summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:06:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:06:31 +0000
commit2ff14448863ac1a1dd9533461708e29aae170c2d (patch)
tree85b9fea2bbfe3f06473cfa381eed11f273b57c5c
parentAdding debian version 1.64.0+dfsg1-1. (diff)
downloadrustc-2ff14448863ac1a1dd9533461708e29aae170c2d.tar.xz
rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.zip
Adding debian version 1.65.0+dfsg1-2.debian/1.65.0+dfsg1-2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--Cargo.lock865
-rw-r--r--Cargo.toml17
-rw-r--r--README.md27
-rw-r--r--RELEASES.md103
-rw-r--r--compiler/rustc_apfloat/src/lib.rs2
-rw-r--r--compiler/rustc_arena/src/lib.rs8
-rw-r--r--compiler/rustc_ast/Cargo.toml9
-rw-r--r--compiler/rustc_ast/src/ast.rs266
-rw-r--r--compiler/rustc_ast/src/ast_traits.rs90
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs153
-rw-r--r--compiler/rustc_ast/src/lib.rs8
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs77
-rw-r--r--compiler/rustc_ast/src/node_id.rs2
-rw-r--r--compiler/rustc_ast/src/token.rs49
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs127
-rw-r--r--compiler/rustc_ast/src/util/literal.rs32
-rw-r--r--compiler/rustc_ast/src/util/parser.rs68
-rw-r--r--compiler/rustc_ast/src/visit.rs66
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml14
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs191
-rw-r--r--compiler/rustc_ast_lowering/src/block.rs13
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs347
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs235
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs45
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs162
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs479
-rw-r--r--compiler/rustc_ast_lowering/src/lifetime_collector.rs15
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs112
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs46
-rw-r--r--compiler/rustc_ast_passes/Cargo.toml1
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs298
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs245
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs97
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs6
-rw-r--r--compiler/rustc_ast_passes/src/node_count.rs22
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs38
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs6
-rw-r--r--compiler/rustc_attr/src/builtin.rs398
-rw-r--r--compiler/rustc_attr/src/lib.rs5
-rw-r--r--compiler/rustc_attr/src/session_diagnostics.rs398
-rw-r--r--compiler/rustc_borrowck/src/constraint_generation.rs2
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs11
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs34
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs64
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs14
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs160
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs156
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs18
-rw-r--r--compiler/rustc_borrowck/src/invalidation.rs26
-rw-r--r--compiler/rustc_borrowck/src/lib.rs56
-rw-r--r--compiler/rustc_borrowck/src/location.rs5
-rw-r--r--compiler/rustc_borrowck/src/nll.rs5
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs15
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs192
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs57
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs4
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs30
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs125
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs35
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs69
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs64
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs223
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs22
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml13
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/cmdline_attrs.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs69
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs15
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs87
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/edition_panic.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs193
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs15
-rw-r--r--compiler/rustc_codegen_cranelift/.cirrus.yml2
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/main.yml10
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock151
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml14
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md4
-rw-r--r--compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock20
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/abi_checker.rs60
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_backend.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/mod.rs58
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs11
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/rustc_info.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs619
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/utils.rs29
-rwxr-xr-xcompiler/rustc_codegen_cranelift/clean_all.sh2
-rw-r--r--compiler/rustc_codegen_cranelift/config.txt35
-rw-r--r--compiler/rustc_codegen_cranelift/example/alloc_system.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs117
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0001-abi-checker-Disable-failing-tests.patch36
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0023-sysroot-Ignore-failing-tests.patch12
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/tests.sh203
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/comments.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs29
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/returning.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/src/analyze.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs281
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs46
-rw-r--r--compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs168
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs85
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs213
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs282
-rw-r--r--compiler/rustc_codegen_cranelift/src/discriminant.rs31
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs560
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs49
-rw-r--r--compiler/rustc_codegen_cranelift/src/global_asm.rs114
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs176
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/cpuid.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs68
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs38
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs55
-rw-r--r--compiler/rustc_codegen_cranelift/src/main_shim.rs15
-rw-r--r--compiler/rustc_codegen_cranelift/src/optimize/mod.rs17
-rw-r--r--compiler/rustc_codegen_cranelift/src/pretty_clif.rs61
-rw-r--r--compiler/rustc_codegen_cranelift/src/toolchain.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/trap.rs25
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs13
-rwxr-xr-xcompiler/rustc_codegen_cranelift/test.sh13
-rw-r--r--compiler/rustc_codegen_gcc/example/alloc_system.rs2
-rw-r--r--compiler/rustc_codegen_gcc/patches/0024-core-Disable-portable-simd-test.patch1
-rw-r--r--compiler/rustc_codegen_gcc/src/abi.rs39
-rw-r--r--compiler/rustc_codegen_gcc/src/archive.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs174
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs12
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs20
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs105
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs49
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs26
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs91
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs87
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs35
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs740
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs96
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/utils.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs96
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs1
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs73
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs402
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs67
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs29
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs81
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs56
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs32
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs221
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs36
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs157
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs1
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs8
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs40
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs117
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs21
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs35
-rw-r--r--compiler/rustc_const_eval/src/errors.rs125
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs39
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs16
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs71
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs66
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs111
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs234
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs35
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs14
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs34
-rw-r--r--compiler/rustc_const_eval/src/interpret/traits.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs259
-rw-r--r--compiler/rustc_const_eval/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/might_permit_raw_init.rs6
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs8
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs161
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs66
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs30
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs93
-rw-r--r--compiler/rustc_data_structures/Cargo.toml23
-rw-r--r--compiler/rustc_data_structures/src/fingerprint.rs4
-rw-r--r--compiler/rustc_data_structures/src/fx.rs15
-rw-r--r--compiler/rustc_data_structures/src/lib.rs5
-rw-r--r--compiler/rustc_data_structures/src/map_in_place.rs127
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs4
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs20
-rw-r--r--compiler/rustc_data_structures/src/sync.rs4
-rw-r--r--compiler/rustc_data_structures/src/thin_vec.rs135
-rw-r--r--compiler/rustc_data_structures/src/thin_vec/tests.rs42
-rw-r--r--compiler/rustc_data_structures/src/transitive_relation.rs121
-rw-r--r--compiler/rustc_data_structures/src/transitive_relation/tests.rs48
-rw-r--r--compiler/rustc_driver/Cargo.toml3
-rw-r--r--compiler/rustc_driver/src/lib.rs61
-rw-r--r--compiler/rustc_driver/src/pretty.rs16
-rw-r--r--compiler/rustc_driver/src/session_diagnostics.rs40
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0695.md3
-rw-r--r--compiler/rustc_error_codes/src/lib.rs2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl139
-rw-r--r--compiler/rustc_error_messages/locales/en-US/ast_passes.ftl91
-rw-r--r--compiler/rustc_error_messages/locales/en-US/attr.ftl107
-rw-r--r--compiler/rustc_error_messages/locales/en-US/borrowck.ftl58
-rw-r--r--compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/const_eval.ftl78
-rw-r--r--compiler/rustc_error_messages/locales/en-US/driver.ftl13
-rw-r--r--compiler/rustc_error_messages/locales/en-US/expand.ftl21
-rw-r--r--compiler/rustc_error_messages/locales/en-US/infer.ftl171
-rw-r--r--compiler/rustc_error_messages/locales/en-US/interface.ftl43
-rw-r--r--compiler/rustc_error_messages/locales/en-US/lint.ftl366
-rw-r--r--compiler/rustc_error_messages/locales/en-US/metadata.ftl275
-rw-r--r--compiler/rustc_error_messages/locales/en-US/middle.ftl17
-rw-r--r--compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl29
-rw-r--r--compiler/rustc_error_messages/locales/en-US/monomorphize.ftl26
-rw-r--r--compiler/rustc_error_messages/locales/en-US/parser.ftl148
-rw-r--r--compiler/rustc_error_messages/locales/en-US/passes.ftl230
-rw-r--r--compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/privacy.ftl20
-rw-r--r--compiler/rustc_error_messages/locales/en-US/query_system.ftl25
-rw-r--r--compiler/rustc_error_messages/locales/en-US/save_analysis.ftl1
-rw-r--r--compiler/rustc_error_messages/locales/en-US/session.ftl68
-rw-r--r--compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl1
-rw-r--r--compiler/rustc_error_messages/locales/en-US/trait_selection.ftl26
-rw-r--r--compiler/rustc_error_messages/locales/en-US/ty_utils.ftl47
-rw-r--r--compiler/rustc_error_messages/locales/en-US/typeck.ftl88
-rw-r--r--compiler/rustc_error_messages/src/lib.rs23
-rw-r--r--compiler/rustc_errors/Cargo.toml7
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs25
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs50
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs33
-rw-r--r--compiler/rustc_errors/src/emitter.rs140
-rw-r--r--compiler/rustc_errors/src/json.rs19
-rw-r--r--compiler/rustc_errors/src/lib.rs162
-rw-r--r--compiler/rustc_errors/src/translation.rs103
-rw-r--r--compiler/rustc_expand/src/base.rs58
-rw-r--r--compiler/rustc_expand/src/build.rs43
-rw-r--r--compiler/rustc_expand/src/config.rs74
-rw-r--r--compiler/rustc_expand/src/errors.rs48
-rw-r--r--compiler/rustc_expand/src/expand.rs40
-rw-r--r--compiler/rustc_expand/src/lib.rs6
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs11
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs34
-rw-r--r--compiler/rustc_expand/src/module.rs8
-rw-r--r--compiler/rustc_expand/src/placeholders.rs8
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs71
-rw-r--r--compiler/rustc_feature/src/accepted.rs6
-rw-r--r--compiler/rustc_feature/src/active.rs22
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs33
-rw-r--r--compiler/rustc_feature/src/lib.rs6
-rw-r--r--compiler/rustc_feature/src/removed.rs3
-rw-r--r--compiler/rustc_fs_util/src/lib.rs3
-rw-r--r--compiler/rustc_graphviz/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/def.rs25
-rw-r--r--compiler/rustc_hir/src/definitions.rs1
-rw-r--r--compiler/rustc_hir/src/errors.rs10
-rw-r--r--compiler/rustc_hir/src/hir.rs219
-rw-r--r--compiler/rustc_hir/src/hir_id.rs12
-rw-r--r--compiler/rustc_hir/src/intravisit.rs168
-rw-r--r--compiler/rustc_hir/src/lang_items.rs15
-rw-r--r--compiler/rustc_hir/src/lib.rs8
-rw-r--r--compiler/rustc_hir/src/pat_util.rs19
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs17
-rw-r--r--compiler/rustc_hir/src/target.rs15
-rw-r--r--compiler/rustc_hir/src/weak_lang_items.rs6
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs150
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_index/src/lib.rs4
-rw-r--r--compiler/rustc_index/src/vec.rs4
-rw-r--r--compiler/rustc_infer/Cargo.toml1
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs499
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs172
-rw-r--r--compiler/rustc_infer/src/infer/at.rs6
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs13
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs74
-rw-r--r--compiler/rustc_infer/src/infer/canonical/substitute.rs7
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs54
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs349
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs347
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs147
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs10
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs54
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs5
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs15
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs150
-rw-r--r--compiler/rustc_infer/src/infer/free_regions.rs13
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs1
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs307
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs126
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs62
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs34
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs62
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs36
-rw-r--r--compiler/rustc_infer/src/infer/outlives/test_type_match.rs15
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs6
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs31
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs17
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs1
-rw-r--r--compiler/rustc_infer/src/infer/undo_log.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs5
-rw-r--r--compiler/rustc_interface/Cargo.toml1
-rw-r--r--compiler/rustc_interface/src/errors.rs89
-rw-r--r--compiler/rustc_interface/src/interface.rs8
-rw-r--r--compiler/rustc_interface/src/lib.rs8
-rw-r--r--compiler/rustc_interface/src/passes.rs103
-rw-r--r--compiler/rustc_interface/src/queries.rs20
-rw-r--r--compiler/rustc_interface/src/tests.rs11
-rw-r--r--compiler/rustc_interface/src/util.rs4
-rw-r--r--compiler/rustc_lexer/src/lib.rs4
-rw-r--r--compiler/rustc_lint/src/array_into_iter.rs3
-rw-r--r--compiler/rustc_lint/src/builtin.rs197
-rw-r--r--compiler/rustc_lint/src/context.rs135
-rw-r--r--compiler/rustc_lint/src/early.rs30
-rw-r--r--compiler/rustc_lint/src/errors.rs162
-rw-r--r--compiler/rustc_lint/src/hidden_unicode_codepoints.rs4
-rw-r--r--compiler/rustc_lint/src/internal.rs18
-rw-r--r--compiler/rustc_lint/src/late.rs59
-rw-r--r--compiler/rustc_lint/src/let_underscore.rs175
-rw-r--r--compiler/rustc_lint/src/levels.rs132
-rw-r--r--compiler/rustc_lint/src/lib.rs55
-rw-r--r--compiler/rustc_lint/src/methods.rs18
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs25
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs3
-rw-r--r--compiler/rustc_lint/src/passes.rs14
-rw-r--r--compiler/rustc_lint/src/types.rs115
-rw-r--r--compiler/rustc_lint/src/unused.rs102
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs64
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs27
-rw-r--r--compiler/rustc_llvm/build.rs11
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp13
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp11
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp74
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp67
-rw-r--r--compiler/rustc_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_log/src/lib.rs3
-rw-r--r--compiler/rustc_macros/Cargo.toml2
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs84
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs110
-rw-r--r--compiler/rustc_macros/src/diagnostics/fluent.rs56
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs20
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs740
-rw-r--r--compiler/rustc_macros/src/diagnostics/utils.rs59
-rw-r--r--compiler/rustc_macros/src/lib.rs33
-rw-r--r--compiler/rustc_macros/src/query.rs502
-rw-r--r--compiler/rustc_macros/src/symbols.rs2
-rw-r--r--compiler/rustc_metadata/src/creader.rs56
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs79
-rw-r--r--compiler/rustc_metadata/src/errors.rs679
-rw-r--r--compiler/rustc_metadata/src/fs.rs25
-rw-r--r--compiler/rustc_metadata/src/lib.rs11
-rw-r--r--compiler/rustc_metadata/src/locator.rs329
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs346
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs402
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs47
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs683
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs54
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs19
-rw-r--r--compiler/rustc_middle/Cargo.toml31
-rw-r--r--compiler/rustc_middle/src/arena.rs4
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs43
-rw-r--r--compiler/rustc_middle/src/error.rs50
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs93
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs27
-rw-r--r--compiler/rustc_middle/src/lib.rs7
-rw-r--r--compiler/rustc_middle/src/metadata.rs3
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs6
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs8
-rw-r--r--compiler/rustc_middle/src/middle/resolve_lifetime.rs10
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs77
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs2
-rw-r--r--compiler/rustc_middle/src/mir/generic_graph.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs331
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs13
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs6
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs15
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs163
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs194
-rw-r--r--compiler/rustc_middle/src/mir/patch.rs36
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs60
-rw-r--r--compiler/rustc_middle/src/mir/query.rs26
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs4
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs207
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs4
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs4
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs207
-rw-r--r--compiler/rustc_middle/src/mir/type_visitable.rs170
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs186
-rw-r--r--compiler/rustc_middle/src/query/mod.rs176
-rw-r--r--compiler/rustc_middle/src/thir.rs236
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs29
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs62
-rw-r--r--compiler/rustc_middle/src/traits/query.rs12
-rw-r--r--compiler/rustc_middle/src/traits/select.rs3
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs2
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs2
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs2
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs8
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs2
-rw-r--r--compiler/rustc_middle/src/ty/binding.rs14
-rw-r--r--compiler/rustc_middle/src/ty/cast.rs4
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs8
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs20
-rw-r--r--compiler/rustc_middle/src/ty/consts/valtree.rs5
-rw-r--r--compiler/rustc_middle/src/ty/context.rs54
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs18
-rw-r--r--compiler/rustc_middle/src/ty/error.rs45
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs16
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs43
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs26
-rw-r--r--compiler/rustc_middle/src/ty/impls_ty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs720
-rw-r--r--compiler/rustc_middle/src/ty/layout_sanity_check.rs303
-rw-r--r--compiler/rustc_middle/src/ty/list.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs324
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs4
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs7
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs118
-rw-r--r--compiler/rustc_middle/src/ty/query.rs36
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs39
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs496
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs57
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs8
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs1
-rw-r--r--compiler/rustc_middle/src/ty/util.rs10
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs14
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs8
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs8
-rw-r--r--compiler/rustc_middle/src/values.rs54
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs213
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs37
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs144
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs31
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs25
-rw-r--r--compiler/rustc_mir_build/src/build/expr/stmt.rs22
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs157
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs24
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs50
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs14
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs616
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs38
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs19
-rw-r--r--compiler/rustc_mir_build/src/lib.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/block.rs18
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs72
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs116
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs32
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs48
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs47
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs127
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs28
-rw-r--r--compiler/rustc_mir_dataflow/Cargo.toml3
-rw-r--r--compiler/rustc_mir_dataflow/src/errors.rs71
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs22
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs107
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs30
-rw-r--r--compiler/rustc_mir_dataflow/src/storage.rs2
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_call_guards.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs19
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs91
-rw-r--r--compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs2
-rw-r--r--compiler/rustc_mir_transform/src/const_goto.rs4
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs127
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs66
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs6
-rw-r--r--compiler/rustc_mir_transform/src/dead_store_elimination.rs2
-rw-r--r--compiler/rustc_mir_transform/src/deaggregator.rs4
-rw-r--r--compiler/rustc_mir_transform/src/deduplicate_blocks.rs5
-rw-r--r--compiler/rustc_mir_transform/src/deref_separator.rs23
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs8
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs6
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs40
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs16
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs2
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs108
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs371
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs180
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs31
-rw-r--r--compiler/rustc_mir_transform/src/multiple_return_terminators.rs2
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs4
-rw-r--r--compiler/rustc_mir_transform/src/nrvo.rs8
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs73
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs4
-rw-r--r--compiler/rustc_mir_transform/src/remove_uninit_drops.rs2
-rw-r--r--compiler/rustc_mir_transform/src/required_consts.rs11
-rw-r--r--compiler/rustc_mir_transform/src/reveal_all.rs2
-rw-r--r--compiler/rustc_mir_transform/src/separate_const_switch.rs8
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs131
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs10
-rw-r--r--compiler/rustc_mir_transform/src/simplify_comparison_integral.rs2
-rw-r--r--compiler/rustc_mir_transform/src/simplify_try.rs4
-rw-r--r--compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs6
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs76
-rw-r--r--compiler/rustc_monomorphize/Cargo.toml4
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs168
-rw-r--r--compiler/rustc_monomorphize/src/errors.rs85
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs7
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs15
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs55
-rw-r--r--compiler/rustc_monomorphize/src/util.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs8
-rw-r--r--compiler/rustc_parse/src/lib.rs6
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs31
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs78
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs476
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs837
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs15
-rw-r--r--compiler/rustc_parse/src/parser/item.rs192
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs45
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs24
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs59
-rw-r--r--compiler/rustc_parse/src/parser/path.rs22
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs70
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs39
-rw-r--r--compiler/rustc_parse_format/src/lib.rs87
-rw-r--r--compiler/rustc_parse_format/src/tests.rs43
-rw-r--r--compiler/rustc_passes/src/check_attr.rs82
-rw-r--r--compiler/rustc_passes/src/dead.rs22
-rw-r--r--compiler/rustc_passes/src/entry.rs56
-rw-r--r--compiler/rustc_passes/src/errors.rs201
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs2
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs540
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/lib_features.rs25
-rw-r--r--compiler/rustc_passes/src/liveness.rs220
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs96
-rw-r--r--compiler/rustc_passes/src/stability.rs176
-rw-r--r--compiler/rustc_plugin_impl/Cargo.toml1
-rw-r--r--compiler/rustc_plugin_impl/src/errors.rs20
-rw-r--r--compiler/rustc_plugin_impl/src/lib.rs3
-rw-r--r--compiler/rustc_plugin_impl/src/load.rs16
-rw-r--r--compiler/rustc_privacy/src/errors.rs22
-rw-r--r--compiler/rustc_privacy/src/lib.rs168
-rw-r--r--compiler/rustc_query_impl/Cargo.toml4
-rw-r--r--compiler/rustc_query_impl/src/lib.rs10
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs76
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs447
-rw-r--r--compiler/rustc_query_impl/src/profiling_support.rs12
-rw-r--r--compiler/rustc_query_impl/src/values.rs45
-rw-r--r--compiler/rustc_query_system/Cargo.toml8
-rw-r--r--compiler/rustc_query_system/src/error.rs80
-rw-r--r--compiler/rustc_query_system/src/ich/hcx.rs25
-rw-r--r--compiler/rustc_query_system/src/ich/impls_hir.rs24
-rw-r--r--compiler/rustc_query_system/src/ich/impls_syntax.rs8
-rw-r--r--compiler/rustc_query_system/src/lib.rs9
-rw-r--r--compiler/rustc_query_system/src/query/config.rs20
-rw-r--r--compiler/rustc_query_system/src/query/job.rs69
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs10
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs88
-rw-r--r--compiler/rustc_query_system/src/values.rs14
-rw-r--r--compiler/rustc_resolve/src/access_levels.rs160
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs56
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs2
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs3
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs61
-rw-r--r--compiler/rustc_resolve/src/ident.rs83
-rw-r--r--compiler/rustc_resolve/src/imports.rs109
-rw-r--r--compiler/rustc_resolve/src/late.rs234
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs133
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs511
-rw-r--r--compiler/rustc_resolve/src/lib.rs87
-rw-r--r--compiler/rustc_resolve/src/macros.rs31
-rw-r--r--compiler/rustc_save_analysis/Cargo.toml2
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs19
-rw-r--r--compiler/rustc_save_analysis/src/errors.rs10
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs40
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs10
-rw-r--r--compiler/rustc_serialize/Cargo.toml1
-rw-r--r--compiler/rustc_serialize/src/collection_impls.rs20
-rw-r--r--compiler/rustc_serialize/src/lib.rs5
-rw-r--r--compiler/rustc_serialize/src/serialize.rs28
-rw-r--r--compiler/rustc_session/Cargo.toml1
-rw-r--r--compiler/rustc_session/src/cgu_reuse_tracker.rs44
-rw-r--r--compiler/rustc_session/src/config.rs43
-rw-r--r--compiler/rustc_session/src/config/sigpipe.rs22
-rw-r--r--compiler/rustc_session/src/cstore.rs35
-rw-r--r--compiler/rustc_session/src/errors.rs221
-rw-r--r--compiler/rustc_session/src/filesearch.rs1
-rw-r--r--compiler/rustc_session/src/lib.rs8
-rw-r--r--compiler/rustc_session/src/options.rs88
-rw-r--r--compiler/rustc_session/src/output.rs35
-rw-r--r--compiler/rustc_session/src/parse.rs112
-rw-r--r--compiler/rustc_session/src/session.rs178
-rw-r--r--compiler/rustc_smir/src/lib.rs2
-rw-r--r--compiler/rustc_smir/src/mir.rs12
-rw-r--r--compiler/rustc_span/src/def_id.rs15
-rw-r--r--compiler/rustc_span/src/hygiene.rs29
-rw-r--r--compiler/rustc_span/src/lib.rs37
-rw-r--r--compiler/rustc_span/src/source_map.rs107
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs51
-rw-r--r--compiler/rustc_symbol_mangling/Cargo.toml2
-rw-r--r--compiler/rustc_symbol_mangling/src/errors.rs34
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs8
-rw-r--r--compiler/rustc_symbol_mangling/src/test.rs26
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs24
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs14
-rw-r--r--compiler/rustc_target/src/abi/call/aarch64.rs43
-rw-r--r--compiler/rustc_target/src/abi/call/amdgpu.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/arm.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/avr.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/bpf.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/hexagon.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/m68k.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mips.rs8
-rw-r--r--compiler/rustc_target/src/abi/call/mips64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs46
-rw-r--r--compiler/rustc_target/src/abi/call/msp430.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/nvptx.rs33
-rw-r--r--compiler/rustc_target/src/abi/call/nvptx64.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/riscv.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/s390x.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/sparc.rs8
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/wasm.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/x86.rs6
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/x86_win64.rs2
-rw-r--r--compiler/rustc_target/src/abi/mod.rs67
-rw-r--r--compiler/rustc_target/src/lib.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_darwin.rs8
-rw-r--r--compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs1
-rw-r--r--compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/android_base.rs3
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs58
-rw-r--r--compiler/rustc_target/src/spec/apple_sdk_base.rs45
-rw-r--r--compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs2
-rw-r--r--compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs19
-rw-r--r--compiler/rustc_target/src/spec/armv4t_none_eabi.rs56
-rw-r--r--compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs2
-rw-r--r--compiler/rustc_target/src/spec/avr_gnu_base.rs3
-rw-r--r--compiler/rustc_target/src/spec/bpf_base.rs2
-rw-r--r--compiler/rustc_target/src/spec/crt_objects.rs40
-rw-r--r--compiler/rustc_target/src/spec/fuchsia_base.rs5
-rw-r--r--compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/i686_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/l4re_base.rs5
-rw-r--r--compiler/rustc_target/src/spec/linux_base.rs8
-rw-r--r--compiler/rustc_target/src/spec/linux_musl_base.rs8
-rw-r--r--compiler/rustc_target/src/spec/mod.rs415
-rw-r--r--compiler/rustc_target/src/spec/msvc_base.rs5
-rw-r--r--compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs17
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs18
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs86
-rw-r--r--compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs4
-rw-r--r--compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs4
-rw-r--r--compiler/rustc_target/src/spec/uefi_msvc_base.rs3
-rw-r--r--compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs4
-rw-r--r--compiler/rustc_target/src/spec/wasm32_wasi.rs4
-rw-r--r--compiler/rustc_target/src/spec/wasm_base.rs5
-rw-r--r--compiler/rustc_target/src/spec/windows_gnu_base.rs15
-rw-r--r--compiler/rustc_target/src/spec/windows_gnullvm_base.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs6
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_none.rs7
-rw-r--r--compiler/rustc_trait_selection/src/autoderef.rs19
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs102
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs17
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/codegen.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs88
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs47
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs206
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs354
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs33
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs201
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/on_unimplemented.rs71
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs (renamed from compiler/rustc_typeck/src/outlives/outlives_bounds.rs)41
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs211
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs57
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs95
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs56
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs120
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs51
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs25
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs37
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs13
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs69
-rw-r--r--compiler/rustc_traits/src/lib.rs4
-rw-r--r--compiler/rustc_traits/src/type_op.rs58
-rw-r--r--compiler/rustc_transmute/Cargo.toml5
-rw-r--r--compiler/rustc_transmute/src/layout/dfa.rs1
-rw-r--r--compiler/rustc_transmute/src/layout/nfa.rs6
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs36
-rw-r--r--compiler/rustc_transmute/src/lib.rs73
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/mod.rs6
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/query_context.rs2
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/tests.rs4
-rw-r--r--compiler/rustc_ty_utils/Cargo.toml1
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs195
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs69
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs61
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs123
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs7
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs7
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs6
-rw-r--r--compiler/rustc_type_ir/src/lib.rs51
-rw-r--r--compiler/rustc_type_ir/src/sty.rs105
-rw-r--r--compiler/rustc_typeck/Cargo.toml1
-rw-r--r--compiler/rustc_typeck/src/astconv/errors.rs1
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs7
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs341
-rw-r--r--compiler/rustc_typeck/src/check/_match.rs122
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs25
-rw-r--r--compiler/rustc_typeck/src/check/cast.rs121
-rw-r--r--compiler/rustc_typeck/src/check/check.rs195
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs90
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs89
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs449
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs87
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs2
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs454
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs90
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs25
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs752
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs14
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs383
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs26
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs5
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs4
-rw-r--r--compiler/rustc_typeck/src/check/inherited.rs30
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs28
-rw-r--r--compiler/rustc_typeck/src/check/intrinsicck.rs71
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs14
-rw-r--r--compiler/rustc_typeck/src/check/method/mod.rs62
-rw-r--r--compiler/rustc_typeck/src/check/method/prelude2021.rs1
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs19
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs277
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs81
-rw-r--r--compiler/rustc_typeck/src/check/op.rs505
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs67
-rw-r--r--compiler/rustc_typeck/src/check/region.rs43
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs47
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs6
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs196
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs39
-rw-r--r--compiler/rustc_typeck/src/check_unused.rs63
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs59
-rw-r--r--compiler/rustc_typeck/src/collect.rs178
-rw-r--r--compiler/rustc_typeck/src/collect/item_bounds.rs16
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs149
-rw-r--r--compiler/rustc_typeck/src/errors.rs95
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs5
-rw-r--r--compiler/rustc_typeck/src/hir_wf_check.rs12
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs93
-rw-r--r--compiler/rustc_typeck/src/lib.rs54
-rw-r--r--compiler/rustc_typeck/src/outlives/mod.rs1
-rw-r--r--compiler/rustc_typeck/src/outlives/utils.rs6
-rw-r--r--compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs255
-rw-r--r--compiler/rustc_typeck/src/variance/constraints.rs14
-rw-r--r--config.toml.example8
-rwxr-xr-xdebian/bin/rust-lld2
-rw-r--r--debian/changelog39
-rw-r--r--debian/control30
-rw-r--r--debian/copyright122
-rw-r--r--debian/libstd-rust-1.64.lintian-overrides13
-rw-r--r--debian/libstd-rust-1.65.install (renamed from debian/libstd-rust-1.64.install)0
-rw-r--r--debian/libstd-rust-1.65.lintian-overrides13
-rw-r--r--debian/patches/d-0000-ignore-removed-submodules.patch143
-rw-r--r--debian/patches/d-0004-clippy-feature-sync.patch8
-rw-r--r--debian/patches/d-0005-no-jemalloc.patch9
-rw-r--r--debian/patches/d-bootstrap-cargo-check-cfg.patch2
-rw-r--r--debian/patches/d-bootstrap-custom-debuginfo-path.patch2
-rw-r--r--debian/patches/d-bootstrap-disable-git.patch2
-rw-r--r--debian/patches/d-bootstrap-read-beta-version-from-file.patch2
-rw-r--r--debian/patches/d-bootstrap-rustflags.patch2
-rw-r--r--debian/patches/d-rust-lldb-paths2
-rw-r--r--debian/patches/d-rustc-add-soname.patch2
-rw-r--r--debian/patches/d-rustc-windows-ssp.patch2
-rw-r--r--debian/patches/series5
-rw-r--r--debian/patches/u-arm-compiler-builtins-add-sync-builtin-fallbacks.patch223
-rw-r--r--debian/patches/u-fix-backtrace-tests.patch54
-rw-r--r--debian/patches/u-ignore-bpf-test.patch18
-rw-r--r--debian/patches/u-make-compiletest-work-without-rpath.patch187
-rw-r--r--debian/patches/u-rustc-llvm-cross-flags.patch2
-rw-r--r--debian/patches/ubuntu-Revert-Use-constant-eval-to-do-strict-validity-check.patch569
-rw-r--r--debian/patches/ubuntu-disable-ppc64el-asm-tests.patch6
-rwxr-xr-xdebian/rules11
-rw-r--r--debian/rust-lldb.links2
-rw-r--r--debian/rustc.links6
-rw-r--r--debian/upstream-tarball-unsuspicious.txt308
-rw-r--r--git-commit-hash2
-rw-r--r--library/alloc/src/alloc.rs6
-rw-r--r--library/alloc/src/alloc/tests.rs2
-rw-r--r--library/alloc/src/boxed.rs310
-rw-r--r--library/alloc/src/boxed/thin.rs10
-rw-r--r--library/alloc/src/collections/binary_heap.rs3
-rw-r--r--library/alloc/src/collections/btree/dedup_sorted_iter.rs4
-rw-r--r--library/alloc/src/collections/btree/map/entry.rs11
-rw-r--r--library/alloc/src/collections/btree/node.rs16
-rw-r--r--library/alloc/src/collections/linked_list.rs2
-rw-r--r--library/alloc/src/collections/mod.rs4
-rw-r--r--library/alloc/src/collections/vec_deque/drain.rs44
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs10
-rw-r--r--library/alloc/src/ffi/c_str.rs32
-rw-r--r--library/alloc/src/lib.rs16
-rw-r--r--library/alloc/src/macros.rs2
-rw-r--r--library/alloc/src/rc.rs2
-rw-r--r--library/alloc/src/slice.rs86
-rw-r--r--library/alloc/src/str.rs24
-rw-r--r--library/alloc/src/string.rs39
-rw-r--r--library/alloc/src/sync.rs22
-rw-r--r--library/alloc/src/sync/tests.rs19
-rw-r--r--library/alloc/src/vec/drain.rs73
-rw-r--r--library/alloc/src/vec/drain_filter.rs60
-rw-r--r--library/alloc/src/vec/in_place_collect.rs2
-rw-r--r--library/alloc/src/vec/into_iter.rs21
-rw-r--r--library/alloc/src/vec/is_zero.rs16
-rw-r--r--library/alloc/src/vec/mod.rs27
-rw-r--r--library/alloc/src/vec/spec_extend.rs2
-rw-r--r--library/alloc/tests/lib.rs2
-rw-r--r--library/alloc/tests/str.rs10
-rw-r--r--library/alloc/tests/string.rs126
-rw-r--r--library/alloc/tests/thin_box.rs8
-rw-r--r--library/alloc/tests/vec.rs276
-rw-r--r--library/alloc/tests/vec_deque.rs161
-rw-r--r--library/backtrace/.github/workflows/main.yml4
-rw-r--r--library/backtrace/Cargo.toml4
-rw-r--r--library/backtrace/src/backtrace/miri.rs6
-rw-r--r--library/core/benches/num/int_log/mod.rs6
-rw-r--r--library/core/src/alloc/global.rs2
-rw-r--r--library/core/src/alloc/layout.rs113
-rw-r--r--library/core/src/alloc/mod.rs10
-rw-r--r--library/core/src/any.rs244
-rw-r--r--library/core/src/array/equality.rs7
-rw-r--r--library/core/src/array/mod.rs13
-rw-r--r--library/core/src/bool.rs6
-rw-r--r--library/core/src/borrow.rs2
-rw-r--r--library/core/src/char/decode.rs11
-rw-r--r--library/core/src/char/methods.rs25
-rw-r--r--library/core/src/char/mod.rs10
-rw-r--r--library/core/src/cmp.rs34
-rw-r--r--library/core/src/convert/mod.rs11
-rw-r--r--library/core/src/default.rs2
-rw-r--r--library/core/src/error.md137
-rw-r--r--library/core/src/error.rs508
-rw-r--r--library/core/src/ffi/c_double.md4
-rw-r--r--library/core/src/ffi/c_float.md4
-rw-r--r--library/core/src/ffi/c_str.rs29
-rw-r--r--library/core/src/fmt/builders.rs18
-rw-r--r--library/core/src/fmt/mod.rs9
-rw-r--r--library/core/src/future/poll_fn.rs11
-rw-r--r--library/core/src/hash/mod.rs2
-rw-r--r--library/core/src/hint.rs21
-rw-r--r--library/core/src/intrinsics.rs438
-rw-r--r--library/core/src/iter/adapters/array_chunks.rs182
-rw-r--r--library/core/src/iter/adapters/by_ref_sized.rs29
-rw-r--r--library/core/src/iter/adapters/flatten.rs375
-rw-r--r--library/core/src/iter/adapters/mod.rs4
-rw-r--r--library/core/src/iter/adapters/skip.rs27
-rw-r--r--library/core/src/iter/mod.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs45
-rw-r--r--library/core/src/lib.rs8
-rw-r--r--library/core/src/macros/mod.rs53
-rw-r--r--library/core/src/marker.rs11
-rw-r--r--library/core/src/mem/maybe_uninit.rs10
-rw-r--r--library/core/src/mem/mod.rs10
-rw-r--r--library/core/src/mem/transmutability.rs86
-rw-r--r--library/core/src/mem/valid_align.rs18
-rw-r--r--library/core/src/num/bignum.rs2
-rw-r--r--library/core/src/num/dec2flt/decimal.rs2
-rw-r--r--library/core/src/num/error.rs20
-rw-r--r--library/core/src/num/f32.rs153
-rw-r--r--library/core/src/num/f64.rs153
-rw-r--r--library/core/src/num/int_macros.rs116
-rw-r--r--library/core/src/num/mod.rs14
-rw-r--r--library/core/src/num/nonzero.rs46
-rw-r--r--library/core/src/num/uint_macros.rs42
-rw-r--r--library/core/src/ops/drop.rs2
-rw-r--r--library/core/src/ops/function.rs25
-rw-r--r--library/core/src/ops/generator.rs2
-rw-r--r--library/core/src/ops/range.rs2
-rw-r--r--library/core/src/ops/try_trait.rs84
-rw-r--r--library/core/src/option.rs6
-rw-r--r--library/core/src/panicking.rs4
-rw-r--r--library/core/src/primitive_docs.rs72
-rw-r--r--library/core/src/ptr/const_ptr.rs107
-rw-r--r--library/core/src/ptr/metadata.rs18
-rw-r--r--library/core/src/ptr/mod.rs18
-rw-r--r--library/core/src/ptr/mut_ptr.rs98
-rw-r--r--library/core/src/result.rs39
-rw-r--r--library/core/src/slice/ascii.rs2
-rw-r--r--library/core/src/slice/index.rs20
-rw-r--r--library/core/src/slice/iter.rs8
-rw-r--r--library/core/src/slice/iter/macros.rs18
-rw-r--r--library/core/src/slice/memchr.rs37
-rw-r--r--library/core/src/slice/mod.rs53
-rw-r--r--library/core/src/slice/raw.rs4
-rw-r--r--library/core/src/slice/sort.rs36
-rw-r--r--library/core/src/str/error.rs20
-rw-r--r--library/core/src/str/lossy.rs244
-rw-r--r--library/core/src/str/mod.rs14
-rw-r--r--library/core/src/str/validations.rs4
-rw-r--r--library/core/src/sync/atomic.rs80
-rw-r--r--library/core/src/task/wake.rs50
-rw-r--r--library/core/src/time.rs24
-rw-r--r--library/core/src/tuple.rs2
-rw-r--r--library/core/src/unicode/unicode_data.rs65
-rw-r--r--library/core/tests/alloc.rs44
-rw-r--r--library/core/tests/any.rs2
-rw-r--r--library/core/tests/atomic.rs2
-rw-r--r--library/core/tests/const_ptr.rs6
-rw-r--r--library/core/tests/iter/adapters/array_chunks.rs179
-rw-r--r--library/core/tests/iter/adapters/by_ref_sized.rs20
-rw-r--r--library/core/tests/iter/adapters/flatten.rs42
-rw-r--r--library/core/tests/iter/adapters/mod.rs24
-rw-r--r--library/core/tests/iter/adapters/skip.rs31
-rw-r--r--library/core/tests/lib.rs6
-rw-r--r--library/core/tests/num/int_log.rs156
-rw-r--r--library/core/tests/num/int_macros.rs26
-rw-r--r--library/core/tests/num/uint_macros.rs22
-rw-r--r--library/core/tests/ptr.rs2
-rw-r--r--library/core/tests/result.rs9
-rw-r--r--library/core/tests/slice.rs3
-rw-r--r--library/core/tests/str_lossy.rs138
-rw-r--r--library/panic_abort/src/android.rs2
-rw-r--r--library/panic_abort/src/lib.rs33
-rw-r--r--library/panic_unwind/src/emcc.rs16
-rw-r--r--library/panic_unwind/src/gcc.rs262
-rw-r--r--library/panic_unwind/src/lib.rs5
-rw-r--r--library/panic_unwind/src/seh.rs25
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs2
-rw-r--r--library/portable-simd/crates/std_float/src/lib.rs6
-rw-r--r--library/proc_macro/src/bridge/client.rs2
-rw-r--r--library/proc_macro/src/bridge/mod.rs29
-rw-r--r--library/proc_macro/src/bridge/server.rs39
-rw-r--r--library/proc_macro/src/diagnostic.rs21
-rw-r--r--library/proc_macro/src/lib.rs7
-rw-r--r--library/rtstartup/rsbegin.rs19
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/src/alloc.rs5
-rw-r--r--library/std/src/backtrace.rs21
-rw-r--r--library/std/src/collections/hash/map.rs11
-rw-r--r--library/std/src/collections/hash/map/tests.rs24
-rw-r--r--library/std/src/collections/hash/set.rs2
-rw-r--r--library/std/src/error.rs379
-rw-r--r--library/std/src/f32.rs2
-rw-r--r--library/std/src/f32/tests.rs78
-rw-r--r--library/std/src/f64.rs2
-rw-r--r--library/std/src/f64/tests.rs76
-rw-r--r--library/std/src/ffi/os_str.rs3
-rw-r--r--library/std/src/fs.rs41
-rw-r--r--library/std/src/io/buffered/bufreader.rs22
-rw-r--r--library/std/src/io/buffered/bufreader/buffer.rs27
-rw-r--r--library/std/src/io/buffered/tests.rs58
-rw-r--r--library/std/src/io/copy.rs34
-rw-r--r--library/std/src/io/cursor.rs10
-rw-r--r--library/std/src/io/error.rs11
-rw-r--r--library/std/src/io/error/repr_bitpacked.rs4
-rw-r--r--library/std/src/io/impls.rs22
-rw-r--r--library/std/src/io/mod.rs93
-rw-r--r--library/std/src/io/readbuf.rs307
-rw-r--r--library/std/src/io/readbuf/tests.rs220
-rw-r--r--library/std/src/io/stdio.rs51
-rw-r--r--library/std/src/io/tests.rs23
-rw-r--r--library/std/src/io/util.rs14
-rw-r--r--library/std/src/io/util/tests.rs48
-rw-r--r--library/std/src/keyword_docs.rs6
-rw-r--r--library/std/src/lib.rs34
-rw-r--r--library/std/src/macros.rs36
-rw-r--r--library/std/src/net/display_buffer.rs40
-rw-r--r--library/std/src/net/ip_addr.rs (renamed from library/std/src/net/ip.rs)257
-rw-r--r--library/std/src/net/ip_addr/tests.rs (renamed from library/std/src/net/ip/tests.rs)98
-rw-r--r--library/std/src/net/mod.rs13
-rw-r--r--library/std/src/net/parser.rs138
-rw-r--r--library/std/src/net/socket_addr.rs (renamed from library/std/src/net/addr.rs)58
-rw-r--r--library/std/src/net/socket_addr/tests.rs (renamed from library/std/src/net/addr/tests.rs)69
-rw-r--r--library/std/src/os/android/mod.rs1
-rw-r--r--library/std/src/os/android/net.rs4
-rw-r--r--library/std/src/os/fd/owned.rs3
-rw-r--r--library/std/src/os/fd/raw.rs8
-rw-r--r--library/std/src/os/fortanix_sgx/mod.rs5
-rw-r--r--library/std/src/os/linux/mod.rs1
-rw-r--r--library/std/src/os/linux/net.rs4
-rw-r--r--library/std/src/os/mod.rs3
-rw-r--r--library/std/src/os/net/mod.rs7
-rw-r--r--library/std/src/os/net/tcp.rs70
-rw-r--r--library/std/src/os/net/tests.rs29
-rw-r--r--library/std/src/os/unix/net/addr.rs18
-rw-r--r--library/std/src/os/unix/net/datagram.rs25
-rw-r--r--library/std/src/os/unix/net/listener.rs10
-rw-r--r--library/std/src/os/unix/net/stream.rs25
-rw-r--r--library/std/src/os/wasi/io/fd.rs3
-rw-r--r--library/std/src/os/wasi/io/mod.rs6
-rw-r--r--library/std/src/os/wasi/io/raw.rs18
-rw-r--r--library/std/src/panic.rs33
-rw-r--r--library/std/src/path/tests.rs5
-rw-r--r--library/std/src/personality.rs46
-rw-r--r--library/std/src/personality/dwarf/eh.rs (renamed from library/panic_unwind/src/dwarf/eh.rs)4
-rw-r--r--library/std/src/personality/dwarf/mod.rs (renamed from library/panic_unwind/src/dwarf/mod.rs)0
-rw-r--r--library/std/src/personality/dwarf/tests.rs (renamed from library/panic_unwind/src/dwarf/tests.rs)0
-rw-r--r--library/std/src/personality/emcc.rs20
-rw-r--r--library/std/src/personality/gcc.rs279
-rw-r--r--library/std/src/primitive_docs.rs72
-rw-r--r--library/std/src/process.rs10
-rw-r--r--library/std/src/rt.rs31
-rw-r--r--library/std/src/sync/mpsc/mpsc_queue/tests.rs2
-rw-r--r--library/std/src/sync/mpsc/spsc_queue/tests.rs5
-rw-r--r--library/std/src/sync/mpsc/sync_tests.rs21
-rw-r--r--library/std/src/sync/mpsc/tests.rs12
-rw-r--r--library/std/src/sync/mutex.rs1
-rw-r--r--library/std/src/sync/once_lock.rs55
-rw-r--r--library/std/src/sync/rwlock.rs2
-rw-r--r--library/std/src/sync/rwlock/tests.rs2
-rw-r--r--library/std/src/sys/hermit/condvar.rs90
-rw-r--r--library/std/src/sys/hermit/fs.rs18
-rw-r--r--library/std/src/sys/hermit/futex.rs39
-rw-r--r--library/std/src/sys/hermit/mod.rs17
-rw-r--r--library/std/src/sys/hermit/mutex.rs216
-rw-r--r--library/std/src/sys/hermit/net.rs2
-rw-r--r--library/std/src/sys/hermit/rwlock.rs144
-rw-r--r--library/std/src/sys/itron/mutex.rs6
-rw-r--r--library/std/src/sys/sgx/abi/thread.rs8
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/alloc.rs165
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/mod.rs8
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/raw.rs24
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/tests.rs34
-rw-r--r--library/std/src/sys/sgx/mod.rs2
-rw-r--r--library/std/src/sys/sgx/mutex.rs3
-rw-r--r--library/std/src/sys/solid/fs.rs24
-rw-r--r--library/std/src/sys/solid/mod.rs2
-rw-r--r--library/std/src/sys/unix/fd.rs11
-rw-r--r--library/std/src/sys/unix/fs.rs24
-rw-r--r--library/std/src/sys/unix/locks/fuchsia_mutex.rs5
-rw-r--r--library/std/src/sys/unix/locks/futex_mutex.rs5
-rw-r--r--library/std/src/sys/unix/locks/futex_rwlock.rs2
-rw-r--r--library/std/src/sys/unix/locks/pthread_condvar.rs2
-rw-r--r--library/std/src/sys/unix/locks/pthread_mutex.rs2
-rw-r--r--library/std/src/sys/unix/mod.rs42
-rw-r--r--library/std/src/sys/unix/net.rs22
-rw-r--r--library/std/src/sys/unix/os_str.rs40
-rw-r--r--library/std/src/sys/unix/os_str/tests.rs8
-rw-r--r--library/std/src/sys/unix/process/process_common.rs59
-rw-r--r--library/std/src/sys/unix/process/process_common/tests.rs24
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs4
-rw-r--r--library/std/src/sys/unix/rand.rs18
-rw-r--r--library/std/src/sys/unix/thread.rs32
-rw-r--r--library/std/src/sys/unix/thread_parker/mod.rs21
-rw-r--r--library/std/src/sys/unix/thread_parker/netbsd.rs113
-rw-r--r--library/std/src/sys/unix/thread_parker/pthread.rs (renamed from library/std/src/sys/unix/thread_parker.rs)14
-rw-r--r--library/std/src/sys/unsupported/alloc.rs7
-rw-r--r--library/std/src/sys/unsupported/common.rs2
-rw-r--r--library/std/src/sys/unsupported/fs.rs4
-rw-r--r--library/std/src/sys/unsupported/locks/mutex.rs3
-rw-r--r--library/std/src/sys/unsupported/process.rs3
-rw-r--r--library/std/src/sys/wasi/fs.rs6
-rw-r--r--library/std/src/sys/wasi/stdio.rs23
-rw-r--r--library/std/src/sys/windows/alloc.rs5
-rw-r--r--library/std/src/sys/windows/c.rs35
-rw-r--r--library/std/src/sys/windows/cmath.rs2
-rw-r--r--library/std/src/sys/windows/compat.rs232
-rw-r--r--library/std/src/sys/windows/fs.rs119
-rw-r--r--library/std/src/sys/windows/handle.rs12
-rw-r--r--library/std/src/sys/windows/locks/mutex.rs2
-rw-r--r--library/std/src/sys/windows/mod.rs28
-rw-r--r--library/std/src/sys/windows/os.rs6
-rw-r--r--library/std/src/sys/windows/os_str.rs4
-rw-r--r--library/std/src/sys/windows/path/tests.rs2
-rw-r--r--library/std/src/sys/windows/rand.rs121
-rw-r--r--library/std/src/sys/windows/stdio.rs41
-rw-r--r--library/std/src/sys/windows/thread_local_dtor.rs4
-rw-r--r--library/std/src/sys/windows/thread_parker.rs22
-rw-r--r--library/std/src/sys_common/net.rs8
-rw-r--r--library/std/src/sys_common/remutex.rs46
-rw-r--r--library/std/src/sys_common/remutex/tests.rs37
-rw-r--r--library/std/src/sys_common/thread_local_key.rs2
-rw-r--r--library/std/src/sys_common/thread_local_key/tests.rs9
-rw-r--r--library/std/src/sys_common/thread_parker/mod.rs1
-rw-r--r--library/std/src/sys_common/wtf8.rs95
-rw-r--r--library/std/src/sys_common/wtf8/tests.rs295
-rw-r--r--library/std/src/thread/local.rs3
-rw-r--r--library/std/src/thread/mod.rs85
-rw-r--r--library/std/src/thread/tests.rs50
-rw-r--r--library/std/src/time/tests.rs3
-rw-r--r--library/stdarch/CONTRIBUTING.md2
-rw-r--r--library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile2
-rw-r--r--library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile2
-rw-r--r--library/stdarch/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile2
-rwxr-xr-xlibrary/stdarch/ci/dox.sh9
-rw-r--r--library/stdarch/crates/core_arch/Cargo.toml1
-rw-r--r--library/stdarch/crates/core_arch/build.rs3
-rw-r--r--library/stdarch/crates/core_arch/src/aarch64/crc.rs4
-rw-r--r--library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs2538
-rw-r--r--library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs74
-rw-r--r--library/stdarch/crates/core_arch/src/arm/neon.rs21
-rw-r--r--library/stdarch/crates/core_arch/src/arm/v7.rs1
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/crc.rs12
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/crypto.rs28
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs4060
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs352
-rw-r--r--library/stdarch/crates/core_arch/src/powerpc/altivec.rs5
-rw-r--r--library/stdarch/crates/core_arch/src/x86/avx2.rs2
-rw-r--r--library/stdarch/crates/core_arch/src/x86/avx512bw.rs16
-rw-r--r--library/stdarch/crates/core_arch/src/x86/avx512gfni.rs6
-rw-r--r--library/stdarch/crates/core_arch/src/x86/sse.rs32
-rw-r--r--library/stdarch/crates/core_arch/src/x86/sse2.rs4
-rw-r--r--library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs34
-rw-r--r--library/stdarch/crates/intrinsic-test/missing_aarch64.txt14
-rw-r--r--library/stdarch/crates/intrinsic-test/src/argument.rs107
-rw-r--r--library/stdarch/crates/intrinsic-test/src/intrinsic.rs65
-rw-r--r--library/stdarch/crates/intrinsic-test/src/main.rs54
-rw-r--r--library/stdarch/crates/intrinsic-test/src/types.rs44
-rw-r--r--library/stdarch/crates/intrinsic-test/src/values.rs9
-rw-r--r--library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs3
-rw-r--r--library/stdarch/crates/std_detect/src/detect/macros.rs27
-rw-r--r--library/stdarch/crates/stdarch-gen/neon.spec24
-rw-r--r--library/stdarch/crates/stdarch-gen/src/main.rs55
-rw-r--r--library/stdarch/examples/hex.rs27
-rw-r--r--library/test/src/stats.rs2
-rw-r--r--library/test/src/term/terminfo/mod.rs20
-rw-r--r--library/unwind/build.rs15
-rw-r--r--library/unwind/src/lib.rs20
-rw-r--r--src/README.md2
-rw-r--r--src/bootstrap/Cargo.lock1
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/bin/rustc.rs21
-rw-r--r--src/bootstrap/bin/rustdoc.rs11
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/bootstrap/builder.rs44
-rw-r--r--src/bootstrap/builder/tests.rs2
-rw-r--r--src/bootstrap/check.rs2
-rw-r--r--src/bootstrap/compile.rs11
-rw-r--r--src/bootstrap/config.rs72
-rw-r--r--src/bootstrap/dist.rs59
-rw-r--r--src/bootstrap/doc.rs2
-rw-r--r--src/bootstrap/flags.rs15
-rw-r--r--src/bootstrap/install.rs9
-rw-r--r--src/bootstrap/lib.rs33
-rw-r--r--src/bootstrap/mk/Makefile.in11
-rw-r--r--src/bootstrap/native.rs107
-rw-r--r--src/bootstrap/run.rs22
-rw-r--r--src/bootstrap/setup.rs2
-rw-r--r--src/bootstrap/tarball.rs8
-rw-r--r--src/bootstrap/test.rs119
-rw-r--r--src/bootstrap/tool.rs28
-rw-r--r--src/bootstrap/toolstate.rs1
-rw-r--r--src/bootstrap/util.rs14
-rw-r--r--src/ci/docker/host-x86_64/arm-android/Dockerfile8
-rw-r--r--src/ci/docker/host-x86_64/armhf-gnu/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-android/Dockerfile5
-rw-r--r--src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile18
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-various-2/build-fuchsia-toolchain.sh100
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh2
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile12
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in22
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt145
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/wasm32/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile7
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile (renamed from src/ci/docker/host-x86_64/x86_64-gnu-llvm-12-stage1/Dockerfile)16
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile (renamed from src/ci/docker/host-x86_64/x86_64-gnu-llvm-12/Dockerfile)32
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile14
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh1
-rwxr-xr-xsrc/ci/docker/run.sh11
-rw-r--r--src/ci/docker/scripts/android-base-apt-get.sh1
-rw-r--r--src/ci/docker/static/gitconfig2
-rw-r--r--src/ci/github-actions/ci.yml57
-rwxr-xr-xsrc/ci/run.sh22
-rwxr-xr-xsrc/ci/scripts/install-clang.sh4
-rw-r--r--src/doc/book/2018-edition/book.toml2
-rw-r--r--src/doc/book/2018-edition/src/theme/2018-edition.css9
-rw-r--r--src/doc/book/2018-edition/src/theme/index.hbs37
-rw-r--r--src/doc/book/listings/ch20-web-server/listing-20-24/src/lib.rs4
-rw-r--r--src/doc/book/src/ch01-03-hello-cargo.md2
-rw-r--r--src/doc/book/src/ch06-02-match.md2
-rw-r--r--src/doc/book/src/ch09-02-recoverable-errors-with-result.md2
-rw-r--r--src/doc/book/src/ch20-02-multithreaded.md2
-rw-r--r--src/doc/book/src/title-page.md4
-rw-r--r--src/doc/edition-guide/README.md4
-rw-r--r--src/doc/edition-guide/book.toml2
-rw-r--r--src/doc/edition-guide/src/SUMMARY.md2
-rw-r--r--src/doc/edition-guide/src/editions/creating-a-new-project.md48
-rw-r--r--src/doc/edition-guide/src/editions/index.md10
-rw-r--r--src/doc/edition-guide/src/introduction.md2
-rw-r--r--src/doc/index.md2
-rw-r--r--src/doc/nomicon/src/lifetime-mismatch.md2
-rw-r--r--src/doc/nomicon/src/lifetimes.md2
-rw-r--r--src/doc/nomicon/src/other-reprs.md20
-rw-r--r--src/doc/reference/book.toml1
-rw-r--r--src/doc/reference/src/attributes/testing.md3
-rw-r--r--src/doc/reference/src/attributes/type_system.md8
-rw-r--r--src/doc/reference/src/crates-and-source-files.md6
-rw-r--r--src/doc/rust-by-example/book.toml1
-rw-r--r--src/doc/rust-by-example/src/SUMMARY.md2
-rw-r--r--src/doc/rust-by-example/src/error/option_unwrap/defaults.md12
-rw-r--r--src/doc/rust-by-example/src/flow_control.md2
-rw-r--r--src/doc/rust-by-example/src/hello/print.md22
-rw-r--r--src/doc/rust-by-example/src/meta.md4
-rw-r--r--src/doc/rust-by-example/src/meta/doc.md2
-rw-r--r--src/doc/rust-by-example/src/meta/playground.md (renamed from src/doc/rust-by-example/src/meta/playpen.md)8
-rw-r--r--src/doc/rust-by-example/src/std_misc/threads/testcase_mapreduce.md8
-rw-r--r--src/doc/rustc-dev-guide/book.toml2
-rw-r--r--src/doc/rustc-dev-guide/ci/date-check/src/main.rs180
-rw-r--r--src/doc/rustc-dev-guide/src/backend/backend-agnostic.md5
-rw-r--r--src/doc/rustc-dev-guide/src/backend/codegen.md19
-rw-r--r--src/doc/rustc-dev-guide/src/backend/updating-llvm.md18
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping.md29
-rw-r--r--src/doc/rustc-dev-guide/src/building/prerequisites.md3
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md2
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-debugging.md31
-rw-r--r--src/doc/rustc-dev-guide/src/contributing.md37
-rw-r--r--src/doc/rustc-dev-guide/src/conventions.md4
-rw-r--r--src/doc/rustc-dev-guide/src/crates-io.md16
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md79
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md159
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/lintstore.md45
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/translation.md27
-rw-r--r--src/doc/rustc-dev-guide/src/git.md12
-rw-r--r--src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md7
-rw-r--r--src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md6
-rw-r--r--src/doc/rustc-dev-guide/src/overview.md2
-rw-r--r--src/doc/rustc-dev-guide/src/parallel-rustc.md161
-rw-r--r--src/doc/rustc-dev-guide/src/part-5-intro.md65
-rw-r--r--src/doc/rustc-dev-guide/src/profiling.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md2
-rw-r--r--src/doc/rustc-dev-guide/src/query.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals.md2
-rw-r--r--src/doc/rustc-dev-guide/src/salsa.md2
-rw-r--r--src/doc/rustc-dev-guide/src/stabilization_guide.md26
-rw-r--r--src/doc/rustc-dev-guide/src/test-implementation.md1
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md2
-rw-r--r--src/doc/rustc-dev-guide/src/the-parser.md17
-rw-r--r--src/doc/rustc-dev-guide/src/thir.md163
-rw-r--r--src/doc/rustc-dev-guide/src/traits/chalk.md4
-rw-r--r--src/doc/rustc-dev-guide/src/traits/resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/type-inference.md10
-rw-r--r--src/doc/rustc/src/SUMMARY.md2
-rw-r--r--src/doc/rustc/src/instrument-coverage.md28
-rw-r--r--src/doc/rustc/src/linker-plugin-lto.md4
-rw-r--r--src/doc/rustc/src/platform-support.md10
-rw-r--r--src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md74
-rw-r--r--src/doc/rustc/src/platform-support/armv4t-none-eabi.md70
-rw-r--r--src/doc/rustc/src/platform-support/fuchsia.md689
-rw-r--r--src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md2
-rw-r--r--src/doc/rustc/src/platform-support/openbsd.md2
-rw-r--r--src/doc/rustc/src/platform-support/pc-windows-gnullvm.md2
-rw-r--r--src/doc/rustc/src/platform-support/unknown-uefi.md2
-rw-r--r--src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md2
-rw-r--r--src/doc/rustdoc/book.toml4
-rw-r--r--src/doc/unstable-book/src/compiler-flags/check-cfg.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/sanitizer.md36
-rw-r--r--src/doc/unstable-book/src/language-features/raw-dylib.md10
-rw-r--r--src/doc/unstable-book/src/language-features/unix-sigpipe.md54
-rw-r--r--src/etc/check_missing_items.py189
-rwxr-xr-xsrc/etc/cpu-usage-over-time-plot.sh2
-rw-r--r--src/etc/gdb_lookup.py3
-rw-r--r--src/etc/gdb_providers.py11
-rw-r--r--src/etc/htmldocck.py24
-rw-r--r--src/etc/installer/msi/rust.wxs14
-rw-r--r--src/etc/installer/pkg/Distribution.xml17
-rw-r--r--src/etc/lldb_commands1
-rw-r--r--src/etc/lldb_lookup.py3
-rw-r--r--src/etc/lldb_providers.py8
-rw-r--r--src/etc/natvis/intrinsic.natvis249
-rw-r--r--src/etc/natvis/liballoc.natvis8
-rwxr-xr-xsrc/etc/pre-push.sh2
-rw-r--r--src/etc/rust_types.py3
-rw-r--r--src/librustdoc/Cargo.toml13
-rw-r--r--src/librustdoc/clean/auto_trait.rs20
-rw-r--r--src/librustdoc/clean/blanket_impl.rs4
-rw-r--r--src/librustdoc/clean/inline.rs55
-rw-r--r--src/librustdoc/clean/mod.rs1248
-rw-r--r--src/librustdoc/clean/types.rs142
-rw-r--r--src/librustdoc/clean/utils.rs83
-rw-r--r--src/librustdoc/config.rs16
-rw-r--r--src/librustdoc/doctest.rs9
-rw-r--r--src/librustdoc/fold.rs2
-rw-r--r--src/librustdoc/formats/cache.rs2
-rw-r--r--src/librustdoc/formats/item_type.rs1
-rw-r--r--src/librustdoc/html/format.rs45
-rw-r--r--src/librustdoc/html/highlight.rs355
-rw-r--r--src/librustdoc/html/highlight/fixtures/decorations.html6
-rw-r--r--src/librustdoc/html/highlight/fixtures/dos_line.html2
-rw-r--r--src/librustdoc/html/highlight/fixtures/highlight.html8
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.html39
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.rs1
-rw-r--r--src/librustdoc/html/highlight/fixtures/union.html10
-rw-r--r--src/librustdoc/html/highlight/tests.rs18
-rw-r--r--src/librustdoc/html/markdown.rs32
-rw-r--r--src/librustdoc/html/render/context.rs37
-rw-r--r--src/librustdoc/html/render/mod.rs399
-rw-r--r--src/librustdoc/html/render/print_item.rs95
-rw-r--r--src/librustdoc/html/render/search_index.rs13
-rw-r--r--src/librustdoc/html/render/span_map.rs34
-rw-r--r--src/librustdoc/html/render/write_shared.rs79
-rw-r--r--src/librustdoc/html/sources.rs22
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css597
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css279
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css216
-rw-r--r--src/librustdoc/html/static/css/themes/light.css214
-rw-r--r--src/librustdoc/html/static/images/down-arrow.svg2
-rw-r--r--src/librustdoc/html/static/js/main.js89
-rw-r--r--src/librustdoc/html/static/js/search.js31
-rw-r--r--src/librustdoc/html/static/js/source-script.js20
-rw-r--r--src/librustdoc/html/templates/page.html8
-rw-r--r--src/librustdoc/json/conversions.rs295
-rw-r--r--src/librustdoc/json/import_finder.rs38
-rw-r--r--src/librustdoc/json/mod.rs38
-rw-r--r--src/librustdoc/lib.rs4
-rw-r--r--src/librustdoc/lint.rs9
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs18
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs21
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs26
-rw-r--r--src/librustdoc/passes/html_tags.rs85
-rw-r--r--src/librustdoc/passes/propagate_doc_cfg.rs62
-rw-r--r--src/librustdoc/passes/strip_hidden.rs8
-rw-r--r--src/librustdoc/passes/strip_private.rs10
-rw-r--r--src/librustdoc/passes/stripper.rs65
-rw-r--r--src/librustdoc/scrape_examples.rs2
-rw-r--r--src/librustdoc/theme.rs393
-rw-r--r--src/librustdoc/theme/tests.rs120
-rw-r--r--src/librustdoc/visit.rs2
-rw-r--r--src/librustdoc/visit_ast.rs12
-rw-r--r--src/rustdoc-json-types/lib.rs160
-rw-r--r--src/rustdoc-json-types/tests.rs4
-rw-r--r--src/stage0.json568
-rw-r--r--src/test/assembly/aarch64-pointer-auth.rs1
-rw-r--r--src/test/assembly/asm/avr-modifiers.rs1
-rw-r--r--src/test/assembly/asm/avr-types.rs1
-rw-r--r--src/test/assembly/asm/bpf-types.rs1
-rw-r--r--src/test/assembly/asm/msp430-types.rs1
-rw-r--r--src/test/assembly/asm/powerpc-types.rs1
-rw-r--r--src/test/assembly/stack-protector/stack-protector-target-support.rs1
-rw-r--r--src/test/assembly/x86_64-floating-point-clamp.rs25
-rw-r--r--src/test/auxiliary/rust_test_helpers.c12
-rw-r--r--src/test/codegen/README.md22
-rw-r--r--src/test/codegen/abi-repr-ext.rs46
-rw-r--r--src/test/codegen/asm-may_unwind.rs1
-rw-r--r--src/test/codegen/async-fn-debug-awaitee-field.rs4
-rw-r--r--src/test/codegen/async-fn-debug-msvc.rs7
-rw-r--r--src/test/codegen/atomic-operations-llvm-12.rs84
-rw-r--r--src/test/codegen/atomic-operations.rs1
-rw-r--r--src/test/codegen/avr/avr-func-addrspace.rs2
-rw-r--r--src/test/codegen/branch-protection.rs1
-rw-r--r--src/test/codegen/debug-vtable.rs2
-rw-r--r--src/test/codegen/external-no-mangle-statics.rs5
-rw-r--r--src/test/codegen/generator-debug-msvc.rs12
-rw-r--r--src/test/codegen/generator-debug.rs4
-rw-r--r--src/test/codegen/instrument-coverage.rs17
-rw-r--r--src/test/codegen/intrinsics/mask.rs11
-rw-r--r--src/test/codegen/issue-34634.rs2
-rw-r--r--src/test/codegen/issue-85872-multiple-reverse.rs20
-rw-r--r--src/test/codegen/issue-96274.rs17
-rw-r--r--src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs19
-rw-r--r--src/test/codegen/layout-size-checks.rs31
-rw-r--r--src/test/codegen/mem-replace-direct-memcpy.rs12
-rw-r--r--src/test/codegen/merge-functions.rs7
-rw-r--r--src/test/codegen/mir-inlined-line-numbers.rs25
-rw-r--r--src/test/codegen/pic-relocation-model.rs7
-rw-r--r--src/test/codegen/pie-relocation-model.rs2
-rw-r--r--src/test/codegen/some-abis-do-extend-params-to-32-bits.rs204
-rw-r--r--src/test/codegen/try_question_mark_nop.rs54
-rw-r--r--src/test/codegen/unwind-abis/aapcs-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs2
-rw-r--r--src/test/codegen/unwind-abis/c-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/cdecl-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/fastcall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs2
-rw-r--r--src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs2
-rw-r--r--src/test/codegen/unwind-abis/nounwind.rs2
-rw-r--r--src/test/codegen/unwind-abis/stdcall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/system-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/sysv64-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/thiscall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/win64-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-extern-exports.rs2
-rw-r--r--src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs61
-rw-r--r--src/test/debuginfo/collapse-debuginfo-no-attr.rs60
-rw-r--r--src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs63
-rw-r--r--src/test/debuginfo/collapse-debuginfo-with-attr.rs59
-rw-r--r--src/test/debuginfo/generator-objects.rs13
-rw-r--r--src/test/debuginfo/msvc-pretty-enums.rs212
-rw-r--r--src/test/debuginfo/msvc-scalarpair-params.rs8
-rw-r--r--src/test/debuginfo/mutex.rs15
-rw-r--r--src/test/debuginfo/numeric-types.rs87
-rw-r--r--src/test/debuginfo/pretty-std.rs22
-rw-r--r--src/test/debuginfo/result-types.rs11
-rw-r--r--src/test/debuginfo/type-names.rs34
-rw-r--r--src/test/incremental/hashes/enum_defs.rs8
-rw-r--r--src/test/incremental/hashes/trait_defs.rs16
-rw-r--r--src/test/incremental/hygiene/load_cached_hygiene.rs2
-rw-r--r--src/test/incremental/issue-100521-change-struct-name-assocty.rs65
-rw-r--r--src/test/incremental/issue-49043.rs2
-rw-r--r--src/test/incremental/split_debuginfo_cached.rs4
-rw-r--r--src/test/incremental/split_debuginfo_mode.rs8
-rw-r--r--src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs2
-rw-r--r--src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs2
-rw-r--r--src/test/mir-opt/README.md12
-rw-r--r--src/test/mir-opt/array-index-is-temporary.rs2
-rw-r--r--src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir64
-rw-r--r--src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir (renamed from src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir)0
-rw-r--r--src/test/mir-opt/asm_unwind_panic_abort.rs1
-rw-r--r--src/test/mir-opt/bool_compare.rs2
-rw-r--r--src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff77
-rw-r--r--src/test/mir-opt/combine_array_len.norm2.InstCombine.diff (renamed from src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff)0
-rw-r--r--src/test/mir-opt/combine_array_len.rs2
-rw-r--r--src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff74
-rw-r--r--src/test/mir-opt/const_goto.rs2
-rw-r--r--src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff2
-rw-r--r--src/test/mir-opt/const_goto_storage.rs2
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff6
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir2
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff6
-rw-r--r--src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/aggregate.rs1
-rw-r--r--src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff7
-rw-r--r--src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff7
-rw-r--r--src/test/mir-opt/const_prop/array_index.rs1
-rw-r--r--src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff10
-rw-r--r--src/test/mir-opt/const_prop/bad_op_div_by_zero.rs1
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff2
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff2
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.rs1
-rw-r--r--src/test/mir-opt/const_prop/boxes.main.ConstProp.diff13
-rw-r--r--src/test/mir-opt/const_prop/boxes.rs1
-rw-r--r--src/test/mir-opt/const_prop/cast.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/cast.rs1
-rw-r--r--src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/checked_add.rs1
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs1
-rw-r--r--src/test/mir-opt/const_prop/control-flow-simplification.rs7
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff2
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff2
-rw-r--r--src/test/mir-opt/const_prop/discriminant.rs1
-rw-r--r--src/test/mir-opt/const_prop/indirect.main.ConstProp.diff4
-rw-r--r--src/test/mir-opt/const_prop/indirect.rs1
-rw-r--r--src/test/mir-opt/const_prop/issue-66971.rs1
-rw-r--r--src/test/mir-opt/const_prop/issue-67019.rs1
-rw-r--r--src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.rs1
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable.rs1
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate.rs1
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs1
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs1
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.rs1
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff5
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs1
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.rs1
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff4
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.rs1
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff2
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff4
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.rs1
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff2
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff2
-rw-r--r--src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff2
-rw-r--r--src/test/mir-opt/deaggregator_test.rs2
-rw-r--r--src/test/mir-opt/deaggregator_test_enum.rs2
-rw-r--r--src/test/mir-opt/deaggregator_test_enum_2.rs1
-rw-r--r--src/test/mir-opt/deaggregator_test_multiple.rs1
-rw-r--r--src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff89
-rw-r--r--src/test/mir-opt/deduplicate_blocks.rs2
-rw-r--r--src/test/mir-opt/derefer_complex_case.main.Derefer.diff12
-rw-r--r--src/test/mir-opt/derefer_complex_case.rs1
-rw-r--r--src/test/mir-opt/derefer_inline_test.main.Derefer.diff4
-rw-r--r--src/test/mir-opt/derefer_inline_test.rs1
-rw-r--r--src/test/mir-opt/derefer_terminator_test.main.Derefer.diff11
-rw-r--r--src/test/mir-opt/derefer_terminator_test.rs1
-rw-r--r--src/test/mir-opt/derefer_test.main.Derefer.diff4
-rw-r--r--src/test/mir-opt/derefer_test.rs1
-rw-r--r--src/test/mir-opt/derefer_test_multiple.main.Derefer.diff12
-rw-r--r--src/test/mir-opt/derefer_test_multiple.rs1
-rw-r--r--src/test/mir-opt/dest-prop/union.rs2
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.rs5
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff344
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff36
-rw-r--r--src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff2
-rw-r--r--src/test/mir-opt/enum_cast.bar.mir_map.0.mir10
-rw-r--r--src/test/mir-opt/enum_cast.boo.mir_map.0.mir10
-rw-r--r--src/test/mir-opt/enum_cast.droppy.mir_map.0.mir40
-rw-r--r--src/test/mir-opt/enum_cast.foo.mir_map.0.mir10
-rw-r--r--src/test/mir-opt/equal_true.rs2
-rw-r--r--src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir16
-rw-r--r--src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir30
-rw-r--r--src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir62
-rw-r--r--src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir28
-rw-r--r--src/test/mir-opt/inline/cycle.g.Inline.diff28
-rw-r--r--src/test/mir-opt/inline/cycle.main.Inline.diff50
-rw-r--r--src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff30
-rw-r--r--src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff12
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place.rs2
-rw-r--r--src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir22
-rw-r--r--src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir8
-rw-r--r--src/test/mir-opt/inline/inline_cycle.one.Inline.diff2
-rw-r--r--src/test/mir-opt/inline/inline_cycle.two.Inline.diff30
-rw-r--r--src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff2
-rw-r--r--src/test/mir-opt/inline/inline_diverging.f.Inline.diff2
-rw-r--r--src/test/mir-opt/inline/inline_diverging.h.Inline.diff34
-rw-r--r--src/test/mir-opt/inline/inline_generator.main.Inline.diff90
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff86
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff (renamed from src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff)42
-rw-r--r--src/test/mir-opt/inline/inline_options.main.Inline.after.mir24
-rw-r--r--src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir30
-rw-r--r--src/test/mir-opt/inline/inline_specialization.main.Inline.diff2
-rw-r--r--src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir12
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir4
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir4
-rw-r--r--src/test/mir-opt/inline/polymorphic-recursion.rs25
-rw-r--r--src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff2
-rw-r--r--src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff12
-rw-r--r--src/test/mir-opt/instrument_coverage.rs1
-rw-r--r--src/test/mir-opt/issue-101867.rs9
-rw-r--r--src/test/mir-opt/issue-101973.rs20
-rw-r--r--src/test/mir-opt/issue-41697.rs2
-rw-r--r--src/test/mir-opt/issue-72181.rs4
-rw-r--r--src/test/mir-opt/issue-73223.rs3
-rw-r--r--src/test/mir-opt/issue-91633.rs31
-rw-r--r--src/test/mir-opt/issue_101867.main.mir_map.0.mir75
-rw-r--r--src/test/mir-opt/issue_101973.inner.ConstProp.diff100
-rw-r--r--src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir20
-rw-r--r--src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir (renamed from src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir)0
-rw-r--r--src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir17
-rw-r--r--src/test/mir-opt/issue_72181.bar.mir_map.0.mir (renamed from src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir)0
-rw-r--r--src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir27
-rw-r--r--src/test/mir-opt/issue_72181.foo.mir_map.0.mir (renamed from src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir)0
-rw-r--r--src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir62
-rw-r--r--src/test/mir-opt/issue_72181.main.mir_map.0.mir (renamed from src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir)0
-rw-r--r--src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff117
-rw-r--r--src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff117
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff157
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff (renamed from src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff)14
-rw-r--r--src/test/mir-opt/issue_91633.bar.mir_map.0.mir39
-rw-r--r--src/test/mir-opt/issue_91633.foo.mir_map.0.mir57
-rw-r--r--src/test/mir-opt/issue_91633.fun.mir_map.0.mir35
-rw-r--r--src/test/mir-opt/issue_91633.hey.mir_map.0.mir35
-rw-r--r--src/test/mir-opt/issue_99325.main.mir_map.0.mir2
-rw-r--r--src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir4
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff66
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff70
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff79
-rw-r--r--src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff93
-rw-r--r--src/test/mir-opt/lower_array_len.array_len.InstCombine.diff27
-rw-r--r--src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff26
-rw-r--r--src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/lower_array_len.rs11
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir49
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir62
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir11
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir11
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.rs39
-rw-r--r--src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff2
-rw-r--r--src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff26
-rw-r--r--src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff26
-rw-r--r--src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff72
-rw-r--r--src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff2
-rw-r--r--src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff2
-rw-r--r--src/test/mir-opt/lower_intrinsics.rs54
-rw-r--r--src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff2
-rw-r--r--src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff2
-rw-r--r--src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff6
-rw-r--r--src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir (renamed from src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir)38
-rw-r--r--src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir (renamed from src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir)34
-rw-r--r--src/test/mir-opt/lower_intrinsics_e2e.rs32
-rw-r--r--src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir2
-rw-r--r--src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff88
-rw-r--r--src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff (renamed from src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff)4
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff30
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff30
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff55
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir10
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir10
-rw-r--r--src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff42
-rw-r--r--src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff42
-rw-r--r--src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff113
-rw-r--r--src/test/mir-opt/matches_reduce_branches.rs5
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff28
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff (renamed from src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff)12
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff28
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff (renamed from src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff)12
-rw-r--r--src/test/mir-opt/matches_u8.rs4
-rw-r--r--src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir27
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir23
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir23
-rw-r--r--src/test/mir-opt/not_equal_false.rs1
-rw-r--r--src/test/mir-opt/packed-struct-drop-aligned.rs2
-rw-r--r--src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir55
-rw-r--r--src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir (renamed from src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir)15
-rw-r--r--src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff50
-rw-r--r--src/test/mir-opt/remove_storage_markers.rs2
-rw-r--r--src/test/mir-opt/remove_zsts_dont_touch_unions.rs2
-rw-r--r--src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir16
-rw-r--r--src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir25
-rw-r--r--src/test/mir-opt/retag.rs1
-rw-r--r--src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.ConstProp.diff145
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir127
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff35
-rw-r--r--src/test/mir-opt/separate_const_switch.rs4
-rw-r--r--src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff95
-rw-r--r--src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir69
-rw-r--r--src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff43
-rw-r--r--src/test/mir-opt/simple-match.rs2
-rw-r--r--src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir29
-rw-r--r--src/test/mir-opt/simple_match.match_bool.mir_map.0.mir (renamed from src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir)0
-rw-r--r--src/test/mir-opt/simplify-arm-identity.rs3
-rw-r--r--src/test/mir-opt/simplify-arm.rs3
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-consts.rs1
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs3
-rw-r--r--src/test/mir-opt/simplify-locals.rs2
-rw-r--r--src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff46
-rw-r--r--src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff46
-rw-r--r--src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff58
-rw-r--r--src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff58
-rw-r--r--src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff12
-rw-r--r--src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff12
-rw-r--r--src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff61
-rw-r--r--src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff61
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff54
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff39
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff (renamed from src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff)29
-rw-r--r--src/test/mir-opt/simplify_try.rs30
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff22
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff18
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir18
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir14
-rw-r--r--src/test/mir-opt/slice-drop-shim.rs2
-rw-r--r--src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir101
-rw-r--r--src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir (renamed from src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir)0
-rw-r--r--src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir2
-rw-r--r--src/test/mir-opt/storage_ranges.main.nll.0.mir11
-rw-r--r--src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir96
-rw-r--r--src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir53
-rw-r--r--src/test/mir-opt/try_identity_e2e.rs34
-rw-r--r--src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir8
-rw-r--r--src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir2
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir24
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff34
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir28
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff48
-rw-r--r--src/test/mir-opt/unreachable.main.UnreachablePropagation.diff9
-rw-r--r--src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff25
-rw-r--r--src/test/mir-opt/unusual-item-types.rs2
-rw-r--r--src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir10
-rw-r--r--src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir (renamed from src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir)0
-rw-r--r--src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir12
-rw-r--r--src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir (renamed from src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir)0
-rw-r--r--src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir39
-rw-r--r--src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir (renamed from src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir)0
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir10
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir (renamed from src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir)2
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff55
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff (renamed from src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff)0
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir17
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir (renamed from src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir)0
-rw-r--r--src/test/mir-opt/while_let_loops.rs1
-rw-r--r--src/test/pretty/gat-bounds.rs2
-rw-r--r--src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile2
-rw-r--r--src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile2
-rw-r--r--src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile2
-rw-r--r--src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile2
-rw-r--r--src/test/run-make-fulldeps/archive-duplicate-names/Makefile2
-rw-r--r--src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile2
-rw-r--r--src/test/run-make-fulldeps/atomic-lock-free/Makefile2
-rw-r--r--src/test/run-make-fulldeps/bare-outfile/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-dynamic-dylib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-dynamic-rlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-static-dylib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-static-rlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile2
-rw-r--r--src/test/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile2
-rw-r--r--src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile2
-rw-r--r--src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile2
-rw-r--r--src/test/run-make-fulldeps/codegen-options-parsing/Makefile2
-rw-r--r--src/test/run-make-fulldeps/compile-stdin/Makefile2
-rw-r--r--src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile2
-rw-r--r--src/test/run-make-fulldeps/compiler-lookup-paths/Makefile2
-rw-r--r--src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile2
-rw-r--r--src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile2
-rw-r--r--src/test/run-make-fulldeps/crate-data-smoke/Makefile2
-rw-r--r--src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile2
-rw-r--r--src/test/run-make-fulldeps/crate-name-priority/Makefile2
-rw-r--r--src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile2
-rw-r--r--src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile2
-rw-r--r--src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile2
-rw-r--r--src/test/run-make-fulldeps/cross-lang-lto/Makefile2
-rw-r--r--src/test/run-make-fulldeps/debug-assertions/Makefile2
-rw-r--r--src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile2
-rw-r--r--src/test/run-make-fulldeps/dep-info-spaces/Makefile2
-rw-r--r--src/test/run-make-fulldeps/dep-info/Makefile2
-rw-r--r--src/test/run-make-fulldeps/dylib-chain/Makefile2
-rw-r--r--src/test/run-make-fulldeps/emit-stack-sizes/Makefile2
-rw-r--r--src/test/run-make-fulldeps/emit/Makefile2
-rw-r--r--src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile2
-rw-r--r--src/test/run-make-fulldeps/error-writing-dependencies/Makefile2
-rw-r--r--src/test/run-make-fulldeps/exit-code/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-diff-internal-name/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-flag-rename-transitive/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-generic/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-mangle/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-reachable/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-fn-with-union/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-multiple-copies/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-multiple-copies2/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extern-overrides-distribution/Makefile2
-rw-r--r--src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile2
-rw-r--r--src/test/run-make-fulldeps/foreign-double-unwind/Makefile2
-rw-r--r--src/test/run-make-fulldeps/foreign-exceptions/Makefile2
-rw-r--r--src/test/run-make-fulldeps/fpic/Makefile2
-rw-r--r--src/test/run-make-fulldeps/glibc-staticlib-args/Makefile2
-rw-r--r--src/test/run-make-fulldeps/hir-tree/Makefile2
-rw-r--r--src/test/run-make-fulldeps/include_bytes_deps/Makefile2
-rw-r--r--src/test/run-make-fulldeps/incr-add-rust-src-component/Makefile2
-rw-r--r--src/test/run-make-fulldeps/inline-always-many-cgu/Makefile2
-rw-r--r--src/test/run-make-fulldeps/interdependent-c-libraries/Makefile2
-rw-r--r--src/test/run-make-fulldeps/intrinsic-unreachable/Makefile2
-rw-r--r--src/test/run-make-fulldeps/invalid-library/Makefile2
-rw-r--r--src/test/run-make-fulldeps/invalid-staticlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-11908/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-14500/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-14698/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-15460/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-18943/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-19371/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-20626/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-22131/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-24445/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-25581/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-26006/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-26092/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-28595/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-28766/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-30063/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-33329/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-35164/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-37839/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-37893/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-38237/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-40535/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-46239/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-47551/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-47551/eh_frame-terminator.rs1
-rw-r--r--src/test/run-make-fulldeps/issue-51671/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-53964/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-64153/Makefile4
-rw-r--r--src/test/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-69368/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-69368/a.rs5
-rw-r--r--src/test/run-make-fulldeps/issue-7349/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-97463-abi-param-passing/Makefile14
-rw-r--r--src/test/run-make-fulldeps/issue-97463-abi-param-passing/bad.c24
-rw-r--r--src/test/run-make-fulldeps/issue-97463-abi-param-passing/param_passing.rs38
-rw-r--r--src/test/run-make-fulldeps/issue64319/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issues-41478-43796/Makefile2
-rw-r--r--src/test/run-make-fulldeps/libs-through-symlinks/Makefile2
-rw-r--r--src/test/run-make-fulldeps/libtest-json/Makefile2
-rw-r--r--src/test/run-make-fulldeps/link-arg/Makefile2
-rw-r--r--src/test/run-make-fulldeps/link-args-order/Makefile2
-rw-r--r--src/test/run-make-fulldeps/link-cfg/Makefile2
-rw-r--r--src/test/run-make-fulldeps/link-dedup/Makefile2
-rw-r--r--src/test/run-make-fulldeps/link-path-order/Makefile2
-rw-r--r--src/test/run-make-fulldeps/linkage-attr-on-static/Makefile2
-rw-r--r--src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile2
-rw-r--r--src/test/run-make-fulldeps/long-linker-command-lines/Makefile2
-rw-r--r--src/test/run-make-fulldeps/longjmp-across-rust/Makefile2
-rw-r--r--src/test/run-make-fulldeps/ls-metadata/Makefile2
-rw-r--r--src/test/run-make-fulldeps/lto-dylib-dep/Makefile2
-rw-r--r--src/test/run-make-fulldeps/lto-empty/Makefile2
-rw-r--r--src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/lto-readonly-lib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/lto-smoke-c/Makefile2
-rw-r--r--src/test/run-make-fulldeps/lto-smoke/Makefile2
-rw-r--r--src/test/run-make-fulldeps/manual-crate-name/Makefile2
-rw-r--r--src/test/run-make-fulldeps/manual-link/Makefile2
-rw-r--r--src/test/run-make-fulldeps/many-crates-but-no-match/Makefile2
-rw-r--r--src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile2
-rw-r--r--src/test/run-make-fulldeps/min-global-align/Makefile2
-rw-r--r--src/test/run-make-fulldeps/mismatching-target-triples/Makefile2
-rw-r--r--src/test/run-make-fulldeps/missing-crate-dependency/Makefile2
-rw-r--r--src/test/run-make-fulldeps/mixing-deps/Makefile2
-rw-r--r--src/test/run-make-fulldeps/mixing-formats/Makefile2
-rw-r--r--src/test/run-make-fulldeps/mixing-libs/Makefile2
-rw-r--r--src/test/run-make-fulldeps/msvc-opt-minsize/Makefile2
-rw-r--r--src/test/run-make-fulldeps/multiple-emits/Makefile2
-rw-r--r--src/test/run-make-fulldeps/no-builtins-lto/Makefile2
-rw-r--r--src/test/run-make-fulldeps/no-duplicate-libs/Makefile2
-rw-r--r--src/test/run-make-fulldeps/no-intermediate-extras/Makefile2
-rw-r--r--src/test/run-make-fulldeps/obey-crate-type-flag/Makefile2
-rw-r--r--src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile2
-rw-r--r--src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile2
-rw-r--r--src/test/run-make-fulldeps/output-type-permutations/Makefile2
-rw-r--r--src/test/run-make-fulldeps/output-with-hyphens/Makefile2
-rw-r--r--src/test/run-make-fulldeps/override-aliased-flags/Makefile2
-rw-r--r--src/test/run-make-fulldeps/panic-impl-transitive/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pgo-branch-weights/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pgo-gen-lto/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pgo-gen/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pgo-use/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile2
-rw-r--r--src/test/run-make-fulldeps/prefer-dylib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/prefer-rlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pretty-expanded/Makefile2
-rw-r--r--src/test/run-make-fulldeps/pretty-print-to-file/Makefile2
-rw-r--r--src/test/run-make-fulldeps/print-cfg/Makefile2
-rw-r--r--src/test/run-make-fulldeps/print-target-list/Makefile2
-rw-r--r--src/test/run-make-fulldeps/profile/Makefile2
-rw-r--r--src/test/run-make-fulldeps/prune-link-args/Makefile2
-rw-r--r--src/test/run-make-fulldeps/redundant-libs/Makefile2
-rw-r--r--src/test/run-make-fulldeps/relocation-model/Makefile2
-rw-r--r--src/test/run-make-fulldeps/relro-levels/Makefile2
-rw-r--r--src/test/run-make-fulldeps/remap-path-prefix/Makefile2
-rw-r--r--src/test/run-make-fulldeps/reproducible-build-2/Makefile2
-rw-r--r--src/test/run-make-fulldeps/reproducible-build/Makefile2
-rw-r--r--src/test/run-make-fulldeps/resolve-rename/Makefile2
-rw-r--r--src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile2
-rw-r--r--src/test/run-make-fulldeps/return-non-c-like-enum/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rlib-chain/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-determinism/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-error-lines/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-io-error/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-map-file/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-output-path/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile2
-rw-r--r--src/test/run-make-fulldeps/rustdoc-themes/Makefile2
-rw-r--r--src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile2
-rw-r--r--src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile2
-rw-r--r--src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile2
-rw-r--r--src/test/run-make-fulldeps/save-analysis-fail/Makefile2
-rw-r--r--src/test/run-make-fulldeps/save-analysis-fail/foo.rs15
-rw-r--r--src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile2
-rw-r--r--src/test/run-make-fulldeps/save-analysis/Makefile2
-rw-r--r--src/test/run-make-fulldeps/save-analysis/foo.rs15
-rw-r--r--src/test/run-make-fulldeps/separate-link-fail/Makefile2
-rw-r--r--src/test/run-make-fulldeps/separate-link/Makefile2
-rw-r--r--src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile2
-rw-r--r--src/test/run-make-fulldeps/sepcomp-inlining/Makefile2
-rw-r--r--src/test/run-make-fulldeps/sepcomp-separate/Makefile2
-rw-r--r--src/test/run-make-fulldeps/share-generics-dylib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/simd-ffi/Makefile2
-rw-r--r--src/test/run-make-fulldeps/simple-dylib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/simple-rlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/split-debuginfo/Makefile41
-rw-r--r--src/test/run-make-fulldeps/stable-symbol-names/Makefile2
-rw-r--r--src/test/run-make-fulldeps/static-dylib-by-default/Makefile2
-rw-r--r--src/test/run-make-fulldeps/static-extern-type/Makefile2
-rw-r--r--src/test/run-make-fulldeps/static-unwinding/Makefile2
-rw-r--r--src/test/run-make-fulldeps/staticlib-blank-lib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/std-core-cycle/Makefile2
-rw-r--r--src/test/run-make-fulldeps/stdin-non-utf8/Makefile2
-rw-r--r--src/test/run-make-fulldeps/suspicious-library/Makefile2
-rw-r--r--src/test/run-make-fulldeps/symbols-include-type-name/Makefile2
-rw-r--r--src/test/run-make-fulldeps/symlinked-extern/Makefile2
-rw-r--r--src/test/run-make-fulldeps/symlinked-libraries/Makefile2
-rw-r--r--src/test/run-make-fulldeps/symlinked-rlib/Makefile2
-rw-r--r--src/test/run-make-fulldeps/target-cpu-native/Makefile2
-rw-r--r--src/test/run-make-fulldeps/target-specs/Makefile2
-rw-r--r--src/test/run-make-fulldeps/target-without-atomic-cas/Makefile2
-rw-r--r--src/test/run-make-fulldeps/test-harness/Makefile2
-rw-r--r--src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile2
-rw-r--r--src/test/run-make-fulldeps/use-extern-for-plugins/Makefile2
-rw-r--r--src/test/run-make-fulldeps/use-suggestions-rust-2018/Makefile2
-rw-r--r--src/test/run-make-fulldeps/used-cdylib-macos/Makefile2
-rw-r--r--src/test/run-make-fulldeps/used/Makefile2
-rw-r--r--src/test/run-make-fulldeps/version/Makefile2
-rw-r--r--src/test/run-make-fulldeps/volatile-intrinsics/Makefile2
-rw-r--r--src/test/run-make-fulldeps/weird-output-filenames/Makefile2
-rw-r--r--src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile2
-rw-r--r--src/test/run-make-fulldeps/windows-spawn/Makefile2
-rw-r--r--src/test/run-make-fulldeps/windows-subsystem/Makefile2
-rw-r--r--src/test/run-make/const_fn_mir/Makefile2
-rw-r--r--src/test/run-make/coverage-llvmir/filecheck.testprog.txt2
-rw-r--r--src/test/run-make/coverage-reports/Makefile6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.async.txt2
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.closure.txt16
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.generator.txt2
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt2
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt5
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt4
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.yield.txt4
-rw-r--r--src/test/run-make/coverage/async.rs2
-rw-r--r--src/test/run-make/dep-graph/Makefile2
-rw-r--r--src/test/run-make/emit-named-files/Makefile2
-rw-r--r--src/test/run-make/emit-path-unhashed/Makefile2
-rw-r--r--src/test/run-make/emit-shared-files/Makefile2
-rw-r--r--src/test/run-make/env-dep-info/Makefile2
-rw-r--r--src/test/run-make/export-executable-symbols/Makefile2
-rw-r--r--src/test/run-make/fmt-write-bloat/Makefile2
-rw-r--r--src/test/run-make/issue-10971-temps-dir/Makefile2
-rw-r--r--src/test/run-make/issue-47384/Makefile2
-rw-r--r--src/test/run-make/issue-71519/Makefile3
-rw-r--r--src/test/run-make/issue-85401-static-mir/Makefile16
-rw-r--r--src/test/run-make/issue-85401-static-mir/bar.rs4
-rw-r--r--src/test/run-make/issue-85401-static-mir/baz.rs3
-rw-r--r--src/test/run-make/issue-85401-static-mir/foo.rs5
-rw-r--r--src/test/run-make/issue-85441/Makefile2
-rw-r--r--src/test/run-make/issue-88756-default-output/Makefile2
-rw-r--r--src/test/run-make/issue-96498/Makefile2
-rw-r--r--src/test/run-make/libtest-thread-limit/Makefile2
-rw-r--r--src/test/run-make/llvm-outputs/Makefile2
-rw-r--r--src/test/run-make/native-link-modifier-bundle/Makefile2
-rw-r--r--src/test/run-make/native-link-modifier-whole-archive/Makefile2
-rw-r--r--src/test/run-make/pass-linker-flags-from-dep/Makefile2
-rw-r--r--src/test/run-make/pass-linker-flags/Makefile2
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/Makefile2
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/extern.c15
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/lib.rs11
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/output.msvc.txt1
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/output.txt2
-rw-r--r--src/test/run-make/raw-dylib-c/Makefile2
-rw-r--r--src/test/run-make/raw-dylib-c/extern_1.c12
-rw-r--r--src/test/run-make/raw-dylib-c/lib.rs13
-rw-r--r--src/test/run-make/raw-dylib-c/output.txt3
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/Makefile22
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/driver.rs125
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.c103
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.gnu.def21
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.msvc.def25
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/output.txt19
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/Makefile31
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs21
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c11
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c6
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs21
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs6
-rw-r--r--src/test/run-make/raw-dylib-inline-cross-dylib/output.txt6
-rw-r--r--src/test/run-make/raw-dylib-link-ordinal/Makefile2
-rw-r--r--src/test/run-make/raw-dylib-link-ordinal/exporter.c7
-rw-r--r--src/test/run-make/raw-dylib-link-ordinal/exporter.def2
-rw-r--r--src/test/run-make/raw-dylib-link-ordinal/lib.rs10
-rw-r--r--src/test/run-make/raw-dylib-link-ordinal/output.txt2
-rw-r--r--src/test/run-make/raw-dylib-stdcall-ordinal/Makefile2
-rw-r--r--src/test/run-make/raw-dylib-stdcall-ordinal/lib.rs2
-rw-r--r--src/test/run-make/remap-path-prefix-dwarf/Makefile2
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile22
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs5
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs4
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs11
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/Makefile34
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/main.rs4
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs13
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs13
-rw-r--r--src/test/run-make/rustc-macro-dep-files/Makefile2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-multiple/Makefile2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-ordering/Makefile2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-remap/Makefile2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/Makefile2
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-whitespace/Makefile2
-rw-r--r--src/test/run-make/rustdoc-with-out-dir-option/Makefile2
-rw-r--r--src/test/run-make/rustdoc-with-output-option/Makefile2
-rw-r--r--src/test/run-make/rustdoc-with-short-out-dir-option/Makefile2
-rw-r--r--src/test/run-make/static-pie/Makefile2
-rw-r--r--src/test/run-make/thumb-none-cortex-m/Makefile2
-rw-r--r--src/test/run-make/thumb-none-qemu/Makefile2
-rw-r--r--src/test/run-make/track-path-dep-info/Makefile2
-rw-r--r--src/test/run-make/track-pgo-dep-info/Makefile26
-rw-r--r--src/test/run-make/track-pgo-dep-info/main.rs1
-rw-r--r--src/test/run-make/translation/Makefile25
-rw-r--r--src/test/run-make/translation/basic-translation.ftl2
-rw-r--r--src/test/run-make/translation/broken.ftl3
-rw-r--r--src/test/run-make/translation/missing.ftl3
-rw-r--r--src/test/run-make/translation/test.rs (renamed from src/test/run-make/translation/basic-translation.rs)0
-rw-r--r--src/test/run-make/translation/working.ftl2
-rw-r--r--src/test/run-make/unstable-flag-required/Makefile2
-rw-r--r--src/test/run-make/wasm-abi/Makefile2
-rw-r--r--src/test/run-make/wasm-custom-section/Makefile2
-rw-r--r--src/test/run-make/wasm-custom-sections-opt/Makefile2
-rw-r--r--src/test/run-make/wasm-export-all-symbols/Makefile2
-rw-r--r--src/test/run-make/wasm-import-module/Makefile2
-rw-r--r--src/test/run-make/wasm-panic-small/Makefile2
-rw-r--r--src/test/run-make/wasm-spurious-import/Makefile2
-rw-r--r--src/test/run-make/wasm-stringify-ints-small/Makefile2
-rw-r--r--src/test/run-make/wasm-symbols-different-module/Makefile2
-rw-r--r--src/test/run-make/wasm-symbols-not-exported/Makefile2
-rw-r--r--src/test/run-make/wasm-symbols-not-imported/Makefile2
-rw-r--r--src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile2
-rw-r--r--src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh2
-rw-r--r--src/test/run-pass-valgrind/cast-enum-with-dtor.rs2
-rw-r--r--src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs4
-rw-r--r--src/test/run-pass-valgrind/coerce-match.rs15
-rw-r--r--src/test/rustdoc-gui/anchors.goml128
-rw-r--r--src/test/rustdoc-gui/check_info_sign_position.goml8
-rw-r--r--src/test/rustdoc-gui/code-tags.goml4
-rw-r--r--src/test/rustdoc-gui/codeblock-tooltip.goml96
-rw-r--r--src/test/rustdoc-gui/docblock-table-overflow.goml4
-rw-r--r--src/test/rustdoc-gui/docblock-table.goml4
-rw-r--r--src/test/rustdoc-gui/headings.goml6
-rw-r--r--src/test/rustdoc-gui/item-info-alignment.goml10
-rw-r--r--src/test/rustdoc-gui/item-summary-table.goml2
-rw-r--r--src/test/rustdoc-gui/label-next-to-symbol.goml26
-rw-r--r--src/test/rustdoc-gui/links-color.goml85
-rw-r--r--src/test/rustdoc-gui/overflow-tooltip-information.goml2
-rw-r--r--src/test/rustdoc-gui/pocket-menu.goml4
-rw-r--r--src/test/rustdoc-gui/search-filter.goml18
-rw-r--r--src/test/rustdoc-gui/search-form-elements.goml243
-rw-r--r--src/test/rustdoc-gui/search-input.goml23
-rw-r--r--src/test/rustdoc-gui/search-result-color.goml204
-rw-r--r--src/test/rustdoc-gui/search-result-display.goml31
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile-scroll.goml31
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code-display.goml15
-rw-r--r--src/test/rustdoc-gui/src/lib2/lib.rs40
-rw-r--r--src/test/rustdoc-gui/src/staged_api/Cargo.toml3
-rw-r--r--src/test/rustdoc-gui/src/staged_api/lib.rs2
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs32
-rw-r--r--src/test/rustdoc-gui/toggle-click-deadspace.goml5
-rw-r--r--src/test/rustdoc-gui/type-declation-overflow.goml4
-rw-r--r--src/test/rustdoc-gui/where-whitespace.goml27
-rw-r--r--src/test/rustdoc-json/assoc_items.rs32
-rw-r--r--src/test/rustdoc-json/assoc_type.rs9
-rw-r--r--src/test/rustdoc-json/blanket_impls.rs7
-rw-r--r--src/test/rustdoc-json/doc_hidden_failure.rs2
-rw-r--r--src/test/rustdoc-json/enums/discriminant/basic.rs12
-rw-r--r--src/test/rustdoc-json/enums/discriminant/expr.rs39
-rw-r--r--src/test/rustdoc-json/enums/discriminant/limits.rs43
-rw-r--r--src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs15
-rw-r--r--src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs10
-rw-r--r--src/test/rustdoc-json/enums/field_hidden.rs13
-rw-r--r--src/test/rustdoc-json/enums/kind.rs37
-rw-r--r--src/test/rustdoc-json/enums/struct_field_hidden.rs17
-rw-r--r--src/test/rustdoc-json/enums/tuple_fields_hidden.rs94
-rw-r--r--src/test/rustdoc-json/enums/variant_struct.rs10
-rw-r--r--src/test/rustdoc-json/enums/variant_tuple_struct.rs10
-rw-r--r--src/test/rustdoc-json/fn_pointer/abi.rs14
-rw-r--r--src/test/rustdoc-json/fn_pointer/generics.rs16
-rw-r--r--src/test/rustdoc-json/fn_pointer/qualifiers.rs12
-rw-r--r--src/test/rustdoc-json/fns/abi.rs14
-rw-r--r--src/test/rustdoc-json/fns/async_return.rs36
-rw-r--r--src/test/rustdoc-json/fns/generic_args.rs96
-rw-r--r--src/test/rustdoc-json/fns/generic_returns.rs12
-rw-r--r--src/test/rustdoc-json/fns/generics.rs32
-rw-r--r--src/test/rustdoc-json/fns/qualifiers.rs36
-rw-r--r--src/test/rustdoc-json/generic-associated-types/gats.rs42
-rw-r--r--src/test/rustdoc-json/generic_impl.rs7
-rw-r--r--src/test/rustdoc-json/glob_import.rs5
-rw-r--r--src/test/rustdoc-json/impls/auto.rs18
-rw-r--r--src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs1
-rw-r--r--src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs1
-rw-r--r--src/test/rustdoc-json/impls/blanket_with_local.rs8
-rw-r--r--src/test/rustdoc-json/impls/foreign_for_local.rs18
-rw-r--r--src/test/rustdoc-json/impls/import_from_private.rs22
-rw-r--r--src/test/rustdoc-json/impls/local_for_foreign.rs18
-rw-r--r--src/test/rustdoc-json/impls/local_for_local.rs15
-rw-r--r--src/test/rustdoc-json/impls/local_for_local_primitive.rs21
-rw-r--r--src/test/rustdoc-json/impls/local_for_primitive.rs7
-rw-r--r--src/test/rustdoc-json/intra-doc-links/non_page.rs34
-rw-r--r--src/test/rustdoc-json/intra-doc-links/user_written.rs8
-rw-r--r--src/test/rustdoc-json/keyword.rs9
-rw-r--r--src/test/rustdoc-json/lifetime/longest.rs40
-rw-r--r--src/test/rustdoc-json/lifetime/outlives.rs34
-rw-r--r--src/test/rustdoc-json/methods/abi.rs30
-rw-r--r--src/test/rustdoc-json/methods/qualifiers.rs36
-rw-r--r--src/test/rustdoc-json/nested.rs39
-rw-r--r--src/test/rustdoc-json/output_generics.rs11
-rw-r--r--src/test/rustdoc-json/primitive.rs18
-rw-r--r--src/test/rustdoc-json/primitive_overloading.rs5
-rw-r--r--src/test/rustdoc-json/primitives.rs22
-rw-r--r--src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs11
-rw-r--r--src/test/rustdoc-json/reexport/glob_collision.rs28
-rw-r--r--src/test/rustdoc-json/reexport/glob_empty_mod.rs8
-rw-r--r--src/test/rustdoc-json/reexport/glob_extern.rs15
-rw-r--r--src/test/rustdoc-json/reexport/glob_private.rs25
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod.rs9
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs16
-rw-r--r--src/test/rustdoc-json/reexport/macro.rs10
-rw-r--r--src/test/rustdoc-json/reexport/mod_not_included.rs14
-rw-r--r--src/test/rustdoc-json/reexport/private_twice_one_inline.rs18
-rw-r--r--src/test/rustdoc-json/reexport/private_two_names.rs17
-rw-r--r--src/test/rustdoc-json/reexport/rename_private.rs7
-rw-r--r--src/test/rustdoc-json/reexport/rename_public.rs16
-rw-r--r--src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs18
-rw-r--r--src/test/rustdoc-json/reexport/simple_private.rs11
-rw-r--r--src/test/rustdoc-json/reexport/simple_public.rs14
-rw-r--r--src/test/rustdoc-json/return_private.rs4
-rw-r--r--src/test/rustdoc-json/stripped_modules.rs10
-rw-r--r--src/test/rustdoc-json/structs/plain_all_pub.rs11
-rw-r--r--src/test/rustdoc-json/structs/plain_doc_hidden.rs11
-rw-r--r--src/test/rustdoc-json/structs/plain_empty.rs9
-rw-r--r--src/test/rustdoc-json/structs/plain_pub_priv.rs9
-rw-r--r--src/test/rustdoc-json/structs/tuple.rs7
-rw-r--r--src/test/rustdoc-json/structs/tuple_empty.rs2
-rw-r--r--src/test/rustdoc-json/structs/tuple_pub_priv.rs13
-rw-r--r--src/test/rustdoc-json/structs/unit.rs7
-rw-r--r--src/test/rustdoc-json/structs/with_generics.rs16
-rw-r--r--src/test/rustdoc-json/structs/with_primitives.rs12
-rw-r--r--src/test/rustdoc-json/traits/has_body.rs16
-rw-r--r--src/test/rustdoc-json/traits/implementors.rs14
-rw-r--r--src/test/rustdoc-json/traits/supertrait.rs22
-rw-r--r--src/test/rustdoc-json/traits/uses_extern_trait.rs7
-rw-r--r--src/test/rustdoc-json/type/dyn.rs59
-rw-r--r--src/test/rustdoc-json/type/extern.rs10
-rw-r--r--src/test/rustdoc-json/type/fn_lifetime.rs41
-rw-r--r--src/test/rustdoc-json/type/generic_default.rs46
-rw-r--r--src/test/rustdoc-json/type/hrtb.rs24
-rw-r--r--src/test/rustdoc-json/unions/impl.rs10
-rw-r--r--src/test/rustdoc-json/unions/union.rs14
-rw-r--r--src/test/rustdoc-ui/check-fail.rs1
-rw-r--r--src/test/rustdoc-ui/check-fail.stderr12
-rw-r--r--src/test/rustdoc-ui/check.rs4
-rw-r--r--src/test/rustdoc-ui/check.stderr18
-rw-r--r--src/test/rustdoc-ui/doc-without-codeblock.rs3
-rw-r--r--src/test/rustdoc-ui/doc-without-codeblock.stderr12
-rw-r--r--src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs10
-rw-r--r--src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr29
-rw-r--r--src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr12
-rw-r--r--src/test/rustdoc-ui/invalid-html-tags.rs7
-rw-r--r--src/test/rustdoc-ui/invalid-html-tags.stderr8
-rw-r--r--src/test/rustdoc-ui/issue-101076.rs14
-rw-r--r--src/test/rustdoc-ui/lint-group.rs2
-rw-r--r--src/test/rustdoc-ui/lint-group.stderr12
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.rs1
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.stderr12
-rw-r--r--src/test/rustdoc-ui/normalize-cycle.rs2
-rw-r--r--src/test/rustdoc-ui/rustc-check-passes.rs4
-rw-r--r--src/test/rustdoc-ui/rustc-check-passes.stderr6
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs42
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr48
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics.fixed40
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics.rs40
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics.stderr90
-rw-r--r--src/test/rustdoc-ui/z-help.stdout3
-rw-r--r--src/test/rustdoc/all.rs2
-rw-r--r--src/test/rustdoc/anchors.no_const_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_const_anchor2.html2
-rw-r--r--src/test/rustdoc/anchors.no_method_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_trait_method_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_tymethod_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_type_anchor.html2
-rw-r--r--src/test/rustdoc/assoc-consts.rs8
-rw-r--r--src/test/rustdoc/auxiliary/incoherent-impl-types.rs7
-rw-r--r--src/test/rustdoc/cfg_doc_reexport.rs33
-rw-r--r--src/test/rustdoc/check-source-code-urls-to-def-std.rs8
-rw-r--r--src/test/rustdoc/check-source-code-urls-to-def.rs22
-rw-r--r--src/test/rustdoc/codeblock-title.rs6
-rw-r--r--src/test/rustdoc/const-display.rs6
-rw-r--r--src/test/rustdoc/const-generics/const-generics-docs.rs8
-rw-r--r--src/test/rustdoc/deprecated-impls.rs36
-rw-r--r--src/test/rustdoc/doc_auto_cfg_nested_impl.rs24
-rw-r--r--src/test/rustdoc/elided-lifetime.rs14
-rw-r--r--src/test/rustdoc/empty-impl-block-private-with-doc.rs44
-rw-r--r--src/test/rustdoc/empty-impl-block-private.rs40
-rw-r--r--src/test/rustdoc/empty-mod-private.rs6
-rw-r--r--src/test/rustdoc/empty-mod-public.rs6
-rw-r--r--src/test/rustdoc/empty-section.rs2
-rw-r--r--src/test/rustdoc/ensure-src-link.rs2
-rw-r--r--src/test/rustdoc/generic-associated-types/gats.rs5
-rw-r--r--src/test/rustdoc/generic-associated-types/issue-94683.rs5
-rw-r--r--src/test/rustdoc/glob-shadowing-const.rs20
-rw-r--r--src/test/rustdoc/glob-shadowing.rs86
-rw-r--r--src/test/rustdoc/hidden-impls.rs4
-rw-r--r--src/test/rustdoc/hidden-line.rs2
-rw-r--r--src/test/rustdoc/hidden-methods.rs8
-rw-r--r--src/test/rustdoc/hide-unstable-trait.rs4
-rw-r--r--src/test/rustdoc/higher-ranked-trait-bounds.rs8
-rw-r--r--src/test/rustdoc/impl-parts-crosscrate.rs8
-rw-r--r--src/test/rustdoc/impl-parts.rs4
-rw-r--r--src/test/rustdoc/impl-trait-alias.rs4
-rw-r--r--src/test/rustdoc/impossible-default.rs20
-rw-r--r--src/test/rustdoc/infinite-redirection.rs2
-rw-r--r--src/test/rustdoc/inline_cross/add-docs.rs2
-rw-r--r--src/test/rustdoc/inline_cross/assoc-items.rs4
-rw-r--r--src/test/rustdoc/inline_cross/hidden-use.rs4
-rw-r--r--src/test/rustdoc/inline_cross/proc_macro.rs12
-rw-r--r--src/test/rustdoc/inline_local/glob-extern-document-private-items.rs10
-rw-r--r--src/test/rustdoc/inline_local/glob-extern.rs6
-rw-r--r--src/test/rustdoc/inline_local/glob-private-document-private-items.rs26
-rw-r--r--src/test/rustdoc/inline_local/glob-private.rs12
-rw-r--r--src/test/rustdoc/inline_local/hidden-use.rs4
-rw-r--r--src/test/rustdoc/inline_local/macro_by_example.rs2
-rw-r--r--src/test/rustdoc/inline_local/please_inline.rs4
-rw-r--r--src/test/rustdoc/internal.rs10
-rw-r--r--src/test/rustdoc/intra-doc/assoc-reexport-super.rs20
-rw-r--r--src/test/rustdoc/intra-doc/extern-type.rs6
-rw-r--r--src/test/rustdoc/issue-100620.rs19
-rw-r--r--src/test/rustdoc/issue-100679-sidebar-links-deref.rs30
-rw-r--r--src/test/rustdoc/issue-101743-bold-tag.rs19
-rw-r--r--src/test/rustdoc/issue-16265-1.rs2
-rw-r--r--src/test/rustdoc/issue-16265-2.rs2
-rw-r--r--src/test/rustdoc/issue-20727-4.rs4
-rw-r--r--src/test/rustdoc/issue-21801.rs2
-rw-r--r--src/test/rustdoc/issue-23511.rs2
-rw-r--r--src/test/rustdoc/issue-23812.rs16
-rw-r--r--src/test/rustdoc/issue-27104.rs6
-rw-r--r--src/test/rustdoc/issue-27759.rs4
-rw-r--r--src/test/rustdoc/issue-29503.rs2
-rw-r--r--src/test/rustdoc/issue-29584.rs2
-rw-r--r--src/test/rustdoc/issue-31899.rs8
-rw-r--r--src/test/rustdoc/issue-32374.rs16
-rw-r--r--src/test/rustdoc/issue-32395.rs12
-rw-r--r--src/test/rustdoc/issue-34473.rs2
-rw-r--r--src/test/rustdoc/issue-34928.rs2
-rw-r--r--src/test/rustdoc/issue-41783.codeblock.html5
-rw-r--r--src/test/rustdoc/issue-41783.rs14
-rw-r--r--src/test/rustdoc/issue-50159.rs4
-rw-r--r--src/test/rustdoc/issue-51236.rs2
-rw-r--r--src/test/rustdoc/issue-53689.rs2
-rw-r--r--src/test/rustdoc/issue-54705.rs6
-rw-r--r--src/test/rustdoc/issue-61592.rs4
-rw-r--r--src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs16
-rw-r--r--src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs16
-rw-r--r--src/test/rustdoc/issue-89852.rs4
-rw-r--r--src/test/rustdoc/issue-98697.rs2
-rw-r--r--src/test/rustdoc/link-title-escape.rs2
-rw-r--r--src/test/rustdoc/macro-document-private-duplicate.rs10
-rw-r--r--src/test/rustdoc/macro-private-not-documented.rs4
-rw-r--r--src/test/rustdoc/macro_rules-matchers.rs29
-rw-r--r--src/test/rustdoc/markdown-summaries.rs12
-rw-r--r--src/test/rustdoc/masked.rs14
-rw-r--r--src/test/rustdoc/module-impls.rs2
-rw-r--r--src/test/rustdoc/nested-modules.rs14
-rw-r--r--src/test/rustdoc/no-crate-filter.rs2
-rw-r--r--src/test/rustdoc/primitive-reference.rs37
-rw-r--r--src/test/rustdoc/primitive-slice-auto-trait.rs4
-rw-r--r--src/test/rustdoc/recursive-deref.rs8
-rw-r--r--src/test/rustdoc/remove-url-from-headings.rs2
-rw-r--r--src/test/rustdoc/rustc-incoherent-impls.rs28
-rw-r--r--src/test/rustdoc/search-index-summaries.rs6
-rw-r--r--src/test/rustdoc/search-index.rs10
-rw-r--r--src/test/rustdoc/short-docblock-codeblock.rs4
-rw-r--r--src/test/rustdoc/short-docblock.rs10
-rw-r--r--src/test/rustdoc/show-const-contents.rs48
-rw-r--r--src/test/rustdoc/sized_trait.rs4
-rw-r--r--src/test/rustdoc/sort-modules-by-appearance.rs4
-rw-r--r--src/test/rustdoc/source-file.rs2
-rw-r--r--src/test/rustdoc/src-links-auto-impls.rs2
-rw-r--r--src/test/rustdoc/static-root-path.rs20
-rw-r--r--src/test/rustdoc/synthetic_auto/basic.rs4
-rw-r--r--src/test/rustdoc/synthetic_auto/complex.rs2
-rw-r--r--src/test/rustdoc/synthetic_auto/lifetimes.rs4
-rw-r--r--src/test/rustdoc/synthetic_auto/manual.rs2
-rw-r--r--src/test/rustdoc/synthetic_auto/nested.rs4
-rw-r--r--src/test/rustdoc/synthetic_auto/no-redundancy.rs2
-rw-r--r--src/test/rustdoc/synthetic_auto/project.rs4
-rw-r--r--src/test/rustdoc/synthetic_auto/self-referential.rs2
-rw-r--r--src/test/rustdoc/synthetic_auto/static-region.rs2
-rw-r--r--src/test/rustdoc/table-in-docblock.rs2
-rw-r--r--src/test/rustdoc/toggle-item-contents.rs4
-rw-r--r--src/test/rustdoc/trait-impl-items-links-and-anchors.rs2
-rw-r--r--src/test/rustdoc/trait-impl.rs24
-rw-r--r--src/test/rustdoc/tuple-struct-fields-doc.rs2
-rw-r--r--src/test/rustdoc/type-layout-flag-required.rs2
-rw-r--r--src/test/rustdoc/type-layout.rs64
-rw-r--r--src/test/rustdoc/typedef.rs2
-rw-r--r--src/test/rustdoc/universal-impl-trait.rs30
-rw-r--r--src/test/rustdoc/version-separator-without-source.rs2
-rw-r--r--src/test/rustdoc/where-clause-order.rs2
-rw-r--r--src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html7
-rw-r--r--src/test/rustdoc/where.rs35
-rw-r--r--src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs2
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs6
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-for-crate.rs2
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/duplicate-a-b.ftl1
-rw-r--r--src/test/ui-fulldeps/fluent-messages/duplicate-a.ftl2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/duplicate-b.ftl1
-rw-r--r--src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/missing-crate-name.ftl2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/missing-message.ftl2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl1
-rw-r--r--src/test/ui-fulldeps/fluent-messages/test.rs37
-rw-r--r--src/test/ui-fulldeps/fluent-messages/test.stderr60
-rw-r--r--src/test/ui-fulldeps/fluent-messages/valid.ftl2
-rw-r--r--src/test/ui-fulldeps/internal-lints/diagnostics.rs30
-rw-r--r--src/test/ui-fulldeps/internal-lints/diagnostics.stderr30
-rw-r--r--src/test/ui-fulldeps/issue-15778-pass.rs23
-rw-r--r--src/test/ui-fulldeps/issue-15778-pass.stderr10
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs5
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs215
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr338
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs165
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr246
-rw-r--r--src/test/ui/abi/issues/issue-97463-broken-abi-leaked-uninit-data.rs39
-rw-r--r--src/test/ui/allocator/no_std-alloc-error-handler-custom.rs2
-rw-r--r--src/test/ui/allocator/no_std-alloc-error-handler-default.rs2
-rw-r--r--src/test/ui/argument-suggestions/basic.stderr10
-rw-r--r--src/test/ui/argument-suggestions/complex.stderr4
-rw-r--r--src/test/ui/argument-suggestions/exotic-calls.stderr8
-rw-r--r--src/test/ui/argument-suggestions/extra_arguments.stderr28
-rw-r--r--src/test/ui/argument-suggestions/invalid_arguments.stderr20
-rw-r--r--src/test/ui/argument-suggestions/issue-100478.rs52
-rw-r--r--src/test/ui/argument-suggestions/issue-100478.stderr81
-rw-r--r--src/test/ui/argument-suggestions/issue-101097.rs21
-rw-r--r--src/test/ui/argument-suggestions/issue-101097.stderr160
-rw-r--r--src/test/ui/argument-suggestions/issue-96638.stderr6
-rw-r--r--src/test/ui/argument-suggestions/issue-97197.stderr2
-rw-r--r--src/test/ui/argument-suggestions/issue-97484.stderr7
-rw-r--r--src/test/ui/argument-suggestions/issue-98894.stderr2
-rw-r--r--src/test/ui/argument-suggestions/issue-98897.stderr2
-rw-r--r--src/test/ui/argument-suggestions/issue-99482.stderr2
-rw-r--r--src/test/ui/argument-suggestions/missing_arguments.stderr38
-rw-r--r--src/test/ui/argument-suggestions/mixed_cases.stderr12
-rw-r--r--src/test/ui/argument-suggestions/permuted_arguments.stderr4
-rw-r--r--src/test/ui/argument-suggestions/swapped_arguments.stderr10
-rw-r--r--src/test/ui/argument-suggestions/too-long.rs41
-rw-r--r--src/test/ui/argument-suggestions/too-long.stderr24
-rw-r--r--src/test/ui/argument-suggestions/two-mismatch-notes.rs11
-rw-r--r--src/test/ui/argument-suggestions/two-mismatch-notes.stderr29
-rw-r--r--src/test/ui/array-slice-vec/suggest-array-length.fixed26
-rw-r--r--src/test/ui/array-slice-vec/suggest-array-length.rs26
-rw-r--r--src/test/ui/array-slice-vec/suggest-array-length.stderr108
-rw-r--r--src/test/ui/asm/aarch64/may_unwind.rs1
-rw-r--r--src/test/ui/asm/aarch64/type-check-3.stderr40
-rw-r--r--src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr4
-rw-r--r--src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr4
-rw-r--r--src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr4
-rw-r--r--src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr4
-rw-r--r--src/test/ui/asm/may_unwind.rs1
-rw-r--r--src/test/ui/asm/naked-functions.stderr103
-rw-r--r--src/test/ui/asm/type-check-1.stderr4
-rw-r--r--src/test/ui/asm/unpretty-expanded.rs3
-rw-r--r--src/test/ui/asm/unpretty-expanded.stdout9
-rw-r--r--src/test/ui/asm/x86_64/may_unwind.rs2
-rw-r--r--src/test/ui/asm/x86_64/sym.rs1
-rw-r--r--src/test/ui/asm/x86_64/type-check-3.stderr16
-rw-r--r--src/test/ui/associated-consts/defaults-cyclic-fail.stderr4
-rw-r--r--src/test/ui/associated-consts/issue-102335-const.rs12
-rw-r--r--src/test/ui/associated-consts/issue-102335-const.stderr9
-rw-r--r--src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr2
-rw-r--r--src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr2
-rw-r--r--src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr2
-rw-r--r--src/test/ui/associated-type-bounds/binder-on-bound.rs2
-rw-r--r--src/test/ui/associated-type-bounds/binder-on-bound.stderr2
-rw-r--r--src/test/ui/associated-type-bounds/elision.rs2
-rw-r--r--src/test/ui/associated-type-bounds/issue-102335-ty.rs12
-rw-r--r--src/test/ui/associated-type-bounds/issue-102335-ty.stderr9
-rw-r--r--src/test/ui/associated-type-bounds/issue-79949.rs1
-rw-r--r--src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr8
-rw-r--r--src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr12
-rw-r--r--src/test/ui/associated-types/associated-types-eq-3.stderr6
-rw-r--r--src/test/ui/associated-types/associated-types-eq-hr.stderr8
-rw-r--r--src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20346.stderr6
-rw-r--r--src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr12
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-bound.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr8
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding-2.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding-2.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-path-2.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-path-2.stderr32
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr4
-rw-r--r--src/test/ui/associated-types/defaults-suitability.stderr6
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.badbase.stderr17
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.badnll.stderr2
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-2.stderr4
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.stderr4
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.stderr2
-rw-r--r--src/test/ui/associated-types/issue-22560.stderr46
-rw-r--r--src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr6
-rw-r--r--src/test/ui/associated-types/issue-44153.stderr2
-rw-r--r--src/test/ui/associated-types/issue-59324.rs2
-rw-r--r--src/test/ui/associated-types/issue-59324.stderr17
-rw-r--r--src/test/ui/associated-types/issue-62200.rs3
-rw-r--r--src/test/ui/associated-types/issue-62200.stderr3
-rw-r--r--src/test/ui/associated-types/issue-65774-1.stderr2
-rw-r--r--src/test/ui/associated-types/issue-87261.stderr84
-rw-r--r--src/test/ui/associated-types/substs-ppaux.normal.stderr8
-rw-r--r--src/test/ui/associated-types/substs-ppaux.verbose.stderr8
-rw-r--r--src/test/ui/async-await/async-await-let-else.drop-tracking.stderr110
-rw-r--r--src/test/ui/async-await/async-await-let-else.no-drop-tracking.stderr (renamed from src/test/ui/async-await/async-await-let-else.stderr)28
-rw-r--r--src/test/ui/async-await/async-await-let-else.rs13
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.rs8
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr8
-rw-r--r--src/test/ui/async-await/async-trait-fn.rs3
-rw-r--r--src/test/ui/async-await/async-trait-fn.stderr75
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.rs3
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr30
-rw-r--r--src/test/ui/async-await/generator-desc.stderr4
-rw-r--r--src/test/ui/async-await/issue-101715.rs17
-rw-r--r--src/test/ui/async-await/issue-101715.stderr16
-rw-r--r--src/test/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr (renamed from src/test/ui/async-await/issue-64130-4-async-move.stderr)6
-rw-r--r--src/test/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr26
-rw-r--r--src/test/ui/async-await/issue-64130-4-async-move.rs10
-rw-r--r--src/test/ui/async-await/issue-67252-unnamed-future.stderr10
-rw-r--r--src/test/ui/async-await/issue-68112.drop_tracking.stderr79
-rw-r--r--src/test/ui/async-await/issue-68112.no_drop_tracking.stderr (renamed from src/test/ui/async-await/issue-68112.stderr)39
-rw-r--r--src/test/ui/async-await/issue-68112.rs11
-rw-r--r--src/test/ui/async-await/issue-70594.stderr12
-rw-r--r--src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr10
-rw-r--r--src/test/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr (renamed from src/test/ui/async-await/issue-70935-complex-spans.normal.stderr)8
-rw-r--r--src/test/ui/async-await/issue-70935-complex-spans.rs5
-rw-r--r--src/test/ui/async-await/issue-73137.rs3
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr14
-rw-r--r--src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr (renamed from src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr)18
-rw-r--r--src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs6
-rw-r--r--src/test/ui/async-await/issues/issue-95307.stderr14
-rw-r--r--src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr35
-rw-r--r--src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr (renamed from src/test/ui/async-await/partial-drop-partial-reinit.stderr)6
-rw-r--r--src/test/ui/async-await/partial-drop-partial-reinit.rs11
-rw-r--r--src/test/ui/async-await/unnecessary-await.stderr2
-rw-r--r--src/test/ui/attempted-access-non-fatal.rs4
-rw-r--r--src/test/ui/attempted-access-non-fatal.stderr46
-rw-r--r--src/test/ui/attributes/collapse-debuginfo-invalid.rs110
-rw-r--r--src/test/ui/attributes/collapse-debuginfo-invalid.stderr222
-rw-r--r--src/test/ui/attributes/issue-100631.rs8
-rw-r--r--src/test/ui/attributes/issue-100631.stderr12
-rw-r--r--src/test/ui/attributes/issue-90873.stderr4
-rw-r--r--src/test/ui/attributes/register-attr-tool-fail.rs13
-rw-r--r--src/test/ui/attributes/register-attr-tool-fail.stderr42
-rw-r--r--src/test/ui/attributes/register-attr-tool-import.rs17
-rw-r--r--src/test/ui/attributes/register-attr-tool-import.stderr38
-rw-r--r--src/test/ui/attributes/register-attr-tool-prelude.rs14
-rw-r--r--src/test/ui/attributes/register-attr-tool-prelude.stderr15
-rw-r--r--src/test/ui/attributes/register-attr-tool-unused.rs8
-rw-r--r--src/test/ui/attributes/register-attr-tool-unused.stderr21
-rw-r--r--src/test/ui/attributes/register-attr-tool.rs19
-rw-r--r--src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs31
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs5
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr14
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs14
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr15
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs6
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs9
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs15
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs6
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs6
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr8
-rw-r--r--src/test/ui/auto-ref-slice-plus-ref.stderr2
-rw-r--r--src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr4
-rw-r--r--src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr6
-rw-r--r--src/test/ui/backtrace-apple-no-dsymutil.rs2
-rw-r--r--src/test/ui/binop/binary-op-on-double-ref.stderr2
-rw-r--r--src/test/ui/binop/issue-77910-1.stderr2
-rw-r--r--src/test/ui/binop/issue-77910-2.stderr5
-rw-r--r--src/test/ui/block-result/issue-22645.stderr2
-rw-r--r--src/test/ui/block-result/issue-3563.stderr2
-rw-r--r--src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr30
-rw-r--r--src/test/ui/borrowck/borrowck-describe-lvalue.stderr12
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr10
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr20
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr2
-rw-r--r--src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs8
-rw-r--r--src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr18
-rw-r--r--src/test/ui/borrowck/index-mut-help.rs3
-rw-r--r--src/test/ui/borrowck/index-mut-help.stderr19
-rw-r--r--src/test/ui/borrowck/issue-101119.rs16
-rw-r--r--src/test/ui/borrowck/issue-101119.stderr15
-rw-r--r--src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr4
-rw-r--r--src/test/ui/borrowck/issue-64453.stderr1
-rw-r--r--src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs14
-rw-r--r--src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr37
-rw-r--r--src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr5
-rw-r--r--src/test/ui/borrowck/two-phase-nonrecv-autoref.rs4
-rw-r--r--src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs2
-rw-r--r--src/test/ui/btreemap/btreemap-index-mut.rs6
-rw-r--r--src/test/ui/btreemap/btreemap-index-mut.stderr19
-rw-r--r--src/test/ui/c-variadic/issue-86053-1.stderr6
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.stderr4
-rw-r--r--src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs1
-rw-r--r--src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr15
-rw-r--r--src/test/ui/chalkify/type_wf.rs4
-rw-r--r--src/test/ui/chalkify/type_wf.stderr6
-rw-r--r--src/test/ui/check-cfg/allow-at-crate-level.rs8
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-value.stderr6
-rw-r--r--src/test/ui/check-cfg/mix.rs2
-rw-r--r--src/test/ui/check-cfg/mix.stderr10
-rw-r--r--src/test/ui/check-static-values-constraints.stderr1
-rw-r--r--src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr12
-rw-r--r--src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr2
-rw-r--r--src/test/ui/closure_context/issue-26046-fn-mut.stderr2
-rw-r--r--src/test/ui/closure_context/issue-26046-fn-once.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr10
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr10
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/repr_packed.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr16
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs2
-rw-r--r--src/test/ui/closures/binder/disallow-const.rs6
-rw-r--r--src/test/ui/closures/binder/disallow-const.stderr8
-rw-r--r--src/test/ui/closures/binder/disallow-ty.rs6
-rw-r--r--src/test/ui/closures/binder/disallow-ty.stderr8
-rw-r--r--src/test/ui/closures/closure-move-sync.stderr22
-rw-r--r--src/test/ui/closures/closure-wrong-kind.stderr10
-rw-r--r--src/test/ui/closures/coerce-unsafe-to-closure.stderr2
-rw-r--r--src/test/ui/closures/issue-10398.rs4
-rw-r--r--src/test/ui/closures/issue-10398.stderr2
-rw-r--r--src/test/ui/closures/issue-52437.rs1
-rw-r--r--src/test/ui/closures/issue-52437.stderr13
-rw-r--r--src/test/ui/closures/issue-6801.rs4
-rw-r--r--src/test/ui/closures/issue-84128.rs2
-rw-r--r--src/test/ui/closures/issue-84128.stderr5
-rw-r--r--src/test/ui/closures/print/closure-print-generic-verbose-1.stderr2
-rw-r--r--src/test/ui/codegen/issue-101585-128bit-repeat.rs14
-rw-r--r--src/test/ui/codegen/issue-99551.rs21
-rw-r--r--src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr2
-rw-r--r--src/test/ui/coercion/coerce-to-bang.stderr10
-rw-r--r--src/test/ui/coercion/issue-101066.rs16
-rw-r--r--src/test/ui/coherence/auxiliary/trait-with-const-param.rs1
-rw-r--r--src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs13
-rw-r--r--src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr (renamed from src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr)2
-rw-r--r--src/test/ui/coherence/const-generics-orphan-check-ok.rs28
-rw-r--r--src/test/ui/coherence/issue-100191-2.rs12
-rw-r--r--src/test/ui/coherence/issue-100191-2.stderr14
-rw-r--r--src/test/ui/coherence/issue-100191.rs21
-rw-r--r--src/test/ui/coherence/issue-100191.stderr12
-rw-r--r--src/test/ui/command/command-current-dir.rs2
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr4
-rw-r--r--src/test/ui/const-generics/argument_order.stderr4
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.rs2
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.stderr2
-rw-r--r--src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.rs4
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs2
-rw-r--r--src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr2
-rw-r--r--src/test/ui/const-generics/defaults/trait_objects_fail.stderr8
-rw-r--r--src/test/ui/const-generics/early/const-param-from-outer-fn.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr96
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/different-fn.stderr4
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-100217.rs42
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-100360.rs13
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr4
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr4
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-73298.rs23
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-82268.rs73
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr8
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-83972.rs38
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-84669.rs30
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr12
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-86710.rs73
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-89851.rs12
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs24
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr20
-rw-r--r--src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr13
-rw-r--r--src/test/ui/const-generics/issue-103243.rs37
-rw-r--r--src/test/ui/const-generics/issues/issue-100313.rs21
-rw-r--r--src/test/ui/const-generics/issues/issue-100313.stderr15
-rw-r--r--src/test/ui/const-generics/issues/issue-73260.stderr24
-rw-r--r--src/test/ui/const-generics/issues/issue-79674.stderr12
-rw-r--r--src/test/ui/const-generics/issues/issue-83466.rs2
-rw-r--r--src/test/ui/const-generics/issues/issue-83765.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-87493.stderr8
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr26
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr26
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.rs6
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.full.stderr4
-rw-r--r--src/test/ui/consts/assert-type-intrinsics.rs4
-rw-r--r--src/test/ui/consts/assert-type-intrinsics.stderr8
-rw-r--r--src/test/ui/consts/const-block-const-bound.stderr4
-rw-r--r--src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr2
-rw-r--r--src/test/ui/consts/const-blocks/migrate-fail.stderr4
-rw-r--r--src/test/ui/consts/const-blocks/nll-fail.stderr4
-rw-r--r--src/test/ui/consts/const-blocks/trait-error.stderr2
-rw-r--r--src/test/ui/consts/const-err4.32bit.stderr11
-rw-r--r--src/test/ui/consts/const-err4.64bit.stderr11
-rw-r--r--src/test/ui/consts/const-err4.rs3
-rw-r--r--src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr110
-rw-r--r--src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs6
-rw-r--r--src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr2
-rw-r--r--src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr2
-rw-r--r--src/test/ui/consts/const-eval/issue-91827-extern-types.rs1
-rw-r--r--src/test/ui/consts/const-eval/ub-enum-overwrite.rs3
-rw-r--r--src/test/ui/consts/const-eval/ub-enum-overwrite.stderr13
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.32bit.stderr25
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.64bit.stderr25
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.rs5
-rw-r--r--src/test/ui/consts/const-eval/ub-int-array.32bit.stderr39
-rw-r--r--src/test/ui/consts/const-eval/ub-int-array.64bit.stderr39
-rw-r--r--src/test/ui/consts/const-eval/ub-int-array.rs12
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr15
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr15
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.rs3
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr28
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr28
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.rs6
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr90
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr90
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.rs12
-rw-r--r--src/test/ui/consts/const-eval/union-const-eval-field.rs3
-rw-r--r--src/test/ui/consts/const-eval/union-const-eval-field.stderr13
-rw-r--r--src/test/ui/consts/const-eval/union-ice.rs12
-rw-r--r--src/test/ui/consts/const-eval/union-ice.stderr39
-rw-r--r--src/test/ui/consts/const-eval/union-ub.32bit.stderr11
-rw-r--r--src/test/ui/consts/const-eval/union-ub.64bit.stderr11
-rw-r--r--src/test/ui/consts/const-eval/union-ub.rs3
-rw-r--r--src/test/ui/consts/const-float-bits-reject-conv.stderr40
-rw-r--r--src/test/ui/consts/const-points-to-static.32bit.stderr2
-rw-r--r--src/test/ui/consts/const-points-to-static.64bit.stderr2
-rw-r--r--src/test/ui/consts/const_in_pattern/incomplete-slice.rs15
-rw-r--r--src/test/ui/consts/const_in_pattern/incomplete-slice.stderr26
-rw-r--r--src/test/ui/consts/extra-const-ub/detect-extra-ub.rs45
-rw-r--r--src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr117
-rw-r--r--src/test/ui/consts/extra-const-ub/issue-100771.rs20
-rw-r--r--src/test/ui/consts/extra-const-ub/issue-101034.rs17
-rw-r--r--src/test/ui/consts/issue-32829-2.stderr2
-rw-r--r--src/test/ui/consts/issue-36163.stderr2
-rw-r--r--src/test/ui/consts/issue-miri-1910.rs1
-rw-r--r--src/test/ui/consts/issue-miri-1910.stderr12
-rw-r--r--src/test/ui/consts/mir_check_nonconst.stderr1
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/ptr_arith.rs5
-rw-r--r--src/test/ui/consts/miri_unleashed/ptr_arith.stderr2
-rw-r--r--src/test/ui/consts/miri_unleashed/slice_eq.rs12
-rw-r--r--src/test/ui/consts/offset.rs1
-rw-r--r--src/test/ui/consts/offset_from.rs1
-rw-r--r--src/test/ui/consts/offset_from_ub.rs2
-rw-r--r--src/test/ui/consts/ptr_comparisons.rs24
-rw-r--r--src/test/ui/consts/ptr_comparisons.stderr14
-rw-r--r--src/test/ui/consts/unnormalized-param-env.rs31
-rw-r--r--src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs1
-rw-r--r--src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr21
-rw-r--r--src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs3
-rw-r--r--src/test/ui/deprecation/deprecation-sanity.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr22
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.rs3
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.stderr22
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.stderr22
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr22
-rw-r--r--src/test/ui/derives/deriving-copyclone.stderr12
-rw-r--r--src/test/ui/derives/deriving-no-inner-impl-error-message.rs1
-rw-r--r--src/test/ui/derives/deriving-no-inner-impl-error-message.stderr24
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.rs2
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout65
-rw-r--r--src/test/ui/deriving/issue-103157.rs12
-rw-r--r--src/test/ui/deriving/issue-103157.stderr30
-rw-r--r--src/test/ui/deriving/issue-89188-gat-hrtb.rs2
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr6
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr6
-rw-r--r--src/test/ui/did_you_mean/use_instead_of_import.fixed8
-rw-r--r--src/test/ui/did_you_mean/use_instead_of_import.rs8
-rw-r--r--src/test/ui/did_you_mean/use_instead_of_import.stderr16
-rw-r--r--src/test/ui/drop/drop-foreign-fundamental.rs23
-rw-r--r--src/test/ui/drop/drop-foreign-fundamental.stderr9
-rw-r--r--src/test/ui/drop/drop_order.rs145
-rw-r--r--src/test/ui/dropck/drop-on-non-struct.rs7
-rw-r--r--src/test/ui/dropck/drop-on-non-struct.stderr4
-rw-r--r--src/test/ui/dst/dst-bad-coercions.stderr8
-rw-r--r--src/test/ui/dst/dst-rvalue.rs6
-rw-r--r--src/test/ui/dst/dst-rvalue.stderr28
-rw-r--r--src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr35
-rw-r--r--src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr10
-rw-r--r--src/test/ui/dyn-keyword/dyn-angle-brackets.stderr5
-rw-r--r--src/test/ui/dyn-star/const.rs14
-rw-r--r--src/test/ui/dyn-star/drop.rs23
-rw-r--r--src/test/ui/dyn-star/drop.run.stdout1
-rw-r--r--src/test/ui/dyn-star/error.rs13
-rw-r--r--src/test/ui/dyn-star/error.stderr9
-rw-r--r--src/test/ui/dyn-star/feature-gate-dyn_star.rs9
-rw-r--r--src/test/ui/dyn-star/feature-gate-dyn_star.stderr12
-rw-r--r--src/test/ui/dyn-star/make-dyn-star.rs13
-rw-r--r--src/test/ui/dyn-star/method.rs26
-rw-r--r--src/test/ui/dyn-star/syntax.rs11
-rw-r--r--src/test/ui/dynamically-sized-types/dst-struct.rs3
-rw-r--r--src/test/ui/dynamically-sized-types/dst-trait.rs1
-rw-r--r--src/test/ui/empty/empty-never-array.rs2
-rw-r--r--src/test/ui/empty/empty-never-array.stderr6
-rw-r--r--src/test/ui/enum/enum-discrim-autosizing.rs4
-rw-r--r--src/test/ui/enum/enum-discrim-autosizing.stderr4
-rw-r--r--src/test/ui/env-funky-keys.rs1
-rw-r--r--src/test/ui/error-codes/E0004.stderr6
-rw-r--r--src/test/ui/error-codes/E0005.stderr2
-rw-r--r--src/test/ui/error-codes/E0057.stderr4
-rw-r--r--src/test/ui/error-codes/E0060.stderr2
-rw-r--r--src/test/ui/error-codes/E0061.stderr4
-rw-r--r--src/test/ui/error-codes/E0081.rs37
-rw-r--r--src/test/ui/error-codes/E0081.stderr52
-rw-r--r--src/test/ui/error-codes/E0107.stderr2
-rw-r--r--src/test/ui/error-codes/E0117.rs2
-rw-r--r--src/test/ui/error-codes/E0117.stderr4
-rw-r--r--src/test/ui/error-codes/E0120.stderr4
-rw-r--r--src/test/ui/error-codes/E0271.stderr6
-rw-r--r--src/test/ui/error-codes/E0275.stderr4
-rw-r--r--src/test/ui/error-codes/E0277-2.stderr4
-rw-r--r--src/test/ui/error-codes/E0401.stderr8
-rw-r--r--src/test/ui/error-codes/E0565-2.stderr4
-rw-r--r--src/test/ui/explore-issue-38412.stderr6
-rw-r--r--src/test/ui/expr/if/if-branch-types.stderr5
-rw-r--r--src/test/ui/expr/if/if-else-type-mismatch.stderr10
-rw-r--r--src/test/ui/extern/extern-types-unsized.stderr12
-rw-r--r--src/test/ui/extern/extern-wrong-value-type.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs7
-rw-r--r--src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr30
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_associated_types.rs31
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr78
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-label_break_value.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-label_break_value.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-let_else.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-let_else.stderr14
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr6
-rw-r--r--src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr15
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs8
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr21
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-register_attr.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-register_attr.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-unix_sigpipe.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-unix_sigpipe.stderr12
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs30
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr21
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs26
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr24
-rw-r--r--src/test/ui/fmt/ifmt-bad-arg.rs2
-rw-r--r--src/test/ui/fmt/ifmt-bad-arg.stderr13
-rw-r--r--src/test/ui/fmt/ifmt-unimpl.stderr2
-rw-r--r--src/test/ui/fmt/send-sync.stderr14
-rw-r--r--src/test/ui/fn/fn-compare-mismatch.stderr10
-rw-r--r--src/test/ui/fn/fn-item-type.stderr10
-rw-r--r--src/test/ui/fn/fn-trait-formatting.stderr8
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs3
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-2.stderr17
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs5
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr14
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-4.rs24
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-4.stderr14
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-5.rs23
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type-5.stderr19
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type.rs6
-rw-r--r--src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr20
-rw-r--r--src/test/ui/for-loop-while/break-while-condition.stderr8
-rw-r--r--src/test/ui/for-loop-while/label_break_value.rs1
-rw-r--r--src/test/ui/for-loop-while/label_break_value_invalid.rs1
-rw-r--r--src/test/ui/for-loop-while/label_break_value_invalid.stderr6
-rw-r--r--src/test/ui/for/for-c-in-str.rs2
-rw-r--r--src/test/ui/for/for-c-in-str.stderr2
-rw-r--r--src/test/ui/for/for-loop-bogosity.stderr2
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err.rs28
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err.stderr38
-rw-r--r--src/test/ui/generator/clone-impl-async.rs71
-rw-r--r--src/test/ui/generator/clone-impl-async.stderr171
-rw-r--r--src/test/ui/generator/clone-impl-static.rs17
-rw-r--r--src/test/ui/generator/clone-impl-static.stderr31
-rw-r--r--src/test/ui/generator/clone-impl.rs73
-rw-r--r--src/test/ui/generator/clone-impl.stderr142
-rw-r--r--src/test/ui/generator/drop-tracking-parent-expression.stderr12
-rw-r--r--src/test/ui/generator/drop-yield-twice.stderr12
-rw-r--r--src/test/ui/generator/generator-yielding-or-returning-itself.stderr26
-rw-r--r--src/test/ui/generator/issue-68112.rs3
-rw-r--r--src/test/ui/generator/issue-68112.stderr12
-rw-r--r--src/test/ui/generator/not-send-sync.stderr28
-rw-r--r--src/test/ui/generator/partial-drop.stderr39
-rw-r--r--src/test/ui/generator/print/generator-print-verbose-1.stderr12
-rw-r--r--src/test/ui/generator/print/generator-print-verbose-2.stderr28
-rw-r--r--src/test/ui/generator/type-mismatch-signature-deduction.stderr6
-rw-r--r--src/test/ui/generator/yield-outside-generator-issue-78653.stderr2
-rw-r--r--src/test/ui/generic-associated-types/anonymize-bound-vars.rs1
-rw-r--r--src/test/ui/generic-associated-types/auxiliary/foo_defn.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-1.rs35
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr20
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-2.rs40
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-2.stderr22
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-3.rs23
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-3.stderr22
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.stderr4
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.rs1
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.stderr6
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.rs23
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.stderr20
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.stderr4
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.stderr8
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.rs1
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.stderr4
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-91762.rs (renamed from src/test/ui/generic-associated-types/issue-91762.rs)5
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-91762.stderr (renamed from src/test/ui/generic-associated-types/issue-91762.stderr)2
-rw-r--r--src/test/ui/generic-associated-types/collections-project-default.rs1
-rw-r--r--src/test/ui/generic-associated-types/collections-project-default.stderr2
-rw-r--r--src/test/ui/generic-associated-types/collections.rs1
-rw-r--r--src/test/ui/generic-associated-types/collectivity-regression.rs2
-rw-r--r--src/test/ui/generic-associated-types/collectivity-regression.stderr2
-rw-r--r--src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs1
-rw-r--r--src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs1
-rw-r--r--src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs1
-rw-r--r--src/test/ui/generic-associated-types/const_params_have_right_type.rs2
-rw-r--r--src/test/ui/generic-associated-types/const_params_have_right_type.stderr2
-rw-r--r--src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs2
-rw-r--r--src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr2
-rw-r--r--src/test/ui/generic-associated-types/construct_with_other_type.rs2
-rw-r--r--src/test/ui/generic-associated-types/cross-crate-bounds.stderr2
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.rs1
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.stderr8
-rw-r--r--src/test/ui/generic-associated-types/empty_generics.rs2
-rw-r--r--src/test/ui/generic-associated-types/empty_generics.stderr2
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr2
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator.rs1
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr2
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator_2.rs1
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs16
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr21
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs16
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr19
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs2
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr4
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr4
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path.rs1
-rw-r--r--src/test/ui/generic-associated-types/gat-incomplete-warning.rs5
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs2
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr6
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs2
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr8
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs2
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr18
-rw-r--r--src/test/ui/generic-associated-types/generic-associated-type-bounds.rs2
-rw-r--r--src/test/ui/generic-associated-types/generic-associated-types-where.rs2
-rw-r--r--src/test/ui/generic-associated-types/generic-associated-types-where.stderr4
-rw-r--r--src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs2
-rw-r--r--src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr4
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.rs1
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr26
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds_ok.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-101020.rs35
-rw-r--r--src/test/ui/generic-associated-types/issue-101020.stderr25
-rw-r--r--src/test/ui/generic-associated-types/issue-102333.rs15
-rw-r--r--src/test/ui/generic-associated-types/issue-102335-gat.rs12
-rw-r--r--src/test/ui/generic-associated-types/issue-102335-gat.stderr9
-rw-r--r--src/test/ui/generic-associated-types/issue-47206-where-clause.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-47206-where-clause.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-67424.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-67424.stderr12
-rw-r--r--src/test/ui/generic-associated-types/issue-67510-pass.base.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-67510-pass.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-67510.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-67510.stderr8
-rw-r--r--src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-68643-broken-mir.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-1.rs3
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-2.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-2.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-68649-pass.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68653.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68656-unsized-values.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-70303.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-70304.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-70304.stderr6
-rw-r--r--src/test/ui/generic-associated-types/issue-71176.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-71176.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-1.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-1.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-2.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-2.stderr10
-rw-r--r--src/test/ui/generic-associated-types/issue-74816.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-74816.stderr8
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.stderr10
-rw-r--r--src/test/ui/generic-associated-types/issue-76407.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.base.stderr14
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.extended.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-76826.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs4
-rw-r--r--src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr26
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.base.stderr8
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.extended.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.base.stderr14
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.extended.stderr8
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-1.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-1.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-2.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-2.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-80433-reduced.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-80433.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-80433.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-81487.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-81862.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-81862.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-84931.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-84931.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-85921.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-86483.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-86787.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-86787.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_a.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_a.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_b.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_b.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-2.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-specialization.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-specialization.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-87429.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-87748.rs21
-rw-r--r--src/test/ui/generic-associated-types/issue-87750.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-87750.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-88287.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-88287.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-88360.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-88360.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-88405.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-88459.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-89352.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-90014.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-90014.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-90729.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.migrate.stderr13
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.stderr18
-rw-r--r--src/test/ui/generic-associated-types/issue-91883.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-91883.stderr6
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-92096.migrate.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-92096.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-92096.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-92280.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-92954.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-93141.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-93262.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-93340.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-93341.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-93342.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-93874.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-95305.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-95305.stderr2
-rw-r--r--src/test/ui/generic-associated-types/iterable.rs2
-rw-r--r--src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs2
-rw-r--r--src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr4
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.fixed2
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.stderr4
-rw-r--r--src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs2
-rw-r--r--src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr2
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_args.rs2
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_args.stderr12
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_const.rs2
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_const.stderr4
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind.rs1
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind.stderr12
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs1
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr12
-rw-r--r--src/test/ui/generic-associated-types/parse/in-trait-impl.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/in-trait.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expressions.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr4
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr10
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-segments.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-segments.stderr6
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr8
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-types.rs2
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-types.stderr6
-rw-r--r--src/test/ui/generic-associated-types/pointer_family.rs2
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs2
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr4
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle.rs1
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle.stderr4
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs2
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr6
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.rs15
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.stderr43
-rw-r--r--src/test/ui/generic-associated-types/shadowing.rs2
-rw-r--r--src/test/ui/generic-associated-types/shadowing.stderr8
-rw-r--r--src/test/ui/generic-associated-types/streaming_iterator.rs2
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.base.stderr4
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.extended.stderr4
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.rs1
-rw-r--r--src/test/ui/generic-associated-types/type-param-defaults.rs34
-rw-r--r--src/test/ui/generic-associated-types/type-param-defaults.stderr20
-rw-r--r--src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs2
-rw-r--r--src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr14
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs2
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr8
-rw-r--r--src/test/ui/generic-associated-types/variance_constraints.rs1
-rw-r--r--src/test/ui/generics/issue-59508-1.rs2
-rw-r--r--src/test/ui/generics/issue-59508-1.stderr2
-rw-r--r--src/test/ui/generics/issue-59508.fixed2
-rw-r--r--src/test/ui/generics/issue-59508.rs2
-rw-r--r--src/test/ui/generics/issue-59508.stderr2
-rw-r--r--src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs2
-rw-r--r--src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr2
-rw-r--r--src/test/ui/generics/issue-98432.stderr6
-rw-r--r--src/test/ui/generics/lifetime-before-type-params.rs8
-rw-r--r--src/test/ui/generics/lifetime-before-type-params.stderr8
-rw-r--r--src/test/ui/hashmap/hashmap-index-mut.rs6
-rw-r--r--src/test/ui/hashmap/hashmap-index-mut.stderr19
-rw-r--r--src/test/ui/higher-rank-trait-bounds/complex.rs (renamed from src/test/ui/hrtb/complex.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/due-to-where-clause.rs (renamed from src/test/ui/hrtb/due-to-where-clause.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/due-to-where-clause.stderr (renamed from src/test/ui/hrtb/due-to-where-clause.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs (renamed from src/test/ui/hrtb/hrtb-cache-issue-54302.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr (renamed from src/test/ui/hrtb/hrtb-cache-issue-54302.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs (renamed from src/test/ui/hrtb/hrtb-conflate-regions.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr (renamed from src/test/ui/hrtb/hrtb-conflate-regions.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs (renamed from src/test/ui/hrtb/hrtb-debruijn-in-receiver.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr (renamed from src/test/ui/hrtb/hrtb-debruijn-in-receiver.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs (renamed from src/test/ui/hrtb/hrtb-exists-forall-fn.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr (renamed from src/test/ui/hrtb/hrtb-exists-forall-fn.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs (renamed from src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr (renamed from src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs (renamed from src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs (renamed from src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr (renamed from src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs (renamed from src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr (renamed from src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs (renamed from src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr (renamed from src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs (renamed from src/test/ui/hrtb/hrtb-identity-fn-borrows.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr (renamed from src/test/ui/hrtb/hrtb-identity-fn-borrows.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs (renamed from src/test/ui/hrtb/hrtb-just-for-static.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr (renamed from src/test/ui/hrtb/hrtb-just-for-static.stderr)6
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr (renamed from src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs (renamed from src/test/ui/hrtb/hrtb-perfect-forwarding.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr (renamed from src/test/ui/hrtb/hrtb-perfect-forwarding.stderr)6
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-30786.rs (renamed from src/test/ui/hrtb/issue-30786.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-30786.stderr (renamed from src/test/ui/hrtb/issue-30786.stderr)8
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-46989.rs (renamed from src/test/ui/hrtb/issue-46989.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-46989.stderr (renamed from src/test/ui/hrtb/issue-46989.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-57639.rs (renamed from src/test/ui/hrtb/issue-57639.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-58451.rs (renamed from src/test/ui/hrtb/issue-58451.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-58451.stderr (renamed from src/test/ui/hrtb/issue-58451.stderr)2
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs (renamed from src/test/ui/hrtb/issue-62203-hrtb-ice.rs)12
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr (renamed from src/test/ui/hrtb/issue-62203-hrtb-ice.stderr)30
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-88446.rs (renamed from src/test/ui/hrtb/issue-88446.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-90177.rs (renamed from src/test/ui/hrtb/issue-90177.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-95034.rs (renamed from src/test/ui/hrtb/issue-95034.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-95034.stderr (renamed from src/test/ui/hrtb/issue-95034.stderr)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-95230.rs (renamed from src/test/ui/hrtb/issue-95230.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr6
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs1
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr13
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr6
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs2
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs2
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr10
-rw-r--r--src/test/ui/impl-trait/equality.stderr7
-rw-r--r--src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr5
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.rs9
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.stderr18
-rw-r--r--src/test/ui/impl-trait/in-trait/deep-match-works.rs16
-rw-r--r--src/test/ui/impl-trait/in-trait/deep-match.rs15
-rw-r--r--src/test/ui/impl-trait/in-trait/deep-match.stderr15
-rw-r--r--src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs13
-rw-r--r--src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr17
-rw-r--r--src/test/ui/impl-trait/in-trait/encode.rs9
-rw-r--r--src/test/ui/impl-trait/in-trait/nested-rpitit.rs32
-rw-r--r--src/test/ui/impl-trait/in-trait/object-safety.rs22
-rw-r--r--src/test/ui/impl-trait/in-trait/object-safety.stderr50
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs19
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr17
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl.rs48
-rw-r--r--src/test/ui/impl-trait/in-trait/reveal.rs18
-rw-r--r--src/test/ui/impl-trait/in-trait/success.rs40
-rw-r--r--src/test/ui/impl-trait/in-trait/wf-bounds.rs16
-rw-r--r--src/test/ui/impl-trait/in-trait/wf-bounds.stderr33
-rw-r--r--src/test/ui/impl-trait/issue-100075-2.rs8
-rw-r--r--src/test/ui/impl-trait/issue-100075-2.stderr24
-rw-r--r--src/test/ui/impl-trait/issue-100075.rs21
-rw-r--r--src/test/ui/impl-trait/issue-100075.stderr12
-rw-r--r--src/test/ui/impl-trait/issue-103599.rs10
-rw-r--r--src/test/ui/impl-trait/issue-103599.stderr14
-rw-r--r--src/test/ui/impl-trait/issue-99914.rs13
-rw-r--r--src/test/ui/impl-trait/issue-99914.stderr21
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.stderr2
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait2.stderr2
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait3.stderr2
-rw-r--r--src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs23
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.stderr4
-rw-r--r--src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr4
-rw-r--r--src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr4
-rw-r--r--src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr96
-rw-r--r--src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr2
-rw-r--r--src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr2
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr6
-rw-r--r--src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.rs27
-rw-r--r--src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr15
-rw-r--r--src/test/ui/implied-bounds/impl-header-unnormalized-types.rs28
-rw-r--r--src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr20
-rw-r--r--src/test/ui/implied-bounds/issue-100690.rs45
-rw-r--r--src/test/ui/implied-bounds/issue-100690.stderr22
-rw-r--r--src/test/ui/implied-bounds/issue-101951.rs50
-rw-r--r--src/test/ui/index-help.stderr2
-rw-r--r--src/test/ui/indexing-requires-a-uint.stderr2
-rw-r--r--src/test/ui/inference/issue-71732.stderr6
-rw-r--r--src/test/ui/inference/issue-86162-1.stderr2
-rw-r--r--src/test/ui/inference/issue-86162-2.stderr2
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs2
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr2
-rw-r--r--src/test/ui/integral-indexing.stderr16
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.stderr8
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace-std.rs6
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr2
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace.rs18
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr2
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.rs14
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.stderr85
-rw-r--r--src/test/ui/issue-94866.stderr6
-rw-r--r--src/test/ui/issues/auxiliary/issue-2380.rs4
-rw-r--r--src/test/ui/issues/issue-100550-normalization-ice-exposed-by-mir-inlining.rs39
-rw-r--r--src/test/ui/issues/issue-100605.rs9
-rw-r--r--src/test/ui/issues/issue-100605.stderr46
-rw-r--r--src/test/ui/issues/issue-10682.rs4
-rw-r--r--src/test/ui/issues/issue-10767.rs4
-rw-r--r--src/test/ui/issues/issue-10802.rs9
-rw-r--r--src/test/ui/issues/issue-11192.rs8
-rw-r--r--src/test/ui/issues/issue-11192.stderr2
-rw-r--r--src/test/ui/issues/issue-11374.stderr2
-rw-r--r--src/test/ui/issues/issue-11515.rs6
-rw-r--r--src/test/ui/issues/issue-11515.stderr6
-rw-r--r--src/test/ui/issues/issue-11552.rs6
-rw-r--r--src/test/ui/issues/issue-11844.rs4
-rw-r--r--src/test/ui/issues/issue-11844.stderr2
-rw-r--r--src/test/ui/issues/issue-12127.rs4
-rw-r--r--src/test/ui/issues/issue-13323.rs3
-rw-r--r--src/test/ui/issues/issue-14399.rs4
-rw-r--r--src/test/ui/issues/issue-14915.rs4
-rw-r--r--src/test/ui/issues/issue-14915.stderr2
-rw-r--r--src/test/ui/issues/issue-15524.rs16
-rw-r--r--src/test/ui/issues/issue-15524.stderr40
-rw-r--r--src/test/ui/issues/issue-15571.rs7
-rw-r--r--src/test/ui/issues/issue-15763.rs9
-rw-r--r--src/test/ui/issues/issue-16538.mir.stderr1
-rw-r--r--src/test/ui/issues/issue-16538.thir.stderr1
-rw-r--r--src/test/ui/issues/issue-16739.rs7
-rw-r--r--src/test/ui/issues/issue-16774.rs3
-rw-r--r--src/test/ui/issues/issue-16939.stderr2
-rw-r--r--src/test/ui/issues/issue-17252.stderr2
-rw-r--r--src/test/ui/issues/issue-17322.rs4
-rw-r--r--src/test/ui/issues/issue-18611.stderr8
-rw-r--r--src/test/ui/issues/issue-18819.stderr12
-rw-r--r--src/test/ui/issues/issue-20162.stderr6
-rw-r--r--src/test/ui/issues/issue-20413.stderr16
-rw-r--r--src/test/ui/issues/issue-20605.stderr4
-rw-r--r--src/test/ui/issues/issue-20831-debruijn.stderr24
-rw-r--r--src/test/ui/issues/issue-21033.rs5
-rw-r--r--src/test/ui/issues/issue-21763.stderr6
-rw-r--r--src/test/ui/issues/issue-21950.stderr18
-rw-r--r--src/test/ui/issues/issue-22872.stderr2
-rw-r--r--src/test/ui/issues/issue-2288.rs4
-rw-r--r--src/test/ui/issues/issue-23024.rs3
-rw-r--r--src/test/ui/issues/issue-23024.stderr6
-rw-r--r--src/test/ui/issues/issue-23122-2.stderr7
-rw-r--r--src/test/ui/issues/issue-23302-3.stderr4
-rw-r--r--src/test/ui/issues/issue-23491.rs3
-rw-r--r--src/test/ui/issues/issue-23611-enum-swap-in-drop.rs2
-rw-r--r--src/test/ui/issues/issue-25901.stderr1
-rw-r--r--src/test/ui/issues/issue-26217.stderr6
-rw-r--r--src/test/ui/issues/issue-2708.rs4
-rw-r--r--src/test/ui/issues/issue-2734.rs8
-rw-r--r--src/test/ui/issues/issue-2735.rs8
-rw-r--r--src/test/ui/issues/issue-28344.stderr4
-rw-r--r--src/test/ui/issues/issue-2935.rs3
-rw-r--r--src/test/ui/issues/issue-3026.rs4
-rw-r--r--src/test/ui/issues/issue-31173.rs11
-rw-r--r--src/test/ui/issues/issue-31173.stderr42
-rw-r--r--src/test/ui/issues/issue-3121.rs3
-rw-r--r--src/test/ui/issues/issue-3214.stderr5
-rw-r--r--src/test/ui/issues/issue-32709.stderr2
-rw-r--r--src/test/ui/issues/issue-3290.rs3
-rw-r--r--src/test/ui/issues/issue-33941.rs6
-rw-r--r--src/test/ui/issues/issue-33941.stderr18
-rw-r--r--src/test/ui/issues/issue-34334.stderr6
-rw-r--r--src/test/ui/issues/issue-34349.stderr10
-rw-r--r--src/test/ui/issues/issue-3447.rs3
-rw-r--r--src/test/ui/issues/issue-35241.stderr4
-rw-r--r--src/test/ui/issues/issue-35570.rs3
-rw-r--r--src/test/ui/issues/issue-35570.stderr12
-rw-r--r--src/test/ui/issues/issue-3794.rs3
-rw-r--r--src/test/ui/issues/issue-3878.rs3
-rw-r--r--src/test/ui/issues/issue-38821.stderr2
-rw-r--r--src/test/ui/issues/issue-39970.stderr2
-rw-r--r--src/test/ui/issues/issue-40510-3.stderr4
-rw-r--r--src/test/ui/issues/issue-40827.stderr4
-rw-r--r--src/test/ui/issues/issue-41139.stderr4
-rw-r--r--src/test/ui/issues/issue-41726.stderr4
-rw-r--r--src/test/ui/issues/issue-41974.stderr4
-rw-r--r--src/test/ui/issues/issue-43988.stderr4
-rw-r--r--src/test/ui/issues/issue-47511.stderr3
-rw-r--r--src/test/ui/issues/issue-4759.rs4
-rw-r--r--src/test/ui/issues/issue-4935.stderr2
-rw-r--r--src/test/ui/issues/issue-4972.rs1
-rw-r--r--src/test/ui/issues/issue-4972.stderr2
-rw-r--r--src/test/ui/issues/issue-49824.stderr4
-rw-r--r--src/test/ui/issues/issue-5100.rs2
-rw-r--r--src/test/ui/issues/issue-5192.rs4
-rw-r--r--src/test/ui/issues/issue-5439.rs4
-rw-r--r--src/test/ui/issues/issue-5439.stderr6
-rw-r--r--src/test/ui/issues/issue-5666.rs5
-rw-r--r--src/test/ui/issues/issue-5718.rs4
-rw-r--r--src/test/ui/issues/issue-57362-1.stderr4
-rw-r--r--src/test/ui/issues/issue-5884.rs4
-rw-r--r--src/test/ui/issues/issue-59488.rs1
-rw-r--r--src/test/ui/issues/issue-59488.stderr41
-rw-r--r--src/test/ui/issues/issue-5997-enum.stderr8
-rw-r--r--src/test/ui/issues/issue-5997-struct.stderr8
-rw-r--r--src/test/ui/issues/issue-60218.stderr4
-rw-r--r--src/test/ui/issues/issue-62480.rs2
-rw-r--r--src/test/ui/issues/issue-62480.stderr4
-rw-r--r--src/test/ui/issues/issue-6318.rs4
-rw-r--r--src/test/ui/issues/issue-6557.rs1
-rw-r--r--src/test/ui/issues/issue-66706.rs3
-rw-r--r--src/test/ui/issues/issue-66706.stderr35
-rw-r--r--src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr12
-rw-r--r--src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr2
-rw-r--r--src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr14
-rw-r--r--src/test/ui/issues/issue-69455.stderr2
-rw-r--r--src/test/ui/issues/issue-7013.rs4
-rw-r--r--src/test/ui/issues/issue-7013.stderr8
-rw-r--r--src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr9
-rw-r--r--src/test/ui/issues/issue-7364.rs4
-rw-r--r--src/test/ui/issues/issue-7364.stderr6
-rw-r--r--src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs4
-rw-r--r--src/test/ui/issues/issue-86756.stderr5
-rw-r--r--src/test/ui/issues/issue-9129.rs4
-rw-r--r--src/test/ui/issues/issue-9382.rs5
-rw-r--r--src/test/ui/issues/issue-99875.rs16
-rw-r--r--src/test/ui/issues/issue-99875.stderr33
-rw-r--r--src/test/ui/iterators/collect-into-array.rs1
-rw-r--r--src/test/ui/iterators/collect-into-array.stderr6
-rw-r--r--src/test/ui/iterators/collect-into-slice.rs5
-rw-r--r--src/test/ui/iterators/collect-into-slice.stderr23
-rw-r--r--src/test/ui/iterators/integral.stderr24
-rw-r--r--src/test/ui/iterators/issue-28098.rs4
-rw-r--r--src/test/ui/iterators/issue-28098.stderr50
-rw-r--r--src/test/ui/iterators/issue-58952-filter-type-length.rs2
-rw-r--r--src/test/ui/iterators/ranges.stderr4
-rw-r--r--src/test/ui/iterators/string.stderr4
-rw-r--r--src/test/ui/json-multiple.stderr1
-rw-r--r--src/test/ui/json-options.stderr1
-rw-r--r--src/test/ui/json/json-and-color.rs (renamed from src/test/ui/json-and-color.rs)0
-rw-r--r--src/test/ui/json/json-and-color.stderr (renamed from src/test/ui/json-and-color.stderr)0
-rw-r--r--src/test/ui/json/json-and-error-format.rs (renamed from src/test/ui/json-and-error-format.rs)0
-rw-r--r--src/test/ui/json/json-and-error-format.stderr (renamed from src/test/ui/json-and-error-format.stderr)0
-rw-r--r--src/test/ui/json/json-bom-plus-crlf-multifile-aux.rs (renamed from src/test/ui/json-bom-plus-crlf-multifile-aux.rs)0
-rw-r--r--src/test/ui/json/json-bom-plus-crlf-multifile.rs (renamed from src/test/ui/json-bom-plus-crlf-multifile.rs)0
-rw-r--r--src/test/ui/json/json-bom-plus-crlf-multifile.stderr (renamed from src/test/ui/json-bom-plus-crlf-multifile.stderr)0
-rw-r--r--src/test/ui/json/json-bom-plus-crlf.rs (renamed from src/test/ui/json-bom-plus-crlf.rs)0
-rw-r--r--src/test/ui/json/json-bom-plus-crlf.stderr (renamed from src/test/ui/json-bom-plus-crlf.stderr)0
-rw-r--r--src/test/ui/json/json-invalid.rs (renamed from src/test/ui/json-invalid.rs)0
-rw-r--r--src/test/ui/json/json-invalid.stderr (renamed from src/test/ui/json-invalid.stderr)0
-rw-r--r--src/test/ui/json/json-multiple.polonius.stderr (renamed from src/test/ui/json-multiple.polonius.stderr)0
-rw-r--r--src/test/ui/json/json-multiple.rs (renamed from src/test/ui/json-multiple.rs)0
-rw-r--r--src/test/ui/json/json-multiple.stderr1
-rw-r--r--src/test/ui/json/json-options.polonius.stderr (renamed from src/test/ui/json-options.polonius.stderr)0
-rw-r--r--src/test/ui/json/json-options.rs (renamed from src/test/ui/json-options.rs)0
-rw-r--r--src/test/ui/json/json-options.stderr1
-rw-r--r--src/test/ui/json/json-short.rs (renamed from src/test/ui/json-short.rs)0
-rw-r--r--src/test/ui/json/json-short.stderr (renamed from src/test/ui/json-short.stderr)0
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params-2.rs2
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params-2.stderr4
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params.stderr12
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr6
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr6
-rw-r--r--src/test/ui/kindck/kindck-nonsendable-1.stderr10
-rw-r--r--src/test/ui/kindck/kindck-send-object.stderr12
-rw-r--r--src/test/ui/kindck/kindck-send-object1.stderr12
-rw-r--r--src/test/ui/kindck/kindck-send-object2.stderr12
-rw-r--r--src/test/ui/kindck/kindck-send-owned.stderr6
-rw-r--r--src/test/ui/label/label_break_value_continue.rs1
-rw-r--r--src/test/ui/label/label_break_value_continue.stderr6
-rw-r--r--src/test/ui/label/label_break_value_desugared_break.rs9
-rw-r--r--src/test/ui/label/label_break_value_illegal_uses.fixed1
-rw-r--r--src/test/ui/label/label_break_value_illegal_uses.rs1
-rw-r--r--src/test/ui/label/label_break_value_illegal_uses.stderr8
-rw-r--r--src/test/ui/label/label_break_value_unlabeled_break.rs1
-rw-r--r--src/test/ui/label/label_break_value_unlabeled_break.stderr4
-rw-r--r--src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr4
-rw-r--r--src/test/ui/layout/zero-sized-array-enum-niche.stderr2
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/branches.stderr6
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr12
-rw-r--r--src/test/ui/let-else/const-fn.rs19
-rw-r--r--src/test/ui/let-else/issue-100103.rs15
-rw-r--r--src/test/ui/let-else/issue-102317.rs20
-rw-r--r--src/test/ui/let-else/issue-94176.rs10
-rw-r--r--src/test/ui/let-else/issue-94176.stderr19
-rw-r--r--src/test/ui/let-else/issue-99975.rs20
-rw-r--r--src/test/ui/let-else/let-else-allow-in-expr.rs2
-rw-r--r--src/test/ui/let-else/let-else-allow-in-expr.stderr6
-rw-r--r--src/test/ui/let-else/let-else-allow-unused.rs2
-rw-r--r--src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs2
-rw-r--r--src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs4
-rw-r--r--src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs2
-rw-r--r--src/test/ui/let-else/let-else-binding-explicit-mut.rs2
-rw-r--r--src/test/ui/let-else/let-else-binding-immutable.rs2
-rw-r--r--src/test/ui/let-else/let-else-bindings.rs2
-rw-r--r--src/test/ui/let-else/let-else-bool-binop-init.fixed2
-rw-r--r--src/test/ui/let-else/let-else-bool-binop-init.rs2
-rw-r--r--src/test/ui/let-else/let-else-brace-before-else.fixed2
-rw-r--r--src/test/ui/let-else/let-else-brace-before-else.rs2
-rw-r--r--src/test/ui/let-else/let-else-check.rs2
-rw-r--r--src/test/ui/let-else/let-else-check.stderr6
-rw-r--r--src/test/ui/let-else/let-else-deref-coercion-annotated.rs2
-rw-r--r--src/test/ui/let-else/let-else-deref-coercion.rs2
-rw-r--r--src/test/ui/let-else/let-else-destructuring.rs1
-rw-r--r--src/test/ui/let-else/let-else-destructuring.stderr4
-rw-r--r--src/test/ui/let-else/let-else-drop-order.rs270
-rw-r--r--src/test/ui/let-else/let-else-drop-order.run.stdout51
-rw-r--r--src/test/ui/let-else/let-else-if.rs2
-rw-r--r--src/test/ui/let-else/let-else-if.stderr2
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.rs2
-rw-r--r--src/test/ui/let-else/let-else-missing-semicolon.rs2
-rw-r--r--src/test/ui/let-else/let-else-missing-semicolon.stderr4
-rw-r--r--src/test/ui/let-else/let-else-no-double-error.rs2
-rw-r--r--src/test/ui/let-else/let-else-non-copy.rs2
-rw-r--r--src/test/ui/let-else/let-else-non-diverging.rs2
-rw-r--r--src/test/ui/let-else/let-else-non-diverging.stderr6
-rw-r--r--src/test/ui/let-else/let-else-ref-bindings-pass.rs2
-rw-r--r--src/test/ui/let-else/let-else-ref-bindings.rs2
-rw-r--r--src/test/ui/let-else/let-else-run-pass.rs2
-rw-r--r--src/test/ui/let-else/let-else-scope.rs2
-rw-r--r--src/test/ui/let-else/let-else-scope.stderr2
-rw-r--r--src/test/ui/let-else/let-else-slicing-error.rs2
-rw-r--r--src/test/ui/let-else/let-else-source-expr-nomove-pass.rs2
-rw-r--r--src/test/ui/let-else/let-else-temp-borrowck.rs2
-rw-r--r--src/test/ui/let-else/let-else-temporary-lifetime.rs13
-rw-r--r--src/test/ui/let-else/let-else-then-diverge.rs19
-rw-r--r--src/test/ui/let-else/let-else-then-diverge.stderr14
-rw-r--r--src/test/ui/let-else/let-else.rs8
-rw-r--r--src/test/ui/lexical-scopes.stderr2
-rw-r--r--src/test/ui/lifetimes/fullwidth-ampersand.rs7
-rw-r--r--src/test/ui/lifetimes/fullwidth-ampersand.stderr26
-rw-r--r--src/test/ui/lifetimes/issue-26638.stderr2
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs6
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr14
-rw-r--r--src/test/ui/lifetimes/missing-lifetime-in-alias.rs2
-rw-r--r--src/test/ui/lifetimes/missing-lifetime-in-alias.stderr10
-rw-r--r--src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs9
-rw-r--r--src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr23
-rw-r--r--src/test/ui/limits/issue-17913.rs6
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-early.stderr4
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-late.stderr4
-rw-r--r--src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr15
-rw-r--r--src/test/ui/lint/force-warn/cap-lints-allow.stderr15
-rw-r--r--src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr15
-rw-r--r--src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr15
-rw-r--r--src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr15
-rw-r--r--src/test/ui/lint/issue-101284.rs15
-rw-r--r--src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs2
-rw-r--r--src/test/ui/lint/let_underscore/let_underscore_drop.rs14
-rw-r--r--src/test/ui/lint/let_underscore/let_underscore_drop.stderr22
-rw-r--r--src/test/ui/lint/let_underscore/let_underscore_lock.rs7
-rw-r--r--src/test/ui/lint/let_underscore/let_underscore_lock.stderr20
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-early.rs176
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-early.stderr486
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-late.rs197
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-late.stderr428
-rw-r--r--src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs30
-rw-r--r--src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr27
-rw-r--r--src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr27
-rw-r--r--src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr (renamed from src/test/ui/lint/must_not_suspend/ref.stderr)8
-rw-r--r--src/test/ui/lint/must_not_suspend/ref.rs12
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.rs15
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.stderr60
-rw-r--r--src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr12
-rw-r--r--src/test/ui/lint/unused/lint-unused-variables.stderr28
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.rs6
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.stderr14
-rw-r--r--src/test/ui/lint/unused_labels.rs1
-rw-r--r--src/test/ui/lint/unused_labels.stderr20
-rw-r--r--src/test/ui/lint/unused_parens_multibyte_recovery.rs11
-rw-r--r--src/test/ui/lint/unused_parens_multibyte_recovery.stderr43
-rw-r--r--src/test/ui/liveness/liveness-consts.stderr12
-rw-r--r--src/test/ui/lowering/issue-96847.rs14
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr2
-rw-r--r--src/test/ui/macros/auxiliary/issue-100199.rs18
-rw-r--r--src/test/ui/macros/issue-100199.rs16
-rw-r--r--src/test/ui/macros/issue-100199.stderr15
-rw-r--r--src/test/ui/macros/stringify.rs11
-rw-r--r--src/test/ui/malformed/malformed-regressions.stderr4
-rw-r--r--src/test/ui/match/issue-42679.rs7
-rw-r--r--src/test/ui/match/match_non_exhaustive.rs2
-rw-r--r--src/test/ui/match/match_non_exhaustive.stderr8
-rw-r--r--src/test/ui/methods/method-call-err-msg.stderr16
-rw-r--r--src/test/ui/methods/method-on-ambiguous-numeric-type.stderr8
-rw-r--r--src/test/ui/mir/issue-100476-recursion-check-blewup.rs42
-rw-r--r--src/test/ui/mir/issue-101844.rs73
-rw-r--r--src/test/ui/mir/issue-102389.rs8
-rw-r--r--src/test/ui/mir/issue-102389.stderr9
-rw-r--r--src/test/ui/mir/issue-99852.rs24
-rw-r--r--src/test/ui/mir/issue-99866.rs25
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-100550-unnormalized-projection.rs30
-rw-r--r--src/test/ui/mir/mir_codegen_calls_diverging_drops.rs1
-rw-r--r--src/test/ui/mismatched_types/E0409.stderr4
-rw-r--r--src/test/ui/mismatched_types/E0631.rs2
-rw-r--r--src/test/ui/mismatched_types/E0631.stderr8
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.rs2
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.stderr8
-rw-r--r--src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs23
-rw-r--r--src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr26
-rw-r--r--src/test/ui/mismatched_types/dont-point-return-on-E0308.rs18
-rw-r--r--src/test/ui/mismatched_types/dont-point-return-on-E0308.stderr19
-rw-r--r--src/test/ui/mismatched_types/issue-19109.stderr2
-rw-r--r--src/test/ui/mismatched_types/issue-84976.stderr5
-rw-r--r--src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr6
-rw-r--r--src/test/ui/mismatched_types/normalize-fn-sig.rs16
-rw-r--r--src/test/ui/mismatched_types/normalize-fn-sig.stderr19
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.stderr4
-rw-r--r--src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed21
-rw-r--r--src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs21
-rw-r--r--src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr49
-rw-r--r--src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed28
-rw-r--r--src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs28
-rw-r--r--src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr47
-rw-r--r--src/test/ui/modules/auxiliary/dummy_lib.rs2
-rw-r--r--src/test/ui/modules/special_module_name.rs8
-rw-r--r--src/test/ui/modules/special_module_name.stderr37
-rw-r--r--src/test/ui/modules/special_module_name_ignore.rs9
-rw-r--r--src/test/ui/moves/move-out-of-array-ref.stderr4
-rw-r--r--src/test/ui/moves/move-out-of-slice-2.stderr8
-rw-r--r--src/test/ui/mutexguard-sync.stderr2
-rw-r--r--src/test/ui/namespace/namespace-mix.stderr8
-rw-r--r--src/test/ui/nested-ty-params.stderr12
-rw-r--r--src/test/ui/never_type/defaulted-never-note.fallback.stderr6
-rw-r--r--src/test/ui/never_type/defaulted-never-note.rs1
-rw-r--r--src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr6
-rw-r--r--src/test/ui/never_type/fallback-closure-wrap.fallback.stderr2
-rw-r--r--src/test/ui/never_type/fallback-closure-wrap.rs4
-rw-r--r--src/test/ui/never_type/feature-gate-never_type_fallback.stderr8
-rw-r--r--src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr20
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr12
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr12
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr7
-rw-r--r--src/test/ui/nll/issue-21232-partial-init-and-use.rs2
-rw-r--r--src/test/ui/nll/issue-51244.stderr2
-rw-r--r--src/test/ui/nll/local-outlives-static-via-hrtb.stderr12
-rw-r--r--src/test/ui/nll/normalization-bounds-error.stderr8
-rw-r--r--src/test/ui/nll/polonius/assignment-kills-loans.rs2
-rw-r--r--src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs1
-rw-r--r--src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr11
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr22
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr22
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr27
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr26
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr43
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr14
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr27
-rw-r--r--src/test/ui/nll/type-test-universe.stderr6
-rw-r--r--src/test/ui/nll/user-annotations/adt-nullary-enums.stderr5
-rw-r--r--src/test/ui/nll/user-annotations/adt-tuple-struct-calls.stderr10
-rw-r--r--src/test/ui/nll/user-annotations/fns.stderr6
-rw-r--r--src/test/ui/nll/user-annotations/method-call.stderr5
-rw-r--r--src/test/ui/nll/user-annotations/method-ufcs-3.stderr5
-rw-r--r--src/test/ui/no-send-res-ports.stderr17
-rw-r--r--src/test/ui/not-clone-closure.stderr6
-rw-r--r--src/test/ui/not-enough-arguments.stderr4
-rw-r--r--src/test/ui/not-panic/not-panic-safe-2.stderr12
-rw-r--r--src/test/ui/not-panic/not-panic-safe-3.stderr12
-rw-r--r--src/test/ui/not-panic/not-panic-safe-4.stderr12
-rw-r--r--src/test/ui/not-panic/not-panic-safe-5.stderr6
-rw-r--r--src/test/ui/not-panic/not-panic-safe-6.stderr12
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default.rs44
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default.stderr60
-rw-r--r--src/test/ui/object-safety/issue-19538.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.curr.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-bounds.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-generics.curr.stderr8
-rw-r--r--src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr8
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.curr.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.curr.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-sized.curr.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/on-unimplemented/enclosing-scope.rs27
-rw-r--r--src/test/ui/on-unimplemented/enclosing-scope.stderr86
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.rs3
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.stderr51
-rw-r--r--src/test/ui/on-unimplemented/on-impl.rs1
-rw-r--r--src/test/ui/on-unimplemented/on-impl.stderr15
-rw-r--r--src/test/ui/on-unimplemented/parent-label.rs27
-rw-r--r--src/test/ui/on-unimplemented/parent-label.stderr69
-rw-r--r--src/test/ui/on-unimplemented/slice-index.stderr4
-rw-r--r--src/test/ui/or-patterns/inner-or-pat.or3.stderr11
-rw-r--r--src/test/ui/or-patterns/inner-or-pat.or4.stderr11
-rw-r--r--src/test/ui/or-patterns/inner-or-pat.rs73
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.rs16
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr13
-rw-r--r--src/test/ui/parser/bad-interpolated-block.rs2
-rw-r--r--src/test/ui/parser/bad-interpolated-block.stderr6
-rw-r--r--src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs4
-rw-r--r--src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr24
-rw-r--r--src/test/ui/parser/do-not-suggest-semicolon-before-array.rs8
-rw-r--r--src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr10
-rw-r--r--src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs3
-rw-r--r--src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr8
-rw-r--r--src/test/ui/parser/fn-defined-using-def.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-def.stderr10
-rw-r--r--src/test/ui/parser/fn-defined-using-fun.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-fun.stderr10
-rw-r--r--src/test/ui/parser/fn-defined-using-func.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-func.stderr10
-rw-r--r--src/test/ui/parser/fn-defined-using-function.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-function.stderr10
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.rs2
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr184
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs2
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr20
-rw-r--r--src/test/ui/parser/increment-notfixed.stderr30
-rw-r--r--src/test/ui/parser/issue-100197-mut-let.fixed6
-rw-r--r--src/test/ui/parser/issue-100197-mut-let.rs6
-rw-r--r--src/test/ui/parser/issue-100197-mut-let.stderr8
-rw-r--r--src/test/ui/parser/issue-101477-enum.fixed10
-rw-r--r--src/test/ui/parser/issue-101477-enum.rs10
-rw-r--r--src/test/ui/parser/issue-101477-enum.stderr14
-rw-r--r--src/test/ui/parser/issue-101477-let.fixed6
-rw-r--r--src/test/ui/parser/issue-101477-let.rs6
-rw-r--r--src/test/ui/parser/issue-101477-let.stderr8
-rw-r--r--src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed8
-rw-r--r--src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs8
-rw-r--r--src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr14
-rw-r--r--src/test/ui/parser/issues/issue-14303-enum.rs6
-rw-r--r--src/test/ui/parser/issues/issue-14303-enum.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-fn-def.rs4
-rw-r--r--src/test/ui/parser/issues/issue-14303-fn-def.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-impl.rs6
-rw-r--r--src/test/ui/parser/issues/issue-14303-impl.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-path.rs13
-rw-r--r--src/test/ui/parser/issues/issue-14303-path.stderr9
-rw-r--r--src/test/ui/parser/issues/issue-14303-struct.rs6
-rw-r--r--src/test/ui/parser/issues/issue-14303-struct.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-trait.rs4
-rw-r--r--src/test/ui/parser/issues/issue-14303-trait.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303.rs33
-rw-r--r--src/test/ui/parser/issues/issue-14303.stderr39
-rw-r--r--src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr4
-rw-r--r--src/test/ui/parser/issues/issue-89574.stderr4
-rw-r--r--src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr4
-rw-r--r--src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr8
-rw-r--r--src/test/ui/parser/kw-in-trait-bounds.rs47
-rw-r--r--src/test/ui/parser/kw-in-trait-bounds.stderr171
-rw-r--r--src/test/ui/parser/labeled-no-colon-expr.rs2
-rw-r--r--src/test/ui/parser/labeled-no-colon-expr.stderr16
-rw-r--r--src/test/ui/parser/public-instead-of-pub-1.fixed11
-rw-r--r--src/test/ui/parser/public-instead-of-pub-1.rs11
-rw-r--r--src/test/ui/parser/public-instead-of-pub-1.stderr13
-rw-r--r--src/test/ui/parser/public-instead-of-pub-2.rs7
-rw-r--r--src/test/ui/parser/public-instead-of-pub-2.stderr8
-rw-r--r--src/test/ui/parser/public-instead-of-pub-3.fixed9
-rw-r--r--src/test/ui/parser/public-instead-of-pub-3.rs9
-rw-r--r--src/test/ui/parser/public-instead-of-pub-3.stderr13
-rw-r--r--src/test/ui/parser/recover-field-semi.rs16
-rw-r--r--src/test/ui/parser/recover-field-semi.stderr29
-rw-r--r--src/test/ui/parser/recover-labeled-non-block-expr.fixed1
-rw-r--r--src/test/ui/parser/recover-labeled-non-block-expr.rs1
-rw-r--r--src/test/ui/parser/recover-labeled-non-block-expr.stderr12
-rw-r--r--src/test/ui/parser/recover-missing-semi-before-item.fixed61
-rw-r--r--src/test/ui/parser/recover-missing-semi-before-item.rs61
-rw-r--r--src/test/ui/parser/recover-missing-semi-before-item.stderr83
-rw-r--r--src/test/ui/parser/removed-syntax-field-semicolon.rs2
-rw-r--r--src/test/ui/parser/removed-syntax-field-semicolon.stderr4
-rw-r--r--src/test/ui/parser/removed-syntax-static-fn.stderr4
-rw-r--r--src/test/ui/parser/struct-filed-with-attr.fixed18
-rw-r--r--src/test/ui/parser/struct-filed-with-attr.rs18
-rw-r--r--src/test/ui/parser/struct-filed-with-attr.stderr8
-rw-r--r--src/test/ui/parser/struct-literal-in-for.stderr2
-rw-r--r--src/test/ui/parser/suggest-assoc-const.fixed10
-rw-r--r--src/test/ui/parser/suggest-assoc-const.rs10
-rw-r--r--src/test/ui/parser/suggest-assoc-const.stderr8
-rw-r--r--src/test/ui/parser/suggest-const-for-global-var.rs6
-rw-r--r--src/test/ui/parser/suggest-const-for-global-var.stderr8
-rw-r--r--src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed7
-rw-r--r--src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs7
-rw-r--r--src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr15
-rw-r--r--src/test/ui/parser/suggest-semicolon-before-array.fixed11
-rw-r--r--src/test/ui/parser/suggest-semicolon-before-array.rs11
-rw-r--r--src/test/ui/parser/suggest-semicolon-before-array.stderr13
-rw-r--r--src/test/ui/parser/trait-object-delimiters.rs2
-rw-r--r--src/test/ui/parser/trait-object-delimiters.stderr4
-rw-r--r--src/test/ui/parser/trait-object-trait-parens.stderr15
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.fixed2
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.rs2
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.stderr6
-rw-r--r--src/test/ui/parser/type-alias-where.rs2
-rw-r--r--src/test/ui/parser/type-alias-where.stderr4
-rw-r--r--src/test/ui/parser/unnecessary-let.rs11
-rw-r--r--src/test/ui/parser/unnecessary-let.stderr20
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr10
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr5
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr37
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr30
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr40
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr52
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr45
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr35
-rw-r--r--src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr5
-rw-r--r--src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr2
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr2
-rw-r--r--src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr6
-rw-r--r--src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr30
-rw-r--r--src/test/ui/pattern/rest-pat-semantic-disallowed.rs2
-rw-r--r--src/test/ui/pattern/rest-pat-syntactic.rs5
-rw-r--r--src/test/ui/pattern/rest-pat-syntactic.stderr24
-rw-r--r--src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.fixed10
-rw-r--r--src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.rs9
-rw-r--r--src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.stderr24
-rw-r--r--src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs8
-rw-r--r--src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr24
-rw-r--r--src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr28
-rw-r--r--src/test/ui/pattern/usefulness/empty-match.normal.stderr28
-rw-r--r--src/test/ui/pattern/usefulness/empty-match.rs12
-rw-r--r--src/test/ui/pattern/usefulness/issue-15129.rs2
-rw-r--r--src/test/ui/pattern/usefulness/issue-15129.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/issue-31561.rs2
-rw-r--r--src/test/ui/pattern/usefulness/issue-31561.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/issue-35609.stderr32
-rw-r--r--src/test/ui/pattern/usefulness/issue-39362.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/issue-40221.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/issue-50900.rs2
-rw-r--r--src/test/ui/pattern/usefulness/issue-50900.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/issue-56379.rs2
-rw-r--r--src/test/ui/pattern/usefulness/issue-56379.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/issue-72377.rs2
-rw-r--r--src/test/ui/pattern/usefulness/issue-72377.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/match-arm-statics-2.rs4
-rw-r--r--src/test/ui/pattern/usefulness/match-arm-statics-2.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs32
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr42
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs2
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.rs6
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.stderr20
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs10
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr28
-rw-r--r--src/test/ui/pattern/usefulness/stable-gated-patterns.rs2
-rw-r--r--src/test/ui/pattern/usefulness/stable-gated-patterns.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/top-level-alternation.rs2
-rw-r--r--src/test/ui/pattern/usefulness/top-level-alternation.stderr24
-rw-r--r--src/test/ui/pattern/usefulness/unstable-gated-patterns.rs2
-rw-r--r--src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr6
-rw-r--r--src/test/ui/phantom-auto-trait.stderr4
-rw-r--r--src/test/ui/privacy/access_levels.rs49
-rw-r--r--src/test/ui/privacy/access_levels.stderr125
-rw-r--r--src/test/ui/proc-macro/auxiliary/expand-expr.rs23
-rw-r--r--src/test/ui/proc-macro/auxiliary/re-export.rs19
-rw-r--r--src/test/ui/proc-macro/crt-static.rs2
-rw-r--r--src/test/ui/proc-macro/dollar-crate-issue-101211.rs29
-rw-r--r--src/test/ui/proc-macro/expand-to-unstable-2.rs17
-rw-r--r--src/test/ui/proc-macro/expand-to-unstable-2.stderr10
-rw-r--r--src/test/ui/proc-macro/inner-attrs.rs1
-rw-r--r--src/test/ui/proc-macro/inner-attrs.stderr8
-rw-r--r--src/test/ui/proc-macro/inner-attrs.stdout356
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-1.rs1
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-1.stderr2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-2.rs1
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-2.stderr2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-3.rs1
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-3.stderr2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.rs1
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.stderr6
-rw-r--r--src/test/ui/proc-macro/issue-36935.rs1
-rw-r--r--src/test/ui/proc-macro/issue-36935.stderr4
-rw-r--r--src/test/ui/proc-macro/issue-41211.rs16
-rw-r--r--src/test/ui/proc-macro/issue-41211.stderr22
-rw-r--r--src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs1
-rw-r--r--src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.stderr2
-rw-r--r--src/test/ui/proc-macro/issue-79148.rs10
-rw-r--r--src/test/ui/proc-macro/issue-79148.stderr16
-rw-r--r--src/test/ui/proc-macro/load-panic-backtrace.rs1
-rw-r--r--src/test/ui/proc-macro/load-panic-backtrace.stderr2
-rw-r--r--src/test/ui/proc-macro/load-panic.rs1
-rw-r--r--src/test/ui/proc-macro/load-panic.stderr2
-rw-r--r--src/test/ui/proc-macro/signature.stderr7
-rw-r--r--src/test/ui/process/core-run-destroy.rs1
-rw-r--r--src/test/ui/process/process-envs.rs1
-rw-r--r--src/test/ui/process/process-remove-from-env.rs1
-rw-r--r--src/test/ui/process/process-sigpipe.rs1
-rw-r--r--src/test/ui/ptr_ops/issue-80309-safe.rs1
-rw-r--r--src/test/ui/ptr_ops/issue-80309.rs1
-rw-r--r--src/test/ui/range/range-1.stderr6
-rw-r--r--src/test/ui/recursion/issue-83150.stderr6
-rw-r--r--src/test/ui/recursion/issue-95134.rs28
-rw-r--r--src/test/ui/recursion/issue-95134.stderr7
-rw-r--r--src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr2
-rw-r--r--src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.rs12
-rw-r--r--src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr14
-rw-r--r--src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs2
-rw-r--r--src/test/ui/regions/outlives-with-missing.rs16
-rw-r--r--src/test/ui/regions/outlives-with-missing.stderr12
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs3
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr17
-rw-r--r--src/test/ui/reify-intrinsic.stderr3
-rw-r--r--src/test/ui/repr/invalid_repr_list_help.rs17
-rw-r--r--src/test/ui/repr/invalid_repr_list_help.stderr35
-rw-r--r--src/test/ui/resolve/bad-type-env-capture.stderr6
-rw-r--r--src/test/ui/resolve/issue-100365.rs50
-rw-r--r--src/test/ui/resolve/issue-100365.stderr54
-rw-r--r--src/test/ui/resolve/issue-22692.rs59
-rw-r--r--src/test/ui/resolve/issue-22692.stderr85
-rw-r--r--src/test/ui/resolve/issue-3021-c.stderr16
-rw-r--r--src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs1
-rw-r--r--src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr43
-rw-r--r--src/test/ui/resolve/issue-73427.rs6
-rw-r--r--src/test/ui/resolve/issue-73427.stderr44
-rw-r--r--src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs21
-rw-r--r--src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr12
-rw-r--r--src/test/ui/resolve/privacy-enum-ctor.stderr22
-rw-r--r--src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr8
-rw-r--r--src/test/ui/resolve/resolve-inconsistent-names.rs1
-rw-r--r--src/test/ui/resolve/resolve-inconsistent-names.stderr9
-rw-r--r--src/test/ui/resolve/resolve-primitive-fallback.stderr2
-rw-r--r--src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr18
-rw-r--r--src/test/ui/resolve/suggest-path-for-tuple-struct.stderr8
-rw-r--r--src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs52
-rw-r--r--src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr82
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs8
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr11
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs4
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr12
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr16
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr6
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr6
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr6
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr48
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr42
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs9
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr8
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs10
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr8
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs9
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr8
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs17
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr14
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs7
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr8
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs7
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr19
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs6
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr15
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs6
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr15
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs6
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr21
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs24
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr20
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs6
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr15
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs6
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr15
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs17
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr14
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs1
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr13
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs3
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr13
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs2
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs29
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr12
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr6
-rw-r--r--src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr12
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.stderr25
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes.stderr45
-rw-r--r--src/test/ui/sanitize/memory-eager.rs38
-rw-r--r--src/test/ui/sanitize/memory.rs14
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr2
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/simd/intrinsic/ptr-cast.rs33
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs5
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr46
-rw-r--r--src/test/ui/span/issue-34264.stderr6
-rw-r--r--src/test/ui/span/issue-35987.stderr4
-rw-r--r--src/test/ui/span/issue-36530.rs12
-rw-r--r--src/test/ui/span/issue-36530.stderr12
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.rs4
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.stderr18
-rw-r--r--src/test/ui/span/lint-unused-unsafe.mir.stderr548
-rw-r--r--src/test/ui/span/lint-unused-unsafe.rs74
-rw-r--r--src/test/ui/span/missing-unit-argument.stderr16
-rw-r--r--src/test/ui/specialization/default-generic-associated-type-bound.rs3
-rw-r--r--src/test/ui/specialization/default-generic-associated-type-bound.stderr6
-rw-r--r--src/test/ui/specialization/issue-33017.rs2
-rw-r--r--src/test/ui/specialization/issue-38091-2.stderr2
-rw-r--r--src/test/ui/specialization/issue-39448.stderr4
-rw-r--r--src/test/ui/specialization/issue-45814.stderr4
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.stderr22
-rw-r--r--src/test/ui/stability-attribute/auxiliary/ctor-stability.rs8
-rw-r--r--src/test/ui/stability-attribute/auxiliary/default_body.rs29
-rw-r--r--src/test/ui/stability-attribute/ctor-stability.rs8
-rw-r--r--src/test/ui/stability-attribute/default-body-stability-err.rs19
-rw-r--r--src/test/ui/stability-attribute/default-body-stability-err.stderr38
-rw-r--r--src/test/ui/stability-attribute/default-body-stability-ok-enables.rs18
-rw-r--r--src/test/ui/stability-attribute/default-body-stability-ok-impls.rs21
-rw-r--r--src/test/ui/static/static-vec-repeat-not-constant.stderr1
-rw-r--r--src/test/ui/stats/hir-stats.rs42
-rw-r--r--src/test/ui/stats/hir-stats.stderr178
-rw-r--r--src/test/ui/std-backtrace.rs2
-rw-r--r--src/test/ui/str/str-idx.stderr4
-rw-r--r--src/test/ui/str/str-mut-idx.stderr4
-rw-r--r--src/test/ui/structs-enums/align-struct.rs5
-rw-r--r--src/test/ui/structs-enums/type-sizes.rs79
-rw-r--r--src/test/ui/structs/struct-record-suggestion.fixed24
-rw-r--r--src/test/ui/structs/struct-record-suggestion.rs24
-rw-r--r--src/test/ui/structs/struct-record-suggestion.stderr23
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.stderr24
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.stderr2
-rw-r--r--src/test/ui/suggestions/as-ref-2.fixed13
-rw-r--r--src/test/ui/suggestions/as-ref-2.rs2
-rw-r--r--src/test/ui/suggestions/as-ref-2.stderr10
-rw-r--r--src/test/ui/suggestions/as-ref.rs7
-rw-r--r--src/test/ui/suggestions/as-ref.stderr62
-rw-r--r--src/test/ui/suggestions/assoc-const-as-field.stderr4
-rw-r--r--src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr4
-rw-r--r--src/test/ui/suggestions/bool_typo_err_suggest.rs12
-rw-r--r--src/test/ui/suggestions/bool_typo_err_suggest.stderr25
-rw-r--r--src/test/ui/suggestions/call-boxed.rs7
-rw-r--r--src/test/ui/suggestions/call-boxed.stderr20
-rw-r--r--src/test/ui/suggestions/call-on-missing.rs39
-rw-r--r--src/test/ui/suggestions/call-on-missing.stderr75
-rw-r--r--src/test/ui/suggestions/const-no-type.rs14
-rw-r--r--src/test/ui/suggestions/const-no-type.stderr28
-rw-r--r--src/test/ui/suggestions/copied-and-cloned.fixed23
-rw-r--r--src/test/ui/suggestions/copied-and-cloned.rs23
-rw-r--r--src/test/ui/suggestions/copied-and-cloned.stderr83
-rw-r--r--src/test/ui/suggestions/deref-path-method.rs6
-rw-r--r--src/test/ui/suggestions/deref-path-method.stderr14
-rw-r--r--src/test/ui/suggestions/derive-clone-for-eq.stderr2
-rw-r--r--src/test/ui/suggestions/derive-macro-missing-bounds.stderr16
-rw-r--r--src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr2
-rw-r--r--src/test/ui/suggestions/dont-try-removing-the-field.rs17
-rw-r--r--src/test/ui/suggestions/dont-try-removing-the-field.stderr10
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr14
-rw-r--r--src/test/ui/suggestions/field-access-considering-privacy.rs35
-rw-r--r--src/test/ui/suggestions/field-access-considering-privacy.stderr14
-rw-r--r--src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr4
-rw-r--r--src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr60
-rw-r--r--src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr6
-rw-r--r--src/test/ui/suggestions/imm-ref-trait-object-literal.stderr2
-rw-r--r--src/test/ui/suggestions/into-str.stderr2
-rw-r--r--src/test/ui/suggestions/issue-101421.rs12
-rw-r--r--src/test/ui/suggestions/issue-101421.stderr17
-rw-r--r--src/test/ui/suggestions/issue-101465.rs25
-rw-r--r--src/test/ui/suggestions/issue-101465.stderr25
-rw-r--r--src/test/ui/suggestions/issue-101984.rs27
-rw-r--r--src/test/ui/suggestions/issue-101984.stderr14
-rw-r--r--src/test/ui/suggestions/issue-61963.stderr35
-rw-r--r--src/test/ui/suggestions/issue-62843.stderr4
-rw-r--r--src/test/ui/suggestions/issue-71394-no-from-impl.stderr8
-rw-r--r--src/test/ui/suggestions/issue-84973-2.stderr2
-rw-r--r--src/test/ui/suggestions/issue-84973-blacklist.stderr6
-rw-r--r--src/test/ui/suggestions/issue-84973-negative.stderr2
-rw-r--r--src/test/ui/suggestions/issue-84973.stderr2
-rw-r--r--src/test/ui/suggestions/issue-85347.rs3
-rw-r--r--src/test/ui/suggestions/issue-85347.stderr15
-rw-r--r--src/test/ui/suggestions/issue-89064.rs35
-rw-r--r--src/test/ui/suggestions/issue-89064.stderr82
-rw-r--r--src/test/ui/suggestions/issue-96223.stderr4
-rw-r--r--src/test/ui/suggestions/issue-96555.stderr6
-rw-r--r--src/test/ui/suggestions/issue-97677.fixed2
-rw-r--r--src/test/ui/suggestions/issue-97677.stderr4
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr4
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr18
-rw-r--r--src/test/ui/suggestions/many-type-ascription.rs4
-rw-r--r--src/test/ui/suggestions/many-type-ascription.stderr12
-rw-r--r--src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.rs18
-rw-r--r--src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr24
-rw-r--r--src/test/ui/suggestions/option-content-move.fixed39
-rw-r--r--src/test/ui/suggestions/option-content-move.rs2
-rw-r--r--src/test/ui/suggestions/option-content-move.stderr14
-rw-r--r--src/test/ui/suggestions/restrict-type-not-param.rs12
-rw-r--r--src/test/ui/suggestions/restrict-type-not-param.stderr26
-rw-r--r--src/test/ui/suggestions/return-closures.rs13
-rw-r--r--src/test/ui/suggestions/return-closures.stderr27
-rw-r--r--src/test/ui/suggestions/return-cycle-2.rs14
-rw-r--r--src/test/ui/suggestions/return-cycle-2.stderr12
-rw-r--r--src/test/ui/suggestions/return-cycle.rs14
-rw-r--r--src/test/ui/suggestions/return-cycle.stderr12
-rw-r--r--src/test/ui/suggestions/slice-issue-87994.stderr16
-rw-r--r--src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.rs10
-rw-r--r--src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.stderr21
-rw-r--r--src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed15
-rw-r--r--src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs15
-rw-r--r--src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr25
-rw-r--r--src/test/ui/suggestions/suggest-blanket-impl-local-trait.rs2
-rw-r--r--src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr35
-rw-r--r--src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr4
-rw-r--r--src/test/ui/suggestions/suggest-dereferencing-index.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr6
-rw-r--r--src/test/ui/suggestions/suggest-methods.stderr8
-rw-r--r--src/test/ui/suggestions/suggest-move-lifetimes.stderr8
-rw-r--r--src/test/ui/suggestions/suggest-move-types.stderr4
-rw-r--r--src/test/ui/suggestions/suggest-ref-macro.stderr10
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-1.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-2.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-3.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr5
-rw-r--r--src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr5
-rw-r--r--src/test/ui/suggestions/too-many-field-suggestions.rs29
-rw-r--r--src/test/ui/suggestions/too-many-field-suggestions.stderr44
-rw-r--r--src/test/ui/suggestions/try-removing-the-field.rs17
-rw-r--r--src/test/ui/suggestions/try-removing-the-field.stderr12
-rw-r--r--src/test/ui/suggestions/type-ascription-and-other-error.rs6
-rw-r--r--src/test/ui/suggestions/type-ascription-and-other-error.stderr8
-rw-r--r--src/test/ui/suggestions/unnamable-types.stderr20
-rw-r--r--src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr2
-rw-r--r--src/test/ui/tag-variant-disr-dup.rs12
-rw-r--r--src/test/ui/tag-variant-disr-dup.stderr14
-rw-r--r--src/test/ui/thir-tree.stdout22
-rw-r--r--src/test/ui/traits/alias/cross-crate.stderr4
-rw-r--r--src/test/ui/traits/alias/generic-default-in-dyn.rs10
-rw-r--r--src/test/ui/traits/alias/generic-default-in-dyn.stderr39
-rw-r--r--src/test/ui/traits/alias/self-in-const-generics.rs12
-rw-r--r--src/test/ui/traits/alias/self-in-const-generics.stderr11
-rw-r--r--src/test/ui/traits/alias/self-in-generics.rs15
-rw-r--r--src/test/ui/traits/alias/self-in-generics.stderr11
-rw-r--r--src/test/ui/traits/assoc-type-in-superbad.rs8
-rw-r--r--src/test/ui/traits/assoc-type-in-superbad.stderr6
-rw-r--r--src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr4
-rw-r--r--src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr4
-rw-r--r--src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr4
-rw-r--r--src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr6
-rw-r--r--src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr6
-rw-r--r--src/test/ui/traits/bad-method-typaram-kind.stderr4
-rw-r--r--src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs3
-rw-r--r--src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr8
-rw-r--r--src/test/ui/traits/bound/not-on-bare-trait.stderr5
-rw-r--r--src/test/ui/traits/bound/on-structs-and-enums-locals.rs2
-rw-r--r--src/test/ui/traits/bound/on-structs-and-enums-locals.stderr6
-rw-r--r--src/test/ui/traits/bound/on-structs-and-enums-xc1.rs2
-rw-r--r--src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr6
-rw-r--r--src/test/ui/traits/cycle-cache-err-60010.stderr4
-rw-r--r--src/test/ui/traits/inductive-overflow/lifetime.rs2
-rw-r--r--src/test/ui/traits/inductive-overflow/lifetime.stderr4
-rw-r--r--src/test/ui/traits/inductive-overflow/simultaneous.stderr2
-rw-r--r--src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr2
-rw-r--r--src/test/ui/traits/inductive-overflow/supertrait.stderr2
-rw-r--r--src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr30
-rw-r--r--src/test/ui/traits/issue-18400.stderr4
-rw-r--r--src/test/ui/traits/issue-20692.stderr2
-rw-r--r--src/test/ui/traits/issue-38604.stderr2
-rw-r--r--src/test/ui/traits/issue-71036.rs2
-rw-r--r--src/test/ui/traits/issue-71036.stderr2
-rw-r--r--src/test/ui/traits/issue-71136.stderr2
-rw-r--r--src/test/ui/traits/issue-77982.stderr8
-rw-r--r--src/test/ui/traits/issue-82830.stderr2
-rw-r--r--src/test/ui/traits/issue-91594.stderr6
-rw-r--r--src/test/ui/traits/issue-91949-hangs-on-recursion.stderr4
-rw-r--r--src/test/ui/traits/issue-97576.stderr8
-rw-r--r--src/test/ui/traits/multidispatch-bad.stderr2
-rw-r--r--src/test/ui/traits/multidispatch-convert-ambig-dest.stderr10
-rw-r--r--src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs2
-rw-r--r--src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr8
-rw-r--r--src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr2
-rw-r--r--src/test/ui/traits/object/enforce-supertrait-projection.stderr4
-rw-r--r--src/test/ui/traits/object/safety.stderr2
-rw-r--r--src/test/ui/traits/pointee-tail-is-generic-errors.stderr8
-rw-r--r--src/test/ui/traits/resolution-in-overloaded-op.stderr4
-rw-r--r--src/test/ui/traits/suggest-deferences/issue-39029.stderr12
-rw-r--r--src/test/ui/traits/suggest-deferences/issue-62530.stderr10
-rw-r--r--src/test/ui/traits/suggest-deferences/multiple-0.stderr10
-rw-r--r--src/test/ui/traits/suggest-deferences/root-obligation.stderr4
-rw-r--r--src/test/ui/traits/suggest-where-clause.stderr4
-rw-r--r--src/test/ui/traits/test-2.stderr2
-rw-r--r--src/test/ui/traits/trait-upcasting/subtrait-method.stderr10
-rw-r--r--src/test/ui/traits/unspecified-self-in-trait-ref.rs (renamed from src/test/ui/unspecified-self-in-trait-ref.rs)0
-rw-r--r--src/test/ui/traits/unspecified-self-in-trait-ref.stderr (renamed from src/test/ui/unspecified-self-in-trait-ref.stderr)0
-rw-r--r--src/test/ui/transmutability/abstraction/abstracted_assume.rs27
-rw-r--r--src/test/ui/transmutability/abstraction/const_generic_fn.rs6
-rw-r--r--src/test/ui/transmutability/arrays/should_have_correct_length.rs4
-rw-r--r--src/test/ui/transmutability/arrays/should_inherit_alignment.rs9
-rw-r--r--src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs9
-rw-r--r--src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr120
-rw-r--r--src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs11
-rw-r--r--src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr420
-rw-r--r--src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs11
-rw-r--r--src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr126
-rw-r--r--src/test/ui/transmutability/enums/should_order_correctly.rs9
-rw-r--r--src/test/ui/transmutability/enums/should_pad_variants.rs9
-rw-r--r--src/test/ui/transmutability/enums/should_pad_variants.stderr20
-rw-r--r--src/test/ui/transmutability/enums/should_respect_endianness.rs9
-rw-r--r--src/test/ui/transmutability/enums/should_respect_endianness.stderr20
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs2
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs2
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs2
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs29
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr37
-rw-r--r--src/test/ui/transmutability/primitives/bool.rs6
-rw-r--r--src/test/ui/transmutability/primitives/bool.stderr6
-rw-r--r--src/test/ui/transmutability/primitives/numbers.rs2
-rw-r--r--src/test/ui/transmutability/primitives/numbers.stderr342
-rw-r--r--src/test/ui/transmutability/primitives/unit.rs9
-rw-r--r--src/test/ui/transmutability/primitives/unit.stderr20
-rw-r--r--src/test/ui/transmutability/references.rs11
-rw-r--r--src/test/ui/transmutability/references.stderr23
-rw-r--r--src/test/ui/transmutability/structs/repr/should_handle_align.rs11
-rw-r--r--src/test/ui/transmutability/structs/repr/should_handle_packed.rs11
-rw-r--r--src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs11
-rw-r--r--src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr252
-rw-r--r--src/test/ui/transmutability/structs/should_order_fields_correctly.rs9
-rw-r--r--src/test/ui/transmutability/unions/boolish.rs4
-rw-r--r--src/test/ui/transmutability/unions/repr/should_handle_align.rs11
-rw-r--r--src/test/ui/transmutability/unions/repr/should_handle_packed.rs11
-rw-r--r--src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs11
-rw-r--r--src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr42
-rw-r--r--src/test/ui/transmutability/unions/should_pad_variants.rs9
-rw-r--r--src/test/ui/transmutability/unions/should_pad_variants.stderr20
-rw-r--r--src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs5
-rw-r--r--src/test/ui/transmutability/unions/should_reject_contraction.rs4
-rw-r--r--src/test/ui/transmutability/unions/should_reject_contraction.stderr6
-rw-r--r--src/test/ui/transmutability/unions/should_reject_disjoint.rs5
-rw-r--r--src/test/ui/transmutability/unions/should_reject_disjoint.stderr16
-rw-r--r--src/test/ui/transmutability/unions/should_reject_intersecting.rs6
-rw-r--r--src/test/ui/transmutability/unions/should_reject_intersecting.stderr12
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs6
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs6
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs6
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs6
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs6
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr2
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr4
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr8
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr8
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr8
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs3
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr12
-rw-r--r--src/test/ui/try-block/try-block-bad-type.stderr2
-rw-r--r--src/test/ui/try-trait/bad-interconversion.stderr75
-rw-r--r--src/test/ui/try-trait/option-to-result.stderr24
-rw-r--r--src/test/ui/try-trait/try-on-option-diagnostics.stderr47
-rw-r--r--src/test/ui/try-trait/try-on-option.stderr24
-rw-r--r--src/test/ui/try-trait/try-operator-on-main.stderr30
-rw-r--r--src/test/ui/tuple/add-tuple-within-arguments.stderr4
-rw-r--r--src/test/ui/tuple/builtin-fail.rs19
-rw-r--r--src/test/ui/tuple/builtin-fail.stderr55
-rw-r--r--src/test/ui/tuple/builtin.rs20
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-3.stderr11
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-4.stderr2
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_args.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_args2.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs.stderr58
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs31
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57961.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57961.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-1.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-1.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-2.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-2.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98604.rs6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98604.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98608.rs6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98608.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr2
-rw-r--r--src/test/ui/type/issue-100584.rs15
-rw-r--r--src/test/ui/type/issue-100584.stderr44
-rw-r--r--src/test/ui/type/type-alias-bounds.rs2
-rw-r--r--src/test/ui/type/type-arg-out-of-scope.stderr12
-rw-r--r--src/test/ui/type/type-ascription-instead-of-initializer.stderr2
-rw-r--r--src/test/ui/type/type-check-defaults.stderr8
-rw-r--r--src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr16
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-2.stderr12
-rw-r--r--src/test/ui/type_length_limit.stderr4
-rw-r--r--src/test/ui/typeck/assign-non-lval-derefmut.stderr4
-rw-r--r--src/test/ui/typeck/assign-non-lval-mut-ref.stderr4
-rw-r--r--src/test/ui/typeck/assign-non-lval-needs-deref.rs19
-rw-r--r--src/test/ui/typeck/assign-non-lval-needs-deref.stderr16
-rw-r--r--src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs8
-rw-r--r--src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr20
-rw-r--r--src/test/ui/typeck/issue-100164.fixed9
-rw-r--r--src/test/ui/typeck/issue-100164.rs9
-rw-r--r--src/test/ui/typeck/issue-100164.stderr14
-rw-r--r--src/test/ui/typeck/issue-100246.rs30
-rw-r--r--src/test/ui/typeck/issue-100246.stderr13
-rw-r--r--src/test/ui/typeck/issue-100285.rs22
-rw-r--r--src/test/ui/typeck/issue-100285.stderr34
-rw-r--r--src/test/ui/typeck/issue-29124.stderr8
-rw-r--r--src/test/ui/typeck/issue-79040.stderr4
-rw-r--r--src/test/ui/typeck/issue-87181/empty-tuple-method.rs2
-rw-r--r--src/test/ui/typeck/issue-87181/empty-tuple-method.stderr6
-rw-r--r--src/test/ui/typeck/issue-87181/enum-variant.rs2
-rw-r--r--src/test/ui/typeck/issue-87181/enum-variant.stderr6
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-field.stderr10
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-method.stderr9
-rw-r--r--src/test/ui/typeck/issue-90101.stderr2
-rw-r--r--src/test/ui/typeck/issue-91210-ptr-method.stderr9
-rw-r--r--src/test/ui/typeck/issue-91633.rs8
-rw-r--r--src/test/ui/typeck/issue-96738.stderr18
-rw-r--r--src/test/ui/typeck/issue-98982.rs9
-rw-r--r--src/test/ui/typeck/issue-98982.stderr24
-rw-r--r--src/test/ui/typeck/point-at-type-param-in-path-expr.rs6
-rw-r--r--src/test/ui/typeck/point-at-type-param-in-path-expr.stderr17
-rw-r--r--src/test/ui/typeck/remove-extra-argument.stderr2
-rw-r--r--src/test/ui/typeck/struct-enum-wrong-args.stderr16
-rw-r--r--src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr14
-rw-r--r--src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr8
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item.stderr4
-rw-r--r--src/test/ui/typeof/issue-100183.rs6
-rw-r--r--src/test/ui/typeof/issue-100183.stderr14
-rw-r--r--src/test/ui/ufcs/ufcs-qpath-self-mismatch.rs1
-rw-r--r--src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr30
-rw-r--r--src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs8
-rw-r--r--src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr17
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr12
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr6
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr6
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr6
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr6
-rw-r--r--src/test/ui/uninhabited/uninhabited-irrefutable.rs2
-rw-r--r--src/test/ui/uninhabited/uninhabited-irrefutable.stderr6
-rw-r--r--src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr2
-rw-r--r--src/test/ui/union/union-generic.mirunsafeck.stderr4
-rw-r--r--src/test/ui/union/union-generic.thirunsafeck.stderr4
-rw-r--r--src/test/ui/unpretty/avoid-crash.rs4
-rw-r--r--src/test/ui/unpretty/avoid-crash.stderr4
-rw-r--r--src/test/ui/unpretty/bad-literal.rs8
-rw-r--r--src/test/ui/unpretty/bad-literal.stderr10
-rw-r--r--src/test/ui/unpretty/bad-literal.stdout11
-rw-r--r--src/test/ui/unpretty/pretty-let-else.rs10
-rw-r--r--src/test/ui/unpretty/pretty-let-else.stdout18
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr38
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs2
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr24
-rw-r--r--src/test/ui/unsized-locals/unsized-exprs.stderr4
-rw-r--r--src/test/ui/unsized/issue-71659.stderr6
-rw-r--r--src/test/ui/unsized/issue-75707.stderr4
-rw-r--r--src/test/ui/unsized/issue-75899-but-gats.rs21
-rw-r--r--src/test/ui/unsized/issue-75899.rs18
-rw-r--r--src/test/ui/unsized/unsized-fn-param.stderr16
-rw-r--r--src/test/ui/unsized/unsized-struct.stderr4
-rw-r--r--src/test/ui/unsized/unsized3.stderr10
-rw-r--r--src/test/ui/variance/variance-use-contravariant-struct-1.rs2
-rw-r--r--src/test/ui/variance/variance-use-contravariant-struct-2.rs2
-rw-r--r--src/test/ui/variance/variance-use-invariant-struct-1.rs2
-rw-r--r--src/test/ui/wait-forked-but-failed-child.rs1
-rw-r--r--src/test/ui/wf/hir-wf-check-erase-regions.stderr4
-rw-r--r--src/test/ui/wf/wf-const-type.stderr2
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr6
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr6
-rw-r--r--src/test/ui/wf/wf-foreign-fn-decl-ret.stderr4
-rw-r--r--src/test/ui/wf/wf-static-type.stderr2
-rw-r--r--src/test/ui/wf/wf-trait-fn-ret.stderr4
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr4
-rw-r--r--src/test/ui/where-clauses/where-clause-method-substituion.stderr4
-rw-r--r--src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr6
-rw-r--r--src/tools/build-manifest/Cargo.toml1
-rw-r--r--src/tools/build-manifest/src/main.rs2
-rw-r--r--src/tools/clippy/.github/workflows/clippy.yml1
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml1
-rw-r--r--src/tools/clippy/CHANGELOG.md171
-rw-r--r--src/tools/clippy/CONTRIBUTING.md6
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/README.md2
-rw-r--r--src/tools/clippy/book/src/configuration.md2
-rw-r--r--src/tools/clippy/book/src/development/common_tools_writing_lints.md2
-rw-r--r--src/tools/clippy/clippy_dev/src/bless.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs8
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs10
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs204
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/as_underscore.rs74
-rw-r--r--src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/async_yields_async.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs125
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/borrow_as_ptr.rs99
-rw-r--r--src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/bytecount.rs103
-rw-r--r--src/tools/clippy/clippy_lints/src/bytes_count_to_len.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs86
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_underscore.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs63
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs109
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/create_dir.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/default.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs714
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_names.rs (renamed from src/tools/clippy/clippy_lints/src/blacklisted_name.rs)26
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_types.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/doc_link_with_quotes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/duplicate_mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/equatable_if_let.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/fallible_impl_from.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs119
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs106
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/format_push_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/from_str_radix_10.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/mod.rs56
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs100
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result_unit_err.rs66
-rw-r--r--src/tools/clippy/clippy_lints/src/future_not_send.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/get_first.rs68
-rw-r--r--src/tools/clippy/clippy_lints/src/if_let_mutex.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_return.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/infinite_iter.rs102
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs96
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/let_if_seq.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_all.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_complexity.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_correctness.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_lints.rs59
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_nursery.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_perf.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_restriction.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_style.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs482
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_find.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_collect.rs48
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs69
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_ok_or.rs98
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_string_new.rs135
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/map_clone.rs167
-rw-r--r--src/tools/clippy/clippy_lints/src/map_err_ignore.rs154
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/match_result_ok.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/needless_match.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs88
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/try_err.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytecount.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs96
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_used.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_first.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs107
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs64
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs122
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs967
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/open_options.rs (renamed from src/tools/clippy/clippy_lints/src/open_options.rs)54
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/repeat_once.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs58
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unit_hash.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs (renamed from src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs)162
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs226
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unwrap_or_else_default.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/utils.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/minmax.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/multi_assignments.rs65
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_reference.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_for_each.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_late_init.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/octal_escapes.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs823
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic.rs119
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs173
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/op_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs167
-rw-r--r--src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_to_none.rs105
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs74
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs84
-rw-r--r--src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_slicing.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/ref_option_ref.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/regex.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_once.rs89
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/self_named_constructors.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs145
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/to_digit_is_some.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs108
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs400
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmuting_null.rs61
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/transmuting_null.rs89
-rw-r--r--src/tools/clippy/clippy_lints/src/unicode.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/uninit_vec.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_hash.rs78
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs42
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_peekable.rs226
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_rounding.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_unit.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap_in_result.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs57
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints.rs61
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs64
-rw-r--r--src/tools/clippy/clippy_lints/src/verbose_file_reads.rs88
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs145
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml3
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs329
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs39
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs84
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs676
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/numeric_literal.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/ptr.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs30
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs118
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs11
-rw-r--r--src/tools/clippy/lintcheck/lintcheck_crates.toml2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/rustc_tools_util/src/lib.rs4
-rw-r--r--src/tools/clippy/src/docs.rs596
-rw-r--r--src/tools/clippy/src/docs/absurd_extreme_comparisons.txt25
-rw-r--r--src/tools/clippy/src/docs/alloc_instead_of_core.txt18
-rw-r--r--src/tools/clippy/src/docs/allow_attributes_without_reason.txt22
-rw-r--r--src/tools/clippy/src/docs/almost_complete_letter_range.txt15
-rw-r--r--src/tools/clippy/src/docs/almost_swapped.txt15
-rw-r--r--src/tools/clippy/src/docs/approx_constant.txt24
-rw-r--r--src/tools/clippy/src/docs/arithmetic_side_effects.txt33
-rw-r--r--src/tools/clippy/src/docs/as_conversions.txt32
-rw-r--r--src/tools/clippy/src/docs/as_underscore.txt21
-rw-r--r--src/tools/clippy/src/docs/assertions_on_constants.txt14
-rw-r--r--src/tools/clippy/src/docs/assertions_on_result_states.txt14
-rw-r--r--src/tools/clippy/src/docs/assign_op_pattern.txt28
-rw-r--r--src/tools/clippy/src/docs/async_yields_async.txt28
-rw-r--r--src/tools/clippy/src/docs/await_holding_invalid_type.txt29
-rw-r--r--src/tools/clippy/src/docs/await_holding_lock.txt51
-rw-r--r--src/tools/clippy/src/docs/await_holding_refcell_ref.txt47
-rw-r--r--src/tools/clippy/src/docs/bad_bit_mask.txt30
-rw-r--r--src/tools/clippy/src/docs/bind_instead_of_map.txt22
-rw-r--r--src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt16
-rw-r--r--src/tools/clippy/src/docs/blocks_in_if_conditions.txt21
-rw-r--r--src/tools/clippy/src/docs/bool_assert_comparison.txt16
-rw-r--r--src/tools/clippy/src/docs/bool_comparison.txt18
-rw-r--r--src/tools/clippy/src/docs/bool_to_int_with_if.txt26
-rw-r--r--src/tools/clippy/src/docs/borrow_as_ptr.txt26
-rw-r--r--src/tools/clippy/src/docs/borrow_deref_ref.txt27
-rw-r--r--src/tools/clippy/src/docs/borrow_interior_mutable_const.txt40
-rw-r--r--src/tools/clippy/src/docs/borrowed_box.txt19
-rw-r--r--src/tools/clippy/src/docs/box_collection.txt23
-rw-r--r--src/tools/clippy/src/docs/boxed_local.txt18
-rw-r--r--src/tools/clippy/src/docs/branches_sharing_code.txt32
-rw-r--r--src/tools/clippy/src/docs/builtin_type_shadow.txt15
-rw-r--r--src/tools/clippy/src/docs/bytes_count_to_len.txt18
-rw-r--r--src/tools/clippy/src/docs/bytes_nth.txt16
-rw-r--r--src/tools/clippy/src/docs/cargo_common_metadata.txt33
-rw-r--r--src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt21
-rw-r--r--src/tools/clippy/src/docs/cast_abs_to_unsigned.txt16
-rw-r--r--src/tools/clippy/src/docs/cast_enum_constructor.txt11
-rw-r--r--src/tools/clippy/src/docs/cast_enum_truncation.txt12
-rw-r--r--src/tools/clippy/src/docs/cast_lossless.txt26
-rw-r--r--src/tools/clippy/src/docs/cast_possible_truncation.txt16
-rw-r--r--src/tools/clippy/src/docs/cast_possible_wrap.txt17
-rw-r--r--src/tools/clippy/src/docs/cast_precision_loss.txt19
-rw-r--r--src/tools/clippy/src/docs/cast_ptr_alignment.txt21
-rw-r--r--src/tools/clippy/src/docs/cast_ref_to_mut.txt28
-rw-r--r--src/tools/clippy/src/docs/cast_sign_loss.txt15
-rw-r--r--src/tools/clippy/src/docs/cast_slice_different_sizes.txt38
-rw-r--r--src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt20
-rw-r--r--src/tools/clippy/src/docs/char_lit_as_u8.txt21
-rw-r--r--src/tools/clippy/src/docs/chars_last_cmp.txt17
-rw-r--r--src/tools/clippy/src/docs/chars_next_cmp.txt19
-rw-r--r--src/tools/clippy/src/docs/checked_conversions.txt15
-rw-r--r--src/tools/clippy/src/docs/clone_double_ref.txt16
-rw-r--r--src/tools/clippy/src/docs/clone_on_copy.txt11
-rw-r--r--src/tools/clippy/src/docs/clone_on_ref_ptr.txt21
-rw-r--r--src/tools/clippy/src/docs/cloned_instead_of_copied.txt16
-rw-r--r--src/tools/clippy/src/docs/cmp_nan.txt16
-rw-r--r--src/tools/clippy/src/docs/cmp_null.txt23
-rw-r--r--src/tools/clippy/src/docs/cmp_owned.txt18
-rw-r--r--src/tools/clippy/src/docs/cognitive_complexity.txt13
-rw-r--r--src/tools/clippy/src/docs/collapsible_else_if.txt29
-rw-r--r--src/tools/clippy/src/docs/collapsible_if.txt23
-rw-r--r--src/tools/clippy/src/docs/collapsible_match.txt31
-rw-r--r--src/tools/clippy/src/docs/collapsible_str_replace.txt19
-rw-r--r--src/tools/clippy/src/docs/comparison_chain.txt36
-rw-r--r--src/tools/clippy/src/docs/comparison_to_empty.txt31
-rw-r--r--src/tools/clippy/src/docs/copy_iterator.txt20
-rw-r--r--src/tools/clippy/src/docs/crate_in_macro_def.txt35
-rw-r--r--src/tools/clippy/src/docs/create_dir.txt15
-rw-r--r--src/tools/clippy/src/docs/crosspointer_transmute.txt12
-rw-r--r--src/tools/clippy/src/docs/dbg_macro.txt16
-rw-r--r--src/tools/clippy/src/docs/debug_assert_with_mut_call.txt18
-rw-r--r--src/tools/clippy/src/docs/decimal_literal_representation.txt13
-rw-r--r--src/tools/clippy/src/docs/declare_interior_mutable_const.txt46
-rw-r--r--src/tools/clippy/src/docs/default_instead_of_iter_empty.txt15
-rw-r--r--src/tools/clippy/src/docs/default_numeric_fallback.txt28
-rw-r--r--src/tools/clippy/src/docs/default_trait_access.txt16
-rw-r--r--src/tools/clippy/src/docs/default_union_representation.txt36
-rw-r--r--src/tools/clippy/src/docs/deprecated_cfg_attr.txt24
-rw-r--r--src/tools/clippy/src/docs/deprecated_semver.txt13
-rw-r--r--src/tools/clippy/src/docs/deref_addrof.txt22
-rw-r--r--src/tools/clippy/src/docs/deref_by_slicing.txt17
-rw-r--r--src/tools/clippy/src/docs/derivable_impls.txt35
-rw-r--r--src/tools/clippy/src/docs/derive_hash_xor_eq.txt23
-rw-r--r--src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt44
-rw-r--r--src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt25
-rw-r--r--src/tools/clippy/src/docs/disallowed_methods.txt41
-rw-r--r--src/tools/clippy/src/docs/disallowed_names.txt12
-rw-r--r--src/tools/clippy/src/docs/disallowed_script_idents.txt32
-rw-r--r--src/tools/clippy/src/docs/disallowed_types.txt33
-rw-r--r--src/tools/clippy/src/docs/diverging_sub_expression.txt19
-rw-r--r--src/tools/clippy/src/docs/doc_link_with_quotes.txt16
-rw-r--r--src/tools/clippy/src/docs/doc_markdown.txt35
-rw-r--r--src/tools/clippy/src/docs/double_comparisons.txt17
-rw-r--r--src/tools/clippy/src/docs/double_must_use.txt17
-rw-r--r--src/tools/clippy/src/docs/double_neg.txt12
-rw-r--r--src/tools/clippy/src/docs/double_parens.txt24
-rw-r--r--src/tools/clippy/src/docs/drop_copy.txt15
-rw-r--r--src/tools/clippy/src/docs/drop_non_drop.txt13
-rw-r--r--src/tools/clippy/src/docs/drop_ref.txt17
-rw-r--r--src/tools/clippy/src/docs/duplicate_mod.txt31
-rw-r--r--src/tools/clippy/src/docs/duplicate_underscore_argument.txt16
-rw-r--r--src/tools/clippy/src/docs/duration_subsec.txt19
-rw-r--r--src/tools/clippy/src/docs/else_if_without_else.txt27
-rw-r--r--src/tools/clippy/src/docs/empty_drop.txt20
-rw-r--r--src/tools/clippy/src/docs/empty_enum.txt27
-rw-r--r--src/tools/clippy/src/docs/empty_line_after_outer_attr.txt35
-rw-r--r--src/tools/clippy/src/docs/empty_loop.txt27
-rw-r--r--src/tools/clippy/src/docs/empty_structs_with_brackets.txt14
-rw-r--r--src/tools/clippy/src/docs/enum_clike_unportable_variant.txt16
-rw-r--r--src/tools/clippy/src/docs/enum_glob_use.txt24
-rw-r--r--src/tools/clippy/src/docs/enum_variant_names.txt30
-rw-r--r--src/tools/clippy/src/docs/eq_op.txt22
-rw-r--r--src/tools/clippy/src/docs/equatable_if_let.txt23
-rw-r--r--src/tools/clippy/src/docs/erasing_op.txt15
-rw-r--r--src/tools/clippy/src/docs/err_expect.txt16
-rw-r--r--src/tools/clippy/src/docs/excessive_precision.txt18
-rw-r--r--src/tools/clippy/src/docs/exhaustive_enums.txt23
-rw-r--r--src/tools/clippy/src/docs/exhaustive_structs.txt23
-rw-r--r--src/tools/clippy/src/docs/exit.txt12
-rw-r--r--src/tools/clippy/src/docs/expect_fun_call.txt24
-rw-r--r--src/tools/clippy/src/docs/expect_used.txt26
-rw-r--r--src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt20
-rw-r--r--src/tools/clippy/src/docs/explicit_auto_deref.txt16
-rw-r--r--src/tools/clippy/src/docs/explicit_counter_loop.txt21
-rw-r--r--src/tools/clippy/src/docs/explicit_deref_methods.txt24
-rw-r--r--src/tools/clippy/src/docs/explicit_into_iter_loop.txt20
-rw-r--r--src/tools/clippy/src/docs/explicit_iter_loop.txt25
-rw-r--r--src/tools/clippy/src/docs/explicit_write.txt18
-rw-r--r--src/tools/clippy/src/docs/extend_with_drain.txt21
-rw-r--r--src/tools/clippy/src/docs/extra_unused_lifetimes.txt23
-rw-r--r--src/tools/clippy/src/docs/fallible_impl_from.txt32
-rw-r--r--src/tools/clippy/src/docs/field_reassign_with_default.txt23
-rw-r--r--src/tools/clippy/src/docs/filetype_is_file.txt29
-rw-r--r--src/tools/clippy/src/docs/filter_map_identity.txt14
-rw-r--r--src/tools/clippy/src/docs/filter_map_next.txt16
-rw-r--r--src/tools/clippy/src/docs/filter_next.txt16
-rw-r--r--src/tools/clippy/src/docs/flat_map_identity.txt14
-rw-r--r--src/tools/clippy/src/docs/flat_map_option.txt16
-rw-r--r--src/tools/clippy/src/docs/float_arithmetic.txt11
-rw-r--r--src/tools/clippy/src/docs/float_cmp.txt28
-rw-r--r--src/tools/clippy/src/docs/float_cmp_const.txt26
-rw-r--r--src/tools/clippy/src/docs/float_equality_without_abs.txt26
-rw-r--r--src/tools/clippy/src/docs/fn_address_comparisons.txt17
-rw-r--r--src/tools/clippy/src/docs/fn_params_excessive_bools.txt31
-rw-r--r--src/tools/clippy/src/docs/fn_to_numeric_cast.txt21
-rw-r--r--src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt35
-rw-r--r--src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt26
-rw-r--r--src/tools/clippy/src/docs/for_kv_map.txt22
-rw-r--r--src/tools/clippy/src/docs/for_loops_over_fallibles.txt32
-rw-r--r--src/tools/clippy/src/docs/forget_copy.txt21
-rw-r--r--src/tools/clippy/src/docs/forget_non_drop.txt13
-rw-r--r--src/tools/clippy/src/docs/forget_ref.txt15
-rw-r--r--src/tools/clippy/src/docs/format_in_format_args.txt16
-rw-r--r--src/tools/clippy/src/docs/format_push_string.txt26
-rw-r--r--src/tools/clippy/src/docs/from_iter_instead_of_collect.txt24
-rw-r--r--src/tools/clippy/src/docs/from_over_into.txt26
-rw-r--r--src/tools/clippy/src/docs/from_str_radix_10.txt25
-rw-r--r--src/tools/clippy/src/docs/future_not_send.txt29
-rw-r--r--src/tools/clippy/src/docs/get_first.txt19
-rw-r--r--src/tools/clippy/src/docs/get_last_with_len.txt26
-rw-r--r--src/tools/clippy/src/docs/get_unwrap.txt30
-rw-r--r--src/tools/clippy/src/docs/identity_op.txt11
-rw-r--r--src/tools/clippy/src/docs/if_let_mutex.txt25
-rw-r--r--src/tools/clippy/src/docs/if_not_else.txt25
-rw-r--r--src/tools/clippy/src/docs/if_same_then_else.txt15
-rw-r--r--src/tools/clippy/src/docs/if_then_some_else_none.txt26
-rw-r--r--src/tools/clippy/src/docs/ifs_same_cond.txt25
-rw-r--r--src/tools/clippy/src/docs/implicit_clone.txt19
-rw-r--r--src/tools/clippy/src/docs/implicit_hasher.txt26
-rw-r--r--src/tools/clippy/src/docs/implicit_return.txt22
-rw-r--r--src/tools/clippy/src/docs/implicit_saturating_sub.txt21
-rw-r--r--src/tools/clippy/src/docs/imprecise_flops.txt23
-rw-r--r--src/tools/clippy/src/docs/inconsistent_digit_grouping.txt17
-rw-r--r--src/tools/clippy/src/docs/inconsistent_struct_constructor.txt40
-rw-r--r--src/tools/clippy/src/docs/index_refutable_slice.txt29
-rw-r--r--src/tools/clippy/src/docs/indexing_slicing.txt33
-rw-r--r--src/tools/clippy/src/docs/ineffective_bit_mask.txt25
-rw-r--r--src/tools/clippy/src/docs/inefficient_to_string.txt17
-rw-r--r--src/tools/clippy/src/docs/infallible_destructuring_match.txt29
-rw-r--r--src/tools/clippy/src/docs/infinite_iter.txt13
-rw-r--r--src/tools/clippy/src/docs/inherent_to_string.txt29
-rw-r--r--src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt37
-rw-r--r--src/tools/clippy/src/docs/init_numbered_fields.txt24
-rw-r--r--src/tools/clippy/src/docs/inline_always.txt23
-rw-r--r--src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt16
-rw-r--r--src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt16
-rw-r--r--src/tools/clippy/src/docs/inline_fn_without_body.txt14
-rw-r--r--src/tools/clippy/src/docs/inspect_for_each.txt23
-rw-r--r--src/tools/clippy/src/docs/int_plus_one.txt15
-rw-r--r--src/tools/clippy/src/docs/integer_arithmetic.txt18
-rw-r--r--src/tools/clippy/src/docs/integer_division.txt19
-rw-r--r--src/tools/clippy/src/docs/into_iter_on_ref.txt18
-rw-r--r--src/tools/clippy/src/docs/invalid_null_ptr_usage.txt16
-rw-r--r--src/tools/clippy/src/docs/invalid_regex.txt12
-rw-r--r--src/tools/clippy/src/docs/invalid_upcast_comparisons.txt18
-rw-r--r--src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt12
-rw-r--r--src/tools/clippy/src/docs/invisible_characters.txt10
-rw-r--r--src/tools/clippy/src/docs/is_digit_ascii_radix.txt20
-rw-r--r--src/tools/clippy/src/docs/items_after_statements.txt37
-rw-r--r--src/tools/clippy/src/docs/iter_cloned_collect.txt17
-rw-r--r--src/tools/clippy/src/docs/iter_count.txt22
-rw-r--r--src/tools/clippy/src/docs/iter_next_loop.txt17
-rw-r--r--src/tools/clippy/src/docs/iter_next_slice.txt16
-rw-r--r--src/tools/clippy/src/docs/iter_not_returning_iterator.txt26
-rw-r--r--src/tools/clippy/src/docs/iter_nth.txt20
-rw-r--r--src/tools/clippy/src/docs/iter_nth_zero.txt17
-rw-r--r--src/tools/clippy/src/docs/iter_on_empty_collections.txt25
-rw-r--r--src/tools/clippy/src/docs/iter_on_single_items.txt24
-rw-r--r--src/tools/clippy/src/docs/iter_overeager_cloned.txt22
-rw-r--r--src/tools/clippy/src/docs/iter_skip_next.txt18
-rw-r--r--src/tools/clippy/src/docs/iter_with_drain.txt16
-rw-r--r--src/tools/clippy/src/docs/iterator_step_by_zero.txt13
-rw-r--r--src/tools/clippy/src/docs/just_underscores_and_digits.txt14
-rw-r--r--src/tools/clippy/src/docs/large_const_arrays.txt17
-rw-r--r--src/tools/clippy/src/docs/large_digit_groups.txt12
-rw-r--r--src/tools/clippy/src/docs/large_enum_variant.txt41
-rw-r--r--src/tools/clippy/src/docs/large_include_file.txt21
-rw-r--r--src/tools/clippy/src/docs/large_stack_arrays.txt10
-rw-r--r--src/tools/clippy/src/docs/large_types_passed_by_value.txt24
-rw-r--r--src/tools/clippy/src/docs/len_without_is_empty.txt19
-rw-r--r--src/tools/clippy/src/docs/len_zero.txt28
-rw-r--r--src/tools/clippy/src/docs/let_and_return.txt21
-rw-r--r--src/tools/clippy/src/docs/let_underscore_drop.txt29
-rw-r--r--src/tools/clippy/src/docs/let_underscore_lock.txt20
-rw-r--r--src/tools/clippy/src/docs/let_underscore_must_use.txt17
-rw-r--r--src/tools/clippy/src/docs/let_unit_value.txt13
-rw-r--r--src/tools/clippy/src/docs/linkedlist.txt32
-rw-r--r--src/tools/clippy/src/docs/lossy_float_literal.txt18
-rw-r--r--src/tools/clippy/src/docs/macro_use_imports.txt12
-rw-r--r--src/tools/clippy/src/docs/main_recursion.txt13
-rw-r--r--src/tools/clippy/src/docs/manual_assert.txt18
-rw-r--r--src/tools/clippy/src/docs/manual_async_fn.txt16
-rw-r--r--src/tools/clippy/src/docs/manual_bits.txt15
-rw-r--r--src/tools/clippy/src/docs/manual_filter_map.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_find.txt24
-rw-r--r--src/tools/clippy/src/docs/manual_find_map.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_flatten.txt25
-rw-r--r--src/tools/clippy/src/docs/manual_instant_elapsed.txt21
-rw-r--r--src/tools/clippy/src/docs/manual_map.txt17
-rw-r--r--src/tools/clippy/src/docs/manual_memcpy.txt18
-rw-r--r--src/tools/clippy/src/docs/manual_non_exhaustive.txt41
-rw-r--r--src/tools/clippy/src/docs/manual_ok_or.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_range_contains.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_rem_euclid.txt17
-rw-r--r--src/tools/clippy/src/docs/manual_retain.txt15
-rw-r--r--src/tools/clippy/src/docs/manual_saturating_arithmetic.txt18
-rw-r--r--src/tools/clippy/src/docs/manual_split_once.txt29
-rw-r--r--src/tools/clippy/src/docs/manual_str_repeat.txt15
-rw-r--r--src/tools/clippy/src/docs/manual_string_new.txt20
-rw-r--r--src/tools/clippy/src/docs/manual_strip.txt24
-rw-r--r--src/tools/clippy/src/docs/manual_swap.txt22
-rw-r--r--src/tools/clippy/src/docs/manual_unwrap_or.txt20
-rw-r--r--src/tools/clippy/src/docs/many_single_char_names.txt12
-rw-r--r--src/tools/clippy/src/docs/map_clone.txt22
-rw-r--r--src/tools/clippy/src/docs/map_collect_result_unit.txt14
-rw-r--r--src/tools/clippy/src/docs/map_entry.txt28
-rw-r--r--src/tools/clippy/src/docs/map_err_ignore.txt93
-rw-r--r--src/tools/clippy/src/docs/map_flatten.txt21
-rw-r--r--src/tools/clippy/src/docs/map_identity.txt16
-rw-r--r--src/tools/clippy/src/docs/map_unwrap_or.txt22
-rw-r--r--src/tools/clippy/src/docs/match_as_ref.txt23
-rw-r--r--src/tools/clippy/src/docs/match_bool.txt24
-rw-r--r--src/tools/clippy/src/docs/match_like_matches_macro.txt32
-rw-r--r--src/tools/clippy/src/docs/match_on_vec_items.txt29
-rw-r--r--src/tools/clippy/src/docs/match_overlapping_arm.txt16
-rw-r--r--src/tools/clippy/src/docs/match_ref_pats.txt26
-rw-r--r--src/tools/clippy/src/docs/match_result_ok.txt27
-rw-r--r--src/tools/clippy/src/docs/match_same_arms.txt38
-rw-r--r--src/tools/clippy/src/docs/match_single_binding.txt23
-rw-r--r--src/tools/clippy/src/docs/match_str_case_mismatch.txt22
-rw-r--r--src/tools/clippy/src/docs/match_wild_err_arm.txt16
-rw-r--r--src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt27
-rw-r--r--src/tools/clippy/src/docs/maybe_infinite_iter.txt16
-rw-r--r--src/tools/clippy/src/docs/mem_forget.txt12
-rw-r--r--src/tools/clippy/src/docs/mem_replace_option_with_none.txt21
-rw-r--r--src/tools/clippy/src/docs/mem_replace_with_default.txt18
-rw-r--r--src/tools/clippy/src/docs/mem_replace_with_uninit.txt24
-rw-r--r--src/tools/clippy/src/docs/min_max.txt18
-rw-r--r--src/tools/clippy/src/docs/mismatched_target_os.txt24
-rw-r--r--src/tools/clippy/src/docs/mismatching_type_param_order.txt33
-rw-r--r--src/tools/clippy/src/docs/misrefactored_assign_op.txt20
-rw-r--r--src/tools/clippy/src/docs/missing_const_for_fn.txt40
-rw-r--r--src/tools/clippy/src/docs/missing_docs_in_private_items.txt9
-rw-r--r--src/tools/clippy/src/docs/missing_enforced_import_renames.txt22
-rw-r--r--src/tools/clippy/src/docs/missing_errors_doc.txt21
-rw-r--r--src/tools/clippy/src/docs/missing_inline_in_public_items.txt45
-rw-r--r--src/tools/clippy/src/docs/missing_panics_doc.txt24
-rw-r--r--src/tools/clippy/src/docs/missing_safety_doc.txt26
-rw-r--r--src/tools/clippy/src/docs/missing_spin_loop.txt27
-rw-r--r--src/tools/clippy/src/docs/mistyped_literal_suffixes.txt15
-rw-r--r--src/tools/clippy/src/docs/mixed_case_hex_literals.txt16
-rw-r--r--src/tools/clippy/src/docs/mixed_read_write_in_expression.txt32
-rw-r--r--src/tools/clippy/src/docs/mod_module_files.txt22
-rw-r--r--src/tools/clippy/src/docs/module_inception.txt24
-rw-r--r--src/tools/clippy/src/docs/module_name_repetitions.txt20
-rw-r--r--src/tools/clippy/src/docs/modulo_arithmetic.txt15
-rw-r--r--src/tools/clippy/src/docs/modulo_one.txt16
-rw-r--r--src/tools/clippy/src/docs/multi_assignments.txt17
-rw-r--r--src/tools/clippy/src/docs/multiple_crate_versions.txt19
-rw-r--r--src/tools/clippy/src/docs/multiple_inherent_impl.txt26
-rw-r--r--src/tools/clippy/src/docs/must_use_candidate.txt23
-rw-r--r--src/tools/clippy/src/docs/must_use_unit.txt13
-rw-r--r--src/tools/clippy/src/docs/mut_from_ref.txt26
-rw-r--r--src/tools/clippy/src/docs/mut_mut.txt12
-rw-r--r--src/tools/clippy/src/docs/mut_mutex_lock.txt29
-rw-r--r--src/tools/clippy/src/docs/mut_range_bound.txt29
-rw-r--r--src/tools/clippy/src/docs/mutable_key_type.txt61
-rw-r--r--src/tools/clippy/src/docs/mutex_atomic.txt22
-rw-r--r--src/tools/clippy/src/docs/mutex_integer.txt22
-rw-r--r--src/tools/clippy/src/docs/naive_bytecount.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_arbitrary_self_type.txt44
-rw-r--r--src/tools/clippy/src/docs/needless_bitwise_bool.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_bool.txt26
-rw-r--r--src/tools/clippy/src/docs/needless_borrow.txt21
-rw-r--r--src/tools/clippy/src/docs/needless_borrowed_reference.txt30
-rw-r--r--src/tools/clippy/src/docs/needless_collect.txt14
-rw-r--r--src/tools/clippy/src/docs/needless_continue.txt61
-rw-r--r--src/tools/clippy/src/docs/needless_doctest_main.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_for_each.txt24
-rw-r--r--src/tools/clippy/src/docs/needless_late_init.txt42
-rw-r--r--src/tools/clippy/src/docs/needless_lifetimes.txt29
-rw-r--r--src/tools/clippy/src/docs/needless_match.txt36
-rw-r--r--src/tools/clippy/src/docs/needless_option_as_deref.txt18
-rw-r--r--src/tools/clippy/src/docs/needless_option_take.txt17
-rw-r--r--src/tools/clippy/src/docs/needless_parens_on_range_literals.txt23
-rw-r--r--src/tools/clippy/src/docs/needless_pass_by_value.txt27
-rw-r--r--src/tools/clippy/src/docs/needless_question_mark.txt43
-rw-r--r--src/tools/clippy/src/docs/needless_range_loop.txt23
-rw-r--r--src/tools/clippy/src/docs/needless_return.txt19
-rw-r--r--src/tools/clippy/src/docs/needless_splitn.txt16
-rw-r--r--src/tools/clippy/src/docs/needless_update.txt30
-rw-r--r--src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt26
-rw-r--r--src/tools/clippy/src/docs/neg_multiply.txt18
-rw-r--r--src/tools/clippy/src/docs/negative_feature_names.txt22
-rw-r--r--src/tools/clippy/src/docs/never_loop.txt15
-rw-r--r--src/tools/clippy/src/docs/new_ret_no_self.txt47
-rw-r--r--src/tools/clippy/src/docs/new_without_default.txt32
-rw-r--r--src/tools/clippy/src/docs/no_effect.txt12
-rw-r--r--src/tools/clippy/src/docs/no_effect_replace.txt11
-rw-r--r--src/tools/clippy/src/docs/no_effect_underscore_binding.txt16
-rw-r--r--src/tools/clippy/src/docs/non_ascii_literal.txt19
-rw-r--r--src/tools/clippy/src/docs/non_octal_unix_permissions.txt23
-rw-r--r--src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt36
-rw-r--r--src/tools/clippy/src/docs/nonminimal_bool.txt23
-rw-r--r--src/tools/clippy/src/docs/nonsensical_open_options.txt14
-rw-r--r--src/tools/clippy/src/docs/nonstandard_macro_braces.txt15
-rw-r--r--src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt30
-rw-r--r--src/tools/clippy/src/docs/obfuscated_if_else.txt21
-rw-r--r--src/tools/clippy/src/docs/octal_escapes.txt33
-rw-r--r--src/tools/clippy/src/docs/ok_expect.txt19
-rw-r--r--src/tools/clippy/src/docs/only_used_in_recursion.txt58
-rw-r--r--src/tools/clippy/src/docs/op_ref.txt17
-rw-r--r--src/tools/clippy/src/docs/option_as_ref_deref.txt15
-rw-r--r--src/tools/clippy/src/docs/option_env_unwrap.txt19
-rw-r--r--src/tools/clippy/src/docs/option_filter_map.txt15
-rw-r--r--src/tools/clippy/src/docs/option_if_let_else.txt46
-rw-r--r--src/tools/clippy/src/docs/option_map_or_none.txt19
-rw-r--r--src/tools/clippy/src/docs/option_map_unit_fn.txt27
-rw-r--r--src/tools/clippy/src/docs/option_option.txt32
-rw-r--r--src/tools/clippy/src/docs/or_fun_call.txt27
-rw-r--r--src/tools/clippy/src/docs/or_then_unwrap.txt22
-rw-r--r--src/tools/clippy/src/docs/out_of_bounds_indexing.txt22
-rw-r--r--src/tools/clippy/src/docs/overflow_check_conditional.txt11
-rw-r--r--src/tools/clippy/src/docs/overly_complex_bool_expr.txt20
-rw-r--r--src/tools/clippy/src/docs/panic.txt10
-rw-r--r--src/tools/clippy/src/docs/panic_in_result_fn.txt22
-rw-r--r--src/tools/clippy/src/docs/panicking_unwrap.txt18
-rw-r--r--src/tools/clippy/src/docs/partialeq_ne_impl.txt18
-rw-r--r--src/tools/clippy/src/docs/partialeq_to_none.txt24
-rw-r--r--src/tools/clippy/src/docs/path_buf_push_overwrite.txt25
-rw-r--r--src/tools/clippy/src/docs/pattern_type_mismatch.txt64
-rw-r--r--src/tools/clippy/src/docs/positional_named_format_parameters.txt15
-rw-r--r--src/tools/clippy/src/docs/possible_missing_comma.txt14
-rw-r--r--src/tools/clippy/src/docs/precedence.txt17
-rw-r--r--src/tools/clippy/src/docs/print_in_format_impl.txt34
-rw-r--r--src/tools/clippy/src/docs/print_literal.txt20
-rw-r--r--src/tools/clippy/src/docs/print_stderr.txt21
-rw-r--r--src/tools/clippy/src/docs/print_stdout.txt21
-rw-r--r--src/tools/clippy/src/docs/print_with_newline.txt16
-rw-r--r--src/tools/clippy/src/docs/println_empty_string.txt16
-rw-r--r--src/tools/clippy/src/docs/ptr_arg.txt29
-rw-r--r--src/tools/clippy/src/docs/ptr_as_ptr.txt22
-rw-r--r--src/tools/clippy/src/docs/ptr_eq.txt22
-rw-r--r--src/tools/clippy/src/docs/ptr_offset_with_cast.txt30
-rw-r--r--src/tools/clippy/src/docs/pub_use.txt28
-rw-r--r--src/tools/clippy/src/docs/question_mark.txt18
-rw-r--r--src/tools/clippy/src/docs/range_minus_one.txt27
-rw-r--r--src/tools/clippy/src/docs/range_plus_one.txt36
-rw-r--r--src/tools/clippy/src/docs/range_zip_with_len.txt16
-rw-r--r--src/tools/clippy/src/docs/rc_buffer.txt27
-rw-r--r--src/tools/clippy/src/docs/rc_clone_in_vec_init.txt29
-rw-r--r--src/tools/clippy/src/docs/rc_mutex.txt26
-rw-r--r--src/tools/clippy/src/docs/read_zero_byte_vec.txt30
-rw-r--r--src/tools/clippy/src/docs/recursive_format_impl.txt32
-rw-r--r--src/tools/clippy/src/docs/redundant_allocation.txt17
-rw-r--r--src/tools/clippy/src/docs/redundant_clone.txt23
-rw-r--r--src/tools/clippy/src/docs/redundant_closure.txt25
-rw-r--r--src/tools/clippy/src/docs/redundant_closure_call.txt17
-rw-r--r--src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt15
-rw-r--r--src/tools/clippy/src/docs/redundant_else.txt30
-rw-r--r--src/tools/clippy/src/docs/redundant_feature_names.txt23
-rw-r--r--src/tools/clippy/src/docs/redundant_field_names.txt22
-rw-r--r--src/tools/clippy/src/docs/redundant_pattern.txt22
-rw-r--r--src/tools/clippy/src/docs/redundant_pattern_matching.txt45
-rw-r--r--src/tools/clippy/src/docs/redundant_pub_crate.txt21
-rw-r--r--src/tools/clippy/src/docs/redundant_slicing.txt24
-rw-r--r--src/tools/clippy/src/docs/redundant_static_lifetimes.txt19
-rw-r--r--src/tools/clippy/src/docs/ref_binding_to_reference.txt21
-rw-r--r--src/tools/clippy/src/docs/ref_option_ref.txt19
-rw-r--r--src/tools/clippy/src/docs/repeat_once.txt25
-rw-r--r--src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt24
-rw-r--r--src/tools/clippy/src/docs/result_large_err.txt36
-rw-r--r--src/tools/clippy/src/docs/result_map_or_into_option.txt16
-rw-r--r--src/tools/clippy/src/docs/result_map_unit_fn.txt26
-rw-r--r--src/tools/clippy/src/docs/result_unit_err.txt40
-rw-r--r--src/tools/clippy/src/docs/return_self_not_must_use.txt46
-rw-r--r--src/tools/clippy/src/docs/reversed_empty_ranges.txt26
-rw-r--r--src/tools/clippy/src/docs/same_functions_in_if_condition.txt41
-rw-r--r--src/tools/clippy/src/docs/same_item_push.txt29
-rw-r--r--src/tools/clippy/src/docs/same_name_method.txt23
-rw-r--r--src/tools/clippy/src/docs/search_is_some.txt24
-rw-r--r--src/tools/clippy/src/docs/self_assignment.txt32
-rw-r--r--src/tools/clippy/src/docs/self_named_constructors.txt26
-rw-r--r--src/tools/clippy/src/docs/self_named_module_files.txt22
-rw-r--r--src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt20
-rw-r--r--src/tools/clippy/src/docs/separated_literal_suffix.txt17
-rw-r--r--src/tools/clippy/src/docs/serde_api_misuse.txt10
-rw-r--r--src/tools/clippy/src/docs/shadow_reuse.txt20
-rw-r--r--src/tools/clippy/src/docs/shadow_same.txt18
-rw-r--r--src/tools/clippy/src/docs/shadow_unrelated.txt22
-rw-r--r--src/tools/clippy/src/docs/short_circuit_statement.txt14
-rw-r--r--src/tools/clippy/src/docs/should_implement_trait.txt22
-rw-r--r--src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt43
-rw-r--r--src/tools/clippy/src/docs/similar_names.txt12
-rw-r--r--src/tools/clippy/src/docs/single_char_add_str.txt18
-rw-r--r--src/tools/clippy/src/docs/single_char_lifetime_names.txt28
-rw-r--r--src/tools/clippy/src/docs/single_char_pattern.txt20
-rw-r--r--src/tools/clippy/src/docs/single_component_path_imports.txt21
-rw-r--r--src/tools/clippy/src/docs/single_element_loop.txt21
-rw-r--r--src/tools/clippy/src/docs/single_match.txt21
-rw-r--r--src/tools/clippy/src/docs/single_match_else.txt29
-rw-r--r--src/tools/clippy/src/docs/size_of_in_element_count.txt16
-rw-r--r--src/tools/clippy/src/docs/skip_while_next.txt16
-rw-r--r--src/tools/clippy/src/docs/slow_vector_initialization.txt24
-rw-r--r--src/tools/clippy/src/docs/stable_sort_primitive.txt31
-rw-r--r--src/tools/clippy/src/docs/std_instead_of_alloc.txt18
-rw-r--r--src/tools/clippy/src/docs/std_instead_of_core.txt18
-rw-r--r--src/tools/clippy/src/docs/str_to_string.txt18
-rw-r--r--src/tools/clippy/src/docs/string_add.txt27
-rw-r--r--src/tools/clippy/src/docs/string_add_assign.txt17
-rw-r--r--src/tools/clippy/src/docs/string_extend_chars.txt23
-rw-r--r--src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt15
-rw-r--r--src/tools/clippy/src/docs/string_lit_as_bytes.txt39
-rw-r--r--src/tools/clippy/src/docs/string_slice.txt17
-rw-r--r--src/tools/clippy/src/docs/string_to_string.txt19
-rw-r--r--src/tools/clippy/src/docs/strlen_on_c_strings.txt20
-rw-r--r--src/tools/clippy/src/docs/struct_excessive_bools.txt29
-rw-r--r--src/tools/clippy/src/docs/suboptimal_flops.txt50
-rw-r--r--src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt17
-rw-r--r--src/tools/clippy/src/docs/suspicious_assignment_formatting.txt12
-rw-r--r--src/tools/clippy/src/docs/suspicious_else_formatting.txt30
-rw-r--r--src/tools/clippy/src/docs/suspicious_map.txt13
-rw-r--r--src/tools/clippy/src/docs/suspicious_op_assign_impl.txt15
-rw-r--r--src/tools/clippy/src/docs/suspicious_operation_groupings.txt41
-rw-r--r--src/tools/clippy/src/docs/suspicious_splitn.txt22
-rw-r--r--src/tools/clippy/src/docs/suspicious_to_owned.txt39
-rw-r--r--src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt18
-rw-r--r--src/tools/clippy/src/docs/swap_ptr_to_ref.txt23
-rw-r--r--src/tools/clippy/src/docs/tabs_in_doc_comments.txt44
-rw-r--r--src/tools/clippy/src/docs/temporary_assignment.txt12
-rw-r--r--src/tools/clippy/src/docs/to_digit_is_some.txt15
-rw-r--r--src/tools/clippy/src/docs/to_string_in_format_args.txt17
-rw-r--r--src/tools/clippy/src/docs/todo.txt10
-rw-r--r--src/tools/clippy/src/docs/too_many_arguments.txt14
-rw-r--r--src/tools/clippy/src/docs/too_many_lines.txt17
-rw-r--r--src/tools/clippy/src/docs/toplevel_ref_arg.txt28
-rw-r--r--src/tools/clippy/src/docs/trailing_empty_array.txt22
-rw-r--r--src/tools/clippy/src/docs/trait_duplication_in_bounds.txt37
-rw-r--r--src/tools/clippy/src/docs/transmute_bytes_to_str.txt27
-rw-r--r--src/tools/clippy/src/docs/transmute_float_to_int.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_int_to_bool.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_int_to_char.txt27
-rw-r--r--src/tools/clippy/src/docs/transmute_int_to_float.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_num_to_bytes.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt21
-rw-r--r--src/tools/clippy/src/docs/transmute_ptr_to_ref.txt21
-rw-r--r--src/tools/clippy/src/docs/transmute_undefined_repr.txt22
-rw-r--r--src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt16
-rw-r--r--src/tools/clippy/src/docs/transmuting_null.txt15
-rw-r--r--src/tools/clippy/src/docs/trim_split_whitespace.txt14
-rw-r--r--src/tools/clippy/src/docs/trivial_regex.txt18
-rw-r--r--src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt43
-rw-r--r--src/tools/clippy/src/docs/try_err.txt28
-rw-r--r--src/tools/clippy/src/docs/type_complexity.txt14
-rw-r--r--src/tools/clippy/src/docs/type_repetition_in_bounds.txt16
-rw-r--r--src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt43
-rw-r--r--src/tools/clippy/src/docs/undropped_manually_drops.txt22
-rw-r--r--src/tools/clippy/src/docs/unicode_not_nfc.txt12
-rw-r--r--src/tools/clippy/src/docs/unimplemented.txt10
-rw-r--r--src/tools/clippy/src/docs/uninit_assumed_init.txt28
-rw-r--r--src/tools/clippy/src/docs/uninit_vec.txt41
-rw-r--r--src/tools/clippy/src/docs/unit_arg.txt14
-rw-r--r--src/tools/clippy/src/docs/unit_cmp.txt33
-rw-r--r--src/tools/clippy/src/docs/unit_hash.txt20
-rw-r--r--src/tools/clippy/src/docs/unit_return_expecting_ord.txt20
-rw-r--r--src/tools/clippy/src/docs/unnecessary_cast.txt19
-rw-r--r--src/tools/clippy/src/docs/unnecessary_filter_map.txt23
-rw-r--r--src/tools/clippy/src/docs/unnecessary_find_map.txt23
-rw-r--r--src/tools/clippy/src/docs/unnecessary_fold.txt17
-rw-r--r--src/tools/clippy/src/docs/unnecessary_join.txt25
-rw-r--r--src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt32
-rw-r--r--src/tools/clippy/src/docs/unnecessary_mut_passed.txt17
-rw-r--r--src/tools/clippy/src/docs/unnecessary_operation.txt12
-rw-r--r--src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt16
-rw-r--r--src/tools/clippy/src/docs/unnecessary_self_imports.txt19
-rw-r--r--src/tools/clippy/src/docs/unnecessary_sort_by.txt21
-rw-r--r--src/tools/clippy/src/docs/unnecessary_to_owned.txt24
-rw-r--r--src/tools/clippy/src/docs/unnecessary_unwrap.txt20
-rw-r--r--src/tools/clippy/src/docs/unnecessary_wraps.txt36
-rw-r--r--src/tools/clippy/src/docs/unneeded_field_pattern.txt26
-rw-r--r--src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt28
-rw-r--r--src/tools/clippy/src/docs/unnested_or_patterns.txt22
-rw-r--r--src/tools/clippy/src/docs/unreachable.txt10
-rw-r--r--src/tools/clippy/src/docs/unreadable_literal.txt16
-rw-r--r--src/tools/clippy/src/docs/unsafe_derive_deserialize.txt27
-rw-r--r--src/tools/clippy/src/docs/unsafe_removed_from_name.txt15
-rw-r--r--src/tools/clippy/src/docs/unseparated_literal_suffix.txt18
-rw-r--r--src/tools/clippy/src/docs/unsound_collection_transmute.txt25
-rw-r--r--src/tools/clippy/src/docs/unused_async.txt23
-rw-r--r--src/tools/clippy/src/docs/unused_io_amount.txt31
-rw-r--r--src/tools/clippy/src/docs/unused_peekable.txt26
-rw-r--r--src/tools/clippy/src/docs/unused_rounding.txt17
-rw-r--r--src/tools/clippy/src/docs/unused_self.txt23
-rw-r--r--src/tools/clippy/src/docs/unused_unit.txt18
-rw-r--r--src/tools/clippy/src/docs/unusual_byte_groupings.txt12
-rw-r--r--src/tools/clippy/src/docs/unwrap_in_result.txt39
-rw-r--r--src/tools/clippy/src/docs/unwrap_or_else_default.txt18
-rw-r--r--src/tools/clippy/src/docs/unwrap_used.txt37
-rw-r--r--src/tools/clippy/src/docs/upper_case_acronyms.txt25
-rw-r--r--src/tools/clippy/src/docs/use_debug.txt12
-rw-r--r--src/tools/clippy/src/docs/use_self.txt31
-rw-r--r--src/tools/clippy/src/docs/used_underscore_binding.txt19
-rw-r--r--src/tools/clippy/src/docs/useless_asref.txt17
-rw-r--r--src/tools/clippy/src/docs/useless_attribute.txt36
-rw-r--r--src/tools/clippy/src/docs/useless_conversion.txt17
-rw-r--r--src/tools/clippy/src/docs/useless_format.txt22
-rw-r--r--src/tools/clippy/src/docs/useless_let_if_seq.txt39
-rw-r--r--src/tools/clippy/src/docs/useless_transmute.txt12
-rw-r--r--src/tools/clippy/src/docs/useless_vec.txt18
-rw-r--r--src/tools/clippy/src/docs/vec_box.txt26
-rw-r--r--src/tools/clippy/src/docs/vec_init_then_push.txt23
-rw-r--r--src/tools/clippy/src/docs/vec_resize_to_zero.txt15
-rw-r--r--src/tools/clippy/src/docs/verbose_bit_mask.txt15
-rw-r--r--src/tools/clippy/src/docs/verbose_file_reads.txt17
-rw-r--r--src/tools/clippy/src/docs/vtable_address_comparisons.txt17
-rw-r--r--src/tools/clippy/src/docs/while_immutable_condition.txt20
-rw-r--r--src/tools/clippy/src/docs/while_let_loop.txt25
-rw-r--r--src/tools/clippy/src/docs/while_let_on_iterator.txt20
-rw-r--r--src/tools/clippy/src/docs/wildcard_dependencies.txt13
-rw-r--r--src/tools/clippy/src/docs/wildcard_enum_match_arm.txt25
-rw-r--r--src/tools/clippy/src/docs/wildcard_imports.txt45
-rw-r--r--src/tools/clippy/src/docs/wildcard_in_or_patterns.txt22
-rw-r--r--src/tools/clippy/src/docs/write_literal.txt21
-rw-r--r--src/tools/clippy/src/docs/write_with_newline.txt18
-rw-r--r--src/tools/clippy/src/docs/writeln_empty_string.txt16
-rw-r--r--src/tools/clippy/src/docs/wrong_self_convention.txt39
-rw-r--r--src/tools/clippy/src/docs/wrong_transmute.txt15
-rw-r--r--src/tools/clippy/src/docs/zero_divided_by_zero.txt15
-rw-r--r--src/tools/clippy/src/docs/zero_prefixed_literal.txt32
-rw-r--r--src/tools/clippy/src/docs/zero_ptr.txt16
-rw-r--r--src/tools/clippy/src/docs/zero_sized_map_values.txt24
-rw-r--r--src/tools/clippy/src/docs/zst_offset.txt11
-rw-r--r--src/tools/clippy/src/driver.rs2
-rw-r--r--src/tools/clippy/src/main.rs13
-rw-r--r--src/tools/clippy/tests/check-fmt.rs2
-rw-r--r--src/tools/clippy/tests/compile-test.rs19
-rw-r--r--src/tools/clippy/tests/dogfood.rs4
-rw-r--r--src/tools/clippy/tests/integration.rs4
-rw-r--r--src/tools/clippy/tests/lint_message_convention.rs4
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/arithmetic_allowed/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs (renamed from src/tools/clippy/tests/ui-toml/arithmetic_allowed/arithmetic_allowed.rs)2
-rw-r--r--src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/bad_toml_type/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/bad_toml_type/conf_bad_type.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.stderr16
-rw-r--r--src/tools/clippy/tests/ui-toml/blacklisted_names_append/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/blacklisted_names_replace/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/conf_deprecated_key/clippy.toml5
-rw-r--r--src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_append/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs (renamed from src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.rs)4
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr16
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_replace/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs (renamed from src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.rs)4
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/duplicated_keys/clippy.toml5
-rw-r--r--src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_blacklist/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.stderr46
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallow/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs (renamed from src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.rs)2
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr46
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr4
-rw-r--r--src/tools/clippy/tests/ui/arithmetic.fixed27
-rw-r--r--src/tools/clippy/tests/ui/arithmetic.rs27
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs57
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr22
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.fixed8
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.rs8
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.stderr10
-rw-r--r--src/tools/clippy/tests/ui/author.stdout2
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.stdout6
-rw-r--r--src/tools/clippy/tests/ui/author/loop.stdout4
-rw-r--r--src/tools/clippy/tests/ui/author/matches.stdout4
-rw-r--r--src/tools/clippy/tests/ui/author/struct.rs7
-rw-r--r--src/tools/clippy/tests/ui/author/struct.stdout6
-rw-r--r--src/tools/clippy/tests/ui/blacklisted_name.stderr88
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.fixed85
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.rs109
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.stderr84
-rw-r--r--src/tools/clippy/tests/ui/borrow_box.rs2
-rw-r--r--src/tools/clippy/tests/ui/box_collection.rs2
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs10
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr12
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr8
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed24
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs24
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr46
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.fixed7
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.rs7
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.stderr8
-rw-r--r--src/tools/clippy/tests/ui/collapsible_str_replace.fixed73
-rw-r--r--src/tools/clippy/tests/ui/collapsible_str_replace.rs76
-rw-r--r--src/tools/clippy/tests/ui/collapsible_str_replace.stderr86
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2760.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3462.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9405.rs11
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9405.stderr11
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9414.rs8
-rw-r--r--src/tools/clippy/tests/ui/crashes/regressions.rs2
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.rs1
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.stderr2
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.fixed6
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.rs6
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.stderr18
-rw-r--r--src/tools/clippy/tests/ui/disallowed_names.rs (renamed from src/tools/clippy/tests/ui/blacklisted_name.rs)4
-rw-r--r--src/tools/clippy/tests/ui/disallowed_names.stderr88
-rw-r--r--src/tools/clippy/tests/ui/diverging_sub_expression.rs2
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_no_std.rs1
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_no_std.stderr4
-rw-r--r--src/tools/clippy/tests/ui/expect.rs3
-rw-r--r--src/tools/clippy/tests/ui/expect.stderr12
-rw-r--r--src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs4
-rw-r--r--src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr4
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.fixed51
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.rs51
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.stderr144
-rw-r--r--src/tools/clippy/tests/ui/floating_point_exp.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_exp.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_exp.stderr12
-rw-r--r--src/tools/clippy/tests/ui/floating_point_log.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_log.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_log.stderr54
-rw-r--r--src/tools/clippy/tests/ui/floating_point_logbase.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_logbase.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_logbase.stderr12
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powf.fixed8
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powf.rs8
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powf.stderr76
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powi.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powi.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powi.stderr10
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.fixed5
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.rs5
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.stderr28
-rw-r--r--src/tools/clippy/tests/ui/format.fixed2
-rw-r--r--src/tools/clippy/tests/ui/format.rs2
-rw-r--r--src/tools/clippy/tests/ui/format_args.fixed51
-rw-r--r--src/tools/clippy/tests/ui/format_args.rs51
-rw-r--r--src/tools/clippy/tests/ui/format_args.stderr56
-rw-r--r--src/tools/clippy/tests/ui/identity_op.fixed2
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.rs8
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.stderr30
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.stderr8
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.rs4
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_on_empty_collections.fixed63
-rw-r--r--src/tools/clippy/tests/ui/iter_on_empty_collections.rs63
-rw-r--r--src/tools/clippy/tests/ui/iter_on_empty_collections.stderr40
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.fixed63
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.rs63
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.stderr40
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next.rs2
-rw-r--r--src/tools/clippy/tests/ui/large_enum_variant.rs24
-rw-r--r--src/tools/clippy/tests/ui/large_enum_variant.stderr256
-rw-r--r--src/tools/clippy/tests/ui/let_if_seq.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_instant_elapsed.fixed27
-rw-r--r--src/tools/clippy/tests/ui/manual_instant_elapsed.rs27
-rw-r--r--src/tools/clippy/tests/ui/manual_instant_elapsed.stderr16
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_or.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_or.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_string_new.fixed63
-rw-r--r--src/tools/clippy/tests/ui/manual_string_new.rs63
-rw-r--r--src/tools/clippy/tests/ui/manual_string_new.stderr58
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed25
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs25
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr8
-rw-r--r--src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr8
-rw-r--r--src/tools/clippy/tests/ui/methods.rs2
-rw-r--r--src/tools/clippy/tests/ui/mismatching_type_param_order.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs9
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.rs (renamed from src/tools/clippy/tests/ui/missing-doc.rs)13
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.stderr (renamed from src/tools/clippy/tests/ui/missing-doc.stderr)48
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate.rs (renamed from src/tools/clippy/tests/ui/missing-doc-crate.rs)0
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate_missing.rs (renamed from src/tools/clippy/tests/ui/missing-doc-crate-missing.rs)0
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr (renamed from src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr)2
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_impl.rs (renamed from src/tools/clippy/tests/ui/missing-doc-impl.rs)15
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_impl.stderr (renamed from src/tools/clippy/tests/ui/missing-doc-impl.stderr)30
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed6
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.rs6
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr32
-rw-r--r--src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs2
-rw-r--r--src/tools/clippy/tests/ui/multi_assignments.rs9
-rw-r--r--src/tools/clippy/tests/ui/multi_assignments.stderr40
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.fixed7
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.rs7
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed117
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs117
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr48
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.rs189
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.stderr119
-rw-r--r--src/tools/clippy/tests/ui/needless_match.fixed39
-rw-r--r--src/tools/clippy/tests/ui/needless_match.rs46
-rw-r--r--src/tools/clippy/tests/ui/needless_match.stderr23
-rw-r--r--src/tools/clippy/tests/ui/needless_return.fixed11
-rw-r--r--src/tools/clippy/tests/ui/needless_return.rs11
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr74
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion.rs133
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion.stderr193
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion2.rs91
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion2.stderr63
-rw-r--r--src/tools/clippy/tests/ui/op_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed9
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs21
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.stderr48
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed12
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.rs4
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr32
-rw-r--r--src/tools/clippy/tests/ui/overly_complex_bool_expr.rs (renamed from src/tools/clippy/tests/ui/logic_bug.rs)4
-rw-r--r--src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr (renamed from src/tools/clippy/tests/ui/logic_bug.stderr)22
-rw-r--r--src/tools/clippy/tests/ui/partialeq_to_none.fixed74
-rw-r--r--src/tools/clippy/tests/ui/partialeq_to_none.rs74
-rw-r--r--src/tools/clippy/tests/ui/partialeq_to_none.stderr110
-rw-r--r--src/tools/clippy/tests/ui/positional_named_format_parameters.fixed56
-rw-r--r--src/tools/clippy/tests/ui/positional_named_format_parameters.rs56
-rw-r--r--src/tools/clippy/tests/ui/positional_named_format_parameters.stderr418
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed15
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs15
-rw-r--r--src/tools/clippy/tests/ui/range_plus_minus_one.fixed19
-rw-r--r--src/tools/clippy/tests/ui/range_plus_minus_one.rs19
-rw-r--r--src/tools/clippy/tests/ui/range_plus_minus_one.stderr18
-rw-r--r--src/tools/clippy/tests/ui/rc_mutex.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.rs12
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.stderr40
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed20
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs20
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr50
-rw-r--r--src/tools/clippy/tests/ui/regex.rs2
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed4
-rw-r--r--src/tools/clippy/tests/ui/rename.rs4
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr88
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.rs99
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.stderr91
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.rs4
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr8
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.rs1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs2
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr10
-rw-r--r--src/tools/clippy/tests/ui/skip_while_next.rs2
-rw-r--r--src/tools/clippy/tests/ui/string_add.rs4
-rw-r--r--src/tools/clippy/tests/ui/string_add_assign.fixed4
-rw-r--r--src/tools/clippy/tests/ui/string_add_assign.rs4
-rw-r--r--src/tools/clippy/tests/ui/suspicious_to_owned.rs62
-rw-r--r--src/tools/clippy/tests/ui/suspicious_to_owned.stderr42
-rw-r--r--src/tools/clippy/tests/ui/swap.fixed2
-rw-r--r--src/tools/clippy/tests/ui/swap.rs2
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed112
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs218
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr165
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs166
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr71
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.rs12
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.stderr38
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/unicode.fixed48
-rw-r--r--src/tools/clippy/tests/ui/unicode.rs48
-rw-r--r--src/tools/clippy/tests/ui/unicode.stderr46
-rw-r--r--src/tools/clippy/tests/ui/uninit.rs2
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.rs12
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.stderr20
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.fixed9
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs9
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.stderr14
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed88
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs88
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr8
-rw-r--r--src/tools/clippy/tests/ui/unused_peekable.rs144
-rw-r--r--src/tools/clippy/tests/ui/unused_peekable.stderr67
-rw-r--r--src/tools/clippy/tests/ui/unwrap.rs3
-rw-r--r--src/tools/clippy/tests/ui/unwrap.stderr10
-rw-r--r--src/tools/clippy/tests/ui/unwrap_expect_used.rs35
-rw-r--r--src/tools/clippy/tests/ui/unwrap_expect_used.stderr52
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or_else_default.fixed3
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or_else_default.rs3
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or_else_default.stderr8
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.rs2
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion_try.rs4
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion_try.stderr2
-rw-r--r--src/tools/clippy/tests/ui/vec_resize_to_zero.rs12
-rw-r--r--src/tools/clippy/tests/ui/vec_resize_to_zero.stderr10
-rw-r--r--src/tools/clippy/tests/ui/verbose_file_reads.rs2
-rw-r--r--src/tools/clippy/tests/workspace.rs14
-rw-r--r--src/tools/compiletest/Cargo.toml1
-rw-r--r--src/tools/compiletest/src/common.rs132
-rw-r--r--src/tools/compiletest/src/header.rs49
-rw-r--r--src/tools/compiletest/src/header/tests.rs193
-rw-r--r--src/tools/compiletest/src/main.rs9
-rw-r--r--src/tools/compiletest/src/runtest.rs26
-rw-r--r--src/tools/compiletest/src/util.rs152
-rw-r--r--src/tools/compiletest/src/util/tests.rs37
-rw-r--r--src/tools/error_index_generator/Cargo.toml5
-rw-r--r--src/tools/error_index_generator/book_config.toml19
-rw-r--r--src/tools/error_index_generator/build.rs31
-rw-r--r--src/tools/error_index_generator/error-index.css38
-rw-r--r--src/tools/error_index_generator/error-index.js9
-rw-r--r--src/tools/error_index_generator/main.rs377
-rw-r--r--src/tools/error_index_generator/redirect.js16
-rw-r--r--src/tools/jsondocck/src/cache.rs70
-rw-r--r--src/tools/jsondocck/src/main.rs122
-rw-r--r--src/tools/jsondoclint/Cargo.toml12
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs184
-rw-r--r--src/tools/jsondoclint/src/json_find.rs74
-rw-r--r--src/tools/jsondoclint/src/main.rs64
-rw-r--r--src/tools/jsondoclint/src/validator.rs442
-rw-r--r--src/tools/lint-docs/src/groups.rs1
-rw-r--r--src/tools/lld-wrapper/src/main.rs41
-rwxr-xr-xsrc/tools/publish_toolstate.py14
-rw-r--r--src/tools/replace-version-placeholder/Cargo.toml10
-rw-r--r--src/tools/replace-version-placeholder/src/main.rs30
-rw-r--r--src/tools/rust-analyzer/.vscode/launch.json2
-rw-r--r--src/tools/rust-analyzer/Cargo.lock241
-rw-r--r--src/tools/rust-analyzer/README.md2
-rw-r--r--src/tools/rust-analyzer/bench_data/glorious_old_parser2
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs42
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/flycheck/src/lib.rs53
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body.rs24
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs127
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs608
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs34
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs35
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs70
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/generics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs179
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres.rs15
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs24
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs32
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/pretty.rs209
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs253
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/test_db.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/visibility.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/ast_id_map.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs22
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/db.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs298
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/name.rs63
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/quote.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/Cargo.toml6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/usefulness.rs29
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs39
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs244
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs33
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs173
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs184
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs193
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs43
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs81
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs45
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs15
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs173
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs72
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs40
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs159
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs157
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs294
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs119
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs44
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs375
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs142
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs101
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs248
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs364
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs162
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs293
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs111
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs124
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs70
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs69
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs24
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs26
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs77
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs80
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs31
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/line_index.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/rename.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/source_change.rs147
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs120
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs310
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs46
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs33
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs158
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs25
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs134
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs186
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/join_lines.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs24
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/matching_brace.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs133
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/move_item.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/parent_module.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/prime_caches.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs267
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs74
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs30
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_hir.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs2
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs2
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs11
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs26
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs5
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs47
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs130
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast43
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs3
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast23
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast23
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast116
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs10
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast49
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast40
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast23
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs5
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast43
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs1
-rw-r--r--src/tools/rust-analyzer/crates/paths/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs5
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs105
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs156
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs529
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs32
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs89
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs493
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs304
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs81
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs84
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs339
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs166
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs1125
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs139
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs792
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs61
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs13
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs17
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs6
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs26
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs675
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs24
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml5
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs7
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs16
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs448
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs61
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs37
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs40
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs67
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs497
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs79
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs191
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs114
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs7
-rw-r--r--src/tools/rust-analyzer/crates/sourcegen/src/lib.rs14
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/hash.rs80
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/lib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs193
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs415
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs264
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs21
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/fuzz.rs5
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/hacks.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs27
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/minicore.rs15
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs18
-rw-r--r--src/tools/rust-analyzer/crates/vfs/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/vfs/src/file_set.rs3
-rw-r--r--src/tools/rust-analyzer/crates/vfs/src/lib.rs11
-rw-r--r--src/tools/rust-analyzer/docs/dev/README.md8
-rw-r--r--src/tools/rust-analyzer/docs/dev/architecture.md4
-rw-r--r--src/tools/rust-analyzer/docs/dev/guide.md2
-rw-r--r--src/tools/rust-analyzer/docs/dev/lsp-extensions.md2
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc56
-rw-r--r--src/tools/rust-analyzer/docs/user/manual.adoc15
-rw-r--r--src/tools/rust-analyzer/lib/la-arena/src/lib.rs50
-rw-r--r--src/tools/rust-analyzer/lib/la-arena/src/map.rs169
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/src/socket.rs2
-rw-r--r--src/tools/rust-analyzer/xtask/src/release.rs2
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml14
-rw-r--r--src/tools/rustc-workspace-hack/README.md12
-rw-r--r--src/tools/rustdoc-gui/tester.js16
-rw-r--r--src/tools/rustfmt/Processes.md4
-rw-r--r--src/tools/rustfmt/README.md2
-rw-r--r--src/tools/rustfmt/atom.md4
-rw-r--r--src/tools/rustfmt/src/attr.rs5
-rw-r--r--src/tools/rustfmt/src/expr.rs8
-rw-r--r--src/tools/rustfmt/src/imports.rs4
-rw-r--r--src/tools/rustfmt/src/modules.rs8
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs2
-rw-r--r--src/tools/rustfmt/src/parse/session.rs52
-rw-r--r--src/tools/rustfmt/src/patterns.rs12
-rw-r--r--src/tools/rustfmt/src/skip.rs4
-rw-r--r--src/tools/rustfmt/src/visitor.rs4
-rw-r--r--src/tools/rustfmt/tests/source/issue-3217.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue_4257.rs3
-rw-r--r--src/tools/rustfmt/tests/source/issue_4911.rs1
-rw-r--r--src/tools/rustfmt/tests/source/issue_4943.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3217.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue_4257.rs3
-rw-r--r--src/tools/rustfmt/tests/target/issue_4911.rs1
-rw-r--r--src/tools/rustfmt/tests/target/issue_4943.rs2
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/bins.rs10
-rw-r--r--src/tools/tidy/src/deps.rs16
-rw-r--r--src/tools/tidy/src/error_codes_check.rs2
-rw-r--r--src/tools/tidy/src/features.rs37
-rw-r--r--src/tools/tidy/src/features/version.rs19
-rw-r--r--src/tools/tidy/src/lib.rs74
-rw-r--r--src/tools/tidy/src/main.rs7
-rw-r--r--src/tools/tidy/src/pal.rs2
-rw-r--r--src/tools/tidy/src/style.rs15
-rw-r--r--src/tools/tidy/src/walk.rs66
-rw-r--r--src/tools/unicode-table-generator/src/cascading_map.rs78
-rw-r--r--src/tools/unicode-table-generator/src/main.rs12
-rw-r--r--src/tools/unicode-table-generator/src/range_search.rs15
-rw-r--r--src/tools/unicode-table-generator/src/raw_emitter.rs32
-rw-r--r--src/tools/unicode-table-generator/src/unicode_download.rs31
-rw-r--r--src/tools/unstable-book-gen/src/main.rs33
-rw-r--r--src/version2
-rw-r--r--vendor/annotate-snippets-0.8.0/.cargo-checksum.json1
-rw-r--r--vendor/annotate-snippets-0.8.0/CHANGELOG.md29
-rw-r--r--vendor/annotate-snippets-0.8.0/Cargo.lock630
-rw-r--r--vendor/annotate-snippets-0.8.0/Cargo.toml62
-rw-r--r--vendor/annotate-snippets-0.8.0/LICENSE-APACHE201
-rw-r--r--vendor/annotate-snippets-0.8.0/LICENSE-MIT19
-rw-r--r--vendor/annotate-snippets-0.8.0/README.md92
-rw-r--r--vendor/annotate-snippets-0.8.0/benches/simple.rs74
-rw-r--r--vendor/annotate-snippets-0.8.0/examples/expected_type.rs43
-rw-r--r--vendor/annotate-snippets-0.8.0/examples/footer.rs39
-rw-r--r--vendor/annotate-snippets-0.8.0/examples/format.rs61
-rw-r--r--vendor/annotate-snippets-0.8.0/examples/multislice.rs38
-rw-r--r--vendor/annotate-snippets-0.8.0/src/display_list/from_snippet.rs517
-rw-r--r--vendor/annotate-snippets-0.8.0/src/display_list/mod.rs37
-rw-r--r--vendor/annotate-snippets-0.8.0/src/display_list/structs.rs191
-rw-r--r--vendor/annotate-snippets-0.8.0/src/formatter/mod.rs397
-rw-r--r--vendor/annotate-snippets-0.8.0/src/formatter/style.rs52
-rw-r--r--vendor/annotate-snippets-0.8.0/src/lib.rs54
-rw-r--r--vendor/annotate-snippets-0.8.0/src/snippet.rs88
-rw-r--r--vendor/annotate-snippets-0.8.0/src/stylesheets/color.rs50
-rw-r--r--vendor/annotate-snippets-0.8.0/src/stylesheets/mod.rs11
-rw-r--r--vendor/annotate-snippets-0.8.0/src/stylesheets/no_color.rs31
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/diff/mod.rs43
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs401
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml40
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt14
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml18
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt9
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml18
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt9
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml25
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt14
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml18
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt9
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs45
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/formatter.rs552
-rw-r--r--vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs167
-rw-r--r--vendor/anyhow/.cargo-checksum.json2
-rw-r--r--vendor/anyhow/Cargo.toml2
-rw-r--r--vendor/anyhow/build.rs32
-rw-r--r--vendor/anyhow/src/backtrace.rs2
-rw-r--r--vendor/anyhow/src/context.rs25
-rw-r--r--vendor/anyhow/src/ensure.rs20
-rw-r--r--vendor/anyhow/src/error.rs40
-rw-r--r--vendor/anyhow/src/kind.rs4
-rw-r--r--vendor/anyhow/src/lib.rs6
-rw-r--r--vendor/anyhow/src/macros.rs32
-rw-r--r--vendor/anyhow/src/wrapper.rs13
-rw-r--r--vendor/anyhow/tests/test_ensure.rs2
-rw-r--r--vendor/anyhow/tests/ui/must-use.stderr2
-rw-r--r--vendor/anyhow/tests/ui/no-impl.stderr12
-rw-r--r--vendor/block-buffer-0.7.3/.cargo-checksum.json1
-rw-r--r--vendor/block-buffer-0.7.3/Cargo.toml36
-rw-r--r--vendor/block-buffer-0.7.3/LICENSE-APACHE201
-rw-r--r--vendor/block-buffer-0.7.3/LICENSE-MIT25
-rw-r--r--vendor/block-buffer-0.7.3/src/lib.rs210
-rw-r--r--vendor/block-padding/.cargo-checksum.json1
-rw-r--r--vendor/block-padding/Cargo.toml26
-rw-r--r--vendor/block-padding/LICENSE-APACHE201
-rw-r--r--vendor/block-padding/LICENSE-MIT25
-rw-r--r--vendor/block-padding/src/lib.rs323
-rw-r--r--vendor/byte-tools/.cargo-checksum.json1
-rw-r--r--vendor/byte-tools/Cargo.toml21
-rw-r--r--vendor/byte-tools/LICENSE-APACHE201
-rw-r--r--vendor/byte-tools/LICENSE-MIT25
-rw-r--r--vendor/byte-tools/src/lib.rs29
-rw-r--r--vendor/byteorder/.cargo-checksum.json1
-rw-r--r--vendor/byteorder/CHANGELOG.md139
-rw-r--r--vendor/byteorder/COPYING3
-rw-r--r--vendor/byteorder/Cargo.toml43
-rw-r--r--vendor/byteorder/LICENSE-MIT21
-rw-r--r--vendor/byteorder/README.md63
-rw-r--r--vendor/byteorder/UNLICENSE24
-rw-r--r--vendor/byteorder/benches/bench.rs324
-rw-r--r--vendor/byteorder/rustfmt.toml2
-rw-r--r--vendor/byteorder/src/io.rs1592
-rw-r--r--vendor/byteorder/src/lib.rs4052
-rw-r--r--vendor/camino/.cargo-checksum.json2
-rw-r--r--vendor/camino/CHANGELOG.md22
-rw-r--r--vendor/camino/Cargo.toml2
-rw-r--r--vendor/camino/build.rs27
-rw-r--r--vendor/camino/src/lib.rs137
-rw-r--r--vendor/clap/.cargo-checksum.json2
-rw-r--r--vendor/clap/Cargo.lock159
-rw-r--r--vendor/clap/Cargo.toml36
-rw-r--r--vendor/clap/LICENSE-MIT2
-rw-r--r--vendor/clap/README.md146
-rw-r--r--vendor/clap/examples/README.md40
-rw-r--r--vendor/clap/examples/cargo-example-derive.md2
-rw-r--r--vendor/clap/examples/cargo-example-derive.rs4
-rw-r--r--vendor/clap/examples/cargo-example.md2
-rw-r--r--vendor/clap/examples/cargo-example.rs2
-rw-r--r--vendor/clap/examples/demo.md9
-rw-r--r--vendor/clap/examples/demo.rs2
-rw-r--r--vendor/clap/examples/derive_ref/README.md440
-rw-r--r--vendor/clap/examples/derive_ref/augment_args.rs11
-rw-r--r--vendor/clap/examples/derive_ref/flatten_hand_args.rs8
-rw-r--r--vendor/clap/examples/escaped-positional-derive.md4
-rw-r--r--vendor/clap/examples/escaped-positional-derive.rs4
-rw-r--r--vendor/clap/examples/escaped-positional.md4
-rw-r--r--vendor/clap/examples/escaped-positional.rs9
-rw-r--r--vendor/clap/examples/git-derive.md4
-rw-r--r--vendor/clap/examples/git-derive.rs4
-rw-r--r--vendor/clap/examples/git.md2
-rw-r--r--vendor/clap/examples/git.rs2
-rw-r--r--vendor/clap/examples/multicall-busybox.md6
-rw-r--r--vendor/clap/examples/multicall-hostname.md6
-rw-r--r--vendor/clap/examples/pacman.md2
-rw-r--r--vendor/clap/examples/pacman.rs5
-rw-r--r--vendor/clap/examples/tutorial_builder/01_quick.md37
-rw-r--r--vendor/clap/examples/tutorial_builder/01_quick.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/02_app_settings.md19
-rw-r--r--vendor/clap/examples/tutorial_builder/02_app_settings.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/02_apps.md19
-rw-r--r--vendor/clap/examples/tutorial_builder/02_crate.md18
-rw-r--r--vendor/clap/examples/tutorial_builder/02_crate.rs3
-rw-r--r--vendor/clap/examples/tutorial_builder/03_01_flag_bool.md23
-rw-r--r--vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs11
-rw-r--r--vendor/clap/examples/tutorial_builder/03_01_flag_count.md23
-rw-r--r--vendor/clap/examples/tutorial_builder/03_01_flag_count.rs11
-rw-r--r--vendor/clap/examples/tutorial_builder/03_02_option.md32
-rw-r--r--vendor/clap/examples/tutorial_builder/03_02_option.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/03_03_positional.md22
-rw-r--r--vendor/clap/examples/tutorial_builder/03_03_positional.rs6
-rw-r--r--vendor/clap/examples/tutorial_builder/03_04_subcommands.md64
-rw-r--r--vendor/clap/examples/tutorial_builder/03_04_subcommands.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/03_05_default_values.md22
-rw-r--r--vendor/clap/examples/tutorial_builder/03_05_default_values.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/04_01_enum.md29
-rw-r--r--vendor/clap/examples/tutorial_builder/04_01_enum.rs44
-rw-r--r--vendor/clap/examples/tutorial_builder/04_01_possible.md29
-rw-r--r--vendor/clap/examples/tutorial_builder/04_01_possible.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/04_02_parse.md31
-rw-r--r--vendor/clap/examples/tutorial_builder/04_02_parse.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/04_02_validate.md31
-rw-r--r--vendor/clap/examples/tutorial_builder/04_02_validate.rs4
-rw-r--r--vendor/clap/examples/tutorial_builder/04_03_relations.md58
-rw-r--r--vendor/clap/examples/tutorial_builder/04_03_relations.rs10
-rw-r--r--vendor/clap/examples/tutorial_builder/04_04_custom.md57
-rw-r--r--vendor/clap/examples/tutorial_builder/04_04_custom.rs15
-rw-r--r--vendor/clap/examples/tutorial_builder/05_01_assert.rs15
-rw-r--r--vendor/clap/examples/tutorial_builder/README.md658
-rw-r--r--vendor/clap/examples/tutorial_derive/01_quick.md37
-rw-r--r--vendor/clap/examples/tutorial_derive/02_app_settings.md19
-rw-r--r--vendor/clap/examples/tutorial_derive/02_apps.md19
-rw-r--r--vendor/clap/examples/tutorial_derive/02_crate.md18
-rw-r--r--vendor/clap/examples/tutorial_derive/02_crate.rs2
-rw-r--r--vendor/clap/examples/tutorial_derive/03_01_flag_bool.md23
-rw-r--r--vendor/clap/examples/tutorial_derive/03_01_flag_count.md23
-rw-r--r--vendor/clap/examples/tutorial_derive/03_02_option.md32
-rw-r--r--vendor/clap/examples/tutorial_derive/03_03_positional.md22
-rw-r--r--vendor/clap/examples/tutorial_derive/03_04_subcommands.md64
-rw-r--r--vendor/clap/examples/tutorial_derive/03_05_default_values.md22
-rw-r--r--vendor/clap/examples/tutorial_derive/04_01_enum.md29
-rw-r--r--vendor/clap/examples/tutorial_derive/04_01_enum.rs4
-rw-r--r--vendor/clap/examples/tutorial_derive/04_02_parse.md31
-rw-r--r--vendor/clap/examples/tutorial_derive/04_02_validate.md31
-rw-r--r--vendor/clap/examples/tutorial_derive/04_03_relations.md58
-rw-r--r--vendor/clap/examples/tutorial_derive/04_03_relations.rs2
-rw-r--r--vendor/clap/examples/tutorial_derive/04_04_custom.md57
-rw-r--r--vendor/clap/examples/tutorial_derive/05_01_assert.rs2
-rw-r--r--vendor/clap/examples/tutorial_derive/README.md639
-rw-r--r--vendor/clap/examples/typed-derive.md4
-rw-r--r--vendor/clap/examples/typed-derive.rs4
-rw-r--r--vendor/clap/src/_cookbook/cargo_example.rs7
-rw-r--r--vendor/clap/src/_cookbook/cargo_example_derive0
-rw-r--r--vendor/clap/src/_cookbook/cargo_example_derive.rs7
-rw-r--r--vendor/clap/src/_cookbook/escaped_positional.rs7
-rw-r--r--vendor/clap/src/_cookbook/escaped_positional_derive.rs7
-rw-r--r--vendor/clap/src/_cookbook/git.rs7
-rw-r--r--vendor/clap/src/_cookbook/git_derive.rs7
-rw-r--r--vendor/clap/src/_cookbook/mod.rs55
-rw-r--r--vendor/clap/src/_cookbook/multicall_busybox.rs7
-rw-r--r--vendor/clap/src/_cookbook/multicall_hostname.rs7
-rw-r--r--vendor/clap/src/_cookbook/pacman.rs7
-rw-r--r--vendor/clap/src/_cookbook/repl.rs5
-rw-r--r--vendor/clap/src/_cookbook/typed_derive.rs7
-rw-r--r--vendor/clap/src/_derive/_tutorial.rs205
-rw-r--r--vendor/clap/src/_derive/mod.rs510
-rw-r--r--vendor/clap/src/_faq.rs95
-rw-r--r--vendor/clap/src/_features.rs27
-rw-r--r--vendor/clap/src/_tutorial.rs204
-rw-r--r--vendor/clap/src/builder/action.rs8
-rw-r--r--vendor/clap/src/builder/app_settings.rs32
-rw-r--r--vendor/clap/src/builder/arg.rs20
-rw-r--r--vendor/clap/src/builder/arg_settings.rs27
-rw-r--r--vendor/clap/src/builder/command.rs106
-rw-r--r--vendor/clap/src/builder/value_parser.rs2
-rw-r--r--vendor/clap/src/derive.rs28
-rw-r--r--vendor/clap/src/error/kind.rs2
-rw-r--r--vendor/clap/src/error/mod.rs11
-rw-r--r--vendor/clap/src/lib.rs91
-rw-r--r--vendor/clap/src/macros.rs24
-rw-r--r--vendor/clap/src/output/usage.rs117
-rw-r--r--vendor/clap/src/parser/arg_matcher.rs4
-rw-r--r--vendor/clap/src/parser/error.rs11
-rw-r--r--vendor/clap/src/parser/matches/arg_matches.rs74
-rw-r--r--vendor/clap/src/parser/parser.rs148
-rw-r--r--vendor/clap_derive/.cargo-checksum.json2
-rw-r--r--vendor/clap_derive/Cargo.toml5
-rw-r--r--vendor/clap_derive/LICENSE-MIT2
-rw-r--r--vendor/clap_derive/README.md4
-rw-r--r--vendor/clap_derive/src/attrs.rs159
-rw-r--r--vendor/clap_derive/src/derives/value_enum.rs2
-rw-r--r--vendor/clap_derive/src/parse.rs4
-rw-r--r--vendor/compiler_builtins/.cargo-checksum.json2
-rw-r--r--vendor/compiler_builtins/Cargo.lock6
-rw-r--r--vendor/compiler_builtins/Cargo.toml3
-rw-r--r--vendor/compiler_builtins/build.rs10
-rw-r--r--vendor/compiler_builtins/libm/src/math/acosh.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/acoshf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/asinh.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/asinhf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/atanh.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/atanhf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/copysign.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/copysignf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/erf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/erff.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/exp10.rs5
-rw-r--r--vendor/compiler_builtins/libm/src/math/exp10f.rs5
-rw-r--r--vendor/compiler_builtins/libm/src/math/fenv.rs6
-rw-r--r--vendor/compiler_builtins/libm/src/math/fmaf.rs35
-rw-r--r--vendor/compiler_builtins/libm/src/math/ilogb.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/ilogbf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/lgamma.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/lgamma_r.rs3
-rw-r--r--vendor/compiler_builtins/libm/src/math/lgammaf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/lgammaf_r.rs3
-rw-r--r--vendor/compiler_builtins/libm/src/math/rem_pio2_large.rs2
-rw-r--r--vendor/compiler_builtins/libm/src/math/sincos.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/sincosf.rs1
-rw-r--r--vendor/compiler_builtins/libm/src/math/tgamma.rs13
-rw-r--r--vendor/compiler_builtins/libm/src/math/tgammaf.rs1
-rw-r--r--vendor/compiler_builtins/src/arm.rs4
-rw-r--r--vendor/compiler_builtins/src/arm_linux.rs110
-rw-r--r--vendor/compiler_builtins/src/float/conv.rs8
-rw-r--r--vendor/compiler_builtins/src/lib.rs2
-rw-r--r--vendor/compiler_builtins/src/macros.rs12
-rw-r--r--vendor/compiler_builtins/src/math.rs17
-rw-r--r--vendor/compiler_builtins/src/mem/impls.rs14
-rw-r--r--vendor/compiler_builtins/src/mem/mod.rs11
-rw-r--r--vendor/compiler_builtins/src/mem/x86_64.rs150
-rw-r--r--vendor/crossbeam-channel/.cargo-checksum.json2
-rw-r--r--vendor/crossbeam-channel/CHANGELOG.md4
-rw-r--r--vendor/crossbeam-channel/Cargo.lock10
-rw-r--r--vendor/crossbeam-channel/Cargo.toml4
-rw-r--r--vendor/crossbeam-channel/README.md4
-rw-r--r--vendor/crossbeam-channel/src/flavors/array.rs4
-rw-r--r--vendor/crossbeam-channel/src/flavors/list.rs18
-rw-r--r--vendor/crossbeam-channel/src/flavors/zero.rs10
-rw-r--r--vendor/crossbeam-channel/tests/array.rs6
-rw-r--r--vendor/crossbeam-channel/tests/golang.rs7
-rw-r--r--vendor/crossbeam-channel/tests/list.rs3
-rw-r--r--vendor/crossbeam-channel/tests/mpsc.rs15
-rw-r--r--vendor/crossbeam-channel/tests/select.rs1
-rw-r--r--vendor/crossbeam-channel/tests/select_macro.rs1
-rw-r--r--vendor/crossbeam-channel/tests/thread_locals.rs2
-rw-r--r--vendor/crossbeam-channel/tests/zero.rs8
-rw-r--r--vendor/crossbeam-deque/.cargo-checksum.json2
-rw-r--r--vendor/crossbeam-deque/CHANGELOG.md18
-rw-r--r--vendor/crossbeam-deque/Cargo.toml26
-rw-r--r--vendor/crossbeam-deque/README.md4
-rw-r--r--vendor/crossbeam-deque/src/deque.rs76
-rw-r--r--vendor/crossbeam-deque/src/lib.rs1
-rw-r--r--vendor/crossbeam-deque/tests/fifo.rs21
-rw-r--r--vendor/crossbeam-deque/tests/injector.rs28
-rw-r--r--vendor/crossbeam-deque/tests/lifo.rs23
-rw-r--r--vendor/crossbeam-epoch/.cargo-checksum.json2
-rw-r--r--vendor/crossbeam-epoch/CHANGELOG.md6
-rw-r--r--vendor/crossbeam-epoch/Cargo.lock105
-rw-r--r--vendor/crossbeam-epoch/Cargo.toml4
-rw-r--r--vendor/crossbeam-epoch/README.md4
-rw-r--r--vendor/crossbeam-epoch/build.rs12
-rw-r--r--vendor/crossbeam-epoch/src/atomic.rs108
-rw-r--r--vendor/crossbeam-epoch/src/collector.rs6
-rw-r--r--vendor/crossbeam-epoch/src/deferred.rs19
-rw-r--r--vendor/crossbeam-epoch/src/guard.rs6
-rw-r--r--vendor/crossbeam-epoch/src/internal.rs109
-rw-r--r--vendor/crossbeam-queue/.cargo-checksum.json1
-rw-r--r--vendor/crossbeam-queue/CHANGELOG.md54
-rw-r--r--vendor/crossbeam-queue/Cargo.toml51
-rw-r--r--vendor/crossbeam-queue/README.md54
-rw-r--r--vendor/crossbeam-queue/build.rs41
-rw-r--r--vendor/crossbeam-queue/no_atomic.rs73
-rw-r--r--vendor/crossbeam-queue/src/array_queue.rs522
-rw-r--r--vendor/crossbeam-queue/src/lib.rs34
-rw-r--r--vendor/crossbeam-queue/src/seg_queue.rs545
-rw-r--r--vendor/crossbeam-queue/tests/array_queue.rs359
-rw-r--r--vendor/crossbeam-queue/tests/seg_queue.rs190
-rw-r--r--vendor/crossbeam-utils/.cargo-checksum.json2
-rw-r--r--vendor/crossbeam-utils/CHANGELOG.md4
-rw-r--r--vendor/crossbeam-utils/Cargo.toml4
-rw-r--r--vendor/crossbeam-utils/README.md4
-rw-r--r--vendor/crossbeam-utils/build.rs7
-rw-r--r--vendor/crossbeam-utils/src/atomic/atomic_cell.rs17
-rw-r--r--vendor/crossbeam-utils/src/backoff.rs2
-rw-r--r--vendor/crossbeam-utils/src/sync/parker.rs6
-rw-r--r--vendor/crossbeam-utils/tests/wait_group.rs5
-rw-r--r--vendor/crossbeam/.cargo-checksum.json1
-rw-r--r--vendor/crossbeam/CHANGELOG.md93
-rw-r--r--vendor/crossbeam/Cargo.toml59
-rw-r--r--vendor/crossbeam/LICENSE-APACHE201
-rw-r--r--vendor/crossbeam/LICENSE-MIT27
-rw-r--r--vendor/crossbeam/README.md158
-rw-r--r--vendor/crossbeam/no_atomic.rs59
-rw-r--r--vendor/crossbeam/src/lib.rs96
-rw-r--r--vendor/crossbeam/tests/subcrates.rs47
-rw-r--r--vendor/digest-0.8.1/.cargo-checksum.json1
-rw-r--r--vendor/digest-0.8.1/Cargo.toml36
-rw-r--r--vendor/digest-0.8.1/LICENSE-APACHE201
-rw-r--r--vendor/digest-0.8.1/LICENSE-MIT25
-rw-r--r--vendor/digest-0.8.1/src/dev.rs218
-rw-r--r--vendor/digest-0.8.1/src/digest.rs86
-rw-r--r--vendor/digest-0.8.1/src/dyn_digest.rs63
-rw-r--r--vendor/digest-0.8.1/src/errors.rs20
-rw-r--r--vendor/digest-0.8.1/src/lib.rs141
-rw-r--r--vendor/either/.cargo-checksum.json2
-rw-r--r--vendor/either/Cargo.toml4
-rw-r--r--vendor/either/README.rst13
-rw-r--r--vendor/either/src/lib.rs71
-rw-r--r--vendor/fake-simd/.cargo-checksum.json1
-rw-r--r--vendor/fake-simd/Cargo.toml9
-rw-r--r--vendor/fake-simd/LICENSE-APACHE201
-rw-r--r--vendor/fake-simd/LICENSE-MIT26
-rw-r--r--vendor/fake-simd/src/lib.rs108
-rw-r--r--vendor/fortanix-sgx-abi/.cargo-checksum.json2
-rw-r--r--vendor/fortanix-sgx-abi/Cargo.toml36
-rw-r--r--vendor/fortanix-sgx-abi/src/lib.rs164
-rw-r--r--vendor/fs-err/.cargo-checksum.json2
-rw-r--r--vendor/fs-err/CHANGELOG.md19
-rw-r--r--vendor/fs-err/Cargo.toml45
-rw-r--r--vendor/fs-err/README.md2
-rw-r--r--vendor/fs-err/README.tpl28
-rw-r--r--vendor/fs-err/src/dir.rs13
-rw-r--r--vendor/fs-err/src/errors.rs30
-rw-r--r--vendor/fs-err/src/file.rs76
-rw-r--r--vendor/fs-err/src/lib.rs43
-rw-r--r--vendor/fs-err/src/open_options.rs1
-rw-r--r--vendor/fs-err/src/os/unix.rs6
-rw-r--r--vendor/fs-err/src/os/windows.rs4
-rw-r--r--vendor/fs-err/src/path.rs2
-rw-r--r--vendor/fs-err/tests/version-numbers.rs9
-rw-r--r--vendor/generic-array-0.12.4/.cargo-checksum.json1
-rw-r--r--vendor/generic-array-0.12.4/CHANGELOG.md51
-rw-r--r--vendor/generic-array-0.12.4/Cargo.toml40
-rw-r--r--vendor/generic-array-0.12.4/LICENSE21
-rw-r--r--vendor/generic-array-0.12.4/README.md34
-rw-r--r--vendor/generic-array-0.12.4/rustfmt.toml3
-rw-r--r--vendor/generic-array-0.12.4/src/arr.rs126
-rw-r--r--vendor/generic-array-0.12.4/src/functional.rs94
-rw-r--r--vendor/generic-array-0.12.4/src/hex.rs102
-rw-r--r--vendor/generic-array-0.12.4/src/impl_serde.rs108
-rw-r--r--vendor/generic-array-0.12.4/src/impls.rs182
-rw-r--r--vendor/generic-array-0.12.4/src/iter.rs190
-rw-r--r--vendor/generic-array-0.12.4/src/lib.rs632
-rw-r--r--vendor/generic-array-0.12.4/src/sequence.rs320
-rw-r--r--vendor/generic-array-0.12.4/tests/arr.rs27
-rw-r--r--vendor/generic-array-0.12.4/tests/generics.rs98
-rw-r--r--vendor/generic-array-0.12.4/tests/hex.rs61
-rw-r--r--vendor/generic-array-0.12.4/tests/import_name.rs10
-rw-r--r--vendor/generic-array-0.12.4/tests/iter.rs164
-rw-r--r--vendor/generic-array-0.12.4/tests/mod.rs287
-rw-r--r--vendor/getrandom/.cargo-checksum.json2
-rw-r--r--vendor/getrandom/CHANGELOG.md18
-rw-r--r--vendor/getrandom/Cargo.toml38
-rw-r--r--vendor/getrandom/src/bsd_arandom.rs1
-rw-r--r--vendor/getrandom/src/dragonfly.rs1
-rw-r--r--vendor/getrandom/src/error.rs4
-rw-r--r--vendor/getrandom/src/lib.rs2
-rw-r--r--vendor/getrandom/src/linux_android.rs1
-rw-r--r--vendor/getrandom/src/macos.rs1
-rw-r--r--vendor/getrandom/src/openbsd.rs1
-rw-r--r--vendor/getrandom/src/solaris_illumos.rs1
-rw-r--r--vendor/getrandom/src/util_libc.rs57
-rw-r--r--vendor/getrandom/src/wasi.rs12
-rw-r--r--vendor/getrandom/src/windows.rs1
-rw-r--r--vendor/gimli/.cargo-checksum.json2
-rw-r--r--vendor/gimli/CHANGELOG.md22
-rw-r--r--vendor/gimli/Cargo.lock37
-rw-r--r--vendor/gimli/Cargo.toml79
-rw-r--r--vendor/gimli/README.md6
-rw-r--r--vendor/gimli/examples/dwarf-validate.rs2
-rw-r--r--vendor/gimli/examples/dwarfdump.rs45
-rw-r--r--vendor/gimli/examples/simple.rs2
-rw-r--r--vendor/gimli/examples/simple_line.rs13
-rw-r--r--vendor/gimli/fixtures/self/README.md2
-rw-r--r--vendor/gimli/src/constants.rs2
-rw-r--r--vendor/gimli/src/lib.rs2
-rw-r--r--vendor/gimli/src/read/abbrev.rs2
-rw-r--r--vendor/gimli/src/read/aranges.rs2
-rw-r--r--vendor/gimli/src/read/cfi.rs134
-rw-r--r--vendor/gimli/src/read/line.rs2
-rw-r--r--vendor/gimli/src/read/lists.rs1
-rw-r--r--vendor/gimli/src/read/loclists.rs4
-rw-r--r--vendor/gimli/src/read/mod.rs2
-rw-r--r--vendor/gimli/src/read/op.rs21
-rw-r--r--vendor/gimli/src/read/pubnames.rs2
-rw-r--r--vendor/gimli/src/read/pubtypes.rs2
-rw-r--r--vendor/gimli/src/read/rnglists.rs4
-rw-r--r--vendor/gimli/src/read/str.rs4
-rw-r--r--vendor/gimli/src/read/unit.rs4
-rw-r--r--vendor/gimli/src/read/util.rs2
-rw-r--r--vendor/gimli/src/read/value.rs2
-rw-r--r--vendor/gimli/src/write/cfi.rs15
-rw-r--r--vendor/gimli/src/write/op.rs6
-rw-r--r--vendor/gimli/tests/convert_self.rs2
-rw-r--r--vendor/handlebars/.cargo-checksum.json2
-rw-r--r--vendor/handlebars/CHANGELOG.md75
-rw-r--r--vendor/handlebars/Cargo.lock1368
-rw-r--r--vendor/handlebars/Cargo.toml89
-rw-r--r--vendor/handlebars/README.md26
-rw-r--r--vendor/handlebars/examples/dev_mode.rs24
-rw-r--r--vendor/handlebars/examples/error.rs52
-rw-r--r--vendor/handlebars/examples/helper_macro.rs63
-rw-r--r--vendor/handlebars/examples/partials.rs19
-rw-r--r--vendor/handlebars/examples/script.rs7
-rw-r--r--vendor/handlebars/release.toml2
-rw-r--r--vendor/handlebars/src/context.rs19
-rw-r--r--vendor/handlebars/src/decorators/mod.rs12
-rw-r--r--vendor/handlebars/src/error.rs98
-rw-r--r--vendor/handlebars/src/grammar.pest27
-rw-r--r--vendor/handlebars/src/grammar.rs29
-rw-r--r--vendor/handlebars/src/helpers/helper_each.rs94
-rw-r--r--vendor/handlebars/src/helpers/helper_if.rs40
-rw-r--r--vendor/handlebars/src/helpers/helper_lookup.rs12
-rw-r--r--vendor/handlebars/src/helpers/helper_with.rs15
-rw-r--r--vendor/handlebars/src/helpers/mod.rs3
-rw-r--r--vendor/handlebars/src/helpers/scripting.rs14
-rw-r--r--vendor/handlebars/src/json/path.rs4
-rw-r--r--vendor/handlebars/src/lib.rs21
-rw-r--r--vendor/handlebars/src/macros.rs7
-rw-r--r--vendor/handlebars/src/output.rs6
-rw-r--r--vendor/handlebars/src/partial.rs363
-rw-r--r--vendor/handlebars/src/registry.rs272
-rw-r--r--vendor/handlebars/src/render.rs93
-rw-r--r--vendor/handlebars/src/support.rs58
-rw-r--r--vendor/handlebars/src/template.rs233
-rw-r--r--vendor/handlebars/tests/embed.rs29
-rw-r--r--vendor/handlebars/tests/escape.rs42
-rw-r--r--vendor/handlebars/tests/helper_macro.rs13
-rw-r--r--vendor/handlebars/tests/helper_with_space.rs54
-rw-r--r--vendor/handlebars/tests/templates/hello.hbs1
-rw-r--r--vendor/handlebars/tests/whitespace.rs24
-rw-r--r--vendor/hermit-abi/.cargo-checksum.json2
-rw-r--r--vendor/hermit-abi/Cargo.toml31
-rw-r--r--vendor/hermit-abi/src/errno.rs397
-rw-r--r--vendor/hermit-abi/src/lib.rs74
-rw-r--r--vendor/itoa/.cargo-checksum.json2
-rw-r--r--vendor/itoa/Cargo.toml8
-rw-r--r--vendor/itoa/README.md2
-rw-r--r--vendor/itoa/src/lib.rs4
-rw-r--r--vendor/lazycell/.cargo-checksum.json1
-rw-r--r--vendor/lazycell/CHANGELOG.md197
-rw-r--r--vendor/lazycell/Cargo.toml34
-rw-r--r--vendor/lazycell/LICENSE-APACHE (renamed from vendor/crossbeam-queue/LICENSE-APACHE)0
-rw-r--r--vendor/lazycell/LICENSE-MIT (renamed from vendor/crossbeam-queue/LICENSE-MIT)5
-rw-r--r--vendor/lazycell/README.md73
-rw-r--r--vendor/lazycell/src/lib.rs680
-rw-r--r--vendor/lazycell/src/serde_impl.rs86
-rw-r--r--vendor/libc/.cargo-checksum.json2
-rw-r--r--vendor/libc/CONTRIBUTING.md4
-rw-r--r--vendor/libc/Cargo.toml2
-rw-r--r--vendor/libc/README.md8
-rw-r--r--vendor/libc/build.rs15
-rw-r--r--vendor/libc/src/fuchsia/mod.rs11
-rw-r--r--vendor/libc/src/lib.rs10
-rw-r--r--vendor/libc/src/macros.rs16
-rw-r--r--vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs1
-rw-r--r--vendor/libc/src/unix/bsd/apple/mod.rs59
-rw-r--r--vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs69
-rw-r--r--vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs103
-rw-r--r--vendor/libc/src/unix/bsd/freebsdlike/mod.rs42
-rw-r--r--vendor/libc/src/unix/bsd/mod.rs6
-rw-r--r--vendor/libc/src/unix/bsd/netbsdlike/mod.rs11
-rw-r--r--vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs160
-rw-r--r--vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs11
-rw-r--r--vendor/libc/src/unix/haiku/mod.rs92
-rw-r--r--vendor/libc/src/unix/linux_like/android/b64/mod.rs3
-rw-r--r--vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs7
-rw-r--r--vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs342
-rw-r--r--vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs2
-rw-r--r--vendor/libc/src/unix/linux_like/android/mod.rs212
-rw-r--r--vendor/libc/src/unix/linux_like/emscripten/mod.rs2
-rw-r--r--vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs22
-rw-r--r--vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs16
-rw-r--r--vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs17
-rw-r--r--vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs13
-rw-r--r--vendor/libc/src/unix/linux_like/linux/gnu/mod.rs8
-rw-r--r--vendor/libc/src/unix/linux_like/linux/mod.rs14
-rw-r--r--vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs15
-rw-r--r--vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs2
-rw-r--r--vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs1
-rw-r--r--vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs18
-rw-r--r--vendor/libc/src/unix/linux_like/linux/musl/mod.rs2
-rw-r--r--vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs2
-rw-r--r--vendor/libc/src/unix/linux_like/mod.rs13
-rw-r--r--vendor/libc/src/unix/mod.rs16
-rw-r--r--vendor/libc/src/unix/newlib/espidf/mod.rs5
-rw-r--r--vendor/libc/src/unix/solarish/mod.rs2
-rw-r--r--vendor/libc/src/windows/mod.rs12
-rw-r--r--vendor/lsp-types/.cargo-checksum.json2
-rw-r--r--vendor/lsp-types/CHANGELOG.md6
-rw-r--r--vendor/lsp-types/Cargo.toml3
-rw-r--r--vendor/lsp-types/README.md2
-rw-r--r--vendor/lsp-types/src/lib.rs5
-rw-r--r--vendor/lsp-types/src/semantic_tokens.rs32
-rw-r--r--vendor/memmap2/.cargo-checksum.json2
-rw-r--r--vendor/memmap2/CHANGELOG.md22
-rw-r--r--vendor/memmap2/Cargo.lock2
-rw-r--r--vendor/memmap2/Cargo.toml3
-rw-r--r--vendor/memmap2/src/lib.rs149
-rw-r--r--vendor/memmap2/src/unix.rs42
-rw-r--r--vendor/memmap2/src/windows.rs43
-rw-r--r--vendor/minifier/.cargo-checksum.json2
-rw-r--r--vendor/minifier/Cargo.lock2
-rw-r--r--vendor/minifier/Cargo.toml2
-rw-r--r--vendor/minifier/src/css/token.rs51
-rw-r--r--vendor/once_cell/.cargo-checksum.json2
-rw-r--r--vendor/once_cell/CHANGELOG.md5
-rw-r--r--vendor/once_cell/Cargo.lock164
-rw-r--r--vendor/once_cell/Cargo.toml4
-rw-r--r--vendor/once_cell/src/imp_std.rs93
-rw-r--r--vendor/opaque-debug/.cargo-checksum.json1
-rw-r--r--vendor/opaque-debug/Cargo.toml22
-rw-r--r--vendor/opaque-debug/LICENSE-APACHE201
-rw-r--r--vendor/opaque-debug/LICENSE-MIT25
-rw-r--r--vendor/opaque-debug/src/lib.rs24
-rw-r--r--vendor/pest/.cargo-checksum.json2
-rw-r--r--vendor/pest/Cargo.lock80
-rw-r--r--vendor/pest/Cargo.toml45
-rw-r--r--vendor/pest/_README.md23
-rw-r--r--vendor/pest/examples/parens.rs4
-rw-r--r--vendor/pest/src/error.rs172
-rw-r--r--vendor/pest/src/iterators/flat_pairs.rs9
-rw-r--r--vendor/pest/src/iterators/pair.rs22
-rw-r--r--vendor/pest/src/iterators/pairs.rs19
-rw-r--r--vendor/pest/src/iterators/tokens.rs14
-rw-r--r--vendor/pest/src/lib.rs20
-rw-r--r--vendor/pest/src/macros.rs114
-rw-r--r--vendor/pest/src/parser.rs6
-rw-r--r--vendor/pest/src/parser_state.rs132
-rw-r--r--vendor/pest/src/position.rs81
-rw-r--r--vendor/pest/src/prec_climber.rs171
-rw-r--r--vendor/pest/src/span.rs189
-rw-r--r--vendor/pest/src/stack.rs4
-rw-r--r--vendor/pest/src/token.rs2
-rw-r--r--vendor/pest/src/unicode/binary.rs3190
-rw-r--r--vendor/pest/src/unicode/category.rs2175
-rw-r--r--vendor/pest/src/unicode/mod.rs2
-rw-r--r--vendor/pest/tests/calculator.rs18
-rw-r--r--vendor/pest/tests/json.rs75
-rw-r--r--vendor/pest_derive/.cargo-checksum.json2
-rw-r--r--vendor/pest_derive/Cargo.toml40
-rw-r--r--vendor/pest_derive/_README.md37
-rw-r--r--vendor/pest_derive/src/lib.rs7
-rw-r--r--vendor/pest_derive/tests/grammar.pest4
-rw-r--r--vendor/pest_derive/tests/grammar.rs31
-rw-r--r--vendor/pest_derive/tests/grammar_inline.rs4
-rw-r--r--vendor/pest_derive/tests/lists.rs4
-rw-r--r--vendor/pest_derive/tests/reporting.rs4
-rw-r--r--vendor/pest_generator/.cargo-checksum.json2
-rw-r--r--vendor/pest_generator/Cargo.toml34
-rw-r--r--vendor/pest_generator/_README.md23
-rw-r--r--vendor/pest_generator/src/generator.rs72
-rw-r--r--vendor/pest_generator/src/macros.rs14
-rw-r--r--vendor/pest_meta/.cargo-checksum.json2
-rw-r--r--vendor/pest_meta/Cargo.toml46
-rw-r--r--vendor/pest_meta/_README.md23
-rw-r--r--vendor/pest_meta/src/ast.rs2
-rw-r--r--vendor/pest_meta/src/grammar.pest2
-rw-r--r--vendor/pest_meta/src/grammar.rs2
-rw-r--r--vendor/pest_meta/src/lib.rs20
-rw-r--r--vendor/pest_meta/src/optimizer/concatenator.rs39
-rw-r--r--vendor/pest_meta/src/optimizer/factorizer.rs61
-rw-r--r--vendor/pest_meta/src/optimizer/lister.rs42
-rw-r--r--vendor/pest_meta/src/optimizer/mod.rs104
-rw-r--r--vendor/pest_meta/src/optimizer/restorer.rs14
-rw-r--r--vendor/pest_meta/src/optimizer/rotater.rs13
-rw-r--r--vendor/pest_meta/src/optimizer/skipper.rs39
-rw-r--r--vendor/pest_meta/src/optimizer/unroller.rs107
-rw-r--r--vendor/pest_meta/src/parser.rs93
-rw-r--r--vendor/pest_meta/src/validator.rs222
-rw-r--r--vendor/pretty_assertions/.cargo-checksum.json (renamed from vendor/pretty_assertions-0.7.2/.cargo-checksum.json)0
-rw-r--r--vendor/pretty_assertions/CHANGELOG.md (renamed from vendor/pretty_assertions-0.7.2/CHANGELOG.md)0
-rw-r--r--vendor/pretty_assertions/Cargo.lock (renamed from vendor/pretty_assertions-0.7.2/Cargo.lock)0
-rw-r--r--vendor/pretty_assertions/Cargo.toml (renamed from vendor/pretty_assertions-0.7.2/Cargo.toml)0
-rw-r--r--vendor/pretty_assertions/LICENSE-APACHE (renamed from vendor/pretty_assertions-0.7.2/LICENSE-APACHE)0
-rw-r--r--vendor/pretty_assertions/LICENSE-MIT (renamed from vendor/pretty_assertions-0.7.2/LICENSE-MIT)0
-rw-r--r--vendor/pretty_assertions/README.md (renamed from vendor/pretty_assertions-0.7.2/README.md)0
-rw-r--r--vendor/pretty_assertions/examples/pretty_assertion.png (renamed from vendor/pretty_assertions-0.7.2/examples/pretty_assertion.png)bin21419 -> 21419 bytes
-rw-r--r--vendor/pretty_assertions/examples/pretty_assertion.rs (renamed from vendor/pretty_assertions-0.7.2/examples/pretty_assertion.rs)0
-rw-r--r--vendor/pretty_assertions/examples/pretty_assertion_v0_6_1.png (renamed from vendor/pretty_assertions-0.7.2/examples/pretty_assertion_v0_6_1.png)bin21236 -> 21236 bytes
-rw-r--r--vendor/pretty_assertions/examples/standard_assertion.png (renamed from vendor/pretty_assertions-0.7.2/examples/standard_assertion.png)bin21727 -> 21727 bytes
-rw-r--r--vendor/pretty_assertions/examples/standard_assertion.rs (renamed from vendor/pretty_assertions-0.7.2/examples/standard_assertion.rs)0
-rwxr-xr-xvendor/pretty_assertions/scripts/check (renamed from vendor/pretty_assertions-0.7.2/scripts/check)0
-rwxr-xr-xvendor/pretty_assertions/scripts/install (renamed from vendor/pretty_assertions-0.7.2/scripts/install)0
-rwxr-xr-xvendor/pretty_assertions/scripts/publish (renamed from vendor/pretty_assertions-0.7.2/scripts/publish)0
-rw-r--r--vendor/pretty_assertions/src/lib.rs (renamed from vendor/pretty_assertions-0.7.2/src/lib.rs)0
-rw-r--r--vendor/pretty_assertions/src/printer.rs (renamed from vendor/pretty_assertions-0.7.2/src/printer.rs)0
-rw-r--r--vendor/proc-macro2/.cargo-checksum.json2
-rw-r--r--vendor/proc-macro2/Cargo.toml12
-rw-r--r--vendor/proc-macro2/src/detection.rs2
-rw-r--r--vendor/proc-macro2/src/fallback.rs169
-rw-r--r--vendor/proc-macro2/src/lib.rs40
-rw-r--r--vendor/proc-macro2/src/marker.rs4
-rw-r--r--vendor/proc-macro2/src/parse.rs64
-rw-r--r--vendor/proc-macro2/src/rcvec.rs142
-rw-r--r--vendor/proc-macro2/src/wrapper.rs14
-rw-r--r--vendor/proc-macro2/tests/comments.rs2
-rw-r--r--vendor/proc-macro2/tests/test.rs9
-rw-r--r--vendor/quick-error-1.2.3/.cargo-checksum.json1
-rw-r--r--vendor/quick-error-1.2.3/Cargo.lock6
-rw-r--r--vendor/quick-error-1.2.3/Cargo.toml23
-rw-r--r--vendor/quick-error-1.2.3/LICENSE-APACHE202
-rw-r--r--vendor/quick-error-1.2.3/LICENSE-MIT19
-rw-r--r--vendor/quick-error-1.2.3/README.rst66
-rw-r--r--vendor/quick-error-1.2.3/bulk.yaml8
-rw-r--r--vendor/quick-error-1.2.3/examples/context.rs48
-rw-r--r--vendor/quick-error-1.2.3/src/lib.rs1262
-rw-r--r--vendor/quick-error-1.2.3/vagga.yaml36
-rw-r--r--vendor/quick-error/.cargo-checksum.json2
-rw-r--r--vendor/quick-error/Cargo.lock3
-rw-r--r--vendor/quick-error/Cargo.toml3
-rw-r--r--vendor/quick-error/README.rst6
-rw-r--r--vendor/quick-error/examples/context.rs21
-rw-r--r--vendor/quick-error/src/lib.rs292
-rw-r--r--vendor/quick-error/vagga.yaml6
-rw-r--r--vendor/quote/.cargo-checksum.json2
-rw-r--r--vendor/quote/Cargo.toml7
-rw-r--r--vendor/quote/src/ext.rs4
-rw-r--r--vendor/quote/src/ident_fragment.rs2
-rw-r--r--vendor/quote/src/lib.rs2
-rw-r--r--vendor/quote/src/runtime.rs10
-rw-r--r--vendor/quote/src/to_tokens.rs6
-rw-r--r--vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr2
-rw-r--r--vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr2
-rw-r--r--vendor/quote/tests/ui/does-not-have-iter-separated.stderr2
-rw-r--r--vendor/quote/tests/ui/does-not-have-iter.stderr2
-rw-r--r--vendor/quote/tests/ui/not-repeatable.stderr76
-rw-r--r--vendor/redox_syscall/.cargo-checksum.json2
-rw-r--r--vendor/redox_syscall/Cargo.toml2
-rw-r--r--vendor/redox_syscall/src/arch/x86.rs105
-rw-r--r--vendor/redox_syscall/src/io/mod.rs4
-rw-r--r--vendor/redox_syscall/src/lib.rs2
-rw-r--r--vendor/regex-syntax/.cargo-checksum.json2
-rw-r--r--vendor/regex-syntax/Cargo.toml2
-rw-r--r--vendor/regex-syntax/src/ast/mod.rs6
-rw-r--r--vendor/regex-syntax/src/ast/parse.rs144
-rw-r--r--vendor/regex-syntax/src/ast/visitor.rs12
-rw-r--r--vendor/regex-syntax/src/error.rs4
-rw-r--r--vendor/regex-syntax/src/hir/interval.rs4
-rw-r--r--vendor/regex-syntax/src/hir/literal/mod.rs28
-rw-r--r--vendor/regex-syntax/src/hir/mod.rs18
-rw-r--r--vendor/regex-syntax/src/hir/translate.rs20
-rw-r--r--vendor/regex-syntax/src/lib.rs2
-rw-r--r--vendor/regex-syntax/src/parser.rs2
-rw-r--r--vendor/regex-syntax/src/unicode.rs7
-rw-r--r--vendor/regex-syntax/src/unicode_tables/age.rs198
-rw-r--r--vendor/regex-syntax/src/unicode_tables/case_folding_simple.rs98
-rw-r--r--vendor/regex-syntax/src/unicode_tables/general_category.rs747
-rw-r--r--vendor/regex-syntax/src/unicode_tables/grapheme_cluster_break.rs49
-rw-r--r--vendor/regex-syntax/src/unicode_tables/perl_decimal.rs11
-rw-r--r--vendor/regex-syntax/src/unicode_tables/perl_space.rs6
-rw-r--r--vendor/regex-syntax/src/unicode_tables/perl_word.rs128
-rw-r--r--vendor/regex-syntax/src/unicode_tables/property_bool.rs1128
-rw-r--r--vendor/regex-syntax/src/unicode_tables/property_names.rs6
-rw-r--r--vendor/regex-syntax/src/unicode_tables/property_values.rs26
-rw-r--r--vendor/regex-syntax/src/unicode_tables/script.rs222
-rw-r--r--vendor/regex-syntax/src/unicode_tables/script_extension.rs229
-rw-r--r--vendor/regex-syntax/src/unicode_tables/sentence_break.rs182
-rw-r--r--vendor/regex-syntax/src/unicode_tables/word_break.rs134
-rw-r--r--vendor/regex-syntax/src/utf8.rs6
-rw-r--r--vendor/regex/.cargo-checksum.json2
-rw-r--r--vendor/regex/CHANGELOG.md21
-rw-r--r--vendor/regex/Cargo.lock18
-rw-r--r--vendor/regex/Cargo.toml4
-rw-r--r--vendor/regex/src/backtrack.rs12
-rw-r--r--vendor/regex/src/compile.rs57
-rw-r--r--vendor/regex/src/dfa.rs38
-rw-r--r--vendor/regex/src/exec.rs14
-rw-r--r--vendor/regex/src/expand.rs8
-rw-r--r--vendor/regex/src/input.rs4
-rw-r--r--vendor/regex/src/lib.rs1
-rw-r--r--vendor/regex/src/literal/imp.rs4
-rw-r--r--vendor/regex/src/pattern.rs2
-rw-r--r--vendor/regex/src/pikevm.rs2
-rw-r--r--vendor/regex/src/prog.rs2
-rw-r--r--vendor/regex/src/re_bytes.rs12
-rw-r--r--vendor/regex/src/re_set.rs44
-rw-r--r--vendor/regex/src/re_trait.rs13
-rw-r--r--vendor/regex/src/re_unicode.rs24
-rw-r--r--vendor/regex/src/utf8.rs2
-rw-r--r--vendor/regex/tests/unicode.rs17
-rw-r--r--vendor/rustc_tools_util/.cargo-checksum.json1
-rw-r--r--vendor/rustc_tools_util/Cargo.toml25
-rw-r--r--vendor/rustc_tools_util/README.md62
-rw-r--r--vendor/rustc_tools_util/src/lib.rs158
-rw-r--r--vendor/ryu/.cargo-checksum.json2
-rw-r--r--vendor/ryu/Cargo.lock54
-rw-r--r--vendor/ryu/Cargo.toml8
-rw-r--r--vendor/ryu/README.md2
-rw-r--r--vendor/ryu/src/lib.rs4
-rw-r--r--vendor/semver/.cargo-checksum.json2
-rw-r--r--vendor/semver/Cargo.toml7
-rw-r--r--vendor/semver/build.rs2
-rw-r--r--vendor/semver/src/lib.rs2
-rw-r--r--vendor/serde/.cargo-checksum.json2
-rw-r--r--vendor/serde/Cargo.toml10
-rw-r--r--vendor/serde/src/de/mod.rs14
-rw-r--r--vendor/serde/src/lib.rs9
-rw-r--r--vendor/serde/src/ser/mod.rs8
-rw-r--r--vendor/serde_derive/.cargo-checksum.json2
-rw-r--r--vendor/serde_derive/Cargo.toml5
-rw-r--r--vendor/serde_derive/src/lib.rs2
-rw-r--r--vendor/serde_json/.cargo-checksum.json2
-rw-r--r--vendor/serde_json/Cargo.toml11
-rw-r--r--vendor/serde_json/src/lib.rs3
-rw-r--r--vendor/serde_json/src/number.rs35
-rw-r--r--vendor/serde_json/src/value/mod.rs22
-rw-r--r--vendor/serde_json/tests/debug.rs43
-rw-r--r--vendor/serde_json/tests/regression/issue795.rs2
-rw-r--r--vendor/serde_json/tests/stream.rs1
-rw-r--r--vendor/serde_json/tests/test.rs1
-rw-r--r--vendor/serde_json/tests/ui/missing_colon.stderr2
-rw-r--r--vendor/serde_json/tests/ui/missing_value.stderr2
-rw-r--r--vendor/serde_repr/.cargo-checksum.json2
-rw-r--r--vendor/serde_repr/Cargo.toml11
-rw-r--r--vendor/serde_repr/README.md2
-rw-r--r--vendor/serde_repr/src/lib.rs2
-rw-r--r--vendor/serde_repr/tests/test.rs1
-rw-r--r--vendor/sha-1-0.8.2/.cargo-checksum.json1
-rw-r--r--vendor/sha-1-0.8.2/Cargo.lock148
-rw-r--r--vendor/sha-1-0.8.2/Cargo.toml58
-rw-r--r--vendor/sha-1-0.8.2/LICENSE-APACHE201
-rw-r--r--vendor/sha-1-0.8.2/LICENSE-MIT27
-rw-r--r--vendor/sha-1-0.8.2/benches/lib.rs7
-rw-r--r--vendor/sha-1-0.8.2/examples/sha1sum.rs49
-rw-r--r--vendor/sha-1-0.8.2/src/aarch64.rs9
-rw-r--r--vendor/sha-1-0.8.2/src/consts.rs19
-rw-r--r--vendor/sha-1-0.8.2/src/lib.rs141
-rw-r--r--vendor/sha-1-0.8.2/src/utils.rs300
-rw-r--r--vendor/sha-1-0.8.2/tests/data/one_million_a.bin1
-rw-r--r--vendor/sha-1-0.8.2/tests/data/sha1.blb1
-rw-r--r--vendor/sha-1-0.8.2/tests/lib.rs14
-rw-r--r--vendor/syn/.cargo-checksum.json2
-rw-r--r--vendor/syn/Cargo.toml11
-rw-r--r--vendor/syn/benches/file.rs34
-rw-r--r--vendor/syn/src/buffer.rs102
-rw-r--r--vendor/syn/src/lib.rs4
-rw-r--r--vendor/syn/tests/common/eq.rs47
-rw-r--r--vendor/syn/tests/test_derive_input.rs2
-rw-r--r--vendor/syn/tests/test_stmt.rs2
-rw-r--r--vendor/thin-vec/.cargo-checksum.json1
-rw-r--r--vendor/thin-vec/Cargo.toml33
-rw-r--r--vendor/thin-vec/README.md9
-rw-r--r--vendor/thin-vec/src/lib.rs3117
-rw-r--r--vendor/thiserror-impl/.cargo-checksum.json2
-rw-r--r--vendor/thiserror-impl/Cargo.toml4
-rw-r--r--vendor/thiserror-impl/src/expand.rs108
-rw-r--r--vendor/thiserror-impl/src/generics.rs1
-rw-r--r--vendor/thiserror-impl/src/lib.rs5
-rw-r--r--vendor/thiserror-impl/src/valid.rs6
-rw-r--r--vendor/thiserror/.cargo-checksum.json2
-rw-r--r--vendor/thiserror/Cargo.toml12
-rw-r--r--vendor/thiserror/README.md2
-rw-r--r--vendor/thiserror/src/lib.rs5
-rw-r--r--vendor/thiserror/tests/compiletest.rs3
-rw-r--r--vendor/thiserror/tests/test_backtrace.rs41
-rw-r--r--vendor/thiserror/tests/test_display.rs2
-rw-r--r--vendor/thiserror/tests/test_error.rs1
-rw-r--r--vendor/thiserror/tests/test_expr.rs3
-rw-r--r--vendor/thiserror/tests/test_from.rs2
-rw-r--r--vendor/thiserror/tests/test_generics.rs2
-rw-r--r--vendor/thiserror/tests/test_option.rs6
-rw-r--r--vendor/thiserror/tests/test_path.rs2
-rw-r--r--vendor/thiserror/tests/test_source.rs2
-rw-r--r--vendor/thiserror/tests/test_transparent.rs2
-rw-r--r--vendor/thiserror/tests/ui/concat-display.stderr2
-rw-r--r--vendor/thiserror/tests/ui/from-backtrace-backtrace.rs10
-rw-r--r--vendor/thiserror/tests/ui/from-backtrace-backtrace.stderr5
-rw-r--r--vendor/thiserror/tests/ui/no-display.stderr12
-rw-r--r--vendor/thiserror/tests/ui/source-enum-not-error.stderr44
-rw-r--r--vendor/thiserror/tests/ui/source-struct-not-error.stderr42
-rw-r--r--vendor/tracing-core/.cargo-checksum.json2
-rw-r--r--vendor/tracing-core/CHANGELOG.md23
-rw-r--r--vendor/tracing-core/Cargo.toml6
-rw-r--r--vendor/tracing-core/README.md26
-rw-r--r--vendor/tracing-core/src/callsite.rs9
-rw-r--r--vendor/tracing-core/src/dispatcher.rs15
-rw-r--r--vendor/tracing-core/src/field.rs44
-rw-r--r--vendor/tracing-core/src/metadata.rs89
-rw-r--r--vendor/tracing-subscriber/.cargo-checksum.json2
-rw-r--r--vendor/tracing-subscriber/CHANGELOG.md13
-rw-r--r--vendor/tracing-subscriber/Cargo.toml2
-rw-r--r--vendor/tracing-subscriber/README.md2
-rw-r--r--vendor/tracing-subscriber/src/lib.rs2
-rw-r--r--vendor/tracing-subscriber/src/reload.rs12
-rw-r--r--vendor/tracing-subscriber/tests/reload.rs32
-rw-r--r--vendor/tracing/.cargo-checksum.json2
-rw-r--r--vendor/tracing/CHANGELOG.md30
-rw-r--r--vendor/tracing/Cargo.toml48
-rw-r--r--vendor/tracing/README.md10
-rw-r--r--vendor/tracing/benches/baseline.rs24
-rw-r--r--vendor/tracing/benches/dispatch_get_clone.rs15
-rw-r--r--vendor/tracing/benches/dispatch_get_ref.rs16
-rw-r--r--vendor/tracing/benches/empty_span.rs43
-rw-r--r--vendor/tracing/benches/enter_span.rs16
-rw-r--r--vendor/tracing/benches/event.rs12
-rw-r--r--vendor/tracing/benches/global_subscriber.rs136
-rw-r--r--vendor/tracing/benches/no_subscriber.rs101
-rw-r--r--vendor/tracing/benches/shared.rs160
-rw-r--r--vendor/tracing/benches/span_fields.rs23
-rw-r--r--vendor/tracing/benches/span_no_fields.rs13
-rw-r--r--vendor/tracing/benches/span_repeated.rs20
-rw-r--r--vendor/tracing/benches/subscriber.rs189
-rw-r--r--vendor/tracing/src/lib.rs6
-rw-r--r--vendor/tracing/src/span.rs18
-rw-r--r--vendor/tracing/src/subscriber.rs17
-rw-r--r--vendor/tracing/tests/event.rs24
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/.cargo-checksum.json1
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/CODE_OF_CONDUCT.md49
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/CONTRIBUTING.md8
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/Cargo.toml43
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-APACHE201
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception220
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-MIT23
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/ORG_CODE_OF_CONDUCT.md143
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/README.md94
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/SECURITY.md29
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/src/error.rs52
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib.rs48
-rw-r--r--vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib_generated.rs1940
-rw-r--r--version2
-rwxr-xr-xx.py30
6686 files changed, 145311 insertions, 95340 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2569b3e19..fda523611 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -79,17 +79,11 @@ dependencies = [
"maplit",
"once_cell",
"tendril",
- "url 2.2.2",
+ "url",
]
[[package]]
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"
@@ -109,9 +103,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.60"
+version = "1.0.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
+checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
[[package]]
name = "array_tool"
@@ -217,32 +211,11 @@ dependencies = [
[[package]]
name = "block-buffer"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
-dependencies = [
- "block-padding",
- "byte-tools",
- "byteorder",
- "generic-array 0.12.4",
-]
-
-[[package]]
-name = "block-buffer"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
dependencies = [
- "generic-array 0.14.4",
-]
-
-[[package]]
-name = "block-padding"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
-dependencies = [
- "byte-tools",
+ "generic-array",
]
[[package]]
@@ -263,7 +236,6 @@ dependencies = [
"anyhow",
"flate2",
"hex 0.4.2",
- "num_cpus",
"rayon",
"serde",
"serde_json",
@@ -285,12 +257,6 @@ dependencies = [
]
[[package]]
-name = "byte-tools"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
-
-[[package]]
name = "bytecount"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -300,12 +266,6 @@ dependencies = [
]
[[package]]
-name = "byteorder"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
-
-[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -328,7 +288,7 @@ dependencies = [
[[package]]
name = "cargo"
-version = "0.65.0"
+version = "0.66.0"
dependencies = [
"anyhow",
"atty",
@@ -339,7 +299,6 @@ dependencies = [
"cargo-util",
"clap",
"crates-io",
- "crossbeam-utils",
"curl",
"curl-sys",
"env_logger 0.9.0",
@@ -363,12 +322,11 @@ dependencies = [
"libgit2-sys",
"log",
"memchr",
- "num_cpus",
"opener",
"openssl",
"os_info",
"pathdiff",
- "percent-encoding 2.1.0",
+ "percent-encoding",
"pretty_env_logger",
"rustc-workspace-hack",
"rustfix",
@@ -385,7 +343,7 @@ dependencies = [
"toml_edit",
"unicode-width",
"unicode-xid",
- "url 2.2.2",
+ "url",
"walkdir",
"winapi",
]
@@ -423,6 +381,7 @@ dependencies = [
name = "cargo-miri"
version = "0.1.0"
dependencies = [
+ "cargo_metadata 0.15.0",
"directories",
"rustc-workspace-hack",
"rustc_version",
@@ -470,12 +429,13 @@ dependencies = [
"tar",
"termcolor",
"toml_edit",
- "url 2.2.2",
+ "url",
+ "winapi",
]
[[package]]
name = "cargo-util"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"anyhow",
"core-foundation",
@@ -525,9 +485,9 @@ version = "0.1.0"
[[package]]
name = "cc"
-version = "1.0.69"
+version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
dependencies = [
"jobserver",
]
@@ -617,9 +577,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "3.2.5"
+version = "3.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7"
+checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"
dependencies = [
"atty",
"bitflags",
@@ -643,9 +603,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "3.2.5"
+version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9"
+checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [
"heck",
"proc-macro-error",
@@ -665,14 +625,14 @@ dependencies = [
[[package]]
name = "clippy"
-version = "0.1.64"
+version = "0.1.65"
dependencies = [
"clippy_lints",
"clippy_utils",
"compiletest_rs",
"derive-new",
"filetime",
- "futures 0.3.19",
+ "futures",
"if_chain",
"itertools",
"parking_lot 0.12.1",
@@ -680,7 +640,7 @@ dependencies = [
"regex",
"rustc-semver",
"rustc-workspace-hack",
- "rustc_tools_util 0.2.0",
+ "rustc_tools_util",
"semver",
"serde",
"syn",
@@ -708,7 +668,7 @@ dependencies = [
[[package]]
name = "clippy_lints"
-version = "0.1.64"
+version = "0.1.65"
dependencies = [
"cargo_metadata 0.14.0",
"clippy_utils",
@@ -725,15 +685,16 @@ dependencies = [
"toml",
"unicode-normalization",
"unicode-script",
- "url 2.2.2",
+ "url",
]
[[package]]
name = "clippy_utils"
-version = "0.1.64"
+version = "0.1.65"
dependencies = [
"arrayvec",
"if_chain",
+ "itertools",
"rustc-semver",
]
@@ -777,9 +738,9 @@ dependencies = [
[[package]]
name = "combine"
-version = "4.6.3"
+version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50b727aacc797f9fc28e355d21f34709ac4fc9adecfe470ad07b8f4464f53062"
+checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
dependencies = [
"bytes",
"memchr",
@@ -805,9 +766,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
-version = "0.1.73"
+version = "0.1.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71b72fde1d7792ca3bd654f7c3ea4508f9e4d0c826e24179eabb7fcc97a90bc3"
+checksum = "4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"
dependencies = [
"cc",
"rustc-std-workspace-core",
@@ -822,6 +783,7 @@ dependencies = [
"getopts",
"glob",
"lazy_static",
+ "lazycell",
"libc",
"miow",
"regex",
@@ -927,10 +889,10 @@ version = "0.34.0"
dependencies = [
"anyhow",
"curl",
- "percent-encoding 2.1.0",
+ "percent-encoding",
"serde",
"serde_json",
- "url 2.2.2",
+ "url",
]
[[package]]
@@ -1016,7 +978,7 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06"
dependencies = [
- "generic-array 0.14.4",
+ "generic-array",
]
[[package]]
@@ -1042,16 +1004,6 @@ dependencies = [
]
[[package]]
-name = "ctor"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
name = "curl"
version = "0.4.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1100,17 +1052,6 @@ dependencies = [
]
[[package]]
-name = "derive_more"
-version = "0.99.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1124,20 +1065,11 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "digest"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-dependencies = [
- "generic-array 0.12.4",
-]
-
-[[package]]
-name = "digest"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837"
dependencies = [
- "block-buffer 0.10.2",
+ "block-buffer",
"crypto-common",
]
@@ -1285,8 +1217,7 @@ dependencies = [
name = "error_index_generator"
version = "0.0.0"
dependencies = [
- "rustdoc",
- "walkdir",
+ "mdbook",
]
[[package]]
@@ -1318,12 +1249,6 @@ dependencies = [
]
[[package]]
-name = "fake-simd"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
-
-[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1422,14 +1347,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
- "percent-encoding 2.1.0",
+ "percent-encoding",
]
[[package]]
name = "fortanix-sgx-abi"
-version = "0.3.3"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"
+checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-core",
@@ -1437,9 +1362,9 @@ dependencies = [
[[package]]
name = "fs-err"
-version = "2.5.0"
+version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcd1163ae48bda72a20ae26d66a04d3094135cadab911cff418ae5e33f253431"
+checksum = "64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50"
[[package]]
name = "fs_extra"
@@ -1448,12 +1373,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
[[package]]
-name = "fst"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f"
-
-[[package]]
name = "futf"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1465,12 +1384,6 @@ dependencies = [
[[package]]
name = "futures"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
-
-[[package]]
-name = "futures"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4"
@@ -1509,7 +1422,6 @@ dependencies = [
"futures-core",
"futures-task",
"futures-util",
- "num_cpus",
]
[[package]]
@@ -1547,7 +1459,6 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
dependencies = [
- "futures 0.1.31",
"futures-channel",
"futures-core",
"futures-io",
@@ -1572,15 +1483,6 @@ dependencies = [
[[package]]
name = "generic-array"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
-dependencies = [
- "typenum",
-]
-
-[[package]]
-name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
@@ -1658,9 +1560,9 @@ dependencies = [
[[package]]
name = "git2"
-version = "0.14.2"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3826a6e0e2215d7a41c2bfc7c9244123969273f3476b939a226aac0ab56e9e3c"
+checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
dependencies = [
"bitflags",
"libc",
@@ -1668,19 +1570,19 @@ dependencies = [
"log",
"openssl-probe",
"openssl-sys",
- "url 2.2.2",
+ "url",
]
[[package]]
name = "git2-curl"
-version = "0.15.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ee51709364c341fbb6fe2a385a290fb9196753bdde2fc45447d27cd31b11b13"
+checksum = "ed817a00721e2f8037ba722e60358d4956dae9cca10315fc982f967907d3b0cd"
dependencies = [
"curl",
"git2",
"log",
- "url 2.2.2",
+ "url",
]
[[package]]
@@ -1713,16 +1615,16 @@ dependencies = [
[[package]]
name = "handlebars"
-version = "4.1.0"
+version = "4.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72a0ffab8c36d0436114310c7e10b59b3307e650ddfabf6d006028e29a70c6e6"
+checksum = "360d9740069b2f6cbb63ce2dbaa71a20d3185350cbb990d7bebeb9318415eb17"
dependencies = [
"log",
"pest",
"pest_derive",
- "quick-error 2.0.0",
"serde",
"serde_json",
+ "thiserror",
]
[[package]]
@@ -1754,12 +1656,13 @@ dependencies = [
[[package]]
name = "hermit-abi"
-version = "0.2.0"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab7905ea95c6d9af62940f9d7dd9596d54c334ae2c15300c482051292d5637f"
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"compiler_builtins",
"libc",
+ "rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
@@ -1812,7 +1715,7 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
- "quick-error 1.2.3",
+ "quick-error",
]
[[package]]
@@ -1823,17 +1726,6 @@ checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
[[package]]
name = "idna"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-dependencies = [
- "matches",
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "idna"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
@@ -1869,13 +1761,13 @@ dependencies = [
[[package]]
name = "im-rc"
-version = "15.0.0"
+version = "15.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
+checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe"
dependencies = [
"bitmaps",
- "rand_core 0.5.1",
- "rand_xoshiro 0.4.0",
+ "rand_core 0.6.2",
+ "rand_xoshiro",
"sized-chunks",
"typenum",
"version_check",
@@ -1987,12 +1879,6 @@ dependencies = [
]
[[package]]
-name = "json"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
-
-[[package]]
name = "jsondocck"
version = "0.1.0"
dependencies = [
@@ -2006,123 +1892,29 @@ dependencies = [
]
[[package]]
-name = "jsonpath_lib"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61352ec23883402b7d30b3313c16cbabefb8907361c4eb669d990cbb87ceee5a"
-dependencies = [
- "array_tool",
- "env_logger 0.7.1",
- "log",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "jsonrpc-client-transports"
-version = "18.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a"
+name = "jsondoclint"
+version = "0.1.0"
dependencies = [
- "derive_more",
- "futures 0.3.19",
- "jsonrpc-core",
- "jsonrpc-pubsub",
- "jsonrpc-server-utils",
- "log",
- "parity-tokio-ipc",
- "serde",
+ "anyhow",
+ "fs-err",
+ "rustdoc-json-types",
"serde_json",
- "tokio",
- "url 1.7.2",
]
[[package]]
-name = "jsonrpc-core"
-version = "18.0.0"
+name = "jsonpath_lib"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb"
+checksum = "61352ec23883402b7d30b3313c16cbabefb8907361c4eb669d990cbb87ceee5a"
dependencies = [
- "futures 0.3.19",
- "futures-executor",
- "futures-util",
+ "array_tool",
+ "env_logger 0.7.1",
"log",
"serde",
- "serde_derive",
"serde_json",
]
[[package]]
-name = "jsonrpc-core-client"
-version = "18.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0"
-dependencies = [
- "futures 0.3.19",
- "jsonrpc-client-transports",
-]
-
-[[package]]
-name = "jsonrpc-derive"
-version = "18.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "jsonrpc-ipc-server"
-version = "18.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845"
-dependencies = [
- "futures 0.3.19",
- "jsonrpc-core",
- "jsonrpc-server-utils",
- "log",
- "parity-tokio-ipc",
- "parking_lot 0.11.2",
- "tower-service",
-]
-
-[[package]]
-name = "jsonrpc-pubsub"
-version = "18.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011"
-dependencies = [
- "futures 0.3.19",
- "jsonrpc-core",
- "lazy_static",
- "log",
- "parking_lot 0.11.2",
- "rand 0.7.3",
- "serde",
-]
-
-[[package]]
-name = "jsonrpc-server-utils"
-version = "18.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4"
-dependencies = [
- "bytes",
- "futures 0.3.19",
- "globset",
- "jsonrpc-core",
- "lazy_static",
- "log",
- "tokio",
- "tokio-stream",
- "tokio-util",
- "unicase",
-]
-
-[[package]]
name = "kstring"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2145,18 +1937,37 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.131"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40"
dependencies = [
"rustc-std-workspace-core",
]
[[package]]
+name = "libffi"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e454b3efb16fba3b17810ae5e41df02b649e564ab3c5a34b3b93ed07ad287e6"
+dependencies = [
+ "libc",
+ "libffi-sys",
+]
+
+[[package]]
+name = "libffi-sys"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab4106b7f09d7b87d021334d5618fac1dfcfb824d4c5fe111ff0074dfd242e15"
+dependencies = [
+ "cc",
+]
+
+[[package]]
name = "libgit2-sys"
-version = "0.13.2+1.4.2"
+version = "0.14.0+1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a42de9a51a5c12e00fc0e4ca6bc2ea43582fc6418488e8f615e905d886f258b"
+checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b"
dependencies = [
"cc",
"libc",
@@ -2265,30 +2076,6 @@ dependencies = [
]
[[package]]
-name = "lsp-codec"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa939d0b62476a5a19fb7fcb423a5c6ce8c7e09b851d37531e2fe3e0e6d9d257"
-dependencies = [
- "bytes",
- "serde_json",
- "tokio-util",
-]
-
-[[package]]
-name = "lsp-types"
-version = "0.60.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe3edefcd66dde1f7f1df706f46520a3c93adc5ca4bc5747da6621195e894efd"
-dependencies = [
- "bitflags",
- "serde",
- "serde_json",
- "serde_repr",
- "url 2.2.2",
-]
-
-[[package]]
name = "lzma-sys"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2346,7 +2133,7 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6a38fc55c8bbc10058782919516f88826e70320db6d206aebc49611d24216ae"
dependencies = [
- "digest 0.10.2",
+ "digest",
]
[[package]]
@@ -2421,9 +2208,9 @@ dependencies = [
[[package]]
name = "minifier"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac96d1e7a65f206443f95afff6de8f1690c77c97d6fc9c9bb2d2cd0662e9ff9f"
+checksum = "8eb022374af2f446981254e6bf9efb6e2c9e1a53176d395fca02792fd4435729"
[[package]]
name = "minimal-lexical"
@@ -2453,19 +2240,6 @@ dependencies = [
]
[[package]]
-name = "mio"
-version = "0.7.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
-dependencies = [
- "libc",
- "log",
- "miow",
- "ntapi",
- "winapi",
-]
-
-[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2483,6 +2257,8 @@ dependencies = [
"getrandom 0.2.0",
"lazy_static",
"libc",
+ "libffi",
+ "libloading",
"log",
"measureme",
"rand 0.8.5",
@@ -2517,15 +2293,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
-name = "ntapi"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "num-integer"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2595,12 +2362,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
[[package]]
-name = "opaque-debug"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
-
-[[package]]
name = "opener"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2654,16 +2415,10 @@ dependencies = [
]
[[package]]
-name = "ordslice"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
-
-[[package]]
name = "os_info"
-version = "3.4.0"
+version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0eca3ecae1481e12c3d9379ec541b238a16f0b75c9a409942daa8ec20dbfdb62"
+checksum = "5209b2162b2c140df493a93689e04f8deab3a67634f5bc7a553c0a98e5b8d399"
dependencies = [
"log",
"serde",
@@ -2677,15 +2432,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
[[package]]
-name = "output_vt100"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "owo-colors"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2725,20 +2471,6 @@ dependencies = [
]
[[package]]
-name = "parity-tokio-ipc"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6"
-dependencies = [
- "futures 0.3.19",
- "libc",
- "log",
- "rand 0.7.3",
- "tokio",
- "winapi",
-]
-
-[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2794,12 +2526,6 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]]
name = "percent-encoding"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-
-[[package]]
-name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
@@ -2815,18 +2541,19 @@ dependencies = [
[[package]]
name = "pest"
-version = "2.1.3"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4"
dependencies = [
+ "thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
-version = "2.1.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
+checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91"
dependencies = [
"pest",
"pest_generator",
@@ -2834,9 +2561,9 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.1.3"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
+checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad"
dependencies = [
"pest",
"pest_meta",
@@ -2847,13 +2574,13 @@ dependencies = [
[[package]]
name = "pest_meta"
-version = "2.1.3"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
+checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04"
dependencies = [
- "maplit",
+ "once_cell",
"pest",
- "sha-1 0.8.2",
+ "sha-1",
]
[[package]]
@@ -2946,18 +2673,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2968,15 +2683,6 @@ dependencies = [
]
[[package]]
-name = "proc-macro-crate"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
-dependencies = [
- "toml",
-]
-
-[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3065,12 +2771,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
-name = "quick-error"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda"
-
-[[package]]
name = "quine-mc_cluskey"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3086,37 +2786,6 @@ dependencies = [
]
[[package]]
-name = "racer"
-version = "2.2.2"
-dependencies = [
- "bitflags",
- "derive_more",
- "env_logger 0.7.1",
- "humantime 2.0.1",
- "lazy_static",
- "lazycell",
- "log",
- "racer-cargo-metadata",
- "rls-span",
-]
-
-[[package]]
-name = "racer-cargo-metadata"
-version = "0.1.2"
-dependencies = [
- "racer-interner",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "racer-interner"
-version = "0.1.0"
-dependencies = [
- "serde",
-]
-
-[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3198,15 +2867,6 @@ dependencies = [
[[package]]
name = "rand_xoshiro"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
-dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_xoshiro"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
@@ -3301,68 +2961,18 @@ dependencies = [
]
[[package]]
-name = "rls"
-version = "1.41.0"
+name = "replace-version-placeholder"
+version = "0.1.0"
dependencies = [
- "anyhow",
- "cargo",
- "cargo-util",
- "cargo_metadata 0.14.0",
- "clippy_lints",
- "crossbeam-channel",
- "difference",
- "env_logger 0.9.0",
- "futures 0.3.19",
- "heck",
- "home",
- "itertools",
- "jsonrpc-core",
- "lazy_static",
- "log",
- "lsp-codec",
- "lsp-types",
- "num_cpus",
- "ordslice",
- "racer",
- "rand 0.8.5",
- "rayon",
- "regex",
- "rls-analysis",
- "rls-data",
- "rls-ipc",
- "rls-rustc",
- "rls-span",
- "rls-vfs",
- "rustc-workspace-hack",
- "rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly",
- "serde",
- "serde_derive",
- "serde_ignored",
- "serde_json",
- "tempfile",
- "tokio",
- "tokio-stream",
- "tokio-util",
- "toml",
- "toml_edit",
- "url 2.2.2",
+ "tidy",
"walkdir",
]
[[package]]
-name = "rls-analysis"
-version = "0.18.3"
+name = "rls"
+version = "2.0.0"
dependencies = [
- "derive-new",
- "env_logger 0.9.0",
- "fst",
- "itertools",
- "json",
- "lazy_static",
- "log",
- "rls-data",
- "rls-span",
+ "rustc-workspace-hack",
"serde",
"serde_json",
]
@@ -3378,33 +2988,6 @@ dependencies = [
]
[[package]]
-name = "rls-ipc"
-version = "0.1.0"
-dependencies = [
- "jsonrpc-core",
- "jsonrpc-core-client",
- "jsonrpc-derive",
- "jsonrpc-ipc-server",
- "rls-data",
- "serde",
-]
-
-[[package]]
-name = "rls-rustc"
-version = "0.6.0"
-dependencies = [
- "clippy_lints",
- "env_logger 0.9.0",
- "futures 0.3.19",
- "log",
- "rand 0.8.5",
- "rls-data",
- "rls-ipc",
- "serde",
- "tokio",
-]
-
-[[package]]
name = "rls-span"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3414,16 +2997,6 @@ dependencies = [
]
[[package]]
-name = "rls-vfs"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce4b57b25b4330ed5ec14028fc02141e083ddafda327e7eb598dc0569c8c83c9"
-dependencies = [
- "log",
- "rls-span",
-]
-
-[[package]]
name = "rust-demangler"
version = "0.0.1"
dependencies = [
@@ -3522,21 +3095,12 @@ name = "rustc-workspace-hack"
version = "1.0.0"
dependencies = [
"bstr",
- "byteorder",
"clap",
- "crossbeam-utils",
- "libc",
"libz-sys",
- "memchr",
- "proc-macro2",
- "quote",
- "rand_core 0.5.1",
"regex",
- "serde",
"serde_json",
- "smallvec",
"syn",
- "url 2.2.2",
+ "url",
"winapi",
]
@@ -3567,6 +3131,7 @@ dependencies = [
"rustc_serialize",
"rustc_span",
"smallvec",
+ "thin-vec",
"tracing",
]
@@ -3581,12 +3146,14 @@ dependencies = [
"rustc_errors",
"rustc_hir",
"rustc_index",
+ "rustc_macros",
"rustc_middle",
"rustc_query_system",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec",
+ "thin-vec",
"tracing",
]
@@ -3601,6 +3168,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
+ "rustc_macros",
"rustc_parse",
"rustc_session",
"rustc_span",
@@ -3680,6 +3248,7 @@ dependencies = [
"rustc_span",
"rustc_target",
"smallvec",
+ "thin-vec",
"tracing",
]
@@ -3692,6 +3261,7 @@ dependencies = [
"libc",
"libloading",
"measureme",
+ "object 0.29.0",
"rustc-demangle",
"rustc_ast",
"rustc_attr",
@@ -3727,7 +3297,6 @@ dependencies = [
"object 0.29.0",
"pathdiff",
"regex",
- "rustc_apfloat",
"rustc_arena",
"rustc_ast",
"rustc_attr",
@@ -3804,6 +3373,7 @@ dependencies = [
"stable_deref_trait",
"stacker",
"tempfile",
+ "thin-vec",
"tracing",
"winapi",
]
@@ -3825,6 +3395,7 @@ dependencies = [
"rustc_interface",
"rustc_lint",
"rustc_log",
+ "rustc_macros",
"rustc_metadata",
"rustc_middle",
"rustc_parse",
@@ -3862,7 +3433,7 @@ dependencies = [
name = "rustc_errors"
version = "0.0.0"
dependencies = [
- "annotate-snippets 0.8.0",
+ "annotate-snippets",
"atty",
"rustc_data_structures",
"rustc_error_messages",
@@ -3871,6 +3442,7 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
+ "rustc_target",
"serde",
"serde_json",
"termcolor",
@@ -3988,6 +3560,7 @@ dependencies = [
"rustc_macros",
"rustc_middle",
"rustc_serialize",
+ "rustc_session",
"rustc_span",
"rustc_target",
"smallvec",
@@ -4017,6 +3590,7 @@ dependencies = [
"rustc_hir",
"rustc_incremental",
"rustc_lint",
+ "rustc_macros",
"rustc_metadata",
"rustc_middle",
"rustc_mir_build",
@@ -4114,7 +3688,7 @@ dependencies = [
name = "rustc_macros"
version = "0.1.0"
dependencies = [
- "annotate-snippets 0.8.0",
+ "annotate-snippets",
"fluent-bundle",
"fluent-syntax",
"proc-macro2",
@@ -4162,7 +3736,7 @@ dependencies = [
"gsgdt",
"polonius-engine",
"rand 0.8.5",
- "rand_xoshiro 0.6.0",
+ "rand_xoshiro",
"rustc-rayon",
"rustc-rayon-core",
"rustc_apfloat",
@@ -4183,6 +3757,7 @@ dependencies = [
"rustc_target",
"rustc_type_ir",
"smallvec",
+ "thin-vec",
"tracing",
]
@@ -4217,11 +3792,14 @@ dependencies = [
"regex",
"rustc_ast",
"rustc_data_structures",
+ "rustc_errors",
"rustc_graphviz",
"rustc_hir",
"rustc_index",
+ "rustc_macros",
"rustc_middle",
"rustc_serialize",
+ "rustc_session",
"rustc_span",
"rustc_target",
"smallvec",
@@ -4257,8 +3835,10 @@ name = "rustc_monomorphize"
version = "0.0.0"
dependencies = [
"rustc_data_structures",
+ "rustc_errors",
"rustc_hir",
"rustc_index",
+ "rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
@@ -4325,6 +3905,7 @@ dependencies = [
"rustc_ast",
"rustc_errors",
"rustc_lint",
+ "rustc_macros",
"rustc_metadata",
"rustc_session",
"rustc_span",
@@ -4365,6 +3946,8 @@ dependencies = [
"rustc_serialize",
"rustc_session",
"rustc_span",
+ "rustc_target",
+ "thin-vec",
"tracing",
]
@@ -4386,7 +3969,9 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
+ "rustc_type_ir",
"smallvec",
+ "thin-vec",
"tracing",
]
@@ -4423,9 +4008,11 @@ dependencies = [
"rustc_ast",
"rustc_ast_pretty",
"rustc_data_structures",
+ "rustc_errors",
"rustc_hir",
"rustc_hir_pretty",
"rustc_lexer",
+ "rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
@@ -4440,6 +4027,7 @@ dependencies = [
"indexmap",
"rustc_macros",
"smallvec",
+ "thin-vec",
]
[[package]]
@@ -4447,7 +4035,6 @@ name = "rustc_session"
version = "0.0.0"
dependencies = [
"getopts",
- "num_cpus",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
@@ -4489,7 +4076,7 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"scoped-tls",
- "sha-1 0.10.0",
+ "sha-1",
"sha2",
"tracing",
"unicode-width",
@@ -4503,7 +4090,9 @@ dependencies = [
"punycode",
"rustc-demangle",
"rustc_data_structures",
+ "rustc_errors",
"rustc_hir",
+ "rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
@@ -4530,12 +4119,6 @@ name = "rustc_tools_util"
version = "0.2.0"
[[package]]
-name = "rustc_tools_util"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b725dadae9fabc488df69a287f5a99c5eaf5d10853842a8a3dfac52476f544ee"
-
-[[package]]
name = "rustc_trait_selection"
version = "0.0.0"
dependencies = [
@@ -4585,6 +4168,7 @@ version = "0.1.0"
dependencies = [
"itertools",
"rustc_data_structures",
+ "rustc_hir",
"rustc_infer",
"rustc_macros",
"rustc_middle",
@@ -4602,6 +4186,7 @@ dependencies = [
"rustc_hir",
"rustc_index",
"rustc_infer",
+ "rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
@@ -4632,6 +4217,7 @@ dependencies = [
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
+ "rustc_feature",
"rustc_graphviz",
"rustc_hir",
"rustc_hir_pretty",
@@ -4679,6 +4265,7 @@ dependencies = [
"serde_json",
"smallvec",
"tempfile",
+ "thin-vec",
"tracing",
"tracing-subscriber",
"tracing-tree",
@@ -4729,7 +4316,7 @@ dependencies = [
name = "rustfmt-nightly"
version = "1.5.1"
dependencies = [
- "annotate-snippets 0.9.1",
+ "annotate-snippets",
"anyhow",
"bytecount",
"cargo_metadata 0.14.0",
@@ -4839,18 +4426,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.140"
+version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
+checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.140"
+version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
+checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
dependencies = [
"proc-macro2",
"quote",
@@ -4868,9 +4455,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.82"
+version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
+checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
dependencies = [
"indexmap",
"itoa",
@@ -4879,29 +4466,6 @@ dependencies = [
]
[[package]]
-name = "serde_repr"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "sha-1"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
-dependencies = [
- "block-buffer 0.7.3",
- "digest 0.8.1",
- "fake-simd",
- "opaque-debug",
-]
-
-[[package]]
name = "sha-1"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4909,7 +4473,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
- "digest 0.10.2",
+ "digest",
]
[[package]]
@@ -4920,7 +4484,7 @@ checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
- "digest 0.10.2",
+ "digest",
]
[[package]]
@@ -4945,15 +4509,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
[[package]]
-name = "signal-hook-registry"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "similar"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4995,9 +4550,9 @@ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e"
[[package]]
name = "snapbox"
-version = "0.2.9"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1f212b806d6f56d19838e36a0aaa7e79a0bc9ca177e873fb87651ad92f983e2"
+checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7"
dependencies = [
"concolor",
"content_inspector",
@@ -5013,9 +4568,9 @@ dependencies = [
[[package]]
name = "snapbox-macros"
-version = "0.2.1"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930"
+checksum = "8a253e6f894cfa440cba00600a249fa90869d8e0ec45ab274a456e043a0ce8f2"
[[package]]
name = "socket2"
@@ -5064,7 +4619,7 @@ dependencies = [
"dlmalloc",
"fortanix-sgx-abi",
"hashbrown",
- "hermit-abi 0.2.0",
+ "hermit-abi 0.2.6",
"libc",
"miniz_oxide 0.4.0",
"object 0.26.2",
@@ -5253,19 +4808,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
+name = "thin-vec"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "104c2cb3180b6fb6d5b2278768e9b88b578d32ba751ea6e8d026688a40d7ed87"
+
+[[package]]
name = "thiserror"
-version = "1.0.30"
+version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
+checksum = "3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.30"
+version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
+checksum = "c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09"
dependencies = [
"proc-macro2",
"quote",
@@ -5298,7 +4859,6 @@ name = "tidy"
version = "0.1.0"
dependencies = [
"cargo_metadata 0.14.0",
- "crossbeam-utils",
"lazy_static",
"regex",
"walkdir",
@@ -5338,39 +4898,8 @@ checksum = "50dae83881bc9b0403dd5b44ea9deed3e939856cc8722d5be37f0d6e5c6d53dd"
dependencies = [
"autocfg",
"bytes",
- "libc",
"memchr",
- "mio",
- "num_cpus",
- "once_cell",
"pin-project-lite",
- "signal-hook-registry",
- "winapi",
-]
-
-[[package]]
-name = "tokio-stream"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f"
-dependencies = [
- "futures-core",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "log",
- "pin-project-lite",
- "tokio",
]
[[package]]
@@ -5402,16 +4931,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa7c7f42dea4b1b99439786f5633aeb9c14c1b53f75e282803c2ec2ad545873c"
[[package]]
-name = "tower-service"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
-
-[[package]]
name = "tracing"
-version = "0.1.29"
+version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
+checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [
"cfg-if 1.0.0",
"pin-project-lite",
@@ -5421,9 +4944,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.18"
+version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
+checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
dependencies = [
"proc-macro2",
"quote",
@@ -5432,11 +4955,12 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.21"
+version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
+checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
- "lazy_static",
+ "once_cell",
+ "valuable",
]
[[package]]
@@ -5525,14 +5049,16 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "ui_test"
-version = "0.1.0"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d1f546a5883ae78da735bba529ec1116661e2f73582f23920d994dc97da3a22"
dependencies = [
"cargo_metadata 0.15.0",
"color-eyre",
"colored",
"crossbeam",
+ "diff",
"lazy_static",
- "pretty_assertions",
"regex",
"rustc_version",
"serde",
@@ -5732,25 +5258,14 @@ dependencies = [
[[package]]
name = "url"
-version = "1.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
-dependencies = [
- "idna 0.1.5",
- "matches",
- "percent-encoding 1.0.1",
-]
-
-[[package]]
-name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
- "idna 0.2.0",
+ "idna",
"matches",
- "percent-encoding 2.1.0",
+ "percent-encoding",
"serde",
]
@@ -5767,6 +5282,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
name = "vcpkg"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index ffc886d47..e49fe5e2f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,8 +33,10 @@ members = [
"src/tools/unicode-table-generator",
"src/tools/expand-yaml-anchors",
"src/tools/jsondocck",
+ "src/tools/jsondoclint",
"src/tools/html-checker",
"src/tools/bump-stage0",
+ "src/tools/replace-version-placeholder",
"src/tools/lld-wrapper",
]
@@ -96,21 +98,6 @@ gimli.debug = 0
miniz_oxide.debug = 0
object.debug = 0
-# We want the RLS to use the version of Cargo that we've got vendored in this
-# repository to ensure that the same exact version of Cargo is used by both the
-# RLS and the Cargo binary itself. The RLS depends on Cargo as a git repository
-# so we use a `[patch]` here to override the github repository with our local
-# vendored copy.
-[patch."https://github.com/rust-lang/cargo"]
-cargo = { path = "src/tools/cargo" }
-cargo-util = { path = "src/tools/cargo/crates/cargo-util" }
-
-[patch."https://github.com/rust-lang/rustfmt"]
-# Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
-# that we're shipping as well (to ensure that the rustfmt in RLS and the
-# `rustfmt` executable are the same exact version).
-rustfmt-nightly = { path = "src/tools/rustfmt" }
-
[patch.crates-io]
# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
# here
diff --git a/README.md b/README.md
index 7f601d5ee..27e7145c5 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ Read ["Installation"] from [The Book].
## Installing from Source
The Rust build system uses a Python script called `x.py` to build the compiler,
-which manages the bootstrapping process. It lives in the root of the project.
+which manages the bootstrapping process. It lives at the root of the project.
The `x.py` command can be run directly on most systems in the following format:
@@ -32,7 +32,7 @@ The `x.py` command can be run directly on most systems in the following format:
This is how the documentation and examples assume you are running `x.py`.
-Systems such as Ubuntu 20.04 LTS do not create the necessary `python` command by default when Python is installed that allows `x.py` to be run directly. In that case you can either create a symlink for `python` (Ubuntu provides the `python-is-python3` package for this), or run `x.py` using Python itself:
+Systems such as Ubuntu 20.04 LTS do not create the necessary `python` command by default when Python is installed that allows `x.py` to be run directly. In that case, you can either create a symlink for `python` (Ubuntu provides the `python-is-python3` package for this), or run `x.py` using Python itself:
```sh
# Python 3
@@ -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 an install directory if you are not installing in the default directory.
4. Build and install:
@@ -103,11 +103,10 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
### Building on Windows
There are two prominent ABIs in use on Windows: the native (MSVC) ABI used by
-Visual Studio, and the GNU ABI used by the GCC toolchain. Which version of Rust
-you need depends largely on what C/C++ libraries you want to interoperate with:
-for interop with software produced by Visual Studio use the MSVC build of Rust;
-for interop with GNU software built using the MinGW/MSYS2 toolchain use the GNU
-build.
+Visual Studio and the GNU ABI used by the GCC toolchain. Which version of Rust
+you need depends largely on what C/C++ libraries you want to interoperate with.
+Use the MSVC build of Rust to interop with software produced by Visual Studio and
+the GNU build to interop with GNU software built using the MinGW/MSYS2 toolchain.
#### MinGW
@@ -115,10 +114,10 @@ build.
[msys2]: https://www.msys2.org/
-1. Grab the latest [MSYS2 installer][msys2] and go through the installer.
+1. Download the latest [MSYS2 installer][msys2] and go through the installer.
-2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
- MSYS2 (i.e. `C:\msys64`), depending on whether you want 32-bit or 64-bit
+2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from the MSYS2 installation
+ directory (e.g. `C:\msys64`), depending on whether you want 32-bit or 64-bit
Rust. (As of the latest version of MSYS2 you have to run `msys2_shell.cmd
-mingw32` or `msys2_shell.cmd -mingw64` from the command line instead)
@@ -153,7 +152,7 @@ build.
#### MSVC
MSVC builds of Rust additionally require an installation of Visual Studio 2017
-(or later) so `rustc` can use its linker. The simplest way is to get the
+(or later) so `rustc` can use its linker. The simplest way is to get
[Visual Studio], check the “C++ build tools†and “Windows 10 SDK†workload.
[Visual Studio]: https://visualstudio.microsoft.com/downloads/
@@ -168,7 +167,7 @@ shell with:
python x.py build
```
-Currently, building Rust only works with some known versions of Visual Studio. If
+Right now, building Rust only works with some known versions of Visual Studio. If
you have a more recent version installed and the build system doesn't understand,
you may need to force rustbuild to use an older version. This can be done
by manually calling the appropriate vcvars file before running the bootstrap.
@@ -225,7 +224,7 @@ the ABI used. I.e., if the ABI was `x86_64-pc-windows-msvc`, the directory will
Since the Rust compiler is written in Rust, it must be built by a
precompiled "snapshot" version of itself (made in an earlier stage of
-development). As such, source builds require a connection to the Internet, to
+development). As such, source builds require an Internet connection to
fetch snapshots, and an OS that can execute the available snapshot binaries.
Snapshot binaries are currently built and tested on several platforms:
diff --git a/RELEASES.md b/RELEASES.md
index 694bd0965..a3df56f1d 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,106 @@
+Version 1.65.0 (2022-11-03)
+==========================
+
+Language
+--------
+- [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/)
+- [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/)
+- [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/)
+- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/)
+- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/)
+- [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/).
+ Usage of `MaybeUninit` is the correct way to work with uninitialized memory.
+- [Stabilize raw-dylib for Windows x86_64, aarch64, and thumbv7a](https://github.com/rust-lang/rust/pull/99916/)
+- [Do not allow `Drop` impl on foreign ADTs](https://github.com/rust-lang/rust/pull/99576/)
+
+Compiler
+--------
+- [Stabilize -Csplit-debuginfo on Linux](https://github.com/rust-lang/rust/pull/98051/)
+- [Use niche-filling optimization even when multiple variants have data](https://github.com/rust-lang/rust/pull/94075/)
+- [Associated type projections are now verified to be well-formed prior to resolving the underlying type](https://github.com/rust-lang/rust/pull/99217/#issuecomment-1209365630)
+- [Stringify non-shorthand visibility correctly](https://github.com/rust-lang/rust/pull/100350/)
+- [Normalize struct field types when unsizing](https://github.com/rust-lang/rust/pull/101831/)
+- [Update to LLVM 15](https://github.com/rust-lang/rust/pull/99464/)
+- [Fix aarch64 call abi to correctly zeroext when needed](https://github.com/rust-lang/rust/pull/97800/)
+- [debuginfo: Generalize C++-like encoding for enums](https://github.com/rust-lang/rust/pull/98393/)
+- [Add `special_module_name` lint](https://github.com/rust-lang/rust/pull/94467/)
+- [Add support for generating unique profraw files by default when using `-C instrument-coverage`](https://github.com/rust-lang/rust/pull/100384/)
+- [Allow dynamic linking for iOS/tvOS targets](https://github.com/rust-lang/rust/pull/100636/)
+
+New targets:
+
+- [Add armv4t-none-eabi as a tier 3 target](https://github.com/rust-lang/rust/pull/100244/)
+- [Add powerpc64-unknown-openbsd and riscv64-unknown-openbsd as tier 3 targets](https://github.com/rust-lang/rust/pull/101025/)
+ - Refer to Rust's [platform support page][platform-support-doc] for more
+ information on Rust's tiered platform support.
+
+Libraries
+---------
+
+- [Don't generate `PartialEq::ne` in derive(PartialEq)](https://github.com/rust-lang/rust/pull/98655/)
+- [Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default](https://github.com/rust-lang/rust/pull/101325/)
+- [Forbid mixing `System` with direct system allocator calls](https://github.com/rust-lang/rust/pull/101394/)
+- [Document no support for writing to non-blocking stdio/stderr](https://github.com/rust-lang/rust/pull/101416/)
+- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295)
+ This also changes the safety conditions on `Layout::from_size_align_unchecked`.
+
+Stabilized APIs
+---------------
+
+- [`std::backtrace::Backtrace`](https://doc.rust-lang.org/stable/std/backtrace/struct.Backtrace.html)
+- [`Bound::as_ref`](https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.as_ref)
+- [`std::io::read_to_string`](https://doc.rust-lang.org/stable/std/io/fn.read_to_string.html)
+- [`<*const T>::cast_mut`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut)
+- [`<*mut T>::cast_const`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const)
+
+These APIs are now stable in const contexts:
+
+- [`<*const T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
+- [`<*mut T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
+
+Cargo
+-----
+
+- [Apply GitHub fast path even for partial hashes](https://github.com/rust-lang/cargo/pull/10807/)
+- [Do not add home bin path to PATH if it's already there](https://github.com/rust-lang/cargo/pull/11023/)
+- [Take priority into account within the pending queue](https://github.com/rust-lang/cargo/pull/11032/).
+ This slightly optimizes job scheduling by Cargo, with typically small improvements on larger crate graph builds.
+
+Compatibility Notes
+-------------------
+
+- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295).
+ This also changes the safety conditions on `Layout::from_size_align_unchecked`.
+- [`PollFn` now only implements `Unpin` if the closure is `Unpin`](https://github.com/rust-lang/rust/pull/102737).
+ This is a possible breaking change if users were relying on the blanket unpin implementation.
+ See discussion on the PR for details of why this change was made.
+- [Drop ExactSizeIterator impl from std::char::EscapeAscii](https://github.com/rust-lang/rust/pull/99880)
+ This is a backwards-incompatible change to the standard library's surface
+ area, but is unlikely to affect real world usage.
+- [Do not consider a single repeated lifetime eligible for elision in the return type](https://github.com/rust-lang/rust/pull/103450)
+ This behavior was unintentionally changed in 1.64.0, and this release reverts that change by making this an error again.
+- [Reenable disabled early syntax gates as future-incompatibility lints](https://github.com/rust-lang/rust/pull/99935/)
+- [Update the minimum external LLVM to 13](https://github.com/rust-lang/rust/pull/100460/)
+- [Don't duplicate file descriptors into stdio fds](https://github.com/rust-lang/rust/pull/101426/)
+- [Sunset RLS](https://github.com/rust-lang/rust/pull/100863/)
+- [Deny usage of `#![cfg_attr(..., crate_type = ...)]` to set the crate type](https://github.com/rust-lang/rust/pull/99784/)
+ This strengthens the forward compatibility lint deprecated_cfg_attr_crate_type_name to deny.
+- [`llvm-has-rust-patches` allows setting the build system to treat the LLVM as having Rust-specific patches](https://github.com/rust-lang/rust/pull/101072)
+ This option may need to be set for distributions that are building Rust with a patched LLVM via `llvm-config`, not the built-in LLVM.
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Add `x.sh` and `x.ps1` shell scripts](https://github.com/rust-lang/rust/pull/99992/)
+- [compiletest: use target cfg instead of hard-coded tables](https://github.com/rust-lang/rust/pull/100260/)
+- [Use object instead of LLVM for reading bitcode from rlibs](https://github.com/rust-lang/rust/pull/98100/)
+- [Enable MIR inlining for optimized compilations](https://github.com/rust-lang/rust/pull/91743)
+ This provides a 3-10% improvement in compiletimes for real world crates. See [perf results](https://perf.rust-lang.org/compare.html?start=aedf78e56b2279cc869962feac5153b6ba7001ed&end=0075bb4fad68e64b6d1be06bf2db366c30bc75e1&stat=instructions:u).
+
Version 1.64.0 (2022-09-22)
===========================
diff --git a/compiler/rustc_apfloat/src/lib.rs b/compiler/rustc_apfloat/src/lib.rs
index cfc3d5b15..dde368e7b 100644
--- a/compiler/rustc_apfloat/src/lib.rs
+++ b/compiler/rustc_apfloat/src/lib.rs
@@ -33,6 +33,8 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![no_std]
#![forbid(unsafe_code)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate alloc;
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index a5f1cbc96..46dbbd83d 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -16,10 +16,12 @@
#![feature(maybe_uninit_slice)]
#![feature(min_specialization)]
#![feature(decl_macro)]
+#![feature(pointer_byte_offsets)]
#![feature(rustc_attrs)]
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]
-#![feature(ptr_const_cast)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
use smallvec::SmallVec;
@@ -210,7 +212,7 @@ impl<T> TypedArena<T> {
unsafe {
if mem::size_of::<T>() == 0 {
- self.ptr.set((self.ptr.get() as *mut u8).wrapping_offset(1) as *mut T);
+ self.ptr.set(self.ptr.get().wrapping_byte_add(1));
let ptr = ptr::NonNull::<T>::dangling().as_ptr();
// Don't drop the object. This `write` is equivalent to `forget`.
ptr::write(ptr, object);
@@ -218,7 +220,7 @@ impl<T> TypedArena<T> {
} else {
let ptr = self.ptr.get();
// Advance the pointer.
- self.ptr.set(self.ptr.get().offset(1));
+ self.ptr.set(self.ptr.get().add(1));
// Write into uninitialized memory.
ptr::write(ptr, object);
&mut *ptr
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml
index 9822e9864..c24180bac 100644
--- a/compiler/rustc_ast/Cargo.toml
+++ b/compiler/rustc_ast/Cargo.toml
@@ -7,12 +7,13 @@ edition = "2021"
doctest = false
[dependencies]
-rustc_serialize = { path = "../rustc_serialize" }
-tracing = "0.1"
-rustc_span = { path = "../rustc_span" }
+bitflags = "1.2.1"
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_index = { path = "../rustc_index" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-bitflags = "1.2.1"
+thin-vec = "0.2.8"
+tracing = "0.1"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 870a7c0be..d86db8f8b 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -24,22 +24,19 @@ pub use UnsafeSource::*;
use crate::ptr::P;
use crate::token::{self, CommentKind, Delimiter};
-use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream};
-
+use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, 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::{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};
-
-use std::cmp::Ordering;
use std::convert::TryFrom;
use std::fmt;
use std::mem;
+use thin_vec::ThinVec;
/// A "Label" is an identifier of some point in sources,
/// e.g. in the following code:
@@ -94,7 +91,7 @@ pub struct Path {
/// The segments in the path: the things separated by `::`.
/// Global paths begin with `kw::PathRoot`.
pub segments: Vec<PathSegment>,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
impl PartialEq<Symbol> for Path {
@@ -326,46 +323,17 @@ pub type GenericBounds = Vec<GenericBound>;
/// Specifies the enforced ordering for generic parameters. In the future,
/// if we wanted to relax this order, we could override `PartialEq` and
/// `PartialOrd`, to allow the kinds to be unordered.
-#[derive(Hash, Clone, Copy)]
+#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum ParamKindOrd {
Lifetime,
- Type,
- Const,
- // `Infer` is not actually constructed directly from the AST, but is implicitly constructed
- // during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
- Infer,
-}
-
-impl Ord for ParamKindOrd {
- fn cmp(&self, other: &Self) -> Ordering {
- use ParamKindOrd::*;
- let to_int = |v| match v {
- Lifetime => 0,
- Infer | Type | Const => 1,
- };
-
- to_int(*self).cmp(&to_int(*other))
- }
-}
-impl PartialOrd for ParamKindOrd {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
+ TypeOrConst,
}
-impl PartialEq for ParamKindOrd {
- fn eq(&self, other: &Self) -> bool {
- self.cmp(other) == Ordering::Equal
- }
-}
-impl Eq for ParamKindOrd {}
impl fmt::Display for ParamKindOrd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ParamKindOrd::Lifetime => "lifetime".fmt(f),
- ParamKindOrd::Type => "type".fmt(f),
- ParamKindOrd::Const { .. } => "const".fmt(f),
- ParamKindOrd::Infer => "infer".fmt(f),
+ ParamKindOrd::TypeOrConst => "type and const".fmt(f),
}
}
}
@@ -497,7 +465,6 @@ pub struct WhereRegionPredicate {
/// E.g., `T = int`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereEqPredicate {
- pub id: NodeId,
pub span: Span,
pub lhs_ty: P<Ty>,
pub rhs_ty: P<Ty>,
@@ -505,7 +472,7 @@ pub struct WhereEqPredicate {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Crate {
- pub attrs: Vec<Attribute>,
+ pub attrs: AttrVec,
pub items: Vec<P<Item>>,
pub spans: ModSpans,
/// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
@@ -567,7 +534,7 @@ pub struct Block {
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
pub rules: BlockCheckMode,
pub span: Span,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
/// The following *isn't* a parse error, but will cause multiple errors in following stages.
/// ```compile_fail
/// let x = {
@@ -586,7 +553,7 @@ pub struct Pat {
pub id: NodeId,
pub kind: PatKind,
pub span: Span,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
impl Pat {
@@ -597,7 +564,7 @@ impl Pat {
// In a type expression `_` is an inference variable.
PatKind::Wild => TyKind::Infer,
// An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
- PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => {
+ PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
TyKind::Path(None, Path::from_ident(*ident))
}
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
@@ -684,10 +651,43 @@ pub struct PatField {
pub is_placeholder: bool,
}
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
-pub enum BindingMode {
- ByRef(Mutability),
- ByValue(Mutability),
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
+pub enum ByRef {
+ Yes,
+ No,
+}
+
+impl From<bool> for ByRef {
+ fn from(b: bool) -> ByRef {
+ match b {
+ false => ByRef::No,
+ true => ByRef::Yes,
+ }
+ }
+}
+
+/// Explicit binding annotations given in the HIR for a binding. Note
+/// that this is not the final binding *mode* that we infer after type
+/// inference.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
+pub struct BindingAnnotation(pub ByRef, pub Mutability);
+
+impl BindingAnnotation {
+ pub const NONE: Self = Self(ByRef::No, Mutability::Not);
+ pub const REF: Self = Self(ByRef::Yes, Mutability::Not);
+ pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
+ pub const REF_MUT: Self = Self(ByRef::Yes, Mutability::Mut);
+
+ pub fn prefix_str(self) -> &'static str {
+ match self {
+ Self::NONE => "",
+ Self::REF => "ref ",
+ Self::MUT => "mut ",
+ Self::REF_MUT => "ref mut ",
+ }
+ }
}
#[derive(Clone, Encodable, Decodable, Debug)]
@@ -716,7 +716,7 @@ pub enum PatKind {
/// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
/// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
/// during name resolution.
- Ident(BindingMode, Ident, Option<P<Pat>>),
+ Ident(BindingAnnotation, Ident, Option<P<Pat>>),
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
@@ -771,7 +771,7 @@ pub enum PatKind {
Paren(P<Pat>),
/// A macro pattern; pre-expansion.
- MacCall(MacCall),
+ MacCall(P<MacCall>),
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
@@ -937,8 +937,8 @@ impl Stmt {
/// a trailing semicolon.
///
/// This only modifies the parsed AST struct, not the attached
- /// `LazyTokenStream`. The parser is responsible for calling
- /// `CreateTokenStream::add_trailing_semi` when there is actually
+ /// `LazyAttrTokenStream`. The parser is responsible for calling
+ /// `ToAttrTokenStream::add_trailing_semi` when there is actually
/// a semicolon in the tokenstream.
pub fn add_trailing_semicolon(mut self) -> Self {
self.kind = match self.kind {
@@ -981,10 +981,10 @@ pub enum StmtKind {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MacCallStmt {
- pub mac: MacCall,
+ pub mac: P<MacCall>,
pub style: MacStmtStyle,
pub attrs: AttrVec,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
@@ -1009,7 +1009,7 @@ pub struct Local {
pub kind: LocalKind,
pub span: Span,
pub attrs: AttrVec,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
@@ -1108,7 +1108,7 @@ pub struct Expr {
pub kind: ExprKind,
pub span: Span,
pub attrs: AttrVec,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
impl Expr {
@@ -1269,7 +1269,7 @@ impl Expr {
id: DUMMY_NODE_ID,
kind: ExprKind::Err,
span: DUMMY_SP,
- attrs: ThinVec::new(),
+ attrs: AttrVec::new(),
tokens: None,
},
)
@@ -1439,7 +1439,7 @@ pub enum ExprKind {
InlineAsm(P<InlineAsm>),
/// A macro invocation; pre-expansion.
- MacCall(MacCall),
+ MacCall(P<MacCall>),
/// A struct literal expression.
///
@@ -1691,7 +1691,7 @@ pub enum StrStyle {
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct Lit {
/// The original literal token as written in source code.
- pub token: token::Lit,
+ pub token_lit: token::Lit,
/// The "semantic" representation of the literal lowered from the original tokens.
/// Strings are unescaped, hexadecimal forms are eliminated, etc.
/// FIXME: Remove this and only create the semantic representation during lowering to HIR.
@@ -1719,7 +1719,7 @@ impl StrLit {
StrStyle::Raw(n) => token::StrRaw(n),
};
Lit {
- token: token::Lit::new(token_kind, self.symbol, self.suffix),
+ token_lit: token::Lit::new(token_kind, self.symbol, self.suffix),
span: self.span,
kind: LitKind::Str(self.symbol_unescaped, self.style),
}
@@ -1753,7 +1753,8 @@ pub enum LitFloatType {
/// E.g., `"foo"`, `42`, `12.34`, or `bool`.
#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
pub enum LitKind {
- /// A string literal (`"foo"`).
+ /// A string literal (`"foo"`). The symbol is unescaped, and so may differ
+ /// from the original token's symbol.
Str(Symbol, StrStyle),
/// A byte string (`b"foo"`).
ByteStr(Lrc<[u8]>),
@@ -1763,12 +1764,13 @@ pub enum LitKind {
Char(char),
/// An integer literal (`1`).
Int(u128, LitIntType),
- /// A float literal (`1f64` or `1E10f64`).
+ /// A float literal (`1f64` or `1E10f64`). Stored as a symbol rather than
+ /// `f64` so that `LitKind` can impl `Eq` and `Hash`.
Float(Symbol, LitFloatType),
/// A boolean literal.
Bool(bool),
/// Placeholder for a literal that wasn't well-formed in some way.
- Err(Symbol),
+ Err,
}
impl LitKind {
@@ -1807,7 +1809,7 @@ impl LitKind {
| LitKind::Int(_, LitIntType::Unsuffixed)
| LitKind::Float(_, LitFloatType::Unsuffixed)
| LitKind::Bool(..)
- | LitKind::Err(..) => false,
+ | LitKind::Err => false,
}
}
}
@@ -1966,7 +1968,7 @@ pub struct Ty {
pub id: NodeId,
pub kind: TyKind,
pub span: Span,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
impl Clone for Ty {
@@ -2042,7 +2044,7 @@ pub enum TyKind {
/// Inferred type of a `self` or `&self` argument in a method.
ImplicitSelf,
/// A macro in the type position.
- MacCall(MacCall),
+ MacCall(P<MacCall>),
/// Placeholder for a kind that has failed to be defined.
Err,
/// Placeholder for a `va_list`.
@@ -2059,8 +2061,11 @@ impl TyKind {
}
pub fn is_simple_path(&self) -> Option<Symbol> {
- if let TyKind::Path(None, Path { segments, .. }) = &self && segments.len() == 1 {
- Some(segments[0].ident.name)
+ if let TyKind::Path(None, Path { segments, .. }) = &self
+ && let [segment] = &segments[..]
+ && segment.args.is_none()
+ {
+ Some(segment.ident.name)
} else {
None
}
@@ -2071,6 +2076,7 @@ impl TyKind {
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum TraitObjectSyntax {
Dyn,
+ DynStar,
None,
}
@@ -2086,15 +2092,15 @@ pub enum InlineAsmRegOrRegClass {
bitflags::bitflags! {
#[derive(Encodable, Decodable, HashStable_Generic)]
pub struct InlineAsmOptions: u16 {
- const PURE = 1 << 0;
- const NOMEM = 1 << 1;
- const READONLY = 1 << 2;
+ const PURE = 1 << 0;
+ const NOMEM = 1 << 1;
+ const READONLY = 1 << 2;
const PRESERVES_FLAGS = 1 << 3;
- const NORETURN = 1 << 4;
- const NOSTACK = 1 << 5;
- const ATT_SYNTAX = 1 << 6;
- const RAW = 1 << 7;
- const MAY_UNWIND = 1 << 8;
+ const NORETURN = 1 << 4;
+ const NOSTACK = 1 << 5;
+ const ATT_SYNTAX = 1 << 6;
+ const RAW = 1 << 7;
+ const MAY_UNWIND = 1 << 8;
}
}
@@ -2230,7 +2236,7 @@ pub type ExplicitSelf = Spanned<SelfKind>;
impl Param {
/// Attempts to cast parameter to `ExplicitSelf`.
pub fn to_self(&self) -> Option<ExplicitSelf> {
- if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind {
+ if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), ident, _) = self.pat.kind {
if ident.name == kw::SelfLower {
return match self.ty.kind {
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
@@ -2260,11 +2266,24 @@ impl Param {
pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
let span = eself.span.to(eself_ident.span);
let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span, tokens: None });
- let param = |mutbl, ty| Param {
+ let (mutbl, ty) = match eself.node {
+ SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
+ SelfKind::Value(mutbl) => (mutbl, infer_ty),
+ SelfKind::Region(lt, mutbl) => (
+ Mutability::Not,
+ P(Ty {
+ id: DUMMY_NODE_ID,
+ kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }),
+ span,
+ tokens: None,
+ }),
+ ),
+ };
+ Param {
attrs,
pat: P(Pat {
id: DUMMY_NODE_ID,
- kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
+ kind: PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), eself_ident, None),
span,
tokens: None,
}),
@@ -2272,19 +2291,6 @@ impl Param {
ty,
id: DUMMY_NODE_ID,
is_placeholder: false,
- };
- match eself.node {
- SelfKind::Explicit(ty, mutbl) => param(mutbl, ty),
- SelfKind::Value(mutbl) => param(mutbl, infer_ty),
- SelfKind::Region(lt, mutbl) => param(
- Mutability::Not,
- P(Ty {
- id: DUMMY_NODE_ID,
- kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }),
- span,
- tokens: None,
- }),
- ),
}
}
}
@@ -2336,9 +2342,9 @@ impl Async {
}
/// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
- pub fn opt_return_id(self) -> Option<NodeId> {
+ pub fn opt_return_id(self) -> Option<(NodeId, Span)> {
match self {
- Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id),
+ Async::Yes { return_impl_trait_id, span, .. } => Some((return_impl_trait_id, span)),
Async::No => None,
}
}
@@ -2522,8 +2528,8 @@ impl<S: Encoder> Encodable<S> for AttrId {
}
impl<D: Decoder> Decodable<D> for AttrId {
- fn decode(_: &mut D) -> AttrId {
- crate::attr::mk_attr_id()
+ default fn decode(_: &mut D) -> AttrId {
+ panic!("cannot decode `AttrId` with `{}`", std::any::type_name::<D>());
}
}
@@ -2531,7 +2537,7 @@ impl<D: Decoder> Decodable<D> for AttrId {
pub struct AttrItem {
pub path: Path,
pub args: MacArgs,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
/// A list of attributes.
@@ -2549,9 +2555,15 @@ pub struct Attribute {
}
#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct NormalAttr {
+ pub item: AttrItem,
+ pub tokens: Option<LazyAttrTokenStream>,
+}
+
+#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AttrKind {
/// A normal attribute.
- Normal(AttrItem, Option<LazyTokenStream>),
+ Normal(P<NormalAttr>),
/// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
/// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
@@ -2596,13 +2608,13 @@ impl PolyTraitRef {
pub struct Visibility {
pub kind: VisibilityKind,
pub span: Span,
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum VisibilityKind {
Public,
- Restricted { path: P<Path>, id: NodeId },
+ Restricted { path: P<Path>, id: NodeId, shorthand: bool },
Inherited,
}
@@ -2665,7 +2677,7 @@ impl VariantData {
/// An item definition.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Item<K = ItemKind> {
- pub attrs: Vec<Attribute>,
+ pub attrs: AttrVec,
pub id: NodeId,
pub span: Span,
pub vis: Visibility,
@@ -2682,7 +2694,7 @@ pub struct Item<K = ItemKind> {
///
/// Note that the tokens here do not include the outer attributes, but will
/// include inner attributes.
- pub tokens: Option<LazyTokenStream>,
+ pub tokens: Option<LazyAttrTokenStream>,
}
impl Item {
@@ -2873,7 +2885,7 @@ pub enum ItemKind {
/// A macro invocation.
///
/// E.g., `foo!(..)`.
- MacCall(MacCall),
+ MacCall(P<MacCall>),
/// A macro definition.
MacroDef(MacroDef),
@@ -2947,7 +2959,7 @@ pub enum AssocItemKind {
/// An associated type.
TyAlias(Box<TyAlias>),
/// A macro expanding to associated items.
- MacCall(MacCall),
+ MacCall(P<MacCall>),
}
impl AssocItemKind {
@@ -2996,7 +3008,7 @@ pub enum ForeignItemKind {
/// An foreign type.
TyAlias(Box<TyAlias>),
/// A macro expanding to foreign items.
- MacCall(MacCall),
+ MacCall(P<MacCall>),
}
impl From<ForeignItemKind> for ItemKind {
@@ -3030,22 +3042,34 @@ pub type ForeignItem = Item<ForeignItemKind>;
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
+ use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
- rustc_data_structures::static_assert_size!(AssocItemKind, 72);
- rustc_data_structures::static_assert_size!(Attribute, 152);
- rustc_data_structures::static_assert_size!(Block, 48);
- rustc_data_structures::static_assert_size!(Expr, 104);
- rustc_data_structures::static_assert_size!(Fn, 192);
- rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
- rustc_data_structures::static_assert_size!(GenericBound, 88);
- rustc_data_structures::static_assert_size!(Generics, 72);
- rustc_data_structures::static_assert_size!(Impl, 200);
- rustc_data_structures::static_assert_size!(Item, 200);
- rustc_data_structures::static_assert_size!(ItemKind, 112);
- rustc_data_structures::static_assert_size!(Lit, 48);
- rustc_data_structures::static_assert_size!(Pat, 120);
- rustc_data_structures::static_assert_size!(Path, 40);
- rustc_data_structures::static_assert_size!(PathSegment, 24);
- rustc_data_structures::static_assert_size!(Stmt, 32);
- rustc_data_structures::static_assert_size!(Ty, 96);
+ static_assert_size!(AssocItem, 104);
+ static_assert_size!(AssocItemKind, 32);
+ static_assert_size!(Attribute, 32);
+ static_assert_size!(Block, 48);
+ static_assert_size!(Expr, 104);
+ static_assert_size!(ExprKind, 72);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(Fn, 184);
+ static_assert_size!(ForeignItem, 96);
+ static_assert_size!(ForeignItemKind, 24);
+ static_assert_size!(GenericArg, 24);
+ static_assert_size!(GenericBound, 88);
+ static_assert_size!(Generics, 72);
+ static_assert_size!(Impl, 200);
+ static_assert_size!(Item, 184);
+ static_assert_size!(ItemKind, 112);
+ static_assert_size!(Lit, 48);
+ static_assert_size!(LitKind, 24);
+ static_assert_size!(Local, 72);
+ static_assert_size!(Param, 40);
+ static_assert_size!(Pat, 120);
+ static_assert_size!(PatKind, 96);
+ static_assert_size!(Path, 40);
+ static_assert_size!(PathSegment, 24);
+ static_assert_size!(Stmt, 32);
+ static_assert_size!(StmtKind, 16);
+ static_assert_size!(Ty, 96);
+ static_assert_size!(TyKind, 72);
}
diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs
index 5c30a75a1..1b31be07f 100644
--- a/compiler/rustc_ast/src/ast_traits.rs
+++ b/compiler/rustc_ast/src/ast_traits.rs
@@ -4,7 +4,7 @@
use crate::ptr::P;
use crate::token::Nonterminal;
-use crate::tokenstream::LazyTokenStream;
+use crate::tokenstream::LazyAttrTokenStream;
use crate::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant};
use crate::{AssocItem, Expr, ForeignItem, Item, NodeId};
use crate::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
@@ -124,18 +124,18 @@ impl HasSpan for AttrItem {
/// A trait for AST nodes having (or not having) collected tokens.
pub trait HasTokens {
- fn tokens(&self) -> Option<&LazyTokenStream>;
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>>;
+ fn tokens(&self) -> Option<&LazyAttrTokenStream>;
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>>;
}
macro_rules! impl_has_tokens {
($($T:ty),+ $(,)?) => {
$(
impl HasTokens for $T {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
self.tokens.as_ref()
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
Some(&mut self.tokens)
}
}
@@ -147,10 +147,10 @@ macro_rules! impl_has_tokens_none {
($($T:ty),+ $(,)?) => {
$(
impl HasTokens for $T {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
None
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
None
}
}
@@ -162,25 +162,25 @@ impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path,
impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant);
impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
self.ast_deref().tokens()
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
self.ast_deref_mut().tokens_mut()
}
}
impl<T: HasTokens> HasTokens for Option<T> {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
self.as_ref().and_then(|inner| inner.tokens())
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
self.as_mut().and_then(|inner| inner.tokens_mut())
}
}
impl HasTokens for StmtKind {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
match self {
StmtKind::Local(local) => local.tokens.as_ref(),
StmtKind::Item(item) => item.tokens(),
@@ -189,7 +189,7 @@ impl HasTokens for StmtKind {
StmtKind::MacCall(mac) => mac.tokens.as_ref(),
}
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
match self {
StmtKind::Local(local) => Some(&mut local.tokens),
StmtKind::Item(item) => item.tokens_mut(),
@@ -201,26 +201,26 @@ impl HasTokens for StmtKind {
}
impl HasTokens for Stmt {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
self.kind.tokens()
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
self.kind.tokens_mut()
}
}
impl HasTokens for Attribute {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
match &self.kind {
- AttrKind::Normal(_, tokens) => tokens.as_ref(),
+ AttrKind::Normal(normal) => normal.tokens.as_ref(),
kind @ AttrKind::DocComment(..) => {
panic!("Called tokens on doc comment attr {:?}", kind)
}
}
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
Some(match &mut self.kind {
- AttrKind::Normal(_, tokens) => tokens,
+ AttrKind::Normal(normal) => &mut normal.tokens,
kind @ AttrKind::DocComment(..) => {
panic!("Called tokens_mut on doc comment attr {:?}", kind)
}
@@ -229,7 +229,7 @@ impl HasTokens for Attribute {
}
impl HasTokens for Nonterminal {
- fn tokens(&self) -> Option<&LazyTokenStream> {
+ fn tokens(&self) -> Option<&LazyAttrTokenStream> {
match self {
Nonterminal::NtItem(item) => item.tokens(),
Nonterminal::NtStmt(stmt) => stmt.tokens(),
@@ -243,7 +243,7 @@ impl HasTokens for Nonterminal {
Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None,
}
}
- fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
+ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
match self {
Nonterminal::NtItem(item) => item.tokens_mut(),
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
@@ -270,7 +270,7 @@ pub trait HasAttrs {
/// during token collection.
const SUPPORTS_CUSTOM_INNER_ATTRS: bool;
fn attrs(&self) -> &[Attribute];
- fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
+ fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec));
}
macro_rules! impl_has_attrs {
@@ -279,12 +279,13 @@ macro_rules! impl_has_attrs {
impl HasAttrs for $T {
const SUPPORTS_CUSTOM_INNER_ATTRS: bool = $inner;
+ #[inline]
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
- fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
- VecOrAttrVec::visit(&mut self.attrs, f)
+ fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
+ f(&mut self.attrs)
}
}
)+
@@ -299,7 +300,7 @@ macro_rules! impl_has_attrs_none {
fn attrs(&self) -> &[Attribute] {
&[]
}
- fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {}
+ fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {}
}
)+
};
@@ -330,7 +331,7 @@ impl<T: AstDeref<Target: HasAttrs>> HasAttrs for T {
fn attrs(&self) -> &[Attribute] {
self.ast_deref().attrs()
}
- fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
+ fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
self.ast_deref_mut().visit_attrs(f)
}
}
@@ -340,7 +341,7 @@ impl<T: HasAttrs> HasAttrs for Option<T> {
fn attrs(&self) -> &[Attribute] {
self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[])
}
- fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
+ fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
if let Some(inner) = self.as_mut() {
inner.visit_attrs(f);
}
@@ -362,13 +363,13 @@ impl HasAttrs for StmtKind {
}
}
- fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
+ fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
match self {
- StmtKind::Local(local) => visit_attrvec(&mut local.attrs, f),
+ StmtKind::Local(local) => f(&mut local.attrs),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
StmtKind::Item(item) => item.visit_attrs(f),
StmtKind::Empty => {}
- StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f),
+ StmtKind::MacCall(mac) => f(&mut mac.attrs),
}
}
}
@@ -378,38 +379,11 @@ impl HasAttrs for Stmt {
fn attrs(&self) -> &[Attribute] {
self.kind.attrs()
}
- fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
+ fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
self.kind.visit_attrs(f);
}
}
-/// Helper trait for the impls above. Abstracts over
-/// the two types of attribute fields that AST nodes
-/// may have (`Vec<Attribute>` or `AttrVec`).
-trait VecOrAttrVec {
- fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
-}
-
-impl VecOrAttrVec for Vec<Attribute> {
- fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
- f(self)
- }
-}
-
-impl VecOrAttrVec for AttrVec {
- fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
- visit_attrvec(self, f)
- }
-}
-
-fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec<Attribute>)) {
- crate::mut_visit::visit_clobber(attrs, |attrs| {
- let mut vec = attrs.into();
- f(&mut vec);
- vec.into()
- });
-}
-
/// A newtype around an AST node that implements the traits above if the node implements them.
pub struct AstNodeWrapper<Wrapped, Tag> {
pub wrapped: Wrapped,
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 86af7769d..990f4f8f1 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -7,18 +7,22 @@ use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, Neste
use crate::ast::{Path, PathSegment};
use crate::ptr::P;
use crate::token::{self, CommentKind, Delimiter, Token};
-use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
-use crate::tokenstream::{LazyTokenStream, TokenStream};
+use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
use crate::util::comments;
-use rustc_data_structures::thin_vec::ThinVec;
+use rustc_data_structures::sync::WorkerLocal;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
+use std::cell::Cell;
use std::iter;
+#[cfg(debug_assertions)]
+use std::ops::BitXor;
+#[cfg(debug_assertions)]
+use std::sync::atomic::{AtomicU32, Ordering};
pub struct MarkedAttrs(GrowableBitSet<AttrId>);
@@ -114,7 +118,7 @@ impl Attribute {
#[inline]
pub fn has_name(&self, name: Symbol) -> bool {
match self.kind {
- AttrKind::Normal(ref item, _) => item.path == name,
+ AttrKind::Normal(ref normal) => normal.item.path == name,
AttrKind::DocComment(..) => false,
}
}
@@ -122,9 +126,9 @@ impl Attribute {
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
pub fn ident(&self) -> Option<Ident> {
match self.kind {
- AttrKind::Normal(ref item, _) => {
- if item.path.segments.len() == 1 {
- Some(item.path.segments[0].ident)
+ AttrKind::Normal(ref normal) => {
+ if normal.item.path.segments.len() == 1 {
+ Some(normal.item.path.segments[0].ident)
} else {
None
}
@@ -138,14 +142,16 @@ impl Attribute {
pub fn value_str(&self) -> Option<Symbol> {
match self.kind {
- AttrKind::Normal(ref item, _) => item.meta_kind().and_then(|kind| kind.value_str()),
+ AttrKind::Normal(ref normal) => {
+ normal.item.meta_kind().and_then(|kind| kind.value_str())
+ }
AttrKind::DocComment(..) => None,
}
}
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
match self.kind {
- AttrKind::Normal(ref item, _) => match item.meta_kind() {
+ AttrKind::Normal(ref normal) => match normal.item.meta_kind() {
Some(MetaItemKind::List(list)) => Some(list),
_ => None,
},
@@ -154,8 +160,8 @@ impl Attribute {
}
pub fn is_word(&self) -> bool {
- if let AttrKind::Normal(item, _) = &self.kind {
- matches!(item.args, MacArgs::Empty)
+ if let AttrKind::Normal(normal) = &self.kind {
+ matches!(normal.item.args, MacArgs::Empty)
} else {
false
}
@@ -182,13 +188,7 @@ impl MetaItem {
}
pub fn value_str(&self) -> Option<Symbol> {
- match self.kind {
- MetaItemKind::NameValue(ref v) => match v.kind {
- LitKind::Str(ref s, _) => Some(*s),
- _ => None,
- },
- _ => None,
- }
+ self.kind.value_str()
}
pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
@@ -237,6 +237,9 @@ impl AttrItem {
}
impl Attribute {
+ /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example).
+ /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not
+ /// a doc comment) will return `false`.
pub fn is_doc_comment(&self) -> bool {
match self.kind {
AttrKind::Normal(..) => false,
@@ -244,10 +247,16 @@ impl Attribute {
}
}
+ /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
+ /// * `///doc` returns `Some(("doc", CommentKind::Line))`.
+ /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`.
+ /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`.
+ /// * `#[doc(...)]` returns `None`.
pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
match self.kind {
AttrKind::DocComment(kind, data) => Some((data, kind)),
- AttrKind::Normal(ref item, _) if item.path == sym::doc => item
+ AttrKind::Normal(ref normal) if normal.item.path == sym::doc => normal
+ .item
.meta_kind()
.and_then(|kind| kind.value_str())
.map(|data| (data, CommentKind::Line)),
@@ -255,11 +264,15 @@ impl Attribute {
}
}
+ /// Returns the documentation if this is a doc comment or a sugared doc comment.
+ /// * `///doc` returns `Some("doc")`.
+ /// * `#[doc = "doc"]` returns `Some("doc")`.
+ /// * `#[doc(...)]` returns `None`.
pub fn doc_str(&self) -> Option<Symbol> {
match self.kind {
AttrKind::DocComment(.., data) => Some(data),
- AttrKind::Normal(ref item, _) if item.path == sym::doc => {
- item.meta_kind().and_then(|kind| kind.value_str())
+ AttrKind::Normal(ref normal) if normal.item.path == sym::doc => {
+ normal.item.meta_kind().and_then(|kind| kind.value_str())
}
_ => None,
}
@@ -271,14 +284,14 @@ impl Attribute {
pub fn get_normal_item(&self) -> &AttrItem {
match self.kind {
- AttrKind::Normal(ref item, _) => item,
+ AttrKind::Normal(ref normal) => &normal.item,
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
}
}
pub fn unwrap_normal_item(self) -> AttrItem {
match self.kind {
- AttrKind::Normal(item, _) => item,
+ AttrKind::Normal(normal) => normal.into_inner().item,
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
}
}
@@ -286,31 +299,30 @@ impl Attribute {
/// Extracts the MetaItem from inside this Attribute.
pub fn meta(&self) -> Option<MetaItem> {
match self.kind {
- AttrKind::Normal(ref item, _) => item.meta(self.span),
+ AttrKind::Normal(ref normal) => normal.item.meta(self.span),
AttrKind::DocComment(..) => None,
}
}
pub fn meta_kind(&self) -> Option<MetaItemKind> {
match self.kind {
- AttrKind::Normal(ref item, _) => item.meta_kind(),
+ AttrKind::Normal(ref normal) => normal.item.meta_kind(),
AttrKind::DocComment(..) => None,
}
}
- pub fn tokens(&self) -> AttrAnnotatedTokenStream {
+ pub fn tokens(&self) -> TokenStream {
match self.kind {
- AttrKind::Normal(_, ref tokens) => tokens
+ AttrKind::Normal(ref normal) => normal
+ .tokens
.as_ref()
.unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self))
- .create_token_stream(),
- AttrKind::DocComment(comment_kind, data) => AttrAnnotatedTokenStream::from((
- AttrAnnotatedTokenTree::Token(Token::new(
- token::DocComment(comment_kind, self.style, data),
- self.span,
- )),
+ .to_attr_token_stream()
+ .to_tokenstream(),
+ AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token(
+ Token::new(token::DocComment(comment_kind, self.style, data), self.span),
Spacing::Alone,
- )),
+ )]),
}
}
}
@@ -340,47 +352,86 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
NestedMetaItem::MetaItem(mk_word_item(ident))
}
-pub(crate) fn mk_attr_id() -> AttrId {
- use std::sync::atomic::AtomicU32;
- use std::sync::atomic::Ordering;
+pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>);
- static NEXT_ATTR_ID: AtomicU32 = AtomicU32::new(0);
+#[cfg(debug_assertions)]
+static MAX_ATTR_ID: AtomicU32 = AtomicU32::new(u32::MAX);
- let id = NEXT_ATTR_ID.fetch_add(1, Ordering::SeqCst);
- assert!(id != u32::MAX);
- AttrId::from_u32(id)
+impl AttrIdGenerator {
+ pub fn new() -> Self {
+ // We use `(index as u32).reverse_bits()` to initialize the
+ // starting value of AttrId in each worker thread.
+ // The `index` is the index of the worker thread.
+ // This ensures that the AttrId generated in each thread is unique.
+ AttrIdGenerator(WorkerLocal::new(|index| {
+ let index: u32 = index.try_into().unwrap();
+
+ #[cfg(debug_assertions)]
+ {
+ let max_id = ((index + 1).next_power_of_two() - 1).bitxor(u32::MAX).reverse_bits();
+ MAX_ATTR_ID.fetch_min(max_id, Ordering::Release);
+ }
+
+ Cell::new(index.reverse_bits())
+ }))
+ }
+
+ pub fn mk_attr_id(&self) -> AttrId {
+ let id = self.0.get();
+
+ // Ensure the assigned attr_id does not overlap the bits
+ // representing the number of threads.
+ #[cfg(debug_assertions)]
+ assert!(id <= MAX_ATTR_ID.load(Ordering::Acquire));
+
+ self.0.set(id + 1);
+ AttrId::from_u32(id)
+ }
}
-pub fn mk_attr(style: AttrStyle, path: Path, args: MacArgs, span: Span) -> Attribute {
- mk_attr_from_item(AttrItem { path, args, tokens: None }, None, style, span)
+pub fn mk_attr(
+ g: &AttrIdGenerator,
+ style: AttrStyle,
+ path: Path,
+ args: MacArgs,
+ span: Span,
+) -> Attribute {
+ mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span)
}
pub fn mk_attr_from_item(
+ g: &AttrIdGenerator,
item: AttrItem,
- tokens: Option<LazyTokenStream>,
+ tokens: Option<LazyAttrTokenStream>,
style: AttrStyle,
span: Span,
) -> Attribute {
- Attribute { kind: AttrKind::Normal(item, tokens), id: mk_attr_id(), style, span }
+ Attribute {
+ kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })),
+ id: g.mk_attr_id(),
+ style,
+ span,
+ }
}
/// Returns an inner attribute with the given value and span.
-pub fn mk_attr_inner(item: MetaItem) -> Attribute {
- mk_attr(AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span)
+pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
+ mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span)
}
/// Returns an outer attribute with the given value and span.
-pub fn mk_attr_outer(item: MetaItem) -> Attribute {
- mk_attr(AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span)
+pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
+ mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span)
}
pub fn mk_doc_comment(
+ g: &AttrIdGenerator,
comment_kind: CommentKind,
style: AttrStyle,
data: Symbol,
span: Span,
) -> Attribute {
- Attribute { kind: AttrKind::DocComment(comment_kind, data), id: mk_attr_id(), style, span }
+ Attribute { kind: AttrKind::DocComment(comment_kind, data), id: g.mk_attr_id(), style, span }
}
pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
@@ -484,7 +535,7 @@ impl MetaItemKind {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::Lit(lit.clone()),
span: lit.span,
- attrs: ThinVec::new(),
+ attrs: ast::AttrVec::new(),
tokens: None,
});
MacArgs::Eq(span, MacArgsEq::Ast(expr))
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 4b94ec0d6..bd7a85b07 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -13,17 +13,23 @@
#![feature(const_default_impls)]
#![feature(const_trait_impl)]
#![feature(if_let_guard)]
-#![feature(label_break_value)]
+#![cfg_attr(bootstrap, feature(label_break_value))]
#![feature(let_chains)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(slice_internals)]
#![feature(stmt_expr_attributes)]
#![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
+#[macro_use]
+extern crate tracing;
+
pub mod util {
pub mod classify;
pub mod comments;
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 01bd498b3..9fd0b63c4 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -14,7 +14,6 @@ use crate::tokenstream::*;
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::sync::Lrc;
-use rustc_data_structures::thin_vec::ThinVec;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Ident;
use rustc_span::Span;
@@ -338,12 +337,7 @@ where
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
-pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) {
- visit_vec(attrs, |attr| vis.visit_attribute(attr));
-}
-
-// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
-pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
+pub fn visit_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
for attr in attrs.iter_mut() {
vis.visit_attribute(attr);
}
@@ -398,7 +392,7 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>(
vis.visit_ident(ident);
vis.visit_pat(pat);
vis.visit_span(span);
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
smallvec![fp]
}
@@ -424,7 +418,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> {
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
vis.visit_id(id);
vis.visit_pat(pat);
visit_opt(guard, |guard| vis.visit_expr(guard));
@@ -507,7 +501,7 @@ pub fn noop_flat_map_variant<T: MutVisitor>(
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
visitor.visit_ident(ident);
visitor.visit_vis(vis);
- visit_thin_attrs(attrs, visitor);
+ visit_attrs(attrs, visitor);
visitor.visit_id(id);
visitor.visit_variant_data(data);
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
@@ -589,14 +583,16 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
}
}
vis.visit_span(span);
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis);
}
pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
let Attribute { kind, id: _, style: _, span } = attr;
match kind {
- AttrKind::Normal(AttrItem { path, args, tokens }, attr_tokens) => {
+ AttrKind::Normal(normal) => {
+ let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
+ &mut **normal;
vis.visit_path(path);
visit_mac_args(args, vis);
visit_lazy_tts(tokens, vis);
@@ -638,7 +634,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> {
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
vis.visit_id(id);
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
vis.visit_pat(pat);
vis.visit_span(span);
vis.visit_ty(ty);
@@ -646,21 +642,21 @@ pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> Smal
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
-pub fn visit_attr_annotated_tt<T: MutVisitor>(tt: &mut AttrAnnotatedTokenTree, vis: &mut T) {
+pub fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) {
match tt {
- AttrAnnotatedTokenTree::Token(token) => {
+ AttrTokenTree::Token(token, _) => {
visit_token(token, vis);
}
- AttrAnnotatedTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
+ AttrTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
vis.visit_span(open);
vis.visit_span(close);
- visit_attr_annotated_tts(tts, vis);
+ visit_attr_tts(tts, vis);
}
- AttrAnnotatedTokenTree::Attributes(data) => {
+ AttrTokenTree::Attributes(data) => {
for attr in &mut *data.attrs {
match &mut attr.kind {
- AttrKind::Normal(_, attr_tokens) => {
- visit_lazy_tts(attr_tokens, vis);
+ AttrKind::Normal(normal) => {
+ visit_lazy_tts(&mut normal.tokens, vis);
}
AttrKind::DocComment(..) => {
vis.visit_span(&mut attr.span);
@@ -694,27 +690,27 @@ pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T)
}
}
-pub fn visit_attr_annotated_tts<T: MutVisitor>(
- AttrAnnotatedTokenStream(tts): &mut AttrAnnotatedTokenStream,
- vis: &mut T,
-) {
+pub fn visit_attr_tts<T: MutVisitor>(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) {
if T::VISIT_TOKENS && !tts.is_empty() {
let tts = Lrc::make_mut(tts);
- visit_vec(tts, |(tree, _is_joint)| visit_attr_annotated_tt(tree, vis));
+ visit_vec(tts, |tree| visit_attr_tt(tree, vis));
}
}
-pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(lazy_tts: Option<&mut LazyTokenStream>, vis: &mut T) {
+pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(
+ lazy_tts: Option<&mut LazyAttrTokenStream>,
+ vis: &mut T,
+) {
if T::VISIT_TOKENS {
if let Some(lazy_tts) = lazy_tts {
- let mut tts = lazy_tts.create_token_stream();
- visit_attr_annotated_tts(&mut tts, vis);
- *lazy_tts = LazyTokenStream::new(tts);
+ let mut tts = lazy_tts.to_attr_token_stream();
+ visit_attr_tts(&mut tts, vis);
+ *lazy_tts = LazyAttrTokenStream::new(tts);
}
}
}
-pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) {
+pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>, vis: &mut T) {
visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis);
}
@@ -880,7 +876,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
if let Some(ref mut colon_span) = colon_span {
vis.visit_span(colon_span);
}
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
match kind {
GenericParamKind::Lifetime => {}
@@ -933,8 +929,7 @@ pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis:
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
}
WherePredicate::EqPredicate(ep) => {
- let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep;
- vis.visit_id(id);
+ let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep;
vis.visit_span(span);
vis.visit_ty(lhs_ty);
vis.visit_ty(rhs_ty);
@@ -977,7 +972,7 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
visitor.visit_vis(vis);
visitor.visit_id(id);
visitor.visit_ty(ty);
- visit_thin_attrs(attrs, visitor);
+ visit_attrs(attrs, visitor);
smallvec![fd]
}
@@ -990,7 +985,7 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>(
vis.visit_expr(expr);
vis.visit_id(id);
vis.visit_span(span);
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
smallvec![f]
}
@@ -1430,7 +1425,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
}
vis.visit_id(id);
vis.visit_span(span);
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis);
}
@@ -1476,7 +1471,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
StmtKind::MacCall(mut mac) => {
let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
vis.visit_mac_call(mac_);
- visit_thin_attrs(attrs, vis);
+ visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis);
smallvec![StmtKind::MacCall(mac)]
}
@@ -1486,7 +1481,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
match &mut visibility.kind {
VisibilityKind::Public | VisibilityKind::Inherited => {}
- VisibilityKind::Restricted { path, id } => {
+ VisibilityKind::Restricted { path, id, shorthand: _ } => {
vis.visit_path(path);
vis.visit_id(id);
}
@@ -1511,12 +1506,6 @@ impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
}
}
-impl<T> DummyAstNode for ThinVec<T> {
- fn dummy() -> Self {
- Default::default()
- }
-}
-
impl DummyAstNode for Item {
fn dummy() -> Self {
Item {
diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs
index 7f928cb57..7b5acc3f4 100644
--- a/compiler/rustc_ast/src/node_id.rs
+++ b/compiler/rustc_ast/src/node_id.rs
@@ -13,7 +13,7 @@ rustc_index::newtype_index! {
}
}
-rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeId);
+rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId);
/// The [`NodeId`] used to represent the root of the crate.
pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0);
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 85d9687c6..97dfb7837 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -398,6 +398,30 @@ impl Token {
}
}
+ /// Returns `true` if the token can appear at the start of an pattern.
+ ///
+ /// Shamelessly borrowed from `can_begin_expr`, only used for diagnostics right now.
+ pub fn can_begin_pattern(&self) -> bool {
+ match self.uninterpolate().kind {
+ Ident(name, is_raw) =>
+ ident_can_begin_expr(name, self.span, is_raw), // value name or keyword
+ | OpenDelim(Delimiter::Bracket | Delimiter::Parenthesis) // tuple or array
+ | Literal(..) // literal
+ | BinOp(Minus) // unary minus
+ | BinOp(And) // reference
+ | AndAnd // double reference
+ // DotDotDot is no longer supported
+ | DotDot | DotDotDot | DotDotEq // ranges
+ | Lt | BinOp(Shl) // associated path
+ | ModSep => true, // global path
+ Interpolated(ref nt) => matches!(**nt, NtLiteral(..) |
+ NtPat(..) |
+ NtBlock(..) |
+ NtPath(..)),
+ _ => false,
+ }
+ }
+
/// Returns `true` if the token can appear at the start of a type.
pub fn can_begin_type(&self) -> bool {
match self.uninterpolate().kind {
@@ -436,6 +460,31 @@ impl Token {
|| self == &OpenDelim(Delimiter::Parenthesis)
}
+ /// Returns `true` if the token can appear at the start of an item.
+ pub fn can_begin_item(&self) -> bool {
+ match self.kind {
+ Ident(name, _) => [
+ kw::Fn,
+ kw::Use,
+ kw::Struct,
+ kw::Enum,
+ kw::Pub,
+ kw::Trait,
+ kw::Extern,
+ kw::Impl,
+ kw::Unsafe,
+ kw::Const,
+ kw::Static,
+ kw::Union,
+ kw::Macro,
+ kw::Mod,
+ kw::Type,
+ ]
+ .contains(&name),
+ _ => false,
+ }
+ }
+
/// Returns `true` if the token is any literal.
pub fn is_lit(&self) -> bool {
matches!(self.kind, Literal(..))
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 9e4a22e1f..875cd620d 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -121,12 +121,12 @@ where
}
}
-pub trait CreateTokenStream: sync::Send + sync::Sync {
- fn create_token_stream(&self) -> AttrAnnotatedTokenStream;
+pub trait ToAttrTokenStream: sync::Send + sync::Sync {
+ fn to_attr_token_stream(&self) -> AttrTokenStream;
}
-impl CreateTokenStream for AttrAnnotatedTokenStream {
- fn create_token_stream(&self) -> AttrAnnotatedTokenStream {
+impl ToAttrTokenStream for AttrTokenStream {
+ fn to_attr_token_stream(&self) -> AttrTokenStream {
self.clone()
}
}
@@ -135,68 +135,68 @@ impl CreateTokenStream for AttrAnnotatedTokenStream {
/// of an actual `TokenStream` until it is needed.
/// `Box` is here only to reduce the structure size.
#[derive(Clone)]
-pub struct LazyTokenStream(Lrc<Box<dyn CreateTokenStream>>);
+pub struct LazyAttrTokenStream(Lrc<Box<dyn ToAttrTokenStream>>);
-impl LazyTokenStream {
- pub fn new(inner: impl CreateTokenStream + 'static) -> LazyTokenStream {
- LazyTokenStream(Lrc::new(Box::new(inner)))
+impl LazyAttrTokenStream {
+ pub fn new(inner: impl ToAttrTokenStream + 'static) -> LazyAttrTokenStream {
+ LazyAttrTokenStream(Lrc::new(Box::new(inner)))
}
- pub fn create_token_stream(&self) -> AttrAnnotatedTokenStream {
- self.0.create_token_stream()
+ pub fn to_attr_token_stream(&self) -> AttrTokenStream {
+ self.0.to_attr_token_stream()
}
}
-impl fmt::Debug for LazyTokenStream {
+impl fmt::Debug for LazyAttrTokenStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "LazyTokenStream({:?})", self.create_token_stream())
+ write!(f, "LazyAttrTokenStream({:?})", self.to_attr_token_stream())
}
}
-impl<S: Encoder> Encodable<S> for LazyTokenStream {
+impl<S: Encoder> Encodable<S> for LazyAttrTokenStream {
fn encode(&self, s: &mut S) {
// Used by AST json printing.
- Encodable::encode(&self.create_token_stream(), s);
+ Encodable::encode(&self.to_attr_token_stream(), s);
}
}
-impl<D: Decoder> Decodable<D> for LazyTokenStream {
+impl<D: Decoder> Decodable<D> for LazyAttrTokenStream {
fn decode(_d: &mut D) -> Self {
- panic!("Attempted to decode LazyTokenStream");
+ panic!("Attempted to decode LazyAttrTokenStream");
}
}
-impl<CTX> HashStable<CTX> for LazyTokenStream {
+impl<CTX> HashStable<CTX> for LazyAttrTokenStream {
fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) {
- panic!("Attempted to compute stable hash for LazyTokenStream");
+ panic!("Attempted to compute stable hash for LazyAttrTokenStream");
}
}
-/// A `AttrAnnotatedTokenStream` is similar to a `TokenStream`, but with extra
+/// An `AttrTokenStream` is similar to a `TokenStream`, but with extra
/// information about the tokens for attribute targets. This is used
/// during expansion to perform early cfg-expansion, and to process attributes
/// during proc-macro invocations.
#[derive(Clone, Debug, Default, Encodable, Decodable)]
-pub struct AttrAnnotatedTokenStream(pub Lrc<Vec<(AttrAnnotatedTokenTree, Spacing)>>);
+pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>);
-/// Like `TokenTree`, but for `AttrAnnotatedTokenStream`
+/// Like `TokenTree`, but for `AttrTokenStream`.
#[derive(Clone, Debug, Encodable, Decodable)]
-pub enum AttrAnnotatedTokenTree {
- Token(Token),
- Delimited(DelimSpan, Delimiter, AttrAnnotatedTokenStream),
+pub enum AttrTokenTree {
+ Token(Token, Spacing),
+ Delimited(DelimSpan, Delimiter, AttrTokenStream),
/// Stores the attributes for an attribute target,
/// along with the tokens for that attribute target.
/// See `AttributesData` for more information
Attributes(AttributesData),
}
-impl AttrAnnotatedTokenStream {
- pub fn new(tokens: Vec<(AttrAnnotatedTokenTree, Spacing)>) -> AttrAnnotatedTokenStream {
- AttrAnnotatedTokenStream(Lrc::new(tokens))
+impl AttrTokenStream {
+ pub fn new(tokens: Vec<AttrTokenTree>) -> AttrTokenStream {
+ AttrTokenStream(Lrc::new(tokens))
}
- /// Converts this `AttrAnnotatedTokenStream` to a plain `TokenStream
- /// During conversion, `AttrAnnotatedTokenTree::Attributes` get 'flattened'
+ /// Converts this `AttrTokenStream` to a plain `TokenStream`.
+ /// During conversion, `AttrTokenTree::Attributes` get 'flattened'
/// back to a `TokenStream` of the form `outer_attr attr_target`.
/// If there are inner attributes, they are inserted into the proper
/// place in the attribute target tokens.
@@ -204,31 +204,27 @@ impl AttrAnnotatedTokenStream {
let trees: Vec<_> = self
.0
.iter()
- .flat_map(|tree| match &tree.0 {
- AttrAnnotatedTokenTree::Token(inner) => {
- smallvec![TokenTree::Token(inner.clone(), tree.1)].into_iter()
+ .flat_map(|tree| match &tree {
+ AttrTokenTree::Token(inner, spacing) => {
+ smallvec![TokenTree::Token(inner.clone(), *spacing)].into_iter()
}
- AttrAnnotatedTokenTree::Delimited(span, delim, stream) => {
+ AttrTokenTree::Delimited(span, delim, stream) => {
smallvec![TokenTree::Delimited(*span, *delim, stream.to_tokenstream()),]
.into_iter()
}
- AttrAnnotatedTokenTree::Attributes(data) => {
+ AttrTokenTree::Attributes(data) => {
let mut outer_attrs = Vec::new();
let mut inner_attrs = Vec::new();
for attr in &data.attrs {
match attr.style {
- crate::AttrStyle::Outer => {
- outer_attrs.push(attr);
- }
- crate::AttrStyle::Inner => {
- inner_attrs.push(attr);
- }
+ crate::AttrStyle::Outer => outer_attrs.push(attr),
+ crate::AttrStyle::Inner => inner_attrs.push(attr),
}
}
let mut target_tokens: Vec<_> = data
.tokens
- .create_token_stream()
+ .to_attr_token_stream()
.to_tokenstream()
.0
.iter()
@@ -239,9 +235,9 @@ impl AttrAnnotatedTokenStream {
// Check the last two trees (to account for a trailing semi)
for tree in target_tokens.iter_mut().rev().take(2) {
if let TokenTree::Delimited(span, delim, delim_tokens) = tree {
- // Inner attributes are only supported on extern blocks, functions, impls,
- // and modules. All of these have their inner attributes placed at
- // the beginning of the rightmost outermost braced group:
+ // Inner attributes are only supported on extern blocks, functions,
+ // impls, and modules. All of these have their inner attributes
+ // placed at the beginning of the rightmost outermost braced group:
// e.g. fn foo() { #![my_attr} }
//
// Therefore, we can insert them back into the right location
@@ -255,7 +251,7 @@ impl AttrAnnotatedTokenStream {
let mut builder = TokenStreamBuilder::new();
for inner_attr in inner_attrs {
- builder.push(inner_attr.tokens().to_tokenstream());
+ builder.push(inner_attr.tokens());
}
builder.push(delim_tokens.clone());
*tree = TokenTree::Delimited(*span, *delim, builder.build());
@@ -273,7 +269,7 @@ impl AttrAnnotatedTokenStream {
let mut flat: SmallVec<[_; 1]> = SmallVec::new();
for attr in outer_attrs {
// FIXME: Make this more efficient
- flat.extend(attr.tokens().to_tokenstream().0.clone().iter().cloned());
+ flat.extend(attr.tokens().0.clone().iter().cloned());
}
flat.extend(target_tokens);
flat.into_iter()
@@ -300,7 +296,7 @@ pub struct AttributesData {
pub attrs: AttrVec,
/// The underlying tokens for the attribute target that `attrs`
/// are applied to
- pub tokens: LazyTokenStream,
+ pub tokens: LazyAttrTokenStream,
}
/// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s.
@@ -363,12 +359,6 @@ impl TokenStream {
}
}
-impl From<(AttrAnnotatedTokenTree, Spacing)> for AttrAnnotatedTokenStream {
- fn from((tree, spacing): (AttrAnnotatedTokenTree, Spacing)) -> AttrAnnotatedTokenStream {
- AttrAnnotatedTokenStream::new(vec![(tree, spacing)])
- }
-}
-
impl iter::FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self {
TokenStream::new(iter.into_iter().collect::<Vec<TokenTree>>())
@@ -420,21 +410,6 @@ impl TokenStream {
TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect()))
}
- fn opt_from_ast(node: &(impl HasAttrs + HasTokens)) -> Option<TokenStream> {
- 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())
- }
-
// Create a token stream containing a single token with alone spacing.
pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream {
TokenStream::new(vec![TokenTree::token_alone(kind, span)])
@@ -451,8 +426,18 @@ impl 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))
+ let Some(tokens) = node.tokens() else {
+ panic!("missing tokens for node at {:?}: {:?}", node.span(), node);
+ };
+ let attrs = node.attrs();
+ let attr_stream = if attrs.is_empty() {
+ tokens.to_attr_token_stream()
+ } else {
+ let attr_data =
+ AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() };
+ AttrTokenStream::new(vec![AttrTokenTree::Attributes(attr_data)])
+ };
+ attr_stream.to_tokenstream()
}
pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
@@ -555,7 +540,7 @@ impl TokenStreamBuilder {
// 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 iter = streams.into_iter();
let mut res_stream_lrc = iter.next().unwrap().0;
// Append the subsequent elements to the result stream, after
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 9c18f55c0..536b38560 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -9,7 +9,6 @@ use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
use std::ascii;
-use tracing::debug;
pub enum LitError {
NotLiteral,
@@ -23,7 +22,7 @@ pub enum LitError {
impl LitKind {
/// Converts literal token into a semantic literal.
- pub fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
+ pub fn from_token_lit(lit: token::Lit) -> Result<LitKind, LitError> {
let token::Lit { kind, symbol, suffix } = lit;
if suffix.is_some() && !kind.may_have_suffix() {
return Err(LitError::InvalidSuffix);
@@ -146,14 +145,14 @@ impl LitKind {
LitKind::ByteStr(bytes.into())
}
- token::Err => LitKind::Err(symbol),
+ token::Err => LitKind::Err,
})
}
/// Attempts to recover a token from semantic literal.
/// This function is used when the original token doesn't exist (e.g. the literal is created
/// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
- pub fn to_lit_token(&self) -> token::Lit {
+ pub fn to_token_lit(&self) -> token::Lit {
let (kind, symbol, suffix) = match *self {
LitKind::Str(symbol, ast::StrStyle::Cooked) => {
// Don't re-intern unless the escaped string is different.
@@ -164,12 +163,7 @@ impl LitKind {
}
LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None),
LitKind::ByteStr(ref bytes) => {
- let string = bytes
- .iter()
- .cloned()
- .flat_map(ascii::escape_default)
- .map(Into::<char>::into)
- .collect::<String>();
+ let string = bytes.escape_ascii().to_string();
(token::ByteStr, Symbol::intern(&string), None)
}
LitKind::Byte(byte) => {
@@ -199,7 +193,9 @@ impl LitKind {
let symbol = if value { kw::True } else { kw::False };
(token::Bool, symbol, None)
}
- LitKind::Err(symbol) => (token::Err, symbol, None),
+ // This only shows up in places like `-Zunpretty=hir` output, so we
+ // don't bother to produce something useful.
+ LitKind::Err => (token::Err, Symbol::intern("<bad-literal>"), None),
};
token::Lit::new(kind, symbol, suffix)
@@ -208,8 +204,8 @@ impl LitKind {
impl Lit {
/// Converts literal token into an AST literal.
- pub fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> {
- Ok(Lit { token, kind: LitKind::from_lit_token(token)?, span })
+ pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> {
+ Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
}
/// Converts arbitrary token into an AST literal.
@@ -232,21 +228,21 @@ impl Lit {
_ => return Err(LitError::NotLiteral),
};
- Lit::from_lit_token(lit, token.span)
+ Lit::from_token_lit(lit, token.span)
}
/// Attempts to recover an AST literal from semantic literal.
/// This function is used when the original token doesn't exist (e.g. the literal is created
/// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
pub fn from_lit_kind(kind: LitKind, span: Span) -> Lit {
- Lit { token: kind.to_lit_token(), kind, span }
+ Lit { token_lit: kind.to_token_lit(), kind, span }
}
/// Losslessly convert an AST literal into a token.
pub fn to_token(&self) -> Token {
- let kind = match self.token.kind {
- token::Bool => token::Ident(self.token.symbol, false),
- _ => token::Literal(self.token),
+ let kind = match self.token_lit.kind {
+ token::Bool => token::Ident(self.token_lit.symbol, false),
+ _ => token::Literal(self.token_lit),
};
Token::new(kind, self.span)
}
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 74b7fe9e2..6c5c7f66f 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -297,11 +297,11 @@ impl ExprPrecedence {
match self {
ExprPrecedence::Closure => PREC_CLOSURE,
- ExprPrecedence::Break |
- ExprPrecedence::Continue |
- ExprPrecedence::Ret |
- ExprPrecedence::Yield |
- ExprPrecedence::Yeet => PREC_JUMP,
+ ExprPrecedence::Break
+ | ExprPrecedence::Continue
+ | ExprPrecedence::Ret
+ | ExprPrecedence::Yield
+ | ExprPrecedence::Yeet => PREC_JUMP,
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
@@ -318,43 +318,43 @@ impl ExprPrecedence {
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,
// Unary, prefix
- ExprPrecedence::Box |
- ExprPrecedence::AddrOf |
+ ExprPrecedence::Box
+ | ExprPrecedence::AddrOf
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
// but we need to print `(let _ = a) < b` as-is with parens.
- ExprPrecedence::Let |
- ExprPrecedence::Unary => PREC_PREFIX,
+ | ExprPrecedence::Let
+ | ExprPrecedence::Unary => PREC_PREFIX,
// Unary, postfix
- ExprPrecedence::Await |
- ExprPrecedence::Call |
- ExprPrecedence::MethodCall |
- ExprPrecedence::Field |
- ExprPrecedence::Index |
- ExprPrecedence::Try |
- ExprPrecedence::InlineAsm |
- ExprPrecedence::Mac => PREC_POSTFIX,
+ ExprPrecedence::Await
+ | ExprPrecedence::Call
+ | ExprPrecedence::MethodCall
+ | ExprPrecedence::Field
+ | ExprPrecedence::Index
+ | ExprPrecedence::Try
+ | ExprPrecedence::InlineAsm
+ | ExprPrecedence::Mac => PREC_POSTFIX,
// Never need parens
- ExprPrecedence::Array |
- ExprPrecedence::Repeat |
- ExprPrecedence::Tup |
- ExprPrecedence::Lit |
- ExprPrecedence::Path |
- ExprPrecedence::Paren |
- ExprPrecedence::If |
- ExprPrecedence::While |
- ExprPrecedence::ForLoop |
- ExprPrecedence::Loop |
- ExprPrecedence::Match |
- ExprPrecedence::ConstBlock |
- ExprPrecedence::Block |
- ExprPrecedence::TryBlock |
- ExprPrecedence::Async |
- ExprPrecedence::Struct |
- ExprPrecedence::Err => PREC_PAREN,
+ ExprPrecedence::Array
+ | ExprPrecedence::Repeat
+ | ExprPrecedence::Tup
+ | ExprPrecedence::Lit
+ | ExprPrecedence::Path
+ | ExprPrecedence::Paren
+ | ExprPrecedence::If
+ | ExprPrecedence::While
+ | ExprPrecedence::ForLoop
+ | ExprPrecedence::Loop
+ | ExprPrecedence::Match
+ | ExprPrecedence::ConstBlock
+ | ExprPrecedence::Block
+ | ExprPrecedence::TryBlock
+ | ExprPrecedence::Async
+ | ExprPrecedence::Struct
+ | ExprPrecedence::Err => PREC_PAREN,
}
}
}
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index d9594b323..1d0de5a4b 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -156,8 +156,8 @@ pub trait Visitor<'ast>: Sized {
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
walk_where_predicate(self, p)
}
- fn visit_fn(&mut self, fk: FnKind<'ast>, s: Span, _: NodeId) {
- walk_fn(self, fk, s)
+ fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) {
+ walk_fn(self, fk)
}
fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) {
walk_assoc_item(self, i, ctxt)
@@ -168,8 +168,8 @@ pub trait Visitor<'ast>: Sized {
fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) {
walk_param_bound(self, bounds)
}
- fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
- walk_poly_trait_ref(self, t, m)
+ fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) {
+ walk_poly_trait_ref(self, t)
}
fn visit_variant_data(&mut self, s: &'ast VariantData) {
walk_struct_def(self, s)
@@ -177,14 +177,8 @@ pub trait Visitor<'ast>: Sized {
fn visit_field_def(&mut self, s: &'ast FieldDef) {
walk_field_def(self, s)
}
- fn visit_enum_def(
- &mut self,
- enum_definition: &'ast EnumDef,
- generics: &'ast Generics,
- item_id: NodeId,
- _: Span,
- ) {
- walk_enum_def(self, enum_definition, generics, item_id)
+ fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) {
+ walk_enum_def(self, enum_definition)
}
fn visit_variant(&mut self, v: &'ast Variant) {
walk_variant(self, v)
@@ -207,11 +201,11 @@ pub trait Visitor<'ast>: Sized {
fn visit_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId, _nested: bool) {
walk_use_tree(self, use_tree, id)
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) {
- walk_path_segment(self, path_span, path_segment)
+ fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
+ walk_path_segment(self, path_segment)
}
- fn visit_generic_args(&mut self, path_span: Span, generic_args: &'ast GenericArgs) {
- walk_generic_args(self, path_span, generic_args)
+ fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) {
+ walk_generic_args(self, generic_args)
}
fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) {
walk_generic_arg(self, generic_arg)
@@ -287,11 +281,8 @@ pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime
visitor.visit_ident(lifetime.ident);
}
-pub fn walk_poly_trait_ref<'a, V>(
- visitor: &mut V,
- trait_ref: &'a PolyTraitRef,
- _: &TraitBoundModifier,
-) where
+pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef)
+where
V: Visitor<'a>,
{
walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params);
@@ -334,7 +325,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
}
ItemKind::Enum(ref enum_definition, ref generics) => {
visitor.visit_generics(generics);
- visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
+ visitor.visit_enum_def(enum_definition)
}
ItemKind::Impl(box Impl {
defaultness: _,
@@ -377,12 +368,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
walk_list!(visitor, visit_attribute, &item.attrs);
}
-pub fn walk_enum_def<'a, V: Visitor<'a>>(
- visitor: &mut V,
- enum_definition: &'a EnumDef,
- _: &'a Generics,
- _: NodeId,
-) {
+pub fn walk_enum_def<'a, V: Visitor<'a>>(visitor: &mut V, enum_definition: &'a EnumDef) {
walk_list!(visitor, visit_variant, &enum_definition.variants);
}
@@ -449,7 +435,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) {
for segment in &path.segments {
- visitor.visit_path_segment(path.span, segment);
+ visitor.visit_path_segment(segment);
}
}
@@ -471,18 +457,14 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree,
}
}
-pub fn walk_path_segment<'a, V: Visitor<'a>>(
- visitor: &mut V,
- path_span: Span,
- segment: &'a PathSegment,
-) {
+pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V, segment: &'a PathSegment) {
visitor.visit_ident(segment.ident);
if let Some(ref args) = segment.args {
- visitor.visit_generic_args(path_span, args);
+ visitor.visit_generic_args(args);
}
}
-pub fn walk_generic_args<'a, V>(visitor: &mut V, _path_span: Span, generic_args: &'a GenericArgs)
+pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs)
where
V: Visitor<'a>,
{
@@ -516,7 +498,7 @@ where
pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'a AssocConstraint) {
visitor.visit_ident(constraint.ident);
if let Some(ref gen_args) = constraint.gen_args {
- visitor.visit_generic_args(gen_args.span(), gen_args);
+ visitor.visit_generic_args(gen_args);
}
match constraint.kind {
AssocConstraintKind::Equality { ref term } => match term {
@@ -598,7 +580,7 @@ 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::Trait(ref typ, ref _modifier) => visitor.visit_poly_trait_ref(typ),
GenericBound::Outlives(ref lifetime) => {
visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)
}
@@ -673,7 +655,7 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &
visitor.visit_fn_ret_ty(&function_declaration.output);
}
-pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Span) {
+pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) {
match kind {
FnKind::Fn(_, _, sig, _, generics, body) => {
visitor.visit_generics(generics);
@@ -814,7 +796,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::MethodCall(ref segment, ref arguments, _span) => {
- visitor.visit_path_segment(expression.span, segment);
+ visitor.visit_path_segment(segment);
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
@@ -935,14 +917,14 @@ pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
}
pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
- if let VisibilityKind::Restricted { ref path, id } = vis.kind {
+ if let VisibilityKind::Restricted { ref path, id, shorthand: _ } = vis.kind {
visitor.visit_path(path, id);
}
}
pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
match attr.kind {
- AttrKind::Normal(ref item, ref _tokens) => walk_mac_args(visitor, &item.args),
+ AttrKind::Normal(ref normal) => walk_mac_args(visitor, &normal.item.args),
AttrKind::DocComment(..) => {}
}
}
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 39ba62ef2..ce1c8d499 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -8,16 +8,18 @@ doctest = false
[dependencies]
rustc_arena = { path = "../rustc_arena" }
-tracing = "0.1"
+rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
-rustc_hir = { path = "../rustc_hir" }
-rustc_target = { path = "../rustc_target" }
rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_middle = { path = "../rustc_middle" }
+rustc_macros = { path = "../rustc_macros" }
rustc_query_system = { path = "../rustc_query_system" }
-rustc_span = { path = "../rustc_span" }
-rustc_errors = { path = "../rustc_errors" }
rustc_session = { path = "../rustc_session" }
-rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
+tracing = "0.1"
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 4166b4fc2..24672efc6 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -1,11 +1,17 @@
use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt};
+use super::errors::{
+ AbiSpecifiedMultipleTimes, AttSyntaxOnlyX86, ClobberAbiNotSupported,
+ InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
+ InvalidAsmTemplateModifierRegClass, InvalidAsmTemplateModifierRegClassSub,
+ InvalidAsmTemplateModifierSym, InvalidRegister, InvalidRegisterClass, RegisterClassOnlyClobber,
+ RegisterConflict,
+};
use super::LoweringContext;
use rustc_ast::ptr::P;
use rustc_ast::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::definitions::DefPathData;
@@ -26,13 +32,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let asm_arch =
if self.tcx.sess.opts.actually_rustdoc { None } else { self.tcx.sess.asm_arch };
if asm_arch.is_none() && !self.tcx.sess.opts.actually_rustdoc {
- struct_span_err!(
- self.tcx.sess,
- sp,
- E0472,
- "inline assembly is unsupported on this target"
- )
- .emit();
+ self.tcx.sess.emit_err(InlineAsmUnsupportedTarget { span: sp });
}
if let Some(asm_arch) = asm_arch {
// Inline assembly is currently only stable for these architectures.
@@ -59,10 +59,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&& !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
&& !self.tcx.sess.opts.actually_rustdoc
{
- self.tcx
- .sess
- .struct_span_err(sp, "the `att_syntax` option is only supported on x86")
- .emit();
+ self.tcx.sess.emit_err(AttSyntaxOnlyX86 { span: sp });
}
if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
feature_err(
@@ -82,51 +79,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// If the abi was already in the list, emit an error
match clobber_abis.get(&abi) {
Some((prev_name, prev_sp)) => {
- let mut err = self.tcx.sess.struct_span_err(
- *abi_span,
- &format!("`{}` ABI specified multiple times", prev_name),
- );
- err.span_label(*prev_sp, "previously specified here");
-
// Multiple different abi names may actually be the same ABI
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
let source_map = self.tcx.sess.source_map();
- if source_map.span_to_snippet(*prev_sp)
- != source_map.span_to_snippet(*abi_span)
- {
- err.note("these ABIs are equivalent on the current target");
- }
+ let equivalent = (source_map.span_to_snippet(*prev_sp)
+ != source_map.span_to_snippet(*abi_span))
+ .then_some(());
- err.emit();
+ self.tcx.sess.emit_err(AbiSpecifiedMultipleTimes {
+ abi_span: *abi_span,
+ prev_name: *prev_name,
+ prev_span: *prev_sp,
+ equivalent,
+ });
}
None => {
- clobber_abis.insert(abi, (abi_name, *abi_span));
+ clobber_abis.insert(abi, (*abi_name, *abi_span));
}
}
}
Err(&[]) => {
- self.tcx
- .sess
- .struct_span_err(
- *abi_span,
- "`clobber_abi` is not supported on this target",
- )
- .emit();
+ self.tcx.sess.emit_err(ClobberAbiNotSupported { abi_span: *abi_span });
}
Err(supported_abis) => {
- let mut err = self
- .tcx
- .sess
- .struct_span_err(*abi_span, "invalid ABI for `clobber_abi`");
let mut abis = format!("`{}`", supported_abis[0]);
for m in &supported_abis[1..] {
let _ = write!(abis, ", `{}`", m);
}
- err.note(&format!(
- "the following ABIs are supported on this target: {}",
- abis
- ));
- err.emit();
+ self.tcx.sess.emit_err(InvalidAbiClobberAbi {
+ abi_span: *abi_span,
+ supported_abis: abis,
+ });
}
}
}
@@ -141,24 +124,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.iter()
.map(|(op, op_sp)| {
let lower_reg = |reg| match reg {
- InlineAsmRegOrRegClass::Reg(s) => {
+ InlineAsmRegOrRegClass::Reg(reg) => {
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
- asm::InlineAsmReg::parse(asm_arch, s).unwrap_or_else(|e| {
- let msg = format!("invalid register `{}`: {}", s, e);
- sess.struct_span_err(*op_sp, &msg).emit();
+ asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| {
+ sess.emit_err(InvalidRegister { op_span: *op_sp, reg, error });
asm::InlineAsmReg::Err
})
} else {
asm::InlineAsmReg::Err
})
}
- InlineAsmRegOrRegClass::RegClass(s) => {
+ InlineAsmRegOrRegClass::RegClass(reg_class) => {
asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch {
- asm::InlineAsmRegClass::parse(asm_arch, s).unwrap_or_else(|e| {
- let msg = format!("invalid register class `{}`: {}", s, e);
- sess.struct_span_err(*op_sp, &msg).emit();
- asm::InlineAsmRegClass::Err
- })
+ asm::InlineAsmRegClass::parse(asm_arch, reg_class).unwrap_or_else(
+ |error| {
+ sess.emit_err(InvalidRegisterClass {
+ op_span: *op_sp,
+ reg_class,
+ error,
+ });
+ asm::InlineAsmRegClass::Err
+ },
+ )
} else {
asm::InlineAsmRegClass::Err
})
@@ -168,26 +155,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let op = match *op {
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
reg: lower_reg(reg),
- expr: self.lower_expr_mut(expr),
+ expr: self.lower_expr(expr),
},
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
reg: lower_reg(reg),
late,
- expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
+ expr: expr.as_ref().map(|expr| self.lower_expr(expr)),
},
InlineAsmOperand::InOut { reg, late, ref expr } => {
hir::InlineAsmOperand::InOut {
reg: lower_reg(reg),
late,
- expr: self.lower_expr_mut(expr),
+ expr: self.lower_expr(expr),
}
}
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
hir::InlineAsmOperand::SplitInOut {
reg: lower_reg(reg),
late,
- in_expr: self.lower_expr_mut(in_expr),
- out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
+ in_expr: self.lower_expr(in_expr),
+ out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)),
}
}
InlineAsmOperand::Const { ref anon_const } => {
@@ -233,7 +220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&sym.qself,
&sym.path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
hir::InlineAsmOperand::SymStatic { path, def_id }
} else {
@@ -282,50 +269,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
let valid_modifiers = class.valid_modifiers(asm_arch.unwrap());
if !valid_modifiers.contains(&modifier) {
- let mut err = sess.struct_span_err(
- placeholder_span,
- "invalid asm template modifier for this register class",
- );
- err.span_label(placeholder_span, "template modifier");
- err.span_label(op_sp, "argument");
- if !valid_modifiers.is_empty() {
+ let sub = if !valid_modifiers.is_empty() {
let mut mods = format!("`{}`", valid_modifiers[0]);
for m in &valid_modifiers[1..] {
let _ = write!(mods, ", `{}`", m);
}
- err.note(&format!(
- "the `{}` register class supports \
- the following template modifiers: {}",
- class.name(),
- mods
- ));
+ InvalidAsmTemplateModifierRegClassSub::SupportModifier {
+ class_name: class.name(),
+ modifiers: mods,
+ }
} else {
- err.note(&format!(
- "the `{}` register class does not support template modifiers",
- class.name()
- ));
- }
- err.emit();
+ InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier {
+ class_name: class.name(),
+ }
+ };
+ sess.emit_err(InvalidAsmTemplateModifierRegClass {
+ placeholder_span,
+ op_span: op_sp,
+ sub,
+ });
}
}
hir::InlineAsmOperand::Const { .. } => {
- let mut err = sess.struct_span_err(
+ sess.emit_err(InvalidAsmTemplateModifierConst {
placeholder_span,
- "asm template modifiers are not allowed for `const` arguments",
- );
- err.span_label(placeholder_span, "template modifier");
- err.span_label(op_sp, "argument");
- err.emit();
+ op_span: op_sp,
+ });
}
hir::InlineAsmOperand::SymFn { .. }
| hir::InlineAsmOperand::SymStatic { .. } => {
- let mut err = sess.struct_span_err(
+ sess.emit_err(InvalidAsmTemplateModifierSym {
placeholder_span,
- "asm template modifiers are not allowed for `sym` arguments",
- );
- err.span_label(placeholder_span, "template modifier");
- err.span_label(op_sp, "argument");
- err.emit();
+ op_span: op_sp,
+ });
}
}
}
@@ -346,12 +322,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// require that the operand name an explicit register, not a
// register class.
if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() {
- let msg = format!(
- "register class `{}` can only be used as a clobber, \
- not as an input or output",
- reg_class.name()
- );
- sess.struct_span_err(op_sp, &msg).emit();
+ sess.emit_err(RegisterClassOnlyClobber {
+ op_span: op_sp,
+ reg_class_name: reg_class.name(),
+ });
continue;
}
@@ -391,16 +365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
unreachable!();
};
- let msg = format!(
- "register `{}` conflicts with register `{}`",
- reg.name(),
- reg2.name()
- );
- let mut err = sess.struct_span_err(op_sp, &msg);
- err.span_label(op_sp, &format!("register `{}`", reg.name()));
- err.span_label(op_sp2, &format!("register `{}`", reg2.name()));
-
- match (op, op2) {
+ let in_out = match (op, op2) {
(
hir::InlineAsmOperand::In { .. },
hir::InlineAsmOperand::Out { late, .. },
@@ -411,14 +376,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) => {
assert!(!*late);
let out_op_sp = if input { op_sp2 } else { op_sp };
- let msg = "use `lateout` instead of \
- `out` to avoid conflict";
- err.span_help(out_op_sp, msg);
- }
- _ => {}
- }
+ Some(out_op_sp)
+ },
+ _ => None,
+ };
- err.emit();
+ sess.emit_err(RegisterConflict {
+ op_span1: op_sp,
+ op_span2: op_sp2,
+ reg1_name: reg.name(),
+ reg2_name: reg2.name(),
+ in_out
+ });
}
Entry::Vacant(v) => {
if r == reg {
diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs
index 7cbfe143b..12a0cc0d2 100644
--- a/compiler/rustc_ast_lowering/src/block.rs
+++ b/compiler/rustc_ast_lowering/src/block.rs
@@ -1,8 +1,6 @@
use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
use rustc_hir as hir;
-use rustc_session::parse::feature_err;
-use rustc_span::sym;
use smallvec::SmallVec;
@@ -87,20 +85,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ty = l
.ty
.as_ref()
- .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
+ .map(|t| self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
let init = l.kind.init().map(|init| self.lower_expr(init));
let hir_id = self.lower_node_id(l.id);
let pat = self.lower_pat(&l.pat);
let els = if let LocalKind::InitElse(_, els) = &l.kind {
- if !self.tcx.features().let_else {
- feature_err(
- &self.tcx.sess.parse_sess,
- sym::let_else,
- l.span,
- "`let...else` statements are unstable",
- )
- .emit();
- }
Some(self.lower_block(els, false))
} else {
None
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
new file mode 100644
index 000000000..c87d0ca96
--- /dev/null
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -0,0 +1,347 @@
+use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic, DiagnosticArgFromDisplay};
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_span::{symbol::Ident, Span, Symbol};
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::generic_type_with_parentheses, code = "E0214")]
+pub struct GenericTypeWithParentheses {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[subdiagnostic]
+ pub sub: Option<UseAngleBrackets>,
+}
+
+#[derive(Clone, Copy)]
+pub struct UseAngleBrackets {
+ pub open_param: Span,
+ pub close_param: Span,
+}
+
+impl AddSubdiagnostic for UseAngleBrackets {
+ fn add_to_diagnostic(self, diag: &mut Diagnostic) {
+ diag.multipart_suggestion(
+ fluent::ast_lowering::use_angle_brackets,
+ vec![(self.open_param, String::from("<")), (self.close_param, String::from(">"))],
+ Applicability::MaybeIncorrect,
+ );
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[help]
+#[diag(ast_lowering::invalid_abi, code = "E0703")]
+pub struct InvalidAbi {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub abi: Symbol,
+ pub valid_abis: String,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::assoc_ty_parentheses)]
+pub struct AssocTyParentheses {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub sub: AssocTyParenthesesSub,
+}
+
+#[derive(Clone, Copy)]
+pub enum AssocTyParenthesesSub {
+ Empty { parentheses_span: Span },
+ NotEmpty { open_param: Span, close_param: Span },
+}
+
+impl AddSubdiagnostic for AssocTyParenthesesSub {
+ fn add_to_diagnostic(self, diag: &mut Diagnostic) {
+ match self {
+ Self::Empty { parentheses_span } => diag.multipart_suggestion(
+ fluent::ast_lowering::remove_parentheses,
+ vec![(parentheses_span, String::new())],
+ Applicability::MaybeIncorrect,
+ ),
+ Self::NotEmpty { open_param, close_param } => diag.multipart_suggestion(
+ fluent::ast_lowering::use_angle_brackets,
+ vec![(open_param, String::from("<")), (close_param, String::from(">"))],
+ Applicability::MaybeIncorrect,
+ ),
+ };
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_lowering::misplaced_impl_trait, code = "E0562")]
+pub struct MisplacedImplTrait<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub position: DiagnosticArgFromDisplay<'a>,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::rustc_box_attribute_error)]
+pub struct RustcBoxAttributeError {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::underscore_expr_lhs_assign)]
+pub struct UnderscoreExprLhsAssign {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::base_expression_double_dot)]
+pub struct BaseExpressionDoubleDot {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::await_only_in_async_fn_and_blocks, code = "E0728")]
+pub struct AwaitOnlyInAsyncFnAndBlocks {
+ #[primary_span]
+ #[label]
+ pub dot_await_span: Span,
+ #[label(ast_lowering::this_not_async)]
+ pub item_span: Option<Span>,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::generator_too_many_parameters, code = "E0628")]
+pub struct GeneratorTooManyParameters {
+ #[primary_span]
+ pub fn_decl_span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::closure_cannot_be_static, code = "E0697")]
+pub struct ClosureCannotBeStatic {
+ #[primary_span]
+ pub fn_decl_span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[help]
+#[diag(ast_lowering::async_non_move_closure_not_supported, code = "E0708")]
+pub struct AsyncNonMoveClosureNotSupported {
+ #[primary_span]
+ pub fn_decl_span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::functional_record_update_destructuring_assignment)]
+pub struct FunctionalRecordUpdateDestructuringAssignemnt {
+ #[primary_span]
+ #[suggestion(code = "", applicability = "machine-applicable")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::async_generators_not_supported, code = "E0727")]
+pub struct AsyncGeneratorsNotSupported {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::inline_asm_unsupported_target, code = "E0472")]
+pub struct InlineAsmUnsupportedTarget {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::att_syntax_only_x86)]
+pub struct AttSyntaxOnlyX86 {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::abi_specified_multiple_times)]
+pub struct AbiSpecifiedMultipleTimes {
+ #[primary_span]
+ pub abi_span: Span,
+ pub prev_name: Symbol,
+ #[label]
+ pub prev_span: Span,
+ #[note]
+ pub equivalent: Option<()>,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::clobber_abi_not_supported)]
+pub struct ClobberAbiNotSupported {
+ #[primary_span]
+ pub abi_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[note]
+#[diag(ast_lowering::invalid_abi_clobber_abi)]
+pub struct InvalidAbiClobberAbi {
+ #[primary_span]
+ pub abi_span: Span,
+ pub supported_abis: String,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::invalid_register)]
+pub struct InvalidRegister<'a> {
+ #[primary_span]
+ pub op_span: Span,
+ pub reg: Symbol,
+ pub error: &'a str,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::invalid_register_class)]
+pub struct InvalidRegisterClass<'a> {
+ #[primary_span]
+ pub op_span: Span,
+ pub reg_class: Symbol,
+ pub error: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_lowering::invalid_asm_template_modifier_reg_class)]
+pub struct InvalidAsmTemplateModifierRegClass {
+ #[primary_span]
+ #[label(ast_lowering::template_modifier)]
+ pub placeholder_span: Span,
+ #[label(ast_lowering::argument)]
+ pub op_span: Span,
+ #[subdiagnostic]
+ pub sub: InvalidAsmTemplateModifierRegClassSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum InvalidAsmTemplateModifierRegClassSub {
+ #[note(ast_lowering::support_modifiers)]
+ SupportModifier { class_name: Symbol, modifiers: String },
+ #[note(ast_lowering::does_not_support_modifiers)]
+ DoesNotSupportModifier { class_name: Symbol },
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::invalid_asm_template_modifier_const)]
+pub struct InvalidAsmTemplateModifierConst {
+ #[primary_span]
+ #[label(ast_lowering::template_modifier)]
+ pub placeholder_span: Span,
+ #[label(ast_lowering::argument)]
+ pub op_span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::invalid_asm_template_modifier_sym)]
+pub struct InvalidAsmTemplateModifierSym {
+ #[primary_span]
+ #[label(ast_lowering::template_modifier)]
+ pub placeholder_span: Span,
+ #[label(ast_lowering::argument)]
+ pub op_span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::register_class_only_clobber)]
+pub struct RegisterClassOnlyClobber {
+ #[primary_span]
+ pub op_span: Span,
+ pub reg_class_name: Symbol,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::register_conflict)]
+pub struct RegisterConflict<'a> {
+ #[primary_span]
+ #[label(ast_lowering::register1)]
+ pub op_span1: Span,
+ #[label(ast_lowering::register2)]
+ pub op_span2: Span,
+ pub reg1_name: &'a str,
+ pub reg2_name: &'a str,
+ #[help]
+ pub in_out: Option<Span>,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[help]
+#[diag(ast_lowering::sub_tuple_binding)]
+pub struct SubTupleBinding<'a> {
+ #[primary_span]
+ #[label]
+ #[suggestion_verbose(
+ ast_lowering::sub_tuple_binding_suggestion,
+ code = "..",
+ applicability = "maybe-incorrect"
+ )]
+ pub span: Span,
+ pub ident: Ident,
+ pub ident_name: Symbol,
+ pub ctx: &'a str,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::extra_double_dot)]
+pub struct ExtraDoubleDot<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[label(ast_lowering::previously_used_here)]
+ pub prev_span: Span,
+ pub ctx: &'a str,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[note]
+#[diag(ast_lowering::misplaced_double_dot)]
+pub struct MisplacedDoubleDot {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::misplaced_relax_trait_bound)]
+pub struct MisplacedRelaxTraitBound {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::not_supported_for_lifetime_binder_async_closure)]
+pub struct NotSupportedForLifetimeBinderAsyncClosure {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::arbitrary_expression_in_pattern)]
+pub struct ArbitraryExpressionInPattern {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::inclusive_range_with_no_end)]
+pub struct InclusiveRangeWithNoEnd {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[diag(ast_lowering::trait_fn_async, code = "E0706")]
+#[note]
+#[note(ast_lowering::note2)]
+pub struct TraitFnAsync {
+ #[primary_span]
+ pub fn_span: Span,
+ #[label]
+ pub span: Span,
+}
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index fb6715ff1..7b8070d3c 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1,19 +1,23 @@
+use super::errors::{
+ AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
+ BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt,
+ GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure,
+ RustcBoxAttributeError, UnderscoreExprLhsAssign,
+};
use super::ResolverAstLoweringExt;
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
use crate::{FnDeclKind, ImplTraitPosition};
-
use rustc_ast::attr;
use rustc_ast::ptr::P as AstP;
use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_data_structures::thin_vec::ThinVec;
-use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::definitions::DefPathData;
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
use rustc_span::symbol::{sym, Ident};
use rustc_span::DUMMY_SP;
+use thin_vec::thin_vec;
impl<'hir> LoweringContext<'_, 'hir> {
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
@@ -46,13 +50,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let hir_id = self.lower_node_id(e.id);
return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
} else {
- self.tcx.sess
- .struct_span_err(
- e.span,
- "#[rustc_box] requires precisely one argument \
- and no other attributes are allowed",
- )
- .emit();
+ self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span });
hir::ExprKind::Err
}
} else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
@@ -68,10 +66,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
seg,
ParamMode::Optional,
ParenthesizedGenericArgs::Err,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
));
- let args = self.lower_exprs(args);
- hir::ExprKind::MethodCall(hir_seg, args, self.lower_span(span))
+ let receiver = self.lower_expr(&args[0]);
+ let args =
+ self.arena.alloc_from_iter(args[1..].iter().map(|x| self.lower_expr_mut(x)));
+ hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(span))
}
ExprKind::Binary(binop, ref lhs, ref rhs) => {
let binop = self.lower_binop(binop);
@@ -90,13 +90,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Cast(ref expr, ref ty) => {
let expr = self.lower_expr(expr);
let ty =
- self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ExprKind::Cast(expr, ty)
}
ExprKind::Type(ref expr, ref ty) => {
let expr = self.lower_expr(expr);
let ty =
- self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ExprKind::Type(expr, ty)
}
ExprKind::AddrOf(k, m, ref ohs) => {
@@ -146,13 +146,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
),
ExprKind::Await(ref expr) => {
- let span = if expr.span.hi() < e.span.hi() {
- expr.span.shrink_to_hi().with_hi(e.span.hi())
+ let dot_await_span = if expr.span.hi() < e.span.hi() {
+ let span_with_whitespace = self
+ .tcx
+ .sess
+ .source_map()
+ .span_extend_while(expr.span, char::is_whitespace)
+ .unwrap_or(expr.span);
+ span_with_whitespace.shrink_to_hi().with_hi(e.span.hi())
} else {
// this is a recovered `await expr`
e.span
};
- self.lower_expr_await(span, expr)
+ self.lower_expr_await(dot_await_span, expr)
}
ExprKind::Closure(
ref binder,
@@ -210,13 +216,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
}
ExprKind::Underscore => {
- self.tcx
- .sess.struct_span_err(
- e.span,
- "in expressions, `_` can only be used on the left-hand side of an assignment",
- )
- .span_label(e.span, "`_` not allowed here")
- .emit();
+ self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
hir::ExprKind::Err
}
ExprKind::Path(ref qself, ref path) => {
@@ -225,7 +225,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
hir::ExprKind::Path(qpath)
}
@@ -248,11 +248,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let rest = match &se.rest {
StructRest::Base(e) => Some(self.lower_expr(e)),
StructRest::Rest(sp) => {
- self.tcx
- .sess
- .struct_span_err(*sp, "base expression required after `..`")
- .span_label(*sp, "add a base expression here")
- .emit();
+ self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp });
Some(&*self.arena.alloc(self.expr_err(*sp)))
}
StructRest::None => None,
@@ -263,7 +259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&se.qself,
&se.path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
)),
self.arena
.alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -446,12 +442,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond));
let new_cond = self.manage_let_cond(lowered_cond);
let then = self.lower_block_expr(body);
- let expr_break = self.expr_break(span, ThinVec::new());
+ let expr_break = self.expr_break(span, AttrVec::new());
let stmt_break = self.stmt_expr(span, expr_break);
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
- let else_expr = self.arena.alloc(self.expr_block(else_blk, ThinVec::new()));
+ let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
- let if_expr = self.expr(span, if_kind, ThinVec::new());
+ let if_expr = self.expr(span, if_kind, AttrVec::new());
let block = self.block_expr(self.arena.alloc(if_expr));
let span = self.lower_span(span.with_hi(cond.span.hi()));
let opt_label = self.lower_label(opt_label);
@@ -510,7 +506,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let constructor = self.arena.alloc(self.expr_lang_item_path(
method_span,
lang_item,
- ThinVec::new(),
+ AttrVec::new(),
None,
));
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
@@ -562,7 +558,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::ExprKind<'hir> {
let output = match ret_ty {
Some(ty) => hir::FnRetTy::Return(
- self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
+ self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
),
None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
};
@@ -587,7 +583,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (pat, task_context_hid) = self.pat_ident_binding_mode(
span,
Ident::with_dummy_span(sym::_task_context),
- hir::BindingAnnotation::Mutable,
+ hir::BindingAnnotation::MUT,
);
let param = hir::Param {
hir_id: self.next_id(),
@@ -633,7 +629,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let gen_future = self.expr_lang_item_path(
unstable_span,
hir::LangItem::FromGenerator,
- ThinVec::new(),
+ AttrVec::new(),
None,
);
@@ -661,17 +657,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
match self.generator_kind {
Some(hir::GeneratorKind::Async(_)) => {}
Some(hir::GeneratorKind::Gen) | None => {
- let mut err = struct_span_err!(
- self.tcx.sess,
+ self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
dot_await_span,
- E0728,
- "`await` is only allowed inside `async` functions and blocks"
- );
- err.span_label(dot_await_span, "only allowed inside `async` functions and blocks");
- if let Some(item_sp) = self.current_item {
- err.span_label(item_sp, "this is not `async`");
- }
- err.emit();
+ item_span: self.current_item,
+ });
}
}
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
@@ -688,7 +677,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// this name to identify what is being awaited by a suspended async functions.
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
let (awaitee_pat, awaitee_pat_hid) =
- self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable);
+ self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::MUT);
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
@@ -745,7 +734,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break =
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
- this.arena.alloc(this.expr(gen_future_span, expr_break, ThinVec::new()))
+ this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new()))
});
self.arm(ready_pat, break_x)
};
@@ -778,7 +767,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let yield_expr = self.expr(
span,
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
- ThinVec::new(),
+ AttrVec::new(),
);
let yield_expr = self.arena.alloc(yield_expr);
@@ -866,7 +855,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
// Lower outside new scope to preserve `is_in_loop_condition`.
- let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
+ let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None);
let c = self.arena.alloc(hir::Closure {
binder: binder_clause,
@@ -891,13 +880,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
match generator_kind {
Some(hir::GeneratorKind::Gen) => {
if decl.inputs.len() > 1 {
- struct_span_err!(
- self.tcx.sess,
- fn_decl_span,
- E0628,
- "too many parameters for a generator (expected 0 or 1 parameters)"
- )
- .emit();
+ self.tcx.sess.emit_err(GeneratorTooManyParameters { fn_decl_span });
}
Some(movability)
}
@@ -906,13 +889,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
None => {
if movability == Movability::Static {
- struct_span_err!(
- self.tcx.sess,
- fn_decl_span,
- E0697,
- "closures cannot be static"
- )
- .emit();
+ self.tcx.sess.emit_err(ClosureCannotBeStatic { fn_decl_span });
}
None
}
@@ -945,10 +922,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl_span: Span,
) -> hir::ExprKind<'hir> {
if let &ClosureBinder::For { span, .. } = binder {
- self.tcx.sess.span_err(
- span,
- "`for<...>` binders on `async` closures are not currently supported",
- );
+ self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
}
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
@@ -959,17 +933,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
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!(
- this.tcx.sess,
- fn_decl_span,
- E0708,
- "`async` non-`move` closures with parameters are not currently supported",
- )
- .help(
- "consider using `let` statements to manually capture \
- variables by reference before entering an `async move` closure",
- )
- .emit();
+ this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span });
}
// Transform `async |x: u8| -> X { ... }` into
@@ -985,17 +949,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AsyncGeneratorKind::Closure,
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
);
- this.expr(fn_decl_span, async_body, ThinVec::new())
+ this.expr(fn_decl_span, async_body, AttrVec::new())
});
body_id
});
let bound_generic_params = self.lower_lifetime_binder(closure_id, 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 = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
+ let fn_decl =
+ self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None);
let c = self.arena.alloc(hir::Closure {
binder: binder_clause,
@@ -1165,11 +1129,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
// Destructure like a tuple struct.
- let tuple_struct_pat =
- hir::PatKind::TupleStruct(qpath, pats, rest.map(|r| r.0));
+ let tuple_struct_pat = hir::PatKind::TupleStruct(
+ qpath,
+ pats,
+ hir::DotDotPos::new(rest.map(|r| r.0)),
+ );
return self.pat_without_dbm(lhs.span, tuple_struct_pat);
}
}
@@ -1181,7 +1148,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
// Destructure like a unit struct.
let unit_struct_pat = hir::PatKind::Path(qpath);
@@ -1205,24 +1172,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
&se.qself,
&se.path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
let fields_omitted = match &se.rest {
StructRest::Base(e) => {
- self.tcx
- .sess
- .struct_span_err(
- e.span,
- "functional record updates are not allowed in destructuring \
- assignments",
- )
- .span_suggestion(
- e.span,
- "consider removing the trailing pattern",
- "",
- rustc_errors::Applicability::MachineApplicable,
- )
- .emit();
+ self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignemnt {
+ span: e.span,
+ });
true
}
StructRest::Rest(_) => true,
@@ -1235,13 +1191,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Tup(elements) => {
let (pats, rest) =
self.destructure_sequence(elements, "tuple", eq_sign_span, assignments);
- let tuple_pat = hir::PatKind::Tuple(pats, rest.map(|r| r.0));
+ let tuple_pat = hir::PatKind::Tuple(pats, hir::DotDotPos::new(rest.map(|r| r.0)));
return self.pat_without_dbm(lhs.span, tuple_pat);
}
ExprKind::Paren(e) => {
// We special-case `(..)` for consistency with patterns.
if let ExprKind::Range(None, None, RangeLimits::HalfOpen) = e.kind {
- let tuple_pat = hir::PatKind::Tuple(&[], Some(0));
+ let tuple_pat = hir::PatKind::Tuple(&[], hir::DotDotPos::new(Some(0)));
return self.pat_without_dbm(lhs.span, tuple_pat);
} else {
return self.destructure_assign_mut(e, eq_sign_span, assignments);
@@ -1255,7 +1211,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ident = self.expr_ident(lhs.span, ident, binding);
let assign =
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
- let expr = self.expr(lhs.span, assign, ThinVec::new());
+ let expr = self.expr(lhs.span, assign, AttrVec::new());
assignments.push(self.stmt_expr(lhs.span, expr));
pat
}
@@ -1297,7 +1253,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let fn_path =
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
let fn_expr =
- self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
+ self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
}
@@ -1317,7 +1273,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
(Some(..), Some(..), HalfOpen) => hir::LangItem::Range,
(None, Some(..), Closed) => hir::LangItem::RangeToInclusive,
(Some(..), Some(..), Closed) => unreachable!(),
- (_, None, Closed) => self.diagnostic().span_fatal(span, "inclusive range with no end"),
+ (start, None, Closed) => {
+ self.tcx.sess.emit_err(InclusiveRangeWithNoEnd { span });
+ match start {
+ Some(..) => hir::LangItem::RangeFrom,
+ None => hir::LangItem::RangeFull,
+ }
+ }
};
let fields = self.arena.alloc_from_iter(
@@ -1404,8 +1366,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
+ let hir_id = self.lower_node_id(f.id);
+ self.lower_attrs(hir_id, &f.attrs);
hir::ExprField {
- hir_id: self.next_id(),
+ hir_id,
ident: self.lower_ident(f.ident),
expr: self.lower_expr(&f.expr),
span: self.lower_span(f.span),
@@ -1417,13 +1381,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
match self.generator_kind {
Some(hir::GeneratorKind::Gen) => {}
Some(hir::GeneratorKind::Async(_)) => {
- struct_span_err!(
- self.tcx.sess,
- span,
- E0727,
- "`async` generators are not yet supported"
- )
- .emit();
+ self.tcx.sess.emit_err(AsyncGeneratorsNotSupported { span });
}
None => self.generator_kind = Some(hir::GeneratorKind::Gen),
}
@@ -1468,7 +1426,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `None => break`
let none_arm = {
let break_expr =
- self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, ThinVec::new()));
+ self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
let pat = self.pat_none(for_span);
self.arm(pat, break_expr)
};
@@ -1477,14 +1435,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
let some_arm = {
let some_pat = self.pat_some(pat_span, pat);
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
- let body_expr = self.arena.alloc(self.expr_block(body_block, ThinVec::new()));
+ let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new()));
self.arm(some_pat, body_expr)
};
// `mut iter`
let iter = Ident::with_dummy_span(sym::iter);
let (iter_pat, iter_pat_nid) =
- self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::Mutable);
+ self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::MUT);
// `match Iterator::next(&mut iter) { ... }`
let match_expr = {
@@ -1534,15 +1492,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::MatchSource::ForLoopDesugar,
));
- let attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
-
// This is effectively `{ let _result = ...; _result }`.
// The construct was introduced in #21984 and is necessary to make sure that
// temporaries in the `head` expression are dropped and do not leak to the
// surrounding scope of the `match` since the `match` is not a terminating scope.
//
// Also, add the attributes to the outer returned expr node.
- self.expr_drop_temps_mut(for_span, match_expr, attrs.into())
+ self.expr_drop_temps_mut(for_span, match_expr, e.attrs.clone())
}
/// Desugar `ExprKind::Try` from: `<expr>?` into:
@@ -1592,9 +1548,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let uc_nested = attr::mk_nested_word_item(uc_ident);
attr::mk_list_item(allow_ident, vec![uc_nested])
};
- attr::mk_attr_outer(allow)
+ attr::mk_attr_outer(&self.tcx.sess.parse_sess.attr_id_generator, allow)
};
- let attrs = vec![attr];
+ let attrs: AttrVec = thin_vec![attr];
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
let continue_arm = {
@@ -1604,7 +1560,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
val_ident,
val_pat_nid,
- ThinVec::from(attrs.clone()),
+ attrs.clone(),
));
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr)
@@ -1623,7 +1579,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(residual_expr),
unstable_span,
);
- let thin_attrs = ThinVec::from(attrs);
let ret_expr = if let Some(catch_node) = self.catch_scope {
let target_id = Ok(self.lower_node_id(catch_node));
self.arena.alloc(self.expr(
@@ -1632,13 +1587,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Destination { label: None, target_id },
Some(from_residual_expr),
),
- thin_attrs,
+ attrs,
))
} else {
self.arena.alloc(self.expr(
try_span,
hir::ExprKind::Ret(Some(from_residual_expr)),
- thin_attrs,
+ attrs,
))
};
@@ -1726,7 +1681,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
arms: &'hir [hir::Arm<'hir>],
source: hir::MatchSource,
) -> hir::Expr<'hir> {
- self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new())
+ self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new())
}
fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> {
@@ -1743,12 +1698,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr(
span,
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
- ThinVec::new(),
+ AttrVec::new(),
)
}
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
- self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new()))
+ self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new()))
}
fn expr_call_mut(
@@ -1757,7 +1712,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
e: &'hir hir::Expr<'hir>,
args: &'hir [hir::Expr<'hir>],
) -> hir::Expr<'hir> {
- self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
+ self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new())
}
fn expr_call(
@@ -1777,7 +1732,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> {
let path =
- self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id));
+ self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
self.expr_call_mut(span, path, args)
}
@@ -1820,7 +1775,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: Ident,
binding: hir::HirId,
) -> hir::Expr<'hir> {
- self.expr_ident_with_attrs(sp, ident, binding, ThinVec::new())
+ self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new())
}
fn expr_ident_with_attrs(
@@ -1830,12 +1785,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
binding: hir::HirId,
attrs: AttrVec,
) -> hir::Expr<'hir> {
+ let hir_id = self.next_id();
+ let res = Res::Local(binding);
let expr_path = hir::ExprKind::Path(hir::QPath::Resolved(
None,
self.arena.alloc(hir::Path {
span: self.lower_span(span),
- res: Res::Local(binding),
- segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
+ res,
+ segments: arena_vec![self; hir::PathSegment::new(ident, hir_id, res)],
}),
));
@@ -1858,13 +1815,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
}),
None,
),
- ThinVec::new(),
+ AttrVec::new(),
)
}
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
let blk = self.block_all(span, &[], None);
- let expr = self.expr_block(blk, ThinVec::new());
+ let expr = self.expr_block(blk, AttrVec::new());
self.arena.alloc(expr)
}
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index d5af74d47..85846b567 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -11,8 +11,6 @@ use rustc_session::Session;
use rustc_span::source_map::SourceMap;
use rustc_span::{Span, DUMMY_SP};
-use tracing::debug;
-
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
pub(super) struct NodeCollector<'a, 'hir> {
/// Source map
@@ -31,7 +29,7 @@ pub(super) struct NodeCollector<'a, 'hir> {
definitions: &'a definitions::Definitions,
}
-#[tracing::instrument(level = "debug", skip(sess, definitions, bodies))]
+#[instrument(level = "debug", skip(sess, definitions, bodies))]
pub(super) fn index_hir<'hir>(
sess: &Session,
definitions: &definitions::Definitions,
@@ -67,10 +65,11 @@ pub(super) fn index_hir<'hir>(
}
impl<'a, 'hir> NodeCollector<'a, 'hir> {
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
debug_assert_eq!(self.owner, hir_id.owner);
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
+ debug_assert_ne!(hir_id.local_id, self.parent_node);
// Make sure that the DepNode of some node coincides with the HirId
// owner of that node.
@@ -142,7 +141,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_item(&mut self, i: &'hir Item<'hir>) {
debug_assert_eq!(i.def_id, self.owner);
self.with_parent(i.hir_id(), |this| {
@@ -156,7 +155,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
debug_assert_eq!(fi.def_id, self.owner);
self.with_parent(fi.hir_id(), |this| {
@@ -175,7 +174,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
})
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
debug_assert_eq!(ti.def_id, self.owner);
self.with_parent(ti.hir_id(), |this| {
@@ -183,7 +182,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
debug_assert_eq!(ii.def_id, self.owner);
self.with_parent(ii.hir_id(), |this| {
@@ -199,6 +198,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
+ fn visit_pat_field(&mut self, field: &'hir PatField<'hir>) {
+ self.insert(field.span, field.hir_id, Node::PatField(field));
+ self.with_parent(field.hir_id, |this| {
+ intravisit::walk_pat_field(this, field);
+ });
+ }
+
fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
let node = Node::Arm(arm);
@@ -225,6 +231,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
+ fn visit_expr_field(&mut self, field: &'hir ExprField<'hir>) {
+ self.insert(field.span, field.hir_id, Node::ExprField(field));
+ self.with_parent(field.hir_id, |this| {
+ intravisit::walk_expr_field(this, field);
+ });
+ }
+
fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
@@ -233,11 +246,9 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment<'hir>) {
- if let Some(hir_id) = path_segment.hir_id {
- self.insert(path_span, hir_id, Node::PathSegment(path_segment));
- }
- intravisit::walk_path_segment(self, path_span, path_segment);
+ fn visit_path_segment(&mut self, path_segment: &'hir PathSegment<'hir>) {
+ self.insert(path_segment.ident.span, path_segment.hir_id, Node::PathSegment(path_segment));
+ intravisit::walk_path_segment(self, path_segment);
}
fn visit_ty(&mut self, ty: &'hir Ty<'hir>) {
@@ -269,12 +280,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fk: intravisit::FnKind<'hir>,
fd: &'hir FnDecl<'hir>,
b: BodyId,
- s: Span,
+ _: Span,
id: HirId,
) {
assert_eq!(self.owner, id.owner);
assert_eq!(self.parent_node, id.local_id);
- intravisit::walk_fn(self, fk, fd, b, s, id);
+ intravisit::walk_fn(self, fk, fd, b, id);
}
fn visit_block(&mut self, block: &'hir Block<'hir>) {
@@ -295,14 +306,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime));
}
- fn visit_variant(&mut self, v: &'hir Variant<'hir>, g: &'hir Generics<'hir>, item_id: HirId) {
+ fn visit_variant(&mut self, v: &'hir Variant<'hir>) {
self.insert(v.span, v.id, Node::Variant(v));
self.with_parent(v.id, |this| {
// Register the constructor of this variant.
if let Some(ctor_hir_id) = v.data.ctor_hir_id() {
this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data));
}
- intravisit::walk_variant(this, v, g, item_id);
+ intravisit::walk_variant(this, v);
});
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index ee4c0036f..550833275 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,5 +1,6 @@
+use super::errors::{InvalidAbi, MisplacedRelaxTraitBound};
use super::ResolverAstLoweringExt;
-use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
+use super::{Arena, AstOwner, ImplTraitContext, ImplTraitPosition};
use super::{FnDeclKind, LoweringContext, ParamMode};
use rustc_ast::ptr::P;
@@ -7,7 +8,6 @@ use rustc_ast::visit::AssocCtxt;
use rustc_ast::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sorted_map::SortedMap;
-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};
@@ -25,6 +25,7 @@ use std::iter;
pub(super) struct ItemLowerer<'a, 'hir> {
pub(super) tcx: TyCtxt<'hir>,
pub(super) resolver: &'a mut ResolverAstLowering,
+ pub(super) ast_arena: &'a Arena<'static>,
pub(super) ast_index: &'a IndexVec<LocalDefId, AstOwner<'a>>,
pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
}
@@ -60,6 +61,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
tcx: self.tcx,
resolver: self.resolver,
arena: self.tcx.hir_arena,
+ ast_arena: self.ast_arena,
// HirId handling.
bodies: Vec::new(),
@@ -85,6 +87,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
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()),
+ generics_def_id_map: Default::default(),
};
lctx.with_hir_id_owner(owner, |lctx| f(lctx));
@@ -120,7 +123,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
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);
- hir::OwnerNode::Crate(lctx.arena.alloc(module))
+ hir::OwnerNode::Crate(module)
})
}
@@ -158,14 +161,18 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
}
impl<'hir> LoweringContext<'_, 'hir> {
- pub(super) fn lower_mod(&mut self, items: &[P<Item>], spans: &ModSpans) -> hir::Mod<'hir> {
- hir::Mod {
+ pub(super) fn lower_mod(
+ &mut self,
+ items: &[P<Item>],
+ spans: &ModSpans,
+ ) -> &'hir hir::Mod<'hir> {
+ self.arena.alloc(hir::Mod {
spans: hir::ModSpans {
inner_span: self.lower_span(spans.inner_span),
inject_use_span: self.lower_span(spans.inject_use_span),
},
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
- }
+ })
}
pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
@@ -259,10 +266,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
let body_id =
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
- let itctx = ImplTraitContext::Universal;
- let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {
+ let mut itctx = ImplTraitContext::Universal;
+ let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
let ret_id = asyncness.opt_return_id();
- this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id)
+ this.lower_fn_decl(&decl, Some(id), fn_sig_span, FnDeclKind::Fn, ret_id)
});
let sig = hir::FnSig {
decl,
@@ -306,8 +313,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, ty) = self.lower_generics(
&generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
- |this| this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ |this| this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy),
);
hir::ItemKind::TyAlias(ty, generics)
}
@@ -319,7 +326,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, ty) = self.lower_generics(
&generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.arena.alloc(this.ty(span, hir::TyKind::Err)),
);
hir::ItemKind::TyAlias(ty, generics)
@@ -328,7 +335,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, variants) = self.lower_generics(
generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
this.arena.alloc_from_iter(
enum_definition.variants.iter().map(|x| this.lower_variant(x)),
@@ -341,7 +348,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, struct_def) = self.lower_generics(
generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, struct_def),
);
hir::ItemKind::Struct(struct_def, generics)
@@ -350,7 +357,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, vdata) = self.lower_generics(
generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, vdata),
);
hir::ItemKind::Union(vdata, generics)
@@ -378,18 +385,18 @@ 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 mut itctx = ImplTraitContext::Universal;
let (generics, (trait_ref, lowered_ty)) =
- self.lower_generics(ast_generics, id, itctx, |this| {
+ self.lower_generics(ast_generics, id, &mut itctx, |this| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
this.lower_trait_ref(
trait_ref,
- ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
)
});
let lowered_ty = this
- .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(trait_ref, lowered_ty)
});
@@ -428,11 +435,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, (unsafety, items, bounds)) = self.lower_generics(
generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let bounds = this.lower_param_bounds(
bounds,
- ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
);
let items = this.arena.alloc_from_iter(
items.iter().map(|item| this.lower_trait_item_ref(item)),
@@ -447,11 +454,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, bounds) = self.lower_generics(
generics,
id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
this.lower_param_bounds(
bounds,
- ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
},
);
@@ -474,7 +481,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
body: Option<&Expr>,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
- let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(ty, self.lower_const_body(span, body))
}
@@ -647,12 +654,18 @@ 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 mut itctx = ImplTraitContext::Universal;
let (generics, (fn_dec, fn_args)) =
- self.lower_generics(generics, i.id, itctx, |this| {
+ self.lower_generics(generics, i.id, &mut itctx, |this| {
(
// Disallow `impl Trait` in foreign items.
- this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
+ this.lower_fn_decl(
+ fdec,
+ None,
+ sig.span,
+ FnDeclKind::ExternFn,
+ None,
+ ),
this.lower_fn_params_to_names(fdec),
)
});
@@ -661,7 +674,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ForeignItemKind::Static(ref t, m, _) => {
let ty =
- self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ForeignItemKind::Static(ty, m)
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@@ -729,11 +742,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
self.arena.alloc(t)
} else {
- self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+ self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type))
};
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
@@ -756,14 +769,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, kind, has_default) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => {
- let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
+ let asyncness = sig.header.asyncness;
let names = self.lower_fn_params_to_names(&sig.decl);
- let (generics, sig) =
- self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
+ let (generics, sig) = self.lower_method_sig(
+ generics,
+ sig,
+ i.id,
+ FnDeclKind::Trait,
+ asyncness.opt_return_id(),
+ );
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
@@ -791,15 +810,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, kind) = self.lower_generics(
&generics,
i.id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = ty.as_ref().map(|x| {
- this.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+ this.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type))
});
hir::TraitItemKind::Type(
this.lower_param_bounds(
bounds,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
ty,
)
@@ -852,7 +871,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, kind) = match &i.kind {
AssocItemKind::Const(_, ty, expr) => {
- let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(
hir::Generics::empty(),
hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
@@ -879,14 +898,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_generics(
&generics,
i.id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|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);
+ let ty = this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy);
hir::ImplItemKind::TyAlias(ty)
}
},
@@ -947,7 +966,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
params: &'hir [hir::Param<'hir>],
value: hir::Expr<'hir>,
) -> hir::BodyId {
- let body = hir::Body { generator_kind: self.generator_kind, params, value };
+ let body = hir::Body {
+ generator_kind: self.generator_kind,
+ params,
+ value: self.arena.alloc(value),
+ };
let id = body.id();
debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
@@ -1074,12 +1097,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Check if this is a binding pattern, if so, we can optimize and avoid adding a
// `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
let (ident, is_simple_parameter) = match parameter.pat.kind {
- hir::PatKind::Binding(
- hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
- _,
- ident,
- _,
- ) => (ident, true),
+ hir::PatKind::Binding(hir::BindingAnnotation(ByRef::No, _), _, ident, _) => {
+ (ident, true)
+ }
// For `ref mut` or wildcard arguments, we can't reuse the binding, but
// we can keep the same name for the parameter.
// This lets rustdoc render it correctly in documentation.
@@ -1144,7 +1164,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (move_pat, move_id) = this.pat_ident_binding_mode(
desugared_span,
ident,
- hir::BindingAnnotation::Mutable,
+ hir::BindingAnnotation::MUT,
);
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
let move_stmt = this.stmt_let_pat(
@@ -1225,12 +1245,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
sig: &FnSig,
id: NodeId,
kind: FnDeclKind,
- is_async: Option<NodeId>,
+ is_async: Option<(NodeId, Span)>,
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
let header = self.lower_fn_header(sig.header);
- 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)
+ let mut itctx = ImplTraitContext::Universal;
+ let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| {
+ this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async)
});
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
}
@@ -1260,10 +1280,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn error_on_invalid_abi(&self, abi: StrLit) {
- struct_span_err!(self.tcx.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
- .span_label(abi.span, "invalid ABI")
- .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
- .emit();
+ self.tcx.sess.emit_err(InvalidAbi {
+ span: abi.span,
+ abi: abi.symbol,
+ valid_abis: abi::all_names().join(", "),
+ });
}
fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
@@ -1294,7 +1315,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
generics: &Generics,
parent_node_id: NodeId,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
f: impl FnOnce(&mut Self) -> T,
) -> (&'hir hir::Generics<'hir>, T) {
debug_assert!(self.impl_trait_defs.is_empty());
@@ -1338,11 +1359,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
let is_param = *is_param.get_or_insert_with(compute_is_param);
if !is_param {
- self.diagnostic().span_err(
- bound.span(),
- "`?Trait` bounds are only permitted at the \
- point where a type parameter is declared",
- );
+ self.tcx.sess.emit_err(MisplacedRelaxTraitBound { span: bound.span() });
}
}
}
@@ -1403,7 +1420,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
id: NodeId,
kind: &GenericParamKind,
bounds: &[GenericBound],
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
origin: PredicateOrigin,
) -> Option<hir::WherePredicate<'hir>> {
// Do not create a clause if we do not have anything inside it.
@@ -1434,10 +1451,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
GenericParamKind::Const { .. } => None,
GenericParamKind::Type { .. } => {
let def_id = self.local_def_id(id).to_def_id();
+ let hir_id = self.next_id();
+ let res = Res::Def(DefKind::TyParam, def_id);
let ty_path = self.arena.alloc(hir::Path {
span: param_span,
- res: Res::Def(DefKind::TyParam, def_id),
- segments: self.arena.alloc_from_iter([hir::PathSegment::from_ident(ident)]),
+ res,
+ segments: self
+ .arena
+ .alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),
});
let ty_id = self.next_id();
let bounded_ty =
@@ -1475,11 +1496,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
}) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params: self.lower_generic_params(bound_generic_params),
bounded_ty: self
- .lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+ .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
bounds: self.arena.alloc_from_iter(bounds.iter().map(|bound| {
self.lower_param_bound(
bound,
- ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
})),
span: self.lower_span(span),
@@ -1494,17 +1515,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
lifetime: self.lower_lifetime(lifetime),
bounds: self.lower_param_bounds(
bounds,
- ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
in_where_clause: true,
}),
- WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
+ WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
- hir_id: self.lower_node_id(id),
lhs_ty: self
- .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+ .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
rhs_ty: self
- .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+ .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
span: self.lower_span(span),
})
}
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 224dc3c23..9012aa704 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -32,14 +32,20 @@
#![feature(box_patterns)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
+use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait, TraitFnAsync};
+
+use rustc_arena::declare_arena;
+use rustc_ast::ptr::P;
use rustc_ast::visit;
use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
@@ -49,7 +55,7 @@ use rustc_data_structures::fx::FxHashMap;
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, Applicability, Handler};
+use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
@@ -75,6 +81,7 @@ macro_rules! arena_vec {
mod asm;
mod block;
+mod errors;
mod expr;
mod index;
mod item;
@@ -89,6 +96,13 @@ struct LoweringContext<'a, 'hir> {
/// Used to allocate HIR nodes.
arena: &'hir hir::Arena<'hir>,
+ /// Used to allocate temporary AST nodes for use during lowering.
+ /// This allows us to create "fake" AST -- these nodes can sometimes
+ /// be allocated on the stack, but other times we need them to live longer
+ /// than the current stack frame, so they can be collected into vectors
+ /// and things like that.
+ ast_arena: &'a Arena<'static>,
+
/// Bodies inside the owner being lowered.
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
/// Attributes inside the owner being lowered.
@@ -126,8 +140,23 @@ struct LoweringContext<'a, 'hir> {
allow_try_trait: Option<Lrc<[Symbol]>>,
allow_gen_future: Option<Lrc<[Symbol]>>,
allow_into_future: Option<Lrc<[Symbol]>>,
+
+ /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
+ /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
+ /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
+ /// field from the original parameter 'a to the new parameter 'a1.
+ generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
}
+declare_arena!([
+ [] tys: rustc_ast::Ty,
+ [] aba: rustc_ast::AngleBracketedArgs,
+ [] ptr: rustc_ast::PolyTraitRef,
+ // This _marker field is needed because `declare_arena` creates `Arena<'tcx>` and we need to
+ // use `'tcx`. If we don't have this we get a compile error.
+ [] _marker: std::marker::PhantomData<&'tcx ()>,
+]);
+
trait ResolverAstLoweringExt {
fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
@@ -136,12 +165,6 @@ trait ResolverAstLoweringExt {
fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind;
- /// Record the map from `from` local def id to `to` local def id, on `generics_def_id_map`
- /// field.
- fn record_def_id_remap(&mut self, from: LocalDefId, to: LocalDefId);
- /// Get the previously recorded `to` local def id given the `from` local def id, obtained using
- /// `generics_def_id_map` field.
- fn get_remapped_def_id(&self, local_def_id: LocalDefId) -> LocalDefId;
}
impl ResolverAstLoweringExt for ResolverAstLowering {
@@ -209,41 +232,6 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind {
self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang)
}
-
- /// Push a remapping into the top-most map.
- /// Panics if no map has been pushed.
- /// Remapping is used when creating lowering `-> impl Trait` return
- /// types to create the resulting opaque type.
- #[tracing::instrument(level = "debug", skip(self))]
- fn record_def_id_remap(&mut self, from: LocalDefId, to: LocalDefId) {
- self.generics_def_id_map.last_mut().expect("no map pushed").insert(from, to);
- }
-
- fn get_remapped_def_id(&self, mut local_def_id: LocalDefId) -> LocalDefId {
- // `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we
- // push new mappings so we need to try first the latest mappings, hence `iter().rev()`.
- //
- // Consider:
- //
- // `fn test<'a, 'b>() -> impl Trait<&'a u8, Ty = impl Sized + 'b> {}`
- //
- // We would end with a generics_def_id_map like:
- //
- // `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]`
- //
- // for the opaque type generated on `impl Sized + 'b`, We want the result to be:
- // impl_sized#'b, so iterating forward is the wrong thing to do.
- for map in self.generics_def_id_map.iter().rev() {
- if let Some(r) = map.get(&local_def_id) {
- debug!("def_id_remapper: remapping from `{local_def_id:?}` to `{r:?}`");
- local_def_id = *r;
- } else {
- debug!("def_id_remapper: no remapping for `{local_def_id:?}` found in map");
- }
- }
-
- local_def_id
- }
}
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
@@ -264,6 +252,7 @@ enum ImplTraitContext {
ReturnPositionOpaqueTy {
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
origin: hir::OpaqueTyOrigin,
+ in_trait: bool,
},
/// Impl trait in type aliases.
TypeAliasesOpaqueTy,
@@ -323,7 +312,7 @@ impl std::fmt::Display for ImplTraitPosition {
}
}
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq)]
enum FnDeclKind {
Fn,
Inherent,
@@ -335,9 +324,17 @@ enum FnDeclKind {
}
impl FnDeclKind {
- fn impl_trait_return_allowed(&self) -> bool {
+ fn impl_trait_return_allowed(&self, tcx: TyCtxt<'_>) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true,
+ FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true,
+ _ => false,
+ }
+ }
+
+ fn impl_trait_in_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
+ match self {
+ FnDeclKind::Trait if tcx.features().return_position_impl_trait_in_trait => true,
_ => false,
}
}
@@ -430,10 +427,13 @@ pub fn lower_to_hir<'hir>(tcx: TyCtxt<'hir>, (): ()) -> hir::Crate<'hir> {
tcx.definitions_untracked().def_index_count(),
);
+ let ast_arena = Arena::default();
+
for def_id in ast_index.indices() {
item::ItemLowerer {
tcx,
resolver: &mut resolver,
+ ast_arena: &ast_arena,
ast_index: &ast_index,
owners: &mut owners,
}
@@ -500,6 +500,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
/// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
+ /// resolver (if any).
+ fn orig_opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
+ self.resolver.node_id_to_def_id.get(&node).map(|local_def_id| *local_def_id)
+ }
+
+ fn orig_local_def_id(&self, node: NodeId) -> LocalDefId {
+ self.orig_opt_local_def_id(node)
+ .unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node))
+ }
+
+ /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
/// resolver (if any), after applying any remapping from `get_remapped_def_id`.
///
/// For example, in a function like `fn foo<'a>(x: &'a u32)`,
@@ -513,16 +524,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// we would create an opaque type `type FooReturn<'a1> = impl Debug + 'a1`.
/// When lowering the `Debug + 'a` bounds, we add a remapping to map `'a` to `'a1`.
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
- self.resolver
- .node_id_to_def_id
- .get(&node)
- .map(|local_def_id| self.resolver.get_remapped_def_id(*local_def_id))
+ self.orig_opt_local_def_id(node).map(|local_def_id| self.get_remapped_def_id(local_def_id))
}
fn local_def_id(&self, node: NodeId) -> LocalDefId {
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node))
}
+ /// Get the previously recorded `to` local def id given the `from` local def id, obtained using
+ /// `generics_def_id_map` field.
+ fn get_remapped_def_id(&self, local_def_id: LocalDefId) -> LocalDefId {
+ // `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we
+ // push new mappings, so we first need to get the latest (innermost) mappings, hence `iter().rev()`.
+ //
+ // Consider:
+ //
+ // `fn test<'a, 'b>() -> impl Trait<&'a u8, Ty = impl Sized + 'b> {}`
+ //
+ // We would end with a generics_def_id_map like:
+ //
+ // `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]`
+ //
+ // for the opaque type generated on `impl Sized + 'b`, we want the result to be: impl_sized#'b.
+ // So, if we were trying to find first from the start (outermost) would give the wrong result, impl_trait#'b.
+ self.generics_def_id_map
+ .iter()
+ .rev()
+ .find_map(|map| map.get(&local_def_id).map(|local_def_id| *local_def_id))
+ .unwrap_or(local_def_id)
+ }
+
/// Freshen the `LoweringContext` and ready it to lower a nested item.
/// The lowered item is registered into `self.children`.
///
@@ -591,9 +622,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
remap: FxHashMap<LocalDefId, LocalDefId>,
f: impl FnOnce(&mut Self) -> R,
) -> R {
- self.resolver.generics_def_id_map.push(remap);
+ self.generics_def_id_map.push(remap);
let res = f(self);
- self.resolver.generics_def_id_map.pop();
+ self.generics_def_id_map.pop();
res
}
@@ -644,14 +675,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> (Fingerprint, Fingerprint) {
self.tcx.with_stable_hashing_context(|mut hcx| {
let mut stable_hasher = StableHasher::new();
- hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
+ hcx.with_hir_bodies(node.def_id(), bodies, |hcx| {
node.hash_stable(hcx, &mut stable_hasher)
});
let hash_including_bodies = stable_hasher.finish();
let mut stable_hasher = StableHasher::new();
- hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
- node.hash_stable(hcx, &mut stable_hasher)
- });
+ hcx.without_hir_bodies(|hcx| node.hash_stable(hcx, &mut stable_hasher));
let hash_without_bodies = stable_hasher.finish();
(hash_including_bodies, hash_without_bodies)
})
@@ -663,6 +692,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// actually used in the HIR, as that would trigger an assertion in the
/// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
/// properly. Calling the method twice with the same `NodeId` is fine though.
+ #[instrument(level = "debug", skip(self), ret)]
fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
assert_ne!(ast_node_id, DUMMY_NODE_ID);
@@ -696,6 +726,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
/// Generate a new `HirId` without a backing `NodeId`.
+ #[instrument(level = "debug", skip(self), ret)]
fn next_id(&mut self) -> hir::HirId {
let owner = self.current_hir_id_owner;
let local_id = self.item_local_id_counter;
@@ -767,7 +798,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
/// Converts a lifetime into a new generic parameter.
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn lifetime_res_to_generic_param(
&mut self,
ident: Ident,
@@ -811,7 +842,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
/// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
/// parameters will be successful.
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
#[inline]
fn lower_lifetime_binder(
&mut self,
@@ -874,14 +905,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// the `HirId`s. We don't actually need HIR version of attributes anyway.
// Tokens are also not needed after macro expansion and parsing.
let kind = match attr.kind {
- AttrKind::Normal(ref item, _) => AttrKind::Normal(
- AttrItem {
- path: item.path.clone(),
- args: self.lower_mac_args(&item.args),
+ AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
+ item: AttrItem {
+ path: normal.item.path.clone(),
+ args: self.lower_mac_args(&normal.item.args),
tokens: None,
},
- None,
- ),
+ tokens: None,
+ })),
AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data),
};
@@ -929,8 +960,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
lit.clone()
} else {
Lit {
- token: token::Lit::new(token::LitKind::Err, kw::Empty, None),
- kind: LitKind::Err(kw::Empty),
+ token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
+ kind: LitKind::Err,
span: DUMMY_SP,
}
};
@@ -956,7 +987,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_assoc_ty_constraint(
&mut self,
constraint: &AssocConstraint,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> hir::TypeBinding<'hir> {
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
// lower generic arguments of identifier in constraint
@@ -967,18 +998,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
GenericArgs::Parenthesized(ref data) => {
self.emit_bad_parenthesized_trait_in_assoc_ty(data);
- self.lower_angle_bracketed_parameter_data(
- &data.as_angle_bracketed_args(),
- ParamMode::Explicit,
- itctx,
- )
- .0
+ let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args());
+ self.lower_angle_bracketed_parameter_data(aba, ParamMode::Explicit, itctx).0
}
};
gen_args_ctor.into_generic_args(self)
} else {
self.arena.alloc(hir::GenericArgs::none())
};
+ let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy;
let kind = match constraint.kind {
AssocConstraintKind::Equality { ref term } => {
@@ -1016,9 +1044,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// then to an opaque type).
//
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
- ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
- (true, ImplTraitContext::TypeAliasesOpaqueTy)
- }
+ ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => (true, itctx_tait),
// We are in the parameter position, but not within a dyn type:
//
@@ -1040,15 +1066,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.with_dyn_type_scope(false, |this| {
let node_id = this.next_node_id();
- let ty = this.lower_ty(
- &Ty {
- id: node_id,
- kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
- span: this.lower_span(constraint.span),
- tokens: None,
- },
- itctx,
- );
+ let ty = this.ast_arena.tys.alloc(Ty {
+ id: node_id,
+ kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
+ span: this.lower_span(constraint.span),
+ tokens: None,
+ });
+ let ty = this.lower_ty(ty, itctx);
hir::TypeBindingKind::Equality { term: ty.into() }
})
@@ -1072,19 +1096,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
- let mut err = self.tcx.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 sub = 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,
- );
+ AssocTyParenthesesSub::Empty { parentheses_span }
}
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
else {
@@ -1098,20 +1114,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// 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();
+ AssocTyParenthesesSub::NotEmpty { open_param, close_param }
+ };
+ self.tcx.sess.emit_err(AssocTyParentheses { span: data.span, sub });
}
#[instrument(level = "debug", skip(self))]
fn lower_generic_arg(
&mut self,
arg: &ast::GenericArg,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> hir::GenericArg<'hir> {
match arg {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
@@ -1163,7 +1175,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
_ => {}
}
- GenericArg::Type(self.lower_ty_direct(&ty, itctx))
+ GenericArg::Type(self.lower_ty(&ty, itctx))
}
ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
value: self.lower_anon_const(&ct),
@@ -1173,7 +1185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
#[instrument(level = "debug", skip(self))]
- fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
+ fn lower_ty(&mut self, t: &Ty, itctx: &ImplTraitContext) -> &'hir hir::Ty<'hir> {
self.arena.alloc(self.lower_ty_direct(t, itctx))
}
@@ -1183,11 +1195,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself: &Option<QSelf>,
path: &Path,
param_mode: ParamMode,
- itctx: ImplTraitContext,
+ 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 rare occurrence 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()
@@ -1196,19 +1208,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&& let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res()
{
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
+ let poly_trait_ref = this.ast_arena.ptr.alloc(PolyTraitRef {
+ bound_generic_params: vec![],
+ trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
+ span: t.span
+ });
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
- },
+ poly_trait_ref,
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);
+ 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() };
}
@@ -1225,7 +1238,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.ty(span, hir::TyKind::Tup(tys))
}
- fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> 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,
@@ -1241,7 +1254,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else {
self.next_node_id()
};
- let span = self.tcx.sess.source_map().next_point(t.span.shrink_to_lo());
+ let span = self.tcx.sess.source_map().start_point(t.span);
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
});
let lifetime = self.lower_lifetime(&region);
@@ -1253,7 +1266,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
generic_params,
unsafety: self.lower_unsafety(f.unsafety),
abi: self.lower_extern(f.ext),
- decl: self.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
+ decl: self.lower_fn_decl(&f.decl, None, t.span, FnDeclKind::Pointer, None),
param_names: self.lower_fn_params_to_names(&f.decl),
}))
}
@@ -1268,14 +1281,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
}
TyKind::ImplicitSelf => {
+ let hir_id = self.next_id();
let res = self.expect_full_res(t.id);
let res = self.lower_res(res);
hir::TyKind::Path(hir::QPath::Resolved(
None,
self.arena.alloc(hir::Path {
res,
- segments: arena_vec![self; hir::PathSegment::from_ident(
- Ident::with_dummy_span(kw::SelfUpper)
+ segments: arena_vec![self; hir::PathSegment::new(
+ Ident::with_dummy_span(kw::SelfUpper),
+ hir_id,
+ res
)],
span: self.lower_span(t.span),
}),
@@ -1318,19 +1334,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::ImplTrait(def_node_id, ref bounds) => {
let span = t.span;
match itctx {
- ImplTraitContext::ReturnPositionOpaqueTy { origin } => {
- self.lower_opaque_impl_trait(span, origin, def_node_id, bounds, itctx)
- }
- ImplTraitContext::TypeAliasesOpaqueTy => {
- let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
- self.lower_opaque_impl_trait(
+ ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self
+ .lower_opaque_impl_trait(
span,
- hir::OpaqueTyOrigin::TyAlias,
+ *origin,
def_node_id,
bounds,
- nested_itctx,
- )
- }
+ *in_trait,
+ itctx,
+ ),
+ ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
+ span,
+ hir::OpaqueTyOrigin::TyAlias,
+ def_node_id,
+ bounds,
+ false,
+ &ImplTraitContext::TypeAliasesOpaqueTy,
+ ),
ImplTraitContext::Universal => {
let span = t.span;
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
@@ -1342,15 +1362,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
path
}
+ ImplTraitContext::Disallowed(
+ position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn),
+ ) => {
+ self.tcx
+ .sess
+ .create_feature_err(
+ MisplacedImplTrait {
+ span: t.span,
+ position: DiagnosticArgFromDisplay(&position),
+ },
+ sym::return_position_impl_trait_in_trait,
+ )
+ .emit();
+ hir::TyKind::Err
+ }
ImplTraitContext::Disallowed(position) => {
- let mut err = struct_span_err!(
- self.tcx.sess,
- t.span,
- E0562,
- "`impl Trait` only allowed in function and inherent method return types, not in {}",
- position
- );
- err.emit();
+ self.tcx.sess.emit_err(MisplacedImplTrait {
+ span: t.span,
+ position: DiagnosticArgFromDisplay(&position),
+ });
hir::TyKind::Err
}
}
@@ -1397,14 +1428,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
/// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
/// for the lifetimes that get captured (`'x`, in our example above) and reference those.
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
fn lower_opaque_impl_trait(
&mut self,
span: Span,
origin: hir::OpaqueTyOrigin,
opaque_ty_node_id: NodeId,
bounds: &GenericBounds,
- itctx: ImplTraitContext,
+ in_trait: bool,
+ itctx: &ImplTraitContext,
) -> hir::TyKind<'hir> {
// Make sure we know that some funky desugaring has been going on here.
// This is a first: there is code in other places like for loop
@@ -1492,6 +1524,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}),
bounds: hir_bounds,
origin,
+ in_trait,
};
debug!(?opaque_ty_item);
@@ -1518,7 +1551,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
debug!(?lifetimes);
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
- hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
+ hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes, in_trait)
}
/// Registers a new opaque type with the proper `NodeId`s and
@@ -1577,7 +1610,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
LifetimeRes::Fresh { param, binder: _ } => {
debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
- if let Some(old_def_id) = self.opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
+ if let Some(old_def_id) = self.orig_opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
let node_id = self.next_node_id();
let new_def_id = self.create_def(
@@ -1626,19 +1659,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
// given DefId, otherwise impl Trait is disallowed. Must be `Some` if
// `make_ret_async` is also `Some`.
- // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
- // This guards against trait declarations and implementations where `impl Trait` is
- // disallowed.
// `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` 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))]
+ // return type `impl Trait` item, and the `Span` points to the `async` keyword.
+ #[instrument(level = "debug", skip(self))]
fn lower_fn_decl(
&mut self,
decl: &FnDecl,
fn_node_id: Option<NodeId>,
+ fn_span: Span,
kind: FnDeclKind,
- make_ret_async: Option<NodeId>,
+ make_ret_async: Option<(NodeId, Span)>,
) -> &'hir hir::FnDecl<'hir> {
let c_variadic = decl.c_variadic();
@@ -1651,11 +1682,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
if fn_node_id.is_some() {
- self.lower_ty_direct(&param.ty, ImplTraitContext::Universal)
+ self.lower_ty_direct(&param.ty, &ImplTraitContext::Universal)
} else {
self.lower_ty_direct(
&param.ty,
- ImplTraitContext::Disallowed(match kind {
+ &ImplTraitContext::Disallowed(match kind {
FnDeclKind::Fn | FnDeclKind::Inherent => {
unreachable!("fn should allow in-band lifetimes")
}
@@ -1669,20 +1700,63 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}));
- let output = if let Some(ret_id) = make_ret_async {
- self.lower_async_fn_ret_ty(
- &decl.output,
- fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
- ret_id,
- )
+ let output = if let Some((ret_id, span)) = make_ret_async {
+ match kind {
+ FnDeclKind::Trait => {
+ if !kind.impl_trait_in_trait_allowed(self.tcx) {
+ self.tcx
+ .sess
+ .create_feature_err(
+ TraitFnAsync { fn_span, span },
+ sym::return_position_impl_trait_in_trait,
+ )
+ .emit();
+ }
+ self.lower_async_fn_ret_ty(
+ &decl.output,
+ fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
+ ret_id,
+ true,
+ )
+ }
+ _ => {
+ if !kind.impl_trait_return_allowed(self.tcx) {
+ if kind == FnDeclKind::Impl {
+ self.tcx
+ .sess
+ .create_feature_err(
+ TraitFnAsync { fn_span, span },
+ sym::return_position_impl_trait_in_trait,
+ )
+ .emit();
+ } else {
+ self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
+ }
+ }
+ self.lower_async_fn_ret_ty(
+ &decl.output,
+ fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
+ ret_id,
+ false,
+ )
+ }
+ }
} else {
match decl.output {
FnRetTy::Ty(ref ty) => {
- let context = match fn_node_id {
- Some(fn_node_id) if kind.impl_trait_return_allowed() => {
+ let mut context = match fn_node_id {
+ Some(fn_node_id) if kind.impl_trait_return_allowed(self.tcx) => {
+ let fn_def_id = self.local_def_id(fn_node_id);
+ ImplTraitContext::ReturnPositionOpaqueTy {
+ origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+ in_trait: false,
+ }
+ }
+ Some(fn_node_id) if kind.impl_trait_in_trait_allowed(self.tcx) => {
let fn_def_id = self.local_def_id(fn_node_id);
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+ in_trait: true,
}
}
_ => ImplTraitContext::Disallowed(match kind {
@@ -1696,7 +1770,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
}),
};
- hir::FnRetTy::Return(self.lower_ty(ty, context))
+ hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
}
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
}
@@ -1707,10 +1781,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
output,
c_variadic,
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
- use BindingMode::{ByRef, ByValue};
let is_mutable_pat = matches!(
arg.pat.kind,
- PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..)
+ PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..)
);
match arg.ty.kind {
@@ -1741,12 +1814,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// `output`: unlowered output type (`T` in `-> T`)
// `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
// `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn lower_async_fn_ret_ty(
&mut self,
output: &FnRetTy,
fn_node_id: NodeId,
opaque_ty_node_id: NodeId,
+ in_trait: bool,
) -> hir::FnRetTy<'hir> {
let span = output.span();
@@ -1805,7 +1879,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let extra_lifetime_params = self.resolver.take_extra_lifetime_params(opaque_ty_node_id);
debug!(?extra_lifetime_params);
for (ident, outer_node_id, outer_res) in extra_lifetime_params {
- let outer_def_id = self.local_def_id(outer_node_id);
+ let outer_def_id = self.orig_local_def_id(outer_node_id);
let inner_node_id = self.next_node_id();
// Add a definition for the in scope lifetime def.
@@ -1873,8 +1947,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
//
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
// hence the elision takes place at the fn site.
- let future_bound =
- this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span);
+ let future_bound = this.lower_async_fn_output_type_to_future_bound(
+ output,
+ span,
+ ImplTraitContext::ReturnPositionOpaqueTy {
+ origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+ in_trait,
+ },
+ );
let generic_params = this.arena.alloc_from_iter(collected_lifetimes.iter().map(
|&(new_node_id, lifetime, _)| {
@@ -1912,6 +1992,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}),
bounds: arena_vec![this; future_bound],
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+ in_trait,
};
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
@@ -1948,8 +2029,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let res = res.unwrap_or(
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
);
- let l = self.new_named_lifetime_with_res(id, span, ident, res);
- hir::GenericArg::Lifetime(l)
+ hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res))
},
));
@@ -1957,8 +2037,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Foo = impl Trait` is, internally, created as a child of the
// async fn, so the *type parameters* are inherited. It's
// only the lifetime parameters that we must supply.
- let opaque_ty_ref =
- hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
+ let opaque_ty_ref = hir::TyKind::OpaqueDef(
+ hir::ItemId { def_id: opaque_ty_def_id },
+ generic_args,
+ in_trait,
+ );
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
}
@@ -1967,8 +2050,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_async_fn_output_type_to_future_bound(
&mut self,
output: &FnRetTy,
- fn_def_id: LocalDefId,
span: Span,
+ mut nested_impl_trait_context: ImplTraitContext,
) -> hir::GenericBound<'hir> {
// Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output {
@@ -1976,10 +2059,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
// `impl Future` opaque type that `async fn` implicitly
// generates.
- let context = ImplTraitContext::ReturnPositionOpaqueTy {
- origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
- };
- self.lower_ty(ty, context)
+ self.lower_ty(ty, &mut nested_impl_trait_context)
}
FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
};
@@ -2005,7 +2085,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bound(
&mut self,
tpb: &GenericBound,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> hir::GenericBound<'hir> {
match tpb {
GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
@@ -2018,24 +2098,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
- fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
+ fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
let span = self.lower_span(l.ident.span);
let ident = self.lower_ident(l.ident);
self.new_named_lifetime(l.id, l.id, span, ident)
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn new_named_lifetime_with_res(
&mut self,
id: NodeId,
span: Span,
ident: Ident,
res: LifetimeRes,
- ) -> hir::Lifetime {
+ ) -> &'hir hir::Lifetime {
let name = match res {
LifetimeRes::Param { param, .. } => {
let p_name = ParamName::Plain(ident);
- let param = self.resolver.get_remapped_def_id(param);
+ let param = self.get_remapped_def_id(param);
hir::LifetimeName::Param(param, p_name)
}
@@ -2052,17 +2132,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
debug!(?name);
- hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
+ self.arena.alloc(hir::Lifetime {
+ hir_id: self.lower_node_id(id),
+ span: self.lower_span(span),
+ name,
+ })
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn new_named_lifetime(
&mut self,
id: NodeId,
new_id: NodeId,
span: Span,
ident: Ident,
- ) -> hir::Lifetime {
+ ) -> &'hir hir::Lifetime {
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
self.new_named_lifetime_with_res(new_id, span, ident, res)
}
@@ -2117,7 +2201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
GenericParamKind::Type { ref default, .. } => {
let kind = hir::GenericParamKind::Type {
default: default.as_ref().map(|x| {
- self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+ self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type))
}),
synthetic: false,
};
@@ -2125,7 +2209,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
}
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
- let ty = self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+ let ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
let default = default.as_ref().map(|def| self.lower_anon_const(def));
(
hir::ParamName::Plain(self.lower_ident(param.ident)),
@@ -2135,7 +2219,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
- fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> 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),
@@ -2143,11 +2227,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn lower_poly_trait_ref(
&mut self,
p: &PolyTraitRef,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
@@ -2155,14 +2239,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
}
- fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> 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 }
}
+ #[instrument(level = "debug", skip(self), ret)]
fn lower_param_bounds(
&mut self,
bounds: &[GenericBound],
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> hir::GenericBounds<'hir> {
self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
}
@@ -2170,11 +2255,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bounds_mut<'s>(
&'s mut self,
bounds: &'s [GenericBound],
- itctx: ImplTraitContext,
+ itctx: &'s ImplTraitContext,
) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
}
+ #[instrument(level = "debug", skip(self), ret)]
fn lower_generic_and_bounds(
&mut self,
node_id: NodeId,
@@ -2200,16 +2286,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
node_id,
&GenericParamKind::Type { default: None },
bounds,
- ImplTraitContext::Universal,
+ &ImplTraitContext::Universal,
hir::PredicateOrigin::ImplTrait,
);
+ let hir_id = self.next_id();
+ let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
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))],
+ res,
+ segments:
+ arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
}),
));
@@ -2235,7 +2324,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
c.value.span,
"using `_` for array lengths is unstable",
)
- .emit();
+ .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
hir::ArrayLen::Body(self.lower_anon_const(c))
}
}
@@ -2372,11 +2461,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
- self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
+ self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::NONE)
}
fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
- self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated)
+ self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::NONE)
}
fn pat_ident_binding_mode(
@@ -2465,14 +2554,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
/// when the bound is written, even if it is written with `'_` like in
/// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
- fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
+ fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
let r = hir::Lifetime {
hir_id: self.next_id(),
span: self.lower_span(span),
name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
};
debug!("elided_dyn_bound: r={:?}", r);
- r
+ self.arena.alloc(r)
}
}
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
index 81006e00f..914fc5f58 100644
--- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs
+++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
@@ -1,9 +1,6 @@
use super::ResolverAstLoweringExt;
use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
-use rustc_ast::{
- FnRetTy, GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, TraitBoundModifier, Ty,
- TyKind,
-};
+use rustc_ast::{FnRetTy, GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind};
use rustc_hir::def::LifetimeRes;
use rustc_middle::span_bug;
use rustc_middle::ty::ResolverAstLowering;
@@ -66,15 +63,15 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
self.record_lifetime_use(*lifetime);
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) {
- self.record_elided_anchor(path_segment.id, path_span);
- visit::walk_path_segment(self, path_span, path_segment);
+ fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
+ self.record_elided_anchor(path_segment.id, path_segment.ident.span);
+ visit::walk_path_segment(self, path_segment);
}
- fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
+ fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) {
self.current_binders.push(t.trait_ref.ref_id);
- visit::walk_poly_trait_ref(self, t, m);
+ visit::walk_poly_trait_ref(self, t);
self.current_binders.pop();
}
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index bd2e76e55..1ea76fdbf 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -1,3 +1,6 @@
+use super::errors::{
+ ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
+};
use super::ResolverAstLoweringExt;
use super::{ImplTraitContext, LoweringContext, ParamMode};
use crate::ImplTraitPosition;
@@ -5,7 +8,6 @@ use crate::ImplTraitPosition;
use rustc_ast::ptr::P;
use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_span::symbol::Ident;
@@ -22,7 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let node = loop {
match pattern.kind {
PatKind::Wild => break hir::PatKind::Wild,
- PatKind::Ident(ref binding_mode, ident, ref sub) => {
+ PatKind::Ident(binding_mode, ident, ref sub) => {
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
}
@@ -35,7 +37,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -51,7 +53,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
break hir::PatKind::Path(qpath);
}
@@ -61,15 +63,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &mut ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
- let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::PatField {
- hir_id: self.next_id(),
- ident: self.lower_ident(f.ident),
- pat: self.lower_pat(&f.pat),
- is_shorthand: f.is_shorthand,
- span: self.lower_span(f.span),
+ let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
+ let hir_id = self.lower_node_id(f.id);
+ self.lower_attrs(hir_id, &f.attrs);
+
+ hir::PatField {
+ hir_id,
+ ident: self.lower_ident(f.ident),
+ pat: self.lower_pat(&f.pat),
+ is_shorthand: f.is_shorthand,
+ span: self.lower_span(f.span),
+ }
}));
break hir::PatKind::Struct(qpath, fs, etc);
}
@@ -109,7 +116,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
pats: &[P<Pat>],
ctx: &str,
- ) -> (&'hir [hir::Pat<'hir>], Option<usize>) {
+ ) -> (&'hir [hir::Pat<'hir>], hir::DotDotPos) {
let mut elems = Vec::with_capacity(pats.len());
let mut rest = None;
@@ -129,20 +136,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// This is not allowed as a sub-tuple pattern
PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
let sp = pat.span;
- self.diagnostic()
- .struct_span_err(
- sp,
- &format!("`{} @` is not allowed in a {}", ident.name, ctx),
- )
- .span_label(sp, "this is only allowed in slice patterns")
- .help("remove this and bind each tuple field independently")
- .span_suggestion_verbose(
- sp,
- &format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident),
- "..",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ self.tcx.sess.emit_err(SubTupleBinding {
+ span: sp,
+ ident_name: ident.name,
+ ident,
+ ctx,
+ });
}
_ => {}
}
@@ -161,7 +160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
- (self.arena.alloc_from_iter(elems), rest.map(|(ddpos, _)| ddpos))
+ (self.arena.alloc_from_iter(elems), hir::DotDotPos::new(rest.map(|(ddpos, _)| ddpos)))
}
/// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
@@ -177,9 +176,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut prev_rest_span = None;
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`.
- let lower_rest_sub = |this: &mut Self, pat, bm, ident, sub| {
+ let lower_rest_sub = |this: &mut Self, pat, ann, ident, sub| {
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
- let node = this.lower_pat_ident(pat, bm, ident, lower_sub);
+ let node = this.lower_pat_ident(pat, ann, ident, lower_sub);
this.pat_with_node_id_of(pat, node)
};
@@ -195,9 +194,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
// Found a sub-slice pattern `$binding_mode $ident @ ..`.
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
- PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
+ PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
prev_rest_span = Some(sub.span);
- slice = Some(self.arena.alloc(lower_rest_sub(self, pat, bm, ident, sub)));
+ slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub)));
break;
}
// It was not a subslice pattern so lower it normally.
@@ -210,9 +209,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// There was a previous subslice pattern; make sure we don't allow more.
let rest_span = match pat.kind {
PatKind::Rest => Some(pat.span),
- PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
+ PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
// #69103: Lower into `binding @ _` as above to avoid ICEs.
- after.push(lower_rest_sub(self, pat, bm, ident, sub));
+ after.push(lower_rest_sub(self, pat, ann, ident, sub));
Some(sub.span)
}
_ => None,
@@ -236,7 +235,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_pat_ident(
&mut self,
p: &Pat,
- binding_mode: &BindingMode,
+ annotation: BindingAnnotation,
ident: Ident,
lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
) -> hir::PatKind<'hir> {
@@ -249,29 +248,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
hir::PatKind::Binding(
- self.lower_binding_mode(binding_mode),
+ annotation,
self.lower_node_id(canonical_id),
self.lower_ident(ident),
lower_sub(self),
)
}
- Some(res) => hir::PatKind::Path(hir::QPath::Resolved(
- None,
- self.arena.alloc(hir::Path {
- span: self.lower_span(ident.span),
- res: self.lower_res(res),
- segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))],
- }),
- )),
- }
- }
-
- fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
- match *b {
- BindingMode::ByValue(Mutability::Not) => hir::BindingAnnotation::Unannotated,
- BindingMode::ByRef(Mutability::Not) => hir::BindingAnnotation::Ref,
- BindingMode::ByValue(Mutability::Mut) => hir::BindingAnnotation::Mutable,
- BindingMode::ByRef(Mutability::Mut) => hir::BindingAnnotation::RefMut,
+ Some(res) => {
+ let hir_id = self.next_id();
+ let res = self.lower_res(res);
+ hir::PatKind::Path(hir::QPath::Resolved(
+ None,
+ self.arena.alloc(hir::Path {
+ span: self.lower_span(ident.span),
+ res,
+ segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
+ }),
+ ))
+ }
}
}
@@ -291,19 +285,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
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))
- .span_label(prev_sp, "previously used here")
- .emit();
+ self.tcx.sess.emit_err(ExtraDoubleDot { span: sp, prev_span: prev_sp, ctx });
}
/// Used to ban the `..` pattern in places it shouldn't be semantically.
fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> {
- self.diagnostic()
- .struct_span_err(sp, "`..` patterns are not allowed here")
- .note("only allowed in tuple, tuple struct, and slice patterns")
- .emit();
+ self.tcx.sess.emit_err(MisplacedDoubleDot { span: sp });
// We're not in a list context so `..` can be reasonably treated
// as `_` because it should always be valid and roughly matches the
@@ -340,8 +327,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExprKind::Path(..) if allow_paths => {}
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
_ => {
- self.diagnostic()
- .span_err(expr.span, "arbitrary expressions aren't allowed in patterns");
+ self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span });
return self.arena.alloc(self.expr_err(expr.span));
}
}
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 393be3b45..6bb1bb9ea 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -1,11 +1,11 @@
use crate::ImplTraitPosition;
+use super::errors::{GenericTypeWithParentheses, UseAngleBrackets};
use super::ResolverAstLoweringExt;
use super::{GenericArgsCtor, LifetimeRes, ParenthesizedGenericArgs};
use super::{ImplTraitContext, LoweringContext, ParamMode};
use rustc_ast::{self as ast, *};
-use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, PartialRes, Res};
use rustc_hir::GenericArg;
@@ -13,7 +13,6 @@ use rustc_span::symbol::{kw, Ident};
use rustc_span::{BytePos, Span, DUMMY_SP};
use smallvec::smallvec;
-use tracing::debug;
impl<'a, 'hir> LoweringContext<'a, 'hir> {
#[instrument(level = "trace", skip(self))]
@@ -23,7 +22,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself: &Option<QSelf>,
p: &Path,
param_mode: ParamMode,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> hir::QPath<'hir> {
let qself_position = qself.as_ref().map(|q| q.position);
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
@@ -157,7 +156,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
segment,
param_mode,
ParenthesizedGenericArgs::Err,
- ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+ &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
)
})),
span: self.lower_span(p.span),
@@ -181,11 +180,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
segment: &PathSegment,
param_mode: ParamMode,
parenthesized_generic_args: ParenthesizedGenericArgs,
- itctx: ImplTraitContext,
+ 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 {
- let msg = "parenthesized type parameters may only be used with a `Fn` trait";
match **generic_args {
GenericArgs::AngleBracketed(ref data) => {
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
@@ -193,10 +191,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
ParenthesizedGenericArgs::Err => {
- let mut err = struct_span_err!(self.tcx.sess, data.span, E0214, "{}", msg);
- err.span_label(data.span, "only `Fn` traits may use parentheses");
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
- if !data.inputs.is_empty() {
+ let sub = 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
@@ -212,16 +208,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.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();
+
+ Some(UseAngleBrackets { open_param, close_param })
+ } else {
+ None
+ };
+ self.tcx.sess.emit_err(GenericTypeWithParentheses { span: data.span, sub });
(
self.lower_angle_bracketed_parameter_data(
&data.as_angle_bracketed_args(),
@@ -258,16 +250,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
let res = self.expect_full_res(segment.id);
- let id = self.lower_node_id(segment.id);
+ let hir_id = self.lower_node_id(segment.id);
debug!(
"lower_path_segment: ident={:?} original-id={:?} new-id={:?}",
- segment.ident, segment.id, id,
+ segment.ident, segment.id, hir_id,
);
hir::PathSegment {
ident: self.lower_ident(segment.ident),
- hir_id: Some(id),
- res: Some(self.lower_res(res)),
+ hir_id,
+ res: self.lower_res(res),
infer_args,
args: if generic_args.is_empty() && generic_args.span.is_empty() {
None
@@ -324,7 +316,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
data: &AngleBracketedArgs,
param_mode: ParamMode,
- itctx: ImplTraitContext,
+ itctx: &ImplTraitContext,
) -> (GenericArgsCtor<'hir>, bool) {
let has_non_lt_args = data.args.iter().any(|arg| match arg {
AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_))
@@ -358,15 +350,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// we generally don't permit such things (see #51008).
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))
+ 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))
+ 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 args = smallvec![GenericArg::Type(self.arena.alloc(self.ty_tup(*inputs_span, inputs)))];
let binding = self.output_ty_binding(output_ty.span, output_ty);
(
GenericArgsCtor {
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index 22742b2ad..37eff9207 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -11,6 +11,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
+rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 2d9d0073f..b1d10e07a 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -13,9 +13,7 @@ use rustc_ast::walk_list;
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{
- error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
-};
+use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -29,6 +27,8 @@ use rustc_target::spec::abi;
use std::mem;
use std::ops::{Deref, DerefMut};
+use crate::errors::*;
+
const MORE_EXTERN: &str =
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
@@ -121,30 +121,9 @@ impl<'a> AstValidator<'a> {
fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) {
let sess = &self.session;
if sess.opts.unstable_features.is_nightly_build() {
- let err = "`let` expressions are not supported here";
- let mut diag = sess.struct_span_err(expr.span, err);
- diag.note("only supported directly in conditions of `if` and `while` expressions");
- match forbidden_let_reason {
- ForbiddenLetReason::GenericForbidden => {}
- ForbiddenLetReason::NotSupportedOr(span) => {
- diag.span_note(
- span,
- "`||` operators are not supported in let chain expressions",
- );
- }
- ForbiddenLetReason::NotSupportedParentheses(span) => {
- diag.span_note(
- span,
- "`let`s wrapped in parentheses are not supported in a context with let \
- chains",
- );
- }
- }
- diag.emit();
+ sess.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason });
} else {
- sess.struct_span_err(expr.span, "expected expression, found statement (`let`)")
- .note("variable declaration using `let` is a statement")
- .emit();
+ sess.emit_err(ForbiddenLetStable { span: expr.span });
}
}
@@ -175,7 +154,7 @@ impl<'a> AstValidator<'a> {
DEPRECATED_WHERE_CLAUSE_LOCATION,
id,
where_clauses.0.1,
- "where clause not allowed here",
+ fluent::ast_passes::deprecated_where_clause_location,
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(
where_clauses.1.1.shrink_to_hi(),
suggestion,
@@ -205,10 +184,7 @@ impl<'a> AstValidator<'a> {
AssocConstraintKind::Equality { .. } => {}
AssocConstraintKind::Bound { .. } => {
if self.is_assoc_ty_bound_banned {
- self.err_handler().span_err(
- constraint.span,
- "associated type bounds are not allowed within structs, enums, or unions",
- );
+ self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span });
}
}
}
@@ -247,11 +223,9 @@ impl<'a> AstValidator<'a> {
for (i, segment) in path.segments.iter().enumerate() {
// Allow `impl Trait` iff we're on the final path segment
if i == path.segments.len() - 1 {
- self.visit_path_segment(path.span, segment);
+ self.visit_path_segment(segment);
} else {
- self.with_banned_impl_trait(|this| {
- this.visit_path_segment(path.span, segment)
- });
+ self.with_banned_impl_trait(|this| this.visit_path_segment(segment));
}
}
}
@@ -280,38 +254,33 @@ impl<'a> AstValidator<'a> {
fn check_lifetime(&self, ident: Ident) {
let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty];
if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
- self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names");
+ self.session.emit_err(KeywordLifetime { span: ident.span });
}
}
fn check_label(&self, ident: Ident) {
if ident.without_first_quote().is_reserved() {
- self.err_handler()
- .span_err(ident.span, &format!("invalid label name `{}`", ident.name));
+ self.session.emit_err(InvalidLabel { span: ident.span, name: ident.name });
}
}
- fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
+ fn invalid_visibility(&self, vis: &Visibility, note: Option<InvalidVisibilityNote>) {
if let VisibilityKind::Inherited = vis.kind {
return;
}
- let mut err =
- struct_span_err!(self.session, vis.span, E0449, "unnecessary visibility qualifier");
- if vis.kind.is_pub() {
- err.span_label(vis.span, "`pub` not permitted here because it's implied");
- }
- if let Some(note) = note {
- err.note(note);
- }
- err.emit();
+ self.session.emit_err(InvalidVisibility {
+ span: vis.span,
+ implied: if vis.kind.is_pub() { Some(vis.span) } else { None },
+ note,
+ });
}
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
for Param { pat, .. } in &decl.inputs {
match pat.kind {
- PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None) | PatKind::Wild => {}
- PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ident, None) => {
+ PatKind::Ident(BindingAnnotation::NONE, _, None) | PatKind::Wild => {}
+ PatKind::Ident(BindingAnnotation::MUT, ident, None) => {
report_err(pat.span, Some(ident), true)
}
_ => report_err(pat.span, None, false),
@@ -319,31 +288,9 @@ impl<'a> AstValidator<'a> {
}
}
- fn check_trait_fn_not_async(&self, fn_span: Span, asyncness: Async) {
- if let Async::Yes { span, .. } = asyncness {
- struct_span_err!(
- self.session,
- fn_span,
- E0706,
- "functions in traits cannot be declared `async`"
- )
- .span_label(span, "`async` because of this")
- .note("`async` trait functions are not currently supported")
- .note("consider using the `async-trait` crate: https://crates.io/crates/async-trait")
- .emit();
- }
- }
-
fn check_trait_fn_not_const(&self, constness: Const) {
if let Const::Yes(span) = constness {
- struct_span_err!(
- self.session,
- span,
- E0379,
- "functions in traits cannot be declared const"
- )
- .span_label(span, "functions in traits cannot be const")
- .emit();
+ self.session.emit_err(TraitFnConst { span });
}
}
@@ -356,8 +303,7 @@ impl<'a> AstValidator<'a> {
GenericParamKind::Lifetime { .. } => {
if !param.bounds.is_empty() {
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
- self.err_handler()
- .span_err(spans, "lifetime bounds cannot be used in this context");
+ self.session.emit_err(ForbiddenLifetimeBound { spans });
}
None
}
@@ -365,10 +311,7 @@ impl<'a> AstValidator<'a> {
})
.collect();
if !non_lt_param_spans.is_empty() {
- self.err_handler().span_err(
- non_lt_param_spans,
- "only lifetime parameters can be used in this context",
- );
+ self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans });
}
}
@@ -385,10 +328,7 @@ impl<'a> AstValidator<'a> {
let max_num_args: usize = u16::MAX.into();
if fn_decl.inputs.len() > max_num_args {
let Param { span, .. } = fn_decl.inputs[0];
- self.err_handler().span_fatal(
- span,
- &format!("function can not have more than {} arguments", max_num_args),
- );
+ self.session.emit_fatal(FnParamTooMany { span, max_num_args });
}
}
@@ -396,19 +336,13 @@ impl<'a> AstValidator<'a> {
match &*fn_decl.inputs {
[Param { ty, span, .. }] => {
if let TyKind::CVarArgs = ty.kind {
- self.err_handler().span_err(
- *span,
- "C-variadic function must be declared with at least one named argument",
- );
+ self.session.emit_err(FnParamCVarArgsOnly { span: *span });
}
}
[ps @ .., _] => {
for Param { ty, span, .. } in ps {
if let TyKind::CVarArgs = ty.kind {
- self.err_handler().span_err(
- *span,
- "`...` must be the last argument of a C-variadic function",
- );
+ self.session.emit_err(FnParamCVarArgsNotLast { span: *span });
}
}
}
@@ -435,19 +369,9 @@ impl<'a> AstValidator<'a> {
})
.for_each(|attr| {
if attr.is_doc_comment() {
- self.err_handler()
- .struct_span_err(
- attr.span,
- "documentation comments cannot be applied to function parameters",
- )
- .span_label(attr.span, "doc comments are not allowed here")
- .emit();
+ self.session.emit_err(FnParamDocComment { span: attr.span });
} else {
- self.err_handler().span_err(
- attr.span,
- "allow, cfg, cfg_attr, deny, expect, \
- forbid, and warn are the only allowed built-in attributes in function parameters",
- );
+ self.session.emit_err(FnParamForbiddenAttr { span: attr.span });
}
});
}
@@ -455,14 +379,7 @@ impl<'a> AstValidator<'a> {
fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) {
if param.is_self() {
- self.err_handler()
- .struct_span_err(
- param.span,
- "`self` parameter is only allowed in associated functions",
- )
- .span_label(param.span, "not semantically valid as function parameter")
- .note("associated functions are those in `impl` or `trait` definitions")
- .emit();
+ self.session.emit_err(FnParamForbiddenSelf { span: param.span });
}
}
}
@@ -470,47 +387,20 @@ impl<'a> AstValidator<'a> {
fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
if let Defaultness::Default(def_span) = defaultness {
let span = self.session.source_map().guess_head_span(span);
- self.err_handler()
- .struct_span_err(span, "`default` is only allowed on items in trait impls")
- .span_label(def_span, "`default` because of this")
- .emit();
+ self.session.emit_err(ForbiddenDefault { span, def_span });
}
}
- fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) {
- self.error_item_without_body_with_help(sp, ctx, msg, sugg, |_| ());
- }
-
- fn error_item_without_body_with_help(
- &self,
- sp: Span,
- ctx: &str,
- msg: &str,
- sugg: &str,
- help: impl FnOnce(&mut DiagnosticBuilder<'_, ErrorGuaranteed>),
- ) {
+ /// If `sp` ends with a semicolon, returns it as a `Span`
+ /// Otherwise, returns `sp.shrink_to_hi()`
+ fn ending_semi_or_hi(&self, sp: Span) -> Span {
let source_map = self.session.source_map();
let end = source_map.end_point(sp);
- let replace_span = if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
+
+ if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
end
} else {
sp.shrink_to_hi()
- };
- let mut err = self.err_handler().struct_span_err(sp, msg);
- err.span_suggestion(
- replace_span,
- &format!("provide a definition for the {}", ctx),
- sugg,
- Applicability::HasPlaceholders,
- );
- help(&mut err);
- err.emit();
- }
-
- fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
- if body.is_none() {
- let msg = format!("associated {} in `impl` without body", ctx);
- self.error_item_without_body(sp, ctx, &msg, sugg);
}
}
@@ -947,10 +837,10 @@ fn validate_generic_param_order(
let (kind, bounds, span) = (&param.kind, &param.bounds, ident.span);
let (ord_kind, ident) = match &param.kind {
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()),
- GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
+ GenericParamKind::Type { default: _ } => (ParamKindOrd::TypeOrConst, ident.to_string()),
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
let ty = pprust::ty_to_string(ty);
- (ParamKindOrd::Const, format!("const {}: {}", ident, ty))
+ (ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty))
}
};
param_idents.push((kind, ord_kind, bounds, idx, ident));
@@ -1180,7 +1070,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.invalid_visibility(
&item.vis,
- Some("place qualifiers on individual impl items instead"),
+ Some(InvalidVisibilityNote::IndividualImplItems),
);
if let Unsafe::Yes(span) = unsafety {
error(span, "unsafe").code(error_code!(E0197)).emit();
@@ -1203,37 +1093,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_defaultness(item.span, defaultness);
if body.is_none() {
- let msg = "free function without a body";
- let ext = sig.header.ext;
-
- let f = |e: &mut DiagnosticBuilder<'_, _>| {
- if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext
- {
- let start_suggestion = if let Extern::Explicit(abi, _) = ext {
- format!("extern \"{}\" {{", abi.symbol_unescaped)
- } else {
- "extern {".to_owned()
- };
-
- let end_suggestion = " }".to_owned();
- let end_span = item.span.shrink_to_hi();
-
- e
- .multipart_suggestion(
- "if you meant to declare an externally defined function, use an `extern` block",
- vec![(*start_span, start_suggestion), (end_span, end_suggestion)],
- Applicability::MaybeIncorrect,
- );
- }
- };
-
- self.error_item_without_body_with_help(
- item.span,
- "function",
- msg,
- " { <body> }",
- f,
- );
+ self.session.emit_err(FnWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ extern_block_suggestion: match sig.header.ext {
+ Extern::None => None,
+ Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
+ start_span,
+ end_span: item.span.shrink_to_hi(),
+ abi: None,
+ }),
+ Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
+ start_span,
+ end_span: item.span.shrink_to_hi(),
+ abi: Some(abi.symbol_unescaped),
+ }),
+ },
+ });
}
self.visit_vis(&item.vis);
@@ -1248,7 +1124,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let old_item = mem::replace(&mut self.extern_mod, Some(item));
self.invalid_visibility(
&item.vis,
- Some("place qualifiers on individual foreign items instead"),
+ Some(InvalidVisibilityNote::IndividualForeignItems),
);
if let Unsafe::Yes(span) = unsafety {
self.err_handler().span_err(span, "extern block cannot be declared unsafe");
@@ -1339,12 +1215,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Const(def, .., None) => {
self.check_defaultness(item.span, def);
- let msg = "free constant item without body";
- self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
+ self.session.emit_err(ConstWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
}
ItemKind::Static(.., None) => {
- let msg = "free static item without body";
- self.error_item_without_body(item.span, "static", msg, " = <expr>;");
+ self.session.emit_err(StaticWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
}
ItemKind::TyAlias(box TyAlias {
defaultness,
@@ -1355,8 +1235,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}) => {
self.check_defaultness(item.span, defaultness);
if ty.is_none() {
- let msg = "free type alias without body";
- self.error_item_without_body(item.span, "type", msg, " = <type>;");
+ self.session.emit_err(TyAliasWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
}
self.check_type_no_bounds(bounds, "this context");
if where_clauses.1.0 {
@@ -1409,7 +1291,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
// Mirrors `visit::walk_generic_args`, but tracks relevant state.
- fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
+ fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) {
match *generic_args {
GenericArgs::AngleBracketed(ref data) => {
self.check_generic_args_before_constraints(data);
@@ -1548,25 +1430,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
visit::walk_param_bound(self, bound)
}
- fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifier) {
+ fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef) {
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
- visit::walk_poly_trait_ref(self, t, m);
+ visit::walk_poly_trait_ref(self, t);
}
fn visit_variant_data(&mut self, s: &'a VariantData) {
self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
}
- fn visit_enum_def(
- &mut self,
- enum_definition: &'a EnumDef,
- generics: &'a Generics,
- item_id: NodeId,
- _: Span,
- ) {
- self.with_banned_assoc_ty_bound(|this| {
- visit::walk_enum_def(this, enum_definition, generics, item_id)
- })
+ fn visit_enum_def(&mut self, enum_definition: &'a EnumDef) {
+ self.with_banned_assoc_ty_bound(|this| visit::walk_enum_def(this, enum_definition))
}
fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
@@ -1653,7 +1527,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
matches!(fk.header(), Some(FnHeader { constness: Const::Yes(_), .. }))
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
- self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk, span));
+ self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
}
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
@@ -1668,10 +1542,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if ctxt == AssocCtxt::Impl {
match &item.kind {
AssocItemKind::Const(_, _, body) => {
- self.check_impl_item_provided(item.span, body, "constant", " = <expr>;");
+ if body.is_none() {
+ self.session.emit_err(AssocConstWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
+ }
}
AssocItemKind::Fn(box Fn { body, .. }) => {
- self.check_impl_item_provided(item.span, body, "function", " { <body> }");
+ if body.is_none() {
+ self.session.emit_err(AssocFnWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
+ }
}
AssocItemKind::TyAlias(box TyAlias {
generics,
@@ -1681,7 +1565,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ty,
..
}) => {
- self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
+ if ty.is_none() {
+ self.session.emit_err(AssocTypeWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
+ }
self.check_type_no_bounds(bounds, "`impl`s");
if ty.is_some() {
self.check_gat_where(
@@ -1699,7 +1588,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.invalid_visibility(&item.vis, None);
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
self.check_trait_fn_not_const(sig.header.constness);
- self.check_trait_fn_not_async(item.span, sig.header.asyncness);
}
}
@@ -1896,14 +1784,14 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
/// Used to forbid `let` expressions in certain syntactic locations.
#[derive(Clone, Copy)]
-enum ForbiddenLetReason {
+pub(crate) enum ForbiddenLetReason {
/// `let` is not valid and the source environment is not important
GenericForbidden,
/// A let chain with the `||` operator
NotSupportedOr(Span),
/// A let chain with invalid parentheses
///
- /// For exemple, `let 1 = 1 && (expr && expr)` is allowed
+ /// For example, `let 1 = 1 && (expr && expr)` is allowed
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
NotSupportedParentheses(Span),
}
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
new file mode 100644
index 000000000..4f3b09c58
--- /dev/null
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -0,0 +1,245 @@
+//! Errors emitted by ast_passes.
+
+use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic};
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_span::{Span, Symbol};
+
+use crate::ast_validation::ForbiddenLetReason;
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::forbidden_let)]
+#[note]
+pub struct ForbiddenLet {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub(crate) reason: ForbiddenLetReason,
+}
+
+impl AddSubdiagnostic for ForbiddenLetReason {
+ fn add_to_diagnostic(self, diag: &mut Diagnostic) {
+ match self {
+ Self::GenericForbidden => {}
+ Self::NotSupportedOr(span) => {
+ diag.span_note(span, fluent::ast_passes::not_supported_or);
+ }
+ Self::NotSupportedParentheses(span) => {
+ diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
+ }
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::forbidden_let_stable)]
+#[note]
+pub struct ForbiddenLetStable {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::forbidden_assoc_constraint)]
+pub struct ForbiddenAssocConstraint {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::keyword_lifetime)]
+pub struct KeywordLifetime {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::invalid_label)]
+pub struct InvalidLabel {
+ #[primary_span]
+ pub span: Span,
+ pub name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::invalid_visibility, code = "E0449")]
+pub struct InvalidVisibility {
+ #[primary_span]
+ pub span: Span,
+ #[label(ast_passes::implied)]
+ pub implied: Option<Span>,
+ #[subdiagnostic]
+ pub note: Option<InvalidVisibilityNote>,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum InvalidVisibilityNote {
+ #[note(ast_passes::individual_impl_items)]
+ IndividualImplItems,
+ #[note(ast_passes::individual_foreign_items)]
+ IndividualForeignItems,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::trait_fn_const, code = "E0379")]
+pub struct TraitFnConst {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::forbidden_lifetime_bound)]
+pub struct ForbiddenLifetimeBound {
+ #[primary_span]
+ pub spans: Vec<Span>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::forbidden_non_lifetime_param)]
+pub struct ForbiddenNonLifetimeParam {
+ #[primary_span]
+ pub spans: Vec<Span>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_param_too_many)]
+pub struct FnParamTooMany {
+ #[primary_span]
+ pub span: Span,
+ pub max_num_args: usize,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_param_c_var_args_only)]
+pub struct FnParamCVarArgsOnly {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_param_c_var_args_not_last)]
+pub struct FnParamCVarArgsNotLast {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_param_doc_comment)]
+pub struct FnParamDocComment {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_param_forbidden_attr)]
+pub struct FnParamForbiddenAttr {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_param_forbidden_self)]
+#[note]
+pub struct FnParamForbiddenSelf {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::forbidden_default)]
+pub struct ForbiddenDefault {
+ #[primary_span]
+ pub span: Span,
+ #[label]
+ pub def_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::assoc_const_without_body)]
+pub struct AssocConstWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
+ pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::assoc_fn_without_body)]
+pub struct AssocFnWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
+ pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::assoc_type_without_body)]
+pub struct AssocTypeWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " = <type>;", applicability = "has-placeholders")]
+ pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::const_without_body)]
+pub struct ConstWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
+ pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::static_without_body)]
+pub struct StaticWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
+ pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::ty_alias_without_body)]
+pub struct TyAliasWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " = <type>;", applicability = "has-placeholders")]
+ pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ast_passes::fn_without_body)]
+pub struct FnWithoutBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
+ pub replace_span: Span,
+ #[subdiagnostic]
+ pub extern_block_suggestion: Option<ExternBlockSuggestion>,
+}
+
+pub struct ExternBlockSuggestion {
+ pub start_span: Span,
+ pub end_span: Span,
+ pub abi: Option<Symbol>,
+}
+
+impl AddSubdiagnostic for ExternBlockSuggestion {
+ fn add_to_diagnostic(self, diag: &mut Diagnostic) {
+ let start_suggestion = if let Some(abi) = self.abi {
+ format!("extern \"{}\" {{", abi)
+ } else {
+ "extern {".to_owned()
+ };
+ let end_suggestion = " }".to_owned();
+
+ diag.multipart_suggestion(
+ fluent::ast_passes::extern_block_suggestion,
+ vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
+ Applicability::MaybeIncorrect,
+ );
+ }
+}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 789eca1f0..aeff73c5b 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -2,17 +2,15 @@ use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
use rustc_ast::{PatKind, RangeEnd, VariantData};
-use rustc_errors::{struct_span_err, Applicability};
+use rustc_errors::{struct_span_err, Applicability, StashKey};
+use rustc_feature::Features;
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
-use rustc_feature::{Features, GateIssue};
-use rustc_session::parse::{feature_err, feature_err_issue};
+use rustc_session::parse::{feature_err, feature_warn};
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym;
use rustc_span::Span;
-use tracing::debug;
-
macro_rules! gate_feature_fn {
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
let (visitor, has_feature, span, name, explain, help) =
@@ -20,9 +18,7 @@ macro_rules! gate_feature_fn {
let has_feature: bool = has_feature(visitor.features);
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
if !has_feature && !span.allows_unstable($name) {
- feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
- .help(help)
- .emit();
+ feature_err(&visitor.sess.parse_sess, name, span, explain).help(help).emit();
}
}};
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
@@ -31,8 +27,19 @@ macro_rules! gate_feature_fn {
let has_feature: bool = has_feature(visitor.features);
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
if !has_feature && !span.allows_unstable($name) {
- feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
- .emit();
+ feature_err(&visitor.sess.parse_sess, name, span, explain).emit();
+ }
+ }};
+ (future_incompatible; $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
+ let (visitor, has_feature, span, name, explain) =
+ (&*$visitor, $has_feature, $span, $name, $explain);
+ let has_feature: bool = has_feature(visitor.features);
+ debug!(
+ "gate_feature(feature = {:?}, span = {:?}); has? {} (future_incompatible)",
+ name, span, has_feature
+ );
+ if !has_feature && !span.allows_unstable($name) {
+ feature_warn(&visitor.sess.parse_sess, name, span, explain);
}
}};
}
@@ -44,6 +51,9 @@ macro_rules! gate_feature_post {
($visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
};
+ (future_incompatible; $visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
+ gate_feature_fn!(future_incompatible; $visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
+ };
}
pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) {
@@ -330,25 +340,6 @@ impl<'a> PostExpansionVisitor<'a> {
}
}
- fn check_gat(&self, generics: &ast::Generics, span: Span) {
- if !generics.params.is_empty() {
- gate_feature_post!(
- &self,
- generic_associated_types,
- span,
- "generic associated types are unstable"
- );
- }
- if !generics.where_clause.predicates.is_empty() {
- gate_feature_post!(
- &self,
- generic_associated_types,
- span,
- "where clauses on associated types are unstable"
- );
- }
- }
-
/// Feature gate `impl Trait` inside `type Alias = $type_expr;`.
fn check_impl_trait(&self, ty: &ast::Ty) {
struct ImplTraitVisitor<'a> {
@@ -417,6 +408,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|| attr.has_name(sym::stable)
|| attr.has_name(sym::rustc_const_unstable)
|| attr.has_name(sym::rustc_const_stable)
+ || attr.has_name(sym::rustc_default_body_unstable)
{
struct_span_err!(
self.sess,
@@ -562,6 +554,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::TyKind::Never => {
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
}
+ ast::TyKind::TraitObject(_, ast::TraitObjectSyntax::DynStar, ..) => {
+ gate_feature_post!(&self, dyn_star, ty.span, "dyn* trait objects are unstable");
+ }
_ => {}
}
visit::walk_ty(self, ty)
@@ -587,11 +582,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
{
// When we encounter a statement of the form `foo: Ty = val;`, this will emit a type
// ascription error, but the likely intention was to write a `let` statement. (#78907).
- feature_err_issue(
+ feature_err(
&self.sess.parse_sess,
sym::type_ascription,
lhs.span,
- GateIssue::Language,
"type ascription is experimental",
).span_suggestion_verbose(
lhs.span.shrink_to_lo(),
@@ -614,28 +608,27 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
);
}
ast::ExprKind::Type(..) => {
- // To avoid noise about type ascription in common syntax errors, only emit if it
- // is the *only* error.
if self.sess.parse_sess.span_diagnostic.err_count() == 0 {
+ // To avoid noise about type ascription in common syntax errors,
+ // only emit if it is the *only* error.
gate_feature_post!(
&self,
type_ascription,
e.span,
"type ascription is experimental"
);
+ } else {
+ // And if it isn't, cancel the early-pass warning.
+ self.sess
+ .parse_sess
+ .span_diagnostic
+ .steal_diagnostic(e.span, StashKey::EarlySyntaxWarning)
+ .map(|err| err.cancel());
}
}
ast::ExprKind::TryBlock(_) => {
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
}
- ast::ExprKind::Block(_, Some(label)) => {
- gate_feature_post!(
- &self,
- label_break_value,
- label.ident.span,
- "labels on blocks are unstable"
- );
- }
_ => {}
}
visit::walk_expr(self, e)
@@ -690,7 +683,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
}
- visit::walk_fn(self, fn_kind, span)
+ visit::walk_fn(self, fn_kind)
}
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
@@ -708,7 +701,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
let is_fn = match i.kind {
ast::AssocItemKind::Fn(_) => true,
- ast::AssocItemKind::TyAlias(box ast::TyAlias { ref generics, ref ty, .. }) => {
+ ast::AssocItemKind::TyAlias(box ast::TyAlias { ref ty, .. }) => {
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!(
&self,
@@ -720,7 +713,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
if let Some(ty) = ty {
self.check_impl_trait(ty);
}
- self.check_gat(generics, i.span);
false
}
_ => false,
@@ -789,14 +781,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
// All uses of `gate_all!` below this point were added in #65742,
// and subsequently disabled (with the non-early gating readded).
+ // We emit an early future-incompatible warning for these.
+ // New syntax gates should go above here to get a hard error gate.
macro_rules! gate_all {
($gate:ident, $msg:literal) => {
- // FIXME(eddyb) do something more useful than always
- // disabling these uses of early feature-gatings.
- if false {
- for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
- gate_feature_post!(&visitor, $gate, *span, $msg);
- }
+ for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
+ gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg);
}
};
}
@@ -807,13 +797,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(box_patterns, "box pattern syntax is experimental");
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
gate_all!(try_blocks, "`try` blocks are unstable");
- gate_all!(label_break_value, "labels on blocks are unstable");
gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
- // To avoid noise about type ascription in common syntax errors,
- // only emit if it is the *only* error. (Also check it last.)
- if sess.parse_sess.span_diagnostic.err_count() == 0 {
- gate_all!(type_ascription, "type ascription is experimental");
- }
+ gate_all!(type_ascription, "type ascription is experimental");
visit::walk_crate(&mut visitor, krate);
}
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 9d52c3288..8aa9d57f0 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -9,10 +9,14 @@
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![recursion_limit = "256"]
+#[macro_use]
+extern crate tracing;
+
pub mod ast_validation;
+mod errors;
pub mod feature_gate;
pub mod node_count;
pub mod show_span;
diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs
index 9c7369c83..fa42f8778 100644
--- a/compiler/rustc_ast_passes/src/node_count.rs
+++ b/compiler/rustc_ast_passes/src/node_count.rs
@@ -63,9 +63,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_generics(self, g)
}
- fn visit_fn(&mut self, fk: visit::FnKind<'_>, s: Span, _: NodeId) {
+ fn visit_fn(&mut self, fk: visit::FnKind<'_>, _: Span, _: NodeId) {
self.count += 1;
- walk_fn(self, fk, s)
+ walk_fn(self, fk)
}
fn visit_assoc_item(&mut self, ti: &AssocItem, ctxt: AssocCtxt) {
self.count += 1;
@@ -79,9 +79,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_param_bound(self, bounds)
}
- fn visit_poly_trait_ref(&mut self, t: &PolyTraitRef, m: &TraitBoundModifier) {
+ fn visit_poly_trait_ref(&mut self, t: &PolyTraitRef) {
self.count += 1;
- walk_poly_trait_ref(self, t, m)
+ walk_poly_trait_ref(self, t)
}
fn visit_variant_data(&mut self, s: &VariantData) {
self.count += 1;
@@ -91,15 +91,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_field_def(self, s)
}
- fn visit_enum_def(
- &mut self,
- enum_definition: &EnumDef,
- generics: &Generics,
- item_id: NodeId,
- _: Span,
- ) {
+ fn visit_enum_def(&mut self, enum_definition: &EnumDef) {
self.count += 1;
- walk_enum_def(self, enum_definition, generics, item_id)
+ walk_enum_def(self, enum_definition)
}
fn visit_variant(&mut self, v: &Variant) {
self.count += 1;
@@ -121,9 +115,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_use_tree(self, use_tree, id)
}
- fn visit_generic_args(&mut self, path_span: Span, generic_args: &GenericArgs) {
+ fn visit_generic_args(&mut self, generic_args: &GenericArgs) {
self.count += 1;
- walk_generic_args(self, path_span, generic_args)
+ walk_generic_args(self, generic_args)
}
fn visit_assoc_constraint(&mut self, constraint: &AssocConstraint) {
self.count += 1;
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 79178830b..bf094af5f 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(with_negative_coherence)]
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 5eb7bf634..b87c6f78d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -11,8 +11,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser;
-use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
-use rustc_ast::{attr, Term};
+use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax};
+use rustc_ast::{attr, BindingAnnotation, ByRef, Term};
use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
@@ -22,6 +22,7 @@ use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol};
use rustc_span::{BytePos, FileName, Span};
+use rustc_ast::attr::AttrIdGenerator;
use std::borrow::Cow;
pub use self::delimited::IterDelimited;
@@ -107,6 +108,7 @@ pub fn print_crate<'a>(
ann: &'a dyn PpAnn,
is_expanded: bool,
edition: Edition,
+ g: &AttrIdGenerator,
) -> String {
let mut s =
State { s: pp::Printer::new(), comments: Some(Comments::new(sm, filename, input)), ann };
@@ -120,7 +122,7 @@ pub fn print_crate<'a>(
// `#![feature(prelude_import)]`
let pi_nested = attr::mk_nested_word_item(Ident::with_dummy_span(sym::prelude_import));
let list = attr::mk_list_item(Ident::with_dummy_span(sym::feature), vec![pi_nested]);
- let fake_attr = attr::mk_attr_inner(list);
+ let fake_attr = attr::mk_attr_inner(g, list);
s.print_attribute(&fake_attr);
// Currently, in Rust 2018 we don't have `extern crate std;` at the crate
@@ -128,7 +130,7 @@ pub fn print_crate<'a>(
if edition == Edition::Edition2015 {
// `#![no_std]`
let no_std_meta = attr::mk_word_item(Ident::with_dummy_span(sym::no_std));
- let fake_attr = attr::mk_attr_inner(no_std_meta);
+ let fake_attr = attr::mk_attr_inner(g, no_std_meta);
s.print_attribute(&fake_attr);
}
}
@@ -372,7 +374,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
fn print_literal(&mut self, lit: &ast::Lit) {
self.maybe_print_comment(lit.span.lo());
- self.word(lit.token.to_string())
+ self.word(lit.token_lit.to_string())
}
fn print_string(&mut self, st: &str, style: ast::StrStyle) {
@@ -442,12 +444,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
}
self.maybe_print_comment(attr.span.lo());
match attr.kind {
- ast::AttrKind::Normal(ref item, _) => {
+ ast::AttrKind::Normal(ref normal) => {
match attr.style {
ast::AttrStyle::Inner => self.word("#!["),
ast::AttrStyle::Outer => self.word("#["),
}
- self.print_attr_item(&item, attr.span);
+ self.print_attr_item(&normal.item, attr.span);
self.word("]");
}
ast::AttrKind::DocComment(comment_kind, data) => {
@@ -1399,16 +1401,12 @@ impl<'a> State<'a> {
is that it doesn't matter */
match pat.kind {
PatKind::Wild => self.word("_"),
- PatKind::Ident(binding_mode, ident, ref sub) => {
- match binding_mode {
- ast::BindingMode::ByRef(mutbl) => {
- self.word_nbsp("ref");
- self.print_mutability(mutbl, false);
- }
- ast::BindingMode::ByValue(ast::Mutability::Not) => {}
- ast::BindingMode::ByValue(ast::Mutability::Mut) => {
- self.word_nbsp("mut");
- }
+ PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => {
+ if by_ref == ByRef::Yes {
+ self.word_nbsp("ref");
+ }
+ if mutbl == Mutability::Mut {
+ self.word_nbsp("mut");
}
self.print_ident(ident);
if let Some(ref p) = *sub {
@@ -1487,12 +1485,10 @@ impl<'a> State<'a> {
}
PatKind::Ref(ref inner, mutbl) => {
self.word("&");
- if mutbl == ast::Mutability::Mut {
+ if mutbl == Mutability::Mut {
self.word("mut ");
}
- if let PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Mut), ..) =
- inner.kind
- {
+ if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind {
self.popen();
self.print_pat(inner);
self.pclose();
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index f1caf22f3..54bac29a6 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -218,6 +218,8 @@ impl<'a> State<'a> {
ast::ItemKind::GlobalAsm(ref asm) => {
self.head(visibility_qualified(&item.vis, "global_asm!"));
self.print_inline_asm(asm);
+ self.word(";");
+ self.end();
self.end();
}
ast::ItemKind::TyAlias(box ast::TyAlias {
@@ -412,9 +414,9 @@ impl<'a> State<'a> {
pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) {
match vis.kind {
ast::VisibilityKind::Public => self.word_nbsp("pub"),
- ast::VisibilityKind::Restricted { ref path, .. } => {
+ ast::VisibilityKind::Restricted { ref path, id: _, shorthand } => {
let path = Self::to_string(|s| s.print_path(path, false, 0));
- if path == "crate" || path == "self" || path == "super" {
+ if shorthand && (path == "crate" || path == "self" || path == "super") {
self.word_nbsp(format!("pub({})", path))
} else {
self.word_nbsp(format!("pub(in {})", path))
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 10a9cfb62..753f62dd5 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -3,7 +3,6 @@
use rustc_ast as ast;
use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId};
use rustc_ast_pretty::pprust;
-use rustc_errors::{struct_span_err, Applicability};
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
use rustc_macros::HashStable_Generic;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
@@ -14,6 +13,20 @@ use rustc_span::hygiene::Transparency;
use rustc_span::{symbol::sym, symbol::Symbol, Span};
use std::num::NonZeroU32;
+use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
+
+/// The version placeholder that recently stabilized features contain inside the
+/// `since` field of the `#[stable]` attribute.
+///
+/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591).
+pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
+
+pub fn rust_version_symbol() -> Symbol {
+ let version = option_env!("CFG_VERSION").unwrap_or("<current>");
+ let version = version.split(' ').next().unwrap();
+ Symbol::intern(&version)
+}
+
pub fn is_builtin_attr(attr: &Attribute) -> bool {
attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
}
@@ -25,46 +38,43 @@ enum AttrError {
NonIdentFeature,
MissingFeature,
MultipleStabilityLevels,
- UnsupportedLiteral(&'static str, /* is_bytestr */ bool),
+ UnsupportedLiteral(UnsupportedLiteralReason, /* is_bytestr */ bool),
+}
+
+pub(crate) enum UnsupportedLiteralReason {
+ Generic,
+ CfgString,
+ DeprecatedString,
+ DeprecatedKvPair,
}
fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
- let diag = &sess.span_diagnostic;
match error {
AttrError::MultipleItem(item) => {
- struct_span_err!(diag, span, E0538, "multiple '{}' items", item).emit();
+ sess.emit_err(session_diagnostics::MultipleItem { span, item });
}
AttrError::UnknownMetaItem(item, expected) => {
- let expected = expected.iter().map(|name| format!("`{}`", name)).collect::<Vec<_>>();
- struct_span_err!(diag, span, E0541, "unknown meta item '{}'", item)
- .span_label(span, format!("expected one of {}", expected.join(", ")))
- .emit();
+ sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected });
}
AttrError::MissingSince => {
- struct_span_err!(diag, span, E0542, "missing 'since'").emit();
+ sess.emit_err(session_diagnostics::MissingSince { span });
}
AttrError::NonIdentFeature => {
- struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit();
+ sess.emit_err(session_diagnostics::NonIdentFeature { span });
}
AttrError::MissingFeature => {
- struct_span_err!(diag, span, E0546, "missing 'feature'").emit();
+ sess.emit_err(session_diagnostics::MissingFeature { span });
}
AttrError::MultipleStabilityLevels => {
- struct_span_err!(diag, span, E0544, "multiple stability levels").emit();
+ sess.emit_err(session_diagnostics::MultipleStabilityLevels { span });
}
- AttrError::UnsupportedLiteral(msg, is_bytestr) => {
- let mut err = struct_span_err!(diag, span, E0565, "{}", msg);
- if is_bytestr {
- if let Ok(lint_str) = sess.source_map().span_to_snippet(span) {
- err.span_suggestion(
- span,
- "consider removing the prefix",
- &lint_str[1..],
- Applicability::MaybeIncorrect,
- );
- }
- }
- err.emit();
+ AttrError::UnsupportedLiteral(reason, is_bytestr) => {
+ sess.emit_err(session_diagnostics::UnsupportedLiteral {
+ span,
+ reason,
+ is_bytestr,
+ start_point_span: sess.source_map().start_point(span),
+ });
}
}
}
@@ -131,6 +141,14 @@ impl ConstStability {
}
}
+/// Represents the `#[rustc_default_body_unstable]` attribute.
+#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(HashStable_Generic)]
+pub struct DefaultBodyStability {
+ pub level: StabilityLevel,
+ pub feature: Symbol,
+}
+
/// The available stability levels.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic)]
@@ -214,7 +232,8 @@ pub fn find_stability(
sess: &Session,
attrs: &[Attribute],
item_sp: Span,
-) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>) {
+) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
+{
find_stability_generic(sess, attrs.iter(), item_sp)
}
@@ -222,7 +241,7 @@ fn find_stability_generic<'a, I>(
sess: &Session,
attrs_iter: I,
item_sp: Span,
-) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>)
+) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
where
I: Iterator<Item = &'a Attribute>,
{
@@ -230,11 +249,10 @@ where
let mut stab: Option<(Stability, Span)> = None;
let mut const_stab: Option<(ConstStability, Span)> = None;
+ let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
let mut promotable = false;
let mut allowed_through_unstable_modules = false;
- let diagnostic = &sess.parse_sess.span_diagnostic;
-
'outer: for attr in attrs_iter {
if ![
sym::rustc_const_unstable,
@@ -243,6 +261,7 @@ where
sym::stable,
sym::rustc_promotable,
sym::rustc_allowed_through_unstable_modules,
+ sym::rustc_default_body_unstable,
]
.iter()
.any(|&s| attr.has_name(s))
@@ -273,14 +292,14 @@ where
*item = Some(v);
true
} else {
- struct_span_err!(diagnostic, meta.span, E0539, "incorrect meta item").emit();
+ sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span });
false
}
};
let meta_name = meta.name_or_empty();
match meta_name {
- sym::rustc_const_unstable | sym::unstable => {
+ sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => {
if meta_name == sym::unstable && stab.is_some() {
handle_errors(
&sess.parse_sess,
@@ -295,6 +314,13 @@ where
AttrError::MultipleStabilityLevels,
);
break;
+ } else if meta_name == sym::rustc_default_body_unstable && body_stab.is_some() {
+ handle_errors(
+ &sess.parse_sess,
+ attr.span,
+ AttrError::MultipleStabilityLevels,
+ );
+ break;
}
let mut feature = None;
@@ -308,7 +334,7 @@ where
handle_errors(
&sess.parse_sess,
meta.span(),
- AttrError::UnsupportedLiteral("unsupported literal", false),
+ AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
);
continue 'outer;
};
@@ -332,39 +358,28 @@ where
// is a name/value pair string literal.
issue_num = match issue.unwrap().as_str() {
"none" => None,
- issue => {
- let emit_diag = |msg: &str| {
- struct_span_err!(
- diagnostic,
- mi.span,
- E0545,
- "`issue` must be a non-zero numeric string \
- or \"none\"",
- )
- .span_label(mi.name_value_literal_span().unwrap(), msg)
- .emit();
- };
- match issue.parse() {
- Ok(0) => {
- emit_diag(
- "`issue` must not be \"0\", \
- use \"none\" instead",
- );
- continue 'outer;
- }
- Ok(num) => NonZeroU32::new(num),
- Err(err) => {
- emit_diag(&err.to_string());
- continue 'outer;
- }
+ issue => match issue.parse::<NonZeroU32>() {
+ Ok(num) => Some(num),
+ Err(err) => {
+ sess.emit_err(
+ session_diagnostics::InvalidIssueString {
+ span: mi.span,
+ cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
+ mi.name_value_literal_span().unwrap(),
+ err.kind(),
+ ),
+ },
+ );
+ continue 'outer;
}
- }
+ },
};
}
sym::soft => {
if !mi.is_word() {
- let msg = "`soft` should not have any arguments";
- sess.parse_sess.span_diagnostic.span_err(mi.span, msg);
+ sess.emit_err(session_diagnostics::SoftNoArgs {
+ span: mi.span,
+ });
}
is_soft = true;
}
@@ -405,11 +420,16 @@ where
};
if sym::unstable == meta_name {
stab = Some((Stability { level, feature }, attr.span));
- } else {
+ } else if sym::rustc_const_unstable == meta_name {
const_stab = Some((
ConstStability { level, feature, promotable: false },
attr.span,
));
+ } else if sym::rustc_default_body_unstable == meta_name {
+ body_stab =
+ Some((DefaultBodyStability { level, feature }, attr.span));
+ } else {
+ unreachable!("Unknown stability attribute {meta_name}");
}
}
(None, _, _) => {
@@ -417,8 +437,7 @@ where
continue;
}
_ => {
- struct_span_err!(diagnostic, attr.span, E0547, "missing 'issue'")
- .emit();
+ sess.emit_err(session_diagnostics::MissingIssue { span: attr.span });
continue;
}
}
@@ -471,13 +490,20 @@ where
handle_errors(
&sess.parse_sess,
lit.span,
- AttrError::UnsupportedLiteral("unsupported literal", false),
+ AttrError::UnsupportedLiteral(
+ UnsupportedLiteralReason::Generic,
+ false,
+ ),
);
continue 'outer;
}
}
}
+ if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
+ since = Some(rust_version_symbol());
+ }
+
match (feature, since) {
(Some(feature), Some(since)) => {
let level = Stable { since, allowed_through_unstable_modules: false };
@@ -510,14 +536,7 @@ where
if let Some((ref mut stab, _)) = const_stab {
stab.promotable = promotable;
} else {
- struct_span_err!(
- diagnostic,
- item_sp,
- E0717,
- "`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` \
- or a `rustc_const_stable` attribute"
- )
- .emit();
+ sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp });
}
}
@@ -532,17 +551,11 @@ where
{
*allowed_through_unstable_modules = true;
} else {
- struct_span_err!(
- diagnostic,
- item_sp,
- E0789,
- "`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute"
- )
- .emit();
+ sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
}
}
- (stab, const_stab)
+ (stab, const_stab, body_stab)
}
pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option<Symbol> {
@@ -652,25 +665,18 @@ pub fn eval_condition(
NestedMetaItem::Literal(Lit { span, .. })
| NestedMetaItem::MetaItem(MetaItem { span, .. }),
] => {
- sess.span_diagnostic
- .struct_span_err(*span, "expected a version literal")
- .emit();
+ sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
return false;
}
[..] => {
- sess.span_diagnostic
- .struct_span_err(cfg.span, "expected single version literal")
- .emit();
+ sess.emit_err(session_diagnostics::ExpectedSingleVersionLiteral {
+ span: cfg.span,
+ });
return false;
}
};
let Some(min_version) = parse_version(min_version.as_str(), false) else {
- sess.span_diagnostic
- .struct_span_warn(
- *span,
- "unknown version literal format, assuming it refers to a future version",
- )
- .emit();
+ sess.emit_warning(session_diagnostics::UnknownVersionLiteral { span: *span });
return false;
};
let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap();
@@ -688,7 +694,7 @@ pub fn eval_condition(
handle_errors(
sess,
mi.span(),
- AttrError::UnsupportedLiteral("unsupported literal", false),
+ AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
);
return false;
}
@@ -713,13 +719,9 @@ pub fn eval_condition(
}),
sym::not => {
if mis.len() != 1 {
- struct_span_err!(
- sess.span_diagnostic,
- cfg.span,
- E0536,
- "expected 1 cfg-pattern"
- )
- .emit();
+ sess.emit_err(session_diagnostics::ExpectedOneCfgPattern {
+ span: cfg.span,
+ });
return false;
}
@@ -745,21 +747,16 @@ pub fn eval_condition(
})
}
_ => {
- struct_span_err!(
- sess.span_diagnostic,
- cfg.span,
- E0537,
- "invalid predicate `{}`",
- pprust::path_to_string(&cfg.path)
- )
- .emit();
+ sess.emit_err(session_diagnostics::InvalidPredicate {
+ span: cfg.span,
+ predicate: pprust::path_to_string(&cfg.path),
+ });
false
}
}
}
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");
+ sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
true
}
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => {
@@ -767,7 +764,7 @@ pub fn eval_condition(
sess,
lit.span,
AttrError::UnsupportedLiteral(
- "literal in `cfg` predicate value must be a string",
+ UnsupportedLiteralReason::CfgString,
lit.kind.is_bytestr(),
),
);
@@ -811,7 +808,6 @@ where
I: Iterator<Item = &'a Attribute>,
{
let mut depr: Option<(Deprecation, Span)> = None;
- let diagnostic = &sess.parse_sess.span_diagnostic;
let is_rustc = sess.features_untracked().staged_api;
'outer: for attr in attrs_iter {
@@ -847,14 +843,14 @@ where
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral(
- "literal in `deprecated` \
- value must be a string",
+ UnsupportedLiteralReason::DeprecatedString,
lit.kind.is_bytestr(),
),
);
} else {
- struct_span_err!(diagnostic, meta.span, E0551, "incorrect meta item")
- .emit();
+ sess.emit_err(session_diagnostics::IncorrectMetaItem2 {
+ span: meta.span,
+ });
}
false
@@ -876,14 +872,11 @@ where
}
sym::suggestion => {
if !sess.features_untracked().deprecated_suggestion {
- let mut diag = sess.struct_span_err(
- mi.span,
- "suggestions on deprecated items are unstable",
- );
- if sess.is_nightly_build() {
- diag.help("add `#![feature(deprecated_suggestion)]` to the crate root");
- }
- diag.note("see #94785 for more details").emit();
+ sess.emit_err(session_diagnostics::DeprecatedItemSuggestion {
+ span: mi.span,
+ is_nightly: sess.is_nightly_build().then_some(()),
+ details: (),
+ });
}
if !get(mi, &mut suggestion) {
@@ -911,7 +904,7 @@ where
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral(
- "item in `deprecated` must be a key/value pair",
+ UnsupportedLiteralReason::DeprecatedKvPair,
false,
),
);
@@ -929,7 +922,7 @@ where
}
if note.is_none() {
- struct_span_err!(diagnostic, attr.span, E0543, "missing 'note'").emit();
+ sess.emit_err(session_diagnostics::MissingNote { span: attr.span });
continue;
}
}
@@ -999,19 +992,9 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
sym::simd => Some(ReprSimd),
sym::transparent => Some(ReprTransparent),
sym::align => {
- let mut err = struct_span_err!(
- diagnostic,
- item.span(),
- E0589,
- "invalid `repr(align)` attribute: `align` needs an argument"
- );
- err.span_suggestion(
- item.span(),
- "supply an argument here",
- "align(...)",
- Applicability::HasPlaceholders,
- );
- err.emit();
+ sess.emit_err(session_diagnostics::InvalidReprAlignNeedArg {
+ span: item.span(),
+ });
recognised = true;
None
}
@@ -1040,109 +1023,64 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|| int_type_of_word(name).is_some()
{
recognised = true;
- struct_span_err!(
- diagnostic,
- item.span(),
- E0552,
- "invalid representation hint: `{}` does not take a parenthesized argument list",
- name.to_ident_string(),
- ).emit();
+ sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
+ span: item.span(),
+ name: name.to_ident_string(),
+ });
}
if let Some(literal_error) = literal_error {
- struct_span_err!(
- diagnostic,
- item.span(),
- E0589,
- "invalid `repr({})` attribute: {}",
- name.to_ident_string(),
- literal_error
- )
- .emit();
+ sess.emit_err(session_diagnostics::InvalidReprGeneric {
+ span: item.span(),
+ repr_arg: name.to_ident_string(),
+ error_part: literal_error,
+ });
}
} else if let Some(meta_item) = item.meta_item() {
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
let name = meta_item.name_or_empty().to_ident_string();
recognised = true;
- let mut err = struct_span_err!(
- diagnostic,
- item.span(),
- E0693,
- "incorrect `repr({})` attribute format",
- name,
- );
- match value.kind {
- ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
- err.span_suggestion(
- item.span(),
- "use parentheses instead",
- format!("{}({})", name, int),
- Applicability::MachineApplicable,
- );
- }
- ast::LitKind::Str(s, _) => {
- err.span_suggestion(
- item.span(),
- "use parentheses instead",
- format!("{}({})", name, s),
- Applicability::MachineApplicable,
- );
- }
- _ => {}
- }
- err.emit();
- } else {
- if matches!(
- meta_item.name_or_empty(),
- sym::C | sym::simd | sym::transparent
- ) || int_type_of_word(meta_item.name_or_empty()).is_some()
- {
- recognised = true;
- struct_span_err!(
- diagnostic,
- meta_item.span,
- E0552,
- "invalid representation hint: `{}` does not take a value",
- meta_item.name_or_empty().to_ident_string(),
- )
- .emit();
- }
+ sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
+ span: item.span(),
+ repr_arg: &name,
+ cause: IncorrectReprFormatGenericCause::from_lit_kind(
+ item.span(),
+ &value.kind,
+ &name,
+ ),
+ });
+ } else if matches!(
+ meta_item.name_or_empty(),
+ sym::C | sym::simd | sym::transparent
+ ) || int_type_of_word(meta_item.name_or_empty()).is_some()
+ {
+ recognised = true;
+ sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
+ span: meta_item.span,
+ name: meta_item.name_or_empty().to_ident_string(),
+ });
}
} else if let MetaItemKind::List(_) = meta_item.kind {
if meta_item.has_name(sym::align) {
recognised = true;
- struct_span_err!(
- diagnostic,
- meta_item.span,
- E0693,
- "incorrect `repr(align)` attribute format: \
- `align` takes exactly one argument in parentheses"
- )
- .emit();
+ sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
+ span: meta_item.span,
+ });
} else if meta_item.has_name(sym::packed) {
recognised = true;
- struct_span_err!(
- diagnostic,
- meta_item.span,
- E0552,
- "incorrect `repr(packed)` attribute format: \
- `packed` takes exactly one parenthesized argument, \
- or no parentheses at all"
- )
- .emit();
+ sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
+ span: meta_item.span,
+ });
} else if matches!(
meta_item.name_or_empty(),
sym::C | sym::simd | sym::transparent
) || int_type_of_word(meta_item.name_or_empty()).is_some()
{
recognised = true;
- struct_span_err!(
- diagnostic,
- meta_item.span,
- E0552,
- "invalid representation hint: `{}` does not take a parenthesized argument list",
- meta_item.name_or_empty().to_ident_string(),
- ).emit();
+ sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
+ span: meta_item.span,
+ name: meta_item.name_or_empty().to_ident_string(),
+ });
}
}
}
@@ -1239,10 +1177,10 @@ fn allow_unstable<'a>(
let list = attrs
.filter_map(move |attr| {
attr.meta_item_list().or_else(|| {
- sess.diagnostic().span_err(
- attr.span,
- &format!("`{}` expects a list of feature names", symbol.to_ident_string()),
- );
+ sess.emit_err(session_diagnostics::ExpectsFeatureList {
+ span: attr.span,
+ name: symbol.to_ident_string(),
+ });
None
})
})
@@ -1251,10 +1189,10 @@ fn allow_unstable<'a>(
list.into_iter().filter_map(move |it| {
let name = it.ident().map(|ident| ident.name);
if name.is_none() {
- sess.diagnostic().span_err(
- it.span(),
- &format!("`{}` expects feature names", symbol.to_ident_string()),
- );
+ sess.emit_err(session_diagnostics::ExpectsFeatures {
+ span: it.span(),
+ name: symbol.to_ident_string(),
+ });
}
name
})
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index c3f9f0cf3..52e65a9c7 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -5,12 +5,15 @@
//! to this crate.
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
mod builtin;
+mod session_diagnostics;
pub use builtin::*;
pub use IntType::*;
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
new file mode 100644
index 000000000..085175d4b
--- /dev/null
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -0,0 +1,398 @@
+use std::num::IntErrorKind;
+
+use rustc_ast as ast;
+use rustc_errors::{
+ error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler,
+};
+use rustc_macros::SessionDiagnostic;
+use rustc_session::SessionDiagnostic;
+use rustc_span::{Span, Symbol};
+
+use crate::UnsupportedLiteralReason;
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::expected_one_cfg_pattern, code = "E0536")]
+pub(crate) struct ExpectedOneCfgPattern {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::invalid_predicate, code = "E0537")]
+pub(crate) struct InvalidPredicate {
+ #[primary_span]
+ pub span: Span,
+
+ pub predicate: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::multiple_item, code = "E0538")]
+pub(crate) struct MultipleItem {
+ #[primary_span]
+ pub span: Span,
+
+ pub item: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::incorrect_meta_item, code = "E0539")]
+pub(crate) struct IncorrectMetaItem {
+ #[primary_span]
+ pub span: Span,
+}
+
+// Error code: E0541
+pub(crate) struct UnknownMetaItem<'a> {
+ pub span: Span,
+ pub item: String,
+ pub expected: &'a [&'a str],
+}
+
+// Manual implementation to be able to format `expected` items correctly.
+impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> {
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::<Vec<_>>();
+ let mut diag = handler.struct_span_err_with_code(
+ self.span,
+ fluent::attr::unknown_meta_item,
+ error_code!(E0541),
+ );
+ diag.set_arg("item", self.item);
+ diag.set_arg("expected", expected.join(", "));
+ diag.span_label(self.span, fluent::attr::label);
+ diag
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::missing_since, code = "E0542")]
+pub(crate) struct MissingSince {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::missing_note, code = "E0543")]
+pub(crate) struct MissingNote {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::multiple_stability_levels, code = "E0544")]
+pub(crate) struct MultipleStabilityLevels {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::invalid_issue_string, code = "E0545")]
+pub(crate) struct InvalidIssueString {
+ #[primary_span]
+ pub span: Span,
+
+ #[subdiagnostic]
+ pub cause: Option<InvalidIssueStringCause>,
+}
+
+// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be
+// translatable.
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum InvalidIssueStringCause {
+ #[label(attr::must_not_be_zero)]
+ MustNotBeZero {
+ #[primary_span]
+ span: Span,
+ },
+
+ #[label(attr::empty)]
+ Empty {
+ #[primary_span]
+ span: Span,
+ },
+
+ #[label(attr::invalid_digit)]
+ InvalidDigit {
+ #[primary_span]
+ span: Span,
+ },
+
+ #[label(attr::pos_overflow)]
+ PosOverflow {
+ #[primary_span]
+ span: Span,
+ },
+
+ #[label(attr::neg_overflow)]
+ NegOverflow {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+impl InvalidIssueStringCause {
+ pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
+ match kind {
+ IntErrorKind::Empty => Some(Self::Empty { span }),
+ IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
+ IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }),
+ IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }),
+ IntErrorKind::Zero => Some(Self::MustNotBeZero { span }),
+ _ => None,
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::missing_feature, code = "E0546")]
+pub(crate) struct MissingFeature {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::non_ident_feature, code = "E0546")]
+pub(crate) struct NonIdentFeature {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::missing_issue, code = "E0547")]
+pub(crate) struct MissingIssue {
+ #[primary_span]
+ pub span: Span,
+}
+
+// FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring the error code. Consider
+// changing this to `IncorrectMetaItem`. See #51489.
+#[derive(SessionDiagnostic)]
+#[diag(attr::incorrect_meta_item, code = "E0551")]
+pub(crate) struct IncorrectMetaItem2 {
+ #[primary_span]
+ pub span: Span,
+}
+
+// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
+// It is more similar to `IncorrectReprFormatGeneric`.
+#[derive(SessionDiagnostic)]
+#[diag(attr::incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")]
+pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::invalid_repr_hint_no_paren, code = "E0552")]
+pub(crate) struct InvalidReprHintNoParen {
+ #[primary_span]
+ pub span: Span,
+
+ pub name: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::invalid_repr_hint_no_value, code = "E0552")]
+pub(crate) struct InvalidReprHintNoValue {
+ #[primary_span]
+ pub span: Span,
+
+ pub name: String,
+}
+
+// Error code: E0565
+pub(crate) struct UnsupportedLiteral {
+ pub span: Span,
+ pub reason: UnsupportedLiteralReason,
+ pub is_bytestr: bool,
+ pub start_point_span: Span,
+}
+
+impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral {
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ let mut diag = handler.struct_span_err_with_code(
+ self.span,
+ match self.reason {
+ UnsupportedLiteralReason::Generic => fluent::attr::unsupported_literal_generic,
+ UnsupportedLiteralReason::CfgString => fluent::attr::unsupported_literal_cfg_string,
+ UnsupportedLiteralReason::DeprecatedString => {
+ fluent::attr::unsupported_literal_deprecated_string
+ }
+ UnsupportedLiteralReason::DeprecatedKvPair => {
+ fluent::attr::unsupported_literal_deprecated_kv_pair
+ }
+ },
+ error_code!(E0565),
+ );
+ if self.is_bytestr {
+ diag.span_suggestion(
+ self.start_point_span,
+ fluent::attr::unsupported_literal_suggestion,
+ "",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ diag
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::invalid_repr_align_need_arg, code = "E0589")]
+pub(crate) struct InvalidReprAlignNeedArg {
+ #[primary_span]
+ #[suggestion(code = "align(...)", applicability = "has-placeholders")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::invalid_repr_generic, code = "E0589")]
+pub(crate) struct InvalidReprGeneric<'a> {
+ #[primary_span]
+ pub span: Span,
+
+ pub repr_arg: String,
+ pub error_part: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::incorrect_repr_format_align_one_arg, code = "E0693")]
+pub(crate) struct IncorrectReprFormatAlignOneArg {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::incorrect_repr_format_generic, code = "E0693")]
+pub(crate) struct IncorrectReprFormatGeneric<'a> {
+ #[primary_span]
+ pub span: Span,
+
+ pub repr_arg: &'a str,
+
+ #[subdiagnostic]
+ pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum IncorrectReprFormatGenericCause<'a> {
+ #[suggestion(attr::suggestion, code = "{name}({int})", applicability = "machine-applicable")]
+ Int {
+ #[primary_span]
+ span: Span,
+
+ #[skip_arg]
+ name: &'a str,
+
+ #[skip_arg]
+ int: u128,
+ },
+
+ #[suggestion(
+ attr::suggestion,
+ code = "{name}({symbol})",
+ applicability = "machine-applicable"
+ )]
+ Symbol {
+ #[primary_span]
+ span: Span,
+
+ #[skip_arg]
+ name: &'a str,
+
+ #[skip_arg]
+ symbol: Symbol,
+ },
+}
+
+impl<'a> IncorrectReprFormatGenericCause<'a> {
+ pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
+ match kind {
+ ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
+ Some(Self::Int { span, name, int: *int })
+ }
+ ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
+ _ => None,
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::rustc_promotable_pairing, code = "E0717")]
+pub(crate) struct RustcPromotablePairing {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::rustc_allowed_unstable_pairing, code = "E0789")]
+pub(crate) struct RustcAllowedUnstablePairing {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::cfg_predicate_identifier)]
+pub(crate) struct CfgPredicateIdentifier {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::deprecated_item_suggestion)]
+pub(crate) struct DeprecatedItemSuggestion {
+ #[primary_span]
+ pub span: Span,
+
+ #[help]
+ pub is_nightly: Option<()>,
+
+ #[note]
+ pub details: (),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::expected_single_version_literal)]
+pub(crate) struct ExpectedSingleVersionLiteral {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::expected_version_literal)]
+pub(crate) struct ExpectedVersionLiteral {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::expects_feature_list)]
+pub(crate) struct ExpectsFeatureList {
+ #[primary_span]
+ pub span: Span,
+
+ pub name: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::expects_features)]
+pub(crate) struct ExpectsFeatures {
+ #[primary_span]
+ pub span: Span,
+
+ pub name: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::soft_no_args)]
+pub(crate) struct SoftNoArgs {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(attr::unknown_version_literal)]
+pub(crate) struct UnknownVersionLiteral {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs
index 5e9cec5c3..144fd15fc 100644
--- a/compiler/rustc_borrowck/src/constraint_generation.rs
+++ b/compiler/rustc_borrowck/src/constraint_generation.rs
@@ -31,7 +31,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>(
body,
};
- for (bb, data) in body.basic_blocks().iter_enumerated() {
+ for (bb, data) in body.basic_blocks.iter_enumerated() {
cg.visit_basic_block_data(bb, data);
}
}
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index a504d0c91..df0412813 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -21,10 +21,7 @@ pub(crate) struct OutlivesConstraintSet<'tcx> {
impl<'tcx> OutlivesConstraintSet<'tcx> {
pub(crate) fn push(&mut self, constraint: OutlivesConstraint<'tcx>) {
- debug!(
- "OutlivesConstraintSet::push({:?}: {:?} @ {:?}",
- constraint.sup, constraint.sub, constraint.locations
- );
+ debug!("OutlivesConstraintSet::push({:?})", constraint);
if constraint.sup == constraint.sub {
// 'a: 'a is pretty uninteresting
return;
@@ -73,7 +70,7 @@ impl<'tcx> Index<OutlivesConstraintIndex> for OutlivesConstraintSet<'tcx> {
}
}
-#[derive(Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq)]
pub struct OutlivesConstraint<'tcx> {
// NB. The ordering here is not significant for correctness, but
// it is for convenience. Before we dump the constraints in the
@@ -105,8 +102,8 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
- "({:?}: {:?}) due to {:?} ({:?})",
- self.sup, self.sub, self.locations, self.variance_info
+ "({:?}: {:?}) due to {:?} ({:?}) ({:?})",
+ self.sup, self.sub, self.locations, self.variance_info, self.category,
)
}
}
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 97d5a8d15..9f7a4d499 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -143,7 +143,7 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> {
fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self {
OutOfScopePrecomputer {
- visited: BitSet::new_empty(body.basic_blocks().len()),
+ visited: BitSet::new_empty(body.basic_blocks.len()),
visit_stack: vec![],
body,
regioncx,
@@ -391,7 +391,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
| mir::StatementKind::Retag { .. }
| mir::StatementKind::AscribeUserType(..)
| mir::StatementKind::Coverage(..)
- | mir::StatementKind::CopyNonOverlapping(..)
+ | mir::StatementKind::Intrinsic(..)
| mir::StatementKind::Nop => {}
}
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 1ef2b0ae9..b1def1892 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -484,9 +484,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
};
nice_error.try_report_from_nll().or_else(|| {
if let SubregionOrigin::Subtype(trace) = cause {
- Some(
- infcx.report_and_explain_type_error(*trace, &TypeError::RegionsPlaceholderMismatch),
- )
+ Some(infcx.report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch))
} else {
None
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 8bc8964bb..f2204c242 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -258,7 +258,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let ty = place.ty(self.body, self.infcx.tcx).ty;
// If we're in pattern, we do nothing in favor of the previous suggestion (#80913).
- if is_loop_move & !in_pattern {
+ // Same for if we're in a loop, see #101119.
+ if is_loop_move & !in_pattern && !matches!(use_spans, UseSpans::ClosureUse { .. }) {
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
// We have a `&mut` ref, we need to reborrow on each iteration (#62112).
err.span_suggestion_verbose(
@@ -451,7 +452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_borrow_fn_like(
&self,
- err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ err: &mut Diagnostic,
ty: Ty<'tcx>,
move_sites: &[MoveSite],
value_name: &str,
@@ -526,12 +527,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
true
}
- fn suggest_adding_copy_bounds(
- &self,
- err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
- ty: Ty<'tcx>,
- span: Span,
- ) {
+ fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());
@@ -1124,6 +1120,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// short a lifetime. (But sometimes it is more useful to report
/// it as a more direct conflict between the execution of a
/// `Drop::drop` with an aliasing borrow.)
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn report_borrowed_value_does_not_live_long_enough(
&mut self,
location: Location,
@@ -1131,13 +1128,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place_span: (Place<'tcx>, Span),
kind: Option<WriteKind>,
) {
- debug!(
- "report_borrowed_value_does_not_live_long_enough(\
- {:?}, {:?}, {:?}, {:?}\
- )",
- location, borrow, place_span, kind
- );
-
let drop_span = place_span.1;
let root_place =
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
@@ -1194,10 +1184,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0));
let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place);
- debug!(
- "report_borrowed_value_does_not_live_long_enough(place_desc: {:?}, explanation: {:?})",
- place_desc, explanation
- );
+ debug!(?place_desc, ?explanation);
+
let err = match (place_desc, explanation) {
// If the outlives constraint comes from inside the closure,
// for example:
@@ -1469,6 +1457,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err
}
+ #[instrument(level = "debug", skip(self))]
fn report_temporary_value_does_not_live_long_enough(
&mut self,
location: Location,
@@ -1478,13 +1467,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
proper_span: Span,
explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
- debug!(
- "report_temporary_value_does_not_live_long_enough(\
- {:?}, {:?}, {:?}, {:?}\
- )",
- location, borrow, drop_span, proper_span
- );
-
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation
{
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 72aee0267..1c01e78ab 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{self, RegionVid, TyCtxt};
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{sym, DesugaringKind, Span};
-use crate::region_infer::BlameConstraint;
+use crate::region_infer::{BlameConstraint, ExtraConstraintInfo};
use crate::{
borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt,
WriteKind,
@@ -38,6 +38,7 @@ pub(crate) enum BorrowExplanation<'tcx> {
span: Span,
region_name: RegionName,
opt_place_desc: Option<String>,
+ extra_info: Vec<ExtraConstraintInfo>,
},
Unexplained,
}
@@ -243,6 +244,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
ref region_name,
ref opt_place_desc,
from_closure: _,
+ ref extra_info,
} => {
region_name.highlight_region_name(err);
@@ -268,18 +270,30 @@ impl<'tcx> BorrowExplanation<'tcx> {
);
};
+ for extra in extra_info {
+ match extra {
+ ExtraConstraintInfo::PlaceholderFromPredicate(span) => {
+ err.span_note(*span, format!("due to current limitations in the borrow checker, this implies a `'static` lifetime"));
+ }
+ }
+ }
+
self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
}
_ => {}
}
}
- pub(crate) fn add_lifetime_bound_suggestion_to_diagnostic(
+
+ fn add_lifetime_bound_suggestion_to_diagnostic(
&self,
err: &mut Diagnostic,
category: &ConstraintCategory<'tcx>,
span: Span,
region_name: &RegionName,
) {
+ if !span.is_desugaring(DesugaringKind::OpaqueTy) {
+ return;
+ }
if let ConstraintCategory::OpaqueType = category {
let suggestable_name =
if region_name.was_named() { region_name.name } else { kw::UnderscoreLifetime };
@@ -305,18 +319,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self,
borrow_region: RegionVid,
outlived_region: RegionVid,
- ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>) {
- let BlameConstraint { category, from_closure, cause, variance_info: _ } =
- self.regioncx.best_blame_constraint(
- &self.body,
- borrow_region,
- NllRegionVariableOrigin::FreeRegion,
- |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region),
- );
+ ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) {
+ let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint(
+ borrow_region,
+ NllRegionVariableOrigin::FreeRegion,
+ |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region),
+ );
+ let BlameConstraint { category, from_closure, cause, .. } = blame_constraint;
let outlived_fr_name = self.give_region_a_name(outlived_region);
- (category, from_closure, cause.span, outlived_fr_name)
+ (category, from_closure, cause.span, outlived_fr_name, extra_info)
}
/// Returns structured explanation for *why* the borrow contains the
@@ -332,26 +345,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// - second half is the place being accessed
///
/// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn explain_why_borrow_contains_point(
&self,
location: Location,
borrow: &BorrowData<'tcx>,
kind_place: Option<(WriteKind, Place<'tcx>)>,
) -> BorrowExplanation<'tcx> {
- debug!(
- "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})",
- location, borrow, kind_place
- );
-
let regioncx = &self.regioncx;
let body: &Body<'_> = &self.body;
let tcx = self.infcx.tcx;
let borrow_region_vid = borrow.region;
- debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid);
+ debug!(?borrow_region_vid);
let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location);
- debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub);
+ debug!(?region_sub);
match find_use::find(body, regioncx, tcx, region_sub, location) {
Some(Cause::LiveVar(local, location)) => {
@@ -392,7 +401,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
None => {
if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
- let (category, from_closure, span, region_name) =
+ let (category, from_closure, span, region_name, extra_info) =
self.free_region_constraint_info(borrow_region_vid, region);
if let Some(region_name) = region_name {
let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
@@ -402,19 +411,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
span,
region_name,
opt_place_desc,
+ extra_info,
}
} else {
- debug!(
- "explain_why_borrow_contains_point: \
- Could not generate a region name"
- );
+ debug!("Could not generate a region name");
BorrowExplanation::Unexplained
}
} else {
- debug!(
- "explain_why_borrow_contains_point: \
- Could not generate an error region vid"
- );
+ debug!("Could not generate an error region vid");
BorrowExplanation::Unexplained
}
}
@@ -455,7 +459,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return outmost_back_edge;
}
- let block = &self.body.basic_blocks()[location.block];
+ let block = &self.body.basic_blocks[location.block];
if location.statement_index < block.statements.len() {
let successor = location.successor_within_block();
@@ -514,7 +518,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
if loop_head.dominates(from, &self.dominators) {
- let block = &self.body.basic_blocks()[from.block];
+ let block = &self.body.basic_blocks[from.block];
if from.statement_index < block.statements.len() {
let successor = from.successor_within_block();
@@ -564,7 +568,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
UseSpans::PatUse(span)
| UseSpans::OtherUse(span)
| UseSpans::FnSelfUse { var_span: span, .. } => {
- let block = &self.body.basic_blocks()[location.block];
+ let block = &self.body.basic_blocks[location.block];
let kind = if let Some(&Statement {
kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)),
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 098e8de94..683084cf0 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1086,14 +1086,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
),
);
}
- if is_option_or_result && maybe_reinitialized_locations_is_empty {
- err.span_suggestion_verbose(
- fn_call_span.shrink_to_lo(),
- "consider calling `.as_ref()` to borrow the type's contents",
- "as_ref().",
- Applicability::MachineApplicable,
- );
- }
// Avoid pointing to the same function in multiple different
// error messages.
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
@@ -1102,6 +1094,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
);
}
+ if is_option_or_result && maybe_reinitialized_locations_is_empty {
+ err.span_label(
+ var_span,
+ "help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents",
+ );
+ }
}
// Other desugarings takes &self, which cannot cause a move
_ => {}
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index cb3cd479a..8d4c38d3a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -88,7 +88,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(StatementKind::Assign(box (
place,
Rvalue::Use(Operand::Move(move_from)),
- ))) = self.body.basic_blocks()[location.block]
+ ))) = self.body.basic_blocks[location.block]
.statements
.get(location.statement_index)
.map(|stmt| &stmt.kind)
@@ -360,7 +360,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
diag.span_label(upvar_span, "captured outer variable");
diag.span_label(
- self.body.span,
+ self.infcx.tcx.def_span(def_id),
format!("captured by this `{closure_kind}` closure"),
);
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 0ad4abbce..6b5014fa9 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1,23 +1,23 @@
+use rustc_errors::{
+ Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
+};
use rustc_hir as hir;
+use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_middle::hir::map::Map;
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{
hir::place::PlaceBase,
- mir::{
- self, BindingForm, ClearCrossCrate, ImplicitSelfKind, Local, LocalDecl, LocalInfo,
- LocalKind, Location,
- },
+ mir::{self, BindingForm, ClearCrossCrate, Local, LocalDecl, LocalInfo, LocalKind, Location},
};
use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::{sym, BytePos, Span};
use crate::diagnostics::BorrowedContentSource;
use crate::MirBorrowckCtxt;
use rustc_const_eval::util::collect_writes::FindAssignments;
-use rustc_errors::{Applicability, Diagnostic};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum AccessKind {
@@ -309,7 +309,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&& !matches!(
decl.local_info,
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
- ImplicitSelfKind::MutRef
+ hir::ImplicitSelfKind::MutRef
))))
)
{
@@ -364,7 +364,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
&& let hir::PatKind::Binding(
- hir::BindingAnnotation::Unannotated,
+ hir::BindingAnnotation::NONE,
_,
upvar_ident,
_,
@@ -614,6 +614,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
"trait `IndexMut` is required to modify indexed content, \
but it is not implemented for `{ty}`",
));
+ self.suggest_map_index_mut_alternatives(ty, &mut err, span);
}
_ => (),
}
@@ -627,6 +628,127 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.buffer_error(err);
}
+ fn suggest_map_index_mut_alternatives(
+ &self,
+ ty: Ty<'_>,
+ err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+ span: Span,
+ ) {
+ let Some(adt) = ty.ty_adt_def() else { return };
+ let did = adt.did();
+ if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
+ || self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did)
+ {
+ struct V<'a, 'b, 'tcx, G: EmissionGuarantee> {
+ assign_span: Span,
+ err: &'a mut DiagnosticBuilder<'b, G>,
+ ty: Ty<'tcx>,
+ suggested: bool,
+ }
+ impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> {
+ fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) {
+ hir::intravisit::walk_stmt(self, stmt);
+ let expr = match stmt.kind {
+ hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr,
+ hir::StmtKind::Local(hir::Local { init: Some(expr), .. }) => expr,
+ _ => {
+ return;
+ }
+ };
+ if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
+ && let hir::ExprKind::Index(val, index) = place.kind
+ && (expr.span == self.assign_span || place.span == self.assign_span)
+ {
+ // val[index] = rv;
+ // ---------- place
+ self.err.multipart_suggestions(
+ &format!(
+ "to modify a `{}`, use `.get_mut()`, `.insert()` or the entry API",
+ self.ty,
+ ),
+ vec![
+ vec![ // val.insert(index, rv);
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".insert(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(rv.span.lo()),
+ ", ".to_string(),
+ ),
+ (rv.span.shrink_to_hi(), ")".to_string()),
+ ],
+ vec![ // val.get_mut(index).map(|v| { *v = rv; });
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".get_mut(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(place.span.hi()),
+ ").map(|val| { *val".to_string(),
+ ),
+ (
+ rv.span.shrink_to_hi(),
+ "; })".to_string(),
+ ),
+ ],
+ vec![ // let x = val.entry(index).or_insert(rv);
+ (val.span.shrink_to_lo(), "let val = ".to_string()),
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".entry(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(rv.span.lo()),
+ ").or_insert(".to_string(),
+ ),
+ (rv.span.shrink_to_hi(), ")".to_string()),
+ ],
+ ].into_iter(),
+ Applicability::MachineApplicable,
+ );
+ self.suggested = true;
+ } else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
+ && let hir::ExprKind::Index(val, index) = receiver.kind
+ && expr.span == self.assign_span
+ {
+ // val[index].path(args..);
+ self.err.multipart_suggestion(
+ &format!("to modify a `{}` use `.get_mut()`", self.ty),
+ vec![
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".get_mut(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(receiver.span.hi()),
+ ").map(|val| val".to_string(),
+ ),
+ (sp.shrink_to_hi(), ")".to_string()),
+ ],
+ Applicability::MachineApplicable,
+ );
+ self.suggested = true;
+ }
+ }
+ }
+ let hir_map = self.infcx.tcx.hir();
+ let def_id = self.body.source.def_id();
+ let hir_id = hir_map.local_def_id_to_hir_id(def_id.as_local().unwrap());
+ let node = hir_map.find(hir_id);
+ let Some(hir::Node::Item(item)) = node else { return; };
+ let hir::ItemKind::Fn(.., body_id) = item.kind else { return; };
+ let body = self.infcx.tcx.hir().body(body_id);
+ let mut v = V { assign_span: span, err, ty, suggested: false };
+ v.visit_body(body);
+ if !v.suggested {
+ err.help(&format!(
+ "to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API",
+ ));
+ }
+ }
+ }
+
/// User cannot make signature of a trait mutable without changing the
/// trait. So we find if this error belongs to a trait and if so we move
/// suggestion to the trait or disable it if it is out of scope of this crate
@@ -786,11 +908,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
[
Expr {
kind:
- MethodCall(
- path_segment,
- _args,
- span,
- ),
+ MethodCall(path_segment, _, _, span),
hir_id,
..
},
@@ -810,10 +928,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
_,
) = hir_map.body(fn_body_id).value.kind
{
- let opt_suggestions = path_segment
- .hir_id
- .map(|path_hir_id| self.infcx.tcx.typeck(path_hir_id.owner))
- .and_then(|typeck| typeck.type_dependent_def_id(*hir_id))
+ let opt_suggestions = self
+ .infcx
+ .tcx
+ .typeck(path_segment.hir_id.owner)
+ .type_dependent_def_id(*hir_id)
.and_then(|def_id| self.infcx.tcx.impl_of_method(def_id))
.map(|def_id| self.infcx.tcx.associated_items(def_id))
.map(|assoc_items| {
@@ -851,6 +970,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let hir = self.infcx.tcx.hir();
let closure_id = self.mir_hir_id();
+ let closure_span = self.infcx.tcx.def_span(self.mir_def_id());
let fn_call_id = hir.get_parent_node(closure_id);
let node = hir.get(fn_call_id);
let def_id = hir.enclosing_body_owner(fn_call_id);
@@ -902,7 +1022,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(span) = arg {
err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
err.span_label(func.span, "expects `Fn` instead of `FnMut`");
- err.span_label(self.body.span, "in this closure");
+ err.span_label(closure_span, "in this closure");
look_at_return = false;
}
}
@@ -928,7 +1048,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
sig.decl.output.span(),
"change this to return `FnMut` instead of `Fn`",
);
- err.span_label(self.body.span, "in this closure");
+ err.span_label(closure_span, "in this closure");
}
_ => {}
}
@@ -952,7 +1072,7 @@ fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symb
//
// Deliberately fall into this case for all implicit self types,
// so that we don't fall in to the next case with them.
- *kind == mir::ImplicitSelfKind::MutRef
+ *kind == hir::ImplicitSelfKind::MutRef
}
_ if Some(kw::SelfLower) == local_name => {
// Otherwise, check if the name is the `self` keyword - in which case
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index d359d7efb..35c3df768 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -6,7 +6,6 @@ use rustc_errors::Diagnostic;
use rustc_middle::ty::RegionVid;
use smallvec::SmallVec;
use std::collections::BTreeMap;
-use tracing::debug;
use crate::MirBorrowckCtxt;
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 176090c3b..34be2874f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
//! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxHashSet;
@@ -23,10 +25,13 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use crate::borrowck_errors;
-use crate::session_diagnostics::GenericDoesNotLiveLongEnough;
+use crate::session_diagnostics::{
+ FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr,
+ LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
+};
use super::{OutlivesSuggestionBuilder, RegionName};
-use crate::region_infer::BlameConstraint;
+use crate::region_infer::{BlameConstraint, ExtraConstraintInfo};
use crate::{
nll::ConstraintDescription,
region_infer::{values::RegionElement, TypeTest},
@@ -229,7 +234,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
let (_, cause) = self.regioncx.find_outlives_blame_span(
- &self.body,
longer_fr,
NllRegionVariableOrigin::Placeholder(placeholder),
error_vid,
@@ -350,10 +354,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
) {
debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
- let BlameConstraint { category, cause, variance_info, from_closure: _ } =
- self.regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| {
+ let (blame_constraint, extra_info) =
+ self.regioncx.best_blame_constraint(fr, fr_origin, |r| {
self.regioncx.provides_universal_region(r, fr, outlived_fr)
});
+ let BlameConstraint { category, cause, variance_info, .. } = blame_constraint;
debug!("report_region_error: category={:?} {:?} {:?}", category, cause, variance_info);
@@ -462,6 +467,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
+ for extra in extra_info {
+ match extra {
+ ExtraConstraintInfo::PlaceholderFromPredicate(span) => {
+ diag.span_note(span, format!("due to current limitations in the borrow checker, this implies a `'static` lifetime"));
+ }
+ }
+ }
+
self.buffer_error(diag);
}
@@ -488,12 +501,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
- let mut diag = self
- .infcx
- .tcx
- .sess
- .struct_span_err(*span, "captured variable cannot escape `FnMut` closure body");
-
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
if let ty::Opaque(def_id, _) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id)
@@ -501,19 +508,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
debug!("report_fnmut_error: output_ty={:?}", output_ty);
- let message = match output_ty.kind() {
- ty::Closure(_, _) => {
- "returns a closure that contains a reference to a captured variable, which then \
- escapes the closure body"
- }
- ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => {
- "returns an `async` block that contains a reference to a captured variable, which then \
- escapes the closure body"
- }
- _ => "returns a reference to a captured variable which escapes the closure body",
+ let err = FnMutError {
+ span: *span,
+ ty_err: match output_ty.kind() {
+ ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
+ ty::Adt(def, _)
+ if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) =>
+ {
+ FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
+ }
+ _ => FnMutReturnTypeErr::ReturnRef { span: *span },
+ },
};
- diag.span_label(*span, message);
+ let mut diag = self.infcx.tcx.sess.create_err(err);
if let ReturnConstraint::ClosureUpvar(upvar_field) = kind {
let def_id = match self.regioncx.universal_regions().defining_ty {
@@ -532,20 +540,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap();
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");
+ diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span });
+ diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span });
}
}
if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() {
- diag.span_label(fr_span, "inferred to be a `FnMut` closure");
+ diag.subdiagnostic(VarHereDenote::FnMutInferred { span: fr_span });
}
- diag.note(
- "`FnMut` closures only have access to their captured variables while they are \
- executing...",
- );
- diag.note("...therefore, they cannot allow references to captured variables to escape");
+ self.suggest_move_on_borrowing_closure(&mut diag);
diag
}
@@ -562,6 +566,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// LL | ref_obj(x)
/// | ^^^^^^^^^^ `x` escapes the function body here
/// ```
+ #[instrument(level = "debug", skip(self))]
fn report_escaping_data_error(
&self,
errci: &ErrorConstraintInfo<'tcx>,
@@ -680,42 +685,37 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
..
} = errci;
- let mut diag =
- self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough");
-
let (_, mir_def_name) =
self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id());
+ let err = LifetimeOutliveErr { span: *span };
+ let mut diag = self.infcx.tcx.sess.create_err(err);
+
let fr_name = self.give_region_a_name(*fr).unwrap();
fr_name.highlight_region_name(&mut diag);
let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap();
outlived_fr_name.highlight_region_name(&mut diag);
- match (category, outlived_fr_is_local, fr_is_local) {
- (ConstraintCategory::Return(_), true, _) => {
- diag.span_label(
- *span,
- format!(
- "{mir_def_name} was supposed to return data with lifetime `{outlived_fr_name}` but it is returning \
- data with lifetime `{fr_name}`",
- ),
- );
- }
- _ => {
- diag.span_label(
- *span,
- format!(
- "{}requires that `{}` must outlive `{}`",
- category.description(),
- fr_name,
- outlived_fr_name,
- ),
- );
- }
- }
+ let err_category = match (category, outlived_fr_is_local, fr_is_local) {
+ (ConstraintCategory::Return(_), true, _) => LifetimeReturnCategoryErr::WrongReturn {
+ span: *span,
+ mir_def_name,
+ outlived_fr_name,
+ fr_name: &fr_name,
+ },
+ _ => LifetimeReturnCategoryErr::ShortReturn {
+ span: *span,
+ category_desc: category.description(),
+ free_region_name: &fr_name,
+ outlived_fr_name,
+ },
+ };
+
+ diag.subdiagnostic(err_category);
self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr);
self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr);
+ self.suggest_move_on_borrowing_closure(&mut diag);
diag
}
@@ -783,7 +783,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn maybe_suggest_constrain_dyn_trait_impl(
&self,
- diag: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ diag: &mut Diagnostic,
f: Region<'tcx>,
o: Region<'tcx>,
category: &ConstraintCategory<'tcx>,
@@ -860,7 +860,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ident.span,
"calling this method introduces the `impl`'s 'static` requirement",
);
- err.span_note(multi_span, "the used `impl` has a `'static` requirement");
+ err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span });
err.span_suggestion_verbose(
span.shrink_to_hi(),
"consider relaxing the implicit `'static` requirement",
@@ -901,4 +901,46 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag);
}
+
+ fn suggest_move_on_borrowing_closure(&self, diag: &mut Diagnostic) {
+ let map = self.infcx.tcx.hir();
+ let body_id = map.body_owned_by(self.mir_def_id());
+ let expr = &map.body(body_id).value;
+ let mut closure_span = None::<rustc_span::Span>;
+ match expr.kind {
+ hir::ExprKind::MethodCall(.., args, _) => {
+ for arg in args {
+ if let hir::ExprKind::Closure(hir::Closure {
+ capture_clause: hir::CaptureBy::Ref,
+ ..
+ }) = arg.kind
+ {
+ closure_span = Some(arg.span.shrink_to_lo());
+ break;
+ }
+ }
+ }
+ hir::ExprKind::Block(blk, _) => {
+ if let Some(ref expr) = blk.expr {
+ // only when the block is a closure
+ if let hir::ExprKind::Closure(hir::Closure {
+ capture_clause: hir::CaptureBy::Ref,
+ ..
+ }) = expr.kind
+ {
+ closure_span = Some(expr.span.shrink_to_lo());
+ }
+ }
+ }
+ _ => {}
+ }
+ if let Some(closure_span) = closure_span {
+ diag.span_suggestion_verbose(
+ closure_span,
+ "consider adding 'move' keyword before the nested closure",
+ "move ",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index a87e8bd5b..6c1eaa809 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -265,7 +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))]
+ #[instrument(level = "trace", skip(self))]
fn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName> {
let error_region = self.to_error_region(fr)?;
@@ -357,11 +357,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
ty::BoundRegionKind::BrAnon(_) => None,
},
- ty::ReLateBound(..)
- | ty::ReVar(..)
- | ty::RePlaceholder(..)
- | ty::ReEmpty(_)
- | ty::ReErased => None,
+ ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None,
}
}
@@ -373,7 +369,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// | fn foo(x: &u32) { .. }
/// ------- fully elaborated type of `x` is `&'1 u32`
/// ```
- #[tracing::instrument(level = "trace", skip(self))]
+ #[instrument(level = "trace", skip(self))]
fn give_name_if_anonymous_region_appears_in_arguments(
&self,
fr: RegionVid,
@@ -662,7 +658,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// | let x = Some(&22);
/// - fully elaborated type of `x` is `Option<&'1 u32>`
/// ```
- #[tracing::instrument(level = "trace", skip(self))]
+ #[instrument(level = "trace", skip(self))]
fn give_name_if_anonymous_region_appears_in_upvars(&self, fr: RegionVid) -> Option<RegionName> {
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(
@@ -682,7 +678,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))]
+ #[instrument(level = "trace", skip(self))]
fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option<RegionName> {
let tcx = self.infcx.tcx;
let hir = tcx.hir();
@@ -772,7 +768,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
let hir = self.infcx.tcx.hir();
- let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
+ let hir::TyKind::OpaqueDef(id, _, _) = hir_ty.kind else {
span_bug!(
hir_ty.span,
"lowered return type of async fn is not OpaqueDef: {:?}",
@@ -814,7 +810,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}
}
- #[tracing::instrument(level = "trace", skip(self))]
+ #[instrument(level = "trace", skip(self))]
fn give_name_if_anonymous_region_appears_in_yield_ty(
&self,
fr: RegionVid,
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs
index ec521b1cf..3157f861d 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/invalidation.rs
@@ -1,6 +1,6 @@
use rustc_data_structures::graph::dominators::Dominators;
use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{BasicBlock, Body, Location, Place, Rvalue};
+use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue};
use rustc_middle::mir::{BorrowKind, Mutability, Operand};
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::mir::{Statement, StatementKind};
@@ -63,23 +63,24 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
StatementKind::FakeRead(box (_, _)) => {
// Only relevant for initialized/liveness/safety checks.
}
- StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
+ self.consume_operand(location, op);
+ }
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
ref src,
ref dst,
ref count,
- }) => {
+ })) => {
self.consume_operand(location, src);
self.consume_operand(location, dst);
self.consume_operand(location, count);
}
- StatementKind::Nop
+ // Only relevant for mir typeck
+ StatementKind::AscribeUserType(..)
+ // Doesn't have any language semantics
| StatementKind::Coverage(..)
- | StatementKind::AscribeUserType(..)
- | StatementKind::Retag { .. }
- | StatementKind::StorageLive(..) => {
- // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant
- // to borrow check.
- }
+ // Does not actually affect borrowck
+ | StatementKind::StorageLive(..) => {}
StatementKind::StorageDead(local) => {
self.access_place(
location,
@@ -88,7 +89,10 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
LocalMutationIsAllowed::Yes,
);
}
- StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+ StatementKind::Nop
+ | StatementKind::Retag { .. }
+ | StatementKind::Deinit(..)
+ | StatementKind::SetDiscriminant { .. } => {
bug!("Statement not allowed in this MIR phase")
}
}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 3d8b07382..86da87d06 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -3,7 +3,7 @@
#![allow(rustc::potential_query_instability)]
#![feature(box_patterns)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]
@@ -19,15 +19,15 @@ extern crate tracing;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet;
use rustc_index::vec::IndexVec;
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
use rustc_middle::mir::{
- traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem,
- PlaceRef, VarDebugInfoContents,
+ traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand,
+ Place, PlaceElem, PlaceRef, VarDebugInfoContents,
};
use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
@@ -51,6 +51,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE
use rustc_mir_dataflow::Analysis;
use rustc_mir_dataflow::MoveDataParamEnv;
+use crate::session_diagnostics::VarNeedNotMut;
+
use self::diagnostics::{AccessKind, RegionName};
use self::location::LocationTable;
use self::prefixes::PrefixSet;
@@ -425,17 +427,9 @@ fn do_mir_borrowck<'a, 'tcx>(
continue;
}
- tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| {
- let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
- lint.build("variable does not need to be mutable")
- .span_suggestion_short(
- mut_span,
- "remove this `mut`",
- "",
- Applicability::MachineApplicable,
- )
- .emit();
- })
+ let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
+
+ tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
}
let tainted_by_errors = mbcx.emit_errors();
@@ -597,22 +591,19 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
flow_state,
);
}
- StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
- ..
- }) => {
- span_bug!(
+ StatementKind::Intrinsic(box ref kind) => match kind {
+ NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
+ NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
span,
"Unexpected CopyNonOverlapping, should only appear after lower_intrinsics",
)
}
- StatementKind::Nop
+ // Only relevant for mir typeck
+ StatementKind::AscribeUserType(..)
+ // Doesn't have any language semantics
| StatementKind::Coverage(..)
- | StatementKind::AscribeUserType(..)
- | StatementKind::Retag { .. }
- | StatementKind::StorageLive(..) => {
- // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant
- // to borrow check.
- }
+ // Does not actually affect borrowck
+ | StatementKind::StorageLive(..) => {}
StatementKind::StorageDead(local) => {
self.access_place(
location,
@@ -622,7 +613,10 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
flow_state,
);
}
- StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+ StatementKind::Nop
+ | StatementKind::Retag { .. }
+ | StatementKind::Deinit(..)
+ | StatementKind::SetDiscriminant { .. } => {
bug!("Statement not allowed in this MIR phase")
}
}
@@ -982,6 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self, flow_state))]
fn check_access_for_conflict(
&mut self,
location: Location,
@@ -990,11 +985,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
rw: ReadOrWrite,
flow_state: &Flows<'cx, 'tcx>,
) -> bool {
- debug!(
- "check_access_for_conflict(location={:?}, place_span={:?}, sd={:?}, rw={:?})",
- location, place_span, sd, rw,
- );
-
let mut error_reported = false;
let tcx = self.infcx.tcx;
let body = self.body;
@@ -1458,13 +1448,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// Checks whether a borrow of this place is invalidated when the function
/// exits
+ #[instrument(level = "debug", skip(self))]
fn check_for_invalidation_at_exit(
&mut self,
location: Location,
borrow: &BorrowData<'tcx>,
span: Span,
) {
- debug!("check_for_invalidation_at_exit({:?})", borrow);
let place = borrow.borrowed_place;
let mut root_place = PlaceRef { local: place.local, projection: &[] };
diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs
index 70a311694..877944d3d 100644
--- a/compiler/rustc_borrowck/src/location.rs
+++ b/compiler/rustc_borrowck/src/location.rs
@@ -33,7 +33,7 @@ impl LocationTable {
pub(crate) fn new(body: &Body<'_>) -> Self {
let mut num_points = 0;
let statements_before_block = body
- .basic_blocks()
+ .basic_blocks
.iter()
.map(|block_data| {
let v = num_points;
@@ -86,8 +86,7 @@ impl LocationTable {
let (block, &first_index) = self
.statements_before_block
.iter_enumerated()
- .filter(|(_, first_index)| **first_index <= point_index)
- .last()
+ .rfind(|&(_, &first_index)| first_index <= point_index)
.unwrap();
let statement_index = (point_index - first_index) / 2;
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 0961203d7..12b2481cc 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -389,8 +389,9 @@ pub(super) fn dump_annotation<'a, 'tcx>(
// viewing the intraprocedural state, the -Zdump-mir output is
// better.
+ let def_span = tcx.def_span(body.source.def_id());
let mut err = if let Some(closure_region_requirements) = closure_region_requirements {
- let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "external requirements");
+ let mut err = tcx.sess.diagnostic().span_note_diag(def_span, "external requirements");
regioncx.annotate(tcx, &mut err);
@@ -409,7 +410,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
err
} else {
- let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "no external requirements");
+ let mut err = tcx.sess.diagnostic().span_note_diag(def_span, "no external requirements");
regioncx.annotate(tcx, &mut err);
err
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 97335fd0d..6e5a96bee 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -44,6 +44,7 @@ pub(crate) fn places_conflict<'tcx>(
/// access depth. The `bias` parameter is used to determine how the unknowable (comparing runtime
/// array indices, for example) should be interpreted - this depends on what the caller wants in
/// order to make the conservative choice and preserve soundness.
+#[instrument(level = "debug", skip(tcx, body))]
pub(super) fn borrow_conflicts_with_place<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
@@ -53,11 +54,6 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
access: AccessDepth,
bias: PlaceConflictBias,
) -> bool {
- debug!(
- "borrow_conflicts_with_place({:?}, {:?}, {:?}, {:?})",
- borrow_place, access_place, access, bias,
- );
-
// This Local/Local case is handled by the more general code below, but
// it's so common that it's a speed win to check for it first.
if let Some(l1) = borrow_place.as_local() && let Some(l2) = access_place.as_local() {
@@ -140,10 +136,9 @@ fn place_components_conflict<'tcx>(
for (i, (borrow_c, &access_c)) in
iter::zip(borrow_place.projection, access_place.projection).enumerate()
{
- debug!("borrow_conflicts_with_place: borrow_c = {:?}", borrow_c);
- let borrow_proj_base = &borrow_place.projection[..i];
+ debug!(?borrow_c, ?access_c);
- debug!("borrow_conflicts_with_place: access_c = {:?}", access_c);
+ let borrow_proj_base = &borrow_place.projection[..i];
// Borrow and access path both have more components.
//
@@ -180,7 +175,7 @@ fn place_components_conflict<'tcx>(
// idea, at least for now, so just give up and
// report a conflict. This is unsafe code anyway so
// the user could always use raw pointers.
- debug!("borrow_conflicts_with_place: arbitrary -> conflict");
+ debug!("arbitrary -> conflict");
return true;
}
Overlap::EqualOrDisjoint => {
@@ -189,7 +184,7 @@ fn place_components_conflict<'tcx>(
Overlap::Disjoint => {
// We have proven the borrow disjoint - further
// projections will remain disjoint.
- debug!("borrow_conflicts_with_place: disjoint");
+ debug!("disjoint");
return false;
}
}
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 2894c6d29..244e6e342 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -135,7 +135,6 @@ pub struct RegionInferenceContext<'tcx> {
/// adds a new lower bound to the SCC it is analyzing: so you wind up
/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
/// minimal viable option.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub(crate) struct AppliedMemberConstraint {
/// The SCC that was affected. (The "member region".)
///
@@ -246,6 +245,11 @@ enum Trace<'tcx> {
NotVisited,
}
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub enum ExtraConstraintInfo {
+ PlaceholderFromPredicate(Span),
+}
+
impl<'tcx> RegionInferenceContext<'tcx> {
/// Creates a new region inference context with a total of
/// `num_region_variables` valid inference variables; the first N
@@ -591,13 +595,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// constraints were too strong, and if so, emit or propagate those errors.
if infcx.tcx.sess.opts.unstable_opts.polonius {
self.check_polonius_subset_errors(
- body,
outlives_requirements.as_mut(),
&mut errors_buffer,
polonius_output.expect("Polonius output is unavailable despite `-Z polonius`"),
);
} else {
- self.check_universal_regions(body, outlives_requirements.as_mut(), &mut errors_buffer);
+ self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
}
if errors_buffer.is_empty() {
@@ -1139,7 +1142,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// include the CFG anyhow.
/// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
/// a result `'y`.
- #[instrument(skip(self), level = "debug")]
+ #[instrument(skip(self), level = "debug", ret)]
pub(crate) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
debug!(r = %self.region_value_str(r));
@@ -1151,8 +1154,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
}
- debug!(?lub);
-
lub
}
@@ -1167,8 +1168,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Therefore, this method should only be used in diagnostic code,
/// where displaying *some* named universal region is better than
/// falling back to 'static.
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn approx_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
- debug!("approx_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
+ debug!("{}", self.region_value_str(r));
// Find the smallest universal region that contains all other
// universal regions within `region`.
@@ -1177,7 +1179,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let static_r = self.universal_regions.fr_static;
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
- debug!("approx_universal_upper_bound: ur={:?} lub={:?} new_lub={:?}", ur, lub, new_lub);
+ debug!(?ur, ?lub, ?new_lub);
// The upper bound of two non-static regions is static: this
// means we know nothing about the relationship between these
// two regions. Pick a 'better' one to use when constructing
@@ -1201,7 +1203,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}
- debug!("approx_universal_upper_bound: r={:?} lub={:?}", r, lub);
+ debug!(?r, ?lub);
lub
}
@@ -1332,15 +1334,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
// Evaluate whether `sup_region: sub_region`.
- #[instrument(skip(self), level = "debug")]
+ #[instrument(skip(self), level = "debug", ret)]
fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
debug!(
- "eval_outlives: sup_region's value = {:?} universal={:?}",
+ "sup_region's value = {:?} universal={:?}",
self.region_value_str(sup_region),
self.universal_regions.is_universal_region(sup_region),
);
debug!(
- "eval_outlives: sub_region's value = {:?} universal={:?}",
+ "sub_region's value = {:?} universal={:?}",
self.region_value_str(sub_region),
self.universal_regions.is_universal_region(sub_region),
);
@@ -1353,7 +1355,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// 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 \
+ "sub universe `{sub_region_scc:?}` is not nameable \
by super `{sup_region_scc:?}`, promoting to static",
);
@@ -1374,9 +1376,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
});
if !universal_outlives {
- debug!(
- "eval_outlives: returning false because sub region contains a universal region not present in super"
- );
+ debug!("sub region contains a universal region not present in super");
return false;
}
@@ -1385,15 +1385,13 @@ 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"
- );
+ debug!("super is universal and hence contains all points");
return true;
}
- 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
+ debug!("comparison between points in sup/sub");
+
+ self.scc_values.contains_points(sup_region_scc, sub_region_scc)
}
/// Once regions have been propagated, this method is used to see
@@ -1415,7 +1413,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// report them as errors.
fn check_universal_regions(
&self,
- body: &Body<'tcx>,
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
errors_buffer: &mut RegionErrors<'tcx>,
) {
@@ -1426,7 +1423,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// they did not grow too large, accumulating any requirements
// for our caller into the `outlives_requirements` vector.
self.check_universal_region(
- body,
fr,
&mut propagated_outlives_requirements,
errors_buffer,
@@ -1467,7 +1463,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// report them as errors.
fn check_polonius_subset_errors(
&self,
- body: &Body<'tcx>,
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
errors_buffer: &mut RegionErrors<'tcx>,
polonius_output: Rc<PoloniusOutput>,
@@ -1514,7 +1509,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let propagated = self.try_propagate_universal_region_error(
*longer_fr,
*shorter_fr,
- body,
&mut propagated_outlives_requirements,
);
if propagated == RegionRelationCheckResult::Error {
@@ -1554,13 +1548,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
///
/// Things that are to be propagated are accumulated into the
/// `outlives_requirements` vector.
- #[instrument(
- skip(self, body, propagated_outlives_requirements, errors_buffer),
- level = "debug"
- )]
+ #[instrument(skip(self, propagated_outlives_requirements, errors_buffer), level = "debug")]
fn check_universal_region(
&self,
- body: &Body<'tcx>,
longer_fr: RegionVid,
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
errors_buffer: &mut RegionErrors<'tcx>,
@@ -1583,7 +1573,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
if let RegionRelationCheckResult::Error = self.check_universal_region_relation(
longer_fr,
representative,
- body,
propagated_outlives_requirements,
) {
errors_buffer.push(RegionErrorKind::RegionError {
@@ -1603,7 +1592,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
if let RegionRelationCheckResult::Error = self.check_universal_region_relation(
longer_fr,
shorter_fr,
- body,
propagated_outlives_requirements,
) {
// We only report the first region error. Subsequent errors are hidden so as
@@ -1628,7 +1616,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&self,
longer_fr: RegionVid,
shorter_fr: RegionVid,
- body: &Body<'tcx>,
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
) -> RegionRelationCheckResult {
// If it is known that `fr: o`, carry on.
@@ -1644,7 +1631,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
self.try_propagate_universal_region_error(
longer_fr,
shorter_fr,
- body,
propagated_outlives_requirements,
)
}
@@ -1656,7 +1642,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&self,
longer_fr: RegionVid,
shorter_fr: RegionVid,
- body: &Body<'tcx>,
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
) -> RegionRelationCheckResult {
if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
@@ -1668,7 +1653,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!("try_propagate_universal_region_error: fr_minus={:?}", fr_minus);
let blame_span_category = self.find_outlives_blame_span(
- body,
longer_fr,
NllRegionVariableOrigin::FreeRegion,
shorter_fr,
@@ -1822,50 +1806,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn retrieve_closure_constraint_info(
&self,
- _body: &Body<'tcx>,
- constraint: &OutlivesConstraint<'tcx>,
- ) -> BlameConstraint<'tcx> {
- let loc = match constraint.locations {
- Locations::All(span) => {
- return BlameConstraint {
- category: constraint.category,
- from_closure: false,
- cause: ObligationCause::dummy_with_span(span),
- variance_info: constraint.variance_info,
- };
+ constraint: OutlivesConstraint<'tcx>,
+ ) -> Option<(ConstraintCategory<'tcx>, Span)> {
+ match constraint.locations {
+ Locations::All(_) => None,
+ Locations::Single(loc) => {
+ self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)).copied()
}
- Locations::Single(loc) => loc,
- };
-
- let opt_span_category =
- self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub));
- opt_span_category
- .map(|&(category, span)| BlameConstraint {
- category,
- from_closure: true,
- cause: ObligationCause::dummy_with_span(span),
- variance_info: constraint.variance_info,
- })
- .unwrap_or(BlameConstraint {
- category: constraint.category,
- from_closure: false,
- cause: ObligationCause::dummy_with_span(constraint.span),
- variance_info: constraint.variance_info,
- })
+ }
}
/// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`.
pub(crate) fn find_outlives_blame_span(
&self,
- body: &Body<'tcx>,
fr1: RegionVid,
fr1_origin: NllRegionVariableOrigin,
fr2: RegionVid,
) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>) {
- let BlameConstraint { category, cause, .. } =
- self.best_blame_constraint(body, fr1, fr1_origin, |r| {
- self.provides_universal_region(r, fr1, fr2)
- });
+ let BlameConstraint { category, cause, .. } = self
+ .best_blame_constraint(fr1, fr1_origin, |r| self.provides_universal_region(r, fr1, fr2))
+ .0;
(category, cause)
}
@@ -1970,7 +1930,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
/// Finds some region R such that `fr1: R` and `R` is live at `elem`.
- #[instrument(skip(self), level = "trace")]
+ #[instrument(skip(self), level = "trace", ret)]
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)]);
@@ -2048,23 +2008,18 @@ 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.
+ #[instrument(level = "debug", skip(self, target_test))]
pub(crate) fn best_blame_constraint(
&self,
- body: &Body<'tcx>,
from_region: RegionVid,
from_region_origin: NllRegionVariableOrigin,
target_test: impl Fn(RegionVid) -> bool,
- ) -> BlameConstraint<'tcx> {
- debug!(
- "best_blame_constraint(from_region={:?}, from_region_origin={:?})",
- from_region, from_region_origin
- );
-
+ ) -> (BlameConstraint<'tcx>, Vec<ExtraConstraintInfo>) {
// Find all paths
let (path, target_region) =
self.find_constraint_paths_between_regions(from_region, target_test).unwrap();
debug!(
- "best_blame_constraint: path={:#?}",
+ "path={:#?}",
path.iter()
.map(|c| format!(
"{:?} ({:?}: {:?})",
@@ -2075,6 +2030,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.collect::<Vec<_>>()
);
+ let mut extra_info = vec![];
+ for constraint in path.iter() {
+ let outlived = constraint.sub;
+ let Some(origin) = self.var_infos.get(outlived) else { continue; };
+ let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(p)) = origin.origin else { continue; };
+ debug!(?constraint, ?p);
+ let ConstraintCategory::Predicate(span) = constraint.category else { continue; };
+ extra_info.push(ExtraConstraintInfo::PlaceholderFromPredicate(span));
+ // We only want to point to one
+ break;
+ }
+
// We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint.
// Instead, we use it to produce an improved `ObligationCauseCode`.
// FIXME - determine what we should do if we encounter multiple `ConstraintCategory::Predicate`
@@ -2100,23 +2067,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let mut categorized_path: Vec<BlameConstraint<'tcx>> = path
.iter()
.map(|constraint| {
- if constraint.category == ConstraintCategory::ClosureBounds {
- self.retrieve_closure_constraint_info(body, &constraint)
- } else {
- BlameConstraint {
- category: constraint.category,
- from_closure: false,
- cause: ObligationCause::new(
- constraint.span,
- CRATE_HIR_ID,
- cause_code.clone(),
- ),
- variance_info: constraint.variance_info,
- }
+ let (category, span, from_closure, cause_code) =
+ if constraint.category == ConstraintCategory::ClosureBounds {
+ if let Some((category, span)) =
+ self.retrieve_closure_constraint_info(*constraint)
+ {
+ (category, span, true, ObligationCauseCode::MiscObligation)
+ } else {
+ (
+ constraint.category,
+ constraint.span,
+ false,
+ ObligationCauseCode::MiscObligation,
+ )
+ }
+ } else {
+ (constraint.category, constraint.span, false, cause_code.clone())
+ };
+ BlameConstraint {
+ category,
+ from_closure,
+ cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code),
+ variance_info: constraint.variance_info,
+ outlives_constraint: *constraint,
}
})
.collect();
- debug!("best_blame_constraint: categorized_path={:#?}", categorized_path);
+ debug!("categorized_path={:#?}", categorized_path);
// To find the best span to cite, we first try to look for the
// final constraint that is interesting and where the `sup` is
@@ -2214,10 +2191,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let best_choice =
if blame_source { range.rev().find(find_region) } else { range.find(find_region) };
- debug!(
- "best_blame_constraint: best_choice={:?} blame_source={}",
- best_choice, blame_source
- );
+ debug!(?best_choice, ?blame_source, ?extra_info);
if let Some(i) = best_choice {
if let Some(next) = categorized_path.get(i + 1) {
@@ -2226,7 +2200,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
{
// The return expression is being influenced by the return type being
// impl Trait, point at the return type and not the return expr.
- return next.clone();
+ return (next.clone(), extra_info);
}
}
@@ -2246,7 +2220,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}
- return categorized_path[i].clone();
+ return (categorized_path[i].clone(), extra_info);
}
// If that search fails, that is.. unusual. Maybe everything
@@ -2254,9 +2228,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// appears to be the most interesting point to report to the
// user via an even more ad-hoc guess.
categorized_path.sort_by(|p0, p1| p0.category.cmp(&p1.category));
- debug!("best_blame_constraint: sorted_path={:#?}", categorized_path);
+ debug!("sorted_path={:#?}", categorized_path);
- categorized_path.remove(0)
+ (categorized_path.remove(0), extra_info)
}
pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
@@ -2338,7 +2312,13 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
outlives_requirement={:?}",
region, outlived_region, outlives_requirement,
);
- ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region))
+ (
+ ty::Binder::dummy(ty::OutlivesPredicate(
+ region.into(),
+ outlived_region,
+ )),
+ ConstraintCategory::BoringNoLocation,
+ )
}
ClosureOutlivesSubject::Ty(ty) => {
@@ -2348,7 +2328,10 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
outlives_requirement={:?}",
ty, outlived_region, outlives_requirement,
);
- ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region))
+ (
+ ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)),
+ ConstraintCategory::BoringNoLocation,
+ )
}
}
})
@@ -2362,4 +2345,5 @@ pub struct BlameConstraint<'tcx> {
pub from_closure: bool,
pub cause: ObligationCause<'tcx>,
pub variance_info: ty::VarianceDiagInfo<'tcx>,
+ pub outlives_constraint: OutlivesConstraint<'tcx>,
}
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index d6712b6a4..9d088642f 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -16,6 +16,8 @@ use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::TraitEngineExt as _;
+use crate::session_diagnostics::ConstNotUsedTraitAlias;
+
use super::RegionInferenceContext;
impl<'tcx> RegionInferenceContext<'tcx> {
@@ -58,7 +60,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Calling `universal_upper_bound` for such a region gives `fr_fn_body`,
/// which has no `external_name` in which case we use `'empty` as the
/// region to pass to `infer_opaque_definition_from_instantiation`.
- #[instrument(level = "debug", skip(self, infcx))]
+ #[instrument(level = "debug", skip(self, infcx), ret)]
pub(crate) fn infer_opaque_types(
&self,
infcx: &InferCtxt<'_, 'tcx>,
@@ -107,7 +109,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
- .unwrap_or(infcx.tcx.lifetimes.re_root_empty),
+ .unwrap_or(infcx.tcx.lifetimes.re_erased),
_ => region,
});
@@ -431,7 +433,7 @@ struct ReverseMapper<'tcx> {
key: ty::OpaqueTypeKey<'tcx>,
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
- map_missing_regions_to_empty: bool,
+ do_not_error: bool,
/// initially `Some`, set to `None` once error has been reported
hidden_ty: Option<Ty<'tcx>>,
@@ -448,29 +450,19 @@ impl<'tcx> ReverseMapper<'tcx> {
hidden_ty: Ty<'tcx>,
span: Span,
) -> Self {
- Self {
- tcx,
- key,
- map,
- map_missing_regions_to_empty: false,
- hidden_ty: Some(hidden_ty),
- span,
- }
+ Self { tcx, key, map, do_not_error: false, hidden_ty: Some(hidden_ty), span }
}
- fn fold_kind_mapping_missing_regions_to_empty(
- &mut self,
- kind: GenericArg<'tcx>,
- ) -> GenericArg<'tcx> {
- assert!(!self.map_missing_regions_to_empty);
- self.map_missing_regions_to_empty = true;
+ fn fold_kind_no_missing_regions_error(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
+ assert!(!self.do_not_error);
+ self.do_not_error = true;
let kind = kind.fold_with(self);
- self.map_missing_regions_to_empty = false;
+ self.do_not_error = false;
kind
}
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
- assert!(!self.map_missing_regions_to_empty);
+ assert!(!self.do_not_error);
kind.fold_with(self)
}
}
@@ -494,9 +486,9 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
ty::ReErased => return r,
// The regions that we expect from borrow checking.
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
+ ty::ReEarlyBound(_) | ty::ReFree(_) => {}
- ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) => {
+ ty::RePlaceholder(_) | ty::ReVar(_) => {
// All of the regions in the type should either have been
// erased by writeback, or mapped back to named regions by
// borrow checking.
@@ -508,7 +500,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
match self.map.get(&r.into()).map(|k| k.unpack()) {
Some(GenericArgKind::Lifetime(r1)) => r1,
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
- None if self.map_missing_regions_to_empty => self.tcx.lifetimes.re_root_empty,
+ None if self.do_not_error => self.tcx.lifetimes.re_static,
None if generics.parent.is_some() => {
if let Some(hidden_ty) = self.hidden_ty.take() {
unexpected_hidden_region_diagnostic(
@@ -520,7 +512,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
)
.emit();
}
- self.tcx.lifetimes.re_root_empty
+ self.tcx.lifetimes.re_static
}
None => {
self.tcx
@@ -572,7 +564,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
- self.fold_kind_mapping_missing_regions_to_empty(kind)
+ self.fold_kind_no_missing_regions_error(kind)
} else {
// ...but not elsewhere.
self.fold_kind_normally(kind)
@@ -587,7 +579,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
- self.fold_kind_mapping_missing_regions_to_empty(kind)
+ self.fold_kind_no_missing_regions_error(kind)
} else {
// ...but not elsewhere.
self.fold_kind_normally(kind)
@@ -639,17 +631,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
Some(GenericArgKind::Const(c1)) => c1,
Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
None => {
- self.tcx
- .sess
- .struct_span_err(
- self.span,
- &format!(
- "const parameter `{}` is part of concrete type but not \
- used in parameter list for the `impl Trait` type alias",
- ct
- ),
- )
- .emit();
+ self.tcx.sess.emit_err(ConstNotUsedTraitAlias {
+ ct: ct.to_string(),
+ span: self.span,
+ });
self.tcx().const_error(ct.ty())
}
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index c81ef10f7..de20a4bb4 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -25,7 +25,7 @@ impl RegionValueElements {
pub(crate) fn new(body: &Body<'_>) -> Self {
let mut num_points = 0;
let statements_before_block: IndexVec<BasicBlock, usize> = body
- .basic_blocks()
+ .basic_blocks
.iter()
.map(|block_data| {
let v = num_points;
@@ -37,7 +37,7 @@ impl RegionValueElements {
debug!("RegionValueElements: num_points={:#?}", num_points);
let mut basic_blocks = IndexVec::with_capacity(num_points);
- for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
+ for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
}
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 7a8ce621c..63b2088f7 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -2,6 +2,7 @@ use rustc_index::vec::IndexVec;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_middle::mir::visit::{MutVisitor, TyContext};
use rustc_middle::mir::{Body, Location, Promoted};
+use rustc_middle::mir::{Constant, ConstantKind};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
@@ -37,6 +38,21 @@ where
})
}
+// FIXME(valtrees): This function is necessary because `fold_regions`
+// panics for mir constants in the visitor.
+//
+// Once `visit_mir_constant` is removed we can also remove this function
+// and just use `renumber_regions`.
+fn renumber_regions_in_mir_constant<'tcx>(
+ infcx: &InferCtxt<'_, 'tcx>,
+ value: ConstantKind<'tcx>,
+) -> ConstantKind<'tcx> {
+ infcx.tcx.super_fold_regions(value, |_region, _depth| {
+ let origin = NllRegionVariableOrigin::Existential { from_forall: false };
+ infcx.next_nll_region_var(origin)
+ })
+}
+
struct NllVisitor<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
}
@@ -48,6 +64,13 @@ impl<'a, 'tcx> NllVisitor<'a, 'tcx> {
{
renumber_regions(self.infcx, value)
}
+
+ fn renumber_regions_in_mir_constant(
+ &mut self,
+ value: ConstantKind<'tcx>,
+ ) -> ConstantKind<'tcx> {
+ renumber_regions_in_mir_constant(self.infcx, value)
+ }
}
impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
@@ -77,7 +100,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
debug!(?region);
}
- fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) {
- *constant = self.renumber_regions(*constant);
+ #[instrument(skip(self), level = "debug")]
+ fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) {
+ let literal = constant.literal;
+ constant.literal = self.renumber_regions_in_mir_constant(literal);
+ debug!("constant: {:#?}", constant);
}
}
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 895723d44..5d750c6ca 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -1,9 +1,12 @@
-use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_errors::{IntoDiagnosticArg, MultiSpan};
+use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
use rustc_middle::ty::Ty;
use rustc_span::Span;
+use crate::diagnostics::RegionName;
+
#[derive(SessionDiagnostic)]
-#[error(borrowck::move_unsized, code = "E0161")]
+#[diag(borrowck::move_unsized, code = "E0161")]
pub(crate) struct MoveUnsized<'tcx> {
pub ty: Ty<'tcx>,
#[primary_span]
@@ -12,7 +15,7 @@ pub(crate) struct MoveUnsized<'tcx> {
}
#[derive(SessionDiagnostic)]
-#[error(borrowck::higher_ranked_lifetime_error)]
+#[diag(borrowck::higher_ranked_lifetime_error)]
pub(crate) struct HigherRankedLifetimeError {
#[subdiagnostic]
pub cause: Option<HigherRankedErrorCause>,
@@ -29,16 +32,128 @@ pub(crate) enum HigherRankedErrorCause {
}
#[derive(SessionDiagnostic)]
-#[error(borrowck::higher_ranked_subtype_error)]
+#[diag(borrowck::higher_ranked_subtype_error)]
pub(crate) struct HigherRankedSubtypeError {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(borrowck::generic_does_not_live_long_enough)]
+#[diag(borrowck::generic_does_not_live_long_enough)]
pub(crate) struct GenericDoesNotLiveLongEnough {
pub kind: String,
#[primary_span]
pub span: Span,
}
+
+#[derive(LintDiagnostic)]
+#[diag(borrowck::var_does_not_need_mut)]
+pub(crate) struct VarNeedNotMut {
+ #[suggestion_short(applicability = "machine-applicable", code = "")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(borrowck::const_not_used_in_type_alias)]
+pub(crate) struct ConstNotUsedTraitAlias {
+ pub ct: String,
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(borrowck::var_cannot_escape_closure)]
+#[note]
+#[note(borrowck::cannot_escape)]
+pub(crate) struct FnMutError {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub ty_err: FnMutReturnTypeErr,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum VarHereDenote {
+ #[label(borrowck::var_here_captured)]
+ Captured {
+ #[primary_span]
+ span: Span,
+ },
+ #[label(borrowck::var_here_defined)]
+ Defined {
+ #[primary_span]
+ span: Span,
+ },
+ #[label(borrowck::closure_inferred_mut)]
+ FnMutInferred {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum FnMutReturnTypeErr {
+ #[label(borrowck::returned_closure_escaped)]
+ ReturnClosure {
+ #[primary_span]
+ span: Span,
+ },
+ #[label(borrowck::returned_async_block_escaped)]
+ ReturnAsyncBlock {
+ #[primary_span]
+ span: Span,
+ },
+ #[label(borrowck::returned_ref_escaped)]
+ ReturnRef {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(borrowck::lifetime_constraints_error)]
+pub(crate) struct LifetimeOutliveErr {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum LifetimeReturnCategoryErr<'a> {
+ #[label(borrowck::returned_lifetime_wrong)]
+ WrongReturn {
+ #[primary_span]
+ span: Span,
+ mir_def_name: &'a str,
+ outlived_fr_name: RegionName,
+ fr_name: &'a RegionName,
+ },
+ #[label(borrowck::returned_lifetime_short)]
+ ShortReturn {
+ #[primary_span]
+ span: Span,
+ category_desc: &'static str,
+ free_region_name: &'a RegionName,
+ outlived_fr_name: RegionName,
+ },
+}
+
+impl IntoDiagnosticArg for &RegionName {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ format!("{}", self).into_diagnostic_arg()
+ }
+}
+
+impl IntoDiagnosticArg for RegionName {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ format!("{}", self).into_diagnostic_arg()
+ }
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum RequireStaticErr {
+ #[note(borrowck::used_impl_require_static)]
+ UsedImpl {
+ #[primary_span]
+ multi_span: MultiSpan,
+ },
+}
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index 6cfe5efb6..9271a2f4d 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -24,8 +24,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
/// **Any `rustc_infer::infer` operations that might generate region
/// constraints should occur within this method so that those
/// constraints can be properly localized!**
- #[instrument(skip(self, category, op), level = "trace")]
- pub(super) fn fully_perform_op<R, Op>(
+ #[instrument(skip(self, op), level = "trace")]
+ pub(super) fn fully_perform_op<R: fmt::Debug, Op>(
&mut self,
locations: Locations,
category: ConstraintCategory<'tcx>,
@@ -39,6 +39,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?;
+ debug!(?output, ?constraints);
+
if let Some(data) = constraints {
self.push_region_constraints(locations, category, data);
}
@@ -90,17 +92,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
locations: Locations,
category: ConstraintCategory<'tcx>,
) {
- self.prove_predicates(
- Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
+ self.prove_predicate(
+ ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
- }))),
+ }))
+ .to_predicate(self.tcx()),
locations,
category,
);
}
+ #[instrument(level = "debug", skip(self))]
pub(super) fn normalize_and_prove_instantiated_predicates(
&mut self,
// Keep this parameter for now, in case we start using
@@ -115,8 +119,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.zip(instantiated_predicates.spans.into_iter())
{
debug!(?predicate);
- let predicate = self.normalize(predicate, locations);
- self.prove_predicate(predicate, locations, ConstraintCategory::Predicate(span));
+ let category = ConstraintCategory::Predicate(span);
+ let predicate = self.normalize_with_category(predicate, locations, category);
+ self.prove_predicate(predicate, locations, category);
}
}
@@ -152,15 +157,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
})
}
- #[instrument(skip(self), level = "debug")]
pub(super) fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{
+ self.normalize_with_category(value, location, ConstraintCategory::Boring)
+ }
+
+ #[instrument(skip(self), level = "debug")]
+ pub(super) fn normalize_with_category<T>(
+ &mut self,
+ value: T,
+ location: impl NormalizeLocation,
+ category: ConstraintCategory<'tcx>,
+ ) -> T
+ where
+ T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
+ {
let param_env = self.param_env;
self.fully_perform_op(
location.to_locations(),
- ConstraintCategory::Boring,
+ category,
param_env.and(type_op::normalize::Normalize::new(value)),
)
.unwrap_or_else(|NoSolution| {
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 167960918..71eae0583 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -6,7 +6,7 @@ use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{Span, DUMMY_SP};
@@ -86,7 +86,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
}
- pub(super) fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) {
+ fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) {
debug!("generate: constraints at: {:#?}", self.locations);
// Extract out various useful fields we'll need below.
@@ -98,34 +98,25 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
// region constraints like `for<'a> 'a: 'b`. At some point
// when we move to universes, we will, and this assertion
// will start to fail.
- let ty::OutlivesPredicate(k1, r2) = query_constraint.no_bound_vars().unwrap_or_else(|| {
- bug!("query_constraint {:?} contained bound vars", query_constraint,);
- });
+ let ty::OutlivesPredicate(k1, r2) =
+ query_constraint.0.no_bound_vars().unwrap_or_else(|| {
+ bug!("query_constraint {:?} contained bound vars", query_constraint,);
+ });
+
+ let constraint_category = query_constraint.1;
match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
let r1_vid = self.to_region_vid(r1);
let r2_vid = self.to_region_vid(r2);
- self.add_outlives(r1_vid, r2_vid);
+ self.add_outlives(r1_vid, r2_vid, constraint_category);
}
- GenericArgKind::Type(mut t1) => {
+ GenericArgKind::Type(t1) => {
// we don't actually use this for anything, but
// the `TypeOutlives` code needs an origin.
let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
- // Placeholder regions need to be converted now because it may
- // create new region variables, which can't be done later when
- // verifying these bounds.
- if t1.has_placeholders() {
- t1 = tcx.fold_regions(t1, |r, _| match *r {
- ty::RePlaceholder(placeholder) => {
- self.constraints.placeholder_region(self.infcx, placeholder)
- }
- _ => r,
- });
- }
-
TypeOutlives::new(
&mut *self,
tcx,
@@ -133,7 +124,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
Some(implicit_region_bound),
param_env,
)
- .type_must_outlive(origin, t1, r2);
+ .type_must_outlive(origin, t1, r2, constraint_category);
}
GenericArgKind::Const(_) => {
@@ -143,6 +134,25 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
}
+ /// Placeholder regions need to be converted eagerly because it may
+ /// create new region variables, which we must not do when verifying
+ /// our region bounds.
+ ///
+ /// FIXME: This should get removed once higher ranked region obligations
+ /// are dealt with during trait solving.
+ fn replace_placeholders_with_nll<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
+ if value.has_placeholders() {
+ self.tcx.fold_regions(value, |r, _| match *r {
+ ty::RePlaceholder(placeholder) => {
+ self.constraints.placeholder_region(self.infcx, placeholder)
+ }
+ _ => r,
+ })
+ } else {
+ value
+ }
+ }
+
fn verify_to_type_test(
&mut self,
generic_kind: GenericKind<'tcx>,
@@ -150,7 +160,6 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
verify_bound: VerifyBound<'tcx>,
) -> TypeTest<'tcx> {
let lower_bound = self.to_region_vid(region);
-
TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound }
}
@@ -162,10 +171,19 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
}
- fn add_outlives(&mut self, sup: ty::RegionVid, sub: ty::RegionVid) {
+ fn add_outlives(
+ &mut self,
+ sup: ty::RegionVid,
+ sub: ty::RegionVid,
+ category: ConstraintCategory<'tcx>,
+ ) {
+ let category = match self.category {
+ ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category,
+ _ => self.category,
+ };
self.constraints.outlives_constraints.push(OutlivesConstraint {
locations: self.locations,
- category: self.category,
+ category,
span: self.span,
sub,
sup,
@@ -185,10 +203,11 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
_origin: SubregionOrigin<'tcx>,
a: ty::Region<'tcx>,
b: ty::Region<'tcx>,
+ constraint_category: ConstraintCategory<'tcx>,
) {
let b = self.to_region_vid(b);
let a = self.to_region_vid(a);
- self.add_outlives(b, a);
+ self.add_outlives(b, a, constraint_category);
}
fn push_verify(
@@ -198,6 +217,8 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
a: ty::Region<'tcx>,
bound: VerifyBound<'tcx>,
) {
+ let kind = self.replace_placeholders_with_nll(kind);
+ let bound = self.replace_placeholders_with_nll(bound);
let type_test = self.verify_to_type_test(kind, a, bound);
self.add_type_test(type_test);
}
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 cc0318ede..f1b1c33a1 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -1,5 +1,5 @@
use rustc_data_structures::frozen::Frozen;
-use rustc_data_structures::transitive_relation::TransitiveRelation;
+use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder};
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
@@ -61,25 +61,13 @@ pub(crate) fn create<'tcx>(
constraints,
universal_regions: universal_regions.clone(),
region_bound_pairs: Default::default(),
- relations: UniversalRegionRelations {
- universal_regions: universal_regions.clone(),
- outlives: Default::default(),
- inverse_outlives: Default::default(),
- },
+ outlives: Default::default(),
+ inverse_outlives: Default::default(),
}
.create()
}
impl UniversalRegionRelations<'_> {
- /// Records in the `outlives_relation` (and
- /// `inverse_outlives_relation`) that `fr_a: fr_b`. Invoked by the
- /// builder below.
- fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
- debug!("relate_universal_regions: fr_a={:?} outlives fr_b={:?}", fr_a, fr_b);
- self.outlives.add(fr_a, fr_b);
- self.inverse_outlives.add(fr_b, fr_a);
- }
-
/// Given two universal regions, returns the postdominating
/// upper-bound (effectively the least upper bound).
///
@@ -216,11 +204,20 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> {
constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
// outputs:
- relations: UniversalRegionRelations<'tcx>,
+ outlives: TransitiveRelationBuilder<RegionVid>,
+ inverse_outlives: TransitiveRelationBuilder<RegionVid>,
region_bound_pairs: RegionBoundPairs<'tcx>,
}
impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
+ /// Records in the `outlives_relation` (and
+ /// `inverse_outlives_relation`) that `fr_a: fr_b`.
+ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
+ debug!("relate_universal_regions: fr_a={:?} outlives fr_b={:?}", fr_a, fr_b);
+ self.outlives.add(fr_a, fr_b);
+ self.inverse_outlives.add(fr_b, fr_a);
+ }
+
pub(crate) fn create(mut self) -> CreateResult<'tcx> {
let unnormalized_input_output_tys = self
.universal_regions
@@ -242,10 +239,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
let constraint_sets: Vec<_> = unnormalized_input_output_tys
.flat_map(|ty| {
debug!("build: input_or_output={:?}", ty);
- // We only add implied bounds for the normalized type as the unnormalized
- // type may not actually get checked by the caller.
- //
- // Can otherwise be unsound, see #91068.
+ // We add implied bounds from both the unnormalized and normalized ty.
+ // See issue #87748
+ let constraints_implied1 = self.add_implied_bounds(ty);
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
@@ -269,13 +265,14 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// }
// impl Foo for () {
// type Bar = ();
- // fn foo(&self) ->&() {}
+ // fn foo(&self) -> &() {}
// }
// ```
// Both &Self::Bar and &() are WF
- let constraints_implied = self.add_implied_bounds(norm_ty);
+ let constraints_implied2 =
+ if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
normalized_inputs_and_output.push(norm_ty);
- constraints1.into_iter().chain(constraints_implied)
+ constraints1.into_iter().chain(constraints_implied1).chain(constraints_implied2)
})
.collect();
@@ -292,9 +289,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
let fr_fn_body = self.universal_regions.fr_fn_body;
for fr in self.universal_regions.universal_regions() {
debug!("build: relating free region {:?} to itself and to 'static", fr);
- self.relations.relate_universal_regions(fr, fr);
- self.relations.relate_universal_regions(fr_static, fr);
- self.relations.relate_universal_regions(fr, fr_fn_body);
+ self.relate_universal_regions(fr, fr);
+ self.relate_universal_regions(fr_static, fr);
+ self.relate_universal_regions(fr, fr_fn_body);
}
for data in &constraint_sets {
@@ -313,7 +310,11 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
}
CreateResult {
- universal_region_relations: Frozen::freeze(self.relations),
+ universal_region_relations: Frozen::freeze(UniversalRegionRelations {
+ universal_regions: self.universal_regions,
+ outlives: self.outlives.freeze(),
+ inverse_outlives: self.inverse_outlives.freeze(),
+ }),
region_bound_pairs: self.region_bound_pairs,
normalized_inputs_and_output,
}
@@ -346,17 +347,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
match outlives_bound {
OutlivesBound::RegionSubRegion(r1, r2) => {
- // `where Type:` is lowered to `where Type: 'empty` so that
- // we check `Type` is well formed, but there's no use for
- // this bound here.
- if r1.is_empty() {
- return;
- }
-
// The bound says that `r1 <= r2`; we store `r2: r1`.
let r1 = self.universal_regions.to_region_vid(r1);
let r2 = self.universal_regions.to_region_vid(r2);
- self.relations.relate_universal_regions(r2, r1);
+ self.relate_universal_regions(r2, r1);
}
OutlivesBound::RegionSubParam(r_a, param_b) => {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index d32b1edcd..3713ec3f5 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -30,8 +30,9 @@ use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{
- self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueHiddenType,
- OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
+ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
+ OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType,
+ UserTypeAnnotationIndex,
};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{Span, DUMMY_SP};
@@ -178,97 +179,15 @@ pub(crate) fn type_check<'mir, 'tcx>(
upvars,
};
- let opaque_type_values = type_check_internal(
+ let mut checker = TypeChecker::new(
infcx,
- param_env,
body,
- promoted,
+ param_env,
&region_bound_pairs,
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,
- body,
- elements,
- flow_inits,
- move_data,
- location_table,
- use_polonius,
- );
-
- translate_outlives_facts(&mut cx);
- let opaque_type_values =
- infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
-
- opaque_type_values
- .into_iter()
- .map(|(opaque_type_key, decl)| {
- cx.fully_perform_op(
- Locations::All(body.span),
- ConstraintCategory::OpaqueType,
- CustomTypeOp::new(
- |infcx| {
- infcx.register_member_constraints(
- param_env,
- opaque_type_key,
- decl.hidden_type.ty,
- decl.hidden_type.span,
- );
- Ok(InferOk { value: (), obligations: vec![] })
- },
- || "opaque_type_map".to_string(),
- ),
- )
- .unwrap();
- let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
- trace!(
- "finalized opaque type {:?} to {:#?}",
- opaque_type_key,
- hidden_type.ty.kind()
- );
- if hidden_type.has_infer_types_or_consts() {
- infcx.tcx.sess.delay_span_bug(
- decl.hidden_type.span,
- &format!("could not resolve {:#?}", hidden_type.ty.kind()),
- );
- hidden_type.ty = infcx.tcx.ty_error();
- }
-
- (opaque_type_key, (hidden_type, decl.origin))
- })
- .collect()
- },
);
- MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
-}
-
-#[instrument(
- skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra),
- level = "debug"
-)]
-fn type_check_internal<'a, 'tcx, R>(
- infcx: &'a InferCtxt<'a, 'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- body: &'a Body<'tcx>,
- promoted: &'a IndexVec<Promoted, Body<'tcx>>,
- region_bound_pairs: &'a RegionBoundPairs<'tcx>,
- implicit_region_bound: ty::Region<'tcx>,
- 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,
- param_env,
- region_bound_pairs,
- implicit_region_bound,
- borrowck_context,
- );
let errors_reported = {
let mut verifier = TypeVerifier::new(&mut checker, promoted);
verifier.visit_body(&body);
@@ -280,7 +199,56 @@ fn type_check_internal<'a, 'tcx, R>(
checker.typeck_mir(body);
}
- extra(checker)
+ checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
+ liveness::generate(
+ &mut checker,
+ body,
+ elements,
+ flow_inits,
+ move_data,
+ location_table,
+ use_polonius,
+ );
+
+ translate_outlives_facts(&mut checker);
+ let opaque_type_values = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
+
+ let opaque_type_values = opaque_type_values
+ .into_iter()
+ .map(|(opaque_type_key, decl)| {
+ checker
+ .fully_perform_op(
+ Locations::All(body.span),
+ ConstraintCategory::OpaqueType,
+ CustomTypeOp::new(
+ |infcx| {
+ infcx.register_member_constraints(
+ param_env,
+ opaque_type_key,
+ decl.hidden_type.ty,
+ decl.hidden_type.span,
+ );
+ Ok(InferOk { value: (), obligations: vec![] })
+ },
+ || "opaque_type_map".to_string(),
+ ),
+ )
+ .unwrap();
+ let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
+ trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
+ if hidden_type.has_infer_types_or_consts() {
+ infcx.tcx.sess.delay_span_bug(
+ decl.hidden_type.span,
+ &format!("could not resolve {:#?}", hidden_type.ty.kind()),
+ );
+ hidden_type.ty = infcx.tcx.ty_error();
+ }
+
+ (opaque_type_key, (hidden_type, decl.origin))
+ })
+ .collect();
+
+ MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
}
fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
@@ -344,6 +312,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
}
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
+ debug!(?constant, ?location, "visit_constant");
+
self.super_constant(constant, location);
let ty = self.sanitize_type(constant, constant.literal.ty());
@@ -387,11 +357,15 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
let tcx = self.tcx();
let maybe_uneval = match constant.literal {
ConstantKind::Ty(ct) => match ct.kind() {
- ty::ConstKind::Unevaluated(uv) => Some(uv),
+ ty::ConstKind::Unevaluated(_) => {
+ bug!("should not encounter unevaluated ConstantKind::Ty here, got {:?}", ct)
+ }
_ => None,
},
+ ConstantKind::Unevaluated(uv, _) => Some(uv),
_ => None,
};
+
if let Some(uv) = maybe_uneval {
if let Some(promoted) = uv.promoted {
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
@@ -1076,6 +1050,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
+ debug!(?annotation);
match annotation {
UserType::Ty(mut ty) => {
ty = self.normalize(ty, Locations::All(span));
@@ -1334,12 +1309,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);
}
}
- StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
- ..
- }) => span_bug!(
- stmt.source_info.span,
- "Unexpected StatementKind::CopyNonOverlapping, should only appear after lowering_intrinsics",
- ),
+ StatementKind::Intrinsic(box ref kind) => match kind {
+ NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location),
+ NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
+ stmt.source_info.span,
+ "Unexpected NonDivergingIntrinsic::CopyNonOverlapping, should only appear after lowering_intrinsics",
+ ),
+ },
StatementKind::FakeRead(..)
| StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
@@ -1448,9 +1424,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
))
});
debug!(?sig);
- let sig = self.normalize(sig, term_location);
- self.check_call_dest(body, term, &sig, *destination, target, term_location);
-
+ // IMPORTANT: We have to prove well formed for the function signature before
+ // we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc`
+ // get normalized away, causing us to ignore the `'b: 'a` bound used by the function.
+ //
+ // Normalization results in a well formed type if the input is well formed, so we
+ // don't have to check it twice.
+ //
+ // See #91068 for an example.
self.prove_predicates(
sig.inputs_and_output
.iter()
@@ -1458,6 +1439,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
term_location.to_locations(),
ConstraintCategory::Boring,
);
+ let sig = self.normalize(sig, term_location);
+ self.check_call_dest(body, term, &sig, *destination, target, term_location);
// The ordinary liveness rules will ensure that all
// regions in the type of the callee are live here. We
@@ -1834,14 +1817,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
+ debug!(?op, ?location, "check_operand");
+
if let Operand::Constant(constant) = op {
let maybe_uneval = match constant.literal {
- ConstantKind::Ty(ct) => match ct.kind() {
- ty::ConstKind::Unevaluated(uv) => Some(uv),
- _ => None,
- },
- _ => None,
+ ConstantKind::Val(..) | ConstantKind::Ty(_) => None,
+ ConstantKind::Unevaluated(uv, _) => Some(uv),
};
+
if let Some(uv) = maybe_uneval {
if uv.promoted.is_none() {
let tcx = self.tcx();
@@ -1904,7 +1887,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
- &Rvalue::NullaryOp(_, ty) => {
+ &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
@@ -2033,6 +2016,36 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);
}
+ CastKind::DynStar => {
+ // get the constraints from the target type (`dyn* Clone`)
+ //
+ // apply them to prove that the source type `Foo` implements `Clone` etc
+ let (existential_predicates, region) = match ty.kind() {
+ Dynamic(predicates, region, ty::DynStar) => (predicates, region),
+ _ => panic!("Invalid dyn* cast_ty"),
+ };
+
+ let self_ty = op.ty(body, tcx);
+
+ self.prove_predicates(
+ existential_predicates
+ .iter()
+ .map(|predicate| predicate.with_self_ty(tcx, self_ty)),
+ location.to_locations(),
+ ConstraintCategory::Cast,
+ );
+
+ let outlives_predicate =
+ tcx.mk_predicate(Binder::dummy(ty::PredicateKind::TypeOutlives(
+ ty::OutlivesPredicate(self_ty, *region),
+ )));
+ self.prove_predicate(
+ outlives_predicate,
+ location.to_locations(),
+ ConstraintCategory::Cast,
+ );
+ }
+
CastKind::Pointer(PointerCast::MutToConstPointer) => {
let ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
@@ -2584,7 +2597,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.enumerate()
.filter_map(|(idx, constraint)| {
let ty::OutlivesPredicate(k1, r2) =
- constraint.no_bound_vars().unwrap_or_else(|| {
+ constraint.0.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", constraint,);
});
@@ -2659,7 +2672,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.check_local(&body, local, local_decl);
}
- for (block, block_data) in body.basic_blocks().iter_enumerated() {
+ for (block, block_data) in body.basic_blocks.iter_enumerated() {
let mut location = Location { block, statement_index: 0 };
for stmt in &block_data.statements {
if !stmt.source_info.span.is_dummy() {
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 2a7713bc4..8cf9ed53d 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -54,13 +54,6 @@ pub struct UniversalRegions<'tcx> {
/// The total number of universal region variables instantiated.
num_universals: usize,
- /// A special region variable created for the `'empty(U0)` region.
- /// Note that this is **not** a "universal" region, as it doesn't
- /// represent a universally bound placeholder or any such thing.
- /// But we do create it here in this type because it's a useful region
- /// to have around in a few limited cases.
- pub root_empty: RegionVid,
-
/// The "defining" type for this function, with all universal
/// regions instantiated. For a closure or generator, this is the
/// closure type, but for a top-level function it's the `FnDef`.
@@ -323,11 +316,7 @@ impl<'tcx> UniversalRegions<'tcx> {
/// See `UniversalRegionIndices::to_region_vid`.
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
- if let ty::ReEmpty(ty::UniverseIndex::ROOT) = *r {
- self.root_empty
- } else {
- self.indices.to_region_vid(r)
- }
+ self.indices.to_region_vid(r)
}
/// As part of the NLL unit tests, you can annotate a function with
@@ -501,16 +490,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
_ => None,
};
- let root_empty = self
- .infcx
- .next_nll_region_var(NllRegionVariableOrigin::Existential { from_forall: true })
- .to_region_vid();
-
UniversalRegions {
indices,
fr_static,
fr_fn_body,
- root_empty,
first_extern_index,
first_local_index,
num_universals,
@@ -768,10 +751,9 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
) {
- debug!("replace_late_bound_regions_with_nll_infer_vars(mir_def_id={:?})", mir_def_id);
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| {
- debug!("replace_late_bound_regions_with_nll_infer_vars: r={:?}", r);
+ debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR);
debug!(?region_vid);
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index 8d8e9d9b5..6469d0d7b 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -7,20 +7,21 @@ edition = "2021"
doctest = false
[dependencies]
-rustc_parse_format = { path = "../rustc_parse_format" }
-tracing = "0.1"
+rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
+rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
+rustc_parse_format = { path = "../rustc_parse_format" }
rustc_parse = { path = "../rustc_parse" }
-rustc_target = { path = "../rustc_target" }
rustc_session = { path = "../rustc_session" }
-smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../rustc_ast" }
-rustc_expand = { path = "../rustc_expand" }
rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
+tracing = "0.1"
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 1a0ea8f41..a1051d990 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -852,7 +852,7 @@ pub(super) fn expand_global_asm<'cx>(
if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
MacEager::items(smallvec![P(ast::Item {
ident: Ident::empty(),
- attrs: Vec::new(),
+ attrs: ast::AttrVec::new(),
id: ast::DUMMY_NODE_ID,
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
vis: ast::Visibility {
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 925c36edb..119724b50 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -52,7 +52,7 @@ pub fn expand_assert<'cx>(
let expr = if let Some(tokens) = custom_message {
let then = cx.expr(
call_site_span,
- ExprKind::MacCall(MacCall {
+ ExprKind::MacCall(P(MacCall {
path: panic_path(),
args: P(MacArgs::Delimited(
DelimSpan::from_single(call_site_span),
@@ -60,7 +60,7 @@ pub fn expand_assert<'cx>(
tokens,
)),
prior_type_ascription: None,
- }),
+ })),
);
expr_if_not(cx, call_site_span, cond_expr, then, None)
}
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index dcea883a5..f80215a3c 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -13,6 +13,7 @@ use rustc_span::{
symbol::{sym, Ident, Symbol},
Span,
};
+use thin_vec::thin_vec;
pub(super) struct Context<'cx, 'a> {
// An optimization.
@@ -116,7 +117,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
self.cx.item(
self.span,
Ident::empty(),
- vec![self.cx.attribute(attr::mk_list_item(
+ thin_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))],
))],
@@ -177,7 +178,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
});
self.cx.expr(
self.span,
- ExprKind::MacCall(MacCall {
+ ExprKind::MacCall(P(MacCall {
path: panic_path,
args: P(MacArgs::Delimited(
DelimSpan::from_single(self.span),
@@ -185,7 +186,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
initial.into_iter().chain(captures).collect::<TokenStream>(),
)),
prior_type_ascription: None,
- }),
+ })),
)
}
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index aa355150b..9046bf130 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -36,7 +36,7 @@ pub fn expand_cfg(
}
#[derive(SessionDiagnostic)]
-#[error(builtin_macros::requires_cfg_pattern)]
+#[diag(builtin_macros::requires_cfg_pattern)]
struct RequiresCfgPattern {
#[primary_span]
#[label]
@@ -44,7 +44,7 @@ struct RequiresCfgPattern {
}
#[derive(SessionDiagnostic)]
-#[error(builtin_macros::expected_one_cfg_pattern)]
+#[diag(builtin_macros::expected_one_cfg_pattern)]
struct OneCfgPattern {
#[primary_span]
span: Span,
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 89b2c3292..e673dff0d 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -188,14 +188,14 @@ impl CfgEval<'_, '_> {
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
- // `AttrAnnotatedTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
+ // to the captured `AttrTokenStream` (specifically, we capture
+ // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
let mut parser =
rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None);
parser.capture_cfg = true;
annotatable = parse_annotatable_with(&mut parser);
- // Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring
+ // Now that we have our re-parsed `AttrTokenStream`, recursively configuring
// our attribute target will correctly the tokens as well.
flat_map_annotatable(self, annotatable)
}
diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index 747e48ece..db05c00d2 100644
--- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
@@ -28,7 +28,13 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
continue;
}
- krate.attrs.push(mk_attr(AttrStyle::Inner, path, args, start_span.to(end_span)));
+ krate.attrs.push(mk_attr(
+ &parse_sess.attr_id_generator,
+ AttrStyle::Inner,
+ path,
+ args,
+ start_span.to(end_span),
+ ));
}
krate
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index a23dd1d12..41f4e8c23 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -39,7 +39,7 @@ pub fn expand_concat(
ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
cx.span_err(e.span, "cannot concatenate a byte string literal");
}
- ast::LitKind::Err(_) => {
+ ast::LitKind::Err => {
has_errors = true;
}
},
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index a1afec410..66e86bf21 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,6 +1,5 @@
use rustc_ast as ast;
use rustc_ast::{ptr::P, tokenstream::TokenStream};
-use rustc_data_structures::sync::Lrc;
use rustc_errors::Applicability;
use rustc_expand::base::{self, DummyResult};
@@ -43,7 +42,7 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
ast::LitKind::Bool(_) => {
cx.span_err(expr.span, "cannot concatenate boolean literals");
}
- ast::LitKind::Err(_) => {}
+ ast::LitKind::Err => {}
ast::LitKind::Int(_, _) if !is_nested => {
let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
@@ -185,5 +184,5 @@ pub fn expand_concat_bytes(
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
}
let sp = cx.with_def_site_ctxt(sp);
- base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator))))
+ base::MacEager::expr(cx.expr_byte_str(sp, accumulator))
}
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index d3de10ca4..e0fb7affb 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -32,7 +32,8 @@ impl MultiItemModifier for Expander {
ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
let template =
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
- let attr = attr::mk_attr_outer(meta_item.clone());
+ let attr =
+ attr::mk_attr_outer(&sess.parse_sess.attr_id_generator, meta_item.clone());
validate_attr::check_builtin_attribute(
&sess.parse_sess,
&attr,
@@ -126,9 +127,9 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
}
fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
- let help_msg = match lit.token.kind {
- token::Str if rustc_lexer::is_ident(lit.token.symbol.as_str()) => {
- format!("try using `#[derive({})]`", lit.token.symbol)
+ let help_msg = match lit.token_lit.kind {
+ token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => {
+ format!("try using `#[derive({})]`", lit.token_lit.symbol)
}
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
};
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 5ef68c6ae..77e0b6c55 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -15,7 +15,6 @@ pub fn expand_deriving_copy(
) {
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(marker::Copy),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 7755ff779..c7f2d95e7 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -1,12 +1,12 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-
use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, VariantData};
use rustc_data_structures::fx::FxHashSet;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_clone(
cx: &mut ExtCtxt<'_>,
@@ -68,10 +68,9 @@ pub fn expand_deriving_clone(
}
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(clone::Clone),
additional_bounds: bounds,
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 4e798bf6a..5b556c5c9 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_eq(
cx: &mut ExtCtxt<'_>,
@@ -20,10 +21,9 @@ pub fn expand_deriving_eq(
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
let no_coverage = cx.meta_word(span, sym::no_coverage);
- let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
+ let attrs = thin_vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(cmp::Eq),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 1612be862..726258695 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -1,11 +1,11 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-
use rustc_ast::MetaItem;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_ord(
cx: &mut ExtCtxt<'_>,
@@ -15,10 +15,9 @@ pub fn expand_deriving_ord(
push: &mut dyn FnMut(Annotatable),
) {
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(cmp::Ord),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 0141b3377..42ee65b57 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -1,12 +1,12 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std};
-
use rustc_ast::ptr::P;
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_partial_eq(
cx: &mut ExtCtxt<'_>,
@@ -15,14 +15,8 @@ pub fn expand_deriving_partial_eq(
item: &Annotatable,
push: &mut dyn FnMut(Annotatable),
) {
- fn cs_op(
- cx: &mut ExtCtxt<'_>,
- span: Span,
- substr: &Substructure<'_>,
- op: BinOpKind,
- combiner: BinOpKind,
- base: bool,
- ) -> BlockOrExpr {
+ fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
+ let base = true;
let expr = cs_fold(
true, // use foldl
cx,
@@ -47,39 +41,22 @@ pub fn expand_deriving_partial_eq(
cx.expr_deref(field.span, expr.clone())
}
};
- cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr))
+ cx.expr_binary(
+ field.span,
+ BinOpKind::Eq,
+ convert(&field.self_expr),
+ convert(other_expr),
+ )
+ }
+ CsFold::Combine(span, expr1, expr2) => {
+ cx.expr_binary(span, BinOpKind::And, expr1, expr2)
}
- CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
CsFold::Fieldless => cx.expr_bool(span, base),
},
);
BlockOrExpr::new_expr(expr)
}
- fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
- cs_op(cx, span, substr, BinOpKind::Eq, BinOpKind::And, true)
- }
- fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
- cs_op(cx, span, substr, BinOpKind::Ne, BinOpKind::Or, false)
- }
-
- macro_rules! md {
- ($name:expr, $f:ident) => {{
- let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
- MethodDef {
- name: $name,
- generics: Bounds::empty(),
- explicit_self: true,
- nonself_args: vec![(self_ref(), sym::other)],
- ret_ty: Path(path_local!(bool)),
- attributes: attrs,
- unify_fieldless_variants: true,
- combine_substructure: combine_substructure(Box::new(|a, b, c| $f(a, b, c))),
- }
- }};
- }
-
super::inject_impl_of_structural_trait(
cx,
span,
@@ -88,17 +65,23 @@ pub fn expand_deriving_partial_eq(
push,
);
- // avoid defining `ne` if we can
- // c-like enums, enums without any fields and structs without fields
- // can safely define only `eq`.
- let mut methods = vec![md!(sym::eq, cs_eq)];
- if !is_type_without_fields(item) {
- methods.push(md!(sym::ne, cs_ne));
- }
+ // No need to generate `ne`, the default suffices, and not generating it is
+ // faster.
+ let inline = cx.meta_word(span, sym::inline);
+ let attrs = thin_vec![cx.attribute(inline)];
+ let methods = vec![MethodDef {
+ name: sym::eq,
+ generics: Bounds::empty(),
+ explicit_self: true,
+ nonself_args: vec![(self_ref(), sym::other)],
+ ret_ty: Path(path_local!(bool)),
+ attributes: attrs,
+ unify_fieldless_variants: true,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| cs_eq(a, b, c))),
+ }];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(cmp::PartialEq),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 2ebb01cc8..516892aed 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -1,11 +1,11 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_std, pathvec_std};
-
use rustc_ast::MetaItem;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_partial_ord(
cx: &mut ExtCtxt<'_>,
@@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord(
Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std));
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let partial_cmp_def = MethodDef {
name: sym::partial_cmp,
@@ -36,7 +36,6 @@ pub fn expand_deriving_partial_ord(
let trait_def = TraitDef {
span,
- attributes: vec![],
path: path_std!(cmp::PartialOrd),
additional_bounds: vec![],
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index ceef893e8..4af7fd816 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -19,7 +19,6 @@ pub fn expand_deriving_debug(
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(fmt::Debug),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
@@ -30,7 +29,7 @@ pub fn expand_deriving_debug(
explicit_self: true,
nonself_args: vec![(fmtr, sym::f)],
ret_ty: Path(path_std!(fmt::Result)),
- attributes: Vec::new(),
+ attributes: ast::AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
show_substructure(a, b, c)
@@ -52,7 +51,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
// We want to make sure we have the ctxt set so that we can use unstable methods
let span = cx.with_def_site_ctxt(span);
- let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
+ let name = cx.expr_str(span, ident.name);
let fmt = substr.nonselflike_args[0].clone();
// Struct and tuples are similar enough that we use the same code for both,
@@ -89,10 +88,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
for i in 0..fields.len() {
let field = &fields[i];
if is_struct {
- let name = cx.expr_lit(
- field.span,
- ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
- );
+ let name = cx.expr_str(field.span, field.name.unwrap().name);
args.push(name);
}
// Use an extra indirection to make sure this works for unsized types.
@@ -108,10 +104,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
for field in fields {
if is_struct {
- name_exprs.push(cx.expr_lit(
- field.span,
- ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
- ));
+ name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name));
}
// Use an extra indirection to make sure this works for unsized types.
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index d688143a2..7174dbbe7 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -22,7 +22,6 @@ pub fn expand_deriving_rustc_decodable(
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
@@ -48,7 +47,7 @@ pub fn expand_deriving_rustc_decodable(
],
PathKind::Std,
)),
- attributes: Vec::new(),
+ attributes: ast::AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
decodable_substructure(a, b, c, krate)
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 517769091..a94c8a996 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -1,16 +1,14 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
-
use rustc_ast as ast;
-use rustc_ast::walk_list;
-use rustc_ast::EnumDef;
-use rustc_ast::VariantData;
+use rustc_ast::{walk_list, EnumDef, VariantData};
use rustc_errors::Applicability;
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::Ident;
use rustc_span::symbol::{kw, sym};
use rustc_span::Span;
use smallvec::SmallVec;
+use thin_vec::thin_vec;
pub fn expand_deriving_default(
cx: &mut ExtCtxt<'_>,
@@ -22,10 +20,9 @@ pub fn expand_deriving_default(
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: Path::new(vec![kw::Default, sym::Default]),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 70167cac6..b220e5423 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -89,7 +89,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::pathvec_std;
-use rustc_ast::{ExprKind, MetaItem, Mutability};
+use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@@ -106,7 +106,6 @@ pub fn expand_deriving_rustc_encodable(
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
@@ -132,7 +131,7 @@ pub fn expand_deriving_rustc_encodable(
],
PathKind::Std,
)),
- attributes: Vec::new(),
+ attributes: AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c, krate)
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 735017aa5..3cc160adb 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -162,30 +162,28 @@
pub use StaticFields::*;
pub use SubstructureFields::*;
-use std::cell::RefCell;
-use std::iter;
-use std::vec;
-
+use crate::deriving;
use rustc_ast::ptr::P;
-use rustc_ast::{self as ast, EnumDef, Expr, Generics, PatKind};
+use rustc_ast::{
+ self as ast, BindingAnnotation, ByRef, EnumDef, Expr, Generics, Mutability, PatKind,
+};
use rustc_ast::{GenericArg, GenericParamKind, VariantData};
use rustc_attr as attr;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
-
+use std::cell::RefCell;
+use std::iter;
+use std::vec;
+use thin_vec::thin_vec;
use ty::{Bounds, Path, Ref, Self_, Ty};
-use crate::deriving;
-
pub mod ty;
pub struct TraitDef<'a> {
/// The span for the current #[derive(Foo)] header.
pub span: Span,
- pub attributes: Vec<ast::Attribute>,
-
/// Path of the trait, including any type parameters
pub path: Path,
@@ -219,7 +217,7 @@ pub struct MethodDef<'a> {
/// Returns type
pub ret_ty: Ty,
- pub attributes: Vec<ast::Attribute>,
+ pub attributes: ast::AttrVec,
/// Can we combine fieldless variants for enums into a single match arm?
/// If true, indicates that the trait operation uses the enum tag in some
@@ -383,16 +381,11 @@ fn find_type_parameters(
}
// Place bound generic params on a stack, to extract them when a type is encountered.
- fn visit_poly_trait_ref(
- &mut self,
- trait_ref: &'a ast::PolyTraitRef,
- modifier: &'a ast::TraitBoundModifier,
- ) {
+ fn visit_poly_trait_ref(&mut self, trait_ref: &'a ast::PolyTraitRef) {
let stack_len = self.bound_generic_params_stack.len();
- self.bound_generic_params_stack
- .extend(trait_ref.bound_generic_params.clone().into_iter());
+ self.bound_generic_params_stack.extend(trait_ref.bound_generic_params.iter().cloned());
- visit::walk_poly_trait_ref(self, trait_ref, modifier);
+ visit::walk_poly_trait_ref(self, trait_ref);
self.bound_generic_params_stack.truncate(stack_len);
}
@@ -568,7 +561,7 @@ impl<'a> TraitDef<'a> {
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
- attrs: Vec::new(),
+ attrs: ast::AttrVec::new(),
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
defaultness: ast::Defaultness::Final,
generics: Generics::default(),
@@ -609,7 +602,7 @@ impl<'a> TraitDef<'a> {
param.bounds.iter().cloned()
).collect();
- cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, vec![], bounds, None)
+ cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None)
}
GenericParamKind::Const { ty, kw_span, .. } => {
let const_nodefault_kind = GenericParamKind::Const {
@@ -644,11 +637,7 @@ impl<'a> TraitDef<'a> {
}
ast::WherePredicate::EqPredicate(we) => {
let span = we.span.with_ctxt(ctxt);
- ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
- id: ast::DUMMY_NODE_ID,
- span,
- ..we.clone()
- })
+ ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() })
}
}
}));
@@ -726,15 +715,13 @@ impl<'a> TraitDef<'a> {
let self_type = cx.ty_path(path);
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
+ let attrs = thin_vec![attr];
let opt_trait_ref = Some(trait_ref);
- let mut a = vec![attr];
- a.extend(self.attributes.iter().cloned());
-
cx.item(
self.span,
Ident::empty(),
- a,
+ attrs,
ast::ItemKind::Impl(Box::new(ast::Impl {
unsafety: ast::Unsafe::No,
polarity: ast::ImplPolarity::Positive,
@@ -1078,9 +1065,9 @@ impl<'a> MethodDef<'a> {
let mut body = mk_body(cx, selflike_fields);
let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]);
- let use_ref_pat = is_packed && !always_copy;
+ let by_ref = ByRef::from(is_packed && !always_copy);
let patterns =
- trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, use_ref_pat);
+ trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, by_ref);
// Do the let-destructuring.
let mut stmts: Vec<_> = iter::zip(selflike_args, patterns)
@@ -1262,13 +1249,13 @@ impl<'a> MethodDef<'a> {
let sp = variant.span.with_ctxt(trait_.span.ctxt());
let variant_path = cx.path(sp, vec![type_ident, variant.ident]);
- let use_ref_pat = false; // because enums can't be repr(packed)
+ let by_ref = ByRef::No; // because enums can't be repr(packed)
let mut subpats: Vec<_> = trait_.create_struct_patterns(
cx,
variant_path,
&variant.data,
&prefixes,
- use_ref_pat,
+ by_ref,
);
// `(VariantK, VariantK, ...)` or just `VariantK`.
@@ -1429,7 +1416,7 @@ impl<'a> TraitDef<'a> {
struct_path: ast::Path,
struct_def: &'a VariantData,
prefixes: &[String],
- use_ref_pat: bool,
+ by_ref: ByRef,
) -> Vec<P<ast::Pat>> {
prefixes
.iter()
@@ -1437,17 +1424,19 @@ impl<'a> TraitDef<'a> {
let pieces_iter =
struct_def.fields().iter().enumerate().map(|(i, struct_field)| {
let sp = struct_field.span.with_ctxt(self.span.ctxt());
- let binding_mode = if use_ref_pat {
- ast::BindingMode::ByRef(ast::Mutability::Not)
- } else {
- ast::BindingMode::ByValue(ast::Mutability::Not)
- };
let ident = self.mk_pattern_ident(prefix, i);
let path = ident.with_span_pos(sp);
(
sp,
struct_field.ident,
- cx.pat(path.span, PatKind::Ident(binding_mode, path, None)),
+ cx.pat(
+ path.span,
+ PatKind::Ident(
+ BindingAnnotation(by_ref, Mutability::Not),
+ path,
+ None,
+ ),
+ ),
)
});
@@ -1637,19 +1626,3 @@ where
StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
}
}
-
-/// Returns `true` if the type has no value fields
-/// (for an enum, no variant has any fields)
-pub fn is_type_without_fields(item: &Annotatable) -> bool {
- if let Annotatable::Item(ref item) = *item {
- match item.kind {
- ast::ItemKind::Enum(ref enum_def, _) => {
- enum_def.variants.iter().all(|v| v.data.fields().is_empty())
- }
- ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(),
- _ => false,
- }
- } else {
- false
- }
-}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 4d46f7cd4..36e2e2930 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -146,7 +146,6 @@ fn mk_ty_param(
cx: &ExtCtxt<'_>,
span: Span,
name: Symbol,
- attrs: &[ast::Attribute],
bounds: &[Path],
self_ident: Ident,
self_generics: &Generics,
@@ -158,7 +157,7 @@ fn mk_ty_param(
cx.trait_bound(path)
})
.collect();
- cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
+ cx.typaram(span, Ident::new(name, span), bounds, None)
}
/// Bounds on type parameters.
@@ -183,7 +182,7 @@ impl Bounds {
.iter()
.map(|t| {
let (name, ref bounds) = *t;
- mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
+ mk_ty_param(cx, span, name, &bounds, self_ty, self_generics)
})
.collect();
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 32ae3d344..f1f02e7ce 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_std, pathvec_std};
-use rustc_ast::{MetaItem, Mutability};
+use rustc_ast::{AttrVec, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
@@ -21,7 +21,6 @@ pub fn expand_deriving_hash(
let arg = Path::new_local(typaram);
let hash_trait_def = TraitDef {
span,
- attributes: Vec::new(),
path,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
@@ -32,7 +31,7 @@ pub fn expand_deriving_hash(
explicit_self: true,
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
ret_ty: Unit,
- attributes: vec![],
+ attributes: AttrVec::new(),
unify_fieldless_variants: true,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
hash_substructure(a, b, c)
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index c1ca089da..a65d0bad6 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -164,7 +164,7 @@ fn inject_impl_of_structural_trait(
// Keep the lint and stability attributes of the original item, to control
// how the generated implementation is linted.
- let mut attrs = Vec::new();
+ let mut attrs = ast::AttrVec::new();
attrs.extend(
item.attrs
.iter()
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index ea0e768a5..3f1a8b3bc 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -48,7 +48,7 @@ fn expand<'cx>(
MacEager::expr(
cx.expr(
sp,
- ExprKind::MacCall(MacCall {
+ ExprKind::MacCall(P(MacCall {
path: Path {
span: sp,
segments: cx
@@ -64,7 +64,7 @@ fn expand<'cx>(
tts,
)),
prior_type_ascription: None,
- }),
+ })),
),
)
}
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 9eb96ec76..210048710 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -130,64 +130,46 @@ impl PositionalNamedArgsLint {
/// CountIsParam, which contains an index into the arguments.
fn maybe_add_positional_named_arg(
&mut self,
- current_positional_arg: usize,
- total_args_length: usize,
- format_argument_index: usize,
+ arg: Option<&FormatArg>,
ty: PositionalNamedArgType,
cur_piece: usize,
inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
- names: &FxHashMap<Symbol, (usize, Span)>,
has_formatting: bool,
) {
- let start_of_named_args = total_args_length - names.len();
- if current_positional_arg >= start_of_named_args {
- self.maybe_push(
- format_argument_index,
- ty,
- cur_piece,
- inner_span_to_replace,
- names,
- has_formatting,
- )
+ if let Some(arg) = arg {
+ if let Some(name) = arg.name {
+ self.push(name, ty, cur_piece, inner_span_to_replace, has_formatting)
+ }
}
}
- /// Try constructing a PositionalNamedArg struct and pushing it into the vec of positional
- /// named arguments. If a named arg associated with `format_argument_index` cannot be found,
- /// a new item will not be added as the lint cannot be emitted in this case.
- fn maybe_push(
+ /// Construct a PositionalNamedArg struct and push it into the vec of positional
+ /// named arguments.
+ fn push(
&mut self,
- format_argument_index: usize,
+ arg_name: Ident,
ty: PositionalNamedArgType,
cur_piece: usize,
inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
- names: &FxHashMap<Symbol, (usize, Span)>,
has_formatting: bool,
) {
- let named_arg = names
- .iter()
- .find(|&(_, &(index, _))| index == format_argument_index)
- .map(|found| found.clone());
-
- if let Some((&replacement, &(_, positional_named_arg_span))) = named_arg {
- // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in
- // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is
- // `Precision`.
- let inner_span_to_replace = if ty == PositionalNamedArgType::Precision {
- inner_span_to_replace
- .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end })
- } else {
- inner_span_to_replace
- };
- self.positional_named_args.push(PositionalNamedArg {
- ty,
- cur_piece,
- inner_span_to_replace,
- replacement,
- positional_named_arg_span,
- has_formatting,
- });
- }
+ // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in
+ // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is
+ // `Precision`.
+ let inner_span_to_replace = if ty == PositionalNamedArgType::Precision {
+ inner_span_to_replace
+ .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end })
+ } else {
+ inner_span_to_replace
+ };
+ self.positional_named_args.push(PositionalNamedArg {
+ ty,
+ cur_piece,
+ inner_span_to_replace,
+ replacement: arg_name.name,
+ positional_named_arg_span: arg_name.span,
+ has_formatting,
+ });
}
}
@@ -211,7 +193,7 @@ struct Context<'a, 'b> {
/// * `arg_types` (in JSON): `[[0, 1, 0], [0, 1, 1], [0, 1]]`
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
/// * `names` (in JSON): `{"foo": 2}`
- args: Vec<P<ast::Expr>>,
+ args: Vec<FormatArg>,
/// The number of arguments that were added by implicit capturing.
num_captured_args: usize,
/// Placeholder slot numbers indexed by argument.
@@ -219,7 +201,7 @@ struct Context<'a, 'b> {
/// Unique format specs seen for each argument.
arg_unique_types: Vec<Vec<ArgumentType>>,
/// Map from named arguments to their resolved indices.
- names: FxHashMap<Symbol, (usize, Span)>,
+ names: FxHashMap<Symbol, usize>,
/// The latest consecutive literal strings, or empty if there weren't any.
literal: String,
@@ -282,7 +264,7 @@ struct Context<'a, 'b> {
pub struct FormatArg {
expr: P<ast::Expr>,
- named: bool,
+ name: Option<Ident>,
}
/// Parses the arguments from the given list of tokens, returning the diagnostic
@@ -298,9 +280,9 @@ fn parse_args<'a>(
ecx: &mut ExtCtxt<'a>,
sp: Span,
tts: TokenStream,
-) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, (usize, Span)>)> {
+) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, usize>)> {
let mut args = Vec::<FormatArg>::new();
- let mut names = FxHashMap::<Symbol, (usize, Span)>::default();
+ let mut names = FxHashMap::<Symbol, usize>::default();
let mut p = ecx.new_parser_from_tts(tts);
@@ -365,9 +347,9 @@ fn parse_args<'a>(
p.bump();
p.expect(&token::Eq)?;
let e = p.parse_expr()?;
- if let Some((prev, _)) = names.get(&ident.name) {
+ if let Some(&prev) = names.get(&ident.name) {
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident))
- .span_label(args[*prev].expr.span, "previously here")
+ .span_label(args[prev].expr.span, "previously here")
.span_label(e.span, "duplicate argument")
.emit();
continue;
@@ -378,8 +360,8 @@ fn parse_args<'a>(
// if the input is valid, we can simply append to the positional
// args. And remember the names.
let slot = args.len();
- names.insert(ident.name, (slot, ident.span));
- args.push(FormatArg { expr: e, named: true });
+ names.insert(ident.name, slot);
+ args.push(FormatArg { expr: e, name: Some(ident) });
}
_ => {
let e = p.parse_expr()?;
@@ -389,12 +371,12 @@ fn parse_args<'a>(
"positional arguments cannot follow named arguments",
);
err.span_label(e.span, "positional arguments must be before named arguments");
- for pos in names.values() {
- err.span_label(args[pos.0].expr.span, "named argument");
+ for &pos in names.values() {
+ err.span_label(args[pos].expr.span, "named argument");
}
err.emit();
}
- args.push(FormatArg { expr: e, named: false });
+ args.push(FormatArg { expr: e, name: None });
}
}
}
@@ -410,8 +392,7 @@ impl<'a, 'b> Context<'a, 'b> {
fn resolve_name_inplace(&mut self, p: &mut parse::Piece<'_>) {
// NOTE: the `unwrap_or` branch is needed in case of invalid format
// arguments, e.g., `format_args!("{foo}")`.
- let lookup =
- |s: &str| self.names.get(&Symbol::intern(s)).unwrap_or(&(0, Span::default())).0;
+ let lookup = |s: &str| self.names.get(&Symbol::intern(s)).copied().unwrap_or(0);
match *p {
parse::String(_) => {}
@@ -432,7 +413,7 @@ impl<'a, 'b> Context<'a, 'b> {
/// Verifies one piece of a parse string, and remembers it if valid.
/// All errors are not emitted as fatal so we can continue giving errors
/// about this and possibly other format strings.
- fn verify_piece(&mut self, p: &parse::Piece<'_>) {
+ fn verify_piece(&mut self, p: &parse::Piece<'a>) {
match *p {
parse::String(..) => {}
parse::NextArgument(ref arg) => {
@@ -452,18 +433,20 @@ impl<'a, 'b> Context<'a, 'b> {
let has_precision = arg.format.precision != Count::CountImplied;
let has_width = arg.format.width != Count::CountImplied;
+ if has_precision || has_width {
+ // push before named params are resolved to aid diagnostics
+ self.arg_with_formatting.push(arg.format);
+ }
+
// argument second, if it's an implicit positional parameter
// it's written second, so it should come after width/precision.
let pos = match arg.position {
parse::ArgumentIs(i) => {
self.unused_names_lint.maybe_add_positional_named_arg(
- i,
- self.args.len(),
- i,
+ self.args.get(i),
PositionalNamedArgType::Arg,
self.curpiece,
Some(arg.position_span),
- &self.names,
has_precision || has_width,
);
@@ -471,13 +454,10 @@ impl<'a, 'b> Context<'a, 'b> {
}
parse::ArgumentImplicitlyIs(i) => {
self.unused_names_lint.maybe_add_positional_named_arg(
- i,
- self.args.len(),
- i,
+ self.args.get(i),
PositionalNamedArgType::Arg,
self.curpiece,
None,
- &self.names,
has_precision || has_width,
);
Exact(i)
@@ -561,15 +541,12 @@ impl<'a, 'b> Context<'a, 'b> {
) {
match c {
parse::CountImplied | parse::CountIs(..) => {}
- parse::CountIsParam(i) => {
+ parse::CountIsParam(i) | parse::CountIsStar(i) => {
self.unused_names_lint.maybe_add_positional_named_arg(
- i,
- self.args.len(),
- i,
+ self.args.get(i),
named_arg_type,
self.curpiece,
*inner_span,
- &self.names,
true,
);
self.verify_arg_type(Exact(i), Count);
@@ -609,7 +586,11 @@ impl<'a, 'b> Context<'a, 'b> {
let mut zero_based_note = false;
let count = self.pieces.len()
- + self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
+ + self
+ .arg_with_formatting
+ .iter()
+ .filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_)))
+ .count();
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
e = self.ecx.struct_span_err(
sp,
@@ -622,7 +603,7 @@ impl<'a, 'b> Context<'a, 'b> {
);
for arg in &self.args {
// Point at the arguments that will be formatted.
- e.span_label(arg.span, "");
+ e.span_label(arg.expr.span, "");
}
} else {
let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
@@ -658,7 +639,7 @@ impl<'a, 'b> Context<'a, 'b> {
if let Some(span) = fmt.precision_span {
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
match fmt.precision {
- parse::CountIsParam(pos) if pos > self.num_args() => {
+ parse::CountIsParam(pos) if pos >= self.num_args() => {
e.span_label(
span,
&format!(
@@ -670,12 +651,12 @@ impl<'a, 'b> Context<'a, 'b> {
);
zero_based_note = true;
}
- parse::CountIsParam(pos) => {
+ parse::CountIsStar(pos) => {
let count = self.pieces.len()
+ self
.arg_with_formatting
.iter()
- .filter(|fmt| fmt.precision_span.is_some())
+ .filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_)))
.count();
e.span_label(
span,
@@ -692,7 +673,7 @@ impl<'a, 'b> Context<'a, 'b> {
);
if let Some(arg) = self.args.get(pos) {
e.span_label(
- arg.span,
+ arg.expr.span,
"this parameter corresponds to the precision flag",
);
}
@@ -771,7 +752,7 @@ impl<'a, 'b> Context<'a, 'b> {
match self.names.get(&name) {
Some(&idx) => {
// Treat as positional arg.
- self.verify_arg_type(Capture(idx.0), ty)
+ self.verify_arg_type(Capture(idx), ty)
}
None => {
// For the moment capturing variables from format strings expanded from macros is
@@ -787,8 +768,11 @@ impl<'a, 'b> Context<'a, 'b> {
self.fmtsp
};
self.num_captured_args += 1;
- self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
- self.names.insert(name, (idx, span));
+ self.args.push(FormatArg {
+ expr: self.ecx.expr_ident(span, Ident::new(name, span)),
+ name: Some(Ident::new(name, span)),
+ });
+ self.names.insert(name, idx);
self.verify_arg_type(Capture(idx), ty)
} else {
let msg = format!("there is no argument named `{}`", name);
@@ -853,7 +837,7 @@ impl<'a, 'b> Context<'a, 'b> {
};
match c {
parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))),
- parse::CountIsParam(i) => {
+ parse::CountIsParam(i) | parse::CountIsStar(i) => {
// This needs mapping too, as `i` is referring to a macro
// argument. If `i` is not found in `count_positions` then
// the error had already been emitted elsewhere.
@@ -924,31 +908,27 @@ impl<'a, 'b> Context<'a, 'b> {
},
position_span: arg.position_span,
format: parse::FormatSpec {
- fill: arg.format.fill,
+ fill: None,
align: parse::AlignUnknown,
flags: 0,
precision: parse::CountImplied,
- precision_span: None,
+ precision_span: arg.format.precision_span,
width: parse::CountImplied,
- width_span: None,
+ width_span: arg.format.width_span,
ty: arg.format.ty,
ty_span: arg.format.ty_span,
},
};
let fill = arg.format.fill.unwrap_or(' ');
-
let pos_simple = arg.position.index() == simple_arg.position.index();
- if arg.format.precision_span.is_some() || arg.format.width_span.is_some() {
- self.arg_with_formatting.push(arg.format);
- }
- if !pos_simple || arg.format != simple_arg.format || fill != ' ' {
+ if !pos_simple || arg.format != simple_arg.format {
self.all_pieces_simple = false;
}
// Build the format
- let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill));
+ let fill = self.ecx.expr_char(sp, fill);
let align = |name| {
let mut p = Context::rtpath(self.ecx, sym::Alignment);
p.push(Ident::new(name, sp));
@@ -1054,11 +1034,11 @@ impl<'a, 'b> Context<'a, 'b> {
// evaluated a single time each, in the order written by the programmer,
// and that the surrounding future/generator (if any) is Send whenever
// possible.
- let no_need_for_match =
- nicely_ordered && !original_args.iter().skip(1).any(|e| may_contain_yield_point(e));
+ let no_need_for_match = nicely_ordered
+ && !original_args.iter().skip(1).any(|arg| may_contain_yield_point(&arg.expr));
for (arg_index, arg_ty) in fmt_arg_index_and_ty {
- let e = &mut original_args[arg_index];
+ let e = &mut original_args[arg_index].expr;
let span = e.span;
let arg = if no_need_for_match {
let expansion_span = e.span.with_ctxt(self.macsp.ctxt());
@@ -1087,7 +1067,9 @@ impl<'a, 'b> Context<'a, 'b> {
// span is otherwise unavailable in the MIR used by borrowck).
let heads = original_args
.into_iter()
- .map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e))
+ .map(|arg| {
+ self.ecx.expr_addr_of(arg.expr.span.with_ctxt(self.macsp.ctxt()), arg.expr)
+ })
.collect();
let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::args, self.macsp));
@@ -1199,7 +1181,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>)
cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
span: MultiSpan::from_span(named_arg.positional_named_arg_span),
- msg: msg.clone(),
+ msg: msg.into(),
node_id: ast::CRATE_NODE_ID,
lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally {
@@ -1220,7 +1202,7 @@ pub fn expand_preparsed_format_args(
sp: Span,
efmt: P<ast::Expr>,
args: Vec<FormatArg>,
- names: FxHashMap<Symbol, (usize, Span)>,
+ names: FxHashMap<Symbol, usize>,
append_newline: bool,
) -> P<ast::Expr> {
// NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because
@@ -1312,16 +1294,17 @@ pub fn expand_preparsed_format_args(
if err.should_be_replaced_with_positional_argument {
let captured_arg_span =
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
- let positional_args = args.iter().filter(|arg| !arg.named).collect::<Vec<_>>();
+ let n_positional_args =
+ args.iter().rposition(|arg| arg.name.is_none()).map_or(0, |i| i + 1);
if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) {
- let span = match positional_args.last() {
+ let span = match args[..n_positional_args].last() {
Some(arg) => arg.expr.span,
None => fmt_sp,
};
e.multipart_suggestion_verbose(
"consider using a positional formatting argument instead",
vec![
- (captured_arg_span, positional_args.len().to_string()),
+ (captured_arg_span, n_positional_args.to_string()),
(span.shrink_to_hi(), format!(", {}", arg)),
],
Applicability::MachineApplicable,
@@ -1338,11 +1321,9 @@ pub fn expand_preparsed_format_args(
.map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
.collect();
- let named_pos: FxHashSet<usize> = names.values().cloned().map(|(i, _)| i).collect();
-
let mut cx = Context {
ecx,
- args: args.into_iter().map(|arg| arg.expr).collect(),
+ args,
num_captured_args: 0,
arg_types,
arg_unique_types,
@@ -1410,14 +1391,12 @@ pub fn expand_preparsed_format_args(
.enumerate()
.filter(|(i, ty)| ty.is_empty() && !cx.count_positions.contains_key(&i))
.map(|(i, _)| {
- let msg = if named_pos.contains(&i) {
- // named argument
+ let msg = if cx.args[i].name.is_some() {
"named argument never used"
} else {
- // positional argument
"argument never used"
};
- (cx.args[i].span, msg)
+ (cx.args[i].expr.span, msg)
})
.collect::<Vec<_>>();
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 36cfbba45..45b9b8ab6 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -4,11 +4,12 @@ use rustc_ast::expand::allocator::{
AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
};
use rustc_ast::ptr::P;
-use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
+use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand(
ecx: &mut ExtCtxt<'_>,
@@ -113,10 +114,10 @@ impl AllocFnFactory<'_, '_> {
self.cx.expr_call(self.ty_span, method, args)
}
- fn attrs(&self) -> Vec<Attribute> {
+ fn attrs(&self) -> AttrVec {
let special = sym::rustc_std_internal_symbol;
let special = self.cx.meta_word(self.span, special);
- vec![self.cx.attribute(special)]
+ thin_vec![self.cx.attribute(special)]
}
fn arg_ty(
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 11565ba72..8aeb3b82a 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -9,13 +9,16 @@
#![feature(if_let_guard)]
#![feature(is_sorted)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![recursion_limit = "256"]
extern crate proc_macro;
+#[macro_use]
+extern crate tracing;
+
use crate::deriving::*;
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 5cfda3349..ebe1c3663 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -281,7 +281,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
let proc_macro = Ident::new(sym::proc_macro, span);
- let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None));
+ let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
let bridge = Ident::new(sym::bridge, span);
let client = Ident::new(sym::client, span);
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 8bf3a0799..d78bbc3c9 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -216,7 +216,7 @@ pub fn expand_include_bytes(
}
};
match cx.source_map().load_binary_file(&file) {
- Ok(bytes) => base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(bytes.into()))),
+ Ok(bytes) => base::MacEager::expr(cx.expr_byte_str(sp, bytes)),
Err(e) => {
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
DummyResult::any(sp)
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index 09ad5f9b3..49ef538f0 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -6,6 +6,7 @@ use rustc_span::edition::Edition::*;
use rustc_span::hygiene::AstPass;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::DUMMY_SP;
+use thin_vec::thin_vec;
pub fn inject(
mut krate: ast::Crate,
@@ -51,7 +52,7 @@ pub fn inject(
cx.item(
span,
ident,
- vec![cx.attribute(cx.meta_word(span, sym::macro_use))],
+ thin_vec![cx.attribute(cx.meta_word(span, sym::macro_use))],
ast::ItemKind::ExternCrate(None),
),
);
@@ -78,7 +79,7 @@ pub fn inject(
let use_item = cx.item(
span,
Ident::empty(),
- vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
+ thin_vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
ast::ItemKind::Use(ast::UseTree {
prefix: cx.path(span, import_path),
kind: ast::UseTreeKind::Glob,
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index e20375689..7efb6cc61 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -1,7 +1,6 @@
/// The expansion from a test function to the appropriate test struct for libtest
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
-
use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::ptr::P;
@@ -11,8 +10,8 @@ use rustc_expand::base::*;
use rustc_session::Session;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
-
use std::iter;
+use thin_vec::thin_vec;
// #[test_case] is used by custom test authors to mark tests
// When building for test, it needs to make the item public and gensym the name
@@ -219,7 +218,7 @@ pub fn expand_test_or_bench(
let mut test_const = cx.item(
sp,
Ident::new(item.ident.name, sp),
- vec![
+ thin_vec![
// #[cfg(test)]
cx.attribute(attr::mk_list_item(
Ident::new(sym::cfg, attr_sp),
@@ -334,9 +333,9 @@ pub fn expand_test_or_bench(
});
// extern crate test
- let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None));
+ let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
- tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
+ debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
if is_stmt {
vec![
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 0ebe29df9..561ca00c7 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -14,7 +14,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::PanicStrategy;
use smallvec::{smallvec, SmallVec};
-use tracing::debug;
+use thin_vec::thin_vec;
use std::{iter, mem};
@@ -187,7 +187,10 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
let dc_nested =
attr::mk_nested_word_item(Ident::new(sym::dead_code, self.def_site));
let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
- let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
+ let allow_dead_code = attr::mk_attr_outer(
+ &self.sess.parse_sess.attr_id_generator,
+ allow_dead_code_item,
+ );
let attrs = attrs
.into_iter()
.filter(|attr| {
@@ -298,8 +301,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let call_test_main = ecx.stmt_expr(call_test_main);
// extern crate test
- let test_extern_stmt =
- ecx.stmt_item(sp, ecx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)));
+ let test_extern_stmt = ecx.stmt_item(
+ sp,
+ ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)),
+ );
// #[rustc_main]
let main_meta = ecx.meta_word(sp, sym::rustc_main);
@@ -333,7 +338,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let main = P(ast::Item {
ident: main_id,
- attrs: vec![main_attr],
+ attrs: thin_vec![main_attr],
id: ast::DUMMY_NODE_ID,
kind: main,
vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },
diff --git a/compiler/rustc_codegen_cranelift/.cirrus.yml b/compiler/rustc_codegen_cranelift/.cirrus.yml
index 61da6a249..732edd661 100644
--- a/compiler/rustc_codegen_cranelift/.cirrus.yml
+++ b/compiler/rustc_codegen_cranelift/.cirrus.yml
@@ -22,4 +22,4 @@ task:
- # Reduce amount of benchmark runs as they are slow
- export COMPILE_RUNS=2
- export RUN_RUNS=2
- - ./test.sh
+ - ./y.rs test
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index aa556a21b..e8897e9ae 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -103,7 +103,7 @@ jobs:
# Enable extra checks
export CG_CLIF_ENABLE_VERIFIER=1
- ./test.sh
+ ./y.rs test
- name: Package prebuilt cg_clif
run: tar cvfJ cg_clif.tar.xz build
@@ -162,14 +162,14 @@ jobs:
#name: Test
run: |
# Enable backtraces for easier debugging
- #export RUST_BACKTRACE=1
+ #$Env:RUST_BACKTRACE=1
# Reduce amount of benchmark runs as they are slow
- #export COMPILE_RUNS=2
- #export RUN_RUNS=2
+ #$Env:COMPILE_RUNS=2
+ #$Env:RUN_RUNS=2
# Enable extra checks
- #export CG_CLIF_ENABLE_VERIFIER=1
+ #$Env:CG_CLIF_ENABLE_VERIFIER=1
./y.exe build
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index 532049c85..edae7e471 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -15,9 +15,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.56"
+version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
+checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
[[package]]
name = "ar"
@@ -50,18 +50,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "749d0d6022c9038dccf480bdde2a38d435937335bf2bb0f14e815d94517cdce8"
+checksum = "93945adbccc8d731503d3038814a51e8317497c9e205411820348132fa01a358"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e94370cc7b37bf652ccd8bb8f09bd900997f7ccf97520edfc75554bb5c4abbea"
+checksum = "2b482acc9d0d0d1ad3288a90a8150ee648be3dce8dc8c8669ff026f72debdc31"
dependencies = [
"cranelift-bforest",
"cranelift-codegen-meta",
@@ -77,30 +77,30 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a3cea8fdab90e44018c5b9a1dfd460d8ee265ac354337150222a354628bdb6"
+checksum = "f9ec188d71e663192ef9048f204e410a7283b609942efc9fcc77da6d496edbb8"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ac72f76f2698598951ab26d8c96eaa854810e693e7dd52523958b5909fde6b2"
+checksum = "3ad794b1b1c2c7bd9f7b76cfe0f084eaf7753e55d56191c3f7d89e8fa4978b99"
[[package]]
name = "cranelift-entity"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09eaeacfcd2356fe0e66b295e8f9d59fdd1ac3ace53ba50de14d628ec902f72d"
+checksum = "342da0d5056f4119d3c311c4aab2460ceb6ee6e127bb395b76dd2279a09ea7a5"
[[package]]
name = "cranelift-frontend"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dba69c9980d5ffd62c18a2bde927855fcd7c8dc92f29feaf8636052662cbd99c"
+checksum = "dfff792f775b07d4d9cfe9f1c767ce755c6cbadda1bbd6db18a1c75ff9f7376a"
dependencies = [
"cranelift-codegen",
"log",
@@ -110,15 +110,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2920dc1e05cac40304456ed3301fde2c09bd6a9b0210bcfa2f101398d628d5b"
+checksum = "8d51089478849f2ac8ef60a8a2d5346c8d4abfec0e45ac5b24530ef9f9499e1e"
[[package]]
name = "cranelift-jit"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c3c5ed067f2c81577e431f3039148a9c187b33cc79e0d1731fede27d801ec56"
+checksum = "095936e41720f86004b4c57ce88e6a13af28646bb3a6fb4afbebd5ae90c50029"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -129,14 +129,14 @@ dependencies = [
"log",
"region",
"target-lexicon",
- "winapi",
+ "windows-sys",
]
[[package]]
name = "cranelift-module"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eee6784303bf9af235237a4885f7417e09a35df896d38ea969a0081064b3ede4"
+checksum = "704a1aea4723d97eafe0fb7af110f6f6868b1ac95f5380bbc9adb2a3b8cf97e8"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -144,9 +144,9 @@ dependencies = [
[[package]]
name = "cranelift-native"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f04dfa45f9b2a6f587c564d6b63388e00cd6589d2df6ea2758cf79e1a13285e6"
+checksum = "885debe62f2078638d6585f54c9f05f5c2008f22ce5a2a9100ada785fc065dbd"
dependencies = [
"cranelift-codegen",
"libc",
@@ -155,9 +155,9 @@ dependencies = [
[[package]]
name = "cranelift-object"
-version = "0.85.3"
+version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf38b2c505db749276793116c0cb30bd096206c7810e471677a453134881881"
+checksum = "aac1310cf1081ae8eca916c92cd163b977c77cab6e831fa812273c26ff921816"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -187,9 +187,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
@@ -198,43 +198,37 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.26.1"
+version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
+checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
dependencies = [
"indexmap",
]
[[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.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
name = "indexmap"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
- "hashbrown 0.12.3",
+ "hashbrown",
]
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
[[package]]
name = "libloading"
@@ -248,9 +242,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.14"
+version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
@@ -266,33 +260,33 @@ dependencies = [
[[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"
[[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",
- "hashbrown 0.11.2",
+ "hashbrown",
"indexmap",
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.10.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "regalloc2"
-version = "0.2.3"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a8d23b35d7177df3b9d31ed8a9ab4bf625c668be77a319d4f5efd4a5257701c"
+checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779"
dependencies = [
"fxhash",
"log",
@@ -340,15 +334,15 @@ checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
[[package]]
name = "smallvec"
-version = "1.8.1"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
+checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]]
name = "target-lexicon"
-version = "0.12.3"
+version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1"
+checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
[[package]]
name = "version_check"
@@ -358,9 +352,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
+version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
@@ -383,3 +377,46 @@ name = "winapi-x86_64-pc-windows-gnu"
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"
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index 61e977e3e..e7c342748 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,15 +8,15 @@ crate-type = ["dylib"]
[dependencies]
# These have to be in sync with each other
-cranelift-codegen = { version = "0.85.3", features = ["unwind", "all-arch"] }
-cranelift-frontend = "0.85.3"
-cranelift-module = "0.85.3"
-cranelift-native = "0.85.3"
-cranelift-jit = { version = "0.85.3", optional = true }
-cranelift-object = "0.85.3"
+cranelift-codegen = { version = "0.87.0", features = ["unwind", "all-arch"] }
+cranelift-frontend = "0.87.0"
+cranelift-module = "0.87.0"
+cranelift-native = "0.87.0"
+cranelift-jit = { version = "0.87.0", optional = true }
+cranelift-object = "0.87.0"
target-lexicon = "0.12.0"
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
-object = { version = "0.28.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
+object = { version = "0.29.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.9.1"
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index 8a2db5a43..1e84c7fa3 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -52,9 +52,7 @@ configuration options.
## Not yet supported
* Inline assembly ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1041))
- * On Linux there is support for invoking an external assembler for `global_asm!` and `asm!`.
- `llvm_asm!` will remain unimplemented forever. `asm!` doesn't yet support reg classes. You
- have to specify specific registers instead.
+ * On UNIX there is support for invoking an external assembler for `global_asm!` and `asm!`.
* SIMD ([tracked here](https://github.com/bjorn3/rustc_codegen_cranelift/issues/171), some basic things work)
## License
diff --git a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
index 7b2cdd273..6c5043bb6 100644
--- a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
@@ -56,9 +56,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
-version = "0.1.75"
+version = "0.1.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6e3183e88f659a862835db8f4b67dbeed3d93e44dd4927eef78edb1c149d784"
+checksum = "4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"
dependencies = [
"rustc-std-workspace-core",
]
@@ -69,9 +69,9 @@ version = "0.0.0"
[[package]]
name = "dlmalloc"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
+checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a"
dependencies = [
"compiler_builtins",
"libc",
@@ -80,9 +80,9 @@ dependencies = [
[[package]]
name = "fortanix-sgx-abi"
-version = "0.3.3"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"
+checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-core",
@@ -123,9 +123,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7668753748e445859e4e373c3d41117235d9feed578392f5a3a73efdc751ca4a"
+checksum = "897cd85af6387be149f55acf168e41be176a02de7872403aaab184afc2f327e6"
dependencies = [
"compiler_builtins",
"libc",
@@ -135,9 +135,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
dependencies = [
"rustc-std-workspace-core",
]
diff --git a/compiler/rustc_codegen_cranelift/build_system/abi_checker.rs b/compiler/rustc_codegen_cranelift/build_system/abi_checker.rs
new file mode 100644
index 000000000..67dbd0a38
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/build_system/abi_checker.rs
@@ -0,0 +1,60 @@
+use super::build_sysroot;
+use super::config;
+use super::utils::spawn_and_wait;
+use build_system::SysrootKind;
+use std::env;
+use std::path::Path;
+use std::process::Command;
+
+pub(crate) fn run(
+ channel: &str,
+ sysroot_kind: SysrootKind,
+ target_dir: &Path,
+ cg_clif_build_dir: &Path,
+ host_triple: &str,
+ target_triple: &str,
+) {
+ if !config::get_bool("testsuite.abi-checker") {
+ eprintln!("[SKIP] abi-checker");
+ return;
+ }
+
+ if host_triple != target_triple {
+ eprintln!("[SKIP] abi-checker (cross-compilation not supported)");
+ return;
+ }
+
+ eprintln!("Building sysroot for abi-checker");
+ build_sysroot::build_sysroot(
+ channel,
+ sysroot_kind,
+ target_dir,
+ cg_clif_build_dir,
+ host_triple,
+ target_triple,
+ );
+
+ eprintln!("Running abi-checker");
+ let mut abi_checker_path = env::current_dir().unwrap();
+ abi_checker_path.push("abi-checker");
+ env::set_current_dir(abi_checker_path.clone()).unwrap();
+
+ let build_dir = abi_checker_path.parent().unwrap().join("build");
+ let cg_clif_dylib_path = build_dir.join(if cfg!(windows) { "bin" } else { "lib" }).join(
+ env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX,
+ );
+
+ let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
+
+ let mut cmd = Command::new("cargo");
+ cmd.arg("run");
+ cmd.arg("--target");
+ cmd.arg(target_triple);
+ cmd.arg("--");
+ cmd.arg("--pairs");
+ cmd.args(pairs);
+ cmd.arg("--add-rustc-codegen-backend");
+ cmd.arg(format!("cgclif:{}", cg_clif_dylib_path.display()));
+
+ spawn_and_wait(cmd);
+}
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
index 48faec8bc..9e59b8199 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
@@ -2,6 +2,8 @@ use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
+use super::utils::is_ci;
+
pub(crate) fn build_backend(
channel: &str,
host_triple: &str,
@@ -14,7 +16,7 @@ pub(crate) fn build_backend(
let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default();
- if env::var("CI").as_ref().map(|val| &**val) == Ok("true") {
+ if is_ci() {
// Deny warnings on CI
rustflags += " -Dwarnings";
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
index 16cce83dd..7e205b0fd 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
@@ -2,7 +2,7 @@ use std::fs;
use std::path::{Path, PathBuf};
use std::process::{self, Command};
-use super::rustc_info::{get_file_name, get_rustc_version};
+use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
use super::utils::{spawn_and_wait, try_hard_link};
use super::SysrootKind;
@@ -10,10 +10,12 @@ pub(crate) fn build_sysroot(
channel: &str,
sysroot_kind: SysrootKind,
target_dir: &Path,
- cg_clif_build_dir: PathBuf,
+ cg_clif_build_dir: &Path,
host_triple: &str,
target_triple: &str,
) {
+ eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
+
if target_dir.exists() {
fs::remove_dir_all(target_dir).unwrap();
}
@@ -35,11 +37,13 @@ pub(crate) fn build_sysroot(
// Build and copy rustc and cargo wrappers
for wrapper in ["rustc-clif", "cargo-clif"] {
+ let wrapper_name = get_wrapper_file_name(wrapper, "bin");
+
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(target_dir.join(wrapper_name))
.arg("-g");
spawn_and_wait(build_cargo_wrapper_cmd);
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/mod.rs b/compiler/rustc_codegen_cranelift/build_system/mod.rs
index b897b7fba..c3706dc6f 100644
--- a/compiler/rustc_codegen_cranelift/build_system/mod.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/mod.rs
@@ -2,11 +2,15 @@ use std::env;
use std::path::PathBuf;
use std::process;
+use self::utils::is_ci;
+
+mod abi_checker;
mod build_backend;
mod build_sysroot;
mod config;
mod prepare;
mod rustc_info;
+mod tests;
mod utils;
fn usage() {
@@ -15,6 +19,9 @@ fn usage() {
eprintln!(
" ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
);
+ eprintln!(
+ " ./y.rs test [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
+ );
}
macro_rules! arg_error {
@@ -25,11 +32,13 @@ macro_rules! arg_error {
}};
}
+#[derive(PartialEq, Debug)]
enum Command {
Build,
+ Test,
}
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
pub(crate) enum SysrootKind {
None,
Clif,
@@ -42,16 +51,22 @@ pub fn main() {
// The target dir is expected in the default location. Guard against the user changing it.
env::set_var("CARGO_TARGET_DIR", "target");
+ if is_ci() {
+ // Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
+ env::set_var("CARGO_BUILD_INCREMENTAL", "false");
+ }
+
let mut args = env::args().skip(1);
let command = match args.next().as_deref() {
Some("prepare") => {
if args.next().is_some() {
- arg_error!("./x.rs prepare doesn't expect arguments");
+ arg_error!("./y.rs prepare doesn't expect arguments");
}
prepare::prepare();
process::exit(0);
}
Some("build") => Command::Build,
+ Some("test") => Command::Test,
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
Some(command) => arg_error!("Unknown command {}", command),
None => {
@@ -117,12 +132,35 @@ pub fn main() {
let cg_clif_build_dir =
build_backend::build_backend(channel, &host_triple, use_unstable_features);
- build_sysroot::build_sysroot(
- channel,
- sysroot_kind,
- &target_dir,
- cg_clif_build_dir,
- &host_triple,
- &target_triple,
- );
+ match command {
+ Command::Test => {
+ tests::run_tests(
+ channel,
+ sysroot_kind,
+ &target_dir,
+ &cg_clif_build_dir,
+ &host_triple,
+ &target_triple,
+ );
+
+ abi_checker::run(
+ channel,
+ sysroot_kind,
+ &target_dir,
+ &cg_clif_build_dir,
+ &host_triple,
+ &target_triple,
+ );
+ }
+ Command::Build => {
+ build_sysroot::build_sysroot(
+ channel,
+ sysroot_kind,
+ &target_dir,
+ &cg_clif_build_dir,
+ &host_triple,
+ &target_triple,
+ );
+ }
+ }
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index 8bb00352d..d23b7f00d 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -15,6 +15,14 @@ pub(crate) fn prepare() {
Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
clone_repo_shallow_github(
+ "abi-checker",
+ "Gankra",
+ "abi-checker",
+ "a2232d45f202846f5c02203c9f27355360f9a2ff",
+ );
+ apply_patches("abi-checker", Path::new("abi-checker"));
+
+ clone_repo_shallow_github(
"rand",
"rust-random",
"rand",
@@ -50,8 +58,7 @@ pub(crate) fn prepare() {
spawn_and_wait(build_cmd);
fs::copy(
Path::new("simple-raytracer/target/debug").join(get_file_name("main", "bin")),
- // FIXME use get_file_name here too once testing is migrated to rust
- "simple-raytracer/raytracer_cg_llvm",
+ Path::new("simple-raytracer").join(get_file_name("raytracer_cg_llvm", "bin")),
)
.unwrap();
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs b/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs
index 9206bb02b..913b589af 100644
--- a/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs
@@ -63,3 +63,12 @@ pub(crate) fn get_file_name(crate_name: &str, crate_type: &str) -> String {
assert!(file_name.contains(crate_name));
file_name
}
+
+/// Similar to `get_file_name`, but converts any dashes (`-`) in the `crate_name` to
+/// underscores (`_`). This is specially made for the the rustc and cargo wrappers
+/// which have a dash in the name, and that is not allowed in a crate name.
+pub(crate) fn get_wrapper_file_name(crate_name: &str, crate_type: &str) -> String {
+ let crate_name = crate_name.replace('-', "_");
+ let wrapper_name = get_file_name(&crate_name, crate_type);
+ wrapper_name.replace('_', "-")
+}
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
new file mode 100644
index 000000000..e21397cec
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -0,0 +1,619 @@
+use super::build_sysroot;
+use super::config;
+use super::rustc_info::get_wrapper_file_name;
+use super::utils::{spawn_and_wait, spawn_and_wait_with_input};
+use build_system::SysrootKind;
+use std::env;
+use std::ffi::OsStr;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::process::Command;
+
+struct TestCase {
+ config: &'static str,
+ func: &'static dyn Fn(&TestRunner),
+}
+
+impl TestCase {
+ const fn new(config: &'static str, func: &'static dyn Fn(&TestRunner)) -> Self {
+ Self { config, func }
+ }
+}
+
+const NO_SYSROOT_SUITE: &[TestCase] = &[
+ TestCase::new("build.mini_core", &|runner| {
+ runner.run_rustc([
+ "example/mini_core.rs",
+ "--crate-name",
+ "mini_core",
+ "--crate-type",
+ "lib,dylib",
+ "--target",
+ &runner.target_triple,
+ ]);
+ }),
+ TestCase::new("build.example", &|runner| {
+ runner.run_rustc([
+ "example/example.rs",
+ "--crate-type",
+ "lib",
+ "--target",
+ &runner.target_triple,
+ ]);
+ }),
+ TestCase::new("jit.mini_core_hello_world", &|runner| {
+ let mut jit_cmd = runner.rustc_command([
+ "-Zunstable-options",
+ "-Cllvm-args=mode=jit",
+ "-Cprefer-dynamic",
+ "example/mini_core_hello_world.rs",
+ "--cfg",
+ "jit",
+ "--target",
+ &runner.host_triple,
+ ]);
+ jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
+ spawn_and_wait(jit_cmd);
+
+ eprintln!("[JIT-lazy] mini_core_hello_world");
+ let mut jit_cmd = runner.rustc_command([
+ "-Zunstable-options",
+ "-Cllvm-args=mode=jit-lazy",
+ "-Cprefer-dynamic",
+ "example/mini_core_hello_world.rs",
+ "--cfg",
+ "jit",
+ "--target",
+ &runner.host_triple,
+ ]);
+ jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
+ spawn_and_wait(jit_cmd);
+ }),
+ TestCase::new("aot.mini_core_hello_world", &|runner| {
+ runner.run_rustc([
+ "example/mini_core_hello_world.rs",
+ "--crate-name",
+ "mini_core_hello_world",
+ "--crate-type",
+ "bin",
+ "-g",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]);
+ }),
+];
+
+const BASE_SYSROOT_SUITE: &[TestCase] = &[
+ TestCase::new("aot.arbitrary_self_types_pointers_and_wrappers", &|runner| {
+ runner.run_rustc([
+ "example/arbitrary_self_types_pointers_and_wrappers.rs",
+ "--crate-name",
+ "arbitrary_self_types_pointers_and_wrappers",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []);
+ }),
+ TestCase::new("aot.issue_91827_extern_types", &|runner| {
+ runner.run_rustc([
+ "example/issue-91827-extern-types.rs",
+ "--crate-name",
+ "issue_91827_extern_types",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("issue_91827_extern_types", []);
+ }),
+ TestCase::new("build.alloc_system", &|runner| {
+ runner.run_rustc([
+ "example/alloc_system.rs",
+ "--crate-type",
+ "lib",
+ "--target",
+ &runner.target_triple,
+ ]);
+ }),
+ TestCase::new("aot.alloc_example", &|runner| {
+ runner.run_rustc([
+ "example/alloc_example.rs",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("alloc_example", []);
+ }),
+ TestCase::new("jit.std_example", &|runner| {
+ runner.run_rustc([
+ "-Zunstable-options",
+ "-Cllvm-args=mode=jit",
+ "-Cprefer-dynamic",
+ "example/std_example.rs",
+ "--target",
+ &runner.host_triple,
+ ]);
+
+ eprintln!("[JIT-lazy] std_example");
+ runner.run_rustc([
+ "-Zunstable-options",
+ "-Cllvm-args=mode=jit-lazy",
+ "-Cprefer-dynamic",
+ "example/std_example.rs",
+ "--target",
+ &runner.host_triple,
+ ]);
+ }),
+ TestCase::new("aot.std_example", &|runner| {
+ runner.run_rustc([
+ "example/std_example.rs",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("std_example", ["arg"]);
+ }),
+ TestCase::new("aot.dst_field_align", &|runner| {
+ runner.run_rustc([
+ "example/dst-field-align.rs",
+ "--crate-name",
+ "dst_field_align",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("dst_field_align", []);
+ }),
+ TestCase::new("aot.subslice-patterns-const-eval", &|runner| {
+ runner.run_rustc([
+ "example/subslice-patterns-const-eval.rs",
+ "--crate-type",
+ "bin",
+ "-Cpanic=abort",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("subslice-patterns-const-eval", []);
+ }),
+ TestCase::new("aot.track-caller-attribute", &|runner| {
+ runner.run_rustc([
+ "example/track-caller-attribute.rs",
+ "--crate-type",
+ "bin",
+ "-Cpanic=abort",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("track-caller-attribute", []);
+ }),
+ TestCase::new("aot.float-minmax-pass", &|runner| {
+ runner.run_rustc([
+ "example/float-minmax-pass.rs",
+ "--crate-type",
+ "bin",
+ "-Cpanic=abort",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("float-minmax-pass", []);
+ }),
+ TestCase::new("aot.mod_bench", &|runner| {
+ runner.run_rustc([
+ "example/mod_bench.rs",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_triple,
+ ]);
+ runner.run_out_command("mod_bench", []);
+ }),
+];
+
+const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
+ TestCase::new("test.rust-random/rand", &|runner| {
+ runner.in_dir(["rand"], |runner| {
+ runner.run_cargo(["clean"]);
+
+ if runner.host_triple == runner.target_triple {
+ eprintln!("[TEST] rust-random/rand");
+ runner.run_cargo(["test", "--workspace"]);
+ } else {
+ eprintln!("[AOT] rust-random/rand");
+ runner.run_cargo([
+ "build",
+ "--workspace",
+ "--target",
+ &runner.target_triple,
+ "--tests",
+ ]);
+ }
+ });
+ }),
+ TestCase::new("bench.simple-raytracer", &|runner| {
+ runner.in_dir(["simple-raytracer"], |runner| {
+ let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string());
+
+ if runner.host_triple == runner.target_triple {
+ eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
+ let mut bench_compile = Command::new("hyperfine");
+ bench_compile.arg("--runs");
+ bench_compile.arg(&run_runs);
+ bench_compile.arg("--warmup");
+ bench_compile.arg("1");
+ bench_compile.arg("--prepare");
+ bench_compile.arg(format!("{:?}", runner.cargo_command(["clean"])));
+
+ if cfg!(windows) {
+ bench_compile.arg("cmd /C \"set RUSTFLAGS= && cargo build\"");
+ } else {
+ bench_compile.arg("RUSTFLAGS='' cargo build");
+ }
+
+ bench_compile.arg(format!("{:?}", runner.cargo_command(["build"])));
+ spawn_and_wait(bench_compile);
+
+ eprintln!("[BENCH RUN] ebobby/simple-raytracer");
+ fs::copy(PathBuf::from("./target/debug/main"), PathBuf::from("raytracer_cg_clif"))
+ .unwrap();
+
+ let mut bench_run = Command::new("hyperfine");
+ bench_run.arg("--runs");
+ bench_run.arg(&run_runs);
+ bench_run.arg(PathBuf::from("./raytracer_cg_llvm"));
+ bench_run.arg(PathBuf::from("./raytracer_cg_clif"));
+ spawn_and_wait(bench_run);
+ } else {
+ runner.run_cargo(["clean"]);
+ eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
+ eprintln!("[COMPILE] ebobby/simple-raytracer");
+ runner.run_cargo(["build", "--target", &runner.target_triple]);
+ eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
+ }
+ });
+ }),
+ TestCase::new("test.libcore", &|runner| {
+ runner.in_dir(["build_sysroot", "sysroot_src", "library", "core", "tests"], |runner| {
+ runner.run_cargo(["clean"]);
+
+ if runner.host_triple == runner.target_triple {
+ runner.run_cargo(["test"]);
+ } else {
+ eprintln!("Cross-Compiling: Not running tests");
+ runner.run_cargo(["build", "--target", &runner.target_triple, "--tests"]);
+ }
+ });
+ }),
+ TestCase::new("test.regex-shootout-regex-dna", &|runner| {
+ runner.in_dir(["regex"], |runner| {
+ runner.run_cargo(["clean"]);
+
+ // newer aho_corasick versions throw a deprecation warning
+ let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
+
+ let mut build_cmd = runner.cargo_command([
+ "build",
+ "--example",
+ "shootout-regex-dna",
+ "--target",
+ &runner.target_triple,
+ ]);
+ build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
+ spawn_and_wait(build_cmd);
+
+ if runner.host_triple == runner.target_triple {
+ let mut run_cmd = runner.cargo_command([
+ "run",
+ "--example",
+ "shootout-regex-dna",
+ "--target",
+ &runner.target_triple,
+ ]);
+ run_cmd.env("RUSTFLAGS", lint_rust_flags);
+
+ let input =
+ fs::read_to_string(PathBuf::from("examples/regexdna-input.txt")).unwrap();
+ let expected_path = PathBuf::from("examples/regexdna-output.txt");
+ let expected = fs::read_to_string(&expected_path).unwrap();
+
+ let output = spawn_and_wait_with_input(run_cmd, input);
+ // Make sure `[codegen mono items] start` doesn't poison the diff
+ let output = output
+ .lines()
+ .filter(|line| !line.contains("codegen mono items"))
+ .chain(Some("")) // This just adds the trailing newline
+ .collect::<Vec<&str>>()
+ .join("\r\n");
+
+ let output_matches = expected.lines().eq(output.lines());
+ if !output_matches {
+ let res_path = PathBuf::from("res.txt");
+ fs::write(&res_path, &output).unwrap();
+
+ if cfg!(windows) {
+ println!("Output files don't match!");
+ println!("Expected Output:\n{}", expected);
+ println!("Actual Output:\n{}", output);
+ } else {
+ let mut diff = Command::new("diff");
+ diff.arg("-u");
+ diff.arg(res_path);
+ diff.arg(expected_path);
+ spawn_and_wait(diff);
+ }
+
+ std::process::exit(1);
+ }
+ }
+ });
+ }),
+ TestCase::new("test.regex", &|runner| {
+ runner.in_dir(["regex"], |runner| {
+ runner.run_cargo(["clean"]);
+
+ // newer aho_corasick versions throw a deprecation warning
+ let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
+
+ if runner.host_triple == runner.target_triple {
+ let mut run_cmd = runner.cargo_command([
+ "test",
+ "--tests",
+ "--",
+ "--exclude-should-panic",
+ "--test-threads",
+ "1",
+ "-Zunstable-options",
+ "-q",
+ ]);
+ run_cmd.env("RUSTFLAGS", lint_rust_flags);
+ spawn_and_wait(run_cmd);
+ } else {
+ eprintln!("Cross-Compiling: Not running tests");
+ let mut build_cmd =
+ runner.cargo_command(["build", "--tests", "--target", &runner.target_triple]);
+ build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
+ spawn_and_wait(build_cmd);
+ }
+ });
+ }),
+ TestCase::new("test.portable-simd", &|runner| {
+ runner.in_dir(["portable-simd"], |runner| {
+ runner.run_cargo(["clean"]);
+ runner.run_cargo(["build", "--all-targets", "--target", &runner.target_triple]);
+
+ if runner.host_triple == runner.target_triple {
+ runner.run_cargo(["test", "-q"]);
+ }
+ });
+ }),
+];
+
+pub(crate) fn run_tests(
+ channel: &str,
+ sysroot_kind: SysrootKind,
+ target_dir: &Path,
+ cg_clif_build_dir: &Path,
+ host_triple: &str,
+ target_triple: &str,
+) {
+ let runner = TestRunner::new(host_triple.to_string(), target_triple.to_string());
+
+ if config::get_bool("testsuite.no_sysroot") {
+ build_sysroot::build_sysroot(
+ channel,
+ SysrootKind::None,
+ &target_dir,
+ cg_clif_build_dir,
+ &host_triple,
+ &target_triple,
+ );
+
+ let _ = fs::remove_dir_all(Path::new("target").join("out"));
+ runner.run_testsuite(NO_SYSROOT_SUITE);
+ } else {
+ eprintln!("[SKIP] no_sysroot tests");
+ }
+
+ let run_base_sysroot = config::get_bool("testsuite.base_sysroot");
+ let run_extended_sysroot = config::get_bool("testsuite.extended_sysroot");
+
+ if run_base_sysroot || run_extended_sysroot {
+ build_sysroot::build_sysroot(
+ channel,
+ sysroot_kind,
+ &target_dir,
+ cg_clif_build_dir,
+ &host_triple,
+ &target_triple,
+ );
+ }
+
+ if run_base_sysroot {
+ runner.run_testsuite(BASE_SYSROOT_SUITE);
+ } else {
+ eprintln!("[SKIP] base_sysroot tests");
+ }
+
+ if run_extended_sysroot {
+ runner.run_testsuite(EXTENDED_SYSROOT_SUITE);
+ } else {
+ eprintln!("[SKIP] extended_sysroot tests");
+ }
+}
+
+struct TestRunner {
+ root_dir: PathBuf,
+ out_dir: PathBuf,
+ jit_supported: bool,
+ rust_flags: String,
+ run_wrapper: Vec<String>,
+ host_triple: String,
+ target_triple: String,
+}
+
+impl TestRunner {
+ pub fn new(host_triple: String, target_triple: String) -> Self {
+ let root_dir = env::current_dir().unwrap();
+
+ let mut out_dir = root_dir.clone();
+ out_dir.push("target");
+ out_dir.push("out");
+
+ let is_native = host_triple == target_triple;
+ let jit_supported =
+ target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
+
+ let mut rust_flags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
+ let mut run_wrapper = Vec::new();
+
+ if !is_native {
+ match target_triple.as_str() {
+ "aarch64-unknown-linux-gnu" => {
+ // We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
+ rust_flags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rust_flags);
+ run_wrapper = vec!["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"];
+ }
+ "x86_64-pc-windows-gnu" => {
+ // We are cross-compiling for Windows. Run tests in wine.
+ run_wrapper = vec!["wine"];
+ }
+ _ => {
+ println!("Unknown non-native platform");
+ }
+ }
+ }
+
+ // FIXME fix `#[linkage = "extern_weak"]` without this
+ if host_triple.contains("darwin") {
+ rust_flags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rust_flags);
+ }
+
+ Self {
+ root_dir,
+ out_dir,
+ jit_supported,
+ rust_flags,
+ run_wrapper: run_wrapper.iter().map(|s| s.to_string()).collect(),
+ host_triple,
+ target_triple,
+ }
+ }
+
+ pub fn run_testsuite(&self, tests: &[TestCase]) {
+ for &TestCase { config, func } in tests {
+ let (tag, testname) = config.split_once('.').unwrap();
+ let tag = tag.to_uppercase();
+ let is_jit_test = tag == "JIT";
+
+ if !config::get_bool(config) || (is_jit_test && !self.jit_supported) {
+ eprintln!("[{tag}] {testname} (skipped)");
+ continue;
+ } else {
+ eprintln!("[{tag}] {testname}");
+ }
+
+ func(self);
+ }
+ }
+
+ fn in_dir<'a, I, F>(&self, dir: I, callback: F)
+ where
+ I: IntoIterator<Item = &'a str>,
+ F: FnOnce(&TestRunner),
+ {
+ let current = env::current_dir().unwrap();
+ let mut new = current.clone();
+ for d in dir {
+ new.push(d);
+ }
+
+ env::set_current_dir(new).unwrap();
+ callback(self);
+ env::set_current_dir(current).unwrap();
+ }
+
+ fn rustc_command<I, S>(&self, args: I) -> Command
+ where
+ I: IntoIterator<Item = S>,
+ S: AsRef<OsStr>,
+ {
+ let mut rustc_clif = self.root_dir.clone();
+ rustc_clif.push("build");
+ rustc_clif.push(get_wrapper_file_name("rustc-clif", "bin"));
+
+ let mut cmd = Command::new(rustc_clif);
+ cmd.args(self.rust_flags.split_whitespace());
+ cmd.arg("-L");
+ cmd.arg(format!("crate={}", self.out_dir.display()));
+ cmd.arg("--out-dir");
+ cmd.arg(format!("{}", self.out_dir.display()));
+ cmd.arg("-Cdebuginfo=2");
+ cmd.args(args);
+ cmd
+ }
+
+ fn run_rustc<I, S>(&self, args: I)
+ where
+ I: IntoIterator<Item = S>,
+ S: AsRef<OsStr>,
+ {
+ spawn_and_wait(self.rustc_command(args));
+ }
+
+ fn run_out_command<'a, I>(&self, name: &str, args: I)
+ where
+ I: IntoIterator<Item = &'a str>,
+ {
+ let mut full_cmd = vec![];
+
+ // Prepend the RUN_WRAPPER's
+ if !self.run_wrapper.is_empty() {
+ full_cmd.extend(self.run_wrapper.iter().cloned());
+ }
+
+ full_cmd.push({
+ let mut out_path = self.out_dir.clone();
+ out_path.push(name);
+ out_path.to_str().unwrap().to_string()
+ });
+
+ for arg in args.into_iter() {
+ full_cmd.push(arg.to_string());
+ }
+
+ let mut cmd_iter = full_cmd.into_iter();
+ let first = cmd_iter.next().unwrap();
+
+ let mut cmd = Command::new(first);
+ cmd.args(cmd_iter);
+
+ spawn_and_wait(cmd);
+ }
+
+ fn cargo_command<I, S>(&self, args: I) -> Command
+ where
+ I: IntoIterator<Item = S>,
+ S: AsRef<OsStr>,
+ {
+ let mut cargo_clif = self.root_dir.clone();
+ cargo_clif.push("build");
+ cargo_clif.push(get_wrapper_file_name("cargo-clif", "bin"));
+
+ let mut cmd = Command::new(cargo_clif);
+ cmd.args(args);
+ cmd.env("RUSTFLAGS", &self.rust_flags);
+ cmd
+ }
+
+ fn run_cargo<'a, I>(&self, args: I)
+ where
+ I: IntoIterator<Item = &'a str>,
+ {
+ spawn_and_wait(self.cargo_command(args));
+ }
+}
diff --git a/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs
index 12b5d70fa..bdf8f8ecd 100644
--- a/compiler/rustc_codegen_cranelift/build_system/utils.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/utils.rs
@@ -1,6 +1,8 @@
+use std::env;
use std::fs;
+use std::io::Write;
use std::path::Path;
-use std::process::{self, Command};
+use std::process::{self, Command, Stdio};
#[track_caller]
pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
@@ -18,6 +20,27 @@ pub(crate) fn spawn_and_wait(mut cmd: Command) {
}
}
+#[track_caller]
+pub(crate) fn spawn_and_wait_with_input(mut cmd: Command, input: String) -> String {
+ let mut child = cmd
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .spawn()
+ .expect("Failed to spawn child process");
+
+ let mut stdin = child.stdin.take().expect("Failed to open stdin");
+ std::thread::spawn(move || {
+ stdin.write_all(input.as_bytes()).expect("Failed to write to stdin");
+ });
+
+ let output = child.wait_with_output().expect("Failed to read stdout");
+ if !output.status.success() {
+ process::exit(1);
+ }
+
+ String::from_utf8(output.stdout).unwrap()
+}
+
pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
for entry in fs::read_dir(from).unwrap() {
let entry = entry.unwrap();
@@ -33,3 +56,7 @@ pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
}
}
}
+
+pub(crate) fn is_ci() -> bool {
+ env::var("CI").as_ref().map(|val| &**val) == Ok("true")
+}
diff --git a/compiler/rustc_codegen_cranelift/clean_all.sh b/compiler/rustc_codegen_cranelift/clean_all.sh
index ea1f8c1e8..62e52bd19 100755
--- a/compiler/rustc_codegen_cranelift/clean_all.sh
+++ b/compiler/rustc_codegen_cranelift/clean_all.sh
@@ -3,4 +3,4 @@ set -e
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
rm -rf target/ build/ perf.data{,.old} y.bin
-rm -rf rand/ regex/ simple-raytracer/ portable-simd/
+rm -rf rand/ regex/ simple-raytracer/ portable-simd/ abi-checker/
diff --git a/compiler/rustc_codegen_cranelift/config.txt b/compiler/rustc_codegen_cranelift/config.txt
index b14db27d6..2264d301d 100644
--- a/compiler/rustc_codegen_cranelift/config.txt
+++ b/compiler/rustc_codegen_cranelift/config.txt
@@ -15,3 +15,38 @@
# This option can be changed while the build system is already running for as long as sysroot
# building hasn't started yet.
#keep_sysroot
+
+
+# Testsuite
+#
+# Each test suite item has a corresponding key here. The default is to run all tests.
+# Comment any of these lines to skip individual tests.
+
+testsuite.no_sysroot
+build.mini_core
+build.example
+jit.mini_core_hello_world
+aot.mini_core_hello_world
+
+testsuite.base_sysroot
+aot.arbitrary_self_types_pointers_and_wrappers
+aot.issue_91827_extern_types
+build.alloc_system
+aot.alloc_example
+jit.std_example
+aot.std_example
+aot.dst_field_align
+aot.subslice-patterns-const-eval
+aot.track-caller-attribute
+aot.float-minmax-pass
+aot.mod_bench
+
+testsuite.extended_sysroot
+test.rust-random/rand
+bench.simple-raytracer
+test.libcore
+test.regex-shootout-regex-dna
+test.regex
+test.portable-simd
+
+testsuite.abi-checker
diff --git a/compiler/rustc_codegen_cranelift/example/alloc_system.rs b/compiler/rustc_codegen_cranelift/example/alloc_system.rs
index cf95c89bc..50261c193 100644
--- a/compiler/rustc_codegen_cranelift/example/alloc_system.rs
+++ b/compiler/rustc_codegen_cranelift/example/alloc_system.rs
@@ -94,7 +94,7 @@ mod platform {
struct Header(*mut u8);
const HEAP_ZERO_MEMORY: DWORD = 0x00000008;
unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
- &mut *(ptr as *mut Header).offset(-1)
+ &mut *(ptr as *mut Header).sub(1)
}
unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
let aligned = ptr.add(align - (ptr as usize & (align - 1)));
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 8b6042a3d..42f8aa50b 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -535,7 +535,7 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
}
#[lang = "box_free"]
-unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, alloc: ()) {
+unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, _alloc: ()) {
libc::free(ptr.pointer.0 as *mut u8);
}
@@ -575,11 +575,19 @@ pub mod intrinsics {
}
pub mod libc {
+ // With the new Universal CRT, msvc has switched to all the printf functions being inline wrapper
+ // functions. legacy_stdio_definitions.lib which provides the printf wrapper functions as normal
+ // symbols to link against.
+ #[cfg_attr(unix, link(name = "c"))]
+ #[cfg_attr(target_env="msvc", link(name="legacy_stdio_definitions"))]
+ extern "C" {
+ pub fn printf(format: *const i8, ...) -> i32;
+ }
+
#[cfg_attr(unix, link(name = "c"))]
#[cfg_attr(target_env = "msvc", link(name = "msvcrt"))]
extern "C" {
pub fn puts(s: *const i8) -> i32;
- pub fn printf(format: *const i8, ...) -> i32;
pub fn malloc(size: usize) -> *mut u8;
pub fn free(ptr: *mut u8);
pub fn memcpy(dst: *mut u8, src: *const u8, size: 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 aa1f239ba..e83be3a3d 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -139,7 +139,7 @@ pub struct bool_11 {
field10: bool,
}
-extern "C" fn bool_struct_in_11(arg0: bool_11) {}
+extern "C" fn bool_struct_in_11(_arg0: bool_11) {}
#[allow(unreachable_code)] // FIXME false positive
fn main() {
@@ -321,7 +321,7 @@ fn main() {
#[cfg(not(any(jit, windows)))]
test_tls();
- #[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
+ #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "darwin")))]
unsafe {
global_asm_test();
}
@@ -343,7 +343,7 @@ fn main() {
}
}
-#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
+#[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "darwin")))]
extern "C" {
fn global_asm_test();
}
@@ -358,6 +358,16 @@ global_asm! {
"
}
+#[cfg(all(not(jit), target_arch = "x86_64", target_os = "darwin"))]
+global_asm! {
+ "
+ .global _global_asm_test
+ _global_asm_test:
+ // comment that would normally be removed by LLVM
+ ret
+ "
+}
+
#[repr(C)]
enum c_void {
_1,
@@ -375,6 +385,7 @@ struct pthread_attr_t {
}
#[link(name = "pthread")]
+#[cfg(unix)]
extern "C" {
fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int;
@@ -391,6 +402,91 @@ extern "C" {
) -> c_int;
}
+type DWORD = u32;
+type LPDWORD = *mut u32;
+
+type LPVOID = *mut c_void;
+type HANDLE = *mut c_void;
+
+#[link(name = "msvcrt")]
+#[cfg(windows)]
+extern "C" {
+ fn WaitForSingleObject(
+ hHandle: LPVOID,
+ dwMilliseconds: DWORD
+ ) -> DWORD;
+
+ fn CreateThread(
+ lpThreadAttributes: LPVOID, // Technically LPSECURITY_ATTRIBUTES, but we don't use it anyway
+ dwStackSize: usize,
+ lpStartAddress: extern "C" fn(_: *mut c_void) -> *mut c_void,
+ lpParameter: LPVOID,
+ dwCreationFlags: DWORD,
+ lpThreadId: LPDWORD
+ ) -> HANDLE;
+}
+
+struct Thread {
+ #[cfg(windows)]
+ handle: HANDLE,
+ #[cfg(unix)]
+ handle: pthread_t,
+}
+
+impl Thread {
+ unsafe fn create(f: extern "C" fn(_: *mut c_void) -> *mut c_void) -> Self {
+ #[cfg(unix)]
+ {
+ let mut attr: pthread_attr_t = zeroed();
+ let mut thread: pthread_t = 0;
+
+ if pthread_attr_init(&mut attr) != 0 {
+ assert!(false);
+ }
+
+ if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 {
+ assert!(false);
+ }
+
+ Thread {
+ handle: thread,
+ }
+ }
+
+ #[cfg(windows)]
+ {
+ let handle = CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32);
+
+ if (handle as u64) == 0 {
+ assert!(false);
+ }
+
+ Thread {
+ handle,
+ }
+ }
+ }
+
+
+ unsafe fn join(self) {
+ #[cfg(unix)]
+ {
+ let mut res = 0 as *mut c_void;
+ pthread_join(self.handle, &mut res);
+ }
+
+ #[cfg(windows)]
+ {
+ // The INFINITE macro is used to signal operations that do not timeout.
+ let infinite = 0xffffffff;
+ assert!(WaitForSingleObject(self.handle, infinite) == 0);
+ }
+ }
+}
+
+
+
+
#[thread_local]
#[cfg(not(jit))]
static mut TLS: u8 = 42;
@@ -404,21 +500,10 @@ extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void {
#[cfg(not(jit))]
fn test_tls() {
unsafe {
- let mut attr: pthread_attr_t = zeroed();
- let mut thread: pthread_t = 0;
-
assert_eq!(TLS, 42);
- if pthread_attr_init(&mut attr) != 0 {
- assert!(false);
- }
-
- if pthread_create(&mut thread, &attr, mutate_tls, 0 as *mut c_void) != 0 {
- assert!(false);
- }
-
- let mut res = 0 as *mut c_void;
- pthread_join(thread, &mut res);
+ let thread = Thread::create(mutate_tls);
+ thread.join();
// TLS of main thread must not have been changed by the other thread.
assert_eq!(TLS, 42);
diff --git a/compiler/rustc_codegen_cranelift/patches/0001-abi-checker-Disable-failing-tests.patch b/compiler/rustc_codegen_cranelift/patches/0001-abi-checker-Disable-failing-tests.patch
new file mode 100644
index 000000000..526366a75
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/patches/0001-abi-checker-Disable-failing-tests.patch
@@ -0,0 +1,36 @@
+From 1a315ba225577dbbd1f449d9609f16f984f68708 Mon Sep 17 00:00:00 2001
+From: Afonso Bordado <afonso360@users.noreply.github.com>
+Date: Fri, 12 Aug 2022 22:51:58 +0000
+Subject: [PATCH] Disable abi-checker tests
+
+---
+ src/report.rs | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/src/report.rs b/src/report.rs
+index 7346f5e..8347762 100644
+--- a/src/report.rs
++++ b/src/report.rs
+@@ -45,6 +45,20 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn AbiImpl, callee: &dyn AbiImpl
+ //
+ // THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES
+
++ // Currently MSVC has some broken ABI issues. Furthermore, they cause
++ // a STATUS_ACCESS_VIOLATION, so we can't even run them. Ensure that they compile and link.
++ if cfg!(windows) && (test.test_name == "bool" || test.test_name == "ui128") {
++ result.run = Link;
++ result.check = Pass(Link);
++ }
++
++ // structs is broken in the current release of cranelift for aarch64.
++ // It has been fixed for cranelift 0.88: https://github.com/bytecodealliance/wasmtime/pull/4634
++ if cfg!(target_arch = "aarch64") && test.test_name == "structs" {
++ result.run = Link;
++ result.check = Pass(Link);
++ }
++
+ // END OF VENDOR RESERVED AREA
+ //
+ //
+--
+2.34.1
diff --git a/compiler/rustc_codegen_cranelift/patches/0023-sysroot-Ignore-failing-tests.patch b/compiler/rustc_codegen_cranelift/patches/0023-sysroot-Ignore-failing-tests.patch
index 50ef0bd94..f3cd7ee77 100644
--- a/compiler/rustc_codegen_cranelift/patches/0023-sysroot-Ignore-failing-tests.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0023-sysroot-Ignore-failing-tests.patch
@@ -46,5 +46,17 @@ index 4bc44e9..8e3c7a4 100644
#[test]
fn cell_allows_array_cycle() {
+diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs
+index 13b12db..96fe4b9 100644
+--- a/library/core/tests/atomic.rs
++++ b/library/core/tests/atomic.rs
+@@ -185,6 +185,7 @@ fn ptr_bitops() {
+ }
+
+ #[test]
++#[cfg_attr(target_arch = "s390x", ignore)] // s390x backend doesn't support stack alignment >8 bytes
+ #[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
+ fn ptr_bitops_tagging() {
+ #[repr(align(16))]
--
2.21.0 (Apple Git-122)
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 3ab395d89..14f2746ec 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2022-07-25"
+channel = "nightly-2022-08-24"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/compiler/rustc_codegen_cranelift/scripts/tests.sh b/compiler/rustc_codegen_cranelift/scripts/tests.sh
deleted file mode 100755
index 9b5ffa409..000000000
--- a/compiler/rustc_codegen_cranelift/scripts/tests.sh
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env bash
-
-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=''
-
-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"
- $MY_RUSTC example/mini_core.rs --crate-name mini_core --crate-type lib,dylib --target "$TARGET_TRIPLE"
-
- echo "[BUILD] example"
- $MY_RUSTC example/example.rs --crate-type lib --target "$TARGET_TRIPLE"
-
- if [[ "$JIT_SUPPORTED" = "1" ]]; then
- echo "[JIT] mini_core_hello_world"
- CG_CLIF_JIT_ARGS="abc bcd" $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic example/mini_core_hello_world.rs --cfg jit --target "$HOST_TRIPLE"
-
- echo "[JIT-lazy] mini_core_hello_world"
- CG_CLIF_JIT_ARGS="abc bcd" $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/mini_core_hello_world.rs --cfg jit --target "$HOST_TRIPLE"
- else
- echo "[JIT] mini_core_hello_world (skipped)"
- fi
-
- echo "[AOT] mini_core_hello_world"
- $MY_RUSTC example/mini_core_hello_world.rs --crate-name mini_core_hello_world --crate-type bin -g --target "$TARGET_TRIPLE"
- $RUN_WRAPPER ./target/out/mini_core_hello_world abc bcd
- # (echo "break set -n main"; echo "run"; sleep 1; echo "si -c 10"; sleep 1; echo "frame variable") | lldb -- ./target/out/mini_core_hello_world abc bcd
-}
-
-function base_sysroot_tests() {
- echo "[AOT] arbitrary_self_types_pointers_and_wrappers"
- $MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
- $RUN_WRAPPER ./target/out/arbitrary_self_types_pointers_and_wrappers
-
- echo "[AOT] issue_91827_extern_types"
- $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 "[BUILD] alloc_system"
- $MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"
-
- echo "[AOT] alloc_example"
- $MY_RUSTC example/alloc_example.rs --crate-type bin --target "$TARGET_TRIPLE"
- $RUN_WRAPPER ./target/out/alloc_example
-
- if [[ "$JIT_SUPPORTED" = "1" ]]; then
- echo "[JIT] std_example"
- $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
-
- echo "[JIT-lazy] std_example"
- $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
- else
- echo "[JIT] std_example (skipped)"
- fi
-
- 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
-
- echo "[AOT] track-caller-attribute"
- $MY_RUSTC example/track-caller-attribute.rs --crate-type bin -Cpanic=abort --target "$TARGET_TRIPLE"
- $RUN_WRAPPER ./target/out/track-caller-attribute
-
- echo "[AOT] float-minmax-pass"
- $MY_RUSTC example/float-minmax-pass.rs --crate-type bin -Cpanic=abort --target "$TARGET_TRIPLE"
- $RUN_WRAPPER ./target/out/float-minmax-pass
-
- echo "[AOT] mod_bench"
- $MY_RUSTC example/mod_bench.rs --crate-type bin --target "$TARGET_TRIPLE"
- $RUN_WRAPPER ./target/out/mod_bench
-}
-
-function extended_sysroot_tests() {
- pushd rand
- ../build/cargo-clif clean
- if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
- echo "[TEST] rust-random/rand"
- ../build/cargo-clif test --workspace
- else
- echo "[AOT] rust-random/rand"
- ../build/cargo-clif build --workspace --target $TARGET_TRIPLE --tests
- fi
- popd
-
- pushd simple-raytracer
- if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
- echo "[BENCH COMPILE] ebobby/simple-raytracer"
- hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo-clif clean" \
- "RUSTFLAGS='' cargo build" \
- "../build/cargo-clif build"
-
- echo "[BENCH RUN] ebobby/simple-raytracer"
- cp ./target/debug/main ./raytracer_cg_clif
- hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
- else
- ../build/cargo-clif clean
- echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
- echo "[COMPILE] ebobby/simple-raytracer"
- ../build/cargo-clif build --target $TARGET_TRIPLE
- echo "[BENCH RUN] ebobby/simple-raytracer (skipped)"
- fi
- popd
-
- pushd build_sysroot/sysroot_src/library/core/tests
- echo "[TEST] libcore"
- ../../../../../build/cargo-clif clean
- if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
- ../../../../../build/cargo-clif test
- else
- ../../../../../build/cargo-clif build --target $TARGET_TRIPLE --tests
- fi
- popd
-
- pushd regex
- echo "[TEST] rust-lang/regex example shootout-regex-dna"
- ../build/cargo-clif clean
- export RUSTFLAGS="$RUSTFLAGS --cap-lints warn" # newer aho_corasick versions throw a deprecation warning
- # Make sure `[codegen mono items] start` doesn't poison the diff
- ../build/cargo-clif build --example shootout-regex-dna --target $TARGET_TRIPLE
- if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
- cat examples/regexdna-input.txt \
- | ../build/cargo-clif run --example shootout-regex-dna --target $TARGET_TRIPLE \
- | grep -v "Spawned thread" > res.txt
- diff -u res.txt examples/regexdna-output.txt
- fi
-
- if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
- echo "[TEST] rust-lang/regex tests"
- ../build/cargo-clif test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
- else
- echo "[AOT] rust-lang/regex tests"
- ../build/cargo-clif build --tests --target $TARGET_TRIPLE
- fi
- popd
-
- pushd portable-simd
- echo "[TEST] rust-lang/portable-simd"
- ../build/cargo-clif clean
- ../build/cargo-clif build --all-targets --target $TARGET_TRIPLE
- if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
- ../build/cargo-clif test -q
- fi
- popd
-}
-
-case "$1" in
- "no_sysroot")
- no_sysroot_tests
- ;;
- "base_sysroot")
- base_sysroot_tests
- ;;
- "extended_sysroot")
- extended_sysroot_tests
- ;;
- *)
- echo "unknown test suite"
- ;;
-esac
diff --git a/compiler/rustc_codegen_cranelift/src/abi/comments.rs b/compiler/rustc_codegen_cranelift/src/abi/comments.rs
index 37d2679c1..7f4619b5c 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/comments.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/comments.rs
@@ -24,7 +24,7 @@ pub(super) fn add_arg_comment<'tcx>(
local: Option<mir::Local>,
local_field: Option<usize>,
params: &[Value],
- arg_abi_mode: PassMode,
+ arg_abi_mode: &PassMode,
arg_layout: TyAndLayout<'tcx>,
) {
if !fx.clif_comments.enabled() {
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 815450f68..0497c2570 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -342,7 +342,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let ret_place = codegen_place(fx, destination);
- // Handle special calls like instrinsics and empty drop glue.
+ // Handle special calls like intrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
let instance = ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
.unwrap()
diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
index 6c10baa53..96e25d3a8 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
@@ -23,7 +23,7 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
(RegKind::Integer, 9..=16) => types::I128,
(RegKind::Float, 4) => types::F32,
(RegKind::Float, 8) => types::F64,
- (RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
+ (RegKind::Vector, size) => types::I8.by(u32::try_from(size).unwrap()).unwrap(),
_ => unreachable!("{:?}", reg),
};
AbiParam::new(clif_ty)
@@ -38,7 +38,7 @@ fn apply_arg_attrs_to_abi_param(mut param: AbiParam, arg_attrs: ArgAttributes) -
param
}
-fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
+fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[AbiParam; 2]> {
let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 {
(0, 0)
} else {
@@ -100,7 +100,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
}
_ => unreachable!("{:?}", self.layout.abi),
},
- PassMode::Cast(cast) => cast_target_to_abi_params(cast),
+ PassMode::Cast(ref cast, pad_i32) => {
+ assert!(!pad_i32, "padding support not yet implemented");
+ cast_target_to_abi_params(cast)
+ }
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
if on_stack {
// Abi requires aligning struct size to pointer size
@@ -145,7 +148,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
}
_ => unreachable!("{:?}", self.layout.abi),
},
- PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()),
+ PassMode::Cast(ref cast, _) => {
+ (None, cast_target_to_abi_params(cast).into_iter().collect())
+ }
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => {
assert!(!on_stack);
(Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![])
@@ -160,7 +165,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
pub(super) fn to_casted_value<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
arg: CValue<'tcx>,
- cast: CastTarget,
+ cast: &CastTarget,
) -> SmallVec<[Value; 2]> {
let (ptr, meta) = arg.force_stack(fx);
assert!(meta.is_none());
@@ -179,12 +184,12 @@ pub(super) fn from_casted_value<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
block_params: &[Value],
layout: TyAndLayout<'tcx>,
- cast: CastTarget,
+ cast: &CastTarget,
) -> CValue<'tcx> {
let abi_params = cast_target_to_abi_params(cast);
let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();
let layout_size = u32::try_from(layout.size.bytes()).unwrap();
- let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
+ let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
// specify stack slot alignment.
@@ -193,7 +198,7 @@ pub(super) fn from_casted_value<'tcx>(
// larger alignment than the integer.
size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16,
});
- let ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0));
+ let ptr = Pointer::stack_slot(stack_slot);
let mut offset = 0;
let mut block_params_iter = block_params.iter().copied();
for param in abi_params {
@@ -224,7 +229,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
let (a, b) = arg.load_scalar_pair(fx);
smallvec![a, b]
}
- PassMode::Cast(cast) => to_casted_value(fx, arg, cast),
+ PassMode::Cast(ref cast, _) => to_casted_value(fx, arg, cast),
PassMode::Indirect { .. } => {
if is_owned {
match arg.force_stack(fx) {
@@ -268,7 +273,7 @@ pub(super) fn cvalue_for_param<'tcx>(
local,
local_field,
&block_params,
- arg_abi.mode,
+ &arg_abi.mode,
arg_abi.layout,
);
@@ -282,7 +287,9 @@ pub(super) fn cvalue_for_param<'tcx>(
assert_eq!(block_params.len(), 2, "{:?}", block_params);
Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout))
}
- PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)),
+ PassMode::Cast(ref cast, _) => {
+ Some(from_casted_value(fx, &block_params, arg_abi.layout, cast))
+ }
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
assert_eq!(block_params.len(), 1, "{:?}", block_params);
Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout))
diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs
index ff3bb2dfd..aaa141876 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs
@@ -13,7 +13,7 @@ pub(super) fn codegen_return_param<'tcx>(
block_params_iter: &mut impl Iterator<Item = Value>,
) -> CPlace<'tcx> {
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode {
- PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => {
+ PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => {
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
(
super::make_local_place(
@@ -44,7 +44,7 @@ pub(super) fn codegen_return_param<'tcx>(
Some(RETURN_PLACE),
None,
&ret_param,
- fx.fn_abi.as_ref().unwrap().ret.mode,
+ &fx.fn_abi.as_ref().unwrap().ret.mode,
fx.fn_abi.as_ref().unwrap().ret.layout,
);
@@ -75,7 +75,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
- PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => (None, None),
+ PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => (None, None),
};
let call_inst = f(fx, return_ptr);
@@ -92,7 +92,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
ret_place
.write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout));
}
- PassMode::Cast(cast) => {
+ PassMode::Cast(ref cast, _) => {
let results =
fx.bcx.inst_results(call_inst).iter().copied().collect::<SmallVec<[Value; 2]>>();
let result =
@@ -131,7 +131,7 @@ pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
let (ret_val_a, ret_val_b) = place.to_cvalue(fx).load_scalar_pair(fx);
fx.bcx.ins().return_(&[ret_val_a, ret_val_b]);
}
- PassMode::Cast(cast) => {
+ PassMode::Cast(ref cast, _) => {
let place = fx.get_local_place(RETURN_PLACE);
let ret_val = place.to_cvalue(fx);
let ret_vals = super::pass_mode::to_casted_value(fx, ret_val, cast);
diff --git a/compiler/rustc_codegen_cranelift/src/analyze.rs b/compiler/rustc_codegen_cranelift/src/analyze.rs
index 35b89358b..0cbb9f3ec 100644
--- a/compiler/rustc_codegen_cranelift/src/analyze.rs
+++ b/compiler/rustc_codegen_cranelift/src/analyze.rs
@@ -26,7 +26,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec<Local, SsaKind> {
})
.collect::<IndexVec<Local, SsaKind>>();
- for bb in fx.mir.basic_blocks().iter() {
+ for bb in fx.mir.basic_blocks.iter() {
for stmt in bb.statements.iter() {
match &stmt.kind {
Assign(place_and_rval) => match &place_and_rval.1 {
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
index b4c790961..fb5313f17 100644
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ b/compiler/rustc_codegen_cranelift/src/archive.rs
@@ -38,6 +38,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
_lib_name: &str,
_dll_imports: &[rustc_session::cstore::DllImport],
_tmpdir: &Path,
+ _is_direct_dependency: bool,
) -> PathBuf {
bug!("creating dll imports is not supported");
}
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 122e103ff..399474d79 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -6,21 +6,43 @@ use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
-use indexmap::IndexSet;
-
use crate::constant::ConstantCx;
+use crate::debuginfo::FunctionDebugContext;
use crate::prelude::*;
use crate::pretty_clif::CommentWriter;
-pub(crate) fn codegen_fn<'tcx>(
- cx: &mut crate::CodegenCx<'tcx>,
+pub(crate) struct CodegenedFunction {
+ symbol_name: String,
+ func_id: FuncId,
+ func: Function,
+ clif_comments: CommentWriter,
+ func_debug_cx: Option<FunctionDebugContext>,
+}
+
+#[cfg_attr(not(feature = "jit"), allow(dead_code))]
+pub(crate) fn codegen_and_compile_fn<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ cx: &mut crate::CodegenCx,
+ cached_context: &mut Context,
module: &mut dyn Module,
instance: Instance<'tcx>,
) {
- let tcx = cx.tcx;
-
let _inst_guard =
crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name));
+
+ let cached_func = std::mem::replace(&mut cached_context.func, Function::new());
+ let codegened_func = codegen_fn(tcx, cx, cached_func, module, instance);
+
+ compile_fn(cx, cached_context, module, codegened_func);
+}
+
+pub(crate) fn codegen_fn<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ cx: &mut crate::CodegenCx,
+ cached_func: Function,
+ module: &mut dyn Module,
+ instance: Instance<'tcx>,
+) -> CodegenedFunction {
debug_assert!(!instance.substs.needs_infer());
let mir = tcx.instance_mir(instance.def);
@@ -34,15 +56,14 @@ pub(crate) fn codegen_fn<'tcx>(
});
// Declare function
- let symbol_name = tcx.symbol_name(instance);
+ let symbol_name = tcx.symbol_name(instance).name.to_string();
let sig = get_function_sig(tcx, module.isa().triple(), instance);
- let func_id = module.declare_function(symbol_name.name, Linkage::Local, &sig).unwrap();
-
- cx.cached_context.clear();
+ let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap();
// Make the FunctionBuilder
let mut func_ctx = FunctionBuilderContext::new();
- let mut func = std::mem::replace(&mut cx.cached_context.func, Function::new());
+ let mut func = cached_func;
+ func.clear();
func.name = ExternalName::user(0, func_id.as_u32());
func.signature = sig;
func.collect_debug_info();
@@ -52,13 +73,19 @@ pub(crate) fn codegen_fn<'tcx>(
// Predefine blocks
let start_block = bcx.create_block();
let block_map: IndexVec<BasicBlock, Block> =
- (0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
+ (0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect();
// Make FunctionCx
let target_config = module.target_config();
let pointer_type = target_config.pointer_type();
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
+ let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
+ Some(debug_context.define_function(tcx, &symbol_name, mir.span))
+ } else {
+ None
+ };
+
let mut fx = FunctionCx {
cx,
module,
@@ -66,6 +93,7 @@ pub(crate) fn codegen_fn<'tcx>(
target_config,
pointer_type,
constants_cx: ConstantCx::new(),
+ func_debug_cx,
instance,
symbol_name,
@@ -78,81 +106,48 @@ pub(crate) fn codegen_fn<'tcx>(
caller_location: None, // set by `codegen_fn_prelude`
clif_comments,
- source_info_set: indexmap::IndexSet::new(),
+ last_source_file: None,
next_ssa_var: 0,
};
- let arg_uninhabited = fx
- .mir
- .args_iter()
- .any(|arg| fx.layout_of(fx.monomorphize(fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
-
- if !crate::constant::check_constants(&mut fx) {
- fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
- fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
- crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted");
- } else if arg_uninhabited {
- fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
- fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
- fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
- } else {
- tcx.sess.time("codegen clif ir", || {
- tcx.sess
- .time("codegen prelude", || crate::abi::codegen_fn_prelude(&mut fx, start_block));
- codegen_fn_content(&mut fx);
- });
- }
+ tcx.sess.time("codegen clif ir", || codegen_fn_body(&mut fx, start_block));
// Recover all necessary data from fx, before accessing func will prevent future access to it.
- let instance = fx.instance;
+ let symbol_name = fx.symbol_name;
let clif_comments = fx.clif_comments;
- let source_info_set = fx.source_info_set;
- let local_map = fx.local_map;
+ let func_debug_cx = fx.func_debug_cx;
fx.constants_cx.finalize(fx.tcx, &mut *fx.module);
- crate::pretty_clif::write_clif_file(
- tcx,
- "unopt",
- module.isa(),
- instance,
- &func,
- &clif_comments,
- );
+ if cx.should_write_ir {
+ crate::pretty_clif::write_clif_file(
+ tcx.output_filenames(()),
+ &symbol_name,
+ "unopt",
+ module.isa(),
+ &func,
+ &clif_comments,
+ );
+ }
// Verify function
verify_func(tcx, &clif_comments, &func);
- compile_fn(
- cx,
- module,
- instance,
- symbol_name.name,
- func_id,
- func,
- clif_comments,
- source_info_set,
- local_map,
- );
+ CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }
}
-fn compile_fn<'tcx>(
- cx: &mut crate::CodegenCx<'tcx>,
+pub(crate) fn compile_fn(
+ cx: &mut crate::CodegenCx,
+ cached_context: &mut Context,
module: &mut dyn Module,
- instance: Instance<'tcx>,
- symbol_name: &str,
- func_id: FuncId,
- func: Function,
- mut clif_comments: CommentWriter,
- source_info_set: IndexSet<SourceInfo>,
- local_map: IndexVec<mir::Local, CPlace<'tcx>>,
+ codegened_func: CodegenedFunction,
) {
- let tcx = cx.tcx;
+ let clif_comments = codegened_func.clif_comments;
// Store function in context
- let context = &mut cx.cached_context;
+ let context = cached_context;
context.clear();
- context.func = func;
+ context.func = codegened_func.func;
// If the return block is not reachable, then the SSA builder may have inserted an `iconst.i128`
// instruction, which doesn't have an encoding.
@@ -164,17 +159,6 @@ fn compile_fn<'tcx>(
// invalidate it when it would change.
context.domtree.clear();
- // Perform rust specific optimizations
- tcx.sess.time("optimize clif ir", || {
- crate::optimize::optimize_function(
- tcx,
- module.isa(),
- instance,
- context,
- &mut clif_comments,
- );
- });
-
#[cfg(any())] // This is never true
let _clif_guard = {
use std::fmt::Write;
@@ -203,46 +187,44 @@ fn compile_fn<'tcx>(
};
// Define function
- tcx.sess.time("define function", || {
- context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
- module.define_function(func_id, context).unwrap();
+ cx.profiler.verbose_generic_activity("define function").run(|| {
+ context.want_disasm = cx.should_write_ir;
+ module.define_function(codegened_func.func_id, context).unwrap();
});
- // Write optimized function to file for debugging
- crate::pretty_clif::write_clif_file(
- tcx,
- "opt",
- module.isa(),
- instance,
- &context.func,
- &clif_comments,
- );
+ if cx.should_write_ir {
+ // Write optimized function to file for debugging
+ crate::pretty_clif::write_clif_file(
+ &cx.output_filenames,
+ &codegened_func.symbol_name,
+ "opt",
+ module.isa(),
+ &context.func,
+ &clif_comments,
+ );
- if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
- crate::pretty_clif::write_ir_file(
- tcx,
- || format!("{}.vcode", tcx.symbol_name(instance).name),
- |file| file.write_all(disasm.as_bytes()),
- )
+ if let Some(disasm) = &context.compiled_code().unwrap().disasm {
+ crate::pretty_clif::write_ir_file(
+ &cx.output_filenames,
+ &format!("{}.vcode", codegened_func.symbol_name),
+ |file| file.write_all(disasm.as_bytes()),
+ )
+ }
}
// Define debuginfo for function
let isa = module.isa();
let debug_context = &mut cx.debug_context;
let unwind_context = &mut cx.unwind_context;
- tcx.sess.time("generate debug info", || {
+ cx.profiler.verbose_generic_activity("generate debug info").run(|| {
if let Some(debug_context) = debug_context {
- debug_context.define_function(
- instance,
- func_id,
- symbol_name,
- isa,
+ codegened_func.func_debug_cx.unwrap().finalize(
+ debug_context,
+ codegened_func.func_id,
context,
- &source_info_set,
- local_map,
);
}
- unwind_context.add_function(func_id, &context, isa);
+ unwind_context.add_function(codegened_func.func_id, &context, isa);
});
}
@@ -268,8 +250,28 @@ pub(crate) fn verify_func(
});
}
-fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
- for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() {
+fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
+ if !crate::constant::check_constants(fx) {
+ fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
+ fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
+ // compilation should have been aborted
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+ return;
+ }
+
+ let arg_uninhabited = fx
+ .mir
+ .args_iter()
+ .any(|arg| fx.layout_of(fx.monomorphize(fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
+ if arg_uninhabited {
+ fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
+ fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+ return;
+ }
+ fx.tcx.sess.time("codegen prelude", || crate::abi::codegen_fn_prelude(fx, start_block));
+
+ for (bb, bb_data) in fx.mir.basic_blocks.iter_enumerated() {
let block = fx.get_block(bb);
fx.bcx.switch_to_block(block);
@@ -457,17 +459,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
template,
operands,
*options,
+ *destination,
);
-
- match *destination {
- Some(destination) => {
- let destination_block = fx.get_block(destination);
- fx.bcx.ins().jump(destination_block, &[]);
- }
- None => {
- fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
- }
- }
}
TerminatorKind::Resume | TerminatorKind::Abort => {
// FIXME implement unwinding
@@ -708,12 +701,14 @@ fn codegen_stmt<'tcx>(
let operand = codegen_operand(fx, operand);
operand.unsize_value(fx, lval);
}
+ Rvalue::Cast(CastKind::DynStar, _, _) => {
+ // FIXME(dyn-star)
+ unimplemented!()
+ }
Rvalue::Discriminant(place) => {
let place = codegen_place(fx, place);
let value = place.to_cvalue(fx);
- let discr =
- crate::discriminant::codegen_get_discriminant(fx, value, dest_layout);
- lval.write_cvalue(fx, discr);
+ crate::discriminant::codegen_get_discriminant(fx, lval, value, dest_layout);
}
Rvalue::Repeat(ref operand, times) => {
let operand = codegen_operand(fx, operand);
@@ -803,20 +798,31 @@ fn codegen_stmt<'tcx>(
| StatementKind::AscribeUserType(..) => {}
StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"),
- StatementKind::CopyNonOverlapping(inner) => {
- let dst = codegen_operand(fx, &inner.dst);
- let pointee = dst
- .layout()
- .pointee_info_at(fx, rustc_target::abi::Size::ZERO)
- .expect("Expected pointer");
- let dst = dst.load_scalar(fx);
- let src = codegen_operand(fx, &inner.src).load_scalar(fx);
- let count = codegen_operand(fx, &inner.count).load_scalar(fx);
- let elem_size: u64 = pointee.size.bytes();
- let bytes =
- if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
- fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
- }
+ StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic {
+ // We ignore `assume` intrinsics, they are only useful for optimizations
+ NonDivergingIntrinsic::Assume(_) => {}
+ NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
+ src,
+ dst,
+ count,
+ }) => {
+ let dst = codegen_operand(fx, dst);
+ let pointee = dst
+ .layout()
+ .pointee_info_at(fx, rustc_target::abi::Size::ZERO)
+ .expect("Expected pointer");
+ let dst = dst.load_scalar(fx);
+ let src = codegen_operand(fx, src).load_scalar(fx);
+ let count = codegen_operand(fx, count).load_scalar(fx);
+ let elem_size: u64 = pointee.size.bytes();
+ let bytes = if elem_size != 1 {
+ fx.bcx.ins().imul_imm(count, elem_size as i64)
+ } else {
+ count
+ };
+ fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
+ }
+ },
}
}
@@ -934,8 +940,11 @@ pub(crate) fn codegen_panic_inner<'tcx>(
args: &[Value],
span: Span,
) {
- let def_id =
- fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s));
+ let def_id = fx
+ .tcx
+ .lang_items()
+ .require(lang_item)
+ .unwrap_or_else(|e| fx.tcx.sess.span_fatal(span, e.to_string()));
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
let symbol_name = fx.tcx.symbol_name(instance).name;
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index f9dc1b516..589594465 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -1,14 +1,18 @@
use cranelift_codegen::isa::TargetFrontendConfig;
+use gimli::write::FileId;
+
+use rustc_data_structures::sync::Lrc;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
};
-use rustc_middle::ty::SymbolName;
+use rustc_span::SourceFile;
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Integer, Primitive};
use rustc_target::spec::{HasTargetSpec, Target};
use crate::constant::ConstantCx;
+use crate::debuginfo::FunctionDebugContext;
use crate::prelude::*;
pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type {
@@ -74,7 +78,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
_ => unreachable!(),
};
- match scalar_to_clif_type(tcx, element).by(u16::try_from(count).unwrap()) {
+ match scalar_to_clif_type(tcx, element).by(u32::try_from(count).unwrap()) {
// Cranelift currently only implements icmp for 128bit vectors.
Some(vector_ty) if vector_ty.bits() == 128 => vector_ty,
_ => return None,
@@ -232,15 +236,16 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool {
}
pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
- pub(crate) cx: &'clif mut crate::CodegenCx<'tcx>,
+ pub(crate) cx: &'clif mut crate::CodegenCx,
pub(crate) module: &'m mut dyn Module,
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) target_config: TargetFrontendConfig, // Cached from module
pub(crate) pointer_type: Type, // Cached from module
pub(crate) constants_cx: ConstantCx,
+ pub(crate) func_debug_cx: Option<FunctionDebugContext>,
pub(crate) instance: Instance<'tcx>,
- pub(crate) symbol_name: SymbolName<'tcx>,
+ pub(crate) symbol_name: String,
pub(crate) mir: &'tcx Body<'tcx>,
pub(crate) fn_abi: Option<&'tcx FnAbi<'tcx, Ty<'tcx>>>,
@@ -252,7 +257,11 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
pub(crate) caller_location: Option<CValue<'tcx>>,
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
- pub(crate) source_info_set: indexmap::IndexSet<SourceInfo>,
+
+ /// Last accessed source file and it's debuginfo file id.
+ ///
+ /// For optimization purposes only
+ pub(crate) last_source_file: Option<(Lrc<SourceFile>, FileId)>,
/// This should only be accessed by `CPlace::new_var`.
pub(crate) next_ssa_var: u32,
@@ -336,8 +345,31 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
}
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
- let (index, _) = self.source_info_set.insert_full(source_info);
- self.bcx.set_srcloc(SourceLoc::new(index as u32));
+ if let Some(debug_context) = &mut self.cx.debug_context {
+ let (file, line, column) =
+ DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span);
+
+ // add_source_file is very slow.
+ // Optimize for the common case of the current file not being changed.
+ let mut cached_file_id = None;
+ if let Some((ref last_source_file, last_file_id)) = self.last_source_file {
+ // If the allocations are not equal, the files may still be equal, but that
+ // doesn't matter, as this is just an optimization.
+ if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) {
+ cached_file_id = Some(last_file_id);
+ }
+ }
+
+ let file_id = if let Some(file_id) = cached_file_id {
+ file_id
+ } else {
+ debug_context.add_source_file(&file)
+ };
+
+ let source_loc =
+ self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column);
+ self.bcx.set_srcloc(source_loc);
+ }
}
// Note: must be kept in sync with get_caller_location from cg_ssa
diff --git a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs
new file mode 100644
index 000000000..dfde97920
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs
@@ -0,0 +1,168 @@
+use std::sync::{Arc, Condvar, Mutex};
+
+use rustc_session::Session;
+
+use jobserver::HelperThread;
+
+// FIXME don't panic when a worker thread panics
+
+pub(super) struct ConcurrencyLimiter {
+ helper_thread: Option<HelperThread>,
+ state: Arc<Mutex<state::ConcurrencyLimiterState>>,
+ available_token_condvar: Arc<Condvar>,
+}
+
+impl ConcurrencyLimiter {
+ pub(super) fn new(sess: &Session, pending_jobs: usize) -> Self {
+ let state = Arc::new(Mutex::new(state::ConcurrencyLimiterState::new(pending_jobs)));
+ let available_token_condvar = Arc::new(Condvar::new());
+
+ let state_helper = state.clone();
+ let available_token_condvar_helper = available_token_condvar.clone();
+ let helper_thread = sess
+ .jobserver
+ .clone()
+ .into_helper_thread(move |token| {
+ let mut state = state_helper.lock().unwrap();
+ state.add_new_token(token.unwrap());
+ available_token_condvar_helper.notify_one();
+ })
+ .unwrap();
+ ConcurrencyLimiter {
+ helper_thread: Some(helper_thread),
+ state,
+ available_token_condvar: Arc::new(Condvar::new()),
+ }
+ }
+
+ pub(super) fn acquire(&mut self) -> ConcurrencyLimiterToken {
+ let mut state = self.state.lock().unwrap();
+ loop {
+ state.assert_invariants();
+
+ if state.try_start_job() {
+ return ConcurrencyLimiterToken {
+ state: self.state.clone(),
+ available_token_condvar: self.available_token_condvar.clone(),
+ };
+ }
+
+ self.helper_thread.as_mut().unwrap().request_token();
+ state = self.available_token_condvar.wait(state).unwrap();
+ }
+ }
+
+ pub(super) fn job_already_done(&mut self) {
+ let mut state = self.state.lock().unwrap();
+ state.job_already_done();
+ }
+}
+
+impl Drop for ConcurrencyLimiter {
+ fn drop(&mut self) {
+ //
+ self.helper_thread.take();
+
+ // Assert that all jobs have finished
+ let state = Mutex::get_mut(Arc::get_mut(&mut self.state).unwrap()).unwrap();
+ state.assert_done();
+ }
+}
+
+#[derive(Debug)]
+pub(super) struct ConcurrencyLimiterToken {
+ state: Arc<Mutex<state::ConcurrencyLimiterState>>,
+ available_token_condvar: Arc<Condvar>,
+}
+
+impl Drop for ConcurrencyLimiterToken {
+ fn drop(&mut self) {
+ let mut state = self.state.lock().unwrap();
+ state.job_finished();
+ self.available_token_condvar.notify_one();
+ }
+}
+
+mod state {
+ use jobserver::Acquired;
+
+ #[derive(Debug)]
+ pub(super) struct ConcurrencyLimiterState {
+ pending_jobs: usize,
+ active_jobs: usize,
+
+ // None is used to represent the implicit token, Some to represent explicit tokens
+ tokens: Vec<Option<Acquired>>,
+ }
+
+ impl ConcurrencyLimiterState {
+ pub(super) fn new(pending_jobs: usize) -> Self {
+ ConcurrencyLimiterState { pending_jobs, active_jobs: 0, tokens: vec![None] }
+ }
+
+ pub(super) fn assert_invariants(&self) {
+ // There must be no excess active jobs
+ assert!(self.active_jobs <= self.pending_jobs);
+
+ // There may not be more active jobs than there are tokens
+ assert!(self.active_jobs <= self.tokens.len());
+ }
+
+ pub(super) fn assert_done(&self) {
+ assert_eq!(self.pending_jobs, 0);
+ assert_eq!(self.active_jobs, 0);
+ }
+
+ pub(super) fn add_new_token(&mut self, token: Acquired) {
+ self.tokens.push(Some(token));
+ self.drop_excess_capacity();
+ }
+
+ pub(super) fn try_start_job(&mut self) -> bool {
+ if self.active_jobs < self.tokens.len() {
+ // Using existing token
+ self.job_started();
+ return true;
+ }
+
+ false
+ }
+
+ pub(super) fn job_started(&mut self) {
+ self.assert_invariants();
+ self.active_jobs += 1;
+ self.drop_excess_capacity();
+ self.assert_invariants();
+ }
+
+ pub(super) fn job_finished(&mut self) {
+ self.assert_invariants();
+ self.pending_jobs -= 1;
+ self.active_jobs -= 1;
+ self.assert_invariants();
+ self.drop_excess_capacity();
+ self.assert_invariants();
+ }
+
+ pub(super) fn job_already_done(&mut self) {
+ self.assert_invariants();
+ self.pending_jobs -= 1;
+ self.assert_invariants();
+ self.drop_excess_capacity();
+ self.assert_invariants();
+ }
+
+ fn drop_excess_capacity(&mut self) {
+ self.assert_invariants();
+
+ // Drop all tokens that can never be used anymore
+ self.tokens.truncate(std::cmp::max(self.pending_jobs, 1));
+
+ // Keep some excess tokens to satisfy requests faster
+ const MAX_EXTRA_CAPACITY: usize = 2;
+ self.tokens.truncate(std::cmp::max(self.active_jobs + MAX_EXTRA_CAPACITY, 1));
+
+ self.assert_invariants();
+ }
+ }
+}
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index 7f7fd0e9c..6b4ed9b9d 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -41,36 +41,30 @@ impl ConstantCx {
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
let mut all_constants_ok = true;
for constant in &fx.mir.required_consts {
- let const_ = match fx.monomorphize(constant.literal) {
- ConstantKind::Ty(ct) => ct,
+ let unevaluated = match fx.monomorphize(constant.literal) {
+ ConstantKind::Ty(ct) => match ct.kind() {
+ ConstKind::Unevaluated(uv) => uv.expand(),
+ ConstKind::Value(_) => continue,
+ ConstKind::Param(_)
+ | ConstKind::Infer(_)
+ | ConstKind::Bound(_, _)
+ | ConstKind::Placeholder(_)
+ | ConstKind::Error(_) => unreachable!("{:?}", ct),
+ },
+ ConstantKind::Unevaluated(uv, _) => uv,
ConstantKind::Val(..) => continue,
};
- match const_.kind() {
- ConstKind::Value(_) => {}
- ConstKind::Unevaluated(unevaluated) => {
- if let Err(err) =
- fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
- {
- all_constants_ok = false;
- match err {
- ErrorHandled::Reported(_) | ErrorHandled::Linted => {
- fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
- }
- ErrorHandled::TooGeneric => {
- span_bug!(
- constant.span,
- "codgen encountered polymorphic constant: {:?}",
- err
- );
- }
- }
+
+ if let Err(err) = fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
+ all_constants_ok = false;
+ match err {
+ ErrorHandled::Reported(_) | ErrorHandled::Linted => {
+ fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
+ }
+ ErrorHandled::TooGeneric => {
+ span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
}
}
- ConstKind::Param(_)
- | ConstKind::Infer(_)
- | ConstKind::Bound(_, _)
- | ConstKind::Placeholder(_)
- | ConstKind::Error(_) => unreachable!("{:?}", const_),
}
}
all_constants_ok
@@ -122,36 +116,28 @@ pub(crate) fn codegen_constant<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
constant: &Constant<'tcx>,
) -> CValue<'tcx> {
- let const_ = match fx.monomorphize(constant.literal) {
- ConstantKind::Ty(ct) => ct,
- ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty),
- };
- 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 })
+ let (const_val, ty) = match fx.monomorphize(constant.literal) {
+ ConstantKind::Ty(const_) => unreachable!("{:?}", const_),
+ ConstantKind::Unevaluated(ty::Unevaluated { def, substs, promoted }, ty)
if fx.tcx.is_static(def.did) =>
{
assert!(substs.is_empty());
assert!(promoted.is_none());
- return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty())).to_cvalue(fx);
+ return codegen_static_ref(fx, def.did, fx.layout_of(ty)).to_cvalue(fx);
}
- ConstKind::Unevaluated(unevaluated) => {
+ ConstantKind::Unevaluated(unevaluated, ty) => {
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
- Ok(const_val) => const_val,
+ Ok(const_val) => (const_val, ty),
Err(_) => {
span_bug!(constant.span, "erroneous constant not captured by required_consts");
}
}
}
- ConstKind::Param(_)
- | ConstKind::Infer(_)
- | ConstKind::Bound(_, _)
- | ConstKind::Placeholder(_)
- | ConstKind::Error(_) => unreachable!("{:?}", const_),
+ ConstantKind::Val(val, ty) => (val, ty),
};
- codegen_const_value(fx, const_val, const_.ty())
+ codegen_const_value(fx, const_val, ty)
}
pub(crate) fn codegen_const_value<'tcx>(
@@ -430,7 +416,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
data_ctx.define(bytes.into_boxed_slice());
- for &(offset, alloc_id) in alloc.relocations().iter() {
+ for &(offset, alloc_id) in alloc.provenance().iter() {
let addend = {
let endianness = tcx.data_layout.endian;
let offset = offset.bytes() as usize;
@@ -496,6 +482,9 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
.eval_for_mir(fx.tcx, ParamEnv::reveal_all())
.try_to_value(fx.tcx),
ConstantKind::Val(val, _) => Some(val),
+ ConstantKind::Unevaluated(uv, _) => {
+ fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).ok()
+ }
},
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
// inside a temporary before being passed to the intrinsic requiring the const argument.
@@ -505,7 +494,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
return None;
}
let mut computed_const_val = None;
- for bb_data in fx.mir.basic_blocks() {
+ for bb_data in fx.mir.basic_blocks.iter() {
for stmt in &bb_data.statements {
match &stmt.kind {
StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => {
@@ -536,9 +525,11 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
{
return None;
}
- StatementKind::CopyNonOverlapping(_) => {
- return None;
- } // conservative handling
+ StatementKind::Intrinsic(ref intrinsic) => match **intrinsic {
+ NonDivergingIntrinsic::CopyNonOverlapping(..) => return None,
+ NonDivergingIntrinsic::Assume(..) => {}
+ },
+ // conservative handling
StatementKind::Assign(_)
| StatementKind::FakeRead(_)
| StatementKind::SetDiscriminant { .. }
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs
index 589910ede..9583cd2ec 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs
@@ -9,7 +9,7 @@ use gimli::{RunTimeEndian, SectionId};
use super::object::WriteDebugInfo;
use super::DebugContext;
-impl DebugContext<'_> {
+impl DebugContext {
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
let root = self.dwarf.unit.root();
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
index bbcb95913..463de6a91 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
@@ -3,8 +3,10 @@
use std::ffi::OsStr;
use std::path::{Component, Path};
+use crate::debuginfo::FunctionDebugContext;
use crate::prelude::*;
+use rustc_data_structures::sync::Lrc;
use rustc_span::{
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
};
@@ -14,7 +16,6 @@ use cranelift_codegen::MachSrcLoc;
use gimli::write::{
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
- UnitEntryId,
};
// OPTIMIZATION: It is cheaper to do this in one pass than using `.parent()` and `.file_name()`.
@@ -47,9 +48,9 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
}
}
-pub(crate) const MD5_LEN: usize = 16;
+const MD5_LEN: usize = 16;
-pub(crate) fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
+fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
if hash.kind == SourceFileHashAlgorithm::Md5 {
let mut buf = [0u8; MD5_LEN];
buf.copy_from_slice(hash.hash_bytes());
@@ -59,160 +60,132 @@ pub(crate) fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
}
}
-fn line_program_add_file(
- line_program: &mut LineProgram,
- line_strings: &mut LineStringTable,
- file: &SourceFile,
-) -> FileId {
- match &file.name {
- FileName::Real(path) => {
- let (dir_path, file_name) = split_path_dir_and_file(path.remapped_path_if_available());
- let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
- let file_name = osstr_as_utf8_bytes(file_name);
-
- let dir_id = if !dir_name.is_empty() {
- let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
- line_program.add_directory(dir_name)
- } else {
- line_program.default_directory()
- };
- let file_name = LineString::new(file_name, line_program.encoding(), line_strings);
+impl DebugContext {
+ pub(crate) fn get_span_loc(
+ tcx: TyCtxt<'_>,
+ function_span: Span,
+ span: Span,
+ ) -> (Lrc<SourceFile>, u64, u64) {
+ // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
+ // In order to have a good line stepping behavior in debugger, we overwrite debug
+ // locations of macro expansions with that of the outermost expansion site (when the macro is
+ // annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
+ let span = if tcx.should_collapse_debuginfo(span) {
+ span
+ } else {
+ // Walk up the macro expansion chain until we reach a non-expanded span.
+ // We also stop at the function body level because no line stepping can occur
+ // at the level above that.
+ rustc_span::hygiene::walk_chain(span, function_span.ctxt())
+ };
- let info = make_file_info(file.src_hash);
+ match tcx.sess.source_map().lookup_line(span.lo()) {
+ Ok(SourceFileAndLine { sf: file, line }) => {
+ let line_pos = file.line_begin_pos(span.lo());
- line_program.file_has_md5 &= info.is_some();
- line_program.add_file(file_name, dir_id, info)
+ (
+ file,
+ u64::try_from(line).unwrap() + 1,
+ u64::from((span.lo() - line_pos).to_u32()) + 1,
+ )
+ }
+ Err(file) => (file, 0, 0),
}
- // FIXME give more appropriate file names
- filename => {
- let dir_id = line_program.default_directory();
- let dummy_file_name = LineString::new(
- filename.prefer_remapped().to_string().into_bytes(),
- line_program.encoding(),
- line_strings,
- );
- line_program.add_file(dummy_file_name, dir_id, None)
+ }
+
+ pub(crate) fn add_source_file(&mut self, source_file: &SourceFile) -> FileId {
+ let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program;
+ let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings;
+
+ match &source_file.name {
+ FileName::Real(path) => {
+ let (dir_path, file_name) =
+ split_path_dir_and_file(path.remapped_path_if_available());
+ let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
+ let file_name = osstr_as_utf8_bytes(file_name);
+
+ let dir_id = if !dir_name.is_empty() {
+ let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
+ line_program.add_directory(dir_name)
+ } else {
+ line_program.default_directory()
+ };
+ let file_name = LineString::new(file_name, line_program.encoding(), line_strings);
+
+ let info = make_file_info(source_file.src_hash);
+
+ line_program.file_has_md5 &= info.is_some();
+ line_program.add_file(file_name, dir_id, info)
+ }
+ // FIXME give more appropriate file names
+ filename => {
+ let dir_id = line_program.default_directory();
+ let dummy_file_name = LineString::new(
+ filename.prefer_remapped().to_string().into_bytes(),
+ line_program.encoding(),
+ line_strings,
+ );
+ line_program.add_file(dummy_file_name, dir_id, None)
+ }
}
}
}
-impl<'tcx> DebugContext<'tcx> {
- pub(super) fn emit_location(&mut self, entry_id: UnitEntryId, span: Span) {
- let loc = self.tcx.sess.source_map().lookup_char_pos(span.lo());
-
- let file_id = line_program_add_file(
- &mut self.dwarf.unit.line_program,
- &mut self.dwarf.line_strings,
- &loc.file,
- );
-
- let entry = self.dwarf.unit.get_mut(entry_id);
-
- entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
- entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(loc.line as u64));
- entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(loc.col.to_usize() as u64));
+impl FunctionDebugContext {
+ pub(crate) fn add_dbg_loc(&mut self, file_id: FileId, line: u64, column: u64) -> SourceLoc {
+ let (index, _) = self.source_loc_set.insert_full((file_id, line, column));
+ SourceLoc::new(u32::try_from(index).unwrap())
}
pub(super) fn create_debug_lines(
&mut self,
+ debug_context: &mut DebugContext,
symbol: usize,
- entry_id: UnitEntryId,
context: &Context,
- function_span: Span,
- source_info_set: &indexmap::IndexSet<SourceInfo>,
) -> CodeOffset {
- let tcx = self.tcx;
- let line_program = &mut self.dwarf.unit.line_program;
-
- let line_strings = &mut self.dwarf.line_strings;
- let mut last_span = None;
- let mut last_file = None;
- let mut create_row_for_span = |line_program: &mut LineProgram, span: Span| {
- if let Some(last_span) = last_span {
- if span == last_span {
- line_program.generate_row();
- return;
- }
- }
- last_span = Some(span);
-
- // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
- // In order to have a good line stepping behavior in debugger, we overwrite debug
- // locations of macro expansions with that of the outermost expansion site
- // (unless the crate is being compiled with `-Z debug-macros`).
- let span = if !span.from_expansion() || tcx.sess.opts.unstable_opts.debug_macros {
- span
- } else {
- // Walk up the macro expansion chain until we reach a non-expanded span.
- // We also stop at the function body level because no line stepping can occur
- // at the level above that.
- rustc_span::hygiene::walk_chain(span, function_span.ctxt())
+ let create_row_for_span =
+ |debug_context: &mut DebugContext, source_loc: (FileId, u64, u64)| {
+ let (file_id, line, col) = source_loc;
+
+ debug_context.dwarf.unit.line_program.row().file = file_id;
+ debug_context.dwarf.unit.line_program.row().line = line;
+ debug_context.dwarf.unit.line_program.row().column = col;
+ debug_context.dwarf.unit.line_program.generate_row();
};
- let (file, line, col) = match tcx.sess.source_map().lookup_line(span.lo()) {
- Ok(SourceFileAndLine { sf: file, line }) => {
- let line_pos = file.line_begin_pos(span.lo());
-
- (
- file,
- u64::try_from(line).unwrap() + 1,
- u64::from((span.lo() - line_pos).to_u32()) + 1,
- )
- }
- Err(file) => (file, 0, 0),
- };
-
- // line_program_add_file is very slow.
- // Optimize for the common case of the current file not being changed.
- let current_file_changed = if let Some(last_file) = &last_file {
- // If the allocations are not equal, then the files may still be equal, but that
- // is not a problem, as this is just an optimization.
- !rustc_data_structures::sync::Lrc::ptr_eq(last_file, &file)
- } else {
- true
- };
- if current_file_changed {
- let file_id = line_program_add_file(line_program, line_strings, &file);
- line_program.row().file = file_id;
- last_file = Some(file);
- }
-
- line_program.row().line = line;
- line_program.row().column = col;
- line_program.generate_row();
- };
-
- line_program.begin_sequence(Some(Address::Symbol { symbol, addend: 0 }));
+ debug_context
+ .dwarf
+ .unit
+ .line_program
+ .begin_sequence(Some(Address::Symbol { symbol, addend: 0 }));
let mut func_end = 0;
- let mcr = context.mach_compile_result.as_ref().unwrap();
+ let mcr = context.compiled_code().unwrap();
for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() {
- line_program.row().address_offset = u64::from(start);
+ debug_context.dwarf.unit.line_program.row().address_offset = u64::from(start);
if !loc.is_default() {
- let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap();
- create_row_for_span(line_program, source_info.span);
+ let source_loc = *self.source_loc_set.get_index(loc.bits() as usize).unwrap();
+ create_row_for_span(debug_context, source_loc);
} else {
- create_row_for_span(line_program, function_span);
+ create_row_for_span(debug_context, self.function_source_loc);
}
func_end = end;
}
- line_program.end_sequence(u64::from(func_end));
+ debug_context.dwarf.unit.line_program.end_sequence(u64::from(func_end));
let func_end = mcr.buffer.total_size();
assert_ne!(func_end, 0);
- let entry = self.dwarf.unit.get_mut(entry_id);
+ let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
entry.set(
gimli::DW_AT_low_pc,
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
);
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
- self.emit_location(entry_id, function_span);
-
func_end
}
}
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
index 693092ba5..c55db2017 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
@@ -7,35 +7,34 @@ mod unwind;
use crate::prelude::*;
-use rustc_index::vec::IndexVec;
-
-use cranelift_codegen::entity::EntityRef;
-use cranelift_codegen::ir::{Endianness, LabelValueLoc, ValueLabel};
+use cranelift_codegen::ir::Endianness;
use cranelift_codegen::isa::TargetIsa;
-use cranelift_codegen::ValueLocRange;
use gimli::write::{
- Address, AttributeValue, DwarfUnit, Expression, LineProgram, LineString, Location,
- LocationList, Range, RangeList, UnitEntryId,
+ Address, AttributeValue, DwarfUnit, FileId, LineProgram, LineString, Range, RangeList,
+ UnitEntryId,
};
-use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
+use gimli::{Encoding, Format, LineEncoding, RunTimeEndian};
+use indexmap::IndexSet;
pub(crate) use emit::{DebugReloc, DebugRelocName};
pub(crate) use unwind::UnwindContext;
-pub(crate) struct DebugContext<'tcx> {
- tcx: TyCtxt<'tcx>,
-
+pub(crate) struct DebugContext {
endian: RunTimeEndian,
dwarf: DwarfUnit,
unit_range_list: RangeList,
+}
- types: FxHashMap<Ty<'tcx>, UnitEntryId>,
+pub(crate) struct FunctionDebugContext {
+ entry_id: UnitEntryId,
+ function_source_loc: (FileId, u64, u64),
+ source_loc_set: indexmap::IndexSet<(FileId, u64, u64)>,
}
-impl<'tcx> DebugContext<'tcx> {
- pub(crate) fn new(tcx: TyCtxt<'tcx>, isa: &dyn TargetIsa) -> Self {
+impl DebugContext {
+ pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa) -> Self {
let encoding = Encoding {
format: Format::Dwarf32,
// FIXME this should be configurable
@@ -101,127 +100,18 @@ impl<'tcx> DebugContext<'tcx> {
root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0)));
}
- DebugContext {
- tcx,
-
- endian,
-
- dwarf,
- unit_range_list: RangeList(Vec::new()),
-
- types: FxHashMap::default(),
- }
- }
-
- fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId {
- if let Some(type_id) = self.types.get(&ty) {
- return *type_id;
- }
-
- let new_entry = |dwarf: &mut DwarfUnit, tag| dwarf.unit.add(dwarf.unit.root(), tag);
-
- let primitive = |dwarf: &mut DwarfUnit, ate| {
- let type_id = new_entry(dwarf, gimli::DW_TAG_base_type);
- let type_entry = dwarf.unit.get_mut(type_id);
- type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(ate));
- type_id
- };
-
- let name = format!("{}", ty);
- let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap();
-
- let type_id = match ty.kind() {
- ty::Bool => primitive(&mut self.dwarf, gimli::DW_ATE_boolean),
- ty::Char => primitive(&mut self.dwarf, gimli::DW_ATE_UTF),
- ty::Uint(_) => primitive(&mut self.dwarf, gimli::DW_ATE_unsigned),
- ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed),
- ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float),
- ty::Ref(_, pointee_ty, _mutbl)
- | ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl: _mutbl }) => {
- let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type);
-
- // Ensure that type is inserted before recursing to avoid duplicates
- self.types.insert(ty, type_id);
-
- let pointee = self.dwarf_ty(*pointee_ty);
-
- let type_entry = self.dwarf.unit.get_mut(type_id);
-
- //type_entry.set(gimli::DW_AT_mutable, AttributeValue::Flag(mutbl == rustc_hir::Mutability::Mut));
- type_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(pointee));
-
- type_id
- }
- ty::Adt(adt_def, _substs) if adt_def.is_struct() && !layout.is_unsized() => {
- let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type);
-
- // Ensure that type is inserted before recursing to avoid duplicates
- self.types.insert(ty, type_id);
-
- let variant = adt_def.non_enum_variant();
-
- for (field_idx, field_def) in variant.fields.iter().enumerate() {
- let field_offset = layout.fields.offset(field_idx);
- let field_layout = layout.field(
- &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
- field_idx,
- );
-
- let field_type = self.dwarf_ty(field_layout.ty);
-
- let field_id = self.dwarf.unit.add(type_id, gimli::DW_TAG_member);
- let field_entry = self.dwarf.unit.get_mut(field_id);
-
- field_entry.set(
- gimli::DW_AT_name,
- AttributeValue::String(field_def.name.as_str().to_string().into_bytes()),
- );
- field_entry.set(
- gimli::DW_AT_data_member_location,
- AttributeValue::Udata(field_offset.bytes()),
- );
- field_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(field_type));
- }
-
- type_id
- }
- _ => new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type),
- };
-
- let type_entry = self.dwarf.unit.get_mut(type_id);
-
- type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
- type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
-
- self.types.insert(ty, type_id);
-
- type_id
- }
-
- fn define_local(&mut self, scope: UnitEntryId, name: String, ty: Ty<'tcx>) -> UnitEntryId {
- let dw_ty = self.dwarf_ty(ty);
-
- let var_id = self.dwarf.unit.add(scope, gimli::DW_TAG_variable);
- let var_entry = self.dwarf.unit.get_mut(var_id);
-
- var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
- var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
-
- var_id
+ DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()) }
}
pub(crate) fn define_function(
&mut self,
- instance: Instance<'tcx>,
- func_id: FuncId,
+ tcx: TyCtxt<'_>,
name: &str,
- isa: &dyn TargetIsa,
- context: &Context,
- source_info_set: &indexmap::IndexSet<SourceInfo>,
- local_map: IndexVec<mir::Local, CPlace<'tcx>>,
- ) {
- let symbol = func_id.as_u32() as usize;
- let mir = self.tcx.instance_mir(instance.def);
+ function_span: Span,
+ ) -> FunctionDebugContext {
+ let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span);
+
+ let file_id = self.add_source_file(&file);
// FIXME: add to appropriate scope instead of root
let scope = self.dwarf.unit.root();
@@ -233,14 +123,35 @@ impl<'tcx> DebugContext<'tcx> {
entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id));
- let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set);
+ entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
+ entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line));
+ entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(column));
- self.unit_range_list.0.push(Range::StartLength {
+ FunctionDebugContext {
+ entry_id,
+ function_source_loc: (file_id, line, column),
+ source_loc_set: IndexSet::new(),
+ }
+ }
+}
+
+impl FunctionDebugContext {
+ pub(crate) fn finalize(
+ mut self,
+ debug_context: &mut DebugContext,
+ func_id: FuncId,
+ context: &Context,
+ ) {
+ let symbol = func_id.as_u32() as usize;
+
+ let end = self.create_debug_lines(debug_context, symbol, context);
+
+ debug_context.unit_range_list.0.push(Range::StartLength {
begin: Address::Symbol { symbol, addend: 0 },
length: u64::from(end),
});
- let func_entry = self.dwarf.unit.get_mut(entry_id);
+ let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id);
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
func_entry.set(
gimli::DW_AT_low_pc,
@@ -248,110 +159,5 @@ impl<'tcx> DebugContext<'tcx> {
);
// Using Udata for DW_AT_high_pc requires at least DWARF4
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
-
- // FIXME make it more reliable and implement scopes before re-enabling this.
- if false {
- let value_labels_ranges = std::collections::HashMap::new(); // FIXME
-
- for (local, _local_decl) in mir.local_decls.iter_enumerated() {
- let ty = self.tcx.subst_and_normalize_erasing_regions(
- instance.substs,
- ty::ParamEnv::reveal_all(),
- mir.local_decls[local].ty,
- );
- let var_id = self.define_local(entry_id, format!("{:?}", local), ty);
-
- let location = place_location(
- self,
- isa,
- symbol,
- &local_map,
- &value_labels_ranges,
- Place { local, projection: ty::List::empty() },
- );
-
- let var_entry = self.dwarf.unit.get_mut(var_id);
- var_entry.set(gimli::DW_AT_location, location);
- }
- }
-
- // FIXME create locals for all entries in mir.var_debug_info
- }
-}
-
-fn place_location<'tcx>(
- debug_context: &mut DebugContext<'tcx>,
- isa: &dyn TargetIsa,
- symbol: usize,
- local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
- #[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
- ValueLabel,
- Vec<ValueLocRange>,
- >,
- place: Place<'tcx>,
-) -> AttributeValue {
- assert!(place.projection.is_empty()); // FIXME implement them
-
- match local_map[place.local].inner() {
- CPlaceInner::Var(_local, var) => {
- let value_label = cranelift_codegen::ir::ValueLabel::new(var.index());
- if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) {
- let loc_list = LocationList(
- value_loc_ranges
- .iter()
- .map(|value_loc_range| Location::StartEnd {
- begin: Address::Symbol {
- symbol,
- addend: i64::from(value_loc_range.start),
- },
- end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
- data: translate_loc(isa, value_loc_range.loc).unwrap(),
- })
- .collect(),
- );
- let loc_list_id = debug_context.dwarf.unit.locations.add(loc_list);
-
- AttributeValue::LocationListRef(loc_list_id)
- } else {
- // FIXME set value labels for unused locals
-
- AttributeValue::Exprloc(Expression::new())
- }
- }
- CPlaceInner::VarPair(_, _, _) => {
- // FIXME implement this
-
- AttributeValue::Exprloc(Expression::new())
- }
- CPlaceInner::VarLane(_, _, _) => {
- // FIXME implement this
-
- AttributeValue::Exprloc(Expression::new())
- }
- CPlaceInner::Addr(_, _) => {
- // FIXME implement this (used by arguments and returns)
-
- AttributeValue::Exprloc(Expression::new())
-
- // For PointerBase::Stack:
- //AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot)).unwrap())
- }
- }
-}
-
-// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
-fn translate_loc(isa: &dyn TargetIsa, loc: LabelValueLoc) -> Option<Expression> {
- match loc {
- LabelValueLoc::Reg(reg) => {
- let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
- let mut expr = Expression::new();
- expr.op_reg(gimli::Register(machine_reg));
- Some(expr)
- }
- LabelValueLoc::SPOffset(offset) => {
- let mut expr = Expression::new();
- expr.op_breg(X86_64::RSP, offset);
- Some(expr)
- }
}
}
diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs
index f619bb5ed..97b395bcd 100644
--- a/compiler/rustc_codegen_cranelift/src/discriminant.rs
+++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs
@@ -42,10 +42,10 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
Variants::Multiple {
tag: _,
tag_field,
- tag_encoding: TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
+ tag_encoding: TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
variants: _,
} => {
- if variant_index != dataful_variant {
+ if variant_index != untagged_variant {
let niche = place.place_field(fx, mir::Field::new(tag_field));
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
let niche_value = ty::ScalarInt::try_from_uint(
@@ -62,16 +62,14 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
pub(crate) fn codegen_get_discriminant<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
+ dest: CPlace<'tcx>,
value: CValue<'tcx>,
dest_layout: TyAndLayout<'tcx>,
-) -> CValue<'tcx> {
+) {
let layout = value.layout();
- if layout.abi == Abi::Uninhabited {
- let true_ = fx.bcx.ins().iconst(types::I32, 1);
- fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached);
- // Return a dummy value
- return CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout);
+ if layout.abi.is_uninhabited() {
+ return;
}
let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
@@ -89,7 +87,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
} else {
ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap()
};
- return CValue::const_val(fx, dest_layout, discr_val);
+ let res = CValue::const_val(fx, dest_layout, discr_val);
+ dest.write_cvalue(fx, res);
+ return;
}
Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => {
(tag, *tag_field, tag_encoding)
@@ -110,9 +110,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
_ => false,
};
let val = clif_intcast(fx, tag, cast_to, signed);
- CValue::by_val(val, dest_layout)
+ let res = CValue::by_val(val, dest_layout);
+ dest.write_cvalue(fx, res);
}
- TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
+ TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
// Rebase from niche values to discriminants, and check
// whether the result is in range for the niche variants.
@@ -168,9 +169,11 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
};
- let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
- let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
- CValue::by_val(discr, dest_layout)
+ let untagged_variant =
+ fx.bcx.ins().iconst(cast_to, i64::from(untagged_variant.as_u32()));
+ let discr = fx.bcx.ins().select(is_niche, niche_discr, untagged_variant);
+ let res = CValue::by_val(discr, dest_layout);
+ dest.write_cvalue(fx, res);
}
}
}
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 3cd1ef563..8eabe1cbc 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -1,33 +1,129 @@
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
//! standalone executable.
+use std::fs::File;
use std::path::PathBuf;
+use std::sync::Arc;
+use std::thread::JoinHandle;
-use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
+use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::mir::mono::{CodegenUnit, MonoItem};
use rustc_session::cgu_reuse_tracker::CguReuse;
-use rustc_session::config::{DebugInfo, OutputType};
+use rustc_session::config::{DebugInfo, OutputFilenames, OutputType};
use rustc_session::Session;
-use cranelift_codegen::isa::TargetIsa;
use cranelift_object::{ObjectBuilder, ObjectModule};
+use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken};
+use crate::global_asm::GlobalAsmConfig;
use crate::{prelude::*, BackendConfig};
-struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>);
+struct ModuleCodegenResult {
+ module_regular: CompiledModule,
+ module_global_asm: Option<CompiledModule>,
+ existing_work_product: Option<(WorkProductId, WorkProduct)>,
+}
+
+enum OngoingModuleCodegen {
+ Sync(Result<ModuleCodegenResult, String>),
+ Async(JoinHandle<Result<ModuleCodegenResult, String>>),
+}
-impl<HCX> HashStable<HCX> for ModuleCodegenResult {
+impl<HCX> HashStable<HCX> for OngoingModuleCodegen {
fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
// do nothing
}
}
-fn make_module(sess: &Session, isa: Box<dyn TargetIsa>, name: String) -> ObjectModule {
+pub(crate) struct OngoingCodegen {
+ modules: Vec<OngoingModuleCodegen>,
+ allocator_module: Option<CompiledModule>,
+ metadata_module: Option<CompiledModule>,
+ metadata: EncodedMetadata,
+ crate_info: CrateInfo,
+ concurrency_limiter: ConcurrencyLimiter,
+}
+
+impl OngoingCodegen {
+ pub(crate) fn join(
+ self,
+ sess: &Session,
+ backend_config: &BackendConfig,
+ ) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
+ let mut work_products = FxHashMap::default();
+ let mut modules = vec![];
+
+ for module_codegen in self.modules {
+ let module_codegen_result = match module_codegen {
+ OngoingModuleCodegen::Sync(module_codegen_result) => module_codegen_result,
+ OngoingModuleCodegen::Async(join_handle) => match join_handle.join() {
+ Ok(module_codegen_result) => module_codegen_result,
+ Err(panic) => std::panic::resume_unwind(panic),
+ },
+ };
+
+ let module_codegen_result = match module_codegen_result {
+ Ok(module_codegen_result) => module_codegen_result,
+ Err(err) => sess.fatal(&err),
+ };
+ let ModuleCodegenResult { module_regular, module_global_asm, existing_work_product } =
+ module_codegen_result;
+
+ if let Some((work_product_id, work_product)) = existing_work_product {
+ work_products.insert(work_product_id, work_product);
+ } else {
+ let work_product = if backend_config.disable_incr_cache {
+ None
+ } else if let Some(module_global_asm) = &module_global_asm {
+ rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
+ sess,
+ &module_regular.name,
+ &[
+ ("o", &module_regular.object.as_ref().unwrap()),
+ ("asm.o", &module_global_asm.object.as_ref().unwrap()),
+ ],
+ )
+ } else {
+ rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
+ sess,
+ &module_regular.name,
+ &[("o", &module_regular.object.as_ref().unwrap())],
+ )
+ };
+ if let Some((work_product_id, work_product)) = work_product {
+ work_products.insert(work_product_id, work_product);
+ }
+ }
+
+ modules.push(module_regular);
+ if let Some(module_global_asm) = module_global_asm {
+ modules.push(module_global_asm);
+ }
+ }
+
+ drop(self.concurrency_limiter);
+
+ (
+ CodegenResults {
+ modules,
+ allocator_module: self.allocator_module,
+ metadata_module: self.metadata_module,
+ metadata: self.metadata,
+ crate_info: self.crate_info,
+ },
+ work_products,
+ )
+ }
+}
+
+fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> ObjectModule {
+ let isa = crate::build_isa(sess, backend_config);
+
let mut builder =
ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap();
// Unlike cg_llvm, cg_clif defaults to disabling -Zfunction-sections. For cg_llvm binary size
@@ -37,15 +133,15 @@ fn make_module(sess: &Session, isa: Box<dyn TargetIsa>, name: String) -> ObjectM
ObjectModule::new(builder)
}
-fn emit_module(
- tcx: TyCtxt<'_>,
- backend_config: &BackendConfig,
+fn emit_cgu(
+ output_filenames: &OutputFilenames,
+ prof: &SelfProfilerRef,
name: String,
- kind: ModuleKind,
module: ObjectModule,
- debug: Option<DebugContext<'_>>,
+ debug: Option<DebugContext>,
unwind_context: UnwindContext,
-) -> ModuleCodegenResult {
+ global_asm_object_file: Option<PathBuf>,
+) -> Result<ModuleCodegenResult, String> {
let mut product = module.finish();
if let Some(mut debug) = debug {
@@ -54,134 +150,191 @@ fn emit_module(
unwind_context.emit(&mut product);
- let tmp_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(&name));
- let obj = product.object.write().unwrap();
+ let module_regular =
+ emit_module(output_filenames, prof, product.object, ModuleKind::Regular, name.clone())?;
+
+ Ok(ModuleCodegenResult {
+ module_regular,
+ module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule {
+ name: format!("{name}.asm"),
+ kind: ModuleKind::Regular,
+ object: Some(global_asm_object_file),
+ dwarf_object: None,
+ bytecode: None,
+ }),
+ existing_work_product: None,
+ })
+}
- tcx.sess.prof.artifact_size("object_file", name.clone(), obj.len().try_into().unwrap());
+fn emit_module(
+ output_filenames: &OutputFilenames,
+ prof: &SelfProfilerRef,
+ object: cranelift_object::object::write::Object<'_>,
+ kind: ModuleKind,
+ name: String,
+) -> Result<CompiledModule, String> {
+ let tmp_file = output_filenames.temp_path(OutputType::Object, Some(&name));
+ let mut file = match File::create(&tmp_file) {
+ Ok(file) => file,
+ Err(err) => return Err(format!("error creating object file: {}", err)),
+ };
- if let Err(err) = std::fs::write(&tmp_file, obj) {
- tcx.sess.fatal(&format!("error writing object file: {}", err));
+ if let Err(err) = object.write_stream(&mut file) {
+ return Err(format!("error writing object file: {}", err));
}
- let work_product = if backend_config.disable_incr_cache {
- None
- } else {
- rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
- tcx.sess,
- &name,
- &[("o", &tmp_file)],
- )
- };
+ prof.artifact_size("object_file", &*name, file.metadata().unwrap().len());
- ModuleCodegenResult(
- CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None },
- work_product,
- )
+ Ok(CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None })
}
fn reuse_workproduct_for_cgu(
tcx: TyCtxt<'_>,
cgu: &CodegenUnit<'_>,
- work_products: &mut FxHashMap<WorkProductId, WorkProduct>,
-) -> CompiledModule {
+) -> Result<ModuleCodegenResult, String> {
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(
+ let obj_out_regular =
+ tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
+ let source_file_regular = rustc_incremental::in_incr_comp_dir_sess(
&tcx.sess,
&work_product.saved_files.get("o").expect("no saved object file in work product"),
);
- if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
- tcx.sess.err(&format!(
+
+ if let Err(err) = rustc_fs_util::link_or_copy(&source_file_regular, &obj_out_regular) {
+ return Err(format!(
"unable to copy {} to {}: {}",
- source_file.display(),
- obj_out.display(),
+ source_file_regular.display(),
+ obj_out_regular.display(),
err
));
}
+ let obj_out_global_asm =
+ crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm");
+ let has_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") {
+ let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o);
+ if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm)
+ {
+ return Err(format!(
+ "unable to copy {} to {}: {}",
+ source_file_regular.display(),
+ obj_out_regular.display(),
+ err
+ ));
+ }
+ true
+ } else {
+ false
+ };
- work_products.insert(cgu.work_product_id(), work_product);
-
- CompiledModule {
- name: cgu.name().to_string(),
- kind: ModuleKind::Regular,
- object: Some(obj_out),
- dwarf_object: None,
- bytecode: None,
- }
+ Ok(ModuleCodegenResult {
+ module_regular: CompiledModule {
+ name: cgu.name().to_string(),
+ kind: ModuleKind::Regular,
+ object: Some(obj_out_regular),
+ dwarf_object: None,
+ bytecode: None,
+ },
+ module_global_asm: if has_global_asm {
+ Some(CompiledModule {
+ name: cgu.name().to_string(),
+ kind: ModuleKind::Regular,
+ object: Some(obj_out_global_asm),
+ dwarf_object: None,
+ bytecode: None,
+ })
+ } else {
+ None
+ },
+ existing_work_product: Some((cgu.work_product_id(), work_product)),
+ })
}
fn module_codegen(
tcx: TyCtxt<'_>,
- (backend_config, cgu_name): (BackendConfig, rustc_span::Symbol),
-) -> ModuleCodegenResult {
- let cgu = tcx.codegen_unit(cgu_name);
- let mono_items = cgu.items_in_deterministic_order(tcx);
-
- let isa = crate::build_isa(tcx.sess, &backend_config);
- let mut module = make_module(tcx.sess, isa, cgu_name.as_str().to_string());
-
- let mut cx = crate::CodegenCx::new(
- tcx,
- backend_config.clone(),
- module.isa(),
- tcx.sess.opts.debuginfo != DebugInfo::None,
- cgu_name,
- );
- super::predefine_mono_items(tcx, &mut module, &mono_items);
- for (mono_item, _) in mono_items {
- match mono_item {
- MonoItem::Fn(inst) => {
- cx.tcx
- .sess
- .time("codegen fn", || crate::base::codegen_fn(&mut cx, &mut module, inst));
- }
- MonoItem::Static(def_id) => crate::constant::codegen_static(tcx, &mut module, def_id),
- MonoItem::GlobalAsm(item_id) => {
- let item = cx.tcx.hir().item(item_id);
- if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
- if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
- cx.global_asm.push_str("\n.intel_syntax noprefix\n");
- } else {
- cx.global_asm.push_str("\n.att_syntax\n");
- }
- for piece in asm.template {
- match *piece {
- InlineAsmTemplatePiece::String(ref s) => cx.global_asm.push_str(s),
- InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
- }
- }
- cx.global_asm.push_str("\n.att_syntax\n\n");
- } else {
- bug!("Expected GlobalAsm found {:?}", item);
+ (backend_config, global_asm_config, cgu_name, token): (
+ BackendConfig,
+ Arc<GlobalAsmConfig>,
+ rustc_span::Symbol,
+ ConcurrencyLimiterToken,
+ ),
+) -> OngoingModuleCodegen {
+ let (cgu_name, mut cx, mut module, codegened_functions) = tcx.sess.time("codegen cgu", || {
+ let cgu = tcx.codegen_unit(cgu_name);
+ let mono_items = cgu.items_in_deterministic_order(tcx);
+
+ let mut module = make_module(tcx.sess, &backend_config, cgu_name.as_str().to_string());
+
+ let mut cx = crate::CodegenCx::new(
+ tcx,
+ backend_config.clone(),
+ module.isa(),
+ tcx.sess.opts.debuginfo != DebugInfo::None,
+ cgu_name,
+ );
+ super::predefine_mono_items(tcx, &mut module, &mono_items);
+ let mut codegened_functions = vec![];
+ for (mono_item, _) in mono_items {
+ match mono_item {
+ MonoItem::Fn(inst) => {
+ tcx.sess.time("codegen fn", || {
+ let codegened_function = crate::base::codegen_fn(
+ tcx,
+ &mut cx,
+ Function::new(),
+ &mut module,
+ inst,
+ );
+ codegened_functions.push(codegened_function);
+ });
+ }
+ MonoItem::Static(def_id) => {
+ crate::constant::codegen_static(tcx, &mut module, def_id)
+ }
+ MonoItem::GlobalAsm(item_id) => {
+ crate::global_asm::codegen_global_asm_item(tcx, &mut cx.global_asm, item_id);
}
}
}
- }
- crate::main_shim::maybe_create_entry_wrapper(
- tcx,
- &mut module,
- &mut cx.unwind_context,
- false,
- cgu.is_primary(),
- );
-
- let debug_context = cx.debug_context;
- let unwind_context = cx.unwind_context;
- let codegen_result = tcx.sess.time("write object file", || {
- emit_module(
+ crate::main_shim::maybe_create_entry_wrapper(
tcx,
- &backend_config,
- cgu.name().as_str().to_string(),
- ModuleKind::Regular,
- module,
- debug_context,
- unwind_context,
- )
+ &mut module,
+ &mut cx.unwind_context,
+ false,
+ cgu.is_primary(),
+ );
+
+ let cgu_name = cgu.name().as_str().to_owned();
+
+ (cgu_name, cx, module, codegened_functions)
});
- codegen_global_asm(tcx, cgu.name().as_str(), &cx.global_asm);
+ OngoingModuleCodegen::Async(std::thread::spawn(move || {
+ cx.profiler.clone().verbose_generic_activity("compile functions").run(|| {
+ let mut cached_context = Context::new();
+ for codegened_func in codegened_functions {
+ crate::base::compile_fn(&mut cx, &mut cached_context, &mut module, codegened_func);
+ }
+ });
- codegen_result
+ let global_asm_object_file =
+ cx.profiler.verbose_generic_activity("compile assembly").run(|| {
+ crate::global_asm::compile_global_asm(&global_asm_config, &cgu_name, &cx.global_asm)
+ })?;
+
+ let codegen_result = cx.profiler.verbose_generic_activity("write object file").run(|| {
+ emit_cgu(
+ &global_asm_config.output_filenames,
+ &cx.profiler,
+ cgu_name,
+ module,
+ cx.debug_context,
+ cx.unwind_context,
+ global_asm_object_file,
+ )
+ });
+ std::mem::drop(token);
+ codegen_result
+ }))
}
pub(crate) fn run_aot(
@@ -189,9 +342,7 @@ pub(crate) fn run_aot(
backend_config: BackendConfig,
metadata: EncodedMetadata,
need_metadata_module: bool,
-) -> Box<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)> {
- let mut work_products = FxHashMap::default();
-
+) -> Box<OngoingCodegen> {
let cgus = if tcx.sess.opts.output_types.should_codegen() {
tcx.collect_and_partition_mono_items(()).1
} else {
@@ -206,62 +357,69 @@ pub(crate) fn run_aot(
}
}
+ let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx));
+
+ let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len());
+
let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || {
cgus.iter()
.map(|cgu| {
- let cgu_reuse = determine_cgu_reuse(tcx, cgu);
+ let cgu_reuse = if backend_config.disable_incr_cache {
+ CguReuse::No
+ } else {
+ determine_cgu_reuse(tcx, cgu)
+ };
tcx.sess.cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse);
match cgu_reuse {
- _ if backend_config.disable_incr_cache => {}
- CguReuse::No => {}
- CguReuse::PreLto => {
- return reuse_workproduct_for_cgu(tcx, &*cgu, &mut work_products);
+ CguReuse::No => {
+ let dep_node = cgu.codegen_dep_node(tcx);
+ tcx.dep_graph
+ .with_task(
+ dep_node,
+ tcx,
+ (
+ backend_config.clone(),
+ global_asm_config.clone(),
+ cgu.name(),
+ concurrency_limiter.acquire(),
+ ),
+ module_codegen,
+ Some(rustc_middle::dep_graph::hash_result),
+ )
+ .0
+ }
+ CguReuse::PreLto => unreachable!(),
+ CguReuse::PostLto => {
+ concurrency_limiter.job_already_done();
+ OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, &*cgu))
}
- CguReuse::PostLto => unreachable!(),
- }
-
- let dep_node = cgu.codegen_dep_node(tcx);
- let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task(
- dep_node,
- tcx,
- (backend_config.clone(), cgu.name()),
- module_codegen,
- Some(rustc_middle::dep_graph::hash_result),
- );
-
- if let Some((id, product)) = work_product {
- work_products.insert(id, product);
}
-
- module
})
.collect::<Vec<_>>()
});
tcx.sess.abort_if_errors();
- let isa = crate::build_isa(tcx.sess, &backend_config);
- let mut allocator_module = make_module(tcx.sess, isa, "allocator_shim".to_string());
- assert_eq!(pointer_ty(tcx), allocator_module.target_config().pointer_type());
+ let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string());
let mut allocator_unwind_context = UnwindContext::new(allocator_module.isa(), true);
let created_alloc_shim =
crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context);
let allocator_module = if created_alloc_shim {
- let ModuleCodegenResult(module, work_product) = emit_module(
- tcx,
- &backend_config,
- "allocator_shim".to_string(),
+ let mut product = allocator_module.finish();
+ allocator_unwind_context.emit(&mut product);
+
+ match emit_module(
+ tcx.output_filenames(()),
+ &tcx.sess.prof,
+ product.object,
ModuleKind::Allocator,
- allocator_module,
- None,
- allocator_unwind_context,
- );
- if let Some((id, product)) = work_product {
- work_products.insert(id, product);
+ "allocator_shim".to_owned(),
+ ) {
+ Ok(allocator_module) => Some(allocator_module),
+ Err(err) => tcx.sess.fatal(err),
}
- Some(module)
} else {
None
};
@@ -308,102 +466,14 @@ pub(crate) fn run_aot(
}
.to_owned();
- Box::new((
- CodegenResults {
- modules,
- allocator_module,
- metadata_module,
- metadata,
- crate_info: CrateInfo::new(tcx, target_cpu),
- },
- work_products,
- ))
-}
-
-fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
- use std::io::Write;
- use std::process::{Command, Stdio};
-
- if global_asm.is_empty() {
- return;
- }
-
- if cfg!(not(feature = "inline_asm"))
- || tcx.sess.target.is_like_osx
- || tcx.sess.target.is_like_windows
- {
- if global_asm.contains("__rust_probestack") {
- return;
- }
-
- // FIXME fix linker error on macOS
- if cfg!(not(feature = "inline_asm")) {
- tcx.sess.fatal(
- "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
- );
- } else {
- tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
- }
- }
-
- let assembler = crate::toolchain::get_toolchain_binary(tcx.sess, "as");
- let linker = crate::toolchain::get_toolchain_binary(tcx.sess, "ld");
-
- // Remove all LLVM style comments
- let global_asm = global_asm
- .lines()
- .map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
- .collect::<Vec<_>>()
- .join("\n");
-
- let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
-
- // Assemble `global_asm`
- let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
- let mut child = Command::new(assembler)
- .arg("-o")
- .arg(&global_asm_object_file)
- .stdin(Stdio::piped())
- .spawn()
- .expect("Failed to spawn `as`.");
- child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
- let status = child.wait().expect("Failed to wait for `as`.");
- if !status.success() {
- tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm));
- }
-
- // Link the global asm and main object file together
- let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
- std::fs::rename(&output_object_file, &main_object_file).unwrap();
- let status = Command::new(linker)
- .arg("-r") // Create a new object file
- .arg("-o")
- .arg(output_object_file)
- .arg(&main_object_file)
- .arg(&global_asm_object_file)
- .status()
- .unwrap();
- if !status.success() {
- tcx.sess.fatal(&format!(
- "Failed to link `{}` and `{}` together",
- main_object_file.display(),
- global_asm_object_file.display(),
- ));
- }
-
- std::fs::remove_file(global_asm_object_file).unwrap();
- std::fs::remove_file(main_object_file).unwrap();
-}
-
-fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
- let mut new_filename = path.file_stem().unwrap().to_owned();
- new_filename.push(postfix);
- if let Some(extension) = path.extension() {
- new_filename.push(".");
- new_filename.push(extension);
- }
- path.set_file_name(new_filename);
- path
+ Box::new(OngoingCodegen {
+ modules,
+ allocator_module,
+ metadata_module,
+ metadata,
+ crate_info: CrateInfo::new(tcx, target_cpu),
+ concurrency_limiter,
+ })
}
// Adapted from https://github.com/rust-lang/rust/blob/303d8aff6092709edd4dbd35b1c88e9aa40bf6d8/src/librustc_codegen_ssa/base.rs#L922-L953
@@ -432,5 +502,5 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
cgu.name()
);
- if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No }
+ if tcx.try_mark_green(&dep_node) { CguReuse::PostLto } else { CguReuse::No }
}
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index a56a91000..0e77e4004 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -61,11 +61,11 @@ impl UnsafeMessage {
}
}
-fn create_jit_module<'tcx>(
- tcx: TyCtxt<'tcx>,
+fn create_jit_module(
+ tcx: TyCtxt<'_>,
backend_config: &BackendConfig,
hotswap: bool,
-) -> (JITModule, CodegenCx<'tcx>) {
+) -> (JITModule, CodegenCx) {
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
let imported_symbols = load_imported_symbols_for_jit(tcx.sess, crate_info);
@@ -111,6 +111,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
&backend_config,
matches!(backend_config.codegen_mode, CodegenMode::JitLazy),
);
+ let mut cached_context = Context::new();
let (_, cgus) = tcx.collect_and_partition_mono_items(());
let mono_items = cgus
@@ -128,11 +129,19 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
MonoItem::Fn(inst) => match backend_config.codegen_mode {
CodegenMode::Aot => unreachable!(),
CodegenMode::Jit => {
- cx.tcx.sess.time("codegen fn", || {
- crate::base::codegen_fn(&mut cx, &mut jit_module, inst)
+ tcx.sess.time("codegen fn", || {
+ crate::base::codegen_and_compile_fn(
+ tcx,
+ &mut cx,
+ &mut cached_context,
+ &mut jit_module,
+ inst,
+ )
});
}
- CodegenMode::JitLazy => codegen_shim(&mut cx, &mut jit_module, inst),
+ CodegenMode::JitLazy => {
+ codegen_shim(tcx, &mut cx, &mut cached_context, &mut jit_module, inst)
+ }
},
MonoItem::Static(def_id) => {
crate::constant::codegen_static(tcx, &mut jit_module, def_id);
@@ -259,7 +268,15 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
false,
Symbol::intern("dummy_cgu_name"),
);
- tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, jit_module, instance));
+ tcx.sess.time("codegen fn", || {
+ crate::base::codegen_and_compile_fn(
+ tcx,
+ &mut cx,
+ &mut Context::new(),
+ jit_module,
+ instance,
+ )
+ });
assert!(cx.global_asm.is_empty());
jit_module.finalize_definitions();
@@ -334,9 +351,13 @@ fn load_imported_symbols_for_jit(
imported_symbols
}
-fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: Instance<'tcx>) {
- let tcx = cx.tcx;
-
+fn codegen_shim<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ cx: &mut CodegenCx,
+ cached_context: &mut Context,
+ module: &mut JITModule,
+ inst: Instance<'tcx>,
+) {
let pointer_type = module.target_config().pointer_type();
let name = tcx.symbol_name(inst).name;
@@ -357,8 +378,9 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
)
.unwrap();
- cx.cached_context.clear();
- let trampoline = &mut cx.cached_context.func;
+ let context = cached_context;
+ context.clear();
+ let trampoline = &mut context.func;
trampoline.signature = sig.clone();
let mut builder_ctx = FunctionBuilderContext::new();
@@ -381,5 +403,6 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();
trampoline_builder.ins().return_(&ret_vals);
- module.define_function(func_id, &mut cx.cached_context).unwrap();
+ module.define_function(func_id, context).unwrap();
+ cx.unwind_context.add_function(func_id, context, module.isa());
}
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
new file mode 100644
index 000000000..dcbcaba30
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -0,0 +1,114 @@
+//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
+//! standalone executable.
+
+use std::io::Write;
+use std::path::PathBuf;
+use std::process::{Command, Stdio};
+use std::sync::Arc;
+
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_hir::ItemId;
+use rustc_session::config::{OutputFilenames, OutputType};
+
+use crate::prelude::*;
+
+pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) {
+ let item = tcx.hir().item(item_id);
+ if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
+ if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
+ global_asm.push_str("\n.intel_syntax noprefix\n");
+ } else {
+ global_asm.push_str("\n.att_syntax\n");
+ }
+ for piece in asm.template {
+ match *piece {
+ InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s),
+ InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
+ }
+ }
+ global_asm.push_str("\n.att_syntax\n\n");
+ } else {
+ bug!("Expected GlobalAsm found {:?}", item);
+ }
+}
+
+#[derive(Debug)]
+pub(crate) struct GlobalAsmConfig {
+ asm_enabled: bool,
+ assembler: PathBuf,
+ pub(crate) output_filenames: Arc<OutputFilenames>,
+}
+
+impl GlobalAsmConfig {
+ pub(crate) fn new(tcx: TyCtxt<'_>) -> Self {
+ let asm_enabled = cfg!(feature = "inline_asm") && !tcx.sess.target.is_like_windows;
+
+ GlobalAsmConfig {
+ asm_enabled,
+ assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
+ output_filenames: tcx.output_filenames(()).clone(),
+ }
+ }
+}
+
+pub(crate) fn compile_global_asm(
+ config: &GlobalAsmConfig,
+ cgu_name: &str,
+ global_asm: &str,
+) -> Result<Option<PathBuf>, String> {
+ if global_asm.is_empty() {
+ return Ok(None);
+ }
+
+ if !config.asm_enabled {
+ if global_asm.contains("__rust_probestack") {
+ return Ok(None);
+ }
+
+ // FIXME fix linker error on macOS
+ if cfg!(not(feature = "inline_asm")) {
+ return Err(
+ "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift"
+ .to_owned(),
+ );
+ } else {
+ return Err("asm! and global_asm! are not yet supported on Windows".to_owned());
+ }
+ }
+
+ // Remove all LLVM style comments
+ let global_asm = global_asm
+ .lines()
+ .map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
+ .collect::<Vec<_>>()
+ .join("\n");
+
+ let output_object_file = config.output_filenames.temp_path(OutputType::Object, Some(cgu_name));
+
+ // Assemble `global_asm`
+ let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
+ let mut child = Command::new(&config.assembler)
+ .arg("-o")
+ .arg(&global_asm_object_file)
+ .stdin(Stdio::piped())
+ .spawn()
+ .expect("Failed to spawn `as`.");
+ child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
+ let status = child.wait().expect("Failed to wait for `as`.");
+ if !status.success() {
+ return Err(format!("Failed to assemble `{}`", global_asm));
+ }
+
+ Ok(Some(global_asm_object_file))
+}
+
+pub(crate) fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
+ let mut new_filename = path.file_stem().unwrap().to_owned();
+ new_filename.push(postfix);
+ if let Some(extension) = path.extension() {
+ new_filename.push(".");
+ new_filename.push(extension);
+ }
+ path.set_file_name(new_filename);
+ path
+}
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 241de5e36..8b3d475cb 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -15,15 +15,19 @@ pub(crate) fn codegen_inline_asm<'tcx>(
template: &[InlineAsmTemplatePiece],
operands: &[InlineAsmOperand<'tcx>],
options: InlineAsmOptions,
+ destination: Option<mir::BasicBlock>,
) {
// FIXME add .eh_frame unwind info directives
if !template.is_empty() {
+ // Used by panic_abort
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
- let true_ = fx.bcx.ins().iconst(types::I32, 1);
- fx.bcx.ins().trapnz(true_, TrapCode::User(1));
+ fx.bcx.ins().trap(TrapCode::User(1));
return;
- } else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
+ }
+
+ // Used by stdarch
+ if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
&& matches!(
template[1],
InlineAsmTemplatePiece::Placeholder {
@@ -47,51 +51,46 @@ pub(crate) fn codegen_inline_asm<'tcx>(
{
assert_eq!(operands.len(), 4);
let (leaf, eax_place) = match operands[1] {
- InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
- assert_eq!(
- reg,
- InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
- );
- (
- crate::base::codegen_operand(fx, in_value).load_scalar(fx),
- crate::base::codegen_place(fx, out_place.unwrap()),
- )
- }
+ InlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
+ late: true,
+ ref in_value,
+ out_place: Some(out_place),
+ } => (
+ crate::base::codegen_operand(fx, in_value).load_scalar(fx),
+ crate::base::codegen_place(fx, out_place),
+ ),
_ => unreachable!(),
};
let ebx_place = match operands[0] {
- InlineAsmOperand::Out { reg, late: true, place } => {
- assert_eq!(
- reg,
+ InlineAsmOperand::Out {
+ reg:
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
- X86InlineAsmRegClass::reg
- ))
- );
- crate::base::codegen_place(fx, place.unwrap())
- }
+ X86InlineAsmRegClass::reg,
+ )),
+ late: true,
+ place: Some(place),
+ } => crate::base::codegen_place(fx, place),
_ => unreachable!(),
};
let (sub_leaf, ecx_place) = match operands[2] {
- InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
- assert_eq!(
- reg,
- InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
- );
- (
- crate::base::codegen_operand(fx, in_value).load_scalar(fx),
- crate::base::codegen_place(fx, out_place.unwrap()),
- )
- }
+ InlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
+ late: true,
+ ref in_value,
+ out_place: Some(out_place),
+ } => (
+ crate::base::codegen_operand(fx, in_value).load_scalar(fx),
+ crate::base::codegen_place(fx, out_place),
+ ),
_ => unreachable!(),
};
let edx_place = match operands[3] {
- InlineAsmOperand::Out { reg, late: true, place } => {
- assert_eq!(
- reg,
- InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
- );
- crate::base::codegen_place(fx, place.unwrap())
- }
+ InlineAsmOperand::Out {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
+ late: true,
+ place: Some(place),
+ } => crate::base::codegen_place(fx, place),
_ => unreachable!(),
};
@@ -101,12 +100,99 @@ pub(crate) fn codegen_inline_asm<'tcx>(
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
+ let destination_block = fx.get_block(destination.unwrap());
+ fx.bcx.ins().jump(destination_block, &[]);
return;
- } else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
+ }
+
+ // Used by compiler-builtins
+ if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
+ return;
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
+ return;
+ }
+
+ // Used by measureme
+ if template[0] == InlineAsmTemplatePiece::String("xor %eax, %eax".to_string())
+ && template[1] == InlineAsmTemplatePiece::String("\n".to_string())
+ && template[2] == InlineAsmTemplatePiece::String("mov %rbx, ".to_string())
+ && matches!(
+ template[3],
+ InlineAsmTemplatePiece::Placeholder {
+ operand_idx: 0,
+ modifier: Some('r'),
+ span: _
+ }
+ )
+ && template[4] == InlineAsmTemplatePiece::String("\n".to_string())
+ && template[5] == InlineAsmTemplatePiece::String("cpuid".to_string())
+ && template[6] == InlineAsmTemplatePiece::String("\n".to_string())
+ && template[7] == InlineAsmTemplatePiece::String("mov ".to_string())
+ && matches!(
+ template[8],
+ InlineAsmTemplatePiece::Placeholder {
+ operand_idx: 0,
+ modifier: Some('r'),
+ span: _
+ }
+ )
+ && template[9] == InlineAsmTemplatePiece::String(", %rbx".to_string())
+ {
+ let destination_block = fx.get_block(destination.unwrap());
+ fx.bcx.ins().jump(destination_block, &[]);
+ return;
+ } else if template[0] == InlineAsmTemplatePiece::String("rdpmc".to_string()) {
+ // Return zero dummy values for all performance counters
+ match operands[0] {
+ InlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
+ value: _,
+ } => {}
+ _ => unreachable!(),
+ };
+ let lo = match operands[1] {
+ InlineAsmOperand::Out {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
+ late: true,
+ place: Some(place),
+ } => crate::base::codegen_place(fx, place),
+ _ => unreachable!(),
+ };
+ let hi = match operands[2] {
+ InlineAsmOperand::Out {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
+ late: true,
+ place: Some(place),
+ } => crate::base::codegen_place(fx, place),
+ _ => unreachable!(),
+ };
+
+ let u32_layout = fx.layout_of(fx.tcx.types.u32);
+ let zero = fx.bcx.ins().iconst(types::I32, 0);
+ lo.write_cvalue(fx, CValue::by_val(zero, u32_layout));
+ hi.write_cvalue(fx, CValue::by_val(zero, u32_layout));
+
+ let destination_block = fx.get_block(destination.unwrap());
+ fx.bcx.ins().jump(destination_block, &[]);
+ return;
+ } else if template[0] == InlineAsmTemplatePiece::String("lock xadd ".to_string())
+ && matches!(
+ template[1],
+ InlineAsmTemplatePiece::Placeholder { operand_idx: 1, modifier: None, span: _ }
+ )
+ && template[2] == InlineAsmTemplatePiece::String(", (".to_string())
+ && matches!(
+ template[3],
+ InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ }
+ )
+ && template[4] == InlineAsmTemplatePiece::String(")".to_string())
+ {
+ let destination_block = fx.get_block(destination.unwrap());
+ fx.bcx.ins().jump(destination_block, &[]);
+ return;
}
}
@@ -175,6 +261,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
}
call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs);
+
+ match destination {
+ Some(destination) => {
+ let destination_block = fx.get_block(destination);
+ fx.bcx.ins().jump(destination_block, &[]);
+ }
+ None => {
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+ }
+ }
}
struct InlineAssemblyGenerator<'a, 'tcx> {
@@ -637,7 +733,7 @@ fn call_inline_asm<'tcx>(
inputs: Vec<(Size, Value)>,
outputs: Vec<(Size, CPlace<'tcx>)>,
) {
- let stack_slot = fx.bcx.func.create_stack_slot(StackSlotData {
+ let stack_slot = fx.bcx.func.create_sized_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
size: u32::try_from(slot_size.bytes()).unwrap(),
});
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/cpuid.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/cpuid.rs
index d02dfd93c..5120b89c4 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/cpuid.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/cpuid.rs
@@ -62,7 +62,7 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
fx.bcx.switch_to_block(unsupported_leaf);
- crate::trap::trap_unreachable(
+ crate::trap::trap_unimplemented(
fx,
"__cpuid_count arch intrinsic doesn't yet support specified leaf",
);
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index 869670c8c..a799dca93 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -139,6 +139,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
.sess
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
crate::trap::trap_unimplemented(fx, intrinsic);
+ return;
}
}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index b2a83e1d4..2e4ca594f 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -44,7 +44,7 @@ fn report_atomic_type_validation_error<'tcx>(
),
);
// Prevent verifier error
- crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
}
pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Option<Type> {
@@ -53,7 +53,7 @@ pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx
_ => unreachable!(),
};
- match scalar_to_clif_type(tcx, element).by(u16::try_from(count).unwrap()) {
+ match scalar_to_clif_type(tcx, element).by(u32::try_from(count).unwrap()) {
// Cranelift currently only implements icmp for 128bit vectors.
Some(vector_ty) if vector_ty.bits() == 128 => Some(vector_ty),
_ => None,
@@ -203,7 +203,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
sym::transmute => {
crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info);
}
- _ => unimplemented!("unsupported instrinsic {}", intrinsic),
+ _ => unimplemented!("unsupported intrinsic {}", intrinsic),
}
return;
};
@@ -301,7 +301,44 @@ fn codegen_float_intrinsic_call<'tcx>(
_ => unreachable!(),
};
- let res = fx.easy_call(name, &args, ty);
+ let layout = fx.layout_of(ty);
+ let res = match intrinsic {
+ sym::fmaf32 | sym::fmaf64 => {
+ let a = args[0].load_scalar(fx);
+ let b = args[1].load_scalar(fx);
+ let c = args[2].load_scalar(fx);
+ CValue::by_val(fx.bcx.ins().fma(a, b, c), layout)
+ }
+ sym::copysignf32 | sym::copysignf64 => {
+ let a = args[0].load_scalar(fx);
+ let b = args[1].load_scalar(fx);
+ CValue::by_val(fx.bcx.ins().fcopysign(a, b), layout)
+ }
+ sym::fabsf32
+ | sym::fabsf64
+ | sym::floorf32
+ | sym::floorf64
+ | sym::ceilf32
+ | sym::ceilf64
+ | sym::truncf32
+ | sym::truncf64 => {
+ let a = args[0].load_scalar(fx);
+
+ let val = match intrinsic {
+ sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(a),
+ sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(a),
+ sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(a),
+ sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(a),
+ _ => unreachable!(),
+ };
+
+ CValue::by_val(val, layout)
+ }
+ // These intrinsics aren't supported natively by Cranelift.
+ // Lower them to a libcall.
+ _ => fx.easy_call(name, &args, ty),
+ };
+
ret.write_cvalue(fx, res);
true
@@ -320,9 +357,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
let usize_layout = fx.layout_of(fx.tcx.types.usize);
match intrinsic {
- sym::assume => {
- intrinsic_args!(fx, args => (_a); intrinsic);
- }
sym::likely | sym::unlikely => {
intrinsic_args!(fx, args => (a); intrinsic);
@@ -540,6 +574,13 @@ fn codegen_regular_intrinsic_call<'tcx>(
ret.write_cvalue(fx, CValue::by_val(res, base.layout()));
}
+ sym::ptr_mask => {
+ intrinsic_args!(fx, args => (ptr, mask); intrinsic);
+ let ptr = ptr.load_scalar(fx);
+ let mask = mask.load_scalar(fx);
+ fx.bcx.ins().band(ptr, mask);
+ }
+
sym::transmute => {
intrinsic_args!(fx, args => (from); intrinsic);
@@ -775,20 +816,13 @@ fn codegen_regular_intrinsic_call<'tcx>(
ret.write_cvalue(fx, val);
}
- sym::ptr_guaranteed_eq => {
+ sym::ptr_guaranteed_cmp => {
intrinsic_args!(fx, args => (a, b); intrinsic);
let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b);
ret.write_cvalue(fx, val);
}
- sym::ptr_guaranteed_ne => {
- intrinsic_args!(fx, args => (a, b); intrinsic);
-
- let val = crate::num::codegen_ptr_binop(fx, BinOp::Ne, a, b);
- ret.write_cvalue(fx, val);
- }
-
sym::caller_location => {
intrinsic_args!(fx, args => (); intrinsic);
@@ -818,8 +852,6 @@ 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());
- fx.bcx.ins().jump(ret_block, &[]);
return;
} else {
fx.tcx
@@ -851,8 +883,6 @@ 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());
- fx.bcx.ins().jump(ret_block, &[]);
return;
} else {
fx.tcx
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 30e3d1125..1f358b1bb 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -14,7 +14,7 @@ fn report_simd_type_validation_error(
) {
fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
// Prevent verifier error
- crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
}
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
@@ -157,7 +157,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
),
);
// Prevent verifier error
- crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
return;
}
}
@@ -186,7 +186,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let size = Size::from_bytes(
4 * ret_lane_count, /* size_of([u32; ret_lane_count]) */
);
- alloc.inner().get_bytes(fx, alloc_range(offset, size)).unwrap()
+ alloc
+ .inner()
+ .get_bytes_strip_provenance(fx, alloc_range(offset, size))
+ .unwrap()
}
_ => unreachable!("{:?}", idx_const),
};
@@ -274,12 +277,17 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
idx_const
} else {
fx.tcx.sess.span_warn(span, "Index argument for `simd_extract` is not a constant");
- let res = crate::trap::trap_unimplemented_ret_value(
+ let trap_block = fx.bcx.create_block();
+ let dummy_block = fx.bcx.create_block();
+ let true_ = fx.bcx.ins().iconst(types::I8, 1);
+ fx.bcx.ins().brnz(true_, trap_block, &[]);
+ fx.bcx.ins().jump(dummy_block, &[]);
+ fx.bcx.switch_to_block(trap_block);
+ crate::trap::trap_unimplemented(
fx,
- ret.layout(),
"Index argument for `simd_extract` is not a constant",
);
- ret.write_cvalue(fx, res);
+ fx.bcx.switch_to_block(dummy_block);
return;
};
@@ -392,21 +400,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let layout = a.layout();
let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let res_lane_layout = fx.layout_of(lane_ty);
for lane in 0..lane_count {
- let a_lane = a.value_lane(fx, lane);
- let b_lane = b.value_lane(fx, lane);
- let c_lane = c.value_lane(fx, lane);
+ let a_lane = a.value_lane(fx, lane).load_scalar(fx);
+ let b_lane = b.value_lane(fx, lane).load_scalar(fx);
+ let c_lane = c.value_lane(fx, lane).load_scalar(fx);
- let res_lane = match lane_ty.kind() {
- ty::Float(FloatTy::F32) => {
- fx.easy_call("fmaf", &[a_lane, b_lane, c_lane], lane_ty)
- }
- ty::Float(FloatTy::F64) => {
- fx.easy_call("fma", &[a_lane, b_lane, c_lane], lane_ty)
- }
- _ => unreachable!(),
- };
+ let res_lane = fx.bcx.ins().fma(a_lane, b_lane, c_lane);
+ let res_lane = CValue::by_val(res_lane, res_lane_layout);
ret.place_lane(fx, lane).write_cvalue(fx, res_lane);
}
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index bb0793b1d..913414e76 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -4,6 +4,7 @@
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]
+extern crate jobserver;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_ast;
@@ -25,10 +26,12 @@ extern crate rustc_target;
extern crate rustc_driver;
use std::any::Any;
-use std::cell::Cell;
+use std::cell::{Cell, RefCell};
+use std::sync::Arc;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
+use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_errors::ErrorGuaranteed;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
@@ -51,11 +54,13 @@ mod cast;
mod codegen_i128;
mod common;
mod compiler_builtins;
+mod concurrency_limiter;
mod config;
mod constant;
mod debuginfo;
mod discriminant;
mod driver;
+mod global_asm;
mod inline_asm;
mod intrinsics;
mod linkage;
@@ -119,19 +124,20 @@ impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
/// The codegen context holds any information shared between the codegen of individual functions
/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module).
-struct CodegenCx<'tcx> {
- tcx: TyCtxt<'tcx>,
+struct CodegenCx {
+ profiler: SelfProfilerRef,
+ output_filenames: Arc<OutputFilenames>,
+ should_write_ir: bool,
global_asm: String,
inline_asm_index: Cell<usize>,
- cached_context: Context,
- debug_context: Option<DebugContext<'tcx>>,
+ debug_context: Option<DebugContext>,
unwind_context: UnwindContext,
cgu_name: Symbol,
}
-impl<'tcx> CodegenCx<'tcx> {
+impl CodegenCx {
fn new(
- tcx: TyCtxt<'tcx>,
+ tcx: TyCtxt<'_>,
backend_config: BackendConfig,
isa: &dyn TargetIsa,
debug_info: bool,
@@ -147,10 +153,11 @@ impl<'tcx> CodegenCx<'tcx> {
None
};
CodegenCx {
- tcx,
+ profiler: tcx.prof.clone(),
+ output_filenames: tcx.output_filenames(()).clone(),
+ should_write_ir: crate::pretty_clif::should_write_ir(tcx),
global_asm: String::new(),
inline_asm_index: Cell::new(0),
- cached_context: Context::new(),
debug_context,
unwind_context,
cgu_name,
@@ -159,7 +166,7 @@ impl<'tcx> CodegenCx<'tcx> {
}
pub struct CraneliftCodegenBackend {
- pub config: Option<BackendConfig>,
+ pub config: RefCell<Option<BackendConfig>>,
}
impl CodegenBackend for CraneliftCodegenBackend {
@@ -169,6 +176,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
Lto::No | Lto::ThinLocal => {}
Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."),
}
+
+ let mut config = self.config.borrow_mut();
+ if config.is_none() {
+ let new_config = BackendConfig::from_opts(&sess.opts.cg.llvm_args)
+ .unwrap_or_else(|err| sess.fatal(&err));
+ *config = Some(new_config);
+ }
}
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
@@ -186,15 +200,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
need_metadata_module: bool,
) -> Box<dyn Any> {
tcx.sess.abort_if_errors();
- let config = if let Some(config) = self.config.clone() {
- config
- } else {
- if !tcx.sess.unstable_options() && !tcx.sess.opts.cg.llvm_args.is_empty() {
- tcx.sess.fatal("`-Z unstable-options` must be passed to allow configuring cg_clif");
- }
- BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
- .unwrap_or_else(|err| tcx.sess.fatal(&err))
- };
+ let config = self.config.borrow().clone().unwrap();
match config.codegen_mode {
CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module),
CodegenMode::Jit | CodegenMode::JitLazy => {
@@ -210,12 +216,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
fn join_codegen(
&self,
ongoing_codegen: Box<dyn Any>,
- _sess: &Session,
+ sess: &Session,
_outputs: &OutputFilenames,
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
- Ok(*ongoing_codegen
- .downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>()
- .unwrap())
+ Ok(ongoing_codegen
+ .downcast::<driver::aot::OngoingCodegen>()
+ .unwrap()
+ .join(sess, self.config.borrow().as_ref().unwrap()))
}
fn link(
@@ -312,5 +319,5 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
- Box::new(CraneliftCodegenBackend { config: None })
+ Box::new(CraneliftCodegenBackend { config: RefCell::new(None) })
}
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index c67b6e98b..3c024a84d 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -1,7 +1,7 @@
use rustc_hir::LangItem;
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::AssocKind;
-use rustc_session::config::EntryFnType;
+use rustc_session::config::{sigpipe, EntryFnType};
use rustc_span::symbol::Ident;
use crate::prelude::*;
@@ -15,12 +15,12 @@ pub(crate) fn maybe_create_entry_wrapper(
is_jit: bool,
is_primary_cgu: bool,
) {
- let (main_def_id, is_main_fn) = match tcx.entry_fn(()) {
+ let (main_def_id, (is_main_fn, sigpipe)) = match tcx.entry_fn(()) {
Some((def_id, entry_ty)) => (
def_id,
match entry_ty {
- EntryFnType::Main => true,
- EntryFnType::Start => false,
+ EntryFnType::Main { sigpipe } => (true, sigpipe),
+ EntryFnType::Start => (false, sigpipe::DEFAULT),
},
),
None => return,
@@ -35,7 +35,7 @@ pub(crate) fn maybe_create_entry_wrapper(
return;
}
- create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn);
+ create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn, sigpipe);
fn create_entry_fn(
tcx: TyCtxt<'_>,
@@ -44,6 +44,7 @@ pub(crate) fn maybe_create_entry_wrapper(
rust_main_def_id: DefId,
ignore_lang_start_wrapper: bool,
is_main_fn: bool,
+ sigpipe: u8,
) {
let main_ret_ty = tcx.fn_sig(rust_main_def_id).output();
// Given that `main()` has no arguments,
@@ -83,6 +84,7 @@ pub(crate) fn maybe_create_entry_wrapper(
bcx.switch_to_block(block);
let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type());
let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type());
+ let arg_sigpipe = bcx.ins().iconst(types::I8, sigpipe as i64);
let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);
@@ -143,7 +145,8 @@ pub(crate) fn maybe_create_entry_wrapper(
let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref);
let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func);
- let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv]);
+ let call_inst =
+ bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]);
bcx.inst_results(call_inst)[0]
} else {
// using user-defined start fn
diff --git a/compiler/rustc_codegen_cranelift/src/optimize/mod.rs b/compiler/rustc_codegen_cranelift/src/optimize/mod.rs
index d1f89adb3..0df7e8229 100644
--- a/compiler/rustc_codegen_cranelift/src/optimize/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/optimize/mod.rs
@@ -1,20 +1,3 @@
//! Various optimizations specific to cg_clif
-use cranelift_codegen::isa::TargetIsa;
-
-use crate::prelude::*;
-
pub(crate) mod peephole;
-
-pub(crate) fn optimize_function<'tcx>(
- tcx: TyCtxt<'tcx>,
- isa: &dyn TargetIsa,
- instance: Instance<'tcx>,
- ctx: &mut Context,
- clif_comments: &mut crate::pretty_clif::CommentWriter,
-) {
- // FIXME classify optimizations over opt levels once we have more
-
- crate::pretty_clif::write_clif_file(tcx, "preopt", isa, instance, &ctx.func, &*clif_comments);
- crate::base::verify_func(tcx, &*clif_comments, &ctx.func);
-}
diff --git a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
index 1d1ec2168..a7af16268 100644
--- a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
+++ b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
@@ -62,7 +62,7 @@ use cranelift_codegen::{
};
use rustc_middle::ty::layout::FnAbiOf;
-use rustc_session::config::OutputType;
+use rustc_session::config::{OutputFilenames, OutputType};
use crate::prelude::*;
@@ -205,15 +205,11 @@ pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool {
}
pub(crate) fn write_ir_file(
- tcx: TyCtxt<'_>,
- name: impl FnOnce() -> String,
+ output_filenames: &OutputFilenames,
+ name: &str,
write: impl FnOnce(&mut dyn Write) -> std::io::Result<()>,
) {
- if !should_write_ir(tcx) {
- return;
- }
-
- let clif_output_dir = tcx.output_filenames(()).with_extension("clif");
+ let clif_output_dir = output_filenames.with_extension("clif");
match std::fs::create_dir(&clif_output_dir) {
Ok(()) => {}
@@ -221,44 +217,43 @@ pub(crate) fn write_ir_file(
res @ Err(_) => res.unwrap(),
}
- let clif_file_name = clif_output_dir.join(name());
+ let clif_file_name = clif_output_dir.join(name);
let res = std::fs::File::create(clif_file_name).and_then(|mut file| write(&mut file));
if let Err(err) = res {
- tcx.sess.warn(&format!("error writing ir file: {}", err));
+ // Using early_warn as no Session is available here
+ rustc_session::early_warn(
+ rustc_session::config::ErrorOutputType::default(),
+ &format!("error writing ir file: {}", err),
+ );
}
}
-pub(crate) fn write_clif_file<'tcx>(
- tcx: TyCtxt<'tcx>,
+pub(crate) fn write_clif_file(
+ output_filenames: &OutputFilenames,
+ symbol_name: &str,
postfix: &str,
isa: &dyn cranelift_codegen::isa::TargetIsa,
- instance: Instance<'tcx>,
func: &cranelift_codegen::ir::Function,
mut clif_comments: &CommentWriter,
) {
// FIXME work around filename too long errors
- write_ir_file(
- tcx,
- || format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
- |file| {
- let mut clif = String::new();
- cranelift_codegen::write::decorate_function(&mut clif_comments, &mut clif, func)
- .unwrap();
+ write_ir_file(output_filenames, &format!("{}.{}.clif", symbol_name, postfix), |file| {
+ let mut clif = String::new();
+ cranelift_codegen::write::decorate_function(&mut clif_comments, &mut clif, func).unwrap();
- for flag in isa.flags().iter() {
- writeln!(file, "set {}", flag)?;
- }
- write!(file, "target {}", isa.triple().architecture.to_string())?;
- for isa_flag in isa.isa_flags().iter() {
- write!(file, " {}", isa_flag)?;
- }
- writeln!(file, "\n")?;
- writeln!(file)?;
- file.write_all(clif.as_bytes())?;
- Ok(())
- },
- );
+ for flag in isa.flags().iter() {
+ writeln!(file, "set {}", flag)?;
+ }
+ write!(file, "target {}", isa.triple().architecture.to_string())?;
+ for isa_flag in isa.isa_flags().iter() {
+ write!(file, " {}", isa_flag)?;
+ }
+ writeln!(file, "\n")?;
+ writeln!(file)?;
+ file.write_all(clif.as_bytes())?;
+ Ok(())
+ });
}
impl fmt::Debug for FunctionCx<'_, '_, '_> {
diff --git a/compiler/rustc_codegen_cranelift/src/toolchain.rs b/compiler/rustc_codegen_cranelift/src/toolchain.rs
index f86236ef3..b6b465e1f 100644
--- a/compiler/rustc_codegen_cranelift/src/toolchain.rs
+++ b/compiler/rustc_codegen_cranelift/src/toolchain.rs
@@ -8,10 +8,8 @@ use rustc_session::Session;
/// Tries to infer the path of a binary for the target toolchain from the linker name.
pub(crate) fn get_toolchain_binary(sess: &Session, tool: &str) -> PathBuf {
let (mut linker, _linker_flavor) = linker_and_flavor(sess);
- let linker_file_name = linker
- .file_name()
- .and_then(|name| name.to_str())
- .unwrap_or_else(|| sess.fatal("couldn't extract file name from specified linker"));
+ let linker_file_name =
+ linker.file_name().unwrap().to_str().expect("linker filename should be valid UTF-8");
if linker_file_name == "ld.lld" {
if tool != "ld" {
diff --git a/compiler/rustc_codegen_cranelift/src/trap.rs b/compiler/rustc_codegen_cranelift/src/trap.rs
index 923269c4d..82a2ec579 100644
--- a/compiler/rustc_codegen_cranelift/src/trap.rs
+++ b/compiler/rustc_codegen_cranelift/src/trap.rs
@@ -25,33 +25,10 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
fx.bcx.ins().call(puts, &[msg_ptr]);
}
-/// Use this for example when a function call should never return. This will fill the current block,
-/// so you can **not** add instructions to it afterwards.
-///
-/// Trap code: user65535
-pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
- codegen_print(fx, msg.as_ref());
- fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
-}
/// Use this when something is unimplemented, but `libcore` or `libstd` requires it to codegen.
-/// Unlike `trap_unreachable` this will not fill the current block, so you **must** add instructions
-/// to it afterwards.
///
/// Trap code: user65535
pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
codegen_print(fx, msg.as_ref());
- let true_ = fx.bcx.ins().iconst(types::I32, 1);
- fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
-}
-
-/// Like `trap_unimplemented` but returns a fake value of the specified type.
-///
-/// Trap code: user65535
-pub(crate) fn trap_unimplemented_ret_value<'tcx>(
- fx: &mut FunctionCx<'_, '_, 'tcx>,
- dest_layout: TyAndLayout<'tcx>,
- msg: impl AsRef<str>,
-) -> CValue<'tcx> {
- trap_unimplemented(fx, msg);
- CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout)
+ fx.bcx.ins().trap(TrapCode::User(!0));
}
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 052ca0a08..dd9d891dd 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -29,6 +29,7 @@ pub(crate) fn unsized_info<'tcx>(
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
+ // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
return old_info;
}
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index 45ae2bd8f..cfaadca94 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -122,7 +122,7 @@ impl<'tcx> CValue<'tcx> {
let clif_ty = match layout.abi {
Abi::Scalar(scalar) => scalar_to_clif_type(fx.tcx, scalar),
Abi::Vector { element, count } => scalar_to_clif_type(fx.tcx, element)
- .by(u16::try_from(count).unwrap())
+ .by(u32::try_from(count).unwrap())
.unwrap(),
_ => unreachable!("{:?}", layout.ty),
};
@@ -330,7 +330,7 @@ impl<'tcx> CPlace<'tcx> {
.fatal(&format!("values of type {} are too big to store on the stack", layout.ty));
}
- let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
+ let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
// specify stack slot alignment.
@@ -472,7 +472,7 @@ impl<'tcx> CPlace<'tcx> {
}
_ if src_ty.is_vector() || dst_ty.is_vector() => {
// FIXME do something more efficient for transmutes between vectors and integers.
- let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
+ let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
// specify stack slot alignment.
@@ -519,7 +519,7 @@ impl<'tcx> CPlace<'tcx> {
if let ty::Array(element, len) = dst_layout.ty.kind() {
// Can only happen for vector types
let len =
- u16::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap();
+ u32::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap();
let vector_ty = fx.clif_type(*element).unwrap().by(len).unwrap();
let data = match from.0 {
@@ -614,7 +614,7 @@ impl<'tcx> CPlace<'tcx> {
dst_align,
src_align,
true,
- MemFlags::trusted(),
+ flags,
);
}
CValueInner::ByRef(_, Some(_)) => todo!(),
@@ -815,7 +815,8 @@ pub(crate) fn assert_assignable<'tcx>(
);
// fn(&T) -> for<'l> fn(&'l T) is allowed
}
- (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => {
+ (&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => {
+ // FIXME(dyn-star): Do the right thing with DynKinds
for (from, to) in from_traits.iter().zip(to_traits) {
let from =
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from);
diff --git a/compiler/rustc_codegen_cranelift/test.sh b/compiler/rustc_codegen_cranelift/test.sh
index a10924628..3d929a1d5 100755
--- a/compiler/rustc_codegen_cranelift/test.sh
+++ b/compiler/rustc_codegen_cranelift/test.sh
@@ -1,13 +1,2 @@
#!/usr/bin/env bash
-set -e
-
-./y.rs build --sysroot none "$@"
-
-rm -r target/out || true
-
-scripts/tests.sh no_sysroot
-
-./y.rs build "$@"
-
-scripts/tests.sh base_sysroot
-scripts/tests.sh extended_sysroot
+exec ./y.rs test
diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs
index 5f66ca67f..89661918d 100644
--- a/compiler/rustc_codegen_gcc/example/alloc_system.rs
+++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs
@@ -156,7 +156,7 @@ mod platform {
struct Header(*mut u8);
const HEAP_ZERO_MEMORY: DWORD = 0x00000008;
unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
- &mut *(ptr as *mut Header).offset(-1)
+ &mut *(ptr as *mut Header).sub(1)
}
unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
let aligned = ptr.add(align - (ptr as usize & (align - 1)));
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 d5fa1cec0..c59a40df0 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
@@ -14,7 +14,6 @@ index 06c7be0..359e2e7 100644
@@ -75,7 +75,6 @@
#![feature(never_type)]
#![feature(unwrap_infallible)]
- #![feature(result_into_ok_or_err)]
-#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(once_cell)]
diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs
index 0ed3e1fbe..848c34211 100644
--- a/compiler/rustc_codegen_gcc/src/abi.rs
+++ b/compiler/rustc_codegen_gcc/src/abi.rs
@@ -107,45 +107,24 @@ pub trait FnAbiGccExt<'gcc, 'tcx> {
impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> (Type<'gcc>, Vec<Type<'gcc>>, bool, FxHashSet<usize>) {
let mut on_stack_param_indices = FxHashSet::default();
- let args_capacity: usize = self.args.iter().map(|arg|
- if arg.pad.is_some() {
- 1
- }
- else {
- 0
- } +
- if let PassMode::Pair(_, _) = arg.mode {
- 2
- } else {
- 1
- }
- ).sum();
+
+ // This capacity calculation is approximate.
let mut argument_tys = Vec::with_capacity(
- if let PassMode::Indirect { .. } = self.ret.mode {
- 1
- }
- else {
- 0
- } + args_capacity,
+ self.args.len() + if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 }
);
let return_ty =
match self.ret.mode {
PassMode::Ignore => cx.type_void(),
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx),
- PassMode::Cast(cast) => cast.gcc_type(cx),
+ PassMode::Cast(ref cast, _) => cast.gcc_type(cx),
PassMode::Indirect { .. } => {
argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
cx.type_void()
}
};
- for arg in &self.args {
- // add padding
- if let Some(ty) = arg.pad {
- argument_tys.push(ty.gcc_type(cx));
- }
-
+ for arg in self.args.iter() {
let arg_ty = match arg.mode {
PassMode::Ignore => continue,
PassMode::Direct(_) => arg.layout.immediate_gcc_type(cx),
@@ -157,7 +136,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Indirect { extra_attrs: Some(_), .. } => {
unimplemented!();
}
- PassMode::Cast(cast) => cast.gcc_type(cx),
+ PassMode::Cast(ref cast, pad_i32) => {
+ // add padding
+ if pad_i32 {
+ argument_tys.push(Reg::i32().gcc_type(cx));
+ }
+ cast.gcc_type(cx)
+ }
PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => {
on_stack_param_indices.insert(argument_tys.len());
arg.memory_ty(cx)
diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs
index f863abdcc..96c773101 100644
--- a/compiler/rustc_codegen_gcc/src/archive.rs
+++ b/compiler/rustc_codegen_gcc/src/archive.rs
@@ -45,6 +45,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
_lib_name: &str,
_dll_imports: &[DllImport],
_tmpdir: &Path,
+ _is_direct_dependency: bool,
) -> PathBuf {
unimplemented!();
}
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 4d40dd099..6994eeb00 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -15,8 +15,11 @@ use gccjit::{
Type,
UnaryOp,
};
+use rustc_apfloat::{ieee, Float, Round, Status};
use rustc_codegen_ssa::MemFlags;
-use rustc_codegen_ssa::common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope};
+use rustc_codegen_ssa::common::{
+ AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind,
+};
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{
@@ -31,6 +34,7 @@ use rustc_codegen_ssa::traits::{
StaticBuilderMethods,
};
use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::bug;
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_span::Span;
@@ -1271,12 +1275,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
val
}
- fn fptoui_sat(&mut self, _val: RValue<'gcc>, _dest_ty: Type<'gcc>) -> Option<RValue<'gcc>> {
- None
+ fn fptoui_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
+ self.fptoint_sat(false, val, dest_ty)
}
- fn fptosi_sat(&mut self, _val: RValue<'gcc>, _dest_ty: Type<'gcc>) -> Option<RValue<'gcc>> {
- None
+ fn fptosi_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
+ self.fptoint_sat(true, val, dest_ty)
}
fn instrprof_increment(&mut self, _fn_name: RValue<'gcc>, _hash: RValue<'gcc>, _num_counters: RValue<'gcc>, _index: RValue<'gcc>) {
@@ -1285,6 +1289,166 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
}
impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
+ fn fptoint_sat(&mut self, signed: bool, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
+ let src_ty = self.cx.val_ty(val);
+ let (float_ty, int_ty) = if self.cx.type_kind(src_ty) == TypeKind::Vector {
+ assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty));
+ (self.cx.element_type(src_ty), self.cx.element_type(dest_ty))
+ } else {
+ (src_ty, dest_ty)
+ };
+
+ // FIXME(jistone): the following was originally the fallback SSA implementation, before LLVM 13
+ // added native `fptosi.sat` and `fptoui.sat` conversions, but it was used by GCC as well.
+ // Now that LLVM always relies on its own, the code has been moved to GCC, but the comments are
+ // still LLVM-specific. This should be updated, and use better GCC specifics if possible.
+
+ let int_width = self.cx.int_width(int_ty);
+ let float_width = self.cx.float_width(float_ty);
+ // LLVM's fpto[su]i returns undef when the input val is infinite, NaN, or does not fit into the
+ // destination integer type after rounding towards zero. This `undef` value can cause UB in
+ // safe code (see issue #10184), so we implement a saturating conversion on top of it:
+ // Semantically, the mathematical value of the input is rounded towards zero to the next
+ // mathematical integer, and then the result is clamped into the range of the destination
+ // integer type. Positive and negative infinity are mapped to the maximum and minimum value of
+ // the destination integer type. NaN is mapped to 0.
+ //
+ // Define f_min and f_max as the largest and smallest (finite) floats that are exactly equal to
+ // a value representable in int_ty.
+ // They are exactly equal to int_ty::{MIN,MAX} if float_ty has enough significand bits.
+ // Otherwise, int_ty::MAX must be rounded towards zero, as it is one less than a power of two.
+ // int_ty::MIN, however, is either zero or a negative power of two and is thus exactly
+ // representable. Note that this only works if float_ty's exponent range is sufficiently large.
+ // f16 or 256 bit integers would break this property. Right now the smallest float type is f32
+ // with exponents ranging up to 127, which is barely enough for i128::MIN = -2^127.
+ // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
+ // we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
+ // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
+ let int_max = |signed: bool, int_width: u64| -> u128 {
+ let shift_amount = 128 - int_width;
+ if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount }
+ };
+ let int_min = |signed: bool, int_width: u64| -> i128 {
+ if signed { i128::MIN >> (128 - int_width) } else { 0 }
+ };
+
+ let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) {
+ let rounded_min =
+ ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero);
+ assert_eq!(rounded_min.status, Status::OK);
+ let rounded_max =
+ ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero);
+ assert!(rounded_max.value.is_finite());
+ (rounded_min.value.to_bits(), rounded_max.value.to_bits())
+ };
+ let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) {
+ let rounded_min =
+ ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero);
+ assert_eq!(rounded_min.status, Status::OK);
+ let rounded_max =
+ ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero);
+ assert!(rounded_max.value.is_finite());
+ (rounded_min.value.to_bits(), rounded_max.value.to_bits())
+ };
+ // To implement saturation, we perform the following steps:
+ //
+ // 1. Cast val to an integer with fpto[su]i. This may result in undef.
+ // 2. Compare val to f_min and f_max, and use the comparison results to select:
+ // a) int_ty::MIN if val < f_min or val is NaN
+ // b) int_ty::MAX if val > f_max
+ // c) the result of fpto[su]i otherwise
+ // 3. If val is NaN, return 0.0, otherwise return the result of step 2.
+ //
+ // This avoids resulting undef because values in range [f_min, f_max] by definition fit into the
+ // destination type. It creates an undef temporary, but *producing* undef is not UB. Our use of
+ // undef does not introduce any non-determinism either.
+ // More importantly, the above procedure correctly implements saturating conversion.
+ // Proof (sketch):
+ // If val is NaN, 0 is returned by definition.
+ // Otherwise, val is finite or infinite and thus can be compared with f_min and f_max.
+ // This yields three cases to consider:
+ // (1) if val in [f_min, f_max], the result of fpto[su]i is returned, which agrees with
+ // saturating conversion for inputs in that range.
+ // (2) if val > f_max, then val is larger than int_ty::MAX. This holds even if f_max is rounded
+ // (i.e., if f_max < int_ty::MAX) because in those cases, nextUp(f_max) is already larger
+ // than int_ty::MAX. Because val is larger than int_ty::MAX, the return value of int_ty::MAX
+ // is correct.
+ // (3) if val < f_min, then val is smaller than int_ty::MIN. As shown earlier, f_min exactly equals
+ // int_ty::MIN and therefore the return value of int_ty::MIN is correct.
+ // QED.
+
+ let float_bits_to_llval = |bx: &mut Self, bits| {
+ let bits_llval = match float_width {
+ 32 => bx.cx().const_u32(bits as u32),
+ 64 => bx.cx().const_u64(bits as u64),
+ n => bug!("unsupported float width {}", n),
+ };
+ bx.bitcast(bits_llval, float_ty)
+ };
+ let (f_min, f_max) = match float_width {
+ 32 => compute_clamp_bounds_single(signed, int_width),
+ 64 => compute_clamp_bounds_double(signed, int_width),
+ n => bug!("unsupported float width {}", n),
+ };
+ let f_min = float_bits_to_llval(self, f_min);
+ let f_max = float_bits_to_llval(self, f_max);
+ let int_max = self.cx.const_uint_big(int_ty, int_max(signed, int_width));
+ let int_min = self.cx.const_uint_big(int_ty, int_min(signed, int_width) as u128);
+ let zero = self.cx.const_uint(int_ty, 0);
+
+ // If we're working with vectors, constants must be "splatted": the constant is duplicated
+ // into each lane of the vector. The algorithm stays the same, we are just using the
+ // same constant across all lanes.
+ let maybe_splat = |bx: &mut Self, val| {
+ if bx.cx().type_kind(dest_ty) == TypeKind::Vector {
+ bx.vector_splat(bx.vector_length(dest_ty), val)
+ } else {
+ val
+ }
+ };
+ let f_min = maybe_splat(self, f_min);
+ let f_max = maybe_splat(self, f_max);
+ let int_max = maybe_splat(self, int_max);
+ let int_min = maybe_splat(self, int_min);
+ let zero = maybe_splat(self, zero);
+
+ // Step 1 ...
+ let fptosui_result = if signed { self.fptosi(val, dest_ty) } else { self.fptoui(val, dest_ty) };
+ let less_or_nan = self.fcmp(RealPredicate::RealULT, val, f_min);
+ let greater = self.fcmp(RealPredicate::RealOGT, val, f_max);
+
+ // Step 2: We use two comparisons and two selects, with %s1 being the
+ // result:
+ // %less_or_nan = fcmp ult %val, %f_min
+ // %greater = fcmp olt %val, %f_max
+ // %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result
+ // %s1 = select %greater, int_ty::MAX, %s0
+ // Note that %less_or_nan uses an *unordered* comparison. This
+ // comparison is true if the operands are not comparable (i.e., if val is
+ // NaN). The unordered comparison ensures that s1 becomes int_ty::MIN if
+ // val is NaN.
+ //
+ // Performance note: Unordered comparison can be lowered to a "flipped"
+ // comparison and a negation, and the negation can be merged into the
+ // select. Therefore, it not necessarily any more expensive than an
+ // ordered ("normal") comparison. Whether these optimizations will be
+ // performed is ultimately up to the backend, but at least x86 does
+ // perform them.
+ let s0 = self.select(less_or_nan, int_min, fptosui_result);
+ let s1 = self.select(greater, int_max, s0);
+
+ // Step 3: NaN replacement.
+ // For unsigned types, the above step already yielded int_ty::MIN == 0 if val is NaN.
+ // Therefore we only need to execute this step for signed integer types.
+ if signed {
+ // LLVM has no isNaN predicate, so we use (val == val) instead
+ let cmp = self.fcmp(RealPredicate::RealOEQ, val, val);
+ self.select(cmp, s1, zero)
+ } else {
+ s1
+ }
+ }
+
#[cfg(feature="master")]
pub fn shuffle_vector(&mut self, v1: RValue<'gcc>, v2: RValue<'gcc>, mask: RValue<'gcc>) -> RValue<'gcc> {
let struct_type = mask.get_type().is_struct().expect("mask of struct type");
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index ccb6cbbc2..aa1c271c3 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -158,10 +158,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
None
}
- fn zst_to_backend(&self, _ty: Type<'gcc>) -> RValue<'gcc> {
- self.const_undef(self.type_ix(0))
- }
-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
match cv {
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index c0b8d2181..356c03ee3 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -127,7 +127,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
//
// We could remove this hack whenever we decide to drop macOS 10.10 support.
if self.tcx.sess.target.options.is_like_osx {
- // The `inspect` method is okay here because we checked relocations, and
+ // The `inspect` method is okay here because we checked for provenance, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).
//
@@ -296,17 +296,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAllocation<'tcx>) -> RValue<'gcc> {
let alloc = alloc.inner();
- let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
+ let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1);
let dl = cx.data_layout();
let pointer_size = dl.pointer_size.bytes() as usize;
let mut next_offset = 0;
- for &(offset, alloc_id) in alloc.relocations().iter() {
+ for &(offset, alloc_id) in alloc.provenance().iter() {
let offset = offset.bytes();
assert_eq!(offset as usize as u64, offset);
let offset = offset as usize;
if offset > next_offset {
- // This `inspect` is okay since we have checked that it is not within a relocation, it
+ // This `inspect` is okay since we have checked that it is not within a pointer with provenance, it
// is within the bounds of the allocation, and it doesn't affect interpreter execution
// (we inspect the result after interpreter execution). Any undef byte is replaced with
// some arbitrary byte value.
@@ -319,7 +319,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
read_target_uint( dl.endian,
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
// affect interpreter execution (we inspect the result after interpreter execution),
- // and we properly interpret the relocation as a relocation pointer offset.
+ // and we properly interpret the provenance as a relocation pointer offset.
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
)
.expect("const_alloc_to_llvm: could not read relocation pointer")
@@ -336,7 +336,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
}
if alloc.len() >= next_offset {
let range = next_offset..alloc.len();
- // This `inspect` is okay since we have check that it is after all relocations, it is
+ // This `inspect` is okay since we have check that it is after all provenance, it is
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
// inspect the result after interpreter execution). Any undef byte is replaced with some
// arbitrary byte value.
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 5fbdedac0..02cedd464 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -130,7 +130,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0);
let mut ptr = args[0].immediate();
- if let PassMode::Cast(ty) = fn_abi.ret.mode {
+ if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
}
let load = self.volatile_load(ptr.get_type(), ptr);
@@ -309,6 +309,18 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
return;
}
+ sym::ptr_mask => {
+ let usize_type = self.context.new_type::<usize>();
+ let void_ptr_type = self.context.new_type::<*const ()>();
+
+ let ptr = args[0].immediate();
+ let mask = args[1].immediate();
+
+ let addr = self.bitcast(ptr, usize_type);
+ let masked = self.and(addr, mask);
+ self.bitcast(masked, void_ptr_type)
+ },
+
_ if name_str.starts_with("simd_") => {
match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
Ok(llval) => llval,
@@ -320,7 +332,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
};
if !fn_abi.ret.is_ignore() {
- if let PassMode::Cast(ty) = fn_abi.ret.mode {
+ if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
let ptr_llty = self.type_ptr_to(ty.gcc_type(self));
let ptr = self.pointercast(result.llval, ptr_llty);
self.store(llval, ptr, result.align);
@@ -416,7 +428,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
else if self.is_unsized_indirect() {
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
}
- else if let PassMode::Cast(cast) = self.mode {
+ else if let PassMode::Cast(ref cast, _) = self.mode {
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
let can_store_through_cast_ptr = false;
@@ -481,7 +493,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
PassMode::Indirect { extra_attrs: Some(_), .. } => {
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
},
- PassMode::Direct(_) | PassMode::Indirect { extra_attrs: None, .. } | PassMode::Cast(_) => {
+ PassMode::Direct(_) | PassMode::Indirect { extra_attrs: None, .. } | PassMode::Cast(..) => {
let next_arg = next();
self.store(bx, next_arg, dst);
},
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 8a206c036..223466fb9 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -19,6 +19,7 @@
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
+extern crate rustc_apfloat;
extern crate rustc_ast;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index f9a5463ef..74115353a 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -13,6 +13,7 @@ cstr = "0.2"
libc = "0.2"
libloading = "0.7.1"
measureme = "10.0.0"
+object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] }
tracing = "0.1"
rustc_middle = { path = "../rustc_middle" }
rustc-demangle = "0.1.21"
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 9eb3574e7..26f5225f6 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -19,6 +19,7 @@ use rustc_target::abi::call::ArgAbi;
pub use rustc_target::abi::call::*;
use rustc_target::abi::{self, HasDataLayout, Int};
pub use rustc_target::spec::abi::Abi;
+use rustc_target::spec::SanitizerSet;
use libc::c_uint;
use smallvec::SmallVec;
@@ -90,6 +91,13 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
if regular.contains(ArgAttribute::NoAliasMutRef) && should_use_mutable_noalias(cx) {
attrs.push(llvm::AttributeKind::NoAlias.create_attr(cx.llcx));
}
+ } else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
+ // If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
+ // memory sanitizer's behavior.
+
+ if regular.contains(ArgAttribute::NoUndef) {
+ attrs.push(llvm::AttributeKind::NoUndef.create_attr(cx.llcx));
+ }
}
attrs
@@ -213,7 +221,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst)
} else if self.is_unsized_indirect() {
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
- } else if let PassMode::Cast(cast) = self.mode {
+ } else if let PassMode::Cast(cast, _) = &self.mode {
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
let can_store_through_cast_ptr = false;
@@ -283,7 +291,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
}
PassMode::Direct(_)
| PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ }
- | PassMode::Cast(_) => {
+ | PassMode::Cast(..) => {
let next_arg = next();
self.store(bx, next_arg, dst);
}
@@ -325,20 +333,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
// Ignore "extra" args from the call site for C variadic functions.
// Only the "fixed" args are part of the LLVM function signature.
- let args = if self.c_variadic { &self.args[..self.fixed_count] } else { &self.args };
+ let args =
+ if self.c_variadic { &self.args[..self.fixed_count as usize] } else { &self.args };
- let args_capacity: usize = args.iter().map(|arg|
- if arg.pad.is_some() { 1 } else { 0 } +
- if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
- ).sum();
+ // This capacity calculation is approximate.
let mut llargument_tys = Vec::with_capacity(
- if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } + args_capacity,
+ self.args.len() + if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 },
);
- let llreturn_ty = match self.ret.mode {
+ let llreturn_ty = match &self.ret.mode {
PassMode::Ignore => cx.type_void(),
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx),
- PassMode::Cast(cast) => cast.llvm_type(cx),
+ PassMode::Cast(cast, _) => cast.llvm_type(cx),
PassMode::Indirect { .. } => {
llargument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
cx.type_void()
@@ -346,12 +352,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
};
for arg in args {
- // add padding
- if let Some(ty) = arg.pad {
- llargument_tys.push(ty.llvm_type(cx));
- }
-
- let llarg_ty = match arg.mode {
+ let llarg_ty = match &arg.mode {
PassMode::Ignore => continue,
PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx),
PassMode::Pair(..) => {
@@ -366,7 +367,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 1, true));
continue;
}
- PassMode::Cast(cast) => cast.llvm_type(cx),
+ PassMode::Cast(cast, pad_i32) => {
+ // add padding
+ if *pad_i32 {
+ llargument_tys.push(Reg::i32().llvm_type(cx));
+ }
+ cast.llvm_type(cx)
+ }
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
cx.type_ptr_to(arg.memory_ty(cx))
}
@@ -426,46 +433,46 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
i += 1;
i - 1
};
- match self.ret.mode {
- PassMode::Direct(ref attrs) => {
+ match &self.ret.mode {
+ PassMode::Direct(attrs) => {
attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
}
- PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
+ PassMode::Indirect { attrs, extra_attrs: _, on_stack } => {
assert!(!on_stack);
let i = apply(attrs);
let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx));
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
}
- PassMode::Cast(cast) => {
+ PassMode::Cast(cast, _) => {
cast.attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
}
_ => {}
}
- for arg in &self.args {
- if arg.pad.is_some() {
- apply(&ArgAttributes::new());
- }
- match arg.mode {
+ for arg in self.args.iter() {
+ match &arg.mode {
PassMode::Ignore => {}
- PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => {
+ PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
let i = apply(attrs);
let byval = llvm::CreateByValAttr(cx.llcx, arg.layout.llvm_type(cx));
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]);
}
- PassMode::Direct(ref attrs)
- | PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => {
+ PassMode::Direct(attrs)
+ | PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
apply(attrs);
}
- PassMode::Indirect { ref attrs, extra_attrs: Some(ref extra_attrs), on_stack } => {
+ PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
assert!(!on_stack);
apply(attrs);
apply(extra_attrs);
}
- PassMode::Pair(ref a, ref b) => {
+ PassMode::Pair(a, b) => {
apply(a);
apply(b);
}
- PassMode::Cast(cast) => {
+ PassMode::Cast(cast, pad_i32) => {
+ if *pad_i32 {
+ apply(&ArgAttributes::new());
+ }
apply(&cast.attrs);
}
}
@@ -488,17 +495,17 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
i += 1;
i - 1
};
- match self.ret.mode {
- PassMode::Direct(ref attrs) => {
+ match &self.ret.mode {
+ PassMode::Direct(attrs) => {
attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, bx.cx, callsite);
}
- PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
+ PassMode::Indirect { attrs, extra_attrs: _, on_stack } => {
assert!(!on_stack);
let i = apply(bx.cx, attrs);
let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx));
attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[sret]);
}
- PassMode::Cast(cast) => {
+ PassMode::Cast(cast, _) => {
cast.attrs.apply_attrs_to_callsite(
llvm::AttributePlace::ReturnValue,
&bx.cx,
@@ -517,13 +524,10 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}
}
}
- for arg in &self.args {
- if arg.pad.is_some() {
- apply(bx.cx, &ArgAttributes::new());
- }
- match arg.mode {
+ for arg in self.args.iter() {
+ match &arg.mode {
PassMode::Ignore => {}
- PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => {
+ PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
let i = apply(bx.cx, attrs);
let byval = llvm::CreateByValAttr(bx.cx.llcx, arg.layout.llvm_type(bx));
attributes::apply_to_callsite(
@@ -532,23 +536,22 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
&[byval],
);
}
- PassMode::Direct(ref attrs)
- | PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => {
+ PassMode::Direct(attrs)
+ | PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
apply(bx.cx, attrs);
}
- PassMode::Indirect {
- ref attrs,
- extra_attrs: Some(ref extra_attrs),
- on_stack: _,
- } => {
+ PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack: _ } => {
apply(bx.cx, attrs);
apply(bx.cx, extra_attrs);
}
- PassMode::Pair(ref a, ref b) => {
+ PassMode::Pair(a, b) => {
apply(bx.cx, a);
apply(bx.cx, b);
}
- PassMode::Cast(cast) => {
+ PassMode::Cast(cast, pad_i32) => {
+ if *pad_i32 {
+ apply(bx.cx, &ArgAttributes::new());
+ }
apply(bx.cx, &cast.attrs);
}
}
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index a53946995..5202ac697 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -3,7 +3,6 @@ use crate::builder::Builder;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm;
-use crate::llvm_util;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
@@ -20,7 +19,6 @@ use rustc_target::asm::*;
use libc::{c_char, c_uint};
use smallvec::SmallVec;
-use tracing::debug;
impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
fn codegen_inline_asm(
@@ -419,13 +417,6 @@ pub(crate) fn inline_asm_call<'ll>(
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr().cast(), cons.len());
debug!("constraint verification result: {:?}", constraints_ok);
if constraints_ok {
- if unwind && llvm_util::get_version() < (13, 0, 0) {
- bx.cx.sess().span_fatal(
- line_spans[0],
- "unwinding from inline assembly is only supported on llvm >= 13.",
- );
- }
-
let v = llvm::LLVMRustInlineAsm(
fty,
asm.as_ptr().cast(),
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index aabbe8ac2..eff2436d4 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -35,6 +35,10 @@ pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attrib
/// Get LLVM attribute for the provided inline heuristic.
#[inline]
fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll Attribute> {
+ if !cx.tcx.sess.opts.unstable_opts.inline_llvm {
+ // disable LLVM inlining
+ return Some(AttributeKind::NoInline.create_attr(cx.llcx));
+ }
match inline {
InlineAttr::Hint => Some(AttributeKind::InlineHint.create_attr(cx.llcx)),
InlineAttr::Always => Some(AttributeKind::AlwaysInline.create_attr(cx.llcx)),
@@ -386,7 +390,8 @@ pub fn from_fn_attrs<'ll, 'tcx>(
) {
let span = cx
.tcx
- .get_attr(instance.def_id(), sym::target_feature)
+ .get_attrs(instance.def_id(), sym::target_feature)
+ .next()
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
let msg = format!(
"the target features {} must all be either enabled or disabled together",
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 27039cda2..ed96355a0 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -8,10 +8,11 @@ use std::path::{Path, PathBuf};
use std::ptr;
use std::str;
+use crate::common;
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
-use rustc_session::cstore::{DllCallingConvention, DllImport};
+use rustc_session::cstore::DllImport;
use rustc_session::Session;
/// Helper for adding many files to an archive.
@@ -103,29 +104,28 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
+ is_direct_dependency: bool,
) -> PathBuf {
+ let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
let output_path = {
let mut output_path: PathBuf = tmpdir.to_path_buf();
- output_path.push(format!("{}_imports", lib_name));
+ output_path.push(format!("{}{}", lib_name, name_suffix));
output_path.with_extension("lib")
};
let target = &sess.target;
- let mingw_gnu_toolchain = target.vendor == "pc"
- && target.os == "windows"
- && target.env == "gnu"
- && target.abi.is_empty();
+ let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(target);
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
.iter()
.map(|import: &DllImport| {
if sess.target.arch == "x86" {
(
- LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain),
- import.ordinal,
+ common::i686_decorated_name(import, mingw_gnu_toolchain, false),
+ import.ordinal(),
)
} else {
- (import.name.to_string(), import.ordinal)
+ (import.name.to_string(), import.ordinal())
}
})
.collect();
@@ -136,7 +136,8 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
- let def_file_path = tmpdir.join(format!("{}_imports", lib_name)).with_extension("def");
+ let def_file_path =
+ tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def");
let def_file_content = format!(
"EXPORTS\n{}",
@@ -159,6 +160,9 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
}
};
+ // --no-leading-underscore: For the `import_name_type` feature to work, we need to be
+ // able to control the *exact* spelling of each of the symbols that are being imported:
+ // hence we don't want `dlltool` adding leading underscores automatically.
let dlltool = find_binutils_dlltool(sess);
let result = std::process::Command::new(dlltool)
.args([
@@ -168,6 +172,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
lib_name,
"-l",
output_path.to_str().unwrap(),
+ "--no-leading-underscore",
])
.output();
@@ -188,10 +193,10 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
- tracing::trace!("invoking LLVMRustWriteImportLibrary");
- tracing::trace!(" dll_name {:#?}", dll_name_z);
- tracing::trace!(" output_path {}", output_path.display());
- tracing::trace!(
+ trace!("invoking LLVMRustWriteImportLibrary");
+ trace!(" dll_name {:#?}", dll_name_z);
+ trace!(" output_path {}", output_path.display());
+ trace!(
" import names: {}",
dll_imports
.iter()
@@ -322,22 +327,6 @@ impl<'a> LlvmArchiveBuilder<'a> {
ret
}
}
-
- fn i686_decorated_name(import: &DllImport, mingw: bool) -> String {
- let name = import.name;
- let prefix = if mingw { "" } else { "_" };
-
- match import.calling_convention {
- DllCallingConvention::C => format!("{}{}", prefix, name),
- DllCallingConvention::Stdcall(arg_list_size) => {
- format!("{}{}@{}", prefix, name, arg_list_size)
- }
- DllCallingConvention::Fastcall(arg_list_size) => format!("@{}@{}", name, arg_list_size),
- DllCallingConvention::Vectorcall(arg_list_size) => {
- format!("{}@@{}", name, arg_list_size)
- }
- }
- }
}
fn string_to_io_error(s: String) -> io::Error {
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 3731c6bcf..a89df00e2 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -1,15 +1,16 @@
use crate::back::write::{
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
};
-use crate::llvm::archive_ro::ArchiveRO;
use crate::llvm::{self, build_string, False, True};
use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
+use object::read::archive::ArchiveFile;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, TargetMachineFactoryConfig};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::memmap::Mmap;
use rustc_errors::{FatalError, Handler};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
@@ -17,7 +18,6 @@ use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{self, CrateType, Lto};
-use tracing::{debug, info};
use std::ffi::{CStr, CString};
use std::fs::File;
@@ -107,14 +107,24 @@ fn prepare_lto(
.extend(exported_symbols[&cnum].iter().filter_map(symbol_filter));
}
- let archive = ArchiveRO::open(path).expect("wanted an rlib");
+ let archive_data = unsafe {
+ Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
+ .expect("couldn't map rlib")
+ };
+ let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let obj_files = archive
- .iter()
- .filter_map(|child| child.ok().and_then(|c| c.name().map(|name| (name, c))))
+ .members()
+ .filter_map(|child| {
+ child.ok().and_then(|c| {
+ std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))
+ })
+ })
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
- match get_bitcode_slice_from_object_data(child.data()) {
+ match get_bitcode_slice_from_object_data(
+ child.data(&*archive_data).expect("corrupt rlib"),
+ ) {
Ok(data) => {
let module = SerializedModule::FromRlib(data.to_vec());
upstream_modules.push((module, CString::new(name).unwrap()));
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 534d32e8a..a695df840 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -5,7 +5,7 @@ use crate::back::profiling::{
use crate::base;
use crate::common;
use crate::consts;
-use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
+use crate::llvm::{self, DiagnosticInfo, PassManager};
use crate::llvm_util;
use crate::type_::Type;
use crate::LlvmCodegenBackend;
@@ -28,7 +28,6 @@ use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::InnerSpan;
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo};
-use tracing::debug;
use libc::{c_char, c_int, c_uint, c_void, size_t};
use std::ffi::CString;
@@ -304,7 +303,6 @@ impl<'a> DiagnosticHandlers<'a> {
remark_passes.as_ptr(),
remark_passes.len(),
);
- llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data.cast());
DiagnosticHandlers { data, llcx, old_handler }
}
}
@@ -312,9 +310,7 @@ impl<'a> DiagnosticHandlers<'a> {
impl<'a> Drop for DiagnosticHandlers<'a> {
fn drop(&mut self) {
- use std::ptr::null_mut;
unsafe {
- llvm::LLVMRustSetInlineAsmDiagnosticHandler(self.llcx, inline_asm_handler, null_mut());
llvm::LLVMRustContextSetDiagnosticHandler(self.llcx, self.old_handler);
drop(Box::from_raw(self.data));
}
@@ -342,16 +338,6 @@ fn report_inline_asm(
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source);
}
-unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) {
- if user.is_null() {
- return;
- }
- let (cgcx, _) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));
-
- let smdiag = llvm::diagnostic::SrcMgrDiagnostic::unpack(diag);
- report_inline_asm(cgcx, smdiag.message, smdiag.level, cookie, smdiag.source);
-}
-
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
if user.is_null() {
return;
@@ -423,6 +409,14 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> {
.map(|path_buf| CString::new(path_buf.to_string_lossy().as_bytes()).unwrap())
}
+fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
+ if config.instrument_coverage {
+ Some(CString::new("default_%m_%p.profraw").unwrap())
+ } else {
+ None
+ }
+}
+
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
cgcx: &CodegenContext<LlvmCodegenBackend>,
diag_handler: &Handler,
@@ -438,6 +432,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
let pgo_use_path = get_pgo_use_path(config);
let pgo_sample_use_path = get_pgo_sample_use_path(config);
let is_lto = opt_stage == llvm::OptStage::ThinLTO || opt_stage == llvm::OptStage::FatLTO;
+ let instr_profile_output_path = get_instr_profile_output_path(config);
// Sanitizer instrumentation is only inserted during the pre-link optimization stage.
let sanitizer_options = if !is_lto {
Some(llvm::SanitizerOptions {
@@ -488,6 +483,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
config.instrument_coverage,
+ instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
config.instrument_gcov,
pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
config.debug_info_for_profiling,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index d3096c73a..63b63c6a1 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -3,7 +3,6 @@ use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm::{self, BasicBlock, False};
use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
-use crate::llvm_util;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
@@ -28,7 +27,6 @@ use std::ffi::CStr;
use std::iter;
use std::ops::Deref;
use std::ptr;
-use tracing::{debug, instrument};
// All Builders must have an llfn associated with them
#[must_use]
@@ -726,11 +724,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) }
}
- fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
+ fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.fptoint_sat(false, val, dest_ty)
}
- fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
+ fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.fptoint_sat(true, val, dest_ty)
}
@@ -1038,25 +1036,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
dst: &'ll Value,
cmp: &'ll Value,
src: &'ll Value,
- mut order: rustc_codegen_ssa::common::AtomicOrdering,
+ order: rustc_codegen_ssa::common::AtomicOrdering,
failure_order: rustc_codegen_ssa::common::AtomicOrdering,
weak: bool,
) -> &'ll Value {
let weak = if weak { llvm::True } else { llvm::False };
- if llvm_util::get_version() < (13, 0, 0) {
- use rustc_codegen_ssa::common::AtomicOrdering::*;
- // Older llvm has the pre-C++17 restriction on
- // success and failure memory ordering,
- // requiring the former to be at least as strong as the latter.
- // So, for llvm 12, we upgrade the success ordering to a stronger
- // one if necessary.
- match (order, failure_order) {
- (Relaxed, Acquire) => order = Acquire,
- (Release, Acquire) => order = AcquireRelease,
- (_, SequentiallyConsistent) => order = SequentiallyConsistent,
- _ => {}
- }
- }
unsafe {
llvm::LLVMRustBuildAtomicCmpXchg(
self.llbuilder,
@@ -1444,51 +1428,32 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
}
}
- fn fptoint_sat_broken_in_llvm(&self) -> bool {
- match self.tcx.sess.target.arch.as_ref() {
- // FIXME - https://bugs.llvm.org/show_bug.cgi?id=50083
- "riscv64" => llvm_util::get_version() < (13, 0, 0),
- _ => false,
- }
- }
-
- fn fptoint_sat(
- &mut self,
- signed: bool,
- val: &'ll Value,
- dest_ty: &'ll Type,
- ) -> Option<&'ll Value> {
- if !self.fptoint_sat_broken_in_llvm() {
- let src_ty = self.cx.val_ty(val);
- let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector
- {
- assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty));
- (
- self.cx.element_type(src_ty),
- self.cx.element_type(dest_ty),
- Some(self.cx.vector_length(src_ty)),
- )
- } else {
- (src_ty, dest_ty, None)
- };
- let float_width = self.cx.float_width(float_ty);
- let int_width = self.cx.int_width(int_ty);
-
- let instr = if signed { "fptosi" } else { "fptoui" };
- let name = if let Some(vector_length) = vector_length {
- format!(
- "llvm.{}.sat.v{}i{}.v{}f{}",
- instr, vector_length, int_width, vector_length, float_width
- )
- } else {
- format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
- };
- let f =
- self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
- Some(self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None))
+ fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ let src_ty = self.cx.val_ty(val);
+ let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector {
+ assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty));
+ (
+ self.cx.element_type(src_ty),
+ self.cx.element_type(dest_ty),
+ Some(self.cx.vector_length(src_ty)),
+ )
} else {
- None
- }
+ (src_ty, dest_ty, None)
+ };
+ let float_width = self.cx.float_width(float_ty);
+ let int_width = self.cx.int_width(int_ty);
+
+ let instr = if signed { "fptosi" } else { "fptoui" };
+ let name = if let Some(vector_length) = vector_length {
+ format!(
+ "llvm.{}.sat.v{}i{}.v{}f{}",
+ instr, vector_length, int_width, vector_length, float_width
+ )
+ } else {
+ format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
+ };
+ let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
+ self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None)
}
pub(crate) fn landing_pad(
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 72155d874..b83c1e8f0 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -6,11 +6,11 @@
use crate::abi::FnAbiLlvmExt;
use crate::attributes;
+use crate::common;
use crate::context::CodegenCx;
use crate::llvm;
use crate::value::Value;
use rustc_codegen_ssa::traits::*;
-use tracing::debug;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
use rustc_middle::ty::{self, Instance, TypeVisitable};
@@ -79,13 +79,18 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
llfn
}
} else {
- let llfn = cx.declare_fn(sym, fn_abi);
+ let instance_def_id = instance.def_id();
+ let llfn = if tcx.sess.target.arch == "x86" &&
+ let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym)
+ {
+ cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi)
+ } else {
+ cx.declare_fn(sym, fn_abi)
+ };
debug!("get_fn: not casting pointer!");
attributes::from_fn_attrs(cx, llfn, instance);
- let instance_def_id = instance.def_id();
-
// Apply an appropriate linkage/visibility value to our item that we
// just declared.
//
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index fb4da9a5f..acee9134f 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -10,13 +10,17 @@ use crate::value::Value;
use rustc_ast::Mutability;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
+use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
+use rustc_middle::ty::TyCtxt;
+use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType};
use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer, Size};
+use rustc_target::spec::Target;
use libc::{c_char, c_uint};
-use tracing::debug;
+use std::fmt::Write;
/*
* A note on nomenclature of linking: "extern", "foreign", and "upcall".
@@ -211,7 +215,11 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
- try_as_const_integral(v).map(|v| unsafe { llvm::LLVMConstIntGetZExtValue(v) })
+ try_as_const_integral(v).and_then(|v| unsafe {
+ let mut i = 0u64;
+ let success = llvm::LLVMRustConstIntGetZExtValue(v, &mut i);
+ success.then_some(i)
+ })
}
fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
@@ -222,10 +230,6 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
})
}
- fn zst_to_backend(&self, _llty: &'ll Type) -> &'ll Value {
- self.const_undef(self.type_ix(0))
- }
-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value {
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
match cv {
@@ -357,3 +361,74 @@ fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 {
fn try_as_const_integral(v: &Value) -> Option<&ConstantInt> {
unsafe { llvm::LLVMIsAConstantInt(v) }
}
+
+pub(crate) fn get_dllimport<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ id: DefId,
+ name: &str,
+) -> Option<&'tcx DllImport> {
+ tcx.native_library(id)
+ .map(|lib| lib.dll_imports.iter().find(|di| di.name.as_str() == name))
+ .flatten()
+}
+
+pub(crate) fn is_mingw_gnu_toolchain(target: &Target) -> bool {
+ target.vendor == "pc" && target.os == "windows" && target.env == "gnu" && target.abi.is_empty()
+}
+
+pub(crate) fn i686_decorated_name(
+ dll_import: &DllImport,
+ mingw: bool,
+ disable_name_mangling: bool,
+) -> String {
+ let name = dll_import.name.as_str();
+
+ let (add_prefix, add_suffix) = match dll_import.import_name_type {
+ Some(PeImportNameType::NoPrefix) => (false, true),
+ Some(PeImportNameType::Undecorated) => (false, false),
+ _ => (true, true),
+ };
+
+ // Worst case: +1 for disable name mangling, +1 for prefix, +4 for suffix (@@__).
+ let mut decorated_name = String::with_capacity(name.len() + 6);
+
+ if disable_name_mangling {
+ // LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled.
+ decorated_name.push('\x01');
+ }
+
+ let prefix = if add_prefix && dll_import.is_fn {
+ match dll_import.calling_convention {
+ DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
+ DllCallingConvention::Stdcall(_) => (!mingw
+ || dll_import.import_name_type == Some(PeImportNameType::Decorated))
+ .then_some('_'),
+ DllCallingConvention::Fastcall(_) => Some('@'),
+ }
+ } else if !dll_import.is_fn && !mingw {
+ // For static variables, prefix with '_' on MSVC.
+ Some('_')
+ } else {
+ None
+ };
+ if let Some(prefix) = prefix {
+ decorated_name.push(prefix);
+ }
+
+ decorated_name.push_str(name);
+
+ if add_suffix && dll_import.is_fn {
+ match dll_import.calling_convention {
+ DllCallingConvention::C => {}
+ DllCallingConvention::Stdcall(arg_list_size)
+ | DllCallingConvention::Fastcall(arg_list_size) => {
+ write!(&mut decorated_name, "@{}", arg_list_size).unwrap();
+ }
+ DllCallingConvention::Vectorcall(arg_list_size) => {
+ write!(&mut decorated_name, "@@{}", arg_list_size).unwrap();
+ }
+ }
+ }
+
+ decorated_name
+}
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 18467e370..a559f7f3d 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -1,5 +1,5 @@
use crate::base;
-use crate::common::CodegenCx;
+use crate::common::{self, CodegenCx};
use crate::debuginfo;
use crate::llvm::{self, True};
use crate::llvm_util;
@@ -23,16 +23,15 @@ use rustc_target::abi::{
AddressSpace, Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange,
};
use std::ops::Range;
-use tracing::debug;
pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>) -> &'ll Value {
let alloc = alloc.inner();
- let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
+ let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1);
let dl = cx.data_layout();
let pointer_size = dl.pointer_size.bytes() as usize;
- // Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`,
- // so `range` must be within the bounds of `alloc` and not contain or overlap a relocation.
+ // Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`, so `range`
+ // must be within the bounds of `alloc` and not contain or overlap a pointer provenance.
fn append_chunks_of_init_and_uninit_bytes<'ll, 'a, 'b>(
llvals: &mut Vec<&'ll Value>,
cx: &'a CodegenCx<'ll, 'b>,
@@ -79,12 +78,12 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
}
let mut next_offset = 0;
- for &(offset, alloc_id) in alloc.relocations().iter() {
+ for &(offset, alloc_id) in alloc.provenance().iter() {
let offset = offset.bytes();
assert_eq!(offset as usize as u64, offset);
let offset = offset as usize;
if offset > next_offset {
- // This `inspect` is okay since we have checked that it is not within a relocation, it
+ // This `inspect` is okay since we have checked that there is no provenance, it
// is within the bounds of the allocation, and it doesn't affect interpreter execution
// (we inspect the result after interpreter execution).
append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, next_offset..offset);
@@ -93,7 +92,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
dl.endian,
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
// affect interpreter execution (we inspect the result after interpreter execution),
- // and we properly interpret the relocation as a relocation pointer offset.
+ // and we properly interpret the provenance as a relocation pointer offset.
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
)
.expect("const_alloc_to_llvm: could not read relocation pointer")
@@ -121,7 +120,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
}
if alloc.len() >= next_offset {
let range = next_offset..alloc.len();
- // This `inspect` is okay since we have check that it is after all relocations, it is
+ // This `inspect` is okay since we have check that it is after all provenance, it is
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
// inspect the result after interpreter execution).
append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, range);
@@ -160,7 +159,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
attrs: &CodegenFnAttrs,
ty: Ty<'tcx>,
sym: &str,
- span_def_id: DefId,
+ def_id: DefId,
) -> &'ll Value {
let llty = cx.layout_of(ty).llvm_type(cx);
if let Some(linkage) = attrs.linkage {
@@ -175,7 +174,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
cx.layout_of(mt.ty).llvm_type(cx)
} else {
cx.sess().span_fatal(
- cx.tcx.def_span(span_def_id),
+ cx.tcx.def_span(def_id),
"must have type `*const T` or `*mut T` due to `#[linkage]` attribute",
)
};
@@ -194,7 +193,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
real_name.push_str(sym);
let g2 = cx.define_global(&real_name, llty).unwrap_or_else(|| {
cx.sess().span_fatal(
- cx.tcx.def_span(span_def_id),
+ cx.tcx.def_span(def_id),
&format!("symbol `{}` is already defined", &sym),
)
});
@@ -202,6 +201,10 @@ fn check_and_apply_linkage<'ll, 'tcx>(
llvm::LLVMSetInitializer(g2, g1);
g2
}
+ } else if cx.tcx.sess.target.arch == "x86" &&
+ let Some(dllimport) = common::get_dllimport(cx.tcx, def_id, sym)
+ {
+ cx.declare_global(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&cx.tcx.sess.target), true), llty)
} else {
// Generate an external declaration.
// FIXME(nagisa): investigate whether it can be changed into define_global
@@ -475,7 +478,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
//
// We could remove this hack whenever we decide to drop macOS 10.10 support.
if self.tcx.sess.target.is_like_osx {
- // The `inspect` method is okay here because we checked relocations, and
+ // The `inspect` method is okay here because we checked for provenance, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).
//
@@ -483,7 +486,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
// happens to be zero. Instead, we should only check the value of defined bytes
// and set all undefined bytes to zero if this allocation is headed for the
// BSS.
- let all_bytes_are_zero = alloc.relocations().is_empty()
+ let all_bytes_are_zero = alloc.provenance().is_empty()
&& alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
.iter()
@@ -507,9 +510,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
section.as_str().as_ptr().cast(),
section.as_str().len() as c_uint,
);
- assert!(alloc.relocations().is_empty());
+ assert!(alloc.provenance().is_empty());
- // The `inspect` method is okay here because we checked relocations, and
+ // The `inspect` method is okay here because we checked for provenance, and
// because we are doing this access to inspect the final interpreter state (not
// as part of the interpreter execution).
let bytes =
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 5857b83f6..67ffc7cb9 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -142,17 +142,6 @@ pub unsafe fn create_module<'ll>(
let mut target_data_layout = sess.target.data_layout.to_string();
let llvm_version = llvm_util::get_version();
- if llvm_version < (13, 0, 0) {
- if sess.target.arch == "powerpc64" {
- target_data_layout = target_data_layout.replace("-S128", "");
- }
- if sess.target.arch == "wasm32" {
- target_data_layout = "e-m:e-p:32:32-i64:64-n32:64-S128".to_string();
- }
- if sess.target.arch == "wasm64" {
- target_data_layout = "e-m:e-p:64:64-i64:64-n32:64-S128".to_string();
- }
- }
if llvm_version < (14, 0, 0) {
if sess.target.llvm_target == "i686-pc-windows-msvc"
|| sess.target.llvm_target == "i586-pc-windows-msvc"
@@ -897,6 +886,9 @@ impl<'ll> CodegenCx<'ll, '_> {
ifn!("llvm.dbg.declare", fn(t_metadata, t_metadata) -> void);
ifn!("llvm.dbg.value", fn(t_metadata, t_i64, t_metadata) -> void);
}
+
+ ifn!("llvm.ptrmask", fn(i8p, t_isize) -> i8p);
+
None
}
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 58f391692..0d1df6fb1 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -16,8 +16,6 @@ use rustc_middle::ty::TyCtxt;
use std::ffi::CString;
-use tracing::debug;
-
/// Generates and exports the Coverage Map.
///
/// Rust Coverage Map generation supports LLVM Coverage Mapping Format versions
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 98ba38356..964a632b6 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -28,7 +28,6 @@ use std::cell::RefCell;
use std::ffi::CString;
use std::iter;
-use tracing::debug;
pub mod mapgen;
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index bd84100e0..163ccd946 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -42,7 +42,6 @@ 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_char, c_longlong, c_uint};
use std::borrow::Cow;
@@ -51,7 +50,6 @@ 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 {
@@ -114,6 +112,7 @@ macro_rules! return_if_di_node_created_in_meantime {
}
/// Extract size and alignment from a TyAndLayout.
+#[inline]
fn size_and_align_of<'tcx>(ty_and_layout: TyAndLayout<'tcx>) -> (Size, Align) {
(ty_and_layout.size, ty_and_layout.align.abi)
}
@@ -1499,24 +1498,18 @@ fn vcall_visibility_metadata<'ll, 'tcx>(
// 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
- }
+ | (Lto::No, Visibility::Restricted(_), 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,
+ | (Lto::ThinLocal | Lto::Thin | Lto::Fat, Visibility::Restricted(_), 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
- }
+ (_, Visibility::Restricted(_), true) => VCallVisibility::TranslationUnit,
};
let trait_ref_typeid = typeid_for_trait_ref(cx.tcx, trait_ref);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index d6e2c8ccd..129e336c7 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -1,19 +1,21 @@
use std::borrow::Cow;
use libc::c_uint;
-use rustc_codegen_ssa::debuginfo::{
- type_names::compute_debuginfo_type_name, wants_c_like_enum_debuginfo,
+use rustc_codegen_ssa::{
+ debuginfo::{type_names::compute_debuginfo_type_name, wants_c_like_enum_debuginfo},
+ traits::ConstMethods,
};
+
+use rustc_index::vec::IndexVec;
use rustc_middle::{
bug,
ty::{
self,
layout::{LayoutOf, TyAndLayout},
- util::Discr,
- AdtDef, GeneratorSubsts,
+ AdtDef, GeneratorSubsts, Ty,
},
};
-use rustc_target::abi::{Size, TagEncoding, VariantIdx, Variants};
+use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
use smallvec::smallvec;
use crate::{
@@ -21,9 +23,9 @@ use crate::{
debuginfo::{
metadata::{
build_field_di_node, closure_saved_names_of_captured_variables,
- enums::tag_base_type,
- file_metadata, generator_layout_and_saved_local_names, size_and_align_of,
- type_map::{self, UniqueTypeId},
+ enums::{tag_base_type, DiscrResult},
+ file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node,
+ type_map::{self, Stub, UniqueTypeId},
unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
UNKNOWN_LINE_NUMBER,
},
@@ -35,59 +37,161 @@ use crate::{
},
};
-/// In CPP-like mode, we generate a union of structs for each variant and an
-/// explicit discriminant field roughly equivalent to the following C/C++ code:
+// The names of the associated constants in each variant wrapper struct.
+// These have to match up with the names being used in `intrinsic.natvis`.
+const ASSOC_CONST_DISCR_NAME: &str = "NAME";
+const ASSOC_CONST_DISCR_EXACT: &str = "DISCR_EXACT";
+const ASSOC_CONST_DISCR_BEGIN: &str = "DISCR_BEGIN";
+const ASSOC_CONST_DISCR_END: &str = "DISCR_END";
+
+const ASSOC_CONST_DISCR128_EXACT_LO: &str = "DISCR128_EXACT_LO";
+const ASSOC_CONST_DISCR128_EXACT_HI: &str = "DISCR128_EXACT_HI";
+const ASSOC_CONST_DISCR128_BEGIN_LO: &str = "DISCR128_BEGIN_LO";
+const ASSOC_CONST_DISCR128_BEGIN_HI: &str = "DISCR128_BEGIN_HI";
+const ASSOC_CONST_DISCR128_END_LO: &str = "DISCR128_END_LO";
+const ASSOC_CONST_DISCR128_END_HI: &str = "DISCR128_END_HI";
+
+// The name of the tag field in the top-level union
+const TAG_FIELD_NAME: &str = "tag";
+const TAG_FIELD_NAME_128_LO: &str = "tag128_lo";
+const TAG_FIELD_NAME_128_HI: &str = "tag128_hi";
+
+// We assign a "virtual" discriminant value to the sole variant of
+// a single-variant enum.
+const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0;
+
+/// In CPP-like mode, we generate a union with a field for each variant and an
+/// explicit tag field. The field of each variant has a struct type
+/// that encodes the discrimiant of the variant and it's data layout.
+/// The union also has a nested enumeration type that is only used for encoding
+/// variant names in an efficient way. Its enumerator values do _not_ correspond
+/// to the enum's discriminant values.
+/// It's roughly equivalent to the following C/C++ code:
///
/// ```c
-/// union enum$<{fully-qualified-name}> {
-/// struct {variant 0 name} {
-/// <variant 0 fields>
+/// union enum2$<{fully-qualified-name}> {
+/// struct Variant0 {
+/// struct {name-of-variant-0} {
+/// <variant 0 fields>
+/// } value;
+///
+/// static VariantNames NAME = {name-of-variant-0};
+/// static int_type DISCR_EXACT = {discriminant-of-variant-0};
/// } variant0;
+///
/// <other variant structs>
-/// {name} discriminant;
+///
+/// int_type tag;
+///
+/// enum VariantNames {
+/// <name-of-variant-0> = 0, // The numeric values are variant index,
+/// <name-of-variant-1> = 1, // not discriminant values.
+/// <name-of-variant-2> = 2,
+/// ...
+/// }
/// }
/// ```
///
-/// As you can see, the type name is wrapped `enum$`. This way we can have a
-/// single NatVis rule for handling all enums.
+/// As you can see, the type name is wrapped in `enum2$<_>`. This way we can
+/// have a single NatVis rule for handling all enums. The `2` in `enum2$<_>`
+/// is an encoding version tag, so that debuggers can decide to decode this
+/// differently than the previous `enum$<_>` encoding emitted by earlier
+/// compiler versions.
///
-/// At the LLVM IR level this looks like
+/// Niche-tag enums have one special variant, usually called the
+/// "untagged variant". This variant has a field that
+/// doubles as the tag of the enum. The variant is active when the value of
+/// that field is within a pre-defined range. Therefore the variant struct
+/// has a `DISCR_BEGIN` and `DISCR_END` field instead of `DISCR_EXACT` in
+/// that case. Both `DISCR_BEGIN` and `DISCR_END` are inclusive bounds.
+/// Note that these ranges can wrap around, so that `DISCR_END < DISCR_BEGIN`.
///
-/// ```txt
-/// DW_TAG_union_type (top-level type for enum)
-/// DW_TAG_member (member for variant 1)
-/// DW_TAG_member (member for variant 2)
-/// DW_TAG_member (member for variant 3)
-/// DW_TAG_structure_type (type of variant 1)
-/// DW_TAG_structure_type (type of variant 2)
-/// DW_TAG_structure_type (type of variant 3)
-/// DW_TAG_enumeration_type (type of tag)
-/// ```
+/// Single-variant enums don't actually have a tag field. In this case we
+/// emit a static tag field (that always has the value 0) so we can use the
+/// same representation (and NatVis).
///
-/// The above encoding applies for enums with a direct tag. For niche-tag we have to do things
-/// differently in order to allow a NatVis visualizer to extract all the information needed:
-/// We generate a union of two fields, one for the dataful variant
-/// and one that just points to the discriminant (which is some field within the dataful variant).
-/// We also create a DW_TAG_enumeration_type DIE that contains tag values for the non-dataful
-/// variants and make the discriminant field that type. We then use NatVis to render the enum type
-/// correctly in Windbg/VS. This will generate debuginfo roughly equivalent to the following C:
+/// For niche-layout enums it's possible to have a 128-bit tag. NatVis, VS, and
+/// WinDbg (the main targets for CPP-like debuginfo at the moment) don't support
+/// 128-bit integers, so all values involved get split into two 64-bit fields.
+/// Instead of the `tag` field, we generate two fields `tag128_lo` and `tag128_hi`,
+/// Instead of `DISCR_EXACT`, we generate `DISCR128_EXACT_LO` and `DISCR128_EXACT_HI`,
+/// and so on.
///
-/// ```c
-/// union enum$<{name}, {min niche}, {max niche}, {dataful variant name}> {
-/// struct <dataful variant name> {
-/// <fields in dataful variant>
-/// } dataful_variant;
-/// enum Discriminant$ {
-/// <non-dataful variants>
-/// } discriminant;
+///
+/// The following pseudocode shows how to decode an enum value in a debugger:
+///
+/// ```text
+///
+/// fn find_active_variant(enum_value) -> (VariantName, VariantValue) {
+/// let is_128_bit = enum_value.has_field("tag128_lo");
+///
+/// if !is_128_bit {
+/// // Note: `tag` can be a static field for enums with only one
+/// // inhabited variant.
+/// let tag = enum_value.field("tag").value;
+///
+/// // For each variant, check if it is a match. Only one of them will match,
+/// // so if we find it we can return it immediately.
+/// for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) {
+/// if variant_field.has_field("DISCR_EXACT") {
+/// // This variant corresponds to a single tag value
+/// if variant_field.field("DISCR_EXACT").value == tag {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// } else {
+/// // This is a range variant
+/// let begin = variant_field.field("DISCR_BEGIN");
+/// let end = variant_field.field("DISCR_END");
+///
+/// if is_in_range(tag, begin, end) {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// }
+/// }
+/// } else {
+/// // Basically the same as with smaller tags, we just have to
+/// // stitch the values together.
+/// let tag: u128 = (enum_value.field("tag128_lo").value as u128) |
+/// (enum_value.field("tag128_hi").value as u128 << 64);
+///
+/// for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) {
+/// if variant_field.has_field("DISCR128_EXACT_LO") {
+/// let discr_exact = (variant_field.field("DISCR128_EXACT_LO" as u128) |
+/// (variant_field.field("DISCR128_EXACT_HI") as u128 << 64);
+///
+/// // This variant corresponds to a single tag value
+/// if discr_exact.value == tag {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// } else {
+/// // This is a range variant
+/// let begin = (variant_field.field("DISCR128_BEGIN_LO").value as u128) |
+/// (variant_field.field("DISCR128_BEGIN_HI").value as u128 << 64);
+/// let end = (variant_field.field("DISCR128_END_LO").value as u128) |
+/// (variant_field.field("DISCR128_END_HI").value as u128 << 64);
+///
+/// if is_in_range(tag, begin, end) {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// }
+/// }
+/// }
+///
+/// // We should have found an active variant at this point.
+/// unreachable!();
/// }
-/// ```
///
-/// The NatVis in `intrinsic.natvis` matches on the type name `enum$<*, *, *, *>`
-/// and evaluates `this.discriminant`. If the value is between the min niche and max
-/// niche, then the enum is in the dataful variant and `this.dataful_variant` is
-/// rendered. Otherwise, the enum is in one of the non-dataful variants. In that
-/// case, we just need to render the name of the `this.discriminant` enum.
+/// // Check if a value is within the given range
+/// // (where the range might wrap around the value space)
+/// fn is_in_range(value, start, end) -> bool {
+/// if start < end {
+/// value >= start && value <= end
+/// } else {
+/// value >= start || value <= end
+/// }
+/// }
+///
+/// ```
pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>,
@@ -135,27 +239,28 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
ref variants,
tag_field,
..
- } => build_union_fields_for_direct_tag_enum(
+ } => build_union_fields_for_enum(
cx,
enum_adt_def,
enum_type_and_layout,
enum_type_di_node,
- &mut variants.indices(),
+ variants.indices(),
tag_field,
+ None,
),
Variants::Multiple {
- tag_encoding: TagEncoding::Niche { dataful_variant, .. },
+ tag_encoding: TagEncoding::Niche { untagged_variant, .. },
ref variants,
tag_field,
..
- } => build_union_fields_for_niche_tag_enum(
+ } => build_union_fields_for_enum(
cx,
enum_adt_def,
enum_type_and_layout,
enum_type_di_node,
- dataful_variant,
- &mut variants.indices(),
+ variants.indices(),
tag_field,
+ Some(untagged_variant),
),
}
},
@@ -217,137 +322,344 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
cx,
- enum_type_and_layout.ty,
+ enum_type_and_layout,
enum_type_di_node,
variant_index,
enum_adt_def.variant(variant_index),
variant_layout,
);
- // NOTE: The field name of the union is the same as the variant name, not "variant0".
- let variant_name = enum_adt_def.variant(variant_index).name.as_str();
+ let tag_base_type = cx.tcx.types.u32;
+ let tag_base_type_di_node = type_di_node(cx, tag_base_type);
+ let tag_base_type_align = cx.align_of(tag_base_type);
+
+ let variant_names_type_di_node = build_variant_names_type_di_node(
+ cx,
+ enum_type_di_node,
+ std::iter::once((
+ variant_index,
+ Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
+ )),
+ );
- smallvec![build_field_di_node(
+ let variant_struct_type_wrapper_di_node = build_variant_struct_wrapper_type_di_node(
cx,
+ enum_type_and_layout,
enum_type_di_node,
- variant_name,
- // NOTE: We use the size and align of the entire type, not from variant_layout
- // since the later is sometimes smaller (if it has fewer fields).
- size_and_align_of(enum_type_and_layout),
- Size::ZERO,
- DIFlags::FlagZero,
+ variant_index,
+ None,
variant_struct_type_di_node,
- )]
+ variant_names_type_di_node,
+ tag_base_type_di_node,
+ tag_base_type,
+ DiscrResult::NoDiscriminant,
+ );
+
+ smallvec![
+ build_field_di_node(
+ cx,
+ enum_type_di_node,
+ &variant_union_field_name(variant_index),
+ // NOTE: We use the size and align of the entire type, not from variant_layout
+ // since the later is sometimes smaller (if it has fewer fields).
+ size_and_align_of(enum_type_and_layout),
+ Size::ZERO,
+ DIFlags::FlagZero,
+ variant_struct_type_wrapper_di_node,
+ ),
+ unsafe {
+ llvm::LLVMRustDIBuilderCreateStaticMemberType(
+ DIB(cx),
+ enum_type_di_node,
+ TAG_FIELD_NAME.as_ptr().cast(),
+ TAG_FIELD_NAME.len(),
+ unknown_file_metadata(cx),
+ UNKNOWN_LINE_NUMBER,
+ variant_names_type_di_node,
+ DIFlags::FlagZero,
+ Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)),
+ tag_base_type_align.bits() as u32,
+ )
+ }
+ ]
}
-fn build_union_fields_for_direct_tag_enum<'ll, 'tcx>(
+fn build_union_fields_for_enum<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
enum_adt_def: AdtDef<'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>,
enum_type_di_node: &'ll DIType,
- variant_indices: &mut dyn Iterator<Item = VariantIdx>,
+ variant_indices: impl Iterator<Item = VariantIdx> + Clone,
tag_field: usize,
+ untagged_variant_index: Option<VariantIdx>,
) -> SmallVec<&'ll DIType> {
+ let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
+
+ let variant_names_type_di_node = build_variant_names_type_di_node(
+ cx,
+ enum_type_di_node,
+ variant_indices.clone().map(|variant_index| {
+ let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
+ (variant_index, variant_name)
+ }),
+ );
+
let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices
.map(|variant_index| {
let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
+ let variant_def = enum_adt_def.variant(variant_index);
+
+ let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
+ cx,
+ enum_type_and_layout,
+ enum_type_di_node,
+ variant_index,
+ variant_def,
+ variant_layout,
+ );
+
VariantFieldInfo {
variant_index,
- variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
- cx,
- enum_type_and_layout.ty,
- enum_type_di_node,
- variant_index,
- enum_adt_def.variant(variant_index),
- variant_layout,
- ),
+ variant_struct_type_di_node,
source_info: None,
+ discr: super::compute_discriminant_value(cx, enum_type_and_layout, variant_index),
}
})
.collect();
- let discr_type_name = cx.tcx.item_name(enum_adt_def.did());
- let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
- let discr_type_di_node = super::build_enumeration_type_di_node(
- cx,
- discr_type_name.as_str(),
- tag_base_type,
- &mut enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
- (discr, Cow::from(enum_adt_def.variant(variant_index).name.as_str()))
- }),
- enum_type_di_node,
- );
-
build_union_fields_for_direct_tag_enum_or_generator(
cx,
enum_type_and_layout,
enum_type_di_node,
&variant_field_infos,
- discr_type_di_node,
+ variant_names_type_di_node,
+ tag_base_type,
tag_field,
+ untagged_variant_index,
)
}
-fn build_union_fields_for_niche_tag_enum<'ll, 'tcx>(
+// The base type of the VariantNames DW_AT_enumeration_type is always the same.
+// It has nothing to do with the tag of the enum and just has to be big enough
+// to hold all variant names.
+fn variant_names_enum_base_type<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> Ty<'tcx> {
+ cx.tcx.types.u32
+}
+
+/// This function builds a DW_AT_enumeration_type that contains an entry for
+/// each variant. Note that this has nothing to do with the discriminant. The
+/// numeric value of each enumerator corresponds to the variant index. The
+/// type is only used for efficiently encoding the name of each variant in
+/// debuginfo.
+fn build_variant_names_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
- enum_adt_def: AdtDef<'tcx>,
- enum_type_and_layout: TyAndLayout<'tcx>,
- enum_type_di_node: &'ll DIType,
- dataful_variant_index: VariantIdx,
- variant_indices: &mut dyn Iterator<Item = VariantIdx>,
- tag_field: usize,
-) -> SmallVec<&'ll DIType> {
- let dataful_variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
+ containing_scope: &'ll DIType,
+ variants: impl Iterator<Item = (VariantIdx, Cow<'tcx, str>)>,
+) -> &'ll DIType {
+ // Create an enumerator for each variant.
+ super::build_enumeration_type_di_node(
cx,
- enum_type_and_layout.ty,
- enum_type_di_node,
- dataful_variant_index,
- &enum_adt_def.variant(dataful_variant_index),
- enum_type_and_layout.for_variant(cx, dataful_variant_index),
- );
+ "VariantNames",
+ variant_names_enum_base_type(cx),
+ variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32() as u64)),
+ containing_scope,
+ )
+}
- let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
- // Create an DW_TAG_enumerator for each variant except the dataful one.
- let discr_type_di_node = super::build_enumeration_type_di_node(
+fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
+ cx: &CodegenCx<'ll, 'tcx>,
+ enum_or_generator_type_and_layout: TyAndLayout<'tcx>,
+ enum_or_generator_type_di_node: &'ll DIType,
+ variant_index: VariantIdx,
+ untagged_variant_index: Option<VariantIdx>,
+ variant_struct_type_di_node: &'ll DIType,
+ variant_names_type_di_node: &'ll DIType,
+ tag_base_type_di_node: &'ll DIType,
+ tag_base_type: Ty<'tcx>,
+ discr: DiscrResult,
+) -> &'ll DIType {
+ type_map::build_type_with_children(
cx,
- "Discriminant$",
- tag_base_type,
- &mut variant_indices.filter_map(|variant_index| {
- if let Some(discr_val) =
- super::compute_discriminant_value(cx, enum_type_and_layout, variant_index)
- {
- let discr = Discr { val: discr_val as u128, ty: tag_base_type };
- let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
- Some((discr, variant_name))
- } else {
- debug_assert_eq!(variant_index, dataful_variant_index);
- None
- }
- }),
- enum_type_di_node,
- );
-
- smallvec![
- build_field_di_node(
- cx,
- enum_type_di_node,
- "dataful_variant",
- size_and_align_of(enum_type_and_layout),
- Size::ZERO,
- DIFlags::FlagZero,
- dataful_variant_struct_type_di_node,
- ),
- build_field_di_node(
+ type_map::stub(
cx,
- enum_type_di_node,
- "discriminant",
- cx.size_and_align_of(tag_base_type),
- enum_type_and_layout.fields.offset(tag_field),
+ Stub::Struct,
+ UniqueTypeId::for_enum_variant_struct_type_wrapper(
+ cx.tcx,
+ enum_or_generator_type_and_layout.ty,
+ variant_index,
+ ),
+ &variant_struct_wrapper_type_name(variant_index),
+ // NOTE: We use size and align of enum_type, not from variant_layout:
+ size_and_align_of(enum_or_generator_type_and_layout),
+ Some(enum_or_generator_type_di_node),
DIFlags::FlagZero,
- discr_type_di_node,
),
- ]
+ |cx, wrapper_struct_type_di_node| {
+ enum DiscrKind {
+ Exact(u64),
+ Exact128(u128),
+ Range(u64, u64),
+ Range128(u128, u128),
+ }
+
+ let (tag_base_type_size, tag_base_type_align) = cx.size_and_align_of(tag_base_type);
+ let is_128_bits = tag_base_type_size.bits() > 64;
+
+ let discr = match discr {
+ DiscrResult::NoDiscriminant => DiscrKind::Exact(SINGLE_VARIANT_VIRTUAL_DISR),
+ DiscrResult::Value(discr_val) => {
+ if is_128_bits {
+ DiscrKind::Exact128(discr_val)
+ } else {
+ debug_assert_eq!(discr_val, discr_val as u64 as u128);
+ DiscrKind::Exact(discr_val as u64)
+ }
+ }
+ DiscrResult::Range(min, max) => {
+ assert_eq!(Some(variant_index), untagged_variant_index);
+ if is_128_bits {
+ DiscrKind::Range128(min, max)
+ } else {
+ debug_assert_eq!(min, min as u64 as u128);
+ debug_assert_eq!(max, max as u64 as u128);
+ DiscrKind::Range(min as u64, max as u64)
+ }
+ }
+ };
+
+ let mut fields = SmallVec::new();
+
+ // We always have a field for the value
+ fields.push(build_field_di_node(
+ cx,
+ wrapper_struct_type_di_node,
+ "value",
+ size_and_align_of(enum_or_generator_type_and_layout),
+ Size::ZERO,
+ DIFlags::FlagZero,
+ variant_struct_type_di_node,
+ ));
+
+ let build_assoc_const =
+ |name: &str, type_di_node: &'ll DIType, value: u64, align: Align| unsafe {
+ llvm::LLVMRustDIBuilderCreateStaticMemberType(
+ DIB(cx),
+ wrapper_struct_type_di_node,
+ name.as_ptr().cast(),
+ name.len(),
+ unknown_file_metadata(cx),
+ UNKNOWN_LINE_NUMBER,
+ type_di_node,
+ DIFlags::FlagZero,
+ Some(cx.const_u64(value)),
+ align.bits() as u32,
+ )
+ };
+
+ // We also always have an associated constant for the discriminant value
+ // of the variant.
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_NAME,
+ variant_names_type_di_node,
+ variant_index.as_u32() as u64,
+ cx.align_of(variant_names_enum_base_type(cx)),
+ ));
+
+ // Emit the discriminant value (or range) corresponding to the variant.
+ match discr {
+ DiscrKind::Exact(discr_val) => {
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_EXACT,
+ tag_base_type_di_node,
+ discr_val,
+ tag_base_type_align,
+ ));
+ }
+ DiscrKind::Exact128(discr_val) => {
+ let align = cx.align_of(cx.tcx.types.u64);
+ let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+ let Split128 { hi, lo } = split_128(discr_val);
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_EXACT_LO,
+ type_di_node,
+ lo,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_EXACT_HI,
+ type_di_node,
+ hi,
+ align,
+ ));
+ }
+ DiscrKind::Range(begin, end) => {
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_BEGIN,
+ tag_base_type_di_node,
+ begin,
+ tag_base_type_align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_END,
+ tag_base_type_di_node,
+ end,
+ tag_base_type_align,
+ ));
+ }
+ DiscrKind::Range128(begin, end) => {
+ let align = cx.align_of(cx.tcx.types.u64);
+ let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+ let Split128 { hi: begin_hi, lo: begin_lo } = split_128(begin);
+ let Split128 { hi: end_hi, lo: end_lo } = split_128(end);
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_BEGIN_HI,
+ type_di_node,
+ begin_hi,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_BEGIN_LO,
+ type_di_node,
+ begin_lo,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_END_HI,
+ type_di_node,
+ end_hi,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_END_LO,
+ type_di_node,
+ end_lo,
+ align,
+ ));
+ }
+ }
+
+ fields
+ },
+ NO_GENERICS,
+ )
+ .di_node
+}
+
+struct Split128 {
+ hi: u64,
+ lo: u64,
+}
+
+fn split_128(value: u128) -> Split128 {
+ Split128 { hi: (value >> 64) as u64, lo: value as u64 }
}
fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
@@ -369,6 +681,29 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
let common_upvar_names = closure_saved_names_of_captured_variables(cx.tcx, generator_def_id);
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
+ let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
+
+ let tag_base_type = tag_base_type(cx, generator_type_and_layout);
+
+ let variant_names_type_di_node = build_variant_names_type_di_node(
+ cx,
+ generator_type_di_node,
+ variant_range
+ .clone()
+ .map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))),
+ );
+
+ let discriminants: IndexVec<VariantIdx, DiscrResult> = {
+ let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx);
+ let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
+ IndexVec::with_capacity(variant_count);
+ for (variant_index, discr) in discriminants_iter {
+ // Assert that the index in the IndexMap matches up with the given VariantIdx.
+ assert_eq!(variant_index, discriminants.next_index());
+ discriminants.push(DiscrResult::Value(discr.val));
+ }
+ discriminants
+ };
// Build the type node for each field.
let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range
@@ -391,29 +726,24 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
None
};
- VariantFieldInfo { variant_index, variant_struct_type_di_node, source_info }
+ VariantFieldInfo {
+ variant_index,
+ variant_struct_type_di_node,
+ source_info,
+ discr: discriminants[variant_index],
+ }
})
.collect();
- let tag_base_type = tag_base_type(cx, generator_type_and_layout);
- let discr_type_name = "Discriminant$";
- let discr_type_di_node = super::build_enumeration_type_di_node(
- cx,
- discr_type_name,
- tag_base_type,
- &mut generator_substs
- .discriminants(generator_def_id, cx.tcx)
- .map(|(variant_index, discr)| (discr, GeneratorSubsts::variant_name(variant_index))),
- generator_type_di_node,
- );
-
build_union_fields_for_direct_tag_enum_or_generator(
cx,
generator_type_and_layout,
generator_type_di_node,
&variant_field_infos[..],
- discr_type_di_node,
+ variant_names_type_di_node,
+ tag_base_type,
tag_field,
+ None,
)
}
@@ -425,8 +755,11 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
enum_type_di_node: &'ll DIType,
variant_field_infos: &[VariantFieldInfo<'ll>],
discr_type_di_node: &'ll DIType,
+ tag_base_type: Ty<'tcx>,
tag_field: usize,
+ untagged_variant_index: Option<VariantIdx>,
) -> SmallVec<&'ll DIType> {
+ let tag_base_type_di_node = type_di_node(cx, tag_base_type);
let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
// We create a field in the union for each variant ...
@@ -438,6 +771,19 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
let field_name = variant_union_field_name(variant_member_info.variant_index);
let (size, align) = size_and_align_of(enum_type_and_layout);
+ let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node(
+ cx,
+ enum_type_and_layout,
+ enum_type_di_node,
+ variant_member_info.variant_index,
+ untagged_variant_index,
+ variant_member_info.variant_struct_type_di_node,
+ discr_type_di_node,
+ tag_base_type_di_node,
+ tag_base_type,
+ variant_member_info.discr,
+ );
+
// We use LLVMRustDIBuilderCreateMemberType() member type directly because
// the build_field_di_node() function does not support specifying a source location,
// which is something that we don't do anywhere else.
@@ -456,7 +802,7 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
// Union fields are always at offset zero
Size::ZERO.bits(),
DIFlags::FlagZero,
- variant_member_info.variant_struct_type_di_node,
+ variant_struct_type_wrapper,
)
}
}));
@@ -466,16 +812,53 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
);
- // ... and a field for the discriminant.
- unions_fields.push(build_field_di_node(
- cx,
- enum_type_di_node,
- "discriminant",
- cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
- enum_type_and_layout.fields.offset(tag_field),
- DIFlags::FlagZero,
- discr_type_di_node,
- ));
+ // ... and a field for the tag. If the tag is 128 bits wide, this will actually
+ // be two 64-bit fields.
+ let is_128_bits = cx.size_of(tag_base_type).bits() > 64;
+
+ if is_128_bits {
+ let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+ let size_and_align = cx.size_and_align_of(cx.tcx.types.u64);
+
+ let (lo_offset, hi_offset) = match cx.tcx.data_layout.endian {
+ Endian::Little => (0, 8),
+ Endian::Big => (8, 0),
+ };
+
+ let tag_field_offset = enum_type_and_layout.fields.offset(tag_field).bytes();
+ let lo_offset = Size::from_bytes(tag_field_offset + lo_offset);
+ let hi_offset = Size::from_bytes(tag_field_offset + hi_offset);
+
+ unions_fields.push(build_field_di_node(
+ cx,
+ enum_type_di_node,
+ TAG_FIELD_NAME_128_LO,
+ size_and_align,
+ lo_offset,
+ DIFlags::FlagZero,
+ type_di_node,
+ ));
+
+ unions_fields.push(build_field_di_node(
+ cx,
+ enum_type_di_node,
+ TAG_FIELD_NAME_128_HI,
+ size_and_align,
+ hi_offset,
+ DIFlags::FlagZero,
+ type_di_node,
+ ));
+ } else {
+ unions_fields.push(build_field_di_node(
+ cx,
+ enum_type_di_node,
+ TAG_FIELD_NAME,
+ cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
+ enum_type_and_layout.fields.offset(tag_field),
+ DIFlags::FlagZero,
+ tag_base_type_di_node,
+ ));
+ }
unions_fields
}
@@ -485,6 +868,7 @@ struct VariantFieldInfo<'ll> {
variant_index: VariantIdx,
variant_struct_type_di_node: &'ll DIType,
source_info: Option<(&'ll DIFile, c_uint)>,
+ discr: DiscrResult,
}
fn variant_union_field_name(variant_index: VariantIdx) -> Cow<'static, str> {
@@ -512,3 +896,29 @@ fn variant_union_field_name(variant_index: VariantIdx) -> Cow<'static, str> {
.map(|&s| Cow::from(s))
.unwrap_or_else(|| format!("variant{}", variant_index.as_usize()).into())
}
+
+fn variant_struct_wrapper_type_name(variant_index: VariantIdx) -> Cow<'static, str> {
+ const PRE_ALLOCATED: [&str; 16] = [
+ "Variant0",
+ "Variant1",
+ "Variant2",
+ "Variant3",
+ "Variant4",
+ "Variant5",
+ "Variant6",
+ "Variant7",
+ "Variant8",
+ "Variant9",
+ "Variant10",
+ "Variant11",
+ "Variant12",
+ "Variant13",
+ "Variant14",
+ "Variant15",
+ ];
+
+ PRE_ALLOCATED
+ .get(variant_index.as_usize())
+ .map(|&s| Cow::from(s))
+ .unwrap_or_else(|| format!("Variant{}", variant_index.as_usize()).into())
+}
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index 73e01d045..14044d0f9 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -10,7 +10,6 @@ use rustc_middle::{
ty::{
self,
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
- util::Discr,
AdtDef, GeneratorSubsts, Ty, VariantDef,
},
};
@@ -90,8 +89,11 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
cx,
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
tag_base_type(cx, enum_type_and_layout),
- &mut enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
- (discr, Cow::from(enum_adt_def.variant(variant_index).name.as_str()))
+ enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
+ let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
+ // Is there anything we can do to support 128-bit C-Style enums?
+ let value = discr.val as u64;
+ (name, value)
}),
containing_scope,
),
@@ -152,7 +154,7 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
type_name: &str,
base_type: Ty<'tcx>,
- variants: &mut dyn Iterator<Item = (Discr<'tcx>, Cow<'tcx, str>)>,
+ enumerators: impl Iterator<Item = (Cow<'tcx, str>, u64)>,
containing_scope: &'ll DIType,
) -> &'ll DIType {
let is_unsigned = match base_type.kind() {
@@ -161,18 +163,15 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
_ => bug!("build_enumeration_type_di_node() called with non-integer tag type."),
};
- let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = variants
- .map(|(discr, variant_name)| {
- unsafe {
- Some(llvm::LLVMRustDIBuilderCreateEnumerator(
- DIB(cx),
- variant_name.as_ptr().cast(),
- variant_name.len(),
- // FIXME: what if enumeration has i128 discriminant?
- discr.val as i64,
- is_unsigned,
- ))
- }
+ let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = enumerators
+ .map(|(name, value)| unsafe {
+ Some(llvm::LLVMRustDIBuilderCreateEnumerator(
+ DIB(cx),
+ name.as_ptr().cast(),
+ name.len(),
+ value as i64,
+ is_unsigned,
+ ))
})
.collect();
@@ -247,23 +246,27 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
/// and a DW_TAG_member for each field (but not the discriminant).
fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
- enum_type: Ty<'tcx>,
+ enum_type_and_layout: TyAndLayout<'tcx>,
enum_type_di_node: &'ll DIType,
variant_index: VariantIdx,
variant_def: &VariantDef,
variant_layout: TyAndLayout<'tcx>,
) -> &'ll DIType {
- debug_assert_eq!(variant_layout.ty, enum_type);
+ debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
type_map::build_type_with_children(
cx,
type_map::stub(
cx,
Stub::Struct,
- UniqueTypeId::for_enum_variant_struct_type(cx.tcx, enum_type, variant_index),
+ UniqueTypeId::for_enum_variant_struct_type(
+ cx.tcx,
+ enum_type_and_layout.ty,
+ variant_index,
+ ),
variant_def.name.as_str(),
// NOTE: We use size and align of enum_type, not from variant_layout:
- cx.size_and_align_of(enum_type),
+ size_and_align_of(enum_type_and_layout),
Some(enum_type_di_node),
DIFlags::FlagZero,
),
@@ -290,9 +293,9 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
type_di_node(cx, field_layout.ty),
)
})
- .collect()
+ .collect::<SmallVec<_>>()
},
- |cx| build_generic_type_param_di_nodes(cx, enum_type),
+ |cx| build_generic_type_param_di_nodes(cx, enum_type_and_layout.ty),
)
.di_node
}
@@ -398,39 +401,60 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
.di_node
}
+#[derive(Copy, Clone)]
+enum DiscrResult {
+ NoDiscriminant,
+ Value(u128),
+ Range(u128, u128),
+}
+
+impl DiscrResult {
+ fn opt_single_val(&self) -> Option<u128> {
+ if let Self::Value(d) = *self { Some(d) } else { None }
+ }
+}
+
/// Returns the discriminant value corresponding to the variant index.
///
/// Will return `None` if there is less than two variants (because then the enum won't have)
-/// a tag, and if this is the dataful variant of a niche-layout enum (because then there is no
+/// a tag, and if this is the untagged variant of a niche-layout enum (because then there is no
/// single discriminant value).
fn compute_discriminant_value<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>,
variant_index: VariantIdx,
-) -> Option<u64> {
+) -> DiscrResult {
match enum_type_and_layout.layout.variants() {
- &Variants::Single { .. } => None,
- &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => Some(
- enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val
- as u64,
+ &Variants::Single { .. } => DiscrResult::NoDiscriminant,
+ &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => DiscrResult::Value(
+ enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val,
),
&Variants::Multiple {
- tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant },
+ tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, untagged_variant },
tag,
..
} => {
- if variant_index == dataful_variant {
- None
+ if variant_index == untagged_variant {
+ let valid_range = enum_type_and_layout
+ .for_variant(cx, variant_index)
+ .largest_niche
+ .as_ref()
+ .unwrap()
+ .valid_range;
+
+ let min = valid_range.start.min(valid_range.end);
+ let min = tag.size(cx).truncate(min);
+
+ let max = valid_range.start.max(valid_range.end);
+ let max = tag.size(cx).truncate(max);
+
+ DiscrResult::Range(min, max)
} else {
let value = (variant_index.as_u32() as u128)
.wrapping_sub(niche_variants.start().as_u32() as u128)
.wrapping_add(niche_start);
let value = tag.size(cx).truncate(value);
- // NOTE(eddyb) do *NOT* remove this assert, until
- // we pass the full 128-bit value to LLVM, otherwise
- // truncation will be silent and remain undetected.
- assert_eq!(value as u64 as u128, value);
- Some(value as u64)
+ DiscrResult::Value(value)
}
}
}
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index f1935e0ec..becbccc43 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -88,7 +88,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
variant_name: Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
cx,
- enum_type,
+ enum_type_and_layout,
enum_type_di_node,
variant_index,
enum_adt_def.variant(variant_index),
@@ -378,7 +378,7 @@ fn build_discr_member_di_node<'ll, 'tcx>(
///
/// The DW_AT_discr_value is optional, and is omitted if
/// - This is the only variant of a univariant enum (i.e. their is no discriminant)
-/// - This is the "dataful" variant of a niche-layout enum
+/// - This is the "untagged" variant of a niche-layout enum
/// (where only the other variants are identified by a single value)
///
/// There is only ever a single member, the type of which is a struct that describes the
@@ -413,7 +413,13 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
enum_type_and_layout.size.bits(),
enum_type_and_layout.align.abi.bits() as u32,
Size::ZERO.bits(),
- discr_value.map(|v| cx.const_u64(v)),
+ discr_value.opt_single_val().map(|value| {
+ // NOTE(eddyb) do *NOT* remove this assert, until
+ // we pass the full 128-bit value to LLVM, otherwise
+ // truncation will be silent and remain undetected.
+ assert_eq!(value as u64 as u128, value);
+ cx.const_u64(value as u64)
+ }),
DIFlags::FlagZero,
variant_member_info.variant_struct_type_di_node,
)
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
index ce2f419c4..e30622cbd 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
@@ -47,6 +47,8 @@ pub(super) enum UniqueTypeId<'tcx> {
VariantPart(Ty<'tcx>, private::HiddenZst),
/// The ID for the artificial struct type describing a single enum variant.
VariantStructType(Ty<'tcx>, VariantIdx, private::HiddenZst),
+ /// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode.
+ VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
/// The ID of the artificial type we create for VTables.
VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst),
}
@@ -71,6 +73,15 @@ impl<'tcx> UniqueTypeId<'tcx> {
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
}
+ pub fn for_enum_variant_struct_type_wrapper(
+ tcx: TyCtxt<'tcx>,
+ enum_ty: Ty<'tcx>,
+ variant_idx: VariantIdx,
+ ) -> Self {
+ debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
+ UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
+ }
+
pub fn for_vtable_ty(
tcx: TyCtxt<'tcx>,
self_type: Ty<'tcx>,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index cf591295b..b23fe3fc9 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -39,7 +39,6 @@ use smallvec::SmallVec;
use std::cell::OnceCell;
use std::cell::RefCell;
use std::iter;
-use tracing::debug;
mod create_scope_map;
pub mod gdb;
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
index 8f2436739..a40cfc8b2 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
@@ -6,7 +6,7 @@ use super::CodegenUnitDebugContext;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
use rustc_middle::ty::{self, DefIdTree, Ty};
-use tracing::trace;
+use trace;
use crate::common::CodegenCx;
use crate::llvm;
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index fa0ecd18f..0f663a267 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -22,7 +22,6 @@ use rustc_codegen_ssa::traits::TypeMembershipMethods;
use rustc_middle::ty::Ty;
use rustc_symbol_mangling::typeid::typeid_for_fnabi;
use smallvec::SmallVec;
-use tracing::debug;
/// Declare a function.
///
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 9f3647492..a640de42a 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -71,6 +71,7 @@ fn get_simple_intrinsic<'ll>(
sym::nearbyintf64 => "llvm.nearbyint.f64",
sym::roundf32 => "llvm.round.f32",
sym::roundf64 => "llvm.round.f64",
+ sym::ptr_mask => "llvm.ptrmask",
_ => return None,
};
Some(cx.get_intrinsic(llvm_name))
@@ -161,7 +162,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0);
let ptr = args[0].immediate();
- let load = if let PassMode::Cast(ty) = fn_abi.ret.mode {
+ let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
let llty = ty.llvm_type(self);
let ptr = self.pointercast(ptr, self.type_ptr_to(llty));
self.volatile_load(llty, ptr)
@@ -374,7 +375,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
};
if !fn_abi.ret.is_ignore() {
- if let PassMode::Cast(ty) = fn_abi.ret.mode {
+ if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
let ptr_llty = self.type_ptr_to(ty.llvm_type(self));
let ptr = self.pointercast(result.llval, ptr_llty);
self.store(llval, ptr, result.align);
@@ -1704,6 +1705,97 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
bitwise_red!(simd_reduce_all: vector_reduce_and, true);
bitwise_red!(simd_reduce_any: vector_reduce_or, true);
+ if name == sym::simd_cast_ptr {
+ 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
+ );
+
+ match in_elem.kind() {
+ ty::RawPtr(p) => {
+ let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
+ bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
+ });
+ assert!(!check_sized); // we are in codegen, so we shouldn't see these types
+ require!(metadata.is_unit(), "cannot cast fat pointer `{}`", in_elem)
+ }
+ _ => return_error!("expected pointer, got `{}`", in_elem),
+ }
+ match out_elem.kind() {
+ ty::RawPtr(p) => {
+ let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
+ bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
+ });
+ assert!(!check_sized); // we are in codegen, so we shouldn't see these types
+ require!(metadata.is_unit(), "cannot cast to fat pointer `{}`", out_elem)
+ }
+ _ => return_error!("expected pointer, got `{}`", out_elem),
+ }
+
+ if in_elem == out_elem {
+ return Ok(args[0].immediate());
+ } else {
+ return Ok(bx.pointercast(args[0].immediate(), llret_ty));
+ }
+ }
+
+ if name == sym::simd_expose_addr {
+ 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
+ );
+
+ match in_elem.kind() {
+ ty::RawPtr(_) => {}
+ _ => return_error!("expected pointer, got `{}`", in_elem),
+ }
+ match out_elem.kind() {
+ ty::Uint(ty::UintTy::Usize) => {}
+ _ => return_error!("expected `usize`, got `{}`", out_elem),
+ }
+
+ return Ok(bx.ptrtoint(args[0].immediate(), llret_ty));
+ }
+
+ if name == sym::simd_from_exposed_addr {
+ 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
+ );
+
+ match in_elem.kind() {
+ ty::Uint(ty::UintTy::Usize) => {}
+ _ => return_error!("expected `usize`, got `{}`", in_elem),
+ }
+ match out_elem.kind() {
+ ty::RawPtr(_) => {}
+ _ => return_error!("expected pointer, got `{}`", out_elem),
+ }
+
+ return Ok(bx.inttoptr(args[0].immediate(), llret_ty));
+ }
+
if name == sym::simd_cast || name == sym::simd_as {
require_simd!(ret_ty, "return");
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 636d689a3..42c65e04e 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -7,7 +7,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(hash_raw_entry)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(extern_types)]
#![feature(once_cell)]
#![feature(iter_intersperse)]
@@ -16,6 +16,8 @@
#[macro_use]
extern crate rustc_macros;
+#[macro_use]
+extern crate tracing;
use back::write::{create_informational_target_machine, create_target_machine};
diff --git a/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
index 64db4f746..7d9489702 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
@@ -83,17 +83,6 @@ impl<'a> Child<'a> {
}
}
}
-
- pub fn data(&self) -> &'a [u8] {
- unsafe {
- let mut data_len = 0;
- let data_ptr = super::LLVMRustArchiveChildData(self.raw, &mut data_len);
- if data_ptr.is_null() {
- panic!("failed to read data from archive child");
- }
- slice::from_raw_parts(data_ptr as *const u8, data_len as usize)
- }
- }
}
impl<'a> Drop for Child<'a> {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 3139f93bf..ce27dc5a5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1096,7 +1096,7 @@ extern "C" {
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value;
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value;
pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value;
- pub fn LLVMConstIntGetZExtValue(ConstantVal: &ConstantInt) -> c_ulonglong;
+ pub fn LLVMRustConstIntGetZExtValue(ConstantVal: &ConstantInt, Value: &mut u64) -> bool;
pub fn LLVMRustConstInt128Get(
ConstantVal: &ConstantInt,
SExt: bool,
@@ -2079,6 +2079,19 @@ extern "C" {
Ty: &'a DIType,
) -> &'a DIType;
+ pub fn LLVMRustDIBuilderCreateStaticMemberType<'a>(
+ Builder: &DIBuilder<'a>,
+ Scope: &'a DIDescriptor,
+ Name: *const c_char,
+ NameLen: size_t,
+ File: &'a DIFile,
+ LineNo: c_uint,
+ Ty: &'a DIType,
+ Flags: DIFlags,
+ val: Option<&'a Value>,
+ AlignInBits: u32,
+ ) -> &'a DIDerivedType;
+
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
Builder: &DIBuilder<'a>,
Scope: &'a DIScope,
@@ -2347,6 +2360,7 @@ extern "C" {
PGOGenPath: *const c_char,
PGOUsePath: *const c_char,
InstrumentCoverage: bool,
+ InstrProfileOutput: *const c_char,
InstrumentGCOV: bool,
PGOSampleUsePath: *const c_char,
DebugInfoForProfiling: bool,
@@ -2375,7 +2389,6 @@ extern "C" {
AIR: &ArchiveIterator<'a>,
) -> Option<&'a mut ArchiveChild<'a>>;
pub fn LLVMRustArchiveChildName(ACR: &ArchiveChild<'_>, size: &mut size_t) -> *const c_char;
- pub fn LLVMRustArchiveChildData(ACR: &ArchiveChild<'_>, size: &mut size_t) -> *const c_char;
pub fn LLVMRustArchiveChildFree<'a>(ACR: &'a mut ArchiveChild<'a>);
pub fn LLVMRustArchiveIteratorFree<'a>(AIR: &'a mut ArchiveIterator<'a>);
pub fn LLVMRustDestroyArchive(AR: &'static mut Archive);
@@ -2410,12 +2423,6 @@ extern "C" {
cookie_out: &mut c_uint,
) -> &'a SMDiagnostic;
- pub fn LLVMRustSetInlineAsmDiagnosticHandler(
- C: &Context,
- H: InlineAsmDiagHandlerTy,
- CX: *mut c_void,
- );
-
#[allow(improper_ctypes)]
pub fn LLVMRustUnpackSMDiagnostic(
d: &SMDiagnostic,
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index a0a640473..60707a1c3 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -15,7 +15,6 @@ use rustc_span::symbol::Symbol;
use rustc_target::spec::{MergeFunctions, PanicStrategy};
use smallvec::{smallvec, SmallVec};
use std::ffi::{CStr, CString};
-use tracing::debug;
use std::mem;
use std::path::Path;
@@ -92,16 +91,6 @@ unsafe fn configure_llvm(sess: &Session) {
add("-generate-arange-section", false);
}
- // Disable the machine outliner by default in LLVM versions 11 and LLVM
- // version 12, where it leads to miscompilation.
- //
- // Ref:
- // - https://github.com/rust-lang/rust/issues/85351
- // - https://reviews.llvm.org/D103167
- if llvm_util::get_version() < (13, 0, 0) {
- add("-enable-machine-outliner=never", false);
- }
-
match sess.opts.unstable_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
MergeFunctions::Aliases => {
@@ -165,6 +154,10 @@ pub fn time_trace_profiler_finish(file_name: &Path) {
//
// To find a list of LLVM's names, check llvm-project/llvm/include/llvm/Support/*TargetParser.def
// where the * matches the architecture's name
+//
+// For targets not present in the above location, see llvm-project/llvm/lib/Target/{ARCH}/*.td
+// where `{ARCH}` is the architecture name. Look for instances of `SubtargetFeature`.
+//
// Beware to not use the llvm github project for this, but check the git submodule
// found in src/llvm-project
// Though note that Rust can also be build with an external precompiled version of LLVM
@@ -440,6 +433,8 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
.features
.split(',')
.filter(|v| !v.is_empty() && backend_feature_name(v).is_some())
+ // Drop +atomics-32 feature introduced in LLVM 15.
+ .filter(|v| *v != "+atomics-32" || get_version() >= (15, 0, 0))
.map(String::from),
);
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index 6e9428485..1eceb7f5c 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -11,7 +11,6 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
use rustc_middle::ty::{self, Instance, TypeVisitable};
use rustc_session::config::CrateType;
use rustc_target::spec::RelocModel;
-use tracing::debug;
impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
fn predefine_static(
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 9f0e6c80b..dc1165835 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -11,7 +11,6 @@ use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
use rustc_target::abi::{Int, Pointer, F32, F64};
use rustc_target::abi::{PointeeInfo, Scalar, Size, TyAbiInterface, Variants};
use smallvec::{smallvec, SmallVec};
-use tracing::debug;
use std::fmt::Write;
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 46d6344db..d868e3d56 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -26,7 +26,6 @@ rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
rustc_middle = { path = "../rustc_middle" }
-rustc_apfloat = { path = "../rustc_apfloat" }
rustc_attr = { path = "../rustc_attr" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 0d2aa483d..bb76ca5d2 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -1,44 +1,16 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::memmap::Mmap;
use rustc_session::cstore::DllImport;
use rustc_session::Session;
+use rustc_span::symbol::Symbol;
+use object::read::archive::ArchiveFile;
+
+use std::fmt::Display;
+use std::fs::File;
use std::io;
use std::path::{Path, PathBuf};
-pub(super) fn find_library(
- name: &str,
- verbatim: bool,
- search_paths: &[PathBuf],
- sess: &Session,
-) -> PathBuf {
- // On Windows, static libraries sometimes show up as libfoo.a and other
- // times show up as foo.lib
- let oslibname = if verbatim {
- name.to_string()
- } else {
- format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
- };
- let unixlibname = format!("lib{}.a", name);
-
- for path in search_paths {
- debug!("looking for {} inside {:?}", name, path);
- let test = path.join(&oslibname);
- if test.exists() {
- return test;
- }
- if oslibname != unixlibname {
- let test = path.join(&unixlibname);
- if test.exists() {
- return test;
- }
- }
- }
- sess.fatal(&format!(
- "could not find native static library `{}`, \
- perhaps an -L flag is missing?",
- name
- ));
-}
-
pub trait ArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
@@ -53,7 +25,38 @@ pub trait ArchiveBuilderBuilder {
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
+ is_direct_dependency: bool,
) -> PathBuf;
+
+ fn extract_bundled_libs(
+ &self,
+ rlib: &Path,
+ outdir: &Path,
+ bundled_lib_file_names: &FxHashSet<Symbol>,
+ ) -> Result<(), String> {
+ let message = |msg: &str, e: &dyn Display| format!("{} '{}': {}", msg, &rlib.display(), e);
+ let archive_map = unsafe {
+ Mmap::map(File::open(rlib).map_err(|e| message("failed to open file", &e))?)
+ .map_err(|e| message("failed to mmap file", &e))?
+ };
+ let archive = ArchiveFile::parse(&*archive_map)
+ .map_err(|e| message("failed to parse archive", &e))?;
+
+ for entry in archive.members() {
+ let entry = entry.map_err(|e| message("failed to read entry", &e))?;
+ let data = entry
+ .data(&*archive_map)
+ .map_err(|e| message("failed to get data from archive member", &e))?;
+ let name = std::str::from_utf8(entry.name())
+ .map_err(|e| message("failed to convert name", &e))?;
+ if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
+ continue; // We need to extract only native libraries.
+ }
+ std::fs::write(&outdir.join(&name), data)
+ .map_err(|e| message("failed to write file", &e))?;
+ }
+ Ok(())
+ }
}
pub trait ArchiveBuilder<'a> {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 63207803e..6cce95427 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1,11 +1,13 @@
use rustc_arena::TypedArena;
use rustc_ast::CRATE_NODE_ID;
-use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxIndexMap;
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;
+use rustc_metadata::find_native_static_library;
use rustc_metadata::fs::{emit_metadata, METADATA_FILENAME};
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -20,11 +22,11 @@ use rustc_session::utils::NativeLibKind;
use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
-use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
-use super::archive::{find_library, ArchiveBuilder, ArchiveBuilderBuilder};
+use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use super::command::Command;
use super::linker::{self, Linker};
use super::metadata::{create_rmeta_file, MetadataPosition};
@@ -44,7 +46,7 @@ use std::io::{BufWriter, Write};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
-use std::{ascii, char, env, fmt, fs, io, mem, str};
+use std::{env, fmt, fs, io, mem, str};
pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
if let Err(e) = fs::remove_file(path) {
@@ -307,6 +309,9 @@ fn link_rlib<'a>(
}
}
+ // Used if packed_bundled_libs flag enabled.
+ let mut packed_bundled_libs = Vec::new();
+
// Note that in this loop we are ignoring the value of `lib.cfg`. That is,
// we may not be configured to actually include a static library if we're
// adding it here. That's because later when we consume this rlib we'll
@@ -326,6 +331,8 @@ fn link_rlib<'a>(
for lib in codegen_results.crate_info.used_libraries.iter() {
match lib.kind {
NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
+ if flavor == RlibFlavor::Normal && sess.opts.unstable_opts.packed_bundled_libs => {}
+ NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
if flavor == RlibFlavor::Normal =>
{
// Don't allow mixing +bundle with +whole_archive since an rlib may contain
@@ -348,7 +355,16 @@ fn link_rlib<'a>(
}
if let Some(name) = lib.name {
let location =
- find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
+ find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
+ if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
+ packed_bundled_libs.push(find_native_static_library(
+ lib.filename.unwrap().as_str(),
+ Some(true),
+ &lib_search_paths,
+ sess,
+ ));
+ continue;
+ }
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
sess.fatal(&format!(
"failed to add native library {}: {}",
@@ -360,13 +376,14 @@ fn link_rlib<'a>(
}
for (raw_dylib_name, raw_dylib_imports) in
- collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
+ collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
{
let output_path = archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir.as_ref(),
+ true,
);
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| {
@@ -403,6 +420,12 @@ fn link_rlib<'a>(
ab.add_file(&trailing_metadata);
}
+ // Add all bundled static native library dependencies.
+ // Archives added to the end of .rlib archive, see comment above for the reason.
+ for lib in packed_bundled_libs {
+ ab.add_file(&lib)
+ }
+
return Ok(ab);
}
@@ -412,9 +435,9 @@ fn link_rlib<'a>(
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
/// linker appears to expect only a single import library for each library used, so we need to
/// collate the symbols together by library name before generating the import libraries.
-fn collate_raw_dylibs(
- sess: &Session,
- used_libraries: &[NativeLib],
+fn collate_raw_dylibs<'a, 'b>(
+ sess: &'a Session,
+ used_libraries: impl IntoIterator<Item = &'b NativeLib>,
) -> Result<Vec<(String, Vec<DllImport>)>, ErrorGuaranteed> {
// Use index maps to preserve original order of imports and libraries.
let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
@@ -552,14 +575,6 @@ fn link_staticlib<'a>(
Ok(())
}
-fn escape_stdout_stderr_string(s: &[u8]) -> String {
- str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
- let mut x = "Non-UTF-8 output: ".to_string();
- x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
- x
- })
-}
-
/// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a
/// DWARF package.
fn link_dwarf_object<'a>(
@@ -764,15 +779,15 @@ fn link_natively<'a>(
"Linker does not support -static-pie command line option. Retrying with -static instead."
);
// Mirror `add_(pre,post)_link_objects` to replace CRT objects.
- let self_contained = crt_objects_fallback(sess, crate_type);
+ let self_contained = self_contained(sess, crate_type);
let opts = &sess.target;
let pre_objects = if self_contained {
- &opts.pre_link_objects_fallback
+ &opts.pre_link_objects_self_contained
} else {
&opts.pre_link_objects
};
let post_objects = if self_contained {
- &opts.post_link_objects_fallback
+ &opts.post_link_objects_self_contained
} else {
&opts.post_link_objects
};
@@ -866,7 +881,7 @@ fn link_natively<'a>(
if !prog.status.success() {
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
- let escaped_output = escape_stdout_stderr_string(&output);
+ let escaped_output = escape_string(&output);
let mut err = sess.struct_err(&format!(
"linking with `{}` failed: {}",
linker_path.display(),
@@ -934,8 +949,8 @@ fn link_natively<'a>(
sess.abort_if_errors();
}
- info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr));
- info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout));
+ info!("linker stderr:\n{}", escape_string(&prog.stderr));
+ info!("linker stdout:\n{}", escape_string(&prog.stdout));
}
Err(e) => {
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
@@ -1065,11 +1080,10 @@ fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Opti
}
fn escape_string(s: &[u8]) -> String {
- str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
- let mut x = "Non-UTF-8 output: ".to_string();
- x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
- x
- })
+ match str::from_utf8(s) {
+ Ok(s) => s.to_owned(),
+ Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()),
+ }
}
fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
@@ -1173,13 +1187,6 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// only the linker flavor is known; use the default linker for the selected flavor
(None, Some(flavor)) => Some((
PathBuf::from(match flavor {
- LinkerFlavor::Em => {
- if cfg!(windows) {
- "emcc.bat"
- } else {
- "emcc"
- }
- }
LinkerFlavor::Gcc => {
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
// On historical Solaris systems, "cc" may have
@@ -1194,11 +1201,17 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
}
}
LinkerFlavor::Ld => "ld",
- LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::Lld(_) => "lld",
- LinkerFlavor::PtxLinker => "rust-ptx-linker",
- LinkerFlavor::BpfLinker => "bpf-linker",
- LinkerFlavor::L4Bender => "l4-bender",
+ LinkerFlavor::Msvc => "link.exe",
+ LinkerFlavor::EmCc => {
+ if cfg!(windows) {
+ "emcc.bat"
+ } else {
+ "emcc"
+ }
+ }
+ LinkerFlavor::Bpf => "bpf-linker",
+ LinkerFlavor::Ptx => "rust-ptx-linker",
}),
flavor,
)),
@@ -1208,7 +1221,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
});
let flavor = if stem == "emcc" {
- LinkerFlavor::Em
+ LinkerFlavor::EmCc
} else if stem == "gcc"
|| stem.ends_with("-gcc")
|| stem == "clang"
@@ -1236,7 +1249,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// linker and linker flavor specified via command line have precedence over what the target
// specification specifies
- if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
+ let linker_flavor = sess.opts.cg.linker_flavor.map(LinkerFlavor::from_cli);
+ if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
return ret;
}
@@ -1556,26 +1570,26 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
true
}
-/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
+/// Various toolchain components used during linking are used from rustc distribution
+/// instead of being found somewhere on the host system.
/// We only provide such support for a very limited number of targets.
-fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
+fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
if let Some(self_contained) = sess.opts.cg.link_self_contained {
return self_contained;
}
- match sess.target.crt_objects_fallback {
+ match sess.target.link_self_contained {
+ LinkSelfContainedDefault::False => false,
+ LinkSelfContainedDefault::True => true,
// FIXME: Find a better heuristic for "native musl toolchain is available",
// based on host and linker path, for example.
// (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
- Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
- Some(CrtObjectsFallback::Mingw) => {
+ LinkSelfContainedDefault::Musl => sess.crt_static(Some(crate_type)),
+ LinkSelfContainedDefault::Mingw => {
sess.host == sess.target
&& sess.target.vendor != "uwp"
&& detect_self_contained_mingw(&sess)
}
- // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
- Some(CrtObjectsFallback::Wasm) => true,
- None => false,
}
}
@@ -1583,12 +1597,21 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
fn add_pre_link_objects(
cmd: &mut dyn Linker,
sess: &Session,
+ flavor: LinkerFlavor,
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
+ // FIXME: we are currently missing some infra here (per-linker-flavor CRT objects),
+ // so Fuchsia has to be special-cased.
let opts = &sess.target;
- let objects =
- if self_contained { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects };
+ let empty = Default::default();
+ let objects = if self_contained {
+ &opts.pre_link_objects_self_contained
+ } else if !(sess.target.os == "fuchsia" && flavor == LinkerFlavor::Gcc) {
+ &opts.pre_link_objects
+ } else {
+ &empty
+ };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
cmd.add_object(&get_object_file_path(sess, obj, self_contained));
}
@@ -1601,9 +1624,11 @@ fn add_post_link_objects(
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
- let opts = &sess.target;
- let objects =
- if self_contained { &opts.post_link_objects_fallback } else { &opts.post_link_objects };
+ let objects = if self_contained {
+ &sess.target.post_link_objects_self_contained
+ } else {
+ &sess.target.post_link_objects
+ };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
cmd.add_object(&get_object_file_path(sess, obj, self_contained));
}
@@ -1703,6 +1728,13 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor
/// that are necessary for the linking. They are only present in symbol table but not actually
/// used in any sections, so the linker will therefore pick relevant rlibs for linking, but
/// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections.
+///
+/// There's a few internal crates in the standard library (aka libcore and
+/// libstd) which actually have a circular dependence upon one another. This
+/// currently arises through "weak lang items" where libcore requires things
+/// like `rust_begin_unwind` but libstd ends up defining it. To get this
+/// circular dependence to work correctly we declare some of these things
+/// in this synthetic object.
fn add_linked_symbol_object(
cmd: &mut dyn Linker,
sess: &Session,
@@ -1882,12 +1914,12 @@ fn linker_with_args<'a>(
out_filename: &Path,
codegen_results: &CodegenResults,
) -> Result<Command, ErrorGuaranteed> {
- let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
+ let self_contained = self_contained(sess, crate_type);
let cmd = &mut *super::linker::get_linker(
sess,
path,
flavor,
- crt_objects_fallback,
+ self_contained,
&codegen_results.crate_info.target_cpu,
);
let link_output_kind = link_output_kind(sess, crate_type);
@@ -1914,7 +1946,7 @@ fn linker_with_args<'a>(
// ------------ Object code and libraries, order-dependent ------------
// Pre-link CRT objects.
- add_pre_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
+ add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained);
add_linked_symbol_object(
cmd,
@@ -1947,7 +1979,6 @@ fn linker_with_args<'a>(
// Upstream rust libraries are not supposed to depend on our local native
// libraries as that would violate the structure of the DAG, in that
// scenario they are required to link to them as well in a shared fashion.
- // (The current implementation still doesn't prevent it though, see the FIXME below.)
//
// Note that upstream rust libraries may contain native dependencies as
// well, but they also can't depend on what we just started to add to the
@@ -1968,15 +1999,16 @@ fn linker_with_args<'a>(
// and move this option back to the top.
cmd.add_as_needed();
- // FIXME: Move this below to other native libraries
- // (or alternatively link all native libraries after their respective crates).
- // This change is somewhat breaking in practice due to local static libraries being linked
- // as whole-archive (#85144), so removing whole-archive may be a pre-requisite.
+ // Local native libraries of all kinds.
+ //
+ // If `-Zlink-native-libraries=false` is set, then the assumption is that an
+ // external build system already has the native dependencies defined, and it
+ // will provide them to the linker itself.
if sess.opts.unstable_opts.link_native_libraries {
add_local_native_libraries(cmd, sess, codegen_results);
}
- // Upstream rust libraries and their non-bundled static libraries
+ // Upstream rust libraries and their (possibly bundled) static native libraries.
add_upstream_rust_crates(
cmd,
sess,
@@ -1986,24 +2018,54 @@ fn linker_with_args<'a>(
tmpdir,
);
- // Upstream dynamic native libraries linked with `#[link]` attributes at and `-l`
- // command line options.
- // If -Zlink-native-libraries=false is set, then the assumption is that an
- // external build system already has the native dependencies defined, and it
- // will provide them to the linker itself.
+ // Dynamic native libraries from upstream crates.
+ //
+ // FIXME: Merge this to `add_upstream_rust_crates` so that all native libraries are linked
+ // together with their respective upstream crates, and in their originally specified order.
+ // This may be slightly breaking due to our use of `--as-needed` and needs a crater run.
if sess.opts.unstable_opts.link_native_libraries {
add_upstream_native_libraries(cmd, sess, codegen_results);
}
// Link with the import library generated for any raw-dylib functions.
for (raw_dylib_name, raw_dylib_imports) in
- collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
+ collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
{
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir,
+ true,
+ ));
+ }
+ // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
+ // they are used within inlined functions or instantiated generic functions. We do this *after*
+ // handling the raw-dylib symbols in the current crate to make sure that those are chosen first
+ // by the linker.
+ let (_, dependency_linkage) = codegen_results
+ .crate_info
+ .dependency_formats
+ .iter()
+ .find(|(ty, _)| *ty == crate_type)
+ .expect("failed to find crate type in dependency format list");
+ let native_libraries_from_nonstatics = codegen_results
+ .crate_info
+ .native_libraries
+ .iter()
+ .filter_map(|(cnum, libraries)| {
+ (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries)
+ })
+ .flatten();
+ for (raw_dylib_name, raw_dylib_imports) in
+ collate_raw_dylibs(sess, native_libraries_from_nonstatics)?
+ {
+ cmd.add_object(&archive_builder_builder.create_dll_import_lib(
+ sess,
+ &raw_dylib_name,
+ &raw_dylib_imports,
+ tmpdir,
+ false,
));
}
@@ -2024,7 +2086,7 @@ fn linker_with_args<'a>(
cmd,
sess,
link_output_kind,
- crt_objects_fallback,
+ self_contained,
flavor,
crate_type,
codegen_results,
@@ -2040,7 +2102,7 @@ fn linker_with_args<'a>(
// ------------ Object code and libraries, order-dependent ------------
// Post-link CRT objects.
- add_post_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
+ add_post_link_objects(cmd, sess, link_output_kind, self_contained);
// ------------ Late order-dependent options ------------
@@ -2057,7 +2119,7 @@ fn add_order_independent_options(
cmd: &mut dyn Linker,
sess: &Session,
link_output_kind: LinkOutputKind,
- crt_objects_fallback: bool,
+ self_contained: bool,
flavor: LinkerFlavor,
crate_type: CrateType,
codegen_results: &CodegenResults,
@@ -2070,7 +2132,10 @@ fn add_order_independent_options(
add_link_script(cmd, sess, tmpdir, crate_type);
- if sess.target.os == "fuchsia" && crate_type == CrateType::Executable {
+ if sess.target.os == "fuchsia"
+ && crate_type == CrateType::Executable
+ && flavor != LinkerFlavor::Gcc
+ {
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
"asan/"
} else {
@@ -2086,7 +2151,7 @@ fn add_order_independent_options(
// Make the binary compatible with data execution prevention schemes.
cmd.add_no_exec();
- if crt_objects_fallback {
+ if self_contained {
cmd.no_crt_objects();
}
@@ -2099,11 +2164,11 @@ fn add_order_independent_options(
});
}
- if flavor == LinkerFlavor::PtxLinker {
+ if flavor == LinkerFlavor::Ptx {
// Provide the linker with fallback to internal `target-cpu`.
cmd.arg("--fallback-arch");
cmd.arg(&codegen_results.crate_info.target_cpu);
- } else if flavor == LinkerFlavor::BpfLinker {
+ } else if flavor == LinkerFlavor::Bpf {
cmd.arg("--cpu");
cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.arg("--cpu-features");
@@ -2115,7 +2180,7 @@ fn add_order_independent_options(
cmd.linker_plugin_lto();
- add_library_search_dirs(cmd, sess, crt_objects_fallback);
+ add_library_search_dirs(cmd, sess, self_contained);
cmd.output_filename(out_filename);
@@ -2319,72 +2384,25 @@ fn add_upstream_rust_crates<'a>(
// crates.
let deps = &codegen_results.crate_info.used_crates;
- // There's a few internal crates in the standard library (aka libcore and
- // libstd) which actually have a circular dependence upon one another. This
- // currently arises through "weak lang items" where libcore requires things
- // like `rust_begin_unwind` but libstd ends up defining it. To get this
- // circular dependence to work correctly in all situations we'll need to be
- // sure to correctly apply the `--start-group` and `--end-group` options to
- // GNU linkers, otherwise if we don't use any other symbol from the standard
- // library it'll get discarded and the whole application won't link.
- //
- // In this loop we're calculating the `group_end`, after which crate to
- // pass `--end-group` and `group_start`, before which crate to pass
- // `--start-group`. We currently do this by passing `--end-group` after
- // the first crate (when iterating backwards) that requires a lang item
- // defined somewhere else. Once that's set then when we've defined all the
- // necessary lang items we'll pass `--start-group`.
- //
- // Note that this isn't amazing logic for now but it should do the trick
- // for the current implementation of the standard library.
- let mut group_end = None;
- let mut group_start = None;
- // Crates available for linking thus far.
- let mut available = FxHashSet::default();
- // Crates required to satisfy dependencies discovered so far.
- let mut required = FxHashSet::default();
-
- let info = &codegen_results.crate_info;
- for &cnum in deps.iter().rev() {
- if let Some(missing) = info.missing_lang_items.get(&cnum) {
- let missing_crates = missing.iter().map(|i| info.lang_item_to_crate.get(i).copied());
- required.extend(missing_crates);
- }
-
- required.insert(Some(cnum));
- available.insert(Some(cnum));
-
- if required.len() > available.len() && group_end.is_none() {
- group_end = Some(cnum);
- }
- if required.len() == available.len() && group_end.is_some() {
- group_start = Some(cnum);
- break;
- }
- }
-
- // If we didn't end up filling in all lang items from upstream crates then
- // we'll be filling it in with our crate. This probably means we're the
- // standard library itself, so skip this for now.
- if group_end.is_some() && group_start.is_none() {
- group_end = None;
- }
-
let mut compiler_builtins = None;
let search_path = OnceCell::new();
for &cnum in deps.iter() {
- if group_start == Some(cnum) {
- cmd.group_start();
- }
-
// We may not pass all crates through to the linker. Some crates may
// appear statically in an existing dylib, meaning we'll pick up all the
// symbols from the dylib.
let src = &codegen_results.crate_info.used_crate_source[&cnum];
match data[cnum.as_usize() - 1] {
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
- add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+ add_static_crate(
+ cmd,
+ sess,
+ archive_builder_builder,
+ codegen_results,
+ tmpdir,
+ cnum,
+ &Default::default(),
+ );
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
@@ -2394,17 +2412,41 @@ fn add_upstream_rust_crates<'a>(
}
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Linkage::Static => {
- add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+ let bundled_libs = if sess.opts.unstable_opts.packed_bundled_libs {
+ codegen_results.crate_info.native_libraries[&cnum]
+ .iter()
+ .filter_map(|lib| lib.filename)
+ .collect::<FxHashSet<_>>()
+ } else {
+ Default::default()
+ };
+ add_static_crate(
+ cmd,
+ sess,
+ archive_builder_builder,
+ codegen_results,
+ tmpdir,
+ cnum,
+ &bundled_libs,
+ );
// Link static native libs with "-bundle" modifier only if the crate they originate from
// is being linked statically to the current crate. If it's linked dynamically
// or is an rlib already included via some other dylib crate, the symbols from
// native libs will have already been included in that dylib.
//
- // If -Zlink-native-libraries=false is set, then the assumption is that an
+ // If `-Zlink-native-libraries=false` is set, then the assumption is that an
// external build system already has the native dependencies defined, and it
// will provide them to the linker itself.
if sess.opts.unstable_opts.link_native_libraries {
+ if sess.opts.unstable_opts.packed_bundled_libs {
+ // If rlib contains native libs as archives, unpack them to tmpdir.
+ let rlib = &src.rlib.as_ref().unwrap().0;
+ archive_builder_builder
+ .extract_bundled_libs(rlib, tmpdir, &bundled_libs)
+ .unwrap_or_else(|e| sess.fatal(e));
+ }
+
let mut last = (None, NativeLibKind::Unspecified, None);
for lib in &codegen_results.crate_info.native_libraries[&cnum] {
let Some(name) = lib.name else {
@@ -2437,6 +2479,14 @@ fn add_upstream_rust_crates<'a>(
bundle: Some(false),
whole_archive: Some(false) | None,
} => {
+ // HACK/FIXME: Fixup a circular dependency between libgcc and libc
+ // with glibc. This logic should be moved to the libc crate.
+ if sess.target.os == "linux"
+ && sess.target.env == "gnu"
+ && name == "c"
+ {
+ cmd.link_staticlib("gcc", false);
+ }
cmd.link_staticlib(name, lib.verbatim.unwrap_or(false));
}
NativeLibKind::LinkArg => {
@@ -2446,20 +2496,23 @@ fn add_upstream_rust_crates<'a>(
| NativeLibKind::Framework { .. }
| NativeLibKind::Unspecified
| NativeLibKind::RawDylib => {}
- NativeLibKind::Static {
- bundle: Some(true) | None,
- whole_archive: _,
- } => {}
+ NativeLibKind::Static { bundle: Some(true) | None, whole_archive } => {
+ if sess.opts.unstable_opts.packed_bundled_libs {
+ // If rlib contains native libs as archives, they are unpacked to tmpdir.
+ let path = tmpdir.join(lib.filename.unwrap().as_str());
+ if whole_archive == Some(true) {
+ cmd.link_whole_rlib(&path);
+ } else {
+ cmd.link_rlib(&path);
+ }
+ }
+ }
}
}
}
}
Linkage::Dynamic => add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0),
}
-
- if group_end == Some(cnum) {
- cmd.group_end();
- }
}
// compiler-builtins are always placed last to ensure that they're
@@ -2468,7 +2521,15 @@ fn add_upstream_rust_crates<'a>(
// was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
// is used)
if let Some(cnum) = compiler_builtins {
- add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+ add_static_crate(
+ cmd,
+ sess,
+ archive_builder_builder,
+ codegen_results,
+ tmpdir,
+ cnum,
+ &Default::default(),
+ );
}
// Converts a library file-stem into a cc -l argument
@@ -2501,6 +2562,7 @@ fn add_upstream_rust_crates<'a>(
codegen_results: &CodegenResults,
tmpdir: &Path,
cnum: CrateNum,
+ bundled_lib_file_names: &FxHashSet<Symbol>,
) {
let src = &codegen_results.crate_info.used_crate_source[&cnum];
let cratepath = &src.rlib.as_ref().unwrap().0;
@@ -2529,6 +2591,7 @@ fn add_upstream_rust_crates<'a>(
let dst = tmpdir.join(cratepath.file_name().unwrap());
let name = cratepath.file_name().unwrap().to_str().unwrap();
let name = &name[3..name.len() - 5]; // chop off lib/.rlib
+ let bundled_lib_file_names = bundled_lib_file_names.clone();
sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| {
let canonical_name = name.replace('-', "_");
@@ -2562,6 +2625,15 @@ fn add_upstream_rust_crates<'a>(
let skip_because_lto =
upstream_rust_objects_already_included && is_rust_object && is_builtins;
+ // We skip native libraries because:
+ // 1. This native libraries won't be used from the generated rlib,
+ // so we can throw them away to avoid the copying work.
+ // 2. We can't allow it to be a single remaining entry in archive
+ // as some linkers may complain on that.
+ if bundled_lib_file_names.contains(&Symbol::intern(f)) {
+ return true;
+ }
+
if skip_because_cfg_say_so || skip_because_lto {
return true;
}
@@ -2657,7 +2729,7 @@ fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
}
}
-fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
+pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
match sess.lto() {
config::Lto::Fat => true,
config::Lto::Thin => {
@@ -2674,11 +2746,16 @@ 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" | "watchos")
+ || !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos")
|| (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
{
return;
}
+
+ if os == "macos" && flavor != LinkerFlavor::Lld(LldFlavor::Ld64) {
+ return;
+ }
+
let sdk_name = match (arch.as_ref(), os.as_ref()) {
("aarch64", "tvos") => "appletvos",
("x86_64", "tvos") => "appletvsimulator",
@@ -2694,6 +2771,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
("aarch64", "watchos") => "watchos",
("arm", "watchos") => "watchos",
+ (_, "macos") => "macosx",
_ => {
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
return;
@@ -2777,20 +2855,24 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let LinkerFlavor::Gcc = flavor {
match ld_impl {
LdImpl::Lld => {
- 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()));
+ // Implement the "self-contained" part of -Zgcc-ld
+ // by adding rustc distribution directories to the tool search path.
+ for path in sess.get_tools_search_paths(false) {
+ cmd.arg({
+ let mut arg = OsString::from("-B");
+ arg.push(path.join("gcc-ld"));
+ arg
+ });
+ }
+ // Implement the "linker flavor" part of -Zgcc-ld
+ // by asking cc to use some kind of lld.
+ cmd.arg("-fuse-ld=lld");
+ if sess.target.lld_flavor != LldFlavor::Ld {
+ // Tell clang to use a non-default LLD flavor.
+ // Gcc doesn't understand the target option, but we currently assume
+ // that gcc is not used for Apple and Wasm targets (#97402).
+ cmd.arg(format!("--target={}", sess.target.llvm_target));
+ }
}
}
} else {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index ce51b2e95..e505543b2 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1,4 +1,3 @@
-use super::archive;
use super::command::Command;
use super::symbol_export;
use rustc_span::symbol::sym;
@@ -11,6 +10,7 @@ use std::path::{Path, PathBuf};
use std::{env, mem, str};
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_metadata::find_native_static_library;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
use rustc_middle::ty::TyCtxt;
@@ -126,29 +126,26 @@ pub fn get_linker<'a>(
// to the linker args construction.
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
match flavor {
- LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
- Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
- }
- LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Gcc => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
as Box<dyn Linker>
}
-
+ LinkerFlavor::Ld if sess.target.os == "l4re" => {
+ Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
+ }
LinkerFlavor::Lld(LldFlavor::Ld)
| LinkerFlavor::Lld(LldFlavor::Ld64)
| LinkerFlavor::Ld => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
as Box<dyn Linker>
}
-
+ LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
+ Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
+ }
LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
-
- LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
-
- LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
-
- LinkerFlavor::L4Bender => Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>,
+ LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
+ LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
+ LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
}
}
@@ -186,8 +183,6 @@ pub trait Linker {
fn no_default_libraries(&mut self);
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
fn subsystem(&mut self, subsystem: &str);
- fn group_start(&mut self);
- fn group_end(&mut self);
fn linker_plugin_lto(&mut self);
fn add_eh_frame_header(&mut self) {}
fn add_no_exec(&mut self) {}
@@ -519,7 +514,7 @@ impl<'a> Linker for GccLinker<'a> {
// -force_load is the macOS equivalent of --whole-archive, but it
// involves passing the full path to the library to link.
self.linker_arg("-force_load");
- let lib = archive::find_library(lib, verbatim, search_path, &self.sess);
+ let lib = find_native_static_library(lib, Some(verbatim), search_path, &self.sess);
self.linker_arg(&lib);
}
}
@@ -733,18 +728,6 @@ impl<'a> Linker for GccLinker<'a> {
self.hint_dynamic(); // Reset to default before returning the composed command line.
}
- fn group_start(&mut self) {
- if self.takes_hints() {
- self.linker_arg("--start-group");
- }
- }
-
- fn group_end(&mut self) {
- if self.takes_hints() {
- self.linker_arg("--end-group");
- }
- }
-
fn linker_plugin_lto(&mut self) {
match self.sess.opts.cg.linker_plugin_lto {
LinkerPluginLto::Disabled => {
@@ -1022,10 +1005,6 @@ impl<'a> Linker for MsvcLinker<'a> {
}
}
- // MSVC doesn't need group indicators
- fn group_start(&mut self) {}
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {
// Do nothing
}
@@ -1168,10 +1147,6 @@ impl<'a> Linker for EmLinker<'a> {
// noop
}
- // Appears not necessary on Emscripten
- fn group_start(&mut self) {}
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {
// Do nothing
}
@@ -1347,10 +1322,6 @@ impl<'a> Linker for WasmLd<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
- // Not needed for now with LLD
- fn group_start(&mut self) {}
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {
// Do nothing for now
}
@@ -1479,14 +1450,6 @@ impl<'a> Linker for L4Bender<'a> {
self.hint_static(); // Reset to default before returning the composed command line.
}
- fn group_start(&mut self) {
- self.cmd.arg("--start-group");
- }
-
- fn group_end(&mut self) {
- self.cmd.arg("--end-group");
- }
-
fn linker_plugin_lto(&mut self) {}
fn control_flow_guard(&mut self) {}
@@ -1667,10 +1630,6 @@ impl<'a> Linker for PtxLinker<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
- fn group_start(&mut self) {}
-
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {}
}
@@ -1780,9 +1739,5 @@ impl<'a> Linker for BpfLinker<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
- fn group_start(&mut self) {}
-
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {}
}
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 0302c2881..99ddd1764 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -117,6 +117,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
"riscv32" => Architecture::Riscv32,
"riscv64" => Architecture::Riscv64,
"sparc64" => Architecture::Sparc64,
+ "avr" => Architecture::Avr,
+ "msp430" => Architecture::Msp430,
+ "hexagon" => Architecture::Hexagon,
+ "bpf" => Architecture::Bpf,
// Unsupported architecture.
_ => return None,
};
@@ -187,12 +191,12 @@ pub enum MetadataPosition {
Last,
}
-// For rlibs we "pack" rustc metadata into a dummy object file. When rustc
-// creates a dylib crate type it will pass `--whole-archive` (or the
-// platform equivalent) to include all object files from an rlib into the
-// final dylib itself. This causes linkers to iterate and try to include all
-// files located in an archive, so if metadata is stored in an archive then
-// it needs to be of a form that the linker will be able to process.
+// For rlibs we "pack" rustc metadata into a dummy object file.
+//
+// Historically it was needed because rustc linked rlibs as whole-archive in some cases.
+// In that case linkers try to include all files located in an archive, so if metadata is stored
+// in an archive then it needs to be of a form that the linker is able to process.
+// Now it's not clear whether metadata still needs to be wrapped into an object file or not.
//
// Note, though, that we don't actually want this metadata to show up in any
// final output of the compiler. Instead this is purely for rustc's own
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index e6b605575..8d7e2c5cf 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -103,18 +103,14 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
}
})
.map(|def_id| {
- let (export_level, used) = if special_runtime_crate {
- let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
- // We won't link right if these symbols are stripped during LTO.
- let used = match name {
- "rust_eh_personality"
- | "rust_eh_register_frames"
- | "rust_eh_unregister_frames" => true,
- _ => false,
- };
- (SymbolExportLevel::Rust, used)
+ // We won't link right if this symbol is stripped during LTO.
+ let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
+ let used = name == "rust_eh_personality";
+
+ let export_level = if special_runtime_crate {
+ SymbolExportLevel::Rust
} else {
- (symbol_export_level(tcx, def_id.to_def_id()), false)
+ symbol_export_level(tcx, def_id.to_def_id())
};
let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id());
debug!(
@@ -544,7 +540,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
.unwrap_or((Conv::Rust, &[]));
- // Decorate symbols with prefices, suffices and total number of bytes of arguments.
+ // Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
let (prefix, suffix) = match conv {
Conv::X86Fastcall => ("@", "@"),
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 1b5ad8710..68f3b19b7 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::profiling::TimingGuard;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter;
-use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
+use rustc_errors::{translation::Translate, DiagnosticId, FatalError, Handler, Level};
use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{
@@ -256,8 +256,11 @@ impl ModuleConfig {
{
MergeFunctions::Disabled => false,
MergeFunctions::Trampolines | MergeFunctions::Aliases => {
- sess.opts.optimize == config::OptLevel::Default
- || sess.opts.optimize == config::OptLevel::Aggressive
+ use config::OptLevel::*;
+ match sess.opts.optimize {
+ Aggressive | Default | SizeMin | Size => true,
+ Less | No => false,
+ }
}
},
@@ -1737,6 +1740,16 @@ impl SharedEmitter {
}
}
+impl Translate for SharedEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+ None
+ }
+
+ fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+ panic!("shared emitter attempted to translate a diagnostic");
+ }
+}
+
impl Emitter for SharedEmitter {
fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
let fluent_args = self.to_fluent_args(diag.args());
@@ -1758,14 +1771,6 @@ impl Emitter for SharedEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}
-
- fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
- None
- }
-
- fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
- panic!("shared emitter attempted to translate a diagnostic");
- }
}
impl SharedEmitterMain {
@@ -1887,7 +1892,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
}
});
- sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic());
+ sess.cgu_reuse_tracker.check_expected_reuse(sess);
sess.abort_if_errors();
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index a840b2709..b98ff4957 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -1,3 +1,4 @@
+use crate::back::link::are_upstream_rust_objects_already_included;
use crate::back::metadata::create_compressed_metadata_file;
use crate::back::write::{
compute_per_cgu_lto_type, start_async_codegen, submit_codegened_module_to_llvm,
@@ -12,7 +13,7 @@ use crate::traits::*;
use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind};
use rustc_attr as attr;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::par_iter;
@@ -21,10 +22,12 @@ 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;
+use rustc_hir::weak_lang_items::WEAK_ITEMS_SYMBOLS;
use rustc_index::vec::Idx;
use rustc_metadata::EncodedMetadata;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::exported_symbols;
+use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_middle::middle::lang_items;
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
@@ -34,6 +37,7 @@ use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
use rustc_session::Session;
use rustc_span::symbol::sym;
+use rustc_span::Symbol;
use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
use rustc_target::abi::{Align, VariantIdx};
@@ -151,6 +155,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
+ // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
return old_info;
}
@@ -162,6 +167,11 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
if let Some(entry_idx) = vptr_entry_idx {
let ptr_ty = cx.type_i8p();
let ptr_align = cx.tcx().data_layout.pointer_align.abi;
+ let vtable_ptr_ty = cx.scalar_pair_element_backend_type(
+ cx.layout_of(cx.tcx().mk_mut_ptr(target)),
+ 1,
+ true,
+ );
let llvtable = bx.pointercast(old_info, bx.type_ptr_to(ptr_ty));
let gep = bx.inbounds_gep(
ptr_ty,
@@ -172,7 +182,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx.nonnull_metadata(new_vptr);
// VTable loads are invariant.
bx.set_invariant_load(new_vptr);
- new_vptr
+ bx.pointercast(new_vptr, vtable_ptr_ty)
} else {
old_info
}
@@ -388,15 +398,14 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let main_llfn = cx.get_fn_addr(instance);
- let use_start_lang_item = EntryFnType::Start != entry_type;
- let entry_fn = create_entry_fn::<Bx>(cx, main_llfn, main_def_id, use_start_lang_item);
+ let entry_fn = create_entry_fn::<Bx>(cx, main_llfn, main_def_id, entry_type);
return Some(entry_fn);
fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
rust_main: Bx::Value,
rust_main_def_id: DefId,
- use_start_lang_item: bool,
+ entry_type: EntryFnType,
) -> Bx::Function {
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
// depending on whether the target needs `argc` and `argv` to be passed in.
@@ -441,7 +450,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let i8pp_ty = cx.type_ptr_to(cx.type_i8p());
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
- let (start_fn, start_ty, args) = if use_start_lang_item {
+ let (start_fn, start_ty, args) = if let EntryFnType::Main { sigpipe } = entry_type {
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
let start_fn = cx.get_fn_addr(
ty::Instance::resolve(
@@ -453,8 +462,13 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
.unwrap()
.unwrap(),
);
- let start_ty = cx.type_func(&[cx.val_ty(rust_main), isize_ty, i8pp_ty], isize_ty);
- (start_fn, start_ty, vec![rust_main, arg_argc, arg_argv])
+
+ let i8_ty = cx.type_i8();
+ let arg_sigpipe = bx.const_u8(sigpipe);
+
+ let start_ty =
+ cx.type_func(&[cx.val_ty(rust_main), isize_ty, i8pp_ty, i8_ty], isize_ty);
+ (start_fn, start_ty, vec![rust_main, arg_argc, arg_argv, arg_sigpipe])
} else {
debug!("using user-defined start fn");
let start_ty = cx.type_func(&[isize_ty, i8pp_ty], isize_ty);
@@ -810,21 +824,16 @@ impl CrateInfo {
crate_name: Default::default(),
used_crates,
used_crate_source: Default::default(),
- lang_item_to_crate: Default::default(),
- missing_lang_items: Default::default(),
dependency_formats: tcx.dependency_formats(()).clone(),
windows_subsystem,
natvis_debugger_visualizers: Default::default(),
};
- let lang_items = tcx.lang_items();
-
let crates = tcx.crates(());
let n_crates = crates.len();
info.native_libraries.reserve(n_crates);
info.crate_name.reserve(n_crates);
info.used_crate_source.reserve(n_crates);
- info.missing_lang_items.reserve(n_crates);
for &cnum in crates.iter() {
info.native_libraries
@@ -842,17 +851,41 @@ impl CrateInfo {
if tcx.is_no_builtins(cnum) {
info.is_no_builtins.insert(cnum);
}
- let missing = tcx.missing_lang_items(cnum);
- for &item in missing.iter() {
- if let Ok(id) = lang_items.require(item) {
- info.lang_item_to_crate.insert(item, id.krate);
- }
- }
+ }
- // No need to look for lang items that don't actually need to exist.
- let missing =
- missing.iter().cloned().filter(|&l| lang_items::required(tcx, l)).collect();
- info.missing_lang_items.insert(cnum, missing);
+ // Handle circular dependencies in the standard library.
+ // See comment before `add_linked_symbol_object` function for the details.
+ // If global LTO is enabled then almost everything (*) is glued into a single object file,
+ // so this logic is not necessary and can cause issues on some targets (due to weak lang
+ // item symbols being "privatized" to that object file), so we disable it.
+ // (*) Native libs, and `#[compiler_builtins]` and `#[no_builtins]` crates are not glued,
+ // and we assume that they cannot define weak lang items. This is not currently enforced
+ // by the compiler, but that's ok because all this stuff is unstable anyway.
+ let target = &tcx.sess.target;
+ if !are_upstream_rust_objects_already_included(tcx.sess) {
+ let missing_weak_lang_items: FxHashSet<&Symbol> = info
+ .used_crates
+ .iter()
+ .flat_map(|cnum| {
+ tcx.missing_lang_items(*cnum)
+ .iter()
+ .filter(|l| lang_items::required(tcx, **l))
+ .filter_map(|item| WEAK_ITEMS_SYMBOLS.get(item))
+ })
+ .collect();
+ let prefix = if target.is_like_windows && target.arch == "x86" { "_" } else { "" };
+ info.linked_symbols
+ .iter_mut()
+ .filter(|(crate_type, _)| {
+ !matches!(crate_type, CrateType::Rlib | CrateType::Staticlib)
+ })
+ .for_each(|(_, linked_symbols)| {
+ linked_symbols.extend(
+ missing_weak_lang_items
+ .iter()
+ .map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)),
+ )
+ });
}
let embed_visualizers = tcx.sess.crate_types().iter().any(|&crate_type| match crate_type {
@@ -873,7 +906,7 @@ impl CrateInfo {
}
});
- if tcx.sess.target.is_like_msvc && embed_visualizers {
+ if target.is_like_msvc && embed_visualizers {
info.natvis_debugger_visualizers =
collect_debugger_visualizers_transitive(tcx, DebuggerVisualizerType::Natvis);
}
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 8cd5a0fc2..135ed680d 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -18,11 +18,10 @@ use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathD
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, ExistentialProjection, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
-use rustc_target::abi::{Integer, TagEncoding, Variants};
+use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
+use rustc_target::abi::Integer;
use smallvec::SmallVec;
-use std::borrow::Cow;
use std::fmt::Write;
use crate::debuginfo::wants_c_like_enum_debuginfo;
@@ -98,7 +97,6 @@ fn push_debuginfo_type_name<'tcx>(
if let Some(ty_and_layout) = layout_for_cpp_like_fallback {
msvc_enum_fallback(
- tcx,
ty_and_layout,
&|output, visited| {
push_item_name(tcx, def.did(), true, output);
@@ -391,11 +389,10 @@ fn push_debuginfo_type_name<'tcx>(
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
// "{async_fn_env#0}<T1, T2, ...>", etc.
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
- // an artificial `enum$<>` type, as defined in msvc_enum_fallback().
+ // an artificial `enum2$<>` type, as defined in msvc_enum_fallback().
if cpp_like_debuginfo && t.is_generator() {
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
msvc_enum_fallback(
- tcx,
ty_and_layout,
&|output, visited| {
push_closure_or_generator_name(tcx, def_id, substs, true, output, visited);
@@ -428,58 +425,17 @@ fn push_debuginfo_type_name<'tcx>(
/// MSVC names enums differently than other platforms so that the debugging visualization
// format (natvis) is able to understand enums and render the active variant correctly in the
- // debugger. For more information, look in `src/etc/natvis/intrinsic.natvis` and
- // `EnumMemberDescriptionFactor::create_member_descriptions`.
+ // debugger. For more information, look in
+ // rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs.
fn msvc_enum_fallback<'tcx>(
- tcx: TyCtxt<'tcx>,
ty_and_layout: TyAndLayout<'tcx>,
push_inner: &dyn Fn(/*output*/ &mut String, /*visited*/ &mut FxHashSet<Ty<'tcx>>),
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
) {
debug_assert!(!wants_c_like_enum_debuginfo(ty_and_layout));
- let ty = ty_and_layout.ty;
-
- output.push_str("enum$<");
+ output.push_str("enum2$<");
push_inner(output, visited);
-
- let variant_name = |variant_index| match ty.kind() {
- ty::Adt(adt_def, _) => {
- debug_assert!(adt_def.is_enum());
- Cow::from(adt_def.variant(variant_index).name.as_str())
- }
- ty::Generator(..) => GeneratorSubsts::variant_name(variant_index),
- _ => unreachable!(),
- };
-
- if let Variants::Multiple {
- tag_encoding: TagEncoding::Niche { dataful_variant, .. },
- tag,
- variants,
- ..
- } = &ty_and_layout.variants
- {
- let dataful_variant_layout = &variants[*dataful_variant];
-
- // calculate the range of values for the dataful variant
- let dataful_discriminant_range =
- dataful_variant_layout.largest_niche().unwrap().valid_range;
-
- let min = dataful_discriminant_range.start;
- let min = tag.size(&tcx).truncate(min);
-
- let max = dataful_discriminant_range.end;
- let max = tag.size(&tcx).truncate(max);
-
- let dataful_variant_name = variant_name(*dataful_variant);
- write!(output, ", {}, {}, {}", min, max, dataful_variant_name).unwrap();
- } else if let Variants::Single { index: variant_idx } = &ty_and_layout.variants {
- // Uninhabited enums can't be constructed and should never need to be visualized so
- // skip this step for them.
- if !ty_and_layout.abi.is_uninhabited() {
- write!(output, ", {}", variant_name(*variant_idx)).unwrap();
- }
- }
push_close_angle_bracket(true, output);
}
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 1802eedf1..e736b2aba 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -1,7 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
#![feature(try_blocks)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![feature(associated_type_bounds)]
#![feature(strict_provenance)]
@@ -25,7 +25,6 @@ use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_hir::def_id::CrateNum;
-use rustc_hir::LangItem;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -113,6 +112,7 @@ bitflags::bitflags! {
pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Option<Symbol>,
+ pub filename: Option<Symbol>,
pub cfg: Option<ast::MetaItem>,
pub verbatim: Option<bool>,
pub dll_imports: Vec<cstore::DllImport>,
@@ -122,6 +122,7 @@ impl From<&cstore::NativeLib> for NativeLib {
fn from(lib: &cstore::NativeLib) -> Self {
NativeLib {
kind: lib.kind,
+ filename: lib.filename,
name: lib.name,
cfg: lib.cfg.clone(),
verbatim: lib.verbatim,
@@ -152,8 +153,6 @@ pub struct CrateInfo {
pub used_libraries: Vec<NativeLib>,
pub used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>,
pub used_crates: Vec<CrateNum>,
- pub lang_item_to_crate: FxHashMap<LangItem, CrateNum>,
- pub missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>,
pub dependency_formats: Lrc<Dependencies>,
pub windows_subsystem: Option<String>,
pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
@@ -168,6 +167,13 @@ pub struct CodegenResults {
pub crate_info: CrateInfo,
}
+pub enum CodegenErrors<'a> {
+ WrongFileType,
+ EmptyVersionNumber,
+ EncodingVersionMismatch { version_array: String, rlink_version: u32 },
+ RustcVersionMismatch { rustc_version: String, current_version: &'a str },
+}
+
pub fn provide(providers: &mut Providers) {
crate::back::symbol_export::provide(providers);
crate::base::provide(providers);
@@ -212,30 +218,34 @@ impl CodegenResults {
encoder.finish()
}
- pub fn deserialize_rlink(data: Vec<u8>) -> Result<Self, String> {
+ pub fn deserialize_rlink<'a>(data: Vec<u8>) -> Result<Self, CodegenErrors<'a>> {
// The Decodable machinery is not used here because it panics if the input data is invalid
// and because its internal representation may change.
if !data.starts_with(RLINK_MAGIC) {
- return Err("The input does not look like a .rlink file".to_string());
+ return Err(CodegenErrors::WrongFileType);
}
let data = &data[RLINK_MAGIC.len()..];
if data.len() < 4 {
- return Err("The input does not contain version number".to_string());
+ return Err(CodegenErrors::EmptyVersionNumber);
}
let mut version_array: [u8; 4] = Default::default();
version_array.copy_from_slice(&data[..4]);
if u32::from_be_bytes(version_array) != RLINK_VERSION {
- return Err(".rlink file was produced with encoding version {version_array}, but the current version is {RLINK_VERSION}".to_string());
+ return Err(CodegenErrors::EncodingVersionMismatch {
+ version_array: String::from_utf8_lossy(&version_array).to_string(),
+ rlink_version: RLINK_VERSION,
+ });
}
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 {
- return Err(format!(
- ".rlink file was produced by rustc version {rustc_version}, but the current version is {current_version}."
- ));
+ return Err(CodegenErrors::RustcVersionMismatch {
+ rustc_version: rustc_version.to_string(),
+ current_version,
+ });
}
let codegen_results = CodegenResults::decode(&mut decoder);
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index 27d791d90..cae46ebd2 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -1,6 +1,6 @@
use crate::traits::*;
-use rustc_middle::ty::{self, subst::GenericArgKind, ExistentialPredicate, Ty, TyCtxt};
+use rustc_middle::ty::{self, subst::GenericArgKind, Ty};
use rustc_session::config::Lto;
use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::abi::call::FnAbi;
@@ -29,7 +29,7 @@ impl<'a, 'tcx> VirtualIndex {
&& bx.cx().sess().lto() == Lto::Fat
{
let typeid =
- bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), get_trait_ref(bx.tcx(), ty)));
+ bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(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);
@@ -64,17 +64,13 @@ impl<'a, 'tcx> VirtualIndex {
}
}
-fn get_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> {
+/// This takes a valid `self` receiver type and extracts the principal trait
+/// ref of the type.
+fn expect_dyn_trait_in_self<'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")
- }
- });
+ if let ty::Dynamic(data, _, _) = ty.kind() {
+ return data.principal().expect("expected principal trait object");
}
}
}
@@ -90,6 +86,7 @@ fn get_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::PolyExistentialTr
/// The `trait_ref` encodes the erased self type. Hence if we are
/// making an object `Foo<dyn Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T: Trait`.
+#[instrument(level = "debug", skip(cx))]
pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,
ty: Ty<'tcx>,
@@ -97,8 +94,6 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
) -> Cx::Value {
let tcx = cx.tcx();
- debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref);
-
// Check the cache.
if let Some(&val) = cx.vtables().borrow().get(&(ty, trait_ref)) {
return val;
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 24da48ead..c7617d2e4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -266,7 +266,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
mir: &mir::Body<'tcx>,
) {
- for (bb, data) in mir.basic_blocks().iter_enumerated() {
+ for (bb, data) in mir.basic_blocks.iter_enumerated() {
match data.terminator().kind {
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
@@ -296,7 +296,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
}
fn propagate<'tcx>(result: &mut IndexVec<mir::BasicBlock, CleanupKind>, mir: &mir::Body<'tcx>) {
- let mut funclet_succs = IndexVec::from_elem(None, mir.basic_blocks());
+ let mut funclet_succs = IndexVec::from_elem(None, &mir.basic_blocks);
let mut set_successor = |funclet: mir::BasicBlock, succ| match funclet_succs[funclet] {
ref mut s @ None => {
@@ -359,7 +359,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
}
}
- let mut result = IndexVec::from_elem(CleanupKind::NotCleanup, mir.basic_blocks());
+ let mut result = IndexVec::from_elem(CleanupKind::NotCleanup, &mir.basic_blocks);
discover_masters(&mut result, mir);
propagate(&mut result, mir);
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 3eee58d9d..a6b226ef7 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -13,15 +13,14 @@ use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::lang_items::LangItem;
use rustc_index::vec::Idx;
-use rustc_middle::mir::AssertKind;
-use rustc_middle::mir::{self, SwitchTargets};
+use rustc_middle::mir::{self, AssertKind, SwitchTargets};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Instance, Ty, TypeVisitable};
use rustc_span::source_map::Span;
use rustc_span::{sym, Symbol};
use rustc_symbol_mangling::typeid::typeid_for_fnabi;
-use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
+use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
use rustc_target::spec::abi::Abi;
@@ -324,7 +323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.unreachable();
return;
}
- let llval = match self.fn_abi.ret.mode {
+ let llval = match &self.fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { .. } => {
bx.ret_void();
return;
@@ -339,7 +338,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
- PassMode::Cast(cast_ty) => {
+ PassMode::Cast(cast_ty, _) => {
let op = match self.locals[mir::RETURN_PLACE] {
LocalRef::Operand(Some(op)) => op,
LocalRef::Operand(None) => bug!("use of return before def"),
@@ -360,7 +359,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
llval
}
};
- let ty = bx.cast_backend_type(&cast_ty);
+ let ty = bx.cast_backend_type(cast_ty);
let addr = bx.pointercast(llslot, bx.type_ptr_to(ty));
bx.load(ty, addr, self.fn_abi.ret.layout.align.abi)
}
@@ -368,6 +367,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.ret(llval);
}
+ #[tracing::instrument(level = "trace", skip(self, helper, bx))]
fn codegen_drop_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
@@ -398,13 +398,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (drop_fn, fn_abi) = match ty.kind() {
// FIXME(eddyb) perhaps move some of this logic into
// `Instance::resolve_drop_in_place`?
- ty::Dynamic(..) => {
+ ty::Dynamic(_, _, ty::Dyn) => {
+ // IN THIS ARM, WE HAVE:
+ // ty = *mut (dyn Trait)
+ // which is: exists<T> ( *mut T, Vtable<T: Trait> )
+ // args[0] args[1]
+ //
+ // args = ( Data, Vtable )
+ // |
+ // v
+ // /-------\
+ // | ... |
+ // \-------/
+ //
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
substs: drop_fn.substs,
};
+ debug!("ty = {:?}", ty);
+ debug!("drop_fn = {:?}", drop_fn);
+ debug!("args = {:?}", args);
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
let vtable = args[1];
+ // Truncate vtable off of args list
args = &args[..1];
(
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
@@ -412,6 +428,51 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
fn_abi,
)
}
+ ty::Dynamic(_, _, ty::DynStar) => {
+ // IN THIS ARM, WE HAVE:
+ // ty = *mut (dyn* Trait)
+ // which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
+ //
+ // args = [ * ]
+ // |
+ // v
+ // ( Data, Vtable )
+ // |
+ // v
+ // /-------\
+ // | ... |
+ // \-------/
+ //
+ //
+ // WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING
+ //
+ // data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer)
+ // vtable = (*args[0]).1 // loads the vtable out
+ // (data, vtable) // an equivalent Rust `*mut dyn Trait`
+ //
+ // SO THEN WE CAN USE THE ABOVE CODE.
+ let virtual_drop = Instance {
+ def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
+ substs: drop_fn.substs,
+ };
+ debug!("ty = {:?}", ty);
+ debug!("drop_fn = {:?}", drop_fn);
+ debug!("args = {:?}", args);
+ let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
+ let data = args[0];
+ let data_ty = bx.cx().backend_type(place.layout);
+ let vtable_ptr =
+ bx.gep(data_ty, data, &[bx.cx().const_i32(0), bx.cx().const_i32(1)]);
+ let vtable = bx.load(bx.type_i8p(), vtable_ptr, abi::Align::ONE);
+ // Truncate vtable off of args list
+ args = &args[..1];
+ debug!("args' = {:?}", args);
+ (
+ meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
+ .get_fn(&mut bx, vtable, ty, &fn_abi),
+ fn_abi,
+ )
+ }
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
};
helper.do_call(
@@ -798,58 +859,78 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let mut op = self.codegen_operand(&mut bx, arg);
if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
- if let Pair(..) = op.val {
- // In the case of Rc<Self>, we need to explicitly pass a
- // *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
- // that is understood elsewhere in the compiler as a method on
- // `dyn Trait`.
- // To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
- // we get a value of a built-in pointer type
- 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr()
- && !op.layout.ty.is_region_ptr()
- {
- for i in 0..op.layout.fields.count() {
- let field = op.extract_field(&mut bx, i);
- if !field.layout.is_zst() {
- // we found the one non-zero-sized field that is allowed
- // now find *its* non-zero-sized field, or stop if it's a
- // pointer
- op = field;
- continue 'descend_newtypes;
+ match op.val {
+ Pair(data_ptr, meta) => {
+ // In the case of Rc<Self>, we need to explicitly pass a
+ // *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
+ // that is understood elsewhere in the compiler as a method on
+ // `dyn Trait`.
+ // To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
+ // we get a value of a built-in pointer type
+ 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr()
+ && !op.layout.ty.is_region_ptr()
+ {
+ for i in 0..op.layout.fields.count() {
+ let field = op.extract_field(&mut bx, i);
+ if !field.layout.is_zst() {
+ // we found the one non-zero-sized field that is allowed
+ // now find *its* non-zero-sized field, or stop if it's a
+ // pointer
+ op = field;
+ continue 'descend_newtypes;
+ }
}
+
+ span_bug!(span, "receiver has no non-zero-sized fields {:?}", op);
}
- span_bug!(span, "receiver has no non-zero-sized fields {:?}", op);
+ // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
+ // data pointer and vtable. Look up the method in the vtable, and pass
+ // the data pointer as the first argument
+ llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
+ &mut bx,
+ meta,
+ op.layout.ty,
+ &fn_abi,
+ ));
+ llargs.push(data_ptr);
+ continue 'make_args;
}
-
- // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
- // data pointer and vtable. Look up the method in the vtable, and pass
- // 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,
- op.layout.ty,
- &fn_abi,
- ));
- llargs.push(data_ptr);
- continue 'make_args;
+ Ref(data_ptr, Some(meta), _) => {
+ // by-value dynamic dispatch
+ llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
+ &mut bx,
+ meta,
+ op.layout.ty,
+ &fn_abi,
+ ));
+ llargs.push(data_ptr);
+ continue;
+ }
+ Immediate(_) => {
+ let ty::Ref(_, ty, _) = op.layout.ty.kind() else {
+ span_bug!(span, "can't codegen a virtual call on {:#?}", op);
+ };
+ if !ty.is_dyn_star() {
+ span_bug!(span, "can't codegen a virtual call on {:#?}", op);
}
- other => bug!("expected a Pair, got {:?}", other),
+ // FIXME(dyn-star): Make sure this is done on a &dyn* receiver
+ let place = op.deref(bx.cx());
+ let data_ptr = place.project_field(&mut bx, 0);
+ let meta_ptr = place.project_field(&mut bx, 1);
+ let meta = bx.load_operand(meta_ptr);
+ llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
+ &mut bx,
+ meta.immediate(),
+ op.layout.ty,
+ &fn_abi,
+ ));
+ llargs.push(data_ptr.llval);
+ continue;
+ }
+ _ => {
+ span_bug!(span, "can't codegen a virtual call on {:#?}", op);
}
- } 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,
- op.layout.ty,
- &fn_abi,
- ));
- llargs.push(data_ptr);
- continue;
- } else {
- span_bug!(span, "can't codegen a virtual call on {:?}", op);
}
}
@@ -1161,39 +1242,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
llargs: &mut Vec<Bx::Value>,
arg: &ArgAbi<'tcx, Ty<'tcx>>,
) {
- // Fill padding with undef value, where applicable.
- if let Some(ty) = arg.pad {
- llargs.push(bx.const_undef(bx.reg_backend_type(&ty)))
- }
-
- if arg.is_ignore() {
- return;
- }
-
- if let PassMode::Pair(..) = arg.mode {
- match op.val {
+ match arg.mode {
+ PassMode::Ignore => return,
+ PassMode::Cast(_, true) => {
+ // Fill padding with undef value, where applicable.
+ llargs.push(bx.const_undef(bx.reg_backend_type(&Reg::i32())));
+ }
+ PassMode::Pair(..) => match op.val {
Pair(a, b) => {
llargs.push(a);
llargs.push(b);
return;
}
_ => bug!("codegen_argument: {:?} invalid for pair argument", op),
- }
- } else if arg.is_unsized_indirect() {
- match op.val {
+ },
+ PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => match op.val {
Ref(a, Some(b), _) => {
llargs.push(a);
llargs.push(b);
return;
}
_ => bug!("codegen_argument: {:?} invalid for unsized indirect argument", op),
- }
+ },
+ _ => {}
}
// Force by-ref if we have to load through a cast pointer.
let (mut llval, align, by_ref) = match op.val {
Immediate(_) | Pair(..) => match arg.mode {
- PassMode::Indirect { .. } | PassMode::Cast(_) => {
+ PassMode::Indirect { .. } | PassMode::Cast(..) => {
let scratch = PlaceRef::alloca(bx, arg.layout);
op.val.store(bx, scratch);
(scratch.llval, scratch.align, true)
@@ -1225,8 +1302,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if by_ref && !arg.is_indirect() {
// Have to load the argument, maybe while casting it.
- if let PassMode::Cast(ty) = arg.mode {
- let llty = bx.cast_backend_type(&ty);
+ if let PassMode::Cast(ty, _) = &arg.mode {
+ let llty = bx.cast_backend_type(ty);
let addr = bx.pointercast(llval, bx.type_ptr_to(llty));
llval = bx.load(llty, addr, align.min(arg.layout.align.abi));
} else {
@@ -1625,7 +1702,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
DirectOperand(index) => {
// If there is a cast, we have to store and reload.
- let op = if let PassMode::Cast(_) = ret_abi.mode {
+ let op = if let PassMode::Cast(..) = ret_abi.mode {
let tmp = PlaceRef::alloca(bx, ret_abi.layout);
tmp.storage_live(bx);
bx.store_arg(&ret_abi, llval, tmp);
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 9a995fbf6..4c6ab457c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -25,26 +25,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
constant: &mir::Constant<'tcx>,
) -> Result<ConstValue<'tcx>, ErrorHandled> {
let ct = self.monomorphize(constant.literal);
- let ct = match ct {
- mir::ConstantKind::Ty(ct) => ct,
+ let uv = match ct {
+ mir::ConstantKind::Ty(ct) => match ct.kind() {
+ ty::ConstKind::Unevaluated(uv) => uv.expand(),
+ ty::ConstKind::Value(val) => {
+ return Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val)));
+ }
+ err => span_bug!(
+ constant.span,
+ "encountered bad ConstKind after monomorphizing: {:?}",
+ err
+ ),
+ },
+ mir::ConstantKind::Unevaluated(uv, _) => uv,
mir::ConstantKind::Val(val, _) => return Ok(val),
};
- match ct.kind() {
- ty::ConstKind::Unevaluated(ct) => self
- .cx
- .tcx()
- .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None)
- .map_err(|err| {
- self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
- err
- }),
- 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: {:?}",
- err
- ),
- }
+
+ self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| {
+ self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
+ err
+ })
}
/// process constant containing SIMD shuffle indices
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 8c3186efc..157c1c823 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -3,7 +3,7 @@ use rustc_index::vec::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir;
use rustc_middle::ty;
-use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
@@ -93,15 +93,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
/// In order to have a good line stepping behavior in debugger, we overwrite debug
- /// locations of macro expansions with that of the outermost expansion site
- /// (unless the crate is being compiled with `-Z debug-macros`).
+ /// locations of macro expansions with that of the outermost expansion site (when the macro is
+ /// annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
fn adjust_span_for_debugging(&self, mut span: Span) -> Span {
// Bail out if debug info emission is not enabled.
if self.debug_context.is_none() {
return span;
}
- if span.from_expansion() && !self.cx.sess().opts.unstable_opts.debug_macros {
+ if self.cx.tcx().should_collapse_debuginfo(span) {
// Walk up the macro expansion chain until we reach a non-expanded span.
// We also stop at the function body level because no line stepping can occur
// at the level above that.
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 94ac71a4d..215edbe02 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -77,10 +77,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
let llval = match name {
- sym::assume => {
- bx.assume(args[0].immediate());
- return;
- }
sym::abort => {
bx.abort();
return;
@@ -555,14 +551,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return;
}
- sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
+ sym::ptr_guaranteed_cmp => {
let a = args[0].immediate();
let b = args[1].immediate();
- if name == sym::ptr_guaranteed_eq {
- bx.icmp(IntPredicate::IntEQ, a, b)
- } else {
- bx.icmp(IntPredicate::IntNE, a, b)
- }
+ bx.icmp(IntPredicate::IntEQ, a, b)
}
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
@@ -597,8 +589,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
};
if !fn_abi.ret.is_ignore() {
- if let PassMode::Cast(ty) = fn_abi.ret.mode {
- let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(&ty));
+ if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
+ let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(ty));
let ptr = bx.pointercast(result.llval, ptr_llty);
bx.store(llval, ptr, result.align);
} else {
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 8ee375fa9..2b931bfc9 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -150,13 +150,13 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let start_llbb = Bx::append_block(cx, llfn, "start");
let mut bx = Bx::build(cx, start_llbb);
- if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) {
+ if mir.basic_blocks.iter().any(|bb| bb.is_cleanup) {
bx.set_personality_fn(cx.eh_personality());
}
let cleanup_kinds = analyze::cleanup_kinds(&mir);
let cached_llbbs: IndexVec<mir::BasicBlock, Option<Bx::BasicBlock>> = mir
- .basic_blocks()
+ .basic_blocks
.indices()
.map(|bb| if bb == mir::START_BLOCK { Some(start_llbb) } else { None })
.collect();
@@ -172,8 +172,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
unreachable_block: None,
double_unwind_guard: None,
cleanup_kinds,
- landing_pads: IndexVec::from_elem(None, mir.basic_blocks()),
- funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks().len()),
+ landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
+ funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
locals: IndexVec::new(),
debug_context,
per_local_var_debug_info: None,
@@ -191,7 +191,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// errored or at least linted
ErrorHandled::Reported(_) | ErrorHandled::Linted => {}
ErrorHandled::TooGeneric => {
- span_bug!(const_.span, "codgen encountered polymorphic constant: {:?}", err)
+ span_bug!(const_.span, "codegen encountered polymorphic constant: {:?}", err)
}
}
}
@@ -283,7 +283,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
for i in 0..tupled_arg_tys.len() {
let arg = &fx.fn_abi.args[idx];
idx += 1;
- if arg.pad.is_some() {
+ if let PassMode::Cast(_, true) = arg.mode {
llarg_idx += 1;
}
let pr_field = place.project_field(bx, i);
@@ -309,7 +309,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let arg = &fx.fn_abi.args[idx];
idx += 1;
- if arg.pad.is_some() {
+ if let PassMode::Cast(_, true) = arg.mode {
llarg_idx += 1;
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index c612634fc..37b1e0362 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -72,10 +72,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
) -> Self {
let layout = bx.layout_of(ty);
- if layout.is_zst() {
- return OperandRef::new_zst(bx, layout);
- }
-
let val = match val {
ConstValue::Scalar(x) => {
let Abi::Scalar(scalar) = layout.abi else {
@@ -84,10 +80,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
OperandValue::Immediate(llval)
}
- ConstValue::ZeroSized => {
- let llval = bx.zst_to_backend(bx.immediate_backend_type(layout));
- OperandValue::Immediate(llval)
- }
+ ConstValue::ZeroSized => return OperandRef::new_zst(bx, layout),
ConstValue::Slice { data, start, end } => {
let Abi::ScalarPair(a_scalar, _) = layout.abi else {
bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 268c4d765..13d8f6edd 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -4,7 +4,6 @@ use super::{FunctionCx, LocalRef};
use crate::common::IntPredicate;
use crate::glue;
use crate::traits::*;
-use crate::MemFlags;
use rustc_middle::mir;
use rustc_middle::mir::tcx::PlaceTy;
@@ -245,7 +244,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
};
bx.intcast(tag.immediate(), cast_to, signed)
}
- TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
+ TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
// Rebase from niche values to discriminants, and check
// whether the result is in range for the niche variants.
let niche_llty = bx.cx().immediate_backend_type(tag.layout);
@@ -303,7 +302,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
bx.select(
is_niche,
niche_discr,
- bx.cx().const_uint(cast_to, dataful_variant.as_u32() as u64),
+ bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
)
}
}
@@ -338,21 +337,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
}
Variants::Multiple {
tag_encoding:
- TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
+ TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
tag_field,
..
} => {
- if variant_index != dataful_variant {
- if bx.cx().sess().target.arch == "arm"
- || bx.cx().sess().target.arch == "aarch64"
- {
- // FIXME(#34427): as workaround for LLVM bug on ARM,
- // use memset of 0 before assigning niche value.
- let fill_byte = bx.cx().const_u8(0);
- let size = bx.cx().const_usize(self.layout.size.bytes());
- bx.memset(self.llval, fill_byte, size, self.align, MemFlags::empty());
- }
-
+ if variant_index != untagged_variant {
let niche = self.project_field(bx, tag_field);
let niche_llty = bx.cx().immediate_backend_type(niche.layout);
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 26b9fbf44..56852b0fc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -4,6 +4,7 @@ use super::{FunctionCx, LocalRef};
use crate::base;
use crate::common::{self, IntPredicate};
+use crate::meth::get_vtable;
use crate::traits::*;
use crate::MemFlags;
@@ -87,7 +88,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let size = bx.const_usize(dest.layout.size.bytes());
// Use llvm.memset.p0i8.* to initialize all zero arrays
- if bx.cx().const_to_opt_uint(v) == Some(0) {
+ if bx.cx().const_to_opt_u128(v, false) == Some(0) {
let fill = bx.cx().const_u8(0);
bx.memset(start, fill, size, dest.align, MemFlags::empty());
return bx;
@@ -271,6 +272,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bug!("unexpected non-pair operand");
}
}
+ mir::CastKind::DynStar => {
+ let data = match operand.val {
+ OperandValue::Ref(_, _, _) => todo!(),
+ OperandValue::Immediate(v) => v,
+ OperandValue::Pair(_, _) => todo!(),
+ };
+ let trait_ref =
+ if let ty::Dynamic(data, _, ty::DynStar) = cast.ty.kind() {
+ data.principal()
+ } else {
+ bug!("Only valid to do a DynStar cast into a DynStar type")
+ };
+ let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref);
+ OperandValue::Pair(data, vtable)
+ }
mir::CastKind::Pointer(
PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
)
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index f452f2988..1db0fb3a6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -1,4 +1,5 @@
use rustc_middle::mir;
+use rustc_middle::mir::NonDivergingIntrinsic;
use super::FunctionCx;
use super::LocalRef;
@@ -73,11 +74,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.codegen_coverage(&mut bx, coverage.clone(), statement.source_info.scope);
bx
}
- mir::StatementKind::CopyNonOverlapping(box mir::CopyNonOverlapping {
- ref src,
- ref dst,
- ref count,
- }) => {
+ mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
+ let op_val = self.codegen_operand(&mut bx, op);
+ bx.assume(op_val.immediate());
+ bx
+ }
+ mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
+ mir::CopyNonOverlapping { ref count, ref src, ref dst },
+ )) => {
let dst_val = self.codegen_operand(&mut bx, dst);
let src_val = self.codegen_operand(&mut bx, src);
let count = self.codegen_operand(&mut bx, count).immediate();
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index ecad05185..0e259bcd1 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -210,8 +210,11 @@ const POWERPC_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("vsx", Some(sym::powerpc_target_feature)),
];
-const MIPS_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] =
- &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))];
+const MIPS_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+ ("fp64", Some(sym::mips_target_feature)),
+ ("msa", Some(sym::mips_target_feature)),
+ ("virt", Some(sym::mips_target_feature)),
+];
const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("m", Some(sym::riscv_target_feature)),
@@ -227,6 +230,10 @@ const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("zhinxmin", Some(sym::riscv_target_feature)),
("zfh", Some(sym::riscv_target_feature)),
("zfhmin", Some(sym::riscv_target_feature)),
+ ("zba", Some(sym::riscv_target_feature)),
+ ("zbb", Some(sym::riscv_target_feature)),
+ ("zbc", Some(sym::riscv_target_feature)),
+ ("zbs", Some(sym::riscv_target_feature)),
("zbkb", Some(sym::riscv_target_feature)),
("zbkc", Some(sym::riscv_target_feature)),
("zbkx", Some(sym::riscv_target_feature)),
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 9f49749bb..10cf8948b 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -1,6 +1,5 @@
use super::abi::AbiBuilderMethods;
use super::asm::AsmBuilderMethods;
-use super::consts::ConstMethods;
use super::coverageinfo::CoverageInfoBuilderMethods;
use super::debuginfo::DebugInfoBuilderMethods;
use super::intrinsic::IntrinsicCallMethods;
@@ -15,7 +14,6 @@ use crate::mir::operand::OperandRef;
use crate::mir::place::PlaceRef;
use crate::MemFlags;
-use rustc_apfloat::{ieee, Float, Round, Status};
use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
use rustc_middle::ty::Ty;
use rustc_span::Span;
@@ -188,8 +186,8 @@ pub trait BuilderMethods<'a, 'tcx>:
fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
- fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option<Self::Value>;
- fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option<Self::Value>;
+ fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
+ fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn fptoui(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn fptosi(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn uitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
@@ -223,156 +221,7 @@ pub trait BuilderMethods<'a, 'tcx>:
return if signed { self.fptosi(x, dest_ty) } else { self.fptoui(x, dest_ty) };
}
- let try_sat_result =
- if signed { self.fptosi_sat(x, dest_ty) } else { self.fptoui_sat(x, dest_ty) };
- if let Some(try_sat_result) = try_sat_result {
- return try_sat_result;
- }
-
- let int_width = self.cx().int_width(int_ty);
- let float_width = self.cx().float_width(float_ty);
- // LLVM's fpto[su]i returns undef when the input x is infinite, NaN, or does not fit into the
- // destination integer type after rounding towards zero. This `undef` value can cause UB in
- // safe code (see issue #10184), so we implement a saturating conversion on top of it:
- // Semantically, the mathematical value of the input is rounded towards zero to the next
- // mathematical integer, and then the result is clamped into the range of the destination
- // integer type. Positive and negative infinity are mapped to the maximum and minimum value of
- // the destination integer type. NaN is mapped to 0.
- //
- // Define f_min and f_max as the largest and smallest (finite) floats that are exactly equal to
- // a value representable in int_ty.
- // They are exactly equal to int_ty::{MIN,MAX} if float_ty has enough significand bits.
- // Otherwise, int_ty::MAX must be rounded towards zero, as it is one less than a power of two.
- // int_ty::MIN, however, is either zero or a negative power of two and is thus exactly
- // representable. Note that this only works if float_ty's exponent range is sufficiently large.
- // f16 or 256 bit integers would break this property. Right now the smallest float type is f32
- // with exponents ranging up to 127, which is barely enough for i128::MIN = -2^127.
- // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
- // we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
- // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
- let int_max = |signed: bool, int_width: u64| -> u128 {
- let shift_amount = 128 - int_width;
- if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount }
- };
- let int_min = |signed: bool, int_width: u64| -> i128 {
- if signed { i128::MIN >> (128 - int_width) } else { 0 }
- };
-
- let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) {
- let rounded_min =
- ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero);
- assert_eq!(rounded_min.status, Status::OK);
- let rounded_max =
- ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero);
- assert!(rounded_max.value.is_finite());
- (rounded_min.value.to_bits(), rounded_max.value.to_bits())
- };
- let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) {
- let rounded_min =
- ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero);
- assert_eq!(rounded_min.status, Status::OK);
- let rounded_max =
- ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero);
- assert!(rounded_max.value.is_finite());
- (rounded_min.value.to_bits(), rounded_max.value.to_bits())
- };
- // To implement saturation, we perform the following steps:
- //
- // 1. Cast x to an integer with fpto[su]i. This may result in undef.
- // 2. Compare x to f_min and f_max, and use the comparison results to select:
- // a) int_ty::MIN if x < f_min or x is NaN
- // b) int_ty::MAX if x > f_max
- // c) the result of fpto[su]i otherwise
- // 3. If x is NaN, return 0.0, otherwise return the result of step 2.
- //
- // This avoids resulting undef because values in range [f_min, f_max] by definition fit into the
- // destination type. It creates an undef temporary, but *producing* undef is not UB. Our use of
- // undef does not introduce any non-determinism either.
- // More importantly, the above procedure correctly implements saturating conversion.
- // Proof (sketch):
- // If x is NaN, 0 is returned by definition.
- // Otherwise, x is finite or infinite and thus can be compared with f_min and f_max.
- // This yields three cases to consider:
- // (1) if x in [f_min, f_max], the result of fpto[su]i is returned, which agrees with
- // saturating conversion for inputs in that range.
- // (2) if x > f_max, then x is larger than int_ty::MAX. This holds even if f_max is rounded
- // (i.e., if f_max < int_ty::MAX) because in those cases, nextUp(f_max) is already larger
- // than int_ty::MAX. Because x is larger than int_ty::MAX, the return value of int_ty::MAX
- // is correct.
- // (3) if x < f_min, then x is smaller than int_ty::MIN. As shown earlier, f_min exactly equals
- // int_ty::MIN and therefore the return value of int_ty::MIN is correct.
- // QED.
-
- let float_bits_to_llval = |bx: &mut Self, bits| {
- let bits_llval = match float_width {
- 32 => bx.cx().const_u32(bits as u32),
- 64 => bx.cx().const_u64(bits as u64),
- n => bug!("unsupported float width {}", n),
- };
- bx.bitcast(bits_llval, float_ty)
- };
- let (f_min, f_max) = match float_width {
- 32 => compute_clamp_bounds_single(signed, int_width),
- 64 => compute_clamp_bounds_double(signed, int_width),
- n => bug!("unsupported float width {}", n),
- };
- let f_min = float_bits_to_llval(self, f_min);
- let f_max = float_bits_to_llval(self, f_max);
- let int_max = self.cx().const_uint_big(int_ty, int_max(signed, int_width));
- let int_min = self.cx().const_uint_big(int_ty, int_min(signed, int_width) as u128);
- let zero = self.cx().const_uint(int_ty, 0);
-
- // If we're working with vectors, constants must be "splatted": the constant is duplicated
- // into each lane of the vector. The algorithm stays the same, we are just using the
- // same constant across all lanes.
- let maybe_splat = |bx: &mut Self, val| {
- if bx.cx().type_kind(dest_ty) == TypeKind::Vector {
- bx.vector_splat(bx.vector_length(dest_ty), val)
- } else {
- val
- }
- };
- let f_min = maybe_splat(self, f_min);
- let f_max = maybe_splat(self, f_max);
- let int_max = maybe_splat(self, int_max);
- let int_min = maybe_splat(self, int_min);
- let zero = maybe_splat(self, zero);
-
- // Step 1 ...
- let fptosui_result = if signed { self.fptosi(x, dest_ty) } else { self.fptoui(x, dest_ty) };
- let less_or_nan = self.fcmp(RealPredicate::RealULT, x, f_min);
- let greater = self.fcmp(RealPredicate::RealOGT, x, f_max);
-
- // Step 2: We use two comparisons and two selects, with %s1 being the
- // result:
- // %less_or_nan = fcmp ult %x, %f_min
- // %greater = fcmp olt %x, %f_max
- // %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result
- // %s1 = select %greater, int_ty::MAX, %s0
- // Note that %less_or_nan uses an *unordered* comparison. This
- // comparison is true if the operands are not comparable (i.e., if x is
- // NaN). The unordered comparison ensures that s1 becomes int_ty::MIN if
- // x is NaN.
- //
- // Performance note: Unordered comparison can be lowered to a "flipped"
- // comparison and a negation, and the negation can be merged into the
- // select. Therefore, it not necessarily any more expensive than an
- // ordered ("normal") comparison. Whether these optimizations will be
- // performed is ultimately up to the backend, but at least x86 does
- // perform them.
- let s0 = self.select(less_or_nan, int_min, fptosui_result);
- let s1 = self.select(greater, int_max, s0);
-
- // Step 3: NaN replacement.
- // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN.
- // Therefore we only need to execute this step for signed integer types.
- if signed {
- // LLVM has no isNaN predicate, so we use (x == x) instead
- let cmp = self.fcmp(RealPredicate::RealOEQ, x, x);
- self.select(cmp, s1, zero)
- } else {
- s1
- }
+ if signed { self.fptosi_sat(x, dest_ty) } else { self.fptoui_sat(x, dest_ty) }
}
fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index 8a91d4735..fdc7a30e8 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -29,7 +29,6 @@ pub trait ConstMethods<'tcx>: BackendTypes {
fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value;
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value;
- fn zst_to_backend(&self, llty: Self::Type) -> Self::Value;
fn from_const_alloc(
&self,
layout: TyAndLayout<'tcx>,
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 322bfd5ce..09d53331b 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -9,13 +9,13 @@ use rustc_span::{Span, Symbol};
use super::InterpCx;
use crate::interpret::{
- struct_error, ErrorHandled, FrameInfo, InterpError, InterpErrorInfo, Machine, MachineStopType, UnsupportedOpInfo,
+ struct_error, ErrorHandled, FrameInfo, InterpError, InterpErrorInfo, Machine, MachineStopType,
+ UnsupportedOpInfo,
};
/// The CTFE machine has some custom error kinds.
#[derive(Clone, Debug)]
pub enum ConstEvalErrKind {
- NeedsRfc(String),
ConstAccessesStatic,
ModifiedGlobal,
AssertFailure(AssertKind<ConstInt>),
@@ -42,9 +42,6 @@ impl fmt::Display for ConstEvalErrKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::ConstEvalErrKind::*;
match *self {
- NeedsRfc(ref msg) => {
- write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg)
- }
ConstAccessesStatic => write!(f, "constant accesses static"),
ModifiedGlobal => {
write!(f, "modifying a static's initial value from another static's initializer")
@@ -158,6 +155,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
InterpError::Unsupported(
UnsupportedOpInfo::ReadPointerAsBytes
| UnsupportedOpInfo::PartialPointerOverwrite(_)
+ | UnsupportedOpInfo::PartialPointerCopy(_),
) => {
err.help("this code performed an operation that depends on the underlying bytes representing a pointer");
err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
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 975fb4b22..a2f14e753 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -2,8 +2,8 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
use crate::interpret::eval_nullary_intrinsic;
use crate::interpret::{
intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
- Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
- ScalarMaybeUninit, StackPopCleanup, InterpError,
+ Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
+ RefTracking, StackPopCleanup,
};
use rustc_hir::def::DefKind;
@@ -74,14 +74,16 @@ fn eval_body_using_ecx<'mir, 'tcx>(
None => InternKind::Constant,
}
};
+ ecx.machine.check_alignment = false; // interning doesn't need to respect alignment
intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
+ // we leave alignment checks off, since this `ecx` will not be used for further evaluation anyway
debug!("eval_body_using_ecx done: {:?}", *ret);
Ok(ret)
}
/// The `InterpCx` is only meant to be used to do field and index projections into constants for
-/// `simd_shuffle` and const patterns in match arms.
+/// `simd_shuffle` and const patterns in match arms. It never performs alignment checks.
///
/// The function containing the `match` that is currently being analyzed may have generic bounds
/// that inform us about the generic bounds of the constant. E.g., using an associated constant
@@ -98,7 +100,11 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
tcx,
root_span,
param_env,
- CompileTimeInterpreter::new(tcx.const_eval_limit(), can_access_statics),
+ CompileTimeInterpreter::new(
+ tcx.const_eval_limit(),
+ can_access_statics,
+ /*check_alignment:*/ false,
+ ),
)
}
@@ -166,10 +172,7 @@ pub(super) fn op_to_const<'tcx>(
// see comment on `let try_as_immediate` above
Err(imm) => match *imm {
_ if imm.layout.is_zst() => ConstValue::ZeroSized,
- Immediate::Scalar(x) => match x {
- ScalarMaybeUninit::Scalar(s) => ConstValue::Scalar(s),
- ScalarMaybeUninit::Uninit => to_const_value(&op.assert_mem_place()),
- },
+ Immediate::Scalar(x) => ConstValue::Scalar(x),
Immediate::ScalarPair(a, b) => {
debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
// We know `offset` is relative to the allocation, so we can use `into_parts`.
@@ -194,7 +197,7 @@ pub(super) fn op_to_const<'tcx>(
}
}
-#[instrument(skip(tcx), level = "debug")]
+#[instrument(skip(tcx), level = "debug", ret)]
pub(crate) fn turn_into_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
constant: ConstAlloc<'tcx>,
@@ -203,7 +206,13 @@ pub(crate) fn turn_into_const_value<'tcx>(
let cid = key.value;
let def_id = cid.instance.def.def_id();
let is_static = tcx.is_static(def_id);
- let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static);
+ // This is just accessing an already computed constant, so no need to check alginment here.
+ let ecx = mk_eval_cx(
+ tcx,
+ tcx.def_span(key.value.instance.def_id()),
+ key.param_env,
+ /*can_access_statics:*/ is_static,
+ );
let mplace = ecx.raw_const_to_mplace(constant).expect(
"can only fail if layout computation failed, \
@@ -215,10 +224,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
);
// Turn this into a proper constant.
- let const_val = op_to_const(&ecx, &mplace.into());
- debug!(?const_val);
-
- const_val
+ op_to_const(&ecx, &mplace.into())
}
#[instrument(skip(tcx), level = "debug")]
@@ -300,7 +306,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
key.param_env,
// Statics (and promoteds inside statics) may access other statics, because unlike consts
// they do not have to behave "as if" they were evaluated at runtime.
- CompileTimeInterpreter::new(tcx.const_eval_limit(), /*can_access_statics:*/ is_static),
+ CompileTimeInterpreter::new(
+ tcx.const_eval_limit(),
+ /*can_access_statics:*/ is_static,
+ /*check_alignment:*/ tcx.sess.opts.unstable_opts.extra_const_ub_checks,
+ ),
);
let res = ecx.load_mir(cid.instance.def, cid.promoted);
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index fc2e6652a..e5acacd91 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -35,21 +35,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
// All `#[rustc_do_not_const_check]` functions should be hooked here.
let def_id = instance.def_id();
- if Some(def_id) == self.tcx.lang_items().const_eval_select() {
- // redirect to const_eval_select_ct
- if let Some(const_eval_select) = self.tcx.lang_items().const_eval_select_ct() {
- return Ok(Some(
- ty::Instance::resolve(
- *self.tcx,
- ty::ParamEnv::reveal_all(),
- const_eval_select,
- instance.substs,
- )
- .unwrap()
- .unwrap(),
- ));
- }
- } else if Some(def_id) == self.tcx.lang_items().panic_display()
+ if Some(def_id) == self.tcx.lang_items().panic_display()
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
{
// &str or &&str
@@ -89,10 +75,10 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
/// exhaustion error.
///
/// Setting this to `0` disables the limit and allows the interpreter to run forever.
- pub steps_remaining: usize,
+ pub(super) steps_remaining: usize,
/// The virtual call stack.
- pub(crate) stack: Vec<Frame<'mir, 'tcx, AllocId, ()>>,
+ pub(super) stack: Vec<Frame<'mir, 'tcx, AllocId, ()>>,
/// We need to make sure consts never point to anything mutable, even recursively. That is
/// relied on for pattern matching on consts with references.
@@ -101,14 +87,22 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
/// This boolean here controls the second part.
pub(super) can_access_statics: bool,
+
+ /// Whether to check alignment during evaluation.
+ pub(super) check_alignment: bool,
}
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
- pub(crate) fn new(const_eval_limit: Limit, can_access_statics: bool) -> Self {
+ pub(crate) fn new(
+ const_eval_limit: Limit,
+ can_access_statics: bool,
+ check_alignment: bool,
+ ) -> Self {
CompileTimeInterpreter {
steps_remaining: const_eval_limit.0,
stack: Vec::new(),
can_access_statics,
+ check_alignment,
}
}
}
@@ -197,34 +191,35 @@ impl interpret::MayLeak for ! {
}
impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
- fn guaranteed_eq(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, bool> {
+ /// See documentation on the `ptr_guaranteed_cmp` intrinsic.
+ fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
Ok(match (a, b) {
// Comparisons between integers are always known.
- (Scalar::Int { .. }, Scalar::Int { .. }) => a == b,
- // Equality with integers can never be known for sure.
- (Scalar::Int { .. }, Scalar::Ptr(..)) | (Scalar::Ptr(..), Scalar::Int { .. }) => false,
- // FIXME: return `true` for when both sides are the same pointer, *except* that
- // some things (like functions and vtables) do not have stable addresses
- // so we need to be careful around them (see e.g. #73722).
- (Scalar::Ptr(..), Scalar::Ptr(..)) => false,
- })
- }
-
- fn guaranteed_ne(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, bool> {
- Ok(match (a, b) {
- // Comparisons between integers are always known.
- (Scalar::Int(_), Scalar::Int(_)) => a != b,
+ (Scalar::Int { .. }, Scalar::Int { .. }) => {
+ if a == b {
+ 1
+ } else {
+ 0
+ }
+ }
// Comparisons of abstract pointers with null pointers are known if the pointer
// is in bounds, because if they are in bounds, the pointer can't be null.
// Inequality with integers other than null can never be known for sure.
(Scalar::Int(int), ptr @ Scalar::Ptr(..))
- | (ptr @ Scalar::Ptr(..), Scalar::Int(int)) => {
- int.is_null() && !self.scalar_may_be_null(ptr)?
+ | (ptr @ Scalar::Ptr(..), Scalar::Int(int))
+ if int.is_null() && !self.scalar_may_be_null(ptr)? =>
+ {
+ 0
}
- // FIXME: return `true` for at least some comparisons where we can reliably
+ // Equality with integers can never be known for sure.
+ (Scalar::Int { .. }, Scalar::Ptr(..)) | (Scalar::Ptr(..), Scalar::Int { .. }) => 2,
+ // FIXME: return a `1` for when both sides are the same pointer, *except* that
+ // some things (like functions and vtables) do not have stable addresses
+ // so we need to be careful around them (see e.g. #73722).
+ // FIXME: return `0` for at least some comparisons where we can reliably
// determine the result of runtime inequality tests at compile-time.
// Examples include comparison of addresses in different static items.
- (Scalar::Ptr(..), Scalar::Ptr(..)) => false,
+ (Scalar::Ptr(..), Scalar::Ptr(..)) => 2,
})
}
}
@@ -236,6 +231,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
+ #[inline(always)]
+ fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ ecx.machine.check_alignment
+ }
+
+ #[inline(always)]
+ fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
+ }
+
fn load_mir(
ecx: &InterpCx<'mir, 'tcx, Self>,
instance: ty::InstanceDef<'tcx>,
@@ -251,9 +256,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
);
throw_inval!(AlreadyReported(guar));
} else {
+ // `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
+ // so this should be unreachable.
let path = ecx.tcx.def_path_str(def.did);
- Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path))
- .into())
+ bug!("trying to call extern function `{path}` at compile-time");
}
}
_ => Ok(ecx.tcx.instance_mir(instance)),
@@ -321,22 +327,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
// CTFE-specific intrinsics.
let Some(ret) = target else {
- return Err(ConstEvalErrKind::NeedsRfc(format!(
- "calling intrinsic `{}`",
- intrinsic_name
- ))
- .into());
+ throw_unsup_format!("intrinsic `{intrinsic_name}` is not supported at compile-time");
};
match intrinsic_name {
- sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
- let a = ecx.read_immediate(&args[0])?.to_scalar()?;
- let b = ecx.read_immediate(&args[1])?.to_scalar()?;
- let cmp = if intrinsic_name == sym::ptr_guaranteed_eq {
- ecx.guaranteed_eq(a, b)?
- } else {
- ecx.guaranteed_ne(a, b)?
- };
- ecx.write_scalar(Scalar::from_bool(cmp), dest)?;
+ sym::ptr_guaranteed_cmp => {
+ let a = ecx.read_scalar(&args[0])?;
+ let b = ecx.read_scalar(&args[1])?;
+ let cmp = ecx.guaranteed_cmp(a, b)?;
+ ecx.write_scalar(Scalar::from_u8(cmp), dest)?;
}
sym::const_allocate => {
let size = ecx.read_scalar(&args[0])?.to_machine_usize(ecx)?;
@@ -382,11 +380,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
}
}
_ => {
- return Err(ConstEvalErrKind::NeedsRfc(format!(
- "calling intrinsic `{}`",
- intrinsic_name
- ))
- .into());
+ throw_unsup_format!(
+ "intrinsic `{intrinsic_name}` is not supported at compile-time"
+ );
}
}
@@ -429,7 +425,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
_left: &ImmTy<'tcx>,
_right: &ImmTy<'tcx>,
) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
- Err(ConstEvalErrKind::NeedsRfc("pointer arithmetic or comparison".to_string()).into())
+ throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
}
fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
@@ -451,7 +447,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_ptr: Pointer<AllocId>,
) -> InterpResult<'tcx> {
- Err(ConstEvalErrKind::NeedsRfc("exposing pointers".to_string()).into())
+ // This is only reachable with -Zunleash-the-miri-inside-of-you.
+ throw_unsup_format!("exposing pointers is not possible at compile-time")
}
#[inline(always)]
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 948c33494..d9c4ae4d5 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -1,16 +1,16 @@
// Not in interpret to make sure we do not use private implementation details
+use crate::errors::MaxNumNodesInConstErr;
+use crate::interpret::{
+ intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta,
+ Scalar,
+};
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 crate::interpret::{
- intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta,
- Scalar,
-};
-
mod error;
mod eval_queries;
mod fn_queries;
@@ -72,12 +72,17 @@ pub(crate) fn eval_to_valtree<'tcx>(
Ok(valtree) => Ok(Some(valtree)),
Err(err) => {
let did = cid.instance.def_id();
- let s = cid.display(tcx);
+ let global_const_id = cid.display(tcx);
match err {
ValTreeCreationError::NodesOverflow => {
- let msg = format!("maximum number of nodes exceeded in constant {}", &s);
+ let msg = format!(
+ "maximum number of nodes exceeded in constant {}",
+ &global_const_id
+ );
let mut diag = match tcx.hir().span_if_local(did) {
- Some(span) => tcx.sess.struct_span_err(span, &msg),
+ Some(span) => {
+ tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id })
+ }
None => tcx.sess.struct_err(&msg),
};
diag.emit();
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 8fff4571d..a964fe846 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -3,7 +3,7 @@ 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,
+ MemoryKind, PlaceTy, Scalar,
};
use crate::interpret::{MPlaceTy, Value};
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
@@ -90,14 +90,14 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
let Ok(val) = ecx.read_immediate(&place.into()) else {
return Err(ValTreeCreationError::Other);
};
- let val = val.to_scalar().unwrap();
+ let val = val.to_scalar();
*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`).
+ // equality at compile-time (see `ptr_guaranteed_cmp`).
// 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(_) => Err(ValTreeCreationError::NonSupportedType),
@@ -204,7 +204,7 @@ fn get_info_on_unsized_field<'tcx>(
(unsized_inner_ty, num_elems)
}
-#[instrument(skip(ecx), level = "debug")]
+#[instrument(skip(ecx), level = "debug", ret)]
fn create_pointee_place<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
ty: Ty<'tcx>,
@@ -237,14 +237,11 @@ fn create_pointee_place<'tcx>(
let ptr = ecx.allocate_ptr(size, align, MemoryKind::Stack).unwrap();
debug!(?ptr);
- let place = MPlaceTy::from_aligned_ptr_with_meta(
+ MPlaceTy::from_aligned_ptr_with_meta(
ptr.into(),
layout,
MemPlaceMeta::Meta(Scalar::from_machine_usize(num_elems as u64, &tcx)),
- );
- debug!(?place);
-
- place
+ )
} else {
create_mplace_from_layout(ecx, ty)
}
@@ -253,7 +250,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 `valtree_into_mplace` into one function
-#[instrument(skip(tcx), level = "debug")]
+#[instrument(skip(tcx), level = "debug", ret)]
pub fn valtree_to_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
@@ -294,7 +291,7 @@ pub fn valtree_to_const_value<'tcx>(
dump_place(&ecx, place.into());
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
- let const_val = match ty.kind() {
+ match ty.kind() {
ty::Ref(_, _, _) => {
let ref_place = place.to_ref(&tcx);
let imm =
@@ -303,10 +300,7 @@ pub fn valtree_to_const_value<'tcx>(
op_to_const(&ecx, &imm.into())
}
_ => op_to_const(&ecx, &place.into()),
- };
- debug!(?const_val);
-
- const_val
+ }
}
ty::Never
| ty::Error(_)
@@ -349,11 +343,7 @@ fn valtree_into_mplace<'tcx>(
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
let scalar_int = valtree.unwrap_leaf();
debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place);
- ecx.write_immediate(
- Immediate::Scalar(ScalarMaybeUninit::Scalar(scalar_int.into())),
- &place.into(),
- )
- .unwrap();
+ ecx.write_immediate(Immediate::Scalar(scalar_int.into()), &place.into()).unwrap();
}
ty::Ref(_, inner_ty, _) => {
let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree);
@@ -366,11 +356,10 @@ fn valtree_into_mplace<'tcx>(
let imm = match inner_ty.kind() {
ty::Slice(_) | ty::Str => {
let len = valtree.unwrap_branch().len();
- let len_scalar =
- ScalarMaybeUninit::Scalar(Scalar::from_machine_usize(len as u64, &tcx));
+ let len_scalar = Scalar::from_machine_usize(len as u64, &tcx);
Immediate::ScalarPair(
- ScalarMaybeUninit::from_maybe_pointer((*pointee_place).ptr, &tcx),
+ Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx),
len_scalar,
)
}
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index a463fe7b9..c3547cb3a 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -3,7 +3,7 @@ use rustc_macros::SessionDiagnostic;
use rustc_span::Span;
#[derive(SessionDiagnostic)]
-#[error(const_eval::unstable_in_stable)]
+#[diag(const_eval::unstable_in_stable)]
pub(crate) struct UnstableInStable {
pub gate: String,
#[primary_span]
@@ -22,14 +22,14 @@ pub(crate) struct UnstableInStable {
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::thread_local_access, code = "E0625")]
+#[diag(const_eval::thread_local_access, code = "E0625")]
pub(crate) struct NonConstOpErr {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::static_access, code = "E0013")]
+#[diag(const_eval::static_access, code = "E0013")]
#[help]
pub(crate) struct StaticAccessErr {
#[primary_span]
@@ -41,7 +41,7 @@ pub(crate) struct StaticAccessErr {
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::raw_ptr_to_int)]
+#[diag(const_eval::raw_ptr_to_int)]
#[note]
#[note(const_eval::note2)]
pub(crate) struct RawPtrToIntErr {
@@ -50,7 +50,7 @@ pub(crate) struct RawPtrToIntErr {
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::raw_ptr_comparison)]
+#[diag(const_eval::raw_ptr_comparison)]
#[note]
pub(crate) struct RawPtrComparisonErr {
#[primary_span]
@@ -58,14 +58,14 @@ pub(crate) struct RawPtrComparisonErr {
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::panic_non_str)]
+#[diag(const_eval::panic_non_str)]
pub(crate) struct PanicNonStrErr {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::mut_deref, code = "E0658")]
+#[diag(const_eval::mut_deref, code = "E0658")]
pub(crate) struct MutDerefErr {
#[primary_span]
pub span: Span,
@@ -73,7 +73,7 @@ pub(crate) struct MutDerefErr {
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::transient_mut_borrow, code = "E0658")]
+#[diag(const_eval::transient_mut_borrow, code = "E0658")]
pub(crate) struct TransientMutBorrowErr {
#[primary_span]
pub span: Span,
@@ -81,9 +81,116 @@ pub(crate) struct TransientMutBorrowErr {
}
#[derive(SessionDiagnostic)]
-#[error(const_eval::transient_mut_borrow_raw, code = "E0658")]
+#[diag(const_eval::transient_mut_borrow_raw, code = "E0658")]
pub(crate) struct TransientMutBorrowErrRaw {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::max_num_nodes_in_const)]
+pub(crate) struct MaxNumNodesInConstErr {
+ #[primary_span]
+ pub span: Span,
+ pub global_const_id: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unallowed_fn_pointer_call)]
+pub(crate) struct UnallowedFnPointerCall {
+ #[primary_span]
+ pub span: Span,
+ pub kind: ConstContext,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unstable_const_fn)]
+pub(crate) struct UnstableConstFn {
+ #[primary_span]
+ pub span: Span,
+ pub def_path: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unallowed_mutable_refs, code = "E0764")]
+pub(crate) struct UnallowedMutableRefs {
+ #[primary_span]
+ pub span: Span,
+ pub kind: ConstContext,
+ #[note(const_eval::teach_note)]
+ pub teach: Option<()>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unallowed_mutable_refs_raw, code = "E0764")]
+pub(crate) struct UnallowedMutableRefsRaw {
+ #[primary_span]
+ pub span: Span,
+ pub kind: ConstContext,
+ #[note(const_eval::teach_note)]
+ pub teach: Option<()>,
+}
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::non_const_fmt_macro_call, code = "E0015")]
+pub(crate) struct NonConstFmtMacroCall {
+ #[primary_span]
+ pub span: Span,
+ pub kind: ConstContext,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::non_const_fn_call, code = "E0015")]
+pub(crate) struct NonConstFnCall {
+ #[primary_span]
+ pub span: Span,
+ pub def_path_str: String,
+ pub kind: ConstContext,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unallowed_op_in_const_context)]
+pub(crate) struct UnallowedOpInConstContext {
+ #[primary_span]
+ pub span: Span,
+ pub msg: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unallowed_heap_allocations, code = "E0010")]
+pub(crate) struct UnallowedHeapAllocations {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub kind: ConstContext,
+ #[note(const_eval::teach_note)]
+ pub teach: Option<()>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::unallowed_inline_asm, code = "E0015")]
+pub(crate) struct UnallowedInlineAsm {
+ #[primary_span]
+ pub span: Span,
+ pub kind: ConstContext,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::interior_mutable_data_refer, code = "E0492")]
+pub(crate) struct InteriorMutableDataRefer {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[help]
+ pub opt_help: Option<()>,
+ pub kind: ConstContext,
+ #[note(const_eval::teach_note)]
+ pub teach: Option<()>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(const_eval::interior_mutability_borrow)]
+pub(crate) struct InteriorMutabilityBorrow {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index c97c31eb9..cbe985480 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -108,6 +108,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
_ => span_bug!(self.cur_span(), "closure fn pointer on {:?}", src.layout.ty),
}
}
+
+ DynStar => {
+ if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
+ // Initial cast from sized to dyn trait
+ let vtable = self.get_vtable_ptr(src.layout.ty, data.principal())?;
+ let vtable = Scalar::from_maybe_pointer(vtable, self);
+ let data = self.read_immediate(src)?.to_scalar();
+ let _assert_pointer_sized = data.to_pointer(self)?;
+ let val = Immediate::ScalarPair(data, vtable);
+ self.write_immediate(val, dest)?;
+ } else {
+ bug!()
+ }
+ }
}
Ok(())
}
@@ -123,10 +137,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match src.layout.ty.kind() {
// Floating point
Float(FloatTy::F32) => {
- return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, cast_ty).into());
+ return Ok(self.cast_from_float(src.to_scalar().to_f32()?, cast_ty).into());
}
Float(FloatTy::F64) => {
- return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, cast_ty).into());
+ return Ok(self.cast_from_float(src.to_scalar().to_f64()?, cast_ty).into());
}
// The rest is integer/pointer-"like", including fn ptr casts
_ => assert!(
@@ -153,7 +167,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_eq!(dest_layout.size, self.pointer_size());
assert!(src.layout.ty.is_unsafe_ptr());
return match **src {
- Immediate::ScalarPair(data, _) => Ok(data.check_init()?.into()),
+ Immediate::ScalarPair(data, _) => Ok(data.into()),
Immediate::Scalar(..) => span_bug!(
self.cur_span(),
"{:?} input to a fat-to-thin cast ({:?} -> {:?})",
@@ -167,7 +181,7 @@ 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()?;
+ let scalar = src.to_scalar();
Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
}
@@ -179,7 +193,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_matches!(src.layout.ty.kind(), ty::RawPtr(_) | ty::FnPtr(_));
assert!(cast_ty.is_integral());
- let scalar = src.to_scalar()?;
+ let scalar = src.to_scalar();
let ptr = scalar.to_pointer(self)?;
match ptr.into_pointer_or_addr() {
Ok(ptr) => M::expose_ptr(self, ptr)?,
@@ -197,7 +211,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_matches!(cast_ty.kind(), ty::RawPtr(_));
// First cast to usize.
- let scalar = src.to_scalar()?;
+ 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)?;
@@ -291,14 +305,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
(&ty::Array(_, length), &ty::Slice(_)) => {
- let ptr = self.read_immediate(src)?.to_scalar()?;
+ let ptr = self.read_scalar(src)?;
// u64 cast is from usize to u64, which is always good
let val =
Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env), self);
self.write_immediate(val, dest)
}
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
- let (old_data, old_vptr) = self.read_immediate(src)?.to_scalar_pair()?;
+ let val = self.read_immediate(src)?;
+ if data_a.principal() == data_b.principal() {
+ // A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables.
+ return self.write_immediate(*val, dest);
+ }
+ let (old_data, old_vptr) = val.to_scalar_pair();
let old_vptr = old_vptr.to_pointer(self)?;
let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?;
if old_trait != data_a.principal() {
@@ -307,10 +326,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?;
self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
}
- (_, &ty::Dynamic(ref data, _)) => {
+ (_, &ty::Dynamic(ref data, _, ty::Dyn)) => {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?;
- let ptr = self.read_immediate(src)?.to_scalar()?;
+ let ptr = self.read_scalar(src)?;
let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx);
self.write_immediate(val, dest)
}
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 150d6589b..d37eaeed0 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -21,7 +21,7 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou
use super::{
AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace,
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance,
- Scalar, ScalarMaybeUninit, StackPopJump,
+ Scalar, StackPopJump,
};
use crate::transform::validate::equal_up_to_regions;
@@ -187,9 +187,6 @@ pub enum LocalValue<Prov: Provenance = AllocId> {
impl<'tcx, Prov: Provenance + 'static> LocalState<'tcx, Prov> {
/// Read the local's value or error if the local is not yet live or not live anymore.
- ///
- /// Note: This may only be invoked from the `Machine::access_local` hook and not from
- /// anywhere else. You may be invalidating machine invariants if you do!
#[inline]
pub fn access(&self) -> InterpResult<'tcx, &Operand<Prov>> {
match &self.value {
@@ -782,7 +779,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_eq!(
unwinding,
match self.frame().loc {
- Ok(loc) => self.body().basic_blocks()[loc.block].is_cleanup,
+ Ok(loc) => self.body().basic_blocks[loc.block].is_cleanup,
Err(_) => true,
}
);
@@ -991,16 +988,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
}
LocalValue::Live(Operand::Immediate(Immediate::Scalar(val))) => {
write!(fmt, " {:?}", val)?;
- if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val {
+ if let Scalar::Ptr(ptr, _size) = val {
allocs.push(ptr.provenance.get_alloc_id());
}
}
LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(val1, val2))) => {
write!(fmt, " ({:?}, {:?})", val1, val2)?;
- if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val1 {
+ if let Scalar::Ptr(ptr, _size) = val1 {
allocs.push(ptr.provenance.get_alloc_id());
}
- if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val2 {
+ if let Scalar::Ptr(ptr, _size) = val2 {
allocs.push(ptr.provenance.get_alloc_id());
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 376b8872c..24dbc7695 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
alloc.mutability = Mutability::Not;
};
// link the alloc id to the actual allocation
- leftover_allocations.extend(alloc.relocations().iter().map(|&(_, alloc_id)| alloc_id));
+ leftover_allocations.extend(alloc.provenance().iter().map(|&(_, alloc_id)| alloc_id));
let alloc = tcx.intern_const_alloc(alloc);
tcx.set_alloc_id_memory(alloc_id, alloc);
None
@@ -191,10 +191,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
return Ok(true);
};
- // If there are no relocations in this allocation, it does not contain references
+ // If there is no provenance in this allocation, it does not contain references
// that point to another allocation, and we can avoid the interning walk.
if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? {
- if !alloc.has_relocations() {
+ if !alloc.has_provenance() {
return Ok(false);
}
} else {
@@ -233,8 +233,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
}
fn visit_value(&mut self, mplace: &MPlaceTy<'tcx>) -> InterpResult<'tcx> {
- // Handle Reference types, as these are the only relocations supported by const eval.
- // Raw pointers (and boxes) are handled by the `leftover_relocations` logic.
+ // Handle Reference types, as these are the only types with provenance supported by const eval.
+ // Raw pointers (and boxes) are handled by the `leftover_allocations` logic.
let tcx = self.ecx.tcx;
let ty = mplace.layout.ty;
if let ty::Ref(_, referenced_ty, ref_mutability) = *ty.kind() {
@@ -334,7 +334,7 @@ pub enum InternKind {
/// tracks where in the value we are and thus can show much better error messages.
/// Any errors here would anyway be turned into `const_err` lints, whereas validation failures
/// are hard errors.
-#[tracing::instrument(level = "debug", skip(ecx))]
+#[instrument(level = "debug", skip(ecx))]
pub fn intern_const_alloc_recursive<
'mir,
'tcx: 'mir,
@@ -410,7 +410,7 @@ pub fn intern_const_alloc_recursive<
// references and a `leftover_allocations` set (where we only have a todo-list here).
// So we hand-roll the interning logic here again.
match intern_kind {
- // Statics may contain mutable allocations even behind relocations.
+ // Statics may point to mutable allocations.
// Even for immutable statics it would be ok to have mutable allocations behind
// raw pointers, e.g. for `static FOO: *const AtomicUsize = &AtomicUsize::new(42)`.
InternKind::Static(_) => {}
@@ -441,7 +441,7 @@ pub fn intern_const_alloc_recursive<
}
let alloc = tcx.intern_const_alloc(alloc);
tcx.set_alloc_id_memory(alloc_id, alloc);
- for &(_, alloc_id) in alloc.inner().relocations().iter() {
+ for &(_, alloc_id) in alloc.inner().provenance().iter() {
if leftover_allocations.insert(alloc_id) {
todo.push(alloc_id);
}
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 08209eb79..8637d6a77 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::mir::{
self,
interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
- BinOp,
+ BinOp, NonDivergingIntrinsic,
};
use rustc_middle::ty;
use rustc_middle::ty::layout::LayoutOf as _;
@@ -79,9 +79,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
ty::Projection(_)
| ty::Opaque(_, _)
| ty::Param(_)
- | ty::Bound(_, _)
| ty::Placeholder(_)
| ty::Infer(_) => throw_inval!(TooGeneric),
+ ty::Bound(_, _) => bug!("bound ty during ctfe"),
ty::Bool
| ty::Char
| ty::Int(_)
@@ -95,7 +95,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(_)
- | ty::Dynamic(_, _)
+ | ty::Dynamic(_, _, _)
| ty::Closure(_, _)
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
@@ -184,7 +184,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
| sym::bitreverse => {
let ty = substs.type_at(0);
let layout_of = self.layout_of(ty)?;
- let val = self.read_scalar(&args[0])?.check_init()?;
+ let val = self.read_scalar(&args[0])?;
let bits = val.to_bits(layout_of.size)?;
let kind = match layout_of.abi {
Abi::Scalar(scalar) => scalar.primitive(),
@@ -256,7 +256,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, &l, &r)?;
if overflowed {
let layout = self.layout_of(substs.type_at(0))?;
- let r_val = r.to_scalar()?.to_bits(layout.size)?;
+ let r_val = r.to_scalar().to_bits(layout.size)?;
if let sym::unchecked_shl | sym::unchecked_shr = intrinsic_name {
throw_ub_format!("overflowing shift by {} in `{}`", r_val, intrinsic_name);
} else {
@@ -269,9 +269,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
let layout = self.layout_of(substs.type_at(0))?;
- let val = self.read_scalar(&args[0])?.check_init()?;
+ let val = self.read_scalar(&args[0])?;
let val_bits = val.to_bits(layout.size)?;
- let raw_shift = self.read_scalar(&args[1])?.check_init()?;
+ let raw_shift = self.read_scalar(&args[1])?;
let raw_shift_bits = raw_shift.to_bits(layout.size)?;
let width_bits = u128::from(layout.size.bits());
let shift_bits = raw_shift_bits % width_bits;
@@ -320,7 +320,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
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.
+ // Neither pointer points to an allocation.
// If these are inequal or null, this *will* fail the deref check below.
(a, b)
}
@@ -506,12 +506,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// These just return their argument
self.copy_op(&args[0], dest, /*allow_transmute*/ false)?;
}
- sym::assume => {
- let cond = self.read_scalar(&args[0])?.check_init()?.to_bool()?;
- if !cond {
- throw_ub_format!("`assume` intrinsic called with `false`");
- }
- }
sym::raw_eq => {
let result = self.raw_eq_intrinsic(&args[0], &args[1])?;
self.write_scalar(result, dest)?;
@@ -536,6 +530,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(true)
}
+ pub(super) fn emulate_nondiverging_intrinsic(
+ &mut self,
+ intrinsic: &NonDivergingIntrinsic<'tcx>,
+ ) -> InterpResult<'tcx> {
+ match intrinsic {
+ NonDivergingIntrinsic::Assume(op) => {
+ let op = self.eval_operand(op, None)?;
+ let cond = self.read_scalar(&op)?.to_bool()?;
+ if !cond {
+ throw_ub_format!("`assume` called with `false`");
+ }
+ Ok(())
+ }
+ NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
+ count,
+ src,
+ dst,
+ }) => {
+ let src = self.eval_operand(src, None)?;
+ let dst = self.eval_operand(dst, None)?;
+ let count = self.eval_operand(count, None)?;
+ self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)
+ }
+ }
+ }
+
pub fn exact_div(
&mut self,
a: &ImmTy<'tcx, M::Provenance>,
@@ -570,7 +590,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// term since the sign of the second term can be inferred from this and
// the fact that the operation has overflowed (if either is 0 no
// overflow can occur)
- let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?;
+ let first_term: u128 = l.to_scalar().to_bits(l.layout.size)?;
let first_term_positive = first_term & (1 << (num_bits - 1)) == 0;
if first_term_positive {
// Negative overflow not possible since the positive first term
@@ -687,10 +707,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap().ty)?;
assert!(!layout.is_unsized());
- let lhs = self.read_pointer(lhs)?;
- let rhs = self.read_pointer(rhs)?;
- let lhs_bytes = self.read_bytes_ptr(lhs, layout.size)?;
- let rhs_bytes = self.read_bytes_ptr(rhs, layout.size)?;
+ let get_bytes = |this: &InterpCx<'mir, 'tcx, M>,
+ op: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>,
+ size|
+ -> InterpResult<'tcx, &[u8]> {
+ let ptr = this.read_pointer(op)?;
+ let Some(alloc_ref) = self.get_ptr_alloc(ptr, size, Align::ONE)? else {
+ // zero-sized access
+ return Ok(&[]);
+ };
+ if alloc_ref.has_provenance() {
+ throw_ub_format!("`raw_eq` on bytes with provenance");
+ }
+ alloc_ref.get_bytes_strip_provenance()
+ };
+
+ let lhs_bytes = get_bytes(self, lhs, layout.size)?;
+ let rhs_bytes = get_bytes(self, rhs, layout.size)?;
Ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
}
}
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 5864b9215..91f4f0425 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
@@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let mut source_info = *frame.body.source_info(loc);
// If this is a `Call` terminator, use the `fn_span` instead.
- let block = &frame.body.basic_blocks()[loc.block];
+ let block = &frame.body.basic_blocks[loc.block];
if loc.statement_index == block.statements.len() {
debug!(
"find_closest_untracked_caller_location: got terminator {:?} ({:?})",
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 f9847742f..7e4c5fcb0 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
@@ -48,7 +48,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
| ty::FnPtr(_)
| ty::Never
| ty::Tuple(_)
- | ty::Dynamic(_, _) => self.pretty_print_type(ty),
+ | ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
// Placeholders (all printed as `_` to uniformize them).
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 71ccd1799..530e252b7 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -6,6 +6,7 @@ use std::borrow::{Borrow, Cow};
use std::fmt::Debug;
use std::hash::Hash;
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::DefId;
@@ -123,18 +124,15 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Whether memory accesses should be alignment-checked.
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
- /// Whether, when checking alignment, we should `force_int` and thus support
+ /// Whether, when checking alignment, we should look at the actual address and thus support
/// custom alignment logic based on whatever the integer address happens to be.
///
- /// Requires Provenance::OFFSET_IS_ADDR to be true.
- fn force_int_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
+ /// If this returns true, Provenance::OFFSET_IS_ADDR must be true.
+ fn use_addr_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
/// Whether to enforce the validity invariant
fn enforce_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 function calls should be [ABI](CallAbi)-checked.
fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
true
@@ -218,23 +216,12 @@ pub trait Machine<'mir, 'tcx>: Sized {
right: &ImmTy<'tcx, Self::Provenance>,
) -> InterpResult<'tcx, (Scalar<Self::Provenance>, bool, Ty<'tcx>)>;
- /// Called to read the specified `local` from the `frame`.
- /// Since reading a ZST is not actually accessing memory or locals, this is never invoked
- /// for ZST reads.
- #[inline]
- fn access_local<'a>(
- frame: &'a Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>,
- local: mir::Local,
- ) -> InterpResult<'tcx, &'a Operand<Self::Provenance>>
- where
- 'tcx: 'mir,
- {
- frame.locals[local].access()
- }
-
/// Called to write the specified `local` from the `frame`.
/// Since writing a ZST is not actually accessing memory or locals, this is never invoked
/// for ZST reads.
+ ///
+ /// Due to borrow checker trouble, we indicate the `frame` as an index rather than an `&mut
+ /// Frame`.
#[inline]
fn access_local_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
@@ -329,7 +316,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// 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.
+ /// This must only fail if `alloc` contains provenance.
fn adjust_allocation<'b>(
ecx: &InterpCx<'mir, 'tcx, Self>,
id: AllocId,
@@ -337,13 +324,22 @@ pub trait Machine<'mir, 'tcx>: Sized {
kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>>;
+ fn eval_inline_asm(
+ _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+ _template: &'tcx [InlineAsmTemplatePiece],
+ _operands: &[mir::InlineAsmOperand<'tcx>],
+ _options: InlineAsmOptions,
+ ) -> InterpResult<'tcx> {
+ throw_unsup_format!("inline assembly is not supported")
+ }
+
/// Hook for performing extra checks on a memory read access.
///
/// Takes read-only access to the allocation so we can keep all the memory read
/// operations take `&self`. Use a `RefCell` in `AllocExtra` if you
/// need to mutate.
#[inline(always)]
- fn memory_read(
+ fn before_memory_read(
_tcx: TyCtxt<'tcx>,
_machine: &Self,
_alloc_extra: &Self::AllocExtra,
@@ -355,7 +351,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Hook for performing extra checks on a memory write access.
#[inline(always)]
- fn memory_written(
+ fn before_memory_write(
_tcx: TyCtxt<'tcx>,
_machine: &mut Self,
_alloc_extra: &mut Self::AllocExtra,
@@ -367,7 +363,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Hook for performing extra operations on a memory deallocation.
#[inline(always)]
- fn memory_deallocated(
+ fn before_memory_deallocation(
_tcx: TyCtxt<'tcx>,
_machine: &mut Self,
_alloc_extra: &mut Self::AllocExtra,
@@ -437,29 +433,12 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
type FrameExtra = ();
#[inline(always)]
- fn enforce_alignment(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
- // We do not check for alignment to avoid having to carry an `Align`
- // in `ConstValue::ByRef`.
- false
- }
-
- #[inline(always)]
- fn force_int_for_alignment_check(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
- // We do not support `force_int`.
+ fn use_addr_for_alignment_check(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
+ // We do not support `use_addr`.
false
}
#[inline(always)]
- fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
- false // for now, we don't enforce validity
- }
-
- #[inline(always)]
- fn enforce_number_init(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
- true
- }
-
- #[inline(always)]
fn checked_binop_checks_overflow(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
true
}
@@ -510,6 +489,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
) -> InterpResult<$tcx, Pointer<Option<AllocId>>> {
// Allow these casts, but make the pointer not dereferenceable.
// (I.e., they behave like transmutation.)
+ // This is correct because no pointers can ever be exposed in compile-time evaluation.
Ok(Pointer::from_addr(addr))
}
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index ed2c4edf9..ed155fbfe 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -21,7 +21,6 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
use super::{
alloc_range, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg, GlobalAlloc, InterpCx,
InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Provenance, Scalar,
- ScalarMaybeUninit,
};
#[derive(Debug, PartialEq, Copy, Clone)]
@@ -215,7 +214,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.allocate_raw_ptr(alloc, kind).unwrap()
}
- /// This can fail only of `alloc` contains relocations.
+ /// This can fail only of `alloc` contains provenance.
pub fn allocate_raw_ptr(
&mut self,
alloc: Allocation,
@@ -327,7 +326,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Let the machine take some extra action
let size = alloc.size();
- M::memory_deallocated(
+ M::before_memory_deallocation(
*self.tcx,
&mut self.machine,
&mut alloc.extra,
@@ -438,15 +437,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
msg,
})
}
- // Ensure we never consider the null pointer dereferencable.
+ // Ensure we never consider the null pointer dereferenceable.
if M::Provenance::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 {
- if M::force_int_for_alignment_check(self) {
- // `force_int_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true.
+ if M::use_addr_for_alignment_check(self) {
+ // `use_addr_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true.
check_offset_align(ptr.addr().bytes(), align)?;
} else {
// Check allocation alignment and offset alignment.
@@ -520,6 +519,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Gives raw access to the `Allocation`, without bounds or alignment checks.
/// The caller is responsible for calling the access hooks!
+ ///
+ /// You almost certainly want to use `get_ptr_alloc`/`get_ptr_alloc_mut` instead.
fn get_alloc_raw(
&self,
id: AllocId,
@@ -573,7 +574,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
)?;
if let Some((alloc_id, offset, prov, alloc)) = ptr_and_alloc {
let range = alloc_range(offset, size);
- M::memory_read(*self.tcx, &self.machine, &alloc.extra, (alloc_id, prov), range)?;
+ M::before_memory_read(*self.tcx, &self.machine, &alloc.extra, (alloc_id, prov), range)?;
Ok(Some(AllocRef { alloc, range, tcx: *self.tcx, alloc_id }))
} else {
// Even in this branch we have to be sure that we actually access the allocation, in
@@ -589,6 +590,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(&self.get_alloc_raw(id)?.extra)
}
+ /// Return the `mutability` field of the given allocation.
+ pub fn get_alloc_mutability<'a>(&'a self, id: AllocId) -> InterpResult<'tcx, Mutability> {
+ Ok(self.get_alloc_raw(id)?.mutability)
+ }
+
/// Gives raw mutable access to the `Allocation`, without bounds or alignment checks.
/// The caller is responsible for calling the access hooks!
///
@@ -634,7 +640,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// We cannot call `get_raw_mut` inside `check_and_deref_ptr` as that would duplicate `&mut self`.
let (alloc, machine) = self.get_alloc_raw_mut(alloc_id)?;
let range = alloc_range(offset, size);
- M::memory_written(tcx, machine, &mut alloc.extra, (alloc_id, prov), range)?;
+ M::before_memory_write(tcx, machine, &mut alloc.extra, (alloc_id, prov), range)?;
Ok(Some(AllocRefMut { alloc, range, tcx, alloc_id }))
} else {
Ok(None)
@@ -788,10 +794,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
todo.extend(static_roots);
while let Some(id) = todo.pop() {
if reachable.insert(id) {
- // This is a new allocation, add its relocations to `todo`.
+ // This is a new allocation, add the allocation it points to to `todo`.
if let Some((_, alloc)) = self.memory.alloc_map.get(id) {
todo.extend(
- alloc.relocations().values().filter_map(|prov| prov.get_alloc_id()),
+ alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()),
);
}
}
@@ -827,7 +833,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
allocs_to_print: &mut VecDeque<AllocId>,
alloc: &Allocation<Prov, Extra>,
) -> std::fmt::Result {
- for alloc_id in alloc.relocations().values().filter_map(|prov| prov.get_alloc_id()) {
+ for alloc_id in alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()) {
allocs_to_print.push_back(alloc_id);
}
write!(fmt, "{}", display_allocation(tcx, alloc))
@@ -894,11 +900,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
/// Reading and writing.
impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> {
/// `range` is relative to this allocation reference, not the base of the allocation.
- pub fn write_scalar(
- &mut self,
- range: AllocRange,
- val: ScalarMaybeUninit<Prov>,
- ) -> InterpResult<'tcx> {
+ pub fn write_scalar(&mut self, range: AllocRange, val: Scalar<Prov>) -> InterpResult<'tcx> {
let range = self.range.subrange(range);
debug!("write_scalar at {:?}{range:?}: {val:?}", self.alloc_id);
Ok(self
@@ -908,15 +910,11 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> {
}
/// `offset` is relative to this allocation reference, not the base of the allocation.
- pub fn write_ptr_sized(
- &mut self,
- offset: Size,
- val: ScalarMaybeUninit<Prov>,
- ) -> InterpResult<'tcx> {
+ pub fn write_ptr_sized(&mut self, offset: Size, val: Scalar<Prov>) -> InterpResult<'tcx> {
self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val)
}
- /// Mark the entire referenced range as uninitalized
+ /// Mark the entire referenced range as uninitialized
pub fn write_uninit(&mut self) -> InterpResult<'tcx> {
Ok(self
.alloc
@@ -931,7 +929,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> {
&self,
range: AllocRange,
read_provenance: bool,
- ) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> {
+ ) -> InterpResult<'tcx, Scalar<Prov>> {
let range = self.range.subrange(range);
let res = self
.alloc
@@ -942,12 +940,12 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> {
}
/// `range` is relative to this allocation reference, not the base of the allocation.
- pub fn read_integer(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> {
+ pub fn read_integer(&self, range: AllocRange) -> InterpResult<'tcx, Scalar<Prov>> {
self.read_scalar(range, /*read_provenance*/ false)
}
/// `offset` is relative to this allocation reference, not the base of the allocation.
- pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> {
+ pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, Scalar<Prov>> {
self.read_scalar(
alloc_range(offset, self.tcx.data_layout().pointer_size),
/*read_provenance*/ true,
@@ -955,29 +953,25 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> {
}
/// `range` is relative to this allocation reference, not the base of the allocation.
- pub fn check_bytes(
- &self,
- range: AllocRange,
- allow_uninit: bool,
- allow_ptr: bool,
- ) -> InterpResult<'tcx> {
+ pub fn get_bytes_strip_provenance<'b>(&'b self) -> InterpResult<'tcx, &'a [u8]> {
Ok(self
.alloc
- .check_bytes(&self.tcx, self.range.subrange(range), allow_uninit, allow_ptr)
+ .get_bytes_strip_provenance(&self.tcx, self.range)
.map_err(|e| e.to_interp_error(self.alloc_id))?)
}
- /// Returns whether the allocation has relocations for the entire range of the `AllocRef`.
- pub(crate) fn has_relocations(&self) -> bool {
- self.alloc.has_relocations(&self.tcx, self.range)
+ /// Returns whether the allocation has provenance anywhere in the range of the `AllocRef`.
+ pub(crate) fn has_provenance(&self) -> bool {
+ self.alloc.range_has_provenance(&self.tcx, self.range)
}
}
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
- /// Reads the given number of bytes from memory. Returns them as a slice.
+ /// Reads the given number of bytes from memory, and strips their provenance if possible.
+ /// Returns them as a slice.
///
/// Performs appropriate bounds checks.
- pub fn read_bytes_ptr(
+ pub fn read_bytes_ptr_strip_provenance(
&self,
ptr: Pointer<Option<M::Provenance>>,
size: Size,
@@ -990,7 +984,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// (We are staying inside the bounds here so all is good.)
Ok(alloc_ref
.alloc
- .get_bytes(&alloc_ref.tcx, alloc_ref.range)
+ .get_bytes_strip_provenance(&alloc_ref.tcx, alloc_ref.range)
.map_err(|e| e.to_interp_error(alloc_ref.alloc_id))?)
}
@@ -1071,7 +1065,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
};
let src_alloc = self.get_alloc_raw(src_alloc_id)?;
let src_range = alloc_range(src_offset, size);
- M::memory_read(*tcx, &self.machine, &src_alloc.extra, (src_alloc_id, src_prov), src_range)?;
+ M::before_memory_read(
+ *tcx,
+ &self.machine,
+ &src_alloc.extra,
+ (src_alloc_id, src_prov),
+ src_range,
+ )?;
// We need the `dest` ptr for the next operation, so we get it now.
// We already did the source checks and called the hooks so we are good to return early.
let Some((dest_alloc_id, dest_offset, dest_prov)) = dest_parts else {
@@ -1079,24 +1079,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok(());
};
- // This checks relocation edges on the src, which needs to happen before
- // `prepare_relocation_copy`.
- let src_bytes = src_alloc
- .get_bytes_with_uninit_and_ptr(&tcx, src_range)
- .map_err(|e| e.to_interp_error(src_alloc_id))?
- .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
- // first copy the relocations to a temporary buffer, because
- // `get_bytes_mut` will clear the relocations, which is correct,
- // since we don't want to keep any relocations at the target.
- let relocations =
- src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
+ // Checks provenance edges on the src, which needs to happen before
+ // `prepare_provenance_copy`.
+ if src_alloc.range_has_provenance(&tcx, alloc_range(src_range.start, Size::ZERO)) {
+ throw_unsup!(PartialPointerCopy(Pointer::new(src_alloc_id, src_range.start)));
+ }
+ if src_alloc.range_has_provenance(&tcx, alloc_range(src_range.end(), Size::ZERO)) {
+ throw_unsup!(PartialPointerCopy(Pointer::new(src_alloc_id, src_range.end())));
+ }
+ let src_bytes = src_alloc.get_bytes_unchecked(src_range).as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
+ // first copy the provenance to a temporary buffer, because
+ // `get_bytes_mut` will clear the provenance, which is correct,
+ // since we don't want to keep any provenance at the target.
+ let provenance =
+ src_alloc.prepare_provenance_copy(self, src_range, dest_offset, num_copies);
// Prepare a copy of the initialization mask.
let compressed = src_alloc.compress_uninit_range(src_range);
// Destination alloc preparations and access hooks.
let (dest_alloc, extra) = self.get_alloc_raw_mut(dest_alloc_id)?;
let dest_range = alloc_range(dest_offset, size * num_copies);
- M::memory_written(
+ M::before_memory_write(
*tcx,
extra,
&mut dest_alloc.extra,
@@ -1118,7 +1121,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
dest_alloc
.write_uninit(&tcx, dest_range)
.map_err(|e| e.to_interp_error(dest_alloc_id))?;
- // We can forget about the relocations, this is all not initialized anyway.
+ // We can forget about the provenance, this is all not initialized anyway.
return Ok(());
}
@@ -1162,8 +1165,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
alloc_range(dest_offset, size), // just a single copy (i.e., not full `dest_range`)
num_copies,
);
- // copy the relocations to the destination
- dest_alloc.mark_relocation_range(relocations);
+ // copy the provenance to the destination
+ dest_alloc.mark_provenance_range(provenance);
Ok(())
}
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 94ba62c16..0e3959b61 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -1,11 +1,9 @@
//! Functions concerning immediate values and operands, and reading from operands.
//! All high-level functions to read from memory work on operands as sources.
-use std::fmt::Write;
-
use rustc_hir::def::Namespace;
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
-use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
+use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty};
use rustc_middle::{mir, ty};
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding};
@@ -14,7 +12,7 @@ use rustc_target::abi::{VariantIdx, Variants};
use super::{
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId,
InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Place, PlaceTy, Pointer,
- Provenance, Scalar, ScalarMaybeUninit,
+ Provenance, Scalar,
};
/// An `Immediate` represents a single immediate self-contained Rust value.
@@ -27,23 +25,14 @@ use super::{
#[derive(Copy, Clone, Debug)]
pub enum Immediate<Prov: Provenance = AllocId> {
/// A single scalar value (must have *initialized* `Scalar` ABI).
- /// FIXME: we also currently often use this for ZST.
- /// `ScalarMaybeUninit` should reject ZST, and we should use `Uninit` for them instead.
- Scalar(ScalarMaybeUninit<Prov>),
+ Scalar(Scalar<Prov>),
/// A pair of two scalar value (must have `ScalarPair` ABI where both fields are
/// `Scalar::Initialized`).
- ScalarPair(ScalarMaybeUninit<Prov>, ScalarMaybeUninit<Prov>),
+ ScalarPair(Scalar<Prov>, Scalar<Prov>),
/// A value of fully uninitialized memory. Can have and size and layout.
Uninit,
}
-impl<Prov: Provenance> From<ScalarMaybeUninit<Prov>> for Immediate<Prov> {
- #[inline(always)]
- fn from(val: ScalarMaybeUninit<Prov>) -> Self {
- Immediate::Scalar(val)
- }
-}
-
impl<Prov: Provenance> From<Scalar<Prov>> for Immediate<Prov> {
#[inline(always)]
fn from(val: Scalar<Prov>) -> Self {
@@ -51,13 +40,13 @@ impl<Prov: Provenance> From<Scalar<Prov>> for Immediate<Prov> {
}
}
-impl<'tcx, Prov: Provenance> Immediate<Prov> {
+impl<Prov: Provenance> Immediate<Prov> {
pub fn from_pointer(p: Pointer<Prov>, cx: &impl HasDataLayout) -> Self {
- Immediate::Scalar(ScalarMaybeUninit::from_pointer(p, cx))
+ Immediate::Scalar(Scalar::from_pointer(p, cx))
}
pub fn from_maybe_pointer(p: Pointer<Option<Prov>>, cx: &impl HasDataLayout) -> Self {
- Immediate::Scalar(ScalarMaybeUninit::from_maybe_pointer(p, cx))
+ Immediate::Scalar(Scalar::from_maybe_pointer(p, cx))
}
pub fn new_slice(val: Scalar<Prov>, len: u64, cx: &impl HasDataLayout) -> Self {
@@ -69,41 +58,28 @@ impl<'tcx, Prov: Provenance> Immediate<Prov> {
vtable: Pointer<Option<Prov>>,
cx: &impl HasDataLayout,
) -> Self {
- Immediate::ScalarPair(val.into(), ScalarMaybeUninit::from_maybe_pointer(vtable, cx))
+ Immediate::ScalarPair(val.into(), Scalar::from_maybe_pointer(vtable, cx))
}
#[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
- pub fn to_scalar_or_uninit(self) -> ScalarMaybeUninit<Prov> {
+ pub fn to_scalar(self) -> Scalar<Prov> {
match self {
Immediate::Scalar(val) => val,
Immediate::ScalarPair(..) => bug!("Got a scalar pair where a scalar was expected"),
- Immediate::Uninit => ScalarMaybeUninit::Uninit,
+ Immediate::Uninit => bug!("Got uninit where a scalar was expected"),
}
}
#[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
- pub fn to_scalar(self) -> InterpResult<'tcx, Scalar<Prov>> {
- self.to_scalar_or_uninit().check_init()
- }
-
- #[inline]
- #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
- pub fn to_scalar_or_uninit_pair(self) -> (ScalarMaybeUninit<Prov>, ScalarMaybeUninit<Prov>) {
+ pub fn to_scalar_pair(self) -> (Scalar<Prov>, Scalar<Prov>) {
match self {
Immediate::ScalarPair(val1, val2) => (val1, val2),
Immediate::Scalar(..) => bug!("Got a scalar where a scalar pair was expected"),
- Immediate::Uninit => (ScalarMaybeUninit::Uninit, ScalarMaybeUninit::Uninit),
+ Immediate::Uninit => bug!("Got uninit where a scalar pair was expected"),
}
}
-
- #[inline]
- #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
- pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar<Prov>, Scalar<Prov>)> {
- let (val1, val2) = self.to_scalar_or_uninit_pair();
- Ok((val1.check_init()?, val2.check_init()?))
- }
}
// ScalarPair needs a type to interpret, so we often have an immediate and a type together
@@ -119,27 +95,17 @@ impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
/// Helper function for printing a scalar to a FmtPrinter
fn p<'a, 'tcx, Prov: Provenance>(
cx: FmtPrinter<'a, 'tcx>,
- s: ScalarMaybeUninit<Prov>,
+ s: Scalar<Prov>,
ty: Ty<'tcx>,
) -> Result<FmtPrinter<'a, 'tcx>, std::fmt::Error> {
match s {
- ScalarMaybeUninit::Scalar(Scalar::Int(int)) => {
- cx.pretty_print_const_scalar_int(int, ty, true)
- }
- ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _sz)) => {
+ Scalar::Int(int) => cx.pretty_print_const_scalar_int(int, ty, true),
+ Scalar::Ptr(ptr, _sz) => {
// Just print the ptr value. `pretty_print_const_scalar_ptr` would also try to
// print what is points to, which would fail since it has no access to the local
// memory.
cx.pretty_print_const_pointer(ptr, ty, true)
}
- ScalarMaybeUninit::Uninit => cx.typed_value(
- |mut this| {
- this.write_str("uninit ")?;
- Ok(this)
- },
- |this| this.print_type(ty),
- " ",
- ),
}
}
ty::tls::with(|tcx| {
@@ -269,7 +235,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline]
pub fn to_const_int(self) -> ConstInt {
assert!(self.layout.ty.is_integral());
- let int = self.to_scalar().expect("to_const_int doesn't work on scalar pairs").assert_int();
+ let int = self.to_scalar().assert_int();
ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral())
}
}
@@ -327,7 +293,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
fn read_immediate_from_mplace_raw(
&self,
mplace: &MPlaceTy<'tcx, M::Provenance>,
- force: bool,
) -> InterpResult<'tcx, Option<ImmTy<'tcx, M::Provenance>>> {
if mplace.layout.is_unsized() {
// Don't touch unsized
@@ -345,47 +310,44 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// case where some of the bytes are initialized and others are not. So, we need an extra
// check that walks over the type of `mplace` to make sure it is truly correct to treat this
// like a `Scalar` (or `ScalarPair`).
- let scalar_layout = match mplace.layout.abi {
- // `if` does not work nested inside patterns, making this a bit awkward to express.
- Abi::Scalar(abi::Scalar::Initialized { value: s, .. }) => Some(s),
- Abi::Scalar(s) if force => Some(s.primitive()),
- _ => None,
- };
- if let Some(s) = scalar_layout {
- let size = s.size(self);
- assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
- let scalar = alloc
- .read_scalar(alloc_range(Size::ZERO, size), /*read_provenance*/ s.is_ptr())?;
- return Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout }));
- }
- let scalar_pair_layout = match mplace.layout.abi {
+ Ok(match mplace.layout.abi {
+ Abi::Scalar(abi::Scalar::Initialized { value: s, .. }) => {
+ let size = s.size(self);
+ assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
+ let scalar = alloc.read_scalar(
+ alloc_range(Size::ZERO, size),
+ /*read_provenance*/ s.is_ptr(),
+ )?;
+ Some(ImmTy { imm: scalar.into(), layout: mplace.layout })
+ }
Abi::ScalarPair(
abi::Scalar::Initialized { value: a, .. },
abi::Scalar::Initialized { value: b, .. },
- ) => Some((a, b)),
- Abi::ScalarPair(a, b) if force => Some((a.primitive(), b.primitive())),
- _ => None,
- };
- if let Some((a, b)) = scalar_pair_layout {
- // We checked `ptr_align` above, so all fields will have the alignment they need.
- // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
- // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
- 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),
- /*read_provenance*/ a.is_ptr(),
- )?;
- let b_val = alloc
- .read_scalar(alloc_range(b_offset, b_size), /*read_provenance*/ b.is_ptr())?;
- return Ok(Some(ImmTy {
- imm: Immediate::ScalarPair(a_val, b_val),
- layout: mplace.layout,
- }));
- }
- // Neither a scalar nor scalar pair.
- return Ok(None);
+ ) => {
+ // We checked `ptr_align` above, so all fields will have the alignment they need.
+ // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
+ // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
+ 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),
+ /*read_provenance*/ a.is_ptr(),
+ )?;
+ let b_val = alloc.read_scalar(
+ alloc_range(b_offset, b_size),
+ /*read_provenance*/ b.is_ptr(),
+ )?;
+ Some(ImmTy {
+ imm: Immediate::ScalarPair(a_val.into(), b_val.into()),
+ layout: mplace.layout,
+ })
+ }
+ _ => {
+ // Neither a scalar nor scalar pair.
+ None
+ }
+ })
}
/// Try returning an immediate for the operand. If the layout does not permit loading this as an
@@ -394,20 +356,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// succeed! Whether it succeeds depends on whether the layout can be represented
/// in an `Immediate`, not on which data is stored there currently.
///
- /// If `force` is `true`, then even scalars with fields that can be ununit will be
- /// read. This means the load is lossy and should not be written back!
- /// This flag exists only for validity checking.
- ///
/// This is an internal function that should not usually be used; call `read_immediate` instead.
/// ConstProp needs it, though.
pub fn read_immediate_raw(
&self,
src: &OpTy<'tcx, M::Provenance>,
- force: bool,
) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> {
Ok(match src.try_as_mplace() {
Ok(ref mplace) => {
- if let Some(val) = self.read_immediate_from_mplace_raw(mplace, force)? {
+ if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? {
Ok(val)
} else {
Err(*mplace)
@@ -418,24 +375,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
/// Read an immediate from a place, asserting that that is possible with the given layout.
+ ///
+ /// If this suceeds, the `ImmTy` is never `Uninit`.
#[inline(always)]
pub fn read_immediate(
&self,
op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
- if let Ok(imm) = self.read_immediate_raw(op, /*force*/ false)? {
- Ok(imm)
- } else {
- span_bug!(self.cur_span(), "primitive read failed for type: {:?}", op.layout.ty);
+ if !matches!(
+ op.layout.abi,
+ Abi::Scalar(abi::Scalar::Initialized { .. })
+ | Abi::ScalarPair(abi::Scalar::Initialized { .. }, abi::Scalar::Initialized { .. })
+ ) {
+ span_bug!(self.cur_span(), "primitive read not possible for type: {:?}", op.layout.ty);
}
+ let imm = self.read_immediate_raw(op)?.unwrap();
+ if matches!(*imm, Immediate::Uninit) {
+ throw_ub!(InvalidUninitBytes(None));
+ }
+ Ok(imm)
}
/// Read a scalar from a place
pub fn read_scalar(
&self,
op: &OpTy<'tcx, M::Provenance>,
- ) -> InterpResult<'tcx, ScalarMaybeUninit<M::Provenance>> {
- Ok(self.read_immediate(op)?.to_scalar_or_uninit())
+ ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
+ Ok(self.read_immediate(op)?.to_scalar())
}
/// Read a pointer from a place.
@@ -449,7 +415,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Turn the wide MPlace into a string (must already be dereferenced!)
pub fn read_str(&self, mplace: &MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx, &str> {
let len = mplace.len(self)?;
- let bytes = self.read_bytes_ptr(mplace.ptr, Size::from_bytes(len))?;
+ let bytes = self.read_bytes_ptr_strip_provenance(mplace.ptr, Size::from_bytes(len))?;
let str = std::str::from_utf8(bytes).map_err(|err| err_ub!(InvalidStr(err)))?;
Ok(str)
}
@@ -478,7 +444,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
- /// Read from a local. Will not actually access the local if reading from a ZST.
+ /// Read from a local.
/// Will not access memory, instead an indirect `Operand` is returned.
///
/// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an
@@ -490,12 +456,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
let layout = self.layout_of_local(frame, local, layout)?;
- let op = if layout.is_zst() {
- // Bypass `access_local` (helps in ConstProp)
- Operand::Immediate(Immediate::Uninit)
- } else {
- *M::access_local(frame, local)?
- };
+ let op = *frame.locals[local].access()?;
Ok(OpTy { op, layout, align: Some(layout.align.abi) })
}
@@ -598,15 +559,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
match c.kind() {
- ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
+ ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => throw_inval!(TooGeneric),
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => {
throw_inval!(AlreadyReported(reported))
}
ty::ConstKind::Unevaluated(uv) => {
+ // NOTE: We evaluate to a `ValTree` here as a check to ensure
+ // we're working with valid constants, even though we never need it.
let instance = self.resolve(uv.def, uv.substs)?;
- Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
+ let cid = GlobalId { instance, promoted: None };
+ let _valtree = self
+ .tcx
+ .eval_to_valtree(self.param_env.and(cid))?
+ .unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv));
+
+ Ok(self.eval_to_allocation(cid)?.into())
}
- ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => {
+ ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c)
}
ty::ConstKind::Value(valtree) => {
@@ -622,9 +591,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
val: &mir::ConstantKind<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+ // FIXME(const_prop): normalization needed b/c const prop lint in
+ // `mir_drops_elaborated_and_const_checked`, which happens before
+ // optimized MIR. Only after optimizing the MIR can we guarantee
+ // that the `RevealAll` pass has happened and that the body's consts
+ // are normalized, so any call to resolve before that needs to be
+ // manually normalized.
+ let val = self.tcx.normalize_erasing_regions(self.param_env, *val);
match val {
- mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
- mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
+ mir::ConstantKind::Ty(ct) => self.const_to_op(ct, layout),
+ mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
+ mir::ConstantKind::Unevaluated(uv, _) => {
+ let instance = self.resolve(uv.def, uv.substs)?;
+ Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
+ }
}
}
@@ -727,7 +707,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Figure out which discriminant and variant this corresponds to.
Ok(match *tag_encoding {
TagEncoding::Direct => {
- let scalar = tag_val.to_scalar()?;
+ let scalar = tag_val.to_scalar();
// Generate a specific error if `tag_val` is not an integer.
// (`tag_bits` itself is only used for error messages below.)
let tag_bits = scalar
@@ -757,8 +737,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Return the cast value, and the index.
(discr_val, index.0)
}
- TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
- let tag_val = tag_val.to_scalar()?;
+ TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
+ let tag_val = tag_val.to_scalar();
// Compute the variant this niche value/"tag" corresponds to. With niche layout,
// discriminant (encoded in niche/tag) and variant index are the same.
let variants_start = niche_variants.start().as_u32();
@@ -775,7 +755,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if !ptr_valid {
throw_ub!(InvalidTag(dbg_val))
}
- dataful_variant
+ untagged_variant
}
Ok(tag_bits) => {
let tag_bits = tag_bits.assert_bits(tag_layout.size);
@@ -785,9 +765,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let niche_start_val = ImmTy::from_uint(niche_start, tag_layout);
let variant_index_relative_val =
self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?;
- let variant_index_relative = variant_index_relative_val
- .to_scalar()?
- .assert_bits(tag_val.layout.size);
+ let variant_index_relative =
+ variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size);
// Check if this is in the range that indicates an actual discriminant.
if variant_index_relative <= u128::from(variants_end - variants_start) {
let variant_index_relative = u32::try_from(variant_index_relative)
@@ -806,7 +785,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert!(usize::try_from(variant_index).unwrap() < variants_len);
VariantIdx::from_u32(variant_index)
} else {
- dataful_variant
+ untagged_variant
}
}
};
@@ -820,12 +799,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64", not(bootstrap)))]
mod size_asserts {
use super::*;
+ use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
- rustc_data_structures::static_assert_size!(Immediate, 56);
- rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
- rustc_data_structures::static_assert_size!(Operand, 64);
- rustc_data_structures::static_assert_size!(OpTy<'_>, 88);
+ static_assert_size!(Immediate, 48);
+ static_assert_size!(ImmTy<'_>, 64);
+ static_assert_size!(Operand, 56);
+ static_assert_size!(OpTy<'_>, 80);
}
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index f9912d706..1f1d06651 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -329,21 +329,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match left.layout.ty.kind() {
ty::Char => {
assert_eq!(left.layout.ty, right.layout.ty);
- let left = left.to_scalar()?;
- let right = right.to_scalar()?;
+ let left = left.to_scalar();
+ let right = right.to_scalar();
Ok(self.binary_char_op(bin_op, left.to_char()?, right.to_char()?))
}
ty::Bool => {
assert_eq!(left.layout.ty, right.layout.ty);
- let left = left.to_scalar()?;
- let right = right.to_scalar()?;
+ let left = left.to_scalar();
+ let right = right.to_scalar();
Ok(self.binary_bool_op(bin_op, left.to_bool()?, right.to_bool()?))
}
ty::Float(fty) => {
assert_eq!(left.layout.ty, right.layout.ty);
let ty = left.layout.ty;
- let left = left.to_scalar()?;
- let right = right.to_scalar()?;
+ let left = left.to_scalar();
+ let right = right.to_scalar();
Ok(match fty {
FloatTy::F32 => {
self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?)
@@ -363,8 +363,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
right.layout.ty
);
- let l = left.to_scalar()?.to_bits(left.layout.size)?;
- let r = right.to_scalar()?.to_bits(right.layout.size)?;
+ let l = left.to_scalar().to_bits(left.layout.size)?;
+ let r = right.to_scalar().to_bits(right.layout.size)?;
self.binary_int_op(bin_op, l, left.layout, r, right.layout)
}
_ if left.layout.ty.is_any_ptr() => {
@@ -410,7 +410,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
use rustc_middle::mir::UnOp::*;
let layout = val.layout;
- let val = val.to_scalar()?;
+ let val = val.to_scalar();
trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty);
match layout.ty.kind() {
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index f4571a1ca..b32889290 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -2,8 +2,6 @@
//! into a place.
//! All high-level functions to write to memory work on places as destinations.
-use std::hash::Hash;
-
use rustc_ast::Mutability;
use rustc_middle::mir;
use rustc_middle::ty;
@@ -13,7 +11,7 @@ use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding, Vari
use super::{
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand,
- Pointer, Provenance, Scalar, ScalarMaybeUninit,
+ Pointer, Provenance, Scalar,
};
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
@@ -254,8 +252,6 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
// These are defined here because they produce a place.
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
#[inline(always)]
- /// Note: do not call `as_ref` on the resulting place. This function should only be used to
- /// read from the resulting mplace, not to get its address back.
pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
match **self {
Operand::Indirect(mplace) => {
@@ -267,8 +263,6 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
#[inline(always)]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
- /// Note: do not call `as_ref` on the resulting place. This function should only be used to
- /// read from the resulting mplace, not to get its address back.
pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
self.try_as_mplace().unwrap()
}
@@ -294,7 +288,7 @@ impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> {
// FIXME: Working around https://github.com/rust-lang/rust/issues/54385
impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M>
where
- Prov: Provenance + Eq + Hash + 'static,
+ Prov: Provenance + 'static,
M: Machine<'mir, 'tcx, Provenance = Prov>,
{
/// Take a value, which represents a (thin or wide) reference, and make it a place.
@@ -312,7 +306,7 @@ where
let layout = self.layout_of(pointee_type)?;
let (ptr, meta) = match **val {
Immediate::Scalar(ptr) => (ptr, MemPlaceMeta::None),
- Immediate::ScalarPair(ptr, meta) => (ptr, MemPlaceMeta::Meta(meta.check_init()?)),
+ Immediate::ScalarPair(ptr, meta) => (ptr, MemPlaceMeta::Meta(meta)),
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
};
@@ -467,7 +461,7 @@ where
#[inline(always)]
pub fn write_scalar(
&mut self,
- val: impl Into<ScalarMaybeUninit<M::Provenance>>,
+ val: impl Into<Scalar<M::Provenance>>,
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
self.write_immediate(Immediate::Scalar(val.into()), dest)
@@ -644,9 +638,9 @@ where
// Let us see if the layout is simple so we take a shortcut,
// avoid force_allocation.
- let src = match self.read_immediate_raw(src, /*force*/ false)? {
+ let src = match self.read_immediate_raw(src)? {
Ok(src_val) => {
- assert!(!src.layout.is_unsized(), "cannot have unsized immediates");
+ assert!(!src.layout.is_unsized(), "cannot copy unsized immediates");
assert!(
!dest.layout.is_unsized(),
"the src is sized, so the dest must also be sized"
@@ -823,7 +817,7 @@ where
}
abi::Variants::Multiple {
tag_encoding:
- TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
+ TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
tag: tag_layout,
tag_field,
..
@@ -831,7 +825,7 @@ where
// No need to validate that the discriminant here because the
// `TyAndLayout::for_variant()` call earlier already checks the variant is valid.
- if variant_index != dataful_variant {
+ if variant_index != untagged_variant {
let variants_start = niche_variants.start().as_u32();
let variant_index_relative = variant_index
.as_u32()
@@ -891,10 +885,13 @@ where
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
+ use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
- rustc_data_structures::static_assert_size!(MemPlaceMeta, 24);
- rustc_data_structures::static_assert_size!(MemPlace, 40);
- rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 64);
- rustc_data_structures::static_assert_size!(Place, 48);
- rustc_data_structures::static_assert_size!(PlaceTy<'_>, 72);
+ static_assert_size!(MemPlaceMeta, 24);
+ static_assert_size!(MemPlace, 40);
+ static_assert_size!(MPlaceTy<'_>, 64);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(Place, 40);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(PlaceTy<'_>, 64);
}
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 742339f2b..77da8f104 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -1,14 +1,12 @@
//! This file implements "place projections"; basically a symmetric API for 3 types: MPlaceTy, OpTy, PlaceTy.
//!
-//! OpTy and PlaceTy genrally work by "let's see if we are actually an MPlaceTy, and do something custom if not".
+//! OpTy and PlaceTy generally work by "let's see if we are actually an MPlaceTy, and do something custom if not".
//! For PlaceTy, the custom thing is basically always to call `force_allocation` and then use the MPlaceTy logic anyway.
//! For OpTy, the custom thing on field pojections has to be pretty clever (since `Operand::Immediate` can have fields),
//! but for array/slice operations it only has to worry about `Operand::Uninit`. That makes the value part trivial,
//! but we still need to do bounds checking and adjust the layout. To not duplicate that with MPlaceTy, we actually
//! implement the logic on OpTy, and MPlaceTy calls that.
-use std::hash::Hash;
-
use rustc_middle::mir;
use rustc_middle::ty;
use rustc_middle::ty::layout::LayoutOf;
@@ -22,7 +20,7 @@ use super::{
// FIXME: Working around https://github.com/rust-lang/rust/issues/54385
impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M>
where
- Prov: Provenance + Eq + Hash + 'static,
+ Prov: Provenance + 'static,
M: Machine<'mir, 'tcx, Provenance = Prov>,
{
//# Field access
@@ -100,6 +98,8 @@ where
// This makes several assumptions about what layouts we will encounter; we match what
// codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
let field_val: Immediate<_> = match (*base, base.layout.abi) {
+ // if the entire value is uninit, then so is the field (can happen in ConstProp)
+ (Immediate::Uninit, _) => Immediate::Uninit,
// the field contains no information, can be left uninit
_ if field_layout.is_zst() => Immediate::Uninit,
// the field covers the entire type
@@ -124,6 +124,7 @@ where
b_val
})
}
+ // everything else is a bug
_ => span_bug!(
self.cur_span(),
"invalid field access on immediate {}, layout {:#?}",
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index fea158a9f..c6e04cbfb 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -53,7 +53,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.pop_stack_frame(/* unwinding */ true)?;
return Ok(true);
};
- let basic_block = &self.body().basic_blocks()[loc.block];
+ let basic_block = &self.body().basic_blocks[loc.block];
if let Some(stmt) = basic_block.statements.get(loc.statement_index) {
let old_frames = self.frame_idx();
@@ -114,13 +114,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
M::retag(self, *kind, &dest)?;
}
- // Call CopyNonOverlapping
- CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { src, dst, count }) => {
- let src = self.eval_operand(src, None)?;
- let dst = self.eval_operand(dst, None)?;
- let count = self.eval_operand(count, None)?;
- self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)?;
- }
+ Intrinsic(box ref intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
// Statements we do not track.
AscribeUserType(..) => {}
@@ -251,8 +245,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Len(place) => {
let src = self.eval_place(place)?;
- let mplace = self.force_allocation(&src)?;
- let len = mplace.len(self)?;
+ let op = self.place_to_op(&src)?;
+ let len = op.len(self)?;
self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?;
}
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index d563e35f9..50a82aa0e 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -1,5 +1,6 @@
use std::borrow::Cow;
+use rustc_ast::ast::InlineAsmOptions;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
use rustc_middle::ty::Instance;
use rustc_middle::{
@@ -129,8 +130,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
Assert { ref cond, expected, ref msg, target, cleanup } => {
- let cond_val =
- self.read_immediate(&self.eval_operand(cond, None)?)?.to_scalar()?.to_bool()?;
+ let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?;
if expected == cond_val {
self.go_to_block(target);
} else {
@@ -167,8 +167,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
terminator.kind
),
- // Inline assembly can't be interpreted.
- InlineAsm { .. } => throw_unsup_format!("inline assembly is not supported"),
+ InlineAsm { template, ref operands, options, destination, .. } => {
+ M::eval_inline_asm(self, template, operands, options)?;
+ if options.contains(InlineAsmOptions::NORETURN) {
+ throw_ub_format!("returned from noreturn inline assembly");
+ }
+ self.go_to_block(
+ destination
+ .expect("InlineAsm terminators without noreturn must have a destination"),
+ )
+ }
}
Ok(())
@@ -215,12 +223,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
_ => false,
}
};
- // Padding must be fully equal.
- let pad_compat = || caller_abi.pad == callee_abi.pad;
// When comparing the PassMode, we have to be smart about comparing the attributes.
- let arg_attr_compat = |a1: ArgAttributes, a2: ArgAttributes| {
+ let arg_attr_compat = |a1: &ArgAttributes, a2: &ArgAttributes| {
// There's only one regular attribute that matters for the call ABI: InReg.
- // Everything else is things like noalias, dereferencable, nonnull, ...
+ // Everything else is things like noalias, dereferenceable, nonnull, ...
// (This also applies to pointee_size, pointee_align.)
if a1.regular.contains(ArgAttribute::InReg) != a2.regular.contains(ArgAttribute::InReg)
{
@@ -233,13 +239,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
return true;
};
- let mode_compat = || match (caller_abi.mode, callee_abi.mode) {
+ let mode_compat = || match (&caller_abi.mode, &callee_abi.mode) {
(PassMode::Ignore, PassMode::Ignore) => true,
(PassMode::Direct(a1), PassMode::Direct(a2)) => arg_attr_compat(a1, a2),
(PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => {
arg_attr_compat(a1, a2) && arg_attr_compat(b1, b2)
}
- (PassMode::Cast(c1), PassMode::Cast(c2)) => c1 == c2,
+ (PassMode::Cast(c1, pad1), PassMode::Cast(c2, pad2)) => c1 == c2 && pad1 == pad2,
(
PassMode::Indirect { attrs: a1, extra_attrs: None, on_stack: s1 },
PassMode::Indirect { attrs: a2, extra_attrs: None, on_stack: s2 },
@@ -251,7 +257,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
_ => false,
};
- if layout_compat() && pad_compat() && mode_compat() {
+ if layout_compat() && mode_compat() {
return true;
}
trace!(
@@ -534,7 +540,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let mut non_zst_field = None;
for i in 0..receiver.layout.fields.count() {
let field = self.operand_field(&receiver, i)?;
- if !field.layout.is_zst() {
+ let zst =
+ field.layout.is_zst() && field.layout.align.abi.bytes() == 1;
+ if !zst {
assert!(
non_zst_field.is_none(),
"multiple non-ZST fields in dyn receiver type {}",
@@ -557,7 +565,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.tcx
.struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env);
let ty::Dynamic(data, ..) = receiver_tail.kind() else {
- span_bug!(self.cur_span(), "dyanmic call on non-`dyn` type {}", receiver_tail)
+ span_bug!(self.cur_span(), "dynamic call on non-`dyn` type {}", receiver_tail)
};
// Get the required information from the vtable.
diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs
index b3a511d5a..cab23b724 100644
--- a/compiler/rustc_const_eval/src/interpret/traits.rs
+++ b/compiler/rustc_const_eval/src/interpret/traits.rs
@@ -32,7 +32,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(vtable_ptr.into())
}
- /// Returns a high-level representation of the entires of the given vtable.
+ /// Returns a high-level representation of the entries of the given vtable.
pub fn get_vtable_entries(
&self,
vtable: Pointer<Option<M::Provenance>>,
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 0e50d1ed4..14aaee6ac 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -5,9 +5,10 @@
//! to be const-safe.
use std::convert::TryFrom;
-use std::fmt::Write;
+use std::fmt::{Display, Write};
use std::num::NonZeroUsize;
+use rustc_ast::Mutability;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_middle::mir::interpret::InterpError;
@@ -19,9 +20,11 @@ use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, Wr
use std::hash::Hash;
+// for the validation errors
+use super::UndefinedBehaviorInfo::*;
use super::{
- alloc_range, CheckInAllocMsg, GlobalAlloc, Immediate, InterpCx, InterpResult, MPlaceTy,
- Machine, MemPlaceMeta, OpTy, Scalar, ScalarMaybeUninit, ValueVisitor,
+ CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine,
+ MemPlaceMeta, OpTy, Scalar, ValueVisitor,
};
macro_rules! throw_validation_failure {
@@ -59,6 +62,7 @@ macro_rules! throw_validation_failure {
/// });
/// ```
///
+/// The patterns must be of type `UndefinedBehaviorInfo`.
/// An additional expected parameter can also be added to the failure message:
///
/// ```
@@ -86,7 +90,7 @@ macro_rules! try_validation {
// allocation here as this can only slow down builds that fail anyway.
Err(e) => match e.kind() {
$(
- $($p)|+ =>
+ InterpError::UndefinedBehavior($($p)|+) =>
throw_validation_failure!(
$where,
{ $( $what_fmt ),+ } $( expected { $( $expected_fmt ),+ } )?
@@ -304,6 +308,26 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
Ok(r)
}
+ fn read_immediate(
+ &self,
+ op: &OpTy<'tcx, M::Provenance>,
+ expected: impl Display,
+ ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
+ Ok(try_validation!(
+ self.ecx.read_immediate(op),
+ self.path,
+ InvalidUninitBytes(None) => { "uninitialized memory" } expected { "{expected}" }
+ ))
+ }
+
+ fn read_scalar(
+ &self,
+ op: &OpTy<'tcx, M::Provenance>,
+ expected: impl Display,
+ ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
+ Ok(self.read_immediate(op, expected)?.to_scalar())
+ }
+
fn check_wide_ptr_meta(
&mut self,
meta: MemPlaceMeta<M::Provenance>,
@@ -317,8 +341,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let (_ty, _trait) = try_validation!(
self.ecx.get_ptr_vtable(vtable),
self.path,
- err_ub!(DanglingIntPointer(..)) |
- err_ub!(InvalidVTablePointer(..)) =>
+ DanglingIntPointer(..) |
+ InvalidVTablePointer(..) =>
{ "{vtable}" } expected { "a vtable pointer" },
);
// FIXME: check if the type/trait match what ty::Dynamic says?
@@ -344,14 +368,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
value: &OpTy<'tcx, M::Provenance>,
kind: &str,
) -> InterpResult<'tcx> {
- let value = self.ecx.read_immediate(value)?;
+ let place =
+ self.ecx.ref_to_mplace(&self.read_immediate(value, format_args!("a {kind}"))?)?;
// Handle wide pointers.
// Check metadata early, for better diagnostics
- let place = try_validation!(
- self.ecx.ref_to_mplace(&value),
- self.path,
- err_ub!(InvalidUninitBytes(None)) => { "uninitialized {}", kind },
- );
if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?;
}
@@ -359,7 +379,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let size_and_align = try_validation!(
self.ecx.size_and_align_of_mplace(&place),
self.path,
- err_ub!(InvalidMeta(msg)) => { "invalid {} metadata: {}", kind, msg },
+ InvalidMeta(msg) => { "invalid {} metadata: {}", kind, msg },
);
let (size, align) = size_and_align
// for the purpose of validity, consider foreign types to have
@@ -375,21 +395,21 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
),
self.path,
- err_ub!(AlignmentCheckFailed { required, has }) =>
+ AlignmentCheckFailed { required, has } =>
{
"an unaligned {kind} (required {} byte alignment but found {})",
required.bytes(),
has.bytes()
},
- err_ub!(DanglingIntPointer(0, _)) =>
+ DanglingIntPointer(0, _) =>
{ "a null {kind}" },
- err_ub!(DanglingIntPointer(i, _)) =>
+ DanglingIntPointer(i, _) =>
{ "a dangling {kind} (address {i:#x} is unallocated)" },
- err_ub!(PointerOutOfBounds { .. }) =>
+ PointerOutOfBounds { .. } =>
{ "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(..)) =>
+ PointerUseAfterFree(..) =>
{ "a dangling {kind} (use-after-free)" },
);
// Do not allow pointers to uninhabited types.
@@ -403,34 +423,51 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// Proceed recursively even for ZST, no reason to skip them!
// `!` is a ZST and we want to validate it.
if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr) {
- // Special handling for pointers to statics (irrespective of their type).
+ // Let's see what kind of memory this points to.
let alloc_kind = self.ecx.tcx.try_get_global_alloc(alloc_id);
- if let Some(GlobalAlloc::Static(did)) = alloc_kind {
- assert!(!self.ecx.tcx.is_thread_local_static(did));
- assert!(self.ecx.tcx.is_static(did));
- if matches!(
- self.ctfe_mode,
- Some(CtfeValidationMode::Const { allow_static_ptrs: false, .. })
- ) {
- // See const_eval::machine::MemoryExtra::can_access_statics for why
- // this check is so important.
- // This check is reachable when the const just referenced the static,
- // but never read it (so we never entered `before_access_global`).
- throw_validation_failure!(self.path,
- { "a {} pointing to a static variable", kind }
- );
+ match alloc_kind {
+ Some(GlobalAlloc::Static(did)) => {
+ // Special handling for pointers to statics (irrespective of their type).
+ assert!(!self.ecx.tcx.is_thread_local_static(did));
+ assert!(self.ecx.tcx.is_static(did));
+ if matches!(
+ self.ctfe_mode,
+ Some(CtfeValidationMode::Const { allow_static_ptrs: false, .. })
+ ) {
+ // See const_eval::machine::MemoryExtra::can_access_statics for why
+ // this check is so important.
+ // This check is reachable when the const just referenced the static,
+ // but never read it (so we never entered `before_access_global`).
+ throw_validation_failure!(self.path,
+ { "a {} pointing to a static variable in a constant", kind }
+ );
+ }
+ // We skip recursively checking other statics. These statics must be sound by
+ // themselves, and the only way to get broken statics here is by using
+ // unsafe code.
+ // The reasons we don't check other statics is twofold. For one, in all
+ // sound cases, the static was already validated on its own, and second, we
+ // trigger cycle errors if we try to compute the value of the other static
+ // and that static refers back to us.
+ // We might miss const-invalid data,
+ // but things are still sound otherwise (in particular re: consts
+ // referring to statics).
+ return Ok(());
}
- // We skip checking other statics. These statics must be sound by
- // themselves, and the only way to get broken statics here is by using
- // unsafe code.
- // The reasons we don't check other statics is twofold. For one, in all
- // sound cases, the static was already validated on its own, and second, we
- // trigger cycle errors if we try to compute the value of the other static
- // and that static refers back to us.
- // We might miss const-invalid data,
- // but things are still sound otherwise (in particular re: consts
- // referring to statics).
- return Ok(());
+ Some(GlobalAlloc::Memory(alloc)) => {
+ if alloc.inner().mutability == Mutability::Mut
+ && matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. }))
+ {
+ // This should be unreachable, but if someone manages to copy a pointer
+ // out of a `static`, then that pointer might point to mutable memory,
+ // and we would catch that here.
+ throw_validation_failure!(self.path,
+ { "a {} pointing to mutable memory in a constant", kind }
+ );
+ }
+ }
+ // Nothing to check for these.
+ None | Some(GlobalAlloc::Function(..) | GlobalAlloc::VTable(..)) => {}
}
}
let path = &self.path;
@@ -446,20 +483,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
Ok(())
}
- fn read_scalar(
- &self,
- op: &OpTy<'tcx, M::Provenance>,
- ) -> InterpResult<'tcx, ScalarMaybeUninit<M::Provenance>> {
- self.ecx.read_scalar(op)
- }
-
- fn read_immediate_forced(
- &self,
- op: &OpTy<'tcx, M::Provenance>,
- ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
- Ok(*self.ecx.read_immediate_raw(op, /*force*/ true)?.unwrap())
- }
-
/// Check if this is a value of primitive type, and if yes check the validity of the value
/// at that type. Return `true` if the type is indeed primitive.
fn try_visit_primitive(
@@ -470,41 +493,39 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let ty = value.layout.ty;
match ty.kind() {
ty::Bool => {
- let value = self.read_scalar(value)?;
+ let value = self.read_scalar(value, "a boolean")?;
try_validation!(
value.to_bool(),
self.path,
- err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) =>
+ InvalidBool(..) =>
{ "{:x}", value } expected { "a boolean" },
);
Ok(true)
}
ty::Char => {
- let value = self.read_scalar(value)?;
+ let value = self.read_scalar(value, "a unicode scalar value")?;
try_validation!(
value.to_char(),
self.path,
- err_ub!(InvalidChar(..)) | err_ub!(InvalidUninitBytes(None)) =>
+ InvalidChar(..) =>
{ "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
);
Ok(true)
}
ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
- let value = self.read_scalar(value)?;
// NOTE: Keep this in sync with the array optimization for int/float
// types below!
- if M::enforce_number_init(self.ecx) {
- try_validation!(
- value.check_init(),
- self.path,
- err_ub!(InvalidUninitBytes(..)) =>
- { "{:x}", value } expected { "initialized bytes" }
- );
- }
+ let value = self.read_scalar(
+ value,
+ if matches!(ty.kind(), ty::Float(..)) {
+ "a floating point number"
+ } else {
+ "an integer"
+ },
+ )?;
// 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_ptr = value.check_init().map_or(false, |v| matches!(v, Scalar::Ptr(..)));
- if is_ptr {
+ if matches!(value, Scalar::Ptr(..)) {
throw_validation_failure!(self.path,
{ "{:x}", value } expected { "plain (non-pointer) bytes" }
)
@@ -515,11 +536,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// We are conservative with uninit for integers, but try to
// actually enforce the strict rules for raw pointers (mostly because
// that lets us re-use `ref_to_mplace`).
- let place = try_validation!(
- self.ecx.read_immediate(value).and_then(|ref i| self.ecx.ref_to_mplace(i)),
- self.path,
- err_ub!(InvalidUninitBytes(None)) => { "uninitialized raw pointer" },
- );
+ let place =
+ self.ecx.ref_to_mplace(&self.read_immediate(value, "a raw pointer")?)?;
if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?;
}
@@ -527,7 +545,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
}
ty::Ref(_, ty, mutbl) => {
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. }))
- && *mutbl == hir::Mutability::Mut
+ && *mutbl == Mutability::Mut
{
// A mutable reference inside a const? That does not seem right (except if it is
// a ZST).
@@ -540,11 +558,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
Ok(true)
}
ty::FnPtr(_sig) => {
- let value = try_validation!(
- self.ecx.read_scalar(value).and_then(|v| v.check_init()),
- self.path,
- err_ub!(InvalidUninitBytes(None)) => { "uninitialized bytes" } expected { "a proper pointer or integer value" },
- );
+ let value = self.read_scalar(value, "a function pointer")?;
// If we check references recursively, also check that this points to a function.
if let Some(_) = self.ref_tracking {
@@ -552,8 +566,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let _fn = try_validation!(
self.ecx.get_ptr_fn(ptr),
self.path,
- err_ub!(DanglingIntPointer(..)) |
- err_ub!(InvalidFunctionPointer(..)) =>
+ DanglingIntPointer(..) |
+ InvalidFunctionPointer(..) =>
{ "{ptr}" } expected { "a function pointer" },
);
// FIXME: Check if the signature matches
@@ -595,40 +609,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
fn visit_scalar(
&mut self,
- scalar: ScalarMaybeUninit<M::Provenance>,
+ scalar: Scalar<M::Provenance>,
scalar_layout: ScalarAbi,
) -> InterpResult<'tcx> {
- // We check `is_full_range` in a slightly complicated way because *if* we are checking
- // number validity, then we want to ensure that `Scalar::Initialized` is indeed initialized,
- // i.e. that we go over the `check_init` below.
let size = scalar_layout.size(self.ecx);
- let is_full_range = match scalar_layout {
- ScalarAbi::Initialized { .. } => {
- if M::enforce_number_init(self.ecx) {
- false // not "full" since uninit is not accepted
- } else {
- scalar_layout.is_always_valid(self.ecx)
- }
- }
- ScalarAbi::Union { .. } => true,
- };
- if is_full_range {
- // Nothing to check. Cruciall we don't even `read_scalar` until here, since that would
- // fail for `Union` scalars!
- return Ok(());
- }
- // We have something to check: it must at least be initialized.
let valid_range = scalar_layout.valid_range(self.ecx);
let WrappingRange { start, end } = valid_range;
let max_value = size.unsigned_int_max();
assert!(end <= max_value);
- let value = try_validation!(
- scalar.check_init(),
- self.path,
- err_ub!(InvalidUninitBytes(None)) => { "{:x}", scalar }
- expected { "something {}", wrapping_range_format(valid_range, max_value) },
- );
- let bits = match value.try_to_int() {
+ let bits = match scalar.try_to_int() {
Ok(int) => int.assert_bits(size),
Err(_) => {
// So this is a pointer then, and casting to an int failed.
@@ -636,7 +625,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// We support 2 kinds of ranges here: full range, and excluding zero.
if start == 1 && end == max_value {
// Only null is the niche. So make sure the ptr is NOT null.
- if self.ecx.scalar_may_be_null(value)? {
+ if self.ecx.scalar_may_be_null(scalar)? {
throw_validation_failure!(self.path,
{ "a potentially null pointer" }
expected {
@@ -693,9 +682,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
Ok(try_validation!(
this.ecx.read_discriminant(op),
this.path,
- err_ub!(InvalidTag(val)) =>
+ InvalidTag(val) =>
{ "{:x}", val } expected { "a valid enum tag" },
- err_ub!(InvalidUninitBytes(None)) =>
+ InvalidUninitBytes(None) =>
{ "uninitialized bytes" } expected { "a valid enum tag" },
)
.1)
@@ -788,10 +777,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
);
}
Abi::Scalar(scalar_layout) => {
- // We use a 'forced' read because we always need a `Immediate` here
- // and treating "partially uninit" as "fully uninit" is fine for us.
- let scalar = self.read_immediate_forced(op)?.to_scalar_or_uninit();
- self.visit_scalar(scalar, scalar_layout)?;
+ if !scalar_layout.is_uninit_valid() {
+ // There is something to check here.
+ let scalar = self.read_scalar(op, "initiailized scalar value")?;
+ self.visit_scalar(scalar, scalar_layout)?;
+ }
}
Abi::ScalarPair(a_layout, b_layout) => {
// There is no `rustc_layout_scalar_valid_range_start` for pairs, so
@@ -799,10 +789,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// but that can miss bugs in layout computation. Layout computation
// is subtle due to enums having ScalarPair layout, where one field
// is the discriminant.
- if cfg!(debug_assertions) {
- // We use a 'forced' read because we always need a `Immediate` here
- // and treating "partially uninit" as "fully uninit" is fine for us.
- let (a, b) = self.read_immediate_forced(op)?.to_scalar_or_uninit_pair();
+ if cfg!(debug_assertions)
+ && !a_layout.is_uninit_valid()
+ && !b_layout.is_uninit_valid()
+ {
+ // We can only proceed if *both* scalars need to be initialized.
+ // FIXME: find a way to also check ScalarPair when one side can be uninit but
+ // the other must be init.
+ let (a, b) =
+ self.read_immediate(op, "initiailized scalar value")?.to_scalar_pair();
self.visit_scalar(a, a_layout)?;
self.visit_scalar(b, b_layout)?;
}
@@ -830,9 +825,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
let mplace = op.assert_mem_place(); // strings are unsized and hence never immediate
let len = mplace.len(self.ecx)?;
try_validation!(
- self.ecx.read_bytes_ptr(mplace.ptr, Size::from_bytes(len)),
+ self.ecx.read_bytes_ptr_strip_provenance(mplace.ptr, Size::from_bytes(len)),
self.path,
- err_ub!(InvalidUninitBytes(..)) => { "uninitialized data in `str`" },
+ InvalidUninitBytes(..) => { "uninitialized data in `str`" },
);
}
ty::Array(tys, ..) | ty::Slice(tys)
@@ -880,13 +875,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// We also accept uninit, for consistency with the slow path.
let alloc = self.ecx.get_ptr_alloc(mplace.ptr, size, mplace.align)?.expect("we already excluded size 0");
- match alloc.check_bytes(
- alloc_range(Size::ZERO, size),
- /*allow_uninit*/ !M::enforce_number_init(self.ecx),
- /*allow_ptr*/ false,
- ) {
+ match alloc.get_bytes_strip_provenance() {
// In the happy case, we needn't check anything else.
- Ok(()) => {}
+ Ok(_) => {}
// Some error happened, try to provide a more detailed description.
Err(err) => {
// For some errors we might be able to provide extra information.
@@ -981,6 +972,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// It will error if the bits at the destination do not match the ones described by the layout.
#[inline(always)]
pub fn validate_operand(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
+ // Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's
+ // still correct to not use `ctfe_mode`: that mode is for validation of the final constant
+ // value, it rules out things like `UnsafeCell` in awkward places. It also can make checking
+ // recurse through references which, for now, we don't want here, either.
self.validate_operand_internal(op, vec![], None, None)
}
}
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 72ac6af68..9f47d302a 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -10,7 +10,7 @@ Rust MIR: a lowered representation of Rust.
#![feature(decl_macro)]
#![feature(exact_size_is_empty)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(slice_ptr_get)]
diff --git a/compiler/rustc_const_eval/src/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/might_permit_raw_init.rs
index f971c2238..37ffa19cc 100644
--- a/compiler/rustc_const_eval/src/might_permit_raw_init.rs
+++ b/compiler/rustc_const_eval/src/might_permit_raw_init.rs
@@ -13,7 +13,11 @@ pub fn might_permit_raw_init<'tcx>(
let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
if strict {
- let machine = CompileTimeInterpreter::new(Limit::new(0), false);
+ let machine = CompileTimeInterpreter::new(
+ Limit::new(0),
+ /*can_access_statics:*/ false,
+ /*check_alignment:*/ true,
+ );
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
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 0adb88a18..7e15858c8 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -135,7 +135,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
// qualifs for the return type.
let return_block = ccx
.body
- .basic_blocks()
+ .basic_blocks
.iter_enumerated()
.find(|(_, block)| matches!(block.terminator().kind, TerminatorKind::Return))
.map(|(bb, _)| bb);
@@ -546,6 +546,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// Since no pointer can ever get exposed (rejected above), this is easy to support.
}
+ Rvalue::Cast(CastKind::DynStar, _, _) => {
+ unimplemented!()
+ }
+
Rvalue::Cast(CastKind::Misc, _, _) => {}
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
@@ -678,7 +682,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
| StatementKind::Retag { .. }
| StatementKind::AscribeUserType(..)
| StatementKind::Coverage(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Nop => {}
}
}
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 338022616..5fb4bf638 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -1,6 +1,7 @@
//! Concrete error types for all operations which may be invalid in a certain const context.
use hir::def_id::LocalDefId;
+use hir::ConstContext;
use rustc_errors::{
error_code, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
};
@@ -23,8 +24,11 @@ use rustc_trait_selection::traits::SelectionContext;
use super::ConstCx;
use crate::errors::{
- MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr,
- TransientMutBorrowErr, TransientMutBorrowErrRaw,
+ InteriorMutabilityBorrow, InteriorMutableDataRefer, MutDerefErr, NonConstFmtMacroCall,
+ NonConstFnCall, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr,
+ TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall,
+ UnallowedHeapAllocations, UnallowedInlineAsm, UnallowedMutableRefs, UnallowedMutableRefsRaw,
+ UnallowedOpInConstContext, UnstableConstFn,
};
use crate::util::{call_kind, CallDesugaringKind, CallKind};
@@ -96,10 +100,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- ccx.tcx.sess.struct_span_err(
- span,
- &format!("function pointer calls are not allowed in {}s", ccx.const_kind()),
- )
+ ccx.tcx.sess.create_err(UnallowedFnPointerCall { span, kind: ccx.const_kind() })
}
}
@@ -307,22 +308,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
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(),
- )
+ ccx.tcx.sess.create_err(NonConstFmtMacroCall { span, kind: ccx.const_kind() })
}
- _ => struct_span_err!(
- ccx.tcx.sess,
+ _ => ccx.tcx.sess.create_err(NonConstFnCall {
span,
- E0015,
- "cannot call non-const fn `{}` in {}s",
- ccx.tcx.def_path_str_with_substs(callee, substs),
- ccx.const_kind(),
- ),
+ def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs),
+ kind: ccx.const_kind(),
+ }),
};
err.note(&format!(
@@ -331,6 +323,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
ccx.const_kind(),
));
+ if let ConstContext::Static(_) = ccx.const_kind() {
+ err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell");
+ }
+
err
}
}
@@ -349,10 +345,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let FnCallUnstable(def_id, feature) = *self;
- let mut err = ccx.tcx.sess.struct_span_err(
- span,
- &format!("`{}` is not yet stable as a const fn", ccx.tcx.def_path_str(def_id)),
- );
+ let mut err = ccx
+ .tcx
+ .sess
+ .create_err(UnstableConstFn { span, def_path: ccx.tcx.def_path_str(def_id) });
if ccx.is_const_stable_const_fn() {
err.help("const-stable functions can only call other const-stable functions");
@@ -387,9 +383,12 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
- feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg)
+ ccx.tcx.sess.create_feature_err(
+ UnallowedOpInConstContext { span, msg },
+ sym::const_async_blocks,
+ )
} else {
- ccx.tcx.sess.struct_span_err(span, &msg)
+ ccx.tcx.sess.create_err(UnallowedOpInConstContext { span, msg })
}
}
}
@@ -402,23 +401,11 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let mut err = struct_span_err!(
- ccx.tcx.sess,
+ ccx.tcx.sess.create_err(UnallowedHeapAllocations {
span,
- E0010,
- "allocations are not allowed in {}s",
- ccx.const_kind()
- );
- err.span_label(span, format!("allocation not allowed in {}s", ccx.const_kind()));
- if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
- err.note(
- "The value of statics and constants must be known at compile time, \
- and they live for the entire lifetime of a program. Creating a boxed \
- value allocates memory on the heap at runtime, and therefore cannot \
- be done at compile time.",
- );
- }
- err
+ kind: ccx.const_kind(),
+ teach: ccx.tcx.sess.teach(&error_code!(E0010)).then_some(()),
+ })
}
}
@@ -430,13 +417,7 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- struct_span_err!(
- ccx.tcx.sess,
- span,
- E0015,
- "inline assembly is not allowed in {}s",
- ccx.const_kind()
- )
+ ccx.tcx.sess.create_err(UnallowedInlineAsm { span, kind: ccx.const_kind() })
}
}
@@ -482,12 +463,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- feature_err(
- &ccx.tcx.sess.parse_sess,
- sym::const_refs_to_cell,
- span,
- "cannot borrow here, since the borrowed element may contain interior mutability",
- )
+ ccx.tcx.sess.create_feature_err(InteriorMutabilityBorrow { span }, sym::const_refs_to_cell)
}
}
@@ -502,32 +478,22 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let mut err = struct_span_err!(
- ccx.tcx.sess,
- span,
- E0492,
- "{}s cannot refer to interior mutable data",
- ccx.const_kind(),
- );
- err.span_label(
- span,
- "this borrow of an interior mutable value may end up in the final value",
- );
+ // FIXME: Maybe a more elegant solution to this if else case
if let hir::ConstContext::Static(_) = ccx.const_kind() {
- err.help(
- "to fix this, the value can be extracted to a separate \
- `static` item and then referenced",
- );
- }
- if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
- err.note(
- "A constant containing interior mutable data behind a reference can allow you
- to modify that data. This would make multiple uses of a constant to be able to
- see different values and allow circumventing the `Send` and `Sync` requirements
- for shared mutable data, which is unsound.",
- );
+ ccx.tcx.sess.create_err(InteriorMutableDataRefer {
+ span,
+ opt_help: Some(()),
+ kind: ccx.const_kind(),
+ teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
+ })
+ } else {
+ ccx.tcx.sess.create_err(InteriorMutableDataRefer {
+ span,
+ opt_help: None,
+ kind: ccx.const_kind(),
+ teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
+ })
}
- err
}
}
@@ -553,33 +519,18 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let raw = match self.0 {
- hir::BorrowKind::Raw => "raw ",
- hir::BorrowKind::Ref => "",
- };
-
- let mut err = struct_span_err!(
- ccx.tcx.sess,
- span,
- E0764,
- "{}mutable references are not allowed in the final value of {}s",
- raw,
- ccx.const_kind(),
- );
-
- if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
- err.note(
- "References in statics and constants may only refer \
- to immutable values.\n\n\
- Statics are shared everywhere, and if they refer to \
- mutable data one might violate memory safety since \
- holding multiple mutable references to shared data \
- is not allowed.\n\n\
- If you really want global mutable state, try using \
- static mut or a global UnsafeCell.",
- );
+ match self.0 {
+ hir::BorrowKind::Raw => ccx.tcx.sess.create_err(UnallowedMutableRefsRaw {
+ span,
+ kind: ccx.const_kind(),
+ teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
+ }),
+ hir::BorrowKind::Ref => ccx.tcx.sess.create_err(UnallowedMutableRefs {
+ span,
+ kind: ccx.const_kind(),
+ teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
+ }),
}
- err
}
}
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 c8a63c9c3..6c73ef5a8 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -5,12 +5,11 @@
use rustc_errors::ErrorGuaranteed;
use rustc_hir::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::TraitEngine;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
use rustc_span::DUMMY_SP;
use rustc_trait_selection::traits::{
- self, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngineExt,
+ self, ImplSource, Obligation, ObligationCause, SelectionContext,
};
use super::ConstCx;
@@ -189,15 +188,8 @@ impl Qualif for NeedsNonConstDrop {
return false;
}
- // If we successfully found one, then select all of the predicates
- // implied by our const drop impl.
- let mut fcx = <dyn TraitEngine<'tcx>>::new(cx.tcx);
- for nested in impl_src.nested_obligations() {
- fcx.register_predicate_obligation(&infcx, nested);
- }
-
// If we had any errors, then it's bad
- !fcx.select_all_or_error(&infcx).is_empty()
+ !traits::fully_solve_obligations(&infcx, impl_src.nested_obligations()).is_empty()
})
}
@@ -354,31 +346,43 @@ 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.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.
- assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
- // Don't peek inside trait associated constants.
- if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
- let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
- cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
- } else {
- cx.tcx.at(constant.span).mir_const_qualif(def.did)
- };
-
- if !Q::in_qualifs(&qualifs) {
- return false;
- }
+ // FIXME(valtrees): check whether const qualifs should behave the same
+ // way for type and mir constants.
+ let uneval = match constant.literal {
+ ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => {
+ let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() };
+
+ Some(uv.expand())
+ }
+ ConstantKind::Ty(_) => None,
+ ConstantKind::Unevaluated(uv, _) => Some(uv),
+ ConstantKind::Val(..) => None,
+ };
- // Just in case the type is more specific than
- // the definition, e.g., impl associated const
- // with type parameters, take it into account.
+ if let Some(ty::Unevaluated { def, substs: _, promoted }) = uneval {
+ // 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.
+ assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
+
+ // Don't peek inside trait associated constants.
+ if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
+ let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
+ cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
+ } else {
+ cx.tcx.at(constant.span).mir_const_qualif(def.did)
+ };
+
+ if !Q::in_qualifs(&qualifs) {
+ return false;
}
+
+ // Just in case the type is more specific than
+ // the definition, e.g., impl associated const
+ // with type parameters, take it into account.
}
}
+
// Otherwise use the qualifs of the type.
Q::in_any_value_of_ty(cx, constant.literal.ty())
}
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index ed4d8c95d..f7a7cc88a 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -41,7 +41,7 @@ pub struct PromoteTemps<'tcx> {
impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
fn phase_change(&self) -> Option<MirPhase> {
- Some(MirPhase::ConstsPromoted)
+ Some(MirPhase::Analysis(AnalysisPhase::Initial))
}
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -710,7 +710,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}
fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) {
- let last = self.promoted.basic_blocks().last().unwrap();
+ let last = self.promoted.basic_blocks.last().unwrap();
let data = &mut self.promoted[last];
data.statements.push(Statement {
source_info: SourceInfo::outermost(span),
@@ -803,7 +803,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
self.visit_operand(arg, loc);
}
- let last = self.promoted.basic_blocks().last().unwrap();
+ let last = self.promoted.basic_blocks.last().unwrap();
let new_target = self.new_block();
*self.promoted[last].terminator_mut() = Terminator {
@@ -839,27 +839,16 @@ 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),
- }),
- });
+ let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
+ let uneval = ty::Unevaluated { def, substs, promoted: Some(promoted_id) };
Operand::Constant(Box::new(Constant {
span,
user_ty: None,
- literal: ConstantKind::from_const(_const, tcx),
+ literal: ConstantKind::Unevaluated(uneval, ty),
}))
};
+
let blocks = self.source.basic_blocks.as_mut();
let local_decls = &mut self.source.local_decls;
let loc = candidate.location;
@@ -969,7 +958,7 @@ pub fn promote_candidates<'tcx>(
let mut scope = body.source_scopes[body.source_info(candidate.location).scope].clone();
scope.parent_scope = None;
- let promoted = Body::new(
+ let mut promoted = Body::new(
body.source, // `promoted` gets filled in below
IndexVec::new(),
IndexVec::from_elem_n(scope, 1),
@@ -981,6 +970,7 @@ pub fn promote_candidates<'tcx>(
body.generator_kind(),
body.tainted_by_errors,
);
+ promoted.phase = MirPhase::Analysis(AnalysisPhase::Initial);
let promoter = Promoter {
promoted,
@@ -1046,7 +1036,7 @@ pub fn is_const_fn_in_array_repeat_expression<'tcx>(
_ => {}
}
- for block in body.basic_blocks() {
+ for block in body.basic_blocks.iter() {
if let Some(Terminator { kind: TerminatorKind::Call { func, destination, .. }, .. }) =
&block.terminator
{
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 15e820f2d..4aa98cb13 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -7,9 +7,10 @@ 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, CastKind, Local, Location,
- MirPass, MirPhase, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, Rvalue, SourceScope,
- Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK,
+ traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping,
+ Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef,
+ ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
+ TerminatorKind, UnOp, START_BLOCK,
};
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::Subst;
@@ -89,9 +90,8 @@ pub fn equal_up_to_regions<'tcx>(
// Normalize lifetimes away on both sides, then compare.
let normalize = |ty: Ty<'tcx>| {
- tcx.normalize_erasing_regions(
- param_env,
- ty.fold_with(&mut BottomUpFolder {
+ tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty).fold_with(
+ &mut BottomUpFolder {
tcx,
// FIXME: We erase all late-bound lifetimes, but this is not fully correct.
// If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`,
@@ -103,7 +103,7 @@ pub fn equal_up_to_regions<'tcx>(
// Leave consts and types unchanged.
ct_op: |ct| ct,
ty_op: |ty| ty,
- }),
+ },
)
};
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
@@ -142,8 +142,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if bb == START_BLOCK {
self.fail(location, "start block must not have predecessors")
}
- if let Some(bb) = self.body.basic_blocks().get(bb) {
- let src = self.body.basic_blocks().get(location.block).unwrap();
+ if let Some(bb) = self.body.basic_blocks.get(bb) {
+ let src = self.body.basic_blocks.get(location.block).unwrap();
match (src.is_cleanup, bb.is_cleanup, edge_kind) {
// Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges
(false, false, EdgeKind::Normal)
@@ -183,16 +183,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if (src, dest).has_opaque_types() {
return true;
}
- // Normalize projections and things like that.
- let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
- let src = self.tcx.normalize_erasing_regions(param_env, src);
- let dest = self.tcx.normalize_erasing_regions(param_env, dest);
+ // Normalize projections and things like that.
// Type-changing assignments can happen when subtyping is used. While
// all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type
// differences. So we compare ignoring lifetimes.
- equal_up_to_regions(self.tcx, param_env, src, dest)
+
+ // First, try with reveal_all. This might not work in some cases, as the predicates
+ // can be cleared in reveal_all mode. We try the reveal first anyways as it is used
+ // by some other passes like inlining as well.
+ let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
+ if equal_up_to_regions(self.tcx, param_env, src, dest) {
+ return true;
+ }
+
+ // If this fails, we can try it without the reveal.
+ equal_up_to_regions(self.tcx, self.param_env, src, dest)
}
}
@@ -223,7 +230,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
// This check is somewhat expensive, so only run it when -Zvalidate-mir is passed.
- if self.tcx.sess.opts.unstable_opts.validate_mir && self.mir_phase < MirPhase::DropsLowered
+ if self.tcx.sess.opts.unstable_opts.validate_mir
+ && self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial)
{
// `Operand::Copy` is only supposed to be used with `Copy` types.
if let Operand::Copy(place) = operand {
@@ -254,7 +262,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.fail(location, format!("bad index ({:?} != usize)", index_ty))
}
}
- ProjectionElem::Deref if self.mir_phase >= MirPhase::GeneratorsLowered => {
+ ProjectionElem::Deref
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::PostCleanup) =>
+ {
let base_ty = Place::ty_from(local, proj_base, &self.body.local_decls, self.tcx).ty;
if base_ty.is_box() {
@@ -362,7 +372,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// 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
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial)
&& place.projection.len() > 1
&& cntxt != PlaceContext::NonUse(VarDebugInfo)
&& place.projection[1..].contains(&ProjectionElem::Deref)
@@ -386,8 +396,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
Rvalue::Aggregate(agg_kind, _) => {
let disallowed = match **agg_kind {
AggregateKind::Array(..) => false,
- AggregateKind::Generator(..) => self.mir_phase >= MirPhase::GeneratorsLowered,
- _ => self.mir_phase >= MirPhase::Deaggregated,
+ _ => self.mir_phase >= MirPhase::Runtime(RuntimePhase::PostCleanup),
};
if disallowed {
self.fail(
@@ -397,10 +406,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
Rvalue::Ref(_, BorrowKind::Shallow, _) => {
- if self.mir_phase >= MirPhase::DropsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
- "`Assign` statement with a `Shallow` borrow should have been removed after drop lowering phase",
+ "`Assign` statement with a `Shallow` borrow should have been removed in runtime MIR",
);
}
}
@@ -560,6 +569,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
);
}
}
+ CastKind::DynStar => {
+ // FIXME(dyn-star): make sure nothing needs to be done here.
+ }
// Nothing to check here
CastKind::PointerFromExposedAddress
| CastKind::PointerExposeAddress
@@ -614,7 +626,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
StatementKind::AscribeUserType(..) => {
- if self.mir_phase >= MirPhase::DropsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
"`AscribeUserType` should have been removed after drop lowering phase",
@@ -622,18 +634,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
StatementKind::FakeRead(..) => {
- if self.mir_phase >= MirPhase::DropsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
"`FakeRead` should have been removed after drop lowering phase",
);
}
}
- StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
- ref src,
- ref dst,
- ref count,
- }) => {
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
+ let ty = op.ty(&self.body.local_decls, self.tcx);
+ if !ty.is_bool() {
+ self.fail(
+ location,
+ format!("`assume` argument must be `bool`, but got: `{}`", ty),
+ );
+ }
+ }
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
+ CopyNonOverlapping { src, dst, count },
+ )) => {
let src_ty = src.ty(&self.body.local_decls, self.tcx);
let op_src_ty = if let Some(src_deref) = src_ty.builtin_deref(true) {
src_deref.ty
@@ -666,7 +685,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
StatementKind::SetDiscriminant { place, .. } => {
- if self.mir_phase < MirPhase::Deaggregated {
+ if self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
}
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
@@ -681,7 +700,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
StatementKind::Deinit(..) => {
- if self.mir_phase < MirPhase::Deaggregated {
+ if self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, "`Deinit`is not allowed until deaggregation");
}
}
@@ -761,7 +780,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
TerminatorKind::DropAndReplace { target, unwind, .. } => {
- if self.mir_phase >= MirPhase::DropsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
"`DropAndReplace` should have been removed during drop elaboration",
@@ -832,7 +851,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
if self.body.generator.is_none() {
self.fail(location, "`Yield` cannot appear outside generator bodies");
}
- if self.mir_phase >= MirPhase::GeneratorsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, "`Yield` should have been replaced by generator lowering");
}
self.check_edge(location, *resume, EdgeKind::Normal);
@@ -841,7 +860,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
TerminatorKind::FalseEdge { real_target, imaginary_target } => {
- if self.mir_phase >= MirPhase::DropsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
"`FalseEdge` should have been removed after drop elaboration",
@@ -851,7 +870,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.check_edge(location, *imaginary_target, EdgeKind::Normal);
}
TerminatorKind::FalseUnwind { real_target, unwind } => {
- if self.mir_phase >= MirPhase::DropsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
"`FalseUnwind` should have been removed after drop elaboration",
@@ -874,7 +893,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
if self.body.generator.is_none() {
self.fail(location, "`GeneratorDrop` cannot appear outside generator bodies");
}
- if self.mir_phase >= MirPhase::GeneratorsLowered {
+ if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
location,
"`GeneratorDrop` should have been replaced by generator lowering",
@@ -883,13 +902,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
TerminatorKind::Resume | TerminatorKind::Abort => {
let bb = location.block;
- if !self.body.basic_blocks()[bb].is_cleanup {
+ if !self.body.basic_blocks[bb].is_cleanup {
self.fail(location, "Cannot `Resume` or `Abort` from non-cleanup basic block")
}
}
TerminatorKind::Return => {
let bb = location.block;
- if self.body.basic_blocks()[bb].is_cleanup {
+ if self.body.basic_blocks[bb].is_cleanup {
self.fail(location, "Cannot `Return` from cleanup basic block")
}
}
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 5c641f54f..2d8658db5 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -8,25 +8,26 @@ doctest = false
[dependencies]
arrayvec = { version = "0.7", default-features = false }
+bitflags = "1.2.1"
+cfg-if = "0.1.2"
ena = "0.14"
indexmap = { version = "1.9.1" }
-tracing = "0.1"
jobserver_crate = { version = "0.1.13", package = "jobserver" }
-rustc_serialize = { path = "../rustc_serialize" }
-rustc_macros = { path = "../rustc_macros" }
-rustc_graphviz = { path = "../rustc_graphviz" }
-cfg-if = "0.1.2"
-stable_deref_trait = "1.0.0"
-rayon = { version = "0.4.0", package = "rustc-rayon", optional = true }
+libc = "0.2"
+measureme = "10.0.0"
rayon-core = { version = "0.4.0", package = "rustc-rayon-core", optional = true }
+rayon = { version = "0.4.0", package = "rustc-rayon", optional = true }
+rustc_graphviz = { path = "../rustc_graphviz" }
rustc-hash = "1.1.0"
-smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] }
rustc_index = { path = "../rustc_index", package = "rustc_index" }
-bitflags = "1.2.1"
-measureme = "10.0.0"
-libc = "0.2"
+rustc_macros = { path = "../rustc_macros" }
+rustc_serialize = { path = "../rustc_serialize" }
+smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] }
+stable_deref_trait = "1.0.0"
stacker = "0.1.14"
tempfile = "3.2"
+thin-vec = "0.2.8"
+tracing = "0.1"
[dependencies.parking_lot]
version = "0.11"
diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs
index 5ff2d18dd..a39178016 100644
--- a/compiler/rustc_data_structures/src/fingerprint.rs
+++ b/compiler/rustc_data_structures/src/fingerprint.rs
@@ -29,7 +29,7 @@ impl Fingerprint {
// quality hash values, let's still combine the two values because the
// Fingerprints in DefPathHash have the StableCrateId portion which is
// the same for all DefPathHashes from the same crate. Combining the
- // two halfs makes sure we get a good quality hash in such cases too.
+ // two halves makes sure we get a good quality hash in such cases too.
self.0.wrapping_mul(3).wrapping_add(self.1)
}
@@ -120,7 +120,7 @@ impl FingerprintHasher for crate::unhash::Unhasher {
// quality hash values, let's still combine the two values because the
// Fingerprints in DefPathHash have the StableCrateId portion which is
// the same for all DefPathHashes from the same crate. Combining the
- // two halfs makes sure we get a good quality hash in such cases too.
+ // two halves makes sure we get a good quality hash in such cases too.
//
// Since `Unhasher` is used only in the context of HashMaps, it is OK
// to combine the two components in an order-independent way (which is
diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs
index bbeb193db..0d0c51b68 100644
--- a/compiler/rustc_data_structures/src/fx.rs
+++ b/compiler/rustc_data_structures/src/fx.rs
@@ -2,13 +2,26 @@ use std::hash::BuildHasherDefault;
pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
+pub type StdEntry<'a, K, V> = std::collections::hash_map::Entry<'a, K, V>;
+
pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
+pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
#[macro_export]
macro_rules! define_id_collections {
- ($map_name:ident, $set_name:ident, $key:ty) => {
+ ($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
pub type $map_name<T> = $crate::fx::FxHashMap<$key, T>;
pub type $set_name = $crate::fx::FxHashSet<$key>;
+ pub type $entry_name<'a, T> = $crate::fx::StdEntry<'a, $key, T>;
+ };
+}
+
+#[macro_export]
+macro_rules! define_stable_id_collections {
+ ($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
+ pub type $map_name<T> = $crate::fx::FxIndexMap<$key, T>;
+ pub type $set_name = $crate::fx::FxIndexSet<$key>;
+ pub type $entry_name<'a, T> = $crate::fx::IndexEntry<'a, $key, T>;
};
}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 265f45b72..56f7823ef 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -13,7 +13,7 @@
#![feature(cell_leak)]
#![feature(control_flow_enum)]
#![feature(extend_one)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(hash_raw_entry)]
#![feature(hasher_prefixfree_extras)]
#![feature(maybe_uninit_uninit_array)]
@@ -28,6 +28,8 @@
#![feature(vec_into_raw_parts)]
#![allow(rustc::default_hash_types)]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
@@ -73,7 +75,6 @@ pub mod profiling;
pub mod sharded;
pub mod stack;
pub mod sync;
-pub mod thin_vec;
pub mod tiny_list;
pub mod transitive_relation;
pub mod vec_linked_list;
diff --git a/compiler/rustc_data_structures/src/map_in_place.rs b/compiler/rustc_data_structures/src/map_in_place.rs
index 874de03d3..a0d4b7ade 100644
--- a/compiler/rustc_data_structures/src/map_in_place.rs
+++ b/compiler/rustc_data_structures/src/map_in_place.rs
@@ -1,5 +1,6 @@
use smallvec::{Array, SmallVec};
use std::ptr;
+use thin_vec::ThinVec;
pub trait MapInPlace<T>: Sized {
fn map_in_place<F>(&mut self, mut f: F)
@@ -15,94 +16,64 @@ pub trait MapInPlace<T>: Sized {
I: IntoIterator<Item = T>;
}
-impl<T> MapInPlace<T> for Vec<T> {
- fn flat_map_in_place<F, I>(&mut self, mut f: F)
- where
- F: FnMut(T) -> I,
- I: IntoIterator<Item = T>,
- {
- let mut read_i = 0;
- let mut write_i = 0;
- unsafe {
- let mut old_len = self.len();
- self.set_len(0); // make sure we just leak elements in case of panic
+// The implementation of this method is syntactically identical for all the
+// different vector types.
+macro_rules! flat_map_in_place {
+ () => {
+ fn flat_map_in_place<F, I>(&mut self, mut f: F)
+ where
+ F: FnMut(T) -> I,
+ I: IntoIterator<Item = T>,
+ {
+ let mut read_i = 0;
+ let mut write_i = 0;
+ unsafe {
+ let mut old_len = self.len();
+ self.set_len(0); // make sure we just leak elements in case of panic
- while read_i < old_len {
- // move the read_i'th item out of the vector and map it
- // to an iterator
- let e = ptr::read(self.as_ptr().add(read_i));
- let iter = f(e).into_iter();
- read_i += 1;
+ while read_i < old_len {
+ // move the read_i'th item out of the vector and map it
+ // to an iterator
+ let e = ptr::read(self.as_ptr().add(read_i));
+ let iter = f(e).into_iter();
+ read_i += 1;
- for e in iter {
- if write_i < read_i {
- ptr::write(self.as_mut_ptr().add(write_i), e);
- write_i += 1;
- } else {
- // If this is reached we ran out of space
- // in the middle of the vector.
- // However, the vector is in a valid state here,
- // so we just do a somewhat inefficient insert.
- self.set_len(old_len);
- self.insert(write_i, e);
+ for e in iter {
+ if write_i < read_i {
+ ptr::write(self.as_mut_ptr().add(write_i), e);
+ write_i += 1;
+ } else {
+ // If this is reached we ran out of space
+ // in the middle of the vector.
+ // However, the vector is in a valid state here,
+ // so we just do a somewhat inefficient insert.
+ self.set_len(old_len);
+ self.insert(write_i, e);
- old_len = self.len();
- self.set_len(0);
+ old_len = self.len();
+ self.set_len(0);
- read_i += 1;
- write_i += 1;
+ read_i += 1;
+ write_i += 1;
+ }
}
}
- }
- // write_i tracks the number of actually written new items.
- self.set_len(write_i);
+ // write_i tracks the number of actually written new items.
+ self.set_len(write_i);
+ }
}
- }
+ };
}
-impl<T, A: Array<Item = T>> MapInPlace<T> for SmallVec<A> {
- fn flat_map_in_place<F, I>(&mut self, mut f: F)
- where
- F: FnMut(T) -> I,
- I: IntoIterator<Item = T>,
- {
- let mut read_i = 0;
- let mut write_i = 0;
- unsafe {
- let mut old_len = self.len();
- self.set_len(0); // make sure we just leak elements in case of panic
-
- while read_i < old_len {
- // move the read_i'th item out of the vector and map it
- // to an iterator
- let e = ptr::read(self.as_ptr().add(read_i));
- let iter = f(e).into_iter();
- read_i += 1;
-
- for e in iter {
- if write_i < read_i {
- ptr::write(self.as_mut_ptr().add(write_i), e);
- write_i += 1;
- } else {
- // If this is reached we ran out of space
- // in the middle of the vector.
- // However, the vector is in a valid state here,
- // so we just do a somewhat inefficient insert.
- self.set_len(old_len);
- self.insert(write_i, e);
-
- old_len = self.len();
- self.set_len(0);
+impl<T> MapInPlace<T> for Vec<T> {
+ flat_map_in_place!();
+}
- read_i += 1;
- write_i += 1;
- }
- }
- }
+impl<T, A: Array<Item = T>> MapInPlace<T> for SmallVec<A> {
+ flat_map_in_place!();
+}
- // write_i tracks the number of actually written new items.
- self.set_len(write_i);
- }
- }
+impl<T> MapInPlace<T> for ThinVec<T> {
+ flat_map_in_place!();
}
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 07a96dd7d..e351b650a 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -117,6 +117,10 @@ pub trait ObligationProcessor {
}
/// The result type used by `process_obligation`.
+// `repr(C)` to inhibit the niche filling optimization. Otherwise, the `match` appearing
+// in `process_obligations` is significantly slower, which can substantially affect
+// benchmarks like `rustc-perf`'s inflate and keccak.
+#[repr(C)]
#[derive(Debug)]
pub enum ProcessResult<O, E> {
Unchanged,
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 9efea1228..937cb6715 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -164,7 +164,7 @@ impl<K: Ord, V> SortedMap<K, V> {
/// It is up to the caller to make sure that the elements are sorted by key
/// and that there are no duplicates.
#[inline]
- pub fn insert_presorted(&mut self, mut elements: Vec<(K, V)>) {
+ pub fn insert_presorted(&mut self, elements: Vec<(K, V)>) {
if elements.is_empty() {
return;
}
@@ -173,28 +173,28 @@ impl<K: Ord, V> SortedMap<K, V> {
let start_index = self.lookup_index_for(&elements[0].0);
- let drain = match start_index {
+ let elements = match start_index {
Ok(index) => {
- let mut drain = elements.drain(..);
- self.data[index] = drain.next().unwrap();
- drain
+ let mut elements = elements.into_iter();
+ self.data[index] = elements.next().unwrap();
+ elements
}
Err(index) => {
if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 {
// We can copy the whole range without having to mix with
// existing elements.
- self.data.splice(index..index, elements.drain(..));
+ self.data.splice(index..index, elements.into_iter());
return;
}
- let mut drain = elements.drain(..);
- self.data.insert(index, drain.next().unwrap());
- drain
+ let mut elements = elements.into_iter();
+ self.data.insert(index, elements.next().unwrap());
+ elements
}
};
// Insert the rest
- for (k, v) in drain {
+ for (k, v) in elements {
self.insert(k, v);
}
}
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 52952a793..9c0fb8265 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -48,7 +48,7 @@ cfg_if! {
/// the native atomic types.
/// You should use this type through the `AtomicU64`, `AtomicUsize`, etc, type aliases
/// as it's not intended to be used separately.
- #[derive(Debug)]
+ #[derive(Debug, Default)]
pub struct Atomic<T: Copy>(Cell<T>);
impl<T: Copy> Atomic<T> {
@@ -56,9 +56,7 @@ cfg_if! {
pub fn new(v: T) -> Self {
Atomic(Cell::new(v))
}
- }
- impl<T: Copy> Atomic<T> {
#[inline]
pub fn into_inner(self) -> T {
self.0.into_inner()
diff --git a/compiler/rustc_data_structures/src/thin_vec.rs b/compiler/rustc_data_structures/src/thin_vec.rs
deleted file mode 100644
index 716259142..000000000
--- a/compiler/rustc_data_structures/src/thin_vec.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-use crate::stable_hasher::{HashStable, StableHasher};
-
-use std::iter::FromIterator;
-
-/// A vector type optimized for cases where this size is usually 0 (cf. `SmallVec`).
-/// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
-/// which uses only a single (null) pointer.
-#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
-pub struct ThinVec<T>(Option<Box<Vec<T>>>);
-
-impl<T> ThinVec<T> {
- pub fn new() -> Self {
- ThinVec(None)
- }
-
- pub fn iter(&self) -> std::slice::Iter<'_, T> {
- self.into_iter()
- }
-
- pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
- self.into_iter()
- }
-
- pub fn push(&mut self, item: T) {
- match *self {
- ThinVec(Some(ref mut vec)) => vec.push(item),
- ThinVec(None) => *self = vec![item].into(),
- }
- }
-}
-
-impl<T> From<Vec<T>> for ThinVec<T> {
- fn from(vec: Vec<T>) -> Self {
- if vec.is_empty() { ThinVec(None) } else { ThinVec(Some(Box::new(vec))) }
- }
-}
-
-impl<T> Into<Vec<T>> for ThinVec<T> {
- fn into(self) -> Vec<T> {
- match self {
- ThinVec(None) => Vec::new(),
- ThinVec(Some(vec)) => *vec,
- }
- }
-}
-
-impl<T> ::std::ops::Deref for ThinVec<T> {
- type Target = [T];
- fn deref(&self) -> &[T] {
- match *self {
- ThinVec(None) => &[],
- ThinVec(Some(ref vec)) => vec,
- }
- }
-}
-
-impl<T> ::std::ops::DerefMut for ThinVec<T> {
- fn deref_mut(&mut self) -> &mut [T] {
- match *self {
- ThinVec(None) => &mut [],
- ThinVec(Some(ref mut vec)) => vec,
- }
- }
-}
-
-impl<T> FromIterator<T> for ThinVec<T> {
- fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
- // `Vec::from_iter()` should not allocate if the iterator is empty.
- let vec: Vec<_> = iter.into_iter().collect();
- if vec.is_empty() { ThinVec(None) } else { ThinVec(Some(Box::new(vec))) }
- }
-}
-
-impl<T> IntoIterator for ThinVec<T> {
- type Item = T;
- type IntoIter = std::vec::IntoIter<T>;
-
- fn into_iter(self) -> Self::IntoIter {
- // This is still performant because `Vec::new()` does not allocate.
- self.0.map_or_else(Vec::new, |ptr| *ptr).into_iter()
- }
-}
-
-impl<'a, T> IntoIterator for &'a ThinVec<T> {
- type Item = &'a T;
- type IntoIter = std::slice::Iter<'a, T>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.as_ref().iter()
- }
-}
-
-impl<'a, T> IntoIterator for &'a mut ThinVec<T> {
- type Item = &'a mut T;
- type IntoIter = std::slice::IterMut<'a, T>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.as_mut().iter_mut()
- }
-}
-
-impl<T> Extend<T> for ThinVec<T> {
- fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
- match *self {
- ThinVec(Some(ref mut vec)) => vec.extend(iter),
- ThinVec(None) => *self = iter.into_iter().collect::<Vec<_>>().into(),
- }
- }
-
- fn extend_one(&mut self, item: T) {
- self.push(item)
- }
-
- fn extend_reserve(&mut self, additional: usize) {
- match *self {
- ThinVec(Some(ref mut vec)) => vec.reserve(additional),
- ThinVec(None) => *self = Vec::with_capacity(additional).into(),
- }
- }
-}
-
-impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ThinVec<T> {
- fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
- (**self).hash_stable(hcx, hasher)
- }
-}
-
-impl<T> Default for ThinVec<T> {
- fn default() -> Self {
- Self(None)
- }
-}
-
-#[cfg(test)]
-mod tests;
diff --git a/compiler/rustc_data_structures/src/thin_vec/tests.rs b/compiler/rustc_data_structures/src/thin_vec/tests.rs
deleted file mode 100644
index 0221b9912..000000000
--- a/compiler/rustc_data_structures/src/thin_vec/tests.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use super::*;
-
-impl<T> ThinVec<T> {
- fn into_vec(self) -> Vec<T> {
- self.into()
- }
-}
-
-#[test]
-fn test_from_iterator() {
- assert_eq!(std::iter::empty().collect::<ThinVec<String>>().into_vec(), Vec::<String>::new());
- assert_eq!(std::iter::once(42).collect::<ThinVec<_>>().into_vec(), vec![42]);
- assert_eq!([1, 2].into_iter().collect::<ThinVec<_>>().into_vec(), vec![1, 2]);
- assert_eq!([1, 2, 3].into_iter().collect::<ThinVec<_>>().into_vec(), vec![1, 2, 3]);
-}
-
-#[test]
-fn test_into_iterator_owned() {
- assert_eq!(ThinVec::new().into_iter().collect::<Vec<String>>(), Vec::<String>::new());
- assert_eq!(ThinVec::from(vec![1]).into_iter().collect::<Vec<_>>(), vec![1]);
- assert_eq!(ThinVec::from(vec![1, 2]).into_iter().collect::<Vec<_>>(), vec![1, 2]);
- assert_eq!(ThinVec::from(vec![1, 2, 3]).into_iter().collect::<Vec<_>>(), vec![1, 2, 3]);
-}
-
-#[test]
-fn test_into_iterator_ref() {
- assert_eq!(ThinVec::new().iter().collect::<Vec<&String>>(), Vec::<&String>::new());
- assert_eq!(ThinVec::from(vec![1]).iter().collect::<Vec<_>>(), vec![&1]);
- assert_eq!(ThinVec::from(vec![1, 2]).iter().collect::<Vec<_>>(), vec![&1, &2]);
- assert_eq!(ThinVec::from(vec![1, 2, 3]).iter().collect::<Vec<_>>(), vec![&1, &2, &3]);
-}
-
-#[test]
-fn test_into_iterator_ref_mut() {
- assert_eq!(ThinVec::new().iter_mut().collect::<Vec<&mut String>>(), Vec::<&mut String>::new());
- assert_eq!(ThinVec::from(vec![1]).iter_mut().collect::<Vec<_>>(), vec![&mut 1]);
- assert_eq!(ThinVec::from(vec![1, 2]).iter_mut().collect::<Vec<_>>(), vec![&mut 1, &mut 2]);
- assert_eq!(
- ThinVec::from(vec![1, 2, 3]).iter_mut().collect::<Vec<_>>(),
- vec![&mut 1, &mut 2, &mut 3],
- );
-}
diff --git a/compiler/rustc_data_structures/src/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs
index 0ff64969b..f016c391f 100644
--- a/compiler/rustc_data_structures/src/transitive_relation.rs
+++ b/compiler/rustc_data_structures/src/transitive_relation.rs
@@ -1,45 +1,57 @@
+use crate::frozen::Frozen;
use crate::fx::FxIndexSet;
-use crate::sync::Lock;
use rustc_index::bit_set::BitMatrix;
use std::fmt::Debug;
use std::hash::Hash;
use std::mem;
+use std::ops::Deref;
#[cfg(test)]
mod tests;
#[derive(Clone, Debug)]
-pub struct TransitiveRelation<T> {
+pub struct TransitiveRelationBuilder<T> {
// List of elements. This is used to map from a T to a usize.
elements: FxIndexSet<T>,
// List of base edges in the graph. Require to compute transitive
// closure.
edges: Vec<Edge>,
+}
+
+#[derive(Debug)]
+pub struct TransitiveRelation<T> {
+ // Frozen transitive relation elements and edges.
+ builder: Frozen<TransitiveRelationBuilder<T>>,
- // This is a cached transitive closure derived from the edges.
- // Currently, we build it lazily and just throw out any existing
- // copy whenever a new edge is added. (The Lock is to permit
- // the lazy computation.) This is kind of silly, except for the
- // fact its size is tied to `self.elements.len()`, so I wanted to
- // wait before building it up to avoid reallocating as new edges
- // are added with new elements. Perhaps better would be to ask the
- // user for a batch of edges to minimize this effect, but I
- // already wrote the code this way. :P -nmatsakis
- closure: Lock<Option<BitMatrix<usize, usize>>>,
+ // Cached transitive closure derived from the edges.
+ closure: Frozen<BitMatrix<usize, usize>>,
}
-// HACK(eddyb) manual impl avoids `Default` bound on `T`.
-impl<T: Eq + Hash> Default for TransitiveRelation<T> {
- fn default() -> Self {
+impl<T> Deref for TransitiveRelation<T> {
+ type Target = Frozen<TransitiveRelationBuilder<T>>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.builder
+ }
+}
+
+impl<T: Clone> Clone for TransitiveRelation<T> {
+ fn clone(&self) -> Self {
TransitiveRelation {
- elements: Default::default(),
- edges: Default::default(),
- closure: Default::default(),
+ builder: Frozen::freeze(self.builder.deref().clone()),
+ closure: Frozen::freeze(self.closure.deref().clone()),
}
}
}
+// HACK(eddyb) manual impl avoids `Default` bound on `T`.
+impl<T: Eq + Hash> Default for TransitiveRelationBuilder<T> {
+ fn default() -> Self {
+ TransitiveRelationBuilder { elements: Default::default(), edges: Default::default() }
+ }
+}
+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug)]
struct Index(usize);
@@ -49,7 +61,7 @@ struct Edge {
target: Index,
}
-impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
+impl<T: Eq + Hash + Copy> TransitiveRelationBuilder<T> {
pub fn is_empty(&self) -> bool {
self.edges.is_empty()
}
@@ -63,23 +75,19 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
}
fn add_index(&mut self, a: T) -> Index {
- let (index, added) = self.elements.insert_full(a);
- if added {
- // if we changed the dimensions, clear the cache
- *self.closure.get_mut() = None;
- }
+ let (index, _added) = self.elements.insert_full(a);
Index(index)
}
/// Applies the (partial) function to each edge and returns a new
- /// relation. If `f` returns `None` for any end-point, returns
- /// `None`.
- pub fn maybe_map<F, U>(&self, mut f: F) -> Option<TransitiveRelation<U>>
+ /// relation builder. If `f` returns `None` for any end-point,
+ /// returns `None`.
+ pub fn maybe_map<F, U>(&self, mut f: F) -> Option<TransitiveRelationBuilder<U>>
where
F: FnMut(T) -> Option<U>,
U: Clone + Debug + Eq + Hash + Copy,
{
- let mut result = TransitiveRelation::default();
+ let mut result = TransitiveRelationBuilder::default();
for edge in &self.edges {
result.add(f(self.elements[edge.source.0])?, f(self.elements[edge.target.0])?);
}
@@ -93,10 +101,38 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
let edge = Edge { source: a, target: b };
if !self.edges.contains(&edge) {
self.edges.push(edge);
+ }
+ }
+
+ /// Compute the transitive closure derived from the edges, and converted to
+ /// the final result. After this, all elements will be immutable to maintain
+ /// the correctness of the result.
+ pub fn freeze(self) -> TransitiveRelation<T> {
+ let mut matrix = BitMatrix::new(self.elements.len(), self.elements.len());
+ let mut changed = true;
+ while changed {
+ changed = false;
+ for edge in &self.edges {
+ // add an edge from S -> T
+ changed |= matrix.insert(edge.source.0, edge.target.0);
- // added an edge, clear the cache
- *self.closure.get_mut() = None;
+ // add all outgoing edges from T into S
+ changed |= matrix.union_rows(edge.target.0, edge.source.0);
+ }
}
+ TransitiveRelation { builder: Frozen::freeze(self), closure: Frozen::freeze(matrix) }
+ }
+}
+
+impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
+ /// Applies the (partial) function to each edge and returns a new
+ /// relation including transitive closures.
+ pub fn maybe_map<F, U>(&self, f: F) -> Option<TransitiveRelation<U>>
+ where
+ F: FnMut(T) -> Option<U>,
+ U: Clone + Debug + Eq + Hash + Copy,
+ {
+ Some(self.builder.maybe_map(f)?.freeze())
}
/// Checks whether `a < target` (transitively)
@@ -322,30 +358,7 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
where
OP: FnOnce(&BitMatrix<usize, usize>) -> R,
{
- let mut closure_cell = self.closure.borrow_mut();
- let mut closure = closure_cell.take();
- if closure.is_none() {
- closure = Some(self.compute_closure());
- }
- let result = op(closure.as_ref().unwrap());
- *closure_cell = closure;
- result
- }
-
- fn compute_closure(&self) -> BitMatrix<usize, usize> {
- let mut matrix = BitMatrix::new(self.elements.len(), self.elements.len());
- let mut changed = true;
- while changed {
- changed = false;
- for edge in &self.edges {
- // add an edge from S -> T
- changed |= matrix.insert(edge.source.0, edge.target.0);
-
- // add all outgoing edges from T into S
- changed |= matrix.union_rows(edge.target.0, edge.source.0);
- }
- }
- matrix
+ op(&self.closure)
}
/// Lists all the base edges in the graph: the initial _non-transitive_ set of element
diff --git a/compiler/rustc_data_structures/src/transitive_relation/tests.rs b/compiler/rustc_data_structures/src/transitive_relation/tests.rs
index e1f4c7ee0..e756c546e 100644
--- a/compiler/rustc_data_structures/src/transitive_relation/tests.rs
+++ b/compiler/rustc_data_structures/src/transitive_relation/tests.rs
@@ -10,9 +10,10 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
#[test]
fn test_one_step() {
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "b");
relation.add("a", "c");
+ let relation = relation.freeze();
assert!(relation.contains("a", "c"));
assert!(relation.contains("a", "b"));
assert!(!relation.contains("b", "a"));
@@ -21,7 +22,7 @@ fn test_one_step() {
#[test]
fn test_many_steps() {
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "b");
relation.add("a", "c");
relation.add("a", "f");
@@ -31,6 +32,7 @@ fn test_many_steps() {
relation.add("b", "e");
relation.add("e", "g");
+ let relation = relation.freeze();
assert!(relation.contains("a", "b"));
assert!(relation.contains("a", "c"));
@@ -51,9 +53,10 @@ fn mubs_triangle() {
// ^
// |
// b
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "tcx");
relation.add("b", "tcx");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["tcx"]);
assert_eq!(relation.parents("a"), vec!["tcx"]);
assert_eq!(relation.parents("b"), vec!["tcx"]);
@@ -72,7 +75,7 @@ fn mubs_best_choice1() {
// need the second pare down call to get the right result (after
// intersection, we have [1, 2], but 2 -> 1).
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("0", "1");
relation.add("0", "2");
@@ -80,6 +83,7 @@ fn mubs_best_choice1() {
relation.add("3", "1");
relation.add("3", "2");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["2"]);
assert_eq!(relation.parents("0"), vec!["2"]);
@@ -99,7 +103,7 @@ fn mubs_best_choice2() {
// Like the preceding test, but in this case intersection is [2,
// 1], and hence we rely on the first pare down call.
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("0", "1");
relation.add("0", "2");
@@ -107,6 +111,7 @@ fn mubs_best_choice2() {
relation.add("3", "1");
relation.add("3", "2");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["1"]);
assert_eq!(relation.parents("0"), vec!["1"]);
@@ -118,12 +123,13 @@ fn mubs_best_choice2() {
fn mubs_no_best_choice() {
// in this case, the intersection yields [1, 2], and the "pare
// down" calls find nothing to remove.
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("0", "1");
relation.add("0", "2");
relation.add("3", "1");
relation.add("3", "2");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["1", "2"]);
assert_eq!(relation.parents("0"), vec!["1", "2"]);
@@ -135,7 +141,7 @@ fn mubs_best_choice_scc() {
// in this case, 1 and 2 form a cycle; we pick arbitrarily (but
// consistently).
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("0", "1");
relation.add("0", "2");
@@ -144,6 +150,7 @@ fn mubs_best_choice_scc() {
relation.add("3", "1");
relation.add("3", "2");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["1"]);
assert_eq!(relation.parents("0"), vec!["1"]);
@@ -157,13 +164,14 @@ fn pdub_crisscross() {
// /\ |
// b -> b1 ---+
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "a1");
relation.add("a", "b1");
relation.add("b", "a1");
relation.add("b", "b1");
relation.add("a1", "x");
relation.add("b1", "x");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["a1", "b1"]);
assert_eq!(relation.postdom_upper_bound("a", "b"), Some("x"));
@@ -179,7 +187,7 @@ fn pdub_crisscross_more() {
// /\ /\ |
// b -> b1 -> b2 ---------+
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "a1");
relation.add("a", "b1");
relation.add("b", "a1");
@@ -194,6 +202,7 @@ fn pdub_crisscross_more() {
relation.add("a3", "x");
relation.add("b2", "x");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["a1", "b1"]);
assert_eq!(relation.minimal_upper_bounds("a1", "b1"), vec!["a2", "b2"]);
@@ -210,11 +219,12 @@ fn pdub_lub() {
// |
// b -> b1 ---+
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "a1");
relation.add("b", "b1");
relation.add("a1", "x");
relation.add("b1", "x");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["x"]);
assert_eq!(relation.postdom_upper_bound("a", "b"), Some("x"));
@@ -233,10 +243,11 @@ fn mubs_intermediate_node_on_one_side_only() {
// b
// "digraph { a -> c -> d; b -> d; }",
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "c");
relation.add("c", "d");
relation.add("b", "d");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["d"]);
}
@@ -252,12 +263,13 @@ fn mubs_scc_1() {
// b
// "digraph { a -> c -> d; d -> c; a -> d; b -> d; }",
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "c");
relation.add("c", "d");
relation.add("d", "c");
relation.add("a", "d");
relation.add("b", "d");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
}
@@ -272,12 +284,13 @@ fn mubs_scc_2() {
// +--- b
// "digraph { a -> c -> d; d -> c; b -> d; b -> c; }",
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "c");
relation.add("c", "d");
relation.add("d", "c");
relation.add("b", "d");
relation.add("b", "c");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
}
@@ -292,13 +305,14 @@ fn mubs_scc_3() {
// b ---+
// "digraph { a -> c -> d -> e -> c; b -> d; b -> e; }",
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "c");
relation.add("c", "d");
relation.add("d", "e");
relation.add("e", "c");
relation.add("b", "d");
relation.add("b", "e");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
}
@@ -314,13 +328,14 @@ fn mubs_scc_4() {
// b ---+
// "digraph { a -> c -> d -> e -> c; a -> d; b -> e; }"
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
relation.add("a", "c");
relation.add("c", "d");
relation.add("d", "e");
relation.add("e", "c");
relation.add("a", "d");
relation.add("b", "e");
+ let relation = relation.freeze();
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
}
@@ -352,10 +367,11 @@ fn parent() {
(1, /*->*/ 3),
];
- let mut relation = TransitiveRelation::default();
+ let mut relation = TransitiveRelationBuilder::default();
for (a, b) in pairs {
relation.add(a, b);
}
+ let relation = relation.freeze();
let p = relation.postdom_parent(3);
assert_eq!(p, Some(0));
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
index 08d5d4f34..d1d02ed73 100644
--- a/compiler/rustc_driver/Cargo.toml
+++ b/compiler/rustc_driver/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
crate-type = ["dylib"]
[dependencies]
-tracing = { version = "0.1.28" }
+tracing = { version = "0.1.35" }
serde_json = "1.0.59"
rustc_log = { path = "../rustc_log" }
rustc_middle = { path = "../rustc_middle" }
@@ -19,6 +19,7 @@ rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
+rustc_macros = { path = "../rustc_macros" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_parse = { path = "../rustc_parse" }
rustc_plugin_impl = { path = "../rustc_plugin_impl" }
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 53ae913f9..8fb950819 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -5,10 +5,12 @@
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
@@ -16,7 +18,7 @@ extern crate tracing;
pub extern crate rustc_plugin_impl as plugin;
use rustc_ast as ast;
-use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults};
+use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::SeqCst;
use rustc_errors::registry::{InvalidErrorCode, Registry};
@@ -56,6 +58,12 @@ use std::time::Instant;
pub mod args;
pub mod pretty;
+mod session_diagnostics;
+
+use crate::session_diagnostics::{
+ RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
+ RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead,
+};
/// Exit status code used for successful compilation and help output.
pub const EXIT_SUCCESS: i32 = 0;
@@ -581,18 +589,35 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp
sess.init_crate_types(collect_crate_types(sess, &[]));
let outputs = compiler.build_output_filenames(sess, &[]);
let rlink_data = fs::read(file).unwrap_or_else(|err| {
- sess.fatal(&format!("failed to read rlink file: {}", err));
+ sess.emit_fatal(RlinkUnableToRead { err });
});
let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) {
Ok(codegen) => codegen,
- Err(error) => {
- sess.fatal(&format!("Could not deserialize .rlink file: {error}"));
+ Err(err) => {
+ match err {
+ CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType),
+ CodegenErrors::EmptyVersionNumber => {
+ sess.emit_fatal(RLinkEmptyVersionNumber)
+ }
+ CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => {
+ sess.emit_fatal(RLinkEncodingVersionMismatch {
+ version_array,
+ rlink_version,
+ })
+ }
+ CodegenErrors::RustcVersionMismatch { rustc_version, current_version } => {
+ sess.emit_fatal(RLinkRustcVersionMismatch {
+ rustc_version,
+ current_version,
+ })
+ }
+ };
}
};
let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
abort_on_err(result, sess);
} else {
- sess.fatal("rlink must be a file")
+ sess.emit_fatal(RlinkNotAFile {})
}
Compilation::Stop
} else {
@@ -1070,7 +1095,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
Some(matches)
}
-fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<ast::Attribute>> {
+fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::AttrVec> {
match input {
Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess),
Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str(
@@ -1094,22 +1119,25 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
while let Some(arg) = args.next() {
if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
let content = if arg.len() == a.len() {
+ // A space-separated option, like `-C incremental=foo` or `--crate-type rlib`
match args.next() {
Some(arg) => arg.to_string(),
None => continue,
}
} else if arg.get(a.len()..a.len() + 1) == Some("=") {
+ // An equals option, like `--crate-type=rlib`
arg[a.len() + 1..].to_string()
} else {
+ // A non-space option, like `-Cincremental=foo`
arg[a.len()..].to_string()
};
- if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| content.starts_with(exc)) {
+ let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
+ if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
excluded_cargo_defaults = true;
} else {
result.push(a.to_string());
- match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| content.starts_with(*s))
- {
- Some(s) => result.push(s.to_string()),
+ match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
+ Some(s) => result.push(format!("{}=[REDACTED]", s)),
None => result.push(content),
}
}
@@ -1148,6 +1176,17 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
LazyLock::new(|| {
let hook = panic::take_hook();
panic::set_hook(Box::new(|info| {
+ // If the error was caused by a broken pipe then this is not a bug.
+ // Write the error and return immediately. See #98700.
+ #[cfg(windows)]
+ if let Some(msg) = info.payload().downcast_ref::<String>() {
+ if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)")
+ {
+ early_error_no_abort(ErrorOutputType::default(), &msg);
+ return;
+ }
+ };
+
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
(*DEFAULT_HOOK)(info);
diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs
index f66b1a297..2874fa0ca 100644
--- a/compiler/rustc_driver/src/pretty.rs
+++ b/compiler/rustc_driver/src/pretty.rs
@@ -1,5 +1,6 @@
//! The various pretty-printing routines.
+use crate::session_diagnostics::UnprettyDumpFail;
use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_errors::ErrorGuaranteed;
@@ -357,12 +358,15 @@ fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
(src, src_name)
}
-fn write_or_print(out: &str, ofile: Option<&Path>) {
+fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) {
match ofile {
None => print!("{}", out),
Some(p) => {
if let Err(e) = std::fs::write(p, out) {
- panic!("print-print failed to write {} due to {}", p.display(), e);
+ sess.emit_fatal(UnprettyDumpFail {
+ path: p.display().to_string(),
+ err: e.to_string(),
+ });
}
}
}
@@ -392,6 +396,7 @@ pub fn print_after_parsing(
annotation.pp_ann(),
false,
parse.edition,
+ &sess.parse_sess.attr_id_generator,
)
})
}
@@ -402,7 +407,7 @@ pub fn print_after_parsing(
_ => unreachable!(),
};
- write_or_print(&out, ofile);
+ write_or_print(&out, ofile, sess);
}
pub fn print_after_hir_lowering<'tcx>(
@@ -434,6 +439,7 @@ pub fn print_after_hir_lowering<'tcx>(
annotation.pp_ann(),
true,
parse.edition,
+ &sess.parse_sess.attr_id_generator,
)
})
}
@@ -468,7 +474,7 @@ pub fn print_after_hir_lowering<'tcx>(
_ => unreachable!(),
};
- write_or_print(&out, ofile);
+ write_or_print(&out, ofile, tcx.sess);
}
// In an ideal world, this would be a public function called by the driver after
@@ -512,7 +518,7 @@ fn print_with_analysis(
_ => unreachable!(),
};
- write_or_print(&out, ofile);
+ write_or_print(&out, ofile, tcx.sess);
Ok(())
}
diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs
new file mode 100644
index 000000000..e9696792d
--- /dev/null
+++ b/compiler/rustc_driver/src/session_diagnostics.rs
@@ -0,0 +1,40 @@
+use rustc_macros::SessionDiagnostic;
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::rlink_unable_to_read)]
+pub(crate) struct RlinkUnableToRead {
+ pub err: std::io::Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::rlink_wrong_file_type)]
+pub(crate) struct RLinkWrongFileType;
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::rlink_empty_version_number)]
+pub(crate) struct RLinkEmptyVersionNumber;
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::rlink_encoding_version_mismatch)]
+pub(crate) struct RLinkEncodingVersionMismatch {
+ pub version_array: String,
+ pub rlink_version: u32,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::rlink_rustc_version_mismatch)]
+pub(crate) struct RLinkRustcVersionMismatch<'a> {
+ pub rustc_version: String,
+ pub current_version: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::rlink_no_a_file)]
+pub(crate) struct RlinkNotAFile;
+
+#[derive(SessionDiagnostic)]
+#[diag(driver::unpretty_dump_fail)]
+pub(crate) struct UnprettyDumpFail {
+ pub path: String,
+ pub err: String,
+}
diff --git a/compiler/rustc_error_codes/src/error_codes/E0695.md b/compiler/rustc_error_codes/src/error_codes/E0695.md
index 5013e83ca..577f42ef3 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0695.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0695.md
@@ -3,7 +3,6 @@ A `break` statement without a label appeared inside a labeled block.
Erroneous code example:
```compile_fail,E0695
-# #![feature(label_break_value)]
loop {
'a: {
break;
@@ -14,7 +13,6 @@ loop {
Make sure to always label the `break`:
```
-# #![feature(label_break_value)]
'l: loop {
'a: {
break 'l;
@@ -25,7 +23,6 @@ Make sure to always label the `break`:
Or if you want to `break` the labeled block:
```
-# #![feature(label_break_value)]
loop {
'a: {
break 'a;
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index f2432f616..bd424dd9d 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -1,4 +1,6 @@
#![deny(rustdoc::invalid_codeblock_attributes)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
//! This library is used to gather all error codes into one place,
//! the goal being to make their maintenance easier.
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl
new file mode 100644
index 000000000..c45e045b4
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl
@@ -0,0 +1,139 @@
+ast_lowering_generic_type_with_parentheses =
+ parenthesized type parameters may only be used with a `Fn` trait
+ .label = only `Fn` traits may use parentheses
+
+ast_lowering_use_angle_brackets = use angle brackets instead
+
+ast_lowering_invalid_abi =
+ invalid ABI: found `{$abi}`
+ .label = invalid ABI
+ .help = valid ABIs: {$valid_abis}
+
+ast_lowering_assoc_ty_parentheses =
+ parenthesized generic arguments cannot be used in associated type constraints
+
+ast_lowering_remove_parentheses = remove these parentheses
+
+ast_lowering_misplaced_impl_trait =
+ `impl Trait` only allowed in function and inherent method return types, not in {$position}
+
+ast_lowering_rustc_box_attribute_error =
+ #[rustc_box] requires precisely one argument and no other attributes are allowed
+
+ast_lowering_underscore_expr_lhs_assign =
+ in expressions, `_` can only be used on the left-hand side of an assignment
+ .label = `_` not allowed here
+
+ast_lowering_base_expression_double_dot =
+ base expression required after `..`
+ .label = add a base expression here
+
+ast_lowering_await_only_in_async_fn_and_blocks =
+ `await` is only allowed inside `async` functions and blocks
+ .label = only allowed inside `async` functions and blocks
+
+ast_lowering_this_not_async = this is not `async`
+
+ast_lowering_generator_too_many_parameters =
+ too many parameters for a generator (expected 0 or 1 parameters)
+
+ast_lowering_closure_cannot_be_static = closures cannot be static
+
+ast_lowering_async_non_move_closure_not_supported =
+ `async` non-`move` closures with parameters are not currently supported
+ .help = consider using `let` statements to manually capture variables by reference before entering an `async move` closure
+
+ast_lowering_functional_record_update_destructuring_assignment =
+ functional record updates are not allowed in destructuring assignments
+ .suggestion = consider removing the trailing pattern
+
+ast_lowering_async_generators_not_supported =
+ `async` generators are not yet supported
+
+ast_lowering_inline_asm_unsupported_target =
+ inline assembly is unsupported on this target
+
+ast_lowering_att_syntax_only_x86 =
+ the `att_syntax` option is only supported on x86
+
+ast_lowering_abi_specified_multiple_times =
+ `{$prev_name}` ABI specified multiple times
+ .label = previously specified here
+ .note = these ABIs are equivalent on the current target
+
+ast_lowering_clobber_abi_not_supported =
+ `clobber_abi` is not supported on this target
+
+ast_lowering_invalid_abi_clobber_abi =
+ invalid ABI for `clobber_abi`
+ .note = the following ABIs are supported on this target: {$supported_abis}
+
+ast_lowering_invalid_register =
+ invalid register `{$reg}`: {$error}
+
+ast_lowering_invalid_register_class =
+ invalid register class `{$reg_class}`: {$error}
+
+ast_lowering_invalid_asm_template_modifier_reg_class =
+ invalid asm template modifier for this register class
+
+ast_lowering_argument = argument
+
+ast_lowering_template_modifier = template modifier
+
+ast_lowering_support_modifiers =
+ the `{$class_name}` register class supports the following template modifiers: {$modifiers}
+
+ast_lowering_does_not_support_modifiers =
+ the `{$class_name}` register class does not support template modifiers
+
+ast_lowering_invalid_asm_template_modifier_const =
+ asm template modifiers are not allowed for `const` arguments
+
+ast_lowering_invalid_asm_template_modifier_sym =
+ asm template modifiers are not allowed for `sym` arguments
+
+ast_lowering_register_class_only_clobber =
+ register class `{$reg_class_name}` can only be used as a clobber, not as an input or output
+
+ast_lowering_register_conflict =
+ register `{$reg1_name}` conflicts with register `{$reg2_name}`
+ .help = use `lateout` instead of `out` to avoid conflict
+
+ast_lowering_register1 = register `{$reg1_name}`
+
+ast_lowering_register2 = register `{$reg2_name}`
+
+ast_lowering_sub_tuple_binding =
+ `{$ident_name} @` is not allowed in a {$ctx}
+ .label = this is only allowed in slice patterns
+ .help = remove this and bind each tuple field independently
+
+ast_lowering_sub_tuple_binding_suggestion = if you don't need to use the contents of {$ident}, discard the tuple's remaining fields
+
+ast_lowering_extra_double_dot =
+ `..` can only be used once per {$ctx} pattern
+ .label = can only be used once per {$ctx} pattern
+
+ast_lowering_previously_used_here = previously used here
+
+ast_lowering_misplaced_double_dot =
+ `..` patterns are not allowed here
+ .note = only allowed in tuple, tuple struct, and slice patterns
+
+ast_lowering_misplaced_relax_trait_bound =
+ `?Trait` bounds are only permitted at the point where a type parameter is declared
+
+ast_lowering_not_supported_for_lifetime_binder_async_closure =
+ `for<...>` binders on `async` closures are not currently supported
+
+ast_lowering_arbitrary_expression_in_pattern =
+ arbitrary expressions aren't allowed in patterns
+
+ast_lowering_inclusive_range_with_no_end = inclusive range with no end
+
+ast_lowering_trait_fn_async =
+ functions in traits cannot be declared `async`
+ .label = `async` because of this
+ .note = `async` trait functions are not currently supported
+ .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
new file mode 100644
index 000000000..e5cd1142b
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -0,0 +1,91 @@
+ast_passes_forbidden_let =
+ `let` expressions are not supported here
+ .note = only supported directly in conditions of `if` and `while` expressions
+ .not_supported_or = `||` operators are not supported in let chain expressions
+ .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
+
+ast_passes_forbidden_let_stable =
+ expected expression, found statement (`let`)
+ .note = variable declaration using `let` is a statement
+
+ast_passes_deprecated_where_clause_location =
+ where clause not allowed here
+
+ast_passes_forbidden_assoc_constraint =
+ associated type bounds are not allowed within structs, enums, or unions
+
+ast_passes_keyword_lifetime =
+ lifetimes cannot use keyword names
+
+ast_passes_invalid_label =
+ invalid label name `{$name}`
+
+ast_passes_invalid_visibility =
+ unnecessary visibility qualifier
+ .implied = `pub` not permitted here because it's implied
+ .individual_impl_items = place qualifiers on individual impl items instead
+ .individual_foreign_items = place qualifiers on individual foreign items instead
+
+ast_passes_trait_fn_const =
+ functions in traits cannot be declared const
+ .label = functions in traits cannot be const
+
+ast_passes_forbidden_lifetime_bound =
+ lifetime bounds cannot be used in this context
+
+ast_passes_forbidden_non_lifetime_param =
+ only lifetime parameters can be used in this context
+
+ast_passes_fn_param_too_many =
+ function can not have more than {$max_num_args} arguments
+
+ast_passes_fn_param_c_var_args_only =
+ C-variadic function must be declared with at least one named argument
+
+ast_passes_fn_param_c_var_args_not_last =
+ `...` must be the last argument of a C-variadic function
+
+ast_passes_fn_param_doc_comment =
+ documentation comments cannot be applied to function parameters
+ .label = doc comments are not allowed here
+
+ast_passes_fn_param_forbidden_attr =
+ allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
+
+ast_passes_fn_param_forbidden_self =
+ `self` parameter is only allowed in associated functions
+ .label = not semantically valid as function parameter
+ .note = associated functions are those in `impl` or `trait` definitions
+
+ast_passes_forbidden_default =
+ `default` is only allowed on items in trait impls
+ .label = `default` because of this
+
+ast_passes_assoc_const_without_body =
+ associated constant in `impl` without body
+ .suggestion = provide a definition for the constant
+
+ast_passes_assoc_fn_without_body =
+ associated function in `impl` without body
+ .suggestion = provide a definition for the function
+
+ast_passes_assoc_type_without_body =
+ associated type in `impl` without body
+ .suggestion = provide a definition for the type
+
+ast_passes_const_without_body =
+ free constant item without body
+ .suggestion = provide a definition for the constant
+
+ast_passes_static_without_body =
+ free static item without body
+ .suggestion = provide a definition for the static
+
+ast_passes_ty_alias_without_body =
+ free type alias without body
+ .suggestion = provide a definition for the type
+
+ast_passes_fn_without_body =
+ free function without a body
+ .suggestion = provide a definition for the function
+ .extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl
new file mode 100644
index 000000000..a7f8c993d
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl
@@ -0,0 +1,107 @@
+attr_expected_one_cfg_pattern =
+ expected 1 cfg-pattern
+
+attr_invalid_predicate =
+ invalid predicate `{$predicate}`
+
+attr_multiple_item =
+ multiple '{$item}' items
+
+attr_incorrect_meta_item =
+ incorrect meta item
+
+attr_unknown_meta_item =
+ unknown meta item '{$item}'
+ .label = expected one of {$expected}
+
+attr_missing_since =
+ missing 'since'
+
+attr_missing_note =
+ missing 'note'
+
+attr_multiple_stability_levels =
+ multiple stability levels
+
+attr_invalid_issue_string =
+ `issue` must be a non-zero numeric string or "none"
+ .must_not_be_zero = `issue` must not be "0", use "none" instead
+ .empty = cannot parse integer from empty string
+ .invalid_digit = invalid digit found in string
+ .pos_overflow = number too large to fit in target type
+ .neg_overflow = number too small to fit in target type
+
+attr_missing_feature =
+ missing 'feature'
+
+attr_non_ident_feature =
+ 'feature' is not an identifier
+
+attr_missing_issue =
+ missing 'issue'
+
+attr_incorrect_repr_format_packed_one_or_zero_arg =
+ incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
+
+attr_invalid_repr_hint_no_paren =
+ invalid representation hint: `{$name}` does not take a parenthesized argument list
+
+attr_invalid_repr_hint_no_value =
+ invalid representation hint: `{$name}` does not take a value
+
+attr_unsupported_literal_generic =
+ unsupported literal
+attr_unsupported_literal_cfg_string =
+ literal in `cfg` predicate value must be a string
+attr_unsupported_literal_deprecated_string =
+ literal in `deprecated` value must be a string
+attr_unsupported_literal_deprecated_kv_pair =
+ item in `deprecated` must be a key/value pair
+attr_unsupported_literal_suggestion =
+ consider removing the prefix
+
+attr_invalid_repr_align_need_arg =
+ invalid `repr(align)` attribute: `align` needs an argument
+ .suggestion = supply an argument here
+
+attr_invalid_repr_generic =
+ invalid `repr({$repr_arg})` attribute: {$error_part}
+
+attr_incorrect_repr_format_align_one_arg =
+ incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
+
+attr_incorrect_repr_format_generic =
+ incorrect `repr({$repr_arg})` attribute format
+ .suggestion = use parentheses instead
+
+attr_rustc_promotable_pairing =
+ `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute
+
+attr_rustc_allowed_unstable_pairing =
+ `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute
+
+attr_cfg_predicate_identifier =
+ `cfg` predicate key must be an identifier
+
+attr_deprecated_item_suggestion =
+ suggestions on deprecated items are unstable
+ .help = add `#![feature(deprecated_suggestion)]` to the crate root
+ .note = see #94785 for more details
+
+attr_expected_single_version_literal =
+ expected single version literal
+
+attr_expected_version_literal =
+ expected a version literal
+
+attr_expects_feature_list =
+ `{$name}` expects a list of feature names
+
+attr_expects_features =
+ `{$name}` expects feature names
+
+attr_soft_no_args =
+ `soft` should not have any arguments
+
+attr_unknown_version_literal =
+ unknown version literal format, assuming it refers to a future version
diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
index 645673ef4..67f2156f3 100644
--- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
@@ -1,18 +1,60 @@
-borrowck-move-unsized =
+borrowck_move_unsized =
cannot move a value of type `{$ty}`
.label = the size of `{$ty}` cannot be statically determined
-borrowck-higher-ranked-lifetime-error =
+borrowck_higher_ranked_lifetime_error =
higher-ranked lifetime error
-borrowck-could-not-prove =
+borrowck_could_not_prove =
could not prove `{$predicate}`
-borrowck-could-not-normalize =
+borrowck_could_not_normalize =
could not normalize `{$value}`
-borrowck-higher-ranked-subtype-error =
+borrowck_higher_ranked_subtype_error =
higher-ranked subtype error
-
-generic-does-not-live-long-enough =
- `{$kind}` does not live long enough \ No newline at end of file
+
+borrowck_generic_does_not_live_long_enough =
+ `{$kind}` does not live long enough
+
+borrowck_move_borrowed =
+ cannot move out of `{$desc}` beacause it is borrowed
+
+borrowck_var_does_not_need_mut =
+ variable does not need to be mutable
+ .suggestion = remove this `mut`
+
+borrowck_const_not_used_in_type_alias =
+ const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+
+borrowck_var_cannot_escape_closure =
+ captured variable cannot escape `FnMut` closure body
+ .note = `FnMut` closures only have access to their captured variables while they are executing...
+ .cannot_escape = ...therefore, they cannot allow references to captured variables to escape
+
+borrowck_var_here_defined = variable defined here
+
+borrowck_var_here_captured = variable captured here
+
+borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
+
+borrowck_returned_closure_escaped =
+ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+
+borrowck_returned_async_block_escaped =
+ returns an `async` block that contains a reference to a captured variable, which then escapes the closure body
+
+borrowck_returned_ref_escaped =
+ returns a reference to a captured variable which escapes the closure body
+
+borrowck_lifetime_constraints_error =
+ lifetime may not live long enough
+
+borrowck_returned_lifetime_wrong =
+ {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}`
+
+borrowck_returned_lifetime_short =
+ {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`
+
+borrowck_used_impl_require_static =
+ the used `impl` has a `'static` requirement
diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
index 1d3e33c81..4d088e27b 100644
--- a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
@@ -1,5 +1,5 @@
-builtin-macros-requires-cfg-pattern =
+builtin_macros_requires_cfg_pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
-builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
+builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
index 3f2ff8610..33bb116d6 100644
--- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
@@ -1,31 +1,83 @@
-const-eval-unstable-in-stable =
+const_eval_unstable_in_stable =
const-stable function cannot use `#[feature({$gate})]`
- .unstable-sugg = if it is not part of the public API, make this function unstably const
- .bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+ .unstable_sugg = if it is not part of the public API, make this function unstably const
+ .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
-const-eval-thread-local-access =
+const_eval_thread_local_access =
thread-local statics cannot be accessed at compile-time
-const-eval-static-access =
+const_eval_static_access =
{$kind}s cannot refer to statics
.help = consider extracting the value of the `static` to a `const`, and referring to that
- .teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
- .teach-help = To fix this, the value can be extracted to a `const` and then used.
+ .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
+ .teach_help = To fix this, the value can be extracted to a `const` and then used.
-const-eval-raw-ptr-to-int =
+const_eval_raw_ptr_to_int =
pointers cannot be cast to integers during const eval
.note = at compile-time, pointers do not have an integer value
.note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
-const-eval-raw-ptr-comparison =
+const_eval_raw_ptr_comparison =
pointers cannot be reliably compared during const eval
.note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
-const-eval-panic-non-str = argument to `panic!()` in a const context must have type `&str`
+const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
-const-eval-mut-deref =
+const_eval_mut_deref =
mutation through a reference is not allowed in {$kind}s
-const-eval-transient-mut-borrow = mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s
-const-eval-transient-mut-borrow-raw = raw mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s
+
+const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
+
+const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s
+
+const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
+
+const_eval_unallowed_mutable_refs =
+ mutable references are not allowed in the final value of {$kind}s
+ .teach_note =
+ References in statics and constants may only refer to immutable values.\n\n
+ Statics are shared everywhere, and if they refer to mutable data one might violate memory
+ safety since holding multiple mutable references to shared data is not allowed.\n\n
+ If you really want global mutable state, try using static mut or a global UnsafeCell.
+
+const_eval_unallowed_mutable_refs_raw =
+ raw mutable references are not allowed in the final value of {$kind}s
+ .teach_note =
+ References in statics and constants may only refer to immutable values.\n\n
+ Statics are shared everywhere, and if they refer to mutable data one might violate memory
+ safety since holding multiple mutable references to shared data is not allowed.\n\n
+ If you really want global mutable state, try using static mut or a global UnsafeCell.
+
+const_eval_non_const_fmt_macro_call =
+ cannot call non-const formatting macro in {$kind}s
+
+const_eval_non_const_fn_call =
+ cannot call non-const fn `{$def_path_str}` in {$kind}s
+
+const_eval_unallowed_op_in_const_context =
+ {$msg}
+
+const_eval_unallowed_heap_allocations =
+ allocations are not allowed in {$kind}s
+ .label = allocation not allowed in {$kind}s
+ .teach_note =
+ The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
+
+const_eval_unallowed_inline_asm =
+ inline assembly is not allowed in {$kind}s
+
+const_eval_interior_mutable_data_refer =
+ {$kind}s cannot refer to interior mutable data
+ .label = this borrow of an interior mutable value may end up in the final value
+ .help = to fix this, the value can be extracted to a separate `static` item and then referenced
+ .teach_note =
+ A constant containing interior mutable data behind a reference can allow you to modify that data.
+ This would make multiple uses of a constant to be able to see different values and allow circumventing
+ the `Send` and `Sync` requirements for shared mutable data, which is unsound.
+
+const_eval_interior_mutability_borrow =
+ cannot borrow here, since the borrowed element may contain interior mutability
diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_error_messages/locales/en-US/driver.ftl
new file mode 100644
index 000000000..8ad198c86
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/driver.ftl
@@ -0,0 +1,13 @@
+driver_rlink_unable_to_read = failed to read rlink file: `{$err}`
+
+driver_rlink_wrong_file_type = The input does not look like a .rlink file
+
+driver_rlink_empty_version_number = The input does not contain version number
+
+driver_rlink_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}`
+
+driver_rlink_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}`
+
+driver_rlink_no_a_file = rlink must be a file
+
+driver_unpretty_dump_fail = pretty-print failed to write `{$path}` due to error `{$err}`
diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_error_messages/locales/en-US/expand.ftl
index 8d506a3ea..572059115 100644
--- a/compiler/rustc_error_messages/locales/en-US/expand.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/expand.ftl
@@ -1,5 +1,22 @@
-expand-explain-doc-comment-outer =
+expand_explain_doc_comment_outer =
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
-expand-explain-doc-comment-inner =
+expand_explain_doc_comment_inner =
inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
+
+expand_expr_repeat_no_syntax_vars =
+ attempted to repeat an expression containing no syntax variables matched as repeating at this depth
+
+expand_must_repeat_once =
+ this must repeat at least once
+
+expand_count_repetition_misplaced =
+ `count` can not be placed inside the inner-most repetition
+
+expand_meta_var_expr_unrecognized_var =
+ variable `{$key}` is not recognized in meta-variable expression
+
+expand_var_still_repeating =
+ variable '{$ident}' is still repeating at this depth
+
+expand_meta_var_dif_seq_matchers = {$msg}
diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl
new file mode 100644
index 000000000..65371a285
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl
@@ -0,0 +1,171 @@
+infer_opaque_hidden_type =
+ opaque type's hidden type cannot be another opaque type from the same scope
+ .label = one of the two opaque types used here has to be outside its defining scope
+ .opaque_type = opaque type whose hidden type is being assigned
+ .hidden_type = opaque type being used as hidden type
+
+infer_type_annotations_needed = {$source_kind ->
+ [closure] type annotations needed for the closure `{$source_name}`
+ [normal] type annotations needed for `{$source_name}`
+ *[other] type annotations needed
+}
+ .label = type must be known at this point
+
+infer_label_bad = {$bad_kind ->
+ *[other] cannot infer type
+ [more_info] cannot infer {$prefix_kind ->
+ *[type] type for {$prefix}
+ [const_with_param] the value of const parameter
+ [const] the value of the constant
+ } `{$name}`{$has_parent ->
+ [true] {" "}declared on the {$parent_prefix} `{$parent_name}`
+ *[false] {""}
+ }
+}
+
+infer_source_kind_subdiag_let = {$kind ->
+ [with_pattern] consider giving `{$name}` an explicit type
+ [closure] consider giving this closure parameter an explicit type
+ *[other] consider giving this pattern a type
+}{$x_kind ->
+ [has_name] , where the {$prefix_kind ->
+ *[type] type for {$prefix}
+ [const_with_param] the value of const parameter
+ [const] the value of the constant
+ } `{$arg_name}` is specified
+ [underscore] , where the placeholders `_` are specified
+ *[empty] {""}
+}
+
+infer_source_kind_subdiag_generic_label =
+ cannot infer {$is_type ->
+ [true] type
+ *[false] the value
+ } of the {$is_type ->
+ [true] type
+ *[false] const
+ } {$parent_exists ->
+ [true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}`
+ *[false] parameter {$param_name}
+ }
+
+infer_source_kind_subdiag_generic_suggestion =
+ consider specifying the generic {$arg_count ->
+ [one] argument
+ *[other] arguments
+ }
+
+infer_source_kind_fully_qualified =
+ try using a fully qualified path to specify the expected types
+
+infer_source_kind_closure_return =
+ try giving this closure an explicit return type
+
+# generator_kind may need to be translated
+infer_need_type_info_in_generator =
+ type inside {$generator_kind ->
+ [async_block] `async` block
+ [async_closure] `async` closure
+ [async_fn] `async fn` body
+ *[generator] generator
+ } must be known in this context
+
+
+infer_subtype = ...so that the {$requirement ->
+ [method_compat] method type is compatible with trait
+ [type_compat] associated type is compatible with trait
+ [const_compat] const is compatible with trait
+ [expr_assignable] expression is assignable
+ [if_else_different] `if` and `else` have incompatible types
+ [no_else] `if` missing an `else` returns `()`
+ [fn_main_correct_type] `main` function has the correct type
+ [fn_start_correct_type] #[start]` function has the correct type
+ [intristic_correct_type] intrinsic has the correct type
+ [method_correct_type] method receiver has the correct type
+ *[other] types are compatible
+}
+infer_subtype_2 = ...so that {$requirement ->
+ [method_compat] method type is compatible with trait
+ [type_compat] associated type is compatible with trait
+ [const_compat] const is compatible with trait
+ [expr_assignable] expression is assignable
+ [if_else_different] `if` and `else` have incompatible types
+ [no_else] `if` missing an `else` returns `()`
+ [fn_main_correct_type] `main` function has the correct type
+ [fn_start_correct_type] #[start]` function has the correct type
+ [intristic_correct_type] intrinsic has the correct type
+ [method_correct_type] method receiver has the correct type
+ *[other] types are compatible
+}
+
+infer_reborrow = ...so that reference does not outlive borrowed content
+infer_reborrow_upvar = ...so that closure can access `{$name}`
+infer_relate_object_bound = ...so that it can be closed over into an object
+infer_data_borrowed = ...so that the type `{$name}` is not borrowed for too long
+infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
+infer_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
+ [true] ...
+ *[false] {""}
+}
+infer_relate_param_bound_2 = ...that is required by this bound
+infer_relate_region_param_bound = ...so that the declared lifetime parameter bounds are satisfied
+infer_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait
+infer_ascribe_user_type_prove_predicate = ...so that the where clause holds
+
+infer_nothing = {""}
+
+infer_lifetime_mismatch = lifetime mismatch
+
+infer_declared_different = this parameter and the return type are declared with different lifetimes...
+infer_data_returned = ...but data{$label_var1_exists ->
+ [true] {" "}from `{$label_var1}`
+ *[false] {""}
+} is returned here
+
+infer_data_lifetime_flow = ...but data with one lifetime flows into the other here
+infer_declared_multiple = this type is declared with multiple lifetimes...
+infer_types_declared_different = these two types are declared with different lifetimes...
+infer_data_flows = ...but data{$label_var1_exists ->
+ [true] -> {" "}from `{$label_var1}`
+ *[false] -> {""}
+} flows{$label_var2_exists ->
+ [true] -> {" "}into `{$label_var2}`
+ *[false] -> {""}
+} here
+
+infer_lifetime_param_suggestion = consider introducing a named lifetime parameter{$is_impl ->
+ [true] {" "}and update trait if needed
+ *[false] {""}
+}
+infer_lifetime_param_suggestion_elided = each elided lifetime in input position becomes a distinct lifetime
+
+infer_region_explanation = {$pref_kind ->
+ *[should_not_happen] [{$pref_kind}]
+ [empty] {""}
+}{$pref_kind ->
+ [empty] {""}
+ *[other] {" "}
+}{$desc_kind ->
+ *[should_not_happen] [{$desc_kind}]
+ [restatic] the static lifetime
+ [reempty] the empty lifetime
+ [reemptyuni] the empty lifetime in universe {$desc_arg}
+ [revar] lifetime {$desc_arg}
+
+ [as_defined] the lifetime `{$desc_arg}` as defined here
+ [as_defined_anon] the anonymous lifetime as defined here
+ [defined_here] the anonymous lifetime defined here
+ [anon_num_here] the anonymous lifetime #{$desc_num_arg} defined here
+ [defined_here_reg] the lifetime `{$desc_arg}` as defined here
+}{$suff_kind ->
+ *[should_not_happen] [{$suff_kind}]
+ [empty]{""}
+ [continues] ...
+}
+
+infer_mismatched_static_lifetime = incompatible lifetime on type
+infer_msl_impl_note = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+infer_msl_introduces_static = introduces a `'static` lifetime requirement
+infer_msl_unmet_req = because this has an unmet lifetime requirement
+infer_msl_trait_note = this has an implicit `'static` lifetime requirement
+infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement
diff --git a/compiler/rustc_error_messages/locales/en-US/interface.ftl b/compiler/rustc_error_messages/locales/en-US/interface.ftl
new file mode 100644
index 000000000..bbcb8fc28
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/interface.ftl
@@ -0,0 +1,43 @@
+interface_ferris_identifier =
+ Ferris cannot be used as an identifier
+ .suggestion = try using their name instead
+
+interface_emoji_identifier =
+ identifiers cannot contain emoji: `{$ident}`
+
+interface_mixed_bin_crate =
+ cannot mix `bin` crate type with others
+
+interface_mixed_proc_macro_crate =
+ cannot mix `proc-macro` crate type with others
+
+interface_proc_macro_doc_without_arg =
+ Trying to document proc macro crate without passing '--crate-type proc-macro to rustdoc
+ .warn = The generated documentation may be incorrect
+
+interface_error_writing_dependencies =
+ error writing dependencies to `{$path}`: {$error}
+
+interface_input_file_would_be_overwritten =
+ the input file "{$path}" would be overwritten by the generated executable
+
+interface_generated_file_conflicts_with_directory =
+ the generated executable for the input file "{$input_path}" conflicts with the existing directory "{$dir_path}"
+
+interface_temps_dir_error =
+ failed to find or create the directory specified by `--temps-dir`
+
+interface_out_dir_error =
+ failed to find or create the directory specified by `--out-dir`
+
+interface_cant_emit_mir =
+ could not emit MIR: {$error}
+
+interface_rustc_error_fatal =
+ fatal error triggered by #[rustc_error]
+
+interface_rustc_error_unexpected_annotation =
+ unexpected annotation used with `#[rustc_error(...)]!
+
+interface_failed_writing_file =
+ failed to write file {$path}: {$error}"
diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl
index 55e96e58e..7f9918e4f 100644
--- a/compiler/rustc_error_messages/locales/en-US/lint.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl
@@ -1,22 +1,22 @@
-lint-array-into-iter =
+lint_array_into_iter =
this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <{$target} as IntoIterator>::into_iter in Rust 2021
- .use-iter-suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
- .remove-into-iter-suggestion = or remove `.into_iter()` to iterate by value
- .use-explicit-into-iter-suggestion =
+ .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ .remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
+ .use_explicit_into_iter_suggestion =
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
-lint-enum-intrinsics-mem-discriminant =
+lint_enum_intrinsics_mem_discriminant =
the return value of `mem::discriminant` is unspecified when called with a non-enum type
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
-lint-enum-intrinsics-mem-variant =
+lint_enum_intrinsics_mem_variant =
the return value of `mem::variant_count` is unspecified when called with a non-enum type
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
-lint-expectation = this lint expectation is unfulfilled
+lint_expectation = this lint expectation is unfulfilled
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
-lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of text present in {$label}
+lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label}
.label = this {$label} contains {$count ->
[one] an invisible
*[other] invisible
@@ -25,68 +25,68 @@ lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of
*[other] codepoints
}
.note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
- .suggestion-remove = if their presence wasn't intentional, you can remove them
- .suggestion-escape = if you want to keep them but make them visible in your source code, you can escape them
- .no-suggestion-note-escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
+ .suggestion_remove = if their presence wasn't intentional, you can remove them
+ .suggestion_escape = if you want to keep them but make them visible in your source code, you can escape them
+ .no_suggestion_note_escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
-lint-default-hash-types = prefer `{$preferred}` over `{$used}`, it has better performance
+lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
.note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
-lint-query-instability = using `{$query}` can result in unstable query results
+lint_query_instability = using `{$query}` can result in unstable query results
.note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
-lint-tykind-kind = usage of `ty::TyKind::<kind>`
+lint_tykind_kind = usage of `ty::TyKind::<kind>`
.suggestion = try using `ty::<kind>` directly
-lint-tykind = usage of `ty::TyKind`
+lint_tykind = usage of `ty::TyKind`
.help = try using `Ty` instead
-lint-ty-qualified = usage of qualified `ty::{$ty}`
+lint_ty_qualified = usage of qualified `ty::{$ty}`
.suggestion = try importing it and using it unqualified
-lint-lintpass-by-hand = implementing `LintPass` by hand
+lint_lintpass_by_hand = implementing `LintPass` by hand
.help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
-lint-non-existant-doc-keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
+lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
.help = only existing keywords are allowed in core/std
-lint-diag-out-of-impl =
+lint_diag_out_of_impl =
diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
-lint-untranslatable-diag = diagnostics should be created using translatable messages
+lint_untranslatable_diag = diagnostics should be created using translatable messages
-lint-cstring-ptr = getting the inner pointer of a temporary `CString`
- .as-ptr-label = this pointer will be invalid
- .unwrap-label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
+lint_cstring_ptr = getting the inner pointer of a temporary `CString`
+ .as_ptr_label = this pointer will be invalid
+ .unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
.note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
.help = for more information, see https://doc.rust-lang.org/reference/destructors.html
-lint-identifier-non-ascii-char = identifier contains non-ASCII characters
+lint_identifier_non_ascii_char = identifier contains non-ASCII characters
-lint-identifier-uncommon-codepoints = identifier contains uncommon Unicode codepoints
+lint_identifier_uncommon_codepoints = identifier contains uncommon Unicode codepoints
-lint-confusable-identifier-pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
+lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
.label = this is where the previous identifier occurred
-lint-mixed-script-confusables =
+lint_mixed_script_confusables =
the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
- .includes-note = the usage includes {$includes}
+ .includes_note = the usage includes {$includes}
.note = please recheck to make sure their usages are indeed what you want
-lint-non-fmt-panic = panic message is not a string literal
+lint_non_fmt_panic = panic message is not a string literal
.note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
- .more-info-note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
- .supports-fmt-note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
- .supports-fmt-suggestion = remove the `format!(..)` macro call
- .display-suggestion = add a "{"{"}{"}"}" format string to `Display` the message
- .debug-suggestion =
+ .more_info_note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ .supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
+ .supports_fmt_suggestion = remove the `format!(..)` macro call
+ .display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message
+ .debug_suggestion =
add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}`
- .panic-suggestion = {$already_suggested ->
+ .panic_suggestion = {$already_suggested ->
[true] or use
*[false] use
} std::panic::panic_any instead
-lint-non-fmt-panic-unused =
+lint_non_fmt_panic_unused =
panic message contains {$count ->
[one] an unused
*[other] unused
@@ -95,13 +95,13 @@ lint-non-fmt-panic-unused =
*[other] placeholders
}
.note = this message is not used as a format string when given without arguments, but will be in Rust 2021
- .add-args-suggestion = add the missing {$count ->
+ .add_args_suggestion = add the missing {$count ->
[one] argument
*[other] arguments
}
- .add-fmt-suggestion = or add a "{"{"}{"}"}" format string to use the message literally
+ .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
-lint-non-fmt-panic-braces =
+lint_non_fmt_panic_braces =
panic message contains {$count ->
[one] a brace
*[other] braces
@@ -109,30 +109,30 @@ lint-non-fmt-panic-braces =
.note = this message is not used as a format string, but will be in Rust 2021
.suggestion = add a "{"{"}{"}"}" format string to use the message literally
-lint-non-camel-case-type = {$sort} `{$name}` should have an upper camel case name
+lint_non_camel_case_type = {$sort} `{$name}` should have an upper camel case name
.suggestion = convert the identifier to upper camel case
.label = should have an UpperCamelCase name
-lint-non-snake-case = {$sort} `{$name}` should have a snake case name
- .rename-or-convert-suggestion = rename the identifier or convert it to a snake case raw identifier
- .cannot-convert-note = `{$sc}` cannot be used as a raw identifier
- .rename-suggestion = rename the identifier
- .convert-suggestion = convert the identifier to snake case
+lint_non_snake_case = {$sort} `{$name}` should have a snake case name
+ .rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
+ .cannot_convert_note = `{$sc}` cannot be used as a raw identifier
+ .rename_suggestion = rename the identifier
+ .convert_suggestion = convert the identifier to snake case
.help = convert the identifier to snake case: `{$sc}`
.label = should have a snake_case name
-lint-non-upper_case-global = {$sort} `{$name}` should have an upper case name
+lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name
.suggestion = convert the identifier to upper case
.label = should have an UPPER_CASE name
-lint-noop-method-call = call to `.{$method}()` on a reference in this situation does nothing
+lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing
.label = unnecessary method call
.note = the type `{$receiver_ty}` which `{$method}` is being called on is the same as the type returned from `{$method}`, so the method call does not do anything and can be removed
-lint-pass-by-value = passing `{$ty}` by reference
+lint_pass_by_value = passing `{$ty}` by reference
.suggestion = try passing by value
-lint-redundant-semicolons =
+lint_redundant_semicolons =
unnecessary trailing {$multiple ->
[true] semicolons
*[false] semicolon
@@ -142,254 +142,294 @@ lint-redundant-semicolons =
*[false] this semicolon
}
-lint-drop-trait-constraints =
+lint_drop_trait_constraints =
bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped
-lint-drop-glue =
+lint_drop_glue =
types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped
-lint-range-endpoint-out-of-range = range endpoint is out of range for `{$ty}`
+lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
.suggestion = use an inclusive range instead
-lint-overflowing-bin-hex = literal out of range for `{$ty}`
- .negative-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
- .negative-becomes-note = and the value `-{$lit}` will become `{$actually}{$ty}`
- .positive-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
+lint_overflowing_bin_hex = literal out of range for `{$ty}`
+ .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
+ .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
+ .positive_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
.suggestion = consider using the type `{$suggestion_ty}` instead
.help = consider using the type `{$suggestion_ty}` instead
-lint-overflowing-int = literal out of range for `{$ty}`
+lint_overflowing_int = literal out of range for `{$ty}`
.note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
.help = consider using the type `{$suggestion_ty}` instead
-lint-only-cast-u8-to-char = only `u8` can be cast into `char`
+lint_only_cast_u8_to_char = only `u8` can be cast into `char`
.suggestion = use a `char` literal instead
-lint-overflowing-uint = literal out of range for `{$ty}`
+lint_overflowing_uint = literal out of range for `{$ty}`
.note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
-lint-overflowing-literal = literal out of range for `{$ty}`
+lint_overflowing_literal = literal out of range for `{$ty}`
.note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`
-lint-unused-comparisons = comparison is useless due to type limits
+lint_unused_comparisons = comparison is useless due to type limits
-lint-improper-ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
+lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
.label = not FFI-safe
.note = the type is defined here
-lint-improper-ctypes-opaque = opaque types have no C equivalent
+lint_improper_ctypes_opaque = opaque types have no C equivalent
-lint-improper-ctypes-fnptr-reason = this function pointer has Rust-specific calling convention
-lint-improper-ctypes-fnptr-help = consider using an `extern fn(...) -> ...` function pointer instead
+lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
+lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
-lint-improper-ctypes-tuple-reason = tuples have unspecified layout
-lint-improper-ctypes-tuple-help = consider using a struct instead
+lint_improper_ctypes_tuple_reason = tuples have unspecified layout
+lint_improper_ctypes_tuple_help = consider using a struct instead
-lint-improper-ctypes-str-reason = string slices have no C equivalent
-lint-improper-ctypes-str-help = consider using `*const u8` and a length instead
+lint_improper_ctypes_str_reason = string slices have no C equivalent
+lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
-lint-improper-ctypes-dyn = trait objects have no C equivalent
+lint_improper_ctypes_dyn = trait objects have no C equivalent
-lint-improper-ctypes-slice-reason = slices have no C equivalent
-lint-improper-ctypes-slice-help = consider using a raw pointer instead
+lint_improper_ctypes_slice_reason = slices have no C equivalent
+lint_improper_ctypes_slice_help = consider using a raw pointer instead
-lint-improper-ctypes-128bit = 128-bit integers don't currently have a known stable ABI
+lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stable ABI
-lint-improper-ctypes-char-reason = the `char` type has no C equivalent
-lint-improper-ctypes-char-help = consider using `u32` or `libc::wchar_t` instead
+lint_improper_ctypes_char_reason = the `char` type has no C equivalent
+lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
-lint-improper-ctypes-non-exhaustive = this enum is non-exhaustive
-lint-improper-ctypes-non-exhaustive-variant = this enum has non-exhaustive variants
+lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
+lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
-lint-improper-ctypes-enum-repr-reason = enum has no representation hint
-lint-improper-ctypes-enum-repr-help =
+lint_improper_ctypes_enum_repr_reason = enum has no representation hint
+lint_improper_ctypes_enum_repr_help =
consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-lint-improper-ctypes-struct-fieldless-reason = this struct has no fields
-lint-improper-ctypes-struct-fieldless-help = consider adding a member to this struct
+lint_improper_ctypes_struct_fieldless_reason = this struct has no fields
+lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
-lint-improper-ctypes-union-fieldless-reason = this union has no fields
-lint-improper-ctypes-union-fieldless-help = consider adding a member to this union
+lint_improper_ctypes_union_fieldless_reason = this union has no fields
+lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
-lint-improper-ctypes-struct-non-exhaustive = this struct is non-exhaustive
-lint-improper-ctypes-union-non-exhaustive = this union is non-exhaustive
+lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive
+lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
-lint-improper-ctypes-struct-layout-reason = this struct has unspecified layout
-lint-improper-ctypes-struct-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout
+lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
-lint-improper-ctypes-union-layout-reason = this union has unspecified layout
-lint-improper-ctypes-union-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
+lint_improper_ctypes_union_layout_reason = this union has unspecified layout
+lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
-lint-improper-ctypes-box = box cannot be represented as a single pointer
+lint_improper_ctypes_box = box cannot be represented as a single pointer
-lint-improper-ctypes-enum-phantomdata = this enum contains a PhantomData field
+lint_improper_ctypes_enum_phantomdata = this enum contains a PhantomData field
-lint-improper-ctypes-struct-zst = this struct contains only zero-sized fields
+lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields
-lint-improper-ctypes-array-reason = passing raw arrays by value is not FFI-safe
-lint-improper-ctypes-array-help = consider passing a pointer to the array
+lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
+lint_improper_ctypes_array_help = consider passing a pointer to the array
-lint-improper-ctypes-only-phantomdata = composed only of `PhantomData`
+lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
-lint-variant-size-differences =
+lint_variant_size_differences =
enum variant is more than three times larger ({$largest} bytes) than the next largest
-lint-atomic-ordering-load = atomic loads cannot have `Release` or `AcqRel` ordering
+lint_atomic_ordering_load = atomic loads cannot have `Release` or `AcqRel` ordering
.help = consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
-lint-atomic-ordering-store = atomic stores cannot have `Acquire` or `AcqRel` ordering
+lint_atomic_ordering_store = atomic stores cannot have `Acquire` or `AcqRel` ordering
.help = consider using ordering modes `Release`, `SeqCst` or `Relaxed`
-lint-atomic-ordering-fence = memory fences cannot have `Relaxed` ordering
+lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering
.help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
-lint-atomic-ordering-invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
+lint_atomic_ordering_invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
.label = invalid failure ordering
.help = consider using `Acquire` or `Relaxed` failure ordering instead
-lint-unused-op = unused {$op} that must be used
+lint_unused_op = unused {$op} that must be used
.label = the {$op} produces a value
.suggestion = use `let _ = ...` to ignore the resulting value
-lint-unused-result = unused result of type `{$ty}`
+lint_unused_result = unused result of type `{$ty}`
-lint-unused-closure =
+lint_unused_closure =
unused {$pre}{$count ->
[one] closure
*[other] closures
}{$post} that must be used
.note = closures are lazy and do nothing unless called
-lint-unused-generator =
+lint_unused_generator =
unused {$pre}{$count ->
[one] generator
*[other] generator
}{$post} that must be used
.note = generators are lazy and do nothing unless resumed
-lint-unused-def = unused {$pre}`{$def}`{$post} that must be used
+lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
-lint-path-statement-drop = path statement drops value
+lint_path_statement_drop = path statement drops value
.suggestion = use `drop` to clarify the intent
-lint-path-statement-no-effect = path statement with no effect
+lint_path_statement_no_effect = path statement with no effect
-lint-unused-delim = unnecessary {$delim} around {$item}
+lint_unused_delim = unnecessary {$delim} around {$item}
.suggestion = remove these {$delim}
-lint-unused-import-braces = braces around {$node} is unnecessary
+lint_unused_import_braces = braces around {$node} is unnecessary
-lint-unused-allocation = unnecessary allocation, use `&` instead
-lint-unused-allocation-mut = unnecessary allocation, use `&mut` instead
+lint_unused_allocation = unnecessary allocation, use `&` instead
+lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead
-lint-builtin-while-true = denote infinite loops with `loop {"{"} ... {"}"}`
+lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
.suggestion = use `loop`
-lint-builtin-box-pointers = type uses owned (Box type) pointers: {$ty}
+lint_builtin_box_pointers = type uses owned (Box type) pointers: {$ty}
-lint-builtin-non-shorthand-field-patterns = the `{$ident}:` in this pattern is redundant
+lint_builtin_non_shorthand_field_patterns = the `{$ident}:` in this pattern is redundant
.suggestion = use shorthand field pattern
-lint-builtin-overridden-symbol-name =
+lint_builtin_overridden_symbol_name =
the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
-lint-builtin-overridden-symbol-section =
+lint_builtin_overridden_symbol_section =
the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
-lint-builtin-allow-internal-unsafe =
+lint_builtin_allow_internal_unsafe =
`allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
-lint-builtin-unsafe-block = usage of an `unsafe` block
+lint_builtin_unsafe_block = usage of an `unsafe` block
-lint-builtin-unsafe-trait = declaration of an `unsafe` trait
+lint_builtin_unsafe_trait = declaration of an `unsafe` trait
-lint-builtin-unsafe-impl = implementation of an `unsafe` trait
+lint_builtin_unsafe_impl = implementation of an `unsafe` trait
-lint-builtin-no-mangle-fn = declaration of a `no_mangle` function
-lint-builtin-export-name-fn = declaration of a function with `export_name`
-lint-builtin-link-section-fn = declaration of a function with `link_section`
+lint_builtin_no_mangle_fn = declaration of a `no_mangle` function
+lint_builtin_export_name_fn = declaration of a function with `export_name`
+lint_builtin_link_section_fn = declaration of a function with `link_section`
-lint-builtin-no-mangle-static = declaration of a `no_mangle` static
-lint-builtin-export-name-static = declaration of a static with `export_name`
-lint-builtin-link-section-static = declaration of a static with `link_section`
+lint_builtin_no_mangle_static = declaration of a `no_mangle` static
+lint_builtin_export_name_static = declaration of a static with `export_name`
+lint_builtin_link_section_static = declaration of a static with `link_section`
-lint-builtin-no-mangle-method = declaration of a `no_mangle` method
-lint-builtin-export-name-method = declaration of a method with `export_name`
+lint_builtin_no_mangle_method = declaration of a `no_mangle` method
+lint_builtin_export_name_method = declaration of a method with `export_name`
-lint-builtin-decl-unsafe-fn = declaration of an `unsafe` function
-lint-builtin-decl-unsafe-method = declaration of an `unsafe` method
-lint-builtin-impl-unsafe-method = implementation of an `unsafe` method
+lint_builtin_decl_unsafe_fn = declaration of an `unsafe` function
+lint_builtin_decl_unsafe_method = declaration of an `unsafe` method
+lint_builtin_impl_unsafe_method = implementation of an `unsafe` method
-lint-builtin-missing-doc = missing documentation for {$article} {$desc}
+lint_builtin_missing_doc = missing documentation for {$article} {$desc}
-lint-builtin-missing-copy-impl = type could implement `Copy`; consider adding `impl Copy`
+lint_builtin_missing_copy_impl = type could implement `Copy`; consider adding `impl Copy`
-lint-builtin-missing-debug-impl =
+lint_builtin_missing_debug_impl =
type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation
-lint-builtin-anonymous-params = anonymous parameters are deprecated and will be removed in the next edition
+lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition
.suggestion = try naming the parameter or explicitly ignoring it
-lint-builtin-deprecated-attr-link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
-lint-builtin-deprecated-attr-used = use of deprecated attribute `{$name}`: no longer used.
-lint-builtin-deprecated-attr-default-suggestion = remove this attribute
+lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
+lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
+lint_builtin_deprecated_attr_default_suggestion = remove this attribute
-lint-builtin-unused-doc-comment = unused doc comment
+lint_builtin_unused_doc_comment = unused doc comment
.label = rustdoc does not generate documentation for {$kind}
- .plain-help = use `//` for a plain comment
- .block-help = use `/* */` for a plain comment
+ .plain_help = use `//` for a plain comment
+ .block_help = use `/* */` for a plain comment
-lint-builtin-no-mangle-generic = functions generic over types or consts must be mangled
+lint_builtin_no_mangle_generic = functions generic over types or consts must be mangled
.suggestion = remove this attribute
-lint-builtin-const-no-mangle = const items should never be `#[no_mangle]`
+lint_builtin_const_no_mangle = const items should never be `#[no_mangle]`
.suggestion = try a static value
-lint-builtin-mutable-transmutes =
+lint_builtin_mutable_transmutes =
transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
-lint-builtin-unstable-features = unstable feature
+lint_builtin_unstable_features = unstable feature
-lint-builtin-unreachable-pub = unreachable `pub` {$what}
+lint_builtin_unreachable_pub = unreachable `pub` {$what}
.suggestion = consider restricting its visibility
.help = or consider exporting it for use by other crates
-lint-builtin-type-alias-bounds-help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+lint_builtin_unexpected_cli_config_name = unexpected `{$name}` as condition name
+ .help = was set with `--cfg` but isn't in the `--check-cfg` expected names
-lint-builtin-type-alias-where-clause = where clauses are not enforced in type aliases
+lint_builtin_unexpected_cli_config_value = unexpected condition value `{$value}` for condition name `{$name}`
+ .help = was set with `--cfg` but isn't in the `--check-cfg` expected values
+
+lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+
+lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases
.suggestion = the clause will not be checked when the type alias is used, and should be removed
-lint-builtin-type-alias-generic-bounds = bounds on generic parameters are not enforced in type aliases
+lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases
.suggestion = the bound will not be checked when the type alias is used, and should be removed
-lint-builtin-trivial-bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
+lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
-lint-builtin-ellipsis-inclusive-range-patterns = `...` range patterns are deprecated
+lint_builtin_ellipsis_inclusive_range_patterns = `...` range patterns are deprecated
.suggestion = use `..=` for an inclusive range
-lint-builtin-unnameable-test-items = cannot test inner items
+lint_builtin_unnameable_test_items = cannot test inner items
-lint-builtin-keyword-idents = `{$kw}` is a keyword in the {$next} edition
+lint_builtin_keyword_idents = `{$kw}` is a keyword in the {$next} edition
.suggestion = you can use a raw identifier to stay compatible
-lint-builtin-explicit-outlives = outlives requirements can be inferred
+lint_builtin_explicit_outlives = outlives requirements can be inferred
.suggestion = remove {$count ->
[one] this bound
*[other] these bounds
}
-lint-builtin-incomplete-features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
+lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
.note = see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
.help = consider using `min_{$name}` instead, which is more stable and complete
-lint-builtin-clashing-extern-same-name = `{$this_fi}` redeclared with a different signature
- .previous-decl-label = `{$orig}` previously declared here
- .mismatch-label = this signature doesn't match the previous declaration
-lint-builtin-clashing-extern-diff-name = `{$this_fi}` redeclares `{$orig}` with a different signature
- .previous-decl-label = `{$orig}` previously declared here
- .mismatch-label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_same_name = `{$this_fi}` redeclared with a different signature
+ .previous_decl_label = `{$orig}` previously declared here
+ .mismatch_label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_diff_name = `{$this_fi}` redeclares `{$orig}` with a different signature
+ .previous_decl_label = `{$orig}` previously declared here
+ .mismatch_label = this signature doesn't match the previous declaration
-lint-builtin-deref-nullptr = dereferencing a null pointer
+lint_builtin_deref_nullptr = dereferencing a null pointer
.label = this code causes undefined behavior when executed
-lint-builtin-asm-labels = avoid using named labels in inline assembly
+lint_builtin_asm_labels = avoid using named labels in inline assembly
+
+lint_overruled_attribute = {$lint_level}({$lint_source}) incompatible with previous forbid
+ .label = overruled by previous forbid
+
+lint_default_source = `forbid` lint level is the default for {$id}
+
+lint_node_source = `forbid` level set here
+ .note = {$reason}
+
+lint_command_line_source = `forbid` lint level was set on command line
+
+lint_malformed_attribute = malformed lint attribute input
+
+lint_bad_attribute_argument = bad attribute argument
+
+lint_reason_must_be_string_literal = reason must be a string literal
+
+lint_reason_must_come_last = reason in lint attribute must come last
+
+lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`
+ .help = add `#![register_tool({$tool_name})]` to the crate root
+
+lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´
+
+lint_requested_level = requested on the command line with `{$level} {$lint_name}`
+
+lint_check_name_unknown = unknown lint: `{$lint_name}`
+ .help = did you mean: `{$suggestion}`
+
+lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}`
+
+lint_check_name_warning = {$msg}
+
+lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name}
diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
new file mode 100644
index 000000000..d27100c56
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
@@ -0,0 +1,275 @@
+metadata_rlib_required =
+ crate `{$crate_name}` required to be available in rlib format, but was not found in this form
+
+metadata_lib_required =
+ crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
+
+metadata_crate_dep_multiple =
+ cannot satisfy dependencies so `{$crate_name}` only shows up once
+ .help = having upstream crates all available in one format will likely make this go away
+
+metadata_two_panic_runtimes =
+ cannot link together two panic runtimes: {$prev_name} and {$cur_name}
+
+metadata_bad_panic_strategy =
+ the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`
+
+metadata_required_panic_strategy =
+ the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
+
+metadata_incompatible_panic_in_drop_strategy =
+ the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
+
+metadata_multiple_names_in_link =
+ multiple `name` arguments in a single `#[link]` attribute
+
+metadata_multiple_kinds_in_link =
+ multiple `kind` arguments in a single `#[link]` attribute
+
+metadata_link_name_form =
+ link name must be of the form `name = "string"`
+
+metadata_link_kind_form =
+ link kind must be of the form `kind = "string"`
+
+metadata_link_modifiers_form =
+ link modifiers must be of the form `modifiers = "string"`
+
+metadata_link_cfg_form =
+ link cfg must be of the form `cfg(/* predicate */)`
+
+metadata_wasm_import_form =
+ wasm import module must be of the form `wasm_import_module = "string"`
+
+metadata_empty_link_name =
+ link name must not be empty
+ .label = empty link name
+
+metadata_link_framework_apple =
+ link kind `framework` is only supported on Apple targets
+
+metadata_framework_only_windows =
+ link kind `raw-dylib` is only supported on Windows targets
+
+metadata_unknown_link_kind =
+ unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib
+ .label = unknown link kind
+
+metadata_multiple_link_modifiers =
+ multiple `modifiers` arguments in a single `#[link]` attribute
+
+metadata_multiple_cfgs =
+ multiple `cfg` arguments in a single `#[link]` attribute
+
+metadata_link_cfg_single_predicate =
+ link cfg must have a single predicate argument
+
+metadata_multiple_wasm_import =
+ multiple `wasm_import_module` arguments in a single `#[link]` attribute
+
+metadata_unexpected_link_arg =
+ unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
+
+metadata_invalid_link_modifier =
+ invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
+
+metadata_multiple_modifiers =
+ multiple `{$modifier}` modifiers in a single `modifiers` argument
+
+metadata_bundle_needs_static =
+ linking modifier `bundle` is only compatible with `static` linking kind
+
+metadata_whole_archive_needs_static =
+ linking modifier `whole-archive` is only compatible with `static` linking kind
+
+metadata_as_needed_compatibility =
+ linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
+
+metadata_unknown_link_modifier =
+ unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed
+
+metadata_incompatible_wasm_link =
+ `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
+
+metadata_link_requires_name =
+ `#[link]` attribute requires a `name = "string"` argument
+ .label = missing `name` argument
+
+metadata_raw_dylib_no_nul =
+ link name must not contain NUL characters if link kind is `raw-dylib`
+
+metadata_link_ordinal_raw_dylib =
+ `#[link_ordinal]` is only supported if link kind is `raw-dylib`
+
+metadata_lib_framework_apple =
+ library kind `framework` is only supported on Apple targets
+
+metadata_empty_renaming_target =
+ an empty renaming target was specified for library `{$lib_name}`
+
+metadata_renaming_no_link =
+ renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library
+
+metadata_multiple_renamings =
+ multiple renamings were specified for library `{$lib_name}`
+
+metadata_no_link_mod_override =
+ overriding linking modifiers from command line is not supported
+
+metadata_unsupported_abi_i686 =
+ ABI not supported by `#[link(kind = "raw-dylib")]` on i686
+
+metadata_unsupported_abi =
+ ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
+
+metadata_fail_create_file_encoder =
+ failed to create file encoder: {$err}
+
+metadata_fail_seek_file =
+ failed to seek the file: {$err}
+
+metadata_fail_write_file =
+ failed to write to the file: {$err}
+
+metadata_crate_not_panic_runtime =
+ the crate `{$crate_name}` is not a panic runtime
+
+metadata_no_panic_strategy =
+ the crate `{$crate_name}` does not have the panic strategy `{$strategy}`
+
+metadata_profiler_builtins_needs_core =
+ `profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
+
+metadata_not_profiler_runtime =
+ the crate `{$crate_name}` is not a profiler runtime
+
+metadata_no_multiple_global_alloc =
+ cannot define multiple global allocators
+ .label = cannot define a new global allocator
+
+metadata_prev_global_alloc =
+ previous global allocator defined here
+
+metadata_conflicting_global_alloc =
+ the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}
+
+metadata_global_alloc_required =
+ no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
+
+metadata_no_transitive_needs_dep =
+ the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`
+
+metadata_failed_write_error =
+ failed to write {$filename}: {$err}
+
+metadata_missing_native_library =
+ could not find native static library `{$libname}`, perhaps an -L flag is missing?
+
+metadata_failed_create_tempdir =
+ couldn't create a temp dir: {$err}
+
+metadata_failed_create_file =
+ failed to create the file {$filename}: {$err}
+
+metadata_failed_create_encoded_metadata =
+ failed to create encoded metadata from file: {$err}
+
+metadata_non_ascii_name =
+ cannot load a crate with a non-ascii name `{$crate_name}`
+
+metadata_extern_location_not_exist =
+ extern location for {$crate_name} does not exist: {$location}
+
+metadata_extern_location_not_file =
+ extern location for {$crate_name} is not a file: {$location}
+
+metadata_multiple_candidates =
+ multiple {$flavor} candidates for `{$crate_name}` found
+
+metadata_multiple_matching_crates =
+ multiple matching crates for `{$crate_name}`
+ .note = candidates:{$candidates}
+
+metadata_symbol_conflicts_current =
+ the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
+
+metadata_symbol_conflicts_others =
+ found two different crates with name `{$crate_name}` that are not distinguished by differing `-C metadata`. This will result in symbol conflicts between the two.
+
+metadata_stable_crate_id_collision =
+ found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values.
+
+metadata_dl_error =
+ {$err}
+
+metadata_newer_crate_version =
+ found possibly newer version of crate `{$crate_name}`{$add_info}
+ .note = perhaps that crate needs to be recompiled?
+
+metadata_found_crate_versions =
+ the following crate versions were found:{$found_crates}
+
+metadata_no_crate_with_triple =
+ couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info}
+
+metadata_found_staticlib =
+ found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}
+ .help = please recompile that crate using --crate-type lib
+
+metadata_incompatible_rustc =
+ found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
+ .help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)
+
+metadata_invalid_meta_files =
+ found invalid metadata files for crate `{$crate_name}`{$add_info}
+
+metadata_cannot_find_crate =
+ can't find crate for `{$crate_name}`{$add_info}
+
+metadata_no_dylib_plugin =
+ plugin `{$crate_name}` only found in rlib format, but must be available in dylib format
+
+metadata_target_not_installed =
+ the `{$locator_triple}` target may not be installed
+
+metadata_target_no_std_support =
+ the `{$locator_triple}` target may not support the standard library
+
+metadata_consider_downloading_target =
+ consider downloading the target with `rustup target add {$locator_triple}`
+
+metadata_std_required =
+ `std` is required by `{$current_crate}` because it does not declare `#![no_std]`
+
+metadata_consider_building_std =
+ consider building the standard library from source with `cargo build -Zbuild-std`
+
+metadata_compiler_missing_profiler =
+ the compiler may have been built without the profiler runtime
+
+metadata_install_missing_components =
+ maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`
+
+metadata_cant_find_crate =
+ can't find crate
+
+metadata_crate_location_unknown_type =
+ extern location for {$crate_name} is of an unknown type: {$path}
+
+metadata_lib_filename_form =
+ file name should be lib*.rlib or {dll_prefix}*.{dll_suffix}
+
+metadata_multiple_import_name_type =
+ multiple `import_name_type` arguments in a single `#[link]` attribute
+
+metadata_import_name_type_form =
+ import name type must be of the form `import_name_type = "string"`
+
+metadata_import_name_type_x86 =
+ import name type is only supported on x86
+
+metadata_unknown_import_name_type =
+ unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated
+
+metadata_import_name_type_raw =
+ import name type can only be used with link kind `raw-dylib`
diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl
new file mode 100644
index 000000000..ed8348864
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl
@@ -0,0 +1,17 @@
+middle_drop_check_overflow =
+ overflow while adding drop-check rules for {$ty}
+ .note = overflowed on {$overflow_ty}
+
+middle_opaque_hidden_type_mismatch =
+ concrete type differs from previous defining opaque type use
+ .label = expected `{$self_ty}`, got `{$other_ty}`
+
+middle_conflict_types =
+ this expression supplies two conflicting concrete types for the same opaque type
+
+middle_previous_use_here =
+ previous use here
+
+middle_limit_invalid =
+ `limit` must be a non-negative integer
+ .label = {$error_str}
diff --git a/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl b/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl
new file mode 100644
index 000000000..988541525
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl
@@ -0,0 +1,29 @@
+mir_dataflow_path_must_end_in_filename =
+ path must end in a filename
+
+mir_dataflow_unknown_formatter =
+ unknown formatter
+
+mir_dataflow_duplicate_values_for =
+ duplicate values for `{$name}`
+
+mir_dataflow_requires_an_argument =
+ `{$name}` requires an argument
+
+mir_dataflow_stop_after_dataflow_ended_compilation =
+ stop_after_dataflow ended compilation
+
+mir_dataflow_peek_must_be_place_or_ref_place =
+ rustc_peek: argument expression must be either `place` or `&place`
+
+mir_dataflow_peek_must_be_not_temporary =
+ dataflow::sanity_check cannot feed a non-temp to rustc_peek
+
+mir_dataflow_peek_bit_not_set =
+ rustc_peek: bit not set
+
+mir_dataflow_peek_argument_not_a_local =
+ rustc_peek: argument was not a local
+
+mir_dataflow_peek_argument_untracked =
+ rustc_peek: argument untracked
diff --git a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl b/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl
new file mode 100644
index 000000000..42c84fdd2
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl
@@ -0,0 +1,26 @@
+monomorphize_recursion_limit =
+ reached the recursion limit while instantiating `{$shrunk}`
+ .note = `{$def_path_str}` defined here
+
+monomorphize_written_to_path = the full type name has been written to '{$path}'
+
+monomorphize_type_length_limit = reached the type-length limit while instantiating `{$shrunk}`
+
+monomorphize_consider_type_length_limit =
+ consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate
+
+monomorphize_fatal_error = {$error_message}
+
+monomorphize_unknown_partition_strategy = unknown partitioning strategy
+
+monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined
+
+monomorphize_unused_generic_params = item has unused generic parameters
+
+monomorphize_large_assignments =
+ moving {$size} bytes
+ .label = value moved from here
+ .note = The current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
+
+monomorphize_requires_lang_item =
+ requires `{$lang_item}` lang_item
diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl
index 076b1b1ca..f74df3d97 100644
--- a/compiler/rustc_error_messages/locales/en-US/parser.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl
@@ -1,34 +1,158 @@
-parser-struct-literal-body-without-path =
+parser_struct_literal_body_without_path =
struct literal body without path
.suggestion = you might have forgotten to add the struct literal inside the block
-parser-maybe-report-ambiguous-plus =
+parser_maybe_report_ambiguous_plus =
ambiguous `+` in a type
.suggestion = use parentheses to disambiguate
-parser-maybe-recover-from-bad-type-plus =
+parser_maybe_recover_from_bad_type_plus =
expected a path on the left-hand side of `+`, not `{$ty}`
-parser-add-paren = try adding parentheses
+parser_add_paren = try adding parentheses
-parser-forgot-paren = perhaps you forgot parentheses?
+parser_forgot_paren = perhaps you forgot parentheses?
-parser-expect-path = expected a path
+parser_expect_path = expected a path
-parser-maybe-recover-from-bad-qpath-stage-2 =
+parser_maybe_recover_from_bad_qpath_stage_2 =
missing angle brackets in associated item path
.suggestion = try: `{$ty}`
-parser-incorrect-semicolon =
+parser_incorrect_semicolon =
expected item, found `;`
.suggestion = remove this semicolon
.help = {$name} declarations are not followed by a semicolon
-parser-incorrect-use-of-await =
+parser_incorrect_use_of_await =
incorrect use of `await`
- .parentheses-suggestion = `await` is not a method call, remove the parentheses
- .postfix-suggestion = `await` is a postfix operation
+ .parentheses_suggestion = `await` is not a method call, remove the parentheses
+ .postfix_suggestion = `await` is a postfix operation
-parser-in-in-typo =
+parser_in_in_typo =
expected iterable, found keyword `in`
.suggestion = remove the duplicated `in`
+
+parser_invalid_variable_declaration =
+ invalid variable declaration
+
+parser_switch_mut_let_order =
+ switch the order of `mut` and `let`
+parser_missing_let_before_mut = missing keyword
+parser_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
+parser_use_let_not_var = write `let` instead of `var` to introduce a new variable
+
+parser_invalid_comparison_operator = invalid comparison operator `{$invalid}`
+ .use_instead = `{$invalid}` is not a valid comparison operator, use `{$correct}`
+ .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering`
+
+parser_invalid_logical_operator = `{$incorrect}` is not a logical operator
+ .note = unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+ .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction
+ .use_pipe_pipe_for_disjunction = use `||` to perform logical disjunction
+
+parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
+ .suggestion = use `!` to perform bitwise not
+
+parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier
+ .suggestion = use `!` to perform logical negation
+
+parser_malformed_loop_label = malformed loop label
+ .suggestion = use the correct loop label format
+
+parser_lifetime_in_borrow_expression = borrow expressions cannot be annotated with lifetimes
+ .suggestion = remove the lifetime annotation
+ .label = annotated with lifetime here
+
+parser_field_expression_with_generic = field expressions cannot have generic arguments
+
+parser_macro_invocation_with_qualified_path = macros cannot use qualified paths
+
+parser_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label
+
+parser_require_colon_after_labeled_expression = labeled expression must be followed by `:`
+ .note = labels are used before loops and blocks, allowing e.g., `break 'label` to them
+ .label = the label
+ .suggestion = add `:` after the label
+
+parser_do_catch_syntax_removed = found removed `do catch` syntax
+ .note = following RFC #2388, the new non-placeholder syntax is `try`
+ .suggestion = replace with the new syntax
+
+parser_float_literal_requires_integer_part = float literals must have an integer part
+ .suggestion = must have an integer part
+
+parser_invalid_int_literal_width = invalid width `{$width}` for integer literal
+ .help = valid widths are 8, 16, 32, 64 and 128
+
+parser_invalid_num_literal_base_prefix = invalid base prefix for number literal
+ .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
+ .suggestion = try making the prefix lowercase
+
+parser_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal
+ .label = invalid suffix `{$suffix}`
+ .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+parser_invalid_float_literal_width = invalid width `{$width}` for float literal
+ .help = valid widths are 32 and 64
+
+parser_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
+ .label = invalid suffix `{$suffix}`
+ .help = valid suffixes are `f32` and `f64`
+
+parser_int_literal_too_large = integer literal is too large
+
+parser_missing_semicolon_before_array = expected `;`, found `[`
+ .suggestion = consider adding `;` here
+
+parser_invalid_block_macro_segment = cannot use a `block` macro fragment here
+ .label = the `block` fragment is within this context
+
+parser_if_expression_missing_then_block = this `if` expression is missing a block after the condition
+ .add_then_block = add a block here
+ .condition_possibly_unfinished = this binary operation is possibly unfinished
+
+parser_if_expression_missing_condition = missing condition for `if` expression
+ .condition_label = expected condition here
+ .block_label = if this block is the condition of the `if` expression, then it must be followed by another block
+
+parser_expected_expression_found_let = expected expression, found `let` statement
+
+parser_expected_else_block = expected `{"{"}`, found {$first_tok}
+ .label = expected an `if` or a block after this `else`
+ .suggestion = add an `if` if this is the condition of a chained `else if` statement
+
+parser_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches
+ .branch_label = the attributes are attached to this branch
+ .ctx_label = the branch belongs to this `{$ctx}`
+ .suggestion = remove the attributes
+
+parser_missing_in_in_for_loop = missing `in` in `for` loop
+ .use_in_not_of = try using `in` here instead
+ .add_in = try adding `in` here
+
+parser_missing_comma_after_match_arm = expected `,` following `match` arm
+ .suggestion = missing a comma here to end this `match` arm
+
+parser_catch_after_try = keyword `catch` cannot follow a `try` block
+ .help = try using `match` on the result of the `try` block instead
+
+parser_comma_after_base_struct = cannot use a comma after the base struct
+ .note = the base struct must always be the last field
+ .suggestion = remove this comma
+
+parser_eq_field_init = expected `:`, found `=`
+ .suggestion = replace equals symbol with a colon
+
+parser_dotdotdot = unexpected token: `...`
+ .suggest_exclusive_range = use `..` for an exclusive range
+ .suggest_inclusive_range = or `..=` for an inclusive range
+
+parser_left_arrow_operator = unexpected token: `<-`
+ .suggestion = if you meant to write a comparison against a negative value, add a space in between `<` and `-`
+
+parser_remove_let = expected pattern, found `let`
+ .suggestion = remove the unnecessary `let` keyword
+
+parser_use_eq_instead = unexpected `==`
+ .suggestion = try using `=` instead
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl
index b17eb9c2d..556a6452f 100644
--- a/compiler/rustc_error_messages/locales/en-US/passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl
@@ -1,178 +1,178 @@
--passes-previously-accepted =
+-passes_previously_accepted =
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
--passes-see-issue =
+-passes_see_issue =
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
-passes-outer-crate-level-attr =
+passes_outer_crate_level_attr =
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-passes-inner-crate-level-attr =
+passes_inner_crate_level_attr =
crate-level attribute should be in the root module
-passes-ignored-attr-with-macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
- .warn = {-passes-previously-accepted}
- .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr_with_macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
+ .warn = {-passes_previously_accepted}
+ .note = {-passes_see_issue(issue: "80564")}
-passes-ignored-attr = `#[{$sym}]` is ignored on struct fields and match arms
- .warn = {-passes-previously-accepted}
- .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr = `#[{$sym}]` is ignored on struct fields and match arms
+ .warn = {-passes_previously_accepted}
+ .note = {-passes_see_issue(issue: "80564")}
-passes-inline-ignored-function-prototype = `#[inline]` is ignored on function prototypes
+passes_inline_ignored_function_prototype = `#[inline]` is ignored on function prototypes
-passes-inline-ignored-constants = `#[inline]` is ignored on constants
- .warn = {-passes-previously-accepted}
- .note = {-passes-see-issue(issue: "65833")}
+passes_inline_ignored_constants = `#[inline]` is ignored on constants
+ .warn = {-passes_previously_accepted}
+ .note = {-passes_see_issue(issue: "65833")}
-passes-inline-not-fn-or-closure = attribute should be applied to function or closure
+passes_inline_not_fn_or_closure = attribute should be applied to function or closure
.label = not a function or closure
-passes-no-coverage-ignored-function-prototype = `#[no_coverage]` is ignored on function prototypes
+passes_no_coverage_ignored_function_prototype = `#[no_coverage]` is ignored on function prototypes
-passes-no-coverage-propagate =
+passes_no_coverage_propagate =
`#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
-passes-no-coverage-fn-defn = `#[no_coverage]` may only be applied to function definitions
+passes_no_coverage_fn_defn = `#[no_coverage]` may only be applied to function definitions
-passes-no-coverage-not-coverable = `#[no_coverage]` must be applied to coverable code
+passes_no_coverage_not_coverable = `#[no_coverage]` must be applied to coverable code
.label = not coverable code
-passes-should-be-applied-to-fn = attribute should be applied to a function definition
+passes_should_be_applied_to_fn = attribute should be applied to a function definition
.label = not a function definition
-passes-naked-tracked-caller = cannot use `#[track_caller]` with `#[naked]`
+passes_naked_tracked_caller = cannot use `#[track_caller]` with `#[naked]`
-passes-should-be-applied-to-struct-enum = attribute should be applied to a struct or enum
+passes_should_be_applied_to_struct_enum = attribute should be applied to a struct or enum
.label = not a struct or enum
-passes-should-be-applied-to-trait = attribute should be applied to a trait
+passes_should_be_applied_to_trait = attribute should be applied to a trait
.label = not a trait
-passes-target-feature-on-statement = {passes-should-be-applied-to-fn}
- .warn = {-passes-previously-accepted}
- .label = {passes-should-be-applied-to-fn.label}
+passes_target_feature_on_statement = {passes_should_be_applied_to_fn}
+ .warn = {-passes_previously_accepted}
+ .label = {passes_should_be_applied_to_fn.label}
-passes-should-be-applied-to-static = attribute should be applied to a static
+passes_should_be_applied_to_static = attribute should be applied to a static
.label = not a static
-passes-doc-expect-str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
+passes_doc_expect_str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
-passes-doc-alias-empty = {$attr_str} attribute cannot have empty value
+passes_doc_alias_empty = {$attr_str} attribute cannot have empty value
-passes-doc-alias-bad-char = {$char_} character isn't allowed in {$attr_str}
+passes_doc_alias_bad_char = {$char_} character isn't allowed in {$attr_str}
-passes-doc-alias-start-end = {$attr_str} cannot start or end with ' '
+passes_doc_alias_start_end = {$attr_str} cannot start or end with ' '
-passes-doc-alias-bad-location = {$attr_str} isn't allowed on {$location}
+passes_doc_alias_bad_location = {$attr_str} isn't allowed on {$location}
-passes-doc-alias-not-an-alias = {$attr_str} is the same as the item's name
+passes_doc_alias_not_an_alias = {$attr_str} is the same as the item's name
-passes-doc-alias-duplicated = doc alias is duplicated
+passes_doc_alias_duplicated = doc alias is duplicated
.label = first defined here
-passes-doc-alias-not-string-literal = `#[doc(alias("a"))]` expects string literals
+passes_doc_alias_not_string_literal = `#[doc(alias("a"))]` expects string literals
-passes-doc-alias-malformed =
+passes_doc_alias_malformed =
doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]`
-passes-doc-keyword-empty-mod = `#[doc(keyword = "...")]` should be used on empty modules
+passes_doc_keyword_empty_mod = `#[doc(keyword = "...")]` should be used on empty modules
-passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules
+passes_doc_keyword_not_mod = `#[doc(keyword = "...")]` should be used on modules
-passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier
+passes_doc_keyword_invalid_ident = `{$doc_keyword}` is not a valid identifier
-passes-doc-fake-variadic-not-valid =
+passes_doc_fake_variadic_not_valid =
`#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity
-passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks
+passes_doc_keyword_only_impl = `#[doc(keyword = "...")]` should be used on impl blocks
-passes-doc-inline-conflict-first = this attribute...
-passes-doc-inline-conflict-second = ...conflicts with this attribute
-passes-doc-inline-conflict = conflicting doc inlining attributes
+passes_doc_inline_conflict_first = this attribute...
+passes_doc_inline_conflict_second = ...conflicts with this attribute
+passes_doc_inline_conflict = conflicting doc inlining attributes
.help = remove one of the conflicting attributes
-passes-doc-inline-only-use = this attribute can only be applied to a `use` item
+passes_doc_inline_only_use = this attribute can only be applied to a `use` item
.label = only applicable on `use` items
- .not-a-use-item-label = not a `use` item
+ .not_a_use_item_label = not a `use` item
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
-passes-doc-attr-not-crate-level =
+passes_doc_attr_not_crate_level =
`#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
-passes-attr-crate-level = this attribute can only be applied at the crate level
+passes_attr_crate_level = this attribute can only be applied at the crate level
.suggestion = to apply to the crate, use an inner attribute
.help = to apply to the crate, use an inner attribute
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
-passes-doc-test-unknown = unknown `doc(test)` attribute `{$path}`
+passes_doc_test_unknown = unknown `doc(test)` attribute `{$path}`
-passes-doc-test-takes-list = `#[doc(test(...)]` takes a list of attributes
+passes_doc_test_takes_list = `#[doc(test(...)]` takes a list of attributes
-passes-doc-primitive = `doc(primitive)` should never have been stable
+passes_doc_primitive = `doc(primitive)` should never have been stable
-passes-doc-test-unknown-any = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_any = unknown `doc` attribute `{$path}`
-passes-doc-test-unknown-spotlight = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_spotlight = unknown `doc` attribute `{$path}`
.note = `doc(spotlight)` was renamed to `doc(notable_trait)`
.suggestion = use `notable_trait` instead
- .no-op-note = `doc(spotlight)` is now a no-op
+ .no_op_note = `doc(spotlight)` is now a no-op
-passes-doc-test-unknown-include = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_include = unknown `doc` attribute `{$path}`
.suggestion = use `doc = include_str!` instead
-passes-doc-invalid = invalid `doc` attribute
+passes_doc_invalid = invalid `doc` attribute
-passes-pass-by-value = `pass_by_value` attribute should be applied to a struct, enum or type alias
+passes_pass_by_value = `pass_by_value` attribute should be applied to a struct, enum or type alias
.label = is not a struct, enum or type alias
-passes-allow-incoherent-impl =
+passes_allow_incoherent_impl =
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
.label = the only currently supported targets are inherent methods
-passes-has-incoherent-inherent-impl =
+passes_has_incoherent_inherent_impl =
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
.label = only adts, extern types and traits are supported
-passes-must-use-async =
+passes_must_use_async =
`must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
.label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
-passes-must-use-no-effect = `#[must_use]` has no effect when applied to {$article} {$target}
+passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target}
-passes-must-not-suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
+passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
.label = is not a struct, enum, or trait
-passes-cold = {passes-should-be-applied-to-fn}
- .warn = {-passes-previously-accepted}
- .label = {passes-should-be-applied-to-fn.label}
+passes_cold = {passes_should_be_applied_to_fn}
+ .warn = {-passes_previously_accepted}
+ .label = {passes_should_be_applied_to_fn.label}
-passes-link = attribute should be applied to an `extern` block with non-Rust ABI
- .warn = {-passes-previously-accepted}
+passes_link = attribute should be applied to an `extern` block with non-Rust ABI
+ .warn = {-passes_previously_accepted}
.label = not an `extern` block
-passes-link-name = attribute should be applied to a foreign function or static
- .warn = {-passes-previously-accepted}
+passes_link_name = attribute should be applied to a foreign function or static
+ .warn = {-passes_previously_accepted}
.label = not a foreign function or static
.help = try `#[link(name = "{$value}")]` instead
-passes-no-link = attribute should be applied to an `extern crate` item
+passes_no_link = attribute should be applied to an `extern crate` item
.label = not an `extern crate` item
-passes-export-name = attribute should be applied to a free function, impl method or static
+passes_export_name = attribute should be applied to a free function, impl method or static
.label = not a free function, impl method or static
-passes-rustc-layout-scalar-valid-range-not-struct = attribute should be applied to a struct
+passes_rustc_layout_scalar_valid_range_not_struct = attribute should be applied to a struct
.label = not a struct
-passes-rustc-layout-scalar-valid-range-arg = expected exactly one integer literal argument
+passes_rustc_layout_scalar_valid_range_arg = expected exactly one integer literal argument
-passes-rustc-legacy-const-generics-only = #[rustc_legacy_const_generics] functions must only have const generics
+passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics
.label = non-const generic parameter
-passes-rustc-legacy-const-generics-index = #[rustc_legacy_const_generics] must have one index for each generic parameter
+passes_rustc_legacy_const_generics_index = #[rustc_legacy_const_generics] must have one index for each generic parameter
.label = generic parameters
-passes-rustc-legacy-const-generics-index-exceed = index exceeds number of arguments
+passes_rustc_legacy_const_generics_index_exceed = index exceeds number of arguments
.label = there {$arg_count ->
[one] is
*[other] are
@@ -181,84 +181,90 @@ passes-rustc-legacy-const-generics-index-exceed = index exceeds number of argume
*[other] arguments
}
-passes-rustc-legacy-const-generics-index-negative = arguments should be non-negative integers
+passes_rustc_legacy_const_generics_index_negative = arguments should be non-negative integers
-passes-rustc-dirty-clean = attribute requires -Z query-dep-graph to be enabled
+passes_rustc_dirty_clean = attribute requires -Z query-dep-graph to be enabled
-passes-link-section = attribute should be applied to a function or static
- .warn = {-passes-previously-accepted}
+passes_link_section = attribute should be applied to a function or static
+ .warn = {-passes_previously_accepted}
.label = not a function or static
-passes-no-mangle-foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
- .warn = {-passes-previously-accepted}
+passes_no_mangle_foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
+ .warn = {-passes_previously_accepted}
.label = foreign {$foreign_item_kind}
.note = symbol names in extern blocks are not mangled
.suggestion = remove this attribute
-passes-no-mangle = attribute should be applied to a free function, impl method or static
- .warn = {-passes-previously-accepted}
+passes_no_mangle = attribute should be applied to a free function, impl method or static
+ .warn = {-passes_previously_accepted}
.label = not a free function, impl method or static
-passes-repr-ident = meta item in `repr` must be an identifier
+passes_repr_ident = meta item in `repr` must be an identifier
-passes-repr-conflicting = conflicting representation hints
+passes_repr_conflicting = conflicting representation hints
-passes-used-static = attribute must be applied to a `static` variable
+passes_used_static = attribute must be applied to a `static` variable
-passes-used-compiler-linker = `used(compiler)` and `used(linker)` can't be used together
+passes_used_compiler_linker = `used(compiler)` and `used(linker)` can't be used together
-passes-allow-internal-unstable = attribute should be applied to a macro
+passes_allow_internal_unstable = attribute should be applied to a macro
.label = not a macro
-passes-debug-visualizer-placement = attribute should be applied to a module
+passes_debug_visualizer_placement = attribute should be applied to a module
-passes-debug-visualizer-invalid = invalid argument
- .note-1 = expected: `natvis_file = "..."`
- .note-2 = OR
- .note-3 = expected: `gdb_script_file = "..."`
+passes_debug_visualizer_invalid = invalid argument
+ .note_1 = expected: `natvis_file = "..."`
+ .note_2 = OR
+ .note_3 = expected: `gdb_script_file = "..."`
-passes-rustc-allow-const-fn-unstable = attribute should be applied to `const fn`
+passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn`
.label = not a `const fn`
-passes-rustc-std-internal-symbol = attribute should be applied to functions or statics
+passes_rustc_std_internal_symbol = attribute should be applied to functions or statics
.label = not a function or static
-passes-const-trait = attribute should be applied to a trait
+passes_const_trait = attribute should be applied to a trait
-passes-stability-promotable = attribute cannot be applied to an expression
+passes_stability_promotable = attribute cannot be applied to an expression
-passes-deprecated = attribute is ignored here
+passes_deprecated = attribute is ignored here
-passes-macro-use = `#[{$name}]` only has an effect on `extern crate` and modules
+passes_macro_use = `#[{$name}]` only has an effect on `extern crate` and modules
-passes-macro-export = `#[macro_export]` only has an effect on macro definitions
+passes_macro_export = `#[macro_export]` only has an effect on macro definitions
-passes-plugin-registrar = `#[plugin_registrar]` only has an effect on functions
+passes_plugin_registrar = `#[plugin_registrar]` only has an effect on functions
-passes-unused-empty-lints-note = attribute `{$name}` with an empty list has no effect
+passes_unused_empty_lints_note = attribute `{$name}` with an empty list has no effect
-passes-unused-no-lints-note = attribute `{$name}` without any lints has no effect
+passes_unused_no_lints_note = attribute `{$name}` without any lints has no effect
-passes-unused-default-method-body-const-note =
+passes_unused_default_method_body_const_note =
`default_method_body_is_const` has been replaced with `#[const_trait]` on traits
-passes-unused = unused attribute
+passes_unused = unused attribute
.suggestion = remove this attribute
-passes-non-exported-macro-invalid-attrs = attribute should be applied to function or closure
+passes_non_exported_macro_invalid_attrs = attribute should be applied to function or closure
.label = not a function or closure
-passes-unused-duplicate = unused attribute
+passes_unused_duplicate = unused attribute
.suggestion = remove this attribute
.note = attribute also specified here
- .warn = {-passes-previously-accepted}
+ .warn = {-passes_previously_accepted}
-passes-unused-multiple = multiple `{$name}` attributes
+passes_unused_multiple = multiple `{$name}` attributes
.suggestion = remove this attribute
.note = attribute also specified here
-passes-rustc-lint-opt-ty = `#[rustc_lint_opt_ty]` should be applied to a struct
+passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct
.label = not a struct
-passes-rustc-lint-opt-deny-field-access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
+passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
.label = not a field
+
+passes_link_ordinal = attribute should be applied to a foreign function or static
+ .label = not a foreign function or static
+
+passes_collapse_debuginfo = `collapse_debuginfo` attribute should be applied to macro definitions
+ .label = not a macro definition
diff --git a/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl b/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl
new file mode 100644
index 000000000..8db32a42c
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl
@@ -0,0 +1,4 @@
+plugin_impl_load_plugin_error = {$msg}
+
+plugin_impl_malformed_plugin_attribute = malformed `plugin` attribute
+ .label = malformed attribute
diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_error_messages/locales/en-US/privacy.ftl
index f8a750da9..da987152f 100644
--- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/privacy.ftl
@@ -1,20 +1,22 @@
-privacy-field-is-private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
-privacy-field-is-private-is-update-syntax-label = field `{$field_name}` is private
-privacy-field-is-private-label = private field
+privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
+privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
+privacy_field_is_private_label = private field
-privacy-item-is-private = {$kind} `{$descr}` is private
+privacy_item_is_private = {$kind} `{$descr}` is private
.label = private {$kind}
-privacy-unnamed-item-is-private = {$kind} is private
+privacy_unnamed_item_is_private = {$kind} is private
.label = private {$kind}
-privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
+privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface
.label = can't leak {$vis_descr} {$kind}
- .visibility-label = `{$descr}` declared as {$vis_descr}
+ .visibility_label = `{$descr}` declared as {$vis_descr}
-privacy-from-private-dep-in-public-interface =
+privacy_report_access_level = {$descr}
+
+privacy_from_private_dep_in_public_interface =
{$kind} `{$descr}` from private dependency '{$krate}' in public interface
-private-in-public-lint =
+privacy_private_in_public_lint =
{$vis_descr} {$kind} `{$descr}` in public interface (error {$kind ->
[trait] E0445
*[other] E0446
diff --git a/compiler/rustc_error_messages/locales/en-US/query_system.ftl b/compiler/rustc_error_messages/locales/en-US/query_system.ftl
new file mode 100644
index 000000000..167704e46
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/query_system.ftl
@@ -0,0 +1,25 @@
+query_system_reentrant = internal compiler error: re-entrant incremental verify failure, suppressing message
+
+query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node}
+ .help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile
+
+query_system_increment_compilation_note1 = Please follow the instructions below to create a bug report with the provided information
+query_system_increment_compilation_note2 = See <https://github.com/rust-lang/rust/issues/84970> for more information
+
+query_system_cycle = cycle detected when {$stack_bottom}
+
+query_system_cycle_usage = cycle used when {$usage}
+
+query_system_cycle_stack_single = ...which immediately requires {$stack_bottom} again
+
+query_system_cycle_stack_multiple = ...which again requires {$stack_bottom}, completing the cycle
+
+query_system_cycle_recursive_ty_alias = type aliases cannot be recursive
+query_system_cycle_recursive_ty_alias_help1 = consider using a struct, enum, or union instead to break the cycle
+query_system_cycle_recursive_ty_alias_help2 = see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
+
+query_system_cycle_recursive_trait_alias = trait aliases cannot be recursive
+
+query_system_cycle_which_requires = ...which requires {$desc}...
+
+query_system_query_overflow = queries overflow the depth limit!
diff --git a/compiler/rustc_error_messages/locales/en-US/save_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/save_analysis.ftl
new file mode 100644
index 000000000..36c2ff468
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/save_analysis.ftl
@@ -0,0 +1 @@
+save_analysis_could_not_open = Could not open `{$file_name}`: `{$err}`
diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl
new file mode 100644
index 000000000..76cae3c81
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/session.ftl
@@ -0,0 +1,68 @@
+session_incorrect_cgu_reuse_type =
+ CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
+ [one] {"at least "}
+ *[other] {""}
+ }`{$expected_reuse}`
+
+session_cgu_not_recorded =
+ CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded`
+
+session_feature_gate_error = {$explain}
+
+session_feature_diagnostic_for_issue =
+ see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
+
+session_feature_diagnostic_help =
+ add `#![feature({$feature})]` to the crate attributes to enable
+
+session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine
+
+session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
+
+session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets
+
+session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist.
+
+session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`
+
+session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
+
+session_sanitizers_not_supported = {$us} sanitizers are not supported for this target
+
+session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`
+
+session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
+
+session_sanitizer_cfi_enabled = `-Zsanitizer=cfi` requires `-Clto`
+
+session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto`
+
+session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is greater than 5
+
+session_target_invalid_address_space = invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
+
+session_target_invalid_bits = invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
+
+session_target_missing_alignment = missing alignment for `{$cause}` in "data-layout"
+
+session_target_invalid_alignment = invalid alignment for `{$cause}` in "data-layout": {$err}
+
+session_target_inconsistent_architecture = inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
+
+session_target_inconsistent_pointer_width = inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
+
+session_target_invalid_bits_size = {$err}
+
+session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored
+
+session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform
+
+session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
+
+session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}`
+
+session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen
+
+session_crate_name_empty = crate name must not be empty
+
+session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
diff --git a/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl b/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl
new file mode 100644
index 000000000..b7d48280f
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl
@@ -0,0 +1 @@
+symbol_mangling_test_output = {$kind}({$content})
diff --git a/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl b/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl
new file mode 100644
index 000000000..004e0ab18
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl
@@ -0,0 +1,26 @@
+trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
+
+trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
+
+trait_selection_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
+ .label = deref recursion limit reached
+ .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
+
+trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
+ .label = empty on-clause here
+
+trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]`
+ .label = invalid on-clause here
+
+trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a valid value
+ .label = expected value here
+ .note = eg `#[rustc_on_unimplemented(message="foo")]`
+
+trait_selection_negative_positive_conflict = found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
+ [none] {""}
+ *[default] {" "}for type `{$self_desc}`
+ }:
+ .negative_implementation_here = negative implementation here
+ .negative_implementation_in_crate = negative implementation in crate `{$negative_impl_cname}`
+ .positive_implementation_here = positive implementation here
+ .positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}`
diff --git a/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl b/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl
new file mode 100644
index 000000000..1040ee1c9
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl
@@ -0,0 +1,47 @@
+ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop
+
+ty_utils_generic_constant_too_complex = overly complex generic constant
+ .help = consider moving this anonymous constant into a `const` function
+ .maybe_supported = this operation may be supported in the future
+
+ty_utils_borrow_not_supported = borrowing is not supported in generic constants
+
+ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants
+
+ty_utils_array_not_supported = array construction is not supported in generic constants
+
+ty_utils_block_not_supported = blocks are not supported in generic constant
+
+ty_utils_never_to_any_not_supported = converting nevers to any is not supported in generic constant
+
+ty_utils_tuple_not_supported = tuple construction is not supported in generic constants
+
+ty_utils_index_not_supported = indexing is not supported in generic constant
+
+ty_utils_field_not_supported = field access is not supported in generic constant
+
+ty_utils_const_block_not_supported = const blocks are not supported in generic constant
+
+ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants
+
+ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants
+
+ty_utils_yield_not_supported = generator control flow is not allowed in generic constants
+
+ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants
+
+ty_utils_box_not_supported = allocations are not allowed in generic constants
+
+ty_utils_binary_not_supported = unsupported binary operation in generic constants
+
+ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow
+
+ty_utils_assign_not_supported = assignment is not supported in generic constants
+
+ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants
+
+ty_utils_control_flow_not_supported = control flow is not supported in generic constants
+
+ty_utils_inline_asm_not_supported = assembly is not supported in generic constants
+
+ty_utils_operation_not_supported = unsupported operation in generic constant
diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
index c61735a57..272731d99 100644
--- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
@@ -1,101 +1,101 @@
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
- .previous-use-label = first use of `{$ident}`
+ .previous_use_label = first use of `{$ident}`
-typeck-unrecognized-atomic-operation =
+typeck_unrecognized_atomic_operation =
unrecognized atomic operation function: `{$op}`
.label = unrecognized atomic operation
-typeck-wrong-number-of-generic-arguments-to-intrinsic =
+typeck_wrong_number_of_generic_arguments_to_intrinsic =
intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
.label = expected {$expected} {$descr} {$expected ->
[one] parameter
*[other] parameters
}
-typeck-unrecognized-intrinsic-function =
+typeck_unrecognized_intrinsic_function =
unrecognized intrinsic function: `{$name}`
.label = unrecognized intrinsic
-typeck-lifetimes-or-bounds-mismatch-on-trait =
+typeck_lifetimes_or_bounds_mismatch_on_trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
- .generics-label = lifetimes in impl do not match this {$item_kind} in trait
+ .generics_label = lifetimes in impl do not match this {$item_kind} in trait
-typeck-drop-impl-on-wrong-item =
- the `Drop` trait may only be implemented for structs, enums, and unions
- .label = must be a struct, enum, or union
+typeck_drop_impl_on_wrong_item =
+ the `Drop` trait may only be implemented for local structs, enums, and unions
+ .label = must be a struct, enum, or union in the current crate
-typeck-field-already-declared =
+typeck_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
- .previous-decl-label = `{$field_name}` first declared here
+ .previous_decl_label = `{$field_name}` first declared here
-typeck-copy-impl-on-type-with-dtor =
+typeck_copy_impl_on_type_with_dtor =
the trait `Copy` may not be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
-typeck-multiple-relaxed-default-bounds =
+typeck_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
-typeck-copy-impl-on-non-adt =
+typeck_copy_impl_on_non_adt =
the trait `Copy` may not be implemented for this type
.label = type is not a structure or enumeration
-typeck-trait-object-declared-with-no-traits =
+typeck_trait_object_declared_with_no_traits =
at least one trait is required for an object type
- .alias-span = this alias does not contain a trait
+ .alias_span = this alias does not contain a trait
-typeck-ambiguous-lifetime-bound =
+typeck_ambiguous_lifetime_bound =
ambiguous lifetime bound, explicit lifetime bound required
-typeck-assoc-type-binding-not-allowed =
+typeck_assoc_type_binding_not_allowed =
associated type bindings are not allowed here
.label = associated type not allowed here
-typeck-functional-record-update-on-non-struct =
+typeck_functional_record_update_on_non_struct =
functional record update syntax requires a struct
-typeck-typeof-reserved-keyword-used =
+typeck_typeof_reserved_keyword_used =
`typeof` is a reserved keyword but unimplemented
.suggestion = consider replacing `typeof(...)` with an actual type
.label = reserved keyword
-typeck-return-stmt-outside-of-fn-body =
+typeck_return_stmt_outside_of_fn_body =
return statement outside of function body
- .encl-body-label = the return is part of this body...
- .encl-fn-label = ...not the enclosing function body
+ .encl_body_label = the return is part of this body...
+ .encl_fn_label = ...not the enclosing function body
-typeck-yield-expr-outside-of-generator =
+typeck_yield_expr_outside_of_generator =
yield expression outside of generator literal
-typeck-struct-expr-non-exhaustive =
+typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
-typeck-method-call-on-unknown-type =
+typeck_method_call_on_unknown_type =
the type of this value must be known to call a method on a raw pointer on it
-typeck-value-of-associated-struct-already-specified =
+typeck_value_of_associated_struct_already_specified =
the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
.label = re-bound here
- .previous-bound-label = `{$item_name}` bound here first
+ .previous_bound_label = `{$item_name}` bound here first
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
-typeck-add-return-type-add = try adding a return type
+typeck_add_return_type_add = try adding a return type
-typeck-add-return-type-missing-here = a return type might be missing here
+typeck_add_return_type_missing_here = a return type might be missing here
-typeck-expected-default-return-type = expected `()` because of default return type
+typeck_expected_default_return_type = expected `()` because of default return type
-typeck-expected-return-type = expected `{$expected}` because of return type
+typeck_expected_return_type = expected `{$expected}` because of return type
-typeck-unconstrained-opaque-type = unconstrained opaque type
+typeck_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same module
-typeck-missing-type-params =
+typeck_missing_type_params =
the type {$parameterCount ->
[one] parameter
*[other] parameters
@@ -111,15 +111,25 @@ typeck-missing-type-params =
[one] type
*[other] types
}
- .no-suggestion-label = missing {$parameterCount ->
+ .no_suggestion_label = missing {$parameterCount ->
[one] reference
*[other] references
} to {$parameters}
.note = because of the default `Self` reference, type parameters must be specified on object types
-typeck-manual-implementation =
+typeck_manual_implementation =
manual implementations of `{$trait_name}` are experimental
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
-typeck-substs-on-overridden-impl = could not resolve substs on overridden impl
+typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
+
+typeck_unused_extern_crate =
+ unused extern crate
+ .suggestion = remove it
+
+typeck_extern_crate_not_idiomatic =
+ `extern crate` is not idiomatic in the new edition
+ .suggestion = convert it to a `{$msg_code}`
+
+typeck_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 02bb04d98..b6e0f3faa 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -2,6 +2,11 @@
#![feature(once_cell)]
#![feature(rustc_attrs)]
#![feature(type_alias_impl_trait)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
+#[macro_use]
+extern crate tracing;
use fluent_bundle::FluentResource;
use fluent_syntax::parser::ParserError;
@@ -14,7 +19,6 @@ use std::fmt;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
-use tracing::{instrument, trace};
#[cfg(not(parallel_compiler))]
use std::cell::LazyCell as Lazy;
@@ -31,15 +35,32 @@ pub use unic_langid::{langid, LanguageIdentifier};
// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
fluent_messages! {
+ ast_lowering => "../locales/en-US/ast_lowering.ftl",
+ ast_passes => "../locales/en-US/ast_passes.ftl",
+ attr => "../locales/en-US/attr.ftl",
borrowck => "../locales/en-US/borrowck.ftl",
builtin_macros => "../locales/en-US/builtin_macros.ftl",
const_eval => "../locales/en-US/const_eval.ftl",
+ driver => "../locales/en-US/driver.ftl",
expand => "../locales/en-US/expand.ftl",
+ session => "../locales/en-US/session.ftl",
+ interface => "../locales/en-US/interface.ftl",
+ infer => "../locales/en-US/infer.ftl",
lint => "../locales/en-US/lint.ftl",
+ middle => "../locales/en-US/middle.ftl",
+ monomorphize => "../locales/en-US/monomorphize.ftl",
+ metadata => "../locales/en-US/metadata.ftl",
parser => "../locales/en-US/parser.ftl",
passes => "../locales/en-US/passes.ftl",
+ plugin_impl => "../locales/en-US/plugin_impl.ftl",
privacy => "../locales/en-US/privacy.ftl",
+ query_system => "../locales/en-US/query_system.ftl",
+ trait_selection => "../locales/en-US/trait_selection.ftl",
+ save_analysis => "../locales/en-US/save_analysis.ftl",
+ ty_utils => "../locales/en-US/ty_utils.ftl",
typeck => "../locales/en-US/typeck.ftl",
+ mir_dataflow => "../locales/en-US/mir_dataflow.ftl",
+ symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
}
pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 7d7e92c52..c36ca11fa 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -13,15 +13,16 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
rustc_macros = { path = "../rustc_macros" }
rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_target = { path = "../rustc_target" }
rustc_hir = { path = "../rustc_hir" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
unicode-width = "0.1.4"
atty = "0.2"
termcolor = "1.0"
-annotate-snippets = "0.8.0"
+annotate-snippets = "0.9"
termize = "0.1.1"
-serde = { version = "1.0.125", features = ["derive"] }
+serde = { version = "1.0.125", features = [ "derive" ] }
serde_json = "1.0.59"
[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }
+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 0fcd61d1e..b32fc3c71 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -7,6 +7,7 @@
use crate::emitter::FileWithAnnotatedLines;
use crate::snippet::Line;
+use crate::translation::Translate;
use crate::{
CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle,
LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
@@ -32,6 +33,16 @@ pub struct AnnotateSnippetEmitterWriter {
macro_backtrace: bool,
}
+impl Translate for AnnotateSnippetEmitterWriter {
+ fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
+ self.fluent_bundle.as_ref()
+ }
+
+ fn fallback_fluent_bundle(&self) -> &FluentBundle {
+ &**self.fallback_bundle
+ }
+}
+
impl Emitter for AnnotateSnippetEmitterWriter {
/// The entry point for the diagnostics generation
fn emit_diagnostic(&mut self, diag: &Diagnostic) {
@@ -63,14 +74,6 @@ impl Emitter for AnnotateSnippetEmitterWriter {
self.source_map.as_ref()
}
- fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
- self.fluent_bundle.as_ref()
- }
-
- fn fallback_fluent_bundle(&self) -> &FluentBundle {
- &**self.fallback_bundle
- }
-
fn should_show_explain(&self) -> bool {
!self.short_message
}
@@ -183,7 +186,11 @@ impl AnnotateSnippetEmitterWriter {
annotation_type: annotation_type_for_level(*level),
}),
footer: vec![],
- opt: FormatOptions { color: true, anonymized_line_numbers: self.ui_testing },
+ opt: FormatOptions {
+ color: true,
+ anonymized_line_numbers: self.ui_testing,
+ margin: None,
+ },
slices: annotated_files
.iter()
.map(|(source, line_index, annotations)| {
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 17e6c9e95..a774b52c8 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -8,11 +8,14 @@ use rustc_error_messages::FluentValue;
use rustc_hir as hir;
use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_span::edition::LATEST_STABLE_EDITION;
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
use rustc_span::{edition::Edition, Span, DUMMY_SP};
+use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
use std::borrow::Cow;
use std::fmt;
use std::hash::{Hash, Hasher};
+use std::num::ParseIntError;
+use std::path::{Path, PathBuf};
/// Error type for `Diagnostic`'s `suggestions` field, indicating that
/// `.disable_suggestions()` was called on the `Diagnostic`.
@@ -83,10 +86,16 @@ into_diagnostic_arg_using_display!(
u64,
i128,
u128,
+ std::io::Error,
std::num::NonZeroU32,
hir::Target,
Edition,
Ident,
+ MacroRulesNormalizedIdent,
+ ParseIntError,
+ StackProtector,
+ &TargetTriple,
+ SplitDebuginfo
);
impl IntoDiagnosticArg for bool {
@@ -123,12 +132,30 @@ impl IntoDiagnosticArg for String {
}
}
+impl<'a> IntoDiagnosticArg for &'a Path {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
+ }
+}
+
+impl IntoDiagnosticArg for PathBuf {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
+ }
+}
+
impl IntoDiagnosticArg for usize {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Number(self)
}
}
+impl IntoDiagnosticArg for PanicStrategy {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
+ }
+}
+
impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
fn into(self) -> FluentValue<'source> {
match self {
@@ -671,19 +698,12 @@ impl Diagnostic {
suggestion: Vec<(Span, String)>,
applicability: Applicability,
) -> &mut Self {
- assert!(!suggestion.is_empty());
- self.push_suggestion(CodeSuggestion {
- substitutions: vec![Substitution {
- parts: suggestion
- .into_iter()
- .map(|(span, snippet)| SubstitutionPart { snippet, span })
- .collect(),
- }],
- msg: self.subdiagnostic_message_to_diagnostic_message(msg),
- style: SuggestionStyle::CompletelyHidden,
+ self.multipart_suggestion_with_style(
+ msg,
+ suggestion,
applicability,
- });
- self
+ SuggestionStyle::CompletelyHidden,
+ )
}
/// Prints out a message with a suggested edit of the code.
@@ -966,12 +986,12 @@ impl Diagnostic {
fn sub_with_highlights<M: Into<SubdiagnosticMessage>>(
&mut self,
level: Level,
- mut message: Vec<(M, Style)>,
+ message: Vec<(M, Style)>,
span: MultiSpan,
render_span: Option<MultiSpan>,
) {
let message = message
- .drain(..)
+ .into_iter()
.map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.0), m.1))
.collect();
let sub = SubDiagnostic { level, message, span, render_span };
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 9e68ee282..7e29dc207 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -12,7 +12,6 @@ use std::fmt::{self, Debug};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::thread::panicking;
-use tracing::debug;
/// Used for emitting structured error messages and other diagnostic information.
///
@@ -84,6 +83,13 @@ pub trait EmissionGuarantee: Sized {
/// of `Self` without actually performing the emission.
#[track_caller]
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self;
+
+ /// Creates a new `DiagnosticBuilder` that will return this type of guarantee.
+ #[track_caller]
+ fn make_diagnostic_builder(
+ handler: &Handler,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> DiagnosticBuilder<'_, Self>;
}
/// Private module for sealing the `IsError` helper trait.
@@ -166,6 +172,15 @@ impl EmissionGuarantee for ErrorGuaranteed {
}
}
}
+
+ fn make_diagnostic_builder(
+ handler: &Handler,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> DiagnosticBuilder<'_, Self> {
+ DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(
+ handler, msg,
+ )
+ }
}
impl<'a> DiagnosticBuilder<'a, ()> {
@@ -208,6 +223,13 @@ impl EmissionGuarantee for () {
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
}
}
+
+ fn make_diagnostic_builder(
+ handler: &Handler,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> DiagnosticBuilder<'_, Self> {
+ DiagnosticBuilder::new(handler, Level::Warning(None), msg)
+ }
}
impl<'a> DiagnosticBuilder<'a, !> {
@@ -247,6 +269,13 @@ impl EmissionGuarantee for ! {
// Then fatally error, returning `!`
crate::FatalError.raise()
}
+
+ fn make_diagnostic_builder(
+ handler: &Handler,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> DiagnosticBuilder<'_, Self> {
+ DiagnosticBuilder::new_fatal(handler, msg)
+ }
}
/// In general, the `DiagnosticBuilder` uses deref to allow access to
@@ -566,7 +595,7 @@ impl Drop for DiagnosticBuilderInner<'_> {
),
));
handler.emit_diagnostic(&mut self.diagnostic);
- panic!();
+ panic!("error was constructed but not emitted");
}
}
// `.emit()` was previously called, or maybe we're during `.cancel()`.
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 61d953cd6..66fbb8f12 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -14,15 +14,15 @@ use rustc_span::{FileLines, SourceFile, Span};
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString};
use crate::styled_buffer::StyledBuffer;
+use crate::translation::Translate;
use crate::{
- CodeSuggestion, Diagnostic, DiagnosticArg, DiagnosticId, DiagnosticMessage, FluentBundle,
- Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
- SuggestionStyle,
+ CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, FluentBundle, Handler,
+ LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle,
};
use rustc_lint_defs::pluralize;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::sync::Lrc;
use rustc_error_messages::FluentArgs;
use rustc_span::hygiene::{ExpnKind, MacroKind};
@@ -34,7 +34,6 @@ use std::iter;
use std::path::Path;
use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
use termcolor::{Buffer, Color, WriteColor};
-use tracing::*;
/// Default column width, used in tests and when terminal dimensions cannot be determined.
const DEFAULT_COLUMN_WIDTH: usize = 140;
@@ -200,7 +199,7 @@ impl Margin {
const ANONYMIZED_LINE_NUM: &str = "LL";
/// Emitter trait for emitting errors.
-pub trait Emitter {
+pub trait Emitter: Translate {
/// Emit a structured diagnostic.
fn emit_diagnostic(&mut self, diag: &Diagnostic);
@@ -231,84 +230,6 @@ pub trait Emitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>>;
- /// Return `FluentBundle` with localized diagnostics for the locale requested by the user. If no
- /// language was requested by the user then this will be `None` and `fallback_fluent_bundle`
- /// should be used.
- fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>>;
-
- /// Return `FluentBundle` with localized diagnostics for the default locale of the compiler.
- /// Used when the user has not requested a specific language or when a localized diagnostic is
- /// unavailable for the requested locale.
- fn fallback_fluent_bundle(&self) -> &FluentBundle;
-
- /// Convert diagnostic arguments (a rustc internal type that exists to implement
- /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
- ///
- /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
- /// passed around as a reference thereafter.
- fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> {
- FromIterator::from_iter(args.to_vec().drain(..))
- }
-
- /// Convert `DiagnosticMessage`s to a string, performing translation if necessary.
- fn translate_messages(
- &self,
- messages: &[(DiagnosticMessage, Style)],
- args: &FluentArgs<'_>,
- ) -> Cow<'_, str> {
- Cow::Owned(
- messages.iter().map(|(m, _)| self.translate_message(m, args)).collect::<String>(),
- )
- }
-
- /// Convert a `DiagnosticMessage` to a string, performing translation if necessary.
- fn translate_message<'a>(
- &'a self,
- message: &'a DiagnosticMessage,
- args: &'a FluentArgs<'_>,
- ) -> Cow<'_, str> {
- trace!(?message, ?args);
- let (identifier, attr) = match message {
- DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg),
- DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
- };
-
- let bundle = match self.fluent_bundle() {
- Some(bundle) if bundle.has_message(&identifier) => bundle,
- _ => self.fallback_fluent_bundle(),
- };
-
- let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle");
- let value = match attr {
- Some(attr) => {
- if let Some(attr) = message.get_attribute(attr) {
- attr.value()
- } else {
- panic!("missing attribute `{attr}` in fluent message `{identifier}`")
- }
- }
- None => {
- if let Some(value) = message.value() {
- value
- } else {
- panic!("missing value in fluent message `{identifier}`")
- }
- }
- };
-
- let mut err = vec![];
- let translated = bundle.format_pattern(value, Some(&args), &mut err);
- trace!(?translated, ?err);
- debug_assert!(
- err.is_empty(),
- "identifier: {:?}, args: {:?}, errors: {:?}",
- identifier,
- args,
- err
- );
- translated
- }
-
/// Formats the substitutions of the primary_span
///
/// There are a lot of conditions to this method, but in short:
@@ -598,11 +519,7 @@ pub trait Emitter {
}
}
-impl Emitter for EmitterWriter {
- fn source_map(&self) -> Option<&Lrc<SourceMap>> {
- self.sm.as_ref()
- }
-
+impl Translate for EmitterWriter {
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
self.fluent_bundle.as_ref()
}
@@ -610,6 +527,12 @@ impl Emitter for EmitterWriter {
fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
}
+}
+
+impl Emitter for EmitterWriter {
+ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+ self.sm.as_ref()
+ }
fn emit_diagnostic(&mut self, diag: &Diagnostic) {
let fluent_args = self.to_fluent_args(diag.args());
@@ -654,11 +577,7 @@ pub struct SilentEmitter {
pub fatal_note: Option<String>,
}
-impl Emitter for SilentEmitter {
- fn source_map(&self) -> Option<&Lrc<SourceMap>> {
- None
- }
-
+impl Translate for SilentEmitter {
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
None
}
@@ -666,6 +585,12 @@ impl Emitter for SilentEmitter {
fn fallback_fluent_bundle(&self) -> &FluentBundle {
panic!("silent emitter attempted to translate message")
}
+}
+
+impl Emitter for SilentEmitter {
+ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+ None
+ }
fn emit_diagnostic(&mut self, d: &Diagnostic) {
if d.level == Level::Fatal {
@@ -1562,7 +1487,7 @@ impl EmitterWriter {
);
// Contains the vertical lines' positions for active multiline annotations
- let mut multilines = FxHashMap::default();
+ let mut multilines = FxIndexMap::default();
// Get the left-side margin to remove it
let mut whitespace_margin = usize::MAX;
@@ -1779,7 +1704,7 @@ impl EmitterWriter {
{
notice_capitalization |= only_capitalization;
- let has_deletion = parts.iter().any(|p| p.is_deletion());
+ let has_deletion = parts.iter().any(|p| p.is_deletion(sm));
let is_multiline = complete.lines().count() > 1;
if let Some(span) = span.primary_span() {
@@ -1955,16 +1880,23 @@ impl EmitterWriter {
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;
+ // If this addition is _only_ whitespace, then don't trim it,
+ // or else we're just not rendering anything.
+ let is_whitespace_addition = part.snippet.trim().is_empty();
+
// Do not underline the leading...
- let start = part.snippet.len().saturating_sub(part.snippet.trim_start().len());
+ let start = if is_whitespace_addition {
+ 0
+ } else {
+ part.snippet.len().saturating_sub(part.snippet.trim_start().len())
+ };
// ...or trailing spaces. Account for substitutions containing unicode
// characters.
- let sub_len: usize = part
- .snippet
- .trim()
- .chars()
- .map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1))
- .sum();
+ let sub_len: usize =
+ if is_whitespace_addition { &part.snippet } else { part.snippet.trim() }
+ .chars()
+ .map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1))
+ .sum();
let offset: isize = offsets
.iter()
@@ -2205,7 +2137,7 @@ impl EmitterWriter {
}
}
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
enum DisplaySuggestion {
Underline,
Diff,
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index b8cd334b4..1680c6acc 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -13,6 +13,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
use crate::emitter::{Emitter, HumanReadableErrorType};
use crate::registry::Registry;
+use crate::translation::Translate;
use crate::DiagnosticId;
use crate::{
CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic,
@@ -122,6 +123,16 @@ impl JsonEmitter {
}
}
+impl Translate for JsonEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
+ self.fluent_bundle.as_ref()
+ }
+
+ fn fallback_fluent_bundle(&self) -> &FluentBundle {
+ &**self.fallback_bundle
+ }
+}
+
impl Emitter for JsonEmitter {
fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
let data = Diagnostic::from_errors_diagnostic(diag, self);
@@ -189,14 +200,6 @@ impl Emitter for JsonEmitter {
Some(&self.sm)
}
- fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
- self.fluent_bundle.as_ref()
- }
-
- fn fallback_fluent_bundle(&self) -> &FluentBundle {
- &**self.fallback_bundle
- }
-
fn should_show_explain(&self) -> bool {
!matches!(self.json_rendered, HumanReadableErrorType::Short(_))
}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 2409c0b5a..a7b01feeb 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -4,15 +4,14 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(drain_filter)]
-#![feature(backtrace)]
#![feature(if_let_guard)]
+#![feature(adt_const_params)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
-#![feature(adt_const_params)]
+#![feature(result_option_inspect)]
#![feature(rustc_attrs)]
#![allow(incomplete_features)]
-#![allow(rustc::potential_query_instability)]
#[macro_use]
extern crate rustc_macros;
@@ -27,7 +26,7 @@ use Level::*;
use emitter::{is_case_difference, Emitter, EmitterWriter};
use registry::Registry;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{self, Lock, Lrc};
use rustc_data_structures::AtomicRef;
@@ -59,6 +58,7 @@ mod lock;
pub mod registry;
mod snippet;
mod styled_buffer;
+pub mod translation;
pub use snippet::Style;
@@ -68,8 +68,8 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a, ErrorGuaranteed>>;
// (See also the comment on `DiagnosticBuilder`'s `diagnostic` field.)
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16);
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64", not(bootstrap)))]
+rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
pub enum SuggestionStyle {
@@ -150,21 +150,20 @@ pub struct SubstitutionHighlight {
impl SubstitutionPart {
pub fn is_addition(&self, sm: &SourceMap) -> bool {
- !self.snippet.is_empty()
- && sm
- .span_to_snippet(self.span)
- .map_or(self.span.is_empty(), |snippet| snippet.trim().is_empty())
+ !self.snippet.is_empty() && !self.replaces_meaningful_content(sm)
}
- pub fn is_deletion(&self) -> bool {
- self.snippet.trim().is_empty()
+ pub fn is_deletion(&self, sm: &SourceMap) -> bool {
+ self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm)
}
pub fn is_replacement(&self, sm: &SourceMap) -> bool {
- !self.snippet.is_empty()
- && sm
- .span_to_snippet(self.span)
- .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
+ !self.snippet.is_empty() && self.replaces_meaningful_content(sm)
+ }
+
+ fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
+ sm.span_to_snippet(self.span)
+ .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
}
}
@@ -412,7 +411,7 @@ struct HandlerInner {
taught_diagnostics: FxHashSet<DiagnosticId>,
/// Used to suggest rustc --explain <error code>
- emitted_diagnostic_codes: FxHashSet<DiagnosticId>,
+ emitted_diagnostic_codes: FxIndexSet<DiagnosticId>,
/// This set contains a hash of every diagnostic that has been emitted by
/// this handler. These hashes is used to avoid emitting the same error
@@ -455,9 +454,11 @@ struct HandlerInner {
}
/// A key denoting where from a diagnostic was stashed.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum StashKey {
ItemNoType,
+ UnderscoreForArrayLengths,
+ EarlySyntaxWarning,
}
fn default_track_diagnostic(_: &Diagnostic) {}
@@ -625,19 +626,17 @@ impl Handler {
/// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
let mut inner = self.inner.borrow_mut();
- // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
- // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
- // See the PR for a discussion.
- inner.stashed_diagnostics.insert((span, key), diag);
+ inner.stash((span, key), diag);
}
/// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
- self.inner
- .borrow_mut()
- .stashed_diagnostics
- .remove(&(span, key))
- .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
+ let mut inner = self.inner.borrow_mut();
+ inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
+ }
+
+ pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
+ self.inner.borrow().stashed_diagnostics.get(&(span, key)).is_some()
}
/// Emit all stashed diagnostics.
@@ -645,6 +644,15 @@ impl Handler {
self.inner.borrow_mut().emit_stashed_diagnostics()
}
+ /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`.
+ #[rustc_lint_diagnostics]
+ pub fn struct_diagnostic<G: EmissionGuarantee>(
+ &self,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> DiagnosticBuilder<'_, G> {
+ G::make_diagnostic_builder(self, msg)
+ }
+
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
///
/// Attempting to `.emit()` the builder will only emit if either:
@@ -1105,13 +1113,31 @@ impl HandlerInner {
/// Emit all stashed diagnostics.
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
+ let has_errors = self.has_errors();
let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
let mut reported = None;
for mut diag in diags {
+ // Decrement the count tracking the stash; emitting will increment it.
if diag.is_error() {
- reported = Some(ErrorGuaranteed(()));
+ if matches!(diag.level, Level::Error { lint: true }) {
+ self.lint_err_count -= 1;
+ } else {
+ self.err_count -= 1;
+ }
+ } else {
+ if diag.is_force_warn() {
+ self.warn_count -= 1;
+ } else {
+ // Unless they're forced, don't flush stashed warnings when
+ // there are errors, to avoid causing warning overload. The
+ // stash would've been stolen already if it were important.
+ if has_errors {
+ continue;
+ }
+ }
}
- self.emit_diagnostic(&mut diag);
+ let reported_this = self.emit_diagnostic(&mut diag);
+ reported = reported.or(reported_this);
}
reported
}
@@ -1225,9 +1251,13 @@ impl HandlerInner {
}
fn treat_err_as_bug(&self) -> bool {
- self.flags
- .treat_err_as_bug
- .map_or(false, |c| self.err_count() + self.lint_err_count >= c.get())
+ self.flags.treat_err_as_bug.map_or(false, |c| {
+ self.err_count() + self.lint_err_count + self.delayed_bug_count() >= c.get()
+ })
+ }
+
+ fn delayed_bug_count(&self) -> usize {
+ self.delayed_span_bugs.len() + self.delayed_good_path_bugs.len()
}
fn print_error_count(&mut self, registry: &Registry) {
@@ -1301,9 +1331,47 @@ impl HandlerInner {
}
}
+ fn stash(&mut self, key: (Span, StashKey), diagnostic: Diagnostic) {
+ // Track the diagnostic for counts, but don't panic-if-treat-err-as-bug
+ // yet; that happens when we actually emit the diagnostic.
+ if diagnostic.is_error() {
+ if matches!(diagnostic.level, Level::Error { lint: true }) {
+ self.lint_err_count += 1;
+ } else {
+ self.err_count += 1;
+ }
+ } else {
+ // Warnings are only automatically flushed if they're forced.
+ if diagnostic.is_force_warn() {
+ self.warn_count += 1;
+ }
+ }
+
+ // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
+ // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
+ // See the PR for a discussion.
+ self.stashed_diagnostics.insert(key, diagnostic);
+ }
+
+ fn steal(&mut self, key: (Span, StashKey)) -> Option<Diagnostic> {
+ let diagnostic = self.stashed_diagnostics.remove(&key)?;
+ if diagnostic.is_error() {
+ if matches!(diagnostic.level, Level::Error { lint: true }) {
+ self.lint_err_count -= 1;
+ } else {
+ self.err_count -= 1;
+ }
+ } else {
+ if diagnostic.is_force_warn() {
+ self.warn_count -= 1;
+ }
+ }
+ Some(diagnostic)
+ }
+
#[inline]
fn err_count(&self) -> usize {
- self.err_count + self.stashed_diagnostics.len()
+ self.err_count
}
fn has_errors(&self) -> bool {
@@ -1345,7 +1413,9 @@ impl HandlerInner {
// This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before
// incrementing `err_count` by one, so we need to +1 the comparing.
// FIXME: Would be nice to increment err_count in a more coherent way.
- if self.flags.treat_err_as_bug.map_or(false, |c| self.err_count() + 1 >= c.get()) {
+ if self.flags.treat_err_as_bug.map_or(false, |c| {
+ self.err_count() + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get()
+ }) {
// FIXME: don't abort here if report_delayed_bugs is off
self.span_bug(sp, msg);
}
@@ -1445,14 +1515,24 @@ impl HandlerInner {
if self.treat_err_as_bug() {
match (
self.err_count() + self.lint_err_count,
+ self.delayed_bug_count(),
self.flags.treat_err_as_bug.map(|c| c.get()).unwrap_or(0),
) {
- (1, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"),
- (0 | 1, _) => {}
- (count, as_bug) => panic!(
- "aborting after {} errors due to `-Z treat-err-as-bug={}`",
- count, as_bug,
- ),
+ (1, 0, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"),
+ (0, 1, 1) => panic!("aborting due delayed bug with `-Z treat-err-as-bug=1`"),
+ (count, delayed_count, as_bug) => {
+ if delayed_count > 0 {
+ panic!(
+ "aborting after {} errors and {} delayed bugs due to `-Z treat-err-as-bug={}`",
+ count, delayed_count, as_bug,
+ )
+ } else {
+ panic!(
+ "aborting after {} errors due to `-Z treat-err-as-bug={}`",
+ count, as_bug,
+ )
+ }
+ }
}
}
}
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
new file mode 100644
index 000000000..4f407badb
--- /dev/null
+++ b/compiler/rustc_errors/src/translation.rs
@@ -0,0 +1,103 @@
+use crate::snippet::Style;
+use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle};
+use rustc_data_structures::sync::Lrc;
+use rustc_error_messages::FluentArgs;
+use std::borrow::Cow;
+
+pub trait Translate {
+ /// Return `FluentBundle` with localized diagnostics for the locale requested by the user. If no
+ /// language was requested by the user then this will be `None` and `fallback_fluent_bundle`
+ /// should be used.
+ fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>>;
+
+ /// Return `FluentBundle` with localized diagnostics for the default locale of the compiler.
+ /// Used when the user has not requested a specific language or when a localized diagnostic is
+ /// unavailable for the requested locale.
+ fn fallback_fluent_bundle(&self) -> &FluentBundle;
+
+ /// Convert diagnostic arguments (a rustc internal type that exists to implement
+ /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
+ ///
+ /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
+ /// passed around as a reference thereafter.
+ fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> {
+ FromIterator::from_iter(args.iter().cloned())
+ }
+
+ /// Convert `DiagnosticMessage`s to a string, performing translation if necessary.
+ fn translate_messages(
+ &self,
+ messages: &[(DiagnosticMessage, Style)],
+ args: &FluentArgs<'_>,
+ ) -> Cow<'_, str> {
+ Cow::Owned(
+ messages.iter().map(|(m, _)| self.translate_message(m, args)).collect::<String>(),
+ )
+ }
+
+ /// Convert a `DiagnosticMessage` to a string, performing translation if necessary.
+ fn translate_message<'a>(
+ &'a self,
+ message: &'a DiagnosticMessage,
+ args: &'a FluentArgs<'_>,
+ ) -> Cow<'_, str> {
+ trace!(?message, ?args);
+ let (identifier, attr) = match message {
+ DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg),
+ DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
+ };
+
+ let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
+ let message = bundle.get_message(&identifier)?;
+ let value = match attr {
+ Some(attr) => message.get_attribute(attr)?.value(),
+ None => message.value()?,
+ };
+ debug!(?message, ?value);
+
+ let mut errs = vec![];
+ let translated = bundle.format_pattern(value, Some(&args), &mut errs);
+ debug!(?translated, ?errs);
+ Some((translated, errs))
+ };
+
+ self.fluent_bundle()
+ .and_then(|bundle| translate_with_bundle(bundle))
+ // If `translate_with_bundle` returns `None` with the primary bundle, this is likely
+ // just that the primary bundle doesn't contain the message being translated, so
+ // proceed to the fallback bundle.
+ //
+ // However, when errors are produced from translation, then that means the translation
+ // is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided).
+ //
+ // In debug builds, assert so that compiler devs can spot the broken translation and
+ // fix it..
+ .inspect(|(_, errs)| {
+ debug_assert!(
+ errs.is_empty(),
+ "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+ identifier,
+ attr,
+ args,
+ errs
+ );
+ })
+ // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
+ // just hide it and try with the fallback bundle.
+ .filter(|(_, errs)| errs.is_empty())
+ .or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
+ .map(|(translated, errs)| {
+ // Always bail out for errors with the fallback bundle.
+ assert!(
+ errs.is_empty(),
+ "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+ identifier,
+ attr,
+ args,
+ errs
+ );
+ translated
+ })
+ .expect("failed to find message in primary or fallback fluent bundles")
+ }
+}
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 6e093811f..e1da3ecde 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -6,7 +6,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor};
-use rustc_ast::{self as ast, Attribute, HasAttrs, Item, NodeId, PatKind};
+use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::sync::{self, Lrc};
@@ -71,7 +71,7 @@ impl Annotatable {
}
}
- pub fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
+ pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
match self {
Annotatable::Item(item) => item.visit_attrs(f),
Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f),
@@ -693,10 +693,6 @@ pub struct SyntaxExtension {
pub span: Span,
/// List of unstable features that are treated as stable inside this macro.
pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
- /// Suppresses the `unsafe_code` lint for code produced by this macro.
- pub allow_internal_unsafe: bool,
- /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
- pub local_inner_macros: bool,
/// The macro's stability info.
pub stability: Option<Stability>,
/// The macro's deprecation info.
@@ -708,6 +704,13 @@ pub struct SyntaxExtension {
/// Built-in macros have a couple of special properties like availability
/// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
pub builtin_name: Option<Symbol>,
+ /// Suppresses the `unsafe_code` lint for code produced by this macro.
+ pub allow_internal_unsafe: bool,
+ /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
+ pub local_inner_macros: bool,
+ /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other
+ /// words, was the macro definition annotated with `#[collapse_debuginfo]`)?
+ pub collapse_debuginfo: bool,
}
impl SyntaxExtension {
@@ -729,14 +732,15 @@ impl SyntaxExtension {
SyntaxExtension {
span: DUMMY_SP,
allow_internal_unstable: None,
- allow_internal_unsafe: false,
- local_inner_macros: false,
stability: None,
deprecation: None,
helper_attrs: Vec::new(),
edition,
builtin_name: None,
kind,
+ allow_internal_unsafe: false,
+ local_inner_macros: false,
+ collapse_debuginfo: false,
}
}
@@ -754,12 +758,13 @@ impl SyntaxExtension {
let allow_internal_unstable =
attr::allow_internal_unstable(sess, &attrs).collect::<Vec<Symbol>>();
- let mut local_inner_macros = false;
- if let Some(macro_export) = sess.find_by_name(attrs, sym::macro_export) {
- if let Some(l) = macro_export.meta_item_list() {
- local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
- }
- }
+ let allow_internal_unsafe = sess.contains_name(attrs, sym::allow_internal_unsafe);
+ let local_inner_macros = sess
+ .find_by_name(attrs, sym::macro_export)
+ .and_then(|macro_export| macro_export.meta_item_list())
+ .map_or(false, |l| attr::list_contains_name(&l, sym::local_inner_macros));
+ let collapse_debuginfo = sess.contains_name(attrs, sym::collapse_debuginfo);
+ tracing::debug!(?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
let (builtin_name, helper_attrs) = sess
.find_by_name(attrs, sym::rustc_builtin_macro)
@@ -772,7 +777,7 @@ impl SyntaxExtension {
)
})
.unwrap_or_else(|| (None, helper_attrs));
- let (stability, const_stability) = attr::find_stability(&sess, attrs, span);
+ let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span);
if let Some((_, sp)) = const_stability {
sess.parse_sess
.span_diagnostic
@@ -784,19 +789,31 @@ impl SyntaxExtension {
)
.emit();
}
+ if let Some((_, sp)) = body_stability {
+ sess.parse_sess
+ .span_diagnostic
+ .struct_span_err(sp, "macros cannot have body stability attributes")
+ .span_label(sp, "invalid body stability attribute")
+ .span_label(
+ sess.source_map().guess_head_span(span),
+ "body stability attribute affects this macro",
+ )
+ .emit();
+ }
SyntaxExtension {
kind,
span,
allow_internal_unstable: (!allow_internal_unstable.is_empty())
.then(|| allow_internal_unstable.into()),
- allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe),
- local_inner_macros,
stability: stability.map(|(s, _)| s),
deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
helper_attrs,
edition,
builtin_name,
+ allow_internal_unsafe,
+ local_inner_macros,
+ collapse_debuginfo,
}
}
@@ -841,11 +858,12 @@ impl SyntaxExtension {
call_site,
self.span,
self.allow_internal_unstable.clone(),
- self.allow_internal_unsafe,
- self.local_inner_macros,
self.edition,
macro_def_id,
parent_module,
+ self.allow_internal_unsafe,
+ self.local_inner_macros,
+ self.collapse_debuginfo,
)
}
}
@@ -1216,7 +1234,7 @@ pub fn expr_to_spanned_string<'a>(
);
Some((err, true))
}
- ast::LitKind::Err(_) => None,
+ ast::LitKind::Err => None,
_ => Some((cx.struct_span_err(l.span, err_msg), false)),
},
ast::ExprKind::Err => None,
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index fa3e2a4a5..50d2be3ce 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -3,6 +3,7 @@ use crate::base::ExtCtxt;
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp};
+use rustc_data_structures::sync::Lrc;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -106,14 +107,13 @@ impl<'a> ExtCtxt<'a> {
&self,
span: Span,
ident: Ident,
- attrs: Vec<ast::Attribute>,
bounds: ast::GenericBounds,
default: Option<P<ast::Ty>>,
) -> ast::GenericParam {
ast::GenericParam {
ident: ident.with_span_pos(span),
id: ast::DUMMY_NODE_ID,
- attrs: attrs.into(),
+ attrs: AttrVec::new(),
bounds,
kind: ast::GenericParamKind::Type { default },
is_placeholder: false,
@@ -178,8 +178,7 @@ impl<'a> ExtCtxt<'a> {
ex: P<ast::Expr>,
) -> ast::Stmt {
let pat = if mutbl {
- let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut);
- self.pat_ident_binding_mode(sp, ident, binding_mode)
+ self.pat_ident_binding_mode(sp, ident, ast::BindingAnnotation::MUT)
} else {
self.pat_ident(sp, ident)
};
@@ -330,23 +329,38 @@ impl<'a> ExtCtxt<'a> {
self.expr_struct(span, self.path_ident(span, id), fields)
}
- pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> {
+ fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> {
let lit = ast::Lit::from_lit_kind(lit_kind, span);
self.expr(span, ast::ExprKind::Lit(lit))
}
+
pub fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
self.expr_lit(
span,
ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
)
}
+
pub fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> {
self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32)))
}
+
pub fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> {
self.expr_lit(sp, ast::LitKind::Bool(value))
}
+ pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
+ self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
+ }
+
+ pub fn expr_char(&self, sp: Span, ch: char) -> P<ast::Expr> {
+ self.expr_lit(sp, ast::LitKind::Char(ch))
+ }
+
+ pub fn expr_byte_str(&self, sp: Span, bytes: Vec<u8>) -> P<ast::Expr> {
+ self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes)))
+ }
+
/// `[expr1, expr2, ...]`
pub fn expr_array(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
self.expr(sp, ast::ExprKind::Array(exprs))
@@ -357,10 +371,6 @@ impl<'a> ExtCtxt<'a> {
self.expr_addr_of(sp, self.expr_array(sp, exprs))
}
- pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
- self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
- }
-
pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> {
self.expr(sp, ast::ExprKind::Cast(expr, ty))
}
@@ -434,17 +444,16 @@ impl<'a> ExtCtxt<'a> {
self.pat(span, PatKind::Lit(expr))
}
pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
- let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Not);
- self.pat_ident_binding_mode(span, ident, binding_mode)
+ self.pat_ident_binding_mode(span, ident, ast::BindingAnnotation::NONE)
}
pub fn pat_ident_binding_mode(
&self,
span: Span,
ident: Ident,
- bm: ast::BindingMode,
+ ann: ast::BindingAnnotation,
) -> P<ast::Pat> {
- let pat = PatKind::Ident(bm, ident.with_span_pos(span), None);
+ let pat = PatKind::Ident(ann, ident.with_span_pos(span), None);
self.pat(span, pat)
}
pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> {
@@ -564,7 +573,7 @@ impl<'a> ExtCtxt<'a> {
&self,
span: Span,
name: Ident,
- attrs: Vec<ast::Attribute>,
+ attrs: ast::AttrVec,
kind: ast::ItemKind,
) -> P<ast::Item> {
// FIXME: Would be nice if our generated code didn't violate
@@ -592,7 +601,7 @@ impl<'a> ExtCtxt<'a> {
mutbl: ast::Mutability,
expr: P<ast::Expr>,
) -> P<ast::Item> {
- self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
+ self.item(span, name, AttrVec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
}
pub fn item_const(
@@ -603,11 +612,11 @@ impl<'a> ExtCtxt<'a> {
expr: P<ast::Expr>,
) -> P<ast::Item> {
let def = ast::Defaultness::Final;
- self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr)))
+ self.item(span, name, AttrVec::new(), ast::ItemKind::Const(def, ty, Some(expr)))
}
pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute {
- attr::mk_attr_outer(mi)
+ attr::mk_attr_outer(&self.sess.parse_sess.attr_id_generator, mi)
}
pub fn meta_word(&self, sp: Span, w: Symbol) -> ast::MetaItem {
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 3e1acf438..8d4e36407 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -2,9 +2,9 @@
use rustc_ast::ptr::P;
use rustc_ast::token::{Delimiter, Token, TokenKind};
-use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
+use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree};
use rustc_ast::tokenstream::{DelimSpan, Spacing};
-use rustc_ast::tokenstream::{LazyTokenStream, TokenTree};
+use rustc_ast::tokenstream::{LazyAttrTokenStream, TokenTree};
use rustc_ast::NodeId;
use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem};
use rustc_attr as attr;
@@ -215,7 +215,7 @@ pub fn features(
let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) {
None => {
// The entire crate is unconfigured.
- krate.attrs = Vec::new();
+ krate.attrs = ast::AttrVec::new();
krate.items = Vec::new();
Features::default()
}
@@ -259,27 +259,27 @@ impl<'a> StripUnconfigured<'a> {
fn try_configure_tokens<T: HasTokens>(&self, node: &mut T) {
if self.config_tokens {
if let Some(Some(tokens)) = node.tokens_mut() {
- let attr_annotated_tokens = tokens.create_token_stream();
- *tokens = LazyTokenStream::new(self.configure_tokens(&attr_annotated_tokens));
+ let attr_stream = tokens.to_attr_token_stream();
+ *tokens = LazyAttrTokenStream::new(self.configure_tokens(&attr_stream));
}
}
}
- fn configure_krate_attrs(&self, mut attrs: Vec<ast::Attribute>) -> Option<Vec<ast::Attribute>> {
+ fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
if self.in_cfg(&attrs) { Some(attrs) } else { None }
}
- /// Performs cfg-expansion on `stream`, producing a new `AttrAnnotatedTokenStream`.
+ /// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
/// This is only used during the invocation of `derive` proc-macros,
/// which require that we cfg-expand their entire input.
/// Normal cfg-expansion operates on parsed AST nodes via the `configure` method
- fn configure_tokens(&self, stream: &AttrAnnotatedTokenStream) -> AttrAnnotatedTokenStream {
- fn can_skip(stream: &AttrAnnotatedTokenStream) -> bool {
- stream.0.iter().all(|(tree, _spacing)| match tree {
- AttrAnnotatedTokenTree::Attributes(_) => false,
- AttrAnnotatedTokenTree::Token(_) => true,
- AttrAnnotatedTokenTree::Delimited(_, _, inner) => can_skip(inner),
+ fn configure_tokens(&self, stream: &AttrTokenStream) -> AttrTokenStream {
+ fn can_skip(stream: &AttrTokenStream) -> bool {
+ stream.0.iter().all(|tree| match tree {
+ AttrTokenTree::Attributes(_) => false,
+ AttrTokenTree::Token(..) => true,
+ AttrTokenTree::Delimited(_, _, inner) => can_skip(inner),
})
}
@@ -290,38 +290,36 @@ impl<'a> StripUnconfigured<'a> {
let trees: Vec<_> = stream
.0
.iter()
- .flat_map(|(tree, spacing)| match tree.clone() {
- AttrAnnotatedTokenTree::Attributes(mut data) => {
- let mut attrs: Vec<_> = std::mem::take(&mut data.attrs).into();
- attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
- data.attrs = attrs.into();
+ .flat_map(|tree| match tree.clone() {
+ AttrTokenTree::Attributes(mut data) => {
+ data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
if self.in_cfg(&data.attrs) {
- data.tokens = LazyTokenStream::new(
- self.configure_tokens(&data.tokens.create_token_stream()),
+ data.tokens = LazyAttrTokenStream::new(
+ self.configure_tokens(&data.tokens.to_attr_token_stream()),
);
- Some((AttrAnnotatedTokenTree::Attributes(data), *spacing)).into_iter()
+ Some(AttrTokenTree::Attributes(data)).into_iter()
} else {
None.into_iter()
}
}
- AttrAnnotatedTokenTree::Delimited(sp, delim, mut inner) => {
+ AttrTokenTree::Delimited(sp, delim, mut inner) => {
inner = self.configure_tokens(&inner);
- Some((AttrAnnotatedTokenTree::Delimited(sp, delim, inner), *spacing))
+ Some(AttrTokenTree::Delimited(sp, delim, inner))
.into_iter()
}
- AttrAnnotatedTokenTree::Token(ref token) if let TokenKind::Interpolated(ref nt) = token.kind => {
+ AttrTokenTree::Token(ref token, _) if let TokenKind::Interpolated(ref nt) = token.kind => {
panic!(
"Nonterminal should have been flattened at {:?}: {:?}",
token.span, nt
);
}
- AttrAnnotatedTokenTree::Token(token) => {
- Some((AttrAnnotatedTokenTree::Token(token), *spacing)).into_iter()
+ AttrTokenTree::Token(token, spacing) => {
+ Some(AttrTokenTree::Token(token, spacing)).into_iter()
}
})
.collect();
- AttrAnnotatedTokenStream::new(trees)
+ AttrTokenStream::new(trees)
}
/// Parse and expand all `cfg_attr` attributes into a list of attributes
@@ -390,7 +388,7 @@ impl<'a> StripUnconfigured<'a> {
attr: &Attribute,
(item, item_span): (ast::AttrItem, Span),
) -> Attribute {
- let orig_tokens = attr.tokens().to_tokenstream();
+ let orig_tokens = attr.tokens();
// We are taking an attribute of the form `#[cfg_attr(pred, attr)]`
// and producing an attribute of the form `#[attr]`. We
@@ -406,27 +404,33 @@ impl<'a> StripUnconfigured<'a> {
};
let pound_span = pound_token.span;
- let mut trees = vec![(AttrAnnotatedTokenTree::Token(pound_token), Spacing::Alone)];
+ let mut trees = vec![AttrTokenTree::Token(pound_token, Spacing::Alone)];
if attr.style == AttrStyle::Inner {
// For inner attributes, we do the same thing for the `!` in `#![some_attr]`
let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) = orig_trees.next().unwrap() else {
panic!("Bad tokens for attribute {:?}", attr);
};
- trees.push((AttrAnnotatedTokenTree::Token(bang_token), Spacing::Alone));
+ trees.push(AttrTokenTree::Token(bang_token, Spacing::Alone));
}
// We don't really have a good span to use for the synthesized `[]`
// in `#[attr]`, so just use the span of the `#` token.
- let bracket_group = AttrAnnotatedTokenTree::Delimited(
+ let bracket_group = AttrTokenTree::Delimited(
DelimSpan::from_single(pound_span),
Delimiter::Bracket,
item.tokens
.as_ref()
.unwrap_or_else(|| panic!("Missing tokens for {:?}", item))
- .create_token_stream(),
+ .to_attr_token_stream(),
+ );
+ trees.push(bracket_group);
+ let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees)));
+ let attr = attr::mk_attr_from_item(
+ &self.sess.parse_sess.attr_id_generator,
+ item,
+ tokens,
+ attr.style,
+ item_span,
);
- trees.push((bracket_group, Spacing::Alone));
- let tokens = Some(LazyTokenStream::new(AttrAnnotatedTokenStream::new(trees)));
- let attr = attr::mk_attr_from_item(item, tokens, attr.style, item_span);
if attr.has_name(sym::crate_type) {
self.sess.parse_sess.buffer_lint(
rustc_lint_defs::builtin::DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
new file mode 100644
index 000000000..0feae0deb
--- /dev/null
+++ b/compiler/rustc_expand/src/errors.rs
@@ -0,0 +1,48 @@
+use rustc_macros::SessionDiagnostic;
+use rustc_span::symbol::MacroRulesNormalizedIdent;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::expr_repeat_no_syntax_vars)]
+pub(crate) struct NoSyntaxVarsExprRepeat {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::must_repeat_once)]
+pub(crate) struct MustRepeatOnce {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::count_repetition_misplaced)]
+pub(crate) struct CountRepetitionMisplaced {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::meta_var_expr_unrecognized_var)]
+pub(crate) struct MetaVarExprUnrecognizedVar {
+ #[primary_span]
+ pub span: Span,
+ pub key: MacroRulesNormalizedIdent,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::var_still_repeating)]
+pub(crate) struct VarStillRepeating {
+ #[primary_span]
+ pub span: Span,
+ pub ident: MacroRulesNormalizedIdent,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::meta_var_dif_seq_matchers)]
+pub(crate) struct MetaVarsDifSeqMatchers {
+ #[primary_span]
+ pub span: Span,
+ pub msg: String,
+}
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 93eeca5b2..c2add852a 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -11,7 +11,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
-use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, ExprKind, ForeignItemKind};
+use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, AttrVec, ExprKind, ForeignItemKind};
use rustc_ast::{HasAttrs, HasNodeId};
use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind};
use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
@@ -306,7 +306,7 @@ pub struct Invocation {
pub enum InvocationKind {
Bang {
- mac: ast::MacCall,
+ mac: P<ast::MacCall>,
span: Span,
},
Attr {
@@ -1001,7 +1001,7 @@ enum AddSemicolon {
/// of functionality used by `InvocationCollector`.
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
type OutputTy = SmallVec<[Self; 1]>;
- type AttrsTy: Deref<Target = [ast::Attribute]> = Vec<ast::Attribute>;
+ type AttrsTy: Deref<Target = [ast::Attribute]> = ast::AttrVec;
const KIND: AstFragmentKind;
fn to_annotatable(self) -> Annotatable;
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy;
@@ -1017,7 +1017,7 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
fn is_mac_call(&self) -> bool {
false
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
unreachable!()
}
fn pre_flat_map_node_collect_attr(_cfg: &StripUnconfigured<'_>, _attr: &ast::Attribute) {}
@@ -1046,7 +1046,7 @@ impl InvocationCollectorNode for P<ast::Item> {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ItemKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
ItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1154,7 +1154,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let item = self.wrapped.into_inner();
match item.kind {
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1179,7 +1179,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let item = self.wrapped.into_inner();
match item.kind {
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1202,7 +1202,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ForeignItemKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
ForeignItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1323,7 +1323,7 @@ impl InvocationCollectorNode for ast::Stmt {
StmtKind::Local(..) | StmtKind::Empty => false,
}
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
// We pull macro invocations (both attributes and fn-like macro calls) out of their
// `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
let (add_semicolon, mac, attrs) = match self.kind {
@@ -1333,7 +1333,7 @@ impl InvocationCollectorNode for ast::Stmt {
}
StmtKind::Item(item) => match item.into_inner() {
ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => {
- (mac.args.need_semicolon(), mac, attrs.into())
+ (mac.args.need_semicolon(), mac, attrs)
}
_ => unreachable!(),
},
@@ -1387,10 +1387,10 @@ impl InvocationCollectorNode for P<ast::Ty> {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ast::TyKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
- TyKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No),
+ TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
_ => unreachable!(),
}
}
@@ -1411,10 +1411,10 @@ impl InvocationCollectorNode for P<ast::Pat> {
fn is_mac_call(&self) -> bool {
matches!(self.kind, PatKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
- PatKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No),
+ PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
_ => unreachable!(),
}
}
@@ -1439,7 +1439,7 @@ impl InvocationCollectorNode for P<ast::Expr> {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ExprKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1466,7 +1466,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
}
- fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.wrapped.into_inner();
match node.kind {
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1512,7 +1512,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
}
- fn collect_bang(&mut self, mac: ast::MacCall, kind: AstFragmentKind) -> AstFragment {
+ fn collect_bang(&mut self, mac: P<ast::MacCall>, kind: AstFragmentKind) -> AstFragment {
// cache the macro call span so that it can be
// easily adjusted for incremental compilation
let span = mac.span();
@@ -1646,7 +1646,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) {
node.visit_attrs(|attrs| {
- attrs.splice(pos..pos, self.cfg().expand_cfg_attr(attr, false));
+ // Repeated `insert` calls is inefficient, but the number of
+ // insertions is almost always 0 or 1 in practice.
+ for cfg in self.cfg().expand_cfg_attr(attr, false).into_iter().rev() {
+ attrs.insert(pos, cfg)
+ }
});
}
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 9d0232822..ffc9abe64 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -3,7 +3,7 @@
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(macro_metavar_expr)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
@@ -15,6 +15,9 @@
#[macro_use]
extern crate rustc_macros;
+#[macro_use]
+extern crate tracing;
+
extern crate proc_macro as pm;
mod placeholders;
@@ -26,6 +29,7 @@ pub mod base;
pub mod build;
#[macro_use]
pub mod config;
+pub mod errors;
pub mod expand;
pub mod module;
pub mod proc_macro;
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 4fa91dfea..c8bdc3931 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -430,7 +430,7 @@ impl TtParser {
}
}
MatcherLoc::Delimited => {
- // Entering the delimeter is trivial.
+ // Entering the delimiter is trivial.
mp.idx += 1;
self.cur_mps.push(mp);
}
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index f7e1575af..7764ffd24 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -14,7 +14,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, TransparencyError};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_feature::Features;
use rustc_lint_defs::builtin::{
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
@@ -32,7 +32,6 @@ use rustc_span::Span;
use std::borrow::Cow;
use std::collections::hash_map::Entry;
use std::{mem, slice};
-use tracing::debug;
pub(crate) struct ParserAnyMacro<'a> {
parser: Parser<'a>,
@@ -608,11 +607,7 @@ enum ExplainDocComment {
},
}
-fn annotate_doc_comment(
- err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
- sm: &SourceMap,
- span: Span,
-) {
+fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) {
if let Ok(src) = sm.span_to_snippet(span) {
if src.starts_with("///") || src.starts_with("/**") {
err.subdiagnostic(ExplainDocComment::Outer { span });
@@ -980,7 +975,7 @@ impl<'tt> TokenSet<'tt> {
self.maybe_empty = false;
}
- // Adds `tok` to the set for `self`, marking sequence as non-empy.
+ // Adds `tok` to the set for `self`, marking sequence as non-empty.
fn add_one(&mut self, tt: TtHandle<'tt>) {
if !self.tokens.contains(&tt) {
self.tokens.push(tt);
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index fc808401a..99fe47454 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -112,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_token_lit(*lit)
&& let LitKind::Int(n_u128, LitIntType::Unsuffixed) = lit_kind
&& let Ok(n_usize) = usize::try_from(n_u128)
{
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index e47ea83ac..bec6d1a2d 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -1,4 +1,8 @@
use crate::base::ExtCtxt;
+use crate::errors::{
+ CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce,
+ NoSyntaxVarsExprRepeat, VarStillRepeating,
+};
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch};
use crate::mbe::{self, MetaVarExpr};
use rustc_ast::mut_visit::{self, MutVisitor};
@@ -165,11 +169,7 @@ pub(super) fn transcribe<'a>(
seq @ mbe::TokenTree::Sequence(_, delimited) => {
match lockstep_iter_size(&seq, interp, &repeats) {
LockstepIterSize::Unconstrained => {
- return Err(cx.struct_span_err(
- seq.span(), /* blame macro writer */
- "attempted to repeat an expression containing no syntax variables \
- matched as repeating at this depth",
- ));
+ return Err(cx.create_err(NoSyntaxVarsExprRepeat { span: seq.span() }));
}
LockstepIterSize::Contradiction(msg) => {
@@ -177,7 +177,7 @@ pub(super) fn transcribe<'a>(
// happens when two meta-variables are used in the same repetition in a
// sequence, but they come from different sequence matchers and repeat
// different amounts.
- return Err(cx.struct_span_err(seq.span(), &msg));
+ return Err(cx.create_err(MetaVarsDifSeqMatchers { span: seq.span(), msg }));
}
LockstepIterSize::Constraint(len, _) => {
@@ -193,10 +193,7 @@ pub(super) fn transcribe<'a>(
// FIXME: this really ought to be caught at macro definition
// time... It happens when the Kleene operator in the matcher and
// the body for the same meta-variable do not match.
- return Err(cx.struct_span_err(
- sp.entire(),
- "this must repeat at least once",
- ));
+ return Err(cx.create_err(MustRepeatOnce { span: sp.entire() }));
}
} else {
// 0 is the initial counter (we have done 0 repetitions so far). `len`
@@ -239,10 +236,7 @@ pub(super) fn transcribe<'a>(
}
MatchedSeq(..) => {
// We were unable to descend far enough. This is an error.
- return Err(cx.struct_span_err(
- sp, /* blame the macro writer */
- &format!("variable '{}' is still repeating at this depth", ident),
- ));
+ return Err(cx.create_err(VarStillRepeating { span: sp, ident }));
}
}
} else {
@@ -448,10 +442,7 @@ fn count_repetitions<'a>(
match matched {
MatchedTokenTree(_) | MatchedNonterminal(_) => {
if declared_lhs_depth == 0 {
- return Err(cx.struct_span_err(
- sp.entire(),
- "`count` can not be placed inside the inner-most repetition",
- ));
+ return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
}
match depth_opt {
None => Ok(1),
@@ -499,12 +490,7 @@ where
{
let span = ident.span;
let key = MacroRulesNormalizedIdent::new(ident);
- interp.get(&key).ok_or_else(|| {
- cx.struct_span_err(
- span,
- &format!("variable `{}` is not recognized in meta-variable expression", key),
- )
- })
+ interp.get(&key).ok_or_else(|| cx.create_err(MetaVarExprUnrecognizedVar { span, key }))
}
/// Used by meta-variable expressions when an user input is out of the actual declared bounds. For
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 0315d1163..9002a24e4 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -1,6 +1,6 @@
use crate::base::ModuleData;
use rustc_ast::ptr::P;
-use rustc_ast::{token, Attribute, Inline, Item, ModSpans};
+use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans};
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed};
use rustc_parse::new_parser_from_file;
use rustc_parse::validate_attr;
@@ -48,7 +48,7 @@ pub(crate) fn parse_external_mod(
span: Span, // The span to blame on errors.
module: &ModuleData,
mut dir_ownership: DirOwnership,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
) -> ParsedExternalMod {
// We bail on the first error, but that error does not cause a fatal error... (1)
let result: Result<_, ModError<'_>> = try {
@@ -63,9 +63,9 @@ pub(crate) fn parse_external_mod(
// Actually parse the external file as a module.
let mut parser = new_parser_from_file(&sess.parse_sess, &mp.file_path, Some(span));
- let (mut inner_attrs, items, inner_span) =
+ let (inner_attrs, items, inner_span) =
parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?;
- attrs.append(&mut inner_attrs);
+ attrs.extend(inner_attrs);
(items, inner_span, mp.file_path)
};
// (1) ...instead, we return a dummy module.
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 0d5d6ee07..3b0d5ddb9 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -15,16 +15,16 @@ pub fn placeholder(
id: ast::NodeId,
vis: Option<ast::Visibility>,
) -> AstFragment {
- fn mac_placeholder() -> ast::MacCall {
- ast::MacCall {
+ fn mac_placeholder() -> P<ast::MacCall> {
+ P(ast::MacCall {
path: ast::Path { span: DUMMY_SP, segments: Vec::new(), tokens: None },
args: P(ast::MacArgs::Empty),
prior_type_ascription: None,
- }
+ })
}
let ident = Ident::empty();
- let attrs = Vec::new();
+ let attrs = ast::AttrVec::new();
let vis = vis.unwrap_or(ast::Visibility {
span: DUMMY_SP,
kind: ast::VisibilityKind::Inherited,
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 7d9a4aed0..59a7b668a 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -6,7 +6,7 @@ use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
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_errors::{MultiSpan, PResult};
use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parse_stream_from_source_str;
use rustc_session::parse::ParseSess;
@@ -15,7 +15,7 @@ use rustc_span::symbol::{self, sym, Symbol};
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
use pm::bridge::{
- server, DelimSpan, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
+ server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
};
use pm::{Delimiter, Level, LineColumn};
use std::ops::Bound;
@@ -368,8 +368,6 @@ impl server::Types for Rustc<'_, '_> {
type FreeFunctions = FreeFunctions;
type TokenStream = TokenStream;
type SourceFile = Lrc<SourceFile>;
- type MultiSpan = Vec<Span>;
- type Diagnostic = Diagnostic;
type Span = Span;
type Symbol = Symbol;
}
@@ -436,6 +434,21 @@ impl server::FreeFunctions for Rustc<'_, '_> {
span: self.call_site,
})
}
+
+ fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) {
+ let mut diag =
+ rustc_errors::Diagnostic::new(diagnostic.level.to_internal(), diagnostic.message);
+ diag.set_span(MultiSpan::from_spans(diagnostic.spans));
+ for child in diagnostic.children {
+ diag.sub(
+ child.level.to_internal(),
+ child.message,
+ MultiSpan::from_spans(child.spans),
+ None,
+ );
+ }
+ self.sess().span_diagnostic.emit_diagnostic(&mut diag);
+ }
}
impl server::TokenStream for Rustc<'_, '_> {
@@ -486,20 +499,26 @@ impl server::TokenStream for Rustc<'_, '_> {
// 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) if l.token.kind == token::Bool => Ok(
- tokenstream::TokenStream::token_alone(token::Ident(l.token.symbol, false), l.span),
- ),
+ ast::ExprKind::Lit(l) if l.token_lit.kind == token::Bool => {
+ Ok(tokenstream::TokenStream::token_alone(
+ token::Ident(l.token_lit.symbol, false),
+ l.span,
+ ))
+ }
ast::ExprKind::Lit(l) => {
- Ok(tokenstream::TokenStream::token_alone(token::Literal(l.token), l.span))
+ Ok(tokenstream::TokenStream::token_alone(token::Literal(l.token_lit), l.span))
}
ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind {
- ast::ExprKind::Lit(l) => match l.token {
+ ast::ExprKind::Lit(l) => match l.token_lit {
token::Lit { kind: token::Integer | token::Float, .. } => {
Ok(Self::TokenStream::from_iter([
// FIXME: The span of the `-` token is lost when
// parsing, so we cannot faithfully recover it here.
tokenstream::TokenTree::token_alone(token::BinOp(token::Minus), e.span),
- tokenstream::TokenTree::token_alone(token::Literal(l.token), l.span),
+ tokenstream::TokenTree::token_alone(
+ token::Literal(l.token_lit),
+ l.span,
+ ),
]))
}
_ => Err(()),
@@ -577,38 +596,6 @@ impl server::SourceFile for Rustc<'_, '_> {
}
}
-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)
- }
-}
-
-impl server::Diagnostic for Rustc<'_, '_> {
- fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
- let mut diag = Diagnostic::new(level.to_internal(), msg);
- diag.set_span(MultiSpan::from_spans(spans));
- diag
- }
-
- fn sub(
- &mut self,
- diag: &mut Self::Diagnostic,
- level: Level,
- msg: &str,
- spans: Self::MultiSpan,
- ) {
- 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);
- }
-}
-
impl server::Span for Rustc<'_, '_> {
fn debug(&mut self, span: Self::Span) -> String {
if self.ecx.ecfg.span_debug {
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 099c40b21..8efb7ccc1 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -161,6 +161,8 @@ declare_features! (
(accepted, fn_must_use, "1.27.0", Some(43302), None),
/// Allows capturing variables in scope using format_args!
(accepted, format_args_capture, "1.58.0", Some(67984), None),
+ /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
+ (accepted, generic_associated_types, "1.65.0", Some(44265), None),
/// Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
(accepted, generic_param_attrs, "1.27.0", Some(48848), None),
/// Allows the `#[global_allocator]` attribute.
@@ -186,6 +188,10 @@ declare_features! (
/// Allows some increased flexibility in the name resolution rules,
/// especially around globs and shadowing (RFC 1560).
(accepted, item_like_imports, "1.15.0", Some(35120), None),
+ /// Allows `'a: { break 'a; }`.
+ (accepted, label_break_value, "1.65.0", Some(48594), None),
+ /// Allows `let...else` statements.
+ (accepted, let_else, "1.65.0", Some(87335), None),
/// Allows `break {expr}` with a value inside `loop`s.
(accepted, loop_break_value, "1.19.0", Some(37339), None),
/// Allows use of `?` as the Kleene "at most one" operator in macros.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index ef4a17564..3aecfba5f 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -221,6 +221,8 @@ declare_features! (
(active, rustc_private, "1.0.0", Some(27812), None),
/// Allows using internal rustdoc features like `doc(primitive)` or `doc(keyword)`.
(active, rustdoc_internals, "1.58.0", Some(90418), None),
+ /// Allows using the `rustdoc::missing_doc_code_examples` lint
+ (active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None),
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
(active, start, "1.0.0", Some(29633), None),
/// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
@@ -336,6 +338,8 @@ declare_features! (
(active, closure_track_caller, "1.57.0", Some(87417), None),
/// Allows to use the `#[cmse_nonsecure_entry]` attribute.
(active, cmse_nonsecure_entry, "1.48.0", Some(75835), None),
+ /// Allows use of the `#[collapse_debuginfo]` attribute.
+ (active, collapse_debuginfo, "1.65.0", Some(100758), None),
/// Allows `async {}` expressions in const contexts.
(active, const_async_blocks, "1.53.0", Some(85368), None),
// Allows limiting the evaluation steps of const expressions
@@ -380,6 +384,8 @@ declare_features! (
(active, doc_cfg_hide, "1.57.0", Some(43781), None),
/// Allows `#[doc(masked)]`.
(active, doc_masked, "1.21.0", Some(44027), None),
+ /// Allows `dyn* Trait` objects.
+ (incomplete, dyn_star, "1.65.0", Some(91611), None),
/// Allows `X..Y` patterns.
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),
/// Allows exhaustive pattern matching on types that contain uninhabited types.
@@ -394,12 +400,12 @@ declare_features! (
(active, ffi_returns_twice, "1.34.0", Some(58314), None),
/// Allows using `#[repr(align(...))]` on function items
(active, fn_align, "1.53.0", Some(82232), None),
+ /// Allows generators to be cloned.
+ (active, generator_clone, "1.65.0", Some(95360), None),
/// Allows defining generators.
(active, generators, "1.21.0", Some(43122), None),
/// Infer generic args for both consts and types.
(active, generic_arg_infer, "1.55.0", Some(85077), None),
- /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
- (active, generic_associated_types, "1.23.0", Some(44265), None),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
(incomplete, generic_associated_types_extended, "1.61.0", Some(95451), None),
/// Allows non-trivial generic constants which have to have wfness manually propagated to callers
@@ -420,14 +426,10 @@ declare_features! (
(active, intra_doc_pointers, "1.51.0", Some(80896), None),
/// Allows `#[instruction_set(_)]` attribute
(active, isa_attribute, "1.48.0", Some(74727), None),
- /// Allows `'a: { break 'a; }`.
- (active, label_break_value, "1.28.0", Some(48594), None),
// Allows setting the threshold for the `large_assignments` lint.
(active, large_assignments, "1.52.0", Some(83518), None),
/// Allows `if/while p && let q = r && ...` chains.
(active, let_chains, "1.37.0", Some(53667), None),
- /// Allows `let...else` statements.
- (active, let_else, "1.56.0", Some(87335), None),
/// Allows `#[link(..., cfg(..))]`.
(active, link_cfg, "1.14.0", Some(37406), None),
/// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
@@ -480,17 +482,17 @@ declare_features! (
/// Allows macro attributes on expressions, statements and non-inline modules.
(active, proc_macro_hygiene, "1.30.0", Some(54727), None),
/// Allows the use of raw-dylibs (RFC 2627).
- (incomplete, raw_dylib, "1.40.0", Some(58713), None),
+ (active, raw_dylib, "1.65.0", Some(58713), None),
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
(active, raw_ref_op, "1.41.0", Some(64490), None),
- /// Allows using the `#[register_attr]` attribute.
- (active, register_attr, "1.41.0", Some(66080), None),
/// Allows using the `#[register_tool]` attribute.
(active, register_tool, "1.41.0", Some(66079), None),
/// Allows the `#[repr(i128)]` attribute for enums.
(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 return-position `impl Trait` in traits.
+ (incomplete, return_position_impl_trait_in_trait, "1.65.0", Some(91611), 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.
@@ -523,6 +525,8 @@ declare_features! (
/// Allows creation of instances of a struct by moving fields that have
/// not changed from prior instances of the same struct (RFC #2528)
(active, type_changing_struct_update, "1.58.0", Some(86555), None),
+ /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
+ (active, unix_sigpipe, "1.65.0", Some(97889), 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 0e73d8fd7..b50c972e6 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -277,7 +277,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing),
ungated!(
should_panic, Normal,
- template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"), FutureWarnFollowing,
+ template!(Word, List: r#"expected = "reason""#, NameValueStr: "reason"), FutureWarnFollowing,
),
// FIXME(Centril): This can be used on stable but shouldn't.
ungated!(reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing),
@@ -335,7 +335,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// ABI, linking, symbols, and FFI
ungated!(
link, Normal,
- template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...""#),
+ template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#),
DuplicatesOk,
),
ungated!(link_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
@@ -345,6 +345,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
ungated!(no_mangle, Normal, template!(Word), WarnFollowing, @only_local: true),
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, @only_local: true),
+ ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding),
// Limits:
ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
@@ -359,6 +360,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
// Entry point:
+ gated!(unix_sigpipe, Normal, template!(Word, NameValueStr: "inherit|sig_ign|sig_dfl"), ErrorFollowing, experimental!(unix_sigpipe)),
ungated!(start, Normal, template!(Word), WarnFollowing),
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing),
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing),
@@ -405,10 +407,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Linking:
gated!(naked, Normal, template!(Word), WarnFollowing, @only_local: true, naked_functions, experimental!(naked)),
- gated!(
- link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, raw_dylib,
- experimental!(link_ordinal)
- ),
// Plugins:
BuiltinAttribute {
@@ -459,10 +457,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
gated!(ffi_pure, Normal, template!(Word), WarnFollowing, experimental!(ffi_pure)),
gated!(ffi_const, Normal, template!(Word), WarnFollowing, experimental!(ffi_const)),
gated!(
- register_attr, CrateLevel, template!(List: "attr1, attr2, ..."), DuplicatesOk,
- experimental!(register_attr),
- ),
- gated!(
register_tool, CrateLevel, template!(List: "tool1, tool2, ..."), DuplicatesOk,
experimental!(register_tool),
),
@@ -484,6 +478,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
experimental!(deprecated_safe),
),
+ // `#[collapse_debuginfo]`
+ gated!(
+ collapse_debuginfo, Normal, template!(Word), WarnFollowing,
+ experimental!(collapse_debuginfo)
+ ),
+
// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
// ==========================================================================
@@ -499,6 +499,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
+ ungated!(
+ rustc_default_body_unstable, Normal,
+ template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk
+ ),
gated!(
allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), DuplicatesOk,
"allow_internal_unstable side-steps feature gating and stability checks",
@@ -758,6 +762,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Internal attributes, Testing:
// ==========================================================================
+ rustc_attr!(TEST, rustc_access_level, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_outlives, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing),
@@ -821,6 +826,14 @@ pub fn is_builtin_only_local(name: Symbol) -> bool {
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local)
}
+pub fn is_valid_for_get_attr(name: Symbol) -> bool {
+ BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| match attr.duplicates {
+ WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
+ | FutureWarnPreceding => true,
+ DuplicatesOk | WarnFollowingWordOnly => false,
+ })
+}
+
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
LazyLock::new(|| {
let mut map = FxHashMap::default();
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index efb830527..bdaa0ee88 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -12,6 +12,8 @@
//! symbol to the `accepted` or `removed` modules respectively.
#![feature(once_cell)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
mod accepted;
mod active;
@@ -149,7 +151,7 @@ pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
pub use builtin_attrs::AttributeDuplicates;
pub use builtin_attrs::{
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
- AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg,
- BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
+ is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
+ GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
};
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 2ddaf9201..79a12801d 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -163,6 +163,9 @@ declare_features! (
(removed, quad_precision_float, "1.0.0", None, None, None),
(removed, quote, "1.33.0", Some(29601), None, None),
(removed, reflect, "1.0.0", Some(27749), None, None),
+ /// Allows using the `#[register_attr]` attribute.
+ (removed, register_attr, "1.65.0", Some(66080), None,
+ Some("removed in favor of `#![register_tool]`")),
/// Allows using the macros:
/// + `__diagnostic_used`
/// + `__register_diagnostic`
diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs
index 87e97c746..63998bb6b 100644
--- a/compiler/rustc_fs_util/src/lib.rs
+++ b/compiler/rustc_fs_util/src/lib.rs
@@ -1,3 +1,6 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
use std::ffi::CString;
use std::fs;
use std::io;
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index 6eaff5c2f..3c1bb5532 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -273,6 +273,8 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
use LabelText::*;
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index be5b7eccb..e7c26bd72 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -45,8 +45,6 @@ pub enum NonMacroAttrKind {
/// Single-segment custom attribute registered by a derive macro
/// but used before that derive macro was expanded (deprecated).
DeriveHelperCompat,
- /// Single-segment custom attribute registered with `#[register_attr]`.
- Registered,
}
/// What kind of definition something is; e.g., `mod` vs `struct`.
@@ -111,6 +109,8 @@ pub enum DefKind {
InlineConst,
/// Opaque type, aka `impl Trait`.
OpaqueTy,
+ /// A return-position `impl Trait` in a trait definition
+ ImplTraitPlaceholder,
Field,
/// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
LifetimeParam,
@@ -140,6 +140,7 @@ impl DefKind {
panic!("impossible struct constructor")
}
DefKind::OpaqueTy => "opaque type",
+ DefKind::ImplTraitPlaceholder => "opaque type in trait",
DefKind::TyAlias => "type alias",
DefKind::TraitAlias => "trait alias",
DefKind::AssocTy => "associated type",
@@ -219,7 +220,8 @@ impl DefKind {
| DefKind::Use
| DefKind::ForeignMod
| DefKind::GlobalAsm
- | DefKind::Impl => None,
+ | DefKind::Impl
+ | DefKind::ImplTraitPlaceholder => None,
}
}
@@ -256,6 +258,7 @@ impl DefKind {
| DefKind::Use
| DefKind::ForeignMod
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Impl
| DefKind::Field
| DefKind::TyParam
@@ -310,6 +313,7 @@ pub enum Res<Id = hir::HirId> {
///
/// **Belongs to the type namespace.**
PrimTy(hir::PrimTy),
+
/// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
/// optionally with the [`DefId`] of the item introducing the `Self` type alias.
///
@@ -357,7 +361,8 @@ pub enum Res<Id = hir::HirId> {
/// const fn baz<T>() -> usize { 10 }
/// ```
/// We do however allow `Self` in repeat expression even if it is generic to not break code
- /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint:
+ /// which already works on stable while causing the `const_evaluatable_unchecked` future compat
+ /// lint:
/// ```
/// fn foo<T>() {
/// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
@@ -372,6 +377,7 @@ pub enum Res<Id = hir::HirId> {
/// from mentioning generics (i.e. when used in an anonymous constant).
alias_to: Option<(DefId, bool)>,
},
+
/// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
///
/// **Belongs to the type namespace.**
@@ -385,6 +391,7 @@ pub enum Res<Id = hir::HirId> {
///
/// *See also [`Res::SelfTy`].*
SelfCtor(DefId),
+
/// A local variable or function parameter.
///
/// **Belongs to the value namespace.**
@@ -455,7 +462,7 @@ impl PartialRes {
/// Different kinds of symbols can coexist even if they share the same textual name.
/// Therefore, they each have a separate universe (known as a "namespace").
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Namespace {
/// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
/// (and, by extension, crates).
@@ -564,15 +571,11 @@ impl NonMacroAttrKind {
NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
"derive helper attribute"
}
- NonMacroAttrKind::Registered => "explicitly registered attribute",
}
}
pub fn article(self) -> &'static str {
- match self {
- NonMacroAttrKind::Registered => "an",
- _ => "a",
- }
+ "a"
}
/// Users of some attributes cannot mark them as used, so they are considered always used.
@@ -581,7 +584,7 @@ impl NonMacroAttrKind {
NonMacroAttrKind::Tool
| NonMacroAttrKind::DeriveHelper
| NonMacroAttrKind::DeriveHelperCompat => true,
- NonMacroAttrKind::Builtin(..) | NonMacroAttrKind::Registered => false,
+ NonMacroAttrKind::Builtin(..) => false,
}
}
}
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index c2c551e78..d85ac960f 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -15,7 +15,6 @@ use rustc_span::symbol::{kw, sym, Symbol};
use std::fmt::{self, Write};
use std::hash::Hash;
-use tracing::debug;
/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
diff --git a/compiler/rustc_hir/src/errors.rs b/compiler/rustc_hir/src/errors.rs
new file mode 100644
index 000000000..e593ed104
--- /dev/null
+++ b/compiler/rustc_hir/src/errors.rs
@@ -0,0 +1,10 @@
+use crate::LangItem;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
+pub struct LangItemError(pub LangItem);
+
+impl ToString for LangItemError {
+ fn to_string(&self) -> String {
+ format!("requires `{}` lang_item", self.0.name())
+ }
+}
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 617433a98..a8436ea64 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -7,7 +7,7 @@ use crate::LangItem;
use rustc_ast as ast;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
-pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
+pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::fingerprint::Fingerprint;
@@ -139,11 +139,10 @@ impl LifetimeName {
match self {
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
- // 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
- // equivalently to "some fresh name". They correspond to
- // early-bound regions on an impl, in other words.
+ // 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 equivalently to "some fresh name".
+ // They correspond to early-bound regions on an impl, in other words.
LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
}
}
@@ -202,13 +201,8 @@ impl Path<'_> {
pub struct PathSegment<'hir> {
/// The identifier portion of this path segment.
pub ident: Ident,
- // `id` and `res` are optional. We currently only use these in save-analysis,
- // any path segments without these will not have save-analysis info and
- // therefore will not have 'jump to def' in IDEs, but otherwise will not be
- // affected. (In general, we don't bother to get the defs for synthesized
- // segments, only for segments which have come from the AST).
- pub hir_id: Option<HirId>,
- pub res: Option<Res>,
+ pub hir_id: HirId,
+ pub res: Res,
/// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
@@ -226,12 +220,12 @@ pub struct PathSegment<'hir> {
impl<'hir> PathSegment<'hir> {
/// Converts an identifier to the corresponding segment.
- pub fn from_ident(ident: Ident) -> PathSegment<'hir> {
- PathSegment { ident, hir_id: None, res: None, infer_args: true, args: None }
+ pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
+ PathSegment { ident, hir_id, res, infer_args: true, args: None }
}
pub fn invalid() -> Self {
- Self::from_ident(Ident::empty())
+ Self::new(Ident::empty(), HirId::INVALID, Res::Err)
}
pub fn args(&self) -> &GenericArgs<'hir> {
@@ -264,8 +258,8 @@ impl InferArg {
#[derive(Debug, HashStable_Generic)]
pub enum GenericArg<'hir> {
- Lifetime(Lifetime),
- Type(Ty<'hir>),
+ Lifetime(&'hir Lifetime),
+ Type(&'hir Ty<'hir>),
Const(ConstArg),
Infer(InferArg),
}
@@ -280,7 +274,7 @@ impl GenericArg<'_> {
}
}
- pub fn id(&self) -> HirId {
+ pub fn hir_id(&self) -> HirId {
match self {
GenericArg::Lifetime(l) => l.hir_id,
GenericArg::Type(t) => t.hir_id,
@@ -305,9 +299,9 @@ impl GenericArg<'_> {
pub fn to_ord(&self) -> ast::ParamKindOrd {
match self {
GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
- GenericArg::Type(_) => ast::ParamKindOrd::Type,
- GenericArg::Const(_) => ast::ParamKindOrd::Const,
- GenericArg::Infer(_) => ast::ParamKindOrd::Infer,
+ GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
+ ast::ParamKindOrd::TypeOrConst
+ }
}
}
@@ -435,7 +429,7 @@ pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
- Outlives(Lifetime),
+ Outlives(&'hir Lifetime),
}
impl GenericBound<'_> {
@@ -581,8 +575,7 @@ impl<'hir> Generics<'hir> {
if self.has_where_clause_predicates {
self.predicates
.iter()
- .filter(|p| p.in_where_clause())
- .last()
+ .rfind(|&p| p.in_where_clause())
.map_or(end, |p| p.span())
.shrink_to_hi()
.to(end)
@@ -761,7 +754,7 @@ impl<'hir> WhereBoundPredicate<'hir> {
pub struct WhereRegionPredicate<'hir> {
pub span: Span,
pub in_where_clause: bool,
- pub lifetime: Lifetime,
+ pub lifetime: &'hir Lifetime,
pub bounds: GenericBounds<'hir>,
}
@@ -778,7 +771,6 @@ impl<'hir> WhereRegionPredicate<'hir> {
/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Debug, HashStable_Generic)]
pub struct WhereEqPredicate<'hir> {
- pub hir_id: HirId,
pub span: Span,
pub lhs_ty: &'hir Ty<'hir>,
pub rhs_ty: &'hir Ty<'hir>,
@@ -841,7 +833,16 @@ impl<'tcx> OwnerNodes<'tcx> {
impl fmt::Debug for OwnerNodes<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnerNodes")
+ // Do not print all the pointers to all the nodes, as it would be unreadable.
.field("node", &self.nodes[ItemLocalId::from_u32(0)])
+ .field(
+ "parents",
+ &self
+ .nodes
+ .iter_enumerated()
+ .map(|(id, parented_node)| (id, parented_node.as_ref().map(|node| node.parent)))
+ .collect::<Vec<_>>(),
+ )
.field("bodies", &self.bodies)
.field("local_id_to_def_id", &self.local_id_to_def_id)
.field("hash_without_bodies", &self.hash_without_bodies)
@@ -1050,30 +1051,6 @@ pub struct PatField<'hir> {
pub span: Span,
}
-/// Explicit binding annotations given in the HIR for a binding. Note
-/// that this is not the final binding *mode* that we infer after type
-/// inference.
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
-pub enum BindingAnnotation {
- /// No binding annotation given: this means that the final binding mode
- /// will depend on whether we have skipped through a `&` reference
- /// when matching. For example, the `x` in `Some(x)` will have binding
- /// mode `None`; if you do `let Some(x) = &Some(22)`, it will
- /// ultimately be inferred to be by-reference.
- ///
- /// Note that implicit reference skipping is not implemented yet (#42640).
- Unannotated,
-
- /// Annotated with `mut x` -- could be either ref or not, similar to `None`.
- Mutable,
-
- /// Annotated as `ref`, like `ref x`
- Ref,
-
- /// Annotated as `ref mut x`.
- RefMut,
-}
-
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum RangeEnd {
Included,
@@ -1089,6 +1066,35 @@ impl fmt::Display for RangeEnd {
}
}
+// Equivalent to `Option<usize>`. That type takes up 16 bytes on 64-bit, but
+// this type only takes up 4 bytes, at the cost of being restricted to a
+// maximum value of `u32::MAX - 1`. In practice, this is more than enough.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
+pub struct DotDotPos(u32);
+
+impl DotDotPos {
+ // Panics if n >= u32::MAX.
+ pub fn new(n: Option<usize>) -> Self {
+ match n {
+ Some(n) => {
+ assert!(n < u32::MAX as usize);
+ Self(n as u32)
+ }
+ None => Self(u32::MAX),
+ }
+ }
+
+ pub fn as_opt_usize(&self) -> Option<usize> {
+ if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
+ }
+}
+
+impl fmt::Debug for DotDotPos {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.as_opt_usize().fmt(f)
+ }
+}
+
#[derive(Debug, HashStable_Generic)]
pub enum PatKind<'hir> {
/// Represents a wildcard pattern (i.e., `_`).
@@ -1105,9 +1111,9 @@ pub enum PatKind<'hir> {
Struct(QPath<'hir>, &'hir [PatField<'hir>], bool),
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
- /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
+ /// If the `..` pattern fragment is present, then `DotDotPos` denotes its position.
/// `0 <= position <= subpats.len()`
- TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], Option<usize>),
+ TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
@@ -1119,7 +1125,7 @@ pub enum PatKind<'hir> {
/// A tuple pattern (e.g., `(a, b)`).
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// `0 <= position <= subpats.len()`
- Tuple(&'hir [Pat<'hir>], Option<usize>),
+ Tuple(&'hir [Pat<'hir>], DotDotPos),
/// A `box` pattern.
Box(&'hir Pat<'hir>),
@@ -1322,7 +1328,7 @@ pub enum StmtKind<'hir> {
Semi(&'hir Expr<'hir>),
}
-/// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
+/// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`).
#[derive(Debug, HashStable_Generic)]
pub struct Local<'hir> {
pub pat: &'hir Pat<'hir>,
@@ -1439,7 +1445,7 @@ pub struct BodyId {
#[derive(Debug, HashStable_Generic)]
pub struct Body<'hir> {
pub params: &'hir [Param<'hir>],
- pub value: Expr<'hir>,
+ pub value: &'hir Expr<'hir>,
pub generator_kind: Option<GeneratorKind>,
}
@@ -1626,7 +1632,7 @@ pub struct AnonConst {
}
/// An expression.
-#[derive(Debug)]
+#[derive(Debug, HashStable_Generic)]
pub struct Expr<'hir> {
pub hir_id: HirId,
pub kind: ExprKind<'hir>,
@@ -1882,11 +1888,11 @@ pub enum ExprKind<'hir> {
///
/// The `PathSegment` represents the method name and its generic arguments
/// (within the angle brackets).
- /// The first element of the `&[Expr]` is the expression that evaluates
+ /// The `&Expr` is the expression that evaluates
/// to the object on which the method is being called on (the receiver),
- /// and the remaining elements are the rest of the arguments.
+ /// and the `&[Expr]` is the rest of the arguments.
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
- /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d], span)`.
+ /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d], span)`.
/// The final `Span` represents the span of the function and arguments
/// (e.g. `foo::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(a, b, c, d)`
///
@@ -1894,7 +1900,7 @@ pub enum ExprKind<'hir> {
/// the `hir_id` of the `MethodCall` node itself.
///
/// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id
- MethodCall(&'hir PathSegment<'hir>, &'hir [Expr<'hir>], Span),
+ MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(&'hir [Expr<'hir>]),
/// A binary operation (e.g., `a + b`, `a * b`).
@@ -2380,7 +2386,7 @@ impl TypeBinding<'_> {
}
}
-#[derive(Debug)]
+#[derive(Debug, HashStable_Generic)]
pub struct Ty<'hir> {
pub hir_id: HirId,
pub kind: TyKind<'hir>,
@@ -2402,6 +2408,14 @@ impl<'hir> Ty<'hir> {
_ => None,
}
}
+
+ pub fn peel_refs(&self) -> &Self {
+ let mut final_ty = self;
+ while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
+ final_ty = &ty;
+ }
+ final_ty
+ }
}
/// Not represented directly in the AST; referred to by name through a `ty_path`.
@@ -2506,6 +2520,7 @@ pub struct OpaqueTy<'hir> {
pub generics: &'hir Generics<'hir>,
pub bounds: GenericBounds<'hir>,
pub origin: OpaqueTyOrigin,
+ pub in_trait: bool,
}
/// From whence the opaque type came.
@@ -2529,7 +2544,7 @@ pub enum TyKind<'hir> {
/// A raw pointer (i.e., `*const T` or `*mut T`).
Ptr(MutTy<'hir>),
/// A reference (i.e., `&'a T` or `&'a mut T`).
- Rptr(Lifetime, MutTy<'hir>),
+ Rptr(&'hir Lifetime, MutTy<'hir>),
/// A bare function (e.g., `fn(usize) -> bool`).
BareFn(&'hir BareFnTy<'hir>),
/// The never type (`!`).
@@ -2545,10 +2560,12 @@ pub enum TyKind<'hir> {
///
/// The generic argument list contains the lifetimes (and in the future
/// possibly parameters) that are actually bound on the `impl Trait`.
- OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
+ ///
+ /// The last parameter specifies whether this opaque appears in a trait definition.
+ OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
- TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime, TraitObjectSyntax),
+ TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
/// Unused for now.
Typeof(AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been
@@ -2562,23 +2579,23 @@ pub enum TyKind<'hir> {
pub enum InlineAsmOperand<'hir> {
In {
reg: InlineAsmRegOrRegClass,
- expr: Expr<'hir>,
+ expr: &'hir Expr<'hir>,
},
Out {
reg: InlineAsmRegOrRegClass,
late: bool,
- expr: Option<Expr<'hir>>,
+ expr: Option<&'hir Expr<'hir>>,
},
InOut {
reg: InlineAsmRegOrRegClass,
late: bool,
- expr: Expr<'hir>,
+ expr: &'hir Expr<'hir>,
},
SplitInOut {
reg: InlineAsmRegOrRegClass,
late: bool,
- in_expr: Expr<'hir>,
- out_expr: Option<Expr<'hir>>,
+ in_expr: &'hir Expr<'hir>,
+ out_expr: Option<&'hir Expr<'hir>>,
},
Const {
anon_const: AnonConst,
@@ -2643,7 +2660,7 @@ pub struct FnDecl<'hir> {
}
/// Represents what type of implicit self a function has, if any.
-#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum ImplicitSelfKind {
/// Represents a `fn x(self);`.
Imm,
@@ -2992,7 +3009,7 @@ pub enum ItemKind<'hir> {
/// A MBE macro definition (`macro_rules!` or `macro`).
Macro(ast::MacroDef, MacroKind),
/// A module.
- Mod(Mod<'hir>),
+ Mod(&'hir Mod<'hir>),
/// An external module, e.g. `extern { .. }`.
ForeignMod { abi: Abi, items: &'hir [ForeignItemRef] },
/// Module-level inline assembly (from `global_asm!`).
@@ -3217,7 +3234,7 @@ impl<'hir> OwnerNode<'hir> {
}
}
- pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> {
+ pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
match self {
OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
| OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
@@ -3332,12 +3349,14 @@ pub enum Node<'hir> {
Field(&'hir FieldDef<'hir>),
AnonConst(&'hir AnonConst),
Expr(&'hir Expr<'hir>),
+ ExprField(&'hir ExprField<'hir>),
Stmt(&'hir Stmt<'hir>),
PathSegment(&'hir PathSegment<'hir>),
Ty(&'hir Ty<'hir>),
TypeBinding(&'hir TypeBinding<'hir>),
TraitRef(&'hir TraitRef<'hir>),
Pat(&'hir Pat<'hir>),
+ PatField(&'hir PatField<'hir>),
Arm(&'hir Arm<'hir>),
Block(&'hir Block<'hir>),
Local(&'hir Local<'hir>),
@@ -3388,6 +3407,8 @@ impl<'hir> Node<'hir> {
| Node::Block(..)
| Node::Ctor(..)
| Node::Pat(..)
+ | Node::PatField(..)
+ | Node::ExprField(..)
| Node::Arm(..)
| Node::Local(..)
| Node::Crate(..)
@@ -3397,19 +3418,20 @@ impl<'hir> Node<'hir> {
}
}
- pub fn fn_decl(&self) -> Option<&'hir FnDecl<'hir>> {
+ pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
match self {
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
- Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
+ Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
+ | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
Some(fn_decl)
}
_ => None,
}
}
- pub fn fn_sig(&self) -> Option<&'hir FnSig<'hir>> {
+ pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
match self {
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
@@ -3491,16 +3513,37 @@ impl<'hir> Node<'hir> {
mod size_asserts {
use super::*;
// These are in alphabetical order, which is easy to maintain.
- rustc_data_structures::static_assert_size!(Block<'static>, 48);
- rustc_data_structures::static_assert_size!(Expr<'static>, 56);
- rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72);
- rustc_data_structures::static_assert_size!(GenericBound<'_>, 48);
- rustc_data_structures::static_assert_size!(Generics<'static>, 56);
- rustc_data_structures::static_assert_size!(ImplItem<'static>, 88);
- rustc_data_structures::static_assert_size!(Impl<'static>, 80);
- rustc_data_structures::static_assert_size!(Item<'static>, 80);
- rustc_data_structures::static_assert_size!(Pat<'static>, 88);
- rustc_data_structures::static_assert_size!(QPath<'static>, 24);
- rustc_data_structures::static_assert_size!(TraitItem<'static>, 96);
- rustc_data_structures::static_assert_size!(Ty<'static>, 72);
+ static_assert_size!(Block<'_>, 48);
+ static_assert_size!(Body<'_>, 32);
+ static_assert_size!(Expr<'_>, 64);
+ static_assert_size!(ExprKind<'_>, 48);
+ static_assert_size!(FnDecl<'_>, 40);
+ static_assert_size!(ForeignItem<'_>, 72);
+ static_assert_size!(ForeignItemKind<'_>, 40);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(GenericArg<'_>, 24);
+ static_assert_size!(GenericBound<'_>, 48);
+ static_assert_size!(Generics<'_>, 56);
+ static_assert_size!(Impl<'_>, 80);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(ImplItem<'_>, 80);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(ImplItemKind<'_>, 32);
+ static_assert_size!(Item<'_>, 80);
+ static_assert_size!(ItemKind<'_>, 48);
+ static_assert_size!(Local<'_>, 64);
+ static_assert_size!(Param<'_>, 32);
+ static_assert_size!(Pat<'_>, 72);
+ static_assert_size!(PatKind<'_>, 48);
+ static_assert_size!(Path<'_>, 48);
+ static_assert_size!(PathSegment<'_>, 56);
+ static_assert_size!(QPath<'_>, 24);
+ static_assert_size!(Stmt<'_>, 32);
+ static_assert_size!(StmtKind<'_>, 16);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(TraitItem<'_>, 88);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(TraitItemKind<'_>, 48);
+ static_assert_size!(Ty<'_>, 48);
+ static_assert_size!(TyKind<'_>, 32);
}
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index 346ac9e96..84b0740c7 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -20,6 +20,9 @@ pub struct HirId {
}
impl HirId {
+ /// Signal local id which should never be used.
+ pub const INVALID: HirId = HirId { owner: CRATE_DEF_ID, local_id: ItemLocalId::INVALID };
+
#[inline]
pub fn expect_owner(self) -> LocalDefId {
assert_eq!(self.local_id.index(), 0);
@@ -64,8 +67,13 @@ impl PartialOrd for HirId {
}
}
-rustc_data_structures::define_id_collections!(HirIdMap, HirIdSet, HirId);
-rustc_data_structures::define_id_collections!(ItemLocalMap, ItemLocalSet, ItemLocalId);
+rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
+rustc_data_structures::define_id_collections!(
+ ItemLocalMap,
+ ItemLocalSet,
+ ItemLocalMapEntry,
+ ItemLocalId
+);
rustc_index::newtype_index! {
/// An `ItemLocalId` uniquely identifies something within a given "item-like";
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index e676acebe..8f5f314ec 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -298,7 +298,7 @@ pub trait Visitor<'v>: Sized {
fn visit_id(&mut self, _hir_id: HirId) {
// Nothing to do.
}
- fn visit_name(&mut self, _span: Span, _name: Symbol) {
+ fn visit_name(&mut self, _name: Symbol) {
// Nothing to do.
}
fn visit_ident(&mut self, ident: Ident) {
@@ -325,6 +325,9 @@ pub trait Visitor<'v>: Sized {
fn visit_pat(&mut self, p: &'v Pat<'v>) {
walk_pat(self, p)
}
+ fn visit_pat_field(&mut self, f: &'v PatField<'v>) {
+ walk_pat_field(self, f)
+ }
fn visit_array_length(&mut self, len: &'v ArrayLen) {
walk_array_len(self, len)
}
@@ -337,6 +340,9 @@ pub trait Visitor<'v>: Sized {
fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
walk_let_expr(self, lex)
}
+ fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
+ walk_expr_field(self, field)
+ }
fn visit_ty(&mut self, t: &'v Ty<'v>) {
walk_ty(self, t)
}
@@ -355,8 +361,8 @@ pub trait Visitor<'v>: Sized {
fn visit_fn_decl(&mut self, fd: &'v FnDecl<'v>) {
walk_fn_decl(self, fd)
}
- fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl<'v>, b: BodyId, s: Span, id: HirId) {
- walk_fn(self, fk, fd, b, s, id)
+ fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl<'v>, b: BodyId, _: Span, id: HirId) {
+ walk_fn(self, fk, fd, b, id)
}
fn visit_use(&mut self, path: &'v Path<'v>, hir_id: HirId) {
walk_use(self, path, hir_id)
@@ -382,33 +388,20 @@ pub trait Visitor<'v>: Sized {
fn visit_param_bound(&mut self, bounds: &'v GenericBound<'v>) {
walk_param_bound(self, bounds)
}
- fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>, m: TraitBoundModifier) {
- walk_poly_trait_ref(self, t, m)
- }
- fn visit_variant_data(
- &mut self,
- s: &'v VariantData<'v>,
- _: Symbol,
- _: &'v Generics<'v>,
- _parent_id: HirId,
- _: Span,
- ) {
+ fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) {
+ walk_poly_trait_ref(self, t)
+ }
+ fn visit_variant_data(&mut self, s: &'v VariantData<'v>) {
walk_struct_def(self, s)
}
fn visit_field_def(&mut self, s: &'v FieldDef<'v>) {
walk_field_def(self, s)
}
- fn visit_enum_def(
- &mut self,
- enum_definition: &'v EnumDef<'v>,
- generics: &'v Generics<'v>,
- item_id: HirId,
- _: Span,
- ) {
- walk_enum_def(self, enum_definition, generics, item_id)
+ fn visit_enum_def(&mut self, enum_definition: &'v EnumDef<'v>, item_id: HirId) {
+ walk_enum_def(self, enum_definition, item_id)
}
- fn visit_variant(&mut self, v: &'v Variant<'v>, g: &'v Generics<'v>, item_id: HirId) {
- walk_variant(self, v, g, item_id)
+ fn visit_variant(&mut self, v: &'v Variant<'v>) {
+ walk_variant(self, v)
}
fn visit_label(&mut self, label: &'v Label) {
walk_label(self, label)
@@ -427,17 +420,18 @@ pub trait Visitor<'v>: Sized {
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
walk_lifetime(self, lifetime)
}
- fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, span: Span) {
- walk_qpath(self, qpath, id, span)
+ // The span is that of the surrounding type/pattern/expr/whatever.
+ fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) {
+ walk_qpath(self, qpath, id)
}
fn visit_path(&mut self, path: &'v Path<'v>, _id: HirId) {
walk_path(self, path)
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment<'v>) {
- walk_path_segment(self, path_span, path_segment)
+ fn visit_path_segment(&mut self, path_segment: &'v PathSegment<'v>) {
+ walk_path_segment(self, path_segment)
}
- fn visit_generic_args(&mut self, path_span: Span, generic_args: &'v GenericArgs<'v>) {
- walk_generic_args(self, path_span, generic_args)
+ fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) {
+ walk_generic_args(self, generic_args)
}
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding<'v>) {
walk_assoc_type_binding(self, type_binding)
@@ -479,7 +473,7 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
}
pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) {
- visitor.visit_name(ident.span, ident.name);
+ visitor.visit_name(ident.name);
}
pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
@@ -501,11 +495,7 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
}
}
-pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
- visitor: &mut V,
- trait_ref: &'v PolyTraitRef<'v>,
- _modifier: TraitBoundModifier,
-) {
+pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>) {
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
visitor.visit_trait_ref(&trait_ref.trait_ref);
}
@@ -526,7 +516,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
ItemKind::ExternCrate(orig_name) => {
visitor.visit_id(item.hir_id());
if let Some(orig_name) = orig_name {
- visitor.visit_name(item.span, orig_name);
+ visitor.visit_name(orig_name);
}
}
ItemKind::Use(ref path, _) => {
@@ -572,7 +562,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
ItemKind::Enum(ref enum_definition, ref generics) => {
visitor.visit_generics(generics);
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
- visitor.visit_enum_def(enum_definition, generics, item.hir_id(), item.span)
+ visitor.visit_enum_def(enum_definition, item.hir_id())
}
ItemKind::Impl(Impl {
unsafety: _,
@@ -595,13 +585,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
| ItemKind::Union(ref struct_definition, ref generics) => {
visitor.visit_generics(generics);
visitor.visit_id(item.hir_id());
- visitor.visit_variant_data(
- struct_definition,
- item.ident.name,
- generics,
- item.hir_id(),
- item.span,
- );
+ visitor.visit_variant_data(struct_definition);
}
ItemKind::Trait(.., ref generics, bounds, trait_item_refs) => {
visitor.visit_id(item.hir_id());
@@ -649,28 +633,16 @@ pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id:
pub fn walk_enum_def<'v, V: Visitor<'v>>(
visitor: &mut V,
enum_definition: &'v EnumDef<'v>,
- generics: &'v Generics<'v>,
item_id: HirId,
) {
visitor.visit_id(item_id);
- walk_list!(visitor, visit_variant, enum_definition.variants, generics, item_id);
+ walk_list!(visitor, visit_variant, enum_definition.variants);
}
-pub fn walk_variant<'v, V: Visitor<'v>>(
- visitor: &mut V,
- variant: &'v Variant<'v>,
- generics: &'v Generics<'v>,
- parent_item_id: HirId,
-) {
+pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant<'v>) {
visitor.visit_ident(variant.ident);
visitor.visit_id(variant.id);
- visitor.visit_variant_data(
- &variant.data,
- variant.ident.name,
- generics,
- parent_item_id,
- variant.span,
- );
+ visitor.visit_variant_data(&variant.data);
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
}
@@ -695,7 +667,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
TyKind::Path(ref qpath) => {
visitor.visit_qpath(qpath, typ.hir_id, typ.span);
}
- TyKind::OpaqueDef(item_id, lifetimes) => {
+ TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
visitor.visit_nested_item(item_id);
walk_list!(visitor, visit_generic_arg, lifetimes);
}
@@ -705,7 +677,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
}
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
for bound in bounds {
- visitor.visit_poly_trait_ref(bound, TraitBoundModifier::None);
+ visitor.visit_poly_trait_ref(bound);
}
visitor.visit_lifetime(lifetime);
}
@@ -718,12 +690,7 @@ pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) {
visitor.visit_id(inf.hir_id);
}
-pub fn walk_qpath<'v, V: Visitor<'v>>(
- visitor: &mut V,
- qpath: &'v QPath<'v>,
- id: HirId,
- span: Span,
-) {
+pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) {
match *qpath {
QPath::Resolved(ref maybe_qself, ref path) => {
walk_list!(visitor, visit_ty, maybe_qself);
@@ -731,7 +698,7 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(
}
QPath::TypeRelative(ref qself, ref segment) => {
visitor.visit_ty(qself);
- visitor.visit_path_segment(span, segment);
+ visitor.visit_path_segment(segment);
}
QPath::LangItem(..) => {}
}
@@ -739,27 +706,19 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) {
for segment in path.segments {
- visitor.visit_path_segment(path.span, segment);
+ visitor.visit_path_segment(segment);
}
}
-pub fn walk_path_segment<'v, V: Visitor<'v>>(
- visitor: &mut V,
- path_span: Span,
- segment: &'v PathSegment<'v>,
-) {
+pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, segment: &'v PathSegment<'v>) {
visitor.visit_ident(segment.ident);
- walk_list!(visitor, visit_id, segment.hir_id);
+ visitor.visit_id(segment.hir_id);
if let Some(ref args) = segment.args {
- visitor.visit_generic_args(path_span, args);
+ visitor.visit_generic_args(args);
}
}
-pub fn walk_generic_args<'v, V: Visitor<'v>>(
- visitor: &mut V,
- _path_span: Span,
- generic_args: &'v GenericArgs<'v>,
-) {
+pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, generic_args: &'v GenericArgs<'v>) {
walk_list!(visitor, visit_generic_arg, generic_args.args);
walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings);
}
@@ -770,7 +729,7 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
) {
visitor.visit_id(type_binding.hir_id);
visitor.visit_ident(type_binding.ident);
- visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
+ visitor.visit_generic_args(type_binding.gen_args);
match type_binding.kind {
TypeBindingKind::Equality { ref term } => match term {
Term::Ty(ref ty) => visitor.visit_ty(ty),
@@ -792,11 +751,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
}
PatKind::Struct(ref qpath, fields, _) => {
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
- for field in fields {
- visitor.visit_id(field.hir_id);
- visitor.visit_ident(field.ident);
- visitor.visit_pat(&field.pat)
- }
+ walk_list!(visitor, visit_pat_field, fields);
}
PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats),
PatKind::Tuple(tuple_elements, _) => {
@@ -823,6 +778,12 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
}
}
+pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
+ visitor.visit_id(field.hir_id);
+ visitor.visit_ident(field.ident);
+ visitor.visit_pat(&field.pat)
+}
+
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
visitor.visit_id(foreign_item.hir_id());
visitor.visit_ident(foreign_item.ident);
@@ -842,12 +803,12 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v
pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) {
match *bound {
- GenericBound::Trait(ref typ, modifier) => {
- visitor.visit_poly_trait_ref(typ, modifier);
+ GenericBound::Trait(ref typ, _modifier) => {
+ visitor.visit_poly_trait_ref(typ);
}
- GenericBound::LangItemTrait(_, span, hir_id, args) => {
+ GenericBound::LangItemTrait(_, _span, hir_id, args) => {
visitor.visit_id(hir_id);
- visitor.visit_generic_args(span, args);
+ visitor.visit_generic_args(args);
}
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
}
@@ -899,10 +860,7 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
visitor.visit_lifetime(lifetime);
walk_list!(visitor, visit_param_bound, bounds);
}
- WherePredicate::EqPredicate(WhereEqPredicate {
- hir_id, ref lhs_ty, ref rhs_ty, ..
- }) => {
- visitor.visit_id(hir_id);
+ WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
visitor.visit_ty(lhs_ty);
visitor.visit_ty(rhs_ty);
}
@@ -936,7 +894,6 @@ pub fn walk_fn<'v, V: Visitor<'v>>(
function_kind: FnKind<'v>,
function_declaration: &'v FnDecl<'v>,
body_id: BodyId,
- _span: Span,
id: HirId,
) {
visitor.visit_id(id);
@@ -1090,6 +1047,12 @@ pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>)
walk_list!(visitor, visit_ty, let_expr.ty);
}
+pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
+ visitor.visit_id(field.hir_id);
+ visitor.visit_ident(field.ident);
+ visitor.visit_expr(&field.expr)
+}
+
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
visitor.visit_id(expression.hir_id);
match expression.kind {
@@ -1104,11 +1067,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
}
ExprKind::Struct(ref qpath, fields, ref optional_base) => {
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
- for field in fields {
- visitor.visit_id(field.hir_id);
- visitor.visit_ident(field.ident);
- visitor.visit_expr(&field.expr)
- }
+ walk_list!(visitor, visit_expr_field, fields);
walk_list!(visitor, visit_expr, optional_base);
}
ExprKind::Tup(subexpressions) => {
@@ -1118,8 +1077,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments);
}
- ExprKind::MethodCall(ref segment, arguments, _) => {
- visitor.visit_path_segment(expression.span, segment);
+ ExprKind::MethodCall(ref segment, receiver, arguments, _) => {
+ visitor.visit_path_segment(segment);
+ visitor.visit_expr(receiver);
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index c337be12a..ca615a491 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -8,6 +8,7 @@
//! * Functions called by the compiler itself.
use crate::def_id::DefId;
+use crate::errors::LangItemError;
use crate::{MethodKind, Target};
use rustc_ast as ast;
@@ -115,9 +116,9 @@ macro_rules! language_item_table {
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
- /// returns an error message as a string.
- pub fn require(&self, it: LangItem) -> Result<DefId, String> {
- self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name()))
+ /// returns an error encapsulating the `LangItem`.
+ pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
+ self.items[it as usize].ok_or_else(|| LangItemError(it))
}
/// Returns the [`DefId`]s of all lang items in a group.
@@ -192,7 +193,8 @@ language_item_table! {
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);
// language items relating to transmutability
- TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(6);
+ TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0);
+ TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(3);
Add(Op), sym::add, add_trait, Target::Trait, GenericRequirement::Exact(1);
Sub(Op), sym::sub, sub_trait, Target::Trait, GenericRequirement::Exact(1);
@@ -236,7 +238,6 @@ language_item_table! {
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None;
Generator, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1);
- GeneratorReturn, sym::generator_return, generator_return, Target::AssocTy, GenericRequirement::None;
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;
@@ -267,8 +268,6 @@ language_item_table! {
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
- ConstEvalSelect, sym::const_eval_select, const_eval_select, Target::Fn, GenericRequirement::Exact(4);
- ConstConstEvalSelect, sym::const_eval_select_ct,const_eval_select_ct, Target::Fn, GenericRequirement::Exact(4);
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
@@ -290,6 +289,8 @@ language_item_table! {
Try, sym::Try, try_trait, Target::Trait, GenericRequirement::None;
+ Tuple, sym::tuple_trait, tuple_trait, Target::Trait, GenericRequirement::Exact(0);
+
SliceLen, sym::slice_len_fn, slice_len_fn, Target::Method(MethodKind::Inherent), GenericRequirement::None;
// Language items from AST lowering
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 0f9e6fa7b..946da9265 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,17 +5,22 @@
#![feature(associated_type_defaults)]
#![feature(closure_track_caller)]
#![feature(const_btree_new)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
#[macro_use]
+extern crate tracing;
+
+#[macro_use]
extern crate rustc_data_structures;
extern crate self as rustc_hir;
@@ -25,6 +30,7 @@ pub mod def;
pub mod def_path_hash_map;
pub mod definitions;
pub mod diagnostic_items;
+pub mod errors;
pub use rustc_span::def_id;
mod hir;
pub mod hir_id;
diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs
index 93112199b..0c1819bb0 100644
--- a/compiler/rustc_hir/src/pat_util.rs
+++ b/compiler/rustc_hir/src/pat_util.rs
@@ -1,6 +1,6 @@
use crate::def::{CtorOf, DefKind, Res};
use crate::def_id::DefId;
-use crate::hir::{self, HirId, PatKind};
+use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind};
use rustc_data_structures::fx::FxHashSet;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::Ident;
@@ -35,7 +35,7 @@ pub trait EnumerateAndAdjustIterator {
fn enumerate_and_adjust(
self,
expected_len: usize,
- gap_pos: Option<usize>,
+ gap_pos: hir::DotDotPos,
) -> EnumerateAndAdjust<Self>
where
Self: Sized;
@@ -45,7 +45,7 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
fn enumerate_and_adjust(
self,
expected_len: usize,
- gap_pos: Option<usize>,
+ gap_pos: hir::DotDotPos,
) -> EnumerateAndAdjust<Self>
where
Self: Sized,
@@ -53,7 +53,7 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
let actual_len = self.len();
EnumerateAndAdjust {
enumerate: self.enumerate(),
- gap_pos: gap_pos.unwrap_or(expected_len),
+ gap_pos: gap_pos.as_opt_usize().unwrap_or(expected_len),
gap_len: expected_len - actual_len,
}
}
@@ -93,12 +93,7 @@ impl hir::Pat<'_> {
pub fn simple_ident(&self) -> Option<Ident> {
match self.kind {
- PatKind::Binding(
- hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
- _,
- ident,
- None,
- ) => Some(ident),
+ PatKind::Binding(BindingAnnotation(ByRef::No, _), _, ident, None) => Some(ident),
_ => None,
}
}
@@ -135,11 +130,11 @@ impl hir::Pat<'_> {
pub fn contains_explicit_ref_binding(&self) -> Option<hir::Mutability> {
let mut result = None;
self.each_binding(|annotation, _, _, _| match annotation {
- hir::BindingAnnotation::Ref => match result {
+ hir::BindingAnnotation::REF => match result {
None | Some(hir::Mutability::Not) => result = Some(hir::Mutability::Not),
_ => {}
},
- hir::BindingAnnotation::RefMut => result = Some(hir::Mutability::Mut),
+ hir::BindingAnnotation::REF_MUT => result = Some(hir::Mutability::Mut),
_ => {}
});
result
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 8ccd59e8e..5b9c42686 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -1,8 +1,7 @@
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use crate::hir::{
- AttributeMap, BodyId, Crate, Expr, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
- Ty,
+ AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
};
use crate::hir_id::{HirId, ItemLocalId};
use rustc_span::def_id::DefPathHash;
@@ -14,8 +13,6 @@ pub trait HashStableContext:
rustc_ast::HashStableContext + rustc_target::HashStableContext
{
fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher);
- fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher);
- fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
}
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
@@ -96,18 +93,6 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for BodyId {
// want to pick up on a reference changing its target, so we hash the NodeIds
// in "DefPath Mode".
-impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Expr<'_> {
- fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
- hcx.hash_hir_expr(self, hasher)
- }
-}
-
-impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Ty<'_> {
- fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
- hcx.hash_hir_ty(self, hasher)
- }
-}
-
impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
// We ignore the `nodes` and `bodies` fields since these refer to information included in
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 6236dea10..5917d5e34 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -36,6 +36,7 @@ pub enum Target {
GlobalAsm,
TyAlias,
OpaqueTy,
+ ImplTraitPlaceholder,
Enum,
Variant,
Struct,
@@ -56,6 +57,8 @@ pub enum Target {
GenericParam(GenericParamKind),
MacroDef,
Param,
+ PatField,
+ ExprField,
}
impl Display for Target {
@@ -77,7 +80,13 @@ impl Target {
ItemKind::ForeignMod { .. } => Target::ForeignMod,
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
ItemKind::TyAlias(..) => Target::TyAlias,
- ItemKind::OpaqueTy(..) => Target::OpaqueTy,
+ ItemKind::OpaqueTy(ref opaque) => {
+ if opaque.in_trait {
+ Target::ImplTraitPlaceholder
+ } else {
+ Target::OpaqueTy
+ }
+ }
ItemKind::Enum(..) => Target::Enum,
ItemKind::Struct(..) => Target::Struct,
ItemKind::Union(..) => Target::Union,
@@ -101,6 +110,7 @@ impl Target {
DefKind::GlobalAsm => Target::GlobalAsm,
DefKind::TyAlias => Target::TyAlias,
DefKind::OpaqueTy => Target::OpaqueTy,
+ DefKind::ImplTraitPlaceholder => Target::ImplTraitPlaceholder,
DefKind::Enum => Target::Enum,
DefKind::Struct => Target::Struct,
DefKind::Union => Target::Union,
@@ -155,6 +165,7 @@ impl Target {
Target::GlobalAsm => "global asm",
Target::TyAlias => "type alias",
Target::OpaqueTy => "opaque type",
+ Target::ImplTraitPlaceholder => "opaque type in trait",
Target::Enum => "enum",
Target::Variant => "enum variant",
Target::Struct => "struct",
@@ -183,6 +194,8 @@ impl Target {
},
Target::MacroDef => "macro def",
Target::Param => "function param",
+ Target::PatField => "pattern field",
+ Target::ExprField => "struct field",
}
}
}
diff --git a/compiler/rustc_hir/src/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs
index b6a85c047..da9c9c121 100644
--- a/compiler/rustc_hir/src/weak_lang_items.rs
+++ b/compiler/rustc_hir/src/weak_lang_items.rs
@@ -18,6 +18,12 @@ pub static WEAK_ITEMS_REFS: LazyLock<FxIndexMap<Symbol, LangItem>> = LazyLock::n
map
});
+pub static WEAK_ITEMS_SYMBOLS: LazyLock<FxIndexMap<LangItem, Symbol>> = LazyLock::new(|| {
+ let mut map = FxIndexMap::default();
+ $(map.insert(LangItem::$item, sym::$sym);)*
+ map
+});
+
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol>
{
lang_items::extract(attrs).and_then(|(name, _)| {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index e0179bd3e..35a58296e 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1,4 +1,6 @@
#![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_ast as ast;
use rustc_ast::util::parser::{self, AssocOp, Fixity};
@@ -7,7 +9,9 @@ use rustc_ast_pretty::pp::{self, Breaks};
use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir;
use rustc_hir::LifetimeParamKind;
-use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term};
+use rustc_hir::{
+ BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Mutability, Node, Term,
+};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
@@ -83,12 +87,14 @@ impl<'a> State<'a> {
Node::Variant(a) => self.print_variant(a),
Node::AnonConst(a) => self.print_anon_const(a),
Node::Expr(a) => self.print_expr(a),
+ Node::ExprField(a) => self.print_expr_field(&a),
Node::Stmt(a) => self.print_stmt(a),
Node::PathSegment(a) => self.print_path_segment(a),
Node::Ty(a) => self.print_type(a),
Node::TypeBinding(a) => self.print_type_binding(a),
Node::TraitRef(a) => self.print_trait_ref(a),
Node::Pat(a) => self.print_pat(a),
+ Node::PatField(a) => self.print_patfield(&a),
Node::Arm(a) => self.print_arm(a),
Node::Infer(_) => self.word("_"),
Node::Block(a) => {
@@ -911,6 +917,10 @@ impl<'a> State<'a> {
if let Some(els) = els {
self.nbsp();
self.word_space("else");
+ // containing cbox, will be closed by print-block at `}`
+ self.cbox(0);
+ // head-box, will be closed by print-block after `{`
+ self.ibox(0);
self.print_block(els);
}
@@ -1123,20 +1133,7 @@ impl<'a> State<'a> {
) {
self.print_qpath(qpath, true);
self.word("{");
- self.commasep_cmnt(
- Consistent,
- fields,
- |s, field| {
- s.ibox(INDENT_UNIT);
- if !field.is_shorthand {
- s.print_ident(field.ident);
- s.word_space(":");
- }
- s.print_expr(field.expr);
- s.end()
- },
- |f| f.span,
- );
+ self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span);
if let Some(expr) = wth {
self.ibox(INDENT_UNIT);
if !fields.is_empty() {
@@ -1153,6 +1150,20 @@ impl<'a> State<'a> {
self.word("}");
}
+ fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
+ if self.attrs(field.hir_id).is_empty() {
+ self.space();
+ }
+ self.cbox(INDENT_UNIT);
+ self.print_outer_attributes(&self.attrs(field.hir_id));
+ if !field.is_shorthand {
+ self.print_ident(field.ident);
+ self.word_space(":");
+ }
+ self.print_expr(&field.expr);
+ self.end()
+ }
+
fn print_expr_tup(&mut self, exprs: &[hir::Expr<'_>]) {
self.popen();
self.commasep_exprs(Inconsistent, exprs);
@@ -1172,15 +1183,20 @@ impl<'a> State<'a> {
self.print_call_post(args)
}
- fn print_expr_method_call(&mut self, segment: &hir::PathSegment<'_>, args: &[hir::Expr<'_>]) {
- let base_args = &args[1..];
- self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
+ fn print_expr_method_call(
+ &mut self,
+ segment: &hir::PathSegment<'_>,
+ receiver: &hir::Expr<'_>,
+ args: &[hir::Expr<'_>],
+ ) {
+ let base_args = args;
+ self.print_expr_maybe_paren(&receiver, parser::PREC_POSTFIX);
self.word(".");
self.print_ident(segment.ident);
let generic_args = segment.args();
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
- self.print_generic_args(generic_args, segment.infer_args, true);
+ self.print_generic_args(generic_args, true);
}
self.print_call_post(base_args)
@@ -1240,7 +1256,7 @@ impl<'a> State<'a> {
fn print_literal(&mut self, lit: &hir::Lit) {
self.maybe_print_comment(lit.span.lo());
- self.word(lit.node.to_lit_token().to_string())
+ self.word(lit.node.to_token_lit().to_string())
}
fn print_inline_asm(&mut self, asm: &hir::InlineAsm<'_>) {
@@ -1385,8 +1401,8 @@ impl<'a> State<'a> {
hir::ExprKind::Call(func, args) => {
self.print_expr_call(func, args);
}
- hir::ExprKind::MethodCall(segment, args, _) => {
- self.print_expr_method_call(segment, args);
+ hir::ExprKind::MethodCall(segment, receiver, args, _) => {
+ self.print_expr_method_call(segment, receiver, args);
}
hir::ExprKind::Binary(op, lhs, rhs) => {
self.print_expr_binary(op, lhs, rhs);
@@ -1583,7 +1599,7 @@ impl<'a> State<'a> {
}
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident);
- self.print_generic_args(segment.args(), segment.infer_args, colons_before_params);
+ self.print_generic_args(segment.args(), colons_before_params);
}
}
}
@@ -1591,7 +1607,7 @@ impl<'a> State<'a> {
pub fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) {
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident);
- self.print_generic_args(segment.args(), segment.infer_args, false);
+ self.print_generic_args(segment.args(), false);
}
}
@@ -1610,11 +1626,7 @@ impl<'a> State<'a> {
}
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident);
- self.print_generic_args(
- segment.args(),
- segment.infer_args,
- colons_before_params,
- );
+ self.print_generic_args(segment.args(), colons_before_params);
}
}
@@ -1622,11 +1634,7 @@ impl<'a> State<'a> {
self.word("::");
let item_segment = path.segments.last().unwrap();
self.print_ident(item_segment.ident);
- self.print_generic_args(
- item_segment.args(),
- item_segment.infer_args,
- colons_before_params,
- )
+ self.print_generic_args(item_segment.args(), colons_before_params)
}
hir::QPath::TypeRelative(qself, item_segment) => {
// If we've got a compound-qualified-path, let's push an additional pair of angle
@@ -1642,11 +1650,7 @@ impl<'a> State<'a> {
self.word("::");
self.print_ident(item_segment.ident);
- self.print_generic_args(
- item_segment.args(),
- item_segment.infer_args,
- colons_before_params,
- )
+ self.print_generic_args(item_segment.args(), colons_before_params)
}
hir::QPath::LangItem(lang_item, span, _) => {
self.word("#[lang = \"");
@@ -1659,7 +1663,6 @@ impl<'a> State<'a> {
fn print_generic_args(
&mut self,
generic_args: &hir::GenericArgs<'_>,
- infer_args: bool,
colons_before_params: bool,
) {
if generic_args.parenthesized {
@@ -1706,13 +1709,6 @@ impl<'a> State<'a> {
);
}
- // FIXME(eddyb): this would leak into error messages (e.g.,
- // "non-exhaustive patterns: `Some::<..>(_)` not covered").
- if infer_args && false {
- start_or_comma(self);
- self.word("..");
- }
-
for binding in generic_args.bindings {
start_or_comma(self);
self.print_type_binding(binding);
@@ -1726,7 +1722,7 @@ impl<'a> State<'a> {
pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) {
self.print_ident(binding.ident);
- self.print_generic_args(binding.gen_args, false, false);
+ self.print_generic_args(binding.gen_args, false);
self.space();
match binding.kind {
hir::TypeBindingKind::Equality { ref term } => {
@@ -1749,20 +1745,12 @@ impl<'a> State<'a> {
// is that it doesn't matter
match pat.kind {
PatKind::Wild => self.word("_"),
- PatKind::Binding(binding_mode, _, ident, sub) => {
- match binding_mode {
- hir::BindingAnnotation::Ref => {
- self.word_nbsp("ref");
- self.print_mutability(hir::Mutability::Not, false);
- }
- hir::BindingAnnotation::RefMut => {
- self.word_nbsp("ref");
- self.print_mutability(hir::Mutability::Mut, false);
- }
- hir::BindingAnnotation::Unannotated => {}
- hir::BindingAnnotation::Mutable => {
- self.word_nbsp("mut");
- }
+ PatKind::Binding(BindingAnnotation(by_ref, mutbl), _, ident, sub) => {
+ if by_ref == ByRef::Yes {
+ self.word_nbsp("ref");
+ }
+ if mutbl == Mutability::Mut {
+ self.word_nbsp("mut");
}
self.print_ident(ident);
if let Some(p) = sub {
@@ -1773,7 +1761,8 @@ impl<'a> State<'a> {
PatKind::TupleStruct(ref qpath, elts, ddpos) => {
self.print_qpath(qpath, true);
self.popen();
- if let Some(ddpos) = ddpos {
+ if let Some(ddpos) = ddpos.as_opt_usize() {
+ let ddpos = ddpos as usize;
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
if ddpos != 0 {
self.word_space(",");
@@ -1799,20 +1788,7 @@ impl<'a> State<'a> {
if !empty {
self.space();
}
- self.commasep_cmnt(
- Consistent,
- fields,
- |s, f| {
- s.cbox(INDENT_UNIT);
- if !f.is_shorthand {
- s.print_ident(f.ident);
- s.word_nbsp(":");
- }
- s.print_pat(f.pat);
- s.end()
- },
- |f| f.pat.span,
- );
+ self.commasep_cmnt(Consistent, &fields, |s, f| s.print_patfield(f), |f| f.pat.span);
if etc {
if !fields.is_empty() {
self.word_space(",");
@@ -1829,7 +1805,7 @@ impl<'a> State<'a> {
}
PatKind::Tuple(elts, ddpos) => {
self.popen();
- if let Some(ddpos) = ddpos {
+ if let Some(ddpos) = ddpos.as_opt_usize() {
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
if ddpos != 0 {
self.word_space(",");
@@ -1907,6 +1883,20 @@ impl<'a> State<'a> {
self.ann.post(self, AnnNode::Pat(pat))
}
+ pub fn print_patfield(&mut self, field: &hir::PatField<'_>) {
+ if self.attrs(field.hir_id).is_empty() {
+ self.space();
+ }
+ self.cbox(INDENT_UNIT);
+ self.print_outer_attributes(&self.attrs(field.hir_id));
+ if !field.is_shorthand {
+ self.print_ident(field.ident);
+ self.word_nbsp(":");
+ }
+ self.print_pat(field.pat);
+ self.end();
+ }
+
pub fn print_param(&mut self, arg: &hir::Param<'_>) {
self.print_outer_attributes(self.attrs(arg.hir_id));
self.print_pat(arg.pat);
@@ -2403,9 +2393,9 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
contains_exterior_struct_lit(x)
}
- hir::ExprKind::MethodCall(.., exprs, _) => {
+ hir::ExprKind::MethodCall(_, receiver, ..) => {
// `X { y: 1 }.bar(...)`
- contains_exterior_struct_lit(&exprs[0])
+ contains_exterior_struct_lit(receiver)
}
_ => false,
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 1e88e8091..2c9e21f76 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -2,7 +2,7 @@
#![deny(missing_docs)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 33c3c536f..a00d7bd68 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -1,7 +1,9 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(allow_internal_unstable)]
#![feature(bench_black_box)]
#![feature(extend_one)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(new_uninit)]
#![feature(step_trait)]
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index 30ff36421..4172ce3bb 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -172,7 +172,9 @@ impl<I: Idx, T> IndexVec<I, T> {
}
#[inline]
- pub fn indices(&self) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + 'static {
+ pub fn indices(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static {
(0..self.len()).map(|n| I::new(n))
}
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml
index 02ac83a5e..aced787d6 100644
--- a/compiler/rustc_infer/Cargo.toml
+++ b/compiler/rustc_infer/Cargo.toml
@@ -15,6 +15,7 @@ rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
+rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
new file mode 100644
index 000000000..d232a1864
--- /dev/null
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -0,0 +1,499 @@
+use hir::GenericParamKind;
+use rustc_errors::{
+ fluent, AddSubdiagnostic, Applicability, DiagnosticMessage, DiagnosticStyledString, MultiSpan,
+};
+use rustc_hir as hir;
+use rustc_hir::{FnRetTy, Ty};
+use rustc_macros::SessionDiagnostic;
+use rustc_middle::ty::{Region, TyCtxt};
+use rustc_span::symbol::kw;
+use rustc_span::{symbol::Ident, BytePos, Span};
+
+use crate::infer::error_reporting::{
+ need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
+ ObligationCauseAsDiagArg,
+};
+
+pub mod note_and_explain;
+
+#[derive(SessionDiagnostic)]
+#[diag(infer::opaque_hidden_type)]
+pub struct OpaqueHiddenTypeDiag {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[note(infer::opaque_type)]
+ pub opaque_type: Span,
+ #[note(infer::hidden_type)]
+ pub hidden_type: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(infer::type_annotations_needed, code = "E0282")]
+pub struct AnnotationRequired<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub source_kind: &'static str,
+ pub source_name: &'a str,
+ #[label]
+ pub failure_span: Option<Span>,
+ #[subdiagnostic]
+ pub bad_label: Option<InferenceBadError<'a>>,
+ #[subdiagnostic]
+ pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
+ #[subdiagnostic]
+ pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
+}
+
+// Copy of `AnnotationRequired` for E0283
+#[derive(SessionDiagnostic)]
+#[diag(infer::type_annotations_needed, code = "E0283")]
+pub struct AmbigousImpl<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub source_kind: &'static str,
+ pub source_name: &'a str,
+ #[label]
+ pub failure_span: Option<Span>,
+ #[subdiagnostic]
+ pub bad_label: Option<InferenceBadError<'a>>,
+ #[subdiagnostic]
+ pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
+ #[subdiagnostic]
+ pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
+}
+
+// Copy of `AnnotationRequired` for E0284
+#[derive(SessionDiagnostic)]
+#[diag(infer::type_annotations_needed, code = "E0284")]
+pub struct AmbigousReturn<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub source_kind: &'static str,
+ pub source_name: &'a str,
+ #[label]
+ pub failure_span: Option<Span>,
+ #[subdiagnostic]
+ pub bad_label: Option<InferenceBadError<'a>>,
+ #[subdiagnostic]
+ pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
+ #[subdiagnostic]
+ pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(infer::need_type_info_in_generator, code = "E0698")]
+pub struct NeedTypeInfoInGenerator<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub generator_kind: GeneratorKindAsDiagArg,
+ #[subdiagnostic]
+ pub bad_label: InferenceBadError<'a>,
+}
+
+// Used when a better one isn't available
+#[derive(SessionSubdiagnostic)]
+#[label(infer::label_bad)]
+pub struct InferenceBadError<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub bad_kind: &'static str,
+ pub prefix_kind: UnderspecifiedArgKind,
+ pub has_parent: bool,
+ pub prefix: &'a str,
+ pub parent_prefix: &'a str,
+ pub parent_name: String,
+ pub name: String,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum SourceKindSubdiag<'a> {
+ #[suggestion_verbose(
+ infer::source_kind_subdiag_let,
+ code = ": {type_name}",
+ applicability = "has-placeholders"
+ )]
+ LetLike {
+ #[primary_span]
+ span: Span,
+ name: String,
+ type_name: String,
+ kind: &'static str,
+ x_kind: &'static str,
+ prefix_kind: UnderspecifiedArgKind,
+ prefix: &'a str,
+ arg_name: String,
+ },
+ #[label(infer::source_kind_subdiag_generic_label)]
+ GenericLabel {
+ #[primary_span]
+ span: Span,
+ is_type: bool,
+ param_name: String,
+ parent_exists: bool,
+ parent_prefix: String,
+ parent_name: String,
+ },
+ #[suggestion_verbose(
+ infer::source_kind_subdiag_generic_suggestion,
+ code = "::<{args}>",
+ applicability = "has-placeholders"
+ )]
+ GenericSuggestion {
+ #[primary_span]
+ span: Span,
+ arg_count: usize,
+ args: String,
+ },
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum SourceKindMultiSuggestion<'a> {
+ #[multipart_suggestion_verbose(
+ infer::source_kind_fully_qualified,
+ applicability = "has-placeholders"
+ )]
+ FullyQualified {
+ #[suggestion_part(code = "{def_path}({adjustment}")]
+ span_lo: Span,
+ #[suggestion_part(code = "{successor_pos}")]
+ span_hi: Span,
+ def_path: String,
+ adjustment: &'a str,
+ successor_pos: &'a str,
+ },
+ #[multipart_suggestion_verbose(
+ infer::source_kind_closure_return,
+ applicability = "has-placeholders"
+ )]
+ ClosureReturn {
+ #[suggestion_part(code = "{start_span_code}")]
+ start_span: Span,
+ start_span_code: String,
+ #[suggestion_part(code = " }}")]
+ end_span: Option<Span>,
+ },
+}
+
+impl<'a> SourceKindMultiSuggestion<'a> {
+ pub fn new_fully_qualified(
+ span: Span,
+ def_path: String,
+ adjustment: &'a str,
+ successor: (&'a str, BytePos),
+ ) -> Self {
+ Self::FullyQualified {
+ span_lo: span.shrink_to_lo(),
+ span_hi: span.shrink_to_hi().with_hi(successor.1),
+ def_path,
+ adjustment,
+ successor_pos: successor.0,
+ }
+ }
+
+ pub fn new_closure_return(
+ ty_info: String,
+ data: &'a FnRetTy<'a>,
+ should_wrap_expr: Option<Span>,
+ ) -> Self {
+ let (arrow, post) = match data {
+ FnRetTy::DefaultReturn(_) => ("-> ", " "),
+ _ => ("", ""),
+ };
+ let (start_span, start_span_code, end_span) = match should_wrap_expr {
+ Some(end_span) => {
+ (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post), Some(end_span))
+ }
+ None => (data.span(), format!("{}{}{}", arrow, ty_info, post), None),
+ };
+ Self::ClosureReturn { start_span, start_span_code, end_span }
+ }
+}
+
+pub enum RegionOriginNote<'a> {
+ Plain {
+ span: Span,
+ msg: DiagnosticMessage,
+ },
+ WithName {
+ span: Span,
+ msg: DiagnosticMessage,
+ name: &'a str,
+ continues: bool,
+ },
+ WithRequirement {
+ span: Span,
+ requirement: ObligationCauseAsDiagArg<'a>,
+ expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>,
+ },
+}
+
+impl AddSubdiagnostic for RegionOriginNote<'_> {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ let mut label_or_note = |span, msg: DiagnosticMessage| {
+ let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
+ let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
+ let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
+ if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
+ diag.span_label(span, msg);
+ } else if span_is_primary && expanded_sub_count == 0 {
+ diag.note(msg);
+ } else {
+ diag.span_note(span, msg);
+ }
+ };
+ match self {
+ RegionOriginNote::Plain { span, msg } => {
+ label_or_note(span, msg);
+ }
+ RegionOriginNote::WithName { span, msg, name, continues } => {
+ label_or_note(span, msg);
+ diag.set_arg("name", name);
+ diag.set_arg("continues", continues);
+ }
+ RegionOriginNote::WithRequirement {
+ span,
+ requirement,
+ expected_found: Some((expected, found)),
+ } => {
+ label_or_note(span, fluent::infer::subtype);
+ diag.set_arg("requirement", requirement);
+
+ diag.note_expected_found(&"", expected, &"", found);
+ }
+ RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
+ // FIXME: this really should be handled at some earlier stage. Our
+ // handling of region checking when type errors are present is
+ // *terrible*.
+ label_or_note(span, fluent::infer::subtype_2);
+ diag.set_arg("requirement", requirement);
+ }
+ };
+ }
+}
+
+pub enum LifetimeMismatchLabels {
+ InRet {
+ param_span: Span,
+ ret_span: Span,
+ span: Span,
+ label_var1: Option<Ident>,
+ },
+ Normal {
+ hir_equal: bool,
+ ty_sup: Span,
+ ty_sub: Span,
+ span: Span,
+ sup: Option<Ident>,
+ sub: Option<Ident>,
+ },
+}
+
+impl AddSubdiagnostic for LifetimeMismatchLabels {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ match self {
+ LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
+ diag.span_label(param_span, fluent::infer::declared_different);
+ diag.span_label(ret_span, fluent::infer::nothing);
+ diag.span_label(span, fluent::infer::data_returned);
+ diag.set_arg("label_var1_exists", label_var1.is_some());
+ diag.set_arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default());
+ }
+ LifetimeMismatchLabels::Normal {
+ hir_equal,
+ ty_sup,
+ ty_sub,
+ span,
+ sup: label_var1,
+ sub: label_var2,
+ } => {
+ if hir_equal {
+ diag.span_label(ty_sup, fluent::infer::declared_multiple);
+ diag.span_label(ty_sub, fluent::infer::nothing);
+ diag.span_label(span, fluent::infer::data_lifetime_flow);
+ } else {
+ diag.span_label(ty_sup, fluent::infer::types_declared_different);
+ diag.span_label(ty_sub, fluent::infer::nothing);
+ diag.span_label(span, fluent::infer::data_flows);
+ diag.set_arg("label_var1_exists", label_var1.is_some());
+ diag.set_arg(
+ "label_var1",
+ label_var1.map(|x| x.to_string()).unwrap_or_default(),
+ );
+ diag.set_arg("label_var2_exists", label_var2.is_some());
+ diag.set_arg(
+ "label_var2",
+ label_var2.map(|x| x.to_string()).unwrap_or_default(),
+ );
+ }
+ }
+ }
+ }
+}
+
+pub struct AddLifetimeParamsSuggestion<'a> {
+ pub tcx: TyCtxt<'a>,
+ pub sub: Region<'a>,
+ pub ty_sup: &'a Ty<'a>,
+ pub ty_sub: &'a Ty<'a>,
+ pub add_note: bool,
+}
+
+impl AddSubdiagnostic for AddLifetimeParamsSuggestion<'_> {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ let mut mk_suggestion = || {
+ let (
+ hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. },
+ hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. },
+ ) = (self.ty_sub, self.ty_sup) else {
+ return false;
+ };
+
+ if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() {
+ return false;
+ };
+
+ let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else {
+ return false;
+ };
+
+ let hir_id = self.tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
+
+ let node = self.tcx.hir().get(hir_id);
+ let is_impl = matches!(&node, hir::Node::ImplItem(_));
+ let generics = match node {
+ hir::Node::Item(&hir::Item {
+ kind: hir::ItemKind::Fn(_, ref generics, ..),
+ ..
+ })
+ | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
+ | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
+ _ => return false,
+ };
+
+ let suggestion_param_name = generics
+ .params
+ .iter()
+ .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
+ .map(|p| p.name.ident().name)
+ .find(|i| *i != kw::UnderscoreLifetime);
+ let introduce_new = suggestion_param_name.is_none();
+ let suggestion_param_name =
+ suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
+
+ debug!(?lifetime_sup.span);
+ debug!(?lifetime_sub.span);
+ let make_suggestion = |span: rustc_span::Span| {
+ if span.is_empty() {
+ (span, format!("{}, ", suggestion_param_name))
+ } else if let Ok("&") = self.tcx.sess.source_map().span_to_snippet(span).as_deref()
+ {
+ (span.shrink_to_hi(), format!("{} ", suggestion_param_name))
+ } else {
+ (span, suggestion_param_name.clone())
+ }
+ };
+ let mut suggestions =
+ vec![make_suggestion(lifetime_sub.span), make_suggestion(lifetime_sup.span)];
+
+ if introduce_new {
+ let new_param_suggestion = if let Some(first) =
+ generics.params.iter().find(|p| !p.name.ident().span.is_empty())
+ {
+ (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name))
+ } else {
+ (generics.span, format!("<{}>", suggestion_param_name))
+ };
+
+ suggestions.push(new_param_suggestion);
+ }
+
+ diag.multipart_suggestion(
+ fluent::infer::lifetime_param_suggestion,
+ suggestions,
+ Applicability::MaybeIncorrect,
+ );
+ diag.set_arg("is_impl", is_impl);
+ true
+ };
+ if mk_suggestion() && self.add_note {
+ diag.note(fluent::infer::lifetime_param_suggestion_elided);
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(infer::lifetime_mismatch, code = "E0623")]
+pub struct LifetimeMismatch<'a> {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub labels: LifetimeMismatchLabels,
+ #[subdiagnostic]
+ pub suggestion: AddLifetimeParamsSuggestion<'a>,
+}
+
+pub struct IntroducesStaticBecauseUnmetLifetimeReq {
+ pub unmet_requirements: MultiSpan,
+ pub binding_span: Span,
+}
+
+impl AddSubdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
+ fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) {
+ self.unmet_requirements
+ .push_span_label(self.binding_span, fluent::infer::msl_introduces_static);
+ diag.span_note(self.unmet_requirements, fluent::infer::msl_unmet_req);
+ }
+}
+
+pub struct ImplNote {
+ pub impl_span: Option<Span>,
+}
+
+impl AddSubdiagnostic for ImplNote {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ match self.impl_span {
+ Some(span) => diag.span_note(span, fluent::infer::msl_impl_note),
+ None => diag.note(fluent::infer::msl_impl_note),
+ };
+ }
+}
+
+pub enum TraitSubdiag {
+ Note { span: Span },
+ Sugg { span: Span },
+}
+
+// FIXME(#100717) used in `Vec<TraitSubdiag>` so requires eager translation/list support
+impl AddSubdiagnostic for TraitSubdiag {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ match self {
+ TraitSubdiag::Note { span } => {
+ diag.span_note(span, "this has an implicit `'static` lifetime requirement");
+ }
+ TraitSubdiag::Sugg { span } => {
+ diag.span_suggestion_verbose(
+ span,
+ "consider relaxing the implicit `'static` requirement",
+ " + '_".to_owned(),
+ rustc_errors::Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(infer::mismatched_static_lifetime)]
+pub struct MismatchedStaticLifetime<'a> {
+ #[primary_span]
+ pub cause_span: Span,
+ #[subdiagnostic]
+ pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq,
+ #[subdiagnostic]
+ pub expl: Option<note_and_explain::RegionExplanation<'a>>,
+ #[subdiagnostic]
+ pub impl_note: ImplNote,
+ #[subdiagnostic]
+ pub trait_subdiags: Vec<TraitSubdiag>,
+}
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
new file mode 100644
index 000000000..7e051835b
--- /dev/null
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -0,0 +1,172 @@
+use crate::infer::error_reporting::nice_region_error::find_anon_type;
+use rustc_errors::{self, fluent, AddSubdiagnostic, IntoDiagnosticArg};
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_span::{symbol::kw, Span};
+
+#[derive(Default)]
+struct DescriptionCtx<'a> {
+ span: Option<Span>,
+ kind: &'a str,
+ arg: String,
+ num_arg: u32,
+}
+
+impl<'a> DescriptionCtx<'a> {
+ fn new<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ region: ty::Region<'tcx>,
+ alt_span: Option<Span>,
+ ) -> Option<Self> {
+ let mut me = DescriptionCtx::default();
+ me.span = alt_span;
+ match *region {
+ ty::ReEarlyBound(_) | ty::ReFree(_) => {
+ return Self::from_early_bound_and_free_regions(tcx, region);
+ }
+ ty::ReStatic => {
+ me.kind = "restatic";
+ }
+
+ ty::RePlaceholder(_) => return None,
+
+ // FIXME(#13998) RePlaceholder should probably print like
+ // ReFree rather than dumping Debug output on the user.
+ //
+ // We shouldn't really be having unification failures with ReVar
+ // and ReLateBound though.
+ ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
+ me.kind = "revar";
+ me.arg = format!("{:?}", region);
+ }
+ };
+ Some(me)
+ }
+
+ fn from_early_bound_and_free_regions<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ region: ty::Region<'tcx>,
+ ) -> Option<Self> {
+ let mut me = DescriptionCtx::default();
+ let scope = region.free_region_binding_scope(tcx).expect_local();
+ match *region {
+ ty::ReEarlyBound(ref br) => {
+ let mut sp = tcx.def_span(scope);
+ if let Some(param) =
+ tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
+ {
+ sp = param.span;
+ }
+ if br.has_name() {
+ me.kind = "as_defined";
+ me.arg = br.name.to_string();
+ } else {
+ me.kind = "as_defined_anon";
+ };
+ me.span = Some(sp)
+ }
+ ty::ReFree(ref fr) => {
+ if !fr.bound_region.is_named()
+ && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
+ {
+ me.kind = "defined_here";
+ me.span = Some(ty.span);
+ } else {
+ match fr.bound_region {
+ ty::BoundRegionKind::BrNamed(_, name) => {
+ let mut sp = tcx.def_span(scope);
+ if let Some(param) =
+ tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
+ {
+ sp = param.span;
+ }
+ if name == kw::UnderscoreLifetime {
+ me.kind = "as_defined_anon";
+ } else {
+ me.kind = "as_defined";
+ me.arg = name.to_string();
+ };
+ me.span = Some(sp);
+ }
+ ty::BrAnon(idx) => {
+ me.kind = "anon_num_here";
+ me.num_arg = idx+1;
+ me.span = Some(tcx.def_span(scope));
+ },
+ _ => {
+ me.kind = "defined_here_reg";
+ me.arg = region.to_string();
+ me.span = Some(tcx.def_span(scope));
+ },
+ }
+ }
+ }
+ _ => bug!(),
+ }
+ Some(me)
+ }
+
+ fn add_to(self, diag: &mut rustc_errors::Diagnostic) {
+ diag.set_arg("desc_kind", self.kind);
+ diag.set_arg("desc_arg", self.arg);
+ diag.set_arg("desc_num_arg", self.num_arg);
+ }
+}
+
+pub enum PrefixKind {
+ Empty,
+}
+
+pub enum SuffixKind {
+ Continues,
+}
+
+impl IntoDiagnosticArg for PrefixKind {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ let kind = match self {
+ Self::Empty => "empty",
+ }
+ .into();
+ rustc_errors::DiagnosticArgValue::Str(kind)
+ }
+}
+
+impl IntoDiagnosticArg for SuffixKind {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ let kind = match self {
+ Self::Continues => "continues",
+ }
+ .into();
+ rustc_errors::DiagnosticArgValue::Str(kind)
+ }
+}
+
+pub struct RegionExplanation<'a> {
+ desc: DescriptionCtx<'a>,
+ prefix: PrefixKind,
+ suffix: SuffixKind,
+}
+
+impl RegionExplanation<'_> {
+ pub fn new<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ region: ty::Region<'tcx>,
+ alt_span: Option<Span>,
+ prefix: PrefixKind,
+ suffix: SuffixKind,
+ ) -> Option<Self> {
+ Some(Self { desc: DescriptionCtx::new(tcx, region, alt_span)?, prefix, suffix })
+ }
+}
+
+impl AddSubdiagnostic for RegionExplanation<'_> {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ if let Some(span) = self.desc.span {
+ diag.span_note(span, fluent::infer::region_explanation);
+ } else {
+ diag.note(fluent::infer::region_explanation);
+ }
+ self.desc.add_to(diag);
+ diag.set_arg("pref_kind", self.prefix);
+ diag.set_arg("suff_kind", self.suffix);
+ }
+}
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 130214a65..00e238648 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -74,10 +74,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
evaluation_cache: self.evaluation_cache.clone(),
reported_trait_errors: self.reported_trait_errors.clone(),
reported_closure_mismatch: self.reported_closure_mismatch.clone(),
- tainted_by_errors_flag: self.tainted_by_errors_flag.clone(),
+ tainted_by_errors: self.tainted_by_errors.clone(),
err_count_on_creation: self.err_count_on_creation,
in_snapshot: self.in_snapshot.clone(),
universe: self.universe.clone(),
+ normalize_fn_sig_for_diagnostic: self
+ .normalize_fn_sig_for_diagnostic
+ .as_ref()
+ .map(|f| f.clone()),
}
}
}
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index ca7862c9d..9488d0a6c 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -180,11 +180,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match *r {
- ty::ReFree(_)
- | ty::ReErased
- | ty::ReStatic
- | ty::ReEmpty(ty::UniverseIndex::ROOT)
- | ty::ReEarlyBound(..) => r,
+ ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r,
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
@@ -199,10 +195,6 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
)
}
- ty::ReEmpty(ui) => {
- bug!("canonicalizing 'empty in universe {:?}", ui) // FIXME
- }
-
_ => {
// Other than `'static` or `'empty`, the query
// response should be executing in a fully
@@ -372,7 +364,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
debug!(
"canonical: region var found with vid {:?}, \
opportunistically resolved to {:?}",
- vid, r
+ vid, resolved_vid
);
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
self.canonicalize_mode.canonicalize_free_region(self, r)
@@ -381,7 +373,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
ty::ReStatic
| ty::ReEarlyBound(..)
| ty::ReFree(_)
- | ty::ReEmpty(_)
| ty::RePlaceholder(..)
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
}
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 8dc20544f..56e834898 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec;
use rustc_middle::arena::ArenaAllocatable;
+use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation;
@@ -63,8 +64,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
{
let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
+ debug!("query_response = {:#?}", query_response);
let canonical_result = self.canonicalize_response(query_response);
-
debug!("canonical_result = {:#?}", canonical_result);
Ok(self.tcx.arena.alloc(canonical_result))
@@ -125,13 +126,17 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
debug!("ambig_errors = {:#?}", ambig_errors);
let region_obligations = self.take_registered_region_obligations();
+ debug!(?region_obligations);
let region_constraints = self.with_region_constraints(|region_constraints| {
make_query_region_constraints(
tcx,
- region_obligations.iter().map(|r_o| (r_o.sup_type, r_o.sub_region)),
+ region_obligations
+ .iter()
+ .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
region_constraints,
)
});
+ debug!(?region_constraints);
let certainty =
if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous };
@@ -246,6 +251,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// the original values `v_o` that was canonicalized into a
// variable...
+ let constraint_category = cause.to_constraint_category();
+
for (index, original_value) in original_values.var_values.iter().enumerate() {
// ...with the value `v_r` of that variable from the query.
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
@@ -261,12 +268,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
(GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => {
// To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
if v_o != v_r {
- output_query_region_constraints
- .outlives
- .push(ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)));
- output_query_region_constraints
- .outlives
- .push(ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)));
+ output_query_region_constraints.outlives.push((
+ ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)),
+ constraint_category,
+ ));
+ output_query_region_constraints.outlives.push((
+ ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)),
+ constraint_category,
+ ));
}
}
@@ -312,7 +321,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// Screen out `'a: 'a` cases -- we skip the binder here but
// only compare the inner values to one another, so they are still at
// consistent binding levels.
- let ty::OutlivesPredicate(k1, r2) = r_c.skip_binder();
+ let ty::OutlivesPredicate(k1, r2) = r_c.0.skip_binder();
if k1 != r2.into() { Some(r_c) } else { None }
}),
);
@@ -557,7 +566,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Obligation<'tcx, ty::Predicate<'tcx>> {
- let ty::OutlivesPredicate(k1, r2) = predicate.skip_binder();
+ let ty::OutlivesPredicate(k1, r2) = predicate.0.skip_binder();
let atom = match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
@@ -572,7 +581,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
}
};
- let predicate = predicate.rebind(atom).to_predicate(self.tcx);
+ let predicate = predicate.0.rebind(atom).to_predicate(self.tcx);
Obligation::new(cause, param_env, predicate)
}
@@ -623,7 +632,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// creates query region constraints.
pub fn make_query_region_constraints<'tcx>(
tcx: TyCtxt<'tcx>,
- outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>)>,
+ outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
region_constraints: &RegionConstraintData<'tcx>,
) -> QueryRegionConstraints<'tcx> {
let RegionConstraintData { constraints, verifys, givens, member_constraints } =
@@ -632,28 +641,35 @@ pub fn make_query_region_constraints<'tcx>(
assert!(verifys.is_empty());
assert!(givens.is_empty());
+ debug!(?constraints);
+
let outlives: Vec<_> = constraints
.iter()
- .map(|(k, _)| match *k {
- // Swap regions because we are going from sub (<=) to outlives
- // (>=).
- Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
- tcx.mk_region(ty::ReVar(v2)).into(),
- tcx.mk_region(ty::ReVar(v1)),
- ),
- Constraint::VarSubReg(v1, r2) => {
- ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
- }
- Constraint::RegSubVar(r1, v2) => {
- ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
- }
- Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
+ .map(|(k, origin)| {
+ // no bound vars in the code above
+ let constraint = ty::Binder::dummy(match *k {
+ // Swap regions because we are going from sub (<=) to outlives
+ // (>=).
+ Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
+ tcx.mk_region(ty::ReVar(v2)).into(),
+ tcx.mk_region(ty::ReVar(v1)),
+ ),
+ Constraint::VarSubReg(v1, r2) => {
+ ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
+ }
+ Constraint::RegSubVar(r1, v2) => {
+ ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
+ }
+ Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
+ });
+ (constraint, origin.to_constraint_category())
})
- .map(ty::Binder::dummy) // no bound vars in the code above
.chain(
outlives_obligations
- .map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
- .map(ty::Binder::dummy), // no bound vars in the code above
+ // no bound vars in the code above
+ .map(|(ty, r, constraint_category)| {
+ (ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), r)), constraint_category)
+ }),
)
.collect();
diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs
index 34b611342..389afe22e 100644
--- a/compiler/rustc_infer/src/infer/canonical/substitute.rs
+++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs
@@ -72,15 +72,16 @@ where
value
} else {
let delegate = FnMutDelegate {
- regions: |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
+ regions: &mut |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
GenericArgKind::Lifetime(l) => l,
r => bug!("{:?} is a region but value is {:?}", br, r),
},
- types: |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() {
+ types: &mut |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() {
GenericArgKind::Type(ty) => ty,
r => bug!("{:?} is a type but value is {:?}", bound_ty, r),
},
- consts: |bound_ct: ty::BoundVar, _| match var_values.var_values[bound_ct].unpack() {
+ consts: &mut |bound_ct: ty::BoundVar, _| match var_values.var_values[bound_ct].unpack()
+ {
GenericArgKind::Const(ct) => ct,
c => bug!("{:?} is a const but value is {:?}", bound_ct, c),
},
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 8bf1de34a..c406df9e4 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -391,7 +391,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
/// Preconditions:
///
/// - `for_vid` is a "root vid"
- #[instrument(skip(self), level = "trace")]
+ #[instrument(skip(self), level = "trace", ret)]
fn generalize(
&self,
ty: Ty<'tcx>,
@@ -435,15 +435,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
cache: SsoHashMap::new(),
};
- let ty = match generalize.relate(ty, ty) {
- Ok(ty) => ty,
- Err(e) => {
- debug!(?e, "failure");
- return Err(e);
- }
- };
+ let ty = generalize.relate(ty, ty)?;
let needs_wf = generalize.needs_wf;
- trace!(?ty, ?needs_wf, "success");
Ok(Generalization { ty, needs_wf })
}
@@ -493,12 +486,13 @@ struct Generalizer<'cx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
- cache: SsoHashMap<Ty<'tcx>, RelateResult<'tcx, Ty<'tcx>>>,
+ cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
}
/// Result from a generalization operation. This includes
/// not only the generalized type, but also a bool flag
/// indicating whether further WF checks are needed.
+#[derive(Debug)]
struct Generalization<'tcx> {
ty: Ty<'tcx>,
@@ -599,8 +593,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
- if let Some(result) = self.cache.get(&t) {
- return result.clone();
+ if let Some(&result) = self.cache.get(&t) {
+ return Ok(result);
}
debug!("generalize: t={:?}", t);
@@ -670,10 +664,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
Ok(t)
}
_ => relate::super_relate_tys(self, t, t),
- };
+ }?;
- self.cache.insert(t, result.clone());
- return result;
+ self.cache.insert(t, result);
+ Ok(result)
}
fn regions(
@@ -694,7 +688,6 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
ty::RePlaceholder(..)
| ty::ReVar(..)
- | ty::ReEmpty(_)
| ty::ReStatic
| ty::ReEarlyBound(..)
| ty::ReFree(..) => {
@@ -749,10 +742,9 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
}
}
}
- ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
- if self.tcx().lazy_normalization() =>
- {
- assert_eq!(promoted, None);
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
+ assert_eq!(promoted, ());
+
let substs = self.relate_with_variance(
ty::Variance::Invariant,
ty::VarianceDiagInfo::default(),
@@ -856,10 +848,9 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
debug_assert_eq!(t, _t);
- debug!("ConstInferUnifier: t={:?}", t);
match t.kind() {
&ty::Infer(ty::TyVar(vid)) => {
@@ -883,12 +874,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
.borrow_mut()
.type_variables()
.new_var(self.for_universe, origin);
- let u = self.tcx().mk_ty_var(new_var_id);
- debug!(
- "ConstInferUnifier: replacing original vid={:?} with new={:?}",
- vid, u
- );
- Ok(u)
+ Ok(self.tcx().mk_ty_var(new_var_id))
}
}
}
@@ -914,7 +900,6 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
ty::RePlaceholder(..)
| ty::ReVar(..)
- | ty::ReEmpty(_)
| ty::ReStatic
| ty::ReEarlyBound(..)
| ty::ReFree(..) => {
@@ -932,14 +917,13 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn consts(
&mut self,
c: ty::Const<'tcx>,
_c: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug_assert_eq!(c, _c);
- debug!("ConstInferUnifier: c={:?}", c);
match c.kind() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
@@ -980,16 +964,16 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
}
}
}
- ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
- if self.tcx().lazy_normalization() =>
- {
- assert_eq!(promoted, None);
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
+ assert_eq!(promoted, ());
+
let substs = self.relate_with_variance(
ty::Variance::Invariant,
ty::VarianceDiagInfo::default(),
substs,
substs,
)?;
+
Ok(self.tcx().mk_const(ty::ConstS {
ty: c.ty(),
kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 20864c657..eb5afe828 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -58,14 +58,16 @@ use crate::traits::{
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
+use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan};
use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::Node;
use rustc_middle::dep_graph::DepContext;
use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
use rustc_middle::ty::{
self, error::TypeError, Binder, List, Region, Subst, Ty, TyCtxt, TypeFoldable,
TypeSuperVisitable, TypeVisitable,
@@ -77,7 +79,7 @@ use std::{cmp, fmt, iter};
mod note;
-mod need_type_info;
+pub(crate) mod need_type_info;
pub use need_type_info::TypeAnnotationNeeded;
pub mod nice_region_error;
@@ -95,11 +97,6 @@ pub(super) fn note_and_explain_region<'tcx>(
msg_span_from_free_region(tcx, region, alt_span)
}
- ty::ReEmpty(ty::UniverseIndex::ROOT) => ("the empty lifetime".to_owned(), alt_span),
-
- // uh oh, hope no user ever sees THIS
- ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), alt_span),
-
ty::RePlaceholder(_) => return,
// FIXME(#13998) RePlaceholder should probably print like
@@ -138,8 +135,6 @@ fn msg_span_from_free_region<'tcx>(
(msg, Some(span))
}
ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
- ty::ReEmpty(ty::UniverseIndex::ROOT) => ("an empty lifetime".to_owned(), alt_span),
- ty::ReEmpty(ui) => (format!("an empty lifetime in universe {:?}", ui), alt_span),
_ => bug!("{:?}", region),
}
}
@@ -249,17 +244,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
// Explain the region we are capturing.
match *hidden_region {
- ty::ReEmpty(ty::UniverseIndex::ROOT) => {
- // All lifetimes shorter than the function body are `empty` in
- // lexical region resolution. The default explanation of "an empty
- // lifetime" isn't really accurate here.
- let message = format!(
- "hidden type `{}` captures lifetime smaller than the function body",
- hidden_ty
- );
- err.span_note(span, &message);
- }
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) => {
+ ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
// Assuming regionck succeeded (*), we ought to always be
// capturing *some* region from the fn header, and hence it
// ought to be free. So under normal circumstances, we will go
@@ -385,7 +370,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
RegionResolutionError::UpperBoundUniverseConflict(
_,
_,
- var_universe,
+ _,
sup_origin,
sup_r,
) => {
@@ -396,7 +381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// placeholder. In practice, we expect more
// tailored errors that don't really use this
// value.
- let sub_r = self.tcx.mk_region(ty::ReEmpty(var_universe));
+ let sub_r = self.tcx.lifetimes.re_erased;
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
}
@@ -457,7 +442,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
/// Adds a note if the types come from similarly named crates
- fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: &TypeError<'tcx>) {
+ fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: TypeError<'tcx>) {
use hir::def_id::CrateNum;
use rustc_hir::definitions::DisambiguatedDefPathData;
use ty::print::Printer;
@@ -561,7 +546,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
};
- match *terr {
+ match terr {
TypeError::Sorts(ref exp_found) => {
// if they are both "path types", there's a chance of ambiguity
// due to different versions of the same crate
@@ -583,7 +568,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err: &mut Diagnostic,
cause: &ObligationCause<'tcx>,
exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
- terr: &TypeError<'tcx>,
+ terr: TypeError<'tcx>,
) {
match *cause.code() {
ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
@@ -739,12 +724,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err.help("...or use `match` instead of `let...else`");
}
_ => {
- if let ObligationCauseCode::BindingObligation(_, binding_span) =
- cause.code().peel_derives()
+ if let ObligationCauseCode::BindingObligation(_, span)
+ | ObligationCauseCode::ExprBindingObligation(_, span, ..)
+ = cause.code().peel_derives()
+ && let TypeError::RegionsPlaceholderMismatch = terr
{
- if matches!(terr, TypeError::RegionsPlaceholderMismatch) {
- err.span_note(*binding_span, "the lifetime requirement is introduced here");
- }
+ err.span_note(*span, "the lifetime requirement is introduced here");
}
}
}
@@ -960,12 +945,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
+ fn normalize_fn_sig_for_diagnostic(&self, sig: ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> {
+ if let Some(normalize) = &self.normalize_fn_sig_for_diagnostic {
+ normalize(self, sig)
+ } else {
+ sig
+ }
+ }
+
/// Given two `fn` signatures highlight only sub-parts that are different.
fn cmp_fn_sig(
&self,
sig1: &ty::PolyFnSig<'tcx>,
sig2: &ty::PolyFnSig<'tcx>,
) -> (DiagnosticStyledString, DiagnosticStyledString) {
+ let sig1 = &self.normalize_fn_sig_for_diagnostic(*sig1);
+ let sig2 = &self.normalize_fn_sig_for_diagnostic(*sig2);
+
let get_lifetimes = |sig| {
use rustc_hir::def::Namespace;
let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS)
@@ -1422,9 +1418,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// the message in `secondary_span` as the primary label, and apply the message that would
/// otherwise be used for the primary label on the `secondary_span` `Span`. This applies on
/// E0271, like `src/test/ui/issues/issue-39970.stderr`.
- #[tracing::instrument(
+ #[instrument(
level = "debug",
- skip(self, diag, secondary_span, swap_secondary_and_primary, force_label)
+ skip(self, diag, secondary_span, swap_secondary_and_primary, prefer_label)
)]
pub fn note_type_err(
&self,
@@ -1432,9 +1428,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>,
secondary_span: Option<(Span, String)>,
mut values: Option<ValuePairs<'tcx>>,
- terr: &TypeError<'tcx>,
+ terr: TypeError<'tcx>,
swap_secondary_and_primary: bool,
- force_label: bool,
+ prefer_label: bool,
) {
let span = cause.span();
@@ -1574,23 +1570,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Some(values) => {
let values = self.resolve_vars_if_possible(values);
let (is_simple_error, exp_found) = match values {
- ValuePairs::Terms(infer::ExpectedFound {
- expected: ty::Term::Ty(expected),
- found: ty::Term::Ty(found),
- }) => {
- let is_simple_err = expected.is_simple_text() && found.is_simple_text();
- OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
- .report(diag);
-
- (
- is_simple_err,
- Mismatch::Variable(infer::ExpectedFound { expected, found }),
- )
+ ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
+ match (expected.unpack(), found.unpack()) {
+ (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
+ let is_simple_err =
+ expected.is_simple_text() && found.is_simple_text();
+ OpaqueTypesVisitor::visit_expected_found(
+ self.tcx, expected, found, span,
+ )
+ .report(diag);
+
+ (
+ is_simple_err,
+ Mismatch::Variable(infer::ExpectedFound { expected, found }),
+ )
+ }
+ (ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
+ (false, Mismatch::Fixed("constant"))
+ }
+ _ => (false, Mismatch::Fixed("type")),
+ }
}
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
(false, Mismatch::Fixed("trait"))
}
- _ => (false, Mismatch::Fixed("type")),
+ ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
};
let vals = match self.values_str(values) {
Some((expected, found)) => Some((expected, found)),
@@ -1612,7 +1616,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
TypeError::ObjectUnsafeCoercion(_) => {}
_ => {
let mut label_or_note = |span: Span, msg: &str| {
- if force_label || &[span] == diag.span.primary_spans() {
+ if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
diag.span_label(span, msg);
} else {
diag.span_note(span, msg);
@@ -1662,6 +1666,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pos.col.to_usize() + 1,
)
}
+ (true, ty::Projection(proj))
+ if self.tcx.def_kind(proj.item_def_id)
+ == DefKind::ImplTraitPlaceholder =>
+ {
+ let sm = self.tcx.sess.source_map();
+ let pos = sm.lookup_char_pos(self.tcx.def_span(proj.item_def_id).lo());
+ format!(
+ " (trait associated opaque type at <{}:{}:{}>)",
+ sm.filename_for_diagnostics(&pos.file.name),
+ pos.line,
+ pos.col.to_usize() + 1,
+ )
+ }
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
@@ -1713,7 +1730,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty::error::TypeError::Sorts(terr)
if exp_found.map_or(false, |ef| terr.found == ef.found) =>
{
- Some(*terr)
+ Some(terr)
}
_ => exp_found,
};
@@ -1750,6 +1767,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
&& let Some(def_id) = def_id.as_local()
+ && terr.involves_regions()
{
let span = self.tcx.def_span(def_id);
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
@@ -2037,22 +2055,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
(exp_found.expected.kind(), exp_found.found.kind())
{
if let ty::Adt(found_def, found_substs) = *found_ty.kind() {
- let path_str = format!("{:?}", exp_def);
if exp_def == &found_def {
- let opt_msg = "you can convert from `&Option<T>` to `Option<&T>` using \
- `.as_ref()`";
- let result_msg = "you can convert from `&Result<T, E>` to \
- `Result<&T, &E>` using `.as_ref()`";
let have_as_ref = &[
- ("std::option::Option", opt_msg),
- ("core::option::Option", opt_msg),
- ("std::result::Result", result_msg),
- ("core::result::Result", result_msg),
+ (
+ sym::Option,
+ "you can convert from `&Option<T>` to `Option<&T>` using \
+ `.as_ref()`",
+ ),
+ (
+ sym::Result,
+ "you can convert from `&Result<T, E>` to \
+ `Result<&T, &E>` using `.as_ref()`",
+ ),
];
- if let Some(msg) = have_as_ref
- .iter()
- .find_map(|(path, msg)| (&path_str == path).then_some(msg))
- {
+ if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
+ self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
+ }) {
let mut show_suggestion = true;
for (exp_ty, found_ty) in
iter::zip(exp_substs.types(), found_substs.types())
@@ -2078,7 +2096,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
diag.span_suggestion(
span,
*msg,
- format!("{}.as_ref()", snippet),
+ // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&`
+ format!("{}.as_ref()", snippet.trim_start_matches('&')),
Applicability::MachineApplicable,
);
}
@@ -2091,7 +2110,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn report_and_explain_type_error(
&self,
trace: TypeTrace<'tcx>,
- terr: &TypeError<'tcx>,
+ terr: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
use crate::traits::ObligationCauseCode::MatchExpressionArm;
@@ -2254,11 +2273,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return None;
}
- Some(match (exp_found.expected, exp_found.found) {
- (ty::Term::Ty(expected), ty::Term::Ty(found)) => self.cmp(expected, found),
- (expected, found) => (
- DiagnosticStyledString::highlighted(expected.to_string()),
- DiagnosticStyledString::highlighted(found.to_string()),
+ Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) {
+ (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => self.cmp(expected, found),
+ _ => (
+ DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
+ DiagnosticStyledString::highlighted(exp_found.found.to_string()),
),
})
}
@@ -2376,19 +2395,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
type_param_span: Option<(Span, bool)>,
bound_kind: GenericKind<'tcx>,
sub: S,
+ add_lt_sugg: Option<(Span, String)>,
) {
let msg = "consider adding an explicit lifetime bound";
if let Some((sp, has_lifetimes)) = type_param_span {
let suggestion =
if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
- err.span_suggestion_verbose(
- sp,
- &format!("{}...", msg),
- suggestion,
+ let mut suggestions = vec![(sp, suggestion)];
+ if let Some(add_lt_sugg) = add_lt_sugg {
+ suggestions.push(add_lt_sugg);
+ }
+ err.multipart_suggestion_verbose(
+ format!("{msg}..."),
+ suggestions,
Applicability::MaybeIncorrect, // Issue #41966
);
} else {
- let consider = format!("{} `{}: {}`...", msg, bound_kind, sub,);
+ let consider = format!("{} `{}: {}`...", msg, bound_kind, sub);
err.help(&consider);
}
}
@@ -2404,7 +2427,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let mut sugg =
vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
- if let Some(lt) = add_lt_sugg {
+ if let Some(lt) = add_lt_sugg.clone() {
sugg.push(lt);
sugg.rotate_right(1);
}
@@ -2510,7 +2533,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// for the bound is not suitable for suggestions when `-Zverbose` is set because it
// uses `Debug` output, so we handle it specially here so that suggestions are
// always correct.
- binding_suggestion(&mut err, type_param_span, bound_kind, name);
+ binding_suggestion(&mut err, type_param_span, bound_kind, name, None);
err
}
@@ -2523,7 +2546,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"{} may not live long enough",
labeled_user_string
);
- binding_suggestion(&mut err, type_param_span, bound_kind, "'static");
+ binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None);
err
}
@@ -2557,7 +2580,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
new_binding_suggestion(&mut err, type_param_span);
}
_ => {
- binding_suggestion(&mut err, type_param_span, bound_kind, new_lt);
+ binding_suggestion(
+ &mut err,
+ type_param_span,
+ bound_kind,
+ new_lt,
+ add_lt_sugg,
+ );
}
}
}
@@ -2659,67 +2688,95 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// Float types, respectively). When comparing two ADTs, these rules apply recursively.
pub fn same_type_modulo_infer(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
let (a, b) = self.resolve_vars_if_possible((a, b));
- match (a.kind(), b.kind()) {
- (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) => {
- if def_a != def_b {
- return false;
- }
+ SameTypeModuloInfer(self).relate(a, b).is_ok()
+ }
+}
- substs_a
- .types()
- .zip(substs_b.types())
- .all(|(a, b)| self.same_type_modulo_infer(a, b))
- }
- (&ty::FnDef(did_a, substs_a), &ty::FnDef(did_b, substs_b)) => {
- if did_a != did_b {
- return false;
- }
+struct SameTypeModuloInfer<'a, 'tcx>(&'a InferCtxt<'a, 'tcx>);
- substs_a
- .types()
- .zip(substs_b.types())
- .all(|(a, b)| self.same_type_modulo_infer(a, b))
- }
- (&ty::Int(_) | &ty::Uint(_), &ty::Infer(ty::InferTy::IntVar(_)))
+impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.0.tcx
+ }
+
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ // Unused, only for consts which we treat as always equal
+ ty::ParamEnv::empty()
+ }
+
+ fn tag(&self) -> &'static str {
+ "SameTypeModuloInfer"
+ }
+
+ fn a_is_expected(&self) -> bool {
+ true
+ }
+
+ fn relate_with_variance<T: relate::Relate<'tcx>>(
+ &mut self,
+ _variance: ty::Variance,
+ _info: ty::VarianceDiagInfo<'tcx>,
+ a: T,
+ b: T,
+ ) -> relate::RelateResult<'tcx, T> {
+ self.relate(a, b)
+ }
+
+ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+ match (a.kind(), b.kind()) {
+ (ty::Int(_) | ty::Uint(_), ty::Infer(ty::InferTy::IntVar(_)))
| (
- &ty::Infer(ty::InferTy::IntVar(_)),
- &ty::Int(_) | &ty::Uint(_) | &ty::Infer(ty::InferTy::IntVar(_)),
+ ty::Infer(ty::InferTy::IntVar(_)),
+ ty::Int(_) | ty::Uint(_) | ty::Infer(ty::InferTy::IntVar(_)),
)
- | (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
+ | (ty::Float(_), ty::Infer(ty::InferTy::FloatVar(_)))
| (
- &ty::Infer(ty::InferTy::FloatVar(_)),
- &ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)),
+ ty::Infer(ty::InferTy::FloatVar(_)),
+ ty::Float(_) | ty::Infer(ty::InferTy::FloatVar(_)),
)
- | (&ty::Infer(ty::InferTy::TyVar(_)), _)
- | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
- (&ty::Ref(_, ty_a, mut_a), &ty::Ref(_, ty_b, mut_b)) => {
- mut_a == mut_b && self.same_type_modulo_infer(ty_a, ty_b)
- }
- (&ty::RawPtr(a), &ty::RawPtr(b)) => {
- a.mutbl == b.mutbl && self.same_type_modulo_infer(a.ty, b.ty)
- }
- (&ty::Slice(a), &ty::Slice(b)) => self.same_type_modulo_infer(a, b),
- (&ty::Array(a_ty, a_ct), &ty::Array(b_ty, b_ct)) => {
- self.same_type_modulo_infer(a_ty, b_ty) && a_ct == b_ct
- }
- (&ty::Tuple(a), &ty::Tuple(b)) => {
- if a.len() != b.len() {
- return false;
- }
- std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b))
- }
- (&ty::FnPtr(a), &ty::FnPtr(b)) => {
- let a = a.skip_binder().inputs_and_output;
- let b = b.skip_binder().inputs_and_output;
- if a.len() != b.len() {
- return false;
- }
- std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b))
- }
- // FIXME(compiler-errors): This needs to be generalized more
- _ => a == b,
+ | (ty::Infer(ty::InferTy::TyVar(_)), _)
+ | (_, ty::Infer(ty::InferTy::TyVar(_))) => Ok(a),
+ (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Mismatch),
+ _ => relate::super_relate_tys(self, a, b),
+ }
+ }
+
+ fn regions(
+ &mut self,
+ a: ty::Region<'tcx>,
+ b: ty::Region<'tcx>,
+ ) -> RelateResult<'tcx, ty::Region<'tcx>> {
+ if (a.is_var() && b.is_free_or_static())
+ || (b.is_var() && a.is_free_or_static())
+ || (a.is_var() && b.is_var())
+ || a == b
+ {
+ Ok(a)
+ } else {
+ Err(TypeError::Mismatch)
}
}
+
+ fn binders<T>(
+ &mut self,
+ a: ty::Binder<'tcx, T>,
+ b: ty::Binder<'tcx, T>,
+ ) -> relate::RelateResult<'tcx, ty::Binder<'tcx, T>>
+ where
+ T: relate::Relate<'tcx>,
+ {
+ Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
+ }
+
+ fn consts(
+ &mut self,
+ a: ty::Const<'tcx>,
+ _b: ty::Const<'tcx>,
+ ) -> relate::RelateResult<'tcx, ty::Const<'tcx>> {
+ // FIXME(compiler-errors): This could at least do some first-order
+ // relation
+ Ok(a)
+ }
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
@@ -2781,12 +2838,12 @@ pub enum FailureCode {
}
pub trait ObligationCauseExt<'tcx> {
- fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode;
+ fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
fn as_requirement_str(&self) -> &'static str;
}
impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
- fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
+ fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode {
use self::FailureCode::*;
use crate::traits::ObligationCauseCode::*;
match self.code() {
@@ -2823,7 +2880,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
TypeError::IntrinsicCast => {
Error0308("cannot coerce intrinsics to function pointers")
}
- TypeError::ObjectUnsafeCoercion(did) => Error0038(*did),
+ TypeError::ObjectUnsafeCoercion(did) => Error0038(did),
_ => Error0308("mismatched types"),
},
}
@@ -2853,6 +2910,30 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
}
}
+/// Newtype to allow implementing IntoDiagnosticArg
+pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>);
+
+impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ use crate::traits::ObligationCauseCode::*;
+ let kind = match self.0.code() {
+ CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat",
+ CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => "type_compat",
+ CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => "const_compat",
+ ExprAssignable => "expr_assignable",
+ IfExpression { .. } => "if_else_different",
+ IfExpressionWithNoElse => "no_else",
+ MainFunctionType => "fn_main_correct_type",
+ StartFunctionType => "fn_start_correct_type",
+ IntrinsicType => "intristic_correct_type",
+ MethodReceiver => "method_correct_type",
+ _ => "other",
+ }
+ .into();
+ rustc_errors::DiagnosticArgValue::Str(kind)
+ }
+}
+
/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
/// extra information about each type, but we only care about the category.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 561d1354e..cb2be9358 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -1,6 +1,10 @@
+use crate::errors::{
+ AmbigousImpl, AmbigousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator,
+ SourceKindMultiSuggestion, SourceKindSubdiag,
+};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::InferCtxt;
-use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def::{CtorOf, DefKind, Namespace};
@@ -14,6 +18,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
use rustc_middle::ty::{self, DefIdTree, InferConst};
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
+use rustc_session::SessionDiagnostic;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{BytePos, Span};
use std::borrow::Cow;
@@ -60,38 +65,49 @@ pub struct InferenceDiagnosticsParentData {
name: String,
}
+#[derive(Clone)]
pub enum UnderspecifiedArgKind {
Type { prefix: Cow<'static, str> },
Const { is_parameter: bool },
}
impl InferenceDiagnosticsData {
- /// Generate a label for a generic argument which can't be inferred. When not
- /// much is known about the argument, `use_diag` may be used to describe the
- /// labeled value.
- fn cannot_infer_msg(&self) -> String {
- if self.name == "_" && matches!(self.kind, UnderspecifiedArgKind::Type { .. }) {
- return "cannot infer type".to_string();
- }
-
- let suffix = match &self.parent {
- Some(parent) => parent.suffix_string(),
- None => String::new(),
- };
-
- // For example: "cannot infer type for type parameter `T`"
- format!("cannot infer {} `{}`{}", self.kind.prefix_string(), self.name, suffix)
+ fn can_add_more_info(&self) -> bool {
+ !(self.name == "_" && matches!(self.kind, UnderspecifiedArgKind::Type { .. }))
}
- fn where_x_is_specified(&self, in_type: Ty<'_>) -> String {
+ fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str {
if in_type.is_ty_infer() {
- String::new()
+ "empty"
} else if self.name == "_" {
// FIXME: Consider specializing this message if there is a single `_`
// in the type.
- ", where the placeholders `_` are specified".to_string()
+ "underscore"
} else {
- format!(", where the {} `{}` is specified", self.kind.prefix_string(), self.name)
+ "has_name"
+ }
+ }
+
+ /// Generate a label for a generic argument which can't be inferred. When not
+ /// much is known about the argument, `use_diag` may be used to describe the
+ /// labeled value.
+ fn make_bad_error(&self, span: Span) -> InferenceBadError<'_> {
+ let has_parent = self.parent.is_some();
+ let bad_kind = if self.can_add_more_info() { "more_info" } else { "other" };
+ let (parent_prefix, parent_name) = self
+ .parent
+ .as_ref()
+ .map(|parent| (parent.prefix, parent.name.clone()))
+ .unwrap_or_default();
+ InferenceBadError {
+ span,
+ bad_kind,
+ prefix_kind: self.kind.clone(),
+ prefix: self.kind.try_get_prefix().unwrap_or_default(),
+ name: self.name.clone(),
+ has_parent,
+ parent_prefix,
+ parent_name,
}
}
}
@@ -113,18 +129,24 @@ impl InferenceDiagnosticsParentData {
fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<InferenceDiagnosticsParentData> {
Self::for_parent_def_id(tcx, tcx.parent(def_id))
}
+}
- fn suffix_string(&self) -> String {
- format!(" declared on the {} `{}`", self.prefix, self.name)
+impl IntoDiagnosticArg for UnderspecifiedArgKind {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ let kind = match self {
+ Self::Type { .. } => "type",
+ Self::Const { is_parameter: true } => "const_with_param",
+ Self::Const { is_parameter: false } => "const",
+ };
+ rustc_errors::DiagnosticArgValue::Str(kind.into())
}
}
impl UnderspecifiedArgKind {
- fn prefix_string(&self) -> Cow<'static, str> {
+ fn try_get_prefix(&self) -> Option<&str> {
match self {
- Self::Type { prefix } => format!("type for {}", prefix).into(),
- Self::Const { is_parameter: true } => "the value of const parameter".into(),
- Self::Const { is_parameter: false } => "the value of the constant".into(),
+ Self::Type { prefix } => Some(prefix.as_ref()),
+ Self::Const { .. } => None,
}
}
}
@@ -177,7 +199,7 @@ fn ty_to_string<'tcx>(infcx: &InferCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> String {
}
/// We don't want to directly use `ty_to_string` for closures as their type isn't really
-/// something users are familar with. Directly printing the `fn_sig` of closures also
+/// something users are familiar with. Directly printing the `fn_sig` of closures also
/// doesn't work as they actually use the "rust-call" API.
fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> String {
let ty::Closure(_, substs) = ty.kind() else { unreachable!() };
@@ -303,11 +325,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
arg_data: InferenceDiagnosticsData,
error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let error_code = error_code.into();
- let mut err =
- self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code);
- err.span_label(span, arg_data.cannot_infer_msg());
- err
+ let source_kind = "other";
+ let source_name = "";
+ let failure_span = None;
+ let infer_subdiags = Vec::new();
+ let multi_suggestions = Vec::new();
+ let bad_label = Some(arg_data.make_bad_error(span));
+ match error_code {
+ TypeAnnotationNeeded::E0282 => AnnotationRequired {
+ span,
+ source_kind,
+ source_name,
+ failure_span,
+ infer_subdiags,
+ multi_suggestions,
+ bad_label,
+ }
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+ TypeAnnotationNeeded::E0283 => AmbigousImpl {
+ span,
+ source_kind,
+ source_name,
+ failure_span,
+ infer_subdiags,
+ multi_suggestions,
+ bad_label,
+ }
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+ TypeAnnotationNeeded::E0284 => AmbigousReturn {
+ span,
+ source_kind,
+ source_name,
+ failure_span,
+ infer_subdiags,
+ multi_suggestions,
+ bad_label,
+ }
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+ }
}
pub fn emit_inference_failure_err(
@@ -340,48 +395,39 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return self.bad_inference_failure_err(failure_span, arg_data, error_code)
};
- let error_code = error_code.into();
- let mut err = self.tcx.sess.struct_span_err_with_code(
- span,
- &format!("type annotations needed{}", kind.ty_msg(self)),
- error_code,
- );
-
- if should_label_span && !failure_span.overlaps(span) {
- err.span_label(failure_span, "type must be known at this point");
- }
+ let (source_kind, name) = kind.ty_localized_msg(self);
+ let failure_span = if should_label_span && !failure_span.overlaps(span) {
+ Some(failure_span)
+ } else {
+ None
+ };
+ let mut infer_subdiags = Vec::new();
+ let mut multi_suggestions = Vec::new();
match kind {
InferSourceKind::LetBinding { insert_span, pattern_name, ty } => {
- let suggestion_msg = if let Some(name) = pattern_name {
- format!(
- "consider giving `{}` an explicit type{}",
- name,
- arg_data.where_x_is_specified(ty)
- )
- } else {
- format!(
- "consider giving this pattern a type{}",
- arg_data.where_x_is_specified(ty)
- )
- };
- err.span_suggestion_verbose(
- insert_span,
- &suggestion_msg,
- format!(": {}", ty_to_string(self, ty)),
- Applicability::HasPlaceholders,
- );
+ infer_subdiags.push(SourceKindSubdiag::LetLike {
+ span: insert_span,
+ name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
+ x_kind: arg_data.where_x_is_kind(ty),
+ prefix_kind: arg_data.kind.clone(),
+ prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
+ arg_name: arg_data.name,
+ kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
+ type_name: ty_to_string(self, ty),
+ });
}
InferSourceKind::ClosureArg { insert_span, ty } => {
- err.span_suggestion_verbose(
- insert_span,
- &format!(
- "consider giving this closure parameter an explicit type{}",
- arg_data.where_x_is_specified(ty)
- ),
- format!(": {}", ty_to_string(self, ty)),
- Applicability::HasPlaceholders,
- );
+ infer_subdiags.push(SourceKindSubdiag::LetLike {
+ span: insert_span,
+ name: String::new(),
+ x_kind: arg_data.where_x_is_kind(ty),
+ prefix_kind: arg_data.kind.clone(),
+ prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
+ arg_name: arg_data.name,
+ kind: "closure",
+ type_name: ty_to_string(self, ty),
+ });
}
InferSourceKind::GenericArg {
insert_span,
@@ -393,19 +439,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let generics = self.tcx.generics_of(generics_def_id);
let is_type = matches!(arg.unpack(), GenericArgKind::Type(_));
- let cannot_infer_msg = format!(
- "cannot infer {} of the {} parameter `{}`{}",
- if is_type { "type" } else { "the value" },
- if is_type { "type" } else { "const" },
- generics.params[argument_index].name,
- // We use the `generics_def_id` here, as even when suggesting `None::<T>`,
- // the type parameter `T` was still declared on the enum, not on the
- // variant.
+ let (parent_exists, parent_prefix, parent_name) =
InferenceDiagnosticsParentData::for_parent_def_id(self.tcx, generics_def_id)
- .map_or(String::new(), |parent| parent.suffix_string()),
- );
+ .map_or((false, String::new(), String::new()), |parent| {
+ (true, parent.prefix.to_string(), parent.name)
+ });
- err.span_label(span, cannot_infer_msg);
+ infer_subdiags.push(SourceKindSubdiag::GenericLabel {
+ span,
+ is_type,
+ param_name: generics.params[argument_index].name.to_string(),
+ parent_exists,
+ parent_prefix,
+ parent_name,
+ });
let args = fmt_printer(self, Namespace::TypeNS)
.comma_sep(generic_args.iter().copied().map(|arg| {
@@ -435,15 +482,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.unwrap()
.into_buffer();
- err.span_suggestion_verbose(
- insert_span,
- &format!(
- "consider specifying the generic argument{}",
- pluralize!(generic_args.len()),
- ),
- format!("::<{}>", args),
- Applicability::HasPlaceholders,
- );
+ infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
+ span: insert_span,
+ arg_count: generic_args.len(),
+ args,
+ });
}
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
let printer = fmt_printer(self, Namespace::ValueNS);
@@ -468,37 +511,54 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => "",
};
- let suggestion = vec![
- (receiver.span.shrink_to_lo(), format!("{def_path}({adjustment}")),
- (receiver.span.shrink_to_hi().with_hi(successor.1), successor.0.to_string()),
- ];
- err.multipart_suggestion_verbose(
- "try using a fully qualified path to specify the expected types",
- suggestion,
- Applicability::HasPlaceholders,
- );
+ multi_suggestions.push(SourceKindMultiSuggestion::new_fully_qualified(
+ receiver.span,
+ def_path,
+ adjustment,
+ successor,
+ ));
}
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
- let ret = ty_to_string(self, ty);
- let (arrow, post) = match data {
- FnRetTy::DefaultReturn(_) => ("-> ", " "),
- _ => ("", ""),
- };
- let suggestion = match should_wrap_expr {
- Some(end_span) => vec![
- (data.span(), format!("{}{}{}{{ ", arrow, ret, post)),
- (end_span, " }".to_string()),
- ],
- None => vec![(data.span(), format!("{}{}{}", arrow, ret, post))],
- };
- err.multipart_suggestion_verbose(
- "try giving this closure an explicit return type",
- suggestion,
- Applicability::HasPlaceholders,
- );
+ let ty_info = ty_to_string(self, ty);
+ multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return(
+ ty_info,
+ data,
+ should_wrap_expr,
+ ));
+ }
+ }
+ match error_code {
+ TypeAnnotationNeeded::E0282 => AnnotationRequired {
+ span,
+ source_kind,
+ source_name: &name,
+ failure_span,
+ infer_subdiags,
+ multi_suggestions,
+ bad_label: None,
+ }
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+ TypeAnnotationNeeded::E0283 => AmbigousImpl {
+ span,
+ source_kind,
+ source_name: &name,
+ failure_span,
+ infer_subdiags,
+ multi_suggestions,
+ bad_label: None,
+ }
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+ TypeAnnotationNeeded::E0284 => AmbigousReturn {
+ span,
+ source_kind,
+ source_name: &name,
+ failure_span,
+ infer_subdiags,
+ multi_suggestions,
+ bad_label: None,
}
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
}
- err
}
pub fn need_type_info_err_in_generator(
@@ -510,15 +570,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let ty = self.resolve_vars_if_possible(ty);
let data = self.extract_inference_diagnostics_data(ty.into(), None);
- let mut err = struct_span_err!(
- self.tcx.sess,
+ NeedTypeInfoInGenerator {
+ bad_label: data.make_bad_error(span),
span,
- E0698,
- "type inside {} must be known in this context",
- kind,
- );
- err.span_label(span, data.cannot_infer_msg());
- err
+ generator_kind: GeneratorKindAsDiagArg(kind),
+ }
+ .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+ }
+}
+
+pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
+
+impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ let kind = match self.0 {
+ hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
+ hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
+ hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
+ hir::GeneratorKind::Gen => "generator",
+ };
+ rustc_errors::DiagnosticArgValue::Str(kind.into())
}
}
@@ -579,22 +650,22 @@ impl<'tcx> InferSource<'tcx> {
}
impl<'tcx> InferSourceKind<'tcx> {
- fn ty_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> String {
+ fn ty_localized_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> (&'static str, String) {
match *self {
InferSourceKind::LetBinding { ty, .. }
| InferSourceKind::ClosureArg { ty, .. }
| InferSourceKind::ClosureReturn { ty, .. } => {
if ty.is_closure() {
- format!(" for the closure `{}`", closure_as_fn_str(infcx, ty))
+ ("closure", closure_as_fn_str(infcx, ty))
} else if !ty.is_ty_infer() {
- format!(" for `{}`", ty_to_string(infcx, ty))
+ ("normal", ty_to_string(infcx, ty))
} else {
- String::new()
+ ("other", String::new())
}
}
// FIXME: We should be able to add some additional info here.
InferSourceKind::GenericArg { .. }
- | InferSourceKind::FullyQualifiedMethodCall { .. } => String::new(),
+ | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()),
}
}
}
@@ -830,7 +901,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
}
}
}
- hir::ExprKind::MethodCall(segment, _, _) => {
+ hir::ExprKind::MethodCall(segment, ..) => {
if let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id) {
let generics = tcx.generics_of(def_id);
let insertable: Option<_> = try {
@@ -838,7 +909,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
None?
}
let substs = self.node_substs_opt(expr.hir_id)?;
- let span = tcx.hir().span(segment.hir_id?);
+ let span = tcx.hir().span(segment.hir_id);
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
InsertableGenericArgs {
insert_span,
@@ -886,13 +957,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
path.segments
.iter()
.filter_map(move |segment| {
- let res = segment.res?;
+ let res = segment.res;
let generics_def_id = tcx.res_generics_def_id(res)?;
let generics = tcx.generics_of(generics_def_id);
if generics.has_impl_trait() {
return None;
}
- let span = tcx.hir().span(segment.hir_id?);
+ let span = tcx.hir().span(segment.hir_id);
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
Some(InsertableGenericArgs {
insert_span,
@@ -925,7 +996,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
if !segment.infer_args || generics.has_impl_trait() {
None?;
}
- let span = tcx.hir().span(segment.hir_id?);
+ let span = tcx.hir().span(segment.hir_id);
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id }
};
@@ -1061,7 +1132,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
let generic_args = &generics.own_substs_no_defaults(tcx, substs)
[generics.own_counts().lifetimes..];
let span = match expr.kind {
- ExprKind::MethodCall(path, _, _) => path.ident.span,
+ ExprKind::MethodCall(path, ..) => path.ident.span,
_ => expr.span,
};
@@ -1110,7 +1181,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
})
.any(|generics| generics.has_impl_trait())
};
- if let ExprKind::MethodCall(path, args, span) = expr.kind
+ if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind
&& let Some(substs) = self.node_substs_opt(expr.hir_id)
&& substs.iter().any(|arg| self.generic_arg_contains_target(arg))
&& let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
@@ -1118,12 +1189,12 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
&& !has_impl_trait(def_id)
{
let successor =
- args.get(1).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
+ args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
let substs = self.infcx.resolve_vars_if_possible(substs);
self.update_infer_source(InferSource {
span: path.ident.span,
kind: InferSourceKind::FullyQualifiedMethodCall {
- receiver: args.first().unwrap(),
+ receiver,
successor,
substs,
def_id,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
index 9a2ab3e32..3a4320a9a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -1,6 +1,9 @@
//! Error Reporting for Anonymous Region Lifetime Errors
//! where both the regions are anonymous.
+use crate::errors::AddLifetimeParamsSuggestion;
+use crate::errors::LifetimeMismatch;
+use crate::errors::LifetimeMismatchLabels;
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
@@ -8,11 +11,10 @@ use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::SubregionOrigin;
use crate::infer::TyCtxt;
-use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
-use rustc_hir as hir;
-use rustc_hir::{GenericParamKind, Ty};
+use rustc_errors::AddSubdiagnostic;
+use rustc_errors::{Diagnostic, ErrorGuaranteed};
+use rustc_hir::Ty;
use rustc_middle::ty::Region;
-use rustc_span::symbol::kw;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Print the error message for lifetime errors when both the concerned regions are anonymous.
@@ -98,137 +100,50 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let sub_is_ret_type =
self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
- let span_label_var1 = match anon_param_sup.pat.simple_ident() {
- Some(simple_ident) => format!(" from `{}`", simple_ident),
- None => String::new(),
- };
-
- let span_label_var2 = match anon_param_sub.pat.simple_ident() {
- Some(simple_ident) => format!(" into `{}`", simple_ident),
- None => String::new(),
- };
-
debug!(
"try_report_anon_anon_conflict: sub_is_ret_type={:?} sup_is_ret_type={:?}",
sub_is_ret_type, sup_is_ret_type
);
- let mut err = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch");
-
- match (sup_is_ret_type, sub_is_ret_type) {
+ let labels = match (sup_is_ret_type, sub_is_ret_type) {
(ret_capture @ Some(ret_span), _) | (_, ret_capture @ Some(ret_span)) => {
let param_span =
if sup_is_ret_type == ret_capture { ty_sub.span } else { ty_sup.span };
-
- err.span_label(
+ LifetimeMismatchLabels::InRet {
param_span,
- "this parameter and the return type are declared with different lifetimes...",
- );
- err.span_label(ret_span, "");
- err.span_label(span, format!("...but data{} is returned here", span_label_var1));
- }
-
- (None, None) => {
- if ty_sup.hir_id == ty_sub.hir_id {
- err.span_label(ty_sup.span, "this type is declared with multiple lifetimes...");
- err.span_label(ty_sub.span, "");
- err.span_label(span, "...but data with one lifetime flows into the other here");
- } else {
- err.span_label(
- ty_sup.span,
- "these two types are declared with different lifetimes...",
- );
- err.span_label(ty_sub.span, "");
- err.span_label(
- span,
- format!("...but data{} flows{} here", span_label_var1, span_label_var2),
- );
+ ret_span,
+ span,
+ label_var1: anon_param_sup.pat.simple_ident(),
}
}
- }
- if suggest_adding_lifetime_params(self.tcx(), sub, ty_sup, ty_sub, &mut err) {
- err.note("each elided lifetime in input position becomes a distinct lifetime");
- }
+ (None, None) => LifetimeMismatchLabels::Normal {
+ hir_equal: ty_sup.hir_id == ty_sub.hir_id,
+ ty_sup: ty_sup.span,
+ ty_sub: ty_sub.span,
+ span,
+ sup: anon_param_sup.pat.simple_ident(),
+ sub: anon_param_sub.pat.simple_ident(),
+ },
+ };
- let reported = err.emit();
+ let suggestion =
+ AddLifetimeParamsSuggestion { tcx: self.tcx(), sub, ty_sup, ty_sub, add_note: true };
+ let err = LifetimeMismatch { span, labels, suggestion };
+ let reported = self.tcx().sess.emit_err(err);
Some(reported)
}
}
+/// Currently only used in rustc_borrowck, probably should be
+/// removed in favour of public_errors::AddLifetimeParamsSuggestion
pub fn suggest_adding_lifetime_params<'tcx>(
tcx: TyCtxt<'tcx>,
sub: Region<'tcx>,
- ty_sup: &Ty<'_>,
- ty_sub: &Ty<'_>,
+ ty_sup: &'tcx Ty<'_>,
+ ty_sub: &'tcx Ty<'_>,
err: &mut Diagnostic,
-) -> bool {
- let (
- hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. },
- hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. },
- ) = (ty_sub, ty_sup) else {
- return false;
- };
-
- if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() {
- return false;
- };
-
- let Some(anon_reg) = tcx.is_suitable_region(sub) else {
- return false;
- };
-
- let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
-
- let node = tcx.hir().get(hir_id);
- let is_impl = matches!(&node, hir::Node::ImplItem(_));
- let generics = match node {
- hir::Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, ref generics, ..), .. })
- | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
- | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
- _ => return false,
- };
-
- let suggestion_param_name = generics
- .params
- .iter()
- .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
- .map(|p| p.name.ident().name)
- .find(|i| *i != kw::UnderscoreLifetime);
- let introduce_new = suggestion_param_name.is_none();
- let suggestion_param_name =
- suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
-
- debug!(?lifetime_sup.span);
- debug!(?lifetime_sub.span);
- let make_suggestion = |span: rustc_span::Span| {
- if span.is_empty() {
- (span, format!("{}, ", suggestion_param_name))
- } else if let Ok("&") = tcx.sess.source_map().span_to_snippet(span).as_deref() {
- (span.shrink_to_hi(), format!("{} ", suggestion_param_name))
- } else {
- (span, suggestion_param_name.clone())
- }
- };
- let mut suggestions =
- vec![make_suggestion(lifetime_sub.span), make_suggestion(lifetime_sup.span)];
-
- if introduce_new {
- let new_param_suggestion =
- if let Some(first) = generics.params.iter().find(|p| !p.name.ident().span.is_empty()) {
- (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name))
- } else {
- (generics.span, format!("<{}>", suggestion_param_name))
- };
-
- suggestions.push(new_param_suggestion);
- }
-
- let mut sugg = String::from("consider introducing a named lifetime parameter");
- if is_impl {
- sugg.push_str(" and update trait if needed");
- }
- err.multipart_suggestion(sugg, suggestions, Applicability::MaybeIncorrect);
-
- true
+) {
+ let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false };
+ suggestion.add_to_diagnostic(err);
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
index c1b201da6..d8f540b74 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -91,7 +91,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
hir::TyKind::TraitObject(bounds, ..) => {
for bound in bounds {
self.current_index.shift_in(1);
- self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
+ self.visit_poly_trait_ref(bound);
self.current_index.shift_out(1);
}
}
@@ -103,7 +103,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
// Find the index of the named region that was part of the
// error. We will then search the function parameters for a bound
// region at the right depth with the same index
- (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => {
+ (Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
if id == def_id {
self.found_type = Some(arg);
@@ -133,7 +133,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
Some(
rl::Region::Static
| rl::Region::Free(_, _)
- | rl::Region::EarlyBound(_, _)
+ | rl::Region::EarlyBound(_)
| rl::Region::LateBound(_, _, _),
)
| None,
@@ -188,7 +188,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
match (self.tcx.named_region(lifetime.hir_id), self.bound_region) {
// the lifetime of the TyPath!
- (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => {
+ (Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
if id == def_id {
self.found_it = true;
@@ -209,7 +209,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
(
Some(
rl::Region::Static
- | rl::Region::EarlyBound(_, _)
+ | rl::Region::EarlyBound(_)
| rl::Region::LateBound(_, _, _)
| rl::Region::Free(_, _),
)
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
index 893ca3cf7..1410e2b63 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
@@ -1,13 +1,14 @@
//! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate
//! to hold.
+use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
+use crate::errors::{ImplNote, MismatchedStaticLifetime, TraitSubdiag};
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::error_reporting::note_and_explain_region;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::ObligationCauseCode;
use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
use rustc_middle::ty::TypeVisitor;
@@ -35,15 +36,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else {
return None;
};
- let ObligationCauseCode::BindingObligation(_def_id, binding_span) = *parent.code() else {
+ let (ObligationCauseCode::BindingObligation(_, binding_span) | ObligationCauseCode::ExprBindingObligation(_, binding_span, ..))
+ = *parent.code() else {
return None;
};
- let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type");
+
// FIXME: we should point at the lifetime
- let mut multi_span: MultiSpan = vec![binding_span].into();
- multi_span.push_span_label(binding_span, "introduces a `'static` lifetime requirement");
- err.span_note(multi_span, "because this has an unmet lifetime requirement");
- note_and_explain_region(self.tcx(), &mut err, "", sup, "...", Some(binding_span));
+ let multi_span: MultiSpan = vec![binding_span].into();
+ let multispan_subdiag = IntroducesStaticBecauseUnmetLifetimeReq {
+ unmet_requirements: multi_span,
+ binding_span,
+ };
+
+ let expl = note_and_explain::RegionExplanation::new(
+ self.tcx(),
+ sup,
+ Some(binding_span),
+ note_and_explain::PrefixKind::Empty,
+ note_and_explain::SuffixKind::Continues,
+ );
+ let mut impl_span = None;
+ let mut trait_subdiags = Vec::new();
if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
// If an impl is local, then maybe this isn't what they want. Try to
// be as helpful as possible with implicit lifetimes.
@@ -72,31 +85,30 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// there aren't trait objects or because none are implicit, then just
// write a single note on the impl itself.
- let impl_span = self.tcx().def_span(*impl_def_id);
- err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+ impl_span = Some(self.tcx().def_span(*impl_def_id));
} else {
// Otherwise, point at all implicit static lifetimes
- err.note("...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
for span in &traits {
- err.span_note(*span, "this has an implicit `'static` lifetime requirement");
+ trait_subdiags.push(TraitSubdiag::Note { span: *span });
// It would be nice to put this immediately under the above note, but they get
// pushed to the end.
- err.span_suggestion_verbose(
- span.shrink_to_hi(),
- "consider relaxing the implicit `'static` requirement",
- " + '_",
- Applicability::MaybeIncorrect,
- );
+ trait_subdiags.push(TraitSubdiag::Sugg { span: span.shrink_to_hi() });
}
}
} else {
// Otherwise just point out the impl.
- let impl_span = self.tcx().def_span(*impl_def_id);
- err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+ impl_span = Some(self.tcx().def_span(*impl_def_id));
}
- let reported = err.emit();
+ let err = MismatchedStaticLifetime {
+ cause_span: cause.span,
+ unmet_lifetime_reqs: multispan_subdiag,
+ expl,
+ impl_note: ImplNote { impl_span },
+ trait_subdiags,
+ };
+ let reported = self.tcx().sess.emit_err(err);
Some(reported)
}
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index 998699158..d4db07512 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -211,7 +211,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
);
let mut err = self.tcx().sess.struct_span_err(span, &msg);
- let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = *cause.code() {
+ let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id)
+ | ObligationCauseCode::ExprItemObligation(def_id, ..) =
+ *cause.code()
+ {
err.span_label(span, "doesn't satisfy where-clause");
err.span_label(
self.tcx().def_span(def_id),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 9886c572a..ae56bea6f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -232,7 +232,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
ObligationCauseCode::MatchImpl(parent, ..) => parent.code(),
_ => cause.code(),
}
- && let (&ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code)
+ && let (&ObligationCauseCode::ItemObligation(item_def_id) | &ObligationCauseCode::ExprItemObligation(item_def_id, ..), None) = (code, override_error_code)
{
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
// lifetime as above, but called using a fully-qualified path to the method:
@@ -300,7 +300,7 @@ pub fn suggest_new_region_bound(
continue;
}
match fn_return.kind {
- TyKind::OpaqueDef(item_id, _) => {
+ TyKind::OpaqueDef(item_id, _, _) => {
let item = tcx.hir().item(item_id);
let ItemKind::OpaqueTy(opaque) = &item.kind else {
return;
@@ -544,7 +544,7 @@ pub struct TraitObjectVisitor(pub FxHashSet<DefId>);
impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
- ty::Dynamic(preds, re) if re.is_static() => {
+ ty::Dynamic(preds, re, _) if re.is_static() => {
if let Some(def_id) = preds.principal_def_id() {
self.0.insert(def_id);
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index da465a764..a6a39d062 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -154,16 +154,11 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
}
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
[segment]
- if segment
- .res
- .map(|res| {
- matches!(
- res,
- Res::SelfTy { trait_: _, alias_to: _ }
- | Res::Def(hir::def::DefKind::TyParam, _)
- )
- })
- .unwrap_or(false) =>
+ if matches!(
+ segment.res,
+ Res::SelfTy { trait_: _, alias_to: _ }
+ | Res::Def(hir::def::DefKind::TyParam, _)
+ ) =>
{
self.types.push(path.span);
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index c1940c5c0..adaa47c01 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -1,100 +1,89 @@
-use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
+use crate::errors::RegionOriginNote;
+use crate::infer::error_reporting::note_and_explain_region;
use crate::infer::{self, InferCtxt, SubregionOrigin};
-use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{
+ fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
+};
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, Region};
+use super::ObligationCauseAsDiagArg;
+
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) {
- let mut label_or_note = |span, msg: &str| {
- let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count();
- let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count();
- let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span);
- if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
- err.span_label(span, msg);
- } else if span_is_primary && expanded_sub_count == 0 {
- err.note(msg);
- } else {
- err.span_note(span, msg);
- }
- };
match *origin {
- infer::Subtype(ref trace) => {
- if let Some((expected, found)) = self.values_str(trace.values) {
- label_or_note(
- trace.cause.span,
- &format!("...so that the {}", trace.cause.as_requirement_str()),
- );
-
- err.note_expected_found(&"", expected, &"", found);
- } else {
- // FIXME: this really should be handled at some earlier stage. Our
- // handling of region checking when type errors are present is
- // *terrible*.
-
- label_or_note(
- trace.cause.span,
- &format!("...so that {}", trace.cause.as_requirement_str()),
- );
- }
- }
- infer::Reborrow(span) => {
- label_or_note(span, "...so that reference does not outlive borrowed content");
+ infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
+ span: trace.cause.span,
+ requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
+ expected_found: self.values_str(trace.values),
}
+ .add_to_diagnostic(err),
+ infer::Reborrow(span) => RegionOriginNote::Plain { span, msg: fluent::infer::reborrow }
+ .add_to_diagnostic(err),
infer::ReborrowUpvar(span, ref upvar_id) => {
let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
- label_or_note(span, &format!("...so that closure can access `{}`", var_name));
+ RegionOriginNote::WithName {
+ span,
+ msg: fluent::infer::reborrow,
+ name: &var_name.to_string(),
+ continues: false,
+ }
+ .add_to_diagnostic(err);
}
infer::RelateObjectBound(span) => {
- label_or_note(span, "...so that it can be closed over into an object");
+ RegionOriginNote::Plain { span, msg: fluent::infer::relate_object_bound }
+ .add_to_diagnostic(err);
}
infer::DataBorrowed(ty, span) => {
- label_or_note(
+ RegionOriginNote::WithName {
span,
- &format!(
- "...so that the type `{}` is not borrowed for too long",
- self.ty_to_string(ty)
- ),
- );
+ msg: fluent::infer::data_borrowed,
+ name: &self.ty_to_string(ty),
+ continues: false,
+ }
+ .add_to_diagnostic(err);
}
infer::ReferenceOutlivesReferent(ty, span) => {
- label_or_note(
+ RegionOriginNote::WithName {
span,
- &format!(
- "...so that the reference type `{}` does not outlive the data it points at",
- self.ty_to_string(ty)
- ),
- );
+ msg: fluent::infer::reference_outlives_referent,
+ name: &self.ty_to_string(ty),
+ continues: false,
+ }
+ .add_to_diagnostic(err);
}
- infer::RelateParamBound(span, t, opt_span) => {
- label_or_note(
+ infer::RelateParamBound(span, ty, opt_span) => {
+ RegionOriginNote::WithName {
span,
- &format!(
- "...so that the type `{}` will meet its required lifetime bounds{}",
- self.ty_to_string(t),
- if opt_span.is_some() { "..." } else { "" },
- ),
- );
+ msg: fluent::infer::relate_param_bound,
+ name: &self.ty_to_string(ty),
+ continues: opt_span.is_some(),
+ }
+ .add_to_diagnostic(err);
if let Some(span) = opt_span {
- err.span_note(span, "...that is required by this bound");
+ RegionOriginNote::Plain { span, msg: fluent::infer::relate_param_bound_2 }
+ .add_to_diagnostic(err);
}
}
infer::RelateRegionParamBound(span) => {
- label_or_note(
- span,
- "...so that the declared lifetime parameter bounds are satisfied",
- );
+ RegionOriginNote::Plain { span, msg: fluent::infer::relate_region_param_bound }
+ .add_to_diagnostic(err);
}
infer::CompareImplItemObligation { span, .. } => {
- label_or_note(
- span,
- "...so that the definition in impl matches the definition from the trait",
- );
+ RegionOriginNote::Plain { span, msg: fluent::infer::compare_impl_item_obligation }
+ .add_to_diagnostic(err);
}
infer::CheckAssociatedTypeBounds { ref parent, .. } => {
self.note_region_origin(err, &parent);
}
+ infer::AscribeUserTypeProvePredicate(span) => {
+ RegionOriginNote::Plain {
+ span,
+ msg: fluent::infer::ascribe_user_type_prove_predicate,
+ }
+ .add_to_diagnostic(err);
+ }
}
}
@@ -107,7 +96,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
match origin {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
- let mut err = self.report_and_explain_type_error(trace, &terr);
+ let mut err = self.report_and_explain_type_error(trace, terr);
match (*sub, *sup) {
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
(ty::RePlaceholder(_), _) => {
@@ -374,6 +363,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err
}
+ infer::AscribeUserTypeProvePredicate(span) => {
+ let mut err =
+ struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied");
+ note_and_explain_region(
+ self.tcx,
+ &mut err,
+ "lifetime instantiated with ",
+ sup,
+ "",
+ None,
+ );
+ note_and_explain_region(
+ self.tcx,
+ &mut err,
+ "but lifetime must outlive ",
+ sub,
+ "",
+ None,
+ );
+ err
+ }
}
}
@@ -390,10 +400,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if matches!(
&trace.cause.code().peel_derives(),
ObligationCauseCode::BindingObligation(..)
+ | ObligationCauseCode::ExprBindingObligation(..)
) =>
{
// Hack to get around the borrow checker because trace.cause has an `Rc`.
- if let ObligationCauseCode::BindingObligation(_, span) =
+ if let ObligationCauseCode::BindingObligation(_, span)
+ | ObligationCauseCode::ExprBindingObligation(_, span, ..) =
&trace.cause.code().peel_derives()
{
let span = *span;
@@ -406,7 +418,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
infer::Subtype(box trace) => {
let terr = TypeError::RegionsPlaceholderMismatch;
- return self.report_and_explain_type_error(trace, &terr);
+ return self.report_and_explain_type_error(trace, terr);
}
_ => return self.report_concrete_failure(placeholder_origin, sub, sup),
}
diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs
index d566634a4..728d691a2 100644
--- a/compiler/rustc_infer/src/infer/free_regions.rs
+++ b/compiler/rustc_infer/src/infer/free_regions.rs
@@ -27,13 +27,13 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
}
}
-#[derive(Clone, Debug, Default)]
+#[derive(Clone, Debug)]
pub struct FreeRegionMap<'tcx> {
// Stores the relation `a < b`, where `a` and `b` are regions.
//
// Invariant: only free regions like `'x` or `'static` are stored
// in this relation, not scopes.
- relation: TransitiveRelation<Region<'tcx>>,
+ pub(crate) relation: TransitiveRelation<Region<'tcx>>,
}
impl<'tcx> FreeRegionMap<'tcx> {
@@ -45,15 +45,6 @@ impl<'tcx> FreeRegionMap<'tcx> {
self.relation.is_empty()
}
- // Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
- // (with the exception that `'static: 'x` is not notable)
- pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
- debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
- if sub.is_free_or_static() && sup.is_free() {
- self.relation.add(sub, sup)
- }
- }
-
/// Tests whether `r_a <= r_b`.
///
/// Both regions must meet `is_free_or_static`.
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 84004d2b2..fee15afc7 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -126,7 +126,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::ReFree(_)
| ty::ReVar(_)
| ty::RePlaceholder(..)
- | ty::ReEmpty(_)
| ty::ReErased => {
// replace all free regions with 'erased
self.tcx().lifetimes.re_erased
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
index d0d9efe15..0ce271c0e 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
@@ -69,7 +69,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// For more details visit the relevant sections of the [rustc dev guide].
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
- #[instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
pub fn replace_bound_vars_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T
where
T: TypeFoldable<'tcx> + Copy,
@@ -81,19 +81,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let next_universe = self.create_next_universe();
let delegate = FnMutDelegate {
- regions: |br: ty::BoundRegion| {
+ regions: &mut |br: ty::BoundRegion| {
self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
universe: next_universe,
name: br.kind,
}))
},
- types: |bound_ty: ty::BoundTy| {
+ types: &mut |bound_ty: ty::BoundTy| {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: next_universe,
name: bound_ty.var,
}))
},
- consts: |bound_var: ty::BoundVar, ty| {
+ consts: &mut |bound_var: ty::BoundVar, ty| {
self.tcx.mk_const(ty::ConstS {
kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
universe: next_universe,
@@ -104,9 +104,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
},
};
- let result = self.tcx.replace_bound_vars_uncached(binder, delegate);
- debug!(?next_universe, ?result);
- result
+ debug!(?next_universe);
+ self.tcx.replace_bound_vars_uncached(binder, delegate)
}
/// See [RegionConstraintCollector::leak_check][1].
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 3783cfb4c..5f13b2b3d 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -15,8 +15,9 @@ use rustc_data_structures::graph::implementation::{
use rustc_data_structures::intern::Interned;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::PlaceholderRegion;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
+use rustc_middle::ty::{ReEarlyBound, ReErased, ReFree, ReStatic};
use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar};
use rustc_middle::ty::{Region, RegionVid};
use rustc_span::Span;
@@ -51,6 +52,13 @@ pub struct LexicalRegionResolutions<'tcx> {
#[derive(Copy, Clone, Debug)]
pub(crate) enum VarValue<'tcx> {
+ /// Empty lifetime is for data that is never accessed. We tag the
+ /// empty lifetime with a universe -- the idea is that we don't
+ /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
+ /// Therefore, the `'empty` in a universe `U` is less than all
+ /// regions visible from `U`, but not less than regions not visible
+ /// from `U`.
+ Empty(ty::UniverseIndex),
Value(Region<'tcx>),
ErrorValue,
}
@@ -117,7 +125,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
&mut self,
errors: &mut Vec<RegionResolutionError<'tcx>>,
) -> LexicalRegionResolutions<'tcx> {
- let mut var_data = self.construct_var_data(self.tcx());
+ let mut var_data = self.construct_var_data();
if cfg!(debug_assertions) {
self.dump_constraints();
@@ -137,13 +145,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
/// Initially, the value for all variables is set to `'empty`, the
/// empty region. The `expansion` phase will grow this larger.
- fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
+ fn construct_var_data(&self) -> LexicalRegionResolutions<'tcx> {
LexicalRegionResolutions {
values: IndexVec::from_fn_n(
|vid| {
let vid_universe = self.var_infos[vid].universe;
- let re_empty = tcx.mk_region(ty::ReEmpty(vid_universe));
- VarValue::Value(re_empty)
+ VarValue::Empty(vid_universe)
},
self.num_vars(),
),
@@ -189,20 +196,131 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
}
+ /// Gets the LUb of a given region and the empty region
+ fn lub_empty(&self, a_region: Region<'tcx>) -> Result<Region<'tcx>, PlaceholderRegion> {
+ match *a_region {
+ ReLateBound(..) | ReErased => {
+ bug!("cannot relate region: {:?}", a_region);
+ }
+
+ ReVar(v_id) => {
+ span_bug!(
+ self.var_infos[v_id].origin.span(),
+ "lub invoked with non-concrete regions: {:?}",
+ a_region,
+ );
+ }
+
+ ReStatic => {
+ // nothing lives longer than `'static`
+ Ok(self.tcx().lifetimes.re_static)
+ }
+
+ ReEarlyBound(_) | ReFree(_) => {
+ // All empty regions are less than early-bound, free,
+ // and scope regions.
+ Ok(a_region)
+ }
+
+ RePlaceholder(placeholder) => Err(placeholder),
+ }
+ }
+
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
+ // In the first pass, we expand region vids according to constraints we
+ // have previously found. In the second pass, we loop through the region
+ // vids we expanded and expand *across* region vids (effectively
+ // "expanding" new `RegSubVar` constraints).
+
+ // Tracks the `VarSubVar` constraints generated for each region vid. We
+ // later use this to expand across vids.
let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
+ // Tracks the changed region vids.
let mut changes = Vec::new();
for constraint in self.data.constraints.keys() {
- let (a_vid, a_region, b_vid, b_data) = match *constraint {
+ match *constraint {
Constraint::RegSubVar(a_region, b_vid) => {
let b_data = var_values.value_mut(b_vid);
- (None, a_region, b_vid, b_data)
+
+ if self.expand_node(a_region, b_vid, b_data) {
+ changes.push(b_vid);
+ }
}
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
VarValue::ErrorValue => continue,
+ VarValue::Empty(a_universe) => {
+ let b_data = var_values.value_mut(b_vid);
+
+ let changed = (|| match *b_data {
+ VarValue::Empty(b_universe) => {
+ // Empty regions are ordered according to the universe
+ // they are associated with.
+ let ui = a_universe.min(b_universe);
+
+ debug!(
+ "Expanding value of {:?} \
+ from empty lifetime with universe {:?} \
+ to empty lifetime with universe {:?}",
+ b_vid, b_universe, ui
+ );
+
+ *b_data = VarValue::Empty(ui);
+ true
+ }
+ VarValue::Value(cur_region) => {
+ let lub = match self.lub_empty(cur_region) {
+ Ok(r) => r,
+ // If the empty and placeholder regions are in the same universe,
+ // then the LUB is the Placeholder region (which is the cur_region).
+ // If they are not in the same universe, the LUB is the Static lifetime.
+ Err(placeholder) if a_universe == placeholder.universe => {
+ cur_region
+ }
+ Err(_) => self.tcx().lifetimes.re_static,
+ };
+
+ if lub == cur_region {
+ return false;
+ }
+
+ debug!(
+ "Expanding value of {:?} from {:?} to {:?}",
+ b_vid, cur_region, lub
+ );
+
+ *b_data = VarValue::Value(lub);
+ true
+ }
+
+ VarValue::ErrorValue => false,
+ })();
+
+ if changed {
+ changes.push(b_vid);
+ }
+ match b_data {
+ VarValue::Value(Region(Interned(ReStatic, _)))
+ | VarValue::ErrorValue => (),
+ _ => {
+ constraints[a_vid].push((a_vid, b_vid));
+ constraints[b_vid].push((a_vid, b_vid));
+ }
+ }
+ }
VarValue::Value(a_region) => {
let b_data = var_values.value_mut(b_vid);
- (Some(a_vid), a_region, b_vid, b_data)
+
+ if self.expand_node(a_region, b_vid, b_data) {
+ changes.push(b_vid);
+ }
+ match b_data {
+ VarValue::Value(Region(Interned(ReStatic, _)))
+ | VarValue::ErrorValue => (),
+ _ => {
+ constraints[a_vid].push((a_vid, b_vid));
+ constraints[b_vid].push((a_vid, b_vid));
+ }
+ }
}
},
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
@@ -210,18 +328,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// is done, in `collect_errors`.
continue;
}
- };
- if self.expand_node(a_region, b_vid, b_data) {
- changes.push(b_vid);
- }
- if let Some(a_vid) = a_vid {
- match b_data {
- VarValue::Value(Region(Interned(ReStatic, _))) | VarValue::ErrorValue => (),
- _ => {
- constraints[a_vid].push((a_vid, b_vid));
- constraints[b_vid].push((a_vid, b_vid));
- }
- }
}
}
@@ -242,6 +348,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
}
+ /// Expands the value of the region represented with `b_vid` with current
+ /// value `b_data` to the lub of `b_data` and `a_region`. The corresponds
+ /// with the constraint `'?b: 'a` (`'a <: '?b`), where `'a` is some known
+ /// region and `'?b` is some region variable.
fn expand_node(
&self,
a_region: Region<'tcx>,
@@ -263,14 +373,28 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
match *b_data {
+ VarValue::Empty(empty_ui) => {
+ let lub = match self.lub_empty(a_region) {
+ Ok(r) => r,
+ // If this empty region is from a universe that can
+ // name the placeholder, then the placeholder is
+ // larger; otherwise, the only ancestor is `'static`.
+ Err(placeholder) if empty_ui.can_name(placeholder.universe) => {
+ self.tcx().mk_region(RePlaceholder(placeholder))
+ }
+ Err(_) => self.tcx().lifetimes.re_static,
+ };
+
+ debug!("Expanding value of {:?} from empty lifetime to {:?}", b_vid, lub);
+
+ *b_data = VarValue::Value(lub);
+ true
+ }
VarValue::Value(cur_region) => {
// This is a specialized version of the `lub_concrete_regions`
// check below for a common case, here purely as an
// optimization.
let b_universe = self.var_infos[b_vid].universe;
- if let ReEmpty(a_universe) = *a_region && a_universe == b_universe {
- return false;
- }
let mut lub = self.lub_concrete_regions(a_region, cur_region);
if lub == cur_region {
@@ -300,6 +424,78 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
}
+ /// True if `a <= b`.
+ fn sub_region_values(&self, a: VarValue<'tcx>, b: VarValue<'tcx>) -> bool {
+ match (a, b) {
+ // Error region is `'static`
+ (VarValue::ErrorValue, _) | (_, VarValue::ErrorValue) => return true,
+ (VarValue::Empty(a_ui), VarValue::Empty(b_ui)) => {
+ // Empty regions are ordered according to the universe
+ // they are associated with.
+ a_ui.min(b_ui) == b_ui
+ }
+ (VarValue::Value(a), VarValue::Empty(_)) => {
+ match *a {
+ ReLateBound(..) | ReErased => {
+ bug!("cannot relate region: {:?}", a);
+ }
+
+ ReVar(v_id) => {
+ span_bug!(
+ self.var_infos[v_id].origin.span(),
+ "lub_concrete_regions invoked with non-concrete region: {:?}",
+ a
+ );
+ }
+
+ ReStatic | ReEarlyBound(_) | ReFree(_) => {
+ // nothing lives longer than `'static`
+
+ // All empty regions are less than early-bound, free,
+ // and scope regions.
+
+ false
+ }
+
+ RePlaceholder(_) => {
+ // The LUB is either `a` or `'static`
+ false
+ }
+ }
+ }
+ (VarValue::Empty(a_ui), VarValue::Value(b)) => {
+ match *b {
+ ReLateBound(..) | ReErased => {
+ bug!("cannot relate region: {:?}", b);
+ }
+
+ ReVar(v_id) => {
+ span_bug!(
+ self.var_infos[v_id].origin.span(),
+ "lub_concrete_regions invoked with non-concrete regions: {:?}",
+ b
+ );
+ }
+
+ ReStatic | ReEarlyBound(_) | ReFree(_) => {
+ // nothing lives longer than `'static`
+ // All empty regions are less than early-bound, free,
+ // and scope regions.
+ true
+ }
+
+ RePlaceholder(placeholder) => {
+ // If this empty region is from a universe that can
+ // name the placeholder, then the placeholder is
+ // larger; otherwise, the only ancestor is `'static`.
+ if a_ui.can_name(placeholder.universe) { true } else { false }
+ }
+ }
+ }
+ (VarValue::Value(a), VarValue::Value(b)) => self.sub_concrete_regions(a, b),
+ }
+ }
+
/// True if `a <= b`, but not defined over inference variables.
#[instrument(level = "trace", skip(self))]
fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
@@ -333,9 +529,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
///
/// Neither `a` nor `b` may be an inference variable (hence the
/// term "concrete regions").
- #[instrument(level = "trace", skip(self))]
+ #[instrument(level = "trace", skip(self), ret)]
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
- let r = match (*a, *b) {
+ match (*a, *b) {
(ReLateBound(..), _) | (_, ReLateBound(..)) | (ReErased, _) | (_, ReErased) => {
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
}
@@ -355,37 +551,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
self.tcx().lifetimes.re_static
}
- (ReEmpty(_), ReEarlyBound(_) | ReFree(_)) => {
- // All empty regions are less than early-bound, free,
- // and scope regions.
- b
- }
-
- (ReEarlyBound(_) | ReFree(_), ReEmpty(_)) => {
- // All empty regions are less than early-bound, free,
- // and scope regions.
- a
- }
-
- (ReEmpty(a_ui), ReEmpty(b_ui)) => {
- // Empty regions are ordered according to the universe
- // they are associated with.
- let ui = a_ui.min(b_ui);
- self.tcx().mk_region(ReEmpty(ui))
- }
-
- (ReEmpty(empty_ui), RePlaceholder(placeholder))
- | (RePlaceholder(placeholder), ReEmpty(empty_ui)) => {
- // If this empty region is from a universe that can
- // name the placeholder, then the placeholder is
- // larger; otherwise, the only ancestor is `'static`.
- if empty_ui.can_name(placeholder.universe) {
- self.tcx().mk_region(RePlaceholder(placeholder))
- } else {
- self.tcx().lifetimes.re_static
- }
- }
-
(ReEarlyBound(_) | ReFree(_), ReEarlyBound(_) | ReFree(_)) => {
self.region_rels.lub_free_regions(a, b)
}
@@ -399,11 +564,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
self.tcx().lifetimes.re_static
}
}
- };
-
- debug!("lub_concrete_regions({:?}, {:?}) = {:?}", a, b, r);
-
- r
+ }
}
/// After expansion is complete, go and check upper bounds (i.e.,
@@ -512,7 +673,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
for (node_vid, value) in var_data.values.iter_enumerated() {
match *value {
- VarValue::Value(_) => { /* Inference successful */ }
+ VarValue::Empty(_) | VarValue::Value(_) => { /* Inference successful */ }
VarValue::ErrorValue => {
// Inference impossible: this value contains
// inconsistent constraints.
@@ -833,12 +994,25 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
VerifyBound::OutlivedBy(r) => {
- self.sub_concrete_regions(min, var_values.normalize(self.tcx(), *r))
+ let a = match *min {
+ ty::ReVar(rid) => var_values.values[rid],
+ _ => VarValue::Value(min),
+ };
+ let b = match **r {
+ ty::ReVar(rid) => var_values.values[rid],
+ _ => VarValue::Value(*r),
+ };
+ self.sub_region_values(a, b)
}
- VerifyBound::IsEmpty => {
- matches!(*min, ty::ReEmpty(_))
- }
+ VerifyBound::IsEmpty => match *min {
+ ty::ReVar(rid) => match var_values.values[rid] {
+ VarValue::ErrorValue => false,
+ VarValue::Empty(_) => true,
+ VarValue::Value(_) => false,
+ },
+ _ => false,
+ },
VerifyBound::AnyBound(bs) => {
bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min))
@@ -880,6 +1054,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
) -> ty::Region<'tcx> {
let result = match *r {
ty::ReVar(rid) => match self.values[rid] {
+ VarValue::Empty(_) => r,
VarValue::Value(r) => r,
VarValue::ErrorValue => tcx.lifetimes.re_static,
},
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index d7d1b5fa2..3abed1221 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -20,6 +20,7 @@ use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
+use rustc_middle::mir::ConstraintCategory;
use rustc_middle::traits::select;
use rustc_middle::ty::abstract_const::{AbstractConst, FailureKind};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -32,7 +33,7 @@ pub use rustc_middle::ty::IntVarValue;
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
use rustc_span::symbol::Symbol;
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
use std::cell::{Cell, Ref, RefCell};
use std::fmt;
@@ -316,12 +317,12 @@ pub struct InferCtxt<'a, 'tcx> {
///
/// Don't read this flag directly, call `is_tainted_by_errors()`
/// and `set_tainted_by_errors()`.
- tainted_by_errors_flag: Cell<bool>,
+ tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
/// Track how many errors were reported when this infcx is created.
/// If the number of errors increases, that's also a sign (line
/// `tainted_by_errors`) to avoid reporting certain kinds of errors.
- // FIXME(matthewjasper) Merge into `tainted_by_errors_flag`
+ // FIXME(matthewjasper) Merge into `tainted_by_errors`
err_count_on_creation: usize,
/// This flag is true while there is an active snapshot.
@@ -337,6 +338,9 @@ pub struct InferCtxt<'a, 'tcx> {
/// when we enter into a higher-ranked (`for<..>`) type or trait
/// bound.
universe: Cell<ty::UniverseIndex>,
+
+ normalize_fn_sig_for_diagnostic:
+ Option<Lrc<dyn Fn(&InferCtxt<'_, 'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
}
/// See the `error_reporting` module for more details.
@@ -350,12 +354,11 @@ pub enum ValuePairs<'tcx> {
impl<'tcx> ValuePairs<'tcx> {
pub fn ty(&self) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
- if let ValuePairs::Terms(ExpectedFound {
- expected: ty::Term::Ty(expected),
- found: ty::Term::Ty(found),
- }) = self
+ if let ValuePairs::Terms(ExpectedFound { expected, found }) = self
+ && let Some(expected) = expected.ty()
+ && let Some(found) = found.ty()
{
- Some((*expected, *found))
+ Some((expected, found))
} else {
None
}
@@ -406,7 +409,11 @@ pub enum SubregionOrigin<'tcx> {
/// Comparing the signature and requirements of an impl method against
/// the containing trait.
- CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
+ CompareImplItemObligation {
+ span: Span,
+ impl_item_def_id: LocalDefId,
+ trait_item_def_id: DefId,
+ },
/// Checking that the bounds of a trait's associated type hold for a given impl
CheckAssociatedTypeBounds {
@@ -414,12 +421,24 @@ pub enum SubregionOrigin<'tcx> {
impl_item_def_id: LocalDefId,
trait_item_def_id: DefId,
},
+
+ AscribeUserTypeProvePredicate(Span),
}
// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(SubregionOrigin<'_>, 32);
+impl<'tcx> SubregionOrigin<'tcx> {
+ pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
+ match self {
+ Self::Subtype(type_trace) => type_trace.cause.to_constraint_category(),
+ Self::AscribeUserTypeProvePredicate(span) => ConstraintCategory::Predicate(*span),
+ _ => ConstraintCategory::BoringNoLocation,
+ }
+ }
+}
+
/// Times when we replace late-bound regions with variables:
#[derive(Clone, Copy, Debug)]
pub enum LateBoundRegionConversionTime {
@@ -504,7 +523,7 @@ pub enum FixupError<'tcx> {
}
/// See the `region_obligations` field for more information.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct RegionObligation<'tcx> {
pub sub_region: ty::Region<'tcx>,
pub sup_type: Ty<'tcx>,
@@ -540,6 +559,8 @@ pub struct InferCtxtBuilder<'tcx> {
defining_use_anchor: DefiningAnchor,
considering_regions: bool,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
+ normalize_fn_sig_for_diagnostic:
+ Option<Lrc<dyn Fn(&InferCtxt<'_, 'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
}
pub trait TyCtxtInferExt<'tcx> {
@@ -553,6 +574,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
defining_use_anchor: DefiningAnchor::Error,
considering_regions: true,
fresh_typeck_results: None,
+ normalize_fn_sig_for_diagnostic: None,
}
}
}
@@ -582,6 +604,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
self
}
+ pub fn with_normalize_fn_sig_for_diagnostic(
+ mut self,
+ fun: Lrc<dyn Fn(&InferCtxt<'_, 'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
+ ) -> Self {
+ self.normalize_fn_sig_for_diagnostic = Some(fun);
+ self
+ }
+
/// Given a canonical value `C` as a starting point, create an
/// inference context that contains each of the bound values
/// within instantiated as a fresh variable. The `f` closure is
@@ -611,6 +641,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
defining_use_anchor,
considering_regions,
ref fresh_typeck_results,
+ ref normalize_fn_sig_for_diagnostic,
} = *self;
let in_progress_typeck_results = fresh_typeck_results.as_ref();
f(InferCtxt {
@@ -624,11 +655,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
evaluation_cache: Default::default(),
reported_trait_errors: Default::default(),
reported_closure_mismatch: Default::default(),
- tainted_by_errors_flag: Cell::new(false),
+ tainted_by_errors: Cell::new(None),
err_count_on_creation: tcx.sess.err_count(),
in_snapshot: Cell::new(false),
skip_leak_check: Cell::new(false),
universe: Cell::new(ty::UniverseIndex::ROOT),
+ normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
+ .as_ref()
+ .map(|f| f.clone()),
})
}
}
@@ -988,7 +1022,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
predicate: ty::PolyCoercePredicate<'tcx>,
- ) -> Option<InferResult<'tcx, ()>> {
+ ) -> Result<InferResult<'tcx, ()>, (TyVid, TyVid)> {
let subtype_predicate = predicate.map_bound(|p| ty::SubtypePredicate {
a_is_expected: false, // when coercing from `a` to `b`, `b` is expected
a: p.a,
@@ -1002,7 +1036,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
predicate: ty::PolySubtypePredicate<'tcx>,
- ) -> Option<InferResult<'tcx, ()>> {
+ ) -> Result<InferResult<'tcx, ()>, (TyVid, TyVid)> {
// Check for two unresolved inference variables, in which case we can
// make no progress. This is partly a micro-optimization, but it's
// also an opportunity to "sub-unify" the variables. This isn't
@@ -1021,12 +1055,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
match (r_a.kind(), r_b.kind()) {
(&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
self.inner.borrow_mut().type_variables().sub(a_vid, b_vid);
- return None;
+ return Err((a_vid, b_vid));
}
_ => {}
}
- Some(self.commit_if_ok(|_snapshot| {
+ Ok(self.commit_if_ok(|_snapshot| {
let ty::SubtypePredicate { a_is_expected, a, b } =
self.replace_bound_vars_with_placeholders(predicate);
@@ -1227,23 +1261,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn is_tainted_by_errors(&self) -> bool {
debug!(
"is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
- tainted_by_errors_flag={})",
+ tainted_by_errors={})",
self.tcx.sess.err_count(),
self.err_count_on_creation,
- self.tainted_by_errors_flag.get()
+ self.tainted_by_errors.get().is_some()
);
if self.tcx.sess.err_count() > self.err_count_on_creation {
return true; // errors reported since this infcx was made
}
- self.tainted_by_errors_flag.get()
+ self.tainted_by_errors.get().is_some()
}
/// Set the "tainted by errors" flag to true. We call this when we
/// observe an error from a prior pass.
pub fn set_tainted_by_errors(&self) {
debug!("set_tainted_by_errors()");
- self.tainted_by_errors_flag.set(true)
+ self.tainted_by_errors.set(Some(
+ self.tcx.sess.delay_span_bug(DUMMY_SP, "`InferCtxt` incorrectly tainted by errors"),
+ ));
}
pub fn skip_region_resolution(&self) {
@@ -1313,7 +1349,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// `resolve_vars_if_possible` as well as `fully_resolve`.
///
/// Make sure to call [`InferCtxt::process_registered_region_obligations`]
- /// first, or preferrably use [`InferCtxt::check_region_obligations_and_report_errors`]
+ /// first, or preferably use [`InferCtxt::check_region_obligations_and_report_errors`]
/// to do both of these operations together.
pub fn resolve_regions_and_report_errors(
&self,
@@ -1527,8 +1563,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
actual: Ty<'tcx>,
err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let trace = TypeTrace::types(cause, true, expected, actual);
- self.report_and_explain_type_error(trace, &err)
+ self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
}
pub fn report_mismatched_consts(
@@ -1538,8 +1573,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
actual: ty::Const<'tcx>,
err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let trace = TypeTrace::consts(cause, true, expected, actual);
- self.report_and_explain_type_error(trace, &err)
+ self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
}
pub fn replace_bound_vars_with_fresh_vars<T>(
@@ -1656,7 +1690,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn try_const_eval_resolve(
&self,
param_env: ty::ParamEnv<'tcx>,
- unevaluated: ty::Unevaluated<'tcx>,
+ unevaluated: ty::Unevaluated<'tcx, ()>,
ty: Ty<'tcx>,
span: Option<Span>,
) -> Result<ty::Const<'tcx>, ErrorHandled> {
@@ -1691,7 +1725,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn const_eval_resolve(
&self,
mut param_env: ty::ParamEnv<'tcx>,
- unevaluated: ty::Unevaluated<'tcx>,
+ unevaluated: ty::Unevaluated<'tcx, ()>,
span: Option<Span>,
) -> EvalToValTreeResult<'tcx> {
let mut substs = self.resolve_vars_if_possible(unevaluated.substs);
@@ -1700,7 +1734,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// Postpone the evaluation of constants whose substs depend on inference
// variables
if substs.has_infer_types_or_consts() {
- let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
+ let ac = AbstractConst::new(self.tcx, unevaluated);
match ac {
Ok(None) => {
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
@@ -1722,11 +1756,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
debug!(?param_env_erased);
debug!(?substs_erased);
- let unevaluated = ty::Unevaluated {
- def: unevaluated.def,
- substs: substs_erased,
- promoted: unevaluated.promoted,
- };
+ let unevaluated =
+ ty::Unevaluated { def: unevaluated.def, substs: substs_erased, promoted: () };
// The return value is the evaluated value which doesn't contain any reference to inference
// variables, thus we don't need to substitute back the original values.
@@ -1814,7 +1845,7 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
/// Tries to extract an inference variable from a type, returns `None`
/// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`).
- pub fn maybe_from_ty(ty: Ty<'tcx>) -> Option<Self> {
+ fn maybe_from_ty(ty: Ty<'tcx>) -> Option<Self> {
match *ty.kind() {
ty::Infer(ty::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)),
ty::Infer(ty::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)),
@@ -1825,7 +1856,7 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
/// Tries to extract an inference variable from a constant, returns `None`
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
- pub fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
+ fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
match ct.kind() {
ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
_ => None,
@@ -1937,6 +1968,18 @@ impl<'tcx> TypeTrace<'tcx> {
}
}
+ pub fn poly_trait_refs(
+ cause: &ObligationCause<'tcx>,
+ a_is_expected: bool,
+ a: ty::PolyTraitRef<'tcx>,
+ b: ty::PolyTraitRef<'tcx>,
+ ) -> TypeTrace<'tcx> {
+ TypeTrace {
+ cause: cause.clone(),
+ values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+ }
+ }
+
pub fn consts(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
@@ -1962,6 +2005,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
DataBorrowed(_, a) => a,
ReferenceOutlivesReferent(_, a) => a,
CompareImplItemObligation { span, .. } => span,
+ AscribeUserTypeProvePredicate(span) => span,
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
}
}
@@ -1994,6 +2038,10 @@ impl<'tcx> SubregionOrigin<'tcx> {
parent: Box::new(default()),
},
+ traits::ObligationCauseCode::AscribeUserTypeProvePredicate(span) => {
+ SubregionOrigin::AscribeUserTypeProvePredicate(span)
+ }
+
_ => default(),
}
}
@@ -2015,16 +2063,6 @@ impl RegionVariableOrigin {
}
}
-impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "RegionObligation(sub_region={:?}, sup_type={:?})",
- self.sub_region, self.sup_type
- )
- }
-}
-
/// Replaces substs that reference param or infer variables with suitable
/// placeholders. This function is meant to remove these param and infer
/// substs when they're not actually needed to evaluate a constant.
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index bab4f3e9e..00fc442d3 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -396,6 +396,32 @@ where
generalizer.relate(value, value)
}
+
+ fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+ let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
+ let mut generalize = |ty, ty_is_expected| {
+ let var = self.infcx.next_ty_var_id_in_universe(
+ TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span: self.delegate.span(),
+ },
+ ty::UniverseIndex::ROOT,
+ );
+ if ty_is_expected {
+ self.relate_ty_var((ty, var))
+ } else {
+ self.relate_ty_var((var, ty))
+ }
+ };
+ let (a, b) = match (a.kind(), b.kind()) {
+ (&ty::Opaque(..), _) => (a, generalize(b, false)?),
+ (_, &ty::Opaque(..)) => (generalize(a, true)?, b),
+ _ => unreachable!(),
+ };
+ self.delegate.register_opaque_type(a, b, true)?;
+ trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
+ Ok(a)
+ }
}
/// When we instantiate an inference variable with a value in
@@ -516,7 +542,7 @@ where
true
}
- #[instrument(skip(self, info), level = "trace")]
+ #[instrument(skip(self, info), level = "trace", ret)]
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
@@ -534,8 +560,6 @@ where
self.ambient_variance = old_ambient_variance;
- debug!(?r);
-
Ok(r)
}
@@ -572,32 +596,16 @@ where
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
- self.infcx.super_combine_tys(self, a, b)
+ infcx.super_combine_tys(self, a, b).or_else(|err| {
+ self.tcx().sess.delay_span_bug(
+ self.delegate.span(),
+ "failure to relate an opaque to itself should result in an error later on",
+ );
+ if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
+ })
}
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => {
- let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
- let mut generalize = |ty, ty_is_expected| {
- let var = infcx.next_ty_var_id_in_universe(
- TypeVariableOrigin {
- kind: TypeVariableOriginKind::MiscVariable,
- span: self.delegate.span(),
- },
- ty::UniverseIndex::ROOT,
- );
- if ty_is_expected {
- self.relate_ty_var((ty, var))
- } else {
- self.relate_ty_var((var, ty))
- }
- };
- let (a, b) = match (a.kind(), b.kind()) {
- (&ty::Opaque(..), _) => (a, generalize(b, false)?),
- (_, &ty::Opaque(..)) => (generalize(a, true)?, b),
- _ => unreachable!(),
- };
- self.delegate.register_opaque_type(a, b, true)?;
- trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
- Ok(a)
+ self.relate_opaques(a, b)
}
(&ty::Projection(projection_ty), _)
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index e579afbf3..8c9ddf866 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -1,3 +1,4 @@
+use crate::errors::OpaqueHiddenTypeDiag;
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
use crate::traits;
use hir::def_id::{DefId, LocalDefId};
@@ -72,7 +73,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// for opaque types, and then use that kind to fix the spans for type errors
// that we see later on.
let ty_var = self.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::TypeInference,
+ kind: TypeVariableOriginKind::OpaqueTypeInference(def_id),
span,
});
obligations.extend(
@@ -153,22 +154,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if let Some(OpaqueTyOrigin::TyAlias) =
did2.as_local().and_then(|did2| self.opaque_type_origin(did2, cause.span))
{
- self.tcx
- .sess
- .struct_span_err(
- cause.span,
- "opaque type's hidden type cannot be another opaque type from the same scope",
- )
- .span_label(cause.span, "one of the two opaque types used here has to be outside its defining scope")
- .span_note(
- self.tcx.def_span(def_id),
- "opaque type whose hidden type is being assigned",
- )
- .span_note(
- self.tcx.def_span(did2),
- "opaque type being used as hidden type",
- )
- .emit();
+ self.tcx.sess.emit_err(OpaqueHiddenTypeDiag {
+ span: cause.span,
+ hidden_type: self.tcx.def_span(did2),
+ opaque_type: self.tcx.def_span(def_id),
+ });
}
}
Some(self.register_hidden_type(
@@ -400,7 +390,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
});
}
- #[instrument(skip(self), level = "trace")]
+ #[instrument(skip(self), level = "trace", ret)]
pub fn opaque_type_origin(&self, def_id: LocalDefId, span: Span) -> Option<OpaqueTyOrigin> {
let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let parent_def_id = match self.defining_use_anchor {
@@ -431,16 +421,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
in_definition_scope.then_some(*origin)
}
- #[instrument(skip(self), level = "trace")]
+ #[instrument(skip(self), level = "trace", ret)]
fn opaque_ty_origin_unchecked(&self, def_id: LocalDefId, span: Span) -> OpaqueTyOrigin {
- let origin = match self.tcx.hir().expect_item(def_id).kind {
+ match self.tcx.hir().expect_item(def_id).kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin,
ref itemkind => {
span_bug!(span, "weird opaque type: {:?}, {:#?}", def_id, itemkind)
}
- };
- trace!(?origin);
- origin
+ }
}
}
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index fb12da0cc..4d124554a 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -29,7 +29,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
}
}
- #[instrument(level = "debug")]
+ #[instrument(level = "debug", ret)]
pub fn take_opaque_types(&mut self) -> OpaqueTypeMap<'tcx> {
std::mem::take(&mut self.opaque_types)
}
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index b2decd64f..9922b156e 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -2,6 +2,7 @@ use crate::infer::free_regions::FreeRegionMap;
use crate::infer::{GenericKind, InferCtxt};
use crate::traits::query::OutlivesBound;
use rustc_data_structures::fx::FxIndexSet;
+use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
use super::explicit_outlives_bounds;
@@ -51,23 +52,49 @@ pub struct OutlivesEnvironment<'tcx> {
region_bound_pairs: RegionBoundPairs<'tcx>,
}
+/// Builder of OutlivesEnvironment.
+#[derive(Debug)]
+struct OutlivesEnvironmentBuilder<'tcx> {
+ param_env: ty::ParamEnv<'tcx>,
+ region_relation: TransitiveRelationBuilder<Region<'tcx>>,
+ region_bound_pairs: RegionBoundPairs<'tcx>,
+}
+
/// "Region-bound pairs" tracks outlives relations that are known to
/// be true, either because of explicit where-clauses like `T: 'a` or
/// because of implied bounds.
pub type RegionBoundPairs<'tcx> =
FxIndexSet<ty::OutlivesPredicate<GenericKind<'tcx>, Region<'tcx>>>;
-impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
- pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
- let mut env = OutlivesEnvironment {
+impl<'tcx> OutlivesEnvironment<'tcx> {
+ /// Create a builder using `ParamEnv` and add explicit outlives bounds into it.
+ fn builder(param_env: ty::ParamEnv<'tcx>) -> OutlivesEnvironmentBuilder<'tcx> {
+ let mut builder = OutlivesEnvironmentBuilder {
param_env,
- free_region_map: Default::default(),
+ region_relation: Default::default(),
region_bound_pairs: Default::default(),
};
- env.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
+ builder.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
- env
+ builder
+ }
+
+ #[inline]
+ /// Create a new `OutlivesEnvironment` without extra outlives bounds.
+ pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
+ Self::builder(param_env).build()
+ }
+
+ /// Create a new `OutlivesEnvironment` with extra outlives bounds.
+ pub fn with_bounds<'a>(
+ param_env: ty::ParamEnv<'tcx>,
+ infcx: Option<&InferCtxt<'a, 'tcx>>,
+ extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
+ ) -> Self {
+ let mut builder = Self::builder(param_env);
+ builder.add_outlives_bounds(infcx, extra_bounds);
+ builder.build()
}
/// Borrows current value of the `free_region_map`.
@@ -79,6 +106,18 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
&self.region_bound_pairs
}
+}
+
+impl<'a, 'tcx> OutlivesEnvironmentBuilder<'tcx> {
+ #[inline]
+ #[instrument(level = "debug")]
+ fn build(self) -> OutlivesEnvironment<'tcx> {
+ OutlivesEnvironment {
+ param_env: self.param_env,
+ free_region_map: FreeRegionMap { relation: self.region_relation.freeze() },
+ region_bound_pairs: self.region_bound_pairs,
+ }
+ }
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
///
@@ -86,11 +125,8 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
/// contain inference variables, it must be supplied, in which
/// case we will register "givens" on the inference context. (See
/// `RegionConstraintData`.)
- pub fn add_outlives_bounds<I>(
- &mut self,
- infcx: Option<&InferCtxt<'a, 'tcx>>,
- outlives_bounds: I,
- ) where
+ fn add_outlives_bounds<I>(&mut self, infcx: Option<&InferCtxt<'a, 'tcx>>, outlives_bounds: I)
+ where
I: IntoIterator<Item = OutlivesBound<'tcx>>,
{
// Record relationships such as `T:'x` that don't go into the
@@ -122,7 +158,9 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
// system to be more general and to make use
// of *every* relationship that arises here,
// but presently we do not.)
- self.free_region_map.relate_regions(r_a, r_b);
+ if r_a.is_free_or_static() && r_b.is_free() {
+ self.region_relation.add(r_a, r_b)
+ }
}
}
}
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 2a085288f..2d19d1823 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -9,7 +9,7 @@ pub mod verify;
use rustc_middle::traits::query::OutlivesBound;
use rustc_middle::ty;
-#[instrument(level = "debug", skip(param_env))]
+#[instrument(level = "debug", skip(param_env), ret)]
pub fn explicit_outlives_bounds<'tcx>(
param_env: ty::ParamEnv<'tcx>,
) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index ad052f58c..5bd1774f6 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -69,6 +69,7 @@ use crate::infer::{
use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::undo_log::UndoLogs;
use rustc_hir::def_id::LocalDefId;
+use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeVisitable};
use smallvec::smallvec;
@@ -92,12 +93,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
sub_region: Region<'tcx>,
cause: &ObligationCause<'tcx>,
) {
+ debug!(?sup_type, ?sub_region, ?cause);
let origin = SubregionOrigin::from_obligation_cause(cause, || {
infer::RelateParamBound(
cause.span,
sup_type,
match cause.code().peel_derives() {
- ObligationCauseCode::BindingObligation(_, span) => Some(*span),
+ ObligationCauseCode::BindingObligation(_, span)
+ | ObligationCauseCode::ExprBindingObligation(_, span, ..) => Some(*span),
_ => None,
},
)
@@ -161,7 +164,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let outlives =
&mut TypeOutlives::new(self, self.tcx, &region_bound_pairs, None, param_env);
- outlives.type_must_outlive(origin, sup_type, sub_region);
+ let category = origin.to_constraint_category();
+ outlives.type_must_outlive(origin, sup_type, sub_region, category);
}
}
@@ -205,6 +209,7 @@ pub trait TypeOutlivesDelegate<'tcx> {
origin: SubregionOrigin<'tcx>,
a: ty::Region<'tcx>,
b: ty::Region<'tcx>,
+ constraint_category: ConstraintCategory<'tcx>,
);
fn push_verify(
@@ -247,19 +252,19 @@ where
/// - `origin`, the reason we need this constraint
/// - `ty`, the type `T`
/// - `region`, the region `'a`
+ #[instrument(level = "debug", skip(self))]
pub fn type_must_outlive(
&mut self,
origin: infer::SubregionOrigin<'tcx>,
ty: Ty<'tcx>,
region: ty::Region<'tcx>,
+ category: ConstraintCategory<'tcx>,
) {
- debug!("type_must_outlive(ty={:?}, region={:?}, origin={:?})", ty, region, origin);
-
assert!(!ty.has_escaping_bound_vars());
let mut components = smallvec![];
push_outlives_components(self.tcx, ty, &mut components);
- self.components_must_outlive(origin, &components, region);
+ self.components_must_outlive(origin, &components, region, category);
}
fn components_must_outlive(
@@ -267,12 +272,13 @@ where
origin: infer::SubregionOrigin<'tcx>,
components: &[Component<'tcx>],
region: ty::Region<'tcx>,
+ category: ConstraintCategory<'tcx>,
) {
for component in components.iter() {
let origin = origin.clone();
match component {
Component::Region(region1) => {
- self.delegate.push_sub_region_constraint(origin, region, *region1);
+ self.delegate.push_sub_region_constraint(origin, region, *region1, category);
}
Component::Param(param_ty) => {
self.param_ty_must_outlive(origin, region, *param_ty);
@@ -281,7 +287,7 @@ where
self.projection_must_outlive(origin, region, *projection_ty);
}
Component::EscapingProjection(subcomponents) => {
- self.components_must_outlive(origin, &subcomponents, region);
+ self.components_must_outlive(origin, &subcomponents, region, category);
}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error
@@ -312,7 +318,7 @@ where
self.delegate.push_verify(origin, generic, region, verify_bound);
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn projection_must_outlive(
&mut self,
origin: infer::SubregionOrigin<'tcx>,
@@ -388,13 +394,19 @@ where
if approx_env_bounds.is_empty() && trait_bounds.is_empty() && needs_infer {
debug!("projection_must_outlive: no declared bounds");
+ let constraint = origin.to_constraint_category();
for k in projection_ty.substs {
match k.unpack() {
GenericArgKind::Lifetime(lt) => {
- self.delegate.push_sub_region_constraint(origin.clone(), region, lt);
+ self.delegate.push_sub_region_constraint(
+ origin.clone(),
+ region,
+ lt,
+ constraint,
+ );
}
GenericArgKind::Type(ty) => {
- self.type_must_outlive(origin.clone(), ty, region);
+ self.type_must_outlive(origin.clone(), ty, region, constraint);
}
GenericArgKind::Const(_) => {
// Const parameters don't impose constraints.
@@ -432,7 +444,8 @@ where
let unique_bound = trait_bounds[0];
debug!("projection_must_outlive: unique trait bound = {:?}", unique_bound);
debug!("projection_must_outlive: unique declared bound appears in trait ref");
- self.delegate.push_sub_region_constraint(origin, region, unique_bound);
+ let category = origin.to_constraint_category();
+ self.delegate.push_sub_region_constraint(origin, region, unique_bound, category);
return;
}
@@ -454,6 +467,7 @@ impl<'cx, 'tcx> TypeOutlivesDelegate<'tcx> for &'cx InferCtxt<'cx, 'tcx> {
origin: SubregionOrigin<'tcx>,
a: ty::Region<'tcx>,
b: ty::Region<'tcx>,
+ _constraint_category: ConstraintCategory<'tcx>,
) {
self.sub_regions(origin, a, b)
}
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index 772e297b7..a5c21f0fb 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -34,7 +34,7 @@ use crate::infer::region_constraints::VerifyIfEq;
/// like are used. This is a particular challenge since this function is invoked
/// very late in inference and hence cannot make use of the normal inference
/// machinery.
-#[tracing::instrument(level = "debug", skip(tcx, param_env))]
+#[instrument(level = "debug", skip(tcx, param_env))]
pub fn extract_verify_if_eq<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@@ -71,7 +71,7 @@ pub fn extract_verify_if_eq<'tcx>(
}
/// True if a (potentially higher-ranked) outlives
-#[tracing::instrument(level = "debug", skip(tcx, param_env))]
+#[instrument(level = "debug", skip(tcx, param_env))]
pub(super) fn can_match_erased_ty<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@@ -110,7 +110,7 @@ impl<'tcx> Match<'tcx> {
/// Binds the pattern variable `br` to `value`; returns an `Err` if the pattern
/// is already bound to a different value.
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn bind(
&mut self,
br: ty::BoundRegion,
@@ -174,7 +174,14 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
#[instrument(skip(self), level = "debug")]
fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
- if pattern == value { Ok(pattern) } else { relate::super_relate_tys(self, pattern, value) }
+ if let ty::Error(_) = pattern.kind() {
+ // Unlike normal `TypeRelation` rules, `ty::Error` does not equal any type.
+ self.no_match()
+ } else if pattern == value {
+ Ok(pattern)
+ } else {
+ relate::super_relate_tys(self, pattern, value)
+ }
}
#[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index c7d7ef40d..752334950 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -50,13 +50,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
- debug!("param_bound(param_ty={:?})", param_ty);
-
// Start with anything like `T: 'a` we can scrape from the
// environment. If the environment contains something like
// `for<'a> T: 'a`, then we know that `T` outlives everything.
let declared_bounds_from_env = self.declared_generic_bounds_from_env(param_ty);
+ debug!(?declared_bounds_from_env);
let mut param_bounds = vec![];
for declared_bound in declared_bounds_from_env {
let bound_region = declared_bound.map_bound(|outlives| outlives.1);
@@ -65,6 +65,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
param_bounds.push(VerifyBound::OutlivedBy(region));
} else {
// This is `for<'a> T: 'a`. This means that `T` outlives everything! All done here.
+ debug!("found that {param_ty:?} outlives any lifetime, returning empty vector");
return VerifyBound::AllBounds(vec![]);
}
}
@@ -72,6 +73,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
// Add in the default bound of fn body that applies to all in
// scope type parameters:
if let Some(r) = self.implicit_region_bound {
+ debug!("adding implicit region bound of {r:?}");
param_bounds.push(VerifyBound::OutlivedBy(r));
}
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 0d4472a1c..e43d28ee5 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -187,7 +187,7 @@ pub enum GenericKind<'tcx> {
/// }
/// ```
/// This is described with an `AnyRegion('a, 'b)` node.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, TypeFoldable, TypeVisitable)]
pub enum VerifyBound<'tcx> {
/// See [`VerifyIfEq`] docs
IfEq(ty::Binder<'tcx, VerifyIfEq<'tcx>>),
@@ -426,21 +426,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
data
}
- pub fn data(&self) -> &RegionConstraintData<'tcx> {
+ pub(super) fn data(&self) -> &RegionConstraintData<'tcx> {
&self.data
}
- pub fn start_snapshot(&mut self) -> RegionSnapshot {
+ pub(super) fn start_snapshot(&mut self) -> RegionSnapshot {
debug!("RegionConstraintCollector: start_snapshot");
RegionSnapshot { any_unifications: self.any_unifications }
}
- pub fn rollback_to(&mut self, snapshot: RegionSnapshot) {
+ pub(super) fn rollback_to(&mut self, snapshot: RegionSnapshot) {
debug!("RegionConstraintCollector: rollback_to({:?})", snapshot);
self.any_unifications = snapshot.any_unifications;
}
- pub fn new_region_var(
+ pub(super) fn new_region_var(
&mut self,
universe: ty::UniverseIndex,
origin: RegionVariableOrigin,
@@ -455,12 +455,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
/// Returns the universe for the given variable.
- pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex {
+ pub(super) fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex {
self.var_infos[vid].universe
}
/// Returns the origin for the given variable.
- pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
+ pub(super) fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
self.var_infos[vid].origin
}
@@ -492,7 +492,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
self.undo_log.push(AddVerify(index));
}
- pub fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) {
+ pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) {
// cannot add givens once regions are resolved
if self.data.givens.insert((sub, sup)) {
debug!("add_given({:?} <= {:?})", sub, sup);
@@ -501,7 +501,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
}
- pub fn make_eqregion(
+ pub(super) fn make_eqregion(
&mut self,
origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
@@ -530,7 +530,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
}
- pub fn member_constraint(
+ pub(super) fn member_constraint(
&mut self,
key: ty::OpaqueTypeKey<'tcx>,
definition_span: Span,
@@ -554,7 +554,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
#[instrument(skip(self, origin), level = "debug")]
- pub fn make_subregion(
+ pub(super) fn make_subregion(
&mut self,
origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
@@ -585,7 +585,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
}
- pub fn verify_generic_bound(
+ pub(super) fn verify_generic_bound(
&mut self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
@@ -595,7 +595,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
self.add_verify(Verify { kind, origin, region: sub, bound });
}
- pub fn lub_regions(
+ pub(super) fn lub_regions(
&mut self,
tcx: TyCtxt<'tcx>,
origin: SubregionOrigin<'tcx>,
@@ -613,7 +613,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
}
- pub fn glb_regions(
+ pub(super) fn glb_regions(
&mut self,
tcx: TyCtxt<'tcx>,
origin: SubregionOrigin<'tcx>,
@@ -634,7 +634,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
/// Resolves the passed RegionVid to the root RegionVid in the unification table
- pub fn opportunistic_resolve_var(&mut self, rid: ty::RegionVid) -> ty::RegionVid {
+ pub(super) fn opportunistic_resolve_var(&mut self, rid: ty::RegionVid) -> ty::RegionVid {
self.unification_table().find(rid).vid
}
@@ -699,7 +699,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => {
ty::UniverseIndex::ROOT
}
- ty::ReEmpty(ui) => ui,
ty::RePlaceholder(placeholder) => placeholder.universe,
ty::ReVar(vid) => self.var_universe(vid),
ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index b27571275..b7eab5d43 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -4,6 +4,7 @@ use super::SubregionOrigin;
use crate::infer::combine::ConstEquateRelation;
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::traits::Obligation;
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::TyVar;
@@ -141,17 +142,27 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
Ok(infcx.tcx.mk_ty_var(var))
};
let (a, b) = if self.a_is_expected { (a, b) } else { (b, a) };
- let (a, b) = match (a.kind(), b.kind()) {
+ let (ga, gb) = match (a.kind(), b.kind()) {
(&ty::Opaque(..), _) => (a, generalize(b, true)?),
(_, &ty::Opaque(..)) => (generalize(a, false)?, b),
_ => unreachable!(),
};
self.fields.obligations.extend(
infcx
- .handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())?
+ .handle_opaque_type(ga, gb, true, &self.fields.trace.cause, self.param_env())
+ // Don't leak any generalized type variables out of this
+ // subtyping relation in the case of a type error.
+ .map_err(|err| {
+ let (ga, gb) = self.fields.infcx.resolve_vars_if_possible((ga, gb));
+ if let TypeError::Sorts(sorts) = err && sorts.expected == ga && sorts.found == gb {
+ TypeError::Sorts(ExpectedFound { expected: a, found: b })
+ } else {
+ err
+ }
+ })?
.obligations,
);
- Ok(a)
+ Ok(ga)
}
_ => {
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index a0e2965b6..7ff086452 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -122,6 +122,7 @@ pub enum TypeVariableOriginKind {
MiscVariable,
NormalizeProjectionType,
TypeInference,
+ OpaqueTypeInference(DefId),
TypeParameterDefinition(Symbol, Option<DefId>),
/// One of the upvars or closure kind parameters in a `ClosureSubsts`
diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs
index 74a26ebc3..611961ab1 100644
--- a/compiler/rustc_infer/src/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/undo_log.rs
@@ -100,7 +100,7 @@ impl Default for InferCtxtUndoLogs<'_> {
}
/// The UndoLogs trait defines how we undo a particular kind of action (of type T). We can undo any
-/// action that is convertable into an UndoLog (per the From impls above).
+/// action that is convertible into an UndoLog (per the From impls above).
impl<'tcx, T> UndoLogs<T> for InferCtxtUndoLogs<'tcx>
where
UndoLog<'tcx>: From<T>,
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 7769a68ba..ef60d2c91 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -17,9 +17,9 @@
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(extend_one)]
-#![feature(label_break_value)]
+#![cfg_attr(bootstrap, feature(label_break_value))]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(try_blocks)]
@@ -35,5 +35,6 @@ extern crate tracing;
#[macro_use]
extern crate rustc_middle;
+mod errors;
pub mod infer;
pub mod traits;
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 1ecbc876c..da4002d09 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -17,6 +17,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_expand = { path = "../rustc_expand" }
+rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
new file mode 100644
index 000000000..6a497aed4
--- /dev/null
+++ b/compiler/rustc_interface/src/errors.rs
@@ -0,0 +1,89 @@
+use rustc_macros::SessionDiagnostic;
+use rustc_span::{Span, Symbol};
+
+use std::io;
+use std::path::Path;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::ferris_identifier)]
+pub struct FerrisIdentifier {
+ #[primary_span]
+ pub spans: Vec<Span>,
+ #[suggestion(code = "ferris", applicability = "maybe-incorrect")]
+ pub first_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::emoji_identifier)]
+pub struct EmojiIdentifier {
+ #[primary_span]
+ pub spans: Vec<Span>,
+ pub ident: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::mixed_bin_crate)]
+pub struct MixedBinCrate;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::mixed_proc_macro_crate)]
+pub struct MixedProcMacroCrate;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::proc_macro_doc_without_arg)]
+pub struct ProcMacroDocWithoutArg;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::error_writing_dependencies)]
+pub struct ErrorWritingDependencies<'a> {
+ pub path: &'a Path,
+ pub error: io::Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::input_file_would_be_overwritten)]
+pub struct InputFileWouldBeOverWritten<'a> {
+ pub path: &'a Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::generated_file_conflicts_with_directory)]
+pub struct GeneratedFileConflictsWithDirectory<'a> {
+ pub input_path: &'a Path,
+ pub dir_path: &'a Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::temps_dir_error)]
+pub struct TempsDirError;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::out_dir_error)]
+pub struct OutDirError;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::cant_emit_mir)]
+pub struct CantEmitMIR {
+ pub error: io::Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::rustc_error_fatal)]
+pub struct RustcErrorFatal {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::rustc_error_unexpected_annotation)]
+pub struct RustcErrorUnexpectedAnnotation {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::failed_writing_file)]
+pub struct FailedWritingFile<'a> {
+ pub path: &'a Path,
+ pub error: io::Error,
+}
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 94f81b660..949bd02ad 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -176,7 +176,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
let ident = arg.ident().expect("multi-segment cfg key");
names_valid.insert(ident.name.to_string());
} else {
- error!("`names()` arguments must be simple identifers");
+ error!("`names()` arguments must be simple identifiers");
}
}
continue 'specs;
@@ -204,7 +204,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
continue 'specs;
} else {
error!(
- "`values()` first argument must be a simple identifer"
+ "`values()` first argument must be a simple identifier"
);
}
} else if args.is_empty() {
@@ -330,9 +330,9 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
}
// JUSTIFICATION: before session exists, only config
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
- tracing::trace!("run_compiler");
+ trace!("run_compiler");
util::run_in_thread_pool_with_globals(
config.opts.edition,
config.opts.unstable_opts.threads,
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index d443057eb..41cd7b0e9 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,12 +1,18 @@
#![feature(box_patterns)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
+#[macro_use]
+extern crate tracing;
mod callbacks;
+mod errors;
pub mod interface;
mod passes;
mod proc_macro_decls;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 8f0835917..c41b154c3 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1,3 +1,8 @@
+use crate::errors::{
+ CantEmitMIR, EmojiIdentifier, ErrorWritingDependencies, FerrisIdentifier,
+ GeneratedFileConflictsWithDirectory, InputFileWouldBeOverWritten, MixedBinCrate,
+ MixedProcMacroCrate, OutDirError, ProcMacroDocWithoutArg, TempsDirError,
+};
use crate::interface::{Compiler, Result};
use crate::proc_macro_decls;
use crate::util;
@@ -8,7 +13,7 @@ use rustc_borrowck as mir_borrowck;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
-use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, PResult};
+use rustc_errors::{ErrorGuaranteed, PResult};
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
use rustc_hir::def_id::StableCrateId;
use rustc_hir::definitions::Definitions;
@@ -33,7 +38,6 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_span::FileName;
use rustc_trait_selection::traits;
use rustc_typeck as typeck;
-use tracing::{info, warn};
use std::any::Any;
use std::cell::RefCell;
@@ -64,7 +68,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
}
if sess.opts.unstable_opts.hir_stats {
- hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS");
+ hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1");
}
Ok(krate)
@@ -160,7 +164,7 @@ pub fn create_resolver(
krate: &ast::Crate,
crate_name: &str,
) -> BoxedResolver {
- tracing::trace!("create_resolver");
+ trace!("create_resolver");
BoxedResolver::new(sess, move |sess, resolver_arenas| {
Resolver::new(sess, krate, crate_name, metadata_loader, resolver_arenas)
})
@@ -274,7 +278,7 @@ pub fn configure_and_expand(
crate_name: &str,
resolver: &mut Resolver<'_>,
) -> Result<ast::Crate> {
- tracing::trace!("configure_and_expand");
+ trace!("configure_and_expand");
pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name);
rustc_builtin_macros::register_builtin_macros(resolver);
@@ -374,10 +378,10 @@ pub fn configure_and_expand(
if crate_types.len() > 1 {
if is_executable_crate {
- sess.err("cannot mix `bin` crate type with others");
+ sess.emit_err(MixedBinCrate);
}
if is_proc_macro_crate {
- sess.err("cannot mix `proc-macro` crate type with others");
+ sess.emit_err(MixedProcMacroCrate);
}
}
@@ -388,13 +392,7 @@ pub fn configure_and_expand(
// However, we do emit a warning, to let such users know that they should
// start passing '--crate-type proc-macro'
if has_proc_macro_decls && sess.opts.actually_rustdoc && !is_proc_macro_crate {
- let mut msg = sess.diagnostic().struct_warn(
- "Trying to document proc macro crate \
- without passing '--crate-type proc-macro to rustdoc",
- );
-
- msg.warn("The generated documentation may be incorrect");
- msg.emit();
+ sess.emit_warning(ProcMacroDocWithoutArg);
} else {
krate = sess.time("maybe_create_a_macro_crate", || {
let is_test_crate = sess.opts.test;
@@ -417,7 +415,7 @@ pub fn configure_and_expand(
}
if sess.opts.unstable_opts.hir_stats {
- hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS");
+ hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS", "ast-stats-2");
}
resolver.resolve_crate(&krate);
@@ -443,23 +441,9 @@ pub fn configure_and_expand(
spans.sort();
if ident == sym::ferris {
let first_span = spans[0];
- sess.diagnostic()
- .struct_span_err(
- MultiSpan::from(spans),
- "Ferris cannot be used as an identifier",
- )
- .span_suggestion(
- first_span,
- "try using their name instead",
- "ferris",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ sess.emit_err(FerrisIdentifier { spans, first_span });
} else {
- sess.diagnostic().span_err(
- MultiSpan::from(spans),
- &format!("identifiers cannot contain emoji: `{}`", ident),
- );
+ sess.emit_err(EmojiIdentifier { spans, ident });
}
}
});
@@ -589,13 +573,24 @@ fn write_out_deps(
// Account for explicitly marked-to-track files
// (e.g. accessed in proc macros).
let file_depinfo = sess.parse_sess.file_depinfo.borrow();
- let extra_tracked_files = file_depinfo.iter().map(|path_sym| {
- let path = PathBuf::from(path_sym.as_str());
+
+ let normalize_path = |path: PathBuf| {
let file = FileName::from(path);
escape_dep_filename(&file.prefer_local().to_string())
- });
+ };
+
+ let extra_tracked_files =
+ file_depinfo.iter().map(|path_sym| normalize_path(PathBuf::from(path_sym.as_str())));
files.extend(extra_tracked_files);
+ // We also need to track used PGO profile files
+ if let Some(ref profile_instr) = sess.opts.cg.profile_use {
+ files.push(normalize_path(profile_instr.as_path().to_path_buf()));
+ }
+ if let Some(ref profile_sample) = sess.opts.unstable_opts.profile_sample_use {
+ files.push(normalize_path(profile_sample.as_path().to_path_buf()));
+ }
+
if sess.binary_dep_depinfo() {
if let Some(ref backend) = sess.opts.unstable_opts.codegen_backend {
if backend.contains('.') {
@@ -662,11 +657,9 @@ fn write_out_deps(
.emit_artifact_notification(&deps_filename, "dep-info");
}
}
- Err(e) => sess.fatal(&format!(
- "error writing dependencies to `{}`: {}",
- deps_filename.display(),
- e
- )),
+ Err(error) => {
+ sess.emit_fatal(ErrorWritingDependencies { path: &deps_filename, error });
+ }
}
}
@@ -696,20 +689,12 @@ pub fn prepare_outputs(
if let Some(ref input_path) = compiler.input_path {
if sess.opts.will_create_output_file() {
if output_contains_path(&output_paths, input_path) {
- let reported = sess.err(&format!(
- "the input file \"{}\" would be overwritten by the generated \
- executable",
- input_path.display()
- ));
+ let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path });
return Err(reported);
}
- if let Some(dir_path) = output_conflicts_with_dir(&output_paths) {
- let reported = sess.err(&format!(
- "the generated executable for the input file \"{}\" conflicts with the \
- existing directory \"{}\"",
- input_path.display(),
- dir_path.display()
- ));
+ if let Some(ref dir_path) = output_conflicts_with_dir(&output_paths) {
+ let reported =
+ sess.emit_err(GeneratedFileConflictsWithDirectory { input_path, dir_path });
return Err(reported);
}
}
@@ -717,8 +702,7 @@ pub fn prepare_outputs(
if let Some(ref dir) = compiler.temps_dir {
if fs::create_dir_all(dir).is_err() {
- let reported =
- sess.err("failed to find or create the directory specified by `--temps-dir`");
+ let reported = sess.emit_err(TempsDirError);
return Err(reported);
}
}
@@ -731,8 +715,7 @@ pub fn prepare_outputs(
if !only_dep_info {
if let Some(ref dir) = compiler.output_dir {
if fs::create_dir_all(dir).is_err() {
- let reported =
- sess.err("failed to find or create the directory specified by `--out-dir`");
+ let reported = sess.emit_err(OutDirError);
return Err(reported);
}
}
@@ -907,13 +890,13 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
});
},
{
- sess.time("liveness_and_intrinsic_checking", || {
- tcx.hir().par_for_each_module(|module| {
+ sess.time("liveness_checking", || {
+ tcx.hir().par_body_owners(|def_id| {
// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
//
// maybe move the check to a MIR pass?
- tcx.ensure().check_mod_liveness(module);
+ tcx.ensure().check_liveness(def_id.to_def_id());
});
});
}
@@ -1015,8 +998,8 @@ pub fn start_codegen<'tcx>(
info!("Post-codegen\n{:?}", tcx.debug_stats());
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
- if let Err(e) = rustc_mir_transform::dump_mir::emit_mir(tcx, outputs) {
- tcx.sess.err(&format!("could not emit MIR: {}", e));
+ if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx, outputs) {
+ tcx.sess.emit_err(CantEmitMIR { error });
tcx.sess.abort_if_errors();
}
}
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 73402ae08..6c725a01b 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -1,3 +1,4 @@
+use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
use crate::interface::{Compiler, Result};
use crate::passes::{self, BoxedResolver, QueryContext};
@@ -165,7 +166,7 @@ impl<'tcx> Queries<'tcx> {
pub fn expansion(
&self,
) -> Result<&Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>> {
- tracing::trace!("expansion");
+ trace!("expansion");
self.expansion.compute(|| {
let crate_name = self.crate_name()?.peek().clone();
let (krate, lint_store) = self.register_plugins()?.take();
@@ -274,18 +275,14 @@ impl<'tcx> Queries<'tcx> {
// Bare `#[rustc_error]`.
None => {
- tcx.sess.span_fatal(
- tcx.def_span(def_id),
- "fatal error triggered by #[rustc_error]",
- );
+ tcx.sess.emit_fatal(RustcErrorFatal { span: tcx.def_span(def_id) });
}
// Some other attribute.
Some(_) => {
- tcx.sess.span_warn(
- tcx.def_span(def_id),
- "unexpected annotation used with `#[rustc_error(...)]!",
- );
+ tcx.sess.emit_warning(RustcErrorUnexpectedAnnotation {
+ span: tcx.def_span(def_id),
+ });
}
}
}
@@ -360,9 +357,8 @@ impl Linker {
if sess.opts.unstable_opts.no_link {
let encoded = CodegenResults::serialize_rlink(&codegen_results);
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
- std::fs::write(&rlink_file, encoded).map_err(|err| {
- sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
- })?;
+ std::fs::write(&rlink_file, encoded)
+ .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
return Ok(());
}
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index a9fdfa241..c7615a577 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -1,4 +1,4 @@
-#![cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#![allow(rustc::bad_opt_access)]
use crate::interface::parse_cfgspecs;
use rustc_data_structures::fx::FxHashSet;
@@ -21,10 +21,8 @@ use rustc_session::{build_session, getopts, DiagnosticOutput, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
use rustc_span::SourceFileHashAlgorithm;
-use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy};
-use rustc_target::spec::{
- RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel,
-};
+use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
+use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
use std::collections::{BTreeMap, BTreeSet};
use std::iter::FromIterator;
@@ -552,7 +550,7 @@ fn test_codegen_options_tracking_hash() {
untracked!(link_args, vec![String::from("abc"), String::from("def")]);
untracked!(link_self_contained, Some(true));
untracked!(linker, Some(PathBuf::from("linker")));
- untracked!(linker_flavor, Some(LinkerFlavor::Gcc));
+ untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc));
untracked!(no_stack_check, true);
untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")]));
untracked!(rpath, true);
@@ -767,6 +765,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(no_profiler_runtime, true);
tracked!(oom, OomStrategy::Panic);
tracked!(osx_rpath_install_name, true);
+ tracked!(packed_bundled_libs, true);
tracked!(panic_abort_tests, true);
tracked!(panic_in_drop, PanicStrategy::Abort);
tracked!(pick_stable_methods_before_any_unstable, false);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 5e5596f13..f7e70d355 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -1,3 +1,4 @@
+use info;
use libloading::Library;
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
@@ -31,7 +32,6 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::OnceLock;
use std::thread;
-use tracing::info;
/// Function pointer type that constructs a new CodegenBackend.
pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
@@ -559,7 +559,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
// command line, then reuse the empty `base` Vec to hold the types that
// will be found in crate attributes.
// JUSTIFICATION: before wrapper fn is available
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
let mut base = session.opts.crate_types.clone();
if base.is_empty() {
base.extend(attr_types);
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 6d311af90..a79c98264 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -18,6 +18,8 @@
//! lexeme types.
//!
//! [`rustc_parse::lexer`]: ../rustc_parse/lexer/index.html
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
// We want to be able to build this crate with a stable compiler, so no
// `#![feature]` attributes should be added.
@@ -139,7 +141,7 @@ pub enum TokenKind {
Unknown,
}
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DocStyle {
Outer,
Inner,
diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs
index 121fefdc6..b97f8acb3 100644
--- a/compiler/rustc_lint/src/array_into_iter.rs
+++ b/compiler/rustc_lint/src/array_into_iter.rs
@@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
}
// We only care about method call expressions.
- if let hir::ExprKind::MethodCall(call, args, _) = &expr.kind {
+ if let hir::ExprKind::MethodCall(call, receiver_arg, ..) = &expr.kind {
if call.ident.name != sym::into_iter {
return;
}
@@ -75,7 +75,6 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
};
// As this is a method call expression, we have at least one argument.
- let receiver_arg = &args[0];
let receiver_ty = cx.typeck_results().expr_ty(receiver_arg);
let adjustments = cx.typeck_results().expr_adjustments(receiver_arg);
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index bd58021f7..0ff2ef5cd 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -21,6 +21,7 @@
//! `late_lint_methods!` invocation in `lib.rs`.
use crate::{
+ errors::BuiltinEllpisisInclusiveRangePatterns,
types::{transparent_newtype_field, CItemKind},
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
};
@@ -58,7 +59,6 @@ use rustc_trait_selection::traits::{self, misc::can_type_implement_copy};
use crate::nonstandard_style::{method_context, MethodLateContext};
use std::fmt::Write;
-use tracing::{debug, trace};
// hardwired lints from librustc_middle
pub use rustc_session::lint::builtin::*;
@@ -259,17 +259,8 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
== Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results()))
{
cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, |lint| {
- let binding = match binding_annot {
- hir::BindingAnnotation::Unannotated => None,
- hir::BindingAnnotation::Mutable => Some("mut"),
- hir::BindingAnnotation::Ref => Some("ref"),
- hir::BindingAnnotation::RefMut => Some("ref mut"),
- };
- let suggested_ident = if let Some(binding) = binding {
- format!("{} {}", binding, ident)
- } else {
- ident.to_string()
- };
+ let suggested_ident =
+ format!("{}{}", binding_annot.prefix_str(), ident);
lint.build(fluent::lint::builtin_non_shorthand_field_patterns)
.set_arg("ident", ident.clone())
.span_suggestion(
@@ -1476,7 +1467,7 @@ impl TypeAliasBounds {
if TypeAliasBounds::is_type_variable_assoc(qpath) {
self.err.span_help(span, fluent::lint::builtin_type_alias_bounds_help);
}
- intravisit::walk_qpath(self, qpath, id, span)
+ intravisit::walk_qpath(self, qpath, id)
}
}
@@ -1760,18 +1751,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
None => format!("&(..={})", end),
};
if join.edition() >= Edition::Edition2021 {
- let mut err = cx.sess().struct_span_err_with_code(
- pat.span,
- msg,
- rustc_errors::error_code!(E0783),
- );
- err.span_suggestion(
- pat.span,
- suggestion,
+ cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns {
+ span: pat.span,
+ suggestion: pat.span,
replace,
- Applicability::MachineApplicable,
- )
- .emit();
+ });
} else {
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| {
lint.build(msg)
@@ -1787,18 +1771,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
} else {
let replace = "..=";
if join.edition() >= Edition::Edition2021 {
- let mut err = cx.sess().struct_span_err_with_code(
- pat.span,
- msg,
- rustc_errors::error_code!(E0783),
- );
- err.span_suggestion_short(
- join,
- suggestion,
- replace,
- Applicability::MachineApplicable,
- )
- .emit();
+ cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns {
+ span: pat.span,
+ suggestion: join,
+ replace: replace.to_string(),
+ });
} else {
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| {
lint.build(msg)
@@ -2023,7 +2000,7 @@ impl KeywordIdents {
}
impl EarlyLintPass for KeywordIdents {
- fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) {
+ fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) {
self.check_tokens(cx, mac_def.body.inner_tokens());
}
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
@@ -2039,13 +2016,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
impl ExplicitOutlivesRequirements {
fn lifetimes_outliving_lifetime<'tcx>(
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
- index: u32,
+ def_id: DefId,
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
- ty::ReEarlyBound(ebr) if ebr.index == index => Some(b),
+ ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b),
_ => None,
},
_ => None,
@@ -2082,8 +2059,12 @@ impl ExplicitOutlivesRequirements {
.filter_map(|(i, bound)| {
if let hir::GenericBound::Outlives(lifetime) = bound {
let is_inferred = match tcx.named_region(lifetime.hir_id) {
- Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| {
- if let ty::ReEarlyBound(ebr) = **r { ebr.index == index } else { false }
+ Some(Region::EarlyBound(def_id)) => inferred_outlives.iter().any(|r| {
+ if let ty::ReEarlyBound(ebr) = **r {
+ ebr.def_id == def_id
+ } else {
+ false
+ }
}),
_ => false,
};
@@ -2177,11 +2158,14 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
for (i, where_predicate) in hir_generics.predicates.iter().enumerate() {
let (relevant_lifetimes, bounds, span, in_where_clause) = match where_predicate {
hir::WherePredicate::RegionPredicate(predicate) => {
- if let Some(Region::EarlyBound(index, ..)) =
+ if let Some(Region::EarlyBound(region_def_id)) =
cx.tcx.named_region(predicate.lifetime.hir_id)
{
(
- Self::lifetimes_outliving_lifetime(inferred_outlives, index),
+ Self::lifetimes_outliving_lifetime(
+ inferred_outlives,
+ region_def_id,
+ ),
&predicate.bounds,
predicate.span,
predicate.in_where_clause,
@@ -2419,13 +2403,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
_ => {}
}
}
- } else if let hir::ExprKind::MethodCall(_, ref args, _) = expr.kind {
+ } else if let hir::ExprKind::MethodCall(_, receiver, ..) = expr.kind {
// Find problematic calls to `MaybeUninit::assume_init`.
let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
if cx.tcx.is_diagnostic_item(sym::assume_init, def_id) {
// This is a call to *some* method named `assume_init`.
// See if the `self` parameter is one of the dangerous constructors.
- if let hir::ExprKind::Call(ref path_expr, _) = args[0].kind {
+ if let hir::ExprKind::Call(ref path_expr, _) = receiver.kind {
if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
match cx.tcx.get_diagnostic_name(def_id) {
@@ -2475,6 +2459,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
Char if init == InitKind::Uninit => {
Some(("characters must be a valid Unicode codepoint".to_string(), None))
}
+ Int(_) | Uint(_) if init == InitKind::Uninit => {
+ Some(("integers must not be uninitialized".to_string(), None))
+ }
+ Float(_) if init == InitKind::Uninit => {
+ Some(("floats must not be uninitialized".to_string(), None))
+ }
+ RawPtr(_) if init == InitKind::Uninit => {
+ Some(("raw pointers must not be uninitialized".to_string(), None))
+ }
// Recurse and checks for some compound types.
Adt(adt_def, substs) if !adt_def.is_union() => {
// First check if this ADT has a layout attribute (like `NonNull` and friends).
@@ -3170,3 +3163,117 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
}
}
}
+
+declare_lint! {
+ /// The `special_module_name` lint detects module
+ /// declarations for files that have a special meaning.
+ ///
+ /// ### Example
+ ///
+ /// ```rust,compile_fail
+ /// mod lib;
+ ///
+ /// fn main() {
+ /// lib::run();
+ /// }
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// Cargo recognizes `lib.rs` and `main.rs` as the root of a
+ /// library or binary crate, so declaring them as modules
+ /// will lead to miscompilation of the crate unless configured
+ /// explicitly.
+ ///
+ /// To access a library from a binary target within the same crate,
+ /// use `your_crate_name::` as the path path instead of `lib::`:
+ ///
+ /// ```rust,compile_fail
+ /// // bar/src/lib.rs
+ /// fn run() {
+ /// // ...
+ /// }
+ ///
+ /// // bar/src/main.rs
+ /// fn main() {
+ /// bar::run();
+ /// }
+ /// ```
+ ///
+ /// Binary targets cannot be used as libraries and so declaring
+ /// one as a module is not allowed.
+ pub SPECIAL_MODULE_NAME,
+ Warn,
+ "module declarations for files with a special meaning",
+}
+
+declare_lint_pass!(SpecialModuleName => [SPECIAL_MODULE_NAME]);
+
+impl EarlyLintPass for SpecialModuleName {
+ fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
+ for item in &krate.items {
+ if let ast::ItemKind::Mod(
+ _,
+ ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _),
+ ) = item.kind
+ {
+ if item.attrs.iter().any(|a| a.has_name(sym::path)) {
+ continue;
+ }
+
+ match item.ident.name.as_str() {
+ "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
+ lint.build("found module declaration for lib.rs")
+ .note("lib.rs is the root of this crate's library target")
+ .help("to refer to it from other targets, use the library's name as the path")
+ .emit()
+ }),
+ "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
+ lint.build("found module declaration for main.rs")
+ .note("a binary crate cannot be used as library")
+ .emit()
+ }),
+ _ => continue
+ }
+ }
+ }
+ }
+}
+
+pub use rustc_session::lint::builtin::UNEXPECTED_CFGS;
+
+declare_lint_pass!(UnexpectedCfgs => [UNEXPECTED_CFGS]);
+
+impl EarlyLintPass for UnexpectedCfgs {
+ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
+ let cfg = &cx.sess().parse_sess.config;
+ let check_cfg = &cx.sess().parse_sess.check_config;
+ for &(name, value) in cfg {
+ if let Some(names_valid) = &check_cfg.names_valid {
+ if !names_valid.contains(&name) {
+ cx.lookup(UNEXPECTED_CFGS, None::<MultiSpan>, |diag| {
+ diag.build(fluent::lint::builtin_unexpected_cli_config_name)
+ .help(fluent::lint::help)
+ .set_arg("name", name)
+ .emit();
+ });
+ }
+ }
+ if let Some(value) = value {
+ if let Some(values) = &check_cfg.values_valid.get(&name) {
+ if !values.contains(&value) {
+ cx.lookup(UNEXPECTED_CFGS, None::<MultiSpan>, |diag| {
+ diag.build(fluent::lint::builtin_unexpected_cli_config_value)
+ .help(fluent::lint::help)
+ .set_arg("name", name)
+ .set_arg("value", value)
+ .emit();
+ });
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b95fc341d..7ca6ec5d9 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -16,12 +16,16 @@
use self::TargetLint::*;
+use crate::errors::{
+ CheckNameDeprecated, CheckNameUnknown, CheckNameUnknownTool, CheckNameWarning, RequestedLevel,
+ UnsupportedGroup,
+};
use crate::levels::LintLevelsBuilder;
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync;
-use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err};
+use rustc_errors::add_elided_lifetime_in_path_suggestion;
use rustc_errors::{
Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle,
};
@@ -39,14 +43,17 @@ use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintI
use rustc_session::Session;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{sym, Ident, Symbol};
-use rustc_span::{BytePos, Span, DUMMY_SP};
+use rustc_span::{BytePos, Span};
use rustc_target::abi;
-use tracing::debug;
use std::cell::Cell;
use std::iter;
use std::slice;
+type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync;
+type LateLintPassFactory =
+ dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::Send + sync::Sync;
+
/// Information about the registered lints.
///
/// This is basically the subset of `Context` that we can
@@ -61,11 +68,11 @@ pub struct LintStore {
/// interior mutability, we don't enforce this (and lints should, in theory,
/// be compatible with being constructed more than once, though not
/// necessarily in a sane manner. This is safe though.)
- pub pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
- pub early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
- pub late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
+ pub pre_expansion_passes: Vec<Box<EarlyLintPassFactory>>,
+ pub early_passes: Vec<Box<EarlyLintPassFactory>>,
+ pub late_passes: Vec<Box<LateLintPassFactory>>,
/// This is unique in that we construct them per-module, so not once.
- pub late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
+ pub late_module_passes: Vec<Box<LateLintPassFactory>>,
/// Lints indexed by name.
by_name: FxHashMap<String, TargetLint>,
@@ -183,14 +190,20 @@ impl LintStore {
pub fn register_late_pass(
&mut self,
- pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
+ pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
+ + 'static
+ + sync::Send
+ + sync::Sync,
) {
self.late_passes.push(Box::new(pass));
}
pub fn register_late_mod_pass(
&mut self,
- pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
+ pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
+ + 'static
+ + sync::Send
+ + sync::Sync,
) {
self.late_module_passes.push(Box::new(pass));
}
@@ -326,68 +339,41 @@ impl LintStore {
) {
let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn(_)) {
- struct_span_err!(
- sess,
- DUMMY_SP,
- E0602,
- "`{}` lint group is not supported with ´--force-warn´",
- crate::WARNINGS.name_lower()
- )
- .emit();
+ sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
return;
}
- let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
- CheckLintNameResult::Ok(_) => None,
- CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)),
+ let lint_name = lint_name.to_string();
+ match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
+ CheckLintNameResult::Warning(msg, _) => {
+ sess.emit_warning(CheckNameWarning {
+ msg,
+ sub: RequestedLevel { level, lint_name },
+ });
+ }
CheckLintNameResult::NoLint(suggestion) => {
- let mut err =
- struct_span_err!(sess, DUMMY_SP, E0602, "unknown lint: `{}`", lint_name);
-
- if let Some(suggestion) = suggestion {
- err.help(&format!("did you mean: `{}`", suggestion));
+ sess.emit_err(CheckNameUnknown {
+ lint_name: lint_name.clone(),
+ suggestion,
+ sub: RequestedLevel { level, lint_name },
+ });
+ }
+ CheckLintNameResult::Tool(result) => {
+ if let Err((Some(_), new_name)) = result {
+ sess.emit_warning(CheckNameDeprecated {
+ lint_name: lint_name.clone(),
+ new_name,
+ sub: RequestedLevel { level, lint_name },
+ });
}
-
- Some(err.forget_guarantee())
}
- CheckLintNameResult::Tool(result) => match result {
- Err((Some(_), new_name)) => Some(sess.struct_warn(&format!(
- "lint name `{}` is deprecated \
- and does not have an effect anymore. \
- Use: {}",
- lint_name, new_name
- ))),
- _ => None,
- },
- CheckLintNameResult::NoTool => Some(
- struct_span_err!(
- sess,
- DUMMY_SP,
- E0602,
- "unknown lint tool: `{}`",
- tool_name.unwrap()
- )
- .forget_guarantee(),
- ),
+ CheckLintNameResult::NoTool => {
+ sess.emit_err(CheckNameUnknownTool {
+ tool_name: tool_name.unwrap(),
+ sub: RequestedLevel { level, lint_name },
+ });
+ }
+ _ => {}
};
-
- if let Some(mut db) = db {
- let msg = format!(
- "requested on the command line with `{} {}`",
- match level {
- Level::Allow => "-A",
- Level::Warn => "-W",
- Level::ForceWarn(_) => "--force-warn",
- Level::Deny => "-D",
- Level::Forbid => "-F",
- Level::Expect(_) => {
- unreachable!("lints with the level of `expect` should not run this code");
- }
- },
- lint_name
- );
- db.note(&msg);
- db.emit();
- }
}
/// True if this symbol represents a lint group name.
@@ -440,7 +426,7 @@ impl LintStore {
None => {
// 1. The tool is currently running, so this lint really doesn't exist.
// FIXME: should this handle tools that never register a lint, like rustfmt?
- tracing::debug!("lints={:?}", self.by_name.keys().collect::<Vec<_>>());
+ debug!("lints={:?}", self.by_name.keys().collect::<Vec<_>>());
let tool_prefix = format!("{}::", tool_name);
return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
self.no_lint_suggestion(&complete_name)
@@ -533,7 +519,7 @@ impl LintStore {
CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name)))
}
Some(other) => {
- tracing::debug!("got renamed lint {:?}", other);
+ debug!("got renamed lint {:?}", other);
CheckLintNameResult::NoLint(None)
}
}
@@ -582,7 +568,7 @@ pub trait LintPassObject: Sized {}
impl LintPassObject for EarlyLintPassObject {}
-impl LintPassObject for LateLintPassObject {}
+impl LintPassObject for LateLintPassObject<'_> {}
pub trait LintContext: Sized {
type PassObject: LintPassObject;
@@ -865,9 +851,14 @@ pub trait LintContext: Sized {
if let Some(positional_arg_to_replace) = position_sp_to_replace {
let name = if is_formatting_arg { named_arg_name + "$" } else { named_arg_name };
-
+ let span_to_replace = if let Ok(positional_arg_content) =
+ self.sess().source_map().span_to_snippet(positional_arg_to_replace) && positional_arg_content.starts_with(':') {
+ positional_arg_to_replace.shrink_to_lo()
+ } else {
+ positional_arg_to_replace
+ };
db.span_suggestion_verbose(
- positional_arg_to_replace,
+ span_to_replace,
"use the named argument by name to avoid ambiguity",
name,
Applicability::MaybeIncorrect,
@@ -968,8 +959,8 @@ impl<'a> EarlyContext<'a> {
}
}
-impl LintContext for LateContext<'_> {
- type PassObject = LateLintPassObject;
+impl<'tcx> LintContext for LateContext<'tcx> {
+ type PassObject = LateLintPassObject<'tcx>;
/// Gets the overall compiler `Session` object.
fn sess(&self) -> &Session {
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index d13711c3a..96ecd79a6 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -26,7 +26,6 @@ use rustc_span::symbol::Ident;
use rustc_span::Span;
use std::slice;
-use tracing::debug;
macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
$cx.pass.$f(&$cx.context, $($args),*);
@@ -45,7 +44,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
lint_id.lint,
Some(span),
|lint| {
- lint.build(&msg).emit();
+ lint.build(msg).emit();
},
diagnostic,
);
@@ -101,6 +100,12 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
run_early_pass!(self, check_pat_post, p);
}
+ fn visit_pat_field(&mut self, field: &'a ast::PatField) {
+ self.with_lint_attrs(field.id, &field.attrs, |cx| {
+ ast_visit::walk_pat_field(cx, field);
+ });
+ }
+
fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
self.check_id(c.id);
ast_visit::walk_anon_const(self, c);
@@ -142,7 +147,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, span: Span, id: ast::NodeId) {
run_early_pass!(self, check_fn, fk, span, id);
self.check_id(id);
- ast_visit::walk_fn(self, fk, span);
+ ast_visit::walk_fn(self, fk);
// Explicitly check for lints associated with 'closure_id', since
// it does not have a corresponding AST node
@@ -219,9 +224,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
}
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
- run_early_pass!(self, check_generic_param, param);
- self.check_id(param.id);
- ast_visit::walk_generic_param(self, param);
+ self.with_lint_attrs(param.id, &param.attrs, |cx| {
+ run_early_pass!(cx, check_generic_param, param);
+ ast_visit::walk_generic_param(cx, param);
+ });
}
fn visit_generics(&mut self, g: &'a ast::Generics) {
@@ -233,9 +239,9 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
ast_visit::walk_where_predicate(self, p);
}
- fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef, m: &'a ast::TraitBoundModifier) {
- run_early_pass!(self, check_poly_trait_ref, t, m);
- ast_visit::walk_poly_trait_ref(self, t, m);
+ fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {
+ run_early_pass!(self, check_poly_trait_ref, t);
+ ast_visit::walk_poly_trait_ref(self, t);
}
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
@@ -260,9 +266,9 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
ast_visit::walk_path(self, p);
}
- fn visit_path_segment(&mut self, path_span: Span, s: &'a ast::PathSegment) {
+ fn visit_path_segment(&mut self, s: &'a ast::PathSegment) {
self.check_id(s.id);
- ast_visit::walk_path_segment(self, path_span, s);
+ ast_visit::walk_path_segment(self, s);
}
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
@@ -270,7 +276,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
}
fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) {
- run_early_pass!(self, check_mac_def, mac, id);
+ run_early_pass!(self, check_mac_def, mac);
self.check_id(id);
}
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
new file mode 100644
index 000000000..5c183d409
--- /dev/null
+++ b/compiler/rustc_lint/src/errors.rs
@@ -0,0 +1,162 @@
+use rustc_errors::{fluent, AddSubdiagnostic, ErrorGuaranteed, Handler};
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_session::{lint::Level, SessionDiagnostic};
+use rustc_span::{Span, Symbol};
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::overruled_attribute, code = "E0453")]
+pub struct OverruledAttribute {
+ #[primary_span]
+ pub span: Span,
+ #[label]
+ pub overruled: Span,
+ pub lint_level: String,
+ pub lint_source: Symbol,
+ #[subdiagnostic]
+ pub sub: OverruledAttributeSub,
+}
+//
+pub enum OverruledAttributeSub {
+ DefaultSource { id: String },
+ NodeSource { span: Span, reason: Option<Symbol> },
+ CommandLineSource,
+}
+
+impl AddSubdiagnostic for OverruledAttributeSub {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ match self {
+ OverruledAttributeSub::DefaultSource { id } => {
+ diag.note(fluent::lint::default_source);
+ diag.set_arg("id", id);
+ }
+ OverruledAttributeSub::NodeSource { span, reason } => {
+ diag.span_label(span, fluent::lint::node_source);
+ if let Some(rationale) = reason {
+ diag.note(rationale.as_str());
+ }
+ }
+ OverruledAttributeSub::CommandLineSource => {
+ diag.note(fluent::lint::command_line_source);
+ }
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::malformed_attribute, code = "E0452")]
+pub struct MalformedAttribute {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub sub: MalformedAttributeSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum MalformedAttributeSub {
+ #[label(lint::bad_attribute_argument)]
+ BadAttributeArgument(#[primary_span] Span),
+ #[label(lint::reason_must_be_string_literal)]
+ ReasonMustBeStringLiteral(#[primary_span] Span),
+ #[label(lint::reason_must_come_last)]
+ ReasonMustComeLast(#[primary_span] Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::unknown_tool_in_scoped_lint, code = "E0710")]
+pub struct UnknownToolInScopedLint {
+ #[primary_span]
+ pub span: Option<Span>,
+ pub tool_name: Symbol,
+ pub lint_name: String,
+ #[help]
+ pub is_nightly_build: Option<()>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::builtin_ellipsis_inclusive_range_patterns, code = "E0783")]
+pub struct BuiltinEllpisisInclusiveRangePatterns {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion_short(code = "{replace}", applicability = "machine-applicable")]
+ pub suggestion: Span,
+ pub replace: String,
+}
+
+pub struct RequestedLevel {
+ pub level: Level,
+ pub lint_name: String,
+}
+
+impl AddSubdiagnostic for RequestedLevel {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ diag.note(fluent::lint::requested_level);
+ diag.set_arg(
+ "level",
+ match self.level {
+ Level::Allow => "-A",
+ Level::Warn => "-W",
+ Level::ForceWarn(_) => "--force-warn",
+ Level::Deny => "-D",
+ Level::Forbid => "-F",
+ Level::Expect(_) => {
+ unreachable!("lints with the level of `expect` should not run this code");
+ }
+ },
+ );
+ diag.set_arg("lint_name", self.lint_name);
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::unsupported_group, code = "E0602")]
+pub struct UnsupportedGroup {
+ pub lint_group: String,
+}
+
+pub struct CheckNameUnknown {
+ pub lint_name: String,
+ pub suggestion: Option<Symbol>,
+ pub sub: RequestedLevel,
+}
+
+impl SessionDiagnostic<'_> for CheckNameUnknown {
+ fn into_diagnostic(
+ self,
+ handler: &Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = handler.struct_err(fluent::lint::check_name_unknown);
+ diag.code(rustc_errors::error_code!(E0602));
+ if let Some(suggestion) = self.suggestion {
+ diag.help(fluent::lint::help);
+ diag.set_arg("suggestion", suggestion);
+ }
+ diag.set_arg("lint_name", self.lint_name);
+ diag.subdiagnostic(self.sub);
+ diag
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::check_name_unknown_tool, code = "E0602")]
+pub struct CheckNameUnknownTool {
+ pub tool_name: Symbol,
+ #[subdiagnostic]
+ pub sub: RequestedLevel,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::check_name_warning)]
+pub struct CheckNameWarning {
+ pub msg: String,
+ #[subdiagnostic]
+ pub sub: RequestedLevel,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(lint::check_name_deprecated)]
+pub struct CheckNameDeprecated {
+ pub lint_name: String,
+ pub new_name: String,
+ #[subdiagnostic]
+ pub sub: RequestedLevel,
+}
diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
index fe2712525..8f2222132 100644
--- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
+++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
@@ -120,8 +120,8 @@ impl EarlyLintPass for HiddenUnicodeCodepoints {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
// byte strings are already handled well enough by `EscapeError::NonAsciiCharInByteString`
let (text, span, padding) = match &expr.kind {
- ast::ExprKind::Lit(ast::Lit { token, kind, span }) => {
- let text = token.symbol;
+ ast::ExprKind::Lit(ast::Lit { token_lit, kind, span }) => {
+ let text = token_lit.symbol;
if !contains_text_flow_control_chars(text.as_str()) {
return;
}
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index c26d78247..dd1fc5916 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -12,7 +12,6 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
-use tracing::debug;
declare_tool_lint! {
pub rustc::DEFAULT_HASH_TYPES,
@@ -52,7 +51,7 @@ fn typeck_results_of_method_fn<'tcx>(
expr: &Expr<'_>,
) -> Option<(Span, DefId, ty::subst::SubstsRef<'tcx>)> {
match expr.kind {
- ExprKind::MethodCall(segment, _, _)
+ ExprKind::MethodCall(segment, ..)
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) =>
{
Some((segment.ident.span, def_id, cx.typeck_results().node_substs(expr.hir_id)))
@@ -119,8 +118,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
_: rustc_hir::HirId,
) {
if let Some(segment) = path.segments.iter().nth_back(1)
- && let Some(res) = &segment.res
- && lint_ty_kind_usage(cx, res)
+ && lint_ty_kind_usage(cx, &segment.res)
{
let span = path.span.with_hi(
segment.args.map_or(segment.ident.span, |a| a.span_ext).hi()
@@ -393,8 +391,14 @@ impl LateLintPass<'_> for Diagnostics {
return;
}
+ let mut found_parent_with_attr = false;
let mut found_impl = false;
- for (_, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
+ for (hir_id, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
+ if let Some(owner_did) = hir_id.as_owner() {
+ found_parent_with_attr = found_parent_with_attr
+ || cx.tcx.has_attr(owner_did.to_def_id(), sym::rustc_lint_diagnostics);
+ }
+
debug!(?parent);
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent &&
let Impl { of_trait: Some(of_trait), .. } = impl_ &&
@@ -407,7 +411,7 @@ impl LateLintPass<'_> for Diagnostics {
}
}
debug!(?found_impl);
- if !found_impl {
+ if !found_parent_with_attr && !found_impl {
cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| {
lint.build(fluent::lint::diag_out_of_impl).emit();
})
@@ -425,7 +429,7 @@ impl LateLintPass<'_> for Diagnostics {
}
}
debug!(?found_diagnostic_message);
- if !found_diagnostic_message {
+ if !found_parent_with_attr && !found_diagnostic_message {
cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| {
lint.build(fluent::lint::untranslatable_diag).emit();
})
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index a329b3751..da6f1c5ee 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -24,13 +24,11 @@ use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::LintPass;
-use rustc_span::symbol::Symbol;
use rustc_span::Span;
use std::any::Any;
use std::cell::Cell;
use std::slice;
-use tracing::debug;
/// Extract the `LintStore` from the query context.
/// This function exists because we've erased `LintStore` as `dyn Any` in the context.
@@ -78,8 +76,8 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> {
self.context.param_env = old_param_env;
}
- fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) {
- lint_callback!(self, check_mod, m, s, n);
+ fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, n: hir::HirId) {
+ lint_callback!(self, check_mod, m, n);
hir_visit::walk_mod(self, m, n);
}
}
@@ -189,19 +187,12 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
let old_cached_typeck_results = self.context.cached_typeck_results.take();
let body = self.context.tcx.hir().body(body_id);
lint_callback!(self, check_fn, fk, decl, body, span, id);
- hir_visit::walk_fn(self, fk, decl, body_id, span, id);
+ hir_visit::walk_fn(self, fk, decl, body_id, id);
self.context.enclosing_body = old_enclosing_body;
self.context.cached_typeck_results.set(old_cached_typeck_results);
}
- fn visit_variant_data(
- &mut self,
- s: &'tcx hir::VariantData<'tcx>,
- _: Symbol,
- _: &'tcx hir::Generics<'tcx>,
- _: hir::HirId,
- _: Span,
- ) {
+ fn visit_variant_data(&mut self, s: &'tcx hir::VariantData<'tcx>) {
lint_callback!(self, check_struct_def, s);
hir_visit::walk_struct_def(self, s);
}
@@ -213,15 +204,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
})
}
- fn visit_variant(
- &mut self,
- v: &'tcx hir::Variant<'tcx>,
- g: &'tcx hir::Generics<'tcx>,
- item_id: hir::HirId,
- ) {
+ fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
self.with_lint_attrs(v.id, |cx| {
lint_callback!(cx, check_variant, v);
- hir_visit::walk_variant(cx, v, g, item_id);
+ hir_visit::walk_variant(cx, v);
})
}
@@ -234,9 +220,9 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
hir_visit::walk_inf(self, inf);
}
- fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) {
+ fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: hir::HirId) {
if !self.context.only_module {
- self.process_mod(m, s, n);
+ self.process_mod(m, n);
}
}
@@ -272,13 +258,9 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
hir_visit::walk_where_predicate(self, p);
}
- fn visit_poly_trait_ref(
- &mut self,
- t: &'tcx hir::PolyTraitRef<'tcx>,
- m: hir::TraitBoundModifier,
- ) {
- lint_callback!(self, check_poly_trait_ref, t, m);
- hir_visit::walk_poly_trait_ref(self, t, m);
+ fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef<'tcx>) {
+ lint_callback!(self, check_poly_trait_ref, t);
+ hir_visit::walk_poly_trait_ref(self, t);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
@@ -320,12 +302,12 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
}
-struct LateLintPassObjects<'a> {
- lints: &'a mut [LateLintPassObject],
+struct LateLintPassObjects<'a, 'tcx> {
+ lints: &'a mut [LateLintPassObject<'tcx>],
}
#[allow(rustc::lint_pass_impl_without_macro)]
-impl LintPass for LateLintPassObjects<'_> {
+impl LintPass for LateLintPassObjects<'_, '_> {
fn name(&self) -> &'static str {
panic!()
}
@@ -343,7 +325,7 @@ macro_rules! expand_late_lint_pass_impl_methods {
macro_rules! late_lint_pass_impl {
([], [$hir:tt], $methods:tt) => {
- impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_> {
+ impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
expand_late_lint_pass_impl_methods!([$hir], $methods);
}
};
@@ -372,8 +354,8 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
let mut cx = LateContextAndPass { context, pass };
- let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
- cx.process_mod(module, span, hir_id);
+ let (module, _span, hir_id) = tcx.hir().get_module(module_def_id);
+ cx.process_mod(module, hir_id);
// Visit the crate attributes
if hir_id == hir::CRATE_HIR_ID {
@@ -396,7 +378,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
late_lint_mod_pass(tcx, module_def_id, builtin_lints);
let mut passes: Vec<_> =
- unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
+ unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
if !passes.is_empty() {
late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
@@ -432,7 +414,8 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
}
fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
- let mut passes = unerased_lint_store(tcx).late_passes.iter().map(|p| (p)()).collect::<Vec<_>>();
+ let mut passes =
+ unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
if !tcx.sess.opts.unstable_opts.no_interleave_lints {
if !passes.is_empty() {
@@ -448,7 +431,7 @@ fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints
}
let mut passes: Vec<_> =
- unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
+ unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
for pass in &mut passes {
tcx.sess.prof.extra_verbose_generic_activity("run_late_module_lint", pass.name()).run(
diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs
new file mode 100644
index 000000000..7e885e6c5
--- /dev/null
+++ b/compiler/rustc_lint/src/let_underscore.rs
@@ -0,0 +1,175 @@
+use crate::{LateContext, LateLintPass, LintContext};
+use rustc_errors::{Applicability, LintDiagnosticBuilder, MultiSpan};
+use rustc_hir as hir;
+use rustc_middle::ty;
+use rustc_span::Symbol;
+
+declare_lint! {
+ /// The `let_underscore_drop` lint checks for statements which don't bind
+ /// an expression which has a non-trivial Drop implementation to anything,
+ /// causing the expression to be dropped immediately instead of at end of
+ /// scope.
+ ///
+ /// ### Example
+ /// ```
+ /// struct SomeStruct;
+ /// impl Drop for SomeStruct {
+ /// fn drop(&mut self) {
+ /// println!("Dropping SomeStruct");
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// #[warn(let_underscore_drop)]
+ /// // SomeStuct is dropped immediately instead of at end of scope,
+ /// // so "Dropping SomeStruct" is printed before "end of main".
+ /// // The order of prints would be reversed if SomeStruct was bound to
+ /// // a name (such as "_foo").
+ /// let _ = SomeStruct;
+ /// println!("end of main");
+ /// }
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// Statements which assign an expression to an underscore causes the
+ /// expression to immediately drop instead of extending the expression's
+ /// lifetime to the end of the scope. This is usually unintended,
+ /// especially for types like `MutexGuard`, which are typically used to
+ /// lock a mutex for the duration of an entire scope.
+ ///
+ /// If you want to extend the expression's lifetime to the end of the scope,
+ /// assign an underscore-prefixed name (such as `_foo`) to the expression.
+ /// If you do actually want to drop the expression immediately, then
+ /// calling `std::mem::drop` on the expression is clearer and helps convey
+ /// intent.
+ pub LET_UNDERSCORE_DROP,
+ Allow,
+ "non-binding let on a type that implements `Drop`"
+}
+
+declare_lint! {
+ /// The `let_underscore_lock` lint checks for statements which don't bind
+ /// a mutex to anything, causing the lock to be released immediately instead
+ /// of at end of scope, which is typically incorrect.
+ ///
+ /// ### Example
+ /// ```compile_fail
+ /// use std::sync::{Arc, Mutex};
+ /// use std::thread;
+ /// let data = Arc::new(Mutex::new(0));
+ ///
+ /// thread::spawn(move || {
+ /// // The lock is immediately released instead of at the end of the
+ /// // scope, which is probably not intended.
+ /// let _ = data.lock().unwrap();
+ /// println!("doing some work");
+ /// let mut lock = data.lock().unwrap();
+ /// *lock += 1;
+ /// });
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// Statements which assign an expression to an underscore causes the
+ /// expression to immediately drop instead of extending the expression's
+ /// lifetime to the end of the scope. This is usually unintended,
+ /// especially for types like `MutexGuard`, which are typically used to
+ /// lock a mutex for the duration of an entire scope.
+ ///
+ /// If you want to extend the expression's lifetime to the end of the scope,
+ /// assign an underscore-prefixed name (such as `_foo`) to the expression.
+ /// If you do actually want to drop the expression immediately, then
+ /// calling `std::mem::drop` on the expression is clearer and helps convey
+ /// intent.
+ pub LET_UNDERSCORE_LOCK,
+ Deny,
+ "non-binding let on a synchronization lock"
+}
+
+declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK]);
+
+const SYNC_GUARD_SYMBOLS: [Symbol; 3] = [
+ rustc_span::sym::MutexGuard,
+ rustc_span::sym::RwLockReadGuard,
+ rustc_span::sym::RwLockWriteGuard,
+];
+
+impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
+ fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
+ if !matches!(local.pat.kind, hir::PatKind::Wild) {
+ return;
+ }
+ if let Some(init) = local.init {
+ let init_ty = cx.typeck_results().expr_ty(init);
+ // If the type has a trivial Drop implementation, then it doesn't
+ // matter that we drop the value immediately.
+ if !init_ty.needs_drop(cx.tcx, cx.param_env) {
+ return;
+ }
+ let is_sync_lock = match init_ty.kind() {
+ ty::Adt(adt, _) => SYNC_GUARD_SYMBOLS
+ .iter()
+ .any(|guard_symbol| cx.tcx.is_diagnostic_item(*guard_symbol, adt.did())),
+ _ => false,
+ };
+
+ if is_sync_lock {
+ let mut span = MultiSpan::from_spans(vec![local.pat.span, init.span]);
+ span.push_span_label(
+ local.pat.span,
+ "this lock is not assigned to a binding and is immediately dropped".to_string(),
+ );
+ span.push_span_label(
+ init.span,
+ "this binding will immediately drop the value assigned to it".to_string(),
+ );
+ cx.struct_span_lint(LET_UNDERSCORE_LOCK, span, |lint| {
+ build_and_emit_lint(
+ lint,
+ local,
+ init.span,
+ "non-binding let on a synchronization lock",
+ )
+ })
+ } else {
+ cx.struct_span_lint(LET_UNDERSCORE_DROP, local.span, |lint| {
+ build_and_emit_lint(
+ lint,
+ local,
+ init.span,
+ "non-binding let on a type that implements `Drop`",
+ );
+ })
+ }
+ }
+ }
+}
+
+fn build_and_emit_lint(
+ lint: LintDiagnosticBuilder<'_, ()>,
+ local: &hir::Local<'_>,
+ init_span: rustc_span::Span,
+ msg: &str,
+) {
+ lint.build(msg)
+ .span_suggestion_verbose(
+ local.pat.span,
+ "consider binding to an unused variable to avoid immediately dropping the value",
+ "_unused",
+ Applicability::MachineApplicable,
+ )
+ .multipart_suggestion(
+ "consider immediately dropping the value",
+ vec![
+ (local.span.until(init_span), "drop(".to_string()),
+ (init_span.shrink_to_hi(), ")".to_string()),
+ ],
+ Applicability::MachineApplicable,
+ )
+ .emit();
+}
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 00e96f20d..1e16ac51e 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -3,7 +3,7 @@ use crate::late::unerased_lint_store;
use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{struct_span_err, Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan};
+use rustc_errors::{Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan};
use rustc_hir as hir;
use rustc_hir::{intravisit, HirId};
use rustc_middle::hir::nested_filter;
@@ -21,7 +21,11 @@ use rustc_session::parse::{add_feature_diagnostics, feature_err};
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
-use tracing::debug;
+
+use crate::errors::{
+ MalformedAttribute, MalformedAttributeSub, OverruledAttribute, OverruledAttributeSub,
+ UnknownToolInScopedLint,
+};
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
let store = unerased_lint_store(tcx);
@@ -186,16 +190,26 @@ impl<'s> LintLevelsBuilder<'s> {
}
};
if !fcw_warning {
- let mut diag_builder = struct_span_err!(
- self.sess,
- src.span(),
- E0453,
- "{}({}) incompatible with previous forbid",
- level.as_str(),
- src.name(),
- );
- decorate_diag(&mut diag_builder);
- diag_builder.emit();
+ self.sess.emit_err(OverruledAttribute {
+ span: src.span(),
+ overruled: src.span(),
+ lint_level: level.as_str().to_string(),
+ lint_source: src.name(),
+ sub: match old_src {
+ LintLevelSource::Default => {
+ OverruledAttributeSub::DefaultSource { id: id.to_string() }
+ }
+ LintLevelSource::Node(_, forbid_source_span, reason) => {
+ OverruledAttributeSub::NodeSource {
+ span: forbid_source_span,
+ reason,
+ }
+ }
+ LintLevelSource::CommandLine(_, _) => {
+ OverruledAttributeSub::CommandLineSource
+ }
+ },
+ });
} else {
self.struct_lint(
FORBIDDEN_LINT_GROUPS,
@@ -266,7 +280,6 @@ impl<'s> LintLevelsBuilder<'s> {
self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev });
let sess = self.sess;
- let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
for (attr_index, attr) in attrs.iter().enumerate() {
if attr.has_name(sym::automatically_derived) {
self.current_specs_mut().insert(
@@ -317,20 +330,27 @@ impl<'s> LintLevelsBuilder<'s> {
}
reason = Some(rationale);
} else {
- bad_attr(name_value.span)
- .span_label(name_value.span, "reason must be a string literal")
- .emit();
+ sess.emit_err(MalformedAttribute {
+ span: name_value.span,
+ sub: MalformedAttributeSub::ReasonMustBeStringLiteral(
+ name_value.span,
+ ),
+ });
}
// found reason, reslice meta list to exclude it
metas.pop().unwrap();
} else {
- bad_attr(item.span)
- .span_label(item.span, "bad attribute argument")
- .emit();
+ sess.emit_err(MalformedAttribute {
+ span: item.span,
+ sub: MalformedAttributeSub::BadAttributeArgument(item.span),
+ });
}
}
ast::MetaItemKind::List(_) => {
- bad_attr(item.span).span_label(item.span, "bad attribute argument").emit();
+ sess.emit_err(MalformedAttribute {
+ span: item.span,
+ sub: MalformedAttributeSub::BadAttributeArgument(item.span),
+ });
}
}
}
@@ -348,20 +368,21 @@ impl<'s> LintLevelsBuilder<'s> {
let meta_item = match li {
ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item,
_ => {
- let mut err = bad_attr(sp);
- let mut add_label = true;
if let Some(item) = li.meta_item() {
if let ast::MetaItemKind::NameValue(_) = item.kind {
if item.path == sym::reason {
- err.span_label(sp, "reason in lint attribute must come last");
- add_label = false;
+ sess.emit_err(MalformedAttribute {
+ span: sp,
+ sub: MalformedAttributeSub::ReasonMustComeLast(sp),
+ });
+ continue;
}
}
}
- if add_label {
- err.span_label(sp, "bad attribute argument");
- }
- err.emit();
+ sess.emit_err(MalformedAttribute {
+ span: sp,
+ sub: MalformedAttributeSub::BadAttributeArgument(sp),
+ });
continue;
}
};
@@ -419,8 +440,10 @@ impl<'s> LintLevelsBuilder<'s> {
sp,
reason,
);
- for id in ids {
- self.insert_spec(*id, (level, src));
+ for &id in ids {
+ if self.check_gated_lint(id, attr.span) {
+ self.insert_spec(id, (level, src));
+ }
}
if let Level::Expect(expect_id) = level {
self.lint_expectations.push((
@@ -485,22 +508,12 @@ impl<'s> LintLevelsBuilder<'s> {
}
&CheckLintNameResult::NoTool => {
- let mut err = struct_span_err!(
- sess,
- tool_ident.map_or(DUMMY_SP, |ident| ident.span),
- E0710,
- "unknown tool name `{}` found in scoped lint: `{}::{}`",
- tool_name.unwrap(),
- tool_name.unwrap(),
- pprust::path_to_string(&meta_item.path),
- );
- if sess.is_nightly_build() {
- err.help(&format!(
- "add `#![register_tool({})]` to the crate root",
- tool_name.unwrap()
- ));
- }
- err.emit();
+ sess.emit_err(UnknownToolInScopedLint {
+ span: tool_ident.map(|ident| ident.span),
+ tool_name: tool_name.unwrap(),
+ lint_name: pprust::path_to_string(&meta_item.path),
+ is_nightly_build: sess.is_nightly_build().then_some(()),
+ });
continue;
}
@@ -766,20 +779,21 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
})
}
+ fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+ self.with_lint_attrs(field.hir_id, |builder| {
+ intravisit::walk_expr_field(builder, field);
+ })
+ }
+
fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
self.with_lint_attrs(s.hir_id, |builder| {
intravisit::walk_field_def(builder, s);
})
}
- fn visit_variant(
- &mut self,
- v: &'tcx hir::Variant<'tcx>,
- g: &'tcx hir::Generics<'tcx>,
- item_id: hir::HirId,
- ) {
+ fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
self.with_lint_attrs(v.id, |builder| {
- intravisit::walk_variant(builder, v, g, item_id);
+ intravisit::walk_variant(builder, v);
})
}
@@ -806,6 +820,18 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
intravisit::walk_impl_item(builder, impl_item);
});
}
+
+ fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+ self.with_lint_attrs(field.hir_id, |builder| {
+ intravisit::walk_pat_field(builder, field);
+ })
+ }
+
+ fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+ self.with_lint_attrs(p.hir_id, |builder| {
+ intravisit::walk_generic_param(builder, p);
+ });
+ }
}
pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 389a0b5d1..752a751f6 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -34,7 +34,7 @@
#![feature(iter_intersperse)]
#![feature(iter_order_by)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
#![recursion_limit = "256"]
@@ -42,16 +42,20 @@
extern crate rustc_middle;
#[macro_use]
extern crate rustc_session;
+#[macro_use]
+extern crate tracing;
mod array_into_iter;
pub mod builtin;
mod context;
mod early;
mod enum_intrinsics_non_enums;
+mod errors;
mod expect;
pub mod hidden_unicode_codepoints;
mod internal;
mod late;
+mod let_underscore;
mod levels;
mod methods;
mod non_ascii_idents;
@@ -83,6 +87,7 @@ use builtin::*;
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
use hidden_unicode_codepoints::*;
use internal::*;
+use let_underscore::*;
use methods::*;
use non_ascii_idents::*;
use non_fmt_panic::NonPanicFmt;
@@ -130,6 +135,7 @@ macro_rules! early_lint_passes {
UnusedBraces: UnusedBraces,
UnusedImportBraces: UnusedImportBraces,
UnsafeCode: UnsafeCode,
+ SpecialModuleName: SpecialModuleName,
AnonymousParameters: AnonymousParameters,
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
NonCamelCaseTypes: NonCamelCaseTypes,
@@ -140,6 +146,7 @@ macro_rules! early_lint_passes {
IncompleteFeatures: IncompleteFeatures,
RedundantSemicolons: RedundantSemicolons,
UnusedDocComment: UnusedDocComment,
+ UnexpectedCfgs: UnexpectedCfgs,
]
);
};
@@ -185,6 +192,7 @@ macro_rules! late_lint_mod_passes {
VariantSizeDifferences: VariantSizeDifferences,
BoxPointers: BoxPointers,
PathStatements: PathStatements,
+ LetUnderscore: LetUnderscore,
// Depends on referenced function signatures in expressions
UnusedResults: UnusedResults,
NonUpperCaseGlobals: NonUpperCaseGlobals,
@@ -252,26 +260,41 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
)
}
- macro_rules! register_pass {
+ macro_rules! register_early_pass {
($method:ident, $ty:ident, $constructor:expr) => {
store.register_lints(&$ty::get_lints());
store.$method(|| Box::new($constructor));
};
}
- macro_rules! register_passes {
+ macro_rules! register_late_pass {
+ ($method:ident, $ty:ident, $constructor:expr) => {
+ store.register_lints(&$ty::get_lints());
+ store.$method(|_| Box::new($constructor));
+ };
+ }
+
+ macro_rules! register_early_passes {
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
$(
- register_pass!($method, $passes, $constructor);
+ register_early_pass!($method, $passes, $constructor);
+ )*
+ )
+ }
+
+ macro_rules! register_late_passes {
+ ($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
+ $(
+ register_late_pass!($method, $passes, $constructor);
)*
)
}
if no_interleave_lints {
- pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
- early_lint_passes!(register_passes, register_early_pass);
- late_lint_passes!(register_passes, register_late_pass);
- late_lint_mod_passes!(register_passes, register_late_mod_pass);
+ pre_expansion_lint_passes!(register_early_passes, register_pre_expansion_pass);
+ early_lint_passes!(register_early_passes, register_early_pass);
+ late_lint_passes!(register_late_passes, register_late_pass);
+ late_lint_mod_passes!(register_late_passes, register_late_mod_pass);
} else {
store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
@@ -311,6 +334,8 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
REDUNDANT_SEMICOLONS
);
+ add_lint_group!("let_underscore", LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK);
+
add_lint_group!(
"rust_2018_idioms",
BARE_TRAIT_OBJECTS,
@@ -500,19 +525,19 @@ fn register_internals(store: &mut LintStore) {
store.register_lints(&LintPassImpl::get_lints());
store.register_early_pass(|| Box::new(LintPassImpl));
store.register_lints(&DefaultHashTypes::get_lints());
- store.register_late_pass(|| Box::new(DefaultHashTypes));
+ store.register_late_pass(|_| Box::new(DefaultHashTypes));
store.register_lints(&QueryStability::get_lints());
- store.register_late_pass(|| Box::new(QueryStability));
+ store.register_late_pass(|_| Box::new(QueryStability));
store.register_lints(&ExistingDocKeyword::get_lints());
- store.register_late_pass(|| Box::new(ExistingDocKeyword));
+ store.register_late_pass(|_| Box::new(ExistingDocKeyword));
store.register_lints(&TyTyKind::get_lints());
- store.register_late_pass(|| Box::new(TyTyKind));
+ store.register_late_pass(|_| Box::new(TyTyKind));
store.register_lints(&Diagnostics::get_lints());
- store.register_late_pass(|| Box::new(Diagnostics));
+ store.register_late_pass(|_| Box::new(Diagnostics));
store.register_lints(&BadOptAccess::get_lints());
- store.register_late_pass(|| Box::new(BadOptAccess));
+ store.register_late_pass(|_| Box::new(BadOptAccess));
store.register_lints(&PassByValue::get_lints());
- store.register_late_pass(|| Box::new(PassByValue));
+ store.register_late_pass(|_| Box::new(PassByValue));
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
// these lints will trigger all of the time - change this once migration to diagnostic structs
diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs
index ff5a01749..5f7f03480 100644
--- a/compiler/rustc_lint/src/methods.rs
+++ b/compiler/rustc_lint/src/methods.rs
@@ -44,9 +44,13 @@ fn in_macro(span: Span) -> bool {
fn first_method_call<'tcx>(
expr: &'tcx Expr<'tcx>,
-) -> Option<(&'tcx PathSegment<'tcx>, &'tcx [Expr<'tcx>])> {
- if let ExprKind::MethodCall(path, args, _) = &expr.kind {
- if args.iter().any(|e| e.span.from_expansion()) { None } else { Some((path, *args)) }
+) -> Option<(&'tcx PathSegment<'tcx>, &'tcx Expr<'tcx>)> {
+ if let ExprKind::MethodCall(path, receiver, args, ..) = &expr.kind {
+ if args.iter().any(|e| e.span.from_expansion()) || receiver.span.from_expansion() {
+ None
+ } else {
+ Some((path, *receiver))
+ }
} else {
None
}
@@ -59,15 +63,13 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr {
}
match first_method_call(expr) {
- Some((path, args)) if path.ident.name == sym::as_ptr => {
- let unwrap_arg = &args[0];
+ Some((path, unwrap_arg)) if path.ident.name == sym::as_ptr => {
let as_ptr_span = path.ident.span;
match first_method_call(unwrap_arg) {
- Some((path, args))
+ Some((path, receiver))
if path.ident.name == sym::unwrap || path.ident.name == sym::expect =>
{
- let source_arg = &args[0];
- lint_cstring_as_ptr(cx, as_ptr_span, source_arg, unwrap_arg);
+ lint_cstring_as_ptr(cx, as_ptr_span, receiver, unwrap_arg);
}
_ => return,
}
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 8d04d68bf..768ad8483 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -327,13 +327,7 @@ impl NonSnakeCase {
}
impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
- fn check_mod(
- &mut self,
- cx: &LateContext<'_>,
- _: &'tcx hir::Mod<'tcx>,
- _: Span,
- id: hir::HirId,
- ) {
+ fn check_mod(&mut self, cx: &LateContext<'_>, _: &'tcx hir::Mod<'tcx>, id: hir::HirId) {
if id != hir::CRATE_HIR_ID {
return;
}
@@ -437,19 +431,14 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
if let PatKind::Binding(_, hid, ident, _) = p.kind {
- if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
+ if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
{
- if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind {
- if field_pats
- .iter()
- .any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id)
- {
- // Only check if a new name has been introduced, to avoid warning
- // on both the struct definition and this pattern.
- self.check_snake_case(cx, "variable", &ident);
- }
- return;
+ if !field.is_shorthand {
+ // Only check if a new name has been introduced, to avoid warning
+ // on both the struct definition and this pattern.
+ self.check_snake_case(cx, "variable", &ident);
}
+ return;
}
self.check_snake_case(cx, "variable", &ident);
}
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
index 11a752ff0..d1449496d 100644
--- a/compiler/rustc_lint/src/noop_method_call.rs
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -41,7 +41,7 @@ declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]);
impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// We only care about method calls.
- let ExprKind::MethodCall(call, elements, _) = &expr.kind else {
+ let ExprKind::MethodCall(call, receiver, ..) = &expr.kind else {
return
};
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
@@ -81,7 +81,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
) {
return;
}
- let receiver = &elements[0];
let receiver_ty = cx.typeck_results().expr_ty(receiver);
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
if receiver_ty != expr_ty {
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index cb7bd407e..1c6a057d1 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -16,7 +16,7 @@ macro_rules! late_lint_methods {
fn check_body_post(a: &$hir hir::Body<$hir>);
fn check_crate();
fn check_crate_post();
- fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId);
+ fn check_mod(a: &$hir hir::Mod<$hir>, b: hir::HirId);
fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>);
fn check_item(a: &$hir hir::Item<$hir>);
fn check_item_post(a: &$hir hir::Item<$hir>);
@@ -31,7 +31,7 @@ macro_rules! late_lint_methods {
fn check_ty(a: &$hir hir::Ty<$hir>);
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
fn check_generics(a: &$hir hir::Generics<$hir>);
- fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>, b: hir::TraitBoundModifier);
+ fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>);
fn check_fn(
a: rustc_hir::intravisit::FnKind<$hir>,
b: &$hir hir::FnDecl<$hir>,
@@ -156,14 +156,13 @@ macro_rules! early_lint_methods {
fn check_generic_arg(a: &ast::GenericArg);
fn check_generic_param(a: &ast::GenericParam);
fn check_generics(a: &ast::Generics);
- fn check_poly_trait_ref(a: &ast::PolyTraitRef,
- b: &ast::TraitBoundModifier);
+ fn check_poly_trait_ref(a: &ast::PolyTraitRef);
fn check_fn(a: rustc_ast::visit::FnKind<'_>, c: Span, d_: ast::NodeId);
fn check_trait_item(a: &ast::AssocItem);
fn check_impl_item(a: &ast::AssocItem);
fn check_variant(a: &ast::Variant);
fn check_attribute(a: &ast::Attribute);
- fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId);
+ fn check_mac_def(a: &ast::MacroDef);
fn check_mac(a: &ast::MacCall);
/// Called when entering a syntax node that can have lint attributes such
@@ -244,6 +243,5 @@ macro_rules! declare_combined_early_lint_pass {
}
/// A lint pass boxed up as a trait object.
-pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>;
-pub type LateLintPassObject =
- Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + sync::Sync + 'static>;
+pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + 'static>;
+pub type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + sync::Send + 'tcx>;
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 5c07afeb7..4fb6d65a6 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -19,7 +19,6 @@ use rustc_target::spec::abi::Abi as SpecAbi;
use std::cmp;
use std::iter;
use std::ops::ControlFlow;
-use tracing::debug;
declare_lint! {
/// The `unused_comparisons` lint detects comparisons made useless by
@@ -125,45 +124,51 @@ fn lint_overflowing_range_endpoint<'tcx>(
lit_val: u128,
max: u128,
expr: &'tcx hir::Expr<'tcx>,
- parent_expr: &'tcx hir::Expr<'tcx>,
ty: &str,
) -> bool {
// We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`.
+ let par_id = cx.tcx.hir().get_parent_node(expr.hir_id);
+ let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
+ let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id);
+ let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false };
+ if !is_range_literal(struct_expr) {
+ return false;
+ };
+ let ExprKind::Struct(_, eps, _) = &struct_expr.kind else { return false };
+ if eps.len() != 2 {
+ return false;
+ }
+
let mut overwritten = false;
- if let ExprKind::Struct(_, eps, _) = &parent_expr.kind {
- if eps.len() != 2 {
- return false;
- }
- // We can suggest using an inclusive range
- // (`..=`) instead only if it is the `end` that is
- // overflowing and only by 1.
- if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
- cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| {
- let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
- err.set_arg("ty", ty);
- if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
- use ast::{LitIntType, LitKind};
- // We need to preserve the literal's suffix,
- // as it may determine typing information.
- let suffix = match lit.node {
- LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
- LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
- LitKind::Int(_, LitIntType::Unsuffixed) => "",
- _ => bug!(),
- };
- let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
- err.span_suggestion(
- parent_expr.span,
- fluent::lint::suggestion,
- suggestion,
- Applicability::MachineApplicable,
- );
- err.emit();
- overwritten = true;
- }
- });
- }
+ // We can suggest using an inclusive range
+ // (`..=`) instead only if it is the `end` that is
+ // overflowing and only by 1.
+ if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
+ cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| {
+ let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
+ err.set_arg("ty", ty);
+ if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
+ use ast::{LitIntType, LitKind};
+ // We need to preserve the literal's suffix,
+ // as it may determine typing information.
+ let suffix = match lit.node {
+ LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
+ LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
+ LitKind::Int(_, LitIntType::Unsuffixed) => "",
+ _ => bug!(),
+ };
+ let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
+ err.span_suggestion(
+ struct_expr.span,
+ fluent::lint::suggestion,
+ suggestion,
+ Applicability::MachineApplicable,
+ );
+ err.emit();
+ overwritten = true;
+ }
+ });
}
overwritten
}
@@ -339,16 +344,9 @@ fn lint_int_literal<'tcx>(
return;
}
- let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
- if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
- if let hir::ExprKind::Struct(..) = par_e.kind {
- if is_range_literal(par_e)
- && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
- {
- // The overflowing literal lint was overridden.
- return;
- }
- }
+ if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
+ // The overflowing literal lint was overridden.
+ return;
}
cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
@@ -408,16 +406,13 @@ fn lint_uint_literal<'tcx>(
return;
}
}
- hir::ExprKind::Struct(..) if is_range_literal(par_e) => {
- let t = t.name_str();
- if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
- // The overflowing literal lint was overridden.
- return;
- }
- }
_ => {}
}
}
+ if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
+ // The overflowing literal lint was overridden.
+ return;
+ }
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
report_bin_hex_error(
cx,
@@ -724,7 +719,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
Some(match *ty.kind() {
ty::Adt(field_def, field_substs) => {
let inner_field_ty = {
- let first_non_zst_ty = field_def
+ let mut first_non_zst_ty = field_def
.variants()
.iter()
.filter_map(|v| transparent_newtype_field(cx.tcx, v));
@@ -734,7 +729,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
"Wrong number of fields for transparent type"
);
first_non_zst_ty
- .last()
+ .next_back()
.expect("No non-zst fields in transparent type.")
.ty(tcx, field_substs)
};
@@ -1463,7 +1458,7 @@ impl InvalidAtomicOrdering {
sym::AtomicI64,
sym::AtomicI128,
];
- if let ExprKind::MethodCall(ref method_path, args, _) = &expr.kind
+ if let ExprKind::MethodCall(ref method_path, _, args, _) = &expr.kind
&& recognized_names.contains(&method_path.ident.name)
&& let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
&& let Some(impl_did) = cx.tcx.impl_of_method(m_def_id)
@@ -1499,8 +1494,8 @@ impl InvalidAtomicOrdering {
fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) {
if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store])
&& let Some((ordering_arg, invalid_ordering)) = match method {
- sym::load => Some((&args[1], sym::Release)),
- sym::store => Some((&args[2], sym::Acquire)),
+ sym::load => Some((&args[0], sym::Release)),
+ sym::store => Some((&args[1], sym::Acquire)),
_ => None,
}
&& let Some(ordering) = Self::match_ordering(cx, ordering_arg)
@@ -1541,8 +1536,8 @@ impl InvalidAtomicOrdering {
else {return };
let fail_order_arg = match method {
- sym::fetch_update => &args[2],
- sym::compare_exchange | sym::compare_exchange_weak => &args[4],
+ sym::fetch_update => &args[1],
+ sym::compare_exchange | sym::compare_exchange_weak => &args[3],
_ => return,
};
@@ -1550,7 +1545,7 @@ impl InvalidAtomicOrdering {
if matches!(fail_ordering, sym::Release | sym::AcqRel) {
#[derive(LintDiagnostic)]
- #[lint(lint::atomic_ordering_invalid)]
+ #[diag(lint::atomic_ordering_invalid)]
#[help]
struct InvalidAtomicOrderingDiag {
method: Symbol,
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index b6cf18291..8c9ceb711 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -11,7 +11,7 @@ use rustc_middle::ty::adjustment;
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::Symbol;
use rustc_span::symbol::{kw, sym};
-use rustc_span::{BytePos, Span, DUMMY_SP};
+use rustc_span::{BytePos, Span};
declare_lint! {
/// The `unused_must_use` lint detects unused result of a type flagged as
@@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
}
has_emitted
}
- ty::Dynamic(binder, _) => {
+ ty::Dynamic(binder, _, _) => {
let mut has_emitted = false;
for predicate in binder.iter() {
if let ty::ExistentialPredicate::Trait(ref trait_ref) =
@@ -268,7 +268,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
},
ty::Closure(..) => {
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
- // FIXME(davidtwco): this isn't properly translatable becauses of the
+ // FIXME(davidtwco): this isn't properly translatable because of the
// pre/post strings
lint.build(fluent::lint::unused_closure)
.set_arg("count", plural_len)
@@ -281,7 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
}
ty::Generator(..) => {
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
- // FIXME(davidtwco): this isn't properly translatable becauses of the
+ // FIXME(davidtwco): this isn't properly translatable because of the
// pre/post strings
lint.build(fluent::lint::unused_generator)
.set_arg("count", plural_len)
@@ -310,7 +310,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
) -> bool {
if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) {
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
- // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
+ // FIXME(davidtwco): this isn't properly translatable because of the pre/post
// strings
let mut err = lint.build(fluent::lint::unused_def);
err.set_arg("pre", descr_pre_path);
@@ -504,23 +504,23 @@ trait UnusedDelimLint {
ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => {
let start = block.stmts[0].span;
let end = block.stmts[block.stmts.len() - 1].span;
- if value.span.from_expansion() || start.from_expansion() || end.from_expansion() {
- (
- value.span.with_hi(value.span.lo() + BytePos(1)),
- value.span.with_lo(value.span.hi() - BytePos(1)),
- )
+ if let Some(start) = start.find_ancestor_inside(value.span)
+ && let Some(end) = end.find_ancestor_inside(value.span)
+ {
+ Some((
+ value.span.with_hi(start.lo()),
+ value.span.with_lo(end.hi()),
+ ))
} else {
- (value.span.with_hi(start.lo()), value.span.with_lo(end.hi()))
+ None
}
}
ast::ExprKind::Paren(ref expr) => {
- if value.span.from_expansion() || expr.span.from_expansion() {
- (
- value.span.with_hi(value.span.lo() + BytePos(1)),
- value.span.with_lo(value.span.hi() - BytePos(1)),
- )
+ let expr_span = expr.span.find_ancestor_inside(value.span);
+ if let Some(expr_span) = expr_span {
+ Some((value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi())))
} else {
- (value.span.with_hi(expr.span.lo()), value.span.with_lo(expr.span.hi()))
+ None
}
}
_ => return,
@@ -529,36 +529,38 @@ trait UnusedDelimLint {
left_pos.map_or(false, |s| s >= value.span.lo()),
right_pos.map_or(false, |s| s <= value.span.hi()),
);
- self.emit_unused_delims(cx, spans, ctx.into(), keep_space);
+ self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space);
}
fn emit_unused_delims(
&self,
cx: &EarlyContext<'_>,
- spans: (Span, Span),
+ value_span: Span,
+ spans: Option<(Span, Span)>,
msg: &str,
keep_space: (bool, bool),
) {
- // FIXME(flip1995): Quick and dirty fix for #70814. This should be fixed in rustdoc
- // properly.
- if spans.0 == DUMMY_SP || spans.1 == DUMMY_SP {
- return;
- }
-
- cx.struct_span_lint(self.lint(), MultiSpan::from(vec![spans.0, spans.1]), |lint| {
- let replacement = vec![
- (spans.0, if keep_space.0 { " ".into() } else { "".into() }),
- (spans.1, if keep_space.1 { " ".into() } else { "".into() }),
- ];
- lint.build(fluent::lint::unused_delim)
- .set_arg("delim", Self::DELIM_STR)
- .set_arg("item", msg)
- .multipart_suggestion(
+ let primary_span = if let Some((lo, hi)) = spans {
+ MultiSpan::from(vec![lo, hi])
+ } else {
+ MultiSpan::from(value_span)
+ };
+ cx.struct_span_lint(self.lint(), primary_span, |lint| {
+ let mut db = lint.build(fluent::lint::unused_delim);
+ db.set_arg("delim", Self::DELIM_STR);
+ db.set_arg("item", msg);
+ if let Some((lo, hi)) = spans {
+ let replacement = vec![
+ (lo, if keep_space.0 { " ".into() } else { "".into() }),
+ (hi, if keep_space.1 { " ".into() } else { "".into() }),
+ ];
+ db.multipart_suggestion(
fluent::lint::suggestion,
replacement,
Applicability::MachineApplicable,
- )
- .emit();
+ );
+ }
+ db.emit();
});
}
@@ -750,7 +752,7 @@ impl UnusedParens {
avoid_or: bool,
avoid_mut: bool,
) {
- use ast::{BindingMode, Mutability, PatKind};
+ use ast::{BindingAnnotation, PatKind};
if let PatKind::Paren(inner) = &value.kind {
match inner.kind {
@@ -762,19 +764,18 @@ impl UnusedParens {
// Avoid `p0 | .. | pn` if we should.
PatKind::Or(..) if avoid_or => return,
// Avoid `mut x` and `mut x @ p` if we should:
- PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..) if avoid_mut => return,
+ PatKind::Ident(BindingAnnotation::MUT, ..) if avoid_mut => {
+ return;
+ }
// Otherwise proceed with linting.
_ => {}
}
- let spans = if value.span.from_expansion() || inner.span.from_expansion() {
- (
- value.span.with_hi(value.span.lo() + BytePos(1)),
- value.span.with_lo(value.span.hi() - BytePos(1)),
- )
+ let spans = if let Some(inner) = inner.span.find_ancestor_inside(value.span) {
+ Some((value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())))
} else {
- (value.span.with_hi(inner.span.lo()), value.span.with_lo(inner.span.hi()))
+ None
};
- self.emit_unused_delims(cx, spans, "pattern", (false, false));
+ self.emit_unused_delims(cx, value.span, spans, "pattern", (false, false));
}
}
}
@@ -879,15 +880,12 @@ impl EarlyLintPass for UnusedParens {
);
}
_ => {
- let spans = if ty.span.from_expansion() || r.span.from_expansion() {
- (
- ty.span.with_hi(ty.span.lo() + BytePos(1)),
- ty.span.with_lo(ty.span.hi() - BytePos(1)),
- )
+ let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) {
+ Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())))
} else {
- (ty.span.with_hi(r.span.lo()), ty.span.with_lo(r.span.hi()))
+ None
};
- self.emit_unused_delims(cx, spans, "type", (false, false));
+ self.emit_unused_delims(cx, ty.span, spans, "type", (false, false));
}
}
}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index f00165cd3..e5dfda24d 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3094,7 +3094,7 @@ declare_lint! {
///
/// ### Example
///
- /// ```rust
+ /// ```rust,compile_fail
/// #![cfg_attr(debug_assertions, crate_type = "lib")]
/// ```
///
@@ -3114,7 +3114,7 @@ declare_lint! {
/// rustc instead of `#![cfg_attr(..., crate_type = "...")]` and
/// `--crate-name` instead of `#![cfg_attr(..., crate_name = "...")]`.
pub DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
- Warn,
+ Deny,
"detects usage of `#![cfg_attr(..., crate_type/crate_name = \"...\")]`",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #91632 <https://github.com/rust-lang/rust/issues/91632>",
@@ -3206,12 +3206,62 @@ declare_lint! {
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
Warn,
- "tranparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields",
+ "transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #78586 <https://github.com/rust-lang/rust/issues/78586>",
};
}
+declare_lint! {
+ /// The `unstable_syntax_pre_expansion` lint detects the use of unstable
+ /// syntax that is discarded during attribute expansion.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// #[cfg(FALSE)]
+ /// macro foo() {}
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// The input to active attributes such as `#[cfg]` or procedural macro
+ /// attributes is required to be valid syntax. Previously, the compiler only
+ /// gated the use of unstable syntax features after resolving `#[cfg]` gates
+ /// and expanding procedural macros.
+ ///
+ /// To avoid relying on unstable syntax, move the use of unstable syntax
+ /// into a position where the compiler does not parse the syntax, such as a
+ /// functionlike macro.
+ ///
+ /// ```rust
+ /// # #![deny(unstable_syntax_pre_expansion)]
+ ///
+ /// macro_rules! identity {
+ /// ( $($tokens:tt)* ) => { $($tokens)* }
+ /// }
+ ///
+ /// #[cfg(FALSE)]
+ /// identity! {
+ /// macro foo() {}
+ /// }
+ /// ```
+ ///
+ /// This is a [future-incompatible] lint to transition this
+ /// to a hard error in the future. See [issue #65860] for more details.
+ ///
+ /// [issue #65860]: https://github.com/rust-lang/rust/issues/65860
+ /// [future-incompatible]: ../index.md#future-incompatible-lints
+ pub UNSTABLE_SYNTAX_PRE_EXPANSION,
+ Warn,
+ "unstable syntax can change at any point in the future, causing a hard error!",
+ @future_incompatible = FutureIncompatibleInfo {
+ reference: "issue #65860 <https://github.com/rust-lang/rust/issues/65860>",
+ };
+}
+
declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
@@ -3280,6 +3330,7 @@ declare_lint_pass! {
POINTER_STRUCTURAL_MATCH,
NONTRIVIAL_STRUCTURAL_MATCH,
SOFT_UNSTABLE,
+ UNSTABLE_SYNTAX_PRE_EXPANSION,
INLINE_NO_SANITIZE,
BAD_ASM_STYLE,
ASM_SUB_REGISTER,
@@ -3314,7 +3365,6 @@ declare_lint_pass! {
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
DUPLICATE_MACRO_ATTRIBUTES,
SUSPICIOUS_AUTO_TRAIT_IMPLS,
- UNEXPECTED_CFGS,
DEPRECATED_WHERE_CLAUSE_LOCATION,
TEST_UNSTABLE_LINT,
FFI_UNWIND_CALLS,
@@ -3357,7 +3407,7 @@ declare_lint! {
///
/// ### Example of drop reorder
///
- /// ```rust,compile_fail
+ /// ```rust,edition2018,compile_fail
/// #![deny(rust_2021_incompatible_closure_captures)]
/// # #![allow(unused)]
///
@@ -3393,7 +3443,7 @@ declare_lint! {
///
/// ### Example of auto-trait
///
- /// ```rust,compile_fail
+ /// ```rust,edition2018,compile_fail
/// #![deny(rust_2021_incompatible_closure_captures)]
/// use std::thread;
///
@@ -3938,8 +3988,6 @@ declare_lint! {
/// ### Example
///
/// ```rust
- /// #![feature(generic_associated_types)]
- ///
/// trait Trait {
/// type Assoc<'a> where Self: 'a;
/// }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 6acbe97a7..11b2d057a 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,4 +1,6 @@
#![feature(min_specialization)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
@@ -7,7 +9,7 @@ pub use self::Level::*;
use rustc_ast::node_id::{NodeId, NodeMap};
use rustc_ast::{AttrId, Attribute};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_error_messages::MultiSpan;
+use rustc_error_messages::{DiagnosticMessage, MultiSpan};
use rustc_hir::HashStableContext;
use rustc_hir::HirId;
use rustc_span::edition::Edition;
@@ -39,7 +41,8 @@ macro_rules! pluralize {
/// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
/// to determine whether it should be automatically applied or if the user should be consulted
/// before applying the suggestion.
-#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable, Serialize, Deserialize)]
+#[derive(Copy, Clone, Debug, Hash, Encodable, Decodable, Serialize, Deserialize)]
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub enum Applicability {
/// The suggestion is definitely what the user intended, or maintains the exact meaning of the code.
/// This suggestion should be automatically applied.
@@ -489,7 +492,7 @@ pub struct BufferedEarlyLint {
pub span: MultiSpan,
/// The lint message.
- pub msg: String,
+ pub msg: DiagnosticMessage,
/// The `NodeId` of the AST node that generated the lint.
pub node_id: NodeId,
@@ -518,11 +521,11 @@ impl LintBuffer {
lint: &'static Lint,
node_id: NodeId,
span: MultiSpan,
- msg: &str,
+ msg: impl Into<DiagnosticMessage>,
diagnostic: BuiltinLintDiagnostics,
) {
let lint_id = LintId::of(lint);
- let msg = msg.to_string();
+ let msg = msg.into();
self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic });
}
@@ -535,7 +538,7 @@ impl LintBuffer {
lint: &'static Lint,
id: NodeId,
sp: impl Into<MultiSpan>,
- msg: &str,
+ msg: impl Into<DiagnosticMessage>,
) {
self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
}
@@ -545,7 +548,7 @@ impl LintBuffer {
lint: &'static Lint,
id: NodeId,
sp: impl Into<MultiSpan>,
- msg: &str,
+ msg: impl Into<DiagnosticMessage>,
diagnostic: BuiltinLintDiagnostics,
) {
self.add_lint(lint, id, sp.into(), msg, diagnostic)
@@ -655,18 +658,21 @@ macro_rules! declare_lint {
macro_rules! declare_tool_lint {
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
+ $(, @feature_gate = $gate:expr;)?
) => (
- $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false}
+ $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false $(, @feature_gate = $gate;)?}
);
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
report_in_external_macro: $rep:expr
+ $(, @feature_gate = $gate:expr;)?
) => (
- $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep}
+ $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep $(, @feature_gate = $gate;)?}
);
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
$external:expr
+ $(, @feature_gate = $gate:expr;)?
) => (
$(#[$attr])*
$vis static $NAME: &$crate::Lint = &$crate::Lint {
@@ -677,8 +683,9 @@ macro_rules! declare_tool_lint {
report_in_external_macro: $external,
future_incompatible: None,
is_plugin: true,
- feature_gate: None,
+ $(feature_gate: Some($gate),)?
crate_level_only: false,
+ ..$crate::Lint::default_fields_for_macro()
};
);
}
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 62ef5804d..28e092c1e 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -242,6 +242,13 @@ fn main() {
println!("cargo:rustc-link-lib=uuid");
} else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") {
println!("cargo:rustc-link-lib=z");
+ } else if target.starts_with("arm")
+ || target.starts_with("mips-")
+ || target.starts_with("mipsel-")
+ || target.starts_with("powerpc-")
+ {
+ // 32-bit targets need to link libatomic.
+ println!("cargo:rustc-link-lib=atomic");
}
cmd.args(&components);
@@ -335,10 +342,10 @@ fn main() {
};
// RISC-V GCC erroneously requires libatomic for sub-word
- // atomic operations. FreeBSD uses Clang as its system
+ // atomic operations. Some BSD uses Clang as its system
// compiler and provides no libatomic in its base system so
// does not want this.
- if !target.contains("freebsd") && target.starts_with("riscv") {
+ if target.starts_with("riscv") && !target.contains("freebsd") && !target.contains("openbsd") {
println!("cargo:rustc-link-lib=atomic");
}
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index 97541e615..448a1f62f 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -154,19 +154,6 @@ LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
return Name.data();
}
-extern "C" const char *LLVMRustArchiveChildData(LLVMRustArchiveChildRef Child,
- size_t *Size) {
- StringRef Buf;
- Expected<StringRef> BufOrErr = Child->getBuffer();
- if (!BufOrErr) {
- LLVMRustSetLastError(toString(BufOrErr.takeError()).c_str());
- return nullptr;
- }
- Buf = BufOrErr.get();
- *Size = Buf.size();
- return Buf.data();
-}
-
extern "C" LLVMRustArchiveMemberRef
LLVMRustArchiveMemberNew(char *Filename, char *Name,
LLVMRustArchiveChildRef Child) {
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 154f554d6..7da6ab713 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -24,17 +24,10 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
const char* const Filenames[],
size_t FilenamesLen,
RustStringRef BufferOut) {
-#if LLVM_VERSION_GE(13,0)
SmallVector<std::string,32> FilenameRefs;
for (size_t i = 0; i < FilenamesLen; i++) {
FilenameRefs.push_back(std::string(Filenames[i]));
}
-#else
- SmallVector<StringRef,32> FilenameRefs;
- for (size_t i = 0; i < FilenamesLen; i++) {
- FilenameRefs.push_back(StringRef(Filenames[i]));
- }
-#endif
auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter(
makeArrayRef(FilenameRefs));
RawRustStringOstream OS(BufferOut);
@@ -109,9 +102,5 @@ extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
}
extern "C" uint32_t LLVMRustCoverageMappingVersion() {
-#if LLVM_VERSION_GE(13, 0)
return coverage::CovMapVersion::Version6;
-#else
- return coverage::CovMapVersion::Version5;
-#endif
}
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 0a6bd4999..24e188260 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -31,6 +31,9 @@
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
+#if LLVM_VERSION_GE(15, 0)
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
+#endif
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/LTO/LTO.h"
@@ -131,7 +134,12 @@ extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool
const bool CompileKernel = false;
return wrap(createMemorySanitizerLegacyPassPass(
- MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
+#if LLVM_VERSION_GE(14, 0)
+ MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, /*EagerChecks=*/true}
+#else
+ MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}
+#endif
+ ));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
@@ -822,7 +830,8 @@ LLVMRustOptimizeWithNewPassManager(
bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
LLVMRustSanitizerOptions *SanitizerOptions,
const char *PGOGenPath, const char *PGOUsePath,
- bool InstrumentCoverage, bool InstrumentGCOV,
+ bool InstrumentCoverage, const char *InstrProfileOutput,
+ bool InstrumentGCOV,
const char *PGOSampleUsePath, bool DebugInfoForProfiling,
void* LlvmSelfProfiler,
LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
@@ -869,19 +878,11 @@ LLVMRustOptimizeWithNewPassManager(
PGOOptions::NoCSAction, DebugInfoForProfiling);
}
-#if LLVM_VERSION_GE(13, 0)
PassBuilder PB(TM, PTO, PGOOpt, &PIC);
LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
CGSCCAnalysisManager CGAM;
ModuleAnalysisManager MAM;
-#else
- PassBuilder PB(DebugPassManager, TM, PTO, PGOOpt, &PIC);
- LoopAnalysisManager LAM(DebugPassManager);
- FunctionAnalysisManager FAM(DebugPassManager);
- CGSCCAnalysisManager CGAM(DebugPassManager);
- ModuleAnalysisManager MAM(DebugPassManager);
-#endif
FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
@@ -922,8 +923,11 @@ LLVMRustOptimizeWithNewPassManager(
if (InstrumentCoverage) {
PipelineStartEPCallbacks.push_back(
- [](ModulePassManager &MPM, OptimizationLevel Level) {
+ [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
InstrProfOptions Options;
+ if (InstrProfileOutput) {
+ Options.InstrProfileOutput = InstrProfileOutput;
+ }
MPM.addPass(InstrProfiling(Options, false));
}
);
@@ -931,18 +935,28 @@ LLVMRustOptimizeWithNewPassManager(
if (SanitizerOptions) {
if (SanitizerOptions->SanitizeMemory) {
+#if LLVM_VERSION_GE(14, 0)
+ MemorySanitizerOptions Options(
+ SanitizerOptions->SanitizeMemoryTrackOrigins,
+ SanitizerOptions->SanitizeMemoryRecover,
+ /*CompileKernel=*/false,
+ /*EagerChecks=*/true);
+#else
MemorySanitizerOptions Options(
SanitizerOptions->SanitizeMemoryTrackOrigins,
SanitizerOptions->SanitizeMemoryRecover,
/*CompileKernel=*/false);
+#endif
OptimizerLastEPCallbacks.push_back(
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
-#if LLVM_VERSION_GE(14, 0)
+#if LLVM_VERSION_GE(14, 0) && LLVM_VERSION_LT(16, 0)
MPM.addPass(ModuleMemorySanitizerPass(Options));
#else
MPM.addPass(MemorySanitizerPass(Options));
#endif
+#if LLVM_VERSION_LT(16, 0)
MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
+#endif
}
);
}
@@ -973,8 +987,12 @@ LLVMRustOptimizeWithNewPassManager(
/*UseAfterScope=*/true,
AsanDetectStackUseAfterReturnMode::Runtime,
};
+#if LLVM_VERSION_LT(16, 0)
MPM.addPass(ModuleAddressSanitizerPass(opts));
#else
+ MPM.addPass(AddressSanitizerPass(opts));
+#endif
+#else
MPM.addPass(ModuleAddressSanitizerPass(
/*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
@@ -1015,11 +1033,7 @@ LLVMRustOptimizeWithNewPassManager(
}
}
-#if LLVM_VERSION_GE(13, 0)
ModulePassManager MPM;
-#else
- ModulePassManager MPM(DebugPassManager);
-#endif
bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
if (!NoPrepopulatePasses) {
// The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
@@ -1434,17 +1448,13 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
Ret->ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
};
-#if LLVM_VERSION_GE(13,0)
// Uses FromPrevailing visibility scheme which works for many binary
// formats. We probably could and should use ELF visibility scheme for many of
// our targets, however.
lto::Config conf;
thinLTOResolvePrevailingInIndex(conf, Ret->Index, isPrevailing, recordNewLinkage,
Ret->GUIDPreservedSymbols);
-#else
- thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
- Ret->GUIDPreservedSymbols);
-#endif
+
// Here we calculate an `ExportedGUIDs` set for use in the `isExported`
// callback below. This callback below will dictate the linkage for all
// summaries in the index, and we basically just only want to ensure that dead
@@ -1599,13 +1609,31 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
{
raw_string_ostream OS(Ret->data);
{
- legacy::PassManager PM;
if (is_thin) {
+#if LLVM_VERSION_LT(15, 0)
+ legacy::PassManager PM;
PM.add(createWriteThinLTOBitcodePass(OS));
+ PM.run(*unwrap(M));
+#else
+ PassBuilder PB;
+ LoopAnalysisManager LAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+ ModulePassManager MPM;
+ MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
+ MPM.run(*unwrap(M), MAM);
+#endif
} else {
+ legacy::PassManager PM;
PM.add(createBitcodeWriterPass(OS));
+ PM.run(*unwrap(M));
}
- PM.run(*unwrap(M));
}
}
return Ret.release();
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 5f5b5de79..6ee3c7d68 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -413,18 +413,12 @@ LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
LLVMValueRef Old, LLVMValueRef Source,
LLVMAtomicOrdering Order,
LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
-#if LLVM_VERSION_GE(13,0)
// Rust probably knows the alignment of the target value and should be able to
// specify something more precise than MaybeAlign here. See also
// https://reviews.llvm.org/D97224 which may be a useful reference.
AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
fromRust(FailureOrder));
-#else
- AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
- unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
- fromRust(FailureOrder));
-#endif
ACXI->setWeak(Weak);
return wrap(ACXI);
}
@@ -472,19 +466,11 @@ LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
char *Constraints, size_t ConstraintsLen,
LLVMBool HasSideEffects, LLVMBool IsAlignStack,
LLVMRustAsmDialect Dialect, LLVMBool CanThrow) {
-#if LLVM_VERSION_GE(13, 0)
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
StringRef(AsmString, AsmStringLen),
StringRef(Constraints, ConstraintsLen),
HasSideEffects, IsAlignStack,
fromRust(Dialect), CanThrow));
-#else
- return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
- StringRef(AsmString, AsmStringLen),
- StringRef(Constraints, ConstraintsLen),
- HasSideEffects, IsAlignStack,
- fromRust(Dialect)));
-#endif
}
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
@@ -924,6 +910,30 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
fromRust(Flags), unwrapDI<DIType>(Ty)));
}
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
+ LLVMRustDIBuilderRef Builder,
+ LLVMMetadataRef Scope,
+ const char *Name,
+ size_t NameLen,
+ LLVMMetadataRef File,
+ unsigned LineNo,
+ LLVMMetadataRef Ty,
+ LLVMRustDIFlags Flags,
+ LLVMValueRef val,
+ uint32_t AlignInBits
+) {
+ return wrap(Builder->createStaticMemberType(
+ unwrapDI<DIDescriptor>(Scope),
+ StringRef(Name, NameLen),
+ unwrapDI<DIFile>(File),
+ LineNo,
+ unwrapDI<DIType>(Ty),
+ fromRust(Flags),
+ unwrap<llvm::ConstantInt>(val),
+ AlignInBits
+ ));
+}
+
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
LLVMMetadataRef File, unsigned Line, unsigned Col) {
@@ -1250,10 +1260,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
return LLVMRustDiagnosticKind::Linker;
case DK_Unsupported:
return LLVMRustDiagnosticKind::Unsupported;
-#if LLVM_VERSION_GE(13, 0)
case DK_SrcMgr:
return LLVMRustDiagnosticKind::SrcMgr;
-#endif
default:
return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
? LLVMRustDiagnosticKind::OptimizationRemarkOther
@@ -1327,30 +1335,11 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
-#if LLVM_VERSION_LT(13, 0)
-using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
-#else
-using LLVMInlineAsmDiagHandlerTy = void*;
-#endif
-
-extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
- LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
- // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
- // with LLVM 13 this function is gone.
-#if LLVM_VERSION_LT(13, 0)
- unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
-#endif
-}
-
extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(
LLVMDiagnosticInfoRef DI, unsigned *Cookie) {
-#if LLVM_VERSION_GE(13, 0)
llvm::DiagnosticInfoSrcMgr *SM = static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
*Cookie = SM->getLocCookie();
return wrap(&SM->getSMDiag());
-#else
- report_fatal_error("Shouldn't get called on older versions");
-#endif
}
extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
@@ -1629,6 +1618,14 @@ extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
}
+extern "C" bool LLVMRustConstIntGetZExtValue(LLVMValueRef CV, uint64_t *value) {
+ auto C = unwrap<llvm::ConstantInt>(CV);
+ if (C->getBitWidth() > 64)
+ return false;
+ *value = C->getZExtValue();
+ return true;
+}
+
// Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
// the common sizes (1, 8, 16, 32, 64, 128 bits)
extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index 8eade02a4..8542dcf5b 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
// NOTE: This crate only exists to allow linking on mingw targets.
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index f2ec80b0c..458f5e87b 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -38,6 +38,9 @@
//! debugging, you can make changes inside those crates and quickly run main.rs
//! to read the debug logs.
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
use std::env::{self, VarError};
use std::fmt::{self, Display};
use std::io;
diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml
index 25b3aadc1..547c8debb 100644
--- a/compiler/rustc_macros/Cargo.toml
+++ b/compiler/rustc_macros/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
proc-macro = true
[dependencies]
-annotate-snippets = "0.8.0"
+annotate-snippets = "0.9"
fluent-bundle = "0.15.2"
fluent-syntax = "0.11"
synstructure = "0.12.1"
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 6b5b8b593..cf1c59455 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -21,7 +21,7 @@ impl<'a> SessionDiagnosticDerive<'a> {
builder: DiagnosticDeriveBuilder {
diag,
fields: build_field_mapping(&structure),
- kind: None,
+ kind: DiagnosticDeriveKind::SessionDiagnostic,
code: None,
slug: None,
},
@@ -34,49 +34,31 @@ impl<'a> SessionDiagnosticDerive<'a> {
let SessionDiagnosticDerive { mut structure, sess, mut builder } = self;
let ast = structure.ast();
- let (implementation, param_ty) = {
+ let implementation = {
if let syn::Data::Struct(..) = ast.data {
let preamble = builder.preamble(&structure);
let (attrs, args) = builder.body(&mut structure);
let span = ast.span().unwrap();
let diag = &builder.diag;
- let init = match (builder.kind.value(), builder.slug.value()) {
- (None, _) => {
- span_err(span, "diagnostic kind not specified")
- .help("use the `#[error(...)]` attribute to create an error")
- .emit();
- return DiagnosticDeriveError::ErrorHandled.to_compile_error();
- }
- (Some(kind), None) => {
+ let init = match builder.slug.value() {
+ None => {
span_err(span, "diagnostic slug not specified")
.help(&format!(
- "specify the slug as the first argument to the attribute, such as \
- `#[{}(typeck::example_error)]`",
- kind.descr()
+ "specify the slug as the first argument to the `#[diag(...)]` attribute, \
+ such as `#[diag(typeck::example_error)]`",
))
.emit();
return DiagnosticDeriveError::ErrorHandled.to_compile_error();
}
- (Some(DiagnosticDeriveKind::Lint), _) => {
- span_err(span, "only `#[error(..)]` and `#[warning(..)]` are supported")
- .help("use the `#[error(...)]` attribute to create a error")
- .emit();
- return DiagnosticDeriveError::ErrorHandled.to_compile_error();
- }
- (Some(DiagnosticDeriveKind::Error), Some(slug)) => {
- quote! {
- let mut #diag = #sess.struct_err(rustc_errors::fluent::#slug);
- }
- }
- (Some(DiagnosticDeriveKind::Warn), Some(slug)) => {
+ Some(slug) => {
quote! {
- let mut #diag = #sess.struct_warn(rustc_errors::fluent::#slug);
+ let mut #diag = #sess.struct_diagnostic(rustc_errors::fluent::#slug);
}
}
};
- let implementation = quote! {
+ quote! {
#init
#preamble
match self {
@@ -86,18 +68,7 @@ impl<'a> SessionDiagnosticDerive<'a> {
#args
}
#diag
- };
- let param_ty = match builder.kind {
- Some((DiagnosticDeriveKind::Error, _)) => {
- quote! { rustc_errors::ErrorGuaranteed }
- }
- Some((DiagnosticDeriveKind::Lint | DiagnosticDeriveKind::Warn, _)) => {
- quote! { () }
- }
- _ => unreachable!(),
- };
-
- (implementation, param_ty)
+ }
} else {
span_err(
ast.span().unwrap(),
@@ -105,20 +76,20 @@ impl<'a> SessionDiagnosticDerive<'a> {
)
.emit();
- let implementation = DiagnosticDeriveError::ErrorHandled.to_compile_error();
- let param_ty = quote! { rustc_errors::ErrorGuaranteed };
- (implementation, param_ty)
+ DiagnosticDeriveError::ErrorHandled.to_compile_error()
}
};
structure.gen_impl(quote! {
- gen impl<'__session_diagnostic_sess> rustc_session::SessionDiagnostic<'__session_diagnostic_sess, #param_ty>
+ gen impl<'__session_diagnostic_sess, G>
+ rustc_session::SessionDiagnostic<'__session_diagnostic_sess, G>
for @Self
+ where G: rustc_errors::EmissionGuarantee
{
fn into_diagnostic(
self,
- #sess: &'__session_diagnostic_sess rustc_session::parse::ParseSess
- ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, #param_ty> {
+ #sess: &'__session_diagnostic_sess rustc_errors::Handler
+ ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, G> {
use rustc_errors::IntoDiagnosticArg;
#implementation
}
@@ -139,7 +110,7 @@ impl<'a> LintDiagnosticDerive<'a> {
builder: DiagnosticDeriveBuilder {
diag,
fields: build_field_mapping(&structure),
- kind: None,
+ kind: DiagnosticDeriveKind::LintDiagnostic,
code: None,
slug: None,
},
@@ -158,30 +129,17 @@ impl<'a> LintDiagnosticDerive<'a> {
let diag = &builder.diag;
let span = ast.span().unwrap();
- let init = match (builder.kind.value(), builder.slug.value()) {
- (None, _) => {
- span_err(span, "diagnostic kind not specified")
- .help("use the `#[error(...)]` attribute to create an error")
- .emit();
- return DiagnosticDeriveError::ErrorHandled.to_compile_error();
- }
- (Some(kind), None) => {
+ let init = match builder.slug.value() {
+ None => {
span_err(span, "diagnostic slug not specified")
.help(&format!(
"specify the slug as the first argument to the attribute, such as \
- `#[{}(typeck::example_error)]`",
- kind.descr()
+ `#[diag(typeck::example_error)]`",
))
.emit();
return DiagnosticDeriveError::ErrorHandled.to_compile_error();
}
- (Some(DiagnosticDeriveKind::Error | DiagnosticDeriveKind::Warn), _) => {
- span_err(span, "only `#[lint(..)]` is supported")
- .help("use the `#[lint(...)]` attribute to create a lint")
- .emit();
- return DiagnosticDeriveError::ErrorHandled.to_compile_error();
- }
- (Some(DiagnosticDeriveKind::Lint), Some(slug)) => {
+ Some(slug) => {
quote! {
let mut #diag = #diag.build(rustc_errors::fluent::#slug);
}
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 6c9561925..2a4fe48a8 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -18,30 +18,15 @@ use syn::{
};
use synstructure::{BindingInfo, Structure};
-/// What kind of diagnostic is being derived - an error, a warning or a lint?
-#[derive(Copy, Clone)]
+/// What kind of diagnostic is being derived - a fatal/error/warning or a lint?
+#[derive(Copy, Clone, PartialEq, Eq)]
pub(crate) enum DiagnosticDeriveKind {
- /// `#[error(..)]`
- Error,
- /// `#[warn(..)]`
- Warn,
- /// `#[lint(..)]`
- Lint,
-}
-
-impl DiagnosticDeriveKind {
- /// Returns human-readable string corresponding to the kind.
- pub fn descr(&self) -> &'static str {
- match self {
- DiagnosticDeriveKind::Error => "error",
- DiagnosticDeriveKind::Warn => "warning",
- DiagnosticDeriveKind::Lint => "lint",
- }
- }
+ SessionDiagnostic,
+ LintDiagnostic,
}
/// Tracks persistent information required for building up individual calls to diagnostic methods
-/// for generated diagnostic derives - both `SessionDiagnostic` for errors/warnings and
+/// for generated diagnostic derives - both `SessionDiagnostic` for fatal/errors/warnings and
/// `LintDiagnostic` for lints.
pub(crate) struct DiagnosticDeriveBuilder {
/// The identifier to use for the generated `DiagnosticBuilder` instance.
@@ -51,8 +36,8 @@ pub(crate) struct DiagnosticDeriveBuilder {
/// derive builder.
pub fields: HashMap<String, TokenStream>,
- /// Kind of diagnostic requested via the struct attribute.
- pub kind: Option<(DiagnosticDeriveKind, proc_macro::Span)>,
+ /// Kind of diagnostic that should be derived.
+ pub kind: DiagnosticDeriveKind,
/// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
/// has the actual diagnostic message.
pub slug: Option<(Path, proc_macro::Span)>,
@@ -143,7 +128,7 @@ impl DiagnosticDeriveBuilder {
}
/// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct
- /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates
+ /// attributes like `#[diag(..)]`, such as the slug and error code. Generates
/// diagnostic builder calls for setting error code and creating note/help messages.
fn generate_structure_code_for_attr(
&mut self,
@@ -156,16 +141,16 @@ impl DiagnosticDeriveBuilder {
let name = name.as_str();
let meta = attr.parse_meta()?;
- let is_help_note_or_warn = matches!(name, "help" | "note" | "warn_");
+ let is_diag = name == "diag";
let nested = match meta {
- // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or
+ // Most attributes are lists, like `#[diag(..)]` for most cases or
// `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug.
Meta::List(MetaList { ref nested, .. }) => nested,
// Subdiagnostics without spans can be applied to the type too, and these are just
- // paths: `#[help]` and `#[note]`
- Meta::Path(_) if is_help_note_or_warn => {
- let fn_name = if name == "warn_" {
+ // paths: `#[help]`, `#[note]` and `#[warning]`
+ Meta::Path(_) if !is_diag => {
+ let fn_name = if name == "warning" {
Ident::new("warn", attr.span())
} else {
Ident::new(name, attr.span())
@@ -178,41 +163,42 @@ impl DiagnosticDeriveBuilder {
// Check the kind before doing any further processing so that there aren't misleading
// "no kind specified" errors if there are failures later.
match name {
- "error" => self.kind.set_once((DiagnosticDeriveKind::Error, span)),
- "warning" => self.kind.set_once((DiagnosticDeriveKind::Warn, span)),
- "lint" => self.kind.set_once((DiagnosticDeriveKind::Lint, span)),
- "help" | "note" | "warn_" => (),
+ "error" | "lint" => throw_invalid_attr!(attr, &meta, |diag| {
+ diag.help("`error` and `lint` have been replaced by `diag`")
+ }),
+ "warn_" => throw_invalid_attr!(attr, &meta, |diag| {
+ diag.help("`warn_` have been replaced by `warning`")
+ }),
+ "diag" | "help" | "note" | "warning" => (),
_ => throw_invalid_attr!(attr, &meta, |diag| {
- diag.help(
- "only `error`, `warning`, `help`, `note` and `warn_` are valid attributes",
- )
+ diag.help("only `diag`, `help`, `note` and `warning` are valid attributes")
}),
}
- // First nested element should always be the path, e.g. `#[error(typeck::invalid)]` or
+ // First nested element should always be the path, e.g. `#[diag(typeck::invalid)]` or
// `#[help(typeck::another_help)]`.
let mut nested_iter = nested.into_iter();
if let Some(nested_attr) = nested_iter.next() {
// Report an error if there are any other list items after the path.
- if is_help_note_or_warn && nested_iter.next().is_some() {
+ if !is_diag && nested_iter.next().is_some() {
throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
diag.help(
- "`help`, `note` and `warn_` struct attributes can only have one argument",
+ "`help`, `note` and `warning` struct attributes can only have one argument",
)
});
}
match nested_attr {
- NestedMeta::Meta(Meta::Path(path)) if is_help_note_or_warn => {
- let fn_name = proc_macro2::Ident::new(name, attr.span());
- return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); });
- }
NestedMeta::Meta(Meta::Path(path)) => {
- self.slug.set_once((path.clone(), span));
+ if is_diag {
+ self.slug.set_once((path.clone(), span));
+ } else {
+ let fn_name = proc_macro2::Ident::new(name, attr.span());
+ return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); });
+ }
}
NestedMeta::Meta(meta @ Meta::NameValue(_))
- if !is_help_note_or_warn
- && meta.path().segments.last().unwrap().ident == "code" =>
+ if is_diag && meta.path().segments.last().unwrap().ident == "code" =>
{
// don't error for valid follow-up attributes
}
@@ -253,7 +239,7 @@ impl DiagnosticDeriveBuilder {
}
}
- Ok(tokens.drain(..).collect())
+ Ok(tokens.into_iter().collect())
}
fn generate_field_attrs_code(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
@@ -346,21 +332,31 @@ impl DiagnosticDeriveBuilder {
Ok(quote! {})
}
"primary_span" => {
- report_error_if_not_applied_to_span(attr, &info)?;
- Ok(quote! {
- #diag.set_span(#binding);
- })
+ match self.kind {
+ DiagnosticDeriveKind::SessionDiagnostic => {
+ report_error_if_not_applied_to_span(attr, &info)?;
+
+ Ok(quote! {
+ #diag.set_span(#binding);
+ })
+ }
+ DiagnosticDeriveKind::LintDiagnostic => {
+ throw_invalid_attr!(attr, &meta, |diag| {
+ diag.help("the `primary_span` field attribute is not valid for lint diagnostics")
+ })
+ }
+ }
}
"label" => {
report_error_if_not_applied_to_span(attr, &info)?;
Ok(self.add_spanned_subdiagnostic(binding, ident, parse_quote! { _subdiag::label }))
}
- "note" | "help" | "warn_" => {
+ "note" | "help" | "warning" => {
let warn_ident = Ident::new("warn", Span::call_site());
let (ident, path) = match name {
"note" => (ident, parse_quote! { _subdiag::note }),
"help" => (ident, parse_quote! { _subdiag::help }),
- "warn_" => (&warn_ident, parse_quote! { _subdiag::warn }),
+ "warning" => (&warn_ident, parse_quote! { _subdiag::warn }),
_ => unreachable!(),
};
if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
@@ -397,7 +393,7 @@ impl DiagnosticDeriveBuilder {
"suggestion" | "suggestion_short" | "suggestion_hidden" | "suggestion_verbose" => {
return self.generate_inner_field_code_suggestion(attr, info);
}
- "label" | "help" | "note" | "warn_" => (),
+ "label" | "help" | "note" | "warning" => (),
_ => throw_invalid_attr!(attr, &meta, |diag| {
diag.help(
"only `label`, `help`, `note`, `warn` or `suggestion{,_short,_hidden,_verbose}` are \
@@ -429,14 +425,14 @@ impl DiagnosticDeriveBuilder {
Ok(self.add_spanned_subdiagnostic(binding, ident, msg))
}
"note" | "help" if type_is_unit(&info.ty) => Ok(self.add_subdiagnostic(ident, msg)),
- // `warn_` must be special-cased because the attribute `warn` already has meaning and
+ // `warning` must be special-cased because the attribute `warn` already has meaning and
// so isn't used, despite the diagnostic API being named `warn`.
- "warn_" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => Ok(self
+ "warning" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => Ok(self
.add_spanned_subdiagnostic(binding, &Ident::new("warn", Span::call_site()), msg)),
- "warn_" if type_is_unit(&info.ty) => {
+ "warning" if type_is_unit(&info.ty) => {
Ok(self.add_subdiagnostic(&Ident::new("warn", Span::call_site()), msg))
}
- "note" | "help" | "warn_" => report_type_error(attr, "`Span` or `()`")?,
+ "note" | "help" | "warning" => report_type_error(attr, "`Span` or `()`")?,
_ => unreachable!(),
}
}
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs
index 562d5e9f4..f7d8b494e 100644
--- a/compiler/rustc_macros/src/diagnostics/fluent.rs
+++ b/compiler/rustc_macros/src/diagnostics/fluent.rs
@@ -187,17 +187,41 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
for entry in resource.entries() {
let span = res.ident.span();
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
- let _ = previous_defns.entry(name.to_string()).or_insert(ident_span);
+ let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
+
+ if name.contains('-') {
+ Diagnostic::spanned(
+ path_span,
+ Level::Error,
+ format!("name `{name}` contains a '-' character"),
+ )
+ .help("replace any '-'s with '_'s")
+ .emit();
+ }
+
+ // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
+ // `const_eval_baz` => `baz` (in `const_eval.ftl`)
+ // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
+ // The last case we error about above, but we want to fall back gracefully
+ // so that only the error is being emitted and not also one about the macro
+ // failing.
+ let crate_prefix = format!("{}_", res.ident);
+
+ let snake_name = name.replace('-', "_");
+ let snake_name = match snake_name.strip_prefix(&crate_prefix) {
+ Some(rest) => Ident::new(rest, span),
+ None => {
+ Diagnostic::spanned(
+ path_span,
+ Level::Error,
+ format!("name `{name}` does not start with the crate name"),
+ )
+ .help(format!("prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"))
+ .emit();
+ Ident::new(&snake_name, span)
+ }
+ };
- // `typeck-foo-bar` => `foo_bar` (in `typeck.ftl`)
- // `const-eval-baz` => `baz` (in `const_eval.ftl`)
- let snake_name = Ident::new(
- // FIXME: should probably trim prefix, not replace all occurrences
- &name
- .replace(&format!("{}-", res.ident).replace('_', "-"), "")
- .replace('-', "_"),
- span,
- );
constants.extend(quote! {
pub const #snake_name: crate::DiagnosticMessage =
crate::DiagnosticMessage::FluentIdentifier(
@@ -212,6 +236,16 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
continue;
}
+ if attr_name.contains('-') {
+ Diagnostic::spanned(
+ path_span,
+ Level::Error,
+ format!("attribute `{attr_name}` contains a '-' character"),
+ )
+ .help("replace any '-'s with '_'s")
+ .emit();
+ }
+
constants.extend(quote! {
pub const #snake_name: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(
@@ -227,7 +261,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
match e {
FluentError::Overriding { kind, id } => {
Diagnostic::spanned(
- ident_span,
+ path_span,
Level::Error,
format!("overrides existing {}: `{}`", kind, id),
)
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 399790026..2ff21e18f 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -23,7 +23,7 @@ use synstructure::Structure;
/// # extern crate rust_middle;
/// # use rustc_middle::ty::Ty;
/// #[derive(SessionDiagnostic)]
-/// #[error(borrowck::move_out_of_borrow, code = "E0505")]
+/// #[diag(borrowck::move_out_of_borrow, code = "E0505")]
/// pub struct MoveOutOfBorrowError<'tcx> {
/// pub name: Ident,
/// pub ty: Ty<'tcx>,
@@ -38,9 +38,9 @@ use synstructure::Structure;
/// ```
///
/// ```fluent
-/// move-out-of-borrow = cannot move out of {$name} because it is borrowed
+/// move_out_of_borrow = cannot move out of {$name} because it is borrowed
/// .label = cannot move out of borrow
-/// .first-borrow-label = `{$ty}` first borrowed here
+/// .first_borrow_label = `{$ty}` first borrowed here
/// .suggestion = consider cloning here
/// ```
///
@@ -67,7 +67,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
///
/// ```ignore (rust)
/// #[derive(LintDiagnostic)]
-/// #[lint(lint::atomic_ordering_invalid_fail_success)]
+/// #[diag(lint::atomic_ordering_invalid_fail_success)]
/// pub struct AtomicOrderingInvalidLint {
/// method: Symbol,
/// success_ordering: Symbol,
@@ -84,9 +84,9 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// ```
///
/// ```fluent
-/// lint-atomic-ordering-invalid-fail-success = `{$method}`'s success ordering must be at least as strong as its failure ordering
-/// .fail-label = `{$fail_ordering}` failure ordering
-/// .success-label = `{$success_ordering}` success ordering
+/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering
+/// .fail_label = `{$fail_ordering}` failure ordering
+/// .success_label = `{$success_ordering}` success ordering
/// .suggestion = consider using `{$success_suggestion}` success ordering instead
/// ```
///
@@ -140,11 +140,11 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// ```
///
/// ```fluent
-/// parser-expected-identifier = expected identifier
+/// parser_expected_identifier = expected identifier
///
-/// parser-expected-identifier-found = expected identifier, found {$found}
+/// parser_expected_identifier-found = expected identifier, found {$found}
///
-/// parser-raw-identifier = escape `{$ident}` to use it as an identifier
+/// parser_raw_identifier = escape `{$ident}` to use it as an identifier
/// ```
///
/// Then, later, to add the subdiagnostic:
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index edf4dbed9..dce5d3cfb 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -12,7 +12,7 @@ use quote::{format_ident, quote};
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
-use syn::{parse_quote, spanned::Spanned, Meta, MetaList, MetaNameValue, NestedMeta, Path};
+use syn::{spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path};
use synstructure::{BindingInfo, Structure, VariantInfo};
/// Which kind of suggestion is being created?
@@ -28,8 +28,41 @@ enum SubdiagnosticSuggestionKind {
Verbose,
}
+impl FromStr for SubdiagnosticSuggestionKind {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "" => Ok(SubdiagnosticSuggestionKind::Normal),
+ "_short" => Ok(SubdiagnosticSuggestionKind::Short),
+ "_hidden" => Ok(SubdiagnosticSuggestionKind::Hidden),
+ "_verbose" => Ok(SubdiagnosticSuggestionKind::Verbose),
+ _ => Err(()),
+ }
+ }
+}
+
+impl SubdiagnosticSuggestionKind {
+ pub fn to_suggestion_style(&self) -> TokenStream {
+ match self {
+ SubdiagnosticSuggestionKind::Normal => {
+ quote! { rustc_errors::SuggestionStyle::ShowCode }
+ }
+ SubdiagnosticSuggestionKind::Short => {
+ quote! { rustc_errors::SuggestionStyle::HideCodeInline }
+ }
+ SubdiagnosticSuggestionKind::Hidden => {
+ quote! { rustc_errors::SuggestionStyle::HideCodeAlways }
+ }
+ SubdiagnosticSuggestionKind::Verbose => {
+ quote! { rustc_errors::SuggestionStyle::ShowAlways }
+ }
+ }
+ }
+}
+
/// Which kind of subdiagnostic is being created from a variant?
-#[derive(Clone, Copy)]
+#[derive(Clone)]
enum SubdiagnosticKind {
/// `#[label(...)]`
Label,
@@ -37,34 +70,12 @@ enum SubdiagnosticKind {
Note,
/// `#[help(...)]`
Help,
- /// `#[warn_(...)]`
+ /// `#[warning(...)]`
Warn,
/// `#[suggestion{,_short,_hidden,_verbose}]`
- Suggestion(SubdiagnosticSuggestionKind),
-}
-
-impl FromStr for SubdiagnosticKind {
- type Err = ();
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- match s {
- "label" => Ok(SubdiagnosticKind::Label),
- "note" => Ok(SubdiagnosticKind::Note),
- "help" => Ok(SubdiagnosticKind::Help),
- "warn_" => Ok(SubdiagnosticKind::Warn),
- "suggestion" => Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal)),
- "suggestion_short" => {
- Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short))
- }
- "suggestion_hidden" => {
- Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Hidden))
- }
- "suggestion_verbose" => {
- Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Verbose))
- }
- _ => Err(()),
- }
- }
+ Suggestion { suggestion_kind: SubdiagnosticSuggestionKind, code: TokenStream },
+ /// `#[multipart_suggestion{,_short,_hidden,_verbose}]`
+ MultipartSuggestion { suggestion_kind: SubdiagnosticSuggestionKind },
}
impl quote::IdentFragment for SubdiagnosticKind {
@@ -74,17 +85,9 @@ impl quote::IdentFragment for SubdiagnosticKind {
SubdiagnosticKind::Note => write!(f, "note"),
SubdiagnosticKind::Help => write!(f, "help"),
SubdiagnosticKind::Warn => write!(f, "warn"),
- SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal) => {
- write!(f, "suggestion")
- }
- SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short) => {
- write!(f, "suggestion_short")
- }
- SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Hidden) => {
- write!(f, "suggestion_hidden")
- }
- SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Verbose) => {
- write!(f, "suggestion_verbose")
+ SubdiagnosticKind::Suggestion { .. } => write!(f, "suggestion_with_style"),
+ SubdiagnosticKind::MultipartSuggestion { .. } => {
+ write!(f, "multipart_suggestion_with_style")
}
}
}
@@ -148,11 +151,9 @@ impl<'a> SessionSubdiagnosticDerive<'a> {
variant,
span,
fields: fields_map,
- kind: None,
- slug: None,
- code: None,
span_field: None,
applicability: None,
+ has_suggestion_parts: false,
};
builder.into_tokens().unwrap_or_else(|v| v.to_compile_error())
});
@@ -193,21 +194,15 @@ struct SessionSubdiagnosticDeriveBuilder<'a> {
/// derive builder.
fields: HashMap<String, TokenStream>,
- /// Subdiagnostic kind of the type/variant.
- kind: Option<(SubdiagnosticKind, proc_macro::Span)>,
-
- /// Slug of the subdiagnostic - corresponds to the Fluent identifier for the message - from the
- /// `#[kind(slug)]` attribute on the type or variant.
- slug: Option<(Path, proc_macro::Span)>,
- /// If a suggestion, the code to suggest as a replacement - from the `#[kind(code = "...")]`
- /// attribute on the type or variant.
- code: Option<(TokenStream, proc_macro::Span)>,
-
/// Identifier for the binding to the `#[primary_span]` field.
span_field: Option<(proc_macro2::Ident, proc_macro::Span)>,
/// If a suggestion, the identifier for the binding to the `#[applicability]` field or a
/// `rustc_errors::Applicability::*` variant directly.
applicability: Option<(TokenStream, proc_macro::Span)>,
+
+ /// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error
+ /// during finalization if still `false`.
+ has_suggestion_parts: bool,
}
impl<'a> HasFieldMap for SessionSubdiagnosticDeriveBuilder<'a> {
@@ -216,8 +211,40 @@ impl<'a> HasFieldMap for SessionSubdiagnosticDeriveBuilder<'a> {
}
}
+/// Provides frequently-needed information about the diagnostic kinds being derived for this type.
+#[derive(Clone, Copy, Debug)]
+struct KindsStatistics {
+ has_multipart_suggestion: bool,
+ all_multipart_suggestions: bool,
+ has_normal_suggestion: bool,
+}
+
+impl<'a> FromIterator<&'a SubdiagnosticKind> for KindsStatistics {
+ fn from_iter<T: IntoIterator<Item = &'a SubdiagnosticKind>>(kinds: T) -> Self {
+ let mut ret = Self {
+ has_multipart_suggestion: false,
+ all_multipart_suggestions: true,
+ has_normal_suggestion: false,
+ };
+ for kind in kinds {
+ if let SubdiagnosticKind::MultipartSuggestion { .. } = kind {
+ ret.has_multipart_suggestion = true;
+ } else {
+ ret.all_multipart_suggestions = false;
+ }
+
+ if let SubdiagnosticKind::Suggestion { .. } = kind {
+ ret.has_normal_suggestion = true;
+ }
+ }
+ ret
+ }
+}
+
impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
- fn identify_kind(&mut self) -> Result<(), DiagnosticDeriveError> {
+ fn identify_kind(&mut self) -> Result<Vec<(SubdiagnosticKind, Path)>, DiagnosticDeriveError> {
+ let mut kind_slugs = vec![];
+
for attr in self.variant.ast().attrs {
let span = attr.span().unwrap();
@@ -225,116 +252,121 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
let name = name.as_str();
let meta = attr.parse_meta()?;
- let kind = match meta {
- Meta::List(MetaList { ref nested, .. }) => {
- let mut nested_iter = nested.into_iter();
- if let Some(nested_attr) = nested_iter.next() {
- match nested_attr {
- NestedMeta::Meta(Meta::Path(path)) => {
- self.slug.set_once((path.clone(), span));
- }
- NestedMeta::Meta(meta @ Meta::NameValue(_))
- if matches!(
- meta.path().segments.last().unwrap().ident.to_string().as_str(),
- "code" | "applicability"
- ) =>
- {
- // don't error for valid follow-up attributes
- }
- nested_attr => {
- throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
- diag.help(
- "first argument of the attribute should be the diagnostic \
- slug",
- )
- })
- }
- };
- }
+ let Meta::List(MetaList { ref nested, .. }) = meta else {
+ throw_invalid_attr!(attr, &meta);
+ };
- for nested_attr in nested_iter {
- let meta = match nested_attr {
- NestedMeta::Meta(ref meta) => meta,
- _ => throw_invalid_nested_attr!(attr, &nested_attr),
- };
-
- let span = meta.span().unwrap();
- let nested_name = meta.path().segments.last().unwrap().ident.to_string();
- let nested_name = nested_name.as_str();
-
- match meta {
- Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
- match nested_name {
- "code" => {
- let formatted_str = self.build_format(&s.value(), s.span());
- self.code.set_once((formatted_str, span));
- }
- "applicability" => {
- let value = match Applicability::from_str(&s.value()) {
- Ok(v) => v,
- Err(()) => {
- span_err(span, "invalid applicability").emit();
- Applicability::Unspecified
- }
- };
- self.applicability.set_once((quote! { #value }, span));
- }
- _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
- diag.help(
- "only `code` and `applicability` are valid nested \
- attributes",
- )
- }),
- }
- }
- _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
- if matches!(meta, Meta::Path(_)) {
- diag.help(
- "a diagnostic slug must be the first argument to the \
- attribute",
- )
- } else {
- diag
- }
- }),
- }
+ let mut kind = match name {
+ "label" => SubdiagnosticKind::Label,
+ "note" => SubdiagnosticKind::Note,
+ "help" => SubdiagnosticKind::Help,
+ "warning" => SubdiagnosticKind::Warn,
+ _ => {
+ if let Some(suggestion_kind) =
+ name.strip_prefix("suggestion").and_then(|s| s.parse().ok())
+ {
+ SubdiagnosticKind::Suggestion { suggestion_kind, code: TokenStream::new() }
+ } else if let Some(suggestion_kind) =
+ name.strip_prefix("multipart_suggestion").and_then(|s| s.parse().ok())
+ {
+ SubdiagnosticKind::MultipartSuggestion { suggestion_kind }
+ } else {
+ throw_invalid_attr!(attr, &meta);
}
-
- let Ok(kind) = SubdiagnosticKind::from_str(name) else {
- throw_invalid_attr!(attr, &meta)
- };
-
- kind
}
- _ => throw_invalid_attr!(attr, &meta),
};
- if matches!(
- kind,
- SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note
- ) && self.code.is_some()
- {
- throw_span_err!(
- span,
- &format!("`code` is not a valid nested attribute of a `{}` attribute", name)
- );
+ let mut slug = None;
+ let mut code = None;
+
+ let mut nested_iter = nested.into_iter();
+ if let Some(nested_attr) = nested_iter.next() {
+ match nested_attr {
+ NestedMeta::Meta(Meta::Path(path)) => {
+ slug.set_once((path.clone(), span));
+ }
+ NestedMeta::Meta(meta @ Meta::NameValue(_))
+ if matches!(
+ meta.path().segments.last().unwrap().ident.to_string().as_str(),
+ "code" | "applicability"
+ ) =>
+ {
+ // Don't error for valid follow-up attributes.
+ }
+ nested_attr => {
+ throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help(
+ "first argument of the attribute should be the diagnostic \
+ slug",
+ )
+ })
+ }
+ };
}
- if matches!(
- kind,
- SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note
- ) && self.applicability.is_some()
- {
- throw_span_err!(
- span,
- &format!(
- "`applicability` is not a valid nested attribute of a `{}` attribute",
- name
- )
- );
+ for nested_attr in nested_iter {
+ let meta = match nested_attr {
+ NestedMeta::Meta(ref meta) => meta,
+ _ => throw_invalid_nested_attr!(attr, &nested_attr),
+ };
+
+ let span = meta.span().unwrap();
+ let nested_name = meta.path().segments.last().unwrap().ident.to_string();
+ let nested_name = nested_name.as_str();
+
+ let value = match meta {
+ Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) => value,
+ Meta::Path(_) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help("a diagnostic slug must be the first argument to the attribute")
+ }),
+ _ => throw_invalid_nested_attr!(attr, &nested_attr),
+ };
+
+ match nested_name {
+ "code" => {
+ if matches!(kind, SubdiagnosticKind::Suggestion { .. }) {
+ let formatted_str = self.build_format(&value.value(), value.span());
+ code.set_once((formatted_str, span));
+ } else {
+ span_err(
+ span,
+ &format!(
+ "`code` is not a valid nested attribute of a `{}` attribute",
+ name
+ ),
+ )
+ .emit();
+ }
+ }
+ "applicability" => {
+ if matches!(
+ kind,
+ SubdiagnosticKind::Suggestion { .. }
+ | SubdiagnosticKind::MultipartSuggestion { .. }
+ ) {
+ let value =
+ Applicability::from_str(&value.value()).unwrap_or_else(|()| {
+ span_err(span, "invalid applicability").emit();
+ Applicability::Unspecified
+ });
+ self.applicability.set_once((quote! { #value }, span));
+ } else {
+ span_err(
+ span,
+ &format!(
+ "`applicability` is not a valid nested attribute of a `{}` attribute",
+ name
+ )
+ ).emit();
+ }
+ }
+ _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help("only `code` and `applicability` are valid nested attributes")
+ }),
+ }
}
- if self.slug.is_none() {
+ let Some((slug, _)) = slug else {
throw_span_err!(
span,
&format!(
@@ -342,150 +374,334 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
name
)
);
+ };
+
+ match kind {
+ SubdiagnosticKind::Suggestion { code: ref mut code_field, .. } => {
+ let Some((code, _)) = code else {
+ throw_span_err!(span, "suggestion without `code = \"...\"`");
+ };
+ *code_field = code;
+ }
+ SubdiagnosticKind::Label
+ | SubdiagnosticKind::Note
+ | SubdiagnosticKind::Help
+ | SubdiagnosticKind::Warn
+ | SubdiagnosticKind::MultipartSuggestion { .. } => {}
}
- self.kind.set_once((kind, span));
+ kind_slugs.push((kind, slug))
}
- Ok(())
+ Ok(kind_slugs)
}
- fn generate_field_code(
+ /// Generates the code for a field with no attributes.
+ fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream {
+ let ast = binding.ast();
+ assert_eq!(ast.attrs.len(), 0, "field with attribute used as diagnostic arg");
+
+ let diag = &self.diag;
+ let ident = ast.ident.as_ref().unwrap();
+ quote! {
+ #diag.set_arg(
+ stringify!(#ident),
+ #binding
+ );
+ }
+ }
+
+ /// Generates the necessary code for all attributes on a field.
+ fn generate_field_attr_code(
&mut self,
binding: &BindingInfo<'_>,
- is_suggestion: bool,
- ) -> Result<TokenStream, DiagnosticDeriveError> {
+ kind_stats: KindsStatistics,
+ ) -> TokenStream {
let ast = binding.ast();
+ assert!(ast.attrs.len() > 0, "field without attributes generating attr code");
+ // Abstract over `Vec<T>` and `Option<T>` fields using `FieldInnerTy`, which will
+ // apply the generated code on each element in the `Vec` or `Option`.
let inner_ty = FieldInnerTy::from_type(&ast.ty);
- let info = FieldInfo {
- binding: binding,
- ty: inner_ty.inner_type().unwrap_or(&ast.ty),
- span: &ast.span(),
- };
+ ast.attrs
+ .iter()
+ .map(|attr| {
+ let info = FieldInfo {
+ binding,
+ ty: inner_ty.inner_type().unwrap_or(&ast.ty),
+ span: &ast.span(),
+ };
- for attr in &ast.attrs {
- let name = attr.path.segments.last().unwrap().ident.to_string();
- let name = name.as_str();
- let span = attr.span().unwrap();
+ let generated = self
+ .generate_field_code_inner(kind_stats, attr, info)
+ .unwrap_or_else(|v| v.to_compile_error());
- let meta = attr.parse_meta()?;
- match meta {
- Meta::Path(_) => match name {
- "primary_span" => {
- report_error_if_not_applied_to_span(attr, &info)?;
- self.span_field.set_once((binding.binding.clone(), span));
- return Ok(quote! {});
- }
- "applicability" if is_suggestion => {
- report_error_if_not_applied_to_applicability(attr, &info)?;
- let binding = binding.binding.clone();
- self.applicability.set_once((quote! { #binding }, span));
- return Ok(quote! {});
- }
- "applicability" => {
- span_err(span, "`#[applicability]` is only valid on suggestions").emit();
- return Ok(quote! {});
- }
- "skip_arg" => {
- return Ok(quote! {});
- }
- _ => throw_invalid_attr!(attr, &meta, |diag| {
+ inner_ty.with(binding, generated)
+ })
+ .collect()
+ }
+
+ fn generate_field_code_inner(
+ &mut self,
+ kind_stats: KindsStatistics,
+ attr: &Attribute,
+ info: FieldInfo<'_>,
+ ) -> Result<TokenStream, DiagnosticDeriveError> {
+ let meta = attr.parse_meta()?;
+ match meta {
+ Meta::Path(path) => self.generate_field_code_inner_path(kind_stats, attr, info, path),
+ Meta::List(list @ MetaList { .. }) => {
+ self.generate_field_code_inner_list(kind_stats, attr, info, list)
+ }
+ _ => throw_invalid_attr!(attr, &meta),
+ }
+ }
+
+ /// Generates the code for a `[Meta::Path]`-like attribute on a field (e.g. `#[primary_span]`).
+ fn generate_field_code_inner_path(
+ &mut self,
+ kind_stats: KindsStatistics,
+ attr: &Attribute,
+ info: FieldInfo<'_>,
+ path: Path,
+ ) -> Result<TokenStream, DiagnosticDeriveError> {
+ let span = attr.span().unwrap();
+ let ident = &path.segments.last().unwrap().ident;
+ let name = ident.to_string();
+ let name = name.as_str();
+
+ match name {
+ "skip_arg" => Ok(quote! {}),
+ "primary_span" => {
+ if kind_stats.has_multipart_suggestion {
+ throw_invalid_attr!(attr, &Meta::Path(path), |diag| {
diag.help(
- "only `primary_span`, `applicability` and `skip_arg` are valid field \
- attributes",
+ "multipart suggestions use one or more `#[suggestion_part]`s rather \
+ than one `#[primary_span]`",
)
- }),
- },
- _ => throw_invalid_attr!(attr, &meta),
+ })
+ }
+
+ report_error_if_not_applied_to_span(attr, &info)?;
+
+ let binding = info.binding.binding.clone();
+ self.span_field.set_once((binding, span));
+
+ Ok(quote! {})
+ }
+ "suggestion_part" => {
+ self.has_suggestion_parts = true;
+
+ if kind_stats.has_multipart_suggestion {
+ span_err(span, "`#[suggestion_part(...)]` attribute without `code = \"...\"`")
+ .emit();
+ Ok(quote! {})
+ } else {
+ throw_invalid_attr!(attr, &Meta::Path(path), |diag| {
+ diag.help(
+ "`#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead",
+ )
+ });
+ }
+ }
+ "applicability" => {
+ if kind_stats.has_multipart_suggestion || kind_stats.has_normal_suggestion {
+ report_error_if_not_applied_to_applicability(attr, &info)?;
+
+ let binding = info.binding.binding.clone();
+ self.applicability.set_once((quote! { #binding }, span));
+ } else {
+ span_err(span, "`#[applicability]` is only valid on suggestions").emit();
+ }
+
+ Ok(quote! {})
}
+ _ => throw_invalid_attr!(attr, &Meta::Path(path), |diag| {
+ let mut span_attrs = vec![];
+ if kind_stats.has_multipart_suggestion {
+ span_attrs.push("suggestion_part");
+ }
+ if !kind_stats.all_multipart_suggestions {
+ span_attrs.push("primary_span")
+ }
+ diag.help(format!(
+ "only `{}`, `applicability` and `skip_arg` are valid field attributes",
+ span_attrs.join(", ")
+ ))
+ }),
}
+ }
- let ident = ast.ident.as_ref().unwrap();
+ /// Generates the code for a `[Meta::List]`-like attribute on a field (e.g.
+ /// `#[suggestion_part(code = "...")]`).
+ fn generate_field_code_inner_list(
+ &mut self,
+ kind_stats: KindsStatistics,
+ attr: &Attribute,
+ info: FieldInfo<'_>,
+ list: MetaList,
+ ) -> Result<TokenStream, DiagnosticDeriveError> {
+ let span = attr.span().unwrap();
+ let ident = &list.path.segments.last().unwrap().ident;
+ let name = ident.to_string();
+ let name = name.as_str();
+
+ match name {
+ "suggestion_part" => {
+ if !kind_stats.has_multipart_suggestion {
+ throw_invalid_attr!(attr, &Meta::List(list), |diag| {
+ diag.help(
+ "`#[suggestion_part(...)]` is only valid in multipart suggestions",
+ )
+ })
+ }
- let diag = &self.diag;
- let generated = quote! {
- #diag.set_arg(
- stringify!(#ident),
- #binding
- );
- };
+ self.has_suggestion_parts = true;
+
+ report_error_if_not_applied_to_span(attr, &info)?;
+
+ let mut code = None;
+ for nested_attr in list.nested.iter() {
+ let NestedMeta::Meta(ref meta) = nested_attr else {
+ throw_invalid_nested_attr!(attr, &nested_attr);
+ };
+
+ let span = meta.span().unwrap();
+ let nested_name = meta.path().segments.last().unwrap().ident.to_string();
+ let nested_name = nested_name.as_str();
+
+ let Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) = meta else {
+ throw_invalid_nested_attr!(attr, &nested_attr);
+ };
+
+ match nested_name {
+ "code" => {
+ let formatted_str = self.build_format(&value.value(), value.span());
+ code.set_once((formatted_str, span));
+ }
+ _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help("`code` is the only valid nested attribute")
+ }),
+ }
+ }
- Ok(inner_ty.with(binding, generated))
+ let Some((code, _)) = code else {
+ span_err(span, "`#[suggestion_part(...)]` attribute without `code = \"...\"`")
+ .emit();
+ return Ok(quote! {});
+ };
+ let binding = info.binding;
+
+ Ok(quote! { suggestions.push((#binding, #code)); })
+ }
+ _ => throw_invalid_attr!(attr, &Meta::List(list), |diag| {
+ let mut span_attrs = vec![];
+ if kind_stats.has_multipart_suggestion {
+ span_attrs.push("suggestion_part");
+ }
+ if !kind_stats.all_multipart_suggestions {
+ span_attrs.push("primary_span")
+ }
+ diag.help(format!(
+ "only `{}`, `applicability` and `skip_arg` are valid field attributes",
+ span_attrs.join(", ")
+ ))
+ }),
+ }
}
- fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
- self.identify_kind()?;
- let Some(kind) = self.kind.map(|(kind, _)| kind) else {
+ pub fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
+ let kind_slugs = self.identify_kind()?;
+ if kind_slugs.is_empty() {
throw_span_err!(
self.variant.ast().ident.span().unwrap(),
"subdiagnostic kind not specified"
);
};
- let is_suggestion = matches!(kind, SubdiagnosticKind::Suggestion(_));
+ let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect();
- let mut args = TokenStream::new();
- for binding in self.variant.bindings() {
- let arg = self
- .generate_field_code(binding, is_suggestion)
- .unwrap_or_else(|v| v.to_compile_error());
- args.extend(arg);
- }
-
- // Missing slug errors will already have been reported.
- let slug = self
- .slug
- .as_ref()
- .map(|(slug, _)| slug.clone())
- .unwrap_or_else(|| parse_quote! { you::need::to::specify::a::slug });
- let code = match self.code.as_ref() {
- Some((code, _)) => Some(quote! { #code }),
- None if is_suggestion => {
- span_err(self.span, "suggestion without `code = \"...\"`").emit();
- Some(quote! { /* macro error */ "..." })
- }
- None => None,
+ let init = if kind_stats.has_multipart_suggestion {
+ quote! { let mut suggestions = Vec::new(); }
+ } else {
+ quote! {}
};
+ let attr_args: TokenStream = self
+ .variant
+ .bindings()
+ .iter()
+ .filter(|binding| !binding.ast().attrs.is_empty())
+ .map(|binding| self.generate_field_attr_code(binding, kind_stats))
+ .collect();
+
let span_field = self.span_field.as_ref().map(|(span, _)| span);
- let applicability = match self.applicability.clone() {
- Some((applicability, _)) => Some(applicability),
- None if is_suggestion => {
- span_err(self.span, "suggestion without `applicability`").emit();
- Some(quote! { rustc_errors::Applicability::Unspecified })
- }
- None => None,
- };
+ let applicability = self.applicability.take().map_or_else(
+ || quote! { rustc_errors::Applicability::Unspecified },
+ |(applicability, _)| applicability,
+ );
let diag = &self.diag;
- let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
- let message = quote! { rustc_errors::fluent::#slug };
- let call = if matches!(kind, SubdiagnosticKind::Suggestion(..)) {
- if let Some(span) = span_field {
- quote! { #diag.#name(#span, #message, #code, #applicability); }
- } else {
- span_err(self.span, "suggestion without `#[primary_span]` field").emit();
- quote! { unreachable!(); }
- }
- } else if matches!(kind, SubdiagnosticKind::Label) {
- if let Some(span) = span_field {
- quote! { #diag.#name(#span, #message); }
- } else {
- span_err(self.span, "label without `#[primary_span]` field").emit();
- quote! { unreachable!(); }
- }
- } else {
- if let Some(span) = span_field {
- quote! { #diag.#name(#span, #message); }
- } else {
- quote! { #diag.#name(#message); }
- }
- };
+ let mut calls = TokenStream::new();
+ for (kind, slug) in kind_slugs {
+ let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
+ let message = quote! { rustc_errors::fluent::#slug };
+ let call = match kind {
+ SubdiagnosticKind::Suggestion { suggestion_kind, code } => {
+ if let Some(span) = span_field {
+ let style = suggestion_kind.to_suggestion_style();
+
+ quote! { #diag.#name(#span, #message, #code, #applicability, #style); }
+ } else {
+ span_err(self.span, "suggestion without `#[primary_span]` field").emit();
+ quote! { unreachable!(); }
+ }
+ }
+ SubdiagnosticKind::MultipartSuggestion { suggestion_kind } => {
+ if !self.has_suggestion_parts {
+ span_err(
+ self.span,
+ "multipart suggestion without any `#[suggestion_part(...)]` fields",
+ )
+ .emit();
+ }
+
+ let style = suggestion_kind.to_suggestion_style();
+
+ quote! { #diag.#name(#message, suggestions, #applicability, #style); }
+ }
+ SubdiagnosticKind::Label => {
+ if let Some(span) = span_field {
+ quote! { #diag.#name(#span, #message); }
+ } else {
+ span_err(self.span, "label without `#[primary_span]` field").emit();
+ quote! { unreachable!(); }
+ }
+ }
+ _ => {
+ if let Some(span) = span_field {
+ quote! { #diag.#name(#span, #message); }
+ } else {
+ quote! { #diag.#name(#message); }
+ }
+ }
+ };
+ calls.extend(call);
+ }
+
+ let plain_args: TokenStream = self
+ .variant
+ .bindings()
+ .iter()
+ .filter(|binding| binding.ast().attrs.is_empty())
+ .map(|binding| self.generate_field_set_arg(binding))
+ .collect();
Ok(quote! {
- #call
- #args
+ #init
+ #attr_args
+ #calls
+ #plain_args
})
}
}
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index 002abb152..ad9ecd39b 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -235,35 +235,40 @@ pub(crate) trait HasFieldMap {
// the referenced fields. Leaves `it` sitting on the closing brace of the format string, so
// the next call to `it.next()` retrieves the next character.
while let Some(c) = it.next() {
- if c == '{' && *it.peek().unwrap_or(&'\0') != '{' {
- let mut eat_argument = || -> Option<String> {
- let mut result = String::new();
- // Format specifiers look like:
- //
- // format := '{' [ argument ] [ ':' format_spec ] '}' .
- //
- // Therefore, we only need to eat until ':' or '}' to find the argument.
- while let Some(c) = it.next() {
- result.push(c);
- let next = *it.peek().unwrap_or(&'\0');
- if next == '}' {
- break;
- } else if next == ':' {
- // Eat the ':' character.
- assert_eq!(it.next().unwrap(), ':');
- break;
- }
- }
- // Eat until (and including) the matching '}'
- while it.next()? != '}' {
- continue;
+ if c != '{' {
+ continue;
+ }
+ if *it.peek().unwrap_or(&'\0') == '{' {
+ assert_eq!(it.next().unwrap(), '{');
+ continue;
+ }
+ let mut eat_argument = || -> Option<String> {
+ let mut result = String::new();
+ // Format specifiers look like:
+ //
+ // format := '{' [ argument ] [ ':' format_spec ] '}' .
+ //
+ // Therefore, we only need to eat until ':' or '}' to find the argument.
+ while let Some(c) = it.next() {
+ result.push(c);
+ let next = *it.peek().unwrap_or(&'\0');
+ if next == '}' {
+ break;
+ } else if next == ':' {
+ // Eat the ':' character.
+ assert_eq!(it.next().unwrap(), ':');
+ break;
}
- Some(result)
- };
-
- if let Some(referenced_field) = eat_argument() {
- referenced_fields.insert(referenced_field);
}
+ // Eat until (and including) the matching '}'
+ while it.next()? != '}' {
+ continue;
+ }
+ Some(result)
+ };
+
+ if let Some(referenced_field) = eat_argument() {
+ referenced_fields.insert(referenced_field);
}
}
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index ab509b26f..2c027d754 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -1,9 +1,11 @@
#![feature(allow_internal_unstable)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_span)]
#![allow(rustc::default_hash_types)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#![recursion_limit = "128"]
use synstructure::decl_derive;
@@ -65,10 +67,10 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
/// ..where `typeck.ftl` has the following contents..
///
/// ```fluent
-/// typeck-field-multiply-specified-in-initializer =
+/// typeck_field_multiply_specified_in_initializer =
/// field `{$ident}` specified more than once
/// .label = used more than once
-/// .label-previous-use = first use of `{$ident}`
+/// .label_previous_use = first use of `{$ident}`
/// ```
/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and
/// will generate the following code:
@@ -81,11 +83,11 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
/// mod fluent_generated {
/// mod typeck {
/// pub const field_multiply_specified_in_initializer: DiagnosticMessage =
-/// DiagnosticMessage::fluent("typeck-field-multiply-specified-in-initializer");
+/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer");
/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage =
/// DiagnosticMessage::fluent_attr(
-/// "typeck-field-multiply-specified-in-initializer",
-/// "previous-use-label"
+/// "typeck_field_multiply_specified_in_initializer",
+/// "previous_use_label"
/// );
/// }
/// }
@@ -127,12 +129,10 @@ decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
decl_derive!(
[SessionDiagnostic, attributes(
// struct attributes
- warning,
- error,
- lint,
+ diag,
help,
note,
- warn_,
+ warning,
// field attributes
skip_arg,
primary_span,
@@ -146,12 +146,10 @@ decl_derive!(
decl_derive!(
[LintDiagnostic, attributes(
// struct attributes
- warning,
- error,
- lint,
+ diag,
help,
note,
- warn_,
+ warning,
// field attributes
skip_arg,
primary_span,
@@ -168,13 +166,18 @@ decl_derive!(
label,
help,
note,
- warn_,
+ warning,
suggestion,
suggestion_short,
suggestion_hidden,
suggestion_verbose,
+ multipart_suggestion,
+ multipart_suggestion_short,
+ multipart_suggestion_hidden,
+ multipart_suggestion_verbose,
// field attributes
skip_arg,
primary_span,
+ suggestion_part,
applicability)] => diagnostics::session_subdiagnostic_derive
);
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index a69126533..d49926c90 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -1,139 +1,17 @@
use proc_macro::TokenStream;
-use proc_macro2::{Delimiter, TokenTree};
use quote::{quote, quote_spanned};
use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{
- braced, parenthesized, parse_macro_input, parse_quote, AttrStyle, Attribute, Block, Error,
- Expr, Ident, ReturnType, Token, Type,
+ braced, parenthesized, parse_macro_input, parse_quote, token, AttrStyle, Attribute, Block,
+ Error, Expr, Ident, Pat, ReturnType, Token, Type,
};
mod kw {
syn::custom_keyword!(query);
}
-/// Ident or a wildcard `_`.
-struct IdentOrWild(Ident);
-
-impl Parse for IdentOrWild {
- fn parse(input: ParseStream<'_>) -> Result<Self> {
- Ok(if input.peek(Token![_]) {
- let underscore = input.parse::<Token![_]>()?;
- IdentOrWild(Ident::new("_", underscore.span()))
- } else {
- IdentOrWild(input.parse()?)
- })
- }
-}
-
-/// A modifier for a query
-enum QueryModifier {
- /// The description of the query.
- Desc(Option<Ident>, Punctuated<Expr, Token![,]>),
-
- /// Use this type for the in-memory cache.
- Storage(Type),
-
- /// Cache the query to disk if the `Expr` returns true.
- Cache(Option<IdentOrWild>, Block),
-
- /// Custom code to load the query from disk.
- LoadCached(Ident, Ident, Block),
-
- /// A cycle error for this query aborting the compilation with a fatal error.
- FatalCycle(Ident),
-
- /// A cycle error results in a delay_bug call
- CycleDelayBug(Ident),
-
- /// Don't hash the result, instead just mark a query red if it runs
- NoHash(Ident),
-
- /// Generate a dep node based on the dependencies of the query
- Anon(Ident),
-
- /// Always evaluate the query, ignoring its dependencies
- EvalAlways(Ident),
-
- /// Use a separate query provider for local and extern crates
- SeparateProvideExtern(Ident),
-
- /// Always remap the ParamEnv's constness before hashing and passing to the query provider
- RemapEnvConstness(Ident),
-}
-
-impl Parse for QueryModifier {
- fn parse(input: ParseStream<'_>) -> Result<Self> {
- let modifier: Ident = input.parse()?;
- if modifier == "desc" {
- // Parse a description modifier like:
- // `desc { |tcx| "foo {}", tcx.item_path(key) }`
- let attr_content;
- braced!(attr_content in input);
- let tcx = if attr_content.peek(Token![|]) {
- attr_content.parse::<Token![|]>()?;
- let tcx = attr_content.parse()?;
- attr_content.parse::<Token![|]>()?;
- Some(tcx)
- } else {
- None
- };
- let desc = attr_content.parse_terminated(Expr::parse)?;
- Ok(QueryModifier::Desc(tcx, desc))
- } else if modifier == "cache_on_disk_if" {
- // Parse a cache modifier like:
- // `cache(tcx, value) { |tcx| key.is_local() }`
- let has_args = if let TokenTree::Group(group) = input.fork().parse()? {
- group.delimiter() == Delimiter::Parenthesis
- } else {
- false
- };
- let args = if has_args {
- let args;
- parenthesized!(args in input);
- let tcx = args.parse()?;
- Some(tcx)
- } else {
- None
- };
- let block = input.parse()?;
- Ok(QueryModifier::Cache(args, block))
- } else if modifier == "load_cached" {
- // Parse a load_cached modifier like:
- // `load_cached(tcx, id) { tcx.on_disk_cache.try_load_query_result(tcx, id) }`
- let args;
- parenthesized!(args in input);
- let tcx = args.parse()?;
- args.parse::<Token![,]>()?;
- let id = args.parse()?;
- let block = input.parse()?;
- Ok(QueryModifier::LoadCached(tcx, id, block))
- } else if modifier == "storage" {
- let args;
- parenthesized!(args in input);
- let ty = args.parse()?;
- Ok(QueryModifier::Storage(ty))
- } else if modifier == "fatal_cycle" {
- Ok(QueryModifier::FatalCycle(modifier))
- } else if modifier == "cycle_delay_bug" {
- Ok(QueryModifier::CycleDelayBug(modifier))
- } else if modifier == "no_hash" {
- Ok(QueryModifier::NoHash(modifier))
- } else if modifier == "anon" {
- Ok(QueryModifier::Anon(modifier))
- } else if modifier == "eval_always" {
- Ok(QueryModifier::EvalAlways(modifier))
- } else if modifier == "separate_provide_extern" {
- Ok(QueryModifier::SeparateProvideExtern(modifier))
- } else if modifier == "remap_env_constness" {
- Ok(QueryModifier::RemapEnvConstness(modifier))
- } else {
- Err(Error::new(modifier.span(), "unknown query modifier"))
- }
- }
-}
-
/// Ensures only doc comment attributes are used
fn check_attributes(attrs: Vec<Attribute>) -> Result<Vec<Attribute>> {
let inner = |attr: Attribute| {
@@ -154,16 +32,16 @@ fn check_attributes(attrs: Vec<Attribute>) -> Result<Vec<Attribute>> {
/// A compiler query. `query ... { ... }`
struct Query {
doc_comments: Vec<Attribute>,
- modifiers: List<QueryModifier>,
+ modifiers: QueryModifiers,
name: Ident,
- key: IdentOrWild,
+ key: Pat,
arg: Type,
result: ReturnType,
}
impl Parse for Query {
fn parse(input: ParseStream<'_>) -> Result<Self> {
- let doc_comments = check_attributes(input.call(Attribute::parse_outer)?)?;
+ let mut doc_comments = check_attributes(input.call(Attribute::parse_outer)?)?;
// Parse the query declaration. Like `query type_of(key: DefId) -> Ty<'tcx>`
input.parse::<kw::query>()?;
@@ -178,7 +56,13 @@ impl Parse for Query {
// Parse the query modifiers
let content;
braced!(content in input);
- let modifiers = content.parse()?;
+ let modifiers = parse_query_modifiers(&content)?;
+
+ // If there are no doc-comments, give at least some idea of what
+ // it does by showing the query description.
+ if doc_comments.is_empty() {
+ doc_comments.push(doc_comment_from_desc(&modifiers.desc.1)?);
+ }
Ok(Query { doc_comments, modifiers, name, key, arg, result })
}
@@ -202,13 +86,10 @@ struct QueryModifiers {
desc: (Option<Ident>, Punctuated<Expr, Token![,]>),
/// Use this type for the in-memory cache.
- storage: Option<Type>,
+ arena_cache: Option<Ident>,
/// Cache the query to disk if the `Block` returns true.
- cache: Option<(Option<IdentOrWild>, Block)>,
-
- /// Custom code to load the query from disk.
- load_cached: Option<(Ident, Ident, Block)>,
+ cache: Option<(Option<Pat>, Block)>,
/// A cycle error for this query aborting the compilation with a fatal error.
fatal_cycle: Option<Ident>,
@@ -222,9 +103,12 @@ struct QueryModifiers {
/// Generate a dep node based on the dependencies of the query
anon: Option<Ident>,
- // Always evaluate the query, ignoring its dependencies
+ /// Always evaluate the query, ignoring its dependencies
eval_always: Option<Ident>,
+ /// Whether the query has a call depth limit
+ depth_limit: Option<Ident>,
+
/// Use a separate query provider for local and extern crates
separate_provide_extern: Option<Ident>,
@@ -232,10 +116,8 @@ struct QueryModifiers {
remap_env_constness: Option<Ident>,
}
-/// Process query modifiers into a struct, erroring on duplicates
-fn process_modifiers(query: &mut Query) -> QueryModifiers {
- let mut load_cached = None;
- let mut storage = None;
+fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
+ let mut arena_cache = None;
let mut cache = None;
let mut desc = None;
let mut fatal_cycle = None;
@@ -243,121 +125,77 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
let mut no_hash = None;
let mut anon = None;
let mut eval_always = None;
+ let mut depth_limit = None;
let mut separate_provide_extern = None;
let mut remap_env_constness = None;
- for modifier in query.modifiers.0.drain(..) {
- match modifier {
- QueryModifier::LoadCached(tcx, id, block) => {
- if load_cached.is_some() {
- panic!("duplicate modifier `load_cached` for query `{}`", query.name);
- }
- load_cached = Some((tcx, id, block));
- }
- QueryModifier::Storage(ty) => {
- if storage.is_some() {
- panic!("duplicate modifier `storage` for query `{}`", query.name);
- }
- storage = Some(ty);
- }
- QueryModifier::Cache(args, expr) => {
- if cache.is_some() {
- panic!("duplicate modifier `cache` for query `{}`", query.name);
- }
- cache = Some((args, expr));
- }
- QueryModifier::Desc(tcx, list) => {
- if desc.is_some() {
- panic!("duplicate modifier `desc` for query `{}`", query.name);
- }
- // If there are no doc-comments, give at least some idea of what
- // it does by showing the query description.
- if query.doc_comments.is_empty() {
- use ::syn::*;
- let mut list = list.iter();
- let format_str: String = match list.next() {
- Some(&Expr::Lit(ExprLit { lit: Lit::Str(ref lit_str), .. })) => {
- lit_str.value().replace("`{}`", "{}") // We add them later anyways for consistency
- }
- _ => panic!("Expected a string literal"),
- };
- let mut fmt_fragments = format_str.split("{}");
- let mut doc_string = fmt_fragments.next().unwrap().to_string();
- list.map(::quote::ToTokens::to_token_stream).zip(fmt_fragments).for_each(
- |(tts, next_fmt_fragment)| {
- use ::core::fmt::Write;
- write!(
- &mut doc_string,
- " `{}` {}",
- tts.to_string().replace(" . ", "."),
- next_fmt_fragment,
- )
- .unwrap();
- },
- );
- let doc_string = format!(
- "[query description - consider adding a doc-comment!] {}",
- doc_string
- );
- let comment = parse_quote! {
- #[doc = #doc_string]
- };
- query.doc_comments.push(comment);
- }
- desc = Some((tcx, list));
- }
- QueryModifier::FatalCycle(ident) => {
- if fatal_cycle.is_some() {
- panic!("duplicate modifier `fatal_cycle` for query `{}`", query.name);
- }
- fatal_cycle = Some(ident);
- }
- QueryModifier::CycleDelayBug(ident) => {
- if cycle_delay_bug.is_some() {
- panic!("duplicate modifier `cycle_delay_bug` for query `{}`", query.name);
- }
- cycle_delay_bug = Some(ident);
- }
- QueryModifier::NoHash(ident) => {
- if no_hash.is_some() {
- panic!("duplicate modifier `no_hash` for query `{}`", query.name);
- }
- no_hash = Some(ident);
- }
- QueryModifier::Anon(ident) => {
- if anon.is_some() {
- panic!("duplicate modifier `anon` for query `{}`", query.name);
- }
- anon = Some(ident);
- }
- QueryModifier::EvalAlways(ident) => {
- if eval_always.is_some() {
- panic!("duplicate modifier `eval_always` for query `{}`", query.name);
- }
- eval_always = Some(ident);
- }
- QueryModifier::SeparateProvideExtern(ident) => {
- if separate_provide_extern.is_some() {
- panic!(
- "duplicate modifier `separate_provide_extern` for query `{}`",
- query.name
- );
- }
- separate_provide_extern = Some(ident);
- }
- QueryModifier::RemapEnvConstness(ident) => {
- if remap_env_constness.is_some() {
- panic!("duplicate modifier `remap_env_constness` for query `{}`", query.name);
+
+ while !input.is_empty() {
+ let modifier: Ident = input.parse()?;
+
+ macro_rules! try_insert {
+ ($name:ident = $expr:expr) => {
+ if $name.is_some() {
+ return Err(Error::new(modifier.span(), "duplicate modifier"));
}
- remap_env_constness = Some(ident)
- }
+ $name = Some($expr);
+ };
+ }
+
+ if modifier == "desc" {
+ // Parse a description modifier like:
+ // `desc { |tcx| "foo {}", tcx.item_path(key) }`
+ let attr_content;
+ braced!(attr_content in input);
+ let tcx = if attr_content.peek(Token![|]) {
+ attr_content.parse::<Token![|]>()?;
+ let tcx = attr_content.parse()?;
+ attr_content.parse::<Token![|]>()?;
+ Some(tcx)
+ } else {
+ None
+ };
+ let list = attr_content.parse_terminated(Expr::parse)?;
+ try_insert!(desc = (tcx, list));
+ } else if modifier == "cache_on_disk_if" {
+ // Parse a cache modifier like:
+ // `cache(tcx) { |tcx| key.is_local() }`
+ let args = if input.peek(token::Paren) {
+ let args;
+ parenthesized!(args in input);
+ let tcx = args.parse()?;
+ Some(tcx)
+ } else {
+ None
+ };
+ let block = input.parse()?;
+ try_insert!(cache = (args, block));
+ } else if modifier == "arena_cache" {
+ try_insert!(arena_cache = modifier);
+ } else if modifier == "fatal_cycle" {
+ try_insert!(fatal_cycle = modifier);
+ } else if modifier == "cycle_delay_bug" {
+ try_insert!(cycle_delay_bug = modifier);
+ } else if modifier == "no_hash" {
+ try_insert!(no_hash = modifier);
+ } else if modifier == "anon" {
+ try_insert!(anon = modifier);
+ } else if modifier == "eval_always" {
+ try_insert!(eval_always = modifier);
+ } else if modifier == "depth_limit" {
+ try_insert!(depth_limit = modifier);
+ } else if modifier == "separate_provide_extern" {
+ try_insert!(separate_provide_extern = modifier);
+ } else if modifier == "remap_env_constness" {
+ try_insert!(remap_env_constness = modifier);
+ } else {
+ return Err(Error::new(modifier.span(), "unknown query modifier"));
}
}
- let desc = desc.unwrap_or_else(|| {
- panic!("no description provided for query `{}`", query.name);
- });
- QueryModifiers {
- load_cached,
- storage,
+ let Some(desc) = desc else {
+ return Err(input.error("no description provided"));
+ };
+ Ok(QueryModifiers {
+ arena_cache,
cache,
desc,
fatal_cycle,
@@ -365,43 +203,48 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
no_hash,
anon,
eval_always,
+ depth_limit,
separate_provide_extern,
remap_env_constness,
- }
+ })
+}
+
+fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attribute> {
+ use ::syn::*;
+ let mut iter = list.iter();
+ let format_str: String = match iter.next() {
+ Some(&Expr::Lit(ExprLit { lit: Lit::Str(ref lit_str), .. })) => {
+ lit_str.value().replace("`{}`", "{}") // We add them later anyways for consistency
+ }
+ _ => return Err(Error::new(list.span(), "Expected a string literal")),
+ };
+ let mut fmt_fragments = format_str.split("{}");
+ let mut doc_string = fmt_fragments.next().unwrap().to_string();
+ iter.map(::quote::ToTokens::to_token_stream).zip(fmt_fragments).for_each(
+ |(tts, next_fmt_fragment)| {
+ use ::core::fmt::Write;
+ write!(
+ &mut doc_string,
+ " `{}` {}",
+ tts.to_string().replace(" . ", "."),
+ next_fmt_fragment,
+ )
+ .unwrap();
+ },
+ );
+ let doc_string = format!("[query description - consider adding a doc-comment!] {}", doc_string);
+ Ok(parse_quote! { #[doc = #doc_string] })
}
/// Add the impl of QueryDescription for the query to `impls` if one is requested
-fn add_query_description_impl(
- query: &Query,
- modifiers: QueryModifiers,
- impls: &mut proc_macro2::TokenStream,
-) {
+fn add_query_description_impl(query: &Query, impls: &mut proc_macro2::TokenStream) {
let name = &query.name;
- let key = &query.key.0;
+ let key = &query.key;
+ let modifiers = &query.modifiers;
// Find out if we should cache the query on disk
let cache = if let Some((args, expr)) = modifiers.cache.as_ref() {
- let try_load_from_disk = if let Some((tcx, id, block)) = modifiers.load_cached.as_ref() {
- // Use custom code to load the query from disk
- quote! {
- const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>>
- = Some(|#tcx, #id| { #block });
- }
- } else {
- // Use the default code to load the query from disk
- quote! {
- const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>>
- = Some(|tcx, id| tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id));
- }
- };
-
- let tcx = args
- .as_ref()
- .map(|t| {
- let t = &t.0;
- quote! { #t }
- })
- .unwrap_or_else(|| quote! { _ });
+ let tcx = args.as_ref().map(|t| quote! { #t }).unwrap_or_else(|| quote! { _ });
// expr is a `Block`, meaning that `{ #expr }` gets expanded
// to `{ { stmts... } }`, which triggers the `unused_braces` lint.
quote! {
@@ -410,29 +253,22 @@ fn add_query_description_impl(
fn cache_on_disk(#tcx: TyCtxt<'tcx>, #key: &Self::Key) -> bool {
#expr
}
-
- #try_load_from_disk
}
} else {
- if modifiers.load_cached.is_some() {
- panic!("load_cached modifier on query `{}` without a cache modifier", name);
- }
quote! {
#[inline]
fn cache_on_disk(_: TyCtxt<'tcx>, _: &Self::Key) -> bool {
false
}
-
- const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>> = None;
}
};
- let (tcx, desc) = modifiers.desc;
+ let (tcx, desc) = &modifiers.desc;
let tcx = tcx.as_ref().map_or_else(|| quote! { _ }, |t| quote! { #t });
let desc = quote! {
#[allow(unused_variables)]
- fn describe(tcx: QueryCtxt<$tcx>, key: Self::Key) -> String {
+ fn describe(tcx: QueryCtxt<'tcx>, key: Self::Key) -> String {
let (#tcx, #key) = (*tcx, key);
::rustc_middle::ty::print::with_no_trimmed_paths!(
format!(#desc)
@@ -441,7 +277,7 @@ fn add_query_description_impl(
};
impls.extend(quote! {
- (#name<$tcx:tt>) => {
+ (#name) => {
#desc
#cache
};
@@ -453,13 +289,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
let mut query_stream = quote! {};
let mut query_description_stream = quote! {};
- let mut dep_node_def_stream = quote! {};
let mut cached_queries = quote! {};
- for mut query in queries.0 {
- let modifiers = process_modifiers(&mut query);
- let name = &query.name;
- let arg = &query.arg;
+ for query in queries.0 {
+ let Query { name, arg, modifiers, .. } = &query;
let result_full = &query.result;
let result = match query.result {
ReturnType::Default => quote! { -> () },
@@ -474,38 +307,32 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
let mut attributes = Vec::new();
- // Pass on the fatal_cycle modifier
- if let Some(fatal_cycle) = &modifiers.fatal_cycle {
- attributes.push(quote! { (#fatal_cycle) });
- };
- // Pass on the storage modifier
- if let Some(ref ty) = modifiers.storage {
- let span = ty.span();
- attributes.push(quote_spanned! {span=> (storage #ty) });
- };
- // Pass on the cycle_delay_bug modifier
- if let Some(cycle_delay_bug) = &modifiers.cycle_delay_bug {
- attributes.push(quote! { (#cycle_delay_bug) });
- };
- // Pass on the no_hash modifier
- if let Some(no_hash) = &modifiers.no_hash {
- attributes.push(quote! { (#no_hash) });
- };
- // Pass on the anon modifier
- if let Some(anon) = &modifiers.anon {
- attributes.push(quote! { (#anon) });
- };
- // Pass on the eval_always modifier
- if let Some(eval_always) = &modifiers.eval_always {
- attributes.push(quote! { (#eval_always) });
- };
- // Pass on the separate_provide_extern modifier
- if let Some(separate_provide_extern) = &modifiers.separate_provide_extern {
- attributes.push(quote! { (#separate_provide_extern) });
+ macro_rules! passthrough {
+ ( $( $modifier:ident ),+ $(,)? ) => {
+ $( if let Some($modifier) = &modifiers.$modifier {
+ attributes.push(quote! { (#$modifier) });
+ }; )+
+ }
}
- // Pass on the remap_env_constness modifier
- if let Some(remap_env_constness) = &modifiers.remap_env_constness {
- attributes.push(quote! { (#remap_env_constness) });
+
+ passthrough!(
+ fatal_cycle,
+ arena_cache,
+ cycle_delay_bug,
+ no_hash,
+ anon,
+ eval_always,
+ depth_limit,
+ separate_provide_extern,
+ remap_env_constness,
+ );
+
+ if modifiers.cache.is_some() {
+ attributes.push(quote! { (cache) });
+ }
+ // Pass on the cache modifier
+ if modifiers.cache.is_some() {
+ attributes.push(quote! { (cache) });
}
// This uses the span of the query definition for the commas,
@@ -516,48 +343,27 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
// be very useful.
let span = name.span();
let attribute_stream = quote_spanned! {span=> #(#attributes),*};
- let doc_comments = query.doc_comments.iter();
+ let doc_comments = &query.doc_comments;
// Add the query to the group
query_stream.extend(quote! {
#(#doc_comments)*
[#attribute_stream] fn #name(#arg) #result,
});
- // Create a dep node for the query
- dep_node_def_stream.extend(quote! {
- [#attribute_stream] #name(#arg),
- });
-
- add_query_description_impl(&query, modifiers, &mut query_description_stream);
+ add_query_description_impl(&query, &mut query_description_stream);
}
TokenStream::from(quote! {
#[macro_export]
macro_rules! rustc_query_append {
- ([$($macro:tt)*][$($other:tt)*]) => {
- $($macro)* {
- $($other)*
-
+ ($macro:ident! $( [$($other:tt)*] )?) => {
+ $macro! {
+ $( $($other)* )?
#query_stream
-
}
}
}
- macro_rules! rustc_dep_node_append {
- ([$($macro:tt)*][$($other:tt)*]) => {
- $($macro)*(
- $($other)*
- #dep_node_def_stream
- );
- }
- }
- #[macro_export]
- macro_rules! rustc_cached_queries {
- ($($macro:tt)*) => {
- $($macro)*(#cached_queries);
- }
- }
#[macro_export]
macro_rules! rustc_query_description {
#query_description_stream
diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs
index 1b245f2a7..92590c33b 100644
--- a/compiler/rustc_macros/src/symbols.rs
+++ b/compiler/rustc_macros/src/symbols.rs
@@ -195,10 +195,10 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
#n,
});
}
- let _ = counter; // for future use
let output = quote! {
const SYMBOL_DIGITS_BASE: u32 = #digits_base;
+ const PREINTERNED_SYMBOLS_COUNT: u32 = #counter;
#[doc(hidden)]
#[allow(non_upper_case_globals)]
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 708d0b1fd..cfcceecbe 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -1,5 +1,9 @@
//! Validates all used crates and extern libraries and loads their metadata
+use crate::errors::{
+ ConflictingGlobalAlloc, CrateNotPanicRuntime, GlobalAllocRequired, NoMultipleGlobalAlloc,
+ NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore,
+};
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
@@ -29,7 +33,6 @@ use proc_macro::bridge::client::ProcMacro;
use std::ops::Fn;
use std::path::Path;
use std::{cmp, env};
-use tracing::{debug, info};
#[derive(Clone)]
pub struct CStore {
@@ -263,7 +266,7 @@ impl<'a> CrateLoader<'a> {
fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Option<CrateNum> {
for (cnum, data) in self.cstore.iter_crate_data() {
if data.name() != name {
- tracing::trace!("{} did not match {}", data.name(), name);
+ trace!("{} did not match {}", data.name(), name);
continue;
}
@@ -746,15 +749,10 @@ impl<'a> CrateLoader<'a> {
// Sanity check the loaded crate to ensure it is indeed a panic runtime
// and the panic strategy is indeed what we thought it was.
if !data.is_panic_runtime() {
- self.sess.err(&format!("the crate `{}` is not a panic runtime", name));
+ self.sess.emit_err(CrateNotPanicRuntime { crate_name: name });
}
if data.required_panic_strategy() != Some(desired_strategy) {
- self.sess.err(&format!(
- "the crate `{}` does not have the panic \
- strategy `{}`",
- name,
- desired_strategy.desc()
- ));
+ self.sess.emit_err(NoPanicStrategy { crate_name: name, strategy: desired_strategy });
}
self.cstore.injected_panic_runtime = Some(cnum);
@@ -774,10 +772,7 @@ impl<'a> CrateLoader<'a> {
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) {
- self.sess.err(
- "`profiler_builtins` crate (required by compiler options) \
- is not compatible with crate attribute `#![no_core]`",
- );
+ self.sess.emit_err(ProfilerBuiltinsNeedsCore);
}
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
@@ -785,18 +780,14 @@ impl<'a> CrateLoader<'a> {
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
if !data.is_profiler_runtime() {
- self.sess.err(&format!("the crate `{}` is not a profiler runtime", name));
+ self.sess.emit_err(NotProfilerRuntime { crate_name: name });
}
}
fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
self.cstore.has_global_allocator = match &*global_allocator_spans(&self.sess, krate) {
[span1, span2, ..] => {
- self.sess
- .struct_span_err(*span2, "cannot define multiple global allocators")
- .span_label(*span2, "cannot define a new global allocator")
- .span_label(*span1, "previous global allocator defined here")
- .emit();
+ self.sess.emit_err(NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
true
}
spans => !spans.is_empty(),
@@ -832,11 +823,10 @@ impl<'a> CrateLoader<'a> {
if data.has_global_allocator() {
match global_allocator {
Some(other_crate) => {
- self.sess.err(&format!(
- "the `#[global_allocator]` in {} conflicts with global allocator in: {}",
- other_crate,
- data.name()
- ));
+ self.sess.emit_err(ConflictingGlobalAlloc {
+ crate_name: data.name(),
+ other_crate_name: other_crate,
+ });
}
None => global_allocator = Some(data.name()),
}
@@ -855,10 +845,7 @@ impl<'a> CrateLoader<'a> {
if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator)
&& !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator())
{
- self.sess.err(
- "no global memory allocator found but one is required; link to std or add \
- `#[global_allocator]` to a static item that implements the GlobalAlloc trait",
- );
+ self.sess.emit_err(GlobalAllocRequired);
}
self.cstore.allocator_kind = Some(AllocatorKind::Default);
}
@@ -882,14 +869,11 @@ impl<'a> CrateLoader<'a> {
for dep in self.cstore.crate_dependencies_in_reverse_postorder(krate) {
let data = self.cstore.get_crate_data(dep);
if needs_dep(&data) {
- self.sess.err(&format!(
- "the crate `{}` cannot depend \
- on a crate that needs {}, but \
- it depends on `{}`",
- self.cstore.get_crate_data(krate).name(),
- what,
- data.name()
- ));
+ self.sess.emit_err(NoTransitiveNeedsDep {
+ crate_name: self.cstore.get_crate_data(krate).name(),
+ needs_crate_name: what,
+ deps_crate_name: data.name(),
+ });
}
}
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index b765c34f8..6112ec9e4 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -52,6 +52,10 @@
//! than finding a number of solutions (there are normally quite a few).
use crate::creader::CStore;
+use crate::errors::{
+ BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
+ RequiredPanicStrategy, RlibRequired, TwoPanicRuntimes,
+};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::CrateNum;
@@ -136,11 +140,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
if src.rlib.is_some() {
continue;
}
- sess.err(&format!(
- "crate `{}` required to be available in rlib format, \
- but was not found in this form",
- tcx.crate_name(cnum)
- ));
+ sess.emit_err(RlibRequired { crate_name: tcx.crate_name(cnum) });
}
return Vec::new();
}
@@ -158,11 +158,11 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
let name = tcx.crate_name(cnum);
let src = tcx.used_crate_source(cnum);
if src.dylib.is_some() {
- tracing::info!("adding dylib: {}", name);
+ info!("adding dylib: {}", name);
add_library(tcx, cnum, RequireDynamic, &mut formats);
let deps = tcx.dylib_dependency_formats(cnum);
for &(depnum, style) in deps.iter() {
- tracing::info!("adding {:?}: {}", style, tcx.crate_name(depnum));
+ info!("adding {:?}: {}", style, tcx.crate_name(depnum));
add_library(tcx, depnum, style, &mut formats);
}
}
@@ -190,7 +190,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
&& tcx.dep_kind(cnum) == CrateDepKind::Explicit
{
assert!(src.rlib.is_some() || src.rmeta.is_some());
- tracing::info!("adding staticlib: {}", tcx.crate_name(cnum));
+ info!("adding staticlib: {}", tcx.crate_name(cnum));
add_library(tcx, cnum, RequireStatic, &mut formats);
ret[cnum.as_usize() - 1] = Linkage::Static;
}
@@ -224,12 +224,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
Linkage::Static => "rlib",
_ => "dylib",
};
- sess.err(&format!(
- "crate `{}` required to be available in {} format, \
- but was not found in this form",
- tcx.crate_name(cnum),
- kind
- ));
+ sess.emit_err(LibRequired { crate_name: tcx.crate_name(cnum), kind: kind });
}
}
}
@@ -253,17 +248,7 @@ fn add_library(
// This error is probably a little obscure, but I imagine that it
// can be refined over time.
if link2 != link || link == RequireStatic {
- tcx.sess
- .struct_err(&format!(
- "cannot satisfy dependencies so `{}` only \
- shows up once",
- tcx.crate_name(cnum)
- ))
- .help(
- "having upstream crates all available in one format \
- will likely make this go away",
- )
- .emit();
+ tcx.sess.emit_err(CrateDepMultiple { crate_name: tcx.crate_name(cnum) });
}
}
None => {
@@ -360,11 +345,7 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
if let Some((prev, _)) = panic_runtime {
let prev_name = tcx.crate_name(prev);
let cur_name = tcx.crate_name(cnum);
- sess.err(&format!(
- "cannot link together two \
- panic runtimes: {} and {}",
- prev_name, cur_name
- ));
+ sess.emit_err(TwoPanicRuntimes { prev_name, cur_name });
}
panic_runtime = Some((
cnum,
@@ -384,13 +365,10 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
// First up, validate that our selected panic runtime is indeed exactly
// our same strategy.
if found_strategy != desired_strategy {
- sess.err(&format!(
- "the linked panic runtime `{}` is \
- not compiled with this crate's \
- panic strategy `{}`",
- tcx.crate_name(runtime_cnum),
- desired_strategy.desc()
- ));
+ sess.emit_err(BadPanicStrategy {
+ runtime: tcx.crate_name(runtime_cnum),
+ strategy: desired_strategy,
+ });
}
// Next up, verify that all other crates are compatible with this panic
@@ -407,28 +385,19 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
}
if let Some(found_strategy) = tcx.required_panic_strategy(cnum) && desired_strategy != found_strategy {
- sess.err(&format!(
- "the crate `{}` requires \
- panic strategy `{}` which is \
- incompatible with this crate's \
- strategy of `{}`",
- tcx.crate_name(cnum),
- found_strategy.desc(),
- desired_strategy.desc()
- ));
+ sess.emit_err(RequiredPanicStrategy {
+ crate_name: tcx.crate_name(cnum),
+ found_strategy,
+ desired_strategy});
}
let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
if tcx.sess.opts.unstable_opts.panic_in_drop != found_drop_strategy {
- sess.err(&format!(
- "the crate `{}` is compiled with the \
- panic-in-drop strategy `{}` which is \
- incompatible with this crate's \
- strategy of `{}`",
- tcx.crate_name(cnum),
- found_drop_strategy.desc(),
- tcx.sess.opts.unstable_opts.panic_in_drop.desc()
- ));
+ sess.emit_err(IncompatiblePanicInDropStrategy {
+ crate_name: tcx.crate_name(cnum),
+ found_strategy: found_drop_strategy,
+ desired_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
+ });
}
}
}
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
new file mode 100644
index 000000000..7d63fad32
--- /dev/null
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -0,0 +1,679 @@
+use std::{
+ io::Error,
+ path::{Path, PathBuf},
+};
+
+use rustc_errors::{error_code, ErrorGuaranteed};
+use rustc_macros::SessionDiagnostic;
+use rustc_session::{config, SessionDiagnostic};
+use rustc_span::{sym, Span, Symbol};
+use rustc_target::spec::{PanicStrategy, TargetTriple};
+
+use crate::locator::CrateFlavor;
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::rlib_required)]
+pub struct RlibRequired {
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::lib_required)]
+pub struct LibRequired<'a> {
+ pub crate_name: Symbol,
+ pub kind: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::crate_dep_multiple)]
+#[help]
+pub struct CrateDepMultiple {
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::two_panic_runtimes)]
+pub struct TwoPanicRuntimes {
+ pub prev_name: Symbol,
+ pub cur_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::bad_panic_strategy)]
+pub struct BadPanicStrategy {
+ pub runtime: Symbol,
+ pub strategy: PanicStrategy,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::required_panic_strategy)]
+pub struct RequiredPanicStrategy {
+ pub crate_name: Symbol,
+ pub found_strategy: PanicStrategy,
+ pub desired_strategy: PanicStrategy,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::incompatible_panic_in_drop_strategy)]
+pub struct IncompatiblePanicInDropStrategy {
+ pub crate_name: Symbol,
+ pub found_strategy: PanicStrategy,
+ pub desired_strategy: PanicStrategy,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_names_in_link)]
+pub struct MultipleNamesInLink {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_kinds_in_link)]
+pub struct MultipleKindsInLink {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_name_form)]
+pub struct LinkNameForm {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_kind_form)]
+pub struct LinkKindForm {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_modifiers_form)]
+pub struct LinkModifiersForm {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_cfg_form)]
+pub struct LinkCfgForm {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::wasm_import_form)]
+pub struct WasmImportForm {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::empty_link_name, code = "E0454")]
+pub struct EmptyLinkName {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_framework_apple, code = "E0455")]
+pub struct LinkFrameworkApple {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::framework_only_windows, code = "E0455")]
+pub struct FrameworkOnlyWindows {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::unknown_link_kind, code = "E0458")]
+pub struct UnknownLinkKind<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub kind: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_link_modifiers)]
+pub struct MultipleLinkModifiers {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_cfgs)]
+pub struct MultipleCfgs {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_cfg_single_predicate)]
+pub struct LinkCfgSinglePredicate {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_wasm_import)]
+pub struct MultipleWasmImport {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::unexpected_link_arg)]
+pub struct UnexpectedLinkArg {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::invalid_link_modifier)]
+pub struct InvalidLinkModifier {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_modifiers)]
+pub struct MultipleModifiers<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub modifier: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::bundle_needs_static)]
+pub struct BundleNeedsStatic {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::whole_archive_needs_static)]
+pub struct WholeArchiveNeedsStatic {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::as_needed_compatibility)]
+pub struct AsNeededCompatibility {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::unknown_link_modifier)]
+pub struct UnknownLinkModifier<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub modifier: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::incompatible_wasm_link)]
+pub struct IncompatibleWasmLink {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_requires_name, code = "E0459")]
+pub struct LinkRequiresName {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::raw_dylib_no_nul)]
+pub struct RawDylibNoNul {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::link_ordinal_raw_dylib)]
+pub struct LinkOrdinalRawDylib {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::lib_framework_apple)]
+pub struct LibFrameworkApple;
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::empty_renaming_target)]
+pub struct EmptyRenamingTarget<'a> {
+ pub lib_name: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::renaming_no_link)]
+pub struct RenamingNoLink<'a> {
+ pub lib_name: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_renamings)]
+pub struct MultipleRenamings<'a> {
+ pub lib_name: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::no_link_mod_override)]
+pub struct NoLinkModOverride {
+ #[primary_span]
+ pub span: Option<Span>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::unsupported_abi_i686)]
+pub struct UnsupportedAbiI686 {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::unsupported_abi)]
+pub struct UnsupportedAbi {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::fail_create_file_encoder)]
+pub struct FailCreateFileEncoder {
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::fail_seek_file)]
+pub struct FailSeekFile {
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::fail_write_file)]
+pub struct FailWriteFile {
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::crate_not_panic_runtime)]
+pub struct CrateNotPanicRuntime {
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::no_panic_strategy)]
+pub struct NoPanicStrategy {
+ pub crate_name: Symbol,
+ pub strategy: PanicStrategy,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::profiler_builtins_needs_core)]
+pub struct ProfilerBuiltinsNeedsCore;
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::not_profiler_runtime)]
+pub struct NotProfilerRuntime {
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::no_multiple_global_alloc)]
+pub struct NoMultipleGlobalAlloc {
+ #[primary_span]
+ #[label]
+ pub span2: Span,
+ #[label(metadata::prev_global_alloc)]
+ pub span1: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::conflicting_global_alloc)]
+pub struct ConflictingGlobalAlloc {
+ pub crate_name: Symbol,
+ pub other_crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::global_alloc_required)]
+pub struct GlobalAllocRequired;
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::no_transitive_needs_dep)]
+pub struct NoTransitiveNeedsDep<'a> {
+ pub crate_name: Symbol,
+ pub needs_crate_name: &'a str,
+ pub deps_crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::failed_write_error)]
+pub struct FailedWriteError {
+ pub filename: PathBuf,
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::missing_native_library)]
+pub struct MissingNativeLibrary<'a> {
+ pub libname: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::failed_create_tempdir)]
+pub struct FailedCreateTempdir {
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::failed_create_file)]
+pub struct FailedCreateFile<'a> {
+ pub filename: &'a Path,
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::failed_create_encoded_metadata)]
+pub struct FailedCreateEncodedMetadata {
+ pub err: Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::non_ascii_name)]
+pub struct NonAsciiName {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::extern_location_not_exist)]
+pub struct ExternLocationNotExist<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub location: &'a Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::extern_location_not_file)]
+pub struct ExternLocationNotFile<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub location: &'a Path,
+}
+
+pub(crate) struct MultipleCandidates {
+ pub span: Span,
+ pub flavor: CrateFlavor,
+ pub crate_name: Symbol,
+ pub candidates: Vec<PathBuf>,
+}
+
+impl SessionDiagnostic<'_> for MultipleCandidates {
+ fn into_diagnostic(
+ self,
+ handler: &'_ rustc_errors::Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = handler.struct_err(rustc_errors::fluent::metadata::multiple_candidates);
+ diag.set_arg("crate_name", self.crate_name);
+ diag.set_arg("flavor", self.flavor);
+ diag.code(error_code!(E0465));
+ diag.set_span(self.span);
+ for (i, candidate) in self.candidates.iter().enumerate() {
+ diag.span_note(self.span, &format!("candidate #{}: {}", i + 1, candidate.display()));
+ }
+ diag
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_matching_crates, code = "E0464")]
+#[note]
+pub struct MultipleMatchingCrates {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub candidates: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::symbol_conflicts_current, code = "E0519")]
+pub struct SymbolConflictsCurrent {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::symbol_conflicts_others, code = "E0523")]
+pub struct SymbolConflictsOthers {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::stable_crate_id_collision)]
+pub struct StableCrateIdCollision {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name0: Symbol,
+ pub crate_name1: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::dl_error)]
+pub struct DlError {
+ #[primary_span]
+ pub span: Span,
+ pub err: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::newer_crate_version, code = "E0460")]
+#[note]
+#[note(metadata::found_crate_versions)]
+pub struct NewerCrateVersion {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub add_info: String,
+ pub found_crates: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::no_crate_with_triple, code = "E0461")]
+#[note(metadata::found_crate_versions)]
+pub struct NoCrateWithTriple<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub locator_triple: &'a str,
+ pub add_info: String,
+ pub found_crates: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::found_staticlib, code = "E0462")]
+#[note(metadata::found_crate_versions)]
+#[help]
+pub struct FoundStaticlib {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub add_info: String,
+ pub found_crates: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::incompatible_rustc, code = "E0514")]
+#[note(metadata::found_crate_versions)]
+#[help]
+pub struct IncompatibleRustc {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub add_info: String,
+ pub found_crates: String,
+ pub rustc_version: String,
+}
+
+pub struct InvalidMetadataFiles {
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub add_info: String,
+ pub crate_rejections: Vec<String>,
+}
+
+impl SessionDiagnostic<'_> for InvalidMetadataFiles {
+ fn into_diagnostic(
+ self,
+ handler: &'_ rustc_errors::Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = handler.struct_err(rustc_errors::fluent::metadata::invalid_meta_files);
+ diag.set_arg("crate_name", self.crate_name);
+ diag.set_arg("add_info", self.add_info);
+ diag.code(error_code!(E0786));
+ diag.set_span(self.span);
+ for crate_rejection in self.crate_rejections {
+ diag.note(crate_rejection);
+ }
+ diag
+ }
+}
+
+pub struct CannotFindCrate {
+ pub span: Span,
+ pub crate_name: Symbol,
+ pub add_info: String,
+ pub missing_core: bool,
+ pub current_crate: String,
+ pub is_nightly_build: bool,
+ pub profiler_runtime: Symbol,
+ pub locator_triple: TargetTriple,
+}
+
+impl SessionDiagnostic<'_> for CannotFindCrate {
+ fn into_diagnostic(
+ self,
+ handler: &'_ rustc_errors::Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = handler.struct_err(rustc_errors::fluent::metadata::cannot_find_crate);
+ diag.set_arg("crate_name", self.crate_name);
+ diag.set_arg("current_crate", self.current_crate);
+ diag.set_arg("add_info", self.add_info);
+ diag.set_arg("locator_triple", self.locator_triple.triple());
+ diag.code(error_code!(E0463));
+ diag.set_span(self.span);
+ if (self.crate_name == sym::std || self.crate_name == sym::core)
+ && self.locator_triple != TargetTriple::from_triple(config::host_triple())
+ {
+ if self.missing_core {
+ diag.note(rustc_errors::fluent::metadata::target_not_installed);
+ } else {
+ diag.note(rustc_errors::fluent::metadata::target_no_std_support);
+ }
+ // NOTE: this suggests using rustup, even though the user may not have it installed.
+ // That's because they could choose to install it; or this may give them a hint which
+ // target they need to install from their distro.
+ if self.missing_core {
+ diag.help(rustc_errors::fluent::metadata::consider_downloading_target);
+ }
+ // Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
+ // NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
+ // If it's not a dummy, that means someone added `extern crate std` explicitly and
+ // `#![no_std]` won't help.
+ if !self.missing_core && self.span.is_dummy() {
+ diag.note(rustc_errors::fluent::metadata::std_required);
+ }
+ if self.is_nightly_build {
+ diag.help(rustc_errors::fluent::metadata::consider_building_std);
+ }
+ } else if self.crate_name == self.profiler_runtime {
+ diag.note(rustc_errors::fluent::metadata::compiler_missing_profiler);
+ } else if self.crate_name.as_str().starts_with("rustc_") {
+ diag.help(rustc_errors::fluent::metadata::install_missing_components);
+ }
+ diag.span_label(self.span, rustc_errors::fluent::metadata::cant_find_crate);
+ diag
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::no_dylib_plugin, code = "E0457")]
+pub struct NoDylibPlugin {
+ #[primary_span]
+ pub span: Span,
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::crate_location_unknown_type)]
+pub struct CrateLocationUnknownType<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub path: &'a Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::lib_filename_form)]
+pub struct LibFilenameForm<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub dll_prefix: &'a str,
+ pub dll_suffix: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::multiple_import_name_type)]
+pub struct MultipleImportNameType {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::import_name_type_form)]
+pub struct ImportNameTypeForm {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::import_name_type_x86)]
+pub struct ImportNameTypeX86 {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::unknown_import_name_type)]
+pub struct UnknownImportNameType<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub import_name_type: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(metadata::import_name_type_raw)]
+pub struct ImportNameTypeRaw {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs
index e6072901a..f360a5864 100644
--- a/compiler/rustc_metadata/src/fs.rs
+++ b/compiler/rustc_metadata/src/fs.rs
@@ -1,3 +1,6 @@
+use crate::errors::{
+ FailedCreateEncodedMetadata, FailedCreateFile, FailedCreateTempdir, FailedWriteError,
+};
use crate::{encode_metadata, EncodedMetadata};
use rustc_data_structures::temp_dir::MaybeTempDir;
@@ -23,8 +26,8 @@ pub fn emit_metadata(sess: &Session, metadata: &[u8], tmpdir: &MaybeTempDir) ->
let out_filename = tmpdir.as_ref().join(METADATA_FILENAME);
let result = fs::write(&out_filename, metadata);
- if let Err(e) = result {
- sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
+ if let Err(err) = result {
+ sess.emit_fatal(FailedWriteError { filename: out_filename, err });
}
out_filename
@@ -65,7 +68,7 @@ pub fn encode_and_write_metadata(
let metadata_tmpdir = TempFileBuilder::new()
.prefix("rmeta")
.tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new("")))
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailedCreateTempdir { err }));
let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME);
@@ -73,12 +76,8 @@ pub fn encode_and_write_metadata(
// This simplifies the creation of the output `out_filename` when requested.
match metadata_kind {
MetadataKind::None => {
- std::fs::File::create(&metadata_filename).unwrap_or_else(|e| {
- tcx.sess.fatal(&format!(
- "failed to create the file {}: {}",
- metadata_filename.display(),
- e
- ))
+ std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {
+ tcx.sess.emit_fatal(FailedCreateFile { filename: &metadata_filename, err });
});
}
MetadataKind::Uncompressed | MetadataKind::Compressed => {
@@ -93,8 +92,8 @@ pub fn encode_and_write_metadata(
// this file always exists.
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
- if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) {
- tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
+ if let Err(err) = non_durable_rename(&metadata_filename, &out_filename) {
+ tcx.sess.emit_fatal(FailedWriteError { filename: out_filename, err });
}
if tcx.sess.opts.json_artifact_notifications {
tcx.sess
@@ -109,8 +108,8 @@ pub fn encode_and_write_metadata(
// Load metadata back to memory: codegen may need to include it in object files.
let metadata =
- EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|e| {
- tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e))
+ EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|err| {
+ tcx.sess.emit_fatal(FailedCreateEncodedMetadata { err });
});
let need_metadata_module = metadata_kind == MetadataKind::Compressed;
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 6440f3e39..6f5604b7e 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -2,10 +2,10 @@
#![feature(decl_macro)]
#![feature(drain_filter)]
#![feature(generators)]
-#![feature(generic_associated_types)]
+#![cfg_attr(bootstrap, feature(generic_associated_types))]
#![feature(iter_from_generator)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![feature(proc_macro_internals)]
#![feature(macro_metavar_expr)]
@@ -16,6 +16,8 @@
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
extern crate proc_macro;
@@ -26,6 +28,9 @@ extern crate rustc_middle;
#[macro_use]
extern crate rustc_data_structures;
+#[macro_use]
+extern crate tracing;
+
pub use rmeta::{provide, provide_extern};
mod dependency_format;
@@ -34,8 +39,10 @@ mod native_libs;
mod rmeta;
pub mod creader;
+pub mod errors;
pub mod fs;
pub mod locator;
pub use fs::{emit_metadata, METADATA_FILENAME};
+pub use native_libs::find_native_static_library;
pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 2c1c84b0b..35f9ef92a 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -213,6 +213,13 @@
//! metadata::locator or metadata::creader for all the juicy details!
use crate::creader::Library;
+use crate::errors::{
+ CannotFindCrate, CrateLocationUnknownType, DlError, ExternLocationNotExist,
+ ExternLocationNotFile, FoundStaticlib, IncompatibleRustc, InvalidMetadataFiles,
+ LibFilenameForm, MultipleCandidates, MultipleMatchingCrates, NewerCrateVersion,
+ NoCrateWithTriple, NoDylibPlugin, NonAsciiName, StableCrateIdCollision, SymbolConflictsCurrent,
+ SymbolConflictsOthers,
+};
use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -220,23 +227,23 @@ use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef;
-use rustc_errors::{struct_span_err, FatalError};
+use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
use rustc_session::config::{self, CrateType};
use rustc_session::cstore::{CrateSource, MetadataLoader};
use rustc_session::filesearch::FileSearch;
use rustc_session::search_paths::PathKind;
use rustc_session::utils::CanonicalizedPath;
use rustc_session::Session;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::Symbol;
use rustc_span::Span;
use rustc_target::spec::{Target, TargetTriple};
use snap::read::FrameDecoder;
+use std::borrow::Cow;
use std::fmt::Write as _;
use std::io::{Read, Result as IoResult, Write};
use std::path::{Path, PathBuf};
use std::{cmp, fmt, fs};
-use tracing::{debug, info};
#[derive(Clone)]
pub(crate) struct CrateLocator<'a> {
@@ -288,6 +295,16 @@ impl fmt::Display for CrateFlavor {
}
}
+impl IntoDiagnosticArg for CrateFlavor {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ match self {
+ CrateFlavor::Rlib => DiagnosticArgValue::Str(Cow::Borrowed("rlib")),
+ CrateFlavor::Rmeta => DiagnosticArgValue::Str(Cow::Borrowed("rmeta")),
+ CrateFlavor::Dylib => DiagnosticArgValue::Str(Cow::Borrowed("dylib")),
+ }
+ }
+}
+
impl<'a> CrateLocator<'a> {
pub(crate) fn new(
sess: &'a Session,
@@ -938,41 +955,20 @@ impl fmt::Display for MetadataError<'_> {
impl CrateError {
pub(crate) fn report(self, sess: &Session, span: Span, missing_core: bool) {
- let mut diag = match self {
- CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
- span,
- &format!("cannot load a crate with a non-ascii name `{}`", crate_name),
- ),
- CrateError::ExternLocationNotExist(crate_name, loc) => sess.struct_span_err(
- span,
- &format!("extern location for {} does not exist: {}", crate_name, loc.display()),
- ),
- CrateError::ExternLocationNotFile(crate_name, loc) => sess.struct_span_err(
- span,
- &format!("extern location for {} is not a file: {}", crate_name, loc.display()),
- ),
+ match self {
+ CrateError::NonAsciiName(crate_name) => {
+ sess.emit_err(NonAsciiName { span, crate_name });
+ }
+ CrateError::ExternLocationNotExist(crate_name, loc) => {
+ sess.emit_err(ExternLocationNotExist { span, crate_name, location: &loc });
+ }
+ CrateError::ExternLocationNotFile(crate_name, loc) => {
+ sess.emit_err(ExternLocationNotFile { span, crate_name, location: &loc });
+ }
CrateError::MultipleCandidates(crate_name, flavor, candidates) => {
- let mut err = struct_span_err!(
- sess,
- span,
- E0465,
- "multiple {} candidates for `{}` found",
- flavor,
- crate_name,
- );
- for (i, candidate) in candidates.iter().enumerate() {
- err.span_note(span, &format!("candidate #{}: {}", i + 1, candidate.display()));
- }
- err
+ sess.emit_err(MultipleCandidates { span, flavor: flavor, crate_name, candidates });
}
CrateError::MultipleMatchingCrates(crate_name, libraries) => {
- let mut err = struct_span_err!(
- sess,
- span,
- E0464,
- "multiple matching crates for `{}`",
- crate_name
- );
let mut libraries: Vec<_> = libraries.into_values().collect();
// Make ordering of candidates deterministic.
// This has to `clone()` to work around lifetime restrictions with `sort_by_key()`.
@@ -1000,223 +996,142 @@ impl CrateError {
s
})
.collect::<String>();
- err.note(&format!("candidates:{}", candidates));
- err
+ sess.emit_err(MultipleMatchingCrates { span, crate_name, candidates });
+ }
+ CrateError::SymbolConflictsCurrent(root_name) => {
+ sess.emit_err(SymbolConflictsCurrent { span, crate_name: root_name });
+ }
+ CrateError::SymbolConflictsOthers(root_name) => {
+ sess.emit_err(SymbolConflictsOthers { span, crate_name: root_name });
}
- CrateError::SymbolConflictsCurrent(root_name) => struct_span_err!(
- sess,
- span,
- E0519,
- "the current crate is indistinguishable from one of its dependencies: it has the \
- same crate-name `{}` and was compiled with the same `-C metadata` arguments. \
- This will result in symbol conflicts between the two.",
- root_name,
- ),
- CrateError::SymbolConflictsOthers(root_name) => struct_span_err!(
- sess,
- span,
- E0523,
- "found two different crates with name `{}` that are not distinguished by differing \
- `-C metadata`. This will result in symbol conflicts between the two.",
- root_name,
- ),
CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
- let msg = format!(
- "found crates (`{}` and `{}`) with colliding StableCrateId values.",
- crate_name0, crate_name1
- );
- sess.struct_span_err(span, &msg)
+ sess.emit_err(StableCrateIdCollision {
+ span,
+ crate_name0: crate_name0,
+ crate_name1: crate_name1,
+ });
+ }
+ CrateError::DlOpen(s) | CrateError::DlSym(s) => {
+ sess.emit_err(DlError { span, err: s });
}
- CrateError::DlOpen(s) | CrateError::DlSym(s) => sess.struct_span_err(span, &s),
CrateError::LocatorCombined(locator) => {
let crate_name = locator.crate_name;
- let add = match &locator.root {
+ let add_info = match &locator.root {
None => String::new(),
Some(r) => format!(" which `{}` depends on", r.name),
};
- let mut msg = "the following crate versions were found:".to_string();
- let mut err = if !locator.crate_rejections.via_hash.is_empty() {
- let mut err = struct_span_err!(
- sess,
- span,
- E0460,
- "found possibly newer version of crate `{}`{}",
- crate_name,
- add,
- );
- err.note("perhaps that crate needs to be recompiled?");
+ // FIXME: There are no tests for CrateLocationUnknownType or LibFilenameForm
+ if !locator.crate_rejections.via_filename.is_empty() {
+ let mismatches = locator.crate_rejections.via_filename.iter();
+ for CrateMismatch { path, .. } in mismatches {
+ sess.emit_err(CrateLocationUnknownType { span, path: &path });
+ sess.emit_err(LibFilenameForm {
+ span,
+ dll_prefix: &locator.dll_prefix,
+ dll_suffix: &locator.dll_suffix,
+ });
+ }
+ }
+ let mut found_crates = String::new();
+ if !locator.crate_rejections.via_hash.is_empty() {
let mismatches = locator.crate_rejections.via_hash.iter();
for CrateMismatch { path, .. } in mismatches {
- msg.push_str(&format!("\ncrate `{}`: {}", crate_name, path.display()));
+ found_crates.push_str(&format!(
+ "\ncrate `{}`: {}",
+ crate_name,
+ path.display()
+ ));
}
if let Some(r) = locator.root {
for path in r.source.paths() {
- msg.push_str(&format!("\ncrate `{}`: {}", r.name, path.display()));
+ found_crates.push_str(&format!(
+ "\ncrate `{}`: {}",
+ r.name,
+ path.display()
+ ));
}
}
- err.note(&msg);
- err
- } else if !locator.crate_rejections.via_triple.is_empty() {
- let mut err = struct_span_err!(
- sess,
+ sess.emit_err(NewerCrateVersion {
span,
- E0461,
- "couldn't find crate `{}` with expected target triple {}{}",
- crate_name,
- locator.triple,
- add,
- );
+ crate_name: crate_name,
+ add_info,
+ found_crates,
+ });
+ } else if !locator.crate_rejections.via_triple.is_empty() {
let mismatches = locator.crate_rejections.via_triple.iter();
for CrateMismatch { path, got } in mismatches {
- msg.push_str(&format!(
+ found_crates.push_str(&format!(
"\ncrate `{}`, target triple {}: {}",
crate_name,
got,
path.display(),
));
}
- err.note(&msg);
- err
- } else if !locator.crate_rejections.via_kind.is_empty() {
- let mut err = struct_span_err!(
- sess,
+ sess.emit_err(NoCrateWithTriple {
span,
- E0462,
- "found staticlib `{}` instead of rlib or dylib{}",
- crate_name,
- add,
- );
- err.help("please recompile that crate using --crate-type lib");
+ crate_name: crate_name,
+ locator_triple: locator.triple.triple(),
+ add_info,
+ found_crates,
+ });
+ } else if !locator.crate_rejections.via_kind.is_empty() {
let mismatches = locator.crate_rejections.via_kind.iter();
for CrateMismatch { path, .. } in mismatches {
- msg.push_str(&format!("\ncrate `{}`: {}", crate_name, path.display()));
+ found_crates.push_str(&format!(
+ "\ncrate `{}`: {}",
+ crate_name,
+ path.display()
+ ));
}
- err.note(&msg);
- err
+ sess.emit_err(FoundStaticlib { span, crate_name, add_info, found_crates });
} else if !locator.crate_rejections.via_version.is_empty() {
- let mut err = struct_span_err!(
- sess,
- span,
- E0514,
- "found crate `{}` compiled by an incompatible version of rustc{}",
- crate_name,
- add,
- );
- err.help(&format!(
- "please recompile that crate using this compiler ({}) \
- (consider running `cargo clean` first)",
- rustc_version(),
- ));
let mismatches = locator.crate_rejections.via_version.iter();
for CrateMismatch { path, got } in mismatches {
- msg.push_str(&format!(
+ found_crates.push_str(&format!(
"\ncrate `{}` compiled by {}: {}",
crate_name,
got,
path.display(),
));
}
- err.note(&msg);
- err
- } else if !locator.crate_rejections.via_invalid.is_empty() {
- let mut err = struct_span_err!(
- sess,
+ sess.emit_err(IncompatibleRustc {
span,
- E0786,
- "found invalid metadata files for crate `{}`{}",
crate_name,
- add,
- );
+ add_info,
+ found_crates,
+ rustc_version: rustc_version(),
+ });
+ } else if !locator.crate_rejections.via_invalid.is_empty() {
+ let mut crate_rejections = Vec::new();
for CrateMismatch { path: _, got } in locator.crate_rejections.via_invalid {
- err.note(&got);
+ crate_rejections.push(got);
}
- err
+ sess.emit_err(InvalidMetadataFiles {
+ span,
+ crate_name,
+ add_info,
+ crate_rejections,
+ });
} else {
- let mut err = struct_span_err!(
- sess,
+ sess.emit_err(CannotFindCrate {
span,
- E0463,
- "can't find crate for `{}`{}",
crate_name,
- add,
- );
-
- if (crate_name == sym::std || crate_name == sym::core)
- && locator.triple != TargetTriple::from_triple(config::host_triple())
- {
- if missing_core {
- err.note(&format!(
- "the `{}` target may not be installed",
- locator.triple
- ));
- } else {
- err.note(&format!(
- "the `{}` target may not support the standard library",
- locator.triple
- ));
- }
- // NOTE: this suggests using rustup, even though the user may not have it installed.
- // That's because they could choose to install it; or this may give them a hint which
- // target they need to install from their distro.
- if missing_core {
- err.help(&format!(
- "consider downloading the target with `rustup target add {}`",
- locator.triple
- ));
- }
- // Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
- // NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
- // If it's not a dummy, that means someone added `extern crate std` explicitly and `#![no_std]` won't help.
- if !missing_core && span.is_dummy() {
- let current_crate =
- sess.opts.crate_name.as_deref().unwrap_or("<unknown>");
- err.note(&format!(
- "`std` is required by `{}` because it does not declare `#![no_std]`",
- current_crate
- ));
- }
- if sess.is_nightly_build() {
- err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
- }
- } else if crate_name
- == Symbol::intern(&sess.opts.unstable_opts.profiler_runtime)
- {
- err.note("the compiler may have been built without the profiler runtime");
- } else if crate_name.as_str().starts_with("rustc_") {
- err.help(
- "maybe you need to install the missing components with: \
- `rustup component add rust-src rustc-dev llvm-tools-preview`",
- );
- }
- err.span_label(span, "can't find crate");
- err
- };
-
- if !locator.crate_rejections.via_filename.is_empty() {
- let mismatches = locator.crate_rejections.via_filename.iter();
- for CrateMismatch { path, .. } in mismatches {
- err.note(&format!(
- "extern location for {} is of an unknown type: {}",
- crate_name,
- path.display(),
- ))
- .help(&format!(
- "file name should be lib*.rlib or {}*.{}",
- locator.dll_prefix, locator.dll_suffix
- ));
- }
+ add_info,
+ missing_core,
+ current_crate: sess
+ .opts
+ .crate_name
+ .clone()
+ .unwrap_or("<unknown>".to_string()),
+ is_nightly_build: sess.is_nightly_build(),
+ profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime),
+ locator_triple: locator.triple,
+ });
}
- err
}
- CrateError::NonDylibPlugin(crate_name) => struct_span_err!(
- sess,
- span,
- E0457,
- "plugin `{}` only found in rlib format, but must be available in dylib format",
- crate_name,
- ),
- };
-
- diag.emit();
+ CrateError::NonDylibPlugin(crate_name) => {
+ sess.emit_err(NoDylibPlugin { span, crate_name });
+ }
+ }
}
}
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 9f6079ecb..257741c13 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -1,17 +1,83 @@
use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
-use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib};
+use rustc_session::config::CrateType;
+use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType};
use rustc_session::parse::feature_err;
+use rustc_session::search_paths::PathKind;
use rustc_session::utils::NativeLibKind;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_target::spec::abi::Abi;
+use crate::errors::{
+ AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, EmptyRenamingTarget,
+ FrameworkOnlyWindows, ImportNameTypeForm, ImportNameTypeRaw, ImportNameTypeX86,
+ IncompatibleWasmLink, InvalidLinkModifier, LibFrameworkApple, LinkCfgForm,
+ LinkCfgSinglePredicate, LinkFrameworkApple, LinkKindForm, LinkModifiersForm, LinkNameForm,
+ LinkOrdinalRawDylib, LinkRequiresName, MissingNativeLibrary, MultipleCfgs,
+ MultipleImportNameType, MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers,
+ MultipleNamesInLink, MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul,
+ RenamingNoLink, UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier,
+ UnsupportedAbi, UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic,
+};
+
+use std::path::PathBuf;
+
+pub fn find_native_static_library(
+ name: &str,
+ verbatim: Option<bool>,
+ search_paths: &[PathBuf],
+ sess: &Session,
+) -> PathBuf {
+ let verbatim = verbatim.unwrap_or(false);
+ // On Windows, static libraries sometimes show up as libfoo.a and other
+ // times show up as foo.lib
+ let oslibname = if verbatim {
+ name.to_string()
+ } else {
+ format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
+ };
+ let unixlibname = format!("lib{}.a", name);
+
+ for path in search_paths {
+ let test = path.join(&oslibname);
+ if test.exists() {
+ return test;
+ }
+ if oslibname != unixlibname {
+ let test = path.join(&unixlibname);
+ if test.exists() {
+ return test;
+ }
+ }
+ }
+ sess.emit_fatal(MissingNativeLibrary { libname: name });
+}
+
+fn find_bundled_library(
+ name: Option<Symbol>,
+ verbatim: Option<bool>,
+ kind: NativeLibKind,
+ sess: &Session,
+) -> Option<Symbol> {
+ if sess.opts.unstable_opts.packed_bundled_libs &&
+ sess.crate_types().iter().any(|ct| ct == &CrateType::Rlib || ct == &CrateType::Staticlib) &&
+ let NativeLibKind::Static { bundle: Some(true) | None, .. } = kind {
+ find_native_static_library(
+ name.unwrap().as_str(),
+ verbatim,
+ &sess.target_filesearch(PathKind::Native).search_path_dirs(),
+ sess,
+ ).file_name().and_then(|s| s.to_str()).map(Symbol::intern)
+ } else {
+ None
+ }
+}
+
pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
let mut collector = Collector { tcx, libs: Vec::new() };
for id in tcx.hir().items() {
@@ -61,36 +127,31 @@ impl<'tcx> Collector<'tcx> {
let mut modifiers = None;
let mut cfg = None;
let mut wasm_import_module = None;
+ let mut import_name_type = None;
for item in items.iter() {
match item.name_or_empty() {
sym::name => {
if name.is_some() {
- let msg = "multiple `name` arguments in a single `#[link]` attribute";
- sess.span_err(item.span(), msg);
+ sess.emit_err(MultipleNamesInLink { span: item.span() });
continue;
}
let Some(link_name) = item.value_str() else {
- let msg = "link name must be of the form `name = \"string\"`";
- sess.span_err(item.span(), msg);
+ sess.emit_err(LinkNameForm { span: item.span() });
continue;
};
let span = item.name_value_literal_span().unwrap();
if link_name.is_empty() {
- struct_span_err!(sess, span, E0454, "link name must not be empty")
- .span_label(span, "empty link name")
- .emit();
+ sess.emit_err(EmptyLinkName { span });
}
name = Some((link_name, span));
}
sym::kind => {
if kind.is_some() {
- let msg = "multiple `kind` arguments in a single `#[link]` attribute";
- sess.span_err(item.span(), msg);
+ sess.emit_err(MultipleKindsInLink { span: item.span() });
continue;
}
let Some(link_kind) = item.value_str() else {
- let msg = "link kind must be of the form `kind = \"string\"`";
- sess.span_err(item.span(), msg);
+ sess.emit_err(LinkKindForm { span: item.span() });
continue;
};
@@ -100,44 +161,26 @@ impl<'tcx> Collector<'tcx> {
"dylib" => NativeLibKind::Dylib { as_needed: None },
"framework" => {
if !sess.target.is_like_osx {
- struct_span_err!(
- sess,
- span,
- E0455,
- "link kind `framework` is only supported on Apple targets"
- )
- .emit();
+ sess.emit_err(LinkFrameworkApple { span });
}
NativeLibKind::Framework { as_needed: None }
}
"raw-dylib" => {
if !sess.target.is_like_windows {
- struct_span_err!(
- sess,
- span,
- E0455,
- "link kind `raw-dylib` is only supported on Windows targets"
- )
- .emit();
- } else if !features.raw_dylib {
+ sess.emit_err(FrameworkOnlyWindows { span });
+ } else if !features.raw_dylib && sess.target.arch == "x86" {
feature_err(
&sess.parse_sess,
sym::raw_dylib,
span,
- "link kind `raw-dylib` is unstable",
+ "link kind `raw-dylib` is unstable on x86",
)
.emit();
}
NativeLibKind::RawDylib
}
kind => {
- let msg = format!(
- "unknown link kind `{kind}`, expected one of: \
- static, dylib, framework, raw-dylib"
- );
- struct_span_err!(sess, span, E0458, "{}", msg)
- .span_label(span, "unknown link kind")
- .emit();
+ sess.emit_err(UnknownLinkKind { span, kind });
continue;
}
};
@@ -145,32 +188,26 @@ impl<'tcx> Collector<'tcx> {
}
sym::modifiers => {
if modifiers.is_some() {
- let msg =
- "multiple `modifiers` arguments in a single `#[link]` attribute";
- sess.span_err(item.span(), msg);
+ sess.emit_err(MultipleLinkModifiers { span: item.span() });
continue;
}
let Some(link_modifiers) = item.value_str() else {
- let msg = "link modifiers must be of the form `modifiers = \"string\"`";
- sess.span_err(item.span(), msg);
+ sess.emit_err(LinkModifiersForm { span: item.span() });
continue;
};
modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
}
sym::cfg => {
if cfg.is_some() {
- let msg = "multiple `cfg` arguments in a single `#[link]` attribute";
- sess.span_err(item.span(), msg);
+ sess.emit_err(MultipleCfgs { span: item.span() });
continue;
}
let Some(link_cfg) = item.meta_item_list() else {
- let msg = "link cfg must be of the form `cfg(/* predicate */)`";
- sess.span_err(item.span(), msg);
+ sess.emit_err(LinkCfgForm { span: item.span() });
continue;
};
let [NestedMetaItem::MetaItem(link_cfg)] = link_cfg else {
- let msg = "link cfg must have a single predicate argument";
- sess.span_err(item.span(), msg);
+ sess.emit_err(LinkCfgSinglePredicate { span: item.span() });
continue;
};
if !features.link_cfg {
@@ -186,23 +223,55 @@ impl<'tcx> Collector<'tcx> {
}
sym::wasm_import_module => {
if wasm_import_module.is_some() {
- let msg = "multiple `wasm_import_module` arguments \
- in a single `#[link]` attribute";
- sess.span_err(item.span(), msg);
+ sess.emit_err(MultipleWasmImport { span: item.span() });
continue;
}
let Some(link_wasm_import_module) = item.value_str() else {
- let msg = "wasm import module must be of the form \
- `wasm_import_module = \"string\"`";
- sess.span_err(item.span(), msg);
+ sess.emit_err(WasmImportForm { span: item.span() });
continue;
};
wasm_import_module = Some((link_wasm_import_module, item.span()));
}
+ sym::import_name_type => {
+ if import_name_type.is_some() {
+ sess.emit_err(MultipleImportNameType { span: item.span() });
+ continue;
+ }
+ let Some(link_import_name_type) = item.value_str() else {
+ sess.emit_err(ImportNameTypeForm { span: item.span() });
+ continue;
+ };
+ if self.tcx.sess.target.arch != "x86" {
+ sess.emit_err(ImportNameTypeX86 { span: item.span() });
+ continue;
+ }
+
+ let link_import_name_type = match link_import_name_type.as_str() {
+ "decorated" => PeImportNameType::Decorated,
+ "noprefix" => PeImportNameType::NoPrefix,
+ "undecorated" => PeImportNameType::Undecorated,
+ import_name_type => {
+ sess.emit_err(UnknownImportNameType {
+ span: item.span(),
+ import_name_type,
+ });
+ continue;
+ }
+ };
+ if !features.raw_dylib {
+ let span = item.name_value_literal_span().unwrap();
+ feature_err(
+ &sess.parse_sess,
+ sym::raw_dylib,
+ span,
+ "import name type is unstable",
+ )
+ .emit();
+ }
+ import_name_type = Some((link_import_name_type, item.span()));
+ }
_ => {
- let msg = "unexpected `#[link]` argument, expected one of: \
- name, kind, modifiers, cfg, wasm_import_module";
- sess.span_err(item.span(), msg);
+ sess.emit_err(UnexpectedLinkArg { span: item.span() });
}
}
}
@@ -214,11 +283,7 @@ impl<'tcx> Collector<'tcx> {
let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
Some(m) => (m, modifier.starts_with('+')),
None => {
- sess.span_err(
- span,
- "invalid linking modifier syntax, expected '+' or '-' prefix \
- before one of: bundle, verbatim, whole-archive, as-needed",
- );
+ sess.emit_err(InvalidLinkModifier { span });
continue;
}
};
@@ -236,10 +301,7 @@ impl<'tcx> Collector<'tcx> {
}
let assign_modifier = |dst: &mut Option<bool>| {
if dst.is_some() {
- let msg = format!(
- "multiple `{modifier}` modifiers in a single `modifiers` argument"
- );
- sess.span_err(span, &msg);
+ sess.emit_err(MultipleModifiers { span, modifier });
} else {
*dst = Some(value);
}
@@ -249,11 +311,7 @@ impl<'tcx> Collector<'tcx> {
assign_modifier(bundle)
}
("bundle", _) => {
- sess.span_err(
- span,
- "linking modifier `bundle` is only compatible with \
- `static` linking kind",
- );
+ sess.emit_err(BundleNeedsStatic { span });
}
("verbatim", _) => {
@@ -265,11 +323,7 @@ impl<'tcx> Collector<'tcx> {
assign_modifier(whole_archive)
}
("whole-archive", _) => {
- sess.span_err(
- span,
- "linking modifier `whole-archive` is only compatible with \
- `static` linking kind",
- );
+ sess.emit_err(WholeArchiveNeedsStatic { span });
}
("as-needed", Some(NativeLibKind::Dylib { as_needed }))
@@ -278,21 +332,11 @@ impl<'tcx> Collector<'tcx> {
assign_modifier(as_needed)
}
("as-needed", _) => {
- sess.span_err(
- span,
- "linking modifier `as-needed` is only compatible with \
- `dylib` and `framework` linking kinds",
- );
+ sess.emit_err(AsNeededCompatibility { span });
}
_ => {
- sess.span_err(
- span,
- format!(
- "unknown linking modifier `{modifier}`, expected one of: \
- bundle, verbatim, whole-archive, as-needed"
- ),
- );
+ sess.emit_err(UnknownLinkModifier { span, modifier });
}
}
}
@@ -300,39 +344,66 @@ impl<'tcx> Collector<'tcx> {
if let Some((_, span)) = wasm_import_module {
if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
- let msg = "`wasm_import_module` is incompatible with \
- other arguments in `#[link]` attributes";
- sess.span_err(span, msg);
+ sess.emit_err(IncompatibleWasmLink { span });
}
} else if name.is_none() {
- struct_span_err!(
- sess,
- m.span,
- E0459,
- "`#[link]` attribute requires a `name = \"string\"` argument"
- )
- .span_label(m.span, "missing `name` argument")
- .emit();
+ sess.emit_err(LinkRequiresName { span: m.span });
+ }
+
+ // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
+ if let Some((_, span)) = import_name_type {
+ if kind != Some(NativeLibKind::RawDylib) {
+ sess.emit_err(ImportNameTypeRaw { span });
+ }
}
let dll_imports = match kind {
Some(NativeLibKind::RawDylib) => {
if let Some((name, span)) = name && name.as_str().contains('\0') {
- sess.span_err(
- span,
- "link name must not contain NUL characters if link kind is `raw-dylib`",
- );
+ sess.emit_err(RawDylibNoNul { span });
}
foreign_mod_items
.iter()
- .map(|child_item| self.build_dll_import(abi, child_item))
+ .map(|child_item| {
+ self.build_dll_import(
+ abi,
+ import_name_type.map(|(import_name_type, _)| import_name_type),
+ child_item,
+ )
+ })
.collect()
}
- _ => Vec::new(),
+ _ => {
+ for child_item in foreign_mod_items {
+ if self.tcx.def_kind(child_item.id.def_id).has_codegen_attrs()
+ && self
+ .tcx
+ .codegen_fn_attrs(child_item.id.def_id)
+ .link_ordinal
+ .is_some()
+ {
+ let link_ordinal_attr = self
+ .tcx
+ .hir()
+ .attrs(self.tcx.hir().local_def_id_to_hir_id(child_item.id.def_id))
+ .iter()
+ .find(|a| a.has_name(sym::link_ordinal))
+ .unwrap();
+ sess.emit_err(LinkOrdinalRawDylib { span: link_ordinal_attr.span });
+ }
+ }
+
+ Vec::new()
+ }
};
+
+ let name = name.map(|(name, _)| name);
+ let kind = kind.unwrap_or(NativeLibKind::Unspecified);
+ let filename = find_bundled_library(name, verbatim, kind, sess);
self.libs.push(NativeLib {
- name: name.map(|(name, _)| name),
- kind: kind.unwrap_or(NativeLibKind::Unspecified),
+ name,
+ filename,
+ kind,
cfg,
foreign_module: Some(it.def_id.to_def_id()),
wasm_import_module: wasm_import_module.map(|(name, _)| name),
@@ -349,7 +420,7 @@ impl<'tcx> Collector<'tcx> {
for lib in &self.tcx.sess.opts.libs {
if let NativeLibKind::Framework { .. } = lib.kind && !self.tcx.sess.target.is_like_osx {
// Cannot check this when parsing options because the target is not yet available.
- self.tcx.sess.err("library kind `framework` is only supported on Apple targets");
+ self.tcx.sess.emit_err(LibFrameworkApple);
}
if let Some(ref new_name) = lib.new_name {
let any_duplicate = self
@@ -358,23 +429,11 @@ impl<'tcx> Collector<'tcx> {
.filter_map(|lib| lib.name.as_ref())
.any(|n| n.as_str() == lib.name);
if new_name.is_empty() {
- self.tcx.sess.err(format!(
- "an empty renaming target was specified for library `{}`",
- lib.name
- ));
+ self.tcx.sess.emit_err(EmptyRenamingTarget { lib_name: &lib.name });
} else if !any_duplicate {
- self.tcx.sess.err(format!(
- "renaming of the library `{}` was specified, \
- however this crate contains no `#[link(...)]` \
- attributes referencing this library",
- lib.name
- ));
+ self.tcx.sess.emit_err(RenamingNoLink { lib_name: &lib.name });
} else if !renames.insert(&lib.name) {
- self.tcx.sess.err(format!(
- "multiple renamings were \
- specified for library `{}`",
- lib.name
- ));
+ self.tcx.sess.emit_err(MultipleRenamings { lib_name: &lib.name });
}
}
}
@@ -399,10 +458,13 @@ impl<'tcx> Collector<'tcx> {
// involved or not, library reordering and kind overriding without
// explicit `:rename` in particular.
if lib.has_modifiers() || passed_lib.has_modifiers() {
- let msg = "overriding linking modifiers from command line is not supported";
match lib.foreign_module {
- Some(def_id) => self.tcx.sess.span_err(self.tcx.def_span(def_id), msg),
- None => self.tcx.sess.err(msg),
+ Some(def_id) => self.tcx.sess.emit_err(NoLinkModOverride {
+ span: Some(self.tcx.def_span(def_id)),
+ }),
+ None => {
+ self.tcx.sess.emit_err(NoLinkModOverride { span: None })
+ }
};
}
if passed_lib.kind != NativeLibKind::Unspecified {
@@ -421,8 +483,13 @@ impl<'tcx> Collector<'tcx> {
if existing.is_empty() {
// Add if not found
let new_name: Option<&str> = passed_lib.new_name.as_deref();
+ let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
+ let sess = self.tcx.sess;
+ let filename =
+ find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, sess);
self.libs.push(NativeLib {
- name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
+ name,
+ filename,
kind: passed_lib.kind,
cfg: None,
foreign_module: None,
@@ -462,7 +529,12 @@ impl<'tcx> Collector<'tcx> {
.sum()
}
- fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef) -> DllImport {
+ fn build_dll_import(
+ &self,
+ abi: Abi,
+ import_name_type: Option<PeImportNameType>,
+ item: &hir::ForeignItemRef,
+ ) -> DllImport {
let calling_convention = if self.tcx.sess.target.arch == "x86" {
match abi {
Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
@@ -476,29 +548,29 @@ impl<'tcx> Collector<'tcx> {
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
}
_ => {
- self.tcx.sess.span_fatal(
- item.span,
- r#"ABI not supported by `#[link(kind = "raw-dylib")]` on i686"#,
- );
+ self.tcx.sess.emit_fatal(UnsupportedAbiI686 { span: item.span });
}
}
} else {
match abi {
Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
_ => {
- self.tcx.sess.span_fatal(
- item.span,
- r#"ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture"#,
- );
+ self.tcx.sess.emit_fatal(UnsupportedAbi { span: item.span });
}
}
};
+ let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.def_id);
+ let import_name_type = codegen_fn_attrs
+ .link_ordinal
+ .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
+
DllImport {
- name: item.ident.name,
- ordinal: self.tcx.codegen_fn_attrs(item.id.def_id).link_ordinal,
+ name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name),
+ import_name_type,
calling_convention,
span: item.span,
+ is_fn: self.tcx.def_kind(item.id.def_id).is_fn_like(),
}
}
}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 40dc4fb05..830417eea 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -4,7 +4,6 @@ use crate::creader::{CStore, CrateMetadataRef};
use crate::rmeta::*;
use rustc_ast as ast;
-use rustc_ast::ptr::P;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::svh::Svh;
@@ -33,7 +32,7 @@ use rustc_session::cstore::{
use rustc_session::Session;
use rustc_span::hygiene::{ExpnIndex, MacroKind};
use rustc_span::source_map::{respan, Spanned};
-use rustc_span::symbol::{sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
use proc_macro::bridge::client::ProcMacro;
@@ -42,7 +41,6 @@ use std::iter::TrustedLen;
use std::mem;
use std::num::NonZeroUsize;
use std::path::Path;
-use tracing::debug;
pub(super) use cstore_impl::provide;
pub use cstore_impl::provide_extern;
@@ -99,7 +97,7 @@ pub(crate) struct CrateMetadata {
/// Proc macro descriptions for this crate, if it's a proc macro crate.
raw_proc_macros: Option<&'static [ProcMacro]>,
/// Source maps for code from the crate.
- source_map_import_info: OnceCell<Vec<ImportedSourceFile>>,
+ source_map_import_info: Lock<Vec<Option<ImportedSourceFile>>>,
/// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`.
def_path_hash_map: DefPathHashMapRef<'static>,
/// Likewise for ExpnHash.
@@ -143,7 +141,8 @@ pub(crate) struct CrateMetadata {
}
/// Holds information about a rustc_span::SourceFile imported from another crate.
-/// See `imported_source_files()` for more information.
+/// See `imported_source_file()` for more information.
+#[derive(Clone)]
struct ImportedSourceFile {
/// This SourceFile's byte-offset within the source_map of its original crate
original_start_pos: rustc_span::BytePos,
@@ -160,9 +159,6 @@ pub(super) struct DecodeContext<'a, 'tcx> {
sess: Option<&'tcx Session>,
tcx: Option<TyCtxt<'tcx>>,
- // Cache the last used source_file for translating spans as an optimization.
- last_source_file_index: usize,
-
lazy_state: LazyState,
// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
@@ -191,7 +187,6 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
blob: self.blob(),
sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
tcx,
- last_source_file_index: 0,
lazy_state: LazyState::NoNode,
alloc_decoding_session: self
.cdata()
@@ -455,6 +450,13 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex {
}
}
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ast::AttrId {
+ fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ast::AttrId {
+ let sess = d.sess.expect("can't decode AttrId without Session");
+ sess.parse_sess.attr_id_generator.mk_attr_id()
+ }
+}
+
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext {
let cdata = decoder.cdata();
@@ -527,6 +529,9 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
bug!("Cannot decode Span without Session.")
};
+ // Index of the file in the corresponding crate's list of encoded files.
+ let metadata_index = u32::decode(decoder);
+
// There are two possibilities here:
// 1. This is a 'local span', which is located inside a `SourceFile`
// that came from this crate. In this case, we use the source map data
@@ -553,10 +558,10 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
// to be based on the *foreign* crate (e.g. crate C), not the crate
// we are writing metadata for (e.g. crate B). This allows us to
// treat the 'local' and 'foreign' cases almost identically during deserialization:
- // we can call `imported_source_files` for the proper crate, and binary search
+ // we can call `imported_source_file` for the proper crate, and binary search
// through the returned slice using our span.
- let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
- decoder.cdata().imported_source_files(sess)
+ let source_file = if tag == TAG_VALID_SPAN_LOCAL {
+ decoder.cdata().imported_source_file(metadata_index, sess)
} else {
// When we encode a proc-macro crate, all `Span`s should be encoded
// with `TAG_VALID_SPAN_LOCAL`
@@ -577,66 +582,69 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
cnum
);
- // Decoding 'foreign' spans should be rare enough that it's
- // not worth it to maintain a per-CrateNum cache for `last_source_file_index`.
- // We just set it to 0, to ensure that we don't try to access something out
- // of bounds for our initial 'guess'
- decoder.last_source_file_index = 0;
-
let foreign_data = decoder.cdata().cstore.get_crate_data(cnum);
- foreign_data.imported_source_files(sess)
- };
-
- let source_file = {
- // Optimize for the case that most spans within a translated item
- // originate from the same source_file.
- let last_source_file = &imported_source_files[decoder.last_source_file_index];
-
- if lo >= last_source_file.original_start_pos && lo <= last_source_file.original_end_pos
- {
- last_source_file
- } else {
- let index = imported_source_files
- .binary_search_by_key(&lo, |source_file| source_file.original_start_pos)
- .unwrap_or_else(|index| index - 1);
-
- // Don't try to cache the index for foreign spans,
- // as this would require a map from CrateNums to indices
- if tag == TAG_VALID_SPAN_LOCAL {
- decoder.last_source_file_index = index;
- }
- &imported_source_files[index]
- }
+ foreign_data.imported_source_file(metadata_index, sess)
};
- // Make sure our binary search above is correct.
+ // Make sure our span is well-formed.
debug_assert!(
- lo >= source_file.original_start_pos && lo <= source_file.original_end_pos,
- "Bad binary search: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
+ lo + source_file.original_start_pos <= source_file.original_end_pos,
+ "Malformed encoded span: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
lo,
source_file.original_start_pos,
source_file.original_end_pos
);
- // Make sure we correctly filtered out invalid spans during encoding
+ // Make sure we correctly filtered out invalid spans during encoding.
debug_assert!(
- hi >= source_file.original_start_pos && hi <= source_file.original_end_pos,
- "Bad binary search: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
+ hi + source_file.original_start_pos <= source_file.original_end_pos,
+ "Malformed encoded span: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
hi,
source_file.original_start_pos,
source_file.original_end_pos
);
- let lo =
- (lo + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
- let hi =
- (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
+ let lo = lo + source_file.translated_source_file.start_pos;
+ let hi = hi + source_file.translated_source_file.start_pos;
// Do not try to decode parent for foreign spans.
Span::new(lo, hi, ctxt, None)
}
}
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol {
+ fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
+ let tag = d.read_u8();
+
+ match tag {
+ SYMBOL_STR => {
+ let s = d.read_str();
+ Symbol::intern(s)
+ }
+ SYMBOL_OFFSET => {
+ // read str offset
+ let pos = d.read_usize();
+ let old_pos = d.opaque.position();
+
+ // move to str ofset and read
+ d.opaque.set_position(pos);
+ let s = d.read_str();
+ let sym = Symbol::intern(s);
+
+ // restore position
+ d.opaque.set_position(old_pos);
+
+ sym
+ }
+ SYMBOL_PREINTERNED => {
+ let symbol_index = d.read_u32();
+ Symbol::new_from_decoded(symbol_index)
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [ty::abstract_const::Node<'tcx>] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
@@ -783,26 +791,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.opt_item_ident(item_index, sess).expect("no encoded ident for item")
}
- fn maybe_kind(self, item_id: DefIndex) -> Option<EntryKind> {
- self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
- }
-
#[inline]
pub(super) fn map_encoded_cnum_to_current(self, cnum: CrateNum) -> CrateNum {
if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] }
}
- fn kind(self, item_id: DefIndex) -> EntryKind {
- self.maybe_kind(item_id).unwrap_or_else(|| {
- bug!(
- "CrateMetadata::kind({:?}): id not found, in crate {:?} with number {}",
- item_id,
- self.root.name,
- self.cnum,
- )
- })
- }
-
fn def_kind(self, item_id: DefIndex) -> DefKind {
self.root.tables.opt_def_kind.get(self, item_id).unwrap_or_else(|| {
bug!(
@@ -854,21 +847,16 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
- fn get_variant(self, kind: &EntryKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
- let data = match kind {
- EntryKind::Variant(data) | EntryKind::Struct(data) | EntryKind::Union(data) => {
- data.decode(self)
- }
- _ => bug!(),
- };
-
+ fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
let adt_kind = match kind {
- EntryKind::Variant(_) => ty::AdtKind::Enum,
- EntryKind::Struct(..) => ty::AdtKind::Struct,
- EntryKind::Union(..) => ty::AdtKind::Union,
+ DefKind::Variant => ty::AdtKind::Enum,
+ DefKind::Struct => ty::AdtKind::Struct,
+ DefKind::Union => ty::AdtKind::Union,
_ => bug!(),
};
+ let data = self.root.tables.variant_data.get(self, index).unwrap().decode(self);
+
let variant_did =
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
let ctor_did = data.ctor.map(|index| self.local_def_id(index));
@@ -899,13 +887,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
- let kind = self.kind(item_id);
+ let kind = self.def_kind(item_id);
let did = self.local_def_id(item_id);
let adt_kind = match kind {
- EntryKind::Enum => ty::AdtKind::Enum,
- EntryKind::Struct(_) => ty::AdtKind::Struct,
- EntryKind::Union(_) => ty::AdtKind::Union,
+ DefKind::Enum => ty::AdtKind::Enum,
+ DefKind::Struct => ty::AdtKind::Struct,
+ DefKind::Union => ty::AdtKind::Union,
_ => bug!("get_adt_def called on a non-ADT {:?}", did),
};
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
@@ -917,7 +905,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.get(self, item_id)
.unwrap_or_else(LazyArray::empty)
.decode(self)
- .map(|index| self.get_variant(&self.kind(index), index, did))
+ .map(|index| self.get_variant(&self.def_kind(index), index, did))
.collect()
} else {
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
@@ -930,8 +918,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.tables.generics_of.get(self, item_id).unwrap().decode((self, sess))
}
- fn get_visibility(self, id: DefIndex) -> ty::Visibility {
- self.root.tables.visibility.get(self, id).unwrap().decode(self)
+ fn get_visibility(self, id: DefIndex) -> ty::Visibility<DefId> {
+ self.root
+ .tables
+ .visibility
+ .get(self, id)
+ .unwrap()
+ .decode(self)
+ .map_id(|index| self.local_def_id(index))
}
fn get_trait_item_def_id(self, id: DefIndex) -> Option<DefId> {
@@ -1027,10 +1021,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let vis = self.get_visibility(child_index);
let span = self.get_span(child_index, sess);
let macro_rules = match kind {
- DefKind::Macro(..) => match self.kind(child_index) {
- EntryKind::MacroDef(_, macro_rules) => macro_rules,
- _ => unreachable!(),
- },
+ DefKind::Macro(..) => {
+ self.root.tables.macro_rules.get(self, child_index).is_some()
+ }
_ => false,
};
@@ -1084,14 +1077,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
}
- match self.kind(id) {
- EntryKind::Mod(exports) => {
- for exp in exports.decode((self, sess)) {
- callback(exp);
- }
+ if let Some(exports) = self.root.tables.module_reexports.get(self, id) {
+ for exp in exports.decode((self, sess)) {
+ callback(exp);
}
- EntryKind::Enum | EntryKind::Trait => {}
- _ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)),
}
}
@@ -1104,19 +1093,21 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId {
- match self.kind(id) {
- EntryKind::Mod(_) | EntryKind::Enum | EntryKind::Trait => {
- self.get_expn_that_defined(id, sess)
- }
+ match self.def_kind(id) {
+ DefKind::Mod | DefKind::Enum | DefKind::Trait => self.get_expn_that_defined(id, sess),
_ => panic!("Expected module, found {:?}", self.local_def_id(id)),
}
}
- fn get_fn_has_self_parameter(self, id: DefIndex) -> bool {
- match self.kind(id) {
- EntryKind::AssocFn { has_self, .. } => has_self,
- _ => false,
- }
+ fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool {
+ self.root
+ .tables
+ .fn_arg_names
+ .get(self, id)
+ .unwrap_or_else(LazyArray::empty)
+ .decode((self, sess))
+ .nth(0)
+ .map_or(false, |ident| ident.name == kw::SelfLower)
}
fn get_associated_item_def_ids(
@@ -1133,15 +1124,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.map(move |child_index| self.local_def_id(child_index))
}
- fn get_associated_item(self, id: DefIndex) -> ty::AssocItem {
+ fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
let name = self.item_name(id);
- let (kind, container, has_self) = match self.kind(id) {
- EntryKind::AssocConst(container) => (ty::AssocKind::Const, container, false),
- EntryKind::AssocFn { container, has_self } => (ty::AssocKind::Fn, container, has_self),
- EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false),
- _ => bug!("cannot get associated-item of `{:?}`", id),
+ let kind = match self.def_kind(id) {
+ DefKind::AssocConst => ty::AssocKind::Const,
+ DefKind::AssocFn => ty::AssocKind::Fn,
+ DefKind::AssocTy => ty::AssocKind::Type,
+ _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
};
+ let has_self = self.get_fn_has_self_parameter(id, sess);
+ let container = self.root.tables.assoc_container.get(self, id).unwrap();
ty::AssocItem {
name,
@@ -1154,9 +1147,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> {
- match self.kind(node_id) {
- EntryKind::Struct(data) | EntryKind::Variant(data) => {
- let vdata = data.decode(self);
+ match self.def_kind(node_id) {
+ DefKind::Struct | DefKind::Variant => {
+ let vdata = self.root.tables.variant_data.get(self, node_id).unwrap().decode(self);
vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind))
}
_ => None,
@@ -1202,7 +1195,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.map(move |index| respan(self.get_span(index, sess), self.item_name(index)))
}
- fn get_struct_field_visibilities(self, id: DefIndex) -> impl Iterator<Item = Visibility> + 'a {
+ fn get_struct_field_visibilities(
+ self,
+ id: DefIndex,
+ ) -> impl Iterator<Item = Visibility<DefId>> + 'a {
self.root
.tables
.children
@@ -1344,18 +1340,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef {
- match self.kind(id) {
- EntryKind::MacroDef(mac_args, macro_rules) => {
- ast::MacroDef { body: P(mac_args.decode((self, sess))), macro_rules }
+ match self.def_kind(id) {
+ DefKind::Macro(_) => {
+ let macro_rules = self.root.tables.macro_rules.get(self, id).is_some();
+ let body =
+ self.root.tables.macro_definition.get(self, id).unwrap().decode((self, sess));
+ ast::MacroDef { macro_rules, body: ast::ptr::P(body) }
}
_ => bug!(),
}
}
fn is_foreign_item(self, id: DefIndex) -> bool {
- match self.kind(id) {
- EntryKind::ForeignStatic | EntryKind::ForeignFn => true,
- _ => false,
+ if let Some(parent) = self.def_key(id).parent {
+ matches!(self.def_kind(parent), DefKind::ForeignMod)
+ } else {
+ false
}
}
@@ -1453,7 +1453,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
///
/// Proc macro crates don't currently export spans, so this function does not have
/// to work for them.
- fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
+ fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile {
fn filter<'a>(sess: &Session, path: Option<&'a Path>) -> Option<&'a Path> {
path.filter(|_| {
// Only spend time on further checks if we have what to translate *to*.
@@ -1541,90 +1541,96 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
};
- self.cdata.source_map_import_info.get_or_init(|| {
- let external_source_map = self.root.source_map.decode(self);
-
- external_source_map
- .map(|source_file_to_import| {
- // We can't reuse an existing SourceFile, so allocate a new one
- // containing the information we need.
- let rustc_span::SourceFile {
- mut name,
- src_hash,
- start_pos,
- end_pos,
- lines,
- multibyte_chars,
- non_narrow_chars,
- normalized_pos,
- name_hash,
- ..
- } = source_file_to_import;
-
- // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
- // during rust bootstrapping by `remap-debuginfo = true`, and the user
- // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
- // then we change `name` to a similar state as if the rust was bootstrapped
- // with `remap-debuginfo = true`.
- // This is useful for testing so that tests about the effects of
- // `try_to_translate_virtual_to_real` don't have to worry about how the
- // compiler is bootstrapped.
- if let Some(virtual_dir) =
- &sess.opts.unstable_opts.simulate_remapped_rust_src_base
- {
- if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
- if let rustc_span::FileName::Real(ref mut old_name) = name {
- if let rustc_span::RealFileName::LocalPath(local) = old_name {
- if let Ok(rest) = local.strip_prefix(real_dir) {
- *old_name = rustc_span::RealFileName::Remapped {
- local_path: None,
- virtual_name: virtual_dir.join(rest),
- };
- }
+ let mut import_info = self.cdata.source_map_import_info.lock();
+ for _ in import_info.len()..=(source_file_index as usize) {
+ import_info.push(None);
+ }
+ import_info[source_file_index as usize]
+ .get_or_insert_with(|| {
+ let source_file_to_import = self
+ .root
+ .source_map
+ .get(self, source_file_index)
+ .expect("missing source file")
+ .decode(self);
+
+ // We can't reuse an existing SourceFile, so allocate a new one
+ // containing the information we need.
+ let rustc_span::SourceFile {
+ mut name,
+ src_hash,
+ start_pos,
+ end_pos,
+ lines,
+ multibyte_chars,
+ non_narrow_chars,
+ normalized_pos,
+ name_hash,
+ ..
+ } = source_file_to_import;
+
+ // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
+ // during rust bootstrapping by `remap-debuginfo = true`, and the user
+ // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
+ // then we change `name` to a similar state as if the rust was bootstrapped
+ // with `remap-debuginfo = true`.
+ // This is useful for testing so that tests about the effects of
+ // `try_to_translate_virtual_to_real` don't have to worry about how the
+ // compiler is bootstrapped.
+ if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
+ {
+ if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
+ if let rustc_span::FileName::Real(ref mut old_name) = name {
+ if let rustc_span::RealFileName::LocalPath(local) = old_name {
+ if let Ok(rest) = local.strip_prefix(real_dir) {
+ *old_name = rustc_span::RealFileName::Remapped {
+ local_path: None,
+ virtual_name: virtual_dir.join(rest),
+ };
}
}
}
}
+ }
- // If this file's path has been remapped to `/rustc/$hash`,
- // we might be able to reverse that (also see comments above,
- // on `try_to_translate_virtual_to_real`).
- try_to_translate_virtual_to_real(&mut name);
-
- let source_length = (end_pos - start_pos).to_usize();
-
- let local_version = sess.source_map().new_imported_source_file(
- name,
- src_hash,
- name_hash,
- source_length,
- self.cnum,
- lines,
- multibyte_chars,
- non_narrow_chars,
- normalized_pos,
- start_pos,
- end_pos,
- );
- debug!(
- "CrateMetaData::imported_source_files alloc \
+ // If this file's path has been remapped to `/rustc/$hash`,
+ // we might be able to reverse that (also see comments above,
+ // on `try_to_translate_virtual_to_real`).
+ try_to_translate_virtual_to_real(&mut name);
+
+ let source_length = (end_pos - start_pos).to_usize();
+
+ let local_version = sess.source_map().new_imported_source_file(
+ name,
+ src_hash,
+ name_hash,
+ source_length,
+ self.cnum,
+ lines,
+ multibyte_chars,
+ non_narrow_chars,
+ normalized_pos,
+ start_pos,
+ source_file_index,
+ );
+ debug!(
+ "CrateMetaData::imported_source_files alloc \
source_file {:?} original (start_pos {:?} end_pos {:?}) \
translated (start_pos {:?} end_pos {:?})",
- local_version.name,
- start_pos,
- end_pos,
- local_version.start_pos,
- local_version.end_pos
- );
+ local_version.name,
+ start_pos,
+ end_pos,
+ local_version.start_pos,
+ local_version.end_pos
+ );
- ImportedSourceFile {
- original_start_pos: start_pos,
- original_end_pos: end_pos,
- translated_source_file: local_version,
- }
- })
- .collect()
- })
+ ImportedSourceFile {
+ original_start_pos: start_pos,
+ original_end_pos: end_pos,
+ translated_source_file: local_version,
+ }
+ })
+ .clone()
}
fn get_generator_diagnostic_data(
@@ -1687,7 +1693,7 @@ impl CrateMetadata {
trait_impls,
incoherent_impls: Default::default(),
raw_proc_macros,
- source_map_import_info: OnceCell::new(),
+ source_map_import_info: Lock::new(Vec::new()),
def_path_hash_map,
expn_hash_map: Default::default(),
alloc_decoding_state,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 38ce50e83..dede1b212 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -76,9 +76,9 @@ impl ProcessQueryValue<'_, Option<DeprecationEntry>> for Option<Deprecation> {
}
macro_rules! provide_one {
- (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table }) => {
+ ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table }) => {
provide_one! {
- <$lt> $tcx, $def_id, $other, $cdata, $name => {
+ $tcx, $def_id, $other, $cdata, $name => {
$cdata
.root
.tables
@@ -89,9 +89,9 @@ macro_rules! provide_one {
}
}
};
- (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_direct }) => {
+ ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_direct }) => {
provide_one! {
- <$lt> $tcx, $def_id, $other, $cdata, $name => {
+ $tcx, $def_id, $other, $cdata, $name => {
// We don't decode `table_direct`, since it's not a Lazy, but an actual value
$cdata
.root
@@ -102,11 +102,11 @@ macro_rules! provide_one {
}
}
};
- (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => {
- fn $name<$lt>(
- $tcx: TyCtxt<$lt>,
- def_id_arg: ty::query::query_keys::$name<$lt>,
- ) -> ty::query::query_values::$name<$lt> {
+ ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => {
+ fn $name<'tcx>(
+ $tcx: TyCtxt<'tcx>,
+ def_id_arg: ty::query::query_keys::$name<'tcx>,
+ ) -> ty::query::query_values::$name<'tcx> {
let _prof_timer =
$tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name)));
@@ -130,11 +130,11 @@ macro_rules! provide_one {
}
macro_rules! provide {
- (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
+ ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
$($name:ident => { $($compute:tt)* })*) => {
pub fn provide_extern(providers: &mut ExternProviders) {
$(provide_one! {
- <$lt> $tcx, $def_id, $other, $cdata, $name => { $($compute)* }
+ $tcx, $def_id, $other, $cdata, $name => { $($compute)* }
})*
*providers = ExternProviders {
@@ -187,7 +187,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) {
}
}
-provide! { <'tcx> tcx, def_id, other, cdata,
+provide! { tcx, def_id, other, cdata,
explicit_item_bounds => { table }
explicit_predicates_of => { table }
generics_of => { table }
@@ -199,6 +199,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
codegen_fn_attrs => { table }
impl_trait_ref => { table }
const_param_default => { table }
+ object_lifetime_default => { table }
thir_abstract_const => { table }
optimized_mir => { table }
mir_for_ctfe => { table }
@@ -207,8 +208,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
def_ident_span => { table }
lookup_stability => { table }
lookup_const_stability => { table }
+ lookup_default_body_stability => { table }
lookup_deprecation_entry => { table }
- visibility => { table }
unused_generic_params => { table }
opt_def_kind => { table_direct }
impl_parent => { table }
@@ -223,6 +224,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
generator_kind => { table }
trait_def => { table }
+ visibility => { cdata.get_visibility(def_id.index) }
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
adt_destructor => {
let _ = cdata;
@@ -231,7 +233,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
associated_item_def_ids => {
tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess))
}
- associated_item => { cdata.get_associated_item(def_id.index) }
+ associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
@@ -340,7 +342,8 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
assert_eq!(cnum, LOCAL_CRATE);
false
},
- native_library_kind: |tcx, id| {
+ native_library_kind: |tcx, id| tcx.native_library(id).map(|l| l.kind),
+ native_library: |tcx, id| {
tcx.native_libraries(id.krate)
.iter()
.filter(|lib| native_libs::relevant_lib(&tcx.sess, lib))
@@ -354,7 +357,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
.foreign_items
.contains(&id)
})
- .map(|l| l.kind)
},
native_libraries: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
@@ -483,7 +485,7 @@ impl CStore {
pub fn struct_field_visibilities_untracked(
&self,
def: DefId,
- ) -> impl Iterator<Item = Visibility> + '_ {
+ ) -> impl Iterator<Item = Visibility<DefId>> + '_ {
self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
}
@@ -491,7 +493,7 @@ impl CStore {
self.get_crate_data(def.krate).get_ctor_def_id_and_kind(def.index)
}
- pub fn visibility_untracked(&self, def: DefId) -> Visibility {
+ pub fn visibility_untracked(&self, def: DefId) -> Visibility<DefId> {
self.get_crate_data(def.krate).get_visibility(def.index)
}
@@ -533,8 +535,8 @@ impl CStore {
)
}
- pub fn fn_has_self_parameter_untracked(&self, def: DefId) -> bool {
- self.get_crate_data(def.krate).get_fn_has_self_parameter(def.index)
+ pub fn fn_has_self_parameter_untracked(&self, def: DefId, sess: &Session) -> bool {
+ self.get_crate_data(def.krate).get_fn_has_self_parameter(def.index, sess)
}
pub fn crate_source_untracked(&self, cnum: CrateNum) -> Lrc<CrateSource> {
@@ -675,6 +677,9 @@ impl CrateStore for CStore {
}
fn import_source_files(&self, sess: &Session, cnum: CrateNum) {
- self.get_crate_data(cnum).imported_source_files(sess);
+ let cdata = self.get_crate_data(cnum);
+ for file_index in 0..cdata.root.source_map.size() {
+ cdata.imported_source_file(file_index as u32, sess);
+ }
}
}
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 33278367c..5a60ea794 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1,3 +1,4 @@
+use crate::errors::{FailCreateFileEncoder, FailSeekFile, FailWriteFile};
use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
use crate::rmeta::table::TableBuilder;
use crate::rmeta::*;
@@ -16,8 +17,6 @@ use rustc_hir::def_id::{
use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::lang_items;
-use rustc_hir::{AnonConst, GenericParamKind};
-use rustc_index::bit_set::GrowableBitSet;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::{
@@ -39,12 +38,12 @@ use rustc_span::{
};
use rustc_target::abi::VariantIdx;
use std::borrow::Borrow;
+use std::collections::hash_map::Entry;
use std::hash::Hash;
use std::io::{Read, Seek, Write};
use std::iter;
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
-use tracing::{debug, trace};
pub(super) struct EncodeContext<'a, 'tcx> {
opaque: opaque::FileEncoder,
@@ -66,15 +65,13 @@ pub(super) struct EncodeContext<'a, 'tcx> {
// The indices (into the `SourceMap`'s `MonotonicVec`)
// of all of the `SourceFiles` that we need to serialize.
// When we serialize a `Span`, we insert the index of its
- // `SourceFile` into the `GrowableBitSet`.
- //
- // This needs to be a `GrowableBitSet` and not a
- // regular `BitSet` because we may actually import new `SourceFiles`
- // during metadata encoding, due to executing a query
- // with a result containing a foreign `Span`.
- required_source_files: Option<GrowableBitSet<usize>>,
+ // `SourceFile` into the `FxIndexSet`.
+ // The order inside the `FxIndexSet` is used as on-disk
+ // order of `SourceFiles`, and encoded inside `Span`s.
+ required_source_files: Option<FxIndexSet<usize>>,
is_proc_macro: bool,
hygiene_ctxt: &'a HygieneEncodeContext,
+ symbol_table: FxHashMap<Symbol, usize>,
}
/// If the current crate is a proc-macro, returns early with `Lazy:empty()`.
@@ -238,17 +235,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
s.source_file_cache =
(source_map.files()[source_file_index].clone(), source_file_index);
}
+ let (ref source_file, source_file_index) = s.source_file_cache;
+ debug_assert!(source_file.contains(span.lo));
- if !s.source_file_cache.0.contains(span.hi) {
+ if !source_file.contains(span.hi) {
// Unfortunately, macro expansion still sometimes generates Spans
// that malformed in this way.
return TAG_PARTIAL_SPAN.encode(s);
}
- let source_files = s.required_source_files.as_mut().expect("Already encoded SourceMap!");
- // Record the fact that we need to encode the data for this `SourceFile`
- source_files.insert(s.source_file_cache.1);
-
// There are two possible cases here:
// 1. This span comes from a 'foreign' crate - e.g. some crate upstream of the
// crate we are writing metadata for. When the metadata for *this* crate gets
@@ -265,7 +260,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
// if we're a proc-macro crate.
// This allows us to avoid loading the dependencies of proc-macro crates: all of
// the information we need to decode `Span`s is stored in the proc-macro crate.
- let (tag, lo, hi) = if s.source_file_cache.0.is_imported() && !s.is_proc_macro {
+ let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
// To simplify deserialization, we 'rebase' this span onto the crate it originally came from
// (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
// are relative to the source map information for the 'foreign' crate whose CrateNum
@@ -275,29 +270,41 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
//
// All of this logic ensures that the final result of deserialization is a 'normal'
// Span that can be used without any additional trouble.
- let external_start_pos = {
+ let metadata_index = {
// Introduce a new scope so that we drop the 'lock()' temporary
- match &*s.source_file_cache.0.external_src.lock() {
- ExternalSource::Foreign { original_start_pos, .. } => *original_start_pos,
+ match &*source_file.external_src.lock() {
+ ExternalSource::Foreign { metadata_index, .. } => *metadata_index,
src => panic!("Unexpected external source {:?}", src),
}
};
- let lo = (span.lo - s.source_file_cache.0.start_pos) + external_start_pos;
- let hi = (span.hi - s.source_file_cache.0.start_pos) + external_start_pos;
- (TAG_VALID_SPAN_FOREIGN, lo, hi)
+ (TAG_VALID_SPAN_FOREIGN, metadata_index)
} else {
- (TAG_VALID_SPAN_LOCAL, span.lo, span.hi)
+ // Record the fact that we need to encode the data for this `SourceFile`
+ let source_files =
+ s.required_source_files.as_mut().expect("Already encoded SourceMap!");
+ let (metadata_index, _) = source_files.insert_full(source_file_index);
+ let metadata_index: u32 =
+ metadata_index.try_into().expect("cannot export more than U32_MAX files");
+
+ (TAG_VALID_SPAN_LOCAL, metadata_index)
};
- tag.encode(s);
- lo.encode(s);
+ // Encode the start position relative to the file start, so we profit more from the
+ // variable-length integer encoding.
+ let lo = span.lo - source_file.start_pos;
// Encode length which is usually less than span.hi and profits more
// from the variable-length integer encoding that we use.
- let len = hi - lo;
+ let len = span.hi - span.lo;
+
+ tag.encode(s);
+ lo.encode(s);
len.encode(s);
+ // Encode the index of the `SourceFile` for the span, in order to make decoding faster.
+ metadata_index.encode(s);
+
if tag == TAG_VALID_SPAN_FOREIGN {
// This needs to be two lines to avoid holding the `s.source_file_cache`
// while calling `cnum.encode(s)`
@@ -307,6 +314,31 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
}
}
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Symbol {
+ fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
+ // if symbol preinterned, emit tag and symbol index
+ if self.is_preinterned() {
+ s.opaque.emit_u8(SYMBOL_PREINTERNED);
+ s.opaque.emit_u32(self.as_u32());
+ } else {
+ // otherwise write it as string or as offset to it
+ match s.symbol_table.entry(*self) {
+ Entry::Vacant(o) => {
+ s.opaque.emit_u8(SYMBOL_STR);
+ let pos = s.opaque.position();
+ o.insert(pos);
+ s.emit_str(self.as_str());
+ }
+ Entry::Occupied(o) => {
+ let x = o.get().clone();
+ s.emit_u8(SYMBOL_OFFSET);
+ s.emit_usize(x);
+ }
+ }
+ }
+ }
+}
+
impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
const CLEAR_CROSS_CRATE: bool = true;
@@ -449,7 +481,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy(DefPathHashMapRef::BorrowedFromTcx(self.tcx.def_path_hash_to_def_index_map()))
}
- fn encode_source_map(&mut self) -> LazyArray<rustc_span::SourceFile> {
+ fn encode_source_map(&mut self) -> LazyTable<u32, LazyValue<rustc_span::SourceFile>> {
let source_map = self.tcx.sess.source_map();
let all_source_files = source_map.files();
@@ -460,66 +492,64 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let working_directory = &self.tcx.sess.opts.working_dir;
- let adapted = all_source_files
- .iter()
- .enumerate()
- .filter(|(idx, source_file)| {
- // Only serialize `SourceFile`s that were used
- // during the encoding of a `Span`
- required_source_files.contains(*idx) &&
- // Don't serialize imported `SourceFile`s, unless
- // we're in a proc-macro crate.
- (!source_file.is_imported() || self.is_proc_macro)
- })
- .map(|(_, source_file)| {
- // At export time we expand all source file paths to absolute paths because
- // downstream compilation sessions can have a different compiler working
- // directory, so relative paths from this or any other upstream crate
- // won't be valid anymore.
- //
- // At this point we also erase the actual on-disk path and only keep
- // the remapped version -- as is necessary for reproducible builds.
- match source_file.name {
- FileName::Real(ref original_file_name) => {
- let adapted_file_name =
- source_map.path_mapping().to_embeddable_absolute_path(
- original_file_name.clone(),
- working_directory,
- );
-
- if adapted_file_name != *original_file_name {
- let mut adapted: SourceFile = (**source_file).clone();
- adapted.name = FileName::Real(adapted_file_name);
- adapted.name_hash = {
- let mut hasher: StableHasher = StableHasher::new();
- adapted.name.hash(&mut hasher);
- hasher.finish::<u128>()
- };
- Lrc::new(adapted)
- } else {
- // Nothing to adapt
- source_file.clone()
- }
+ let mut adapted = TableBuilder::default();
+
+ // Only serialize `SourceFile`s that were used during the encoding of a `Span`.
+ //
+ // The order in which we encode source files is important here: the on-disk format for
+ // `Span` contains the index of the corresponding `SourceFile`.
+ for (on_disk_index, &source_file_index) in required_source_files.iter().enumerate() {
+ let source_file = &all_source_files[source_file_index];
+ // Don't serialize imported `SourceFile`s, unless we're in a proc-macro crate.
+ assert!(!source_file.is_imported() || self.is_proc_macro);
+
+ // At export time we expand all source file paths to absolute paths because
+ // downstream compilation sessions can have a different compiler working
+ // directory, so relative paths from this or any other upstream crate
+ // won't be valid anymore.
+ //
+ // At this point we also erase the actual on-disk path and only keep
+ // the remapped version -- as is necessary for reproducible builds.
+ let mut source_file = match source_file.name {
+ FileName::Real(ref original_file_name) => {
+ let adapted_file_name = source_map
+ .path_mapping()
+ .to_embeddable_absolute_path(original_file_name.clone(), working_directory);
+
+ if adapted_file_name != *original_file_name {
+ let mut adapted: SourceFile = (**source_file).clone();
+ adapted.name = FileName::Real(adapted_file_name);
+ adapted.name_hash = {
+ let mut hasher: StableHasher = StableHasher::new();
+ adapted.name.hash(&mut hasher);
+ hasher.finish::<u128>()
+ };
+ Lrc::new(adapted)
+ } else {
+ // Nothing to adapt
+ source_file.clone()
}
- // expanded code, not from a file
- _ => source_file.clone(),
- }
- })
- .map(|mut source_file| {
- // We're serializing this `SourceFile` into our crate metadata,
- // so mark it as coming from this crate.
- // This also ensures that we don't try to deserialize the
- // `CrateNum` for a proc-macro dependency - since proc macro
- // dependencies aren't loaded when we deserialize a proc-macro,
- // trying to remap the `CrateNum` would fail.
- if self.is_proc_macro {
- Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
}
- source_file
- })
- .collect::<Vec<_>>();
+ // expanded code, not from a file
+ _ => source_file.clone(),
+ };
+
+ // We're serializing this `SourceFile` into our crate metadata,
+ // so mark it as coming from this crate.
+ // This also ensures that we don't try to deserialize the
+ // `CrateNum` for a proc-macro dependency - since proc macro
+ // dependencies aren't loaded when we deserialize a proc-macro,
+ // trying to remap the `CrateNum` would fail.
+ if self.is_proc_macro {
+ Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
+ }
+
+ let on_disk_index: u32 =
+ on_disk_index.try_into().expect("cannot export more than U32_MAX files");
+ adapted.set(on_disk_index, self.lazy(source_file));
+ }
- self.lazy_array(adapted.iter().map(|rc| &**rc))
+ adapted.encode(&mut self.opaque)
}
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
@@ -817,6 +847,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
| DefKind::Use
| DefKind::ForeignMod
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Impl
| DefKind::Field => true,
DefKind::TyParam
@@ -849,6 +880,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
| DefKind::ForeignMod
| DefKind::TyAlias
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Enum
| DefKind::Union
| DefKind::Impl
@@ -937,6 +969,7 @@ fn should_encode_variances(def_kind: DefKind) -> bool {
| DefKind::ForeignMod
| DefKind::TyAlias
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Impl
| DefKind::Trait
| DefKind::TraitAlias
@@ -973,6 +1006,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Impl
| DefKind::Field
| DefKind::TyParam
@@ -989,6 +1023,103 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
}
}
+fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Ctor(..)
+ | DefKind::Field
+ | DefKind::Fn
+ | DefKind::Const
+ | DefKind::Static(..)
+ | DefKind::TyAlias
+ | DefKind::OpaqueTy
+ | DefKind::ForeignTy
+ | DefKind::Impl
+ | DefKind::AssocFn
+ | DefKind::AssocConst
+ | DefKind::Closure
+ | DefKind::Generator
+ | DefKind::ConstParam
+ | DefKind::AnonConst
+ | DefKind::InlineConst => true,
+
+ DefKind::ImplTraitPlaceholder => {
+ let parent_def_id = tcx.impl_trait_in_trait_parent(def_id.to_def_id());
+ let assoc_item = tcx.associated_item(parent_def_id);
+ match assoc_item.container {
+ // Always encode an RPIT in an impl fn, since it always has a body
+ ty::AssocItemContainer::ImplContainer => true,
+ ty::AssocItemContainer::TraitContainer => {
+ // Encode an RPIT for a trait only if the trait has a default body
+ assoc_item.defaultness(tcx).has_value()
+ }
+ }
+ }
+
+ DefKind::AssocTy => {
+ let assoc_item = tcx.associated_item(def_id);
+ match assoc_item.container {
+ ty::AssocItemContainer::ImplContainer => true,
+ ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
+ }
+ }
+ DefKind::TyParam => {
+ let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(def_id) else { bug!() };
+ let hir::GenericParamKind::Type { default, .. } = param.kind else { bug!() };
+ default.is_some()
+ }
+
+ DefKind::Trait
+ | DefKind::TraitAlias
+ | DefKind::Mod
+ | DefKind::ForeignMod
+ | DefKind::Macro(..)
+ | DefKind::Use
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::ExternCrate => false,
+ }
+}
+
+fn should_encode_const(def_kind: DefKind) -> bool {
+ match def_kind {
+ DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => true,
+
+ DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Ctor(..)
+ | DefKind::Field
+ | DefKind::Fn
+ | DefKind::Static(..)
+ | DefKind::TyAlias
+ | DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
+ | DefKind::ForeignTy
+ | DefKind::Impl
+ | DefKind::AssocFn
+ | DefKind::Closure
+ | DefKind::Generator
+ | DefKind::ConstParam
+ | DefKind::InlineConst
+ | DefKind::AssocTy
+ | DefKind::TyParam
+ | DefKind::Trait
+ | DefKind::TraitAlias
+ | DefKind::Mod
+ | DefKind::ForeignMod
+ | DefKind::Macro(..)
+ | DefKind::Use
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::ExternCrate => false,
+ }
+}
+
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_attrs(&mut self, def_id: LocalDefId) {
let mut attrs = self
@@ -1014,7 +1145,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_kind = tcx.opt_def_kind(local_id);
let Some(def_kind) = def_kind else { continue };
self.tables.opt_def_kind.set(def_id.index, def_kind);
- record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
+ let def_span = tcx.def_span(local_id);
+ record!(self.tables.def_span[def_id] <- def_span);
self.encode_attrs(local_id);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
if let Some(ident_span) = tcx.def_ident_span(def_id) {
@@ -1024,11 +1156,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
}
if should_encode_visibility(def_kind) {
- record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
+ let vis =
+ self.tcx.local_visibility(local_id).map_id(|def_id| def_id.local_def_index);
+ record!(self.tables.visibility[def_id] <- vis);
}
if should_encode_stability(def_kind) {
self.encode_stability(def_id);
self.encode_const_stability(def_id);
+ self.encode_default_body_stability(def_id);
self.encode_deprecation(def_id);
}
if should_encode_variances(def_kind) {
@@ -1044,6 +1179,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
}
}
+ if should_encode_type(tcx, local_id, def_kind) {
+ record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
+ }
+ if let DefKind::TyParam = def_kind {
+ let default = self.tcx.object_lifetime_default(def_id);
+ record!(self.tables.object_lifetime_default[def_id] <- default);
+ }
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
}
@@ -1060,11 +1202,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
- fn encode_item_type(&mut self, def_id: DefId) {
- debug!("EncodeContext::encode_item_type({:?})", def_id);
- record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
- }
-
fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
let tcx = self.tcx;
let variant = &def.variant(index);
@@ -1078,13 +1215,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
- record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+ record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
}));
- self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn {
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
if let Some(ctor_def_id) = variant.ctor_def_id {
@@ -1107,9 +1243,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
- record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+ record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
- self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
@@ -1126,15 +1261,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// code uses it). However, we skip encoding anything relating to child
// items - we encode information about proc-macros later on.
let reexports = if !self.is_proc_macro {
- match tcx.module_reexports(local_def_id) {
- Some(exports) => self.lazy_array(exports),
- _ => LazyArray::empty(),
- }
+ tcx.module_reexports(local_def_id).unwrap_or(&[])
} else {
- LazyArray::empty()
+ &[]
};
- record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
+ record_array!(self.tables.module_reexports[def_id] <- reexports);
if self.is_proc_macro {
// Encode this here because we don't do it in encode_def_ids.
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
@@ -1162,22 +1294,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
- fn encode_field(
- &mut self,
- adt_def: ty::AdtDef<'tcx>,
- variant_index: VariantIdx,
- field_index: usize,
- ) {
- let variant = &adt_def.variant(variant_index);
- let field = &variant.fields[field_index];
-
- let def_id = field.did;
- debug!("EncodeContext::encode_field({:?})", def_id);
-
- record!(self.tables.kind[def_id] <- EntryKind::Field);
- self.encode_item_type(def_id);
- }
-
fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx;
@@ -1191,9 +1307,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
};
record!(self.tables.repr_options[def_id] <- adt_def.repr());
+ record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
- record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data)));
- self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
@@ -1214,18 +1329,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let ast_item = tcx.hir().expect_trait_item(def_id.expect_local());
self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
let trait_item = tcx.associated_item(def_id);
+ self.tables.assoc_container.set(def_id.index, trait_item.container);
match trait_item.kind {
- ty::AssocKind::Const => {
- let rendered = rustc_hir_pretty::to_string(
- &(&self.tcx.hir() as &dyn intravisit::Map<'_>),
- |s| s.print_trait_item(ast_item),
- );
-
- record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::TraitContainer));
- record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default());
- record!(self.tables.rendered_const[def_id] <- rendered);
- }
+ ty::AssocKind::Const => {}
ty::AssocKind::Fn => {
let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() };
match *m {
@@ -1238,24 +1345,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
};
self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
self.tables.constness.set(def_id.index, hir::Constness::NotConst);
- record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
- container: ty::AssocItemContainer::TraitContainer,
- has_self: trait_item.fn_has_self_parameter,
- });
}
ty::AssocKind::Type => {
self.encode_explicit_item_bounds(def_id);
- record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::TraitContainer));
- }
- }
- match trait_item.kind {
- ty::AssocKind::Const | ty::AssocKind::Fn => {
- self.encode_item_type(def_id);
- }
- ty::AssocKind::Type => {
- if ast_item.defaultness.has_value() {
- self.encode_item_type(def_id);
- }
}
}
if trait_item.kind == ty::AssocKind::Fn {
@@ -1270,20 +1362,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
let impl_item = self.tcx.associated_item(def_id);
+ self.tables.assoc_container.set(def_id.index, impl_item.container);
match impl_item.kind {
- ty::AssocKind::Const => {
- if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
- let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
- let const_data = self.encode_rendered_const_for_body(body_id);
-
- record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::ImplContainer));
- record!(self.tables.mir_const_qualif[def_id] <- qualifs);
- record!(self.tables.rendered_const[def_id] <- const_data);
- } else {
- bug!()
- }
- }
ty::AssocKind::Fn => {
let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
@@ -1295,16 +1376,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::Constness::NotConst
};
self.tables.constness.set(def_id.index, constness);
- record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
- container: ty::AssocItemContainer::ImplContainer,
- has_self: impl_item.fn_has_self_parameter,
- });
- }
- ty::AssocKind::Type => {
- record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::ImplContainer));
}
+ ty::AssocKind::Const | ty::AssocKind::Type => {}
}
- self.encode_item_type(def_id);
if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
self.tables.trait_item_def_id.set(def_id.index, trait_item_def_id.into());
}
@@ -1321,40 +1395,43 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
return;
}
- let keys_and_jobs = self
- .tcx
- .mir_keys(())
- .iter()
- .filter_map(|&def_id| {
- let (encode_const, encode_opt) = should_encode_mir(self.tcx, def_id);
- if encode_const || encode_opt {
- Some((def_id, encode_const, encode_opt))
- } else {
- None
- }
- })
- .collect::<Vec<_>>();
- for (def_id, encode_const, encode_opt) in keys_and_jobs.into_iter() {
+ let tcx = self.tcx;
+
+ let keys_and_jobs = tcx.mir_keys(()).iter().filter_map(|&def_id| {
+ let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
+ if encode_const || encode_opt { Some((def_id, encode_const, encode_opt)) } else { None }
+ });
+ for (def_id, encode_const, encode_opt) in keys_and_jobs {
debug_assert!(encode_const || encode_opt);
debug!("EntryBuilder::encode_mir({:?})", def_id);
if encode_opt {
- record!(self.tables.optimized_mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
+ record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
}
if encode_const {
- record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
+ record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));
// FIXME(generic_const_exprs): this feels wrong to have in `encode_mir`
- let abstract_const = self.tcx.thir_abstract_const(def_id);
+ let abstract_const = tcx.thir_abstract_const(def_id);
if let Ok(Some(abstract_const)) = abstract_const {
record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const);
}
+
+ if should_encode_const(tcx.def_kind(def_id)) {
+ let qualifs = tcx.mir_const_qualif(def_id);
+ record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
+ let body_id = tcx.hir().maybe_body_owned_by(def_id);
+ if let Some(body_id) = body_id {
+ let const_data = self.encode_rendered_const_for_body(body_id);
+ record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
+ }
+ }
}
- record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
+ record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
let instance =
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
- let unused = self.tcx.unused_generic_params(instance);
+ let unused = tcx.unused_generic_params(instance);
if !unused.is_empty() {
record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
}
@@ -1385,6 +1462,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
+ fn encode_default_body_stability(&mut self, def_id: DefId) {
+ debug!("EncodeContext::encode_default_body_stability({:?})", def_id);
+
+ // The query lookup can take a measurable amount of time in crates with many items. Check if
+ // the stability attributes are even enabled before using their queries.
+ if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked {
+ if let Some(stab) = self.tcx.lookup_default_body_stability(def_id) {
+ record!(self.tables.lookup_default_body_stability[def_id] <- stab)
+ }
+ }
+ }
+
fn encode_deprecation(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_deprecation({:?})", def_id);
if let Some(depr) = self.tcx.lookup_deprecation(def_id) {
@@ -1405,38 +1494,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
debug!("EncodeContext::encode_info_for_item({:?})", def_id);
- let entry_kind = match item.kind {
- hir::ItemKind::Static(..) => EntryKind::Static,
- hir::ItemKind::Const(_, body_id) => {
- let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id);
- let const_data = self.encode_rendered_const_for_body(body_id);
- record!(self.tables.mir_const_qualif[def_id] <- qualifs);
- record!(self.tables.rendered_const[def_id] <- const_data);
- EntryKind::Const
- }
+ match item.kind {
hir::ItemKind::Fn(ref sig, .., body) => {
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
self.tables.constness.set(def_id.index, sig.header.constness);
- EntryKind::Fn
}
hir::ItemKind::Macro(ref macro_def, _) => {
- EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules)
+ if macro_def.macro_rules {
+ self.tables.macro_rules.set(def_id.index, ());
+ }
+ record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
}
hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod(item.def_id, m);
}
- hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod,
- hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
- hir::ItemKind::TyAlias(..) => EntryKind::Type,
hir::ItemKind::OpaqueTy(..) => {
self.encode_explicit_item_bounds(def_id);
- EntryKind::OpaqueTy
}
hir::ItemKind::Enum(..) => {
let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
- EntryKind::Enum
}
hir::ItemKind::Struct(ref struct_def, _) => {
let adt_def = self.tcx.adt_def(def_id);
@@ -1451,24 +1529,24 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
.map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
let variant = adt_def.non_enum_variant();
- EntryKind::Struct(self.lazy(VariantData {
+ record!(self.tables.variant_data[def_id] <- VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
ctor,
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- }))
+ });
}
hir::ItemKind::Union(..) => {
let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
let variant = adt_def.non_enum_variant();
- EntryKind::Union(self.lazy(VariantData {
+ record!(self.tables.variant_data[def_id] <- VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
ctor: None,
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
- }))
+ });
}
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
self.tables.impl_defaultness.set(def_id.index, *defaultness);
@@ -1494,26 +1572,24 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let polarity = self.tcx.impl_polarity(def_id);
self.tables.impl_polarity.set(def_id.index, polarity);
-
- EntryKind::Impl
}
hir::ItemKind::Trait(..) => {
let trait_def = self.tcx.trait_def(def_id);
record!(self.tables.trait_def[def_id] <- trait_def);
-
- EntryKind::Trait
}
hir::ItemKind::TraitAlias(..) => {
let trait_def = self.tcx.trait_def(def_id);
record!(self.tables.trait_def[def_id] <- trait_def);
-
- EntryKind::TraitAlias
}
hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
bug!("cannot encode info for item {:?}", item)
}
+ hir::ItemKind::Static(..)
+ | hir::ItemKind::Const(..)
+ | hir::ItemKind::ForeignMod { .. }
+ | hir::ItemKind::GlobalAsm(..)
+ | hir::ItemKind::TyAlias(..) => {}
};
- record!(self.tables.kind[def_id] <- entry_kind);
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
hir::ItemKind::Enum(..) => record_array!(self.tables.children[def_id] <-
@@ -1541,18 +1617,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
_ => {}
}
- match item.kind {
- hir::ItemKind::Static(..)
- | hir::ItemKind::Const(..)
- | hir::ItemKind::Fn(..)
- | hir::ItemKind::TyAlias(..)
- | hir::ItemKind::OpaqueTy(..)
- | hir::ItemKind::Enum(..)
- | hir::ItemKind::Struct(..)
- | hir::ItemKind::Union(..)
- | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id),
- _ => {}
- }
if let hir::ItemKind::Fn(..) = item.kind {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
if tcx.is_intrinsic(def_id) {
@@ -1564,12 +1628,43 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
}
}
- }
+ // In some cases, along with the item itself, we also
+ // encode some sub-items. Usually we want some info from the item
+ // so it's easier to do that here then to wait until we would encounter
+ // normally in the visitor walk.
+ match item.kind {
+ hir::ItemKind::Enum(..) => {
+ let def = self.tcx.adt_def(item.def_id.to_def_id());
+ for (i, variant) in def.variants().iter_enumerated() {
+ self.encode_enum_variant_info(def, i);
- fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
- record!(self.tables.kind[def_id] <- kind);
- if encode_type {
- self.encode_item_type(def_id);
+ if let Some(_ctor_def_id) = variant.ctor_def_id {
+ self.encode_enum_variant_ctor(def, i);
+ }
+ }
+ }
+ hir::ItemKind::Struct(ref struct_def, _) => {
+ let def = self.tcx.adt_def(item.def_id.to_def_id());
+ // If the struct has a constructor, encode it.
+ if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
+ let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
+ self.encode_struct_ctor(def, ctor_def_id.to_def_id());
+ }
+ }
+ hir::ItemKind::Impl { .. } => {
+ for &trait_item_def_id in
+ self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+ {
+ self.encode_info_for_impl_item(trait_item_def_id);
+ }
+ }
+ hir::ItemKind::Trait(..) => {
+ for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+ {
+ self.encode_info_for_trait_item(item_def_id);
+ }
+ }
+ _ => {}
}
}
@@ -1584,34 +1679,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ty::Generator(..) => {
let data = self.tcx.generator_kind(def_id).unwrap();
let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
- record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator);
record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
record!(self.tables.generator_diagnostic_data[def_id.to_def_id()] <- generator_diagnostic_data);
}
- ty::Closure(..) => {
- record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Closure);
+ ty::Closure(_, substs) => {
+ record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
}
_ => bug!("closure that is neither generator nor closure"),
}
- self.encode_item_type(def_id.to_def_id());
- if let ty::Closure(def_id, substs) = *ty.kind() {
- record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
- }
- }
-
- fn encode_info_for_anon_const(&mut self, id: hir::HirId) {
- let def_id = self.tcx.hir().local_def_id(id);
- debug!("EncodeContext::encode_info_for_anon_const({:?})", def_id);
- let body_id = self.tcx.hir().body_owned_by(def_id);
- let const_data = self.encode_rendered_const_for_body(body_id);
- let qualifs = self.tcx.mir_const_qualif(def_id);
-
- record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst);
- record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
- record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
- self.encode_item_type(def_id.to_def_id());
}
fn encode_native_libraries(&mut self) -> LazyArray<NativeLib> {
@@ -1670,7 +1747,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.tables.opt_def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local());
- record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id()));
+ let vis = tcx.local_visibility(CRATE_DEF_ID).map_id(|def_id| def_id.local_def_index);
+ record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis);
if let Some(stability) = stability {
record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability);
}
@@ -1709,7 +1787,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_id = id.to_def_id();
self.tables.opt_def_kind.set(def_id.index, DefKind::Macro(macro_kind));
- record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
+ self.tables.proc_macro.set(def_id.index, macro_kind);
self.encode_attrs(id);
record!(self.tables.def_keys[def_id] <- def_key);
record!(self.tables.def_ident_span[def_id] <- span);
@@ -1947,18 +2025,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::Constness::NotConst
};
self.tables.constness.set(def_id.index, constness);
- record!(self.tables.kind[def_id] <- EntryKind::ForeignFn);
- }
- hir::ForeignItemKind::Static(..) => {
- record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic);
- }
- hir::ForeignItemKind::Type => {
- record!(self.tables.kind[def_id] <- EntryKind::ForeignType);
+ record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
+ hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => {}
}
- self.encode_item_type(def_id);
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
- record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
if tcx.is_intrinsic(def_id) {
self.tables.is_intrinsic.set(def_id.index, ());
}
@@ -1977,17 +2048,12 @@ impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
intravisit::walk_expr(self, ex);
self.encode_info_for_expr(ex);
}
- fn visit_anon_const(&mut self, c: &'tcx AnonConst) {
- intravisit::walk_anon_const(self, c);
- self.encode_info_for_anon_const(c.hir_id);
- }
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
intravisit::walk_item(self, item);
match item.kind {
hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these
_ => self.encode_info_for_item(item.def_id.to_def_id(), item),
}
- self.encode_addl_info_for_item(item);
}
fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
intravisit::walk_foreign_item(self, ni);
@@ -2000,29 +2066,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
- fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
- for (variant_index, variant) in adt_def.variants().iter_enumerated() {
- for (field_index, _field) in variant.fields.iter().enumerate() {
- self.encode_field(adt_def, variant_index, field_index);
- }
- }
- }
-
fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
for param in generics.params {
let def_id = self.tcx.hir().local_def_id(param.hir_id);
match param.kind {
- GenericParamKind::Lifetime { .. } => continue,
- GenericParamKind::Type { default, .. } => {
- self.encode_info_for_generic_param(
- def_id.to_def_id(),
- EntryKind::TypeParam,
- default.is_some(),
- );
- }
- GenericParamKind::Const { ref default, .. } => {
+ hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => {}
+ hir::GenericParamKind::Const { ref default, .. } => {
let def_id = def_id.to_def_id();
- self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
if default.is_some() {
record!(self.tables.const_param_default[def_id] <- self.tcx.const_param_default(def_id))
}
@@ -2036,68 +2086,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.encode_info_for_closure(expr.hir_id);
}
}
-
- /// In some cases, along with the item itself, we also
- /// encode some sub-items. Usually we want some info from the item
- /// so it's easier to do that here then to wait until we would encounter
- /// normally in the visitor walk.
- fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
- match item.kind {
- hir::ItemKind::Static(..)
- | hir::ItemKind::Const(..)
- | hir::ItemKind::Fn(..)
- | hir::ItemKind::Macro(..)
- | hir::ItemKind::Mod(..)
- | hir::ItemKind::ForeignMod { .. }
- | hir::ItemKind::GlobalAsm(..)
- | hir::ItemKind::ExternCrate(..)
- | hir::ItemKind::Use(..)
- | hir::ItemKind::TyAlias(..)
- | hir::ItemKind::OpaqueTy(..)
- | hir::ItemKind::TraitAlias(..) => {
- // no sub-item recording needed in these cases
- }
- hir::ItemKind::Enum(..) => {
- let def = self.tcx.adt_def(item.def_id.to_def_id());
- self.encode_fields(def);
-
- for (i, variant) in def.variants().iter_enumerated() {
- self.encode_enum_variant_info(def, i);
-
- if let Some(_ctor_def_id) = variant.ctor_def_id {
- self.encode_enum_variant_ctor(def, i);
- }
- }
- }
- hir::ItemKind::Struct(ref struct_def, _) => {
- let def = self.tcx.adt_def(item.def_id.to_def_id());
- self.encode_fields(def);
-
- // If the struct has a constructor, encode it.
- if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
- let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
- self.encode_struct_ctor(def, ctor_def_id.to_def_id());
- }
- }
- hir::ItemKind::Union(..) => {
- let def = self.tcx.adt_def(item.def_id.to_def_id());
- self.encode_fields(def);
- }
- hir::ItemKind::Impl { .. } => {
- for &trait_item_def_id in
- self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
- {
- self.encode_info_for_impl_item(trait_item_def_id);
- }
- }
- hir::ItemKind::Trait(..) => {
- for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
- {
- self.encode_info_for_trait_item(item_def_id);
- }
- }
- }
- }
}
/// Used to prefetch queries which will be needed later by metadata encoding.
@@ -2220,7 +2208,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
let mut encoder = opaque::FileEncoder::new(path)
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to create file encoder: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailCreateFileEncoder { err }));
encoder.emit_raw_bytes(METADATA_HEADER);
// Will be filled with the root position after encoding everything.
@@ -2228,7 +2216,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
let source_map_files = tcx.sess.source_map().files();
let source_file_cache = (source_map_files[0].clone(), 0);
- let required_source_files = Some(GrowableBitSet::with_capacity(source_map_files.len()));
+ let required_source_files = Some(FxIndexSet::default());
drop(source_map_files);
let hygiene_ctxt = HygieneEncodeContext::default();
@@ -2246,6 +2234,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
required_source_files,
is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
hygiene_ctxt: &hygiene_ctxt,
+ symbol_table: Default::default(),
};
// Encode the rustc version string in a predictable location.
@@ -2264,10 +2253,10 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
// Encode the root position.
let header = METADATA_HEADER.len();
file.seek(std::io::SeekFrom::Start(header as u64))
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to seek the file: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailSeekFile { err }));
let pos = root.position.get();
file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to write to the file: {}", err)));
+ .unwrap_or_else(|err| tcx.sess.emit_fatal(FailWriteFile { err }));
// Return to the position where we are before writing the root position.
file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 66bdecc30..748b3afec 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -16,6 +16,7 @@ use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
+use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
use rustc_middle::mir;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::Providers;
@@ -249,7 +250,7 @@ pub(crate) struct CrateRoot {
def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
- source_map: LazyArray<rustc_span::SourceFile>,
+ source_map: LazyTable<u32, LazyValue<rustc_span::SourceFile>>,
compiler_builtins: bool,
needs_allocator: bool,
@@ -333,16 +334,16 @@ macro_rules! define_tables {
}
define_tables! {
- kind: Table<DefIndex, LazyValue<EntryKind>>,
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
children: Table<DefIndex, LazyArray<DefIndex>>,
opt_def_kind: Table<DefIndex, DefKind>,
- visibility: Table<DefIndex, LazyValue<ty::Visibility>>,
+ visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
def_span: Table<DefIndex, LazyValue<Span>>,
def_ident_span: Table<DefIndex, LazyValue<Span>>,
lookup_stability: Table<DefIndex, LazyValue<attr::Stability>>,
lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
+ lookup_default_body_stability: Table<DefIndex, LazyValue<attr::DefaultBodyStability>>,
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
// As an optimization, a missing entry indicates an empty `&[]`.
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
@@ -357,6 +358,7 @@ define_tables! {
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
+ object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
@@ -390,39 +392,13 @@ define_tables! {
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
may_have_doc_links: Table<DefIndex, ()>,
-}
-
-#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
-enum EntryKind {
- AnonConst,
- Const,
- Static,
- ForeignStatic,
- ForeignMod,
- ForeignType,
- GlobalAsm,
- Type,
- TypeParam,
- ConstParam,
- OpaqueTy,
- Enum,
- Field,
- Variant(LazyValue<VariantData>),
- Struct(LazyValue<VariantData>),
- Union(LazyValue<VariantData>),
- Fn,
- ForeignFn,
- Mod(LazyArray<ModChild>),
- MacroDef(LazyValue<ast::MacArgs>, /*macro_rules*/ bool),
- ProcMacro(MacroKind),
- Closure,
- Generator,
- Trait,
- Impl,
- AssocFn { container: ty::AssocItemContainer, has_self: bool },
- AssocType(ty::AssocItemContainer),
- AssocConst(ty::AssocItemContainer),
- TraitAlias,
+ variant_data: Table<DefIndex, LazyValue<VariantData>>,
+ assoc_container: Table<DefIndex, ty::AssocItemContainer>,
+ // Slot is full when macro is macro_rules.
+ macro_rules: Table<DefIndex, ()>,
+ macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
+ proc_macro: Table<DefIndex, MacroKind>,
+ module_reexports: Table<DefIndex, LazyArray<ModChild>>,
}
#[derive(TyEncodable, TyDecodable)]
@@ -444,6 +420,11 @@ const TAG_VALID_SPAN_LOCAL: u8 = 0;
const TAG_VALID_SPAN_FOREIGN: u8 = 1;
const TAG_PARTIAL_SPAN: u8 = 2;
+// Tags for encoding Symbol's
+const SYMBOL_STR: u8 = 0;
+const SYMBOL_OFFSET: u8 = 1;
+const SYMBOL_PREINTERNED: u8 = 2;
+
pub fn provide(providers: &mut Providers) {
encoder::provide(providers);
decoder::provide(providers);
@@ -451,7 +432,6 @@ pub fn provide(providers: &mut Providers) {
trivially_parameterized_over_tcx! {
VariantData,
- EntryKind,
RawDefId,
TraitImpls,
IncoherentImpls,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 21841ae25..e7c1abd12 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -10,7 +10,6 @@ use rustc_span::hygiene::MacroKind;
use std::convert::TryInto;
use std::marker::PhantomData;
use std::num::NonZeroUsize;
-use tracing::debug;
/// Helper trait, for encoding to, and decoding from, a fixed number of bytes.
/// Used mainly for Lazy positions and lengths.
@@ -51,7 +50,7 @@ macro_rules! fixed_size_enum {
}
match b[0] - 1 {
$(${index()} => Some($($pat)*),)*
- _ => panic!("Unexpected ImplPolarity code: {:?}", b[0]),
+ _ => panic!("Unexpected {} code: {:?}", stringify!($ty), b[0]),
}
}
@@ -91,6 +90,7 @@ fixed_size_enum! {
( AnonConst )
( InlineConst )
( OpaqueTy )
+ ( ImplTraitPlaceholder )
( Field )
( LifetimeParam )
( GlobalAsm )
@@ -141,6 +141,21 @@ fixed_size_enum! {
}
}
+fixed_size_enum! {
+ ty::AssocItemContainer {
+ ( TraitContainer )
+ ( ImplContainer )
+ }
+}
+
+fixed_size_enum! {
+ MacroKind {
+ ( Attr )
+ ( Bang )
+ ( Derive )
+ }
+}
+
// We directly encode `DefPathHash` because a `LazyValue` would incur a 25% cost.
impl FixedSizeEncoding for Option<DefPathHash> {
type ByteArray = [u8; 16];
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 008d2c709..cca17a4ec 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -7,34 +7,35 @@ edition = "2021"
doctest = false
[dependencies]
-rustc_arena = { path = "../rustc_arena" }
bitflags = "1.2.1"
+chalk-ir = "0.80.0"
either = "1.5.0"
gsgdt = "0.1.2"
-tracing = "0.1"
-rustc-rayon = { version = "0.4.0", optional = true }
-rustc-rayon-core = { version = "0.4.0", optional = true }
polonius-engine = "0.13.0"
+rand = "0.8.4"
+rand_xoshiro = "0.6.0"
rustc_apfloat = { path = "../rustc_apfloat" }
+rustc_arena = { path = "../rustc_arena" }
+rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
-rustc_feature = { path = "../rustc_feature" }
-rustc_hir = { path = "../rustc_hir" }
-rustc_target = { path = "../rustc_target" }
-rustc_macros = { path = "../rustc_macros" }
rustc_data_structures = { path = "../rustc_data_structures" }
-rustc_query_system = { path = "../rustc_query_system" }
rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
rustc_graphviz = { path = "../rustc_graphviz" }
+rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_query_system = { path = "../rustc_query_system" }
+rustc-rayon-core = { version = "0.4.0", optional = true }
+rustc-rayon = { version = "0.4.0", optional = true }
rustc_serialize = { path = "../rustc_serialize" }
-rustc_ast = { path = "../rustc_ast" }
-rustc_span = { path = "../rustc_span" }
-chalk-ir = "0.80.0"
-smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
rustc_type_ir = { path = "../rustc_type_ir" }
-rand = "0.8.4"
-rand_xoshiro = "0.6.0"
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
+tracing = "0.1"
[features]
rustc_use_parallel_compiler = ["rustc-rayon", "rustc-rayon-core"]
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index b94de537d..6bdf5a023 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -100,7 +100,9 @@ macro_rules! arena_types {
[decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::def_id::LocalDefId>,
[decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,
- [] dep_kind: rustc_middle::dep_graph::DepKindStruct,
+ [] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>,
+
+ [decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
]);
)
}
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 2d095438f..1fa0c6bab 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -74,7 +74,7 @@ pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value
/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual
/// jump table instead of large matches.
-pub struct DepKindStruct {
+pub struct DepKindStruct<'tcx> {
/// Anonymous queries cannot be replayed from one compiler invocation to the next.
/// When their result is needed, it is recomputed. They are useful for fine-grained
/// dependency tracking, and caching within one compiler invocation.
@@ -124,10 +124,10 @@ pub struct DepKindStruct {
/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
/// `DefId` in `tcx.def_path_hash_to_def_id`.
- pub force_from_dep_node: Option<fn(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool>,
+ pub force_from_dep_node: Option<fn(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool>,
/// Invoke a query to put the on-disk cached value in memory.
- pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'_>, DepNode)>,
+ pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'tcx>, DepNode)>,
}
impl DepKind {
@@ -143,12 +143,10 @@ impl DepKind {
}
macro_rules! define_dep_nodes {
- (<$tcx:tt>
- $(
- [$($attrs:tt)*]
- $variant:ident $(( $tuple_arg_ty:ty $(,)? ))*
- ,)*
- ) => (
+ (
+ $($(#[$attr:meta])*
+ [$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty,)*) => {
+
#[macro_export]
macro_rules! make_dep_kind_array {
($mod:ident) => {[ $($mod::$variant()),* ]};
@@ -158,7 +156,7 @@ macro_rules! define_dep_nodes {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
#[allow(non_camel_case_types)]
pub enum DepKind {
- $($variant),*
+ $( $( #[$attr] )* $variant),*
}
fn dep_kind_from_label_string(label: &str) -> Result<DepKind, ()> {
@@ -176,24 +174,17 @@ macro_rules! define_dep_nodes {
pub const $variant: &str = stringify!($variant);
)*
}
- );
+ };
}
-rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
- // We use this for most things when incr. comp. is turned off.
- [] Null,
-
- // We use this to create a forever-red node.
- [] Red,
-
- [anon] TraitSelect,
-
- // WARNING: if `Symbol` is changed, make sure you update `make_compile_codegen_unit` below.
- [] CompileCodegenUnit(Symbol),
-
- // WARNING: if `MonoItem` is changed, make sure you update `make_compile_mono_item` below.
- // Only used by rustc_codegen_cranelift
- [] CompileMonoItem(MonoItem),
+rustc_query_append!(define_dep_nodes![
+ /// We use this for most things when incr. comp. is turned off.
+ [] fn Null() -> (),
+ /// We use this to create a forever-red node.
+ [] fn Red() -> (),
+ [] fn TraitSelect() -> (),
+ [] fn CompileCodegenUnit() -> (),
+ [] fn CompileMonoItem() -> (),
]);
// WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys.
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
new file mode 100644
index 000000000..18b31a75b
--- /dev/null
+++ b/compiler/rustc_middle/src/error.rs
@@ -0,0 +1,50 @@
+use rustc_macros::SessionDiagnostic;
+use rustc_span::Span;
+
+use crate::ty::Ty;
+
+#[derive(SessionDiagnostic)]
+#[diag(middle::drop_check_overflow, code = "E0320")]
+#[note]
+pub struct DropCheckOverflow<'tcx> {
+ #[primary_span]
+ pub span: Span,
+ pub ty: Ty<'tcx>,
+ pub overflow_ty: Ty<'tcx>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(middle::opaque_hidden_type_mismatch)]
+pub struct OpaqueHiddenTypeMismatch<'tcx> {
+ pub self_ty: Ty<'tcx>,
+ pub other_ty: Ty<'tcx>,
+ #[primary_span]
+ #[label]
+ pub other_span: Span,
+ #[subdiagnostic]
+ pub sub: TypeMismatchReason,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum TypeMismatchReason {
+ #[label(middle::conflict_types)]
+ ConflictType {
+ #[primary_span]
+ span: Span,
+ },
+ #[note(middle::previous_use_here)]
+ PreviousUse {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(middle::limit_invalid)]
+pub struct LimitInvalid<'a> {
+ #[primary_span]
+ pub span: Span,
+ #[label]
+ pub value_span: Span,
+ pub error_str: &'a str,
+}
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 47b04c33e..30a23c342 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -17,28 +17,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
-fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
- match node {
- Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
- | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
- | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
- Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
- | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
- Some(fn_decl)
- }
- _ => None,
- }
-}
-
-pub fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
- match &node {
- Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
- | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
- | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(sig),
- _ => None,
- }
-}
-
#[inline]
pub fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
match node {
@@ -146,10 +124,12 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
}
impl<'hir> Map<'hir> {
+ #[inline]
pub fn krate(self) -> &'hir Crate<'hir> {
self.tcx.hir_crate(())
}
+ #[inline]
pub fn root_module(self) -> &'hir Mod<'hir> {
match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) {
Some(OwnerNode::Crate(item)) => item,
@@ -157,14 +137,17 @@ impl<'hir> Map<'hir> {
}
}
+ #[inline]
pub fn items(self) -> impl Iterator<Item = ItemId> + 'hir {
self.tcx.hir_crate_items(()).items.iter().copied()
}
+ #[inline]
pub fn module_items(self, module: LocalDefId) -> impl Iterator<Item = ItemId> + 'hir {
self.tcx.hir_module_items(module).items()
}
+ #[inline]
pub fn par_for_each_item(self, f: impl Fn(ItemId) + Sync + Send) {
par_for_each_in(&self.tcx.hir_crate_items(()).items[..], |id| f(*id));
}
@@ -229,7 +212,13 @@ impl<'hir> Map<'hir> {
ItemKind::Fn(..) => DefKind::Fn,
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
ItemKind::Mod(..) => DefKind::Mod,
- ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
+ ItemKind::OpaqueTy(ref opaque) => {
+ if opaque.in_trait {
+ DefKind::ImplTraitPlaceholder
+ } else {
+ DefKind::OpaqueTy
+ }
+ }
ItemKind::TyAlias(..) => DefKind::TyAlias,
ItemKind::Enum(..) => DefKind::Enum,
ItemKind::Struct(..) => DefKind::Struct,
@@ -297,6 +286,8 @@ impl<'hir> Map<'hir> {
| Node::Infer(_)
| Node::TraitRef(_)
| Node::Pat(_)
+ | Node::PatField(_)
+ | Node::ExprField(_)
| Node::Local(_)
| Node::Param(_)
| Node::Arm(_)
@@ -306,6 +297,9 @@ impl<'hir> Map<'hir> {
Some(def_kind)
}
+ /// Finds the id of the parent node to this one.
+ ///
+ /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
pub fn find_parent_node(self, id: HirId) -> Option<HirId> {
if id.local_id == ItemLocalId::from_u32(0) {
Some(self.tcx.hir_owner_parent(id.owner))
@@ -313,6 +307,8 @@ impl<'hir> Map<'hir> {
let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
let node = owner.nodes[id.local_id].as_ref()?;
let hir_id = HirId { owner: id.owner, local_id: node.parent };
+ // HIR indexing should have checked that.
+ debug_assert_ne!(id.local_id, node.parent);
Some(hir_id)
}
}
@@ -382,7 +378,7 @@ impl<'hir> Map<'hir> {
pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
if let Some(node) = self.find(hir_id) {
- fn_decl(node)
+ node.fn_decl()
} else {
bug!("no node for hir_id `{}`", hir_id)
}
@@ -390,7 +386,7 @@ impl<'hir> Map<'hir> {
pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
if let Some(node) = self.find(hir_id) {
- fn_sig(node)
+ node.fn_sig()
} else {
bug!("no node for hir_id `{}`", hir_id)
}
@@ -487,11 +483,13 @@ impl<'hir> Map<'hir> {
/// Returns an iterator of the `DefId`s for all body-owners in this
/// crate. If you would prefer to iterate over the bodies
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
+ #[inline]
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
self.tcx.hir_crate_items(()).body_owners.iter().copied()
}
- pub fn par_body_owners<F: Fn(LocalDefId) + Sync + Send>(self, f: F) {
+ #[inline]
+ pub fn par_body_owners(self, f: impl Fn(LocalDefId) + Sync + Send) {
par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id));
}
@@ -499,7 +497,9 @@ impl<'hir> Map<'hir> {
let def_kind = self.tcx.def_kind(def_id);
match def_kind {
DefKind::Trait | DefKind::TraitAlias => def_id,
- DefKind::TyParam | DefKind::ConstParam => self.tcx.local_parent(def_id),
+ DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => {
+ self.tcx.local_parent(def_id)
+ }
_ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind),
}
}
@@ -508,7 +508,9 @@ impl<'hir> Map<'hir> {
let def_kind = self.tcx.def_kind(def_id);
match def_kind {
DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper,
- DefKind::TyParam | DefKind::ConstParam => self.tcx.item_name(def_id.to_def_id()),
+ DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => {
+ self.tcx.item_name(def_id.to_def_id())
+ }
_ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind),
}
}
@@ -624,35 +626,22 @@ impl<'hir> Map<'hir> {
}
}
- #[cfg(not(parallel_compiler))]
#[inline]
- pub fn par_for_each_module(self, f: impl Fn(LocalDefId)) {
- self.for_each_module(f)
- }
-
- #[cfg(parallel_compiler)]
- pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + Sync) {
- use rustc_data_structures::sync::{par_iter, ParallelIterator};
- par_iter_submodules(self.tcx, CRATE_DEF_ID, &f);
-
- fn par_iter_submodules<F>(tcx: TyCtxt<'_>, module: LocalDefId, f: &F)
- where
- F: Fn(LocalDefId) + Sync,
- {
- (*f)(module);
- let items = tcx.hir_module_items(module);
- par_iter(&items.submodules[..]).for_each(|&sm| par_iter_submodules(tcx, sm, f));
- }
+ pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + Sync + Send) {
+ let crate_items = self.tcx.hir_crate_items(());
+ par_for_each_in(&crate_items.submodules[..], |module| f(*module))
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
+ #[inline]
pub fn parent_iter(self, current_id: HirId) -> ParentHirIterator<'hir> {
ParentHirIterator { current_id, map: self }
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
+ #[inline]
pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> {
ParentOwnerIterator { current_id, map: self }
}
@@ -1020,6 +1009,7 @@ impl<'hir> Map<'hir> {
Node::Field(field) => field.span,
Node::AnonConst(constant) => self.body(constant.body).value.span,
Node::Expr(expr) => expr.span,
+ Node::ExprField(field) => field.span,
Node::Stmt(stmt) => stmt.span,
Node::PathSegment(seg) => {
let ident_span = seg.ident.span;
@@ -1030,6 +1020,7 @@ impl<'hir> Map<'hir> {
Node::TypeBinding(tb) => tb.span,
Node::TraitRef(tr) => tr.path.span,
Node::Pat(pat) => pat.span,
+ Node::PatField(field) => field.span,
Node::Arm(arm) => arm.span,
Node::Block(block) => block.span,
Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)),
@@ -1204,7 +1195,13 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
ItemKind::ForeignMod { .. } => "foreign mod",
ItemKind::GlobalAsm(..) => "global asm",
ItemKind::TyAlias(..) => "ty",
- ItemKind::OpaqueTy(..) => "opaque type",
+ ItemKind::OpaqueTy(ref opaque) => {
+ if opaque.in_trait {
+ "opaque type in trait"
+ } else {
+ "opaque type"
+ }
+ }
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union",
@@ -1241,12 +1238,14 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
}
Some(Node::AnonConst(_)) => node_str("const"),
Some(Node::Expr(_)) => node_str("expr"),
+ Some(Node::ExprField(_)) => node_str("expr field"),
Some(Node::Stmt(_)) => node_str("stmt"),
Some(Node::PathSegment(_)) => node_str("path segment"),
Some(Node::Ty(_)) => node_str("type"),
Some(Node::TypeBinding(_)) => node_str("type binding"),
Some(Node::TraitRef(_)) => node_str("trait ref"),
Some(Node::Pat(_)) => node_str("pat"),
+ Some(Node::PatField(_)) => node_str("pattern field"),
Some(Node::Param(_)) => node_str("param"),
Some(Node::Arm(_)) => node_str("arm"),
Some(Node::Block(_)) => node_str("block"),
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 200de9079..d3cf519b6 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -22,6 +22,7 @@
//! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
use crate::infer::MemberConstraint;
+use crate::mir::ConstraintCategory;
use crate::ty::subst::GenericArg;
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
use rustc_index::vec::IndexVec;
@@ -43,6 +44,15 @@ pub struct Canonical<'tcx, V> {
pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
+impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> {
+ fn try_fold_with<F: ty::FallibleTypeFolder<'tcx>>(
+ self,
+ folder: &mut F,
+ ) -> Result<Self, F::Error> {
+ ty::util::fold_list(self, folder, |tcx, v| tcx.intern_canonical_var_infos(v))
+ }
+}
+
/// A set of values corresponding to the canonical variables from some
/// `Canonical`. You can give these values to
/// `canonical_value.substitute` to substitute them into the canonical
@@ -89,6 +99,7 @@ impl<'tcx> Default for OriginalQueryValues<'tcx> {
/// a copy of the canonical value in some other inference context,
/// with fresh inference variables replacing the canonical values.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
+#[derive(TypeFoldable, TypeVisitable)]
pub struct CanonicalVarInfo<'tcx> {
pub kind: CanonicalVarKind<'tcx>,
}
@@ -114,6 +125,7 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
/// in the type-theory sense of the term -- i.e., a "meta" type system
/// that analyzes type-like values.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
+#[derive(TypeFoldable, TypeVisitable)]
pub enum CanonicalVarKind<'tcx> {
/// Some kind of type inference variable.
Ty(CanonicalTyVarKind),
@@ -290,20 +302,15 @@ impl<'tcx, V> Canonical<'tcx, V> {
}
}
-pub type QueryOutlivesConstraint<'tcx> =
- ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>;
+pub type QueryOutlivesConstraint<'tcx> = (
+ ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>,
+ ConstraintCategory<'tcx>,
+);
TrivialTypeTraversalAndLiftImpls! {
for <'tcx> {
crate::infer::canonical::Certainty,
- crate::infer::canonical::CanonicalVarInfo<'tcx>,
- crate::infer::canonical::CanonicalVarKind<'tcx>,
- }
-}
-
-TrivialTypeTraversalImpls! {
- for <'tcx> {
- crate::infer::canonical::CanonicalVarInfos<'tcx>,
+ crate::infer::canonical::CanonicalTyVarKind,
}
}
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index ef06c457b..01b9277b9 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -26,13 +26,12 @@
#![feature(allocator_api)]
#![feature(array_windows)]
#![feature(assert_matches)]
-#![feature(backtrace)]
#![feature(box_patterns)]
#![feature(core_intrinsics)]
#![feature(discriminant_kind)]
#![feature(exhaustive_patterns)]
#![feature(get_mut_unchecked)]
-#![feature(generic_associated_types)]
+#![cfg_attr(bootstrap, feature(generic_associated_types))]
#![feature(if_let_guard)]
#![feature(map_first_last)]
#![feature(negative_impls)]
@@ -41,7 +40,7 @@
#![feature(new_uninit)]
#![feature(once_cell)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(trusted_len)]
#![feature(type_alias_impl_trait)]
@@ -87,6 +86,7 @@ pub mod query;
pub mod arena;
#[macro_use]
pub mod dep_graph;
+pub(crate) mod error;
pub mod hir;
pub mod infer;
pub mod lint;
@@ -96,6 +96,7 @@ pub mod mir;
pub mod thir;
pub mod traits;
pub mod ty;
+mod values;
pub mod util {
pub mod bug;
diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs
index c8e78747d..5ff014c78 100644
--- a/compiler/rustc_middle/src/metadata.rs
+++ b/compiler/rustc_middle/src/metadata.rs
@@ -2,6 +2,7 @@ use crate::ty;
use rustc_hir::def::Res;
use rustc_macros::HashStable;
+use rustc_span::def_id::DefId;
use rustc_span::symbol::Ident;
use rustc_span::Span;
@@ -18,7 +19,7 @@ pub struct ModChild {
/// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
pub res: Res<!>,
/// Visibility of the item.
- pub vis: ty::Visibility,
+ pub vis: ty::Visibility<DefId>,
/// Span of the item.
pub span: Span,
/// A proper `macro_rules` item (not a reexport).
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index cc9706f2d..31c20fa14 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -18,11 +18,11 @@ impl<'tcx> TyCtxt<'tcx> {
/// Returns the `DefId` for a given `LangItem`.
/// If not found, fatally aborts compilation.
pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
- self.lang_items().require(lang_item).unwrap_or_else(|msg| {
+ self.lang_items().require(lang_item).unwrap_or_else(|err| {
if let Some(span) = span {
- self.sess.span_fatal(span, &msg)
+ self.sess.span_fatal(span, err.to_string())
} else {
- self.sess.fatal(&msg)
+ self.sess.fatal(err.to_string())
}
})
}
diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs
index acced0492..53c4d9267 100644
--- a/compiler/rustc_middle/src/middle/limits.rs
+++ b/compiler/rustc_middle/src/middle/limits.rs
@@ -10,6 +10,7 @@
//! just peeks and looks for that attribute.
use crate::bug;
+use crate::error::LimitInvalid;
use crate::ty;
use rustc_ast::Attribute;
use rustc_session::Session;
@@ -56,9 +57,6 @@ fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: u
match s.as_str().parse() {
Ok(n) => return Limit::new(n),
Err(e) => {
- let mut err =
- sess.struct_span_err(attr.span, "`limit` must be a non-negative integer");
-
let value_span = attr
.meta()
.and_then(|meta| meta.name_value_literal_span())
@@ -74,9 +72,7 @@ fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: u
IntErrorKind::Zero => bug!("zero is a valid `limit`"),
kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
};
-
- err.span_label(value_span, error_str);
- err.emit();
+ sess.emit_err(LimitInvalid { span: attr.span, value_span, error_str });
}
}
}
diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs
index 9b2f44567..a171f5711 100644
--- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs
+++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs
@@ -10,7 +10,7 @@ use rustc_macros::HashStable;
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum Region {
Static,
- EarlyBound(/* index */ u32, /* lifetime decl */ DefId),
+ EarlyBound(/* lifetime decl */ DefId),
LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* lifetime decl */ DefId),
Free(DefId, /* lifetime decl */ DefId),
}
@@ -35,7 +35,13 @@ impl<T: PartialEq> Set1<T> {
}
}
-pub type ObjectLifetimeDefault = Set1<Region>;
+#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
+pub enum ObjectLifetimeDefault {
+ Empty,
+ Static,
+ Ambiguous,
+ Param(DefId),
+}
/// Maps the id of each lifetime reference to the lifetime decl
/// that it corresponds to.
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 414912dd0..d182929c4 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -5,7 +5,7 @@ pub use self::StabilityLevel::*;
use crate::ty::{self, DefIdTree, TyCtxt};
use rustc_ast::NodeId;
-use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
+use rustc_attr::{self as attr, ConstStability, DefaultBodyStability, Deprecation, Stability};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diagnostic};
use rustc_feature::GateIssue;
@@ -61,6 +61,7 @@ pub struct Index {
/// are filled by the annotator.
pub stab_map: FxHashMap<LocalDefId, Stability>,
pub const_stab_map: FxHashMap<LocalDefId, ConstStability>,
+ pub default_body_stab_map: FxHashMap<LocalDefId, DefaultBodyStability>,
pub depr_map: FxHashMap<LocalDefId, DeprecationEntry>,
/// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]`
/// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute
@@ -86,6 +87,10 @@ impl Index {
self.const_stab_map.get(&def_id).copied()
}
+ pub fn local_default_body_stability(&self, def_id: LocalDefId) -> Option<DefaultBodyStability> {
+ self.default_body_stab_map.get(&def_id).copied()
+ }
+
pub fn local_deprecation_entry(&self, def_id: LocalDefId) -> Option<DeprecationEntry> {
self.depr_map.get(&def_id).cloned()
}
@@ -288,7 +293,7 @@ fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
// These are not visible outside crate; therefore
// stability markers are irrelevant, if even present.
- ty::Visibility::Restricted(..) | ty::Visibility::Invisible => true,
+ ty::Visibility::Restricted(..) => true,
}
}
@@ -416,6 +421,12 @@ impl<'tcx> TyCtxt<'tcx> {
return EvalResult::Allow;
}
+ // Only the cross-crate scenario matters when checking unstable APIs
+ let cross_crate = !def_id.is_local();
+ if !cross_crate {
+ return EvalResult::Allow;
+ }
+
let stability = self.lookup_stability(def_id);
debug!(
"stability: \
@@ -423,12 +434,6 @@ impl<'tcx> TyCtxt<'tcx> {
def_id, span, stability
);
- // Only the cross-crate scenario matters when checking unstable APIs
- let cross_crate = !def_id.is_local();
- if !cross_crate {
- return EvalResult::Allow;
- }
-
// Issue #38412: private items lack stability markers.
if skip_stability_check_due_to_privacy(self, def_id) {
return EvalResult::Allow;
@@ -492,6 +497,62 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
+ /// Evaluates the default-impl stability of an item.
+ ///
+ /// Returns `EvalResult::Allow` if the item's default implementation is stable, or unstable but the corresponding
+ /// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending
+ /// unstable feature otherwise.
+ pub fn eval_default_body_stability(self, def_id: DefId, span: Span) -> EvalResult {
+ let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
+ if !is_staged_api {
+ return EvalResult::Allow;
+ }
+
+ // Only the cross-crate scenario matters when checking unstable APIs
+ let cross_crate = !def_id.is_local();
+ if !cross_crate {
+ return EvalResult::Allow;
+ }
+
+ let stability = self.lookup_default_body_stability(def_id);
+ debug!(
+ "body stability: inspecting def_id={def_id:?} span={span:?} of stability={stability:?}"
+ );
+
+ // Issue #38412: private items lack stability markers.
+ if skip_stability_check_due_to_privacy(self, def_id) {
+ return EvalResult::Allow;
+ }
+
+ match stability {
+ Some(DefaultBodyStability {
+ level: attr::Unstable { reason, issue, is_soft, .. },
+ feature,
+ }) => {
+ if span.allows_unstable(feature) {
+ debug!("body stability: skipping span={:?} since it is internal", span);
+ return EvalResult::Allow;
+ }
+ if self.features().active(feature) {
+ return EvalResult::Allow;
+ }
+
+ EvalResult::Deny {
+ feature,
+ reason: reason.to_opt_reason(),
+ issue,
+ suggestion: None,
+ is_soft,
+ }
+ }
+ Some(_) => {
+ // Stable APIs are always ok to call
+ EvalResult::Allow
+ }
+ None => EvalResult::Unmarked,
+ }
+ }
+
/// Checks if an item is stable or error out.
///
/// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 78080fcd5..752cbdeae 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -86,7 +86,7 @@ impl<'tcx> BasicBlocks<'tcx> {
///
/// You will only ever need this if you have also called [`BasicBlocks::as_mut_preserves_cfg`].
/// All other methods that allow you to mutate the basic blocks also call this method
- /// themselves, thereby avoiding any risk of accidentaly cache invalidation.
+ /// themselves, thereby avoiding any risk of accidentally cache invalidation.
pub fn invalidate_cfg_cache(&mut self) {
self.predecessor_cache.invalidate();
self.switch_source_cache.invalidate();
diff --git a/compiler/rustc_middle/src/mir/generic_graph.rs b/compiler/rustc_middle/src/mir/generic_graph.rs
index f3621cd99..d1f3561c0 100644
--- a/compiler/rustc_middle/src/mir/generic_graph.rs
+++ b/compiler/rustc_middle/src/mir/generic_graph.rs
@@ -12,14 +12,14 @@ pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Grap
// Nodes
let nodes: Vec<Node> = body
- .basic_blocks()
+ .basic_blocks
.iter_enumerated()
.map(|(block, _)| bb_to_graph_node(block, body, dark_mode))
.collect();
// Edges
let mut edges = Vec::new();
- for (source, _) in body.basic_blocks().iter_enumerated() {
+ for (source, _) in body.basic_blocks.iter_enumerated() {
let def_id = body.source.def_id();
let terminator = body[source].terminator();
let labels = terminator.kind.fmt_successor_labels();
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index db7e0fb8a..37ec04b07 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -16,8 +16,8 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
use super::{
read_target_uint, write_target_uint, AllocId, InterpError, InterpResult, Pointer, Provenance,
- ResourceExhaustionInfo, Scalar, ScalarMaybeUninit, ScalarSizeMismatch, UndefinedBehaviorInfo,
- UninitBytesAccess, UnsupportedOpInfo,
+ ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, UndefinedBehaviorInfo, UninitBytesAccess,
+ UnsupportedOpInfo,
};
use crate::ty;
@@ -34,11 +34,11 @@ pub struct Allocation<Prov = AllocId, Extra = ()> {
/// The actual bytes of the allocation.
/// Note that the bytes of a pointer represent the offset of the pointer.
bytes: Box<[u8]>,
- /// Maps from byte addresses to extra data for each pointer.
+ /// Maps from byte addresses to extra provenance data for each pointer.
/// Only the first byte of a pointer is inserted into the map; i.e.,
/// every entry in this map applies to `pointer_size` consecutive bytes starting
/// at the given offset.
- relocations: Relocations<Prov>,
+ provenance: ProvenanceMap<Prov>,
/// Denotes which part of this allocation is initialized.
init_mask: InitMask,
/// The alignment of the allocation to detect unaligned reads.
@@ -84,7 +84,7 @@ impl hash::Hash for Allocation {
}
// Hash the other fields as usual.
- self.relocations.hash(state);
+ self.provenance.hash(state);
self.init_mask.hash(state);
self.align.hash(state);
self.mutability.hash(state);
@@ -130,6 +130,8 @@ pub enum AllocError {
ReadPointerAsBytes,
/// Partially overwriting a pointer.
PartialPointerOverwrite(Size),
+ /// Partially copying a pointer.
+ PartialPointerCopy(Size),
/// Using uninitialized data where it is not allowed.
InvalidUninitBytes(Option<UninitBytesAccess>),
}
@@ -152,6 +154,9 @@ impl AllocError {
PartialPointerOverwrite(offset) => InterpError::Unsupported(
UnsupportedOpInfo::PartialPointerOverwrite(Pointer::new(alloc_id, offset)),
),
+ PartialPointerCopy(offset) => InterpError::Unsupported(
+ UnsupportedOpInfo::PartialPointerCopy(Pointer::new(alloc_id, offset)),
+ ),
InvalidUninitBytes(info) => InterpError::UndefinedBehavior(
UndefinedBehaviorInfo::InvalidUninitBytes(info.map(|b| (alloc_id, b))),
),
@@ -211,7 +216,7 @@ impl<Prov> Allocation<Prov> {
let size = Size::from_bytes(bytes.len());
Self {
bytes,
- relocations: Relocations::new(),
+ provenance: ProvenanceMap::new(),
init_mask: InitMask::new(size, true),
align,
mutability,
@@ -246,7 +251,7 @@ impl<Prov> Allocation<Prov> {
let bytes = unsafe { bytes.assume_init() };
Ok(Allocation {
bytes,
- relocations: Relocations::new(),
+ provenance: ProvenanceMap::new(),
init_mask: InitMask::new(size, false),
align,
mutability: Mutability::Mut,
@@ -266,22 +271,22 @@ impl Allocation {
) -> Result<Allocation<Prov, Extra>, Err> {
// Compute new pointer provenance, which also adjusts the bytes.
let mut bytes = self.bytes;
- let mut new_relocations = Vec::with_capacity(self.relocations.0.len());
+ let mut new_provenance = Vec::with_capacity(self.provenance.0.len());
let ptr_size = cx.data_layout().pointer_size.bytes_usize();
let endian = cx.data_layout().endian;
- for &(offset, alloc_id) in self.relocations.iter() {
+ for &(offset, alloc_id) in self.provenance.iter() {
let idx = offset.bytes_usize();
let ptr_bytes = &mut bytes[idx..idx + ptr_size];
let bits = read_target_uint(endian, ptr_bytes).unwrap();
let (ptr_prov, ptr_offset) =
adjust_ptr(Pointer::new(alloc_id, Size::from_bytes(bits)))?.into_parts();
write_target_uint(endian, ptr_bytes, ptr_offset.bytes().into()).unwrap();
- new_relocations.push((offset, ptr_prov));
+ new_provenance.push((offset, ptr_prov));
}
// Create allocation.
Ok(Allocation {
bytes,
- relocations: Relocations::from_presorted(new_relocations),
+ provenance: ProvenanceMap::from_presorted(new_provenance),
init_mask: self.init_mask,
align: self.align,
mutability: self.mutability,
@@ -300,8 +305,8 @@ impl<Prov, Extra> Allocation<Prov, Extra> {
Size::from_bytes(self.len())
}
- /// Looks at a slice which may describe uninitialized bytes or describe a relocation. This differs
- /// from `get_bytes_with_uninit_and_ptr` in that it does no relocation checks (even on the
+ /// Looks at a slice which may contain uninitialized bytes or provenance. This differs
+ /// from `get_bytes_with_uninit_and_ptr` in that it does no provenance checks (even on the
/// edges) at all.
/// This must not be used for reads affecting the interpreter execution.
pub fn inspect_with_uninit_and_ptr_outside_interpreter(&self, range: Range<usize>) -> &[u8] {
@@ -313,74 +318,47 @@ impl<Prov, Extra> Allocation<Prov, Extra> {
&self.init_mask
}
- /// Returns the relocation list.
- pub fn relocations(&self) -> &Relocations<Prov> {
- &self.relocations
+ /// Returns the provenance map.
+ pub fn provenance(&self) -> &ProvenanceMap<Prov> {
+ &self.provenance
}
}
/// Byte accessors.
impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
/// This is the entirely abstraction-violating way to just grab the raw bytes without
- /// caring about relocations. It just deduplicates some code between `read_scalar`
- /// and `get_bytes_internal`.
- fn get_bytes_even_more_internal(&self, range: AllocRange) -> &[u8] {
- &self.bytes[range.start.bytes_usize()..range.end().bytes_usize()]
- }
-
- /// The last argument controls whether we error out when there are uninitialized or pointer
- /// bytes. However, we *always* error when there are relocations overlapping the edges of the
- /// range.
- ///
- /// You should never call this, call `get_bytes` or `get_bytes_with_uninit_and_ptr` instead,
+ /// caring about provenance or initialization.
///
/// This function also guarantees that the resulting pointer will remain stable
/// even when new allocations are pushed to the `HashMap`. `mem_copy_repeatedly` relies
/// on that.
- ///
- /// It is the caller's responsibility to check bounds and alignment beforehand.
- fn get_bytes_internal(
- &self,
- cx: &impl HasDataLayout,
- range: AllocRange,
- check_init_and_ptr: bool,
- ) -> AllocResult<&[u8]> {
- if check_init_and_ptr {
- self.check_init(range)?;
- self.check_relocations(cx, range)?;
- } else {
- // We still don't want relocations on the *edges*.
- self.check_relocation_edges(cx, range)?;
- }
-
- Ok(self.get_bytes_even_more_internal(range))
+ #[inline]
+ pub fn get_bytes_unchecked(&self, range: AllocRange) -> &[u8] {
+ &self.bytes[range.start.bytes_usize()..range.end().bytes_usize()]
}
- /// Checks that these bytes are initialized and not pointer bytes, and then return them
- /// as a slice.
+ /// Checks that these bytes are initialized, and then strip provenance (if possible) and return
+ /// them.
///
/// It is the caller's responsibility to check bounds and alignment beforehand.
/// Most likely, you want to use the `PlaceTy` and `OperandTy`-based methods
/// on `InterpCx` instead.
#[inline]
- pub fn get_bytes(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult<&[u8]> {
- self.get_bytes_internal(cx, range, true)
- }
-
- /// It is the caller's responsibility to handle uninitialized and pointer bytes.
- /// However, this still checks that there are no relocations on the *edges*.
- ///
- /// It is the caller's responsibility to check bounds and alignment beforehand.
- #[inline]
- pub fn get_bytes_with_uninit_and_ptr(
+ pub fn get_bytes_strip_provenance(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
) -> AllocResult<&[u8]> {
- self.get_bytes_internal(cx, range, false)
+ self.check_init(range)?;
+ if !Prov::OFFSET_IS_ADDR {
+ if self.range_has_provenance(cx, range) {
+ return Err(AllocError::ReadPointerAsBytes);
+ }
+ }
+ Ok(self.get_bytes_unchecked(range))
}
- /// Just calling this already marks everything as defined and removes relocations,
+ /// Just calling this already marks everything as defined and removes provenance,
/// so be sure to actually put data there!
///
/// It is the caller's responsibility to check bounds and alignment beforehand.
@@ -392,7 +370,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
range: AllocRange,
) -> AllocResult<&mut [u8]> {
self.mark_init(range, true);
- self.clear_relocations(cx, range)?;
+ self.clear_provenance(cx, range)?;
Ok(&mut self.bytes[range.start.bytes_usize()..range.end().bytes_usize()])
}
@@ -404,7 +382,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
range: AllocRange,
) -> AllocResult<*mut [u8]> {
self.mark_init(range, true);
- self.clear_relocations(cx, range)?;
+ self.clear_provenance(cx, range)?;
assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check
let begin_ptr = self.bytes.as_mut_ptr().wrapping_add(range.start.bytes_usize());
@@ -415,28 +393,6 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
/// Reading and writing.
impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
- /// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a
- /// relocation. If `allow_uninit`/`allow_ptr` is `false`, also enforces that the memory in the
- /// given range contains no uninitialized bytes/relocations.
- pub fn check_bytes(
- &self,
- cx: &impl HasDataLayout,
- range: AllocRange,
- allow_uninit: bool,
- allow_ptr: bool,
- ) -> AllocResult {
- // Check bounds and relocations on the edges.
- self.get_bytes_with_uninit_and_ptr(cx, range)?;
- // Check uninit and ptr.
- if !allow_uninit {
- self.check_init(range)?;
- }
- if !allow_ptr {
- self.check_relocations(cx, range)?;
- }
- Ok(())
- }
-
/// Reads a *non-ZST* scalar.
///
/// If `read_provenance` is `true`, this will also read provenance; otherwise (if the machine
@@ -452,47 +408,55 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
cx: &impl HasDataLayout,
range: AllocRange,
read_provenance: bool,
- ) -> AllocResult<ScalarMaybeUninit<Prov>> {
- if read_provenance {
- assert_eq!(range.size, cx.data_layout().pointer_size);
- }
-
+ ) -> AllocResult<Scalar<Prov>> {
// First and foremost, if anything is uninit, bail.
if self.is_init(range).is_err() {
- // This inflates uninitialized bytes to the entire scalar, even if only a few
- // bytes are uninitialized.
- return Ok(ScalarMaybeUninit::Uninit);
+ return Err(AllocError::InvalidUninitBytes(None));
}
- // If we are doing a pointer read, and there is a relocation exactly where we
- // are reading, then we can put data and relocation back together and return that.
- if read_provenance && let Some(&prov) = self.relocations.get(&range.start) {
- // We already checked init and relocations, so we can use this function.
- let bytes = self.get_bytes_even_more_internal(range);
- let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
- let ptr = Pointer::new(prov, Size::from_bytes(bits));
- return Ok(ScalarMaybeUninit::from_pointer(ptr, cx));
- }
+ // Get the integer part of the result. We HAVE TO check provenance before returning this!
+ let bytes = self.get_bytes_unchecked(range);
+ let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
- // If we are *not* reading a pointer, and we can just ignore relocations,
- // then do exactly that.
- if !read_provenance && Prov::OFFSET_IS_ADDR {
- // We just strip provenance.
- let bytes = self.get_bytes_even_more_internal(range);
- let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
- return Ok(ScalarMaybeUninit::Scalar(Scalar::from_uint(bits, range.size)));
+ if read_provenance {
+ assert_eq!(range.size, cx.data_layout().pointer_size);
+
+ // When reading data with provenance, the easy case is finding provenance exactly where we
+ // are reading, then we can put data and provenance back together and return that.
+ if let Some(&prov) = self.provenance.get(&range.start) {
+ // Now we can return the bits, with their appropriate provenance.
+ let ptr = Pointer::new(prov, Size::from_bytes(bits));
+ return Ok(Scalar::from_pointer(ptr, cx));
+ }
+
+ // If we can work on pointers byte-wise, join the byte-wise provenances.
+ if Prov::OFFSET_IS_ADDR {
+ let mut prov = self.offset_get_provenance(cx, range.start);
+ for offset in 1..range.size.bytes() {
+ let this_prov =
+ self.offset_get_provenance(cx, range.start + Size::from_bytes(offset));
+ prov = Prov::join(prov, this_prov);
+ }
+ // Now use this provenance.
+ let ptr = Pointer::new(prov, Size::from_bytes(bits));
+ return Ok(Scalar::from_maybe_pointer(ptr, cx));
+ }
+ } else {
+ // We are *not* reading a pointer.
+ // If we can just ignore provenance, do exactly that.
+ if Prov::OFFSET_IS_ADDR {
+ // We just strip provenance.
+ return Ok(Scalar::from_uint(bits, range.size));
+ }
}
- // It's complicated. Better make sure there is no provenance anywhere.
- // FIXME: If !OFFSET_IS_ADDR, this is the best we can do. But if OFFSET_IS_ADDR, then
- // `read_pointer` is true and we ideally would distinguish the following two cases:
- // - The entire `range` is covered by 2 relocations for the same provenance.
- // Then we should return a pointer with that provenance.
- // - The range has inhomogeneous provenance. Then we should return just the
- // underlying bits.
- let bytes = self.get_bytes(cx, range)?;
- let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
- Ok(ScalarMaybeUninit::Scalar(Scalar::from_uint(bits, range.size)))
+ // Fallback path for when we cannot treat provenance bytewise or ignore it.
+ assert!(!Prov::OFFSET_IS_ADDR);
+ if self.range_has_provenance(cx, range) {
+ return Err(AllocError::ReadPointerAsBytes);
+ }
+ // There is no provenance, we can just return the bits.
+ Ok(Scalar::from_uint(bits, range.size))
}
/// Writes a *non-ZST* scalar.
@@ -507,17 +471,10 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
- val: ScalarMaybeUninit<Prov>,
+ val: Scalar<Prov>,
) -> AllocResult {
assert!(self.mutability == Mutability::Mut);
- let val = match val {
- ScalarMaybeUninit::Scalar(scalar) => scalar,
- ScalarMaybeUninit::Uninit => {
- return self.write_uninit(cx, range);
- }
- };
-
// `to_bits_or_ptr_internal` is the right method because we just want to store this data
// as-is into memory.
let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {
@@ -532,9 +489,9 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
let dst = self.get_bytes_mut(cx, range)?;
write_target_uint(endian, dst, bytes).unwrap();
- // See if we have to also write a relocation.
+ // See if we have to also store some provenance.
if let Some(provenance) = provenance {
- self.relocations.0.insert(range.start, provenance);
+ self.provenance.0.insert(range.start, provenance);
}
Ok(())
@@ -543,64 +500,65 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
/// Write "uninit" to the given memory range.
pub fn write_uninit(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
self.mark_init(range, false);
- self.clear_relocations(cx, range)?;
+ self.clear_provenance(cx, range)?;
return Ok(());
}
}
-/// Relocations.
+/// Provenance.
impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
- /// Returns all relocations overlapping with the given pointer-offset pair.
- fn get_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> &[(Size, Prov)] {
+ /// Returns all provenance overlapping with the given pointer-offset pair.
+ fn range_get_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> &[(Size, Prov)] {
// We have to go back `pointer_size - 1` bytes, as that one would still overlap with
// the beginning of this range.
let start = range.start.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1);
- self.relocations.range(Size::from_bytes(start)..range.end())
+ self.provenance.range(Size::from_bytes(start)..range.end())
}
- /// Returns whether this allocation has relocations overlapping with the given range.
- ///
- /// Note: this function exists to allow `get_relocations` to be private, in order to somewhat
- /// limit access to relocations outside of the `Allocation` abstraction.
- ///
- pub fn has_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> bool {
- !self.get_relocations(cx, range).is_empty()
+ /// Get the provenance of a single byte.
+ fn offset_get_provenance(&self, cx: &impl HasDataLayout, offset: Size) -> Option<Prov> {
+ let prov = self.range_get_provenance(cx, alloc_range(offset, Size::from_bytes(1)));
+ assert!(prov.len() <= 1);
+ prov.first().map(|(_offset, prov)| *prov)
}
- /// Checks that there are no relocations overlapping with the given range.
- #[inline(always)]
- fn check_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
- if self.has_relocations(cx, range) { Err(AllocError::ReadPointerAsBytes) } else { Ok(()) }
+ /// Returns whether this allocation has progrnance overlapping with the given range.
+ ///
+ /// Note: this function exists to allow `range_get_provenance` to be private, in order to somewhat
+ /// limit access to provenance outside of the `Allocation` abstraction.
+ ///
+ pub fn range_has_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> bool {
+ !self.range_get_provenance(cx, range).is_empty()
}
- /// Removes all relocations inside the given range.
- /// If there are relocations overlapping with the edges, they
+ /// Removes all provenance inside the given range.
+ /// If there is provenance overlapping with the edges, it
/// are removed as well *and* the bytes they cover are marked as
/// uninitialized. This is a somewhat odd "spooky action at a distance",
/// but it allows strictly more code to run than if we would just error
/// immediately in that case.
- fn clear_relocations(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult
+ fn clear_provenance(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult
where
Prov: Provenance,
{
- // Find the start and end of the given range and its outermost relocations.
+ // Find the start and end of the given range and its outermost provenance.
let (first, last) = {
- // Find all relocations overlapping the given range.
- let relocations = self.get_relocations(cx, range);
- if relocations.is_empty() {
+ // Find all provenance overlapping the given range.
+ let provenance = self.range_get_provenance(cx, range);
+ if provenance.is_empty() {
return Ok(());
}
(
- relocations.first().unwrap().0,
- relocations.last().unwrap().0 + cx.data_layout().pointer_size,
+ provenance.first().unwrap().0,
+ provenance.last().unwrap().0 + cx.data_layout().pointer_size,
)
};
let start = range.start;
let end = range.end();
- // We need to handle clearing the relocations from parts of a pointer.
- // FIXME: Miri should preserve partial relocations; see
+ // We need to handle clearing the provenance from parts of a pointer.
+ // FIXME: Miri should preserve partial provenance; see
// https://github.com/rust-lang/miri/issues/2181.
if first < start {
if Prov::ERR_ON_PARTIAL_PTR_OVERWRITE {
@@ -623,41 +581,32 @@ impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
self.init_mask.set_range(end, last, false);
}
- // Forget all the relocations.
- // Since relocations do not overlap, we know that removing until `last` (exclusive) is fine,
- // i.e., this will not remove any other relocations just after the ones we care about.
- self.relocations.0.remove_range(first..last);
+ // Forget all the provenance.
+ // Since provenance do not overlap, we know that removing until `last` (exclusive) is fine,
+ // i.e., this will not remove any other provenance just after the ones we care about.
+ self.provenance.0.remove_range(first..last);
Ok(())
}
-
- /// Errors if there are relocations overlapping with the edges of the
- /// given memory range.
- #[inline]
- fn check_relocation_edges(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
- self.check_relocations(cx, alloc_range(range.start, Size::ZERO))?;
- self.check_relocations(cx, alloc_range(range.end(), Size::ZERO))?;
- Ok(())
- }
}
-/// "Relocations" stores the provenance information of pointers stored in memory.
+/// Stores the provenance information of pointers stored in memory.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-pub struct Relocations<Prov = AllocId>(SortedMap<Size, Prov>);
+pub struct ProvenanceMap<Prov = AllocId>(SortedMap<Size, Prov>);
-impl<Prov> Relocations<Prov> {
+impl<Prov> ProvenanceMap<Prov> {
pub fn new() -> Self {
- Relocations(SortedMap::new())
+ ProvenanceMap(SortedMap::new())
}
- // The caller must guarantee that the given relocations are already sorted
+ // The caller must guarantee that the given provenance list is already sorted
// by address and contain no duplicates.
pub fn from_presorted(r: Vec<(Size, Prov)>) -> Self {
- Relocations(SortedMap::from_presorted_elements(r))
+ ProvenanceMap(SortedMap::from_presorted_elements(r))
}
}
-impl<Prov> Deref for Relocations<Prov> {
+impl<Prov> Deref for ProvenanceMap<Prov> {
type Target = SortedMap<Size, Prov>;
fn deref(&self) -> &Self::Target {
@@ -665,36 +614,36 @@ impl<Prov> Deref for Relocations<Prov> {
}
}
-/// A partial, owned list of relocations to transfer into another allocation.
+/// A partial, owned list of provenance to transfer into another allocation.
///
/// Offsets are already adjusted to the destination allocation.
-pub struct AllocationRelocations<Prov> {
- dest_relocations: Vec<(Size, Prov)>,
+pub struct AllocationProvenance<Prov> {
+ dest_provenance: Vec<(Size, Prov)>,
}
impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
- pub fn prepare_relocation_copy(
+ pub fn prepare_provenance_copy(
&self,
cx: &impl HasDataLayout,
src: AllocRange,
dest: Size,
count: u64,
- ) -> AllocationRelocations<Prov> {
- let relocations = self.get_relocations(cx, src);
- if relocations.is_empty() {
- return AllocationRelocations { dest_relocations: Vec::new() };
+ ) -> AllocationProvenance<Prov> {
+ let provenance = self.range_get_provenance(cx, src);
+ if provenance.is_empty() {
+ return AllocationProvenance { dest_provenance: Vec::new() };
}
let size = src.size;
- let mut new_relocations = Vec::with_capacity(relocations.len() * (count as usize));
+ let mut new_provenance = Vec::with_capacity(provenance.len() * (count as usize));
// If `count` is large, this is rather wasteful -- we are allocating a big array here, which
// is mostly filled with redundant information since it's just N copies of the same `Prov`s
- // at slightly adjusted offsets. The reason we do this is so that in `mark_relocation_range`
+ // at slightly adjusted offsets. The reason we do this is so that in `mark_provenance_range`
// we can use `insert_presorted`. That wouldn't work with an `Iterator` that just produces
- // the right sequence of relocations for all N copies.
+ // the right sequence of provenance for all N copies.
for i in 0..count {
- new_relocations.extend(relocations.iter().map(|&(offset, reloc)| {
+ new_provenance.extend(provenance.iter().map(|&(offset, reloc)| {
// compute offset for current repetition
let dest_offset = dest + size * i; // `Size` operations
(
@@ -705,17 +654,17 @@ impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
}));
}
- AllocationRelocations { dest_relocations: new_relocations }
+ AllocationProvenance { dest_provenance: new_provenance }
}
- /// Applies a relocation copy.
- /// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected
- /// to be clear of relocations.
+ /// Applies a provenance copy.
+ /// The affected range, as defined in the parameters to `prepare_provenance_copy` is expected
+ /// to be clear of provenance.
///
/// This is dangerous to use as it can violate internal `Allocation` invariants!
/// It only exists to support an efficient implementation of `mem_copy_repeatedly`.
- pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Prov>) {
- self.relocations.0.insert_presorted(relocations.dest_relocations);
+ pub fn mark_provenance_range(&mut self, provenance: AllocationProvenance<Prov>) {
+ self.provenance.0.insert_presorted(provenance.dest_provenance);
}
}
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index cecb55578..e4039cc7c 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -401,14 +401,18 @@ impl fmt::Display for UndefinedBehaviorInfo {
pub enum UnsupportedOpInfo {
/// Free-form case. Only for errors that are never caught!
Unsupported(String),
- /// Encountered a pointer where we needed raw bytes.
- ReadPointerAsBytes,
/// Overwriting parts of a pointer; the resulting state cannot be represented in our
/// `Allocation` data structure. See <https://github.com/rust-lang/miri/issues/2181>.
PartialPointerOverwrite(Pointer<AllocId>),
+ /// Attempting to `copy` parts of a pointer to somewhere else; the resulting state cannot be
+ /// represented in our `Allocation` data structure. See
+ /// <https://github.com/rust-lang/miri/issues/2181>.
+ PartialPointerCopy(Pointer<AllocId>),
//
// The variants below are only reachable from CTFE/const prop, miri will never emit them.
//
+ /// Encountered a pointer where we needed raw bytes.
+ ReadPointerAsBytes,
/// Accessing thread local statics
ThreadLocalStatic(DefId),
/// Accessing an unsupported extern static.
@@ -420,10 +424,13 @@ impl fmt::Display for UnsupportedOpInfo {
use UnsupportedOpInfo::*;
match self {
Unsupported(ref msg) => write!(f, "{msg}"),
- ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes"),
PartialPointerOverwrite(ptr) => {
write!(f, "unable to overwrite parts of a pointer in memory at {ptr:?}")
}
+ PartialPointerCopy(ptr) => {
+ write!(f, "unable to copy parts of a pointer from memory at {ptr:?}")
+ }
+ ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes"),
ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({did:?})"),
ReadExternStatic(did) => write!(f, "cannot read from extern static ({did:?})"),
}
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 967f8ece1..5e3dfcbcc 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -124,11 +124,11 @@ pub use self::error::{
UninitBytesAccess, UnsupportedOpInfo,
};
-pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar, ScalarMaybeUninit};
+pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar};
pub use self::allocation::{
alloc_range, AllocRange, Allocation, ConstAllocation, InitChunk, InitChunkIter, InitMask,
- Relocations,
+ ProvenanceMap,
};
pub use self::pointer::{Pointer, PointerArithmetic, Provenance};
@@ -137,7 +137,7 @@ pub use self::pointer::{Pointer, PointerArithmetic, Provenance};
/// - A constant
/// - A static
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, Lift)]
+#[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
pub struct GlobalId<'tcx> {
/// For a constant or static, the `Instance` of the item itself.
/// For a promoted global, the `Instance` of the function they belong to.
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index 384954cbb..95e52e391 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -107,8 +107,12 @@ impl<T: HasDataLayout> PointerArithmetic for T {}
/// pointer), but `derive` adds some unnecessary bounds.
pub trait Provenance: Copy + fmt::Debug {
/// Says whether the `offset` field of `Pointer`s with this provenance is the actual physical address.
- /// If `true, ptr-to-int casts work by simply discarding the provenance.
- /// If `false`, ptr-to-int casts are not supported. The offset *must* be relative in that case.
+ /// - If `false`, the offset *must* be relative. This means the bytes representing a pointer are
+ /// different from what the Abstract Machine prescribes, so the interpreter must prevent any
+ /// operation that would inspect the underlying bytes of a pointer, such as ptr-to-int
+ /// transmutation. A `ReadPointerAsBytes` error will be raised in such situations.
+ /// - If `true`, the interpreter will permit operations to inspect the underlying bytes of a
+ /// pointer, and implement ptr-to-int transmutation by stripping provenance.
const OFFSET_IS_ADDR: bool;
/// We also use this trait to control whether to abort execution when a pointer is being partially overwritten
@@ -125,6 +129,9 @@ pub trait Provenance: Copy + fmt::Debug {
/// Otherwise this function is best-effort (but must agree with `Machine::ptr_get_alloc`).
/// (Identifying the offset in that allocation, however, is harder -- use `Memory::ptr_get_alloc` for that.)
fn get_alloc_id(self) -> Option<AllocId>;
+
+ /// Defines the 'join' of provenance: what happens when doing a pointer load and different bytes have different provenance.
+ fn join(left: Option<Self>, right: Option<Self>) -> Option<Self>;
}
impl Provenance for AllocId {
@@ -152,6 +159,10 @@ impl Provenance for AllocId {
fn get_alloc_id(self) -> Option<AllocId> {
Some(self)
}
+
+ fn join(_left: Option<Self>, _right: Option<Self>) -> Option<Self> {
+ panic!("merging provenance is not supported when `OFFSET_IS_ADDR` is false")
+ }
}
/// Represents a pointer in the Miri engine.
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 786927e2d..4207988d7 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -63,7 +63,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn const_eval_resolve_for_typeck(
self,
param_env: ty::ParamEnv<'tcx>,
- ct: ty::Unevaluated<'tcx>,
+ ct: ty::Unevaluated<'tcx, ()>,
span: Option<Span>,
) -> EvalToValTreeResult<'tcx> {
// Cannot resolve `Unevaluated` constants that contain inference
@@ -78,7 +78,7 @@ impl<'tcx> TyCtxt<'tcx> {
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
Ok(Some(instance)) => {
- let cid = GlobalId { instance, promoted: ct.promoted };
+ let cid = GlobalId { instance, promoted: None };
self.const_eval_global_id_for_typeck(param_env, cid, span)
}
Ok(None) => Err(ErrorHandled::TooGeneric),
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 834c114ee..ac5fddb7a 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -8,7 +8,7 @@ use rustc_apfloat::{
use rustc_macros::HashStable;
use rustc_target::abi::{HasDataLayout, Size};
-use crate::ty::{Lift, ParamEnv, ScalarInt, Ty, TyCtxt};
+use crate::ty::{ParamEnv, ScalarInt, Ty, TyCtxt};
use super::{
AllocId, AllocRange, ConstAllocation, InterpResult, Pointer, PointerArithmetic, Provenance,
@@ -27,7 +27,7 @@ pub struct ConstAlloc<'tcx> {
/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
/// array length computations, enum discriminants and the pattern matching logic.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
-#[derive(HashStable)]
+#[derive(HashStable, Lift)]
pub enum ConstValue<'tcx> {
/// Used only for types with `layout::abi::Scalar` ABI.
///
@@ -53,22 +53,6 @@ pub enum ConstValue<'tcx> {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ConstValue<'_>, 32);
-impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
- type Lifted = ConstValue<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ConstValue<'tcx>> {
- Some(match self {
- ConstValue::Scalar(s) => ConstValue::Scalar(s),
- ConstValue::ZeroSized => ConstValue::ZeroSized,
- ConstValue::Slice { data, start, end } => {
- ConstValue::Slice { data: tcx.lift(data)?, start, end }
- }
- ConstValue::ByRef { alloc, offset } => {
- ConstValue::ByRef { alloc: tcx.lift(alloc)?, offset }
- }
- })
- }
-}
-
impl<'tcx> ConstValue<'tcx> {
#[inline]
pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> {
@@ -79,7 +63,7 @@ impl<'tcx> ConstValue<'tcx> {
}
pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
- Some(self.try_to_scalar()?.assert_int())
+ self.try_to_scalar()?.try_to_int().ok()
}
pub fn try_to_bits(&self, size: Size) -> Option<u128> {
@@ -130,9 +114,7 @@ pub enum Scalar<Prov = AllocId> {
/// The raw bytes of a simple value.
Int(ScalarInt),
- /// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
- /// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
- /// relocation and its associated offset together as a `Pointer` here.
+ /// A pointer.
///
/// We also store the size of the pointer, such that a `Scalar` always knows how big it is.
/// The size is always the pointer size of the current target, but this is not information
@@ -368,6 +350,7 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
}
#[inline(always)]
+ #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn assert_int(self) -> ScalarInt {
self.try_to_int().unwrap()
}
@@ -389,6 +372,7 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
}
#[inline(always)]
+ #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn assert_bits(self, target_size: Size) -> u128 {
self.to_bits(target_size).unwrap()
}
@@ -502,145 +486,12 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
}
}
-#[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, HashStable, Hash)]
-pub enum ScalarMaybeUninit<Prov = AllocId> {
- Scalar(Scalar<Prov>),
- Uninit,
-}
-
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(ScalarMaybeUninit, 24);
-
-impl<Prov> From<Scalar<Prov>> for ScalarMaybeUninit<Prov> {
- #[inline(always)]
- fn from(s: Scalar<Prov>) -> Self {
- ScalarMaybeUninit::Scalar(s)
- }
-}
-
-// We want the `Debug` output to be readable as it is used by `derive(Debug)` for
-// all the Miri types.
-impl<Prov: Provenance> fmt::Debug for ScalarMaybeUninit<Prov> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ScalarMaybeUninit::Uninit => write!(f, "<uninitialized>"),
- ScalarMaybeUninit::Scalar(s) => write!(f, "{:?}", s),
- }
- }
-}
-
-impl<Prov: Provenance> fmt::LowerHex for ScalarMaybeUninit<Prov> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ScalarMaybeUninit::Uninit => write!(f, "uninitialized bytes"),
- ScalarMaybeUninit::Scalar(s) => write!(f, "{:x}", s),
- }
- }
-}
-
-impl<Prov> ScalarMaybeUninit<Prov> {
- #[inline]
- pub fn from_pointer(ptr: Pointer<Prov>, cx: &impl HasDataLayout) -> Self {
- ScalarMaybeUninit::Scalar(Scalar::from_pointer(ptr, cx))
- }
-
- #[inline]
- pub fn from_maybe_pointer(ptr: Pointer<Option<Prov>>, cx: &impl HasDataLayout) -> Self {
- ScalarMaybeUninit::Scalar(Scalar::from_maybe_pointer(ptr, cx))
- }
-
- #[inline]
- pub fn check_init<'tcx>(self) -> InterpResult<'tcx, Scalar<Prov>> {
- match self {
- ScalarMaybeUninit::Scalar(scalar) => Ok(scalar),
- ScalarMaybeUninit::Uninit => throw_ub!(InvalidUninitBytes(None)),
- }
- }
-}
-
-impl<'tcx, Prov: Provenance> ScalarMaybeUninit<Prov> {
- #[inline(always)]
- pub fn to_pointer(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, Pointer<Option<Prov>>> {
- self.check_init()?.to_pointer(cx)
- }
-
- #[inline(always)]
- pub fn to_bool(self) -> InterpResult<'tcx, bool> {
- self.check_init()?.to_bool()
- }
-
- #[inline(always)]
- pub fn to_char(self) -> InterpResult<'tcx, char> {
- self.check_init()?.to_char()
- }
-
- #[inline(always)]
- pub fn to_f32(self) -> InterpResult<'tcx, Single> {
- self.check_init()?.to_f32()
- }
-
- #[inline(always)]
- pub fn to_f64(self) -> InterpResult<'tcx, Double> {
- self.check_init()?.to_f64()
- }
-
- #[inline(always)]
- pub fn to_u8(self) -> InterpResult<'tcx, u8> {
- self.check_init()?.to_u8()
- }
-
- #[inline(always)]
- pub fn to_u16(self) -> InterpResult<'tcx, u16> {
- self.check_init()?.to_u16()
- }
-
- #[inline(always)]
- pub fn to_u32(self) -> InterpResult<'tcx, u32> {
- self.check_init()?.to_u32()
- }
-
- #[inline(always)]
- pub fn to_u64(self) -> InterpResult<'tcx, u64> {
- self.check_init()?.to_u64()
- }
-
- #[inline(always)]
- pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
- self.check_init()?.to_machine_usize(cx)
- }
-
- #[inline(always)]
- pub fn to_i8(self) -> InterpResult<'tcx, i8> {
- self.check_init()?.to_i8()
- }
-
- #[inline(always)]
- pub fn to_i16(self) -> InterpResult<'tcx, i16> {
- self.check_init()?.to_i16()
- }
-
- #[inline(always)]
- pub fn to_i32(self) -> InterpResult<'tcx, i32> {
- self.check_init()?.to_i32()
- }
-
- #[inline(always)]
- pub fn to_i64(self) -> InterpResult<'tcx, i64> {
- self.check_init()?.to_i64()
- }
-
- #[inline(always)]
- pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> {
- self.check_init()?.to_machine_isize(cx)
- }
-}
-
/// Gets the bytes of a constant slice value.
pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
if let ConstValue::Slice { data, start, end } = val {
let len = end - start;
data.inner()
- .get_bytes(
+ .get_bytes_strip_provenance(
cx,
AllocRange { start: Size::from_bytes(start), size: Size::from_bytes(len) },
)
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 7ab71f900..3d7a6230e 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -3,7 +3,7 @@
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
use crate::mir::interpret::{
- AllocRange, ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar,
+ AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, LitToConstInput, Scalar,
};
use crate::mir::visit::MirVisitable;
use crate::ty::codec::{TyDecoder, TyEncoder};
@@ -18,7 +18,7 @@ use rustc_data_structures::captures::Captures;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
-use rustc_hir::{self, GeneratorKind};
+use rustc_hir::{self, GeneratorKind, ImplicitSelfKind};
use rustc_hir::{self as hir, HirId};
use rustc_session::Session;
use rustc_target::abi::{Size, VariantIdx};
@@ -128,8 +128,20 @@ pub trait MirPass<'tcx> {
impl MirPhase {
/// Gets the index of the current MirPhase within the set of all `MirPhase`s.
+ ///
+ /// FIXME(JakobDegen): Return a `(usize, usize)` instead.
pub fn phase_index(&self) -> usize {
- *self as usize
+ const BUILT_PHASE_COUNT: usize = 1;
+ const ANALYSIS_PHASE_COUNT: usize = 2;
+ match self {
+ MirPhase::Built => 1,
+ MirPhase::Analysis(analysis_phase) => {
+ 1 + BUILT_PHASE_COUNT + (*analysis_phase as usize)
+ }
+ MirPhase::Runtime(runtime_phase) => {
+ 1 + BUILT_PHASE_COUNT + ANALYSIS_PHASE_COUNT + (*runtime_phase as usize)
+ }
+ }
}
}
@@ -332,11 +344,6 @@ impl<'tcx> Body<'tcx> {
}
#[inline]
- pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
- &self.basic_blocks
- }
-
- #[inline]
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
self.basic_blocks.as_mut()
}
@@ -490,7 +497,7 @@ impl<'tcx> Index<BasicBlock> for Body<'tcx> {
#[inline]
fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
- &self.basic_blocks()[index]
+ &self.basic_blocks[index]
}
}
@@ -646,22 +653,6 @@ pub enum BindingForm<'tcx> {
RefForGuard,
}
-/// Represents what type of implicit self a function has, if any.
-#[derive(Clone, Copy, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
-pub enum ImplicitSelfKind {
- /// Represents a `fn x(self);`.
- Imm,
- /// Represents a `fn x(mut self);`.
- Mut,
- /// Represents a `fn x(&self);`.
- ImmRef,
- /// Represents a `fn x(&mut self);`.
- MutRef,
- /// Represents when a function does not have a self argument or
- /// when a function has a `self: X` argument.
- None,
-}
-
TrivialTypeTraversalAndLiftImpls! { BindingForm<'tcx>, }
mod binding_form_impl {
@@ -832,10 +823,6 @@ pub struct LocalDecl<'tcx> {
pub source_info: SourceInfo,
}
-// `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(LocalDecl<'_>, 56);
-
/// Extra information about a some locals that's used for diagnostics and for
/// classifying variables into local variables, statics, etc, which is needed e.g.
/// for unsafety checking.
@@ -1310,10 +1297,6 @@ pub struct Statement<'tcx> {
pub kind: StatementKind<'tcx>,
}
-// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(Statement<'_>, 32);
-
impl Statement<'_> {
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
/// invalidating statement indices in `Location`s.
@@ -1363,13 +1346,7 @@ impl Debug for Statement<'_> {
write!(fmt, "Coverage::{:?} for {:?}", kind, rgn)
}
Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
- CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
- ref src,
- ref dst,
- ref count,
- }) => {
- write!(fmt, "copy_nonoverlapping(src={:?}, dst={:?}, count={:?})", src, dst, count)
- }
+ Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"),
Nop => write!(fmt, "nop"),
}
}
@@ -1450,7 +1427,7 @@ pub struct PlaceRef<'tcx> {
// Once we stop implementing `Ord` for `DefId`,
// this impl will be unnecessary. Until then, we'll
// leave this impl in place to prevent re-adding a
-// dependnecy on the `Ord` impl for `DefId`
+// dependency on the `Ord` impl for `DefId`
impl<'tcx> !PartialOrd for PlaceRef<'tcx> {}
impl<'tcx> Place<'tcx> {
@@ -1471,7 +1448,9 @@ impl<'tcx> Place<'tcx> {
/// It's guaranteed to be in the first place
pub fn has_deref(&self) -> bool {
// To make sure this is not accidently used in wrong mir phase
- debug_assert!(!self.projection[1..].contains(&PlaceElem::Deref));
+ debug_assert!(
+ self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
+ );
self.projection.first() == Some(&PlaceElem::Deref)
}
@@ -1531,6 +1510,7 @@ impl<'tcx> Place<'tcx> {
}
impl From<Local> for Place<'_> {
+ #[inline]
fn from(local: Local) -> Self {
Place { local, projection: List::empty() }
}
@@ -1838,6 +1818,7 @@ impl<'tcx> Rvalue<'tcx> {
// While the model is undecided, we should be conservative. See
// <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
+ Rvalue::Cast(CastKind::DynStar, _, _) => false,
Rvalue::Use(_)
| Rvalue::CopyForDeref(_)
@@ -2047,6 +2028,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
/// particular, one must be wary of `NaN`!
#[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
+#[derive(TypeFoldable, TypeVisitable)]
pub struct Constant<'tcx> {
pub span: Span,
@@ -2065,6 +2047,10 @@ pub struct Constant<'tcx> {
pub enum ConstantKind<'tcx> {
/// This constant came from the type system
Ty(ty::Const<'tcx>),
+
+ /// An unevaluated mir constant which is not part of the type system.
+ Unevaluated(ty::Unevaluated<'tcx, Option<Promoted>>, Ty<'tcx>),
+
/// This constant cannot go back into the type system, as it represents
/// something the type system cannot handle (e.g. pointers).
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
@@ -2090,20 +2076,11 @@ impl<'tcx> Constant<'tcx> {
}
impl<'tcx> ConstantKind<'tcx> {
- /// Returns `None` if the constant is not trivially safe for use in the type system.
- #[inline]
- pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> {
- match self {
- ConstantKind::Ty(c) => Some(*c),
- ConstantKind::Val(..) => None,
- }
- }
-
#[inline(always)]
pub fn ty(&self) -> Ty<'tcx> {
match self {
ConstantKind::Ty(c) => c.ty(),
- ConstantKind::Val(_, ty) => *ty,
+ ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => *ty,
}
}
@@ -2115,6 +2092,7 @@ impl<'tcx> ConstantKind<'tcx> {
_ => None,
},
ConstantKind::Val(val, _) => Some(val),
+ ConstantKind::Unevaluated(..) => None,
}
}
@@ -2129,6 +2107,7 @@ impl<'tcx> ConstantKind<'tcx> {
_ => None,
},
ConstantKind::Val(val, _) => val.try_to_scalar(),
+ ConstantKind::Unevaluated(..) => None,
}
}
@@ -2161,6 +2140,14 @@ impl<'tcx> ConstantKind<'tcx> {
}
}
Self::Val(_, _) => self,
+ Self::Unevaluated(uneval, ty) => {
+ // FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
+ match tcx.const_eval_resolve(param_env, uneval, None) {
+ Ok(val) => Self::Val(val, ty),
+ Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
+ Err(_) => Self::Ty(tcx.const_error(ty)),
+ }
+ }
}
}
@@ -2186,6 +2173,18 @@ impl<'tcx> ConstantKind<'tcx> {
tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
val.try_to_bits(size)
}
+ Self::Unevaluated(uneval, ty) => {
+ match tcx.const_eval_resolve(param_env, *uneval, None) {
+ Ok(val) => {
+ let size = tcx
+ .layout_of(param_env.with_reveal_all_normalized(tcx).and(*ty))
+ .ok()?
+ .size;
+ val.try_to_bits(size)
+ }
+ Err(_) => None,
+ }
+ }
}
}
@@ -2194,6 +2193,12 @@ impl<'tcx> ConstantKind<'tcx> {
match self {
Self::Ty(ct) => ct.try_eval_bool(tcx, param_env),
Self::Val(val, _) => val.try_to_bool(),
+ Self::Unevaluated(uneval, _) => {
+ match tcx.const_eval_resolve(param_env, *uneval, None) {
+ Ok(val) => val.try_to_bool(),
+ Err(_) => None,
+ }
+ }
}
}
@@ -2202,6 +2207,12 @@ impl<'tcx> ConstantKind<'tcx> {
match self {
Self::Ty(ct) => ct.try_eval_usize(tcx, param_env),
Self::Val(val, _) => val.try_to_machine_usize(tcx),
+ Self::Unevaluated(uneval, _) => {
+ match tcx.const_eval_resolve(param_env, *uneval, None) {
+ Ok(val) => val.try_to_machine_usize(tcx),
+ Err(_) => None,
+ }
+ }
}
}
@@ -2259,7 +2270,7 @@ impl<'tcx> ConstantKind<'tcx> {
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env)
}
- #[instrument(skip(tcx), level = "debug")]
+ #[instrument(skip(tcx), level = "debug", ret)]
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let body_id = match tcx.hir().get(hir_id) {
@@ -2297,21 +2308,19 @@ impl<'tcx> ConstantKind<'tcx> {
let substs =
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
.substs;
- let uneval_const = tcx.mk_const(ty::ConstS {
- kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
- def: ty::WithOptConstParam::unknown(def_id).to_global(),
- substs,
- promoted: None,
- }),
- ty,
- });
- debug!(?uneval_const);
- debug_assert!(!uneval_const.has_free_regions());
- Self::Ty(uneval_const)
+ let uneval = ty::Unevaluated {
+ def: ty::WithOptConstParam::unknown(def_id).to_global(),
+ substs,
+ promoted: None,
+ };
+
+ debug_assert!(!uneval.has_free_regions());
+
+ Self::Unevaluated(uneval, ty)
}
- #[instrument(skip(tcx), level = "debug")]
+ #[instrument(skip(tcx), level = "debug", ret)]
fn from_opt_const_arg_anon_const(
tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
@@ -2394,24 +2403,21 @@ impl<'tcx> ConstantKind<'tcx> {
match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
Ok(val) => {
- debug!("evaluated const value: {:?}", val);
+ debug!("evaluated const value");
Self::Val(val, ty)
}
Err(_) => {
debug!("error encountered during evaluation");
// Error was handled in `const_eval_resolve`. Here we just create a
// new unevaluated const and error hard later in codegen
- let ty_const = tcx.mk_const(ty::ConstS {
- kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
+ Self::Unevaluated(
+ ty::Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
promoted: None,
- }),
+ },
ty,
- });
- debug!(?ty_const);
-
- Self::Ty(ty_const)
+ )
}
}
}
@@ -2422,6 +2428,7 @@ impl<'tcx> ConstantKind<'tcx> {
let const_val = tcx.valtree_to_const_val((c.ty(), valtree));
Self::Val(const_val, c.ty())
}
+ ty::ConstKind::Unevaluated(uv) => Self::Unevaluated(uv.expand(), c.ty()),
_ => Self::Ty(c),
}
}
@@ -2576,8 +2583,6 @@ impl UserTypeProjection {
}
}
-TrivialTypeTraversalAndLiftImpls! { ProjectionKind, }
-
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
Ok(UserTypeProjection {
@@ -2622,6 +2627,11 @@ impl<'tcx> Display for ConstantKind<'tcx> {
match *self {
ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
+ // FIXME(valtrees): Correctly print mir constants.
+ ConstantKind::Unevaluated(..) => {
+ fmt.write_str("_")?;
+ Ok(())
+ }
}
}
}
@@ -2643,15 +2653,7 @@ fn pretty_print_const<'tcx>(
}
fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result {
- fmt.write_str("b\"")?;
- for &c in byte_str {
- for e in std::ascii::escape_default(c) {
- fmt.write_char(e as char)?;
- }
- }
- fmt.write_str("\"")?;
-
- Ok(())
+ write!(fmt, "b\"{}\"", byte_str.escape_ascii())
}
fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec<ConstantKind<'tcx>>) -> fmt::Result {
@@ -2691,8 +2693,8 @@ fn pretty_print_const_value<'tcx>(
match inner.kind() {
ty::Slice(t) => {
if *t == u8_type {
- // The `inspect` here is okay since we checked the bounds, and there are
- // no relocations (we have an active slice reference here). We don't use
+ // The `inspect` here is okay since we checked the bounds, and `u8` carries
+ // no provenance (we have an active slice reference here). We don't use
// this result to affect interpreter execution.
let byte_str = data
.inner()
@@ -2702,8 +2704,8 @@ fn pretty_print_const_value<'tcx>(
}
}
ty::Str => {
- // The `inspect` here is okay since we checked the bounds, and there are no
- // relocations (we have an active `str` reference here). We don't use this
+ // The `inspect` here is okay since we checked the bounds, and `str` carries
+ // no provenance (we have an active `str` reference here). We don't use this
// result to affect interpreter execution.
let slice = data
.inner()
@@ -2718,7 +2720,7 @@ fn pretty_print_const_value<'tcx>(
let n = n.kind().try_to_bits(tcx.data_layout.pointer_size).unwrap();
// cast is ok because we already checked for pointer size (32 or 64 bit) above
let range = AllocRange { start: offset, size: Size::from_bytes(n) };
- let byte_str = alloc.inner().get_bytes(&tcx, range).unwrap();
+ let byte_str = alloc.inner().get_bytes_strip_provenance(&tcx, range).unwrap();
fmt.write_str("*")?;
pretty_print_byte_str(fmt, byte_str)?;
return Ok(());
@@ -2898,3 +2900,17 @@ impl Location {
}
}
}
+
+// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+ use super::*;
+ use rustc_data_structures::static_assert_size;
+ // These are in alphabetical order, which is easy to maintain.
+ static_assert_size!(BasicBlockData<'_>, 144);
+ static_assert_size!(LocalDecl<'_>, 56);
+ static_assert_size!(Statement<'_>, 32);
+ static_assert_size!(StatementKind<'_>, 16);
+ static_assert_size!(Terminator<'_>, 112);
+ static_assert_size!(TerminatorKind<'_>, 96);
+}
diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs
index 15496842d..24fe3b472 100644
--- a/compiler/rustc_middle/src/mir/patch.rs
+++ b/compiler/rustc_middle/src/mir/patch.rs
@@ -19,7 +19,7 @@ pub struct MirPatch<'tcx> {
impl<'tcx> MirPatch<'tcx> {
pub fn new(body: &Body<'tcx>) -> Self {
let mut result = MirPatch {
- patch_map: IndexVec::from_elem(None, body.basic_blocks()),
+ patch_map: IndexVec::from_elem(None, &body.basic_blocks),
new_blocks: vec![],
new_statements: vec![],
new_locals: vec![],
@@ -29,7 +29,7 @@ impl<'tcx> MirPatch<'tcx> {
};
// Check if we already have a resume block
- for (bb, block) in body.basic_blocks().iter_enumerated() {
+ for (bb, block) in body.basic_blocks.iter_enumerated() {
if let TerminatorKind::Resume = block.terminator().kind && block.statements.is_empty() {
result.resume_block = Some(bb);
break;
@@ -61,14 +61,14 @@ impl<'tcx> MirPatch<'tcx> {
}
pub fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location {
- let offset = match bb.index().checked_sub(body.basic_blocks().len()) {
+ let offset = match bb.index().checked_sub(body.basic_blocks.len()) {
Some(index) => self.new_blocks[index].statements.len(),
None => body[bb].statements.len(),
};
Location { block: bb, statement_index: offset }
}
- pub fn new_local_with_info(
+ pub fn new_internal_with_info(
&mut self,
ty: Ty<'tcx>,
span: Span,
@@ -76,14 +76,17 @@ impl<'tcx> MirPatch<'tcx> {
) -> Local {
let index = self.next_local;
self.next_local += 1;
- let mut new_decl = LocalDecl::new(ty, span);
+ let mut new_decl = LocalDecl::new(ty, span).internal();
new_decl.local_info = local_info;
self.new_locals.push(new_decl);
Local::new(index as usize)
}
pub fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local {
- self.new_local_with_info(ty, span, None)
+ let index = self.next_local;
+ self.next_local += 1;
+ self.new_locals.push(LocalDecl::new(ty, span));
+ Local::new(index as usize)
}
pub fn new_internal(&mut self, ty: Ty<'tcx>, span: Span) -> Local {
@@ -126,7 +129,7 @@ impl<'tcx> MirPatch<'tcx> {
debug!(
"MirPatch: {} new blocks, starting from index {}",
self.new_blocks.len(),
- body.basic_blocks().len()
+ body.basic_blocks.len()
);
let bbs = if self.patch_map.is_empty() && self.new_blocks.is_empty() {
body.basic_blocks.as_mut_preserves_cfg()
@@ -147,7 +150,6 @@ impl<'tcx> MirPatch<'tcx> {
let mut delta = 0;
let mut last_bb = START_BLOCK;
- let mut stmts_and_targets: Vec<(Statement<'_>, BasicBlock)> = Vec::new();
for (mut loc, stmt) in new_statements {
if loc.block != last_bb {
delta = 0;
@@ -156,27 +158,11 @@ impl<'tcx> MirPatch<'tcx> {
debug!("MirPatch: adding statement {:?} at loc {:?}+{}", stmt, loc, delta);
loc.statement_index += delta;
let source_info = Self::source_info_for_index(&body[loc.block], loc);
-
- // For mir-opt `Derefer` to work in all cases we need to
- // get terminator's targets and apply the statement to all of them.
- if loc.statement_index > body[loc.block].statements.len() {
- let term = body[loc.block].terminator();
- for i in term.successors() {
- stmts_and_targets.push((Statement { source_info, kind: stmt.clone() }, i));
- }
- delta += 1;
- continue;
- }
-
body[loc.block]
.statements
.insert(loc.statement_index, Statement { source_info, kind: stmt });
delta += 1;
}
-
- for (stmt, target) in stmts_and_targets.into_iter().rev() {
- body[target].statements.insert(0, stmt);
- }
}
pub fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo {
@@ -187,7 +173,7 @@ impl<'tcx> MirPatch<'tcx> {
}
pub fn source_info_for_location(&self, body: &Body<'tcx>, loc: Location) -> SourceInfo {
- let data = match loc.block.index().checked_sub(body.basic_blocks().len()) {
+ let data = match loc.block.index().checked_sub(body.basic_blocks.len()) {
Some(new) => &self.new_blocks[new],
None => &body[loc.block],
};
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 0ce41337b..0b42137d4 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -318,10 +318,10 @@ where
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
{
write_mir_intro(tcx, body, w)?;
- for block in body.basic_blocks().indices() {
+ for block in body.basic_blocks.indices() {
extra_data(PassWhere::BeforeBlock(block), w)?;
write_basic_block(tcx, block, body, extra_data, w)?;
- if block.index() + 1 != body.basic_blocks().len() {
+ if block.index() + 1 != body.basic_blocks.len() {
writeln!(w)?;
}
}
@@ -464,12 +464,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
let val = match literal {
ConstantKind::Ty(ct) => match ct.kind() {
ty::ConstKind::Param(p) => format!("Param({})", p),
- ty::ConstKind::Unevaluated(uv) => format!(
- "Unevaluated({}, {:?}, {:?})",
- self.tcx.def_path_str(uv.def.did),
- uv.substs,
- uv.promoted,
- ),
+ ty::ConstKind::Unevaluated(uv) => {
+ format!(
+ "Unevaluated({}, {:?}, {:?})",
+ self.tcx.def_path_str(uv.def.did),
+ uv.substs,
+ uv.promoted,
+ )
+ }
ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)),
ty::ConstKind::Error(_) => "Error".to_string(),
// These variants shouldn't exist in the MIR.
@@ -477,6 +479,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
| ty::ConstKind::Infer(_)
| ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal),
},
+ ConstantKind::Unevaluated(uv, _) => {
+ format!(
+ "Unevaluated({}, {:?}, {:?})",
+ self.tcx.def_path_str(uv.def.did),
+ uv.substs,
+ uv.promoted,
+ )
+ }
// To keep the diffs small, we render this like we render `ty::Const::Value`.
//
// This changes once `ty::Const::Value` is represented using valtrees.
@@ -676,7 +686,7 @@ pub fn write_allocations<'tcx>(
fn alloc_ids_from_alloc(
alloc: ConstAllocation<'_>,
) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
- alloc.inner().relocations().values().map(|id| *id)
+ alloc.inner().provenance().values().map(|id| *id)
}
fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
@@ -696,9 +706,9 @@ pub fn write_allocations<'tcx>(
struct CollectAllocIds(BTreeSet<AllocId>);
impl<'tcx> Visitor<'tcx> for CollectAllocIds {
- fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) {
+ fn visit_constant(&mut self, c: &Constant<'tcx>, _: Location) {
match c.literal {
- ConstantKind::Ty(c) => self.visit_const(c, loc),
+ ConstantKind::Ty(_) | ConstantKind::Unevaluated(..) => {}
ConstantKind::Val(val, _) => {
self.0.extend(alloc_ids_from_const_val(val));
}
@@ -778,7 +788,7 @@ pub fn write_allocations<'tcx>(
/// If the allocation is small enough to fit into a single line, no start address is given.
/// After the hex dump, an ascii dump follows, replacing all unprintable characters (control
/// characters or characters whose value is larger than 127) with a `.`
-/// This also prints relocations adequately.
+/// This also prints provenance adequately.
pub fn display_allocation<'a, 'tcx, Prov, Extra>(
tcx: TyCtxt<'tcx>,
alloc: &'a Allocation<Prov, Extra>,
@@ -873,34 +883,34 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
if i != line_start {
write!(w, " ")?;
}
- if let Some(&prov) = alloc.relocations().get(&i) {
- // Memory with a relocation must be defined
+ if let Some(&prov) = alloc.provenance().get(&i) {
+ // Memory with provenance must be defined
assert!(alloc.init_mask().is_range_initialized(i, i + ptr_size).is_ok());
let j = i.bytes_usize();
let offset = alloc
.inspect_with_uninit_and_ptr_outside_interpreter(j..j + ptr_size.bytes_usize());
let offset = read_target_uint(tcx.data_layout.endian, offset).unwrap();
let offset = Size::from_bytes(offset);
- let relocation_width = |bytes| bytes * 3;
+ let provenance_width = |bytes| bytes * 3;
let ptr = Pointer::new(prov, offset);
let mut target = format!("{:?}", ptr);
- if target.len() > relocation_width(ptr_size.bytes_usize() - 1) {
+ if target.len() > provenance_width(ptr_size.bytes_usize() - 1) {
// This is too long, try to save some space.
target = format!("{:#?}", ptr);
}
if ((i - line_start) + ptr_size).bytes_usize() > BYTES_PER_LINE {
- // This branch handles the situation where a relocation starts in the current line
+ // This branch handles the situation where a provenance starts in the current line
// but ends in the next one.
let remainder = Size::from_bytes(BYTES_PER_LINE) - (i - line_start);
let overflow = ptr_size - remainder;
- let remainder_width = relocation_width(remainder.bytes_usize()) - 2;
- let overflow_width = relocation_width(overflow.bytes_usize() - 1) + 1;
+ let remainder_width = provenance_width(remainder.bytes_usize()) - 2;
+ let overflow_width = provenance_width(overflow.bytes_usize() - 1) + 1;
ascii.push('╾');
for _ in 0..remainder.bytes() - 1 {
ascii.push('─');
}
if overflow_width > remainder_width && overflow_width >= target.len() {
- // The case where the relocation fits into the part in the next line
+ // The case where the provenance fits into the part in the next line
write!(w, "╾{0:─^1$}", "", remainder_width)?;
line_start =
write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?;
@@ -921,11 +931,11 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
i += ptr_size;
continue;
} else {
- // This branch handles a relocation that starts and ends in the current line.
- let relocation_width = relocation_width(ptr_size.bytes_usize() - 1);
- oversized_ptr(&mut target, relocation_width);
+ // This branch handles a provenance that starts and ends in the current line.
+ let provenance_width = provenance_width(ptr_size.bytes_usize() - 1);
+ oversized_ptr(&mut target, provenance_width);
ascii.push('╾');
- write!(w, "╾{0:─^1$}╼", target, relocation_width)?;
+ write!(w, "╾{0:─^1$}╼", target, provenance_width)?;
for _ in 0..ptr_size.bytes() - 2 {
ascii.push('─');
}
@@ -935,7 +945,7 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
} else if alloc.init_mask().is_range_initialized(i, i + Size::from_bytes(1)).is_ok() {
let j = i.bytes_usize();
- // Checked definedness (and thus range) and relocations. This access also doesn't
+ // Checked definedness (and thus range) and provenance. This access also doesn't
// influence interpreter execution but is only for debugging.
let c = alloc.inspect_with_uninit_and_ptr_outside_interpreter(j..j + 1)[0];
write!(w, "{:02x}", c)?;
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index dd9f8795f..d89efe2b3 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -2,7 +2,7 @@
use crate::mir::{Body, ConstantKind, Promoted};
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
@@ -115,21 +115,6 @@ pub enum UnusedUnsafe {
/// `unsafe` block nested under another (used) `unsafe` block
/// > ``… because it's nested under this `unsafe` block``
InUnsafeBlock(hir::HirId),
- /// `unsafe` block nested under `unsafe fn`
- /// > ``… because it's nested under this `unsafe fn` ``
- ///
- /// the second HirId here indicates the first usage of the `unsafe` block,
- /// which allows retrieval of the LintLevelSource for why that operation would
- /// have been permitted without the block
- InUnsafeFn(hir::HirId, hir::HirId),
-}
-
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UsedUnsafeBlockData {
- SomeDisallowedInUnsafeFn,
- // the HirId here indicates the first usage of the `unsafe` block
- // (i.e. the one that's first encountered in the MIR traversal of the unsafety check)
- AllAllowedInUnsafeFn(hir::HirId),
}
#[derive(TyEncodable, TyDecodable, HashStable, Debug)]
@@ -138,10 +123,7 @@ pub struct UnsafetyCheckResult {
pub violations: Vec<UnsafetyViolation>,
/// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
- ///
- /// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether
- /// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`.
- pub used_unsafe_blocks: FxHashMap<hir::HirId, UsedUnsafeBlockData>,
+ pub used_unsafe_blocks: FxHashSet<hir::HirId>,
/// This is `Some` iff the item is not a closure.
pub unused_unsafes: Option<Vec<(hir::HirId, UnusedUnsafe)>>,
@@ -345,7 +327,7 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
///
/// See also `rustc_const_eval::borrow_check::constraints`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
-#[derive(TyEncodable, TyDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)]
pub enum ConstraintCategory<'tcx> {
Return(ReturnConstraint),
Yield,
@@ -387,7 +369,7 @@ pub enum ConstraintCategory<'tcx> {
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
-#[derive(TyEncodable, TyDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
pub enum ReturnConstraint {
Normal,
ClosureUpvar(Field),
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index 4418b848e..4e06d9101 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -105,7 +105,7 @@ where
}
let body_span = hir_body.unwrap().value.span;
let mut span_viewables = Vec::new();
- for (bb, data) in body.basic_blocks().iter_enumerated() {
+ for (bb, data) in body.basic_blocks.iter_enumerated() {
match spanview {
MirSpanview::Statement => {
for (i, statement) in data.statements.iter().enumerate() {
@@ -249,7 +249,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
Retag(..) => "Retag",
AscribeUserType(..) => "AscribeUserType",
Coverage(..) => "Coverage",
- CopyNonOverlapping(..) => "CopyNonOverlapping",
+ Intrinsic(..) => "Intrinsic",
Nop => "Nop",
}
}
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index eb90169d0..c7d0283aa 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -23,75 +23,110 @@ use rustc_span::symbol::Symbol;
use rustc_span::Span;
use rustc_target::asm::InlineAsmRegOrRegClass;
-/// The various "big phases" that MIR goes through.
+/// Represents the "flavors" of MIR.
///
-/// These phases all describe dialects of MIR. Since all MIR uses the same datastructures, the
-/// dialects forbid certain variants or values in certain phases. The sections below summarize the
-/// changes, but do not document them thoroughly. The full documentation is found in the appropriate
-/// documentation for the thing the change is affecting.
+/// All flavors of MIR use the same data structure, but there are some important differences. These
+/// differences come in two forms: Dialects and phases.
///
-/// Warning: ordering of variants is significant.
+/// Dialects represent a stronger distinction than phases. This is because the transitions between
+/// dialects are semantic changes, and therefore technically *lowerings* between distinct IRs. In
+/// other words, the same [`Body`](crate::mir::Body) might be well-formed for multiple dialects, but
+/// have different semantic meaning and different behavior at runtime.
+///
+/// Each dialect additionally has a number of phases. However, phase changes never involve semantic
+/// changes. If some MIR is well-formed both before and after a phase change, it is also guaranteed
+/// that it has the same semantic meaning. In this sense, phase changes can only add additional
+/// restrictions on what MIR is well-formed.
+///
+/// When adding phases, remember to update [`MirPhase::phase_index`].
#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(HashStable)]
pub enum MirPhase {
- /// The dialect of MIR used during all phases before `DropsLowered` is the same. This is also
- /// the MIR that analysis such as borrowck uses.
- ///
- /// One important thing to remember about the behavior of this section of MIR is that drop terminators
- /// (including drop and replace) are *conditional*. The elaborate drops pass will then replace each
- /// instance of a drop terminator with a nop, an unconditional drop, or a drop conditioned on a drop
- /// flag. Of course, this means that it is important that the drop elaboration can accurately recognize
- /// when things are initialized and when things are de-initialized. That means any code running on this
- /// version of MIR must be sure to produce output that drop elaboration can reason about. See the
- /// section on the drop terminatorss for more details.
- Built = 0,
- // FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
- // We used to have this for pre-miri MIR based const eval.
- Const = 1,
- /// This phase checks the MIR for promotable elements and takes them out of the main MIR body
- /// by creating a new MIR body per promoted element. After this phase (and thus the termination
- /// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir`
- /// query.
- ConstsPromoted = 2,
- /// After this projections may only contain deref projections as the first element.
- Derefered = 3,
- /// Beginning with this phase, the following variants are disallowed:
- /// * [`TerminatorKind::DropAndReplace`]
+ /// The MIR that is generated by MIR building.
+ ///
+ /// The only things that operate on this dialect are unsafeck, the various MIR lints, and const
+ /// qualifs.
+ ///
+ /// This has no distinct phases.
+ Built,
+ /// The MIR used for most analysis.
+ ///
+ /// The only semantic change between analysis and built MIR is constant promotion. In built MIR,
+ /// sequences of statements that would generally be subject to constant promotion are
+ /// semantically constants, while in analysis MIR all constants are explicit.
+ ///
+ /// The result of const promotion is available from the `mir_promoted` and `promoted_mir` queries.
+ ///
+ /// This is the version of MIR used by borrowck and friends.
+ Analysis(AnalysisPhase),
+ /// The MIR used for CTFE, optimizations, and codegen.
+ ///
+ /// The semantic changes that occur in the lowering from analysis to runtime MIR are as follows:
+ ///
+ /// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly speaking,
+ /// if dataflow analysis determines that the place being dropped is uninitialized, the drop will
+ /// not be executed. The exact semantics of this aren't written down anywhere, which means they
+ /// are essentially "what drop elaboration does." In runtime MIR, the drops are unconditional;
+ /// when a `Drop` terminator is reached, if the type has drop glue that drop glue is always
+ /// executed. This may be UB if the underlying place is not initialized.
+ /// - Packed drops: Places might in general be misaligned - in most cases this is UB, the exception
+ /// is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be misaligned
+ /// for this reason implicitly moves `P` to a temporary before dropping. Runtime MIR has no such
+ /// rules, and dropping a misaligned place is simply UB.
+ /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In runtime
+ /// MIR, this is UB.
+ /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same way
+ /// that Rust itself has them. Where exactly these are is generally subject to change, and so we
+ /// don't document this here. Runtime MIR has all retags explicit.
+ /// - Generator bodies: In analysis MIR, locals may actually be behind a pointer that user code has
+ /// access to. This occurs in generator bodies. Such locals do not behave like other locals,
+ /// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals -
+ /// all generator bodies are lowered and so all places that look like locals really are locals.
+ /// - Const prop lints: The lint pass which reports eg `200_u8 + 200_u8` as an error is run as a
+ /// part of analysis to runtime MIR lowering. This means that transformations which may supress
+ /// such errors may not run on analysis MIR.
+ Runtime(RuntimePhase),
+}
+
+/// See [`MirPhase::Analysis`].
+#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(HashStable)]
+pub enum AnalysisPhase {
+ Initial = 0,
+ /// Beginning in this phase, the following variants are disallowed:
/// * [`TerminatorKind::FalseUnwind`]
/// * [`TerminatorKind::FalseEdge`]
/// * [`StatementKind::FakeRead`]
/// * [`StatementKind::AscribeUserType`]
/// * [`Rvalue::Ref`] with `BorrowKind::Shallow`
///
- /// And the following variant is allowed:
- /// * [`StatementKind::Retag`]
- ///
- /// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop`
- /// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands
- /// are allowed for non-`Copy` types.
- DropsLowered = 4,
- /// Beginning with this phase, the following variant is disallowed:
+ /// Furthermore, `Deref` projections must be the first projection within any place (if they
+ /// appear at all)
+ PostCleanup = 1,
+}
+
+/// See [`MirPhase::Runtime`].
+#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(HashStable)]
+pub enum RuntimePhase {
+ /// In addition to the semantic changes, beginning with this phase, the following variants are
+ /// disallowed:
+ /// * [`TerminatorKind::DropAndReplace`]
+ /// * [`TerminatorKind::Yield`]
+ /// * [`TerminatorKind::GeneratorDrop`]
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
///
- /// And the following variant is allowed:
+ /// And the following variants are allowed:
+ /// * [`StatementKind::Retag`]
/// * [`StatementKind::SetDiscriminant`]
- Deaggregated = 5,
- /// Before this phase, generators are in the "source code" form, featuring `yield` statements
- /// and such. With this phase change, they are transformed into a proper state machine. Running
- /// optimizations before this change can be potentially dangerous because the source code is to
- /// some extent a "lie." In particular, `yield` terminators effectively make the value of all
- /// locals visible to the caller. This means that dead store elimination before them, or code
- /// motion across them, is not correct in general. This is also exasperated by type checking
- /// having pre-computed a list of the types that it thinks are ok to be live across a yield
- /// point - this is necessary to decide eg whether autotraits are implemented. Introducing new
- /// types across a yield point will lead to ICEs becaues of this.
- ///
- /// Beginning with this phase, the following variants are disallowed:
- /// * [`TerminatorKind::Yield`]
- /// * [`TerminatorKind::GeneratorDrop`]
+ /// * [`StatementKind::Deinit`]
+ ///
+ /// Furthermore, `Copy` operands are allowed for non-`Copy` types.
+ Initial = 0,
+ /// Beginning with this phase, the following variant is disallowed:
/// * [`ProjectionElem::Deref`] of `Box`
- GeneratorsLowered = 6,
- Optimized = 7,
+ PostCleanup = 1,
+ Optimized = 2,
}
///////////////////////////////////////////////////////////////////////////
@@ -292,12 +327,40 @@ pub enum StatementKind<'tcx> {
/// executed.
Coverage(Box<Coverage>),
+ /// Denotes a call to an intrinsic that does not require an unwind path and always returns.
+ /// This avoids adding a new block and a terminator for simple intrinsics.
+ Intrinsic(Box<NonDivergingIntrinsic<'tcx>>),
+
+ /// No-op. Useful for deleting instructions without affecting statement indices.
+ Nop,
+}
+
+#[derive(
+ Clone,
+ TyEncodable,
+ TyDecodable,
+ Debug,
+ PartialEq,
+ Hash,
+ HashStable,
+ TypeFoldable,
+ TypeVisitable
+)]
+pub enum NonDivergingIntrinsic<'tcx> {
+ /// Denotes a call to the intrinsic function `assume`.
+ ///
+ /// The operand must be a boolean. Optimizers may use the value of the boolean to backtrack its
+ /// computation to infer information about other variables. So if the boolean came from a
+ /// `x < y` operation, subsequent operations on `x` and `y` could elide various bound checks.
+ /// If the argument is `false`, this operation is equivalent to `TerminatorKind::Unreachable`.
+ Assume(Operand<'tcx>),
+
/// Denotes a call to the intrinsic function `copy_nonoverlapping`.
///
/// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer,
/// or `Box` pointing to the same type `T`. `count` must evaluate to a `usize`. Then, `src` and
/// `dest` are dereferenced, and `count * size_of::<T>()` bytes beginning with the first byte of
- /// the `src` place are copied to the continguous range of bytes beginning with the first byte
+ /// the `src` place are copied to the contiguous range of bytes beginning with the first byte
/// of `dest`.
///
/// **Needs clarification**: In what order are operands computed and dereferenced? It should
@@ -305,10 +368,18 @@ pub enum StatementKind<'tcx> {
///
/// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved?
/// I vaguely remember Ralf saying somewhere that he thought it should not be.
- CopyNonOverlapping(Box<CopyNonOverlapping<'tcx>>),
+ CopyNonOverlapping(CopyNonOverlapping<'tcx>),
+}
- /// No-op. Useful for deleting instructions without affecting statement indices.
- Nop,
+impl std::fmt::Display for NonDivergingIntrinsic<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Assume(op) => write!(f, "assume({op:?})"),
+ Self::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
+ write!(f, "copy_nonoverlapping(dst = {dst:?}, src = {src:?}, count = {count:?})")
+ }
+ }
+ }
}
/// Describes what kind of retag is to be performed.
@@ -343,7 +414,7 @@ pub enum FakeReadCause {
/// Some(closure_def_id).
/// Otherwise, the value of the optional LocalDefId will be None.
//
- // We can use LocaDefId here since fake read statements are removed
+ // We can use LocalDefId here since fake read statements are removed
// before codegen in the `CleanupNonCodegenStatements` pass.
ForMatchedPlace(Option<LocalDefId>),
@@ -417,7 +488,7 @@ pub struct CopyNonOverlapping<'tcx> {
/// must also be `cleanup`. This is a part of the type system and checked statically, so it is
/// still an error to have such an edge in the CFG even if it's known that it won't be taken at
/// runtime.
-#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
+#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum TerminatorKind<'tcx> {
/// Block has one successor; we continue execution there.
Goto { target: BasicBlock },
@@ -670,7 +741,7 @@ pub enum TerminatorKind<'tcx> {
}
/// Information about an assertion failure.
-#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, PartialOrd)]
+#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum AssertKind<O> {
BoundsCheck { len: O, index: O },
Overflow(BinOp, O, O),
@@ -792,7 +863,7 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
///
/// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
/// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct Place<'tcx> {
pub local: Local,
@@ -801,7 +872,7 @@ pub struct Place<'tcx> {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(TyEncodable, TyDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub enum ProjectionElem<V, T> {
Deref,
Field(Field, T),
@@ -884,7 +955,7 @@ pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
/// **Needs clarifiation:** Is loading a place that has its variant index set well-formed? Miri
/// currently implements it, but it seems like this may be something to check against in the
/// validator.
-#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
+#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum Operand<'tcx> {
/// Creates a value by loading the given place.
///
@@ -915,7 +986,7 @@ pub enum Operand<'tcx> {
/// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
/// clarification**: Which order?). These are then used to produce a "value" - the same kind of
/// value that an [`Operand`] produces.
-#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
+#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum Rvalue<'tcx> {
/// Yields the operand unchanged
Use(Operand<'tcx>),
@@ -1068,11 +1139,14 @@ pub enum CastKind {
/// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are
/// translated into `&raw mut/const *r`, i.e., they are not actually casts.
Pointer(PointerCast),
+ /// Cast into a dyn* object.
+ DynStar,
/// Remaining unclassified casts.
Misc,
}
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
+#[derive(TypeFoldable, TypeVisitable)]
pub enum AggregateKind<'tcx> {
/// The type is of the element
Array(Ty<'tcx>),
@@ -1160,7 +1234,8 @@ pub enum BinOp {
mod size_asserts {
use super::*;
// These are in alphabetical order, which is easy to maintain.
- static_assert_size!(AggregateKind<'_>, 48);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(AggregateKind<'_>, 40);
static_assert_size!(Operand<'_>, 24);
static_assert_size!(Place<'_>, 16);
static_assert_size!(PlaceElem<'_>, 24);
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 9ccf5aea6..4ea333cff 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -14,7 +14,7 @@ use std::slice;
pub use super::query::*;
-#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, PartialOrd)]
+#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
pub struct SwitchTargets {
/// Possible values. The locations to branch to in each case
/// are found in the corresponding indices from the `targets` vector.
@@ -102,7 +102,7 @@ impl<'a> Iterator for SwitchTargetsIter<'a> {
impl<'a> ExactSizeIterator for SwitchTargetsIter<'a> {}
-#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct Terminator<'tcx> {
pub source_info: SourceInfo,
pub kind: TerminatorKind<'tcx>,
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 627dc32f3..55b2c5927 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -37,7 +37,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
Preorder {
body,
- visited: BitSet::new_empty(body.basic_blocks().len()),
+ visited: BitSet::new_empty(body.basic_blocks.len()),
worklist,
root_is_start_block: root == START_BLOCK,
}
@@ -71,7 +71,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
fn size_hint(&self) -> (usize, Option<usize>) {
// All the blocks, minus the number of blocks we've visited.
- let upper = self.body.basic_blocks().len() - self.visited.count();
+ let upper = self.body.basic_blocks.len() - self.visited.count();
let lower = if self.root_is_start_block {
// We will visit all remaining blocks exactly once.
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index 82a6b0c50..9d098c808 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -1,8 +1,9 @@
//! `TypeFoldable` implementations for MIR types
+use rustc_ast::InlineAsmTemplatePiece;
+
use super::*;
use crate::ty;
-use rustc_data_structures::functor::IdFunctor;
TrivialTypeTraversalAndLiftImpls! {
BlockTailInfo,
@@ -13,96 +14,27 @@ TrivialTypeTraversalAndLiftImpls! {
SourceScope,
SourceScopeLocalData,
UserTypeAnnotationIndex,
+ BorrowKind,
+ CastKind,
+ BinOp,
+ NullOp,
+ UnOp,
+ hir::Movability,
+ BasicBlock,
+ SwitchTargets,
+ GeneratorKind,
+ GeneratorSavedLocal,
}
-impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- use crate::mir::TerminatorKind::*;
-
- let kind = match self.kind {
- Goto { target } => Goto { target },
- SwitchInt { discr, switch_ty, targets } => SwitchInt {
- discr: discr.try_fold_with(folder)?,
- switch_ty: switch_ty.try_fold_with(folder)?,
- targets,
- },
- Drop { place, target, unwind } => {
- Drop { place: place.try_fold_with(folder)?, target, unwind }
- }
- DropAndReplace { place, value, target, unwind } => DropAndReplace {
- place: place.try_fold_with(folder)?,
- value: value.try_fold_with(folder)?,
- target,
- unwind,
- },
- Yield { value, resume, resume_arg, drop } => Yield {
- value: value.try_fold_with(folder)?,
- resume,
- resume_arg: resume_arg.try_fold_with(folder)?,
- drop,
- },
- Call { func, args, destination, target, cleanup, from_hir_call, fn_span } => Call {
- func: func.try_fold_with(folder)?,
- args: args.try_fold_with(folder)?,
- destination: destination.try_fold_with(folder)?,
- target,
- cleanup,
- from_hir_call,
- fn_span,
- },
- Assert { cond, expected, msg, target, cleanup } => {
- use AssertKind::*;
- let msg = match msg {
- BoundsCheck { len, index } => BoundsCheck {
- len: len.try_fold_with(folder)?,
- index: index.try_fold_with(folder)?,
- },
- Overflow(op, l, r) => {
- Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?)
- }
- OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?),
- DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?),
- RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?),
- ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
- };
- Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup }
- }
- GeneratorDrop => GeneratorDrop,
- Resume => Resume,
- Abort => Abort,
- Return => Return,
- Unreachable => Unreachable,
- FalseEdge { real_target, imaginary_target } => {
- FalseEdge { real_target, imaginary_target }
- }
- FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
- InlineAsm { template, operands, options, line_spans, destination, cleanup } => {
- InlineAsm {
- template,
- operands: operands.try_fold_with(folder)?,
- options,
- line_spans,
- destination,
- cleanup,
- }
- }
- };
- Ok(Terminator { source_info: self.source_info, kind })
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<'tcx> for &'tcx [InlineAsmTemplatePiece] {
+ fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
Ok(self)
}
}
-impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- Ok(Place {
- local: self.local.try_fold_with(folder)?,
- projection: self.projection.try_fold_with(folder)?,
- })
+impl<'tcx> TypeFoldable<'tcx> for &'tcx [Span] {
+ fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
+ Ok(self)
}
}
@@ -112,114 +44,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
}
}
-impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- use crate::mir::Rvalue::*;
- Ok(match self {
- Use(op) => Use(op.try_fold_with(folder)?),
- Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?),
- ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?),
- Ref(region, bk, place) => {
- Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
- }
- CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?),
- AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
- Len(place) => Len(place.try_fold_with(folder)?),
- Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),
- BinaryOp(op, box (rhs, lhs)) => {
- BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)))
- }
- CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp(
- op,
- Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)),
- ),
- UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?),
- Discriminant(place) => Discriminant(place.try_fold_with(folder)?),
- NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?),
- Aggregate(kind, fields) => {
- let kind = kind.try_map_id(|kind| {
- Ok(match kind {
- AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?),
- AggregateKind::Tuple => AggregateKind::Tuple,
- AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
- def,
- v,
- substs.try_fold_with(folder)?,
- user_ty.try_fold_with(folder)?,
- n,
- ),
- AggregateKind::Closure(id, substs) => {
- AggregateKind::Closure(id, substs.try_fold_with(folder)?)
- }
- AggregateKind::Generator(id, substs, movablity) => {
- AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity)
- }
- })
- })?;
- Aggregate(kind, fields.try_fold_with(folder)?)
- }
- ShallowInitBox(op, ty) => {
- ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?)
- }
- })
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- Ok(match self {
- Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?),
- Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?),
- Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?),
- })
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- use crate::mir::ProjectionElem::*;
-
- Ok(match self {
- Deref => Deref,
- Field(f, ty) => Field(f, ty.try_fold_with(folder)?),
- Index(v) => Index(v.try_fold_with(folder)?),
- Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
- ConstantIndex { offset, min_length, from_end } => {
- ConstantIndex { offset, min_length, from_end }
- }
- Subslice { from, to, from_end } => Subslice { from, to, from_end },
- })
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Field {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
- Ok(self)
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
- Ok(self)
- }
-}
-
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self)
}
}
-impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- Ok(Constant {
- span: self.span,
- user_ty: self.user_ty.try_fold_with(folder)?,
- literal: self.literal.try_fold_with(folder)?,
- })
- }
-}
-
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
#[inline(always)]
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
@@ -235,6 +65,9 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> {
match self {
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)),
ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),
+ ConstantKind::Unevaluated(uv, t) => {
+ Ok(ConstantKind::Unevaluated(uv.try_fold_with(folder)?, t.try_fold_with(folder)?))
+ }
}
}
}
diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs
index 6a0801cb0..be19bb486 100644
--- a/compiler/rustc_middle/src/mir/type_visitable.rs
+++ b/compiler/rustc_middle/src/mir/type_visitable.rs
@@ -1,165 +1,6 @@
//! `TypeVisitable` implementations for MIR types
use super::*;
-use crate::ty;
-
-impl<'tcx> TypeVisitable<'tcx> for Terminator<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- use crate::mir::TerminatorKind::*;
-
- match self.kind {
- SwitchInt { ref discr, switch_ty, .. } => {
- discr.visit_with(visitor)?;
- switch_ty.visit_with(visitor)
- }
- Drop { ref place, .. } => place.visit_with(visitor),
- DropAndReplace { ref place, ref value, .. } => {
- place.visit_with(visitor)?;
- value.visit_with(visitor)
- }
- Yield { ref value, .. } => value.visit_with(visitor),
- Call { ref func, ref args, ref destination, .. } => {
- destination.visit_with(visitor)?;
- func.visit_with(visitor)?;
- args.visit_with(visitor)
- }
- Assert { ref cond, ref msg, .. } => {
- cond.visit_with(visitor)?;
- use AssertKind::*;
- match msg {
- BoundsCheck { ref len, ref index } => {
- len.visit_with(visitor)?;
- index.visit_with(visitor)
- }
- Overflow(_, l, r) => {
- l.visit_with(visitor)?;
- r.visit_with(visitor)
- }
- OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
- op.visit_with(visitor)
- }
- ResumedAfterReturn(_) | ResumedAfterPanic(_) => ControlFlow::CONTINUE,
- }
- }
- InlineAsm { ref operands, .. } => operands.visit_with(visitor),
- Goto { .. }
- | Resume
- | Abort
- | Return
- | GeneratorDrop
- | Unreachable
- | FalseEdge { .. }
- | FalseUnwind { .. } => ControlFlow::CONTINUE,
- }
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for GeneratorKind {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
- ControlFlow::CONTINUE
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for Place<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.local.visit_with(visitor)?;
- self.projection.visit_with(visitor)
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.iter().try_for_each(|t| t.visit_with(visitor))
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- use crate::mir::Rvalue::*;
- match *self {
- Use(ref op) => op.visit_with(visitor),
- CopyForDeref(ref place) => {
- let op = &Operand::Copy(*place);
- op.visit_with(visitor)
- }
- Repeat(ref op, _) => op.visit_with(visitor),
- ThreadLocalRef(did) => did.visit_with(visitor),
- Ref(region, _, ref place) => {
- region.visit_with(visitor)?;
- place.visit_with(visitor)
- }
- AddressOf(_, ref place) => place.visit_with(visitor),
- Len(ref place) => place.visit_with(visitor),
- Cast(_, ref op, ty) => {
- op.visit_with(visitor)?;
- ty.visit_with(visitor)
- }
- BinaryOp(_, box (ref rhs, ref lhs)) | CheckedBinaryOp(_, box (ref rhs, ref lhs)) => {
- rhs.visit_with(visitor)?;
- lhs.visit_with(visitor)
- }
- UnaryOp(_, ref val) => val.visit_with(visitor),
- Discriminant(ref place) => place.visit_with(visitor),
- NullaryOp(_, ty) => ty.visit_with(visitor),
- Aggregate(ref kind, ref fields) => {
- match **kind {
- AggregateKind::Array(ty) => {
- ty.visit_with(visitor)?;
- }
- AggregateKind::Tuple => {}
- AggregateKind::Adt(_, _, substs, user_ty, _) => {
- substs.visit_with(visitor)?;
- user_ty.visit_with(visitor)?;
- }
- AggregateKind::Closure(_, substs) => {
- substs.visit_with(visitor)?;
- }
- AggregateKind::Generator(_, substs, _) => {
- substs.visit_with(visitor)?;
- }
- }
- fields.visit_with(visitor)
- }
- ShallowInitBox(ref op, ty) => {
- op.visit_with(visitor)?;
- ty.visit_with(visitor)
- }
- }
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for Operand<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- match *self {
- Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
- Operand::Constant(ref c) => c.visit_with(visitor),
- }
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for PlaceElem<'tcx> {
- fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
- use crate::mir::ProjectionElem::*;
-
- match self {
- Field(_, ty) => ty.visit_with(visitor),
- Index(v) => v.visit_with(visitor),
- _ => ControlFlow::CONTINUE,
- }
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for Field {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
- ControlFlow::CONTINUE
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for GeneratorSavedLocal {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
- ControlFlow::CONTINUE
- }
-}
impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
@@ -167,13 +8,6 @@ impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> {
}
}
-impl<'tcx> TypeVisitable<'tcx> for Constant<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.literal.visit_with(visitor)?;
- self.user_ty.visit_with(visitor)
- }
-}
-
impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_mir_const(*self)
@@ -185,6 +19,10 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> {
match *self {
ConstantKind::Ty(c) => c.visit_with(visitor),
ConstantKind::Val(_, t) => t.visit_with(visitor),
+ ConstantKind::Unevaluated(uv, t) => {
+ uv.visit_with(visitor)?;
+ t.visit_with(visitor)
+ }
}
}
}
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 891608764..d9b24566b 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -80,6 +80,8 @@ macro_rules! make_mir_visitor {
self.super_body(body);
}
+ extra_body_methods!($($mutability)?);
+
fn visit_basic_block_data(
&mut self,
block: BasicBlock,
@@ -235,14 +237,6 @@ macro_rules! make_mir_visitor {
self.super_region(region);
}
- fn visit_const(
- &mut self,
- constant: $(& $mutability)? ty::Const<'tcx>,
- _: Location,
- ) {
- self.super_const(constant);
- }
-
fn visit_substs(
&mut self,
substs: & $($mutability)? SubstsRef<'tcx>,
@@ -287,63 +281,7 @@ macro_rules! make_mir_visitor {
&mut self,
body: &$($mutability)? Body<'tcx>,
) {
- let span = body.span;
- if let Some(gen) = &$($mutability)? body.generator {
- if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
- self.visit_ty(
- yield_ty,
- TyContext::YieldTy(SourceInfo::outermost(span))
- );
- }
- }
-
- // for best performance, we want to use an iterator rather
- // than a for-loop, to avoid calling `body::Body::invalidate` for
- // each basic block.
- #[allow(unused_macro_rules)]
- macro_rules! basic_blocks {
- (mut) => (body.basic_blocks_mut().iter_enumerated_mut());
- () => (body.basic_blocks().iter_enumerated());
- }
- for (bb, data) in basic_blocks!($($mutability)?) {
- self.visit_basic_block_data(bb, data);
- }
-
- for scope in &$($mutability)? body.source_scopes {
- self.visit_source_scope_data(scope);
- }
-
- self.visit_ty(
- $(& $mutability)? body.return_ty(),
- TyContext::ReturnTy(SourceInfo::outermost(body.span))
- );
-
- for local in body.local_decls.indices() {
- self.visit_local_decl(local, & $($mutability)? body.local_decls[local]);
- }
-
- #[allow(unused_macro_rules)]
- macro_rules! type_annotations {
- (mut) => (body.user_type_annotations.iter_enumerated_mut());
- () => (body.user_type_annotations.iter_enumerated());
- }
-
- for (index, annotation) in type_annotations!($($mutability)?) {
- self.visit_user_type_annotation(
- index, annotation
- );
- }
-
- for var_debug_info in &$($mutability)? body.var_debug_info {
- self.visit_var_debug_info(var_debug_info);
- }
-
- self.visit_span($(& $mutability)? body.span);
-
- for const_ in &$($mutability)? body.required_consts {
- let location = START_BLOCK.start_location();
- self.visit_constant(const_, location);
- }
+ super_body!(self, body, $($mutability, true)?);
}
fn super_basic_block_data(&mut self,
@@ -479,14 +417,15 @@ macro_rules! make_mir_visitor {
location
)
}
- StatementKind::CopyNonOverlapping(box crate::mir::CopyNonOverlapping{
- src,
- dst,
- count,
- }) => {
- self.visit_operand(src, location);
- self.visit_operand(dst, location);
- self.visit_operand(count, location)
+ StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => {
+ match intrinsic {
+ NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location),
+ NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
+ self.visit_operand(src, location);
+ self.visit_operand(dst, location);
+ self.visit_operand(count, location);
+ }
+ }
}
StatementKind::Nop => {}
}
@@ -930,8 +869,9 @@ macro_rules! make_mir_visitor {
self.visit_span($(& $mutability)? *span);
drop(user_ty); // no visit method for this
match literal {
- ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location),
+ ConstantKind::Ty(_) => {}
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
+ ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
}
}
@@ -969,9 +909,6 @@ macro_rules! make_mir_visitor {
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
}
- fn super_const(&mut self, _const: $(& $mutability)? ty::Const<'tcx>) {
- }
-
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
}
@@ -982,12 +919,7 @@ macro_rules! make_mir_visitor {
body: &$($mutability)? Body<'tcx>,
location: Location
) {
- #[allow(unused_macro_rules)]
- macro_rules! basic_blocks {
- (mut) => (body.basic_blocks_mut());
- () => (body.basic_blocks());
- }
- let basic_block = & $($mutability)? basic_blocks!($($mutability)?)[location.block];
+ let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block];
if basic_block.statements.len() == location.statement_index {
if let Some(ref $($mutability)? terminator) = basic_block.terminator {
self.visit_terminator(terminator, location)
@@ -1002,6 +934,94 @@ macro_rules! make_mir_visitor {
}
}
+macro_rules! basic_blocks {
+ ($body:ident, mut, true) => {
+ $body.basic_blocks.as_mut()
+ };
+ ($body:ident, mut, false) => {
+ $body.basic_blocks.as_mut_preserves_cfg()
+ };
+ ($body:ident,) => {
+ $body.basic_blocks
+ };
+}
+
+macro_rules! basic_blocks_iter {
+ ($body:ident, mut, $invalidate:tt) => {
+ basic_blocks!($body, mut, $invalidate).iter_enumerated_mut()
+ };
+ ($body:ident,) => {
+ basic_blocks!($body,).iter_enumerated()
+ };
+}
+
+macro_rules! extra_body_methods {
+ (mut) => {
+ fn visit_body_preserves_cfg(&mut self, body: &mut Body<'tcx>) {
+ self.super_body_preserves_cfg(body);
+ }
+
+ fn super_body_preserves_cfg(&mut self, body: &mut Body<'tcx>) {
+ super_body!(self, body, mut, false);
+ }
+ };
+ () => {};
+}
+
+macro_rules! super_body {
+ ($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => {
+ let span = $body.span;
+ if let Some(gen) = &$($mutability)? $body.generator {
+ if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
+ $self.visit_ty(
+ yield_ty,
+ TyContext::YieldTy(SourceInfo::outermost(span))
+ );
+ }
+ }
+
+ for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) {
+ $self.visit_basic_block_data(bb, data);
+ }
+
+ for scope in &$($mutability)? $body.source_scopes {
+ $self.visit_source_scope_data(scope);
+ }
+
+ $self.visit_ty(
+ $(& $mutability)? $body.return_ty(),
+ TyContext::ReturnTy(SourceInfo::outermost($body.span))
+ );
+
+ for local in $body.local_decls.indices() {
+ $self.visit_local_decl(local, & $($mutability)? $body.local_decls[local]);
+ }
+
+ #[allow(unused_macro_rules)]
+ macro_rules! type_annotations {
+ (mut) => ($body.user_type_annotations.iter_enumerated_mut());
+ () => ($body.user_type_annotations.iter_enumerated());
+ }
+
+ for (index, annotation) in type_annotations!($($mutability)?) {
+ $self.visit_user_type_annotation(
+ index, annotation
+ );
+ }
+
+ for var_debug_info in &$($mutability)? $body.var_debug_info {
+ $self.visit_var_debug_info(var_debug_info);
+ }
+
+ $self.visit_span($(& $mutability)? $body.span);
+
+ for const_ in &$($mutability)? $body.required_consts {
+ let location = START_BLOCK.start_location();
+ $self.visit_constant(const_, location);
+ }
+ }
+}
+
macro_rules! visit_place_fns {
(mut) => {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d8483e7e4..4b336ea62 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -47,14 +47,14 @@ rustc_queries! {
/// To avoid this fate, do not call `tcx.hir().krate()`; instead,
/// prefer wrappers like `tcx.visit_all_items_in_krate()`.
query hir_crate(key: ()) -> Crate<'tcx> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "get the crate HIR" }
}
/// All items in the crate.
query hir_crate_items(_: ()) -> rustc_middle::hir::ModuleItems {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "get HIR crate items" }
}
@@ -64,7 +64,7 @@ rustc_queries! {
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
/// Avoid calling this query directly.
query hir_module_items(key: LocalDefId) -> rustc_middle::hir::ModuleItems {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
cache_on_disk_if { true }
}
@@ -161,6 +161,14 @@ rustc_queries! {
separate_provide_extern
}
+ query collect_trait_impl_trait_tys(key: DefId)
+ -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>
+ {
+ desc { "compare an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
+ cache_on_disk_if { key.is_local() }
+ separate_provide_extern
+ }
+
query analysis(key: ()) -> Result<(), ErrorGuaranteed> {
eval_always
desc { "running analysis passes on this crate" }
@@ -189,7 +197,7 @@ rustc_queries! {
/// associated generics.
query generics_of(key: DefId) -> ty::Generics {
desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) }
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@@ -261,13 +269,13 @@ rustc_queries! {
}
query native_libraries(_: CrateNum) -> Vec<NativeLib> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "looking up the native libraries of a linked crate" }
separate_provide_extern
}
query lint_levels(_: ()) -> LintLevelMap {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "computing the lint levels for items in this crate" }
}
@@ -300,7 +308,7 @@ rustc_queries! {
/// Create a THIR tree for debugging.
query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> String {
no_hash
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
}
@@ -308,7 +316,7 @@ rustc_queries! {
/// them. This includes all the body owners, but also things like struct
/// constructors.
query mir_keys(_: ()) -> rustc_data_structures::fx::FxIndexSet<LocalDefId> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "getting a list of all mir_keys" }
}
@@ -415,7 +423,7 @@ rustc_queries! {
query symbols_for_closure_captures(
key: (LocalDefId, LocalDefId)
) -> Vec<rustc_span::Symbol> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc {
|tcx| "symbols for captures of closure `{}` in `{}`",
tcx.def_path_str(key.1.to_def_id()),
@@ -435,7 +443,7 @@ rustc_queries! {
/// MIR pass (assuming the -Cinstrument-coverage option is enabled).
query coverageinfo(key: ty::InstanceDef<'tcx>) -> mir::CoverageInfo {
desc { |tcx| "retrieving coverage info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
}
/// Returns the `CodeRegions` for a function that has instrumented coverage, in case the
@@ -445,7 +453,7 @@ rustc_queries! {
|tcx| "retrieving the covered `CodeRegion`s, if instrumented, for `{}`",
tcx.def_path_str(key)
}
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
cache_on_disk_if { key.is_local() }
}
@@ -483,7 +491,7 @@ rustc_queries! {
}
query wasm_import_module_map(_: CrateNum) -> FxHashMap<DefId, String> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "wasm import module map" }
}
@@ -559,7 +567,7 @@ rustc_queries! {
query trait_def(key: DefId) -> ty::TraitDef {
desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) }
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@@ -637,7 +645,7 @@ rustc_queries! {
/// Gets a map with the variance of every item; use `item_variance` instead.
query crate_variances(_: ()) -> ty::CrateVariancesMap<'tcx> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "computing the variances for items in this crate" }
}
@@ -650,7 +658,7 @@ rustc_queries! {
/// Maps from thee `DefId` of a type to its (inferred) outlives.
query inferred_outlives_crate(_: ()) -> ty::CratePredicatesMap<'tcx> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "computing the inferred outlives predicates for items in this crate" }
}
@@ -664,14 +672,14 @@ rustc_queries! {
/// Maps from a trait item to the trait item "descriptor".
query associated_item(key: DefId) -> ty::AssocItem {
desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) }
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
/// Collects the associated items defined on a trait or impl.
query associated_items(key: DefId) -> ty::AssocItems<'tcx> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
}
@@ -697,7 +705,7 @@ rustc_queries! {
/// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be
///`{ trait_f: impl_f, trait_g: impl_g }`
query impl_item_implementor_ids(impl_id: DefId) -> FxHashMap<DefId, DefId> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "comparing impl items against trait for {}", tcx.def_path_str(impl_id) }
}
@@ -765,11 +773,20 @@ rustc_queries! {
desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) }
}
+ /// Returns the types assumed to be well formed while "inside" of the given item.
+ ///
+ /// Note that we've liberated the late bound regions of function signatures, so
+ /// this can not be used to check whether these types are well formed.
+ query assumed_wf_types(key: DefId) -> &'tcx ty::List<Ty<'tcx>> {
+ desc { |tcx| "computing the implied bounds of {}", tcx.def_path_str(key) }
+ }
+
/// Computes the signature of the function.
query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> {
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
+ cycle_delay_bug
}
/// Performs lint checking for the module.
@@ -809,8 +826,8 @@ rustc_queries! {
desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) }
}
- query check_mod_liveness(key: LocalDefId) -> () {
- desc { |tcx| "checking liveness of variables in {}", describe_as_module(key, tcx) }
+ query check_liveness(key: DefId) {
+ desc { |tcx| "checking liveness of variables in {}", tcx.def_path_str(key) }
}
/// Return the live symbols in the crate for dead code check.
@@ -821,7 +838,7 @@ rustc_queries! {
FxHashSet<LocalDefId>,
FxHashMap<LocalDefId, Vec<(DefId, DefId)>>
) {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "find live symbols in crate" }
}
@@ -867,13 +884,6 @@ rustc_queries! {
query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
cache_on_disk_if { true }
- load_cached(tcx, id) {
- let typeck_results: Option<ty::TypeckResults<'tcx>> = tcx
- .on_disk_cache().as_ref()
- .and_then(|c| c.try_load_query_result(*tcx, id));
-
- typeck_results.map(|x| &*tcx.arena.alloc(x))
- }
}
query used_trait_imports(key: LocalDefId) -> &'tcx FxHashSet<LocalDefId> {
@@ -905,7 +915,7 @@ rustc_queries! {
/// Gets a complete map from all types to their inherent impls.
/// Not meant to be used directly outside of coherence.
query crate_inherent_impls(k: ()) -> CrateInherentImpls {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "all inherent impls defined in crate" }
}
@@ -1038,7 +1048,7 @@ rustc_queries! {
}
query reachable_set(_: ()) -> FxHashSet<LocalDefId> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "reachability" }
}
@@ -1050,7 +1060,7 @@ rustc_queries! {
/// Generates a MIR body for the shim.
query mir_shims(key: ty::InstanceDef<'tcx>) -> mir::Body<'tcx> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) }
}
@@ -1094,6 +1104,11 @@ rustc_queries! {
separate_provide_extern
}
+ query lookup_default_body_stability(def_id: DefId) -> Option<attr::DefaultBodyStability> {
+ desc { |tcx| "looking up default body stability of `{}`", tcx.def_path_str(def_id) }
+ separate_provide_extern
+ }
+
query should_inherit_track_caller(def_id: DefId) -> bool {
desc { |tcx| "computing should_inherit_track_caller of `{}`", tcx.def_path_str(def_id) }
}
@@ -1119,7 +1134,7 @@ rustc_queries! {
query codegen_fn_attrs(def_id: DefId) -> CodegenFnAttrs {
desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) }
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@@ -1136,8 +1151,8 @@ rustc_queries! {
/// Gets the rendered value of the specified constant or associated constant.
/// Used by rustdoc.
query rendered_const(def_id: DefId) -> String {
- storage(ArenaCacheSelector<'tcx>)
- desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) }
+ arena_cache
+ desc { |tcx| "rendering constant initializer of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@@ -1181,14 +1196,11 @@ rustc_queries! {
}
}
- query codegen_fulfill_obligation(
+ query codegen_select_candidate(
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
cache_on_disk_if { true }
- desc { |tcx|
- "checking if `{}` fulfills its obligations",
- tcx.def_path_str(key.1.def_id())
- }
+ desc { |tcx| "computing candidate for `{}`", key.1 }
}
/// Return all `impl` blocks in the current crate.
@@ -1198,12 +1210,12 @@ rustc_queries! {
/// Given a trait `trait_id`, return all known `impl` blocks.
query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "trait impls of `{}`", tcx.def_path_str(trait_id) }
}
query specialization_graph_of(trait_id: DefId) -> specialization_graph::Graph {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
cache_on_disk_if { true }
}
@@ -1295,6 +1307,7 @@ rustc_queries! {
query layout_of(
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> {
+ depth_limit
desc { "computing layout of `{}`", key.value }
remap_env_constness
}
@@ -1329,7 +1342,7 @@ rustc_queries! {
}
query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "get the linkage format of all dependencies" }
}
@@ -1422,7 +1435,7 @@ rustc_queries! {
// like the compiler-generated `main` function and so on.
query reachable_non_generics(_: CrateNum)
-> DefIdMap<SymbolExportInfo> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "looking up the exported symbols of a crate" }
separate_provide_extern
}
@@ -1445,7 +1458,7 @@ rustc_queries! {
/// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
/// better, `Instance::upstream_monomorphization()`.
query upstream_monomorphizations(_: ()) -> DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "collecting available upstream monomorphizations" }
}
@@ -1459,7 +1472,7 @@ rustc_queries! {
query upstream_monomorphizations_for(def_id: DefId)
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>>
{
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx|
"collecting available upstream monomorphizations for `{}`",
tcx.def_path_str(def_id),
@@ -1487,7 +1500,7 @@ rustc_queries! {
}
query foreign_modules(_: CrateNum) -> FxHashMap<DefId, ForeignModule> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "looking up the foreign modules of a linked crate" }
separate_provide_extern
}
@@ -1513,13 +1526,13 @@ rustc_queries! {
separate_provide_extern
}
query extra_filename(_: CrateNum) -> String {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "looking up the extra filename for a crate" }
separate_provide_extern
}
query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "looking up the paths for extern crates" }
separate_provide_extern
@@ -1551,6 +1564,9 @@ rustc_queries! {
-> Option<NativeLibKind> {
desc { |tcx| "native_library_kind({})", tcx.def_path_str(def_id) }
}
+ query native_library(def_id: DefId) -> Option<&'tcx NativeLib> {
+ desc { |tcx| "native_library({})", tcx.def_path_str(def_id) }
+ }
/// Does lifetime resolution, but does not descend into trait items. This
/// should only be used for resolving lifetimes of on trait definitions,
@@ -1558,14 +1574,14 @@ rustc_queries! {
/// the same lifetimes and is responsible for diagnostics.
/// See `rustc_resolve::late::lifetimes for details.
query resolve_lifetimes_trait_definition(_: LocalDefId) -> ResolveLifetimes {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "resolving lifetimes for a trait definition" }
}
/// Does lifetime resolution on items. Importantly, we can't resolve
/// lifetimes directly on things like trait methods, because of trait params.
/// See `rustc_resolve::late::lifetimes for details.
query resolve_lifetimes(_: LocalDefId) -> ResolveLifetimes {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "resolving lifetimes" }
}
query named_region_map(_: LocalDefId) ->
@@ -1575,19 +1591,31 @@ rustc_queries! {
query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxIndexSet<LocalDefId>> {
desc { "testing if a region is late bound" }
}
- /// For a given item (like a struct), gets the default lifetimes to be used
+ /// For a given item's generic parameter, gets the default lifetimes to be used
/// for each parameter if a trait object were to be passed for that parameter.
- /// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
- /// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
- query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
- desc { "looking up lifetime defaults for a region on an item" }
+ /// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`.
+ /// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`.
+ /// This query will panic if passed something that is not a type parameter.
+ query object_lifetime_default(key: DefId) -> ObjectLifetimeDefault {
+ desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(key) }
+ separate_provide_extern
}
query late_bound_vars_map(_: LocalDefId)
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
desc { "looking up late bound vars" }
}
- query visibility(def_id: DefId) -> ty::Visibility {
+ /// Computes the visibility of the provided `def_id`.
+ ///
+ /// If the item from the `def_id` doesn't have a visibility, it will panic. For example
+ /// a generic type parameter will panic if you call this method on it:
+ ///
+ /// ```
+ /// pub trait Foo<T: Debug> {}
+ /// ```
+ ///
+ /// In here, if you call `visibility` on `T`, it'll panic.
+ query visibility(def_id: DefId) -> ty::Visibility<DefId> {
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
@@ -1623,7 +1651,7 @@ rustc_queries! {
}
query lib_features(_: ()) -> LibFeatures {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "calculating the lib features map" }
}
query defined_lib_features(_: CrateNum) -> &'tcx [(Symbol, Option<Symbol>)] {
@@ -1631,7 +1659,7 @@ rustc_queries! {
separate_provide_extern
}
query stability_implications(_: CrateNum) -> FxHashMap<Symbol, Symbol> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "calculating the implications between `#[unstable]` features defined in a crate" }
separate_provide_extern
}
@@ -1642,14 +1670,14 @@ rustc_queries! {
}
/// Returns the lang items defined in another crate by loading it from metadata.
query get_lang_items(_: ()) -> LanguageItems {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "calculating the lang items map" }
}
/// Returns all diagnostic items defined in all crates.
query all_diagnostic_items(_: ()) -> rustc_hir::diagnostic_items::DiagnosticItems {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "calculating the diagnostic items map" }
}
@@ -1662,7 +1690,7 @@ rustc_queries! {
/// Returns the diagnostic items defined in a crate.
query diagnostic_items(_: CrateNum) -> rustc_hir::diagnostic_items::DiagnosticItems {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "calculating the diagnostic items map in a crate" }
separate_provide_extern
}
@@ -1672,11 +1700,11 @@ rustc_queries! {
separate_provide_extern
}
query visible_parent_map(_: ()) -> DefIdMap<DefId> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "calculating the visible parent map" }
}
query trimmed_def_paths(_: ()) -> FxHashMap<DefId, Symbol> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "calculating trimmed def paths" }
}
query missing_extern_crate_item(_: CrateNum) -> bool {
@@ -1685,14 +1713,14 @@ rustc_queries! {
separate_provide_extern
}
query used_crate_source(_: CrateNum) -> Lrc<CrateSource> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "looking at the source for a crate" }
separate_provide_extern
}
/// Returns the debugger visualizers defined for this crate.
query debugger_visualizers(_: CrateNum) -> Vec<rustc_span::DebuggerVisualizerFile> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { "looking up the debugger visualizers for this crate" }
separate_provide_extern
}
@@ -1726,7 +1754,7 @@ rustc_queries! {
}
query stability_index(_: ()) -> stability::Index {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "calculating the stability index for the local crate" }
}
@@ -1951,6 +1979,14 @@ rustc_queries! {
}
}
+ query is_impossible_method(key: (DefId, DefId)) -> bool {
+ desc { |tcx|
+ "checking if {} is impossible to call within {}",
+ tcx.def_path_str(key.1),
+ tcx.def_path_str(key.0),
+ }
+ }
+
query method_autoderef_steps(
goal: CanonicalTyGoal<'tcx>
) -> MethodAutoderefStepsResult<'tcx> {
@@ -1959,7 +1995,7 @@ rustc_queries! {
}
query supported_target_features(_: CrateNum) -> FxHashMap<String, Option<Symbol>> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "looking up supported target features" }
}
@@ -2029,7 +2065,7 @@ rustc_queries! {
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
/// because the `ty::Ty`-based wfcheck is always run.
query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option<traits::ObligationCause<'tcx>> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
no_hash
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
@@ -2039,13 +2075,13 @@ rustc_queries! {
/// The list of backend features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
/// `--target` and similar).
query global_backend_features(_: ()) -> Vec<String> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
eval_always
desc { "computing the backend features for CLI flags" }
}
query generator_diagnostic_data(key: DefId) -> Option<GeneratorDiagnosticData<'tcx>> {
- storage(ArenaCacheSelector<'tcx>)
+ arena_cache
desc { |tcx| "looking up generator diagnostic data of `{}`", tcx.def_path_str(key) }
separate_provide_extern
}
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index b856af1d8..86b415050 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -15,50 +15,33 @@ use rustc_hir::def_id::DefId;
use rustc_hir::RangeEnd;
use rustc_index::newtype_index;
use rustc_index::vec::IndexVec;
-use rustc_middle::infer::canonical::Canonical;
use rustc_middle::middle::region;
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::CanonicalUserTypeAnnotation;
-use rustc_middle::ty::{self, AdtDef, Ty, UpvarSubsts, UserType};
-use rustc_span::{Span, Symbol, DUMMY_SP};
+use rustc_middle::ty::{self, AdtDef, Ty, UpvarSubsts};
+use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
+use rustc_span::def_id::LocalDefId;
+use rustc_span::{sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_target::asm::InlineAsmRegOrRegClass;
-
-use rustc_span::def_id::LocalDefId;
use std::fmt;
use std::ops::Index;
pub mod visit;
-newtype_index! {
- /// An index to an [`Arm`] stored in [`Thir::arms`]
- #[derive(HashStable)]
- pub struct ArmId {
- DEBUG_FORMAT = "a{}"
- }
-}
-
-newtype_index! {
- /// An index to an [`Expr`] stored in [`Thir::exprs`]
- #[derive(HashStable)]
- pub struct ExprId {
- DEBUG_FORMAT = "e{}"
- }
-}
-
-newtype_index! {
- #[derive(HashStable)]
- /// An index to a [`Stmt`] stored in [`Thir::stmts`]
- pub struct StmtId {
- DEBUG_FORMAT = "s{}"
- }
-}
-
macro_rules! thir_with_elements {
- ($($name:ident: $id:ty => $value:ty,)*) => {
+ ($($name:ident: $id:ty => $value:ty => $format:literal,)*) => {
+ $(
+ newtype_index! {
+ #[derive(HashStable)]
+ pub struct $id {
+ DEBUG_FORMAT = $format
+ }
+ }
+ )*
+
/// A container for a THIR body.
///
/// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
@@ -90,10 +73,29 @@ macro_rules! thir_with_elements {
}
}
+pub const UPVAR_ENV_PARAM: ParamId = ParamId::from_u32(0);
+
thir_with_elements! {
- arms: ArmId => Arm<'tcx>,
- exprs: ExprId => Expr<'tcx>,
- stmts: StmtId => Stmt<'tcx>,
+ arms: ArmId => Arm<'tcx> => "a{}",
+ blocks: BlockId => Block => "b{}",
+ exprs: ExprId => Expr<'tcx> => "e{}",
+ stmts: StmtId => Stmt<'tcx> => "s{}",
+ params: ParamId => Param<'tcx> => "p{}",
+}
+
+/// Description of a type-checked function parameter.
+#[derive(Clone, Debug, HashStable)]
+pub struct Param<'tcx> {
+ /// The pattern that appears in the parameter list, or None for implicit parameters.
+ pub pat: Option<Box<Pat<'tcx>>>,
+ /// The possibly inferred type.
+ pub ty: Ty<'tcx>,
+ /// Span of the explicitly provided type, or None if inferred for closures.
+ pub ty_span: Option<Span>,
+ /// Whether this param is `self`, and how it is bound.
+ pub self_kind: Option<hir::ImplicitSelfKind>,
+ /// HirId for lints.
+ pub hir_id: Option<hir::HirId>,
}
#[derive(Copy, Clone, Debug, HashStable)]
@@ -121,8 +123,10 @@ pub struct Block {
pub safety_mode: BlockSafety,
}
+type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
+
#[derive(Clone, Debug, HashStable)]
-pub struct Adt<'tcx> {
+pub struct AdtExpr<'tcx> {
/// The ADT we're constructing.
pub adt_def: AdtDef<'tcx>,
/// The variant of the ADT.
@@ -131,13 +135,30 @@ pub struct Adt<'tcx> {
/// Optional user-given substs: for something like `let x =
/// Bar::<T> { ... }`.
- pub user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
+ pub user_ty: UserTy<'tcx>,
pub fields: Box<[FieldExpr]>,
/// The base, e.g. `Foo {x: 1, .. base}`.
pub base: Option<FruInfo<'tcx>>,
}
+#[derive(Clone, Debug, HashStable)]
+pub struct ClosureExpr<'tcx> {
+ pub closure_id: LocalDefId,
+ pub substs: UpvarSubsts<'tcx>,
+ pub upvars: Box<[ExprId]>,
+ pub movability: Option<hir::Movability>,
+ pub fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>,
+}
+
+#[derive(Clone, Debug, HashStable)]
+pub struct InlineAsmExpr<'tcx> {
+ pub template: &'tcx [InlineAsmTemplatePiece],
+ pub operands: Box<[InlineAsmOperand<'tcx>]>,
+ pub options: InlineAsmOptions,
+ pub line_spans: &'tcx [Span],
+}
+
#[derive(Copy, Clone, Debug, HashStable)]
pub enum BlockSafety {
Safe,
@@ -177,13 +198,13 @@ pub enum StmtKind<'tcx> {
/// `let <PAT> = ...`
///
/// If a type annotation is included, it is added as an ascription pattern.
- pattern: Pat<'tcx>,
+ pattern: Box<Pat<'tcx>>,
/// `let pat: ty = <INIT>`
initializer: Option<ExprId>,
/// `let pat: ty = <INIT> else { <ELSE> }
- else_block: Option<Block>,
+ else_block: Option<BlockId>,
/// The lint level for this `let` statement.
lint_level: LintLevel,
@@ -298,7 +319,7 @@ pub enum ExprKind<'tcx> {
},
Let {
expr: ExprId,
- pat: Pat<'tcx>,
+ pat: Box<Pat<'tcx>>,
},
/// A `match` expression.
Match {
@@ -307,7 +328,7 @@ pub enum ExprKind<'tcx> {
},
/// A block.
Block {
- body: Block,
+ block: BlockId,
},
/// An assignment: `lhs = rhs`.
Assign {
@@ -387,27 +408,21 @@ pub enum ExprKind<'tcx> {
fields: Box<[ExprId]>,
},
/// An ADT constructor, e.g. `Foo {x: 1, y: 2}`.
- Adt(Box<Adt<'tcx>>),
+ Adt(Box<AdtExpr<'tcx>>),
/// A type ascription on a place.
PlaceTypeAscription {
source: ExprId,
/// Type that the user gave to this expression
- user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
+ user_ty: UserTy<'tcx>,
},
/// A type ascription on a value, e.g. `42: i32`.
ValueTypeAscription {
source: ExprId,
/// Type that the user gave to this expression
- user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
+ user_ty: UserTy<'tcx>,
},
/// A closure definition.
- Closure {
- closure_id: LocalDefId,
- substs: UpvarSubsts<'tcx>,
- upvars: Box<[ExprId]>,
- movability: Option<hir::Movability>,
- fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>,
- },
+ Closure(Box<ClosureExpr<'tcx>>),
/// A literal.
Literal {
lit: &'tcx hir::Lit,
@@ -416,17 +431,17 @@ pub enum ExprKind<'tcx> {
/// For literals that don't correspond to anything in the HIR
NonHirLiteral {
lit: ty::ScalarInt,
- user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
+ user_ty: UserTy<'tcx>,
},
/// A literal of a ZST type.
ZstLiteral {
- user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
+ user_ty: UserTy<'tcx>,
},
/// Associated constants and named constants
NamedConst {
def_id: DefId,
substs: SubstsRef<'tcx>,
- user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
+ user_ty: UserTy<'tcx>,
},
ConstParam {
param: ty::ParamConst,
@@ -443,12 +458,7 @@ pub enum ExprKind<'tcx> {
def_id: DefId,
},
/// Inline assembly, i.e. `asm!()`.
- InlineAsm {
- template: &'tcx [InlineAsmTemplatePiece],
- operands: Box<[InlineAsmOperand<'tcx>]>,
- options: InlineAsmOptions,
- line_spans: &'tcx [Span],
- },
+ InlineAsm(Box<InlineAsmExpr<'tcx>>),
/// An expression taking a reference to a thread local.
ThreadLocalRef(DefId),
/// A `yield` expression.
@@ -475,7 +485,7 @@ pub struct FruInfo<'tcx> {
/// A `match` arm.
#[derive(Clone, Debug, HashStable)]
pub struct Arm<'tcx> {
- pub pattern: Pat<'tcx>,
+ pub pattern: Box<Pat<'tcx>>,
pub guard: Option<Guard<'tcx>>,
pub body: ExprId,
pub lint_level: LintLevel,
@@ -487,7 +497,7 @@ pub struct Arm<'tcx> {
#[derive(Clone, Debug, HashStable)]
pub enum Guard<'tcx> {
If(ExprId),
- IfLet(Pat<'tcx>, ExprId),
+ IfLet(Box<Pat<'tcx>>, ExprId),
}
#[derive(Copy, Clone, Debug, HashStable)]
@@ -542,19 +552,28 @@ pub enum BindingMode {
#[derive(Clone, Debug, HashStable)]
pub struct FieldPat<'tcx> {
pub field: Field,
- pub pattern: Pat<'tcx>,
+ pub pattern: Box<Pat<'tcx>>,
}
#[derive(Clone, Debug, HashStable)]
pub struct Pat<'tcx> {
pub ty: Ty<'tcx>,
pub span: Span,
- pub kind: Box<PatKind<'tcx>>,
+ pub kind: PatKind<'tcx>,
}
impl<'tcx> Pat<'tcx> {
pub fn wildcard_from_ty(ty: Ty<'tcx>) -> Self {
- Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) }
+ Pat { ty, span: DUMMY_SP, kind: PatKind::Wild }
+ }
+
+ pub fn simple_ident(&self) -> Option<Symbol> {
+ match self.kind {
+ PatKind::Binding { name, mode: BindingMode::ByValue, subpattern: None, .. } => {
+ Some(name)
+ }
+ _ => None,
+ }
}
}
@@ -589,7 +608,7 @@ pub enum PatKind<'tcx> {
AscribeUserType {
ascription: Ascription<'tcx>,
- subpattern: Pat<'tcx>,
+ subpattern: Box<Pat<'tcx>>,
},
/// `x`, `ref x`, `x @ P`, etc.
@@ -599,7 +618,7 @@ pub enum PatKind<'tcx> {
mode: BindingMode,
var: LocalVarId,
ty: Ty<'tcx>,
- subpattern: Option<Pat<'tcx>>,
+ subpattern: Option<Box<Pat<'tcx>>>,
/// Is this the leftmost occurrence of the binding, i.e., is `var` the
/// `HirId` of this pattern?
is_primary: bool,
@@ -622,7 +641,7 @@ pub enum PatKind<'tcx> {
/// `box P`, `&P`, `&mut P`, etc.
Deref {
- subpattern: Pat<'tcx>,
+ subpattern: Box<Pat<'tcx>>,
},
/// One of the following:
@@ -636,32 +655,32 @@ pub enum PatKind<'tcx> {
value: mir::ConstantKind<'tcx>,
},
- Range(PatRange<'tcx>),
+ Range(Box<PatRange<'tcx>>),
/// Matches against a slice, checking the length and extracting elements.
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
/// e.g., `&[ref xs @ ..]`.
Slice {
- prefix: Vec<Pat<'tcx>>,
- slice: Option<Pat<'tcx>>,
- suffix: Vec<Pat<'tcx>>,
+ prefix: Box<[Box<Pat<'tcx>>]>,
+ slice: Option<Box<Pat<'tcx>>>,
+ suffix: Box<[Box<Pat<'tcx>>]>,
},
/// Fixed match against an array; irrefutable.
Array {
- prefix: Vec<Pat<'tcx>>,
- slice: Option<Pat<'tcx>>,
- suffix: Vec<Pat<'tcx>>,
+ prefix: Box<[Box<Pat<'tcx>>]>,
+ slice: Option<Box<Pat<'tcx>>>,
+ suffix: Box<[Box<Pat<'tcx>>]>,
},
/// An or-pattern, e.g. `p | q`.
/// Invariant: `pats.len() >= 2`.
Or {
- pats: Vec<Pat<'tcx>>,
+ pats: Box<[Box<Pat<'tcx>>]>,
},
}
-#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
+#[derive(Clone, Debug, PartialEq, HashStable)]
pub struct PatRange<'tcx> {
pub lo: mir::ConstantKind<'tcx>,
pub hi: mir::ConstantKind<'tcx>,
@@ -682,7 +701,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
};
let mut start_or_comma = || start_or_continue(", ");
- match *self.kind {
+ match self.kind {
PatKind::Wild => write!(f, "_"),
PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{}: _", subpattern),
PatKind::Binding { mutability, name, mode, ref subpattern, .. } => {
@@ -703,17 +722,32 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
Ok(())
}
PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
- let variant = match *self.kind {
- PatKind::Variant { adt_def, variant_index, .. } => {
- Some(adt_def.variant(variant_index))
- }
- _ => self.ty.ty_adt_def().and_then(|adt| {
- if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }
+ let variant_and_name = match self.kind {
+ PatKind::Variant { adt_def, variant_index, .. } => ty::tls::with(|tcx| {
+ let variant = adt_def.variant(variant_index);
+ let adt_did = adt_def.did();
+ let name = if tcx.get_diagnostic_item(sym::Option) == Some(adt_did)
+ || tcx.get_diagnostic_item(sym::Result) == Some(adt_did)
+ {
+ variant.name.to_string()
+ } else {
+ format!("{}::{}", tcx.def_path_str(adt_def.did()), variant.name)
+ };
+ Some((variant, name))
+ }),
+ _ => self.ty.ty_adt_def().and_then(|adt_def| {
+ if !adt_def.is_enum() {
+ ty::tls::with(|tcx| {
+ Some((adt_def.non_enum_variant(), tcx.def_path_str(adt_def.did())))
+ })
+ } else {
+ None
+ }
}),
};
- if let Some(variant) = variant {
- write!(f, "{}", variant.name)?;
+ if let Some((variant, name)) = &variant_and_name {
+ write!(f, "{}", name)?;
// Only for Adt we can have `S {...}`,
// which we handle separately here.
@@ -722,7 +756,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
let mut printed = 0;
for p in subpatterns {
- if let PatKind::Wild = *p.pattern.kind {
+ if let PatKind::Wild = p.pattern.kind {
continue;
}
let name = variant.fields[p.field.index()].name;
@@ -738,8 +772,9 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
}
}
- let num_fields = variant.map_or(subpatterns.len(), |v| v.fields.len());
- if num_fields != 0 || variant.is_none() {
+ let num_fields =
+ variant_and_name.as_ref().map_or(subpatterns.len(), |(v, _)| v.fields.len());
+ if num_fields != 0 || variant_and_name.is_none() {
write!(f, "(")?;
for i in 0..num_fields {
write!(f, "{}", start_or_comma())?;
@@ -775,7 +810,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
write!(f, "{}", subpattern)
}
PatKind::Constant { value } => write!(f, "{}", value),
- PatKind::Range(PatRange { lo, hi, end }) => {
+ PatKind::Range(box PatRange { lo, hi, end }) => {
write!(f, "{}", lo)?;
write!(f, "{}", end)?;
write!(f, "{}", hi)
@@ -783,24 +818,24 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
PatKind::Slice { ref prefix, ref slice, ref suffix }
| PatKind::Array { ref prefix, ref slice, ref suffix } => {
write!(f, "[")?;
- for p in prefix {
+ for p in prefix.iter() {
write!(f, "{}{}", start_or_comma(), p)?;
}
if let Some(ref slice) = *slice {
write!(f, "{}", start_or_comma())?;
- match *slice.kind {
+ match slice.kind {
PatKind::Wild => {}
_ => write!(f, "{}", slice)?,
}
write!(f, "..")?;
}
- for p in suffix {
+ for p in suffix.iter() {
write!(f, "{}{}", start_or_comma(), p)?;
}
write!(f, "]")
}
PatKind::Or { ref pats } => {
- for pat in pats {
+ for pat in pats.iter() {
write!(f, "{}{}", start_or_continue(" | "), pat)?;
}
Ok(())
@@ -814,8 +849,15 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
mod size_asserts {
use super::*;
// These are in alphabetical order, which is easy to maintain.
- rustc_data_structures::static_assert_size!(Block, 56);
- rustc_data_structures::static_assert_size!(Expr<'_>, 104);
- rustc_data_structures::static_assert_size!(Pat<'_>, 24);
- rustc_data_structures::static_assert_size!(Stmt<'_>, 120);
+ static_assert_size!(Block, 56);
+ static_assert_size!(Expr<'_>, 64);
+ static_assert_size!(ExprKind<'_>, 40);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(Pat<'_>, 72);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(PatKind<'_>, 56);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(Stmt<'_>, 48);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(StmtKind<'_>, 40);
}
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 97249fdd1..79a0e75aa 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -1,5 +1,6 @@
use super::{
- Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir,
+ AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, Guard, InlineAsmExpr, InlineAsmOperand, Pat,
+ PatKind, Stmt, StmtKind, Thir,
};
pub trait Visitor<'a, 'tcx: 'a>: Sized {
@@ -75,7 +76,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor.visit_arm(&visitor.thir()[arm]);
}
}
- Block { ref body } => visitor.visit_block(body),
+ Block { block } => visitor.visit_block(&visitor.thir()[block]),
Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
visitor.visit_expr(&visitor.thir()[lhs]);
visitor.visit_expr(&visitor.thir()[rhs]);
@@ -108,7 +109,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor.visit_expr(&visitor.thir()[field]);
}
}
- Adt(box crate::thir::Adt {
+ Adt(box AdtExpr {
ref fields,
ref base,
adt_def: _,
@@ -126,14 +127,20 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
visitor.visit_expr(&visitor.thir()[source])
}
- Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
+ Closure(box ClosureExpr {
+ closure_id: _,
+ substs: _,
+ upvars: _,
+ movability: _,
+ fake_reads: _,
+ }) => {}
Literal { lit: _, neg: _ } => {}
NonHirLiteral { lit: _, user_ty: _ } => {}
ZstLiteral { user_ty: _ } => {}
NamedConst { def_id: _, substs: _, user_ty: _ } => {}
ConstParam { param: _, def_id: _ } => {}
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
- InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
+ InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
for op in &**operands {
use InlineAsmOperand::*;
match op {
@@ -174,7 +181,7 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm
}
visitor.visit_pat(pattern);
if let Some(block) = else_block {
- visitor.visit_block(block)
+ visitor.visit_block(&visitor.thir()[*block])
}
}
}
@@ -204,7 +211,7 @@ pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'
pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) {
use PatKind::*;
- match pat.kind.as_ref() {
+ match &pat.kind {
AscribeUserType { subpattern, ascription: _ }
| Deref { subpattern }
| Binding {
@@ -225,18 +232,18 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
Constant { value: _ } => {}
Range(_) => {}
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
- for subpattern in prefix {
+ for subpattern in prefix.iter() {
visitor.visit_pat(&subpattern);
}
if let Some(pat) = slice {
- visitor.visit_pat(pat);
+ visitor.visit_pat(&pat);
}
- for subpattern in suffix {
+ for subpattern in suffix.iter() {
visitor.visit_pat(&subpattern);
}
}
Or { pats } => {
- for pat in pats {
+ for pat in pats.iter() {
visitor.visit_pat(&pat);
}
}
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 72b848c3e..68a7af0b8 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -10,9 +10,10 @@ mod structural_impls;
pub mod util;
use crate::infer::canonical::Canonical;
+use crate::mir::ConstraintCategory;
use crate::ty::abstract_const::NotConstEvaluatable;
use crate::ty::subst::SubstsRef;
-use crate::ty::{self, AdtKind, Predicate, Ty, TyCtxt};
+use crate::ty::{self, AdtKind, Ty, TyCtxt};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, Diagnostic};
@@ -183,6 +184,16 @@ impl<'tcx> ObligationCause<'tcx> {
variant(DerivedObligationCause { parent_trait_pred, parent_code: self.code }).into();
self
}
+
+ pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
+ match self.code() {
+ MatchImpl(cause, _) => cause.to_constraint_category(),
+ AscribeUserTypeProvePredicate(predicate_span) => {
+ ConstraintCategory::Predicate(*predicate_span)
+ }
+ _ => ConstraintCategory::BoringNoLocation,
+ }
+ }
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
@@ -234,13 +245,23 @@ pub enum ObligationCauseCode<'tcx> {
/// This is the trait reference from the given projection.
ProjectionWf(ty::ProjectionTy<'tcx>),
- /// In an impl of trait `X` for type `Y`, type `Y` must
- /// also implement all supertraits of `X`.
+ /// Must satisfy all of the where-clause predicates of the
+ /// given item.
ItemObligation(DefId),
- /// Like `ItemObligation`, but with extra detail on the source of the obligation.
+ /// Like `ItemObligation`, but carries the span of the
+ /// predicate when it can be identified.
BindingObligation(DefId, Span),
+ /// Like `ItemObligation`, but carries the `HirId` of the
+ /// expression that caused the obligation, and the `usize`
+ /// indicates exactly which predicate it is in the list of
+ /// instantiated predicates.
+ ExprItemObligation(DefId, rustc_hir::HirId, usize),
+
+ /// Combines `ExprItemObligation` and `BindingObligation`.
+ ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize),
+
/// A type like `&'a T` is WF only if `T: 'a`.
ReferenceOutlivesReferent(Ty<'tcx>),
@@ -406,8 +427,10 @@ pub enum ObligationCauseCode<'tcx> {
BinOp {
rhs_span: Option<Span>,
is_lit: bool,
- output_pred: Option<Predicate<'tcx>>,
+ output_ty: Option<Ty<'tcx>>,
},
+
+ AscribeUserTypeProvePredicate(Span),
}
/// The 'location' at which we try to perform HIR-based wf checking.
@@ -459,6 +482,13 @@ impl<'tcx> ObligationCauseCode<'tcx> {
_ => None,
}
}
+
+ pub fn peel_match_impls(&self) -> &Self {
+ match self {
+ MatchImpl(cause, _) => cause.code(),
+ _ => self,
+ }
+ }
}
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -634,6 +664,10 @@ pub enum ImplSource<'tcx, N> {
/// ImplSource for a `const Drop` implementation.
ConstDestruct(ImplSourceConstDestructData<N>),
+
+ /// ImplSource for a `std::marker::Tuple` implementation.
+ /// This has no nested predicates ever, so no data.
+ Tuple,
}
impl<'tcx, N> ImplSource<'tcx, N> {
@@ -648,7 +682,8 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::Object(d) => d.nested,
ImplSource::FnPointer(d) => d.nested,
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
- | ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
+ | ImplSource::Pointee(ImplSourcePointeeData)
+ | ImplSource::Tuple => Vec::new(),
ImplSource::TraitAlias(d) => d.nested,
ImplSource::TraitUpcasting(d) => d.nested,
ImplSource::ConstDestruct(i) => i.nested,
@@ -666,7 +701,8 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::Object(d) => &d.nested,
ImplSource::FnPointer(d) => &d.nested,
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
- | ImplSource::Pointee(ImplSourcePointeeData) => &[],
+ | ImplSource::Pointee(ImplSourcePointeeData)
+ | ImplSource::Tuple => &[],
ImplSource::TraitAlias(d) => &d.nested,
ImplSource::TraitUpcasting(d) => &d.nested,
ImplSource::ConstDestruct(i) => &i.nested,
@@ -733,6 +769,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
nested: i.nested.into_iter().map(f).collect(),
})
}
+ ImplSource::Tuple => ImplSource::Tuple,
}
}
}
@@ -893,6 +930,12 @@ impl ObjectSafetyViolation {
}
ObjectSafetyViolation::Method(
name,
+ MethodViolationCode::ReferencesImplTraitInTrait,
+ _,
+ ) => format!("method `{}` references an `impl Trait` type in its return type", name)
+ .into(),
+ ObjectSafetyViolation::Method(
+ name,
MethodViolationCode::WhereClauseReferencesSelf,
_,
) => {
@@ -997,6 +1040,9 @@ pub enum MethodViolationCode {
/// e.g., `fn foo(&self) -> Self`
ReferencesSelfOutput,
+ /// e.g., `fn foo(&self) -> impl Sized`
+ ReferencesImplTraitInTrait,
+
/// e.g., `fn foo(&self) where Self: Clone`
WhereClauseReferencesSelf,
@@ -1007,7 +1053,7 @@ pub enum MethodViolationCode {
UndispatchableReceiver(Option<Span>),
}
-/// These are the error cases for `codegen_fulfill_obligation`.
+/// These are the error cases for `codegen_select_candidate`.
#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
pub enum CodegenObligationError {
/// Ambiguity can happen when monomorphizing during trans
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 1f9b474ad..0e6cacb9f 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -5,11 +5,11 @@
//! The providers for the queries defined here can be found in
//! `rustc_traits`.
+use crate::error::DropCheckOverflow;
use crate::infer::canonical::{Canonical, QueryResponse};
use crate::ty::error::TypeError;
use crate::ty::subst::GenericArg;
use crate::ty::{self, Ty, TyCtxt};
-use rustc_errors::struct_span_err;
use rustc_span::source_map::Span;
use std::iter::FromIterator;
@@ -117,15 +117,7 @@ pub struct DropckOutlivesResult<'tcx> {
impl<'tcx> DropckOutlivesResult<'tcx> {
pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
if let Some(overflow_ty) = self.overflows.get(0) {
- let mut err = struct_span_err!(
- tcx.sess,
- span,
- E0320,
- "overflow while adding drop-check rules for {}",
- ty,
- );
- err.note(&format!("overflowed on {}", overflow_ty));
- err.emit();
+ tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty });
}
}
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index e836ba47e..53af3e905 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -160,6 +160,9 @@ pub enum SelectionCandidate<'tcx> {
/// Implementation of `const Destruct`, optionally from a custom `impl const Drop`.
ConstDestructCandidate(Option<DefId>),
+
+ /// Witnesses the fact that a type is a tuple.
+ TupleCandidate,
}
/// The result of trait evaluation. The order is important
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 2465f8e25..0a2819fee 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -115,7 +115,7 @@ impl Node {
matches!(self, Node::Trait(..))
}
- /// Trys to find the associated item that implements `trait_item_def_id`
+ /// Tries to find the associated item that implements `trait_item_def_id`
/// defined in this node.
///
/// If this returns `None`, the item can potentially still be found in
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 7fbd57ac7..c526344e1 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -34,6 +34,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
super::ImplSource::ConstDestruct(ref d) => write!(f, "{:?}", d),
+
+ super::ImplSource::Tuple => write!(f, "ImplSource::Tuple"),
}
}
}
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index bed809930..8f79b4705 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -42,7 +42,7 @@ impl<'tcx> AbstractConst<'tcx> {
ct: ty::Const<'tcx>,
) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
match ct.kind() {
- ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()),
+ ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv),
ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported),
_ => Ok(None),
}
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index d36cf2fe3..b809f1767 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -77,7 +77,7 @@ pub enum PointerCast {
/// At some point, of course, `Box` should move out of the compiler, in which
/// case this is analogous to transforming a struct. E.g., `Box<[i32; 4]>` ->
/// `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`.
-#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct Adjustment<'tcx> {
pub kind: Adjust<'tcx>,
pub target: Ty<'tcx>,
@@ -89,7 +89,7 @@ impl<'tcx> Adjustment<'tcx> {
}
}
-#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum Adjust<'tcx> {
/// Go from ! to any type.
NeverToAny,
@@ -108,7 +108,7 @@ pub enum Adjust<'tcx> {
/// The target type is `U` in both cases, with the region and mutability
/// being those shared by both the receiver and the returned reference.
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
-#[derive(TypeFoldable, TypeVisitable)]
+#[derive(TypeFoldable, TypeVisitable, Lift)]
pub struct OverloadedDeref<'tcx> {
pub region: ty::Region<'tcx>,
pub mutbl: hir::Mutability,
@@ -167,7 +167,7 @@ impl From<AutoBorrowMutability> for hir::Mutability {
}
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
-#[derive(TypeFoldable, TypeVisitable)]
+#[derive(TypeFoldable, TypeVisitable, Lift)]
pub enum AutoBorrow<'tcx> {
/// Converts from T to &T.
Ref(ty::Region<'tcx>, AutoBorrowMutability),
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index c97156ac1..55ee5bd2f 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -42,7 +42,7 @@ impl AssocItem {
}
#[inline]
- pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility {
+ pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility<DefId> {
tcx.visibility(self.def_id)
}
diff --git a/compiler/rustc_middle/src/ty/binding.rs b/compiler/rustc_middle/src/ty/binding.rs
index 3d65429f2..a5b05a4f9 100644
--- a/compiler/rustc_middle/src/ty/binding.rs
+++ b/compiler/rustc_middle/src/ty/binding.rs
@@ -1,6 +1,4 @@
-use rustc_hir::BindingAnnotation;
-use rustc_hir::BindingAnnotation::*;
-use rustc_hir::Mutability;
+use rustc_hir::{BindingAnnotation, ByRef, Mutability};
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Debug, Copy, HashStable)]
pub enum BindingMode {
@@ -11,12 +9,10 @@ pub enum BindingMode {
TrivialTypeTraversalAndLiftImpls! { BindingMode, }
impl BindingMode {
- pub fn convert(ba: BindingAnnotation) -> BindingMode {
- match ba {
- Unannotated => BindingMode::BindByValue(Mutability::Not),
- Mutable => BindingMode::BindByValue(Mutability::Mut),
- Ref => BindingMode::BindByReference(Mutability::Not),
- RefMut => BindingMode::BindByReference(Mutability::Mut),
+ pub fn convert(BindingAnnotation(by_ref, mutbl): BindingAnnotation) -> BindingMode {
+ match by_ref {
+ ByRef::No => BindingMode::BindByValue(mutbl),
+ ByRef::Yes => BindingMode::BindByReference(mutbl),
}
}
}
diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs
index c4b743dd4..981e2d3b6 100644
--- a/compiler/rustc_middle/src/ty/cast.rs
+++ b/compiler/rustc_middle/src/ty/cast.rs
@@ -33,6 +33,8 @@ pub enum CastTy<'tcx> {
FnPtr,
/// Raw pointers.
Ptr(ty::TypeAndMut<'tcx>),
+ /// Casting into a `dyn*` value.
+ DynStar,
}
/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html)
@@ -50,6 +52,7 @@ pub enum CastKind {
ArrayPtrCast,
FnPtrPtrCast,
FnPtrAddrCast,
+ DynStarCast,
}
impl<'tcx> CastTy<'tcx> {
@@ -67,6 +70,7 @@ impl<'tcx> CastTy<'tcx> {
ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
ty::RawPtr(mt) => Some(CastTy::Ptr(mt)),
ty::FnPtr(..) => Some(CastTy::FnPtr),
+ ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar),
_ => None,
}
}
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index f8792edc0..339ff4d35 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -41,7 +41,7 @@ pub struct ConstS<'tcx> {
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(ConstS<'_>, 48);
+static_assert_size!(ConstS<'_>, 40);
impl<'tcx> Const<'tcx> {
#[inline]
@@ -65,8 +65,6 @@ impl<'tcx> Const<'tcx> {
tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
) -> Self {
- debug!("Const::from_anon_const(def={:?})", def);
-
let body_id = match tcx.hir().get_by_def_id(def.did) {
hir::Node::AnonConst(ac) => ac.body,
_ => span_bug!(
@@ -86,7 +84,7 @@ impl<'tcx> Const<'tcx> {
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
- promoted: None,
+ promoted: (),
}),
ty,
}),
@@ -183,7 +181,7 @@ impl<'tcx> Const<'tcx> {
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id).to_global(),
substs,
- promoted: None,
+ promoted: (),
}),
ty,
})
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index cb0137d2e..455015280 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -11,6 +11,7 @@ use rustc_macros::HashStable;
use rustc_target::abi::Size;
use super::ScalarInt;
+
/// An unevaluated, potentially generic, constant.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
#[derive(Hash, HashStable)]
@@ -20,6 +21,12 @@ pub struct Unevaluated<'tcx, P = Option<Promoted>> {
pub promoted: P,
}
+impl rustc_errors::IntoDiagnosticArg for Unevaluated<'_> {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ format!("{:?}", self).into_diagnostic_arg()
+ }
+}
+
impl<'tcx> Unevaluated<'tcx> {
#[inline]
pub fn shrink(self) -> Unevaluated<'tcx, ()> {
@@ -44,7 +51,7 @@ impl<'tcx, P: Default> Unevaluated<'tcx, P> {
/// Represents a constant in Rust.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
-#[derive(Hash, HashStable)]
+#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum ConstKind<'tcx> {
/// A const generic parameter.
Param(ty::ParamConst),
@@ -60,7 +67,7 @@ pub enum ConstKind<'tcx> {
/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
/// variants when the code is monomorphic enough for that.
- Unevaluated(Unevaluated<'tcx>),
+ Unevaluated(Unevaluated<'tcx, ()>),
/// Used to hold computed value.
Value(ty::ValTree<'tcx>),
@@ -71,7 +78,7 @@ pub enum ConstKind<'tcx> {
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(ConstKind<'_>, 40);
+static_assert_size!(ConstKind<'_>, 32);
impl<'tcx> ConstKind<'tcx> {
#[inline]
@@ -174,9 +181,12 @@ impl<'tcx> ConstKind<'tcx> {
param_env: ParamEnv<'tcx>,
eval_mode: EvalMode,
) -> Option<Result<EvalResult<'tcx>, ErrorGuaranteed>> {
+ assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
if let ConstKind::Unevaluated(unevaluated) = self {
use crate::mir::interpret::ErrorHandled;
+ assert_eq!(unevaluated.promoted, ());
+
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
// also does later, but we want to do it before checking for
// inference variables.
@@ -197,7 +207,7 @@ impl<'tcx> ConstKind<'tcx> {
tcx.param_env(unevaluated.def.did).and(ty::Unevaluated {
def: unevaluated.def,
substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did),
- promoted: unevaluated.promoted,
+ promoted: (),
})
} else {
param_env_and
@@ -221,7 +231,7 @@ impl<'tcx> ConstKind<'tcx> {
}
}
EvalMode::Mir => {
- match tcx.const_eval_resolve(param_env, unevaluated, None) {
+ match tcx.const_eval_resolve(param_env, unevaluated.expand(), None) {
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
// and we use the original type, so nothing from `substs`
// (which may be identity substs, see above),
diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs
index 93707bb18..a803fca0d 100644
--- a/compiler/rustc_middle/src/ty/consts/valtree.rs
+++ b/compiler/rustc_middle/src/ty/consts/valtree.rs
@@ -18,7 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
/// `ValTree` does not have this problem with representation, as it only contains integers or
/// lists of (nested) `ValTree`.
pub enum ValTree<'tcx> {
- /// ZSTs, integers, `bool`, `char` are represented as scalars.
+ /// integers, `bool`, `char` are represented as scalars.
/// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values
/// of these types have the same representation.
Leaf(ScalarInt),
@@ -27,8 +27,11 @@ pub enum ValTree<'tcx> {
// dont use SliceOrStr for now
/// The fields of any kind of aggregate. Structs, tuples and arrays are represented by
/// listing their fields' values in order.
+ ///
/// Enums are represented by storing their discriminant as a field, followed by all
/// the fields of the variant.
+ ///
+ /// ZST types are represented as an empty slice.
Branch(&'tcx [ValTree<'tcx>]),
}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 0a0f45ce1..0b497fa4a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -22,6 +22,7 @@ use crate::ty::{
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
+ Visibility,
};
use rustc_ast as ast;
use rustc_data_structures::fingerprint::Fingerprint;
@@ -62,7 +63,7 @@ use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
use rustc_type_ir::sty::TyKind::*;
-use rustc_type_ir::{InternAs, InternIteratorElement, Interner, TypeFlags};
+use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags};
use std::any::Any;
use std::borrow::Borrow;
@@ -275,9 +276,6 @@ pub struct CommonTypes<'tcx> {
}
pub struct CommonLifetimes<'tcx> {
- /// `ReEmpty` in the root universe.
- pub re_root_empty: Region<'tcx>,
-
/// `ReStatic`
pub re_static: Region<'tcx>,
@@ -874,7 +872,7 @@ pub type CanonicalUserTypeAnnotations<'tcx> =
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct CanonicalUserTypeAnnotation<'tcx> {
- pub user_ty: CanonicalUserType<'tcx>,
+ pub user_ty: Box<CanonicalUserType<'tcx>>,
pub span: Span,
pub inferred_ty: Ty<'tcx>,
}
@@ -986,11 +984,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
))
};
- CommonLifetimes {
- re_root_empty: mk(ty::ReEmpty(ty::UniverseIndex::ROOT)),
- re_static: mk(ty::ReStatic),
- re_erased: mk(ty::ReErased),
- }
+ CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) }
}
}
@@ -1089,7 +1083,7 @@ pub struct GlobalCtxt<'tcx> {
pub queries: &'tcx dyn query::QueryEngine<'tcx>,
pub query_caches: query::QueryCaches<'tcx>,
- query_kinds: &'tcx [DepKindStruct],
+ query_kinds: &'tcx [DepKindStruct<'tcx>],
// Internal caches for metadata decoding. No need to track deps on this.
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
@@ -1246,12 +1240,12 @@ impl<'tcx> TyCtxt<'tcx> {
dep_graph: DepGraph,
on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
queries: &'tcx dyn query::QueryEngine<'tcx>,
- query_kinds: &'tcx [DepKindStruct],
+ query_kinds: &'tcx [DepKindStruct<'tcx>],
crate_name: &str,
output_filenames: OutputFilenames,
) -> GlobalCtxt<'tcx> {
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
- s.fatal(&err);
+ s.emit_fatal(err);
});
let interners = CtxtInterners::new(arena);
let common_types = CommonTypes::new(
@@ -1296,7 +1290,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct {
+ pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct<'tcx> {
&self.query_kinds[k as usize]
}
@@ -1498,17 +1492,17 @@ impl<'tcx> TyCtxt<'tcx> {
// Create a dependency to the crate to be sure we re-execute this when the amount of
// definitions change.
self.ensure().hir_crate(());
- // Leak a read lock once we start iterating on definitions, to prevent adding new onces
+ // Leak a read lock once we start iterating on definitions, to prevent adding new ones
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
let definitions = self.definitions.leak();
definitions.iter_local_def_id()
}
pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
- // Create a dependency to the crate to be sure we reexcute this when the amount of
+ // Create a dependency to the crate to be sure we re-execute this when the amount of
// definitions change.
self.ensure().hir_crate(());
- // Leak a read lock once we start iterating on definitions, to prevent adding new onces
+ // Leak a read lock once we start iterating on definitions, to prevent adding new ones
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
let definitions = self.definitions.leak();
definitions.def_path_table()
@@ -1517,10 +1511,10 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn def_path_hash_to_def_index_map(
self,
) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
- // Create a dependency to the crate to be sure we reexcute this when the amount of
+ // Create a dependency to the crate to be sure we re-execute this when the amount of
// definitions change.
self.ensure().hir_crate(());
- // Leak a read lock once we start iterating on definitions, to prevent adding new onces
+ // Leak a read lock once we start iterating on definitions, to prevent adding new ones
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
let definitions = self.definitions.leak();
definitions.def_path_hash_to_def_index_map()
@@ -1596,7 +1590,7 @@ impl<'tcx> TyCtxt<'tcx> {
})
}
- // Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
+ /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = match *region {
ty::ReFree(ref free_region) => {
@@ -1728,6 +1722,11 @@ impl<'tcx> TyCtxt<'tcx> {
.chain(self.crates(()).iter().copied())
.flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
}
+
+ #[inline]
+ pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
+ self.visibility(def_id.to_def_id()).expect_local()
+ }
}
/// A trait implemented for all `X<'a>` types that can be safely and
@@ -1821,7 +1820,9 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable
// This is the impl for `&'a InternalSubsts<'a>`.
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
-CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
+CloneLiftImpls! { for<'tcx> {
+ Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
+} }
pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};
@@ -1829,9 +1830,9 @@ pub mod tls {
use crate::dep_graph::TaskDepsRef;
use crate::ty::query;
use rustc_data_structures::sync::{self, Lock};
- use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::Diagnostic;
use std::mem;
+ use thin_vec::ThinVec;
#[cfg(not(parallel_compiler))]
use std::cell::Cell;
@@ -1857,8 +1858,8 @@ pub mod tls {
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
- /// Used to prevent layout from recursing too deeply.
- pub layout_depth: usize,
+ /// Used to prevent queries from calling too deeply.
+ pub query_depth: usize,
/// The current dep graph task. This is used to add dependencies to queries
/// when executing them.
@@ -1872,7 +1873,7 @@ pub mod tls {
tcx,
query: None,
diagnostics: None,
- layout_depth: 0,
+ query_depth: 0,
task_deps: TaskDepsRef::Ignore,
}
}
@@ -2546,8 +2547,9 @@ impl<'tcx> TyCtxt<'tcx> {
self,
obj: &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
reg: ty::Region<'tcx>,
+ repr: DynKind,
) -> Ty<'tcx> {
- self.mk_ty(Dynamic(obj, reg))
+ self.mk_ty(Dynamic(obj, reg, repr))
}
#[inline]
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index dd2f43210..855917fb8 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -102,13 +102,25 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
generics: &hir::Generics<'_>,
err: &mut Diagnostic,
trait_pred: PolyTraitPredicate<'tcx>,
+ associated_ty: Option<(&'static str, Ty<'tcx>)>,
) -> bool {
if !trait_pred.is_suggestable(tcx, false) {
return false;
}
let param_name = trait_pred.skip_binder().self_ty().to_string();
- let constraint = trait_pred.print_modifiers_and_trait_path().to_string();
+ let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string();
+
+ if let Some((name, term)) = associated_ty {
+ // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
+ // That should be extracted into a helper function.
+ if constraint.ends_with('>') {
+ constraint = format!("{}, {} = {}>", &constraint[..constraint.len() - 1], name, term);
+ } else {
+ constraint.push_str(&format!("<{} = {}>", name, term));
+ }
+ }
+
let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
// Skip, there is a param named Self
@@ -396,7 +408,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
) => {
self.0.push(ty);
}
- hir::TyKind::OpaqueDef(item_id, _) => {
+ hir::TyKind::OpaqueDef(item_id, _, _) => {
self.0.push(ty);
let item = self.1.item(item_id);
hir::intravisit::walk_item(self, item);
@@ -455,7 +467,7 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
}
}
- Dynamic(dty, _) => {
+ Dynamic(dty, _, _) => {
for pred in *dty {
match pred.skip_binder() {
ExistentialPredicate::Trait(_) | ExistentialPredicate::Projection(_) => {
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 4b0bc3c11..01e1e97b2 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -2,6 +2,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty::diagnostics::suggest_constraining_type_param;
use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt};
+use hir::def::DefKind;
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
use rustc_errors::{pluralize, Diagnostic, MultiSpan};
use rustc_hir as hir;
@@ -13,7 +14,7 @@ use rustc_target::spec::abi;
use std::borrow::Cow;
use std::fmt;
-#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)]
pub struct ExpectedFound<T> {
pub expected: T,
pub found: T,
@@ -30,7 +31,8 @@ impl<T> ExpectedFound<T> {
}
// Data structures used in type unification
-#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
+#[rustc_pass_by_value]
pub enum TypeError<'tcx> {
Mismatch,
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
@@ -73,6 +75,18 @@ pub enum TypeError<'tcx> {
TargetFeatureCast(DefId),
}
+impl TypeError<'_> {
+ pub fn involves_regions(self) -> bool {
+ match self {
+ TypeError::RegionsDoesNotOutlive(_, _)
+ | TypeError::RegionsInsufficientlyPolymorphic(_, _)
+ | TypeError::RegionsOverlyPolymorphic(_, _)
+ | TypeError::RegionsPlaceholderMismatch => true,
+ _ => false,
+ }
+ }
+}
+
/// Explains the source of a type err in a short, human readable way. This is meant to be placed
/// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
/// afterwards to present additional details, particularly when it comes to lifetime-related
@@ -211,7 +225,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
}
impl<'tcx> TypeError<'tcx> {
- pub fn must_include_note(&self) -> bool {
+ pub fn must_include_note(self) -> bool {
use self::TypeError::*;
match self {
CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_)
@@ -263,10 +277,23 @@ impl<'tcx> Ty<'tcx> {
}
ty::Slice(ty) if ty.is_simple_ty() => format!("slice `{}`", self).into(),
ty::Slice(_) => "slice".into(),
- ty::RawPtr(_) => "*-ptr".into(),
+ ty::RawPtr(tymut) => {
+ let tymut_string = match tymut.mutbl {
+ hir::Mutability::Mut => tymut.to_string(),
+ hir::Mutability::Not => format!("const {}", tymut.ty),
+ };
+
+ if tymut_string != "_" && (tymut.ty.is_simple_text() || tymut_string.len() < "const raw pointer".len()) {
+ format!("`*{}`", tymut_string).into()
+ } else {
+ // Unknown type name, it's long or has type arguments
+ "raw pointer".into()
+ }
+ },
ty::Ref(_, ty, mutbl) => {
let tymut = ty::TypeAndMut { ty, mutbl };
let tymut_string = tymut.to_string();
+
if tymut_string != "_"
&& (ty.is_simple_text() || tymut_string.len() < "mutable reference".len())
{
@@ -347,7 +374,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn note_and_explain_type_err(
self,
diag: &mut Diagnostic,
- err: &TypeError<'tcx>,
+ err: TypeError<'tcx>,
cause: &ObligationCause<'tcx>,
sp: Span,
body_owner_def_id: DefId,
@@ -512,7 +539,7 @@ impl<T> Trait<T> for X {
diag.span_label(p_span, "this type parameter");
}
}
- (ty::Projection(proj_ty), _) => {
+ (ty::Projection(proj_ty), _) if self.def_kind(proj_ty.item_def_id) != DefKind::ImplTraitPlaceholder => {
self.expected_projection(
diag,
proj_ty,
@@ -521,7 +548,7 @@ impl<T> Trait<T> for X {
cause.code(),
);
}
- (_, ty::Projection(proj_ty)) => {
+ (_, ty::Projection(proj_ty)) if self.def_kind(proj_ty.item_def_id) != DefKind::ImplTraitPlaceholder => {
let msg = format!(
"consider constraining the associated type `{}` to `{}`",
values.found, values.expected,
@@ -568,7 +595,7 @@ impl<T> Trait<T> for X {
}
TargetFeatureCast(def_id) => {
let target_spans =
- self.get_attrs(*def_id, sym::target_feature).map(|attr| attr.span);
+ self.get_attrs(def_id, sym::target_feature).map(|attr| attr.span);
diag.note(
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
);
@@ -640,7 +667,7 @@ impl<T> Trait<T> for X {
self,
diag: &mut Diagnostic,
proj_ty: &ty::ProjectionTy<'tcx>,
- values: &ExpectedFound<Ty<'tcx>>,
+ values: ExpectedFound<Ty<'tcx>>,
body_owner_def_id: DefId,
cause_code: &ObligationCauseCode<'_>,
) {
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index ea6bb8a7a..98b8a7386 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -1,5 +1,5 @@
use crate::ty::subst::{GenericArg, GenericArgKind};
-use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
+use crate::ty::{self, InferConst, Ty, TypeFlags};
use std::slice;
#[derive(Debug)]
@@ -171,7 +171,7 @@ impl FlagComputation {
self.add_substs(substs);
}
- &ty::Dynamic(obj, r) => {
+ &ty::Dynamic(obj, r, _) => {
for predicate in obj.iter() {
self.bound_computation(predicate, |computation, predicate| match predicate {
ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs),
@@ -243,9 +243,9 @@ impl FlagComputation {
}
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
self.add_projection_ty(projection_ty);
- match term {
- Term::Ty(ty) => self.add_ty(ty),
- Term::Const(c) => self.add_const(c),
+ match term.unpack() {
+ ty::TermKind::Ty(ty) => self.add_ty(ty),
+ ty::TermKind::Const(c) => self.add_const(c),
}
}
ty::PredicateKind::WellFormed(arg) => {
@@ -320,9 +320,9 @@ impl FlagComputation {
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
self.add_substs(projection.substs);
- match projection.term {
- ty::Term::Ty(ty) => self.add_ty(ty),
- ty::Term::Const(ct) => self.add_const(ct),
+ match projection.term.unpack() {
+ ty::TermKind::Ty(ty) => self.add_ty(ty),
+ ty::TermKind::Const(ct) => self.add_const(ct),
}
}
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 5e96e278b..cac95e14a 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -302,6 +302,17 @@ impl<'tcx> TyCtxt<'tcx> {
{
value.fold_with(&mut RegionFolder::new(self, &mut f))
}
+
+ pub fn super_fold_regions<T>(
+ self,
+ value: T,
+ mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
+ ) -> T
+ where
+ T: TypeSuperFoldable<'tcx>,
+ {
+ value.super_fold_with(&mut RegionFolder::new(self, &mut f))
+ }
}
/// Folds over the substructure of a type, visiting its component
@@ -353,7 +364,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
t
}
- #[instrument(skip(self), level = "debug")]
+ #[instrument(skip(self), level = "debug", ret)]
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
@@ -377,17 +388,13 @@ pub trait BoundVarReplacerDelegate<'tcx> {
fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx>;
}
-pub struct FnMutDelegate<R, T, C> {
- pub regions: R,
- pub types: T,
- pub consts: C,
+pub struct FnMutDelegate<'a, 'tcx> {
+ pub regions: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
+ pub types: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
+ pub consts: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a),
}
-impl<'tcx, R, T, C> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<R, T, C>
-where
- R: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
- T: FnMut(ty::BoundTy) -> Ty<'tcx>,
- C: FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx>,
-{
+
+impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx> {
(self.regions)(br)
}
@@ -511,7 +518,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn replace_late_bound_regions_uncached<T, F>(
self,
value: Binder<'tcx, T>,
- replace_regions: F,
+ mut replace_regions: F,
) -> T
where
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
@@ -522,9 +529,9 @@ impl<'tcx> TyCtxt<'tcx> {
value
} else {
let delegate = FnMutDelegate {
- regions: replace_regions,
- types: |b| bug!("unexpected bound ty in binder: {b:?}"),
- consts: |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
+ regions: &mut replace_regions,
+ types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"),
+ consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
};
let mut replacer = BoundVarReplacer::new(self, delegate);
value.fold_with(&mut replacer)
@@ -584,19 +591,19 @@ impl<'tcx> TyCtxt<'tcx> {
self.replace_escaping_bound_vars_uncached(
value,
FnMutDelegate {
- regions: |r: ty::BoundRegion| {
+ regions: &mut |r: ty::BoundRegion| {
self.mk_region(ty::ReLateBound(
ty::INNERMOST,
ty::BoundRegion { var: shift_bv(r.var), kind: r.kind },
))
},
- types: |t: ty::BoundTy| {
+ types: &mut |t: ty::BoundTy| {
self.mk_ty(ty::Bound(
ty::INNERMOST,
ty::BoundTy { var: shift_bv(t.var), kind: t.kind },
))
},
- consts: |c, ty: Ty<'tcx>| {
+ consts: &mut |c, ty: Ty<'tcx>| {
self.mk_const(ty::ConstS {
kind: ty::ConstKind::Bound(ty::INNERMOST, shift_bv(c)),
ty,
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index add2df258..0c8bdde9c 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -1,4 +1,3 @@
-use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
use crate::ty;
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::EarlyBinder;
@@ -13,7 +12,7 @@ use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predi
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum GenericParamDefKind {
Lifetime,
- Type { has_default: bool, object_lifetime_default: ObjectLifetimeDefault, synthetic: bool },
+ Type { has_default: bool, synthetic: bool },
Const { has_default: bool },
}
@@ -28,8 +27,9 @@ impl GenericParamDefKind {
pub fn to_ord(&self) -> ast::ParamKindOrd {
match self {
GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime,
- GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type,
- GenericParamDefKind::Const { .. } => ast::ParamKindOrd::Const,
+ GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
+ ast::ParamKindOrd::TypeOrConst
+ }
}
}
@@ -122,6 +122,21 @@ pub struct Generics {
}
impl<'tcx> Generics {
+ /// Looks through the generics and all parents to find the index of the
+ /// given param def-id. This is in comparison to the `param_def_id_to_index`
+ /// struct member, which only stores information about this item's own
+ /// generics.
+ pub fn param_def_id_to_index(&self, tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<u32> {
+ if let Some(idx) = self.param_def_id_to_index.get(&def_id) {
+ Some(*idx)
+ } else if let Some(parent) = self.parent {
+ let parent = tcx.generics_of(parent);
+ parent.param_def_id_to_index(tcx, def_id)
+ } else {
+ None
+ }
+ }
+
#[inline]
pub fn count(&self) -> usize {
self.parent_count + self.params.len()
@@ -252,7 +267,7 @@ impl<'tcx> Generics {
// Filter the default arguments.
//
// This currently uses structural equality instead
- // of semantic equivalance. While not ideal, that's
+ // of semantic equivalence. While not ideal, that's
// good enough for now as this should only be used
// for diagnostics anyways.
own_params.end -= self
@@ -314,6 +329,7 @@ impl<'tcx> GenericPredicates<'tcx> {
}
}
+ #[instrument(level = "debug", skip(self, tcx))]
fn instantiate_into(
&self,
tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index cd00b26b8..d1c0d62ac 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -113,7 +113,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
}
// `Relocations` with default type parameters is a sorted map.
-impl<'a, Prov> HashStable<StableHashingContext<'a>> for mir::interpret::Relocations<Prov>
+impl<'a, Prov> HashStable<StableHashingContext<'a>> for mir::interpret::ProvenanceMap<Prov>
where
Prov: HashStable<StableHashingContext<'a>>,
{
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 3d22f5a04..aaa66deb2 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -169,14 +169,10 @@ impl<'tcx> FieldDef {
param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest<'tcx> {
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
- // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
- // `Visibility::Invisible` so we need to override `self.vis` if we're
- // dealing with an enum.
if is_enum {
data_uninhabitedness()
} else {
match self.vis {
- Visibility::Invisible => DefIdForest::empty(),
Visibility::Restricted(from) => {
let forest = DefIdForest::from_id(from);
let iter = Some(forest).into_iter().chain(Some(data_uninhabitedness()));
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 53218225d..9afd66207 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -20,14 +20,14 @@ use std::fmt;
/// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval
/// will do all required substitution as they run.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, Lift)]
+#[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
pub struct Instance<'tcx> {
pub def: InstanceDef<'tcx>,
pub substs: SubstsRef<'tcx>,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
+#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum InstanceDef<'tcx> {
/// A user-defined callable item.
///
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index ad78d24e9..042eeec3f 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -2,7 +2,10 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
use crate::ty::normalize_erasing_regions::NormalizationError;
use crate::ty::subst::Subst;
-use crate::ty::{self, subst::SubstsRef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable};
+use crate::ty::{
+ self, layout_sanity_check::sanity_check_layout, subst::SubstsRef, EarlyBinder, ReprOptions, Ty,
+ TyCtxt, TypeVisitable,
+};
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_hir as hir;
@@ -19,7 +22,7 @@ use rustc_target::abi::call::{
use rustc_target::abi::*;
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
-use std::cmp;
+use std::cmp::{self, Ordering};
use std::fmt;
use std::iter;
use std::num::NonZeroUsize;
@@ -221,164 +224,46 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
}
}
-/// Enforce some basic invariants on layouts.
-fn sanity_check_layout<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- layout: &TyAndLayout<'tcx>,
-) {
- // Type-level uninhabitedness should always imply ABI uninhabitedness.
- if tcx.conservative_is_privately_uninhabited(param_env.and(layout.ty)) {
- assert!(layout.abi.is_uninhabited());
- }
-
- if layout.size.bytes() % layout.align.abi.bytes() != 0 {
- bug!("size is not a multiple of align, in the following layout:\n{layout:#?}");
- }
-
- if cfg!(debug_assertions) {
- fn check_layout_abi<'tcx>(tcx: TyCtxt<'tcx>, layout: Layout<'tcx>) {
- match layout.abi() {
- Abi::Scalar(scalar) => {
- // No padding in scalars.
- assert_eq!(
- layout.align().abi,
- scalar.align(&tcx).abi,
- "alignment mismatch between ABI and layout in {layout:#?}"
- );
- assert_eq!(
- layout.size(),
- scalar.size(&tcx),
- "size mismatch between ABI and layout in {layout:#?}"
- );
- }
- Abi::Vector { count, element } => {
- // No padding in vectors. Alignment can be strengthened, though.
- assert!(
- layout.align().abi >= element.align(&tcx).abi,
- "alignment mismatch between ABI and layout in {layout:#?}"
- );
- let size = element.size(&tcx) * count;
- assert_eq!(
- layout.size(),
- size.align_to(tcx.data_layout().vector_align(size).abi),
- "size mismatch between ABI and layout in {layout:#?}"
- );
- }
- Abi::ScalarPair(scalar1, scalar2) => {
- // Sanity-check scalar pairs. These are a bit more flexible and support
- // padding, but we can at least ensure both fields actually fit into the layout
- // and the alignment requirement has not been weakened.
- let align1 = scalar1.align(&tcx).abi;
- let align2 = scalar2.align(&tcx).abi;
- assert!(
- layout.align().abi >= cmp::max(align1, align2),
- "alignment mismatch between ABI and layout in {layout:#?}",
- );
- let field2_offset = scalar1.size(&tcx).align_to(align2);
- assert!(
- layout.size() >= field2_offset + scalar2.size(&tcx),
- "size mismatch between ABI and layout in {layout:#?}"
- );
- }
- Abi::Uninhabited | Abi::Aggregate { .. } => {} // Nothing to check.
- }
- }
-
- check_layout_abi(tcx, layout.layout);
-
- if let Variants::Multiple { variants, .. } = &layout.variants {
- for variant in variants {
- check_layout_abi(tcx, *variant);
- // No nested "multiple".
- assert!(matches!(variant.variants(), Variants::Single { .. }));
- // Skip empty variants.
- if variant.size() == Size::ZERO
- || variant.fields().count() == 0
- || variant.abi().is_uninhabited()
- {
- // These are never actually accessed anyway, so we can skip them. (Note that
- // sometimes, variants with fields have size 0, and sometimes, variants without
- // fields have non-0 size.)
- continue;
- }
- // Variants should have the same or a smaller size as the full thing.
- if variant.size() > layout.size {
- bug!(
- "Type with size {} bytes has variant with size {} bytes: {layout:#?}",
- layout.size.bytes(),
- variant.size().bytes(),
- )
- }
- // The top-level ABI and the ABI of the variants should be coherent.
- let abi_coherent = match (layout.abi, variant.abi()) {
- (Abi::Scalar(..), Abi::Scalar(..)) => true,
- (Abi::ScalarPair(..), Abi::ScalarPair(..)) => true,
- (Abi::Uninhabited, _) => true,
- (Abi::Aggregate { .. }, _) => true,
- _ => false,
- };
- if !abi_coherent {
- bug!(
- "Variant ABI is incompatible with top-level ABI:\nvariant={:#?}\nTop-level: {layout:#?}",
- variant
- );
- }
- }
- }
- }
-}
-
#[instrument(skip(tcx, query), level = "debug")]
fn layout_of<'tcx>(
tcx: TyCtxt<'tcx>,
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> {
- ty::tls::with_related_context(tcx, move |icx| {
- let (param_env, ty) = query.into_parts();
- debug!(?ty);
-
- if !tcx.recursion_limit().value_within_limit(icx.layout_depth) {
- tcx.sess.fatal(&format!("overflow representing the type `{}`", ty));
+ let (param_env, ty) = query.into_parts();
+ debug!(?ty);
+
+ let param_env = param_env.with_reveal_all_normalized(tcx);
+ let unnormalized_ty = ty;
+
+ // FIXME: We might want to have two different versions of `layout_of`:
+ // One that can be called after typecheck has completed and can use
+ // `normalize_erasing_regions` here and another one that can be called
+ // before typecheck has completed and uses `try_normalize_erasing_regions`.
+ let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
+ Ok(t) => t,
+ Err(normalization_error) => {
+ return Err(LayoutError::NormalizationFailure(ty, normalization_error));
}
+ };
- // Update the ImplicitCtxt to increase the layout_depth
- let icx = ty::tls::ImplicitCtxt { layout_depth: icx.layout_depth + 1, ..icx.clone() };
-
- ty::tls::enter_context(&icx, |_| {
- let param_env = param_env.with_reveal_all_normalized(tcx);
- let unnormalized_ty = ty;
-
- // FIXME: We might want to have two different versions of `layout_of`:
- // One that can be called after typecheck has completed and can use
- // `normalize_erasing_regions` here and another one that can be called
- // before typecheck has completed and uses `try_normalize_erasing_regions`.
- let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
- Ok(t) => t,
- Err(normalization_error) => {
- return Err(LayoutError::NormalizationFailure(ty, normalization_error));
- }
- };
-
- if ty != unnormalized_ty {
- // Ensure this layout is also cached for the normalized type.
- return tcx.layout_of(param_env.and(ty));
- }
+ if ty != unnormalized_ty {
+ // Ensure this layout is also cached for the normalized type.
+ return tcx.layout_of(param_env.and(ty));
+ }
- let cx = LayoutCx { tcx, param_env };
+ let cx = LayoutCx { tcx, param_env };
- let layout = cx.layout_of_uncached(ty)?;
- let layout = TyAndLayout { ty, layout };
+ let layout = cx.layout_of_uncached(ty)?;
+ let layout = TyAndLayout { ty, layout };
- cx.record_layout_for_printing(layout);
+ cx.record_layout_for_printing(layout);
- sanity_check_layout(tcx, param_env, &layout);
+ sanity_check_layout(&cx, &layout);
- Ok(layout)
- })
- })
+ Ok(layout)
}
+#[derive(Clone, Copy)]
pub struct LayoutCx<'tcx, C> {
pub tcx: C,
pub param_env: ty::ParamEnv<'tcx>,
@@ -740,6 +625,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
tcx.intern_layout(self.scalar_pair(data_ptr, metadata))
}
+ ty::Dynamic(_, _, ty::DynStar) => {
+ let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false));
+ data.valid_range_mut().start = 0;
+ let mut vtable = scalar_unit(Pointer);
+ vtable.valid_range_mut().start = 1;
+ tcx.intern_layout(self.scalar_pair(data, vtable))
+ }
+
// Arrays and slices.
ty::Array(element, mut count) => {
if count.has_projections() {
@@ -794,7 +687,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// Odd unit types.
ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?,
- ty::Dynamic(..) | ty::Foreign(..) => {
+ ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => {
let mut unit = self.univariant_uninterned(
ty,
&[],
@@ -872,7 +765,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// * the element type and length of the single array field, if
// the first field is of array type, or
//
- // * the homogenous field type and the number of fields.
+ // * the homogeneous field type and the number of fields.
let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() {
// First ADT field is an array:
@@ -1161,131 +1054,191 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// that allow representation optimization.)
assert!(def.is_enum());
- // The current code for niche-filling relies on variant indices
- // instead of actual discriminants, so dataful enums with
- // explicit discriminants (RFC #2363) would misbehave.
- let no_explicit_discriminants = def
- .variants()
- .iter_enumerated()
- .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
-
- let mut niche_filling_layout = None;
-
- // Niche-filling enum optimization.
- if !def.repr().inhibit_enum_layout_opt() && no_explicit_discriminants {
- let mut dataful_variant = None;
- let mut niche_variants = VariantIdx::MAX..=VariantIdx::new(0);
+ // Until we've decided whether to use the tagged or
+ // niche filling LayoutS, we don't want to intern the
+ // variant layouts, so we can't store them in the
+ // overall LayoutS. Store the overall LayoutS
+ // and the variant LayoutSs here until then.
+ struct TmpLayout<'tcx> {
+ layout: LayoutS<'tcx>,
+ variants: IndexVec<VariantIdx, LayoutS<'tcx>>,
+ }
- // Find one non-ZST variant.
- 'variants: for (v, fields) in variants.iter_enumerated() {
- if absent(fields) {
- continue 'variants;
+ let calculate_niche_filling_layout =
+ || -> Result<Option<TmpLayout<'tcx>>, LayoutError<'tcx>> {
+ // The current code for niche-filling relies on variant indices
+ // instead of actual discriminants, so enums with
+ // explicit discriminants (RFC #2363) would misbehave.
+ if def.repr().inhibit_enum_layout_opt()
+ || def
+ .variants()
+ .iter_enumerated()
+ .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()))
+ {
+ return Ok(None);
}
- for f in fields {
- if !f.is_zst() {
- if dataful_variant.is_none() {
- dataful_variant = Some(v);
- continue 'variants;
- } else {
- dataful_variant = None;
- break 'variants;
- }
- }
+
+ if variants.len() < 2 {
+ return Ok(None);
}
- niche_variants = *niche_variants.start().min(&v)..=v;
- }
- if niche_variants.start() > niche_variants.end() {
- dataful_variant = None;
- }
+ let mut align = dl.aggregate_align;
+ let mut variant_layouts = variants
+ .iter_enumerated()
+ .map(|(j, v)| {
+ let mut st = self.univariant_uninterned(
+ ty,
+ v,
+ &def.repr(),
+ StructKind::AlwaysSized,
+ )?;
+ st.variants = Variants::Single { index: j };
+
+ align = align.max(st.align);
+
+ Ok(st)
+ })
+ .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+
+ let largest_variant_index = match variant_layouts
+ .iter_enumerated()
+ .max_by_key(|(_i, layout)| layout.size.bytes())
+ .map(|(i, _layout)| i)
+ {
+ None => return Ok(None),
+ Some(i) => i,
+ };
+
+ let all_indices = VariantIdx::new(0)..=VariantIdx::new(variants.len() - 1);
+ let needs_disc = |index: VariantIdx| {
+ index != largest_variant_index && !absent(&variants[index])
+ };
+ let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
+ ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
- if let Some(i) = dataful_variant {
- let count = (niche_variants.end().as_u32()
- - niche_variants.start().as_u32()
- + 1) as u128;
+ let count = niche_variants.size_hint().1.unwrap() as u128;
// Find the field with the largest niche
- let niche_candidate = variants[i]
+ let (field_index, niche, (niche_start, niche_scalar)) = match variants
+ [largest_variant_index]
.iter()
.enumerate()
.filter_map(|(j, field)| Some((j, field.largest_niche?)))
- .max_by_key(|(_, niche)| niche.available(dl));
-
- if let Some((field_index, niche, (niche_start, niche_scalar))) =
- niche_candidate.and_then(|(field_index, niche)| {
- Some((field_index, niche, niche.reserve(self, count)?))
- })
+ .max_by_key(|(_, niche)| niche.available(dl))
+ .and_then(|(j, niche)| Some((j, niche, niche.reserve(self, count)?)))
{
- let mut align = dl.aggregate_align;
- let st = variants
- .iter_enumerated()
- .map(|(j, v)| {
- let mut st = self.univariant_uninterned(
- ty,
- v,
- &def.repr(),
- StructKind::AlwaysSized,
- )?;
- st.variants = Variants::Single { index: j };
+ None => return Ok(None),
+ Some(x) => x,
+ };
+
+ let niche_offset = niche.offset
+ + variant_layouts[largest_variant_index].fields.offset(field_index);
+ let niche_size = niche.value.size(dl);
+ let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
- align = align.max(st.align);
+ let all_variants_fit =
+ variant_layouts.iter_enumerated_mut().all(|(i, layout)| {
+ if i == largest_variant_index {
+ return true;
+ }
- Ok(tcx.intern_layout(st))
- })
- .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+ layout.largest_niche = None;
- let offset = st[i].fields().offset(field_index) + niche.offset;
+ if layout.size <= niche_offset {
+ // This variant will fit before the niche.
+ return true;
+ }
- // Align the total size to the largest alignment.
- let size = st[i].size().align_to(align.abi);
+ // Determine if it'll fit after the niche.
+ let this_align = layout.align.abi;
+ let this_offset = (niche_offset + niche_size).align_to(this_align);
- let abi = if st.iter().all(|v| v.abi().is_uninhabited()) {
- Abi::Uninhabited
- } else if align == st[i].align() && size == st[i].size() {
- // When the total alignment and size match, we can use the
- // same ABI as the scalar variant with the reserved niche.
- match st[i].abi() {
- Abi::Scalar(_) => Abi::Scalar(niche_scalar),
- Abi::ScalarPair(first, second) => {
- // Only the niche is guaranteed to be initialised,
- // so use union layout for the other primitive.
- if offset.bytes() == 0 {
- Abi::ScalarPair(niche_scalar, second.to_union())
- } else {
- Abi::ScalarPair(first.to_union(), niche_scalar)
+ if this_offset + layout.size > size {
+ return false;
+ }
+
+ // It'll fit, but we need to make some adjustments.
+ match layout.fields {
+ FieldsShape::Arbitrary { ref mut offsets, .. } => {
+ for (j, offset) in offsets.iter_mut().enumerate() {
+ if !variants[i][j].is_zst() {
+ *offset += this_offset;
+ }
}
}
- _ => Abi::Aggregate { sized: true },
+ _ => {
+ panic!("Layout of fields should be Arbitrary for variants")
+ }
}
- } else {
- Abi::Aggregate { sized: true }
- };
- let largest_niche = Niche::from_scalar(dl, offset, niche_scalar);
-
- niche_filling_layout = Some(LayoutS {
- variants: Variants::Multiple {
- tag: niche_scalar,
- tag_encoding: TagEncoding::Niche {
- dataful_variant: i,
- niche_variants,
- niche_start,
- },
- tag_field: 0,
- variants: st,
- },
- fields: FieldsShape::Arbitrary {
- offsets: vec![offset],
- memory_index: vec![0],
- },
- abi,
- largest_niche,
- size,
- align,
+ // It can't be a Scalar or ScalarPair because the offset isn't 0.
+ if !layout.abi.is_uninhabited() {
+ layout.abi = Abi::Aggregate { sized: true };
+ }
+ layout.size += this_offset;
+
+ true
});
+
+ if !all_variants_fit {
+ return Ok(None);
}
- }
- }
+
+ let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar);
+
+ let others_zst = variant_layouts.iter_enumerated().all(|(i, layout)| {
+ i == largest_variant_index || layout.size == Size::ZERO
+ });
+ let same_size = size == variant_layouts[largest_variant_index].size;
+ let same_align = align == variant_layouts[largest_variant_index].align;
+
+ let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) {
+ Abi::Uninhabited
+ } else if same_size && same_align && others_zst {
+ match variant_layouts[largest_variant_index].abi {
+ // When the total alignment and size match, we can use the
+ // same ABI as the scalar variant with the reserved niche.
+ Abi::Scalar(_) => Abi::Scalar(niche_scalar),
+ Abi::ScalarPair(first, second) => {
+ // Only the niche is guaranteed to be initialised,
+ // so use union layouts for the other primitive.
+ if niche_offset == Size::ZERO {
+ Abi::ScalarPair(niche_scalar, second.to_union())
+ } else {
+ Abi::ScalarPair(first.to_union(), niche_scalar)
+ }
+ }
+ _ => Abi::Aggregate { sized: true },
+ }
+ } else {
+ Abi::Aggregate { sized: true }
+ };
+
+ let layout = LayoutS {
+ variants: Variants::Multiple {
+ tag: niche_scalar,
+ tag_encoding: TagEncoding::Niche {
+ untagged_variant: largest_variant_index,
+ niche_variants,
+ niche_start,
+ },
+ tag_field: 0,
+ variants: IndexVec::new(),
+ },
+ fields: FieldsShape::Arbitrary {
+ offsets: vec![niche_offset],
+ memory_index: vec![0],
+ },
+ abi,
+ largest_niche,
+ size,
+ align,
+ };
+
+ Ok(Some(TmpLayout { layout, variants: variant_layouts }))
+ };
+
+ let niche_filling_layout = calculate_niche_filling_layout()?;
let (mut min, mut max) = (i128::MAX, i128::MIN);
let discr_type = def.repr().discr_type();
@@ -1540,15 +1493,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
- let layout_variants =
- layout_variants.into_iter().map(|v| tcx.intern_layout(v)).collect();
-
let tagged_layout = LayoutS {
variants: Variants::Multiple {
tag,
tag_encoding: TagEncoding::Direct,
tag_field: 0,
- variants: layout_variants,
+ variants: IndexVec::new(),
},
fields: FieldsShape::Arbitrary {
offsets: vec![Size::ZERO],
@@ -1560,20 +1510,45 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
size,
};
- let best_layout = match (tagged_layout, niche_filling_layout) {
- (tagged_layout, Some(niche_filling_layout)) => {
+ let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants };
+
+ let mut best_layout = match (tagged_layout, niche_filling_layout) {
+ (tl, Some(nl)) => {
// Pick the smaller layout; otherwise,
// pick the layout with the larger niche; otherwise,
// pick tagged as it has simpler codegen.
- cmp::min_by_key(tagged_layout, niche_filling_layout, |layout| {
- let niche_size = layout.largest_niche.map_or(0, |n| n.available(dl));
- (layout.size, cmp::Reverse(niche_size))
- })
+ use Ordering::*;
+ let niche_size = |tmp_l: &TmpLayout<'_>| {
+ tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
+ };
+ match (
+ tl.layout.size.cmp(&nl.layout.size),
+ niche_size(&tl).cmp(&niche_size(&nl)),
+ ) {
+ (Greater, _) => nl,
+ (Equal, Less) => nl,
+ _ => tl,
+ }
}
- (tagged_layout, None) => tagged_layout,
+ (tl, None) => tl,
};
- tcx.intern_layout(best_layout)
+ // Now we can intern the variant layouts and store them in the enum layout.
+ best_layout.layout.variants = match best_layout.layout.variants {
+ Variants::Multiple { tag, tag_encoding, tag_field, .. } => Variants::Multiple {
+ tag,
+ tag_encoding,
+ tag_field,
+ variants: best_layout
+ .variants
+ .into_iter()
+ .map(|layout| tcx.intern_layout(layout))
+ .collect(),
+ },
+ _ => bug!(),
+ };
+
+ tcx.intern_layout(best_layout.layout)
}
// Types with no meaningful known layout.
@@ -2468,7 +2443,9 @@ where
| ty::FnDef(..)
| ty::GeneratorWitness(..)
| ty::Foreign(..)
- | ty::Dynamic(..) => bug!("TyAndLayout::field({:?}): not applicable", this),
+ | ty::Dynamic(_, _, ty::Dyn) => {
+ bug!("TyAndLayout::field({:?}): not applicable", this)
+ }
// Potentially-fat pointers.
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
@@ -2497,7 +2474,7 @@ where
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
ty::Slice(_) | ty::Str => TyMaybeWithLayout::Ty(tcx.types.usize),
- ty::Dynamic(_, _) => {
+ ty::Dynamic(_, _, ty::Dyn) => {
TyMaybeWithLayout::Ty(tcx.mk_imm_ref(
tcx.lifetimes.re_static,
tcx.mk_array(tcx.types.usize, 3),
@@ -2566,6 +2543,22 @@ where
}
}
+ ty::Dynamic(_, _, ty::DynStar) => {
+ if i == 0 {
+ TyMaybeWithLayout::Ty(tcx.types.usize)
+ } else if i == 1 {
+ // FIXME(dyn-star) same FIXME as above applies here too
+ TyMaybeWithLayout::Ty(
+ tcx.mk_imm_ref(
+ tcx.lifetimes.re_static,
+ tcx.mk_array(tcx.types.usize, 3),
+ ),
+ )
+ } else {
+ bug!("no field {i} on dyn*")
+ }
+ }
+
ty::Projection(_)
| ty::Bound(..)
| ty::Placeholder(..)
@@ -2674,11 +2667,11 @@ where
// using more niches than just null (e.g., the first page of
// the address space, or unaligned pointers).
Variants::Multiple {
- tag_encoding: TagEncoding::Niche { dataful_variant, .. },
+ tag_encoding: TagEncoding::Niche { untagged_variant, .. },
tag_field,
..
} if this.fields.offset(tag_field) == offset => {
- Some(this.for_variant(cx, dataful_variant))
+ Some(this.for_variant(cx, untagged_variant))
}
_ => Some(this),
};
@@ -2761,6 +2754,7 @@ impl<'tcx> ty::Instance<'tcx> {
// for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
// or should go through `FnAbi` instead, to avoid losing any
// adjustments `fn_abi_of_instance` might be performing.
+ #[tracing::instrument(level = "debug", skip(tcx, param_env))]
fn fn_sig_for_fn_abi(
&self,
tcx: TyCtxt<'tcx>,
@@ -2907,6 +2901,7 @@ impl<'tcx> ty::Instance<'tcx> {
/// with `-Cpanic=abort` will look like they can't unwind when in fact they
/// might (from a foreign exception or similar).
#[inline]
+#[tracing::instrument(level = "debug", skip(tcx))]
pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
if let Some(did) = fn_def_id {
// Special attribute for functions which can't unwind.
@@ -3123,6 +3118,7 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
/// NB: that includes virtual calls, which are represented by "direct calls"
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
#[inline]
+ #[tracing::instrument(level = "debug", skip(self))]
fn fn_abi_of_instance(
&self,
instance: ty::Instance<'tcx>,
@@ -3179,9 +3175,100 @@ fn fn_abi_of_instance<'tcx>(
)
}
+// Handle safe Rust thin and fat pointers.
+pub fn adjust_for_rust_scalar<'tcx>(
+ cx: LayoutCx<'tcx, TyCtxt<'tcx>>,
+ attrs: &mut ArgAttributes,
+ scalar: Scalar,
+ layout: TyAndLayout<'tcx>,
+ offset: Size,
+ is_return: bool,
+) {
+ // Booleans are always a noundef i1 that needs to be zero-extended.
+ if scalar.is_bool() {
+ attrs.ext(ArgExtension::Zext);
+ attrs.set(ArgAttribute::NoUndef);
+ return;
+ }
+
+ // Scalars which have invalid values cannot be undef.
+ if !scalar.is_always_valid(&cx) {
+ attrs.set(ArgAttribute::NoUndef);
+ }
+
+ // Only pointer types handled below.
+ let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return };
+
+ if !valid_range.contains(0) {
+ attrs.set(ArgAttribute::NonNull);
+ }
+
+ if let Some(pointee) = layout.pointee_info_at(&cx, offset) {
+ if let Some(kind) = pointee.safe {
+ attrs.pointee_align = Some(pointee.align);
+
+ // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable
+ // for the entire duration of the function as they can be deallocated
+ // at any time. Same for shared mutable references. If LLVM had a
+ // way to say "dereferenceable on entry" we could use it here.
+ attrs.pointee_size = match kind {
+ PointerKind::UniqueBorrowed
+ | PointerKind::UniqueBorrowedPinned
+ | PointerKind::Frozen => pointee.size,
+ PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO,
+ };
+
+ // `Box`, `&T`, and `&mut T` cannot be undef.
+ // Note that this only applies to the value of the pointer itself;
+ // this attribute doesn't make it UB for the pointed-to data to be undef.
+ attrs.set(ArgAttribute::NoUndef);
+
+ // The aliasing rules for `Box<T>` are still not decided, but currently we emit
+ // `noalias` for it. This can be turned off using an unstable flag.
+ // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
+ let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true);
+
+ // `&mut` pointer parameters never alias other parameters,
+ // or mutable global data
+ //
+ // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
+ // and can be marked as both `readonly` and `noalias`, as
+ // LLVM's definition of `noalias` is based solely on memory
+ // dependencies rather than pointer equality
+ //
+ // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute
+ // for UniqueBorrowed arguments, so that the codegen backend can decide whether
+ // or not to actually emit the attribute. It can also be controlled with the
+ // `-Zmutable-noalias` debugging option.
+ let no_alias = match kind {
+ PointerKind::SharedMutable
+ | PointerKind::UniqueBorrowed
+ | PointerKind::UniqueBorrowedPinned => false,
+ PointerKind::UniqueOwned => noalias_for_box,
+ PointerKind::Frozen => !is_return,
+ };
+ if no_alias {
+ attrs.set(ArgAttribute::NoAlias);
+ }
+
+ if kind == PointerKind::Frozen && !is_return {
+ attrs.set(ArgAttribute::ReadOnly);
+ }
+
+ if kind == PointerKind::UniqueBorrowed && !is_return {
+ attrs.set(ArgAttribute::NoAliasMutRef);
+ }
+ }
+ }
+}
+
impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// FIXME(eddyb) perhaps group the signature/type-containing (or all of them?)
// arguments of this method, into a separate `struct`.
+ #[tracing::instrument(
+ level = "debug",
+ skip(self, caller_location, fn_def_id, force_thin_self_ptr)
+ )]
fn fn_abi_new_uncached(
&self,
sig: ty::PolyFnSig<'tcx>,
@@ -3191,8 +3278,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// FIXME(eddyb) replace this with something typed, like an `enum`.
force_thin_self_ptr: bool,
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
- debug!("fn_abi_new_uncached({:?}, {:?})", sig, extra_args);
-
let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig);
let conv = conv_from_spec_abi(self.tcx(), sig.abi);
@@ -3234,92 +3319,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
use SpecAbi::*;
let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall);
- // Handle safe Rust thin and fat pointers.
- let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
- scalar: Scalar,
- layout: TyAndLayout<'tcx>,
- offset: Size,
- is_return: bool| {
- // Booleans are always a noundef i1 that needs to be zero-extended.
- if scalar.is_bool() {
- attrs.ext(ArgExtension::Zext);
- attrs.set(ArgAttribute::NoUndef);
- return;
- }
-
- // Scalars which have invalid values cannot be undef.
- if !scalar.is_always_valid(self) {
- attrs.set(ArgAttribute::NoUndef);
- }
-
- // Only pointer types handled below.
- let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return };
-
- if !valid_range.contains(0) {
- attrs.set(ArgAttribute::NonNull);
- }
-
- if let Some(pointee) = layout.pointee_info_at(self, offset) {
- if let Some(kind) = pointee.safe {
- attrs.pointee_align = Some(pointee.align);
-
- // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable
- // for the entire duration of the function as they can be deallocated
- // at any time. Same for shared mutable references. If LLVM had a
- // way to say "dereferenceable on entry" we could use it here.
- attrs.pointee_size = match kind {
- PointerKind::UniqueBorrowed
- | PointerKind::UniqueBorrowedPinned
- | PointerKind::Frozen => pointee.size,
- PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO,
- };
-
- // `Box`, `&T`, and `&mut T` cannot be undef.
- // Note that this only applies to the value of the pointer itself;
- // this attribute doesn't make it UB for the pointed-to data to be undef.
- attrs.set(ArgAttribute::NoUndef);
-
- // The aliasing rules for `Box<T>` are still not decided, but currently we emit
- // `noalias` for it. This can be turned off using an unstable flag.
- // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
- let noalias_for_box =
- self.tcx().sess.opts.unstable_opts.box_noalias.unwrap_or(true);
-
- // `&mut` pointer parameters never alias other parameters,
- // or mutable global data
- //
- // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
- // and can be marked as both `readonly` and `noalias`, as
- // LLVM's definition of `noalias` is based solely on memory
- // dependencies rather than pointer equality
- //
- // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute
- // for UniqueBorrowed arguments, so that the codegen backend can decide whether
- // or not to actually emit the attribute. It can also be controlled with the
- // `-Zmutable-noalias` debugging option.
- let no_alias = match kind {
- PointerKind::SharedMutable
- | PointerKind::UniqueBorrowed
- | PointerKind::UniqueBorrowedPinned => false,
- PointerKind::UniqueOwned => noalias_for_box,
- PointerKind::Frozen => !is_return,
- };
- if no_alias {
- attrs.set(ArgAttribute::NoAlias);
- }
-
- if kind == PointerKind::Frozen && !is_return {
- attrs.set(ArgAttribute::ReadOnly);
- }
-
- if kind == PointerKind::UniqueBorrowed && !is_return {
- attrs.set(ArgAttribute::NoAliasMutRef);
- }
- }
- }
- };
-
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
+ let span = tracing::debug_span!("arg_of");
+ let _entered = span.enter();
let is_return = arg_idx.is_none();
let layout = self.layout_of(ty)?;
@@ -3334,7 +3336,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let mut arg = ArgAbi::new(self, layout, |layout, scalar, offset| {
let mut attrs = ArgAttributes::new();
- adjust_for_rust_scalar(&mut attrs, scalar, *layout, offset, is_return);
+ adjust_for_rust_scalar(*self, &mut attrs, scalar, *layout, offset, is_return);
attrs
});
@@ -3367,7 +3369,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
.map(|(i, ty)| arg_of(ty, Some(i)))
.collect::<Result<_, _>>()?,
c_variadic: sig.c_variadic,
- fixed_count: inputs.len(),
+ fixed_count: inputs.len() as u32,
conv,
can_unwind: fn_can_unwind(self.tcx(), fn_def_id, sig.abi),
};
@@ -3376,6 +3378,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
Ok(self.tcx.arena.alloc(fn_abi))
}
+ #[tracing::instrument(level = "trace", skip(self))]
fn fn_abi_adjust_for_abi(
&self,
fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
@@ -3439,7 +3442,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
}
};
fixup(&mut fn_abi.ret);
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
fixup(arg);
}
} else {
@@ -3450,6 +3453,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
}
}
+#[tracing::instrument(level = "debug", skip(cx))]
fn make_thin_self_ptr<'tcx>(
cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
layout: TyAndLayout<'tcx>,
@@ -3461,7 +3465,7 @@ fn make_thin_self_ptr<'tcx>(
tcx.mk_mut_ptr(layout.ty)
} else {
match layout.abi {
- Abi::ScalarPair(..) => (),
+ Abi::ScalarPair(..) | Abi::Scalar(..) => (),
_ => bug!("receiver type has unsupported layout: {:?}", layout),
}
diff --git a/compiler/rustc_middle/src/ty/layout_sanity_check.rs b/compiler/rustc_middle/src/ty/layout_sanity_check.rs
new file mode 100644
index 000000000..87c85dcff
--- /dev/null
+++ b/compiler/rustc_middle/src/ty/layout_sanity_check.rs
@@ -0,0 +1,303 @@
+use crate::ty::{
+ layout::{LayoutCx, TyAndLayout},
+ TyCtxt,
+};
+use rustc_target::abi::*;
+
+use std::cmp;
+
+/// Enforce some basic invariants on layouts.
+pub(super) fn sanity_check_layout<'tcx>(
+ cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+ layout: &TyAndLayout<'tcx>,
+) {
+ // Type-level uninhabitedness should always imply ABI uninhabitedness.
+ if cx.tcx.conservative_is_privately_uninhabited(cx.param_env.and(layout.ty)) {
+ assert!(layout.abi.is_uninhabited());
+ }
+
+ if layout.size.bytes() % layout.align.abi.bytes() != 0 {
+ bug!("size is not a multiple of align, in the following layout:\n{layout:#?}");
+ }
+
+ if cfg!(debug_assertions) {
+ /// Yields non-ZST fields of the type
+ fn non_zst_fields<'tcx, 'a>(
+ cx: &'a LayoutCx<'tcx, TyCtxt<'tcx>>,
+ layout: &'a TyAndLayout<'tcx>,
+ ) -> impl Iterator<Item = (Size, TyAndLayout<'tcx>)> + 'a {
+ (0..layout.layout.fields().count()).filter_map(|i| {
+ let field = layout.field(cx, i);
+ // Also checking `align == 1` here leads to test failures in
+ // `layout/zero-sized-array-union.rs`, where a type has a zero-size field with
+ // alignment 4 that still gets ignored during layout computation (which is okay
+ // since other fields already force alignment 4).
+ let zst = field.is_zst();
+ (!zst).then(|| (layout.fields.offset(i), field))
+ })
+ }
+
+ fn skip_newtypes<'tcx>(
+ cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+ layout: &TyAndLayout<'tcx>,
+ ) -> TyAndLayout<'tcx> {
+ if matches!(layout.layout.variants(), Variants::Multiple { .. }) {
+ // Definitely not a newtype of anything.
+ return *layout;
+ }
+ let mut fields = non_zst_fields(cx, layout);
+ let Some(first) = fields.next() else {
+ // No fields here, so this could be a primitive or enum -- either way it's not a newtype around a thing
+ return *layout
+ };
+ if fields.next().is_none() {
+ let (offset, first) = first;
+ if offset == Size::ZERO && first.layout.size() == layout.size {
+ // This is a newtype, so keep recursing.
+ // FIXME(RalfJung): I don't think it would be correct to do any checks for
+ // alignment here, so we don't. Is that correct?
+ return skip_newtypes(cx, &first);
+ }
+ }
+ // No more newtypes here.
+ *layout
+ }
+
+ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayout<'tcx>) {
+ match layout.layout.abi() {
+ Abi::Scalar(scalar) => {
+ // No padding in scalars.
+ let size = scalar.size(cx);
+ let align = scalar.align(cx).abi;
+ assert_eq!(
+ layout.layout.size(),
+ size,
+ "size mismatch between ABI and layout in {layout:#?}"
+ );
+ assert_eq!(
+ layout.layout.align().abi,
+ align,
+ "alignment mismatch between ABI and layout in {layout:#?}"
+ );
+ // Check that this matches the underlying field.
+ let inner = skip_newtypes(cx, layout);
+ assert!(
+ matches!(inner.layout.abi(), Abi::Scalar(_)),
+ "`Scalar` type {} is newtype around non-`Scalar` type {}",
+ layout.ty,
+ inner.ty
+ );
+ match inner.layout.fields() {
+ FieldsShape::Primitive => {
+ // Fine.
+ }
+ FieldsShape::Union(..) => {
+ // FIXME: I guess we could also check something here? Like, look at all fields?
+ return;
+ }
+ FieldsShape::Arbitrary { .. } => {
+ // Should be an enum, the only field is the discriminant.
+ assert!(
+ inner.ty.is_enum(),
+ "`Scalar` layout for non-primitive non-enum type {}",
+ inner.ty
+ );
+ assert_eq!(
+ inner.layout.fields().count(),
+ 1,
+ "`Scalar` layout for multiple-field type in {inner:#?}",
+ );
+ let offset = inner.layout.fields().offset(0);
+ let field = inner.field(cx, 0);
+ // The field should be at the right offset, and match the `scalar` layout.
+ assert_eq!(
+ offset,
+ Size::ZERO,
+ "`Scalar` field at non-0 offset in {inner:#?}",
+ );
+ assert_eq!(
+ field.size, size,
+ "`Scalar` field with bad size in {inner:#?}",
+ );
+ assert_eq!(
+ field.align.abi, align,
+ "`Scalar` field with bad align in {inner:#?}",
+ );
+ assert!(
+ matches!(field.abi, Abi::Scalar(_)),
+ "`Scalar` field with bad ABI in {inner:#?}",
+ );
+ }
+ _ => {
+ panic!("`Scalar` layout for non-primitive non-enum type {}", inner.ty);
+ }
+ }
+ }
+ Abi::ScalarPair(scalar1, scalar2) => {
+ // Sanity-check scalar pairs. These are a bit more flexible and support
+ // padding, but we can at least ensure both fields actually fit into the layout
+ // and the alignment requirement has not been weakened.
+ let size1 = scalar1.size(cx);
+ let align1 = scalar1.align(cx).abi;
+ let size2 = scalar2.size(cx);
+ let align2 = scalar2.align(cx).abi;
+ assert!(
+ layout.layout.align().abi >= cmp::max(align1, align2),
+ "alignment mismatch between ABI and layout in {layout:#?}",
+ );
+ let field2_offset = size1.align_to(align2);
+ assert!(
+ layout.layout.size() >= field2_offset + size2,
+ "size mismatch between ABI and layout in {layout:#?}"
+ );
+ // Check that the underlying pair of fields matches.
+ let inner = skip_newtypes(cx, layout);
+ assert!(
+ matches!(inner.layout.abi(), Abi::ScalarPair(..)),
+ "`ScalarPair` type {} is newtype around non-`ScalarPair` type {}",
+ layout.ty,
+ inner.ty
+ );
+ if matches!(inner.layout.variants(), Variants::Multiple { .. }) {
+ // FIXME: ScalarPair for enums is enormously complicated and it is very hard
+ // to check anything about them.
+ return;
+ }
+ match inner.layout.fields() {
+ FieldsShape::Arbitrary { .. } => {
+ // Checked below.
+ }
+ FieldsShape::Union(..) => {
+ // FIXME: I guess we could also check something here? Like, look at all fields?
+ return;
+ }
+ _ => {
+ panic!("`ScalarPair` layout with unexpected field shape in {inner:#?}");
+ }
+ }
+ let mut fields = non_zst_fields(cx, &inner);
+ let (offset1, field1) = fields.next().unwrap_or_else(|| {
+ panic!("`ScalarPair` layout for type with not even one non-ZST field: {inner:#?}")
+ });
+ let (offset2, field2) = fields.next().unwrap_or_else(|| {
+ panic!("`ScalarPair` layout for type with less than two non-ZST fields: {inner:#?}")
+ });
+ assert!(
+ fields.next().is_none(),
+ "`ScalarPair` layout for type with at least three non-ZST fields: {inner:#?}"
+ );
+ // The fields might be in opposite order.
+ let (offset1, field1, offset2, field2) = if offset1 <= offset2 {
+ (offset1, field1, offset2, field2)
+ } else {
+ (offset2, field2, offset1, field1)
+ };
+ // The fields should be at the right offset, and match the `scalar` layout.
+ assert_eq!(
+ offset1,
+ Size::ZERO,
+ "`ScalarPair` first field at non-0 offset in {inner:#?}",
+ );
+ assert_eq!(
+ field1.size, size1,
+ "`ScalarPair` first field with bad size in {inner:#?}",
+ );
+ assert_eq!(
+ field1.align.abi, align1,
+ "`ScalarPair` first field with bad align in {inner:#?}",
+ );
+ assert!(
+ matches!(field1.abi, Abi::Scalar(_)),
+ "`ScalarPair` first field with bad ABI in {inner:#?}",
+ );
+ assert_eq!(
+ offset2, field2_offset,
+ "`ScalarPair` second field at bad offset in {inner:#?}",
+ );
+ assert_eq!(
+ field2.size, size2,
+ "`ScalarPair` second field with bad size in {inner:#?}",
+ );
+ assert_eq!(
+ field2.align.abi, align2,
+ "`ScalarPair` second field with bad align in {inner:#?}",
+ );
+ assert!(
+ matches!(field2.abi, Abi::Scalar(_)),
+ "`ScalarPair` second field with bad ABI in {inner:#?}",
+ );
+ }
+ Abi::Vector { count, element } => {
+ // No padding in vectors. Alignment can be strengthened, though.
+ assert!(
+ layout.layout.align().abi >= element.align(cx).abi,
+ "alignment mismatch between ABI and layout in {layout:#?}"
+ );
+ let size = element.size(cx) * count;
+ assert_eq!(
+ layout.layout.size(),
+ size.align_to(cx.data_layout().vector_align(size).abi),
+ "size mismatch between ABI and layout in {layout:#?}"
+ );
+ }
+ Abi::Uninhabited | Abi::Aggregate { .. } => {} // Nothing to check.
+ }
+ }
+
+ check_layout_abi(cx, layout);
+
+ if let Variants::Multiple { variants, .. } = &layout.variants {
+ for variant in variants.iter() {
+ // No nested "multiple".
+ assert!(matches!(variant.variants(), Variants::Single { .. }));
+ // Variants should have the same or a smaller size as the full thing,
+ // and same for alignment.
+ if variant.size() > layout.size {
+ bug!(
+ "Type with size {} bytes has variant with size {} bytes: {layout:#?}",
+ layout.size.bytes(),
+ variant.size().bytes(),
+ )
+ }
+ if variant.align().abi > layout.align.abi {
+ bug!(
+ "Type with alignment {} bytes has variant with alignment {} bytes: {layout:#?}",
+ layout.align.abi.bytes(),
+ variant.align().abi.bytes(),
+ )
+ }
+ // Skip empty variants.
+ if variant.size() == Size::ZERO
+ || variant.fields().count() == 0
+ || variant.abi().is_uninhabited()
+ {
+ // These are never actually accessed anyway, so we can skip the coherence check
+ // for them. They also fail that check, since they have
+ // `Aggregate`/`Uninhbaited` ABI even when the main type is
+ // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size
+ // 0, and sometimes, variants without fields have non-0 size.)
+ continue;
+ }
+ // The top-level ABI and the ABI of the variants should be coherent.
+ let scalar_coherent = |s1: Scalar, s2: Scalar| {
+ s1.size(cx) == s2.size(cx) && s1.align(cx) == s2.align(cx)
+ };
+ let abi_coherent = match (layout.abi, variant.abi()) {
+ (Abi::Scalar(s1), Abi::Scalar(s2)) => scalar_coherent(s1, s2),
+ (Abi::ScalarPair(a1, b1), Abi::ScalarPair(a2, b2)) => {
+ scalar_coherent(a1, a2) && scalar_coherent(b1, b2)
+ }
+ (Abi::Uninhabited, _) => true,
+ (Abi::Aggregate { .. }, _) => true,
+ _ => false,
+ };
+ if !abi_coherent {
+ bug!(
+ "Variant ABI is incompatible with top-level ABI:\nvariant={:#?}\nTop-level: {layout:#?}",
+ variant
+ );
+ }
+ }
+ }
+ }
+}
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index db3b5cfd1..79365ef28 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -65,6 +65,10 @@ impl<T> List<T> {
pub fn len(&self) -> usize {
self.len
}
+
+ pub fn as_slice(&self) -> &[T] {
+ self
+ }
}
impl<T: Copy> List<T> {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 02da02568..3f9871190 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -15,6 +15,7 @@ pub use self::AssocItemContainer::*;
pub use self::BorrowKind::*;
pub use self::IntVarValue::*;
pub use self::Variance::*;
+use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
use crate::metadata::ModChild;
use crate::middle::privacy::AccessLevels;
use crate::mir::{Body, GeneratorLayout};
@@ -40,6 +41,7 @@ use rustc_hir::Node;
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
+use rustc_serialize::{Decodable, Encodable};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ExpnId, Span};
@@ -49,10 +51,14 @@ pub use vtable::*;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
+use std::marker::PhantomData;
+use std::mem;
+use std::num::NonZeroUsize;
use std::ops::ControlFlow;
use std::{fmt, str};
pub use crate::ty::diagnostics::*;
+pub use rustc_type_ir::DynKind::*;
pub use rustc_type_ir::InferTy::*;
pub use rustc_type_ir::RegionKind::*;
pub use rustc_type_ir::TyKind::*;
@@ -124,6 +130,7 @@ mod erase_regions;
mod generics;
mod impls_ty;
mod instance;
+mod layout_sanity_check;
mod list;
mod parameterized;
mod rvalue_scopes;
@@ -177,11 +184,6 @@ pub struct ResolverAstLowering {
pub label_res_map: NodeMap<ast::NodeId>,
/// Resolutions for lifetimes.
pub lifetimes_res_map: NodeMap<LifetimeRes>,
- /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
- /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
- /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
- /// field from the original parameter 'a to the new parameter 'a1.
- pub generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
/// Lifetime parameters that lowering will have to introduce.
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
@@ -262,13 +264,11 @@ impl fmt::Display for ImplPolarity {
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
-pub enum Visibility {
+pub enum Visibility<Id = LocalDefId> {
/// Visible everywhere (including in other crates).
Public,
/// Visible only in the given crate-local module.
- Restricted(DefId),
- /// Not visible anywhere in the local crate. This is the visibility of private external items.
- Invisible,
+ Restricted(Id),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
@@ -359,31 +359,45 @@ impl<'tcx> DefIdTree for TyCtxt<'tcx> {
}
}
-impl Visibility {
- /// Returns `true` if an item with this visibility is accessible from the given block.
- pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
- let restriction = match self {
- // Public items are visible everywhere.
- Visibility::Public => return true,
- // Private items from other crates are visible nowhere.
- Visibility::Invisible => return false,
- // Restricted items are visible in an arbitrary local module.
- Visibility::Restricted(other) if other.krate != module.krate => return false,
- Visibility::Restricted(module) => module,
- };
+impl<Id> Visibility<Id> {
+ pub fn is_public(self) -> bool {
+ matches!(self, Visibility::Public)
+ }
+
+ pub fn map_id<OutId>(self, f: impl FnOnce(Id) -> OutId) -> Visibility<OutId> {
+ match self {
+ Visibility::Public => Visibility::Public,
+ Visibility::Restricted(id) => Visibility::Restricted(f(id)),
+ }
+ }
+}
- tree.is_descendant_of(module, restriction)
+impl<Id: Into<DefId>> Visibility<Id> {
+ pub fn to_def_id(self) -> Visibility<DefId> {
+ self.map_id(Into::into)
+ }
+
+ /// Returns `true` if an item with this visibility is accessible from the given module.
+ pub fn is_accessible_from(self, module: impl Into<DefId>, tree: impl DefIdTree) -> bool {
+ match self {
+ // Public items are visible everywhere.
+ Visibility::Public => true,
+ Visibility::Restricted(id) => tree.is_descendant_of(module.into(), id.into()),
+ }
}
/// Returns `true` if this visibility is at least as accessible as the given visibility
- pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
- let vis_restriction = match vis {
- Visibility::Public => return self == Visibility::Public,
- Visibility::Invisible => return true,
- Visibility::Restricted(module) => module,
- };
+ pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tree: impl DefIdTree) -> bool {
+ match vis {
+ Visibility::Public => self.is_public(),
+ Visibility::Restricted(id) => self.is_accessible_from(id, tree),
+ }
+ }
+}
- self.is_accessible_from(vis_restriction, tree)
+impl Visibility<DefId> {
+ pub fn expect_local(self) -> Visibility {
+ self.map_id(|id| id.expect_local())
}
// Returns `true` if this item is visible anywhere in the local crate.
@@ -391,13 +405,8 @@ impl Visibility {
match self {
Visibility::Public => true,
Visibility::Restricted(def_id) => def_id.is_local(),
- Visibility::Invisible => false,
}
}
-
- pub fn is_public(self) -> bool {
- matches!(self, Visibility::Public)
- }
}
/// The crate variances map is computed during typeck and contains the
@@ -468,15 +477,6 @@ pub(crate) struct TyS<'tcx> {
outer_exclusive_binder: ty::DebruijnIndex,
}
-// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(TyS<'_>, 40);
-
-// We are actually storing a stable hash cache next to the type, so let's
-// also check the full size
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(WithStableHash<TyS<'_>>, 56);
-
/// Use this rather than `TyS`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[rustc_diagnostic_item = "Ty"]
@@ -533,10 +533,6 @@ pub(crate) struct PredicateS<'tcx> {
outer_exclusive_binder: ty::DebruijnIndex,
}
-// This type is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(PredicateS<'_>, 56);
-
/// Use this rather than `PredicateS`, whenever possible.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[rustc_pass_by_value]
@@ -593,6 +589,29 @@ impl<'tcx> Predicate<'tcx> {
}
self
}
+
+ /// Whether this projection can be soundly normalized.
+ ///
+ /// Wf predicates must not be normalized, as normalization
+ /// can remove required bounds which would cause us to
+ /// unsoundly accept some programs. See #91068.
+ #[inline]
+ pub fn allow_normalization(self) -> bool {
+ match self.kind().skip_binder() {
+ PredicateKind::WellFormed(_) => false,
+ PredicateKind::Trait(_)
+ | PredicateKind::RegionOutlives(_)
+ | PredicateKind::TypeOutlives(_)
+ | PredicateKind::Projection(_)
+ | PredicateKind::ObjectSafe(_)
+ | PredicateKind::ClosureKind(_, _, _)
+ | PredicateKind::Subtype(_)
+ | PredicateKind::Coerce(_)
+ | PredicateKind::ConstEvaluatable(_)
+ | PredicateKind::ConstEquate(_, _)
+ | PredicateKind::TypeWellFormedFromEnv(_) => true,
+ }
+ }
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
@@ -617,7 +636,7 @@ impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum PredicateKind<'tcx> {
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
@@ -789,7 +808,7 @@ impl<'tcx> Predicate<'tcx> {
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>,
@@ -869,7 +888,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
@@ -880,7 +899,7 @@ pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicat
/// whether the `a` type is the type that we should label as "expected" when
/// presenting user diagnostics.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct SubtypePredicate<'tcx> {
pub a_is_expected: bool,
pub a: Ty<'tcx>,
@@ -890,49 +909,142 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct CoercePredicate<'tcx> {
pub a: Ty<'tcx>,
pub b: Ty<'tcx>,
}
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
-pub enum Term<'tcx> {
- Ty(Ty<'tcx>),
- Const(Const<'tcx>),
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Term<'tcx> {
+ ptr: NonZeroUsize,
+ marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
+}
+
+impl Debug for Term<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let data = if let Some(ty) = self.ty() {
+ format!("Term::Ty({:?})", ty)
+ } else if let Some(ct) = self.ct() {
+ format!("Term::Ct({:?})", ct)
+ } else {
+ unreachable!()
+ };
+ f.write_str(&data)
+ }
}
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
fn from(ty: Ty<'tcx>) -> Self {
- Term::Ty(ty)
+ TermKind::Ty(ty).pack()
}
}
impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
fn from(c: Const<'tcx>) -> Self {
- Term::Const(c)
+ TermKind::Const(c).pack()
+ }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
+ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
+ self.unpack().hash_stable(hcx, hasher);
+ }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> {
+ fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+ Ok(self.unpack().try_fold_with(folder)?.pack())
+ }
+}
+
+impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> {
+ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+ self.unpack().visit_with(visitor)
+ }
+}
+
+impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Term<'tcx> {
+ fn encode(&self, e: &mut E) {
+ self.unpack().encode(e)
+ }
+}
+
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
+ fn decode(d: &mut D) -> Self {
+ let res: TermKind<'tcx> = Decodable::decode(d);
+ res.pack()
}
}
impl<'tcx> Term<'tcx> {
+ #[inline]
+ pub fn unpack(self) -> TermKind<'tcx> {
+ let ptr = self.ptr.get();
+ // SAFETY: use of `Interned::new_unchecked` here is ok because these
+ // pointers were originally created from `Interned` types in `pack()`,
+ // and this is just going in the other direction.
+ unsafe {
+ match ptr & TAG_MASK {
+ TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
+ &*((ptr & !TAG_MASK) as *const WithStableHash<ty::TyS<'tcx>>),
+ ))),
+ CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
+ &*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
+ ))),
+ _ => core::intrinsics::unreachable(),
+ }
+ }
+ }
+
pub fn ty(&self) -> Option<Ty<'tcx>> {
- if let Term::Ty(ty) = self { Some(*ty) } else { None }
+ if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None }
}
pub fn ct(&self) -> Option<Const<'tcx>> {
- if let Term::Const(c) = self { Some(*c) } else { None }
+ if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
}
pub fn into_arg(self) -> GenericArg<'tcx> {
- match self {
- Term::Ty(ty) => ty.into(),
- Term::Const(c) => c.into(),
+ match self.unpack() {
+ TermKind::Ty(ty) => ty.into(),
+ TermKind::Const(c) => c.into(),
}
}
}
+const TAG_MASK: usize = 0b11;
+const TYPE_TAG: usize = 0b00;
+const CONST_TAG: usize = 0b01;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable)]
+pub enum TermKind<'tcx> {
+ Ty(Ty<'tcx>),
+ Const(Const<'tcx>),
+}
+
+impl<'tcx> TermKind<'tcx> {
+ #[inline]
+ fn pack(self) -> Term<'tcx> {
+ let (tag, ptr) = match self {
+ TermKind::Ty(ty) => {
+ // Ensure we can use the tag bits.
+ assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
+ (TYPE_TAG, ty.0.0 as *const WithStableHash<ty::TyS<'tcx>> as usize)
+ }
+ TermKind::Const(ct) => {
+ // Ensure we can use the tag bits.
+ assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
+ (CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
+ }
+ };
+
+ Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
+ }
+}
+
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
@@ -946,7 +1058,7 @@ impl<'tcx> Term<'tcx> {
/// Form #2 eventually yields one of these `ProjectionPredicate`
/// instances to normalize the LHS.
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ProjectionPredicate<'tcx> {
pub projection_ty: ProjectionTy<'tcx>,
pub term: Term<'tcx>,
@@ -1002,6 +1114,12 @@ pub trait ToPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx>;
}
+impl<'tcx> ToPredicate<'tcx> for Predicate<'tcx> {
+ fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
+ self
+ }
+}
+
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
@@ -1166,20 +1284,17 @@ pub struct OpaqueHiddenType<'tcx> {
impl<'tcx> OpaqueHiddenType<'tcx> {
pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
// Found different concrete types for the opaque type.
- let mut err = tcx.sess.struct_span_err(
- other.span,
- "concrete type differs from previous defining opaque type use",
- );
- err.span_label(other.span, format!("expected `{}`, got `{}`", self.ty, other.ty));
- if self.span == other.span {
- err.span_label(
- self.span,
- "this expression supplies two conflicting concrete types for the same opaque type",
- );
+ let sub_diag = if self.span == other.span {
+ TypeMismatchReason::ConflictType { span: self.span }
} else {
- err.span_note(self.span, "previous use here");
- }
- err.emit();
+ TypeMismatchReason::PreviousUse { span: self.span }
+ };
+ tcx.sess.emit_err(OpaqueHiddenTypeMismatch {
+ self_ty: self.ty,
+ other_ty: other.ty,
+ other_span: other.span,
+ sub: sub_diag,
+ });
}
}
@@ -1411,7 +1526,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
Ok(ParamEnv::new(
self.caller_bounds().try_fold_with(folder)?,
self.reveal().try_fold_with(folder)?,
- self.constness().try_fold_with(folder)?,
+ self.constness(),
))
}
}
@@ -1419,8 +1534,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.caller_bounds().visit_with(visitor)?;
- self.reveal().visit_with(visitor)?;
- self.constness().visit_with(visitor)
+ self.reveal().visit_with(visitor)
}
}
@@ -1577,7 +1691,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
-#[derive(HashStable)]
+#[derive(HashStable, Lift)]
pub struct ParamEnvAnd<'tcx, T> {
pub param_env: ParamEnv<'tcx>,
pub value: T,
@@ -1779,7 +1893,7 @@ pub enum VariantDiscr {
pub struct FieldDef {
pub did: DefId,
pub name: Symbol,
- pub vis: Visibility,
+ pub vis: Visibility<DefId>,
}
impl PartialEq for FieldDef {
@@ -2256,7 +2370,11 @@ impl<'tcx> TyCtxt<'tcx> {
}
pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
- self.get_attrs(did, attr).next()
+ if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
+ bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
+ } else {
+ self.get_attrs(did, attr).next()
+ }
}
/// Determines whether an item is annotated with an attribute.
@@ -2358,6 +2476,25 @@ impl<'tcx> TyCtxt<'tcx> {
(ident, scope)
}
+ /// Returns `true` if the debuginfo for `span` should be collapsed to the outermost expansion
+ /// site. Only applies when `Span` is the result of macro expansion.
+ ///
+ /// - If the `collapse_debuginfo` feature is enabled then debuginfo is not collapsed by default
+ /// and only when a macro definition is annotated with `#[collapse_debuginfo]`.
+ /// - If `collapse_debuginfo` is not enabled, then debuginfo is collapsed by default.
+ ///
+ /// When `-Zdebug-macros` is provided then debuginfo will never be collapsed.
+ pub fn should_collapse_debuginfo(self, span: Span) -> bool {
+ !self.sess.opts.unstable_opts.debug_macros
+ && if self.features().collapse_debuginfo {
+ span.in_macro_expansion_with_collapse_debuginfo()
+ } else {
+ // Inlined spans should not be collapsed as that leads to all of the
+ // inlined code being attributed to the inline callsite.
+ span.from_expansion() && !span.is_inlined()
+ }
+ }
+
pub fn is_object_safe(self, key: DefId) -> bool {
self.object_safety_violations(key).is_empty()
}
@@ -2372,6 +2509,14 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn is_const_default_method(self, def_id: DefId) -> bool {
matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
}
+
+ pub fn impl_trait_in_trait_parent(self, mut def_id: DefId) -> DefId {
+ while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
+ debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
+ def_id = self.parent(def_id);
+ }
+ def_id
+ }
}
/// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition.
@@ -2516,3 +2661,14 @@ pub struct DestructuredConst<'tcx> {
pub variant: Option<VariantIdx>,
pub fields: &'tcx [ty::Const<'tcx>],
}
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+ use super::*;
+ use rustc_data_structures::static_assert_size;
+ // These are in alphabetical order, which is easy to maintain.
+ static_assert_size!(PredicateS<'_>, 48);
+ static_assert_size!(TyS<'_>, 40);
+ static_assert_size!(WithStableHash<TyS<'_>>, 56);
+}
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 9d8a81165..9db5a2894 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -36,6 +36,7 @@ impl<'tcx> TyCtxt<'tcx> {
///
/// This should only be used outside of type inference. For example,
/// it assumes that normalization will succeed.
+ #[tracing::instrument(level = "debug", skip(self, param_env))]
pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T
where
T: TypeFoldable<'tcx>,
@@ -100,6 +101,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// N.B., currently, higher-ranked type bounds inhibit
/// normalization. Therefore, each time we erase them in
/// codegen, we need to normalize the contents.
+ #[tracing::instrument(level = "debug", skip(self, param_env))]
pub fn normalize_erasing_late_bound_regions<T>(
self,
param_env: ty::ParamEnv<'tcx>,
@@ -188,13 +190,11 @@ struct NormalizeAfterErasingRegionsFolder<'tcx> {
}
impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
- #[instrument(skip(self), level = "debug")]
fn normalize_generic_arg_after_erasing_regions(
&self,
arg: ty::GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> {
let arg = self.param_env.and(arg);
- debug!(?arg);
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index e189ee2fc..9c8dc30e2 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -1,4 +1,4 @@
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, DefIndex};
use rustc_index::vec::{Idx, IndexVec};
use crate::middle::exported_symbols::ExportedSymbol;
@@ -53,17 +53,20 @@ trivially_parameterized_over_tcx! {
crate::metadata::ModChild,
crate::middle::codegen_fn_attrs::CodegenFnAttrs,
crate::middle::exported_symbols::SymbolExportInfo,
+ crate::middle::resolve_lifetime::ObjectLifetimeDefault,
crate::mir::ConstQualifs,
+ ty::AssocItemContainer,
ty::Generics,
ty::ImplPolarity,
ty::ReprOptions,
ty::TraitDef,
- ty::Visibility,
+ ty::Visibility<DefIndex>,
ty::adjustment::CoerceUnsizedInfo,
ty::fast_reject::SimplifiedTypeGen<DefId>,
rustc_ast::Attribute,
rustc_ast::MacArgs,
rustc_attr::ConstStability,
+ rustc_attr::DefaultBodyStability,
rustc_attr::Deprecation,
rustc_attr::Stability,
rustc_hir::Constness,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 7f2e81a71..97bddb93e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1,7 +1,7 @@
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
use crate::ty::{
- self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
+ self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
};
use rustc_apfloat::ieee::{Double, Single};
@@ -619,12 +619,16 @@ pub trait PrettyPrinter<'tcx>:
ty::Adt(def, substs) => {
p!(print_def_path(def.did(), substs));
}
- ty::Dynamic(data, r) => {
+ ty::Dynamic(data, r, repr) => {
let print_r = self.should_print_region(r);
if print_r {
p!("(");
}
- p!("dyn ", print(data));
+ match repr {
+ ty::Dyn => p!("dyn "),
+ ty::DynStar => p!("dyn* "),
+ }
+ p!(print(data));
if print_r {
p!(" + ", print(r), ")");
}
@@ -632,7 +636,13 @@ pub trait PrettyPrinter<'tcx>:
ty::Foreign(def_id) => {
p!(print_def_path(def_id, &[]));
}
- ty::Projection(ref data) => p!(print(data)),
+ ty::Projection(ref data) => {
+ if self.tcx().def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder {
+ return self.pretty_print_opaque_impl_type(data.item_def_id, data.substs);
+ } else {
+ p!(print(data))
+ }
+ }
ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
ty::Opaque(def_id, substs) => {
// FIXME(eddyb) print this with `print_def_path`.
@@ -855,7 +865,7 @@ pub trait PrettyPrinter<'tcx>:
}
p!(")");
- if let Term::Ty(ty) = return_ty.skip_binder() {
+ if let Some(ty) = return_ty.skip_binder().ty() {
if !ty.is_unit() {
p!(" -> ", print(return_ty));
}
@@ -916,12 +926,14 @@ pub trait PrettyPrinter<'tcx>:
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
// unless we can find out what generator return type it comes from.
let term = if let Some(ty) = term.skip_binder().ty()
- && let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind()
- && Some(*item_def_id) == tcx.lang_items().generator_return()
+ && let ty::Projection(proj) = ty.kind()
+ && let assoc = tcx.associated_item(proj.item_def_id)
+ && assoc.trait_container(tcx) == tcx.lang_items().gen_trait()
+ && assoc.name == rustc_span::sym::Return
{
if let ty::Generator(_, substs, _) = substs.type_at(0).kind() {
let return_ty = substs.as_generator().return_ty();
- if !return_ty.is_ty_infer() {
+ if !return_ty.is_ty_var() {
return_ty.into()
} else {
continue;
@@ -942,13 +954,9 @@ pub trait PrettyPrinter<'tcx>:
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
- match term {
- Term::Ty(ty) => {
- p!(print(ty))
- }
- Term::Const(c) => {
- p!(print(c));
- }
+ match term.unpack() {
+ TermKind::Ty(ty) => p!(print(ty)),
+ TermKind::Const(c) => p!(print(c)),
};
}
@@ -1193,15 +1201,9 @@ pub trait PrettyPrinter<'tcx>:
}
match ct.kind() {
- ty::ConstKind::Unevaluated(ty::Unevaluated {
- def,
- substs,
- promoted: Some(promoted),
- }) => {
- p!(print_value_path(def.did, substs));
- p!(write("::{:?}", promoted));
- }
- ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => {
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
+ assert_eq!(promoted, ());
+
match self.tcx().def_kind(def.did) {
DefKind::Static(..) | DefKind::Const | DefKind::AssocConst => {
p!(print_value_path(def.did, substs))
@@ -1275,7 +1277,7 @@ pub trait PrettyPrinter<'tcx>:
let range =
AllocRange { start: offset, size: Size::from_bytes(len) };
if let Ok(byte_str) =
- alloc.inner().get_bytes(&self.tcx(), range)
+ alloc.inner().get_bytes_strip_provenance(&self.tcx(), range)
{
p!(pretty_print_byte_str(byte_str))
} else {
@@ -1401,14 +1403,7 @@ pub trait PrettyPrinter<'tcx>:
}
fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
- define_scoped_cx!(self);
- p!("b\"");
- for &c in byte_str {
- for e in std::ascii::escape_default(c) {
- self.write_char(e as char)?;
- }
- }
- p!("\"");
+ write!(self, "b\"{}\"", byte_str.escape_ascii())?;
Ok(self)
}
@@ -1513,6 +1508,10 @@ pub trait PrettyPrinter<'tcx>:
}
return Ok(self);
}
+ (ty::ValTree::Leaf(leaf), ty::Ref(_, inner_ty, _)) => {
+ p!(write("&"));
+ return self.pretty_print_const_scalar_int(leaf, *inner_ty, print_ty);
+ }
(ty::ValTree::Leaf(leaf), _) => {
return self.pretty_print_const_scalar_int(leaf, ty, print_ty);
}
@@ -1532,6 +1531,34 @@ pub trait PrettyPrinter<'tcx>:
}
Ok(self)
}
+
+ fn pretty_closure_as_impl(
+ mut self,
+ closure: ty::ClosureSubsts<'tcx>,
+ ) -> Result<Self::Const, Self::Error> {
+ let sig = closure.sig();
+ let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
+
+ write!(self, "impl ")?;
+ self.wrap_binder(&sig, |sig, mut cx| {
+ define_scoped_cx!(cx);
+
+ p!(print(kind), "(");
+ for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
+ if i > 0 {
+ p!(", ");
+ }
+ p!(print(arg));
+ }
+ p!(")");
+
+ if !sig.output().is_unit() {
+ p!(" -> ", print(sig.output()));
+ }
+
+ Ok(cx)
+ })
+ }
}
// HACK(eddyb) boxed to avoid moving around a large struct by-value.
@@ -1950,7 +1977,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
ty::ReVar(_) | ty::ReErased => false,
- ty::ReStatic | ty::ReEmpty(_) => true,
+ ty::ReStatic => true,
}
}
@@ -2034,14 +2061,6 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
p!("'static");
return Ok(self);
}
- ty::ReEmpty(ty::UniverseIndex::ROOT) => {
- p!("'<empty>");
- return Ok(self);
- }
- ty::ReEmpty(ui) => {
- p!(write("'<empty:{:?}>", ui));
- return Ok(self);
- }
}
p!("'_");
@@ -2446,6 +2465,11 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
}
}
+#[derive(Debug, Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
+pub struct PrintClosureAsImpl<'tcx> {
+ pub closure: ty::ClosureSubsts<'tcx>,
+}
+
forward_display_to_print! {
ty::Region<'tcx>,
Ty<'tcx>,
@@ -2538,6 +2562,10 @@ define_print_and_forward_display! {
p!(print(self.0.trait_ref.print_only_trait_path()));
}
+ PrintClosureAsImpl<'tcx> {
+ p!(pretty_closure_as_impl(self.closure))
+ }
+
ty::ParamTy {
p!(write("{}", self.name))
}
@@ -2567,9 +2595,9 @@ define_print_and_forward_display! {
}
ty::Term<'tcx> {
- match self {
- ty::Term::Ty(ty) => p!(print(ty)),
- ty::Term::Const(c) => p!(print(c)),
+ match self.unpack() {
+ ty::TermKind::Ty(ty) => p!(print(ty)),
+ ty::TermKind::Const(c) => p!(print(c)),
}
}
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 2452bcf6a..a300a8df2 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -121,8 +121,8 @@ macro_rules! query_storage {
([][$K:ty, $V:ty]) => {
<DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
};
- ([(storage $ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
- <$ty as CacheSelector<$K, $V>>::Cache
+ ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
+ <ArenaCacheSelector<'tcx> as CacheSelector<$K, $V>>::Cache
};
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
query_storage!([$($modifiers)*][$($args)*])
@@ -173,7 +173,7 @@ macro_rules! opt_remap_env_constness {
}
macro_rules! define_callbacks {
- (<$tcx:tt>
+ (
$($(#[$attr:meta])*
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
@@ -187,33 +187,33 @@ macro_rules! define_callbacks {
pub mod query_keys {
use super::*;
- $(pub type $name<$tcx> = $($K)*;)*
+ $(pub type $name<'tcx> = $($K)*;)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_values {
use super::*;
- $(pub type $name<$tcx> = $V;)*
+ $(pub type $name<'tcx> = $V;)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_storage {
use super::*;
- $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
+ $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_stored {
use super::*;
- $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
+ $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
}
#[derive(Default)]
- pub struct QueryCaches<$tcx> {
- $($(#[$attr])* pub $name: query_storage::$name<$tcx>,)*
+ pub struct QueryCaches<'tcx> {
+ $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
}
- impl<$tcx> TyCtxtEnsure<$tcx> {
+ impl<'tcx> TyCtxtEnsure<'tcx> {
$($(#[$attr])*
#[inline(always)]
pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
@@ -231,20 +231,20 @@ macro_rules! define_callbacks {
})*
}
- impl<$tcx> TyCtxt<$tcx> {
+ impl<'tcx> TyCtxt<'tcx> {
$($(#[$attr])*
#[inline(always)]
#[must_use]
- pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
+ pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
{
self.at(DUMMY_SP).$name(key)
})*
}
- impl<$tcx> TyCtxtAt<$tcx> {
+ impl<'tcx> TyCtxtAt<'tcx> {
$($(#[$attr])*
#[inline(always)]
- pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
+ pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
{
let key = key.into_query_param();
opt_remap_env_constness!([$($modifiers)*][key]);
@@ -311,11 +311,11 @@ macro_rules! define_callbacks {
$($(#[$attr])*
fn $name(
&'tcx self,
- tcx: TyCtxt<$tcx>,
+ tcx: TyCtxt<'tcx>,
span: Span,
- key: query_keys::$name<$tcx>,
+ key: query_keys::$name<'tcx>,
mode: QueryMode,
- ) -> Option<query_stored::$name<$tcx>>;)*
+ ) -> Option<query_stored::$name<'tcx>>;)*
}
};
}
@@ -332,7 +332,7 @@ macro_rules! define_callbacks {
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.
-rustc_query_append! { [define_callbacks!][<'tcx>] }
+rustc_query_append! { define_callbacks! }
mod sealed {
use super::{DefId, LocalDefId};
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 818affa71..61c34730d 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -6,7 +6,7 @@
use crate::ty::error::{ExpectedFound, TypeError};
use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
-use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
use rustc_hir as ast;
use rustc_hir::def_id::DefId;
use rustc_span::DUMMY_SP;
@@ -441,7 +441,9 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
(&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(tcx.mk_foreign(a_id)),
- (&ty::Dynamic(a_obj, a_region), &ty::Dynamic(b_obj, b_region)) => {
+ (&ty::Dynamic(a_obj, a_region, a_repr), &ty::Dynamic(b_obj, b_region, b_repr))
+ if a_repr == b_repr =>
+ {
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
relation.relate_with_variance(
ty::Contravariant,
@@ -450,7 +452,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
b_region,
)
})?;
- Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound))
+ Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound, a_repr))
}
(&ty::Generator(a_id, a_substs, movability), &ty::Generator(b_id, b_substs, _))
@@ -572,8 +574,8 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
/// it.
pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
- a: ty::Const<'tcx>,
- b: ty::Const<'tcx>,
+ mut a: ty::Const<'tcx>,
+ mut b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
let tcx = relation.tcx();
@@ -594,9 +596,16 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
);
}
- let eagerly_eval = |x: ty::Const<'tcx>| x.eval(tcx, relation.param_env());
- let a = eagerly_eval(a);
- let b = eagerly_eval(b);
+ // HACK(const_generics): We still need to eagerly evaluate consts when
+ // relating them because during `normalize_param_env_or_error`,
+ // we may relate an evaluated constant in a obligation against
+ // an unnormalized (i.e. unevaluated) const in the param-env.
+ // FIXME(generic_const_exprs): Once we always lazily unify unevaluated constants
+ // these `eval` calls can be removed.
+ if !relation.tcx().features().generic_const_exprs {
+ a = a.eval(tcx, relation.param_env());
+ b = b.eval(tcx, relation.param_env());
+ }
// Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding
@@ -617,7 +626,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
if tcx.features().generic_const_exprs =>
{
- tcx.try_unify_abstract_consts(relation.param_env().and((au.shrink(), bu.shrink())))
+ tcx.try_unify_abstract_consts(relation.param_env().and((au, bu)))
}
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
@@ -626,6 +635,8 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
if au.def == bu.def && au.promoted == bu.promoted =>
{
+ assert_eq!(au.promoted, ());
+
let substs = relation.relate_with_variance(
ty::Variance::Invariant,
ty::VarianceDiagInfo::default(),
@@ -636,7 +647,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: au.def,
substs,
- promoted: au.promoted,
+ promoted: (),
}),
ty: a.ty(),
}));
@@ -803,15 +814,15 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
}
}
-impl<'tcx> Relate<'tcx> for ty::Term<'tcx> {
+impl<'tcx> Relate<'tcx> for Term<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: Self,
b: Self,
) -> RelateResult<'tcx, Self> {
- Ok(match (a, b) {
- (Term::Ty(a), Term::Ty(b)) => relation.relate(a, b)?.into(),
- (Term::Const(a), Term::Const(b)) => relation.relate(a, b)?.into(),
+ Ok(match (a.unpack(), b.unpack()) {
+ (TermKind::Ty(a), TermKind::Ty(b)) => relation.relate(a, b)?.into(),
+ (TermKind::Const(a), TermKind::Const(b)) => relation.relate(a, b)?.into(),
_ => return Err(TypeError::Mismatch),
})
}
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 7660a2f3a..84d6a8b97 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -3,13 +3,12 @@
//! hand, though we've recently added some macros and proc-macros to help with the tedium.
use crate::mir::interpret;
-use crate::mir::ProjectionKind;
+use crate::mir::{Field, ProjectionKind};
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
-use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
+use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
use rustc_data_structures::functor::IdFunctor;
-use rustc_hir as hir;
use rustc_hir::def::Namespace;
use rustc_index::vec::{Idx, IndexVec};
@@ -238,12 +237,24 @@ TrivialTypeTraversalAndLiftImpls! {
crate::ty::Variance,
::rustc_span::Span,
::rustc_errors::ErrorGuaranteed,
+ Field,
+ interpret::Scalar,
+ rustc_target::abi::Size,
+ ty::DelaySpanBugEmitted,
+ rustc_type_ir::DebruijnIndex,
+ ty::BoundVar,
+ ty::Placeholder<ty::BoundVar>,
+}
+
+TrivialTypeTraversalAndLiftImpls! {
+ for<'tcx> {
+ ty::ValTree<'tcx>,
+ }
}
///////////////////////////////////////////////////////////////////////////
// Lift implementations
-// FIXME(eddyb) replace all the uses of `Option::map` with `?`.
impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
type Lifted = (A::Lifted, B::Lifted);
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@@ -261,10 +272,10 @@ impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C)
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
type Lifted = Option<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- match self {
- Some(x) => tcx.lift(x).map(Some),
- None => Some(None),
- }
+ Some(match self {
+ Some(x) => Some(tcx.lift(x)?),
+ None => None,
+ })
}
}
@@ -281,21 +292,21 @@ impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
type Lifted = Box<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(*self).map(Box::new)
+ Some(Box::new(tcx.lift(*self)?))
}
}
impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> {
type Lifted = Rc<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.as_ref().clone()).map(Rc::new)
+ Some(Rc::new(tcx.lift(self.as_ref().clone())?))
}
}
impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> {
type Lifted = Arc<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.as_ref().clone()).map(Arc::new)
+ Some(Arc::new(tcx.lift(self.as_ref().clone())?))
}
}
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
@@ -312,159 +323,18 @@ impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
}
}
-impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
- type Lifted = ty::TraitRef<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
- type Lifted = ty::ExistentialTraitRef<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
- type Lifted = ty::ExistentialPredicate<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- match self {
- ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait),
- ty::ExistentialPredicate::Projection(x) => {
- tcx.lift(x).map(ty::ExistentialPredicate::Projection)
- }
- ty::ExistentialPredicate::AutoTrait(def_id) => {
- Some(ty::ExistentialPredicate::AutoTrait(def_id))
- }
- }
- }
-}
-
impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
type Lifted = ty::Term<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- Some(match self {
- Term::Ty(ty) => Term::Ty(tcx.lift(ty)?),
- Term::Const(c) => Term::Const(tcx.lift(c)?),
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
- type Lifted = ty::TraitPredicate<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
- tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate {
- trait_ref,
- constness: self.constness,
- polarity: self.polarity,
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
- type Lifted = ty::SubtypePredicate<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::SubtypePredicate<'tcx>> {
- tcx.lift((self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
- a_is_expected: self.a_is_expected,
- a,
- b,
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::CoercePredicate<'a> {
- type Lifted = ty::CoercePredicate<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::CoercePredicate<'tcx>> {
- tcx.lift((self.a, self.b)).map(|(a, b)| ty::CoercePredicate { a, b })
- }
-}
-
-impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
- type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift((self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
- type Lifted = ty::ProjectionTy<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
- tcx.lift(self.substs)
- .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
- type Lifted = ty::ProjectionPredicate<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
- tcx.lift((self.projection_ty, self.term))
- .map(|(projection_ty, term)| ty::ProjectionPredicate { projection_ty, term })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
- type Lifted = ty::ExistentialProjection<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.substs).map(|substs| ty::ExistentialProjection {
- substs,
- term: tcx.lift(self.term).expect("type must lift when substs do"),
- item_def_id: self.item_def_id,
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
- type Lifted = ty::PredicateKind<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- match self {
- ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait),
- ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype),
- ty::PredicateKind::Coerce(data) => tcx.lift(data).map(ty::PredicateKind::Coerce),
- ty::PredicateKind::RegionOutlives(data) => {
- tcx.lift(data).map(ty::PredicateKind::RegionOutlives)
- }
- ty::PredicateKind::TypeOutlives(data) => {
- tcx.lift(data).map(ty::PredicateKind::TypeOutlives)
- }
- ty::PredicateKind::Projection(data) => {
- tcx.lift(data).map(ty::PredicateKind::Projection)
- }
- ty::PredicateKind::WellFormed(ty) => tcx.lift(ty).map(ty::PredicateKind::WellFormed),
- ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
- tcx.lift(closure_substs).map(|closure_substs| {
- ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind)
- })
- }
- ty::PredicateKind::ObjectSafe(trait_def_id) => {
- Some(ty::PredicateKind::ObjectSafe(trait_def_id))
- }
- ty::PredicateKind::ConstEvaluatable(uv) => {
- tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv))
- }
- ty::PredicateKind::ConstEquate(c1, c2) => {
- tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2))
- }
- ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
- tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv)
+ Some(
+ match self.unpack() {
+ TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
+ TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
}
- }
+ .pack(),
+ )
}
}
-
-impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<'a, T>
-where
- <T as Lift<'tcx>>::Lifted: TypeVisitable<'tcx>,
-{
- type Lifted = ty::Binder<'tcx, T::Lifted>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- let bound_vars = tcx.lift(self.bound_vars());
- tcx.lift(self.skip_binder())
- .zip(bound_vars)
- .map(|(value, vars)| ty::Binder::bind_with_vars(value, vars))
- }
-}
-
impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
type Lifted = ty::ParamEnv<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@@ -473,178 +343,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
}
}
-impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
- type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.param_env).and_then(|param_env| {
- tcx.lift(self.value).map(|value| ty::ParamEnvAnd { param_env, value })
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
- type Lifted = ty::ClosureSubsts<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.substs).map(|substs| ty::ClosureSubsts { substs })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
- type Lifted = ty::GeneratorSubsts<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.substs).map(|substs| ty::GeneratorSubsts { substs })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
- type Lifted = ty::adjustment::Adjustment<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- let ty::adjustment::Adjustment { kind, target } = self;
- tcx.lift(kind).and_then(|kind| {
- tcx.lift(target).map(|target| ty::adjustment::Adjustment { kind, target })
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
- type Lifted = ty::adjustment::Adjust<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- match self {
- ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny),
- ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)),
- ty::adjustment::Adjust::Deref(overloaded) => {
- tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
- }
- ty::adjustment::Adjust::Borrow(autoref) => {
- tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
- }
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
- type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.region).map(|region| ty::adjustment::OverloadedDeref {
- region,
- mutbl: self.mutbl,
- span: self.span,
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
- type Lifted = ty::adjustment::AutoBorrow<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- match self {
- ty::adjustment::AutoBorrow::Ref(r, m) => {
- tcx.lift(r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
- }
- ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)),
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
- type Lifted = ty::GenSig<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift((self.resume_ty, self.yield_ty, self.return_ty))
- .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
- type Lifted = ty::FnSig<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- tcx.lift(self.inputs_and_output).map(|x| ty::FnSig {
- inputs_and_output: x,
- c_variadic: self.c_variadic,
- unsafety: self.unsafety,
- abi: self.abi,
- })
- }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
- type Lifted = ty::error::ExpectedFound<T::Lifted>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- let ty::error::ExpectedFound { expected, found } = self;
- tcx.lift(expected).and_then(|expected| {
- tcx.lift(found).map(|found| ty::error::ExpectedFound { expected, found })
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
- type Lifted = ty::error::TypeError<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- use crate::ty::error::TypeError::*;
-
- Some(match self {
- Mismatch => Mismatch,
- ConstnessMismatch(x) => ConstnessMismatch(x),
- PolarityMismatch(x) => PolarityMismatch(x),
- UnsafetyMismatch(x) => UnsafetyMismatch(x),
- AbiMismatch(x) => AbiMismatch(x),
- Mutability => Mutability,
- ArgumentMutability(i) => ArgumentMutability(i),
- TupleSize(x) => TupleSize(x),
- FixedArraySize(x) => FixedArraySize(x),
- ArgCount => ArgCount,
- FieldMisMatch(x, y) => FieldMisMatch(x, y),
- RegionsDoesNotOutlive(a, b) => {
- return tcx.lift((a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b));
- }
- RegionsInsufficientlyPolymorphic(a, b) => {
- return tcx.lift(b).map(|b| RegionsInsufficientlyPolymorphic(a, b));
- }
- RegionsOverlyPolymorphic(a, b) => {
- return tcx.lift(b).map(|b| RegionsOverlyPolymorphic(a, b));
- }
- RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
- IntMismatch(x) => IntMismatch(x),
- FloatMismatch(x) => FloatMismatch(x),
- Traits(x) => Traits(x),
- VariadicMismatch(x) => VariadicMismatch(x),
- CyclicTy(t) => return tcx.lift(t).map(|t| CyclicTy(t)),
- CyclicConst(ct) => return tcx.lift(ct).map(|ct| CyclicConst(ct)),
- ProjectionMismatched(x) => ProjectionMismatched(x),
- ArgumentSorts(x, i) => return tcx.lift(x).map(|x| ArgumentSorts(x, i)),
- Sorts(x) => return tcx.lift(x).map(Sorts),
- ExistentialMismatch(x) => return tcx.lift(x).map(ExistentialMismatch),
- ConstMismatch(x) => return tcx.lift(x).map(ConstMismatch),
- IntrinsicCast => IntrinsicCast,
- TargetFeatureCast(x) => TargetFeatureCast(x),
- ObjectUnsafeCoercion(x) => return tcx.lift(x).map(ObjectUnsafeCoercion),
- })
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
- type Lifted = ty::InstanceDef<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- match self {
- ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)),
- ty::InstanceDef::VTableShim(def_id) => Some(ty::InstanceDef::VTableShim(def_id)),
- ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)),
- ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
- ty::InstanceDef::FnPtrShim(def_id, ty) => {
- Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
- }
- ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)),
- ty::InstanceDef::ClosureOnceShim { call_once, track_caller } => {
- Some(ty::InstanceDef::ClosureOnceShim { call_once, track_caller })
- }
- ty::InstanceDef::DropGlue(def_id, ty) => {
- Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?))
- }
- ty::InstanceDef::CloneShim(def_id, ty) => {
- Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?))
- }
- }
- }
-}
-
///////////////////////////////////////////////////////////////////////////
// TypeFoldable implementations.
@@ -844,6 +542,12 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> {
}
}
+impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] {
+ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+ self.iter().try_for_each(|t| t.visit_with(visitor))
+ }
+}
+
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self.try_map_id(|t| t.try_fold_with(folder))
@@ -901,88 +605,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::Existentia
}
}
-impl<'tcx> TypeVisitable<'tcx>
- for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
-{
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.iter().try_for_each(|p| p.visit_with(visitor))
- }
-}
-
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
}
}
-impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<ProjectionKind> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.iter().try_for_each(|t| t.visit_with(visitor))
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- use crate::ty::InstanceDef::*;
- Ok(Self {
- substs: self.substs.try_fold_with(folder)?,
- def: match self.def {
- Item(def) => Item(def.try_fold_with(folder)?),
- VTableShim(did) => VTableShim(did.try_fold_with(folder)?),
- ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?),
- Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?),
- FnPtrShim(did, ty) => {
- FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
- }
- Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i),
- ClosureOnceShim { call_once, track_caller } => {
- ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller }
- }
- DropGlue(did, ty) => {
- DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
- }
- CloneShim(did, ty) => {
- CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
- }
- },
- })
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for ty::instance::Instance<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- use crate::ty::InstanceDef::*;
- self.substs.visit_with(visitor)?;
- match self.def {
- Item(def) => def.visit_with(visitor),
- VTableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
- did.visit_with(visitor)
- }
- FnPtrShim(did, ty) | CloneShim(did, ty) => {
- did.visit_with(visitor)?;
- ty.visit_with(visitor)
- }
- DropGlue(did, ty) => {
- did.visit_with(visitor)?;
- ty.visit_with(visitor)
- }
- ClosureOnceShim { call_once, track_caller: _ } => call_once.visit_with(visitor),
- }
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted })
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for interpret::GlobalId<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.instance.visit_with(visitor)
- }
-}
-
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_ty(self)
@@ -1005,9 +633,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
- ty::Dynamic(trait_ty, region) => {
- ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?)
- }
+ ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
+ trait_ty.try_fold_with(folder)?,
+ region.try_fold_with(folder)?,
+ representation,
+ ),
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
@@ -1051,7 +681,7 @@ impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
}
ty::Slice(typ) => typ.visit_with(visitor),
ty::Adt(_, substs) => substs.visit_with(visitor),
- ty::Dynamic(ref trait_ty, ref reg) => {
+ ty::Dynamic(ref trait_ty, ref reg, _) => {
trait_ty.visit_with(visitor)?;
reg.visit_with(visitor)
}
@@ -1156,12 +786,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
}
}
-impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.iter().try_for_each(|p| p.visit_with(visitor))
- }
-}
-
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self.try_map_id(|x| x.try_fold_with(folder))
@@ -1208,34 +832,6 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> {
}
}
-impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
- Ok(match self {
- ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?),
- ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?),
- ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?),
- ty::ConstKind::Value(_)
- | ty::ConstKind::Bound(..)
- | ty::ConstKind::Placeholder(..)
- | ty::ConstKind::Error(_) => self,
- })
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for ty::ConstKind<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- match *self {
- ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
- ty::ConstKind::Param(p) => p.visit_with(visitor),
- ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
- ty::ConstKind::Value(_)
- | ty::ConstKind::Bound(..)
- | ty::ConstKind::Placeholder(_)
- | ty::ConstKind::Error(_) => ControlFlow::CONTINUE,
- }
- }
-}
-
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
Ok(self)
@@ -1290,15 +886,3 @@ impl<'tcx> TypeVisitable<'tcx> for ty::Unevaluated<'tcx, ()> {
self.expand().visit_with(visitor)
}
}
-
-impl<'tcx> TypeFoldable<'tcx> for hir::Constness {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
- Ok(self)
- }
-}
-
-impl<'tcx> TypeVisitable<'tcx> for hir::Constness {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
- ControlFlow::CONTINUE
- }
-}
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 52c3a3886..36e560850 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -11,6 +11,7 @@ use crate::ty::{
TypeVisitor,
};
use crate::ty::{List, ParamEnv};
+use hir::def::DefKind;
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
@@ -201,7 +202,7 @@ static_assert_size!(TyKind<'_>, 32);
/// * `GR`: The "return type", which is the type of value returned upon
/// completion of the generator.
/// * `GW`: The "generator witness".
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct ClosureSubsts<'tcx> {
/// Lifetime and type parameters from the enclosing function,
/// concatenated with a tuple containing the types of the upvars.
@@ -325,10 +326,14 @@ impl<'tcx> ClosureSubsts<'tcx> {
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
}
}
+
+ pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> {
+ ty::print::PrintClosureAsImpl { closure: self }
+ }
}
/// Similar to `ClosureSubsts`; see the above documentation for more.
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct GeneratorSubsts<'tcx> {
pub substs: SubstsRef<'tcx>,
}
@@ -655,7 +660,7 @@ impl<'tcx> InlineConstSubsts<'tcx> {
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum ExistentialPredicate<'tcx> {
/// E.g., `Iterator`.
Trait(ExistentialTraitRef<'tcx>),
@@ -687,6 +692,9 @@ impl<'tcx> ExistentialPredicate<'tcx> {
}
impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> {
+ /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
+ /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
+ /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
use crate::ty::ToPredicate;
match self.skip_binder() {
@@ -781,7 +789,7 @@ impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
pub substs: SubstsRef<'tcx>,
@@ -845,6 +853,12 @@ impl<'tcx> PolyTraitRef<'tcx> {
}
}
+impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
/// An existential reference to a trait, where `Self` is erased.
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
/// ```ignore (illustrative)
@@ -853,7 +867,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialTraitRef<'tcx> {
pub def_id: DefId,
pub substs: SubstsRef<'tcx>,
@@ -1009,7 +1023,7 @@ impl BoundVariableKind {
///
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(HashStable)]
+#[derive(HashStable, Lift)]
pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
impl<'tcx, T> Binder<'tcx, T>
@@ -1171,7 +1185,7 @@ impl<'tcx, T> Binder<'tcx, Option<T>> {
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ProjectionTy<'tcx> {
/// The parameters of the associated item.
pub substs: SubstsRef<'tcx>,
@@ -1186,7 +1200,9 @@ pub struct ProjectionTy<'tcx> {
impl<'tcx> ProjectionTy<'tcx> {
pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
- tcx.parent(self.item_def_id)
+ let parent = tcx.parent(self.item_def_id);
+ assert_eq!(tcx.def_kind(parent), DefKind::Trait);
+ parent
}
/// Extracts the underlying trait reference and own substs from this projection.
@@ -1221,7 +1237,7 @@ impl<'tcx> ProjectionTy<'tcx> {
}
}
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct GenSig<'tcx> {
pub resume_ty: Ty<'tcx>,
pub yield_ty: Ty<'tcx>,
@@ -1237,7 +1253,7 @@ pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>;
/// - `output`: is the return type.
/// - `c_variadic`: indicates whether this is a C-variadic function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct FnSig<'tcx> {
pub inputs_and_output: &'tcx List<Ty<'tcx>>,
pub c_variadic: bool,
@@ -1419,7 +1435,7 @@ impl From<BoundVar> for BoundTy {
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialProjection<'tcx> {
pub item_def_id: DefId,
pub substs: SubstsRef<'tcx>,
@@ -1501,7 +1517,6 @@ impl<'tcx> Region<'tcx> {
ty::ReStatic => true,
ty::ReVar(..) => false,
ty::RePlaceholder(placeholder) => placeholder.name.is_named(),
- ty::ReEmpty(_) => false,
ty::ReErased => false,
}
}
@@ -1527,11 +1542,6 @@ impl<'tcx> Region<'tcx> {
}
#[inline]
- pub fn is_empty(self) -> bool {
- matches!(*self, ty::ReEmpty(..))
- }
-
- #[inline]
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
match *self {
ty::ReLateBound(debruijn, _) => debruijn >= index,
@@ -1562,7 +1572,7 @@ impl<'tcx> Region<'tcx> {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
}
- ty::ReEmpty(_) | ty::ReStatic => {
+ ty::ReStatic => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
}
ty::ReLateBound(..) => {
@@ -1617,6 +1627,10 @@ impl<'tcx> Region<'tcx> {
_ => self.is_free(),
}
}
+
+ pub fn is_var(self) -> bool {
+ matches!(self.kind(), ty::ReVar(_))
+ }
}
/// Type utilities
@@ -1838,7 +1852,12 @@ impl<'tcx> Ty<'tcx> {
#[inline]
pub fn is_trait(self) -> bool {
- matches!(self.kind(), Dynamic(..))
+ matches!(self.kind(), Dynamic(_, _, ty::Dyn))
+ }
+
+ #[inline]
+ pub fn is_dyn_star(self) -> bool {
+ matches!(self.kind(), Dynamic(_, _, ty::DynStar))
}
#[inline]
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 6262aa180..8e69bf067 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -459,12 +459,6 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
}
}
-impl<'tcx> TypeVisitable<'tcx> for SubstsRef<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
- self.iter().try_for_each(|t| t.visit_with(visitor))
- }
-}
-
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
// This code is fairly hot, though not as hot as `SubstsRef`.
@@ -497,7 +491,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
}
}
-impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
+impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor))
}
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 541dace5c..ac79949fc 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -256,7 +256,6 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
}
// Query provider for `incoherent_impls`.
-#[instrument(level = "debug", skip(tcx))]
pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] {
let mut impls = Vec::new();
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 591bb7831..23ad4d27d 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -627,7 +627,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Expands the given impl trait type, stopping if the type is recursive.
- #[instrument(skip(self), level = "debug")]
+ #[instrument(skip(self), level = "debug", ret)]
pub fn try_expand_impl_trait_type(
self,
def_id: DefId,
@@ -644,7 +644,6 @@ impl<'tcx> TyCtxt<'tcx> {
};
let expanded_type = visitor.expand_opaque_ty(def_id, substs).unwrap();
- trace!(?expanded_type);
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
}
@@ -652,6 +651,13 @@ impl<'tcx> TyCtxt<'tcx> {
ty::EarlyBinder(self.type_of(def_id))
}
+ pub fn bound_trait_impl_trait_tys(
+ self,
+ def_id: DefId,
+ ) -> ty::EarlyBinder<Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>> {
+ ty::EarlyBinder(self.collect_trait_impl_trait_tys(def_id))
+ }
+
pub fn bound_fn_sig(self, def_id: DefId) -> ty::EarlyBinder<ty::PolyFnSig<'tcx>> {
ty::EarlyBinder(self.fn_sig(def_id))
}
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 536506720..5f8cb5782 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -84,7 +84,7 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone {
self.has_vars_bound_at_or_above(ty::INNERMOST)
}
- #[instrument(level = "trace")]
+ #[instrument(level = "trace", ret)]
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags)
}
@@ -560,7 +560,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
type BreakTy = FoundFlags;
#[inline]
- #[instrument(skip(self), level = "trace")]
+ #[instrument(skip(self), level = "trace", ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = t.flags();
trace!(t.flags=?t.flags());
@@ -572,7 +572,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}
#[inline]
- #[instrument(skip(self), level = "trace")]
+ #[instrument(skip(self), level = "trace", ret)]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = r.type_flags();
trace!(r.flags=?flags);
@@ -584,7 +584,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}
#[inline]
- #[instrument(level = "trace")]
+ #[instrument(level = "trace", ret)]
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = FlagComputation::for_const(c);
trace!(r.flags=?flags);
@@ -596,7 +596,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}
#[inline]
- #[instrument(level = "trace")]
+ #[instrument(level = "trace", ret)]
fn visit_unevaluated(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = FlagComputation::for_unevaluated_const(uv);
trace!(r.flags=?flags);
@@ -608,7 +608,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}
#[inline]
- #[instrument(level = "trace")]
+ #[instrument(level = "trace", ret)]
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
debug!(
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
@@ -666,7 +666,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
// ignore the inputs to a projection, as they may not appear
// in the normalized form
if self.just_constrained {
- if let ty::Projection(..) = t.kind() {
+ if let ty::Projection(..) | ty::Opaque(..) = t.kind() {
return ControlFlow::CONTINUE;
}
}
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index 04a9fd1f7..5ca51c25a 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -1,7 +1,7 @@
use std::convert::TryFrom;
use std::fmt;
-use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar, ScalarMaybeUninit};
+use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar};
use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
use rustc_ast::Mutability;
@@ -87,7 +87,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id);
- ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
+ Scalar::from_pointer(fn_ptr, &tcx)
}
VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(),
VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(),
@@ -97,14 +97,14 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let instance = instance.polymorphize(tcx);
let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id);
- ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
+ Scalar::from_pointer(fn_ptr, &tcx)
}
VtblEntry::TraitVPtr(trait_ref) => {
let super_trait_ref = trait_ref
.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref)));
let vptr = Pointer::from(supertrait_alloc_id);
- ScalarMaybeUninit::from_pointer(vptr, &tcx)
+ Scalar::from_pointer(vptr, &tcx)
}
};
vtable
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 02fe1f3a7..a3e11bbf0 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -152,7 +152,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
ty::Projection(data) => {
stack.extend(data.substs.iter().rev());
}
- ty::Dynamic(obj, lt) => {
+ ty::Dynamic(obj, lt, _) => {
stack.push(lt.into());
stack.extend(obj.iter().rev().flat_map(|predicate| {
let (substs, opt_ty) = match predicate.skip_binder() {
@@ -165,9 +165,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
}
};
- substs.iter().rev().chain(opt_ty.map(|term| match term {
- ty::Term::Ty(ty) => ty.into(),
- ty::Term::Const(ct) => ct.into(),
+ substs.iter().rev().chain(opt_ty.map(|term| match term.unpack() {
+ ty::TermKind::Ty(ty) => ty.into(),
+ ty::TermKind::Const(ct) => ct.into(),
}))
}));
}
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
new file mode 100644
index 000000000..7fbe9ae2a
--- /dev/null
+++ b/compiler/rustc_middle/src/values.rs
@@ -0,0 +1,54 @@
+use rustc_middle::ty::{self, AdtSizedConstraint, Ty, TyCtxt};
+use rustc_query_system::Value;
+
+impl<'tcx> Value<TyCtxt<'tcx>> for Ty<'_> {
+ fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+ // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
+ // FIXME: Represent the above fact in the trait system somehow.
+ unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
+ }
+}
+
+impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
+ fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+ // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
+ // FIXME: Represent the above fact in the trait system somehow.
+ unsafe {
+ std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
+ tcx, "<error>",
+ ))
+ }
+ }
+}
+
+impl<'tcx> Value<TyCtxt<'tcx>> for AdtSizedConstraint<'_> {
+ fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+ // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
+ // FIXME: Represent the above fact in the trait system somehow.
+ unsafe {
+ std::mem::transmute::<AdtSizedConstraint<'tcx>, AdtSizedConstraint<'_>>(
+ AdtSizedConstraint(tcx.intern_type_list(&[tcx.ty_error()])),
+ )
+ }
+ }
+}
+
+impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
+ fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+ let err = tcx.ty_error();
+ // FIXME(compiler-errors): It would be nice if we could get the
+ // query key, so we could at least generate a fn signature that
+ // has the right arity.
+ let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
+ [].into_iter(),
+ err,
+ false,
+ rustc_hir::Unsafety::Normal,
+ rustc_target::spec::abi::Abi::Rust,
+ ));
+
+ // SAFETY: This is never called when `Self` is not `ty::Binder<'tcx, ty::FnSig<'tcx>>`.
+ // FIXME: Represent the above fact in the trait system somehow.
+ unsafe { std::mem::transmute::<ty::PolyFnSig<'tcx>, ty::Binder<'_, ty::FnSig<'_>>>(fn_sig) }
+ }
+}
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 687560012..784583d94 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -1,6 +1,7 @@
use crate::build::matches::ArmHasGuard;
use crate::build::ForGuard::OutsideGuard;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
+use rustc_middle::middle::region::Scope;
use rustc_middle::thir::*;
use rustc_middle::{mir::*, ty};
use rustc_span::Span;
@@ -10,7 +11,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
destination: Place<'tcx>,
block: BasicBlock,
- ast_block: &Block,
+ ast_block: BlockId,
source_info: SourceInfo,
) -> BlockAnd<()> {
let Block {
@@ -21,7 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
expr,
targeted_by_break,
safety_mode,
- } = *ast_block;
+ } = self.thir[ast_block];
let expr = expr.map(|expr| &self.thir[expr]);
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
@@ -34,10 +35,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&stmts,
expr,
safety_mode,
+ region_scope,
))
})
} else {
- this.ast_block_stmts(destination, block, span, &stmts, expr, safety_mode)
+ this.ast_block_stmts(
+ destination,
+ block,
+ span,
+ &stmts,
+ expr,
+ safety_mode,
+ region_scope,
+ )
}
})
})
@@ -51,6 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
stmts: &[StmtId],
expr: Option<&Expr<'tcx>>,
safety_mode: BlockSafety,
+ region_scope: Scope,
) -> BlockAnd<()> {
let this = self;
@@ -73,6 +84,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut let_scope_stack = Vec::with_capacity(8);
let outer_source_scope = this.source_scope;
let outer_in_scope_unsafe = this.in_scope_unsafe;
+ // This scope information is kept for breaking out of the parent remainder scope in case
+ // one let-else pattern matching fails.
+ // By doing so, we can be sure that even temporaries that receive extended lifetime
+ // assignments are dropped, too.
+ let mut last_remainder_scope = region_scope;
this.update_source_scope_for_safety_mode(span, safety_mode);
let source_info = this.source_info(span);
@@ -96,12 +112,169 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
StmtKind::Let {
remainder_scope,
init_scope,
+ pattern,
+ initializer: Some(initializer),
+ lint_level,
+ else_block: Some(else_block),
+ } => {
+ // When lowering the statement `let <pat> = <expr> else { <else> };`,
+ // the `<else>` block is nested in the parent scope enclosing this statment.
+ // That scope is usually either the enclosing block scope,
+ // or the remainder scope of the last statement.
+ // This is to make sure that temporaries instantiated in `<expr>` are dropped
+ // as well.
+ // In addition, even though bindings in `<pat>` only come into scope if
+ // the pattern matching passes, in the MIR building the storages for them
+ // are declared as live any way.
+ // This is similar to `let x;` statements without an initializer expression,
+ // where the value of `x` in this example may or may be assigned,
+ // because the storage for their values may not be live after all due to
+ // failure in pattern matching.
+ // For this reason, we declare those storages as live but we do not schedule
+ // any drop yet- they are scheduled later after the pattern matching.
+ // The generated MIR will have `StorageDead` whenever the control flow breaks out
+ // of the parent scope, regardless of the result of the pattern matching.
+ // However, the drops are inserted in MIR only when the control flow breaks out of
+ // the scope of the remainder scope associated with this `let .. else` statement.
+ // Pictorial explanation of the scope structure:
+ // ┌─────────────────────────────────â”
+ // │ Scope of the enclosing block, │
+ // │ or the last remainder scope │
+ // │ ┌───────────────────────────┠│
+ // │ │ Scope for <else> block │ │
+ // │ └───────────────────────────┘ │
+ // │ ┌───────────────────────────┠│
+ // │ │ Remainder scope of │ │
+ // │ │ this let-else statement │ │
+ // │ │ ┌─────────────────────┠│ │
+ // │ │ │ <expr> scope │ │ │
+ // │ │ └─────────────────────┘ │ │
+ // │ │ extended temporaries in │ │
+ // │ │ <expr> lives in this │ │
+ // │ │ scope │ │
+ // │ │ ┌─────────────────────┠│ │
+ // │ │ │ Scopes for the rest │ │ │
+ // │ │ └─────────────────────┘ │ │
+ // │ └───────────────────────────┘ │
+ // └─────────────────────────────────┘
+ // Generated control flow:
+ // │ let Some(x) = y() else { return; }
+ // │
+ // ┌────────▼───────â”
+ // │ evaluate y() │
+ // └────────┬───────┘
+ // │ ┌────────────────â”
+ // ┌────────▼───────┠│Drop temporaries│
+ // │Test the pattern├──────►in y() │
+ // └────────┬───────┘ │because breaking│
+ // │ │out of <expr> │
+ // ┌────────▼───────┠│scope │
+ // │Move value into │ └───────┬────────┘
+ // │binding x │ │
+ // └────────┬───────┘ ┌───────▼────────â”
+ // │ │Drop extended │
+ // ┌────────▼───────┠│temporaries in │
+ // │Drop temporaries│ │<expr> because │
+ // │in y() │ │breaking out of │
+ // │because breaking│ │remainder scope │
+ // │out of <expr> │ └───────┬────────┘
+ // │scope │ │
+ // └────────┬───────┘ ┌───────▼────────â”
+ // │ │Enter <else> ├────────►
+ // ┌────────▼───────┠│block │ return;
+ // │Continue... │ └────────────────┘
+ // └────────────────┘
+
+ let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
+ this.block_context.push(BlockFrame::Statement { ignores_expr_result });
+
+ // Lower the `else` block first because its parent scope is actually
+ // enclosing the rest of the `let .. else ..` parts.
+ let else_block_span = this.thir[*else_block].span;
+ // This place is not really used because this destination place
+ // should never be used to take values at the end of the failure
+ // block.
+ let dummy_place = this.temp(this.tcx.types.never, else_block_span);
+ let failure_entry = this.cfg.start_new_block();
+ let failure_block;
+ unpack!(
+ failure_block = this.ast_block(
+ dummy_place,
+ failure_entry,
+ *else_block,
+ this.source_info(else_block_span),
+ )
+ );
+ this.cfg.terminate(
+ failure_block,
+ this.source_info(else_block_span),
+ TerminatorKind::Unreachable,
+ );
+
+ // Declare the bindings, which may create a source scope.
+ let remainder_span = remainder_scope.span(this.tcx, this.region_scope_tree);
+ this.push_scope((*remainder_scope, source_info));
+ let_scope_stack.push(remainder_scope);
+
+ let visibility_scope =
+ Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
+
+ let init = &this.thir[*initializer];
+ let initializer_span = init.span;
+ this.declare_bindings(
+ visibility_scope,
+ remainder_span,
+ pattern,
+ ArmHasGuard(false),
+ Some((None, initializer_span)),
+ );
+ this.visit_primary_bindings(
+ pattern,
+ UserTypeProjections::none(),
+ &mut |this, _, _, _, node, span, _, _| {
+ this.storage_live_binding(block, node, span, OutsideGuard, true);
+ },
+ );
+ let failure = unpack!(
+ block = this.in_opt_scope(
+ opt_destruction_scope.map(|de| (de, source_info)),
+ |this| {
+ let scope = (*init_scope, source_info);
+ this.in_scope(scope, *lint_level, |this| {
+ this.ast_let_else(
+ block,
+ init,
+ initializer_span,
+ *else_block,
+ &last_remainder_scope,
+ pattern,
+ )
+ })
+ }
+ )
+ );
+ this.cfg.goto(failure, source_info, failure_entry);
+
+ if let Some(source_scope) = visibility_scope {
+ this.source_scope = source_scope;
+ }
+ last_remainder_scope = *remainder_scope;
+ }
+ StmtKind::Let { init_scope, initializer: None, else_block: Some(_), .. } => {
+ span_bug!(
+ init_scope.span(this.tcx, this.region_scope_tree),
+ "initializer is missing, but else block is present in this let binding",
+ )
+ }
+ StmtKind::Let {
+ remainder_scope,
+ init_scope,
ref pattern,
initializer,
lint_level,
- else_block,
+ else_block: None,
} => {
- let ignores_expr_result = matches!(*pattern.kind, PatKind::Wild);
+ let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
this.block_context.push(BlockFrame::Statement { ignores_expr_result });
// Enter the remainder scope, i.e., the bindings' destruction scope.
@@ -125,27 +298,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|this| {
let scope = (*init_scope, source_info);
this.in_scope(scope, *lint_level, |this| {
- if let Some(else_block) = else_block {
- this.ast_let_else(
- block,
- init,
- initializer_span,
- else_block,
- visibility_scope,
- *remainder_scope,
- remainder_span,
- pattern,
- )
- } else {
- this.declare_bindings(
- visibility_scope,
- remainder_span,
- pattern,
- ArmHasGuard(false),
- Some((None, initializer_span)),
- );
- this.expr_into_pattern(block, pattern.clone(), init) // irrefutable pattern
- }
+ this.declare_bindings(
+ visibility_scope,
+ remainder_span,
+ pattern,
+ ArmHasGuard(false),
+ Some((None, initializer_span)),
+ );
+ this.expr_into_pattern(block, &pattern, init) // irrefutable pattern
})
},
)
@@ -178,6 +338,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if let Some(source_scope) = visibility_scope {
this.source_scope = source_scope;
}
+ last_remainder_scope = *remainder_scope;
}
}
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 648d10b9e..c9bec130c 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -2,26 +2,18 @@
use crate::build::{parse_float_into_constval, Builder};
use rustc_ast as ast;
-use rustc_hir::def_id::DefId;
use rustc_middle::mir::interpret::{
Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
};
use rustc_middle::mir::*;
use rustc_middle::thir::*;
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt};
+use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt};
use rustc_target::abi::Size;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Compile `expr`, yielding a compile-time constant. Assumes that
/// `expr` is a valid compile-time constant!
pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
- let create_uneval_from_def_id =
- |tcx: TyCtxt<'tcx>, def_id: DefId, ty: Ty<'tcx>, substs: SubstsRef<'tcx>| {
- let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
- tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty })
- };
-
let this = self;
let tcx = this.tcx;
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
@@ -41,11 +33,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant { span, user_ty: None, literal }
}
- ExprKind::NonHirLiteral { lit, user_ty } => {
- let user_ty = user_ty.map(|user_ty| {
+ ExprKind::NonHirLiteral { lit, ref user_ty } => {
+ let user_ty = user_ty.as_ref().map(|user_ty| {
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
span,
- user_ty,
+ user_ty: user_ty.clone(),
inferred_ty: ty,
})
});
@@ -53,11 +45,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant { span, user_ty: user_ty, literal }
}
- ExprKind::ZstLiteral { user_ty } => {
- let user_ty = user_ty.map(|user_ty| {
+ ExprKind::ZstLiteral { ref user_ty } => {
+ let user_ty = user_ty.as_ref().map(|user_ty| {
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
span,
- user_ty,
+ user_ty: user_ty.clone(),
inferred_ty: ty,
})
});
@@ -65,15 +57,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant { span, user_ty: user_ty, literal }
}
- ExprKind::NamedConst { def_id, substs, user_ty } => {
- let user_ty = user_ty.map(|user_ty| {
+ ExprKind::NamedConst { def_id, substs, ref user_ty } => {
+ let user_ty = user_ty.as_ref().map(|user_ty| {
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
span,
- user_ty,
+ user_ty: user_ty.clone(),
inferred_ty: ty,
})
});
- let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs));
+
+ let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
+ let literal = ConstantKind::Unevaluated(uneval, ty);
Constant { user_ty, span, literal }
}
@@ -85,7 +79,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Constant { user_ty: None, span, literal }
}
ExprKind::ConstBlock { did: def_id, substs } => {
- let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs));
+ let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
+ let literal = ConstantKind::Unevaluated(uneval, ty);
Constant { user_ty: None, span, literal }
}
@@ -144,7 +139,7 @@ pub(crate) fn lit_to_mir_constant<'tcx>(
}
(ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
(ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
- (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported),
+ (ast::LitKind::Err, _) => return Err(LitToConstError::Reported),
_ => return Err(LitToConstError::TypeError),
};
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 0c06aad4e..ebb56e5a2 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -2,7 +2,7 @@
use crate::build::expr::category::Category;
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
-use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::hir::place::Projection as HirProjection;
use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
@@ -59,8 +59,6 @@ pub(crate) enum PlaceBase {
var_hir_id: LocalVarId,
/// DefId of the closure
closure_def_id: LocalDefId,
- /// The trait closure implements, `Fn`, `FnMut`, `FnOnce`
- closure_kind: ty::ClosureKind,
},
}
@@ -145,27 +143,6 @@ fn is_ancestor_or_same_capture(
iter::zip(proj_possible_ancestor, proj_capture).all(|(a, b)| a == b)
}
-/// Computes the index of a capture within the desugared closure provided the closure's
-/// `closure_min_captures` and the capture's index of the capture in the
-/// `ty::MinCaptureList` of the root variable `var_hir_id`.
-fn compute_capture_idx<'tcx>(
- closure_min_captures: &ty::RootVariableMinCaptureList<'tcx>,
- var_hir_id: LocalVarId,
- root_var_idx: usize,
-) -> usize {
- let mut res = 0;
- for (var_id, capture_list) in closure_min_captures {
- if *var_id == var_hir_id.0 {
- res += root_var_idx;
- break;
- } else {
- res += capture_list.len();
- }
- }
-
- res
-}
-
/// Given a closure, returns the index of a capture within the desugared closure struct and the
/// `ty::CapturedPlace` which is the ancestor of the Place represented using the `var_hir_id`
/// and `projection`.
@@ -174,27 +151,17 @@ fn compute_capture_idx<'tcx>(
///
/// Returns None, when the ancestor is not found.
fn find_capture_matching_projections<'a, 'tcx>(
- typeck_results: &'a ty::TypeckResults<'tcx>,
+ upvars: &'a CaptureMap<'tcx>,
var_hir_id: LocalVarId,
- closure_def_id: LocalDefId,
projections: &[PlaceElem<'tcx>],
-) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> {
- let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?;
- let root_variable_min_captures = closure_min_captures.get(&var_hir_id.0)?;
-
+) -> Option<(usize, &'a Capture<'tcx>)> {
let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections);
- // If an ancestor is found, `idx` is the index within the list of captured places
- // for root variable `var_hir_id` and `capture` is the `ty::CapturedPlace` itself.
- let (idx, capture) = root_variable_min_captures.iter().enumerate().find(|(_, capture)| {
+ upvars.get_by_key_enumerated(var_hir_id.0).find(|(_, capture)| {
let possible_ancestor_proj_kinds: Vec<_> =
- capture.place.projections.iter().map(|proj| proj.kind).collect();
+ capture.captured_place.place.projections.iter().map(|proj| proj.kind).collect();
is_ancestor_or_same_capture(&possible_ancestor_proj_kinds, &hir_projections)
- })?;
-
- // Convert index to be from the perspective of the entire closure_min_captures map
- // instead of just the root variable capture list
- Some((compute_capture_idx(closure_min_captures, var_hir_id, idx), capture))
+ })
}
/// Takes a PlaceBuilder and resolves the upvar (if any) within it, so that the
@@ -204,24 +171,15 @@ fn find_capture_matching_projections<'a, 'tcx>(
fn to_upvars_resolved_place_builder<'a, 'tcx>(
from_builder: PlaceBuilder<'tcx>,
tcx: TyCtxt<'tcx>,
- typeck_results: &'a ty::TypeckResults<'tcx>,
+ upvars: &'a CaptureMap<'tcx>,
) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
match from_builder.base {
PlaceBase::Local(_) => Ok(from_builder),
- PlaceBase::Upvar { var_hir_id, closure_def_id, closure_kind } => {
- let mut upvar_resolved_place_builder = PlaceBuilder::from(ty::CAPTURE_STRUCT_LOCAL);
- match closure_kind {
- ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
- upvar_resolved_place_builder = upvar_resolved_place_builder.deref();
- }
- ty::ClosureKind::FnOnce => {}
- }
-
+ PlaceBase::Upvar { var_hir_id, closure_def_id } => {
let Some((capture_index, capture)) =
find_capture_matching_projections(
- typeck_results,
+ upvars,
var_hir_id,
- closure_def_id,
&from_builder.projection,
) else {
let closure_span = tcx.def_span(closure_def_id);
@@ -241,39 +199,17 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
return Err(from_builder);
};
- // We won't be building MIR if the closure wasn't local
- let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_def_id);
- let closure_ty = typeck_results.node_type(closure_hir_id);
-
- let substs = match closure_ty.kind() {
- ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
- ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
- _ => bug!("Lowering capture for non-closure type {:?}", closure_ty),
- };
-
// Access the capture by accessing the field within the Closure struct.
- //
- // We must have inferred the capture types since we are building MIR, therefore
- // it's safe to call `tuple_element_ty` and we can unwrap here because
- // we know that the capture exists and is the `capture_index`-th capture.
- let var_ty = substs.tupled_upvars_ty().tuple_fields()[capture_index];
-
- upvar_resolved_place_builder =
- upvar_resolved_place_builder.field(Field::new(capture_index), var_ty);
-
- // If the variable is captured via ByRef(Immutable/Mutable) Borrow,
- // we need to deref it
- upvar_resolved_place_builder = match capture.info.capture_kind {
- ty::UpvarCapture::ByRef(_) => upvar_resolved_place_builder.deref(),
- ty::UpvarCapture::ByValue => upvar_resolved_place_builder,
- };
+ let capture_info = &upvars[capture_index];
+
+ let mut upvar_resolved_place_builder = PlaceBuilder::from(capture_info.use_place);
// We used some of the projections to build the capture itself,
// now we apply the remaining to the upvar resolved place.
let remaining_projections = strip_prefix(
- capture.place.base_ty,
+ capture.captured_place.place.base_ty,
from_builder.projection,
- &capture.place.projections,
+ &capture.captured_place.place.projections,
);
upvar_resolved_place_builder.projection.extend(remaining_projections);
@@ -315,24 +251,24 @@ fn strip_prefix<'tcx>(
}
impl<'tcx> PlaceBuilder<'tcx> {
- pub(crate) fn into_place<'a>(
+ pub(in crate::build) fn into_place<'a>(
self,
tcx: TyCtxt<'tcx>,
- typeck_results: &'a ty::TypeckResults<'tcx>,
+ upvars: &'a CaptureMap<'tcx>,
) -> Place<'tcx> {
if let PlaceBase::Local(local) = self.base {
Place { local, projection: tcx.intern_place_elems(&self.projection) }
} else {
- self.expect_upvars_resolved(tcx, typeck_results).into_place(tcx, typeck_results)
+ self.expect_upvars_resolved(tcx, upvars).into_place(tcx, upvars)
}
}
fn expect_upvars_resolved<'a>(
self,
tcx: TyCtxt<'tcx>,
- typeck_results: &'a ty::TypeckResults<'tcx>,
+ upvars: &'a CaptureMap<'tcx>,
) -> PlaceBuilder<'tcx> {
- to_upvars_resolved_place_builder(self, tcx, typeck_results).unwrap()
+ to_upvars_resolved_place_builder(self, tcx, upvars).unwrap()
}
/// Attempts to resolve the `PlaceBuilder`.
@@ -346,12 +282,12 @@ impl<'tcx> PlaceBuilder<'tcx> {
/// not captured. This can happen because the final mir that will be
/// generated doesn't require a read for this place. Failures will only
/// happen inside closures.
- pub(crate) fn try_upvars_resolved<'a>(
+ pub(in crate::build) fn try_upvars_resolved<'a>(
self,
tcx: TyCtxt<'tcx>,
- typeck_results: &'a ty::TypeckResults<'tcx>,
+ upvars: &'a CaptureMap<'tcx>,
) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
- to_upvars_resolved_place_builder(self, tcx, typeck_results)
+ to_upvars_resolved_place_builder(self, tcx, upvars)
}
pub(crate) fn base(&self) -> PlaceBase {
@@ -392,6 +328,12 @@ impl<'tcx> From<PlaceBase> for PlaceBuilder<'tcx> {
}
}
+impl<'tcx> From<Place<'tcx>> for PlaceBuilder<'tcx> {
+ fn from(p: Place<'tcx>) -> Self {
+ Self { base: PlaceBase::Local(p.local), projection: p.projection.to_vec() }
+ }
+}
+
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Compile `expr`, yielding a place that we can move from etc.
///
@@ -411,7 +353,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
expr: &Expr<'tcx>,
) -> BlockAnd<Place<'tcx>> {
let place_builder = unpack!(block = self.as_place_builder(block, expr));
- block.and(place_builder.into_place(self.tcx, self.typeck_results))
+ block.and(place_builder.into_place(self.tcx, &self.upvars))
}
/// This is used when constructing a compound `Place`, so that we can avoid creating
@@ -435,7 +377,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
expr: &Expr<'tcx>,
) -> BlockAnd<Place<'tcx>> {
let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr));
- block.and(place_builder.into_place(self.tcx, self.typeck_results))
+ block.and(place_builder.into_place(self.tcx, &self.upvars))
}
/// This is used when constructing a compound `Place`, so that we can avoid creating
@@ -513,7 +455,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(place_builder)
}
- ExprKind::PlaceTypeAscription { source, user_ty } => {
+ ExprKind::PlaceTypeAscription { source, ref user_ty } => {
let place_builder = unpack!(
block = this.expr_as_place(
block,
@@ -526,11 +468,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let annotation_index =
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
span: source_info.span,
- user_ty,
+ user_ty: user_ty.clone(),
inferred_ty: expr.ty,
});
- let place = place_builder.clone().into_place(this.tcx, this.typeck_results);
+ let place = place_builder.clone().into_place(this.tcx, &this.upvars);
this.cfg.push(
block,
Statement {
@@ -547,7 +489,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
block.and(place_builder)
}
- ExprKind::ValueTypeAscription { source, user_ty } => {
+ ExprKind::ValueTypeAscription { source, ref user_ty } => {
let source = &this.thir[source];
let temp =
unpack!(block = this.as_temp(block, source.temp_lifetime, source, mutability));
@@ -555,7 +497,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let annotation_index =
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
span: source_info.span,
- user_ty,
+ user_ty: user_ty.clone(),
inferred_ty: expr.ty,
});
this.cfg.push(
@@ -629,17 +571,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
closure_def_id: LocalDefId,
var_hir_id: LocalVarId,
) -> BlockAnd<PlaceBuilder<'tcx>> {
- let closure_ty =
- self.typeck_results.node_type(self.tcx.hir().local_def_id_to_hir_id(closure_def_id));
-
- let closure_kind = if let ty::Closure(_, closure_substs) = closure_ty.kind() {
- self.infcx.closure_kind(closure_substs).unwrap()
- } else {
- // Generators are considered FnOnce.
- ty::ClosureKind::FnOnce
- };
-
- block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id, closure_kind }))
+ block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id }))
}
/// Lower an index expression
@@ -678,7 +610,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if is_outermost_index {
self.read_fake_borrows(block, fake_borrow_temps, source_info)
} else {
- base_place = base_place.expect_upvars_resolved(self.tcx, self.typeck_results);
+ base_place = base_place.expect_upvars_resolved(self.tcx, &self.upvars);
self.add_fake_borrows_of_base(
&base_place,
block,
@@ -710,7 +642,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
source_info,
len,
- Rvalue::Len(slice.into_place(self.tcx, self.typeck_results)),
+ Rvalue::Len(slice.into_place(self.tcx, &self.upvars)),
);
// lt = idx < len
self.cfg.push_assign(
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 15f2d17c4..f88ab63f0 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -197,13 +197,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// create all the steps directly in MIR with operations all backends need to support anyway.
let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() && adt_def.is_enum() {
let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx);
- let place = unpack!(block = this.as_place(block, source));
+ let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not));
let discr = this.temp(discr_ty, source.span);
this.cfg.push_assign(
block,
source_info,
discr,
- Rvalue::Discriminant(place),
+ Rvalue::Discriminant(temp.into()),
);
(Operand::Move(discr), discr_ty)
@@ -216,6 +216,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
let from_ty = CastTy::from_ty(ty);
let cast_ty = CastTy::from_ty(expr.ty);
+ debug!("ExprKind::Cast from_ty={from_ty:?}, cast_ty={:?}/{cast_ty:?}", expr.ty,);
let cast_kind = match (from_ty, cast_ty) {
(Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
CastKind::PointerExposeAddress
@@ -223,6 +224,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => {
CastKind::PointerFromExposedAddress
}
+ (_, Some(CastTy::DynStar)) => CastKind::DynStar,
(_, _) => CastKind::Misc,
};
block.and(Rvalue::Cast(cast_kind, source, expr.ty))
@@ -302,7 +304,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields))
}
- ExprKind::Closure { closure_id, substs, ref upvars, movability, ref fake_reads } => {
+ ExprKind::Closure(box ClosureExpr {
+ closure_id,
+ substs,
+ ref upvars,
+ movability,
+ ref fake_reads,
+ }) => {
// Convert the closure fake reads, if any, from `ExprRef` to mir `Place`
// and push the fake reads.
// This must come before creating the operands. This is required in case
@@ -322,10 +330,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
if let Ok(place_builder_resolved) =
- place_builder.try_upvars_resolved(this.tcx, this.typeck_results)
+ place_builder.try_upvars_resolved(this.tcx, &this.upvars)
{
- let mir_place =
- place_builder_resolved.into_place(this.tcx, this.typeck_results);
+ let mir_place = place_builder_resolved.into_place(this.tcx, &this.upvars);
this.cfg.push_fake_read(
block,
this.source_info(this.tcx.hir().span(*hir_id)),
@@ -617,7 +624,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// is same as that of the capture in the parent closure.
PlaceBase::Upvar { .. } => {
let enclosing_upvars_resolved =
- arg_place_builder.clone().into_place(this.tcx, this.typeck_results);
+ arg_place_builder.clone().into_place(this.tcx, &this.upvars);
match enclosing_upvars_resolved.as_ref() {
PlaceRef {
@@ -637,12 +644,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
// Not in a closure
debug_assert!(
- this.upvar_mutbls.len() > upvar_index.index(),
- "Unexpected capture place, upvar_mutbls={:#?}, upvar_index={:?}",
- this.upvar_mutbls,
+ this.upvars.len() > upvar_index.index(),
+ "Unexpected capture place, upvars={:#?}, upvar_index={:?}",
+ this.upvars,
upvar_index
);
- this.upvar_mutbls[upvar_index.index()]
+ this.upvars[upvar_index.index()].mutability
}
_ => bug!("Unexpected capture place"),
}
@@ -654,7 +661,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
};
- let arg_place = arg_place_builder.into_place(this.tcx, this.typeck_results);
+ let arg_place = arg_place_builder.into_place(this.tcx, &this.upvars);
this.cfg.push_assign(
block,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index 724b72f87..e5dafb820 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -83,8 +83,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Don't bother with StorageLive and Dead for these temporaries,
// they are never assigned.
ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => (),
- ExprKind::Block { body: Block { expr: None, targeted_by_break: false, .. } }
- if expr_ty.is_never() => {}
+ ExprKind::Block { block }
+ if let Block { expr: None, targeted_by_break: false, .. } = this.thir[block]
+ && expr_ty.is_never() => {}
_ => {
this.cfg
.push(block, Statement { source_info, kind: StatementKind::StorageLive(temp) });
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 017d43d10..224a1b80f 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -46,7 +46,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
})
}
- ExprKind::Block { body: ref ast_block } => {
+ ExprKind::Block { block: ast_block } => {
this.ast_block(destination, block, ast_block, source_info)
}
ExprKind::Match { scrutinee, ref arms } => {
@@ -75,7 +75,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.source_info(then_expr.span)
};
let (then_block, else_block) =
- this.in_if_then_scope(condition_scope, |this| {
+ this.in_if_then_scope(condition_scope, then_expr.span, |this| {
let then_blk = unpack!(this.then_else_break(
block,
&this.thir[cond],
@@ -108,7 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Let { expr, ref pat } => {
let scope = this.local_scope();
- let (true_block, false_block) = this.in_if_then_scope(scope, |this| {
+ let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span)
});
@@ -314,11 +314,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.cfg.push_assign(block, source_info, destination, address_of);
block.unit()
}
- ExprKind::Adt(box Adt {
+ ExprKind::Adt(box AdtExpr {
adt_def,
variant_index,
substs,
- user_ty,
+ ref user_ty,
ref fields,
ref base,
}) => {
@@ -366,9 +366,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None => {
let place_builder = place_builder.clone();
this.consume_by_copy_or_move(
- place_builder
- .field(n, *ty)
- .into_place(this.tcx, this.typeck_results),
+ place_builder.field(n, *ty).into_place(this.tcx, &this.upvars),
)
}
})
@@ -378,10 +376,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
let inferred_ty = expr.ty;
- let user_ty = user_ty.map(|ty| {
+ let user_ty = user_ty.as_ref().map(|user_ty| {
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
span: source_info.span,
- user_ty: ty,
+ user_ty: user_ty.clone(),
inferred_ty,
})
});
@@ -400,7 +398,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
block.unit()
}
- ExprKind::InlineAsm { template, ref operands, options, line_spans } => {
+ ExprKind::InlineAsm(box InlineAsmExpr {
+ template,
+ ref operands,
+ options,
+ line_spans,
+ }) => {
use rustc_middle::{mir, thir};
let operands = operands
.into_iter()
diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs
index a7e1331aa..00dbcaeb0 100644
--- a/compiler/rustc_mir_build/src/build/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs
@@ -116,14 +116,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// it is usually better to focus on `the_value` rather
// than the entirety of block(s) surrounding it.
let adjusted_span = (|| {
- if let ExprKind::Block { body } = &expr.kind && let Some(tail_ex) = body.expr {
+ if let ExprKind::Block { block } = expr.kind
+ && let Some(tail_ex) = this.thir[block].expr
+ {
let mut expr = &this.thir[tail_ex];
- while let ExprKind::Block {
- body: Block { expr: Some(nested_expr), .. },
- }
- | ExprKind::Scope { value: nested_expr, .. } = expr.kind
- {
- expr = &this.thir[nested_expr];
+ loop {
+ match expr.kind {
+ ExprKind::Block { block }
+ if let Some(nested_expr) = this.thir[block].expr =>
+ {
+ expr = &this.thir[nested_expr];
+ }
+ ExprKind::Scope { value: nested_expr, .. } => {
+ expr = &this.thir[nested_expr];
+ }
+ _ => break,
+ }
}
this.block_context.push(BlockFrame::TailExpr {
tail_result_is_ignored: true,
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 58b1564cc..93f382cc6 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -155,7 +155,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
///
/// * From each pre-binding block to the next pre-binding block.
/// * From each otherwise block to the next pre-binding block.
- #[tracing::instrument(level = "debug", skip(self, arms))]
+ #[instrument(level = "debug", skip(self, arms))]
pub(crate) fn match_expr(
&mut self,
destination: Place<'tcx>,
@@ -170,7 +170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut arm_candidates = self.create_match_candidates(scrutinee_place.clone(), &arms);
- let match_has_guard = arms.iter().copied().any(|arm| self.thir[arm].guard.is_some());
+ let match_has_guard = arm_candidates.iter().any(|(_, candidate)| candidate.has_guard);
let mut candidates =
arm_candidates.iter_mut().map(|(_, candidate)| candidate).collect::<Vec<_>>();
@@ -221,9 +221,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let source_info = self.source_info(scrutinee_span);
if let Ok(scrutinee_builder) =
- scrutinee_place_builder.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+ scrutinee_place_builder.clone().try_upvars_resolved(self.tcx, &self.upvars)
{
- let scrutinee_place = scrutinee_builder.into_place(self.tcx, self.typeck_results);
+ let scrutinee_place = scrutinee_builder.into_place(self.tcx, &self.upvars);
self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place);
}
@@ -348,12 +348,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// ```
let mut opt_scrutinee_place: Option<(Option<&Place<'tcx>>, Span)> = None;
let scrutinee_place: Place<'tcx>;
- if let Ok(scrutinee_builder) = scrutinee_place_builder
- .clone()
- .try_upvars_resolved(this.tcx, this.typeck_results)
+ if let Ok(scrutinee_builder) =
+ scrutinee_place_builder.clone().try_upvars_resolved(this.tcx, &this.upvars)
{
- scrutinee_place =
- scrutinee_builder.into_place(this.tcx, this.typeck_results);
+ scrutinee_place = scrutinee_builder.into_place(this.tcx, &this.upvars);
opt_scrutinee_place = Some((Some(&scrutinee_place), scrutinee_span));
}
let scope = this.declare_bindings(
@@ -373,6 +371,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Some(arm.span),
Some(arm.scope),
Some(match_scope),
+ false,
);
if let Some(source_scope) = scope {
@@ -418,6 +417,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span: Option<Span>,
arm_scope: Option<region::Scope>,
match_scope: Option<region::Scope>,
+ storages_alive: bool,
) -> BasicBlock {
if candidate.subcandidates.is_empty() {
// Avoid generating another `BasicBlock` when we only have one
@@ -431,6 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span,
match_scope,
true,
+ storages_alive,
)
} else {
// It's helpful to avoid scheduling drops multiple times to save
@@ -468,6 +469,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span,
match_scope,
schedule_drops,
+ storages_alive,
);
if arm_scope.is_none() {
schedule_drops = false;
@@ -490,10 +492,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub(super) fn expr_into_pattern(
&mut self,
mut block: BasicBlock,
- irrefutable_pat: Pat<'tcx>,
+ irrefutable_pat: &Pat<'tcx>,
initializer: &Expr<'tcx>,
) -> BlockAnd<()> {
- match *irrefutable_pat.kind {
+ match irrefutable_pat.kind {
// Optimize the case of `let x = ...` to write directly into `x`
PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
let place =
@@ -518,17 +520,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// broken.
PatKind::AscribeUserType {
subpattern:
- Pat {
+ box Pat {
kind:
- box PatKind::Binding {
- mode: BindingMode::ByValue,
- var,
- subpattern: None,
- ..
+ PatKind::Binding {
+ mode: BindingMode::ByValue, var, subpattern: None, ..
},
..
},
- ascription: thir::Ascription { annotation, variance: _ },
+ ascription: thir::Ascription { ref annotation, variance: _ },
} => {
let place =
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
@@ -541,7 +540,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let ty_source_info = self.source_info(annotation.span);
- let base = self.canonical_user_type_annotations.push(annotation);
+ let base = self.canonical_user_type_annotations.push(annotation.clone());
self.cfg.push(
block,
Statement {
@@ -573,7 +572,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
_ => {
let place_builder = unpack!(block = self.as_place_builder(block, initializer));
- self.place_into_pattern(block, irrefutable_pat, place_builder, true)
+ self.place_into_pattern(block, &irrefutable_pat, place_builder, true)
}
}
}
@@ -581,7 +580,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub(crate) fn place_into_pattern(
&mut self,
block: BasicBlock,
- irrefutable_pat: Pat<'tcx>,
+ irrefutable_pat: &Pat<'tcx>,
initializer: PlaceBuilder<'tcx>,
set_match_place: bool,
) -> BlockAnd<()> {
@@ -623,9 +622,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// };
// ```
if let Ok(match_pair_resolved) =
- initializer.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+ initializer.clone().try_upvars_resolved(self.tcx, &self.upvars)
{
- let place = match_pair_resolved.into_place(self.tcx, self.typeck_results);
+ let place = match_pair_resolved.into_place(self.tcx, &self.upvars);
*match_place = Some(place);
}
}
@@ -646,6 +645,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
+ false,
)
.unit()
}
@@ -702,9 +702,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let local_id = self.var_local_id(var, for_guard);
let source_info = self.source_info(span);
self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) });
- // Altough there is almost always scope for given variable in corner cases
+ // Although there is almost always scope for given variable in corner cases
// like #92893 we might get variable with no scope.
- if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) && schedule_drop{
+ if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) && schedule_drop {
self.schedule_drop(span, region_scope, local_id, DropKind::Storage);
}
Place::from(local_id)
@@ -744,7 +744,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
"visit_primary_bindings: pattern={:?} pattern_user_ty={:?}",
pattern, pattern_user_ty
);
- match *pattern.kind {
+ match pattern.kind {
PatKind::Binding {
mutability,
name,
@@ -767,7 +767,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| PatKind::Slice { ref prefix, ref slice, ref suffix } => {
let from = u64::try_from(prefix.len()).unwrap();
let to = u64::try_from(suffix.len()).unwrap();
- for subpattern in prefix {
+ for subpattern in prefix.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
}
for subpattern in slice {
@@ -777,7 +777,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
f,
);
}
- for subpattern in suffix {
+ for subpattern in suffix.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
}
}
@@ -830,7 +830,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// may not all be in the leftmost subpattern. For example in
// `let (x | y) = ...`, the primary binding of `y` occurs in
// the right subpattern
- for subpattern in pats {
+ for subpattern in pats.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone(), f);
}
}
@@ -982,7 +982,7 @@ enum TestKind<'tcx> {
},
/// Test whether the value falls within an inclusive or exclusive range
- Range(PatRange<'tcx>),
+ Range(Box<PatRange<'tcx>>),
/// Test that the length of the slice is equal to `len`.
Len { len: u64, op: BinOp },
@@ -1330,7 +1330,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// All of the or-patterns have been sorted to the end, so if the first
// pattern is an or-pattern we only have or-patterns.
- match *first_candidate.match_pairs[0].pattern.kind {
+ match first_candidate.match_pairs[0].pattern.kind {
PatKind::Or { .. } => (),
_ => {
self.test_candidates(
@@ -1350,7 +1350,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut otherwise = None;
for match_pair in match_pairs {
- let PatKind::Or { ref pats } = &*match_pair.pattern.kind else {
+ let PatKind::Or { ref pats } = &match_pair.pattern.kind else {
bug!("Or-patterns should have been sorted to the end");
};
let or_span = match_pair.pattern.span;
@@ -1384,7 +1384,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
candidate: &mut Candidate<'pat, 'tcx>,
otherwise: &mut Option<BasicBlock>,
- pats: &'pat [Pat<'tcx>],
+ pats: &'pat [Box<Pat<'tcx>>],
or_span: Span,
place: PlaceBuilder<'tcx>,
fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
@@ -1605,9 +1605,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Insert a Shallow borrow of any places that is switched on.
if let Some(fb) = fake_borrows && let Ok(match_place_resolved) =
- match_place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+ match_place.clone().try_upvars_resolved(self.tcx, &self.upvars)
{
- let resolved_place = match_place_resolved.into_place(self.tcx, self.typeck_results);
+ let resolved_place = match_place_resolved.into_place(self.tcx, &self.upvars);
fb.insert(resolved_place);
}
@@ -1794,10 +1794,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
let mut opt_expr_place: Option<(Option<&Place<'tcx>>, Span)> = None;
let expr_place: Place<'tcx>;
- if let Ok(expr_builder) =
- expr_place_builder.try_upvars_resolved(self.tcx, self.typeck_results)
- {
- expr_place = expr_builder.into_place(self.tcx, self.typeck_results);
+ if let Ok(expr_builder) = expr_place_builder.try_upvars_resolved(self.tcx, &self.upvars) {
+ expr_place = expr_builder.into_place(self.tcx, &self.upvars);
opt_expr_place = Some((Some(&expr_place), expr_span));
}
let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
@@ -1820,6 +1818,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
+ false,
);
post_guard_block.unit()
@@ -1843,6 +1842,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span: Option<Span>,
match_scope: Option<region::Scope>,
schedule_drops: bool,
+ storages_alive: bool,
) -> BasicBlock {
debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
@@ -1978,7 +1978,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut guard_span = rustc_span::DUMMY_SP;
let (post_guard_block, otherwise_post_guard_block) =
- self.in_if_then_scope(match_scope, |this| match *guard {
+ self.in_if_then_scope(match_scope, guard_span, |this| match *guard {
Guard::If(e) => {
let e = &this.thir[e];
guard_span = e.span;
@@ -2058,7 +2058,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(local_id));
}
assert!(schedule_drops, "patterns with guards must schedule drops");
- self.bind_matched_candidate_for_arm_body(post_guard_block, true, by_value_bindings);
+ self.bind_matched_candidate_for_arm_body(
+ post_guard_block,
+ true,
+ by_value_bindings,
+ storages_alive,
+ );
post_guard_block
} else {
@@ -2072,6 +2077,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.iter()
.flat_map(|(bindings, _)| bindings)
.chain(&candidate.bindings),
+ storages_alive,
);
block
}
@@ -2161,6 +2167,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block: BasicBlock,
schedule_drops: bool,
bindings: impl IntoIterator<Item = &'b Binding<'tcx>>,
+ storages_alive: bool,
) where
'tcx: 'b,
{
@@ -2170,13 +2177,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Assign each of the bindings. This may trigger moves out of the candidate.
for binding in bindings {
let source_info = self.source_info(binding.span);
- let local = self.storage_live_binding(
- block,
- binding.var_id,
- binding.span,
- OutsideGuard,
- schedule_drops,
- );
+ let local = if storages_alive {
+ // Here storages are already alive, probably because this is a binding
+ // from let-else.
+ // We just need to schedule drop for the value.
+ self.var_local_id(binding.var_id, OutsideGuard).into()
+ } else {
+ self.storage_live_binding(
+ block,
+ binding.var_id,
+ binding.span,
+ OutsideGuard,
+ schedule_drops,
+ )
+ };
if schedule_drops {
self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard);
}
@@ -2280,23 +2294,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
mut block: BasicBlock,
init: &Expr<'tcx>,
initializer_span: Span,
- else_block: &Block,
- visibility_scope: Option<SourceScope>,
- remainder_scope: region::Scope,
- remainder_span: Span,
+ else_block: BlockId,
+ let_else_scope: &region::Scope,
pattern: &Pat<'tcx>,
- ) -> BlockAnd<()> {
- let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| {
+ ) -> BlockAnd<BasicBlock> {
+ let else_block_span = self.thir[else_block].span;
+ let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| {
let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span));
- let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) };
+ let pat = Pat { ty: init.ty, span: else_block_span, kind: PatKind::Wild };
let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false);
- this.declare_bindings(
- visibility_scope,
- remainder_span,
- pattern,
- ArmHasGuard(false),
- Some((None, initializer_span)),
- );
let mut candidate = Candidate::new(scrutinee.clone(), pattern, false);
let fake_borrow_temps = this.lower_match_tree(
block,
@@ -2315,10 +2321,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
+ true,
);
// This block is for the failure case
let failure = this.bind_pattern(
- this.source_info(else_block.span),
+ this.source_info(else_block_span),
wildcard,
None,
&fake_borrow_temps,
@@ -2326,29 +2333,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
+ true,
);
- this.break_for_else(failure, remainder_scope, this.source_info(initializer_span));
+ this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span));
matching.unit()
});
-
- // This place is not really used because this destination place
- // should never be used to take values at the end of the failure
- // block.
- let dummy_place = Place { local: RETURN_PLACE, projection: ty::List::empty() };
- let failure_block;
- unpack!(
- failure_block = self.ast_block(
- dummy_place,
- failure,
- else_block,
- self.source_info(else_block.span),
- )
- );
- self.cfg.terminate(
- failure_block,
- self.source_info(else_block.span),
- TerminatorKind::Unreachable,
- );
- matching.unit()
+ matching.and(failure)
}
}
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index c62989041..df221d356 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -67,7 +67,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
loop {
let match_pairs = mem::take(&mut candidate.match_pairs);
- if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, place }] =
+ if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
&*match_pairs
{
existing_bindings.extend_from_slice(&new_bindings);
@@ -113,7 +113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// late as possible.
candidate
.match_pairs
- .sort_by_key(|pair| matches!(*pair.pattern.kind, PatKind::Or { .. }));
+ .sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
debug!(simplified = ?candidate, "simplify_candidate");
return false; // if we were not able to simplify any, done.
}
@@ -127,10 +127,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
candidate: &Candidate<'pat, 'tcx>,
place: PlaceBuilder<'tcx>,
- pats: &'pat [Pat<'tcx>],
+ pats: &'pat [Box<Pat<'tcx>>],
) -> Vec<Candidate<'pat, 'tcx>> {
pats.iter()
- .map(|pat| {
+ .map(|box pat| {
let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard);
self.simplify_candidate(&mut candidate);
candidate
@@ -149,18 +149,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>,
) -> Result<(), MatchPair<'pat, 'tcx>> {
let tcx = self.tcx;
- match *match_pair.pattern.kind {
+ match match_pair.pattern.kind {
PatKind::AscribeUserType {
ref subpattern,
ascription: thir::Ascription { ref annotation, variance },
} => {
// Apply the type ascription to the value at `match_pair.place`, which is the
if let Ok(place_resolved) =
- match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+ match_pair.place.clone().try_upvars_resolved(self.tcx, &self.upvars)
{
candidate.ascriptions.push(Ascription {
annotation: annotation.clone(),
- source: place_resolved.into_place(self.tcx, self.typeck_results),
+ source: place_resolved.into_place(self.tcx, &self.upvars),
variance,
});
}
@@ -185,11 +185,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
is_primary: _,
} => {
if let Ok(place_resolved) =
- match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+ match_pair.place.clone().try_upvars_resolved(self.tcx, &self.upvars)
{
candidate.bindings.push(Binding {
span: match_pair.pattern.span,
- source: place_resolved.into_place(self.tcx, self.typeck_results),
+ source: place_resolved.into_place(self.tcx, &self.upvars),
var_id: var,
binding_mode: mode,
});
@@ -208,7 +208,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Err(match_pair)
}
- PatKind::Range(PatRange { lo, hi, end }) => {
+ PatKind::Range(box PatRange { lo, hi, end }) => {
let (range, bias) = match *lo.ty().kind() {
ty::Char => {
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
@@ -254,7 +254,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut candidate.match_pairs,
&match_pair.place,
prefix,
- slice.as_ref(),
+ slice,
suffix,
);
Ok(())
@@ -294,7 +294,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut candidate.match_pairs,
&match_pair.place,
prefix,
- slice.as_ref(),
+ slice,
suffix,
);
Ok(())
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 598da80c5..47d05a6e3 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -29,7 +29,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
///
/// It is a bug to call this with a not-fully-simplified pattern.
pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
- match *match_pair.pattern.kind {
+ match match_pair.pattern.kind {
PatKind::Variant { adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
span: match_pair.pattern.span,
kind: TestKind::Switch {
@@ -58,10 +58,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
kind: TestKind::Eq { value, ty: match_pair.pattern.ty },
},
- PatKind::Range(range) => {
+ PatKind::Range(ref range) => {
assert_eq!(range.lo.ty(), match_pair.pattern.ty);
assert_eq!(range.hi.ty(), match_pair.pattern.ty);
- Test { span: match_pair.pattern.span, kind: TestKind::Range(range) }
+ Test { span: match_pair.pattern.span, kind: TestKind::Range(range.clone()) }
}
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
@@ -92,7 +92,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
return false;
};
- match *match_pair.pattern.kind {
+ match match_pair.pattern.kind {
PatKind::Constant { value } => {
options
.entry(value)
@@ -102,9 +102,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PatKind::Variant { .. } => {
panic!("you should have called add_variants_to_switch instead!");
}
- PatKind::Range(range) => {
+ PatKind::Range(ref range) => {
// Check that none of the switch values are in the range.
- self.values_not_contained_in_range(range, options).unwrap_or(false)
+ self.values_not_contained_in_range(&*range, options).unwrap_or(false)
}
PatKind::Slice { .. }
| PatKind::Array { .. }
@@ -130,7 +130,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
return false;
};
- match *match_pair.pattern.kind {
+ match match_pair.pattern.kind {
PatKind::Variant { adt_def: _, variant_index, .. } => {
// We have a pattern testing for variant `variant_index`
// set the corresponding index to true
@@ -154,10 +154,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
) {
let place: Place<'tcx>;
- if let Ok(test_place_builder) =
- place_builder.try_upvars_resolved(self.tcx, self.typeck_results)
- {
- place = test_place_builder.into_place(self.tcx, self.typeck_results);
+ if let Ok(test_place_builder) = place_builder.try_upvars_resolved(self.tcx, &self.upvars) {
+ place = test_place_builder.into_place(self.tcx, &self.upvars);
} else {
return;
}
@@ -272,7 +270,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- TestKind::Range(PatRange { lo, hi, ref end }) => {
+ TestKind::Range(box PatRange { lo, hi, ref end }) => {
let lower_bound_success = self.cfg.start_new_block();
let target_blocks = make_target_blocks(self);
@@ -506,7 +504,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let (match_pair_index, match_pair) =
candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == *test_place)?;
- match (&test.kind, &*match_pair.pattern.kind) {
+ match (&test.kind, &match_pair.pattern.kind) {
// If we are performing a variant switch, then this
// informs variant patterns, but nothing else.
(
@@ -540,9 +538,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Some(index)
}
- (&TestKind::SwitchInt { switch_ty: _, ref options }, &PatKind::Range(range)) => {
+ (&TestKind::SwitchInt { switch_ty: _, ref options }, &PatKind::Range(ref range)) => {
let not_contained =
- self.values_not_contained_in_range(range, options).unwrap_or(false);
+ self.values_not_contained_in_range(&*range, options).unwrap_or(false);
if not_contained {
// No switch values are contained in the pattern range,
@@ -569,7 +567,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match_pair_index,
candidate,
prefix,
- slice.as_ref(),
+ slice,
suffix,
);
Some(0)
@@ -607,7 +605,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match_pair_index,
candidate,
prefix,
- slice.as_ref(),
+ slice,
suffix,
);
Some(0)
@@ -631,7 +629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- (&TestKind::Range(test), &PatKind::Range(pat)) => {
+ (&TestKind::Range(ref test), &PatKind::Range(ref pat)) => {
use std::cmp::Ordering::*;
if test == pat {
@@ -658,8 +656,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
no_overlap
}
- (&TestKind::Range(range), &PatKind::Constant { value }) => {
- if let Some(false) = self.const_range_contains(range, value) {
+ (&TestKind::Range(ref range), &PatKind::Constant { value }) => {
+ if let Some(false) = self.const_range_contains(&*range, value) {
// `value` is not contained in the testing range,
// so `value` can be matched only if this test fails.
Some(1)
@@ -678,7 +676,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// However, at this point we can still encounter or-patterns that were extracted
// from previous calls to `sort_candidate`, so we need to manually address that
// case to avoid panicking in `self.test()`.
- if let PatKind::Or { .. } = &*match_pair.pattern.kind {
+ if let PatKind::Or { .. } = &match_pair.pattern.kind {
return None;
}
@@ -708,9 +706,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
match_pair_index: usize,
candidate: &mut Candidate<'pat, 'tcx>,
- prefix: &'pat [Pat<'tcx>],
- opt_slice: Option<&'pat Pat<'tcx>>,
- suffix: &'pat [Pat<'tcx>],
+ prefix: &'pat [Box<Pat<'tcx>>],
+ opt_slice: &'pat Option<Box<Pat<'tcx>>>,
+ suffix: &'pat [Box<Pat<'tcx>>],
) {
let removed_place = candidate.match_pairs.remove(match_pair_index).place;
self.prefix_slice_suffix(
@@ -754,7 +752,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn const_range_contains(
&self,
- range: PatRange<'tcx>,
+ range: &PatRange<'tcx>,
value: ConstantKind<'tcx>,
) -> Option<bool> {
use std::cmp::Ordering::*;
@@ -772,7 +770,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn values_not_contained_in_range(
&self,
- range: PatRange<'tcx>,
+ range: &PatRange<'tcx>,
options: &FxIndexMap<ConstantKind<'tcx>, u128>,
) -> Option<bool> {
for &val in options.keys() {
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index 9a1e98d3b..b61c4fe50 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -26,19 +26,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
place: &PlaceBuilder<'tcx>,
- prefix: &'pat [Pat<'tcx>],
- opt_slice: Option<&'pat Pat<'tcx>>,
- suffix: &'pat [Pat<'tcx>],
+ prefix: &'pat [Box<Pat<'tcx>>],
+ opt_slice: &'pat Option<Box<Pat<'tcx>>>,
+ suffix: &'pat [Box<Pat<'tcx>>],
) {
let tcx = self.tcx;
let (min_length, exact_size) = if let Ok(place_resolved) =
- place.clone().try_upvars_resolved(tcx, self.typeck_results)
+ place.clone().try_upvars_resolved(tcx, &self.upvars)
{
- match place_resolved
- .into_place(tcx, self.typeck_results)
- .ty(&self.local_decls, tcx)
- .ty
- .kind()
+ match place_resolved.into_place(tcx, &self.upvars).ty(&self.local_decls, tcx).ty.kind()
{
ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
_ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 12b8ceede..25c4e51cb 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -1,15 +1,14 @@
-use crate::build;
pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant;
use crate::build::expr::as_place::PlaceBuilder;
use crate::build::scope::DropKind;
-use crate::thir::pattern::pat_from_hir;
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::Float;
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sorted_map::SortedIndexMultiMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::lang_items::LangItem;
use rustc_hir::{GeneratorKind, Node};
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -18,8 +17,9 @@ use rustc_middle::middle::region;
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::*;
-use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir};
-use rustc_middle::ty::subst::Subst;
+use rustc_middle::thir::{
+ self, BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
+};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
use rustc_span::symbol::sym;
use rustc_span::Span;
@@ -47,9 +47,7 @@ pub(crate) fn mir_built<'tcx>(
/// Construct the MIR for a given `DefId`.
fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
- let id = tcx.hir().local_def_id_to_hir_id(def.did);
let body_owner_kind = tcx.hir().body_owner_kind(def.did);
- let typeck_results = tcx.typeck_opt_const_arg(def);
// Ensure unsafeck and abstract const building is ran before we steal the THIR.
// We can't use `ensure()` for `thir_abstract_const` as it doesn't compute the query
@@ -66,235 +64,42 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
}
}
- // Figure out what primary body this item has.
- let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
- Node::Expr(hir::Expr {
- kind: hir::ExprKind::Closure(hir::Closure { fn_decl, body, .. }),
- ..
- }) => (*body, fn_decl.output.span(), None),
- Node::Item(hir::Item {
- kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
- span,
- ..
- })
- | Node::ImplItem(hir::ImplItem {
- kind: hir::ImplItemKind::Fn(hir::FnSig { decl, .. }, body_id),
- span,
- ..
- })
- | Node::TraitItem(hir::TraitItem {
- kind: hir::TraitItemKind::Fn(hir::FnSig { decl, .. }, hir::TraitFn::Provided(body_id)),
- span,
- ..
- }) => {
- // Use the `Span` of the `Item/ImplItem/TraitItem` as the body span,
- // since the def span of a function does not include the body
- (*body_id, decl.output.span(), Some(*span))
- }
- Node::Item(hir::Item {
- kind: hir::ItemKind::Static(ty, _, body_id) | hir::ItemKind::Const(ty, body_id),
- ..
- })
- | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, body_id), .. })
- | Node::TraitItem(hir::TraitItem {
- kind: hir::TraitItemKind::Const(ty, Some(body_id)),
- ..
- }) => (*body_id, ty.span, None),
- Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => {
- (*body, tcx.hir().span(*hir_id), None)
- }
-
- _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def.did),
- };
-
- // If we don't have a specialized span for the body, just use the
- // normal def span.
- let span_with_body = span_with_body.unwrap_or_else(|| tcx.hir().span(id));
-
- tcx.infer_ctxt().enter(|infcx| {
- let body = if let Some(error_reported) = typeck_results.tainted_by_errors {
- build::construct_error(&infcx, def, id, body_id, body_owner_kind, error_reported)
- } else if body_owner_kind.is_fn_or_closure() {
- // fetch the fully liberated fn signature (that is, all bound
- // types/lifetimes replaced)
- let fn_sig = typeck_results.liberated_fn_sigs()[id];
- let fn_def_id = tcx.hir().local_def_id(id);
-
- let safety = match fn_sig.unsafety {
- hir::Unsafety::Normal => Safety::Safe,
- hir::Unsafety::Unsafe => Safety::FnUnsafe,
- };
-
- let body = tcx.hir().body(body_id);
- let (thir, expr) = tcx
- .thir_body(def)
- .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)));
+ let body = match tcx.thir_body(def) {
+ Err(error_reported) => construct_error(tcx, def.did, body_owner_kind, error_reported),
+ Ok((thir, expr)) => {
// We ran all queries that depended on THIR at the beginning
// of `mir_build`, so now we can steal it
let thir = thir.steal();
- let ty = tcx.type_of(fn_def_id);
- let mut abi = fn_sig.abi;
- let implicit_argument = match ty.kind() {
- ty::Closure(..) => {
- // HACK(eddyb) Avoid having RustCall on closures,
- // as it adds unnecessary (and wrong) auto-tupling.
- abi = Abi::Rust;
- vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)]
- }
- ty::Generator(..) => {
- let gen_ty = tcx.typeck_body(body_id).node_type(id);
-
- // The resume argument may be missing, in that case we need to provide it here.
- // It will always be `()` in this case.
- if body.params.is_empty() {
- vec![
- ArgInfo(gen_ty, None, None, None),
- ArgInfo(tcx.mk_unit(), None, None, None),
- ]
- } else {
- vec![ArgInfo(gen_ty, None, None, None)]
- }
- }
- _ => vec![],
- };
-
- let explicit_arguments = body.params.iter().enumerate().map(|(index, arg)| {
- let owner_id = tcx.hir().body_owner(body_id);
- let opt_ty_info;
- let self_arg;
- if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) {
- opt_ty_info = fn_decl
- .inputs
- .get(index)
- // Make sure that inferred closure args have no type span
- .and_then(|ty| if arg.pat.span != ty.span { Some(ty.span) } else { None });
- self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
- match fn_decl.implicit_self {
- hir::ImplicitSelfKind::Imm => Some(ImplicitSelfKind::Imm),
- hir::ImplicitSelfKind::Mut => Some(ImplicitSelfKind::Mut),
- hir::ImplicitSelfKind::ImmRef => Some(ImplicitSelfKind::ImmRef),
- hir::ImplicitSelfKind::MutRef => Some(ImplicitSelfKind::MutRef),
- _ => None,
- }
- } else {
- None
- };
- } else {
- opt_ty_info = None;
- self_arg = None;
- }
-
- // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
- // (as it's created inside the body itself, not passed in from outside).
- let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() {
- let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(arg.span));
-
- tcx.bound_type_of(va_list_did).subst(tcx, &[tcx.lifetimes.re_erased.into()])
- } else {
- fn_sig.inputs()[index]
- };
-
- ArgInfo(ty, opt_ty_info, Some(&arg), self_arg)
- });
- let arguments = implicit_argument.into_iter().chain(explicit_arguments);
-
- let (yield_ty, return_ty) = if body.generator_kind.is_some() {
- let gen_ty = tcx.typeck_body(body_id).node_type(id);
- let gen_sig = match gen_ty.kind() {
- ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
- _ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
- };
- (Some(gen_sig.yield_ty), gen_sig.return_ty)
+ if body_owner_kind.is_fn_or_closure() {
+ construct_fn(tcx, def, &thir, expr)
} else {
- (None, fn_sig.output())
- };
-
- let mut mir = build::construct_fn(
- &thir,
- &infcx,
- def,
- id,
- arguments,
- safety,
- abi,
- return_ty,
- return_ty_span,
- body,
- expr,
- span_with_body,
- );
- if yield_ty.is_some() {
- mir.generator.as_mut().unwrap().yield_ty = yield_ty;
+ construct_const(tcx, def, &thir, expr)
}
- mir
- } else {
- // Get the revealed type of this const. This is *not* the adjusted
- // type of its body, which may be a subtype of this type. For
- // example:
- //
- // fn foo(_: &()) {}
- // static X: fn(&'static ()) = foo;
- //
- // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
- // is not the same as the type of X. We need the type of the return
- // place to be the type of the constant because NLL typeck will
- // equate them.
-
- let return_ty = typeck_results.node_type(id);
-
- let (thir, expr) = tcx
- .thir_body(def)
- .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)));
- // We ran all queries that depended on THIR at the beginning
- // of `mir_build`, so now we can steal it
- let thir = thir.steal();
-
- build::construct_const(&thir, &infcx, expr, def, id, return_ty, return_ty_span)
- };
+ }
+ };
- lints::check(tcx, &body);
-
- // The borrow checker will replace all the regions here with its own
- // inference variables. There's no point having non-erased regions here.
- // The exception is `body.user_type_annotations`, which is used unmodified
- // by borrow checking.
- debug_assert!(
- !(body.local_decls.has_free_regions()
- || body.basic_blocks().has_free_regions()
- || body.var_debug_info.has_free_regions()
- || body.yield_ty().has_free_regions()),
- "Unexpected free regions in MIR: {:?}",
- body,
- );
+ lints::check(tcx, &body);
+
+ // The borrow checker will replace all the regions here with its own
+ // inference variables. There's no point having non-erased regions here.
+ // The exception is `body.user_type_annotations`, which is used unmodified
+ // by borrow checking.
+ debug_assert!(
+ !(body.local_decls.has_free_regions()
+ || body.basic_blocks.has_free_regions()
+ || body.var_debug_info.has_free_regions()
+ || body.yield_ty().has_free_regions()),
+ "Unexpected free regions in MIR: {:?}",
+ body,
+ );
- body
- })
+ body
}
///////////////////////////////////////////////////////////////////////////
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
-fn liberated_closure_env_ty(
- tcx: TyCtxt<'_>,
- closure_expr_id: hir::HirId,
- body_id: hir::BodyId,
-) -> Ty<'_> {
- let closure_ty = tcx.typeck_body(body_id).node_type(closure_expr_id);
-
- let ty::Closure(closure_def_id, closure_substs) = *closure_ty.kind() else {
- bug!("closure expr does not have closure type: {:?}", closure_ty);
- };
-
- let bound_vars =
- tcx.mk_bound_variable_kinds(std::iter::once(ty::BoundVariableKind::Region(ty::BrEnv)));
- let br =
- ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv };
- let env_region = ty::ReLateBound(ty::INNERMOST, br);
- let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
- tcx.erase_late_bound_regions(ty::Binder::bind_with_vars(closure_env_ty, bound_vars))
-}
-
#[derive(Debug, PartialEq, Eq)]
enum BlockFrame {
/// Evaluation is currently within a statement.
@@ -352,7 +157,7 @@ struct BlockContext(Vec<BlockFrame>);
struct Builder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
- infcx: &'a InferCtxt<'a, 'tcx>,
+ infcx: InferCtxt<'a, 'tcx>,
typeck_results: &'tcx TypeckResults<'tcx>,
region_scope_tree: &'tcx region::ScopeTree,
param_env: ty::ParamEnv<'tcx>,
@@ -404,12 +209,21 @@ struct Builder<'a, 'tcx> {
var_indices: FxHashMap<LocalVarId, LocalsForNode>,
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
- upvar_mutbls: Vec<Mutability>,
+ upvars: CaptureMap<'tcx>,
unit_temp: Option<Place<'tcx>>,
var_debug_info: Vec<VarDebugInfo<'tcx>>,
}
+type CaptureMap<'tcx> = SortedIndexMultiMap<usize, hir::HirId, Capture<'tcx>>;
+
+#[derive(Debug)]
+struct Capture<'tcx> {
+ captured_place: &'tcx ty::CapturedPlace<'tcx>,
+ use_place: Place<'tcx>,
+ mutability: Mutability,
+}
+
impl<'a, 'tcx> Builder<'a, 'tcx> {
fn is_bound_var_in_guard(&self, id: LocalVarId) -> bool {
self.guard_context.iter().any(|frame| frame.locals.iter().any(|local| local.id == id))
@@ -615,149 +429,212 @@ macro_rules! unpack {
///////////////////////////////////////////////////////////////////////////
/// the main entry point for building MIR for a function
-struct ArgInfo<'tcx>(
- Ty<'tcx>,
- Option<Span>,
- Option<&'tcx hir::Param<'tcx>>,
- Option<ImplicitSelfKind>,
-);
-
-fn construct_fn<'tcx, A>(
- thir: &Thir<'tcx>,
- infcx: &InferCtxt<'_, 'tcx>,
+fn construct_fn<'tcx>(
+ tcx: TyCtxt<'tcx>,
fn_def: ty::WithOptConstParam<LocalDefId>,
- fn_id: hir::HirId,
- arguments: A,
- safety: Safety,
- abi: Abi,
- return_ty: Ty<'tcx>,
- return_ty_span: Span,
- body: &'tcx hir::Body<'tcx>,
+ thir: &Thir<'tcx>,
expr: ExprId,
- span_with_body: Span,
-) -> Body<'tcx>
-where
- A: Iterator<Item = ArgInfo<'tcx>>,
-{
- let arguments: Vec<_> = arguments.collect();
-
- let tcx = infcx.tcx;
- let span = tcx.hir().span(fn_id);
-
- let mut builder = Builder::new(
- thir,
- infcx,
- fn_def,
- fn_id,
- span_with_body,
- arguments.len(),
- safety,
- return_ty,
- return_ty_span,
- body.generator_kind,
- );
+) -> Body<'tcx> {
+ let span = tcx.def_span(fn_def.did);
+ let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did);
+ let generator_kind = tcx.generator_kind(fn_def.did);
- let call_site_scope =
- region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite };
- let arg_scope =
- region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::Arguments };
- let source_info = builder.source_info(span);
- let call_site_s = (call_site_scope, source_info);
- unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
- let arg_scope_s = (arg_scope, source_info);
- // Attribute epilogue to function's closing brace
- let fn_end = span_with_body.shrink_to_hi();
- let return_block =
- unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
- Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
- builder.args_and_body(
- START_BLOCK,
- fn_def.did,
- &arguments,
- arg_scope,
- &thir[expr],
- )
- }))
- }));
- let source_info = builder.source_info(fn_end);
- builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
- builder.build_drop_trees();
- return_block.unit()
- }));
+ // Figure out what primary body this item has.
+ let body_id = tcx.hir().body_owned_by(fn_def.did);
+ let span_with_body = tcx.hir().span_with_body(fn_id);
+ let return_ty_span = tcx
+ .hir()
+ .fn_decl_by_hir_id(fn_id)
+ .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def.did))
+ .output
+ .span();
+
+ // fetch the fully liberated fn signature (that is, all bound
+ // types/lifetimes replaced)
+ let typeck_results = tcx.typeck_opt_const_arg(fn_def);
+ let fn_sig = typeck_results.liberated_fn_sigs()[fn_id];
+
+ let safety = match fn_sig.unsafety {
+ hir::Unsafety::Normal => Safety::Safe,
+ hir::Unsafety::Unsafe => Safety::FnUnsafe,
+ };
+
+ let mut abi = fn_sig.abi;
+ if let DefKind::Closure = tcx.def_kind(fn_def.did) {
+ // HACK(eddyb) Avoid having RustCall on closures,
+ // as it adds unnecessary (and wrong) auto-tupling.
+ abi = Abi::Rust;
+ }
+
+ let arguments = &thir.params;
+
+ let (yield_ty, return_ty) = if generator_kind.is_some() {
+ let gen_ty = arguments[thir::UPVAR_ENV_PARAM].ty;
+ let gen_sig = match gen_ty.kind() {
+ ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
+ _ => {
+ span_bug!(span, "generator w/o generator type: {:?}", gen_ty)
+ }
+ };
+ (Some(gen_sig.yield_ty), gen_sig.return_ty)
+ } else {
+ (None, fn_sig.output())
+ };
+
+ let mut body = tcx.infer_ctxt().enter(|infcx| {
+ let mut builder = Builder::new(
+ thir,
+ infcx,
+ fn_def,
+ fn_id,
+ span_with_body,
+ arguments.len(),
+ safety,
+ return_ty,
+ return_ty_span,
+ generator_kind,
+ );
+
+ let call_site_scope =
+ region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::CallSite };
+ let arg_scope =
+ region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::Arguments };
+ let source_info = builder.source_info(span);
+ let call_site_s = (call_site_scope, source_info);
+ unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
+ let arg_scope_s = (arg_scope, source_info);
+ // Attribute epilogue to function's closing brace
+ let fn_end = span_with_body.shrink_to_hi();
+ let return_block = unpack!(builder.in_breakable_scope(
+ None,
+ Place::return_place(),
+ fn_end,
+ |builder| {
+ Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
+ builder.args_and_body(
+ START_BLOCK,
+ fn_def.did,
+ arguments,
+ arg_scope,
+ &thir[expr],
+ )
+ }))
+ }
+ ));
+ let source_info = builder.source_info(fn_end);
+ builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
+ builder.build_drop_trees();
+ return_block.unit()
+ }));
+
+ builder.finish()
+ });
- let spread_arg = if abi == Abi::RustCall {
+ body.spread_arg = if abi == Abi::RustCall {
// RustCall pseudo-ABI untuples the last argument.
Some(Local::new(arguments.len()))
} else {
None
};
-
- let mut body = builder.finish();
- body.spread_arg = spread_arg;
+ if yield_ty.is_some() {
+ body.generator.as_mut().unwrap().yield_ty = yield_ty;
+ }
body
}
fn construct_const<'a, 'tcx>(
+ tcx: TyCtxt<'tcx>,
+ def: ty::WithOptConstParam<LocalDefId>,
thir: &'a Thir<'tcx>,
- infcx: &'a InferCtxt<'a, 'tcx>,
expr: ExprId,
- def: ty::WithOptConstParam<LocalDefId>,
- hir_id: hir::HirId,
- const_ty: Ty<'tcx>,
- const_ty_span: Span,
) -> Body<'tcx> {
- let tcx = infcx.tcx;
- let span = tcx.hir().span(hir_id);
- let mut builder = Builder::new(
- thir,
- infcx,
- def,
- hir_id,
- span,
- 0,
- Safety::Safe,
- const_ty,
- const_ty_span,
- None,
- );
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
+
+ // Figure out what primary body this item has.
+ let (span, const_ty_span) = match tcx.hir().get(hir_id) {
+ Node::Item(hir::Item {
+ kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _),
+ span,
+ ..
+ })
+ | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, _), span, .. })
+ | Node::TraitItem(hir::TraitItem {
+ kind: hir::TraitItemKind::Const(ty, Some(_)),
+ span,
+ ..
+ }) => (*span, ty.span),
+ Node::AnonConst(_) => {
+ let span = tcx.def_span(def.did);
+ (span, span)
+ }
+ _ => span_bug!(tcx.def_span(def.did), "can't build MIR for {:?}", def.did),
+ };
+
+ // Get the revealed type of this const. This is *not* the adjusted
+ // type of its body, which may be a subtype of this type. For
+ // example:
+ //
+ // fn foo(_: &()) {}
+ // static X: fn(&'static ()) = foo;
+ //
+ // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
+ // is not the same as the type of X. We need the type of the return
+ // place to be the type of the constant because NLL typeck will
+ // equate them.
+ let typeck_results = tcx.typeck_opt_const_arg(def);
+ let const_ty = typeck_results.node_type(hir_id);
+
+ tcx.infer_ctxt().enter(|infcx| {
+ let mut builder = Builder::new(
+ thir,
+ infcx,
+ def,
+ hir_id,
+ span,
+ 0,
+ Safety::Safe,
+ const_ty,
+ const_ty_span,
+ None,
+ );
- let mut block = START_BLOCK;
- unpack!(block = builder.expr_into_dest(Place::return_place(), block, &thir[expr]));
+ let mut block = START_BLOCK;
+ unpack!(block = builder.expr_into_dest(Place::return_place(), block, &thir[expr]));
- let source_info = builder.source_info(span);
- builder.cfg.terminate(block, source_info, TerminatorKind::Return);
+ let source_info = builder.source_info(span);
+ builder.cfg.terminate(block, source_info, TerminatorKind::Return);
- builder.build_drop_trees();
+ builder.build_drop_trees();
- builder.finish()
+ builder.finish()
+ })
}
/// Construct MIR for an item that has had errors in type checking.
///
/// This is required because we may still want to run MIR passes on an item
/// with type errors, but normal MIR construction can't handle that in general.
-fn construct_error<'a, 'tcx>(
- infcx: &'a InferCtxt<'a, 'tcx>,
- def: ty::WithOptConstParam<LocalDefId>,
- hir_id: hir::HirId,
- body_id: hir::BodyId,
+fn construct_error<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ def: LocalDefId,
body_owner_kind: hir::BodyOwnerKind,
err: ErrorGuaranteed,
) -> Body<'tcx> {
- let tcx = infcx.tcx;
- let span = tcx.hir().span(hir_id);
+ let span = tcx.def_span(def);
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def);
+ let generator_kind = tcx.generator_kind(def);
+
let ty = tcx.ty_error();
- let generator_kind = tcx.hir().body(body_id).generator_kind;
let num_params = match body_owner_kind {
- hir::BodyOwnerKind::Fn => tcx.hir().fn_decl_by_hir_id(hir_id).unwrap().inputs.len(),
+ hir::BodyOwnerKind::Fn => tcx.fn_sig(def).inputs().skip_binder().len(),
hir::BodyOwnerKind::Closure => {
- if generator_kind.is_some() {
- // Generators have an implicit `self` parameter *and* a possibly
- // implicit resume parameter.
- 2
- } else {
- // The implicit self parameter adds another local in MIR.
- 1 + tcx.hir().fn_decl_by_hir_id(hir_id).unwrap().inputs.len()
+ let ty = tcx.type_of(def);
+ match ty.kind() {
+ ty::Closure(_, substs) => {
+ 1 + substs.as_closure().sig().inputs().skip_binder().len()
+ }
+ ty::Generator(..) => 2,
+ _ => bug!("expected closure or generator, found {ty:?}"),
}
}
hir::BodyOwnerKind::Const => 0,
@@ -788,7 +665,7 @@ fn construct_error<'a, 'tcx>(
cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
let mut body = Body::new(
- MirSource::item(def.did.to_def_id()),
+ MirSource::item(def.to_def_id()),
cfg.basic_blocks,
source_scopes,
local_decls,
@@ -806,7 +683,7 @@ fn construct_error<'a, 'tcx>(
impl<'a, 'tcx> Builder<'a, 'tcx> {
fn new(
thir: &'a Thir<'tcx>,
- infcx: &'a InferCtxt<'a, 'tcx>,
+ infcx: InferCtxt<'a, 'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
hir_id: hir::HirId,
span: Span,
@@ -855,7 +732,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
in_scope_unsafe: safety,
local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1),
canonical_user_type_annotations: IndexVec::new(),
- upvar_mutbls: vec![],
+ upvars: CaptureMap::new(),
var_indices: Default::default(),
unit_temp: None,
var_debug_info: vec![],
@@ -896,20 +773,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
mut block: BasicBlock,
fn_def_id: LocalDefId,
- arguments: &[ArgInfo<'tcx>],
+ arguments: &IndexVec<ParamId, Param<'tcx>>,
argument_scope: region::Scope,
expr: &Expr<'tcx>,
) -> BlockAnd<()> {
// Allocate locals for the function arguments
- for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
+ for param in arguments.iter() {
let source_info =
- SourceInfo::outermost(arg_opt.map_or(self.fn_span, |arg| arg.pat.span));
- let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info));
+ SourceInfo::outermost(param.pat.as_ref().map_or(self.fn_span, |pat| pat.span));
+ let arg_local =
+ self.local_decls.push(LocalDecl::with_source_info(param.ty, source_info));
// If this is a simple binding pattern, give debuginfo a nice name.
- if let Some(arg) = arg_opt && let Some(ident) = arg.pat.simple_ident() {
+ if let Some(ref pat) = param.pat && let Some(name) = pat.simple_ident() {
self.var_debug_info.push(VarDebugInfo {
- name: ident.name,
+ name,
source_info,
value: VarDebugInfoContents::Place(arg_local.into()),
});
@@ -924,7 +802,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// indexed closure and we stored in a map called closure_min_captures in TypeckResults
// with the closure's DefId. Here, we run through that vec of UpvarIds for
// the given closure and use the necessary information to create upvar
- // debuginfo and to fill `self.upvar_mutbls`.
+ // debuginfo and to fill `self.upvars`.
if hir_typeck_results.closure_min_captures.get(&fn_def_id).is_some() {
let mut closure_env_projs = vec![];
let mut closure_ty = self.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
@@ -944,7 +822,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.closure_min_captures_flattened(fn_def_id)
.zip(capture_tys.zip(capture_syms));
- self.upvar_mutbls = captures_with_tys
+ self.upvars = captures_with_tys
.enumerate()
.map(|(i, (captured_place, (ty, sym)))| {
let capture = captured_place.info.capture_kind;
@@ -964,48 +842,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
};
+ let use_place = Place {
+ local: ty::CAPTURE_STRUCT_LOCAL,
+ projection: tcx.intern_place_elems(&projs),
+ };
self.var_debug_info.push(VarDebugInfo {
name: *sym,
source_info: SourceInfo::outermost(tcx_hir.span(var_id)),
- value: VarDebugInfoContents::Place(Place {
- local: ty::CAPTURE_STRUCT_LOCAL,
- projection: tcx.intern_place_elems(&projs),
- }),
+ value: VarDebugInfoContents::Place(use_place),
});
- mutability
+ let capture = Capture { captured_place, use_place, mutability };
+ (var_id, capture)
})
.collect();
}
let mut scope = None;
// Bind the argument patterns
- for (index, arg_info) in arguments.iter().enumerate() {
+ for (index, param) in arguments.iter().enumerate() {
// Function arguments always get the first Local indices after the return place
let local = Local::new(index + 1);
let place = Place::from(local);
- let &ArgInfo(_, opt_ty_info, arg_opt, ref self_binding) = arg_info;
// Make sure we drop (parts of) the argument even when not matched on.
self.schedule_drop(
- arg_opt.as_ref().map_or(expr.span, |arg| arg.pat.span),
+ param.pat.as_ref().map_or(expr.span, |pat| pat.span),
argument_scope,
local,
DropKind::Value,
);
- let Some(arg) = arg_opt else {
+ let Some(ref pat) = param.pat else {
continue;
};
- let pat = match tcx.hir().get(arg.pat.hir_id) {
- Node::Pat(pat) => pat,
- node => bug!("pattern became {:?}", node),
- };
- let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat);
let original_source_scope = self.source_scope;
- let span = pattern.span;
- self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
- match *pattern.kind {
+ let span = pat.span;
+ if let Some(arg_hir_id) = param.hir_id {
+ self.set_correct_source_scope_for_arg(arg_hir_id, original_source_scope, span);
+ }
+ match pat.kind {
// Don't introduce extra copies for simple bindings
PatKind::Binding {
mutability,
@@ -1016,17 +892,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} => {
self.local_decls[local].mutability = mutability;
self.local_decls[local].source_info.scope = self.source_scope;
- self.local_decls[local].local_info = if let Some(kind) = self_binding {
+ self.local_decls[local].local_info = if let Some(kind) = param.self_kind {
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
- BindingForm::ImplicitSelf(*kind),
+ BindingForm::ImplicitSelf(kind),
))))
} else {
let binding_mode = ty::BindingMode::BindByValue(mutability);
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
VarBindingForm {
binding_mode,
- opt_ty_info,
- opt_match_place: Some((Some(place), span)),
+ opt_ty_info: param.ty_span,
+ opt_match_place: Some((None, span)),
pat_span: span,
},
)))))
@@ -1037,12 +913,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
scope = self.declare_bindings(
scope,
expr.span,
- &pattern,
+ &pat,
matches::ArmHasGuard(false),
Some((Some(&place), span)),
);
let place_builder = PlaceBuilder::from(local);
- unpack!(block = self.place_into_pattern(block, pattern, place_builder, false));
+ unpack!(block = self.place_into_pattern(block, &pat, place_builder, false));
}
}
self.source_scope = original_source_scope;
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index b2fd9f25b..ff66ca595 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -466,9 +466,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let normal_exit_block = f(self);
let breakable_scope = self.scopes.breakable_scopes.pop().unwrap();
assert!(breakable_scope.region_scope == region_scope);
- let break_block = self.build_exit_tree(breakable_scope.break_drops, None);
+ let break_block =
+ self.build_exit_tree(breakable_scope.break_drops, region_scope, span, None);
if let Some(drops) = breakable_scope.continue_drops {
- self.build_exit_tree(drops, loop_block);
+ self.build_exit_tree(drops, region_scope, span, loop_block);
}
match (normal_exit_block, break_block) {
(Some(block), None) | (None, Some(block)) => block,
@@ -510,6 +511,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub(crate) fn in_if_then_scope<F>(
&mut self,
region_scope: region::Scope,
+ span: Span,
f: F,
) -> (BasicBlock, BasicBlock)
where
@@ -524,7 +526,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
assert!(if_then_scope.region_scope == region_scope);
let else_block = self
- .build_exit_tree(if_then_scope.else_drops, None)
+ .build_exit_tree(if_then_scope.else_drops, region_scope, span, None)
.map_or_else(|| self.cfg.start_new_block(), |else_block_and| unpack!(else_block_and));
(then_block, else_block)
@@ -997,10 +999,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Returns the [DropIdx] for the innermost drop if the function unwound at
/// this point. The `DropIdx` will be created if it doesn't already exist.
fn diverge_cleanup(&mut self) -> DropIdx {
- let is_generator = self.generator_kind.is_some();
- let (uncached_scope, mut cached_drop) = self
- .scopes
- .scopes
+ // It is okay to use dummy span because the getting scope index on the topmost scope
+ // must always succeed.
+ self.diverge_cleanup_target(self.scopes.topmost(), DUMMY_SP)
+ }
+
+ /// This is similar to [diverge_cleanup](Self::diverge_cleanup) except its target is set to
+ /// some ancestor scope instead of the current scope.
+ /// It is possible to unwind to some ancestor scope if some drop panics as
+ /// the program breaks out of a if-then scope.
+ fn diverge_cleanup_target(&mut self, target_scope: region::Scope, span: Span) -> DropIdx {
+ let target = self.scopes.scope_index(target_scope, span);
+ let (uncached_scope, mut cached_drop) = self.scopes.scopes[..=target]
.iter()
.enumerate()
.rev()
@@ -1009,7 +1019,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.unwrap_or((0, ROOT_NODE));
- for scope in &mut self.scopes.scopes[uncached_scope..] {
+ if uncached_scope > target {
+ return cached_drop;
+ }
+
+ let is_generator = self.generator_kind.is_some();
+ for scope in &mut self.scopes.scopes[uncached_scope..=target] {
for drop in &scope.drops {
if is_generator || drop.kind == DropKind::Value {
cached_drop = self.scopes.unwind_drops.add_drop(*drop, cached_drop);
@@ -1222,21 +1237,24 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
fn build_exit_tree(
&mut self,
mut drops: DropTree,
+ else_scope: region::Scope,
+ span: Span,
continue_block: Option<BasicBlock>,
) -> Option<BlockAnd<()>> {
let mut blocks = IndexVec::from_elem(None, &drops.drops);
blocks[ROOT_NODE] = continue_block;
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
+ let is_generator = self.generator_kind.is_some();
// Link the exit drop tree to unwind drop tree.
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
- let unwind_target = self.diverge_cleanup();
+ let unwind_target = self.diverge_cleanup_target(else_scope, span);
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
match drop_data.0.kind {
DropKind::Storage => {
- if self.generator_kind.is_some() {
+ if is_generator {
let unwind_drop = self
.scopes
.unwind_drops
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 864caf0ba..495738ebe 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -75,10 +75,11 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
match self.safety_context {
SafetyContext::BuiltinUnsafeBlock => {}
SafetyContext::UnsafeBlock { ref mut used, .. } => {
- if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
- // Mark this block as useful
- *used = true;
- }
+ // Mark this block as useful (even inside `unsafe fn`, where it is technically
+ // redundant -- but we want to eventually enable `unsafe_op_in_unsafe_fn` by
+ // default which will require those blocks:
+ // https://github.com/rust-lang/rust/issues/71668#issuecomment-1203075594).
+ *used = true;
}
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
SafetyContext::UnsafeFn => {
@@ -213,7 +214,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
fn visit_pat(&mut self, pat: &Pat<'tcx>) {
if self.in_union_destructure {
- match *pat.kind {
+ match pat.kind {
// binding to a variable allows getting stuff out of variable
PatKind::Binding { .. }
// match is conditional on having this value
@@ -235,7 +236,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
}
};
- match &*pat.kind {
+ match &pat.kind {
PatKind::Leaf { .. } => {
if let ty::Adt(adt_def, ..) = pat.ty.kind() {
if adt_def.is_union() {
@@ -390,7 +391,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
ExprKind::InlineAsm { .. } => {
self.requires_unsafe(expr.span, UseOfInlineAssembly);
}
- ExprKind::Adt(box Adt {
+ ExprKind::Adt(box AdtExpr {
adt_def,
variant_index: _,
substs: _,
@@ -401,13 +402,13 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
(Bound::Unbounded, Bound::Unbounded) => {}
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
},
- ExprKind::Closure {
+ ExprKind::Closure(box ClosureExpr {
closure_id,
substs: _,
upvars: _,
movability: _,
fake_reads: _,
- } => {
+ }) => {
let closure_def = if let Some((did, const_param_id)) =
ty::WithOptConstParam::try_lookup(closure_id, self.tcx)
{
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 11cd2a9aa..0c0a2fe9c 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -6,7 +6,7 @@
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(once_cell)]
#![recursion_limit = "256"]
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index a7e4403a2..f626571b5 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -44,7 +44,7 @@ pub(crate) fn lit_to_const<'tcx>(
}
(ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
(ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
- (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported),
+ (ast::LitKind::Err, _) => return Err(LitToConstError::Reported),
_ => return Err(LitToConstError::TypeError),
};
diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs
index dccaa61ed..321353ca2 100644
--- a/compiler/rustc_mir_build/src/thir/cx/block.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/block.rs
@@ -9,13 +9,13 @@ use rustc_index::vec::Idx;
use rustc_middle::ty::CanonicalUserTypeAnnotation;
impl<'tcx> Cx<'tcx> {
- pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block {
+ pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> BlockId {
// We have to eagerly lower the "spine" of the statements
// in order to get the lexical scoping correctly.
let stmts = self.mirror_stmts(block.hir_id.local_id, block.stmts);
let opt_destruction_scope =
self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id);
- Block {
+ let block = Block {
targeted_by_break: block.targeted_by_break,
region_scope: region::Scope {
id: block.hir_id.local_id,
@@ -34,7 +34,9 @@ impl<'tcx> Cx<'tcx> {
BlockSafety::ExplicitUnsafe(block.hir_id)
}
},
- }
+ };
+
+ self.thir.blocks.push(block)
}
fn mirror_stmts(
@@ -85,21 +87,21 @@ impl<'tcx> Cx<'tcx> {
{
debug!("mirror_stmts: user_ty={:?}", user_ty);
let annotation = CanonicalUserTypeAnnotation {
- user_ty,
+ user_ty: Box::new(user_ty),
span: ty.span,
inferred_ty: self.typeck_results.node_type(ty.hir_id),
};
- pattern = Pat {
+ pattern = Box::new(Pat {
ty: pattern.ty,
span: pattern.span,
- kind: Box::new(PatKind::AscribeUserType {
+ kind: PatKind::AscribeUserType {
ascription: Ascription {
annotation,
variance: ty::Variance::Covariant,
},
subpattern: pattern,
- }),
- };
+ },
+ });
}
}
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 985601712..d059877f8 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -108,8 +108,8 @@ impl<'tcx> Cx<'tcx> {
// // ^ error message points at this expression.
// }
let mut adjust_span = |expr: &mut Expr<'tcx>| {
- if let ExprKind::Block { body } = &expr.kind {
- if let Some(last_expr) = body.expr {
+ if let ExprKind::Block { block } = expr.kind {
+ if let Some(last_expr) = self.thir[block].expr {
span = self.thir[last_expr].span;
expr.span = span;
}
@@ -261,15 +261,19 @@ impl<'tcx> Cx<'tcx> {
let kind = match expr.kind {
// Here comes the interesting stuff:
- hir::ExprKind::MethodCall(segment, ref args, fn_span) => {
+ hir::ExprKind::MethodCall(segment, receiver, ref args, fn_span) => {
// Rewrite a.b(c) into UFCS form like Trait::b(a, c)
let expr = self.method_callee(expr, segment.ident.span, None);
// When we apply adjustments to the receiver, use the span of
// the overall method call for better diagnostics. args[0]
// is guaranteed to exist, since a method call always has a receiver.
- let old_adjustment_span = self.adjustment_span.replace((args[0].hir_id, expr_span));
- tracing::info!("Using method span: {:?}", expr.span);
- let args = self.mirror_exprs(args);
+ let old_adjustment_span =
+ self.adjustment_span.replace((receiver.hir_id, expr_span));
+ info!("Using method span: {:?}", expr.span);
+ let args = std::iter::once(receiver)
+ .chain(args.iter())
+ .map(|expr| self.mirror_expr(expr))
+ .collect();
self.adjustment_span = old_adjustment_span;
ExprKind::Call {
ty: expr.ty,
@@ -329,7 +333,7 @@ impl<'tcx> Cx<'tcx> {
if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
*did = adt_def.did();
}
- u_ty
+ Box::new(u_ty)
});
debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty);
@@ -341,7 +345,7 @@ impl<'tcx> Cx<'tcx> {
expr: self.mirror_expr(e),
})
.collect();
- ExprKind::Adt(Box::new(Adt {
+ ExprKind::Adt(Box::new(AdtExpr {
adt_def,
substs,
variant_index: index,
@@ -369,7 +373,7 @@ impl<'tcx> Cx<'tcx> {
ExprKind::AddressOf { mutability, arg: self.mirror_expr(arg) }
}
- hir::ExprKind::Block(ref blk, _) => ExprKind::Block { body: self.mirror_block(blk) },
+ hir::ExprKind::Block(ref blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
hir::ExprKind::Assign(ref lhs, ref rhs, _) => {
ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) }
@@ -464,9 +468,9 @@ impl<'tcx> Cx<'tcx> {
ty::Adt(adt, substs) => match adt.adt_kind() {
AdtKind::Struct | AdtKind::Union => {
let user_provided_types = self.typeck_results().user_provided_types();
- let user_ty = user_provided_types.get(expr.hir_id).copied();
+ let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
- ExprKind::Adt(Box::new(Adt {
+ ExprKind::Adt(Box::new(AdtExpr {
adt_def: *adt,
variant_index: VariantIdx::new(0),
substs,
@@ -490,9 +494,10 @@ impl<'tcx> Cx<'tcx> {
let index = adt.variant_index_with_id(variant_id);
let user_provided_types =
self.typeck_results().user_provided_types();
- let user_ty = user_provided_types.get(expr.hir_id).copied();
+ let user_ty =
+ user_provided_types.get(expr.hir_id).copied().map(Box::new);
debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
- ExprKind::Adt(Box::new(Adt {
+ ExprKind::Adt(Box::new(AdtExpr {
adt_def: *adt,
variant_index: index,
substs,
@@ -547,7 +552,13 @@ impl<'tcx> Cx<'tcx> {
None => Vec::new(),
};
- ExprKind::Closure { closure_id: def_id, substs, upvars, movability, fake_reads }
+ ExprKind::Closure(Box::new(ClosureExpr {
+ closure_id: def_id,
+ substs,
+ upvars,
+ movability,
+ fake_reads,
+ }))
}
hir::ExprKind::Path(ref qpath) => {
@@ -555,7 +566,7 @@ impl<'tcx> Cx<'tcx> {
self.convert_path_expr(expr, res)
}
- hir::ExprKind::InlineAsm(ref asm) => ExprKind::InlineAsm {
+ hir::ExprKind::InlineAsm(ref asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
template: asm.template,
operands: asm
.operands
@@ -614,7 +625,7 @@ impl<'tcx> Cx<'tcx> {
.collect(),
options: asm.options,
line_spans: asm.line_spans,
- },
+ })),
hir::ExprKind::ConstBlock(ref anon_const) => {
let ty = self.typeck_results().node_type(anon_const.hir_id);
@@ -679,8 +690,8 @@ impl<'tcx> Cx<'tcx> {
let body = self.thir.exprs.push(Expr {
ty: block_ty,
temp_lifetime,
- span: block.span,
- kind: ExprKind::Block { body: block },
+ span: self.thir[block].span,
+ kind: ExprKind::Block { block },
});
ExprKind::Loop { body }
}
@@ -712,14 +723,17 @@ impl<'tcx> Cx<'tcx> {
});
debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty);
- ExprKind::ValueTypeAscription { source: cast_expr, user_ty: Some(*user_ty) }
+ ExprKind::ValueTypeAscription {
+ source: cast_expr,
+ user_ty: Some(Box::new(*user_ty)),
+ }
} else {
cast
}
}
hir::ExprKind::Type(ref source, ref ty) => {
let user_provided_types = self.typeck_results.user_provided_types();
- let user_ty = user_provided_types.get(ty.hir_id).copied();
+ let user_ty = user_provided_types.get(ty.hir_id).copied().map(Box::new);
debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
let mirrored = self.mirror_expr(source);
if source.is_syntactic_place_expr() {
@@ -748,7 +762,7 @@ impl<'tcx> Cx<'tcx> {
&mut self,
hir_id: hir::HirId,
res: Res,
- ) -> Option<ty::CanonicalUserType<'tcx>> {
+ ) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
debug!("user_substs_applied_to_res: res={:?}", res);
let user_provided_type = match res {
// A reference to something callable -- e.g., a fn, method, or
@@ -759,7 +773,7 @@ impl<'tcx> Cx<'tcx> {
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
| Res::Def(DefKind::Const, _)
| Res::Def(DefKind::AssocConst, _) => {
- self.typeck_results().user_provided_types().get(hir_id).copied()
+ self.typeck_results().user_provided_types().get(hir_id).copied().map(Box::new)
}
// A unit struct/variant which is used as a value (e.g.,
@@ -767,11 +781,11 @@ impl<'tcx> Cx<'tcx> {
// this variant -- but with the substitutions given by the
// user.
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
- self.user_substs_applied_to_ty_of_hir_id(hir_id)
+ self.user_substs_applied_to_ty_of_hir_id(hir_id).map(Box::new)
}
// `Self` is used in expression as a tuple struct constructor or a unit struct constructor
- Res::SelfCtor(_) => self.user_substs_applied_to_ty_of_hir_id(hir_id),
+ Res::SelfCtor(_) => self.user_substs_applied_to_ty_of_hir_id(hir_id).map(Box::new),
_ => bug!("user_substs_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
};
@@ -846,22 +860,22 @@ impl<'tcx> Cx<'tcx> {
Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
let user_ty = self.user_substs_applied_to_res(expr.hir_id, res);
- ExprKind::NamedConst { def_id, substs, user_ty: user_ty }
+ ExprKind::NamedConst { def_id, substs, user_ty }
}
Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
let user_provided_types = self.typeck_results.user_provided_types();
- let user_provided_type = user_provided_types.get(expr.hir_id).copied();
- debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
+ let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
+ debug!("convert_path_expr: user_ty={:?}", user_ty);
let ty = self.typeck_results().node_type(expr.hir_id);
match ty.kind() {
// A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case.
- ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(Adt {
+ ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(AdtExpr {
adt_def: *adt_def,
variant_index: adt_def.variant_index_with_ctor_id(def_id),
substs,
- user_ty: user_provided_type,
+ user_ty,
fields: Box::new([]),
base: None,
})),
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index f7351a4ca..3ef1b263f 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -8,12 +8,14 @@ use crate::thir::util::UserAnnotatedTyHelpers;
use rustc_data_structures::steal::Steal;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::lang_items::LangItem;
use rustc_hir::HirId;
use rustc_hir::Node;
use rustc_middle::middle::region;
use rustc_middle::thir::*;
-use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
+use rustc_middle::ty::{self, RvalueScopes, Subst, TyCtxt};
use rustc_span::Span;
pub(crate) fn thir_body<'tcx>(
@@ -27,6 +29,26 @@ pub(crate) fn thir_body<'tcx>(
return Err(reported);
}
let expr = cx.mirror_expr(&body.value);
+
+ let owner_id = hir.local_def_id_to_hir_id(owner_def.did);
+ if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) {
+ let closure_env_param = cx.closure_env_param(owner_def.did, owner_id);
+ let explicit_params = cx.explicit_params(owner_id, fn_decl, body);
+ cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect();
+
+ // The resume argument may be missing, in that case we need to provide it here.
+ // It will always be `()` in this case.
+ if tcx.def_kind(owner_def.did) == DefKind::Generator && body.params.is_empty() {
+ cx.thir.params.push(Param {
+ ty: tcx.mk_unit(),
+ pat: None,
+ ty_span: None,
+ self_kind: None,
+ hir_id: None,
+ });
+ }
+ }
+
Ok((tcx.alloc_steal_thir(cx.thir), expr))
}
@@ -44,11 +66,11 @@ struct Cx<'tcx> {
tcx: TyCtxt<'tcx>,
thir: Thir<'tcx>,
- pub(crate) param_env: ty::ParamEnv<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
- pub(crate) region_scope_tree: &'tcx region::ScopeTree,
- pub(crate) typeck_results: &'tcx ty::TypeckResults<'tcx>,
- pub(crate) rvalue_scopes: &'tcx RvalueScopes,
+ region_scope_tree: &'tcx region::ScopeTree,
+ typeck_results: &'tcx ty::TypeckResults<'tcx>,
+ rvalue_scopes: &'tcx RvalueScopes,
/// When applying adjustments to the expression
/// with the given `HirId`, use the given `Span`,
@@ -77,14 +99,94 @@ impl<'tcx> Cx<'tcx> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
- pub(crate) fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
+ #[instrument(level = "debug", skip(self))]
+ fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Box<Pat<'tcx>> {
let p = match self.tcx.hir().get(p.hir_id) {
Node::Pat(p) => p,
node => bug!("pattern became {:?}", node),
};
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
}
+
+ fn closure_env_param(&self, owner_def: LocalDefId, owner_id: HirId) -> Option<Param<'tcx>> {
+ match self.tcx.def_kind(owner_def) {
+ DefKind::Closure => {
+ let closure_ty = self.typeck_results.node_type(owner_id);
+
+ let ty::Closure(closure_def_id, closure_substs) = *closure_ty.kind() else {
+ bug!("closure expr does not have closure type: {:?}", closure_ty);
+ };
+
+ let bound_vars = self.tcx.mk_bound_variable_kinds(std::iter::once(
+ ty::BoundVariableKind::Region(ty::BrEnv),
+ ));
+ let br = ty::BoundRegion {
+ var: ty::BoundVar::from_usize(bound_vars.len() - 1),
+ kind: ty::BrEnv,
+ };
+ let env_region = ty::ReLateBound(ty::INNERMOST, br);
+ let closure_env_ty =
+ self.tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
+ let liberated_closure_env_ty = self.tcx.erase_late_bound_regions(
+ ty::Binder::bind_with_vars(closure_env_ty, bound_vars),
+ );
+ let env_param = Param {
+ ty: liberated_closure_env_ty,
+ pat: None,
+ ty_span: None,
+ self_kind: None,
+ hir_id: None,
+ };
+
+ Some(env_param)
+ }
+ DefKind::Generator => {
+ let gen_ty = self.typeck_results.node_type(owner_id);
+ let gen_param =
+ Param { ty: gen_ty, pat: None, ty_span: None, self_kind: None, hir_id: None };
+ Some(gen_param)
+ }
+ _ => None,
+ }
+ }
+
+ fn explicit_params<'a>(
+ &'a mut self,
+ owner_id: HirId,
+ fn_decl: &'tcx hir::FnDecl<'tcx>,
+ body: &'tcx hir::Body<'tcx>,
+ ) -> impl Iterator<Item = Param<'tcx>> + 'a {
+ let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];
+
+ body.params.iter().enumerate().map(move |(index, param)| {
+ let ty_span = fn_decl
+ .inputs
+ .get(index)
+ // Make sure that inferred closure args have no type span
+ .and_then(|ty| if param.pat.span != ty.span { Some(ty.span) } else { None });
+
+ let self_kind = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
+ Some(fn_decl.implicit_self)
+ } else {
+ None
+ };
+
+ // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
+ // (as it's created inside the body itself, not passed in from outside).
+ let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() {
+ let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span));
+
+ self.tcx
+ .bound_type_of(va_list_did)
+ .subst(self.tcx, &[self.tcx.lifetimes.re_erased.into()])
+ } else {
+ fn_sig.inputs()[index]
+ };
+
+ let pat = self.pattern_from_hir(param.pat);
+ Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) }
+ })
+ }
}
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 063c07647..d45b88690 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -491,8 +491,8 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
err.span_suggestion_verbose(
semi_span.shrink_to_lo(),
&format!(
- "alternatively, on nightly, you might want to use \
- `#![feature(let_else)]` to handle the variant{} that {} matched",
+ "alternatively, you might want to use \
+ let else to handle the variant{} that {} matched",
pluralize!(witnesses.len()),
match witnesses.len() {
1 => "isn't",
@@ -849,22 +849,22 @@ fn non_exhaustive_match<'p, 'tcx>(
));
}
[.., prev, last] if prev.span.eq_ctxt(last.span) => {
- if let Ok(snippet) = sm.span_to_snippet(prev.span.between(last.span)) {
- let comma = if matches!(last.body.kind, hir::ExprKind::Block(..))
- && last.span.eq_ctxt(last.body.span)
- {
- ""
- } else {
- ","
- };
+ let comma = if matches!(last.body.kind, hir::ExprKind::Block(..))
+ && last.span.eq_ctxt(last.body.span)
+ {
+ ""
+ } else {
+ ","
+ };
+ let spacing = if sm.is_multiline(prev.span.between(last.span)) {
+ sm.indentation_before(last.span).map(|indent| format!("\n{indent}"))
+ } else {
+ Some(" ".to_string())
+ };
+ if let Some(spacing) = spacing {
suggestion = Some((
last.span.shrink_to_hi(),
- format!(
- "{}{}{} => todo!()",
- comma,
- snippet.strip_prefix(',').unwrap_or(&snippet),
- pattern
- ),
+ format!("{}{}{} => todo!()", comma, spacing, pattern),
));
}
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index d6dd0f017..b58685e89 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -19,21 +19,18 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// Converts an evaluated constant to a pattern (if possible).
/// This means aggregate values (like structs and enums) are converted
/// to a pattern that matches the value (as if you'd compared via structural equality).
- #[instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
pub(super) fn const_to_pat(
&self,
cv: mir::ConstantKind<'tcx>,
id: hir::HirId,
span: Span,
mir_structural_match_violation: bool,
- ) -> Pat<'tcx> {
- let pat = self.tcx.infer_ctxt().enter(|infcx| {
+ ) -> Box<Pat<'tcx>> {
+ self.tcx.infer_ctxt().enter(|infcx| {
let mut convert = ConstToPat::new(self, id, span, infcx);
convert.to_pat(cv, mir_structural_match_violation)
- });
-
- debug!(?pat);
- pat
+ })
}
}
@@ -159,7 +156,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
&mut self,
cv: mir::ConstantKind<'tcx>,
mir_structural_match_violation: bool,
- ) -> Pat<'tcx> {
+ ) -> Box<Pat<'tcx>> {
trace!(self.treat_byte_string_as_slice);
// This method is just a wrapper handling a validity check; the heavy lifting is
// performed by the recursive `recur` method, which is not meant to be
@@ -168,7 +165,14 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
// once indirect_structural_match is a full fledged error, this
// level of indirection can be eliminated
- let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation).unwrap();
+ let inlined_const_as_pat =
+ self.recur(cv, mir_structural_match_violation).unwrap_or_else(|_| {
+ Box::new(Pat {
+ span: self.span,
+ ty: cv.ty(),
+ kind: PatKind::Constant { value: cv },
+ })
+ });
if self.include_lint_checks && !self.saw_const_match_error.get() {
// If we were able to successfully convert the const to some pat,
@@ -269,7 +273,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
&self,
cv: mir::ConstantKind<'tcx>,
mir_structural_match_violation: bool,
- ) -> Result<Pat<'tcx>, FallbackToConstRef> {
+ ) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
let id = self.id;
let span = self.span;
let tcx = self.tcx();
@@ -396,7 +400,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?,
slice: None,
- suffix: Vec::new(),
+ suffix: Box::new([]),
},
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
// These are not allowed and will error elsewhere anyway.
@@ -423,8 +427,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
let old = self.behind_reference.replace(true);
let array = tcx.deref_mir_constant(self.param_env.and(cv));
let val = PatKind::Deref {
- subpattern: Pat {
- kind: Box::new(PatKind::Array {
+ subpattern: Box::new(Pat {
+ kind: PatKind::Array {
prefix: tcx
.destructure_mir_constant(param_env, array)
.fields
@@ -432,11 +436,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?,
slice: None,
- suffix: vec![],
- }),
+ suffix: Box::new([]),
+ },
span,
ty: *pointee_ty,
- },
+ }),
};
self.behind_reference.set(old);
val
@@ -449,8 +453,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
let old = self.behind_reference.replace(true);
let array = tcx.deref_mir_constant(self.param_env.and(cv));
let val = PatKind::Deref {
- subpattern: Pat {
- kind: Box::new(PatKind::Slice {
+ subpattern: Box::new(Pat {
+ kind: PatKind::Slice {
prefix: tcx
.destructure_mir_constant(param_env, array)
.fields
@@ -458,11 +462,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.map(|val| self.recur(*val, false))
.collect::<Result<_, _>>()?,
slice: None,
- suffix: vec![],
- }),
+ suffix: Box::new([]),
+ },
span,
ty: tcx.mk_slice(elem_ty),
- },
+ }),
};
self.behind_reference.set(old);
val
@@ -596,6 +600,6 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
);
}
- Ok(Pat { span, ty: cv.ty(), kind: Box::new(kind) })
+ Ok(Box::new(Pat { span, ty: cv.ty(), kind }))
}
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 8d6f8efb6..5105f059f 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -71,9 +71,9 @@ use std::ops::RangeInclusive;
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
fn expand<'p, 'tcx>(pat: &'p Pat<'tcx>, vec: &mut Vec<&'p Pat<'tcx>>) {
- if let PatKind::Or { pats } = pat.kind.as_ref() {
- for pat in pats {
- expand(pat, vec);
+ if let PatKind::Or { pats } = &pat.kind {
+ for pat in pats.iter() {
+ expand(&pat, vec);
}
} else {
vec.push(pat)
@@ -252,10 +252,14 @@ impl IntRange {
let kind = if lo == hi {
PatKind::Constant { value: lo_const }
} else {
- PatKind::Range(PatRange { lo: lo_const, hi: hi_const, end: RangeEnd::Included })
+ PatKind::Range(Box::new(PatRange {
+ lo: lo_const,
+ hi: hi_const,
+ end: RangeEnd::Included,
+ }))
};
- Pat { ty, span: DUMMY_SP, kind: Box::new(kind) }
+ Pat { ty, span: DUMMY_SP, kind }
}
/// Lint on likely incorrect range patterns (#63987)
@@ -1297,7 +1301,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
let mkpat = |pat| DeconstructedPat::from_pat(cx, pat);
let ctor;
let fields;
- match pat.kind.as_ref() {
+ match &pat.kind {
PatKind::AscribeUserType { subpattern, .. } => return mkpat(subpattern),
PatKind::Binding { subpattern: Some(subpat), .. } => return mkpat(subpat),
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
@@ -1342,9 +1346,9 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
fields = Fields::singleton(cx, pat);
}
ty::Adt(adt, _) => {
- ctor = match pat.kind.as_ref() {
+ ctor = match pat.kind {
PatKind::Leaf { .. } => Single,
- PatKind::Variant { variant_index, .. } => Variant(*variant_index),
+ PatKind::Variant { variant_index, .. } => Variant(variant_index),
_ => bug!(),
};
let variant = &adt.variant(ctor.variant_index_for_adt(*adt));
@@ -1402,7 +1406,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
}
}
- &PatKind::Range(PatRange { lo, hi, end }) => {
+ &PatKind::Range(box PatRange { lo, hi, end }) => {
let ty = lo.ty();
ctor = if let Some(int_range) = IntRange::from_range(
cx.tcx,
@@ -1429,7 +1433,8 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
FixedLen(prefix.len() + suffix.len())
};
ctor = Slice(Slice::new(array_len, kind));
- fields = Fields::from_iter(cx, prefix.iter().chain(suffix).map(mkpat));
+ fields =
+ Fields::from_iter(cx, prefix.iter().chain(suffix.iter()).map(|p| mkpat(&*p)));
}
PatKind::Or { .. } => {
ctor = Or;
@@ -1442,15 +1447,15 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
pub(crate) fn to_pat(&self, cx: &MatchCheckCtxt<'p, 'tcx>) -> Pat<'tcx> {
let is_wildcard = |pat: &Pat<'_>| {
- matches!(*pat.kind, PatKind::Binding { subpattern: None, .. } | PatKind::Wild)
+ matches!(pat.kind, PatKind::Binding { subpattern: None, .. } | PatKind::Wild)
};
- let mut subpatterns = self.iter_fields().map(|p| p.to_pat(cx));
- let pat = match &self.ctor {
+ let mut subpatterns = self.iter_fields().map(|p| Box::new(p.to_pat(cx)));
+ let kind = match &self.ctor {
Single | Variant(_) => match self.ty.kind() {
ty::Tuple(..) => PatKind::Leaf {
subpatterns: subpatterns
.enumerate()
- .map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
+ .map(|(i, pattern)| FieldPat { field: Field::new(i), pattern })
.collect(),
},
ty::Adt(adt_def, _) if adt_def.is_box() => {
@@ -1485,7 +1490,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
FixedLen(_) => PatKind::Slice {
prefix: subpatterns.collect(),
slice: None,
- suffix: vec![],
+ suffix: Box::new([]),
},
VarLen(prefix, _) => {
let mut subpatterns = subpatterns.peekable();
@@ -1504,14 +1509,18 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
subpatterns.next();
}
}
- let suffix: Vec<_> = subpatterns.collect();
+ let suffix: Box<[_]> = subpatterns.collect();
let wild = Pat::wildcard_from_ty(self.ty);
- PatKind::Slice { prefix, slice: Some(wild), suffix }
+ PatKind::Slice {
+ prefix: prefix.into_boxed_slice(),
+ slice: Some(Box::new(wild)),
+ suffix,
+ }
}
}
}
&Str(value) => PatKind::Constant { value },
- &FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
+ &FloatRange(lo, hi, end) => PatKind::Range(Box::new(PatRange { lo, hi, end })),
IntRange(range) => return range.to_pat(cx.tcx, self.ty),
Wildcard | NonExhaustive => PatKind::Wild,
Missing { .. } => bug!(
@@ -1523,7 +1532,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
};
- Pat { ty: self.ty, span: DUMMY_SP, kind: Box::new(pat) }
+ Pat { ty: self.ty, span: DUMMY_SP, kind }
}
pub(super) fn is_or_pat(&self) -> bool {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index a13748a2d..0edf6a983 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -29,27 +29,27 @@ use rustc_span::{Span, Symbol};
use std::cmp::Ordering;
#[derive(Clone, Debug)]
-pub(crate) enum PatternError {
+enum PatternError {
AssocConstInPattern(Span),
ConstParamInPattern(Span),
StaticInPattern(Span),
NonConstPath(Span),
}
-pub(crate) struct PatCtxt<'a, 'tcx> {
- pub(crate) tcx: TyCtxt<'tcx>,
- pub(crate) param_env: ty::ParamEnv<'tcx>,
- pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>,
- pub(crate) errors: Vec<PatternError>,
+struct PatCtxt<'a, 'tcx> {
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ typeck_results: &'a ty::TypeckResults<'tcx>,
+ errors: Vec<PatternError>,
include_lint_checks: bool,
}
-pub(crate) fn pat_from_hir<'a, 'tcx>(
+pub(super) fn pat_from_hir<'a, 'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
pat: &'tcx hir::Pat<'tcx>,
-) -> Pat<'tcx> {
+) -> Box<Pat<'tcx>> {
let mut pcx = PatCtxt::new(tcx, param_env, typeck_results);
let result = pcx.lower_pattern(pat);
if !pcx.errors.is_empty() {
@@ -61,7 +61,7 @@ pub(crate) fn pat_from_hir<'a, 'tcx>(
}
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
- pub(crate) fn new(
+ fn new(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -69,12 +69,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
PatCtxt { tcx, param_env, typeck_results, errors: vec![], include_lint_checks: false }
}
- pub(crate) fn include_lint_checks(&mut self) -> &mut Self {
+ fn include_lint_checks(&mut self) -> &mut Self {
self.include_lint_checks = true;
self
}
- pub(crate) fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
+ fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
// pattern has the type that results *after* dereferencing. For example, in this code:
//
@@ -97,13 +97,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let unadjusted_pat = self.lower_pattern_unadjusted(pat);
self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
unadjusted_pat,
- |pat, ref_ty| {
+ |pat: Box<_>, ref_ty| {
debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
- Pat {
+ Box::new(Pat {
span: pat.span,
ty: *ref_ty,
- kind: Box::new(PatKind::Deref { subpattern: pat }),
- }
+ kind: PatKind::Deref { subpattern: pat },
+ })
},
)
}
@@ -113,7 +113,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>,
) -> (PatKind<'tcx>, Option<Ascription<'tcx>>) {
match self.lower_lit(expr) {
- PatKind::AscribeUserType { ascription, subpattern: Pat { kind: box kind, .. } } => {
+ PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
(kind, Some(ascription))
}
kind => (kind, None),
@@ -134,7 +134,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
match (end, cmp) {
// `x..y` where `x < y`.
// Non-empty because the range includes at least `x`.
- (RangeEnd::Excluded, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }),
+ (RangeEnd::Excluded, Some(Ordering::Less)) => {
+ PatKind::Range(Box::new(PatRange { lo, hi, end }))
+ }
// `x..y` where `x >= y`. The range is empty => error.
(RangeEnd::Excluded, _) => {
struct_span_err!(
@@ -149,7 +151,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// `x..=y` where `x == y`.
(RangeEnd::Included, Some(Ordering::Equal)) => PatKind::Constant { value: lo },
// `x..=y` where `x < y`.
- (RangeEnd::Included, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }),
+ (RangeEnd::Included, Some(Ordering::Less)) => {
+ PatKind::Range(Box::new(PatRange { lo, hi, end }))
+ }
// `x..=y` where `x > y` hence the range is empty => error.
(RangeEnd::Included, _) => {
let mut err = struct_span_err!(
@@ -196,8 +200,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
}
}
- fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
+ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
let mut ty = self.typeck_results.node_type(pat.hir_id);
+ let mut span = pat.span;
let kind = match pat.kind {
hir::PatKind::Wild => PatKind::Wild,
@@ -228,7 +233,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// constants somewhere. Have them on the range pattern.
for end in &[lo, hi] {
if let Some((_, Some(ascription))) = end {
- let subpattern = Pat { span: pat.span, ty, kind: Box::new(kind) };
+ let subpattern = Box::new(Pat { span: pat.span, ty, kind });
kind =
PatKind::AscribeUserType { ascription: ascription.clone(), subpattern };
}
@@ -258,6 +263,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
}
hir::PatKind::Binding(_, id, ident, ref sub) => {
+ if let Some(ident_span) = ident.span.find_ancestor_inside(span) {
+ span = span.with_hi(ident_span.hi());
+ }
+
let bm = *self
.typeck_results
.pat_binding_modes()
@@ -322,14 +331,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
hir::PatKind::Or(ref pats) => PatKind::Or { pats: self.lower_patterns(pats) },
};
- Pat { span: pat.span, ty, kind: Box::new(kind) }
+ Box::new(Pat { span, ty, kind })
}
fn lower_tuple_subpats(
&mut self,
pats: &'tcx [hir::Pat<'tcx>],
expected_len: usize,
- gap_pos: Option<usize>,
+ gap_pos: hir::DotDotPos,
) -> Vec<FieldPat<'tcx>> {
pats.iter()
.enumerate_and_adjust(expected_len, gap_pos)
@@ -340,11 +349,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.collect()
}
- fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Vec<Pat<'tcx>> {
+ fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Box<[Box<Pat<'tcx>>]> {
pats.iter().map(|p| self.lower_pattern(p)).collect()
}
- fn lower_opt_pattern(&mut self, pat: &'tcx Option<&'tcx hir::Pat<'tcx>>) -> Option<Pat<'tcx>> {
+ fn lower_opt_pattern(
+ &mut self,
+ pat: &'tcx Option<&'tcx hir::Pat<'tcx>>,
+ ) -> Option<Box<Pat<'tcx>>> {
pat.as_ref().map(|p| self.lower_pattern(p))
}
@@ -436,12 +448,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
if let Some(user_ty) = self.user_substs_applied_to_ty_of_hir_id(hir_id) {
debug!("lower_variant_or_leaf: kind={:?} user_ty={:?} span={:?}", kind, user_ty, span);
let annotation = CanonicalUserTypeAnnotation {
- user_ty,
+ user_ty: Box::new(user_ty),
span,
inferred_ty: self.typeck_results.node_type(hir_id),
};
kind = PatKind::AscribeUserType {
- subpattern: Pat { span, ty, kind: Box::new(kind) },
+ subpattern: Box::new(Pat { span, ty, kind }),
ascription: Ascription { annotation, variance: ty::Variance::Covariant },
};
}
@@ -453,11 +465,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// it to `const_to_pat`. Any other path (like enum variants without fields)
/// is converted to the corresponding pattern via `lower_variant_or_leaf`.
#[instrument(skip(self), level = "debug")]
- fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) -> Pat<'tcx> {
+ fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) -> Box<Pat<'tcx>> {
let ty = self.typeck_results.node_type(id);
let res = self.typeck_results.qpath_res(qpath, id);
- let pat_from_kind = |kind| Pat { span, ty, kind: Box::new(kind) };
+ let pat_from_kind = |kind| Box::new(Pat { span, ty, kind });
let (def_id, is_associated_const) = match res {
Res::Def(DefKind::Const, def_id) => (def_id, false),
@@ -469,7 +481,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Use `Reveal::All` here because patterns are always monomorphic even if their function
// isn't.
let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx);
- let substs = self.typeck_results.node_substs(id);
+ // N.B. There is no guarantee that substs collected in typeck results are fully normalized,
+ // so they need to be normalized in order to pass to `Instance::resolve`, which will ICE
+ // if given unnormalized types.
+ let substs = self
+ .tcx
+ .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_substs(id));
let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, substs) {
Ok(Some(i)) => i,
Ok(None) => {
@@ -505,13 +522,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let user_provided_types = self.typeck_results().user_provided_types();
if let Some(&user_ty) = user_provided_types.get(id) {
let annotation = CanonicalUserTypeAnnotation {
- user_ty,
+ user_ty: Box::new(user_ty),
span,
inferred_ty: self.typeck_results().node_type(id),
};
- Pat {
+ Box::new(Pat {
span,
- kind: Box::new(PatKind::AscribeUserType {
+ kind: PatKind::AscribeUserType {
subpattern: pattern,
ascription: Ascription {
annotation,
@@ -519,9 +536,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// `variance` field documentation for details.
variance: ty::Variance::Contravariant,
},
- }),
+ },
ty: const_.ty(),
- }
+ })
} else {
pattern
}
@@ -553,23 +570,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let value = value.eval(self.tcx, self.param_env);
match value {
- mir::ConstantKind::Ty(c) => {
- match c.kind() {
- ConstKind::Param(_) => {
- self.errors.push(PatternError::ConstParamInPattern(span));
- return PatKind::Wild;
- }
- ConstKind::Unevaluated(_) => {
- // If we land here it means the const can't be evaluated because it's `TooGeneric`.
- self.tcx
- .sess
- .span_err(span, "constant pattern depends on a generic parameter");
- return PatKind::Wild;
- }
- _ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"),
+ mir::ConstantKind::Ty(c) => match c.kind() {
+ ConstKind::Param(_) => {
+ self.errors.push(PatternError::ConstParamInPattern(span));
+ return PatKind::Wild;
}
+ _ => bug!("Expected ConstKind::Param"),
+ },
+ mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
+ mir::ConstantKind::Unevaluated(..) => {
+ // If we land here it means the const can't be evaluated because it's `TooGeneric`.
+ self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter");
+ return PatKind::Wild;
}
- mir::ConstantKind::Val(_, _) => *self.const_to_pat(value, id, span, false).kind,
}
}
@@ -580,7 +593,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
let (lit, neg) = match expr.kind {
hir::ExprKind::Path(ref qpath) => {
- return *self.lower_path(qpath, expr.hir_id, expr.span).kind;
+ return self.lower_path(qpath, expr.hir_id, expr.span).kind;
}
hir::ExprKind::ConstBlock(ref anon_const) => {
return self.lower_inline_const(anon_const, expr.hir_id, expr.span);
@@ -598,7 +611,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let lit_input =
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) {
- Ok(constant) => *self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
+ Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
Err(LitToConstError::Reported) => PatKind::Wild,
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
}
@@ -615,7 +628,7 @@ impl<'tcx> UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> {
}
}
-pub(crate) trait PatternFoldable<'tcx>: Sized {
+trait PatternFoldable<'tcx>: Sized {
fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.super_fold_with(folder)
}
@@ -623,7 +636,7 @@ pub(crate) trait PatternFoldable<'tcx>: Sized {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self;
}
-pub(crate) trait PatternFolder<'tcx>: Sized {
+trait PatternFolder<'tcx>: Sized {
fn fold_pattern(&mut self, pattern: &Pat<'tcx>) -> Pat<'tcx> {
pattern.super_fold_with(self)
}
@@ -646,6 +659,12 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Vec<T> {
}
}
+impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Box<[T]> {
+ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
+ self.iter().map(|t| t.fold_with(folder)).collect()
+ }
+}
+
impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.as_ref().map(|t| t.fold_with(folder))
@@ -732,7 +751,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
PatKind::Deref { subpattern: subpattern.fold_with(folder) }
}
PatKind::Constant { value } => PatKind::Constant { value },
- PatKind::Range(range) => PatKind::Range(range),
+ PatKind::Range(ref range) => PatKind::Range(range.clone()),
PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice {
prefix: prefix.fold_with(folder),
slice: slice.fold_with(folder),
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 0a660ef30..115d34ff8 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -364,8 +364,8 @@ impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> {
/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
/// works well.
#[derive(Clone)]
-struct PatStack<'p, 'tcx> {
- pats: SmallVec<[&'p DeconstructedPat<'p, 'tcx>; 2]>,
+pub(crate) struct PatStack<'p, 'tcx> {
+ pub(crate) pats: SmallVec<[&'p DeconstructedPat<'p, 'tcx>; 2]>,
}
impl<'p, 'tcx> PatStack<'p, 'tcx> {
@@ -403,6 +403,21 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
})
}
+ // Recursively expand all patterns into their subpatterns and push each `PatStack` to matrix.
+ fn expand_and_extend<'a>(&'a self, matrix: &mut Matrix<'p, 'tcx>) {
+ if !self.is_empty() && self.head().is_or_pat() {
+ for pat in self.head().iter_fields() {
+ let mut new_patstack = PatStack::from_pattern(pat);
+ new_patstack.pats.extend_from_slice(&self.pats[1..]);
+ if !new_patstack.is_empty() && new_patstack.head().is_or_pat() {
+ new_patstack.expand_and_extend(matrix);
+ } else if !new_patstack.is_empty() {
+ matrix.push(new_patstack);
+ }
+ }
+ }
+ }
+
/// This computes `S(self.head().ctor(), self)`. See top of the file for explanations.
///
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
@@ -436,7 +451,7 @@ impl<'p, 'tcx> fmt::Debug for PatStack<'p, 'tcx> {
/// A 2D matrix.
#[derive(Clone)]
pub(super) struct Matrix<'p, 'tcx> {
- patterns: Vec<PatStack<'p, 'tcx>>,
+ pub patterns: Vec<PatStack<'p, 'tcx>>,
}
impl<'p, 'tcx> Matrix<'p, 'tcx> {
@@ -453,7 +468,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
/// expands it.
fn push(&mut self, row: PatStack<'p, 'tcx>) {
if !row.is_empty() && row.head().is_or_pat() {
- self.patterns.extend(row.expand_or_pat());
+ row.expand_and_extend(self);
} else {
self.patterns.push(row);
}
@@ -739,8 +754,8 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
hir_id: HirId,
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
) {
- let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, |build| {
+ let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
let mut lint = build.build("some variants are not matched explicitly");
lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
lint.help(
@@ -776,7 +791,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
/// `is_under_guard` is used to inform if the pattern has a guard. If it
/// has one it must not be inserted into the matrix. This shouldn't be
/// relied on for soundness.
-#[instrument(level = "debug", skip(cx, matrix, hir_id))]
+#[instrument(level = "debug", skip(cx, matrix, hir_id), ret)]
fn is_useful<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>,
matrix: &Matrix<'p, 'tcx>,
@@ -902,7 +917,6 @@ fn is_useful<'p, 'tcx>(
v.head().set_reachable();
}
- debug!(?ret);
ret
}
diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml
index baf9735fb..385e9ba74 100644
--- a/compiler/rustc_mir_dataflow/Cargo.toml
+++ b/compiler/rustc_mir_dataflow/Cargo.toml
@@ -13,10 +13,13 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_serialize = { path = "../rustc_serialize" }
+rustc_session = { path = "../rustc_session" }
rustc_target = { path = "../rustc_target" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_mir_dataflow/src/errors.rs b/compiler/rustc_mir_dataflow/src/errors.rs
new file mode 100644
index 000000000..cc1425787
--- /dev/null
+++ b/compiler/rustc_mir_dataflow/src/errors.rs
@@ -0,0 +1,71 @@
+use rustc_macros::SessionDiagnostic;
+use rustc_span::{Span, Symbol};
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::path_must_end_in_filename)]
+pub(crate) struct PathMustEndInFilename {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::unknown_formatter)]
+pub(crate) struct UnknownFormatter {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::duplicate_values_for)]
+pub(crate) struct DuplicateValuesFor {
+ #[primary_span]
+ pub span: Span,
+ pub name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::requires_an_argument)]
+pub(crate) struct RequiresAnArgument {
+ #[primary_span]
+ pub span: Span,
+ pub name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::stop_after_dataflow_ended_compilation)]
+pub(crate) struct StopAfterDataFlowEndedCompilation;
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::peek_must_be_place_or_ref_place)]
+pub(crate) struct PeekMustBePlaceOrRefPlace {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::peek_must_be_not_temporary)]
+pub(crate) struct PeekMustBeNotTemporary {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::peek_bit_not_set)]
+pub(crate) struct PeekBitNotSet {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::peek_argument_not_a_local)]
+pub(crate) struct PeekArgumentNotALocal {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_dataflow::peek_argument_untracked)]
+pub(crate) struct PeekArgumentUntracked {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index f374658ce..bc75645e7 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -1,5 +1,8 @@
//! A solver for dataflow problems.
+use crate::errors::{
+ DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
+};
use crate::framework::BitSetExt;
use std::ffi::OsString;
@@ -108,9 +111,9 @@ where
// Otherwise, compute and store the cumulative transfer function for each block.
let identity = GenKillSet::identity(analysis.bottom_value(body).domain_size());
- let mut trans_for_block = IndexVec::from_elem(identity, body.basic_blocks());
+ let mut trans_for_block = IndexVec::from_elem(identity, &body.basic_blocks);
- for (block, block_data) in body.basic_blocks().iter_enumerated() {
+ for (block, block_data) in body.basic_blocks.iter_enumerated() {
let trans = &mut trans_for_block[block];
A::Direction::gen_kill_effects_in_block(&analysis, trans, block, block_data);
}
@@ -144,7 +147,7 @@ where
apply_trans_for_block: Option<Box<dyn Fn(BasicBlock, &mut A::Domain)>>,
) -> Self {
let bottom_value = analysis.bottom_value(body);
- let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks());
+ let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), &body.basic_blocks);
analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value {
@@ -197,8 +200,7 @@ where
..
} = self;
- let mut dirty_queue: WorkQueue<BasicBlock> =
- WorkQueue::with_none(body.basic_blocks().len());
+ let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len());
if A::Direction::IS_FORWARD {
for (bb, _) in traversal::reverse_postorder(body) {
@@ -347,7 +349,7 @@ impl RustcMirAttrs {
match path.file_name() {
Some(_) => Ok(path),
None => {
- tcx.sess.span_err(attr.span(), "path must end in a filename");
+ tcx.sess.emit_err(PathMustEndInFilename { span: attr.span() });
Err(())
}
}
@@ -356,7 +358,7 @@ impl RustcMirAttrs {
Self::set_field(&mut ret.formatter, tcx, &attr, |s| match s {
sym::gen_kill | sym::two_phase => Ok(s),
_ => {
- tcx.sess.span_err(attr.span(), "unknown formatter");
+ tcx.sess.emit_err(UnknownFormatter { span: attr.span() });
Err(())
}
})
@@ -377,8 +379,7 @@ impl RustcMirAttrs {
mapper: impl FnOnce(Symbol) -> Result<T, ()>,
) -> Result<(), ()> {
if field.is_some() {
- tcx.sess
- .span_err(attr.span(), &format!("duplicate values for `{}`", attr.name_or_empty()));
+ tcx.sess.emit_err(DuplicateValuesFor { span: attr.span(), name: attr.name_or_empty() });
return Err(());
}
@@ -387,8 +388,7 @@ impl RustcMirAttrs {
*field = Some(mapper(s)?);
Ok(())
} else {
- tcx.sess
- .span_err(attr.span(), &format!("`{}` requires an argument", attr.name_or_empty()));
+ tcx.sess.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name_or_empty() });
Err(())
}
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index c94198c56..579fe68a1 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -108,12 +108,12 @@ where
type Edge = CfgEdge;
fn nodes(&self) -> dot::Nodes<'_, Self::Node> {
- self.body.basic_blocks().indices().collect::<Vec<_>>().into()
+ self.body.basic_blocks.indices().collect::<Vec<_>>().into()
}
fn edges(&self) -> dot::Edges<'_, Self::Edge> {
self.body
- .basic_blocks()
+ .basic_blocks
.indices()
.flat_map(|bb| dataflow_successors(self.body, bb))
.collect::<Vec<_>>()
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index f9fd6c9c5..d9aff94fe 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -256,6 +256,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
/// .iterate_to_fixpoint()
/// .into_results_cursor(body);
/// ```
+ #[inline]
fn into_engine<'mir>(
self,
tcx: TyCtxt<'tcx>,
@@ -413,7 +414,7 @@ where
}
/* Extension methods */
-
+ #[inline]
fn into_engine<'mir>(
self,
tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index d9461fd3a..17102454a 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -100,9 +100,9 @@ impl<D: Direction> MockAnalysis<'_, D> {
fn mock_entry_sets(&self) -> IndexVec<BasicBlock, BitSet<usize>> {
let empty = self.bottom_value(self.body);
- let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks());
+ let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks);
- for (bb, _) in self.body.basic_blocks().iter_enumerated() {
+ for (bb, _) in self.body.basic_blocks.iter_enumerated() {
ret[bb] = self.mock_entry_set(bb);
}
@@ -169,7 +169,7 @@ impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> {
const NAME: &'static str = "mock";
fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
- BitSet::new_empty(Self::BASIC_BLOCK_OFFSET + body.basic_blocks().len())
+ BitSet::new_empty(Self::BASIC_BLOCK_OFFSET + body.basic_blocks.len())
}
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
@@ -271,9 +271,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
cursor.allow_unreachable();
let every_target = || {
- body.basic_blocks()
- .iter_enumerated()
- .flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb))
+ body.basic_blocks.iter_enumerated().flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb))
};
let mut seek_to_target = |targ| {
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index 21132eb99..3e08a8799 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -23,12 +23,6 @@ use crate::{Analysis, AnalysisDomain, Backward, CallReturnPlaces, GenKill, GenKi
/// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis
pub struct MaybeLiveLocals;
-impl MaybeLiveLocals {
- fn transfer_function<'a, T>(&self, trans: &'a mut T) -> TransferFunction<'a, T> {
- TransferFunction(trans)
- }
-}
-
impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals {
type Domain = ChunkedBitSet<Local>;
type Direction = Backward;
@@ -54,7 +48,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
statement: &mir::Statement<'tcx>,
location: Location,
) {
- self.transfer_function(trans).visit_statement(statement, location);
+ TransferFunction(trans).visit_statement(statement, location);
}
fn terminator_effect(
@@ -63,7 +57,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
terminator: &mir::Terminator<'tcx>,
location: Location,
) {
- self.transfer_function(trans).visit_terminator(terminator, location);
+ TransferFunction(trans).visit_terminator(terminator, location);
}
fn call_return_effect(
@@ -85,9 +79,11 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
_resume_block: mir::BasicBlock,
resume_place: mir::Place<'tcx>,
) {
- if let Some(local) = resume_place.as_local() {
- trans.kill(local);
- }
+ YieldResumeEffect(trans).visit_place(
+ &resume_place,
+ PlaceContext::MutatingUse(MutatingUseContext::Yield),
+ Location::START,
+ )
}
}
@@ -98,28 +94,51 @@ where
T: GenKill<Local>,
{
fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) {
- let local = place.local;
-
- // We purposefully do not call `super_place` here to avoid calling `visit_local` for this
- // place with one of the `Projection` variants of `PlaceContext`.
- self.visit_projection(place.as_ref(), context, location);
+ if let PlaceContext::MutatingUse(MutatingUseContext::Yield) = context {
+ // The resume place is evaluated and assigned to only after generator resumes, so its
+ // effect is handled separately in `yield_resume_effect`.
+ return;
+ }
match DefUse::for_place(*place, context) {
- Some(DefUse::Def) => self.0.kill(local),
- Some(DefUse::Use) => self.0.gen(local),
+ Some(DefUse::Def) => {
+ if let PlaceContext::MutatingUse(
+ MutatingUseContext::Call | MutatingUseContext::AsmOutput,
+ ) = context
+ {
+ // For the associated terminators, this is only a `Def` when the terminator returns
+ // "successfully." As such, we handle this case separately in `call_return_effect`
+ // above. However, if the place looks like `*_5`, this is still unconditionally a use of
+ // `_5`.
+ } else {
+ self.0.kill(place.local);
+ }
+ }
+ Some(DefUse::Use) => self.0.gen(place.local),
None => {}
}
+
+ self.visit_projection(place.as_ref(), context, location);
}
fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
- // Because we do not call `super_place` above, `visit_local` is only called for locals that
- // do not appear as part of a `Place` in the MIR. This handles cases like the implicit use
- // of the return place in a `Return` terminator or the index in an `Index` projection.
- match DefUse::for_place(local.into(), context) {
- Some(DefUse::Def) => self.0.kill(local),
- Some(DefUse::Use) => self.0.gen(local),
- None => {}
- }
+ DefUse::apply(self.0, local.into(), context);
+ }
+}
+
+struct YieldResumeEffect<'a, T>(&'a mut T);
+
+impl<'tcx, T> Visitor<'tcx> for YieldResumeEffect<'_, T>
+where
+ T: GenKill<Local>,
+{
+ fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) {
+ DefUse::apply(self.0, *place, context);
+ self.visit_projection(place.as_ref(), context, location);
+ }
+
+ fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
+ DefUse::apply(self.0, local.into(), context);
}
}
@@ -130,11 +149,25 @@ enum DefUse {
}
impl DefUse {
+ fn apply<'tcx>(trans: &mut impl GenKill<Local>, place: Place<'tcx>, context: PlaceContext) {
+ match DefUse::for_place(place, context) {
+ Some(DefUse::Def) => trans.kill(place.local),
+ Some(DefUse::Use) => trans.gen(place.local),
+ None => {}
+ }
+ }
+
fn for_place<'tcx>(place: Place<'tcx>, context: PlaceContext) -> Option<DefUse> {
match context {
PlaceContext::NonUse(_) => None,
- PlaceContext::MutatingUse(MutatingUseContext::Store | MutatingUseContext::Deinit) => {
+ PlaceContext::MutatingUse(
+ MutatingUseContext::Call
+ | MutatingUseContext::Yield
+ | MutatingUseContext::AsmOutput
+ | MutatingUseContext::Store
+ | MutatingUseContext::Deinit,
+ ) => {
if place.is_indirect() {
// Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a
// use.
@@ -152,16 +185,6 @@ impl DefUse {
place.is_indirect().then_some(DefUse::Use)
}
- // For the associated terminators, this is only a `Def` when the terminator returns
- // "successfully." As such, we handle this case separately in `call_return_effect`
- // above. However, if the place looks like `*_5`, this is still unconditionally a use of
- // `_5`.
- PlaceContext::MutatingUse(
- MutatingUseContext::Call
- | MutatingUseContext::Yield
- | MutatingUseContext::AsmOutput,
- ) => place.is_indirect().then_some(DefUse::Use),
-
// All other contexts are uses...
PlaceContext::MutatingUse(
MutatingUseContext::AddressOf
@@ -247,7 +270,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
| StatementKind::Retag(..)
| StatementKind::AscribeUserType(..)
| StatementKind::Coverage(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Nop => None,
};
if let Some(destination) = destination {
@@ -290,8 +313,10 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
_resume_block: mir::BasicBlock,
resume_place: mir::Place<'tcx>,
) {
- if let Some(local) = resume_place.as_local() {
- trans.remove(local);
- }
+ YieldResumeEffect(trans).visit_place(
+ &resume_place,
+ PlaceContext::MutatingUse(MutatingUseContext::Yield),
+ Location::START,
+ )
}
}
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index f6b5af90a..18760b6c6 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -142,7 +142,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
| StatementKind::FakeRead(..)
| StatementKind::Nop
| StatementKind::Retag(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::StorageLive(..) => {}
}
}
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 5793a286b..b45c32ee9 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -1,12 +1,14 @@
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(exact_size_is_empty)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(once_cell)]
#![feature(stmt_expr_attributes)]
#![feature(trusted_step)]
#![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
@@ -33,6 +35,7 @@ use self::move_paths::MoveData;
pub mod drop_flag_effects;
pub mod elaborate_drops;
+mod errors;
mod framework;
pub mod impls;
pub mod move_paths;
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 116e5c1f3..f46fd118b 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -243,7 +243,7 @@ pub(super) fn gather_moves<'tcx>(
builder.gather_args();
- for (bb, block) in body.basic_blocks().iter_enumerated() {
+ for (bb, block) in body.basic_blocks.iter_enumerated() {
for (i, stmt) in block.statements.iter().enumerate() {
let source = Location { block: bb, statement_index: i };
builder.gather_statement(source, stmt);
@@ -330,7 +330,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
StatementKind::Retag { .. }
| StatementKind::AscribeUserType(..)
| StatementKind::Coverage(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Nop => {}
}
}
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index a951c5b0b..b36e268cf 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -217,7 +217,7 @@ where
fn new(body: &Body<'_>) -> Self {
LocationMap {
map: body
- .basic_blocks()
+ .basic_blocks
.iter()
.map(|block| vec![T::default(); block.statements.len() + 1])
.collect(),
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index f2471f37a..7cae68efb 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -6,6 +6,10 @@ use rustc_middle::mir::MirPass;
use rustc_middle::mir::{self, Body, Local, Location};
use rustc_middle::ty::{self, Ty, TyCtxt};
+use crate::errors::{
+ PeekArgumentNotALocal, PeekArgumentUntracked, PeekBitNotSet, PeekMustBeNotTemporary,
+ PeekMustBePlaceOrRefPlace, StopAfterDataFlowEndedCompilation,
+};
use crate::framework::BitSetExt;
use crate::impls::{
DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces,
@@ -64,7 +68,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
}
if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
- tcx.sess.fatal("stop_after_dataflow ended compilation");
+ tcx.sess.emit_fatal(StopAfterDataFlowEndedCompilation);
}
}
}
@@ -97,7 +101,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
let mut cursor = ResultsCursor::new(body, results);
- let peek_calls = body.basic_blocks().iter_enumerated().filter_map(|(bb, block_data)| {
+ let peek_calls = body.basic_blocks.iter_enumerated().filter_map(|(bb, block_data)| {
PeekCall::from_terminator(tcx, block_data.terminator()).map(|call| (bb, block_data, call))
});
@@ -133,9 +137,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
}
_ => {
- let msg = "rustc_peek: argument expression \
- must be either `place` or `&place`";
- tcx.sess.span_err(call.span, msg);
+ tcx.sess.emit_err(PeekMustBePlaceOrRefPlace { span: call.span });
}
}
}
@@ -204,18 +206,12 @@ impl PeekCall {
if let Some(local) = place.as_local() {
local
} else {
- tcx.sess.diagnostic().span_err(
- span,
- "dataflow::sanity_check cannot feed a non-temp to rustc_peek.",
- );
+ tcx.sess.emit_err(PeekMustBeNotTemporary { span });
return None;
}
}
_ => {
- tcx.sess.diagnostic().span_err(
- span,
- "dataflow::sanity_check cannot feed a non-temp to rustc_peek.",
- );
+ tcx.sess.emit_err(PeekMustBeNotTemporary { span });
return None;
}
};
@@ -255,12 +251,12 @@ where
let bit_state = flow_state.contains(peek_mpi);
debug!("rustc_peek({:?} = &{:?}) bit_state: {}", call.arg, place, bit_state);
if !bit_state {
- tcx.sess.span_err(call.span, "rustc_peek: bit not set");
+ tcx.sess.emit_err(PeekBitNotSet { span: call.span });
}
}
LookupResult::Parent(..) => {
- tcx.sess.span_err(call.span, "rustc_peek: argument untracked");
+ tcx.sess.emit_err(PeekArgumentUntracked { span: call.span });
}
}
}
@@ -276,12 +272,12 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
) {
info!(?place, "peek_at");
let Some(local) = place.as_local() else {
- tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
+ tcx.sess.emit_err(PeekArgumentNotALocal { span: call.span });
return;
};
if !flow_state.contains(local) {
- tcx.sess.span_err(call.span, "rustc_peek: bit not set");
+ tcx.sess.emit_err(PeekBitNotSet { span: call.span });
}
}
}
diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs
index c909648ea..e5a0e1d31 100644
--- a/compiler/rustc_mir_dataflow/src/storage.rs
+++ b/compiler/rustc_mir_dataflow/src/storage.rs
@@ -7,7 +7,7 @@ use rustc_middle::mir::{self, Local};
pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
let mut always_live_locals = BitSet::new_filled(body.local_decls.len());
- for block in body.basic_blocks() {
+ for block in &*body.basic_blocks {
for statement in &block.statements {
use mir::StatementKind::{StorageDead, StorageLive};
if let StorageLive(l) | StorageDead(l) = statement.kind {
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index 2502e8b60..d8f85d2e3 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -56,7 +56,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
// example.
let mut calls_to_terminate = Vec::new();
let mut cleanups_to_remove = Vec::new();
- for (id, block) in body.basic_blocks().iter_enumerated() {
+ for (id, block) in body.basic_blocks.iter_enumerated() {
if block.is_cleanup {
continue;
}
diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs
index f12c8560c..30966d22e 100644
--- a/compiler/rustc_mir_transform/src/add_call_guards.rs
+++ b/compiler/rustc_mir_transform/src/add_call_guards.rs
@@ -45,7 +45,7 @@ impl AddCallGuards {
// We need a place to store the new blocks generated
let mut new_blocks = Vec::new();
- let cur_len = body.basic_blocks().len();
+ let cur_len = body.basic_blocks.len();
for block in body.basic_blocks_mut() {
match block.terminator {
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index 8de0aad04..ffb5d8c6d 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -55,7 +55,7 @@ fn add_moves_for_packed_drops_patch<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>)
let mut patch = MirPatch::new(body);
let param_env = tcx.param_env(def_id);
- for (bb, data) in body.basic_blocks().iter_enumerated() {
+ for (bb, data) in body.basic_blocks.iter_enumerated() {
let loc = Location { block: bb, statement_index: data.statements.len() };
let terminator = data.terminator();
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index 9c5896c4e..036b55898 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -66,7 +66,6 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
// We need an `AllCallEdges` pass before we can do any work.
super::add_call_guards::AllCallEdges.run_pass(tcx, body);
- let (span, arg_count) = (body.span, body.arg_count);
let basic_blocks = body.basic_blocks.as_mut();
let local_decls = &body.local_decls;
let needs_retag = |place: &Place<'tcx>| {
@@ -90,20 +89,18 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
// PART 1
// Retag arguments at the beginning of the start block.
{
- // FIXME: Consider using just the span covering the function
- // argument declaration.
- let source_info = SourceInfo::outermost(span);
// Gather all arguments, skip return value.
- let places = local_decls
- .iter_enumerated()
- .skip(1)
- .take(arg_count)
- .map(|(local, _)| Place::from(local))
- .filter(needs_retag);
+ let places = local_decls.iter_enumerated().skip(1).take(body.arg_count).filter_map(
+ |(local, decl)| {
+ let place = Place::from(local);
+ needs_retag(&place).then_some((place, decl.source_info))
+ },
+ );
+
// Emit their retags.
basic_blocks[START_BLOCK].statements.splice(
0..0,
- places.map(|place| Statement {
+ places.map(|(place, source_info)| Statement {
source_info,
kind: StatementKind::Retag(RetagKind::FnEntry, Box::new(place)),
}),
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index d564f4801..beff19a3a 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -1,17 +1,16 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::hir_id::HirId;
use rustc_hir::intravisit;
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::{lint, mir::*};
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::Level;
-use std::collections::hash_map;
use std::ops::Bound;
pub struct UnsafetyChecker<'a, 'tcx> {
@@ -23,10 +22,7 @@ pub struct UnsafetyChecker<'a, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
/// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
- ///
- /// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether
- /// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`.
- used_unsafe_blocks: FxHashMap<HirId, UsedUnsafeBlockData>,
+ used_unsafe_blocks: FxHashSet<HirId>,
}
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
@@ -109,7 +105,8 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
// safe (at least as emitted during MIR construction)
}
- StatementKind::CopyNonOverlapping(..) => unreachable!(),
+ // Move to above list once mir construction uses it.
+ StatementKind::Intrinsic(..) => unreachable!(),
}
self.super_statement(statement, location);
}
@@ -130,10 +127,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
&AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => {
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
self.tcx.unsafety_check_result(def_id);
- self.register_violations(
- violations,
- used_unsafe_blocks.iter().map(|(&h, &d)| (h, d)),
- );
+ self.register_violations(violations, used_unsafe_blocks.iter().copied());
}
},
_ => {}
@@ -257,22 +251,8 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
fn register_violations<'a>(
&mut self,
violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
- new_used_unsafe_blocks: impl IntoIterator<Item = (HirId, UsedUnsafeBlockData)>,
+ new_used_unsafe_blocks: impl IntoIterator<Item = HirId>,
) {
- use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
-
- let update_entry = |this: &mut Self, hir_id, new_usage| {
- match this.used_unsafe_blocks.entry(hir_id) {
- hash_map::Entry::Occupied(mut entry) => {
- if new_usage == SomeDisallowedInUnsafeFn {
- *entry.get_mut() = SomeDisallowedInUnsafeFn;
- }
- }
- hash_map::Entry::Vacant(entry) => {
- entry.insert(new_usage);
- }
- };
- };
let safety = self.body.source_scopes[self.source_info.scope]
.local_data
.as_ref()
@@ -299,22 +279,14 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
}
}),
Safety::BuiltinUnsafe => {}
- Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|violation| {
- update_entry(
- self,
- hir_id,
- match self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, violation.lint_root).0
- {
- Level::Allow => AllAllowedInUnsafeFn(violation.lint_root),
- _ => SomeDisallowedInUnsafeFn,
- },
- )
+ Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|_violation| {
+ self.used_unsafe_blocks.insert(hir_id);
}),
};
- new_used_unsafe_blocks
- .into_iter()
- .for_each(|(hir_id, usage_data)| update_entry(self, hir_id, usage_data));
+ new_used_unsafe_blocks.into_iter().for_each(|hir_id| {
+ self.used_unsafe_blocks.insert(hir_id);
+ });
}
fn check_mut_borrowing_layout_constrained_field(
&mut self,
@@ -411,34 +383,28 @@ enum Context {
struct UnusedUnsafeVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
- used_unsafe_blocks: &'a FxHashMap<HirId, UsedUnsafeBlockData>,
+ used_unsafe_blocks: &'a FxHashSet<HirId>,
context: Context,
unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>,
}
impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
- use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
-
if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules {
let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) {
- (Level::Allow, _) => Some(SomeDisallowedInUnsafeFn),
- _ => self.used_unsafe_blocks.get(&block.hir_id).copied(),
+ (Level::Allow, _) => true,
+ _ => self.used_unsafe_blocks.contains(&block.hir_id),
};
let unused_unsafe = match (self.context, used) {
- (_, None) => UnusedUnsafe::Unused,
- (Context::Safe, Some(_))
- | (Context::UnsafeFn(_), Some(SomeDisallowedInUnsafeFn)) => {
+ (_, false) => UnusedUnsafe::Unused,
+ (Context::Safe, true) | (Context::UnsafeFn(_), true) => {
let previous_context = self.context;
self.context = Context::UnsafeBlock(block.hir_id);
intravisit::walk_block(self, block);
self.context = previous_context;
return;
}
- (Context::UnsafeFn(hir_id), Some(AllAllowedInUnsafeFn(lint_root))) => {
- UnusedUnsafe::InUnsafeFn(hir_id, lint_root)
- }
- (Context::UnsafeBlock(hir_id), Some(_)) => UnusedUnsafe::InUnsafeBlock(hir_id),
+ (Context::UnsafeBlock(hir_id), true) => UnusedUnsafe::InUnsafeBlock(hir_id),
};
self.unused_unsafes.push((block.hir_id, unused_unsafe));
}
@@ -462,7 +428,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
fn check_unused_unsafe(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
- used_unsafe_blocks: &FxHashMap<HirId, UsedUnsafeBlockData>,
+ used_unsafe_blocks: &FxHashSet<HirId>,
) -> Vec<(HirId, UnusedUnsafe)> {
let body_id = tcx.hir().maybe_body_owned_by(def_id);
@@ -535,25 +501,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
"because it's nested under this `unsafe` block",
);
}
- UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => {
- db.span_label(
- tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
- "because it's nested under this `unsafe` fn",
- )
- .note(
- "this `unsafe` block does contain unsafe operations, \
- but those are already allowed in an `unsafe fn`",
- );
- let (level, source) =
- tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root);
- assert_eq!(level, Level::Allow);
- lint::explain_lint_level_source(
- UNSAFE_OP_IN_UNSAFE_FN,
- Level::Allow,
- source,
- &mut db,
- );
- }
}
db.emit();
diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
index 611d29a4e..3378923c2 100644
--- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
@@ -33,7 +33,7 @@ pub struct DeleteNonCodegenStatements<'tcx> {
impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut delete = DeleteNonCodegenStatements { tcx };
- delete.visit_body(body);
+ delete.visit_body_preserves_cfg(body);
body.user_type_annotations.raw.clear();
for decl in &mut body.local_decls {
diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs
index 5acf939f0..0a305a402 100644
--- a/compiler/rustc_mir_transform/src/const_goto.rs
+++ b/compiler/rustc_mir_transform/src/const_goto.rs
@@ -61,14 +61,14 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
let _: Option<_> = try {
let target = terminator.kind.as_goto()?;
// We only apply this optimization if the last statement is a const assignment
- let last_statement = self.body.basic_blocks()[location.block].statements.last()?;
+ let last_statement = self.body.basic_blocks[location.block].statements.last()?;
if let (place, Rvalue::Use(Operand::Constant(_const))) =
last_statement.kind.as_assign()?
{
// We found a constant being assigned to `place`.
// Now check that the target of this Goto switches on this place.
- let target_bb = &self.body.basic_blocks()[target];
+ let target_bb = &self.body.basic_blocks[target];
// The `StorageDead(..)` statement does not affect the functionality of mir.
// We can move this part of the statement up to the predecessor.
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index fbc0a767f..7a2a15a84 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -28,7 +28,7 @@ use crate::MirPass;
use rustc_const_eval::interpret::{
self, compile_time_machine, AllocId, ConstAllocation, ConstValue, CtfeValidationMode, Frame,
ImmTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, PlaceTy,
- Pointer, Scalar, ScalarMaybeUninit, StackPopCleanup, StackPopUnwind,
+ Pointer, Scalar, StackPopCleanup, StackPopUnwind,
};
/// The maximum number of bytes that we'll allocate space for a local or the return value.
@@ -131,7 +131,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
let dummy_body = &Body::new(
body.source,
- body.basic_blocks().clone(),
+ (*body.basic_blocks).clone(),
body.source_scopes.clone(),
body.local_decls.clone(),
Default::default(),
@@ -183,6 +183,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
type MemoryKind = !;
+ #[inline(always)]
+ fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ // We do not check for alignment to avoid having to carry an `Align`
+ // in `ConstValue::ByRef`.
+ false
+ }
+
+ #[inline(always)]
+ fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ false // for now, we don't enforce validity
+ }
+
fn load_mir(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_instance: ty::InstanceDef<'tcx>,
@@ -231,24 +243,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
throw_machine_stop_str!("pointer arithmetic or comparisons aren't supported in ConstProp")
}
- fn access_local<'a>(
- frame: &'a Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>,
- local: Local,
- ) -> InterpResult<'tcx, &'a interpret::Operand<Self::Provenance>> {
- let l = &frame.locals[local];
-
- if matches!(
- l.value,
- LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit))
- ) {
- // For us "uninit" means "we don't know its value, might be initiailized or not".
- // So stop here.
- throw_machine_stop_str!("tried to access alocal with unknown value ")
- }
-
- l.access()
- }
-
fn access_local_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
frame: usize,
@@ -419,7 +413,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
fn get_const(&self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
let op = match self.ecx.eval_place_to_op(place, None) {
- Ok(op) => op,
+ Ok(op) => {
+ if matches!(*op, interpret::Operand::Immediate(Immediate::Uninit)) {
+ // Make sure nobody accidentally uses this value.
+ return None;
+ }
+ op
+ }
Err(e) => {
trace!("get_const failed: {}", e);
return None;
@@ -428,7 +428,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// Try to read the local as an immediate so that if it is representable as a scalar, we can
// handle it as such, but otherwise, just return the value as is.
- Some(match self.ecx.read_immediate_raw(&op, /*force*/ false) {
+ Some(match self.ecx.read_immediate_raw(&op) {
Ok(Ok(imm)) => imm.into(),
_ => op,
})
@@ -520,8 +520,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let left_ty = left.ty(self.local_decls, self.tcx);
let left_size = self.ecx.layout_of(left_ty).ok()?.size;
let right_size = r.layout.size;
- let r_bits = r.to_scalar().ok();
- let r_bits = r_bits.and_then(|r| r.to_bits(right_size).ok());
+ let r_bits = r.to_scalar().to_bits(right_size).ok();
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
return None;
}
@@ -550,7 +549,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// and use it to do const-prop here and everywhere else
// where it makes sense.
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
- ScalarMaybeUninit::Scalar(scalar),
+ scalar,
)) = *value
{
*operand = self.operand_from_scalar(
@@ -632,6 +631,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
if rvalue.needs_subst() {
return None;
}
+ if !rvalue
+ .ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
+ .is_sized(self.ecx.tcx, self.param_env)
+ {
+ // the interpreter doesn't support unsized locals (only unsized arguments),
+ // but rustc does (in a kinda broken way), so we have to skip them here
+ return None;
+ }
if self.tcx.sess.mir_opt_level() >= 4 {
self.eval_rvalue_with_identities(rvalue, place)
@@ -649,21 +656,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
self.use_ecx(|this| match rvalue {
Rvalue::BinaryOp(op, box (left, right))
| Rvalue::CheckedBinaryOp(op, box (left, right)) => {
- let l = this.ecx.eval_operand(left, None);
- let r = this.ecx.eval_operand(right, None);
+ let l = this.ecx.eval_operand(left, None).and_then(|x| this.ecx.read_immediate(&x));
+ let r =
+ this.ecx.eval_operand(right, None).and_then(|x| this.ecx.read_immediate(&x));
let const_arg = match (l, r) {
- (Ok(ref x), Err(_)) | (Err(_), Ok(ref x)) => this.ecx.read_immediate(x)?,
- (Err(e), Err(_)) => return Err(e),
- (Ok(_), Ok(_)) => return this.ecx.eval_rvalue_into_place(rvalue, place),
+ (Ok(x), Err(_)) | (Err(_), Ok(x)) => x, // exactly one side is known
+ (Err(e), Err(_)) => return Err(e), // neither side is known
+ (Ok(_), Ok(_)) => return this.ecx.eval_rvalue_into_place(rvalue, place), // both sides are known
};
if !matches!(const_arg.layout.abi, abi::Abi::Scalar(..)) {
// We cannot handle Scalar Pair stuff.
- return this.ecx.eval_rvalue_into_place(rvalue, place);
+ // No point in calling `eval_rvalue_into_place`, since only one side is known
+ throw_machine_stop_str!("cannot optimize this")
}
- let arg_value = const_arg.to_scalar()?.to_bits(const_arg.layout.size)?;
+ let arg_value = const_arg.to_scalar().to_bits(const_arg.layout.size)?;
let dest = this.ecx.eval_place(place)?;
match op {
@@ -677,7 +686,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
BinOp::Mul if const_arg.layout.ty.is_integral() && arg_value == 0 => {
if let Rvalue::CheckedBinaryOp(_, _) = rvalue {
let val = Immediate::ScalarPair(
- const_arg.to_scalar()?.into(),
+ const_arg.to_scalar().into(),
Scalar::from_bool(false).into(),
);
this.ecx.write_immediate(val, &dest)
@@ -685,7 +694,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
this.ecx.write_immediate(*const_arg, &dest)
}
}
- _ => this.ecx.eval_rvalue_into_place(rvalue, place),
+ _ => throw_machine_stop_str!("cannot optimize this"),
}
}
_ => this.ecx.eval_rvalue_into_place(rvalue, place),
@@ -731,21 +740,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
// FIXME> figure out what to do when read_immediate_raw fails
- let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value, /*force*/ false));
+ let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value));
if let Some(Ok(imm)) = imm {
match *imm {
- interpret::Immediate::Scalar(ScalarMaybeUninit::Scalar(scalar)) => {
+ interpret::Immediate::Scalar(scalar) => {
*rval = Rvalue::Use(self.operand_from_scalar(
scalar,
value.layout.ty,
source_info.span,
));
}
- Immediate::ScalarPair(
- ScalarMaybeUninit::Scalar(_),
- ScalarMaybeUninit::Scalar(_),
- ) => {
+ Immediate::ScalarPair(..) => {
// Found a value represented as a pair. For now only do const-prop if the type
// of `rvalue` is also a tuple with two scalars.
// FIXME: enable the general case stated above ^.
@@ -800,13 +806,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
match **op {
- interpret::Operand::Immediate(Immediate::Scalar(ScalarMaybeUninit::Scalar(s))) => {
- s.try_to_int().is_ok()
+ interpret::Operand::Immediate(Immediate::Scalar(s)) => s.try_to_int().is_ok(),
+ interpret::Operand::Immediate(Immediate::ScalarPair(l, r)) => {
+ l.try_to_int().is_ok() && r.try_to_int().is_ok()
}
- interpret::Operand::Immediate(Immediate::ScalarPair(
- ScalarMaybeUninit::Scalar(l),
- ScalarMaybeUninit::Scalar(r),
- )) => l.try_to_int().is_ok() && r.try_to_int().is_ok(),
_ => false,
}
}
@@ -951,7 +954,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
}
fn visit_body(&mut self, body: &mut Body<'tcx>) {
- for (bb, data) in body.basic_blocks_mut().iter_enumerated_mut() {
+ for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
self.visit_basic_block_data(bb, data);
}
}
@@ -1063,26 +1066,28 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
let source_info = terminator.source_info;
self.source_info = Some(source_info);
self.super_terminator(terminator, location);
+ // Do NOT early return in this function, it does some crucial fixup of the state at the end!
match &mut terminator.kind {
TerminatorKind::Assert { expected, ref mut cond, .. } => {
if let Some(ref value) = self.eval_operand(&cond) {
trace!("assertion on {:?} should be {:?}", value, expected);
- let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected));
- let value_const = self.ecx.read_scalar(&value).unwrap();
- if expected != value_const {
- // Poison all places this operand references so that further code
- // doesn't use the invalid value
- match cond {
- Operand::Move(ref place) | Operand::Copy(ref place) => {
- Self::remove_const(&mut self.ecx, place.local);
+ let expected = Scalar::from_bool(*expected);
+ // FIXME should be used use_ecx rather than a local match... but we have
+ // quite a few of these read_scalar/read_immediate that need fixing.
+ if let Ok(value_const) = self.ecx.read_scalar(&value) {
+ if expected != value_const {
+ // Poison all places this operand references so that further code
+ // doesn't use the invalid value
+ match cond {
+ Operand::Move(ref place) | Operand::Copy(ref place) => {
+ Self::remove_const(&mut self.ecx, place.local);
+ }
+ Operand::Constant(_) => {}
}
- Operand::Constant(_) => {}
- }
- } else {
- if self.should_const_prop(value) {
- if let ScalarMaybeUninit::Scalar(scalar) = value_const {
+ } else {
+ if self.should_const_prop(value) {
*cond = self.operand_from_scalar(
- scalar,
+ value_const,
self.tcx.types.bool,
source_info.span,
);
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index c2ea55af4..37e78f4ac 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -6,9 +6,9 @@ use crate::const_prop::ConstPropMachine;
use crate::const_prop::ConstPropMode;
use crate::MirLint;
use rustc_const_eval::const_eval::ConstEvalErr;
+use rustc_const_eval::interpret::Immediate;
use rustc_const_eval::interpret::{
- self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar,
- ScalarMaybeUninit, StackPopCleanup,
+ self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup,
};
use rustc_hir::def::DefKind;
use rustc_hir::HirId;
@@ -22,9 +22,7 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
-use rustc_middle::ty::{
- self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable,
-};
+use rustc_middle::ty::{self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable};
use rustc_session::lint;
use rustc_span::Span;
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
@@ -106,7 +104,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp {
let dummy_body = &Body::new(
body.source,
- body.basic_blocks().clone(),
+ (*body.basic_blocks).clone(),
body.source_scopes.clone(),
body.local_decls.clone(),
Default::default(),
@@ -230,7 +228,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
fn get_const(&self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
let op = match self.ecx.eval_place_to_op(place, None) {
- Ok(op) => op,
+ Ok(op) => {
+ if matches!(*op, interpret::Operand::Immediate(Immediate::Uninit)) {
+ // Make sure nobody accidentally uses this value.
+ return None;
+ }
+ op
+ }
Err(e) => {
trace!("get_const failed: {}", e);
return None;
@@ -239,7 +243,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// Try to read the local as an immediate so that if it is representable as a scalar, we can
// handle it as such, but otherwise, just return the value as is.
- Some(match self.ecx.read_immediate_raw(&op, /*force*/ false) {
+ Some(match self.ecx.read_immediate_raw(&op) {
Ok(Ok(imm)) => imm.into(),
_ => op,
})
@@ -295,18 +299,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let err = ConstEvalErr::new(&self.ecx, error, Some(c.span));
if let Some(lint_root) = self.lint_root(source_info) {
let lint_only = match c.literal {
- ConstantKind::Ty(ct) => match ct.kind() {
+ ConstantKind::Ty(ct) => ct.needs_subst(),
+ ConstantKind::Unevaluated(
+ ty::Unevaluated { def: _, substs: _, promoted: Some(_) },
+ _,
+ ) => {
// Promoteds must lint and not error as the user didn't ask for them
- ConstKind::Unevaluated(ty::Unevaluated {
- def: _,
- substs: _,
- promoted: Some(_),
- }) => true,
- // Out of backwards compatibility we cannot report hard errors in unused
- // generic functions using associated constants of the generic parameters.
- _ => c.literal.needs_subst(),
- },
- ConstantKind::Val(_, ty) => ty.needs_subst(),
+ true
+ }
+ ConstantKind::Unevaluated(..) | ConstantKind::Val(..) => c.needs_subst(),
};
if lint_only {
// Out of backwards compatibility we cannot report hard errors in unused
@@ -401,8 +402,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let left_ty = left.ty(self.local_decls, self.tcx);
let left_size = self.ecx.layout_of(left_ty).ok()?.size;
let right_size = r.layout.size;
- let r_bits = r.to_scalar().ok();
- let r_bits = r_bits.and_then(|r| r.to_bits(right_size).ok());
+ let r_bits = r.to_scalar().to_bits(right_size).ok();
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
debug!("check_binary_op: reporting assert for {:?}", source_info);
self.report_assert_as_lint(
@@ -517,6 +517,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
if rvalue.needs_subst() {
return None;
}
+ if !rvalue
+ .ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
+ .is_sized(self.ecx.tcx, self.param_env)
+ {
+ // the interpreter doesn't support unsized locals (only unsized arguments),
+ // but rustc does (in a kinda broken way), so we have to skip them here
+ return None;
+ }
self.use_ecx(source_info, |this| this.ecx.eval_rvalue_into_place(rvalue, place))
}
@@ -524,7 +532,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
fn visit_body(&mut self, body: &Body<'tcx>) {
- for (bb, data) in body.basic_blocks().iter_enumerated() {
+ for (bb, data) in body.basic_blocks.iter_enumerated() {
self.visit_basic_block_data(bb, data);
}
}
@@ -625,8 +633,12 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
TerminatorKind::Assert { expected, ref msg, ref cond, .. } => {
if let Some(ref value) = self.eval_operand(&cond, source_info) {
trace!("assertion on {:?} should be {:?}", value, expected);
- let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected));
- let value_const = self.ecx.read_scalar(&value).unwrap();
+ let expected = Scalar::from_bool(*expected);
+ let Ok(value_const) = self.ecx.read_scalar(&value) else {
+ // FIXME should be used use_ecx rather than a local match... but we have
+ // quite a few of these read_scalar/read_immediate that need fixing.
+ return
+ };
if expected != value_const {
enum DbgVal<T> {
Val(T),
@@ -643,9 +655,9 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
let mut eval_to_int = |op| {
// This can be `None` if the lhs wasn't const propagated and we just
// triggered the assert on the value of the rhs.
- self.eval_operand(op, source_info).map_or(DbgVal::Underscore, |op| {
- DbgVal::Val(self.ecx.read_immediate(&op).unwrap().to_const_int())
- })
+ self.eval_operand(op, source_info)
+ .and_then(|op| self.ecx.read_immediate(&op).ok())
+ .map_or(DbgVal::Underscore, |op| DbgVal::Val(op.to_const_int()))
};
let msg = match msg {
AssertKind::DivisionByZero(op) => {
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 759ea7cd3..782129be0 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -713,7 +713,7 @@ impl<
ShortCircuitPreorder {
body,
- visited: BitSet::new_empty(body.basic_blocks().len()),
+ visited: BitSet::new_empty(body.basic_blocks.len()),
worklist,
filtered_successors,
}
@@ -747,7 +747,7 @@ impl<
}
fn size_hint(&self) -> (usize, Option<usize>) {
- let size = self.body.basic_blocks().len() - self.visited.count();
+ let size = self.body.basic_blocks.len() - self.visited.count();
(size, Some(size))
}
}
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 2619626a5..604810144 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -80,7 +80,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
return;
}
- match mir_body.basic_blocks()[mir::START_BLOCK].terminator().kind {
+ match mir_body.basic_blocks[mir::START_BLOCK].terminator().kind {
TerminatorKind::Unreachable => {
trace!("InstrumentCoverage skipped for unreachable `START_BLOCK`");
return;
@@ -541,7 +541,7 @@ fn fn_sig_and_body<'tcx>(
// to HIR for it.
let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local");
let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body");
- (hir::map::fn_sig(hir_node), tcx.hir().body(fn_body_id))
+ (hir_node.fn_sig(), tcx.hir().body(fn_body_id))
}
fn get_body_span<'tcx>(
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 9d02f58ae..dc1e68b25 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -84,7 +84,7 @@ impl CoverageVisitor {
}
fn visit_body(&mut self, body: &Body<'_>) {
- for bb_data in body.basic_blocks().iter() {
+ for bb_data in body.basic_blocks.iter() {
for statement in bb_data.statements.iter() {
if let StatementKind::Coverage(box ref coverage) = statement.kind {
if is_inlined(body, statement) {
@@ -138,7 +138,7 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) ->
fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
let body = mir_body(tcx, def_id);
- body.basic_blocks()
+ body.basic_blocks
.iter()
.flat_map(|data| {
data.statements.iter().filter_map(|statement| match statement.kind {
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 423e78317..9f842c929 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -825,7 +825,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
// Retain spans from all other statements
StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Assign(_)
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(..)
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 6380f0352..9c9ed5fa5 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -176,7 +176,7 @@ fn debug_basic_blocks<'tcx>(mir_body: &Body<'tcx>) -> String {
format!(
"{:?}",
mir_body
- .basic_blocks()
+ .basic_blocks
.iter_enumerated()
.map(|(bb, data)| {
let term = &data.terminator();
@@ -213,7 +213,7 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) {
"digraph {} {{\n{}\n}}",
name,
mir_body
- .basic_blocks()
+ .basic_blocks
.iter_enumerated()
.map(|(bb, data)| {
format!(
@@ -653,7 +653,7 @@ fn test_traverse_coverage_with_loops() {
fn synthesize_body_span_from_terminators(mir_body: &Body<'_>) -> Span {
let mut some_span: Option<Span> = None;
- for (_, data) in mir_body.basic_blocks().iter_enumerated() {
+ for (_, data) in mir_body.basic_blocks.iter_enumerated() {
let term_span = data.terminator().source_info.span;
if let Some(span) = some_span.as_mut() {
*span = span.to(term_span);
diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
index 9163672f5..3f3870cc7 100644
--- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs
+++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
@@ -52,7 +52,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
| StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Coverage(_)
- | StatementKind::CopyNonOverlapping(_)
+ | StatementKind::Intrinsic(_)
| StatementKind::Nop => (),
StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => {
diff --git a/compiler/rustc_mir_transform/src/deaggregator.rs b/compiler/rustc_mir_transform/src/deaggregator.rs
index b93fe5879..fe272de20 100644
--- a/compiler/rustc_mir_transform/src/deaggregator.rs
+++ b/compiler/rustc_mir_transform/src/deaggregator.rs
@@ -6,10 +6,6 @@ use rustc_middle::ty::TyCtxt;
pub struct Deaggregator;
impl<'tcx> MirPass<'tcx> for Deaggregator {
- fn phase_change(&self) -> Option<MirPhase> {
- Some(MirPhase::Deaggregated)
- }
-
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
for bb in basic_blocks {
diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
index d1977ed49..909116a77 100644
--- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
+++ b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
@@ -58,7 +58,7 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap<BasicBlock, BasicBlock> {
let mut duplicates = FxHashMap::default();
let bbs_to_go_through =
- body.basic_blocks().iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count();
+ body.basic_blocks.iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count();
let mut same_hashes =
FxHashMap::with_capacity_and_hasher(bbs_to_go_through, Default::default());
@@ -71,8 +71,7 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap<BasicBlock, BasicBlock> {
// When we see bb1, we see that it is a duplicate of bb3, and therefore insert it in the duplicates list
// with replacement bb3.
// When the duplicates are removed, we will end up with only bb3.
- for (bb, bbd) in body.basic_blocks().iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup)
- {
+ for (bb, bbd) in body.basic_blocks.iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) {
// Basic blocks can get really big, so to avoid checking for duplicates in basic blocks
// that are unlikely to have duplicates, we stop early. The early bail number has been
// found experimentally by eprintln while compiling the crates in the rustc-perf suite.
diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs
index a00bb16f7..7508df92d 100644
--- a/compiler/rustc_mir_transform/src/deref_separator.rs
+++ b/compiler/rustc_mir_transform/src/deref_separator.rs
@@ -28,8 +28,6 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
let mut last_len = 0;
let mut last_deref_idx = 0;
- let mut prev_temp: Option<Local> = None;
-
for (idx, elem) in place.projection[0..].iter().enumerate() {
if *elem == ProjectionElem::Deref {
last_deref_idx = idx;
@@ -39,14 +37,12 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref {
let ty = p_ref.ty(&self.local_decls, self.tcx).ty;
- let temp = self.patcher.new_local_with_info(
+ let temp = self.patcher.new_internal_with_info(
ty,
self.local_decls[p_ref.local].source_info.span,
Some(Box::new(LocalInfo::DerefTemp)),
);
- self.patcher.add_statement(loc, StatementKind::StorageLive(temp));
-
// We are adding current p_ref's projections to our
// temp value, excluding projections we already covered.
let deref_place = Place::from(place_local)
@@ -66,22 +62,8 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
Place::from(temp).project_deeper(&place.projection[idx..], self.tcx);
*place = temp_place;
}
-
- // We are destroying the previous temp since it's no longer used.
- if let Some(prev_temp) = prev_temp {
- self.patcher.add_statement(loc, StatementKind::StorageDead(prev_temp));
- }
-
- prev_temp = Some(temp);
}
}
-
- // Since we won't be able to reach final temp, we destroy it outside the loop.
- if let Some(prev_temp) = prev_temp {
- let last_loc =
- Location { block: loc.block, statement_index: loc.statement_index + 1 };
- self.patcher.add_statement(last_loc, StatementKind::StorageDead(prev_temp));
- }
}
}
}
@@ -90,7 +72,7 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let patch = MirPatch::new(body);
let mut checker = DerefChecker { tcx, patcher: patch, local_decls: body.local_decls.clone() };
- for (bb, data) in body.basic_blocks_mut().iter_enumerated_mut() {
+ for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
checker.visit_basic_block_data(bb, data);
}
@@ -100,6 +82,5 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
impl<'tcx> MirPass<'tcx> for Derefer {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
deref_finder(tcx, body);
- body.phase = MirPhase::Derefered;
}
}
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 33572068f..9bc47613e 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -150,7 +150,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
def_id,
body.local_decls.len(),
relevant,
- body.basic_blocks().len()
+ body.basic_blocks.len()
);
if relevant > MAX_LOCALS {
warn!(
@@ -159,11 +159,11 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
);
return;
}
- if body.basic_blocks().len() > MAX_BLOCKS {
+ if body.basic_blocks.len() > MAX_BLOCKS {
warn!(
"too many blocks in {:?} ({}, max is {}), not optimizing",
def_id,
- body.basic_blocks().len(),
+ body.basic_blocks.len(),
MAX_BLOCKS
);
return;
@@ -537,7 +537,7 @@ impl<'a> Conflicts<'a> {
| StatementKind::FakeRead(..)
| StatementKind::AscribeUserType(..)
| StatementKind::Coverage(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Nop => {}
}
}
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index dba42f7af..32e738bbc 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -104,8 +104,8 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
let mut should_cleanup = false;
// Also consider newly generated bbs in the same pass
- for i in 0..body.basic_blocks().len() {
- let bbs = body.basic_blocks();
+ for i in 0..body.basic_blocks.len() {
+ let bbs = &*body.basic_blocks;
let parent = BasicBlock::from_usize(i);
let Some(opt_data) = evaluate_candidate(tcx, body, parent) else {
continue
@@ -316,7 +316,7 @@ fn evaluate_candidate<'tcx>(
body: &Body<'tcx>,
parent: BasicBlock,
) -> Option<OptimizationData<'tcx>> {
- let bbs = body.basic_blocks();
+ let bbs = &body.basic_blocks;
let TerminatorKind::SwitchInt {
targets,
switch_ty: parent_ty,
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index 44e3945d6..294af2455 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -69,10 +69,7 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
let (unique_ty, nonnull_ty, ptr_ty) =
build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did);
- let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
- self.local_decls.push(LocalDecl::new(ptr_ty, source_info.span));
-
- self.patch.add_statement(location, StatementKind::StorageLive(ptr_local));
+ let ptr_local = self.patch.new_internal(ptr_ty, source_info.span);
self.patch.add_assign(
location,
@@ -84,11 +81,6 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
);
place.local = ptr_local;
-
- self.patch.add_statement(
- Location { block: location.block, statement_index: location.statement_index + 1 },
- StatementKind::StorageDead(ptr_local),
- );
}
self.super_place(place, context, location);
@@ -115,34 +107,8 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
let mut visitor =
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
- for (block, BasicBlockData { statements, terminator, .. }) in
- body.basic_blocks.as_mut().iter_enumerated_mut()
- {
- let mut index = 0;
- for statement in statements {
- let location = Location { block, statement_index: index };
- visitor.visit_statement(statement, location);
- index += 1;
- }
-
- if let Some(terminator) = terminator
- && !matches!(terminator.kind, TerminatorKind::Yield{..})
- {
- let location = Location { block, statement_index: index };
- visitor.visit_terminator(terminator, location);
- }
-
- let location = Location { block, statement_index: index };
- match terminator {
- // yielding into a box is handled when lowering generators
- Some(Terminator { kind: TerminatorKind::Yield { value, .. }, .. }) => {
- visitor.visit_operand(value, location);
- }
- Some(terminator) => {
- visitor.visit_terminator(terminator, location);
- }
- None => {}
- }
+ for (block, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
+ visitor.visit_basic_block_data(block, data);
}
visitor.patch.apply(body);
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 9c1fcbaa6..65f4956d2 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -21,10 +21,6 @@ use std::fmt;
pub struct ElaborateDrops;
impl<'tcx> MirPass<'tcx> for ElaborateDrops {
- fn phase_change(&self) -> Option<MirPhase> {
- Some(MirPhase::DropsLowered)
- }
-
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);
@@ -89,13 +85,13 @@ fn find_dead_unwinds<'tcx>(
debug!("find_dead_unwinds({:?})", body.span);
// We only need to do this pass once, because unwind edges can only
// reach cleanup blocks, which can't have unwind edges themselves.
- let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
+ let mut dead_unwinds = BitSet::new_empty(body.basic_blocks.len());
let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env)
.into_engine(tcx, body)
.pass_name("find_dead_unwinds")
.iterate_to_fixpoint()
.into_results_cursor(body);
- for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
+ for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
let place = match bb_data.terminator().kind {
TerminatorKind::Drop { ref place, unwind: Some(_), .. }
| TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => {
@@ -303,7 +299,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
fn collect_drop_flags(&mut self) {
- for (bb, data) in self.body.basic_blocks().iter_enumerated() {
+ for (bb, data) in self.body.basic_blocks.iter_enumerated() {
let terminator = data.terminator();
let place = match terminator.kind {
TerminatorKind::Drop { ref place, .. }
@@ -358,7 +354,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
fn elaborate_drops(&mut self) {
- for (bb, data) in self.body.basic_blocks().iter_enumerated() {
+ for (bb, data) in self.body.basic_blocks.iter_enumerated() {
let loc = Location { block: bb, statement_index: data.statements.len() };
let terminator = data.terminator();
@@ -515,7 +511,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
fn drop_flags_for_fn_rets(&mut self) {
- for (bb, data) in self.body.basic_blocks().iter_enumerated() {
+ for (bb, data) in self.body.basic_blocks.iter_enumerated() {
if let TerminatorKind::Call {
destination, target: Some(tgt), cleanup: Some(_), ..
} = data.terminator().kind
@@ -550,7 +546,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
// drop flags by themselves, to avoid the drop flags being
// clobbered before they are read.
- for (bb, data) in self.body.basic_blocks().iter_enumerated() {
+ for (bb, data) in self.body.basic_blocks.iter_enumerated() {
debug!("drop_flags_for_locs({:?})", data);
for i in 0..(data.statements.len() + 1) {
debug!("drop_flag_for_locs: stmt {}", i);
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 7728fdaff..7522a50a8 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -65,7 +65,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
let mut tainted = false;
- for block in body.basic_blocks() {
+ for block in body.basic_blocks.iter() {
if block.is_cleanup {
continue;
}
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 91ecf3879..705cf776f 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -490,12 +490,12 @@ fn locals_live_across_suspend_points<'tcx>(
.iterate_to_fixpoint()
.into_results_cursor(body_ref);
- let mut storage_liveness_map = IndexVec::from_elem(None, body.basic_blocks());
+ let mut storage_liveness_map = IndexVec::from_elem(None, &body.basic_blocks);
let mut live_locals_at_suspension_points = Vec::new();
let mut source_info_at_suspension_points = Vec::new();
let mut live_locals_at_any_suspension_point = BitSet::new_empty(body.local_decls.len());
- for (block, data) in body.basic_blocks().iter_enumerated() {
+ for (block, data) in body.basic_blocks.iter_enumerated() {
if let TerminatorKind::Yield { .. } = data.terminator().kind {
let loc = Location { block, statement_index: data.statements.len() };
@@ -704,7 +704,7 @@ impl<'mir, 'tcx> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx>
impl StorageConflictVisitor<'_, '_, '_> {
fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) {
// Ignore unreachable blocks.
- if self.body.basic_blocks()[loc.block].terminator().kind == TerminatorKind::Unreachable {
+ if self.body.basic_blocks[loc.block].terminator().kind == TerminatorKind::Unreachable {
return;
}
@@ -886,7 +886,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env };
- for (block, block_data) in body.basic_blocks().iter_enumerated() {
+ for (block, block_data) in body.basic_blocks.iter_enumerated() {
let (target, unwind, source_info) = match block_data.terminator() {
Terminator { source_info, kind: TerminatorKind::Drop { place, target, unwind } } => {
if let Some(local) = place.as_local() {
@@ -991,7 +991,7 @@ fn insert_panic_block<'tcx>(
body: &mut Body<'tcx>,
message: AssertMessage<'tcx>,
) -> BasicBlock {
- let assert_block = BasicBlock::new(body.basic_blocks().len());
+ let assert_block = BasicBlock::new(body.basic_blocks.len());
let term = TerminatorKind::Assert {
cond: Operand::Constant(Box::new(Constant {
span: body.span,
@@ -1021,7 +1021,7 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEn
}
// If there's a return terminator the function may return.
- for block in body.basic_blocks() {
+ for block in body.basic_blocks.iter() {
if let TerminatorKind::Return = block.terminator().kind {
return true;
}
@@ -1038,7 +1038,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
}
// Unwinds can only start at certain terminators.
- for block in body.basic_blocks() {
+ for block in body.basic_blocks.iter() {
match block.terminator().kind {
// These never unwind.
TerminatorKind::Goto { .. }
@@ -1182,8 +1182,6 @@ fn create_cases<'tcx>(
transform: &TransformVisitor<'tcx>,
operation: Operation,
) -> Vec<(usize, BasicBlock)> {
- let tcx = transform.tcx;
-
let source_info = SourceInfo::outermost(body.span);
transform
@@ -1216,85 +1214,13 @@ fn create_cases<'tcx>(
if operation == Operation::Resume {
// Move the resume argument to the destination place of the `Yield` terminator
let resume_arg = Local::new(2); // 0 = return, 1 = self
-
- // handle `box yield` properly
- let box_place = if let [projection @ .., ProjectionElem::Deref] =
- &**point.resume_arg.projection
- {
- let box_place =
- Place::from(point.resume_arg.local).project_deeper(projection, tcx);
-
- let box_ty = box_place.ty(&body.local_decls, tcx).ty;
-
- if box_ty.is_box() { Some((box_place, box_ty)) } else { None }
- } else {
- None
- };
-
- if let Some((box_place, box_ty)) = box_place {
- let unique_did = box_ty
- .ty_adt_def()
- .expect("expected Box to be an Adt")
- .non_enum_variant()
- .fields[0]
- .did;
-
- let Some(nonnull_def) = tcx.type_of(unique_did).ty_adt_def() else {
- span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
- };
-
- let nonnull_did = nonnull_def.non_enum_variant().fields[0].did;
-
- let (unique_ty, nonnull_ty, ptr_ty) =
- crate::elaborate_box_derefs::build_ptr_tys(
- tcx,
- box_ty.boxed_ty(),
- unique_did,
- nonnull_did,
- );
-
- let ptr_local = body.local_decls.push(LocalDecl::new(ptr_ty, body.span));
-
- statements.push(Statement {
- source_info,
- kind: StatementKind::StorageLive(ptr_local),
- });
-
- statements.push(Statement {
- source_info,
- kind: StatementKind::Assign(Box::new((
- Place::from(ptr_local),
- Rvalue::Use(Operand::Copy(box_place.project_deeper(
- &crate::elaborate_box_derefs::build_projection(
- unique_ty, nonnull_ty, ptr_ty,
- ),
- tcx,
- ))),
- ))),
- });
-
- statements.push(Statement {
- source_info,
- kind: StatementKind::Assign(Box::new((
- Place::from(ptr_local)
- .project_deeper(&[ProjectionElem::Deref], tcx),
- Rvalue::Use(Operand::Move(resume_arg.into())),
- ))),
- });
-
- statements.push(Statement {
- source_info,
- kind: StatementKind::StorageDead(ptr_local),
- });
- } else {
- statements.push(Statement {
- source_info,
- kind: StatementKind::Assign(Box::new((
- point.resume_arg,
- Rvalue::Use(Operand::Move(resume_arg.into())),
- ))),
- });
- }
+ statements.push(Statement {
+ source_info,
+ kind: StatementKind::Assign(Box::new((
+ point.resume_arg,
+ Rvalue::Use(Operand::Move(resume_arg.into())),
+ ))),
+ });
}
// Then jump to the real target
@@ -1314,10 +1240,6 @@ fn create_cases<'tcx>(
}
impl<'tcx> MirPass<'tcx> for StateTransform {
- fn phase_change(&self) -> Option<MirPhase> {
- Some(MirPhase::GeneratorsLowered)
- }
-
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let Some(yield_ty) = body.yield_ty() else {
// This only applies to generators
@@ -1530,7 +1452,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
| StatementKind::Retag(..)
| StatementKind::AscribeUserType(..)
| StatementKind::Coverage(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Nop => {}
}
}
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 76b1522f3..d00a384cb 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -8,8 +8,11 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::subst::Subst;
-use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
+use rustc_session::config::OptLevel;
+use rustc_span::def_id::DefId;
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
+use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use super::simplify::{remove_dead_blocks, CfgSimplifier};
@@ -43,8 +46,15 @@ impl<'tcx> MirPass<'tcx> for Inline {
return enabled;
}
- // rust-lang/rust#101004: reverted to old inlining decision logic
- sess.mir_opt_level() >= 3
+ match sess.mir_opt_level() {
+ 0 | 1 => false,
+ 2 => {
+ (sess.opts.optimize == OptLevel::Default
+ || sess.opts.optimize == OptLevel::Aggressive)
+ && sess.opts.incremental == None
+ }
+ _ => true,
+ }
}
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -85,7 +95,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
history: Vec::new(),
changed: false,
};
- let blocks = BasicBlock::new(0)..body.basic_blocks().next_index();
+ let blocks = BasicBlock::new(0)..body.basic_blocks.next_index();
this.process_blocks(body, blocks);
this.changed
}
@@ -95,8 +105,12 @@ struct Inliner<'tcx> {
param_env: ParamEnv<'tcx>,
/// Caller codegen attributes.
codegen_fn_attrs: &'tcx CodegenFnAttrs,
- /// Stack of inlined Instances.
- history: Vec<ty::Instance<'tcx>>,
+ /// Stack of inlined instances.
+ /// We only check the `DefId` and not the substs because we want to
+ /// avoid inlining cases of polymorphic recursion.
+ /// The number of `DefId`s is finite, so checking history is enough
+ /// to ensure that we do not loop endlessly while inlining.
+ history: Vec<DefId>,
/// Indicates that the caller body has been modified.
changed: bool,
}
@@ -124,7 +138,7 @@ impl<'tcx> Inliner<'tcx> {
Ok(new_blocks) => {
debug!("inlined {}", callsite.callee);
self.changed = true;
- self.history.push(callsite.callee);
+ self.history.push(callsite.callee.def_id());
self.process_blocks(caller_body, new_blocks);
self.history.pop();
}
@@ -203,9 +217,9 @@ impl<'tcx> Inliner<'tcx> {
}
}
- let old_blocks = caller_body.basic_blocks().next_index();
+ let old_blocks = caller_body.basic_blocks.next_index();
self.inline_call(caller_body, &callsite, callee_body);
- let new_blocks = old_blocks..caller_body.basic_blocks().next_index();
+ let new_blocks = old_blocks..caller_body.basic_blocks.next_index();
Ok(new_blocks)
}
@@ -300,7 +314,7 @@ impl<'tcx> Inliner<'tcx> {
return None;
}
- if self.history.contains(&callee) {
+ if self.history.contains(&callee.def_id()) {
return None;
}
@@ -395,124 +409,66 @@ impl<'tcx> Inliner<'tcx> {
// Give a bonus functions with a small number of blocks,
// We normally have two or three blocks for even
// very small functions.
- if callee_body.basic_blocks().len() <= 3 {
+ if callee_body.basic_blocks.len() <= 3 {
threshold += threshold / 4;
}
debug!(" final inline threshold = {}", threshold);
// FIXME: Give a bonus to functions with only a single caller
- let mut first_block = true;
- let mut cost = 0;
+ let diverges = matches!(
+ callee_body.basic_blocks[START_BLOCK].terminator().kind,
+ TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. }
+ );
+ if diverges && !matches!(callee_attrs.inline, InlineAttr::Always) {
+ return Err("callee diverges unconditionally");
+ }
- // Traverse the MIR manually so we can account for the effects of
- // inlining on the CFG.
+ let mut checker = CostChecker {
+ tcx: self.tcx,
+ param_env: self.param_env,
+ instance: callsite.callee,
+ callee_body,
+ cost: 0,
+ validation: Ok(()),
+ };
+
+ // Traverse the MIR manually so we can account for the effects of inlining on the CFG.
let mut work_list = vec![START_BLOCK];
- let mut visited = BitSet::new_empty(callee_body.basic_blocks().len());
+ let mut visited = BitSet::new_empty(callee_body.basic_blocks.len());
while let Some(bb) = work_list.pop() {
if !visited.insert(bb.index()) {
continue;
}
- let blk = &callee_body.basic_blocks()[bb];
- for stmt in &blk.statements {
- // Don't count StorageLive/StorageDead in the inlining cost.
- match stmt.kind {
- StatementKind::StorageLive(_)
- | StatementKind::StorageDead(_)
- | StatementKind::Deinit(_)
- | StatementKind::Nop => {}
- _ => cost += INSTR_COST,
- }
- }
- let term = blk.terminator();
- let mut is_drop = false;
- match term.kind {
- TerminatorKind::Drop { ref place, target, unwind }
- | TerminatorKind::DropAndReplace { ref place, target, unwind, .. } => {
- is_drop = true;
- work_list.push(target);
- // If the place doesn't actually need dropping, treat it like
- // a regular goto.
- let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty);
- if ty.needs_drop(tcx, self.param_env) {
- cost += CALL_PENALTY;
- if let Some(unwind) = unwind {
- cost += LANDINGPAD_PENALTY;
- work_list.push(unwind);
- }
- } else {
- cost += INSTR_COST;
- }
- }
+ let blk = &callee_body.basic_blocks[bb];
+ checker.visit_basic_block_data(bb, blk);
- TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. }
- if first_block =>
- {
- // If the function always diverges, don't inline
- // unless the cost is zero
- threshold = 0;
- }
-
- TerminatorKind::Call { func: Operand::Constant(ref f), cleanup, .. } => {
- if let ty::FnDef(def_id, _) =
- *callsite.callee.subst_mir(self.tcx, &f.literal.ty()).kind()
- {
- // Don't give intrinsics the extra penalty for calls
- if tcx.is_intrinsic(def_id) {
- cost += INSTR_COST;
- } else {
- cost += CALL_PENALTY;
- }
- } else {
- cost += CALL_PENALTY;
- }
- if cleanup.is_some() {
- cost += LANDINGPAD_PENALTY;
- }
- }
- TerminatorKind::Assert { cleanup, .. } => {
- cost += CALL_PENALTY;
-
- if cleanup.is_some() {
- cost += LANDINGPAD_PENALTY;
- }
- }
- TerminatorKind::Resume => cost += RESUME_PENALTY,
- TerminatorKind::InlineAsm { cleanup, .. } => {
- cost += INSTR_COST;
+ let term = blk.terminator();
+ if let TerminatorKind::Drop { ref place, target, unwind }
+ | TerminatorKind::DropAndReplace { ref place, target, unwind, .. } = term.kind
+ {
+ work_list.push(target);
- if cleanup.is_some() {
- cost += LANDINGPAD_PENALTY;
+ // If the place doesn't actually need dropping, treat it like a regular goto.
+ let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty);
+ if ty.needs_drop(tcx, self.param_env) && let Some(unwind) = unwind {
+ work_list.push(unwind);
}
- }
- _ => cost += INSTR_COST,
- }
-
- if !is_drop {
- for succ in term.successors() {
- work_list.push(succ);
- }
+ } else {
+ work_list.extend(term.successors())
}
-
- first_block = false;
}
// Count up the cost of local variables and temps, if we know the size
// use that, otherwise we use a moderately-large dummy cost.
-
- let ptr_size = tcx.data_layout.pointer_size.bytes();
-
for v in callee_body.vars_and_temps_iter() {
- let ty = callsite.callee.subst_mir(self.tcx, &callee_body.local_decls[v].ty);
- // Cost of the var is the size in machine-words, if we know
- // it.
- if let Some(size) = type_size_of(tcx, self.param_env, ty) {
- cost += ((size + ptr_size - 1) / ptr_size) as usize;
- } else {
- cost += UNKNOWN_SIZE_COST;
- }
+ checker.visit_local_decl(v, &callee_body.local_decls[v]);
}
+ // Abort if type validation found anything fishy.
+ checker.validation?;
+
+ let cost = checker.cost;
if let InlineAttr::Always = callee_attrs.inline {
debug!("INLINING {:?} because inline(always) [cost={}]", callsite, cost);
Ok(())
@@ -585,7 +541,7 @@ impl<'tcx> Inliner<'tcx> {
args: &args,
new_locals: Local::new(caller_body.local_decls.len())..,
new_scopes: SourceScope::new(caller_body.source_scopes.len())..,
- new_blocks: BasicBlock::new(caller_body.basic_blocks().len())..,
+ new_blocks: BasicBlock::new(caller_body.basic_blocks.len())..,
destination: dest,
callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(),
callsite,
@@ -603,7 +559,9 @@ impl<'tcx> Inliner<'tcx> {
// If there are any locals without storage markers, give them storage only for the
// duration of the call.
for local in callee_body.vars_and_temps_iter() {
- if integrator.always_live_locals.contains(local) {
+ if !callee_body.local_decls[local].internal
+ && integrator.always_live_locals.contains(local)
+ {
let new_local = integrator.map_local(local);
caller_body[callsite.block].statements.push(Statement {
source_info: callsite.source_info,
@@ -616,7 +574,9 @@ impl<'tcx> Inliner<'tcx> {
// the slice once.
let mut n = 0;
for local in callee_body.vars_and_temps_iter().rev() {
- if integrator.always_live_locals.contains(local) {
+ if !callee_body.local_decls[local].internal
+ && integrator.always_live_locals.contains(local)
+ {
let new_local = integrator.map_local(local);
caller_body[block].statements.push(Statement {
source_info: callsite.source_info,
@@ -644,11 +604,11 @@ impl<'tcx> Inliner<'tcx> {
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
// because we are calling `subst_and_normalize_erasing_regions`.
caller_body.required_consts.extend(
- callee_body.required_consts.iter().copied().filter(|&ct| {
- match ct.literal.const_for_ty() {
- Some(ct) => matches!(ct.kind(), ConstKind::Unevaluated(_)),
- None => true,
+ callee_body.required_consts.iter().copied().filter(|&ct| match ct.literal {
+ ConstantKind::Ty(_) => {
+ bug!("should never encounter ty::Unevaluated in `required_consts`")
}
+ ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => true,
}),
);
}
@@ -782,6 +742,193 @@ fn type_size_of<'tcx>(
tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes())
}
+/// Verify that the callee body is compatible with the caller.
+///
+/// This visitor mostly computes the inlining cost,
+/// but also needs to verify that types match because of normalization failure.
+struct CostChecker<'b, 'tcx> {
+ tcx: TyCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ cost: usize,
+ callee_body: &'b Body<'tcx>,
+ instance: ty::Instance<'tcx>,
+ validation: Result<(), &'static str>,
+}
+
+impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
+ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
+ // Don't count StorageLive/StorageDead in the inlining cost.
+ match statement.kind {
+ StatementKind::StorageLive(_)
+ | StatementKind::StorageDead(_)
+ | StatementKind::Deinit(_)
+ | StatementKind::Nop => {}
+ _ => self.cost += INSTR_COST,
+ }
+
+ self.super_statement(statement, location);
+ }
+
+ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
+ let tcx = self.tcx;
+ match terminator.kind {
+ TerminatorKind::Drop { ref place, unwind, .. }
+ | TerminatorKind::DropAndReplace { ref place, unwind, .. } => {
+ // If the place doesn't actually need dropping, treat it like a regular goto.
+ let ty = self.instance.subst_mir(tcx, &place.ty(self.callee_body, tcx).ty);
+ if ty.needs_drop(tcx, self.param_env) {
+ self.cost += CALL_PENALTY;
+ if unwind.is_some() {
+ self.cost += LANDINGPAD_PENALTY;
+ }
+ } else {
+ self.cost += INSTR_COST;
+ }
+ }
+ TerminatorKind::Call { func: Operand::Constant(ref f), cleanup, .. } => {
+ let fn_ty = self.instance.subst_mir(tcx, &f.literal.ty());
+ self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
+ // Don't give intrinsics the extra penalty for calls
+ INSTR_COST
+ } else {
+ CALL_PENALTY
+ };
+ if cleanup.is_some() {
+ self.cost += LANDINGPAD_PENALTY;
+ }
+ }
+ TerminatorKind::Assert { cleanup, .. } => {
+ self.cost += CALL_PENALTY;
+ if cleanup.is_some() {
+ self.cost += LANDINGPAD_PENALTY;
+ }
+ }
+ TerminatorKind::Resume => self.cost += RESUME_PENALTY,
+ TerminatorKind::InlineAsm { cleanup, .. } => {
+ self.cost += INSTR_COST;
+ if cleanup.is_some() {
+ self.cost += LANDINGPAD_PENALTY;
+ }
+ }
+ _ => self.cost += INSTR_COST,
+ }
+
+ self.super_terminator(terminator, location);
+ }
+
+ /// Count up the cost of local variables and temps, if we know the size
+ /// use that, otherwise we use a moderately-large dummy cost.
+ fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
+ let tcx = self.tcx;
+ let ptr_size = tcx.data_layout.pointer_size.bytes();
+
+ let ty = self.instance.subst_mir(tcx, &local_decl.ty);
+ // Cost of the var is the size in machine-words, if we know
+ // it.
+ if let Some(size) = type_size_of(tcx, self.param_env, ty) {
+ self.cost += ((size + ptr_size - 1) / ptr_size) as usize;
+ } else {
+ self.cost += UNKNOWN_SIZE_COST;
+ }
+
+ self.super_local_decl(local, local_decl)
+ }
+
+ /// This method duplicates code from MIR validation in an attempt to detect type mismatches due
+ /// to normalization failure.
+ fn visit_projection_elem(
+ &mut self,
+ local: Local,
+ proj_base: &[PlaceElem<'tcx>],
+ elem: PlaceElem<'tcx>,
+ context: PlaceContext,
+ location: Location,
+ ) {
+ 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.callee_body.local_decls, self.tcx);
+ let check_equal = |this: &mut Self, f_ty| {
+ if !equal_up_to_regions(this.tcx, this.param_env, ty, f_ty) {
+ trace!(?ty, ?f_ty);
+ this.validation = Err("failed to normalize projection type");
+ return;
+ }
+ };
+
+ let kind = match parent_ty.ty.kind() {
+ &ty::Opaque(def_id, substs) => {
+ self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind()
+ }
+ kind => kind,
+ };
+
+ match kind {
+ ty::Tuple(fields) => {
+ let Some(f_ty) = fields.get(f.as_usize()) else {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+ check_equal(self, *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 {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+ check_equal(self, 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 {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+ check_equal(self, f_ty);
+ }
+ &ty::Generator(def_id, substs, _) => {
+ let f_ty = if let Some(var) = parent_ty.variant_index {
+ let gen_body = if def_id == self.callee_body.source.def_id() {
+ self.callee_body
+ } else {
+ self.tcx.optimized_mir(def_id)
+ };
+
+ let Some(layout) = gen_body.generator_layout() else {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+
+ let Some(&local) = layout.variant_fields[var].get(f) else {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+
+ let Some(&f_ty) = layout.field_tys.get(local) else {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+
+ f_ty
+ } else {
+ let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
+ self.validation = Err("malformed MIR");
+ return;
+ };
+
+ f_ty
+ };
+
+ check_equal(self, f_ty);
+ }
+ _ => self.validation = Err("malformed MIR"),
+ }
+ }
+
+ self.super_projection_elem(local, proj_base, elem, context, location);
+ }
+}
+
/**
* Integrator.
*
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 7810218fd..b027f9492 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -153,7 +153,7 @@ pub(crate) fn mir_inliner_callees<'tcx>(
_ => tcx.instance_mir(instance),
};
let mut calls = FxIndexSet::default();
- for bb_data in body.basic_blocks() {
+ for bb_data in body.basic_blocks.iter() {
let terminator = bb_data.terminator();
if let TerminatorKind::Call { func, .. } = &terminator.kind {
let ty = func.ty(&body.local_decls, tcx);
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d968a4885..e6fc85595 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -1,7 +1,7 @@
#![allow(rustc::potential_query_instability)]
#![feature(box_patterns)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(never_type)]
@@ -10,6 +10,7 @@
#![feature(trusted_step)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
+#![feature(if_let_guard)]
#![recursion_limit = "256"]
#[macro_use]
@@ -26,10 +27,14 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_index::vec::IndexVec;
use rustc_middle::mir::visit::Visitor as _;
-use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPass, MirPhase, Promoted};
+use rustc_middle::mir::{
+ traversal, AnalysisPhase, Body, ConstQualifs, Constant, LocalDecl, MirPass, MirPhase, Operand,
+ Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, Statement, StatementKind,
+ TerminatorKind,
+};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
-use rustc_span::{Span, Symbol};
+use rustc_span::sym;
#[macro_use]
mod pass_manager;
@@ -139,6 +144,64 @@ pub fn provide(providers: &mut Providers) {
};
}
+fn remap_mir_for_const_eval_select<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ mut body: Body<'tcx>,
+ context: hir::Constness,
+) -> Body<'tcx> {
+ for bb in body.basic_blocks.as_mut().iter_mut() {
+ let terminator = bb.terminator.as_mut().expect("invalid terminator");
+ match terminator.kind {
+ TerminatorKind::Call {
+ func: Operand::Constant(box Constant { ref literal, .. }),
+ ref mut args,
+ destination,
+ target,
+ cleanup,
+ fn_span,
+ ..
+ } if let ty::FnDef(def_id, _) = *literal.ty().kind()
+ && tcx.item_name(def_id) == sym::const_eval_select
+ && tcx.is_intrinsic(def_id) =>
+ {
+ let [tupled_args, called_in_const, called_at_rt]: [_; 3] = std::mem::take(args).try_into().unwrap();
+ let ty = tupled_args.ty(&body.local_decls, tcx);
+ let fields = ty.tuple_fields();
+ let num_args = fields.len();
+ let func = if context == hir::Constness::Const { called_in_const } else { called_at_rt };
+ let (method, place): (fn(Place<'tcx>) -> Operand<'tcx>, Place<'tcx>) = match tupled_args {
+ Operand::Constant(_) => {
+ // there is no good way of extracting a tuple arg from a constant (const generic stuff)
+ // so we just create a temporary and deconstruct that.
+ let local = body.local_decls.push(LocalDecl::new(ty, fn_span));
+ bb.statements.push(Statement {
+ source_info: SourceInfo::outermost(fn_span),
+ kind: StatementKind::Assign(Box::new((local.into(), Rvalue::Use(tupled_args.clone())))),
+ });
+ (Operand::Move, local.into())
+ }
+ Operand::Move(place) => (Operand::Move, place),
+ Operand::Copy(place) => (Operand::Copy, place),
+ };
+ let place_elems = place.projection;
+ let arguments = (0..num_args).map(|x| {
+ let mut place_elems = place_elems.to_vec();
+ place_elems.push(ProjectionElem::Field(x.into(), fields[x]));
+ let projection = tcx.intern_place_elems(&place_elems);
+ let place = Place {
+ local: place.local,
+ projection,
+ };
+ method(place)
+ }).collect();
+ terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, cleanup, from_hir_call: false, fn_span };
+ }
+ _ => {}
+ }
+ }
+ body
+}
+
fn is_mir_available(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
let def_id = def_id.expect_local();
tcx.mir_keys(()).contains(&def_id)
@@ -159,14 +222,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
set: &'a mut FxIndexSet<LocalDefId>,
}
impl<'tcx> Visitor<'tcx> for GatherCtors<'_, 'tcx> {
- fn visit_variant_data(
- &mut self,
- v: &'tcx hir::VariantData<'tcx>,
- _: Symbol,
- _: &'tcx hir::Generics<'tcx>,
- _: hir::HirId,
- _: Span,
- ) {
+ fn visit_variant_data(&mut self, v: &'tcx hir::VariantData<'tcx>) {
if let hir::VariantData::Tuple(_, hir_id) = *v {
self.set.insert(self.tcx.hir().local_def_id(hir_id));
}
@@ -208,6 +264,8 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) ->
}
/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
+/// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
+/// We used to have this for pre-miri MIR based const eval.
fn mir_const<'tcx>(
tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
@@ -243,7 +301,6 @@ fn mir_const<'tcx>(
// What we need to do constant evaluation.
&simplify::SimplifyCfg::new("initial"),
&rustc_peek::SanityCheck, // Just a lint
- &marker::PhaseChange(MirPhase::Const),
],
);
tcx.alloc_steal_mir(body)
@@ -330,7 +387,9 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
.body_const_context(def.did)
.expect("mir_for_ctfe should not be used for runtime functions");
- let mut body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
+ let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
+
+ let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::Const);
match context {
// Do not const prop functions, either they get executed at runtime or exported to metadata,
@@ -349,7 +408,10 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
pm::run_passes(
tcx,
&mut body,
- &[&const_prop::ConstProp, &marker::PhaseChange(MirPhase::Optimized)],
+ &[
+ &const_prop::ConstProp,
+ &marker::PhaseChange(MirPhase::Runtime(RuntimePhase::Optimized)),
+ ],
);
}
}
@@ -389,38 +451,61 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
body.tainted_by_errors = Some(error_reported);
}
- // IMPORTANT
- pm::run_passes(tcx, &mut body, &[&remove_false_edges::RemoveFalseEdges]);
+ run_analysis_to_runtime_passes(tcx, &mut body);
+
+ tcx.alloc_steal_mir(body)
+}
+
+fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+ assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
+ let did = body.source.def_id();
+
+ debug!("analysis_mir_cleanup({:?})", did);
+ run_analysis_cleanup_passes(tcx, body);
+ assert!(body.phase == MirPhase::Analysis(AnalysisPhase::PostCleanup));
// Do a little drop elaboration before const-checking if `const_precise_live_drops` is enabled.
if check_consts::post_drop_elaboration::checking_enabled(&ConstCx::new(tcx, &body)) {
pm::run_passes(
tcx,
- &mut body,
+ body,
&[
- &simplify::SimplifyCfg::new("remove-false-edges"),
&remove_uninit_drops::RemoveUninitDrops,
+ &simplify::SimplifyCfg::new("remove-false-edges"),
],
);
check_consts::post_drop_elaboration::check_live_drops(tcx, &body); // FIXME: make this a MIR lint
}
- run_post_borrowck_cleanup_passes(tcx, &mut body);
- assert!(body.phase == MirPhase::Deaggregated);
- tcx.alloc_steal_mir(body)
+ debug!("runtime_mir_lowering({:?})", did);
+ run_runtime_lowering_passes(tcx, body);
+ assert!(body.phase == MirPhase::Runtime(RuntimePhase::Initial));
+
+ debug!("runtime_mir_cleanup({:?})", did);
+ run_runtime_cleanup_passes(tcx, body);
+ assert!(body.phase == MirPhase::Runtime(RuntimePhase::PostCleanup));
}
-/// After this series of passes, no lifetime analysis based on borrowing can be done.
-fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
- debug!("post_borrowck_cleanup({:?})", body.source.def_id());
+// FIXME(JakobDegen): Can we make these lists of passes consts?
- let post_borrowck_cleanup: &[&dyn MirPass<'tcx>] = &[
- // Remove all things only needed by analysis
+/// After this series of passes, no lifetime analysis based on borrowing can be done.
+fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+ let passes: &[&dyn MirPass<'tcx>] = &[
+ &remove_false_edges::RemoveFalseEdges,
&simplify_branches::SimplifyConstCondition::new("initial"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&cleanup_post_borrowck::CleanupNonCodegenStatements,
&simplify::SimplifyCfg::new("early-opt"),
&deref_separator::Derefer,
+ &marker::PhaseChange(MirPhase::Analysis(AnalysisPhase::PostCleanup)),
+ ];
+
+ pm::run_passes(tcx, body, passes);
+}
+
+/// Returns the sequence of passes that lowers analysis to runtime MIR.
+fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+ let passes: &[&dyn MirPass<'tcx>] = &[
// These next passes must be executed together
&add_call_guards::CriticalCallEdges,
&elaborate_drops::ElaborateDrops,
@@ -434,16 +519,27 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
// `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
// but before optimizations begin.
&elaborate_box_derefs::ElaborateBoxDerefs,
+ &generator::StateTransform,
&add_retag::AddRetag,
- &lower_intrinsics::LowerIntrinsics,
- &simplify::SimplifyCfg::new("elaborate-drops"),
- // `Deaggregator` is conceptually part of MIR building, some backends rely on it happening
- // and it can help optimizations.
+ // Deaggregator is necessary for const prop. We may want to consider implementing
+ // CTFE support for aggregates.
&deaggregator::Deaggregator,
&Lint(const_prop_lint::ConstProp),
+ &marker::PhaseChange(MirPhase::Runtime(RuntimePhase::Initial)),
+ ];
+ pm::run_passes_no_validate(tcx, body, passes);
+}
+
+/// Returns the sequence of passes that do the initial cleanup of runtime MIR.
+fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+ let passes: &[&dyn MirPass<'tcx>] = &[
+ &elaborate_box_derefs::ElaborateBoxDerefs,
+ &lower_intrinsics::LowerIntrinsics,
+ &simplify::SimplifyCfg::new("elaborate-drops"),
+ &marker::PhaseChange(MirPhase::Runtime(RuntimePhase::PostCleanup)),
];
- pm::run_passes(tcx, body, post_borrowck_cleanup);
+ pm::run_passes(tcx, body, passes);
}
fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -451,9 +547,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
WithMinOptLevel(1, x)
}
- // Lowering generator control-flow and variables has to happen before we do anything else
- // to them. We run some optimizations before that, because they may be harder to do on the state
- // machine than on MIR with async primitives.
+ // The main optimizations that we do on MIR.
pm::run_passes(
tcx,
body,
@@ -465,17 +559,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&uninhabited_enum_branching::UninhabitedEnumBranching,
&o1(simplify::SimplifyCfg::new("after-uninhabited-enum-branching")),
&inline::Inline,
- &generator::StateTransform,
- ],
- );
-
- assert!(body.phase == MirPhase::GeneratorsLowered);
-
- // The main optimizations that we do on MIR.
- pm::run_passes(
- tcx,
- body,
- &[
&remove_storage_markers::RemoveStorageMarkers,
&remove_zsts::RemoveZsts,
&const_goto::ConstGoto,
@@ -507,7 +590,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&deduplicate_blocks::DeduplicateBlocks,
// Some cleanup necessary at least for LLVM and potentially other codegen backends.
&add_call_guards::CriticalCallEdges,
- &marker::PhaseChange(MirPhase::Optimized),
+ &marker::PhaseChange(MirPhase::Runtime(RuntimePhase::Optimized)),
// Dump the end result for testing and debugging purposes.
&dump_mir::Marker("PreCodegen"),
],
@@ -539,8 +622,9 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other),
}
debug!("about to call mir_drops_elaborated...");
- let mut body =
+ let body =
tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal();
+ let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst);
debug!("body: {:#?}", body);
run_optimization_passes(tcx, &mut body);
@@ -566,7 +650,7 @@ fn promoted_mir<'tcx>(
if let Some(error_reported) = tainted_by_errors {
body.tainted_by_errors = Some(error_reported);
}
- run_post_borrowck_cleanup_passes(tcx, body);
+ run_analysis_to_runtime_passes(tcx, body);
}
debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR");
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index b7ba61651..9892580e6 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -46,12 +46,31 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
let mut args = args.drain(..);
block.statements.push(Statement {
source_info: terminator.source_info,
- kind: StatementKind::CopyNonOverlapping(Box::new(
- rustc_middle::mir::CopyNonOverlapping {
- src: args.next().unwrap(),
- dst: args.next().unwrap(),
- count: args.next().unwrap(),
- },
+ kind: StatementKind::Intrinsic(Box::new(
+ NonDivergingIntrinsic::CopyNonOverlapping(
+ rustc_middle::mir::CopyNonOverlapping {
+ src: args.next().unwrap(),
+ dst: args.next().unwrap(),
+ count: args.next().unwrap(),
+ },
+ ),
+ )),
+ });
+ assert_eq!(
+ args.next(),
+ None,
+ "Extra argument for copy_non_overlapping intrinsic"
+ );
+ drop(args);
+ terminator.kind = TerminatorKind::Goto { target };
+ }
+ sym::assume => {
+ let target = target.unwrap();
+ let mut args = args.drain(..);
+ block.statements.push(Statement {
+ source_info: terminator.source_info,
+ kind: StatementKind::Intrinsic(Box::new(
+ NonDivergingIntrinsic::Assume(args.next().unwrap()),
)),
});
assert_eq!(
diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
index 22b6dead9..3957cd92c 100644
--- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
+++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
@@ -15,7 +15,7 @@ impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// find basic blocks with no statement and a return terminator
- let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks().len());
+ let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len());
let def_id = body.source.def_id();
let bbs = body.basic_blocks_mut();
for idx in bbs.indices() {
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index c0217a105..a159e6171 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -21,10 +21,10 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// early returns for edge cases of highly unrolled functions
- if body.basic_blocks().len() > MAX_NUM_BLOCKS {
+ if body.basic_blocks.len() > MAX_NUM_BLOCKS {
return;
}
- if body.local_decls().len() > MAX_NUM_LOCALS {
+ if body.local_decls.len() > MAX_NUM_LOCALS {
return;
}
normalize_array_len_calls(tcx, body)
diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs
index bb063915f..4291e81c7 100644
--- a/compiler/rustc_mir_transform/src/nrvo.rs
+++ b/compiler/rustc_mir_transform/src/nrvo.rs
@@ -53,10 +53,10 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
def_id, returned_local
);
- RenameToReturnPlace { tcx, to_rename: returned_local }.visit_body(body);
+ RenameToReturnPlace { tcx, to_rename: returned_local }.visit_body_preserves_cfg(body);
// Clean up the `NOP`s we inserted for statements made useless by our renaming.
- for block_data in body.basic_blocks_mut() {
+ for block_data in body.basic_blocks.as_mut_preserves_cfg() {
block_data.statements.retain(|stmt| stmt.kind != mir::StatementKind::Nop);
}
@@ -89,7 +89,7 @@ fn local_eligible_for_nrvo(body: &mut mir::Body<'_>) -> Option<Local> {
}
let mut copied_to_return_place = None;
- for block in body.basic_blocks().indices() {
+ for block in body.basic_blocks.indices() {
// Look for blocks with a `Return` terminator.
if !matches!(body[block].terminator().kind, mir::TerminatorKind::Return) {
continue;
@@ -122,7 +122,7 @@ fn find_local_assigned_to_return_place(
body: &mut mir::Body<'_>,
) -> Option<Local> {
let mut block = start;
- let mut seen = HybridBitSet::new_empty(body.basic_blocks().len());
+ let mut seen = HybridBitSet::new_empty(body.basic_blocks.len());
// Iterate as long as `block` has exactly one predecessor that we have not yet visited.
while seen.insert(block) {
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index e27d4ab16..67dae7146 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -1,6 +1,6 @@
use std::borrow::Cow;
-use rustc_middle::mir::{self, Body, MirPhase};
+use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
@@ -72,48 +72,62 @@ where
}
}
+/// Run the sequence of passes without validating the MIR after each pass. The MIR is still
+/// validated at the end.
+pub fn run_passes_no_validate<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ body: &mut Body<'tcx>,
+ passes: &[&dyn MirPass<'tcx>],
+) {
+ run_passes_inner(tcx, body, passes, false);
+}
+
pub fn run_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, passes: &[&dyn MirPass<'tcx>]) {
+ run_passes_inner(tcx, body, passes, true);
+}
+
+fn run_passes_inner<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ body: &mut Body<'tcx>,
+ passes: &[&dyn MirPass<'tcx>],
+ validate_each: bool,
+) {
let start_phase = body.phase;
let mut cnt = 0;
- let validate = tcx.sess.opts.unstable_opts.validate_mir;
+ let validate = validate_each & tcx.sess.opts.unstable_opts.validate_mir;
let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
trace!(?overridden_passes);
- if validate {
- validate_body(tcx, body, format!("start of phase transition from {:?}", start_phase));
- }
-
for pass in passes {
let name = pass.name();
- if let Some((_, polarity)) = overridden_passes.iter().rev().find(|(s, _)| s == &*name) {
- trace!(
- pass = %name,
- "{} as requested by flag",
- if *polarity { "Running" } else { "Not running" },
- );
- if !polarity {
- continue;
- }
- } else {
- if !pass.is_enabled(&tcx.sess) {
- continue;
- }
- }
- let dump_enabled = pass.is_mir_dump_enabled();
+ // Gather information about what we should be doing for this pass
+ let overridden =
+ overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(|(_name, polarity)| {
+ trace!(
+ pass = %name,
+ "{} as requested by flag",
+ if *polarity { "Running" } else { "Not running" },
+ );
+ *polarity
+ });
+ let is_enabled = overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess));
+ let new_phase = pass.phase_change();
+ let dump_enabled = (is_enabled && pass.is_mir_dump_enabled()) || new_phase.is_some();
+ let validate = (validate && is_enabled)
+ || new_phase == Some(MirPhase::Runtime(RuntimePhase::Optimized));
if dump_enabled {
dump_mir(tcx, body, start_phase, &name, cnt, false);
}
-
- pass.run_pass(tcx, body);
-
+ if is_enabled {
+ pass.run_pass(tcx, body);
+ }
if dump_enabled {
dump_mir(tcx, body, start_phase, &name, cnt, true);
cnt += 1;
}
-
if let Some(new_phase) = pass.phase_change() {
if body.phase >= new_phase {
panic!("Invalid MIR phase transition from {:?} to {:?}", body.phase, new_phase);
@@ -121,15 +135,10 @@ pub fn run_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, passes: &[&dyn
body.phase = new_phase;
}
-
if validate {
- validate_body(tcx, body, format!("after pass {}", pass.name()));
+ validate_body(tcx, body, format!("after pass {}", name));
}
}
-
- if validate || body.phase == MirPhase::Optimized {
- validate_body(tcx, body, format!("end of phase transition to {:?}", body.phase));
- }
}
pub fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) {
@@ -144,7 +153,7 @@ pub fn dump_mir<'tcx>(
cnt: usize,
is_after: bool,
) {
- let phase_index = phase as u32;
+ let phase_index = phase.phase_index();
mir::dump_mir(
tcx,
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 5c441c5b1..f1bbf2ea7 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -51,7 +51,7 @@ impl RemoveNoopLandingPads {
StatementKind::Assign { .. }
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(..)
- | StatementKind::CopyNonOverlapping(..)
+ | StatementKind::Intrinsic(..)
| StatementKind::Retag { .. } => {
return false;
}
@@ -94,7 +94,7 @@ impl RemoveNoopLandingPads {
let mut jumps_folded = 0;
let mut landing_pads_removed = 0;
- let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks().len());
+ let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks.len());
// This is a post-order traversal, so that if A post-dominates B
// then A will be visited before B.
diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
index 96b715402..78b6f714a 100644
--- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
@@ -35,7 +35,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
.into_results_cursor(body);
let mut to_remove = vec![];
- for (bb, block) in body.basic_blocks().iter_enumerated() {
+ for (bb, block) in body.basic_blocks.iter_enumerated() {
let terminator = block.terminator();
let (TerminatorKind::Drop { place, .. } | TerminatorKind::DropAndReplace { place, .. })
= &terminator.kind
diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs
index 827ce0c02..cc75947d9 100644
--- a/compiler/rustc_mir_transform/src/required_consts.rs
+++ b/compiler/rustc_mir_transform/src/required_consts.rs
@@ -1,5 +1,5 @@
use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{Constant, Location};
+use rustc_middle::mir::{Constant, ConstantKind, Location};
use rustc_middle::ty::ConstKind;
pub struct RequiredConstsVisitor<'a, 'tcx> {
@@ -15,8 +15,13 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
let literal = constant.literal;
- if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.kind() {
- self.required_consts.push(*constant);
+ match literal {
+ ConstantKind::Ty(c) => match c.kind() {
+ ConstKind::Param(_) => {}
+ _ => bug!("only ConstKind::Param should be encountered here, got {:#?}", c),
+ },
+ ConstantKind::Unevaluated(..) => self.required_consts.push(*constant),
+ ConstantKind::Val(..) => {}
}
}
}
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs
index 4919ad400..abe6cb285 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/reveal_all.rs
@@ -19,7 +19,7 @@ impl<'tcx> MirPass<'tcx> for RevealAll {
}
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
- RevealAllVisitor { tcx, param_env }.visit_body(body);
+ RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
}
}
diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs
index 925eb10a1..2f116aaa9 100644
--- a/compiler/rustc_mir_transform/src/separate_const_switch.rs
+++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs
@@ -62,7 +62,7 @@ impl<'tcx> MirPass<'tcx> for SeparateConstSwitch {
pub fn separate_const_switch(body: &mut Body<'_>) -> usize {
let mut new_blocks: SmallVec<[(BasicBlock, BasicBlock); 6]> = SmallVec::new();
let predecessors = body.basic_blocks.predecessors();
- 'block_iter: for (block_id, block) in body.basic_blocks().iter_enumerated() {
+ 'block_iter: for (block_id, block) in body.basic_blocks.iter_enumerated() {
if let TerminatorKind::SwitchInt {
discr: Operand::Copy(switch_place) | Operand::Move(switch_place),
..
@@ -90,7 +90,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize {
let mut predecessors_left = predecessors[block_id].len();
'predec_iter: for predecessor_id in predecessors[block_id].iter().copied() {
- let predecessor = &body.basic_blocks()[predecessor_id];
+ let predecessor = &body.basic_blocks[predecessor_id];
// First we make sure the predecessor jumps
// in a reasonable way
@@ -249,7 +249,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
| StatementKind::AscribeUserType(_, _)
| StatementKind::Coverage(_)
| StatementKind::StorageDead(_)
- | StatementKind::CopyNonOverlapping(_)
+ | StatementKind::Intrinsic(_)
| StatementKind::Nop => {}
}
}
@@ -317,7 +317,7 @@ fn find_determining_place<'tcx>(
| StatementKind::Retag(_, _)
| StatementKind::AscribeUserType(_, _)
| StatementKind::Coverage(_)
- | StatementKind::CopyNonOverlapping(_)
+ | StatementKind::Intrinsic(_)
| StatementKind::Nop => {}
// If the discriminant is set, it is always set
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 3620e94be..882136200 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -4,7 +4,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_middle::mir::*;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{InternalSubsts, Subst};
-use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
+use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt};
use rustc_target::abi::VariantIdx;
use rustc_index::vec::{Idx, IndexVec};
@@ -17,8 +17,8 @@ use std::iter;
use crate::util::expand_aggregate;
use crate::{
- abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, marker, pass_manager as pm,
- remove_noop_landing_pads, simplify,
+ abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator, marker,
+ pass_manager as pm, remove_noop_landing_pads, simplify,
};
use rustc_middle::mir::patch::MirPatch;
use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
@@ -92,11 +92,12 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
&mut result,
&[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
+ &deref_separator::Derefer,
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("make_shim"),
&add_call_guards::CriticalCallEdges,
&abort_unwinding_calls::AbortUnwindingCalls,
- &marker::PhaseChange(MirPhase::Const),
+ &marker::PhaseChange(MirPhase::Runtime(RuntimePhase::Optimized)),
],
);
@@ -322,6 +323,9 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
builder.tuple_like_shim(dest, src, substs.as_closure().upvar_tys())
}
ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
+ ty::Generator(gen_def_id, substs, hir::Movability::Movable) => {
+ builder.generator_shim(dest, src, *gen_def_id, substs.as_generator())
+ }
_ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty),
};
@@ -387,7 +391,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
/// offset=0 will give you the index of the next BasicBlock,
/// offset=1 will give the index of the next-to-next block,
/// offset=-1 will give you the index of the last-created block
- fn block_index_offset(&mut self, offset: usize) -> BasicBlock {
+ fn block_index_offset(&self, offset: usize) -> BasicBlock {
BasicBlock::new(self.blocks.len() + offset)
}
@@ -460,49 +464,106 @@ impl<'tcx> CloneShimBuilder<'tcx> {
);
}
- fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>, src: Place<'tcx>, tys: I)
+ fn clone_fields<I>(
+ &mut self,
+ dest: Place<'tcx>,
+ src: Place<'tcx>,
+ target: BasicBlock,
+ mut unwind: BasicBlock,
+ tys: I,
+ ) -> BasicBlock
where
I: IntoIterator<Item = Ty<'tcx>>,
{
- let mut previous_field = None;
+ // For an iterator of length n, create 2*n + 1 blocks.
for (i, ity) in tys.into_iter().enumerate() {
+ // Each iteration creates two blocks, referred to here as block 2*i and block 2*i + 1.
+ //
+ // Block 2*i attempts to clone the field. If successful it branches to 2*i + 2 (the
+ // next clone block). If unsuccessful it branches to the previous unwind block, which
+ // is initially the `unwind` argument passed to this function.
+ //
+ // Block 2*i + 1 is the unwind block for this iteration. It drops the cloned value
+ // created by block 2*i. We store this block in `unwind` so that the next clone block
+ // will unwind to it if cloning fails.
+
let field = Field::new(i);
let src_field = self.tcx.mk_place_field(src, field, ity);
let dest_field = self.tcx.mk_place_field(dest, field, ity);
- // #(2i + 1) is the cleanup block for the previous clone operation
- let cleanup_block = self.block_index_offset(1);
- // #(2i + 2) is the next cloning block
- // (or the Return terminator if this is the last block)
+ let next_unwind = self.block_index_offset(1);
let next_block = self.block_index_offset(2);
+ self.make_clone_call(dest_field, src_field, ity, next_block, unwind);
+ self.block(
+ vec![],
+ TerminatorKind::Drop { place: dest_field, target: unwind, unwind: None },
+ true,
+ );
+ unwind = next_unwind;
+ }
+ // If all clones succeed then we end up here.
+ self.block(vec![], TerminatorKind::Goto { target }, false);
+ unwind
+ }
- // BB #(2i)
- // `dest.i = Clone::clone(&src.i);`
- // Goto #(2i + 2) if ok, #(2i + 1) if unwinding happens.
- self.make_clone_call(dest_field, src_field, ity, next_block, cleanup_block);
-
- // BB #(2i + 1) (cleanup)
- if let Some((previous_field, previous_cleanup)) = previous_field.take() {
- // Drop previous field and goto previous cleanup block.
- self.block(
- vec![],
- TerminatorKind::Drop {
- place: previous_field,
- target: previous_cleanup,
- unwind: None,
- },
- true,
- );
- } else {
- // Nothing to drop, just resume.
- self.block(vec![], TerminatorKind::Resume, true);
- }
+ fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>, src: Place<'tcx>, tys: I)
+ where
+ I: IntoIterator<Item = Ty<'tcx>>,
+ {
+ self.block(vec![], TerminatorKind::Goto { target: self.block_index_offset(3) }, false);
+ let unwind = self.block(vec![], TerminatorKind::Resume, true);
+ let target = self.block(vec![], TerminatorKind::Return, false);
- previous_field = Some((dest_field, cleanup_block));
- }
+ let _final_cleanup_block = self.clone_fields(dest, src, target, unwind, tys);
+ }
- self.block(vec![], TerminatorKind::Return, false);
+ fn generator_shim(
+ &mut self,
+ dest: Place<'tcx>,
+ src: Place<'tcx>,
+ gen_def_id: DefId,
+ substs: GeneratorSubsts<'tcx>,
+ ) {
+ self.block(vec![], TerminatorKind::Goto { target: self.block_index_offset(3) }, false);
+ let unwind = self.block(vec![], TerminatorKind::Resume, true);
+ // This will get overwritten with a switch once we know the target blocks
+ let switch = self.block(vec![], TerminatorKind::Unreachable, false);
+ let unwind = self.clone_fields(dest, src, switch, unwind, substs.upvar_tys());
+ let target = self.block(vec![], TerminatorKind::Return, false);
+ let unreachable = self.block(vec![], TerminatorKind::Unreachable, false);
+ let mut cases = Vec::with_capacity(substs.state_tys(gen_def_id, self.tcx).count());
+ for (index, state_tys) in substs.state_tys(gen_def_id, self.tcx).enumerate() {
+ let variant_index = VariantIdx::new(index);
+ let dest = self.tcx.mk_place_downcast_unnamed(dest, variant_index);
+ let src = self.tcx.mk_place_downcast_unnamed(src, variant_index);
+ let clone_block = self.block_index_offset(1);
+ let start_block = self.block(
+ vec![self.make_statement(StatementKind::SetDiscriminant {
+ place: Box::new(Place::return_place()),
+ variant_index,
+ })],
+ TerminatorKind::Goto { target: clone_block },
+ false,
+ );
+ cases.push((index as u128, start_block));
+ let _final_cleanup_block = self.clone_fields(dest, src, target, unwind, state_tys);
+ }
+ let discr_ty = substs.discr_ty(self.tcx);
+ let temp = self.make_place(Mutability::Mut, discr_ty);
+ let rvalue = Rvalue::Discriminant(src);
+ let statement = self.make_statement(StatementKind::Assign(Box::new((temp, rvalue))));
+ match &mut self.blocks[switch] {
+ BasicBlockData { statements, terminator: Some(Terminator { kind, .. }), .. } => {
+ statements.push(statement);
+ *kind = TerminatorKind::SwitchInt {
+ discr: Operand::Move(temp),
+ switch_ty: discr_ty,
+ targets: SwitchTargets::new(cases.into_iter(), unreachable),
+ };
+ }
+ BasicBlockData { terminator: None, .. } => unreachable!(),
+ }
}
}
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 180f4c7dc..57d372fda 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -74,7 +74,7 @@ pub struct CfgSimplifier<'a, 'tcx> {
impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
pub fn new(body: &'a mut Body<'tcx>) -> Self {
- let mut pred_count = IndexVec::from_elem(0u32, body.basic_blocks());
+ let mut pred_count = IndexVec::from_elem(0u32, &body.basic_blocks);
// we can't use mir.predecessors() here because that counts
// dead blocks, which we don't want to.
@@ -263,7 +263,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let reachable = traversal::reachable_as_bitset(body);
- let num_blocks = body.basic_blocks().len();
+ let num_blocks = body.basic_blocks.len();
if num_blocks == reachable.count() {
return;
}
@@ -412,7 +412,7 @@ pub fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
if map.iter().any(Option::is_none) {
// Update references to all vars and tmps now
let mut updater = LocalUpdater { map, tcx };
- updater.visit_body(body);
+ updater.visit_body_preserves_cfg(body);
body.local_decls.shrink_to_fit();
}
@@ -499,7 +499,7 @@ impl UsedLocals {
impl<'tcx> Visitor<'tcx> for UsedLocals {
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
match statement.kind {
- StatementKind::CopyNonOverlapping(..)
+ StatementKind::Intrinsic(..)
| StatementKind::Retag(..)
| StatementKind::Coverage(..)
| StatementKind::FakeRead(..)
@@ -548,7 +548,7 @@ fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>)
while modified {
modified = false;
- for data in body.basic_blocks_mut() {
+ for data in body.basic_blocks.as_mut_preserves_cfg() {
// Remove unnecessary StorageLive and StorageDead annotations.
data.statements.retain(|statement| {
let keep = match &statement.kind {
diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
index bbfaace70..321d8c63b 100644
--- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
@@ -151,7 +151,7 @@ struct OptimizationFinder<'a, 'tcx> {
impl<'tcx> OptimizationFinder<'_, 'tcx> {
fn find_optimizations(&self) -> Vec<OptimizationInfo<'tcx>> {
self.body
- .basic_blocks()
+ .basic_blocks
.iter_enumerated()
.filter_map(|(bb_idx, bb)| {
// find switch
diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs
index d52f1261b..baeb620ef 100644
--- a/compiler/rustc_mir_transform/src/simplify_try.rs
+++ b/compiler/rustc_mir_transform/src/simplify_try.rs
@@ -596,7 +596,7 @@ struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
fn find(&self) -> Vec<SimplifyBranchSameOptimization> {
self.body
- .basic_blocks()
+ .basic_blocks
.iter_enumerated()
.filter_map(|(bb_idx, bb)| {
let (discr_switched_on, targets_and_values) = match &bb.terminator().kind {
@@ -632,7 +632,7 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
let mut iter_bbs_reachable = targets_and_values
.iter()
- .map(|target_and_value| (target_and_value, &self.body.basic_blocks()[target_and_value.target]))
+ .map(|target_and_value| (target_and_value, &self.body.basic_blocks[target_and_value.target]))
.filter(|(_, bb)| {
// Reaching `unreachable` is UB so assume it doesn't happen.
bb.terminator().kind != TerminatorKind::Unreachable
diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
index 30be64f5b..96ea15f1b 100644
--- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
@@ -79,7 +79,7 @@ fn ensure_otherwise_unreachable<'tcx>(
targets: &SwitchTargets,
) -> Option<BasicBlockData<'tcx>> {
let otherwise = targets.otherwise();
- let bb = &body.basic_blocks()[otherwise];
+ let bb = &body.basic_blocks[otherwise];
if bb.terminator().kind == TerminatorKind::Unreachable
&& bb.statements.iter().all(|s| matches!(&s.kind, StatementKind::StorageDead(_)))
{
@@ -102,10 +102,10 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
trace!("UninhabitedEnumBranching starting for {:?}", body.source);
- for bb in body.basic_blocks().indices() {
+ for bb in body.basic_blocks.indices() {
trace!("processing block {:?}", bb);
- let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) else {
+ let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks[bb], tcx, body) else {
continue;
};
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index f916ca362..95fda2eaf 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -12,9 +12,8 @@ pub struct UnreachablePropagation;
impl MirPass<'_> for UnreachablePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
- // Enable only under -Zmir-opt-level=4 as in some cases (check the deeply-nested-opt
- // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code.
- sess.mir_opt_level() >= 4
+ // Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
+ sess.mir_opt_level() >= 2
}
fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -38,7 +37,19 @@ impl MirPass<'_> for UnreachablePropagation {
}
}
+ // We do want do keep some unreachable blocks, but make them empty.
+ for bb in unreachable_blocks {
+ if !tcx.consider_optimizing(|| {
+ format!("UnreachablePropagation {:?} ", body.source.def_id())
+ }) {
+ break;
+ }
+
+ body.basic_blocks_mut()[bb].statements.clear();
+ }
+
let replaced = !replacements.is_empty();
+
for (bb, terminator_kind) in replacements {
if !tcx.consider_optimizing(|| {
format!("UnreachablePropagation {:?} ", body.source.def_id())
@@ -57,42 +68,55 @@ impl MirPass<'_> for UnreachablePropagation {
fn remove_successors<'tcx, F>(
terminator_kind: &TerminatorKind<'tcx>,
- predicate: F,
+ is_unreachable: F,
) -> Option<TerminatorKind<'tcx>>
where
F: Fn(BasicBlock) -> bool,
{
- let terminator = match *terminator_kind {
- TerminatorKind::Goto { target } if predicate(target) => TerminatorKind::Unreachable,
- TerminatorKind::SwitchInt { ref discr, switch_ty, ref targets } => {
+ let terminator = match terminator_kind {
+ // This will unconditionally run into an unreachable and is therefore unreachable as well.
+ TerminatorKind::Goto { target } if is_unreachable(*target) => TerminatorKind::Unreachable,
+ TerminatorKind::SwitchInt { targets, discr, switch_ty } => {
let otherwise = targets.otherwise();
- let original_targets_len = targets.iter().len() + 1;
- let (mut values, mut targets): (Vec<_>, Vec<_>) =
- targets.iter().filter(|(_, bb)| !predicate(*bb)).unzip();
+ // If all targets are unreachable, we can be unreachable as well.
+ if targets.all_targets().iter().all(|bb| is_unreachable(*bb)) {
+ TerminatorKind::Unreachable
+ } else if is_unreachable(otherwise) {
+ // If there are multiple targets, don't delete unreachable branches (like an unreachable otherwise)
+ // unless otherwise is unreachable, in which case deleting a normal branch causes it to be merged with
+ // the otherwise, keeping its unreachable.
+ // This looses information about reachability causing worse codegen.
+ // For example (see src/test/codegen/match-optimizes-away.rs)
+ //
+ // pub enum Two { A, B }
+ // pub fn identity(x: Two) -> Two {
+ // match x {
+ // Two::A => Two::A,
+ // Two::B => Two::B,
+ // }
+ // }
+ //
+ // This generates a `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]`, which allows us or LLVM to
+ // turn it into just `x` later. Without the unreachable, such a transformation would be illegal.
+ // If the otherwise branch is unreachable, we can delete all other unreacahble targets, as they will
+ // still point to the unreachable and therefore not lose reachability information.
+ let reachable_iter = targets.iter().filter(|(_, bb)| !is_unreachable(*bb));
- if !predicate(otherwise) {
- targets.push(otherwise);
- } else {
- values.pop();
- }
+ let new_targets = SwitchTargets::new(reachable_iter, otherwise);
- let retained_targets_len = targets.len();
+ // No unreachable branches were removed.
+ if new_targets.all_targets().len() == targets.all_targets().len() {
+ return None;
+ }
- if targets.is_empty() {
- TerminatorKind::Unreachable
- } else if targets.len() == 1 {
- TerminatorKind::Goto { target: targets[0] }
- } else if original_targets_len != retained_targets_len {
TerminatorKind::SwitchInt {
discr: discr.clone(),
- switch_ty,
- targets: SwitchTargets::new(
- values.iter().copied().zip(targets.iter().copied()),
- *targets.last().unwrap(),
- ),
+ switch_ty: *switch_ty,
+ targets: new_targets,
}
} else {
+ // If the otherwise branch is reachable, we don't want to delete any unreachable branches.
return None;
}
}
diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml
index 41ba4d4b6..59ca04ec8 100644
--- a/compiler/rustc_monomorphize/Cargo.toml
+++ b/compiler/rustc_monomorphize/Cargo.toml
@@ -7,11 +7,13 @@ edition = "2021"
doctest = false
[dependencies]
-smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = [ "union", "may_dangle" ] }
tracing = "0.1"
rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 68b65658c..f1a25a60d 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -112,12 +112,6 @@
//! method in operand position, we treat it as a neighbor of the current
//! mono item. Calls are just a special case of that.
//!
-//! #### Closures
-//! In a way, closures are a simple case. Since every closure object needs to be
-//! constructed somewhere, we can reliably discover them by observing
-//! `RValue::Aggregate` expressions with `AggregateKind::Closure`. This is also
-//! true for closures inlined from other crates.
-//!
//! #### Drop glue
//! Drop glue mono items are introduced by MIR drop-statements. The
//! generated mono item will again have drop-glue item neighbors if the
@@ -128,7 +122,7 @@
//! #### Unsizing Casts
//! A subtle way of introducing neighbor edges is by casting to a trait object.
//! Since the resulting fat-pointer contains a reference to a vtable, we need to
-//! instantiate all object-save methods of the trait, as we need to store
+//! instantiate all object-safe methods of the trait, as we need to store
//! pointers to these functions even if they never get called anywhere. This can
//! be seen as a special case of taking a function reference.
//!
@@ -207,6 +201,8 @@ use std::iter;
use std::ops::Range;
use std::path::PathBuf;
+use crate::errors::{LargeAssignmentsLint, RecursionLimit, RequiresLangItem, TypeLengthLimit};
+
#[derive(PartialEq)]
pub enum MonoItemCollectionMode {
Eager,
@@ -417,7 +413,6 @@ fn collect_items_rec<'tcx>(
// We've been here already, no need to search again.
return;
}
- debug!("BEGIN collect_items_rec({})", starting_point.node);
let mut neighbors = MonoItems { compute_inlining: true, tcx, items: Vec::new() };
let recursion_depth_reset;
@@ -461,7 +456,7 @@ fn collect_items_rec<'tcx>(
recursion_depth_reset = None;
if let Ok(alloc) = tcx.eval_static_initializer(def_id) {
- for &id in alloc.inner().relocations().values() {
+ for &id in alloc.inner().provenance().values() {
collect_miri(tcx, id, &mut neighbors);
}
}
@@ -543,8 +538,6 @@ fn collect_items_rec<'tcx>(
if let Some((def_id, depth)) = recursion_depth_reset {
recursion_depths.insert(def_id, depth);
}
-
- debug!("END collect_items_rec({})", starting_point.node);
}
/// Format instance name that is already known to be too long for rustc.
@@ -604,17 +597,24 @@ fn check_recursion_limit<'tcx>(
// more than the recursion limit is assumed to be causing an
// infinite expansion.
if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
+ let def_span = tcx.def_span(def_id);
+ let def_path_str = tcx.def_path_str(def_id);
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
- let error = format!("reached the recursion limit while instantiating `{}`", shrunk);
- let mut err = tcx.sess.struct_span_fatal(span, &error);
- err.span_note(
- tcx.def_span(def_id),
- &format!("`{}` defined here", tcx.def_path_str(def_id)),
- );
- if let Some(path) = written_to_path {
- err.note(&format!("the full type name has been written to '{}'", path.display()));
- }
- err.emit()
+ let mut path = PathBuf::new();
+ let was_written = if written_to_path.is_some() {
+ path = written_to_path.unwrap();
+ Some(())
+ } else {
+ None
+ };
+ tcx.sess.emit_fatal(RecursionLimit {
+ span,
+ shrunk,
+ def_span,
+ def_path_str,
+ was_written,
+ path,
+ });
}
recursion_depths.insert(def_id, recursion_depth + 1);
@@ -642,16 +642,15 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
// Bail out in these cases to avoid that bad user experience.
if !tcx.type_length_limit().value_within_limit(type_length) {
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
- let msg = format!("reached the type-length limit while instantiating `{}`", shrunk);
- let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
- if let Some(path) = written_to_path {
- diag.note(&format!("the full type name has been written to '{}'", path.display()));
- }
- diag.help(&format!(
- "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
- type_length
- ));
- diag.emit()
+ let span = tcx.def_span(instance.def_id());
+ let mut path = PathBuf::new();
+ let was_written = if written_to_path.is_some() {
+ path = written_to_path.unwrap();
+ Some(())
+ } else {
+ None
+ };
+ tcx.sess.emit_fatal(TypeLengthLimit { span, shrunk, was_written, path, type_length });
}
}
@@ -690,7 +689,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
mir::CastKind::Pointer(PointerCast::Unsize),
ref operand,
target_ty,
- ) => {
+ )
+ | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
let target_ty = self.monomorphize(target_ty);
let source_ty = operand.ty(self.body, self.tcx);
let source_ty = self.monomorphize(source_ty);
@@ -699,7 +699,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
// This could also be a different Unsize instruction, like
// from a fixed sized array to a slice. But we are only
// interested in things that produce a vtable.
- if target_ty.is_trait() && !source_ty.is_trait() {
+ if (target_ty.is_trait() && !source_ty.is_trait())
+ || (target_ty.is_dyn_star() && !source_ty.is_dyn_star())
+ {
create_mono_items_for_vtable_methods(
self.tcx,
target_ty,
@@ -768,7 +770,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
ty::ConstKind::Unevaluated(ct) => {
debug!(?ct);
let param_env = ty::ParamEnv::reveal_all();
- match self.tcx.const_eval_resolve(param_env, ct, None) {
+ match self.tcx.const_eval_resolve(param_env, ct.expand(), None) {
// The `monomorphize` call should have evaluated that constant already.
Ok(val) => val,
Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return,
@@ -781,44 +783,22 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
}
_ => return,
},
- };
- collect_const_value(self.tcx, val, self.output);
- self.visit_ty(literal.ty(), TyContext::Location(location));
- }
-
- #[instrument(skip(self), level = "debug")]
- fn visit_const(&mut self, constant: ty::Const<'tcx>, location: Location) {
- debug!("visiting const {:?} @ {:?}", constant, location);
-
- let substituted_constant = self.monomorphize(constant);
- let param_env = ty::ParamEnv::reveal_all();
-
- match substituted_constant.kind() {
- ty::ConstKind::Value(val) => {
- let const_val = self.tcx.valtree_to_const_val((constant.ty(), val));
- collect_const_value(self.tcx, const_val, self.output)
- }
- ty::ConstKind::Unevaluated(unevaluated) => {
- match self.tcx.const_eval_resolve(param_env, unevaluated, None) {
+ mir::ConstantKind::Unevaluated(uv, _) => {
+ let param_env = ty::ParamEnv::reveal_all();
+ match self.tcx.const_eval_resolve(param_env, uv, None) {
// The `monomorphize` call should have evaluated that constant already.
- Ok(val) => span_bug!(
- self.body.source_info(location).span,
- "collection encountered the unevaluated constant {} which evaluated to {:?}",
- substituted_constant,
- val
- ),
- Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => {}
+ Ok(val) => val,
+ Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return,
Err(ErrorHandled::TooGeneric) => span_bug!(
self.body.source_info(location).span,
- "collection encountered polymorphic constant: {}",
- substituted_constant
+ "collection encountered polymorphic constant: {:?}",
+ literal
),
}
}
- _ => {}
- }
-
- self.super_const(constant);
+ };
+ collect_const_value(self.tcx, val, self.output);
+ MirVisitor::visit_ty(self, literal.ty(), TyContext::Location(location));
}
fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
@@ -830,7 +810,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
mir::TerminatorKind::Call { ref func, .. } => {
let callee_ty = func.ty(self.body, tcx);
let callee_ty = self.monomorphize(callee_ty);
- visit_fn_use(self.tcx, callee_ty, true, source, &mut self.output);
+ visit_fn_use(self.tcx, callee_ty, true, source, &mut self.output)
}
mir::TerminatorKind::Drop { ref place, .. }
| mir::TerminatorKind::DropAndReplace { ref place, .. } => {
@@ -914,17 +894,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
// but correct span? This would make the lint at least accept crate-level lint attributes.
return;
};
- self.tcx.struct_span_lint_hir(
+ self.tcx.emit_spanned_lint(
LARGE_ASSIGNMENTS,
lint_root,
source_info.span,
- |lint| {
- let mut err = lint.build(&format!("moving {} bytes", layout.size.bytes()));
- err.span_label(source_info.span, "value moved from here");
- err.note(&format!(r#"The current maximum size is {}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`"#, limit.bytes()));
- err.emit();
+ LargeAssignmentsLint {
+ span: source_info.span,
+ size: layout.size.bytes(),
+ limit: limit.bytes(),
},
- );
+ )
}
}
}
@@ -1027,6 +1006,11 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) ->
return false;
}
+ if let DefKind::Static(_) = tcx.def_kind(def_id) {
+ // We cannot monomorphize statics from upstream crates.
+ return false;
+ }
+
if !tcx.is_mir_available(def_id) {
bug!("no MIR available for {:?}", def_id);
}
@@ -1039,10 +1023,12 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) ->
/// them.
///
/// For example, the source type might be `&SomeStruct` and the target type
-/// might be `&SomeTrait` in a cast like:
+/// might be `&dyn SomeTrait` in a cast like:
///
+/// ```rust,ignore (not real code)
/// let src: &SomeStruct = ...;
-/// let target = src as &SomeTrait;
+/// let target = src as &dyn SomeTrait;
+/// ```
///
/// Then the output of this function would be (SomeStruct, SomeTrait) since for
/// constructing the `target` fat-pointer we need the vtable for that pair.
@@ -1063,8 +1049,10 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) ->
/// for the pair of `T` (which is a trait) and the concrete type that `T` was
/// originally coerced from:
///
+/// ```rust,ignore (not real code)
/// let src: &ComplexStruct<SomeStruct> = ...;
-/// let target = src as &ComplexStruct<SomeTrait>;
+/// let target = src as &ComplexStruct<dyn SomeTrait>;
+/// ```
///
/// Again, we want this `find_vtable_types_for_unsizing()` to provide the pair
/// `(SomeStruct, SomeTrait)`.
@@ -1105,6 +1093,9 @@ fn find_vtable_types_for_unsizing<'tcx>(
ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty())
}
+ // T as dyn* Trait
+ (_, &ty::Dynamic(_, _, ty::DynStar)) => ptr_vtable(source_ty, target_ty),
+
(&ty::Adt(source_adt_def, source_substs), &ty::Adt(target_adt_def, target_substs)) => {
assert_eq!(source_adt_def, target_adt_def);
@@ -1132,23 +1123,18 @@ fn find_vtable_types_for_unsizing<'tcx>(
}
}
-#[instrument(skip(tcx), level = "debug")]
+#[instrument(skip(tcx), level = "debug", ret)]
fn create_fn_mono_item<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
source: Span,
) -> Spanned<MonoItem<'tcx>> {
- debug!("create_fn_mono_item(instance={})", instance);
-
let def_id = instance.def_id();
if tcx.sess.opts.unstable_opts.profile_closures && def_id.is_local() && tcx.is_closure(def_id) {
crate::util::dump_closure_profile(tcx, instance);
}
- let respanned = respan(source, MonoItem::Fn(instance.polymorphize(tcx)));
- debug!(?respanned);
-
- respanned
+ respan(source, MonoItem::Fn(instance.polymorphize(tcx)))
}
/// Creates a `MonoItem` for each method that is referenced by the vtable for
@@ -1293,7 +1279,7 @@ impl<'v> RootCollector<'_, 'v> {
#[instrument(skip(self), level = "debug")]
fn push_if_root(&mut self, def_id: LocalDefId) {
if self.is_root(def_id) {
- debug!("RootCollector::push_if_root: found root def_id={:?}", def_id);
+ debug!("found root");
let instance = Instance::mono(self.tcx, def_id.to_def_id());
self.output.push(create_fn_mono_item(self.tcx, instance, DUMMY_SP));
@@ -1306,13 +1292,17 @@ impl<'v> RootCollector<'_, 'v> {
/// the return type of `main`. This is not needed when
/// the user writes their own `start` manually.
fn push_extra_entry_roots(&mut self) {
- let Some((main_def_id, EntryFnType::Main)) = self.entry_fn else {
+ let Some((main_def_id, EntryFnType::Main { .. })) = self.entry_fn else {
return;
};
let start_def_id = match self.tcx.lang_items().require(LangItem::Start) {
Ok(s) => s,
- Err(err) => self.tcx.sess.fatal(&err),
+ Err(lang_item_err) => {
+ self.tcx
+ .sess
+ .emit_fatal(RequiresLangItem { lang_item: lang_item_err.0.name().to_string() });
+ }
};
let main_ret_ty = self.tcx.fn_sig(main_def_id).output();
@@ -1415,7 +1405,7 @@ fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIte
}
GlobalAlloc::Memory(alloc) => {
trace!("collecting {:?} with {:#?}", alloc_id, alloc);
- for &inner in alloc.inner().relocations().values() {
+ for &inner in alloc.inner().provenance().values() {
rustc_data_structures::stack::ensure_sufficient_stack(|| {
collect_miri(tcx, inner, output);
});
@@ -1454,7 +1444,7 @@ fn collect_const_value<'tcx>(
match value {
ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => collect_miri(tcx, ptr.provenance, output),
ConstValue::Slice { data: alloc, start: _, end: _ } | ConstValue::ByRef { alloc, .. } => {
- for &id in alloc.inner().relocations().values() {
+ for &id in alloc.inner().provenance().values() {
collect_miri(tcx, id, output);
}
}
diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs
new file mode 100644
index 000000000..d5f05e790
--- /dev/null
+++ b/compiler/rustc_monomorphize/src/errors.rs
@@ -0,0 +1,85 @@
+use std::path::PathBuf;
+
+use rustc_errors::ErrorGuaranteed;
+use rustc_macros::{LintDiagnostic, SessionDiagnostic};
+use rustc_session::SessionDiagnostic;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[diag(monomorphize::recursion_limit)]
+pub struct RecursionLimit {
+ #[primary_span]
+ pub span: Span,
+ pub shrunk: String,
+ #[note]
+ pub def_span: Span,
+ pub def_path_str: String,
+ #[note(monomorphize::written_to_path)]
+ pub was_written: Option<()>,
+ pub path: PathBuf,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(monomorphize::type_length_limit)]
+#[help(monomorphize::consider_type_length_limit)]
+pub struct TypeLengthLimit {
+ #[primary_span]
+ pub span: Span,
+ pub shrunk: String,
+ #[note(monomorphize::written_to_path)]
+ pub was_written: Option<()>,
+ pub path: PathBuf,
+ pub type_length: usize,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(monomorphize::requires_lang_item)]
+pub struct RequiresLangItem {
+ pub lang_item: String,
+}
+
+pub struct UnusedGenericParams {
+ pub span: Span,
+ pub param_spans: Vec<Span>,
+ pub param_names: Vec<String>,
+}
+
+impl SessionDiagnostic<'_> for UnusedGenericParams {
+ fn into_diagnostic(
+ self,
+ handler: &'_ rustc_errors::Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag =
+ handler.struct_err(rustc_errors::fluent::monomorphize::unused_generic_params);
+ diag.set_span(self.span);
+ for (span, name) in self.param_spans.into_iter().zip(self.param_names) {
+ // FIXME: I can figure out how to do a label with a fluent string with a fixed message,
+ // or a label with a dynamic value in a hard-coded string, but I haven't figured out
+ // how to combine the two. 😢
+ diag.span_label(span, format!("generic parameter `{}` is unused", name));
+ }
+ diag
+ }
+}
+
+#[derive(LintDiagnostic)]
+#[diag(monomorphize::large_assignments)]
+#[note]
+pub struct LargeAssignmentsLint {
+ #[label]
+ pub span: Span,
+ pub size: u64,
+ pub limit: u64,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(monomorphize::unknown_partition_strategy)]
+pub struct UnknownPartitionStrategy;
+
+#[derive(SessionDiagnostic)]
+#[diag(monomorphize::symbol_already_defined)]
+pub struct SymbolAlreadyDefined {
+ #[primary_span]
+ pub span: Option<Span>,
+ pub symbol: String,
+}
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index ef4560b5e..ba6ce9fd4 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,8 +1,10 @@
#![feature(array_windows)]
#![feature(control_flow_enum)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
@@ -16,6 +18,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
mod collector;
+mod errors;
mod partitioning;
mod polymorphize;
mod util;
@@ -32,7 +35,7 @@ fn custom_coerce_unsize_info<'tcx>(
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
});
- match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
+ match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
impl_def_id,
..
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index ff2d38693..932edc667 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -108,6 +108,7 @@ use rustc_span::symbol::Symbol;
use crate::collector::InliningMap;
use crate::collector::{self, MonoItemCollectionMode};
+use crate::errors::{SymbolAlreadyDefined, UnknownPartitionStrategy};
pub struct PartitioningCx<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
@@ -149,7 +150,9 @@ fn get_partitioner<'tcx>(tcx: TyCtxt<'tcx>) -> Box<dyn Partitioner<'tcx>> {
match strategy {
"default" => Box::new(default::DefaultPartitioning),
- _ => tcx.sess.fatal("unknown partitioning strategy"),
+ _ => {
+ tcx.sess.emit_fatal(UnknownPartitionStrategy);
+ }
}
}
@@ -331,13 +334,7 @@ where
(span1, span2) => span1.or(span2),
};
- let error_message = format!("symbol `{}` is already defined", sym1);
-
- if let Some(span) = span {
- tcx.sess.span_fatal(span, &error_message)
- } else {
- tcx.sess.fatal(&error_message)
- }
+ tcx.sess.emit_fatal(SymbolAlreadyDefined { span, symbol: sym1.to_string() });
}
}
}
@@ -481,7 +478,7 @@ fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx DefIdSe
continue;
}
let body = tcx.instance_mir(instance.def);
- for block in body.basic_blocks() {
+ for block in body.basic_blocks.iter() {
for statement in &block.statements {
let mir::StatementKind::Coverage(_) = statement.kind else { continue };
let scope = statement.source_info.scope;
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 394843e51..71cab0232 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -9,7 +9,7 @@ use rustc_hir::{def::DefKind, def_id::DefId, ConstContext};
use rustc_index::bit_set::FiniteBitSet;
use rustc_middle::mir::{
visit::{TyContext, Visitor},
- Local, LocalDecl, Location,
+ Constant, ConstantKind, Local, LocalDecl, Location,
};
use rustc_middle::ty::{
self,
@@ -22,6 +22,8 @@ use rustc_span::symbol::sym;
use std::convert::TryInto;
use std::ops::ControlFlow;
+use crate::errors::UnusedGenericParams;
+
/// Provide implementations of queries relating to polymorphization analysis.
pub fn provide(providers: &mut Providers) {
providers.unused_generic_params = unused_generic_params;
@@ -31,7 +33,6 @@ pub fn provide(providers: &mut Providers) {
///
/// Returns a bitset where bits representing unused parameters are set (`is_empty` indicates all
/// parameters are used).
-#[instrument(level = "debug", skip(tcx))]
fn unused_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
instance: ty::InstanceDef<'tcx>,
@@ -169,6 +170,7 @@ fn mark_used_by_default_parameters<'tcx>(
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
@@ -206,22 +208,23 @@ fn emit_unused_generic_params_error<'tcx>(
_ => tcx.def_span(def_id),
};
- let mut err = tcx.sess.struct_span_err(fn_span, "item has unused generic parameters");
-
+ let mut param_spans = Vec::new();
+ let mut param_names = Vec::new();
let mut next_generics = Some(generics);
while let Some(generics) = next_generics {
for param in &generics.params {
if unused_parameters.contains(param.index).unwrap_or(false) {
debug!(?param);
let def_span = tcx.def_span(param.def_id);
- err.span_label(def_span, &format!("generic parameter `{}` is unused", param.name));
+ param_spans.push(def_span);
+ param_names.push(param.name.to_string());
}
}
next_generics = generics.parent.map(|did| tcx.generics_of(did));
}
- err.emit();
+ tcx.sess.emit_err(UnusedGenericParams { span: fn_span, param_spans, param_names });
}
/// Visitor used to aggregate generic parameter uses.
@@ -267,8 +270,15 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
self.super_local_decl(local, local_decl);
}
- fn visit_const(&mut self, c: Const<'tcx>, _: Location) {
- c.visit_with(self);
+ fn visit_constant(&mut self, ct: &Constant<'tcx>, location: Location) {
+ match ct.literal {
+ ConstantKind::Ty(c) => {
+ c.visit_with(self);
+ }
+ ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => {
+ Visitor::visit_ty(self, ty, TyContext::Location(location))
+ }
+ }
}
fn visit_ty(&mut self, ty: Ty<'tcx>, _: TyContext) {
@@ -289,7 +299,26 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
self.unused_parameters.clear(param.index);
ControlFlow::CONTINUE
}
- ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)})
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
+ if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) =>
+ {
+ assert_eq!(promoted, ());
+
+ self.visit_child_body(def.did, substs);
+ ControlFlow::CONTINUE
+ }
+ _ => c.super_visit_with(self),
+ }
+ }
+
+ fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if !constant.has_param_types_or_consts() {
+ return ControlFlow::CONTINUE;
+ }
+
+ match constant {
+ ConstantKind::Ty(ct) => ct.visit_with(self),
+ ConstantKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p) }, _)
// Avoid considering `T` unused when constants are of the form:
// `<Self as Foo<T>>::foo::promoted[p]`
if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self =>
@@ -300,13 +329,9 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
self.visit_body(&promoted[p]);
ControlFlow::CONTINUE
}
- ty::ConstKind::Unevaluated(uv)
- if matches!(self.tcx.def_kind(uv.def.did), DefKind::AnonConst | DefKind::InlineConst) =>
- {
- self.visit_child_body(uv.def.did, uv.substs);
- ControlFlow::CONTINUE
+ ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => {
+ constant.super_visit_with(self)
}
- _ => c.super_visit_with(self),
}
}
diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs
index 847e64dc2..6a4d2df1e 100644
--- a/compiler/rustc_monomorphize/src/util.rs
+++ b/compiler/rustc_monomorphize/src/util.rs
@@ -13,7 +13,7 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
.append(true)
.open(&format!("closure_profile_{}.csv", std::process::id()))
else {
- eprintln!("Cound't open file for writing closure profile");
+ eprintln!("Couldn't open file for writing closure profile");
return;
};
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 848e142e5..63819a2f9 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -14,8 +14,6 @@ use rustc_session::parse::ParseSess;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{edition::Edition, BytePos, Pos, Span};
-use tracing::debug;
-
mod tokentrees;
mod unescape_error_reporting;
mod unicode_chars;
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 273827864..77c4fadab 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -20,13 +20,9 @@ pub(crate) fn emit_unescape_error(
range: Range<usize>,
error: EscapeError,
) {
- tracing::debug!(
+ debug!(
"emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}",
- lit,
- span_with_quotes,
- mode,
- range,
- error
+ lit, span_with_quotes, mode, range, error
);
let last_char = || {
let c = lit[range.clone()].chars().rev().next().unwrap();
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 8c087c65c..a37327f42 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -4,7 +4,7 @@
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![recursion_limit = "256"]
@@ -63,7 +63,7 @@ pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'
pub fn parse_crate_attrs_from_file<'a>(
input: &Path,
sess: &'a ParseSess,
-) -> PResult<'a, Vec<ast::Attribute>> {
+) -> PResult<'a, ast::AttrVec> {
let mut parser = new_parser_from_file(sess, input, None);
parser.parse_inner_attributes()
}
@@ -80,7 +80,7 @@ pub fn parse_crate_attrs_from_source_str(
name: FileName,
source: String,
sess: &ParseSess,
-) -> PResult<'_, Vec<ast::Attribute>> {
+) -> PResult<'_, ast::AttrVec> {
new_parser_from_source_str(sess, name, source).parse_inner_attributes()
}
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index acdbddf40..5fd69b15e 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -7,8 +7,6 @@ use rustc_errors::{error_code, Diagnostic, PResult};
use rustc_span::{sym, BytePos, Span};
use std::convert::TryInto;
-use tracing::debug;
-
// Public for rustfmt usage
#[derive(Debug)]
pub enum InnerAttrPolicy<'a> {
@@ -34,7 +32,7 @@ enum OuterAttributeType {
impl<'a> Parser<'a> {
/// Parses attributes that appear before an item.
pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
- let mut outer_attrs: Vec<ast::Attribute> = Vec::new();
+ let mut outer_attrs = ast::AttrVec::new();
let mut just_parsed_doc_comment = false;
let start_pos = self.token_cursor.num_next_calls;
loop {
@@ -89,6 +87,7 @@ impl<'a> Parser<'a> {
// Always make an outer attribute - this allows us to recover from a misplaced
// inner attribute.
Some(attr::mk_doc_comment(
+ &self.sess.attr_id_generator,
comment_kind,
ast::AttrStyle::Outer,
data,
@@ -106,7 +105,7 @@ impl<'a> Parser<'a> {
break;
}
}
- Ok(AttrWrapper::new(outer_attrs.into(), start_pos))
+ Ok(AttrWrapper::new(outer_attrs, start_pos))
}
/// Matches `attribute = # ! [ meta_item ]`.
@@ -140,7 +139,13 @@ impl<'a> Parser<'a> {
this.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
}
- Ok(attr::mk_attr_from_item(item, None, style, attr_sp))
+ Ok(attr::mk_attr_from_item(
+ &self.sess.attr_id_generator,
+ item,
+ None,
+ style,
+ attr_sp,
+ ))
} else {
let token_str = pprust::token_to_string(&this.token);
let msg = &format!("expected `#`, found `{token_str}`");
@@ -283,8 +288,8 @@ impl<'a> Parser<'a> {
/// terminated by a semicolon.
///
/// Matches `inner_attrs*`.
- pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
- let mut attrs: Vec<ast::Attribute> = vec![];
+ pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
+ let mut attrs = ast::AttrVec::new();
loop {
let start_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap();
// Only try to parse if it is an inner attribute (has `!`).
@@ -293,7 +298,13 @@ impl<'a> Parser<'a> {
} else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
if attr_style == ast::AttrStyle::Inner {
self.bump();
- Some(attr::mk_doc_comment(comment_kind, attr_style, data, self.prev_token.span))
+ Some(attr::mk_doc_comment(
+ &self.sess.attr_id_generator,
+ comment_kind,
+ attr_style,
+ data,
+ self.prev_token.span,
+ ))
} else {
None
}
@@ -303,9 +314,9 @@ impl<'a> Parser<'a> {
if let Some(attr) = attr {
let end_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap();
// If we are currently capturing tokens, mark the location of this inner attribute.
- // If capturing ends up creating a `LazyTokenStream`, we will include
+ // If capturing ends up creating a `LazyAttrTokenStream`, we will include
// this replace range with it, removing the inner attribute from the final
- // `AttrAnnotatedTokenStream`. Inner attributes are stored in the parsed AST note.
+ // `AttrTokenStream`. Inner attributes are stored in the parsed AST note.
// During macro expansion, they are selectively inserted back into the
// token stream (the first inner attribute is removed each time we invoke the
// corresponding macro).
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 6c750ff42..5fdafd187 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -1,7 +1,7 @@
use super::{Capturing, FlatToken, ForceCollect, Parser, ReplaceRange, TokenCursor, TrailingToken};
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
-use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttributesData, CreateTokenStream};
-use rustc_ast::tokenstream::{AttrAnnotatedTokenTree, DelimSpan, LazyTokenStream, Spacing};
+use rustc_ast::tokenstream::{AttrTokenStream, AttributesData, ToAttrTokenStream};
+use rustc_ast::tokenstream::{AttrTokenTree, DelimSpan, LazyAttrTokenStream, Spacing};
use rustc_ast::{self as ast};
use rustc_ast::{AttrVec, Attribute, HasAttrs, HasTokens};
use rustc_errors::PResult;
@@ -15,11 +15,11 @@ use std::ops::Range;
/// for the attribute target. This allows us to perform cfg-expansion on
/// a token stream before we invoke a derive proc-macro.
///
-/// This wrapper prevents direct access to the underlying `Vec<ast::Attribute>`.
+/// This wrapper prevents direct access to the underlying `ast::AttrVec>`.
/// Parsing code can only get access to the underlying attributes
/// by passing an `AttrWrapper` to `collect_tokens_trailing_tokens`.
/// This makes it difficult to accidentally construct an AST node
-/// (which stores a `Vec<ast::Attribute>`) without first collecting tokens.
+/// (which stores an `ast::AttrVec`) without first collecting tokens.
///
/// This struct has its own module, to ensure that the parser code
/// cannot directly access the `attrs` field
@@ -49,9 +49,10 @@ impl AttrWrapper {
self.attrs
}
+ // Prepend `self.attrs` to `attrs`.
// FIXME: require passing an NT to prevent misuse of this method
- pub(crate) fn prepend_to_nt_inner(self, attrs: &mut Vec<Attribute>) {
- let mut self_attrs: Vec<_> = self.attrs.into();
+ pub(crate) fn prepend_to_nt_inner(self, attrs: &mut AttrVec) {
+ let mut self_attrs = self.attrs;
std::mem::swap(attrs, &mut self_attrs);
attrs.extend(self_attrs);
}
@@ -87,7 +88,7 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool {
// This also makes `Parser` very cheap to clone, since
// there is no intermediate collection buffer to clone.
#[derive(Clone)]
-struct LazyTokenStreamImpl {
+struct LazyAttrTokenStreamImpl {
start_token: (Token, Spacing),
cursor_snapshot: TokenCursor,
num_calls: usize,
@@ -96,10 +97,10 @@ struct LazyTokenStreamImpl {
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(LazyTokenStreamImpl, 144);
+rustc_data_structures::static_assert_size!(LazyAttrTokenStreamImpl, 144);
-impl CreateTokenStream for LazyTokenStreamImpl {
- fn create_token_stream(&self) -> AttrAnnotatedTokenStream {
+impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
+ fn to_attr_token_stream(&self) -> AttrTokenStream {
// The token produced by the final call to `{,inlined_}next` was not
// actually consumed by the callback. The combination of chaining the
// initial token and using `take` produces the desired result - we
@@ -116,7 +117,7 @@ impl CreateTokenStream for LazyTokenStreamImpl {
if !self.replace_ranges.is_empty() {
let mut tokens: Vec<_> = tokens.collect();
- let mut replace_ranges = self.replace_ranges.clone();
+ let mut replace_ranges = self.replace_ranges.to_vec();
replace_ranges.sort_by_key(|(range, _)| range.start);
#[cfg(debug_assertions)]
@@ -146,7 +147,7 @@ impl CreateTokenStream for LazyTokenStreamImpl {
// start position, we ensure that any replace range which encloses
// another replace range will capture the *replaced* tokens for the inner
// range, not the original tokens.
- for (range, new_tokens) in replace_ranges.iter().rev() {
+ for (range, new_tokens) in replace_ranges.into_iter().rev() {
assert!(!range.is_empty(), "Cannot replace an empty range: {:?}", range);
// Replace ranges are only allowed to decrease the number of tokens.
assert!(
@@ -165,7 +166,7 @@ impl CreateTokenStream for LazyTokenStreamImpl {
tokens.splice(
(range.start as usize)..(range.end as usize),
- new_tokens.clone().into_iter().chain(filler),
+ new_tokens.into_iter().chain(filler),
);
}
make_token_stream(tokens.into_iter(), self.break_last_token)
@@ -178,7 +179,7 @@ impl CreateTokenStream for LazyTokenStreamImpl {
impl<'a> Parser<'a> {
/// Records all tokens consumed by the provided callback,
/// including the current token. These tokens are collected
- /// into a `LazyTokenStream`, and returned along with the result
+ /// into a `LazyAttrTokenStream`, and returned along with the result
/// of the callback.
///
/// Note: If your callback consumes an opening delimiter
@@ -196,7 +197,7 @@ impl<'a> Parser<'a> {
&mut self,
attrs: AttrWrapper,
force_collect: ForceCollect,
- f: impl FnOnce(&mut Self, Vec<ast::Attribute>) -> PResult<'a, (R, TrailingToken)>,
+ f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, (R, TrailingToken)>,
) -> PResult<'a, R> {
// We only bail out when nothing could possibly observe the collected tokens:
// 1. We cannot be force collecting tokens (since force-collecting requires tokens
@@ -212,7 +213,7 @@ impl<'a> Parser<'a> {
// or `#[cfg_attr]` attributes.
&& !self.capture_cfg
{
- return Ok(f(self, attrs.attrs.into())?.0);
+ return Ok(f(self, attrs.attrs)?.0);
}
let start_token = (self.token.clone(), self.token_spacing);
@@ -222,7 +223,7 @@ impl<'a> Parser<'a> {
let prev_capturing = std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes);
let replace_ranges_start = self.capture_state.replace_ranges.len();
- let ret = f(self, attrs.attrs.into());
+ let ret = f(self, attrs.attrs);
self.capture_state.capturing = prev_capturing;
@@ -296,8 +297,8 @@ impl<'a> Parser<'a> {
// If we 'broke' the last token (e.g. breaking a '>>' token to two '>' tokens),
// then extend the range of captured tokens to include it, since the parser
- // was not actually bumped past it. When the `LazyTokenStream` gets converted
- // into an `AttrAnnotatedTokenStream`, we will create the proper token.
+ // was not actually bumped past it. When the `LazyAttrTokenStream` gets converted
+ // into an `AttrTokenStream`, we will create the proper token.
if self.token_cursor.break_last_token {
assert_eq!(
trailing,
@@ -315,20 +316,20 @@ impl<'a> Parser<'a> {
Box::new([])
} else {
// Grab any replace ranges that occur *inside* the current AST node.
- // We will perform the actual replacement when we convert the `LazyTokenStream`
- // to an `AttrAnnotatedTokenStream`
+ // We will perform the actual replacement when we convert the `LazyAttrTokenStream`
+ // to an `AttrTokenStream`.
let start_calls: u32 = cursor_snapshot_next_calls.try_into().unwrap();
self.capture_state.replace_ranges[replace_ranges_start..replace_ranges_end]
.iter()
.cloned()
- .chain(inner_attr_replace_ranges.clone().into_iter())
+ .chain(inner_attr_replace_ranges.iter().cloned())
.map(|(range, tokens)| {
((range.start - start_calls)..(range.end - start_calls), tokens)
})
.collect()
};
- let tokens = LazyTokenStream::new(LazyTokenStreamImpl {
+ let tokens = LazyAttrTokenStream::new(LazyAttrTokenStreamImpl {
start_token,
num_calls,
cursor_snapshot,
@@ -352,9 +353,9 @@ impl<'a> Parser<'a> {
// on the captured token stream.
if self.capture_cfg
&& matches!(self.capture_state.capturing, Capturing::Yes)
- && has_cfg_or_cfg_attr(&final_attrs)
+ && has_cfg_or_cfg_attr(final_attrs)
{
- let attr_data = AttributesData { attrs: final_attrs.to_vec().into(), tokens };
+ let attr_data = AttributesData { attrs: final_attrs.iter().cloned().collect(), tokens };
// Replace the entire AST node that we just parsed, including attributes,
// with a `FlatToken::AttrTarget`. If this AST node is inside an item
@@ -391,12 +392,12 @@ impl<'a> Parser<'a> {
fn make_token_stream(
mut iter: impl Iterator<Item = (FlatToken, Spacing)>,
break_last_token: bool,
-) -> AttrAnnotatedTokenStream {
+) -> AttrTokenStream {
#[derive(Debug)]
struct FrameData {
// This is `None` for the first frame, `Some` for all others.
open_delim_sp: Option<(Delimiter, Span)>,
- inner: Vec<(AttrAnnotatedTokenTree, Spacing)>,
+ inner: Vec<AttrTokenTree>,
}
let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }];
let mut token_and_spacing = iter.next();
@@ -417,48 +418,47 @@ fn make_token_stream(
open_delim, span
);
let dspan = DelimSpan::from_pair(open_sp, span);
- let stream = AttrAnnotatedTokenStream::new(frame_data.inner);
- let delimited = AttrAnnotatedTokenTree::Delimited(dspan, delim, stream);
+ let stream = AttrTokenStream::new(frame_data.inner);
+ let delimited = AttrTokenTree::Delimited(dspan, delim, stream);
stack
.last_mut()
.unwrap_or_else(|| {
panic!("Bottom token frame is missing for token: {:?}", token)
})
.inner
- .push((delimited, Spacing::Alone));
+ .push(delimited);
}
FlatToken::Token(token) => stack
.last_mut()
.expect("Bottom token frame is missing!")
.inner
- .push((AttrAnnotatedTokenTree::Token(token), spacing)),
+ .push(AttrTokenTree::Token(token, spacing)),
FlatToken::AttrTarget(data) => stack
.last_mut()
.expect("Bottom token frame is missing!")
.inner
- .push((AttrAnnotatedTokenTree::Attributes(data), spacing)),
+ .push(AttrTokenTree::Attributes(data)),
FlatToken::Empty => {}
}
token_and_spacing = iter.next();
}
let mut final_buf = stack.pop().expect("Missing final buf!");
if break_last_token {
- let (last_token, spacing) = final_buf.inner.pop().unwrap();
- if let AttrAnnotatedTokenTree::Token(last_token) = last_token {
+ let last_token = final_buf.inner.pop().unwrap();
+ if let AttrTokenTree::Token(last_token, spacing) = last_token {
let unglued_first = last_token.kind.break_two_token_op().unwrap().0;
// An 'unglued' token is always two ASCII characters
let mut first_span = last_token.span.shrink_to_lo();
first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1));
- final_buf.inner.push((
- AttrAnnotatedTokenTree::Token(Token::new(unglued_first, first_span)),
- spacing,
- ));
+ final_buf
+ .inner
+ .push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing));
} else {
panic!("Unexpected last token {:?}", last_token)
}
}
assert!(stack.is_empty(), "Stack should be empty: final_buf={:?} stack={:?}", final_buf, stack);
- AttrAnnotatedTokenStream::new(final_buf.inner)
+ AttrTokenStream::new(final_buf.inner)
}
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index a2155ac1d..be524db78 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -10,26 +10,25 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
use rustc_ast::util::parser::AssocOp;
use rustc_ast::{
- AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
- BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Mutability, Param, Pat,
- PatKind, Path, PathSegment, QSelf, Ty, TyKind,
+ AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingAnnotation, Block,
+ BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind,
+ Path, PathSegment, QSelf, Ty, TyKind,
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{
fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
};
-use rustc_errors::{pluralize, struct_span_err, Diagnostic, EmissionGuarantee, ErrorGuaranteed};
+use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, Ident};
+use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
use std::ops::{Deref, DerefMut};
use std::mem::take;
use crate::parser;
-use tracing::{debug, trace};
const TURBOFISH_SUGGESTION_STR: &str =
"use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments";
@@ -38,7 +37,7 @@ const TURBOFISH_SUGGESTION_STR: &str =
pub(super) fn dummy_arg(ident: Ident) -> Param {
let pat = P(Pat {
id: ast::DUMMY_NODE_ID,
- kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None),
+ kind: PatKind::Ident(BindingAnnotation::NONE, ident, None),
span: ident.span,
tokens: None,
});
@@ -228,13 +227,13 @@ struct MultiSugg {
}
impl MultiSugg {
- fn emit<G: EmissionGuarantee>(self, err: &mut DiagnosticBuilder<'_, G>) {
+ fn emit(self, err: &mut Diagnostic) {
err.multipart_suggestion(&self.msg, self.patches, self.applicability);
}
/// Overrides individual messages and applicabilities.
- fn emit_many<G: EmissionGuarantee>(
- err: &mut DiagnosticBuilder<'_, G>,
+ fn emit_many(
+ err: &mut Diagnostic,
msg: &str,
applicability: Applicability,
suggestions: impl Iterator<Item = Self>,
@@ -244,7 +243,7 @@ impl MultiSugg {
}
#[derive(SessionDiagnostic)]
-#[error(parser::maybe_report_ambiguous_plus)]
+#[diag(parser::maybe_report_ambiguous_plus)]
struct AmbiguousPlus {
pub sum_ty: String,
#[primary_span]
@@ -253,7 +252,7 @@ struct AmbiguousPlus {
}
#[derive(SessionDiagnostic)]
-#[error(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
+#[diag(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
struct BadTypePlus {
pub ty: String,
#[primary_span]
@@ -287,7 +286,7 @@ pub enum BadTypePlusSub {
}
#[derive(SessionDiagnostic)]
-#[error(parser::maybe_recover_from_bad_qpath_stage_2)]
+#[diag(parser::maybe_recover_from_bad_qpath_stage_2)]
struct BadQPathStage2 {
#[primary_span]
#[suggestion(applicability = "maybe-incorrect")]
@@ -296,7 +295,7 @@ struct BadQPathStage2 {
}
#[derive(SessionDiagnostic)]
-#[error(parser::incorrect_semicolon)]
+#[diag(parser::incorrect_semicolon)]
struct IncorrectSemicolon<'a> {
#[primary_span]
#[suggestion_short(applicability = "machine-applicable")]
@@ -307,7 +306,7 @@ struct IncorrectSemicolon<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(parser::incorrect_use_of_await)]
+#[diag(parser::incorrect_use_of_await)]
struct IncorrectUseOfAwait {
#[primary_span]
#[suggestion(parser::parentheses_suggestion, applicability = "machine-applicable")]
@@ -315,7 +314,7 @@ struct IncorrectUseOfAwait {
}
#[derive(SessionDiagnostic)]
-#[error(parser::incorrect_use_of_await)]
+#[diag(parser::incorrect_use_of_await)]
struct IncorrectAwait {
#[primary_span]
span: Span,
@@ -326,7 +325,7 @@ struct IncorrectAwait {
}
#[derive(SessionDiagnostic)]
-#[error(parser::in_in_typo)]
+#[diag(parser::in_in_typo)]
struct InInTypo {
#[primary_span]
span: Span,
@@ -334,6 +333,394 @@ struct InInTypo {
sugg_span: Span,
}
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_variable_declaration)]
+pub struct InvalidVariableDeclaration {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub sub: InvalidVariableDeclarationSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum InvalidVariableDeclarationSub {
+ #[suggestion(
+ parser::switch_mut_let_order,
+ applicability = "maybe-incorrect",
+ code = "let mut"
+ )]
+ SwitchMutLetOrder(#[primary_span] Span),
+ #[suggestion(
+ parser::missing_let_before_mut,
+ applicability = "machine-applicable",
+ code = "let mut"
+ )]
+ MissingLet(#[primary_span] Span),
+ #[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
+ UseLetNotAuto(#[primary_span] Span),
+ #[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
+ UseLetNotVar(#[primary_span] Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_comparison_operator)]
+pub(crate) struct InvalidComparisonOperator {
+ #[primary_span]
+ pub span: Span,
+ pub invalid: String,
+ #[subdiagnostic]
+ pub sub: InvalidComparisonOperatorSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum InvalidComparisonOperatorSub {
+ #[suggestion_short(
+ parser::use_instead,
+ applicability = "machine-applicable",
+ code = "{correct}"
+ )]
+ Correctable {
+ #[primary_span]
+ span: Span,
+ invalid: String,
+ correct: String,
+ },
+ #[label(parser::spaceship_operator_invalid)]
+ Spaceship(#[primary_span] Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_logical_operator)]
+#[note]
+pub(crate) struct InvalidLogicalOperator {
+ #[primary_span]
+ pub span: Span,
+ pub incorrect: String,
+ #[subdiagnostic]
+ pub sub: InvalidLogicalOperatorSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum InvalidLogicalOperatorSub {
+ #[suggestion_short(
+ parser::use_amp_amp_for_conjunction,
+ applicability = "machine-applicable",
+ code = "&&"
+ )]
+ Conjunction(#[primary_span] Span),
+ #[suggestion_short(
+ parser::use_pipe_pipe_for_disjunction,
+ applicability = "machine-applicable",
+ code = "||"
+ )]
+ Disjunction(#[primary_span] Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::tilde_is_not_unary_operator)]
+pub(crate) struct TildeAsUnaryOperator(
+ #[primary_span]
+ #[suggestion_short(applicability = "machine-applicable", code = "!")]
+ pub Span,
+);
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::unexpected_token_after_not)]
+pub(crate) struct NotAsNegationOperator {
+ #[primary_span]
+ pub negated: Span,
+ pub negated_desc: String,
+ #[suggestion_short(applicability = "machine-applicable", code = "!")]
+ pub not: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::malformed_loop_label)]
+pub(crate) struct MalformedLoopLabel {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "{correct_label}")]
+ pub span: Span,
+ pub correct_label: Ident,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::lifetime_in_borrow_expression)]
+pub(crate) struct LifetimeInBorrowExpression {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ #[label]
+ pub lifetime_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::field_expression_with_generic)]
+pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::macro_invocation_with_qualified_path)]
+pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::unexpected_token_after_label)]
+pub(crate) struct UnexpectedTokenAfterLabel(
+ #[primary_span]
+ #[label(parser::unexpected_token_after_label)]
+ pub Span,
+);
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::require_colon_after_labeled_expression)]
+#[note]
+pub(crate) struct RequireColonAfterLabeledExpression {
+ #[primary_span]
+ pub span: Span,
+ #[label]
+ pub label: Span,
+ #[suggestion_short(applicability = "machine-applicable", code = ": ")]
+ pub label_end: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::do_catch_syntax_removed)]
+#[note]
+pub(crate) struct DoCatchSyntaxRemoved {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "try")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::float_literal_requires_integer_part)]
+pub(crate) struct FloatLiteralRequiresIntegerPart {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "{correct}")]
+ pub span: Span,
+ pub correct: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_int_literal_width)]
+#[help]
+pub(crate) struct InvalidIntLiteralWidth {
+ #[primary_span]
+ pub span: Span,
+ pub width: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_num_literal_base_prefix)]
+#[note]
+pub(crate) struct InvalidNumLiteralBasePrefix {
+ #[primary_span]
+ #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")]
+ pub span: Span,
+ pub fixed: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_num_literal_suffix)]
+#[help]
+pub(crate) struct InvalidNumLiteralSuffix {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub suffix: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_float_literal_width)]
+#[help]
+pub(crate) struct InvalidFloatLiteralWidth {
+ #[primary_span]
+ pub span: Span,
+ pub width: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_float_literal_suffix)]
+#[help]
+pub(crate) struct InvalidFloatLiteralSuffix {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub suffix: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::int_literal_too_large)]
+pub(crate) struct IntLiteralTooLarge {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::missing_semicolon_before_array)]
+pub(crate) struct MissingSemicolonBeforeArray {
+ #[primary_span]
+ pub open_delim: Span,
+ #[suggestion_verbose(applicability = "maybe-incorrect", code = ";")]
+ pub semicolon: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_block_macro_segment)]
+pub(crate) struct InvalidBlockMacroSegment {
+ #[primary_span]
+ pub span: Span,
+ #[label]
+ pub context: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::if_expression_missing_then_block)]
+pub(crate) struct IfExpressionMissingThenBlock {
+ #[primary_span]
+ pub if_span: Span,
+ #[subdiagnostic]
+ pub sub: IfExpressionMissingThenBlockSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum IfExpressionMissingThenBlockSub {
+ #[help(parser::condition_possibly_unfinished)]
+ UnfinishedCondition(#[primary_span] Span),
+ #[help(parser::add_then_block)]
+ AddThenBlock(#[primary_span] Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::if_expression_missing_condition)]
+pub(crate) struct IfExpressionMissingCondition {
+ #[primary_span]
+ #[label(parser::condition_label)]
+ pub if_span: Span,
+ #[label(parser::block_label)]
+ pub block_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::expected_expression_found_let)]
+pub(crate) struct ExpectedExpressionFoundLet {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::expected_else_block)]
+pub(crate) struct ExpectedElseBlock {
+ #[primary_span]
+ pub first_tok_span: Span,
+ pub first_tok: String,
+ #[label]
+ pub else_span: Span,
+ #[suggestion(applicability = "maybe-incorrect", code = "if ")]
+ pub condition_start: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::outer_attribute_not_allowed_on_if_else)]
+pub(crate) struct OuterAttributeNotAllowedOnIfElse {
+ #[primary_span]
+ pub last: Span,
+
+ #[label(parser::branch_label)]
+ pub branch_span: Span,
+
+ #[label(parser::ctx_label)]
+ pub ctx_span: Span,
+ pub ctx: String,
+
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ pub attributes: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::missing_in_in_for_loop)]
+pub(crate) struct MissingInInForLoop {
+ #[primary_span]
+ pub span: Span,
+ #[subdiagnostic]
+ pub sub: MissingInInForLoopSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum MissingInInForLoopSub {
+ // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
+ #[suggestion_short(parser::use_in_not_of, applicability = "maybe-incorrect", code = "in")]
+ InNotOf(#[primary_span] Span),
+ #[suggestion_short(parser::add_in, applicability = "maybe-incorrect", code = " in ")]
+ AddIn(#[primary_span] Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::missing_comma_after_match_arm)]
+pub(crate) struct MissingCommaAfterMatchArm {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = ",")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::catch_after_try)]
+#[help]
+pub(crate) struct CatchAfterTry {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::comma_after_base_struct)]
+#[note]
+pub(crate) struct CommaAfterBaseStruct {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion_short(applicability = "machine-applicable", code = "")]
+ pub comma: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::eq_field_init)]
+pub(crate) struct EqFieldInit {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(applicability = "machine-applicable", code = ":")]
+ pub eq: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::dotdotdot)]
+pub(crate) struct DotDotDot {
+ #[primary_span]
+ #[suggestion(parser::suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
+ #[suggestion(parser::suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::left_arrow_operator)]
+pub(crate) struct LeftArrowOperator {
+ #[primary_span]
+ #[suggestion(applicability = "maybe-incorrect", code = "< -")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::remove_let)]
+pub(crate) struct RemoveLet {
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(parser::use_eq_instead)]
+pub(crate) struct UseEqInstead {
+ #[primary_span]
+ #[suggestion_short(applicability = "machine-applicable", code = "=")]
+ pub span: Span,
+}
+
// SnapshotParser is used to create a snapshot of the parser
// without causing duplicate errors being emitted when the `Parser`
// is dropped.
@@ -387,7 +774,7 @@ impl<'a> Parser<'a> {
/// This is to avoid losing unclosed delims errors `create_snapshot_for_diagnostic` clears.
pub(super) fn restore_snapshot(&mut self, snapshot: SnapshotParser<'a>) {
*self = snapshot.parser;
- self.unclosed_delims.extend(snapshot.unclosed_delims.clone());
+ self.unclosed_delims.extend(snapshot.unclosed_delims);
}
pub fn unclosed_delims(&self) -> &[UnmatchedBrace] {
@@ -555,10 +942,12 @@ impl<'a> Parser<'a> {
return Ok(true);
} else if self.look_ahead(0, |t| {
t == &token::CloseDelim(Delimiter::Brace)
- || (t.can_begin_expr() && t != &token::Semi && t != &token::Pound)
+ || ((t.can_begin_expr() || t.can_begin_item())
+ && t != &token::Semi
+ && t != &token::Pound)
// Avoid triggering with too many trailing `#` in raw string.
|| (sm.is_multiline(
- self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
+ self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()),
) && t == &token::Pound)
}) && !expected.contains(&TokenType::Token(token::Comma))
{
@@ -576,6 +965,14 @@ impl<'a> Parser<'a> {
}
}
+ if self.token.kind == TokenKind::EqEq
+ && self.prev_token.is_ident()
+ && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq)))
+ {
+ // Likely typo: `=` → `==` in let expr or enum item
+ return Err(self.sess.create_err(UseEqInstead { span: self.token.span }));
+ }
+
let expect = tokens_to_string(&expected);
let actual = super::token_descr(&self.token);
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
@@ -590,7 +987,7 @@ impl<'a> Parser<'a> {
)
} else if expected.is_empty() {
(
- format!("unexpected token: {}", actual),
+ format!("unexpected token: {actual}"),
(self.prev_token.span, "unexpected token after this".to_string()),
)
} else {
@@ -603,16 +1000,29 @@ impl<'a> Parser<'a> {
let mut err = self.struct_span_err(self.token.span, &msg_exp);
if let TokenKind::Ident(symbol, _) = &self.prev_token.kind {
- if symbol.as_str() == "public" {
+ if ["def", "fun", "func", "function"].contains(&symbol.as_str()) {
err.span_suggestion_short(
self.prev_token.span,
- "write `pub` instead of `public` to make the item public",
- "pub",
+ &format!("write `fn` instead of `{symbol}` to declare a function"),
+ "fn",
appl,
);
}
}
+ // `pub` may be used for an item or `pub(crate)`
+ if self.prev_token.is_ident_named(sym::public)
+ && (self.token.can_begin_item()
+ || self.token.kind == TokenKind::OpenDelim(Delimiter::Parenthesis))
+ {
+ err.span_suggestion_short(
+ self.prev_token.span,
+ "write `pub` instead of `public` to make the item public",
+ "pub",
+ appl,
+ );
+ }
+
// Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens
// there are unclosed angle brackets
if self.unmatched_angle_bracket_count > 0
@@ -734,7 +1144,7 @@ impl<'a> Parser<'a> {
let mut snapshot = self.create_snapshot_for_diagnostic();
let path =
Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
- let struct_expr = snapshot.parse_struct_expr(None, path, AttrVec::new(), false);
+ let struct_expr = snapshot.parse_struct_expr(None, path, false);
let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
return Some(match (struct_expr, block_tail) {
(Ok(expr), Err(mut err)) => {
@@ -1188,8 +1598,7 @@ impl<'a> Parser<'a> {
outer_op.node,
);
- let mk_err_expr =
- |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err, AttrVec::new())));
+ let mk_err_expr = |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err)));
match inner_op.kind {
ExprKind::Binary(op, ref l1, ref r1) if op.node.is_comparison() => {
@@ -1497,7 +1906,7 @@ impl<'a> Parser<'a> {
MultiSugg {
msg: format!("use `{}= 1` instead", kind.op.chr()),
patches: vec![
- (pre_span, format!("{{ let {} = ", tmp_var)),
+ (pre_span, format!("{{ let {tmp_var} = ")),
(post_span, format!("; {} {}= 1; {} }}", base_src, kind.op.chr(), tmp_var)),
],
applicability: Applicability::HasPlaceholders,
@@ -1647,7 +2056,6 @@ impl<'a> Parser<'a> {
&mut self,
lo: Span,
await_sp: Span,
- attrs: AttrVec,
) -> PResult<'a, P<Expr>> {
let (hi, expr, is_question) = if self.token == token::Not {
// Handle `await!(<expr>)`.
@@ -1662,7 +2070,7 @@ impl<'a> Parser<'a> {
ExprKind::Try(_) => ExprKind::Err,
_ => ExprKind::Await(expr),
};
- let expr = self.mk_expr(lo.to(sp), kind, attrs);
+ let expr = self.mk_expr(lo.to(sp), kind);
self.maybe_recover_from_bad_qpath(expr)
}
@@ -1680,7 +2088,7 @@ impl<'a> Parser<'a> {
// Handle `await { <expr> }`.
// This needs to be handled separately from the next arm to avoid
// interpreting `await { <expr> }?` as `<expr>?.await`.
- self.parse_block_expr(None, self.token.span, BlockCheckMode::Default, AttrVec::new())
+ self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)
} else {
self.parse_expr()
}
@@ -1823,7 +2231,7 @@ impl<'a> Parser<'a> {
err.emit();
// Recover from parse error, callers expect the closing delim to be consumed.
self.consume_block(delim, ConsumeClosingDelim::Yes);
- self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err, AttrVec::new())
+ self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err)
}
}
}
@@ -2334,7 +2742,7 @@ impl<'a> Parser<'a> {
fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option<GenericArg> {
let snapshot = self.create_snapshot_for_diagnostic();
- let param = match self.parse_const_param(vec![]) {
+ let param = match self.parse_const_param(AttrVec::new()) {
Ok(param) => param,
Err(err) => {
err.cancel();
@@ -2577,7 +2985,7 @@ impl<'a> Parser<'a> {
}
_ => {}
},
- PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => {
+ PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
match &first_pat.kind {
PatKind::Ident(_, old_ident, _) => {
let path = PatKind::Path(
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 0719a0ef0..725768c1f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1,4 +1,14 @@
-use super::diagnostics::SnapshotParser;
+use super::diagnostics::{
+ CatchAfterTry, CommaAfterBaseStruct, DoCatchSyntaxRemoved, DotDotDot, EqFieldInit,
+ ExpectedElseBlock, ExpectedExpressionFoundLet, FieldExpressionWithGeneric,
+ FloatLiteralRequiresIntegerPart, IfExpressionMissingCondition, IfExpressionMissingThenBlock,
+ IfExpressionMissingThenBlockSub, InvalidBlockMacroSegment, InvalidComparisonOperator,
+ InvalidComparisonOperatorSub, InvalidLogicalOperator, InvalidLogicalOperatorSub,
+ LeftArrowOperator, LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath,
+ MalformedLoopLabel, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray,
+ NotAsNegationOperator, OuterAttributeNotAllowedOnIfElse, RequireColonAfterLabeledExpression,
+ SnapshotParser, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
+};
use super::pat::{CommaRecoveryMode, RecoverColon, RecoverComma, PARAM_EXPECTED};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{
@@ -6,6 +16,11 @@ use super::{
SemiColonMode, SeqSep, TokenExpectType, TokenType, TrailingToken,
};
use crate::maybe_recover_from_interpolated_ty_qpath;
+use crate::parser::diagnostics::{
+ IntLiteralTooLarge, InvalidFloatLiteralSuffix, InvalidFloatLiteralWidth,
+ InvalidIntLiteralWidth, InvalidNumLiteralBasePrefix, InvalidNumLiteralSuffix,
+ MissingCommaAfterMatchArm,
+};
use core::mem;
use rustc_ast::ptr::P;
@@ -20,10 +35,10 @@ use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
use rustc_ast::{ClosureBinder, StmtKind};
use rustc_ast_pretty::pprust;
-use rustc_data_structures::thin_vec::ThinVec;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
+use rustc_errors::{Applicability, Diagnostic, PResult};
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_session::SessionDiagnostic;
use rustc_span::source_map::{self, Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Pos};
@@ -45,20 +60,12 @@ macro_rules! maybe_whole_expr {
token::NtPath(path) => {
let path = (**path).clone();
$p.bump();
- return Ok($p.mk_expr(
- $p.prev_token.span,
- ExprKind::Path(None, path),
- AttrVec::new(),
- ));
+ return Ok($p.mk_expr($p.prev_token.span, ExprKind::Path(None, path)));
}
token::NtBlock(block) => {
let block = block.clone();
$p.bump();
- return Ok($p.mk_expr(
- $p.prev_token.span,
- ExprKind::Block(block, None),
- AttrVec::new(),
- ));
+ return Ok($p.mk_expr($p.prev_token.span, ExprKind::Block(block, None)));
}
_ => {}
};
@@ -120,7 +127,7 @@ impl<'a> Parser<'a> {
// Special-case handling of `foo(_, _, _)`
err.emit();
self.bump();
- Ok(self.mk_expr(self.prev_token.span, ExprKind::Err, AttrVec::new()))
+ Ok(self.mk_expr(self.prev_token.span, ExprKind::Err))
}
_ => Err(err),
},
@@ -225,15 +232,18 @@ impl<'a> Parser<'a> {
AssocOp::Equal => "==",
AssocOp::NotEqual => "!=",
_ => unreachable!(),
- };
- self.struct_span_err(sp, &format!("invalid comparison operator `{sugg}=`"))
- .span_suggestion_short(
- sp,
- &format!("`{s}=` is not a valid comparison operator, use `{s}`", s = sugg),
- sugg,
- Applicability::MachineApplicable,
- )
- .emit();
+ }
+ .into();
+ let invalid = format!("{}=", &sugg);
+ self.sess.emit_err(InvalidComparisonOperator {
+ span: sp,
+ invalid: invalid.clone(),
+ sub: InvalidComparisonOperatorSub::Correctable {
+ span: sp,
+ invalid,
+ correct: sugg,
+ },
+ });
self.bump();
}
@@ -243,14 +253,15 @@ impl<'a> Parser<'a> {
&& self.prev_token.span.hi() == self.token.span.lo()
{
let sp = op.span.to(self.token.span);
- self.struct_span_err(sp, "invalid comparison operator `<>`")
- .span_suggestion_short(
- sp,
- "`<>` is not a valid comparison operator, use `!=`",
- "!=",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(InvalidComparisonOperator {
+ span: sp,
+ invalid: "<>".into(),
+ sub: InvalidComparisonOperatorSub::Correctable {
+ span: sp,
+ invalid: "<>".into(),
+ correct: "!=".into(),
+ },
+ });
self.bump();
}
@@ -260,12 +271,11 @@ impl<'a> Parser<'a> {
&& self.prev_token.span.hi() == self.token.span.lo()
{
let sp = op.span.to(self.token.span);
- self.struct_span_err(sp, "invalid comparison operator `<=>`")
- .span_label(
- sp,
- "`<=>` is not a valid comparison operator, use `std::cmp::Ordering`",
- )
- .emit();
+ self.sess.emit_err(InvalidComparisonOperator {
+ span: sp,
+ invalid: "<=>".into(),
+ sub: InvalidComparisonOperatorSub::Spaceship(sp),
+ });
self.bump();
}
@@ -329,11 +339,9 @@ impl<'a> Parser<'a> {
| AssocOp::GreaterEqual => {
let ast_op = op.to_ast_binop().unwrap();
let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
- self.mk_expr(span, binary, AttrVec::new())
- }
- AssocOp::Assign => {
- self.mk_expr(span, ExprKind::Assign(lhs, rhs, cur_op_span), AttrVec::new())
+ self.mk_expr(span, binary)
}
+ AssocOp::Assign => self.mk_expr(span, ExprKind::Assign(lhs, rhs, cur_op_span)),
AssocOp::AssignOp(k) => {
let aop = match k {
token::Plus => BinOpKind::Add,
@@ -348,7 +356,7 @@ impl<'a> Parser<'a> {
token::Shr => BinOpKind::Shr,
};
let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs);
- self.mk_expr(span, aopexpr, AttrVec::new())
+ self.mk_expr(span, aopexpr)
}
AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
self.span_bug(span, "AssocOp should have been handled by special case")
@@ -441,11 +449,19 @@ impl<'a> Parser<'a> {
}
(Some(op), _) => (op, self.token.span),
(None, Some((Ident { name: sym::and, span }, false))) => {
- self.error_bad_logical_op("and", "&&", "conjunction");
+ self.sess.emit_err(InvalidLogicalOperator {
+ span: self.token.span,
+ incorrect: "and".into(),
+ sub: InvalidLogicalOperatorSub::Conjunction(self.token.span),
+ });
(AssocOp::LAnd, span)
}
(None, Some((Ident { name: sym::or, span }, false))) => {
- self.error_bad_logical_op("or", "||", "disjunction");
+ self.sess.emit_err(InvalidLogicalOperator {
+ span: self.token.span,
+ incorrect: "or".into(),
+ sub: InvalidLogicalOperatorSub::Disjunction(self.token.span),
+ });
(AssocOp::LOr, span)
}
_ => return None,
@@ -453,19 +469,6 @@ impl<'a> Parser<'a> {
Some(source_map::respan(span, op))
}
- /// Error on `and` and `or` suggesting `&&` and `||` respectively.
- fn error_bad_logical_op(&self, bad: &str, good: &str, english: &str) {
- self.struct_span_err(self.token.span, &format!("`{bad}` is not a logical operator"))
- .span_suggestion_short(
- self.token.span,
- &format!("use `{good}` to perform logical {english}"),
- good,
- Applicability::MachineApplicable,
- )
- .note("unlike in e.g., python and PHP, `&&` and `||` are used for logical operators")
- .emit();
- }
-
/// Checks if this expression is a successfully parsed statement.
fn expr_is_complete(&self, e: &Expr) -> bool {
self.restrictions.contains(Restrictions::STMT_EXPR)
@@ -491,7 +494,7 @@ impl<'a> Parser<'a> {
let limits =
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
let range = self.mk_range(Some(lhs), rhs, limits);
- Ok(self.mk_expr(span, range, AttrVec::new()))
+ Ok(self.mk_expr(span, range))
}
fn is_at_start_of_range_notation_rhs(&self) -> bool {
@@ -540,7 +543,7 @@ impl<'a> Parser<'a> {
(lo, None)
};
let range = this.mk_range(None, opt_end, limits);
- Ok(this.mk_expr(span, range, attrs.into()))
+ Ok(this.mk_expr_with_attrs(span, range, attrs))
})
}
@@ -553,7 +556,7 @@ impl<'a> Parser<'a> {
($this:ident, $attrs:expr, |this, _| $body:expr) => {
$this.collect_tokens_for_expr($attrs, |$this, attrs| {
let (hi, ex) = $body?;
- Ok($this.mk_expr(lo.to(hi), ex, attrs.into()))
+ Ok($this.mk_expr_with_attrs(lo.to(hi), ex, attrs))
})
};
}
@@ -630,14 +633,7 @@ impl<'a> Parser<'a> {
// Recover on `!` suggesting for bitwise negation instead.
fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
- self.struct_span_err(lo, "`~` cannot be used as a unary operator")
- .span_suggestion_short(
- lo,
- "use `!` to perform bitwise not",
- "!",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(TildeAsUnaryOperator(lo));
self.parse_unary_expr(lo, UnOp::Not)
}
@@ -663,20 +659,14 @@ impl<'a> Parser<'a> {
/// Recover on `not expr` in favor of `!expr`.
fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
// Emit the error...
- let not_token = self.look_ahead(1, |t| t.clone());
- self.struct_span_err(
- not_token.span,
- &format!("unexpected {} after identifier", super::token_descr(&not_token)),
- )
- .span_suggestion_short(
+ let negated_token = self.look_ahead(1, |t| t.clone());
+ self.sess.emit_err(NotAsNegationOperator {
+ negated: negated_token.span,
+ negated_desc: super::token_descr(&negated_token),
// Span the `not` plus trailing whitespace to avoid
// trailing whitespace after the `!` in our suggestion
- self.sess.source_map().span_until_non_whitespace(lo.to(not_token.span)),
- "use `!` to perform logical negation",
- "!",
- Applicability::MachineApplicable,
- )
- .emit();
+ not: self.sess.source_map().span_until_non_whitespace(lo.to(negated_token.span)),
+ });
// ...and recover!
self.parse_unary_expr(lo, UnOp::Not)
@@ -705,11 +695,7 @@ impl<'a> Parser<'a> {
expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
) -> PResult<'a, P<Expr>> {
let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
- this.mk_expr(
- this.mk_expr_sp(&lhs, lhs_span, rhs.span),
- expr_kind(lhs, rhs),
- AttrVec::new(),
- )
+ this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs))
};
// Save the state of the parser before parsing type normally, in case there is a
@@ -737,17 +723,13 @@ impl<'a> Parser<'a> {
segments[0].ident.span,
),
};
- match self.parse_labeled_expr(label, AttrVec::new(), false) {
+ match self.parse_labeled_expr(label, false) {
Ok(expr) => {
type_err.cancel();
- self.struct_span_err(label.ident.span, "malformed loop label")
- .span_suggestion(
- label.ident.span,
- "use the correct loop label format",
- label.ident,
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(MalformedLoopLabel {
+ span: label.ident.span,
+ correct_label: label.ident,
+ });
return Ok(expr);
}
Err(err) => {
@@ -859,7 +841,7 @@ impl<'a> Parser<'a> {
);
let mut err = self.struct_span_err(span, &msg);
- let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| {
+ let suggest_parens = |err: &mut Diagnostic| {
let suggestions = vec![
(span.shrink_to_lo(), "(".to_string()),
(span.shrink_to_hi(), ")".to_string()),
@@ -925,15 +907,7 @@ impl<'a> Parser<'a> {
}
fn error_remove_borrow_lifetime(&self, span: Span, lt_span: Span) {
- self.struct_span_err(span, "borrow expressions cannot be annotated with lifetimes")
- .span_label(lt_span, "annotated with lifetime here")
- .span_suggestion(
- lt_span,
- "remove the lifetime annotation",
- "",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(LifetimeInBorrowExpression { span, lifetime_span: lt_span });
}
/// Parse `mut?` or `raw [ const | mut ]`.
@@ -965,18 +939,23 @@ impl<'a> Parser<'a> {
&mut self,
e0: P<Expr>,
lo: Span,
- mut attrs: Vec<ast::Attribute>,
+ mut attrs: ast::AttrVec,
) -> PResult<'a, P<Expr>> {
// Stitch the list of outer attributes onto the return value.
// A little bit ugly, but the best way given the current code
// structure
- self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| {
- expr.map(|mut expr| {
- attrs.extend::<Vec<_>>(expr.attrs.into());
- expr.attrs = attrs.into();
- expr
+ let res = self.parse_dot_or_call_expr_with_(e0, lo);
+ if attrs.is_empty() {
+ res
+ } else {
+ res.map(|expr| {
+ expr.map(|mut expr| {
+ attrs.extend(expr.attrs);
+ expr.attrs = attrs;
+ expr
+ })
})
- })
+ }
}
fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
@@ -990,7 +969,7 @@ impl<'a> Parser<'a> {
};
if has_question {
// `expr?`
- e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e), AttrVec::new());
+ e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e));
continue;
}
let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
@@ -1168,7 +1147,7 @@ impl<'a> Parser<'a> {
let span = self.prev_token.span;
let field = ExprKind::Field(base, Ident::new(field, span));
self.expect_no_suffix(span, "a tuple index", suffix);
- self.mk_expr(lo.to(span), field, AttrVec::new())
+ self.mk_expr(lo.to(span), field)
}
/// Parse a function call expression, `expr(...)`.
@@ -1182,9 +1161,9 @@ impl<'a> Parser<'a> {
};
let open_paren = self.token.span;
- let mut seq = self.parse_paren_expr_seq().map(|args| {
- self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args), AttrVec::new())
- });
+ let mut seq = self
+ .parse_paren_expr_seq()
+ .map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args)));
if let Some(expr) =
self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot)
{
@@ -1258,10 +1237,13 @@ impl<'a> Parser<'a> {
/// Parse an indexing expression `expr[...]`.
fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
+ let prev_span = self.prev_token.span;
+ let open_delim_span = self.token.span;
self.bump(); // `[`
let index = self.parse_expr()?;
+ self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
self.expect(&token::CloseDelim(Delimiter::Bracket))?;
- Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new()))
+ Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index)))
}
/// Assuming we have just parsed `.`, continue parsing into an expression.
@@ -1282,19 +1264,15 @@ impl<'a> Parser<'a> {
let fn_span = fn_span_lo.to(self.prev_token.span);
let span = lo.to(self.prev_token.span);
- Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args, fn_span), AttrVec::new()))
+ Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args, fn_span)))
} else {
// Field access `expr.f`
if let Some(args) = segment.args {
- self.struct_span_err(
- args.span(),
- "field expressions cannot have generic arguments",
- )
- .emit();
+ self.sess.emit_err(FieldExpressionWithGeneric(args.span()));
}
let span = lo.to(self.prev_token.span);
- Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident), AttrVec::new()))
+ Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident)))
}
}
@@ -1309,10 +1287,6 @@ impl<'a> Parser<'a> {
// Outer attributes are already parsed and will be
// added to the return value after the fact.
- //
- // Therefore, prevent sub-parser from parsing
- // attributes by giving them an empty "already-parsed" list.
- let attrs = AttrVec::new();
// Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
let lo = self.token.span;
@@ -1320,13 +1294,13 @@ impl<'a> Parser<'a> {
// This match arm is a special-case of the `_` match arm below and
// could be removed without changing functionality, but it's faster
// to have it here, especially for programs with large constants.
- self.parse_lit_expr(attrs)
+ self.parse_lit_expr()
} else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
- self.parse_tuple_parens_expr(attrs)
+ self.parse_tuple_parens_expr()
} else if self.check(&token::OpenDelim(Delimiter::Brace)) {
- self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs)
+ self.parse_block_expr(None, lo, BlockCheckMode::Default)
} else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) {
- self.parse_closure_expr(attrs).map_err(|mut err| {
+ self.parse_closure_expr().map_err(|mut err| {
// If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
// then suggest parens around the lhs.
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
@@ -1335,65 +1309,66 @@ impl<'a> Parser<'a> {
err
})
} else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
- self.parse_array_or_repeat_expr(attrs, Delimiter::Bracket)
+ self.parse_array_or_repeat_expr(Delimiter::Bracket)
} else if self.check_path() {
- self.parse_path_start_expr(attrs)
+ self.parse_path_start_expr()
} else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
- self.parse_closure_expr(attrs)
+ self.parse_closure_expr()
} else if self.eat_keyword(kw::If) {
- self.parse_if_expr(attrs)
+ self.parse_if_expr()
} else if self.check_keyword(kw::For) {
if self.choose_generics_over_qpath(1) {
- self.parse_closure_expr(attrs)
+ self.parse_closure_expr()
} else {
assert!(self.eat_keyword(kw::For));
- self.parse_for_expr(None, self.prev_token.span, attrs)
+ self.parse_for_expr(None, self.prev_token.span)
}
} else if self.eat_keyword(kw::While) {
- self.parse_while_expr(None, self.prev_token.span, attrs)
+ self.parse_while_expr(None, self.prev_token.span)
} else if let Some(label) = self.eat_label() {
- self.parse_labeled_expr(label, attrs, true)
+ self.parse_labeled_expr(label, true)
} else if self.eat_keyword(kw::Loop) {
let sp = self.prev_token.span;
- self.parse_loop_expr(None, self.prev_token.span, attrs).map_err(|mut err| {
+ self.parse_loop_expr(None, self.prev_token.span).map_err(|mut err| {
err.span_label(sp, "while parsing this `loop` expression");
err
})
} else if self.eat_keyword(kw::Continue) {
let kind = ExprKind::Continue(self.eat_label());
- Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
+ Ok(self.mk_expr(lo.to(self.prev_token.span), kind))
} else if self.eat_keyword(kw::Match) {
let match_sp = self.prev_token.span;
- self.parse_match_expr(attrs).map_err(|mut err| {
+ self.parse_match_expr().map_err(|mut err| {
err.span_label(match_sp, "while parsing this `match` expression");
err
})
} else if self.eat_keyword(kw::Unsafe) {
let sp = self.prev_token.span;
- self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
- .map_err(|mut err| {
+ self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err(
+ |mut err| {
err.span_label(sp, "while parsing this `unsafe` expression");
err
- })
+ },
+ )
} else if self.check_inline_const(0) {
self.parse_const_block(lo.to(self.token.span), false)
} else if self.is_do_catch_block() {
- self.recover_do_catch(attrs)
+ self.recover_do_catch()
} else if self.is_try_block() {
self.expect_keyword(kw::Try)?;
- self.parse_try_block(lo, attrs)
+ self.parse_try_block(lo)
} else if self.eat_keyword(kw::Return) {
- self.parse_return_expr(attrs)
+ self.parse_return_expr()
} else if self.eat_keyword(kw::Break) {
- self.parse_break_expr(attrs)
+ self.parse_break_expr()
} else if self.eat_keyword(kw::Yield) {
- self.parse_yield_expr(attrs)
+ self.parse_yield_expr()
} else if self.is_do_yeet() {
- self.parse_yeet_expr(attrs)
+ self.parse_yeet_expr()
} else if self.check_keyword(kw::Let) {
- self.parse_let_expr(attrs)
+ self.parse_let_expr()
} else if self.eat_keyword(kw::Underscore) {
- Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
+ Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore))
} else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
// Don't complain about bare semicolons after unclosed braces
// recovery in order to keep the error count down. Fixing the
@@ -1412,32 +1387,32 @@ impl<'a> Parser<'a> {
if self.check_keyword(kw::Async) {
if self.is_async_block() {
// Check for `async {` and `async move {`.
- self.parse_async_block(attrs)
+ self.parse_async_block()
} else {
- self.parse_closure_expr(attrs)
+ self.parse_closure_expr()
}
} else if self.eat_keyword(kw::Await) {
- self.recover_incorrect_await_syntax(lo, self.prev_token.span, attrs)
+ self.recover_incorrect_await_syntax(lo, self.prev_token.span)
} else {
- self.parse_lit_expr(attrs)
+ self.parse_lit_expr()
}
} else {
- self.parse_lit_expr(attrs)
+ self.parse_lit_expr()
}
}
- fn parse_lit_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_lit_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
match self.parse_opt_lit() {
Some(literal) => {
- let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs);
+ let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal));
self.maybe_recover_from_bad_qpath(expr)
}
None => self.try_macro_suggestion(),
}
}
- fn parse_tuple_parens_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_tuple_parens_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
let (es, trailing_comma) = match self.parse_seq_to_end(
@@ -1457,15 +1432,11 @@ impl<'a> Parser<'a> {
// `(e,)` is a tuple with only one field, `e`.
ExprKind::Tup(es)
};
- let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
+ let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
self.maybe_recover_from_bad_qpath(expr)
}
- fn parse_array_or_repeat_expr(
- &mut self,
- attrs: AttrVec,
- close_delim: Delimiter,
- ) -> PResult<'a, P<Expr>> {
+ fn parse_array_or_repeat_expr(&mut self, close_delim: Delimiter) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
self.bump(); // `[` or other open delim
@@ -1494,45 +1465,42 @@ impl<'a> Parser<'a> {
ExprKind::Array(vec![first_expr])
}
};
- let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
+ let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
self.maybe_recover_from_bad_qpath(expr)
}
- fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_path_start_expr(&mut self) -> PResult<'a, P<Expr>> {
let (qself, path) = if self.eat_lt() {
let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
(Some(qself), path)
} else {
(None, self.parse_path(PathStyle::Expr)?)
};
- let lo = path.span;
// `!`, as an operator, is prefix, so we know this isn't that.
- let (hi, kind) = if self.eat(&token::Not) {
+ let (span, kind) = if self.eat(&token::Not) {
// MACRO INVOCATION expression
if qself.is_some() {
- self.struct_span_err(path.span, "macros cannot use qualified paths").emit();
+ self.sess.emit_err(MacroInvocationWithQualifiedPath(path.span));
}
- let mac = MacCall {
+ let lo = path.span;
+ let mac = P(MacCall {
path,
args: self.parse_mac_args()?,
prior_type_ascription: self.last_type_ascription,
- };
- (self.prev_token.span, ExprKind::MacCall(mac))
- } else if self.check(&token::OpenDelim(Delimiter::Brace)) {
- if let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path, &attrs) {
+ });
+ (lo.to(self.prev_token.span), ExprKind::MacCall(mac))
+ } else if self.check(&token::OpenDelim(Delimiter::Brace)) &&
+ let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path) {
if qself.is_some() {
self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
}
return expr;
- } else {
- (path.span, ExprKind::Path(qself, path))
- }
} else {
(path.span, ExprKind::Path(qself, path))
};
- let expr = self.mk_expr(lo.to(hi), kind, attrs);
+ let expr = self.mk_expr(span, kind);
self.maybe_recover_from_bad_qpath(expr)
}
@@ -1540,31 +1508,30 @@ impl<'a> Parser<'a> {
fn parse_labeled_expr(
&mut self,
label: Label,
- attrs: AttrVec,
mut consume_colon: bool,
) -> PResult<'a, P<Expr>> {
let lo = label.ident.span;
let label = Some(label);
let ate_colon = self.eat(&token::Colon);
let expr = if self.eat_keyword(kw::While) {
- self.parse_while_expr(label, lo, attrs)
+ self.parse_while_expr(label, lo)
} else if self.eat_keyword(kw::For) {
- self.parse_for_expr(label, lo, attrs)
+ self.parse_for_expr(label, lo)
} else if self.eat_keyword(kw::Loop) {
- self.parse_loop_expr(label, lo, attrs)
+ self.parse_loop_expr(label, lo)
} else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace))
|| self.token.is_whole_block()
{
- self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
+ self.parse_block_expr(label, lo, BlockCheckMode::Default)
} else if !ate_colon
&& (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
{
// We're probably inside of a `Path<'a>` that needs a turbofish
- let msg = "expected `while`, `for`, `loop` or `{` after a label";
- self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
+ self.sess.emit_err(UnexpectedTokenAfterLabel(self.token.span));
consume_colon = false;
Ok(self.mk_expr_err(lo))
} else {
+ // FIXME: use UnexpectedTokenAfterLabel, needs multipart suggestions
let msg = "expected `while`, `for`, `loop` or `{` after a label";
let mut err = self.struct_span_err(self.token.span, msg);
@@ -1618,10 +1585,10 @@ impl<'a> Parser<'a> {
Applicability::MachineApplicable,
);
- // Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to supress future errors about `break 'label`.
+ // Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to suppress future errors about `break 'label`.
let stmt = self.mk_stmt(span, StmtKind::Expr(expr));
let blk = self.mk_block(vec![stmt], BlockCheckMode::Default, span);
- self.mk_expr(span, ExprKind::Block(blk, label), ThinVec::new())
+ self.mk_expr(span, ExprKind::Block(blk, label))
});
err.emit();
@@ -1629,44 +1596,27 @@ impl<'a> Parser<'a> {
}?;
if !ate_colon && consume_colon {
- self.error_labeled_expr_must_be_followed_by_colon(lo, expr.span);
+ self.sess.emit_err(RequireColonAfterLabeledExpression {
+ span: expr.span,
+ label: lo,
+ label_end: lo.shrink_to_hi(),
+ });
}
Ok(expr)
}
- fn error_labeled_expr_must_be_followed_by_colon(&self, lo: Span, span: Span) {
- self.struct_span_err(span, "labeled expression must be followed by `:`")
- .span_label(lo, "the label")
- .span_suggestion_short(
- lo.shrink_to_hi(),
- "add `:` after the label",
- ": ",
- Applicability::MachineApplicable,
- )
- .note("labels are used before loops and blocks, allowing e.g., `break 'label` to them")
- .emit();
- }
-
/// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
- fn recover_do_catch(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn recover_do_catch(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
self.bump(); // `do`
self.bump(); // `catch`
- let span_dc = lo.to(self.prev_token.span);
- self.struct_span_err(span_dc, "found removed `do catch` syntax")
- .span_suggestion(
- span_dc,
- "replace with the new syntax",
- "try",
- Applicability::MachineApplicable,
- )
- .note("following RFC #2388, the new non-placeholder syntax is `try`")
- .emit();
+ let span = lo.to(self.prev_token.span);
+ self.sess.emit_err(DoCatchSyntaxRemoved { span });
- self.parse_try_block(lo, attrs)
+ self.parse_try_block(lo)
}
/// Parse an expression if the token can begin one.
@@ -1675,15 +1625,15 @@ impl<'a> Parser<'a> {
}
/// Parse `"return" expr?`.
- fn parse_return_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_return_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.prev_token.span;
let kind = ExprKind::Ret(self.parse_expr_opt()?);
- let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
+ let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
self.maybe_recover_from_bad_qpath(expr)
}
/// Parse `"do" "yeet" expr?`.
- fn parse_yeet_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_yeet_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
self.bump(); // `do`
@@ -1693,7 +1643,7 @@ impl<'a> Parser<'a> {
let span = lo.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::yeet_expr, span);
- let expr = self.mk_expr(span, kind, attrs);
+ let expr = self.mk_expr(span, kind);
self.maybe_recover_from_bad_qpath(expr)
}
@@ -1705,13 +1655,13 @@ impl<'a> Parser<'a> {
/// `break 'lbl: loop {}`); a labeled break with an unlabeled loop as its value
/// expression only gets a warning for compatibility reasons; and a labeled break
/// with a labeled loop does not even get a warning because there is no ambiguity.
- fn parse_break_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_break_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.prev_token.span;
let mut label = self.eat_label();
let kind = if label.is_some() && self.token == token::Colon {
// The value expression can be a labeled loop, see issue #86948, e.g.:
// `loop { break 'label: loop { break 'label 42; }; }`
- let lexpr = self.parse_labeled_expr(label.take().unwrap(), AttrVec::new(), true)?;
+ let lexpr = self.parse_labeled_expr(label.take().unwrap(), true)?;
self.struct_span_err(
lexpr.span,
"parentheses are required around this expression to avoid confusion with a labeled break expression",
@@ -1753,17 +1703,17 @@ impl<'a> Parser<'a> {
} else {
None
};
- let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Break(label, kind), attrs);
+ let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Break(label, kind));
self.maybe_recover_from_bad_qpath(expr)
}
/// Parse `"yield" expr?`.
- fn parse_yield_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_yield_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.prev_token.span;
let kind = ExprKind::Yield(self.parse_expr_opt()?);
let span = lo.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::generators, span);
- let expr = self.mk_expr(span, kind, attrs);
+ let expr = self.mk_expr(span, kind);
self.maybe_recover_from_bad_qpath(expr)
}
@@ -1775,8 +1725,8 @@ impl<'a> Parser<'a> {
Some(lit) => match lit.kind {
ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
style,
- symbol: lit.token.symbol,
- suffix: lit.token.suffix,
+ symbol: lit.token_lit.symbol,
+ suffix: lit.token_lit.suffix,
span: lit.span,
symbol_unescaped,
}),
@@ -1853,20 +1803,16 @@ impl<'a> Parser<'a> {
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
let symbol = Symbol::intern(&suffixless_lit.to_string());
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
- Some(Lit::from_lit_token(lit, span).unwrap_or_else(|_| unreachable!()))
+ Some(Lit::from_token_lit(lit, span).unwrap_or_else(|_| unreachable!()))
}
}
}
fn error_float_lits_must_have_int_part(&self, token: &Token) {
- self.struct_span_err(token.span, "float literals must have an integer part")
- .span_suggestion(
- token.span,
- "must have an integer part",
- pprust::token_to_string(token),
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(FloatLiteralRequiresIntegerPart {
+ span: token.span,
+ correct: pprust::token_to_string(token).into_owned(),
+ });
}
fn report_lit_error(&self, err: LitError, lit: token::Lit, span: Span) {
@@ -1908,28 +1854,11 @@ impl<'a> Parser<'a> {
let suf = suf.as_str();
if looks_like_width_suffix(&['i', 'u'], &suf) {
// If it looks like a width, try to be helpful.
- let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
- self.struct_span_err(span, &msg)
- .help("valid widths are 8, 16, 32, 64 and 128")
- .emit();
+ self.sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
} else if let Some(fixed) = fix_base_capitalisation(suf) {
- let msg = "invalid base prefix for number literal";
-
- self.struct_span_err(span, msg)
- .note("base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase")
- .span_suggestion(
- span,
- "try making the prefix lowercase",
- fixed,
- Applicability::MaybeIncorrect,
- )
- .emit();
+ self.sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
} else {
- let msg = format!("invalid suffix `{suf}` for number literal");
- self.struct_span_err(span, &msg)
- .span_label(span, format!("invalid suffix `{suf}`"))
- .help("the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)")
- .emit();
+ self.sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
}
}
LitError::InvalidFloatSuffix => {
@@ -1937,14 +1866,10 @@ impl<'a> Parser<'a> {
let suf = suf.as_str();
if looks_like_width_suffix(&['f'], suf) {
// If it looks like a width, try to be helpful.
- let msg = format!("invalid width `{}` for float literal", &suf[1..]);
- self.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit();
+ self.sess
+ .emit_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() });
} else {
- let msg = format!("invalid suffix `{suf}` for float literal");
- self.struct_span_err(span, &msg)
- .span_label(span, format!("invalid suffix `{suf}`"))
- .help("valid suffixes are `f32` and `f64`")
- .emit();
+ self.sess.emit_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() });
}
}
LitError::NonDecimalFloat(base) => {
@@ -1959,7 +1884,7 @@ impl<'a> Parser<'a> {
.emit();
}
LitError::IntTooLarge => {
- self.struct_span_err(span, "integer literal is too large").emit();
+ self.sess.emit_err(IntLiteralTooLarge { span });
}
}
}
@@ -2007,14 +1932,10 @@ impl<'a> Parser<'a> {
let lo = self.token.span;
let minus_present = self.eat(&token::BinOp(token::Minus));
let lit = self.parse_lit()?;
- let expr = self.mk_expr(lit.span, ExprKind::Lit(lit), AttrVec::new());
+ let expr = self.mk_expr(lit.span, ExprKind::Lit(lit));
if minus_present {
- Ok(self.mk_expr(
- lo.to(self.prev_token.span),
- self.mk_unary(UnOp::Neg, expr),
- AttrVec::new(),
- ))
+ Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_unary(UnOp::Neg, expr)))
} else {
Ok(expr)
}
@@ -2029,13 +1950,9 @@ impl<'a> Parser<'a> {
/// Emits a suggestion if it looks like the user meant an array but
/// accidentally used braces, causing the code to be interpreted as a block
/// expression.
- fn maybe_suggest_brackets_instead_of_braces(
- &mut self,
- lo: Span,
- attrs: AttrVec,
- ) -> Option<P<Expr>> {
+ fn maybe_suggest_brackets_instead_of_braces(&mut self, lo: Span) -> Option<P<Expr>> {
let mut snapshot = self.create_snapshot_for_diagnostic();
- match snapshot.parse_array_or_repeat_expr(attrs, Delimiter::Brace) {
+ match snapshot.parse_array_or_repeat_expr(Delimiter::Brace) {
Ok(arr) => {
let hi = snapshot.prev_token.span;
self.struct_span_err(arr.span, "this is a block expression, not an array")
@@ -2056,43 +1973,76 @@ impl<'a> Parser<'a> {
}
}
+ fn suggest_missing_semicolon_before_array(
+ &self,
+ prev_span: Span,
+ open_delim_span: Span,
+ ) -> PResult<'a, ()> {
+ if self.token.kind == token::Comma {
+ if !self.sess.source_map().is_multiline(prev_span.until(self.token.span)) {
+ return Ok(());
+ }
+ let mut snapshot = self.create_snapshot_for_diagnostic();
+ snapshot.bump();
+ match snapshot.parse_seq_to_before_end(
+ &token::CloseDelim(Delimiter::Bracket),
+ SeqSep::trailing_allowed(token::Comma),
+ |p| p.parse_expr(),
+ ) {
+ Ok(_)
+ // When the close delim is `)`, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
+ // but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
+ // This is because the `token.kind` of the close delim is treated as the same as
+ // that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
+ // Therefore, `token.kind` should not be compared here.
+ if snapshot
+ .span_to_snippet(snapshot.token.span)
+ .map_or(false, |snippet| snippet == "]") =>
+ {
+ return Err(MissingSemicolonBeforeArray {
+ open_delim: open_delim_span,
+ semicolon: prev_span.shrink_to_hi(),
+ }.into_diagnostic(&self.sess.span_diagnostic));
+ }
+ Ok(_) => (),
+ Err(err) => err.cancel(),
+ }
+ }
+ Ok(())
+ }
+
/// Parses a block or unsafe block.
pub(super) fn parse_block_expr(
&mut self,
opt_label: Option<Label>,
lo: Span,
blk_mode: BlockCheckMode,
- mut attrs: AttrVec,
) -> PResult<'a, P<Expr>> {
if self.is_array_like_block() {
- if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo, attrs.clone()) {
+ if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo) {
return Ok(arr);
}
}
- if let Some(label) = opt_label {
- self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
- }
-
if self.token.is_whole_block() {
- self.struct_span_err(self.token.span, "cannot use a `block` macro fragment here")
- .span_label(lo.to(self.token.span), "the `block` fragment is within this context")
- .emit();
+ self.sess.emit_err(InvalidBlockMacroSegment {
+ span: self.token.span,
+ context: lo.to(self.token.span),
+ });
}
- let (inner_attrs, blk) = self.parse_block_common(lo, blk_mode)?;
- attrs.extend(inner_attrs);
- Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
+ let (attrs, blk) = self.parse_block_common(lo, blk_mode)?;
+ Ok(self.mk_expr_with_attrs(blk.span, ExprKind::Block(blk, opt_label), attrs))
}
/// Parse a block which takes no attributes and has no label
fn parse_simple_block(&mut self) -> PResult<'a, P<Expr>> {
let blk = self.parse_block()?;
- Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()))
+ Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None)))
}
/// Parses a closure expression (e.g., `move |args| expr`).
- fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
let binder = if self.check_keyword(kw::For) {
@@ -2127,7 +2077,7 @@ impl<'a> Parser<'a> {
_ => {
// If an explicit return type is given, require a block to appear (RFC 968).
let body_lo = self.token.span;
- self.parse_block_expr(None, body_lo, BlockCheckMode::Default, AttrVec::new())?
+ self.parse_block_expr(None, body_lo, BlockCheckMode::Default)?
}
};
@@ -2158,7 +2108,6 @@ impl<'a> Parser<'a> {
body,
lo.to(decl_hi),
),
- attrs,
);
// Disable recovery for closure body
@@ -2221,10 +2170,10 @@ impl<'a> Parser<'a> {
Ok((
Param {
- attrs: attrs.into(),
+ attrs,
ty,
pat,
- span: lo.to(this.token.span),
+ span: lo.to(this.prev_token.span),
id: DUMMY_NODE_ID,
is_placeholder: false,
},
@@ -2234,19 +2183,13 @@ impl<'a> Parser<'a> {
}
/// Parses an `if` expression (`if` token already eaten).
- fn parse_if_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_if_expr(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.prev_token.span;
let cond = self.parse_cond_expr()?;
-
- self.parse_if_after_cond(attrs, lo, cond)
+ self.parse_if_after_cond(lo, cond)
}
- fn parse_if_after_cond(
- &mut self,
- attrs: AttrVec,
- lo: Span,
- mut cond: P<Expr>,
- ) -> PResult<'a, P<Expr>> {
+ fn parse_if_after_cond(&mut self, lo: Span, mut cond: P<Expr>) -> PResult<'a, P<Expr>> {
let cond_span = cond.span;
// Tries to interpret `cond` as either a missing expression if it's a block,
// or as an unfinished expression if it's a binop and the RHS is a block.
@@ -2255,11 +2198,19 @@ impl<'a> Parser<'a> {
let block = match &mut cond.kind {
ExprKind::Binary(Spanned { span: binop_span, .. }, _, right)
if let ExprKind::Block(_, None) = right.kind => {
- this.error_missing_if_then_block(lo, cond_span.shrink_to_lo().to(*binop_span), true).emit();
+ self.sess.emit_err(IfExpressionMissingThenBlock {
+ if_span: lo,
+ sub: IfExpressionMissingThenBlockSub::UnfinishedCondition(
+ cond_span.shrink_to_lo().to(*binop_span)
+ ),
+ });
std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi()))
},
ExprKind::Block(_, None) => {
- this.error_missing_if_cond(lo, cond_span).emit();
+ self.sess.emit_err(IfExpressionMissingCondition {
+ if_span: self.sess.source_map().next_point(lo),
+ block_span: self.sess.source_map().start_point(cond_span),
+ });
std::mem::replace(&mut cond, this.mk_expr_err(cond_span.shrink_to_hi()))
}
_ => {
@@ -2277,7 +2228,10 @@ impl<'a> Parser<'a> {
if let Some(block) = recover_block_from_condition(self) {
block
} else {
- self.error_missing_if_then_block(lo, cond_span, false).emit();
+ self.sess.emit_err(IfExpressionMissingThenBlock {
+ if_span: lo,
+ sub: IfExpressionMissingThenBlockSub::AddThenBlock(cond_span.shrink_to_hi()),
+ });
self.mk_block_err(cond_span.shrink_to_hi())
}
} else {
@@ -2302,45 +2256,13 @@ impl<'a> Parser<'a> {
block
};
let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None };
- Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els), attrs))
- }
-
- fn error_missing_if_then_block(
- &self,
- if_span: Span,
- cond_span: Span,
- is_unfinished: bool,
- ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- let mut err = self.struct_span_err(
- if_span,
- "this `if` expression is missing a block after the condition",
- );
- if is_unfinished {
- err.span_help(cond_span, "this binary operation is possibly unfinished");
- } else {
- err.span_help(cond_span.shrink_to_hi(), "add a block here");
- }
- err
- }
-
- fn error_missing_if_cond(
- &self,
- lo: Span,
- span: Span,
- ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- let next_span = self.sess.source_map().next_point(lo);
- let mut err = self.struct_span_err(next_span, "missing condition for `if` expression");
- err.span_label(next_span, "expected condition here");
- err.span_label(
- self.sess.source_map().start_point(span),
- "if this block is the condition of the `if` expression, then it must be followed by another block"
- );
- err
+ Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els)))
}
/// Parses the condition of a `if` or `while` expression.
fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
- let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)?;
+ let cond =
+ self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)?;
if let ExprKind::Let(..) = cond.kind {
// Remove the last feature gating of a `let` expression since it's stable.
@@ -2351,7 +2273,7 @@ impl<'a> Parser<'a> {
}
/// Parses a `let $pat = $expr` pseudo-expression.
- fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_let_expr(&mut self) -> PResult<'a, P<Expr>> {
// This is a *approximate* heuristic that detects if `let` chains are
// being parsed in the right position. It's approximate because it
// doesn't deny all invalid `let` expressions, just completely wrong usages.
@@ -2360,8 +2282,7 @@ impl<'a> Parser<'a> {
TokenKind::AndAnd | TokenKind::Ident(kw::If, _) | TokenKind::Ident(kw::While, _)
);
if !self.restrictions.contains(Restrictions::ALLOW_LET) || not_in_chain {
- self.struct_span_err(self.token.span, "expected expression, found `let` statement")
- .emit();
+ self.sess.emit_err(ExpectedExpressionFoundLet { span: self.token.span });
}
self.bump(); // Eat `let` token
@@ -2378,7 +2299,7 @@ impl<'a> Parser<'a> {
})?;
let span = lo.to(expr.span);
self.sess.gated_spans.gate(sym::let_chains, span);
- Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span), attrs))
+ Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span)))
}
/// Parses an `else { ... }` expression (`else` token already eaten).
@@ -2386,7 +2307,7 @@ impl<'a> Parser<'a> {
let else_span = self.prev_token.span; // `else`
let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
let expr = if self.eat_keyword(kw::If) {
- self.parse_if_expr(AttrVec::new())?
+ self.parse_if_expr()?
} else if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) {
self.parse_simple_block()?
} else {
@@ -2400,16 +2321,13 @@ impl<'a> Parser<'a> {
if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
&& classify::expr_requires_semi_to_be_stmt(&cond) =>
{
- self.struct_span_err(first_tok_span, format!("expected `{{`, found {first_tok}"))
- .span_label(else_span, "expected an `if` or a block after this `else`")
- .span_suggestion(
- cond.span.shrink_to_lo(),
- "add an `if` if this is the condition of a chained `else if` statement",
- "if ",
- Applicability::MaybeIncorrect,
- )
- .emit();
- self.parse_if_after_cond(AttrVec::new(), cond.span.shrink_to_lo(), cond)?
+ self.sess.emit_err(ExpectedElseBlock {
+ first_tok_span,
+ first_tok,
+ else_span,
+ condition_start: cond.span.shrink_to_lo(),
+ });
+ self.parse_if_after_cond(cond.span.shrink_to_lo(), cond)?
}
Err(e) => {
e.cancel();
@@ -2433,25 +2351,22 @@ impl<'a> Parser<'a> {
branch_span: Span,
attrs: &[ast::Attribute],
) {
- let (span, last) = match attrs {
+ let (attributes, last) = match attrs {
[] => return,
[x0 @ xn] | [x0, .., xn] => (x0.span.to(xn.span), xn.span),
};
let ctx = if is_ctx_else { "else" } else { "if" };
- self.struct_span_err(last, "outer attributes are not allowed on `if` and `else` branches")
- .span_label(branch_span, "the attributes are attached to this branch")
- .span_label(ctx_span, format!("the branch belongs to this `{ctx}`"))
- .span_suggestion(span, "remove the attributes", "", Applicability::MachineApplicable)
- .emit();
+ self.sess.emit_err(OuterAttributeNotAllowedOnIfElse {
+ last,
+ branch_span,
+ ctx_span,
+ ctx: ctx.to_string(),
+ attributes,
+ });
}
/// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
- fn parse_for_expr(
- &mut self,
- opt_label: Option<Label>,
- lo: Span,
- mut attrs: AttrVec,
- ) -> PResult<'a, P<Expr>> {
+ fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
// Record whether we are about to parse `for (`.
// This is used below for recovery in case of `for ( $stuff ) $block`
// in which case we will suggest `for $stuff $block`.
@@ -2474,63 +2389,51 @@ impl<'a> Parser<'a> {
let pat = self.recover_parens_around_for_head(pat, begin_paren);
- let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
- attrs.extend(iattrs);
+ let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);
- Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
+ Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
}
fn error_missing_in_for_loop(&mut self) {
- let (span, msg, sugg) = if self.token.is_ident_named(sym::of) {
+ let (span, sub): (_, fn(_) -> _) = if self.token.is_ident_named(sym::of) {
// Possibly using JS syntax (#75311).
let span = self.token.span;
self.bump();
- (span, "try using `in` here instead", "in")
+ (span, MissingInInForLoopSub::InNotOf)
} else {
- (self.prev_token.span.between(self.token.span), "try adding `in` here", " in ")
+ (self.prev_token.span.between(self.token.span), MissingInInForLoopSub::AddIn)
};
- self.struct_span_err(span, "missing `in` in `for` loop")
- .span_suggestion_short(
- span,
- msg,
- sugg,
- // Has been misleading, at least in the past (closed Issue #48492).
- Applicability::MaybeIncorrect,
- )
- .emit();
+
+ self.sess.emit_err(MissingInInForLoop { span, sub: sub(span) });
}
/// Parses a `while` or `while let` expression (`while` token already eaten).
- fn parse_while_expr(
- &mut self,
- opt_label: Option<Label>,
- lo: Span,
- mut attrs: AttrVec,
- ) -> PResult<'a, P<Expr>> {
+ fn parse_while_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
let cond = self.parse_cond_expr().map_err(|mut err| {
err.span_label(lo, "while parsing the condition of this `while` expression");
err
})?;
- let (iattrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| {
+ let (attrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| {
err.span_label(lo, "while parsing the body of this `while` expression");
err.span_label(cond.span, "this `while` condition successfully parsed");
err
})?;
- attrs.extend(iattrs);
- Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::While(cond, body, opt_label), attrs))
+ Ok(self.mk_expr_with_attrs(
+ lo.to(self.prev_token.span),
+ ExprKind::While(cond, body, opt_label),
+ attrs,
+ ))
}
/// Parses `loop { ... }` (`loop` token already eaten).
- fn parse_loop_expr(
- &mut self,
- opt_label: Option<Label>,
- lo: Span,
- mut attrs: AttrVec,
- ) -> PResult<'a, P<Expr>> {
- let (iattrs, body) = self.parse_inner_attrs_and_block()?;
- attrs.extend(iattrs);
- Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::Loop(body, opt_label), attrs))
+ fn parse_loop_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+ let (attrs, body) = self.parse_inner_attrs_and_block()?;
+ Ok(self.mk_expr_with_attrs(
+ lo.to(self.prev_token.span),
+ ExprKind::Loop(body, opt_label),
+ attrs,
+ ))
}
pub(crate) fn eat_label(&mut self) -> Option<Label> {
@@ -2541,7 +2444,7 @@ impl<'a> Parser<'a> {
}
/// Parses a `match ... { ... }` expression (`match` token already eaten).
- fn parse_match_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_match_expr(&mut self) -> PResult<'a, P<Expr>> {
let match_span = self.prev_token.span;
let lo = self.prev_token.span;
let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
@@ -2561,7 +2464,7 @@ impl<'a> Parser<'a> {
return Err(e);
}
}
- attrs.extend(self.parse_inner_attributes()?);
+ let attrs = self.parse_inner_attributes()?;
let mut arms: Vec<Arm> = Vec::new();
while self.token != token::CloseDelim(Delimiter::Brace) {
@@ -2575,13 +2478,17 @@ impl<'a> Parser<'a> {
if self.token == token::CloseDelim(Delimiter::Brace) {
self.bump();
}
- return Ok(self.mk_expr(span, ExprKind::Match(scrutinee, arms), attrs));
+ return Ok(self.mk_expr_with_attrs(
+ span,
+ ExprKind::Match(scrutinee, arms),
+ attrs,
+ ));
}
}
}
let hi = self.token.span;
self.bump();
- Ok(self.mk_expr(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
+ Ok(self.mk_expr_with_attrs(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
}
/// Attempt to recover from match arm body with statements and no surrounding braces.
@@ -2681,7 +2588,7 @@ impl<'a> Parser<'a> {
}
pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
- // Used to check the `let_chains` and `if_let_guard` features mostly by scaning
+ // Used to check the `let_chains` and `if_let_guard` features mostly by scanning
// `&&` tokens.
fn check_let_expr(expr: &Expr) -> (bool, bool) {
match expr.kind {
@@ -2756,7 +2663,7 @@ impl<'a> Parser<'a> {
let span = body.span;
return Ok((
ast::Arm {
- attrs: attrs.into(),
+ attrs,
pat,
guard,
body,
@@ -2811,17 +2718,9 @@ impl<'a> Parser<'a> {
.is_ok();
if pattern_follows && snapshot.check(&TokenKind::FatArrow) {
err.cancel();
- this.struct_span_err(
- hi.shrink_to_hi(),
- "expected `,` following `match` arm",
- )
- .span_suggestion(
- hi.shrink_to_hi(),
- "missing a comma here to end this `match` arm",
- ",",
- Applicability::MachineApplicable,
- )
- .emit();
+ this.sess.emit_err(MissingCommaAfterMatchArm {
+ span: hi.shrink_to_hi(),
+ });
return Ok(true);
}
}
@@ -2834,7 +2733,7 @@ impl<'a> Parser<'a> {
Ok((
ast::Arm {
- attrs: attrs.into(),
+ attrs,
pat,
guard,
body: expr,
@@ -2848,21 +2747,15 @@ impl<'a> Parser<'a> {
}
/// Parses a `try {...}` expression (`try` token already eaten).
- fn parse_try_block(&mut self, span_lo: Span, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
- let (iattrs, body) = self.parse_inner_attrs_and_block()?;
- attrs.extend(iattrs);
+ fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
+ let (attrs, body) = self.parse_inner_attrs_and_block()?;
if self.eat_keyword(kw::Catch) {
- let mut error = self.struct_span_err(
- self.prev_token.span,
- "keyword `catch` cannot follow a `try` block",
- );
- error.help("try using `match` on the result of the `try` block instead");
- error.emit();
- Err(error)
+ Err(CatchAfterTry { span: self.prev_token.span }
+ .into_diagnostic(&self.sess.span_diagnostic))
} else {
let span = span_lo.to(body.span);
self.sess.gated_spans.gate(sym::try_blocks, span);
- Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
+ Ok(self.mk_expr_with_attrs(span, ExprKind::TryBlock(body), attrs))
}
}
@@ -2884,14 +2777,13 @@ impl<'a> Parser<'a> {
}
/// Parses an `async move? {...}` expression.
- fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ fn parse_async_block(&mut self) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
self.expect_keyword(kw::Async)?;
let capture_clause = self.parse_capture_clause()?;
- let (iattrs, body) = self.parse_inner_attrs_and_block()?;
- attrs.extend(iattrs);
+ let (attrs, body) = self.parse_inner_attrs_and_block()?;
let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
- Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
+ Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
}
fn is_async_block(&self) -> bool {
@@ -2925,14 +2817,13 @@ impl<'a> Parser<'a> {
&mut self,
qself: Option<&ast::QSelf>,
path: &ast::Path,
- attrs: &AttrVec,
) -> Option<PResult<'a, P<Expr>>> {
let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
if struct_allowed || self.is_certainly_not_a_block() {
if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
return Some(Err(err));
}
- let expr = self.parse_struct_expr(qself.cloned(), path.clone(), attrs.clone(), true);
+ let expr = self.parse_struct_expr(qself.cloned(), path.clone(), true);
if let (Ok(expr), false) = (&expr, struct_allowed) {
// This is a struct literal, but we don't can't accept them here.
self.error_struct_lit_not_allowed_here(path.span, expr.span);
@@ -3069,7 +2960,6 @@ impl<'a> Parser<'a> {
&mut self,
qself: Option<ast::QSelf>,
pth: ast::Path,
- attrs: AttrVec,
recover: bool,
) -> PResult<'a, P<Expr>> {
let lo = pth.span;
@@ -3082,7 +2972,7 @@ impl<'a> Parser<'a> {
} else {
ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
};
- Ok(self.mk_expr(span, expr, attrs))
+ Ok(self.mk_expr(span, expr))
}
/// Use in case of error after field-looking code: `S { foo: () with a }`.
@@ -3110,18 +3000,10 @@ impl<'a> Parser<'a> {
if self.token != token::Comma {
return;
}
- self.struct_span_err(
- span.to(self.prev_token.span),
- "cannot use a comma after the base struct",
- )
- .span_suggestion_short(
- self.token.span,
- "remove this comma",
- "",
- Applicability::MachineApplicable,
- )
- .note("the base struct must always be the last field")
- .emit();
+ self.sess.emit_err(CommaAfterBaseStruct {
+ span: span.to(self.prev_token.span),
+ comma: self.token.span,
+ });
self.recover_stmt();
}
@@ -3137,7 +3019,7 @@ impl<'a> Parser<'a> {
// Mimic `x: x` for the `x` field shorthand.
let ident = this.parse_ident_common(false)?;
let path = ast::Path::from_ident(ident);
- (ident, this.mk_expr(ident.span, ExprKind::Path(None, path), AttrVec::new()))
+ (ident, this.mk_expr(ident.span, ExprKind::Path(None, path)))
} else {
let ident = this.parse_field_name()?;
this.error_on_eq_field_init(ident);
@@ -3151,7 +3033,7 @@ impl<'a> Parser<'a> {
span: lo.to(expr.span),
expr,
is_shorthand,
- attrs: attrs.into(),
+ attrs,
id: DUMMY_NODE_ID,
is_placeholder: false,
},
@@ -3167,43 +3049,18 @@ impl<'a> Parser<'a> {
return;
}
- self.struct_span_err(self.token.span, "expected `:`, found `=`")
- .span_suggestion(
- field_name.span.shrink_to_hi().to(self.token.span),
- "replace equals symbol with a colon",
- ":",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(EqFieldInit {
+ span: self.token.span,
+ eq: field_name.span.shrink_to_hi().to(self.token.span),
+ });
}
fn err_dotdotdot_syntax(&self, span: Span) {
- self.struct_span_err(span, "unexpected token: `...`")
- .span_suggestion(
- span,
- "use `..` for an exclusive range",
- "..",
- Applicability::MaybeIncorrect,
- )
- .span_suggestion(
- span,
- "or `..=` for an inclusive range",
- "..=",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ self.sess.emit_err(DotDotDot { span });
}
fn err_larrow_operator(&self, span: Span) {
- self.struct_span_err(span, "unexpected token: `<-`")
- .span_suggestion(
- span,
- "if you meant to write a comparison against a negative value, add a \
- space in between `<` and `-`",
- "< -",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ self.sess.emit_err(LeftArrowOperator { span });
}
fn mk_assign_op(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
@@ -3242,17 +3099,21 @@ impl<'a> Parser<'a> {
fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> {
let span = lo.to(self.prev_token.span);
- let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), AttrVec::new());
+ let await_expr = self.mk_expr(span, ExprKind::Await(self_arg));
self.recover_from_await_method_call();
await_expr
}
- pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
+ pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
}
+ pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> P<Expr> {
+ P(Expr { kind, span, attrs: AttrVec::new(), id: DUMMY_NODE_ID, tokens: None })
+ }
+
pub(super) fn mk_expr_err(&self, span: Span) -> P<Expr> {
- self.mk_expr(span, ExprKind::Err, AttrVec::new())
+ self.mk_expr(span, ExprKind::Err)
}
/// Create expression span ensuring the span of the parent node
@@ -3268,7 +3129,7 @@ impl<'a> Parser<'a> {
fn collect_tokens_for_expr(
&mut self,
attrs: AttrWrapper,
- f: impl FnOnce(&mut Self, Vec<ast::Attribute>) -> PResult<'a, P<Expr>>,
+ f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, P<Expr>>,
) -> PResult<'a, P<Expr>> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
let res = f(this, attrs)?;
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 1acfd93d8..4d0a8b05e 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -1,9 +1,7 @@
use super::{ForceCollect, Parser, TrailingToken};
use rustc_ast::token;
-use rustc_ast::{
- self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
-};
+use rustc_ast::{self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, WhereClause};
use rustc_errors::{Applicability, PResult};
use rustc_span::symbol::kw;
@@ -26,7 +24,7 @@ impl<'a> Parser<'a> {
}
/// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`.
- fn parse_ty_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
+ fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> {
let ident = self.parse_ident()?;
// Parse optional colon and param bounds.
@@ -43,7 +41,7 @@ impl<'a> Parser<'a> {
Ok(GenericParam {
ident,
id: ast::DUMMY_NODE_ID,
- attrs: preceding_attrs.into(),
+ attrs: preceding_attrs,
bounds,
kind: GenericParamKind::Type { default },
is_placeholder: false,
@@ -53,7 +51,7 @@ impl<'a> Parser<'a> {
pub(crate) fn parse_const_param(
&mut self,
- preceding_attrs: Vec<Attribute>,
+ preceding_attrs: AttrVec,
) -> PResult<'a, GenericParam> {
let const_span = self.token.span;
@@ -68,7 +66,7 @@ impl<'a> Parser<'a> {
Ok(GenericParam {
ident,
id: ast::DUMMY_NODE_ID,
- attrs: preceding_attrs.into(),
+ attrs: preceding_attrs,
bounds: Vec::new(),
kind: GenericParamKind::Const { ty, kw_span: const_span, default },
is_placeholder: false,
@@ -109,7 +107,7 @@ impl<'a> Parser<'a> {
Some(ast::GenericParam {
ident: lifetime.ident,
id: lifetime.id,
- attrs: attrs.into(),
+ attrs,
bounds,
kind: ast::GenericParamKind::Lifetime,
is_placeholder: false,
@@ -314,7 +312,6 @@ impl<'a> Parser<'a> {
span: lo.to(self.prev_token.span),
lhs_ty: ty,
rhs_ty,
- id: ast::DUMMY_NODE_ID,
}))
} else {
self.maybe_recover_bounds_doubled_colon(&ty)?;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 567072925..e55b5ce71 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -8,7 +8,7 @@ use rustc_ast::token::{self, Delimiter, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID};
use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
-use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
+use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind};
use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData};
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
@@ -22,7 +22,6 @@ use rustc_span::DUMMY_SP;
use std::convert::TryFrom;
use std::mem;
-use tracing::debug;
impl<'a> Parser<'a> {
/// Parses a source module as a crate. This is the main entry point for the parser.
@@ -32,7 +31,7 @@ impl<'a> Parser<'a> {
}
/// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
- fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
+ fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety();
self.expect_keyword(kw::Mod)?;
let id = self.parse_ident()?;
@@ -40,9 +39,9 @@ impl<'a> Parser<'a> {
ModKind::Unloaded
} else {
self.expect(&token::OpenDelim(Delimiter::Brace))?;
- let (mut inner_attrs, items, inner_span) =
+ let (inner_attrs, items, inner_span) =
self.parse_mod(&token::CloseDelim(Delimiter::Brace))?;
- attrs.append(&mut inner_attrs);
+ attrs.extend(inner_attrs);
ModKind::Loaded(items, Inline::Yes, inner_span)
};
Ok((id, ItemKind::Mod(unsafety, mod_kind)))
@@ -52,7 +51,7 @@ impl<'a> Parser<'a> {
pub fn parse_mod(
&mut self,
term: &TokenKind,
- ) -> PResult<'a, (Vec<Attribute>, Vec<P<Item>>, ModSpans)> {
+ ) -> PResult<'a, (AttrVec, Vec<P<Item>>, ModSpans)> {
let lo = self.token.span;
let attrs = self.parse_inner_attributes()?;
@@ -68,7 +67,12 @@ impl<'a> Parser<'a> {
if !self.maybe_consume_incorrect_semicolon(&items) {
let msg = &format!("expected item, found {token_str}");
let mut err = self.struct_span_err(self.token.span, msg);
- err.span_label(self.token.span, "expected item");
+ let label = if self.is_kw_followed_by_ident(kw::Let) {
+ "consider using `const` or `static` instead of `let` for global variables"
+ } else {
+ "expected item"
+ };
+ err.span_label(self.token.span, label);
return Err(err);
}
}
@@ -129,7 +133,7 @@ impl<'a> Parser<'a> {
fn parse_item_common_(
&mut self,
- mut attrs: Vec<Attribute>,
+ mut attrs: AttrVec,
mac_allowed: bool,
attrs_allowed: bool,
fn_parse_mode: FnParseMode,
@@ -193,7 +197,7 @@ impl<'a> Parser<'a> {
/// Parses one of the items allowed by the flags.
fn parse_item_kind(
&mut self,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
macros_allowed: bool,
lo: Span,
vis: &Visibility,
@@ -271,7 +275,10 @@ impl<'a> Parser<'a> {
// MACRO_RULES ITEM
self.parse_item_macro_rules(vis, has_bang)?
} else if self.isnt_macro_invocation()
- && (self.token.is_ident_named(sym::import) || self.token.is_ident_named(sym::using))
+ && (self.token.is_ident_named(sym::import)
+ || self.token.is_ident_named(sym::using)
+ || self.token.is_ident_named(sym::include)
+ || self.token.is_ident_named(sym::require))
{
return self.recover_import_as_use();
} else if self.isnt_macro_invocation() && vis.kind.is_pub() {
@@ -279,7 +286,7 @@ impl<'a> Parser<'a> {
return Ok(None);
} else if macros_allowed && self.check_path() {
// MACRO INVOCATION ITEM
- (Ident::empty(), ItemKind::MacCall(self.parse_item_macro(vis)?))
+ (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))
} else {
return Ok(None);
};
@@ -526,7 +533,7 @@ impl<'a> Parser<'a> {
/// ```
fn parse_item_impl(
&mut self,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
defaultness: Defaultness,
) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety();
@@ -653,12 +660,12 @@ impl<'a> Parser<'a> {
fn parse_item_list<T>(
&mut self,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
) -> PResult<'a, Vec<T>> {
let open_brace_span = self.token.span;
self.expect(&token::OpenDelim(Delimiter::Brace))?;
- attrs.append(&mut self.parse_inner_attributes()?);
+ attrs.extend(self.parse_inner_attributes()?);
let mut items = Vec::new();
while !self.eat(&token::CloseDelim(Delimiter::Brace)) {
@@ -667,14 +674,55 @@ impl<'a> Parser<'a> {
}
match parse_item(self) {
Ok(None) => {
+ let is_unnecessary_semicolon = !items.is_empty()
+ // When the close delim is `)` in a case like the following, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
+ // but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
+ // This is because the `token.kind` of the close delim is treated as the same as
+ // that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
+ // Therefore, `token.kind` should not be compared here.
+ //
+ // issue-60075.rs
+ // ```
+ // trait T {
+ // fn qux() -> Option<usize> {
+ // let _ = if true {
+ // });
+ // ^ this close delim
+ // Some(4)
+ // }
+ // ```
+ && self
+ .span_to_snippet(self.prev_token.span)
+ .map_or(false, |snippet| snippet == "}")
+ && self.token.kind == token::Semi;
+ let semicolon_span = self.token.span;
// We have to bail or we'll potentially never make progress.
let non_item_span = self.token.span;
+ let is_let = self.token.is_keyword(kw::Let);
+
+ let mut err = self.struct_span_err(non_item_span, "non-item in item list");
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
- self.struct_span_err(non_item_span, "non-item in item list")
- .span_label(open_brace_span, "item list starts here")
- .span_label(non_item_span, "non-item starts here")
- .span_label(self.prev_token.span, "item list ends here")
- .emit();
+ if is_let {
+ err.span_suggestion(
+ non_item_span,
+ "consider using `const` instead of `let` for associated const",
+ "const",
+ Applicability::MachineApplicable,
+ );
+ } else {
+ err.span_label(open_brace_span, "item list starts here")
+ .span_label(non_item_span, "non-item starts here")
+ .span_label(self.prev_token.span, "item list ends here");
+ }
+ if is_unnecessary_semicolon {
+ err.span_suggestion(
+ semicolon_span,
+ "consider removing this semicolon",
+ "",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ err.emit();
break;
}
Ok(Some(item)) => items.extend(item),
@@ -737,7 +785,7 @@ impl<'a> Parser<'a> {
}
/// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
- fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<'a, ItemInfo> {
+ fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety();
// Parse optional `auto` prefix.
let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
@@ -1023,7 +1071,7 @@ impl<'a> Parser<'a> {
/// ```
fn parse_item_foreign_mod(
&mut self,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
mut unsafety: Unsafe,
) -> PResult<'a, ItemInfo> {
let abi = self.parse_abi(); // ABI?
@@ -1124,6 +1172,16 @@ impl<'a> Parser<'a> {
Applicability::MaybeIncorrect,
)
.emit();
+ } else if self.eat_keyword(kw::Let) {
+ let span = self.prev_token.span;
+ self.struct_span_err(const_span.to(span), "`const` and `let` are mutually exclusive")
+ .span_suggestion(
+ const_span.to(span),
+ "remove `let`",
+ "const",
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
}
}
@@ -1131,7 +1189,7 @@ impl<'a> Parser<'a> {
fn recover_const_impl(
&mut self,
const_span: Span,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
defaultness: Defaultness,
) -> PResult<'a, ItemInfo> {
let impl_span = self.token.span;
@@ -1179,10 +1237,11 @@ impl<'a> Parser<'a> {
// Parse the type of a `const` or `static mut?` item.
// That is, the `":" $ty` fragment.
- let ty = if self.eat(&token::Colon) {
- self.parse_ty()?
- } else {
- self.recover_missing_const_type(id, m)
+ let ty = match (self.eat(&token::Colon), self.check(&token::Eq) | self.check(&token::Semi))
+ {
+ // If there wasn't a `:` or the colon was followed by a `=` or `;` recover a missing type.
+ (true, false) => self.parse_ty()?,
+ (colon, _) => self.recover_missing_const_type(colon, m),
};
let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
@@ -1190,9 +1249,9 @@ impl<'a> Parser<'a> {
Ok((id, ty, expr))
}
- /// We were supposed to parse `:` but the `:` was missing.
+ /// We were supposed to parse `":" $ty` but the `:` or the type was missing.
/// This means that the type is missing.
- fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
+ fn recover_missing_const_type(&mut self, colon_present: bool, m: Option<Mutability>) -> P<Ty> {
// Construct the error and stash it away with the hope
// that typeck will later enrich the error with a type.
let kind = match m {
@@ -1200,18 +1259,25 @@ impl<'a> Parser<'a> {
Some(Mutability::Not) => "static",
None => "const",
};
- let mut err = self.struct_span_err(id.span, &format!("missing type for `{kind}` item"));
+
+ let colon = match colon_present {
+ true => "",
+ false => ":",
+ };
+
+ let span = self.prev_token.span.shrink_to_hi();
+ let mut err = self.struct_span_err(span, &format!("missing type for `{kind}` item"));
err.span_suggestion(
- id.span,
+ span,
"provide a type for the item",
- format!("{id}: <type>"),
+ format!("{colon} <type>"),
Applicability::HasPlaceholders,
);
- err.stash(id.span, StashKey::ItemNoType);
+ err.stash(span, StashKey::ItemNoType);
// The user intended that the type be inferred,
// so treat this as if the user wrote e.g. `const A: _ = expr;`.
- P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID, tokens: None })
+ P(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
}
/// Parses an enum declaration.
@@ -1281,7 +1347,7 @@ impl<'a> Parser<'a> {
ident,
vis,
id: DUMMY_NODE_ID,
- attrs: variant_attrs.into(),
+ attrs: variant_attrs,
data: struct_def,
disr_expr,
span: vlo.to(this.prev_token.span),
@@ -1438,7 +1504,7 @@ impl<'a> Parser<'a> {
ident: None,
id: DUMMY_NODE_ID,
ty,
- attrs: attrs.into(),
+ attrs,
is_placeholder: false,
},
TrailingToken::MaybeComma,
@@ -1464,13 +1530,24 @@ impl<'a> Parser<'a> {
adt_ty: &str,
lo: Span,
vis: Visibility,
- attrs: Vec<Attribute>,
+ attrs: AttrVec,
) -> PResult<'a, FieldDef> {
let mut seen_comma: bool = false;
let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?;
if self.token == token::Comma {
seen_comma = true;
}
+ if self.eat(&token::Semi) {
+ let sp = self.prev_token.span;
+ let mut err = self.struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
+ err.span_suggestion_short(
+ sp,
+ "replace `;` with `,`",
+ ",",
+ Applicability::MachineApplicable,
+ );
+ return Err(err);
+ }
match self.token.kind {
token::Comma => {
self.bump();
@@ -1528,8 +1605,12 @@ impl<'a> Parser<'a> {
}
}
- if self.token.is_ident() {
- // This is likely another field; emit the diagnostic and keep going
+ if self.token.is_ident()
+ || (self.token.kind == TokenKind::Pound
+ && (self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Bracket))))
+ {
+ // This is likely another field, TokenKind::Pound is used for `#[..]` attribute for next field,
+ // emit the diagnostic and keep going
err.span_suggestion(
sp,
"try adding a comma",
@@ -1590,7 +1671,7 @@ impl<'a> Parser<'a> {
adt_ty: &str,
lo: Span,
vis: Visibility,
- attrs: Vec<Attribute>,
+ attrs: AttrVec,
) -> PResult<'a, FieldDef> {
let name = self.parse_field_ident(adt_ty, lo)?;
self.expect_field_ty_separator()?;
@@ -1624,7 +1705,7 @@ impl<'a> Parser<'a> {
vis,
id: DUMMY_NODE_ID,
ty,
- attrs: attrs.into(),
+ attrs,
is_placeholder: false,
})
}
@@ -1643,7 +1724,7 @@ impl<'a> Parser<'a> {
// We use `parse_fn` to get a span for the function
let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
if let Err(mut db) =
- self.parse_fn(&mut Vec::new(), fn_parse_mode, lo, &inherited_vis)
+ self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis)
{
db.delay_as_bug();
}
@@ -1919,7 +2000,7 @@ impl<'a> Parser<'a> {
/// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
fn parse_fn(
&mut self,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
fn_parse_mode: FnParseMode,
sig_lo: Span,
vis: &Visibility,
@@ -1942,7 +2023,7 @@ impl<'a> Parser<'a> {
/// or e.g. a block when the function is a provided one.
fn parse_fn_body(
&mut self,
- attrs: &mut Vec<Attribute>,
+ attrs: &mut AttrVec,
ident: &Ident,
sig_hi: &mut Span,
req_body: bool,
@@ -1957,7 +2038,7 @@ impl<'a> Parser<'a> {
// Include the trailing semicolon in the span of the signature
self.expect_semi()?;
*sig_hi = self.prev_token.span;
- (Vec::new(), None)
+ (AttrVec::new(), None)
} else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() {
self.parse_inner_attrs_and_block().map(|(attrs, body)| (attrs, Some(body)))?
} else if self.token.kind == token::Eq {
@@ -1974,7 +2055,7 @@ impl<'a> Parser<'a> {
Applicability::MachineApplicable,
)
.emit();
- (Vec::new(), Some(self.mk_block_err(span)))
+ (AttrVec::new(), Some(self.mk_block_err(span)))
} else {
let expected = if req_body {
&[token::OpenDelim(Delimiter::Brace)][..]
@@ -1991,7 +2072,7 @@ impl<'a> Parser<'a> {
return Err(err);
}
}
- (Vec::new(), None)
+ (AttrVec::new(), None)
};
attrs.extend(inner_attrs);
Ok(body)
@@ -2220,7 +2301,7 @@ impl<'a> Parser<'a> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
if let Some(mut param) = this.parse_self_param()? {
- param.attrs = attrs.into();
+ param.attrs = attrs;
let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
return Ok((res?, TrailingToken::None));
}
@@ -2249,7 +2330,7 @@ impl<'a> Parser<'a> {
(pat, this.parse_ty_for_param()?)
} else {
debug!("parse_param_general ident_to_pat");
- let parser_snapshot_before_ty = this.clone();
+ let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
this.eat_incorrect_doc_comment_for_param_type();
let mut ty = this.parse_ty_for_param();
if ty.is_ok()
@@ -2263,7 +2344,7 @@ impl<'a> Parser<'a> {
match ty {
Ok(ty) => {
let ident = Ident::new(kw::Empty, this.prev_token.span);
- let bm = BindingMode::ByValue(Mutability::Not);
+ let bm = BindingAnnotation::NONE;
let pat = this.mk_pat_ident(ty.span, bm, ident);
(pat, ty)
}
@@ -2272,23 +2353,16 @@ impl<'a> Parser<'a> {
// Recover from attempting to parse the argument as a type without pattern.
Err(err) => {
err.cancel();
- *this = parser_snapshot_before_ty;
+ this.restore_snapshot(parser_snapshot_before_ty);
this.recover_arg_parse()?
}
}
};
- let span = lo.until(this.token.span);
+ let span = lo.to(this.prev_token.span);
Ok((
- Param {
- attrs: attrs.into(),
- id: ast::DUMMY_NODE_ID,
- is_placeholder: false,
- pat,
- span,
- ty,
- },
+ Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
TrailingToken::None,
))
})
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 0c523ad22..4cb198561 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -37,7 +37,6 @@ use rustc_errors::{
use rustc_session::parse::ParseSess;
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use tracing::debug;
use std::ops::Range;
use std::{cmp, mem, slice};
@@ -171,7 +170,7 @@ pub struct ClosureSpans {
/// attribute, we parse a nested AST node that has `#[cfg]` or `#[cfg_attr]`
/// In this case, we use a `ReplaceRange` to replace the entire inner AST node
/// with `FlatToken::AttrTarget`, allowing us to perform eager cfg-expansion
-/// on an `AttrAnnotatedTokenStream`
+/// on an `AttrTokenStream`.
///
/// 2. When we parse an inner attribute while collecting tokens. We
/// remove inner attributes from the token stream entirely, and
@@ -184,7 +183,7 @@ pub type ReplaceRange = (Range<u32>, Vec<(FlatToken, Spacing)>);
/// Controls how we capture tokens. Capturing can be expensive,
/// so we try to avoid performing capturing in cases where
-/// we will never need an `AttrAnnotatedTokenStream`
+/// we will never need an `AttrTokenStream`.
#[derive(Copy, Clone)]
pub enum Capturing {
/// We aren't performing any capturing - this is the default mode.
@@ -238,7 +237,7 @@ struct TokenCursor {
// the trailing `>>` token. The `break_last_token`
// field is used to track this token - it gets
// appended to the captured stream when
- // we evaluate a `LazyTokenStream`
+ // we evaluate a `LazyAttrTokenStream`.
break_last_token: bool,
}
@@ -281,7 +280,7 @@ impl TokenCursor {
if delim != Delimiter::Invisible {
return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone);
}
- // No open delimeter to return; continue on to the next iteration.
+ // No open delimiter to return; continue on to the next iteration.
}
};
} else if let Some(frame) = self.stack.pop() {
@@ -1116,10 +1115,14 @@ impl<'a> Parser<'a> {
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
let anon_const = AnonConst {
id: DUMMY_NODE_ID,
- value: self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()),
+ value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
};
let blk_span = anon_const.value.span;
- Ok(self.mk_expr(span.to(blk_span), ExprKind::ConstBlock(anon_const), AttrVec::from(attrs)))
+ Ok(self.mk_expr_with_attrs(
+ span.to(blk_span),
+ ExprKind::ConstBlock(anon_const),
+ AttrVec::from(attrs),
+ ))
}
/// Parses mutability (`mut` or nothing).
@@ -1295,7 +1298,11 @@ impl<'a> Parser<'a> {
self.bump(); // `in`
let path = self.parse_path(PathStyle::Mod)?; // `path`
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
- let vis = VisibilityKind::Restricted { path: P(path), id: ast::DUMMY_NODE_ID };
+ let vis = VisibilityKind::Restricted {
+ path: P(path),
+ id: ast::DUMMY_NODE_ID,
+ shorthand: false,
+ };
return Ok(Visibility {
span: lo.to(self.prev_token.span),
kind: vis,
@@ -1308,7 +1315,11 @@ impl<'a> Parser<'a> {
self.bump(); // `(`
let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self`
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
- let vis = VisibilityKind::Restricted { path: P(path), id: ast::DUMMY_NODE_ID };
+ let vis = VisibilityKind::Restricted {
+ path: P(path),
+ id: ast::DUMMY_NODE_ID,
+ shorthand: true,
+ };
return Ok(Visibility {
span: lo.to(self.prev_token.span),
kind: vis,
@@ -1371,7 +1382,7 @@ impl<'a> Parser<'a> {
match self.parse_str_lit() {
Ok(str_lit) => Some(str_lit),
Err(Some(lit)) => match lit.kind {
- ast::LitKind::Err(_) => None,
+ ast::LitKind::Err => None,
_ => {
self.struct_span_err(lit.span, "non-string ABI literal")
.span_suggestion(
@@ -1453,11 +1464,11 @@ pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, sess: &Pa
}
}
-/// A helper struct used when building an `AttrAnnotatedTokenStream` from
-/// a `LazyTokenStream`. Both delimiter and non-delimited tokens
+/// A helper struct used when building an `AttrTokenStream` from
+/// a `LazyAttrTokenStream`. Both delimiter and non-delimited tokens
/// are stored as `FlatToken::Token`. A vector of `FlatToken`s
-/// is then 'parsed' to build up an `AttrAnnotatedTokenStream` with nested
-/// `AttrAnnotatedTokenTree::Delimited` tokens
+/// is then 'parsed' to build up an `AttrTokenStream` with nested
+/// `AttrTokenTree::Delimited` tokens.
#[derive(Debug, Clone)]
pub enum FlatToken {
/// A token - this holds both delimiter (e.g. '{' and '}')
@@ -1465,11 +1476,11 @@ pub enum FlatToken {
Token(Token),
/// Holds the `AttributesData` for an AST node. The
/// `AttributesData` is inserted directly into the
- /// constructed `AttrAnnotatedTokenStream` as
- /// an `AttrAnnotatedTokenTree::Attributes`
+ /// constructed `AttrTokenStream` as
+ /// an `AttrTokenTree::Attributes`.
AttrTarget(AttributesData),
/// A special 'empty' token that is ignored during the conversion
- /// to an `AttrAnnotatedTokenStream`. This is used to simplify the
+ /// to an `AttrTokenStream`. This is used to simplify the
/// handling of replace ranges.
Empty,
}
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index e215b6872..103dd8012 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -66,18 +66,18 @@ impl<'a> Parser<'a> {
},
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr { .. } => {
match token.kind {
- token::Ident(..) | // box, ref, mut, and other identifiers (can stricten)
- token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern
- token::OpenDelim(Delimiter::Bracket) | // slice pattern
- token::BinOp(token::And) | // reference
- token::BinOp(token::Minus) | // negative literal
- token::AndAnd | // double reference
- token::Literal(..) | // literal
- token::DotDot | // range pattern (future compat)
- token::DotDotDot | // range pattern (future compat)
- token::ModSep | // path
- token::Lt | // path (UFCS constant)
- token::BinOp(token::Shl) => true, // path (double UFCS)
+ token::Ident(..) | // box, ref, mut, and other identifiers (can stricten)
+ token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern
+ token::OpenDelim(Delimiter::Bracket) | // slice pattern
+ token::BinOp(token::And) | // reference
+ token::BinOp(token::Minus) | // negative literal
+ token::AndAnd | // double reference
+ token::Literal(..) | // literal
+ token::DotDot | // range pattern (future compat)
+ token::DotDotDot | // range pattern (future compat)
+ token::ModSep | // path
+ token::Lt | // path (UFCS constant)
+ token::BinOp(token::Shl) => true, // path (double UFCS)
// leading vert `|` or-pattern
token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr {..}),
token::Interpolated(ref nt) => may_be_ident(nt),
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index ba77a3958..120a3c267 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,10 +1,11 @@
use super::{ForceCollect, Parser, PathStyle, TrailingToken};
+use crate::parser::diagnostics::RemoveLet;
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter};
use rustc_ast::{
- self as ast, AttrVec, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat,
+ self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
};
use rustc_ast_pretty::pprust;
@@ -320,7 +321,13 @@ impl<'a> Parser<'a> {
maybe_recover_from_interpolated_ty_qpath!(self, true);
maybe_whole!(self, NtPat, |x| x);
- let lo = self.token.span;
+ let mut lo = self.token.span;
+
+ if self.token.is_keyword(kw::Let) && self.look_ahead(1, |tok| tok.can_begin_pattern()) {
+ self.bump();
+ self.sess.emit_err(RemoveLet { span: lo });
+ lo = self.token.span;
+ }
let pat = if self.check(&token::BinOp(token::And)) || self.token.kind == token::AndAnd {
self.parse_pat_deref(expected)?
@@ -353,7 +360,7 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(kw::Ref) {
// Parse ref ident @ pat / ref mut ident @ pat
let mutbl = self.parse_mutability();
- self.parse_pat_ident(BindingMode::ByRef(mutbl))?
+ self.parse_pat_ident(BindingAnnotation(ByRef::Yes, mutbl))?
} else if self.eat_keyword(kw::Box) {
self.parse_pat_box()?
} else if self.check_inline_const(0) {
@@ -369,7 +376,7 @@ impl<'a> Parser<'a> {
// Parse `ident @ pat`
// This can give false positives and parse nullary enums,
// they are dealt with later in resolve.
- self.parse_pat_ident(BindingMode::ByValue(Mutability::Not))?
+ self.parse_pat_ident(BindingAnnotation::NONE)?
} else if self.is_start_of_pat_with_path() {
// Parse pattern starting with a path
let (qself, path) = if self.eat_lt() {
@@ -385,7 +392,7 @@ impl<'a> Parser<'a> {
if qself.is_none() && self.check(&token::Not) {
self.parse_pat_mac_invoc(path)?
} else if let Some(form) = self.parse_range_end() {
- let begin = self.mk_expr(span, ExprKind::Path(qself, path), AttrVec::new());
+ let begin = self.mk_expr(span, ExprKind::Path(qself, path));
self.parse_pat_range_begin_with(begin, form)?
} else if self.check(&token::OpenDelim(Delimiter::Brace)) {
self.parse_pat_struct(qself, path)?
@@ -578,7 +585,8 @@ impl<'a> Parser<'a> {
let mut pat = self.parse_pat_no_top_alt(Some("identifier"))?;
// If we don't have `mut $ident (@ pat)?`, error.
- if let PatKind::Ident(BindingMode::ByValue(m @ Mutability::Not), ..) = &mut pat.kind {
+ if let PatKind::Ident(BindingAnnotation(ByRef::No, m @ Mutability::Not), ..) = &mut pat.kind
+ {
// Don't recurse into the subpattern.
// `mut` on the outer binding doesn't affect the inner bindings.
*m = Mutability::Mut;
@@ -604,7 +612,7 @@ impl<'a> Parser<'a> {
)
.emit();
- self.parse_pat_ident(BindingMode::ByRef(Mutability::Mut))
+ self.parse_pat_ident(BindingAnnotation::REF_MUT)
}
/// Turn all by-value immutable bindings in a pattern into mutable bindings.
@@ -613,7 +621,8 @@ impl<'a> Parser<'a> {
struct AddMut(bool);
impl MutVisitor for AddMut {
fn visit_pat(&mut self, pat: &mut P<Pat>) {
- if let PatKind::Ident(BindingMode::ByValue(m @ Mutability::Not), ..) = &mut pat.kind
+ if let PatKind::Ident(BindingAnnotation(ByRef::No, m @ Mutability::Not), ..) =
+ &mut pat.kind
{
self.0 = true;
*m = Mutability::Mut;
@@ -665,7 +674,7 @@ impl<'a> Parser<'a> {
fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> {
self.bump();
let args = self.parse_mac_args()?;
- let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription };
+ let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
Ok(PatKind::MacCall(mac))
}
@@ -807,7 +816,7 @@ impl<'a> Parser<'a> {
(None, self.parse_path(PathStyle::Expr)?)
};
let hi = self.prev_token.span;
- Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path), AttrVec::new()))
+ Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path)))
} else {
self.parse_literal_maybe_minus()
}
@@ -838,7 +847,7 @@ impl<'a> Parser<'a> {
/// Parses `ident` or `ident @ pat`.
/// Used by the copy foo and ref foo patterns to give a good
/// error message when parsing mistakes like `ref foo(a, b)`.
- fn parse_pat_ident(&mut self, binding_mode: BindingMode) -> PResult<'a, PatKind> {
+ fn parse_pat_ident(&mut self, binding_annotation: BindingAnnotation) -> PResult<'a, PatKind> {
let ident = self.parse_ident()?;
let sub = if self.eat(&token::At) {
Some(self.parse_pat_no_top_alt(Some("binding pattern"))?)
@@ -856,7 +865,7 @@ impl<'a> Parser<'a> {
.struct_span_err(self.prev_token.span, "expected identifier, found enum pattern"));
}
- Ok(PatKind::Ident(binding_mode, ident, sub))
+ Ok(PatKind::Ident(binding_annotation, ident, sub))
}
/// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
@@ -936,11 +945,7 @@ impl<'a> Parser<'a> {
None
};
- Ok(PatKind::Ident(
- BindingMode::ByValue(Mutability::Not),
- Ident::new(kw::Box, box_span),
- sub,
- ))
+ Ok(PatKind::Ident(BindingAnnotation::NONE, Ident::new(kw::Box, box_span), sub))
} else {
let pat = self.parse_pat_with_range_pat(false, None)?;
self.sess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span));
@@ -1093,7 +1098,7 @@ impl<'a> Parser<'a> {
.emit();
}
- fn parse_pat_field(&mut self, lo: Span, attrs: Vec<Attribute>) -> PResult<'a, PatField> {
+ fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField> {
// Check if a colon exists one ahead. This means we're parsing a fieldname.
let hi;
let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
@@ -1117,14 +1122,12 @@ impl<'a> Parser<'a> {
let fieldname = self.parse_field_name()?;
hi = self.prev_token.span;
- let bind_type = match (is_ref, is_mut) {
- (true, true) => BindingMode::ByRef(Mutability::Mut),
- (true, false) => BindingMode::ByRef(Mutability::Not),
- (false, true) => BindingMode::ByValue(Mutability::Mut),
- (false, false) => BindingMode::ByValue(Mutability::Not),
+ let mutability = match is_mut {
+ false => Mutability::Not,
+ true => Mutability::Mut,
};
-
- let fieldpat = self.mk_pat_ident(boxed_span.to(hi), bind_type, fieldname);
+ let ann = BindingAnnotation(ByRef::from(is_ref), mutability);
+ let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname);
let subpat =
if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat };
(subpat, fieldname, true)
@@ -1134,15 +1137,15 @@ impl<'a> Parser<'a> {
ident: fieldname,
pat: subpat,
is_shorthand,
- attrs: attrs.into(),
+ attrs,
id: ast::DUMMY_NODE_ID,
span: lo.to(hi),
is_placeholder: false,
})
}
- pub(super) fn mk_pat_ident(&self, span: Span, bm: BindingMode, ident: Ident) -> P<Pat> {
- self.mk_pat(span, PatKind::Ident(bm, ident, None))
+ pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingAnnotation, ident: Ident) -> P<Pat> {
+ self.mk_pat(span, PatKind::Ident(ann, ident, None))
}
pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 5cf1758c3..fdc1af27f 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -13,7 +13,6 @@ use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym, Ident};
use std::mem;
-use tracing::debug;
/// Specifies how to parse a path.
#[derive(Copy, Clone, PartialEq)]
@@ -527,7 +526,7 @@ impl<'a> Parser<'a> {
Ok(ident_gen_args) => ident_gen_args,
Err(()) => return Ok(Some(AngleBracketedArg::Arg(arg))),
};
- if binder.is_some() {
+ if binder {
// FIXME(compiler-errors): this could be improved by suggesting lifting
// this up to the trait, at least before this becomes real syntax.
// e.g. `Trait<for<'a> Assoc = Ty>` -> `for<'a> Trait<Assoc = Ty>`
@@ -652,12 +651,7 @@ impl<'a> Parser<'a> {
pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> {
// Parse const argument.
let value = if let token::OpenDelim(Delimiter::Brace) = self.token.kind {
- self.parse_block_expr(
- None,
- self.token.span,
- BlockCheckMode::Default,
- ast::AttrVec::new(),
- )?
+ self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)?
} else {
self.handle_unambiguous_unbraced_const_arg()?
};
@@ -725,28 +719,24 @@ impl<'a> Parser<'a> {
/// Given a arg inside of generics, we try to destructure it as if it were the LHS in
/// `LHS = ...`, i.e. an associated type binding.
- /// This returns (optionally, if they are present) any `for<'a, 'b>` binder args, the
+ /// This returns a bool indicating if there are any `for<'a, 'b>` binder args, the
/// identifier, and any GAT arguments.
fn get_ident_from_generic_arg(
&self,
gen_arg: &GenericArg,
- ) -> Result<(Option<Vec<ast::GenericParam>>, Ident, Option<GenericArgs>), ()> {
+ ) -> Result<(bool, Ident, Option<GenericArgs>), ()> {
if let GenericArg::Type(ty) = gen_arg {
if let ast::TyKind::Path(qself, path) = &ty.kind
&& qself.is_none()
&& let [seg] = path.segments.as_slice()
{
- return Ok((None, seg.ident, seg.args.as_deref().cloned()));
+ return Ok((false, seg.ident, seg.args.as_deref().cloned()));
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
&& let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None)] =
bounds.as_slice()
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
{
- return Ok((
- Some(trait_ref.bound_generic_params.clone()),
- seg.ident,
- seg.args.as_deref().cloned(),
- ));
+ return Ok((true, seg.ident, seg.args.as_deref().cloned()));
}
}
Err(())
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 51bd9d2d3..3d957406b 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -1,5 +1,7 @@
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
-use super::diagnostics::{AttemptLocalParseRecovery, Error};
+use super::diagnostics::{
+ AttemptLocalParseRecovery, Error, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
+};
use super::expr::LhsExpr;
use super::pat::RecoverComma;
use super::path::PathStyle;
@@ -34,7 +36,7 @@ impl<'a> Parser<'a> {
}))
}
- /// If `force_capture` is true, forces collection of tokens regardless of whether
+ /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of whether
/// or not we have attributes
pub(crate) fn parse_stmt_without_recovery(
&mut self,
@@ -55,18 +57,25 @@ impl<'a> Parser<'a> {
return Ok(Some(stmt.into_inner()));
}
+ if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
+ self.bump();
+ let mut_let_span = lo.to(self.token.span);
+ self.sess.emit_err(InvalidVariableDeclaration {
+ span: mut_let_span,
+ sub: InvalidVariableDeclarationSub::SwitchMutLetOrder(mut_let_span),
+ });
+ }
+
Ok(Some(if self.token.is_keyword(kw::Let) {
self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
} else if self.is_kw_followed_by_ident(kw::Mut) {
- self.recover_stmt_local(lo, attrs, "missing keyword", "let mut")?
+ self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
} else if self.is_kw_followed_by_ident(kw::Auto) {
self.bump(); // `auto`
- let msg = "write `let` instead of `auto` to introduce a new variable";
- self.recover_stmt_local(lo, attrs, msg, "let")?
+ self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)?
} else if self.is_kw_followed_by_ident(sym::var) {
self.bump(); // `var`
- let msg = "write `let` instead of `var` to introduce a new variable";
- self.recover_stmt_local(lo, attrs, msg, "let")?
+ self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)?
} else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
// We have avoided contextual keywords like `union`, items with `crate` visibility,
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
@@ -121,7 +130,7 @@ impl<'a> Parser<'a> {
let path = this.parse_path(PathStyle::Expr)?;
if this.eat(&token::Not) {
- let stmt_mac = this.parse_stmt_mac(lo, attrs.into(), path)?;
+ let stmt_mac = this.parse_stmt_mac(lo, attrs, path)?;
if this.token == token::Semi {
return Ok((stmt_mac, TrailingToken::Semi));
} else {
@@ -130,10 +139,10 @@ impl<'a> Parser<'a> {
}
let expr = if this.eat(&token::OpenDelim(Delimiter::Brace)) {
- this.parse_struct_expr(None, path, AttrVec::new(), true)?
+ this.parse_struct_expr(None, path, true)?
} else {
let hi = this.prev_token.span;
- this.mk_expr(lo.to(hi), ExprKind::Path(None, path), AttrVec::new())
+ this.mk_expr(lo.to(hi), ExprKind::Path(None, path))
};
let expr = this.with_res(Restrictions::STMT_EXPR, |this| {
@@ -168,7 +177,7 @@ impl<'a> Parser<'a> {
None => unreachable!(),
};
- let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription };
+ let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
let kind = if (style == MacStmtStyle::Braces
&& self.token != token::Dot
@@ -179,9 +188,9 @@ impl<'a> Parser<'a> {
StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
} else {
// Since none of the above applied, this is an expression statement macro.
- let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
+ let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
let e = self.maybe_recover_from_bad_qpath(e)?;
- let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
+ let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
StmtKind::Expr(e)
};
@@ -204,13 +213,10 @@ impl<'a> Parser<'a> {
&mut self,
lo: Span,
attrs: AttrWrapper,
- msg: &str,
- sugg: &str,
+ subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub,
) -> PResult<'a, Stmt> {
let stmt = self.recover_local_after_let(lo, attrs)?;
- self.struct_span_err(lo, "invalid variable declaration")
- .span_suggestion(lo, msg, sugg, Applicability::MachineApplicable)
- .emit();
+ self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
Ok(stmt)
}
@@ -223,7 +229,7 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Stmt> {
self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| {
this.expect_keyword(kw::Let)?;
- let local = this.parse_local(attrs.into())?;
+ let local = this.parse_local(attrs)?;
let trailing = if capture_semi && this.token.kind == token::Semi {
TrailingToken::Semi
} else {
@@ -235,7 +241,7 @@ impl<'a> Parser<'a> {
fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
- let local = this.parse_local(attrs.into())?;
+ let local = this.parse_local(attrs)?;
// FIXME - maybe capture semicolon in recovery?
Ok((
this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)),
@@ -247,6 +253,22 @@ impl<'a> Parser<'a> {
/// Parses a local variable declaration.
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
let lo = self.prev_token.span;
+
+ if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
+ self.struct_span_err(
+ lo.to(self.token.span),
+ "`const` and `let` are mutually exclusive",
+ )
+ .span_suggestion(
+ lo.to(self.token.span),
+ "remove `let`",
+ "const",
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ self.bump();
+ }
+
let (pat, colon) = self.parse_pat_before_ty(None, RecoverComma::Yes, "`let` bindings")?;
let (err, ty) = if colon {
@@ -487,9 +509,7 @@ impl<'a> Parser<'a> {
}
/// Parses a block. Inner attributes are allowed.
- pub(super) fn parse_inner_attrs_and_block(
- &mut self,
- ) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
+ pub(super) fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (AttrVec, P<Block>)> {
self.parse_block_common(self.token.span, BlockCheckMode::Default)
}
@@ -498,8 +518,8 @@ impl<'a> Parser<'a> {
&mut self,
lo: Span,
blk_mode: BlockCheckMode,
- ) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
- maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
+ ) -> PResult<'a, (AttrVec, P<Block>)> {
+ maybe_whole!(self, NtBlock, |x| (AttrVec::new(), x));
self.maybe_recover_unexpected_block_label();
if !self.eat(&token::OpenDelim(Delimiter::Brace)) {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 31b40a83e..b47f0c097 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -567,7 +567,8 @@ impl<'a> Parser<'a> {
self.check_keyword(kw::Dyn)
&& (!self.token.uninterpolated_span().rust_2015()
|| self.look_ahead(1, |t| {
- t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t)
+ (t.can_begin_bound() || t.kind == TokenKind::BinOp(token::Star))
+ && !can_continue_type_after_non_fn_ident(t)
}))
}
@@ -576,10 +577,18 @@ impl<'a> Parser<'a> {
/// Note that this does *not* parse bare trait objects.
fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
self.bump(); // `dyn`
+
+ // parse dyn* types
+ let syntax = if self.eat(&TokenKind::BinOp(token::Star)) {
+ TraitObjectSyntax::DynStar
+ } else {
+ TraitObjectSyntax::Dyn
+ };
+
// Always parse bounds greedily for better error recovery.
let bounds = self.parse_generic_bounds(None)?;
*impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
- Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn))
+ Ok(TyKind::TraitObject(bounds, syntax))
}
/// Parses a type starting with a path.
@@ -598,11 +607,11 @@ impl<'a> Parser<'a> {
let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
if self.eat(&token::Not) {
// Macro invocation in type position
- Ok(TyKind::MacCall(MacCall {
+ Ok(TyKind::MacCall(P(MacCall {
path,
args: self.parse_mac_args()?,
prior_type_ascription: self.last_type_ascription,
- }))
+ })))
} else if allow_plus == AllowPlus::Yes && self.check_plus() {
// `Trait1 + Trait2 + 'a`
self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
@@ -640,7 +649,13 @@ impl<'a> Parser<'a> {
let mut bounds = Vec::new();
let mut negative_bounds = Vec::new();
- while self.can_begin_bound() || self.token.is_keyword(kw::Dyn) {
+ while self.can_begin_bound()
+ // Continue even if we find a keyword.
+ // This is necessary for error recover on, for example, `impl fn()`.
+ //
+ // The only keyword that can go after generic bounds is `where`, so stop if it's it.
+ || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))
+ {
if self.token.is_keyword(kw::Dyn) {
// Account for `&dyn Trait + dyn Other`.
self.struct_span_err(self.token.span, "invalid `dyn` keyword")
@@ -804,6 +819,20 @@ impl<'a> Parser<'a> {
let span = tilde.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::const_trait_impl, span);
Some(span)
+ } else if self.eat_keyword(kw::Const) {
+ let span = self.prev_token.span;
+ self.sess.gated_spans.gate(sym::const_trait_impl, span);
+
+ self.struct_span_err(span, "const bounds must start with `~`")
+ .span_suggestion(
+ span.shrink_to_lo(),
+ "add `~`",
+ "~",
+ Applicability::MachineApplicable,
+ )
+ .emit();
+
+ Some(span)
} else {
None
};
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 4890fade5..a9e502016 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -9,6 +9,8 @@
html_playground_url = "https://play.rust-lang.org/",
test(attr(deny(warnings)))
)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
// We want to be able to build this crate with a stable compiler, so no
// `#![feature]` attributes should be added.
@@ -165,6 +167,8 @@ pub enum Count<'a> {
CountIsName(&'a str, InnerSpan),
/// The count is specified by the argument at the given index.
CountIsParam(usize),
+ /// The count is specified by a star (like in `{:.*}`) that refers to the argument at the given index.
+ CountIsStar(usize),
/// The count is implied and cannot be explicitly specified.
CountImplied,
}
@@ -262,9 +266,7 @@ impl<'a> Iterator for Parser<'a> {
}
} else {
if self.is_literal {
- let start = self.to_span_index(self.cur_line_start);
- let end = self.to_span_index(self.input.len());
- let span = start.to(end);
+ let span = self.span(self.cur_line_start, self.input.len());
if self.line_spans.last() != Some(&span) {
self.line_spans.push(span);
}
@@ -382,6 +384,12 @@ impl<'a> Parser<'a> {
InnerOffset(raw + pos + 1)
}
+ fn span(&self, start_pos: usize, end_pos: usize) -> InnerSpan {
+ let start = self.to_span_index(start_pos);
+ let end = self.to_span_index(end_pos);
+ start.to(end)
+ }
+
/// Forces consumption of the specified character. If the character is not
/// found, an error is emitted.
fn must_consume(&mut self, c: char) -> Option<usize> {
@@ -470,9 +478,7 @@ impl<'a> Parser<'a> {
return &self.input[start..pos];
}
'\n' if self.is_literal => {
- let start = self.to_span_index(self.cur_line_start);
- let end = self.to_span_index(pos);
- self.line_spans.push(start.to(end));
+ self.line_spans.push(self.span(self.cur_line_start, pos));
self.cur_line_start = pos + 1;
self.cur.next();
}
@@ -535,6 +541,10 @@ impl<'a> Parser<'a> {
}
}
+ fn current_pos(&mut self) -> usize {
+ if let Some(&(pos, _)) = self.cur.peek() { pos } else { self.input.len() }
+ }
+
/// Parses a format specifier at the current position, returning all of the
/// relevant information in the `FormatSpec` struct.
fn format(&mut self) -> FormatSpec<'a> {
@@ -588,39 +598,37 @@ impl<'a> Parser<'a> {
// no '0' flag and '0$' as the width instead.
if let Some(end) = self.consume_pos('$') {
spec.width = CountIsParam(0);
-
- if let Some((pos, _)) = self.cur.peek().cloned() {
- spec.width_span = Some(self.to_span_index(pos - 2).to(self.to_span_index(pos)));
- }
+ spec.width_span = Some(self.span(end - 1, end + 1));
havewidth = true;
- spec.width_span = Some(self.to_span_index(end - 1).to(self.to_span_index(end + 1)));
} else {
spec.flags |= 1 << (FlagSignAwareZeroPad as u32);
}
}
+
if !havewidth {
- let width_span_start = if let Some((pos, _)) = self.cur.peek() { *pos } else { 0 };
- let (w, sp) = self.count(width_span_start);
- spec.width = w;
- spec.width_span = sp;
+ let start = self.current_pos();
+ spec.width = self.count(start);
+ if spec.width != CountImplied {
+ let end = self.current_pos();
+ spec.width_span = Some(self.span(start, end));
+ }
}
if let Some(start) = self.consume_pos('.') {
- if let Some(end) = self.consume_pos('*') {
+ if self.consume('*') {
// Resolve `CountIsNextParam`.
// We can do this immediately as `position` is resolved later.
let i = self.curarg;
self.curarg += 1;
- spec.precision = CountIsParam(i);
- spec.precision_span =
- Some(self.to_span_index(start).to(self.to_span_index(end + 1)));
+ spec.precision = CountIsStar(i);
} else {
- let (p, sp) = self.count(start);
- spec.precision = p;
- spec.precision_span = sp;
+ spec.precision = self.count(start + 1);
}
+ let end = self.current_pos();
+ spec.precision_span = Some(self.span(start, end));
}
- let ty_span_start = self.cur.peek().map(|(pos, _)| *pos);
+
+ let ty_span_start = self.current_pos();
// Optional radix followed by the actual format specifier
if self.consume('x') {
if self.consume('?') {
@@ -640,11 +648,9 @@ impl<'a> Parser<'a> {
spec.ty = "?";
} else {
spec.ty = self.word();
- let ty_span_end = self.cur.peek().map(|(pos, _)| *pos);
if !spec.ty.is_empty() {
- spec.ty_span = ty_span_start
- .and_then(|s| ty_span_end.map(|e| (s, e)))
- .map(|(start, end)| self.to_span_index(start).to(self.to_span_index(end)));
+ let ty_span_end = self.current_pos();
+ spec.ty_span = Some(self.span(ty_span_start, ty_span_end));
}
}
spec
@@ -668,13 +674,11 @@ impl<'a> Parser<'a> {
return spec;
}
- let ty_span_start = self.cur.peek().map(|(pos, _)| *pos);
+ let ty_span_start = self.current_pos();
spec.ty = self.word();
- let ty_span_end = self.cur.peek().map(|(pos, _)| *pos);
if !spec.ty.is_empty() {
- spec.ty_span = ty_span_start
- .and_then(|s| ty_span_end.map(|e| (s, e)))
- .map(|(start, end)| self.to_span_index(start).to(self.to_span_index(end)));
+ let ty_span_end = self.current_pos();
+ spec.ty_span = Some(self.span(ty_span_start, ty_span_end));
}
spec
@@ -683,26 +687,21 @@ impl<'a> Parser<'a> {
/// Parses a `Count` parameter at the current position. This does not check
/// for 'CountIsNextParam' because that is only used in precision, not
/// width.
- fn count(&mut self, start: usize) -> (Count<'a>, Option<InnerSpan>) {
+ fn count(&mut self, start: usize) -> Count<'a> {
if let Some(i) = self.integer() {
- if let Some(end) = self.consume_pos('$') {
- let span = self.to_span_index(start).to(self.to_span_index(end + 1));
- (CountIsParam(i), Some(span))
- } else {
- (CountIs(i), None)
- }
+ if self.consume('$') { CountIsParam(i) } else { CountIs(i) }
} else {
let tmp = self.cur.clone();
let word = self.word();
if word.is_empty() {
self.cur = tmp;
- (CountImplied, None)
+ CountImplied
} else if let Some(end) = self.consume_pos('$') {
- let span = self.to_span_index(start + 1).to(self.to_span_index(end));
- (CountIsName(word, span), None)
+ let name_span = self.span(start, end);
+ CountIsName(word, name_span)
} else {
self.cur = tmp;
- (CountImplied, None)
+ CountImplied
}
}
}
@@ -735,7 +734,7 @@ impl<'a> Parser<'a> {
"invalid argument name `_`",
"invalid argument name",
"argument name cannot be a single underscore",
- self.to_span_index(start).to(self.to_span_index(end)),
+ self.span(start, end),
);
}
word
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index 578530696..2f8c229c6 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -1,5 +1,6 @@
use super::*;
+#[track_caller]
fn same(fmt: &'static str, p: &[Piece<'static>]) {
let parser = Parser::new(fmt, None, None, false, ParseMode::Format);
assert_eq!(parser.collect::<Vec<Piece<'static>>>(), p);
@@ -190,9 +191,9 @@ fn format_counts() {
align: AlignUnknown,
flags: 0,
precision: CountImplied,
- width: CountIs(10),
precision_span: None,
- width_span: None,
+ width: CountIs(10),
+ width_span: Some(InnerSpan { start: 3, end: 5 }),
ty: "x",
ty_span: None,
},
@@ -208,9 +209,9 @@ fn format_counts() {
align: AlignUnknown,
flags: 0,
precision: CountIs(10),
+ precision_span: Some(InnerSpan { start: 6, end: 9 }),
width: CountIsParam(10),
- precision_span: None,
- width_span: Some(InnerSpan::new(3, 6)),
+ width_span: Some(InnerSpan { start: 3, end: 6 }),
ty: "x",
ty_span: None,
},
@@ -226,9 +227,9 @@ fn format_counts() {
align: AlignUnknown,
flags: 0,
precision: CountIs(10),
+ precision_span: Some(InnerSpan { start: 6, end: 9 }),
width: CountIsParam(0),
- precision_span: None,
- width_span: Some(InnerSpan::new(4, 6)),
+ width_span: Some(InnerSpan { start: 4, end: 6 }),
ty: "x",
ty_span: None,
},
@@ -243,9 +244,9 @@ fn format_counts() {
fill: None,
align: AlignUnknown,
flags: 0,
- precision: CountIsParam(0),
+ precision: CountIsStar(0),
+ precision_span: Some(InnerSpan { start: 3, end: 5 }),
width: CountImplied,
- precision_span: Some(InnerSpan::new(3, 5)),
width_span: None,
ty: "x",
ty_span: None,
@@ -279,15 +280,33 @@ fn format_counts() {
fill: None,
align: AlignUnknown,
flags: 0,
- precision: CountIsName("b", InnerSpan::new(6, 7)),
- width: CountIsName("a", InnerSpan::new(4, 4)),
- precision_span: None,
- width_span: None,
+ precision: CountIsName("b", InnerSpan { start: 6, end: 7 }),
+ precision_span: Some(InnerSpan { start: 5, end: 8 }),
+ width: CountIsName("a", InnerSpan { start: 3, end: 4 }),
+ width_span: Some(InnerSpan { start: 3, end: 5 }),
ty: "?",
ty_span: None,
},
})],
);
+ same(
+ "{:.4}",
+ &[NextArgument(Argument {
+ position: ArgumentImplicitlyIs(0),
+ position_span: InnerSpan { start: 2, end: 2 },
+ format: FormatSpec {
+ fill: None,
+ align: AlignUnknown,
+ flags: 0,
+ precision: CountIs(4),
+ precision_span: Some(InnerSpan { start: 3, end: 5 }),
+ width: CountImplied,
+ width_span: None,
+ ty: "",
+ ty_span: None,
+ },
+ })],
+ )
}
#[test]
fn format_flags() {
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a2ac329f2..b3f15ba7c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -16,6 +16,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID};
use rustc_hir::{MethodKind, Target};
use rustc_middle::hir::nested_filter;
+use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
@@ -130,6 +131,7 @@ impl CheckAttrVisitor<'_> {
| sym::rustc_if_this_changed
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
+ sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
sym::const_trait => self.check_const_trait(attr, span, target),
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
sym::must_use => self.check_must_use(hir_id, &attr, span, target),
@@ -146,6 +148,7 @@ impl CheckAttrVisitor<'_> {
| sym::stable
| sym::rustc_allowed_through_unstable_modules
| sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
+ sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
_ => true,
};
is_valid &= attr_is_valid;
@@ -171,6 +174,7 @@ impl CheckAttrVisitor<'_> {
sym::no_implicit_prelude => {
self.check_generic_attr(hir_id, attr, target, &[Target::Mod])
}
+ sym::rustc_object_lifetime_default => self.check_object_lifetime_default(hir_id),
_ => {}
}
@@ -209,7 +213,14 @@ impl CheckAttrVisitor<'_> {
}
// FIXME(@lcnr): this doesn't belong here.
- if matches!(target, Target::Closure | Target::Fn | Target::Method(_) | Target::ForeignFn) {
+ if matches!(
+ target,
+ Target::Closure
+ | Target::Fn
+ | Target::Method(_)
+ | Target::ForeignFn
+ | Target::ForeignStatic
+ ) {
self.tcx.ensure().codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id));
}
@@ -402,6 +413,38 @@ impl CheckAttrVisitor<'_> {
}
}
+ /// Debugging aid for `object_lifetime_default` query.
+ fn check_object_lifetime_default(&self, hir_id: HirId) {
+ let tcx = self.tcx;
+ if let Some(generics) = tcx.hir().get_generics(tcx.hir().local_def_id(hir_id)) {
+ for p in generics.params {
+ let hir::GenericParamKind::Type { .. } = p.kind else { continue };
+ let param_id = tcx.hir().local_def_id(p.hir_id);
+ let default = tcx.object_lifetime_default(param_id);
+ let repr = match default {
+ ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
+ ObjectLifetimeDefault::Static => "'static".to_owned(),
+ ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
+ ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
+ };
+ tcx.sess.span_err(p.span, &repr);
+ }
+ }
+ }
+
+ /// Checks if `#[collapse_debuginfo]` is applied to a macro.
+ fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) -> bool {
+ match target {
+ Target::MacroDef => true,
+ _ => {
+ self.tcx
+ .sess
+ .emit_err(errors::CollapseDebuginfo { attr_span: attr.span, defn_span: span });
+ false
+ }
+ }
+ }
+
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
fn check_track_caller(
&self,
@@ -632,6 +675,7 @@ impl CheckAttrVisitor<'_> {
| Target::GlobalAsm
| Target::TyAlias
| Target::OpaqueTy
+ | Target::ImplTraitPlaceholder
| Target::Enum
| Target::Variant
| Target::Struct
@@ -644,7 +688,9 @@ impl CheckAttrVisitor<'_> {
| Target::ForeignStatic
| Target::ForeignTy
| Target::GenericParam(..)
- | Target::MacroDef => None,
+ | Target::MacroDef
+ | Target::PatField
+ | Target::ExprField => None,
} {
tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location });
return false;
@@ -1620,6 +1666,8 @@ impl CheckAttrVisitor<'_> {
E0552,
"unrecognized representation hint"
)
+ .help("valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, \
+ `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`")
.emit();
continue;
@@ -1886,6 +1934,16 @@ impl CheckAttrVisitor<'_> {
}
}
+ fn check_link_ordinal(&self, attr: &Attribute, _span: Span, target: Target) -> bool {
+ match target {
+ Target::ForeignFn | Target::ForeignStatic => true,
+ _ => {
+ self.tcx.sess.emit_err(errors::LinkOrdinal { attr_span: attr.span });
+ false
+ }
+ }
+ }
+
fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: Span, target: Target) {
match target {
Target::Closure | Target::Expression | Target::Statement | Target::Arm => {
@@ -2048,14 +2106,14 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
intravisit::walk_expr(self, expr)
}
- fn visit_variant(
- &mut self,
- variant: &'tcx hir::Variant<'tcx>,
- generics: &'tcx hir::Generics<'tcx>,
- item_id: HirId,
- ) {
+ fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+ self.check_attributes(field.hir_id, field.span, Target::ExprField, None);
+ intravisit::walk_expr_field(self, field)
+ }
+
+ fn visit_variant(&mut self, variant: &'tcx hir::Variant<'tcx>) {
self.check_attributes(variant.id, variant.span, Target::Variant, None);
- intravisit::walk_variant(self, variant, generics, item_id)
+ intravisit::walk_variant(self, variant)
}
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
@@ -2063,6 +2121,11 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
intravisit::walk_param(self, param);
}
+
+ fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+ self.check_attributes(field.hir_id, field.span, Target::PatField, None);
+ intravisit::walk_pat_field(self, field);
+ }
}
fn is_c_like_enum(item: &Item<'_>) -> bool {
@@ -2092,6 +2155,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
sym::automatically_derived,
sym::start,
sym::rustc_main,
+ sym::unix_sigpipe,
sym::derive,
sym::test,
sym::test_case,
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 1e2fbeb38..f141d7bee 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -226,19 +226,16 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
lhs: &hir::Pat<'_>,
res: Res,
pats: &[hir::Pat<'_>],
- dotdot: Option<usize>,
+ dotdot: hir::DotDotPos,
) {
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
ty::Adt(adt, _) => adt.variant_of_res(res),
_ => span_bug!(lhs.span, "non-ADT in tuple struct pattern"),
};
- let first_n = pats.iter().enumerate().take(dotdot.unwrap_or(pats.len()));
+ let dotdot = dotdot.as_opt_usize().unwrap_or(pats.len());
+ let first_n = pats.iter().enumerate().take(dotdot);
let missing = variant.fields.len() - pats.len();
- let last_n = pats
- .iter()
- .enumerate()
- .skip(dotdot.unwrap_or(pats.len()))
- .map(|(idx, pat)| (idx + missing, pat));
+ let last_n = pats.iter().enumerate().skip(dotdot).map(|(idx, pat)| (idx + missing, pat));
for (idx, pat) in first_n.chain(last_n) {
if let PatKind::Wild = pat.kind {
continue;
@@ -368,14 +365,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
self.maybe_typeck_results = old_maybe_typeck_results;
}
- fn visit_variant_data(
- &mut self,
- def: &'tcx hir::VariantData<'tcx>,
- _: Symbol,
- _: &hir::Generics<'_>,
- _: hir::HirId,
- _: rustc_span::Span,
- ) {
+ fn visit_variant_data(&mut self, def: &'tcx hir::VariantData<'tcx>) {
let tcx = self.tcx;
let has_repr_c = self.repr_has_repr_c;
let has_repr_simd = self.repr_has_repr_simd;
@@ -457,7 +447,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
}
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
- if let TyKind::OpaqueDef(item_id, _) = ty.kind {
+ if let TyKind::OpaqueDef(item_id, _, _) = ty.kind {
let item = self.tcx.hir().item(item_id);
intravisit::walk_item(self, item);
}
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 7381019a6..cd10170d3 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,11 +1,11 @@
-use rustc_ast::{entry::EntryPointType, Attribute};
+use rustc_ast::entry::EntryPointType;
use rustc_errors::struct_span_err;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::{ItemId, Node, CRATE_HIR_ID};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{DefIdTree, TyCtxt};
-use rustc_session::config::{CrateType, EntryFnType};
+use rustc_session::config::{sigpipe, CrateType, EntryFnType};
use rustc_session::parse::feature_err;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol, DUMMY_SP};
@@ -71,14 +71,12 @@ fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> Entry
}
}
-fn err_if_attr_found(ctxt: &EntryContext<'_>, attrs: &[Attribute], sym: Symbol) {
+fn err_if_attr_found(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol, details: &str) {
+ let attrs = ctxt.tcx.hir().attrs(id.hir_id());
if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym) {
ctxt.tcx
.sess
- .struct_span_err(
- attr.span,
- &format!("`{}` attribute can only be used on functions", sym),
- )
+ .struct_span_err(attr.span, &format!("`{}` attribute {}", sym, details))
.emit();
}
}
@@ -87,14 +85,16 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
let at_root = ctxt.tcx.opt_local_parent(id.def_id) == Some(CRATE_DEF_ID);
match entry_point_type(ctxt, id, at_root) {
- EntryPointType::None => (),
+ EntryPointType::None => {
+ err_if_attr_found(ctxt, id, sym::unix_sigpipe, "can only be used on `fn main()`");
+ }
_ if !matches!(ctxt.tcx.def_kind(id.def_id), DefKind::Fn) => {
- let attrs = ctxt.tcx.hir().attrs(id.hir_id());
- err_if_attr_found(ctxt, attrs, sym::start);
- err_if_attr_found(ctxt, attrs, sym::rustc_main);
+ err_if_attr_found(ctxt, id, sym::start, "can only be used on functions");
+ err_if_attr_found(ctxt, id, sym::rustc_main, "can only be used on functions");
}
EntryPointType::MainNamed => (),
EntryPointType::OtherMain => {
+ err_if_attr_found(ctxt, id, sym::unix_sigpipe, "can only be used on root `fn main()`");
ctxt.non_main_fns.push(ctxt.tcx.def_span(id.def_id));
}
EntryPointType::RustcMainAttr => {
@@ -116,6 +116,7 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
}
}
EntryPointType::Start => {
+ err_if_attr_found(ctxt, id, sym::unix_sigpipe, "can only be used on `fn main()`");
if ctxt.start_fn.is_none() {
ctxt.start_fn = Some((id.def_id, ctxt.tcx.def_span(id.def_id.to_def_id())));
} else {
@@ -136,8 +137,9 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
if let Some((def_id, _)) = visitor.start_fn {
Some((def_id.to_def_id(), EntryFnType::Start))
- } else if let Some((def_id, _)) = visitor.attr_main_fn {
- Some((def_id.to_def_id(), EntryFnType::Main))
+ } else if let Some((local_def_id, _)) = visitor.attr_main_fn {
+ let def_id = local_def_id.to_def_id();
+ Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }))
} else {
if let Some(main_def) = tcx.resolutions(()).main_def && let Some(def_id) = main_def.opt_fn_def_id() {
// non-local main imports are handled below
@@ -161,13 +163,39 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
)
.emit();
}
- return Some((def_id, EntryFnType::Main));
+ return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }));
}
no_main_err(tcx, visitor);
None
}
}
+fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
+ if let Some(attr) = tcx.get_attr(def_id, sym::unix_sigpipe) {
+ match (attr.value_str(), attr.meta_item_list()) {
+ (Some(sym::inherit), None) => sigpipe::INHERIT,
+ (Some(sym::sig_ign), None) => sigpipe::SIG_IGN,
+ (Some(sym::sig_dfl), None) => sigpipe::SIG_DFL,
+ (_, Some(_)) => {
+ // Keep going so that `fn emit_malformed_attribute()` can print
+ // an excellent error message
+ sigpipe::DEFAULT
+ }
+ _ => {
+ tcx.sess
+ .struct_span_err(
+ attr.span,
+ "valid values for `#[unix_sigpipe = \"...\"]` are `inherit`, `sig_ign`, or `sig_dfl`",
+ )
+ .emit();
+ sigpipe::DEFAULT
+ }
+ }
+ } else {
+ sigpipe::DEFAULT
+ }
+}
+
fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
let sp = tcx.def_span(CRATE_DEF_ID);
if *tcx.sess.parse_sess.reached_eof.borrow() {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 5feb0e295..96cc8ae98 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -3,37 +3,37 @@ use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
use rustc_span::{Span, Symbol};
#[derive(LintDiagnostic)]
-#[lint(passes::outer_crate_level_attr)]
+#[diag(passes::outer_crate_level_attr)]
pub struct OuterCrateLevelAttr;
#[derive(LintDiagnostic)]
-#[lint(passes::inner_crate_level_attr)]
+#[diag(passes::inner_crate_level_attr)]
pub struct InnerCrateLevelAttr;
#[derive(LintDiagnostic)]
-#[lint(passes::ignored_attr_with_macro)]
+#[diag(passes::ignored_attr_with_macro)]
pub struct IgnoredAttrWithMacro<'a> {
pub sym: &'a str,
}
#[derive(LintDiagnostic)]
-#[lint(passes::ignored_attr)]
+#[diag(passes::ignored_attr)]
pub struct IgnoredAttr<'a> {
pub sym: &'a str,
}
#[derive(LintDiagnostic)]
-#[lint(passes::inline_ignored_function_prototype)]
+#[diag(passes::inline_ignored_function_prototype)]
pub struct IgnoredInlineAttrFnProto;
#[derive(LintDiagnostic)]
-#[lint(passes::inline_ignored_constants)]
-#[warn_]
+#[diag(passes::inline_ignored_constants)]
+#[warning]
#[note]
pub struct IgnoredInlineAttrConstants;
#[derive(SessionDiagnostic)]
-#[error(passes::inline_not_fn_or_closure, code = "E0518")]
+#[diag(passes::inline_not_fn_or_closure, code = "E0518")]
pub struct InlineNotFnOrClosure {
#[primary_span]
pub attr_span: Span,
@@ -42,19 +42,19 @@ pub struct InlineNotFnOrClosure {
}
#[derive(LintDiagnostic)]
-#[lint(passes::no_coverage_ignored_function_prototype)]
+#[diag(passes::no_coverage_ignored_function_prototype)]
pub struct IgnoredNoCoverageFnProto;
#[derive(LintDiagnostic)]
-#[lint(passes::no_coverage_propagate)]
+#[diag(passes::no_coverage_propagate)]
pub struct IgnoredNoCoveragePropagate;
#[derive(LintDiagnostic)]
-#[lint(passes::no_coverage_fn_defn)]
+#[diag(passes::no_coverage_fn_defn)]
pub struct IgnoredNoCoverageFnDefn;
#[derive(SessionDiagnostic)]
-#[error(passes::no_coverage_not_coverable, code = "E0788")]
+#[diag(passes::no_coverage_not_coverable, code = "E0788")]
pub struct IgnoredNoCoverageNotCoverable {
#[primary_span]
pub attr_span: Span,
@@ -63,7 +63,7 @@ pub struct IgnoredNoCoverageNotCoverable {
}
#[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_fn)]
+#[diag(passes::should_be_applied_to_fn)]
pub struct AttrShouldBeAppliedToFn {
#[primary_span]
pub attr_span: Span,
@@ -72,14 +72,14 @@ pub struct AttrShouldBeAppliedToFn {
}
#[derive(SessionDiagnostic)]
-#[error(passes::naked_tracked_caller, code = "E0736")]
+#[diag(passes::naked_tracked_caller, code = "E0736")]
pub struct NakedTrackedCaller {
#[primary_span]
pub attr_span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_fn, code = "E0739")]
+#[diag(passes::should_be_applied_to_fn, code = "E0739")]
pub struct TrackedCallerWrongLocation {
#[primary_span]
pub attr_span: Span,
@@ -88,7 +88,7 @@ pub struct TrackedCallerWrongLocation {
}
#[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_struct_enum, code = "E0701")]
+#[diag(passes::should_be_applied_to_struct_enum, code = "E0701")]
pub struct NonExhaustiveWrongLocation {
#[primary_span]
pub attr_span: Span,
@@ -97,7 +97,7 @@ pub struct NonExhaustiveWrongLocation {
}
#[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_trait)]
+#[diag(passes::should_be_applied_to_trait)]
pub struct AttrShouldBeAppliedToTrait {
#[primary_span]
pub attr_span: Span,
@@ -106,11 +106,11 @@ pub struct AttrShouldBeAppliedToTrait {
}
#[derive(LintDiagnostic)]
-#[lint(passes::target_feature_on_statement)]
+#[diag(passes::target_feature_on_statement)]
pub struct TargetFeatureOnStatement;
#[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_static)]
+#[diag(passes::should_be_applied_to_static)]
pub struct AttrShouldBeAppliedToStatic {
#[primary_span]
pub attr_span: Span,
@@ -119,7 +119,7 @@ pub struct AttrShouldBeAppliedToStatic {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_expect_str)]
+#[diag(passes::doc_expect_str)]
pub struct DocExpectStr<'a> {
#[primary_span]
pub attr_span: Span,
@@ -127,7 +127,7 @@ pub struct DocExpectStr<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_empty)]
+#[diag(passes::doc_alias_empty)]
pub struct DocAliasEmpty<'a> {
#[primary_span]
pub span: Span,
@@ -135,7 +135,7 @@ pub struct DocAliasEmpty<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_bad_char)]
+#[diag(passes::doc_alias_bad_char)]
pub struct DocAliasBadChar<'a> {
#[primary_span]
pub span: Span,
@@ -144,7 +144,7 @@ pub struct DocAliasBadChar<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_start_end)]
+#[diag(passes::doc_alias_start_end)]
pub struct DocAliasStartEnd<'a> {
#[primary_span]
pub span: Span,
@@ -152,7 +152,7 @@ pub struct DocAliasStartEnd<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_bad_location)]
+#[diag(passes::doc_alias_bad_location)]
pub struct DocAliasBadLocation<'a> {
#[primary_span]
pub span: Span,
@@ -161,7 +161,7 @@ pub struct DocAliasBadLocation<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_not_an_alias)]
+#[diag(passes::doc_alias_not_an_alias)]
pub struct DocAliasNotAnAlias<'a> {
#[primary_span]
pub span: Span,
@@ -169,42 +169,42 @@ pub struct DocAliasNotAnAlias<'a> {
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_alias_duplicated)]
+#[diag(passes::doc_alias_duplicated)]
pub struct DocAliasDuplicated {
#[label]
pub first_defn: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_not_string_literal)]
+#[diag(passes::doc_alias_not_string_literal)]
pub struct DocAliasNotStringLiteral {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_malformed)]
+#[diag(passes::doc_alias_malformed)]
pub struct DocAliasMalformed {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_empty_mod)]
+#[diag(passes::doc_keyword_empty_mod)]
pub struct DocKeywordEmptyMod {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_not_mod)]
+#[diag(passes::doc_keyword_not_mod)]
pub struct DocKeywordNotMod {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_invalid_ident)]
+#[diag(passes::doc_keyword_invalid_ident)]
pub struct DocKeywordInvalidIdent {
#[primary_span]
pub span: Span,
@@ -212,21 +212,21 @@ pub struct DocKeywordInvalidIdent {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_fake_variadic_not_valid)]
+#[diag(passes::doc_fake_variadic_not_valid)]
pub struct DocFakeVariadicNotValid {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_only_impl)]
+#[diag(passes::doc_keyword_only_impl)]
pub struct DocKeywordOnlyImpl {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_inline_conflict)]
+#[diag(passes::doc_inline_conflict)]
#[help]
pub struct DocKeywordConflict {
#[primary_span]
@@ -234,7 +234,7 @@ pub struct DocKeywordConflict {
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_inline_only_use)]
+#[diag(passes::doc_inline_only_use)]
#[note]
pub struct DocInlineOnlyUse {
#[label]
@@ -244,7 +244,7 @@ pub struct DocInlineOnlyUse {
}
#[derive(SessionDiagnostic)]
-#[error(passes::doc_attr_not_crate_level)]
+#[diag(passes::doc_attr_not_crate_level)]
pub struct DocAttrNotCrateLevel<'a> {
#[primary_span]
pub span: Span,
@@ -252,27 +252,27 @@ pub struct DocAttrNotCrateLevel<'a> {
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown)]
+#[diag(passes::doc_test_unknown)]
pub struct DocTestUnknown {
pub path: String,
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_test_takes_list)]
+#[diag(passes::doc_test_takes_list)]
pub struct DocTestTakesList;
#[derive(LintDiagnostic)]
-#[lint(passes::doc_primitive)]
+#[diag(passes::doc_primitive)]
pub struct DocPrimitive;
#[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown_any)]
+#[diag(passes::doc_test_unknown_any)]
pub struct DocTestUnknownAny {
pub path: String,
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown_spotlight)]
+#[diag(passes::doc_test_unknown_spotlight)]
#[note]
#[note(passes::no_op_note)]
pub struct DocTestUnknownSpotlight {
@@ -282,7 +282,7 @@ pub struct DocTestUnknownSpotlight {
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown_include)]
+#[diag(passes::doc_test_unknown_include)]
pub struct DocTestUnknownInclude {
pub path: String,
pub value: String,
@@ -292,11 +292,11 @@ pub struct DocTestUnknownInclude {
}
#[derive(LintDiagnostic)]
-#[lint(passes::doc_invalid)]
+#[diag(passes::doc_invalid)]
pub struct DocInvalid;
#[derive(SessionDiagnostic)]
-#[error(passes::pass_by_value)]
+#[diag(passes::pass_by_value)]
pub struct PassByValue {
#[primary_span]
pub attr_span: Span,
@@ -305,7 +305,7 @@ pub struct PassByValue {
}
#[derive(SessionDiagnostic)]
-#[error(passes::allow_incoherent_impl)]
+#[diag(passes::allow_incoherent_impl)]
pub struct AllowIncoherentImpl {
#[primary_span]
pub attr_span: Span,
@@ -314,7 +314,7 @@ pub struct AllowIncoherentImpl {
}
#[derive(SessionDiagnostic)]
-#[error(passes::has_incoherent_inherent_impl)]
+#[diag(passes::has_incoherent_inherent_impl)]
pub struct HasIncoherentInherentImpl {
#[primary_span]
pub attr_span: Span,
@@ -323,21 +323,21 @@ pub struct HasIncoherentInherentImpl {
}
#[derive(LintDiagnostic)]
-#[lint(passes::must_use_async)]
+#[diag(passes::must_use_async)]
pub struct MustUseAsync {
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[lint(passes::must_use_no_effect)]
+#[diag(passes::must_use_no_effect)]
pub struct MustUseNoEffect {
pub article: &'static str,
pub target: rustc_hir::Target,
}
#[derive(SessionDiagnostic)]
-#[error(passes::must_not_suspend)]
+#[diag(passes::must_not_suspend)]
pub struct MustNotSuspend {
#[primary_span]
pub attr_span: Span,
@@ -346,24 +346,24 @@ pub struct MustNotSuspend {
}
#[derive(LintDiagnostic)]
-#[lint(passes::cold)]
-#[warn_]
+#[diag(passes::cold)]
+#[warning]
pub struct Cold {
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[lint(passes::link)]
-#[warn_]
+#[diag(passes::link)]
+#[warning]
pub struct Link {
#[label]
pub span: Option<Span>,
}
#[derive(LintDiagnostic)]
-#[lint(passes::link_name)]
-#[warn_]
+#[diag(passes::link_name)]
+#[warning]
pub struct LinkName<'a> {
#[help]
pub attr_span: Option<Span>,
@@ -373,7 +373,7 @@ pub struct LinkName<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(passes::no_link)]
+#[diag(passes::no_link)]
pub struct NoLink {
#[primary_span]
pub attr_span: Span,
@@ -382,7 +382,7 @@ pub struct NoLink {
}
#[derive(SessionDiagnostic)]
-#[error(passes::export_name)]
+#[diag(passes::export_name)]
pub struct ExportName {
#[primary_span]
pub attr_span: Span,
@@ -391,7 +391,7 @@ pub struct ExportName {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_layout_scalar_valid_range_not_struct)]
+#[diag(passes::rustc_layout_scalar_valid_range_not_struct)]
pub struct RustcLayoutScalarValidRangeNotStruct {
#[primary_span]
pub attr_span: Span,
@@ -400,14 +400,14 @@ pub struct RustcLayoutScalarValidRangeNotStruct {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_layout_scalar_valid_range_arg)]
+#[diag(passes::rustc_layout_scalar_valid_range_arg)]
pub struct RustcLayoutScalarValidRangeArg {
#[primary_span]
pub attr_span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_only)]
+#[diag(passes::rustc_legacy_const_generics_only)]
pub struct RustcLegacyConstGenericsOnly {
#[primary_span]
pub attr_span: Span,
@@ -416,7 +416,7 @@ pub struct RustcLegacyConstGenericsOnly {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_index)]
+#[diag(passes::rustc_legacy_const_generics_index)]
pub struct RustcLegacyConstGenericsIndex {
#[primary_span]
pub attr_span: Span,
@@ -425,7 +425,7 @@ pub struct RustcLegacyConstGenericsIndex {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_index_exceed)]
+#[diag(passes::rustc_legacy_const_generics_index_exceed)]
pub struct RustcLegacyConstGenericsIndexExceed {
#[primary_span]
#[label]
@@ -434,30 +434,30 @@ pub struct RustcLegacyConstGenericsIndexExceed {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_index_negative)]
+#[diag(passes::rustc_legacy_const_generics_index_negative)]
pub struct RustcLegacyConstGenericsIndexNegative {
#[primary_span]
pub invalid_args: Vec<Span>,
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_dirty_clean)]
+#[diag(passes::rustc_dirty_clean)]
pub struct RustcDirtyClean {
#[primary_span]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[lint(passes::link_section)]
-#[warn_]
+#[diag(passes::link_section)]
+#[warning]
pub struct LinkSection {
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[lint(passes::no_mangle_foreign)]
-#[warn_]
+#[diag(passes::no_mangle_foreign)]
+#[warning]
#[note]
pub struct NoMangleForeign {
#[label]
@@ -468,40 +468,40 @@ pub struct NoMangleForeign {
}
#[derive(LintDiagnostic)]
-#[lint(passes::no_mangle)]
-#[warn_]
+#[diag(passes::no_mangle)]
+#[warning]
pub struct NoMangle {
#[label]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::repr_ident, code = "E0565")]
+#[diag(passes::repr_ident, code = "E0565")]
pub struct ReprIdent {
#[primary_span]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[lint(passes::repr_conflicting, code = "E0566")]
+#[diag(passes::repr_conflicting, code = "E0566")]
pub struct ReprConflicting;
#[derive(SessionDiagnostic)]
-#[error(passes::used_static)]
+#[diag(passes::used_static)]
pub struct UsedStatic {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::used_compiler_linker)]
+#[diag(passes::used_compiler_linker)]
pub struct UsedCompilerLinker {
#[primary_span]
pub spans: Vec<Span>,
}
#[derive(SessionDiagnostic)]
-#[error(passes::allow_internal_unstable)]
+#[diag(passes::allow_internal_unstable)]
pub struct AllowInternalUnstable {
#[primary_span]
pub attr_span: Span,
@@ -510,14 +510,14 @@ pub struct AllowInternalUnstable {
}
#[derive(SessionDiagnostic)]
-#[error(passes::debug_visualizer_placement)]
+#[diag(passes::debug_visualizer_placement)]
pub struct DebugVisualizerPlacement {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::debug_visualizer_invalid)]
+#[diag(passes::debug_visualizer_invalid)]
#[note(passes::note_1)]
#[note(passes::note_2)]
#[note(passes::note_3)]
@@ -527,7 +527,7 @@ pub struct DebugVisualizerInvalid {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_allow_const_fn_unstable)]
+#[diag(passes::rustc_allow_const_fn_unstable)]
pub struct RustcAllowConstFnUnstable {
#[primary_span]
pub attr_span: Span,
@@ -536,7 +536,7 @@ pub struct RustcAllowConstFnUnstable {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_std_internal_symbol)]
+#[diag(passes::rustc_std_internal_symbol)]
pub struct RustcStdInternalSymbol {
#[primary_span]
pub attr_span: Span,
@@ -545,35 +545,42 @@ pub struct RustcStdInternalSymbol {
}
#[derive(SessionDiagnostic)]
-#[error(passes::const_trait)]
+#[diag(passes::const_trait)]
pub struct ConstTrait {
#[primary_span]
pub attr_span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(passes::stability_promotable)]
+#[diag(passes::link_ordinal)]
+pub struct LinkOrdinal {
+ #[primary_span]
+ pub attr_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(passes::stability_promotable)]
pub struct StabilityPromotable {
#[primary_span]
pub attr_span: Span,
}
#[derive(LintDiagnostic)]
-#[lint(passes::deprecated)]
+#[diag(passes::deprecated)]
pub struct Deprecated;
#[derive(LintDiagnostic)]
-#[lint(passes::macro_use)]
+#[diag(passes::macro_use)]
pub struct MacroUse {
pub name: Symbol,
}
#[derive(LintDiagnostic)]
-#[lint(passes::macro_export)]
+#[diag(passes::macro_export)]
pub struct MacroExport;
#[derive(LintDiagnostic)]
-#[lint(passes::plugin_registrar)]
+#[diag(passes::plugin_registrar)]
pub struct PluginRegistrar;
#[derive(SessionSubdiagnostic)]
@@ -587,7 +594,7 @@ pub enum UnusedNote {
}
#[derive(LintDiagnostic)]
-#[lint(passes::unused)]
+#[diag(passes::unused)]
pub struct Unused {
#[suggestion(applicability = "machine-applicable")]
pub attr_span: Span,
@@ -596,7 +603,7 @@ pub struct Unused {
}
#[derive(SessionDiagnostic)]
-#[error(passes::non_exported_macro_invalid_attrs, code = "E0518")]
+#[diag(passes::non_exported_macro_invalid_attrs, code = "E0518")]
pub struct NonExportedMacroInvalidAttrs {
#[primary_span]
#[label]
@@ -604,19 +611,18 @@ pub struct NonExportedMacroInvalidAttrs {
}
#[derive(LintDiagnostic)]
-#[lint(passes::unused_duplicate)]
+#[diag(passes::unused_duplicate)]
pub struct UnusedDuplicate {
- #[primary_span]
#[suggestion(code = "", applicability = "machine-applicable")]
pub this: Span,
#[note]
pub other: Span,
- #[warn_]
+ #[warning]
pub warning: Option<()>,
}
#[derive(SessionDiagnostic)]
-#[error(passes::unused_multiple)]
+#[diag(passes::unused_multiple)]
pub struct UnusedMultiple {
#[primary_span]
#[suggestion(code = "", applicability = "machine-applicable")]
@@ -627,7 +633,7 @@ pub struct UnusedMultiple {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_lint_opt_ty)]
+#[diag(passes::rustc_lint_opt_ty)]
pub struct RustcLintOptTy {
#[primary_span]
pub attr_span: Span,
@@ -636,10 +642,19 @@ pub struct RustcLintOptTy {
}
#[derive(SessionDiagnostic)]
-#[error(passes::rustc_lint_opt_deny_field_access)]
+#[diag(passes::rustc_lint_opt_deny_field_access)]
pub struct RustcLintOptDenyFieldAccess {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
+
+#[derive(SessionDiagnostic)]
+#[diag(passes::collapse_debuginfo)]
+pub struct CollapseDebuginfo {
+ #[primary_span]
+ pub attr_span: Span,
+ #[label]
+ pub defn_span: Span,
+}
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index 212ea9e57..3bb8c0bb4 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -103,7 +103,7 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> {
self.error(|| {
format!(
"ItemLocalIds not assigned densely in {}. \
- Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
+ Max ItemLocalId = {}, missing IDs = {:#?}; seens IDs = {:#?}",
self.hir_map.def_path(owner).to_string_no_crate_verbose(),
max,
missing_items,
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index a3be827a7..0be2fc053 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -21,75 +21,169 @@ enum Id {
None,
}
-struct NodeData {
+struct NodeStats {
count: usize,
size: usize,
}
+impl NodeStats {
+ fn new() -> NodeStats {
+ NodeStats { count: 0, size: 0 }
+ }
+}
+
+struct Node {
+ stats: NodeStats,
+ subnodes: FxHashMap<&'static str, NodeStats>,
+}
+
+impl Node {
+ fn new() -> Node {
+ Node { stats: NodeStats::new(), subnodes: FxHashMap::default() }
+ }
+}
+
+/// This type measures the size of AST and HIR nodes, by implementing the AST
+/// and HIR `Visitor` traits. But we don't measure every visited type because
+/// that could cause double counting.
+///
+/// For example, `ast::Visitor` has `visit_ident`, but `Ident`s are always
+/// stored inline within other AST nodes, so we don't implement `visit_ident`
+/// here. In contrast, we do implement `visit_expr` because `ast::Expr` is
+/// always stored as `P<ast::Expr>`, and every such expression should be
+/// measured separately.
+///
+/// In general, a `visit_foo` method should be implemented here if the
+/// corresponding `Foo` type is always stored on its own, e.g.: `P<Foo>`,
+/// `Box<Foo>`, `Vec<Foo>`, `Box<[Foo]>`.
+///
+/// There are some types in the AST and HIR tree that the visitors do not have
+/// a `visit_*` method for, and so we cannot measure these, which is
+/// unfortunate.
struct StatCollector<'k> {
krate: Option<Map<'k>>,
- data: FxHashMap<&'static str, NodeData>,
+ nodes: FxHashMap<&'static str, Node>,
seen: FxHashSet<Id>,
}
pub fn print_hir_stats(tcx: TyCtxt<'_>) {
let mut collector = StatCollector {
krate: Some(tcx.hir()),
- data: FxHashMap::default(),
+ nodes: FxHashMap::default(),
seen: FxHashSet::default(),
};
tcx.hir().walk_toplevel_module(&mut collector);
tcx.hir().walk_attributes(&mut collector);
- collector.print("HIR STATS");
+ collector.print("HIR STATS", "hir-stats");
}
-pub fn print_ast_stats(krate: &ast::Crate, title: &str) {
+pub fn print_ast_stats(krate: &ast::Crate, title: &str, prefix: &str) {
+ use rustc_ast::visit::Visitor;
+
let mut collector =
- StatCollector { krate: None, data: FxHashMap::default(), seen: FxHashSet::default() };
- ast_visit::walk_crate(&mut collector, krate);
- collector.print(title);
+ StatCollector { krate: None, nodes: FxHashMap::default(), seen: FxHashSet::default() };
+ collector.visit_crate(krate);
+ collector.print(title, prefix);
}
impl<'k> StatCollector<'k> {
- fn record<T>(&mut self, label: &'static str, id: Id, node: &T) {
+ // Record a top-level node.
+ fn record<T>(&mut self, label: &'static str, id: Id, val: &T) {
+ self.record_inner(label, None, id, val);
+ }
+
+ // Record a two-level entry, with a top-level enum type and a variant.
+ fn record_variant<T>(&mut self, label1: &'static str, label2: &'static str, id: Id, val: &T) {
+ self.record_inner(label1, Some(label2), id, val);
+ }
+
+ fn record_inner<T>(
+ &mut self,
+ label1: &'static str,
+ label2: Option<&'static str>,
+ id: Id,
+ val: &T,
+ ) {
if id != Id::None && !self.seen.insert(id) {
return;
}
- let entry = self.data.entry(label).or_insert(NodeData { count: 0, size: 0 });
+ let node = self.nodes.entry(label1).or_insert(Node::new());
+ node.stats.count += 1;
+ node.stats.size = std::mem::size_of_val(val);
- entry.count += 1;
- entry.size = std::mem::size_of_val(node);
+ if let Some(label2) = label2 {
+ let subnode = node.subnodes.entry(label2).or_insert(NodeStats::new());
+ subnode.count += 1;
+ subnode.size = std::mem::size_of_val(val);
+ }
}
- fn print(&self, title: &str) {
- let mut stats: Vec<_> = self.data.iter().collect();
-
- stats.sort_by_key(|&(_, ref d)| d.count * d.size);
+ fn print(&self, title: &str, prefix: &str) {
+ let mut nodes: Vec<_> = self.nodes.iter().collect();
+ nodes.sort_by_key(|&(_, ref node)| node.stats.count * node.stats.size);
- let mut total_size = 0;
+ let total_size = nodes.iter().map(|(_, node)| node.stats.count * node.stats.size).sum();
- eprintln!("\n{}\n", title);
+ eprintln!("{} {}", prefix, title);
+ eprintln!(
+ "{} {:<18}{:>18}{:>14}{:>14}",
+ prefix, "Name", "Accumulated Size", "Count", "Item Size"
+ );
+ eprintln!("{} ----------------------------------------------------------------", prefix);
- eprintln!("{:<18}{:>18}{:>14}{:>14}", "Name", "Accumulated Size", "Count", "Item Size");
- eprintln!("----------------------------------------------------------------");
+ let percent = |m, n| (m * 100) as f64 / n as f64;
- for (label, data) in stats {
+ for (label, node) in nodes {
+ let size = node.stats.count * node.stats.size;
eprintln!(
- "{:<18}{:>18}{:>14}{:>14}",
+ "{} {:<18}{:>10} ({:4.1}%){:>14}{:>14}",
+ prefix,
label,
- to_readable_str(data.count * data.size),
- to_readable_str(data.count),
- to_readable_str(data.size)
+ to_readable_str(size),
+ percent(size, total_size),
+ to_readable_str(node.stats.count),
+ to_readable_str(node.stats.size)
);
-
- total_size += data.count * data.size;
+ if !node.subnodes.is_empty() {
+ let mut subnodes: Vec<_> = node.subnodes.iter().collect();
+ subnodes.sort_by_key(|&(_, ref subnode)| subnode.count * subnode.size);
+
+ for (label, subnode) in subnodes {
+ let size = subnode.count * subnode.size;
+ eprintln!(
+ "{} - {:<18}{:>10} ({:4.1}%){:>14}",
+ prefix,
+ label,
+ to_readable_str(size),
+ percent(size, total_size),
+ to_readable_str(subnode.count),
+ );
+ }
+ }
}
- eprintln!("----------------------------------------------------------------");
- eprintln!("{:<18}{:>18}\n", "Total", to_readable_str(total_size));
+ eprintln!("{} ----------------------------------------------------------------", prefix);
+ eprintln!("{} {:<18}{:>10}", prefix, "Total", to_readable_str(total_size));
+ eprintln!("{}", prefix);
}
}
+// Used to avoid boilerplate for types with many variants.
+macro_rules! record_variants {
+ (
+ ($self:ident, $val:expr, $kind:expr, $id:expr, $mod:ident, $ty:ty, $tykind:ident),
+ [$($variant:ident),*]
+ ) => {
+ match $kind {
+ $(
+ $mod::$tykind::$variant { .. } => {
+ $self.record_variant(stringify!($ty), stringify!($variant), $id, $val)
+ }
+ )*
+ }
+ };
+}
+
impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
fn visit_param(&mut self, param: &'v hir::Param<'v>) {
self.record("Param", Id::Node(param.hir_id), param);
@@ -122,12 +216,46 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_item(&mut self, i: &'v hir::Item<'v>) {
- self.record("Item", Id::Node(i.hir_id()), i);
+ record_variants!(
+ (self, i, i.kind, Id::Node(i.hir_id()), hir, Item, ItemKind),
+ [
+ ExternCrate,
+ Use,
+ Static,
+ Const,
+ Fn,
+ Macro,
+ Mod,
+ ForeignMod,
+ GlobalAsm,
+ TyAlias,
+ OpaqueTy,
+ Enum,
+ Struct,
+ Union,
+ Trait,
+ TraitAlias,
+ Impl
+ ]
+ );
hir_visit::walk_item(self, i)
}
+ fn visit_body(&mut self, b: &'v hir::Body<'v>) {
+ self.record("Body", Id::None, b);
+ hir_visit::walk_body(self, b);
+ }
+
+ fn visit_mod(&mut self, m: &'v hir::Mod<'v>, _s: Span, n: HirId) {
+ self.record("Mod", Id::None, m);
+ hir_visit::walk_mod(self, m, n)
+ }
+
fn visit_foreign_item(&mut self, i: &'v hir::ForeignItem<'v>) {
- self.record("ForeignItem", Id::Node(i.hir_id()), i);
+ record_variants!(
+ (self, i, i.kind, Id::Node(i.hir_id()), hir, ForeignItem, ForeignItemKind),
+ [Fn, Static, Type]
+ );
hir_visit::walk_foreign_item(self, i)
}
@@ -142,7 +270,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
- self.record("Stmt", Id::Node(s.hir_id), s);
+ record_variants!(
+ (self, s, s.kind, Id::Node(s.hir_id), hir, Stmt, StmtKind),
+ [Local, Item, Expr, Semi]
+ );
hir_visit::walk_stmt(self, s)
}
@@ -152,50 +283,135 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_pat(&mut self, p: &'v hir::Pat<'v>) {
- self.record("Pat", Id::Node(p.hir_id), p);
+ record_variants!(
+ (self, p, p.kind, Id::Node(p.hir_id), hir, Pat, PatKind),
+ [Wild, Binding, Struct, TupleStruct, Or, Path, Tuple, Box, Ref, Lit, Range, Slice]
+ );
hir_visit::walk_pat(self, p)
}
- fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
- self.record("Expr", Id::Node(ex.hir_id), ex);
- hir_visit::walk_expr(self, ex)
+ fn visit_pat_field(&mut self, f: &'v hir::PatField<'v>) {
+ self.record("PatField", Id::Node(f.hir_id), f);
+ hir_visit::walk_pat_field(self, f)
+ }
+
+ fn visit_expr(&mut self, e: &'v hir::Expr<'v>) {
+ record_variants!(
+ (self, e, e.kind, Id::Node(e.hir_id), hir, Expr, ExprKind),
+ [
+ Box, ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
+ DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index,
+ Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err
+ ]
+ );
+ hir_visit::walk_expr(self, e)
+ }
+
+ fn visit_let_expr(&mut self, lex: &'v hir::Let<'v>) {
+ self.record("Let", Id::Node(lex.hir_id), lex);
+ hir_visit::walk_let_expr(self, lex)
+ }
+
+ fn visit_expr_field(&mut self, f: &'v hir::ExprField<'v>) {
+ self.record("ExprField", Id::Node(f.hir_id), f);
+ hir_visit::walk_expr_field(self, f)
}
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
- self.record("Ty", Id::Node(t.hir_id), t);
+ record_variants!(
+ (self, t, t.kind, Id::Node(t.hir_id), hir, Ty, TyKind),
+ [
+ Slice,
+ Array,
+ Ptr,
+ Rptr,
+ BareFn,
+ Never,
+ Tup,
+ Path,
+ OpaqueDef,
+ TraitObject,
+ Typeof,
+ Infer,
+ Err
+ ]
+ );
hir_visit::walk_ty(self, t)
}
+ fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
+ self.record("GenericParam", Id::Node(p.hir_id), p);
+ hir_visit::walk_generic_param(self, p)
+ }
+
+ fn visit_generics(&mut self, g: &'v hir::Generics<'v>) {
+ self.record("Generics", Id::None, g);
+ hir_visit::walk_generics(self, g)
+ }
+
+ fn visit_where_predicate(&mut self, p: &'v hir::WherePredicate<'v>) {
+ record_variants!(
+ (self, p, p, Id::None, hir, WherePredicate, WherePredicate),
+ [BoundPredicate, RegionPredicate, EqPredicate]
+ );
+ hir_visit::walk_where_predicate(self, p)
+ }
+
fn visit_fn(
&mut self,
fk: hir_visit::FnKind<'v>,
fd: &'v hir::FnDecl<'v>,
b: hir::BodyId,
- s: Span,
+ _: Span,
id: hir::HirId,
) {
self.record("FnDecl", Id::None, fd);
- hir_visit::walk_fn(self, fk, fd, b, s, id)
+ hir_visit::walk_fn(self, fk, fd, b, id)
}
- fn visit_where_predicate(&mut self, predicate: &'v hir::WherePredicate<'v>) {
- self.record("WherePredicate", Id::None, predicate);
- hir_visit::walk_where_predicate(self, predicate)
+ fn visit_use(&mut self, p: &'v hir::Path<'v>, hir_id: hir::HirId) {
+ // This is `visit_use`, but the type is `Path` so record it that way.
+ self.record("Path", Id::None, p);
+ hir_visit::walk_use(self, p, hir_id)
}
fn visit_trait_item(&mut self, ti: &'v hir::TraitItem<'v>) {
- self.record("TraitItem", Id::Node(ti.hir_id()), ti);
+ record_variants!(
+ (self, ti, ti.kind, Id::Node(ti.hir_id()), hir, TraitItem, TraitItemKind),
+ [Const, Fn, Type]
+ );
hir_visit::walk_trait_item(self, ti)
}
+ fn visit_trait_item_ref(&mut self, ti: &'v hir::TraitItemRef) {
+ self.record("TraitItemRef", Id::Node(ti.id.hir_id()), ti);
+ hir_visit::walk_trait_item_ref(self, ti)
+ }
+
fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) {
- self.record("ImplItem", Id::Node(ii.hir_id()), ii);
+ record_variants!(
+ (self, ii, ii.kind, Id::Node(ii.hir_id()), hir, ImplItem, ImplItemKind),
+ [Const, Fn, TyAlias]
+ );
hir_visit::walk_impl_item(self, ii)
}
- fn visit_param_bound(&mut self, bounds: &'v hir::GenericBound<'v>) {
- self.record("GenericBound", Id::None, bounds);
- hir_visit::walk_param_bound(self, bounds)
+ fn visit_foreign_item_ref(&mut self, fi: &'v hir::ForeignItemRef) {
+ self.record("ForeignItemRef", Id::Node(fi.id.hir_id()), fi);
+ hir_visit::walk_foreign_item_ref(self, fi)
+ }
+
+ fn visit_impl_item_ref(&mut self, ii: &'v hir::ImplItemRef) {
+ self.record("ImplItemRef", Id::Node(ii.id.hir_id()), ii);
+ hir_visit::walk_impl_item_ref(self, ii)
+ }
+
+ fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {
+ record_variants!(
+ (self, b, b, Id::None, hir, GenericBound, GenericBound),
+ [Trait, LangItemTrait, Outlives]
+ );
+ hir_visit::walk_param_bound(self, b)
}
fn visit_field_def(&mut self, s: &'v hir::FieldDef<'v>) {
@@ -203,14 +419,22 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_field_def(self, s)
}
- fn visit_variant(
- &mut self,
- v: &'v hir::Variant<'v>,
- g: &'v hir::Generics<'v>,
- item_id: hir::HirId,
- ) {
+ fn visit_variant(&mut self, v: &'v hir::Variant<'v>) {
self.record("Variant", Id::None, v);
- hir_visit::walk_variant(self, v, g, item_id)
+ hir_visit::walk_variant(self, v)
+ }
+
+ fn visit_generic_arg(&mut self, ga: &'v hir::GenericArg<'v>) {
+ record_variants!(
+ (self, ga, ga, Id::Node(ga.hir_id()), hir, GenericArg, GenericArg),
+ [Lifetime, Type, Const, Infer]
+ );
+ match ga {
+ hir::GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
+ hir::GenericArg::Type(ty) => self.visit_ty(ty),
+ hir::GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
+ hir::GenericArg::Infer(inf) => self.visit_infer(inf),
+ }
}
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
@@ -218,19 +442,19 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_lifetime(self, lifetime)
}
- fn visit_qpath(&mut self, qpath: &'v hir::QPath<'v>, id: hir::HirId, span: Span) {
- self.record("QPath", Id::None, qpath);
- hir_visit::walk_qpath(self, qpath, id, span)
- }
-
fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) {
self.record("Path", Id::None, path);
hir_visit::walk_path(self, path)
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v hir::PathSegment<'v>) {
+ fn visit_path_segment(&mut self, path_segment: &'v hir::PathSegment<'v>) {
self.record("PathSegment", Id::None, path_segment);
- hir_visit::walk_path_segment(self, path_span, path_segment)
+ hir_visit::walk_path_segment(self, path_segment)
+ }
+
+ fn visit_generic_args(&mut self, ga: &'v hir::GenericArgs<'v>) {
+ self.record("GenericArgs", Id::None, ga);
+ hir_visit::walk_generic_args(self, ga)
}
fn visit_assoc_type_binding(&mut self, type_binding: &'v hir::TypeBinding<'v>) {
@@ -241,16 +465,45 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
self.record("Attribute", Id::Attr(attr.id), attr);
}
+
+ fn visit_inline_asm(&mut self, asm: &'v hir::InlineAsm<'v>, id: HirId) {
+ self.record("InlineAsm", Id::None, asm);
+ hir_visit::walk_inline_asm(self, asm, id);
+ }
}
impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
fn visit_foreign_item(&mut self, i: &'v ast::ForeignItem) {
- self.record("ForeignItem", Id::None, i);
+ record_variants!(
+ (self, i, i.kind, Id::None, ast, ForeignItem, ForeignItemKind),
+ [Static, Fn, TyAlias, MacCall]
+ );
ast_visit::walk_foreign_item(self, i)
}
fn visit_item(&mut self, i: &'v ast::Item) {
- self.record("Item", Id::None, i);
+ record_variants!(
+ (self, i, i.kind, Id::None, ast, Item, ItemKind),
+ [
+ ExternCrate,
+ Use,
+ Static,
+ Const,
+ Fn,
+ Mod,
+ ForeignMod,
+ GlobalAsm,
+ TyAlias,
+ Enum,
+ Struct,
+ Union,
+ Trait,
+ TraitAlias,
+ Impl,
+ MacCall,
+ MacroDef
+ ]
+ );
ast_visit::walk_item(self, i)
}
@@ -265,47 +518,119 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_stmt(&mut self, s: &'v ast::Stmt) {
- self.record("Stmt", Id::None, s);
+ record_variants!(
+ (self, s, s.kind, Id::None, ast, Stmt, StmtKind),
+ [Local, Item, Expr, Semi, Empty, MacCall]
+ );
ast_visit::walk_stmt(self, s)
}
+ fn visit_param(&mut self, p: &'v ast::Param) {
+ self.record("Param", Id::None, p);
+ ast_visit::walk_param(self, p)
+ }
+
fn visit_arm(&mut self, a: &'v ast::Arm) {
self.record("Arm", Id::None, a);
ast_visit::walk_arm(self, a)
}
fn visit_pat(&mut self, p: &'v ast::Pat) {
- self.record("Pat", Id::None, p);
+ record_variants!(
+ (self, p, p.kind, Id::None, ast, Pat, PatKind),
+ [
+ Wild,
+ Ident,
+ Struct,
+ TupleStruct,
+ Or,
+ Path,
+ Tuple,
+ Box,
+ Ref,
+ Lit,
+ Range,
+ Slice,
+ Rest,
+ Paren,
+ MacCall
+ ]
+ );
ast_visit::walk_pat(self, p)
}
- fn visit_expr(&mut self, ex: &'v ast::Expr) {
- self.record("Expr", Id::None, ex);
- ast_visit::walk_expr(self, ex)
+ fn visit_expr(&mut self, e: &'v ast::Expr) {
+ record_variants!(
+ (self, e, e.kind, Id::None, ast, Expr, ExprKind),
+ [
+ Box, Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let,
+ If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign,
+ AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret,
+ InlineAsm, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, Err
+ ]
+ );
+ ast_visit::walk_expr(self, e)
}
fn visit_ty(&mut self, t: &'v ast::Ty) {
- self.record("Ty", Id::None, t);
+ record_variants!(
+ (self, t, t.kind, Id::None, ast, Ty, TyKind),
+ [
+ Slice,
+ Array,
+ Ptr,
+ Rptr,
+ BareFn,
+ Never,
+ Tup,
+ Path,
+ TraitObject,
+ ImplTrait,
+ Paren,
+ Typeof,
+ Infer,
+ ImplicitSelf,
+ MacCall,
+ Err,
+ CVarArgs
+ ]
+ );
+
ast_visit::walk_ty(self, t)
}
- fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, s: Span, _: NodeId) {
+ fn visit_generic_param(&mut self, g: &'v ast::GenericParam) {
+ self.record("GenericParam", Id::None, g);
+ ast_visit::walk_generic_param(self, g)
+ }
+
+ fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) {
+ record_variants!(
+ (self, p, p, Id::None, ast, WherePredicate, WherePredicate),
+ [BoundPredicate, RegionPredicate, EqPredicate]
+ );
+ ast_visit::walk_where_predicate(self, p)
+ }
+
+ fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: Span, _: NodeId) {
self.record("FnDecl", Id::None, fk.decl());
- ast_visit::walk_fn(self, fk, s)
+ ast_visit::walk_fn(self, fk)
}
- fn visit_assoc_item(&mut self, item: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
- let label = match ctxt {
- ast_visit::AssocCtxt::Trait => "TraitItem",
- ast_visit::AssocCtxt::Impl => "ImplItem",
- };
- self.record(label, Id::None, item);
- ast_visit::walk_assoc_item(self, item, ctxt);
+ fn visit_assoc_item(&mut self, i: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
+ record_variants!(
+ (self, i, i.kind, Id::None, ast, AssocItem, AssocItemKind),
+ [Const, Fn, TyAlias, MacCall]
+ );
+ ast_visit::walk_assoc_item(self, i, ctxt);
}
- fn visit_param_bound(&mut self, bounds: &'v ast::GenericBound, _ctxt: BoundKind) {
- self.record("GenericBound", Id::None, bounds);
- ast_visit::walk_param_bound(self, bounds)
+ fn visit_param_bound(&mut self, b: &'v ast::GenericBound, _ctxt: BoundKind) {
+ record_variants!(
+ (self, b, b, Id::None, ast, GenericBound, GenericBound),
+ [Trait, Outlives]
+ );
+ ast_visit::walk_param_bound(self, b)
}
fn visit_field_def(&mut self, s: &'v ast::FieldDef) {
@@ -318,27 +643,52 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
ast_visit::walk_variant(self, v)
}
- fn visit_lifetime(&mut self, lifetime: &'v ast::Lifetime, _: ast_visit::LifetimeCtxt) {
- self.record("Lifetime", Id::None, lifetime);
- ast_visit::walk_lifetime(self, lifetime)
+ // `UseTree` has one inline use (in `ast::ItemKind::Use`) and one
+ // non-inline use (in `ast::UseTreeKind::Nested). The former case is more
+ // common, so we don't implement `visit_use_tree` and tolerate the missed
+ // coverage in the latter case.
+
+ // `PathSegment` has one inline use (in `ast::ExprKind::MethodCall`) and
+ // one non-inline use (in `ast::Path::segments`). The latter case is more
+ // common than the former case, so we implement this visitor and tolerate
+ // the double counting in the former case.
+ fn visit_path_segment(&mut self, path_segment: &'v ast::PathSegment) {
+ self.record("PathSegment", Id::None, path_segment);
+ ast_visit::walk_path_segment(self, path_segment)
}
- fn visit_mac_call(&mut self, mac: &'v ast::MacCall) {
- self.record("MacCall", Id::None, mac);
- ast_visit::walk_mac(self, mac)
+ // `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one
+ // non-inline use (in `ast::PathSegment::args`). The latter case is more
+ // common, so we implement `visit_generic_args` and tolerate the double
+ // counting in the former case.
+ fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) {
+ record_variants!(
+ (self, g, g, Id::None, ast, GenericArgs, GenericArgs),
+ [AngleBracketed, Parenthesized]
+ );
+ ast_visit::walk_generic_args(self, g)
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v ast::PathSegment) {
- self.record("PathSegment", Id::None, path_segment);
- ast_visit::walk_path_segment(self, path_span, path_segment)
+ fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
+ record_variants!(
+ (self, attr, attr.kind, Id::None, ast, Attribute, AttrKind),
+ [Normal, DocComment]
+ );
+ ast_visit::walk_attribute(self, attr)
}
- fn visit_assoc_constraint(&mut self, constraint: &'v ast::AssocConstraint) {
- self.record("AssocConstraint", Id::None, constraint);
- ast_visit::walk_assoc_constraint(self, constraint)
+ fn visit_expr_field(&mut self, f: &'v ast::ExprField) {
+ self.record("ExprField", Id::None, f);
+ ast_visit::walk_expr_field(self, f)
}
- fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
- self.record("Attribute", Id::None, attr);
+ fn visit_crate(&mut self, krate: &'v ast::Crate) {
+ self.record("Crate", Id::None, krate);
+ ast_visit::walk_crate(self, krate)
+ }
+
+ fn visit_inline_asm(&mut self, asm: &'v ast::InlineAsm) {
+ self.record("InlineAsm", Id::None, asm);
+ ast_visit::walk_inline_asm(self, asm)
}
}
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 7b2f83958..39ebb8db2 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,7 +8,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(iter_intersperse)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(try_blocks)]
diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index e05994f13..04173c792 100644
--- a/compiler/rustc_passes/src/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
@@ -5,6 +5,7 @@
//! collect them instead.
use rustc_ast::{Attribute, MetaItemKind};
+use rustc_attr::{rust_version_symbol, VERSION_PLACEHOLDER};
use rustc_errors::struct_span_err;
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
@@ -29,11 +30,16 @@ impl<'tcx> LibFeatureCollector<'tcx> {
}
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
- let stab_attrs =
- [sym::stable, sym::unstable, sym::rustc_const_stable, sym::rustc_const_unstable];
+ let stab_attrs = [
+ sym::stable,
+ sym::unstable,
+ sym::rustc_const_stable,
+ sym::rustc_const_unstable,
+ sym::rustc_default_body_unstable,
+ ];
// Find a stability attribute: one of #[stable(…)], #[unstable(…)],
- // #[rustc_const_stable(…)], or #[rustc_const_unstable(…)].
+ // #[rustc_const_stable(…)], #[rustc_const_unstable(…)] or #[rustc_default_body_unstable].
if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) {
let meta_kind = attr.meta_kind();
if let Some(MetaItemKind::List(ref metas)) = meta_kind {
@@ -49,12 +55,21 @@ impl<'tcx> LibFeatureCollector<'tcx> {
}
}
}
+
+ if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
+ since = Some(rust_version_symbol());
+ }
+
if let Some(feature) = feature {
// This additional check for stability is to make sure we
// don't emit additional, irrelevant errors for malformed
// attributes.
- let is_unstable =
- matches!(*stab_attr, sym::unstable | sym::rustc_const_unstable);
+ let is_unstable = matches!(
+ *stab_attr,
+ sym::unstable
+ | sym::rustc_const_unstable
+ | sym::rustc_default_body_unstable
+ );
if since.is_some() || is_unstable {
return Some((feature, since, attr.span));
}
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 461dd52b9..6a4cd79cd 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -89,16 +89,15 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::*;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet};
use rustc_index::vec::IndexVec;
-use rustc_middle::hir::nested_filter;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
use std::collections::VecDeque;
use std::io;
@@ -139,12 +138,54 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
}
}
-fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
- tcx.hir().visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx));
+fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) {
+ let local_def_id = match def_id.as_local() {
+ None => return,
+ Some(def_id) => def_id,
+ };
+
+ // Don't run unused pass for #[derive()]
+ let parent = tcx.local_parent(local_def_id);
+ if let DefKind::Impl = tcx.def_kind(parent)
+ && tcx.has_attr(parent.to_def_id(), sym::automatically_derived)
+ {
+ return;
+ }
+
+ // Don't run unused pass for #[naked]
+ if tcx.has_attr(def_id, sym::naked) {
+ return;
+ }
+
+ let mut maps = IrMaps::new(tcx);
+ let body_id = tcx.hir().body_owned_by(local_def_id);
+ let hir_id = tcx.hir().body_owner(body_id);
+ let body = tcx.hir().body(body_id);
+
+ if let Some(upvars) = tcx.upvars_mentioned(def_id) {
+ for &var_hir_id in upvars.keys() {
+ let var_name = tcx.hir().name(var_hir_id);
+ maps.add_variable(Upvar(var_hir_id, var_name));
+ }
+ }
+
+ // gather up the various local variables, significant expressions,
+ // and so forth:
+ maps.visit_body(body);
+
+ // compute liveness
+ let mut lsets = Liveness::new(&mut maps, local_def_id);
+ let entry_ln = lsets.compute(&body, hir_id);
+ lsets.log_liveness(entry_ln, body_id.hir_id);
+
+ // check for various error conditions
+ lsets.visit_body(body);
+ lsets.warn_about_unused_upvars(entry_ln);
+ lsets.warn_about_unused_args(body, entry_ln);
}
pub fn provide(providers: &mut Providers) {
- *providers = Providers { check_mod_liveness, ..*providers };
+ *providers = Providers { check_liveness, ..*providers };
}
// ______________________________________________________________________
@@ -188,6 +229,19 @@ enum VarKind {
Upvar(HirId, Symbol),
}
+struct CollectLitsVisitor<'tcx> {
+ lit_exprs: Vec<&'tcx hir::Expr<'tcx>>,
+}
+
+impl<'tcx> Visitor<'tcx> for CollectLitsVisitor<'tcx> {
+ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
+ if let hir::ExprKind::Lit(_) = expr.kind {
+ self.lit_exprs.push(expr);
+ }
+ intravisit::walk_expr(self, expr);
+ }
+}
+
struct IrMaps<'tcx> {
tcx: TyCtxt<'tcx>,
live_node_map: HirIdMap<LiveNode>,
@@ -316,56 +370,6 @@ impl<'tcx> IrMaps<'tcx> {
}
impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
- type NestedFilter = nested_filter::OnlyBodies;
-
- fn nested_visit_map(&mut self) -> Self::Map {
- self.tcx.hir()
- }
-
- fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
- debug!("visit_body {:?}", body.id());
-
- // swap in a new set of IR maps for this body
- let mut maps = IrMaps::new(self.tcx);
- let hir_id = maps.tcx.hir().body_owner(body.id());
- let local_def_id = maps.tcx.hir().local_def_id(hir_id);
- let def_id = local_def_id.to_def_id();
-
- // Don't run unused pass for #[derive()]
- let parent = self.tcx.local_parent(local_def_id);
- if let DefKind::Impl = self.tcx.def_kind(parent)
- && self.tcx.has_attr(parent.to_def_id(), sym::automatically_derived)
- {
- return;
- }
-
- // Don't run unused pass for #[naked]
- if self.tcx.has_attr(def_id, sym::naked) {
- return;
- }
-
- if let Some(upvars) = maps.tcx.upvars_mentioned(def_id) {
- for &var_hir_id in upvars.keys() {
- let var_name = maps.tcx.hir().name(var_hir_id);
- maps.add_variable(Upvar(var_hir_id, var_name));
- }
- }
-
- // gather up the various local variables, significant expressions,
- // and so forth:
- intravisit::walk_body(&mut maps, body);
-
- // compute liveness
- let mut lsets = Liveness::new(&mut maps, local_def_id);
- let entry_ln = lsets.compute(&body, hir_id);
- lsets.log_liveness(entry_ln, body.id().hir_id);
-
- // check for various error conditions
- lsets.visit_body(body);
- lsets.warn_about_unused_upvars(entry_ln);
- lsets.warn_about_unused_args(body, entry_ln);
- }
-
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
self.add_from_pat(&local.pat);
if local.els.is_some() {
@@ -1035,9 +1039,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&f, succ)
}
- hir::ExprKind::MethodCall(.., ref args, _) => {
+ hir::ExprKind::MethodCall(.., receiver, ref args, _) => {
let succ = self.check_is_ty_uninhabited(expr, succ);
- self.propagate_through_exprs(args, succ)
+ let succ = self.propagate_through_exprs(args, succ);
+ self.propagate_through_expr(receiver, succ)
}
hir::ExprKind::Tup(ref exprs) => self.propagate_through_exprs(exprs, succ),
@@ -1342,7 +1347,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
- self.check_unused_vars_in_pat(&local.pat, None, |spans, hir_id, ln, var| {
+ self.check_unused_vars_in_pat(&local.pat, None, None, |spans, hir_id, ln, var| {
if local.init.is_some() {
self.warn_about_dead_assign(spans, hir_id, ln, var);
}
@@ -1357,7 +1362,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
}
fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
- self.check_unused_vars_in_pat(&arm.pat, None, |_, _, _, _| {});
+ self.check_unused_vars_in_pat(&arm.pat, None, None, |_, _, _, _| {});
intravisit::walk_arm(self, arm);
}
}
@@ -1396,7 +1401,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
}
hir::ExprKind::Let(let_expr) => {
- this.check_unused_vars_in_pat(let_expr.pat, None, |_, _, _, _| {});
+ this.check_unused_vars_in_pat(let_expr.pat, None, None, |_, _, _, _| {});
}
// no correctness conditions related to liveness
@@ -1517,13 +1522,18 @@ impl<'tcx> Liveness<'_, 'tcx> {
fn warn_about_unused_args(&self, body: &hir::Body<'_>, entry_ln: LiveNode) {
for p in body.params {
- self.check_unused_vars_in_pat(&p.pat, Some(entry_ln), |spans, hir_id, ln, var| {
- if !self.live_on_entry(ln, var) {
- self.report_unused_assign(hir_id, spans, var, |name| {
- format!("value passed to `{}` is never read", name)
- });
- }
- });
+ self.check_unused_vars_in_pat(
+ &p.pat,
+ Some(entry_ln),
+ Some(body),
+ |spans, hir_id, ln, var| {
+ if !self.live_on_entry(ln, var) {
+ self.report_unused_assign(hir_id, spans, var, |name| {
+ format!("value passed to `{}` is never read", name)
+ });
+ }
+ },
+ );
}
}
@@ -1531,6 +1541,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
&self,
pat: &hir::Pat<'_>,
entry_ln: Option<LiveNode>,
+ opt_body: Option<&hir::Body<'_>>,
on_used_on_entry: impl Fn(Vec<Span>, HirId, LiveNode, Variable),
) {
// In an or-pattern, only consider the variable; any later patterns must have the same
@@ -1549,6 +1560,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
.or_insert_with(|| (ln, var, vec![id_and_sp]));
});
+ let can_remove = matches!(&pat.kind, hir::PatKind::Struct(_, _, true));
+
for (_, (ln, var, hir_ids_and_spans)) in vars {
if self.used_on_entry(ln, var) {
let id = hir_ids_and_spans[0].0;
@@ -1556,16 +1569,20 @@ impl<'tcx> Liveness<'_, 'tcx> {
hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
on_used_on_entry(spans, id, ln, var);
} else {
- self.report_unused(hir_ids_and_spans, ln, var);
+ self.report_unused(hir_ids_and_spans, ln, var, can_remove, pat, opt_body);
}
}
}
+ #[instrument(skip(self), level = "INFO")]
fn report_unused(
&self,
hir_ids_and_spans: Vec<(HirId, Span, Span)>,
ln: LiveNode,
var: Variable,
+ can_remove: bool,
+ pat: &hir::Pat<'_>,
+ opt_body: Option<&hir::Body<'_>>,
) {
let first_hir_id = hir_ids_and_spans[0].0;
@@ -1590,6 +1607,32 @@ impl<'tcx> Liveness<'_, 'tcx> {
.emit();
},
)
+ } else if can_remove {
+ self.ir.tcx.struct_span_lint_hir(
+ lint::builtin::UNUSED_VARIABLES,
+ first_hir_id,
+ hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(),
+ |lint| {
+ let mut err = lint.build(&format!("unused variable: `{}`", name));
+ err.multipart_suggestion(
+ "try removing the field",
+ hir_ids_and_spans
+ .iter()
+ .map(|(_, pat_span, _)| {
+ let span = self
+ .ir
+ .tcx
+ .sess
+ .source_map()
+ .span_extend_to_next_char(*pat_span, ',', true);
+ (span.with_hi(BytePos(span.hi().0 + 1)), String::new())
+ })
+ .collect(),
+ Applicability::MachineApplicable,
+ );
+ err.emit();
+ },
+ );
} else {
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
@@ -1643,6 +1686,9 @@ impl<'tcx> Liveness<'_, 'tcx> {
.collect::<Vec<_>>(),
|lint| {
let mut err = lint.build(&format!("unused variable: `{}`", name));
+ if self.has_added_lit_match_name_span(&name, opt_body, &mut err) {
+ err.span_label(pat.span, "unused variable");
+ }
err.multipart_suggestion(
"if this is intentional, prefix it with an underscore",
non_shorthands,
@@ -1656,6 +1702,42 @@ impl<'tcx> Liveness<'_, 'tcx> {
}
}
+ fn has_added_lit_match_name_span(
+ &self,
+ name: &str,
+ opt_body: Option<&hir::Body<'_>>,
+ err: &mut rustc_errors::DiagnosticBuilder<'_, ()>,
+ ) -> bool {
+ let mut has_litstring = false;
+ let Some(opt_body) = opt_body else {return false;};
+ let mut visitor = CollectLitsVisitor { lit_exprs: vec![] };
+ intravisit::walk_body(&mut visitor, opt_body);
+ for lit_expr in visitor.lit_exprs {
+ let hir::ExprKind::Lit(litx) = &lit_expr.kind else { continue };
+ let rustc_ast::LitKind::Str(syb, _) = litx.node else{ continue; };
+ let name_str: &str = syb.as_str();
+ let mut name_pa = String::from("{");
+ name_pa.push_str(&name);
+ name_pa.push('}');
+ if name_str.contains(&name_pa) {
+ err.span_label(
+ lit_expr.span,
+ "you might have meant to use string interpolation in this string literal",
+ );
+ err.multipart_suggestion(
+ "string interpolation only works in `format!` invocations",
+ vec![
+ (lit_expr.span.shrink_to_lo(), "format!(".to_string()),
+ (lit_expr.span.shrink_to_hi(), ")".to_string()),
+ ],
+ Applicability::MachineApplicable,
+ );
+ has_litstring = true;
+ }
+ }
+ has_litstring
+ }
+
fn warn_about_dead_assign(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) {
if !self.live_on_exit(ln, var) {
self.report_unused_assign(hir_id, spans, var, |name| {
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 20765abf3..607973446 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -1,11 +1,12 @@
//! Checks validity of naked functions.
-use rustc_ast::{Attribute, InlineAsmOptions};
+use rustc_ast::InlineAsmOptions;
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
-use rustc_hir::intravisit::{FnKind, Visitor};
-use rustc_hir::{ExprKind, HirId, InlineAsmOperand, StmtKind};
+use rustc_hir::intravisit::Visitor;
+use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
@@ -13,71 +14,58 @@ use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
-fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
- tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckNakedFunctions { tcx });
-}
-
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers { check_mod_naked_functions, ..*providers };
}
-struct CheckNakedFunctions<'tcx> {
- tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
- fn visit_fn(
- &mut self,
- fk: FnKind<'_>,
- _fd: &'tcx hir::FnDecl<'tcx>,
- body_id: hir::BodyId,
- span: Span,
- hir_id: HirId,
- ) {
- let ident_span;
- let fn_header;
-
- match fk {
- FnKind::Closure => {
- // Closures with a naked attribute are rejected during attribute
- // check. Don't validate them any further.
- return;
- }
- FnKind::ItemFn(ident, _, ref header, ..) => {
- ident_span = ident.span;
- fn_header = header;
- }
-
- FnKind::Method(ident, ref sig, ..) => {
- ident_span = ident.span;
- fn_header = &sig.header;
- }
+fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+ let items = tcx.hir_module_items(module_def_id);
+ for def_id in items.definitions() {
+ if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
+ continue;
}
- let attrs = self.tcx.hir().attrs(hir_id);
- let naked = attrs.iter().any(|attr| attr.has_name(sym::naked));
- if naked {
- let body = self.tcx.hir().body(body_id);
- check_abi(self.tcx, hir_id, fn_header.abi, ident_span);
- check_no_patterns(self.tcx, body.params);
- check_no_parameters_use(self.tcx, body);
- check_asm(self.tcx, body, span);
- check_inline(self.tcx, attrs);
+ let naked = tcx.has_attr(def_id.to_def_id(), sym::naked);
+ if !naked {
+ continue;
}
+
+ let (fn_header, body_id) = match tcx.hir().get_by_def_id(def_id) {
+ hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })
+ | hir::Node::TraitItem(hir::TraitItem {
+ kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
+ ..
+ })
+ | hir::Node::ImplItem(hir::ImplItem {
+ kind: hir::ImplItemKind::Fn(sig, body_id),
+ ..
+ }) => (sig.header, *body_id),
+ _ => continue,
+ };
+
+ let body = tcx.hir().body(body_id);
+ check_abi(tcx, def_id, fn_header.abi);
+ check_no_patterns(tcx, body.params);
+ check_no_parameters_use(tcx, body);
+ check_asm(tcx, def_id, body);
+ check_inline(tcx, def_id);
}
}
/// Check that the function isn't inlined.
-fn check_inline(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
- for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) {
+fn check_inline(tcx: TyCtxt<'_>, def_id: LocalDefId) {
+ let attrs = tcx.get_attrs(def_id.to_def_id(), sym::inline);
+ for attr in attrs {
tcx.sess.struct_span_err(attr.span, "naked functions cannot be inlined").emit();
}
}
/// Checks that function uses non-Rust ABI.
-fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) {
+fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) {
if abi == Abi::Rust {
- tcx.struct_span_lint_hir(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, fn_ident_span, |lint| {
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+ let span = tcx.def_span(def_id);
+ tcx.struct_span_lint_hir(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, span, |lint| {
lint.build("Rust ABI is unsupported in naked functions").emit();
});
}
@@ -88,7 +76,7 @@ fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
for param in params {
match param.pat.kind {
hir::PatKind::Wild
- | hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, None) => {}
+ | hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, _, None) => {}
_ => {
tcx.sess
.struct_span_err(
@@ -141,7 +129,7 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
}
/// Checks that function body contains a single inline assembly block.
-fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>, fn_span: Span) {
+fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
let mut this = CheckInlineAssembly { tcx, items: Vec::new() };
this.visit_body(body);
if let [(ItemKind::Asm | ItemKind::Err, _)] = this.items[..] {
@@ -149,7 +137,7 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>, fn_span: Span
} else {
let mut diag = struct_span_err!(
tcx.sess,
- fn_span,
+ tcx.def_span(def_id),
E0787,
"naked functions must contain a single asm block"
);
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index ca6a2ac3d..9ba127609 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -1,8 +1,10 @@
//! A pass that annotates every item and method with its stability level,
//! propagating default levels lexically from parent to children ast nodes.
-use attr::StabilityLevel;
-use rustc_attr::{self as attr, ConstStability, Stability, Unstable, UnstableReason};
+use rustc_attr::{
+ self as attr, rust_version_symbol, ConstStability, Stability, StabilityLevel, Unstable,
+ UnstableReason, VERSION_PLACEHOLDER,
+};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
@@ -10,7 +12,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_hir::hir_id::CRATE_HIR_ID;
use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{FieldDef, Generics, HirId, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
+use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
@@ -161,7 +163,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
return;
}
- let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
+ let (stab, const_stab, body_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
let mut const_span = None;
let const_stab = const_stab.map(|(const_stab, const_span_node)| {
@@ -209,6 +211,13 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
}
}
+ if let Some((body_stab, _span)) = body_stab {
+ // FIXME: check that this item can have body stability
+
+ self.index.default_body_stab_map.insert(def_id, body_stab);
+ debug!(?self.index.default_body_stab_map);
+ }
+
let stab = stab.map(|(stab, span)| {
// Error if prohibited, or can't inherit anything from a container.
if kind == AnnotationKind::Prohibited
@@ -434,7 +443,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
);
}
- fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
+ fn visit_variant(&mut self, var: &'tcx Variant<'tcx>) {
self.annotate(
self.tcx.hir().local_def_id(var.id),
var.span,
@@ -452,12 +461,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
- InheritStability::No,
+ InheritStability::Yes,
|_| {},
);
}
- intravisit::walk_variant(v, var, g, item_id)
+ intravisit::walk_variant(v, var)
},
)
}
@@ -590,9 +599,12 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
intravisit::walk_impl_item(self, ii);
}
- fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
+ fn visit_variant(&mut self, var: &'tcx Variant<'tcx>) {
self.check_missing_stability(self.tcx.hir().local_def_id(var.id), var.span);
- intravisit::walk_variant(self, var, g, item_id);
+ if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
+ self.check_missing_stability(self.tcx.hir().local_def_id(ctor_hir_id), var.span);
+ }
+ intravisit::walk_variant(self, var);
}
fn visit_field_def(&mut self, s: &'tcx FieldDef<'tcx>) {
@@ -613,6 +625,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
let mut index = Index {
stab_map: Default::default(),
const_stab_map: Default::default(),
+ default_body_stab_map: Default::default(),
depr_map: Default::default(),
implications: Default::default(),
};
@@ -673,6 +686,9 @@ pub(crate) fn provide(providers: &mut Providers) {
stability_implications: |tcx, _| tcx.stability().implications.clone(),
lookup_stability: |tcx, id| tcx.stability().local_stability(id.expect_local()),
lookup_const_stability: |tcx, id| tcx.stability().local_const_stability(id.expect_local()),
+ lookup_default_body_stability: |tcx, id| {
+ tcx.stability().local_default_body_stability(id.expect_local())
+ },
lookup_deprecation_entry: |tcx, id| {
tcx.stability().local_deprecation_entry(id.expect_local())
},
@@ -723,7 +739,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
let features = self.tcx.features();
if features.staged_api {
let attrs = self.tcx.hir().attrs(item.hir_id());
- let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item.span);
+ let (stab, const_stab, _) =
+ attr::find_stability(&self.tcx.sess, attrs, item.span);
// If this impl block has an #[unstable] attribute, give an
// error if all involved types and traits are stable, because
@@ -816,7 +833,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
// added, such as `core::intrinsics::transmute`
let parents = path.segments.iter().rev().skip(1);
for path_segment in parents {
- if let Some(def_id) = path_segment.res.as_ref().and_then(Res::opt_def_id) {
+ if let Some(def_id) = path_segment.res.opt_def_id() {
// use `None` for id to prevent deprecation check
self.tcx.check_stability_allow_unstable(
def_id,
@@ -949,51 +966,90 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
remaining_lib_features.remove(&sym::libc);
remaining_lib_features.remove(&sym::test);
- // We always collect the lib features declared in the current crate, even if there are
- // no unknown features, because the collection also does feature attribute validation.
- let local_defined_features = tcx.lib_features(());
- let mut all_lib_features: FxHashMap<_, _> =
- local_defined_features.to_vec().iter().map(|el| *el).collect();
- let mut implications = tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
- for &cnum in tcx.crates(()) {
- implications.extend(tcx.stability_implications(cnum));
- all_lib_features.extend(tcx.defined_lib_features(cnum).iter().map(|el| *el));
- }
-
- // Check that every feature referenced by an `implied_by` exists (for features defined in the
- // local crate).
- for (implied_by, feature) in tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE) {
- // Only `implied_by` needs to be checked, `feature` is guaranteed to exist.
- if !all_lib_features.contains_key(implied_by) {
- let span = local_defined_features
- .stable
- .get(feature)
- .map(|(_, span)| span)
- .or_else(|| local_defined_features.unstable.get(feature))
- .expect("feature that implied another does not exist");
- tcx.sess
- .struct_span_err(
- *span,
- format!("feature `{implied_by}` implying `{feature}` does not exist"),
- )
- .emit();
- }
- }
-
- if !remaining_lib_features.is_empty() {
- for (feature, since) in all_lib_features.iter() {
+ /// For each feature in `defined_features`..
+ ///
+ /// - If it is in `remaining_lib_features` (those features with `#![feature(..)]` attributes in
+ /// the current crate), check if it is stable (or partially stable) and thus an unnecessary
+ /// attribute.
+ /// - If it is in `remaining_implications` (a feature that is referenced by an `implied_by`
+ /// from the current crate), then remove it from the remaining implications.
+ ///
+ /// Once this function has been invoked for every feature (local crate and all extern crates),
+ /// then..
+ ///
+ /// - If features remain in `remaining_lib_features`, then the user has enabled a feature that
+ /// does not exist.
+ /// - If features remain in `remaining_implications`, the `implied_by` refers to a feature that
+ /// does not exist.
+ ///
+ /// By structuring the code in this way: checking the features defined from each crate one at a
+ /// time, less loading from metadata is performed and thus compiler performance is improved.
+ fn check_features<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ remaining_lib_features: &mut FxIndexMap<&Symbol, Span>,
+ remaining_implications: &mut FxHashMap<Symbol, Symbol>,
+ defined_features: &[(Symbol, Option<Symbol>)],
+ all_implications: &FxHashMap<Symbol, Symbol>,
+ ) {
+ for (feature, since) in defined_features {
if let Some(since) = since && let Some(span) = remaining_lib_features.get(&feature) {
// Warn if the user has enabled an already-stable lib feature.
- if let Some(implies) = implications.get(&feature) {
+ if let Some(implies) = all_implications.get(&feature) {
unnecessary_partially_stable_feature_lint(tcx, *span, *feature, *implies, *since);
} else {
unnecessary_stable_feature_lint(tcx, *span, *feature, *since);
}
+
+ }
+ remaining_lib_features.remove(feature);
+
+ // `feature` is the feature doing the implying, but `implied_by` is the feature with
+ // the attribute that establishes this relationship. `implied_by` is guaranteed to be a
+ // feature defined in the local crate because `remaining_implications` is only the
+ // implications from this crate.
+ remaining_implications.remove(feature);
+
+ if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
+ break;
}
- remaining_lib_features.remove(&feature);
- if remaining_lib_features.is_empty() {
+ }
+ }
+
+ // All local crate implications need to have the feature that implies it confirmed to exist.
+ let mut remaining_implications =
+ tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
+
+ // We always collect the lib features declared in the current crate, even if there are
+ // no unknown features, because the collection also does feature attribute validation.
+ let local_defined_features = tcx.lib_features(()).to_vec();
+ if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
+ // Loading the implications of all crates is unavoidable to be able to emit the partial
+ // stabilization diagnostic, but it can be avoided when there are no
+ // `remaining_lib_features`.
+ let mut all_implications = remaining_implications.clone();
+ for &cnum in tcx.crates(()) {
+ all_implications.extend(tcx.stability_implications(cnum));
+ }
+
+ check_features(
+ tcx,
+ &mut remaining_lib_features,
+ &mut remaining_implications,
+ local_defined_features.as_slice(),
+ &all_implications,
+ );
+
+ for &cnum in tcx.crates(()) {
+ if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
break;
}
+ check_features(
+ tcx,
+ &mut remaining_lib_features,
+ &mut remaining_implications,
+ tcx.defined_lib_features(cnum).to_vec().as_slice(),
+ &all_implications,
+ );
}
}
@@ -1001,6 +1057,22 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
}
+ for (implied_by, feature) in remaining_implications {
+ let local_defined_features = tcx.lib_features(());
+ let span = local_defined_features
+ .stable
+ .get(&feature)
+ .map(|(_, span)| span)
+ .or_else(|| local_defined_features.unstable.get(&feature))
+ .expect("feature that implied another does not exist");
+ tcx.sess
+ .struct_span_err(
+ *span,
+ format!("feature `{implied_by}` implying `{feature}` does not exist"),
+ )
+ .emit();
+ }
+
// FIXME(#44232): the `used_features` table no longer exists, so we
// don't lint about unused features. We should re-enable this one day!
}
@@ -1035,7 +1107,15 @@ fn unnecessary_partially_stable_feature_lint(
});
}
-fn unnecessary_stable_feature_lint(tcx: TyCtxt<'_>, span: Span, feature: Symbol, since: Symbol) {
+fn unnecessary_stable_feature_lint(
+ tcx: TyCtxt<'_>,
+ span: Span,
+ feature: Symbol,
+ mut since: Symbol,
+) {
+ if since.as_str() == VERSION_PLACEHOLDER {
+ since = rust_version_symbol();
+ }
tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| {
lint.build(&format!(
"the feature `{feature}` has been stable since {since} and no longer requires an \
diff --git a/compiler/rustc_plugin_impl/Cargo.toml b/compiler/rustc_plugin_impl/Cargo.toml
index b6ea533c8..c409b6c3e 100644
--- a/compiler/rustc_plugin_impl/Cargo.toml
+++ b/compiler/rustc_plugin_impl/Cargo.toml
@@ -11,6 +11,7 @@ doctest = false
libloading = "0.7.1"
rustc_errors = { path = "../rustc_errors" }
rustc_lint = { path = "../rustc_lint" }
+rustc_macros = { path = "../rustc_macros" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_ast = { path = "../rustc_ast" }
rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_plugin_impl/src/errors.rs b/compiler/rustc_plugin_impl/src/errors.rs
new file mode 100644
index 000000000..2bdb6e4fe
--- /dev/null
+++ b/compiler/rustc_plugin_impl/src/errors.rs
@@ -0,0 +1,20 @@
+//! Errors emitted by plugin_impl
+
+use rustc_macros::SessionDiagnostic;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[diag(plugin_impl::load_plugin_error)]
+pub struct LoadPluginError {
+ #[primary_span]
+ pub span: Span,
+ pub msg: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(plugin_impl::malformed_plugin_attribute, code = "E0498")]
+pub struct MalformedPluginAttribute {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
diff --git a/compiler/rustc_plugin_impl/src/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs
index 1195045bd..9ac27c65d 100644
--- a/compiler/rustc_plugin_impl/src/lib.rs
+++ b/compiler/rustc_plugin_impl/src/lib.rs
@@ -8,9 +8,12 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_lint::LintStore;
+mod errors;
pub mod load;
/// Structure used to register plugins.
diff --git a/compiler/rustc_plugin_impl/src/load.rs b/compiler/rustc_plugin_impl/src/load.rs
index 618682da4..8e75e969a 100644
--- a/compiler/rustc_plugin_impl/src/load.rs
+++ b/compiler/rustc_plugin_impl/src/load.rs
@@ -1,16 +1,14 @@
//! Used by `rustc` when loading a plugin.
+use crate::errors::{LoadPluginError, MalformedPluginAttribute};
use crate::Registry;
use libloading::Library;
use rustc_ast::Crate;
-use rustc_errors::struct_span_err;
use rustc_metadata::locator;
use rustc_session::cstore::MetadataLoader;
use rustc_session::Session;
use rustc_span::symbol::{sym, Ident};
-use rustc_span::Span;
-use std::borrow::ToOwned;
use std::env;
use std::mem;
use std::path::PathBuf;
@@ -18,12 +16,6 @@ use std::path::PathBuf;
/// Pointer to a registrar function.
type PluginRegistrarFn = fn(&mut Registry<'_>);
-fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
- struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
- .span_label(span, "malformed attribute")
- .emit();
-}
-
/// Read plugin metadata and dynamically load registrar functions.
pub fn load_plugins(
sess: &Session,
@@ -42,7 +34,9 @@ pub fn load_plugins(
Some(ident) if plugin.is_word() => {
load_plugin(&mut plugins, sess, metadata_loader, ident)
}
- _ => call_malformed_plugin_attribute(sess, plugin.span()),
+ _ => {
+ sess.emit_err(MalformedPluginAttribute { span: plugin.span() });
+ }
}
}
}
@@ -60,7 +54,7 @@ fn load_plugin(
let fun = dylink_registrar(lib).unwrap_or_else(|err| {
// This is fatal: there are almost certainly macros we need inside this crate, so
// continuing would spew "macro undefined" errors.
- sess.span_fatal(ident.span, &err.to_string());
+ sess.emit_fatal(LoadPluginError { span: ident.span, msg: err.to_string() });
});
plugins.push(fun);
}
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index aca7d770f..63f83f896 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -3,7 +3,7 @@ use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
use rustc_span::{Span, Symbol};
#[derive(SessionDiagnostic)]
-#[error(privacy::field_is_private, code = "E0451")]
+#[diag(privacy::field_is_private, code = "E0451")]
pub struct FieldIsPrivate {
#[primary_span]
pub span: Span,
@@ -30,7 +30,7 @@ pub enum FieldIsPrivateLabel {
}
#[derive(SessionDiagnostic)]
-#[error(privacy::item_is_private)]
+#[diag(privacy::item_is_private)]
pub struct ItemIsPrivate<'a> {
#[primary_span]
#[label]
@@ -40,7 +40,7 @@ pub struct ItemIsPrivate<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(privacy::unnamed_item_is_private)]
+#[diag(privacy::unnamed_item_is_private)]
pub struct UnnamedItemIsPrivate {
#[primary_span]
pub span: Span,
@@ -49,7 +49,7 @@ pub struct UnnamedItemIsPrivate {
// Duplicate of `InPublicInterface` but with a different error code, shares the same slug.
#[derive(SessionDiagnostic)]
-#[error(privacy::in_public_interface, code = "E0445")]
+#[diag(privacy::in_public_interface, code = "E0445")]
pub struct InPublicInterfaceTraits<'a> {
#[primary_span]
#[label]
@@ -63,7 +63,7 @@ pub struct InPublicInterfaceTraits<'a> {
// Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug.
#[derive(SessionDiagnostic)]
-#[error(privacy::in_public_interface, code = "E0446")]
+#[diag(privacy::in_public_interface, code = "E0446")]
pub struct InPublicInterface<'a> {
#[primary_span]
#[label]
@@ -75,8 +75,16 @@ pub struct InPublicInterface<'a> {
pub vis_span: Span,
}
+#[derive(SessionDiagnostic)]
+#[diag(privacy::report_access_level)]
+pub struct ReportAccessLevel {
+ #[primary_span]
+ pub span: Span,
+ pub descr: String,
+}
+
#[derive(LintDiagnostic)]
-#[lint(privacy::from_private_dep_in_public_interface)]
+#[diag(privacy::from_private_dep_in_public_interface)]
pub struct FromPrivateDependencyInPublicInterface<'a> {
pub kind: &'a str,
pub descr: DiagnosticArgFromDisplay<'a>,
@@ -84,7 +92,7 @@ pub struct FromPrivateDependencyInPublicInterface<'a> {
}
#[derive(LintDiagnostic)]
-#[lint(privacy::private_in_public_lint)]
+#[diag(privacy::private_in_public_lint)]
pub struct PrivateInPublicLint<'a> {
pub vis_descr: &'static str,
pub kind: &'a str,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index c28d0569d..48ab31ab9 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1,12 +1,15 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(associated_type_defaults)]
#![feature(control_flow_enum)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(rustc_private)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(bootstrap), deny(rustc::untranslatable_diagnostic))]
-#![cfg_attr(not(bootstrap), deny(rustc::diagnostic_outside_of_impl))]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
+#[macro_use]
+extern crate tracing;
mod errors;
@@ -30,7 +33,7 @@ use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::hygiene::Transparency;
-use rustc_span::symbol::{kw, Ident};
+use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use std::marker::PhantomData;
@@ -39,7 +42,8 @@ use std::{cmp, fmt, mem};
use errors::{
FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
- InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, UnnamedItemIsPrivate,
+ InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportAccessLevel,
+ UnnamedItemIsPrivate,
};
////////////////////////////////////////////////////////////////////////////////
@@ -330,7 +334,9 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL>
_kind: &str,
_descr: &dyn fmt::Display,
) -> ControlFlow<Self::BreakTy> {
- self.min = VL::new_min(self, def_id);
+ if let Some(def_id) = def_id.as_local() {
+ self.min = VL::new_min(self, def_id);
+ }
ControlFlow::CONTINUE
}
}
@@ -338,7 +344,7 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL>
trait VisibilityLike: Sized {
const MAX: Self;
const SHALLOW: bool = false;
- fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self;
+ fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self;
// Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
// associated types for which we can't determine visibility precisely.
@@ -353,8 +359,8 @@ trait VisibilityLike: Sized {
}
impl VisibilityLike for ty::Visibility {
const MAX: Self = ty::Visibility::Public;
- fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self {
- min(find.tcx.visibility(def_id), find.min, find.tcx)
+ fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
+ min(find.tcx.local_visibility(def_id), find.min, find.tcx)
}
}
impl VisibilityLike for Option<AccessLevel> {
@@ -369,15 +375,8 @@ impl VisibilityLike for Option<AccessLevel> {
// both "shallow" version of its self type and "shallow" version of its trait if it exists
// (which require reaching the `DefId`s in them).
const SHALLOW: bool = true;
- fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self {
- cmp::min(
- if let Some(def_id) = def_id.as_local() {
- find.access_levels.map.get(&def_id).copied()
- } else {
- Self::MAX
- },
- find.min,
- )
+ fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
+ cmp::min(find.access_levels.map.get(&def_id).copied(), find.min)
}
}
@@ -507,15 +506,15 @@ impl<'tcx> EmbargoVisitor<'tcx> {
let module = self.tcx.hir().get_module(module_def_id).0;
for item_id in module.item_ids {
let def_kind = self.tcx.def_kind(item_id.def_id);
- let vis = self.tcx.visibility(item_id.def_id);
+ let vis = self.tcx.local_visibility(item_id.def_id);
self.update_macro_reachable_def(item_id.def_id, def_kind, vis, defining_mod);
}
if let Some(exports) = self.tcx.module_reexports(module_def_id) {
for export in exports {
- if export.vis.is_accessible_from(defining_mod.to_def_id(), self.tcx) {
+ if export.vis.is_accessible_from(defining_mod, self.tcx) {
if let Res::Def(def_kind, def_id) = export.res {
if let Some(def_id) = def_id.as_local() {
- let vis = self.tcx.visibility(def_id.to_def_id());
+ let vis = self.tcx.local_visibility(def_id);
self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod);
}
}
@@ -538,7 +537,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
match def_kind {
// No type privacy, so can be directly marked as reachable.
DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => {
- if vis.is_accessible_from(module.to_def_id(), self.tcx) {
+ if vis.is_accessible_from(module, self.tcx) {
self.update(def_id, level);
}
}
@@ -550,7 +549,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
DefKind::Macro(_) => {
let item = self.tcx.hir().expect_item(def_id);
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind {
- if vis.is_accessible_from(module.to_def_id(), self.tcx) {
+ if vis.is_accessible_from(module, self.tcx) {
self.update(def_id, level);
}
}
@@ -561,7 +560,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
// hygiene these don't need to be marked reachable. The contents of
// the module, however may be reachable.
DefKind::Mod => {
- if vis.is_accessible_from(module.to_def_id(), self.tcx) {
+ if vis.is_accessible_from(module, self.tcx) {
self.update_macro_reachable(def_id, module);
}
}
@@ -575,8 +574,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
{
for field in struct_def.fields() {
let def_id = self.tcx.hir().local_def_id(field.hir_id);
- let field_vis = self.tcx.visibility(def_id);
- if field_vis.is_accessible_from(module.to_def_id(), self.tcx) {
+ let field_vis = self.tcx.local_visibility(def_id);
+ if field_vis.is_accessible_from(module, self.tcx) {
self.reach(def_id, level).ty();
}
}
@@ -596,6 +595,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
| DefKind::ForeignTy
| DefKind::Fn
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::AssocFn
| DefKind::Trait
| DefKind::TyParam
@@ -650,7 +650,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
hir::ItemKind::Impl(ref impl_) => {
for impl_item_ref in impl_.items {
if impl_.of_trait.is_some()
- || self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
+ || self.tcx.visibility(impl_item_ref.id.def_id).is_public()
{
self.update(impl_item_ref.id.def_id, item_level);
}
@@ -678,7 +678,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
}
hir::ItemKind::ForeignMod { items, .. } => {
for foreign_item in items {
- if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public {
+ if self.tcx.visibility(foreign_item.id.def_id).is_public() {
self.update(foreign_item.id.def_id, item_level);
}
}
@@ -706,12 +706,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
hir::ItemKind::Use(..) => {}
// The interface is empty.
hir::ItemKind::GlobalAsm(..) => {}
- hir::ItemKind::OpaqueTy(..) => {
+ hir::ItemKind::OpaqueTy(ref opaque) => {
// HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
// Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
// mark this as unreachable.
// See https://github.com/rust-lang/rust/issues/75100
- if !self.tcx.sess.opts.actually_rustdoc {
+ if !opaque.in_trait && !self.tcx.sess.opts.actually_rustdoc {
// FIXME: This is some serious pessimization intended to workaround deficiencies
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
// reachable if they are returned via `impl Trait`, even from private functions.
@@ -904,6 +904,60 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
}
}
+////////////////////////////////////////////////////////////////////////////////
+/// Visitor, used for AccessLevels table checking
+////////////////////////////////////////////////////////////////////////////////
+pub struct TestReachabilityVisitor<'tcx, 'a> {
+ tcx: TyCtxt<'tcx>,
+ access_levels: &'a AccessLevels,
+}
+
+impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
+ fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
+ if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_access_level) {
+ let access_level = format!("{:?}", self.access_levels.map.get(&def_id));
+ let span = self.tcx.def_span(def_id.to_def_id());
+ self.tcx.sess.emit_err(ReportAccessLevel { span, descr: access_level });
+ }
+ }
+}
+
+impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
+ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+ self.access_level_diagnostic(item.def_id);
+
+ match item.kind {
+ hir::ItemKind::Enum(ref def, _) => {
+ for variant in def.variants.iter() {
+ let variant_id = self.tcx.hir().local_def_id(variant.id);
+ self.access_level_diagnostic(variant_id);
+ for field in variant.data.fields() {
+ let def_id = self.tcx.hir().local_def_id(field.hir_id);
+ self.access_level_diagnostic(def_id);
+ }
+ }
+ }
+ hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
+ for field in def.fields() {
+ let def_id = self.tcx.hir().local_def_id(field.hir_id);
+ self.access_level_diagnostic(def_id);
+ }
+ }
+ _ => {}
+ }
+ }
+
+ fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
+ self.access_level_diagnostic(item.def_id);
+ }
+ fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
+ self.access_level_diagnostic(item.def_id);
+ }
+ fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
+ self.access_level_diagnostic(item.def_id);
+ }
+}
+
//////////////////////////////////////////////////////////////////////////////////////
/// Name privacy visitor, checks privacy and reports violations.
/// Most of name privacy checks are performed during the main resolution phase,
@@ -1059,7 +1113,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
}
fn item_is_accessible(&self, did: DefId) -> bool {
- self.tcx.visibility(did).is_accessible_from(self.current_item.to_def_id(), self.tcx)
+ self.tcx.visibility(did).is_accessible_from(self.current_item, self.tcx)
}
// Take node-id of an expression or pattern and check its type for privacy.
@@ -1260,7 +1314,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
}
}
- intravisit::walk_qpath(self, qpath, id, span);
+ intravisit::walk_qpath(self, qpath, id);
}
// Check types of patterns.
@@ -1551,8 +1605,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
let mut found_pub_static = false;
for impl_item_ref in impl_.items {
if self.access_levels.is_reachable(impl_item_ref.id.def_id)
- || self.tcx.visibility(impl_item_ref.id.def_id)
- == ty::Visibility::Public
+ || self.tcx.visibility(impl_item_ref.id.def_id).is_public()
{
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item_ref.kind {
@@ -1625,15 +1678,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
intravisit::walk_ty(self, t)
}
- fn visit_variant(
- &mut self,
- v: &'tcx hir::Variant<'tcx>,
- g: &'tcx hir::Generics<'tcx>,
- item_id: hir::HirId,
- ) {
+ fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
if self.access_levels.is_reachable(self.tcx.hir().local_def_id(v.id)) {
self.in_variant = true;
- intravisit::walk_variant(self, v, g, item_id);
+ intravisit::walk_variant(self, v);
self.in_variant = false;
}
}
@@ -1727,18 +1775,17 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
);
}
- let hir_id = match def_id.as_local() {
- Some(def_id) => self.tcx.hir().local_def_id_to_hir_id(def_id),
- None => return false,
+ let Some(local_def_id) = def_id.as_local() else {
+ return false;
};
- let vis = self.tcx.visibility(def_id);
+ let vis = self.tcx.local_visibility(local_def_id);
if !vis.is_at_least(self.required_visibility, self.tcx) {
+ let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
let vis_descr = match vis {
ty::Visibility::Public => "public",
- ty::Visibility::Invisible => "private",
ty::Visibility::Restricted(vis_def_id) => {
- if vis_def_id == self.tcx.parent_module(hir_id).to_def_id() {
+ if vis_def_id == self.tcx.parent_module(hir_id) {
"private"
} else if vis_def_id.is_top_level_module() {
"crate-private"
@@ -1790,7 +1837,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
fn leaks_private_dep(&self, item_id: DefId) -> bool {
let ret = self.required_visibility.is_public() && self.tcx.is_private_dep(item_id.krate);
- tracing::debug!("leaks_private_dep(item_id={:?})={}", item_id, ret);
+ debug!("leaks_private_dep(item_id={:?})={}", item_id, ret);
ret
}
}
@@ -1854,7 +1901,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
pub fn check_item(&mut self, id: ItemId) {
let tcx = self.tcx;
- let item_visibility = tcx.visibility(id.def_id);
+ let item_visibility = tcx.local_visibility(id.def_id);
let def_kind = tcx.def_kind(id.def_id);
match def_kind {
@@ -1905,7 +1952,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
let item = tcx.hir().item(id);
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
for foreign_item in items {
- let vis = tcx.visibility(foreign_item.id.def_id);
+ let vis = tcx.local_visibility(foreign_item.id.def_id);
self.check(foreign_item.id.def_id, vis).generics().predicates().ty();
}
}
@@ -1920,7 +1967,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
for field in struct_def.fields() {
let def_id = tcx.hir().local_def_id(field.hir_id);
- let field_visibility = tcx.visibility(def_id);
+ let field_visibility = tcx.local_visibility(def_id);
self.check(def_id, min(item_visibility, field_visibility, tcx)).ty();
}
}
@@ -1940,7 +1987,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
}
for impl_item_ref in impl_.items {
let impl_item_vis = if impl_.of_trait.is_none() {
- min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx)
+ min(tcx.local_visibility(impl_item_ref.id.def_id), impl_vis, tcx)
} else {
impl_vis
};
@@ -1967,8 +2014,11 @@ pub fn provide(providers: &mut Providers) {
};
}
-fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
- let def_id = def_id.expect_local();
+fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility<DefId> {
+ local_visibility(tcx, def_id.expect_local()).to_def_id()
+}
+
+fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
match tcx.resolutions(()).visibilities.get(&def_id) {
Some(vis) => *vis,
None => {
@@ -1983,9 +2033,10 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
// Visibility on them should have no effect, but to avoid the visibility
// query failing on some items, we provide it for opaque types as well.
| Node::Item(hir::Item {
- kind: hir::ItemKind::Use(_, hir::UseKind::ListStem) | hir::ItemKind::OpaqueTy(..),
+ kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
+ | hir::ItemKind::OpaqueTy(..),
..
- }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_def_id()),
+ }) => ty::Visibility::Restricted(tcx.parent_module(hir_id)),
// Visibilities of trait impl items are inherited from their traits
// and are not filled in resolve.
Node::ImplItem(impl_item) => {
@@ -1998,7 +2049,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
tcx.sess.delay_span_bug(tr.path.span, "trait without a def-id");
ty::Visibility::Public
},
- |def_id| tcx.visibility(def_id),
+ |def_id| tcx.visibility(def_id).expect_local(),
),
_ => span_bug!(impl_item.span, "the parent is not a trait impl"),
}
@@ -2048,6 +2099,9 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
}
}
+ let mut check_visitor = TestReachabilityVisitor { tcx, access_levels: &visitor.access_levels };
+ tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
+
tcx.arena.alloc(visitor.access_levels)
}
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index 5673bb83b..e7f12caaf 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -8,7 +8,6 @@ doctest = false
[dependencies]
measureme = "10.0.0"
-rustc-rayon-core = { version = "0.4.0", optional = true }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
@@ -17,9 +16,12 @@ rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_query_system = { path = "../rustc_query_system" }
+rustc-rayon-core = { version = "0.4.0", optional = true }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+thin-vec = "0.2.8"
tracing = "0.1"
[features]
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index eda61df77..c87d26b39 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -7,16 +7,17 @@
#![feature(rustc_attrs)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
#[macro_use]
extern crate rustc_middle;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::AtomicU64;
use rustc_middle::arena::Arena;
-use rustc_middle::dep_graph::{self, DepKindStruct, SerializedDepNodeIndex};
+use rustc_middle::dep_graph::{self, DepKindStruct};
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine};
use rustc_middle::ty::{self, TyCtxt};
@@ -33,9 +34,6 @@ pub use rustc_query_system::query::{deadlock, QueryContext};
mod keys;
use keys::Key;
-mod values;
-use self::values::Value;
-
pub use rustc_query_system::query::QueryConfig;
pub(crate) use rustc_query_system::query::{QueryDescription, QueryVTable};
@@ -53,7 +51,7 @@ fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
}
}
-rustc_query_append! { [define_queries!][<'tcx>] }
+rustc_query_append! { define_queries! }
impl<'tcx> Queries<'tcx> {
// Force codegen in the dyn-trait transformation in this crate.
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 56fd90c98..0e93f3ce1 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -22,8 +22,9 @@ use rustc_span::hygiene::{
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
};
use rustc_span::source_map::{SourceMap, StableSourceFileId};
-use rustc_span::CachingSourceMapView;
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
+use rustc_span::{CachingSourceMapView, Symbol};
+use std::collections::hash_map::Entry;
use std::io;
use std::mem;
@@ -38,6 +39,11 @@ const TAG_RELATIVE_SPAN: u8 = 2;
const TAG_SYNTAX_CONTEXT: u8 = 0;
const TAG_EXPN_DATA: u8 = 1;
+// Tags for encoding Symbol's
+const SYMBOL_STR: u8 = 0;
+const SYMBOL_OFFSET: u8 = 1;
+const SYMBOL_PREINTERNED: u8 = 2;
+
/// Provides an interface to incremental compilation data cached from the
/// previous compilation session. This data will eventually include the results
/// of a few selected queries (like `typeck` and `mir_optimized`) and
@@ -254,6 +260,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
source_map: CachingSourceMapView::new(tcx.sess.source_map()),
file_to_file_index,
hygiene_context: &hygiene_encode_context,
+ symbol_table: Default::default(),
};
// Encode query results.
@@ -714,6 +721,40 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
}
}
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol {
+ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+ let tag = d.read_u8();
+
+ match tag {
+ SYMBOL_STR => {
+ let s = d.read_str();
+ Symbol::intern(s)
+ }
+ SYMBOL_OFFSET => {
+ // read str offset
+ let pos = d.read_usize();
+ let old_pos = d.opaque.position();
+
+ // move to str ofset and read
+ d.opaque.set_position(pos);
+ let s = d.read_str();
+ let sym = Symbol::intern(s);
+
+ // restore position
+ d.opaque.set_position(old_pos);
+
+ sym
+ }
+ SYMBOL_PREINTERNED => {
+ let symbol_index = d.read_u32();
+ Symbol::new_from_decoded(symbol_index)
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
let stable_id = StableCrateId::decode(d);
@@ -757,6 +798,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId>
}
}
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> {
+ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+ RefDecodable::decode(d)
+ }
+}
+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
for &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>>
{
@@ -815,6 +862,7 @@ pub struct CacheEncoder<'a, 'tcx> {
source_map: CachingSourceMapView<'tcx>,
file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
hygiene_context: &'a HygieneEncodeContext,
+ symbol_table: FxHashMap<Symbol, usize>,
}
impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
@@ -899,6 +947,32 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
}
}
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Symbol {
+ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
+ // if symbol preinterned, emit tag and symbol index
+ if self.is_preinterned() {
+ s.encoder.emit_u8(SYMBOL_PREINTERNED);
+ s.encoder.emit_u32(self.as_u32());
+ } else {
+ // otherwise write it as string or as offset to it
+ match s.symbol_table.entry(*self) {
+ Entry::Vacant(o) => {
+ s.encoder.emit_u8(SYMBOL_STR);
+ let pos = s.encoder.position();
+ o.insert(pos);
+ s.emit_str(self.as_str());
+ }
+ Entry::Occupied(o) => {
+ let x = o.get().clone();
+ s.emit_u8(SYMBOL_OFFSET);
+ s.emit_usize(x);
+ }
+ }
+ }
+ }
+}
+
impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
type I = TyCtxt<'tcx>;
const CLEAR_CROSS_CRATE: bool = false;
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index eda4401c8..6f39bbfc0 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -2,19 +2,28 @@
//! generate the actual methods on tcx which find and execute the provider,
//! manage the caches, and so forth.
+use crate::keys::Key;
+use crate::on_disk_cache::CacheDecoder;
use crate::{on_disk_cache, Queries};
-use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use rustc_middle::ty::tls::{self, ImplicitCtxt};
-use rustc_middle::ty::TyCtxt;
-use rustc_query_system::dep_graph::HasDepContext;
-use rustc_query_system::query::{QueryContext, QueryJobId, QueryMap, QuerySideEffects};
-
-use rustc_data_structures::sync::Lock;
-use rustc_data_structures::thin_vec::ThinVec;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::sync::{AtomicU64, Lock};
use rustc_errors::{Diagnostic, Handler};
-
+use rustc_middle::dep_graph::{
+ self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
+};
+use rustc_middle::ty::tls::{self, ImplicitCtxt};
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
+use rustc_query_system::ich::StableHashingContext;
+use rustc_query_system::query::{
+ force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
+ QuerySideEffects, QueryStackFrame,
+};
+use rustc_query_system::Value;
+use rustc_serialize::Decodable;
use std::any::Any;
use std::num::NonZeroU64;
+use thin_vec::ThinVec;
#[derive(Copy, Clone)]
pub struct QueryCtxt<'tcx> {
@@ -91,6 +100,7 @@ impl QueryContext for QueryCtxt<'_> {
fn start_query<R>(
&self,
token: QueryJobId,
+ depth_limit: bool,
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
compute: impl FnOnce() -> R,
) -> R {
@@ -98,12 +108,16 @@ impl QueryContext for QueryCtxt<'_> {
// as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
// when accessing the `ImplicitCtxt`.
tls::with_related_context(**self, move |current_icx| {
+ if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) {
+ self.depth_limit_error();
+ }
+
// Update the `ImplicitCtxt` to point to our new query job.
let new_icx = ImplicitCtxt {
tcx: **self,
query: Some(token),
diagnostics,
- layout_depth: current_icx.layout_depth,
+ query_depth: current_icx.query_depth + depth_limit as usize,
task_deps: current_icx.task_deps,
};
@@ -137,19 +151,31 @@ impl<'tcx> QueryCtxt<'tcx> {
encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>,
query_result_index: &mut on_disk_cache::EncodedDepNodeIndex,
) {
+ macro_rules! expand_if_cached {
+ ([] $encode:expr) => {};
+ ([(cache) $($rest:tt)*] $encode:expr) => {
+ $encode
+ };
+ ([$other:tt $($modifiers:tt)*] $encode:expr) => {
+ expand_if_cached!([$($modifiers)*] $encode)
+ };
+ }
+
macro_rules! encode_queries {
- ($($query:ident,)*) => {
+ (
+ $($(#[$attr:meta])*
+ [$($modifiers:tt)*] fn $query:ident($($K:tt)*) -> $V:ty,)*) => {
$(
- on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>(
+ expand_if_cached!([$($modifiers)*] on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>(
self,
encoder,
query_result_index
- );
+ ));
)*
}
}
- rustc_cached_queries!(encode_queries!);
+ rustc_query_append!(encode_queries!);
}
pub fn try_print_query_stack(
@@ -163,21 +189,17 @@ impl<'tcx> QueryCtxt<'tcx> {
}
macro_rules! handle_cycle_error {
- ([][$tcx: expr, $error:expr]) => {{
- $error.emit();
- Value::from_cycle_error($tcx)
+ ([]) => {{
+ rustc_query_system::HandleCycleError::Error
}};
- ([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
- $error.emit();
- $tcx.sess.abort_if_errors();
- unreachable!()
+ ([(fatal_cycle) $($rest:tt)*]) => {{
+ rustc_query_system::HandleCycleError::Fatal
}};
- ([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
- $error.delay_as_bug();
- Value::from_cycle_error($tcx)
+ ([(cycle_delay_bug) $($rest:tt)*]) => {{
+ rustc_query_system::HandleCycleError::DelayBug
}};
- ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
- handle_cycle_error!([$($modifiers)*][$($args)*])
+ ([$other:tt $($modifiers:tt)*]) => {
+ handle_cycle_error!([$($modifiers)*])
};
}
@@ -205,6 +227,18 @@ macro_rules! is_eval_always {
};
}
+macro_rules! depth_limit {
+ ([]) => {{
+ false
+ }};
+ ([(depth_limit) $($rest:tt)*]) => {{
+ true
+ }};
+ ([$other:tt $($modifiers:tt)*]) => {
+ depth_limit!([$($modifiers)*])
+ };
+}
+
macro_rules! hash_result {
([]) => {{
Some(dep_graph::hash_result)
@@ -233,106 +267,174 @@ macro_rules! get_provider {
};
}
-macro_rules! opt_remap_env_constness {
- ([][$name:ident]) => {};
- ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
- let $name = $name.without_const();
+macro_rules! should_ever_cache_on_disk {
+ ([]) => {{
+ None
+ }};
+ ([(cache) $($rest:tt)*]) => {{
+ Some($crate::plumbing::try_load_from_disk::<Self::Value>)
+ }};
+ ([$other:tt $($modifiers:tt)*]) => {
+ should_ever_cache_on_disk!([$($modifiers)*])
};
- ([$other:tt $($modifiers:tt)*][$name:ident]) => {
- opt_remap_env_constness!([$($modifiers)*][$name])
+}
+
+pub(crate) fn create_query_frame<
+ 'tcx,
+ K: Copy + Key + for<'a> HashStable<StableHashingContext<'a>>,
+>(
+ tcx: QueryCtxt<'tcx>,
+ do_describe: fn(QueryCtxt<'tcx>, K) -> String,
+ key: K,
+ kind: DepKind,
+ name: &'static str,
+) -> QueryStackFrame {
+ // Disable visible paths printing for performance reasons.
+ // Showing visible path instead of any path is not that important in production.
+ let description = ty::print::with_no_visible_paths!(
+ // Force filename-line mode to avoid invoking `type_of` query.
+ ty::print::with_forced_impl_filename_line!(do_describe(tcx, key))
+ );
+ let description =
+ if tcx.sess.verbose() { format!("{} [{}]", description, name) } else { description };
+ let span = if kind == dep_graph::DepKind::def_span {
+ // The `def_span` query is used to calculate `default_span`,
+ // so exit to avoid infinite recursion.
+ None
+ } else {
+ Some(key.default_span(*tcx))
};
+ let def_kind = if kind == dep_graph::DepKind::opt_def_kind {
+ // Try to avoid infinite recursion.
+ None
+ } else {
+ key.key_as_def_id()
+ .and_then(|def_id| def_id.as_local())
+ .and_then(|def_id| tcx.opt_def_kind(def_id))
+ };
+ let hash = || {
+ tcx.with_stable_hashing_context(|mut hcx| {
+ let mut hasher = StableHasher::new();
+ std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
+ key.hash_stable(&mut hcx, &mut hasher);
+ hasher.finish::<u64>()
+ })
+ };
+
+ QueryStackFrame::new(name, description, span, def_kind, hash)
+}
+
+fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode)
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+{
+ debug_assert!(tcx.dep_graph.is_green(&dep_node));
+
+ let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
+ panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
+ });
+ if Q::cache_on_disk(tcx, &key) {
+ let _ = Q::execute_query(tcx, key);
+ }
+}
+
+pub(crate) fn try_load_from_disk<'tcx, V>(
+ tcx: QueryCtxt<'tcx>,
+ id: SerializedDepNodeIndex,
+) -> Option<V>
+where
+ V: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
+{
+ tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id)
+}
+
+fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+ Q::Value: Value<TyCtxt<'tcx>>,
+{
+ if let Some(key) = Q::Key::recover(tcx, &dep_node) {
+ #[cfg(debug_assertions)]
+ let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
+ let tcx = QueryCtxt::from_tcx(tcx);
+ force_query::<Q, _>(tcx, key, dep_node);
+ true
+ } else {
+ false
+ }
+}
+
+pub(crate) fn query_callback<'tcx, Q: QueryConfig>(
+ is_anon: bool,
+ is_eval_always: bool,
+) -> DepKindStruct<'tcx>
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+{
+ let fingerprint_style = Q::Key::fingerprint_style();
+
+ if is_anon || !fingerprint_style.reconstructible() {
+ return DepKindStruct {
+ is_anon,
+ is_eval_always,
+ fingerprint_style,
+ force_from_dep_node: None,
+ try_load_from_on_disk_cache: None,
+ };
+ }
+
+ DepKindStruct {
+ is_anon,
+ is_eval_always,
+ fingerprint_style,
+ force_from_dep_node: Some(force_from_dep_node::<Q>),
+ try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::<Q>),
+ }
}
+// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
+// invoked by `rustc_query_append`.
macro_rules! define_queries {
- (<$tcx:tt>
+ (
$($(#[$attr:meta])*
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
-
define_queries_struct! {
- tcx: $tcx,
input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
}
- mod make_query {
- use super::*;
-
- // Create an eponymous constructor for each query.
- $(#[allow(nonstandard_style)] $(#[$attr])*
- pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame {
- opt_remap_env_constness!([$($modifiers)*][key]);
- let kind = dep_graph::DepKind::$name;
- let name = stringify!($name);
- // Disable visible paths printing for performance reasons.
- // Showing visible path instead of any path is not that important in production.
- let description = ty::print::with_no_visible_paths!(
- // Force filename-line mode to avoid invoking `type_of` query.
- ty::print::with_forced_impl_filename_line!(
- queries::$name::describe(tcx, key)
- )
- );
- let description = if tcx.sess.verbose() {
- format!("{} [{}]", description, name)
- } else {
- description
- };
- let span = if kind == dep_graph::DepKind::def_span {
- // The `def_span` query is used to calculate `default_span`,
- // so exit to avoid infinite recursion.
- None
- } else {
- Some(key.default_span(*tcx))
- };
- let def_kind = if kind == dep_graph::DepKind::opt_def_kind {
- // Try to avoid infinite recursion.
- None
- } else {
- key.key_as_def_id()
- .and_then(|def_id| def_id.as_local())
- .and_then(|def_id| tcx.opt_def_kind(def_id))
- };
- let hash = || {
- tcx.with_stable_hashing_context(|mut hcx|{
- let mut hasher = StableHasher::new();
- std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
- key.hash_stable(&mut hcx, &mut hasher);
- hasher.finish::<u64>()
- })
- };
-
- QueryStackFrame::new(name, description, span, def_kind, hash)
- })*
- }
-
#[allow(nonstandard_style)]
mod queries {
use std::marker::PhantomData;
- $(pub struct $name<$tcx> {
- data: PhantomData<&$tcx ()>
+ $(pub struct $name<'tcx> {
+ data: PhantomData<&'tcx ()>
})*
}
- $(impl<$tcx> QueryConfig for queries::$name<$tcx> {
- type Key = query_keys::$name<$tcx>;
- type Value = query_values::$name<$tcx>;
- type Stored = query_stored::$name<$tcx>;
+ $(impl<'tcx> QueryConfig for queries::$name<'tcx> {
+ type Key = query_keys::$name<'tcx>;
+ type Value = query_values::$name<'tcx>;
+ type Stored = query_stored::$name<'tcx>;
const NAME: &'static str = stringify!($name);
}
- impl<$tcx> QueryDescription<QueryCtxt<$tcx>> for queries::$name<$tcx> {
- rustc_query_description! { $name<$tcx> }
+ impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::$name<'tcx> {
+ rustc_query_description! { $name }
- type Cache = query_storage::$name<$tcx>;
+ type Cache = query_storage::$name<'tcx>;
#[inline(always)]
- fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<Self::Key>
- where QueryCtxt<$tcx>: 'a
+ fn query_state<'a>(tcx: QueryCtxt<'tcx>) -> &'a QueryState<Self::Key>
+ where QueryCtxt<'tcx>: 'a
{
&tcx.queries.$name
}
#[inline(always)]
- fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a Self::Cache
+ fn query_cache<'a>(tcx: QueryCtxt<'tcx>) -> &'a Self::Cache
where 'tcx:'a
{
&tcx.query_caches.$name
@@ -340,34 +442,34 @@ macro_rules! define_queries {
#[inline]
fn make_vtable(tcx: QueryCtxt<'tcx>, key: &Self::Key) ->
- QueryVTable<QueryCtxt<$tcx>, Self::Key, Self::Value>
+ QueryVTable<QueryCtxt<'tcx>, Self::Key, Self::Value>
{
let compute = get_provider!([$($modifiers)*][tcx, $name, key]);
let cache_on_disk = Self::cache_on_disk(tcx.tcx, key);
QueryVTable {
anon: is_anon!([$($modifiers)*]),
eval_always: is_eval_always!([$($modifiers)*]),
+ depth_limit: depth_limit!([$($modifiers)*]),
dep_kind: dep_graph::DepKind::$name,
hash_result: hash_result!([$($modifiers)*]),
- handle_cycle_error: |tcx, mut error| handle_cycle_error!([$($modifiers)*][tcx, error]),
+ handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
compute,
- cache_on_disk,
- try_load_from_disk: Self::TRY_LOAD_FROM_DISK,
+ try_load_from_disk: if cache_on_disk { should_ever_cache_on_disk!([$($modifiers)*]) } else { None },
}
}
+
+ fn execute_query(tcx: TyCtxt<'tcx>, k: Self::Key) -> Self::Stored {
+ tcx.$name(k)
+ }
})*
#[allow(nonstandard_style)]
mod query_callbacks {
use super::*;
- use rustc_middle::dep_graph::DepNode;
- use rustc_middle::ty::query::query_keys;
- use rustc_query_system::dep_graph::DepNodeParams;
- use rustc_query_system::query::{force_query, QueryDescription};
use rustc_query_system::dep_graph::FingerprintStyle;
// We use this for most things when incr. comp. is turned off.
- pub fn Null() -> DepKindStruct {
+ pub fn Null<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -378,7 +480,7 @@ macro_rules! define_queries {
}
// We use this for the forever-red node.
- pub fn Red() -> DepKindStruct {
+ pub fn Red<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -388,7 +490,7 @@ macro_rules! define_queries {
}
}
- pub fn TraitSelect() -> DepKindStruct {
+ pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: true,
is_eval_always: false,
@@ -398,7 +500,7 @@ macro_rules! define_queries {
}
}
- pub fn CompileCodegenUnit() -> DepKindStruct {
+ pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -408,7 +510,7 @@ macro_rules! define_queries {
}
}
- pub fn CompileMonoItem() -> DepKindStruct {
+ pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -418,108 +520,70 @@ macro_rules! define_queries {
}
}
- $(pub(crate) fn $name()-> DepKindStruct {
- let is_anon = is_anon!([$($modifiers)*]);
- let is_eval_always = is_eval_always!([$($modifiers)*]);
-
- let fingerprint_style =
- <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>::fingerprint_style();
-
- if is_anon || !fingerprint_style.reconstructible() {
- return DepKindStruct {
- is_anon,
- is_eval_always,
- fingerprint_style,
- force_from_dep_node: None,
- try_load_from_on_disk_cache: None,
- }
- }
-
- #[inline(always)]
- fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> Option<query_keys::$name<'tcx>> {
- <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>::recover(tcx, &dep_node)
- }
-
- fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool {
- if let Some(key) = recover(tcx, dep_node) {
- #[cfg(debug_assertions)]
- let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
- let tcx = QueryCtxt::from_tcx(tcx);
- force_query::<queries::$name<'_>, _>(tcx, key, dep_node);
- true
- } else {
- false
- }
- }
-
- fn try_load_from_on_disk_cache(tcx: TyCtxt<'_>, dep_node: DepNode) {
- debug_assert!(tcx.dep_graph.is_green(&dep_node));
-
- let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash));
- if queries::$name::cache_on_disk(tcx, &key) {
- let _ = tcx.$name(key);
- }
- }
-
- DepKindStruct {
- is_anon,
- is_eval_always,
- fingerprint_style,
- force_from_dep_node: Some(force_from_dep_node),
- try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache),
- }
+ $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
+ $crate::plumbing::query_callback::<queries::$name<'tcx>>(
+ is_anon!([$($modifiers)*]),
+ is_eval_always!([$($modifiers)*]),
+ )
})*
}
- pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] {
+ pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
arena.alloc_from_iter(make_dep_kind_array!(query_callbacks))
}
}
}
-// FIXME(eddyb) this macro (and others?) use `$tcx` and `'tcx` interchangeably.
-// We should either not take `$tcx` at all and use `'tcx` everywhere, or use
-// `$tcx` everywhere (even if that isn't necessary due to lack of hygiene).
+use crate::{ExternProviders, OnDiskCache, Providers};
+
+impl<'tcx> Queries<'tcx> {
+ pub fn new(
+ local_providers: Providers,
+ extern_providers: ExternProviders,
+ on_disk_cache: Option<OnDiskCache<'tcx>>,
+ ) -> Self {
+ Queries {
+ local_providers: Box::new(local_providers),
+ extern_providers: Box::new(extern_providers),
+ on_disk_cache,
+ jobs: AtomicU64::new(1),
+ ..Queries::default()
+ }
+ }
+}
+
macro_rules! define_queries_struct {
- (tcx: $tcx:tt,
+ (
input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
- pub struct Queries<$tcx> {
+ #[derive(Default)]
+ pub struct Queries<'tcx> {
local_providers: Box<Providers>,
extern_providers: Box<ExternProviders>,
- pub on_disk_cache: Option<OnDiskCache<$tcx>>,
+ pub on_disk_cache: Option<OnDiskCache<'tcx>>,
jobs: AtomicU64,
- $($(#[$attr])* $name: QueryState<query_keys::$name<$tcx>>,)*
+ $($(#[$attr])* $name: QueryState<<queries::$name<'tcx> as QueryConfig>::Key>,)*
}
- impl<$tcx> Queries<$tcx> {
- pub fn new(
- local_providers: Providers,
- extern_providers: ExternProviders,
- on_disk_cache: Option<OnDiskCache<$tcx>>,
- ) -> Self {
- Queries {
- local_providers: Box::new(local_providers),
- extern_providers: Box::new(extern_providers),
- on_disk_cache,
- jobs: AtomicU64::new(1),
- $($name: Default::default()),*
- }
- }
-
+ impl<'tcx> Queries<'tcx> {
pub(crate) fn try_collect_active_jobs(
- &$tcx self,
- tcx: TyCtxt<$tcx>,
+ &'tcx self,
+ tcx: TyCtxt<'tcx>,
) -> Option<QueryMap> {
let tcx = QueryCtxt { tcx, queries: self };
let mut jobs = QueryMap::default();
$(
+ let make_query = |tcx, key| {
+ let kind = dep_graph::DepKind::$name;
+ let name = stringify!($name);
+ $crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name)
+ };
self.$name.try_collect_active_jobs(
tcx,
- make_query::$name,
+ make_query,
&mut jobs,
)?;
)*
@@ -541,17 +605,16 @@ macro_rules! define_queries_struct {
$($(#[$attr])*
#[inline(always)]
- #[tracing::instrument(level = "trace", skip(self, tcx))]
+ #[tracing::instrument(level = "trace", skip(self, tcx), ret)]
fn $name(
&'tcx self,
- tcx: TyCtxt<$tcx>,
+ tcx: TyCtxt<'tcx>,
span: Span,
- key: query_keys::$name<$tcx>,
+ key: <queries::$name<'tcx> as QueryConfig>::Key,
mode: QueryMode,
- ) -> Option<query_stored::$name<$tcx>> {
- opt_remap_env_constness!([$($modifiers)*][key]);
+ ) -> Option<query_stored::$name<'tcx>> {
let qcx = QueryCtxt { tcx, queries: self };
- get_query::<queries::$name<$tcx>, _>(qcx, span, key, mode)
+ get_query::<queries::$name<'tcx>, _>(qcx, span, key, mode)
})*
}
};
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index 551f09420..98ec3bc09 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -306,19 +306,19 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) {
let mut string_cache = QueryKeyStringCache::new();
macro_rules! alloc_once {
- (<$tcx:tt>
- $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)*
- ) => {
- $({
+ (
+ $($(#[$attr:meta])*
+ [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
+ $(
alloc_self_profile_query_strings_for_query_cache(
tcx,
stringify!($name),
&tcx.query_caches.$name,
&mut string_cache,
);
- })*
+ )+
}
}
- rustc_query_append! { [alloc_once!][<'tcx>] }
+ rustc_query_append! { alloc_once! }
}
diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/values.rs
deleted file mode 100644
index 718a2971c..000000000
--- a/compiler/rustc_query_impl/src/values.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use super::QueryCtxt;
-use rustc_middle::ty::{self, AdtSizedConstraint, Ty};
-
-pub(super) trait Value<'tcx>: Sized {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self;
-}
-
-impl<'tcx, T> Value<'tcx> for T {
- default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T {
- tcx.sess.abort_if_errors();
- bug!("Value::from_cycle_error called without errors");
- }
-}
-
-impl<'tcx> Value<'tcx> for Ty<'_> {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
- // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
- // FIXME: Represent the above fact in the trait system somehow.
- unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
- }
-}
-
-impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
- // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
- // FIXME: Represent the above fact in the trait system somehow.
- unsafe {
- std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
- *tcx, "<error>",
- ))
- }
- }
-}
-
-impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
- // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
- // FIXME: Represent the above fact in the trait system somehow.
- unsafe {
- std::mem::transmute::<AdtSizedConstraint<'tcx>, AdtSizedConstraint<'_>>(
- AdtSizedConstraint(tcx.intern_type_list(&[tcx.ty_error()])),
- )
- }
- }
-}
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index b7787aeb8..d7599a56c 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -7,9 +7,8 @@ edition = "2021"
doctest = false
[dependencies]
+parking_lot = "0.11"
rustc_arena = { path = "../rustc_arena" }
-tracing = "0.1"
-rustc-rayon-core = { version = "0.4.0", optional = true }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
@@ -17,12 +16,15 @@ rustc_feature = { path = "../rustc_feature" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
+rustc-rayon-core = { version = "0.4.0", optional = true }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
-parking_lot = "0.11"
+rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
+tracing = "0.1"
[features]
rustc_use_parallel_compiler = ["rustc-rayon-core"]
diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs
new file mode 100644
index 000000000..3fb06cbed
--- /dev/null
+++ b/compiler/rustc_query_system/src/error.rs
@@ -0,0 +1,80 @@
+use rustc_errors::AddSubdiagnostic;
+use rustc_span::Span;
+
+pub struct CycleStack {
+ pub span: Span,
+ pub desc: String,
+}
+
+impl AddSubdiagnostic for CycleStack {
+ fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
+ diag.span_note(self.span, &format!("...which requires {}...", self.desc));
+ }
+}
+
+#[derive(Copy, Clone)]
+pub enum HandleCycleError {
+ Error,
+ Fatal,
+ DelayBug,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum StackCount {
+ #[note(query_system::cycle_stack_single)]
+ Single,
+ #[note(query_system::cycle_stack_multiple)]
+ Multiple,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum Alias {
+ #[note(query_system::cycle_recursive_ty_alias)]
+ #[help(query_system::cycle_recursive_ty_alias_help1)]
+ #[help(query_system::cycle_recursive_ty_alias_help2)]
+ Ty,
+ #[note(query_system::cycle_recursive_trait_alias)]
+ Trait,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[note(query_system::cycle_usage)]
+pub struct CycleUsage {
+ #[primary_span]
+ pub span: Span,
+ pub usage: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(query_system::cycle, code = "E0391")]
+pub struct Cycle {
+ #[primary_span]
+ pub span: Span,
+ pub stack_bottom: String,
+ #[subdiagnostic]
+ pub cycle_stack: Vec<CycleStack>,
+ #[subdiagnostic]
+ pub stack_count: StackCount,
+ #[subdiagnostic]
+ pub alias: Option<Alias>,
+ #[subdiagnostic]
+ pub cycle_usage: Option<CycleUsage>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(query_system::reentrant)]
+pub struct Reentrant;
+
+#[derive(SessionDiagnostic)]
+#[diag(query_system::increment_compilation)]
+#[help]
+#[note(query_system::increment_compilation_note1)]
+#[note(query_system::increment_compilation_note2)]
+pub struct IncrementCompilation {
+ pub run_cmd: String,
+ pub dep_node: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(query_system::query_overflow)]
+pub struct QueryOverflow;
diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs
index 217fac341..a09b8ca30 100644
--- a/compiler/rustc_query_system/src/ich/hcx.rs
+++ b/compiler/rustc_query_system/src/ich/hcx.rs
@@ -40,11 +40,8 @@ pub struct StableHashingContext<'a> {
#[derive(Clone, Copy)]
pub(super) enum BodyResolver<'tcx> {
Forbidden,
- Traverse {
- hash_bodies: bool,
- owner: LocalDefId,
- bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>>,
- },
+ Ignore,
+ Traverse { owner: LocalDefId, bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>> },
}
impl<'a> StableHashingContext<'a> {
@@ -98,32 +95,20 @@ impl<'a> StableHashingContext<'a> {
Self::new_with_or_without_spans(sess, definitions, cstore, source_span, always_ignore_spans)
}
- /// Allow hashing
#[inline]
- pub fn while_hashing_hir_bodies(&mut self, hb: bool, f: impl FnOnce(&mut Self)) {
- let prev = match &mut self.body_resolver {
- BodyResolver::Forbidden => panic!("Hashing HIR bodies is forbidden."),
- BodyResolver::Traverse { ref mut hash_bodies, .. } => {
- std::mem::replace(hash_bodies, hb)
- }
- };
- f(self);
- match &mut self.body_resolver {
- BodyResolver::Forbidden => unreachable!(),
- BodyResolver::Traverse { ref mut hash_bodies, .. } => *hash_bodies = prev,
- }
+ pub fn without_hir_bodies(&mut self, f: impl FnOnce(&mut StableHashingContext<'_>)) {
+ f(&mut StableHashingContext { body_resolver: BodyResolver::Ignore, ..self.clone() });
}
#[inline]
pub fn with_hir_bodies(
&mut self,
- hash_bodies: bool,
owner: LocalDefId,
bodies: &SortedMap<hir::ItemLocalId, &hir::Body<'_>>,
f: impl FnOnce(&mut StableHashingContext<'_>),
) {
f(&mut StableHashingContext {
- body_resolver: BodyResolver::Traverse { hash_bodies, owner, bodies },
+ body_resolver: BodyResolver::Traverse { owner, bodies },
..self.clone()
});
}
diff --git a/compiler/rustc_query_system/src/ich/impls_hir.rs b/compiler/rustc_query_system/src/ich/impls_hir.rs
index 3390ed9eb..aa008d404 100644
--- a/compiler/rustc_query_system/src/ich/impls_hir.rs
+++ b/compiler/rustc_query_system/src/ich/impls_hir.rs
@@ -12,31 +12,11 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
let hcx = self;
match hcx.body_resolver {
BodyResolver::Forbidden => panic!("Hashing HIR bodies is forbidden."),
- BodyResolver::Traverse { hash_bodies: false, .. } => {}
- BodyResolver::Traverse { hash_bodies: true, owner, bodies } => {
+ BodyResolver::Ignore => {}
+ BodyResolver::Traverse { owner, bodies } => {
assert_eq!(id.hir_id.owner, owner);
bodies[&id.hir_id.local_id].hash_stable(hcx, hasher);
}
}
}
-
- fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
- self.while_hashing_hir_bodies(true, |hcx| {
- let hir::Expr { hir_id, ref span, ref kind } = *expr;
-
- hir_id.hash_stable(hcx, hasher);
- span.hash_stable(hcx, hasher);
- kind.hash_stable(hcx, hasher);
- })
- }
-
- fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
- self.while_hashing_hir_bodies(true, |hcx| {
- let hir::Ty { hir_id, ref kind, ref span } = *ty;
-
- hir_id.hash_stable(hcx, hasher);
- kind.hash_stable(hcx, hasher);
- span.hash_stable(hcx, hasher);
- })
- }
}
diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs
index 1fa085926..0bc811eb0 100644
--- a/compiler/rustc_query_system/src/ich/impls_syntax.rs
+++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs
@@ -42,12 +42,12 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
debug_assert!(!attr.is_doc_comment());
let ast::Attribute { kind, id: _, style, span } = attr;
- if let ast::AttrKind::Normal(item, tokens) = kind {
- item.hash_stable(self, hasher);
+ if let ast::AttrKind::Normal(normal) = kind {
+ normal.item.hash_stable(self, hasher);
style.hash_stable(self, hasher);
span.hash_stable(self, hasher);
assert_matches!(
- tokens.as_ref(),
+ normal.tokens.as_ref(),
None,
"Tokens should have been removed during lowering!"
);
@@ -148,3 +148,5 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
});
}
}
+
+impl<'ctx> rustc_type_ir::HashStableContext for StableHashingContext<'ctx> {}
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 68284dcaa..f92c3831f 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -1,10 +1,12 @@
#![feature(assert_matches)]
#![feature(core_intrinsics)]
#![feature(hash_raw_entry)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(extern_types)]
#![allow(rustc::potential_query_instability)]
+// #![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
@@ -15,5 +17,10 @@ extern crate rustc_macros;
pub mod cache;
pub mod dep_graph;
+mod error;
pub mod ich;
pub mod query;
+mod values;
+
+pub use error::HandleCycleError;
+pub use values::Value;
diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs
index 964914a13..c4549cc9e 100644
--- a/compiler/rustc_query_system/src/query/config.rs
+++ b/compiler/rustc_query_system/src/query/config.rs
@@ -2,12 +2,12 @@
use crate::dep_graph::DepNode;
use crate::dep_graph::SerializedDepNodeIndex;
+use crate::error::HandleCycleError;
use crate::ich::StableHashingContext;
use crate::query::caches::QueryCache;
use crate::query::{QueryContext, QueryState};
use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use std::fmt::Debug;
use std::hash::Hash;
@@ -19,15 +19,17 @@ pub trait QueryConfig {
type Stored: Clone;
}
+#[derive(Copy, Clone)]
pub struct QueryVTable<CTX: QueryContext, K, V> {
pub anon: bool,
pub dep_kind: CTX::DepKind,
pub eval_always: bool,
- pub cache_on_disk: bool,
+ pub depth_limit: bool,
pub compute: fn(CTX::DepContext, K) -> V,
pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
- pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_, ErrorGuaranteed>) -> V,
+ pub handle_cycle_error: HandleCycleError,
+ // NOTE: this is also `None` if `cache_on_disk()` returns false, not just if it's unsupported by the query
pub try_load_from_disk: Option<fn(CTX, SerializedDepNodeIndex) -> Option<V>>,
}
@@ -42,18 +44,9 @@ impl<CTX: QueryContext, K, V> QueryVTable<CTX, K, V> {
pub(crate) fn compute(&self, tcx: CTX::DepContext, key: K) -> V {
(self.compute)(tcx, key)
}
-
- pub(crate) fn try_load_from_disk(&self, tcx: CTX, index: SerializedDepNodeIndex) -> Option<V> {
- self.try_load_from_disk
- .expect("QueryDescription::load_from_disk() called for an unsupported query.")(
- tcx, index,
- )
- }
}
pub trait QueryDescription<CTX: QueryContext>: QueryConfig {
- const TRY_LOAD_FROM_DISK: Option<fn(CTX, SerializedDepNodeIndex) -> Option<Self::Value>>;
-
type Cache: QueryCache<Key = Self::Key, Stored = Self::Stored, Value = Self::Value>;
fn describe(tcx: CTX, key: Self::Key) -> String;
@@ -72,4 +65,7 @@ pub trait QueryDescription<CTX: QueryContext>: QueryConfig {
fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable<CTX, Self::Key, Self::Value>;
fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool;
+
+ // Don't use this method to compute query results, instead use the methods on TyCtxt
+ fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored;
}
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 6d2aff381..45b4079fb 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -1,12 +1,11 @@
+use crate::error::CycleStack;
use crate::query::plumbing::CycleError;
use crate::query::{QueryContext, QueryStackFrame};
-use rustc_hir::def::DefKind;
use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{
- struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level,
-};
-use rustc_session::Session;
+use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level};
+use rustc_hir::def::DefKind;
+use rustc_session::{Session, SessionDiagnostic};
use rustc_span::Span;
use std::hash::Hash;
@@ -536,46 +535,44 @@ pub(crate) fn report_cycle<'a>(
assert!(!stack.is_empty());
let span = stack[0].query.default_span(stack[1 % stack.len()].span);
- let mut err =
- struct_span_err!(sess, span, E0391, "cycle detected when {}", stack[0].query.description);
+
+ let mut cycle_stack = Vec::new();
+
+ use crate::error::StackCount;
+ let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple };
for i in 1..stack.len() {
let query = &stack[i].query;
let span = query.default_span(stack[(i + 1) % stack.len()].span);
- err.span_note(span, &format!("...which requires {}...", query.description));
- }
-
- if stack.len() == 1 {
- err.note(&format!("...which immediately requires {} again", stack[0].query.description));
- } else {
- err.note(&format!(
- "...which again requires {}, completing the cycle",
- stack[0].query.description
- ));
- }
-
- if stack.iter().all(|entry| {
- entry
- .query
- .def_kind
- .map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias | DefKind::TraitAlias))
- }) {
- if stack.iter().all(|entry| {
- entry.query.def_kind.map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias))
- }) {
- err.note("type aliases cannot be recursive");
- err.help("consider using a struct, enum, or union instead to break the cycle");
- err.help("see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information");
- } else {
- err.note("trait aliases cannot be recursive");
- }
+ cycle_stack.push(CycleStack { span, desc: query.description.to_owned() });
}
+ let mut cycle_usage = None;
if let Some((span, query)) = usage {
- err.span_note(query.default_span(span), &format!("cycle used when {}", query.description));
+ cycle_usage = Some(crate::error::CycleUsage {
+ span: query.default_span(span),
+ usage: query.description,
+ });
}
- err
+ let alias = if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TyAlias)) {
+ Some(crate::error::Alias::Ty)
+ } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) {
+ Some(crate::error::Alias::Trait)
+ } else {
+ None
+ };
+
+ let cycle_diag = crate::error::Cycle {
+ span,
+ cycle_stack,
+ stack_bottom: stack[0].query.description.to_owned(),
+ alias,
+ cycle_usage: cycle_usage,
+ stack_count,
+ };
+
+ cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic)
}
pub fn print_query_stack<CTX: QueryContext>(
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index fb2258434..0b07bb64b 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -14,13 +14,12 @@ pub use self::caches::{
mod config;
pub use self::config::{QueryConfig, QueryDescription, QueryVTable};
-use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
-
+use crate::dep_graph::{DepContext, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
use rustc_data_structures::sync::Lock;
-use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::Diagnostic;
use rustc_hir::def::DefKind;
use rustc_span::Span;
+use thin_vec::ThinVec;
/// Description of a frame in the query stack.
///
@@ -119,7 +118,12 @@ pub trait QueryContext: HasDepContext {
fn start_query<R>(
&self,
token: QueryJobId,
+ depth_limit: bool,
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
compute: impl FnOnce() -> R,
) -> R;
+
+ fn depth_limit_error(&self) {
+ self.dep_context().sess().emit_fatal(crate::error::QueryOverflow);
+ }
}
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 5e8ea07d0..8179a674a 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -7,6 +7,8 @@ use crate::query::caches::QueryCache;
use crate::query::config::{QueryDescription, QueryVTable};
use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo};
use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame};
+use crate::values::Value;
+use crate::HandleCycleError;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
#[cfg(parallel_compiler)]
@@ -14,7 +16,6 @@ use rustc_data_structures::profiling::TimingGuard;
#[cfg(parallel_compiler)]
use rustc_data_structures::sharded::Sharded;
use rustc_data_structures::sync::Lock;
-use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
use rustc_session::Session;
use rustc_span::{Span, DUMMY_SP};
@@ -24,6 +25,7 @@ use std::fmt::Debug;
use std::hash::Hash;
use std::mem;
use std::ptr;
+use thin_vec::ThinVec;
pub struct QueryState<K> {
#[cfg(parallel_compiler)]
@@ -118,19 +120,46 @@ where
fn mk_cycle<CTX, V, R>(
tcx: CTX,
error: CycleError,
- handle_cycle_error: fn(CTX, DiagnosticBuilder<'_, ErrorGuaranteed>) -> V,
+ handler: HandleCycleError,
cache: &dyn crate::query::QueryStorage<Value = V, Stored = R>,
) -> R
where
CTX: QueryContext,
- V: std::fmt::Debug,
+ V: std::fmt::Debug + Value<CTX::DepContext>,
R: Clone,
{
let error = report_cycle(tcx.dep_context().sess(), error);
- let value = handle_cycle_error(tcx, error);
+ let value = handle_cycle_error(*tcx.dep_context(), error, handler);
cache.store_nocache(value)
}
+fn handle_cycle_error<CTX, V>(
+ tcx: CTX,
+ mut error: DiagnosticBuilder<'_, ErrorGuaranteed>,
+ handler: HandleCycleError,
+) -> V
+where
+ CTX: DepContext,
+ V: Value<CTX>,
+{
+ use HandleCycleError::*;
+ match handler {
+ Error => {
+ error.emit();
+ Value::from_cycle_error(tcx)
+ }
+ Fatal => {
+ error.emit();
+ tcx.sess().abort_if_errors();
+ unreachable!()
+ }
+ DelayBug => {
+ error.delay_as_bug();
+ Value::from_cycle_error(tcx)
+ }
+ }
+}
+
impl<'tcx, K> JobOwner<'tcx, K>
where
K: Eq + Hash + Clone,
@@ -336,6 +365,7 @@ fn try_execute_query<CTX, C>(
where
C: QueryCache,
C::Key: Clone + DepNodeParams<CTX::DepContext>,
+ C::Value: Value<CTX::DepContext>,
CTX: QueryContext,
{
match JobOwner::<'_, C::Key>::try_start(&tcx, state, span, key.clone()) {
@@ -381,7 +411,9 @@ where
// Fast path for when incr. comp. is off.
if !dep_graph.is_fully_enabled() {
let prof_timer = tcx.dep_context().profiler().query_provider();
- let result = tcx.start_query(job_id, None, || query.compute(*tcx.dep_context(), key));
+ let result = tcx.start_query(job_id, query.depth_limit, None, || {
+ query.compute(*tcx.dep_context(), key)
+ });
let dep_node_index = dep_graph.next_virtual_depnode_index();
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
return (result, dep_node_index);
@@ -394,7 +426,7 @@ where
// The diagnostics for this query will be promoted to the current session during
// `try_mark_green()`, so we can ignore them here.
- if let Some(ret) = tcx.start_query(job_id, None, || {
+ if let Some(ret) = tcx.start_query(job_id, false, None, || {
try_load_from_disk_and_cache_in_memory(tcx, &key, &dep_node, query)
}) {
return ret;
@@ -404,18 +436,20 @@ where
let prof_timer = tcx.dep_context().profiler().query_provider();
let diagnostics = Lock::new(ThinVec::new());
- let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), || {
- if query.anon {
- return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || {
- query.compute(*tcx.dep_context(), key)
- });
- }
+ let (result, dep_node_index) =
+ tcx.start_query(job_id, query.depth_limit, Some(&diagnostics), || {
+ if query.anon {
+ return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || {
+ query.compute(*tcx.dep_context(), key)
+ });
+ }
- // `to_dep_node` is expensive for some `DepKind`s.
- let dep_node = dep_node_opt.unwrap_or_else(|| query.to_dep_node(*tcx.dep_context(), &key));
+ // `to_dep_node` is expensive for some `DepKind`s.
+ let dep_node =
+ dep_node_opt.unwrap_or_else(|| query.to_dep_node(*tcx.dep_context(), &key));
- dep_graph.with_task(dep_node, *tcx.dep_context(), key, query.compute, query.hash_result)
- });
+ dep_graph.with_task(dep_node, *tcx.dep_context(), key, query.compute, query.hash_result)
+ });
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
@@ -454,14 +488,14 @@ where
// First we try to load the result from the on-disk cache.
// Some things are never cached on disk.
- if query.cache_on_disk {
+ if let Some(try_load_from_disk) = query.try_load_from_disk {
let prof_timer = tcx.dep_context().profiler().incr_cache_loading();
// The call to `with_query_deserialization` enforces that no new `DepNodes`
// are created during deserialization. See the docs of that method for more
// details.
- let result = dep_graph
- .with_query_deserialization(|| query.try_load_from_disk(tcx, prev_dep_node_index));
+ let result =
+ dep_graph.with_query_deserialization(|| try_load_from_disk(tcx, prev_dep_node_index));
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
@@ -614,16 +648,12 @@ fn incremental_verify_ich_cold(sess: &Session, dep_node: DebugArg<'_>, result: D
let old_in_panic = INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.replace(true));
if old_in_panic {
- sess.struct_err(
- "internal compiler error: re-entrant incremental verify failure, suppressing message",
- )
- .emit();
+ sess.emit_err(crate::error::Reentrant);
} else {
- sess.struct_err(&format!("internal compiler error: encountered incremental compilation error with {:?}", dep_node))
- .help(&format!("This is a known issue with the compiler. Run {} to allow your project to compile", run_cmd))
- .note("Please follow the instructions below to create a bug report with the provided information")
- .note("See <https://github.com/rust-lang/rust/issues/84970> for more information")
- .emit();
+ sess.emit_err(crate::error::IncrementCompilation {
+ run_cmd,
+ dep_node: format!("{:?}", dep_node),
+ });
panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result);
}
@@ -686,6 +716,7 @@ pub fn get_query<Q, CTX>(tcx: CTX, span: Span, key: Q::Key, mode: QueryMode) ->
where
Q: QueryDescription<CTX>,
Q::Key: DepNodeParams<CTX::DepContext>,
+ Q::Value: Value<CTX::DepContext>,
CTX: QueryContext,
{
let query = Q::make_vtable(tcx, &key);
@@ -718,6 +749,7 @@ pub fn force_query<Q, CTX>(tcx: CTX, key: Q::Key, dep_node: DepNode<CTX::DepKind
where
Q: QueryDescription<CTX>,
Q::Key: DepNodeParams<CTX::DepContext>,
+ Q::Value: Value<CTX::DepContext>,
CTX: QueryContext,
{
// We may be concurrently trying both execute and force a query.
diff --git a/compiler/rustc_query_system/src/values.rs b/compiler/rustc_query_system/src/values.rs
new file mode 100644
index 000000000..aeef66f86
--- /dev/null
+++ b/compiler/rustc_query_system/src/values.rs
@@ -0,0 +1,14 @@
+use crate::dep_graph::DepContext;
+
+pub trait Value<CTX: DepContext>: Sized {
+ fn from_cycle_error(tcx: CTX) -> Self;
+}
+
+impl<CTX: DepContext, T> Value<CTX> for T {
+ default fn from_cycle_error(tcx: CTX) -> T {
+ tcx.sess().abort_if_errors();
+ // Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's
+ // non-trivial to define it earlier.
+ panic!("Value::from_cycle_error called without errors");
+ }
+}
diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs
index 3fba923d9..0a3add2e0 100644
--- a/compiler/rustc_resolve/src/access_levels.rs
+++ b/compiler/rustc_resolve/src/access_levels.rs
@@ -1,25 +1,21 @@
+use crate::imports::ImportKind;
+use crate::NameBinding;
+use crate::NameBindingKind;
+use crate::Resolver;
use rustc_ast::ast;
use rustc_ast::visit;
use rustc_ast::visit::Visitor;
use rustc_ast::Crate;
use rustc_ast::EnumDef;
-use rustc_ast::ForeignMod;
use rustc_ast::NodeId;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::middle::privacy::AccessLevel;
-use rustc_middle::ty::Visibility;
+use rustc_middle::ty::DefIdTree;
use rustc_span::sym;
-use crate::imports::ImportKind;
-use crate::BindingKey;
-use crate::NameBinding;
-use crate::NameBindingKind;
-use crate::Resolver;
-
pub struct AccessLevelsVisitor<'r, 'a> {
r: &'r mut Resolver<'a>,
- prev_level: Option<AccessLevel>,
changed: bool,
}
@@ -28,31 +24,32 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
/// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
/// need access to a TyCtxt for that.
pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
- let mut visitor =
- AccessLevelsVisitor { r, changed: false, prev_level: Some(AccessLevel::Public) };
+ let mut visitor = AccessLevelsVisitor { r, changed: false };
visitor.set_access_level_def_id(CRATE_DEF_ID, Some(AccessLevel::Public));
- visitor.set_exports_access_level(CRATE_DEF_ID);
+ visitor.set_bindings_access_level(CRATE_DEF_ID);
while visitor.changed {
visitor.reset();
visit::walk_crate(&mut visitor, krate);
}
- tracing::info!("resolve::access_levels: {:#?}", r.access_levels);
+ info!("resolve::access_levels: {:#?}", r.access_levels);
}
fn reset(&mut self) {
self.changed = false;
- self.prev_level = Some(AccessLevel::Public);
}
- /// Update the access level of the exports of the given module accordingly. The module access
+ /// Update the access level of the bindings in the given module accordingly. The module access
/// level has to be Exported or Public.
/// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level).
- fn set_exports_access_level(&mut self, module_id: LocalDefId) {
+ fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
assert!(self.r.module_map.contains_key(&&module_id.to_def_id()));
-
+ let module_level = self.r.access_levels.map.get(&module_id).copied();
+ if !module_level.is_some() {
+ return;
+ }
// Set the given binding access level to `AccessLevel::Public` and
// sets the rest of the `use` chain to `AccessLevel::Exported` until
// we hit the actual exported item.
@@ -72,28 +69,20 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
}
};
- let module_level = self.r.access_levels.map.get(&module_id).copied();
- assert!(module_level >= Some(AccessLevel::Exported));
-
- if let Some(exports) = self.r.reexport_map.get(&module_id) {
- let pub_exports = exports
- .iter()
- .filter(|ex| ex.vis == Visibility::Public)
- .cloned()
- .collect::<Vec<_>>();
-
- let module = self.r.get_module(module_id.to_def_id()).unwrap();
- for export in pub_exports.into_iter() {
- if let Some(export_def_id) = export.res.opt_def_id().and_then(|id| id.as_local()) {
- self.set_access_level_def_id(export_def_id, Some(AccessLevel::Exported));
- }
-
- if let Some(ns) = export.res.ns() {
- let key = BindingKey { ident: export.ident, ns, disambiguator: 0 };
- let name_res = self.r.resolution(module, key);
- if let Some(binding) = name_res.borrow().binding() {
- set_import_binding_access_level(self, binding, module_level)
- }
+ let module = self.r.get_module(module_id.to_def_id()).unwrap();
+ let resolutions = self.r.resolutions(module);
+
+ for (.., name_resolution) in resolutions.borrow().iter() {
+ if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() {
+ let access_level = match binding.is_import() {
+ true => {
+ set_import_binding_access_level(self, binding, module_level);
+ Some(AccessLevel::Exported)
+ },
+ false => module_level,
+ };
+ if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
+ self.set_access_level_def_id(def_id, access_level);
}
}
}
@@ -127,97 +116,59 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
fn visit_item(&mut self, item: &'ast ast::Item) {
- let inherited_item_level = match item.kind {
+ let def_id = self.r.local_def_id(item.id);
+ // Set access level of nested items.
+ // If it's a mod, also make the visitor walk all of its items
+ match item.kind {
// Resolved in rustc_privacy when types are available
ast::ItemKind::Impl(..) => return,
- // Only exported `macro_rules!` items are public, but they always are
- ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
- let is_macro_export =
- item.attrs.iter().any(|attr| attr.has_name(sym::macro_export));
- if is_macro_export { Some(AccessLevel::Public) } else { None }
- }
-
- // Foreign modules inherit level from parents.
- ast::ItemKind::ForeignMod(..) => self.prev_level,
-
- // Other `pub` items inherit levels from parents.
- ast::ItemKind::ExternCrate(..)
- | ast::ItemKind::Use(..)
- | ast::ItemKind::Static(..)
- | ast::ItemKind::Const(..)
- | ast::ItemKind::Fn(..)
- | ast::ItemKind::Mod(..)
- | ast::ItemKind::GlobalAsm(..)
- | ast::ItemKind::TyAlias(..)
- | ast::ItemKind::Enum(..)
- | ast::ItemKind::Struct(..)
- | ast::ItemKind::Union(..)
- | ast::ItemKind::Trait(..)
- | ast::ItemKind::TraitAlias(..)
- | ast::ItemKind::MacroDef(..) => {
- if item.vis.kind.is_pub() {
- self.prev_level
- } else {
- None
- }
- }
-
// Should be unreachable at this stage
ast::ItemKind::MacCall(..) => panic!(
"ast::ItemKind::MacCall encountered, this should not anymore appear at this stage"
),
- };
- let access_level = self.set_access_level(item.id, inherited_item_level);
+ // Foreign modules inherit level from parents.
+ ast::ItemKind::ForeignMod(..) => {
+ let parent_level =
+ self.r.access_levels.map.get(&self.r.local_parent(def_id)).copied();
+ self.set_access_level(item.id, parent_level);
+ }
- // Set access level of nested items.
- // If it's a mod, also make the visitor walk all of its items
- match item.kind {
- ast::ItemKind::Mod(..) => {
- if access_level.is_some() {
- self.set_exports_access_level(self.r.local_def_id(item.id));
+ // Only exported `macro_rules!` items are public, but they always are
+ ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
+ if item.attrs.iter().any(|attr| attr.has_name(sym::macro_export)) {
+ self.set_access_level(item.id, Some(AccessLevel::Public));
}
+ }
- let orig_level = std::mem::replace(&mut self.prev_level, access_level);
+ ast::ItemKind::Mod(..) => {
+ self.set_bindings_access_level(def_id);
visit::walk_item(self, item);
- self.prev_level = orig_level;
}
- ast::ItemKind::ForeignMod(ForeignMod { ref items, .. }) => {
- for nested in items {
- if nested.vis.kind.is_pub() {
- self.set_access_level(nested.id, access_level);
- }
- }
- }
ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
+ self.set_bindings_access_level(def_id);
for variant in variants {
- let variant_level = self.set_access_level(variant.id, access_level);
- if let Some(ctor_id) = variant.data.ctor_id() {
- self.set_access_level(ctor_id, access_level);
- }
-
+ let variant_def_id = self.r.local_def_id(variant.id);
+ let variant_level = self.r.access_levels.map.get(&variant_def_id).copied();
for field in variant.data.fields() {
self.set_access_level(field.id, variant_level);
}
}
}
- ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
- if let Some(ctor_id) = def.ctor_id() {
- self.set_access_level(ctor_id, access_level);
- }
+ ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
+ let inherited_level = self.r.access_levels.map.get(&def_id).copied();
for field in def.fields() {
if field.vis.kind.is_pub() {
- self.set_access_level(field.id, access_level);
+ self.set_access_level(field.id, inherited_level);
}
}
}
- ast::ItemKind::Trait(ref trait_kind) => {
- for nested in trait_kind.items.iter() {
- self.set_access_level(nested.id, access_level);
- }
+
+ ast::ItemKind::Trait(..) => {
+ self.set_bindings_access_level(def_id);
}
ast::ItemKind::ExternCrate(..)
@@ -229,9 +180,6 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
| ast::ItemKind::TraitAlias(..)
| ast::ItemKind::MacroDef(..)
| ast::ItemKind::Fn(..) => return,
-
- // Unreachable kinds
- ast::ItemKind::Impl(..) | ast::ItemKind::MacCall(..) => unreachable!(),
}
}
}
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index e955a1798..81b67b758 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -36,28 +36,29 @@ use rustc_span::Span;
use std::cell::Cell;
use std::ptr;
-use tracing::debug;
type Res = def::Res<NodeId>;
-impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, LocalExpnId) {
+impl<'a, Id: Into<DefId>> ToNameBinding<'a>
+ for (Module<'a>, ty::Visibility<Id>, Span, LocalExpnId)
+{
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Module(self.0),
ambiguity: None,
- vis: self.1,
+ vis: self.1.to_def_id(),
span: self.2,
expansion: self.3,
})
}
}
-impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) {
+impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Res(self.0, false),
ambiguity: None,
- vis: self.1,
+ vis: self.1.to_def_id(),
span: self.2,
expansion: self.3,
})
@@ -71,7 +72,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId, IsMacroE
arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Res(self.0, true),
ambiguity: None,
- vis: self.1,
+ vis: self.1.to_def_id(),
span: self.2,
expansion: self.3,
})
@@ -261,7 +262,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
self.r.visibilities[&def_id.expect_local()]
}
// Otherwise, the visibility is restricted to the nearest parent `mod` item.
- _ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()),
+ _ => ty::Visibility::Restricted(
+ self.parent_scope.module.nearest_parent_mod().expect_local(),
+ ),
})
}
ast::VisibilityKind::Restricted { ref path, id, .. } => {
@@ -312,7 +315,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
} else {
let vis = ty::Visibility::Restricted(res.def_id());
if self.r.is_accessible_from(vis, parent_scope.module) {
- Ok(vis)
+ Ok(vis.expect_local())
} else {
Err(VisResolutionError::AncestorOnly(path.span))
}
@@ -380,7 +383,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
has_attributes: !item.attrs.is_empty(),
root_span,
root_id,
- vis: Cell::new(vis),
+ vis: Cell::new(Some(vis)),
used: Cell::new(false),
});
@@ -588,7 +591,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
ast::UseTreeKind::Glob => {
let kind = ImportKind::Glob {
is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import),
- max_vis: Cell::new(ty::Visibility::Invisible),
+ max_vis: Cell::new(None),
};
self.r.visibilities.insert(self.r.local_def_id(id), vis);
self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis);
@@ -650,7 +653,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
true,
// The whole `use` item
item,
- ty::Visibility::Invisible,
+ ty::Visibility::Restricted(
+ self.parent_scope.module.nearest_parent_mod().expect_local(),
+ ),
root_span,
);
}
@@ -766,10 +771,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
if let Some(ctor_node_id) = vdata.ctor_id() {
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
- let mut ctor_vis = if vis == ty::Visibility::Public
+ let mut ctor_vis = if vis.is_public()
&& self.r.session.contains_name(&item.attrs, sym::non_exhaustive)
{
- ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
+ ty::Visibility::Restricted(CRATE_DEF_ID)
} else {
vis
};
@@ -786,7 +791,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
if ctor_vis.is_at_least(field_vis, &*self.r) {
ctor_vis = field_vis;
}
- ret_fields.push(field_vis);
+ ret_fields.push(field_vis.to_def_id());
}
let ctor_def_id = self.r.local_def_id(ctor_node_id);
let ctor_res = Res::Def(
@@ -796,7 +801,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
self.r.visibilities.insert(ctor_def_id, ctor_vis);
- self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis, ret_fields));
+ self.r
+ .struct_constructors
+ .insert(def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields));
}
}
@@ -868,8 +875,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
.map(|module| {
let used = self.process_macro_use_imports(item, module);
- let binding =
- (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
+ let vis = ty::Visibility::<LocalDefId>::Public;
+ let binding = (module, vis, sp, expansion).to_name_binding(self.r.arenas);
(used, Some(ModuleOrUniformRoot::Module(module)), binding)
})
.unwrap_or((true, None, self.r.dummy_binding));
@@ -885,7 +892,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
root_span: item.span,
span: item.span,
module_path: Vec::new(),
- vis: Cell::new(vis),
+ vis: Cell::new(Some(vis)),
used: Cell::new(used),
});
self.r.potentially_unused_imports.push(import);
@@ -965,6 +972,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::TraitAlias
| DefKind::AssocTy,
_,
@@ -1030,7 +1038,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
self.insert_field_names(def_id, field_names);
}
Res::Def(DefKind::AssocFn, def_id) => {
- if cstore.fn_has_self_parameter_untracked(def_id) {
+ if cstore.fn_has_self_parameter_untracked(def_id, self.r.session) {
self.r.has_self.insert(def_id);
}
}
@@ -1118,7 +1126,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
root_span: span,
span,
module_path: Vec::new(),
- vis: Cell::new(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())),
+ vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID))),
used: Cell::new(false),
})
};
@@ -1264,7 +1272,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let vis = if is_macro_export {
ty::Visibility::Public
} else {
- ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
+ ty::Visibility::Restricted(CRATE_DEF_ID)
};
let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas);
self.r.set_binding_parent_module(binding, parent_scope.module);
@@ -1295,7 +1303,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
_ => self.resolve_visibility(&item.vis),
};
- if vis != ty::Visibility::Public {
+ if !vis.is_public() {
self.insert_unused_macro(ident, def_id, item.id, &rule_spans);
}
self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
@@ -1508,10 +1516,10 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
self.r.visibilities.insert(def_id, vis);
// If the variant is marked as non_exhaustive then lower the visibility to within the crate.
- let ctor_vis = if vis == ty::Visibility::Public
+ let ctor_vis = if vis.is_public()
&& self.r.session.contains_name(&variant.attrs, sym::non_exhaustive)
{
- ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
+ ty::Visibility::Restricted(CRATE_DEF_ID)
} else {
vis
};
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index f2f6f1d89..8b58b32b6 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -227,7 +227,7 @@ impl Resolver<'_> {
for import in self.potentially_unused_imports.iter() {
match import.kind {
_ if import.used.get()
- || import.vis.get().is_public()
+ || import.expect_vis().is_public()
|| import.span.is_dummy() =>
{
if let ImportKind::MacroUse = import.kind {
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 66641fb2c..3f88f44ff 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -8,7 +8,6 @@ use rustc_hir::definitions::*;
use rustc_span::hygiene::LocalExpnId;
use rustc_span::symbol::sym;
use rustc_span::Span;
-use tracing::debug;
pub(crate) fn collect_definitions(
resolver: &mut Resolver<'_>,
@@ -155,7 +154,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
}
}
- visit::walk_fn(self, fn_kind, span);
+ visit::walk_fn(self, fn_kind);
}
fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 8839fb1a1..ab71fa0bc 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -25,7 +25,6 @@ use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Span};
-use tracing::debug;
use crate::imports::{Import, ImportKind, ImportResolver};
use crate::late::{PatternSource, Rib};
@@ -511,7 +510,7 @@ impl<'a> Resolver<'a> {
err.span_label(span, "use of generic parameter from outer function");
let sm = self.session.source_map();
- match outer_res {
+ let def_id = match outer_res {
Res::SelfTy { trait_: maybe_trait_defid, alias_to: maybe_impl_defid } => {
if let Some(impl_span) =
maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id))
@@ -536,11 +535,13 @@ impl<'a> Resolver<'a> {
if let Some(span) = self.opt_span(def_id) {
err.span_label(span, "type parameter from outer function");
}
+ def_id
}
Res::Def(DefKind::ConstParam, def_id) => {
if let Some(span) = self.opt_span(def_id) {
err.span_label(span, "const parameter from outer function");
}
+ def_id
}
_ => {
bug!(
@@ -548,28 +549,23 @@ impl<'a> Resolver<'a> {
DefKind::TyParam or DefKind::ConstParam"
);
}
- }
+ };
- if has_generic_params == HasGenericParams::Yes {
+ if let HasGenericParams::Yes(span) = has_generic_params {
// Try to retrieve the span of the function signature and generate a new
// message with a local type or const parameter.
let sugg_msg = "try using a local generic parameter instead";
- if let Some((sugg_span, snippet)) = sm.generate_local_type_param_snippet(span) {
- // Suggest the modification to the user
- err.span_suggestion(
- sugg_span,
- sugg_msg,
- snippet,
- Applicability::MachineApplicable,
- );
- } else if let Some(sp) = sm.generate_fn_name_span(span) {
- err.span_label(
- sp,
- "try adding a local generic parameter in this method instead",
- );
+ let name = self.opt_name(def_id).unwrap_or(sym::T);
+ let (span, snippet) = if span.is_empty() {
+ let snippet = format!("<{}>", name);
+ (span, snippet)
} else {
- err.help("try using a local generic parameter instead");
- }
+ let span = sm.span_through_char(span, '<').shrink_to_hi();
+ let snippet = format!("{}, ", name);
+ (span, snippet)
+ };
+ // Suggest the modification to the user
+ err.span_suggestion(span, sugg_msg, snippet, Applicability::MaybeIncorrect);
}
err
@@ -1175,16 +1171,6 @@ impl<'a> Resolver<'a> {
Scope::Module(module, _) => {
this.add_module_candidates(module, &mut suggestions, filter_fn);
}
- Scope::RegisteredAttrs => {
- let res = Res::NonMacroAttr(NonMacroAttrKind::Registered);
- if filter_fn(res) {
- suggestions.extend(
- this.registered_attrs
- .iter()
- .map(|ident| TypoSuggestion::typo_from_res(ident.name, res)),
- );
- }
- }
Scope::MacroUsePrelude => {
suggestions.extend(this.macro_use_prelude.iter().filter_map(
|(name, binding)| {
@@ -1407,7 +1393,7 @@ impl<'a> Resolver<'a> {
// If only some candidates are accessible, take just them
if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) {
- candidates = candidates.into_iter().filter(|x| x.accessible).collect();
+ candidates.retain(|x| x.accessible)
}
candidates
@@ -2544,12 +2530,15 @@ fn show_candidates(
Applicability::MaybeIncorrect,
);
if let [first, .., last] = &path[..] {
- err.span_suggestion_verbose(
- first.ident.span.until(last.ident.span),
- &format!("if you import `{}`, refer to it directly", last.ident),
- "",
- Applicability::Unspecified,
- );
+ let sp = first.ident.span.until(last.ident.span);
+ if sp.can_be_used_for_suggestions() {
+ err.span_suggestion_verbose(
+ sp,
+ &format!("if you import `{}`, refer to it directly", last.ident),
+ "",
+ Applicability::Unspecified,
+ );
+ }
}
} else {
msg.push(':');
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 6e6782881..2287aa1eb 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -6,6 +6,7 @@ use rustc_middle::bug;
use rustc_middle::ty;
use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_span::def_id::LocalDefId;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
use rustc_span::symbol::{kw, Ident};
@@ -13,7 +14,9 @@ use rustc_span::{Span, DUMMY_SP};
use std::ptr;
-use crate::late::{ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind};
+use crate::late::{
+ ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
+};
use crate::macros::{sub_namespace_match, MacroRulesScope};
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
@@ -24,6 +27,8 @@ use Determinacy::*;
use Namespace::*;
use RibKind::*;
+type Visibility = ty::Visibility<LocalDefId>;
+
impl<'a> Resolver<'a> {
/// A generic scope visitor.
/// Visits scopes in order to resolve some identifier in them or perform other actions.
@@ -125,7 +130,6 @@ impl<'a> Resolver<'a> {
}
Scope::CrateRoot => true,
Scope::Module(..) => true,
- Scope::RegisteredAttrs => use_prelude,
Scope::MacroUsePrelude => use_prelude || rust_2015,
Scope::BuiltinAttrs => true,
Scope::ExternPrelude => use_prelude || is_absolute_path,
@@ -185,12 +189,11 @@ impl<'a> Resolver<'a> {
match ns {
TypeNS => Scope::ExternPrelude,
ValueNS => Scope::StdLibPrelude,
- MacroNS => Scope::RegisteredAttrs,
+ MacroNS => Scope::MacroUsePrelude,
}
}
}
}
- Scope::RegisteredAttrs => Scope::MacroUsePrelude,
Scope::MacroUsePrelude => Scope::StdLibPrelude,
Scope::BuiltinAttrs => break, // nowhere else to search
Scope::ExternPrelude if is_absolute_path => break,
@@ -273,7 +276,7 @@ impl<'a> Resolver<'a> {
///
/// Invariant: This must only be called during main resolution, not during
/// import resolution.
- #[tracing::instrument(level = "debug", skip(self, ribs))]
+ #[instrument(level = "debug", skip(self, ribs))]
pub(crate) fn resolve_ident_in_lexical_scope(
&mut self,
mut ident: Ident,
@@ -367,7 +370,7 @@ impl<'a> Resolver<'a> {
/// expansion and import resolution (perhaps they can be merged in the future).
/// The function is used for resolving initial segments of macro paths (e.g., `foo` in
/// `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
- #[tracing::instrument(level = "debug", skip(self, scope_set))]
+ #[instrument(level = "debug", skip(self, scope_set))]
pub(crate) fn early_resolve_ident_in_lexical_scope(
&mut self,
orig_ident: Ident,
@@ -424,8 +427,7 @@ impl<'a> Resolver<'a> {
let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
let ok = |res, span, arenas| {
Ok((
- (res, ty::Visibility::Public, span, LocalExpnId::ROOT)
- .to_name_binding(arenas),
+ (res, Visibility::Public, span, LocalExpnId::ROOT).to_name_binding(arenas),
Flags::empty(),
))
};
@@ -438,7 +440,7 @@ impl<'a> Resolver<'a> {
{
let binding = (
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
- ty::Visibility::Public,
+ Visibility::Public,
attr.span,
expn_id,
)
@@ -554,14 +556,6 @@ impl<'a> Resolver<'a> {
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
}
}
- Scope::RegisteredAttrs => match this.registered_attrs.get(&ident).cloned() {
- Some(ident) => ok(
- Res::NonMacroAttr(NonMacroAttrKind::Registered),
- ident.span,
- this.arenas,
- ),
- None => Err(Determinacy::Determined),
- },
Scope::MacroUsePrelude => {
match this.macro_use_prelude.get(&ident.name).cloned() {
Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
@@ -716,7 +710,7 @@ impl<'a> Resolver<'a> {
Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn maybe_resolve_ident_in_module(
&mut self,
module: ModuleOrUniformRoot<'a>,
@@ -728,7 +722,7 @@ impl<'a> Resolver<'a> {
.map_err(|(determinacy, _)| determinacy)
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_ident_in_module(
&mut self,
module: ModuleOrUniformRoot<'a>,
@@ -742,7 +736,7 @@ impl<'a> Resolver<'a> {
.map_err(|(determinacy, _)| determinacy)
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_ext(
&mut self,
module: ModuleOrUniformRoot<'a>,
@@ -780,7 +774,7 @@ impl<'a> Resolver<'a> {
)
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_unadjusted(
&mut self,
module: ModuleOrUniformRoot<'a>,
@@ -804,7 +798,7 @@ impl<'a> Resolver<'a> {
/// Attempts to resolve `ident` in namespaces `ns` of `module`.
/// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete.
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_unadjusted_ext(
&mut self,
module: ModuleOrUniformRoot<'a>,
@@ -849,9 +843,8 @@ impl<'a> Resolver<'a> {
if ns == TypeNS {
if ident.name == kw::Crate || ident.name == kw::DollarCrate {
let module = self.resolve_crate_root(ident);
- let binding =
- (module, ty::Visibility::Public, module.span, LocalExpnId::ROOT)
- .to_name_binding(self.arenas);
+ let binding = (module, Visibility::Public, module.span, LocalExpnId::ROOT)
+ .to_name_binding(self.arenas);
return Ok(binding);
} else if ident.name == kw::Super || ident.name == kw::SelfLower {
// FIXME: Implement these with renaming requirements so that e.g.
@@ -951,7 +944,10 @@ impl<'a> Resolver<'a> {
// Check if one of single imports can still define the name,
// if it can then our result is not determined and can be invalidated.
for single_import in &resolution.single_imports {
- if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) {
+ let Some(import_vis) = single_import.vis.get() else {
+ continue;
+ };
+ if !self.is_accessible_from(import_vis, parent_scope.module) {
continue;
}
let Some(module) = single_import.imported_module.get() else {
@@ -1016,7 +1012,10 @@ impl<'a> Resolver<'a> {
// Check if one of glob imports can still define the name,
// if it can then our "no resolution" result is not determined and can be invalidated.
for glob_import in module.globs.borrow().iter() {
- if !self.is_accessible_from(glob_import.vis.get(), parent_scope.module) {
+ let Some(import_vis) = glob_import.vis.get() else {
+ continue;
+ };
+ if !self.is_accessible_from(import_vis, parent_scope.module) {
continue;
}
let module = match glob_import.imported_module.get() {
@@ -1061,7 +1060,7 @@ impl<'a> Resolver<'a> {
}
/// Validate a local resolution (from ribs).
- #[tracing::instrument(level = "debug", skip(self, all_ribs))]
+ #[instrument(level = "debug", skip(self, all_ribs))]
fn validate_res_from_ribs(
&mut self,
rib_index: usize,
@@ -1103,7 +1102,7 @@ impl<'a> Resolver<'a> {
| ForwardGenericParamBanRibKind => {
// Nothing to do. Continue.
}
- ItemRibKind(_) | FnItemRibKind | AssocItemRibKind => {
+ ItemRibKind(_) | AssocItemRibKind => {
// This was an attempt to access an upvar inside a
// named function item. This is not allowed, so we
// report an error.
@@ -1168,10 +1167,10 @@ impl<'a> Resolver<'a> {
let has_generic_params: HasGenericParams = match rib.kind {
NormalRibKind
| ClosureOrAsyncRibKind
- | AssocItemRibKind
| ModuleRibKind(..)
| MacroDefinition(..)
| InlineAsmSymRibKind
+ | AssocItemRibKind
| ForwardGenericParamBanRibKind => {
// Nothing to do. Continue.
continue;
@@ -1180,7 +1179,9 @@ impl<'a> Resolver<'a> {
ConstantItemRibKind(trivial, _) => {
let features = self.session.features_untracked();
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
- if !(trivial == HasGenericParams::Yes || features.generic_const_exprs) {
+ if !(trivial == ConstantHasGenerics::Yes
+ || features.generic_const_exprs)
+ {
// HACK(min_const_generics): If we encounter `Self` in an anonymous constant
// we can't easily tell if it's generic at this stage, so we instead remember
// this and then enforce the self type to be concrete later on.
@@ -1207,7 +1208,6 @@ impl<'a> Resolver<'a> {
// This was an attempt to use a type parameter outside its scope.
ItemRibKind(has_generic_params) => has_generic_params,
- FnItemRibKind => HasGenericParams::Yes,
ConstParamTyRibKind => {
if let Some(span) = finalize {
self.report_error(
@@ -1232,28 +1232,22 @@ impl<'a> Resolver<'a> {
}
}
Res::Def(DefKind::ConstParam, _) => {
- let mut ribs = ribs.iter().peekable();
- if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
- // When declaring const parameters inside function signatures, the first rib
- // is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
- // (spuriously) conflicting with the const param.
- ribs.next();
- }
-
for rib in ribs {
let has_generic_params = match rib.kind {
NormalRibKind
| ClosureOrAsyncRibKind
- | AssocItemRibKind
| ModuleRibKind(..)
| MacroDefinition(..)
| InlineAsmSymRibKind
+ | AssocItemRibKind
| ForwardGenericParamBanRibKind => continue,
ConstantItemRibKind(trivial, _) => {
let features = self.session.features_untracked();
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
- if !(trivial == HasGenericParams::Yes || features.generic_const_exprs) {
+ if !(trivial == ConstantHasGenerics::Yes
+ || features.generic_const_exprs)
+ {
if let Some(span) = finalize {
self.report_error(
span,
@@ -1272,7 +1266,6 @@ impl<'a> Resolver<'a> {
}
ItemRibKind(has_generic_params) => has_generic_params,
- FnItemRibKind => HasGenericParams::Yes,
ConstParamTyRibKind => {
if let Some(span) = finalize {
self.report_error(
@@ -1302,7 +1295,7 @@ impl<'a> Resolver<'a> {
res
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn maybe_resolve_path(
&mut self,
path: &[Segment],
@@ -1312,7 +1305,7 @@ impl<'a> Resolver<'a> {
self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None)
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_path(
&mut self,
path: &[Segment],
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index b89273990..c133c272b 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -23,15 +23,13 @@ use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::Span;
-use tracing::*;
-
use std::cell::Cell;
use std::{mem, ptr};
type Res = def::Res<NodeId>;
/// Contains data for specific kinds of imports.
-#[derive(Clone, Debug)]
+#[derive(Clone)]
pub enum ImportKind<'a> {
Single {
/// `source` in `use prefix::source as target`.
@@ -52,8 +50,8 @@ pub enum ImportKind<'a> {
},
Glob {
is_prelude: bool,
- max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export.
- // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
+ max_vis: Cell<Option<ty::Visibility>>, // The visibility of the greatest re-export.
+ // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
},
ExternCrate {
source: Option<Symbol>,
@@ -62,6 +60,44 @@ pub enum ImportKind<'a> {
MacroUse,
}
+/// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
+/// contain `Cell`s which can introduce infinite loops while printing.
+impl<'a> std::fmt::Debug for ImportKind<'a> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ use ImportKind::*;
+ match self {
+ Single {
+ ref source,
+ ref target,
+ ref type_ns_only,
+ ref nested,
+ ref additional_ids,
+ // Ignore the following to avoid an infinite loop while printing.
+ source_bindings: _,
+ target_bindings: _,
+ } => f
+ .debug_struct("Single")
+ .field("source", source)
+ .field("target", target)
+ .field("type_ns_only", type_ns_only)
+ .field("nested", nested)
+ .field("additional_ids", additional_ids)
+ .finish_non_exhaustive(),
+ Glob { ref is_prelude, ref max_vis } => f
+ .debug_struct("Glob")
+ .field("is_prelude", is_prelude)
+ .field("max_vis", max_vis)
+ .finish(),
+ ExternCrate { ref source, ref target } => f
+ .debug_struct("ExternCrate")
+ .field("source", source)
+ .field("target", target)
+ .finish(),
+ MacroUse => f.debug_struct("MacroUse").finish(),
+ }
+ }
+}
+
/// One import.
#[derive(Debug, Clone)]
pub(crate) struct Import<'a> {
@@ -106,7 +142,7 @@ pub(crate) struct Import<'a> {
pub module_path: Vec<Segment>,
/// The resolution of `module_path`.
pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
- pub vis: Cell<ty::Visibility>,
+ pub vis: Cell<Option<ty::Visibility>>,
pub used: Cell<bool>,
}
@@ -121,6 +157,10 @@ impl<'a> Import<'a> {
_ => false,
}
}
+
+ pub(crate) fn expect_vis(&self) -> ty::Visibility {
+ self.vis.get().expect("encountered cleared import visibility")
+ }
}
/// Records information about the resolution of a name in a namespace of a module.
@@ -161,7 +201,7 @@ fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBindi
import: Import { kind: ImportKind::ExternCrate { .. }, .. },
..
},
- ) => import.vis.get().is_public(),
+ ) => import.expect_vis().is_public(),
_ => false,
}
}
@@ -174,17 +214,20 @@ impl<'a> Resolver<'a> {
binding: &'a NameBinding<'a>,
import: &'a Import<'a>,
) -> &'a NameBinding<'a> {
- let vis = if binding.vis.is_at_least(import.vis.get(), self)
+ let import_vis = import.expect_vis().to_def_id();
+ let vis = if binding.vis.is_at_least(import_vis, self)
|| pub_use_of_private_extern_crate_hack(import, binding)
{
- import.vis.get()
+ import_vis
} else {
binding.vis
};
if let ImportKind::Glob { ref max_vis, .. } = import.kind {
- if vis == import.vis.get() || vis.is_at_least(max_vis.get(), self) {
- max_vis.set(vis)
+ if vis == import_vis
+ || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self))
+ {
+ max_vis.set(Some(vis.expect_local()))
}
}
@@ -498,7 +541,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
} else {
// For better failure detection, pretend that the import will
// not define any names while resolving its module path.
- let orig_vis = import.vis.replace(ty::Visibility::Invisible);
+ let orig_vis = import.vis.take();
let path_res =
self.r.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
import.vis.set(orig_vis);
@@ -533,7 +576,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
if let Err(Undetermined) = source_bindings[ns].get() {
// For better failure detection, pretend that the import will
// not define any names while resolving its module path.
- let orig_vis = import.vis.replace(ty::Visibility::Invisible);
+ let orig_vis = import.vis.take();
let binding = this.resolve_ident_in_module(
module,
source,
@@ -582,7 +625,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
/// Optionally returns an unresolved import error. This error is buffered and used to
/// consolidate multiple unresolved import errors into a single diagnostic.
fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
- let orig_vis = import.vis.replace(ty::Visibility::Invisible);
+ let orig_vis = import.vis.take();
let ignore_binding = match &import.kind {
ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
_ => None,
@@ -689,9 +732,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
});
}
}
- if !is_prelude &&
- max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
- !max_vis.get().is_at_least(import.vis.get(), &*self.r)
+ if !is_prelude
+ && let Some(max_vis) = max_vis.get()
+ && !max_vis.is_at_least(import.expect_vis(), &*self.r)
{
let msg = "glob import doesn't reexport anything because no candidate is public enough";
self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg);
@@ -704,7 +747,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
let mut all_ns_err = true;
self.r.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
- let orig_vis = import.vis.replace(ty::Visibility::Invisible);
+ let orig_vis = import.vis.take();
let binding = this.resolve_ident_in_module(
module,
ident,
@@ -868,8 +911,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
let mut crate_private_reexport = false;
self.r.per_ns(|this, ns| {
if let Ok(binding) = source_bindings[ns].get() {
- let vis = import.vis.get();
- if !binding.vis.is_at_least(vis, &*this) {
+ if !binding.vis.is_at_least(import.expect_vis(), &*this) {
reexport_error = Some((ns, binding));
if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
if binding_def_id.is_top_level_module() {
@@ -1091,24 +1133,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
if let Some(def_id) = module.opt_def_id() {
let mut reexports = Vec::new();
- module.for_each_child(self.r, |_, ident, _, binding| {
- // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
- // into the crate root to actual `NameBindingKind::Import`.
- if binding.is_import()
- || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
- {
- let res = binding.res().expect_non_local();
- // Ambiguous imports are treated as errors at this point and are
- // not exposed to other crates (see #36837 for more details).
- if res != def::Res::Err && !binding.is_ambiguity() {
- reexports.push(ModChild {
- ident,
- res,
- vis: binding.vis,
- span: binding.span,
- macro_rules: false,
- });
- }
+ module.for_each_child(self.r, |this, ident, _, binding| {
+ if let Some(res) = this.is_reexport(binding) {
+ reexports.push(ModChild {
+ ident,
+ res,
+ vis: binding.vis,
+ span: binding.span,
+ macro_rules: false,
+ });
}
});
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index dea3eaecd..d8d82e125 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -20,7 +20,7 @@ use rustc_errors::DiagnosticId;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
-use rustc_hir::{PrimTy, TraitCandidate};
+use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
use rustc_middle::middle::resolve_lifetime::Set1;
use rustc_middle::ty::DefIdTree;
use rustc_middle::{bug, span_bug};
@@ -30,9 +30,9 @@ use rustc_span::{BytePos, Span};
use smallvec::{smallvec, SmallVec};
use rustc_span::source_map::{respan, Spanned};
+use std::assert_matches::debug_assert_matches;
use std::collections::{hash_map::Entry, BTreeSet};
use std::mem::{replace, take};
-use tracing::debug;
mod diagnostics;
pub(crate) mod lifetimes;
@@ -51,7 +51,7 @@ use diagnostics::{
#[derive(Copy, Clone, Debug)]
struct BindingInfo {
span: Span,
- binding_mode: BindingMode,
+ annotation: BindingAnnotation,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -91,13 +91,20 @@ enum PatBoundCtx {
}
/// Does this the item (from the item rib scope) allow generic parameters?
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug)]
pub(crate) enum HasGenericParams {
+ Yes(Span),
+ No,
+}
+
+/// May this constant have generics?
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub(crate) enum ConstantHasGenerics {
Yes,
No,
}
-impl HasGenericParams {
+impl ConstantHasGenerics {
fn force_yes_if(self, b: bool) -> Self {
if b { Self::Yes } else { self }
}
@@ -125,10 +132,6 @@ pub(crate) enum RibKind<'a> {
/// We passed through a closure. Disallow labels.
ClosureOrAsyncRibKind,
- /// We passed through a function definition. Disallow upvars.
- /// Permit only those const parameters that are specified in the function's generics.
- FnItemRibKind,
-
/// We passed through an item scope. Disallow upvars.
ItemRibKind(HasGenericParams),
@@ -136,7 +139,7 @@ pub(crate) enum RibKind<'a> {
///
/// The item may reference generic parameters in trivial constant expressions.
/// All other constants aren't allowed to use generic params at all.
- ConstantItemRibKind(HasGenericParams, Option<(Ident, ConstantItemKind)>),
+ ConstantItemRibKind(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
/// We passed through a module.
ModuleRibKind(Module<'a>),
@@ -165,7 +168,6 @@ impl RibKind<'_> {
match self {
NormalRibKind
| ClosureOrAsyncRibKind
- | FnItemRibKind
| ConstantItemRibKind(..)
| ModuleRibKind(_)
| MacroDefinition(_)
@@ -182,7 +184,6 @@ impl RibKind<'_> {
AssocItemRibKind
| ClosureOrAsyncRibKind
- | FnItemRibKind
| ItemRibKind(..)
| ConstantItemRibKind(..)
| ModuleRibKind(..)
@@ -557,7 +558,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
/// They will be used to determine the correct lifetime for the fn return type.
/// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named
/// lifetimes.
- lifetime_elision_candidates: Option<FxIndexMap<LifetimeRes, LifetimeElisionCandidate>>,
+ lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,
/// The trait that the current context can refer to.
current_trait_ref: Option<(Module<'a>, TraitRef)>,
@@ -629,7 +630,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
// NodeId `ty.id`.
// This span will be used in case of elision failure.
- let span = self.r.session.source_map().next_point(ty.span.shrink_to_lo());
+ let span = self.r.session.source_map().start_point(ty.span);
self.resolve_elided_lifetime(ty.id, span);
visit::walk_ty(self, ty);
}
@@ -723,7 +724,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
self.diagnostic_metadata.current_trait_object = prev;
self.diagnostic_metadata.current_type_path = prev_ty;
}
- fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef, _: &'ast TraitBoundModifier) {
+ fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
self.with_generic_param_rib(
&tref.bound_generic_params,
@@ -751,7 +752,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
this.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: foreign_item.id,
kind: LifetimeBinderKind::Item,
@@ -765,7 +766,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
this.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: foreign_item.id,
kind: LifetimeBinderKind::Function,
@@ -786,7 +787,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
}
}
fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) {
- let rib_kind = match fn_kind {
+ let previous_value = self.diagnostic_metadata.current_function;
+ match fn_kind {
// Bail if the function is foreign, and thus cannot validly have
// a body, or if there's no body for some other reason.
FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
@@ -809,20 +811,18 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
);
return;
}
- FnKind::Fn(FnCtxt::Free, ..) => FnItemRibKind,
- FnKind::Fn(FnCtxt::Assoc(_), ..) => NormalRibKind,
- FnKind::Closure(..) => ClosureOrAsyncRibKind,
+ FnKind::Fn(..) => {
+ self.diagnostic_metadata.current_function = Some((fn_kind, sp));
+ }
+ // Do not update `current_function` for closures: it suggests `self` parameters.
+ FnKind::Closure(..) => {}
};
- let previous_value = self.diagnostic_metadata.current_function;
- if matches!(fn_kind, FnKind::Fn(..)) {
- self.diagnostic_metadata.current_function = Some((fn_kind, sp));
- }
debug!("(resolving function) entering function");
// Create a value rib for the function.
- self.with_rib(ValueNS, rib_kind, |this| {
+ self.with_rib(ValueNS, ClosureOrAsyncRibKind, |this| {
// Create a label rib for the function.
- this.with_label_rib(FnItemRibKind, |this| {
+ this.with_label_rib(ClosureOrAsyncRibKind, |this| {
match fn_kind {
FnKind::Fn(_, _, sig, _, generics, body) => {
this.visit_generics(generics);
@@ -852,7 +852,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// We include all lifetime parameters, either named or "Fresh".
// The order of those parameters does not matter, as long as it is
// deterministic.
- if let Some(async_node_id) = async_node_id {
+ if let Some((async_node_id, _)) = async_node_id {
let mut extra_lifetime_params = this
.r
.extra_lifetime_params_map
@@ -995,7 +995,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// non-trivial constants this is doesn't matter.
self.with_constant_rib(
IsRepeatExpr::No,
- HasGenericParams::Yes,
+ ConstantHasGenerics::Yes,
None,
|this| {
this.smart_resolve_path(
@@ -1031,7 +1031,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
if let Some(ref gen_args) = constraint.gen_args {
// Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
- this.visit_generic_args(gen_args.span(), gen_args)
+ this.visit_generic_args(gen_args)
});
}
match constraint.kind {
@@ -1045,10 +1045,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
}
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) {
+ fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
if let Some(ref args) = path_segment.args {
match &**args {
- GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, path_span, args),
+ GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),
GenericArgs::Parenthesized(p_args) => {
// Probe the lifetime ribs to know how to behave.
for rib in self.lifetime_ribs.iter().rev() {
@@ -1079,7 +1079,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// We have nowhere to introduce generics. Code is malformed,
// so use regular lifetime resolution to avoid spurious errors.
LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {
- visit::walk_generic_args(self, path_span, args);
+ visit::walk_generic_args(self, args);
break;
}
LifetimeRibKind::AnonymousCreateParameter { .. }
@@ -1390,7 +1390,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
})
}
- #[tracing::instrument(level = "debug", skip(self, work))]
+ #[instrument(level = "debug", skip(self, work))]
fn with_lifetime_rib<T>(
&mut self,
kind: LifetimeRibKind,
@@ -1404,7 +1404,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
ret
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {
let ident = lifetime.ident;
@@ -1508,7 +1508,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named);
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_anonymous_lifetime(&mut self, lifetime: &Lifetime, elided: bool) {
debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
@@ -1573,7 +1573,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) {
let id = self.r.next_node_id();
let lt = Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) };
@@ -1586,7 +1586,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.resolve_anonymous_lifetime(&lt, true);
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn create_fresh_lifetime(&mut self, id: NodeId, ident: Ident, binder: NodeId) -> LifetimeRes {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
debug!(?ident.span);
@@ -1604,7 +1604,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
res
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_elided_lifetimes_in_path(
&mut self,
path_id: NodeId,
@@ -1804,7 +1804,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn record_lifetime_res(
&mut self,
id: NodeId,
@@ -1820,14 +1820,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
match res {
LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => {
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
- candidates.insert(res, candidate);
+ candidates.push((res, candidate));
}
}
LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn record_lifetime_param(&mut self, id: NodeId, res: LifetimeRes) {
if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
panic!(
@@ -1838,7 +1838,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
}
/// Perform resolution of a function signature, accounting for lifetime elision.
- #[tracing::instrument(level = "debug", skip(self, inputs))]
+ #[instrument(level = "debug", skip(self, inputs))]
fn resolve_fn_signature(
&mut self,
fn_id: NodeId,
@@ -1873,12 +1873,25 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
has_self: bool,
inputs: impl Iterator<Item = (Option<&'ast Pat>, &'ast Ty)>,
) -> Result<LifetimeRes, (Vec<MissingLifetime>, Vec<ElisionFnParameter>)> {
- let outer_candidates =
- replace(&mut self.lifetime_elision_candidates, Some(Default::default()));
+ enum Elision {
+ /// We have not found any candidate.
+ None,
+ /// We have a candidate bound to `self`.
+ Self_(LifetimeRes),
+ /// We have a candidate bound to a parameter.
+ Param(LifetimeRes),
+ /// We failed elision.
+ Err,
+ }
+
+ // Save elision state to reinstate it later.
+ let outer_candidates = self.lifetime_elision_candidates.take();
- let mut elision_lifetime = None;
- let mut lifetime_count = 0;
+ // Result of elision.
+ let mut elision_lifetime = Elision::None;
+ // Information for diagnostics.
let mut parameter_info = Vec::new();
+ let mut all_candidates = Vec::new();
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
for (index, (pat, ty)) in inputs.enumerate() {
@@ -1886,12 +1899,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
if let Some(pat) = pat {
self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
}
+
+ // Record elision candidates only for this parameter.
+ debug_assert_matches!(self.lifetime_elision_candidates, None);
+ self.lifetime_elision_candidates = Some(Default::default());
self.visit_ty(ty);
+ let local_candidates = self.lifetime_elision_candidates.take();
- if let Some(ref candidates) = self.lifetime_elision_candidates {
- let new_count = candidates.len();
- let local_count = new_count - lifetime_count;
- if local_count != 0 {
+ if let Some(candidates) = local_candidates {
+ let distinct: FxHashSet<_> = candidates.iter().map(|(res, _)| *res).collect();
+ let lifetime_count = distinct.len();
+ if lifetime_count != 0 {
parameter_info.push(ElisionFnParameter {
index,
ident: if let Some(pat) = pat && let PatKind::Ident(_, ident, _) = pat.kind {
@@ -1899,48 +1917,64 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
} else {
None
},
- lifetime_count: local_count,
+ lifetime_count,
span: ty.span,
});
+ all_candidates.extend(candidates.into_iter().filter_map(|(_, candidate)| {
+ match candidate {
+ LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {
+ None
+ }
+ LifetimeElisionCandidate::Missing(missing) => Some(missing),
+ }
+ }));
+ }
+ let mut distinct_iter = distinct.into_iter();
+ if let Some(res) = distinct_iter.next() {
+ match elision_lifetime {
+ // We are the first parameter to bind lifetimes.
+ Elision::None => {
+ if distinct_iter.next().is_none() {
+ // We have a single lifetime => success.
+ elision_lifetime = Elision::Param(res)
+ } else {
+ // We have have multiple lifetimes => error.
+ elision_lifetime = Elision::Err;
+ }
+ }
+ // We have 2 parameters that bind lifetimes => error.
+ Elision::Param(_) => elision_lifetime = Elision::Err,
+ // `self` elision takes precedence over everything else.
+ Elision::Self_(_) | Elision::Err => {}
+ }
}
- lifetime_count = new_count;
}
// Handle `self` specially.
if index == 0 && has_self {
let self_lifetime = self.find_lifetime_for_self(ty);
if let Set1::One(lifetime) = self_lifetime {
- elision_lifetime = Some(lifetime);
- self.lifetime_elision_candidates = None;
+ // We found `self` elision.
+ elision_lifetime = Elision::Self_(lifetime);
} else {
- self.lifetime_elision_candidates = Some(Default::default());
- lifetime_count = 0;
+ // We do not have `self` elision: disregard the `Elision::Param` that we may
+ // have found.
+ elision_lifetime = Elision::None;
}
}
debug!("(resolving function / closure) recorded parameter");
}
- let all_candidates = replace(&mut self.lifetime_elision_candidates, outer_candidates);
- debug!(?all_candidates);
+ // Reinstate elision state.
+ debug_assert_matches!(self.lifetime_elision_candidates, None);
+ self.lifetime_elision_candidates = outer_candidates;
- if let Some(res) = elision_lifetime {
+ if let Elision::Param(res) | Elision::Self_(res) = elision_lifetime {
return Ok(res);
}
- // We do not have a `self` candidate, look at the full list.
- let all_candidates = all_candidates.unwrap();
- if all_candidates.len() == 1 {
- Ok(*all_candidates.first().unwrap().0)
- } else {
- let all_candidates = all_candidates
- .into_iter()
- .filter_map(|(_, candidate)| match candidate {
- LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => None,
- LifetimeElisionCandidate::Missing(missing) => Some(missing),
- })
- .collect();
- Err((all_candidates, parameter_info))
- }
+ // We do not have a candidate.
+ Err((all_candidates, parameter_info))
}
/// List all the lifetimes that appear in the provided type.
@@ -2071,7 +2105,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.with_current_self_item(item, |this| {
this.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2141,7 +2175,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2154,7 +2188,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
ItemKind::Fn(box Fn { ref generics, .. }) => {
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Function,
@@ -2186,7 +2220,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2210,7 +2244,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2251,7 +2285,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// so it doesn't matter whether this is a trivial constant.
this.with_constant_rib(
IsRepeatExpr::No,
- HasGenericParams::Yes,
+ ConstantHasGenerics::Yes,
Some((item.ident, constant_item_kind)),
|this| this.visit_expr(expr),
);
@@ -2412,7 +2446,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// Do not account for the parameters we just bound for function lifetime elision.
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
for (_, res) in function_lifetime_rib.bindings.values() {
- candidates.remove(res);
+ candidates.retain(|(r, _)| r != res);
}
}
@@ -2450,7 +2484,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
fn with_constant_rib(
&mut self,
is_repeat: IsRepeatExpr,
- may_use_generics: HasGenericParams,
+ may_use_generics: ConstantHasGenerics,
item: Option<(Ident, ConstantItemKind)>,
f: impl FnOnce(&mut Self),
) {
@@ -2517,7 +2551,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|this| {
this.with_constant_rib(
IsRepeatExpr::No,
- HasGenericParams::Yes,
+ ConstantHasGenerics::Yes,
None,
|this| this.visit_expr(expr),
)
@@ -2598,7 +2632,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// If applicable, create a rib for the type parameters.
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes),
+ ItemRibKind(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
span: generics.span,
binder: item_id,
@@ -2689,7 +2723,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
this.with_constant_rib(
IsRepeatExpr::No,
- HasGenericParams::Yes,
+ ConstantHasGenerics::Yes,
None,
|this| this.visit_expr(expr),
)
@@ -2866,10 +2900,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
pat.walk(&mut |pat| {
match pat.kind {
- PatKind::Ident(binding_mode, ident, ref sub_pat)
+ PatKind::Ident(annotation, ident, ref sub_pat)
if sub_pat.is_some() || self.is_base_res_local(pat.id) =>
{
- binding_map.insert(ident, BindingInfo { span: ident.span, binding_mode });
+ binding_map.insert(ident, BindingInfo { span: ident.span, annotation });
}
PatKind::Or(ref ps) => {
// Check the consistency of this or-pattern and
@@ -2926,7 +2960,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
binding_error.target.insert(pat_outer.span);
}
Some(binding_outer) => {
- if binding_outer.binding_mode != binding_inner.binding_mode {
+ if binding_outer.annotation != binding_inner.annotation {
// The binding modes in the outer and inner bindings differ.
inconsistent_vars
.entry(name)
@@ -3147,14 +3181,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
fn try_resolve_as_non_binding(
&mut self,
pat_src: PatternSource,
- bm: BindingMode,
+ ann: BindingAnnotation,
ident: Ident,
has_sub: bool,
) -> Option<Res> {
// An immutable (no `mut`) by-value (no `ref`) binding pattern without
// a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
// also be interpreted as a path to e.g. a constant, variant, etc.
- let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
+ let is_syntactic_ambiguity = !has_sub && ann == BindingAnnotation::NONE;
let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
let (res, binding) = match ls_binding {
@@ -3268,11 +3302,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
source: PathSource<'ast>,
finalize: Finalize,
) -> PartialRes {
- tracing::debug!(
+ debug!(
"smart_resolve_path_fragment(qself={:?}, path={:?}, finalize={:?})",
- qself,
- path,
- finalize,
+ qself, path, finalize,
);
let ns = source.namespace();
@@ -3696,9 +3728,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.with_constant_rib(
is_repeat,
if constant.value.is_potential_trivial_const_param() {
- HasGenericParams::Yes
+ ConstantHasGenerics::Yes
} else {
- HasGenericParams::No
+ ConstantHasGenerics::No
},
None,
|this| visit::walk_anon_const(this, constant),
@@ -3707,8 +3739,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
debug!("resolve_anon_const {constant:?}");
- self.with_constant_rib(IsRepeatExpr::No, HasGenericParams::Yes, None, |this| {
- visit::walk_anon_const(this, constant);
+ self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| {
+ visit::walk_anon_const(this, constant)
});
}
@@ -3802,7 +3834,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
for argument in arguments {
self.resolve_expr(argument, None);
}
- self.visit_path_segment(expr.span, segment);
+ self.visit_path_segment(segment);
}
ExprKind::Call(ref callee, ref arguments) => {
@@ -3815,9 +3847,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.with_constant_rib(
IsRepeatExpr::No,
if argument.is_potential_trivial_const_param() {
- HasGenericParams::Yes
+ ConstantHasGenerics::Yes
} else {
- HasGenericParams::No
+ ConstantHasGenerics::No
},
None,
|this| {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 2b1f2b88e..3b095eeeb 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -33,8 +33,6 @@ use rustc_span::{BytePos, Span};
use std::iter;
use std::ops::Deref;
-use tracing::debug;
-
type Res = def::Res<ast::NodeId>;
/// A field or associated item from self type suggested in case of resolution failure.
@@ -161,6 +159,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
msg: String,
fallback_label: String,
span: Span,
+ span_label: Option<(Span, &'a str)>,
could_be_expr: bool,
suggestion: Option<(Span, &'a str, String)>,
}
@@ -172,6 +171,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
msg: format!("expected {}, found {} `{}`", expected, res.descr(), path_str),
fallback_label: format!("not a {expected}"),
span,
+ span_label: match res {
+ Res::Def(kind, def_id) if kind == DefKind::TyParam => {
+ self.def_span(def_id).map(|span| (span, "found this type parameter"))
+ }
+ _ => None,
+ },
could_be_expr: match res {
Res::Def(DefKind::Fn, _) => {
// Verify whether this is a fn call or an Fn used as a type.
@@ -243,14 +248,32 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.map_or_else(String::new, |res| format!("{} ", res.descr()));
(mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)), None)
};
+
+ let (fallback_label, suggestion) = if path_str == "async"
+ && expected.starts_with("struct")
+ {
+ ("`async` blocks are only allowed in Rust 2018 or later".to_string(), suggestion)
+ } else {
+ // check if we are in situation of typo like `True` instead of `true`.
+ let override_suggestion =
+ if ["true", "false"].contains(&item_str.to_string().to_lowercase().as_str()) {
+ let item_typo = item_str.to_string().to_lowercase();
+ Some((
+ item_span,
+ "you may want to use a bool value instead",
+ format!("{}", item_typo),
+ ))
+ } else {
+ suggestion
+ };
+ (format!("not found in {mod_str}"), override_suggestion)
+ };
+
BaseError {
msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"),
- fallback_label: if path_str == "async" && expected.starts_with("struct") {
- "`async` blocks are only allowed in Rust 2018 or later".to_string()
- } else {
- format!("not found in {mod_str}")
- },
+ fallback_label,
span: item_span,
+ span_label: None,
could_be_expr: false,
suggestion,
}
@@ -262,6 +285,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
+ if let Some((span, label)) = base_error.span_label {
+ err.span_label(span, label);
+ }
+
if let Some(sugg) = base_error.suggestion {
err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
}
@@ -590,9 +617,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.filter(|&sp| sp != base_error.span)
.collect();
- let start_span = bounds.iter().map(|bound| bound.span()).next().unwrap();
+ let start_span = bounds[0].span();
// `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
- let end_span = bounds.iter().map(|bound| bound.span()).last().unwrap();
+ let end_span = bounds.last().unwrap().span();
// `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
let last_bound_span = spans.last().cloned().unwrap();
let mut multi_span: MultiSpan = spans.clone().into();
@@ -985,27 +1012,45 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let ns = source.namespace();
let is_expected = &|res| source.is_expected(res);
- let path_sep = |err: &mut Diagnostic, expr: &Expr| match expr.kind {
- ExprKind::Field(_, ident) => {
+ let path_sep = |err: &mut Diagnostic, expr: &Expr, kind: DefKind| {
+ const MESSAGE: &str = "use the path separator to refer to an item";
+
+ let (lhs_span, rhs_span) = match &expr.kind {
+ ExprKind::Field(base, ident) => (base.span, ident.span),
+ ExprKind::MethodCall(_, args, span) => (args[0].span, *span),
+ _ => return false,
+ };
+
+ if lhs_span.eq_ctxt(rhs_span) {
err.span_suggestion(
- expr.span,
- "use the path separator to refer to an item",
- format!("{}::{}", path_str, ident),
+ lhs_span.between(rhs_span),
+ MESSAGE,
+ "::",
Applicability::MaybeIncorrect,
);
true
- }
- ExprKind::MethodCall(ref segment, ..) => {
- let span = expr.span.with_hi(segment.ident.span.hi());
- err.span_suggestion(
- span,
- "use the path separator to refer to an item",
- format!("{}::{}", path_str, segment.ident),
+ } else if kind == DefKind::Struct
+ && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span)
+ && let Ok(snippet) = self.r.session.source_map().span_to_snippet(lhs_source_span)
+ {
+ // The LHS is a type that originates from a macro call.
+ // We have to add angle brackets around it.
+
+ err.span_suggestion_verbose(
+ lhs_source_span.until(rhs_span),
+ MESSAGE,
+ format!("<{snippet}>::"),
Applicability::MaybeIncorrect,
);
true
+ } else {
+ // Either we were unable to obtain the source span / the snippet or
+ // the LHS originates from a macro call and it is not a type and thus
+ // there is no way to replace `.` with `::` and still somehow suggest
+ // valid Rust code.
+
+ false
}
- _ => false,
};
let find_span = |source: &PathSource<'_>, err: &mut Diagnostic| {
@@ -1027,7 +1072,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
match source {
PathSource::Expr(Some(
parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. },
- )) if path_sep(err, &parent) => {}
+ )) if path_sep(err, &parent, DefKind::Struct) => {}
PathSource::Expr(
None
| Some(Expr {
@@ -1143,8 +1188,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
}
}
}
- (Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
- if !path_sep(err, &parent) {
+ (
+ Res::Def(kind @ (DefKind::Mod | DefKind::Trait), _),
+ PathSource::Expr(Some(parent)),
+ ) => {
+ if !path_sep(err, &parent, kind) {
return false;
}
}
@@ -1742,7 +1790,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
}
};
- let mut suggestable_variants = variants
+ let suggestable_variants = variants
.iter()
.filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind))
.map(|(variant, _, kind)| (path_names_to_string(variant), kind))
@@ -1752,8 +1800,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
CtorKind::Fictive => format!("({} {{}})", variant),
})
.collect::<Vec<_>>();
+ let no_suggestable_variant = suggestable_variants.is_empty();
- if !suggestable_variants.is_empty() {
+ if !no_suggestable_variant {
let msg = if suggestable_variants.len() == 1 {
"you might have meant to use the following enum variant"
} else {
@@ -1763,7 +1812,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
err.span_suggestions(
span,
msg,
- suggestable_variants.drain(..),
+ suggestable_variants.into_iter(),
Applicability::MaybeIncorrect,
);
}
@@ -1780,15 +1829,15 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.collect::<Vec<_>>();
if !suggestable_variants_with_placeholders.is_empty() {
- let msg = match (
- suggestable_variants.is_empty(),
- suggestable_variants_with_placeholders.len(),
- ) {
- (true, 1) => "the following enum variant is available",
- (true, _) => "the following enum variants are available",
- (false, 1) => "alternatively, the following enum variant is available",
- (false, _) => "alternatively, the following enum variants are also available",
- };
+ let msg =
+ match (no_suggestable_variant, suggestable_variants_with_placeholders.len()) {
+ (true, 1) => "the following enum variant is available",
+ (true, _) => "the following enum variants are available",
+ (false, 1) => "alternatively, the following enum variant is available",
+ (false, _) => {
+ "alternatively, the following enum variants are also available"
+ }
+ };
err.span_suggestions(
span,
@@ -2021,9 +2070,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
fn suggest_introducing_lifetime(
&self,
- err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+ err: &mut Diagnostic,
name: Option<&str>,
- suggest: impl Fn(&mut DiagnosticBuilder<'_, ErrorGuaranteed>, bool, Span, &str, String) -> bool,
+ suggest: impl Fn(&mut Diagnostic, bool, Span, &str, String) -> bool,
) {
let mut suggest_note = true;
for rib in self.lifetime_ribs.iter().rev() {
@@ -2147,9 +2196,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
err.emit()
}
- pub(crate) fn add_missing_lifetime_specifiers_label(
+ fn add_missing_lifetime_specifiers_label(
&mut self,
- err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+ err: &mut Diagnostic,
lifetime_refs: Vec<MissingLifetime>,
function_param_lifetimes: Option<(Vec<MissingLifetime>, Vec<ElisionFnParameter>)>,
) {
@@ -2300,7 +2349,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
err.multipart_suggestion_verbose(
message,
std::iter::once((span, intro_sugg))
- .chain(spans_suggs.clone())
+ .chain(spans_suggs.iter().cloned())
.collect(),
Applicability::MaybeIncorrect,
);
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 94460e33d..4d9704617 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -11,23 +11,21 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefIdMap, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node};
use rustc_middle::bug;
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_lifetime::*;
-use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
+use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
-use std::borrow::Cow;
use std::fmt;
-use std::mem::take;
trait RegionExt {
- fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region);
+ fn early(hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region);
fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region);
@@ -36,19 +34,13 @@ trait RegionExt {
fn shifted(self, amount: u32) -> Region;
fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region;
-
- fn subst<'a, L>(self, params: L, map: &NamedRegionMap) -> Option<Region>
- where
- L: Iterator<Item = &'a hir::Lifetime>;
}
impl RegionExt for Region {
- fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region) {
- let i = *index;
- *index += 1;
+ fn early(hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) {
let def_id = hir_map.local_def_id(param.hir_id);
- debug!("Region::early: index={} def_id={:?}", i, def_id);
- (def_id, Region::EarlyBound(i, def_id.to_def_id()))
+ debug!("Region::early: def_id={:?}", def_id);
+ (def_id, Region::EarlyBound(def_id.to_def_id()))
}
fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) {
@@ -65,9 +57,7 @@ impl RegionExt for Region {
match *self {
Region::Static => None,
- Region::EarlyBound(_, id) | Region::LateBound(_, _, id) | Region::Free(_, id) => {
- Some(id)
- }
+ Region::EarlyBound(id) | Region::LateBound(_, _, id) | Region::Free(_, id) => Some(id),
}
}
@@ -88,17 +78,6 @@ impl RegionExt for Region {
_ => self,
}
}
-
- fn subst<'a, L>(self, mut params: L, map: &NamedRegionMap) -> Option<Region>
- where
- L: Iterator<Item = &'a hir::Lifetime>,
- {
- if let Region::EarlyBound(index, _) = self {
- params.nth(index as usize).and_then(|lifetime| map.defs.get(&lifetime.hir_id).cloned())
- } else {
- Some(self)
- }
- }
}
/// Maps the id of each lifetime reference to the lifetime decl
@@ -131,9 +110,6 @@ pub(crate) struct LifetimeContext<'a, 'tcx> {
/// be false if the `Item` we are resolving lifetimes for is not a trait or
/// we eventually need lifetimes resolve for trait items.
trait_definition_only: bool,
-
- /// Cache for cross-crate per-definition object lifetime defaults.
- xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
}
#[derive(Debug)]
@@ -147,25 +123,6 @@ enum Scope<'a> {
/// for diagnostics.
lifetimes: FxIndexMap<LocalDefId, Region>,
- /// if we extend this scope with another scope, what is the next index
- /// we should use for an early-bound region?
- next_early_index: u32,
-
- /// Whether or not this binder would serve as the parent
- /// binder for opaque types introduced within. For example:
- ///
- /// ```text
- /// fn foo<'a>() -> impl for<'b> Trait<Item = impl Trait2<'a>>
- /// ```
- ///
- /// Here, the opaque types we create for the `impl Trait`
- /// and `impl Trait2` references will both have the `foo` item
- /// as their parent. When we get to `impl Trait2`, we find
- /// that it is nested within the `for<>` binder -- this flag
- /// allows us to skip that when looking for the parent binder
- /// of the resulting opaque type.
- opaque_type_parent: bool,
-
scope_type: BinderScopeType,
/// The late bound vars for a given item are stored by `HirId` to be
@@ -245,19 +202,9 @@ struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
- Scope::Binder {
- lifetimes,
- next_early_index,
- opaque_type_parent,
- scope_type,
- hir_id,
- where_bound_origin,
- s: _,
- } => f
+ Scope::Binder { lifetimes, scope_type, hir_id, where_bound_origin, s: _ } => f
.debug_struct("Binder")
.field("lifetimes", lifetimes)
- .field("next_early_index", next_early_index)
- .field("opaque_type_parent", opaque_type_parent)
.field("scope_type", scope_type)
.field("hir_id", hir_id)
.field("where_bound_origin", where_bound_origin)
@@ -294,10 +241,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
is_late_bound_map,
- object_lifetime_defaults: |tcx, id| match tcx.hir().find_by_def_id(id) {
- Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item),
- _ => None,
- },
+ object_lifetime_default,
late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id),
..*providers
@@ -334,7 +278,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
/// lifetimes into a single binder.) This requires us to resolve the
/// *trait definition* of `Sub`; basically just enough lifetime information
/// to look at the supertraits.
-#[tracing::instrument(level = "debug", skip(tcx))]
+#[instrument(level = "debug", skip(tcx))]
fn resolve_lifetimes_trait_definition(
tcx: TyCtxt<'_>,
local_def_id: LocalDefId,
@@ -345,7 +289,7 @@ fn resolve_lifetimes_trait_definition(
/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
/// You should not read the result of this query directly, but rather use
/// `named_region_map`, `is_late_bound_map`, etc.
-#[tracing::instrument(level = "debug", skip(tcx))]
+#[instrument(level = "debug", skip(tcx))]
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
convert_named_region_map(do_resolve(tcx, local_def_id, false))
}
@@ -363,7 +307,6 @@ fn do_resolve(
map: &mut named_region_map,
scope: ROOT_SCOPE,
trait_definition_only,
- xcrate_object_lifetime_defaults: Default::default(),
};
visitor.visit_item(item);
@@ -432,13 +375,6 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
item
}
-/// In traits, there is an implicit `Self` type parameter which comes before the generics.
-/// We have to account for this when computing the index of the other generic parameters.
-/// This function returns whether there is such an implicit parameter defined on the given item.
-fn sub_items_have_self_param(node: &hir::ItemKind<'_>) -> bool {
- matches!(*node, hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..))
-}
-
fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::BoundVariableKind {
match region {
Region::LateBound(_, _, def_id) => {
@@ -558,7 +494,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
- let next_early_index = self.next_early_index();
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
bound_generic_params
.iter()
@@ -576,8 +511,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: e.hir_id,
lifetimes,
s: self.scope,
- next_early_index,
- opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
@@ -592,6 +525,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
match &item.kind {
hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
@@ -603,7 +537,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
match item.kind {
hir::ItemKind::Fn(_, ref generics, _) => {
- self.visit_early_late(None, item.hir_id(), generics, |this| {
+ self.visit_early_late(item.hir_id(), generics, |this| {
intravisit::walk_item(this, item);
});
}
@@ -670,31 +604,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
| hir::ItemKind::TraitAlias(ref generics, ..)
| hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
// These kinds of items have only early-bound lifetime parameters.
- let mut index = if sub_items_have_self_param(&item.kind) {
- 1 // Self comes before lifetimes
- } else {
- 0
- };
- let mut non_lifetime_count = 0;
let lifetimes = generics
.params
.iter()
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {
- Some(Region::early(self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
- non_lifetime_count += 1;
- None
+ Some(Region::early(self.tcx.hir(), param))
}
+ GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
})
.collect();
self.map.late_bound_vars.insert(item.hir_id(), vec![]);
let scope = Scope::Binder {
hir_id: item.hir_id(),
lifetimes,
- next_early_index: index + non_lifetime_count,
- opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
s: ROOT_SCOPE,
where_bound_origin: None,
@@ -712,7 +635,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
match item.kind {
hir::ForeignItemKind::Fn(_, _, ref generics) => {
- self.visit_early_late(None, item.hir_id(), generics, |this| {
+ self.visit_early_late(item.hir_id(), generics, |this| {
intravisit::walk_foreign_item(this, item);
})
}
@@ -725,11 +648,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
match ty.kind {
hir::TyKind::BareFn(ref c) => {
- let next_early_index = self.next_early_index();
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c
.generic_params
.iter()
@@ -746,8 +668,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: ty.hir_id,
lifetimes,
s: self.scope,
- next_early_index,
- opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
@@ -762,7 +682,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let scope = Scope::TraitRefBoundary { s: self.scope };
self.with(scope, |this| {
for bound in bounds {
- this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
+ this.visit_poly_trait_ref(bound);
}
});
match lifetime.name {
@@ -795,7 +715,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
};
self.with(scope, |this| this.visit_ty(&mt.ty));
}
- hir::TyKind::OpaqueDef(item_id, lifetimes) => {
+ hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
@@ -886,32 +806,23 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// We want to start our early-bound indices at the end of the parent scope,
// not including any parent `impl Trait`s.
- let mut index = self.next_early_index_for_opaque_type();
- debug!(?index);
-
let mut lifetimes = FxIndexMap::default();
- let mut non_lifetime_count = 0;
debug!(?generics.params);
for param in generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {
- let (def_id, reg) = Region::early(self.tcx.hir(), &mut index, &param);
+ let (def_id, reg) = Region::early(self.tcx.hir(), &param);
lifetimes.insert(def_id, reg);
}
- GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
- non_lifetime_count += 1;
- }
+ GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {}
}
}
- let next_early_index = index + non_lifetime_count;
self.map.late_bound_vars.insert(ty.hir_id, vec![]);
let scope = Scope::Binder {
hir_id: ty.hir_id,
lifetimes,
- next_early_index,
s: self.scope,
- opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
@@ -929,43 +840,32 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
use self::hir::TraitItemKind::*;
match trait_item.kind {
Fn(_, _) => {
- let tcx = self.tcx;
- self.visit_early_late(
- Some(tcx.hir().get_parent_item(trait_item.hir_id())),
- trait_item.hir_id(),
- &trait_item.generics,
- |this| intravisit::walk_trait_item(this, trait_item),
- );
+ self.visit_early_late(trait_item.hir_id(), &trait_item.generics, |this| {
+ intravisit::walk_trait_item(this, trait_item)
+ });
}
Type(bounds, ref ty) => {
let generics = &trait_item.generics;
- let mut index = self.next_early_index();
- debug!("visit_ty: index = {}", index);
- let mut non_lifetime_count = 0;
let lifetimes = generics
.params
.iter()
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {
- Some(Region::early(self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
- non_lifetime_count += 1;
- None
+ Some(Region::early(self.tcx.hir(), param))
}
+ GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
})
.collect();
self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]);
let scope = Scope::Binder {
hir_id: trait_item.hir_id(),
lifetimes,
- next_early_index: index + non_lifetime_count,
s: self.scope,
- opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
@@ -990,43 +890,30 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
use self::hir::ImplItemKind::*;
match impl_item.kind {
- Fn(..) => {
- let tcx = self.tcx;
- self.visit_early_late(
- Some(tcx.hir().get_parent_item(impl_item.hir_id())),
- impl_item.hir_id(),
- &impl_item.generics,
- |this| intravisit::walk_impl_item(this, impl_item),
- );
- }
+ Fn(..) => self.visit_early_late(impl_item.hir_id(), &impl_item.generics, |this| {
+ intravisit::walk_impl_item(this, impl_item)
+ }),
TyAlias(ref ty) => {
let generics = &impl_item.generics;
- let mut index = self.next_early_index();
- let mut non_lifetime_count = 0;
- debug!("visit_ty: index = {}", index);
let lifetimes: FxIndexMap<LocalDefId, Region> = generics
.params
.iter()
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {
- Some(Region::early(self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => {
- non_lifetime_count += 1;
- None
+ Some(Region::early(self.tcx.hir(), param))
}
+ GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None,
})
.collect();
self.map.late_bound_vars.insert(ty.hir_id, vec![]);
let scope = Scope::Binder {
hir_id: ty.hir_id,
lifetimes,
- next_early_index: index + non_lifetime_count,
s: self.scope,
- opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
@@ -1046,7 +933,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
match lifetime_ref.name {
hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
@@ -1129,7 +1016,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
})
.unzip();
this.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone());
- let next_early_index = this.next_early_index();
// Even if there are no lifetimes defined here, we still wrap it in a binder
// scope. If there happens to be a nested poly trait ref (an error), that
// will be `Concatenating` anyways, so we don't have to worry about the depth
@@ -1138,8 +1024,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: bounded_ty.hir_id,
lifetimes,
s: this.scope,
- next_early_index,
- opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
where_bound_origin: Some(origin),
};
@@ -1210,8 +1094,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: *hir_id,
lifetimes: FxIndexMap::default(),
s: self.scope,
- next_early_index: self.next_early_index(),
- opaque_type_parent: false,
scope_type,
where_bound_origin: None,
};
@@ -1223,14 +1105,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
- fn visit_poly_trait_ref(
- &mut self,
- trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
- _modifier: hir::TraitBoundModifier,
- ) {
+ fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
- let next_early_index = self.next_early_index();
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
let initial_bound_vars = binders.len() as u32;
@@ -1260,8 +1137,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: trait_ref.trait_ref.hir_ref_id,
lifetimes,
s: self.scope,
- next_early_index,
- opaque_type_parent: false,
scope_type,
where_bound_origin: None,
};
@@ -1272,139 +1147,49 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
-fn compute_object_lifetime_defaults<'tcx>(
- tcx: TyCtxt<'tcx>,
- item: &hir::Item<'_>,
-) -> Option<&'tcx [ObjectLifetimeDefault]> {
- match item.kind {
- hir::ItemKind::Struct(_, ref generics)
- | hir::ItemKind::Union(_, ref generics)
- | hir::ItemKind::Enum(_, ref generics)
- | hir::ItemKind::OpaqueTy(hir::OpaqueTy {
- ref generics,
- origin: hir::OpaqueTyOrigin::TyAlias,
- ..
- })
- | hir::ItemKind::TyAlias(_, ref generics)
- | hir::ItemKind::Trait(_, _, ref generics, ..) => {
- let result = object_lifetime_defaults_for_item(tcx, generics);
-
- // Debugging aid.
- let attrs = tcx.hir().attrs(item.hir_id());
- if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
- let object_lifetime_default_reprs: String = result
- .iter()
- .map(|set| match *set {
- Set1::Empty => "BaseDefault".into(),
- Set1::One(Region::Static) => "'static".into(),
- Set1::One(Region::EarlyBound(mut i, _)) => generics
- .params
- .iter()
- .find_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- if i == 0 {
- return Some(param.name.ident().to_string().into());
- }
- i -= 1;
- None
- }
- _ => None,
- })
- .unwrap(),
- Set1::One(_) => bug!(),
- Set1::Many => "Ambiguous".into(),
- })
- .collect::<Vec<Cow<'static, str>>>()
- .join(",");
- tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
- }
-
- Some(result)
- }
- _ => None,
- }
-}
-
-/// Scan the bounds and where-clauses on parameters to extract bounds
-/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
-/// for each type parameter.
-fn object_lifetime_defaults_for_item<'tcx>(
- tcx: TyCtxt<'tcx>,
- generics: &hir::Generics<'_>,
-) -> &'tcx [ObjectLifetimeDefault] {
- fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
- for bound in bounds {
- if let hir::GenericBound::Outlives(ref lifetime) = *bound {
- set.insert(lifetime.name.normalize_to_macros_2_0());
- }
- }
- }
-
- let process_param = |param: &hir::GenericParam<'_>| match param.kind {
- GenericParamKind::Lifetime { .. } => None,
+fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> ObjectLifetimeDefault {
+ debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
+ let param_def_id = param_def_id.expect_local();
+ let parent_def_id = tcx.local_parent(param_def_id);
+ let generics = tcx.hir().get_generics(parent_def_id).unwrap();
+ let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id);
+ let param = generics.params.iter().find(|p| p.hir_id == param_hir_id).unwrap();
+
+ // Scan the bounds and where-clauses on parameters to extract bounds
+ // of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
+ // for each type parameter.
+ match param.kind {
GenericParamKind::Type { .. } => {
let mut set = Set1::Empty;
- let param_def_id = tcx.hir().local_def_id(param.hir_id);
- for predicate in generics.predicates {
- // Look for `type: ...` where clauses.
- let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };
-
+ // Look for `type: ...` where clauses.
+ for bound in generics.bounds_for_param(param_def_id) {
// Ignore `for<'a> type: ...` as they can change what
// lifetimes mean (although we could "just" handle it).
- if !data.bound_generic_params.is_empty() {
+ if !bound.bound_generic_params.is_empty() {
continue;
}
- let res = match data.bounded_ty.kind {
- hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
- _ => continue,
- };
-
- if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
- add_bounds(&mut set, &data.bounds);
+ for bound in bound.bounds {
+ if let hir::GenericBound::Outlives(ref lifetime) = *bound {
+ set.insert(lifetime.name.normalize_to_macros_2_0());
+ }
}
}
- Some(match set {
- Set1::Empty => Set1::Empty,
- Set1::One(name) => {
- if name == hir::LifetimeName::Static {
- Set1::One(Region::Static)
- } else {
- generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- let param_def_id = tcx.hir().local_def_id(param.hir_id);
- Some((
- param_def_id,
- hir::LifetimeName::Param(param_def_id, param.name),
- ))
- }
- _ => None,
- })
- .enumerate()
- .find(|&(_, (_, lt_name))| lt_name == name)
- .map_or(Set1::Many, |(i, (def_id, _))| {
- Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id()))
- })
- }
+ match set {
+ Set1::Empty => ObjectLifetimeDefault::Empty,
+ Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
+ Set1::One(hir::LifetimeName::Param(param_def_id, _)) => {
+ ObjectLifetimeDefault::Param(param_def_id.to_def_id())
}
- Set1::Many => Set1::Many,
- })
+ _ => ObjectLifetimeDefault::Ambiguous,
+ }
}
- GenericParamKind::Const { .. } => {
- // Generic consts don't impose any constraints.
- //
- // We still store a dummy value here to allow generic parameters
- // in an arbitrary order.
- Some(Set1::Empty)
+ _ => {
+ bug!("object_lifetime_default_raw must only be called on a type parameter")
}
- };
-
- tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
+ }
}
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
@@ -1413,20 +1198,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
{
let LifetimeContext { tcx, map, .. } = self;
- let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
let mut this = LifetimeContext {
tcx: *tcx,
map,
scope: &wrap_scope,
trait_definition_only: self.trait_definition_only,
- xcrate_object_lifetime_defaults,
};
- let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
+ let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
{
let _enter = span.enter();
f(&mut this);
}
- self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
}
/// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
@@ -1449,30 +1231,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
/// ordering is not important there.
fn visit_early_late<F>(
&mut self,
- parent_id: Option<LocalDefId>,
hir_id: hir::HirId,
generics: &'tcx hir::Generics<'tcx>,
walk: F,
) where
F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
{
- // Find the start of nested early scopes, e.g., in methods.
- let mut next_early_index = 0;
- if let Some(parent_id) = parent_id {
- let parent = self.tcx.hir().expect_item(parent_id);
- if sub_items_have_self_param(&parent.kind) {
- next_early_index += 1; // Self comes before lifetimes
- }
- match parent.kind {
- hir::ItemKind::Trait(_, _, ref generics, ..)
- | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
- next_early_index += generics.params.len() as u32;
- }
- _ => {}
- }
- }
-
- let mut non_lifetime_count = 0;
let mut named_late_bound_vars = 0;
let lifetimes: FxIndexMap<LocalDefId, Region> = generics
.params
@@ -1484,16 +1248,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
named_late_bound_vars += 1;
Some(Region::late(late_bound_idx, self.tcx.hir(), param))
} else {
- Some(Region::early(self.tcx.hir(), &mut next_early_index, param))
+ Some(Region::early(self.tcx.hir(), param))
}
}
- GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
- non_lifetime_count += 1;
- None
- }
+ GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
})
.collect();
- let next_early_index = next_early_index + non_lifetime_count;
let binders: Vec<_> = generics
.params
@@ -1512,52 +1272,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let scope = Scope::Binder {
hir_id,
lifetimes,
- next_early_index,
s: self.scope,
- opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
self.with(scope, walk);
}
- fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 {
- let mut scope = self.scope;
- loop {
- match *scope {
- Scope::Root => return 0,
-
- Scope::Binder { next_early_index, opaque_type_parent, .. }
- if (!only_opaque_type_parent || opaque_type_parent) =>
- {
- return next_early_index;
- }
-
- Scope::Binder { s, .. }
- | Scope::Body { s, .. }
- | Scope::Elision { s, .. }
- | Scope::ObjectLifetimeDefault { s, .. }
- | Scope::Supertrait { s, .. }
- | Scope::TraitRefBoundary { s, .. } => scope = s,
- }
- }
- }
-
- /// Returns the next index one would use for an early-bound-region
- /// if extending the current scope.
- fn next_early_index(&self) -> u32 {
- self.next_early_index_helper(true)
- }
-
- /// Returns the next index one would use for an `impl Trait` that
- /// is being converted into an opaque type alias `impl Trait`. This will be the
- /// next early index from the enclosing item, for the most
- /// part. See the `opaque_type_parent` field for more info.
- fn next_early_index_for_opaque_type(&self) -> u32 {
- self.next_early_index_helper(false)
- }
-
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn resolve_lifetime_ref(
&mut self,
region_def_id: LocalDefId,
@@ -1638,7 +1360,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
return;
}
- // We may fail to resolve higher-ranked lifetimes that are mentionned by APIT.
+ // We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
// AST-based resolution does not care for impl-trait desugaring, which are the
// responibility of lowering. This may create a mismatch between the resolution
// AST found (`region_def_id`) which points to HRTB, and what HIR allows.
@@ -1679,17 +1401,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
);
}
+ #[instrument(level = "debug", skip(self))]
fn visit_segment_args(
&mut self,
res: Res,
depth: usize,
generic_args: &'tcx hir::GenericArgs<'tcx>,
) {
- debug!(
- "visit_segment_args(res={:?}, depth={:?}, generic_args={:?})",
- res, depth, generic_args,
- );
-
if generic_args.parenthesized {
self.visit_fn_like_elision(
generic_args.inputs(),
@@ -1707,13 +1425,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
// Figure out if this is a type/trait segment,
// which requires object lifetime defaults.
- let parent_def_id = |this: &mut Self, def_id: DefId| {
- let def_key = this.tcx.def_key(def_id);
- DefId { krate: def_id.krate, index: def_key.parent.expect("missing parent") }
- };
let type_def_id = match res {
- Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(parent_def_id(self, def_id)),
- Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(parent_def_id(self, def_id)),
+ Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(self.tcx.parent(def_id)),
+ Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(self.tcx.parent(def_id)),
Res::Def(
DefKind::Struct
| DefKind::Union
@@ -1725,7 +1439,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
_ => None,
};
- debug!("visit_segment_args: type_def_id={:?}", type_def_id);
+ debug!(?type_def_id);
// Compute a vector of defaults, one for each type parameter,
// per the rules given in RFCs 599 and 1156. Example:
@@ -1763,55 +1477,52 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
};
let map = &self.map;
- let set_to_region = |set: &ObjectLifetimeDefault| match *set {
- Set1::Empty => {
+ let generics = self.tcx.generics_of(def_id);
+
+ // `type_def_id` points to an item, so there is nothing to inherit generics from.
+ debug_assert_eq!(generics.parent_count, 0);
+
+ let set_to_region = |set: ObjectLifetimeDefault| match set {
+ ObjectLifetimeDefault::Empty => {
if in_body {
None
} else {
Some(Region::Static)
}
}
- Set1::One(r) => {
- let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
- GenericArg::Lifetime(lt) => Some(lt),
+ ObjectLifetimeDefault::Static => Some(Region::Static),
+ ObjectLifetimeDefault::Param(param_def_id) => {
+ // This index can be used with `generic_args` since `parent_count == 0`.
+ let index = generics.param_def_id_to_index[&param_def_id] as usize;
+ generic_args.args.get(index).and_then(|arg| match arg {
+ GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id).copied(),
_ => None,
- });
- r.subst(lifetimes, map)
+ })
}
- Set1::Many => None,
+ ObjectLifetimeDefault::Ambiguous => None,
};
- if let Some(def_id) = def_id.as_local() {
- let id = self.tcx.hir().local_def_id_to_hir_id(def_id);
- self.tcx
- .object_lifetime_defaults(id.owner)
- .unwrap()
- .iter()
- .map(set_to_region)
- .collect()
- } else {
- let tcx = self.tcx;
- self.xcrate_object_lifetime_defaults
- .entry(def_id)
- .or_insert_with(|| {
- tcx.generics_of(def_id)
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamDefKind::Type { object_lifetime_default, .. } => {
- Some(object_lifetime_default)
- }
- GenericParamDefKind::Const { .. } => Some(Set1::Empty),
- GenericParamDefKind::Lifetime => None,
- })
- .collect()
- })
- .iter()
- .map(set_to_region)
- .collect()
- }
+ generics
+ .params
+ .iter()
+ .filter_map(|param| {
+ match self.tcx.def_kind(param.def_id) {
+ // Generic consts don't impose any constraints.
+ //
+ // We still store a dummy value here to allow generic parameters
+ // in an arbitrary order.
+ DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
+ DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
+ // We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
+ // works. Ignore it because it can't have a meaningful lifetime default.
+ DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
+ dk => bug!("unexpected def_kind {:?}", dk),
+ }
+ })
+ .map(set_to_region)
+ .collect()
});
- debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults);
+ debug!(?object_lifetime_defaults);
let mut i = 0;
for arg in generic_args.args {
@@ -1953,7 +1664,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn visit_fn_like_elision(
&mut self,
inputs: &'tcx [hir::Ty<'tcx>],
@@ -2001,7 +1712,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self))]
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
debug!(
node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
@@ -2112,7 +1823,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
// is, those would be potentially inputs to
// projections
if let Some(last_segment) = path.segments.last() {
- self.visit_path_segment(path.span, last_segment);
+ self.visit_path_segment(last_segment);
}
}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 62843c651..26b9284fe 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -7,12 +7,13 @@
//! Type-relative name resolution (methods, fields, associated items) happens in `rustc_typeck`.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)]
@@ -57,8 +58,7 @@ use rustc_span::{Span, DUMMY_SP};
use smallvec::{smallvec, SmallVec};
use std::cell::{Cell, RefCell};
use std::collections::BTreeSet;
-use std::{cmp, fmt, ptr};
-use tracing::debug;
+use std::{fmt, ptr};
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
use imports::{Import, ImportKind, ImportResolver, NameResolution};
@@ -108,7 +108,6 @@ enum Scope<'a> {
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
// lint if it should be reported.
Module(Module<'a>, Option<NodeId>),
- RegisteredAttrs,
MacroUsePrelude,
BuiltinAttrs,
ExternPrelude,
@@ -165,7 +164,6 @@ enum ImplTraitContext {
Universal(LocalDefId),
}
-#[derive(Eq)]
struct BindingError {
name: Symbol,
origin: BTreeSet<Span>,
@@ -173,24 +171,6 @@ struct BindingError {
could_be_path: bool,
}
-impl PartialOrd for BindingError {
- fn partial_cmp(&self, other: &BindingError) -> Option<cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl PartialEq for BindingError {
- fn eq(&self, other: &BindingError) -> bool {
- self.name == other.name
- }
-}
-
-impl Ord for BindingError {
- fn cmp(&self, other: &BindingError) -> cmp::Ordering {
- self.name.cmp(&other.name)
- }
-}
-
enum ResolutionError<'a> {
/// Error E0401: can't use type or const parameters from outer function.
GenericParamsFromOuterFunction(Res, HasGenericParams),
@@ -650,7 +630,7 @@ pub struct NameBinding<'a> {
ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>,
expansion: LocalExpnId,
span: Span,
- vis: ty::Visibility,
+ vis: ty::Visibility<DefId>,
}
pub trait ToNameBinding<'a> {
@@ -847,7 +827,7 @@ impl<'a> NameBinding<'a> {
}
}
-#[derive(Debug, Default, Clone)]
+#[derive(Default, Clone)]
pub struct ExternPreludeEntry<'a> {
extern_crate_item: Option<&'a NameBinding<'a>>,
pub introduced_by_item: bool,
@@ -913,11 +893,6 @@ pub struct Resolver<'a> {
label_res_map: NodeMap<NodeId>,
/// Resolutions for lifetimes.
lifetimes_res_map: NodeMap<LifetimeRes>,
- /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
- /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
- /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
- /// field from the original parameter 'a to the new parameter 'a1.
- generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
/// Lifetime parameters that lowering will have to introduce.
extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
@@ -976,7 +951,6 @@ pub struct Resolver<'a> {
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
/// the surface (`macro` items in libcore), but are actually attributes or derives.
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
- registered_attrs: FxHashSet<Ident>,
registered_tools: RegisteredTools,
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
macro_map: FxHashMap<DefId, MacroData>,
@@ -1020,7 +994,7 @@ pub struct Resolver<'a> {
/// Table for mapping struct IDs into struct constructor IDs,
/// it's not used during normal resolution, only for better error reporting.
/// Also includes of list of each fields visibility
- struct_constructors: DefIdMap<(Res, ty::Visibility, Vec<ty::Visibility>)>,
+ struct_constructors: DefIdMap<(Res, ty::Visibility<DefId>, Vec<ty::Visibility<DefId>>)>,
/// Features enabled for this crate.
active_features: FxHashSet<Symbol>,
@@ -1253,8 +1227,7 @@ impl<'a> Resolver<'a> {
}
}
- let (registered_attrs, registered_tools) =
- macros::registered_attrs_and_tools(session, &krate.attrs);
+ let registered_tools = macros::registered_tools(session, &krate.attrs);
let features = session.features_untracked();
@@ -1282,7 +1255,6 @@ impl<'a> Resolver<'a> {
import_res_map: Default::default(),
label_res_map: Default::default(),
lifetimes_res_map: Default::default(),
- generics_def_id_map: Vec::new(),
extra_lifetime_params_map: Default::default(),
extern_crate_map: Default::default(),
reexport_map: FxHashMap::default(),
@@ -1319,7 +1291,6 @@ impl<'a> Resolver<'a> {
macro_names: FxHashSet::default(),
builtin_macros: Default::default(),
builtin_macro_kinds: Default::default(),
- registered_attrs,
registered_tools,
macro_use_prelude: FxHashMap::default(),
macro_map: FxHashMap::default(),
@@ -1450,7 +1421,6 @@ impl<'a> Resolver<'a> {
import_res_map: self.import_res_map,
label_res_map: self.label_res_map,
lifetimes_res_map: self.lifetimes_res_map,
- generics_def_id_map: self.generics_def_id_map,
extra_lifetime_params_map: self.extra_lifetime_params_map,
next_node_id: self.next_node_id,
node_id_to_def_id: self.node_id_to_def_id,
@@ -1495,7 +1465,6 @@ impl<'a> Resolver<'a> {
import_res_map: self.import_res_map.clone(),
label_res_map: self.label_res_map.clone(),
lifetimes_res_map: self.lifetimes_res_map.clone(),
- generics_def_id_map: self.generics_def_id_map.clone(),
extra_lifetime_params_map: self.extra_lifetime_params_map.clone(),
next_node_id: self.next_node_id.clone(),
node_id_to_def_id: self.node_id_to_def_id.clone(),
@@ -1821,7 +1790,11 @@ impl<'a> Resolver<'a> {
self.pat_span_map.insert(node, span);
}
- fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
+ fn is_accessible_from(
+ &self,
+ vis: ty::Visibility<impl Into<DefId>>,
+ module: Module<'a>,
+ ) -> bool {
vis.is_accessible_from(module.nearest_parent_mod(), self)
}
@@ -1875,10 +1848,8 @@ impl<'a> Resolver<'a> {
self.crate_loader.maybe_process_path_extern(ident.name)?
};
let crate_root = self.expect_module(crate_id.as_def_id());
- Some(
- (crate_root, ty::Visibility::Public, DUMMY_SP, LocalExpnId::ROOT)
- .to_name_binding(self.arenas),
- )
+ let vis = ty::Visibility::<LocalDefId>::Public;
+ Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas))
}
})
}
@@ -1946,6 +1917,16 @@ impl<'a> Resolver<'a> {
def_id.as_local().map(|def_id| self.source_span[def_id])
}
+ /// Retrieves the name of the given `DefId`.
+ #[inline]
+ pub fn opt_name(&self, def_id: DefId) -> Option<Symbol> {
+ let def_key = match def_id.as_local() {
+ Some(def_id) => self.definitions.def_key(def_id),
+ None => self.cstore().def_key(def_id),
+ };
+ def_key.get_opt_name()
+ }
+
/// Checks if an expression refers to a function marked with
/// `#[rustc_legacy_const_generics]` and returns the argument index list
/// from the attribute.
@@ -1985,7 +1966,7 @@ impl<'a> Resolver<'a> {
_ => panic!("invalid arg index"),
}
}
- // Cache the lookup to avoid parsing attributes for an iterm multiple times.
+ // Cache the lookup to avoid parsing attributes for an item multiple times.
self.legacy_const_generic_args.insert(def_id, Some(ret.clone()));
return Some(ret);
}
@@ -2015,6 +1996,24 @@ impl<'a> Resolver<'a> {
}
self.main_def = Some(MainDefinition { res, is_import, span });
}
+
+ // Items that go to reexport table encoded to metadata and visible through it to other crates.
+ fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> {
+ // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
+ // into the crate root to actual `NameBindingKind::Import`.
+ if binding.is_import()
+ || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
+ {
+ let res = binding.res().expect_non_local();
+ // Ambiguous imports are treated as errors at this point and are
+ // not exposed to other crates (see #36837 for more details).
+ if res != def::Res::Err && !binding.is_ambiguity() {
+ return Some(res);
+ }
+ }
+
+ return None;
+ }
}
fn names_to_string(names: &[Symbol]) -> String {
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 070fb9c72..dafa10e9e 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -112,47 +112,32 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
}
}
-/// The code common between processing `#![register_tool]` and `#![register_attr]`.
-fn registered_idents(
- sess: &Session,
- attrs: &[ast::Attribute],
- attr_name: Symbol,
- descr: &str,
-) -> FxHashSet<Ident> {
- let mut registered = FxHashSet::default();
- for attr in sess.filter_by_name(attrs, attr_name) {
+pub(crate) fn registered_tools(sess: &Session, attrs: &[ast::Attribute]) -> FxHashSet<Ident> {
+ let mut registered_tools = FxHashSet::default();
+ for attr in sess.filter_by_name(attrs, sym::register_tool) {
for nested_meta in attr.meta_item_list().unwrap_or_default() {
match nested_meta.ident() {
Some(ident) => {
- if let Some(old_ident) = registered.replace(ident) {
- let msg = format!("{} `{}` was already registered", descr, ident);
+ if let Some(old_ident) = registered_tools.replace(ident) {
+ let msg = format!("{} `{}` was already registered", "tool", ident);
sess.struct_span_err(ident.span, &msg)
.span_label(old_ident.span, "already registered here")
.emit();
}
}
None => {
- let msg = format!("`{}` only accepts identifiers", attr_name);
+ let msg = format!("`{}` only accepts identifiers", sym::register_tool);
let span = nested_meta.span();
sess.struct_span_err(span, &msg).span_label(span, "not an identifier").emit();
}
}
}
}
- registered
-}
-
-pub(crate) fn registered_attrs_and_tools(
- sess: &Session,
- attrs: &[ast::Attribute],
-) -> (FxHashSet<Ident>, FxHashSet<Ident>) {
- let registered_attrs = registered_idents(sess, attrs, sym::register_attr, "attribute");
- let mut registered_tools = registered_idents(sess, attrs, sym::register_tool, "tool");
// We implicitly add `rustfmt` and `clippy` to known tools,
// but it's not an error to register them explicitly.
let predefined_tools = [sym::clippy, sym::rustfmt];
registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span));
- (registered_attrs, registered_tools)
+ registered_tools
}
// Some feature gates for inner attributes are reported as lints for backward compatibility.
@@ -456,7 +441,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
}
PathResult::Indeterminate => indeterminate = true,
// We can only be sure that a path doesn't exist after having tested all the
- // posibilities, only at that time we can return false.
+ // possibilities, only at that time we can return false.
PathResult::Failed { .. } => {}
PathResult::Module(_) => panic!("unexpected path resolution"),
}
diff --git a/compiler/rustc_save_analysis/Cargo.toml b/compiler/rustc_save_analysis/Cargo.toml
index 15a89d82f..181e27f33 100644
--- a/compiler/rustc_save_analysis/Cargo.toml
+++ b/compiler/rustc_save_analysis/Cargo.toml
@@ -9,9 +9,11 @@ rustc_middle = { path = "../rustc_middle" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_lexer = { path = "../rustc_lexer" }
+rustc_macros = { path = "../rustc_macros" }
serde_json = "1"
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index e2e0e1f5b..8bd42d8d2 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -44,8 +44,6 @@ use rls_data::{
RefKind, Relation, RelationKind, SpanData,
};
-use tracing::{debug, error};
-
#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5213
macro_rules! down_cast_data {
($id:ident, $kind:ident, $sp:expr) => {
@@ -805,6 +803,7 @@ impl<'tcx> DumpVisitor<'tcx> {
&mut self,
ex: &'tcx hir::Expr<'tcx>,
seg: &'tcx hir::PathSegment<'tcx>,
+ receiver: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
) {
debug!("process_method_call {:?} {:?}", ex, ex.span);
@@ -825,6 +824,7 @@ impl<'tcx> DumpVisitor<'tcx> {
}
// walk receiver and args
+ self.visit_expr(receiver);
walk_list!(self, visit_expr, args);
}
@@ -914,7 +914,10 @@ impl<'tcx> DumpVisitor<'tcx> {
_,
)
| Res::SelfTy { .. } => {
- self.dump_path_segment_ref(id, &hir::PathSegment::from_ident(ident));
+ self.dump_path_segment_ref(
+ id,
+ &hir::PathSegment::new(ident, hir::HirId::INVALID, Res::Err),
+ );
}
def => {
error!("unexpected definition kind when processing collected idents: {:?}", def)
@@ -974,7 +977,7 @@ impl<'tcx> DumpVisitor<'tcx> {
self.process_macro_use(trait_item.span);
match trait_item.kind {
hir::TraitItemKind::Const(ref ty, body) => {
- let body = body.map(|b| &self.tcx.hir().body(b).value);
+ let body = body.map(|b| self.tcx.hir().body(b).value);
let attrs = self.tcx.hir().attrs(trait_item.hir_id());
self.process_assoc_const(
trait_item.def_id,
@@ -1303,7 +1306,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
if let hir::QPath::Resolved(_, path) = path {
self.write_sub_paths_truncated(path);
}
- intravisit::walk_qpath(self, path, t.hir_id, t.span);
+ intravisit::walk_qpath(self, path, t.hir_id);
}
hir::TyKind::Array(ref ty, ref length) => {
self.visit_ty(ty);
@@ -1318,7 +1321,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
}),
}
}
- hir::TyKind::OpaqueDef(item_id, _) => {
+ hir::TyKind::OpaqueDef(item_id, _, _) => {
let item = self.tcx.hir().item(item_id);
self.nest_typeck_results(item_id.def_id, |v| v.visit_item(item));
}
@@ -1342,7 +1345,9 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
let res = self.save_ctxt.get_path_res(hir_expr.hir_id);
self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), *rest)
}
- hir::ExprKind::MethodCall(ref seg, args, _) => self.process_method_call(ex, seg, args),
+ hir::ExprKind::MethodCall(ref seg, receiver, args, _) => {
+ self.process_method_call(ex, seg, receiver, args)
+ }
hir::ExprKind::Field(ref sub_ex, _) => {
self.visit_expr(&sub_ex);
diff --git a/compiler/rustc_save_analysis/src/errors.rs b/compiler/rustc_save_analysis/src/errors.rs
new file mode 100644
index 000000000..f0ce41d02
--- /dev/null
+++ b/compiler/rustc_save_analysis/src/errors.rs
@@ -0,0 +1,10 @@
+use rustc_macros::SessionDiagnostic;
+
+use std::path::Path;
+
+#[derive(SessionDiagnostic)]
+#[diag(save_analysis::could_not_open)]
+pub(crate) struct CouldNotOpen<'a> {
+ pub file_name: &'a Path,
+ pub err: std::io::Error,
+}
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index a1a2040bb..ce03c2a8a 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -1,13 +1,20 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(if_let_guard)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![feature(never_type)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
+#[macro_use]
+extern crate tracing;
mod dump_visitor;
mod dumper;
#[macro_use]
mod span_utils;
+mod errors;
mod sig;
use rustc_ast as ast;
@@ -45,8 +52,6 @@ use rls_data::{
RefKind, Relation, RelationKind, SpanData,
};
-use tracing::{debug, error, info};
-
pub struct SaveContext<'tcx> {
tcx: TyCtxt<'tcx>,
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
@@ -591,13 +596,14 @@ impl<'tcx> SaveContext<'tcx> {
Node::TraitRef(tr) => tr.path.res,
Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => path.res,
- Node::PathSegment(seg) => match seg.res {
- Some(res) if res != Res::Err => res,
- _ => {
+ Node::PathSegment(seg) => {
+ if seg.res != Res::Err {
+ seg.res
+ } else {
let parent_node = self.tcx.hir().get_parent_node(hir_id);
self.get_path_res(parent_node)
}
- },
+ }
Node::Expr(&hir::Expr { kind: hir::ExprKind::Struct(ref qpath, ..), .. }) => {
self.typeck_results().qpath_res(qpath, hir_id)
@@ -643,7 +649,7 @@ impl<'tcx> SaveContext<'tcx> {
}
pub fn get_path_segment_data(&self, path_seg: &hir::PathSegment<'_>) -> Option<Ref> {
- self.get_path_segment_data_with_id(path_seg, path_seg.hir_id?)
+ self.get_path_segment_data_with_id(path_seg, path_seg.hir_id)
}
pub fn get_path_segment_data_with_id(
@@ -679,6 +685,7 @@ impl<'tcx> SaveContext<'tcx> {
| HirDefKind::AssocTy
| HirDefKind::Trait
| HirDefKind::OpaqueTy
+ | HirDefKind::ImplTraitPlaceholder
| HirDefKind::TyParam,
def_id,
) => Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(def_id) }),
@@ -860,23 +867,12 @@ impl<'l> Visitor<'l> for PathCollector<'l> {
hir::PatKind::TupleStruct(ref path, ..) | hir::PatKind::Path(ref path) => {
self.collected_paths.push((p.hir_id, path));
}
- hir::PatKind::Binding(bm, _, ident, _) => {
+ hir::PatKind::Binding(hir::BindingAnnotation(_, mutbl), _, ident, _) => {
debug!(
"PathCollector, visit ident in pat {}: {:?} {:?}",
ident, p.span, ident.span
);
- let immut = match bm {
- // Even if the ref is mut, you can't change the ref, only
- // the data pointed at, so showing the initialising expression
- // is still worthwhile.
- hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Ref => {
- hir::Mutability::Not
- }
- hir::BindingAnnotation::Mutable | hir::BindingAnnotation::RefMut => {
- hir::Mutability::Mut
- }
- };
- self.collected_idents.push((p.hir_id, ident, immut));
+ self.collected_idents.push((p.hir_id, ident, mutbl));
}
_ => {}
}
@@ -928,7 +924,7 @@ impl<'a> DumpHandler<'a> {
info!("Writing output to {}", file_name.display());
let output_file = BufWriter::new(File::create(&file_name).unwrap_or_else(|e| {
- sess.fatal(&format!("Could not open {}: {}", file_name.display(), e))
+ sess.emit_fatal(errors::CouldNotOpen { file_name: file_name.as_path(), err: e })
}));
(output_file, file_name)
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index d1286c9b8..bae1828cd 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -316,7 +316,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
let text = format!("[{}; {}]", nested_ty.text, expr);
Ok(replace_text(nested_ty, text))
}
- hir::TyKind::OpaqueDef(item_id, _) => {
+ hir::TyKind::OpaqueDef(item_id, _, _) => {
let item = scx.tcx.hir().item(item_id);
item.make(offset, Some(item_id.hir_id()), scx)
}
@@ -561,7 +561,13 @@ impl<'hir> Sig for hir::Item<'hir> {
hir::ItemKind::ForeignMod { .. } => Err("extern mod"),
hir::ItemKind::GlobalAsm(_) => Err("global asm"),
hir::ItemKind::ExternCrate(_) => Err("extern crate"),
- hir::ItemKind::OpaqueTy(..) => Err("opaque type"),
+ hir::ItemKind::OpaqueTy(ref opaque) => {
+ if opaque.in_trait {
+ Err("opaque type in trait")
+ } else {
+ Err("opaque type")
+ }
+ }
// FIXME should implement this (e.g., pub use).
hir::ItemKind::Use(..) => Err("import"),
}
diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml
index dbc5c1519..3b0b3144f 100644
--- a/compiler/rustc_serialize/Cargo.toml
+++ b/compiler/rustc_serialize/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
indexmap = "1.9.1"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
[dev-dependencies]
rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_serialize/src/collection_impls.rs b/compiler/rustc_serialize/src/collection_impls.rs
index 5e53f0b10..8f8c50411 100644
--- a/compiler/rustc_serialize/src/collection_impls.rs
+++ b/compiler/rustc_serialize/src/collection_impls.rs
@@ -1,13 +1,12 @@
//! Implementations of serialization for structures found in liballoc
-use std::hash::{BuildHasher, Hash};
-
use crate::{Decodable, Decoder, Encodable, Encoder};
+use smallvec::{Array, SmallVec};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, LinkedList, VecDeque};
+use std::hash::{BuildHasher, Hash};
use std::rc::Rc;
use std::sync::Arc;
-
-use smallvec::{Array, SmallVec};
+use thin_vec::ThinVec;
impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
fn encode(&self, s: &mut S) {
@@ -23,6 +22,19 @@ impl<D: Decoder, A: Array<Item: Decodable<D>>> Decodable<D> for SmallVec<A> {
}
}
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for ThinVec<T> {
+ fn encode(&self, s: &mut S) {
+ self.as_slice().encode(s);
+ }
+}
+
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for ThinVec<T> {
+ fn decode(d: &mut D) -> ThinVec<T> {
+ let len = d.read_usize();
+ (0..len).map(|_| Decodable::decode(d)).collect()
+ }
+}
+
impl<S: Encoder, T: Encodable<S>> Encodable<S> for LinkedList<T> {
fn encode(&self, s: &mut S) {
s.emit_usize(self.len());
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index e606f4273..fa9c7bd54 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -14,10 +14,13 @@ Core encoding and decoding interfaces.
#![feature(min_specialization)]
#![feature(core_intrinsics)]
#![feature(maybe_uninit_slice)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(new_uninit)]
+#![feature(allocator_api)]
#![cfg_attr(test, feature(test))]
#![allow(rustc::internal)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 36585b8d7..751b209f1 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -4,6 +4,7 @@
Core encoding and decoding interfaces.
*/
+use std::alloc::Allocator;
use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::marker::PhantomData;
@@ -229,9 +230,9 @@ impl<D: Decoder, T> Decodable<D> for PhantomData<T> {
}
}
-impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<[T]> {
- fn decode(d: &mut D) -> Box<[T]> {
- let v: Vec<T> = Decodable::decode(d);
+impl<D: Decoder, A: Allocator + Default, T: Decodable<D>> Decodable<D> for Box<[T], A> {
+ fn decode(d: &mut D) -> Box<[T], A> {
+ let v: Vec<T, A> = Decodable::decode(d);
v.into_boxed_slice()
}
}
@@ -264,16 +265,17 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
}
}
-impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
- default fn decode(d: &mut D) -> Vec<T> {
+impl<D: Decoder, T: Decodable<D>, A: Allocator + Default> Decodable<D> for Vec<T, A> {
+ default fn decode(d: &mut D) -> Vec<T, A> {
let len = d.read_usize();
+ let allocator = A::default();
// SAFETY: we set the capacity in advance, only write elements, and
// only set the length at the end once the writing has succeeded.
- let mut vec = Vec::with_capacity(len);
+ let mut vec = Vec::with_capacity_in(len, allocator);
unsafe {
let ptr: *mut T = vec.as_mut_ptr();
for i in 0..len {
- std::ptr::write(ptr.offset(i as isize), Decodable::decode(d));
+ std::ptr::write(ptr.add(i), Decodable::decode(d));
}
vec.set_len(len);
}
@@ -457,13 +459,15 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> {
}
}
-impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
+impl<S: Encoder, T: ?Sized + Encodable<S>, A: Allocator + Default> Encodable<S> for Box<T, A> {
fn encode(&self, s: &mut S) {
- (**self).encode(s);
+ (**self).encode(s)
}
}
-impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<T> {
- fn decode(d: &mut D) -> Box<T> {
- Box::new(Decodable::decode(d))
+
+impl<D: Decoder, A: Allocator + Default, T: Decodable<D>> Decodable<D> for Box<T, A> {
+ fn decode(d: &mut D) -> Box<T, A> {
+ let allocator = A::default();
+ Box::new_in(Decodable::decode(d), allocator)
}
}
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index 37cfc4a0d..6b1eaa4d3 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -15,6 +15,5 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_span = { path = "../rustc_span" }
rustc_fs_util = { path = "../rustc_fs_util" }
-num_cpus = "1.0"
rustc_ast = { path = "../rustc_ast" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
diff --git a/compiler/rustc_session/src/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs
index dd64e8ab7..2336d9936 100644
--- a/compiler/rustc_session/src/cgu_reuse_tracker.rs
+++ b/compiler/rustc_session/src/cgu_reuse_tracker.rs
@@ -2,10 +2,14 @@
//! compilation. This is used for incremental compilation tests and debug
//! output.
+use crate::errors::{CguNotRecorded, IncorrectCguReuseType};
+use crate::Session;
use rustc_data_structures::fx::FxHashMap;
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_span::{Span, Symbol};
+use std::borrow::Cow;
+use std::fmt::{self};
use std::sync::{Arc, Mutex};
-use tracing::debug;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub enum CguReuse {
@@ -14,6 +18,22 @@ pub enum CguReuse {
PostLto,
}
+impl fmt::Display for CguReuse {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match *self {
+ CguReuse::No => write!(f, "No"),
+ CguReuse::PreLto => write!(f, "PreLto "),
+ CguReuse::PostLto => write!(f, "PostLto "),
+ }
+ }
+}
+
+impl IntoDiagnosticArg for CguReuse {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
+ }
+}
+
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ComparisonKind {
Exact,
@@ -84,7 +104,7 @@ impl CguReuseTracker {
}
}
- pub fn check_expected_reuse(&self, diag: &rustc_errors::Handler) {
+ pub fn check_expected_reuse(&self, sess: &Session) {
if let Some(ref data) = self.data {
let data = data.lock().unwrap();
@@ -98,19 +118,17 @@ impl CguReuseTracker {
};
if error {
- let at_least = if at_least { "at least " } else { "" };
- let msg = format!(
- "CGU-reuse for `{cgu_user_name}` is `{actual_reuse:?}` but \
- should be {at_least}`{expected_reuse:?}`"
- );
- diag.span_err(error_span.0, &msg);
+ let at_least = if at_least { 1 } else { 0 };
+ IncorrectCguReuseType {
+ span: error_span.0,
+ cgu_user_name: &cgu_user_name,
+ actual_reuse,
+ expected_reuse,
+ at_least,
+ };
}
} else {
- let msg = format!(
- "CGU-reuse for `{cgu_user_name}` (mangled: `{cgu_name}`) was \
- not recorded"
- );
- diag.span_fatal(error_span.0, &msg)
+ sess.emit_fatal(CguNotRecorded { cgu_user_name, cgu_name });
}
}
}
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 6a8298605..8bb3878fb 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -12,8 +12,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::ToStableHashKey;
use rustc_target::abi::{Align, TargetDataLayout};
-use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings};
-use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS};
+use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo};
+use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
use crate::parse::{CrateCheckConfig, CrateConfig};
use rustc_feature::UnstableFeatures;
@@ -36,6 +36,8 @@ use std::iter::{self, FromIterator};
use std::path::{Path, PathBuf};
use std::str::{self, FromStr};
+pub mod sigpipe;
+
/// The different settings that the `-C strip` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum Strip {
@@ -798,7 +800,15 @@ impl UnstableOptions {
// The type of entry function, so users can have their own entry functions
#[derive(Copy, Clone, PartialEq, Hash, Debug, HashStable_Generic)]
pub enum EntryFnType {
- Main,
+ Main {
+ /// Specifies what to do with `SIGPIPE` before calling `fn main()`.
+ ///
+ /// What values that are valid and what they mean must be in sync
+ /// across rustc and libstd, but we don't want it public in libstd,
+ /// so we take a bit of an unusual approach with simple constants
+ /// and an `include!()`.
+ sigpipe: u8,
+ },
Start,
}
@@ -888,10 +898,10 @@ fn default_configuration(sess: &Session) -> CrateConfig {
let max_atomic_width = sess.target.max_atomic_width();
let atomic_cas = sess.target.atomic_cas;
let layout = TargetDataLayout::parse(&sess.target).unwrap_or_else(|err| {
- sess.fatal(&err);
+ sess.emit_fatal(err);
});
- let mut ret = FxHashSet::default();
+ let mut ret = CrateConfig::default();
ret.reserve(7); // the minimum number of insertions
// Target bindings.
ret.insert((sym::target_os, Some(Symbol::intern(os))));
@@ -949,7 +959,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
ret.insert((sym::debug_assertions, None));
}
// JUSTIFICATION: before wrapper fn is available
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
ret.insert((sym::proc_macro, None));
}
@@ -2198,7 +2208,7 @@ fn parse_remap_path_prefix(
}
// JUSTIFICATION: before wrapper fn is available
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn build_session_options(matches: &getopts::Matches) -> Options {
let color = parse_color(matches);
@@ -2379,16 +2389,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
}
- if cg.linker_flavor == Some(LinkerFlavor::L4Bender)
- && !nightly_options::is_unstable_enabled(matches)
- {
- early_error(
- error_format,
- "`l4-bender` linker flavor is unstable, `-Z unstable-options` \
- flag must also be passed to explicitly use it",
- );
- }
-
let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format);
let cg = cg;
@@ -2423,13 +2423,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let pretty = parse_pretty(&unstable_opts, error_format);
- if !unstable_opts.unstable_options
- && !target_triple.triple().contains("apple")
- && cg.split_debuginfo.is_some()
- {
- early_error(error_format, "`-Csplit-debuginfo` is unstable on this platform");
- }
-
// Try to find a directory containing the Rust `src`, for more details see
// the doc comment on the `real_rust_source_base_dir` field.
let tmp_buf;
@@ -2537,7 +2530,7 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
),
),
};
- tracing::debug!("got unpretty option: {first:?}");
+ debug!("got unpretty option: {first:?}");
Some(first)
}
diff --git a/compiler/rustc_session/src/config/sigpipe.rs b/compiler/rustc_session/src/config/sigpipe.rs
new file mode 100644
index 000000000..a5c94118a
--- /dev/null
+++ b/compiler/rustc_session/src/config/sigpipe.rs
@@ -0,0 +1,22 @@
+//! NOTE: Keep these constants in sync with `library/std/src/sys/unix/mod.rs`!
+
+/// Do not touch `SIGPIPE`. Use whatever the parent process uses.
+#[allow(dead_code)]
+pub const INHERIT: u8 = 1;
+
+/// Change `SIGPIPE` to `SIG_IGN` so that failed writes results in `EPIPE`
+/// that are eventually converted to `ErrorKind::BrokenPipe`.
+#[allow(dead_code)]
+pub const SIG_IGN: u8 = 2;
+
+/// Change `SIGPIPE` to `SIG_DFL` so that the process is killed when trying
+/// to write to a closed pipe. This is usually the desired behavior for CLI
+/// apps that produce textual output that you want to pipe to other programs
+/// such as `head -n 1`.
+#[allow(dead_code)]
+pub const SIG_DFL: u8 = 3;
+
+/// `SIG_IGN` has been the Rust default since 2014. See
+/// <https://github.com/rust-lang/rust/issues/62569>.
+#[allow(dead_code)]
+pub const DEFAULT: u8 = SIG_IGN;
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index c1fd3c7c6..7d4a1e212 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -68,6 +68,8 @@ pub enum LinkagePreference {
pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Option<Symbol>,
+ /// If packed_bundled_libs enabled, actual filename of library is stored.
+ pub filename: Option<Symbol>,
pub cfg: Option<ast::MetaItem>,
pub foreign_module: Option<DefId>,
pub wasm_import_module: Option<Symbol>,
@@ -81,10 +83,29 @@ impl NativeLib {
}
}
+/// Different ways that the PE Format can decorate a symbol name.
+/// From <https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type>
+#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, PartialEq, Eq)]
+pub enum PeImportNameType {
+ /// IMPORT_ORDINAL
+ /// Uses the ordinal (i.e., a number) rather than the name.
+ Ordinal(u16),
+ /// Same as IMPORT_NAME
+ /// Name is decorated with all prefixes and suffixes.
+ Decorated,
+ /// Same as IMPORT_NAME_NOPREFIX
+ /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept.
+ NoPrefix,
+ /// Same as IMPORT_NAME_UNDECORATE
+ /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all
+ /// trailing characters) are skipped.
+ Undecorated,
+}
+
#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
pub struct DllImport {
pub name: Symbol,
- pub ordinal: Option<u16>,
+ pub import_name_type: Option<PeImportNameType>,
/// Calling convention for the function.
///
/// On x86_64, this is always `DllCallingConvention::C`; on i686, it can be any
@@ -92,6 +113,18 @@ pub struct DllImport {
pub calling_convention: DllCallingConvention,
/// Span of import's "extern" declaration; used for diagnostics.
pub span: Span,
+ /// Is this for a function (rather than a static variable).
+ pub is_fn: bool,
+}
+
+impl DllImport {
+ pub fn ordinal(&self) -> Option<u16> {
+ if let Some(PeImportNameType::Ordinal(ordinal)) = self.import_name_type {
+ Some(ordinal)
+ } else {
+ None
+ }
+ }
}
/// Calling convention for a function defined in an external library.
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
new file mode 100644
index 000000000..c6596ff24
--- /dev/null
+++ b/compiler/rustc_session/src/errors.rs
@@ -0,0 +1,221 @@
+use std::num::NonZeroU32;
+
+use crate::cgu_reuse_tracker::CguReuse;
+use crate::{self as rustc_session, SessionDiagnostic};
+use rustc_errors::{fluent, DiagnosticBuilder, ErrorGuaranteed, Handler, MultiSpan};
+use rustc_macros::SessionDiagnostic;
+use rustc_span::{Span, Symbol};
+use rustc_target::abi::TargetDataLayoutErrors;
+use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
+
+#[derive(SessionDiagnostic)]
+#[diag(session::incorrect_cgu_reuse_type)]
+pub struct IncorrectCguReuseType<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub cgu_user_name: &'a str,
+ pub actual_reuse: CguReuse,
+ pub expected_reuse: CguReuse,
+ pub at_least: u8,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::cgu_not_recorded)]
+pub struct CguNotRecorded<'a> {
+ pub cgu_user_name: &'a str,
+ pub cgu_name: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::feature_gate_error, code = "E0658")]
+pub struct FeatureGateError<'a> {
+ #[primary_span]
+ pub span: MultiSpan,
+ pub explain: &'a str,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[note(session::feature_diagnostic_for_issue)]
+pub struct FeatureDiagnosticForIssue {
+ pub n: NonZeroU32,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[help(session::feature_diagnostic_help)]
+pub struct FeatureDiagnosticHelp {
+ pub feature: Symbol,
+}
+
+impl SessionDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
+ fn into_diagnostic(self, sess: &Handler) -> DiagnosticBuilder<'_, !> {
+ let mut diag;
+ match self {
+ TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
+ diag = sess.struct_fatal(fluent::session::target_invalid_address_space);
+ diag.set_arg("addr_space", addr_space);
+ diag.set_arg("cause", cause);
+ diag.set_arg("err", err);
+ diag
+ }
+ TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
+ diag = sess.struct_fatal(fluent::session::target_invalid_bits);
+ diag.set_arg("kind", kind);
+ diag.set_arg("bit", bit);
+ diag.set_arg("cause", cause);
+ diag.set_arg("err", err);
+ diag
+ }
+ TargetDataLayoutErrors::MissingAlignment { cause } => {
+ diag = sess.struct_fatal(fluent::session::target_missing_alignment);
+ diag.set_arg("cause", cause);
+ diag
+ }
+ TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
+ diag = sess.struct_fatal(fluent::session::target_invalid_alignment);
+ diag.set_arg("cause", cause);
+ diag.set_arg("err", err);
+ diag
+ }
+ TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
+ diag = sess.struct_fatal(fluent::session::target_inconsistent_architecture);
+ diag.set_arg("dl", dl);
+ diag.set_arg("target", target);
+ diag
+ }
+ TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
+ diag = sess.struct_fatal(fluent::session::target_inconsistent_pointer_width);
+ diag.set_arg("pointer_size", pointer_size);
+ diag.set_arg("target", target);
+ diag
+ }
+ TargetDataLayoutErrors::InvalidBitsSize { err } => {
+ diag = sess.struct_fatal(fluent::session::target_invalid_bits_size);
+ diag.set_arg("err", err);
+ diag
+ }
+ }
+ }
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::not_circumvent_feature)]
+pub struct NotCircumventFeature;
+
+#[derive(SessionDiagnostic)]
+#[diag(session::linker_plugin_lto_windows_not_supported)]
+pub struct LinkerPluginToWindowsNotSupported;
+
+#[derive(SessionDiagnostic)]
+#[diag(session::profile_use_file_does_not_exist)]
+pub struct ProfileUseFileDoesNotExist<'a> {
+ pub path: &'a std::path::Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::profile_sample_use_file_does_not_exist)]
+pub struct ProfileSampleUseFileDoesNotExist<'a> {
+ pub path: &'a std::path::Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::target_requires_unwind_tables)]
+pub struct TargetRequiresUnwindTables;
+
+#[derive(SessionDiagnostic)]
+#[diag(session::sanitizer_not_supported)]
+pub struct SanitizerNotSupported {
+ pub us: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::sanitizers_not_supported)]
+pub struct SanitizersNotSupported {
+ pub us: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::cannot_mix_and_match_sanitizers)]
+pub struct CannotMixAndMatchSanitizers {
+ pub first: String,
+ pub second: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::cannot_enable_crt_static_linux)]
+pub struct CannotEnableCrtStaticLinux;
+
+#[derive(SessionDiagnostic)]
+#[diag(session::sanitizer_cfi_enabled)]
+pub struct SanitizerCfiEnabled;
+
+#[derive(SessionDiagnostic)]
+#[diag(session::unstable_virtual_function_elimination)]
+pub struct UnstableVirtualFunctionElimination;
+
+#[derive(SessionDiagnostic)]
+#[diag(session::unsupported_dwarf_version)]
+pub struct UnsupportedDwarfVersion {
+ pub dwarf_version: u32,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::target_stack_protector_not_supported)]
+pub struct StackProtectorNotSupportedForTarget<'a> {
+ pub stack_protector: StackProtector,
+ pub target_triple: &'a TargetTriple,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::split_debuginfo_unstable_platform)]
+pub struct SplitDebugInfoUnstablePlatform {
+ pub debuginfo: SplitDebuginfo,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::file_is_not_writeable)]
+pub struct FileIsNotWriteable<'a> {
+ pub file: &'a std::path::Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::crate_name_does_not_match)]
+pub struct CrateNameDoesNotMatch<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub s: &'a str,
+ pub name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::crate_name_invalid)]
+pub struct CrateNameInvalid<'a> {
+ pub s: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(session::crate_name_empty)]
+pub struct CrateNameEmpty {
+ #[primary_span]
+ pub span: Option<Span>,
+}
+
+pub struct InvalidCharacterInCrateName<'a> {
+ pub span: Option<Span>,
+ pub character: char,
+ pub crate_name: &'a str,
+}
+
+impl crate::SessionDiagnostic<'_> for InvalidCharacterInCrateName<'_> {
+ fn into_diagnostic(
+ self,
+ sess: &Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = sess.struct_err(fluent::session::invalid_character_in_create_name);
+ if let Some(sp) = self.span {
+ diag.set_span(sp);
+ }
+ diag.set_arg("character", self.character);
+ diag.set_arg("crate_name", self.crate_name);
+ diag
+ }
+}
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index c973e3140..e8edb38f5 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -7,7 +7,6 @@ use std::path::{Path, PathBuf};
use crate::search_paths::{PathKind, SearchPath};
use rustc_fs_util::fix_windows_verbatim_for_gcc;
-use tracing::debug;
#[derive(Copy, Clone)]
pub enum FileMatch {
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 7353c1ca0..f6bab775e 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,6 +1,6 @@
#![feature(if_let_guard)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(once_cell)]
@@ -9,9 +9,15 @@
#![feature(map_many_mut)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
+pub mod errors;
+
+#[macro_use]
+extern crate tracing;
pub mod cgu_reuse_tracker;
pub mod utils;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 1827f1c20..d7f1bc0be 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -5,7 +5,7 @@ use crate::lint;
use crate::search_paths::SearchPath;
use crate::utils::NativeLib;
use rustc_errors::LanguageIdentifier;
-use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet};
+use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
use rustc_target::spec::{
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
};
@@ -127,11 +127,11 @@ top_level_options!(
/// `CodegenOptions`, think about how it influences incremental compilation. If in
/// doubt, specify `[TRACKED]`, which is always "correct" but might lead to
/// unnecessary re-compilation.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_ty)]
+ #[rustc_lint_opt_ty]
pub struct Options {
/// The crate config requested for the session, which may be combined
/// with additional crate configurations during the compile process.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field")]
crate_types: Vec<CrateType> [TRACKED],
optimize: OptLevel [TRACKED],
/// Include the `debug_assertions` flag in dependency tracking, since it
@@ -178,9 +178,9 @@ top_level_options!(
/// what rustc was invoked with, but massaged a bit to agree with
/// commands like `--emit llvm-ir` which they're often incompatible with
/// if we otherwise use the defaults of rustc.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field")]
cli_forced_codegen_units: Option<usize> [UNTRACKED],
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
cli_forced_thinlto_off: bool [UNTRACKED],
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
@@ -231,7 +231,7 @@ macro_rules! options {
),* ,) =>
(
#[derive(Clone)]
- #[cfg_attr(not(bootstrap), rustc_lint_opt_ty)]
+ #[rustc_lint_opt_ty]
pub struct $struct_name { $( $( #[$attr] )* pub $opt: $t),* }
impl Default for $struct_name {
@@ -282,7 +282,7 @@ macro_rules! options {
impl Options {
// JUSTIFICATION: defn of the suggested wrapper fn
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
pub fn time_passes(&self) -> bool {
self.unstable_opts.time_passes || self.unstable_opts.time
}
@@ -290,7 +290,7 @@ impl Options {
impl CodegenOptions {
// JUSTIFICATION: defn of the suggested wrapper fn
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
pub fn instrument_coverage(&self) -> InstrumentCoverage {
self.instrument_coverage.unwrap_or(InstrumentCoverage::Off)
}
@@ -382,7 +382,7 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
- pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
+ pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
pub const parse_instrument_coverage: &str =
@@ -582,7 +582,7 @@ mod parse {
pub(crate) fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool {
match v.and_then(|s| s.parse().ok()) {
Some(0) => {
- *slot = ::num_cpus::get();
+ *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get);
true
}
Some(i) => {
@@ -763,8 +763,8 @@ mod parse {
true
}
- pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
- match v.and_then(LinkerFlavor::from_str) {
+ pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
+ match v.and_then(LinkerFlavorCli::from_str) {
Some(lf) => *slot = Some(lf),
_ => return false,
}
@@ -1091,7 +1091,7 @@ options! {
ar: String = (String::new(), parse_string, [UNTRACKED],
"this option is deprecated and does nothing"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field")]
code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED],
"choose the code model to use (`rustc --print code-models` for details)"),
codegen_units: Option<usize> = (None, parse_opt_number, [UNTRACKED],
@@ -1111,14 +1111,14 @@ options! {
"extra data to put in each output filename"),
force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
"force use of the frame pointers"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
"force use of unwind tables"),
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
"enable incremental compilation"),
inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED],
"set the threshold for inlining a function"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage \
reports (note, the compiler build config must include `profiler = true`); \
@@ -1131,7 +1131,7 @@ options! {
"a single extra argument to append to the linker invocation (can be used several times)"),
link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
"extra arguments to append to the linker invocation (space separated)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field")]
link_dead_code: Option<bool> = (None, parse_opt_bool, [TRACKED],
"keep dead code at link time (useful for code coverage) (default: no)"),
link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
@@ -1139,14 +1139,14 @@ options! {
on C toolchain installed in the system"),
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
"system linker to link outputs with"),
- linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
+ linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
"linker flavor"),
linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
parse_linker_plugin_lto, [TRACKED],
"generate build artifacts that are compatible with linker-based LTO"),
llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
"a list of arguments to pass to LLVM (space separated)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED],
"perform LLVM link-time optimizations"),
metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
@@ -1163,10 +1163,10 @@ options! {
"disable LLVM's SLP vectorization pass"),
opt_level: String = ("0".to_string(), parse_string, [TRACKED],
"optimization level (0-3, s, or z; default: 0)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::overflow_checks` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::overflow_checks` instead of this field")]
overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use overflow checks for integer arithmetic"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::panic_strategy` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::panic_strategy` instead of this field")]
panic: Option<PanicStrategy> = (None, parse_opt_panic_strategy, [TRACKED],
"panic strategy to compile crate with"),
passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
@@ -1178,7 +1178,7 @@ options! {
"compile the program with profiling instrumentation"),
profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"use the given `.profdata` file for profile-guided optimization"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::relocation_model` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::relocation_model` instead of this field")]
relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED],
"control generation of position-independent code (PIC) \
(`rustc --print relocation-models` for details)"),
@@ -1190,7 +1190,7 @@ options! {
"save all temporary output files during compilation (default: no)"),
soft_float: bool = (false, parse_bool, [TRACKED],
"use soft float ABI (*eabihf targets only) (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")]
split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED],
"how to handle split-debuginfo, a platform-specific option"),
strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
@@ -1226,13 +1226,13 @@ options! {
"encode MIR of all functions into the crate metadata (default: no)"),
assume_incomplete_release: bool = (false, parse_bool, [TRACKED],
"make cfg(version) treat the current version as incomplete (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field")]
asm_comments: bool = (false, parse_bool, [TRACKED],
"generate comments into the assembly (may change behavior) (default: no)"),
assert_incr_state: Option<String> = (None, parse_opt_string, [UNTRACKED],
"assert that the incremental cache is in given state: \
either `loaded` or `not-loaded`."),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")]
binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
"include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
(default: no)"),
@@ -1310,7 +1310,9 @@ options! {
"emit the bc module with thin LTO info (default: yes)"),
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
"export symbols from executables, as if they were dynamic libraries"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field"))]
+ extra_const_ub_checks: bool = (false, parse_bool, [TRACKED],
+ "turns on more checks to detect const UB, which can be slow (default: no)"),
+ #[rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field")]
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
(default: no)"),
@@ -1343,6 +1345,8 @@ options! {
"hash spans relative to their parent item for incr. comp. (default: no)"),
incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
"verify incr. comp. hashes of green query instances (default: no)"),
+ inline_llvm: bool = (true, parse_bool, [TRACKED],
+ "enable LLVM inlining (default: yes)"),
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable MIR inlining (default: no)"),
inline_mir_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
@@ -1353,7 +1357,7 @@ options! {
"control whether `#[inline]` functions are in all CGUs"),
input_stats: bool = (false, parse_bool, [UNTRACKED],
"gather statistics about the input (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage \
reports (note, the compiler build config must include `profiler = true`); \
@@ -1362,7 +1366,7 @@ options! {
`=except-unused-generics`
`=except-unused-functions`
`=off` (default)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field")]
instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
@@ -1386,7 +1390,7 @@ options! {
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
"control the operation of the MergeFunctions LLVM pass, taking \
the same values as the target option of the same name"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field")]
meta_stats: bool = (false, parse_bool, [UNTRACKED],
"gather metadata statistics (default: no)"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
@@ -1398,7 +1402,7 @@ options! {
disabled by other flags as usual."),
mir_pretty_relative_line_numbers: bool = (false, parse_bool, [UNTRACKED],
"use line numbers relative to the function in mir pretty printing"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")]
mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
@@ -1437,6 +1441,8 @@ options! {
"pass `-install_name @rpath/...` to the macOS linker (default: no)"),
diagnostic_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
"set the current output width for diagnostic truncation"),
+ packed_bundled_libs: bool = (false, parse_bool, [TRACKED],
+ "change rlib format to store native libraries as archives"),
panic_abort_tests: bool = (false, parse_bool, [TRACKED],
"support compiling tests with panic=abort (default: no)"),
panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
@@ -1465,7 +1471,7 @@ options! {
See #77382 and #74551."),
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
"make rustc print the total optimization fuel used by a crate"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field")]
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
"print the LLVM optimization passes being run (default: no)"),
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1543,7 +1549,7 @@ options! {
"exclude spans when debug-printing compiler state (default: no)"),
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
"hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")]
stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED],
"control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"),
strict_init_checks: bool = (false, parse_bool, [TRACKED],
@@ -1564,7 +1570,7 @@ options! {
symbol_mangling_version: Option<SymbolManglingVersion> = (None,
parse_symbol_mangling_version, [TRACKED],
"which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field")]
teach: bool = (false, parse_bool, [TRACKED],
"show extended diagnostic help (default: no)"),
temps_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1580,7 +1586,7 @@ options! {
"emit directionality isolation markers in translated diagnostics"),
tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
"select processor to schedule for (`rustc --print target-cpus` for details)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable ThinLTO when possible"),
thir_unsafeck: bool = (false, parse_bool, [TRACKED],
@@ -1589,19 +1595,19 @@ options! {
/// a sequential compiler for now. This'll likely be adjusted
/// in the future. Note that -Zthreads=0 is the way to get
/// the num_cpus behavior.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field")]
threads: usize = (1, parse_threads, [UNTRACKED],
"use a thread pool with N threads"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
time: bool = (false, parse_bool, [UNTRACKED],
"measure time of rustc processes (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field")]
time_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each LLVM pass (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
time_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each rustc pass (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field")]
tls_model: Option<TlsModel> = (None, parse_tls_model, [TRACKED],
"choose the TLS model to use (`rustc --print tls-models` for details)"),
trace_macros: bool = (false, parse_bool, [UNTRACKED],
@@ -1636,17 +1642,17 @@ options! {
"enable unsound and buggy MIR optimizations (default: no)"),
/// This name is kind of confusing: Most unstable options enable something themselves, while
/// this just allows "normal" options to be feature-gated.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")]
unstable_options: bool = (false, parse_bool, [UNTRACKED],
"adds unstable command line options to rustc interface (default: no)"),
use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use legacy .ctors section for initializers rather than .init_array"),
validate_mir: bool = (false, parse_bool, [UNTRACKED],
"validate MIR after each transformation"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::verbose` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::verbose` instead of this field")]
verbose: bool = (false, parse_bool, [UNTRACKED],
"in general, enable more debug printouts (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field")]
verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
"verify LLVM IR (default: no)"),
virtual_function_elimination: bool = (false, parse_bool, [TRACKED],
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index e5e6579d7..2511bee46 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -1,5 +1,9 @@
//! Related to out filenames of compilation (e.g. save analysis, binaries).
use crate::config::{CrateType, Input, OutputFilenames, OutputType};
+use crate::errors::{
+ CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable,
+ InvalidCharacterInCrateName,
+};
use crate::Session;
use rustc_ast as ast;
use rustc_span::symbol::sym;
@@ -30,11 +34,7 @@ pub fn out_filename(
/// read-only file. We should be consistent.
pub fn check_file_is_writeable(file: &Path, sess: &Session) {
if !is_writeable(file) {
- sess.fatal(&format!(
- "output file {} is not writeable -- check its \
- permissions",
- file.display()
- ));
+ sess.emit_fatal(FileIsNotWriteable { file });
}
}
@@ -61,11 +61,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input)
if let Some(ref s) = sess.opts.crate_name {
if let Some((attr, name)) = attr_crate_name {
if name.as_str() != s {
- let msg = format!(
- "`--crate-name` and `#[crate_name]` are \
- required to match, but `{s}` != `{name}`"
- );
- sess.span_err(attr.span, &msg);
+ sess.emit_err(CrateNameDoesNotMatch { span: attr.span, s, name });
}
}
return validate(s.clone(), None);
@@ -77,11 +73,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input)
if let Input::File(ref path) = *input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with('-') {
- let msg = format!(
- "crate names cannot start with a `-`, but \
- `{s}` has a leading hyphen"
- );
- sess.err(&msg);
+ sess.emit_err(CrateNameInvalid { s });
} else {
return validate(s.replace('-', "_"), None);
}
@@ -94,15 +86,9 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input)
pub fn validate_crate_name(sess: &Session, s: &str, sp: Option<Span>) {
let mut err_count = 0;
{
- let mut say = |s: &str| {
- match sp {
- Some(sp) => sess.span_err(sp, s),
- None => sess.err(s),
- };
- err_count += 1;
- };
if s.is_empty() {
- say("crate name must not be empty");
+ err_count += 1;
+ sess.emit_err(CrateNameEmpty { span: sp });
}
for c in s.chars() {
if c.is_alphanumeric() {
@@ -111,7 +97,8 @@ pub fn validate_crate_name(sess: &Session, s: &str, sp: Option<Span>) {
if c == '_' {
continue;
}
- say(&format!("invalid character `{c}` in crate name: `{s}`"));
+ err_count += 1;
+ sess.emit_err(InvalidCharacterInCrateName { span: sp, character: c, crate_name: s });
}
}
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index f31d52147..0389b2a06 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -2,15 +2,18 @@
//! It also serves as an input to the parser itself.
use crate::config::CheckCfg;
-use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
+use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError};
+use crate::lint::{
+ builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
+};
use crate::SessionDiagnostic;
use rustc_ast::node_id::NodeId;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
use rustc_errors::{
- error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder,
- DiagnosticMessage, ErrorGuaranteed, MultiSpan,
+ fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
+ DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, MultiSpan, StashKey,
};
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
use rustc_span::edition::Edition;
@@ -18,11 +21,12 @@ use rustc_span::hygiene::ExpnId;
use rustc_span::source_map::{FilePathMapping, SourceMap};
use rustc_span::{Span, Symbol};
+use rustc_ast::attr::AttrIdGenerator;
use std::str;
/// The set of keys (and, optionally, values) that define the compilation
/// environment of the crate, used to drive conditional compilation.
-pub type CrateConfig = FxHashSet<(Symbol, Option<Symbol>)>;
+pub type CrateConfig = FxIndexSet<(Symbol, Option<Symbol>)>;
pub type CrateCheckConfig = CheckCfg<Symbol>;
/// Collected spans during parsing for places where a certain feature was
@@ -101,11 +105,60 @@ pub fn feature_err_issue<'a>(
issue: GateIssue,
explain: &str,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658));
+ let span = span.into();
+
+ // Cancel an earlier warning for this same error, if it exists.
+ if let Some(span) = span.primary_span() {
+ sess.span_diagnostic
+ .steal_diagnostic(span, StashKey::EarlySyntaxWarning)
+ .map(|err| err.cancel());
+ }
+
+ let mut err = sess.create_err(FeatureGateError { span, explain });
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
err
}
+/// Construct a future incompatibility diagnostic for a feature gate.
+///
+/// This diagnostic is only a warning and *does not cause compilation to fail*.
+pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explain: &str) {
+ feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
+}
+
+/// Construct a future incompatibility diagnostic for a feature gate.
+///
+/// This diagnostic is only a warning and *does not cause compilation to fail*.
+///
+/// This variant allows you to control whether it is a library or language feature.
+/// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`.
+#[allow(rustc::diagnostic_outside_of_impl)]
+#[allow(rustc::untranslatable_diagnostic)]
+pub fn feature_warn_issue<'a>(
+ sess: &'a ParseSess,
+ feature: Symbol,
+ span: Span,
+ issue: GateIssue,
+ explain: &str,
+) {
+ let mut err = sess.span_diagnostic.struct_span_warn(span, explain);
+ add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
+
+ // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
+ let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
+ let future_incompatible = lint.future_incompatible.as_ref().unwrap();
+ err.code(DiagnosticId::Lint {
+ name: lint.name_lower(),
+ has_future_breakage: false,
+ is_force_warn: false,
+ });
+ err.warn(lint.desc);
+ err.note(format!("for more information, see {}", future_incompatible.reference));
+
+ // A later feature_err call can steal and cancel this warning.
+ err.stash(span, StashKey::EarlySyntaxWarning);
+}
+
/// Adds the diagnostics for a feature to an existing error.
pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, feature: Symbol) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);
@@ -123,14 +176,12 @@ pub fn add_feature_diagnostics_for_issue<'a>(
issue: GateIssue,
) {
if let Some(n) = find_feature_issue(feature, issue) {
- err.note(&format!(
- "see issue #{n} <https://github.com/rust-lang/rust/issues/{n}> for more information"
- ));
+ err.subdiagnostic(FeatureDiagnosticForIssue { n });
}
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
- err.help(&format!("add `#![feature({feature})]` to the crate attributes to enable"));
+ err.subdiagnostic(FeatureDiagnosticHelp { feature });
}
}
@@ -169,6 +220,8 @@ pub struct ParseSess {
/// Spans passed to `proc_macro::quote_span`. Each span has a numerical
/// identifier represented by its position in the vector.
pub proc_macro_quoted_spans: Lock<Vec<Span>>,
+ /// Used to generate new `AttrId`s. Every `AttrId` is unique.
+ pub attr_id_generator: AttrIdGenerator,
}
impl ParseSess {
@@ -191,7 +244,7 @@ impl ParseSess {
Self {
span_diagnostic: handler,
unstable_features: UnstableFeatures::from_environment(None),
- config: FxHashSet::default(),
+ config: FxIndexSet::default(),
check_config: CrateCheckConfig::default(),
edition: ExpnId::root().expn_data().edition,
raw_identifier_spans: Lock::new(Vec::new()),
@@ -207,6 +260,7 @@ impl ParseSess {
type_ascription_path_suggestions: Default::default(),
assume_incomplete_release: false,
proc_macro_quoted_spans: Default::default(),
+ attr_id_generator: AttrIdGenerator::new(),
}
}
@@ -293,7 +347,7 @@ impl ParseSess {
&'a self,
err: impl SessionDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- err.into_diagnostic(self)
+ err.into_diagnostic(&self.span_diagnostic)
}
pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed {
@@ -304,14 +358,27 @@ impl ParseSess {
&'a self,
warning: impl SessionDiagnostic<'a, ()>,
) -> DiagnosticBuilder<'a, ()> {
- warning.into_diagnostic(self)
+ warning.into_diagnostic(&self.span_diagnostic)
}
pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
self.create_warning(warning).emit()
}
+ pub fn create_fatal<'a>(
+ &'a self,
+ fatal: impl SessionDiagnostic<'a, !>,
+ ) -> DiagnosticBuilder<'a, !> {
+ fatal.into_diagnostic(&self.span_diagnostic)
+ }
+
+ pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
+ self.create_fatal(fatal).emit()
+ }
+
#[rustc_lint_diagnostics]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ #[allow(rustc::untranslatable_diagnostic)]
pub fn struct_err(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -320,7 +387,26 @@ impl ParseSess {
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ #[allow(rustc::untranslatable_diagnostic)]
pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.span_diagnostic.struct_warn(msg)
}
+
+ #[rustc_lint_diagnostics]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ #[allow(rustc::untranslatable_diagnostic)]
+ pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
+ self.span_diagnostic.struct_fatal(msg)
+ }
+
+ #[rustc_lint_diagnostics]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ #[allow(rustc::untranslatable_diagnostic)]
+ pub fn struct_diagnostic<G: EmissionGuarantee>(
+ &self,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> DiagnosticBuilder<'_, G> {
+ self.span_diagnostic.struct_diagnostic(msg)
+ }
}
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 9669287b3..a001f87db 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -2,6 +2,13 @@ use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
+use crate::errors::{
+ CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
+ NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
+ SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
+ SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
+ TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
+};
use crate::parse::{add_feature_diagnostics, ParseSess};
use crate::search_paths::{PathKind, SearchPath};
use crate::{filesearch, lint};
@@ -20,8 +27,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
use rustc_errors::json::JsonEmitter;
use rustc_errors::registry::Registry;
use rustc_errors::{
- fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee,
- ErrorGuaranteed, FluentBundle, LazyFallbackBundle, MultiSpan,
+ error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
+ EmissionGuarantee, ErrorGuaranteed, FluentBundle, Handler, LazyFallbackBundle, MultiSpan,
};
use rustc_macros::HashStable_Generic;
pub use rustc_span::def_id::StableCrateId;
@@ -31,7 +38,7 @@ use rustc_span::{sym, SourceFileHashAlgorithm, Symbol};
use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
use rustc_target::spec::{
- SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
+ DebuginfoKind, SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
};
use std::cell::{self, RefCell};
@@ -110,6 +117,12 @@ impl Mul<usize> for Limit {
}
}
+impl rustc_errors::IntoDiagnosticArg for Limit {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub struct Limits {
/// The maximum recursion limit for potentially infinitely recursive
@@ -214,9 +227,9 @@ pub struct PerfStats {
/// `#[derive(SessionDiagnostic)]` -- see [rustc_macros::SessionDiagnostic].
#[rustc_diagnostic_item = "SessionDiagnostic"]
pub trait SessionDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> {
- /// Write out as a diagnostic out of `sess`.
+ /// Write out as a diagnostic out of `Handler`.
#[must_use]
- fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, T>;
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>;
}
impl Session {
@@ -229,6 +242,9 @@ impl Session {
if !unleashed_features.is_empty() {
let mut must_err = false;
// Create a diagnostic pointing at where things got unleashed.
+ // FIXME(#100717): needs eager translation/lists
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
let mut diag = self.struct_warn("skipping const checks");
for &(span, feature_gate) in unleashed_features.iter() {
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
@@ -244,10 +260,7 @@ impl Session {
// If we should err, make sure we did.
if must_err && self.has_errors().is_none() {
// We have skipped a feature gate, and not run into other errors... reject.
- self.err(
- "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
- gates, except when testing error paths in the CTFE engine",
- );
+ self.emit_err(NotCircumventFeature);
}
}
}
@@ -284,6 +297,8 @@ impl Session {
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_warn<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -292,6 +307,8 @@ impl Session {
self.diagnostic().struct_span_warn(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_warn_with_expectation<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -301,6 +318,8 @@ impl Session {
self.diagnostic().struct_span_warn_with_expectation(sp, msg, id)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -310,10 +329,14 @@ impl Session {
self.diagnostic().struct_span_warn_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_warn(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_warn_with_expectation(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -322,6 +345,8 @@ impl Session {
self.diagnostic().struct_warn_with_expectation(msg, id)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_allow<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -330,10 +355,14 @@ impl Session {
self.diagnostic().struct_span_allow(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_allow(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_expect(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -342,6 +371,8 @@ impl Session {
self.diagnostic().struct_expect(msg, id)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -350,6 +381,8 @@ impl Session {
self.diagnostic().struct_span_err(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -360,6 +393,8 @@ impl Session {
}
// FIXME: This method should be removed (every error should have an associated error code).
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_err(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -367,6 +402,8 @@ impl Session {
self.parse_sess.struct_err(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_err_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -375,6 +412,8 @@ impl Session {
self.diagnostic().struct_err_with_code(msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_warn_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -383,6 +422,8 @@ impl Session {
self.diagnostic().struct_warn_with_code(msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_fatal<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -391,6 +432,8 @@ impl Session {
self.diagnostic().struct_span_fatal(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -400,15 +443,21 @@ impl Session {
self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
self.diagnostic().struct_fatal(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
self.diagnostic().span_fatal(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -418,10 +467,14 @@ impl Session {
self.diagnostic().span_fatal_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! {
self.diagnostic().fatal(msg).raise()
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_err_or_warn<S: Into<MultiSpan>>(
&self,
is_warning: bool,
@@ -435,6 +488,8 @@ impl Session {
}
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -443,6 +498,8 @@ impl Session {
self.diagnostic().span_err(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -467,6 +524,9 @@ impl Session {
feature: Symbol,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let mut err = self.parse_sess.create_err(err);
+ if err.code.is_none() {
+ err.code = std::option::Option::Some(error_code!(E0658));
+ }
add_feature_diagnostics(&mut err, &self.parse_sess, feature);
err
}
@@ -482,6 +542,15 @@ impl Session {
pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
self.parse_sess.emit_warning(warning)
}
+ pub fn create_fatal<'a>(
+ &'a self,
+ fatal: impl SessionDiagnostic<'a, !>,
+ ) -> DiagnosticBuilder<'a, !> {
+ self.parse_sess.create_fatal(fatal)
+ }
+ pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
+ self.parse_sess.emit_fatal(fatal)
+ }
#[inline]
pub fn err_count(&self) -> usize {
self.diagnostic().err_count()
@@ -516,9 +585,13 @@ impl Session {
Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
}
}
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().span_warn(sp, msg)
}
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -567,6 +640,8 @@ impl Session {
) {
self.diagnostic().span_note_without_error(sp, msg)
}
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_note_without_error(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -638,7 +713,7 @@ impl Session {
let found_positive = requested_features.clone().any(|r| r == "+crt-static");
// JUSTIFICATION: necessary use of crate_types directly (see FIXME below)
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
if found_positive || found_negative {
found_positive
} else if crate_type == Some(CrateType::ProcMacro)
@@ -661,8 +736,9 @@ impl Session {
)
}
+ /// Returns `true` if the target can use the current split debuginfo configuration.
pub fn target_can_use_split_dwarf(&self) -> bool {
- !self.target.is_like_windows && !self.target.is_like_osx
+ self.target.debuginfo_kind == DebuginfoKind::Dwarf
}
pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String {
@@ -894,7 +970,7 @@ impl Session {
}
// JUSTIFICATION: defn of the suggested wrapper fns
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
impl Session {
pub fn verbose(&self) -> bool {
self.opts.unstable_opts.verbose
@@ -1174,7 +1250,7 @@ impl Session {
}
// JUSTIFICATION: part of session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
fn default_emitter(
sopts: &config::Options,
registry: rustc_errors::registry::Registry,
@@ -1260,7 +1336,7 @@ pub enum DiagnosticOutput {
}
// JUSTIFICATION: literally session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn build_session(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
@@ -1277,10 +1353,8 @@ pub fn build_session(
let warnings_allow = sopts
.lint_opts
.iter()
- .filter(|&&(ref key, _)| *key == "warnings")
- .map(|&(_, ref level)| *level == lint::Allow)
- .last()
- .unwrap_or(false);
+ .rfind(|&&(ref key, _)| *key == "warnings")
+ .map_or(false, |&(_, level)| level == lint::Allow);
let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow);
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
@@ -1437,7 +1511,7 @@ pub fn build_session(
/// If it is useful to have a Session available already for validating a commandline argument, you
/// can do so here.
// JUSTIFICATION: needs to access args to validate them
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
fn validate_commandline_args_with_session_available(sess: &Session) {
// Since we don't know if code in an rlib will be linked to statically or
// dynamically downstream, rustc generates `__imp_` symbols that help linkers
@@ -1450,40 +1524,28 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
&& sess.opts.cg.prefer_dynamic
&& sess.target.is_like_windows
{
- sess.err(
- "Linker plugin based LTO is not supported together with \
- `-C prefer-dynamic` when targeting Windows-like targets",
- );
+ sess.emit_err(LinkerPluginToWindowsNotSupported);
}
// Make sure that any given profiling data actually exists so LLVM can't
// decide to silently skip PGO.
if let Some(ref path) = sess.opts.cg.profile_use {
if !path.exists() {
- sess.err(&format!(
- "File `{}` passed to `-C profile-use` does not exist.",
- path.display()
- ));
+ sess.emit_err(ProfileUseFileDoesNotExist { path });
}
}
// Do the same for sample profile data.
if let Some(ref path) = sess.opts.unstable_opts.profile_sample_use {
if !path.exists() {
- sess.err(&format!(
- "File `{}` passed to `-C profile-sample-use` does not exist.",
- path.display()
- ));
+ sess.emit_err(ProfileSampleUseFileDoesNotExist { path });
}
}
// Unwind tables cannot be disabled if the target requires them.
if let Some(include_uwtables) = sess.opts.cg.force_unwind_tables {
if sess.target.requires_uwtable && !include_uwtables {
- sess.err(
- "target requires unwind tables, they cannot be disabled with \
- `-C force-unwind-tables=no`.",
- );
+ sess.emit_err(TargetRequiresUnwindTables);
}
}
@@ -1493,56 +1555,56 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
match unsupported_sanitizers.into_iter().count() {
0 => {}
1 => {
- sess.err(&format!(
- "{} sanitizer is not supported for this target",
- unsupported_sanitizers
- ));
+ sess.emit_err(SanitizerNotSupported { us: unsupported_sanitizers.to_string() });
}
_ => {
- sess.err(&format!(
- "{} sanitizers are not supported for this target",
- unsupported_sanitizers
- ));
+ sess.emit_err(SanitizersNotSupported { us: unsupported_sanitizers.to_string() });
}
}
// Cannot mix and match sanitizers.
let mut sanitizer_iter = sess.opts.unstable_opts.sanitizer.into_iter();
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
- sess.err(&format!("`-Zsanitizer={first}` is incompatible with `-Zsanitizer={second}`"));
+ sess.emit_err(CannotMixAndMatchSanitizers {
+ first: first.to_string(),
+ second: second.to_string(),
+ });
}
// Cannot enable crt-static with sanitizers on Linux
if sess.crt_static(None) && !sess.opts.unstable_opts.sanitizer.is_empty() {
- sess.err(
- "sanitizer is incompatible with statically linked libc, \
- disable it using `-C target-feature=-crt-static`",
- );
+ sess.emit_err(CannotEnableCrtStaticLinux);
}
// LLVM CFI and VFE both require LTO.
if sess.lto() != config::Lto::Fat {
if sess.is_sanitizer_cfi_enabled() {
- sess.err("`-Zsanitizer=cfi` requires `-Clto`");
+ sess.emit_err(SanitizerCfiEnabled);
}
if sess.opts.unstable_opts.virtual_function_elimination {
- sess.err("`-Zvirtual-function-elimination` requires `-Clto`");
+ sess.emit_err(UnstableVirtualFunctionElimination);
}
}
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
if !sess.target.options.supports_stack_protector {
- sess.warn(&format!(
- "`-Z stack-protector={}` is not supported for target {} and will be ignored",
- sess.opts.unstable_opts.stack_protector, sess.opts.target_triple
- ))
+ sess.emit_warning(StackProtectorNotSupportedForTarget {
+ stack_protector: sess.opts.unstable_opts.stack_protector,
+ target_triple: &sess.opts.target_triple,
+ });
}
}
if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
if dwarf_version > 5 {
- sess.err(&format!("requested DWARF version {} is greater than 5", dwarf_version));
+ sess.emit_err(UnsupportedDwarfVersion { dwarf_version });
}
}
+
+ if !sess.target.options.supported_split_debuginfo.contains(&sess.split_debuginfo())
+ && !sess.opts.unstable_opts.unstable_options
+ {
+ sess.emit_err(SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() });
+ }
}
/// Holds data on the current incremental compilation session, if there is one.
@@ -1586,14 +1648,20 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
rustc_errors::Handler::with_emitter(true, None, emitter)
}
+#[allow(rustc::untranslatable_diagnostic)]
+#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed {
early_error_handler(output).struct_err(msg).emit()
}
+#[allow(rustc::untranslatable_diagnostic)]
+#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
early_error_handler(output).struct_fatal(msg).emit()
}
+#[allow(rustc::untranslatable_diagnostic)]
+#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
early_error_handler(output).struct_warn(msg).emit()
}
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 5c7aaf35b..3e93c6bba 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -11,6 +11,8 @@
test(attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
pub mod mir;
diff --git a/compiler/rustc_smir/src/mir.rs b/compiler/rustc_smir/src/mir.rs
index 855605b1a..887e65729 100644
--- a/compiler/rustc_smir/src/mir.rs
+++ b/compiler/rustc_smir/src/mir.rs
@@ -1,10 +1,10 @@
+pub use crate::very_unstable::hir::ImplicitSelfKind;
pub use crate::very_unstable::middle::mir::{
visit::MutVisitor, AggregateKind, AssertKind, BasicBlock, BasicBlockData, BinOp, BindingForm,
BlockTailInfo, Body, BorrowKind, CastKind, ClearCrossCrate, Constant, ConstantKind,
- CopyNonOverlapping, Coverage, FakeReadCause, Field, GeneratorInfo, ImplicitSelfKind,
- InlineAsmOperand, Local, LocalDecl, LocalInfo, LocalKind, Location, MirPhase, MirSource,
- NullOp, Operand, Place, PlaceRef, ProjectionElem, ProjectionKind, Promoted, RetagKind, Rvalue,
- Safety, SourceInfo, SourceScope, SourceScopeData, SourceScopeLocalData, Statement,
- StatementKind, UnOp, UserTypeProjection, UserTypeProjections, VarBindingForm, VarDebugInfo,
- VarDebugInfoContents,
+ CopyNonOverlapping, Coverage, FakeReadCause, Field, GeneratorInfo, InlineAsmOperand, Local,
+ LocalDecl, LocalInfo, LocalKind, Location, MirPhase, MirSource, NullOp, Operand, Place,
+ PlaceRef, ProjectionElem, ProjectionKind, Promoted, RetagKind, Rvalue, Safety, SourceInfo,
+ SourceScope, SourceScopeData, SourceScopeLocalData, Statement, StatementKind, UnOp,
+ UserTypeProjection, UserTypeProjections, VarBindingForm, VarDebugInfo, VarDebugInfoContents,
};
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index a1533fe46..37b8371a8 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -305,6 +305,12 @@ impl DefId {
}
}
+impl From<LocalDefId> for DefId {
+ fn from(local: LocalDefId) -> DefId {
+ local.to_def_id()
+ }
+}
+
impl<E: Encoder> Encodable<E> for DefId {
default fn encode(&self, s: &mut E) {
self.krate.encode(s);
@@ -331,7 +337,7 @@ impl fmt::Debug for DefId {
}
}
-rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefId);
+rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefIdMapEntry, DefId);
/// A `LocalDefId` is equivalent to a `DefId` with `krate == LOCAL_CRATE`. Since
/// we encode this information in the type, we can ensure at compile time that
@@ -393,7 +399,12 @@ impl<D: Decoder> Decodable<D> for LocalDefId {
}
}
-rustc_data_structures::define_id_collections!(LocalDefIdMap, LocalDefIdSet, LocalDefId);
+rustc_data_structures::define_id_collections!(
+ LocalDefIdMap,
+ LocalDefIdSet,
+ LocalDefIdMapEntry,
+ LocalDefId
+);
impl<CTX: HashStableContext> HashStable<CTX> for DefId {
#[inline]
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index e169d3c7c..191186af6 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -41,7 +41,6 @@ use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt;
use std::hash::Hash;
-use tracing::*;
/// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks".
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -945,12 +944,6 @@ pub struct ExpnData {
/// internally without forcing the whole crate to opt-in
/// to them.
pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
- /// Whether the macro is allowed to use `unsafe` internally
- /// even if the user crate has `#![forbid(unsafe_code)]`.
- pub allow_internal_unsafe: bool,
- /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`)
- /// for a given macro.
- pub local_inner_macros: bool,
/// Edition of the crate in which the macro is defined.
pub edition: Edition,
/// The `DefId` of the macro being invoked,
@@ -958,6 +951,13 @@ pub struct ExpnData {
pub macro_def_id: Option<DefId>,
/// The normal module (`mod`) in which the expanded macro was defined.
pub parent_module: Option<DefId>,
+ /// Suppresses the `unsafe_code` lint for code produced by this macro.
+ pub allow_internal_unsafe: bool,
+ /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
+ pub local_inner_macros: bool,
+ /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other
+ /// words, was the macro definition annotated with `#[collapse_debuginfo]`)?
+ pub collapse_debuginfo: bool,
}
impl !PartialEq for ExpnData {}
@@ -970,11 +970,12 @@ impl ExpnData {
call_site: Span,
def_site: Span,
allow_internal_unstable: Option<Lrc<[Symbol]>>,
- allow_internal_unsafe: bool,
- local_inner_macros: bool,
edition: Edition,
macro_def_id: Option<DefId>,
parent_module: Option<DefId>,
+ allow_internal_unsafe: bool,
+ local_inner_macros: bool,
+ collapse_debuginfo: bool,
) -> ExpnData {
ExpnData {
kind,
@@ -982,12 +983,13 @@ impl ExpnData {
call_site,
def_site,
allow_internal_unstable,
- allow_internal_unsafe,
- local_inner_macros,
edition,
macro_def_id,
parent_module,
disambiguator: 0,
+ allow_internal_unsafe,
+ local_inner_macros,
+ collapse_debuginfo,
}
}
@@ -1005,12 +1007,13 @@ impl ExpnData {
call_site,
def_site: DUMMY_SP,
allow_internal_unstable: None,
- allow_internal_unsafe: false,
- local_inner_macros: false,
edition,
macro_def_id,
parent_module,
disambiguator: 0,
+ allow_internal_unsafe: false,
+ local_inner_macros: false,
+ collapse_debuginfo: false,
}
}
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index cf3069281..da31b3462 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -15,11 +15,13 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(if_let_guard)]
#![feature(negative_impls)]
#![feature(min_specialization)]
#![feature(rustc_attrs)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
@@ -74,8 +76,6 @@ use md5::Md5;
use sha1::Sha1;
use sha2::Sha256;
-use tracing::debug;
-
#[cfg(test)]
mod tests;
@@ -558,12 +558,25 @@ impl Span {
self.data_untracked().is_dummy()
}
- /// Returns `true` if this span comes from a macro or desugaring.
+ /// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
#[inline]
pub fn from_expansion(self) -> bool {
self.ctxt() != SyntaxContext::root()
}
+ /// Returns `true` if `span` originates in a macro's expansion where debuginfo should be
+ /// collapsed.
+ pub fn in_macro_expansion_with_collapse_debuginfo(self) -> bool {
+ let outer_expn = self.ctxt().outer_expn_data();
+ matches!(outer_expn.kind, ExpnKind::Macro(..)) && outer_expn.collapse_debuginfo
+ }
+
+ /// Returns `true` if this span comes from MIR inlining.
+ pub fn is_inlined(self) -> bool {
+ let outer_expn = self.ctxt().outer_expn_data();
+ matches!(outer_expn.kind, ExpnKind::Inlined)
+ }
+
/// Returns `true` if `span` originates in a derive-macro's expansion.
pub fn in_derive_expansion(self) -> bool {
matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
@@ -662,6 +675,16 @@ impl Span {
Some(self)
}
+ /// Like `find_ancestor_inside`, but specifically for when spans might not
+ /// overlaps. Take care when using this, and prefer `find_ancestor_inside`
+ /// when you know that the spans are nested (modulo macro expansion).
+ pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option<Span> {
+ while !Span::eq_ctxt(self, other) {
+ self = self.parent_callsite()?;
+ }
+ Some(self)
+ }
+
/// Edition of the crate from which this span came.
pub fn edition(self) -> edition::Edition {
self.ctxt().edition()
@@ -1094,10 +1117,8 @@ pub enum ExternalSource {
Unneeded,
Foreign {
kind: ExternalSourceKind,
- /// This SourceFile's byte-offset within the source_map of its original crate.
- original_start_pos: BytePos,
- /// The end of this SourceFile within the source_map of its original crate.
- original_end_pos: BytePos,
+ /// Index of the file inside metadata.
+ metadata_index: u32,
},
}
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 28381157d..4d94c92d3 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -23,7 +23,6 @@ use std::{convert::TryFrom, unreachable};
use std::fs;
use std::io;
-use tracing::debug;
#[cfg(test)]
mod tests;
@@ -336,7 +335,7 @@ impl SourceMap {
mut file_local_non_narrow_chars: Vec<NonNarrowChar>,
mut file_local_normalized_pos: Vec<NormalizedPos>,
original_start_pos: BytePos,
- original_end_pos: BytePos,
+ metadata_index: u32,
) -> Lrc<SourceFile> {
let start_pos = self
.allocate_address_space(source_len)
@@ -381,8 +380,7 @@ impl SourceMap {
src_hash,
external_src: Lock::new(ExternalSource::Foreign {
kind: ExternalSourceKind::AbsentOk,
- original_start_pos,
- original_end_pos,
+ metadata_index,
}),
start_pos,
end_pos,
@@ -473,7 +471,7 @@ impl SourceMap {
let hi = self.lookup_char_pos(sp.hi());
let offset = self.lookup_char_pos(relative_to.lo());
- if lo.file.name != offset.file.name {
+ if lo.file.name != offset.file.name || !relative_to.contains(sp) {
return self.span_to_embeddable_string(sp);
}
@@ -722,7 +720,7 @@ impl SourceMap {
})
}
- /// Extends the given `Span` to just after the next occurrence of `c`.
+ /// Extends the given `Span` to just before the next occurrence of `c`.
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
if let Ok(next_source) = self.span_to_next_source(sp) {
let next_source = next_source.split(c).next().unwrap_or("");
@@ -983,93 +981,6 @@ impl SourceMap {
self.files().iter().fold(0, |a, f| a + f.count_lines())
}
- pub fn generate_fn_name_span(&self, span: Span) -> Option<Span> {
- let prev_span = self.span_extend_to_prev_str(span, "fn", true, true)?;
- if let Ok(snippet) = self.span_to_snippet(prev_span) {
- debug!(
- "generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}",
- span, prev_span, snippet
- );
-
- if snippet.is_empty() {
- return None;
- };
-
- let len = snippet
- .find(|c: char| !c.is_alphanumeric() && c != '_')
- .expect("no label after fn");
- Some(prev_span.with_hi(BytePos(prev_span.lo().0 + len as u32)))
- } else {
- None
- }
- }
-
- /// Takes the span of a type parameter in a function signature and try to generate a span for
- /// the function name (with generics) and a new snippet for this span with the pointed type
- /// parameter as a new local type parameter.
- ///
- /// For instance:
- /// ```rust,ignore (pseudo-Rust)
- /// // Given span
- /// fn my_function(param: T)
- /// // ^ Original span
- ///
- /// // Result
- /// fn my_function(param: T)
- /// // ^^^^^^^^^^^ Generated span with snippet `my_function<T>`
- /// ```
- ///
- /// Attention: The method used is very fragile since it essentially duplicates the work of the
- /// parser. If you need to use this function or something similar, please consider updating the
- /// `SourceMap` functions and this function to something more robust.
- pub fn generate_local_type_param_snippet(&self, span: Span) -> Option<(Span, String)> {
- // Try to extend the span to the previous "fn" keyword to retrieve the function
- // signature.
- if let Some(sugg_span) = self.span_extend_to_prev_str(span, "fn", false, true) {
- if let Ok(snippet) = self.span_to_snippet(sugg_span) {
- // Consume the function name.
- let mut offset = snippet
- .find(|c: char| !c.is_alphanumeric() && c != '_')
- .expect("no label after fn");
-
- // Consume the generics part of the function signature.
- let mut bracket_counter = 0;
- let mut last_char = None;
- for c in snippet[offset..].chars() {
- match c {
- '<' => bracket_counter += 1,
- '>' => bracket_counter -= 1,
- '(' => {
- if bracket_counter == 0 {
- break;
- }
- }
- _ => {}
- }
- offset += c.len_utf8();
- last_char = Some(c);
- }
-
- // Adjust the suggestion span to encompass the function name with its generics.
- let sugg_span = sugg_span.with_hi(BytePos(sugg_span.lo().0 + offset as u32));
-
- // Prepare the new suggested snippet to append the type parameter that triggered
- // the error in the generics of the function signature.
- let mut new_snippet = if last_char == Some('>') {
- format!("{}, ", &snippet[..(offset - '>'.len_utf8())])
- } else {
- format!("{}<", &snippet[..offset])
- };
- new_snippet
- .push_str(&self.span_to_snippet(span).unwrap_or_else(|_| "T".to_string()));
- new_snippet.push('>');
-
- return Some((sugg_span, new_snippet));
- }
- }
-
- None
- }
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
source_file.add_external_src(|| {
match source_file.name {
@@ -1148,13 +1059,13 @@ impl FilePathMapping {
return remap_path_prefix(&self.mapping, path);
- #[instrument(level = "debug", skip(mapping))]
+ #[instrument(level = "debug", skip(mapping), ret)]
fn remap_path_prefix(mapping: &[(PathBuf, PathBuf)], path: PathBuf) -> (PathBuf, bool) {
// NOTE: We are iterating over the mapping entries from last to first
// because entries specified later on the command line should
// take precedence.
for &(ref from, ref to) in mapping.iter().rev() {
- debug!("Trying to apply {:?} => {:?}", from, to);
+ debug!("Trying to apply {from:?} => {to:?}");
if let Ok(rest) = path.strip_prefix(from) {
let remapped = if rest.as_os_str().is_empty() {
@@ -1168,15 +1079,15 @@ impl FilePathMapping {
} else {
to.join(rest)
};
- debug!("Match - remapped {:?} => {:?}", path, remapped);
+ debug!("Match - remapped");
return (remapped, true);
} else {
- debug!("No match - prefix {:?} does not match {:?}", from, path);
+ debug!("No match - prefix {from:?} does not match");
}
}
- debug!("Path {:?} was not remapped", path);
+ debug!("not remapped");
(path, false)
}
}
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index be827cea8..3058ec45a 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -251,7 +251,7 @@ fn t10() {
non_narrow_chars,
normalized_pos,
start_pos,
- end_pos,
+ 0,
);
assert!(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 791160ff6..ae4d1a463 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -157,6 +157,7 @@ symbols! {
BTreeSet,
BinaryHeap,
Borrow,
+ BorrowMut,
Break,
C,
CStr,
@@ -213,6 +214,7 @@ symbols! {
IntoIterator,
IoRead,
IoWrite,
+ IpAddr,
IrTyKind,
Is,
ItemContext,
@@ -222,6 +224,7 @@ symbols! {
LinkedList,
LintPass,
Mutex,
+ MutexGuard,
N,
NonZeroI128,
NonZeroI16,
@@ -270,6 +273,8 @@ symbols! {
Rust,
RustcDecodable,
RustcEncodable,
+ RwLockReadGuard,
+ RwLockWriteGuard,
Send,
SeqCst,
SessionDiagnostic,
@@ -280,6 +285,7 @@ symbols! {
StructuralPartialEq,
SubdiagnosticMessage,
Sync,
+ T,
Target,
ToOwned,
ToString,
@@ -334,6 +340,7 @@ symbols! {
alias,
align,
align_offset,
+ alignment,
alignstack,
all,
alloc,
@@ -481,6 +488,7 @@ symbols! {
cmse_nonsecure_entry,
coerce_unsized,
cold,
+ collapse_debuginfo,
column,
column_macro,
compare_and_swap,
@@ -504,7 +512,6 @@ symbols! {
const_deallocate,
const_eval_limit,
const_eval_select,
- const_eval_select_ct,
const_evaluatable_checked,
const_extern_fn,
const_fn,
@@ -644,6 +651,7 @@ symbols! {
dropck_parametricity,
dylib,
dyn_metadata,
+ dyn_star,
dyn_trait,
e,
edition_macro_pats,
@@ -656,7 +664,6 @@ symbols! {
emit_struct,
emit_struct_field,
enable,
- enclosing_scope,
encode,
end,
env,
@@ -759,7 +766,7 @@ symbols! {
gen_future,
gen_kill,
generator,
- generator_return,
+ generator_clone,
generator_state,
generators,
generic_arg_infer,
@@ -802,6 +809,7 @@ symbols! {
impl_trait_in_bindings,
implied_by,
import,
+ import_name_type,
import_shadowing,
imported_main,
in_band_lifetimes,
@@ -817,6 +825,7 @@ symbols! {
infer_outlives_requirements,
infer_static_outlives_requirements,
inherent_associated_types,
+ inherit,
inlateout,
inline,
inline_const,
@@ -859,6 +868,7 @@ symbols! {
lib,
libc,
lifetime,
+ lifetimes,
likely,
line,
line_macro,
@@ -1056,6 +1066,7 @@ symbols! {
panic_unwind,
panicking,
param_attrs,
+ parent_label,
partial_cmp,
partial_ord,
passes,
@@ -1110,14 +1121,15 @@ symbols! {
profiler_builtins,
profiler_runtime,
ptr,
- ptr_guaranteed_eq,
- ptr_guaranteed_ne,
+ ptr_guaranteed_cmp,
+ ptr_mask,
ptr_null,
ptr_null_mut,
ptr_offset_from,
ptr_offset_from_unsigned,
pub_macro_rules,
pub_restricted,
+ public,
pure,
pushpop_unsafe,
qreg,
@@ -1170,8 +1182,10 @@ symbols! {
repr_packed,
repr_simd,
repr_transparent,
+ require,
residual,
result,
+ return_position_impl_trait_in_trait,
rhs,
rintf32,
rintf64,
@@ -1200,6 +1214,7 @@ symbols! {
rust_eh_unregister_frames,
rust_oom,
rustc,
+ rustc_access_level,
rustc_allocator,
rustc_allocator_nounwind,
rustc_allocator_zeroed,
@@ -1217,6 +1232,7 @@ symbols! {
rustc_conversion_suggestion,
rustc_deallocator,
rustc_def_path,
+ rustc_default_body_unstable,
rustc_diagnostic_item,
rustc_diagnostic_macros,
rustc_dirty,
@@ -1279,9 +1295,11 @@ symbols! {
rustc_variance,
rustdoc,
rustdoc_internals,
+ rustdoc_missing_doc_code_examples,
rustfmt,
rvalue_static_promotion,
s,
+ safety,
sanitize,
sanitizer_runtime,
saturating_add,
@@ -1295,6 +1313,8 @@ symbols! {
should_panic,
shr,
shr_assign,
+ sig_dfl,
+ sig_ign,
simd,
simd_add,
simd_and,
@@ -1302,9 +1322,11 @@ symbols! {
simd_as,
simd_bitmask,
simd_cast,
+ simd_cast_ptr,
simd_ceil,
simd_div,
simd_eq,
+ simd_expose_addr,
simd_extract,
simd_fabs,
simd_fcos,
@@ -1320,6 +1342,7 @@ symbols! {
simd_fmin,
simd_fpow,
simd_fpowi,
+ simd_from_exposed_addr,
simd_fsin,
simd_fsqrt,
simd_gather,
@@ -1464,6 +1487,7 @@ symbols! {
trait_alias,
trait_upcasting,
transmute,
+ transmute_opts,
transmute_trait,
transparent,
transparent_enums,
@@ -1480,6 +1504,7 @@ symbols! {
tuple,
tuple_from_req,
tuple_indexing,
+ tuple_trait,
two_phase,
ty,
type_alias_enum_variants,
@@ -1513,6 +1538,7 @@ symbols! {
unit,
universal_impl_trait,
unix,
+ unix_sigpipe,
unlikely,
unmarked_api,
unpin,
@@ -1558,6 +1584,7 @@ symbols! {
va_list,
va_start,
val,
+ validity,
values,
var,
variant_count,
@@ -1801,6 +1828,11 @@ impl Symbol {
Symbol(SymbolIndex::from_u32(n))
}
+ /// for use in Decoder only
+ pub fn new_from_decoded(n: u32) -> Self {
+ Self::new(n)
+ }
+
/// Maps a string to its interned representation.
pub fn intern(string: &str) -> Self {
with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
@@ -1850,14 +1882,14 @@ impl fmt::Display for Symbol {
}
impl<S: Encoder> Encodable<S> for Symbol {
- fn encode(&self, s: &mut S) {
+ default fn encode(&self, s: &mut S) {
s.emit_str(self.as_str());
}
}
impl<D: Decoder> Decodable<D> for Symbol {
#[inline]
- fn decode(d: &mut D) -> Symbol {
+ default fn decode(d: &mut D) -> Symbol {
Symbol::intern(&d.read_str())
}
}
@@ -2025,6 +2057,11 @@ impl Symbol {
pub fn can_be_raw(self) -> bool {
self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
}
+
+ /// Is this symbol was interned in compiler's `symbols!` macro
+ pub fn is_preinterned(self) -> bool {
+ self.as_u32() < PREINTERNED_SYMBOLS_COUNT
+ }
}
impl Ident {
diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml
index b104a40c2..3db052257 100644
--- a/compiler/rustc_symbol_mangling/Cargo.toml
+++ b/compiler/rustc_symbol_mangling/Cargo.toml
@@ -18,3 +18,5 @@ rustc_hir = { path = "../rustc_hir" }
rustc_target = { path = "../rustc_target" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_session = { path = "../rustc_session" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_errors = { path = "../rustc_errors" }
diff --git a/compiler/rustc_symbol_mangling/src/errors.rs b/compiler/rustc_symbol_mangling/src/errors.rs
new file mode 100644
index 000000000..664d2543f
--- /dev/null
+++ b/compiler/rustc_symbol_mangling/src/errors.rs
@@ -0,0 +1,34 @@
+//! Errors emitted by symbol_mangling.
+
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
+use rustc_macros::SessionDiagnostic;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[diag(symbol_mangling::test_output)]
+pub struct TestOutput {
+ #[primary_span]
+ pub span: Span,
+ pub kind: Kind,
+ pub content: String,
+}
+
+pub enum Kind {
+ SymbolName,
+ Demangling,
+ DemanglingAlt,
+ DefPath,
+}
+
+impl IntoDiagnosticArg for Kind {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ let kind = match self {
+ Kind::SymbolName => "symbol-name",
+ Kind::Demangling => "demangling",
+ Kind::DemanglingAlt => "demangling-alt",
+ Kind::DefPath => "def-path",
+ }
+ .into();
+ DiagnosticArgValue::Str(kind)
+ }
+}
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 9241fd82c..46c5fe78f 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -6,8 +6,6 @@ use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitable};
use rustc_middle::util::common::record_time;
-use tracing::debug;
-
use std::fmt::{self, Write};
use std::mem::{self, discriminant};
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 5fc992023..62f44a480 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -91,10 +91,15 @@
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_middle;
+#[macro_use]
+extern crate tracing;
+
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
@@ -105,11 +110,10 @@ use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Instance, TyCtxt};
use rustc_session::config::SymbolManglingVersion;
-use tracing::debug;
-
mod legacy;
mod v0;
+pub mod errors;
pub mod test;
pub mod typeid;
diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs
index 7249ce04c..9d89c9c52 100644
--- a/compiler/rustc_symbol_mangling/src/test.rs
+++ b/compiler/rustc_symbol_mangling/src/test.rs
@@ -4,6 +4,7 @@
//! def-path. This is used for unit testing the code that generates
//! paths etc in all kinds of annoying scenarios.
+use crate::errors::{Kind, TestOutput};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{subst::InternalSubsts, Instance, TyCtxt};
@@ -59,16 +60,31 @@ impl SymbolNamesTest<'_> {
tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def_id)),
);
let mangled = tcx.symbol_name(instance);
- tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled));
+ tcx.sess.emit_err(TestOutput {
+ span: attr.span,
+ kind: Kind::SymbolName,
+ content: format!("{mangled}"),
+ });
if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) {
- tcx.sess.span_err(attr.span, &format!("demangling({})", demangling));
- tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling));
+ tcx.sess.emit_err(TestOutput {
+ span: attr.span,
+ kind: Kind::Demangling,
+ content: format!("{demangling}"),
+ });
+ tcx.sess.emit_err(TestOutput {
+ span: attr.span,
+ kind: Kind::DemanglingAlt,
+ content: format!("{:#}", demangling),
+ });
}
}
for attr in tcx.get_attrs(def_id.to_def_id(), DEF_PATH) {
- let path = with_no_trimmed_paths!(tcx.def_path_str(def_id.to_def_id()));
- tcx.sess.span_err(attr.span, &format!("def-path({})", path));
+ tcx.sess.emit_err(TestOutput {
+ span: attr.span,
+ kind: Kind::DefPath,
+ content: with_no_trimmed_paths!(tcx.def_path_str(def_id.to_def_id())),
+ });
}
}
}
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index a09b52fbf..aa65a72ab 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -13,7 +13,7 @@ use rustc_hir as hir;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{
self, Binder, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind,
- Term, Ty, TyCtxt, UintTy,
+ TermKind, Ty, TyCtxt, UintTy,
};
use rustc_span::def_id::DefId;
use rustc_span::symbol::sym;
@@ -243,13 +243,9 @@ fn encode_predicate<'tcx>(
let name = encode_ty_name(tcx, projection.item_def_id);
let _ = write!(s, "u{}{}", name.len(), &name);
s.push_str(&encode_substs(tcx, projection.substs, dict, options));
- match projection.term {
- Term::Ty(ty) => {
- s.push_str(&encode_ty(tcx, ty, dict, options));
- }
- Term::Const(c) => {
- s.push_str(&encode_const(tcx, c, dict, options));
- }
+ match projection.term.unpack() {
+ TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)),
+ TermKind::Const(c) => s.push_str(&encode_const(tcx, c, dict, options)),
}
}
ty::ExistentialPredicate::AutoTrait(def_id) => {
@@ -309,8 +305,7 @@ fn encode_region<'tcx>(
| RegionKind::ReFree(..)
| RegionKind::ReStatic
| RegionKind::ReVar(..)
- | RegionKind::RePlaceholder(..)
- | RegionKind::ReEmpty(..) => {
+ | RegionKind::RePlaceholder(..) => {
bug!("encode_region: unexpected `{:?}`", region.kind());
}
}
@@ -632,10 +627,13 @@ fn encode_ty<'tcx>(
}
// Trait types
- ty::Dynamic(predicates, region) => {
+ ty::Dynamic(predicates, region, kind) => {
// u3dynI<element-type1[..element-typeN]>E, where <element-type> is <predicate>, as
// vendor extended type.
- let mut s = String::from("u3dynI");
+ let mut s = String::from(match kind {
+ ty::Dyn => "u3dynI",
+ ty::DynStar => "u7dynstarI",
+ });
s.push_str(&encode_predicates(tcx, predicates, dict, options));
s.push_str(&encode_region(tcx, *region, dict, options));
s.push('E');
@@ -888,7 +886,7 @@ pub fn typeid_for_fnabi<'tcx>(
typeid.push('v');
}
} else {
- for n in 0..fn_abi.fixed_count {
+ for n in 0..fn_abi.fixed_count as usize {
let ty = transform_ty(tcx, fn_abi.args[n].layout.ty, transform_ty_options);
typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
}
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 71fa5a448..79d0ef69b 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -479,8 +479,12 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
})?;
}
- ty::Dynamic(predicates, r) => {
- self.push("D");
+ ty::Dynamic(predicates, r, kind) => {
+ self.push(match kind {
+ ty::Dyn => "D",
+ // FIXME(dyn-star): need to update v0 mangling docs
+ ty::DynStar => "D*",
+ });
self = self.print_dyn_existential(predicates)?;
self = r.print(self)?;
}
@@ -543,9 +547,9 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
let name = cx.tcx.associated_item(projection.item_def_id).name;
cx.push("p");
cx.push_ident(name.as_str());
- cx = match projection.term {
- ty::Term::Ty(ty) => ty.print(cx),
- ty::Term::Const(c) => c.print(cx),
+ cx = match projection.term.unpack() {
+ ty::TermKind::Ty(ty) => ty.print(cx),
+ ty::TermKind::Const(c) => c.print(cx),
}?;
}
ty::ExistentialPredicate::AutoTrait(def_id) => {
diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs
index 4613a459c..a84988fa7 100644
--- a/compiler/rustc_target/src/abi/call/aarch64.rs
+++ b/compiler/rustc_target/src/abi/call/aarch64.rs
@@ -1,6 +1,27 @@
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
use crate::abi::{HasDataLayout, TyAbiInterface};
+/// Given integer-types M and register width N (e.g. M=u16 and N=32 bits), the
+/// `ParamExtension` policy specifies how a uM value should be treated when
+/// passed via register or stack-slot of width N. See also rust-lang/rust#97463.
+#[derive(Copy, Clone, PartialEq)]
+pub enum ParamExtension {
+ /// Indicates that when passing an i8/i16, either as a function argument or
+ /// as a return value, it must be sign-extended to 32 bits, and likewise a
+ /// u8/u16 must be zero-extended to 32-bits. (This variant is here to
+ /// accommodate Apple's deviation from the usual AArch64 ABI as defined by
+ /// ARM.)
+ ///
+ /// See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
+ ExtendTo32Bits,
+
+ /// Indicates that no sign- nor zero-extension is performed: if a value of
+ /// type with bitwidth M is passed as function argument or return value,
+ /// then M bits are copied into the least significant M bits, and the
+ /// remaining bits of the register (or word of memory) are untouched.
+ NoExtension,
+}
+
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
where
Ty: TyAbiInterface<'a, C> + Copy,
@@ -24,13 +45,16 @@ where
})
}
-fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
+fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, param_policy: ParamExtension)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
- ret.extend_integer_width_to(32);
+ match param_policy {
+ ParamExtension::ExtendTo32Bits => ret.extend_integer_width_to(32),
+ ParamExtension::NoExtension => {}
+ }
return;
}
if let Some(uniform) = is_homogeneous_aggregate(cx, ret) {
@@ -46,13 +70,16 @@ where
ret.make_indirect();
}
-fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
+fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, param_policy: ParamExtension)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if !arg.layout.is_aggregate() {
- arg.extend_integer_width_to(32);
+ match param_policy {
+ ParamExtension::ExtendTo32Bits => arg.extend_integer_width_to(32),
+ ParamExtension::NoExtension => {}
+ }
return;
}
if let Some(uniform) = is_homogeneous_aggregate(cx, arg) {
@@ -68,19 +95,19 @@ where
arg.make_indirect();
}
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, param_policy: ParamExtension)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
- classify_ret(cx, &mut fn_abi.ret);
+ classify_ret(cx, &mut fn_abi.ret, param_policy);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
- classify_arg(cx, arg);
+ classify_arg(cx, arg, param_policy);
}
}
diff --git a/compiler/rustc_target/src/abi/call/amdgpu.rs b/compiler/rustc_target/src/abi/call/amdgpu.rs
index 9be97476c..e30dead63 100644
--- a/compiler/rustc_target/src/abi/call/amdgpu.rs
+++ b/compiler/rustc_target/src/abi/call/amdgpu.rs
@@ -26,7 +26,7 @@ where
classify_ret(cx, &mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs
index e66c2132b..1923ea588 100644
--- a/compiler/rustc_target/src/abi/call/arm.rs
+++ b/compiler/rustc_target/src/abi/call/arm.rs
@@ -88,7 +88,7 @@ where
classify_ret(cx, &mut fn_abi.ret, vfp);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/avr.rs b/compiler/rustc_target/src/abi/call/avr.rs
index c1f7a1e3a..e20f01355 100644
--- a/compiler/rustc_target/src/abi/call/avr.rs
+++ b/compiler/rustc_target/src/abi/call/avr.rs
@@ -49,7 +49,7 @@ pub fn compute_abi_info<Ty>(fty: &mut FnAbi<'_, Ty>) {
classify_ret_ty(&mut fty.ret);
}
- for arg in &mut fty.args {
+ for arg in fty.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/bpf.rs b/compiler/rustc_target/src/abi/call/bpf.rs
index 466c52553..780e7df43 100644
--- a/compiler/rustc_target/src/abi/call/bpf.rs
+++ b/compiler/rustc_target/src/abi/call/bpf.rs
@@ -22,7 +22,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/hexagon.rs b/compiler/rustc_target/src/abi/call/hexagon.rs
index 8028443b8..80a442048 100644
--- a/compiler/rustc_target/src/abi/call/hexagon.rs
+++ b/compiler/rustc_target/src/abi/call/hexagon.rs
@@ -21,7 +21,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/m68k.rs b/compiler/rustc_target/src/abi/call/m68k.rs
index 58fdc00b6..c1e0f54af 100644
--- a/compiler/rustc_target/src/abi/call/m68k.rs
+++ b/compiler/rustc_target/src/abi/call/m68k.rs
@@ -21,7 +21,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs
index cc4431976..edcd1bab8 100644
--- a/compiler/rustc_target/src/abi/call/mips.rs
+++ b/compiler/rustc_target/src/abi/call/mips.rs
@@ -22,10 +22,8 @@ where
let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
if arg.layout.is_aggregate() {
- arg.cast_to(Uniform { unit: Reg::i32(), total: size });
- if !offset.is_aligned(align) {
- arg.pad_with(Reg::i32());
- }
+ let pad_i32 = !offset.is_aligned(align);
+ arg.cast_to_and_pad_i32(Uniform { unit: Reg::i32(), total: size }, pad_i32);
} else {
arg.extend_integer_width_to(32);
}
@@ -42,7 +40,7 @@ where
classify_ret(cx, &mut fn_abi.ret, &mut offset);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs
index cd54167aa..2700f67b2 100644
--- a/compiler/rustc_target/src/abi/call/mips64.rs
+++ b/compiler/rustc_target/src/abi/call/mips64.rs
@@ -158,7 +158,7 @@ where
classify_ret(cx, &mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 577126a95..d2fb8c32f 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -14,7 +14,6 @@ mod m68k;
mod mips;
mod mips64;
mod msp430;
-mod nvptx;
mod nvptx64;
mod powerpc;
mod powerpc64;
@@ -27,7 +26,7 @@ mod x86;
mod x86_64;
mod x86_win64;
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub enum PassMode {
/// Ignore the argument.
///
@@ -41,9 +40,10 @@ pub enum PassMode {
///
/// The argument has a layout abi of `ScalarPair`.
Pair(ArgAttributes, ArgAttributes),
- /// Pass the argument after casting it, to either
- /// a single uniform or a pair of registers.
- Cast(CastTarget),
+ /// Pass the argument after casting it, to either a single uniform or a
+ /// pair of registers. The bool indicates if a `Reg::i32()` dummy argument
+ /// is emitted before the real argument.
+ Cast(Box<CastTarget>, bool),
/// Pass the argument indirectly via a hidden pointer.
/// The `extra_attrs` value, if any, is for the extra data (vtable or length)
/// which indicates that it refers to an unsized rvalue.
@@ -464,10 +464,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct ArgAbi<'a, Ty> {
pub layout: TyAndLayout<'a, Ty>,
-
- /// Dummy argument, which is emitted before the real argument.
- pub pad: Option<Reg>,
-
pub mode: PassMode,
}
@@ -487,7 +483,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()),
Abi::Aggregate { .. } => PassMode::Direct(ArgAttributes::new()),
};
- ArgAbi { layout, pad: None, mode }
+ ArgAbi { layout, mode }
}
fn indirect_pass_mode(layout: &TyAndLayout<'a, Ty>) -> PassMode {
@@ -549,11 +545,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
}
pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
- self.mode = PassMode::Cast(target.into());
+ self.mode = PassMode::Cast(Box::new(target.into()), false);
}
- pub fn pad_with(&mut self, reg: Reg) {
- self.pad = Some(reg);
+ pub fn cast_to_and_pad_i32<T: Into<CastTarget>>(&mut self, target: T, pad_i32: bool) {
+ self.mode = PassMode::Cast(Box::new(target.into()), pad_i32);
}
pub fn is_indirect(&self) -> bool {
@@ -615,7 +611,7 @@ pub enum Conv {
#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct FnAbi<'a, Ty> {
/// The LLVM types of each argument.
- pub args: Vec<ArgAbi<'a, Ty>>,
+ pub args: Box<[ArgAbi<'a, Ty>]>,
/// LLVM return type.
pub ret: ArgAbi<'a, Ty>,
@@ -626,7 +622,7 @@ pub struct FnAbi<'a, Ty> {
///
/// Should only be different from args.len() when c_variadic is true.
/// This can be used to know whether an argument is variadic or not.
- pub fixed_count: usize,
+ pub fixed_count: u32,
pub conv: Conv,
@@ -689,7 +685,14 @@ impl<'a, Ty> FnAbi<'a, Ty> {
}
}
},
- "aarch64" => aarch64::compute_abi_info(cx, self),
+ "aarch64" => {
+ let param_policy = if cx.target_spec().is_like_osx {
+ aarch64::ParamExtension::ExtendTo32Bits
+ } else {
+ aarch64::ParamExtension::NoExtension
+ };
+ aarch64::compute_abi_info(cx, self, param_policy)
+ }
"amdgpu" => amdgpu::compute_abi_info(cx, self),
"arm" => arm::compute_abi_info(cx, self),
"avr" => avr::compute_abi_info(self),
@@ -702,7 +705,6 @@ impl<'a, Ty> FnAbi<'a, Ty> {
"msp430" => msp430::compute_abi_info(self),
"sparc" => sparc::compute_abi_info(cx, self),
"sparc64" => sparc64::compute_abi_info(cx, self),
- "nvptx" => nvptx::compute_abi_info(self),
"nvptx64" => {
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
nvptx64::compute_ptx_kernel_abi_info(cx, self)
@@ -732,3 +734,13 @@ impl<'a, Ty> FnAbi<'a, Ty> {
Ok(())
}
}
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+ use super::*;
+ use rustc_data_structures::static_assert_size;
+ // These are in alphabetical order, which is easy to maintain.
+ static_assert_size!(ArgAbi<'_, usize>, 56);
+ static_assert_size!(FnAbi<'_, usize>, 80);
+}
diff --git a/compiler/rustc_target/src/abi/call/msp430.rs b/compiler/rustc_target/src/abi/call/msp430.rs
index 0ba73657b..33ef47be0 100644
--- a/compiler/rustc_target/src/abi/call/msp430.rs
+++ b/compiler/rustc_target/src/abi/call/msp430.rs
@@ -30,7 +30,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/nvptx.rs b/compiler/rustc_target/src/abi/call/nvptx.rs
deleted file mode 100644
index 428dd95bb..000000000
--- a/compiler/rustc_target/src/abi/call/nvptx.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Reference: PTX Writer's Guide to Interoperability
-// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability
-
-use crate::abi::call::{ArgAbi, FnAbi};
-
-fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
- if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 {
- ret.make_indirect();
- } else {
- ret.extend_integer_width_to(32);
- }
-}
-
-fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
- if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 {
- arg.make_indirect();
- } else {
- arg.extend_integer_width_to(32);
- }
-}
-
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
- if !fn_abi.ret.is_ignore() {
- classify_ret(&mut fn_abi.ret);
- }
-
- for arg in &mut fn_abi.args {
- if arg.is_ignore() {
- continue;
- }
- classify_arg(arg);
- }
-}
diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs
index fc16f1c97..4abe51cd6 100644
--- a/compiler/rustc_target/src/abi/call/nvptx64.rs
+++ b/compiler/rustc_target/src/abi/call/nvptx64.rs
@@ -38,7 +38,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
@@ -55,7 +55,7 @@ where
panic!("Kernels should not return anything other than () or !");
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/powerpc.rs b/compiler/rustc_target/src/abi/call/powerpc.rs
index 27a5c6d2f..70c32db0a 100644
--- a/compiler/rustc_target/src/abi/call/powerpc.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc.rs
@@ -21,7 +21,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs
index c22ef9c8f..359bb8fc0 100644
--- a/compiler/rustc_target/src/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
@@ -132,7 +132,7 @@ where
classify_ret(cx, &mut fn_abi.ret, abi);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs
index 752b44f64..1cb360f83 100644
--- a/compiler/rustc_target/src/abi/call/riscv.rs
+++ b/compiler/rustc_target/src/abi/call/riscv.rs
@@ -340,7 +340,7 @@ where
arg,
xlen,
flen,
- i >= fn_abi.fixed_count,
+ i >= fn_abi.fixed_count as usize,
&mut avail_gprs,
&mut avail_fprs,
);
diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs
index 13706e8c2..ea2369281 100644
--- a/compiler/rustc_target/src/abi/call/s390x.rs
+++ b/compiler/rustc_target/src/abi/call/s390x.rs
@@ -48,7 +48,7 @@ where
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs
index cc4431976..edcd1bab8 100644
--- a/compiler/rustc_target/src/abi/call/sparc.rs
+++ b/compiler/rustc_target/src/abi/call/sparc.rs
@@ -22,10 +22,8 @@ where
let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
if arg.layout.is_aggregate() {
- arg.cast_to(Uniform { unit: Reg::i32(), total: size });
- if !offset.is_aligned(align) {
- arg.pad_with(Reg::i32());
- }
+ let pad_i32 = !offset.is_aligned(align);
+ arg.cast_to_and_pad_i32(Uniform { unit: Reg::i32(), total: size }, pad_i32);
} else {
arg.extend_integer_width_to(32);
}
@@ -42,7 +40,7 @@ where
classify_ret(cx, &mut fn_abi.ret, &mut offset);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index cc3a0a699..1b74959ad 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -217,7 +217,7 @@ where
classify_arg(cx, &mut fn_abi.ret, Size { raw: 32 });
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/wasm.rs b/compiler/rustc_target/src/abi/call/wasm.rs
index 3237cde10..44427ee53 100644
--- a/compiler/rustc_target/src/abi/call/wasm.rs
+++ b/compiler/rustc_target/src/abi/call/wasm.rs
@@ -50,7 +50,7 @@ where
classify_ret(cx, &mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
@@ -66,7 +66,7 @@ pub fn compute_wasm_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_ret(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index c7d59baf9..7c26335dc 100644
--- a/compiler/rustc_target/src/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
@@ -49,7 +49,7 @@ where
}
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
@@ -72,7 +72,7 @@ where
let mut free_regs = 2;
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
let attrs = match arg.mode {
PassMode::Ignore
| PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
@@ -81,7 +81,7 @@ where
PassMode::Direct(ref mut attrs) => attrs,
PassMode::Pair(..)
| PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ }
- | PassMode::Cast(_) => {
+ | PassMode::Cast(..) => {
unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode)
}
};
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index a52e01a49..c0c071a61 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -239,7 +239,7 @@ where
x86_64_arg_or_ret(&mut fn_abi.ret, false);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs
index 2aad641b1..1aaf0e511 100644
--- a/compiler/rustc_target/src/abi/call/x86_win64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_win64.rs
@@ -31,7 +31,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
if !fn_abi.ret.is_ignore() {
fixup(&mut fn_abi.ret);
}
- for arg in &mut fn_abi.args {
+ for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 92ce4d91d..ec334e588 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -7,7 +7,7 @@ use crate::spec::Target;
use std::convert::{TryFrom, TryInto};
use std::fmt;
use std::iter::Step;
-use std::num::NonZeroUsize;
+use std::num::{NonZeroUsize, ParseIntError};
use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
use std::str::FromStr;
@@ -69,34 +69,46 @@ impl Default for TargetDataLayout {
}
}
+pub enum TargetDataLayoutErrors<'a> {
+ InvalidAddressSpace { addr_space: &'a str, cause: &'a str, err: ParseIntError },
+ InvalidBits { kind: &'a str, bit: &'a str, cause: &'a str, err: ParseIntError },
+ MissingAlignment { cause: &'a str },
+ InvalidAlignment { cause: &'a str, err: String },
+ InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
+ InconsistentTargetPointerWidth { pointer_size: u64, target: u32 },
+ InvalidBitsSize { err: String },
+}
+
impl TargetDataLayout {
- pub fn parse(target: &Target) -> Result<TargetDataLayout, String> {
+ pub fn parse<'a>(target: &'a Target) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
// Parse an address space index from a string.
- let parse_address_space = |s: &str, cause: &str| {
+ let parse_address_space = |s: &'a str, cause: &'a str| {
s.parse::<u32>().map(AddressSpace).map_err(|err| {
- format!("invalid address space `{}` for `{}` in \"data-layout\": {}", s, cause, err)
+ TargetDataLayoutErrors::InvalidAddressSpace { addr_space: s, cause, err }
})
};
// Parse a bit count from a string.
- let parse_bits = |s: &str, kind: &str, cause: &str| {
- s.parse::<u64>().map_err(|err| {
- format!("invalid {} `{}` for `{}` in \"data-layout\": {}", kind, s, cause, err)
+ let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
+ s.parse::<u64>().map_err(|err| TargetDataLayoutErrors::InvalidBits {
+ kind,
+ bit: s,
+ cause,
+ err,
})
};
// Parse a size string.
- let size = |s: &str, cause: &str| parse_bits(s, "size", cause).map(Size::from_bits);
+ let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
// Parse an alignment string.
- let align = |s: &[&str], cause: &str| {
+ let align = |s: &[&'a str], cause: &'a str| {
if s.is_empty() {
- return Err(format!("missing alignment for `{}` in \"data-layout\"", cause));
+ return Err(TargetDataLayoutErrors::MissingAlignment { cause });
}
let align_from_bits = |bits| {
- Align::from_bits(bits).map_err(|err| {
- format!("invalid alignment for `{}` in \"data-layout\": {}", cause, err)
- })
+ Align::from_bits(bits)
+ .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
};
let abi = parse_bits(s[0], "alignment", cause)?;
let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?;
@@ -158,25 +170,24 @@ impl TargetDataLayout {
// Perform consistency checks against the Target information.
if dl.endian != target.endian {
- return Err(format!(
- "inconsistent target specification: \"data-layout\" claims \
- architecture is {}-endian, while \"target-endian\" is `{}`",
- dl.endian.as_str(),
- target.endian.as_str(),
- ));
+ return Err(TargetDataLayoutErrors::InconsistentTargetArchitecture {
+ dl: dl.endian.as_str(),
+ target: target.endian.as_str(),
+ });
}
let target_pointer_width: u64 = target.pointer_width.into();
if dl.pointer_size.bits() != target_pointer_width {
- return Err(format!(
- "inconsistent target specification: \"data-layout\" claims \
- pointers are {}-bit, while \"target-pointer-width\" is `{}`",
- dl.pointer_size.bits(),
- target.pointer_width
- ));
+ return Err(TargetDataLayoutErrors::InconsistentTargetPointerWidth {
+ pointer_size: dl.pointer_size.bits(),
+ target: target.pointer_width,
+ });
}
- dl.c_enum_min_size = Integer::from_size(Size::from_bits(target.c_enum_min_bits))?;
+ dl.c_enum_min_size = match Integer::from_size(Size::from_bits(target.c_enum_min_bits)) {
+ Ok(bits) => bits,
+ Err(err) => return Err(TargetDataLayoutErrors::InvalidBitsSize { err }),
+ };
Ok(dl)
}
@@ -1130,7 +1141,7 @@ pub enum TagEncoding {
/// Niche (values invalid for a type) encoding the discriminant:
/// Discriminant and variant index coincide.
- /// The variant `dataful_variant` contains a niche at an arbitrary
+ /// The variant `untagged_variant` contains a niche at an arbitrary
/// offset (field `tag_field` of the enum), which for a variant with
/// discriminant `d` is set to
/// `(d - niche_variants.start).wrapping_add(niche_start)`.
@@ -1139,7 +1150,7 @@ pub enum TagEncoding {
/// `None` has a null pointer for the second tuple field, and
/// `Some` is the identity function (with a non-null reference).
Niche {
- dataful_variant: VariantIdx,
+ untagged_variant: VariantIdx,
niche_variants: RangeInclusive<VariantIdx>,
niche_start: u128,
},
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 59dbea705..a7deab9d2 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -11,11 +11,13 @@
#![feature(assert_matches)]
#![feature(associated_type_bounds)]
#![feature(exhaustive_patterns)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(step_trait)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
use std::iter::FromIterator;
use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
index 9d36e37d7..6d919a4c2 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
@@ -1,20 +1,20 @@
-use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, Target, TargetOptions};
+use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
- let mut base = super::apple_base::opts("macos");
+ let arch = "arm64";
+ let mut base = super::apple_base::opts("macos", arch, "");
base.cpu = "apple-a14".into();
base.max_atomic_width = Some(128);
// FIXME: The leak sanitizer currently fails the tests, see #88132.
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
- base.add_pre_link_args(LinkerFlavor::Gcc, &["-arch", "arm64"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
- let llvm_target = super::apple_base::macos_llvm_target("arm64");
+ let llvm_target = super::apple_base::macos_llvm_target(arch);
Target {
llvm_target: llvm_target.into(),
diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs
index 1b7161fbb..b301ce68a 100644
--- a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs
+++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs
@@ -18,7 +18,6 @@ pub fn target() -> Target {
panic_strategy: PanicStrategy::Abort,
position_independent_executables: true,
dynamic_linking: true,
- executables: true,
relro_level: RelroLevel::Off,
..Default::default()
},
diff --git a/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
index 59c6a95c2..98d3e79c8 100644
--- a/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
@@ -2,7 +2,7 @@ use crate::spec::Target;
pub fn target() -> Target {
let mut base = super::windows_gnullvm_base::opts();
- base.max_atomic_width = Some(64);
+ base.max_atomic_width = Some(128);
base.features = "+neon,+fp-armv8".into();
base.linker = Some("aarch64-w64-mingw32-clang".into());
diff --git a/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
index 856ec4fb0..7c4544b3f 100644
--- a/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
@@ -2,7 +2,7 @@ use crate::spec::Target;
pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts();
- base.max_atomic_width = Some(64);
+ base.max_atomic_width = Some(128);
base.features = "+neon,+fp-armv8".into();
Target {
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
index 162b091b2..3ef04c676 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
@@ -7,7 +7,7 @@ use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = uefi_msvc_base::opts();
- base.max_atomic_width = Some(64);
+ base.max_atomic_width = Some(128);
base.add_pre_link_args(LinkerFlavor::Msvc, &["/machine:arm64"]);
Target {
diff --git a/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
index 54247fd93..db4dbf817 100644
--- a/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
@@ -2,7 +2,7 @@ use crate::spec::Target;
pub fn target() -> Target {
let mut base = super::windows_uwp_msvc_base::opts();
- base.max_atomic_width = Some(64);
+ base.max_atomic_width = Some(128);
Target {
llvm_target: "aarch64-pc-windows-msvc".into(),
diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs
index dc06597db..9f3e0bd5e 100644
--- a/compiler/rustc_target/src/spec/android_base.rs
+++ b/compiler/rustc_target/src/spec/android_base.rs
@@ -4,12 +4,11 @@ pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
base.os = "android".into();
base.default_dwarf_version = 2;
- base.position_independent_executables = true;
base.has_thread_local = false;
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
// for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
// was to always emit `uwtable`).
base.default_uwtable = true;
- base.crt_static_respected = false;
+ base.crt_static_respected = true;
base
}
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 15e4fb9be..2c72bf88a 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -1,8 +1,42 @@
use std::{borrow::Cow, env};
-use crate::spec::{cvs, FramePointer, LldFlavor, SplitDebuginfo, TargetOptions};
+use crate::spec::{cvs, DebuginfoKind, FramePointer, SplitDebuginfo, StaticCow, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor};
+
+fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
+ let platform_name: StaticCow<str> = match abi {
+ "sim" => format!("{}-simulator", os).into(),
+ "macabi" => "mac-catalyst".into(),
+ _ => os.into(),
+ };
+
+ let platform_version: StaticCow<str> = match os.as_ref() {
+ "ios" => ios_lld_platform_version(),
+ "tvos" => tvos_lld_platform_version(),
+ "watchos" => watchos_lld_platform_version(),
+ "macos" => macos_lld_platform_version(arch),
+ _ => unreachable!(),
+ }
+ .into();
+
+ let mut args = TargetOptions::link_args(
+ LinkerFlavor::Lld(LldFlavor::Ld64),
+ &["-arch", arch, "-platform_version"],
+ );
+ // Manually add owned args unsupported by link arg building helpers.
+ args.entry(LinkerFlavor::Lld(LldFlavor::Ld64)).or_default().extend([
+ platform_name,
+ platform_version.clone(),
+ platform_version,
+ ]);
+ if abi != "macabi" {
+ super::add_link_args(&mut args, LinkerFlavor::Gcc, &["-arch", arch]);
+ }
+
+ args
+}
-pub fn opts(os: &'static str) -> TargetOptions {
+pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOptions {
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
// either the linker will complain if it is used or the binary will end up
// segfaulting at runtime when run on 10.6. Rust by default supports macOS
@@ -24,6 +58,7 @@ pub fn opts(os: &'static str) -> TargetOptions {
// macOS has -dead_strip, which doesn't rely on function_sections
function_sections: false,
dynamic_linking: true,
+ pre_link_args: pre_link_args(os, arch, abi),
linker_is_gnu: false,
families: cvs!["unix"],
is_like_osx: true,
@@ -38,9 +73,15 @@ pub fn opts(os: &'static str) -> TargetOptions {
eh_frame_header: false,
lld_flavor: LldFlavor::Ld64,
+ debuginfo_kind: DebuginfoKind::DwarfDsym,
// The historical default for macOS targets is to run `dsymutil` which
// generates a packed version of debuginfo split from the main file.
split_debuginfo: SplitDebuginfo::Packed,
+ supported_split_debuginfo: Cow::Borrowed(&[
+ SplitDebuginfo::Packed,
+ SplitDebuginfo::Unpacked,
+ SplitDebuginfo::Off,
+ ]),
// This environment variable is pretty magical but is intended for
// producing deterministic builds. This was first discovered to be used
@@ -73,12 +114,17 @@ fn macos_deployment_target(arch: &str) -> (u32, u32) {
.unwrap_or_else(|| macos_default_deployment_target(arch))
}
+fn macos_lld_platform_version(arch: &str) -> String {
+ let (major, minor) = macos_deployment_target(arch);
+ format!("{}.{}", major, minor)
+}
+
pub fn macos_llvm_target(arch: &str) -> String {
let (major, minor) = macos_deployment_target(arch);
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
}
-pub fn macos_link_env_remove() -> Vec<Cow<'static, str>> {
+pub fn macos_link_env_remove() -> Vec<StaticCow<str>> {
let mut env_remove = Vec::with_capacity(2);
// Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
// may occur when we're linking a custom build script while targeting iOS for example.
@@ -109,7 +155,7 @@ pub fn ios_llvm_target(arch: &str) -> String {
format!("{}-apple-ios{}.{}.0", arch, major, minor)
}
-pub fn ios_lld_platform_version() -> String {
+fn ios_lld_platform_version() -> String {
let (major, minor) = ios_deployment_target();
format!("{}.{}", major, minor)
}
@@ -123,7 +169,7 @@ fn tvos_deployment_target() -> (u32, u32) {
deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
}
-pub fn tvos_lld_platform_version() -> String {
+fn tvos_lld_platform_version() -> String {
let (major, minor) = tvos_deployment_target();
format!("{}.{}", major, minor)
}
@@ -132,7 +178,7 @@ fn watchos_deployment_target() -> (u32, u32) {
deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
}
-pub fn watchos_lld_platform_version() -> String {
+fn watchos_lld_platform_version() -> String {
let (major, minor) = watchos_deployment_target();
format!("{}.{}", major, minor)
}
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index d77558f0f..49e302676 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -1,4 +1,4 @@
-use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
+use crate::spec::{cvs, TargetOptions};
use std::borrow::Cow;
use Arch::*;
@@ -61,53 +61,12 @@ fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> {
}
}
-fn pre_link_args(os: &'static str, arch: Arch) -> LinkArgs {
- let mut args = LinkArgs::new();
-
- let target_abi = target_abi(arch);
-
- let platform_name = match target_abi {
- "sim" => format!("{}-simulator", os),
- "macabi" => "mac-catalyst".to_string(),
- _ => os.to_string(),
- };
-
- let platform_version = match os.as_ref() {
- "ios" => super::apple_base::ios_lld_platform_version(),
- "tvos" => super::apple_base::tvos_lld_platform_version(),
- "watchos" => super::apple_base::watchos_lld_platform_version(),
- _ => unreachable!(),
- };
-
- let arch_str = target_arch_name(arch);
-
- if target_abi != "macabi" {
- args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch_str.into()]);
- }
-
- args.insert(
- LinkerFlavor::Lld(LldFlavor::Ld64),
- vec![
- "-arch".into(),
- arch_str.into(),
- "-platform_version".into(),
- platform_name.into(),
- platform_version.clone().into(),
- platform_version.into(),
- ],
- );
-
- args
-}
-
pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
TargetOptions {
abi: target_abi(arch).into(),
cpu: target_cpu(arch).into(),
- dynamic_linking: false,
- pre_link_args: pre_link_args(os, arch),
link_env_remove: link_env_remove(arch),
has_thread_local: false,
- ..super::apple_base::opts(os)
+ ..super::apple_base::opts(os, target_arch_name(arch), target_abi(arch))
}
}
diff --git a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
index 7b23fe1c4..cb7f5f2a5 100644
--- a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
arch: "aarch64".into(),
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".into(),
- max_atomic_width: Some(64),
+ max_atomic_width: Some(128),
forces_embed_bitcode: true,
// These arguments are not actually invoked - they just have
// to look right to pass App Store validation.
diff --git a/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs
new file mode 100644
index 000000000..4836f3cf7
--- /dev/null
+++ b/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs
@@ -0,0 +1,19 @@
+use crate::abi::Endian;
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+ Target {
+ llvm_target: "armeb-unknown-linux-gnueabi".into(),
+ pointer_width: 32,
+ data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
+ arch: "arm".into(),
+ options: TargetOptions {
+ abi: "eabi".into(),
+ features: "+strict-align,+v8,+crc".into(),
+ endian: Endian::Big,
+ max_atomic_width: Some(64),
+ mcount: "\u{1}__gnu_mcount_nc".into(),
+ ..super::linux_gnu_base::opts()
+ },
+ }
+}
diff --git a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
new file mode 100644
index 000000000..797dfe52b
--- /dev/null
+++ b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
@@ -0,0 +1,56 @@
+//! Targets the ARMv4T, with code as `a32` code by default.
+//!
+//! Primarily of use for the GBA, but usable with other devices too.
+//!
+//! Please ping @Lokathor if changes are needed.
+//!
+//! This target profile assumes that you have the ARM binutils in your path
+//! (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free
+//! for all major OSes from the ARM developer's website, and they may also be
+//! available in your system's package manager. Unfortunately, the standard
+//! linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we
+//! must use the GNU `ld` linker.
+//!
+//! **Important:** This target profile **does not** specify a linker script. You
+//! just get the default link script when you build a binary for this target.
+//! The default link script is very likely wrong, so you should use
+//! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script.
+
+use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub fn target() -> Target {
+ Target {
+ llvm_target: "armv4t-none-eabi".into(),
+ pointer_width: 32,
+ arch: "arm".into(),
+ /* Data layout args are '-' separated:
+ * little endian
+ * stack is 64-bit aligned (EABI)
+ * pointers are 32-bit
+ * i64 must be 64-bit aligned (EABI)
+ * mangle names with ELF style
+ * native integers are 32-bit
+ * All other elements are default
+ */
+ data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
+ options: TargetOptions {
+ abi: "eabi".into(),
+ linker_flavor: LinkerFlavor::Ld,
+ linker: Some("arm-none-eabi-ld".into()),
+ asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
+ // Force-enable 32-bit atomics, which allows the use of atomic load/store only.
+ // The resulting atomics are ABI incompatible with atomics backed by libatomic.
+ features: "+soft-float,+strict-align,+atomics-32".into(),
+ main_needs_argc_argv: false,
+ atomic_cas: false,
+ has_thumb_interworking: true,
+ relocation_model: RelocModel::Static,
+ panic_strategy: PanicStrategy::Abort,
+ // from thumb_base, rust-lang/rust#44993.
+ emit_debug_gdb_scripts: false,
+ // from thumb_base, apparently gcc/clang give enums a minimum of 8 bits on no-os targets
+ c_enum_min_bits: 8,
+ ..Default::default()
+ },
+ }
+}
diff --git a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
index b4cf2c5ee..f492c3451 100644
--- a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
@@ -2,6 +2,6 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target};
pub fn target() -> Target {
let mut target = wasm32_unknown_emscripten::target();
- target.add_post_link_args(LinkerFlavor::Em, &["-sWASM=0", "--memory-init-file", "0"]);
+ target.add_post_link_args(LinkerFlavor::EmCc, &["-sWASM=0", "--memory-init-file", "0"]);
target
}
diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs
index 1d441e558..8cca33cc4 100644
--- a/compiler/rustc_target/src/spec/avr_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
/// A base target for AVR devices using the GNU toolchain.
///
@@ -21,6 +21,7 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
max_atomic_width: Some(0),
atomic_cas: false,
+ relocation_model: RelocModel::Static,
..TargetOptions::default()
},
}
diff --git a/compiler/rustc_target/src/spec/bpf_base.rs b/compiler/rustc_target/src/spec/bpf_base.rs
index 3c4da6f88..baf365871 100644
--- a/compiler/rustc_target/src/spec/bpf_base.rs
+++ b/compiler/rustc_target/src/spec/bpf_base.rs
@@ -5,7 +5,7 @@ pub fn opts(endian: Endian) -> TargetOptions {
TargetOptions {
allow_asm: true,
endian,
- linker_flavor: LinkerFlavor::BpfLinker,
+ linker_flavor: LinkerFlavor::Bpf,
atomic_cas: false,
dynamic_linking: true,
no_builtins: true,
diff --git a/compiler/rustc_target/src/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs
index 52ac3622e..c126390f5 100644
--- a/compiler/rustc_target/src/spec/crt_objects.rs
+++ b/compiler/rustc_target/src/spec/crt_objects.rs
@@ -63,7 +63,7 @@ pub(super) fn all(obj: &'static str) -> CrtObjects {
])
}
-pub(super) fn pre_musl_fallback() -> CrtObjects {
+pub(super) fn pre_musl_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
(LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o", "crtbeginS.o"]),
@@ -74,7 +74,7 @@ pub(super) fn pre_musl_fallback() -> CrtObjects {
])
}
-pub(super) fn post_musl_fallback() -> CrtObjects {
+pub(super) fn post_musl_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crtend.o", "crtn.o"]),
(LinkOutputKind::DynamicPicExe, &["crtendS.o", "crtn.o"]),
@@ -85,7 +85,7 @@ pub(super) fn post_musl_fallback() -> CrtObjects {
])
}
-pub(super) fn pre_mingw_fallback() -> CrtObjects {
+pub(super) fn pre_mingw_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]),
(LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]),
@@ -96,7 +96,7 @@ pub(super) fn pre_mingw_fallback() -> CrtObjects {
])
}
-pub(super) fn post_mingw_fallback() -> CrtObjects {
+pub(super) fn post_mingw_self_contained() -> CrtObjects {
all("rsend.o")
}
@@ -108,7 +108,7 @@ pub(super) fn post_mingw() -> CrtObjects {
all("rsend.o")
}
-pub(super) fn pre_wasi_fallback() -> CrtObjects {
+pub(super) fn pre_wasi_self_contained() -> CrtObjects {
// Use crt1-command.o instead of crt1.o to enable support for new-style
// commands. See https://reviews.llvm.org/D81689 for more info.
new(&[
@@ -120,37 +120,41 @@ pub(super) fn pre_wasi_fallback() -> CrtObjects {
])
}
-pub(super) fn post_wasi_fallback() -> CrtObjects {
+pub(super) fn post_wasi_self_contained() -> CrtObjects {
new(&[])
}
-/// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
+/// Which logic to use to determine whether to use self-contained linking mode
+/// if `-Clink-self-contained` is not specified explicitly.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum CrtObjectsFallback {
+pub enum LinkSelfContainedDefault {
+ False,
+ True,
Musl,
Mingw,
- Wasm,
}
-impl FromStr for CrtObjectsFallback {
+impl FromStr for LinkSelfContainedDefault {
type Err = ();
- fn from_str(s: &str) -> Result<CrtObjectsFallback, ()> {
+ fn from_str(s: &str) -> Result<LinkSelfContainedDefault, ()> {
Ok(match s {
- "musl" => CrtObjectsFallback::Musl,
- "mingw" => CrtObjectsFallback::Mingw,
- "wasm" => CrtObjectsFallback::Wasm,
+ "false" => LinkSelfContainedDefault::False,
+ "true" | "wasm" => LinkSelfContainedDefault::True,
+ "musl" => LinkSelfContainedDefault::Musl,
+ "mingw" => LinkSelfContainedDefault::Mingw,
_ => return Err(()),
})
}
}
-impl ToJson for CrtObjectsFallback {
+impl ToJson for LinkSelfContainedDefault {
fn to_json(&self) -> Json {
match *self {
- CrtObjectsFallback::Musl => "musl",
- CrtObjectsFallback::Mingw => "mingw",
- CrtObjectsFallback::Wasm => "wasm",
+ LinkSelfContainedDefault::False => "false",
+ LinkSelfContainedDefault::True => "true",
+ LinkSelfContainedDefault::Musl => "musl",
+ LinkSelfContainedDefault::Mingw => "mingw",
}
.to_json()
}
diff --git a/compiler/rustc_target/src/spec/fuchsia_base.rs b/compiler/rustc_target/src/spec/fuchsia_base.rs
index df1e3275f..962ad0c66 100644
--- a/compiler/rustc_target/src/spec/fuchsia_base.rs
+++ b/compiler/rustc_target/src/spec/fuchsia_base.rs
@@ -1,6 +1,11 @@
use crate::spec::{crt_objects, cvs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
+ // This mirrors the linker options provided by clang. We presume lld for
+ // now. When using clang as the linker it will supply these options for us,
+ // so we only list them for ld/lld.
+ //
+ // https://github.com/llvm/llvm-project/blob/db9322b2066c55254e7691efeab863f43bfcc084/clang/lib/Driver/ToolChains/Fuchsia.cpp#L31
let pre_link_args = TargetOptions::link_args(
LinkerFlavor::Ld,
&[
diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
index cc2c78c69..2a24e4459 100644
--- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
@@ -10,7 +10,6 @@ pub fn target() -> Target {
base.crt_static_default = false;
base.has_rpath = true;
base.linker_is_gnu = false;
- base.dynamic_linking = true;
base.c_enum_min_bits = 8;
diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
index 1718bd77b..5e9ceb844 100644
--- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
@@ -1,7 +1,8 @@
use crate::spec::{FramePointer, LinkerFlavor, StackProbeType, Target, TargetOptions};
pub fn target() -> Target {
- let mut base = super::apple_base::opts("macos");
+ // ld64 only understand i386 and not i686
+ let mut base = super::apple_base::opts("macos", "i386", "");
base.cpu = "yonah".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
diff --git a/compiler/rustc_target/src/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs
index a08756861..b7bc1072b 100644
--- a/compiler/rustc_target/src/spec/l4re_base.rs
+++ b/compiler/rustc_target/src/spec/l4re_base.rs
@@ -1,14 +1,15 @@
-use crate::spec::{cvs, LinkerFlavor, PanicStrategy, TargetOptions};
+use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions};
pub fn opts() -> TargetOptions {
TargetOptions {
os: "l4re".into(),
env: "uclibc".into(),
- linker_flavor: LinkerFlavor::L4Bender,
+ linker_flavor: LinkerFlavor::Ld,
panic_strategy: PanicStrategy::Abort,
linker: Some("l4-bender".into()),
linker_is_gnu: false,
families: cvs!["unix"],
+ relocation_model: RelocModel::Static,
..Default::default()
}
}
diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs
index f4fce3b40..df8e84812 100644
--- a/compiler/rustc_target/src/spec/linux_base.rs
+++ b/compiler/rustc_target/src/spec/linux_base.rs
@@ -1,4 +1,5 @@
-use crate::spec::{cvs, RelroLevel, TargetOptions};
+use crate::spec::{cvs, RelroLevel, SplitDebuginfo, TargetOptions};
+use std::borrow::Cow;
pub fn opts() -> TargetOptions {
TargetOptions {
@@ -10,6 +11,11 @@ pub fn opts() -> TargetOptions {
relro_level: RelroLevel::Full,
has_thread_local: true,
crt_static_respected: true,
+ supported_split_debuginfo: Cow::Borrowed(&[
+ SplitDebuginfo::Packed,
+ SplitDebuginfo::Unpacked,
+ SplitDebuginfo::Off,
+ ]),
..Default::default()
}
}
diff --git a/compiler/rustc_target/src/spec/linux_musl_base.rs b/compiler/rustc_target/src/spec/linux_musl_base.rs
index 207a87ab0..61553e71b 100644
--- a/compiler/rustc_target/src/spec/linux_musl_base.rs
+++ b/compiler/rustc_target/src/spec/linux_musl_base.rs
@@ -1,13 +1,13 @@
-use crate::spec::crt_objects::{self, CrtObjectsFallback};
+use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
use crate::spec::TargetOptions;
pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
base.env = "musl".into();
- base.pre_link_objects_fallback = crt_objects::pre_musl_fallback();
- base.post_link_objects_fallback = crt_objects::post_musl_fallback();
- base.crt_objects_fallback = Some(CrtObjectsFallback::Musl);
+ base.pre_link_objects_self_contained = crt_objects::pre_musl_self_contained();
+ base.post_link_objects_self_contained = crt_objects::post_musl_self_contained();
+ base.link_self_contained = LinkSelfContainedDefault::Musl;
// These targets statically link libc by default
base.crt_static_default = true;
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index f7abeafd3..dc16739bd 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -37,7 +37,7 @@
use crate::abi::Endian;
use crate::json::{Json, ToJson};
use crate::spec::abi::{lookup as lookup_abi, Abi};
-use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::symbol::{sym, Symbol};
@@ -92,14 +92,24 @@ mod windows_uwp_msvc_base;
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LinkerFlavor {
- Em,
Gcc,
- L4Bender,
Ld,
+ Lld(LldFlavor),
Msvc,
+ EmCc,
+ Bpf,
+ Ptx,
+}
+
+#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
+pub enum LinkerFlavorCli {
+ Gcc,
+ Ld,
Lld(LldFlavor),
- PtxLinker,
+ Msvc,
+ Em,
BpfLinker,
+ PtxLinker,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@@ -137,19 +147,40 @@ impl ToJson for LldFlavor {
}
}
-impl ToJson for LinkerFlavor {
- fn to_json(&self) -> Json {
- self.desc().to_json()
+impl LinkerFlavor {
+ pub fn from_cli(cli: LinkerFlavorCli) -> LinkerFlavor {
+ match cli {
+ LinkerFlavorCli::Gcc => LinkerFlavor::Gcc,
+ LinkerFlavorCli::Ld => LinkerFlavor::Ld,
+ LinkerFlavorCli::Lld(lld_flavor) => LinkerFlavor::Lld(lld_flavor),
+ LinkerFlavorCli::Msvc => LinkerFlavor::Msvc,
+ LinkerFlavorCli::Em => LinkerFlavor::EmCc,
+ LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf,
+ LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx,
+ }
+ }
+
+ fn to_cli(self) -> LinkerFlavorCli {
+ match self {
+ LinkerFlavor::Gcc => LinkerFlavorCli::Gcc,
+ LinkerFlavor::Ld => LinkerFlavorCli::Ld,
+ LinkerFlavor::Lld(lld_flavor) => LinkerFlavorCli::Lld(lld_flavor),
+ LinkerFlavor::Msvc => LinkerFlavorCli::Msvc,
+ LinkerFlavor::EmCc => LinkerFlavorCli::Em,
+ LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker,
+ LinkerFlavor::Ptx => LinkerFlavorCli::PtxLinker,
+ }
}
}
-macro_rules! flavor_mappings {
- ($((($($flavor:tt)*), $string:expr),)*) => (
- impl LinkerFlavor {
+
+macro_rules! linker_flavor_cli_impls {
+ ($(($($flavor:tt)*) $string:literal)*) => (
+ impl LinkerFlavorCli {
pub const fn one_of() -> &'static str {
concat!("one of: ", $($string, " ",)*)
}
- pub fn from_str(s: &str) -> Option<Self> {
+ pub fn from_str(s: &str) -> Option<LinkerFlavorCli> {
Some(match s {
$($string => $($flavor)*,)*
_ => return None,
@@ -165,18 +196,23 @@ macro_rules! flavor_mappings {
)
}
-flavor_mappings! {
- ((LinkerFlavor::Em), "em"),
- ((LinkerFlavor::Gcc), "gcc"),
- ((LinkerFlavor::L4Bender), "l4-bender"),
- ((LinkerFlavor::Ld), "ld"),
- ((LinkerFlavor::Msvc), "msvc"),
- ((LinkerFlavor::PtxLinker), "ptx-linker"),
- ((LinkerFlavor::BpfLinker), "bpf-linker"),
- ((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"),
- ((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"),
- ((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"),
- ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"),
+linker_flavor_cli_impls! {
+ (LinkerFlavorCli::Gcc) "gcc"
+ (LinkerFlavorCli::Ld) "ld"
+ (LinkerFlavorCli::Lld(LldFlavor::Ld)) "ld.lld"
+ (LinkerFlavorCli::Lld(LldFlavor::Ld64)) "ld64.lld"
+ (LinkerFlavorCli::Lld(LldFlavor::Link)) "lld-link"
+ (LinkerFlavorCli::Lld(LldFlavor::Wasm)) "wasm-ld"
+ (LinkerFlavorCli::Msvc) "msvc"
+ (LinkerFlavorCli::Em) "em"
+ (LinkerFlavorCli::BpfLinker) "bpf-linker"
+ (LinkerFlavorCli::PtxLinker) "ptx-linker"
+}
+
+impl ToJson for LinkerFlavorCli {
+ fn to_json(&self) -> Json {
+ self.desc().to_json()
+ }
}
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
@@ -467,8 +503,59 @@ impl fmt::Display for LinkOutputKind {
}
pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<StaticCow<str>>>;
+pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>;
+
+/// Which kind of debuginfo does the target use?
+///
+/// Useful in determining whether a target supports Split DWARF (a target with
+/// `DebuginfoKind::Dwarf` and supporting `SplitDebuginfo::Unpacked` for example).
+#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
+pub enum DebuginfoKind {
+ /// DWARF debuginfo (such as that used on `x86_64_unknown_linux_gnu`).
+ #[default]
+ Dwarf,
+ /// DWARF debuginfo in dSYM files (such as on Apple platforms).
+ DwarfDsym,
+ /// Program database files (such as on Windows).
+ Pdb,
+}
+
+impl DebuginfoKind {
+ fn as_str(&self) -> &'static str {
+ match self {
+ DebuginfoKind::Dwarf => "dwarf",
+ DebuginfoKind::DwarfDsym => "dwarf-dsym",
+ DebuginfoKind::Pdb => "pdb",
+ }
+ }
+}
+
+impl FromStr for DebuginfoKind {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "dwarf" => DebuginfoKind::Dwarf,
+ "dwarf-dsym" => DebuginfoKind::DwarfDsym,
+ "pdb" => DebuginfoKind::Pdb,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl ToJson for DebuginfoKind {
+ fn to_json(&self) -> Json {
+ self.as_str().to_json()
+ }
+}
-#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
+impl fmt::Display for DebuginfoKind {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(self.as_str())
+ }
+}
+
+#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub enum SplitDebuginfo {
/// Split debug-information is disabled, meaning that on supported platforms
/// you can find all debug information in the executable itself. This is
@@ -476,7 +563,8 @@ pub enum SplitDebuginfo {
///
/// * Windows - not supported
/// * macOS - don't run `dsymutil`
- /// * ELF - `.dwarf_*` sections
+ /// * ELF - `.debug_*` sections
+ #[default]
Off,
/// Split debug-information can be found in a "packed" location separate
@@ -484,7 +572,7 @@ pub enum SplitDebuginfo {
///
/// * Windows - `*.pdb`
/// * macOS - `*.dSYM` (run `dsymutil`)
- /// * ELF - `*.dwp` (run `rust-llvm-dwp`)
+ /// * ELF - `*.dwp` (run `thorin`)
Packed,
/// Split debug-information can be found in individual object files on the
@@ -509,7 +597,7 @@ impl SplitDebuginfo {
impl FromStr for SplitDebuginfo {
type Err = ();
- fn from_str(s: &str) -> Result<SplitDebuginfo, ()> {
+ fn from_str(s: &str) -> Result<Self, ()> {
Ok(match s {
"off" => SplitDebuginfo::Off,
"unpacked" => SplitDebuginfo::Unpacked,
@@ -786,15 +874,15 @@ impl fmt::Display for StackProtector {
}
macro_rules! supported_targets {
- ( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
+ ( $(($triple:literal, $module:ident ),)+ ) => {
$(mod $module;)+
/// List of supported targets
- pub const TARGETS: &[&str] = &[$($($triple),+),+];
+ pub const TARGETS: &[&str] = &[$($triple),+];
fn load_builtin(target: &str) -> Option<Target> {
let mut t = match target {
- $( $($triple)|+ => $module::target(), )+
+ $( $triple => $module::target(), )+
_ => return None,
};
t.is_builtin = true;
@@ -810,7 +898,7 @@ macro_rules! supported_targets {
$(
#[test] // `#[test]`
fn $module() {
- tests_impl::test_target(super::$module::target());
+ tests_impl::test_target(super::$module::target(), $triple);
}
)+
}
@@ -844,6 +932,7 @@ supported_targets! {
("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi),
("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf),
+ ("armeb-unknown-linux-gnueabi", armeb_unknown_linux_gnueabi),
("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi),
("arm-unknown-linux-musleabihf", arm_unknown_linux_musleabihf),
("armv4t-unknown-linux-gnueabi", armv4t_unknown_linux_gnueabi),
@@ -893,9 +982,11 @@ supported_targets! {
("aarch64-unknown-openbsd", aarch64_unknown_openbsd),
("i686-unknown-openbsd", i686_unknown_openbsd),
+ ("powerpc-unknown-openbsd", powerpc_unknown_openbsd),
+ ("powerpc64-unknown-openbsd", powerpc64_unknown_openbsd),
+ ("riscv64gc-unknown-openbsd", riscv64gc_unknown_openbsd),
("sparc64-unknown-openbsd", sparc64_unknown_openbsd),
("x86_64-unknown-openbsd", x86_64_unknown_openbsd),
- ("powerpc-unknown-openbsd", powerpc_unknown_openbsd),
("aarch64-unknown-netbsd", aarch64_unknown_netbsd),
("armv6-unknown-netbsd-eabihf", armv6_unknown_netbsd_eabihf),
@@ -1028,6 +1119,7 @@ supported_targets! {
("mipsel-sony-psp", mipsel_sony_psp),
("mipsel-unknown-none", mipsel_unknown_none),
("thumbv4t-none-eabi", thumbv4t_none_eabi),
+ ("armv4t-none-eabi", armv4t_none_eabi),
("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu),
("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32),
@@ -1156,48 +1248,54 @@ pub struct TargetOptions {
pub abi: StaticCow<str>,
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
pub vendor: StaticCow<str>,
- /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
- /// on the command line. Defaults to `LinkerFlavor::Gcc`.
- pub linker_flavor: LinkerFlavor,
/// Linker to invoke
pub linker: Option<StaticCow<str>>,
-
+ /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
+ /// on the command line. Defaults to `LinkerFlavor::Gcc`.
+ pub linker_flavor: LinkerFlavor,
+ linker_flavor_json: LinkerFlavorCli,
/// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker
/// without clarifying its flavor in any way.
+ /// FIXME: Merge this into `LinkerFlavor`.
pub lld_flavor: LldFlavor,
+ /// Whether the linker support GNU-like arguments such as -O. Defaults to true.
+ /// FIXME: Merge this into `LinkerFlavor`.
+ pub linker_is_gnu: bool,
- /// Linker arguments that are passed *before* any user-defined libraries.
- pub pre_link_args: LinkArgs,
/// Objects to link before and after all other object code.
pub pre_link_objects: CrtObjects,
pub post_link_objects: CrtObjects,
- /// Same as `(pre|post)_link_objects`, but when we fail to pull the objects with help of the
- /// target's native gcc and fall back to the "self-contained" mode and pull them manually.
- /// See `crt_objects.rs` for some more detailed documentation.
- pub pre_link_objects_fallback: CrtObjects,
- pub post_link_objects_fallback: CrtObjects,
- /// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
- pub crt_objects_fallback: Option<CrtObjectsFallback>,
+ /// Same as `(pre|post)_link_objects`, but when self-contained linking mode is enabled.
+ pub pre_link_objects_self_contained: CrtObjects,
+ pub post_link_objects_self_contained: CrtObjects,
+ pub link_self_contained: LinkSelfContainedDefault,
+ /// Linker arguments that are passed *before* any user-defined libraries.
+ pub pre_link_args: LinkArgs,
+ pre_link_args_json: LinkArgsCli,
/// Linker arguments that are unconditionally passed after any
/// user-defined but before post-link objects. Standard platform
/// libraries that should be always be linked to, usually go here.
pub late_link_args: LinkArgs,
+ late_link_args_json: LinkArgsCli,
/// Linker arguments used in addition to `late_link_args` if at least one
/// Rust dependency is dynamically linked.
pub late_link_args_dynamic: LinkArgs,
+ late_link_args_dynamic_json: LinkArgsCli,
/// Linker arguments used in addition to `late_link_args` if all Rust
/// dependencies are statically linked.
pub late_link_args_static: LinkArgs,
+ late_link_args_static_json: LinkArgsCli,
/// Linker arguments that are unconditionally passed *after* any
/// user-defined libraries.
pub post_link_args: LinkArgs,
+ post_link_args_json: LinkArgsCli,
+
/// Optional link script applied to `dylib` and `executable` crate types.
/// This is a string containing the script, not a path. Can only be applied
/// to linkers where `linker_is_gnu` is true.
pub link_script: Option<StaticCow<str>>,
-
/// Environment variables to be set for the linker invocation.
pub link_env: StaticCow<[(StaticCow<str>, StaticCow<str>)]>,
/// Environment variables to be removed for the linker invocation.
@@ -1254,6 +1352,8 @@ pub struct TargetOptions {
pub abi_return_struct_as_int: bool,
/// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS,
/// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
+ /// Also indiates whether to use Apple-specific ABI changes, such as extending function
+ /// parameters to 32-bits.
pub is_like_osx: bool,
/// Whether the target toolchain is like Solaris's.
/// Only useful for compiling against Illumos/Solaris,
@@ -1282,8 +1382,6 @@ pub struct TargetOptions {
/// Default supported version of DWARF on this platform.
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
pub default_dwarf_version: u32,
- /// Whether the linker support GNU-like arguments such as -O. Defaults to true.
- pub linker_is_gnu: bool,
/// The MinGW toolchain has a known issue that prevents it from correctly
/// handling COFF object files with more than 2<sup>15</sup> sections. Since each weak
/// symbol needs its own COMDAT section, weak linkage implies a large
@@ -1438,9 +1536,13 @@ pub struct TargetOptions {
/// thumb and arm interworking.
pub has_thumb_interworking: bool,
+ /// Which kind of debuginfo is used by this target?
+ pub debuginfo_kind: DebuginfoKind,
/// How to handle split debug information, if at all. Specifying `None` has
/// target-specific meaning.
pub split_debuginfo: SplitDebuginfo,
+ /// Which kinds of split debuginfo are supported by the target?
+ pub supported_split_debuginfo: StaticCow<[SplitDebuginfo]>,
/// The sanitizers supported by this target
///
@@ -1473,15 +1575,11 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
match flavor {
LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)),
LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)),
- LinkerFlavor::Lld(LldFlavor::Wasm) => {}
+ LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Lld(LldFlavor::Wasm) => {}
LinkerFlavor::Lld(lld_flavor) => {
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
}
- LinkerFlavor::Gcc
- | LinkerFlavor::Em
- | LinkerFlavor::L4Bender
- | LinkerFlavor::BpfLinker
- | LinkerFlavor::PtxLinker => {}
+ LinkerFlavor::Gcc | LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {}
}
}
@@ -1499,6 +1597,36 @@ impl TargetOptions {
fn add_post_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
add_link_args(&mut self.post_link_args, flavor, args);
}
+
+ fn update_from_cli(&mut self) {
+ self.linker_flavor = LinkerFlavor::from_cli(self.linker_flavor_json);
+ for (args, args_json) in [
+ (&mut self.pre_link_args, &self.pre_link_args_json),
+ (&mut self.late_link_args, &self.late_link_args_json),
+ (&mut self.late_link_args_dynamic, &self.late_link_args_dynamic_json),
+ (&mut self.late_link_args_static, &self.late_link_args_static_json),
+ (&mut self.post_link_args, &self.post_link_args_json),
+ ] {
+ *args = args_json
+ .iter()
+ .map(|(flavor, args)| (LinkerFlavor::from_cli(*flavor), args.clone()))
+ .collect();
+ }
+ }
+
+ fn update_to_cli(&mut self) {
+ self.linker_flavor_json = self.linker_flavor.to_cli();
+ for (args, args_json) in [
+ (&self.pre_link_args, &mut self.pre_link_args_json),
+ (&self.late_link_args, &mut self.late_link_args_json),
+ (&self.late_link_args_dynamic, &mut self.late_link_args_dynamic_json),
+ (&self.late_link_args_static, &mut self.late_link_args_static_json),
+ (&self.post_link_args, &mut self.post_link_args_json),
+ ] {
+ *args_json =
+ args.iter().map(|(flavor, args)| (flavor.to_cli(), args.clone())).collect();
+ }
+ }
}
impl Default for TargetOptions {
@@ -1513,11 +1641,11 @@ impl Default for TargetOptions {
env: "".into(),
abi: "".into(),
vendor: "unknown".into(),
- linker_flavor: LinkerFlavor::Gcc,
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()),
+ linker_flavor: LinkerFlavor::Gcc,
+ linker_flavor_json: LinkerFlavorCli::Gcc,
lld_flavor: LldFlavor::Ld,
- pre_link_args: LinkArgs::new(),
- post_link_args: LinkArgs::new(),
+ linker_is_gnu: true,
link_script: None,
asm_args: cvs![],
cpu: "generic".into(),
@@ -1544,7 +1672,6 @@ impl Default for TargetOptions {
is_like_msvc: false,
is_like_wasm: false,
default_dwarf_version: 4,
- linker_is_gnu: true,
allows_weak_linkage: true,
has_rpath: false,
no_default_libraries: true,
@@ -1554,12 +1681,19 @@ impl Default for TargetOptions {
relro_level: RelroLevel::None,
pre_link_objects: Default::default(),
post_link_objects: Default::default(),
- pre_link_objects_fallback: Default::default(),
- post_link_objects_fallback: Default::default(),
- crt_objects_fallback: None,
+ pre_link_objects_self_contained: Default::default(),
+ post_link_objects_self_contained: Default::default(),
+ link_self_contained: LinkSelfContainedDefault::False,
+ pre_link_args: LinkArgs::new(),
+ pre_link_args_json: LinkArgsCli::new(),
late_link_args: LinkArgs::new(),
+ late_link_args_json: LinkArgsCli::new(),
late_link_args_dynamic: LinkArgs::new(),
+ late_link_args_dynamic_json: LinkArgsCli::new(),
late_link_args_static: LinkArgs::new(),
+ late_link_args_static_json: LinkArgsCli::new(),
+ post_link_args: LinkArgs::new(),
+ post_link_args_json: LinkArgsCli::new(),
link_env: cvs![],
link_env_remove: cvs![],
archive_format: "gnu".into(),
@@ -1598,7 +1732,10 @@ impl Default for TargetOptions {
use_ctors_section: false,
eh_frame_header: true,
has_thumb_interworking: false,
- split_debuginfo: SplitDebuginfo::Off,
+ debuginfo_kind: Default::default(),
+ split_debuginfo: Default::default(),
+ // `Off` is supported by default, but targets can remove this manually, e.g. Windows.
+ supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
supported_sanitizers: SanitizerSet::empty(),
default_adjusted_cabi: None,
c_enum_min_bits: 32,
@@ -1871,6 +2008,19 @@ impl Target {
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
+ ($key_name:ident, DebuginfoKind) => ( {
+ let name = (stringify!($key_name)).replace("_", "-");
+ obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
+ match s.parse::<DebuginfoKind>() {
+ Ok(level) => base.$key_name = level,
+ _ => return Some(Err(
+ format!("'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
+ 'dwarf-dsym' or 'pdb'.")
+ )),
+ }
+ Some(Ok(()))
+ })).unwrap_or(Ok(()))
+ } );
($key_name:ident, SplitDebuginfo) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@@ -1907,6 +2057,25 @@ impl Target {
}
}
} );
+ ($key_name:ident, falliable_list) => ( {
+ let name = (stringify!($key_name)).replace("_", "-");
+ obj.remove(&name).and_then(|j| {
+ if let Some(v) = j.as_array() {
+ match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() {
+ Ok(l) => { base.$key_name = l },
+ // FIXME: `falliable_list` can't re-use the `key!` macro for list
+ // elements and the error messages from that macro, so it has a bad
+ // generic message instead
+ Err(_) => return Some(Err(
+ format!("`{:?}` is not a valid value for `{}`", j, name)
+ )),
+ }
+ } else {
+ incorrect_type.push(name)
+ }
+ Some(Ok(()))
+ }).unwrap_or(Ok(()))
+ } );
($key_name:ident, optional) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(o) = obj.remove(&name) {
@@ -1929,13 +2098,13 @@ impl Target {
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
- ($key_name:ident, LinkerFlavor) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match LinkerFlavor::from_str(s) {
+ ($key_name:ident = $json_name:expr, LinkerFlavor) => ( {
+ let name = $json_name;
+ obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
+ match LinkerFlavorCli::from_str(s) {
Some(linker_flavor) => base.$key_name = linker_flavor,
_ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \
- Use {}", s, LinkerFlavor::one_of()))),
+ Use {}", s, LinkerFlavorCli::one_of()))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
@@ -1977,20 +2146,20 @@ impl Target {
Ok::<(), String>(())
} );
- ($key_name:ident, crt_objects_fallback) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<CrtObjectsFallback>() {
- Ok(fallback) => base.$key_name = Some(fallback),
- _ => return Some(Err(format!("'{}' is not a valid CRT objects fallback. \
- Use 'musl', 'mingw' or 'wasm'", s))),
+ ($key_name:ident = $json_name:expr, link_self_contained) => ( {
+ let name = $json_name;
+ obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
+ match s.parse::<LinkSelfContainedDefault>() {
+ Ok(lsc_default) => base.$key_name = lsc_default,
+ _ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \
+ Use 'false', 'true', 'musl' or 'mingw'", s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
- ($key_name:ident, link_objects) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(val) = obj.remove(&name) {
+ ($key_name:ident = $json_name:expr, link_objects) => ( {
+ let name = $json_name;
+ if let Some(val) = obj.remove(name) {
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
JSON object with fields per CRT object kind.", name))?;
let mut args = CrtObjects::new();
@@ -2016,14 +2185,14 @@ impl Target {
base.$key_name = args;
}
} );
- ($key_name:ident, link_args) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(val) = obj.remove(&name) {
+ ($key_name:ident = $json_name:expr, link_args) => ( {
+ let name = $json_name;
+ if let Some(val) = obj.remove(name) {
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
JSON object with fields per linker-flavor.", name))?;
- let mut args = LinkArgs::new();
+ let mut args = LinkArgsCli::new();
for (k, v) in obj {
- let flavor = LinkerFlavor::from_str(&k).ok_or_else(|| {
+ let flavor = LinkerFlavorCli::from_str(&k).ok_or_else(|| {
format!("{}: '{}' is not a valid value for linker-flavor. \
Use 'em', 'gcc', 'ld' or 'msvc'", name, k)
})?;
@@ -2109,19 +2278,20 @@ impl Target {
key!(env);
key!(abi);
key!(vendor);
- key!(linker_flavor, LinkerFlavor)?;
key!(linker, optional);
+ key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?;
key!(lld_flavor, LldFlavor)?;
- key!(pre_link_objects, link_objects);
- key!(post_link_objects, link_objects);
- key!(pre_link_objects_fallback, link_objects);
- key!(post_link_objects_fallback, link_objects);
- key!(crt_objects_fallback, crt_objects_fallback)?;
- key!(pre_link_args, link_args);
- key!(late_link_args, link_args);
- key!(late_link_args_dynamic, link_args);
- key!(late_link_args_static, link_args);
- key!(post_link_args, link_args);
+ key!(linker_is_gnu, bool);
+ key!(pre_link_objects = "pre-link-objects", link_objects);
+ key!(post_link_objects = "post-link-objects", link_objects);
+ key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
+ key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
+ key!(link_self_contained = "crt-objects-fallback", link_self_contained)?;
+ key!(pre_link_args_json = "pre-link-args", link_args);
+ key!(late_link_args_json = "late-link-args", link_args);
+ key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args);
+ key!(late_link_args_static_json = "late-link-args-static", link_args);
+ key!(post_link_args_json = "post-link-args", link_args);
key!(link_script, optional);
key!(link_env, env);
key!(link_env_remove, list);
@@ -2149,7 +2319,6 @@ impl Target {
key!(is_like_msvc, bool);
key!(is_like_wasm, bool);
key!(default_dwarf_version, u32);
- key!(linker_is_gnu, bool);
key!(allows_weak_linkage, bool);
key!(has_rpath, bool);
key!(no_default_libraries, bool);
@@ -2193,7 +2362,9 @@ impl Target {
key!(use_ctors_section, bool);
key!(eh_frame_header, bool);
key!(has_thumb_interworking, bool);
+ key!(debuginfo_kind, DebuginfoKind)?;
key!(split_debuginfo, SplitDebuginfo)?;
+ key!(supported_split_debuginfo, falliable_list)?;
key!(supported_sanitizers, SanitizerSet)?;
key!(default_adjusted_cabi, Option<Abi>)?;
key!(c_enum_min_bits, u64);
@@ -2204,6 +2375,8 @@ impl Target {
// This can cause unfortunate ICEs later down the line.
return Err("may not set is_builtin for targets not built-in".into());
}
+ base.update_from_cli();
+
// Each field should have been read using `Json::remove` so any keys remaining are unused.
let remaining_keys = obj.keys();
Ok((
@@ -2219,7 +2392,7 @@ impl Target {
load_builtin(target_triple).expect("built-in target")
}
TargetTriple::TargetJson { .. } => {
- panic!("built-in targets doens't support target-paths")
+ panic!("built-in targets doesn't support target-paths")
}
}
}
@@ -2295,42 +2468,44 @@ impl ToJson for Target {
fn to_json(&self) -> Json {
let mut d = serde_json::Map::new();
let default: TargetOptions = Default::default();
+ let mut target = self.clone();
+ target.update_to_cli();
macro_rules! target_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
- d.insert(name, self.$attr.to_json());
+ d.insert(name, target.$attr.to_json());
}};
}
macro_rules! target_option_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
- if default.$attr != self.$attr {
- d.insert(name, self.$attr.to_json());
+ if default.$attr != target.$attr {
+ d.insert(name, target.$attr.to_json());
}
}};
- ($attr:ident, $key_name:expr) => {{
- let name = $key_name;
- if default.$attr != self.$attr {
- d.insert(name.into(), self.$attr.to_json());
+ ($attr:ident, $json_name:expr) => {{
+ let name = $json_name;
+ if default.$attr != target.$attr {
+ d.insert(name.into(), target.$attr.to_json());
}
}};
- (link_args - $attr:ident) => {{
- let name = (stringify!($attr)).replace("_", "-");
- if default.$attr != self.$attr {
- let obj = self
+ (link_args - $attr:ident, $json_name:expr) => {{
+ let name = $json_name;
+ if default.$attr != target.$attr {
+ let obj = target
.$attr
.iter()
.map(|(k, v)| (k.desc().to_string(), v.clone()))
.collect::<BTreeMap<_, _>>();
- d.insert(name, obj.to_json());
+ d.insert(name.to_string(), obj.to_json());
}
}};
(env - $attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
- if default.$attr != self.$attr {
- let obj = self
+ if default.$attr != target.$attr {
+ let obj = target
.$attr
.iter()
.map(|&(ref k, ref v)| format!("{k}={v}"))
@@ -2352,19 +2527,20 @@ impl ToJson for Target {
target_option_val!(env);
target_option_val!(abi);
target_option_val!(vendor);
- target_option_val!(linker_flavor);
target_option_val!(linker);
+ target_option_val!(linker_flavor_json, "linker-flavor");
target_option_val!(lld_flavor);
+ target_option_val!(linker_is_gnu);
target_option_val!(pre_link_objects);
target_option_val!(post_link_objects);
- target_option_val!(pre_link_objects_fallback);
- target_option_val!(post_link_objects_fallback);
- target_option_val!(crt_objects_fallback);
- target_option_val!(link_args - pre_link_args);
- target_option_val!(link_args - late_link_args);
- target_option_val!(link_args - late_link_args_dynamic);
- target_option_val!(link_args - late_link_args_static);
- target_option_val!(link_args - post_link_args);
+ target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback");
+ target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback");
+ target_option_val!(link_self_contained, "crt-objects-fallback");
+ target_option_val!(link_args - pre_link_args_json, "pre-link-args");
+ target_option_val!(link_args - late_link_args_json, "late-link-args");
+ target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic");
+ target_option_val!(link_args - late_link_args_static_json, "late-link-args-static");
+ target_option_val!(link_args - post_link_args_json, "post-link-args");
target_option_val!(link_script);
target_option_val!(env - link_env);
target_option_val!(link_env_remove);
@@ -2393,7 +2569,6 @@ impl ToJson for Target {
target_option_val!(is_like_msvc);
target_option_val!(is_like_wasm);
target_option_val!(default_dwarf_version);
- target_option_val!(linker_is_gnu);
target_option_val!(allows_weak_linkage);
target_option_val!(has_rpath);
target_option_val!(no_default_libraries);
@@ -2437,7 +2612,9 @@ impl ToJson for Target {
target_option_val!(use_ctors_section);
target_option_val!(eh_frame_header);
target_option_val!(has_thumb_interworking);
+ target_option_val!(debuginfo_kind);
target_option_val!(split_debuginfo);
+ target_option_val!(supported_split_debuginfo);
target_option_val!(supported_sanitizers);
target_option_val!(c_enum_min_bits);
target_option_val!(generate_arange_section);
diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs
index edb30b72b..b3cd38a6e 100644
--- a/compiler/rustc_target/src/spec/msvc_base.rs
+++ b/compiler/rustc_target/src/spec/msvc_base.rs
@@ -1,4 +1,5 @@
-use crate::spec::{LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
+use crate::spec::{DebuginfoKind, LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
+use std::borrow::Cow;
pub fn opts() -> TargetOptions {
// Suppress the verbose logo and authorship debugging output, which would needlessly
@@ -18,6 +19,8 @@ pub fn opts() -> TargetOptions {
// Currently this is the only supported method of debuginfo on MSVC
// where `*.pdb` files show up next to the final artifact.
split_debuginfo: SplitDebuginfo::Packed,
+ supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Packed]),
+ debuginfo_kind: DebuginfoKind::Pdb,
..Default::default()
}
diff --git a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
index 1c5b68001..6ab3a8b7e 100644
--- a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
+++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
options: TargetOptions {
os: "cuda".into(),
vendor: "nvidia".into(),
- linker_flavor: LinkerFlavor::PtxLinker,
+ linker_flavor: LinkerFlavor::Ptx,
// The linker can be installed from `crates.io`.
linker: Some("rust-ptx-linker".into()),
linker_is_gnu: false,
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs
new file mode 100644
index 000000000..9cb3a67dc
--- /dev/null
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs
@@ -0,0 +1,17 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, Target, TargetOptions};
+
+pub fn target() -> Target {
+ let mut base = super::openbsd_base::opts();
+ base.cpu = "ppc64".into();
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
+ base.max_atomic_width = Some(64);
+
+ Target {
+ llvm_target: "powerpc64-unknown-openbsd".into(),
+ pointer_width: 64,
+ data_layout: "E-m:e-i64:64-n32:64".into(),
+ arch: "powerpc64".into(),
+ options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base },
+ }
+}
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
index 516b2de37..75ac66c27 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
@@ -1,5 +1,5 @@
use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
@@ -15,7 +15,6 @@ pub fn target() -> Target {
options: TargetOptions {
endian: Endian::Big,
features: "+secure-plt".into(),
- relocation_model: RelocModel::Pic,
mcount: "_mcount".into(),
..base
},
diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs
new file mode 100644
index 000000000..cd10f3afa
--- /dev/null
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs
@@ -0,0 +1,18 @@
+use crate::spec::{CodeModel, Target, TargetOptions};
+
+pub fn target() -> Target {
+ Target {
+ llvm_target: "riscv64-unknown-openbsd".into(),
+ pointer_width: 64,
+ data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
+ arch: "riscv64".into(),
+ options: TargetOptions {
+ code_model: Some(CodeModel::Medium),
+ cpu: "generic-rv64".into(),
+ features: "+m,+a,+f,+d,+c".into(),
+ llvm_abiname: "lp64d".into(),
+ max_atomic_width: Some(64),
+ ..super::openbsd_base::opts()
+ },
+ }
+}
diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index 1db6db78b..0af599916 100644
--- a/compiler/rustc_target/src/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
@@ -2,28 +2,31 @@ use super::super::*;
use std::assert_matches::assert_matches;
// Test target self-consistency and JSON encoding/decoding roundtrip.
-pub(super) fn test_target(target: Target) {
- target.check_consistency();
- assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target));
+pub(super) fn test_target(mut target: Target, triple: &str) {
+ let recycled_target = Target::from_json(target.to_json()).map(|(j, _)| j);
+ target.update_to_cli();
+ target.check_consistency(triple);
+ assert_eq!(recycled_target, Ok(target));
}
impl Target {
- fn check_consistency(&self) {
+ fn check_consistency(&self, triple: &str) {
assert_eq!(self.is_like_osx, self.vendor == "apple");
assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos");
assert_eq!(self.is_like_windows, self.os == "windows" || self.os == "uefi");
assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
- assert!(self.is_like_windows || !self.is_like_msvc);
+ if self.is_like_msvc {
+ assert!(self.is_like_windows);
+ }
// Check that default linker flavor and lld flavor are compatible
// with some other key properties.
assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64));
assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link));
assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm));
- assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender));
- assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em));
- assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker));
- assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker));
+ assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::EmCc));
+ assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf));
+ assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx));
for args in [
&self.pre_link_args,
@@ -63,17 +66,14 @@ impl Target {
LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
)
}
- (LinkerFlavor::L4Bender, LldFlavor::Ld) => {
- assert_matches!(flavor, LinkerFlavor::L4Bender)
- }
- (LinkerFlavor::Em, LldFlavor::Wasm) => {
- assert_matches!(flavor, LinkerFlavor::Em)
+ (LinkerFlavor::EmCc, LldFlavor::Wasm) => {
+ assert_matches!(flavor, LinkerFlavor::EmCc)
}
- (LinkerFlavor::BpfLinker, LldFlavor::Ld) => {
- assert_matches!(flavor, LinkerFlavor::BpfLinker)
+ (LinkerFlavor::Bpf, LldFlavor::Ld) => {
+ assert_matches!(flavor, LinkerFlavor::Bpf)
}
- (LinkerFlavor::PtxLinker, LldFlavor::Ld) => {
- assert_matches!(flavor, LinkerFlavor::PtxLinker)
+ (LinkerFlavor::Ptx, LldFlavor::Ld) => {
+ assert_matches!(flavor, LinkerFlavor::Ptx)
}
flavors => unreachable!("unexpected flavor combination: {:?}", flavors),
}
@@ -94,8 +94,9 @@ impl Target {
check_noncc(LinkerFlavor::Ld);
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
}
+ LldFlavor::Ld64 => check_noncc(LinkerFlavor::Lld(LldFlavor::Ld64)),
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
- LldFlavor::Ld64 | LldFlavor::Link => {}
+ LldFlavor::Link => {}
},
_ => {}
}
@@ -109,20 +110,57 @@ impl Target {
);
}
- assert!(
- (self.pre_link_objects_fallback.is_empty()
- && self.post_link_objects_fallback.is_empty())
- || self.crt_objects_fallback.is_some()
- );
+ if self.link_self_contained == LinkSelfContainedDefault::False {
+ assert!(
+ self.pre_link_objects_self_contained.is_empty()
+ && self.post_link_objects_self_contained.is_empty()
+ );
+ }
// If your target really needs to deviate from the rules below,
// except it and document the reasons.
// Keep the default "unknown" vendor instead.
assert_ne!(self.vendor, "");
+ assert_ne!(self.os, "");
if !self.can_use_os_unknown() {
// Keep the default "none" for bare metal targets instead.
assert_ne!(self.os, "unknown");
}
+
+ // Check dynamic linking stuff
+ // BPF: when targeting user space vms (like rbpf), those can load dynamic libraries.
+ if self.os == "none" && self.arch != "bpf" {
+ assert!(!self.dynamic_linking);
+ }
+ if self.only_cdylib
+ || self.crt_static_allows_dylibs
+ || !self.late_link_args_dynamic.is_empty()
+ {
+ assert!(self.dynamic_linking);
+ }
+ // Apparently PIC was slow on wasm at some point, see comments in wasm_base.rs
+ if self.dynamic_linking && !(self.is_like_wasm && self.os != "emscripten") {
+ assert_eq!(self.relocation_model, RelocModel::Pic);
+ }
+ // PIEs are supported but not enabled by default with linuxkernel target.
+ if self.position_independent_executables && !triple.ends_with("-linuxkernel") {
+ assert_eq!(self.relocation_model, RelocModel::Pic);
+ }
+ // The UEFI targets do not support dynamic linking but still require PIC (#101377).
+ if self.relocation_model == RelocModel::Pic && self.os != "uefi" {
+ assert!(self.dynamic_linking || self.position_independent_executables);
+ }
+ if self.static_position_independent_executables {
+ assert!(self.position_independent_executables);
+ }
+ if self.position_independent_executables {
+ assert!(self.executables);
+ }
+
+ // Check crt static stuff
+ if self.crt_static_default || self.crt_static_allows_dylibs {
+ assert!(self.crt_static_respected);
+ }
}
// Add your target to the whitelist if it has `std` library
diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
index 7125d141a..bdaaed8b5 100644
--- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
@@ -47,7 +47,9 @@ pub fn target() -> Target {
asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
// minimum extra features, these cannot be disabled via -C
- features: "+soft-float,+strict-align".into(),
+ // Also force-enable 32-bit atomics, which allows the use of atomic load/store only.
+ // The resulting atomics are ABI incompatible with atomics backed by libatomic.
+ features: "+soft-float,+strict-align,+atomics-32".into(),
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
index 2546ab9b7..c9bb0112f 100644
--- a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
@@ -13,7 +13,9 @@ pub fn target() -> Target {
abi: "eabi".into(),
// The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them
// with +strict-align.
- features: "+strict-align".into(),
+ // Also force-enable 32-bit atomics, which allows the use of atomic load/store only.
+ // The resulting atomics are ABI incompatible with atomics backed by libatomic.
+ features: "+strict-align,+atomics-32".into(),
// There are no atomic CAS instructions available in the instruction set of the ARMv6-M
// architecture
atomic_cas: false,
diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
index aee8eb2e3..99af7d85e 100644
--- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
@@ -9,7 +9,8 @@
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
// code runs in the same environment, no process separation is supported.
-use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, TargetOptions};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy};
+use crate::spec::{StackProbeType, TargetOptions};
pub fn opts() -> TargetOptions {
let mut base = super::msvc_base::opts();
diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
index c7e7d2210..6f77ef98c 100644
--- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
@@ -5,13 +5,13 @@ pub fn target() -> Target {
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
let pre_link_args = LinkArgs::new();
let post_link_args = TargetOptions::link_args(
- LinkerFlavor::Em,
+ LinkerFlavor::EmCc,
&["-sABORTING_MALLOC=0", "-Wl,--fatal-warnings"],
);
let opts = TargetOptions {
os: "emscripten".into(),
- linker_flavor: LinkerFlavor::Em,
+ linker_flavor: LinkerFlavor::EmCc,
// emcc emits two files - a .js file to instantiate the wasm and supply platform
// functionality, and a .wasm file.
exe_suffix: ".js".into(),
diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs
index 280457d68..9c30487f4 100644
--- a/compiler/rustc_target/src/spec/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs
@@ -82,8 +82,8 @@ pub fn target() -> Target {
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
- options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback();
- options.post_link_objects_fallback = crt_objects::post_wasi_fallback();
+ options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
+ options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
// Right now this is a bit of a workaround but we're currently saying that
// the target by default has a static crt which we're taking as a signal
diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs
index 9216d3e7b..28a07701e 100644
--- a/compiler/rustc_target/src/spec/wasm_base.rs
+++ b/compiler/rustc_target/src/spec/wasm_base.rs
@@ -1,4 +1,4 @@
-use super::crt_objects::CrtObjectsFallback;
+use super::crt_objects::LinkSelfContainedDefault;
use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
pub fn options() -> TargetOptions {
@@ -96,7 +96,8 @@ pub fn options() -> TargetOptions {
pre_link_args,
- crt_objects_fallback: Some(CrtObjectsFallback::Wasm),
+ // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
+ link_self_contained: LinkSelfContainedDefault::True,
// This has no effect in LLVM 8 or prior, but in LLVM 9 and later when
// PIC code is implemented this has quite a drastic effect if it stays
diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs
index 90e0af3e3..81d44a963 100644
--- a/compiler/rustc_target/src/spec/windows_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs
@@ -1,5 +1,6 @@
-use crate::spec::crt_objects::{self, CrtObjectsFallback};
-use crate::spec::{cvs, LinkerFlavor, TargetOptions};
+use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
+use crate::spec::{cvs, DebuginfoKind, LinkerFlavor, SplitDebuginfo, TargetOptions};
+use std::borrow::Cow;
pub fn opts() -> TargetOptions {
let mut pre_link_args = TargetOptions::link_args(
@@ -76,9 +77,9 @@ pub fn opts() -> TargetOptions {
pre_link_args,
pre_link_objects: crt_objects::pre_mingw(),
post_link_objects: crt_objects::post_mingw(),
- pre_link_objects_fallback: crt_objects::pre_mingw_fallback(),
- post_link_objects_fallback: crt_objects::post_mingw_fallback(),
- crt_objects_fallback: Some(CrtObjectsFallback::Mingw),
+ pre_link_objects_self_contained: crt_objects::pre_mingw_self_contained(),
+ post_link_objects_self_contained: crt_objects::post_mingw_self_contained(),
+ link_self_contained: LinkSelfContainedDefault::Mingw,
late_link_args,
late_link_args_dynamic,
late_link_args_static,
@@ -86,6 +87,10 @@ pub fn opts() -> TargetOptions {
emit_debug_gdb_scripts: false,
requires_uwtable: true,
eh_frame_header: false,
+ // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
+ // output DWO, despite using DWARF, doesn't use ELF..
+ debuginfo_kind: DebuginfoKind::Pdb,
+ supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
..Default::default()
}
}
diff --git a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs
index bae007dc9..f30be2549 100644
--- a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs
+++ b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs
@@ -3,7 +3,7 @@ use crate::spec::{cvs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
// We cannot use `-nodefaultlibs` because compiler-rt has to be passed
// as a path since it's not added to linker search path by the default.
- // There were attemts to make it behave like libgcc (so one can just use -l<name>)
+ // There were attempts to make it behave like libgcc (so one can just use -l<name>)
// but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
let pre_link_args =
TargetOptions::link_args(LinkerFlavor::Gcc, &["-nolibc", "--unwindlib=none"]);
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index dbd26899c..176c9dd6b 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -2,11 +2,12 @@ use crate::spec::TargetOptions;
use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, StackProbeType, Target};
pub fn target() -> Target {
- let mut base = super::apple_base::opts("macos");
+ let arch = "x86_64";
+ let mut base = super::apple_base::opts("macos", arch, "");
base.cpu = "core2".into();
base.max_atomic_width = Some(128); // core2 support cmpxchg16b
base.frame_pointer = FramePointer::Always;
- base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-arch", "x86_64"]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
@@ -16,7 +17,6 @@ pub fn target() -> Target {
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
- let arch = "x86_64";
let llvm_target = super::apple_base::macos_llvm_target(&arch);
Target {
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs
index 78189a0c0..26da7e800 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs
@@ -4,8 +4,6 @@ pub fn target() -> Target {
let mut base = super::l4re_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.crt_static_allows_dylibs = false;
- base.dynamic_linking = false;
base.panic_strategy = PanicStrategy::Abort;
Target {
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
index 809fd642d..b9a345127 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
@@ -4,10 +4,8 @@
// `target-cpu` compiler flags to opt-in more hardware-specific
// features.
-use super::{
- CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType,
- Target, TargetOptions,
-};
+use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy};
+use super::{RelroLevel, StackProbeType, Target, TargetOptions};
pub fn target() -> Target {
let opts = TargetOptions {
@@ -18,7 +16,6 @@ pub fn target() -> Target {
position_independent_executables: true,
static_position_independent_executables: true,
relro_level: RelroLevel::Full,
- relocation_model: RelocModel::Pic,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
linker: Some("rust-lld".into()),
features:
diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs
index 8b7e8984a..36ab8f3bd 100644
--- a/compiler/rustc_trait_selection/src/autoderef.rs
+++ b/compiler/rustc_trait_selection/src/autoderef.rs
@@ -1,6 +1,6 @@
+use crate::errors::AutoDerefReachedRecursionLimit;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{self, TraitEngine};
-use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_infer::infer::InferCtxt;
use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
@@ -222,19 +222,10 @@ pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Spa
Limit(0) => Limit(2),
limit => limit * 2,
};
- struct_span_err!(
- tcx.sess,
+ tcx.sess.emit_err(AutoDerefReachedRecursionLimit {
span,
- E0055,
- "reached the recursion limit while auto-dereferencing `{:?}`",
- ty
- )
- .span_label(span, "deref recursion limit reached")
- .help(&format!(
- "consider increasing the recursion limit by adding a \
- `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
+ ty,
suggested_limit,
- tcx.crate_name(LOCAL_CRATE),
- ))
- .emit();
+ crate_name: tcx.crate_name(LOCAL_CRATE),
+ });
}
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
new file mode 100644
index 000000000..ab0afc545
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -0,0 +1,102 @@
+use rustc_errors::{fluent, ErrorGuaranteed, Handler};
+use rustc_macros::SessionDiagnostic;
+use rustc_middle::ty::{PolyTraitRef, Ty, Unevaluated};
+use rustc_session::{Limit, SessionDiagnostic};
+use rustc_span::{Span, Symbol};
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::dump_vtable_entries)]
+pub struct DumpVTableEntries<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub trait_ref: PolyTraitRef<'a>,
+ pub entries: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::unable_to_construct_constant_value)]
+pub struct UnableToConstructConstantValue<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub unevaluated: Unevaluated<'a>,
+}
+
+#[derive(SessionDiagnostic)]
+#[help]
+#[diag(trait_selection::auto_deref_reached_recursion_limit, code = "E0055")]
+pub struct AutoDerefReachedRecursionLimit<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub ty: Ty<'a>,
+ pub suggested_limit: Limit,
+ pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+pub struct EmptyOnClauseInOnUnimplemented {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::invalid_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+pub struct InvalidOnClauseInOnUnimplemented {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::no_value_in_rustc_on_unimplemented, code = "E0232")]
+#[note]
+pub struct NoValueInOnUnimplemented {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+}
+
+pub struct NegativePositiveConflict<'a> {
+ pub impl_span: Span,
+ pub trait_desc: &'a str,
+ pub self_desc: &'a Option<String>,
+ pub negative_impl_span: Result<Span, Symbol>,
+ pub positive_impl_span: Result<Span, Symbol>,
+}
+
+impl SessionDiagnostic<'_> for NegativePositiveConflict<'_> {
+ fn into_diagnostic(
+ self,
+ handler: &Handler,
+ ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = handler.struct_err(fluent::trait_selection::negative_positive_conflict);
+ diag.set_arg("trait_desc", self.trait_desc);
+ diag.set_arg(
+ "self_desc",
+ self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty),
+ );
+ diag.set_span(self.impl_span);
+ diag.code(rustc_errors::error_code!(E0751));
+ match self.negative_impl_span {
+ Ok(span) => {
+ diag.span_label(span, fluent::trait_selection::negative_implementation_here);
+ }
+ Err(cname) => {
+ diag.note(fluent::trait_selection::negative_implementation_in_crate);
+ diag.set_arg("negative_impl_cname", cname.to_string());
+ }
+ }
+ match self.positive_impl_span {
+ Ok(span) => {
+ diag.span_label(span, fluent::trait_selection::positive_implementation_here);
+ }
+ Err(cname) => {
+ diag.note(fluent::trait_selection::positive_implementation_in_crate);
+ diag.set_arg("positive_impl_cname", cname.to_string());
+ }
+ }
+ diag
+ }
+}
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 9d30374f8..ba403ab2d 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -24,6 +24,13 @@ pub trait InferCtxtExt<'tcx> {
span: Span,
) -> bool;
+ fn type_is_sized_modulo_regions(
+ &self,
+ param_env: ty::ParamEnv<'tcx>,
+ ty: Ty<'tcx>,
+ span: Span,
+ ) -> bool;
+
fn partially_normalize_associated_types_in<T>(
&self,
cause: ObligationCause<'tcx>,
@@ -74,6 +81,16 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, copy_def_id, span)
}
+ fn type_is_sized_modulo_regions(
+ &self,
+ param_env: ty::ParamEnv<'tcx>,
+ ty: Ty<'tcx>,
+ span: Span,
+ ) -> bool {
+ let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
+ traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item, span)
+ }
+
/// Normalizes associated types in `value`, potentially returning
/// new obligations that must further be processed.
fn partially_normalize_associated_types_in<T>(
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 282ee632c..d35f74974 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -16,11 +16,12 @@
#![feature(control_flow_enum)]
#![feature(drain_filter)]
#![feature(hash_drain_filter)]
-#![feature(label_break_value)]
+#![cfg_attr(bootstrap, feature(label_break_value))]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(if_let_guard)]
#![feature(never_type)]
+#![feature(type_alias_impl_trait)]
#![recursion_limit = "512"] // For rustdoc
#[macro_use]
@@ -36,5 +37,6 @@ extern crate rustc_middle;
extern crate smallvec;
pub mod autoderef;
+pub mod errors;
pub mod infer;
pub mod traits;
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 294c81d0b..bcdfa4f12 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -3,13 +3,14 @@
use super::*;
+use crate::errors::UnableToConstructConstantValue;
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::InferCtxt;
use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{Region, RegionVid, Term};
+use rustc_middle::ty::{Region, RegionVid};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -205,10 +206,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// At this point, we already have all of the bounds we need. FulfillmentContext is used
// to store all of the necessary region/lifetime bounds in the InferContext, as well as
// an additional sanity check.
- let mut fulfill = <dyn TraitEngine<'tcx>>::new(tcx);
- fulfill.register_bound(&infcx, full_env, ty, trait_did, ObligationCause::dummy());
- let errors = fulfill.select_all_or_error(&infcx);
-
+ let errors =
+ super::fully_solve_bound(&infcx, ObligationCause::dummy(), full_env, ty, trait_did);
if !errors.is_empty() {
panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, errors);
}
@@ -343,7 +342,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
}
- let obligations = impl_source.clone().nested_obligations().into_iter();
+ let obligations = impl_source.borrow_nested_obligations().iter().cloned();
if !self.evaluate_nested_obligations(
ty,
@@ -613,7 +612,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
- if let Term::Ty(ty) = p.term().skip_binder() {
+ if let Some(ty) = p.term().skip_binder().ty() {
matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
} else {
false
@@ -832,8 +831,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
Ok(None) => {
let tcx = self.tcx;
let def_id = unevaluated.def.did;
- let reported = tcx.sess.struct_span_err(tcx.def_span(def_id), &format!("unable to construct a constant value for the unevaluated constant {:?}", unevaluated)).emit();
-
+ let reported =
+ tcx.sess.emit_err(UnableToConstructConstantValue {
+ span: tcx.def_span(def_id),
+ unevaluated: unevaluated.expand(),
+ });
Err(ErrorHandled::Reported(reported))
}
Err(err) => Err(err),
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs
index c0700748c..08adbcbd4 100644
--- a/compiler/rustc_trait_selection/src/traits/codegen.rs
+++ b/compiler/rustc_trait_selection/src/traits/codegen.rs
@@ -18,8 +18,7 @@ use rustc_middle::ty::{self, TyCtxt};
/// obligations *could be* resolved if we wanted to.
///
/// This also expects that `trait_ref` is fully normalized.
-#[instrument(level = "debug", skip(tcx))]
-pub fn codegen_fulfill_obligation<'tcx>(
+pub fn codegen_select_candidate<'tcx>(
tcx: TyCtxt<'tcx>,
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
@@ -74,7 +73,6 @@ pub fn codegen_fulfill_obligation<'tcx>(
// (ouz-a) This is required for `type-alias-impl-trait/assoc-projection-ice.rs` to pass
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
- debug!("Cache miss: {trait_ref:?} => {impl_source:?}");
Ok(&*tcx.arena.alloc(impl_source))
})
}
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 1c8cdf4ca..292787d4d 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -6,18 +6,20 @@
use crate::infer::outlives::env::OutlivesEnvironment;
use crate::infer::{CombinedSnapshot, InferOk};
+use crate::traits::outlives_bounds::InferCtxtExt as _;
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::util::impl_subject_and_oblig;
use crate::traits::SkipLeakCheck;
use crate::traits::{
- self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
- PredicateObligations, SelectionContext, TraitEngineExt,
+ self, Normalized, Obligation, ObligationCause, ObligationCtxt, PredicateObligation,
+ PredicateObligations, SelectionContext,
};
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic;
-use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::CRATE_HIR_ID;
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::{util, TraitEngine};
+use rustc_infer::traits::util;
use rustc_middle::traits::specialization_graph::OverlapMode;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::subst::Subst;
@@ -302,13 +304,18 @@ fn negative_impl<'cx, 'tcx>(
let impl_env = tcx.param_env(impl1_def_id);
let subject1 = match traits::fully_normalize(
&infcx,
- FulfillmentContext::new(),
ObligationCause::dummy(),
impl_env,
tcx.impl_subject(impl1_def_id),
) {
Ok(s) => s,
- Err(err) => bug!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+ Err(err) => {
+ tcx.sess.delay_span_bug(
+ tcx.def_span(impl1_def_id),
+ format!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+ );
+ return false;
+ }
};
// Attempt to prove that impl2 applies, given all of the above.
@@ -317,7 +324,7 @@ fn negative_impl<'cx, 'tcx>(
let (subject2, obligations) =
impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs);
- !equate(&infcx, impl_env, subject1, subject2, obligations)
+ !equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id)
})
}
@@ -327,6 +334,7 @@ fn equate<'cx, 'tcx>(
subject1: ImplSubject<'tcx>,
subject2: ImplSubject<'tcx>,
obligations: impl Iterator<Item = PredicateObligation<'tcx>>,
+ body_def_id: DefId,
) -> bool {
// do the impls unify? If not, not disjoint.
let Ok(InferOk { obligations: more_obligations, .. }) =
@@ -340,7 +348,7 @@ fn equate<'cx, 'tcx>(
let opt_failing_obligation = obligations
.into_iter()
.chain(more_obligations)
- .find(|o| negative_impl_exists(selcx, impl_env, o));
+ .find(|o| negative_impl_exists(selcx, o, body_def_id));
if let Some(failing_obligation) = opt_failing_obligation {
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
@@ -354,18 +362,16 @@ fn equate<'cx, 'tcx>(
#[instrument(level = "debug", skip(selcx))]
fn negative_impl_exists<'cx, 'tcx>(
selcx: &SelectionContext<'cx, 'tcx>,
- param_env: ty::ParamEnv<'tcx>,
o: &PredicateObligation<'tcx>,
+ body_def_id: DefId,
) -> bool {
- let infcx = &selcx.infcx().fork();
-
- if resolve_negative_obligation(infcx, param_env, o) {
+ if resolve_negative_obligation(selcx.infcx().fork(), o, body_def_id) {
return true;
}
// Try to prove a negative obligation exists for super predicates
- for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) {
- if resolve_negative_obligation(infcx, param_env, &o) {
+ for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) {
+ if resolve_negative_obligation(selcx.infcx().fork(), &o, body_def_id) {
return true;
}
}
@@ -375,9 +381,9 @@ fn negative_impl_exists<'cx, 'tcx>(
#[instrument(level = "debug", skip(infcx))]
fn resolve_negative_obligation<'cx, 'tcx>(
- infcx: &InferCtxt<'cx, 'tcx>,
- param_env: ty::ParamEnv<'tcx>,
+ infcx: InferCtxt<'cx, 'tcx>,
o: &PredicateObligation<'tcx>,
+ body_def_id: DefId,
) -> bool {
let tcx = infcx.tcx;
@@ -385,17 +391,25 @@ fn resolve_negative_obligation<'cx, 'tcx>(
return false;
};
- let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
- fulfillment_cx.register_predicate_obligation(infcx, o);
-
- let errors = fulfillment_cx.select_all_or_error(infcx);
-
- if !errors.is_empty() {
+ let param_env = o.param_env;
+ if !super::fully_solve_obligation(&infcx, o).is_empty() {
return false;
}
- // FIXME -- also add "assumed to be well formed" types into the `outlives_env`
- let outlives_env = OutlivesEnvironment::new(param_env);
+ let (body_id, body_def_id) = if let Some(body_def_id) = body_def_id.as_local() {
+ (tcx.hir().local_def_id_to_hir_id(body_def_id), body_def_id)
+ } else {
+ (CRATE_HIR_ID, CRATE_DEF_ID)
+ };
+
+ let ocx = ObligationCtxt::new(&infcx);
+ let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id);
+ let outlives_env = OutlivesEnvironment::with_bounds(
+ param_env,
+ Some(&infcx),
+ infcx.implied_bounds_tys(param_env, body_id, wf_tys),
+ );
+
infcx.process_registered_region_obligations(outlives_env.region_bound_pairs(), param_env);
infcx.resolve_regions(&outlives_env).is_empty()
@@ -404,12 +418,12 @@ fn resolve_negative_obligation<'cx, 'tcx>(
pub fn trait_ref_is_knowable<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
-) -> Option<Conflict> {
+) -> Result<(), Conflict> {
debug!("trait_ref_is_knowable(trait_ref={:?})", trait_ref);
if orphan_check_trait_ref(tcx, trait_ref, InCrate::Remote).is_ok() {
// A downstream or cousin crate is allowed to implement some
// substitution of this trait-ref.
- return Some(Conflict::Downstream);
+ return Err(Conflict::Downstream);
}
if trait_ref_is_local_or_fundamental(tcx, trait_ref) {
@@ -418,7 +432,7 @@ pub fn trait_ref_is_knowable<'tcx>(
// allowed to implement a substitution of this trait ref, which
// means impls could only come from dependencies of this crate,
// which we already know about.
- return None;
+ return Ok(());
}
// This is a remote non-fundamental trait, so if another crate
@@ -431,10 +445,10 @@ pub fn trait_ref_is_knowable<'tcx>(
// we are an owner.
if orphan_check_trait_ref(tcx, trait_ref, InCrate::Local).is_ok() {
debug!("trait_ref_is_knowable: orphan check passed");
- None
+ Ok(())
} else {
debug!("trait_ref_is_knowable: nonlocal, nonfundamental, unowned");
- Some(Conflict::Upstream)
+ Err(Conflict::Upstream)
}
}
@@ -740,7 +754,21 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
result
}
- // FIXME: Constants should participate in orphan checking.
+ /// All possible values for a constant parameter already exist
+ /// in the crate defining the trait, so they are always non-local[^1].
+ ///
+ /// Because there's no way to have an impl where the first local
+ /// generic argument is a constant, we also don't have to fail
+ /// the orphan check when encountering a parameter or a generic constant.
+ ///
+ /// This means that we can completely ignore constants during the orphan check.
+ ///
+ /// See `src/test/ui/coherence/const-generics-orphan-check-ok.rs` for examples.
+ ///
+ /// [^1]: This might not hold for function pointers or trait objects in the future.
+ /// As these should be quite rare as const arguments and especially rare as impl
+ /// parameters, allowing uncovered const parameters in impls seems more useful
+ /// than allowing `impl<T> Trait<local_fn_ptr, T> for i32` to compile.
fn visit_const(&mut self, _c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
ControlFlow::CONTINUE
}
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 254bc4ab6..5a213987e 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -183,7 +183,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
FailureKind::Concrete => {}
}
}
- let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
+ let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
match concrete {
Err(ErrorHandled::TooGeneric) => {
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
@@ -210,7 +210,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
// and hopefully soon change this to an error.
//
// See #74595 for more details about this.
- let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
+ let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
match concrete {
// If we're evaluating a foreign constant, under a nightly compiler without generic
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 6c177f638..dba4d4f69 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -3,7 +3,8 @@ use std::cell::RefCell;
use super::TraitEngine;
use super::{ChalkFulfillmentContext, FulfillmentContext};
use crate::infer::InferCtxtExt;
-use rustc_hir::def_id::DefId;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::{InferCtxt, InferOk};
use rustc_infer::traits::{
FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
@@ -12,9 +13,11 @@ use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::Span;
pub trait TraitEngineExt<'tcx> {
fn new(tcx: TyCtxt<'tcx>) -> Box<Self>;
+ fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box<Self>;
}
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
@@ -25,6 +28,14 @@ impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
Box::new(FulfillmentContext::new())
}
}
+
+ fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box<Self> {
+ if tcx.sess.opts.unstable_opts.chalk {
+ Box::new(ChalkFulfillmentContext::new())
+ } else {
+ Box::new(FulfillmentContext::new_in_snapshot())
+ }
+ }
}
/// Used if you want to have pleasant experience when dealing
@@ -39,6 +50,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new(infcx.tcx)) }
}
+ pub fn new_in_snapshot(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
+ Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new_in_snapshot(infcx.tcx)) }
+ }
+
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {
self.engine.borrow_mut().register_predicate_obligation(self.infcx, obligation);
}
@@ -109,4 +124,34 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
pub fn select_all_or_error(&self) -> Vec<FulfillmentError<'tcx>> {
self.engine.borrow_mut().select_all_or_error(self.infcx)
}
+
+ pub fn assumed_wf_types(
+ &self,
+ param_env: ty::ParamEnv<'tcx>,
+ span: Span,
+ def_id: LocalDefId,
+ ) -> FxHashSet<Ty<'tcx>> {
+ let tcx = self.infcx.tcx;
+ let assumed_wf_types = tcx.assumed_wf_types(def_id);
+ let mut implied_bounds = FxHashSet::default();
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+ let cause = ObligationCause::misc(span, hir_id);
+ for ty in assumed_wf_types {
+ // FIXME(@lcnr): rustc currently does not check wf for types
+ // pre-normalization, meaning that implied bounds are sometimes
+ // incorrect. See #100910 for more details.
+ //
+ // Not adding the unnormalized types here mostly fixes that, except
+ // that there are projections which are still ambiguous in the item definition
+ // but do normalize successfully when using the item, see #98543.
+ //
+ // Anyways, I will hopefully soon change implied bounds to make all of this
+ // sound and then uncomment this line again.
+
+ // implied_bounds.insert(ty);
+ let normalized = self.normalize(cause.clone(), param_env, ty);
+ implied_bounds.insert(normalized);
+ }
+ implied_bounds
+ }
}
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index e442c5c91..efdb1ace1 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -22,6 +22,7 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::GenericParam;
use rustc_hir::Item;
use rustc_hir::Node;
+use rustc_infer::infer::TypeTrace;
use rustc_infer::traits::TraitEngine;
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@@ -348,7 +349,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
message,
label,
note,
- enclosing_scope,
+ parent_label,
append_const_msg,
} = self.on_unimplemented_note(trait_ref, &obligation);
let have_alt_message = message.is_some() || label.is_some();
@@ -449,12 +450,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
{
"consider using `()`, or a `Result`".to_owned()
} else {
- format!(
- "{}the trait `{}` is not implemented for `{}`",
- pre_message,
- trait_predicate.print_modifiers_and_trait_path(),
- trait_ref.skip_binder().self_ty(),
- )
+ let ty_desc = match trait_ref.skip_binder().self_ty().kind() {
+ ty::FnDef(_, _) => Some("fn item"),
+ ty::Closure(_, _) => Some("closure"),
+ _ => None,
+ };
+
+ match ty_desc {
+ Some(desc) => format!(
+ "{}the trait `{}` is not implemented for {} `{}`",
+ pre_message,
+ trait_predicate.print_modifiers_and_trait_path(),
+ desc,
+ trait_ref.skip_binder().self_ty(),
+ ),
+ None => format!(
+ "{}the trait `{}` is not implemented for `{}`",
+ pre_message,
+ trait_predicate.print_modifiers_and_trait_path(),
+ trait_ref.skip_binder().self_ty(),
+ ),
+ }
};
if self.suggest_add_reference_to_arg(
@@ -514,7 +530,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
err.note(s.as_str());
}
- if let Some(ref s) = enclosing_scope {
+ if let Some(ref s) = parent_label {
let body = tcx
.hir()
.opt_local_def_id(obligation.cause.body_id)
@@ -523,11 +539,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
hir_id: obligation.cause.body_id,
})
});
-
- let enclosing_scope_span =
- tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(body));
-
- err.span_label(enclosing_scope_span, s);
+ err.span_label(tcx.def_span(body), s);
}
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
@@ -859,8 +871,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
- err.emit();
- return;
+ err
}
ty::PredicateKind::WellFormed(ty) => {
@@ -941,9 +952,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self.reported_closure_mismatch.borrow_mut().insert((span, found_span));
+ let mut not_tupled = false;
+
let found = match found_trait_ref.skip_binder().substs.type_at(1).kind() {
ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
- _ => vec![ArgKind::empty()],
+ _ => {
+ not_tupled = true;
+ vec![ArgKind::empty()]
+ }
};
let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
@@ -951,10 +967,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ty::Tuple(ref tys) => {
tys.iter().map(|t| ArgKind::from_expected_ty(t, Some(span))).collect()
}
- _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())],
+ _ => {
+ not_tupled = true;
+ vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())]
+ }
};
- if found.len() == expected.len() {
+ // If this is a `Fn` family trait and either the expected or found
+ // is not tupled, then fall back to just a regular mismatch error.
+ // This shouldn't be common unless manually implementing one of the
+ // traits manually, but don't make it more confusing when it does
+ // happen.
+ if Some(expected_trait_ref.def_id()) != tcx.lang_items().gen_trait() && not_tupled {
+ self.report_and_explain_type_error(
+ TypeTrace::poly_trait_refs(
+ &obligation.cause,
+ true,
+ expected_trait_ref,
+ found_trait_ref,
+ ),
+ ty::error::TypeError::Mismatch,
+ )
+ } else if found.len() == expected.len() {
self.report_closure_arg_mismatch(
span,
found_span,
@@ -1315,6 +1349,13 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
error: &MismatchedProjectionTypes<'tcx>,
);
+ fn maybe_detailed_projection_msg(
+ &self,
+ pred: ty::ProjectionPredicate<'tcx>,
+ normalized_ty: ty::Term<'tcx>,
+ expected_ty: ty::Term<'tcx>,
+ ) -> Option<String>;
+
fn fuzzy_match_tys(
&self,
a: Ty<'tcx>,
@@ -1476,13 +1517,28 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
.emit();
}
FulfillmentErrorCode::CodeConstEquateError(ref expected_found, ref err) => {
- self.report_mismatched_consts(
+ let mut diag = self.report_mismatched_consts(
&error.obligation.cause,
expected_found.expected,
expected_found.found,
err.clone(),
- )
- .emit();
+ );
+ let code = error.obligation.cause.code().peel_derives().peel_match_impls();
+ if let ObligationCauseCode::BindingObligation(..)
+ | ObligationCauseCode::ItemObligation(..)
+ | ObligationCauseCode::ExprBindingObligation(..)
+ | ObligationCauseCode::ExprItemObligation(..) = code
+ {
+ self.note_obligation_cause_code(
+ &mut diag,
+ &error.obligation.predicate,
+ error.obligation.param_env,
+ code,
+ &mut vec![],
+ &mut Default::default(),
+ );
+ }
+ diag.emit();
}
}
}
@@ -1500,8 +1556,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
}
self.probe(|_| {
- let err_buf;
- let mut err = &error.err;
+ let mut err = error.err;
let mut values = None;
// try to find the mismatched types to report the error with.
@@ -1534,31 +1589,28 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code().peel_derives(),
ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::BindingObligation(_, _)
+ | ObligationCauseCode::ExprItemObligation(..)
+ | ObligationCauseCode::ExprBindingObligation(..)
| ObligationCauseCode::ObjectCastObligation(..)
| ObligationCauseCode::OpaqueType
);
- if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
+ if let Err(new_err) = self.at(&obligation.cause, obligation.param_env).eq_exp(
is_normalized_ty_expected,
normalized_ty,
data.term,
) {
- values = Some(infer::ValuePairs::Terms(ExpectedFound::new(
- is_normalized_ty_expected,
- normalized_ty,
- data.term,
- )));
- err_buf = error;
- err = &err_buf;
+ values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
+ err = new_err;
}
}
- let mut diag = struct_span_err!(
- self.tcx.sess,
- obligation.cause.span,
- E0271,
- "type mismatch resolving `{}`",
- predicate
- );
+ let msg = values
+ .and_then(|(predicate, _, normalized_ty, expected_ty)| {
+ self.maybe_detailed_projection_msg(predicate, normalized_ty, expected_ty)
+ })
+ .unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
+ let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
+
let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Projection(proj) => self
.tcx
@@ -1596,7 +1648,13 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
&mut diag,
&obligation.cause,
secondary_span,
- values,
+ values.map(|(_, is_normalized_ty_expected, normalized_ty, term)| {
+ infer::ValuePairs::Terms(ExpectedFound::new(
+ is_normalized_ty_expected,
+ normalized_ty,
+ term,
+ ))
+ }),
err,
true,
false,
@@ -1606,6 +1664,33 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
});
}
+ fn maybe_detailed_projection_msg(
+ &self,
+ pred: ty::ProjectionPredicate<'tcx>,
+ normalized_ty: ty::Term<'tcx>,
+ expected_ty: ty::Term<'tcx>,
+ ) -> Option<String> {
+ let trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
+ let self_ty = pred.projection_ty.self_ty();
+
+ if Some(pred.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output() {
+ Some(format!(
+ "expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it returns `{normalized_ty}`",
+ fn_kind = self_ty.prefix_string(self.tcx)
+ ))
+ } else if Some(trait_def_id) == self.tcx.lang_items().future_trait() {
+ Some(format!(
+ "expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it resolves to `{normalized_ty}`"
+ ))
+ } else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) {
+ Some(format!(
+ "expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it yields `{normalized_ty}`"
+ ))
+ } else {
+ None
+ }
+ }
+
fn fuzzy_match_tys(
&self,
mut a: Ty<'tcx>,
@@ -1731,13 +1816,21 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
return false;
}
if candidates.len() == 1 {
+ let ty_desc = match candidates[0].self_ty().kind() {
+ ty::FnPtr(_) => Some("fn pointer"),
+ _ => None,
+ };
+ let the_desc = match ty_desc {
+ Some(desc) => format!(" implemented for {} `", desc),
+ None => " implemented for `".to_string(),
+ };
err.highlighted_help(vec![
(
format!("the trait `{}` ", candidates[0].print_only_trait_path()),
Style::NoStyle,
),
("is".to_string(), Style::Highlight),
- (" implemented for `".to_string(), Style::NoStyle),
+ (the_desc, Style::NoStyle),
(candidates[0].self_ty().to_string(), Style::Highlight),
("`".to_string(), Style::NoStyle),
]);
@@ -1802,9 +1895,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
// FIXME(compiler-errors): This could be generalized, both to
// be more granular, and probably look past other `#[fundamental]`
// types, too.
- self.tcx
- .visibility(def.did())
- .is_accessible_from(body_id.owner.to_def_id(), self.tcx)
+ self.tcx.visibility(def.did()).is_accessible_from(body_id.owner, self.tcx)
} else {
true
}
@@ -1940,7 +2031,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
let predicate = self.resolve_vars_if_possible(obligation.predicate);
let span = obligation.cause.span;
- debug!(?predicate, obligation.cause.code = tracing::field::debug(&obligation.cause.code()));
+ debug!(?predicate, obligation.cause.code = ?obligation.cause.code());
// Ambiguity errors are often caused as fallout from earlier errors.
// We ignore them if this `infcx` is tainted in some cases below.
@@ -2033,13 +2124,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
}
}
- if let ObligationCauseCode::ItemObligation(def_id) = *obligation.cause.code() {
+ if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
- } else if let (
- Ok(ref snippet),
- &ObligationCauseCode::BindingObligation(def_id, _),
- ) =
- (self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code())
+ } else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span)
+ && let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..)
+ = *obligation.cause.code()
{
let generics = self.tcx.generics_of(def_id);
if generics.params.iter().any(|p| p.name != kw::SelfUpper)
@@ -2119,12 +2208,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
&& let [
..,
trait_path_segment @ hir::PathSegment {
- res: Some(rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, trait_id)),
+ res: rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, trait_id),
..
},
hir::PathSegment {
ident: assoc_item_name,
- res: Some(rustc_hir::def::Res::Def(_, item_id)),
+ res: rustc_hir::def::Res::Def(_, item_id),
..
}
] = path.segments
@@ -2462,15 +2551,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
err: &mut Diagnostic,
obligation: &PredicateObligation<'tcx>,
) {
- let (
- ty::PredicateKind::Trait(pred),
- &ObligationCauseCode::BindingObligation(item_def_id, span),
- ) = (
- obligation.predicate.kind().skip_binder(),
- obligation.cause.code().peel_derives(),
- ) else {
- return;
- };
+ let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
+ let (ObligationCauseCode::BindingObligation(item_def_id, span)
+ | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
+ = *obligation.cause.code().peel_derives() else { return; };
debug!(?pred, ?item_def_id, ?span);
let (Some(node), true) = (
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index e6907637c..e11a42201 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -143,7 +143,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
if let ObligationCauseCode::ItemObligation(item)
- | ObligationCauseCode::BindingObligation(item, _) = *obligation.cause.code()
+ | ObligationCauseCode::BindingObligation(item, _)
+ | ObligationCauseCode::ExprItemObligation(item, ..)
+ | ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
{
// FIXME: maybe also have some way of handling methods
// from other traits? That would require name resolution,
@@ -254,7 +256,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
}
- if let ty::Dynamic(traits, _) = self_ty.kind() {
+ if let ty::Dynamic(traits, _, _) = self_ty.kind() {
for t in traits.iter() {
if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 219413121..13d9c1600 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -20,13 +20,12 @@ use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
-use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::hir::map;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, IsSuggestable,
- ProjectionPredicate, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
- TypeVisitable,
+ ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
};
use rustc_middle::ty::{TypeAndMut, TypeckResults};
use rustc_session::Limit;
@@ -174,7 +173,7 @@ pub trait InferCtxtExt<'tcx> {
&self,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
- proj_pred: Option<ty::PolyProjectionPredicate<'tcx>>,
+ associated_item: Option<(&'static str, Ty<'tcx>)>,
body_id: hir::HirId,
);
@@ -467,7 +466,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
&self,
mut err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
- proj_pred: Option<ty::PolyProjectionPredicate<'tcx>>,
+ associated_ty: Option<(&'static str, Ty<'tcx>)>,
body_id: hir::HirId,
) {
let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
@@ -604,21 +603,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_pred.print_modifiers_and_trait_path().to_string()
);
- if let Some(proj_pred) = proj_pred {
- let ProjectionPredicate { projection_ty, term } = proj_pred.skip_binder();
- let item = self.tcx.associated_item(projection_ty.item_def_id);
-
+ if let Some((name, term)) = associated_ty {
// FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
// That should be extracted into a helper function.
if constraint.ends_with('>') {
constraint = format!(
- "{}, {}={}>",
+ "{}, {} = {}>",
&constraint[..constraint.len() - 1],
- item.name,
+ name,
term
);
} else {
- constraint.push_str(&format!("<{}={}>", item.name, term));
+ constraint.push_str(&format!("<{} = {}>", name, term));
}
}
@@ -648,7 +644,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
..
}) if !param_ty => {
// Missing generic type parameter bound.
- if suggest_arbitrary_trait_bound(self.tcx, generics, &mut err, trait_pred) {
+ if suggest_arbitrary_trait_bound(
+ self.tcx,
+ generics,
+ &mut err,
+ trait_pred,
+ associated_ty,
+ ) {
return;
}
}
@@ -671,11 +673,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
// It only make sense when suggesting dereferences for arguments
- let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
- return false;
- };
- let param_env = obligation.param_env;
- let body_id = obligation.cause.body_id;
+ let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code()
+ else { return false; };
+ let Some(typeck_results) = self.in_progress_typeck_results
+ else { return false; };
+ let typeck_results = typeck_results.borrow();
+ let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id)
+ else { return false; };
+ let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr)
+ else { return false; };
+
let span = obligation.cause.span;
let mut real_trait_pred = trait_pred;
let mut code = obligation.cause.code();
@@ -685,11 +692,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
real_trait_pred = parent_trait_pred;
}
- // Skipping binder here, remapping below
- let real_ty = real_trait_pred.self_ty().skip_binder();
+ let real_ty = real_trait_pred.self_ty();
+ // We `erase_late_bound_regions` here because `make_subregion` does not handle
+ // `ReLateBound`, and we don't particularly care about the regions.
+ if self
+ .can_eq(obligation.param_env, self.tcx.erase_late_bound_regions(real_ty), arg_ty)
+ .is_err()
+ {
+ continue;
+ }
- if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
- let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span);
+ if let ty::Ref(region, base_ty, mutbl) = *real_ty.skip_binder().kind() {
+ let mut autoderef = Autoderef::new(
+ self,
+ obligation.param_env,
+ obligation.cause.body_id,
+ span,
+ base_ty,
+ span,
+ );
if let Some(steps) = autoderef.find_map(|(ty, steps)| {
// Re-add the `&`
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });
@@ -697,24 +718,29 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Remapping bound vars here
let real_trait_pred_and_ty =
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
- let obligation = self
- .mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred_and_ty);
+ let obligation = self.mk_trait_obligation_with_new_self_ty(
+ obligation.param_env,
+ real_trait_pred_and_ty,
+ );
Some(steps).filter(|_| self.predicate_may_hold(&obligation))
}) {
if steps > 0 {
- if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
- // Don't care about `&mut` because `DerefMut` is used less
- // often and user will not expect autoderef happens.
- if src.starts_with('&') && !src.starts_with("&mut ") {
- let derefs = "*".repeat(steps);
- err.span_suggestion(
- span,
- "consider dereferencing here",
- format!("&{}{}", derefs, &src[1..]),
- Applicability::MachineApplicable,
- );
- return true;
- }
+ // Don't care about `&mut` because `DerefMut` is used less
+ // often and user will not expect autoderef happens.
+ if let Some(hir::Node::Expr(hir::Expr {
+ kind:
+ hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr),
+ ..
+ })) = self.tcx.hir().find(*arg_hir_id)
+ {
+ let derefs = "*".repeat(steps);
+ err.span_suggestion_verbose(
+ expr.span.shrink_to_lo(),
+ "consider dereferencing here",
+ derefs,
+ Applicability::MachineApplicable,
+ );
+ return true;
}
}
} else if real_trait_pred != trait_pred {
@@ -724,7 +750,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let real_trait_pred_and_base_ty =
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty));
let obligation = self.mk_trait_obligation_with_new_self_ty(
- param_env,
+ obligation.param_env,
real_trait_pred_and_base_ty,
);
if self.predicate_may_hold(&obligation) {
@@ -750,7 +776,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Get the local name of this closure. This can be inaccurate because
// of the possibility of reassignment, but this should be good enough.
match &kind {
- hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) => {
+ hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, ident, None) => {
Some(ident.name)
}
_ => {
@@ -852,6 +878,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
_ => return false,
};
if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. })
+ && obligation.cause.span.can_be_used_for_suggestions()
{
// When the obligation error has been ensured to have been caused by
// an argument, the `obligation.cause.span` points at the expression
@@ -882,6 +909,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code()
{
&parent_code
+ } else if let ObligationCauseCode::ItemObligation(_)
+ | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
+ {
+ obligation.cause.code()
} else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) =
span.ctxt().outer_expn_data().kind
{
@@ -906,102 +937,121 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let param_env = obligation.param_env;
// Try to apply the original trait binding obligation by borrowing.
- let mut try_borrowing =
- |old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool {
- if blacklist.contains(&old_pred.def_id()) {
- return false;
- }
- // We map bounds to `&T` and `&mut T`
- let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| {
- (
- trait_pred,
- self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
- )
- });
- let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| {
+ let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
+ blacklist: &[DefId]|
+ -> bool {
+ if blacklist.contains(&old_pred.def_id()) {
+ return false;
+ }
+ // We map bounds to `&T` and `&mut T`
+ let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| {
+ (
+ trait_pred,
+ self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
+ )
+ });
+ let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| {
+ (
+ trait_pred,
+ self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
+ )
+ });
+
+ let mk_result = |trait_pred_and_new_ty| {
+ let obligation =
+ self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
+ self.predicate_must_hold_modulo_regions(&obligation)
+ };
+ let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
+ let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
+
+ let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
+ if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
+ && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind()
+ {
(
- trait_pred,
- self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
+ mk_result(old_pred.map_bound(|trait_pred| (trait_pred, *ty))),
+ matches!(mutability, hir::Mutability::Mut),
)
- });
-
- let mk_result = |trait_pred_and_new_ty| {
- let obligation =
- self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
- self.predicate_must_hold_modulo_regions(&obligation)
+ } else {
+ (false, false)
};
- let imm_result = mk_result(trait_pred_and_imm_ref);
- let mut_result = mk_result(trait_pred_and_mut_ref);
-
- if imm_result || mut_result {
- if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
- // We have a very specific type of error, where just borrowing this argument
- // might solve the problem. In cases like this, the important part is the
- // original type obligation, not the last one that failed, which is arbitrary.
- // Because of this, we modify the error to refer to the original obligation and
- // return early in the caller.
-
- let msg = format!("the trait bound `{}` is not satisfied", old_pred);
- if has_custom_message {
- err.note(&msg);
- } else {
- err.message =
- vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
- }
- if snippet.starts_with('&') {
- // This is already a literal borrow and the obligation is failing
- // somewhere else in the obligation chain. Do not suggest non-sense.
- return false;
- }
- err.span_label(
- span,
+
+ if imm_ref_self_ty_satisfies_pred
+ || mut_ref_self_ty_satisfies_pred
+ || ref_inner_ty_satisfies_pred
+ {
+ if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
+ // We don't want a borrowing suggestion on the fields in structs,
+ // ```
+ // struct Foo {
+ // the_foos: Vec<Foo>
+ // }
+ // ```
+ if !matches!(
+ span.ctxt().outer_expn_data().kind,
+ ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
+ ) {
+ return false;
+ }
+ if snippet.starts_with('&') {
+ // This is already a literal borrow and the obligation is failing
+ // somewhere else in the obligation chain. Do not suggest non-sense.
+ return false;
+ }
+ // We have a very specific type of error, where just borrowing this argument
+ // might solve the problem. In cases like this, the important part is the
+ // original type obligation, not the last one that failed, which is arbitrary.
+ // Because of this, we modify the error to refer to the original obligation and
+ // return early in the caller.
+
+ let msg = format!("the trait bound `{}` is not satisfied", old_pred);
+ if has_custom_message {
+ err.note(&msg);
+ } else {
+ err.message =
+ vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
+ }
+ err.span_label(
+ span,
+ format!(
+ "the trait `{}` is not implemented for `{}`",
+ old_pred.print_modifiers_and_trait_path(),
+ old_pred.self_ty().skip_binder(),
+ ),
+ );
+
+ if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
+ err.span_suggestions(
+ span.shrink_to_lo(),
+ "consider borrowing here",
+ ["&".to_string(), "&mut ".to_string()].into_iter(),
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
+ err.span_suggestion_verbose(
+ span.shrink_to_lo(),
&format!(
- "expected an implementor of trait `{}`",
- old_pred.print_modifiers_and_trait_path(),
+ "consider{} borrowing here",
+ if is_mut { " mutably" } else { "" }
),
+ format!("&{}", if is_mut { "mut " } else { "" }),
+ Applicability::MaybeIncorrect,
);
-
- // This if is to prevent a special edge-case
- if matches!(
- span.ctxt().outer_expn_data().kind,
- ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
- ) {
- // We don't want a borrowing suggestion on the fields in structs,
- // ```
- // struct Foo {
- // the_foos: Vec<Foo>
- // }
- // ```
-
- if imm_result && mut_result {
- err.span_suggestions(
- span.shrink_to_lo(),
- "consider borrowing here",
- ["&".to_string(), "&mut ".to_string()].into_iter(),
- Applicability::MaybeIncorrect,
- );
- } else {
- err.span_suggestion_verbose(
- span.shrink_to_lo(),
- &format!(
- "consider{} borrowing here",
- if mut_result { " mutably" } else { "" }
- ),
- format!("&{}", if mut_result { "mut " } else { "" }),
- Applicability::MaybeIncorrect,
- );
- }
- }
- return true;
}
+ return true;
}
- return false;
- };
+ }
+ return false;
+ };
if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code {
try_borrowing(cause.derived.parent_trait_pred, &[])
} else if let ObligationCauseCode::BindingObligation(_, _)
- | ObligationCauseCode::ItemObligation(_) = code
+ | ObligationCauseCode::ItemObligation(_)
+ | ObligationCauseCode::ExprItemObligation(..)
+ | ObligationCauseCode::ExprBindingObligation(..) = code
{
try_borrowing(poly_trait_pred, &never_suggest_borrow)
} else {
@@ -1017,7 +1067,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self_ty: Ty<'tcx>,
object_ty: Ty<'tcx>,
) {
- let ty::Dynamic(predicates, _) = object_ty.kind() else { return; };
+ let ty::Dynamic(predicates, _, ty::Dyn) = object_ty.kind() else { return; };
let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty);
for predicate in predicates.iter() {
@@ -1110,8 +1160,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// and if not maybe suggest doing something else? If we kept the expression around we
// could also check if it is an fn call (very likely) and suggest changing *that*, if
// it is from the local crate.
- err.span_suggestion_verbose(
- expr.span.shrink_to_hi().with_hi(span.hi()),
+ err.span_suggestion(
+ span,
"remove the `.await`",
"",
Applicability::MachineApplicable,
@@ -1315,7 +1365,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let trait_pred = self.resolve_vars_if_possible(trait_pred);
let ty = trait_pred.skip_binder().self_ty();
let is_object_safe = match ty.kind() {
- ty::Dynamic(predicates, _) => {
+ ty::Dynamic(predicates, _, ty::Dyn) => {
// If the `dyn Trait` is not object safe, do not suggest `Box<dyn Trait>`.
predicates
.principal_def_id()
@@ -1375,7 +1425,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let mut spans_and_needs_box = vec![];
match liberated_sig.output().kind() {
- ty::Dynamic(predicates, _) => {
+ ty::Dynamic(predicates, _, _) => {
let cause = ObligationCause::misc(ret_ty.span, fn_hir_id);
let param_env = ty::ParamEnv::empty();
@@ -1541,32 +1591,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
expected: ty::PolyTraitRef<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
pub(crate) fn build_fn_sig_ty<'tcx>(
- tcx: TyCtxt<'tcx>,
+ infcx: &InferCtxt<'_, 'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx> {
let inputs = trait_ref.skip_binder().substs.type_at(1);
let sig = match inputs.kind() {
ty::Tuple(inputs)
- if tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() =>
+ if infcx.tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() =>
{
- tcx.mk_fn_sig(
+ infcx.tcx.mk_fn_sig(
inputs.iter(),
- tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
+ infcx.next_ty_var(TypeVariableOrigin {
+ span: DUMMY_SP,
+ kind: TypeVariableOriginKind::MiscVariable,
+ }),
false,
hir::Unsafety::Normal,
abi::Abi::Rust,
)
}
- _ => tcx.mk_fn_sig(
+ _ => infcx.tcx.mk_fn_sig(
std::iter::once(inputs),
- tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
+ infcx.next_ty_var(TypeVariableOrigin {
+ span: DUMMY_SP,
+ kind: TypeVariableOriginKind::MiscVariable,
+ }),
false,
hir::Unsafety::Normal,
abi::Abi::Rust,
),
};
- tcx.mk_fn_ptr(trait_ref.rebind(sig))
+ infcx.tcx.mk_fn_ptr(trait_ref.rebind(sig))
}
let argument_kind = match expected.skip_binder().self_ty().kind() {
@@ -1586,11 +1642,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let found_span = found_span.unwrap_or(span);
err.span_label(found_span, "found signature defined here");
- let expected = build_fn_sig_ty(self.tcx, expected);
- let found = build_fn_sig_ty(self.tcx, found);
+ let expected = build_fn_sig_ty(self, expected);
+ let found = build_fn_sig_ty(self, found);
- let (expected_str, found_str) =
- self.tcx.infer_ctxt().enter(|infcx| infcx.cmp(expected, found));
+ let (expected_str, found_str) = self.cmp(expected, found);
let signature_kind = format!("{argument_kind} signature");
err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
@@ -2201,7 +2256,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
| ObligationCauseCode::QuestionMark
| ObligationCauseCode::CheckAssociatedTypeBounds { .. }
| ObligationCauseCode::LetElse
- | ObligationCauseCode::BinOp { .. } => {}
+ | ObligationCauseCode::BinOp { .. }
+ | ObligationCauseCode::AscribeUserTypeProvePredicate(..) => {}
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");
}
@@ -2223,11 +2279,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
region, object_ty,
));
}
- ObligationCauseCode::ItemObligation(_item_def_id) => {
+ ObligationCauseCode::ItemObligation(_)
+ | ObligationCauseCode::ExprItemObligation(..) => {
// We hold the `DefId` of the item introducing the obligation, but displaying it
// doesn't add user usable information. It always point at an associated item.
}
- ObligationCauseCode::BindingObligation(item_def_id, span) => {
+ ObligationCauseCode::BindingObligation(item_def_id, span)
+ | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => {
let item_name = tcx.def_path_str(item_def_id);
let mut multispan = MultiSpan::from(span);
if let Some(ident) = tcx.opt_item_ident(item_def_id) {
@@ -2537,9 +2595,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
parent_trait_pred.remap_constness_diag(param_env);
let parent_def_id = parent_trait_pred.def_id();
let msg = format!(
- "required because of the requirements on the impl of `{}` for `{}`",
- parent_trait_pred.print_modifiers_and_trait_path(),
- parent_trait_pred.skip_binder().self_ty()
+ "required for `{}` to implement `{}`",
+ parent_trait_pred.skip_binder().self_ty(),
+ parent_trait_pred.print_modifiers_and_trait_path()
);
let mut is_auto_trait = false;
match self.tcx.hir().get_if_local(data.impl_def_id) {
@@ -2608,9 +2666,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
pluralize!(count)
));
err.note(&format!(
- "required because of the requirements on the impl of `{}` for `{}`",
- parent_trait_pred.print_modifiers_and_trait_path(),
- parent_trait_pred.skip_binder().self_ty()
+ "required for `{}` to implement `{}`",
+ parent_trait_pred.skip_binder().self_ty(),
+ parent_trait_pred.print_modifiers_and_trait_path()
));
}
// #74711: avoid a stack overflow
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 556ef466c..a81fef60a 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -135,7 +135,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
/// `SomeTrait` or a where-clause that lets us unify `$0` with
/// something concrete. If this fails, we'll unify `$0` with
/// `projection_ty` again.
- #[tracing::instrument(level = "debug", skip(self, infcx, param_env, cause))]
+ #[instrument(level = "debug", skip(self, infcx, param_env, cause))]
fn normalize_projection_type(
&mut self,
infcx: &InferCtxt<'_, 'tcx>,
@@ -427,16 +427,14 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
obligation.param_env,
Binder::dummy(subtype),
) {
- None => {
+ Err((a, b)) => {
// None means that both are unresolved.
- pending_obligation.stalled_on = vec![
- TyOrConstInferVar::maybe_from_ty(subtype.a).unwrap(),
- TyOrConstInferVar::maybe_from_ty(subtype.b).unwrap(),
- ];
+ pending_obligation.stalled_on =
+ vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
ProcessResult::Unchanged
}
- Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
- Some(Err(err)) => {
+ Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
+ Ok(Err(err)) => {
let expected_found =
ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b);
ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
@@ -453,16 +451,14 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
obligation.param_env,
Binder::dummy(coerce),
) {
- None => {
+ Err((a, b)) => {
// None means that both are unresolved.
- pending_obligation.stalled_on = vec![
- TyOrConstInferVar::maybe_from_ty(coerce.a).unwrap(),
- TyOrConstInferVar::maybe_from_ty(coerce.b).unwrap(),
- ];
+ pending_obligation.stalled_on =
+ vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
ProcessResult::Unchanged
}
- Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
- Some(Err(err)) => {
+ Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
+ Ok(Err(err)) => {
let expected_found = ExpectedFound::new(false, coerce.a, coerce.b);
ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
expected_found,
@@ -509,11 +505,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.kind(), c2.kind())
{
- if infcx.try_unify_abstract_consts(
- a.shrink(),
- b.shrink(),
- obligation.param_env,
- ) {
+ if infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
return ProcessResult::Changed(vec![]);
}
}
@@ -597,6 +589,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
}
}
+ #[inline(never)]
fn process_backedge<'c, I>(
&mut self,
cycle: I,
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index dd2769c71..e1bd48ba8 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -63,8 +63,7 @@ pub fn can_type_implement_copy<'tcx>(
} else {
ObligationCause::dummy_with_span(span)
};
- let ctx = traits::FulfillmentContext::new();
- match traits::fully_normalize(&infcx, ctx, cause, param_env, ty) {
+ match traits::fully_normalize(&infcx, cause, param_env, ty) {
Ok(ty) => {
if !infcx.type_is_copy_modulo_regions(param_env, ty, span) {
infringing.push((field, ty));
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 9c6bb0731..40596078f 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -13,6 +13,7 @@ mod fulfill;
pub mod misc;
mod object_safety;
mod on_unimplemented;
+pub mod outlives_bounds;
mod project;
pub mod query;
pub(crate) mod relationships;
@@ -22,6 +23,7 @@ mod structural_match;
mod util;
pub mod wf;
+use crate::errors::DumpVTableEntries;
use crate::infer::outlives::env::OutlivesEnvironment;
use crate::infer::{InferCtxt, TyCtxtInferExt};
use crate::traits::error_reporting::InferCtxtExt as _;
@@ -30,10 +32,14 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
+use rustc_infer::traits::TraitEngineExt as _;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry};
+use rustc_middle::ty::{
+ self, DefIdTree, GenericParamDefKind, Subst, ToPredicate, Ty, TyCtxt, TypeSuperVisitable,
+ VtblEntry,
+};
use rustc_span::{sym, Span};
use smallvec::SmallVec;
@@ -113,11 +119,21 @@ pub enum TraitQueryMode {
/// Creates predicate obligations from the generic bounds.
pub fn predicates_for_generics<'tcx>(
- cause: ObligationCause<'tcx>,
+ cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
- util::predicates_for_generics(cause, 0, param_env, generic_bounds)
+ let generic_bounds = generic_bounds;
+ debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
+
+ std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map(
+ move |(idx, (predicate, span))| Obligation {
+ cause: cause(idx, span),
+ recursion_depth: 0,
+ param_env: param_env,
+ predicate,
+ },
+ )
}
/// Determines whether the type `ty` is known to meet `bound` and
@@ -161,22 +177,20 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
// this function's result remains infallible, we must confirm
// that guess. While imperfect, I believe this is sound.
- // The handling of regions in this area of the code is terrible,
- // see issue #29149. We should be able to improve on this with
- // NLL.
- let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
-
// We can use a dummy node-id here because we won't pay any mind
// to region obligations that arise (there shouldn't really be any
// anyhow).
let cause = ObligationCause::misc(span, hir::CRATE_HIR_ID);
- fulfill_cx.register_bound(infcx, param_env, ty, def_id, cause);
+ // The handling of regions in this area of the code is terrible,
+ // see issue #29149. We should be able to improve on this with
+ // NLL.
+ let errors = fully_solve_bound(infcx, cause, param_env, ty, def_id);
// Note: we only assume something is `Copy` if we can
// *definitively* show that it implements `Copy`. Otherwise,
// assume it is move; linear is always ok.
- match fulfill_cx.select_all_or_error(infcx).as_slice() {
+ match &errors[..] {
[] => {
debug!(
"type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
@@ -222,15 +236,13 @@ fn do_normalize_predicates<'tcx>(
// them here too, and we will remove this function when
// we move over to lazy normalization *anyway*.
tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
- let fulfill_cx = FulfillmentContext::new();
- let predicates =
- match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) {
- Ok(predicates) => predicates,
- Err(errors) => {
- let reported = infcx.report_fulfillment_errors(&errors, None, false);
- return Err(reported);
- }
- };
+ let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
+ Ok(predicates) => predicates,
+ Err(errors) => {
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
+ }
+ };
debug!("do_normalize_predictes: normalized predicates = {:?}", predicates);
@@ -381,9 +393,9 @@ pub fn normalize_param_env_or_error<'tcx>(
)
}
+/// Normalize a type and process all resulting obligations, returning any errors
pub fn fully_normalize<'a, 'tcx, T>(
infcx: &InferCtxt<'a, 'tcx>,
- mut fulfill_cx: FulfillmentContext<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: T,
@@ -399,8 +411,10 @@ where
"fully_normalize: normalized_value={:?} obligations={:?}",
normalized_value, obligations
);
+
+ let mut fulfill_cx = FulfillmentContext::new();
for obligation in obligations {
- fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
+ fulfill_cx.register_predicate_obligation(infcx, obligation);
}
debug!("fully_normalize: select_all_or_error start");
@@ -414,6 +428,43 @@ where
Ok(resolved_value)
}
+/// Process an obligation (and any nested obligations that come from it) to
+/// completion, returning any errors
+pub fn fully_solve_obligation<'a, 'tcx>(
+ infcx: &InferCtxt<'a, 'tcx>,
+ obligation: PredicateObligation<'tcx>,
+) -> Vec<FulfillmentError<'tcx>> {
+ let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
+ engine.register_predicate_obligation(infcx, obligation);
+ engine.select_all_or_error(infcx)
+}
+
+/// Process a set of obligations (and any nested obligations that come from them)
+/// to completion
+pub fn fully_solve_obligations<'a, 'tcx>(
+ infcx: &InferCtxt<'a, 'tcx>,
+ obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
+) -> Vec<FulfillmentError<'tcx>> {
+ let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
+ engine.register_predicate_obligations(infcx, obligations);
+ engine.select_all_or_error(infcx)
+}
+
+/// Process a bound (and any nested obligations that come from it) to completion.
+/// This is a convenience function for traits that have no generic arguments, such
+/// as auto traits, and builtin traits like Copy or Sized.
+pub fn fully_solve_bound<'a, 'tcx>(
+ infcx: &InferCtxt<'a, 'tcx>,
+ cause: ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ ty: Ty<'tcx>,
+ bound: DefId,
+) -> Vec<FulfillmentError<'tcx>> {
+ let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
+ engine.register_bound(infcx, param_env, ty, bound, cause);
+ engine.select_all_or_error(infcx)
+}
+
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
/// returns true, then either normalize encountered an error or one of the predicates did not
/// hold. Used when creating vtables to check for unsatisfiable methods.
@@ -424,24 +475,14 @@ pub fn impossible_predicates<'tcx>(
debug!("impossible_predicates(predicates={:?})", predicates);
let result = tcx.infer_ctxt().enter(|infcx| {
- // HACK: Set tainted by errors to gracefully exit in case of overflow.
- infcx.set_tainted_by_errors();
-
let param_env = ty::ParamEnv::reveal_all();
- let mut selcx = SelectionContext::new(&infcx);
- let mut fulfill_cx = FulfillmentContext::new();
- let cause = ObligationCause::dummy();
- let Normalized { value: predicates, obligations } =
- normalize(&mut selcx, param_env, cause.clone(), predicates);
- for obligation in obligations {
- fulfill_cx.register_predicate_obligation(&infcx, obligation);
- }
+ let ocx = ObligationCtxt::new(&infcx);
+ let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates);
for predicate in predicates {
- let obligation = Obligation::new(cause.clone(), param_env, predicate);
- fulfill_cx.register_predicate_obligation(&infcx, obligation);
+ let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
+ ocx.register_obligation(obligation);
}
-
- let errors = fulfill_cx.select_all_or_error(&infcx);
+ let errors = ocx.select_all_or_error();
// Clean up after ourselves
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
@@ -474,6 +515,84 @@ fn subst_and_check_impossible_predicates<'tcx>(
result
}
+/// Checks whether a trait's method is impossible to call on a given impl.
+///
+/// This only considers predicates that reference the impl's generics, and not
+/// those that reference the method's generics.
+fn is_impossible_method<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ (impl_def_id, trait_item_def_id): (DefId, DefId),
+) -> bool {
+ struct ReferencesOnlyParentGenerics<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ generics: &'tcx ty::Generics,
+ trait_item_def_id: DefId,
+ }
+ impl<'tcx> ty::TypeVisitor<'tcx> for ReferencesOnlyParentGenerics<'tcx> {
+ type BreakTy = ();
+ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+ // If this is a parameter from the trait item's own generics, then bail
+ if let ty::Param(param) = t.kind()
+ && let param_def_id = self.generics.type_param(param, self.tcx).def_id
+ && self.tcx.parent(param_def_id) == self.trait_item_def_id
+ {
+ return ControlFlow::BREAK;
+ }
+ t.super_visit_with(self)
+ }
+ fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if let ty::ReEarlyBound(param) = r.kind()
+ && let param_def_id = self.generics.region_param(&param, self.tcx).def_id
+ && self.tcx.parent(param_def_id) == self.trait_item_def_id
+ {
+ return ControlFlow::BREAK;
+ }
+ r.super_visit_with(self)
+ }
+ fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if let ty::ConstKind::Param(param) = ct.kind()
+ && let param_def_id = self.generics.const_param(&param, self.tcx).def_id
+ && self.tcx.parent(param_def_id) == self.trait_item_def_id
+ {
+ return ControlFlow::BREAK;
+ }
+ ct.super_visit_with(self)
+ }
+ }
+
+ let generics = tcx.generics_of(trait_item_def_id);
+ let predicates = tcx.predicates_of(trait_item_def_id);
+ let impl_trait_ref =
+ tcx.impl_trait_ref(impl_def_id).expect("expected impl to correspond to trait");
+ let param_env = tcx.param_env(impl_def_id);
+
+ let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id };
+ let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| {
+ if pred.visit_with(&mut visitor).is_continue() {
+ Some(Obligation::new(
+ ObligationCause::dummy_with_span(*span),
+ param_env,
+ ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs),
+ ))
+ } else {
+ None
+ }
+ });
+
+ tcx.infer_ctxt().ignoring_regions().enter(|ref infcx| {
+ for obligation in predicates_for_trait {
+ // Ignore overflow error, to be conservative.
+ if let Ok(result) = infcx.evaluate_obligation(&obligation)
+ && !result.may_apply()
+ {
+ return true;
+ }
+ }
+
+ false
+ })
+}
+
#[derive(Clone, Debug)]
enum VtblSegment<'tcx> {
MetadataDSA,
@@ -645,8 +764,11 @@ fn dump_vtable_entries<'tcx>(
trait_ref: ty::PolyTraitRef<'tcx>,
entries: &[VtblEntry<'tcx>],
) {
- let msg = format!("vtable entries for `{}`: {:#?}", trait_ref, entries);
- tcx.sess.struct_span_err(sp, &msg).emit();
+ tcx.sess.emit_err(DumpVTableEntries {
+ span: sp,
+ trait_ref,
+ entries: format!("{:#?}", entries),
+ });
}
fn own_existential_vtable_entries<'tcx>(
@@ -849,11 +971,12 @@ pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers {
specialization_graph_of: specialize::specialization_graph_provider,
specializes: specialize::specializes,
- codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
+ codegen_select_candidate: codegen::codegen_select_candidate,
own_existential_vtable_entries,
vtable_entries,
vtable_trait_upcasting_coercion_new_vptr_slot,
subst_and_check_impossible_predicates,
+ is_impossible_method,
try_unify_abstract_consts: |tcx, param_env_and| {
let (param_env, (a, b)) = param_env_and.into_parts();
const_evaluatable::try_unify_abstract_consts(tcx, (a, b), param_env)
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 612f51309..f2779ce2d 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -13,6 +13,7 @@ use super::elaborate_predicates;
use crate::infer::TyCtxtInferExt;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{self, Obligation, ObligationCause};
+use hir::def::DefKind;
use rustc_errors::{FatalError, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -431,6 +432,9 @@ fn virtual_call_violation_for_method<'tcx>(
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
return Some(MethodViolationCode::ReferencesSelfOutput);
}
+ if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
+ return Some(MethodViolationCode::ReferencesImplTraitInTrait);
+ }
// We can't monomorphize things like `fn foo<A>(...)`.
let own_counts = tcx.generics_of(method.def_id).own_counts();
@@ -596,7 +600,7 @@ fn object_ty_for_trait<'tcx>(
let existential_predicates = tcx
.mk_poly_existential_predicates(iter::once(trait_predicate).chain(projection_predicates));
- let object_ty = tcx.mk_dynamic(existential_predicates, lifetime);
+ let object_ty = tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn);
debug!("object_ty_for_trait: object_ty=`{}`", object_ty);
@@ -793,6 +797,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
ControlFlow::CONTINUE
}
}
+ ty::Projection(ref data)
+ if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder =>
+ {
+ // We'll deny these later in their own pass
+ ControlFlow::CONTINUE
+ }
ty::Projection(ref data) => {
// This is a projected type `<Foo as SomeTrait>::X`.
@@ -861,6 +871,22 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
.is_break()
}
+pub fn contains_illegal_impl_trait_in_trait<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ ty: ty::Binder<'tcx, Ty<'tcx>>,
+) -> bool {
+ // FIXME(RPITIT): Perhaps we should use a visitor here?
+ ty.skip_binder().walk().any(|arg| {
+ if let ty::GenericArgKind::Type(ty) = arg.unpack()
+ && let ty::Projection(proj) = ty.kind()
+ {
+ tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+ } else {
+ false
+ }
+ })
+}
+
pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers { object_safety_violations, ..*providers };
}
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index 9227bbf01..4a4f34b76 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -8,6 +8,10 @@ use rustc_parse_format::{ParseMode, Parser, Piece, Position};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
+use crate::errors::{
+ EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
+};
+
#[derive(Clone, Debug)]
pub struct OnUnimplementedFormatString(Symbol);
@@ -18,7 +22,7 @@ pub struct OnUnimplementedDirective {
pub message: Option<OnUnimplementedFormatString>,
pub label: Option<OnUnimplementedFormatString>,
pub note: Option<OnUnimplementedFormatString>,
- pub enclosing_scope: Option<OnUnimplementedFormatString>,
+ pub parent_label: Option<OnUnimplementedFormatString>,
pub append_const_msg: Option<Option<Symbol>>,
}
@@ -27,7 +31,7 @@ pub struct OnUnimplementedNote {
pub message: Option<String>,
pub label: Option<String>,
pub note: Option<String>,
- pub enclosing_scope: Option<String>,
+ pub parent_label: Option<String>,
/// Append a message for `~const Trait` errors. `None` means not requested and
/// should fallback to a generic message, `Some(None)` suggests using the default
/// appended message, `Some(Some(s))` suggests use the `s` message instead of the
@@ -35,21 +39,6 @@ pub struct OnUnimplementedNote {
pub append_const_msg: Option<Option<Symbol>>,
}
-fn parse_error(
- tcx: TyCtxt<'_>,
- span: Span,
- message: &str,
- label: &str,
- note: Option<&str>,
-) -> ErrorGuaranteed {
- let mut diag = struct_span_err!(tcx.sess, span, E0232, "{}", message);
- diag.span_label(span, label);
- if let Some(note) = note {
- diag.note(note);
- }
- diag.emit()
-}
-
impl<'tcx> OnUnimplementedDirective {
fn parse(
tcx: TyCtxt<'tcx>,
@@ -70,25 +59,9 @@ impl<'tcx> OnUnimplementedDirective {
} else {
let cond = item_iter
.next()
- .ok_or_else(|| {
- parse_error(
- tcx,
- span,
- "empty `on`-clause in `#[rustc_on_unimplemented]`",
- "empty on-clause here",
- None,
- )
- })?
+ .ok_or_else(|| tcx.sess.emit_err(EmptyOnClauseInOnUnimplemented { span }))?
.meta_item()
- .ok_or_else(|| {
- parse_error(
- tcx,
- span,
- "invalid `on`-clause in `#[rustc_on_unimplemented]`",
- "invalid on-clause here",
- None,
- )
- })?;
+ .ok_or_else(|| tcx.sess.emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| {
if let Some(value) = cfg.value && let Err(guar) = parse_value(value) {
errored = Some(guar);
@@ -101,7 +74,7 @@ impl<'tcx> OnUnimplementedDirective {
let mut message = None;
let mut label = None;
let mut note = None;
- let mut enclosing_scope = None;
+ let mut parent_label = None;
let mut subcommands = vec![];
let mut append_const_msg = None;
@@ -121,9 +94,9 @@ impl<'tcx> OnUnimplementedDirective {
note = parse_value(note_)?;
continue;
}
- } else if item.has_name(sym::enclosing_scope) && enclosing_scope.is_none() {
- if let Some(enclosing_scope_) = item.value_str() {
- enclosing_scope = parse_value(enclosing_scope_)?;
+ } else if item.has_name(sym::parent_label) && parent_label.is_none() {
+ if let Some(parent_label_) = item.value_str() {
+ parent_label = parse_value(parent_label_)?;
continue;
}
} else if item.has_name(sym::on)
@@ -150,13 +123,7 @@ impl<'tcx> OnUnimplementedDirective {
}
// nothing found
- parse_error(
- tcx,
- item.span(),
- "this attribute must have a valid value",
- "expected value here",
- Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#),
- );
+ tcx.sess.emit_err(NoValueInOnUnimplemented { span: item.span() });
}
if let Some(reported) = errored {
@@ -168,7 +135,7 @@ impl<'tcx> OnUnimplementedDirective {
message,
label,
note,
- enclosing_scope,
+ parent_label,
append_const_msg,
})
}
@@ -193,7 +160,7 @@ impl<'tcx> OnUnimplementedDirective {
attr.span,
)?),
note: None,
- enclosing_scope: None,
+ parent_label: None,
append_const_msg: None,
}))
} else {
@@ -214,7 +181,7 @@ impl<'tcx> OnUnimplementedDirective {
let mut message = None;
let mut label = None;
let mut note = None;
- let mut enclosing_scope = None;
+ let mut parent_label = None;
let mut append_const_msg = None;
info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
@@ -250,8 +217,8 @@ impl<'tcx> OnUnimplementedDirective {
note = Some(note_.clone());
}
- if let Some(ref enclosing_scope_) = command.enclosing_scope {
- enclosing_scope = Some(enclosing_scope_.clone());
+ if let Some(ref parent_label_) = command.parent_label {
+ parent_label = Some(parent_label_.clone());
}
append_const_msg = command.append_const_msg;
@@ -261,7 +228,7 @@ impl<'tcx> OnUnimplementedDirective {
label: label.map(|l| l.format(tcx, trait_ref, &options_map)),
message: message.map(|m| m.format(tcx, trait_ref, &options_map)),
note: note.map(|n| n.format(tcx, trait_ref, &options_map)),
- enclosing_scope: enclosing_scope.map(|e_s| e_s.format(tcx, trait_ref, &options_map)),
+ parent_label: parent_label.map(|e_s| e_s.format(tcx, trait_ref, &options_map)),
append_const_msg,
}
}
diff --git a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 229a64650..3008dfcad 100644
--- a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -1,22 +1,32 @@
+use crate::infer::InferCtxt;
+use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
+use crate::traits::query::NoSolution;
+use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
-use rustc_middle::ty::{self, Ty};
-use rustc_trait_selection::infer::InferCtxt;
-use rustc_trait_selection::traits::query::type_op::{self, TypeOp, TypeOpOutput};
-use rustc_trait_selection::traits::query::NoSolution;
-use rustc_trait_selection::traits::{ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_hir::HirId;
+use rustc_middle::ty::{self, ParamEnv, Ty};
pub use rustc_middle::traits::query::OutlivesBound;
-pub trait InferCtxtExt<'tcx> {
+type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
+pub trait InferCtxtExt<'a, 'tcx> {
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
ty: Ty<'tcx>,
) -> Vec<OutlivesBound<'tcx>>;
+
+ fn implied_bounds_tys(
+ &'a self,
+ param_env: ty::ParamEnv<'tcx>,
+ body_id: hir::HirId,
+ tys: FxHashSet<Ty<'tcx>>,
+ ) -> Bounds<'a, 'tcx>;
}
-impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
+impl<'a, 'cx, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'cx, 'tcx> {
/// Implied bounds are region relationships that we deduce
/// automatically. The idea is that (e.g.) a caller must check that a
/// function's argument types are well-formed immediately before
@@ -36,7 +46,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
/// Note that this may cause outlives obligations to be injected
/// into the inference context with this body-id.
/// - `ty`, the type that we are supposed to assume is WF.
- #[instrument(level = "debug", skip(self, param_env, body_id))]
+ #[instrument(level = "debug", skip(self, param_env, body_id), ret)]
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
@@ -61,6 +71,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
let TypeOpOutput { output, constraints, .. } = result;
if let Some(constraints) = constraints {
+ debug!(?constraints);
// Instantiation may have produced new inference variables and constraints on those
// variables. Process these constraints.
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.tcx);
@@ -87,4 +98,18 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
output
}
+
+ fn implied_bounds_tys(
+ &'a self,
+ param_env: ParamEnv<'tcx>,
+ body_id: HirId,
+ tys: FxHashSet<Ty<'tcx>>,
+ ) -> Bounds<'a, 'tcx> {
+ tys.into_iter()
+ .map(move |ty| {
+ let ty = self.resolve_vars_if_possible(ty);
+ self.implied_outlives_bounds(param_env, body_id, ty)
+ })
+ .flatten()
+ }
}
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index c4e80e1ba..a25fb8543 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -32,6 +32,7 @@ use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
+use rustc_middle::ty::DefIdTree;
use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::sym;
@@ -70,6 +71,8 @@ enum ProjectionCandidate<'tcx> {
/// From an "impl" (or a "pseudo-impl" returned by select)
Select(Selection<'tcx>),
+
+ ImplTraitInTrait(ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>),
}
enum ProjectionCandidateSet<'tcx> {
@@ -231,7 +234,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
/// If successful, this may result in additional obligations.
///
/// See [poly_project_and_unify_type] for an explanation of the return value.
-#[tracing::instrument(level = "debug", skip(selcx))]
+#[instrument(level = "debug", skip(selcx))]
fn project_and_unify_type<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionObligation<'tcx>,
@@ -552,8 +555,23 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
)
.ok()
.flatten()
- .unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self)))
+ .unwrap_or_else(|| ty.super_fold_with(self).into())
};
+ // For cases like #95134 we would like to catch overflows early
+ // otherwise they slip away away and cause ICE.
+ let recursion_limit = self.tcx().recursion_limit();
+ if !recursion_limit.value_within_limit(self.depth)
+ // HACK: Don't overflow when running cargo doc see #100991
+ && !self.tcx().sess.opts.actually_rustdoc
+ {
+ let obligation = Obligation::with_depth(
+ self.cause.clone(),
+ recursion_limit.0,
+ self.param_env,
+ ty,
+ );
+ self.selcx.infcx().report_overflow_error(&obligation, true);
+ }
debug!(
?self.depth,
?ty,
@@ -620,13 +638,27 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
- if self.selcx.tcx().lazy_normalization() || !self.eager_inference_replacement {
+ let tcx = self.selcx.tcx();
+ if tcx.lazy_normalization() {
constant
} else {
let constant = constant.super_fold_with(self);
- debug!(?constant);
- debug!("self.param_env: {:?}", self.param_env);
- constant.eval(self.selcx.tcx(), self.param_env)
+ debug!(?constant, ?self.param_env);
+ with_replaced_escaping_bound_vars(
+ self.selcx.infcx(),
+ &mut self.universes,
+ constant,
+ |constant| constant.eval(tcx, self.param_env),
+ )
+ }
+ }
+
+ #[inline]
+ fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
+ if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
+ p.super_fold_with(self)
+ } else {
+ p
}
}
}
@@ -647,6 +679,41 @@ pub struct BoundVarReplacer<'me, 'tcx> {
universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
}
+/// Executes `f` on `value` after replacing all escaping bound variables with placeholders
+/// and then replaces these placeholders with the original bound variables in the result.
+///
+/// In most places, bound variables should be replaced right when entering a binder, making
+/// this function unnecessary. However, normalization currently does not do that, so we have
+/// to do this lazily.
+///
+/// You should not add any additional uses of this function, at least not without first
+/// discussing it with t-types.
+///
+/// FIXME(@lcnr): We may even consider experimenting with eagerly replacing bound vars during
+/// normalization as well, at which point this function will be unnecessary and can be removed.
+pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: TypeFoldable<'tcx>>(
+ infcx: &'a InferCtxt<'a, 'tcx>,
+ universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>,
+ value: T,
+ f: impl FnOnce(T) -> R,
+) -> R {
+ if value.has_escaping_bound_vars() {
+ let (value, mapped_regions, mapped_types, mapped_consts) =
+ BoundVarReplacer::replace_bound_vars(infcx, universe_indices, value);
+ let result = f(value);
+ PlaceholderReplacer::replace_placeholders(
+ infcx,
+ mapped_regions,
+ mapped_types,
+ mapped_consts,
+ universe_indices,
+ result,
+ )
+ } else {
+ f(value)
+ }
+}
+
impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
/// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that
/// use a binding level above `universe_indices.len()`, we fail.
@@ -1182,7 +1249,7 @@ impl<'tcx> Progress<'tcx> {
///
/// IMPORTANT:
/// - `obligation` must be fully normalized
-#[tracing::instrument(level = "info", skip(selcx))]
+#[instrument(level = "info", skip(selcx))]
fn project<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
@@ -1201,6 +1268,8 @@ fn project<'cx, 'tcx>(
let mut candidates = ProjectionCandidateSet::None;
+ assemble_candidate_for_impl_trait_in_trait(selcx, obligation, &mut candidates);
+
// Make sure that the following procedures are kept in order. ParamEnv
// needs to be first because it has highest priority, and Select checks
// the return value of push_candidate which assumes it's ran at last.
@@ -1239,6 +1308,48 @@ fn project<'cx, 'tcx>(
}
}
+/// If the predicate's item is an `ImplTraitPlaceholder`, we do a select on the
+/// corresponding trait ref. If this yields an `impl`, then we're able to project
+/// to a concrete type, since we have an `impl`'s method to provide the RPITIT.
+fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
+ selcx: &mut SelectionContext<'cx, 'tcx>,
+ obligation: &ProjectionTyObligation<'tcx>,
+ candidate_set: &mut ProjectionCandidateSet<'tcx>,
+) {
+ let tcx = selcx.tcx();
+ if tcx.def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
+ let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
+ let trait_def_id = tcx.parent(trait_fn_def_id);
+ let trait_substs =
+ obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
+ // FIXME(named-returns): Binders
+ let trait_predicate =
+ ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs })
+ .to_poly_trait_predicate();
+
+ let _ =
+ selcx.infcx().commit_if_ok(|_| match selcx.select(&obligation.with(trait_predicate)) {
+ Ok(Some(super::ImplSource::UserDefined(data))) => {
+ candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data));
+ Ok(())
+ }
+ Ok(None) => {
+ candidate_set.mark_ambiguous();
+ return Err(());
+ }
+ Ok(Some(_)) => {
+ // Don't know enough about the impl to provide a useful signature
+ return Err(());
+ }
+ Err(e) => {
+ debug!(error = ?e, "selection error");
+ candidate_set.mark_error(e);
+ return Err(());
+ }
+ });
+ }
+}
+
/// The first thing we have to do is scan through the parameter
/// environment to see whether there are any projection predicates
/// there that can answer this question.
@@ -1344,7 +1455,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
);
}
-#[tracing::instrument(
+#[instrument(
level = "debug",
skip(selcx, candidate_set, ctor, env_predicates, potentially_unnormalized_candidates)
)]
@@ -1395,12 +1506,17 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
}
}
-#[tracing::instrument(level = "debug", skip(selcx, obligation, candidate_set))]
+#[instrument(level = "debug", skip(selcx, obligation, candidate_set))]
fn assemble_candidates_from_impls<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
candidate_set: &mut ProjectionCandidateSet<'tcx>,
) {
+ // Can't assemble candidate from impl for RPITIT
+ if selcx.tcx().def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
+ return;
+ }
+
// If we are resolving `<T as TraitRef<...>>::Item == Type`,
// start out by selecting the predicate `T as TraitRef<...>`:
let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx()));
@@ -1635,7 +1751,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
super::ImplSource::AutoImpl(..)
| super::ImplSource::Builtin(..)
| super::ImplSource::TraitUpcasting(_)
- | super::ImplSource::ConstDestruct(_) => {
+ | super::ImplSource::ConstDestruct(_)
+ | super::ImplSource::Tuple => {
// These traits have no associated types.
selcx.tcx().sess.delay_span_bug(
obligation.cause.span,
@@ -1676,6 +1793,9 @@ fn confirm_candidate<'cx, 'tcx>(
ProjectionCandidate::Select(impl_source) => {
confirm_select_candidate(selcx, obligation, impl_source)
}
+ ProjectionCandidate::ImplTraitInTrait(data) => {
+ confirm_impl_trait_in_trait_candidate(selcx, obligation, data)
+ }
};
// When checking for cycle during evaluation, we compare predicates with
@@ -1710,7 +1830,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
| super::ImplSource::Builtin(..)
| super::ImplSource::TraitUpcasting(_)
| super::ImplSource::TraitAlias(..)
- | super::ImplSource::ConstDestruct(_) => {
+ | super::ImplSource::ConstDestruct(_)
+ | super::ImplSource::Tuple => {
// we don't create Select candidates with this kind of resolution
span_bug!(
obligation.cause.span,
@@ -2038,10 +2159,74 @@ fn confirm_impl_candidate<'cx, 'tcx>(
}
}
+fn confirm_impl_trait_in_trait_candidate<'tcx>(
+ selcx: &mut SelectionContext<'_, 'tcx>,
+ obligation: &ProjectionTyObligation<'tcx>,
+ data: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
+) -> Progress<'tcx> {
+ let tcx = selcx.tcx();
+ let mut obligations = data.nested;
+
+ let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
+ let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
+ return Progress { term: tcx.ty_error().into(), obligations };
+ };
+ if !leaf_def.item.defaultness(tcx).has_value() {
+ return Progress { term: tcx.ty_error().into(), obligations };
+ }
+
+ let impl_fn_def_id = leaf_def.item.def_id;
+ let impl_fn_substs = obligation.predicate.substs.rebase_onto(tcx, trait_fn_def_id, data.substs);
+
+ let cause = ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ super::ItemObligation(impl_fn_def_id),
+ );
+ let predicates = normalize_with_depth_to(
+ selcx,
+ obligation.param_env,
+ cause.clone(),
+ obligation.recursion_depth + 1,
+ tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs),
+ &mut obligations,
+ );
+ obligations.extend(std::iter::zip(predicates.predicates, predicates.spans).map(
+ |(pred, span)| {
+ Obligation::with_depth(
+ ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ if span.is_dummy() {
+ super::ItemObligation(impl_fn_def_id)
+ } else {
+ super::BindingObligation(impl_fn_def_id, span)
+ },
+ ),
+ obligation.recursion_depth + 1,
+ obligation.param_env,
+ pred,
+ )
+ },
+ ));
+
+ let ty = super::normalize_to(
+ selcx,
+ obligation.param_env,
+ cause.clone(),
+ tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
+ .map_bound(|tys| {
+ tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
+ })
+ .subst(tcx, impl_fn_substs),
+ &mut obligations,
+ );
+
+ Progress { term: ty.into(), obligations }
+}
+
// Get obligations corresponding to the predicates from the where-clause of the
// associated type itself.
-// Note: `feature(generic_associated_types)` is required to write such
-// predicates, even for non-generic associated types.
fn assoc_ty_own_obligations<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 449d7a7b4..40acabf62 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -6,7 +6,7 @@ use crate::infer::at::At;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::InferCtxtExt;
-use crate::traits::project::needs_normalization;
+use crate::traits::project::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use rustc_data_structures::sso::SsoHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -48,10 +48,11 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
T: TypeFoldable<'tcx>,
{
debug!(
- "normalize::<{}>(value={:?}, param_env={:?})",
+ "normalize::<{}>(value={:?}, param_env={:?}, cause={:?})",
std::any::type_name::<T>(),
value,
self.param_env,
+ self.cause,
);
if !needs_normalization(&value, self.param_env.reveal()) {
return Ok(Normalized { value, obligations: vec![] });
@@ -266,7 +267,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations);
- Ok(result.normalized_ty)
+
+ let res = result.normalized_ty;
+ // `tcx.normalize_projection_ty` may normalize to a type that still has
+ // unevaluated consts, so keep normalizing here if that's the case.
+ if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
+ Ok(res.try_super_fold_with(self)?)
+ } else {
+ Ok(res)
+ }
}
ty::Projection(data) => {
@@ -275,11 +284,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
let tcx = self.infcx.tcx;
let infcx = self.infcx;
let (data, mapped_regions, mapped_types, mapped_consts) =
- crate::traits::project::BoundVarReplacer::replace_bound_vars(
- infcx,
- &mut self.universes,
- data,
- );
+ BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
let data = data.try_fold_with(self)?;
let mut orig_values = OriginalQueryValues::default();
@@ -305,18 +310,26 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations);
- Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders(
+ let res = PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
mapped_types,
mapped_consts,
&self.universes,
result.normalized_ty,
- ))
+ );
+ // `tcx.normalize_projection_ty` may normalize to a type that still has
+ // unevaluated consts, so keep normalizing here if that's the case.
+ if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
+ Ok(res.try_super_fold_with(self)?)
+ } else {
+ Ok(res)
+ }
}
_ => ty.try_super_fold_with(self),
})()?;
+
self.cache.insert(ty, res);
Ok(res)
}
@@ -326,7 +339,13 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
constant: ty::Const<'tcx>,
) -> Result<ty::Const<'tcx>, Self::Error> {
let constant = constant.try_super_fold_with(self)?;
- Ok(constant.eval(self.infcx.tcx, self.param_env))
+ debug!(?constant, ?self.param_env);
+ Ok(crate::traits::project::with_replaced_escaping_bound_vars(
+ self.infcx,
+ &mut self.universes,
+ constant,
+ |constant| constant.eval(self.infcx.tcx, self.param_env),
+ ))
}
fn try_fold_mir_const(
@@ -348,7 +367,21 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
_ => mir::ConstantKind::Ty(const_folded),
}
}
- mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?,
+ mir::ConstantKind::Val(_, _) | mir::ConstantKind::Unevaluated(..) => {
+ constant.try_super_fold_with(self)?
+ }
})
}
+
+ #[inline]
+ fn try_fold_predicate(
+ &mut self,
+ p: ty::Predicate<'tcx>,
+ ) -> Result<ty::Predicate<'tcx>, Self::Error> {
+ if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
+ p.try_super_fold_with(self)
+ } else {
+ Ok(p)
+ }
+ }
}
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
index c99564936..18988861a 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
@@ -1,11 +1,9 @@
use crate::infer::canonical::query_response;
use crate::infer::{InferCtxt, InferOk};
-use crate::traits::engine::TraitEngineExt as _;
+use crate::traits;
use crate::traits::query::type_op::TypeOpOutput;
use crate::traits::query::Fallible;
-use crate::traits::TraitEngine;
use rustc_infer::infer::region_constraints::RegionConstraintData;
-use rustc_infer::traits::TraitEngineExt as _;
use rustc_span::source_map::DUMMY_SP;
use std::fmt;
@@ -25,7 +23,7 @@ impl<F, G> CustomTypeOp<F, G> {
}
}
-impl<'tcx, F, R, G> super::TypeOp<'tcx> for CustomTypeOp<F, G>
+impl<'tcx, F, R: fmt::Debug, G> super::TypeOp<'tcx> for CustomTypeOp<F, G>
where
F: for<'a, 'cx> FnOnce(&'a InferCtxt<'cx, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
G: Fn() -> String,
@@ -62,8 +60,6 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
infcx: &InferCtxt<'_, 'tcx>,
op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> {
- let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
-
// During NLL, we expect that nobody will register region
// obligations **except** as part of a custom type op (and, at the
// end of each custom type op, we scrape out the region
@@ -77,8 +73,7 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
);
let InferOk { value, obligations } = infcx.commit_if_ok(|_| op())?;
- fulfill_cx.register_predicate_obligations(infcx, obligations);
- let errors = fulfill_cx.select_all_or_error(infcx);
+ let errors = traits::fully_solve_obligations(infcx, obligations);
if !errors.is_empty() {
infcx.tcx.sess.diagnostic().delay_span_bug(
DUMMY_SP,
@@ -94,8 +89,8 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
infcx.tcx,
region_obligations
.iter()
- .map(|r_o| (r_o.sup_type, r_o.sub_region))
- .map(|(ty, r)| (infcx.resolve_vars_if_possible(ty), r)),
+ .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category()))
+ .map(|(ty, r, cc)| (infcx.resolve_vars_if_possible(ty), r, cc)),
&region_constraint_data,
);
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index 578e1d00c..8a7916570 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -26,7 +26,7 @@ pub use rustc_middle::traits::query::type_op::*;
/// extract out the resulting region constraints (or an error if it
/// cannot be completed).
pub trait TypeOp<'tcx>: Sized + fmt::Debug {
- type Output;
+ type Output: fmt::Debug;
type ErrorInfo;
/// Processes the operation and all resulting obligations,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index a60ce0f34..a80527f63 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -8,7 +8,7 @@
use hir::LangItem;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
-use rustc_infer::traits::TraitEngine;
+use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -28,7 +28,7 @@ use super::SelectionCandidate::{self, *};
use super::{EvaluatedCandidate, SelectionCandidateSet, SelectionContext, TraitObligationStack};
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
- #[instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
pub(super) fn candidate_from_obligation<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
@@ -48,7 +48,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let Some(c) =
self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred)
{
- debug!(candidate = ?c, "CACHE HIT");
+ debug!("CACHE HIT");
return c;
}
@@ -61,7 +61,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let (candidate, dep_node) =
self.in_task(|this| this.candidate_from_obligation_no_cache(stack));
- debug!(?candidate, "CACHE MISS");
+ debug!("CACHE MISS");
self.insert_candidate_cache(
stack.obligation.param_env,
cache_fresh_trait_pred,
@@ -75,7 +75,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
- if let Some(conflict) = self.is_knowable(stack) {
+ if let Err(conflict) = self.is_knowable(stack) {
debug!("coherence stage: not knowable");
if self.intercrate_ambiguity_causes.is_some() {
debug!("evaluate_stack: intercrate_ambiguity_causes is some");
@@ -309,6 +309,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// User-defined transmutability impls are permitted.
self.assemble_candidates_from_impls(obligation, &mut candidates);
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
+ } else if lang_items.tuple_trait() == Some(def_id) {
+ self.assemble_candidate_for_tuple(obligation, &mut candidates);
} else {
if lang_items.clone_trait() == Some(def_id) {
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
@@ -337,7 +339,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Ok(candidates)
}
- #[tracing::instrument(level = "debug", skip(self, candidates))]
+ #[instrument(level = "debug", skip(self, candidates))]
fn assemble_candidates_from_projected_tys(
&mut self,
obligation: &TraitObligation<'tcx>,
@@ -367,7 +369,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// supplied to find out whether it is listed among them.
///
/// Never affects the inference environment.
- #[tracing::instrument(level = "debug", skip(self, stack, candidates))]
+ #[instrument(level = "debug", skip(self, stack, candidates))]
fn assemble_candidates_from_caller_bounds<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
@@ -706,8 +708,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn need_migrate_deref_output_trait_object(
&mut self,
ty: Ty<'tcx>,
- cause: &traits::ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
+ cause: &ObligationCause<'tcx>,
) -> Option<(Ty<'tcx>, DefId)> {
let tcx = self.tcx();
if tcx.features().trait_upcasting {
@@ -729,24 +731,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return None;
}
- let mut fulfillcx = traits::FulfillmentContext::new_in_snapshot();
- let normalized_ty = fulfillcx.normalize_projection_type(
- &self.infcx,
+ let ty = traits::normalize_projection_type(
+ self,
param_env,
ty::ProjectionTy {
item_def_id: tcx.lang_items().deref_target()?,
substs: trait_ref.substs,
},
cause.clone(),
- );
-
- let ty::Dynamic(data, ..) = normalized_ty.kind() else {
- return None;
- };
-
- let def_id = data.principal_def_id()?;
-
- return Some((normalized_ty, def_id));
+ 0,
+ // We're *intentionally* throwing these away,
+ // since we don't actually use them.
+ &mut vec![],
+ )
+ .ty()
+ .unwrap();
+
+ if let ty::Dynamic(data, ..) = ty.kind() {
+ Some((ty, data.principal_def_id()?))
+ } else {
+ None
+ }
}
/// Searches for unsizing that might apply to `obligation`.
@@ -809,8 +814,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let Some((deref_output_ty, deref_output_trait_did)) = self
.need_migrate_deref_output_trait_object(
source,
- &obligation.cause,
obligation.param_env,
+ &obligation.cause,
)
{
if deref_output_trait_did == target_trait_did {
@@ -877,7 +882,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
};
}
- #[tracing::instrument(level = "debug", skip(self, obligation, candidates))]
+ #[instrument(level = "debug", skip(self, obligation, candidates))]
fn assemble_candidates_for_transmutability(
&mut self,
obligation: &TraitObligation<'tcx>,
@@ -895,7 +900,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.vec.push(TransmutabilityCandidate);
}
- #[tracing::instrument(level = "debug", skip(self, obligation, candidates))]
+ #[instrument(level = "debug", skip(self, obligation, candidates))]
fn assemble_candidates_for_trait_alias(
&mut self,
obligation: &TraitObligation<'tcx>,
@@ -914,7 +919,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Assembles the trait which are built-in to the language itself:
/// `Copy`, `Clone` and `Sized`.
- #[tracing::instrument(level = "debug", skip(self, candidates))]
+ #[instrument(level = "debug", skip(self, candidates))]
fn assemble_builtin_bound_candidates(
&mut self,
conditions: BuiltinImplConditions<'tcx>,
@@ -1006,4 +1011,46 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
}
+
+ fn assemble_candidate_for_tuple(
+ &mut self,
+ obligation: &TraitObligation<'tcx>,
+ candidates: &mut SelectionCandidateSet<'tcx>,
+ ) {
+ let self_ty = self.infcx().shallow_resolve(obligation.self_ty().skip_binder());
+ match self_ty.kind() {
+ ty::Tuple(_) => {
+ candidates.vec.push(TupleCandidate);
+ }
+ ty::Infer(ty::TyVar(_)) => {
+ candidates.ambiguous = true;
+ }
+ ty::Bool
+ | ty::Char
+ | ty::Int(_)
+ | ty::Uint(_)
+ | ty::Float(_)
+ | ty::Adt(_, _)
+ | ty::Foreign(_)
+ | ty::Str
+ | ty::Array(_, _)
+ | ty::Slice(_)
+ | ty::RawPtr(_)
+ | ty::Ref(_, _, _)
+ | ty::FnDef(_, _)
+ | ty::FnPtr(_)
+ | ty::Dynamic(_, _, _)
+ | ty::Closure(_, _)
+ | ty::Generator(_, _, _)
+ | ty::GeneratorWitness(_)
+ | ty::Never
+ | ty::Projection(_)
+ | ty::Opaque(_, _)
+ | ty::Param(_)
+ | ty::Bound(_, _)
+ | ty::Error(_)
+ | ty::Infer(_)
+ | ty::Placeholder(_) => {}
+ }
+ }
}
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 2a1099fc8..d1deef784 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -126,6 +126,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
ImplSource::ConstDestruct(data)
}
+
+ TupleCandidate => ImplSource::Tuple,
};
if !obligation.predicate.is_const_if_const() {
@@ -279,29 +281,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let predicate = obligation.predicate;
let type_at = |i| predicate.map_bound(|p| p.trait_ref.substs.type_at(i));
- let bool_at = |i| {
- predicate
- .skip_binder()
- .trait_ref
- .substs
- .const_at(i)
- .try_eval_bool(self.tcx(), obligation.param_env)
- .unwrap_or(true)
- };
+ let const_at = |i| predicate.skip_binder().trait_ref.substs.const_at(i);
let src_and_dst = predicate.map_bound(|p| rustc_transmute::Types {
- src: p.trait_ref.substs.type_at(1),
dst: p.trait_ref.substs.type_at(0),
+ src: p.trait_ref.substs.type_at(1),
});
let scope = type_at(2).skip_binder();
- let assume = rustc_transmute::Assume {
- alignment: bool_at(3),
- lifetimes: bool_at(4),
- validity: bool_at(5),
- visibility: bool_at(6),
- };
+ let assume =
+ rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3));
let cause = obligation.cause.clone();
@@ -794,7 +784,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let upcast_trait_ref;
match (source.kind(), target.kind()) {
// TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
- (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
+ (&ty::Dynamic(ref data_a, r_a, repr_a), &ty::Dynamic(ref data_b, r_b, repr_b))
+ if repr_a == repr_b =>
+ {
// See `assemble_candidates_for_unsizing` for more info.
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
let principal_a = data_a.principal().unwrap();
@@ -820,7 +812,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::Binder::dummy),
);
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
- let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
+ let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_b);
// Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed.
@@ -898,7 +890,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut nested = vec![];
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
- (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
+ (&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => {
// See `assemble_candidates_for_unsizing` for more info.
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
let iter = data_a
@@ -917,7 +909,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::Binder::dummy),
);
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
- let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
+ let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn);
// Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed.
@@ -944,7 +936,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
// `T` -> `Trait`
- (_, &ty::Dynamic(ref data, r)) => {
+ (_, &ty::Dynamic(ref data, r, ty::Dyn)) => {
let mut object_dids = data.auto_traits().chain(data.principal_def_id());
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
return Err(TraitNotObjectSafe(did));
@@ -1047,9 +1039,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return Err(Unimplemented);
}
- // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
- let source_tail = tail_field_ty.subst(tcx, substs_a);
- let target_tail = tail_field_ty.subst(tcx, substs_b);
+ // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
+ // normalizing in the process, since `type_of` returns something directly from
+ // astconv (which means it's un-normalized).
+ let source_tail = normalize_with_depth_to(
+ self,
+ obligation.param_env,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ tail_field_ty.subst(tcx, substs_a),
+ &mut nested,
+ );
+ let target_tail = normalize_with_depth_to(
+ self,
+ obligation.param_env,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ tail_field_ty.subst(tcx, substs_b),
+ &mut nested,
+ );
// Check that the source struct with the target's
// unsizing parameters is equal to the target.
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index c01ac1979..75bd2c89f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -295,7 +295,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Attempts to satisfy the obligation. If successful, this will affect the surrounding
/// type environment by performing unification.
- #[instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
pub fn select(
&mut self,
obligation: &TraitObligation<'tcx>,
@@ -325,10 +325,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Err(SelectionError::Overflow(OverflowError::Canonical))
}
Err(e) => Err(e),
- Ok(candidate) => {
- debug!(?candidate, "confirmed");
- Ok(Some(candidate))
- }
+ Ok(candidate) => Ok(Some(candidate)),
}
}
@@ -435,6 +432,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
level = "debug",
skip(self, previous_stack),
fields(previous_stack = ?previous_stack.head())
+ ret,
)]
fn evaluate_predicate_recursively<'o>(
&mut self,
@@ -450,7 +448,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
None => self.check_recursion_limit(&obligation, &obligation)?,
}
- let result = ensure_sufficient_stack(|| {
+ ensure_sufficient_stack(|| {
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(t) => {
@@ -464,15 +462,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let p = bound_predicate.rebind(p);
// Does this code ever run?
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
- Some(Ok(InferOk { mut obligations, .. })) => {
+ Ok(Ok(InferOk { mut obligations, .. })) => {
self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
self.evaluate_predicates_recursively(
previous_stack,
obligations.into_iter(),
)
}
- Some(Err(_)) => Ok(EvaluatedToErr),
- None => Ok(EvaluatedToAmbig),
+ Ok(Err(_)) => Ok(EvaluatedToErr),
+ Err(..) => Ok(EvaluatedToAmbig),
}
}
@@ -480,15 +478,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let p = bound_predicate.rebind(p);
// Does this code ever run?
match self.infcx.coerce_predicate(&obligation.cause, obligation.param_env, p) {
- Some(Ok(InferOk { mut obligations, .. })) => {
+ Ok(Ok(InferOk { mut obligations, .. })) => {
self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
self.evaluate_predicates_recursively(
previous_stack,
obligations.into_iter(),
)
}
- Some(Err(_)) => Ok(EvaluatedToErr),
- None => Ok(EvaluatedToAmbig),
+ Ok(Err(_)) => Ok(EvaluatedToErr),
+ Err(..) => Ok(EvaluatedToAmbig),
}
}
@@ -701,11 +699,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.kind(), c2.kind())
{
- if self.infcx.try_unify_abstract_consts(
- a.shrink(),
- b.shrink(),
- obligation.param_env,
- ) {
+ if self.infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
return Ok(EvaluatedToOk);
}
}
@@ -760,14 +754,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
bug!("TypeWellFormedFromEnv is only used for chalk")
}
}
- });
-
- debug!("finished: {:?} from {:?}", result, obligation);
-
- result
+ })
}
- #[instrument(skip(self, previous_stack), level = "debug")]
+ #[instrument(skip(self, previous_stack), level = "debug", ret)]
fn evaluate_trait_predicate_recursively<'o>(
&mut self,
previous_stack: TraitObligationStackList<'o, 'tcx>,
@@ -798,12 +788,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If a trait predicate is in the (local or global) evaluation cache,
// then we know it holds without cycles.
if let Some(result) = self.check_evaluation_cache(param_env, fresh_trait_pred) {
- debug!(?result, "CACHE HIT");
+ debug!("CACHE HIT");
return Ok(result);
}
if let Some(result) = stack.cache().get_provisional(fresh_trait_pred) {
- debug!(?result, "PROVISIONAL CACHE HIT");
+ debug!("PROVISIONAL CACHE HIT");
stack.update_reached_depth(result.reached_depth);
return Ok(result.result);
}
@@ -826,11 +816,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let reached_depth = stack.reached_depth.get();
if reached_depth >= stack.depth {
- debug!(?result, "CACHE MISS");
+ debug!("CACHE MISS");
self.insert_evaluation_cache(param_env, fresh_trait_pred, dep_node, result);
stack.cache().on_completion(stack.dfn);
} else {
- debug!(?result, "PROVISIONAL");
+ debug!("PROVISIONAL");
debug!(
"caching provisionally because {:?} \
is a cycle participant (at depth {}, reached depth {})",
@@ -1023,7 +1013,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(
level = "debug",
skip(self, stack),
- fields(depth = stack.obligation.recursion_depth)
+ fields(depth = stack.obligation.recursion_depth),
+ ret
)]
fn evaluate_candidate<'o>(
&mut self,
@@ -1056,7 +1047,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
result = result.max(EvaluatedToOkModuloRegions);
}
- debug!(?result);
Ok(result)
}
@@ -1265,11 +1255,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Ok(Some(candidate))
}
- fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Option<Conflict> {
+ fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
debug!("is_knowable(intercrate={:?})", self.intercrate);
if !self.intercrate || stack.obligation.polarity() == ty::ImplPolarity::Negative {
- return None;
+ return Ok(());
}
let obligation = &stack.obligation;
@@ -1405,7 +1395,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// a projection, look at the bounds of `T::Bar`, see if we can find a
/// `Baz` bound. We return indexes into the list returned by
/// `tcx.item_bounds` for any applicable bounds.
- #[instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
fn match_projection_obligation_against_definition_bounds(
&mut self,
obligation: &TraitObligation<'tcx>,
@@ -1435,7 +1425,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// unnecessary ambiguity.
let mut distinct_normalized_bounds = FxHashSet::default();
- let matching_bounds = bounds
+ bounds
.iter()
.enumerate()
.filter_map(|(idx, bound)| {
@@ -1462,10 +1452,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
None
})
- .collect();
-
- debug!(?matching_bounds);
- matching_bounds
+ .collect()
}
/// Equates the trait in `obligation` with trait bound. If the two traits
@@ -1618,7 +1605,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
};
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
- // `DiscriminantKindCandidate`, and `ConstDestructCandidate` to anything else.
+ // `DiscriminantKindCandidate`, `ConstDestructCandidate`, and `TupleCandidate`
+ // to anything else.
//
// This is a fix for #53123 and prevents winnowing from accidentally extending the
// lifetime of a variable.
@@ -1638,7 +1626,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
BuiltinCandidate { has_nested: false }
| DiscriminantKindCandidate
| PointeeCandidate
- | ConstDestructCandidate(_),
+ | ConstDestructCandidate(_)
+ | TupleCandidate,
_,
) => true,
(
@@ -1646,7 +1635,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
BuiltinCandidate { has_nested: false }
| DiscriminantKindCandidate
| PointeeCandidate
- | ConstDestructCandidate(_),
+ | ConstDestructCandidate(_)
+ | TupleCandidate,
) => false,
(ParamCandidate(other), ParamCandidate(victim)) => {
@@ -1871,6 +1861,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Array(..)
| ty::Closure(..)
| ty::Never
+ | ty::Dynamic(_, _, ty::DynStar)
| ty::Error(_) => {
// safe for everything
Where(ty::Binder::dummy(Vec::new()))
@@ -1937,8 +1928,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Dynamic(..)
| ty::Str
| ty::Slice(..)
- | ty::Generator(..)
- | ty::GeneratorWitness(..)
+ | ty::Generator(_, _, hir::Movability::Static)
| ty::Foreign(..)
| ty::Ref(_, _, hir::Mutability::Mut) => None,
@@ -1947,6 +1937,43 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Where(obligation.predicate.rebind(tys.iter().collect()))
}
+ ty::Generator(_, substs, hir::Movability::Movable) => {
+ if self.tcx().features().generator_clone {
+ let resolved_upvars =
+ self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
+ let resolved_witness =
+ self.infcx.shallow_resolve(substs.as_generator().witness());
+ if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
+ // Not yet resolved.
+ Ambiguous
+ } else {
+ let all = substs
+ .as_generator()
+ .upvar_tys()
+ .chain(iter::once(substs.as_generator().witness()))
+ .collect::<Vec<_>>();
+ Where(obligation.predicate.rebind(all))
+ }
+ } else {
+ None
+ }
+ }
+
+ ty::GeneratorWitness(binder) => {
+ let witness_tys = binder.skip_binder();
+ for witness_ty in witness_tys.iter() {
+ let resolved = self.infcx.shallow_resolve(witness_ty);
+ if resolved.is_ty_var() {
+ return Ambiguous;
+ }
+ }
+ // (*) binder moved here
+ let all_vars = self.tcx().mk_bound_variable_kinds(
+ obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
+ );
+ Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
+ }
+
ty::Closure(_, substs) => {
// (*) binder moved here
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
@@ -2153,7 +2180,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
fn match_impl(
&mut self,
impl_def_id: DefId,
@@ -2194,17 +2221,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.at(&cause, obligation.param_env)
.define_opaque_types(false)
.eq(placeholder_obligation_trait_ref, impl_trait_ref)
- .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
+ .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?;
nested_obligations.extend(obligations);
if !self.intercrate
&& self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
{
- debug!("match_impl: reservation impls only apply in intercrate mode");
+ debug!("reservation impls only apply in intercrate mode");
return Err(());
}
- debug!(?impl_substs, ?nested_obligations, "match_impl: success");
Ok(Normalized { value: impl_substs, obligations: nested_obligations })
}
@@ -2335,7 +2361,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// impl or trait. The obligations are substituted and fully
/// normalized. This is used when confirming an impl or default
/// impl.
- #[tracing::instrument(level = "debug", skip(self, cause, param_env))]
+ #[instrument(level = "debug", skip(self, cause, param_env))]
fn impl_or_trait_obligations(
&mut self,
cause: &ObligationCause<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 6223c5ea3..7d299e30a 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -12,11 +12,10 @@
pub mod specialization_graph;
use specialization_graph::GraphExt;
+use crate::errors::NegativePositiveConflict;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::select::IntercrateAmbiguityCause;
-use crate::traits::{
- self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine, TraitEngineExt,
-};
+use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -26,8 +25,8 @@ use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
use rustc_span::{Span, DUMMY_SP};
+use super::util;
use super::SelectionContext;
-use super::{util, FulfillmentContext};
/// Information pertinent to an overlapping impl error.
#[derive(Debug)]
@@ -153,7 +152,6 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
tcx.infer_ctxt().enter(|infcx| {
let impl1_trait_ref = match traits::fully_normalize(
&infcx,
- FulfillmentContext::new(),
ObligationCause::dummy(),
penv,
impl1_trait_ref,
@@ -211,11 +209,8 @@ fn fulfill_implication<'a, 'tcx>(
// (which are packed up in penv)
infcx.save_and_restore_in_snapshot_flag(|infcx| {
- let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
- for oblig in obligations.chain(more_obligations) {
- fulfill_cx.register_predicate_obligation(&infcx, oblig);
- }
- match fulfill_cx.select_all_or_error(infcx).as_slice() {
+ let errors = traits::fully_solve_obligations(&infcx, obligations.chain(more_obligations));
+ match &errors[..] {
[] => {
debug!(
"fulfill_implication: an impl for {:?} specializes {:?}",
@@ -333,35 +328,13 @@ fn report_negative_positive_conflict(
positive_impl_def_id: DefId,
sg: &mut specialization_graph::Graph,
) {
- let impl_span = tcx.def_span(local_impl_def_id);
-
- let mut err = struct_span_err!(
- tcx.sess,
- impl_span,
- E0751,
- "found both positive and negative implementation of trait `{}`{}:",
- overlap.trait_desc,
- overlap.self_desc.clone().map_or_else(String::new, |ty| format!(" for type `{}`", ty))
- );
-
- match tcx.span_of_impl(negative_impl_def_id) {
- Ok(span) => {
- err.span_label(span, "negative implementation here");
- }
- Err(cname) => {
- err.note(&format!("negative implementation in crate `{}`", cname));
- }
- }
-
- match tcx.span_of_impl(positive_impl_def_id) {
- Ok(span) => {
- err.span_label(span, "positive implementation here");
- }
- Err(cname) => {
- err.note(&format!("positive implementation in crate `{}`", cname));
- }
- }
-
+ let mut err = tcx.sess.create_err(NegativePositiveConflict {
+ impl_span: tcx.def_span(local_impl_def_id),
+ trait_desc: &overlap.trait_desc,
+ self_desc: &overlap.self_desc,
+ negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
+ positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
+ });
sg.has_errored = Some(err.emit());
}
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index d25006016..0f5dff01c 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -11,8 +11,6 @@ use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable
use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
pub use rustc_infer::traits::{self, util::*};
-use std::iter;
-
///////////////////////////////////////////////////////////////////////////
// `TraitAliasExpander` iterator
///////////////////////////////////////////////////////////////////////////
@@ -210,7 +208,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
let Normalized { value: predicates, obligations: normalization_obligations2 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
let impl_obligations =
- predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates);
+ super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);
let impl_obligations = impl_obligations
.chain(normalization_obligations1.into_iter())
@@ -219,27 +217,6 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
(subject, impl_obligations)
}
-pub fn predicates_for_generics<'tcx>(
- cause: ObligationCause<'tcx>,
- recursion_depth: usize,
- param_env: ty::ParamEnv<'tcx>,
- generic_bounds: ty::InstantiatedPredicates<'tcx>,
-) -> impl Iterator<Item = PredicateObligation<'tcx>> {
- debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
-
- iter::zip(generic_bounds.predicates, generic_bounds.spans).map(move |(predicate, span)| {
- let cause = match *cause.code() {
- traits::ItemObligation(def_id) if !span.is_dummy() => traits::ObligationCause::new(
- cause.span,
- cause.body_id,
- traits::BindingObligation(def_id, span),
- ),
- _ => cause.clone(),
- };
- Obligation { cause, recursion_depth, param_env, predicate }
- })
-}
-
pub fn predicate_for_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>,
cause: ObligationCause<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 414857f0a..5ea28fb47 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -31,9 +31,9 @@ pub fn obligations<'a, 'tcx>(
if resolved_ty == ty {
// No progress, bail out to prevent "livelock".
return None;
+ } else {
+ resolved_ty
}
-
- resolved_ty
}
_ => ty,
}
@@ -41,16 +41,14 @@ pub fn obligations<'a, 'tcx>(
}
GenericArgKind::Const(ct) => {
match ct.kind() {
- ty::ConstKind::Infer(infer) => {
- let resolved = infcx.shallow_resolve(infer);
- if resolved == infer {
+ ty::ConstKind::Infer(_) => {
+ let resolved = infcx.shallow_resolve(ct);
+ if resolved == ct {
// No progress.
return None;
+ } else {
+ resolved
}
-
- infcx
- .tcx
- .mk_const(ty::ConstS { kind: ty::ConstKind::Infer(resolved), ty: ct.ty() })
}
_ => ct,
}
@@ -103,6 +101,7 @@ pub fn trait_obligations<'a, 'tcx>(
wf.normalize(infcx)
}
+#[instrument(skip(infcx), ret)]
pub fn predicate_obligations<'a, 'tcx>(
infcx: &InferCtxt<'a, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
@@ -131,9 +130,9 @@ pub fn predicate_obligations<'a, 'tcx>(
}
ty::PredicateKind::Projection(t) => {
wf.compute_projection(t.projection_ty);
- wf.compute(match t.term {
- ty::Term::Ty(ty) => ty.into(),
- ty::Term::Const(c) => c.into(),
+ wf.compute(match t.term.unpack() {
+ ty::TermKind::Ty(ty) => ty.into(),
+ ty::TermKind::Const(c) => c.into(),
})
}
ty::PredicateKind::WellFormed(arg) => {
@@ -436,11 +435,13 @@ impl<'tcx> WfPredicates<'tcx> {
}
/// Pushes all the predicates needed to validate that `ty` is WF into `out`.
+ #[instrument(level = "debug", skip(self))]
fn compute(&mut self, arg: GenericArg<'tcx>) {
let mut walker = arg.walk();
let param_env = self.param_env;
let depth = self.recursion_depth;
while let Some(arg) = walker.next() {
+ debug!(?arg, ?self.out);
let ty = match arg.unpack() {
GenericArgKind::Type(ty) => ty,
@@ -455,7 +456,7 @@ impl<'tcx> WfPredicates<'tcx> {
self.out.extend(obligations);
let predicate =
- ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
+ ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
.to_predicate(self.tcx());
let cause = self.cause(traits::WellFormed(None));
self.out.push(traits::Obligation::with_depth(
@@ -490,6 +491,8 @@ impl<'tcx> WfPredicates<'tcx> {
}
};
+ debug!("wf bounds for ty={:?} ty.kind={:#?}", ty, ty.kind());
+
match *ty.kind() {
ty::Bool
| ty::Char
@@ -636,7 +639,7 @@ impl<'tcx> WfPredicates<'tcx> {
}
}
- ty::Dynamic(data, r) => {
+ ty::Dynamic(data, r, _) => {
// WfObject
//
// Here, we defer WF checking due to higher-ranked
@@ -688,6 +691,8 @@ impl<'tcx> WfPredicates<'tcx> {
));
}
}
+
+ debug!(?self.out);
}
}
@@ -713,7 +718,7 @@ impl<'tcx> WfPredicates<'tcx> {
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
.map(|((mut pred, span), origin_def_id)| {
let code = if span.is_dummy() {
- traits::MiscObligation
+ traits::ItemObligation(origin_def_id)
} else {
traits::BindingObligation(origin_def_id, span)
};
@@ -843,7 +848,7 @@ pub fn object_region_bounds<'tcx>(
///
/// Requires that trait definitions have been processed so that we can
/// elaborate predicates and walk supertraits.
-#[instrument(skip(tcx, predicates), level = "debug")]
+#[instrument(skip(tcx, predicates), level = "debug", ret)]
pub(crate) fn required_region_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
erased_self_ty: Ty<'tcx>,
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index c7c604e14..45d5ea93d 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -191,7 +191,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
GenericArgKind::Const(..) => {
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
}
- GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt),
+ GenericArgKind::Lifetime(lt) => bug!("unexpected well formed predicate: {:?}", lt),
},
ty::PredicateKind::ObjectSafe(t) => chalk_ir::GoalData::DomainGoal(
@@ -326,7 +326,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
)),
})
}
- ty::Dynamic(predicates, region) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy {
+ // FIXME(dyn-star): handle the dynamic kind (dyn or dyn*)
+ ty::Dynamic(predicates, region, _kind) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy {
bounds: predicates.lower_into(interner),
lifetime: region.lower_into(interner),
}),
@@ -485,10 +486,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
})
.intern(interner)
}
- ty::ReEmpty(ui) => {
- chalk_ir::LifetimeData::Empty(chalk_ir::UniverseIndex { counter: ui.index() })
- .intern(interner)
- }
ty::ReErased => chalk_ir::LifetimeData::Erased.intern(interner),
}
}
@@ -510,8 +507,8 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
name: ty::BoundRegionKind::BrAnon(p.idx as u32),
}),
chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
- chalk_ir::LifetimeData::Empty(ui) => {
- ty::ReEmpty(ty::UniverseIndex::from_usize(ui.counter))
+ chalk_ir::LifetimeData::Empty(_) => {
+ bug!("Chalk should not have been passed an empty lifetime.")
}
chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index e3e78f70b..691b79f10 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -49,7 +49,8 @@ fn compute_implied_outlives_bounds<'tcx>(
let mut checked_wf_args = rustc_data_structures::fx::FxHashSet::default();
let mut wf_args = vec![ty.into()];
- let mut implied_bounds = vec![];
+ let mut outlives_bounds: Vec<ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>> =
+ vec![];
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(tcx);
@@ -65,30 +66,17 @@ fn compute_implied_outlives_bounds<'tcx>(
// than the ultimate set. (Note: normally there won't be
// unresolved inference variables here anyway, but there might be
// during typeck under some circumstances.)
+ //
+ // FIXME(@lcnr): It's not really "always fine", having fewer implied
+ // bounds can be backward incompatible, e.g. #101951 was caused by
+ // us not dealing with inference vars in `TypeOutlives` predicates.
let obligations = wf::obligations(infcx, param_env, hir::CRATE_HIR_ID, 0, arg, DUMMY_SP)
.unwrap_or_default();
- // N.B., all of these predicates *ought* to be easily proven
- // true. In fact, their correctness is (mostly) implied by
- // other parts of the program. However, in #42552, we had
- // an annoying scenario where:
- //
- // - Some `T::Foo` gets normalized, resulting in a
- // variable `_1` and a `T: Trait<Foo=_1>` constraint
- // (not sure why it couldn't immediately get
- // solved). This result of `_1` got cached.
- // - These obligations were dropped on the floor here,
- // rather than being registered.
- // - Then later we would get a request to normalize
- // `T::Foo` which would result in `_1` being used from
- // the cache, but hence without the `T: Trait<Foo=_1>`
- // constraint. As a result, `_1` never gets resolved,
- // and we get an ICE (in dropck).
- //
- // Therefore, we register any predicates involving
- // inference variables. We restrict ourselves to those
- // involving inference variables both for efficiency and
- // to avoids duplicate errors that otherwise show up.
+ // While these predicates should all be implied by other parts of
+ // the program, they are still relevant as they may constrain
+ // inference variables, which is necessary to add the correct
+ // implied bounds in some cases, mostly when dealing with projections.
fulfill_cx.register_predicate_obligations(
infcx,
obligations.iter().filter(|o| o.predicate.has_infer_types_or_consts()).cloned(),
@@ -96,10 +84,10 @@ fn compute_implied_outlives_bounds<'tcx>(
// From the full set of obligations, just filter down to the
// region relationships.
- implied_bounds.extend(obligations.into_iter().flat_map(|obligation| {
+ outlives_bounds.extend(obligations.into_iter().filter_map(|obligation| {
assert!(!obligation.has_escaping_bound_vars());
match obligation.predicate.kind().no_bound_vars() {
- None => vec![],
+ None => None,
Some(pred) => match pred {
ty::PredicateKind::Trait(..)
| ty::PredicateKind::Subtype(..)
@@ -109,21 +97,18 @@ fn compute_implied_outlives_bounds<'tcx>(
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
- | ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![],
+ | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::WellFormed(arg) => {
wf_args.push(arg);
- vec![]
+ None
}
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
- vec![OutlivesBound::RegionSubRegion(r_b, r_a)]
+ Some(ty::OutlivesPredicate(r_a.into(), r_b))
}
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_a, r_b)) => {
- let ty_a = infcx.resolve_vars_if_possible(ty_a);
- let mut components = smallvec![];
- push_outlives_components(tcx, ty_a, &mut components);
- implied_bounds_from_components(r_b, components)
+ Some(ty::OutlivesPredicate(ty_a.into(), r_b))
}
},
}
@@ -133,9 +118,27 @@ fn compute_implied_outlives_bounds<'tcx>(
// Ensure that those obligations that we had to solve
// get solved *here*.
match fulfill_cx.select_all_or_error(infcx).as_slice() {
- [] => Ok(implied_bounds),
- _ => Err(NoSolution),
+ [] => (),
+ _ => return Err(NoSolution),
}
+
+ // We lazily compute the outlives components as
+ // `select_all_or_error` constrains inference variables.
+ let implied_bounds = outlives_bounds
+ .into_iter()
+ .flat_map(|ty::OutlivesPredicate(a, r_b)| match a.unpack() {
+ ty::GenericArgKind::Lifetime(r_a) => vec![OutlivesBound::RegionSubRegion(r_b, r_a)],
+ ty::GenericArgKind::Type(ty_a) => {
+ let ty_a = infcx.resolve_vars_if_possible(ty_a);
+ let mut components = smallvec![];
+ push_outlives_components(tcx, ty_a, &mut components);
+ implied_bounds_from_components(r_b, components)
+ }
+ ty::GenericArgKind::Const(_) => unreachable!(),
+ })
+ .collect();
+
+ Ok(implied_bounds)
}
/// When we have an implied bound that `T: 'a`, we can further break
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 2bea164c0..2d39e973e 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -1,7 +1,9 @@
//! New recursive solver modeled on Chalk's recursive solver. Most of
//! the guts are broken up into modules; see the comments in those modules.
-#![feature(let_else)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![recursion_limit = "256"]
#[macro_use]
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index d895b647d..1bb6506b3 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::TraitEngineExt as _;
+use rustc_infer::traits::{ObligationCauseCode, TraitEngineExt as _};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts};
use rustc_middle::ty::{
@@ -22,6 +22,7 @@ use rustc_trait_selection::traits::query::type_op::subtype::Subtype;
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, TraitEngine};
use std::fmt;
+use std::iter::zip;
pub(crate) fn provide(p: &mut Providers) {
*p = Providers {
@@ -61,14 +62,15 @@ pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>(
mir_ty, def_id, user_substs
);
- let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx };
- cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs, span)?;
+ let mut cx = AscribeUserTypeCx { infcx, param_env, span: span.unwrap_or(DUMMY_SP), fulfill_cx };
+ cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?;
Ok(())
}
struct AscribeUserTypeCx<'me, 'tcx> {
infcx: &'me InferCtxt<'me, 'tcx>,
param_env: ParamEnv<'tcx>,
+ span: Span,
fulfill_cx: &'me mut dyn TraitEngine<'tcx>,
}
@@ -77,12 +79,15 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
where
T: TypeFoldable<'tcx>,
{
+ self.normalize_with_cause(value, ObligationCause::misc(self.span, hir::CRATE_HIR_ID))
+ }
+
+ fn normalize_with_cause<T>(&mut self, value: T, cause: ObligationCause<'tcx>) -> T
+ where
+ T: TypeFoldable<'tcx>,
+ {
self.infcx
- .partially_normalize_associated_types_in(
- ObligationCause::misc(DUMMY_SP, hir::CRATE_HIR_ID),
- self.param_env,
- value,
- )
+ .partially_normalize_associated_types_in(cause, self.param_env, value)
.into_value_registering_obligations(self.infcx, self.fulfill_cx)
}
@@ -91,18 +96,13 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
T: ToTrace<'tcx>,
{
self.infcx
- .at(&ObligationCause::dummy(), self.param_env)
+ .at(&ObligationCause::dummy_with_span(self.span), self.param_env)
.relate(a, variance, b)?
.into_value_registering_obligations(self.infcx, self.fulfill_cx);
Ok(())
}
- fn prove_predicate(&mut self, predicate: Predicate<'tcx>, span: Option<Span>) {
- let cause = if let Some(span) = span {
- ObligationCause::dummy_with_span(span)
- } else {
- ObligationCause::dummy()
- };
+ fn prove_predicate(&mut self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) {
self.fulfill_cx.register_predicate_obligation(
self.infcx,
Obligation::new(cause, self.param_env, predicate),
@@ -120,20 +120,20 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
EarlyBinder(value).subst(self.tcx(), substs)
}
+ #[instrument(level = "debug", skip(self))]
fn relate_mir_and_user_ty(
&mut self,
mir_ty: Ty<'tcx>,
def_id: DefId,
user_substs: UserSubsts<'tcx>,
- span: Option<Span>,
) -> Result<(), NoSolution> {
let UserSubsts { user_self_ty, substs } = user_substs;
let tcx = self.tcx();
let ty = tcx.type_of(def_id);
let ty = self.subst(ty, substs);
- debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
let ty = self.normalize(ty);
+ debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
self.relate(mir_ty, Variance::Invariant, ty)?;
@@ -144,10 +144,22 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
// outlives" error messages.
let instantiated_predicates =
self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);
- debug!(?instantiated_predicates.predicates);
- for instantiated_predicate in instantiated_predicates.predicates {
- let instantiated_predicate = self.normalize(instantiated_predicate);
- self.prove_predicate(instantiated_predicate, span);
+
+ let cause = ObligationCause::dummy_with_span(self.span);
+
+ debug!(?instantiated_predicates);
+ for (instantiated_predicate, predicate_span) in
+ zip(instantiated_predicates.predicates, instantiated_predicates.spans)
+ {
+ let span = if self.span == DUMMY_SP { predicate_span } else { self.span };
+ let cause = ObligationCause::new(
+ span,
+ hir::CRATE_HIR_ID,
+ ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
+ );
+ let instantiated_predicate =
+ self.normalize_with_cause(instantiated_predicate, cause.clone());
+ self.prove_predicate(instantiated_predicate, cause);
}
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
@@ -160,7 +172,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()))
.to_predicate(self.tcx()),
- span,
+ cause.clone(),
);
}
@@ -177,7 +189,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
// which...could happen with normalization...
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(self.tcx()),
- span,
+ cause,
);
Ok(())
}
diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml
index 9dc96e08a..aa6fe7d24 100644
--- a/compiler/rustc_transmute/Cargo.toml
+++ b/compiler/rustc_transmute/Cargo.toml
@@ -7,7 +7,8 @@ edition = "2021"
[dependencies]
tracing = "0.1"
-rustc_data_structures = { path = "../rustc_data_structures", optional = true}
+rustc_data_structures = { path = "../rustc_data_structures"}
+rustc_hir = { path = "../rustc_hir", optional = true}
rustc_infer = { path = "../rustc_infer", optional = true}
rustc_macros = { path = "../rustc_macros", optional = true}
rustc_middle = { path = "../rustc_middle", optional = true}
@@ -17,7 +18,7 @@ rustc_target = { path = "../rustc_target", optional = true}
[features]
rustc = [
"rustc_middle",
- "rustc_data_structures",
+ "rustc_hir",
"rustc_infer",
"rustc_macros",
"rustc_span",
diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs
index b60ea6e7a..b8922696e 100644
--- a/compiler/rustc_transmute/src/layout/dfa.rs
+++ b/compiler/rustc_transmute/src/layout/dfa.rs
@@ -104,7 +104,6 @@ where
}
#[instrument(level = "debug")]
- #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))]
pub(crate) fn from_nfa(nfa: Nfa<R>) -> Self {
let Nfa { transitions: nfa_transitions, start: nfa_start, accepting: nfa_accepting } = nfa;
diff --git a/compiler/rustc_transmute/src/layout/nfa.rs b/compiler/rustc_transmute/src/layout/nfa.rs
index f25e3c1fd..c2bc47bc0 100644
--- a/compiler/rustc_transmute/src/layout/nfa.rs
+++ b/compiler/rustc_transmute/src/layout/nfa.rs
@@ -119,8 +119,6 @@ where
let mut transitions: Map<State, Map<Transition<R>, Set<State>>> = self.transitions;
- // the iteration order doesn't matter
- #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))]
for (source, transition) in other.transitions {
let fix_state = |state| if state == other.start { self.accepting } else { state };
let entry = transitions.entry(fix_state(source)).or_default();
@@ -142,8 +140,6 @@ where
let mut transitions: Map<State, Map<Transition<R>, Set<State>>> = self.transitions.clone();
- // the iteration order doesn't matter
- #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))]
for (&(mut source), transition) in other.transitions.iter() {
// if source is starting state of `other`, replace with starting state of `self`
if source == other.start {
@@ -152,8 +148,6 @@ where
let entry = transitions.entry(source).or_default();
for (edge, destinations) in transition {
let entry = entry.entry(edge.clone()).or_default();
- // the iteration order doesn't matter
- #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))]
for &(mut destination) in destinations {
// if dest is accepting state of `other`, replace with accepting state of `self`
if destination == other.accepting {
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 70b3ba02b..211c813b8 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -1,4 +1,5 @@
use super::{Byte, Def, Ref};
+use std::ops::ControlFlow;
#[cfg(test)]
mod tests;
@@ -86,17 +87,18 @@ where
F: Fn(D) -> bool,
{
match self {
- Self::Seq(elts) => elts
- .into_iter()
- .map(|elt| elt.prune(f))
- .try_fold(Tree::unit(), |elts, elt| {
+ Self::Seq(elts) => match elts.into_iter().map(|elt| elt.prune(f)).try_fold(
+ Tree::unit(),
+ |elts, elt| {
if elt == Tree::uninhabited() {
- Err(Tree::uninhabited())
+ ControlFlow::Break(Tree::uninhabited())
} else {
- Ok(elts.then(elt))
+ ControlFlow::Continue(elts.then(elt))
}
- })
- .into_ok_or_err(),
+ },
+ ) {
+ ControlFlow::Break(node) | ControlFlow::Continue(node) => node,
+ },
Self::Alt(alts) => alts
.into_iter()
.map(|alt| alt.prune(f))
@@ -315,7 +317,7 @@ pub(crate) mod rustc {
tcx,
)?,
AdtKind::Enum => {
- tracing::trace!(?adt_def, "treeifying enum");
+ trace!(?adt_def, "treeifying enum");
let mut tree = Tree::uninhabited();
for (idx, discr) in adt_def.discriminants(tcx) {
@@ -379,7 +381,7 @@ pub(crate) mod rustc {
let clamp =
|align: Align| align.clamp(min_align, max_align).bytes().try_into().unwrap();
- let variant_span = tracing::trace_span!(
+ let variant_span = trace_span!(
"treeifying variant",
min_align = ?min_align,
max_align = ?max_align,
@@ -394,27 +396,27 @@ pub(crate) mod rustc {
// The layout of the variant is prefixed by the discriminant, if any.
if let Some(discr) = discr {
- tracing::trace!(?discr, "treeifying discriminant");
+ trace!(?discr, "treeifying discriminant");
let discr_layout = alloc::Layout::from_size_align(
layout_summary.discriminant_size,
clamp(layout_summary.discriminant_align),
)
.unwrap();
- tracing::trace!(?discr_layout, "computed discriminant layout");
+ trace!(?discr_layout, "computed discriminant layout");
variant_layout = variant_layout.extend(discr_layout).unwrap().0;
tree = tree.then(Self::from_disr(discr, tcx, layout_summary.discriminant_size));
}
// Next come fields.
- let fields_span = tracing::trace_span!("treeifying fields").entered();
+ let fields_span = trace_span!("treeifying fields").entered();
for field_def in variant_def.fields.iter() {
let field_ty = field_def.ty(tcx, substs_ref);
- let _span = tracing::trace_span!("treeifying field", field = ?field_ty).entered();
+ let _span = trace_span!("treeifying field", field = ?field_ty).entered();
// begin with the field's visibility
tree = tree.then(Self::def(Def::Field(field_def)));
- // compute the field's layout charactaristics
+ // compute the field's layout characteristics
let field_layout = layout_of(tcx, field_ty)?.clamp_align(min_align, max_align);
// next comes the field's padding
@@ -432,7 +434,7 @@ pub(crate) mod rustc {
drop(fields_span);
// finally: padding
- let padding_span = tracing::trace_span!("adding trailing padding").entered();
+ let padding_span = trace_span!("adding trailing padding").entered();
let padding_needed = layout_summary.total_size - variant_layout.size();
if padding_needed > 0 {
tree = tree.then(Self::padding(padding_needed));
@@ -465,7 +467,7 @@ pub(crate) mod rustc {
layout.align().abi.bytes().try_into().unwrap(),
)
.unwrap();
- tracing::trace!(?ty, ?layout, "computed layout for type");
+ trace!(?ty, ?layout, "computed layout for type");
Ok(layout)
}
}
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index cfc7c752a..64cd70d36 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -1,21 +1,12 @@
-#![feature(
- alloc_layout_extra,
- control_flow_enum,
- decl_macro,
- iterator_try_reduce,
- never_type,
- result_into_ok_or_err
-)]
+#![feature(alloc_layout_extra, control_flow_enum, decl_macro, iterator_try_reduce, never_type)]
#![allow(dead_code, unused_variables)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
-#[cfg(feature = "rustc")]
-pub(crate) use rustc_data_structures::fx::{FxHashMap as Map, FxHashSet as Set};
-
-#[cfg(not(feature = "rustc"))]
-pub(crate) use std::collections::{HashMap as Map, HashSet as Set};
+pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};
pub(crate) mod layout;
pub(crate) mod maybe_transmutable;
@@ -24,8 +15,8 @@ pub(crate) mod maybe_transmutable;
pub struct Assume {
pub alignment: bool,
pub lifetimes: bool,
+ pub safety: bool,
pub validity: bool,
- pub visibility: bool,
}
/// The type encodes answers to the question: "Are these types transmutable?"
@@ -67,11 +58,17 @@ pub enum Reason {
#[cfg(feature = "rustc")]
mod rustc {
+ use super::*;
+
+ use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::InferCtxt;
use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::Binder;
+ use rustc_middle::ty::Const;
+ use rustc_middle::ty::ParamEnv;
use rustc_middle::ty::Ty;
+ use rustc_middle::ty::TyCtxt;
/// The source and destination types of a transmutation.
#[derive(TypeFoldable, TypeVisitable, Debug, Clone, Copy)]
@@ -111,6 +108,54 @@ mod rustc {
.answer()
}
}
+
+ impl Assume {
+ /// Constructs an `Assume` from a given const-`Assume`.
+ pub fn from_const<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ c: Const<'tcx>,
+ ) -> Self {
+ use rustc_middle::ty::ScalarInt;
+ use rustc_middle::ty::TypeVisitable;
+ use rustc_span::symbol::sym;
+
+ let c = c.eval(tcx, param_env);
+
+ if let Some(err) = c.error_reported() {
+ return Self { alignment: true, lifetimes: true, safety: true, validity: true };
+ }
+
+ let adt_def = c.ty().ty_adt_def().expect("The given `Const` must be an ADT.");
+
+ assert_eq!(
+ tcx.require_lang_item(LangItem::TransmuteOpts, None),
+ adt_def.did(),
+ "The given `Const` was not marked with the `{}` lang item.",
+ LangItem::TransmuteOpts.name(),
+ );
+
+ let variant = adt_def.non_enum_variant();
+ let fields = c.to_valtree().unwrap_branch();
+
+ let get_field = |name| {
+ let (field_idx, _) = variant
+ .fields
+ .iter()
+ .enumerate()
+ .find(|(_, field_def)| name == field_def.name)
+ .expect(&format!("There were no fields named `{name}`."));
+ fields[field_idx].unwrap_leaf() == ScalarInt::TRUE
+ };
+
+ Self {
+ alignment: get_field(sym::alignment),
+ lifetimes: get_field(sym::lifetimes),
+ safety: get_field(sym::safety),
+ validity: get_field(sym::validity),
+ }
+ }
+ }
}
#[cfg(feature = "rustc")]
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
index 076d922d1..1186eac37 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
@@ -105,12 +105,12 @@ where
#[inline(always)]
#[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))]
pub(crate) fn answer(self) -> Answer<<C as QueryContext>::Ref> {
- let assume_visibility = self.assume.visibility;
+ let assume_visibility = self.assume.safety;
let query_or_answer = self.map_layouts(|src, dst, scope, context| {
// Remove all `Def` nodes from `src`, without checking their visibility.
let src = src.prune(&|def| true);
- tracing::trace!(?src, "pruned src");
+ trace!(?src, "pruned src");
// Remove all `Def` nodes from `dst`, additionally...
let dst = if assume_visibility {
@@ -121,7 +121,7 @@ where
dst.prune(&|def| context.is_accessible_from(def, scope))
};
- tracing::trace!(?dst, "pruned dst");
+ trace!(?dst, "pruned dst");
// Convert `src` from a tree-based representation to an NFA-based representation.
// If the conversion fails because `src` is uninhabited, conclude that the transmutation
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
index 9c2cf4c9a..adab343ac 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
@@ -82,7 +82,7 @@ mod rustc {
false
};
- tracing::trace!(?ret, "ret");
+ trace!(?ret, "ret");
ret
}
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
index d9d125687..4d5772a4f 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
@@ -13,7 +13,7 @@ mod bool {
layout::Tree::<Def, !>::bool(),
layout::Tree::<Def, !>::bool(),
(),
- crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false },
+ crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
UltraMinimal,
)
.answer();
@@ -26,7 +26,7 @@ mod bool {
layout::Dfa::<!>::bool(),
layout::Dfa::<!>::bool(),
(),
- crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false },
+ crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
UltraMinimal,
)
.answer();
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml
index caad2ed42..52fbd3ae0 100644
--- a/compiler/rustc_ty_utils/Cargo.toml
+++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -10,6 +10,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
rustc_infer = { path = "../rustc_infer" }
+rustc_macros = { path = "../rustc_macros" }
rustc_span = { path = "../rustc_span" }
rustc_session = { path = "../rustc_session" }
rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 7c2f4db94..44c4fc48d 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -11,6 +11,8 @@ use rustc_target::abi::VariantIdx;
use std::iter;
+use crate::errors::{GenericConstantTooComplex, GenericConstantTooComplexSub};
+
/// Destructures array, ADT or tuple constants into the constants
/// of their fields.
pub(crate) fn destructure_const<'tcx>(
@@ -93,26 +95,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
self.body.exprs[self.body_id].span
}
- fn error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> {
- let reported = self
- .tcx
- .sess
- .struct_span_err(self.root_span(), "overly complex generic constant")
- .span_label(span, msg)
- .help("consider moving this anonymous constant into a `const` function")
- .emit();
+ fn error(&mut self, sub: GenericConstantTooComplexSub) -> Result<!, ErrorGuaranteed> {
+ let reported = self.tcx.sess.emit_err(GenericConstantTooComplex {
+ span: self.root_span(),
+ maybe_supported: None,
+ sub,
+ });
Err(reported)
}
- fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> {
- let reported = self
- .tcx
- .sess
- .struct_span_err(self.root_span(), "overly complex generic constant")
- .span_label(span, msg)
- .help("consider moving this anonymous constant into a `const` function")
- .note("this operation may be supported in the future")
- .emit();
+
+ fn maybe_supported_error(
+ &mut self,
+ sub: GenericConstantTooComplexSub,
+ ) -> Result<!, ErrorGuaranteed> {
+ let reported = self.tcx.sess.emit_err(GenericConstantTooComplex {
+ span: self.root_span(),
+ maybe_supported: Some(()),
+ sub,
+ });
Err(reported)
}
@@ -154,9 +155,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
return true;
}
- match pat.kind.as_ref() {
+ match pat.kind {
thir::PatKind::Constant { value } => value.has_param_types_or_consts(),
- thir::PatKind::Range(thir::PatRange { lo, hi, .. }) => {
+ thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => {
lo.has_param_types_or_consts() || hi.has_param_types_or_consts()
}
_ => false,
@@ -221,17 +222,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
debug!("AbstractConstBuilder::build: body={:?}", &*self.body);
self.recurse_build(self.body_id)?;
- for n in self.nodes.iter() {
- if let Node::Leaf(ct) = n {
- if let ty::ConstKind::Unevaluated(ct) = ct.kind() {
- // `AbstractConst`s should not contain any promoteds as they require references which
- // are not allowed.
- assert_eq!(ct.promoted, None);
- assert_eq!(ct, self.tcx.erase_regions(ct));
- }
- }
- }
-
Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter()))
}
@@ -243,22 +233,23 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
&ExprKind::Scope { value, .. } => self.recurse_build(value)?,
&ExprKind::PlaceTypeAscription { source, .. }
| &ExprKind::ValueTypeAscription { source, .. } => self.recurse_build(source)?,
- &ExprKind::Literal { lit, neg} => {
+ &ExprKind::Literal { lit, neg } => {
let sp = node.span;
- let constant =
- match self.tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) {
- Ok(c) => c,
- Err(LitToConstError::Reported) => {
- self.tcx.const_error(node.ty)
- }
- Err(LitToConstError::TypeError) => {
- bug!("encountered type error in lit_to_const")
- }
- };
+ let constant = match self.tcx.at(sp).lit_to_const(LitToConstInput {
+ lit: &lit.node,
+ ty: node.ty,
+ neg,
+ }) {
+ Ok(c) => c,
+ Err(LitToConstError::Reported) => self.tcx.const_error(node.ty),
+ Err(LitToConstError::TypeError) => {
+ bug!("encountered type error in lit_to_const")
+ }
+ };
self.nodes.push(Node::Leaf(constant))
}
- &ExprKind::NonHirLiteral { lit , user_ty: _} => {
+ &ExprKind::NonHirLiteral { lit, user_ty: _ } => {
let val = ty::ValTree::from_scalar_int(lit);
self.nodes.push(Node::Leaf(ty::Const::from_value(self.tcx, val, node.ty)))
}
@@ -269,19 +260,17 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
&ExprKind::NamedConst { def_id, substs, user_ty: _ } => {
let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
- let constant = self.tcx.mk_const(ty::ConstS {
- kind: ty::ConstKind::Unevaluated(uneval),
- ty: node.ty,
- });
+ let constant = self
+ .tcx
+ .mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty: node.ty });
self.nodes.push(Node::Leaf(constant))
}
- ExprKind::ConstParam {param, ..} => {
- let const_param = self.tcx.mk_const(ty::ConstS {
- kind: ty::ConstKind::Param(*param),
- ty: node.ty,
- });
+ ExprKind::ConstParam { param, .. } => {
+ let const_param = self
+ .tcx
+ .mk_const(ty::ConstS { kind: ty::ConstKind::Param(*param), ty: node.ty });
self.nodes.push(Node::Leaf(const_param))
}
@@ -311,8 +300,15 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
// bar::<{ N + 1 }>();
// }
// ```
- ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. } } => {
- self.recurse_build(*e)?
+ ExprKind::Block { block } => {
+ if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block]
+ {
+ self.recurse_build(*e)?
+ } else {
+ self.maybe_supported_error(GenericConstantTooComplexSub::BlockNotSupported(
+ node.span,
+ ))?
+ }
}
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
// "coercion cast" i.e. using a coercion or is a no-op.
@@ -325,7 +321,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
let arg = self.recurse_build(source)?;
self.nodes.push(Node::Cast(CastKind::As, arg, node.ty))
}
- ExprKind::Borrow{ arg, ..} => {
+ ExprKind::Borrow { arg, .. } => {
let arg_node = &self.body.exprs[*arg];
// Skip reborrows for now until we allow Deref/Borrow/AddressOf
@@ -334,80 +330,69 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
if let ExprKind::Deref { arg } = arg_node.kind {
self.recurse_build(arg)?
} else {
- self.maybe_supported_error(
+ self.maybe_supported_error(GenericConstantTooComplexSub::BorrowNotSupported(
node.span,
- "borrowing is not supported in generic constants",
- )?
+ ))?
}
}
// FIXME(generic_const_exprs): We may want to support these.
- ExprKind::AddressOf { .. } | ExprKind::Deref {..}=> self.maybe_supported_error(
- node.span,
- "dereferencing or taking the address is not supported in generic constants",
- )?,
- ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error(
- node.span,
- "array construction is not supported in generic constants",
+ ExprKind::AddressOf { .. } | ExprKind::Deref { .. } => self.maybe_supported_error(
+ GenericConstantTooComplexSub::AddressAndDerefNotSupported(node.span),
)?,
- ExprKind::Block { .. } => self.maybe_supported_error(
- node.span,
- "blocks are not supported in generic constant",
+ ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error(
+ GenericConstantTooComplexSub::ArrayNotSupported(node.span),
)?,
ExprKind::NeverToAny { .. } => self.maybe_supported_error(
- node.span,
- "converting nevers to any is not supported in generic constant",
+ GenericConstantTooComplexSub::NeverToAnyNotSupported(node.span),
)?,
ExprKind::Tuple { .. } => self.maybe_supported_error(
- node.span,
- "tuple construction is not supported in generic constants",
+ GenericConstantTooComplexSub::TupleNotSupported(node.span),
)?,
ExprKind::Index { .. } => self.maybe_supported_error(
- node.span,
- "indexing is not supported in generic constant",
+ GenericConstantTooComplexSub::IndexNotSupported(node.span),
)?,
ExprKind::Field { .. } => self.maybe_supported_error(
- node.span,
- "field access is not supported in generic constant",
+ GenericConstantTooComplexSub::FieldNotSupported(node.span),
)?,
ExprKind::ConstBlock { .. } => self.maybe_supported_error(
- node.span,
- "const blocks are not supported in generic constant",
- )?,
- ExprKind::Adt(_) => self.maybe_supported_error(
- node.span,
- "struct/enum construction is not supported in generic constants",
+ GenericConstantTooComplexSub::ConstBlockNotSupported(node.span),
)?,
+ ExprKind::Adt(_) => self
+ .maybe_supported_error(GenericConstantTooComplexSub::AdtNotSupported(node.span))?,
// dont know if this is correct
- ExprKind::Pointer { .. } =>
- self.error(node.span, "pointer casts are not allowed in generic constants")?,
- ExprKind::Yield { .. } =>
- self.error(node.span, "generator control flow is not allowed in generic constants")?,
- ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => self
- .error(
- node.span,
- "loops and loop control flow are not supported in generic constants",
- )?,
- ExprKind::Box { .. } =>
- self.error(node.span, "allocations are not allowed in generic constants")?,
+ ExprKind::Pointer { .. } => {
+ self.error(GenericConstantTooComplexSub::PointerNotSupported(node.span))?
+ }
+ ExprKind::Yield { .. } => {
+ self.error(GenericConstantTooComplexSub::YieldNotSupported(node.span))?
+ }
+ ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => {
+ self.error(GenericConstantTooComplexSub::LoopNotSupported(node.span))?
+ }
+ ExprKind::Box { .. } => {
+ self.error(GenericConstantTooComplexSub::BoxNotSupported(node.span))?
+ }
ExprKind::Unary { .. } => unreachable!(),
// we handle valid unary/binary ops above
- ExprKind::Binary { .. } =>
- self.error(node.span, "unsupported binary operation in generic constants")?,
- ExprKind::LogicalOp { .. } =>
- self.error(node.span, "unsupported operation in generic constants, short-circuiting operations would imply control flow")?,
+ ExprKind::Binary { .. } => {
+ self.error(GenericConstantTooComplexSub::BinaryNotSupported(node.span))?
+ }
+ ExprKind::LogicalOp { .. } => {
+ self.error(GenericConstantTooComplexSub::LogicalOpNotSupported(node.span))?
+ }
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
- self.error(node.span, "assignment is not supported in generic constants")?
+ self.error(GenericConstantTooComplexSub::AssignNotSupported(node.span))?
+ }
+ ExprKind::Closure { .. } | ExprKind::Return { .. } => {
+ self.error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))?
}
- ExprKind::Closure { .. } | ExprKind::Return { .. } => self.error(
- node.span,
- "closures and function keywords are not supported in generic constants",
- )?,
// let expressions imply control flow
- ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } =>
- self.error(node.span, "control flow is not supported in generic constants")?,
+ ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => {
+ self.error(GenericConstantTooComplexSub::ControlFlowNotSupported(node.span))?
+ }
ExprKind::InlineAsm { .. } => {
- self.error(node.span, "assembly is not supported in generic constants")?
+ self.error(GenericConstantTooComplexSub::InlineAsmNotSupported(node.span))?
}
// we dont permit let stmts so `VarRef` and `UpvarRef` cant happen
@@ -415,7 +400,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
| ExprKind::UpvarRef { .. }
| ExprKind::StaticRef { .. }
| ExprKind::ThreadLocalRef(_) => {
- self.error(node.span, "unsupported operation in generic constant")?
+ self.error(GenericConstantTooComplexSub::OperationNotSupported(node.span))?
}
})
}
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
new file mode 100644
index 000000000..3a8ef96c9
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -0,0 +1,69 @@
+//! Errors emitted by ty_utils
+
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_middle::ty::Ty;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[diag(ty_utils::needs_drop_overflow)]
+pub struct NeedsDropOverflow<'tcx> {
+ pub query_ty: Ty<'tcx>,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(ty_utils::generic_constant_too_complex)]
+#[help]
+pub struct GenericConstantTooComplex {
+ #[primary_span]
+ pub span: Span,
+ #[note(ty_utils::maybe_supported)]
+ pub maybe_supported: Option<()>,
+ #[subdiagnostic]
+ pub sub: GenericConstantTooComplexSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum GenericConstantTooComplexSub {
+ #[label(ty_utils::borrow_not_supported)]
+ BorrowNotSupported(#[primary_span] Span),
+ #[label(ty_utils::address_and_deref_not_supported)]
+ AddressAndDerefNotSupported(#[primary_span] Span),
+ #[label(ty_utils::array_not_supported)]
+ ArrayNotSupported(#[primary_span] Span),
+ #[label(ty_utils::block_not_supported)]
+ BlockNotSupported(#[primary_span] Span),
+ #[label(ty_utils::never_to_any_not_supported)]
+ NeverToAnyNotSupported(#[primary_span] Span),
+ #[label(ty_utils::tuple_not_supported)]
+ TupleNotSupported(#[primary_span] Span),
+ #[label(ty_utils::index_not_supported)]
+ IndexNotSupported(#[primary_span] Span),
+ #[label(ty_utils::field_not_supported)]
+ FieldNotSupported(#[primary_span] Span),
+ #[label(ty_utils::const_block_not_supported)]
+ ConstBlockNotSupported(#[primary_span] Span),
+ #[label(ty_utils::adt_not_supported)]
+ AdtNotSupported(#[primary_span] Span),
+ #[label(ty_utils::pointer_not_supported)]
+ PointerNotSupported(#[primary_span] Span),
+ #[label(ty_utils::yield_not_supported)]
+ YieldNotSupported(#[primary_span] Span),
+ #[label(ty_utils::loop_not_supported)]
+ LoopNotSupported(#[primary_span] Span),
+ #[label(ty_utils::box_not_supported)]
+ BoxNotSupported(#[primary_span] Span),
+ #[label(ty_utils::binary_not_supported)]
+ BinaryNotSupported(#[primary_span] Span),
+ #[label(ty_utils::logical_op_not_supported)]
+ LogicalOpNotSupported(#[primary_span] Span),
+ #[label(ty_utils::assign_not_supported)]
+ AssignNotSupported(#[primary_span] Span),
+ #[label(ty_utils::closure_and_return_not_supported)]
+ ClosureAndReturnNotSupported(#[primary_span] Span),
+ #[label(ty_utils::control_flow_not_supported)]
+ ControlFlowNotSupported(#[primary_span] Span),
+ #[label(ty_utils::inline_asm_not_supported)]
+ InlineAsmNotSupported(#[primary_span] Span),
+ #[label(ty_utils::operation_not_supported)]
+ OperationNotSupported(#[primary_span] Span),
+}
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
new file mode 100644
index 000000000..f0d8c240e
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -0,0 +1,61 @@
+use crate::rustc_middle::ty::DefIdTree;
+use rustc_hir::{def::DefKind, def_id::DefId};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+
+pub fn provide(providers: &mut ty::query::Providers) {
+ *providers = ty::query::Providers { assumed_wf_types, ..*providers };
+}
+
+fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List<Ty<'tcx>> {
+ match tcx.def_kind(def_id) {
+ DefKind::Fn => {
+ let sig = tcx.fn_sig(def_id);
+ let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
+ liberated_sig.inputs_and_output
+ }
+ DefKind::AssocFn => {
+ let sig = tcx.fn_sig(def_id);
+ let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
+ let mut assumed_wf_types: Vec<_> =
+ tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into();
+ assumed_wf_types.extend(liberated_sig.inputs_and_output);
+ tcx.intern_type_list(&assumed_wf_types)
+ }
+ DefKind::Impl => match tcx.impl_trait_ref(def_id) {
+ Some(trait_ref) => {
+ let types: Vec<_> = trait_ref.substs.types().collect();
+ tcx.intern_type_list(&types)
+ }
+ // Only the impl self type
+ None => tcx.intern_type_list(&[tcx.type_of(def_id)]),
+ },
+ DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
+ DefKind::Mod
+ | DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Trait
+ | DefKind::TyAlias
+ | DefKind::ForeignTy
+ | DefKind::TraitAlias
+ | DefKind::TyParam
+ | DefKind::Const
+ | DefKind::ConstParam
+ | DefKind::Static(_)
+ | DefKind::Ctor(_, _)
+ | DefKind::Macro(_)
+ | DefKind::ExternCrate
+ | DefKind::Use
+ | DefKind::ForeignMod
+ | DefKind::AnonConst
+ | DefKind::InlineConst
+ | DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
+ | DefKind::Field
+ | DefKind::LifetimeParam
+ | DefKind::GlobalAsm
+ | DefKind::Closure
+ | DefKind::Generator => ty::List::empty(),
+ }
+}
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index bd1d568cd..05738b6c4 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -3,115 +3,11 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::CodegenObligationError;
use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{
- self, Binder, Instance, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
-};
+use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable};
use rustc_span::{sym, DUMMY_SP};
use rustc_trait_selection::traits;
use traits::{translate_substs, Reveal};
-use rustc_data_structures::sso::SsoHashSet;
-use std::collections::btree_map::Entry;
-use std::collections::BTreeMap;
-use std::ops::ControlFlow;
-
-use tracing::debug;
-
-// FIXME(#86795): `BoundVarsCollector` here should **NOT** be used
-// outside of `resolve_associated_item`. It's just to address #64494,
-// #83765, and #85848 which are creating bound types/regions that lose
-// their `Binder` *unintentionally*.
-// It's ideal to remove `BoundVarsCollector` and just use
-// `ty::Binder::*` methods but we use this stopgap until we figure out
-// the "real" fix.
-struct BoundVarsCollector<'tcx> {
- binder_index: ty::DebruijnIndex,
- vars: BTreeMap<u32, ty::BoundVariableKind>,
- // We may encounter the same variable at different levels of binding, so
- // this can't just be `Ty`
- visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>,
-}
-
-impl<'tcx> BoundVarsCollector<'tcx> {
- fn new() -> Self {
- BoundVarsCollector {
- binder_index: ty::INNERMOST,
- vars: BTreeMap::new(),
- visited: SsoHashSet::default(),
- }
- }
-
- fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List<ty::BoundVariableKind> {
- let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or(0);
- for i in 0..max {
- if let None = self.vars.get(&i) {
- panic!("Unknown variable: {:?}", i);
- }
- }
-
- tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v))
- }
-}
-
-impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
- type BreakTy = ();
-
- fn visit_binder<T: TypeVisitable<'tcx>>(
- &mut self,
- t: &Binder<'tcx, T>,
- ) -> ControlFlow<Self::BreakTy> {
- self.binder_index.shift_in(1);
- let result = t.super_visit_with(self);
- self.binder_index.shift_out(1);
- result
- }
-
- fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
- if t.outer_exclusive_binder() < self.binder_index
- || !self.visited.insert((self.binder_index, t))
- {
- return ControlFlow::CONTINUE;
- }
- match *t.kind() {
- ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
- match self.vars.entry(bound_ty.var.as_u32()) {
- Entry::Vacant(entry) => {
- entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind));
- }
- Entry::Occupied(entry) => match entry.get() {
- ty::BoundVariableKind::Ty(_) => {}
- _ => bug!("Conflicting bound vars"),
- },
- }
- }
-
- _ => (),
- };
-
- t.super_visit_with(self)
- }
-
- fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
- match *r {
- ty::ReLateBound(index, br) if index == self.binder_index => {
- match self.vars.entry(br.var.as_u32()) {
- Entry::Vacant(entry) => {
- entry.insert(ty::BoundVariableKind::Region(br.kind));
- }
- Entry::Occupied(entry) => match entry.get() {
- ty::BoundVariableKind::Region(_) => {}
- _ => bug!("Conflicting bound vars"),
- },
- }
- }
-
- _ => (),
- };
-
- r.super_visit_with(self)
- }
-}
-
fn resolve_instance<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
@@ -203,19 +99,14 @@ fn resolve_associated_item<'tcx>(
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
- // See FIXME on `BoundVarsCollector`.
- let mut bound_vars_collector = BoundVarsCollector::new();
- trait_ref.visit_with(&mut bound_vars_collector);
- let trait_binder = ty::Binder::bind_with_vars(trait_ref, bound_vars_collector.into_vars(tcx));
- let vtbl = match tcx.codegen_fulfill_obligation((param_env, trait_binder)) {
+ let vtbl = match tcx.codegen_select_candidate((param_env, ty::Binder::dummy(trait_ref))) {
Ok(vtbl) => vtbl,
Err(CodegenObligationError::Ambiguity) => {
let reported = tcx.sess.delay_span_bug(
tcx.def_span(trait_item_id),
&format!(
- "encountered ambiguity selecting `{:?}` during codegen, presuming due to \
+ "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \
overflow or prior type error",
- trait_binder
),
);
return Err(reported);
@@ -372,7 +263,10 @@ fn resolve_associated_item<'tcx>(
let is_copy = self_ty.is_copy_modulo_regions(tcx.at(DUMMY_SP), param_env);
match self_ty.kind() {
_ if is_copy => (),
- ty::Closure(..) | ty::Tuple(..) => {}
+ ty::Generator(..)
+ | ty::GeneratorWitness(..)
+ | ty::Closure(..)
+ | ty::Tuple(..) => {}
_ => return Ok(None),
};
@@ -397,7 +291,8 @@ fn resolve_associated_item<'tcx>(
| traits::ImplSource::DiscriminantKind(..)
| traits::ImplSource::Pointee(..)
| traits::ImplSource::TraitUpcasting(_)
- | traits::ImplSource::ConstDestruct(_) => None,
+ | traits::ImplSource::ConstDestruct(_)
+ | traits::ImplSource::Tuple => None,
})
}
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 09f5c2a11..8524e57cb 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -6,10 +6,12 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(control_flow_enum)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(never_type)]
#![feature(box_patterns)]
#![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_middle;
@@ -21,6 +23,8 @@ use rustc_middle::ty::query::Providers;
mod assoc;
mod common_traits;
mod consts;
+mod errors;
+mod implied_bounds;
pub mod instance;
mod needs_drop;
pub mod representability;
@@ -30,6 +34,7 @@ pub fn provide(providers: &mut Providers) {
assoc::provide(providers);
common_traits::provide(providers);
consts::provide(providers);
+ implied_bounds::provide(providers);
needs_drop::provide(providers);
ty::provide(providers);
instance::provide(providers);
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 9ad44d14d..ab5a3d8ae 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -9,6 +9,8 @@ use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
use rustc_session::Limit;
use rustc_span::{sym, DUMMY_SP};
+use crate::errors::NeedsDropOverflow;
+
type NeedsDropResult<T> = Result<T, AlwaysRequiresDrop>;
fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
@@ -90,10 +92,7 @@ where
if !self.recursion_limit.value_within_limit(level) {
// Not having a `Span` isn't great. But there's hopefully some other
// recursion limit error as well.
- tcx.sess.span_err(
- DUMMY_SP,
- &format!("overflow while checking whether `{}` requires drop", self.query_ty),
- );
+ tcx.sess.emit_err(NeedsDropOverflow { query_ty: self.query_ty });
return Some(Err(AlwaysRequiresDrop));
}
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index db0d45b86..9266e4e3f 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -104,7 +104,6 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstrain
}
/// See `ParamEnv` struct definition for details.
-#[instrument(level = "debug", skip(tcx))]
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
// The param_env of an impl Trait type is its defining function's param_env
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
@@ -348,7 +347,7 @@ fn instance_def_size_estimate<'tcx>(
match instance_def {
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
let mir = tcx.instance_mir(instance_def);
- mir.basic_blocks().iter().map(|bb| bb.statements.len() + 1).sum()
+ mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
}
// Estimate the size of other compiler-generated shims to be 1.
_ => 1,
@@ -390,7 +389,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
let self_ty = trait_ref.self_ty();
let self_ty_matches = match self_ty.kind() {
- ty::Dynamic(ref data, re) if re.is_static() => data.principal().is_none(),
+ ty::Dynamic(ref data, re, _) if re.is_static() => data.principal().is_none(),
_ => false,
};
@@ -410,7 +409,6 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
}
/// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.
-#[instrument(level = "debug", skip(tcx))]
pub fn conservative_is_privately_uninhabited_raw<'tcx>(
tcx: TyCtxt<'tcx>,
param_env_and: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 791e9e0f5..da30344ef 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -1,6 +1,8 @@
#![feature(fmt_helpers_for_derive)]
#![feature(min_specialization)]
#![feature(rustc_attrs)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate bitflags;
@@ -21,6 +23,9 @@ pub mod sty;
pub use codec::*;
pub use sty::*;
+/// Needed so we can use #[derive(HashStable_Generic)]
+pub trait HashStableContext {}
+
pub trait Interner {
type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
@@ -293,6 +298,7 @@ rustc_index::newtype_index! {
/// is the outer fn.
///
/// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index
+ #[derive(HashStable_Generic)]
pub struct DebruijnIndex {
DEBUG_FORMAT = "DebruijnIndex({})",
const INNERMOST = 0,
@@ -364,7 +370,7 @@ impl DebruijnIndex {
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(Encodable, Decodable)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum IntTy {
Isize,
I8,
@@ -411,7 +417,7 @@ impl IntTy {
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
-#[derive(Encodable, Decodable)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum UintTy {
Usize,
U8,
@@ -458,7 +464,7 @@ impl UintTy {
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(Encodable, Decodable)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum FloatTy {
F32,
F64,
@@ -595,7 +601,7 @@ impl UnifyKey for FloatVid {
}
}
-#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash)]
+#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash, HashStable_Generic)]
#[rustc_pass_by_value]
pub enum Variance {
Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
@@ -664,30 +670,6 @@ impl Variance {
}
}
-impl<CTX> HashStable<CTX> for DebruijnIndex {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- self.as_u32().hash_stable(ctx, hasher);
- }
-}
-
-impl<CTX> HashStable<CTX> for IntTy {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- discriminant(self).hash_stable(ctx, hasher);
- }
-}
-
-impl<CTX> HashStable<CTX> for UintTy {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- discriminant(self).hash_stable(ctx, hasher);
- }
-}
-
-impl<CTX> HashStable<CTX> for FloatTy {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- discriminant(self).hash_stable(ctx, hasher);
- }
-}
-
impl<CTX> HashStable<CTX> for InferTy {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
use InferTy::*;
@@ -701,12 +683,6 @@ impl<CTX> HashStable<CTX> for InferTy {
}
}
-impl<CTX> HashStable<CTX> for Variance {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- discriminant(self).hash_stable(ctx, hasher);
- }
-}
-
impl fmt::Debug for IntVarValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
@@ -809,6 +785,7 @@ rustc_index::newtype_index! {
/// declared, but a type name in a non-zero universe is a placeholder
/// type -- an idealized representative of "types in general" that we
/// use for checking generic functions.
+ #[derive(HashStable_Generic)]
pub struct UniverseIndex {
DEBUG_FORMAT = "U{}",
}
@@ -848,9 +825,3 @@ impl UniverseIndex {
self.private < other.private
}
}
-
-impl<CTX> HashStable<CTX> for UniverseIndex {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- self.private.hash_stable(ctx, hasher);
- }
-}
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index 74737e30b..6d54924e5 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -5,12 +5,12 @@ use std::{fmt, hash};
use crate::DebruijnIndex;
use crate::FloatTy;
+use crate::HashStableContext;
use crate::IntTy;
use crate::Interner;
use crate::TyDecoder;
use crate::TyEncoder;
use crate::UintTy;
-use crate::UniverseIndex;
use self::RegionKind::*;
use self::TyKind::*;
@@ -18,6 +18,34 @@ use self::TyKind::*;
use rustc_data_structures::stable_hasher::HashStable;
use rustc_serialize::{Decodable, Decoder, Encodable};
+/// Specifies how a trait object is represented.
+#[derive(
+ Clone,
+ Copy,
+ PartialEq,
+ Eq,
+ PartialOrd,
+ Ord,
+ Hash,
+ Debug,
+ Encodable,
+ Decodable,
+ HashStable_Generic
+)]
+pub enum DynKind {
+ /// An unsized `dyn Trait` object
+ Dyn,
+ /// A sized `dyn* Trait` object
+ ///
+ /// These objects are represented as a `(data, vtable)` pair where `data` is a ptr-sized value
+ /// (often a pointer to the real object, but not necessarily) and `vtable` is a pointer to
+ /// the vtable for `dyn* Trait`. The representation is essentially the same as `&dyn Trait`
+ /// or similar, but the drop function included in the vtable is responsible for freeing the
+ /// underlying storage if needed. This allows a `dyn*` object to be treated agnostically with
+ /// respect to whether it points to a `Box<T>`, `Rc<T>`, etc.
+ DynStar,
+}
+
/// Defines the kinds of types used by the type system.
///
/// Types written by the user start out as `hir::TyKind` and get
@@ -95,7 +123,7 @@ pub enum TyKind<I: Interner> {
FnPtr(I::PolyFnSig),
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
- Dynamic(I::ListBinderExistentialPredicate, I::Region),
+ Dynamic(I::ListBinderExistentialPredicate, I::Region, DynKind),
/// The anonymous type of a closure. Used to represent the type of `|a| a`.
///
@@ -218,7 +246,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
Ref(_, _, _) => 11,
FnDef(_, _) => 12,
FnPtr(_) => 13,
- Dynamic(_, _) => 14,
+ Dynamic(..) => 14,
Closure(_, _) => 15,
Generator(_, _, _) => 16,
GeneratorWitness(_) => 17,
@@ -252,7 +280,7 @@ impl<I: Interner> Clone for TyKind<I> {
Ref(r, t, m) => Ref(r.clone(), t.clone(), m.clone()),
FnDef(d, s) => FnDef(d.clone(), s.clone()),
FnPtr(s) => FnPtr(s.clone()),
- Dynamic(p, r) => Dynamic(p.clone(), r.clone()),
+ Dynamic(p, r, repr) => Dynamic(p.clone(), r.clone(), repr.clone()),
Closure(d, s) => Closure(d.clone(), s.clone()),
Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
GeneratorWitness(g) => GeneratorWitness(g.clone()),
@@ -297,9 +325,10 @@ impl<I: Interner> PartialEq for TyKind<I> {
__self_0 == __arg_1_0 && __self_1 == __arg_1_1
}
(&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
- (&Dynamic(ref __self_0, ref __self_1), &Dynamic(ref __arg_1_0, ref __arg_1_1)) => {
- __self_0 == __arg_1_0 && __self_1 == __arg_1_1
- }
+ (
+ &Dynamic(ref __self_0, ref __self_1, ref self_repr),
+ &Dynamic(ref __arg_1_0, ref __arg_1_1, ref arg_repr),
+ ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && self_repr == arg_repr,
(&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
__self_0 == __arg_1_0 && __self_1 == __arg_1_1
}
@@ -384,12 +413,16 @@ impl<I: Interner> Ord for TyKind<I> {
}
}
(&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
- (&Dynamic(ref __self_0, ref __self_1), &Dynamic(ref __arg_1_0, ref __arg_1_1)) => {
- match Ord::cmp(__self_0, __arg_1_0) {
- Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
+ (
+ &Dynamic(ref __self_0, ref __self_1, ref self_repr),
+ &Dynamic(ref __arg_1_0, ref __arg_1_1, ref arg_repr),
+ ) => match Ord::cmp(__self_0, __arg_1_0) {
+ Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
+ Ordering::Equal => Ord::cmp(self_repr, arg_repr),
cmp => cmp,
- }
- }
+ },
+ cmp => cmp,
+ },
(&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
match Ord::cmp(__self_0, __arg_1_0) {
Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
@@ -492,10 +525,11 @@ impl<I: Interner> hash::Hash for TyKind<I> {
hash::Hash::hash(&tykind_discriminant(self), state);
hash::Hash::hash(__self_0, state)
}
- (&Dynamic(ref __self_0, ref __self_1),) => {
+ (&Dynamic(ref __self_0, ref __self_1, ref repr),) => {
hash::Hash::hash(&tykind_discriminant(self), state);
hash::Hash::hash(__self_0, state);
- hash::Hash::hash(__self_1, state)
+ hash::Hash::hash(__self_1, state);
+ hash::Hash::hash(repr, state)
}
(&Closure(ref __self_0, ref __self_1),) => {
hash::Hash::hash(&tykind_discriminant(self), state);
@@ -570,7 +604,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
Ref(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Ref", f0, f1, f2),
FnDef(f0, f1) => Formatter::debug_tuple_field2_finish(f, "FnDef", f0, f1),
FnPtr(f0) => Formatter::debug_tuple_field1_finish(f, "FnPtr", f0),
- Dynamic(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Dynamic", f0, f1),
+ Dynamic(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Dynamic", f0, f1, f2),
Closure(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Closure", f0, f1),
Generator(f0, f1, f2) => {
Formatter::debug_tuple_field3_finish(f, "Generator", f0, f1, f2)
@@ -659,9 +693,10 @@ where
FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
polyfnsig.encode(e);
}),
- Dynamic(l, r) => e.emit_enum_variant(disc, |e| {
+ Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
l.encode(e);
r.encode(e);
+ repr.encode(e);
}),
Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
def_id.encode(e);
@@ -748,7 +783,7 @@ where
11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
13 => FnPtr(Decodable::decode(d)),
- 14 => Dynamic(Decodable::decode(d), Decodable::decode(d)),
+ 14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
15 => Closure(Decodable::decode(d), Decodable::decode(d)),
16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
17 => GeneratorWitness(Decodable::decode(d)),
@@ -774,7 +809,7 @@ where
// This is not a derived impl because a derive would require `I: HashStable`
#[allow(rustc::usage_of_ty_tykind)]
-impl<CTX, I: Interner> HashStable<CTX> for TyKind<I>
+impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
where
I::AdtDef: HashStable<CTX>,
I::DefId: HashStable<CTX>,
@@ -845,9 +880,10 @@ where
FnPtr(polyfnsig) => {
polyfnsig.hash_stable(__hcx, __hasher);
}
- Dynamic(l, r) => {
+ Dynamic(l, r, repr) => {
l.hash_stable(__hcx, __hasher);
r.hash_stable(__hcx, __hasher);
+ repr.hash_stable(__hcx, __hasher);
}
Closure(def_id, substs) => {
def_id.hash_stable(__hcx, __hasher);
@@ -1023,14 +1059,6 @@ pub enum RegionKind<I: Interner> {
/// Should not exist outside of type inference.
RePlaceholder(I::PlaceholderRegion),
- /// Empty lifetime is for data that is never accessed. We tag the
- /// empty lifetime with a universe -- the idea is that we don't
- /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
- /// Therefore, the `'empty` in a universe `U` is less than all
- /// regions visible from `U`, but not less than regions not visible
- /// from `U`.
- ReEmpty(UniverseIndex),
-
/// Erased region, used by trait selection, in MIR and during codegen.
ReErased,
}
@@ -1046,8 +1074,7 @@ const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
ReStatic => 3,
ReVar(_) => 4,
RePlaceholder(_) => 5,
- ReEmpty(_) => 6,
- ReErased => 7,
+ ReErased => 6,
}
}
@@ -1072,7 +1099,6 @@ impl<I: Interner> Clone for RegionKind<I> {
ReStatic => ReStatic,
ReVar(a) => ReVar(a.clone()),
RePlaceholder(a) => RePlaceholder(a.clone()),
- ReEmpty(a) => ReEmpty(a.clone()),
ReErased => ReErased,
}
}
@@ -1099,7 +1125,6 @@ impl<I: Interner> PartialEq for RegionKind<I> {
(&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
__self_0 == __arg_1_0
}
- (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => __self_0 == __arg_1_0,
(&ReErased, &ReErased) => true,
_ => true,
}
@@ -1144,7 +1169,6 @@ impl<I: Interner> Ord for RegionKind<I> {
(&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
Ord::cmp(__self_0, __arg_1_0)
}
- (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
(&ReErased, &ReErased) => Ordering::Equal,
_ => Ordering::Equal,
}
@@ -1182,10 +1206,6 @@ impl<I: Interner> hash::Hash for RegionKind<I> {
hash::Hash::hash(&regionkind_discriminant(self), state);
hash::Hash::hash(__self_0, state)
}
- (&ReEmpty(ref __self_0),) => {
- hash::Hash::hash(&regionkind_discriminant(self), state);
- hash::Hash::hash(__self_0, state)
- }
(&ReErased,) => {
hash::Hash::hash(&regionkind_discriminant(self), state);
}
@@ -1211,8 +1231,6 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
- ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui),
-
ReErased => write!(f, "ReErased"),
}
}
@@ -1247,9 +1265,6 @@ where
RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
a.encode(e);
}),
- ReEmpty(a) => e.emit_enum_variant(disc, |e| {
- a.encode(e);
- }),
ReErased => e.emit_enum_variant(disc, |_| {}),
}
}
@@ -1272,8 +1287,7 @@ where
3 => ReStatic,
4 => ReVar(Decodable::decode(d)),
5 => RePlaceholder(Decodable::decode(d)),
- 6 => ReEmpty(Decodable::decode(d)),
- 7 => ReErased,
+ 6 => ReErased,
_ => panic!(
"{}",
format!(
@@ -1286,7 +1300,7 @@ where
}
// This is not a derived impl because a derive would require `I: HashStable`
-impl<CTX, I: Interner> HashStable<CTX> for RegionKind<I>
+impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
where
I::EarlyBoundRegion: HashStable<CTX>,
I::BoundRegion: HashStable<CTX>,
@@ -1305,9 +1319,6 @@ where
ReErased | ReStatic => {
// No variant fields to hash for these ...
}
- ReEmpty(universe) => {
- universe.hash_stable(hcx, hasher);
- }
ReLateBound(db, br) => {
db.hash_stable(hcx, hasher);
br.hash_stable(hcx, hasher);
diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml
index faf52e269..cae29c1d3 100644
--- a/compiler/rustc_typeck/Cargo.toml
+++ b/compiler/rustc_typeck/Cargo.toml
@@ -30,3 +30,4 @@ rustc_ty_utils = { path = "../rustc_ty_utils" }
rustc_lint = { path = "../rustc_lint" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_type_ir = { path = "../rustc_type_ir" }
+rustc_feature = { path = "../rustc_feature" }
diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs
index ff39bf361..a9152bdc5 100644
--- a/compiler/rustc_typeck/src/astconv/errors.rs
+++ b/compiler/rustc_typeck/src/astconv/errors.rs
@@ -29,6 +29,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.tcx().sess.emit_err(MissingTypeParams {
span,
def_span: self.tcx().def_span(def_id),
+ span_snippet: self.tcx().sess.source_map().span_to_snippet(span).ok(),
missing_type_params,
empty_generic_args,
});
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 40aa27a29..afac75de2 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -298,9 +298,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// show that order to the user as a possible order for the parameters
let mut param_types_present = defs
.params
- .clone()
- .into_iter()
- .map(|param| (param.kind.to_ord(), param))
+ .iter()
+ .map(|param| (param.kind.to_ord(), param.clone()))
.collect::<Vec<(ParamKindOrd, GenericParamDef)>>();
param_types_present.sort_by_key(|(ord, _)| *ord);
let (mut param_types_present, ordered_params): (
@@ -648,7 +647,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
multispan.push_span_label(span_late, note);
tcx.struct_span_lint_hir(
LATE_BOUND_LIFETIME_ARGUMENTS,
- args.args[0].id(),
+ args.args[0].hir_id(),
multispan,
|lint| {
lint.build(msg).emit();
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 8a5c7fee6..4bf9562e2 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -16,7 +16,8 @@ use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
- struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan,
+ struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
+ MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -26,6 +27,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::DynKind;
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{
self, Const, DefIdTree, EarlyBinder, IsSuggestable, Ty, TyCtxt, TypeVisitable,
@@ -34,7 +36,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT
use rustc_span::edition::Edition;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, Ident, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
use rustc_target::spec::abi;
use rustc_trait_selection::traits;
use rustc_trait_selection::traits::astconv_object_safety_violations;
@@ -43,7 +45,7 @@ use rustc_trait_selection::traits::error_reporting::{
};
use rustc_trait_selection::traits::wf::object_region_bounds;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
use std::collections::BTreeSet;
use std::slice;
@@ -143,7 +145,7 @@ enum ConvertedBindingKind<'a, 'tcx> {
/// instantiated with some generic arguments providing `'a` explicitly,
/// we taint those arguments with `ExplicitLateBound::Yes` so that we
/// can provide an appropriate diagnostic later.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, PartialEq, Debug)]
pub enum ExplicitLateBound {
Yes,
No,
@@ -166,7 +168,7 @@ pub(crate) enum GenericArgPosition {
/// A marker denoting that the generic arguments that were
/// provided did not match the respective generic parameters.
-#[derive(Clone, Default)]
+#[derive(Clone, Default, Debug)]
pub struct GenericArgCountMismatch {
/// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`).
pub reported: Option<ErrorGuaranteed>,
@@ -176,7 +178,7 @@ pub struct GenericArgCountMismatch {
/// Decorates the result of a generic argument count mismatch
/// check with whether explicit late bounds were provided.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct GenericArgCountResult {
pub explicit_late_bound: ExplicitLateBound,
pub correct: Result<(), GenericArgCountMismatch>,
@@ -200,7 +202,7 @@ pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
}
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
pub fn ast_region_to_region(
&self,
lifetime: &hir::Lifetime,
@@ -209,7 +211,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let tcx = self.tcx();
let lifetime_name = |def_id| tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id));
- let r = match tcx.named_region(lifetime.hir_id) {
+ match tcx.named_region(lifetime.hir_id) {
Some(rl::Region::Static) => tcx.lifetimes.re_static,
Some(rl::Region::LateBound(debruijn, index, def_id)) => {
@@ -221,9 +223,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.mk_region(ty::ReLateBound(debruijn, br))
}
- Some(rl::Region::EarlyBound(index, id)) => {
- let name = lifetime_name(id.expect_local());
- tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: id, index, name }))
+ Some(rl::Region::EarlyBound(def_id)) => {
+ let name = tcx.hir().ty_param_name(def_id.expect_local());
+ let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
+ let generics = tcx.generics_of(item_def_id);
+ let index = generics.param_def_id_to_index[&def_id];
+ tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }))
}
Some(rl::Region::Free(scope, id)) => {
@@ -251,11 +256,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.lifetimes.re_static
})
}
- };
-
- debug!("ast_region_to_region(lifetime={:?}) yields {:?}", lifetime, r);
-
- r
+ }
}
/// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
@@ -315,7 +316,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
/// type itself: `['a]`. The returned `SubstsRef` concatenates these two
/// lists: `[Vec<u8>, u8, 'a]`.
- #[tracing::instrument(level = "debug", skip(self, span))]
+ #[instrument(level = "debug", skip(self, span), ret)]
fn create_substs_for_ast_path<'a>(
&self,
span: Span,
@@ -367,36 +368,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return (tcx.intern_substs(&[]), arg_count);
}
- let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self);
-
struct SubstsForAstPathCtxt<'a, 'tcx> {
astconv: &'a (dyn AstConv<'tcx> + 'a),
def_id: DefId,
generic_args: &'a GenericArgs<'a>,
span: Span,
- missing_type_params: Vec<Symbol>,
inferred_params: Vec<Span>,
infer_args: bool,
- is_object: bool,
- }
-
- impl<'tcx, 'a> SubstsForAstPathCtxt<'tcx, 'a> {
- fn default_needs_object_self(&mut self, param: &ty::GenericParamDef) -> bool {
- let tcx = self.astconv.tcx();
- if let GenericParamDefKind::Type { has_default, .. } = param.kind {
- if self.is_object && has_default {
- let default_ty = tcx.at(self.span).type_of(param.def_id);
- let self_param = tcx.types.self_param;
- if default_ty.walk().any(|arg| arg == self_param.into()) {
- // There is no suitable inference default for a type parameter
- // that references self, in an object type.
- return true;
- }
- }
- }
-
- false
- }
}
impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> {
@@ -420,7 +398,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if has_default {
tcx.check_optional_stability(
param.def_id,
- Some(arg.id()),
+ Some(arg.hir_id()),
arg.span(),
None,
AllowUnstable::No,
@@ -499,41 +477,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default {
// No type parameter provided, but a default exists.
-
- // If we are converting an object type, then the
- // `Self` parameter is unknown. However, some of the
- // other type parameters may reference `Self` in their
- // defaults. This will lead to an ICE if we are not
- // careful!
- if self.default_needs_object_self(param) {
- self.missing_type_params.push(param.name);
- tcx.ty_error().into()
- } else {
- // This is a default type parameter.
- let substs = substs.unwrap();
- if substs.iter().any(|arg| match arg.unpack() {
- GenericArgKind::Type(ty) => ty.references_error(),
- _ => false,
- }) {
- // Avoid ICE #86756 when type error recovery goes awry.
- return tcx.ty_error().into();
- }
- self.astconv
- .normalize_ty(
- self.span,
- EarlyBinder(tcx.at(self.span).type_of(param.def_id))
- .subst(tcx, substs),
- )
- .into()
+ let substs = substs.unwrap();
+ if substs.iter().any(|arg| match arg.unpack() {
+ GenericArgKind::Type(ty) => ty.references_error(),
+ _ => false,
+ }) {
+ // Avoid ICE #86756 when type error recovery goes awry.
+ return tcx.ty_error().into();
}
+ self.astconv
+ .normalize_ty(
+ self.span,
+ EarlyBinder(tcx.at(self.span).type_of(param.def_id))
+ .subst(tcx, substs),
+ )
+ .into()
} else if infer_args {
- // No type parameters were provided, we can infer all.
- let param = if !self.default_needs_object_self(param) {
- Some(param)
- } else {
- None
- };
- self.astconv.ty_infer(param, self.span).into()
+ self.astconv.ty_infer(Some(param), self.span).into()
} else {
// We've already errored above about the mismatch.
tcx.ty_error().into()
@@ -563,10 +523,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
def_id,
span,
generic_args,
- missing_type_params: vec![],
inferred_params: vec![],
infer_args,
- is_object,
};
let substs = Self::create_substs_for_generic_args(
tcx,
@@ -578,18 +536,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&mut substs_ctx,
);
- self.complain_about_missing_type_params(
- substs_ctx.missing_type_params,
- def_id,
- span,
- generic_args.args.is_empty(),
- );
-
- debug!(
- "create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
- generics, self_ty, substs
- );
-
(substs, arg_count)
}
@@ -655,7 +601,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
parent_substs
} else {
- self.create_substs_for_ast_path(
+ let (args, _) = self.create_substs_for_ast_path(
span,
item_def_id,
parent_substs,
@@ -663,8 +609,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
item_segment.args(),
item_segment.infer_args,
None,
- )
- .0
+ );
+
+ let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args());
+ if let Some(b) = assoc_bindings.first() {
+ Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
+ }
+
+ args
}
}
@@ -764,7 +716,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
/// however.
- #[tracing::instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
+ #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
pub(crate) fn instantiate_poly_trait_ref(
&self,
trait_ref: &hir::TraitRef<'_>,
@@ -856,7 +808,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
ty::TraitRef::new(trait_def_id, substs)
}
- #[tracing::instrument(level = "debug", skip(self, span))]
+ #[instrument(level = "debug", skip(self, span))]
fn create_substs_for_ast_trait_ref<'a>(
&self,
span: Span,
@@ -970,7 +922,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// **A note on binders:** there is an implied binder around
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
/// for more details.
- #[tracing::instrument(level = "debug", skip(self, ast_bounds, bounds))]
+ #[instrument(level = "debug", skip(self, ast_bounds, bounds))]
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'hir>>>(
&self,
param_ty: Ty<'tcx>,
@@ -1076,10 +1028,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
- #[tracing::instrument(
- level = "debug",
- skip(self, bounds, speculative, dup_bindings, path_span)
- )]
+ #[instrument(level = "debug", skip(self, bounds, speculative, dup_bindings, path_span))]
fn add_predicates_for_ast_type_binding(
&self,
hir_ref_id: hir::HirId,
@@ -1171,8 +1120,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let ident = Ident::new(assoc_item.name, binding.item_name.span);
let item_segment = hir::PathSegment {
ident,
- hir_id: Some(binding.hir_id),
- res: None,
+ hir_id: binding.hir_id,
+ res: Res::Err,
args: Some(binding.gen_args),
infer_args: false,
};
@@ -1241,11 +1190,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// `<T as Iterator>::Item = u32`
let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
let def_kind = tcx.def_kind(assoc_item_def_id);
- match (def_kind, term) {
- (hir::def::DefKind::AssocTy, ty::Term::Ty(_))
- | (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
+ match (def_kind, term.unpack()) {
+ (hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
+ | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (),
(_, _) => {
- let got = if let ty::Term::Ty(_) = term { "type" } else { "constant" };
+ let got = if let Some(_) = term.ty() { "type" } else { "constant" };
let expected = def_kind.descr(assoc_item_def_id);
tcx.sess
.struct_span_err(
@@ -1310,6 +1259,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_bounds: &[hir::PolyTraitRef<'_>],
lifetime: &hir::Lifetime,
borrowed: bool,
+ representation: DynKind,
) -> Ty<'tcx> {
let tcx = self.tcx();
@@ -1433,9 +1383,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let pred = bound_predicate.rebind(pred);
// A `Self` within the original bound will be substituted with a
// `trait_object_dummy_self`, so check for that.
- let references_self = match pred.skip_binder().term {
- ty::Term::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
- ty::Term::Const(c) => c.ty().walk().any(|arg| arg == dummy_self.into()),
+ let references_self = match pred.skip_binder().term.unpack() {
+ ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
+ ty::TermKind::Const(c) => {
+ c.ty().walk().any(|arg| arg == dummy_self.into())
+ }
};
// If the projection output contains `Self`, force the user to
@@ -1489,31 +1441,94 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
let existential_trait_refs = regular_traits.iter().map(|i| {
i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
- if trait_ref.self_ty() != dummy_self {
- // FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
- // which picks up non-supertraits where clauses - but also, the object safety
- // completely ignores trait aliases, which could be object safety hazards. We
- // `delay_span_bug` here to avoid an ICE in stable even when the feature is
- // disabled. (#66420)
- tcx.sess.delay_span_bug(
- DUMMY_SP,
- &format!(
- "trait_ref_to_existential called on {:?} with non-dummy Self",
- trait_ref,
- ),
+ assert_eq!(trait_ref.self_ty(), dummy_self);
+
+ // Verify that `dummy_self` did not leak inside default type parameters. This
+ // could not be done at path creation, since we need to see through trait aliases.
+ let mut missing_type_params = vec![];
+ let mut references_self = false;
+ let generics = tcx.generics_of(trait_ref.def_id);
+ let substs: Vec<_> = trait_ref
+ .substs
+ .iter()
+ .enumerate()
+ .skip(1) // Remove `Self` for `ExistentialPredicate`.
+ .map(|(index, arg)| {
+ if arg == dummy_self.into() {
+ let param = &generics.params[index];
+ missing_type_params.push(param.name);
+ return tcx.ty_error().into();
+ } else if arg.walk().any(|arg| arg == dummy_self.into()) {
+ references_self = true;
+ return tcx.ty_error().into();
+ }
+ arg
+ })
+ .collect();
+ let substs = tcx.intern_substs(&substs[..]);
+
+ let span = i.bottom().1;
+ let empty_generic_args = trait_bounds.iter().any(|hir_bound| {
+ hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
+ && hir_bound.span.contains(span)
+ });
+ self.complain_about_missing_type_params(
+ missing_type_params,
+ trait_ref.def_id,
+ span,
+ empty_generic_args,
+ );
+
+ if references_self {
+ let def_id = i.bottom().0.def_id();
+ let mut err = struct_span_err!(
+ tcx.sess,
+ i.bottom().1,
+ E0038,
+ "the {} `{}` cannot be made into an object",
+ tcx.def_kind(def_id).descr(def_id),
+ tcx.item_name(def_id),
+ );
+ err.note(
+ rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![])
+ .error_msg(),
);
+ err.emit();
}
- ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+
+ ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs }
})
});
+
let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
- bound.map_bound(|b| {
- if b.projection_ty.self_ty() != dummy_self {
- tcx.sess.delay_span_bug(
- DUMMY_SP,
- &format!("trait_ref_to_existential called on {:?} with non-dummy Self", b),
- );
+ bound.map_bound(|mut b| {
+ assert_eq!(b.projection_ty.self_ty(), dummy_self);
+
+ // Like for trait refs, verify that `dummy_self` did not leak inside default type
+ // parameters.
+ let references_self = b.projection_ty.substs.iter().skip(1).any(|arg| {
+ if arg.walk().any(|arg| arg == dummy_self.into()) {
+ return true;
+ }
+ false
+ });
+ if references_self {
+ tcx.sess
+ .delay_span_bug(span, "trait object projection bounds reference `Self`");
+ let substs: Vec<_> = b
+ .projection_ty
+ .substs
+ .iter()
+ .map(|arg| {
+ if arg.walk().any(|arg| arg == dummy_self.into()) {
+ return tcx.ty_error().into();
+ }
+ arg
+ })
+ .collect();
+ b.projection_ty.substs = tcx.intern_substs(&substs[..]);
}
+
ty::ExistentialProjection::erase_self_ty(tcx, b)
})
});
@@ -1565,7 +1580,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
debug!("region_bound: {:?}", region_bound);
- let ty = tcx.mk_dynamic(existential_predicates, region_bound);
+ let ty = tcx.mk_dynamic(existential_predicates, region_bound, representation);
debug!("trait_object_type: {:?}", ty);
ty
}
@@ -1840,7 +1855,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
[.., hir::PathSegment {
ident,
args,
- res: Some(Res::Def(DefKind::Enum, _)),
+ res: Res::Def(DefKind::Enum, _),
..
}, _] => (
// We need to include the `::` in `Type::Variant::<Args>`
@@ -2106,7 +2121,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
pub fn prohibit_generics<'a>(
&self,
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
- extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>),
+ extend: impl Fn(&mut Diagnostic),
) -> bool {
let args = segments.clone().flat_map(|segment| segment.args().args);
@@ -2122,24 +2137,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let types_and_spans: Vec<_> = segments
.clone()
.flat_map(|segment| {
- segment.res.and_then(|res| {
- if segment.args().args.is_empty() {
- None
- } else {
- Some((
- match res {
- Res::PrimTy(ty) => format!("{} `{}`", res.descr(), ty.name()),
+ if segment.args().args.is_empty() {
+ None
+ } else {
+ Some((
+ match segment.res {
+ Res::PrimTy(ty) => format!("{} `{}`", segment.res.descr(), ty.name()),
Res::Def(_, def_id)
if let Some(name) = self.tcx().opt_item_name(def_id) => {
- format!("{} `{name}`", res.descr())
+ format!("{} `{name}`", segment.res.descr())
}
Res::Err => "this type".to_string(),
- _ => res.descr().to_string(),
+ _ => segment.res.descr().to_string(),
},
segment.ident.span,
))
- }
- })
+ }
})
.collect();
let this_type = match &types_and_spans[..] {
@@ -2355,7 +2368,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let span = path.span;
match path.res {
- Res::Def(DefKind::OpaqueTy, did) => {
+ Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => {
// Check for desugared `impl Trait`.
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
let item_segment = path.segments.split_last().unwrap();
@@ -2584,7 +2597,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
- #[tracing::instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
let tcx = self.tcx();
@@ -2613,22 +2626,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Some(ast_ty),
))
}
- hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
+ hir::TyKind::TraitObject(bounds, ref lifetime, repr) => {
self.maybe_lint_bare_trait(ast_ty, in_path);
- self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
+ let repr = match repr {
+ TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
+ TraitObjectSyntax::DynStar => ty::DynStar,
+ };
+ self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
}
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
debug!(?maybe_qself, ?path);
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
self.res_to_ty(opt_self_ty, path, false)
}
- hir::TyKind::OpaqueDef(item_id, lifetimes) => {
+ hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
let opaque_ty = tcx.hir().item(item_id);
let def_id = item_id.def_id.to_def_id();
match opaque_ty.kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
- self.impl_trait_ty_to_ty(def_id, lifetimes, origin)
+ self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
}
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
}
@@ -2667,7 +2684,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.normalize_ty(ast_ty.span, array_ty)
}
hir::TyKind::Typeof(ref e) => {
- let ty = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
+ let ty_erased = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
+ let ty = tcx.fold_regions(ty_erased, |r, _| {
+ if r.is_erased() { tcx.lifetimes.re_static } else { r }
+ });
let span = ast_ty.span;
tcx.sess.emit_err(TypeofReservedKeywordUsed {
span,
@@ -2688,17 +2708,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir::TyKind::Err => tcx.ty_error(),
};
- debug!(?result_ty);
-
self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
result_ty
}
+ #[instrument(level = "debug", skip(self), ret)]
fn impl_trait_ty_to_ty(
&self,
def_id: DefId,
lifetimes: &[hir::GenericArg<'_>],
origin: OpaqueTyOrigin,
+ in_trait: bool,
) -> Ty<'tcx> {
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
let tcx = self.tcx();
@@ -2742,9 +2762,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
});
debug!("impl_trait_ty_to_ty: substs={:?}", substs);
- let ty = tcx.mk_opaque(def_id, substs);
- debug!("impl_trait_ty_to_ty: {}", ty);
- ty
+ if in_trait { tcx.mk_projection(def_id, substs) } else { tcx.mk_opaque(def_id, substs) }
}
pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
@@ -2839,10 +2857,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
);
if !infer_replacements.is_empty() {
- diag.multipart_suggestion(&format!(
+ diag.multipart_suggestion(
+ &format!(
"try replacing `_` with the type{} in the corresponding trait method signature",
rustc_errors::pluralize!(infer_replacements.len()),
- ), infer_replacements, Applicability::MachineApplicable);
+ ),
+ infer_replacements,
+ Applicability::MachineApplicable,
+ );
}
diag.emit();
@@ -2934,8 +2956,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// though we can easily give a hint that ought to be
// relevant.
err.note(
- "lifetimes appearing in an associated type are not considered constrained",
+ "lifetimes appearing in an associated or opaque type are not considered constrained",
);
+ err.note("consider introducing a named lifetime parameter");
}
err.emit();
@@ -2984,11 +3007,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
/// Make sure that we are in the condition to suggest the blanket implementation.
- fn maybe_lint_blanket_trait_impl<T: rustc_errors::EmissionGuarantee>(
- &self,
- self_ty: &hir::Ty<'_>,
- diag: &mut DiagnosticBuilder<'_, T>,
- ) {
+ fn maybe_lint_blanket_trait_impl(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) {
let tcx = self.tcx();
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id);
if let hir::Node::Item(hir::Item {
@@ -3081,7 +3100,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
sugg,
Applicability::MachineApplicable,
);
- self.maybe_lint_blanket_trait_impl::<()>(&self_ty, &mut diag);
+ self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
diag.emit();
},
);
diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs
index 1b13c98e4..20332e75c 100644
--- a/compiler/rustc_typeck/src/check/_match.rs
+++ b/compiler/rustc_typeck/src/check/_match.rs
@@ -4,7 +4,7 @@ use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::{self as hir, ExprKind};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::Obligation;
-use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Subst, ToPredicate, Ty};
use rustc_span::Span;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::{
@@ -12,7 +12,7 @@ use rustc_trait_selection::traits::{
};
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
- #[instrument(skip(self), level = "debug")]
+ #[instrument(skip(self), level = "debug", ret)]
pub fn check_match(
&self,
expr: &'tcx hir::Expr<'tcx>,
@@ -94,7 +94,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
all_arms_diverge &= self.diverges.get();
- let opt_suggest_box_span = self.opt_suggest_box_span(arm_ty, orig_expected);
+ let opt_suggest_box_span = prior_arm.and_then(|(_, prior_arm_ty, _)| {
+ self.opt_suggest_box_span(prior_arm_ty, arm_ty, orig_expected)
+ });
let (arm_block_id, arm_span) = if let hir::ExprKind::Block(blk, _) = arm.body.kind {
(Some(blk.hir_id), self.find_block_span(blk))
@@ -135,9 +137,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(&arm.body),
arm_ty,
Some(&mut |err| {
- let Some(ret) = self.ret_type_span else {
- return;
- };
+ let Some(ret) = self
+ .tcx
+ .hir()
+ .find_by_def_id(self.body_id.owner)
+ .and_then(|owner| owner.fn_decl())
+ .map(|decl| decl.output.span())
+ else { return; };
let Expectation::IsLast(stmt) = orig_expected else {
return
};
@@ -210,9 +216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We won't diverge unless the scrutinee or all arms diverge.
self.diverges.set(scrut_diverges | all_arms_diverge);
- let match_ty = coercion.complete(self);
- debug!(?match_ty);
- match_ty
+ coercion.complete(self)
}
/// When the previously checked expression (the scrutinee) diverges,
@@ -468,53 +472,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- // When we have a `match` as a tail expression in a `fn` with a returned `impl Trait`
- // we check if the different arms would work with boxed trait objects instead and
- // provide a structured suggestion in that case.
+ /// When we have a `match` as a tail expression in a `fn` with a returned `impl Trait`
+ /// we check if the different arms would work with boxed trait objects instead and
+ /// provide a structured suggestion in that case.
pub(crate) fn opt_suggest_box_span(
&self,
- outer_ty: Ty<'tcx>,
+ first_ty: Ty<'tcx>,
+ second_ty: Ty<'tcx>,
orig_expected: Expectation<'tcx>,
) -> Option<Span> {
+ // FIXME(compiler-errors): This really shouldn't need to be done during the
+ // "good" path of typeck, but here we are.
match orig_expected {
- Expectation::ExpectHasType(expected)
- if self.in_tail_expr
- && self.ret_coercion.as_ref()?.borrow().merged_ty().has_opaque_types()
- && self.can_coerce(outer_ty, expected) =>
- {
- let obligations = self.fulfillment_cx.borrow().pending_obligations();
- let mut suggest_box = !obligations.is_empty();
- for o in obligations {
- match o.predicate.kind().skip_binder() {
- ty::PredicateKind::Trait(t) => {
- let pred =
- ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
- trait_ref: ty::TraitRef {
- def_id: t.def_id(),
- substs: self.tcx.mk_substs_trait(outer_ty, &[]),
- },
- constness: t.constness,
- polarity: t.polarity,
- }));
- let obl = Obligation::new(
- o.cause.clone(),
- self.param_env,
- pred.to_predicate(self.tcx),
- );
- suggest_box &= self.predicate_must_hold_modulo_regions(&obl);
- if !suggest_box {
- // We've encountered some obligation that didn't hold, so the
- // return expression can't just be boxed. We don't need to
- // evaluate the rest of the obligations.
- break;
+ Expectation::ExpectHasType(expected) => {
+ let TypeVariableOrigin {
+ span,
+ kind: TypeVariableOriginKind::OpaqueTypeInference(rpit_def_id),
+ ..
+ } = self.type_var_origin(expected)? else { return None; };
+
+ let sig = *self
+ .typeck_results
+ .borrow()
+ .liberated_fn_sigs()
+ .get(hir::HirId::make_owner(self.body_id.owner))?;
+
+ let substs = sig.output().walk().find_map(|arg| {
+ if let ty::GenericArgKind::Type(ty) = arg.unpack()
+ && let ty::Opaque(def_id, substs) = *ty.kind()
+ && def_id == rpit_def_id
+ {
+ Some(substs)
+ } else {
+ None
+ }
+ })?;
+ let opaque_ty = self.tcx.mk_opaque(rpit_def_id, substs);
+
+ if !self.can_coerce(first_ty, expected) || !self.can_coerce(second_ty, expected) {
+ return None;
+ }
+
+ for ty in [first_ty, second_ty] {
+ for pred in self.tcx.bound_explicit_item_bounds(rpit_def_id).transpose_iter() {
+ let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx, substs);
+ let pred = match pred.kind().skip_binder() {
+ ty::PredicateKind::Trait(mut trait_pred) => {
+ assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
+ trait_pred.trait_ref.substs =
+ self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]);
+ pred.kind().rebind(trait_pred).to_predicate(self.tcx)
}
+ ty::PredicateKind::Projection(mut proj_pred) => {
+ assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
+ proj_pred.projection_ty.substs = self
+ .tcx
+ .mk_substs_trait(ty, &proj_pred.projection_ty.substs[1..]);
+ pred.kind().rebind(proj_pred).to_predicate(self.tcx)
+ }
+ _ => continue,
+ };
+ if !self.predicate_must_hold_modulo_regions(&Obligation::new(
+ ObligationCause::misc(span, self.body_id),
+ self.param_env,
+ pred,
+ )) {
+ return None;
}
- _ => {}
}
}
- // If all the obligations hold (or there are no obligations) the tail expression
- // we can suggest to return a boxed trait object instead of an opaque type.
- if suggest_box { self.ret_type_span } else { None }
+
+ Some(span)
}
_ => None,
}
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 75f5aced8..0d35c2479 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -1,5 +1,5 @@
use super::method::MethodCallee;
-use super::{Expectation, FnCtxt, TupleArgumentsFlag};
+use super::{DefIdOrName, Expectation, FnCtxt, TupleArgumentsFlag};
use crate::type_error_struct;
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
@@ -24,7 +24,8 @@ use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_target::spec::abi;
use rustc_trait_selection::autoderef::Autoderef;
-use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
+use rustc_trait_selection::infer::InferCtxtExt as _;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use std::iter;
@@ -471,7 +472,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
- err.span_label(call_expr.span, "call expression requires function");
+ if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_expr, callee_ty)
+ && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
+ {
+ let descr = match maybe_def {
+ DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id),
+ DefIdOrName::Name(name) => name,
+ };
+ err.span_label(
+ callee_expr.span,
+ format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called")
+ );
+ if let DefIdOrName::DefId(def_id) = maybe_def
+ && let Some(def_span) = self.tcx.hir().span_if_local(def_id)
+ {
+ err.span_label(def_span, "the callable type is defined here");
+ }
+ } else {
+ err.span_label(call_expr.span, "call expression requires function");
+ }
}
if let Some(span) = self.tcx.hir().res_span(def) {
diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs
index 7aaddc2bd..81a979865 100644
--- a/compiler/rustc_typeck/src/check/cast.rs
+++ b/compiler/rustc_typeck/src/check/cast.rs
@@ -32,30 +32,33 @@ use super::FnCtxt;
use crate::hir::def_id::DefId;
use crate::type_error_struct;
+use hir::def_id::LOCAL_CRATE;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
-use rustc_hir::lang_items::LangItem;
+use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode};
use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable};
+use rustc_middle::ty::{self, Binder, Ty, TypeAndMut, TypeVisitable, VariantDef};
use rustc_session::lint;
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
-use rustc_trait_selection::traits;
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
/// Reifies a cast check to be checked once we have full type information for
/// a function context.
#[derive(Debug)]
pub struct CastCheck<'tcx> {
+ /// The expression whose value is being casted
expr: &'tcx hir::Expr<'tcx>,
+ /// The source type for the cast expression
expr_ty: Ty<'tcx>,
expr_span: Span,
+ /// The target type. That is, the type we are casting to.
cast_ty: Ty<'tcx>,
cast_span: Span,
span: Span,
@@ -96,13 +99,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return Err(reported);
}
- if self.type_is_known_to_be_sized_modulo_regions(t, span) {
+ if self.type_is_sized_modulo_regions(self.param_env, t, span) {
return Ok(Some(PointerKind::Thin));
}
Ok(match *t.kind() {
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
- ty::Dynamic(ref tty, ..) => Some(PointerKind::VTable(tty.principal_def_id())),
+ ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())),
ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().fields.last() {
None => Some(PointerKind::Thin),
Some(f) => {
@@ -139,6 +142,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Generator(..)
| ty::Adt(..)
| ty::Never
+ | ty::Dynamic(_, _, ty::DynStar)
| ty::Error(_) => {
let reported = self
.tcx
@@ -173,6 +177,7 @@ pub enum CastError {
/// or "a length". If this argument is None, then the metadata is unknown, for example,
/// when we're typechecking a type parameter with a ?Sized bound.
IntToFatCast(Option<&'static str>),
+ ForeignNonExhaustiveAdt,
}
impl From<ErrorGuaranteed> for CastError {
@@ -199,8 +204,76 @@ fn make_invalid_casting_error<'a, 'tcx>(
)
}
+pub enum CastCheckResult<'tcx> {
+ Ok,
+ Deferred(CastCheck<'tcx>),
+ Err(ErrorGuaranteed),
+}
+
+pub fn check_cast<'tcx>(
+ fcx: &FnCtxt<'_, 'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
+ expr_ty: Ty<'tcx>,
+ cast_ty: Ty<'tcx>,
+ cast_span: Span,
+ span: Span,
+) -> CastCheckResult<'tcx> {
+ if cast_ty.is_dyn_star() {
+ check_dyn_star_cast(fcx, expr, expr_ty, cast_ty)
+ } else {
+ match CastCheck::new(fcx, expr, expr_ty, cast_ty, cast_span, span) {
+ Ok(check) => CastCheckResult::Deferred(check),
+ Err(e) => CastCheckResult::Err(e),
+ }
+ }
+}
+
+fn check_dyn_star_cast<'tcx>(
+ fcx: &FnCtxt<'_, 'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
+ expr_ty: Ty<'tcx>,
+ cast_ty: Ty<'tcx>,
+) -> CastCheckResult<'tcx> {
+ // Find the bounds in the dyn*. For eaxmple, if we have
+ //
+ // let x = 22_usize as dyn* (Clone + Debug + 'static)
+ //
+ // this would return `existential_predicates = [?Self: Clone, ?Self: Debug]` and `region = 'static`.
+ let (existential_predicates, region) = match cast_ty.kind() {
+ ty::Dynamic(predicates, region, ty::DynStar) => (predicates, region),
+ _ => panic!("Invalid dyn* cast_ty"),
+ };
+
+ let cause = ObligationCause::new(
+ expr.span,
+ fcx.body_id,
+ // FIXME(dyn-star): Use a better obligation cause code
+ ObligationCauseCode::MiscObligation,
+ );
+
+ // For each existential predicate (e.g., `?Self: Clone`) substitute
+ // the type of the expression (e.g., `usize` in our example above)
+ // and then require that the resulting predicate (e.g., `usize: Clone`)
+ // holds (it does).
+ for existential_predicate in existential_predicates.iter() {
+ let predicate = existential_predicate.with_self_ty(fcx.tcx, expr_ty);
+ fcx.register_predicate(Obligation::new(cause.clone(), fcx.param_env, predicate));
+ }
+
+ // Enforce the region bound `'static` (e.g., `usize: 'static`, in our example).
+ fcx.register_predicate(Obligation::new(
+ cause,
+ fcx.param_env,
+ fcx.tcx.mk_predicate(Binder::dummy(ty::PredicateKind::TypeOutlives(
+ ty::OutlivesPredicate(expr_ty, *region),
+ ))),
+ ));
+
+ CastCheckResult::Ok
+}
+
impl<'a, 'tcx> CastCheck<'tcx> {
- pub fn new(
+ fn new(
fcx: &FnCtxt<'a, 'tcx>,
expr: &'tcx hir::Expr<'tcx>,
expr_ty: Ty<'tcx>,
@@ -215,7 +288,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
// cases now. We do a more thorough check at the end, once
// inference is more completely known.
match cast_ty.kind() {
- ty::Dynamic(..) | ty::Slice(..) => {
+ ty::Dynamic(_, _, ty::Dyn) | ty::Slice(..) => {
let reported = check.report_cast_to_unsized_type(fcx);
Err(reported)
}
@@ -591,6 +664,17 @@ impl<'a, 'tcx> CastCheck<'tcx> {
}
err.emit();
}
+ CastError::ForeignNonExhaustiveAdt => {
+ make_invalid_casting_error(
+ fcx.tcx.sess,
+ self.span,
+ self.expr_ty,
+ self.cast_ty,
+ fcx,
+ )
+ .note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate")
+ .emit();
+ }
}
}
@@ -692,7 +776,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty);
- if !fcx.type_is_known_to_be_sized_modulo_regions(self.cast_ty, self.span)
+ if !fcx.type_is_sized_modulo_regions(fcx.param_env, self.cast_ty, self.span)
&& !self.cast_ty.has_infer_types()
{
self.report_cast_to_unsized_type(fcx);
@@ -789,6 +873,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
_ => return Err(CastError::NonScalar),
};
+ if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
+ if adt_def.did().krate != LOCAL_CRATE {
+ if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
+ return Err(CastError::ForeignNonExhaustiveAdt);
+ }
+ }
+ }
+
match (t_from, t_cast) {
// These types have invariants! can't cast into them.
(_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),
@@ -835,6 +927,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
+
+ // FIXME(dyn-star): this needs more conditions...
+ (_, DynStar) => Ok(CastKind::DynStarCast),
+
+ // FIXME(dyn-star): do we want to allow dyn* upcasting or other casts?
+ (DynStar, _) => Err(CastError::IllegalCast),
}
}
@@ -1063,10 +1161,3 @@ impl<'a, 'tcx> CastCheck<'tcx> {
);
}
}
-
-impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
- fn type_is_known_to_be_sized_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
- let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
- traits::type_known_to_meet_bound_modulo_regions(self, self.param_env, ty, lang_item, span)
- }
-}
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 9c1fd9b30..d6fa74c87 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -18,6 +18,7 @@ use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::Obligation;
use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
use rustc_middle::hir::nested_filter;
+use rustc_middle::middle::stability::EvalResult;
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -32,7 +33,6 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCtxt};
use rustc_ty_utils::representability::{self, Representability};
-use std::iter;
use std::ops::ControlFlow;
pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
@@ -101,12 +101,11 @@ pub(super) fn check_fn<'a, 'tcx>(
decl.output.span(),
param_env,
));
- // If we replaced declared_ret_ty with infer vars, then we must be infering
+ // If we replaced declared_ret_ty with infer vars, then we must be inferring
// an opaque type, so set a flag so we can improve diagnostics.
fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
- fcx.ret_type_span = Some(decl.output.span());
let span = body.value.span;
@@ -610,12 +609,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
match arg.kind {
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
- [
- PathSegment {
- res: Some(Res::SelfTy { trait_: _, alias_to: impl_ref }),
- ..
- },
- ] => {
+ [PathSegment { res: Res::SelfTy { trait_: _, alias_to: impl_ref }, .. }] => {
let impl_ty_name =
impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id));
self.selftys.push((path.span, impl_ty_name));
@@ -1104,12 +1098,28 @@ fn check_impl_items_against_trait<'tcx>(
missing_items.push(tcx.associated_item(trait_item_id));
}
- if let Some(required_items) = &must_implement_one_of {
- // true if this item is specifically implemented in this impl
- let is_implemented_here = ancestors
- .leaf_def(tcx, trait_item_id)
- .map_or(false, |node_item| !node_item.defining_node.is_from_trait());
+ // true if this item is specifically implemented in this impl
+ let is_implemented_here = ancestors
+ .leaf_def(tcx, trait_item_id)
+ .map_or(false, |node_item| !node_item.defining_node.is_from_trait());
+
+ if !is_implemented_here {
+ match tcx.eval_default_body_stability(trait_item_id, full_impl_span) {
+ EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable(
+ tcx,
+ full_impl_span,
+ trait_item_id,
+ feature,
+ reason,
+ issue,
+ ),
+ // Unmarked default bodies are considered stable (at least for now).
+ EvalResult::Allow | EvalResult::Unmarked => {}
+ }
+ }
+
+ if let Some(required_items) = &must_implement_one_of {
if is_implemented_here {
let trait_item = tcx.associated_item(trait_item_id);
if required_items.contains(&trait_item.ident(tcx)) {
@@ -1448,7 +1458,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
def.destructor(tcx); // force the destructor to be evaluated
if vs.is_empty() {
- if let Some(attr) = tcx.get_attr(def_id.to_def_id(), sym::repr) {
+ if let Some(attr) = tcx.get_attrs(def_id.to_def_id(), sym::repr).next() {
struct_span_err!(
tcx.sess,
attr.span,
@@ -1494,76 +1504,107 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
}
}
- let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
- // This tracks the previous variant span (in the loop) incase we need it for diagnostics
- let mut prev_variant_span: Span = DUMMY_SP;
- for ((_, discr), v) in iter::zip(def.discriminants(tcx), vs) {
- // Check for duplicate discriminant values
- if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
- let variant_did = def.variant(VariantIdx::new(i)).def_id;
- let variant_i_hir_id = tcx.hir().local_def_id_to_hir_id(variant_did.expect_local());
- let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
- let i_span = match variant_i.disr_expr {
- Some(ref expr) => tcx.hir().span(expr.hir_id),
- None => tcx.def_span(variant_did),
- };
- let span = match v.disr_expr {
- Some(ref expr) => tcx.hir().span(expr.hir_id),
- None => v.span,
- };
- let display_discr = format_discriminant_overflow(tcx, v, discr);
- let display_discr_i = format_discriminant_overflow(tcx, variant_i, disr_vals[i]);
- let no_disr = v.disr_expr.is_none();
- let mut err = struct_span_err!(
- tcx.sess,
- sp,
- E0081,
- "discriminant value `{}` assigned more than once",
- discr,
- );
-
- err.span_label(i_span, format!("first assignment of {display_discr_i}"));
- err.span_label(span, format!("second assignment of {display_discr}"));
-
- if no_disr {
- err.span_label(
- prev_variant_span,
- format!(
- "assigned discriminant for `{}` was incremented from this discriminant",
- v.ident
- ),
- );
- }
- err.emit();
- }
-
- disr_vals.push(discr);
- prev_variant_span = v.span;
- }
+ detect_discriminant_duplicate(tcx, def.discriminants(tcx).collect(), vs, sp);
check_representable(tcx, sp, def_id);
check_transparent(tcx, sp, def);
}
-/// In the case that a discriminant is both a duplicate and an overflowing literal,
-/// we insert both the assigned discriminant and the literal it overflowed from into the formatted
-/// output. Otherwise we format the discriminant normally.
-fn format_discriminant_overflow<'tcx>(
+/// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
+fn detect_discriminant_duplicate<'tcx>(
tcx: TyCtxt<'tcx>,
- variant: &hir::Variant<'_>,
- dis: Discr<'tcx>,
-) -> String {
- if let Some(expr) = &variant.disr_expr {
- let body = &tcx.hir().body(expr.body).value;
- if let hir::ExprKind::Lit(lit) = &body.kind
- && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
- && dis.val != *lit_value
- {
- return format!("`{dis}` (overflowed from `{lit_value}`)");
+ mut discrs: Vec<(VariantIdx, Discr<'tcx>)>,
+ vs: &'tcx [hir::Variant<'tcx>],
+ self_span: Span,
+) {
+ // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate.
+ // Here `idx` refers to the order of which the discriminant appears, and its index in `vs`
+ let report = |dis: Discr<'tcx>, idx: usize, err: &mut Diagnostic| {
+ let var = &vs[idx]; // HIR for the duplicate discriminant
+ let (span, display_discr) = match var.disr_expr {
+ Some(ref expr) => {
+ // In the case the discriminant is both a duplicate and overflowed, let the user know
+ if let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind
+ && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
+ && *lit_value != dis.val
+ {
+ (tcx.hir().span(expr.hir_id), format!("`{dis}` (overflowed from `{lit_value}`)"))
+ // Otherwise, format the value as-is
+ } else {
+ (tcx.hir().span(expr.hir_id), format!("`{dis}`"))
+ }
+ }
+ None => {
+ // At this point we know this discriminant is a duplicate, and was not explicitly
+ // assigned by the user. Here we iterate backwards to fetch the HIR for the last
+ // explicitly assigned discriminant, and letting the user know that this was the
+ // increment startpoint, and how many steps from there leading to the duplicate
+ if let Some((n, hir::Variant { span, ident, .. })) =
+ vs[..idx].iter().rev().enumerate().find(|v| v.1.disr_expr.is_some())
+ {
+ let ve_ident = var.ident;
+ let n = n + 1;
+ let sp = if n > 1 { "variants" } else { "variant" };
+
+ err.span_label(
+ *span,
+ format!("discriminant for `{ve_ident}` incremented from this startpoint (`{ident}` + {n} {sp} later => `{ve_ident}` = {dis})"),
+ );
+ }
+
+ (vs[idx].span, format!("`{dis}`"))
+ }
+ };
+
+ err.span_label(span, format!("{display_discr} assigned here"));
+ };
+
+ // Here we loop through the discriminants, comparing each discriminant to another.
+ // When a duplicate is detected, we instantiate an error and point to both
+ // initial and duplicate value. The duplicate discriminant is then discarded by swapping
+ // it with the last element and decrementing the `vec.len` (which is why we have to evaluate
+ // `discrs.len()` anew every iteration, and why this could be tricky to do in a functional
+ // style as we are mutating `discrs` on the fly).
+ let mut i = 0;
+ while i < discrs.len() {
+ let hir_var_i_idx = discrs[i].0.index();
+ let mut error: Option<DiagnosticBuilder<'_, _>> = None;
+
+ let mut o = i + 1;
+ while o < discrs.len() {
+ let hir_var_o_idx = discrs[o].0.index();
+
+ if discrs[i].1.val == discrs[o].1.val {
+ let err = error.get_or_insert_with(|| {
+ let mut ret = struct_span_err!(
+ tcx.sess,
+ self_span,
+ E0081,
+ "discriminant value `{}` assigned more than once",
+ discrs[i].1,
+ );
+
+ report(discrs[i].1, hir_var_i_idx, &mut ret);
+
+ ret
+ });
+
+ report(discrs[o].1, hir_var_o_idx, err);
+
+ // Safe to unwrap here, as we wouldn't reach this point if `discrs` was empty
+ discrs[o] = *discrs.last().unwrap();
+ discrs.pop();
+ } else {
+ o += 1;
+ }
}
- }
- format!("`{dis}`")
+ if let Some(mut e) = error {
+ e.emit();
+ }
+
+ i += 1;
+ }
}
pub(super) fn check_type_params_are_used<'tcx>(
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index fee872155..9b943b160 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -4,6 +4,7 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
use crate::astconv::AstConv;
use crate::rustc_middle::ty::subst::Subst;
+use hir::def::DefKind;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
@@ -29,7 +30,12 @@ struct ExpectedSig<'tcx> {
}
struct ClosureSignatures<'tcx> {
+ /// The signature users of the closure see.
bound_sig: ty::PolyFnSig<'tcx>,
+ /// The signature within the function body.
+ /// This mostly differs in the sense that lifetimes are now early bound and any
+ /// opaque types from the signature expectation are overriden in case there are
+ /// explicit hidden types written by the user in the closure signature.
liberated_sig: ty::FnSig<'tcx>,
}
@@ -58,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.check_closure(expr, expected_kind, decl, body, gen, expected_sig)
}
- #[instrument(skip(self, expr, body, decl), level = "debug")]
+ #[instrument(skip(self, expr, body, decl), level = "debug", ret)]
fn check_closure(
&self,
expr: &hir::Expr<'_>,
@@ -158,11 +164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
},
);
- let closure_type = self.tcx.mk_closure(expr_def_id.to_def_id(), closure_substs.substs);
-
- debug!(?expr.hir_id, ?closure_type);
-
- closure_type
+ self.tcx.mk_closure(expr_def_id.to_def_id(), closure_substs.substs)
}
/// Given the expected type, figures out what it can about this closure we
@@ -262,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// The `cause_span` should be the span that caused us to
/// have this expected signature, or `None` if we can't readily
/// know that.
- #[instrument(level = "debug", skip(self, cause_span))]
+ #[instrument(level = "debug", skip(self, cause_span), ret)]
fn deduce_sig_from_projection(
&self,
cause_span: Option<Span>,
@@ -317,7 +319,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Unsafety::Normal,
Abi::Rust,
));
- debug!(?sig);
Some(ExpectedSig { cause_span, sig })
}
@@ -448,18 +449,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Along the way, it also writes out entries for types that the user
// wrote into our typeck results, which are then later used by the privacy
// check.
- match self.check_supplied_sig_against_expectation(
+ match self.merge_supplied_sig_with_expectation(
hir_id,
expr_def_id,
decl,
body,
- &closure_sigs,
+ closure_sigs,
) {
Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok),
- Err(_) => return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body),
+ Err(_) => self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body),
}
-
- closure_sigs
}
fn sig_of_closure_with_mismatched_number_of_arguments(
@@ -501,21 +500,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Enforce the user's types against the expectation. See
/// `sig_of_closure_with_expectation` for details on the overall
/// strategy.
- fn check_supplied_sig_against_expectation(
+ #[instrument(level = "debug", skip(self, hir_id, expr_def_id, decl, body, expected_sigs))]
+ fn merge_supplied_sig_with_expectation(
&self,
hir_id: hir::HirId,
expr_def_id: DefId,
decl: &hir::FnDecl<'_>,
body: &hir::Body<'_>,
- expected_sigs: &ClosureSignatures<'tcx>,
- ) -> InferResult<'tcx, ()> {
+ mut expected_sigs: ClosureSignatures<'tcx>,
+ ) -> InferResult<'tcx, ClosureSignatures<'tcx>> {
// Get the signature S that the user gave.
//
// (See comment on `sig_of_closure_with_expectation` for the
// meaning of these letters.)
let supplied_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body);
- debug!("check_supplied_sig_against_expectation: supplied_sig={:?}", supplied_sig);
+ debug!(?supplied_sig);
// FIXME(#45727): As discussed in [this comment][c1], naively
// forcing equality here actually results in suboptimal error
@@ -533,23 +533,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
self.commit_if_ok(|_| {
let mut all_obligations = vec![];
+ let inputs: Vec<_> = iter::zip(
+ decl.inputs,
+ supplied_sig.inputs().skip_binder(), // binder moved to (*) below
+ )
+ .map(|(hir_ty, &supplied_ty)| {
+ // Instantiate (this part of..) S to S', i.e., with fresh variables.
+ self.replace_bound_vars_with_fresh_vars(
+ hir_ty.span,
+ LateBoundRegionConversionTime::FnCall,
+ // (*) binder moved to here
+ supplied_sig.inputs().rebind(supplied_ty),
+ )
+ })
+ .collect();
// The liberated version of this signature should be a subtype
// of the liberated form of the expectation.
for ((hir_ty, &supplied_ty), expected_ty) in iter::zip(
- iter::zip(
- decl.inputs,
- supplied_sig.inputs().skip_binder(), // binder moved to (*) below
- ),
+ iter::zip(decl.inputs, &inputs),
expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'.
) {
- // Instantiate (this part of..) S to S', i.e., with fresh variables.
- let supplied_ty = self.replace_bound_vars_with_fresh_vars(
- hir_ty.span,
- LateBoundRegionConversionTime::FnCall,
- supplied_sig.inputs().rebind(supplied_ty),
- ); // recreated from (*) above
-
// Check that E' = S'.
let cause = self.misc(hir_ty.span);
let InferOk { value: (), obligations } =
@@ -568,7 +572,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
all_obligations.extend(obligations);
- Ok(InferOk { value: (), obligations: all_obligations })
+ let inputs = inputs.into_iter().map(|ty| self.resolve_vars_if_possible(ty));
+
+ expected_sigs.liberated_sig = self.tcx.mk_fn_sig(
+ inputs,
+ supplied_output_ty,
+ expected_sigs.liberated_sig.c_variadic,
+ hir::Unsafety::Normal,
+ Abi::RustCall,
+ );
+
+ Ok(InferOk { value: expected_sigs, obligations: all_obligations })
})
}
@@ -576,7 +590,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// types that the user gave into a signature.
///
/// Also, record this closure signature for later.
- #[instrument(skip(self, decl, body), level = "debug")]
+ #[instrument(skip(self, decl, body), level = "debug", ret)]
fn supplied_sig_of_closure(
&self,
hir_id: hir::HirId,
@@ -629,8 +643,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bound_vars,
);
- debug!(?result);
-
let c_result = self.inh.infcx.canonicalize_response(result);
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
@@ -643,7 +655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// user specified. The "desugared" return type is an `impl
/// Future<Output = T>`, so we do this by searching through the
/// obligations to extract the `T`.
- #[instrument(skip(self), level = "debug")]
+ #[instrument(skip(self), level = "debug", ret)]
fn deduce_future_output_from_obligations(
&self,
expr_def_id: DefId,
@@ -687,9 +699,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, substs), s.0))?,
ty::Error(_) => return None,
+ ty::Projection(proj)
+ if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder =>
+ {
+ self.tcx
+ .bound_explicit_item_bounds(proj.item_def_id)
+ .transpose_iter()
+ .map(|e| e.map_bound(|e| *e).transpose_tuple2())
+ .find_map(|(p, s)| get_future_output(p.subst(self.tcx, proj.substs), s.0))?
+ }
_ => span_bug!(
self.tcx.def_span(expr_def_id),
- "async fn generator return type not an inference variable"
+ "async fn generator return type not an inference variable: {ret_ty}"
),
};
@@ -704,7 +725,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
self.register_predicates(obligations);
- debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
Some(output_ty)
}
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 2ed5f569b..def592c46 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -38,10 +38,12 @@
use crate::astconv::AstConv;
use crate::check::FnCtxt;
use rustc_errors::{
- struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
+ struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::Expr;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{Coercion, InferOk, InferResult};
use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt};
@@ -87,6 +89,19 @@ impl<'a, 'tcx> Deref for Coerce<'a, 'tcx> {
type CoerceResult<'tcx> = InferResult<'tcx, (Vec<Adjustment<'tcx>>, Ty<'tcx>)>;
+struct CollectRetsVisitor<'tcx> {
+ ret_exprs: Vec<&'tcx hir::Expr<'tcx>>,
+}
+
+impl<'tcx> Visitor<'tcx> for CollectRetsVisitor<'tcx> {
+ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
+ if let hir::ExprKind::Ret(_) = expr.kind {
+ self.ret_exprs.push(expr);
+ }
+ intravisit::walk_expr(self, expr);
+ }
+}
+
/// Coercing a mutable reference to an immutable works, while
/// coercing `&T` to `&mut T` should be forbidden.
fn coerce_mutbls<'tcx>(
@@ -1464,23 +1479,29 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
}
Err(coercion_error) => {
+ // Mark that we've failed to coerce the types here to suppress
+ // any superfluous errors we might encounter while trying to
+ // emit or provide suggestions on how to fix the initial error.
+ fcx.set_tainted_by_errors();
let (expected, found) = if label_expression_as_expected {
// In the case where this is a "forced unit", like
// `break`, we want to call the `()` "expected"
// since it is implied by the syntax.
// (Note: not all force-units work this way.)"
- (expression_ty, self.final_ty.unwrap_or(self.expected_ty))
+ (expression_ty, self.merged_ty())
} else {
// Otherwise, the "expected" type for error
// reporting is the current unification type,
// which is basically the LUB of the expressions
// we've seen so far (combined with the expected
// type)
- (self.final_ty.unwrap_or(self.expected_ty), expression_ty)
+ (self.merged_ty(), expression_ty)
};
+ let (expected, found) = fcx.resolve_vars_if_possible((expected, found));
let mut err;
let mut unsized_return = false;
+ let mut visitor = CollectRetsVisitor { ret_exprs: vec![] };
match *cause.code() {
ObligationCauseCode::ReturnNoExpression => {
err = struct_span_err!(
@@ -1506,6 +1527,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
if !fcx.tcx.features().unsized_locals {
unsized_return = self.is_return_ty_unsized(fcx, blk_id);
}
+ if let Some(expression) = expression
+ && let hir::ExprKind::Loop(loop_blk, ..) = expression.kind {
+ intravisit::walk_block(& mut visitor, loop_blk);
+ }
}
ObligationCauseCode::ReturnValue(id) => {
err = self.report_return_mismatched_types(
@@ -1551,12 +1576,47 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
);
}
+ if visitor.ret_exprs.len() > 0 && let Some(expr) = expression {
+ self.note_unreachable_loop_return(&mut err, &expr, &visitor.ret_exprs);
+ }
err.emit_unless(unsized_return);
self.final_ty = Some(fcx.tcx.ty_error());
}
}
}
+ fn note_unreachable_loop_return(
+ &self,
+ err: &mut Diagnostic,
+ expr: &hir::Expr<'tcx>,
+ ret_exprs: &Vec<&'tcx hir::Expr<'tcx>>,
+ ) {
+ let hir::ExprKind::Loop(_, _, _, loop_span) = expr.kind else { return;};
+ let mut span: MultiSpan = vec![loop_span].into();
+ span.push_span_label(loop_span, "this might have zero elements to iterate on");
+ const MAXITER: usize = 3;
+ let iter = ret_exprs.iter().take(MAXITER);
+ for ret_expr in iter {
+ span.push_span_label(
+ ret_expr.span,
+ "if the loop doesn't execute, this value would never get returned",
+ );
+ }
+ err.span_note(
+ span,
+ "the function expects a value to always be returned, but loops might run zero times",
+ );
+ if MAXITER < ret_exprs.len() {
+ err.note(&format!(
+ "if the loop doesn't execute, {} other values would never get returned",
+ ret_exprs.len() - MAXITER
+ ));
+ }
+ err.help(
+ "return a value for the case when the loop has zero elements to iterate on, or \
+ consider changing the return type to account for that possibility",
+ );
+ }
fn report_return_mismatched_types<'a>(
&self,
@@ -1648,9 +1708,30 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
);
}
- if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
+ let ret_coercion_span = fcx.ret_coercion_span.get();
+
+ if let Some(sp) = ret_coercion_span
+ // If the closure has an explicit return type annotation, or if
+ // the closure's return type has been inferred from outside
+ // requirements (such as an Fn* trait bound), then a type error
+ // may occur at the first return expression we see in the closure
+ // (if it conflicts with the declared return type). Skip adding a
+ // note in this case, since it would be incorrect.
+ && !fcx.return_type_pre_known
+ {
+ err.span_note(
+ sp,
+ &format!(
+ "return type inferred to be `{}` here",
+ expected
+ ),
+ );
+ }
+
+ if let (Some(sp), Some(fn_output)) = (ret_coercion_span, fn_output) {
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output);
}
+
err
}
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 666498403..59d591acd 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -1,23 +1,26 @@
use super::potentially_plural_count;
-use crate::check::regionck::OutlivesEnvironmentExt;
-use crate::check::wfcheck;
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
-use rustc_data_structures::fx::FxHashSet;
+use hir::def_id::DefId;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit;
use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{self, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::util::ExplicitSelf;
-use rustc_middle::ty::{self, DefIdTree};
+use rustc_middle::ty::{
+ self, AssocItem, DefIdTree, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
+};
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
+use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal,
};
@@ -71,11 +74,78 @@ pub(crate) fn compare_impl_method<'tcx>(
}
}
+/// This function is best explained by example. Consider a trait:
+///
+/// trait Trait<'t, T> {
+/// // `trait_m`
+/// fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
+/// }
+///
+/// And an impl:
+///
+/// impl<'i, 'j, U> Trait<'j, &'i U> for Foo {
+/// // `impl_m`
+/// fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo;
+/// }
+///
+/// We wish to decide if those two method types are compatible.
+/// For this we have to show that, assuming the bounds of the impl hold, the
+/// bounds of `trait_m` imply the bounds of `impl_m`.
+///
+/// We start out with `trait_to_impl_substs`, that maps the trait
+/// type parameters to impl type parameters. This is taken from the
+/// impl trait reference:
+///
+/// trait_to_impl_substs = {'t => 'j, T => &'i U, Self => Foo}
+///
+/// We create a mapping `dummy_substs` that maps from the impl type
+/// parameters to fresh types and regions. For type parameters,
+/// this is the identity transform, but we could as well use any
+/// placeholder types. For regions, we convert from bound to free
+/// regions (Note: but only early-bound regions, i.e., those
+/// declared on the impl or used in type parameter bounds).
+///
+/// impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 }
+///
+/// Now we can apply `placeholder_substs` to the type of the impl method
+/// to yield a new function type in terms of our fresh, placeholder
+/// types:
+///
+/// <'b> fn(t: &'i0 U0, m: &'b) -> Foo
+///
+/// We now want to extract and substitute the type of the *trait*
+/// method and compare it. To do so, we must create a compound
+/// substitution by combining `trait_to_impl_substs` and
+/// `impl_to_placeholder_substs`, and also adding a mapping for the method
+/// type parameters. We extend the mapping to also include
+/// the method parameters.
+///
+/// trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 }
+///
+/// Applying this to the trait method type yields:
+///
+/// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
+///
+/// This type is also the same but the name of the bound region (`'a`
+/// vs `'b`). However, the normal subtyping rules on fn types handle
+/// this kind of equivalency just fine.
+///
+/// We now use these substitutions to ensure that all declared bounds are
+/// satisfied by the implementation's method.
+///
+/// We do this by creating a parameter environment which contains a
+/// substitution corresponding to `impl_to_placeholder_substs`. We then build
+/// `trait_to_placeholder_substs` and use it to convert the predicates contained
+/// in the `trait_m` generics to the placeholder form.
+///
+/// Finally we register each of these predicates as an obligation and check that
+/// they hold.
+#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))]
fn compare_predicate_entailment<'tcx>(
tcx: TyCtxt<'tcx>,
- impl_m: &ty::AssocItem,
+ impl_m: &AssocItem,
impl_m_span: Span,
- trait_m: &ty::AssocItem,
+ trait_m: &AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
let trait_to_impl_substs = impl_trait_ref.substs;
@@ -97,69 +167,6 @@ fn compare_predicate_entailment<'tcx>(
},
);
- // This code is best explained by example. Consider a trait:
- //
- // trait Trait<'t, T> {
- // fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
- // }
- //
- // And an impl:
- //
- // impl<'i, 'j, U> Trait<'j, &'i U> for Foo {
- // fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo;
- // }
- //
- // We wish to decide if those two method types are compatible.
- //
- // We start out with trait_to_impl_substs, that maps the trait
- // type parameters to impl type parameters. This is taken from the
- // impl trait reference:
- //
- // trait_to_impl_substs = {'t => 'j, T => &'i U, Self => Foo}
- //
- // We create a mapping `dummy_substs` that maps from the impl type
- // parameters to fresh types and regions. For type parameters,
- // this is the identity transform, but we could as well use any
- // placeholder types. For regions, we convert from bound to free
- // regions (Note: but only early-bound regions, i.e., those
- // declared on the impl or used in type parameter bounds).
- //
- // impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 }
- //
- // Now we can apply placeholder_substs to the type of the impl method
- // to yield a new function type in terms of our fresh, placeholder
- // types:
- //
- // <'b> fn(t: &'i0 U0, m: &'b) -> Foo
- //
- // We now want to extract and substitute the type of the *trait*
- // method and compare it. To do so, we must create a compound
- // substitution by combining trait_to_impl_substs and
- // impl_to_placeholder_substs, and also adding a mapping for the method
- // type parameters. We extend the mapping to also include
- // the method parameters.
- //
- // trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 }
- //
- // Applying this to the trait method type yields:
- //
- // <'a> fn(t: &'i0 U0, m: &'a) -> Foo
- //
- // This type is also the same but the name of the bound region ('a
- // vs 'b). However, the normal subtyping rules on fn types handle
- // this kind of equivalency just fine.
- //
- // We now use these substitutions to ensure that all declared bounds are
- // satisfied by the implementation's method.
- //
- // We do this by creating a parameter environment which contains a
- // substitution corresponding to impl_to_placeholder_substs. We then build
- // trait_to_placeholder_substs and use it to convert the predicates contained
- // in the trait_m.generics to the placeholder form.
- //
- // Finally we register each of these predicates as an obligation in
- // a fresh FulfillmentCtxt, and invoke select_all_or_error.
-
// Create mapping from impl to placeholder.
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
@@ -264,8 +271,14 @@ fn compare_predicate_entailment<'tcx>(
let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
+
+ // Next, add all inputs and output as well-formed tys. Importantly,
+ // we have to do this before normalization, since the normalized ty may
+ // not contain the input parameters. See issue #87748.
+ wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_sig = ocx.normalize(norm_cause, param_env, trait_sig);
- // Add the resulting inputs and output as well-formed.
+ // We also have to add the normalized trait signature
+ // as we don't normalize during implied bounds computation.
wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
@@ -277,16 +290,30 @@ fn compare_predicate_entailment<'tcx>(
// type would be more appropriate. In other places we have a `Vec<Span>`
// corresponding to their `Vec<Predicate>`, but we don't have that here.
// Fixing this would improve the output of test `issue-83765.rs`.
- let sub_result = infcx
+ let mut result = infcx
.at(&cause, param_env)
.sup(trait_fty, impl_fty)
.map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok));
- if let Err(terr) = sub_result {
+ // HACK(RPITIT): #101614. When we are trying to infer the hidden types for
+ // RPITITs, we need to equate the output tys instead of just subtyping. If
+ // we just use `sup` above, we'll end up `&'static str <: _#1t`, which causes
+ // us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets
+ // fixed up to `ReEmpty`, and which is certainly not what we want.
+ if trait_fty.has_infer_types() {
+ result = result.and_then(|()| {
+ infcx
+ .at(&cause, param_env)
+ .eq(trait_sig.output(), impl_sig.output())
+ .map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok))
+ });
+ }
+
+ if let Err(terr) = result {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
let (impl_err_span, trait_err_span) =
- extract_spans_for_error_reporting(&infcx, &terr, &cause, impl_m, trait_m);
+ extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
cause.span = impl_err_span;
@@ -376,7 +403,7 @@ fn compare_predicate_entailment<'tcx>(
expected: trait_fty.into(),
found: impl_fty.into(),
})),
- &terr,
+ terr,
false,
false,
);
@@ -394,8 +421,11 @@ fn compare_predicate_entailment<'tcx>(
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
- let mut outlives_environment = OutlivesEnvironment::new(param_env);
- outlives_environment.add_implied_bounds(infcx, wf_tys, impl_m_hir_id);
+ let outlives_environment = OutlivesEnvironment::with_bounds(
+ param_env,
+ Some(infcx),
+ infcx.implied_bounds_tys(param_env, impl_m_hir_id, wf_tys),
+ );
infcx.check_region_obligations_and_report_errors(
impl_m.def_id.expect_local(),
&outlives_environment,
@@ -405,6 +435,227 @@ fn compare_predicate_entailment<'tcx>(
})
}
+pub fn collect_trait_impl_trait_tys<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+) -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> {
+ let impl_m = tcx.opt_associated_item(def_id).unwrap();
+ let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
+ let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
+ let param_env = tcx.param_env(def_id);
+
+ let trait_to_impl_substs = impl_trait_ref.substs;
+
+ let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
+ let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
+ let cause = ObligationCause::new(
+ return_span,
+ impl_m_hir_id,
+ ObligationCauseCode::CompareImplItemObligation {
+ impl_item_def_id: impl_m.def_id.expect_local(),
+ trait_item_def_id: trait_m.def_id,
+ kind: impl_m.kind,
+ },
+ );
+
+ // Create mapping from impl to placeholder.
+ let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
+
+ // Create mapping from trait to placeholder.
+ let trait_to_placeholder_substs =
+ impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
+
+ tcx.infer_ctxt().enter(|ref infcx| {
+ let ocx = ObligationCtxt::new(infcx);
+
+ let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
+ let impl_return_ty = ocx.normalize(
+ norm_cause.clone(),
+ param_env,
+ infcx
+ .replace_bound_vars_with_fresh_vars(
+ return_span,
+ infer::HigherRankedType,
+ tcx.fn_sig(impl_m.def_id),
+ )
+ .output(),
+ );
+
+ let mut collector =
+ ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
+ let unnormalized_trait_return_ty = tcx
+ .liberate_late_bound_regions(
+ impl_m.def_id,
+ tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs),
+ )
+ .output()
+ .fold_with(&mut collector);
+ let trait_return_ty =
+ ocx.normalize(norm_cause.clone(), param_env, unnormalized_trait_return_ty);
+
+ let wf_tys = FxHashSet::from_iter([unnormalized_trait_return_ty, trait_return_ty]);
+
+ match infcx.at(&cause, param_env).eq(trait_return_ty, impl_return_ty) {
+ Ok(infer::InferOk { value: (), obligations }) => {
+ ocx.register_obligations(obligations);
+ }
+ Err(terr) => {
+ let mut diag = struct_span_err!(
+ tcx.sess,
+ cause.span(),
+ E0053,
+ "method `{}` has an incompatible return type for trait",
+ trait_m.name
+ );
+ let hir = tcx.hir();
+ infcx.note_type_err(
+ &mut diag,
+ &cause,
+ hir.get_if_local(impl_m.def_id)
+ .and_then(|node| node.fn_decl())
+ .map(|decl| (decl.output.span(), "return type in trait".to_owned())),
+ Some(infer::ValuePairs::Terms(ExpectedFound {
+ expected: trait_return_ty.into(),
+ found: impl_return_ty.into(),
+ })),
+ terr,
+ false,
+ false,
+ );
+ return Err(diag.emit());
+ }
+ }
+
+ // Check that all obligations are satisfied by the implementation's
+ // RPITs.
+ let errors = ocx.select_all_or_error();
+ if !errors.is_empty() {
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
+ }
+
+ // Finally, resolve all regions. This catches wily misuses of
+ // lifetime parameters.
+ let outlives_environment = OutlivesEnvironment::with_bounds(
+ param_env,
+ Some(infcx),
+ infcx.implied_bounds_tys(param_env, impl_m_hir_id, wf_tys),
+ );
+ infcx.check_region_obligations_and_report_errors(
+ impl_m.def_id.expect_local(),
+ &outlives_environment,
+ );
+
+ let mut collected_tys = FxHashMap::default();
+ for (def_id, (ty, substs)) in collector.types {
+ match infcx.fully_resolve(ty) {
+ Ok(ty) => {
+ // `ty` contains free regions that we created earlier while liberating the
+ // trait fn signature. However, projection normalization expects `ty` to
+ // contains `def_id`'s early-bound regions.
+ let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
+ debug!(?id_substs, ?substs);
+ let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> = substs
+ .iter()
+ .enumerate()
+ .map(|(index, arg)| (arg, id_substs[index]))
+ .collect();
+ debug!(?map);
+
+ let ty = tcx.fold_regions(ty, |region, _| {
+ if let ty::ReFree(_) = region.kind() {
+ map[&region.into()].expect_region()
+ } else {
+ region
+ }
+ });
+ debug!(%ty);
+ collected_tys.insert(def_id, ty);
+ }
+ Err(err) => {
+ tcx.sess.delay_span_bug(
+ return_span,
+ format!("could not fully resolve: {ty} => {err:?}"),
+ );
+ collected_tys.insert(def_id, tcx.ty_error());
+ }
+ }
+ }
+
+ Ok(&*tcx.arena.alloc(collected_tys))
+ })
+}
+
+struct ImplTraitInTraitCollector<'a, 'tcx> {
+ ocx: &'a ObligationCtxt<'a, 'tcx>,
+ types: FxHashMap<DefId, (Ty<'tcx>, ty::SubstsRef<'tcx>)>,
+ span: Span,
+ param_env: ty::ParamEnv<'tcx>,
+ body_id: hir::HirId,
+}
+
+impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> {
+ fn new(
+ ocx: &'a ObligationCtxt<'a, 'tcx>,
+ span: Span,
+ param_env: ty::ParamEnv<'tcx>,
+ body_id: hir::HirId,
+ ) -> Self {
+ ImplTraitInTraitCollector { ocx, types: FxHashMap::default(), span, param_env, body_id }
+ }
+}
+
+impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
+ fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
+ self.ocx.infcx.tcx
+ }
+
+ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+ if let ty::Projection(proj) = ty.kind()
+ && self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+ {
+ if let Some((ty, _)) = self.types.get(&proj.item_def_id) {
+ return *ty;
+ }
+ //FIXME(RPITIT): Deny nested RPITIT in substs too
+ if proj.substs.has_escaping_bound_vars() {
+ bug!("FIXME(RPITIT): error here");
+ }
+ // Replace with infer var
+ let infer_ty = self.ocx.infcx.next_ty_var(TypeVariableOrigin {
+ span: self.span,
+ kind: TypeVariableOriginKind::MiscVariable,
+ });
+ self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
+ // Recurse into bounds
+ for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
+ let pred_span = pred.0.1;
+
+ let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx(), proj.substs);
+ let pred = pred.fold_with(self);
+ let pred = self.ocx.normalize(
+ ObligationCause::misc(self.span, self.body_id),
+ self.param_env,
+ pred,
+ );
+
+ self.ocx.register_obligation(traits::Obligation::new(
+ ObligationCause::new(
+ self.span,
+ self.body_id,
+ ObligationCauseCode::BindingObligation(proj.item_def_id, pred_span),
+ ),
+ self.param_env,
+ pred,
+ ));
+ }
+ infer_ty
+ } else {
+ ty.super_fold_with(self)
+ }
+ }
+}
+
fn check_region_bounds_on_impl_item<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &ty::AssocItem,
@@ -463,7 +714,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
#[instrument(level = "debug", skip(infcx))]
fn extract_spans_for_error_reporting<'a, 'tcx>(
infcx: &infer::InferCtxt<'a, 'tcx>,
- terr: &TypeError<'_>,
+ terr: TypeError<'_>,
cause: &ObligationCause<'tcx>,
impl_m: &ty::AssocItem,
trait_m: &ty::AssocItem,
@@ -483,7 +734,7 @@ fn extract_spans_for_error_reporting<'a, 'tcx>(
_ => bug!("{:?} is not a TraitItemKind::Fn", trait_m),
});
- match *terr {
+ match terr {
TypeError::ArgumentMutability(i) => {
(impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
}
@@ -848,8 +1099,7 @@ fn compare_synthetic_generics<'tcx>(
{
if impl_synthetic != trait_synthetic {
let impl_def_id = impl_def_id.expect_local();
- let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_def_id);
- let impl_span = tcx.hir().span(impl_hir_id);
+ let impl_span = tcx.def_span(impl_def_id);
let trait_span = tcx.def_span(trait_def_id);
let mut err = struct_span_err!(
tcx.sess,
@@ -868,17 +1118,16 @@ fn compare_synthetic_generics<'tcx>(
// try taking the name from the trait impl
// FIXME: this is obviously suboptimal since the name can already be used
// as another generic argument
- let new_name = tcx.sess.source_map().span_to_snippet(trait_span).ok()?;
+ let new_name = tcx.opt_item_name(trait_def_id)?;
let trait_m = trait_m.def_id.as_local()?;
- let trait_m = tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m });
+ let trait_m = tcx.hir().expect_trait_item(trait_m);
let impl_m = impl_m.def_id.as_local()?;
- let impl_m = tcx.hir().impl_item(hir::ImplItemId { def_id: impl_m });
+ let impl_m = tcx.hir().expect_impl_item(impl_m);
// in case there are no generics, take the spot between the function name
// and the opening paren of the argument list
- let new_generics_span =
- tcx.sess.source_map().generate_fn_name_span(impl_span)?.shrink_to_hi();
+ let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
// in case there are generics, just replace them
let generics_span =
impl_m.generics.span.substitute_dummy(new_generics_span);
@@ -890,7 +1139,7 @@ fn compare_synthetic_generics<'tcx>(
"try changing the `impl Trait` argument to a generic parameter",
vec![
// replace `impl Trait` with `T`
- (impl_span, new_name),
+ (impl_span, new_name.to_string()),
// replace impl method generics with trait method generics
// This isn't quite right, as users might have changed the names
// of the generics, but it works for the common case
@@ -907,7 +1156,7 @@ fn compare_synthetic_generics<'tcx>(
err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
(|| {
let impl_m = impl_m.def_id.as_local()?;
- let impl_m = tcx.hir().impl_item(hir::ImplItemId { def_id: impl_m });
+ let impl_m = tcx.hir().expect_impl_item(impl_m);
let input_tys = match impl_m.kind {
hir::ImplItemKind::Fn(ref sig, _) => sig.decl.inputs,
_ => unreachable!(),
@@ -1138,7 +1387,7 @@ pub(crate) fn compare_const_impl<'tcx>(
expected: trait_ty.into(),
found: impl_ty.into(),
})),
- &terr,
+ terr,
false,
false,
);
@@ -1300,7 +1549,7 @@ fn compare_type_predicate_entailment<'tcx>(
/// For default associated types the normalization is not possible (the value
/// from the impl could be overridden). We also can't normalize generic
/// associated types (yet) because they contain bound parameters.
-#[tracing::instrument(level = "debug", skip(tcx))]
+#[instrument(level = "debug", skip(tcx))]
pub fn check_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ty: &ty::AssocItem,
@@ -1440,14 +1689,17 @@ pub fn check_type_bounds<'tcx>(
};
debug!(?normalize_param_env);
+ let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
tcx.infer_ctxt().enter(move |infcx| {
let ocx = ObligationCtxt::new(&infcx);
+ let assumed_wf_types =
+ ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty.def_id.expect_local());
+
let mut selcx = traits::SelectionContext::new(&infcx);
- let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
let normalize_cause = ObligationCause::new(
impl_ty_span,
impl_ty_hir_id,
@@ -1458,7 +1710,7 @@ pub fn check_type_bounds<'tcx>(
);
let mk_cause = |span: Span| {
let code = if span.is_dummy() {
- traits::MiscObligation
+ traits::ItemObligation(trait_ty.def_id)
} else {
traits::BindingObligation(trait_ty.def_id, span)
};
@@ -1503,17 +1755,10 @@ pub fn check_type_bounds<'tcx>(
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
- let implied_bounds = match impl_ty.container {
- ty::TraitContainer => FxHashSet::default(),
- ty::ImplContainer => wfcheck::impl_implied_bounds(
- tcx,
- param_env,
- container_id.expect_local(),
- impl_ty_span,
- ),
- };
- let mut outlives_environment = OutlivesEnvironment::new(param_env);
- outlives_environment.add_implied_bounds(&infcx, implied_bounds, impl_ty_hir_id);
+ let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_hir_id, assumed_wf_types);
+ let outlives_environment =
+ OutlivesEnvironment::with_bounds(param_env, Some(&infcx), implied_bounds);
+
infcx.check_region_obligations_and_report_errors(
impl_ty.def_id.expect_local(),
&outlives_environment,
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 4de48dc5b..e1d55ff82 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -42,10 +42,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
self.suggest_missing_parentheses(err, expr);
self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected);
+ self.suggest_copied_or_cloned(err, expr, expr_ty, expected);
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
- self.report_closure_inferred_return_type(err, expected);
}
// Requires that the two types unify, and prints an error message if
@@ -131,7 +131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// N.B., this code relies on `self.diverges` to be accurate. In particular, assignments to `!`
/// will be permitted if the diverges flag is currently "always".
- #[tracing::instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))]
+ #[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))]
pub fn demand_coerce_diag(
&self,
expr: &hir::Expr<'tcx>,
@@ -375,7 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let field_is_local = sole_field.did.is_local();
let field_is_accessible =
- sole_field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx)
+ sole_field.vis.is_accessible_from(expr.hir_id.owner, self.tcx)
// Skip suggestions for unstable public fields (for example `Pin::pointer`)
&& matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked);
@@ -590,7 +590,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let closure_params_len = closure_fn_decl.inputs.len();
let (
Some(Node::Expr(hir::Expr {
- kind: hir::ExprKind::MethodCall(method_path, method_expr, _),
+ kind: hir::ExprKind::MethodCall(method_path, receiver, ..),
..
})),
1,
@@ -598,14 +598,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return None;
};
- let self_ty = self.typeck_results.borrow().expr_ty(&method_expr[0]);
- let self_ty = format!("{:?}", self_ty);
+ let self_ty = self.typeck_results.borrow().expr_ty(receiver);
let name = method_path.ident.name;
- let is_as_ref_able = (self_ty.starts_with("&std::option::Option")
- || self_ty.starts_with("&std::result::Result")
- || self_ty.starts_with("std::option::Option")
- || self_ty.starts_with("std::result::Result"))
- && (name == sym::map || name == sym::and_then);
+ let is_as_ref_able = match self_ty.peel_refs().kind() {
+ ty::Adt(def, _) => {
+ (self.tcx.is_diagnostic_item(sym::Option, def.did())
+ || self.tcx.is_diagnostic_item(sym::Result, def.did()))
+ && (name == sym::map || name == sym::and_then)
+ }
+ _ => false,
+ };
match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) {
(true, Ok(src)) => {
let suggestion = format!("as_ref().{}", src);
@@ -637,11 +639,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}?;
match hir.find(hir.get_parent_node(expr.hir_id))? {
- Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) => {
- for field in *fields {
- if field.ident.name == local.name && field.is_shorthand {
- return Some(local.name);
- }
+ Node::ExprField(field) => {
+ if field.ident.name == local.name && field.is_shorthand {
+ return Some(local.name);
}
}
_ => {}
@@ -767,22 +767,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
if self.can_coerce(ref_ty, expected) {
let mut sugg_sp = sp;
- if let hir::ExprKind::MethodCall(ref segment, ref args, _) = expr.kind {
+ if let hir::ExprKind::MethodCall(ref segment, receiver, args, _) = expr.kind {
let clone_trait =
self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span));
- if let ([arg], Some(true), sym::clone) = (
- &args[..],
- self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map(
+ if args.is_empty()
+ && self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map(
|did| {
let ai = self.tcx.associated_item(did);
ai.trait_container(self.tcx) == Some(clone_trait)
},
- ),
- segment.ident.name,
- ) {
+ ) == Some(true)
+ && segment.ident.name == sym::clone
+ {
// If this expression had a clone call when suggesting borrowing
// we want to suggest removing it because it'd now be unnecessary.
- sugg_sp = arg.span;
+ sugg_sp = receiver.span;
}
}
if let Ok(src) = sm.span_to_snippet(sugg_sp) {
@@ -793,7 +792,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ if is_range_literal(expr) => true,
_ => false,
};
- let sugg_expr = if needs_parens { format!("({src})") } else { src };
if let Some(sugg) = self.can_use_as_ref(expr) {
return Some((
@@ -821,6 +819,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ let sugg_expr = if needs_parens { format!("({src})") } else { src };
return Some(match mutability {
hir::Mutability::Mut => (
sp,
@@ -1072,21 +1071,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut sugg = vec![];
- if let Some(hir::Node::Expr(hir::Expr {
- kind: hir::ExprKind::Struct(_, fields, _), ..
- })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
+ if let Some(hir::Node::ExprField(field)) =
+ self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
{
// `expr` is a literal field for a struct, only suggest if appropriate
- match (*fields)
- .iter()
- .find(|field| field.expr.hir_id == expr.hir_id && field.is_shorthand)
- {
+ if field.is_shorthand {
// This is a field literal
- Some(field) => {
- sugg.push((field.ident.span.shrink_to_lo(), format!("{}: ", field.ident)));
- }
+ sugg.push((field.ident.span.shrink_to_lo(), format!("{}: ", field.ident)));
+ } else {
// Likely a field was meant, but this field wasn't found. Do not suggest anything.
- None => return false,
+ return false;
}
};
@@ -1418,25 +1412,4 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => false,
}
}
-
- // Report the type inferred by the return statement.
- fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) {
- if let Some(sp) = self.ret_coercion_span.get()
- // If the closure has an explicit return type annotation, or if
- // the closure's return type has been inferred from outside
- // requirements (such as an Fn* trait bound), then a type error
- // may occur at the first return expression we see in the closure
- // (if it conflicts with the declared return type). Skip adding a
- // note in this case, since it would be incorrect.
- && !self.return_type_pre_known
- {
- err.span_note(
- sp,
- &format!(
- "return type inferred to be `{}` here",
- self.resolve_vars_if_possible(expected)
- ),
- );
- }
- }
}
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index 321064ec0..ab143c059 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -144,6 +144,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
let assumptions_in_impl_context = assumptions_in_impl_context.predicates;
+ debug!(?assumptions_in_impl_context, ?dtor_predicates.predicates);
+
let self_param_env = tcx.param_env(self_type_did);
// An earlier version of this code attempted to do this checking
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 6e97b0bf2..93b008500 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -3,32 +3,28 @@
//! See `mod.rs` for more context on type checking in general.
use crate::astconv::AstConv as _;
-use crate::check::cast;
+use crate::check::cast::{self, CastCheckResult};
use crate::check::coercion::CoerceMany;
use crate::check::fatally_break_rust;
use crate::check::method::SelfSource;
-use crate::check::report_unexpected_variant_res;
-use crate::check::BreakableCtxt;
-use crate::check::Diverges;
-use crate::check::DynamicCoerceMany;
use crate::check::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
-use crate::check::FnCtxt;
-use crate::check::Needs;
-use crate::check::TupleArgumentsFlag::DontTupleArguments;
+use crate::check::{
+ report_unexpected_variant_res, BreakableCtxt, Diverges, DynamicCoerceMany, FnCtxt, Needs,
+ TupleArgumentsFlag::DontTupleArguments,
+};
use crate::errors::{
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
YieldExprOutsideOfGenerator,
};
use crate::type_error_struct;
-use super::suggest_call_constructor;
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
- EmissionGuarantee, ErrorGuaranteed,
+ ErrorGuaranteed, StashKey,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -44,13 +40,12 @@ use rustc_middle::middle::stability;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
use rustc_middle::ty::error::TypeError::FieldMisMatch;
use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TypeVisitable};
+use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitable};
use rustc_session::parse::feature_err;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Pos};
use rustc_target::spec::abi::Abi::RustIntrinsic;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode};
@@ -326,8 +321,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ExprKind::Block(body, _) => self.check_block_with_expected(&body, expected),
ExprKind::Call(callee, args) => self.check_call(expr, &callee, args, expected),
- ExprKind::MethodCall(segment, args, _) => {
- self.check_method_call(expr, segment, args, expected)
+ ExprKind::MethodCall(segment, receiver, args, _) => {
+ self.check_method_call(expr, segment, receiver, args, expected)
}
ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
ExprKind::Type(e, t) => {
@@ -880,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs: &'tcx hir::Expr<'tcx>,
err_code: &'static str,
op_span: Span,
- adjust_err: impl FnOnce(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>),
+ adjust_err: impl FnOnce(&mut Diagnostic),
) {
if lhs.is_syntactic_place_expr() {
return;
@@ -1002,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let else_ty = self.check_expr_with_expectation(else_expr, expected);
let else_diverges = self.diverges.get();
- let opt_suggest_box_span = self.opt_suggest_box_span(else_ty, orig_expected);
+ let opt_suggest_box_span = self.opt_suggest_box_span(then_ty, else_ty, orig_expected);
let if_cause = self.if_cause(
sp,
cond_expr.span,
@@ -1090,8 +1085,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
- let suggest_deref_binop = |err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
- rhs_ty: Ty<'tcx>| {
+ let suggest_deref_binop = |err: &mut Diagnostic, rhs_ty: Ty<'tcx>| {
if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
// Can only assign if the type is sized, so if `DerefMut` yields a type that is
// unsized, do not suggest dereferencing it.
@@ -1198,13 +1192,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr: &'tcx hir::Expr<'tcx>,
segment: &hir::PathSegment<'_>,
+ rcvr: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
- let rcvr = &args[0];
let rcvr_t = self.check_expr(&rcvr);
// no need to check for bot/err -- callee does that
- let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
+ let rcvr_t = self.structurally_resolved_type(rcvr.span, rcvr_t);
let span = segment.ident.span;
let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) {
@@ -1221,9 +1215,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
rcvr_t,
segment.ident,
- SelfSource::MethodCall(&args[0]),
+ SelfSource::MethodCall(rcvr),
error,
- Some(args),
+ Some((rcvr, args)),
) {
err.emit();
}
@@ -1233,14 +1227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// Call the generic checker.
- self.check_method_argument_types(
- span,
- expr,
- method,
- &args[1..],
- DontTupleArguments,
- expected,
- )
+ self.check_method_argument_types(span, expr, method, &args, DontTupleArguments, expected)
}
fn check_expr_cast(
@@ -1262,8 +1249,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
// Defer other checks until we're done type checking.
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
- match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
- Ok(cast_check) => {
+ match cast::check_cast(self, e, t_expr, t_cast, t.span, expr.span) {
+ CastCheckResult::Ok => t_cast,
+ CastCheckResult::Deferred(cast_check) => {
debug!(
"check_expr_cast: deferring cast from {:?} to {:?}: {:?}",
t_cast, t_expr, cast_check,
@@ -1271,7 +1259,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
deferred_cast_checks.push(cast_check);
t_cast
}
- Err(_) => self.tcx.ty_error(),
+ CastCheckResult::Err(ErrorGuaranteed { .. }) => self.tcx.ty_error(),
}
}
}
@@ -1309,7 +1297,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: expr.span,
})
};
- self.tcx.mk_array(element_ty, args.len() as u64)
+ let array_len = args.len() as u64;
+ self.suggest_array_len(expr, array_len);
+ self.tcx.mk_array(element_ty, array_len)
+ }
+
+ fn suggest_array_len(&self, expr: &'tcx hir::Expr<'tcx>, array_len: u64) {
+ let parent_node = self.tcx.hir().parent_iter(expr.hir_id).find(|(_, node)| {
+ !matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::AddrOf(..), .. }))
+ });
+ let Some((_,
+ hir::Node::Local(hir::Local { ty: Some(ty), .. })
+ | hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. }))
+ ) = parent_node else {
+ return
+ };
+ if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
+ && let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
+ && let Some(span) = self.tcx.hir().opt_span(hir_id)
+ {
+ match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
+ Some(mut err) => {
+ err.span_suggestion(
+ span,
+ "consider specifying the array length",
+ array_len,
+ Applicability::MaybeIncorrect,
+ );
+ err.emit();
+ }
+ None => ()
+ }
+ }
}
fn check_expr_const_block(
@@ -1335,10 +1354,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
element: &'tcx hir::Expr<'tcx>,
count: &'tcx hir::ArrayLen,
expected: Expectation<'tcx>,
- _expr: &'tcx hir::Expr<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let count = self.array_length_to_const(count);
+ if let Some(count) = count.try_eval_usize(tcx, self.param_env) {
+ self.suggest_array_len(expr, count);
+ }
let uty = match expected {
ExpectHasType(uty) => match *uty.kind() {
@@ -1518,7 +1540,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut error_happened = false;
// Type-check each field.
- for field in ast_fields {
+ for (idx, field) in ast_fields.iter().enumerate() {
let ident = tcx.adjust_ident(field.ident, variant.def_id);
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
seen_fields.insert(ident, field.span);
@@ -1556,7 +1578,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Make sure to give a type to the field even if there's
// an error, so we can continue type-checking.
- self.check_expr_coercable_to_type(&field.expr, field_type, None);
+ let ty = self.check_expr_with_hint(&field.expr, field_type);
+ let (_, diag) =
+ self.demand_coerce_diag(&field.expr, ty, field_type, None, AllowTwoPhase::No);
+
+ if let Some(mut diag) = diag {
+ if idx == ast_fields.len() - 1 && remaining_fields.is_empty() {
+ self.suggest_fru_from_range(field, variant, substs, &mut diag);
+ }
+ diag.emit();
+ }
}
// Make sure the programmer specified correct number of fields.
@@ -1695,9 +1726,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let private_fields: Vec<&ty::FieldDef> = variant
.fields
.iter()
- .filter(|field| {
- !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
- })
+ .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr_id), tcx))
.collect();
if !private_fields.is_empty() {
@@ -1784,25 +1813,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
- // If the last field is a range literal, but it isn't supposed to be, then they probably
- // meant to use functional update syntax.
- //
+ if let Some(last) = ast_fields.last() {
+ self.suggest_fru_from_range(last, variant, substs, &mut err);
+ }
+
+ err.emit();
+ }
+
+ /// If the last field is a range literal, but it isn't supposed to be, then they probably
+ /// meant to use functional update syntax.
+ fn suggest_fru_from_range(
+ &self,
+ last_expr_field: &hir::ExprField<'tcx>,
+ variant: &ty::VariantDef,
+ substs: SubstsRef<'tcx>,
+ err: &mut Diagnostic,
+ ) {
// I don't use 'is_range_literal' because only double-sided, half-open ranges count.
- if let Some((
- last,
- ExprKind::Struct(
+ if let ExprKind::Struct(
QPath::LangItem(LangItem::Range, ..),
&[ref range_start, ref range_end],
_,
- ),
- )) = ast_fields.last().map(|last| (last, &last.expr.kind)) &&
- let variant_field =
- variant.fields.iter().find(|field| field.ident(self.tcx) == last.ident) &&
- let range_def_id = self.tcx.lang_items().range_struct() &&
- variant_field
- .and_then(|field| field.ty(self.tcx, substs).ty_adt_def())
- .map(|adt| adt.did())
- != range_def_id
+ ) = last_expr_field.expr.kind
+ && let variant_field =
+ variant.fields.iter().find(|field| field.ident(self.tcx) == last_expr_field.ident)
+ && let range_def_id = self.tcx.lang_items().range_struct()
+ && variant_field
+ .and_then(|field| field.ty(self.tcx, substs).ty_adt_def())
+ .map(|adt| adt.did())
+ != range_def_id
{
let instead = self
.tcx
@@ -1818,8 +1857,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MaybeIncorrect,
);
}
-
- err.emit();
}
/// Report an error for a struct field expression when there are invisible fields.
@@ -2086,15 +2123,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field: Ident,
) -> Ty<'tcx> {
debug!("check_field(expr: {:?}, base: {:?}, field: {:?})", expr, base, field);
- let expr_t = self.check_expr(base);
- let expr_t = self.structurally_resolved_type(base.span, expr_t);
+ let base_ty = self.check_expr(base);
+ let base_ty = self.structurally_resolved_type(base.span, base_ty);
let mut private_candidate = None;
- let mut autoderef = self.autoderef(expr.span, expr_t);
- while let Some((base_t, _)) = autoderef.next() {
- debug!("base_t: {:?}", base_t);
- match base_t.kind() {
+ let mut autoderef = self.autoderef(expr.span, base_ty);
+ while let Some((deref_base_ty, _)) = autoderef.next() {
+ debug!("deref_base_ty: {:?}", deref_base_ty);
+ match deref_base_ty.kind() {
ty::Adt(base_def, substs) if !base_def.is_enum() => {
- debug!("struct named {:?}", base_t);
+ debug!("struct named {:?}", deref_base_ty);
let (ident, def_scope) =
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), self.body_id);
let fields = &base_def.non_enum_variant().fields;
@@ -2142,25 +2179,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// (#90483) apply adjustments to avoid ExprUseVisitor from
// creating erroneous projection.
self.apply_adjustments(base, adjustments);
- self.ban_private_field_access(expr, expr_t, field, did);
+ self.ban_private_field_access(expr, base_ty, field, did);
return field_ty;
}
if field.name == kw::Empty {
- } else if self.method_exists(field, expr_t, expr.hir_id, true) {
- self.ban_take_value_of_method(expr, expr_t, field);
- } else if !expr_t.is_primitive_ty() {
- self.ban_nonexisting_field(field, base, expr, expr_t);
+ } else if self.method_exists(field, base_ty, expr.hir_id, true) {
+ self.ban_take_value_of_method(expr, base_ty, field);
+ } else if !base_ty.is_primitive_ty() {
+ self.ban_nonexisting_field(field, base, expr, base_ty);
} else {
let field_name = field.to_string();
let mut err = type_error_struct!(
self.tcx().sess,
field.span,
- expr_t,
+ base_ty,
E0610,
- "`{expr_t}` is a primitive type and therefore doesn't have fields",
+ "`{base_ty}` is a primitive type and therefore doesn't have fields",
);
- let is_valid_suffix = |field: String| {
+ let is_valid_suffix = |field: &str| {
if field == "f32" || field == "f64" {
return true;
}
@@ -2185,20 +2222,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let suffix = chars.collect::<String>();
suffix.is_empty() || suffix == "f32" || suffix == "f64"
};
- if let ty::Infer(ty::IntVar(_)) = expr_t.kind()
+ let maybe_partial_suffix = |field: &str| -> Option<&str> {
+ let first_chars = ['f', 'l'];
+ if field.len() >= 1
+ && field.to_lowercase().starts_with(first_chars)
+ && field[1..].chars().all(|c| c.is_ascii_digit())
+ {
+ if field.to_lowercase().starts_with(['f']) { Some("f32") } else { Some("f64") }
+ } else {
+ None
+ }
+ };
+ if let ty::Infer(ty::IntVar(_)) = base_ty.kind()
&& let ExprKind::Lit(Spanned {
node: ast::LitKind::Int(_, ast::LitIntType::Unsuffixed),
..
}) = base.kind
&& !base.span.from_expansion()
- && is_valid_suffix(field_name)
{
- err.span_suggestion_verbose(
- field.span.shrink_to_lo(),
- "If the number is meant to be a floating point number, consider adding a `0` after the period",
- '0',
- Applicability::MaybeIncorrect,
- );
+ if is_valid_suffix(&field_name) {
+ err.span_suggestion_verbose(
+ field.span.shrink_to_lo(),
+ "if intended to be a floating point literal, consider adding a `0` after the period",
+ '0',
+ Applicability::MaybeIncorrect,
+ );
+ } else if let Some(correct_suffix) = maybe_partial_suffix(&field_name) {
+ err.span_suggestion_verbose(
+ field.span,
+ format!("if intended to be a floating point literal, consider adding a `0` after the period and a `{correct_suffix}` suffix"),
+ format!("0{correct_suffix}"),
+ Applicability::MaybeIncorrect,
+ );
+ }
}
err.emit();
}
@@ -2206,35 +2262,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx().ty_error()
}
- fn check_call_constructor<G: EmissionGuarantee>(
- &self,
- err: &mut DiagnosticBuilder<'_, G>,
- base: &'tcx hir::Expr<'tcx>,
- def_id: DefId,
- ) {
- if let Some(local_id) = def_id.as_local() {
- let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_id);
- let node = self.tcx.hir().get(hir_id);
-
- if let Some(fields) = node.tuple_fields() {
- let kind = match self.tcx.opt_def_kind(local_id) {
- Some(DefKind::Ctor(of, _)) => of,
- _ => return,
- };
-
- suggest_call_constructor(base.span, kind, fields.len(), err);
- }
- } else {
- // The logic here isn't smart but `associated_item_def_ids`
- // doesn't work nicely on local.
- if let DefKind::Ctor(of, _) = self.tcx.def_kind(def_id) {
- let parent_def_id = self.tcx.parent(def_id);
- let fields = self.tcx.associated_item_def_ids(parent_def_id);
- suggest_call_constructor(base.span, of, fields.len(), err);
- }
- }
- }
-
fn suggest_await_on_field_access(
&self,
err: &mut Diagnostic,
@@ -2277,40 +2304,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn ban_nonexisting_field(
&self,
- field: Ident,
+ ident: Ident,
base: &'tcx hir::Expr<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
- expr_t: Ty<'tcx>,
+ base_ty: Ty<'tcx>,
) {
debug!(
- "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, expr_ty={:?}",
- field, base, expr, expr_t
+ "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}",
+ ident, base, expr, base_ty
);
- let mut err = self.no_such_field_err(field, expr_t, base.hir_id);
+ let mut err = self.no_such_field_err(ident, base_ty, base.hir_id);
- match *expr_t.peel_refs().kind() {
+ match *base_ty.peel_refs().kind() {
ty::Array(_, len) => {
- self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
+ self.maybe_suggest_array_indexing(&mut err, expr, base, ident, len);
}
ty::RawPtr(..) => {
- self.suggest_first_deref_field(&mut err, expr, base, field);
+ self.suggest_first_deref_field(&mut err, expr, base, ident);
}
ty::Adt(def, _) if !def.is_enum() => {
- self.suggest_fields_on_recordish(&mut err, def, field, expr.span);
+ self.suggest_fields_on_recordish(&mut err, def, ident, expr.span);
}
ty::Param(param_ty) => {
self.point_at_param_definition(&mut err, param_ty);
}
ty::Opaque(_, _) => {
- self.suggest_await_on_field_access(&mut err, field, base, expr_t.peel_refs());
- }
- ty::FnDef(def_id, _) => {
- self.check_call_constructor(&mut err, base, def_id);
+ self.suggest_await_on_field_access(&mut err, ident, base, base_ty.peel_refs());
}
_ => {}
}
- if field.name == kw::Await {
+ self.suggest_fn_call(&mut err, base, base_ty, |output_ty| {
+ if let ty::Adt(def, _) = output_ty.kind() && !def.is_enum() {
+ def.non_enum_variant().fields.iter().any(|field| {
+ field.ident(self.tcx) == ident
+ && field.vis.is_accessible_from(expr.hir_id.owner, self.tcx)
+ })
+ } else if let ty::Tuple(tys) = output_ty.kind()
+ && let Ok(idx) = ident.as_str().parse::<usize>()
+ {
+ idx < tys.len()
+ } else {
+ false
+ }
+ });
+
+ if ident.name == kw::Await {
// We know by construction that `<expr>.await` is either on Rust 2015
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
@@ -2398,37 +2437,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr,
Some(span),
);
+ } else if let ty::RawPtr(ty_and_mut) = expr_t.kind()
+ && let ty::Adt(adt_def, _) = ty_and_mut.ty.kind()
+ && let ExprKind::Field(base_expr, _) = expr.kind
+ && adt_def.variants().len() == 1
+ && adt_def
+ .variants()
+ .iter()
+ .next()
+ .unwrap()
+ .fields
+ .iter()
+ .any(|f| f.ident(self.tcx) == field)
+ {
+ err.multipart_suggestion(
+ "to access the field, dereference first",
+ vec![
+ (base_expr.span.shrink_to_lo(), "(*".to_string()),
+ (base_expr.span.shrink_to_hi(), ")".to_string()),
+ ],
+ Applicability::MaybeIncorrect,
+ );
} else {
- let mut found = false;
-
- if let ty::RawPtr(ty_and_mut) = expr_t.kind()
- && let ty::Adt(adt_def, _) = ty_and_mut.ty.kind()
- {
- if adt_def.variants().len() == 1
- && adt_def
- .variants()
- .iter()
- .next()
- .unwrap()
- .fields
- .iter()
- .any(|f| f.ident(self.tcx) == field)
- {
- if let Some(dot_loc) = expr_snippet.rfind('.') {
- found = true;
- err.span_suggestion(
- expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
- "to access the field, dereference first",
- format!("(*{})", &expr_snippet[0..dot_loc]),
- Applicability::MaybeIncorrect,
- );
- }
- }
- }
-
- if !found {
- err.help("methods are immutable and cannot be assigned to");
- }
+ err.help("methods are immutable and cannot be assigned to");
}
err.emit();
@@ -2535,54 +2566,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
// try to add a suggestion in case the field is a nested field of a field of the Adt
- if let Some((fields, substs)) = self.get_field_candidates(span, expr_t) {
- for candidate_field in fields.iter() {
- if let Some(mut field_path) = self.check_for_nested_field_satisfying(
- span,
- &|candidate_field, _| candidate_field.ident(self.tcx()) == field,
- candidate_field,
- substs,
- vec![],
- self.tcx.parent_module(id).to_def_id(),
- ) {
- // field_path includes `field` that we're looking for, so pop it.
+ let mod_id = self.tcx.parent_module(id).to_def_id();
+ if let Some((fields, substs)) =
+ self.get_field_candidates_considering_privacy(span, expr_t, mod_id)
+ {
+ let candidate_fields: Vec<_> = fields
+ .filter_map(|candidate_field| {
+ self.check_for_nested_field_satisfying(
+ span,
+ &|candidate_field, _| candidate_field.ident(self.tcx()) == field,
+ candidate_field,
+ substs,
+ vec![],
+ mod_id,
+ )
+ })
+ .map(|mut field_path| {
field_path.pop();
-
- let field_path_str = field_path
+ field_path
.iter()
.map(|id| id.name.to_ident_string())
.collect::<Vec<String>>()
- .join(".");
- debug!("field_path_str: {:?}", field_path_str);
+ .join(".")
+ })
+ .collect::<Vec<_>>();
- err.span_suggestion_verbose(
- field.span.shrink_to_lo(),
- "one of the expressions' fields has a field of the same name",
- format!("{field_path_str}."),
- Applicability::MaybeIncorrect,
- );
- }
+ let len = candidate_fields.len();
+ if len > 0 {
+ err.span_suggestions(
+ field.span.shrink_to_lo(),
+ format!(
+ "{} of the expressions' fields {} a field of the same name",
+ if len > 1 { "some" } else { "one" },
+ if len > 1 { "have" } else { "has" },
+ ),
+ candidate_fields.iter().map(|path| format!("{path}.")),
+ Applicability::MaybeIncorrect,
+ );
}
}
err
}
- pub(crate) fn get_field_candidates(
+ pub(crate) fn get_field_candidates_considering_privacy(
&self,
span: Span,
- base_t: Ty<'tcx>,
- ) -> Option<(&[ty::FieldDef], SubstsRef<'tcx>)> {
- debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_t);
+ base_ty: Ty<'tcx>,
+ mod_id: DefId,
+ ) -> Option<(impl Iterator<Item = &'tcx ty::FieldDef> + 'tcx, SubstsRef<'tcx>)> {
+ debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_ty);
- for (base_t, _) in self.autoderef(span, base_t) {
+ for (base_t, _) in self.autoderef(span, base_ty) {
match base_t.kind() {
ty::Adt(base_def, substs) if !base_def.is_enum() => {
+ let tcx = self.tcx;
let fields = &base_def.non_enum_variant().fields;
- // For compile-time reasons put a limit on number of fields we search
- if fields.len() > 100 {
- return None;
+ // Some struct, e.g. some that impl `Deref`, have all private fields
+ // because you're expected to deref them to access the _real_ fields.
+ // This, for example, will help us suggest accessing a field through a `Box<T>`.
+ if fields.iter().all(|field| !field.vis.is_accessible_from(mod_id, tcx)) {
+ continue;
}
- return Some((fields, substs));
+ return Some((
+ fields
+ .iter()
+ .filter(move |field| field.vis.is_accessible_from(mod_id, tcx))
+ // For compile-time reasons put a limit on number of fields we search
+ .take(100),
+ substs,
+ ));
}
_ => {}
}
@@ -2599,7 +2651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
candidate_field: &ty::FieldDef,
subst: SubstsRef<'tcx>,
mut field_path: Vec<Ident>,
- id: DefId,
+ mod_id: DefId,
) -> Option<Vec<Ident>> {
debug!(
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
@@ -2611,24 +2663,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// up to a depth of three
None
} else {
- // recursively search fields of `candidate_field` if it's a ty::Adt
field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
let field_ty = candidate_field.ty(self.tcx, subst);
- if let Some((nested_fields, subst)) = self.get_field_candidates(span, field_ty) {
- for field in nested_fields.iter() {
- if field.vis.is_accessible_from(id, self.tcx) {
- if matches(candidate_field, field_ty) {
- return Some(field_path);
- } else if let Some(field_path) = self.check_for_nested_field_satisfying(
- span,
- matches,
- field,
- subst,
- field_path.clone(),
- id,
- ) {
- return Some(field_path);
- }
+ if matches(candidate_field, field_ty) {
+ return Some(field_path);
+ } else if let Some((nested_fields, subst)) =
+ self.get_field_candidates_considering_privacy(span, field_ty, mod_id)
+ {
+ // recursively search fields of `candidate_field` if it's a ty::Adt
+ for field in nested_fields {
+ if let Some(field_path) = self.check_for_nested_field_satisfying(
+ span,
+ matches,
+ field,
+ subst,
+ field_path.clone(),
+ mod_id,
+ ) {
+ return Some(field_path);
}
}
}
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 3a8093345..a40478db9 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.resolve_vars_with_obligations_and_mutate_fulfillment(ty, |_| {})
}
- #[instrument(skip(self, mutate_fulfillment_errors), level = "debug")]
+ #[instrument(skip(self, mutate_fulfillment_errors), level = "debug", ret)]
pub(in super::super) fn resolve_vars_with_obligations_and_mutate_fulfillment(
&self,
mut ty: Ty<'tcx>,
@@ -107,10 +107,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// indirect dependencies that don't seem worth tracking
// precisely.
self.select_obligations_where_possible(false, mutate_fulfillment_errors);
- ty = self.resolve_vars_if_possible(ty);
-
- debug!(?ty);
- ty
+ self.resolve_vars_if_possible(ty)
}
pub(in super::super) fn record_deferred_call_resolution(
@@ -412,7 +409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, ExprKind::Lit(_))),
- output_pred: None,
+ output_ty: None,
},
),
self.param_env,
@@ -498,13 +495,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn to_const(&self, ast_c: &hir::AnonConst) -> ty::Const<'tcx> {
let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
+ let span = self.tcx.hir().span(ast_c.hir_id);
let c = ty::Const::from_anon_const(self.tcx, const_def_id);
- self.register_wf_obligation(
- c.into(),
- self.tcx.hir().span(ast_c.hir_id),
- ObligationCauseCode::WellFormed(None),
- );
- c
+ self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None));
+ self.normalize_associated_types_in(span, c)
}
pub fn const_arg_to_const(
@@ -618,9 +612,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
pub(in super::super) fn select_all_obligations_or_error(&self) {
- let errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self);
+ let mut errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self);
if !errors.is_empty() {
+ self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
self.report_fulfillment_errors(&errors, self.inh.body_id, false);
}
}
@@ -634,6 +629,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
if !result.is_empty() {
mutate_fulfillment_errors(&mut result);
+ self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred);
}
}
@@ -831,23 +827,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = item_ty.subst(self.tcx, substs);
self.write_resolution(hir_id, Ok((def_kind, def_id)));
- self.add_required_obligations_with_code(
- span,
- def_id,
- &substs,
- match lang_item {
- hir::LangItem::IntoFutureIntoFuture => {
- ObligationCauseCode::AwaitableExpr(expr_hir_id)
- }
- hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
- ObligationCauseCode::ForLoopIterator
- }
- hir::LangItem::TryTraitFromOutput
- | hir::LangItem::TryTraitFromResidual
- | hir::LangItem::TryTraitBranch => ObligationCauseCode::QuestionMark,
- _ => traits::ItemObligation(def_id),
- },
- );
+
+ let code = match lang_item {
+ hir::LangItem::IntoFutureIntoFuture => {
+ Some(ObligationCauseCode::AwaitableExpr(expr_hir_id))
+ }
+ hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
+ Some(ObligationCauseCode::ForLoopIterator)
+ }
+ hir::LangItem::TryTraitFromOutput
+ | hir::LangItem::TryTraitFromResidual
+ | hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark),
+ _ => None,
+ };
+ if let Some(code) = code {
+ self.add_required_obligations_with_code(span, def_id, substs, move |_, _| code.clone());
+ } else {
+ self.add_required_obligations_for_hir(span, def_id, substs, hir_id);
+ }
+
(Res::Def(def_kind, def_id), ty)
}
@@ -986,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if found != self.tcx.types.unit {
return;
}
- if let ExprKind::MethodCall(path_segment, [rcvr, ..], _) = expr.kind {
+ if let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind {
if self
.typeck_results
.borrow()
@@ -1359,7 +1357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// First, store the "user substs" for later.
self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
- self.add_required_obligations(span, def_id, &substs);
+ self.add_required_obligations_for_hir(span, def_id, &substs, hir_id);
// Substitute the values for the type parameters into the type of
// the referenced item.
@@ -1396,32 +1394,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
/// Add all the obligations that are required, substituting and normalized appropriately.
- pub(crate) fn add_required_obligations(
+ pub(crate) fn add_required_obligations_for_hir(
&self,
span: Span,
def_id: DefId,
- substs: &SubstsRef<'tcx>,
+ substs: SubstsRef<'tcx>,
+ hir_id: hir::HirId,
) {
- self.add_required_obligations_with_code(
- span,
- def_id,
- substs,
- traits::ItemObligation(def_id),
- )
+ self.add_required_obligations_with_code(span, def_id, substs, |idx, span| {
+ if span.is_dummy() {
+ ObligationCauseCode::ExprItemObligation(def_id, hir_id, idx)
+ } else {
+ ObligationCauseCode::ExprBindingObligation(def_id, span, hir_id, idx)
+ }
+ })
}
- #[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
+ #[instrument(level = "debug", skip(self, code, span, def_id, substs))]
fn add_required_obligations_with_code(
&self,
span: Span,
def_id: DefId,
- substs: &SubstsRef<'tcx>,
- code: ObligationCauseCode<'tcx>,
+ substs: SubstsRef<'tcx>,
+ code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
) {
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
for obligation in traits::predicates_for_generics(
- traits::ObligationCause::new(span, self.body_id, code),
+ |idx, predicate_span| {
+ traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
+ },
self.param_env,
bounds,
) {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
index 7602f2550..fc83994ca 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
@@ -130,14 +130,17 @@ impl<'tcx> ArgMatrix<'tcx> {
let ai = &self.expected_indices;
let ii = &self.provided_indices;
+ // Issue: 100478, when we end the iteration,
+ // `next_unmatched_idx` will point to the index of the first unmatched
+ let mut next_unmatched_idx = 0;
for i in 0..cmp::max(ai.len(), ii.len()) {
- // If we eliminate the last row, any left-over inputs are considered missing
+ // If we eliminate the last row, any left-over arguments are considered missing
if i >= mat.len() {
- return Some(Issue::Missing(i));
+ return Some(Issue::Missing(next_unmatched_idx));
}
- // If we eliminate the last column, any left-over arguments are extra
+ // If we eliminate the last column, any left-over inputs are extra
if mat[i].len() == 0 {
- return Some(Issue::Extra(i));
+ return Some(Issue::Extra(next_unmatched_idx));
}
// Make sure we don't pass the bounds of our matrix
@@ -145,6 +148,7 @@ impl<'tcx> ArgMatrix<'tcx> {
let is_input = i < ii.len();
if is_arg && is_input && matches!(mat[i][i], Compatibility::Compatible) {
// This is a satisfied input, so move along
+ next_unmatched_idx += 1;
continue;
}
@@ -163,7 +167,7 @@ impl<'tcx> ArgMatrix<'tcx> {
if is_input {
for j in 0..ai.len() {
// If we find at least one argument that could satisfy this input
- // this argument isn't useless
+ // this input isn't useless
if matches!(mat[i][j], Compatibility::Compatible) {
useless = false;
break;
@@ -232,8 +236,8 @@ impl<'tcx> ArgMatrix<'tcx> {
if matches!(c, Compatibility::Compatible) { Some(i) } else { None }
})
.collect();
- if compat.len() != 1 {
- // this could go into multiple slots, don't bother exploring both
+ if compat.len() < 1 {
+ // try to find a cycle even when this could go into multiple slots, see #101097
is_cycle = false;
break;
}
@@ -309,7 +313,8 @@ impl<'tcx> ArgMatrix<'tcx> {
}
while !self.provided_indices.is_empty() || !self.expected_indices.is_empty() {
- match self.find_issue() {
+ let res = self.find_issue();
+ match res {
Some(Issue::Invalid(idx)) => {
let compatibility = self.compatibility_matrix[idx][idx].clone();
let input_idx = self.provided_indices[idx];
@@ -364,7 +369,9 @@ impl<'tcx> ArgMatrix<'tcx> {
None => {
// We didn't find any issues, so we need to push the algorithm forward
// First, eliminate any arguments that currently satisfy their inputs
- for (inp, arg) in self.eliminate_satisfied() {
+ let eliminated = self.eliminate_satisfied();
+ assert!(!eliminated.is_empty(), "didn't eliminated any indice in this round");
+ for (inp, arg) in eliminated {
matched_inputs[arg] = Some(inp);
}
}
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index 660e7e4e3..311fcaada 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -15,6 +15,7 @@ use crate::check::{
use crate::structured_errors::StructuredDiagnostic;
use rustc_ast as ast;
+use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -27,13 +28,14 @@ use rustc_infer::infer::InferOk;
use rustc_infer::infer::TypeTrace;
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty};
+use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor};
use rustc_session::Session;
use rustc_span::symbol::Ident;
-use rustc_span::{self, Span};
+use rustc_span::{self, sym, Span};
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
use std::iter;
+use std::ops::ControlFlow;
use std::slice;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -58,7 +60,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
for (asm, hir_id) in deferred_asm_checks.drain(..) {
let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
- InlineAsmCtxt::new_in_fn(self)
+ let get_operand_ty = |expr| {
+ let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
+ let ty = self.resolve_vars_if_possible(ty);
+ if ty.has_infer_types_or_consts() {
+ assert!(self.is_tainted_by_errors());
+ self.tcx.ty_error()
+ } else {
+ self.tcx.erase_regions(ty)
+ }
+ };
+ InlineAsmCtxt::new_in_fn(self.tcx, self.param_env, get_operand_ty)
.check_asm(asm, self.tcx.hir().local_def_id_to_hir_id(enclosing_id));
}
}
@@ -141,7 +153,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) {
let tcx = self.tcx;
- // Conceptually, we've got some number of expected inputs, and some number of provided aguments
+ // Conceptually, we've got some number of expected inputs, and some number of provided arguments
// and we can form a grid of whether each argument could satisfy a given input:
// in1 | in2 | in3 | ...
// arg1 ? | | |
@@ -212,6 +224,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let minimum_input_count = expected_input_tys.len();
let provided_arg_count = provided_args.len();
+ let is_const_eval_select = matches!(fn_def_id, Some(def_id) if
+ self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
+ && self.tcx.is_intrinsic(def_id)
+ && self.tcx.item_name(def_id) == sym::const_eval_select);
+
// We introduce a helper function to demand that a given argument satisfy a given input
// This is more complicated than just checking type equality, as arguments could be coerced
// This version writes those types back so further type checking uses the narrowed types
@@ -237,17 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Cause selection errors caused by resolving a single argument to point at the
// argument and not the call. This lets us customize the span pointed to in the
// fulfillment error to be more accurate.
- let coerced_ty =
- self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| {
- self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
- self.point_at_arg_instead_of_call_if_possible(
- errors,
- call_expr,
- call_span,
- provided_args,
- &expected_input_tys,
- );
- });
+ let coerced_ty = self.resolve_vars_with_obligations(coerced_ty);
let coerce_error = self
.try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
@@ -257,6 +264,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return Compatibility::Incompatible(coerce_error);
}
+ // Check that second and third argument of `const_eval_select` must be `FnDef`, and additionally that
+ // the second argument must be `const fn`. The first argument must be a tuple, but this is already expressed
+ // in the function signature (`F: FnOnce<ARG>`), so I did not bother to add another check here.
+ //
+ // This check is here because there is currently no way to express a trait bound for `FnDef` types only.
+ if is_const_eval_select && (1..=2).contains(&idx) {
+ if let ty::FnDef(def_id, _) = checked_ty.kind() {
+ if idx == 1 && !self.tcx.is_const_fn_raw(*def_id) {
+ self.tcx
+ .sess
+ .struct_span_err(provided_arg.span, "this argument must be a `const fn`")
+ .help("consult the documentation on `const_eval_select` for more information")
+ .emit();
+ }
+ } else {
+ self.tcx
+ .sess
+ .struct_span_err(provided_arg.span, "this argument must be a function item")
+ .note(format!("expected a function item, found {checked_ty}"))
+ .help(
+ "consult the documentation on `const_eval_select` for more information",
+ )
+ .emit();
+ }
+ }
+
// 3. Check if the formal type is a supertype of the checked one
// and register any such obligations for future type checks
let supertype_error = self
@@ -302,16 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// an "opportunistic" trait resolution of any trait bounds on
// the call. This helps coercions.
if check_closures {
- self.select_obligations_where_possible(false, |errors| {
- self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
- self.point_at_arg_instead_of_call_if_possible(
- errors,
- call_expr,
- call_span,
- &provided_args,
- &expected_input_tys,
- );
- })
+ self.select_obligations_where_possible(false, |_| {})
}
// Check each argument, to satisfy the input it was provided for
@@ -440,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call_expr: &hir::Expr<'tcx>,
) {
// Next, let's construct the error
- let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
+ let (error_span, full_call_span, ctor_of, is_method) = match &call_expr.kind {
hir::ExprKind::Call(
hir::Expr { hir_id, span, kind: hir::ExprKind::Path(qpath), .. },
_,
@@ -448,22 +472,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Res::Def(DefKind::Ctor(of, _), _) =
self.typeck_results.borrow().qpath_res(qpath, *hir_id)
{
- (call_span, *span, Some(of))
+ (call_span, *span, Some(of), false)
} else {
- (call_span, *span, None)
+ (call_span, *span, None, false)
}
}
- hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
- hir::ExprKind::MethodCall(path_segment, _, span) => {
+ hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
+ hir::ExprKind::MethodCall(path_segment, _, _, span) => {
let ident_span = path_segment.ident.span;
let ident_span = if let Some(args) = path_segment.args {
ident_span.with_hi(args.span_ext.hi())
} else {
ident_span
};
- (
- *span, ident_span, None, // methods are never ctors
- )
+ // methods are never ctors
+ (*span, ident_span, None, true)
}
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
};
@@ -507,13 +530,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect();
let callee_expr = match &call_expr.peel_blocks().kind {
hir::ExprKind::Call(callee, _) => Some(*callee),
- hir::ExprKind::MethodCall(_, callee, _) => {
+ hir::ExprKind::MethodCall(_, receiver, ..) => {
if let Some((DefKind::AssocFn, def_id)) =
self.typeck_results.borrow().type_dependent_def(call_expr.hir_id)
&& let Some(assoc) = tcx.opt_associated_item(def_id)
&& assoc.fn_has_self_parameter
{
- Some(&callee[0])
+ Some(*receiver)
} else {
None
}
@@ -545,7 +568,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
let can_coerce = self.can_coerce(arg_ty, coerced_ty);
if !can_coerce {
- return Compatibility::Incompatible(None);
+ return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
+ ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
+ )));
}
// Using probe here, since we don't want this subtyping to affect inference.
@@ -577,7 +602,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// First, check if we just need to wrap some arguments in a tuple.
if let Some((mismatch_idx, terr)) =
compatibility_diagonal.iter().enumerate().find_map(|(i, c)| {
- if let Compatibility::Incompatible(Some(terr)) = c { Some((i, terr)) } else { None }
+ if let Compatibility::Incompatible(Some(terr)) = c {
+ Some((i, *terr))
+ } else {
+ None
+ }
})
{
// Is the first bad expected argument a tuple?
@@ -659,7 +688,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MachineApplicable,
);
};
- self.label_fn_like(&mut err, fn_def_id, callee_ty);
+ self.label_fn_like(
+ &mut err,
+ fn_def_id,
+ callee_ty,
+ Some(mismatch_idx),
+ is_method,
+ );
err.emit();
return;
}
@@ -701,16 +736,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
errors.drain_filter(|error| {
- let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(error)) = error else { return false };
+ let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
- if let Some(e) = error {
- if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
- self.report_and_explain_type_error(trace, e).emit();
- return true;
- }
+ if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
+ self.report_and_explain_type_error(trace, *e).emit();
+ return true;
}
false
});
@@ -733,7 +766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
let cause = &self.misc(provided_arg_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
- let mut err = self.report_and_explain_type_error(trace, err);
+ let mut err = self.report_and_explain_type_error(trace, *err);
self.emit_coerce_suggestions(
&mut err,
&provided_args[*provided_idx],
@@ -749,7 +782,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("arguments to this {} are incorrect", call_name),
);
// Call out where the function is defined
- self.label_fn_like(&mut err, fn_def_id, callee_ty);
+ self.label_fn_like(
+ &mut err,
+ fn_def_id,
+ callee_ty,
+ Some(expected_idx.as_usize()),
+ is_method,
+ );
err.emit();
return;
}
@@ -797,7 +836,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Error::Invalid(provided_idx, expected_idx, compatibility) => {
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
let (provided_ty, provided_span) = provided_arg_tys[provided_idx];
- if let Compatibility::Incompatible(error) = &compatibility {
+ if let Compatibility::Incompatible(error) = compatibility {
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
if let Some(e) = error {
@@ -1031,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
// Call out where the function is defined
- self.label_fn_like(&mut err, fn_def_id, callee_ty);
+ self.label_fn_like(&mut err, fn_def_id, callee_ty, None, is_method);
// And add a suggestion block for all of the parameters
let suggestion_text = match suggestion_text {
@@ -1048,11 +1087,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
if let Some(suggestion_text) = suggestion_text {
let source_map = self.sess().source_map();
- let mut suggestion = format!(
- "{}(",
- source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| fn_def_id
- .map_or("".to_string(), |fn_def_id| tcx.item_name(fn_def_id).to_string()))
- );
+ let (mut suggestion, suggestion_span) =
+ if let Some(call_span) = full_call_span.find_ancestor_inside(error_span) {
+ ("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
+ } else {
+ (
+ format!(
+ "{}(",
+ source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
+ fn_def_id.map_or("".to_string(), |fn_def_id| {
+ tcx.item_name(fn_def_id).to_string()
+ })
+ })
+ ),
+ error_span,
+ )
+ };
let mut needs_comma = false;
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
if needs_comma {
@@ -1062,8 +1112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
let suggestion_text = if let Some(provided_idx) = provided_idx
&& let (_, provided_span) = provided_arg_tys[*provided_idx]
- && let Ok(arg_text) =
- source_map.span_to_snippet(provided_span)
+ && let Ok(arg_text) = source_map.span_to_snippet(provided_span)
{
arg_text
} else {
@@ -1081,7 +1130,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
suggestion += ")";
err.span_suggestion_verbose(
- error_span,
+ suggestion_span,
&suggestion_text,
suggestion,
Applicability::HasPlaceholders,
@@ -1129,7 +1178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
opt_ty.unwrap_or_else(|| self.next_float_var())
}
ast::LitKind::Bool(_) => tcx.types.bool,
- ast::LitKind::Err(_) => tcx.ty_error(),
+ ast::LitKind::Err => tcx.ty_error(),
}
}
@@ -1164,7 +1213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
// Check bounds on type arguments used in the path.
- self.add_required_obligations(path_span, did, substs);
+ self.add_required_obligations_for_hir(path_span, did, substs, hir_id);
Some((variant, ty))
} else {
@@ -1601,186 +1650,420 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
- /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
- /// reference a type argument. The reason to walk also the checked type is that the coerced type
- /// can be not easily comparable with predicate type (because of coercion). If the types match
- /// for either checked or coerced type, and there's only *one* argument that does, we point at
- /// the corresponding argument's expression span instead of the `fn` call path span.
- fn point_at_arg_instead_of_call_if_possible(
+ /// Given a vector of fulfillment errors, try to adjust the spans of the
+ /// errors to more accurately point at the cause of the failure.
+ ///
+ /// This applies to calls, methods, and struct expressions. This will also
+ /// try to deduplicate errors that are due to the same cause but might
+ /// have been created with different [`ObligationCause`][traits::ObligationCause]s.
+ pub(super) fn adjust_fulfillment_errors_for_expr_obligation(
&self,
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
- expr: &'tcx hir::Expr<'tcx>,
- call_sp: Span,
- args: &'tcx [hir::Expr<'tcx>],
- expected_tys: &[Ty<'tcx>],
) {
- // We *do not* do this for desugared call spans to keep good diagnostics when involving
- // the `?` operator.
- if call_sp.desugaring_kind().is_some() {
- return;
- }
-
- 'outer: for error in errors {
- // Only if the cause is somewhere inside the expression we want try to point at arg.
- // Otherwise, it means that the cause is somewhere else and we should not change
- // anything because we can break the correct span.
- if !call_sp.contains(error.obligation.cause.span) {
- continue;
+ // Store a mapping from `(Span, Predicate) -> ObligationCause`, so that
+ // other errors that have the same span and predicate can also get fixed,
+ // even if their `ObligationCauseCode` isn't an `Expr*Obligation` kind.
+ // This is important since if we adjust one span but not the other, then
+ // we will have "duplicated" the error on the UI side.
+ let mut remap_cause = FxHashSet::default();
+ let mut not_adjusted = vec![];
+
+ for error in errors {
+ let before_span = error.obligation.cause.span;
+ if self.adjust_fulfillment_error_for_expr_obligation(error)
+ || before_span != error.obligation.cause.span
+ {
+ // Store both the predicate and the predicate *without constness*
+ // since sometimes we instantiate and check both of these in a
+ // method call, for example.
+ remap_cause.insert((
+ before_span,
+ error.obligation.predicate,
+ error.obligation.cause.clone(),
+ ));
+ remap_cause.insert((
+ before_span,
+ error.obligation.predicate.without_const(self.tcx),
+ error.obligation.cause.clone(),
+ ));
+ } else {
+ // If it failed to be adjusted once around, it may be adjusted
+ // via the "remap cause" mapping the second time...
+ not_adjusted.push(error);
}
+ }
- // Peel derived obligation, because it's the type that originally
- // started this inference chain that matters, not the one we wound
- // up with at the end.
- fn unpeel_to_top<'a, 'tcx>(
- mut code: &'a ObligationCauseCode<'tcx>,
- ) -> &'a ObligationCauseCode<'tcx> {
- let mut result_code = code;
- loop {
- let parent = match code {
- ObligationCauseCode::ImplDerivedObligation(c) => &c.derived.parent_code,
- ObligationCauseCode::BuiltinDerivedObligation(c)
- | ObligationCauseCode::DerivedObligation(c) => &c.parent_code,
- _ => break result_code,
- };
- (result_code, code) = (code, parent);
+ for error in not_adjusted {
+ for (span, predicate, cause) in &remap_cause {
+ if *predicate == error.obligation.predicate
+ && span.contains(error.obligation.cause.span)
+ {
+ error.obligation.cause = cause.clone();
+ continue;
}
}
- let self_: ty::subst::GenericArg<'_> =
- match unpeel_to_top(error.obligation.cause.code()) {
- ObligationCauseCode::BuiltinDerivedObligation(code)
- | ObligationCauseCode::DerivedObligation(code) => {
- code.parent_trait_pred.self_ty().skip_binder().into()
+ }
+ }
+
+ fn adjust_fulfillment_error_for_expr_obligation(
+ &self,
+ error: &mut traits::FulfillmentError<'tcx>,
+ ) -> bool {
+ let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx))
+ = *error.obligation.cause.code().peel_derives() else { return false; };
+ let hir = self.tcx.hir();
+ let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; };
+
+ // Skip over mentioning async lang item
+ if Some(def_id) == self.tcx.lang_items().from_generator_fn()
+ && error.obligation.cause.span.desugaring_kind()
+ == Some(rustc_span::DesugaringKind::Async)
+ {
+ return false;
+ }
+
+ let Some(unsubstituted_pred) =
+ self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx)
+ else { return false; };
+
+ let generics = self.tcx.generics_of(def_id);
+ let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
+ ty::PredicateKind::Trait(pred) => pred.trait_ref.substs,
+ ty::PredicateKind::Projection(pred) => pred.projection_ty.substs,
+ _ => ty::List::empty(),
+ };
+
+ let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| {
+ predicate_substs.types().find_map(|ty| {
+ ty.walk().find_map(|arg| {
+ if let ty::GenericArgKind::Type(ty) = arg.unpack()
+ && let ty::Param(param_ty) = ty.kind()
+ && matches(param_ty)
+ {
+ Some(arg)
+ } else {
+ None
}
- ObligationCauseCode::ImplDerivedObligation(code) => {
- code.derived.parent_trait_pred.self_ty().skip_binder().into()
+ })
+ })
+ };
+
+ // Prefer generics that are local to the fn item, since these are likely
+ // to be the cause of the unsatisfied predicate.
+ let mut param_to_point_at = find_param_matching(&|param_ty| {
+ self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id
+ });
+ // Fall back to generic that isn't local to the fn item. This will come
+ // from a trait or impl, for example.
+ let mut fallback_param_to_point_at = find_param_matching(&|param_ty| {
+ self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id
+ && param_ty.name != rustc_span::symbol::kw::SelfUpper
+ });
+ // Finally, the `Self` parameter is possibly the reason that the predicate
+ // is unsatisfied. This is less likely to be true for methods, because
+ // method probe means that we already kinda check that the predicates due
+ // to the `Self` type are true.
+ let mut self_param_to_point_at =
+ find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper);
+
+ // Finally, for ambiguity-related errors, we actually want to look
+ // for a parameter that is the source of the inference type left
+ // over in this predicate.
+ if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code {
+ fallback_param_to_point_at = None;
+ self_param_to_point_at = None;
+ param_to_point_at =
+ self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
+ }
+
+ if self.closure_span_overlaps_error(error, expr.span) {
+ return false;
+ }
+
+ match &expr.kind {
+ hir::ExprKind::Path(qpath) => {
+ if let hir::Node::Expr(hir::Expr {
+ kind: hir::ExprKind::Call(callee, args),
+ hir_id: call_hir_id,
+ span: call_span,
+ ..
+ }) = hir.get(hir.get_parent_node(expr.hir_id))
+ && callee.hir_id == expr.hir_id
+ {
+ if self.closure_span_overlaps_error(error, *call_span) {
+ return false;
}
- _ if let ty::PredicateKind::Trait(predicate) =
- error.obligation.predicate.kind().skip_binder() =>
+
+ for param in
+ [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+ .into_iter()
+ .flatten()
{
- predicate.self_ty().into()
+ if self.point_at_arg_if_possible(
+ error,
+ def_id,
+ param,
+ *call_hir_id,
+ callee.span,
+ None,
+ args,
+ )
+ {
+ return true;
+ }
}
- _ => continue,
- };
- let self_ = self.resolve_vars_if_possible(self_);
- let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_);
-
- let typeck_results = self.typeck_results.borrow();
-
- for (idx, arg) in args.iter().enumerate() {
- // Don't adjust the span if we already have a more precise span
- // within one of the args.
- if arg.span.contains(error.obligation.cause.span) {
- let references_arg =
- typeck_results.expr_ty_opt(arg).map_or(false, &ty_matches_self)
- || expected_tys.get(idx).copied().map_or(false, &ty_matches_self);
- if references_arg && !arg.span.from_expansion() {
- error.obligation.cause.map_code(|parent_code| {
- ObligationCauseCode::FunctionArgumentObligation {
- arg_hir_id: args[idx].hir_id,
- call_hir_id: expr.hir_id,
- parent_code,
- }
- })
+ }
+ // Notably, we only point to params that are local to the
+ // item we're checking, since those are the ones we are able
+ // to look in the final `hir::PathSegment` for. Everything else
+ // would require a deeper search into the `qpath` than I think
+ // is worthwhile.
+ if let Some(param_to_point_at) = param_to_point_at
+ && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
+ {
+ return true;
+ }
+ }
+ hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
+ for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+ .into_iter()
+ .flatten()
+ {
+ if self.point_at_arg_if_possible(
+ error,
+ def_id,
+ param,
+ hir_id,
+ segment.ident.span,
+ Some(receiver),
+ args,
+ ) {
+ return true;
+ }
+ }
+ if let Some(param_to_point_at) = param_to_point_at
+ && self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment)
+ {
+ return true;
+ }
+ }
+ hir::ExprKind::Struct(qpath, fields, ..) => {
+ if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
+ self.typeck_results.borrow().qpath_res(qpath, hir_id)
+ {
+ for param in
+ [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+ {
+ if let Some(param) = param
+ && self.point_at_field_if_possible(
+ error,
+ def_id,
+ param,
+ variant_def_id,
+ fields,
+ )
+ {
+ return true;
+ }
}
- continue 'outer;
+ }
+ if let Some(param_to_point_at) = param_to_point_at
+ && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
+ {
+ return true;
}
}
+ _ => {}
+ }
- // Collect the argument position for all arguments that could have caused this
- // `FulfillmentError`.
- let mut referenced_in: Vec<_> = std::iter::zip(expected_tys, args)
- .enumerate()
- .flat_map(|(idx, (expected_ty, arg))| {
- if let Some(arg_ty) = typeck_results.expr_ty_opt(arg) {
- vec![(idx, arg_ty), (idx, *expected_ty)]
- } else {
- vec![]
- }
- })
- .filter_map(|(i, ty)| {
- let ty = self.resolve_vars_if_possible(ty);
- // We walk the argument type because the argument's type could have
- // been `Option<T>`, but the `FulfillmentError` references `T`.
- if ty_matches_self(ty) { Some(i) } else { None }
- })
- .collect();
+ false
+ }
+
+ fn closure_span_overlaps_error(
+ &self,
+ error: &traits::FulfillmentError<'tcx>,
+ span: Span,
+ ) -> bool {
+ if let traits::FulfillmentErrorCode::CodeSelectionError(
+ traits::SelectionError::OutputTypeParameterMismatch(_, expected, _),
+ ) = error.code
+ && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind()
+ && span.overlaps(self.tcx.def_span(*def_id))
+ {
+ true
+ } else {
+ false
+ }
+ }
+
+ fn point_at_arg_if_possible(
+ &self,
+ error: &mut traits::FulfillmentError<'tcx>,
+ def_id: DefId,
+ param_to_point_at: ty::GenericArg<'tcx>,
+ call_hir_id: hir::HirId,
+ callee_span: Span,
+ receiver: Option<&'tcx hir::Expr<'tcx>>,
+ args: &'tcx [hir::Expr<'tcx>],
+ ) -> bool {
+ let sig = self.tcx.fn_sig(def_id).skip_binder();
+ let args_referencing_param: Vec<_> = sig
+ .inputs()
+ .iter()
+ .enumerate()
+ .filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at))
+ .collect();
+ // If there's one field that references the given generic, great!
+ if let [(idx, _)] = args_referencing_param.as_slice()
+ && let Some(arg) = receiver
+ .map_or(args.get(*idx), |rcvr| if *idx == 0 { Some(rcvr) } else { args.get(*idx - 1) }) {
+ error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span);
+ error.obligation.cause.map_code(|parent_code| {
+ ObligationCauseCode::FunctionArgumentObligation {
+ arg_hir_id: arg.hir_id,
+ call_hir_id,
+ parent_code,
+ }
+ });
+ return true;
+ } else if args_referencing_param.len() > 0 {
+ // If more than one argument applies, then point to the callee span at least...
+ // We have chance to fix this up further in `point_at_generics_if_possible`
+ error.obligation.cause.span = callee_span;
+ }
- // Both checked and coerced types could have matched, thus we need to remove
- // duplicates.
+ false
+ }
- // We sort primitive type usize here and can use unstable sort
- referenced_in.sort_unstable();
- referenced_in.dedup();
+ fn point_at_field_if_possible(
+ &self,
+ error: &mut traits::FulfillmentError<'tcx>,
+ def_id: DefId,
+ param_to_point_at: ty::GenericArg<'tcx>,
+ variant_def_id: DefId,
+ expr_fields: &[hir::ExprField<'tcx>],
+ ) -> bool {
+ let def = self.tcx.adt_def(def_id);
+
+ let identity_substs = ty::InternalSubsts::identity_for_item(self.tcx, def_id);
+ let fields_referencing_param: Vec<_> = def
+ .variant_with_id(variant_def_id)
+ .fields
+ .iter()
+ .filter(|field| {
+ let field_ty = field.ty(self.tcx, identity_substs);
+ find_param_in_ty(field_ty, param_to_point_at)
+ })
+ .collect();
- if let &[idx] = &referenced_in[..] {
- // Do not point at the inside of a macro.
- // That would often result in poor error messages.
- if args[idx].span.from_expansion() {
- continue;
+ if let [field] = fields_referencing_param.as_slice() {
+ for expr_field in expr_fields {
+ // Look for the ExprField that matches the field, using the
+ // same rules that check_expr_struct uses for macro hygiene.
+ if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx)
+ {
+ error.obligation.cause.span = expr_field
+ .expr
+ .span
+ .find_ancestor_in_same_ctxt(error.obligation.cause.span)
+ .unwrap_or(expr_field.span);
+ return true;
}
- // We make sure that only *one* argument matches the obligation failure
- // and we assign the obligation's span to its expression's.
- error.obligation.cause.span = args[idx].span;
- error.obligation.cause.map_code(|parent_code| {
- ObligationCauseCode::FunctionArgumentObligation {
- arg_hir_id: args[idx].hir_id,
- call_hir_id: expr.hir_id,
- parent_code,
- }
- });
- } else if error.obligation.cause.span == call_sp {
- // Make function calls point at the callee, not the whole thing.
- if let hir::ExprKind::Call(callee, _) = expr.kind {
- error.obligation.cause.span = callee.span;
+ }
+ }
+
+ false
+ }
+
+ fn point_at_path_if_possible(
+ &self,
+ error: &mut traits::FulfillmentError<'tcx>,
+ def_id: DefId,
+ param: ty::GenericArg<'tcx>,
+ qpath: &QPath<'tcx>,
+ ) -> bool {
+ match qpath {
+ hir::QPath::Resolved(_, path) => {
+ if let Some(segment) = path.segments.last()
+ && self.point_at_generic_if_possible(error, def_id, param, segment)
+ {
+ return true;
}
}
+ hir::QPath::TypeRelative(_, segment) => {
+ if self.point_at_generic_if_possible(error, def_id, param, segment) {
+ return true;
+ }
+ }
+ _ => {}
}
+
+ false
}
- /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
- /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
- /// were caused by them. If they were, we point at the corresponding type argument's span
- /// instead of the `fn` call path span.
- fn point_at_type_arg_instead_of_call_if_possible(
+ fn point_at_generic_if_possible(
&self,
- errors: &mut Vec<traits::FulfillmentError<'tcx>>,
- call_expr: &'tcx hir::Expr<'tcx>,
- ) {
- if let hir::ExprKind::Call(path, _) = &call_expr.kind {
- if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind {
- for error in errors {
- if let ty::PredicateKind::Trait(predicate) =
- error.obligation.predicate.kind().skip_binder()
- {
- // If any of the type arguments in this path segment caused the
- // `FulfillmentError`, point at its span (#61860).
- for arg in path
- .segments
- .iter()
- .filter_map(|seg| seg.args.as_ref())
- .flat_map(|a| a.args.iter())
- {
- if let hir::GenericArg::Type(hir_ty) = &arg
- && let Some(ty) =
- self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
- && self.resolve_vars_if_possible(ty) == predicate.self_ty()
- {
- error.obligation.cause.span = hir_ty.span;
- break;
- }
- }
- }
+ error: &mut traits::FulfillmentError<'tcx>,
+ def_id: DefId,
+ param_to_point_at: ty::GenericArg<'tcx>,
+ segment: &hir::PathSegment<'tcx>,
+ ) -> bool {
+ let own_substs = self
+ .tcx
+ .generics_of(def_id)
+ .own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
+ let Some((index, _)) = own_substs
+ .iter()
+ .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
+ .enumerate()
+ .find(|(_, arg)| **arg == param_to_point_at) else { return false };
+ let Some(arg) = segment
+ .args()
+ .args
+ .iter()
+ .filter(|arg| matches!(arg, hir::GenericArg::Type(_)))
+ .nth(index) else { return false; };
+ error.obligation.cause.span = arg
+ .span()
+ .find_ancestor_in_same_ctxt(error.obligation.cause.span)
+ .unwrap_or(arg.span());
+ true
+ }
+
+ fn find_ambiguous_parameter_in<T: TypeVisitable<'tcx>>(
+ &self,
+ item_def_id: DefId,
+ t: T,
+ ) -> Option<ty::GenericArg<'tcx>> {
+ struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId);
+ impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> {
+ type BreakTy = ty::GenericArg<'tcx>;
+ fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
+ if let Some(origin) = self.0.type_var_origin(ty)
+ && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) =
+ origin.kind
+ && let generics = self.0.tcx.generics_of(self.1)
+ && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
+ && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1)
+ .get(index as usize)
+ {
+ ControlFlow::Break(*subst)
+ } else {
+ ty.super_visit_with(self)
}
}
}
+ t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value()
}
fn label_fn_like(
&self,
- err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
+ err: &mut Diagnostic,
callable_def_id: Option<DefId>,
callee_ty: Option<Ty<'tcx>>,
+ // A specific argument should be labeled, instead of all of them
+ expected_idx: Option<usize>,
+ is_method: bool,
) {
let Some(mut def_id) = callable_def_id else {
return;
@@ -1838,14 +2121,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let new_def_id = self.probe(|_| {
let trait_ref = ty::TraitRef::new(
call_kind.to_def_id(self.tcx),
- self.tcx.mk_substs([
- ty::GenericArg::from(callee_ty),
- self.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::MiscVariable,
- span: rustc_span::DUMMY_SP,
- })
- .into(),
- ].into_iter()),
+ self.tcx.mk_substs(
+ [
+ ty::GenericArg::from(callee_ty),
+ self.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span: rustc_span::DUMMY_SP,
+ })
+ .into(),
+ ]
+ .into_iter(),
+ ),
);
let obligation = traits::Obligation::new(
traits::ObligationCause::dummy(),
@@ -1860,7 +2146,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
Some(impl_source.impl_def_id)
}
- _ => None
+ _ => None,
}
});
if let Some(new_def_id) = new_def_id {
@@ -1881,14 +2167,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.get_if_local(def_id)
.and_then(|node| node.body_id())
.into_iter()
- .flat_map(|id| self.tcx.hir().body(id).params);
+ .flat_map(|id| self.tcx.hir().body(id).params)
+ .skip(if is_method { 1 } else { 0 });
- for param in params {
+ for (_, param) in params
+ .into_iter()
+ .enumerate()
+ .filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
+ {
spans.push_span_label(param.span, "");
}
let def_kind = self.tcx.def_kind(def_id);
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+ } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
+ && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
+ {
+ let param = expected_idx
+ .and_then(|expected_idx| self.tcx.hir().body(*body).params.get(expected_idx));
+ let (kind, span) = if let Some(param) = param {
+ ("closure parameter", param.span)
+ } else {
+ ("closure", self.tcx.def_span(def_id))
+ };
+ err.span_note(span, &format!("{} defined here", kind));
} else {
let def_kind = self.tcx.def_kind(def_id);
err.span_note(
@@ -1898,3 +2200,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
+
+fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>) -> bool {
+ let mut walk = ty.walk();
+ while let Some(arg) = walk.next() {
+ if arg == param_to_point_at {
+ return true;
+ } else if let ty::GenericArgKind::Type(ty) = arg.unpack()
+ && let ty::Projection(..) = ty.kind()
+ {
+ // This logic may seem a bit strange, but typically when
+ // we have a projection type in a function signature, the
+ // argument that's being passed into that signature is
+ // not actually constraining that projection's substs in
+ // a meaningful way. So we skip it, and see improvements
+ // in some UI tests.
+ walk.skip_current_subtree();
+ }
+ }
+ false
+}
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 05bcc710e..0e22971d3 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -26,6 +26,17 @@ use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
use std::cell::{Cell, RefCell};
use std::ops::Deref;
+/// The `FnCtxt` stores type-checking context needed to type-check bodies of
+/// functions, closures, and `const`s, including performing type inference
+/// with [`InferCtxt`].
+///
+/// This is in contrast to [`ItemCtxt`], which is used to type-check item *signatures*
+/// and thus does not perform type inference.
+///
+/// See [`ItemCtxt`]'s docs for more.
+///
+/// [`ItemCtxt`]: crate::collect::ItemCtxt
+/// [`InferCtxt`]: infer::InferCtxt
pub struct FnCtxt<'a, 'tcx> {
pub(super) body_id: hir::HirId,
@@ -57,8 +68,6 @@ pub struct FnCtxt<'a, 'tcx> {
/// any).
pub(super) ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
- pub(super) ret_type_span: Option<Span>,
-
/// Used exclusively to reduce cost of advanced evaluation used for
/// more helpful diagnostics.
pub(super) in_tail_expr: bool,
@@ -131,7 +140,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
param_env,
err_count_on_creation: inh.tcx.sess.err_count(),
ret_coercion: None,
- ret_type_span: None,
in_tail_expr: false,
ret_coercion_span: Cell::new(None),
resume_yield_tys: None,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 57771e096..ee0ad7b5d 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -2,6 +2,7 @@ use super::FnCtxt;
use crate::astconv::AstConv;
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
+use hir::def_id::DefId;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir as hir;
@@ -16,6 +17,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Binder, IsSuggestable, Subst, ToPredicate, Ty};
use rustc_span::symbol::sym;
use rustc_span::Span;
+use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -61,70 +63,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pointing_at_return_type
}
- /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
- /// the ctor would successfully solve the type mismatch and if so, suggest it:
+ /// When encountering an fn-like type, try accessing the output of the type
+ /// // and suggesting calling it if it satisfies a predicate (i.e. if the
+ /// output has a method or a field):
/// ```compile_fail,E0308
/// fn foo(x: usize) -> usize { x }
/// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
/// ```
- fn suggest_fn_call(
+ pub(crate) fn suggest_fn_call(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
- expected: Ty<'tcx>,
found: Ty<'tcx>,
+ can_satisfy: impl FnOnce(Ty<'tcx>) -> bool,
) -> bool {
- let (def_id, output, inputs) = match *found.kind() {
- ty::FnDef(def_id, _) => {
- let fn_sig = found.fn_sig(self.tcx);
- (def_id, fn_sig.output(), fn_sig.inputs().skip_binder().len())
- }
- ty::Closure(def_id, substs) => {
- let fn_sig = substs.as_closure().sig();
- (def_id, fn_sig.output(), fn_sig.inputs().skip_binder().len() - 1)
- }
- ty::Opaque(def_id, substs) => {
- let sig = self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
- if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
- && Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
- // args tuple will always be substs[1]
- && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
- {
- Some((
- pred.kind().rebind(proj.term.ty().unwrap()),
- args.len(),
- ))
- } else {
- None
- }
- });
- if let Some((output, inputs)) = sig {
- (def_id, output, inputs)
- } else {
- return false;
- }
- }
- _ => return false,
- };
-
- let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output);
- let output = self.normalize_associated_types_in(expr.span, output);
- if !output.is_ty_var() && self.can_coerce(output, expected) {
- let (sugg_call, mut applicability) = match inputs {
+ let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(expr, found)
+ else { return false; };
+ if can_satisfy(output) {
+ let (sugg_call, mut applicability) = match inputs.len() {
0 => ("".to_string(), Applicability::MachineApplicable),
1..=4 => (
- (0..inputs).map(|_| "_").collect::<Vec<_>>().join(", "),
- Applicability::MachineApplicable,
+ inputs
+ .iter()
+ .map(|ty| {
+ if ty.is_suggestable(self.tcx, false) {
+ format!("/* {ty} */")
+ } else {
+ "".to_string()
+ }
+ })
+ .collect::<Vec<_>>()
+ .join(", "),
+ Applicability::HasPlaceholders,
),
- _ => ("...".to_string(), Applicability::HasPlaceholders),
+ _ => ("/* ... */".to_string(), Applicability::HasPlaceholders),
};
- let msg = match self.tcx.def_kind(def_id) {
- DefKind::Fn => "call this function",
- DefKind::Closure | DefKind::OpaqueTy => "call this closure",
- DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct",
- DefKind::Ctor(CtorOf::Variant, _) => "instantiate this tuple variant",
- _ => "call this function",
+ let msg = match def_id_or_name {
+ DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
+ DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct".to_string(),
+ DefKind::Ctor(CtorOf::Variant, _) => {
+ "instantiate this tuple variant".to_string()
+ }
+ kind => format!("call this {}", kind.descr(def_id)),
+ },
+ DefIdOrName::Name(name) => format!("call this {name}"),
};
let sugg = match expr.kind {
@@ -161,6 +144,182 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}
+ /// Extracts information about a callable type for diagnostics. This is a
+ /// heuristic -- it doesn't necessarily mean that a type is always callable,
+ /// because the callable type must also be well-formed to be called.
+ pub(in super::super) fn extract_callable_info(
+ &self,
+ expr: &Expr<'_>,
+ found: Ty<'tcx>,
+ ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
+ // Autoderef is useful here because sometimes we box callables, etc.
+ let Some((def_id_or_name, output, inputs)) = self.autoderef(expr.span, found).silence_errors().find_map(|(found, _)| {
+ match *found.kind() {
+ ty::FnPtr(fn_sig) =>
+ Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs())),
+ ty::FnDef(def_id, _) => {
+ let fn_sig = found.fn_sig(self.tcx);
+ Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
+ }
+ ty::Closure(def_id, substs) => {
+ let fn_sig = substs.as_closure().sig();
+ Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..])))
+ }
+ ty::Opaque(def_id, substs) => {
+ self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
+ if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
+ && Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
+ // args tuple will always be substs[1]
+ && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
+ {
+ Some((
+ DefIdOrName::DefId(def_id),
+ pred.kind().rebind(proj.term.ty().unwrap()),
+ pred.kind().rebind(args.as_slice()),
+ ))
+ } else {
+ None
+ }
+ })
+ }
+ ty::Dynamic(data, _, ty::Dyn) => {
+ data.iter().find_map(|pred| {
+ if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
+ && Some(proj.item_def_id) == self.tcx.lang_items().fn_once_output()
+ // for existential projection, substs are shifted over by 1
+ && let ty::Tuple(args) = proj.substs.type_at(0).kind()
+ {
+ Some((
+ DefIdOrName::Name("trait object"),
+ pred.rebind(proj.term.ty().unwrap()),
+ pred.rebind(args.as_slice()),
+ ))
+ } else {
+ None
+ }
+ })
+ }
+ ty::Param(param) => {
+ let def_id = self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx).def_id;
+ self.tcx.predicates_of(self.body_id.owner).predicates.iter().find_map(|(pred, _)| {
+ if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
+ && Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
+ && proj.projection_ty.self_ty() == found
+ // args tuple will always be substs[1]
+ && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
+ {
+ Some((
+ DefIdOrName::DefId(def_id),
+ pred.kind().rebind(proj.term.ty().unwrap()),
+ pred.kind().rebind(args.as_slice()),
+ ))
+ } else {
+ None
+ }
+ })
+ }
+ _ => None,
+ }
+ }) else { return None; };
+
+ let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output);
+ let inputs = inputs
+ .skip_binder()
+ .iter()
+ .map(|ty| {
+ self.replace_bound_vars_with_fresh_vars(
+ expr.span,
+ infer::FnCall,
+ inputs.rebind(*ty),
+ )
+ })
+ .collect();
+
+ // We don't want to register any extra obligations, which should be
+ // implied by wf, but also because that would possibly result in
+ // erroneous errors later on.
+ let infer::InferOk { value: output, obligations: _ } =
+ self.normalize_associated_types_in_as_infer_ok(expr.span, output);
+
+ if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) }
+ }
+
+ pub fn suggest_two_fn_call(
+ &self,
+ err: &mut Diagnostic,
+ lhs_expr: &'tcx hir::Expr<'tcx>,
+ lhs_ty: Ty<'tcx>,
+ rhs_expr: &'tcx hir::Expr<'tcx>,
+ rhs_ty: Ty<'tcx>,
+ can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool,
+ ) -> bool {
+ let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
+ else { return false; };
+ let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
+ else { return false; };
+
+ if can_satisfy(lhs_output_ty, rhs_output_ty) {
+ let mut sugg = vec![];
+ let mut applicability = Applicability::MachineApplicable;
+
+ for (expr, inputs) in [(lhs_expr, lhs_inputs), (rhs_expr, rhs_inputs)] {
+ let (sugg_call, this_applicability) = match inputs.len() {
+ 0 => ("".to_string(), Applicability::MachineApplicable),
+ 1..=4 => (
+ inputs
+ .iter()
+ .map(|ty| {
+ if ty.is_suggestable(self.tcx, false) {
+ format!("/* {ty} */")
+ } else {
+ "/* value */".to_string()
+ }
+ })
+ .collect::<Vec<_>>()
+ .join(", "),
+ Applicability::HasPlaceholders,
+ ),
+ _ => ("/* ... */".to_string(), Applicability::HasPlaceholders),
+ };
+
+ applicability = applicability.max(this_applicability);
+
+ match expr.kind {
+ hir::ExprKind::Call(..)
+ | hir::ExprKind::Path(..)
+ | hir::ExprKind::Index(..)
+ | hir::ExprKind::Lit(..) => {
+ sugg.extend([(expr.span.shrink_to_hi(), format!("({sugg_call})"))]);
+ }
+ hir::ExprKind::Closure { .. } => {
+ // Might be `{ expr } || { bool }`
+ applicability = Applicability::MaybeIncorrect;
+ sugg.extend([
+ (expr.span.shrink_to_lo(), "(".to_string()),
+ (expr.span.shrink_to_hi(), format!(")({sugg_call})")),
+ ]);
+ }
+ _ => {
+ sugg.extend([
+ (expr.span.shrink_to_lo(), "(".to_string()),
+ (expr.span.shrink_to_hi(), format!(")({sugg_call})")),
+ ]);
+ }
+ }
+ }
+
+ err.multipart_suggestion_verbose(
+ format!("use parentheses to call these"),
+ sugg,
+ applicability,
+ );
+
+ true
+ } else {
+ false
+ }
+ }
+
pub fn suggest_deref_ref_or_into(
&self,
err: &mut Diagnostic,
@@ -178,12 +337,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
err.span_suggestion(sp, &msg, suggestion, applicability);
}
- } else if let (ty::FnDef(def_id, ..), true) =
- (&found.kind(), self.suggest_fn_call(err, expr, expected, found))
+ } else if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected))
+ && let ty::FnDef(def_id, ..) = &found.kind()
+ && let Some(sp) = self.tcx.hir().span_if_local(*def_id)
{
- if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
- err.span_label(sp, format!("{found} defined here"));
- }
+ err.span_label(sp, format!("{found} defined here"));
} else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
if !methods.is_empty() {
@@ -506,30 +664,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
// Only suggest changing the return type for methods that
// haven't set a return type at all (and aren't `fn main()` or an impl).
- match (
- &fn_decl.output,
- found.is_suggestable(self.tcx, false),
- can_suggest,
- expected.is_unit(),
- ) {
- (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
- err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found });
- true
- }
- (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
- // FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
- // that.
- err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span });
- true
- }
- (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
+ match &fn_decl.output {
+ &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() && !can_suggest => {
// `fn main()` must return `()`, do not suggest changing return type
err.subdiagnostic(ExpectedReturnTypeLabel::Unit { span });
- true
+ return true;
+ }
+ &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() => {
+ if found.is_suggestable(self.tcx, false) {
+ err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
+ return true;
+ } else if let ty::Closure(_, substs) = found.kind()
+ // FIXME(compiler-errors): Get better at printing binders...
+ && let closure = substs.as_closure()
+ && closure.sig().is_suggestable(self.tcx, false)
+ {
+ err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: closure.print_as_impl_trait().to_string() });
+ return true;
+ } else {
+ // FIXME: if `found` could be `impl Iterator` we should suggest that.
+ err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span });
+ return true
+ }
}
- // expectation was caused by something else, not the default return
- (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
- (&hir::FnRetTy::Return(ref ty), _, _, _) => {
+ &hir::FnRetTy::Return(ref ty) => {
// Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
@@ -546,9 +704,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.try_suggest_return_impl_trait(err, expected, ty, fn_id);
return true;
}
- false
}
+ _ => {}
}
+ false
}
/// check whether the return type is a generic type with a trait bound
@@ -770,6 +929,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ pub(crate) fn suggest_copied_or_cloned(
+ &self,
+ diag: &mut Diagnostic,
+ expr: &hir::Expr<'_>,
+ expr_ty: Ty<'tcx>,
+ expected_ty: Ty<'tcx>,
+ ) {
+ let ty::Adt(adt_def, substs) = expr_ty.kind() else { return; };
+ let ty::Adt(expected_adt_def, expected_substs) = expected_ty.kind() else { return; };
+ if adt_def != expected_adt_def {
+ return;
+ }
+
+ let mut suggest_copied_or_cloned = || {
+ let expr_inner_ty = substs.type_at(0);
+ let expected_inner_ty = expected_substs.type_at(0);
+ if let ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
+ && self.can_eq(self.param_env, *ty, expected_inner_ty).is_ok()
+ {
+ let def_path = self.tcx.def_path_str(adt_def.did());
+ if self.type_is_copy_modulo_regions(self.param_env, *ty, expr.span) {
+ diag.span_suggestion_verbose(
+ expr.span.shrink_to_hi(),
+ format!(
+ "use `{def_path}::copied` to copy the value inside the `{def_path}`"
+ ),
+ ".copied()",
+ Applicability::MachineApplicable,
+ );
+ } else if let Some(clone_did) = self.tcx.lang_items().clone_trait()
+ && rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
+ self,
+ self.param_env,
+ *ty,
+ clone_did,
+ expr.span
+ )
+ {
+ diag.span_suggestion_verbose(
+ expr.span.shrink_to_hi(),
+ format!(
+ "use `{def_path}::cloned` to clone the value inside the `{def_path}`"
+ ),
+ ".cloned()",
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+ };
+
+ if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result)
+ && adt_def.did() == result_did
+ // Check that the error types are equal
+ && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)).is_ok()
+ {
+ suggest_copied_or_cloned();
+ } else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option)
+ && adt_def.did() == option_did
+ {
+ suggest_copied_or_cloned();
+ }
+ }
+
/// Suggest wrapping the block in square brackets instead of curly braces
/// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`.
pub(crate) fn suggest_block_to_brackets(
@@ -830,7 +1052,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
found_ty: Ty<'tcx>,
expr: &hir::Expr<'_>,
) {
- let hir::ExprKind::MethodCall(segment, &[ref callee_expr], _) = expr.kind else { return; };
+ let hir::ExprKind::MethodCall(segment, callee_expr, &[], _) = expr.kind else { return; };
let Some(clone_trait_did) = self.tcx.lang_items().clone_trait() else { return; };
let ty::Ref(_, pointee_ty, _) = found_ty.kind() else { return };
let results = self.typeck_results.borrow();
@@ -910,3 +1132,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
+
+pub enum DefIdOrName {
+ DefId(DefId),
+ Name(&'static str),
+}
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index d4f800149..7ab6d9e2b 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -17,7 +17,6 @@ use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
use rustc_middle::ty::{self, RvalueScopes, Ty, TyCtxt, TypeVisitable};
use rustc_span::symbol::sym;
use rustc_span::Span;
-use tracing::debug;
mod drop_ranges;
@@ -409,8 +408,15 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
}) {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
} else {
- debug!("parent_node: {:?}", self.fcx.tcx.hir().find_parent_node(expr.hir_id));
- match self.fcx.tcx.hir().find_parent_node(expr.hir_id) {
+ let parent_expr = self
+ .fcx
+ .tcx
+ .hir()
+ .parent_iter(expr.hir_id)
+ .find(|(_, node)| matches!(node, hir::Node::Expr(_)))
+ .map(|(id, _)| id);
+ debug!("parent_expr: {:?}", parent_expr);
+ match parent_expr {
Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }),
None => {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
@@ -457,7 +463,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
}
#[derive(Default)]
-pub struct SuspendCheckData<'a, 'tcx> {
+struct SuspendCheckData<'a, 'tcx> {
expr: Option<&'tcx Expr<'tcx>>,
source_span: Span,
yield_span: Span,
@@ -472,7 +478,7 @@ pub struct SuspendCheckData<'a, 'tcx> {
//
// Note that this technique was chosen over things like a `Suspend` marker trait
// as it is simpler and has precedent in the compiler
-pub fn check_must_not_suspend_ty<'tcx>(
+fn check_must_not_suspend_ty<'tcx>(
fcx: &FnCtxt<'_, 'tcx>,
ty: Ty<'tcx>,
hir_id: HirId,
@@ -489,6 +495,8 @@ pub fn check_must_not_suspend_ty<'tcx>(
let plural_suffix = pluralize!(data.plural_len);
+ debug!("Checking must_not_suspend for {}", ty);
+
match *ty.kind() {
ty::Adt(..) if ty.is_box() => {
let boxed_ty = ty.boxed_ty();
@@ -519,7 +527,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
}
has_emitted
}
- ty::Dynamic(binder, _) => {
+ ty::Dynamic(binder, _, _) => {
let mut has_emitted = false;
for predicate in binder.iter() {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
@@ -580,6 +588,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
},
)
}
+ // If drop tracking is enabled, we want to look through references, since the referrent
+ // may not be considered live across the await point.
+ ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => {
+ let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
+ check_must_not_suspend_ty(fcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
+ }
_ => false,
}
}
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
index a2c23db16..016f4056b 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
@@ -256,6 +256,8 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
| hir::Node::TypeBinding(..)
| hir::Node::TraitRef(..)
| hir::Node::Pat(..)
+ | hir::Node::PatField(..)
+ | hir::Node::ExprField(..)
| hir::Node::Arm(..)
| hir::Node::Local(..)
| hir::Node::Ctor(..)
@@ -432,7 +434,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
self.handle_uninhabited_return(expr);
}
- ExprKind::MethodCall(_, exprs, _) => {
+ ExprKind::MethodCall(_, receiver, exprs, _) => {
+ self.visit_expr(receiver);
for expr in exprs {
self.visit_expr(expr);
}
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs
index ded0888c3..e22675e9d 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs
@@ -159,8 +159,8 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
bk: rustc_middle::ty::BorrowKind,
) {
debug!(
- "borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \
- borrow_kind={bk:?}"
+ "borrow: place_with_id = {place_with_id:#?}, diag_expr_id={diag_expr_id:#?}, \
+ borrow_kind={bk:#?}"
);
self.borrow_place(place_with_id);
diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs
index cd152eb97..37c830d4e 100644
--- a/compiler/rustc_typeck/src/check/inherited.rs
+++ b/compiler/rustc_typeck/src/check/inherited.rs
@@ -1,6 +1,7 @@
use super::callee::DeferredCallResolution;
use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::HirIdMap;
@@ -12,7 +13,9 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::LocalDefIdMap;
use rustc_span::{self, Span};
use rustc_trait_selection::infer::InferCtxtExt as _;
-use rustc_trait_selection::traits::{self, ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_trait_selection::traits::{
+ self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
+};
use std::cell::RefCell;
use std::ops::Deref;
@@ -37,6 +40,7 @@ pub struct Inherited<'a, 'tcx> {
// Some additional `Sized` obligations badly affect type inference.
// These obligations are added in a later stage of typeck.
+ // Removing these may also cause additional complications, see #101066.
pub(super) deferred_sized_obligations:
RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
@@ -89,7 +93,29 @@ impl<'tcx> Inherited<'_, 'tcx> {
infcx: tcx
.infer_ctxt()
.ignoring_regions()
- .with_fresh_in_progress_typeck_results(hir_owner),
+ .with_fresh_in_progress_typeck_results(hir_owner)
+ .with_normalize_fn_sig_for_diagnostic(Lrc::new(move |infcx, fn_sig| {
+ if fn_sig.has_escaping_bound_vars() {
+ return fn_sig;
+ }
+ infcx.probe(|_| {
+ let ocx = ObligationCtxt::new_in_snapshot(infcx);
+ let normalized_fn_sig = ocx.normalize(
+ ObligationCause::dummy(),
+ // FIXME(compiler-errors): This is probably not the right param-env...
+ infcx.tcx.param_env(def_id),
+ fn_sig,
+ );
+ if ocx.select_all_or_error().is_empty() {
+ let normalized_fn_sig =
+ infcx.resolve_vars_if_possible(normalized_fn_sig);
+ if !normalized_fn_sig.needs_infer() {
+ return normalized_fn_sig;
+ }
+ }
+ fn_sig
+ })
+ })),
def_id,
}
}
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index 3f2a0da8d..c7425ff78 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -69,6 +69,9 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
// to note that it's safe to call, since
// safe extern fns are otherwise unprecedented.
sym::abort
+ | sym::assert_inhabited
+ | sym::assert_zero_valid
+ | sym::assert_uninit_valid
| sym::size_of
| sym::min_align_of
| sym::needs_drop
@@ -92,8 +95,7 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
| sym::type_id
| sym::likely
| sym::unlikely
- | sym::ptr_guaranteed_eq
- | sym::ptr_guaranteed_ne
+ | sym::ptr_guaranteed_cmp
| sym::minnumf32
| sym::minnumf64
| sym::maxnumf32
@@ -102,7 +104,8 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
| sym::type_name
| sym::forget
| sym::black_box
- | sym::variant_count => hir::Unsafety::Normal,
+ | sym::variant_count
+ | sym::ptr_mask => hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
}
}
@@ -200,6 +203,15 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
),
+ sym::ptr_mask => (
+ 1,
+ vec![
+ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ tcx.types.usize,
+ ],
+ tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ ),
+
sym::copy | sym::copy_nonoverlapping => (
1,
vec![
@@ -289,8 +301,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
(1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool]))
}
- sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
- (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.bool)
+ sym::ptr_guaranteed_cmp => {
+ (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.u8)
}
sym::const_allocate => {
@@ -465,7 +477,11 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
sym::simd_scatter => (3, vec![param(0), param(1), param(2)], tcx.mk_unit()),
sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)),
- sym::simd_cast | sym::simd_as => (2, vec![param(0)], param(1)),
+ sym::simd_cast
+ | sym::simd_as
+ | sym::simd_cast_ptr
+ | sym::simd_expose_addr
+ | sym::simd_from_exposed_addr => (2, vec![param(0)], param(1)),
sym::simd_bitmask => (2, vec![param(0)], param(1)),
sym::simd_select | sym::simd_select_bitmask => {
(2, vec![param(0), param(1), param(1)], param(1))
diff --git a/compiler/rustc_typeck/src/check/intrinsicck.rs b/compiler/rustc_typeck/src/check/intrinsicck.rs
index df94abbaf..d8fe63dbf 100644
--- a/compiler/rustc_typeck/src/check/intrinsicck.rs
+++ b/compiler/rustc_typeck/src/check/intrinsicck.rs
@@ -9,7 +9,6 @@ use rustc_session::lint;
use rustc_span::{Span, Symbol, DUMMY_SP};
use rustc_target::abi::{Pointer, VariantIdx};
use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
-use rustc_trait_selection::infer::InferCtxtExt;
use super::FnCtxt;
@@ -98,12 +97,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
err.emit();
}
+}
+
+pub struct InlineAsmCtxt<'a, 'tcx> {
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
+}
+
+impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
+ pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
+ InlineAsmCtxt {
+ tcx,
+ param_env: ty::ParamEnv::empty(),
+ get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")),
+ }
+ }
+
+ pub fn new_in_fn(
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
+ ) -> Self {
+ InlineAsmCtxt { tcx, param_env, get_operand_ty: Box::new(get_operand_ty) }
+ }
// FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
// Type still may have region variables, but `Sized` does not depend
// on those, so just erase them before querying.
- if self.tcx.erase_regions(ty).is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
+ if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
return true;
}
if let ty::Foreign(..) = ty.kind() {
@@ -111,36 +134,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
false
}
-}
-
-pub struct InlineAsmCtxt<'a, 'tcx> {
- tcx: TyCtxt<'tcx>,
- fcx: Option<&'a FnCtxt<'a, 'tcx>>,
-}
-
-impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
- pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
- InlineAsmCtxt { tcx, fcx: None }
- }
-
- pub fn new_in_fn(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
- InlineAsmCtxt { tcx: fcx.tcx, fcx: Some(fcx) }
- }
fn check_asm_operand_type(
&self,
idx: usize,
reg: InlineAsmRegOrRegClass,
- expr: &hir::Expr<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
template: &[InlineAsmTemplatePiece],
is_input: bool,
- tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
+ tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>,
target_features: &FxHashSet<Symbol>,
) -> Option<InlineAsmType> {
- let fcx = self.fcx.unwrap_or_else(|| span_bug!(expr.span, "asm operand for global asm"));
- // Check the type against the allowed types for inline asm.
- let ty = fcx.typeck_results.borrow().expr_ty_adjusted(expr);
- let ty = fcx.resolve_vars_if_possible(ty);
+ let ty = (self.get_operand_ty)(expr);
+ if ty.has_infer_types_or_consts() {
+ bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
+ }
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
16 => InlineAsmType::I16,
32 => InlineAsmType::I32,
@@ -148,12 +156,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
_ => unreachable!(),
};
- // Expect types to be fully resolved, no const or type variables.
- if ty.has_infer_types_or_consts() {
- assert!(fcx.is_tainted_by_errors());
- return None;
- }
-
let asm_ty = match *ty.kind() {
// `!` is allowed for input but not for output (issue #87802)
ty::Never if is_input => return None,
@@ -167,7 +169,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
ty::FnPtr(_) => Some(asm_ty_isize),
- ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if fcx.is_thin_ptr_ty(ty) => {
+ ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
Some(asm_ty_isize)
}
ty::Adt(adt, substs) if adt.repr().simd() => {
@@ -219,7 +221,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
// Check that the type implements Copy. The only case where this can
// possibly fail is for SIMD types which don't #[derive(Copy)].
- if !fcx.infcx.type_is_copy_modulo_regions(fcx.param_env, ty, DUMMY_SP) {
+ if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) {
let msg = "arguments for inline assembly must be copyable";
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
err.note(&format!("`{ty}` does not implement the Copy trait"));
@@ -240,8 +242,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
let msg = "incompatible types for asm inout argument";
let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
- let in_expr_ty = fcx.typeck_results.borrow().expr_ty_adjusted(in_expr);
- let in_expr_ty = fcx.resolve_vars_if_possible(in_expr_ty);
+ let in_expr_ty = (self.get_operand_ty)(in_expr);
err.span_label(in_expr.span, &format!("type `{in_expr_ty}`"));
err.span_label(expr.span, &format!("type `{ty}`"));
err.note(
@@ -332,10 +333,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
let mut err = lint.build(msg);
err.span_label(expr.span, "for this argument");
err.help(&format!(
- "use the `{suggested_modifier}` modifier to have the register formatted as `{suggested_result}`",
+ "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`",
));
err.help(&format!(
- "or use the `{default_modifier}` modifier to keep the default formatting of `{default_result}`",
+ "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
));
err.emit();
},
diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index 2c89b63ae..59fd5c315 100644
--- a/compiler/rustc_typeck/src/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
@@ -491,7 +491,19 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// so we just call `predicates_for_generics` directly to avoid redoing work.
// `self.add_required_obligations(self.span, def_id, &all_substs);`
for obligation in traits::predicates_for_generics(
- traits::ObligationCause::new(self.span, self.body_id, traits::ItemObligation(def_id)),
+ |idx, span| {
+ let code = if span.is_dummy() {
+ ObligationCauseCode::ExprItemObligation(def_id, self.call_expr.hir_id, idx)
+ } else {
+ ObligationCauseCode::ExprBindingObligation(
+ def_id,
+ span,
+ self.call_expr.hir_id,
+ idx,
+ )
+ };
+ traits::ObligationCause::new(self.span, self.body_id, code)
+ },
self.param_env,
method_predicates,
) {
diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs
index 0e678c41f..249e9c66b 100644
--- a/compiler/rustc_typeck/src/check/method/mod.rs
+++ b/compiler/rustc_typeck/src/check/method/mod.rs
@@ -20,10 +20,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::{self, InferOk};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
-use rustc_middle::ty::{
- self, AssocKind, DefIdTree, GenericParamDefKind, ProjectionPredicate, ProjectionTy, Term,
- ToPredicate, Ty, TypeVisitable,
-};
+use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TypeVisitable};
use rustc_span::symbol::Ident;
use rustc_span::Span;
use rustc_trait_selection::traits;
@@ -168,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// * `call_expr`: the complete method call: (`foo.bar::<T1,...Tn>(...)`)
/// * `self_expr`: the self expression (`foo`)
/// * `args`: the expressions of the arguments (`a, b + 1, ...`)
- #[instrument(level = "debug", skip(self, call_expr, self_expr))]
+ #[instrument(level = "debug", skip(self))]
pub fn lookup_method(
&self,
self_ty: Ty<'tcx>,
@@ -178,11 +175,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_expr: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
- debug!(
- "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
- segment.ident, self_ty, call_expr, self_expr
- );
-
let pick =
self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?;
@@ -342,22 +334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Construct an obligation
let poly_trait_ref = ty::Binder::dummy(trait_ref);
- let opt_output_ty =
- expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
- let opt_output_assoc_item = self.tcx.associated_items(trait_def_id).find_by_name_and_kind(
- self.tcx,
- Ident::from_str("Output"),
- AssocKind::Type,
- trait_def_id,
- );
- let output_pred =
- opt_output_ty.zip(opt_output_assoc_item).map(|(output_ty, output_assoc_item)| {
- ty::Binder::dummy(ty::PredicateKind::Projection(ProjectionPredicate {
- projection_ty: ProjectionTy { substs, item_def_id: output_assoc_item.def_id },
- term: Term::Ty(output_ty),
- }))
- .to_predicate(self.tcx)
- });
+ let output_ty = expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
(
traits::Obligation::new(
@@ -368,7 +345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
- output_pred,
+ output_ty,
},
),
self.param_env,
@@ -383,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// In particular, it doesn't really do any probing: it simply constructs
/// an obligation for a particular trait with the given self type and checks
/// whether that trait is implemented.
- #[instrument(level = "debug", skip(self, span, opt_input_types))]
+ #[instrument(level = "debug", skip(self, span))]
pub(super) fn lookup_method_in_trait(
&self,
span: Span,
@@ -392,11 +369,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_ty: Ty<'tcx>,
opt_input_types: Option<&[Ty<'tcx>]>,
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
- debug!(
- "lookup_in_trait_adjusted(self_ty={:?}, m_name={}, trait_def_id={:?}, opt_input_types={:?})",
- self_ty, m_name, trait_def_id, opt_input_types
- );
-
let (obligation, substs) =
self.obligation_for_method(span, trait_def_id, self_ty, opt_input_types);
self.construct_obligation_for_trait(
@@ -528,13 +500,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
- output_pred: None,
+ output_ty: None,
},
)
} else {
traits::ObligationCause::misc(span, self.body_id)
};
- obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds));
+ let predicates_cause = cause.clone();
+ obligations.extend(traits::predicates_for_generics(
+ move |_, _| predicates_cause.clone(),
+ self.param_env,
+ bounds,
+ ));
// Also add an obligation for the method type being well-formed.
let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig));
@@ -571,7 +548,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// * `self_ty`: the type to search within (`Foo`)
/// * `self_ty_span` the span for the type being searched within (span of `Foo`)
/// * `expr_id`: the [`hir::HirId`] of the expression composing the entire call
- #[instrument(level = "debug", skip(self))]
+ #[instrument(level = "debug", skip(self), ret)]
pub fn resolve_fully_qualified_call(
&self,
span: Span,
@@ -580,11 +557,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_ty_span: Span,
expr_id: hir::HirId,
) -> Result<(DefKind, DefId), MethodError<'tcx>> {
- debug!(
- "resolve_fully_qualified_call: method_name={:?} self_ty={:?} expr_id={:?}",
- method_name, self_ty, expr_id,
- );
-
let tcx = self.tcx;
// Check if we have an enum variant.
@@ -628,21 +600,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&pick,
);
- debug!("resolve_fully_qualified_call: pick={:?}", pick);
+ debug!(?pick);
{
let mut typeck_results = self.typeck_results.borrow_mut();
let used_trait_imports = Lrc::get_mut(&mut typeck_results.used_trait_imports).unwrap();
for import_id in pick.import_ids {
- debug!("resolve_fully_qualified_call: used_trait_import: {:?}", import_id);
+ debug!(used_trait_import=?import_id);
used_trait_imports.insert(import_id);
}
}
let def_kind = pick.item.kind.as_def_kind();
- debug!(
- "resolve_fully_qualified_call: def_kind={:?}, def_id={:?}",
- def_kind, pick.item.def_id
- );
tcx.check_stability(pick.item.def_id, Some(expr_id), span, Some(method_name.span));
Ok((def_kind, pick.item.def_id))
}
diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs
index 7c68d9304..392695cca 100644
--- a/compiler/rustc_typeck/src/check/method/prelude2021.rs
+++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs
@@ -160,7 +160,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if precise {
let args = args
.iter()
- .skip(1)
.map(|arg| {
let span = arg.span.find_ancestor_inside(sp).unwrap_or_default();
format!(
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index efe15fec7..e9f55ab34 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -253,7 +253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// would result in an error (basically, the same criteria we
/// would use to decide if a method is a plausible fit for
/// ambiguity purposes).
- #[instrument(level = "debug", skip(self, scope_expr_id))]
+ #[instrument(level = "debug", skip(self))]
pub fn probe_for_return_type(
&self,
span: Span,
@@ -262,10 +262,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_ty: Ty<'tcx>,
scope_expr_id: hir::HirId,
) -> Vec<ty::AssocItem> {
- debug!(
- "probe(self_ty={:?}, return_type={}, scope_expr_id={})",
- self_ty, return_type, scope_expr_id
- );
let method_names = self
.probe_op(
span,
@@ -299,7 +295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect()
}
- #[instrument(level = "debug", skip(self, scope_expr_id))]
+ #[instrument(level = "debug", skip(self))]
pub fn probe_for_name(
&self,
span: Span,
@@ -310,10 +306,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
scope_expr_id: hir::HirId,
scope: ProbeScope,
) -> PickResult<'tcx> {
- debug!(
- "probe(self_ty={:?}, item_name={}, scope_expr_id={})",
- self_ty, item_name, scope_expr_id
- );
self.probe_op(
span,
mode,
@@ -1514,8 +1506,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds);
// Convert the bounds into obligations.
- let impl_obligations =
- traits::predicates_for_generics(cause, self.param_env, impl_bounds);
+ let impl_obligations = traits::predicates_for_generics(
+ move |_, _| cause.clone(),
+ self.param_env,
+ impl_bounds,
+ );
let candidate_obligations = impl_obligations
.chain(norm_obligations.into_iter())
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index c92b93cbc..2d459b2cc 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -16,8 +16,8 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_middle::traits::util::supertraits;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::with_crate_prefix;
-use rustc_middle::ty::ToPolyTraitRef;
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Symbol;
use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, Span};
@@ -30,8 +30,8 @@ use rustc_trait_selection::traits::{
use std::cmp::Ordering;
use std::iter;
-use super::probe::{Mode, ProbeScope};
-use super::{super::suggest_call_constructor, CandidateSource, MethodError, NoMatchData};
+use super::probe::{IsSuggestion, Mode, ProbeScope};
+use super::{CandidateSource, MethodError, NoMatchData};
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
@@ -95,7 +95,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_name: Ident,
source: SelfSource<'tcx>,
error: MethodError<'tcx>,
- args: Option<&'tcx [hir::Expr<'tcx>]>,
+ args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
// Avoid suggestions when we don't know what's going on.
if rcvr_ty.references_error() {
@@ -363,44 +363,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
- if self.is_fn_ty(rcvr_ty, span) {
- if let SelfSource::MethodCall(expr) = source {
- let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() {
- if let Some(local_id) = def_id.as_local() {
- let hir_id = tcx.hir().local_def_id_to_hir_id(local_id);
- let node = tcx.hir().get(hir_id);
- let fields = node.tuple_fields();
- if let Some(fields) = fields
- && let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) {
- Some((fields.len(), of))
- } else {
- None
- }
- } else {
- // The logic here isn't smart but `associated_item_def_ids`
- // doesn't work nicely on local.
- if let DefKind::Ctor(of, _) = tcx.def_kind(def_id) {
- let parent_def_id = tcx.parent(*def_id);
- Some((tcx.associated_item_def_ids(parent_def_id).len(), of))
- } else {
- None
- }
- }
- } else {
- None
- };
-
- // If the function is a tuple constructor, we recommend that they call it
- if let Some((fields, kind)) = suggest {
- suggest_call_constructor(expr.span, kind, fields, &mut err);
- } else {
- // General case
- err.span_label(
- expr.span,
- "this is a function, perhaps you wish to call it",
- );
- }
- }
+ if let SelfSource::MethodCall(rcvr_expr) = source {
+ self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
+ let call_expr = self
+ .tcx
+ .hir()
+ .expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id));
+ let probe = self.lookup_probe(
+ span,
+ item_name,
+ output_ty,
+ call_expr,
+ ProbeScope::AllTraits,
+ );
+ probe.is_ok()
+ });
}
let mut custom_span_label = false;
@@ -560,7 +537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bound_spans.push((self.tcx.def_span(def.did()), msg))
}
// Point at the trait object that couldn't satisfy the bound.
- ty::Dynamic(preds, _) => {
+ ty::Dynamic(preds, _, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => bound_spans
@@ -904,7 +881,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- let label_span_not_found = |err: &mut DiagnosticBuilder<'_, _>| {
+ let label_span_not_found = |err: &mut Diagnostic| {
if unsatisfied_predicates.is_empty() {
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
let is_string_or_ref_str = match actual.kind() {
@@ -1000,7 +977,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
label_span_not_found(&mut err);
}
- self.check_for_field_method(&mut err, source, span, actual, item_name);
+ // Don't suggest (for example) `expr.field.method()` if `expr.method()`
+ // doesn't exist due to unsatisfied predicates.
+ if unsatisfied_predicates.is_empty() {
+ self.check_for_field_method(&mut err, source, span, actual, item_name);
+ }
self.check_for_unwrap_self(&mut err, source, span, actual, item_name);
@@ -1017,7 +998,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
rcvr_ty,
item_name,
- args.map(|args| args.len()),
+ args.map(|(_, args)| args.len() + 1),
source,
out_of_scope_traits,
&unsatisfied_predicates,
@@ -1062,19 +1043,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// that had unsatisfied trait bounds
if unsatisfied_predicates.is_empty() {
let def_kind = lev_candidate.kind.as_def_kind();
- err.span_suggestion(
- span,
- &format!(
- "there is {} {} with a similar name",
- def_kind.article(),
- def_kind.descr(lev_candidate.def_id),
- ),
- lev_candidate.name,
- Applicability::MaybeIncorrect,
- );
+ // Methods are defined within the context of a struct and their first parameter is always self,
+ // which represents the instance of the struct the method is being called on
+ // Associated functions don’t take self as a parameter and
+ // they are not methods because they don’t have an instance of the struct to work with.
+ if def_kind == DefKind::AssocFn && lev_candidate.fn_has_self_parameter {
+ err.span_suggestion(
+ span,
+ &format!("there is a method with a similar name",),
+ lev_candidate.name,
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ err.span_suggestion(
+ span,
+ &format!(
+ "there is {} {} with a similar name",
+ def_kind.article(),
+ def_kind.descr(lev_candidate.def_id),
+ ),
+ lev_candidate.name,
+ Applicability::MaybeIncorrect,
+ );
+ }
}
}
+ self.check_for_deref_method(&mut err, source, rcvr_ty, item_name);
+
return Some(err);
}
@@ -1150,7 +1146,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>,
expr: &hir::Expr<'_>,
item_name: Ident,
- err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ err: &mut Diagnostic,
) -> bool {
let tcx = self.tcx;
let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
@@ -1165,7 +1161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => None,
});
if let Some((field, field_ty)) = field_receiver {
- let scope = tcx.parent_module(self.body_id).to_def_id();
+ let scope = tcx.parent_module(self.body_id);
let is_accessible = field.vis.is_accessible_from(scope, tcx);
if is_accessible {
@@ -1282,7 +1278,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// local binding
if let hir::def::Res::Local(hir_id) = path.res {
let span = tcx.hir().span(hir_id);
- let snippet = tcx.sess.source_map().span_to_snippet(span);
let filename = tcx.sess.source_map().span_to_filename(span);
let parent_node =
@@ -1292,7 +1287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
concrete_type,
);
- match (filename, parent_node, snippet) {
+ match (filename, parent_node) {
(
FileName::Real(_),
Node::Local(hir::Local {
@@ -1300,14 +1295,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty,
..
}),
- Ok(ref snippet),
) => {
+ let type_span = ty.map(|ty| ty.span.with_lo(span.hi())).unwrap_or(span.shrink_to_hi());
err.span_suggestion(
// account for `let x: _ = 42;`
- // ^^^^
- span.to(ty.as_ref().map(|ty| ty.span).unwrap_or(span)),
+ // ^^^
+ type_span,
&msg,
- format!("{}: {}", snippet, concrete_type),
+ format!(": {concrete_type}"),
Applicability::MaybeIncorrect,
);
}
@@ -1327,55 +1322,82 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn check_for_field_method(
&self,
- err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ err: &mut Diagnostic,
source: SelfSource<'tcx>,
span: Span,
actual: Ty<'tcx>,
item_name: Ident,
) {
if let SelfSource::MethodCall(expr) = source
- && let Some((fields, substs)) = self.get_field_candidates(span, actual)
+ && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id()
+ && let Some((fields, substs)) =
+ self.get_field_candidates_considering_privacy(span, actual, mod_id)
{
let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
- for candidate_field in fields.iter() {
- if let Some(field_path) = self.check_for_nested_field_satisfying(
- span,
- &|_, field_ty| {
- self.lookup_probe(
- span,
- item_name,
- field_ty,
- call_expr,
- ProbeScope::AllTraits,
- )
- .is_ok()
- },
- candidate_field,
- substs,
- vec![],
- self.tcx.parent_module(expr.hir_id).to_def_id(),
- ) {
- let field_path_str = field_path
+
+ let lang_items = self.tcx.lang_items();
+ let never_mention_traits = [
+ lang_items.clone_trait(),
+ lang_items.deref_trait(),
+ lang_items.deref_mut_trait(),
+ self.tcx.get_diagnostic_item(sym::AsRef),
+ self.tcx.get_diagnostic_item(sym::AsMut),
+ self.tcx.get_diagnostic_item(sym::Borrow),
+ self.tcx.get_diagnostic_item(sym::BorrowMut),
+ ];
+ let candidate_fields: Vec<_> = fields
+ .filter_map(|candidate_field| {
+ self.check_for_nested_field_satisfying(
+ span,
+ &|_, field_ty| {
+ self.lookup_probe(
+ span,
+ item_name,
+ field_ty,
+ call_expr,
+ ProbeScope::TraitsInScope,
+ )
+ .map_or(false, |pick| {
+ !never_mention_traits
+ .iter()
+ .flatten()
+ .any(|def_id| self.tcx.parent(pick.item.def_id) == *def_id)
+ })
+ },
+ candidate_field,
+ substs,
+ vec![],
+ mod_id,
+ )
+ })
+ .map(|field_path| {
+ field_path
.iter()
.map(|id| id.name.to_ident_string())
.collect::<Vec<String>>()
- .join(".");
- debug!("field_path_str: {:?}", field_path_str);
-
- err.span_suggestion_verbose(
- item_name.span.shrink_to_lo(),
- "one of the expressions' fields has a method of the same name",
- format!("{field_path_str}."),
- Applicability::MaybeIncorrect,
- );
- }
+ .join(".")
+ })
+ .collect();
+
+ let len = candidate_fields.len();
+ if len > 0 {
+ err.span_suggestions(
+ item_name.span.shrink_to_lo(),
+ format!(
+ "{} of the expressions' fields {} a method of the same name",
+ if len > 1 { "some" } else { "one" },
+ if len > 1 { "have" } else { "has" },
+ ),
+ candidate_fields.iter().map(|path| format!("{path}.")),
+ Applicability::MaybeIncorrect,
+ );
}
}
}
fn check_for_unwrap_self(
&self,
- err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ err: &mut Diagnostic,
source: SelfSource<'tcx>,
span: Span,
actual: Ty<'tcx>,
@@ -1631,6 +1653,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ fn check_for_deref_method(
+ &self,
+ err: &mut Diagnostic,
+ self_source: SelfSource<'tcx>,
+ rcvr_ty: Ty<'tcx>,
+ item_name: Ident,
+ ) {
+ let SelfSource::QPath(ty) = self_source else { return; };
+ for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) {
+ if let Ok(pick) = self.probe_for_name(
+ ty.span,
+ Mode::Path,
+ item_name,
+ IsSuggestion(true),
+ deref_ty,
+ ty.hir_id,
+ ProbeScope::TraitsInScope,
+ ) {
+ if deref_ty.is_suggestable(self.tcx, true)
+ // If this method receives `&self`, then the provided
+ // argument _should_ coerce, so it's valid to suggest
+ // just changing the path.
+ && pick.item.fn_has_self_parameter
+ && let Some(self_ty) =
+ self.tcx.fn_sig(pick.item.def_id).inputs().skip_binder().get(0)
+ && self_ty.is_ref()
+ {
+ let suggested_path = match deref_ty.kind() {
+ ty::Bool
+ | ty::Char
+ | ty::Int(_)
+ | ty::Uint(_)
+ | ty::Float(_)
+ | ty::Adt(_, _)
+ | ty::Str
+ | ty::Projection(_)
+ | ty::Param(_) => format!("{deref_ty}"),
+ _ => format!("<{deref_ty}>"),
+ };
+ err.span_suggestion_verbose(
+ ty.span,
+ format!("the function `{item_name}` is implemented on `{deref_ty}`"),
+ suggested_path,
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ err.span_note(
+ ty.span,
+ format!("the function `{item_name}` is implemented on `{deref_ty}`"),
+ );
+ }
+ return;
+ }
+ }
+ }
+
/// Print out the type for use in value namespace.
fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
match ty.kind() {
@@ -2232,7 +2310,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
fn print_disambiguation_help<'tcx>(
item_name: Ident,
- args: Option<&'tcx [hir::Expr<'tcx>]>,
+ args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
err: &mut Diagnostic,
trait_name: String,
rcvr_ty: Ty<'_>,
@@ -2244,7 +2322,7 @@ fn print_disambiguation_help<'tcx>(
fn_has_self_parameter: bool,
) {
let mut applicability = Applicability::MachineApplicable;
- let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
+ let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
let args = format!(
"({}{})",
if rcvr_ty.is_region_ptr() {
@@ -2252,7 +2330,8 @@ fn print_disambiguation_help<'tcx>(
} else {
""
},
- args.iter()
+ std::iter::once(receiver)
+ .chain(args.iter())
.map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
applicability = Applicability::HasPlaceholders;
"_".to_owned()
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 17c2e4868..cfae63e4a 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -87,7 +87,6 @@ mod op;
mod pat;
mod place_op;
mod region;
-pub mod regionck;
pub mod rvalue_scopes;
mod upvar;
pub mod wfcheck;
@@ -97,14 +96,13 @@ use check::{check_abi, check_fn, check_mod_item_types};
pub use diverges::Diverges;
pub use expectation::Expectation;
pub use fn_ctxt::*;
-use hir::def::CtorOf;
pub use inherited::{Inherited, InheritedBuilder};
use crate::astconv::AstConv;
use crate::check::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
- pluralize, struct_span_err, Applicability, DiagnosticBuilder, EmissionGuarantee, MultiSpan,
+ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::Res;
@@ -112,7 +110,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{HirIdMap, ImplicitSelfKind, Node};
use rustc_index::bit_set::BitSet;
-use rustc_index::vec::Idx;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
@@ -122,18 +119,20 @@ use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, Ident};
-use rustc_span::{self, BytePos, Span};
+use rustc_span::{self, BytePos, Span, Symbol};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits;
use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
use std::cell::RefCell;
+use std::num::NonZeroU32;
use crate::require_c_abi_if_c_variadic;
use crate::util::common::indenter;
use self::coercion::DynamicCoerceMany;
+use self::compare_method::collect_trait_impl_trait_tys;
use self::region::region_scope_tree;
pub use self::Expectation::*;
@@ -251,6 +250,7 @@ pub fn provide(providers: &mut Providers) {
used_trait_imports,
check_mod_item_types,
region_scope_tree,
+ collect_trait_impl_trait_tys,
..*providers
};
}
@@ -343,7 +343,6 @@ fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::T
typeck_with_fallback(tcx, def_id, fallback)
}
-#[instrument(skip(tcx, fallback))]
fn typeck_with_fallback<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
@@ -548,13 +547,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
// For the wasm32 target statics with `#[link_section]` are placed into custom
// sections of the final output file, but this isn't link custom sections of
// other executable formats. Namely we can only embed a list of bytes,
- // nothing with pointers to anything else or relocations. If any relocation
- // show up, reject them here.
+ // nothing with provenance (pointers to anything else). If any provenance
+ // show up, reject it here.
// `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
// the consumer's responsibility to ensure all bytes that have been read
// have defined values.
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
- && alloc.inner().relocations().len() != 0
+ && alloc.inner().provenance().len() != 0
{
let msg = "statics with a custom `#[link_section]` must be a \
simple list of bytes on the wasm target with no \
@@ -662,6 +661,37 @@ fn missing_items_must_implement_one_of_err(
err.emit();
}
+fn default_body_is_unstable(
+ tcx: TyCtxt<'_>,
+ impl_span: Span,
+ item_did: DefId,
+ feature: Symbol,
+ reason: Option<Symbol>,
+ issue: Option<NonZeroU32>,
+) {
+ let missing_item_name = &tcx.associated_item(item_did).name;
+ let use_of_unstable_library_feature_note = match reason {
+ Some(r) => format!("use of unstable library feature '{feature}': {r}"),
+ None => format!("use of unstable library feature '{feature}'"),
+ };
+
+ let mut err = struct_span_err!(
+ tcx.sess,
+ impl_span,
+ E0046,
+ "not all trait items implemented, missing: `{missing_item_name}`",
+ );
+ err.note(format!("default implementation of `{missing_item_name}` is unstable"));
+ err.note(use_of_unstable_library_feature_note);
+ rustc_session::parse::add_feature_diagnostics_for_issue(
+ &mut err,
+ &tcx.sess.parse_sess,
+ feature,
+ rustc_feature::GateIssue::Library(issue),
+ );
+ err.emit();
+}
+
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
fn bounds_from_generic_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
@@ -935,36 +965,3 @@ fn has_expected_num_generic_args<'tcx>(
generics.count() == expected + if generics.has_self { 1 } else { 0 }
})
}
-
-/// Suggests calling the constructor of a tuple struct or enum variant
-///
-/// * `snippet` - The snippet of code that references the constructor
-/// * `span` - The span of the snippet
-/// * `params` - The number of parameters the constructor accepts
-/// * `err` - A mutable diagnostic builder to add the suggestion to
-fn suggest_call_constructor<G: EmissionGuarantee>(
- span: Span,
- kind: CtorOf,
- params: usize,
- err: &mut DiagnosticBuilder<'_, G>,
-) {
- // Note: tuple-structs don't have named fields, so just use placeholders
- let args = vec!["_"; params].join(", ");
- let applicable = if params > 0 {
- Applicability::HasPlaceholders
- } else {
- // When n = 0, it's an empty-tuple struct/enum variant
- // so we trivially know how to construct it
- Applicability::MachineApplicable
- };
- let kind = match kind {
- CtorOf::Struct => "a struct",
- CtorOf::Variant => "an enum variant",
- };
- err.span_label(span, &format!("this is the constructor of {kind}"));
- err.multipart_suggestion(
- "call the constructor",
- vec![(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), format!(")({args})"))],
- applicable,
- );
-}
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index 920b3e688..4754717c2 100644
--- a/compiler/rustc_typeck/src/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
@@ -11,9 +11,8 @@ use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
};
-use rustc_middle::ty::{
- self, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
-};
+use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
@@ -22,8 +21,6 @@ use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt as
use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt};
use rustc_type_ir::sty::TyKind::*;
-use std::ops::ControlFlow;
-
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Checks a `a <op>= b`
pub fn check_binop_assign(
@@ -57,9 +54,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)
.is_ok()
{
- // Suppress this error, since we already emitted
- // a deref suggestion in check_overloaded_binop
- err.delay_as_bug();
+ // If LHS += RHS is an error, but *LHS += RHS is successful, then we will have
+ // emitted a better suggestion during error handling in check_overloaded_binop.
+ if self
+ .lookup_op_method(
+ lhs_ty,
+ Some(rhs_ty),
+ Some(rhs),
+ Op::Binary(op, IsAssign::Yes),
+ expected,
+ )
+ .is_err()
+ {
+ err.downgrade_to_delayed_bug();
+ } else {
+ // Otherwise, it's valid to suggest dereferencing the LHS here.
+ err.span_suggestion_verbose(
+ lhs.span.shrink_to_lo(),
+ "consider dereferencing the left-hand side of this operation",
+ "*",
+ Applicability::MaybeIncorrect,
+ );
+ }
}
}
});
@@ -294,8 +310,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// error types are considered "builtin"
Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(),
Err(errors) => {
- let source_map = self.tcx.sess.source_map();
- let (mut err, missing_trait, use_output) = match is_assign {
+ let (_, trait_def_id) =
+ lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
+ let missing_trait = trait_def_id
+ .map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
+ let (mut err, output_def_id) = match is_assign {
IsAssign::Yes => {
let mut err = struct_span_err!(
self.tcx.sess,
@@ -309,130 +328,63 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs_expr.span,
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
);
- let missing_trait = match op.node {
- hir::BinOpKind::Add => Some("std::ops::AddAssign"),
- hir::BinOpKind::Sub => Some("std::ops::SubAssign"),
- hir::BinOpKind::Mul => Some("std::ops::MulAssign"),
- hir::BinOpKind::Div => Some("std::ops::DivAssign"),
- hir::BinOpKind::Rem => Some("std::ops::RemAssign"),
- hir::BinOpKind::BitAnd => Some("std::ops::BitAndAssign"),
- hir::BinOpKind::BitXor => Some("std::ops::BitXorAssign"),
- hir::BinOpKind::BitOr => Some("std::ops::BitOrAssign"),
- hir::BinOpKind::Shl => Some("std::ops::ShlAssign"),
- hir::BinOpKind::Shr => Some("std::ops::ShrAssign"),
- _ => None,
- };
self.note_unmet_impls_on_type(&mut err, errors);
- (err, missing_trait, false)
+ (err, None)
}
IsAssign::No => {
- let (message, missing_trait, use_output) = match op.node {
- hir::BinOpKind::Add => (
- format!("cannot add `{rhs_ty}` to `{lhs_ty}`"),
- Some("std::ops::Add"),
- true,
- ),
- hir::BinOpKind::Sub => (
- format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`"),
- Some("std::ops::Sub"),
- true,
- ),
- hir::BinOpKind::Mul => (
- format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`"),
- Some("std::ops::Mul"),
- true,
- ),
- hir::BinOpKind::Div => (
- format!("cannot divide `{lhs_ty}` by `{rhs_ty}`"),
- Some("std::ops::Div"),
- true,
- ),
- hir::BinOpKind::Rem => (
- format!("cannot mod `{lhs_ty}` by `{rhs_ty}`"),
- Some("std::ops::Rem"),
- true,
- ),
- hir::BinOpKind::BitAnd => (
- format!("no implementation for `{lhs_ty} & {rhs_ty}`"),
- Some("std::ops::BitAnd"),
- true,
- ),
- hir::BinOpKind::BitXor => (
- format!("no implementation for `{lhs_ty} ^ {rhs_ty}`"),
- Some("std::ops::BitXor"),
- true,
- ),
- hir::BinOpKind::BitOr => (
- format!("no implementation for `{lhs_ty} | {rhs_ty}`"),
- Some("std::ops::BitOr"),
- true,
- ),
- hir::BinOpKind::Shl => (
- format!("no implementation for `{lhs_ty} << {rhs_ty}`"),
- Some("std::ops::Shl"),
- true,
- ),
- hir::BinOpKind::Shr => (
- format!("no implementation for `{lhs_ty} >> {rhs_ty}`"),
- Some("std::ops::Shr"),
- true,
- ),
- hir::BinOpKind::Eq | hir::BinOpKind::Ne => (
- format!(
- "binary operation `{}` cannot be applied to type `{}`",
- op.node.as_str(),
- lhs_ty
- ),
- Some("std::cmp::PartialEq"),
- false,
- ),
- hir::BinOpKind::Lt
- | hir::BinOpKind::Le
- | hir::BinOpKind::Gt
- | hir::BinOpKind::Ge => (
- format!(
- "binary operation `{}` cannot be applied to type `{}`",
- op.node.as_str(),
- lhs_ty
- ),
- Some("std::cmp::PartialOrd"),
- false,
- ),
- _ => (
- format!(
- "binary operation `{}` cannot be applied to type `{}`",
- op.node.as_str(),
- lhs_ty
- ),
- None,
- false,
+ let message = match op.node {
+ hir::BinOpKind::Add => {
+ format!("cannot add `{rhs_ty}` to `{lhs_ty}`")
+ }
+ hir::BinOpKind::Sub => {
+ format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`")
+ }
+ hir::BinOpKind::Mul => {
+ format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`")
+ }
+ hir::BinOpKind::Div => {
+ format!("cannot divide `{lhs_ty}` by `{rhs_ty}`")
+ }
+ hir::BinOpKind::Rem => {
+ format!("cannot mod `{lhs_ty}` by `{rhs_ty}`")
+ }
+ hir::BinOpKind::BitAnd => {
+ format!("no implementation for `{lhs_ty} & {rhs_ty}`")
+ }
+ hir::BinOpKind::BitXor => {
+ format!("no implementation for `{lhs_ty} ^ {rhs_ty}`")
+ }
+ hir::BinOpKind::BitOr => {
+ format!("no implementation for `{lhs_ty} | {rhs_ty}`")
+ }
+ hir::BinOpKind::Shl => {
+ format!("no implementation for `{lhs_ty} << {rhs_ty}`")
+ }
+ hir::BinOpKind::Shr => {
+ format!("no implementation for `{lhs_ty} >> {rhs_ty}`")
+ }
+ _ => format!(
+ "binary operation `{}` cannot be applied to type `{}`",
+ op.node.as_str(),
+ lhs_ty
),
};
+ let output_def_id = trait_def_id.and_then(|def_id| {
+ self.tcx
+ .associated_item_def_ids(def_id)
+ .iter()
+ .find(|item_def_id| {
+ self.tcx.associated_item(*item_def_id).name == sym::Output
+ })
+ .cloned()
+ });
let mut err = struct_span_err!(self.tcx.sess, op.span, E0369, "{message}");
if !lhs_expr.span.eq(&rhs_expr.span) {
- self.add_type_neq_err_label(
- &mut err,
- lhs_expr.span,
- lhs_ty,
- rhs_ty,
- rhs_expr,
- op,
- is_assign,
- expected,
- );
- self.add_type_neq_err_label(
- &mut err,
- rhs_expr.span,
- rhs_ty,
- lhs_ty,
- lhs_expr,
- op,
- is_assign,
- expected,
- );
+ err.span_label(lhs_expr.span, lhs_ty.to_string());
+ err.span_label(rhs_expr.span, rhs_ty.to_string());
}
self.note_unmet_impls_on_type(&mut err, errors);
- (err, missing_trait, use_output)
+ (err, output_def_id)
}
};
@@ -447,42 +399,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)
.is_ok()
{
- if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
- let msg = &format!(
- "`{}{}` can be used on `{}`, you can dereference `{}`",
- op.node.as_str(),
- match is_assign {
- IsAssign::Yes => "=",
- IsAssign::No => "",
- },
- lhs_deref_ty.peel_refs(),
- lstring,
- );
- err.span_suggestion_verbose(
- lhs_expr.span.shrink_to_lo(),
- msg,
- "*",
- rustc_errors::Applicability::MachineApplicable,
- );
- }
+ let msg = &format!(
+ "`{}{}` can be used on `{}` if you dereference the left-hand side",
+ op.node.as_str(),
+ match is_assign {
+ IsAssign::Yes => "=",
+ IsAssign::No => "",
+ },
+ lhs_deref_ty,
+ );
+ err.span_suggestion_verbose(
+ lhs_expr.span.shrink_to_lo(),
+ msg,
+ "*",
+ rustc_errors::Applicability::MachineApplicable,
+ );
}
};
+ let is_compatible = |lhs_ty, rhs_ty| {
+ self.lookup_op_method(
+ lhs_ty,
+ Some(rhs_ty),
+ Some(rhs_expr),
+ Op::Binary(op, is_assign),
+ expected,
+ )
+ .is_ok()
+ };
+
// We should suggest `a + b` => `*a + b` if `a` is copy, and suggest
// `a += b` => `*a += b` if a is a mut ref.
- if is_assign == IsAssign::Yes
- && let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
- suggest_deref_binop(lhs_deref_ty);
+ if !op.span.can_be_used_for_suggestions() {
+ // Suppress suggestions when lhs and rhs are not in the same span as the error
+ } else if is_assign == IsAssign::Yes
+ && let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty)
+ {
+ suggest_deref_binop(lhs_deref_ty);
} else if is_assign == IsAssign::No
- && let Ref(_, lhs_deref_ty, _) = lhs_ty.kind() {
- if self.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty, lhs_expr.span) {
+ && let Ref(_, lhs_deref_ty, _) = lhs_ty.kind()
+ {
+ if self.type_is_copy_modulo_regions(
+ self.param_env,
+ *lhs_deref_ty,
+ lhs_expr.span,
+ ) {
suggest_deref_binop(*lhs_deref_ty);
}
+ } else if self.suggest_fn_call(&mut err, lhs_expr, lhs_ty, |lhs_ty| {
+ is_compatible(lhs_ty, rhs_ty)
+ }) || self.suggest_fn_call(&mut err, rhs_expr, rhs_ty, |rhs_ty| {
+ is_compatible(lhs_ty, rhs_ty)
+ }) || self.suggest_two_fn_call(
+ &mut err,
+ rhs_expr,
+ rhs_ty,
+ lhs_expr,
+ lhs_ty,
+ |lhs_ty, rhs_ty| is_compatible(lhs_ty, rhs_ty),
+ ) {
+ // Cool
}
- if let Some(missing_trait) = missing_trait {
- let mut visitor = TypeParamVisitor(vec![]);
- visitor.visit_ty(lhs_ty);
+ if let Some(missing_trait) = missing_trait {
if op.node == hir::BinOpKind::Add
&& self.check_str_addition(
lhs_expr, rhs_expr, lhs_ty, rhs_ty, &mut err, is_assign, op,
@@ -491,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// This has nothing here because it means we did string
// concatenation (e.g., "Hello " + "World!"). This means
// we don't want the note in the else clause to be emitted
- } else if let [ty] = &visitor.0[..] {
+ } else if lhs_ty.has_param_types_or_consts() {
// Look for a TraitPredicate in the Fulfillment errors,
// and use it to generate a suggestion.
//
@@ -513,12 +492,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(trait_pred) =
error.obligation.predicate.to_opt_poly_trait_pred()
{
- let proj_pred = match error.obligation.cause.code() {
+ let output_associated_item = match error.obligation.cause.code()
+ {
ObligationCauseCode::BinOp {
- output_pred: Some(output_pred),
+ output_ty: Some(output_ty),
..
- } if use_output => {
- output_pred.to_opt_poly_projection_pred()
+ } => {
+ // Make sure that we're attaching `Output = ..` to the right trait predicate
+ if let Some(output_def_id) = output_def_id
+ && let Some(trait_def_id) = trait_def_id
+ && self.tcx.parent(output_def_id) == trait_def_id
+ {
+ Some(("Output", *output_ty))
+ } else {
+ None
+ }
}
_ => None,
};
@@ -526,12 +514,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_restricting_param_bound(
&mut err,
trait_pred,
- proj_pred,
+ output_associated_item,
self.body_id,
);
}
}
- } else if *ty != lhs_ty {
+ } else {
// When we know that a missing bound is responsible, we don't show
// this note as it is redundant.
err.note(&format!(
@@ -548,69 +536,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(lhs_ty, rhs_ty, return_ty)
}
- /// If one of the types is an uncalled function and calling it would yield the other type,
- /// suggest calling the function. Returns `true` if suggestion would apply (even if not given).
- fn add_type_neq_err_label(
- &self,
- err: &mut Diagnostic,
- span: Span,
- ty: Ty<'tcx>,
- other_ty: Ty<'tcx>,
- other_expr: &'tcx hir::Expr<'tcx>,
- op: hir::BinOp,
- is_assign: IsAssign,
- expected: Expectation<'tcx>,
- ) -> bool /* did we suggest to call a function because of missing parentheses? */ {
- err.span_label(span, ty.to_string());
- if let FnDef(def_id, _) = *ty.kind() {
- if !self.tcx.has_typeck_results(def_id) {
- return false;
- }
- // FIXME: Instead of exiting early when encountering bound vars in
- // the function signature, consider keeping the binder here and
- // propagating it downwards.
- let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() else {
- return false;
- };
-
- let other_ty = if let FnDef(def_id, _) = *other_ty.kind() {
- if !self.tcx.has_typeck_results(def_id) {
- return false;
- }
- // We're emitting a suggestion, so we can just ignore regions
- self.tcx.fn_sig(def_id).skip_binder().output()
- } else {
- other_ty
- };
-
- if self
- .lookup_op_method(
- fn_sig.output(),
- Some(other_ty),
- Some(other_expr),
- Op::Binary(op, is_assign),
- expected,
- )
- .is_ok()
- {
- let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
- ("( /* arguments */ )", Applicability::HasPlaceholders)
- } else {
- ("()", Applicability::MaybeIncorrect)
- };
-
- err.span_suggestion_verbose(
- span.shrink_to_hi(),
- "you might have forgotten to call this function",
- variable_snippet,
- applicability,
- );
- return true;
- }
- }
- false
- }
-
/// Provide actionable suggestions when trying to add two strings with incorrect types,
/// like `&str + &str`, `String + String` and `&str + &String`.
///
@@ -731,14 +656,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("cannot apply unary operator `{}`", op.as_str()),
);
- let mut visitor = TypeParamVisitor(vec![]);
- visitor.visit_ty(operand_ty);
- if let [_] = &visitor.0[..] && let ty::Param(_) = *operand_ty.kind() {
- let predicates = errors
- .iter()
- .filter_map(|error| {
- error.obligation.predicate.to_opt_poly_trait_pred()
- });
+ if operand_ty.has_param_types_or_consts() {
+ let predicates = errors.iter().filter_map(|error| {
+ error.obligation.predicate.to_opt_poly_trait_pred()
+ });
for pred in predicates {
self.suggest_restricting_param_bound(
&mut err,
@@ -806,64 +727,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
op: Op,
expected: Expectation<'tcx>,
) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
- let lang = self.tcx.lang_items();
-
let span = match op {
Op::Binary(op, _) => op.span,
Op::Unary(_, span) => span,
};
- let (opname, trait_did) = if let Op::Binary(op, IsAssign::Yes) = op {
- match op.node {
- hir::BinOpKind::Add => (sym::add_assign, lang.add_assign_trait()),
- hir::BinOpKind::Sub => (sym::sub_assign, lang.sub_assign_trait()),
- hir::BinOpKind::Mul => (sym::mul_assign, lang.mul_assign_trait()),
- hir::BinOpKind::Div => (sym::div_assign, lang.div_assign_trait()),
- hir::BinOpKind::Rem => (sym::rem_assign, lang.rem_assign_trait()),
- hir::BinOpKind::BitXor => (sym::bitxor_assign, lang.bitxor_assign_trait()),
- hir::BinOpKind::BitAnd => (sym::bitand_assign, lang.bitand_assign_trait()),
- hir::BinOpKind::BitOr => (sym::bitor_assign, lang.bitor_assign_trait()),
- hir::BinOpKind::Shl => (sym::shl_assign, lang.shl_assign_trait()),
- hir::BinOpKind::Shr => (sym::shr_assign, lang.shr_assign_trait()),
- hir::BinOpKind::Lt
- | hir::BinOpKind::Le
- | hir::BinOpKind::Ge
- | hir::BinOpKind::Gt
- | hir::BinOpKind::Eq
- | hir::BinOpKind::Ne
- | hir::BinOpKind::And
- | hir::BinOpKind::Or => {
- span_bug!(span, "impossible assignment operation: {}=", op.node.as_str())
- }
- }
- } else if let Op::Binary(op, IsAssign::No) = op {
- match op.node {
- hir::BinOpKind::Add => (sym::add, lang.add_trait()),
- hir::BinOpKind::Sub => (sym::sub, lang.sub_trait()),
- hir::BinOpKind::Mul => (sym::mul, lang.mul_trait()),
- hir::BinOpKind::Div => (sym::div, lang.div_trait()),
- hir::BinOpKind::Rem => (sym::rem, lang.rem_trait()),
- hir::BinOpKind::BitXor => (sym::bitxor, lang.bitxor_trait()),
- hir::BinOpKind::BitAnd => (sym::bitand, lang.bitand_trait()),
- hir::BinOpKind::BitOr => (sym::bitor, lang.bitor_trait()),
- hir::BinOpKind::Shl => (sym::shl, lang.shl_trait()),
- hir::BinOpKind::Shr => (sym::shr, lang.shr_trait()),
- hir::BinOpKind::Lt => (sym::lt, lang.partial_ord_trait()),
- hir::BinOpKind::Le => (sym::le, lang.partial_ord_trait()),
- hir::BinOpKind::Ge => (sym::ge, lang.partial_ord_trait()),
- hir::BinOpKind::Gt => (sym::gt, lang.partial_ord_trait()),
- hir::BinOpKind::Eq => (sym::eq, lang.eq_trait()),
- hir::BinOpKind::Ne => (sym::ne, lang.eq_trait()),
- hir::BinOpKind::And | hir::BinOpKind::Or => {
- span_bug!(span, "&& and || are not overloadable")
- }
- }
- } else if let Op::Unary(hir::UnOp::Not, _) = op {
- (sym::not, lang.not_trait())
- } else if let Op::Unary(hir::UnOp::Neg, _) = op {
- (sym::neg, lang.neg_trait())
- } else {
- bug!("lookup_op_method: op not supported: {:?}", op)
- };
+ let (opname, trait_did) = lang_item_for_op(self.tcx, op, span);
debug!(
"lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})",
@@ -924,6 +792,66 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+fn lang_item_for_op(
+ tcx: TyCtxt<'_>,
+ op: Op,
+ span: Span,
+) -> (rustc_span::Symbol, Option<hir::def_id::DefId>) {
+ let lang = tcx.lang_items();
+ if let Op::Binary(op, IsAssign::Yes) = op {
+ match op.node {
+ hir::BinOpKind::Add => (sym::add_assign, lang.add_assign_trait()),
+ hir::BinOpKind::Sub => (sym::sub_assign, lang.sub_assign_trait()),
+ hir::BinOpKind::Mul => (sym::mul_assign, lang.mul_assign_trait()),
+ hir::BinOpKind::Div => (sym::div_assign, lang.div_assign_trait()),
+ hir::BinOpKind::Rem => (sym::rem_assign, lang.rem_assign_trait()),
+ hir::BinOpKind::BitXor => (sym::bitxor_assign, lang.bitxor_assign_trait()),
+ hir::BinOpKind::BitAnd => (sym::bitand_assign, lang.bitand_assign_trait()),
+ hir::BinOpKind::BitOr => (sym::bitor_assign, lang.bitor_assign_trait()),
+ hir::BinOpKind::Shl => (sym::shl_assign, lang.shl_assign_trait()),
+ hir::BinOpKind::Shr => (sym::shr_assign, lang.shr_assign_trait()),
+ hir::BinOpKind::Lt
+ | hir::BinOpKind::Le
+ | hir::BinOpKind::Ge
+ | hir::BinOpKind::Gt
+ | hir::BinOpKind::Eq
+ | hir::BinOpKind::Ne
+ | hir::BinOpKind::And
+ | hir::BinOpKind::Or => {
+ span_bug!(span, "impossible assignment operation: {}=", op.node.as_str())
+ }
+ }
+ } else if let Op::Binary(op, IsAssign::No) = op {
+ match op.node {
+ hir::BinOpKind::Add => (sym::add, lang.add_trait()),
+ hir::BinOpKind::Sub => (sym::sub, lang.sub_trait()),
+ hir::BinOpKind::Mul => (sym::mul, lang.mul_trait()),
+ hir::BinOpKind::Div => (sym::div, lang.div_trait()),
+ hir::BinOpKind::Rem => (sym::rem, lang.rem_trait()),
+ hir::BinOpKind::BitXor => (sym::bitxor, lang.bitxor_trait()),
+ hir::BinOpKind::BitAnd => (sym::bitand, lang.bitand_trait()),
+ hir::BinOpKind::BitOr => (sym::bitor, lang.bitor_trait()),
+ hir::BinOpKind::Shl => (sym::shl, lang.shl_trait()),
+ hir::BinOpKind::Shr => (sym::shr, lang.shr_trait()),
+ hir::BinOpKind::Lt => (sym::lt, lang.partial_ord_trait()),
+ hir::BinOpKind::Le => (sym::le, lang.partial_ord_trait()),
+ hir::BinOpKind::Ge => (sym::ge, lang.partial_ord_trait()),
+ hir::BinOpKind::Gt => (sym::gt, lang.partial_ord_trait()),
+ hir::BinOpKind::Eq => (sym::eq, lang.eq_trait()),
+ hir::BinOpKind::Ne => (sym::ne, lang.eq_trait()),
+ hir::BinOpKind::And | hir::BinOpKind::Or => {
+ span_bug!(span, "&& and || are not overloadable")
+ }
+ }
+ } else if let Op::Unary(hir::UnOp::Not, _) = op {
+ (sym::not, lang.not_trait())
+ } else if let Op::Unary(hir::UnOp::Neg, _) = op {
+ (sym::neg, lang.neg_trait())
+ } else {
+ bug!("lookup_op_method: op not supported: {:?}", op)
+ }
+}
+
// Binary operator categories. These categories summarize the behavior
// with respect to the builtin operations supported.
enum BinOpCategory {
@@ -1046,17 +974,6 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool
}
}
-struct TypeParamVisitor<'tcx>(Vec<Ty<'tcx>>);
-
-impl<'tcx> TypeVisitor<'tcx> for TypeParamVisitor<'tcx> {
- fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
- if let ty::Param(_) = ty.kind() {
- self.0.push(ty);
- }
- ty.super_visit_with(self)
- }
-}
-
struct TypeParamEraser<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, Span);
impl<'tcx> TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> {
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 837c32355..8906b622b 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -569,7 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
// Determine the binding mode...
let bm = match ba {
- hir::BindingAnnotation::Unannotated => def_bm,
+ hir::BindingAnnotation::NONE => def_bm,
_ => BindingMode::convert(ba),
};
// ...and store it in a side table:
@@ -600,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If there are multiple arms, make sure they all agree on
// what the type of the binding `x` ought to be.
if var_id != pat.hir_id {
- self.check_binding_alt_eq_ty(pat.span, var_id, local_ty, ti);
+ self.check_binding_alt_eq_ty(ba, pat.span, var_id, local_ty, ti);
}
if let Some(p) = sub {
@@ -610,7 +610,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
local_ty
}
- fn check_binding_alt_eq_ty(&self, span: Span, var_id: HirId, ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
+ fn check_binding_alt_eq_ty(
+ &self,
+ ba: hir::BindingAnnotation,
+ span: Span,
+ var_id: HirId,
+ ty: Ty<'tcx>,
+ ti: TopInfo<'tcx>,
+ ) {
let var_ty = self.local_ty(span, var_id).decl_ty;
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
let hir = self.tcx.hir();
@@ -628,12 +635,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
});
let pre = if in_match { "in the same arm, " } else { "" };
err.note(&format!("{}a binding must have the same type in all alternatives", pre));
- // FIXME: check if `var_ty` and `ty` can be made the same type by adding or removing
- // `ref` or `&` to the pattern.
+ self.suggest_adding_missing_ref_or_removing_ref(
+ &mut err,
+ span,
+ var_ty,
+ self.resolve_vars_with_obligations(ty),
+ ba,
+ );
err.emit();
}
}
+ fn suggest_adding_missing_ref_or_removing_ref(
+ &self,
+ err: &mut Diagnostic,
+ span: Span,
+ expected: Ty<'tcx>,
+ actual: Ty<'tcx>,
+ ba: hir::BindingAnnotation,
+ ) {
+ match (expected.kind(), actual.kind(), ba) {
+ (ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::NONE)
+ if self.can_eq(self.param_env, *inner_ty, actual).is_ok() =>
+ {
+ err.span_suggestion_verbose(
+ span.shrink_to_lo(),
+ "consider adding `ref`",
+ "ref ",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ (_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::REF)
+ if self.can_eq(self.param_env, expected, *inner_ty).is_ok() =>
+ {
+ err.span_suggestion_verbose(
+ span.with_hi(span.lo() + BytePos(4)),
+ "consider removing `ref`",
+ "",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ _ => (),
+ }
+ }
+
// Precondition: pat is a Ref(_) pattern
fn borrow_pat_suggestion(&self, err: &mut Diagnostic, pat: &Pat<'_>) {
let tcx = self.tcx;
@@ -882,7 +927,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
match self.tcx.hir().get(self.tcx.hir().get_parent_node(pat.hir_id)) {
- hir::Node::Pat(Pat { kind: hir::PatKind::Struct(..), .. }) => {
+ hir::Node::PatField(..) => {
e.span_suggestion_verbose(
ident.span.shrink_to_hi(),
"bind the struct field to a different name instead",
@@ -936,7 +981,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>,
qpath: &'tcx hir::QPath<'tcx>,
subpats: &'tcx [Pat<'tcx>],
- ddpos: Option<usize>,
+ ddpos: hir::DotDotPos,
expected: Ty<'tcx>,
def_bm: BindingMode,
ti: TopInfo<'tcx>,
@@ -1021,7 +1066,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type-check subpatterns.
if subpats.len() == variant.fields.len()
- || subpats.len() < variant.fields.len() && ddpos.is_some()
+ || subpats.len() < variant.fields.len() && ddpos.as_opt_usize().is_some()
{
let ty::Adt(_, substs) = pat_ty.kind() else {
bug!("unexpected pattern type {:?}", pat_ty);
@@ -1209,14 +1254,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
span: Span,
elements: &'tcx [Pat<'tcx>],
- ddpos: Option<usize>,
+ ddpos: hir::DotDotPos,
expected: Ty<'tcx>,
def_bm: BindingMode,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let mut expected_len = elements.len();
- if ddpos.is_some() {
+ if ddpos.as_opt_usize().is_some() {
// Require known type only when `..` is present.
if let ty::Tuple(tys) = self.structurally_resolved_type(span, expected).kind() {
expected_len = tys.len();
@@ -1352,7 +1397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.iter()
.copied()
.filter(|(field, _)| {
- field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
+ field.vis.is_accessible_from(tcx.parent_module(pat.hir_id), tcx)
&& !matches!(
tcx.eval_stability(field.did, None, DUMMY_SP, None),
EvalResult::Deny { .. }
diff --git a/compiler/rustc_typeck/src/check/region.rs b/compiler/rustc_typeck/src/check/region.rs
index 0081e9049..b89db79be 100644
--- a/compiler/rustc_typeck/src/check/region.rs
+++ b/compiler/rustc_typeck/src/check/region.rs
@@ -126,6 +126,29 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
for (i, statement) in blk.stmts.iter().enumerate() {
match statement.kind {
+ hir::StmtKind::Local(hir::Local { els: Some(els), .. }) => {
+ // Let-else has a special lexical structure for variables.
+ // First we take a checkpoint of the current scope context here.
+ let mut prev_cx = visitor.cx;
+
+ visitor.enter_scope(Scope {
+ id: blk.hir_id.local_id,
+ data: ScopeData::Remainder(FirstStatementIndex::new(i)),
+ });
+ visitor.cx.var_parent = visitor.cx.parent;
+ visitor.visit_stmt(statement);
+ // We need to back out temporarily to the last enclosing scope
+ // for the `else` block, so that even the temporaries receiving
+ // extended lifetime will be dropped inside this block.
+ // We are visiting the `else` block in this order so that
+ // the sequence of visits agree with the order in the default
+ // `hir::intravisit` visitor.
+ mem::swap(&mut prev_cx, &mut visitor.cx);
+ visitor.terminating_scopes.insert(els.hir_id.local_id);
+ visitor.visit_block(els);
+ // From now on, we continue normally.
+ visitor.cx = prev_cx;
+ }
hir::StmtKind::Local(..) | hir::StmtKind::Item(..) => {
// Each declaration introduces a subscope for bindings
// introduced by the declaration; this subscope covers a
@@ -138,10 +161,10 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
data: ScopeData::Remainder(FirstStatementIndex::new(i)),
});
visitor.cx.var_parent = visitor.cx.parent;
+ visitor.visit_stmt(statement)
}
- hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
+ hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => visitor.visit_stmt(statement),
}
- visitor.visit_stmt(statement)
}
walk_list!(visitor, visit_expr, &blk.expr);
}
@@ -460,7 +483,6 @@ fn resolve_local<'tcx>(
visitor: &mut RegionResolutionVisitor<'tcx>,
pat: Option<&'tcx hir::Pat<'tcx>>,
init: Option<&'tcx hir::Expr<'tcx>>,
- els: Option<&'tcx hir::Block<'tcx>>,
) {
debug!("resolve_local(pat={:?}, init={:?})", pat, init);
@@ -547,9 +569,6 @@ fn resolve_local<'tcx>(
if let Some(pat) = pat {
visitor.visit_pat(pat);
}
- if let Some(els) = els {
- visitor.visit_block(els);
- }
/// Returns `true` if `pat` match the `P&` non-terminal.
///
@@ -587,8 +606,7 @@ fn resolve_local<'tcx>(
// & expression, and its lifetime would be extended to the end of the block (due
// to a different rule, not the below code).
match pat.kind {
- PatKind::Binding(hir::BindingAnnotation::Ref, ..)
- | PatKind::Binding(hir::BindingAnnotation::RefMut, ..) => true,
+ PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes, _), ..) => true,
PatKind::Struct(_, ref field_pats, _) => {
field_pats.iter().any(|fp| is_binding_pat(&fp.pat))
@@ -607,10 +625,7 @@ fn resolve_local<'tcx>(
PatKind::Box(ref subpat) => is_binding_pat(&subpat),
PatKind::Ref(_, _)
- | PatKind::Binding(
- hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
- ..,
- )
+ | PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
| PatKind::Wild
| PatKind::Path(_)
| PatKind::Lit(_)
@@ -770,7 +785,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
// (i.e., `'static`), which means that after `g` returns, it drops,
// and all the associated destruction scope rules apply.
self.cx.var_parent = None;
- resolve_local(self, None, Some(&body.value), None);
+ resolve_local(self, None, Some(&body.value));
}
if body.generator_kind.is_some() {
@@ -797,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
resolve_expr(self, ex);
}
fn visit_local(&mut self, l: &'tcx Local<'tcx>) {
- resolve_local(self, Some(&l.pat), l.init, l.els)
+ resolve_local(self, Some(&l.pat), l.init)
}
}
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
deleted file mode 100644
index d49a6138f..000000000
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-use crate::outlives::outlives_bounds::InferCtxtExt as _;
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir as hir;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::InferCtxt;
-use rustc_middle::ty::Ty;
-
-pub(crate) trait OutlivesEnvironmentExt<'tcx> {
- fn add_implied_bounds(
- &mut self,
- infcx: &InferCtxt<'_, 'tcx>,
- fn_sig_tys: FxHashSet<Ty<'tcx>>,
- body_id: hir::HirId,
- );
-}
-
-impl<'tcx> OutlivesEnvironmentExt<'tcx> for OutlivesEnvironment<'tcx> {
- /// This method adds "implied bounds" into the outlives environment.
- /// Implied bounds are outlives relationships that we can deduce
- /// on the basis that certain types must be well-formed -- these are
- /// either the types that appear in the function signature or else
- /// the input types to an impl. For example, if you have a function
- /// like
- ///
- /// ```
- /// fn foo<'a, 'b, T>(x: &'a &'b [T]) { }
- /// ```
- ///
- /// we can assume in the caller's body that `'b: 'a` and that `T:
- /// 'b` (and hence, transitively, that `T: 'a`). This method would
- /// add those assumptions into the outlives-environment.
- ///
- /// Tests: `src/test/ui/regions/regions-free-region-ordering-*.rs`
- #[instrument(level = "debug", skip(self, infcx))]
- fn add_implied_bounds<'a>(
- &mut self,
- infcx: &InferCtxt<'a, 'tcx>,
- fn_sig_tys: FxHashSet<Ty<'tcx>>,
- body_id: hir::HirId,
- ) {
- for ty in fn_sig_tys {
- let ty = infcx.resolve_vars_if_possible(ty);
- let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty);
- self.add_outlives_bounds(Some(infcx), implied_bounds)
- }
- }
-}
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index dd8f943b9..0b207a6c0 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -1217,7 +1217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Combine all the reasons of why the root variable should be captured as a result of
// auto trait implementation issues
- auto_trait_migration_reasons.extend(capture_trait_reasons.clone());
+ auto_trait_migration_reasons.extend(capture_trait_reasons.iter().copied());
diagnostics_info.push(MigrationLintNote {
captures_info,
@@ -2024,6 +2024,10 @@ fn should_do_rust_2021_incompatible_closure_captures_analysis(
tcx: TyCtxt<'_>,
closure_id: hir::HirId,
) -> bool {
+ if tcx.sess.rust_2021() {
+ return false;
+ }
+
let (level, _) =
tcx.lint_level_at_node(lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_id);
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index d0334cd0d..27b3da8ab 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1,5 +1,5 @@
-use crate::check::regionck::OutlivesEnvironmentExt;
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
+use hir::def::DefKind;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
@@ -10,7 +10,7 @@ use rustc_hir::ItemKind;
use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
use rustc_infer::infer::outlives::obligations::TypeOutlives;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::Normalized;
+use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -23,9 +23,8 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::autoderef::Autoderef;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
+use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc_trait_selection::traits::query::normalize::AtExt;
-use rustc_trait_selection::traits::query::NoSolution;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
};
@@ -72,9 +71,11 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
) {
let cause =
traits::ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(loc));
+ // for a type to be WF, we do not need to check if const trait predicates satisfy.
+ let param_env = self.param_env.without_const();
self.ocx.register_obligation(traits::Obligation::new(
cause,
- self.param_env,
+ param_env,
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx()),
));
}
@@ -86,26 +87,31 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
body_def_id: LocalDefId,
f: F,
) where
- F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>) -> FxHashSet<Ty<'tcx>>,
+ F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>),
{
let param_env = tcx.param_env(body_def_id);
let body_id = tcx.hir().local_def_id_to_hir_id(body_def_id);
tcx.infer_ctxt().enter(|ref infcx| {
let ocx = ObligationCtxt::new(infcx);
+
+ let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id);
+
let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env };
if !tcx.features().trivial_bounds {
wfcx.check_false_global_bounds()
}
- let wf_tys = f(&mut wfcx);
+ f(&mut wfcx);
let errors = wfcx.select_all_or_error();
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
return;
}
- let mut outlives_environment = OutlivesEnvironment::new(param_env);
- outlives_environment.add_implied_bounds(infcx, wf_tys, body_id);
+ let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);
+ let outlives_environment =
+ OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
+
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
})
}
@@ -383,7 +389,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
tcx,
param_env,
item_hir_id,
- sig.output(),
+ sig.inputs_and_output,
// We also assume that all of the function signature's parameter types
// are well formed.
&sig.inputs().iter().copied().collect(),
@@ -658,7 +664,7 @@ fn ty_known_to_outlive<'tcx>(
resolve_regions_with_wf_tys(tcx, id, param_env, &wf_tys, |infcx, region_bound_pairs| {
let origin = infer::RelateParamBound(DUMMY_SP, ty, None);
let outlives = &mut TypeOutlives::new(infcx, tcx, region_bound_pairs, None, param_env);
- outlives.type_must_outlive(origin, ty, region);
+ outlives.type_must_outlive(origin, ty, region, ConstraintCategory::BoringNoLocation);
})
}
@@ -676,7 +682,12 @@ fn region_known_to_outlive<'tcx>(
use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate;
let origin = infer::RelateRegionParamBound(DUMMY_SP);
// `region_a: region_b` -> `region_b <= region_a`
- infcx.push_sub_region_constraint(origin, region_b, region_a);
+ infcx.push_sub_region_constraint(
+ origin,
+ region_b,
+ region_a,
+ ConstraintCategory::BoringNoLocation,
+ );
})
}
@@ -694,8 +705,11 @@ fn resolve_regions_with_wf_tys<'tcx>(
// region constraints get added and solved there and we need to test each
// call individually.
tcx.infer_ctxt().enter(|infcx| {
- let mut outlives_environment = OutlivesEnvironment::new(param_env);
- outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id);
+ let outlives_environment = OutlivesEnvironment::with_bounds(
+ param_env,
+ Some(&infcx),
+ infcx.implied_bounds_tys(param_env, id, wf_tys.clone()),
+ );
let region_bound_pairs = outlives_environment.region_bound_pairs();
add_constraints(&infcx, region_bound_pairs);
@@ -761,7 +775,7 @@ impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
match ty.kind {
hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
- [s] => s.res.and_then(|r| r.opt_def_id()) == Some(trait_def_id.to_def_id()),
+ [s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
_ => false,
},
_ => false,
@@ -965,7 +979,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
}
}
-#[tracing::instrument(level = "debug", skip(tcx, span, sig_if_method))]
+#[instrument(level = "debug", skip(tcx, span, sig_if_method))]
fn check_associated_item(
tcx: TyCtxt<'_>,
item_id: LocalDefId,
@@ -976,15 +990,9 @@ fn check_associated_item(
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
let item = tcx.associated_item(item_id);
- let (mut implied_bounds, self_ty) = match item.container {
- ty::TraitContainer => (FxHashSet::default(), tcx.types.self_param),
- ty::ImplContainer => {
- let def_id = item.container_id(tcx);
- (
- impl_implied_bounds(tcx, wfcx.param_env, def_id.expect_local(), span),
- tcx.type_of(def_id),
- )
- }
+ let self_ty = match item.container {
+ ty::TraitContainer => tcx.types.self_param,
+ ty::ImplContainer => tcx.type_of(item.container_id(tcx)),
};
match item.kind {
@@ -1002,7 +1010,6 @@ fn check_associated_item(
sig,
hir_sig.decl,
item.def_id.expect_local(),
- &mut implied_bounds,
);
check_method_receiver(wfcx, hir_sig, item, self_ty);
}
@@ -1017,8 +1024,6 @@ fn check_associated_item(
}
}
}
-
- implied_bounds
})
}
@@ -1118,9 +1123,6 @@ fn check_type_defn<'tcx, F>(
}
check_where_clauses(wfcx, item.span, item.def_id);
-
- // No implied bounds in a struct definition.
- FxHashSet::default()
});
}
@@ -1144,9 +1146,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
}
enter_wf_checking_ctxt(tcx, item.span, item.def_id, |wfcx| {
- check_where_clauses(wfcx, item.span, item.def_id);
-
- FxHashSet::default()
+ check_where_clauses(wfcx, item.span, item.def_id)
});
// Only check traits, don't check trait aliases
@@ -1186,9 +1186,7 @@ fn check_item_fn(
) {
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
let sig = tcx.fn_sig(def_id);
- let mut implied_bounds = FxHashSet::default();
- check_fn_or_method(wfcx, ident.span, sig, decl, def_id, &mut implied_bounds);
- implied_bounds
+ check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
})
}
@@ -1231,13 +1229,10 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
);
}
-
- // No implied bounds in a const, etc.
- FxHashSet::default()
});
}
-#[tracing::instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
+#[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
fn check_impl<'tcx>(
tcx: TyCtxt<'tcx>,
item: &'tcx hir::Item<'tcx>,
@@ -1274,7 +1269,11 @@ fn check_impl<'tcx>(
}
None => {
let self_ty = tcx.type_of(item.def_id);
- let self_ty = wfcx.normalize(item.span, None, self_ty);
+ let self_ty = wfcx.normalize(
+ item.span,
+ Some(WellFormedLoc::Ty(item.hir_id().expect_owner())),
+ self_ty,
+ );
wfcx.register_wf_obligation(
ast_self_ty.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner())),
@@ -1284,8 +1283,6 @@ fn check_impl<'tcx>(
}
check_where_clauses(wfcx, item.span, item.def_id);
-
- impl_implied_bounds(tcx, wfcx.param_env, item.def_id, item.span)
});
}
@@ -1321,7 +1318,11 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
// parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
// be sure if it will error or not as user might always specify the other.
if !ty.needs_subst() {
- wfcx.register_wf_obligation(tcx.def_span(param.def_id), None, ty.into());
+ wfcx.register_wf_obligation(
+ tcx.def_span(param.def_id),
+ Some(WellFormedLoc::Ty(param.def_id.expect_local())),
+ ty.into(),
+ );
}
}
}
@@ -1465,21 +1466,26 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
assert_eq!(predicates.predicates.len(), predicates.spans.len());
let wf_obligations =
iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| {
- traits::wf::predicate_obligations(infcx, wfcx.param_env, wfcx.body_id, p, sp)
+ traits::wf::predicate_obligations(
+ infcx,
+ wfcx.param_env.without_const(),
+ wfcx.body_id,
+ p,
+ sp,
+ )
});
let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect();
wfcx.register_obligations(obligations);
}
-#[tracing::instrument(level = "debug", skip(wfcx, span, hir_decl))]
+#[instrument(level = "debug", skip(wfcx, span, hir_decl))]
fn check_fn_or_method<'tcx>(
wfcx: &WfCheckingCtxt<'_, 'tcx>,
span: Span,
sig: ty::PolyFnSig<'tcx>,
hir_decl: &hir::FnDecl<'_>,
def_id: LocalDefId,
- implied_bounds: &mut FxHashSet<Ty<'tcx>>,
) {
let tcx = wfcx.tcx();
let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
@@ -1521,23 +1527,66 @@ fn check_fn_or_method<'tcx>(
);
}
- implied_bounds.extend(sig.inputs());
-
- wfcx.register_wf_obligation(hir_decl.output.span(), None, sig.output().into());
+ wfcx.register_wf_obligation(
+ hir_decl.output.span(),
+ Some(WellFormedLoc::Param {
+ function: def_id,
+ param_idx: sig.inputs().len().try_into().unwrap(),
+ }),
+ sig.output().into(),
+ );
- // FIXME(#27579) return types should not be implied bounds
- implied_bounds.insert(sig.output());
+ check_where_clauses(wfcx, span, def_id);
- debug!(?implied_bounds);
+ check_return_position_impl_trait_in_trait_bounds(
+ tcx,
+ wfcx,
+ def_id,
+ sig.output(),
+ hir_decl.output.span(),
+ );
+}
- check_where_clauses(wfcx, span, def_id);
+/// Basically `check_associated_type_bounds`, but separated for now and should be
+/// deduplicated when RPITITs get lowered into real associated items.
+fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ wfcx: &WfCheckingCtxt<'_, 'tcx>,
+ fn_def_id: LocalDefId,
+ fn_output: Ty<'tcx>,
+ span: Span,
+) {
+ if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
+ && assoc_item.container == ty::AssocItemContainer::TraitContainer
+ {
+ for arg in fn_output.walk() {
+ if let ty::GenericArgKind::Type(ty) = arg.unpack()
+ && let ty::Projection(proj) = ty.kind()
+ && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+ && tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
+ {
+ let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
+ let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
+ let normalized_bound = wfcx.normalize(span, None, bound);
+ traits::wf::predicate_obligations(
+ wfcx.infcx,
+ wfcx.param_env,
+ wfcx.body_id,
+ normalized_bound,
+ bound_span,
+ )
+ });
+ wfcx.register_obligations(wf_obligations);
+ }
+ }
+ }
}
const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
of the previous types except `Self`)";
-#[tracing::instrument(level = "debug", skip(wfcx))]
+#[instrument(level = "debug", skip(wfcx))]
fn check_method_receiver<'tcx>(
wfcx: &WfCheckingCtxt<'_, 'tcx>,
fn_sig: &hir::FnSig<'_>,
@@ -1817,6 +1866,7 @@ fn report_bivariance(
impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
/// aren't true.
+ #[instrument(level = "debug", skip(self))]
fn check_false_global_bounds(&mut self) {
let tcx = self.ocx.infcx.tcx;
let mut span = self.span;
@@ -1924,40 +1974,6 @@ impl<'a, 'tcx> WfCheckingCtxt<'a, 'tcx> {
}
}
-pub fn impl_implied_bounds<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- impl_def_id: LocalDefId,
- span: Span,
-) -> FxHashSet<Ty<'tcx>> {
- // We completely ignore any obligations caused by normalizing the types
- // we assume to be well formed. Considering that the user of the implied
- // bounds will also normalize them, we leave it to them to emit errors
- // which should result in better causes and spans.
- tcx.infer_ctxt().enter(|infcx| {
- let cause = ObligationCause::misc(span, tcx.hir().local_def_id_to_hir_id(impl_def_id));
- match tcx.impl_trait_ref(impl_def_id) {
- Some(trait_ref) => {
- // Trait impl: take implied bounds from all types that
- // appear in the trait reference.
- match infcx.at(&cause, param_env).normalize(trait_ref) {
- Ok(Normalized { value, obligations: _ }) => value.substs.types().collect(),
- Err(NoSolution) => FxHashSet::default(),
- }
- }
-
- None => {
- // Inherent impl: take implied bounds from the `self` type.
- let self_ty = tcx.type_of(impl_def_id);
- match infcx.at(&cause, param_env).normalize(self_ty) {
- Ok(Normalized { value, obligations: _ }) => FxHashSet::from_iter([value]),
- Err(NoSolution) => FxHashSet::default(),
- }
- }
- }
- })
-}
-
fn error_392(
tcx: TyCtxt<'_>,
span: Span,
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index f549807c3..9ecf34e9a 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -3,7 +3,6 @@
// substitutions.
use crate::check::FnCtxt;
-
use hir::def_id::LocalDefId;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::ErrorGuaranteed;
@@ -16,6 +15,7 @@ use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::TypeckResults;
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
@@ -192,6 +192,27 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
}
}
+ // (ouz-a 1005988): Normally `[T] : std::ops::Index<usize>` should be normalized
+ // into [T] but currently `Where` clause stops the normalization process for it,
+ // here we compare types of expr and base in a code without `Where` clause they would be equal
+ // if they are not we don't modify the expr, hence we bypass the ICE
+ fn is_builtin_index(
+ &mut self,
+ typeck_results: &TypeckResults<'tcx>,
+ e: &hir::Expr<'_>,
+ base_ty: Ty<'tcx>,
+ index_ty: Ty<'tcx>,
+ ) -> bool {
+ if let Some(elem_ty) = base_ty.builtin_index() {
+ let Some(exp_ty) = typeck_results.expr_ty_opt(e) else {return false;};
+ let resolved_exp_ty = self.resolve(exp_ty, &e.span);
+
+ elem_ty == resolved_exp_ty && index_ty == self.fcx.tcx.types.usize
+ } else {
+ false
+ }
+ }
+
// Similar to operators, indexing is always assumed to be overloaded
// Here, correct cases where an indexing expression can be simplified
// to use builtin indexing because the index type is known to be
@@ -222,8 +243,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
)
});
let index_ty = self.fcx.resolve_vars_if_possible(index_ty);
+ let resolved_base_ty = self.resolve(*base_ty, &base.span);
- if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
+ if self.is_builtin_index(&typeck_results, e, resolved_base_ty, index_ty) {
// Remove the method call record
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
typeck_results.node_substs_mut().remove(e.hir_id);
@@ -292,6 +314,17 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
intravisit::walk_expr(self, e);
}
+ fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+ match &p.kind {
+ hir::GenericParamKind::Lifetime { .. } => {
+ // Nothing to write back here
+ }
+ hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
+ self.tcx().sess.delay_span_bug(p.span, format!("unexpected generic param: {p:?}"));
+ }
+ }
+ }
+
fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
self.visit_node_id(b.span, b.hir_id);
intravisit::walk_block(self, b);
@@ -468,7 +501,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
if !errors_buffer.is_empty() {
errors_buffer.sort_by_key(|diag| diag.span.primary_span());
- for mut diag in errors_buffer.drain(..) {
+ for mut diag in errors_buffer {
self.tcx().sess.diagnostic().emit_diagnostic(&mut diag);
}
}
diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs
index 4a3cfa1ca..1d23ed929 100644
--- a/compiler/rustc_typeck/src/check_unused.rs
+++ b/compiler/rustc_typeck/src/check_unused.rs
@@ -1,5 +1,5 @@
+use crate::errors::{ExternCrateNotIdiomatic, UnusedExternCrate};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -108,25 +108,16 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
// We do this in any edition.
if extern_crate.warn_if_unused {
if let Some(&span) = unused_extern_crates.get(&def_id) {
+ // Removal suggestion span needs to include attributes (Issue #54400)
let id = tcx.hir().local_def_id_to_hir_id(def_id);
- tcx.struct_span_lint_hir(lint, id, span, |lint| {
- // Removal suggestion span needs to include attributes (Issue #54400)
- let span_with_attrs = tcx
- .hir()
- .attrs(id)
- .iter()
- .map(|attr| attr.span)
- .fold(span, |acc, attr_span| acc.to(attr_span));
-
- lint.build("unused extern crate")
- .span_suggestion_short(
- span_with_attrs,
- "remove it",
- "",
- Applicability::MachineApplicable,
- )
- .emit();
- });
+ let span_with_attrs = tcx
+ .hir()
+ .attrs(id)
+ .iter()
+ .map(|attr| attr.span)
+ .fold(span, |acc, attr_span| acc.to(attr_span));
+
+ tcx.emit_spanned_lint(lint, id, span, UnusedExternCrate { span: span_with_attrs });
continue;
}
}
@@ -158,23 +149,23 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
if !tcx.hir().attrs(id).is_empty() {
continue;
}
- tcx.struct_span_lint_hir(lint, id, extern_crate.span, |lint| {
- // Otherwise, we can convert it into a `use` of some kind.
- let base_replacement = match extern_crate.orig_name {
- Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name),
- None => format!("use {};", item.ident.name),
- };
- let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default();
- let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) };
- lint.build("`extern crate` is not idiomatic in the new edition")
- .span_suggestion_short(
- extern_crate.span,
- &format!("convert it to a `{}`", add_vis("use".to_string())),
- add_vis(base_replacement),
- Applicability::MachineApplicable,
- )
- .emit();
- })
+
+ let base_replacement = match extern_crate.orig_name {
+ Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name),
+ None => format!("use {};", item.ident.name),
+ };
+ let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default();
+ let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) };
+ tcx.emit_spanned_lint(
+ lint,
+ id,
+ extern_crate.span,
+ ExternCrateNotIdiomatic {
+ span: extern_crate.span,
+ msg_code: add_vis("use".to_string()),
+ suggestion_code: add_vis(base_replacement),
+ },
+ );
}
}
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index 50946cc1d..d08c0d4db 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeV
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
use rustc_trait_selection::traits::predicate_for_trait_def;
-use rustc_trait_selection::traits::{self, ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_trait_selection::traits::{self, ObligationCause};
use std::collections::BTreeMap;
pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) {
@@ -47,9 +47,11 @@ impl<'tcx> Checker<'tcx> {
}
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
- // Destructors only work on nominal types.
- if let ty::Adt(..) | ty::Error(_) = tcx.type_of(impl_did).kind() {
- return;
+ // Destructors only work on local ADT types.
+ match tcx.type_of(impl_did).kind() {
+ ty::Adt(def, _) if def.did().is_local() => return,
+ ty::Error(_) => return,
+ _ => {}
}
let sp = match tcx.hir().expect_item(impl_did).kind {
@@ -109,15 +111,13 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
// it is not immediately clear why Copy is not implemented for a field, since
// all we point at is the field itself.
tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
- let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
- fulfill_cx.register_bound(
+ for error in traits::fully_solve_bound(
&infcx,
+ traits::ObligationCause::dummy_with_span(field_ty_span),
param_env,
ty,
tcx.lang_items().copy_trait().unwrap(),
- traits::ObligationCause::dummy_with_span(field_ty_span),
- );
- for error in fulfill_cx.select_all_or_error(&infcx) {
+ ) {
let error_predicate = error.obligation.predicate;
// Only note if it's not the root obligation, otherwise it's trivial and
// should be self-explanatory (i.e. a field literally doesn't implement Copy).
@@ -315,24 +315,20 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
))
.emit();
} else {
- let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
-
- for field in coerced_fields {
- let predicate = predicate_for_trait_def(
- tcx,
- param_env,
- cause.clone(),
- dispatch_from_dyn_trait,
- 0,
- field.ty(tcx, substs_a),
- &[field.ty(tcx, substs_b).into()],
- );
-
- fulfill_cx.register_predicate_obligation(&infcx, predicate);
- }
-
- // Check that all transitive obligations are satisfied.
- let errors = fulfill_cx.select_all_or_error(&infcx);
+ let errors = traits::fully_solve_obligations(
+ &infcx,
+ coerced_fields.into_iter().map(|field| {
+ predicate_for_trait_def(
+ tcx,
+ param_env,
+ cause.clone(),
+ dispatch_from_dyn_trait,
+ 0,
+ field.ty(tcx, substs_a),
+ &[field.ty(tcx, substs_b).into()],
+ )
+ }),
+ );
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
}
@@ -363,7 +359,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
let unsize_trait = tcx.lang_items().require(LangItem::Unsize).unwrap_or_else(|err| {
- tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
+ tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err.to_string()));
});
let source = tcx.type_of(impl_did);
@@ -573,8 +569,6 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
}
};
- let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
-
// Register an obligation for `A: Trait<B>`.
let cause = traits::ObligationCause::misc(span, impl_hir_id);
let predicate = predicate_for_trait_def(
@@ -586,10 +580,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
source,
&[target.into()],
);
- fulfill_cx.register_predicate_obligation(&infcx, predicate);
-
- // Check that all transitive obligations are satisfied.
- let errors = fulfill_cx.select_all_or_error(&infcx);
+ let errors = traits::fully_solve_obligation(&infcx, predicate);
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
}
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 99996e80c..45a5eca70 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -25,7 +25,7 @@ use rustc_ast::{MetaItemKind, NestedMetaItem};
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -94,7 +94,27 @@ pub fn provide(providers: &mut Providers) {
///////////////////////////////////////////////////////////////////////////
/// Context specific to some particular item. This is what implements
-/// `AstConv`. It has information about the predicates that are defined
+/// [`AstConv`].
+///
+/// # `ItemCtxt` vs `FnCtxt`
+///
+/// `ItemCtxt` is primarily used to type-check item signatures and lower them
+/// from HIR to their [`ty::Ty`] representation, which is exposed using [`AstConv`].
+/// It's also used for the bodies of items like structs where the body (the fields)
+/// are just signatures.
+///
+/// This is in contrast to [`FnCtxt`], which is used to type-check bodies of
+/// functions, closures, and `const`s -- anywhere that expressions and statements show up.
+///
+/// An important thing to note is that `ItemCtxt` does no inference -- it has no [`InferCtxt`] --
+/// while `FnCtxt` does do inference.
+///
+/// [`FnCtxt`]: crate::check::FnCtxt
+/// [`InferCtxt`]: rustc_infer::infer::InferCtxt
+///
+/// # Trait predicates
+///
+/// `ItemCtxt` has information about the predicates that are defined
/// on the trait. Unfortunately, this predicate information is
/// available in various different forms at various points in the
/// process. So we can't just store a pointer to e.g., the AST or the
@@ -553,6 +573,7 @@ fn get_new_lifetime_name<'tcx>(
/// Returns the predicates defined on `item_def_id` of the form
/// `X: Foo` where `X` is the type parameter `def_id`.
+#[instrument(level = "trace", skip(tcx))]
fn type_param_predicates(
tcx: TyCtxt<'_>,
(item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
@@ -659,7 +680,7 @@ impl<'tcx> ItemCtxt<'tcx> {
assoc_name: Option<Ident>,
) -> Vec<(ty::Predicate<'tcx>, Span)> {
let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
- debug!(?param_def_id);
+ trace!(?param_def_id);
ast_generics
.predicates
.iter()
@@ -688,9 +709,8 @@ impl<'tcx> ItemCtxt<'tcx> {
.collect()
}
+ #[instrument(level = "trace", skip(self))]
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
- debug!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b, assoc_name);
-
match b {
hir::GenericBound::Trait(poly_trait_ref, _) => {
let trait_ref = &poly_trait_ref.trait_ref;
@@ -832,12 +852,14 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
tcx.ensure().type_of(trait_item_id.def_id);
}
- hir::TraitItemKind::Const(..) => {
+ hir::TraitItemKind::Const(hir_ty, _) => {
tcx.ensure().type_of(trait_item_id.def_id);
// Account for `const C: _;`.
let mut visitor = HirPlaceholderCollector::default();
visitor.visit_trait_item(trait_item);
- placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
+ if !tcx.sess.diagnostic().has_stashed_diagnostic(hir_ty.span, StashKey::ItemNoType) {
+ placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
+ }
}
hir::TraitItemKind::Type(_, Some(_)) => {
@@ -1326,16 +1348,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
}
}
- fn visit_poly_trait_ref(
- &mut self,
- tr: &'tcx hir::PolyTraitRef<'tcx>,
- m: hir::TraitBoundModifier,
- ) {
+ fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) {
if self.has_late_bound_regions.is_some() {
return;
}
self.outer_index.shift_in(1);
- intravisit::walk_poly_trait_ref(self, tr, m);
+ intravisit::walk_poly_trait_ref(self, tr);
self.outer_index.shift_out(1);
}
@@ -1565,8 +1583,16 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
ItemKind::OpaqueTy(hir::OpaqueTy {
origin:
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+ in_trait,
..
- }) => Some(fn_def_id.to_def_id()),
+ }) => {
+ if in_trait {
+ assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
+ } else {
+ assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
+ }
+ Some(fn_def_id.to_def_id())
+ }
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
let parent_id = tcx.hir().get_parent_item(hir_id);
assert_ne!(parent_id, CRATE_DEF_ID);
@@ -1580,6 +1606,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
_ => None,
};
+ enum Defaults {
+ Allowed,
+ // See #36887
+ FutureCompatDisallowed,
+ Deny,
+ }
+
let no_generics = hir::Generics::empty();
let ast_generics = node.generics().unwrap_or(&no_generics);
let (opt_self, allow_defaults) = match node {
@@ -1597,22 +1630,30 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
pure_wrt_drop: false,
kind: ty::GenericParamDefKind::Type {
has_default: false,
- object_lifetime_default: rl::Set1::Empty,
synthetic: false,
},
});
- (opt_self, true)
+ (opt_self, Defaults::Allowed)
}
ItemKind::TyAlias(..)
| ItemKind::Enum(..)
| ItemKind::Struct(..)
| ItemKind::OpaqueTy(..)
- | ItemKind::Union(..) => (None, true),
- _ => (None, false),
+ | ItemKind::Union(..) => (None, Defaults::Allowed),
+ _ => (None, Defaults::FutureCompatDisallowed),
}
}
- _ => (None, false),
+
+ // GATs
+ Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
+ (None, Defaults::Deny)
+ }
+ Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => {
+ (None, Defaults::Deny)
+ }
+
+ _ => (None, Defaults::FutureCompatDisallowed),
};
let has_self = opt_self.is_some();
@@ -1641,39 +1682,38 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
kind: ty::GenericParamDefKind::Lifetime,
}));
- let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner);
-
// Now create the real type and const parameters.
let type_start = own_start - has_self as u32 + params.len() as u32;
let mut i = 0;
+ const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
+ `struct`, `enum`, `type`, or `trait` definitions";
+
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { ref default, synthetic, .. } => {
- if !allow_defaults && default.is_some() {
- if !tcx.features().default_type_parameter_fallback {
- tcx.struct_span_lint_hir(
- lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
- param.hir_id,
- param.span,
- |lint| {
- lint.build(
- "defaults for type parameters are only allowed in \
- `struct`, `enum`, `type`, or `trait` definitions",
- )
- .emit();
- },
- );
+ if default.is_some() {
+ match allow_defaults {
+ Defaults::Allowed => {}
+ Defaults::FutureCompatDisallowed
+ if tcx.features().default_type_parameter_fallback => {}
+ Defaults::FutureCompatDisallowed => {
+ tcx.struct_span_lint_hir(
+ lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
+ param.hir_id,
+ param.span,
+ |lint| {
+ lint.build(TYPE_DEFAULT_NOT_ALLOWED).emit();
+ },
+ );
+ }
+ Defaults::Deny => {
+ tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED);
+ }
}
}
- let kind = ty::GenericParamDefKind::Type {
- has_default: default.is_some(),
- object_lifetime_default: object_lifetime_defaults
- .as_ref()
- .map_or(rl::Set1::Empty, |o| o[i]),
- synthetic,
- };
+ let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
let param_def = ty::GenericParamDef {
index: type_start + i as u32,
@@ -1686,7 +1726,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
Some(param_def)
}
GenericParamKind::Const { default, .. } => {
- if !allow_defaults && default.is_some() {
+ if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() {
tcx.sess.span_err(
param.span,
"defaults for const parameters are only allowed in \
@@ -1725,11 +1765,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
name: Symbol::intern(arg),
def_id,
pure_wrt_drop: false,
- kind: ty::GenericParamDefKind::Type {
- has_default: false,
- object_lifetime_default: rl::Set1::Empty,
- synthetic: false,
- },
+ kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
}));
}
@@ -1742,11 +1778,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
name: Symbol::intern("<const_ty>"),
def_id,
pure_wrt_drop: false,
- kind: ty::GenericParamDefKind::Type {
- has_default: false,
- object_lifetime_default: rl::Set1::Empty,
- synthetic: false,
- },
+ kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
});
}
}
@@ -1784,7 +1816,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
}
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
- OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
+ OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
Path(hir::QPath::TypeRelative(ty, segment)) => {
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
}
@@ -1805,6 +1837,7 @@ pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir
None
}
+#[instrument(level = "debug", skip(tcx))]
fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
use rustc_hir::Node::*;
use rustc_hir::*;
@@ -2035,8 +2068,8 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
/// Returns a list of type predicates for the definition with ID `def_id`, including inferred
/// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
/// inferred constraints concerning which regions outlive other regions.
+#[instrument(level = "debug", skip(tcx))]
fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
- debug!("predicates_defined_on({:?})", def_id);
let mut result = tcx.explicit_predicates_of(def_id);
debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result,);
let inferred_outlives = tcx.inferred_outlives_of(def_id);
@@ -2102,11 +2135,10 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
/// Returns a list of user-specified type predicates for the definition with ID `def_id`.
/// N.B., this does not include any implied/inferred constraints.
+#[instrument(level = "trace", skip(tcx), ret)]
fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
use rustc_hir::*;
- debug!("explicit_predicates_of(def_id={:?})", def_id);
-
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
let node = tcx.hir().get(hir_id);
@@ -2221,6 +2253,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
+ has_own_self as u32
+ early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
+ trace!(?predicates);
+ trace!(?ast_generics);
+
// Collect the predicates that were written inline by the user on each
// type parameter (e.g., `<T: Foo>`).
for param in ast_generics.params {
@@ -2241,7 +2276,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
Some((param.hir_id, ast_generics.predicates)),
param.span,
);
+ trace!(?bounds);
predicates.extend(bounds.predicates(tcx, param_ty));
+ trace!(?predicates);
}
GenericParamKind::Const { .. } => {
// Bounds on const parameters are currently not possible.
@@ -2250,6 +2287,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
}
}
+ trace!(?predicates);
// Add in the bounds that appear in the where-clause.
for predicate in ast_generics.predicates {
match predicate {
@@ -2335,12 +2373,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
);
}
- let result = ty::GenericPredicates {
+ ty::GenericPredicates {
parent: generics.parent,
predicates: tcx.arena.alloc_from_iter(predicates),
- };
- debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result);
- result
+ }
}
fn const_evaluatable_predicates_of<'tcx>(
@@ -2357,10 +2393,10 @@ fn const_evaluatable_predicates_of<'tcx>(
let def_id = self.tcx.hir().local_def_id(c.hir_id);
let ct = ty::Const::from_anon_const(self.tcx, def_id);
if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
- assert_eq!(uv.promoted, None);
+ assert_eq!(uv.promoted, ());
let span = self.tcx.hir().span(c.hir_id);
self.preds.insert((
- ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
+ ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
.to_predicate(self.tcx),
span,
));
@@ -2816,12 +2852,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
}
Some(_) => {
- tcx.sess
- .struct_span_err(
- attr.span,
- "expected `used`, `used(compiler)` or `used(linker)`",
- )
- .emit();
+ tcx.sess.emit_err(errors::ExpectedUsedSymbol { span: attr.span });
}
None => {
// Unfortunately, unconditionally using `llvm.used` causes
@@ -3278,6 +3309,15 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
use rustc_ast::{Lit, LitIntType, LitKind};
+ if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" {
+ feature_err(
+ &tcx.sess.parse_sess,
+ sym::raw_dylib,
+ attr.span,
+ "`#[link_ordinal]` is unstable on x86",
+ )
+ .emit();
+ }
let meta_item_list = attr.meta_item_list();
let meta_item_list: Option<&[ast::NestedMetaItem]> = meta_item_list.as_ref().map(Vec::as_ref);
let sole_meta_list = match meta_item_list {
diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs
index 0d2b75d33..0d34a8bfe 100644
--- a/compiler/rustc_typeck/src/collect/item_bounds.rs
+++ b/compiler/rustc_typeck/src/collect/item_bounds.rs
@@ -53,20 +53,28 @@ fn associated_type_bounds<'tcx>(
/// impl trait it isn't possible to write a suitable predicate on the
/// containing function and for type-alias impl trait we don't have a backwards
/// compatibility issue.
+#[instrument(level = "trace", skip(tcx), ret)]
fn opaque_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
opaque_def_id: DefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span,
+ in_trait: bool,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
ty::print::with_no_queries!({
- let item_ty =
- tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
+ let substs = InternalSubsts::identity_for_item(tcx, opaque_def_id);
+ let item_ty = if in_trait {
+ tcx.mk_projection(opaque_def_id, substs)
+ } else {
+ tcx.mk_opaque(opaque_def_id, substs)
+ };
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
// Opaque types are implicitly sized unless a `?Sized` bound is found
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
+ debug!(?bounds);
+
tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
})
}
@@ -83,10 +91,10 @@ pub(super) fn explicit_item_bounds(
..
}) => associated_type_bounds(tcx, def_id, bounds, *span),
hir::Node::Item(hir::Item {
- kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }),
+ kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
span,
..
- }) => opaque_type_bounds(tcx, def_id, bounds, *span),
+ }) => opaque_type_bounds(tcx, def_id, bounds, *span, *in_trait),
_ => bug!("item_bounds called on {:?}", def_id),
}
}
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 534ddfa95..a1d1f125f 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -1,6 +1,5 @@
use rustc_errors::{Applicability, StashKey};
use rustc_hir as hir;
-use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit;
use rustc_hir::intravisit::Visitor;
@@ -19,7 +18,6 @@ use crate::errors::UnconstrainedOpaqueType;
/// Computes the relevant generic parameter for a potential generic const argument.
///
/// This should be called using the query `tcx.opt_const_param_of`.
-#[instrument(level = "debug", skip(tcx))]
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
use hir::*;
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
@@ -67,8 +65,8 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
let ty = item_ctxt.ast_ty_to_ty(hir_ty);
// Iterate through the generics of the projection to find the one that corresponds to
- // the def_id that this query was called with. We filter to only const args here as a
- // precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't
+ // the def_id that this query was called with. We filter to only type and const args here
+ // as a precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't
// but it can't hurt to be safe ^^
if let ty::Projection(projection) = ty.kind() {
let generics = tcx.generics_of(projection.item_def_id);
@@ -79,7 +77,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
- .position(|arg| arg.id() == hir_id)
+ .position(|arg| arg.hir_id() == hir_id)
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in segment");
@@ -112,7 +110,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
- .position(|arg| arg.id() == hir_id)
+ .position(|arg| arg.hir_id() == hir_id)
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in segment");
@@ -166,7 +164,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
- .position(|arg| arg.id() == hir_id)
+ .position(|arg| arg.hir_id() == hir_id)
.map(|index| (index, seg)).or_else(|| args.bindings
.iter()
.filter_map(TypeBinding::opt_const)
@@ -180,15 +178,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
return None;
};
- // Try to use the segment resolution if it is valid, otherwise we
- // default to the path resolution.
- let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
- let generics = match tcx.res_generics_def_id(res) {
+ let generics = match tcx.res_generics_def_id(segment.res) {
Some(def_id) => tcx.generics_of(def_id),
None => {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
- &format!("unexpected anon const res {:?} in path: {:?}", res, path),
+ &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
);
return None;
}
@@ -229,7 +224,7 @@ fn get_path_containing_arg_in_pat<'hir>(
.iter()
.filter_map(|seg| seg.args)
.flat_map(|args| args.args)
- .any(|arg| arg.id() == arg_id)
+ .any(|arg| arg.hir_id() == arg_id)
};
let mut arg_path = None;
pat.walk(|pat| match pat.kind {
@@ -338,8 +333,17 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
find_opaque_ty_constraints_for_tait(tcx, def_id)
}
// Opaque types desugared from `impl Trait`.
- ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), .. }) => {
- find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+ ItemKind::OpaqueTy(OpaqueTy {
+ origin:
+ hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
+ in_trait,
+ ..
+ }) => {
+ if in_trait {
+ span_bug!(item.span, "impl-trait in trait has no default")
+ } else {
+ find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+ }
}
ItemKind::Trait(..)
| ItemKind::TraitAlias(..)
@@ -379,7 +383,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
Node::Field(field) => icx.to_ty(field.ty),
- Node::Expr(&Expr { kind: ExprKind::Closure{..}, .. }) => tcx.typeck(def_id).node_type(hir_id),
+ Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => {
+ tcx.typeck(def_id).node_type(hir_id)
+ }
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
// We defer to `type_of` of the corresponding parameter
@@ -411,40 +417,91 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
if asm.operands.iter().any(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const }
- | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
+ | hir::InlineAsmOperand::SymFn { anon_const } => {
+ anon_const.hir_id == hir_id
+ }
_ => false,
}) =>
{
tcx.typeck(def_id).node_type(hir_id)
}
- Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx
- .adt_def(tcx.hir().get_parent_item(hir_id))
- .repr()
- .discr_type()
- .to_ty(tcx),
+ Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
+ tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
+ }
+
+ Node::TypeBinding(
+ binding @ &TypeBinding {
+ hir_id: binding_id,
+ kind: TypeBindingKind::Equality { term: Term::Const(ref e) },
+ ..
+ },
+ ) if let Node::TraitRef(trait_ref) =
+ tcx.hir().get(tcx.hir().get_parent_node(binding_id))
+ && e.hir_id == hir_id =>
+ {
+ let Some(trait_def_id) = trait_ref.trait_def_id() else {
+ return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
+ };
+ let assoc_items = tcx.associated_items(trait_def_id);
+ let assoc_item = assoc_items.find_by_name_and_kind(
+ tcx,
+ binding.ident,
+ ty::AssocKind::Const,
+ def_id.to_def_id(),
+ );
+ if let Some(assoc_item) = assoc_item {
+ tcx.type_of(assoc_item.def_id)
+ } else {
+ // FIXME(associated_const_equality): add a useful error message here.
+ tcx.ty_error_with_message(
+ DUMMY_SP,
+ "Could not find associated const on trait",
+ )
+ }
+ }
- Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
- if let Node::TraitRef(trait_ref) = tcx.hir().get(
- tcx.hir().get_parent_node(binding_id)
- ) =>
+ Node::TypeBinding(
+ binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. },
+ ) if let Node::TraitRef(trait_ref) =
+ tcx.hir().get(tcx.hir().get_parent_node(binding_id))
+ && let Some((idx, _)) =
+ gen_args.args.iter().enumerate().find(|(_, arg)| {
+ if let GenericArg::Const(ct) = arg {
+ ct.value.hir_id == hir_id
+ } else {
+ false
+ }
+ }) =>
{
- let Some(trait_def_id) = trait_ref.trait_def_id() else {
- return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
- };
- let assoc_items = tcx.associated_items(trait_def_id);
- let assoc_item = assoc_items.find_by_name_and_kind(
- tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
- );
- if let Some(assoc_item) = assoc_item {
- tcx.type_of(assoc_item.def_id)
- } else {
- // FIXME(associated_const_equality): add a useful error message here.
- tcx.ty_error_with_message(
- DUMMY_SP,
- "Could not find associated const on trait",
- )
- }
+ let Some(trait_def_id) = trait_ref.trait_def_id() else {
+ return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
+ };
+ let assoc_items = tcx.associated_items(trait_def_id);
+ let assoc_item = assoc_items.find_by_name_and_kind(
+ tcx,
+ binding.ident,
+ match kind {
+ // I think `<A: T>` type bindings requires that `A` is a type
+ TypeBindingKind::Constraint { .. }
+ | TypeBindingKind::Equality { term: Term::Ty(..) } => {
+ ty::AssocKind::Type
+ }
+ TypeBindingKind::Equality { term: Term::Const(..) } => {
+ ty::AssocKind::Const
+ }
+ },
+ def_id.to_def_id(),
+ );
+ if let Some(assoc_item) = assoc_item {
+ tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id)
+ } else {
+ // FIXME(associated_const_equality): add a useful error message here.
+ tcx.ty_error_with_message(
+ DUMMY_SP,
+ "Could not find associated const on trait",
+ )
+ }
}
Node::GenericParam(&GenericParam {
@@ -453,8 +510,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
..
}) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)),
- x =>
- tcx.ty_error_with_message(
+ x => tcx.ty_error_with_message(
DUMMY_SP,
&format!("unexpected const parent in type_of(): {x:?}"),
),
@@ -801,6 +857,9 @@ fn infer_placeholder_type<'a>(
match tcx.sess.diagnostic().steal_diagnostic(span, StashKey::ItemNoType) {
Some(mut err) => {
if !ty.references_error() {
+ // Only suggest adding `:` if it was missing (and suggested by parsing diagnostic)
+ let colon = if span == item_ident.span.shrink_to_hi() { ":" } else { "" };
+
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
// We are typeck and have the real type, so remove that and suggest the actual type.
// FIXME(eddyb) this looks like it should be functionality on `Diagnostic`.
@@ -816,7 +875,7 @@ fn infer_placeholder_type<'a>(
err.span_suggestion(
span,
&format!("provide a type for the {item}", item = kind),
- format!("{}: {}", item_ident, sugg_ty),
+ format!("{colon} {sugg_ty}"),
Applicability::MachineApplicable,
);
} else {
diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs
index 0438ac02e..0d2e66745 100644
--- a/compiler/rustc_typeck/src/errors.rs
+++ b/compiler/rustc_typeck/src/errors.rs
@@ -1,12 +1,12 @@
//! Errors emitted by typeck.
-use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed};
-use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler};
+use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
use rustc_middle::ty::Ty;
-use rustc_session::{parse::ParseSess, SessionDiagnostic};
+use rustc_session::SessionDiagnostic;
use rustc_span::{symbol::Ident, Span, Symbol};
#[derive(SessionDiagnostic)]
-#[error(typeck::field_multiply_specified_in_initializer, code = "E0062")]
+#[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")]
pub struct FieldMultiplySpecifiedInInitializer {
#[primary_span]
#[label]
@@ -17,7 +17,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::unrecognized_atomic_operation, code = "E0092")]
+#[diag(typeck::unrecognized_atomic_operation, code = "E0092")]
pub struct UnrecognizedAtomicOperation<'a> {
#[primary_span]
#[label]
@@ -26,7 +26,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
+#[diag(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
#[primary_span]
#[label]
@@ -37,7 +37,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::unrecognized_intrinsic_function, code = "E0093")]
+#[diag(typeck::unrecognized_intrinsic_function, code = "E0093")]
pub struct UnrecognizedIntrinsicFunction {
#[primary_span]
#[label]
@@ -46,7 +46,7 @@ pub struct UnrecognizedIntrinsicFunction {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
+#[diag(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
pub struct LifetimesOrBoundsMismatchOnTrait {
#[primary_span]
#[label]
@@ -58,7 +58,7 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::drop_impl_on_wrong_item, code = "E0120")]
+#[diag(typeck::drop_impl_on_wrong_item, code = "E0120")]
pub struct DropImplOnWrongItem {
#[primary_span]
#[label]
@@ -66,7 +66,7 @@ pub struct DropImplOnWrongItem {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::field_already_declared, code = "E0124")]
+#[diag(typeck::field_already_declared, code = "E0124")]
pub struct FieldAlreadyDeclared {
pub field_name: Ident,
#[primary_span]
@@ -77,7 +77,7 @@ pub struct FieldAlreadyDeclared {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::copy_impl_on_type_with_dtor, code = "E0184")]
+#[diag(typeck::copy_impl_on_type_with_dtor, code = "E0184")]
pub struct CopyImplOnTypeWithDtor {
#[primary_span]
#[label]
@@ -85,14 +85,14 @@ pub struct CopyImplOnTypeWithDtor {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::multiple_relaxed_default_bounds, code = "E0203")]
+#[diag(typeck::multiple_relaxed_default_bounds, code = "E0203")]
pub struct MultipleRelaxedDefaultBounds {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::copy_impl_on_non_adt, code = "E0206")]
+#[diag(typeck::copy_impl_on_non_adt, code = "E0206")]
pub struct CopyImplOnNonAdt {
#[primary_span]
#[label]
@@ -100,7 +100,7 @@ pub struct CopyImplOnNonAdt {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::trait_object_declared_with_no_traits, code = "E0224")]
+#[diag(typeck::trait_object_declared_with_no_traits, code = "E0224")]
pub struct TraitObjectDeclaredWithNoTraits {
#[primary_span]
pub span: Span,
@@ -109,14 +109,14 @@ pub struct TraitObjectDeclaredWithNoTraits {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0227")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0227")]
pub struct AmbiguousLifetimeBound {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::assoc_type_binding_not_allowed, code = "E0229")]
+#[diag(typeck::assoc_type_binding_not_allowed, code = "E0229")]
pub struct AssocTypeBindingNotAllowed {
#[primary_span]
#[label]
@@ -124,14 +124,14 @@ pub struct AssocTypeBindingNotAllowed {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::functional_record_update_on_non_struct, code = "E0436")]
+#[diag(typeck::functional_record_update_on_non_struct, code = "E0436")]
pub struct FunctionalRecordUpdateOnNonStruct {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::typeof_reserved_keyword_used, code = "E0516")]
+#[diag(typeck::typeof_reserved_keyword_used, code = "E0516")]
pub struct TypeofReservedKeywordUsed<'tcx> {
pub ty: Ty<'tcx>,
#[primary_span]
@@ -142,7 +142,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::return_stmt_outside_of_fn_body, code = "E0572")]
+#[diag(typeck::return_stmt_outside_of_fn_body, code = "E0572")]
pub struct ReturnStmtOutsideOfFnBody {
#[primary_span]
pub span: Span,
@@ -153,14 +153,14 @@ pub struct ReturnStmtOutsideOfFnBody {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::yield_expr_outside_of_generator, code = "E0627")]
+#[diag(typeck::yield_expr_outside_of_generator, code = "E0627")]
pub struct YieldExprOutsideOfGenerator {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::struct_expr_non_exhaustive, code = "E0639")]
+#[diag(typeck::struct_expr_non_exhaustive, code = "E0639")]
pub struct StructExprNonExhaustive {
#[primary_span]
pub span: Span,
@@ -168,14 +168,14 @@ pub struct StructExprNonExhaustive {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::method_call_on_unknown_type, code = "E0699")]
+#[diag(typeck::method_call_on_unknown_type, code = "E0699")]
pub struct MethodCallOnUnknownType {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::value_of_associated_struct_already_specified, code = "E0719")]
+#[diag(typeck::value_of_associated_struct_already_specified, code = "E0719")]
pub struct ValueOfAssociatedStructAlreadySpecified {
#[primary_span]
#[label]
@@ -187,7 +187,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::address_of_temporary_taken, code = "E0745")]
+#[diag(typeck::address_of_temporary_taken, code = "E0745")]
pub struct AddressOfTemporaryTaken {
#[primary_span]
#[label]
@@ -195,7 +195,7 @@ pub struct AddressOfTemporaryTaken {
}
#[derive(SessionSubdiagnostic)]
-pub enum AddReturnTypeSuggestion<'tcx> {
+pub enum AddReturnTypeSuggestion {
#[suggestion(
typeck::add_return_type_add,
code = "-> {found} ",
@@ -204,7 +204,7 @@ pub enum AddReturnTypeSuggestion<'tcx> {
Add {
#[primary_span]
span: Span,
- found: Ty<'tcx>,
+ found: String,
},
#[suggestion(
typeck::add_return_type_missing_here,
@@ -233,7 +233,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::unconstrained_opaque_type)]
+#[diag(typeck::unconstrained_opaque_type)]
#[note]
pub struct UnconstrainedOpaqueType {
#[primary_span]
@@ -244,14 +244,15 @@ pub struct UnconstrainedOpaqueType {
pub struct MissingTypeParams {
pub span: Span,
pub def_span: Span,
+ pub span_snippet: Option<String>,
pub missing_type_params: Vec<Symbol>,
pub empty_generic_args: bool,
}
// Manual implementation of `SessionDiagnostic` to be able to call `span_to_snippet`.
impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
- fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- let mut err = sess.span_diagnostic.struct_span_err_with_code(
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ let mut err = handler.struct_span_err_with_code(
self.span,
rustc_errors::fluent::typeck::missing_type_params,
error_code!(E0393),
@@ -269,12 +270,9 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
err.span_label(self.def_span, rustc_errors::fluent::typeck::label);
let mut suggested = false;
- if let (Ok(snippet), true) = (
- sess.source_map().span_to_snippet(self.span),
- // Don't suggest setting the type params if there are some already: the order is
- // tricky to get right and the user will already know what the syntax is.
- self.empty_generic_args,
- ) {
+ // Don't suggest setting the type params if there are some already: the order is
+ // tricky to get right and the user will already know what the syntax is.
+ if let Some(snippet) = self.span_snippet && self.empty_generic_args {
if snippet.ends_with('>') {
// The user wrote `Trait<'a, T>` or similar. To provide an accurate suggestion
// we would have to preserve the right order. For now, as clearly the user is
@@ -309,7 +307,7 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::manual_implementation, code = "E0183")]
+#[diag(typeck::manual_implementation, code = "E0183")]
#[help]
pub struct ManualImplementation {
#[primary_span]
@@ -319,8 +317,31 @@ pub struct ManualImplementation {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::substs_on_overridden_impl)]
+#[diag(typeck::substs_on_overridden_impl)]
pub struct SubstsOnOverriddenImpl {
#[primary_span]
pub span: Span,
}
+
+#[derive(LintDiagnostic)]
+#[diag(typeck::unused_extern_crate)]
+pub struct UnusedExternCrate {
+ #[suggestion(applicability = "machine-applicable", code = "")]
+ pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(typeck::extern_crate_not_idiomatic)]
+pub struct ExternCrateNotIdiomatic {
+ #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")]
+ pub span: Span,
+ pub msg_code: String,
+ pub suggestion_code: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(typeck::expected_used_symbol)]
+pub struct ExpectedUsedSymbol {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index 74a5b6e42..f483342b4 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -233,8 +233,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
self.consume_exprs(args);
}
- hir::ExprKind::MethodCall(.., args, _) => {
+ hir::ExprKind::MethodCall(.., receiver, args, _) => {
// callee.m(args)
+ self.consume_expr(receiver);
self.consume_exprs(args);
}
@@ -497,7 +498,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
let expr_place = return_if_err!(self.mc.cat_expr(expr));
f(self);
if let Some(els) = els {
- // borrowing because we need to test the descriminant
+ // borrowing because we need to test the discriminant
self.maybe_read_scrutinee(expr, expr_place.clone(), from_ref(pat).iter());
self.walk_block(els)
}
diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs
index 55c7a15f9..7b080dc29 100644
--- a/compiler/rustc_typeck/src/hir_wf_check.rs
+++ b/compiler/rustc_typeck/src/hir_wf_check.rs
@@ -3,11 +3,10 @@ use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{ForeignItem, ForeignItemKind, HirId};
use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::TraitEngine;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder};
-use rustc_trait_selection::traits::{self, TraitEngineExt};
+use rustc_trait_selection::traits;
pub fn provide(providers: &mut Providers) {
*providers = Providers { diagnostic_hir_wf_check, ..*providers };
@@ -66,7 +65,6 @@ fn diagnostic_hir_wf_check<'tcx>(
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
self.tcx.infer_ctxt().enter(|infcx| {
- let mut fulfill = <dyn TraitEngine<'tcx>>::new(self.tcx);
let tcx_ty =
self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let cause = traits::ObligationCause::new(
@@ -74,7 +72,7 @@ fn diagnostic_hir_wf_check<'tcx>(
self.hir_id,
traits::ObligationCauseCode::WellFormed(None),
);
- fulfill.register_predicate_obligation(
+ let errors = traits::fully_solve_obligation(
&infcx,
traits::Obligation::new(
cause,
@@ -83,8 +81,6 @@ fn diagnostic_hir_wf_check<'tcx>(
.to_predicate(self.tcx),
),
);
-
- let errors = fulfill.select_all_or_error(&infcx);
if !errors.is_empty() {
debug!("Wf-check got errors for {:?}: {:?}", ty, errors);
for error in errors {
@@ -144,6 +140,10 @@ fn diagnostic_hir_wf_check<'tcx>(
hir::Node::ForeignItem(ForeignItem {
kind: ForeignItemKind::Static(ty, _), ..
}) => Some(*ty),
+ hir::Node::GenericParam(hir::GenericParam {
+ kind: hir::GenericParamKind::Type { default: Some(ty), .. },
+ ..
+ }) => Some(*ty),
ref node => bug!("Unexpected node {:?}", node),
},
WellFormedLoc::Param { function: _, param_idx } => {
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index 74abb71a1..2741d9f77 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -65,27 +65,25 @@
//! cause use after frees with purely safe code in the same way as specializing
//! on traits with methods can.
-use crate::check::regionck::OutlivesEnvironmentExt;
-use crate::check::wfcheck::impl_implied_bounds;
use crate::constrained_generic_params as cgp;
use crate::errors::SubstsOnOverriddenImpl;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::specialization_graph::Node;
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
use rustc_span::Span;
-use rustc_trait_selection::traits::{self, translate_substs, wf};
+use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
+use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
+use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
- tcx.infer_ctxt().enter(|infcx| {
- check_always_applicable(&infcx, impl_def_id, node);
- });
+ check_always_applicable(tcx, impl_def_id, node);
}
}
@@ -105,16 +103,14 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti
}
/// Check that `impl1` is a sound specialization
-fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId, impl2_node: Node) {
- if let Some((impl1_substs, impl2_substs)) = get_impl_substs(infcx, impl1_def_id, impl2_node) {
+fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) {
+ if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) {
let impl2_def_id = impl2_node.def_id();
debug!(
"check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",
impl1_def_id, impl2_def_id, impl2_substs
);
- let tcx = infcx.tcx;
-
let parent_substs = if impl2_node.is_from_trait() {
impl2_substs.to_vec()
} else {
@@ -124,7 +120,7 @@ fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId,
let span = tcx.def_span(impl1_def_id);
check_static_lifetimes(tcx, &parent_substs, span);
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
- check_predicates(infcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
+ check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
}
}
@@ -139,32 +135,38 @@ fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId,
///
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
fn get_impl_substs<'tcx>(
- infcx: &InferCtxt<'_, 'tcx>,
+ tcx: TyCtxt<'tcx>,
impl1_def_id: LocalDefId,
impl2_node: Node,
) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {
- let tcx = infcx.tcx;
- let param_env = tcx.param_env(impl1_def_id);
+ tcx.infer_ctxt().enter(|ref infcx| {
+ let ocx = ObligationCtxt::new(infcx);
+ let param_env = tcx.param_env(impl1_def_id);
+ let impl1_hir_id = tcx.hir().local_def_id_to_hir_id(impl1_def_id);
- let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
- let impl2_substs =
- translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
+ let assumed_wf_types =
+ ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id);
- let mut outlives_env = OutlivesEnvironment::new(param_env);
- let implied_bounds =
- impl_implied_bounds(infcx.tcx, param_env, impl1_def_id, tcx.def_span(impl1_def_id));
- outlives_env.add_implied_bounds(
- infcx,
- implied_bounds,
- tcx.hir().local_def_id_to_hir_id(impl1_def_id),
- );
- infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
- let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
- let span = tcx.def_span(impl1_def_id);
- tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
- return None;
- };
- Some((impl1_substs, impl2_substs))
+ let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
+ let impl2_substs =
+ translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
+
+ let errors = ocx.select_all_or_error();
+ if !errors.is_empty() {
+ ocx.infcx.report_fulfillment_errors(&errors, None, false);
+ return None;
+ }
+
+ let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_hir_id, assumed_wf_types);
+ let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
+ infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
+ let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
+ let span = tcx.def_span(impl1_def_id);
+ tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
+ return None;
+ };
+ Some((impl1_substs, impl2_substs))
+ })
}
/// Returns a list of all of the unconstrained subst of the given impl.
@@ -279,14 +281,13 @@ fn check_static_lifetimes<'tcx>(
/// * a well-formed predicate of a type argument of the trait being implemented,
/// including the `Self`-type.
fn check_predicates<'tcx>(
- infcx: &InferCtxt<'_, 'tcx>,
+ tcx: TyCtxt<'tcx>,
impl1_def_id: LocalDefId,
impl1_substs: SubstsRef<'tcx>,
impl2_node: Node,
impl2_substs: SubstsRef<'tcx>,
span: Span,
) {
- let tcx = infcx.tcx;
let instantiated = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
let impl1_predicates: Vec<_> = traits::elaborate_predicates_with_span(
tcx,
@@ -343,19 +344,23 @@ fn check_predicates<'tcx>(
// Include the well-formed predicates of the type parameters of the impl.
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs {
- if let Some(obligations) = wf::obligations(
- infcx,
- tcx.param_env(impl1_def_id),
- tcx.hir().local_def_id_to_hir_id(impl1_def_id),
- 0,
- arg,
- span,
- ) {
+ tcx.infer_ctxt().enter(|ref infcx| {
+ let obligations = wf::obligations(
+ infcx,
+ tcx.param_env(impl1_def_id),
+ tcx.hir().local_def_id_to_hir_id(impl1_def_id),
+ 0,
+ arg,
+ span,
+ )
+ .unwrap();
+
+ assert!(!obligations.needs_infer());
impl2_predicates.extend(
traits::elaborate_obligations(tcx, obligations)
.map(|obligation| obligation.predicate),
)
- }
+ })
}
impl2_predicates.extend(
traits::elaborate_predicates_with_span(tcx, always_applicable_traits)
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index f98ae46c5..b1ce972e1 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -64,15 +64,16 @@ This API is completely unstable and subject to change.
#![feature(if_let_guard)]
#![feature(is_sorted)]
#![feature(iter_intersperse)]
-#![feature(label_break_value)]
+#![cfg_attr(bootstrap, feature(label_break_value))]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(once_cell)]
#![feature(slice_partition_dedup)]
#![feature(try_blocks)]
#![feature(is_some_with)]
+#![feature(type_alias_impl_trait)]
#![recursion_limit = "256"]
#[macro_use]
@@ -104,7 +105,6 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{Node, CRATE_HIR_ID};
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
-use rustc_infer::traits::TraitEngineExt as _;
use rustc_middle::middle;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -112,11 +112,8 @@ use rustc_middle::util;
use rustc_session::config::EntryFnType;
use rustc_span::{symbol::sym, Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
-use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
-use rustc_trait_selection::traits::{
- self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt as _,
-};
+use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use std::iter;
@@ -148,18 +145,15 @@ fn require_same_types<'tcx>(
) -> bool {
tcx.infer_ctxt().enter(|ref infcx| {
let param_env = ty::ParamEnv::empty();
- let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
- match infcx.at(cause, param_env).eq(expected, actual) {
- Ok(InferOk { obligations, .. }) => {
- fulfill_cx.register_predicate_obligations(infcx, obligations);
- }
+ let errors = match infcx.at(cause, param_env).eq(expected, actual) {
+ Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
Err(err) => {
infcx.report_mismatched_types(cause, expected, actual, err).emit();
return false;
}
- }
+ };
- match fulfill_cx.select_all_or_error(infcx).as_slice() {
+ match &errors[..] {
[] => true,
errors => {
infcx.report_fulfillment_errors(errors, None, false);
@@ -303,7 +297,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
}
let expected_return_type;
- if let Some(term_id) = tcx.lang_items().termination() {
+ if let Some(term_did) = tcx.lang_items().termination() {
let return_ty = main_fnsig.output();
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
if !return_ty.bound_vars().is_empty() {
@@ -314,33 +308,17 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
}
let return_ty = return_ty.skip_binder();
tcx.infer_ctxt().enter(|infcx| {
+ // Main should have no WC, so empty param env is OK here.
+ let param_env = ty::ParamEnv::empty();
let cause = traits::ObligationCause::new(
return_ty_span,
main_diagnostics_hir_id,
ObligationCauseCode::MainFunctionType,
);
- let mut fulfillment_cx = traits::FulfillmentContext::new();
- // normalize any potential projections in the return type, then add
- // any possible obligations to the fulfillment context.
- // HACK(ThePuzzlemaker) this feels symptomatic of a problem within
- // checking trait fulfillment, not this here. I'm not sure why it
- // works in the example in `fn test()` given in #88609? This also
- // probably isn't the best way to do this.
- let InferOk { value: norm_return_ty, obligations } = infcx
- .partially_normalize_associated_types_in(
- cause.clone(),
- ty::ParamEnv::empty(),
- return_ty,
- );
- fulfillment_cx.register_predicate_obligations(&infcx, obligations);
- fulfillment_cx.register_bound(
- &infcx,
- ty::ParamEnv::empty(),
- norm_return_ty,
- term_id,
- cause,
- );
- let errors = fulfillment_cx.select_all_or_error(&infcx);
+ let ocx = traits::ObligationCtxt::new(&infcx);
+ let norm_return_ty = ocx.normalize(cause.clone(), param_env, return_ty);
+ ocx.register_bound(cause, param_env, norm_return_ty, term_did);
+ let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
error = true;
@@ -466,7 +444,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
fn check_for_entry_fn(tcx: TyCtxt<'_>) {
match tcx.entry_fn(()) {
- Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id),
+ Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
_ => {}
}
diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs
index 8fa65d51e..e50c26765 100644
--- a/compiler/rustc_typeck/src/outlives/mod.rs
+++ b/compiler/rustc_typeck/src/outlives/mod.rs
@@ -9,7 +9,6 @@ use rustc_span::Span;
mod explicit;
mod implicit_infer;
-pub(crate) mod outlives_bounds;
/// Code to write unit test for outlives.
pub mod test;
mod utils;
diff --git a/compiler/rustc_typeck/src/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs
index b718ca942..3e8d023fb 100644
--- a/compiler/rustc_typeck/src/outlives/utils.rs
+++ b/compiler/rustc_typeck/src/outlives/utils.rs
@@ -161,12 +161,6 @@ fn is_free_region(region: Region<'_>) -> bool {
// ignore it. We can't put it on the struct header anyway.
ty::ReLateBound(..) => false,
- // This can appear in `where Self: ` bounds (#64855):
- //
- // struct Bar<T>(<Self as Foo>::Type) where Self: ;
- // struct Baz<'a>(&'a Self) where Self: ;
- ty::ReEmpty(_) => false,
-
// These regions don't appear in types from type declarations:
ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
bug!("unexpected region in outlives inference: {:?}", region);
diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index 99729391e..435912464 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -4,7 +4,6 @@ use rustc_errors::{
MultiSpan,
};
use rustc_hir as hir;
-use rustc_middle::hir::map::fn_sig;
use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
use rustc_session::Session;
use rustc_span::def_id::DefId;
@@ -292,62 +291,60 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
// Creates lifetime name suggestions from the lifetime parameter names
fn get_lifetime_args_suggestions_from_param_names(
&self,
- path_hir_id: Option<hir::HirId>,
+ path_hir_id: hir::HirId,
num_params_to_take: usize,
) -> String {
debug!(?path_hir_id);
- if let Some(path_hir_id) = path_hir_id {
- let mut ret = Vec::new();
- for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
- debug!(?id);
- let params = if let Some(generics) = node.generics() {
- generics.params
- } else if let hir::Node::Ty(ty) = node
- && let hir::TyKind::BareFn(bare_fn) = ty.kind
- {
- bare_fn.generic_params
- } else {
- &[]
- };
- ret.extend(params.iter().filter_map(|p| {
- let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
- = p.kind
- else { return None };
- let hir::ParamName::Plain(name) = p.name else { return None };
- Some(name.to_string())
- }));
- // Suggest `'static` when in const/static item-like.
- if let hir::Node::Item(hir::Item {
- kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
- ..
- })
- | hir::Node::TraitItem(hir::TraitItem {
- kind: hir::TraitItemKind::Const { .. },
- ..
- })
- | hir::Node::ImplItem(hir::ImplItem {
- kind: hir::ImplItemKind::Const { .. },
- ..
- })
- | hir::Node::ForeignItem(hir::ForeignItem {
- kind: hir::ForeignItemKind::Static { .. },
- ..
- })
- | hir::Node::AnonConst(..) = node
- {
- ret.extend(
- std::iter::repeat("'static".to_owned())
- .take(num_params_to_take.saturating_sub(ret.len())),
- );
- }
- if ret.len() >= num_params_to_take {
- return ret[..num_params_to_take].join(", ");
- }
- // We cannot refer to lifetimes defined in an outer function.
- if let hir::Node::Item(_) = node {
- break;
- }
+ let mut ret = Vec::new();
+ for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
+ debug!(?id);
+ let params = if let Some(generics) = node.generics() {
+ generics.params
+ } else if let hir::Node::Ty(ty) = node
+ && let hir::TyKind::BareFn(bare_fn) = ty.kind
+ {
+ bare_fn.generic_params
+ } else {
+ &[]
+ };
+ ret.extend(params.iter().filter_map(|p| {
+ let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
+ = p.kind
+ else { return None };
+ let hir::ParamName::Plain(name) = p.name else { return None };
+ Some(name.to_string())
+ }));
+ // Suggest `'static` when in const/static item-like.
+ if let hir::Node::Item(hir::Item {
+ kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
+ ..
+ })
+ | hir::Node::TraitItem(hir::TraitItem {
+ kind: hir::TraitItemKind::Const { .. },
+ ..
+ })
+ | hir::Node::ImplItem(hir::ImplItem {
+ kind: hir::ImplItemKind::Const { .. },
+ ..
+ })
+ | hir::Node::ForeignItem(hir::ForeignItem {
+ kind: hir::ForeignItemKind::Static { .. },
+ ..
+ })
+ | hir::Node::AnonConst(..) = node
+ {
+ ret.extend(
+ std::iter::repeat("'static".to_owned())
+ .take(num_params_to_take.saturating_sub(ret.len())),
+ );
+ }
+ if ret.len() >= num_params_to_take {
+ return ret[..num_params_to_take].join(", ");
+ }
+ // We cannot refer to lifetimes defined in an outer function.
+ if let hir::Node::Item(_) = node {
+ break;
}
}
@@ -368,7 +365,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
&self,
num_params_to_take: usize,
) -> String {
- let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(fn_sig);
+ let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(hir::Node::fn_sig);
let is_used_in_input = |def_id| {
fn_sig.map_or(false, |fn_sig| {
fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
@@ -524,6 +521,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
if self.not_enough_args_provided() {
self.suggest_adding_args(err);
} else if self.too_many_args_provided() {
+ self.suggest_moving_args_from_assoc_fn_to_trait(err);
self.suggest_removing_args_or_generics(err);
} else {
unreachable!();
@@ -654,6 +652,144 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
}
+ /// Suggests moving redundant argument(s) of an associate function to the
+ /// trait it belongs to.
+ ///
+ /// ```compile_fail
+ /// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)`
+ /// ```
+ fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut Diagnostic) {
+ let trait_ = match self.tcx.trait_of_item(self.def_id) {
+ Some(def_id) => def_id,
+ None => return,
+ };
+
+ // Skip suggestion when the associated function is itself generic, it is unclear
+ // how to split the provided parameters between those to suggest to the trait and
+ // those to remain on the associated type.
+ let num_assoc_fn_expected_args =
+ self.num_expected_type_or_const_args() + self.num_expected_lifetime_args();
+ if num_assoc_fn_expected_args > 0 {
+ return;
+ }
+
+ let num_assoc_fn_excess_args =
+ self.num_excess_type_or_const_args() + self.num_excess_lifetime_args();
+
+ let trait_generics = self.tcx.generics_of(trait_);
+ let num_trait_generics_except_self =
+ trait_generics.count() - if trait_generics.has_self { 1 } else { 0 };
+
+ let msg = format!(
+ "consider moving {these} generic argument{s} to the `{name}` trait, which takes up to {num} argument{s}",
+ these = pluralize!("this", num_assoc_fn_excess_args),
+ s = pluralize!(num_assoc_fn_excess_args),
+ name = self.tcx.item_name(trait_),
+ num = num_trait_generics_except_self,
+ );
+
+ if let Some(parent_node) = self.tcx.hir().find_parent_node(self.path_segment.hir_id)
+ && let Some(parent_node) = self.tcx.hir().find(parent_node)
+ && let hir::Node::Expr(expr) = parent_node {
+ match expr.kind {
+ hir::ExprKind::Path(ref qpath) => {
+ self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
+ err,
+ qpath,
+ msg,
+ num_assoc_fn_excess_args,
+ num_trait_generics_except_self
+ )
+ },
+ hir::ExprKind::MethodCall(..) => {
+ self.suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
+ err,
+ trait_,
+ expr,
+ msg,
+ num_assoc_fn_excess_args,
+ num_trait_generics_except_self
+ )
+ },
+ _ => return,
+ }
+ }
+ }
+
+ fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
+ &self,
+ err: &mut Diagnostic,
+ qpath: &'tcx hir::QPath<'tcx>,
+ msg: String,
+ num_assoc_fn_excess_args: usize,
+ num_trait_generics_except_self: usize,
+ ) {
+ if let hir::QPath::Resolved(_, path) = qpath
+ && let Some(trait_path_segment) = path.segments.get(0) {
+ let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
+
+ if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
+ if let Some(span) = self.gen_args.span_ext()
+ && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
+ let sugg = vec![
+ (self.path_segment.ident.span, format!("{}::{}", snippet, self.path_segment.ident)),
+ (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned())
+ ];
+
+ err.multipart_suggestion(
+ msg,
+ sugg,
+ Applicability::MaybeIncorrect
+ );
+ }
+ }
+ }
+ }
+
+ fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
+ &self,
+ err: &mut Diagnostic,
+ trait_def_id: DefId,
+ expr: &'tcx hir::Expr<'tcx>,
+ msg: String,
+ num_assoc_fn_excess_args: usize,
+ num_trait_generics_except_self: usize,
+ ) {
+ let sm = self.tcx.sess.source_map();
+ let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return; };
+ if num_assoc_fn_excess_args != num_trait_generics_except_self {
+ return;
+ }
+ let Some(gen_args) = self.gen_args.span_ext() else { return; };
+ let Ok(generics) = sm.span_to_snippet(gen_args) else { return; };
+ let Ok(rcvr) = sm.span_to_snippet(
+ rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span)
+ ) else { return; };
+ let Ok(rest) =
+ (match args {
+ [] => Ok(String::new()),
+ [arg] => sm.span_to_snippet(
+ arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span),
+ ),
+ [first, .., last] => {
+ let first_span =
+ first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
+ let last_span =
+ last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
+ sm.span_to_snippet(first_span.to(last_span))
+ }
+ }) else { return; };
+ let comma = if args.len() > 0 { ", " } else { "" };
+ let trait_path = self.tcx.def_path_str(trait_def_id);
+ let method_name = self.tcx.item_name(self.def_id);
+ err.span_suggestion(
+ expr.span,
+ msg,
+ format!("{trait_path}::{generics}::{method_name}({rcvr}{comma}{rest})"),
+ Applicability::MaybeIncorrect,
+ );
+ }
+
/// Suggests to remove redundant argument(s):
///
/// ```text
@@ -763,16 +899,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
// If there is a single unbound associated type and a single excess generic param
// suggest replacing the generic param with the associated type bound
if provided_args_matches_unbound_traits && !unbound_types.is_empty() {
- let mut suggestions = vec![];
let unused_generics = &self.gen_args.args[self.num_expected_type_or_const_args()..];
- for (potential, name) in iter::zip(unused_generics, &unbound_types) {
- if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(potential.span()) {
- suggestions.push((potential.span(), format!("{} = {}", name, snippet)));
- }
- }
+ let suggestions = iter::zip(unused_generics, &unbound_types)
+ .map(|(potential, name)| (potential.span().shrink_to_lo(), format!("{name} = ")))
+ .collect::<Vec<_>>();
if !suggestions.is_empty() {
- err.multipart_suggestion(
+ err.multipart_suggestion_verbose(
&format!(
"replace the generic bound{s} with the associated type{s}",
s = pluralize!(unbound_types.len())
diff --git a/compiler/rustc_typeck/src/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs
index d79450e1a..eaf0310d5 100644
--- a/compiler/rustc_typeck/src/variance/constraints.rs
+++ b/compiler/rustc_typeck/src/variance/constraints.rs
@@ -257,7 +257,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_invariant_substs(current, substs, variance);
}
- ty::Dynamic(data, r) => {
+ ty::Dynamic(data, r, _) => {
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let contra = self.contravariant(variance);
self.add_constraints_from_region(current, r, contra);
@@ -271,11 +271,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
for projection in data.projection_bounds() {
- match projection.skip_binder().term {
- ty::Term::Ty(ty) => {
+ match projection.skip_binder().term.unpack() {
+ ty::TermKind::Ty(ty) => {
self.add_constraints_from_ty(current, ty, self.invariant);
}
- ty::Term::Const(c) => {
+ ty::TermKind::Const(c) => {
self.add_constraints_from_const(current, c, self.invariant)
}
}
@@ -411,11 +411,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// way early-bound regions do, so we skip them here.
}
- ty::ReFree(..)
- | ty::ReVar(..)
- | ty::RePlaceholder(..)
- | ty::ReEmpty(_)
- | ty::ReErased => {
+ ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
// We don't expect to see anything but 'static or bound
// regions when visiting member types or method types.
bug!(
diff --git a/config.toml.example b/config.toml.example
index b3284050f..a967d881b 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -666,6 +666,10 @@ changelog-seen = 2
# target.
#llvm-config = <none> (path)
+# Override detection of whether this is a Rust-patched LLVM. This would be used
+# in conjunction with either an llvm-config or build.submodules = false.
+#llvm-has-rust-patches = if llvm-config { false } else { true }
+
# Normally the build system can find LLVM's FileCheck utility, but if
# not, you can specify an explicit file name for it.
#llvm-filecheck = "/path/to/llvm-version/bin/FileCheck"
@@ -721,6 +725,10 @@ changelog-seen = 2
# probably don't want to use this.
#qemu-rootfs = <none> (path)
+# Skip building the `std` library for this target. Enabled by default for
+# target triples containing `-none`, `nvptx`, `switch`, or `-uefi`.
+#no-std = <platform-specific> (bool)
+
# =============================================================================
# Distribution options
#
diff --git a/debian/bin/rust-lld b/debian/bin/rust-lld
index 04aec84b4..285f1b0da 100755
--- a/debian/bin/rust-lld
+++ b/debian/bin/rust-lld
@@ -6,4 +6,4 @@
# However the tests fail for other reasons, namely we can't build rustdoc
# (which runs the tests) in wasm32 yet. So this is just WIP at the moment,
# it is not expect to work nor to be installed on user machines.
-exec /usr/bin/lld-14 "${@/#-Wl,/}"
+exec /usr/bin/lld-15 "${@/#-Wl,/}"
diff --git a/debian/changelog b/debian/changelog
index d3049a1b9..c7354c1e8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,42 @@
+rustc (1.65.0+dfsg1-2) unstable; urgency=medium
+
+ * Team upload
+ * Source-only upload
+
+ -- Jeremy Bícha <jbicha@ubuntu.com> Mon, 26 Jun 2023 17:16:27 -0400
+
+rustc (1.65.0+dfsg1-1) unstable; urgency=medium
+
+ * Upload to unstable
+
+ -- Fabian Grünbichler <debian@fabian.gruenbichler.email> Tue, 20 Jun 2023 20:16:50 +0200
+
+rustc (1.65.0+dfsg1-1~exp3) experimental; urgency=medium
+
+ * d/rules: fix typo in mipsel workaround
+
+ -- Fabian Grünbichler <debian@fabian.gruenbichler.email> Sun, 12 Mar 2023 08:54:15 +0100
+
+rustc (1.65.0+dfsg1-1~exp2) experimental; urgency=medium
+
+ [ Fabian Grünbichler ]
+ * d/control: add myself to Uploaders
+ * cherry-pick fix for failing backtrace test
+ * bump mipsel test failure allowance to work around broken gdb 13.1
+ * drop duplicate lintian override
+
+ -- Fabian Grünbichler <debian@fabian.gruenbichler.email> Sat, 11 Mar 2023 18:50:19 +0100
+
+rustc (1.65.0+dfsg1-1~exp1) experimental; urgency=medium
+
+ [ Fabian Grünbichler ]
+ * New upstream version 1.65.0+dfsg1
+ * switch to LLVM-15
+ * cherry-pick fix for compiletest with rpath=false
+ * add overrides for rust-analyzer test data
+
+ -- Fabian Gruenbichler <debian@fabian.gruenbichler.email> Wed, 15 Feb 2023 20:12:05 +0100
+
rustc (1.64.0+dfsg1-1) unstable; urgency=medium
* Upload to unstable
diff --git a/debian/control b/debian/control
index 2b059591b..29daa47ad 100644
--- a/debian/control
+++ b/debian/control
@@ -14,13 +14,13 @@ Build-Depends:
dpkg-dev (>= 1.17.14),
python3:native,
cargo:native (>= 0.60.0) <!pkg.rustc.dlstage0>,
- rustc:native (>= 1.63.0+dfsg) <!pkg.rustc.dlstage0>,
- rustc:native (<= 1.64.0++) <!pkg.rustc.dlstage0>,
- llvm-14-dev:native,
- llvm-14-tools:native,
+ rustc:native (>= 1.64.0+dfsg) <!pkg.rustc.dlstage0>,
+ rustc:native (<= 1.65.0++) <!pkg.rustc.dlstage0>,
+ llvm-15-dev:native,
+ llvm-15-tools:native,
gcc-mingw-w64-x86-64-posix:native [amd64] <!nowindows>,
gcc-mingw-w64-i686-posix:native [i386] <!nowindows>,
- libllvm14 (>= 1:14.0.0),
+ libllvm15 (>= 1:15.0.0),
cmake (>= 3.0) | cmake3,
# needed by some vendor crates
pkg-config,
@@ -41,7 +41,7 @@ Build-Depends:
Build-Depends-Indep:
wasi-libc (>= 0.0~git20220510.9886d3d~~) <!nowasm>,
wasi-libc (<= 0.0~git20220510.9886d3d++) <!nowasm>,
- clang-14:native,
+ clang-15:native,
Build-Conflicts: gdb-minimal <!nocheck>
Standards-Version: 4.2.1
Homepage: http://www.rust-lang.org/
@@ -56,12 +56,12 @@ Depends: ${shlibs:Depends}, ${misc:Depends},
libstd-rust-dev (= ${binary:Version}),
gcc, libc-dev, binutils (>= 2.26)
Recommends:
- cargo (>= 0.65.0~~), cargo (<< 0.66.0~~),
+ cargo (>= 0.66.0~~), cargo (<< 0.67.0~~),
# llvm is needed for llvm-dwp for -C split-debuginfo=packed
- llvm-14,
+ llvm-15,
Suggests:
# lld and clang are needed for wasm compilation
- lld-14, clang-14,
+ lld-15, clang-15,
Replaces: libstd-rust-dev (<< 1.25.0+dfsg1-2~~)
Breaks: libstd-rust-dev (<< 1.25.0+dfsg1-2~~)
Description: Rust systems programming language
@@ -77,7 +77,7 @@ Description: Rust systems programming language
generic programming and meta-programming, in both static and dynamic
styles.
-Package: libstd-rust-1.64
+Package: libstd-rust-1.65
Section: libs
Architecture: any
Multi-Arch: same
@@ -104,7 +104,7 @@ Section: libdevel
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends},
- libstd-rust-1.64 (= ${binary:Version}),
+ libstd-rust-1.65 (= ${binary:Version}),
Description: Rust standard libraries - development files
Rust is a curly-brace, block-structured expression language. It
visually resembles the C language family, but differs significantly
@@ -156,7 +156,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
# Embeds wasi-libc so doesn't need to depend on it
# None of its licenses require source redistrib, so no need for Built-Using
Recommends:
- lld-14, clang-14,
+ lld-15, clang-15,
Suggests:
# nodejs contains wasi-node for running the program
nodejs (>= 12.16),
@@ -202,7 +202,7 @@ Description: Rust debugger (gdb)
Package: rust-lldb
Architecture: all
# When updating, also update rust-lldb.links
-Depends: lldb-14, ${misc:Depends}, python3-lldb-14
+Depends: lldb-15, ${misc:Depends}, python3-lldb-15
Replaces: rustc (<< 1.1.0+dfsg1-1)
Description: Rust debugger (lldb)
Rust is a curly-brace, block-structured expression language. It
@@ -267,7 +267,7 @@ Package: rust-clippy
Architecture: any
Multi-Arch: allowed
Depends: ${misc:Depends}, ${shlibs:Depends},
- libstd-rust-1.64 (= ${binary:Version})
+ libstd-rust-1.65 (= ${binary:Version})
Recommends: cargo
Description: Rust linter
Rust is a curly-brace, block-structured expression language. It
@@ -322,7 +322,7 @@ Depends: ${misc:Depends}, ${shlibs:Depends},
rust-gdb (>= ${binary:Version}) | rust-lldb (>= ${binary:Version}),
cargo,
Recommends:
- cargo (>= 0.65.0~~), cargo (<< 0.66.0~~)
+ cargo (>= 0.66.0~~), cargo (<< 0.67.0~~)
Suggests:
rust-doc (>= ${binary:Version}),
rust-src (>= ${binary:Version}),
diff --git a/debian/copyright b/debian/copyright
index 03380c208..cd920fe5a 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -42,17 +42,16 @@ Files-Excluded:
# unused dependencies, generated by debian/prune-unused-deps
# DO NOT EDIT below, AUTOGENERATED
vendor/ahash-0.7.4
- vendor/anyhow-1.0.56
- vendor/anyhow-1.0.58
+ vendor/anyhow-1.0.60
+ vendor/anyhow-1.0.62
vendor/anymap
vendor/arbitrary
vendor/ar
vendor/arrayvec-0.7.0
- vendor/backtrace-0.3.65
vendor/bitmaps
- vendor/byteorder-1.3.4
+ vendor/byteorder
vendor/bytesize
- vendor/cc-1.0.69
+ vendor/camino-1.0.9
vendor/chalk-derive
vendor/chalk-ir
vendor/chalk-recursive
@@ -79,16 +78,18 @@ Files-Excluded:
vendor/cranelift-module
vendor/cranelift-native
vendor/cranelift-object
+ vendor/crossbeam
vendor/crossbeam-channel-0.5.4
+ vendor/crossbeam-deque-0.8.1
vendor/crossbeam-epoch-0.9.6
vendor/crossbeam-epoch-0.9.8
+ vendor/crossbeam-queue
vendor/crossbeam-utils-0.8.8
vendor/crypto-common-0.1.2
vendor/crypto-hash
vendor/curl
vendor/curl-sys
vendor/derive_arbitrary
- vendor/derive_more
vendor/diff-0.1.12
vendor/difference
vendor/digest-0.10.2
@@ -109,43 +110,36 @@ Files-Excluded:
vendor/fsevent-sys
vendor/fs_extra-1.1.0
vendor/fs_extra
- vendor/fst-0.4.5
vendor/fst
- vendor/futures-0.1.31
vendor/fwdansi
vendor/fxhash
vendor/generic-array-0.14.4
vendor/getrandom-0.2.0
vendor/getset
+ vendor/gimli-0.26.1
vendor/git2
vendor/git2-curl
vendor/globset-0.4.8
- vendor/hashbrown-0.11.2
- vendor/hashbrown-0.12.1
vendor/heck-0.3.3
vendor/hex-0.3.2
vendor/hex-0.4.2
- vendor/idna-0.1.5
vendor/idna-0.2.0
vendor/im-rc
vendor/indenter
vendor/inotify
vendor/inotify-sys
vendor/itertools-0.10.1
+ vendor/itoa-1.0.2
vendor/jemalloc-sys
vendor/jod-thread
- vendor/json
- vendor/jsonrpc-client-transports
- vendor/jsonrpc-core
- vendor/jsonrpc-core-client
- vendor/jsonrpc-derive
- vendor/jsonrpc-ipc-server
- vendor/jsonrpc-pubsub
- vendor/jsonrpc-server-utils
vendor/kqueue
vendor/kqueue-sys
vendor/kstring
- vendor/lazycell
+ vendor/libc-0.2.126
+ vendor/libc-0.2.127
+ vendor/libc-0.2.131
+ vendor/libffi
+ vendor/libffi-sys
vendor/libgit2-sys
vendor/libloading-0.6.7
vendor/libloading-0.7.1
@@ -155,64 +149,55 @@ Files-Excluded:
vendor/libz-sys
vendor/linked-hash-map
vendor/log-0.4.14
- vendor/lsp-codec
- vendor/lsp-types-0.60.0
vendor/lzma-sys-0.1.16
vendor/mach
vendor/matches-0.1.8
- vendor/memchr-2.4.1
vendor/mimalloc
- vendor/mio-0.7.14
vendor/mio
vendor/normalize-line-endings
vendor/notify
- vendor/ntapi-0.3.6
- vendor/object-0.28.4
- vendor/once_cell-1.10.0
vendor/once_cell-1.12.0
+ vendor/once_cell-1.13.0
vendor/oorandom
vendor/openssl
vendor/openssl-probe
vendor/openssl-src
vendor/openssl-sys
- vendor/ordslice
vendor/os_info
vendor/owo-colors
- vendor/parity-tokio-ipc
vendor/paste
- vendor/percent-encoding-1.0.1
vendor/pin-project-lite-0.2.8
vendor/pkg-config-0.3.18
- vendor/pretty_assertions
vendor/pretty_env_logger
vendor/proc-macro2-1.0.37
vendor/proc-macro2-1.0.39
- vendor/proc-macro-crate
- vendor/pulldown-cmark-0.9.1
+ vendor/protobuf
+ vendor/protobuf-support
vendor/pulldown-cmark-to-cmark
vendor/quote-1.0.18
- vendor/rand_xoshiro-0.4.0
vendor/redox_syscall-0.2.10
+ vendor/redox_syscall-0.2.13
vendor/regalloc2
+ vendor/regex-1.5.6
+ vendor/regex-syntax-0.6.26
vendor/region
- vendor/rls-vfs
vendor/rustc_version
+ vendor/ryu-1.0.10
vendor/ryu-1.0.5
vendor/salsa
vendor/salsa-macros
vendor/schannel
+ vendor/scip
vendor/security-framework
vendor/security-framework-sys
+ vendor/semver-1.0.12
vendor/serde-1.0.137
- vendor/serde-1.0.138
vendor/serde_derive-1.0.137
- vendor/serde_derive-1.0.138
vendor/serde_ignored
vendor/serde_json-1.0.81
- vendor/serde_repr-0.1.6
+ vendor/serde_json-1.0.83
vendor/sha2-0.10.1
vendor/sharded-slab-0.1.1
- vendor/signal-hook-registry
vendor/similar
vendor/sized-chunks
vendor/slice-group-by
@@ -226,31 +211,29 @@ Files-Excluded:
vendor/syn-1.0.91
vendor/syn-1.0.95
vendor/target-lexicon
+ vendor/thiserror-1.0.31
+ vendor/thiserror-impl-1.0.31
vendor/threadpool
vendor/tikv-jemallocator
vendor/tikv-jemalloc-ctl
vendor/tikv-jemalloc-sys
vendor/tinyvec-0.3.4
- vendor/tokio-stream
- vendor/tokio-util
vendor/toml-0.5.7
vendor/toml_edit
- vendor/tower-service
- vendor/tracing-0.1.29
- vendor/tracing-attributes-0.1.18
- vendor/tracing-core-0.1.21
+ vendor/tracing-0.1.35
+ vendor/tracing-core-0.1.28
vendor/tracing-error
vendor/tracing-log-0.1.2
vendor/tracing-subscriber-0.3.3
vendor/tracing-tree-0.2.0
vendor/typed-arena
vendor/typenum-1.12.0
+ vendor/ui_test
vendor/unicode-bidi-0.3.4
vendor/unicode-ident-1.0.0
vendor/unicode-normalization-0.1.13
vendor/unicode-width-0.1.8
vendor/unicode-xid-0.2.2
- vendor/url-1.7.2
vendor/utf8parse
vendor/vcpkg
vendor/vergen
@@ -460,7 +443,6 @@ Comment: see https://github.com/notriddle/ammonia
Files:
vendor/annotate-snippets/*
- vendor/annotate-snippets-0.8.0/*
Copyright: 2018-2020 Zibi Braniecki <gandalf@mozilla.com>
License: Apache-2.0 or MIT
Comment: see https://github.com/zbraniecki/annotate-snippets-rs
@@ -503,15 +485,8 @@ Comment: see https://github.com/rust-lang/backtrace-rs
Files:
vendor/block-buffer/*
- vendor/block-buffer-0*/*
- vendor/block-padding/*
- vendor/byte-tools/*
vendor/digest/*
- vendor/digest-0*/*
- vendor/fake-simd/*
vendor/md-5/*
- vendor/opaque-debug/*
- vendor/sha-1-0*/*
vendor/sha-1/*
vendor/sha2/*
Copyright: 2016-2020 RustCrypto Developers
@@ -533,7 +508,6 @@ License: Apache-2.0 or MIT
Comment: see https://github.com/llogiq/bytecount
Files:
- vendor/byteorder/*
vendor/globset/*
vendor/ignore/*
vendor/same-file/*
@@ -543,7 +517,6 @@ Files:
Copyright: 2015-2020 Andrew Gallant <jamslam@gmail.com>
License: Unlicense or MIT
Comment:
- see https://github.com/BurntSushi/byteorder
see https://github.com/BurntSushi/same-file
see https://github.com/BurntSushi/walkdir
see https://github.com/BurntSushi/winapi-util
@@ -625,11 +598,9 @@ License: MIT OR Apache-2.0
Comment: see https://github.com/srijs/rust-crc32fast
Files:
- vendor/crossbeam/*
vendor/crossbeam-channel/*
vendor/crossbeam-deque/*
vendor/crossbeam-epoch/*
- vendor/crossbeam-queue/*
vendor/crossbeam-utils/*
Copyright: 2015-2022 The Crossbeam Project Developers
License: MIT or Apache-2.0
@@ -791,7 +762,6 @@ Comment: see https://github.com/servo/futf
Files:
vendor/generic-array/*
- vendor/generic-array-0*/*
Copyright:
2015-2020 Bartłomiej Kamiński <fizyk20@gmail.com>
2015-2020 Aaron Trent <novacrazy@gmail.com>
@@ -903,6 +873,12 @@ Copyright: 2018-2021 Changseok Han <freestrings@gmail.com>
License: MIT
Comment: see https://github.com/freestrings/jsonpath
+Files: vendor/lazycell/*
+Copyright: 2016-2020 Alex Crichton <alex@alexcrichton.com>
+ 2016-2020 Nikita Pekin <contact@nikitapek.in>
+License: MIT or Apache-2.0
+Comment: see https://github.com/indiv0/lazycell
+
Files: vendor/lazy_static/*
Copyright: 2014-2018 Marvin Löbel <loebel.marvin@gmail.com>
License: MIT or Apache-2.0
@@ -1117,7 +1093,7 @@ Copyright: 2017-2017 Emilio Cobos Ãlvarez <emilio@crisal.io>
License: MIT
Comment: see https://github.com/emilio/precomputed-hash
-Files: vendor/pretty_assertions-0.7.2/*
+Files: vendor/pretty_assertions/*
Copyright: 2017-2022 Colin Kiegel <kiegel@gmx.de>
2017-2022 Florent Fayolle <florent.fayolle69@gmail.com>
2017-2022 Tom Milligan <code@tommilligan.net>
@@ -1153,7 +1129,6 @@ Comment: see https://github.com/mcarton/rust-punycode.git
Files:
vendor/quick-error/*
- vendor/quick-error-1*/*
Copyright:
2015-2020 Paul Colomiets <paul@colomiets.name>
2015-2020 Colin Kiegel <kiegel@gmx.de>
@@ -1221,11 +1196,6 @@ Copyright: 2020-2020 flip1995 <hello@philkrones.com>
License: MIT OR Apache-2.0
Comment: see https://github.com/flip1995/rustc-semver
-Files: vendor/rustc_tools_util/*
-Copyright: 2014-2021 Matthias Krüger <matthias.krueger@famsik.de>
-License: MIT or Apache-2.0
-Comment: see https://github.com/rust-lang/rust-clippy
-
Files: vendor/rustfix/*
Copyright:
2016-2021 Pascal Hertleif <killercup@gmail.com>
@@ -1371,17 +1341,22 @@ Copyright: 2016-2020 Yuki Okushi <huyuumi.dev@gmail.com>
License: MIT or Apache-2.0
Comment: see https://github.com/JohnTitor/termize
-Files: vendor/textwrap/*
-Copyright: 2016-2022 Martin Geisler <martin@geisler.net>
-License: MIT
-Comment: see https://github.com/mgeisler/textwrap
-
Files: vendor/text-size/*
Copyright: 2018-2021 Aleksey Kladov <aleksey.kladov@gmail.com>
2018-2021 Christopher Durham (CAD97) <cad97@cad97.com>
License: MIT OR Apache-2.0
Comment: see https://github.com/rust-analyzer/text-size
+Files: vendor/textwrap/*
+Copyright: 2016-2022 Martin Geisler <martin@geisler.net>
+License: MIT
+Comment: see https://github.com/mgeisler/textwrap
+
+Files: vendor/thin-vec/*
+Copyright: 2017-2022 Aria Beingessner <a.beingessner@gmail.com>
+License: MIT or Apache-2.0
+Comment: see https://github.com/gankra/thin-vec
+
Files:
vendor/thiserror/*
vendor/thiserror-impl/*
@@ -1619,11 +1594,6 @@ Copyright: 2019-2022 The Cranelift Project Developers
License: Apache-2.0 with LLVM exception OR Apache-2.0 OR MIT
Comment: see https://github.com/bytecodealliance/wasi
-Files: vendor/wasi-0.10.2+wasi-snapshot-preview1/*
-Copyright: 2019-2022 The Cranelift Project Developers
-License: Apache-2.0 with LLVM exception OR Apache-2.0 OR MIT
-Comment: see https://github.com/bytecodealliance/wasi
-
Files:
vendor/windows_aarch64_msvc/*
vendor/windows_i686_gnu/*
diff --git a/debian/libstd-rust-1.64.lintian-overrides b/debian/libstd-rust-1.64.lintian-overrides
deleted file mode 100644
index 1a992afe2..000000000
--- a/debian/libstd-rust-1.64.lintian-overrides
+++ /dev/null
@@ -1,13 +0,0 @@
-# "libstd" just seemed too generic
-libstd-rust-1.64 binary: package-name-doesnt-match-sonames
-libstd-rust-1.64 binary: sharedobject-in-library-directory-missing-soname
-
-# Rust doesn't use dev shlib symlinks nor any of the other shlib support stuff
-libstd-rust-1.64 binary: dev-pkg-without-shlib-symlink
-libstd-rust-1.64 binary: shlib-without-versioned-soname
-libstd-rust-1.64 binary: unused-shlib-entry-in-control-file
-
-# Libraries that use libc symbols (libterm, libstd, etc) *are* linked
-# to libc. Lintian gets upset that some Rust libraries don't need
-# libc, boo hoo.
-libstd-rust-1.64 binary: library-not-linked-against-libc
diff --git a/debian/libstd-rust-1.64.install b/debian/libstd-rust-1.65.install
index cd4545cca..cd4545cca 100644
--- a/debian/libstd-rust-1.64.install
+++ b/debian/libstd-rust-1.65.install
diff --git a/debian/libstd-rust-1.65.lintian-overrides b/debian/libstd-rust-1.65.lintian-overrides
new file mode 100644
index 000000000..3218caec4
--- /dev/null
+++ b/debian/libstd-rust-1.65.lintian-overrides
@@ -0,0 +1,13 @@
+# "libstd" just seemed too generic
+libstd-rust-1.65 binary: package-name-doesnt-match-sonames
+libstd-rust-1.65 binary: sharedobject-in-library-directory-missing-soname
+
+# Rust doesn't use dev shlib symlinks nor any of the other shlib support stuff
+libstd-rust-1.65 binary: dev-pkg-without-shlib-symlink
+libstd-rust-1.65 binary: shlib-without-versioned-soname
+libstd-rust-1.65 binary: unused-shlib-entry-in-control-file
+
+# Libraries that use libc symbols (libterm, libstd, etc) *are* linked
+# to libc. Lintian gets upset that some Rust libraries don't need
+# libc, boo hoo.
+libstd-rust-1.65 binary: library-not-linked-against-libc
diff --git a/debian/patches/d-0000-ignore-removed-submodules.patch b/debian/patches/d-0000-ignore-removed-submodules.patch
index 3dfaf06cb..26d1e4361 100644
--- a/debian/patches/d-0000-ignore-removed-submodules.patch
+++ b/debian/patches/d-0000-ignore-removed-submodules.patch
@@ -3,21 +3,22 @@ Date: Sat, 2 Oct 2021 01:07:59 +0100
Subject: d-0000-ignore-removed-submodules
---
- Cargo.toml | 36 ++++++++----------------------------
- src/bootstrap/bootstrap.py | 4 ----
- src/bootstrap/builder.rs | 7 +------
- src/bootstrap/doc.rs | 1 -
- src/bootstrap/test.rs | 12 +-----------
- src/tools/clippy/Cargo.toml | 5 -----
- src/tools/rustfmt/Cargo.toml | 5 -----
- src/tools/tidy/src/deps.rs | 2 +-
- 8 files changed, 11 insertions(+), 61 deletions(-)
+ Cargo.toml | 15 ---------------
+ src/bootstrap/bootstrap.py | 4 ----
+ src/bootstrap/builder.rs | 11 +----------
+ src/bootstrap/doc.rs | 1 -
+ src/bootstrap/test.rs | 12 +-----------
+ src/tools/clippy/Cargo.toml | 5 -----
+ src/tools/rust-analyzer/Cargo.toml | 11 ++++++++++-
+ src/tools/rustfmt/Cargo.toml | 5 -----
+ src/tools/tidy/src/deps.rs | 2 +-
+ 9 files changed, 13 insertions(+), 53 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
-index ffc886d..7231b60 100644
+index e49fe5e..863c800 100644
--- a/Cargo.toml
+++ b/Cargo.toml
-@@ -16,25 +16,14 @@ members = [
+@@ -16,27 +16,15 @@ members = [
"src/tools/tidy",
"src/tools/tier-check",
"src/tools/build-manifest",
@@ -38,38 +39,16 @@ index ffc886d..7231b60 100644
"src/tools/unicode-table-generator",
- "src/tools/expand-yaml-anchors",
"src/tools/jsondocck",
+ "src/tools/jsondoclint",
"src/tools/html-checker",
- "src/tools/bump-stage0",
+- "src/tools/replace-version-placeholder",
"src/tools/lld-wrapper",
]
-@@ -96,25 +85,16 @@ gimli.debug = 0
- miniz_oxide.debug = 0
+@@ -99,9 +87,6 @@ miniz_oxide.debug = 0
object.debug = 0
--# We want the RLS to use the version of Cargo that we've got vendored in this
--# repository to ensure that the same exact version of Cargo is used by both the
--# RLS and the Cargo binary itself. The RLS depends on Cargo as a git repository
--# so we use a `[patch]` here to override the github repository with our local
--# vendored copy.
--[patch."https://github.com/rust-lang/cargo"]
--cargo = { path = "src/tools/cargo" }
--cargo-util = { path = "src/tools/cargo/crates/cargo-util" }
--
--[patch."https://github.com/rust-lang/rustfmt"]
--# Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
--# that we're shipping as well (to ensure that the rustfmt in RLS and the
--# `rustfmt` executable are the same exact version).
--rustfmt-nightly = { path = "src/tools/rustfmt" }
-+# The only package that ever uses debug builds is bootstrap.
-+# We care a lot about bootstrap's compile times, so don't include debug info for
-+# dependencies, only bootstrap itself.
-+[profile.dev]
-+debug = 0
-+[profile.dev.package]
-+# Only use debuginfo=1 to further reduce compile times.
-+bootstrap.debug = 1
-
[patch.crates-io]
-# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
-# here
@@ -78,7 +57,7 @@ index ffc886d..7231b60 100644
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on
# here
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
-index 03eec02..c40811f 100644
+index cc08ae5..bf7d696 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -759,10 +759,6 @@ class RustBuild(object):
@@ -93,34 +72,36 @@ index 03eec02..c40811f 100644
args.append("--features")
args.append("build-metrics")
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
-index 0ab4824..629e1bb 100644
+index 14e8ebd..6d43333 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
-@@ -600,7 +600,6 @@ impl<'a> Builder<'a> {
+@@ -600,8 +600,6 @@ impl<'a> Builder<'a> {
+ tool::RemoteTestClient,
tool::RustInstaller,
tool::Cargo,
- tool::Rls,
+- tool::Rls,
- tool::RustAnalyzer,
tool::RustAnalyzerProcMacroSrv,
tool::RustDemangler,
tool::Rustdoc,
-@@ -622,7 +620,6 @@ impl<'a> Builder<'a> {
+@@ -622,8 +621,6 @@ impl<'a> Builder<'a> {
+ check::CodegenBackend,
check::Clippy,
check::Miri,
- check::Rls,
+- check::Rls,
- check::RustAnalyzer,
check::Rustfmt,
check::Bootstrap
),
-@@ -650,7 +647,6 @@ impl<'a> Builder<'a> {
+@@ -650,7 +648,6 @@ impl<'a> Builder<'a> {
+ test::ReplacePlaceholderTest,
test::Cargotest,
test::Cargo,
- test::Rls,
- test::RustAnalyzer,
test::ErrorIndex,
test::Distcheck,
test::RunMakeFullDeps,
-@@ -698,10 +694,8 @@ impl<'a> Builder<'a> {
+@@ -698,10 +695,8 @@ impl<'a> Builder<'a> {
doc::RustdocBook,
doc::RustByExample,
doc::RustcBook,
@@ -131,7 +112,15 @@ index 0ab4824..629e1bb 100644
doc::EmbeddedBook,
doc::EditionGuide,
),
-@@ -723,7 +717,6 @@ impl<'a> Builder<'a> {
+@@ -715,15 +712,12 @@ impl<'a> Builder<'a> {
+ dist::Analysis,
+ dist::Src,
+ dist::Cargo,
+- dist::Rls,
+- dist::RustAnalyzer,
+ dist::Rustfmt,
+ dist::RustDemangler,
+ dist::Clippy,
dist::Miri,
dist::LlvmTools,
dist::RustDev,
@@ -139,7 +128,15 @@ index 0ab4824..629e1bb 100644
// It seems that PlainSourceTarball somehow changes how some of the tools
// perceive their dependencies (see #93033) which would invalidate fingerprints
// and force us to rebuild tools after vendoring dependencies.
-@@ -2054,10 +2047,7 @@ impl<'a> Builder<'a> {
+@@ -736,7 +725,6 @@ impl<'a> Builder<'a> {
+ install::Docs,
+ install::Std,
+ install::Cargo,
+- install::RustAnalyzer,
+ install::Rustfmt,
+ install::RustDemangler,
+ install::Clippy,
+@@ -2056,10 +2050,7 @@ impl<'a> Builder<'a> {
}
}
@@ -152,7 +149,7 @@ index 0ab4824..629e1bb 100644
}
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
-index 2852442..5faa8e5 100644
+index f909ecc..8bf71b1 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -73,7 +73,6 @@ macro_rules! book {
@@ -164,10 +161,10 @@ index 2852442..5faa8e5 100644
EditionGuide, "src/doc/edition-guide", "edition-guide", submodule;
EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule;
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
-index c0fa8c9..8fbc390 100644
+index dd41f84..ba6227c 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
-@@ -1910,17 +1910,7 @@ impl Step for RustcGuide {
+@@ -1886,17 +1886,7 @@ impl Step for RustcGuide {
}
fn run(self, builder: &Builder<'_>) {
@@ -187,7 +184,7 @@ index c0fa8c9..8fbc390 100644
}
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
-index 1c875c3..1aad7cf 100644
+index b7e136c..a844a5d 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -36,11 +36,6 @@ walkdir = "2.3"
@@ -202,6 +199,26 @@ index 1c875c3..1aad7cf 100644
# UI test dependencies
clippy_utils = { path = "clippy_utils" }
derive-new = "0.5"
+diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
+index 6b68ca8..93f755c 100644
+--- a/src/tools/rust-analyzer/Cargo.toml
++++ b/src/tools/rust-analyzer/Cargo.toml
+@@ -1,5 +1,14 @@
+ [workspace]
+-members = ["xtask/", "lib/*", "crates/*"]
++members = [
++ "xtask/",
++ "lib/*",
++ "crates/proc-macro-srv",
++ "crates/proc-macro-srv-cli",
++ "crates/tt",
++ "crates/mbe",
++ "crates/paths",
++ "crates/proc-macro-api",
++]
+ exclude = ["crates/proc-macro-test/imp"]
+
+ [profile.dev]
diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml
index 7a4e02d..27b91f2 100644
--- a/src/tools/rustfmt/Cargo.toml
@@ -219,10 +236,10 @@ index 7a4e02d..27b91f2 100644
[package.metadata.rust-analyzer]
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
-index 333f85f..4df2b54 100644
+index cbd8cfa..6b39fd6 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
-@@ -306,7 +306,7 @@ const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[
+@@ -308,7 +308,7 @@ const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[
// These two crates take quite a long time to build, so don't allow two versions of them
// to accidentally sneak into our dependency graph, in order to ensure we keep our CI times
// under control.
@@ -231,23 +248,3 @@ index 333f85f..4df2b54 100644
];
/// Dependency checks.
-diff --git a/src/tools/rust-analyzer/Cargo.toml b/src.tools/rust-analyzer/Cargo.toml
-index 6b68ca82389..7bc5d1bc5a0 100644
---- a/src/tools/rust-analyzer/Cargo.toml
-+++ b/src/tools/rust-analyzer/Cargo.toml
-@@ -1,5 +1,14 @@
- [workspace]
--members = ["xtask/", "lib/*", "crates/*"]
-+members = [
-+ "xtask/",
-+ "lib/*",
-+ "crates/proc-macro-srv",
-+ "crates/proc-macro-srv-cli",
-+ "crates/tt",
-+ "crates/mbe",
-+ "crates/paths",
-+ "crates/proc-macro-api",
-+]
- exclude = ["crates/proc-macro-test/imp"]
-
- [profile.dev]
diff --git a/debian/patches/d-0004-clippy-feature-sync.patch b/debian/patches/d-0004-clippy-feature-sync.patch
index 8c0c0fb97..19c75955e 100644
--- a/debian/patches/d-0004-clippy-feature-sync.patch
+++ b/debian/patches/d-0004-clippy-feature-sync.patch
@@ -5,15 +5,15 @@ Subject: d-0004-clippy-feature-sync
enable features needed by rustfmt to make build system happy and speedup build.
this is what rustc_workspace_hack does in the upstream build.
---
- src/tools/clippy/Cargo.toml | 3 ++-
+ src/tools/clippy/Cargo.toml | 2 +-
src/tools/rustfmt/Cargo.toml | 2 +-
- 2 files changed, 3 insertions(+), 2 deletions(-)
+ 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
-index 1aad7cf..705a880 100644
+index a844a5d..4dd3f55 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
-@@ -42,7 +43,7 @@ if_chain = "1.0"
+@@ -43,7 +43,7 @@ if_chain = "1.0"
itertools = "0.10.1"
quote = "1.0"
serde = { version = "1.0.125", features = ["derive"] }
diff --git a/debian/patches/d-0005-no-jemalloc.patch b/debian/patches/d-0005-no-jemalloc.patch
index 6d8620a01..ca74117bd 100644
--- a/debian/patches/d-0005-no-jemalloc.patch
+++ b/debian/patches/d-0005-no-jemalloc.patch
@@ -3,8 +3,9 @@ Date: Sat, 2 Oct 2021 01:08:00 +0100
Subject: d-0005-no-jemalloc
---
- compiler/rustc/Cargo.toml | 6 ------
- 1 file changed, 6 deletions(-)
+ compiler/rustc/Cargo.toml | 6 ------
+ src/tools/rust-analyzer/crates/profile/Cargo.toml | 2 --
+ 2 files changed, 8 deletions(-)
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index 27ee3dd..87fb29f 100644
@@ -25,7 +26,7 @@ index 27ee3dd..87fb29f 100644
max_level_info = ['rustc_driver/max_level_info']
rustc_use_parallel_compiler = ['rustc_driver/rustc_use_parallel_compiler']
diff --git a/src/tools/rust-analyzer/crates/profile/Cargo.toml b/src/tools/rust-analyzer/crates/profile/Cargo.toml
-index 99d4179dc20..0b78a45a24b 100644
+index 0b78a45..99d4179 100644
--- a/src/tools/rust-analyzer/crates/profile/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/profile/Cargo.toml
@@ -15,7 +15,6 @@ cfg-if = "1.0.0"
@@ -36,7 +37,7 @@ index 99d4179dc20..0b78a45a24b 100644
[target.'cfg(target_os = "linux")'.dependencies]
perf-event = "0.4.7"
-@@ -24,7 +25,6 @@ winapi = { version = "0.3.9", features = ["processthreadsapi", "psapi"] }
+@@ -25,7 +24,6 @@ winapi = { version = "0.3.9", features = ["processthreadsapi", "psapi"] }
[features]
cpu_profiler = []
diff --git a/debian/patches/d-bootstrap-cargo-check-cfg.patch b/debian/patches/d-bootstrap-cargo-check-cfg.patch
index e15707199..c715b1f31 100644
--- a/debian/patches/d-bootstrap-cargo-check-cfg.patch
+++ b/debian/patches/d-bootstrap-cargo-check-cfg.patch
@@ -5,7 +5,7 @@ diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 0ab4824ac0a..76c476f449b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
-@@ -1480,9 +1480,9 @@ impl<'a> Builder<'a> {
+@@ -1472,9 +1472,9 @@ impl<'a> Builder<'a> {
// complete list of features, so for that reason we don't enable checking of
// features for std crates.
cargo.arg(if mode != Mode::Std {
diff --git a/debian/patches/d-bootstrap-custom-debuginfo-path.patch b/debian/patches/d-bootstrap-custom-debuginfo-path.patch
index f955cffbf..2b548abcf 100644
--- a/debian/patches/d-bootstrap-custom-debuginfo-path.patch
+++ b/debian/patches/d-bootstrap-custom-debuginfo-path.patch
@@ -12,7 +12,7 @@ diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index ddc92ba..259b56e 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
-@@ -1023,10 +1023,9 @@ impl Build {
+@@ -1026,10 +1026,9 @@ impl Build {
match which {
GitRepo::Rustc => {
diff --git a/debian/patches/d-bootstrap-disable-git.patch b/debian/patches/d-bootstrap-disable-git.patch
index ce02d60b3..63823f51b 100644
--- a/debian/patches/d-bootstrap-disable-git.patch
+++ b/debian/patches/d-bootstrap-disable-git.patch
@@ -31,7 +31,7 @@ diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 6181a61..5fe3600 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
-@@ -899,7 +899,10 @@ impl Step for PlainSourceTarball {
+@@ -902,7 +902,10 @@ impl Step for PlainSourceTarball {
}
// If we're building from git sources, we need to vendor a complete distribution.
diff --git a/debian/patches/d-bootstrap-read-beta-version-from-file.patch b/debian/patches/d-bootstrap-read-beta-version-from-file.patch
index a5b385d13..812a653ba 100644
--- a/debian/patches/d-bootstrap-read-beta-version-from-file.patch
+++ b/debian/patches/d-bootstrap-read-beta-version-from-file.patch
@@ -11,7 +11,7 @@ diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 68d387b..ddc92ba 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
-@@ -1266,14 +1266,15 @@ impl Build {
+@@ -1269,14 +1269,15 @@ impl Build {
return s;
}
diff --git a/debian/patches/d-bootstrap-rustflags.patch b/debian/patches/d-bootstrap-rustflags.patch
index a28810e89..dfcdee922 100644
--- a/debian/patches/d-bootstrap-rustflags.patch
+++ b/debian/patches/d-bootstrap-rustflags.patch
@@ -11,7 +11,7 @@ diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 23ea2fe..b2b1c54 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
-@@ -1505,6 +1505,18 @@ impl<'a> Builder<'a> {
+@@ -1499,6 +1499,18 @@ impl<'a> Builder<'a> {
}
}
diff --git a/debian/patches/d-rust-lldb-paths b/debian/patches/d-rust-lldb-paths
index 15028a68f..bea7a3844 100644
--- a/debian/patches/d-rust-lldb-paths
+++ b/debian/patches/d-rust-lldb-paths
@@ -23,7 +23,7 @@ index bce72f1..793f593 100755
RUST_LLDB="$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb"
-lldb=lldb
-+lldb=lldb-14
++lldb=lldb-15
if [ -f "$RUST_LLDB" ]; then
lldb="$RUST_LLDB"
else
diff --git a/debian/patches/d-rustc-add-soname.patch b/debian/patches/d-rustc-add-soname.patch
index 70fdf26b8..e69898bf5 100644
--- a/debian/patches/d-rustc-add-soname.patch
+++ b/debian/patches/d-rustc-add-soname.patch
@@ -28,7 +28,7 @@ diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codege
index 04ec1e7..67296ca 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
-@@ -2175,6 +2175,13 @@ fn add_order_independent_options(
+@@ -2240,6 +2240,13 @@ fn add_order_independent_options(
}
add_rpath_args(cmd, sess, codegen_results, out_filename);
diff --git a/debian/patches/d-rustc-windows-ssp.patch b/debian/patches/d-rustc-windows-ssp.patch
index 5d8ba4785..bbf00594c 100644
--- a/debian/patches/d-rustc-windows-ssp.patch
+++ b/debian/patches/d-rustc-windows-ssp.patch
@@ -11,7 +11,7 @@ diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc
index d11f1f7..137f8eb 100644
--- a/compiler/rustc_target/src/spec/windows_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs
-@@ -40,6 +40,8 @@ pub fn opts() -> TargetOptions {
+@@ -41,6 +41,8 @@ pub fn opts() -> TargetOptions {
"-lmsvcrt",
"-luser32",
"-lkernel32",
diff --git a/debian/patches/series b/debian/patches/series
index c918b658a..d3c74ae4c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,17 +4,17 @@
u-ignore-reproducible-failure.patch
u-reproducible-build.patch
u-ignore-endian-big-diff.patch
+u-make-compiletest-work-without-rpath.patch
+u-fix-backtrace-tests.patch # fixed in 1.66
# can be dropped once upstream updates compiler_builtins
u-arm-compiler-builtins-weak-linkage-arm.patch
-u-arm-compiler-builtins-add-sync-builtin-fallbacks.patch
# can be dropped once upstream updates rustix
u-fix-rustix-for-sparc64.patch
# not forwarded, or forwarded but unlikely to be merged
u-ignore-ppc-hangs.patch
-u-ignore-bpf-test.patch
u-rustc-llvm-cross-flags.patch
u-reproducible-dl-stage0.patch
u-make-tests-work-without-rpath.patch
@@ -67,4 +67,3 @@ d-rustdoc-disable-embedded-fonts.patch
# cherry-picked from ubuntu
ubuntu-disable-ppc64el-asm-tests.patch
ubuntu-ignore-arm-doctest.patch
-ubuntu-Revert-Use-constant-eval-to-do-strict-validity-check.patch
diff --git a/debian/patches/u-arm-compiler-builtins-add-sync-builtin-fallbacks.patch b/debian/patches/u-arm-compiler-builtins-add-sync-builtin-fallbacks.patch
deleted file mode 100644
index 796c17cef..000000000
--- a/debian/patches/u-arm-compiler-builtins-add-sync-builtin-fallbacks.patch
+++ /dev/null
@@ -1,223 +0,0 @@
-From 56172fcd8bd045e38bbdf76697d1fcca1e965d6d Mon Sep 17 00:00:00 2001
-From: Alex Huszagh <ahuszagh@gmail.com>
-Date: Fri, 29 Jul 2022 16:58:05 -0500
-Subject: [PATCH] Add compiler-rt fallbacks for sync builtins on armv5te-musl.
-
----
-https://github.com/rust-lang/compiler-builtins/pull/484
-
- src/arm_linux.rs | 110 +++++++++++++++++++++++++++++++----------------
- 1 file changed, 73 insertions(+), 37 deletions(-)
-
-diff --git a/vendor/compiler_builtins/src/arm_linux.rs b/vendor/compiler_builtins/src/arm_linux.rs
-index 8fe0948..8f22eb6 100644
---- a/vendor/compiler_builtins/src/arm_linux.rs
-+++ b/vendor/compiler_builtins/src/arm_linux.rs
-@@ -55,7 +55,7 @@ fn insert_aligned(aligned: u32, val: u32, shift: u32, mask: u32) -> u32 {
- }
-
- // Generic atomic read-modify-write operation
--unsafe fn atomic_rmw<T, F: Fn(u32) -> u32>(ptr: *mut T, f: F) -> u32 {
-+unsafe fn atomic_rmw<T, F: Fn(u32) -> u32, G: Fn(u32, u32) -> u32>(ptr: *mut T, f: F, g: G) -> u32 {
- let aligned_ptr = align_ptr(ptr);
- let (shift, mask) = get_shift_mask(ptr);
-
-@@ -65,7 +65,7 @@ unsafe fn atomic_rmw<T, F: Fn(u32) -> u32>(ptr: *mut T, f: F) -> u32 {
- let newval = f(curval);
- let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask);
- if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) {
-- return curval;
-+ return g(curval, newval);
- }
- }
- }
-@@ -89,13 +89,21 @@ unsafe fn atomic_cmpxchg<T>(ptr: *mut T, oldval: u32, newval: u32) -> u32 {
- }
-
- macro_rules! atomic_rmw {
-- ($name:ident, $ty:ty, $op:expr) => {
-+ ($name:ident, $ty:ty, $op:expr, $fetch:expr) => {
- intrinsics! {
- pub unsafe extern "C" fn $name(ptr: *mut $ty, val: $ty) -> $ty {
-- atomic_rmw(ptr, |x| $op(x as $ty, val) as u32) as $ty
-+ atomic_rmw(ptr, |x| $op(x as $ty, val) as u32, |old, new| $fetch(old, new)) as $ty
- }
- }
- };
-+
-+ (@old $name:ident, $ty:ty, $op:expr) => {
-+ atomic_rmw!($name, $ty, $op, |old, _| old);
-+ };
-+
-+ (@new $name:ident, $ty:ty, $op:expr) => {
-+ atomic_rmw!($name, $ty, $op, |_, new| new);
-+ };
- }
- macro_rules! atomic_cmpxchg {
- ($name:ident, $ty:ty) => {
-@@ -107,101 +115,129 @@ macro_rules! atomic_cmpxchg {
- };
- }
-
--atomic_rmw!(__sync_fetch_and_add_1, u8, |a: u8, b: u8| a.wrapping_add(b));
--atomic_rmw!(__sync_fetch_and_add_2, u16, |a: u16, b: u16| a
-+atomic_rmw!(@old __sync_fetch_and_add_1, u8, |a: u8, b: u8| a.wrapping_add(b));
-+atomic_rmw!(@old __sync_fetch_and_add_2, u16, |a: u16, b: u16| a
-+ .wrapping_add(b));
-+atomic_rmw!(@old __sync_fetch_and_add_4, u32, |a: u32, b: u32| a
-+ .wrapping_add(b));
-+
-+atomic_rmw!(@new __sync_add_and_fetch_1, u8, |a: u8, b: u8| a.wrapping_add(b));
-+atomic_rmw!(@new __sync_add_and_fetch_2, u16, |a: u16, b: u16| a
- .wrapping_add(b));
--atomic_rmw!(__sync_fetch_and_add_4, u32, |a: u32, b: u32| a
-+atomic_rmw!(@new __sync_add_and_fetch_4, u32, |a: u32, b: u32| a
- .wrapping_add(b));
-
--atomic_rmw!(__sync_fetch_and_sub_1, u8, |a: u8, b: u8| a.wrapping_sub(b));
--atomic_rmw!(__sync_fetch_and_sub_2, u16, |a: u16, b: u16| a
-+atomic_rmw!(@old __sync_fetch_and_sub_1, u8, |a: u8, b: u8| a.wrapping_sub(b));
-+atomic_rmw!(@old __sync_fetch_and_sub_2, u16, |a: u16, b: u16| a
- .wrapping_sub(b));
--atomic_rmw!(__sync_fetch_and_sub_4, u32, |a: u32, b: u32| a
-+atomic_rmw!(@old __sync_fetch_and_sub_4, u32, |a: u32, b: u32| a
- .wrapping_sub(b));
-
--atomic_rmw!(__sync_fetch_and_and_1, u8, |a: u8, b: u8| a & b);
--atomic_rmw!(__sync_fetch_and_and_2, u16, |a: u16, b: u16| a & b);
--atomic_rmw!(__sync_fetch_and_and_4, u32, |a: u32, b: u32| a & b);
-+atomic_rmw!(@new __sync_sub_and_fetch_1, u8, |a: u8, b: u8| a.wrapping_sub(b));
-+atomic_rmw!(@new __sync_sub_and_fetch_2, u16, |a: u16, b: u16| a
-+ .wrapping_sub(b));
-+atomic_rmw!(@new __sync_sub_and_fetch_4, u32, |a: u32, b: u32| a
-+ .wrapping_sub(b));
-+
-+atomic_rmw!(@old __sync_fetch_and_and_1, u8, |a: u8, b: u8| a & b);
-+atomic_rmw!(@old __sync_fetch_and_and_2, u16, |a: u16, b: u16| a & b);
-+atomic_rmw!(@old __sync_fetch_and_and_4, u32, |a: u32, b: u32| a & b);
-+
-+atomic_rmw!(@new __sync_and_and_fetch_1, u8, |a: u8, b: u8| a & b);
-+atomic_rmw!(@new __sync_and_and_fetch_2, u16, |a: u16, b: u16| a & b);
-+atomic_rmw!(@new __sync_and_and_fetch_4, u32, |a: u32, b: u32| a & b);
-+
-+atomic_rmw!(@old __sync_fetch_and_or_1, u8, |a: u8, b: u8| a | b);
-+atomic_rmw!(@old __sync_fetch_and_or_2, u16, |a: u16, b: u16| a | b);
-+atomic_rmw!(@old __sync_fetch_and_or_4, u32, |a: u32, b: u32| a | b);
-+
-+atomic_rmw!(@new __sync_or_and_fetch_1, u8, |a: u8, b: u8| a | b);
-+atomic_rmw!(@new __sync_or_and_fetch_2, u16, |a: u16, b: u16| a | b);
-+atomic_rmw!(@new __sync_or_and_fetch_4, u32, |a: u32, b: u32| a | b);
-+
-+atomic_rmw!(@old __sync_fetch_and_xor_1, u8, |a: u8, b: u8| a ^ b);
-+atomic_rmw!(@old __sync_fetch_and_xor_2, u16, |a: u16, b: u16| a ^ b);
-+atomic_rmw!(@old __sync_fetch_and_xor_4, u32, |a: u32, b: u32| a ^ b);
-
--atomic_rmw!(__sync_fetch_and_or_1, u8, |a: u8, b: u8| a | b);
--atomic_rmw!(__sync_fetch_and_or_2, u16, |a: u16, b: u16| a | b);
--atomic_rmw!(__sync_fetch_and_or_4, u32, |a: u32, b: u32| a | b);
-+atomic_rmw!(@new __sync_xor_and_fetch_1, u8, |a: u8, b: u8| a ^ b);
-+atomic_rmw!(@new __sync_xor_and_fetch_2, u16, |a: u16, b: u16| a ^ b);
-+atomic_rmw!(@new __sync_xor_and_fetch_4, u32, |a: u32, b: u32| a ^ b);
-
--atomic_rmw!(__sync_fetch_and_xor_1, u8, |a: u8, b: u8| a ^ b);
--atomic_rmw!(__sync_fetch_and_xor_2, u16, |a: u16, b: u16| a ^ b);
--atomic_rmw!(__sync_fetch_and_xor_4, u32, |a: u32, b: u32| a ^ b);
-+atomic_rmw!(@old __sync_fetch_and_nand_1, u8, |a: u8, b: u8| !(a & b));
-+atomic_rmw!(@old __sync_fetch_and_nand_2, u16, |a: u16, b: u16| !(a & b));
-+atomic_rmw!(@old __sync_fetch_and_nand_4, u32, |a: u32, b: u32| !(a & b));
-
--atomic_rmw!(__sync_fetch_and_nand_1, u8, |a: u8, b: u8| !(a & b));
--atomic_rmw!(__sync_fetch_and_nand_2, u16, |a: u16, b: u16| !(a & b));
--atomic_rmw!(__sync_fetch_and_nand_4, u32, |a: u32, b: u32| !(a & b));
-+atomic_rmw!(@new __sync_nand_and_fetch_1, u8, |a: u8, b: u8| !(a & b));
-+atomic_rmw!(@new __sync_nand_and_fetch_2, u16, |a: u16, b: u16| !(a & b));
-+atomic_rmw!(@new __sync_nand_and_fetch_4, u32, |a: u32, b: u32| !(a & b));
-
--atomic_rmw!(__sync_fetch_and_max_1, i8, |a: i8, b: i8| if a > b {
-+atomic_rmw!(@old __sync_fetch_and_max_1, i8, |a: i8, b: i8| if a > b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_max_2, i16, |a: i16, b: i16| if a > b {
-+atomic_rmw!(@old __sync_fetch_and_max_2, i16, |a: i16, b: i16| if a > b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_max_4, i32, |a: i32, b: i32| if a > b {
-+atomic_rmw!(@old __sync_fetch_and_max_4, i32, |a: i32, b: i32| if a > b {
- a
- } else {
- b
- });
-
--atomic_rmw!(__sync_fetch_and_umax_1, u8, |a: u8, b: u8| if a > b {
-+atomic_rmw!(@old __sync_fetch_and_umax_1, u8, |a: u8, b: u8| if a > b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_umax_2, u16, |a: u16, b: u16| if a > b {
-+atomic_rmw!(@old __sync_fetch_and_umax_2, u16, |a: u16, b: u16| if a > b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_umax_4, u32, |a: u32, b: u32| if a > b {
-+atomic_rmw!(@old __sync_fetch_and_umax_4, u32, |a: u32, b: u32| if a > b {
- a
- } else {
- b
- });
-
--atomic_rmw!(__sync_fetch_and_min_1, i8, |a: i8, b: i8| if a < b {
-+atomic_rmw!(@old __sync_fetch_and_min_1, i8, |a: i8, b: i8| if a < b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_min_2, i16, |a: i16, b: i16| if a < b {
-+atomic_rmw!(@old __sync_fetch_and_min_2, i16, |a: i16, b: i16| if a < b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_min_4, i32, |a: i32, b: i32| if a < b {
-+atomic_rmw!(@old __sync_fetch_and_min_4, i32, |a: i32, b: i32| if a < b {
- a
- } else {
- b
- });
-
--atomic_rmw!(__sync_fetch_and_umin_1, u8, |a: u8, b: u8| if a < b {
-+atomic_rmw!(@old __sync_fetch_and_umin_1, u8, |a: u8, b: u8| if a < b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_umin_2, u16, |a: u16, b: u16| if a < b {
-+atomic_rmw!(@old __sync_fetch_and_umin_2, u16, |a: u16, b: u16| if a < b {
- a
- } else {
- b
- });
--atomic_rmw!(__sync_fetch_and_umin_4, u32, |a: u32, b: u32| if a < b {
-+atomic_rmw!(@old __sync_fetch_and_umin_4, u32, |a: u32, b: u32| if a < b {
- a
- } else {
- b
- });
-
--atomic_rmw!(__sync_lock_test_and_set_1, u8, |_: u8, b: u8| b);
--atomic_rmw!(__sync_lock_test_and_set_2, u16, |_: u16, b: u16| b);
--atomic_rmw!(__sync_lock_test_and_set_4, u32, |_: u32, b: u32| b);
-+atomic_rmw!(@old __sync_lock_test_and_set_1, u8, |_: u8, b: u8| b);
-+atomic_rmw!(@old __sync_lock_test_and_set_2, u16, |_: u16, b: u16| b);
-+atomic_rmw!(@old __sync_lock_test_and_set_4, u32, |_: u32, b: u32| b);
-
- atomic_cmpxchg!(__sync_val_compare_and_swap_1, u8);
- atomic_cmpxchg!(__sync_val_compare_and_swap_2, u16);
---
-2.39.0
-
diff --git a/debian/patches/u-fix-backtrace-tests.patch b/debian/patches/u-fix-backtrace-tests.patch
new file mode 100644
index 000000000..9a5617ad1
--- /dev/null
+++ b/debian/patches/u-fix-backtrace-tests.patch
@@ -0,0 +1,54 @@
+From 3d8b3e6ca179dc2ac79c038ad607b2321be70e8d Mon Sep 17 00:00:00 2001
+From: Aaron Hill <aa1ronham@gmail.com>
+Date: Wed, 21 Sep 2022 10:24:16 -0500
+Subject: [PATCH] Set 'exec-env:RUST_BACKTRACE=0' in const-eval-select tests
+
+This allows the tests to pass even if the user has RUST_BACKTRACE
+set when running 'x.py'
+---
+ src/test/ui/intrinsics/const-eval-select-backtrace-std.rs | 1 +
+ .../ui/intrinsics/const-eval-select-backtrace-std.run.stderr | 2 +-
+ src/test/ui/intrinsics/const-eval-select-backtrace.rs | 1 +
+ src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr | 2 +-
+ 4 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
+index 29aefe07162b3..1164a3a5b0180 100644
+--- a/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
++++ b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
+@@ -1,6 +1,7 @@
+ // See issue #100696.
+ // run-fail
+ // check-run-results
++// exec-env:RUST_BACKTRACE=0
+ fn main() {
+ &""[1..];
+ }
+diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
+index e53e6034620ca..463cd52c5aa7b 100644
+--- a/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
++++ b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
+@@ -1,2 +1,2 @@
+-thread 'main' panicked at 'byte index 1 is out of bounds of ``', $DIR/const-eval-select-backtrace-std.rs:5:6
++thread 'main' panicked at 'byte index 1 is out of bounds of ``', $DIR/const-eval-select-backtrace-std.rs:6:6
+ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace.rs b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
+index 99f0725200c1d..ef1c7c4195b91 100644
+--- a/src/test/ui/intrinsics/const-eval-select-backtrace.rs
++++ b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
+@@ -2,6 +2,7 @@
+ // See issue #100696.
+ // run-fail
+ // check-run-results
++// exec-env:RUST_BACKTRACE=0
+
+ #[track_caller]
+ fn uhoh() {
+diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
+index 2fd730ac7a68a..54e28db5e533d 100644
+--- a/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
++++ b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
+@@ -1,2 +1,2 @@
+-thread 'main' panicked at 'Aaah!', $DIR/const-eval-select-backtrace.rs:16:9
++thread 'main' panicked at 'Aaah!', $DIR/const-eval-select-backtrace.rs:17:9
+ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/debian/patches/u-ignore-bpf-test.patch b/debian/patches/u-ignore-bpf-test.patch
deleted file mode 100644
index 5fa3464ee..000000000
--- a/debian/patches/u-ignore-bpf-test.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From: Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
-Date: Thu, 14 Jul 2022 13:17:37 +0200
-Subject: u-ignore-bpf-test
-
-Bug: https://github.com/rust-lang/rust/issues/89689
----
- src/test/assembly/asm/bpf-types.rs | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/test/assembly/asm/bpf-types.rs b/src/test/assembly/asm/bpf-types.rs
-index 3428d93..0e129a7 100644
---- a/src/test/assembly/asm/bpf-types.rs
-+++ b/src/test/assembly/asm/bpf-types.rs
-@@ -1,3 +1,4 @@
-+// ignore-test
- // min-llvm-version: 13.0
- // assembly-output: emit-asm
- // compile-flags: --target bpfel-unknown-none -C target_feature=+alu32
diff --git a/debian/patches/u-make-compiletest-work-without-rpath.patch b/debian/patches/u-make-compiletest-work-without-rpath.patch
new file mode 100644
index 000000000..67c3badcd
--- /dev/null
+++ b/debian/patches/u-make-compiletest-work-without-rpath.patch
@@ -0,0 +1,187 @@
+From f8a0cc2ca8a644ddb63867526711ba17cb7508c8 Mon Sep 17 00:00:00 2001
+From: Josh Stone <jistone@redhat.com>
+Date: Fri, 14 Oct 2022 16:11:28 -0700
+Subject: [PATCH] compiletest: set the dylib path when gathering target cfg
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the compiler is built with `rpath = false`, then it won't find its
+own libraries unless the library search path is set. We already do that
+while running the actual compiletests, but #100260 added another rustc
+command for getting the target cfg.
+
+ Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
+ thread 'main' panicked at 'error: failed to get cfg info from "[...]/build/x86_64-unknown-linux-gnu/stage1/bin/rustc"
+ --- stdout
+
+ --- stderr
+ [...]/build/x86_64-unknown-linux-gnu/stage1/bin/rustc: error while loading shared libraries: librustc_driver-a2a76dc626cd02d2.so: cannot open shared object file: No such file or directory
+ ', src/tools/compiletest/src/common.rs:476:13
+
+Now the library path is set here as well, so it works without rpath.
+
+FG: Context adapted
+
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ src/tools/compiletest/src/common.rs | 18 +++++++++++-------
+ src/tools/compiletest/src/runtest.rs | 27 +++------------------------
+ src/tools/compiletest/src/util.rs | 23 +++++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 31 deletions(-)
+
+diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
+index 64df76e2772..98a35810cfd 100644
+--- a/src/tools/compiletest/src/common.rs
++++ b/src/tools/compiletest/src/common.rs
+@@ -2,11 +2,12 @@ pub use self::Mode::*;
+
+ use std::ffi::OsString;
+ use std::fmt;
++use std::iter;
+ use std::path::{Path, PathBuf};
+ use std::process::Command;
+ use std::str::FromStr;
+
+-use crate::util::PathBufExt;
++use crate::util::{add_dylib_path, PathBufExt};
+ use lazycell::LazyCell;
+ use test::ColorConfig;
+
+@@ -389,7 +390,7 @@ impl Config {
+ }
+
+ fn target_cfg(&self) -> &TargetCfg {
+- self.target_cfg.borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target))
++ self.target_cfg.borrow_with(|| TargetCfg::new(self))
+ }
+
+ pub fn matches_arch(&self, arch: &str) -> bool {
+@@ -455,20 +456,22 @@ pub enum Endian {
+ }
+
+ impl TargetCfg {
+- fn new(rustc_path: &Path, target: &str) -> TargetCfg {
+- let output = match Command::new(rustc_path)
++ fn new(config: &Config) -> TargetCfg {
++ let mut command = Command::new(&config.rustc_path);
++ add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
++ let output = match command
+ .arg("--print=cfg")
+ .arg("--target")
+- .arg(target)
++ .arg(&config.target)
+ .output()
+ {
+ Ok(output) => output,
+- Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path),
++ Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", config.rustc_path),
+ };
+ if !output.status.success() {
+ panic!(
+ "error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}",
+- rustc_path,
++ config.rustc_path,
+ String::from_utf8(output.stdout).unwrap(),
+ String::from_utf8(output.stderr).unwrap(),
+ );
+diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
+index 8f289876f73..eb467170249 100644
+--- a/src/tools/compiletest/src/runtest.rs
++++ b/src/tools/compiletest/src/runtest.rs
+@@ -13,7 +13,7 @@ use crate::errors::{self, Error, ErrorKind};
+ use crate::header::TestProps;
+ use crate::json;
+ use crate::read2::read2_abbreviated;
+-use crate::util::{logv, PathBufExt};
++use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
+ use crate::ColorConfig;
+ use regex::{Captures, Regex};
+ use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
+@@ -26,6 +26,7 @@ use std::fs::{self, create_dir_all, File, OpenOptions};
+ use std::hash::{Hash, Hasher};
+ use std::io::prelude::*;
+ use std::io::{self, BufReader};
++use std::iter;
+ use std::path::{Path, PathBuf};
+ use std::process::{Child, Command, ExitStatus, Output, Stdio};
+ use std::str;
+@@ -72,19 +73,6 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
+ f()
+ }
+
+-/// The name of the environment variable that holds dynamic library locations.
+-pub fn dylib_env_var() -> &'static str {
+- if cfg!(windows) {
+- "PATH"
+- } else if cfg!(target_os = "macos") {
+- "DYLD_LIBRARY_PATH"
+- } else if cfg!(target_os = "haiku") {
+- "LIBRARY_PATH"
+- } else {
+- "LD_LIBRARY_PATH"
+- }
+-}
+-
+ /// The platform-specific library name
+ pub fn get_lib_name(lib: &str, dylib: bool) -> String {
+ // In some casess (e.g. MUSL), we build a static
+@@ -1826,16 +1814,7 @@ impl<'test> TestCx<'test> {
+
+ // Need to be sure to put both the lib_path and the aux path in the dylib
+ // search path for the child.
+- let mut path =
+- env::split_paths(&env::var_os(dylib_env_var()).unwrap_or_default()).collect::<Vec<_>>();
+- if let Some(p) = aux_path {
+- path.insert(0, PathBuf::from(p))
+- }
+- path.insert(0, PathBuf::from(lib_path));
+-
+- // Add the new dylib search path var
+- let newpath = env::join_paths(&path).unwrap();
+- command.env(dylib_env_var(), newpath);
++ add_dylib_path(&mut command, iter::once(lib_path).chain(aux_path));
+
+ let mut child = disable_error_reporting(|| command.spawn())
+ .unwrap_or_else(|_| panic!("failed to exec `{:?}`", &command));
+diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
+index 9d047b63c85..4b73be0fbb9 100644
+--- a/src/tools/compiletest/src/util.rs
++++ b/src/tools/compiletest/src/util.rs
+@@ -2,6 +2,7 @@ use crate::common::Config;
+ use std::env;
+ use std::ffi::OsStr;
+ use std::path::PathBuf;
++use std::process::Command;
+
+ use tracing::*;
+
+@@ -105,3 +106,25 @@ impl PathBufExt for PathBuf {
+ }
+ }
+ }
++
++/// The name of the environment variable that holds dynamic library locations.
++pub fn dylib_env_var() -> &'static str {
++ if cfg!(windows) {
++ "PATH"
++ } else if cfg!(target_os = "macos") {
++ "DYLD_LIBRARY_PATH"
++ } else if cfg!(target_os = "haiku") {
++ "LIBRARY_PATH"
++ } else {
++ "LD_LIBRARY_PATH"
++ }
++}
++
++/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
++/// If the dylib_path_var is already set for this cmd, the old value will be overwritten!
++pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator<Item = impl Into<PathBuf>>) {
++ let path_env = env::var_os(dylib_env_var());
++ let old_paths = path_env.as_ref().map(env::split_paths);
++ let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
++ cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
++}
+--
+2.30.2
+
diff --git a/debian/patches/u-rustc-llvm-cross-flags.patch b/debian/patches/u-rustc-llvm-cross-flags.patch
index 95988249e..0e544db8e 100644
--- a/debian/patches/u-rustc-llvm-cross-flags.patch
+++ b/debian/patches/u-rustc-llvm-cross-flags.patch
@@ -11,7 +11,7 @@ diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index b8f67ee..e9b1d0a 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
-@@ -294,7 +294,7 @@ fn main() {
+@@ -301,7 +301,7 @@ fn main() {
if let Some(stripped) = lib.strip_prefix("-LIBPATH:") {
println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target));
} else if let Some(stripped) = lib.strip_prefix("-L") {
diff --git a/debian/patches/ubuntu-Revert-Use-constant-eval-to-do-strict-validity-check.patch b/debian/patches/ubuntu-Revert-Use-constant-eval-to-do-strict-validity-check.patch
deleted file mode 100644
index c9b50d71f..000000000
--- a/debian/patches/ubuntu-Revert-Use-constant-eval-to-do-strict-validity-check.patch
+++ /dev/null
@@ -1,569 +0,0 @@
-From b9e588dfeecca821a4508166027afb6bda721ed6 Mon Sep 17 00:00:00 2001
-From: Simon Chopin <simon.chopin@canonical.com>
-Date: Wed, 18 Jan 2023 17:03:04 +0100
-Subject: [PATCH] Revert "Use constant eval to do strict validity checks"
-
-This reverts commit 27412d1e3e128349bc515c16ce882860e20f037d.
-
-This is likely a LLVM mis-optimization, but we're not really sure. It
-leads to ICE on riscv64.
-
-Bug: https://github.com/rust-lang/rust/issues/102155
-
----
- Cargo.lock | 1 -
- .../src/intrinsics/mod.rs | 15 ++++-
- compiler/rustc_codegen_ssa/Cargo.toml | 1 -
- compiler/rustc_codegen_ssa/src/mir/block.rs | 9 +--
- .../src/const_eval/machine.rs | 2 +-
- .../src/interpret/intrinsics.rs | 56 ++++++++--------
- compiler/rustc_const_eval/src/lib.rs | 6 --
- .../src/might_permit_raw_init.rs | 40 -----------
- compiler/rustc_middle/src/query/mod.rs | 8 ---
- compiler/rustc_middle/src/ty/query.rs | 1 -
- compiler/rustc_query_impl/src/keys.rs | 12 +---
- compiler/rustc_target/src/abi/mod.rs | 38 ++++++-----
- .../intrinsics/panic-uninitialized-zeroed.rs | 66 +++++++------------
- 13 files changed, 94 insertions(+), 161 deletions(-)
- delete mode 100644 compiler/rustc_const_eval/src/might_permit_raw_init.rs
-
-diff --git a/Cargo.lock b/Cargo.lock
-index 2569b3e1976..b88158f9ff8 100644
---- a/Cargo.lock
-+++ b/Cargo.lock
-@@ -3731,7 +3731,6 @@ dependencies = [
- "rustc_arena",
- "rustc_ast",
- "rustc_attr",
-- "rustc_const_eval",
- "rustc_data_structures",
- "rustc_errors",
- "rustc_fs_util",
-diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
-index b2a83e1d4eb..4f9ced001d4 100644
---- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
-+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
-@@ -22,6 +22,7 @@ macro_rules! intrinsic_args {
- 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;
-@@ -693,7 +694,12 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
- return;
- }
-
-- if intrinsic == sym::assert_zero_valid && !fx.tcx.permits_zero_init(layout) {
-+ if intrinsic == sym::assert_zero_valid
-+ && !layout.might_permit_raw_init(
-+ fx,
-+ InitKind::Zero,
-+ fx.tcx.sess.opts.unstable_opts.strict_init_checks) {
-+
- with_no_trimmed_paths!({
- crate::base::codegen_panic(
- fx,
-@@ -707,7 +713,12 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
- return;
- }
-
-- if intrinsic == sym::assert_uninit_valid && !fx.tcx.permits_uninit_init(layout) {
-+ if intrinsic == sym::assert_uninit_valid
-+ && !layout.might_permit_raw_init(
-+ fx,
-+ InitKind::Uninit,
-+ fx.tcx.sess.opts.unstable_opts.strict_init_checks) {
-+
- with_no_trimmed_paths!({
- crate::base::codegen_panic(
- fx,
-diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
-index 46d6344dbb2..e7ee424668b 100644
---- a/compiler/rustc_codegen_ssa/Cargo.toml
-+++ b/compiler/rustc_codegen_ssa/Cargo.toml
-@@ -40,7 +40,6 @@ rustc_metadata = { path = "../rustc_metadata" }
- rustc_query_system = { path = "../rustc_query_system" }
- rustc_target = { path = "../rustc_target" }
- rustc_session = { path = "../rustc_session" }
--rustc_const_eval = { path = "../rustc_const_eval" }
-
- [dependencies.object]
- version = "0.29.0"
-diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
-index 3eee58d9d1c..a9eb4ec6439 100644
---- a/compiler/rustc_codegen_ssa/src/mir/block.rs
-+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
-@@ -22,7 +22,7 @@
- use rustc_span::{sym, Symbol};
- use rustc_symbol_mangling::typeid::typeid_for_fnabi;
- use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
--use rustc_target::abi::{self, HasDataLayout, WrappingRange};
-+use rustc_target::abi::{self, HasDataLayout, InitKind, WrappingRange};
- use rustc_target::spec::abi::Abi;
-
- /// Used by `FunctionCx::codegen_terminator` for emitting common patterns
-@@ -528,6 +528,7 @@ fn codegen_panic_intrinsic(
- source_info: mir::SourceInfo,
- target: Option<mir::BasicBlock>,
- cleanup: Option<mir::BasicBlock>,
-+ 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
-@@ -546,13 +547,12 @@ enum AssertIntrinsic {
- });
- if let Some(intrinsic) = panic_intrinsic {
- use AssertIntrinsic::*;
--
- let ty = instance.unwrap().substs.type_at(0);
- let layout = bx.layout_of(ty);
- let do_panic = match intrinsic {
- Inhabited => layout.abi.is_uninhabited(),
-- ZeroValid => !bx.tcx().permits_zero_init(layout),
-- UninitValid => !bx.tcx().permits_uninit_init(layout),
-+ 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!({
-@@ -687,6 +687,7 @@ fn codegen_call_terminator(
- source_info,
- target,
- cleanup,
-+ self.cx.tcx().sess.opts.unstable_opts.strict_init_checks,
- ) {
- return;
- }
-diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
-index fc2e6652a3d..ef6cff42ad9 100644
---- a/compiler/rustc_const_eval/src/const_eval/machine.rs
-+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
-@@ -104,7 +104,7 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
- }
-
- impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
-- pub(crate) fn new(const_eval_limit: Limit, can_access_statics: bool) -> Self {
-+ pub(super) fn new(const_eval_limit: Limit, can_access_statics: bool) -> Self {
- CompileTimeInterpreter {
- steps_remaining: const_eval_limit.0,
- stack: Vec::new(),
-diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
-index 08209eb7932..e0ce6d9acc8 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::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,
-@@ -435,33 +435,35 @@ pub fn emulate_intrinsic(
- ),
- )?;
- }
--
-- if intrinsic_name == sym::assert_zero_valid {
-- let should_panic = !self.tcx.permits_zero_init(layout);
--
-- if should_panic {
-- M::abort(
-- self,
-- format!(
-- "aborted execution: attempted to zero-initialize type `{}`, which is invalid",
-- ty
-- ),
-- )?;
-- }
-+ if intrinsic_name == sym::assert_zero_valid
-+ && !layout.might_permit_raw_init(
-+ self,
-+ InitKind::Zero,
-+ self.tcx.sess.opts.unstable_opts.strict_init_checks,
-+ )
-+ {
-+ M::abort(
-+ self,
-+ format!(
-+ "aborted execution: attempted to zero-initialize type `{}`, which is invalid",
-+ ty
-+ ),
-+ )?;
- }
--
-- if intrinsic_name == sym::assert_uninit_valid {
-- let should_panic = !self.tcx.permits_uninit_init(layout);
--
-- if should_panic {
-- M::abort(
-- self,
-- format!(
-- "aborted execution: attempted to leave type `{}` uninitialized, which is invalid",
-- ty
-- ),
-- )?;
-- }
-+ if intrinsic_name == sym::assert_uninit_valid
-+ && !layout.might_permit_raw_init(
-+ self,
-+ InitKind::Uninit,
-+ self.tcx.sess.opts.unstable_opts.strict_init_checks,
-+ )
-+ {
-+ M::abort(
-+ self,
-+ format!(
-+ "aborted execution: attempted to leave type `{}` uninitialized, which is invalid",
-+ ty
-+ ),
-+ )?;
- }
- }
- sym::simd_insert => {
-diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
-index 72ac6af685d..d65d4f7eb72 100644
---- a/compiler/rustc_const_eval/src/lib.rs
-+++ b/compiler/rustc_const_eval/src/lib.rs
-@@ -33,13 +33,11 @@
- pub mod const_eval;
- mod errors;
- pub mod interpret;
--mod might_permit_raw_init;
- pub mod transform;
- pub mod util;
-
- use rustc_middle::ty;
- use rustc_middle::ty::query::Providers;
--use rustc_target::abi::InitKind;
-
- pub fn provide(providers: &mut Providers) {
- const_eval::provide(providers);
-@@ -61,8 +59,4 @@ pub fn provide(providers: &mut Providers) {
- let (param_env, value) = param_env_and_value.into_parts();
- const_eval::deref_mir_constant(tcx, param_env, value)
- };
-- providers.permits_uninit_init =
-- |tcx, ty| might_permit_raw_init::might_permit_raw_init(tcx, ty, InitKind::Uninit);
-- providers.permits_zero_init =
-- |tcx, ty| might_permit_raw_init::might_permit_raw_init(tcx, ty, InitKind::Zero);
- }
-diff --git a/compiler/rustc_const_eval/src/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/might_permit_raw_init.rs
-deleted file mode 100644
-index f971c2238c7..00000000000
---- a/compiler/rustc_const_eval/src/might_permit_raw_init.rs
-+++ /dev/null
-@@ -1,40 +0,0 @@
--use crate::const_eval::CompileTimeInterpreter;
--use crate::interpret::{InterpCx, MemoryKind, OpTy};
--use rustc_middle::ty::layout::LayoutCx;
--use rustc_middle::ty::{layout::TyAndLayout, ParamEnv, TyCtxt};
--use rustc_session::Limit;
--use rustc_target::abi::InitKind;
--
--pub fn might_permit_raw_init<'tcx>(
-- tcx: TyCtxt<'tcx>,
-- ty: TyAndLayout<'tcx>,
-- kind: InitKind,
--) -> bool {
-- let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
--
-- if strict {
-- let machine = CompileTimeInterpreter::new(Limit::new(0), false);
--
-- let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
--
-- let allocated = cx
-- .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
-- .expect("OOM: failed to allocate for uninit check");
--
-- if kind == InitKind::Zero {
-- cx.write_bytes_ptr(
-- allocated.ptr,
-- std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()),
-- )
-- .expect("failed to write bytes for zero valid check");
-- }
--
-- let ot: OpTy<'_, _> = allocated.into();
--
-- // Assume that if it failed, it's a validation failure.
-- cx.validate_operand(&ot).is_ok()
-- } else {
-- let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() };
-- ty.might_permit_raw_init(&layout_cx, kind)
-- }
--}
-diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
-index d8483e7e409..e498015a4a5 100644
---- a/compiler/rustc_middle/src/query/mod.rs
-+++ b/compiler/rustc_middle/src/query/mod.rs
-@@ -2049,12 +2049,4 @@
- desc { |tcx| "looking up generator diagnostic data of `{}`", tcx.def_path_str(key) }
- separate_provide_extern
- }
--
-- query permits_uninit_init(key: TyAndLayout<'tcx>) -> bool {
-- desc { "checking to see if {:?} permits being left uninit", key.ty }
-- }
--
-- query permits_zero_init(key: TyAndLayout<'tcx>) -> bool {
-- desc { "checking to see if {:?} permits being left zeroed", key.ty }
-- }
- }
-diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
-index 2452bcf6a61..3d662ed5de4 100644
---- a/compiler/rustc_middle/src/ty/query.rs
-+++ b/compiler/rustc_middle/src/ty/query.rs
-@@ -28,7 +28,6 @@
- use crate::traits::specialization_graph;
- use crate::traits::{self, ImplSource};
- use crate::ty::fast_reject::SimplifiedType;
--use crate::ty::layout::TyAndLayout;
- use crate::ty::subst::{GenericArg, SubstsRef};
- use crate::ty::util::AlwaysRequiresDrop;
- use crate::ty::GeneratorDiagnosticData;
-diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
-index 49175e97f41..4d6bb02c38e 100644
---- a/compiler/rustc_query_impl/src/keys.rs
-+++ b/compiler/rustc_query_impl/src/keys.rs
-@@ -6,7 +6,7 @@
- use rustc_middle::traits;
- use rustc_middle::ty::fast_reject::SimplifiedType;
- use rustc_middle::ty::subst::{GenericArg, SubstsRef};
--use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
-+use rustc_middle::ty::{self, Ty, TyCtxt};
- use rustc_span::symbol::{Ident, Symbol};
- use rustc_span::{Span, DUMMY_SP};
-
-@@ -395,16 +395,6 @@ fn default_span(&self, _: TyCtxt<'_>) -> Span {
- }
- }
-
--impl<'tcx> Key for TyAndLayout<'tcx> {
-- #[inline(always)]
-- fn query_crate_is_local(&self) -> bool {
-- true
-- }
-- fn default_span(&self, _: TyCtxt<'_>) -> Span {
-- DUMMY_SP
-- }
--}
--
- impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) {
- #[inline(always)]
- fn query_crate_is_local(&self) -> bool {
-diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
-index 92ce4d91d84..d103a06060d 100644
---- a/compiler/rustc_target/src/abi/mod.rs
-+++ b/compiler/rustc_target/src/abi/mod.rs
-@@ -1378,7 +1378,7 @@ pub struct PointeeInfo {
-
- /// Used in `might_permit_raw_init` to indicate the kind of initialisation
- /// that is checked to be valid
--#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-+#[derive(Copy, Clone, Debug)]
- pub enum InitKind {
- Zero,
- Uninit,
-@@ -1493,18 +1493,14 @@ pub fn is_zst(&self) -> bool {
- ///
- /// `init_kind` indicates if the memory is zero-initialized or left uninitialized.
- ///
-- /// This code is intentionally conservative, and will not detect
-- /// * zero init of an enum whose 0 variant does not allow zero initialization
-- /// * making uninitialized types who have a full valid range (ints, floats, raw pointers)
-- /// * Any form of invalid value being made inside an array (unless the value is uninhabited)
-+ /// `strict` is an opt-in debugging flag added in #97323 that enables more checks.
- ///
-- /// A strict form of these checks that uses const evaluation exists in
-- /// `rustc_const_eval::might_permit_raw_init`, and a tracking issue for making these checks
-- /// stricter is <https://github.com/rust-lang/rust/issues/66151>.
-+ /// This is conservative: in doubt, it will answer `true`.
- ///
-- /// FIXME: Once all the conservatism is removed from here, and the checks are ran by default,
-- /// we can use the const evaluation checks always instead.
-- pub fn might_permit_raw_init<C>(self, cx: &C, init_kind: InitKind) -> bool
-+ /// FIXME: Once we removed all the conservatism, we could alternatively
-+ /// create an all-0/all-undef constant and run the const value validator to see if
-+ /// this is a valid value for the given type.
-+ pub fn might_permit_raw_init<C>(self, cx: &C, init_kind: InitKind, strict: bool) -> bool
- where
- Self: Copy,
- Ty: TyAbiInterface<'a, C>,
-@@ -1517,8 +1513,13 @@ pub fn might_permit_raw_init<C>(self, cx: &C, init_kind: InitKind) -> bool
- s.valid_range(cx).contains(0)
- }
- InitKind::Uninit => {
-- // The range must include all values.
-- s.is_always_valid(cx)
-+ if strict {
-+ // The type must be allowed to be uninit (which means "is a union").
-+ s.is_uninit_valid()
-+ } else {
-+ // The range must include all values.
-+ s.is_always_valid(cx)
-+ }
- }
- }
- };
-@@ -1539,12 +1540,19 @@ pub fn might_permit_raw_init<C>(self, cx: &C, init_kind: InitKind) -> bool
- // If we have not found an error yet, we need to recursively descend into fields.
- match &self.fields {
- FieldsShape::Primitive | FieldsShape::Union { .. } => {}
-- FieldsShape::Array { .. } => {
-+ FieldsShape::Array { count, .. } => {
- // FIXME(#66151): For now, we are conservative and do not check arrays by default.
-+ if strict
-+ && *count > 0
-+ && !self.field(cx, 0).might_permit_raw_init(cx, init_kind, strict)
-+ {
-+ // Found non empty array with a type that is unhappy about this kind of initialization
-+ return false;
-+ }
- }
- FieldsShape::Arbitrary { offsets, .. } => {
- for idx in 0..offsets.len() {
-- if !self.field(cx, idx).might_permit_raw_init(cx, init_kind) {
-+ if !self.field(cx, idx).might_permit_raw_init(cx, init_kind, strict) {
- // We found a field that is unhappy with this kind of initialization.
- return false;
- }
-diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
-index 255151a9603..3ffd35ecdb8 100644
---- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
-+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
-@@ -57,13 +57,6 @@ enum LR_NonZero {
-
- struct ZeroSized;
-
--#[allow(dead_code)]
--#[repr(i32)]
--enum ZeroIsValid {
-- Zero(u8) = 0,
-- One(NonNull<()>) = 1,
--}
--
- fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
- let err = panic::catch_unwind(op).err();
- assert_eq!(
-@@ -159,12 +152,33 @@ fn main() {
- "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
- );
-
-+ /* FIXME(#66151) we conservatively do not error here yet.
-+ test_panic_msg(
-+ || mem::uninitialized::<LR_NonZero>(),
-+ "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
-+ );
-+ test_panic_msg(
-+ || mem::zeroed::<LR_NonZero>(),
-+ "attempted to zero-initialize type `LR_NonZero`, which is invalid"
-+ );
-+
-+ test_panic_msg(
-+ || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
-+ "attempted to leave type `std::mem::ManuallyDrop<LR_NonZero>` uninitialized, \
-+ which is invalid"
-+ );
-+ test_panic_msg(
-+ || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
-+ "attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
-+ which is invalid"
-+ );
-+ */
-+
- test_panic_msg(
- || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
- "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
- which is invalid"
- );
--
- test_panic_msg(
- || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
- "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
-@@ -182,23 +196,11 @@ fn main() {
- which is invalid"
- );
-
-- test_panic_msg(
-- || mem::uninitialized::<LR_NonZero>(),
-- "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
-- );
--
-- test_panic_msg(
-- || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
-- "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>` uninitialized, \
-- which is invalid"
-- );
--
- test_panic_msg(
- || mem::uninitialized::<NoNullVariant>(),
- "attempted to leave type `NoNullVariant` uninitialized, \
- which is invalid"
- );
--
- test_panic_msg(
- || mem::zeroed::<NoNullVariant>(),
- "attempted to zero-initialize type `NoNullVariant`, \
-@@ -210,12 +212,10 @@ fn main() {
- || mem::uninitialized::<bool>(),
- "attempted to leave type `bool` uninitialized, which is invalid"
- );
--
- test_panic_msg(
- || mem::uninitialized::<LR>(),
- "attempted to leave type `LR` uninitialized, which is invalid"
- );
--
- test_panic_msg(
- || mem::uninitialized::<ManuallyDrop<LR>>(),
- "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
-@@ -229,7 +229,6 @@ fn main() {
- let _val = mem::zeroed::<Option<&'static i32>>();
- let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
- let _val = mem::zeroed::<[!; 0]>();
-- let _val = mem::zeroed::<ZeroIsValid>();
- let _val = mem::uninitialized::<MaybeUninit<bool>>();
- let _val = mem::uninitialized::<[!; 0]>();
- let _val = mem::uninitialized::<()>();
-@@ -260,33 +259,12 @@ fn main() {
- || mem::zeroed::<[NonNull<()>; 1]>(),
- "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
- );
--
-- // FIXME(#66151) we conservatively do not error here yet (by default).
-- test_panic_msg(
-- || mem::zeroed::<LR_NonZero>(),
-- "attempted to zero-initialize type `LR_NonZero`, which is invalid"
-- );
--
-- test_panic_msg(
-- || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
-- "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
-- which is invalid"
-- );
- } else {
- // These are UB because they have not been officially blessed, but we await the resolution
- // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
- // anything about that.
- let _val = mem::uninitialized::<i32>();
- let _val = mem::uninitialized::<*const ()>();
--
-- // These are UB, but best to test them to ensure we don't become unintentionally
-- // stricter.
--
-- // It's currently unchecked to create invalid enums and values inside arrays.
-- let _val = mem::zeroed::<LR_NonZero>();
-- let _val = mem::zeroed::<[LR_NonZero; 1]>();
-- let _val = mem::zeroed::<[NonNull<()>; 1]>();
-- let _val = mem::uninitialized::<[NonNull<()>; 1]>();
- }
- }
- }
---
-2.37.2
-
diff --git a/debian/patches/ubuntu-disable-ppc64el-asm-tests.patch b/debian/patches/ubuntu-disable-ppc64el-asm-tests.patch
index bc841cc8b..001305b6e 100644
--- a/debian/patches/ubuntu-disable-ppc64el-asm-tests.patch
+++ b/debian/patches/ubuntu-disable-ppc64el-asm-tests.patch
@@ -1,6 +1,6 @@
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
-@@ -2749,11 +2749,13 @@
+@@ -2913,11 +2913,13 @@ declare_lint! {
///
/// use std::arch::asm;
///
@@ -17,7 +17,7 @@
--- a/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
+++ b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
@@ -1,6 +1,7 @@
- -include ../tools.mk
+ include ../tools.mk
# ignore-windows-msvc
+# needs-asm-support
@@ -26,7 +26,7 @@
# https://github.com/llvm-mirror/llvm/commit/64b2297786f7fd6f5fa24cdd4db0298fbf211466
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
-@@ -3136,6 +3136,10 @@
+@@ -3053,6 +3053,10 @@ declare_lint! {
/// ### Example
///
/// ```rust,compile_fail
diff --git a/debian/rules b/debian/rules
index 8b83b8272..97f2f071d 100755
--- a/debian/rules
+++ b/debian/rules
@@ -28,8 +28,8 @@ export RUST_LONG_VERSION
DEB_DESTDIR := $(CURDIR)/debian/tmp
# Use system LLVM (comment out to use vendored LLVM)
-LLVM_VERSION = 14
-OLD_LLVM_VERSION = 13
+LLVM_VERSION = 15
+OLD_LLVM_VERSION = 14
# Make it easier to test against a custom LLVM
ifneq (,$(LLVM_DESTDIR))
LLVM_LIBRARY_PATH := $(LLVM_DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH):$(LLVM_DESTDIR)/usr/lib
@@ -278,9 +278,14 @@ FAILURES_ALLOWED = 8
ifneq (,$(filter $(DEB_BUILD_ARCH), armhf))
FAILURES_ALLOWED = 12
endif
-ifneq (,$(filter $(DEB_BUILD_ARCH), armel mips mipsel mips64el))
+ifneq (,$(filter $(DEB_BUILD_ARCH), armel mips mips64el))
FAILURES_ALLOWED = 24
endif
+# workaround broken gdb 13.1 - revert to 24 once fixed
+# #1031946 / #1032785
+ifneq (,$(filter $(DEB_BUILD_ARCH), mipsel))
+ FAILURES_ALLOWED = 25
+endif
ifneq (,$(filter $(DEB_BUILD_ARCH), ppc64 s390x))
FAILURES_ALLOWED = 40
endif
diff --git a/debian/rust-lldb.links b/debian/rust-lldb.links
index d9de18f77..561aff8b5 100644
--- a/debian/rust-lldb.links
+++ b/debian/rust-lldb.links
@@ -1 +1 @@
-usr/share/man/man1/lldb-14.1.gz usr/share/man/man1/rust-lldb.1.gz
+usr/share/man/man1/lldb-15.1.gz usr/share/man/man1/rust-lldb.1.gz
diff --git a/debian/rustc.links b/debian/rustc.links
index db024ff24..10826e2ef 100644
--- a/debian/rustc.links
+++ b/debian/rustc.links
@@ -1,6 +1,6 @@
-usr/bin/lld-14 usr/bin/rust-lld
-usr/bin/clang-14 usr/bin/rust-clang
-usr/bin/llvm-dwp-14 usr/bin/rust-llvm-dwp
+usr/bin/lld-15 usr/bin/rust-lld
+usr/bin/clang-15 usr/bin/rust-clang
+usr/bin/llvm-dwp-15 usr/bin/rust-llvm-dwp
# for -Z gcc-ld=lld, see compiler/rustc_codegen_ssa/src/back/link.rs for logic
usr/bin/rust-lld usr/lib/rustlib/${env:DEB_HOST_RUST_TYPE}/bin/gcc-ld/ld
usr/bin/rust-lld usr/lib/rustlib/${env:DEB_HOST_RUST_TYPE}/bin/gcc-ld/ld64
diff --git a/debian/upstream-tarball-unsuspicious.txt b/debian/upstream-tarball-unsuspicious.txt
index 216c81b8f..5d9dbaf38 100644
--- a/debian/upstream-tarball-unsuspicious.txt
+++ b/debian/upstream-tarball-unsuspicious.txt
@@ -5,9 +5,19 @@
# probably Doing It Wrong. Ask in #debian-rust or the mailing list for pointers.
# False-positive, file(1) misidentifies mime type
+compiler/rustc_error_codes/src/error_codes/E0469.md
+src/doc/reference/src/crates-and-source-files.md
+src/doc/reference/src/items/extern-crates.md
+src/doc/reference/src/items/modules.md
+src/doc/reference/src/types-redirect.html
+src/tools/clippy/src/docs/alloc_instead_of_core.txt
+src/tools/clippy/src/docs/only_used_in_recursion.txt
+vendor/chalk-solve-0.80.0/src/infer/test.rs
+vendor/getrandom-0.1.14/src/wasm32_stdweb.rs
vendor/itertools*/examples/iris.data
-vendor/regex/tests/unicode.rs
+vendor/minifier/src/js/tools.rs
vendor/regex/tests/suffix_reverse.rs
+vendor/regex/tests/unicode.rs
vendor/term/src/terminfo/parser/names.rs
# False-positive, "verylongtext" but OK
@@ -21,6 +31,7 @@ library/portable-simd/*.md
library/std/src/sys/sgx/abi/entry.S
library/stdarch/CONTRIBUTING.md
library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
+src/doc/*/CODE_OF_CONDUCT.md
src/doc/book/first-edition/src/the-stack-and-the-heap.md
src/doc/edition-guide/src/rust-2018/index.md
src/doc/edition-guide/src/rust-2021/disjoint-capture-in-closures.md
@@ -33,41 +44,43 @@ src/doc/rust-by-example/src/flow_control/if_let.md
src/doc/rust-by-example/src/std/arc.md
src/doc/rust-by-example/src/trait/dyn.md
src/doc/rust-by-example/src/unsafe/asm.md
+src/doc/rustc-dev-guide/src/*.md
+src/doc/rustc-dev-guide/src/*/*.md
src/doc/rustc/src/instrument-coverage.md
src/doc/rustc/src/lints/groups.md
-src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
+src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md
src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
+src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
src/doc/rustc/src/targets/known-issues.md
-src/doc/rustc-dev-guide/src/*.md
-src/doc/rustc-dev-guide/src/*/*.md
src/doc/rustdoc/src/*.md
-src/doc/*/CODE_OF_CONDUCT.md
src/doc/unstable-book/src/*/*.md
src/etc/third-party/README.txt
src/librustdoc/html/highlight/fixtures/sample.html
src/librustdoc/html/static/scrape-examples-help.md
-src/tools/rustfmt/*.md
-src/tools/rust-analyzer/docs/user/manual.adoc
+src/tools/clippy/src/docs/trailing_empty_array.txt
src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
-vendor/*/Cargo.toml
+src/tools/rust-analyzer/docs/user/manual.adoc
+src/tools/rustfmt/*.md
+vendor/*/*/*/LICENSE
+vendor/*/*/LICENSE
vendor/*/CHANGELOG.md
vendor/*/CODE_OF_CONDUCT.md
-vendor/*/README.md
-vendor/*/README.tpl
+vendor/*/Cargo.toml
vendor/*/LICENSE
vendor/*/LICENSE-MIT
-vendor/*/*/LICENSE
-vendor/*/*/*/LICENSE
+vendor/*/README.md
vendor/ahash/FAQ.md
vendor/ammonia/src/lib.rs
-vendor/clap/examples/derive_ref/README.md
+vendor/clap/examples/demo.md
+vendor/clap/examples/tutorial_*/*.md
vendor/generic-array/DESIGN.md
vendor/handlebars/src/lib.rs
+vendor/handlebars/src/render.rs
vendor/handlebars/src/template.rs
+vendor/lazy_static/src/lib.rs
vendor/maplit/README.rst
vendor/mdbook/CONTRIBUTING.md
vendor/miniz_oxide/Readme.md
-vendor/lazy_static/src/lib.rs
vendor/pulldown-cmark/tests/suite/footnotes.rs
vendor/rustc-demangle/src/legacy.rs
vendor/stable_deref_trait/src/lib.rs
@@ -76,15 +89,15 @@ vendor/tracing-subscriber/src/fmt/format/json.rs
vendor/unicase/src/lib.rs
vendor/unicode-normalization/src/stream_safe.rs
vendor/winapi/src/lib.rs
+vendor/windows-sys-0.*/src/Windows/Win32/*.rs
+vendor/windows-sys-0.*/src/Windows/Win32/*/*.rs
+vendor/windows-sys-0.*/src/Windows/Win32/*/*/*.rs
+vendor/windows-sys-0.*/src/Windows/Win32/*/*/*/*.rs
vendor/windows-sys/readme.md
vendor/windows-sys/src/Windows/Win32/*.rs
vendor/windows-sys/src/Windows/Win32/*/*.rs
vendor/windows-sys/src/Windows/Win32/*/*/*.rs
vendor/windows-sys/src/Windows/Win32/*/*/*/*.rs
-vendor/windows-sys-0.*/src/Windows/Win32/*.rs
-vendor/windows-sys-0.*/src/Windows/Win32/*/*.rs
-vendor/windows-sys-0.*/src/Windows/Win32/*/*/*.rs
-vendor/windows-sys-0.*/src/Windows/Win32/*/*/*/*.rs
# False-positive, audit-vendor-source automatically flags JS/C files
# The below ones are OK since they're actually part of rust's own source code
@@ -92,18 +105,20 @@ vendor/windows-sys-0.*/src/Windows/Win32/*/*/*/*.rs
src/ci/docker/scripts/qemu-bare-bones-addentropy.c
src/doc/book/*/ferris.js
src/doc/book/ferris.js
+src/doc/reference/src/attributes-redirect.html
src/doc/rustc-dev-guide/mermaid-init.js
src/etc/wasm32-shim.js
-src/librustdoc/html/static/js/*.js
src/librustdoc/html/static/.eslintrc.js
+src/librustdoc/html/static/js/*.js
src/test/auxiliary/rust_test_helpers.c
+src/test/run-make-fulldeps/*/*.c
src/test/run-make/*/*.c
src/test/run-make/wasm-*/*.js
-src/test/run-make-fulldeps/*/*.c
-src/test/rustdoc-js/*.js
src/test/rustdoc-js-std/*.js
-src/tools/rustdoc-js/tester.js
+src/test/rustdoc-js/*.js
+src/tools/error_index_generator/*.js
src/tools/rustdoc-gui/tester.js
+src/tools/rustdoc-js/tester.js
# Embedded libraries, justified in README.source
vendor/dlmalloc/src/dlmalloc.c
@@ -129,85 +144,85 @@ src/tools/clippy/.remarkrc
vendor/elasticlunr-rs/src/lang/*.rs
# False-positive, hand-editable small image
-src/etc/installer/gfx/
-src/doc/embedded-book/src/assets/*.png
-src/doc/embedded-book/src/assets/*.svg
-src/doc/embedded-book/src/assets/f3.jpg
-src/doc/embedded-book/src/assets/verify.jpeg
-src/doc/nomicon/src/img/safeandunsafe.svg
+src/doc/book/2018-edition/src/img/*.png
+src/doc/book/2018-edition/src/img/*.svg
+src/doc/book/2018-edition/src/img/ferris/*.svg
src/doc/book/second-edition/src/img/*.png
src/doc/book/second-edition/src/img/*.svg
-src/doc/book/src/img/ferris/*.svg
src/doc/book/src/img/*.png
src/doc/book/src/img/*.svg
-src/doc/book/2018-edition/src/img/ferris/*.svg
-src/doc/book/2018-edition/src/img/*.svg
-src/doc/book/2018-edition/src/img/*.png
+src/doc/book/src/img/ferris/*.svg
src/doc/book/tools/docx-to-md.xsl
-src/doc/rustc/src/images/*.png
+src/doc/embedded-book/src/assets/*.png
+src/doc/embedded-book/src/assets/*.svg
+src/doc/embedded-book/src/assets/f3.jpg
+src/doc/embedded-book/src/assets/verify.jpeg
+src/doc/nomicon/src/img/safeandunsafe.svg
+src/doc/rustc-dev-guide/src/img/*.png
src/doc/rustc-dev-guide/src/img/rustc_stages.svg
src/doc/rustc-dev-guide/src/queries/example-0.png
-src/doc/rustc-dev-guide/src/img/*.png
+src/doc/rustc/src/images/*.png
+src/etc/installer/gfx/
src/librustdoc/html/static/images/*.svg
src/librustdoc/html/static/images/favicon-*.png
src/test/mir-opt/coverage_graphviz.*.InstrumentCoverage.0.dot
src/tools/rust-analyzer/assets/logo-*.svg
-vendor/mdbook/src/theme/favicon.svg
vendor/mdbook/src/theme/favicon.png
-vendor/pretty_assertions-0.7.2/examples/*.png
+vendor/mdbook/src/theme/favicon.svg
+vendor/pretty_assertions/examples/*.png
# Example code
vendor/html5ever/examples/capi/tokenize.c
vendor/sysinfo/examples/simple.c
# Test data
-library/portable-simd/crates/core_simd/webdriver.json
+library/core/benches/str.rs
+library/core/tests/num/dec2flt/parse.rs
library/portable-simd/crates/core_simd/tests/mask_ops_impl/*.rs
+library/portable-simd/crates/core_simd/webdriver.json
library/std/src/sys/windows/path/tests.rs
library/stdarch/ci/gba.json
+library/stdarch/crates/std_detect/src/detect/test_data/*.auxv
library/stdarch/crates/stdarch-verify/arm-intrinsics.html
library/stdarch/crates/stdarch-verify/x86-intel.xml
-library/stdarch/crates/std_detect/src/detect/test_data/*.auxv
-library/core/benches/str.rs
-library/core/tests/num/dec2flt/parse.rs
-src/test/debuginfo/type-names.cdb.js
-src/test/mir-opt/*.mir
-src/test/mir-opt/*.diff
-src/test/mir-opt/*/*.mir
-src/test/mir-opt/*/*.diff
-src/test/rustdoc/tuples.link2_i32.html
src/test/*/*.rs
-src/test/*/*.stdout
-src/test/*/issues/*.rs
-src/test/*/*/issue-*.rs
-src/test/*/*/issues/*.rs
src/test/*/*.stderr
-src/test/*/*/*.rs
+src/test/*/*.stdout
src/test/*/*/*.json
+src/test/*/*/*.rs
src/test/*/*/*.stderr
src/test/*/*/*.stdout
-src/test/*/*/*/*.stdout
src/test/*/*/*/*.stderr
+src/test/*/*/*/*.stdout
src/test/*/*/*/*/*.stderr
-src/test/run-make/*-sgx-lvi/enclave/*/*/*.c
+src/test/*/*/issue-*.rs
+src/test/*/*/issues/*.rs
+src/test/*/issues/*.rs
+src/test/debuginfo/type-names.cdb.js
+src/test/mir-opt/*.diff
+src/test/mir-opt/*.mir
+src/test/mir-opt/*/*.diff
+src/test/mir-opt/*/*.mir
src/test/run-make/*-sgx-lvi/enclave/*.c
+src/test/run-make/*-sgx-lvi/enclave/*/*/*.c
src/test/rustdoc/*.html
+src/test/rustdoc/tuples.link2_i32.html
src/test/ui/macros/not-utf8.bin
src/tools/*/tests/*/*.stderr
src/tools/clippy/tests/ui-toml/*/*.stderr
src/tools/clippy/tests/ui-toml/large_include_file/too_big.txt
src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
-src/tools/rustfmt/tests/writemode/target/*.json
-src/tools/rustfmt/tests/writemode/target/*.xml
-src/tools/rustfmt/tests/source/*.rs
-src/tools/rustfmt/tests/source/*/*.rs
-src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs
src/tools/rust-analyzer/bench_data/numerous_macro_rules
-src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures/0005.rs
+src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_*.html
+src/tools/rust-analyzer/crates/parser/test_data/lexer/ok/*
src/tools/rust-analyzer/crates/project-model/test_data/*.json
src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt
-src/tools/rust-analyzer/crates/parser/test_data/lexer/ok/*
-src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_*.html
+src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures/0005.rs
+src/tools/rustfmt/tests/source/*.rs
+src/tools/rustfmt/tests/source/*/*.rs
+src/tools/rustfmt/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs
+src/tools/rustfmt/tests/writemode/target/*.json
+src/tools/rustfmt/tests/writemode/target/*.xml
vendor/annotate-snippets/tests/fixtures/no-color/strip_line_non_ws.toml
vendor/bstr/src/unicode/data/*Test.txt
vendor/cargo_metadata*/tests/test_samples.rs
@@ -221,6 +236,7 @@ vendor/fluent-syntax/benches/parser.rs
vendor/gimli-0*/fixtures/self/*
vendor/gimli/fixtures/self/*
vendor/gsgdt/tests/*.json
+vendor/handlebars/tests/helper_with_space.rs
vendor/html5ever/data/bench/*.html
vendor/idna/tests/IdnaTest*.txt
vendor/idna/tests/punycode_tests.json
@@ -245,8 +261,6 @@ vendor/regex/tests/fowler.rs
vendor/rustc-demangle/src/lib.rs
vendor/rustc-demangle/src/v0-large-test-symbols/early-recursion-limit
vendor/serde_json/tests/lexical/parse.rs
-vendor/sha-1-0*/tests/data/*.bin
-vendor/sha-1-0*/tests/data/*.blb
vendor/sha-1/tests/data/*.blb
vendor/sha2/tests/data/*.blb
vendor/term/tests/data/*
@@ -278,101 +292,115 @@ src/librustdoc/html/static/fonts/*.woff2
vendor/bstr/src/unicode/fsm/*.dfa
# file brokenness (detected as Algol source code)
-vendor/digest/src/core_api/wrapper.rs
-vendor/digest/src/core_api/rt_variable.rs
+compiler/rustc_apfloat/src/lib.rs
+compiler/rustc_driver/src/lib.rs
+compiler/rustc_expand/src/mbe/quoted.rs
+compiler/rustc_macros/src/symbols/tests.rs
+library/std/src/sys/unix/process/process_unix.rs
+library/stdarch/crates/stdarch-verify/src/lib.rs
+src/librustdoc/html/markdown/tests.rs
+src/test/run-make-fulldeps/symbol-visibility/Makefile
+src/test/ui/proc-macro/auxiliary/*.rs
+src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+src/tools/clippy/src/docs/from_str_radix_10.txt
+src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
+src/tools/rustfmt/src/formatting.rs
+src/tools/rustfmt/src/parse/parser.rs
+src/tools/rustfmt/src/string.rs
vendor/ahash/src/hash_quality_test.rs
+vendor/ahash/src/lib.rs
+vendor/aho-corasick/src/nfa.rs
+vendor/askama_shared/src/generator.rs
+vendor/block-buffer/tests/mod.rs
vendor/clap/src/derive.rs
+vendor/compiler_builtins/libm/src/math/atan.rs
+vendor/datafrog/src/lib.rs
+vendor/digest/src/core_api/rt_variable.rs
+vendor/digest/src/core_api/wrapper.rs
+vendor/digest/src/dev.rs
+vendor/env_logger-0.*/src/fmt/writer/mod.rs
+vendor/env_logger/src/fmt/writer/mod.rs
+vendor/flate2/src/mem.rs
+vendor/flate2/src/zio.rs
+vendor/futures-macro/src/lib.rs
vendor/futures-macro/src/select.rs
-vendor/nom/src/error.rs
-vendor/nom/src/internal.rs
+vendor/gimli-0.25.0/src/read/aranges.rs
+vendor/gimli-0.25.0/src/read/line.rs
+vendor/gimli-0.25.0/src/read/loclists.rs
+vendor/gimli-0.25.0/src/read/lookup.rs
+vendor/gimli-0.25.0/src/read/rnglists.rs
+vendor/gimli-0.25.0/src/read/unit.rs
+vendor/gimli/src/read/aranges.rs
+vendor/gimli/src/read/line.rs
+vendor/gimli/src/read/loclists.rs
+vendor/gimli/src/read/lookup.rs
+vendor/gimli/src/read/rnglists.rs
+vendor/gimli/src/read/unit.rs
+vendor/indoc/src/lib.rs
+vendor/libm/src/math/atan.rs
+vendor/miniz_oxide-0.4.0/src/deflate/mod.rs
+vendor/miniz_oxide-0.4.0/src/inflate/mod.rs
+vendor/miniz_oxide/src/deflate/mod.rs
+vendor/miniz_oxide/src/inflate/mod.rs
+vendor/nom/src/bits/complete.rs
vendor/nom/src/bits/mod.rs
vendor/nom/src/bits/streaming.rs
-vendor/nom/src/bits/complete.rs
-vendor/nom/src/bytes/streaming.rs
-vendor/nom/src/bytes/complete.rs
vendor/nom/src/branch/mod.rs
vendor/nom/src/branch/tests.rs
-vendor/nom/src/multi/tests.rs
+vendor/nom/src/bytes/complete.rs
+vendor/nom/src/bytes/streaming.rs
+vendor/nom/src/character/complete.rs
+vendor/nom/src/character/streaming.rs
+vendor/nom/src/combinator/mod.rs
+vendor/nom/src/combinator/tests.rs
+vendor/nom/src/error.rs
+vendor/nom/src/internal.rs
vendor/nom/src/multi/mod.rs
+vendor/nom/src/multi/tests.rs
vendor/nom/src/number/complete.rs
vendor/nom/src/number/streaming.rs
-vendor/nom/src/combinator/tests.rs
-vendor/nom/src/character/streaming.rs
-vendor/nom/src/character/complete.rs
vendor/nom/src/sequence/mod.rs
-vendor/nom/tests/multiline.rs
vendor/nom/tests/css.rs
-vendor/askama_shared/src/generator.rs
-vendor/block-buffer/tests/mod.rs
-src/tools/rustfmt/src/parse/parser.rs
-vendor/libm/src/math/atan.rs
-vendor/pest/tests/calculator.rs
-vendor/pest/src/position.rs
+vendor/nom/tests/issues.rs
+vendor/nom/tests/json.rs
+vendor/nom/tests/mp4.rs
+vendor/nom/tests/multiline.rs
vendor/pest/src/parser_state.rs
+vendor/pest/src/position.rs
vendor/pest/src/span.rs
-vendor/aho-corasick/src/nfa.rs
-vendor/miniz_oxide/src/deflate/mod.rs
-vendor/miniz_oxide/src/inflate/mod.rs
-vendor/miniz_oxide-0.4.0/src/deflate/mod.rs
-vendor/miniz_oxide-0.4.0/src/inflate/mod.rs
-vendor/thiserror-impl/src/attr.rs
-vendor/shlex/src/lib.rs
-vendor/semver/src/parse.rs
-vendor/rustc-rayon/tests/sort-panic-safe.rs
-vendor/url/src/parser.rs
-vendor/utf-8/tests/unit.rs
-vendor/rustversion/src/attr.rs
-vendor/env_logger/src/fmt/writer/mod.rs
-vendor/env_logger-0.*/src/fmt/writer/mod.rs
+vendor/pest/tests/calculator.rs
vendor/pest_generator/src/generator.rs
-vendor/digest/src/dev.rs
vendor/proc-macro2/src/parse.rs
-vendor/xz2/src/stream.rs
-vendor/xz2/src/bufread.rs
-vendor/digest-0.8.1/src/dev.rs
-vendor/pulldown-cmark/tests/lib.rs
-vendor/pulldown-cmark/src/linklabel.rs
vendor/pulldown-cmark/benches/html_rendering.rs
-vendor/gimli/src/read/aranges.rs
-vendor/gimli/src/read/rnglists.rs
-vendor/gimli/src/read/unit.rs
-vendor/gimli/src/read/loclists.rs
-vendor/gimli/src/read/line.rs
-vendor/gimli/src/read/lookup.rs
-vendor/gimli-0.25.0/src/read/aranges.rs
-vendor/gimli-0.25.0/src/read/rnglists.rs
-vendor/gimli-0.25.0/src/read/unit.rs
-vendor/gimli-0.25.0/src/read/loclists.rs
-vendor/gimli-0.25.0/src/read/line.rs
-vendor/gimli-0.25.0/src/read/lookup.rs
-vendor/regex-automata/src/regex.rs
+vendor/pulldown-cmark/src/linklabel.rs
+vendor/pulldown-cmark/tests/lib.rs
vendor/rayon/tests/sort-panic-safe.rs
-vendor/syn/tests/test_meta.rs
-vendor/syn/src/punctuated.rs
-vendor/syn/src/derive.rs
-vendor/syn/src/token.rs
+vendor/regex-automata/src/regex.rs
+vendor/rustc-rayon/tests/sort-panic-safe.rs
+vendor/rustversion/src/attr.rs
+vendor/rustversion/src/lib.rs
+vendor/semver/src/parse.rs
+vendor/sha2/src/sha256.rs
+vendor/sha2/src/sha512.rs
+vendor/shlex/src/lib.rs
+vendor/snap/src/compress.rs
+vendor/snap/src/decompress.rs
+vendor/syn/src/attr.rs
+vendor/syn/src/custom_punctuation.rs
vendor/syn/src/data.rs
-vendor/syn/src/ty.rs
-vendor/syn/src/stmt.rs
+vendor/syn/src/derive.rs
+vendor/syn/src/group.rs
vendor/syn/src/pat.rs
-vendor/syn/src/custom_punctuation.rs
vendor/syn/src/path.rs
-vendor/syn/src/attr.rs
-vendor/syn/src/group.rs
-vendor/sha2/src/sha512.rs
-vendor/sha2/src/sha256.rs
-vendor/compiler_builtins/libm/src/math/atan.rs
-vendor/snap/src/decompress.rs
-vendor/snap/src/compress.rs
-vendor/flate2/src/mem.rs
-vendor/flate2/src/zio.rs
-compiler/rustc_expand/src/mbe/quoted.rs
-compiler/rustc_macros/src/symbols/tests.rs
-src/librustdoc/html/markdown/tests.rs
-src/test/run-make-fulldeps/symbol-visibility/Makefile
-src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
-src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
-src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
-src/tools/rustfmt/src/string.rs
-src/tools/rustfmt/src/formatting.rs
-library/std/src/sys/unix/process/process_unix.rs
+vendor/syn/src/punctuated.rs
+vendor/syn/src/stmt.rs
+vendor/syn/src/token.rs
+vendor/syn/src/ty.rs
+vendor/syn/tests/test_meta.rs
+vendor/thiserror-impl/src/attr.rs
+vendor/url/src/parser.rs
+vendor/utf-8/benches/from_utf8_lossy.rs
+vendor/utf-8/tests/unit.rs
+vendor/xz2/src/bufread.rs
+vendor/xz2/src/stream.rs
diff --git a/git-commit-hash b/git-commit-hash
index 7cc889ca0..19793c62f 100644
--- a/git-commit-hash
+++ b/git-commit-hash
@@ -1 +1 @@
-a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52 \ No newline at end of file
+897e37553bba8b42751c67658967889d11ecd120 \ No newline at end of file
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index cc8da7bcc..80b067812 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -30,13 +30,13 @@ extern "Rust" {
#[rustc_allocator]
#[rustc_allocator_nounwind]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
- #[cfg_attr(not(bootstrap), rustc_deallocator)]
+ #[rustc_deallocator]
#[rustc_allocator_nounwind]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
- #[cfg_attr(not(bootstrap), rustc_reallocator)]
+ #[rustc_reallocator]
#[rustc_allocator_nounwind]
fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
- #[cfg_attr(not(bootstrap), rustc_allocator_zeroed)]
+ #[rustc_allocator_zeroed]
#[rustc_allocator_nounwind]
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
}
diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs
index 7d560964d..b2f019459 100644
--- a/library/alloc/src/alloc/tests.rs
+++ b/library/alloc/src/alloc/tests.rs
@@ -15,7 +15,7 @@ fn allocate_zeroed() {
let end = i.add(layout.size());
while i < end {
assert_eq!(*i, 0);
- i = i.offset(1);
+ i = i.add(1);
}
Global.deallocate(ptr.as_non_null_ptr(), layout);
}
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index c1ceeb0de..65e323c9e 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1,4 +1,4 @@
-//! A pointer type for heap allocation.
+//! The `Box<T>` type for heap allocation.
//!
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
@@ -151,6 +151,8 @@ use core::async_iter::AsyncIterator;
use core::borrow;
use core::cmp::Ordering;
use core::convert::{From, TryFrom};
+#[cfg(not(bootstrap))]
+use core::error::Error;
use core::fmt;
use core::future::Future;
use core::hash::{Hash, Hasher};
@@ -174,6 +176,9 @@ use crate::borrow::Cow;
use crate::raw_vec::RawVec;
#[cfg(not(no_global_oom_handling))]
use crate::str::from_boxed_utf8_unchecked;
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+use crate::string::String;
#[cfg(not(no_global_oom_handling))]
use crate::vec::Vec;
@@ -1480,7 +1485,7 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
/// Converts a `&[T]` into a `Box<[T]>`
///
/// This conversion allocates on the heap
- /// and performs a copy of `slice`.
+ /// and performs a copy of `slice` and its contents.
///
/// # Examples
/// ```rust
@@ -2085,3 +2090,304 @@ impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
(**self).size_hint()
}
}
+
+#[cfg(not(bootstrap))]
+impl dyn Error {
+ #[inline]
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[rustc_allow_incoherent_impl]
+ /// Attempts to downcast the box to a concrete type.
+ pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
+ if self.is::<T>() {
+ unsafe {
+ let raw: *mut dyn Error = Box::into_raw(self);
+ Ok(Box::from_raw(raw as *mut T))
+ }
+ } else {
+ Err(self)
+ }
+ }
+}
+
+#[cfg(not(bootstrap))]
+impl dyn Error + Send {
+ #[inline]
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[rustc_allow_incoherent_impl]
+ /// Attempts to downcast the box to a concrete type.
+ pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
+ let err: Box<dyn Error> = self;
+ <dyn Error>::downcast(err).map_err(|s| unsafe {
+ // Reapply the `Send` marker.
+ mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
+ })
+ }
+}
+
+#[cfg(not(bootstrap))]
+impl dyn Error + Send + Sync {
+ #[inline]
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[rustc_allow_incoherent_impl]
+ /// Attempts to downcast the box to a concrete type.
+ pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
+ let err: Box<dyn Error> = self;
+ <dyn Error>::downcast(err).map_err(|s| unsafe {
+ // Reapply the `Send + Sync` marker.
+ mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
+ })
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
+ /// Converts a type of [`Error`] into a box of dyn [`Error`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::fmt;
+ /// use std::mem;
+ ///
+ /// #[derive(Debug)]
+ /// struct AnError;
+ ///
+ /// impl fmt::Display for AnError {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "An error")
+ /// }
+ /// }
+ ///
+ /// impl Error for AnError {}
+ ///
+ /// let an_error = AnError;
+ /// assert!(0 == mem::size_of_val(&an_error));
+ /// let a_boxed_error = Box::<dyn Error>::from(an_error);
+ /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ fn from(err: E) -> Box<dyn Error + 'a> {
+ Box::new(err)
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
+ /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
+ /// dyn [`Error`] + [`Send`] + [`Sync`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::fmt;
+ /// use std::mem;
+ ///
+ /// #[derive(Debug)]
+ /// struct AnError;
+ ///
+ /// impl fmt::Display for AnError {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "An error")
+ /// }
+ /// }
+ ///
+ /// impl Error for AnError {}
+ ///
+ /// unsafe impl Send for AnError {}
+ ///
+ /// unsafe impl Sync for AnError {}
+ ///
+ /// let an_error = AnError;
+ /// assert!(0 == mem::size_of_val(&an_error));
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
+ /// assert!(
+ /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
+ Box::new(err)
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<String> for Box<dyn Error + Send + Sync> {
+ /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::mem;
+ ///
+ /// let a_string_error = "a string error".to_string();
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
+ /// assert!(
+ /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ #[inline]
+ fn from(err: String) -> Box<dyn Error + Send + Sync> {
+ struct StringError(String);
+
+ impl Error for StringError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ &self.0
+ }
+ }
+
+ impl fmt::Display for StringError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(&self.0, f)
+ }
+ }
+
+ // Purposefully skip printing "StringError(..)"
+ impl fmt::Debug for StringError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&self.0, f)
+ }
+ }
+
+ Box::new(StringError(err))
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "string_box_error", since = "1.6.0")]
+impl From<String> for Box<dyn Error> {
+ /// Converts a [`String`] into a box of dyn [`Error`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::mem;
+ ///
+ /// let a_string_error = "a string error".to_string();
+ /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
+ /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ fn from(str_err: String) -> Box<dyn Error> {
+ let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
+ let err2: Box<dyn Error> = err1;
+ err2
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
+ /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
+ ///
+ /// [`str`]: prim@str
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::mem;
+ ///
+ /// let a_str_error = "a str error";
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
+ /// assert!(
+ /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ #[inline]
+ fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
+ From::from(String::from(err))
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "string_box_error", since = "1.6.0")]
+impl From<&str> for Box<dyn Error> {
+ /// Converts a [`str`] into a box of dyn [`Error`].
+ ///
+ /// [`str`]: prim@str
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::mem;
+ ///
+ /// let a_str_error = "a str error";
+ /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
+ /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ fn from(err: &str) -> Box<dyn Error> {
+ From::from(String::from(err))
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "cow_box_error", since = "1.22.0")]
+impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
+ /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::mem;
+ /// use std::borrow::Cow;
+ ///
+ /// let a_cow_str_error = Cow::from("a str error");
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
+ /// assert!(
+ /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
+ From::from(String::from(err))
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "cow_box_error", since = "1.22.0")]
+impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
+ /// Converts a [`Cow`] into a box of dyn [`Error`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::mem;
+ /// use std::borrow::Cow;
+ ///
+ /// let a_cow_str_error = Cow::from("a str error");
+ /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
+ /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+ /// ```
+ fn from(err: Cow<'a, str>) -> Box<dyn Error> {
+ From::from(String::from(err))
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "box_error", since = "1.8.0")]
+impl<T: core::error::Error> core::error::Error for Box<T> {
+ #[allow(deprecated, deprecated_in_future)]
+ fn description(&self) -> &str {
+ core::error::Error::description(&**self)
+ }
+
+ #[allow(deprecated)]
+ fn cause(&self) -> Option<&dyn core::error::Error> {
+ core::error::Error::cause(&**self)
+ }
+
+ fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
+ core::error::Error::source(&**self)
+ }
+}
diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs
index 649ccfcaa..0a20c74b0 100644
--- a/library/alloc/src/boxed/thin.rs
+++ b/library/alloc/src/boxed/thin.rs
@@ -2,6 +2,8 @@
// https://github.com/matthieu-m/rfc2580/blob/b58d1d3cba0d4b5e859d3617ea2d0943aaa31329/examples/thin.rs
// by matthieu-m
use crate::alloc::{self, Layout, LayoutError};
+#[cfg(not(bootstrap))]
+use core::error::Error;
use core::fmt::{self, Debug, Display, Formatter};
use core::marker::PhantomData;
#[cfg(not(no_global_oom_handling))]
@@ -271,3 +273,11 @@ impl<H> WithHeader<H> {
Layout::new::<H>().extend(value_layout)
}
}
+
+#[cfg(not(bootstrap))]
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized + Error> Error for ThinBox<T> {
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ self.deref().source()
+ }
+}
diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs
index 197e7aaac..4583bc9a1 100644
--- a/library/alloc/src/collections/binary_heap.rs
+++ b/library/alloc/src/collections/binary_heap.rs
@@ -1010,7 +1010,8 @@ impl<T> BinaryHeap<T> {
/// current length. The allocator may reserve more space to speculatively
/// avoid frequent allocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional` if it returns
- /// `Ok(())`. Does nothing if capacity is already sufficient.
+ /// `Ok(())`. Does nothing if capacity is already sufficient. This method
+ /// preserves the contents even if an error occurs.
///
/// # Errors
///
diff --git a/library/alloc/src/collections/btree/dedup_sorted_iter.rs b/library/alloc/src/collections/btree/dedup_sorted_iter.rs
index 60bf83b83..17ee78045 100644
--- a/library/alloc/src/collections/btree/dedup_sorted_iter.rs
+++ b/library/alloc/src/collections/btree/dedup_sorted_iter.rs
@@ -3,7 +3,9 @@ use core::iter::Peekable;
/// A iterator for deduping the key of a sorted iterator.
/// When encountering the duplicated key, only the last key-value pair is yielded.
///
-/// Used by [`BTreeMap::bulk_build_from_sorted_iter`].
+/// Used by [`BTreeMap::bulk_build_from_sorted_iter`][1].
+///
+/// [1]: crate::collections::BTreeMap::bulk_build_from_sorted_iter
pub struct DedupSortedIter<K, V, I>
where
I: Iterator<Item = (K, V)>,
diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs
index b6eecf9b0..cd7cdc192 100644
--- a/library/alloc/src/collections/btree/map/entry.rs
+++ b/library/alloc/src/collections/btree/map/entry.rs
@@ -133,6 +133,17 @@ impl<'a, K: Debug + Ord, V: Debug, A: Allocator + Clone> fmt::Display
}
}
+#[cfg(not(bootstrap))]
+#[unstable(feature = "map_try_insert", issue = "82766")]
+impl<'a, K: core::fmt::Debug + Ord, V: core::fmt::Debug> core::error::Error
+ for crate::collections::btree_map::OccupiedError<'a, K, V>
+{
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "key already exists"
+ }
+}
+
impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index d831161bc..f1d2d3b30 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -318,7 +318,7 @@ impl<BorrowType: marker::BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type>
pub fn ascend(
self,
) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> {
- assert!(BorrowType::PERMITS_TRAVERSAL);
+ let _ = BorrowType::TRAVERSAL_PERMIT;
// We need to use raw pointers to nodes because, if BorrowType is marker::ValMut,
// there might be outstanding mutable references to values that we must not invalidate.
let leaf_ptr: *const _ = Self::as_leaf_ptr(&self);
@@ -1003,7 +1003,7 @@ impl<BorrowType: marker::BorrowType, K, V>
/// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should
/// both, upon success, do nothing.
pub fn descend(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
- assert!(BorrowType::PERMITS_TRAVERSAL);
+ let _ = BorrowType::TRAVERSAL_PERMIT;
// We need to use raw pointers to nodes because, if BorrowType is
// marker::ValMut, there might be outstanding mutable references to
// values that we must not invalidate. There's no worry accessing the
@@ -1666,15 +1666,17 @@ pub mod marker {
pub struct ValMut<'a>(PhantomData<&'a mut ()>);
pub trait BorrowType {
- // Whether node references of this borrow type allow traversing
- // to other nodes in the tree.
- const PERMITS_TRAVERSAL: bool = true;
+ // If node references of this borrow type allow traversing to other
+ // nodes in the tree, this constant can be evaluated. Thus reading it
+ // serves as a compile-time assertion.
+ const TRAVERSAL_PERMIT: () = ();
}
impl BorrowType for Owned {
- // Traversal isn't needed, it happens using the result of `borrow_mut`.
+ // Reject evaluation, because traversal isn't needed. Instead traversal
+ // happens using the result of `borrow_mut`.
// By disabling traversal, and only creating new references to roots,
// we know that every reference of the `Owned` type is to a root node.
- const PERMITS_TRAVERSAL: bool = false;
+ const TRAVERSAL_PERMIT: () = panic!();
}
impl BorrowType for Dying {}
impl<'a> BorrowType for Immut<'a> {}
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index e21c8aa3b..6480fcaf9 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1570,7 +1570,7 @@ impl<'a, T> CursorMut<'a, T> {
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
/// This operation should compute in *O*(1) time.
- // `push_front` continues to point to "ghost" when it addes a node to mimic
+ // `push_front` continues to point to "ghost" when it adds a node to mimic
// the behavior of `insert_before` on an empty list.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn push_front(&mut self, elt: T) {
diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs
index 628a5b155..21d0def08 100644
--- a/library/alloc/src/collections/mod.rs
+++ b/library/alloc/src/collections/mod.rs
@@ -152,3 +152,7 @@ trait SpecExtend<I: IntoIterator> {
/// Extends `self` with the contents of the given iterator.
fn spec_extend(&mut self, iter: I);
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "try_reserve", since = "1.57.0")]
+impl core::error::Error for TryReserveError {}
diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs
index 05f94da6d..41baa7102 100644
--- a/library/alloc/src/collections/vec_deque/drain.rs
+++ b/library/alloc/src/collections/vec_deque/drain.rs
@@ -1,10 +1,12 @@
+use core::fmt;
use core::iter::FusedIterator;
+use core::marker::PhantomData;
+use core::mem::{self, MaybeUninit};
use core::ptr::{self, NonNull};
-use core::{fmt, mem};
use crate::alloc::{Allocator, Global};
-use super::{count, Iter, VecDeque};
+use super::{count, wrap_index, VecDeque};
/// A draining iterator over the elements of a `VecDeque`.
///
@@ -20,18 +22,24 @@ pub struct Drain<
> {
after_tail: usize,
after_head: usize,
- iter: Iter<'a, T>,
+ ring: NonNull<[T]>,
+ tail: usize,
+ head: usize,
deque: NonNull<VecDeque<T, A>>,
+ _phantom: PhantomData<&'a T>,
}
impl<'a, T, A: Allocator> Drain<'a, T, A> {
pub(super) unsafe fn new(
after_tail: usize,
after_head: usize,
- iter: Iter<'a, T>,
+ ring: &'a [MaybeUninit<T>],
+ tail: usize,
+ head: usize,
deque: NonNull<VecDeque<T, A>>,
) -> Self {
- Drain { after_tail, after_head, iter, deque }
+ let ring = unsafe { NonNull::new_unchecked(ring as *const [MaybeUninit<T>] as *mut _) };
+ Drain { after_tail, after_head, ring, tail, head, deque, _phantom: PhantomData }
}
}
@@ -41,7 +49,9 @@ impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
f.debug_tuple("Drain")
.field(&self.after_tail)
.field(&self.after_head)
- .field(&self.iter)
+ .field(&self.ring)
+ .field(&self.tail)
+ .field(&self.head)
.finish()
}
}
@@ -118,12 +128,21 @@ impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
#[inline]
fn next(&mut self) -> Option<T> {
- self.iter.next().map(|elt| unsafe { ptr::read(elt) })
+ if self.tail == self.head {
+ return None;
+ }
+ let tail = self.tail;
+ self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
+ // Safety:
+ // - `self.tail` in a ring buffer is always a valid index.
+ // - `self.head` and `self.tail` equality is checked above.
+ unsafe { Some(ptr::read(self.ring.as_ptr().get_unchecked_mut(tail))) }
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
+ let len = count(self.tail, self.head, self.ring.len());
+ (len, Some(len))
}
}
@@ -131,7 +150,14 @@ impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
#[inline]
fn next_back(&mut self) -> Option<T> {
- self.iter.next_back().map(|elt| unsafe { ptr::read(elt) })
+ if self.tail == self.head {
+ return None;
+ }
+ self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
+ // Safety:
+ // - `self.head` in a ring buffer is always a valid index.
+ // - `self.head` and `self.tail` equality is checked above.
+ unsafe { Some(ptr::read(self.ring.as_ptr().get_unchecked_mut(self.head))) }
}
}
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 4d895d837..e3f4deb08 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -794,7 +794,8 @@ impl<T, A: Allocator> VecDeque<T, A> {
/// in the given deque. The collection may reserve more space to speculatively avoid
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional` if it returns
- /// `Ok(())`. Does nothing if capacity is already sufficient.
+ /// `Ok(())`. Does nothing if capacity is already sufficient. This method
+ /// preserves the contents even if an error occurs.
///
/// # Errors
///
@@ -1333,9 +1334,8 @@ impl<T, A: Allocator> VecDeque<T, A> {
// it. We do not write to `self` nor reborrow to a mutable reference.
// Hence the raw pointer we created above, for `deque`, remains valid.
let ring = self.buffer_as_slice();
- let iter = Iter::new(ring, drain_tail, drain_head);
- Drain::new(drain_head, head, iter, deque)
+ Drain::new(drain_head, head, ring, drain_tail, drain_head, deque)
}
}
@@ -2447,8 +2447,8 @@ impl<T, A: Allocator> VecDeque<T, A> {
let mut right_offset = 0;
for i in left_edge..right_edge {
right_offset = (i - left_edge) % (cap - right_edge);
- let src: isize = (right_edge + right_offset) as isize;
- ptr::swap(buf.add(i), buf.offset(src));
+ let src = right_edge + right_offset;
+ ptr::swap(buf.add(i), buf.add(src));
}
let n_ops = right_edge - left_edge;
left_edge += n_ops;
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index ae61b1f1e..aede6d54c 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -436,9 +436,9 @@ impl CString {
///
/// unsafe {
/// assert_eq!(b'f', *ptr as u8);
- /// assert_eq!(b'o', *ptr.offset(1) as u8);
- /// assert_eq!(b'o', *ptr.offset(2) as u8);
- /// assert_eq!(b'\0', *ptr.offset(3) as u8);
+ /// assert_eq!(b'o', *ptr.add(1) as u8);
+ /// assert_eq!(b'o', *ptr.add(2) as u8);
+ /// assert_eq!(b'\0', *ptr.add(3) as u8);
///
/// // retake pointer to free memory
/// let _ = CString::from_raw(ptr);
@@ -1121,3 +1121,29 @@ impl CStr {
CString::from(self)
}
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::error::Error for NulError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "nul byte found in data"
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
+impl core::error::Error for FromVecWithNulError {}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "cstring_into", since = "1.7.0")]
+impl core::error::Error for IntoStringError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "C string contained non-utf8 bytes"
+ }
+
+ fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
+ Some(self.__source())
+ }
+}
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 8b6f40548..8619467c2 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -56,10 +56,6 @@
//! [`Rc`]: rc
//! [`RefCell`]: core::cell
-// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
-// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// rustc itself never sets the feature, so this line has no affect there.
-#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
@@ -77,6 +73,10 @@
))]
#![no_std]
#![needs_allocator]
+// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
//
// Lints:
#![deny(unsafe_op_in_unsafe_fn)]
@@ -111,6 +111,8 @@
#![feature(const_pin)]
#![feature(cstr_from_bytes_until_nul)]
#![feature(dispatch_from_dyn)]
+#![cfg_attr(not(bootstrap), feature(error_generic_member_access))]
+#![cfg_attr(not(bootstrap), feature(error_in_core))]
#![feature(exact_size_is_empty)]
#![feature(extend_one)]
#![feature(fmt_internals)]
@@ -127,10 +129,12 @@
#![feature(nonnull_slice_from_raw_parts)]
#![feature(pattern)]
#![feature(pointer_byte_offsets)]
+#![cfg_attr(not(bootstrap), feature(provide_any))]
#![feature(ptr_internals)]
#![feature(ptr_metadata)]
#![feature(ptr_sub_ptr)]
#![feature(receiver_trait)]
+#![feature(saturating_int_impl)]
#![feature(set_ptr_value)]
#![feature(slice_from_ptr_range)]
#![feature(slice_group_by)]
@@ -145,6 +149,7 @@
#![feature(unchecked_math)]
#![feature(unicode_internals)]
#![feature(unsize)]
+#![feature(utf8_chunks)]
#![feature(std_internals)]
//
// Language features:
@@ -164,7 +169,7 @@
#![cfg_attr(not(test), feature(generator_trait))]
#![feature(hashmap_internals)]
#![feature(lang_items)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
@@ -178,6 +183,7 @@
#![feature(unboxed_closures)]
#![feature(unsized_fn_params)]
#![feature(c_unwind)]
+#![feature(with_negative_coherence)]
//
// Rustdoc features:
#![feature(doc_cfg)]
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index 88eb6aa7a..5198bf297 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -107,6 +107,8 @@ macro_rules! vec {
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
+/// let (x, y) = (1, 2);
+/// format!("{x} + {y} = 3");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index b89b03683..6d247681c 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1142,7 +1142,7 @@ impl<T: Clone> Rc<T> {
/// be cloned.
///
/// See also [`get_mut`], which will fail rather than cloning the inner value
- /// or diassociating [`Weak`] pointers.
+ /// or disassociating [`Weak`] pointers.
///
/// [`clone`]: Clone::clone
/// [`get_mut`]: Rc::get_mut
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 63d4d9452..bcd3f49e2 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -1,82 +1,12 @@
-//! A dynamically-sized view into a contiguous sequence, `[T]`.
+//! Utilities for the slice primitive type.
//!
//! *[See also the slice primitive type](slice).*
//!
-//! Slices are a view into a block of memory represented as a pointer and a
-//! length.
+//! Most of the structs in this module are iterator types which can only be created
+//! using a certain function. For example, `slice.iter()` yields an [`Iter`].
//!
-//! ```
-//! // slicing a Vec
-//! let vec = vec![1, 2, 3];
-//! let int_slice = &vec[..];
-//! // coercing an array to a slice
-//! let str_slice: &[&str] = &["one", "two", "three"];
-//! ```
-//!
-//! Slices are either mutable or shared. The shared slice type is `&[T]`,
-//! while the mutable slice type is `&mut [T]`, where `T` represents the element
-//! type. For example, you can mutate the block of memory that a mutable slice
-//! points to:
-//!
-//! ```
-//! let x = &mut [1, 2, 3];
-//! x[1] = 7;
-//! assert_eq!(x, &[1, 7, 3]);
-//! ```
-//!
-//! Here are some of the things this module contains:
-//!
-//! ## Structs
-//!
-//! There are several structs that are useful for slices, such as [`Iter`], which
-//! represents iteration over a slice.
-//!
-//! ## Trait Implementations
-//!
-//! There are several implementations of common traits for slices. Some examples
-//! include:
-//!
-//! * [`Clone`]
-//! * [`Eq`], [`Ord`] - for slices whose element type are [`Eq`] or [`Ord`].
-//! * [`Hash`] - for slices whose element type is [`Hash`].
-//!
-//! ## Iteration
-//!
-//! The slices implement `IntoIterator`. The iterator yields references to the
-//! slice elements.
-//!
-//! ```
-//! let numbers = &[0, 1, 2];
-//! for n in numbers {
-//! println!("{n} is a number!");
-//! }
-//! ```
-//!
-//! The mutable slice yields mutable references to the elements:
-//!
-//! ```
-//! let mut scores = [7, 8, 9];
-//! for score in &mut scores[..] {
-//! *score += 1;
-//! }
-//! ```
-//!
-//! This iterator yields mutable references to the slice's elements, so while
-//! the element type of the slice is `i32`, the element type of the iterator is
-//! `&mut i32`.
-//!
-//! * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
-//! iterators.
-//! * Further methods that return iterators are [`.split`], [`.splitn`],
-//! [`.chunks`], [`.windows`] and more.
-//!
-//! [`Hash`]: core::hash::Hash
-//! [`.iter`]: slice::iter
-//! [`.iter_mut`]: slice::iter_mut
-//! [`.split`]: slice::split
-//! [`.splitn`]: slice::splitn
-//! [`.chunks`]: slice::chunks
-//! [`.windows`]: slice::windows
+//! A few functions are provided to create a slice from a value reference
+//! or from a raw pointer.
#![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
// It's cleaner to just turn off the unused_imports warning than to fix them.
@@ -1024,7 +954,7 @@ where
// Consume the greater side.
// If equal, prefer the right run to maintain stability.
unsafe {
- let to_copy = if is_less(&*right.offset(-1), &*left.offset(-1)) {
+ let to_copy = if is_less(&*right.sub(1), &*left.sub(1)) {
decrement_and_get(left)
} else {
decrement_and_get(right)
@@ -1038,12 +968,12 @@ where
unsafe fn get_and_increment<T>(ptr: &mut *mut T) -> *mut T {
let old = *ptr;
- *ptr = unsafe { ptr.offset(1) };
+ *ptr = unsafe { ptr.add(1) };
old
}
unsafe fn decrement_and_get<T>(ptr: &mut *mut T) -> *mut T {
- *ptr = unsafe { ptr.offset(-1) };
+ *ptr = unsafe { ptr.sub(1) };
*ptr
}
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index d5ed2c4ad..b28d20cda 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -1,26 +1,6 @@
-//! Unicode string slices.
+//! Utilities for the `str` primitive type.
//!
//! *[See also the `str` primitive type](str).*
-//!
-//! The `&str` type is one of the two main string types, the other being `String`.
-//! Unlike its `String` counterpart, its contents are borrowed.
-//!
-//! # Basic Usage
-//!
-//! A basic string declaration of `&str` type:
-//!
-//! ```
-//! let hello_world = "Hello, World!";
-//! ```
-//!
-//! Here we have declared a string literal, also known as a string slice.
-//! String literals have a static lifetime, which means the string `hello_world`
-//! is guaranteed to be valid for the duration of the entire program.
-//! We can explicitly specify `hello_world`'s lifetime as well:
-//!
-//! ```
-//! let hello_world: &'static str = "Hello, world!";
-//! ```
#![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
@@ -71,6 +51,8 @@ pub use core::str::{RSplit, Split};
pub use core::str::{RSplitN, SplitN};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{RSplitTerminator, SplitTerminator};
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+pub use core::str::{Utf8Chunk, Utf8Chunks};
/// Note: `str` in `Concat<str>` is not meaningful here.
/// This type parameter of the trait only exists to enable another impl.
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index a5118e533..f2448396c 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -44,6 +44,8 @@
#[cfg(not(no_global_oom_handling))]
use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
+#[cfg(not(bootstrap))]
+use core::error::Error;
use core::fmt;
use core::hash;
use core::iter::FusedIterator;
@@ -58,9 +60,9 @@ use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{self, Index, IndexMut, Range, RangeBounds};
use core::ptr;
use core::slice;
-#[cfg(not(no_global_oom_handling))]
-use core::str::lossy;
use core::str::pattern::Pattern;
+#[cfg(not(no_global_oom_handling))]
+use core::str::Utf8Chunks;
#[cfg(not(no_global_oom_handling))]
use crate::borrow::{Cow, ToOwned};
@@ -628,11 +630,11 @@ impl String {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
- let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();
+ let mut iter = Utf8Chunks::new(v);
let first_valid = if let Some(chunk) = iter.next() {
- let lossy::Utf8LossyChunk { valid, broken } = chunk;
- if broken.is_empty() {
+ let valid = chunk.valid();
+ if chunk.invalid().is_empty() {
debug_assert_eq!(valid.len(), v.len());
return Cow::Borrowed(valid);
}
@@ -647,9 +649,9 @@ impl String {
res.push_str(first_valid);
res.push_str(REPLACEMENT);
- for lossy::Utf8LossyChunk { valid, broken } in iter {
- res.push_str(valid);
- if !broken.is_empty() {
+ for chunk in iter {
+ res.push_str(chunk.valid());
+ if !chunk.invalid().is_empty() {
res.push_str(REPLACEMENT);
}
}
@@ -1080,7 +1082,8 @@ impl String {
/// current length. The allocator may reserve more space to speculatively
/// avoid frequent allocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional` if it returns
- /// `Ok(())`. Does nothing if capacity is already sufficient.
+ /// `Ok(())`. Does nothing if capacity is already sufficient. This method
+ /// preserves the contents even if an error occurs.
///
/// # Errors
///
@@ -1938,6 +1941,24 @@ impl fmt::Display for FromUtf16Error {
}
}
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for FromUtf8Error {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "invalid utf-8"
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for FromUtf16Error {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "invalid utf-16"
+ }
+}
+
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for String {
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 4c03cc3ed..4377edeee 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -2763,3 +2763,25 @@ fn data_offset_align(align: usize) -> usize {
let layout = Layout::new::<ArcInner<()>>();
layout.size() + layout.padding_needed_for(align)
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "arc_error", since = "1.52.0")]
+impl<T: core::error::Error + ?Sized> core::error::Error for Arc<T> {
+ #[allow(deprecated, deprecated_in_future)]
+ fn description(&self) -> &str {
+ core::error::Error::description(&**self)
+ }
+
+ #[allow(deprecated)]
+ fn cause(&self) -> Option<&dyn core::error::Error> {
+ core::error::Error::cause(&**self)
+ }
+
+ fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
+ core::error::Error::source(&**self)
+ }
+
+ fn provide<'a>(&'a self, req: &mut core::any::Demand<'a>) {
+ core::error::Error::provide(&**self, req);
+ }
+}
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs
index 202d0e7f0..0fae8953a 100644
--- a/library/alloc/src/sync/tests.rs
+++ b/library/alloc/src/sync/tests.rs
@@ -618,3 +618,22 @@ fn test_arc_cyclic_two_refs() {
assert_eq!(Arc::strong_count(&two_refs), 3);
assert_eq!(Arc::weak_count(&two_refs), 2);
}
+
+/// Test for Arc::drop bug (https://github.com/rust-lang/rust/issues/55005)
+#[test]
+#[cfg(miri)] // relies on Stacked Borrows in Miri
+fn arc_drop_dereferenceable_race() {
+ // The bug seems to take up to 700 iterations to reproduce with most seeds (tested 0-9).
+ for _ in 0..750 {
+ let arc_1 = Arc::new(());
+ let arc_2 = arc_1.clone();
+ let thread = thread::spawn(|| drop(arc_2));
+ // Spin a bit; makes the race more likely to appear
+ let mut i = 0;
+ while i < 256 {
+ i += 1;
+ }
+ drop(arc_1);
+ thread.join().unwrap();
+ }
+}
diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs
index 5cdee0bd4..5b73906a1 100644
--- a/library/alloc/src/vec/drain.rs
+++ b/library/alloc/src/vec/drain.rs
@@ -1,7 +1,7 @@
use crate::alloc::{Allocator, Global};
use core::fmt;
use core::iter::{FusedIterator, TrustedLen};
-use core::mem;
+use core::mem::{self, ManuallyDrop};
use core::ptr::{self, NonNull};
use core::slice::{self};
@@ -65,6 +65,77 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> {
pub fn allocator(&self) -> &A {
unsafe { self.vec.as_ref().allocator() }
}
+
+ /// Keep unyielded elements in the source `Vec`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(drain_keep_rest)]
+ ///
+ /// let mut vec = vec!['a', 'b', 'c'];
+ /// let mut drain = vec.drain(..);
+ ///
+ /// assert_eq!(drain.next().unwrap(), 'a');
+ ///
+ /// // This call keeps 'b' and 'c' in the vec.
+ /// drain.keep_rest();
+ ///
+ /// // If we wouldn't call `keep_rest()`,
+ /// // `vec` would be empty.
+ /// assert_eq!(vec, ['b', 'c']);
+ /// ```
+ #[unstable(feature = "drain_keep_rest", issue = "101122")]
+ pub fn keep_rest(self) {
+ // At this moment layout looks like this:
+ //
+ // [head] [yielded by next] [unyielded] [yielded by next_back] [tail]
+ // ^-- start \_________/-- unyielded_len \____/-- self.tail_len
+ // ^-- unyielded_ptr ^-- tail
+ //
+ // Normally `Drop` impl would drop [unyielded] and then move [tail] to the `start`.
+ // Here we want to
+ // 1. Move [unyielded] to `start`
+ // 2. Move [tail] to a new start at `start + len(unyielded)`
+ // 3. Update length of the original vec to `len(head) + len(unyielded) + len(tail)`
+ // a. In case of ZST, this is the only thing we want to do
+ // 4. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
+ let mut this = ManuallyDrop::new(self);
+
+ unsafe {
+ let source_vec = this.vec.as_mut();
+
+ let start = source_vec.len();
+ let tail = this.tail_start;
+
+ let unyielded_len = this.iter.len();
+ let unyielded_ptr = this.iter.as_slice().as_ptr();
+
+ // ZSTs have no identity, so we don't need to move them around.
+ let needs_move = mem::size_of::<T>() != 0;
+
+ if needs_move {
+ let start_ptr = source_vec.as_mut_ptr().add(start);
+
+ // memmove back unyielded elements
+ if unyielded_ptr != start_ptr {
+ let src = unyielded_ptr;
+ let dst = start_ptr;
+
+ ptr::copy(src, dst, unyielded_len);
+ }
+
+ // memmove back untouched tail
+ if tail != (start + unyielded_len) {
+ let src = source_vec.as_ptr().add(tail);
+ let dst = start_ptr.add(unyielded_len);
+ ptr::copy(src, dst, this.tail_len);
+ }
+ }
+
+ source_vec.set_len(start + unyielded_len + this.tail_len);
+ }
+ }
}
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs
index 3c37c92ae..8c03f1692 100644
--- a/library/alloc/src/vec/drain_filter.rs
+++ b/library/alloc/src/vec/drain_filter.rs
@@ -1,6 +1,7 @@
use crate::alloc::{Allocator, Global};
-use core::ptr::{self};
-use core::slice::{self};
+use core::mem::{self, ManuallyDrop};
+use core::ptr;
+use core::slice;
use super::Vec;
@@ -54,6 +55,61 @@ where
pub fn allocator(&self) -> &A {
self.vec.allocator()
}
+
+ /// Keep unyielded elements in the source `Vec`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(drain_filter)]
+ /// #![feature(drain_keep_rest)]
+ ///
+ /// let mut vec = vec!['a', 'b', 'c'];
+ /// let mut drain = vec.drain_filter(|_| true);
+ ///
+ /// assert_eq!(drain.next().unwrap(), 'a');
+ ///
+ /// // This call keeps 'b' and 'c' in the vec.
+ /// drain.keep_rest();
+ ///
+ /// // If we wouldn't call `keep_rest()`,
+ /// // `vec` would be empty.
+ /// assert_eq!(vec, ['b', 'c']);
+ /// ```
+ #[unstable(feature = "drain_keep_rest", issue = "101122")]
+ pub fn keep_rest(self) {
+ // At this moment layout looks like this:
+ //
+ // _____________________/-- old_len
+ // / \
+ // [kept] [yielded] [tail]
+ // \_______/ ^-- idx
+ // \-- del
+ //
+ // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`)
+ //
+ // 1. Move [tail] after [kept]
+ // 2. Update length of the original vec to `old_len - del`
+ // a. In case of ZST, this is the only thing we want to do
+ // 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
+ let mut this = ManuallyDrop::new(self);
+
+ unsafe {
+ // ZSTs have no identity, so we don't need to move them around.
+ let needs_move = mem::size_of::<T>() != 0;
+
+ if needs_move && this.idx < this.old_len && this.del > 0 {
+ let ptr = this.vec.as_mut_ptr();
+ let src = ptr.add(this.idx);
+ let dst = src.sub(this.del);
+ let tail_len = this.old_len - this.idx;
+ src.copy_to(dst, tail_len);
+ }
+
+ let new_len = this.old_len - this.del;
+ this.vec.set_len(new_len);
+ }
+ }
}
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs
index 55dcb84ad..b211421b2 100644
--- a/library/alloc/src/vec/in_place_collect.rs
+++ b/library/alloc/src/vec/in_place_collect.rs
@@ -267,7 +267,7 @@ where
// one slot in the underlying storage will have been freed up and we can immediately
// write back the result.
unsafe {
- let dst = dst_buf.offset(i as isize);
+ let dst = dst_buf.add(i);
debug_assert!(dst as *const _ <= end, "InPlaceIterable contract violation");
ptr::write(dst, self.__iterator_get_unchecked(i));
// Since this executes user code which can panic we have to bump the pointer
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index 1b483e3fc..b4157fd58 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -4,7 +4,6 @@ use crate::alloc::{Allocator, Global};
use crate::raw_vec::RawVec;
use core::array;
use core::fmt;
-use core::intrinsics::arith_offset;
use core::iter::{
FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce,
};
@@ -148,19 +147,19 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
#[inline]
fn next(&mut self) -> Option<T> {
- if self.ptr as *const _ == self.end {
+ if self.ptr == self.end {
None
} else if mem::size_of::<T>() == 0 {
// purposefully don't use 'ptr.offset' because for
// vectors with 0-size elements this would return the
// same pointer.
- self.ptr = unsafe { arith_offset(self.ptr as *const i8, 1) as *mut T };
+ self.ptr = self.ptr.wrapping_byte_add(1);
// Make up a value of this ZST.
Some(unsafe { mem::zeroed() })
} else {
let old = self.ptr;
- self.ptr = unsafe { self.ptr.offset(1) };
+ self.ptr = unsafe { self.ptr.add(1) };
Some(unsafe { ptr::read(old) })
}
@@ -184,7 +183,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
// SAFETY: due to unchecked casts of unsigned amounts to signed offsets the wraparound
// effectively results in unsigned pointers representing positions 0..usize::MAX,
// which is valid for ZSTs.
- self.ptr = unsafe { arith_offset(self.ptr as *const i8, step_size as isize) as *mut T }
+ self.ptr = self.ptr.wrapping_byte_add(step_size);
} else {
// SAFETY: the min() above ensures that step_size is in bounds
self.ptr = unsafe { self.ptr.add(step_size) };
@@ -217,7 +216,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) });
}
- self.ptr = unsafe { arith_offset(self.ptr as *const i8, N as isize) as *mut T };
+ self.ptr = self.ptr.wrapping_byte_add(N);
// Safety: ditto
return Ok(unsafe { MaybeUninit::array_assume_init(raw_ary) });
}
@@ -267,12 +266,12 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
None
} else if mem::size_of::<T>() == 0 {
// See above for why 'ptr.offset' isn't used
- self.end = unsafe { arith_offset(self.end as *const i8, -1) as *mut T };
+ self.end = self.end.wrapping_byte_sub(1);
// Make up a value of this ZST.
Some(unsafe { mem::zeroed() })
} else {
- self.end = unsafe { self.end.offset(-1) };
+ self.end = unsafe { self.end.sub(1) };
Some(unsafe { ptr::read(self.end) })
}
@@ -283,12 +282,10 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
let step_size = self.len().min(n);
if mem::size_of::<T>() == 0 {
// SAFETY: same as for advance_by()
- self.end = unsafe {
- arith_offset(self.end as *const i8, step_size.wrapping_neg() as isize) as *mut T
- }
+ self.end = self.end.wrapping_byte_sub(step_size);
} else {
// SAFETY: same as for advance_by()
- self.end = unsafe { self.end.offset(step_size.wrapping_neg() as isize) };
+ self.end = unsafe { self.end.sub(step_size) };
}
let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
// SAFETY: same as for advance_by()
diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs
index 92a32779b..2e025c8a4 100644
--- a/library/alloc/src/vec/is_zero.rs
+++ b/library/alloc/src/vec/is_zero.rs
@@ -1,3 +1,5 @@
+use core::num::{Saturating, Wrapping};
+
use crate::boxed::Box;
#[rustc_specialization_trait]
@@ -144,3 +146,17 @@ impl_is_zero_option_of_nonzero!(
NonZeroUsize,
NonZeroIsize,
);
+
+unsafe impl<T: IsZero> IsZero for Wrapping<T> {
+ #[inline]
+ fn is_zero(&self) -> bool {
+ self.0.is_zero()
+ }
+}
+
+unsafe impl<T: IsZero> IsZero for Saturating<T> {
+ #[inline]
+ fn is_zero(&self) -> bool {
+ self.0.is_zero()
+ }
+}
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index fa9f2131c..60b36af5e 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -59,7 +59,7 @@ use core::cmp::Ordering;
use core::convert::TryFrom;
use core::fmt;
use core::hash::{Hash, Hasher};
-use core::intrinsics::{arith_offset, assume};
+use core::intrinsics::assume;
use core::iter;
#[cfg(not(no_global_oom_handling))]
use core::iter::FromIterator;
@@ -436,7 +436,7 @@ impl<T> Vec<T> {
/// an explanation of the difference between length and capacity, see
/// *[Capacity and reallocation]*.
///
- /// If it is imporant to know the exact allocated capacity of a `Vec`,
+ /// If it is important to know the exact allocated capacity of a `Vec`,
/// always use the [`capacity`] method after construction.
///
/// For `Vec<T>` where `T` is a zero-sized type, there will be no allocation
@@ -542,8 +542,8 @@ impl<T> Vec<T> {
///
/// unsafe {
/// // Overwrite memory with 4, 5, 6
- /// for i in 0..len as isize {
- /// ptr::write(p.offset(i), 4 + i);
+ /// for i in 0..len {
+ /// ptr::write(p.add(i), 4 + i);
/// }
///
/// // Put everything back together into a Vec
@@ -591,7 +591,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// an explanation of the difference between length and capacity, see
/// *[Capacity and reallocation]*.
///
- /// If it is imporant to know the exact allocated capacity of a `Vec`,
+ /// If it is important to know the exact allocated capacity of a `Vec`,
/// always use the [`capacity`] method after construction.
///
/// For `Vec<T, A>` where `T` is a zero-sized type, there will be no allocation
@@ -702,8 +702,8 @@ impl<T, A: Allocator> Vec<T, A> {
///
/// unsafe {
/// // Overwrite memory with 4, 5, 6
- /// for i in 0..len as isize {
- /// ptr::write(p.offset(i), 4 + i);
+ /// for i in 0..len {
+ /// ptr::write(p.add(i), 4 + i);
/// }
///
/// // Put everything back together into a Vec
@@ -875,7 +875,8 @@ impl<T, A: Allocator> Vec<T, A> {
/// in the given `Vec<T>`. The collection may reserve more space to speculatively avoid
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional` if it returns
- /// `Ok(())`. Does nothing if capacity is already sufficient.
+ /// `Ok(())`. Does nothing if capacity is already sufficient. This method
+ /// preserves the contents even if an error occurs.
///
/// # Errors
///
@@ -1393,7 +1394,7 @@ impl<T, A: Allocator> Vec<T, A> {
if index < len {
// Shift everything over to make space. (Duplicating the
// `index`th element into two consecutive places.)
- ptr::copy(p, p.offset(1), len - index);
+ ptr::copy(p, p.add(1), len - index);
} else if index == len {
// No elements need shifting.
} else {
@@ -1455,7 +1456,7 @@ impl<T, A: Allocator> Vec<T, A> {
ret = ptr::read(ptr);
// Shift everything down to fill in that spot.
- ptr::copy(ptr.offset(1), ptr, len - index - 1);
+ ptr::copy(ptr.add(1), ptr, len - index - 1);
}
self.set_len(len - 1);
ret
@@ -2408,7 +2409,7 @@ impl<T, A: Allocator> Vec<T, A> {
// Write all elements except the last one
for _ in 1..n {
ptr::write(ptr, value.next());
- ptr = ptr.offset(1);
+ ptr = ptr.add(1);
// Increment the length in every step in case next() panics
local_len.increment_len(1);
}
@@ -2677,7 +2678,7 @@ impl<T, A: Allocator> IntoIterator for Vec<T, A> {
let alloc = ManuallyDrop::new(ptr::read(me.allocator()));
let begin = me.as_mut_ptr();
let end = if mem::size_of::<T>() == 0 {
- arith_offset(begin as *const i8, me.len() as isize) as *const T
+ begin.wrapping_byte_add(me.len())
} else {
begin.add(me.len()) as *const T
};
@@ -2927,6 +2928,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for Vec<T> {
/// Creates an empty `Vec<T>`.
+ ///
+ /// The vector will not allocate until elements are pushed onto it.
fn default() -> Vec<T> {
Vec::new()
}
diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs
index 506ee0ecf..1ea9c827a 100644
--- a/library/alloc/src/vec/spec_extend.rs
+++ b/library/alloc/src/vec/spec_extend.rs
@@ -39,7 +39,7 @@ where
let mut local_len = SetLenOnDrop::new(&mut self.len);
iterator.for_each(move |element| {
ptr::write(ptr, element);
- ptr = ptr.offset(1);
+ ptr = ptr.add(1);
// Since the loop executes user code which can panic we have to bump the pointer
// after each step.
// NB can't overflow since we would have had to alloc the address space
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index d83cd29dd..490c0d8f7 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -38,11 +38,13 @@
#![feature(const_str_from_utf8)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(panic_update_hook)]
+#![feature(pointer_is_aligned)]
#![feature(slice_flatten)]
#![feature(thin_box)]
#![feature(bench_black_box)]
#![feature(strict_provenance)]
#![feature(once_cell)]
+#![feature(drain_keep_rest)]
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index 7379569dd..e30329aa1 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -1010,11 +1010,11 @@ fn test_as_bytes_fail() {
fn test_as_ptr() {
let buf = "hello".as_ptr();
unsafe {
- assert_eq!(*buf.offset(0), b'h');
- assert_eq!(*buf.offset(1), b'e');
- assert_eq!(*buf.offset(2), b'l');
- assert_eq!(*buf.offset(3), b'l');
- assert_eq!(*buf.offset(4), b'o');
+ assert_eq!(*buf.add(0), b'h');
+ assert_eq!(*buf.add(1), b'e');
+ assert_eq!(*buf.add(2), b'l');
+ assert_eq!(*buf.add(3), b'l');
+ assert_eq!(*buf.add(4), b'o');
}
}
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs
index b6836fdc8..99d1296a4 100644
--- a/library/alloc/tests/string.rs
+++ b/library/alloc/tests/string.rs
@@ -693,12 +693,6 @@ fn test_try_reserve() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
- // On 16/32-bit, we check that allocations don't exceed isize::MAX,
- // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
- // Any platform that succeeds for these requests is technically broken with
- // ptr::offset because LLVM is the worst.
- let guards_against_isize = usize::BITS < 64;
-
{
// Note: basic stuff is checked by test_reserve
let mut empty_string: String = String::new();
@@ -712,35 +706,19 @@ fn test_try_reserve() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- // Check isize::MAX + 1 does count as overflow
- assert_matches!(
- empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- // Check usize::MAX does count as overflow
- assert_matches!(
- empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
- } else {
- // Check isize::MAX + 1 is an OOM
- assert_matches!(
- empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
-
- // Check usize::MAX is an OOM
- assert_matches!(
- empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "usize::MAX should trigger an OOM!"
- );
- }
+ // Check isize::MAX + 1 does count as overflow
+ assert_matches!(
+ empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ // Check usize::MAX does count as overflow
+ assert_matches!(
+ empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
}
{
@@ -753,19 +731,13 @@ fn test_try_reserve() {
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
// Should always overflow in the add-to-len
assert_matches!(
ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -785,8 +757,6 @@ fn test_try_reserve_exact() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
- let guards_against_isize = usize::BITS < 64;
-
{
let mut empty_string: String = String::new();
@@ -799,31 +769,17 @@ fn test_try_reserve_exact() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- assert_matches!(
- empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
- } else {
- assert_matches!(
- empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
-
- assert_matches!(
- empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "usize::MAX should trigger an OOM!"
- );
- }
+ assert_matches!(
+ empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ assert_matches!(
+ empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
}
{
@@ -839,19 +795,13 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
assert_matches!(
ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
Err(CapacityOverflow),
diff --git a/library/alloc/tests/thin_box.rs b/library/alloc/tests/thin_box.rs
index 368aa564f..e008b0cc3 100644
--- a/library/alloc/tests/thin_box.rs
+++ b/library/alloc/tests/thin_box.rs
@@ -48,11 +48,11 @@ fn verify_aligned<T>(ptr: *const T) {
// practice these checks are mostly just smoke-detectors for an extremely
// broken `ThinBox` impl, since it's an extremely subtle piece of code.
let ptr = core::hint::black_box(ptr);
- let align = core::mem::align_of::<T>();
assert!(
- (ptr.addr() & (align - 1)) == 0 && !ptr.is_null(),
- "misaligned ThinBox data; valid pointers to `{}` should be aligned to {align}: {ptr:p}",
- core::any::type_name::<T>(),
+ ptr.is_aligned() && !ptr.is_null(),
+ "misaligned ThinBox data; valid pointers to `{ty}` should be aligned to {align}: {ptr:p}",
+ ty = core::any::type_name::<T>(),
+ align = core::mem::align_of::<T>(),
);
}
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index b797e2375..f140fc414 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -294,6 +294,22 @@ fn test_retain() {
}
#[test]
+fn test_retain_predicate_order() {
+ for to_keep in [true, false] {
+ let mut number_of_executions = 0;
+ let mut vec = vec![1, 2, 3, 4];
+ let mut next_expected = 1;
+ vec.retain(|&x| {
+ assert_eq!(next_expected, x);
+ next_expected += 1;
+ number_of_executions += 1;
+ to_keep
+ });
+ assert_eq!(number_of_executions, 4);
+ }
+}
+
+#[test]
fn test_retain_pred_panic_with_hole() {
let v = (0..5).map(Rc::new).collect::<Vec<_>>();
catch_unwind(AssertUnwindSafe(|| {
@@ -355,6 +371,35 @@ fn test_retain_drop_panic() {
}
#[test]
+fn test_retain_maybeuninits() {
+ // This test aimed to be run under miri.
+ use core::mem::MaybeUninit;
+ let mut vec: Vec<_> = [1i32, 2, 3, 4].map(|v| MaybeUninit::new(vec![v])).into();
+ vec.retain(|x| {
+ // SAFETY: Retain must visit every element of Vec in original order and exactly once.
+ // Our values is initialized at creation of Vec.
+ let v = unsafe { x.assume_init_ref()[0] };
+ if v & 1 == 0 {
+ return true;
+ }
+ // SAFETY: Value is initialized.
+ // Value wouldn't be dropped by `Vec::retain`
+ // because `MaybeUninit` doesn't drop content.
+ drop(unsafe { x.assume_init_read() });
+ false
+ });
+ let vec: Vec<i32> = vec
+ .into_iter()
+ .map(|x| unsafe {
+ // SAFETY: All values dropped in retain predicate must be removed by `Vec::retain`.
+ // Remaining values are initialized.
+ x.assume_init()[0]
+ })
+ .collect();
+ assert_eq!(vec, [2, 4]);
+}
+
+#[test]
fn test_dedup() {
fn case(a: Vec<i32>, b: Vec<i32>) {
let mut v = a;
@@ -795,6 +840,36 @@ fn test_drain_leak() {
}
#[test]
+fn test_drain_keep_rest() {
+ let mut v = vec![0, 1, 2, 3, 4, 5, 6];
+ let mut drain = v.drain(1..6);
+ assert_eq!(drain.next(), Some(1));
+ assert_eq!(drain.next_back(), Some(5));
+ assert_eq!(drain.next(), Some(2));
+
+ drain.keep_rest();
+ assert_eq!(v, &[0, 3, 4, 6]);
+}
+
+#[test]
+fn test_drain_keep_rest_all() {
+ let mut v = vec![0, 1, 2, 3, 4, 5, 6];
+ v.drain(1..6).keep_rest();
+ assert_eq!(v, &[0, 1, 2, 3, 4, 5, 6]);
+}
+
+#[test]
+fn test_drain_keep_rest_none() {
+ let mut v = vec![0, 1, 2, 3, 4, 5, 6];
+ let mut drain = v.drain(1..6);
+
+ drain.by_ref().for_each(drop);
+
+ drain.keep_rest();
+ assert_eq!(v, &[0, 6]);
+}
+
+#[test]
fn test_splice() {
let mut v = vec![1, 2, 3, 4, 5];
let a = [10, 11, 12];
@@ -1030,6 +1105,12 @@ fn test_into_iter_drop_allocator() {
}
#[test]
+fn test_into_iter_zst() {
+ for _ in vec![[0u64; 0]].into_iter() {}
+ for _ in vec![[0u64; 0]; 5].into_iter().rev() {}
+}
+
+#[test]
fn test_from_iter_specialization() {
let src: Vec<usize> = vec![0usize; 1];
let srcptr = src.as_ptr();
@@ -1489,6 +1570,35 @@ fn drain_filter_unconsumed() {
}
#[test]
+fn test_drain_filter_keep_rest() {
+ let mut v = vec![0, 1, 2, 3, 4, 5, 6];
+ let mut drain = v.drain_filter(|&mut x| x % 2 == 0);
+ assert_eq!(drain.next(), Some(0));
+ assert_eq!(drain.next(), Some(2));
+
+ drain.keep_rest();
+ assert_eq!(v, &[1, 3, 4, 5, 6]);
+}
+
+#[test]
+fn test_drain_filter_keep_rest_all() {
+ let mut v = vec![0, 1, 2, 3, 4, 5, 6];
+ v.drain_filter(|_| true).keep_rest();
+ assert_eq!(v, &[0, 1, 2, 3, 4, 5, 6]);
+}
+
+#[test]
+fn test_drain_filter_keep_rest_none() {
+ let mut v = vec![0, 1, 2, 3, 4, 5, 6];
+ let mut drain = v.drain_filter(|_| true);
+
+ drain.by_ref().for_each(drop);
+
+ drain.keep_rest();
+ assert_eq!(v, &[]);
+}
+
+#[test]
fn test_reserve_exact() {
// This is all the same as test_reserve
@@ -1527,12 +1637,6 @@ fn test_try_reserve() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
- // On 16/32-bit, we check that allocations don't exceed isize::MAX,
- // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
- // Any platform that succeeds for these requests is technically broken with
- // ptr::offset because LLVM is the worst.
- let guards_against_isize = usize::BITS < 64;
-
{
// Note: basic stuff is checked by test_reserve
let mut empty_bytes: Vec<u8> = Vec::new();
@@ -1546,35 +1650,19 @@ fn test_try_reserve() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- // Check isize::MAX + 1 does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- // Check usize::MAX does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
- } else {
- // Check isize::MAX + 1 is an OOM
- assert_matches!(
- empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
-
- // Check usize::MAX is an OOM
- assert_matches!(
- empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "usize::MAX should trigger an OOM!"
- );
- }
+ // Check isize::MAX + 1 does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ // Check usize::MAX does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
}
{
@@ -1587,19 +1675,13 @@ fn test_try_reserve() {
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
// Should always overflow in the add-to-len
assert_matches!(
ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1620,19 +1702,13 @@ fn test_try_reserve() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
// Should fail in the mul-by-size
assert_matches!(
ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1652,8 +1728,6 @@ fn test_try_reserve_exact() {
const MAX_CAP: usize = isize::MAX as usize;
const MAX_USIZE: usize = usize::MAX;
- let guards_against_isize = size_of::<usize>() < 8;
-
{
let mut empty_bytes: Vec<u8> = Vec::new();
@@ -1666,31 +1740,17 @@ fn test_try_reserve_exact() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
- } else {
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
-
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "usize::MAX should trigger an OOM!"
- );
- }
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
}
{
@@ -1706,19 +1766,13 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
assert_matches!(
ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
Err(CapacityOverflow),
@@ -1739,19 +1793,13 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
assert_matches!(
ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
Err(CapacityOverflow),
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index 89cc7f905..019d73c0b 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -2,7 +2,6 @@ use std::assert_matches::assert_matches;
use std::collections::TryReserveErrorKind::*;
use std::collections::{vec_deque::Drain, VecDeque};
use std::fmt::Debug;
-use std::mem::size_of;
use std::ops::Bound::*;
use std::panic::{catch_unwind, AssertUnwindSafe};
@@ -1161,12 +1160,6 @@ fn test_try_reserve() {
const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
const MAX_USIZE: usize = usize::MAX;
- // On 16/32-bit, we check that allocations don't exceed isize::MAX,
- // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
- // Any platform that succeeds for these requests is technically broken with
- // ptr::offset because LLVM is the worst.
- let guards_against_isize = size_of::<usize>() < 8;
-
{
// Note: basic stuff is checked by test_reserve
let mut empty_bytes: VecDeque<u8> = VecDeque::new();
@@ -1180,31 +1173,19 @@ fn test_try_reserve() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- // Check isize::MAX + 1 does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- // Check usize::MAX does count as overflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
- } else {
- // Check isize::MAX is an OOM
- // VecDeque starts with capacity 7, always adds 1 to the capacity
- // and also rounds the number to next power of 2 so this is the
- // furthest we can go without triggering CapacityOverflow
- assert_matches!(
- empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+ // Check isize::MAX + 1 does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ // Check usize::MAX does count as overflow
+ assert_matches!(
+ empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
}
{
@@ -1217,19 +1198,13 @@ fn test_try_reserve() {
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
// Should always overflow in the add-to-len
assert_matches!(
ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1250,19 +1225,13 @@ fn test_try_reserve() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
// Should fail in the mul-by-size
assert_matches!(
ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1282,8 +1251,6 @@ fn test_try_reserve_exact() {
const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
const MAX_USIZE: usize = usize::MAX;
- let guards_against_isize = size_of::<usize>() < 8;
-
{
let mut empty_bytes: VecDeque<u8> = VecDeque::new();
@@ -1296,29 +1263,17 @@ fn test_try_reserve_exact() {
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
-
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "usize::MAX should trigger an overflow!"
- );
- } else {
- // Check isize::MAX is an OOM
- // VecDeque starts with capacity 7, always adds 1 to the capacity
- // and also rounds the number to next power of 2 so this is the
- // furthest we can go without triggering CapacityOverflow
- assert_matches!(
- empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
+ assert_matches!(
+ empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "usize::MAX should trigger an overflow!"
+ );
}
{
@@ -1334,19 +1289,13 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
assert_matches!(
ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
Err(CapacityOverflow),
@@ -1367,19 +1316,13 @@ fn test_try_reserve_exact() {
{
panic!("isize::MAX shouldn't trigger an overflow!");
}
- if guards_against_isize {
- assert_matches!(
- ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(CapacityOverflow),
- "isize::MAX + 1 should trigger an overflow!"
- );
- } else {
- assert_matches!(
- ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
- Err(AllocError { .. }),
- "isize::MAX + 1 should trigger an OOM!"
- );
- }
+
+ assert_matches!(
+ ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+ Err(CapacityOverflow),
+ "isize::MAX + 1 should trigger an overflow!"
+ );
+
assert_matches!(
ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
Err(CapacityOverflow),
diff --git a/library/backtrace/.github/workflows/main.yml b/library/backtrace/.github/workflows/main.yml
index 5f4bd505b..c11b08dfd 100644
--- a/library/backtrace/.github/workflows/main.yml
+++ b/library/backtrace/.github/workflows/main.yml
@@ -33,8 +33,6 @@ jobs:
rust: stable-i686-msvc
- os: windows-latest
rust: stable-x86_64-gnu
- - os: windows-latest
- rust: stable-i686-gnu
steps:
- uses: actions/checkout@v1
with:
@@ -244,4 +242,4 @@ jobs:
rustup toolchain install nightly --component miri
rustup override set nightly
cargo miri setup
- - run: MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-strict-provenance" cargo miri test
+ - run: MIRIFLAGS="-Zmiri-disable-isolation" cargo miri test
diff --git a/library/backtrace/Cargo.toml b/library/backtrace/Cargo.toml
index 2881c8e8f..ef1c5ec00 100644
--- a/library/backtrace/Cargo.toml
+++ b/library/backtrace/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "backtrace"
-version = "0.3.65"
+version = "0.3.66"
authors = ["The Rust Project Developers"]
build = "build.rs"
license = "MIT/Apache-2.0"
@@ -44,7 +44,7 @@ addr2line = { version = "0.17.0", default-features = false }
miniz_oxide = { version = "0.5.0", default-features = false }
[dependencies.object]
-version = "0.28.0"
+version = "0.29.0"
default-features = false
features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive']
diff --git a/library/backtrace/src/backtrace/miri.rs b/library/backtrace/src/backtrace/miri.rs
index 9a5f65b80..f8c496428 100644
--- a/library/backtrace/src/backtrace/miri.rs
+++ b/library/backtrace/src/backtrace/miri.rs
@@ -91,7 +91,7 @@ pub fn resolve_addr(ptr: *mut c_void) -> Frame {
}
}
-pub unsafe fn trace_unsynchronized<F: FnMut(&super::Frame) -> bool>(mut cb: F) {
+unsafe fn trace_unsynchronized<F: FnMut(&super::Frame) -> bool>(mut cb: F) {
let len = miri_backtrace_size(0);
let mut frames = Vec::with_capacity(len);
@@ -102,6 +102,8 @@ pub unsafe fn trace_unsynchronized<F: FnMut(&super::Frame) -> bool>(mut cb: F) {
for ptr in frames.iter() {
let frame = resolve_addr(*ptr as *mut c_void);
- cb(&super::Frame { inner: frame });
+ if !cb(&super::Frame { inner: frame }) {
+ return;
+ }
}
}
diff --git a/library/core/benches/num/int_log/mod.rs b/library/core/benches/num/int_log/mod.rs
index 19864d2d4..3c01e2998 100644
--- a/library/core/benches/num/int_log/mod.rs
+++ b/library/core/benches/num/int_log/mod.rs
@@ -9,7 +9,7 @@ macro_rules! int_log_bench {
for n in 0..(<$t>::BITS / 8) {
for i in 1..=(100 as $t) {
let x = black_box(i << (n * 8));
- black_box(x.log10());
+ black_box(x.ilog10());
}
}
});
@@ -27,7 +27,7 @@ macro_rules! int_log_bench {
.collect();
bench.iter(|| {
for x in &numbers {
- black_box(black_box(x).log10());
+ black_box(black_box(x).ilog10());
}
});
}
@@ -44,7 +44,7 @@ macro_rules! int_log_bench {
.collect();
bench.iter(|| {
for x in &numbers {
- black_box(black_box(x).log10());
+ black_box(black_box(x).ilog10());
}
});
}
diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs
index 887246c60..6756eecd0 100644
--- a/library/core/src/alloc/global.rs
+++ b/library/core/src/alloc/global.rs
@@ -74,7 +74,7 @@ use crate::ptr;
/// {
/// return null_mut();
/// };
-/// (self.arena.get() as *mut u8).add(allocated)
+/// self.arena.get().cast::<u8>().add(allocated)
/// }
/// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
/// }
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 2f378836c..f03502429 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -1,4 +1,12 @@
+// Seemingly inconsequential code changes to this file can lead to measurable
+// performance impact on compilation times, due at least in part to the fact
+// that the layout code gets called from many instantiations of the various
+// collections, resulting in having to optimize down excess IR multiple times.
+// Your performance intuition is useless. Run perf.
+
use crate::cmp;
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
use crate::mem::{self, ValidAlign};
use crate::ptr::NonNull;
@@ -52,8 +60,8 @@ impl Layout {
/// * `align` must be a power of two,
///
/// * `size`, when rounded up to the nearest multiple of `align`,
- /// must not overflow (i.e., the rounded value must be less than
- /// or equal to `usize::MAX`).
+ /// must not overflow isize (i.e., the rounded value must be
+ /// less than or equal to `isize::MAX`).
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
#[inline]
@@ -62,6 +70,12 @@ impl Layout {
return Err(LayoutError);
}
+ // SAFETY: just checked that align is a power of two.
+ Layout::from_size_valid_align(size, unsafe { ValidAlign::new_unchecked(align) })
+ }
+
+ #[inline(always)]
+ const fn max_size_for_align(align: ValidAlign) -> usize {
// (power-of-two implies align != 0.)
// Rounded up size is:
@@ -76,13 +90,18 @@ impl Layout {
//
// Above implies that checking for summation overflow is both
// necessary and sufficient.
- if size > usize::MAX - (align - 1) {
+ isize::MAX as usize - (align.as_usize() - 1)
+ }
+
+ /// Internal helper constructor to skip revalidating alignment validity.
+ #[inline]
+ const fn from_size_valid_align(size: usize, align: ValidAlign) -> Result<Self, LayoutError> {
+ if size > Self::max_size_for_align(align) {
return Err(LayoutError);
}
- // SAFETY: the conditions for `from_size_align_unchecked` have been
- // checked above.
- unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
+ // SAFETY: Layout::size invariants checked above.
+ Ok(Layout { size, align })
}
/// Creates a layout, bypassing all checks.
@@ -96,8 +115,8 @@ impl Layout {
#[must_use]
#[inline]
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
- // SAFETY: the caller must ensure that `align` is a power of two.
- Layout { size, align: unsafe { ValidAlign::new_unchecked(align) } }
+ // SAFETY: the caller is required to uphold the preconditions.
+ unsafe { Layout { size, align: ValidAlign::new_unchecked(align) } }
}
/// The minimum size in bytes for a memory block of this layout.
@@ -116,7 +135,7 @@ impl Layout {
without modifying the layout"]
#[inline]
pub const fn align(&self) -> usize {
- self.align.as_nonzero().get()
+ self.align.as_usize()
}
/// Constructs a `Layout` suitable for holding a value of type `T`.
@@ -126,10 +145,9 @@ impl Layout {
#[inline]
pub const fn new<T>() -> Self {
let (size, align) = size_align::<T>();
- // SAFETY: the align is guaranteed by Rust to be a power of two and
- // the size+align combo is guaranteed to fit in our address space. As a
- // result use the unchecked constructor here to avoid inserting code
- // that panics if it isn't optimized well enough.
+ // SAFETY: if the type is instantiated, rustc already ensures that its
+ // layout is valid. Use the unchecked constructor to avoid inserting a
+ // panicking codepath that needs to be optimized out.
unsafe { Layout::from_size_align_unchecked(size, align) }
}
@@ -141,7 +159,6 @@ impl Layout {
#[inline]
pub fn for_value<T: ?Sized>(t: &T) -> Self {
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
- debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: see rationale in `new` for why this is using the unsafe variant
unsafe { Layout::from_size_align_unchecked(size, align) }
}
@@ -176,7 +193,6 @@ impl Layout {
pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
// SAFETY: we pass along the prerequisites of these functions to the caller
let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) };
- debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: see rationale in `new` for why this is using the unsafe variant
unsafe { Layout::from_size_align_unchecked(size, align) }
}
@@ -276,12 +292,11 @@ impl Layout {
let pad = self.padding_needed_for(self.align());
// This cannot overflow. Quoting from the invariant of Layout:
// > `size`, when rounded up to the nearest multiple of `align`,
- // > must not overflow (i.e., the rounded value must be less than
- // > `usize::MAX`)
+ // > must not overflow isize (i.e., the rounded value must be
+ // > less than or equal to `isize::MAX`)
let new_size = self.size() + pad;
- // SAFETY: self.align is already known to be valid and new_size has been
- // padded already.
+ // SAFETY: padded size is guaranteed to not exceed `isize::MAX`.
unsafe { Layout::from_size_align_unchecked(new_size, self.align()) }
}
@@ -298,14 +313,13 @@ impl Layout {
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
// This cannot overflow. Quoting from the invariant of Layout:
// > `size`, when rounded up to the nearest multiple of `align`,
- // > must not overflow (i.e., the rounded value must be less than
- // > `usize::MAX`)
+ // > must not overflow isize (i.e., the rounded value must be
+ // > less than or equal to `isize::MAX`)
let padded_size = self.size() + self.padding_needed_for(self.align());
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
- // SAFETY: self.align is already known to be valid and alloc_size has been
- // padded already.
- unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
+ // The safe constructor is called here to enforce the isize size limit.
+ Layout::from_size_valid_align(alloc_size, self.align).map(|layout| (layout, padded_size))
}
/// Creates a layout describing the record for `self` followed by
@@ -356,13 +370,14 @@ impl Layout {
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
- let new_align = cmp::max(self.align(), next.align());
+ let new_align = cmp::max(self.align, next.align);
let pad = self.padding_needed_for(next.align());
let offset = self.size().checked_add(pad).ok_or(LayoutError)?;
let new_size = offset.checked_add(next.size()).ok_or(LayoutError)?;
- let layout = Layout::from_size_align(new_size, new_align)?;
+ // The safe constructor is called here to enforce the isize size limit.
+ let layout = Layout::from_size_valid_align(new_size, new_align)?;
Ok((layout, offset))
}
@@ -382,7 +397,8 @@ impl Layout {
#[inline]
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
let size = self.size().checked_mul(n).ok_or(LayoutError)?;
- Layout::from_size_align(size, self.align())
+ // The safe constructor is called here to enforce the isize size limit.
+ Layout::from_size_valid_align(size, self.align)
}
/// Creates a layout describing the record for `self` followed by
@@ -395,26 +411,39 @@ impl Layout {
#[inline]
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
- Layout::from_size_align(new_size, self.align())
+ // The safe constructor is called here to enforce the isize size limit.
+ Layout::from_size_valid_align(new_size, self.align)
}
/// Creates a layout describing the record for a `[T; n]`.
///
- /// On arithmetic overflow, returns `LayoutError`.
+ /// On arithmetic overflow or when the total size would exceed
+ /// `isize::MAX`, returns `LayoutError`.
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
#[inline]
pub fn array<T>(n: usize) -> Result<Self, LayoutError> {
- let array_size = mem::size_of::<T>().checked_mul(n).ok_or(LayoutError)?;
-
- // SAFETY:
- // - Size: `array_size` cannot be too big because `size_of::<T>()` must
- // be a multiple of `align_of::<T>()`. Therefore, `array_size`
- // rounded up to the nearest multiple of `align_of::<T>()` is just
- // `array_size`. And `array_size` cannot be too big because it was
- // just checked by the `checked_mul()`.
- // - Alignment: `align_of::<T>()` will always give an acceptable
- // (non-zero, power of two) alignment.
- Ok(unsafe { Layout::from_size_align_unchecked(array_size, mem::align_of::<T>()) })
+ // Reduce the amount of code we need to monomorphize per `T`.
+ return inner(mem::size_of::<T>(), ValidAlign::of::<T>(), n);
+
+ #[inline]
+ fn inner(element_size: usize, align: ValidAlign, n: usize) -> Result<Layout, LayoutError> {
+ // We need to check two things about the size:
+ // - That the total size won't overflow a `usize`, and
+ // - That the total size still fits in an `isize`.
+ // By using division we can check them both with a single threshold.
+ // That'd usually be a bad idea, but thankfully here the element size
+ // and alignment are constants, so the compiler will fold all of it.
+ if element_size != 0 && n > Layout::max_size_for_align(align) / element_size {
+ return Err(LayoutError);
+ }
+
+ let array_size = element_size * n;
+
+ // SAFETY: We just checked above that the `array_size` will not
+ // exceed `isize::MAX` even when rounded up to the alignment.
+ // And `ValidAlign` guarantees it's a power of two.
+ unsafe { Ok(Layout::from_size_align_unchecked(array_size, align.as_usize())) }
+ }
}
}
@@ -434,6 +463,10 @@ pub type LayoutErr = LayoutError;
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LayoutError;
+#[cfg(not(bootstrap))]
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+impl Error for LayoutError {}
+
// (we need this for downstream impl of trait Error)
#[stable(feature = "alloc_layout", since = "1.28.0")]
impl fmt::Display for LayoutError {
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index 6cc6e359e..94efa7666 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -21,6 +21,8 @@ pub use self::layout::LayoutErr;
#[stable(feature = "alloc_layout_error", since = "1.50.0")]
pub use self::layout::LayoutError;
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
use crate::ptr::{self, NonNull};
@@ -32,6 +34,14 @@ use crate::ptr::{self, NonNull};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct AllocError;
+#[cfg(not(bootstrap))]
+#[unstable(
+ feature = "allocator_api",
+ reason = "the precise API and guarantees it provides may be tweaked.",
+ issue = "32838"
+)]
+impl Error for AllocError {}
+
// (we need this for downstream impl of trait Error)
#[unstable(feature = "allocator_api", issue = "32838")]
impl fmt::Display for AllocError {
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index f20c497a1..1a379ecc1 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -1,7 +1,4 @@
-//! This module contains the `Any` trait, which enables dynamic typing
-//! of any `'static` type through runtime reflection. It also contains the
-//! `Provider` trait and accompanying API, which enable trait objects to provide
-//! data based on typed requests, an alternate form of runtime reflection.
+//! Utilities for dynamic typing or type reflection.
//!
//! # `Any` and `TypeId`
//!
@@ -799,7 +796,7 @@ pub trait Provider {
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_ref::<str>(&self.field)
- /// .provide_value::<i32>(|| self.num_field);
+ /// .provide_value::<i32>(self.num_field);
/// }
/// }
/// ```
@@ -884,28 +881,55 @@ impl<'a> Demand<'a> {
///
/// # Examples
///
+ /// Provides an `u8`.
+ ///
+ /// ```rust
+ /// #![feature(provide_any)]
+ ///
+ /// use std::any::{Provider, Demand};
+ /// # struct SomeConcreteType { field: u8 }
+ ///
+ /// impl Provider for SomeConcreteType {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// demand.provide_value::<u8>(self.field);
+ /// }
+ /// }
+ /// ```
+ #[unstable(feature = "provide_any", issue = "96024")]
+ pub fn provide_value<T>(&mut self, value: T) -> &mut Self
+ where
+ T: 'static,
+ {
+ self.provide::<tags::Value<T>>(value)
+ }
+
+ /// Provide a value or other type with only static lifetimes computed using a closure.
+ ///
+ /// # Examples
+ ///
/// Provides a `String` by cloning.
///
/// ```rust
- /// # #![feature(provide_any)]
+ /// #![feature(provide_any)]
+ ///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: String }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
- /// demand.provide_value::<String>(|| self.field.clone());
+ /// demand.provide_value_with::<String>(|| self.field.clone());
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
- pub fn provide_value<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
+ pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
where
T: 'static,
{
self.provide_with::<tags::Value<T>>(fulfil)
}
- /// Provide a reference, note that the referee type must be bounded by `'static`,
+ /// Provide a reference. The referee type must be bounded by `'static`,
/// but may be unsized.
///
/// # Examples
@@ -913,7 +937,8 @@ impl<'a> Demand<'a> {
/// Provides a reference to a field as a `&str`.
///
/// ```rust
- /// # #![feature(provide_any)]
+ /// #![feature(provide_any)]
+ ///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: String }
///
@@ -928,6 +953,40 @@ impl<'a> Demand<'a> {
self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
}
+ /// Provide a reference computed using a closure. The referee type
+ /// must be bounded by `'static`, but may be unsized.
+ ///
+ /// # Examples
+ ///
+ /// Provides a reference to a field as a `&str`.
+ ///
+ /// ```rust
+ /// #![feature(provide_any)]
+ ///
+ /// use std::any::{Provider, Demand};
+ /// # struct SomeConcreteType { business: String, party: String }
+ /// # fn today_is_a_weekday() -> bool { true }
+ ///
+ /// impl Provider for SomeConcreteType {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// demand.provide_ref_with::<str>(|| {
+ /// if today_is_a_weekday() {
+ /// &self.business
+ /// } else {
+ /// &self.party
+ /// }
+ /// });
+ /// }
+ /// }
+ /// ```
+ #[unstable(feature = "provide_any", issue = "96024")]
+ pub fn provide_ref_with<T: ?Sized + 'static>(
+ &mut self,
+ fulfil: impl FnOnce() -> &'a T,
+ ) -> &mut Self {
+ self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
+ }
+
/// Provide a value with the given `Type` tag.
fn provide<I>(&mut self, value: I::Reified) -> &mut Self
where
@@ -949,6 +1008,156 @@ impl<'a> Demand<'a> {
}
self
}
+
+ /// Check if the `Demand` would be satisfied if provided with a
+ /// value of the specified type. If the type does not match or has
+ /// already been provided, returns false.
+ ///
+ /// # Examples
+ ///
+ /// Check if an `u8` still needs to be provided and then provides
+ /// it.
+ ///
+ /// ```rust
+ /// #![feature(provide_any)]
+ ///
+ /// use std::any::{Provider, Demand};
+ ///
+ /// struct Parent(Option<u8>);
+ ///
+ /// impl Provider for Parent {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// if let Some(v) = self.0 {
+ /// demand.provide_value::<u8>(v);
+ /// }
+ /// }
+ /// }
+ ///
+ /// struct Child {
+ /// parent: Parent,
+ /// }
+ ///
+ /// impl Child {
+ /// // Pretend that this takes a lot of resources to evaluate.
+ /// fn an_expensive_computation(&self) -> Option<u8> {
+ /// Some(99)
+ /// }
+ /// }
+ ///
+ /// impl Provider for Child {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// // In general, we don't know if this call will provide
+ /// // an `u8` value or not...
+ /// self.parent.provide(demand);
+ ///
+ /// // ...so we check to see if the `u8` is needed before
+ /// // we run our expensive computation.
+ /// if demand.would_be_satisfied_by_value_of::<u8>() {
+ /// if let Some(v) = self.an_expensive_computation() {
+ /// demand.provide_value::<u8>(v);
+ /// }
+ /// }
+ ///
+ /// // The demand will be satisfied now, regardless of if
+ /// // the parent provided the value or we did.
+ /// assert!(!demand.would_be_satisfied_by_value_of::<u8>());
+ /// }
+ /// }
+ ///
+ /// let parent = Parent(Some(42));
+ /// let child = Child { parent };
+ /// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
+ ///
+ /// let parent = Parent(None);
+ /// let child = Child { parent };
+ /// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
+ /// ```
+ #[unstable(feature = "provide_any", issue = "96024")]
+ pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
+ where
+ T: 'static,
+ {
+ self.would_be_satisfied_by::<tags::Value<T>>()
+ }
+
+ /// Check if the `Demand` would be satisfied if provided with a
+ /// reference to a value of the specified type. If the type does
+ /// not match or has already been provided, returns false.
+ ///
+ /// # Examples
+ ///
+ /// Check if a `&str` still needs to be provided and then provides
+ /// it.
+ ///
+ /// ```rust
+ /// #![feature(provide_any)]
+ ///
+ /// use std::any::{Provider, Demand};
+ ///
+ /// struct Parent(Option<String>);
+ ///
+ /// impl Provider for Parent {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// if let Some(v) = &self.0 {
+ /// demand.provide_ref::<str>(v);
+ /// }
+ /// }
+ /// }
+ ///
+ /// struct Child {
+ /// parent: Parent,
+ /// name: String,
+ /// }
+ ///
+ /// impl Child {
+ /// // Pretend that this takes a lot of resources to evaluate.
+ /// fn an_expensive_computation(&self) -> Option<&str> {
+ /// Some(&self.name)
+ /// }
+ /// }
+ ///
+ /// impl Provider for Child {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// // In general, we don't know if this call will provide
+ /// // a `str` reference or not...
+ /// self.parent.provide(demand);
+ ///
+ /// // ...so we check to see if the `&str` is needed before
+ /// // we run our expensive computation.
+ /// if demand.would_be_satisfied_by_ref_of::<str>() {
+ /// if let Some(v) = self.an_expensive_computation() {
+ /// demand.provide_ref::<str>(v);
+ /// }
+ /// }
+ ///
+ /// // The demand will be satisfied now, regardless of if
+ /// // the parent provided the reference or we did.
+ /// assert!(!demand.would_be_satisfied_by_ref_of::<str>());
+ /// }
+ /// }
+ ///
+ /// let parent = Parent(Some("parent".into()));
+ /// let child = Child { parent, name: "child".into() };
+ /// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
+ ///
+ /// let parent = Parent(None);
+ /// let child = Child { parent, name: "child".into() };
+ /// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
+ /// ```
+ #[unstable(feature = "provide_any", issue = "96024")]
+ pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
+ where
+ T: ?Sized + 'static,
+ {
+ self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
+ }
+
+ fn would_be_satisfied_by<I>(&self) -> bool
+ where
+ I: tags::Type<'a>,
+ {
+ matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
+ }
}
#[unstable(feature = "provide_any", issue = "96024")]
@@ -1053,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a {
/// Returns some reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
+ fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
+ where
+ I: tags::Type<'a>,
+ {
+ if self.tag_id() == TypeId::of::<I>() {
+ // SAFETY: Just checked whether we're pointing to an I.
+ Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
+ } else {
+ None
+ }
+ }
+
+ /// Returns some mutable reference to the dynamic value if it is tagged with `I`,
+ /// or `None` otherwise.
+ #[inline]
fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
where
I: tags::Type<'a>,
diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs
index 33f7f494e..b2c895f88 100644
--- a/library/core/src/array/equality.rs
+++ b/library/core/src/array/equality.rs
@@ -173,13 +173,14 @@ macro_rules! is_raw_eq_comparable {
)+};
}
-// SAFETY: All the ordinary integer types allow all bit patterns as distinct values
+// SAFETY: All the ordinary integer types have no padding, and are not pointers.
is_raw_eq_comparable!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
-// SAFETY: bool and char have *niches*, but no *padding*, so this is sound
+// SAFETY: bool and char have *niches*, but no *padding* (and these are not pointer types), so this
+// is sound
is_raw_eq_comparable!(bool, char);
-// SAFETY: Similarly, the non-zero types have a niche, but no undef,
+// SAFETY: Similarly, the non-zero types have a niche, but no undef and no pointers,
// and they compare like their underlying numeric type.
is_raw_eq_comparable!(
NonZeroU8,
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index c9823a136..9effb3790 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -1,4 +1,4 @@
-//! Helper functions and types for fixed-length arrays.
+//! Utilities for the array primitive type.
//!
//! *[See also the array primitive type](array).*
@@ -7,6 +7,8 @@
use crate::borrow::{Borrow, BorrowMut};
use crate::cmp::Ordering;
use crate::convert::{Infallible, TryFrom};
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
use crate::hash::{self, Hash};
use crate::iter::TrustedLen;
@@ -119,6 +121,15 @@ impl fmt::Display for TryFromSliceError {
}
}
+#[cfg(not(bootstrap))]
+#[stable(feature = "try_from", since = "1.34.0")]
+impl Error for TryFromSliceError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ self.__description()
+ }
+}
+
impl TryFromSliceError {
#[unstable(
feature = "array_error_internals",
diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs
index f7a8aa0d9..7667a6508 100644
--- a/library/core/src/bool.rs
+++ b/library/core/src/bool.rs
@@ -6,6 +6,12 @@ impl bool {
/// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
/// or `None` otherwise.
///
+ /// Arguments passed to `then_some` are eagerly evaluated; if you are
+ /// passing the result of a function call, it is recommended to use
+ /// [`then`], which is lazily evaluated.
+ ///
+ /// [`then`]: bool::then
+ ///
/// # Examples
///
/// ```
diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs
index 58eabecf3..8378611eb 100644
--- a/library/core/src/borrow.rs
+++ b/library/core/src/borrow.rs
@@ -1,4 +1,4 @@
-//! A module for working with borrowed data.
+//! Utilities for working with borrowed data.
#![stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs
index 71297acd1..dc8ea66cc 100644
--- a/library/core/src/char/decode.rs
+++ b/library/core/src/char/decode.rs
@@ -1,5 +1,7 @@
//! UTF-8 and UTF-16 decoding iterators
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
use super::from_u32_unchecked;
@@ -121,3 +123,12 @@ impl fmt::Display for DecodeUtf16Error {
write!(f, "unpaired surrogate found: {:x}", self.code)
}
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "decode_utf16", since = "1.9.0")]
+impl Error for DecodeUtf16Error {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "unpaired surrogate found"
+ }
+}
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index eae567cad..b7a63b7c6 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -746,10 +746,19 @@ impl char {
/// assert!(!'中'.is_lowercase());
/// assert!(!' '.is_lowercase());
/// ```
+ ///
+ /// In a const context:
+ ///
+ /// ```
+ /// #![feature(const_unicode_case_lookup)]
+ /// const CAPITAL_DELTA_IS_LOWERCASE: bool = 'Δ'.is_lowercase();
+ /// assert!(!CAPITAL_DELTA_IS_LOWERCASE);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
#[inline]
- pub fn is_lowercase(self) -> bool {
+ pub const fn is_lowercase(self) -> bool {
match self {
'a'..='z' => true,
c => c > '\x7f' && unicode::Lowercase(c),
@@ -779,10 +788,19 @@ impl char {
/// assert!(!'中'.is_uppercase());
/// assert!(!' '.is_uppercase());
/// ```
+ ///
+ /// In a const context:
+ ///
+ /// ```
+ /// #![feature(const_unicode_case_lookup)]
+ /// const CAPITAL_DELTA_IS_UPPERCASE: bool = 'Δ'.is_uppercase();
+ /// assert!(CAPITAL_DELTA_IS_UPPERCASE);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
#[inline]
- pub fn is_uppercase(self) -> bool {
+ pub const fn is_uppercase(self) -> bool {
match self {
'A'..='Z' => true,
c => c > '\x7f' && unicode::Uppercase(c),
@@ -892,8 +910,7 @@ impl char {
///
/// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
/// characters, and `No` for other numeric characters) are specified in the [Unicode Character
- /// Database][ucd] [`UnicodeData.txt`]. Note that this means ideographic numbers like '三'
- /// are considered alphabetic, not numeric. Please consider to use `is_ascii_digit` or `is_digit`.
+ /// Database][ucd] [`UnicodeData.txt`].
///
/// This method doesn't cover everything that could be considered a number, e.g. ideographic numbers like '三'.
/// If you want everything including characters with overlapping purposes then you might want to use
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index 0df23e7bb..72d63ac4b 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -1,4 +1,6 @@
-//! A character type.
+//! Utilities for the `char` primitive type.
+//!
+//! *[See also the `char` primitive type](primitive@char).*
//!
//! The `char` type represents a single character. More specifically, since
//! 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode
@@ -36,6 +38,8 @@ pub use self::methods::encode_utf16_raw;
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
pub use self::methods::encode_utf8_raw;
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt::{self, Write};
use crate::iter::FusedIterator;
@@ -582,3 +586,7 @@ impl fmt::Display for TryFromCharError {
"unicode code point out of range".fmt(fmt)
}
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "u8_from_char", since = "1.59.0")]
+impl Error for TryFromCharError {}
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 20bb67687..d9f2d3d64 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1,6 +1,6 @@
-//! Functionality for ordering and comparison.
+//! Utilities for comparing and ordering values.
//!
-//! This module contains various tools for ordering and comparing values. In
+//! This module contains various tools for comparing and ordering values. In
//! summary:
//!
//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
@@ -23,6 +23,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::marker::Destruct;
+use crate::marker::StructuralPartialEq;
use self::Ordering::*;
@@ -38,8 +39,10 @@ use self::Ordering::*;
///
/// Implementations must ensure that `eq` and `ne` are consistent with each other:
///
-/// - `a != b` if and only if `!(a == b)`
-/// (ensured by the default implementation).
+/// - `a != b` if and only if `!(a == b)`.
+///
+/// The default implementation of `ne` provides this consistency and is almost
+/// always sufficient. It should not be overridden without very good reason.
///
/// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
/// be consistent with `PartialEq` (see the documentation of those traits for the exact
@@ -225,7 +228,8 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
#[stable(feature = "rust1", since = "1.0.0")]
fn eq(&self, other: &Rhs) -> bool;
- /// This method tests for `!=`.
+ /// This method tests for `!=`. The default implementation is almost always
+ /// sufficient, and should not be overridden without very good reason.
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -335,7 +339,7 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> {
/// let result = 2.cmp(&1);
/// assert_eq!(Ordering::Greater, result);
/// ```
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, Copy, Eq, Debug, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(i8)]
pub enum Ordering {
@@ -882,6 +886,18 @@ pub macro Ord($item:item) {
}
#[stable(feature = "rust1", since = "1.0.0")]
+impl StructuralPartialEq for Ordering {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
+impl const PartialEq for Ordering {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ (*self as i32).eq(&(*other as i32))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
impl const Ord for Ordering {
#[inline]
@@ -1139,11 +1155,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn le(&self, other: &Rhs) -> bool {
- // Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
- // FIXME: The root cause was fixed upstream in LLVM with:
- // https://github.com/llvm/llvm-project/commit/9bad7de9a3fb844f1ca2965f35d0c2a3d1e11775
- // Revert this workaround once support for LLVM 12 gets dropped.
- !matches!(self.partial_cmp(other), None | Some(Greater))
+ matches!(self.partial_cmp(other), Some(Less | Equal))
}
/// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index b30c8a4ae..05637c166 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -34,6 +34,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
use crate::hash::{Hash, Hasher};
@@ -556,6 +558,7 @@ where
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for T {
/// Returns the argument unchanged.
+ #[inline(always)]
fn from(t: T) -> T {
t
}
@@ -715,6 +718,14 @@ impl fmt::Display for Infallible {
}
}
+#[cfg(not(bootstrap))]
+#[stable(feature = "str_parse_error2", since = "1.8.0")]
+impl Error for Infallible {
+ fn description(&self) -> &str {
+ match *self {}
+ }
+}
+
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl PartialEq for Infallible {
fn eq(&self, _: &Infallible) -> bool {
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 1ce00828b..b53cd6074 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -1,4 +1,4 @@
-//! The `Default` trait for types which may have meaningful default values.
+//! The `Default` trait for types with a default value.
#![stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/error.md b/library/core/src/error.md
new file mode 100644
index 000000000..891abebbf
--- /dev/null
+++ b/library/core/src/error.md
@@ -0,0 +1,137 @@
+Interfaces for working with Errors.
+
+# Error Handling In Rust
+
+The Rust language provides two complementary systems for constructing /
+representing, reporting, propagating, reacting to, and discarding errors.
+These responsibilities are collectively known as "error handling." The
+components of the first system, the panic runtime and interfaces, are most
+commonly used to represent bugs that have been detected in your program. The
+components of the second system, `Result`, the error traits, and user
+defined types, are used to represent anticipated runtime failure modes of
+your program.
+
+## The Panic Interfaces
+
+The following are the primary interfaces of the panic system and the
+responsibilities they cover:
+
+* [`panic!`] and [`panic_any`] (Constructing, Propagated automatically)
+* [`PanicInfo`] (Reporting)
+* [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting)
+* [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating)
+
+The following are the primary interfaces of the error system and the
+responsibilities they cover:
+
+* [`Result`] (Propagating, Reacting)
+* The [`Error`] trait (Reporting)
+* User defined types (Constructing / Representing)
+* [`match`] and [`downcast`] (Reacting)
+* The question mark operator ([`?`]) (Propagating)
+* The partially stable [`Try`] traits (Propagating, Constructing)
+* [`Termination`] (Reporting)
+
+## Converting Errors into Panics
+
+The panic and error systems are not entirely distinct. Often times errors
+that are anticipated runtime failures in an API might instead represent bugs
+to a caller. For these situations the standard library provides APIs for
+constructing panics with an `Error` as it's source.
+
+* [`Result::unwrap`]
+* [`Result::expect`]
+
+These functions are equivalent, they either return the inner value if the
+`Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
+as the source. The only difference between them is that with `expect` you
+provide a panic error message to be printed alongside the source, whereas
+`unwrap` has a default message indicating only that you unwraped an `Err`.
+
+Of the two, `expect` is generally preferred since its `msg` field allows you
+to convey your intent and assumptions which makes tracking down the source
+of a panic easier. `unwrap` on the other hand can still be a good fit in
+situations where you can trivially show that a piece of code will never
+panic, such as `"127.0.0.1".parse::<std::net::IpAddr>().unwrap()` or early
+prototyping.
+
+# Common Message Styles
+
+There are two common styles for how people word `expect` messages. Using
+the message to present information to users encountering a panic
+("expect as error message") or using the message to present information
+to developers debugging the panic ("expect as precondition").
+
+In the former case the expect message is used to describe the error that
+has occurred which is considered a bug. Consider the following example:
+
+```should_panic
+// Read environment variable, panic if it is not present
+let path = std::env::var("IMPORTANT_PATH").unwrap();
+```
+
+In the "expect as error message" style we would use expect to describe
+that the environment variable was not set when it should have been:
+
+```should_panic
+let path = std::env::var("IMPORTANT_PATH")
+ .expect("env variable `IMPORTANT_PATH` is not set");
+```
+
+In the "expect as precondition" style, we would instead describe the
+reason we _expect_ the `Result` should be `Ok`. With this style we would
+prefer to write:
+
+```should_panic
+let path = std::env::var("IMPORTANT_PATH")
+ .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
+```
+
+The "expect as error message" style does not work as well with the
+default output of the std panic hooks, and often ends up repeating
+information that is already communicated by the source error being
+unwrapped:
+
+```text
+thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
+```
+
+In this example we end up mentioning that an env variable is not set,
+followed by our source message that says the env is not present, the
+only additional information we're communicating is the name of the
+environment variable being checked.
+
+The "expect as precondition" style instead focuses on source code
+readability, making it easier to understand what must have gone wrong in
+situations where panics are being used to represent bugs exclusively.
+Also, by framing our expect in terms of what "SHOULD" have happened to
+prevent the source error, we end up introducing new information that is
+independent from our source error.
+
+```text
+thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
+```
+
+In this example we are communicating not only the name of the
+environment variable that should have been set, but also an explanation
+for why it should have been set, and we let the source error display as
+a clear contradiction to our expectation.
+
+**Hint**: If you're having trouble remembering how to phrase
+expect-as-precondition style error messages remember to focus on the word
+"should" as in "env variable should be set by blah" or "the given binary
+should be available and executable by the current user".
+
+[`panic_any`]: ../../std/panic/fn.panic_any.html
+[`PanicInfo`]: crate::panic::PanicInfo
+[`catch_unwind`]: ../../std/panic/fn.catch_unwind.html
+[`resume_unwind`]: ../../std/panic/fn.resume_unwind.html
+[`downcast`]: crate::error::Error
+[`Termination`]: ../../std/process/trait.Termination.html
+[`Try`]: crate::ops::Try
+[panic hook]: ../../std/panic/fn.set_hook.html
+[`set_hook`]: ../../std/panic/fn.set_hook.html
+[`take_hook`]: ../../std/panic/fn.take_hook.html
+[panic-handler]: <https://doc.rust-lang.org/nomicon/panic-handler.html>
+[`match`]: ../../std/keyword.match.html
+[`?`]: ../../std/result/index.html#the-question-mark-operator-
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
new file mode 100644
index 000000000..4a8efe15e
--- /dev/null
+++ b/library/core/src/error.rs
@@ -0,0 +1,508 @@
+#![doc = include_str!("error.md")]
+#![unstable(feature = "error_in_core", issue = "none")]
+
+#[cfg(test)]
+mod tests;
+
+use crate::any::{Demand, Provider, TypeId};
+use crate::fmt::{Debug, Display};
+
+/// `Error` is a trait representing the basic expectations for error values,
+/// i.e., values of type `E` in [`Result<T, E>`].
+///
+/// Errors must describe themselves through the [`Display`] and [`Debug`]
+/// traits. Error messages are typically concise lowercase sentences without
+/// trailing punctuation:
+///
+/// ```
+/// let err = "NaN".parse::<u32>().unwrap_err();
+/// assert_eq!(err.to_string(), "invalid digit found in string");
+/// ```
+///
+/// Errors may provide cause information. [`Error::source()`] is generally
+/// used when errors cross "abstraction boundaries". If one module must report
+/// an error that is caused by an error from a lower-level module, it can allow
+/// accessing that error via [`Error::source()`]. This makes it possible for the
+/// high-level module to provide its own errors while also revealing some of the
+/// implementation for debugging.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
+#[rustc_has_incoherent_inherent_impls]
+pub trait Error: Debug + Display {
+ /// The lower-level source of this error, if any.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::error::Error;
+ /// use std::fmt;
+ ///
+ /// #[derive(Debug)]
+ /// struct SuperError {
+ /// source: SuperErrorSideKick,
+ /// }
+ ///
+ /// impl fmt::Display for SuperError {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "SuperError is here!")
+ /// }
+ /// }
+ ///
+ /// impl Error for SuperError {
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// Some(&self.source)
+ /// }
+ /// }
+ ///
+ /// #[derive(Debug)]
+ /// struct SuperErrorSideKick;
+ ///
+ /// impl fmt::Display for SuperErrorSideKick {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "SuperErrorSideKick is here!")
+ /// }
+ /// }
+ ///
+ /// impl Error for SuperErrorSideKick {}
+ ///
+ /// fn get_super_error() -> Result<(), SuperError> {
+ /// Err(SuperError { source: SuperErrorSideKick })
+ /// }
+ ///
+ /// fn main() {
+ /// match get_super_error() {
+ /// Err(e) => {
+ /// println!("Error: {e}");
+ /// println!("Caused by: {}", e.source().unwrap());
+ /// }
+ /// _ => println!("No error"),
+ /// }
+ /// }
+ /// ```
+ #[stable(feature = "error_source", since = "1.30.0")]
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ None
+ }
+
+ /// Gets the `TypeId` of `self`.
+ #[doc(hidden)]
+ #[unstable(
+ feature = "error_type_id",
+ reason = "this is memory-unsafe to override in user code",
+ issue = "60784"
+ )]
+ fn type_id(&self, _: private::Internal) -> TypeId
+ where
+ Self: 'static,
+ {
+ TypeId::of::<Self>()
+ }
+
+ /// ```
+ /// if let Err(e) = "xc".parse::<u32>() {
+ /// // Print `e` itself, no need for description().
+ /// eprintln!("Error: {e}");
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
+ fn description(&self) -> &str {
+ "description() is deprecated; use Display"
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[deprecated(
+ since = "1.33.0",
+ note = "replaced by Error::source, which can support downcasting"
+ )]
+ #[allow(missing_docs)]
+ fn cause(&self) -> Option<&dyn Error> {
+ self.source()
+ }
+
+ /// Provides type based access to context intended for error reports.
+ ///
+ /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
+ /// references to member variables from `dyn Error` trait objects.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// #![feature(provide_any)]
+ /// #![feature(error_generic_member_access)]
+ /// use core::fmt;
+ /// use core::any::Demand;
+ ///
+ /// #[derive(Debug)]
+ /// struct MyBacktrace {
+ /// // ...
+ /// }
+ ///
+ /// impl MyBacktrace {
+ /// fn new() -> MyBacktrace {
+ /// // ...
+ /// # MyBacktrace {}
+ /// }
+ /// }
+ ///
+ /// #[derive(Debug)]
+ /// struct SourceError {
+ /// // ...
+ /// }
+ ///
+ /// impl fmt::Display for SourceError {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "Example Source Error")
+ /// }
+ /// }
+ ///
+ /// impl std::error::Error for SourceError {}
+ ///
+ /// #[derive(Debug)]
+ /// struct Error {
+ /// source: SourceError,
+ /// backtrace: MyBacktrace,
+ /// }
+ ///
+ /// impl fmt::Display for Error {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "Example Error")
+ /// }
+ /// }
+ ///
+ /// impl std::error::Error for Error {
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// demand
+ /// .provide_ref::<MyBacktrace>(&self.backtrace)
+ /// .provide_ref::<dyn std::error::Error + 'static>(&self.source);
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let backtrace = MyBacktrace::new();
+ /// let source = SourceError {};
+ /// let error = Error { source, backtrace };
+ /// let dyn_error = &error as &dyn std::error::Error;
+ /// let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
+ ///
+ /// assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
+ /// }
+ /// ```
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ #[allow(unused_variables)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
+}
+
+#[unstable(feature = "error_generic_member_access", issue = "99301")]
+impl<E> Provider for E
+where
+ E: Error + ?Sized,
+{
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ self.provide(demand)
+ }
+}
+
+mod private {
+ // This is a hack to prevent `type_id` from being overridden by `Error`
+ // implementations, since that can enable unsound downcasting.
+ #[unstable(feature = "error_type_id", issue = "60784")]
+ #[derive(Debug)]
+ pub struct Internal;
+}
+
+#[unstable(feature = "never_type", issue = "35121")]
+impl Error for ! {}
+
+impl<'a> dyn Error + 'a {
+ /// Request a reference of type `T` as context about this error.
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
+ core::any::request_ref(self)
+ }
+
+ /// Request a value of type `T` as context about this error.
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ pub fn request_value<T: 'static>(&'a self) -> Option<T> {
+ core::any::request_value(self)
+ }
+}
+
+// Copied from `any.rs`.
+impl dyn Error + 'static {
+ /// Returns `true` if the inner type is the same as `T`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn is<T: Error + 'static>(&self) -> bool {
+ // Get `TypeId` of the type this function is instantiated with.
+ let t = TypeId::of::<T>();
+
+ // Get `TypeId` of the type in the trait object (`self`).
+ let concrete = self.type_id(private::Internal);
+
+ // Compare both `TypeId`s on equality.
+ t == concrete
+ }
+
+ /// Returns some reference to the inner value if it is of type `T`, or
+ /// `None` if it isn't.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
+ if self.is::<T>() {
+ // SAFETY: `is` ensures this type cast is correct
+ unsafe { Some(&*(self as *const dyn Error as *const T)) }
+ } else {
+ None
+ }
+ }
+
+ /// Returns some mutable reference to the inner value if it is of type `T`, or
+ /// `None` if it isn't.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
+ if self.is::<T>() {
+ // SAFETY: `is` ensures this type cast is correct
+ unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
+ } else {
+ None
+ }
+ }
+}
+
+impl dyn Error + 'static + Send {
+ /// Forwards to the method defined on the type `dyn Error`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn is<T: Error + 'static>(&self) -> bool {
+ <dyn Error + 'static>::is::<T>(self)
+ }
+
+ /// Forwards to the method defined on the type `dyn Error`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
+ <dyn Error + 'static>::downcast_ref::<T>(self)
+ }
+
+ /// Forwards to the method defined on the type `dyn Error`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
+ <dyn Error + 'static>::downcast_mut::<T>(self)
+ }
+
+ /// Request a reference of type `T` as context about this error.
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
+ <dyn Error>::request_ref(self)
+ }
+
+ /// Request a value of type `T` as context about this error.
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ pub fn request_value<T: 'static>(&self) -> Option<T> {
+ <dyn Error>::request_value(self)
+ }
+}
+
+impl dyn Error + 'static + Send + Sync {
+ /// Forwards to the method defined on the type `dyn Error`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn is<T: Error + 'static>(&self) -> bool {
+ <dyn Error + 'static>::is::<T>(self)
+ }
+
+ /// Forwards to the method defined on the type `dyn Error`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
+ <dyn Error + 'static>::downcast_ref::<T>(self)
+ }
+
+ /// Forwards to the method defined on the type `dyn Error`.
+ #[stable(feature = "error_downcast", since = "1.3.0")]
+ #[inline]
+ pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
+ <dyn Error + 'static>::downcast_mut::<T>(self)
+ }
+
+ /// Request a reference of type `T` as context about this error.
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
+ <dyn Error>::request_ref(self)
+ }
+
+ /// Request a value of type `T` as context about this error.
+ #[unstable(feature = "error_generic_member_access", issue = "99301")]
+ pub fn request_value<T: 'static>(&self) -> Option<T> {
+ <dyn Error>::request_value(self)
+ }
+}
+
+impl dyn Error {
+ /// Returns an iterator starting with the current error and continuing with
+ /// recursively calling [`Error::source`].
+ ///
+ /// If you want to omit the current error and only use its sources,
+ /// use `skip(1)`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(error_iter)]
+ /// use std::error::Error;
+ /// use std::fmt;
+ ///
+ /// #[derive(Debug)]
+ /// struct A;
+ ///
+ /// #[derive(Debug)]
+ /// struct B(Option<Box<dyn Error + 'static>>);
+ ///
+ /// impl fmt::Display for A {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "A")
+ /// }
+ /// }
+ ///
+ /// impl fmt::Display for B {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// write!(f, "B")
+ /// }
+ /// }
+ ///
+ /// impl Error for A {}
+ ///
+ /// impl Error for B {
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// self.0.as_ref().map(|e| e.as_ref())
+ /// }
+ /// }
+ ///
+ /// let b = B(Some(Box::new(A)));
+ ///
+ /// // let err : Box<Error> = b.into(); // or
+ /// let err = &b as &(dyn Error);
+ ///
+ /// let mut iter = err.sources();
+ ///
+ /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
+ /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
+ /// assert!(iter.next().is_none());
+ /// assert!(iter.next().is_none());
+ /// ```
+ #[unstable(feature = "error_iter", issue = "58520")]
+ #[inline]
+ pub fn sources(&self) -> Source<'_> {
+ // You may think this method would be better in the Error trait, and you'd be right.
+ // Unfortunately that doesn't work, not because of the object safety rules but because we
+ // save a reference to self in Sources below as a trait object. If this method was
+ // declared in Error, then self would have the type &T where T is some concrete type which
+ // implements Error. We would need to coerce self to have type &dyn Error, but that requires
+ // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error
+ // since that would forbid Error trait objects, and we can't put that bound on the method
+ // because that means the method can't be called on trait objects (we'd also need the
+ // 'static bound, but that isn't allowed because methods with bounds on Self other than
+ // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible.
+
+ Source { current: Some(self) }
+ }
+}
+
+/// An iterator over an [`Error`] and its sources.
+///
+/// If you want to omit the initial error and only process
+/// its sources, use `skip(1)`.
+#[unstable(feature = "error_iter", issue = "58520")]
+#[derive(Clone, Debug)]
+pub struct Source<'a> {
+ current: Option<&'a (dyn Error + 'static)>,
+}
+
+#[unstable(feature = "error_iter", issue = "58520")]
+impl<'a> Iterator for Source<'a> {
+ type Item = &'a (dyn Error + 'static);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let current = self.current;
+ self.current = self.current.and_then(Error::source);
+ current
+ }
+}
+
+#[stable(feature = "error_by_ref", since = "1.51.0")]
+impl<'a, T: Error + ?Sized> Error for &'a T {
+ #[allow(deprecated, deprecated_in_future)]
+ fn description(&self) -> &str {
+ Error::description(&**self)
+ }
+
+ #[allow(deprecated)]
+ fn cause(&self) -> Option<&dyn Error> {
+ Error::cause(&**self)
+ }
+
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ Error::source(&**self)
+ }
+
+ fn provide<'b>(&'b self, demand: &mut Demand<'b>) {
+ Error::provide(&**self, demand);
+ }
+}
+
+#[stable(feature = "fmt_error", since = "1.11.0")]
+impl Error for crate::fmt::Error {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "an error occurred when formatting an argument"
+ }
+}
+
+#[stable(feature = "try_borrow", since = "1.13.0")]
+impl Error for crate::cell::BorrowError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "already mutably borrowed"
+ }
+}
+
+#[stable(feature = "try_borrow", since = "1.13.0")]
+impl Error for crate::cell::BorrowMutError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "already borrowed"
+ }
+}
+
+#[stable(feature = "try_from", since = "1.34.0")]
+impl Error for crate::char::CharTryFromError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "converted integer out of range for `char`"
+ }
+}
+
+#[stable(feature = "char_from_str", since = "1.20.0")]
+impl Error for crate::char::ParseCharError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ self.__description()
+ }
+}
+
+#[unstable(feature = "duration_checked_float", issue = "83400")]
+impl Error for crate::time::FromFloatSecsError {}
+
+#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
+impl Error for crate::ffi::FromBytesWithNulError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ self.__description()
+ }
+}
+
+#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+impl Error for crate::ffi::FromBytesUntilNulError {}
diff --git a/library/core/src/ffi/c_double.md b/library/core/src/ffi/c_double.md
index 57f453482..d49e29b6e 100644
--- a/library/core/src/ffi/c_double.md
+++ b/library/core/src/ffi/c_double.md
@@ -1,6 +1,6 @@
Equivalent to C's `double` type.
-This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
+This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
-[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
+[IEEE 754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[`float`]: c_float
diff --git a/library/core/src/ffi/c_float.md b/library/core/src/ffi/c_float.md
index 61e2abc05..36374ef43 100644
--- a/library/core/src/ffi/c_float.md
+++ b/library/core/src/ffi/c_float.md
@@ -1,5 +1,5 @@
Equivalent to C's `float` type.
-This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
+This type will almost always be [`f32`], which is guaranteed to be an [IEEE 754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
-[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
+[IEEE 754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 82e63a7fe..21f80ec02 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -1,7 +1,6 @@
-use crate::ascii;
use crate::cmp::Ordering;
use crate::ffi::c_char;
-use crate::fmt::{self, Write};
+use crate::fmt;
use crate::intrinsics;
use crate::ops;
use crate::slice;
@@ -121,10 +120,10 @@ enum FromBytesWithNulErrorKind {
}
impl FromBytesWithNulError {
- fn interior_nul(pos: usize) -> FromBytesWithNulError {
+ const fn interior_nul(pos: usize) -> FromBytesWithNulError {
FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
}
- fn not_nul_terminated() -> FromBytesWithNulError {
+ const fn not_nul_terminated() -> FromBytesWithNulError {
FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
}
@@ -161,11 +160,7 @@ impl fmt::Display for FromBytesUntilNulError {
#[stable(feature = "cstr_debug", since = "1.3.0")]
impl fmt::Debug for CStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "\"")?;
- for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) {
- f.write_char(byte as char)?;
- }
- write!(f, "\"")
+ write!(f, "\"{}\"", self.to_bytes().escape_ascii())
}
}
@@ -299,7 +294,8 @@ impl CStr {
/// ```
///
#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
- pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
+ #[rustc_const_unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+ pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
let nul_pos = memchr::memchr(0, bytes);
match nul_pos {
Some(nul_pos) => {
@@ -348,7 +344,8 @@ impl CStr {
/// assert!(cstr.is_err());
/// ```
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
- pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
+ #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+ pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
let nul_pos = memchr::memchr(0, bytes);
match nul_pos {
Some(nul_pos) if nul_pos + 1 == bytes.len() => {
@@ -387,6 +384,7 @@ impl CStr {
#[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")]
#[rustc_allow_const_fn_unstable(const_eval_select)]
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
+ #[inline]
fn rt_impl(bytes: &[u8]) -> &CStr {
// Chance at catching some UB at runtime with debug builds.
debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0);
@@ -497,7 +495,8 @@ impl CStr {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn to_bytes(&self) -> &[u8] {
+ #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+ pub const fn to_bytes(&self) -> &[u8] {
let bytes = self.to_bytes_with_nul();
// SAFETY: to_bytes_with_nul returns slice with length at least 1
unsafe { bytes.get_unchecked(..bytes.len() - 1) }
@@ -524,7 +523,8 @@ impl CStr {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn to_bytes_with_nul(&self) -> &[u8] {
+ #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+ pub const fn to_bytes_with_nul(&self) -> &[u8] {
// SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
// is safe on all supported targets.
unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
@@ -547,7 +547,8 @@ impl CStr {
/// assert_eq!(cstr.to_str(), Ok("foo"));
/// ```
#[stable(feature = "cstr_to_str", since = "1.4.0")]
- pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
+ #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+ pub const fn to_str(&self) -> Result<&str, str::Utf8Error> {
// N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
// instead of in `from_ptr()`, it may be worth considering if this should
// be rewritten to do the UTF-8 check inline with the length calculation
diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs
index 32d1a4e55..7da49b04a 100644
--- a/library/core/src/fmt/builders.rs
+++ b/library/core/src/fmt/builders.rs
@@ -28,24 +28,14 @@ impl<'buf, 'state> PadAdapter<'buf, 'state> {
}
impl fmt::Write for PadAdapter<'_, '_> {
- fn write_str(&mut self, mut s: &str) -> fmt::Result {
- while !s.is_empty() {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for s in s.split_inclusive('\n') {
if self.state.on_newline {
self.buf.write_str(" ")?;
}
- let split = match s.find('\n') {
- Some(pos) => {
- self.state.on_newline = true;
- pos + 1
- }
- None => {
- self.state.on_newline = false;
- s.len()
- }
- };
- self.buf.write_str(&s[..split])?;
- s = &s[split..];
+ self.state.on_newline = s.ends_with('\n');
+ self.buf.write_str(s)?;
}
Ok(())
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 372141e09..905212eb3 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -119,6 +119,10 @@ pub trait Write {
///
/// This function will return an instance of [`Error`] on error.
///
+ /// The purpose of std::fmt::Error is to abort the formatting operation when the underlying
+ /// destination encounters some error preventing it from accepting more text; it should
+ /// generally be propagated rather than handled, at least when implementing formatting traits.
+ ///
/// # Examples
///
/// ```
@@ -1815,7 +1819,7 @@ impl<'a> Formatter<'a> {
/// write!(formatter,
/// "Foo({}{})",
/// if self.0 < 0 { '-' } else { '+' },
- /// self.0)
+ /// self.0.abs())
/// } else {
/// write!(formatter, "Foo({})", self.0)
/// }
@@ -1823,6 +1827,7 @@ impl<'a> Formatter<'a> {
/// }
///
/// assert_eq!(&format!("{:+}", Foo(23)), "Foo(+23)");
+ /// assert_eq!(&format!("{:+}", Foo(-23)), "Foo(-23)");
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
/// ```
#[must_use]
@@ -2562,7 +2567,7 @@ macro_rules! tuple {
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item
diff --git a/library/core/src/future/poll_fn.rs b/library/core/src/future/poll_fn.rs
index db2a52332..90cb79739 100644
--- a/library/core/src/future/poll_fn.rs
+++ b/library/core/src/future/poll_fn.rs
@@ -5,7 +5,9 @@ use crate::task::{Context, Poll};
/// Creates a future that wraps a function returning [`Poll`].
///
-/// Polling the future delegates to the wrapped function.
+/// Polling the future delegates to the wrapped function. If the returned future is pinned, then the
+/// captured environment of the wrapped function is also pinned in-place, so as long as the closure
+/// does not move out of its captures it can soundly create pinned references to them.
///
/// # Examples
///
@@ -41,7 +43,7 @@ pub struct PollFn<F> {
}
#[stable(feature = "future_poll_fn", since = "1.64.0")]
-impl<F> Unpin for PollFn<F> {}
+impl<F: Unpin> Unpin for PollFn<F> {}
#[stable(feature = "future_poll_fn", since = "1.64.0")]
impl<F> fmt::Debug for PollFn<F> {
@@ -57,7 +59,8 @@ where
{
type Output = T;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
- (&mut self.f)(cx)
+ fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
+ // SAFETY: We are not moving out of the pinned field.
+ (unsafe { &mut self.get_unchecked_mut().f })(cx)
}
}
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 5974562ac..aa13435e6 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -900,7 +900,7 @@ mod impls {
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 81b6d5737..764e27962 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -31,7 +31,7 @@ use crate::intrinsics;
///
/// `unreachable_unchecked()` can be used in situations where the compiler
/// can't prove invariants that were previously established. Such situations
-/// have a higher chance of occuring if those invariants are upheld by
+/// have a higher chance of occurring if those invariants are upheld by
/// external code that the compiler can't analyze.
/// ```
/// fn prepare_inputs(divisors: &mut Vec<u32>) {
@@ -160,19 +160,16 @@ pub const unsafe fn unreachable_unchecked() -> ! {
#[inline]
#[stable(feature = "renamed_spin_loop", since = "1.49.0")]
pub fn spin_loop() {
- #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
+ #[cfg(target_arch = "x86")]
{
- #[cfg(target_arch = "x86")]
- {
- // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
- unsafe { crate::arch::x86::_mm_pause() };
- }
+ // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
+ unsafe { crate::arch::x86::_mm_pause() };
+ }
- #[cfg(target_arch = "x86_64")]
- {
- // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
- unsafe { crate::arch::x86_64::_mm_pause() };
- }
+ #[cfg(target_arch = "x86_64")]
+ {
+ // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
+ unsafe { crate::arch::x86_64::_mm_pause() };
}
// RISC-V platform spin loop hint implementation
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index cabc5017f..11c75e2c9 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -54,7 +54,9 @@
)]
#![allow(missing_docs)]
-use crate::marker::{Destruct, DiscriminantKind};
+#[cfg(bootstrap)]
+use crate::marker::Destruct;
+use crate::marker::DiscriminantKind;
use crate::mem;
// These imports are used for simplifying intra-doc links
@@ -63,7 +65,7 @@ use crate::mem;
use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
#[stable(feature = "drop_in_place", since = "1.8.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
#[inline]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
@@ -71,214 +73,6 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
unsafe { crate::ptr::drop_in_place(to_drop) }
}
-// These have been renamed.
-#[cfg(bootstrap)]
-extern "rust-intrinsic" {
- pub fn atomic_cxchg<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_load<T: Copy>(src: *const T) -> T;
- pub fn atomic_load_acq<T: Copy>(src: *const T) -> T;
- pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
- pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
- pub fn atomic_store<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_store_rel<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_xchg<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_fence();
- pub fn atomic_fence_acq();
- pub fn atomic_fence_rel();
- pub fn atomic_fence_acqrel();
- pub fn atomic_singlethreadfence();
- pub fn atomic_singlethreadfence_acq();
- pub fn atomic_singlethreadfence_rel();
- pub fn atomic_singlethreadfence_acqrel();
-}
-
-// These have been renamed.
-#[cfg(bootstrap)]
-mod atomics {
- pub use super::atomic_cxchg as atomic_cxchg_seqcst_seqcst;
- pub use super::atomic_cxchg_acq as atomic_cxchg_acquire_acquire;
- pub use super::atomic_cxchg_acq_failrelaxed as atomic_cxchg_acquire_relaxed;
- pub use super::atomic_cxchg_acqrel as atomic_cxchg_acqrel_acquire;
- pub use super::atomic_cxchg_acqrel_failrelaxed as atomic_cxchg_acqrel_relaxed;
- pub use super::atomic_cxchg_failacq as atomic_cxchg_seqcst_acquire;
- pub use super::atomic_cxchg_failrelaxed as atomic_cxchg_seqcst_relaxed;
- pub use super::atomic_cxchg_rel as atomic_cxchg_release_relaxed;
- pub use super::atomic_cxchg_relaxed as atomic_cxchg_relaxed_relaxed;
-
- pub use super::atomic_cxchgweak as atomic_cxchgweak_seqcst_seqcst;
- pub use super::atomic_cxchgweak_acq as atomic_cxchgweak_acquire_acquire;
- pub use super::atomic_cxchgweak_acq_failrelaxed as atomic_cxchgweak_acquire_relaxed;
- pub use super::atomic_cxchgweak_acqrel as atomic_cxchgweak_acqrel_acquire;
- pub use super::atomic_cxchgweak_acqrel_failrelaxed as atomic_cxchgweak_acqrel_relaxed;
- pub use super::atomic_cxchgweak_failacq as atomic_cxchgweak_seqcst_acquire;
- pub use super::atomic_cxchgweak_failrelaxed as atomic_cxchgweak_seqcst_relaxed;
- pub use super::atomic_cxchgweak_rel as atomic_cxchgweak_release_relaxed;
- pub use super::atomic_cxchgweak_relaxed as atomic_cxchgweak_relaxed_relaxed;
-
- pub use super::atomic_load as atomic_load_seqcst;
- pub use super::atomic_load_acq as atomic_load_acquire;
- pub use super::atomic_load_relaxed;
- pub use super::atomic_load_unordered;
-
- pub use super::atomic_store as atomic_store_seqcst;
- pub use super::atomic_store_rel as atomic_store_release;
- pub use super::atomic_store_relaxed;
- pub use super::atomic_store_unordered;
-
- pub use super::atomic_xchg as atomic_xchg_seqcst;
- pub use super::atomic_xchg_acq as atomic_xchg_acquire;
- pub use super::atomic_xchg_acqrel;
- pub use super::atomic_xchg_rel as atomic_xchg_release;
- pub use super::atomic_xchg_relaxed;
-
- pub use super::atomic_xadd as atomic_xadd_seqcst;
- pub use super::atomic_xadd_acq as atomic_xadd_acquire;
- pub use super::atomic_xadd_acqrel;
- pub use super::atomic_xadd_rel as atomic_xadd_release;
- pub use super::atomic_xadd_relaxed;
-
- pub use super::atomic_xsub as atomic_xsub_seqcst;
- pub use super::atomic_xsub_acq as atomic_xsub_acquire;
- pub use super::atomic_xsub_acqrel;
- pub use super::atomic_xsub_rel as atomic_xsub_release;
- pub use super::atomic_xsub_relaxed;
-
- pub use super::atomic_and as atomic_and_seqcst;
- pub use super::atomic_and_acq as atomic_and_acquire;
- pub use super::atomic_and_acqrel;
- pub use super::atomic_and_rel as atomic_and_release;
- pub use super::atomic_and_relaxed;
-
- pub use super::atomic_nand as atomic_nand_seqcst;
- pub use super::atomic_nand_acq as atomic_nand_acquire;
- pub use super::atomic_nand_acqrel;
- pub use super::atomic_nand_rel as atomic_nand_release;
- pub use super::atomic_nand_relaxed;
-
- pub use super::atomic_or as atomic_or_seqcst;
- pub use super::atomic_or_acq as atomic_or_acquire;
- pub use super::atomic_or_acqrel;
- pub use super::atomic_or_rel as atomic_or_release;
- pub use super::atomic_or_relaxed;
-
- pub use super::atomic_xor as atomic_xor_seqcst;
- pub use super::atomic_xor_acq as atomic_xor_acquire;
- pub use super::atomic_xor_acqrel;
- pub use super::atomic_xor_rel as atomic_xor_release;
- pub use super::atomic_xor_relaxed;
-
- pub use super::atomic_max as atomic_max_seqcst;
- pub use super::atomic_max_acq as atomic_max_acquire;
- pub use super::atomic_max_acqrel;
- pub use super::atomic_max_rel as atomic_max_release;
- pub use super::atomic_max_relaxed;
-
- pub use super::atomic_min as atomic_min_seqcst;
- pub use super::atomic_min_acq as atomic_min_acquire;
- pub use super::atomic_min_acqrel;
- pub use super::atomic_min_rel as atomic_min_release;
- pub use super::atomic_min_relaxed;
-
- pub use super::atomic_umin as atomic_umin_seqcst;
- pub use super::atomic_umin_acq as atomic_umin_acquire;
- pub use super::atomic_umin_acqrel;
- pub use super::atomic_umin_rel as atomic_umin_release;
- pub use super::atomic_umin_relaxed;
-
- pub use super::atomic_umax as atomic_umax_seqcst;
- pub use super::atomic_umax_acq as atomic_umax_acquire;
- pub use super::atomic_umax_acqrel;
- pub use super::atomic_umax_rel as atomic_umax_release;
- pub use super::atomic_umax_relaxed;
-
- pub use super::atomic_fence as atomic_fence_seqcst;
- pub use super::atomic_fence_acq as atomic_fence_acquire;
- pub use super::atomic_fence_acqrel;
- pub use super::atomic_fence_rel as atomic_fence_release;
-
- pub use super::atomic_singlethreadfence as atomic_singlethreadfence_seqcst;
- pub use super::atomic_singlethreadfence_acq as atomic_singlethreadfence_acquire;
- pub use super::atomic_singlethreadfence_acqrel;
- pub use super::atomic_singlethreadfence_rel as atomic_singlethreadfence_release;
-}
-
-#[cfg(bootstrap)]
-pub use atomics::*;
-
-#[cfg(not(bootstrap))]
extern "rust-intrinsic" {
// N.B., these intrinsics take raw pointers because they mutate aliased
// memory, which is not valid for either `&` or `&mut`.
@@ -945,30 +739,7 @@ extern "rust-intrinsic" {
/// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`]
/// as the `order`.
pub fn atomic_singlethreadfence_acqrel();
-}
-// These have been renamed.
-//
-// These are the aliases for the old names.
-// To be removed when stdarch and panic_unwind have been updated.
-#[cfg(not(bootstrap))]
-mod atomics {
- pub use super::atomic_cxchg_acqrel_acquire as atomic_cxchg_acqrel;
- pub use super::atomic_cxchg_acqrel_relaxed as atomic_cxchg_acqrel_failrelaxed;
- pub use super::atomic_cxchg_acquire_acquire as atomic_cxchg_acq;
- pub use super::atomic_cxchg_acquire_relaxed as atomic_cxchg_acq_failrelaxed;
- pub use super::atomic_cxchg_relaxed_relaxed as atomic_cxchg_relaxed;
- pub use super::atomic_cxchg_release_relaxed as atomic_cxchg_rel;
- pub use super::atomic_cxchg_seqcst_acquire as atomic_cxchg_failacq;
- pub use super::atomic_cxchg_seqcst_relaxed as atomic_cxchg_failrelaxed;
- pub use super::atomic_cxchg_seqcst_seqcst as atomic_cxchg;
- pub use super::atomic_store_seqcst as atomic_store;
-}
-
-#[cfg(not(bootstrap))]
-pub use atomics::*;
-
-extern "rust-intrinsic" {
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
/// if supported; otherwise, it is a no-op.
/// Prefetches have no effect on the behavior of the program but can change its performance
@@ -1313,7 +1084,7 @@ extern "rust-intrinsic" {
/// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
/// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
/// as expected -- this is touching on many unspecified aspects of the Rust memory model.
- /// Depending on what the code is doing, the following alternatives are preferrable to
+ /// Depending on what the code is doing, the following alternatives are preferable to
/// pointer-to-integer transmutation:
/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
/// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit].
@@ -1463,7 +1234,7 @@ extern "rust-intrinsic" {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+ #[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
#[rustc_diagnostic_item = "transmute"]
pub fn transmute<T, U>(e: T) -> U;
@@ -1518,6 +1289,17 @@ extern "rust-intrinsic" {
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
+ /// Masks out bits of the pointer according to a mask.
+ ///
+ /// Note that, unlike most intrinsics, this is safe to call;
+ /// it does not require an `unsafe` block.
+ /// Therefore, implementations must not require the user to uphold
+ /// any safety invariants.
+ ///
+ /// Consider using [`pointer::mask`] instead.
+ #[cfg(not(bootstrap))]
+ pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
+
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
/// a size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
@@ -2223,29 +2005,32 @@ extern "rust-intrinsic" {
pub fn nontemporal_store<T>(ptr: *mut T, val: T);
/// See documentation of `<*const T>::offset_from` for details.
- #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
+ #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")]
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
/// See documentation of `<*const T>::sub_ptr` for details.
- #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
+ #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
pub fn ptr_offset_from_unsigned<T>(ptr: *const T, base: *const T) -> usize;
/// See documentation of `<*const T>::guaranteed_eq` for details.
+ /// Returns `2` if the result is unknown.
+ /// Returns `1` if the pointers are guaranteed equal
+ /// Returns `0` if the pointers are guaranteed inequal
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
+ #[cfg(not(bootstrap))]
+ pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8;
+
+ #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
+ #[cfg(bootstrap)]
pub fn ptr_guaranteed_eq<T>(ptr: *const T, other: *const T) -> bool;
- /// See documentation of `<*const T>::guaranteed_ne` for details.
- ///
- /// Note that, unlike most intrinsics, this is safe to call;
- /// it does not require an `unsafe` block.
- /// Therefore, implementations must not require the user to uphold
- /// any safety invariants.
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
+ #[cfg(bootstrap)]
pub fn ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;
/// Allocates a block of memory at compile time.
@@ -2282,7 +2067,8 @@ extern "rust-intrinsic" {
///
/// # Safety
///
- /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
+ /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized or carry a
+ /// pointer value.
/// Note that this is a stricter criterion than just the *values* being
/// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
///
@@ -2299,13 +2085,70 @@ extern "rust-intrinsic" {
/// `ptr` must point to a vtable.
/// The intrinsic will return the size stored in that vtable.
- #[cfg(not(bootstrap))]
pub fn vtable_size(ptr: *const ()) -> usize;
/// `ptr` must point to a vtable.
/// The intrinsic will return the alignment stored in that vtable.
- #[cfg(not(bootstrap))]
pub fn vtable_align(ptr: *const ()) -> usize;
+
+ /// Selects which function to call depending on the context.
+ ///
+ /// If this function is evaluated at compile-time, then a call to this
+ /// intrinsic will be replaced with a call to `called_in_const`. It gets
+ /// replaced with a call to `called_at_rt` otherwise.
+ ///
+ /// # Type Requirements
+ ///
+ /// The two functions must be both function items. They cannot be function
+ /// pointers or closures. The first function must be a `const fn`.
+ ///
+ /// `arg` will be the tupled arguments that will be passed to either one of
+ /// the two functions, therefore, both functions must accept the same type of
+ /// arguments. Both functions must return RET.
+ ///
+ /// # Safety
+ ///
+ /// The two functions must behave observably equivalent. Safe code in other
+ /// crates may assume that calling a `const fn` at compile-time and at run-time
+ /// produces the same result. A function that produces a different result when
+ /// evaluated at run-time, or has any other observable side-effects, is
+ /// *unsound*.
+ ///
+ /// Here is an example of how this could cause a problem:
+ /// ```no_run
+ /// #![feature(const_eval_select)]
+ /// #![feature(core_intrinsics)]
+ /// use std::hint::unreachable_unchecked;
+ /// use std::intrinsics::const_eval_select;
+ ///
+ /// // Crate A
+ /// pub const fn inconsistent() -> i32 {
+ /// fn runtime() -> i32 { 1 }
+ /// const fn compiletime() -> i32 { 2 }
+ ///
+ /// unsafe {
+ // // âš  This code violates the required equivalence of `compiletime`
+ /// // and `runtime`.
+ /// const_eval_select((), compiletime, runtime)
+ /// }
+ /// }
+ ///
+ /// // Crate B
+ /// const X: i32 = inconsistent();
+ /// let x = inconsistent();
+ /// if x != X { unsafe { unreachable_unchecked(); }}
+ /// ```
+ ///
+ /// This code causes Undefined Behavior when being run, since the
+ /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
+ /// which violates the principle that a `const fn` must behave the same at
+ /// compile-time and at run-time. The unsafe code in crate B is fine.
+ #[cfg(not(bootstrap))]
+ #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
+ pub fn const_eval_select<ARG, F, G, RET>(arg: ARG, called_in_const: F, called_at_rt: G) -> RET
+ where
+ G: FnOnce<ARG, Output = RET>,
+ F: FnOnce<ARG, Output = RET>;
}
// Some functions are defined here because they accidentally got made
@@ -2316,6 +2159,11 @@ extern "rust-intrinsic" {
/// Check that the preconditions of an unsafe function are followed, if debug_assertions are on,
/// and only at runtime.
///
+/// This macro should be called as `assert_unsafe_precondition!([Generics](name: Type) => Expression)`
+/// where the names specified will be moved into the macro as captured variables, and defines an item
+/// to call `const_eval_select` on. The tokens inside the square brackets are used to denote generics
+/// for the function declaractions and can be omitted if there is no generics.
+///
/// # Safety
///
/// Invoking this macro is only sound if the following code is already UB when the passed
@@ -2330,18 +2178,21 @@ extern "rust-intrinsic" {
/// the occasional mistake, and this check should help them figure things out.
#[allow_internal_unstable(const_eval_select)] // permit this to be called in stably-const fn
macro_rules! assert_unsafe_precondition {
- ($e:expr) => {
+ ($([$($tt:tt)*])?($($i:ident:$ty:ty),*$(,)?) => $e:expr) => {
if cfg!(debug_assertions) {
- // Use a closure so that we can capture arbitrary expressions from the invocation
- let runtime = || {
+ // allow non_snake_case to allow capturing const generics
+ #[allow(non_snake_case)]
+ #[inline(always)]
+ fn runtime$(<$($tt)*>)?($($i:$ty),*) {
if !$e {
// abort instead of panicking to reduce impact on code size
::core::intrinsics::abort();
}
- };
- const fn comptime() {}
+ }
+ #[allow(non_snake_case)]
+ const fn comptime$(<$($tt)*>)?($(_:$ty),*) {}
- ::core::intrinsics::const_eval_select((), comptime, runtime);
+ ::core::intrinsics::const_eval_select(($($i,)*), comptime, runtime);
}
};
}
@@ -2350,7 +2201,7 @@ pub(crate) use assert_unsafe_precondition;
/// Checks whether `ptr` is properly aligned with respect to
/// `align_of::<T>()`.
pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
- !ptr.is_null() && ptr.addr() % mem::align_of::<T>() == 0
+ !ptr.is_null() && ptr.is_aligned()
}
/// Checks whether the regions of memory starting at `src` and `dst` of size
@@ -2365,6 +2216,16 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
diff >= size
}
+#[cfg(bootstrap)]
+pub const fn ptr_guaranteed_cmp(a: *const (), b: *const ()) -> u8 {
+ match (ptr_guaranteed_eq(a, b), ptr_guaranteed_ne(a, b)) {
+ (false, false) => 2,
+ (true, false) => 1,
+ (false, true) => 0,
+ (true, true) => unreachable!(),
+ }
+}
+
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
/// and destination must *not* overlap.
///
@@ -2420,9 +2281,9 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
/// dst.reserve(src_len);
///
/// unsafe {
-/// // The call to offset is always safe because `Vec` will never
+/// // The call to add is always safe because `Vec` will never
/// // allocate more than `isize::MAX` bytes.
-/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
+/// let dst_ptr = dst.as_mut_ptr().add(dst_len);
/// let src_ptr = src.as_ptr();
///
/// // Truncate `src` without dropping its contents. We do this first,
@@ -2451,7 +2312,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
#[doc(alias = "memcpy")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -2464,7 +2325,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
// SAFETY: the safety contract for `copy_nonoverlapping` must be
// upheld by the caller.
unsafe {
- assert_unsafe_precondition!(
+ assert_unsafe_precondition!([T](src: *const T, dst: *mut T, count: usize) =>
is_aligned_and_not_null(src)
&& is_aligned_and_not_null(dst)
&& is_nonoverlapping(src, dst, count)
@@ -2538,7 +2399,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
/// ```
#[doc(alias = "memmove")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -2550,7 +2411,8 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
// SAFETY: the safety contract for `copy` must be upheld by the caller.
unsafe {
- assert_unsafe_precondition!(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst));
+ assert_unsafe_precondition!([T](src: *const T, dst: *mut T) =>
+ is_aligned_and_not_null(src) && is_aligned_and_not_null(dst));
copy(src, dst, count)
}
}
@@ -2606,7 +2468,7 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
/// ```
#[doc(alias = "memset")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -2618,63 +2480,12 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
// SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
unsafe {
- assert_unsafe_precondition!(is_aligned_and_not_null(dst));
+ assert_unsafe_precondition!([T](dst: *mut T) => is_aligned_and_not_null(dst));
write_bytes(dst, val, count)
}
}
-/// Selects which function to call depending on the context.
-///
-/// If this function is evaluated at compile-time, then a call to this
-/// intrinsic will be replaced with a call to `called_in_const`. It gets
-/// replaced with a call to `called_at_rt` otherwise.
-///
-/// # Type Requirements
-///
-/// The two functions must be both function items. They cannot be function
-/// pointers or closures.
-///
-/// `arg` will be the arguments that will be passed to either one of the
-/// two functions, therefore, both functions must accept the same type of
-/// arguments. Both functions must return RET.
-///
-/// # Safety
-///
-/// The two functions must behave observably equivalent. Safe code in other
-/// crates may assume that calling a `const fn` at compile-time and at run-time
-/// produces the same result. A function that produces a different result when
-/// evaluated at run-time, or has any other observable side-effects, is
-/// *unsound*.
-///
-/// Here is an example of how this could cause a problem:
-/// ```no_run
-/// #![feature(const_eval_select)]
-/// #![feature(core_intrinsics)]
-/// use std::hint::unreachable_unchecked;
-/// use std::intrinsics::const_eval_select;
-///
-/// // Crate A
-/// pub const fn inconsistent() -> i32 {
-/// fn runtime() -> i32 { 1 }
-/// const fn compiletime() -> i32 { 2 }
-///
-/// unsafe {
-// // âš  This code violates the required equivalence of `compiletime`
-/// // and `runtime`.
-/// const_eval_select((), compiletime, runtime)
-/// }
-/// }
-///
-/// // Crate B
-/// const X: i32 = inconsistent();
-/// let x = inconsistent();
-/// if x != X { unsafe { unreachable_unchecked(); }}
-/// ```
-///
-/// This code causes Undefined Behavior when being run, since the
-/// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
-/// which violates the principle that a `const fn` must behave the same at
-/// compile-time and at run-time. The unsafe code in crate B is fine.
+#[cfg(bootstrap)]
#[unstable(
feature = "const_eval_select",
issue = "none",
@@ -2696,6 +2507,7 @@ where
called_at_rt.call_once(arg)
}
+#[cfg(bootstrap)]
#[unstable(
feature = "const_eval_select",
issue = "none",
diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs
new file mode 100644
index 000000000..9b479a9f8
--- /dev/null
+++ b/library/core/src/iter/adapters/array_chunks.rs
@@ -0,0 +1,182 @@
+use crate::array;
+use crate::iter::{ByRefSized, FusedIterator, Iterator};
+use crate::ops::{ControlFlow, NeverShortCircuit, Try};
+
+/// An iterator over `N` elements of the iterator at a time.
+///
+/// The chunks do not overlap. If `N` does not divide the length of the
+/// iterator, then the last up to `N-1` elements will be omitted.
+///
+/// This `struct` is created by the [`array_chunks`][Iterator::array_chunks]
+/// method on [`Iterator`]. See its documentation for more.
+#[derive(Debug, Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub struct ArrayChunks<I: Iterator, const N: usize> {
+ iter: I,
+ remainder: Option<array::IntoIter<I::Item, N>>,
+}
+
+impl<I, const N: usize> ArrayChunks<I, N>
+where
+ I: Iterator,
+{
+ #[track_caller]
+ pub(in crate::iter) fn new(iter: I) -> Self {
+ assert!(N != 0, "chunk size must be non-zero");
+ Self { iter, remainder: None }
+ }
+
+ /// Returns an iterator over the remaining elements of the original iterator
+ /// that are not going to be returned by this iterator. The returned
+ /// iterator will yield at most `N-1` elements.
+ #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+ #[inline]
+ pub fn into_remainder(self) -> Option<array::IntoIter<I::Item, N>> {
+ self.remainder
+ }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> Iterator for ArrayChunks<I, N>
+where
+ I: Iterator,
+{
+ type Item = [I::Item; N];
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.try_for_each(ControlFlow::Break).break_value()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (lower, upper) = self.iter.size_hint();
+
+ (lower / N, upper.map(|n| n / N))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count() / N
+ }
+
+ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
+ {
+ let mut acc = init;
+ loop {
+ match self.iter.next_chunk() {
+ Ok(chunk) => acc = f(acc, chunk)?,
+ Err(remainder) => {
+ // Make sure to not override `self.remainder` with an empty array
+ // when `next` is called after `ArrayChunks` exhaustion.
+ self.remainder.get_or_insert(remainder);
+
+ break try { acc };
+ }
+ }
+ }
+ }
+
+ fn fold<B, F>(mut self, init: B, f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
+ }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> DoubleEndedIterator for ArrayChunks<I, N>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.try_rfold((), |(), x| ControlFlow::Break(x)).break_value()
+ }
+
+ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
+ {
+ // We are iterating from the back we need to first handle the remainder.
+ self.next_back_remainder();
+
+ let mut acc = init;
+ let mut iter = ByRefSized(&mut self.iter).rev();
+
+ // NB remainder is handled by `next_back_remainder`, so
+ // `next_chunk` can't return `Err` with non-empty remainder
+ // (assuming correct `I as ExactSizeIterator` impl).
+ while let Ok(mut chunk) = iter.next_chunk() {
+ // FIXME: do not do double reverse
+ // (we could instead add `next_chunk_back` for example)
+ chunk.reverse();
+ acc = f(acc, chunk)?
+ }
+
+ try { acc }
+ }
+
+ fn rfold<B, F>(mut self, init: B, f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.try_rfold(init, NeverShortCircuit::wrap_mut_2(f)).0
+ }
+}
+
+impl<I, const N: usize> ArrayChunks<I, N>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ /// Updates `self.remainder` such that `self.iter.len` is divisible by `N`.
+ fn next_back_remainder(&mut self) {
+ // Make sure to not override `self.remainder` with an empty array
+ // when `next_back` is called after `ArrayChunks` exhaustion.
+ if self.remainder.is_some() {
+ return;
+ }
+
+ // We use the `ExactSizeIterator` implementation of the underlying
+ // iterator to know how many remaining elements there are.
+ let rem = self.iter.len() % N;
+
+ // Take the last `rem` elements out of `self.iter`.
+ let mut remainder =
+ // SAFETY: `unwrap_err` always succeeds because x % N < N for all x.
+ unsafe { self.iter.by_ref().rev().take(rem).next_chunk().unwrap_err_unchecked() };
+
+ // We used `.rev()` above, so we need to re-reverse the reminder
+ remainder.as_mut_slice().reverse();
+ self.remainder = Some(remainder);
+ }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> FusedIterator for ArrayChunks<I, N> where I: FusedIterator {}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> ExactSizeIterator for ArrayChunks<I, N>
+where
+ I: ExactSizeIterator,
+{
+ #[inline]
+ fn len(&self) -> usize {
+ self.iter.len() / N
+ }
+
+ #[inline]
+ fn is_empty(&self) -> bool {
+ self.iter.len() < N
+ }
+}
diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs
index cc1e8e8a2..477e7117c 100644
--- a/library/core/src/iter/adapters/by_ref_sized.rs
+++ b/library/core/src/iter/adapters/by_ref_sized.rs
@@ -1,4 +1,4 @@
-use crate::ops::Try;
+use crate::ops::{NeverShortCircuit, Try};
/// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics.
///
@@ -8,28 +8,31 @@ use crate::ops::Try;
#[derive(Debug)]
pub struct ByRefSized<'a, I>(pub &'a mut I);
+// The following implementations use UFCS-style, rather than trusting autoderef,
+// to avoid accidentally calling the `&mut Iterator` implementations.
+
#[unstable(feature = "std_internals", issue = "none")]
impl<I: Iterator> Iterator for ByRefSized<'_, I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
- self.0.next()
+ I::next(self.0)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
+ I::size_hint(self.0)
}
#[inline]
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
- self.0.advance_by(n)
+ I::advance_by(self.0, n)
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
- self.0.nth(n)
+ I::nth(self.0, n)
}
#[inline]
@@ -37,7 +40,8 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
where
F: FnMut(B, Self::Item) -> B,
{
- self.0.fold(init, f)
+ // `fold` needs ownership, so this can't forward directly.
+ I::try_fold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0
}
#[inline]
@@ -46,7 +50,7 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
{
- self.0.try_fold(init, f)
+ I::try_fold(self.0, init, f)
}
}
@@ -54,17 +58,17 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
- self.0.next_back()
+ I::next_back(self.0)
}
#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
- self.0.advance_back_by(n)
+ I::advance_back_by(self.0, n)
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- self.0.nth_back(n)
+ I::nth_back(self.0, n)
}
#[inline]
@@ -72,7 +76,8 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
where
F: FnMut(B, Self::Item) -> B,
{
- self.0.rfold(init, f)
+ // `rfold` needs ownership, so this can't forward directly.
+ I::try_rfold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0
}
#[inline]
@@ -81,6 +86,6 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
{
- self.0.try_rfold(init, f)
+ I::try_rfold(self.0, init, f)
}
}
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 15a120e35..307016c26 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -1,6 +1,6 @@
use crate::fmt;
use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
-use crate::ops::Try;
+use crate::ops::{ControlFlow, Try};
/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
@@ -73,6 +73,21 @@ where
{
self.inner.fold(init, fold)
}
+
+ #[inline]
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ self.inner.advance_by(n)
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.inner.count()
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ self.inner.last()
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -103,6 +118,11 @@ where
{
self.inner.rfold(init, fold)
}
+
+ #[inline]
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ self.inner.advance_back_by(n)
+ }
}
#[stable(feature = "fused", since = "1.26.0")]
@@ -214,6 +234,21 @@ where
{
self.inner.fold(init, fold)
}
+
+ #[inline]
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ self.inner.advance_by(n)
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.inner.count()
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ self.inner.last()
+ }
}
#[stable(feature = "iterator_flatten", since = "1.29.0")]
@@ -244,6 +279,11 @@ where
{
self.inner.rfold(init, fold)
}
+
+ #[inline]
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ self.inner.advance_back_by(n)
+ }
}
#[stable(feature = "iterator_flatten", since = "1.29.0")]
@@ -280,6 +320,144 @@ where
}
}
+impl<I, U> FlattenCompat<I, U>
+where
+ I: Iterator<Item: IntoIterator<IntoIter = U>>,
+{
+ /// Folds the inner iterators into an accumulator by applying an operation.
+ ///
+ /// Folds over the inner iterators, not over their elements. Is used by the `fold`, `count`,
+ /// and `last` methods.
+ #[inline]
+ fn iter_fold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, U) -> Acc,
+ {
+ #[inline]
+ fn flatten<T: IntoIterator, Acc>(
+ fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
+ ) -> impl FnMut(Acc, T) -> Acc + '_ {
+ move |acc, iter| fold(acc, iter.into_iter())
+ }
+
+ if let Some(iter) = self.frontiter {
+ acc = fold(acc, iter);
+ }
+
+ acc = self.iter.fold(acc, flatten(&mut fold));
+
+ if let Some(iter) = self.backiter {
+ acc = fold(acc, iter);
+ }
+
+ acc
+ }
+
+ /// Folds over the inner iterators as long as the given function returns successfully,
+ /// always storing the most recent inner iterator in `self.frontiter`.
+ ///
+ /// Folds over the inner iterators, not over their elements. Is used by the `try_fold` and
+ /// `advance_by` methods.
+ #[inline]
+ fn iter_try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
+ where
+ Fold: FnMut(Acc, &mut U) -> R,
+ R: Try<Output = Acc>,
+ {
+ #[inline]
+ fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
+ frontiter: &'a mut Option<T::IntoIter>,
+ fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
+ ) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, iter| fold(acc, frontiter.insert(iter.into_iter()))
+ }
+
+ if let Some(iter) = &mut self.frontiter {
+ acc = fold(acc, iter)?;
+ }
+ self.frontiter = None;
+
+ acc = self.iter.try_fold(acc, flatten(&mut self.frontiter, &mut fold))?;
+ self.frontiter = None;
+
+ if let Some(iter) = &mut self.backiter {
+ acc = fold(acc, iter)?;
+ }
+ self.backiter = None;
+
+ try { acc }
+ }
+}
+
+impl<I, U> FlattenCompat<I, U>
+where
+ I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U>>,
+{
+ /// Folds the inner iterators into an accumulator by applying an operation, starting form the
+ /// back.
+ ///
+ /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method.
+ #[inline]
+ fn iter_rfold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, U) -> Acc,
+ {
+ #[inline]
+ fn flatten<T: IntoIterator, Acc>(
+ fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
+ ) -> impl FnMut(Acc, T) -> Acc + '_ {
+ move |acc, iter| fold(acc, iter.into_iter())
+ }
+
+ if let Some(iter) = self.backiter {
+ acc = fold(acc, iter);
+ }
+
+ acc = self.iter.rfold(acc, flatten(&mut fold));
+
+ if let Some(iter) = self.frontiter {
+ acc = fold(acc, iter);
+ }
+
+ acc
+ }
+
+ /// Folds over the inner iterators in reverse order as long as the given function returns
+ /// successfully, always storing the most recent inner iterator in `self.backiter`.
+ ///
+ /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
+ /// `advance_back_by` methods.
+ #[inline]
+ fn iter_try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
+ where
+ Fold: FnMut(Acc, &mut U) -> R,
+ R: Try<Output = Acc>,
+ {
+ #[inline]
+ fn flatten<'a, T: IntoIterator, Acc, R: Try>(
+ backiter: &'a mut Option<T::IntoIter>,
+ fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
+ ) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, iter| fold(acc, backiter.insert(iter.into_iter()))
+ }
+
+ if let Some(iter) = &mut self.backiter {
+ acc = fold(acc, iter)?;
+ }
+ self.backiter = None;
+
+ acc = self.iter.try_rfold(acc, flatten(&mut self.backiter, &mut fold))?;
+ self.backiter = None;
+
+ if let Some(iter) = &mut self.frontiter {
+ acc = fold(acc, iter)?;
+ }
+ self.frontiter = None;
+
+ try { acc }
+ }
+}
+
impl<I, U> Iterator for FlattenCompat<I, U>
where
I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
@@ -323,99 +501,74 @@ where
}
#[inline]
- fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Output = Acc>,
{
#[inline]
- fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
- frontiter: &'a mut Option<T::IntoIter>,
- fold: &'a mut impl FnMut(Acc, T::Item) -> R,
- ) -> impl FnMut(Acc, T) -> R + 'a {
- move |acc, x| {
- let mut mid = x.into_iter();
- let r = mid.try_fold(acc, &mut *fold);
- *frontiter = Some(mid);
- r
- }
- }
-
- if let Some(ref mut front) = self.frontiter {
- init = front.try_fold(init, &mut fold)?;
+ fn flatten<U: Iterator, Acc, R: Try<Output = Acc>>(
+ mut fold: impl FnMut(Acc, U::Item) -> R,
+ ) -> impl FnMut(Acc, &mut U) -> R {
+ move |acc, iter| iter.try_fold(acc, &mut fold)
}
- self.frontiter = None;
- init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
- self.frontiter = None;
-
- if let Some(ref mut back) = self.backiter {
- init = back.try_fold(init, &mut fold)?;
- }
- self.backiter = None;
-
- try { init }
+ self.iter_try_fold(init, flatten(fold))
}
#[inline]
- fn fold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
+ fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
- fn flatten<T: IntoIterator, Acc>(
- fold: &mut impl FnMut(Acc, T::Item) -> Acc,
- ) -> impl FnMut(Acc, T) -> Acc + '_ {
- move |acc, x| x.into_iter().fold(acc, &mut *fold)
- }
-
- if let Some(front) = self.frontiter {
- init = front.fold(init, &mut fold);
- }
-
- init = self.iter.fold(init, flatten(&mut fold));
-
- if let Some(back) = self.backiter {
- init = back.fold(init, &mut fold);
+ fn flatten<U: Iterator, Acc>(
+ mut fold: impl FnMut(Acc, U::Item) -> Acc,
+ ) -> impl FnMut(Acc, U) -> Acc {
+ move |acc, iter| iter.fold(acc, &mut fold)
}
- init
+ self.iter_fold(init, flatten(fold))
}
#[inline]
#[rustc_inherit_overflow_checks]
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
- let mut rem = n;
- loop {
- if let Some(ref mut front) = self.frontiter {
- match front.advance_by(rem) {
- ret @ Ok(_) => return ret,
- Err(advanced) => rem -= advanced,
- }
- }
- self.frontiter = match self.iter.next() {
- Some(iterable) => Some(iterable.into_iter()),
- _ => break,
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
+ match iter.advance_by(n) {
+ Ok(()) => ControlFlow::BREAK,
+ Err(advanced) => ControlFlow::Continue(n - advanced),
}
}
- self.frontiter = None;
-
- if let Some(ref mut back) = self.backiter {
- match back.advance_by(rem) {
- ret @ Ok(_) => return ret,
- Err(advanced) => rem -= advanced,
- }
+ match self.iter_try_fold(n, advance) {
+ ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining),
+ _ => Ok(()),
}
+ }
- if rem > 0 {
- return Err(n - rem);
+ #[inline]
+ fn count(self) -> usize {
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn count<U: Iterator>(acc: usize, iter: U) -> usize {
+ acc + iter.count()
}
- self.backiter = None;
+ self.iter_fold(0, count)
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ #[inline]
+ fn last<U: Iterator>(last: Option<U::Item>, iter: U) -> Option<U::Item> {
+ iter.last().or(last)
+ }
- Ok(())
+ self.iter_fold(None, last)
}
}
@@ -438,105 +591,53 @@ where
}
#[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Output = Acc>,
{
#[inline]
- fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
- backiter: &'a mut Option<T::IntoIter>,
- fold: &'a mut impl FnMut(Acc, T::Item) -> R,
- ) -> impl FnMut(Acc, T) -> R + 'a
- where
- T::IntoIter: DoubleEndedIterator,
- {
- move |acc, x| {
- let mut mid = x.into_iter();
- let r = mid.try_rfold(acc, &mut *fold);
- *backiter = Some(mid);
- r
- }
+ fn flatten<U: DoubleEndedIterator, Acc, R: Try<Output = Acc>>(
+ mut fold: impl FnMut(Acc, U::Item) -> R,
+ ) -> impl FnMut(Acc, &mut U) -> R {
+ move |acc, iter| iter.try_rfold(acc, &mut fold)
}
- if let Some(ref mut back) = self.backiter {
- init = back.try_rfold(init, &mut fold)?;
- }
- self.backiter = None;
-
- init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
- self.backiter = None;
-
- if let Some(ref mut front) = self.frontiter {
- init = front.try_rfold(init, &mut fold)?;
- }
- self.frontiter = None;
-
- try { init }
+ self.iter_try_rfold(init, flatten(fold))
}
#[inline]
- fn rfold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
+ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
- fn flatten<T: IntoIterator, Acc>(
- fold: &mut impl FnMut(Acc, T::Item) -> Acc,
- ) -> impl FnMut(Acc, T) -> Acc + '_
- where
- T::IntoIter: DoubleEndedIterator,
- {
- move |acc, x| x.into_iter().rfold(acc, &mut *fold)
- }
-
- if let Some(back) = self.backiter {
- init = back.rfold(init, &mut fold);
+ fn flatten<U: DoubleEndedIterator, Acc>(
+ mut fold: impl FnMut(Acc, U::Item) -> Acc,
+ ) -> impl FnMut(Acc, U) -> Acc {
+ move |acc, iter| iter.rfold(acc, &mut fold)
}
- init = self.iter.rfold(init, flatten(&mut fold));
-
- if let Some(front) = self.frontiter {
- init = front.rfold(init, &mut fold);
- }
-
- init
+ self.iter_rfold(init, flatten(fold))
}
#[inline]
#[rustc_inherit_overflow_checks]
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
- let mut rem = n;
- loop {
- if let Some(ref mut back) = self.backiter {
- match back.advance_back_by(rem) {
- ret @ Ok(_) => return ret,
- Err(advanced) => rem -= advanced,
- }
- }
- match self.iter.next_back() {
- Some(iterable) => self.backiter = Some(iterable.into_iter()),
- _ => break,
- }
- }
-
- self.backiter = None;
-
- if let Some(ref mut front) = self.frontiter {
- match front.advance_back_by(rem) {
- ret @ Ok(_) => return ret,
- Err(advanced) => rem -= advanced,
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
+ match iter.advance_back_by(n) {
+ Ok(()) => ControlFlow::BREAK,
+ Err(advanced) => ControlFlow::Continue(n - advanced),
}
}
- if rem > 0 {
- return Err(n - rem);
+ match self.iter_try_rfold(n, advance) {
+ ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining),
+ _ => Ok(()),
}
-
- self.frontiter = None;
-
- Ok(())
}
}
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index 916a26e24..bf4fabad3 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -1,6 +1,7 @@
use crate::iter::{InPlaceIterable, Iterator};
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, NeverShortCircuit, Residual, Try};
+mod array_chunks;
mod by_ref_sized;
mod chain;
mod cloned;
@@ -32,6 +33,9 @@ pub use self::{
scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
};
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub use self::array_chunks::ArrayChunks;
+
#[unstable(feature = "std_internals", issue = "none")]
pub use self::by_ref_sized::ByRefSized;
diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs
index 2c283100f..dbf0ae9ec 100644
--- a/library/core/src/iter/adapters/skip.rs
+++ b/library/core/src/iter/adapters/skip.rs
@@ -33,21 +33,32 @@ where
#[inline]
fn next(&mut self) -> Option<I::Item> {
if unlikely(self.n > 0) {
- self.iter.nth(crate::mem::take(&mut self.n) - 1)?;
+ self.iter.nth(crate::mem::take(&mut self.n))
+ } else {
+ self.iter.next()
}
- self.iter.next()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
- // Can't just add n + self.n due to overflow.
if self.n > 0 {
- let to_skip = self.n;
- self.n = 0;
- // nth(n) skips n+1
- self.iter.nth(to_skip - 1)?;
+ let skip: usize = crate::mem::take(&mut self.n);
+ // Checked add to handle overflow case.
+ let n = match skip.checked_add(n) {
+ Some(nth) => nth,
+ None => {
+ // In case of overflow, load skip value, before loading `n`.
+ // Because the amount of elements to iterate is beyond `usize::MAX`, this
+ // is split into two `nth` calls where the `skip` `nth` call is discarded.
+ self.iter.nth(skip - 1)?;
+ n
+ }
+ };
+ // Load nth element including skip.
+ self.iter.nth(n)
+ } else {
+ self.iter.nth(n)
}
- self.iter.nth(n)
}
#[inline]
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index d5c6aed5b..9514466bd 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -398,6 +398,8 @@ pub use self::traits::{
#[stable(feature = "iter_zip", since = "1.59.0")]
pub use self::adapters::zip;
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub use self::adapters::ArrayChunks;
#[unstable(feature = "std_internals", issue = "none")]
pub use self::adapters::ByRefSized;
#[stable(feature = "iter_cloned", since = "1.1.0")]
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 275412b57..b2d08f4b0 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -5,7 +5,7 @@ use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
use super::super::try_process;
use super::super::ByRefSized;
use super::super::TrustedRandomAccessNoCoerce;
-use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
+use super::super::{ArrayChunks, Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
use super::super::{FlatMap, Flatten};
use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
use super::super::{
@@ -3316,6 +3316,49 @@ pub trait Iterator {
Cycle::new(self)
}
+ /// Returns an iterator over `N` elements of the iterator at a time.
+ ///
+ /// The chunks do not overlap. If `N` does not divide the length of the
+ /// iterator, then the last up to `N-1` elements will be omitted and can be
+ /// retrieved from the [`.into_remainder()`][ArrayChunks::into_remainder]
+ /// function of the iterator.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(iter_array_chunks)]
+ ///
+ /// let mut iter = "lorem".chars().array_chunks();
+ /// assert_eq!(iter.next(), Some(['l', 'o']));
+ /// assert_eq!(iter.next(), Some(['r', 'e']));
+ /// assert_eq!(iter.next(), None);
+ /// assert_eq!(iter.into_remainder().unwrap().as_slice(), &['m']);
+ /// ```
+ ///
+ /// ```
+ /// #![feature(iter_array_chunks)]
+ ///
+ /// let data = [1, 1, 2, -2, 6, 0, 3, 1];
+ /// // ^-----^ ^------^
+ /// for [x, y, z] in data.iter().array_chunks() {
+ /// assert_eq!(x + y + z, 4);
+ /// }
+ /// ```
+ #[track_caller]
+ #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+ fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
+ where
+ Self: Sized,
+ {
+ ArrayChunks::new(self)
+ }
+
/// Sums the elements of an iterator.
///
/// Takes each element, adds them together, and returns the result.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 24742bb49..5621d15c1 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -93,6 +93,7 @@
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![allow(explicit_outlives_requirements)]
+#![allow(incomplete_features)]
//
// Library features:
#![feature(const_align_offset)]
@@ -130,7 +131,6 @@
#![feature(const_replace)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_is_null)]
-#![feature(const_ptr_offset_from)]
#![feature(const_ptr_read)]
#![feature(const_ptr_write)]
#![feature(const_raw_ptr_comparison)]
@@ -143,12 +143,14 @@
#![feature(const_type_id)]
#![feature(const_type_name)]
#![feature(const_default_impls)]
+#![feature(const_unicode_case_lookup)]
#![feature(const_unsafecell_get_mut)]
#![feature(core_panic)]
#![feature(duration_consts_float)]
#![feature(maybe_uninit_uninit_array)]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
+#![feature(slice_split_at_unchecked)]
#![feature(str_internals)]
#![feature(utf16_extra)]
#![feature(utf16_extra_const)]
@@ -157,9 +159,11 @@
#![feature(const_slice_from_ref)]
#![feature(const_slice_index)]
#![feature(const_is_char_boundary)]
+#![feature(const_cstr_methods)]
//
// Language features:
#![feature(abi_unadjusted)]
+#![feature(adt_const_params)]
#![feature(allow_internal_unsafe)]
#![feature(allow_internal_unstable)]
#![feature(associated_type_bounds)]
@@ -302,6 +306,8 @@ pub mod clone;
pub mod cmp;
pub mod convert;
pub mod default;
+#[cfg(not(bootstrap))]
+pub mod error;
pub mod marker;
pub mod ops;
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 3a115a8b8..fd96e1ff7 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -350,10 +350,12 @@ macro_rules! matches {
/// Unwraps a result or propagates its error.
///
-/// The `?` operator was added to replace `try!` and should be used instead.
-/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use
-/// it, you will need to use the [raw-identifier syntax][ris]: `r#try`.
+/// The [`?` operator][propagating-errors] was added to replace `try!`
+/// and should be used instead. Furthermore, `try` is a reserved word
+/// in Rust 2018, so if you must use it, you will need to use the
+/// [raw-identifier syntax][ris]: `r#try`.
///
+/// [propagating-errors]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
/// [ris]: https://doc.rust-lang.org/nightly/rust-by-example/compatibility/raw_identifiers.html
///
/// `try!` matches the given [`Result`]. In case of the `Ok` variant, the
@@ -457,11 +459,12 @@ macro_rules! r#try {
///
/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
/// implementing either, as objects do not typically implement both. However, the module must
-/// import the traits qualified so their names do not conflict:
+/// avoid conflict between the trait names, such as by importing them as `_` or otherwise renaming
+/// them:
///
/// ```
-/// use std::fmt::Write as FmtWrite;
-/// use std::io::Write as IoWrite;
+/// use std::fmt::Write as _;
+/// use std::io::Write as _;
///
/// fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut s = String::new();
@@ -474,6 +477,23 @@ macro_rules! r#try {
/// }
/// ```
///
+/// If you also need the trait names themselves, such as to implement one or both on your types,
+/// import the containing module and then name them with a prefix:
+///
+/// ```
+/// # #![allow(unused_imports)]
+/// use std::fmt::{self, Write as _};
+/// use std::io::{self, Write as _};
+///
+/// struct Example;
+///
+/// impl fmt::Write for Example {
+/// fn write_str(&mut self, _s: &str) -> core::fmt::Result {
+/// unimplemented!();
+/// }
+/// }
+/// ```
+///
/// Note: This macro can be used in `no_std` setups as well.
/// In a `no_std` setup you are responsible for the implementation details of the components.
///
@@ -526,25 +546,6 @@ macro_rules! write {
/// Ok(())
/// }
/// ```
-///
-/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
-/// implementing either, as objects do not typically implement both. However, the module must
-/// import the traits qualified so their names do not conflict:
-///
-/// ```
-/// use std::fmt::Write as FmtWrite;
-/// use std::io::Write as IoWrite;
-///
-/// fn main() -> Result<(), Box<dyn std::error::Error>> {
-/// let mut s = String::new();
-/// let mut v = Vec::new();
-///
-/// writeln!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
-/// writeln!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
-/// assert_eq!(v, b"s = \"abc 123\\n\"\n");
-/// Ok(())
-/// }
-/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "writeln_macro")]
@@ -1015,7 +1016,7 @@ pub(crate) mod builtin {
/// Concatenates literals into a byte slice.
///
/// This macro takes any number of comma-separated literals, and concatenates them all into
- /// one, yielding an expression of type `&[u8, _]`, which represents all of the literals
+ /// one, yielding an expression of type `&[u8; _]`, which represents all of the literals
/// concatenated left-to-right. The literals passed can be any combination of:
///
/// - byte literals (`b'r'`)
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 2c5789795..b8239ed88 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -343,7 +343,7 @@ pub trait StructuralEq {
/// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get
/// the error [E0204].
///
-/// [E0204]: ../../error-index.html#E0204
+/// [E0204]: ../../error_codes/E0204.html
///
/// ## When *should* my type be `Copy`?
///
@@ -800,6 +800,15 @@ impl<T: ?Sized> Unpin for *mut T {}
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
pub trait Destruct {}
+/// A marker for tuple types.
+///
+/// The implementation of this trait is built-in and cannot be implemented
+/// for any user type.
+#[unstable(feature = "tuple_trait", issue = "none")]
+#[cfg_attr(not(bootstrap), lang = "tuple_trait")]
+#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
+pub trait Tuple {}
+
/// Implementations of `Copy` for primitive types.
///
/// Implementations that cannot be described in Rust
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index b4ea53608..2490c0767 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -54,9 +54,6 @@ use crate::slice;
/// // The equivalent code with `MaybeUninit<i32>`:
/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! âš ï¸
/// ```
-/// (Notice that the rules around uninitialized integers are not finalized yet, but
-/// until they are, it is advisable to avoid them.)
-///
/// On top of that, remember that most types have additional invariants beyond merely
/// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
/// is considered initialized (under the current implementation; this does not constitute
@@ -130,11 +127,8 @@ use crate::slice;
/// MaybeUninit::uninit().assume_init()
/// };
///
-/// // Dropping a `MaybeUninit` does nothing. Thus using raw pointer
-/// // assignment instead of `ptr::write` does not cause the old
-/// // uninitialized value to be dropped. Also if there is a panic during
-/// // this loop, we have a memory leak, but there is no memory safety
-/// // issue.
+/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
+/// // we have a memory leak, but there is no memory safety issue.
/// for elem in &mut data[..] {
/// elem.write(vec![42]);
/// }
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 20b2d5e26..d2dd2941d 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -665,14 +665,14 @@ pub unsafe fn zeroed<T>() -> T {
/// correctly: it has the same effect as [`MaybeUninit::uninit().assume_init()`][uninit].
/// As the [`assume_init` documentation][assume_init] explains,
/// [the Rust compiler assumes][inv] that values are properly initialized.
-/// As a consequence, calling e.g. `mem::uninitialized::<bool>()` causes immediate
-/// undefined behavior for returning a `bool` that is not definitely either `true`
-/// or `false`. Worse, truly uninitialized memory like what gets returned here
+///
+/// Truly uninitialized memory like what gets returned here
/// is special in that the compiler knows that it does not have a fixed value.
/// This makes it undefined behavior to have uninitialized data in a variable even
/// if that variable has an integer type.
-/// (Notice that the rules around uninitialized integers are not finalized yet, but
-/// until they are, it is advisable to avoid them.)
+///
+/// Therefore, it is immediate undefined behavior to call this function on nearly all types,
+/// including integer types and arrays of integer types, and even if the result is unused.
///
/// [uninit]: MaybeUninit::uninit
/// [assume_init]: MaybeUninit::assume_init
diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs
index b59a5b89d..87a378631 100644
--- a/library/core/src/mem/transmutability.rs
+++ b/library/core/src/mem/transmutability.rs
@@ -9,20 +9,15 @@
message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
)]
-pub unsafe trait BikeshedIntrinsicFrom<
- Src,
- Context,
- const ASSUME_ALIGNMENT: bool,
- const ASSUME_LIFETIMES: bool,
- const ASSUME_VALIDITY: bool,
- const ASSUME_VISIBILITY: bool,
-> where
+pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
+where
Src: ?Sized,
{
}
/// What transmutation safety conditions shall the compiler assume that *you* are checking?
#[unstable(feature = "transmutability", issue = "99571")]
+#[cfg_attr(not(bootstrap), lang = "transmute_opts")]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Assume {
/// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that
@@ -33,11 +28,80 @@ pub struct Assume {
/// that violates Rust's memory model.
pub lifetimes: bool,
+ /// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
+ /// type and field privacy of the destination type (and sometimes of the source type, too).
+ pub safety: bool,
+
/// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid
/// instance of the destination type.
pub validity: bool,
+}
- /// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
- /// type and field privacy of the destination type (and sometimes of the source type, too).
- pub visibility: bool,
+impl Assume {
+ /// Do not assume that *you* have ensured any safety properties are met.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const NOTHING: Self =
+ Self { alignment: false, lifetimes: false, safety: false, validity: false };
+
+ /// Assume only that alignment conditions are met.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING };
+
+ /// Assume only that lifetime conditions are met.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING };
+
+ /// Assume only that safety conditions are met.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING };
+
+ /// Assume only that dynamically-satisfiable validity conditions are met.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING };
+
+ /// Assume both `self` and `other_assumptions`.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const fn and(self, other_assumptions: Self) -> Self {
+ Self {
+ alignment: self.alignment || other_assumptions.alignment,
+ lifetimes: self.lifetimes || other_assumptions.lifetimes,
+ safety: self.safety || other_assumptions.safety,
+ validity: self.validity || other_assumptions.validity,
+ }
+ }
+
+ /// Assume `self`, excepting `other_assumptions`.
+ #[unstable(feature = "transmutability", issue = "99571")]
+ pub const fn but_not(self, other_assumptions: Self) -> Self {
+ Self {
+ alignment: self.alignment && !other_assumptions.alignment,
+ lifetimes: self.lifetimes && !other_assumptions.lifetimes,
+ safety: self.safety && !other_assumptions.safety,
+ validity: self.validity && !other_assumptions.validity,
+ }
+ }
+}
+
+// FIXME(jswrenn): This const op is not actually usable. Why?
+// https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
+#[unstable(feature = "transmutability", issue = "99571")]
+#[rustc_const_unstable(feature = "transmutability", issue = "99571")]
+impl const core::ops::Add for Assume {
+ type Output = Assume;
+
+ fn add(self, other_assumptions: Assume) -> Assume {
+ self.and(other_assumptions)
+ }
+}
+
+// FIXME(jswrenn): This const op is not actually usable. Why?
+// https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
+#[unstable(feature = "transmutability", issue = "99571")]
+#[rustc_const_unstable(feature = "transmutability", issue = "99571")]
+impl const core::ops::Sub for Assume {
+ type Output = Assume;
+
+ fn sub(self, other_assumptions: Assume) -> Assume {
+ self.but_not(other_assumptions)
+ }
}
diff --git a/library/core/src/mem/valid_align.rs b/library/core/src/mem/valid_align.rs
index fcfa95120..32b2afb72 100644
--- a/library/core/src/mem/valid_align.rs
+++ b/library/core/src/mem/valid_align.rs
@@ -1,4 +1,5 @@
use crate::convert::TryFrom;
+use crate::intrinsics::assert_unsafe_precondition;
use crate::num::NonZeroUsize;
use crate::{cmp, fmt, hash, mem, num};
@@ -26,7 +27,8 @@ impl ValidAlign {
/// It must *not* be zero.
#[inline]
pub(crate) const unsafe fn new_unchecked(align: usize) -> Self {
- debug_assert!(align.is_power_of_two());
+ // SAFETY: Precondition passed to the caller.
+ unsafe { assert_unsafe_precondition!((align: usize) => align.is_power_of_two()) };
// SAFETY: By precondition, this must be a power of two, and
// our variants encompass all possible powers of two.
@@ -34,9 +36,14 @@ impl ValidAlign {
}
#[inline]
+ pub(crate) const fn as_usize(self) -> usize {
+ self.0 as usize
+ }
+
+ #[inline]
pub(crate) const fn as_nonzero(self) -> NonZeroUsize {
// SAFETY: All the discriminants are non-zero.
- unsafe { NonZeroUsize::new_unchecked(self.0 as usize) }
+ unsafe { NonZeroUsize::new_unchecked(self.as_usize()) }
}
/// Returns the base 2 logarithm of the alignment.
@@ -46,6 +53,13 @@ impl ValidAlign {
pub(crate) fn log2(self) -> u32 {
self.as_nonzero().trailing_zeros()
}
+
+ /// Returns the alignment for a type.
+ #[inline]
+ pub(crate) fn of<T>() -> Self {
+ // SAFETY: rustc ensures that type alignment is always a power of two.
+ unsafe { ValidAlign::new_unchecked(mem::align_of::<T>()) }
+ }
}
impl fmt::Debug for ValidAlign {
diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs
index de85fdd6e..d2a21b6b3 100644
--- a/library/core/src/num/bignum.rs
+++ b/library/core/src/num/bignum.rs
@@ -137,7 +137,7 @@ macro_rules! define_bignum {
// Find the most significant non-zero digit.
let msd = digits.iter().rposition(|&x| x != 0);
match msd {
- Some(msd) => msd * digitbits + digits[msd].log2() as usize + 1,
+ Some(msd) => msd * digitbits + digits[msd].ilog2() as usize + 1,
// There are no non-zero digits, i.e., the number is zero.
_ => 0,
}
diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs
index f8edc3625..2019f71e6 100644
--- a/library/core/src/num/dec2flt/decimal.rs
+++ b/library/core/src/num/dec2flt/decimal.rs
@@ -32,7 +32,7 @@ impl Default for Decimal {
impl Decimal {
/// The maximum number of digits required to unambiguously round a float.
///
- /// For a double-precision IEEE-754 float, this required 767 digits,
+ /// For a double-precision IEEE 754 float, this required 767 digits,
/// so we store the max digits + 1.
///
/// We can exactly represent a float in radix `b` from radix 2 if
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
index 1a223016d..1f6b40e5d 100644
--- a/library/core/src/num/error.rs
+++ b/library/core/src/num/error.rs
@@ -1,6 +1,8 @@
//! Error types for conversion to integral types.
use crate::convert::Infallible;
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
/// The error type returned when a checked integral type conversion fails.
@@ -144,3 +146,21 @@ impl fmt::Display for ParseIntError {
self.__description().fmt(f)
}
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for ParseIntError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ self.__description()
+ }
+}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "try_from", since = "1.34.0")]
+impl Error for TryFromIntError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ self.__description()
+ }
+}
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 6548ad2e5..2c6a0ba64 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f32` single-precision floating point type.
+//! Constants for the `f32` single-precision floating point type.
//!
//! *[See also the `f32` primitive type][f32].*
//!
@@ -394,7 +394,7 @@ impl f32 {
/// Not a Number (NaN).
///
- /// Note that IEEE-745 doesn't define just a single NaN value;
+ /// Note that IEEE 754 doesn't define just a single NaN value;
/// a plethora of bit patterns are considered to be NaN.
/// Furthermore, the standard makes a difference
/// between a "signaling" and a "quiet" NaN,
@@ -632,7 +632,7 @@ impl f32 {
}
/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
- /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any
+ /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
@@ -654,7 +654,7 @@ impl f32 {
}
/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
- /// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any
+ /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
@@ -678,6 +678,106 @@ impl f32 {
unsafe { mem::transmute::<f32, u32>(self) & 0x8000_0000 != 0 }
}
+ /// Returns the least number greater than `self`.
+ ///
+ /// Let `TINY` be the smallest representable positive `f32`. Then,
+ /// - if `self.is_nan()`, this returns `self`;
+ /// - if `self` is [`NEG_INFINITY`], this returns [`MIN`];
+ /// - if `self` is `-TINY`, this returns -0.0;
+ /// - if `self` is -0.0 or +0.0, this returns `TINY`;
+ /// - if `self` is [`MAX`] or [`INFINITY`], this returns [`INFINITY`];
+ /// - otherwise the unique least value greater than `self` is returned.
+ ///
+ /// The identity `x.next_up() == -(-x).next_down()` holds for all non-NaN `x`. When `x`
+ /// is finite `x == x.next_up().next_down()` also holds.
+ ///
+ /// ```rust
+ /// #![feature(float_next_up_down)]
+ /// // f32::EPSILON is the difference between 1.0 and the next number up.
+ /// assert_eq!(1.0f32.next_up(), 1.0 + f32::EPSILON);
+ /// // But not for most numbers.
+ /// assert!(0.1f32.next_up() < 0.1 + f32::EPSILON);
+ /// assert_eq!(16777216f32.next_up(), 16777218.0);
+ /// ```
+ ///
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
+ /// [`INFINITY`]: Self::INFINITY
+ /// [`MIN`]: Self::MIN
+ /// [`MAX`]: Self::MAX
+ #[unstable(feature = "float_next_up_down", issue = "91399")]
+ #[rustc_const_unstable(feature = "float_next_up_down", issue = "91399")]
+ pub const fn next_up(self) -> Self {
+ // We must use strictly integer arithmetic to prevent denormals from
+ // flushing to zero after an arithmetic operation on some platforms.
+ const TINY_BITS: u32 = 0x1; // Smallest positive f32.
+ const CLEAR_SIGN_MASK: u32 = 0x7fff_ffff;
+
+ let bits = self.to_bits();
+ if self.is_nan() || bits == Self::INFINITY.to_bits() {
+ return self;
+ }
+
+ let abs = bits & CLEAR_SIGN_MASK;
+ let next_bits = if abs == 0 {
+ TINY_BITS
+ } else if bits == abs {
+ bits + 1
+ } else {
+ bits - 1
+ };
+ Self::from_bits(next_bits)
+ }
+
+ /// Returns the greatest number less than `self`.
+ ///
+ /// Let `TINY` be the smallest representable positive `f32`. Then,
+ /// - if `self.is_nan()`, this returns `self`;
+ /// - if `self` is [`INFINITY`], this returns [`MAX`];
+ /// - if `self` is `TINY`, this returns 0.0;
+ /// - if `self` is -0.0 or +0.0, this returns `-TINY`;
+ /// - if `self` is [`MIN`] or [`NEG_INFINITY`], this returns [`NEG_INFINITY`];
+ /// - otherwise the unique greatest value less than `self` is returned.
+ ///
+ /// The identity `x.next_down() == -(-x).next_up()` holds for all non-NaN `x`. When `x`
+ /// is finite `x == x.next_down().next_up()` also holds.
+ ///
+ /// ```rust
+ /// #![feature(float_next_up_down)]
+ /// let x = 1.0f32;
+ /// // Clamp value into range [0, 1).
+ /// let clamped = x.clamp(0.0, 1.0f32.next_down());
+ /// assert!(clamped < 1.0);
+ /// assert_eq!(clamped.next_up(), 1.0);
+ /// ```
+ ///
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
+ /// [`INFINITY`]: Self::INFINITY
+ /// [`MIN`]: Self::MIN
+ /// [`MAX`]: Self::MAX
+ #[unstable(feature = "float_next_up_down", issue = "91399")]
+ #[rustc_const_unstable(feature = "float_next_up_down", issue = "91399")]
+ pub const fn next_down(self) -> Self {
+ // We must use strictly integer arithmetic to prevent denormals from
+ // flushing to zero after an arithmetic operation on some platforms.
+ const NEG_TINY_BITS: u32 = 0x8000_0001; // Smallest (in magnitude) negative f32.
+ const CLEAR_SIGN_MASK: u32 = 0x7fff_ffff;
+
+ let bits = self.to_bits();
+ if self.is_nan() || bits == Self::NEG_INFINITY.to_bits() {
+ return self;
+ }
+
+ let abs = bits & CLEAR_SIGN_MASK;
+ let next_bits = if abs == 0 {
+ NEG_TINY_BITS
+ } else if bits == abs {
+ bits - 1
+ } else {
+ bits + 1
+ };
+ Self::from_bits(next_bits)
+ }
+
/// Takes the reciprocal (inverse) of a number, `1/x`.
///
/// ```
@@ -733,7 +833,7 @@ impl f32 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
- /// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
+ /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
/// This also matches the behavior of libm’s fmax.
///
@@ -753,7 +853,7 @@ impl f32 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
- /// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
+ /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
/// This also matches the behavior of libm’s fmin.
///
@@ -933,10 +1033,14 @@ impl f32 {
}
}
}
- // SAFETY: `u32` is a plain old datatype so we can always... uh...
- // ...look, just pretend you forgot what you just read.
- // Stability concerns.
- let rt_f32_to_u32 = |rt| unsafe { mem::transmute::<f32, u32>(rt) };
+
+ #[inline(always)] // See https://github.com/rust-lang/compiler-builtins/issues/491
+ fn rt_f32_to_u32(x: f32) -> u32 {
+ // SAFETY: `u32` is a plain old datatype so we can always... uh...
+ // ...look, just pretend you forgot what you just read.
+ // Stability concerns.
+ unsafe { mem::transmute(x) }
+ }
// SAFETY: We use internal implementations that either always work or fail at compile time.
unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
}
@@ -947,9 +1051,9 @@ impl f32 {
/// It turns out this is incredibly portable, for two reasons:
///
/// * Floats and Ints have the same endianness on all supported platforms.
- /// * IEEE-754 very precisely specifies the bit layout of floats.
+ /// * IEEE 754 very precisely specifies the bit layout of floats.
///
- /// However there is one caveat: prior to the 2008 version of IEEE-754, how
+ /// However there is one caveat: prior to the 2008 version of IEEE 754, how
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
/// (notably x86 and ARM) picked the interpretation that was ultimately
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
@@ -1021,10 +1125,14 @@ impl f32 {
}
}
}
- // SAFETY: `u32` is a plain old datatype so we can always... uh...
- // ...look, just pretend you forgot what you just read.
- // Stability concerns.
- let rt_u32_to_f32 = |rt| unsafe { mem::transmute::<u32, f32>(rt) };
+
+ #[inline(always)] // See https://github.com/rust-lang/compiler-builtins/issues/491
+ fn rt_u32_to_f32(x: u32) -> f32 {
+ // SAFETY: `u32` is a plain old datatype so we can always... uh...
+ // ...look, just pretend you forgot what you just read.
+ // Stability concerns.
+ unsafe { mem::transmute(x) }
+ }
// SAFETY: We use internal implementations that either always work or fail at compile time.
unsafe { intrinsics::const_eval_select((v,), ct_u32_to_f32, rt_u32_to_f32) }
}
@@ -1282,15 +1390,14 @@ impl f32 {
#[must_use = "method returns a new number and does not mutate the original value"]
#[stable(feature = "clamp", since = "1.50.0")]
#[inline]
- pub fn clamp(self, min: f32, max: f32) -> f32 {
+ pub fn clamp(mut self, min: f32, max: f32) -> f32 {
assert!(min <= max);
- let mut x = self;
- if x < min {
- x = min;
+ if self < min {
+ self = min;
}
- if x > max {
- x = max;
+ if self > max {
+ self = max;
}
- x
+ self
}
}
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 75c92c2f8..fd3c18ce2 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f64` double-precision floating point type.
+//! Constants for the `f64` double-precision floating point type.
//!
//! *[See also the `f64` primitive type][f64].*
//!
@@ -393,7 +393,7 @@ impl f64 {
/// Not a Number (NaN).
///
- /// Note that IEEE-745 doesn't define just a single NaN value;
+ /// Note that IEEE 754 doesn't define just a single NaN value;
/// a plethora of bit patterns are considered to be NaN.
/// Furthermore, the standard makes a difference
/// between a "signaling" and a "quiet" NaN,
@@ -624,7 +624,7 @@ impl f64 {
}
/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
- /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any
+ /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
@@ -655,7 +655,7 @@ impl f64 {
}
/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
- /// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any
+ /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
@@ -688,6 +688,106 @@ impl f64 {
self.is_sign_negative()
}
+ /// Returns the least number greater than `self`.
+ ///
+ /// Let `TINY` be the smallest representable positive `f64`. Then,
+ /// - if `self.is_nan()`, this returns `self`;
+ /// - if `self` is [`NEG_INFINITY`], this returns [`MIN`];
+ /// - if `self` is `-TINY`, this returns -0.0;
+ /// - if `self` is -0.0 or +0.0, this returns `TINY`;
+ /// - if `self` is [`MAX`] or [`INFINITY`], this returns [`INFINITY`];
+ /// - otherwise the unique least value greater than `self` is returned.
+ ///
+ /// The identity `x.next_up() == -(-x).next_down()` holds for all non-NaN `x`. When `x`
+ /// is finite `x == x.next_up().next_down()` also holds.
+ ///
+ /// ```rust
+ /// #![feature(float_next_up_down)]
+ /// // f64::EPSILON is the difference between 1.0 and the next number up.
+ /// assert_eq!(1.0f64.next_up(), 1.0 + f64::EPSILON);
+ /// // But not for most numbers.
+ /// assert!(0.1f64.next_up() < 0.1 + f64::EPSILON);
+ /// assert_eq!(9007199254740992f64.next_up(), 9007199254740994.0);
+ /// ```
+ ///
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
+ /// [`INFINITY`]: Self::INFINITY
+ /// [`MIN`]: Self::MIN
+ /// [`MAX`]: Self::MAX
+ #[unstable(feature = "float_next_up_down", issue = "91399")]
+ #[rustc_const_unstable(feature = "float_next_up_down", issue = "91399")]
+ pub const fn next_up(self) -> Self {
+ // We must use strictly integer arithmetic to prevent denormals from
+ // flushing to zero after an arithmetic operation on some platforms.
+ const TINY_BITS: u64 = 0x1; // Smallest positive f64.
+ const CLEAR_SIGN_MASK: u64 = 0x7fff_ffff_ffff_ffff;
+
+ let bits = self.to_bits();
+ if self.is_nan() || bits == Self::INFINITY.to_bits() {
+ return self;
+ }
+
+ let abs = bits & CLEAR_SIGN_MASK;
+ let next_bits = if abs == 0 {
+ TINY_BITS
+ } else if bits == abs {
+ bits + 1
+ } else {
+ bits - 1
+ };
+ Self::from_bits(next_bits)
+ }
+
+ /// Returns the greatest number less than `self`.
+ ///
+ /// Let `TINY` be the smallest representable positive `f64`. Then,
+ /// - if `self.is_nan()`, this returns `self`;
+ /// - if `self` is [`INFINITY`], this returns [`MAX`];
+ /// - if `self` is `TINY`, this returns 0.0;
+ /// - if `self` is -0.0 or +0.0, this returns `-TINY`;
+ /// - if `self` is [`MIN`] or [`NEG_INFINITY`], this returns [`NEG_INFINITY`];
+ /// - otherwise the unique greatest value less than `self` is returned.
+ ///
+ /// The identity `x.next_down() == -(-x).next_up()` holds for all non-NaN `x`. When `x`
+ /// is finite `x == x.next_down().next_up()` also holds.
+ ///
+ /// ```rust
+ /// #![feature(float_next_up_down)]
+ /// let x = 1.0f64;
+ /// // Clamp value into range [0, 1).
+ /// let clamped = x.clamp(0.0, 1.0f64.next_down());
+ /// assert!(clamped < 1.0);
+ /// assert_eq!(clamped.next_up(), 1.0);
+ /// ```
+ ///
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
+ /// [`INFINITY`]: Self::INFINITY
+ /// [`MIN`]: Self::MIN
+ /// [`MAX`]: Self::MAX
+ #[unstable(feature = "float_next_up_down", issue = "91399")]
+ #[rustc_const_unstable(feature = "float_next_up_down", issue = "91399")]
+ pub const fn next_down(self) -> Self {
+ // We must use strictly integer arithmetic to prevent denormals from
+ // flushing to zero after an arithmetic operation on some platforms.
+ const NEG_TINY_BITS: u64 = 0x8000_0000_0000_0001; // Smallest (in magnitude) negative f64.
+ const CLEAR_SIGN_MASK: u64 = 0x7fff_ffff_ffff_ffff;
+
+ let bits = self.to_bits();
+ if self.is_nan() || bits == Self::NEG_INFINITY.to_bits() {
+ return self;
+ }
+
+ let abs = bits & CLEAR_SIGN_MASK;
+ let next_bits = if abs == 0 {
+ NEG_TINY_BITS
+ } else if bits == abs {
+ bits - 1
+ } else {
+ bits + 1
+ };
+ Self::from_bits(next_bits)
+ }
+
/// Takes the reciprocal (inverse) of a number, `1/x`.
///
/// ```
@@ -744,7 +844,7 @@ impl f64 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
- /// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
+ /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
/// This also matches the behavior of libm’s fmax.
///
@@ -764,7 +864,7 @@ impl f64 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
- /// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
+ /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
/// This also matches the behavior of libm’s fmin.
///
@@ -926,10 +1026,14 @@ impl f64 {
}
}
}
- // SAFETY: `u64` is a plain old datatype so we can always... uh...
- // ...look, just pretend you forgot what you just read.
- // Stability concerns.
- let rt_f64_to_u64 = |rt| unsafe { mem::transmute::<f64, u64>(rt) };
+
+ #[inline(always)] // See https://github.com/rust-lang/compiler-builtins/issues/491
+ fn rt_f64_to_u64(rt: f64) -> u64 {
+ // SAFETY: `u64` is a plain old datatype so we can always... uh...
+ // ...look, just pretend you forgot what you just read.
+ // Stability concerns.
+ unsafe { mem::transmute::<f64, u64>(rt) }
+ }
// SAFETY: We use internal implementations that either always work or fail at compile time.
unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
}
@@ -940,9 +1044,9 @@ impl f64 {
/// It turns out this is incredibly portable, for two reasons:
///
/// * Floats and Ints have the same endianness on all supported platforms.
- /// * IEEE-754 very precisely specifies the bit layout of floats.
+ /// * IEEE 754 very precisely specifies the bit layout of floats.
///
- /// However there is one caveat: prior to the 2008 version of IEEE-754, how
+ /// However there is one caveat: prior to the 2008 version of IEEE 754, how
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
/// (notably x86 and ARM) picked the interpretation that was ultimately
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
@@ -1019,10 +1123,14 @@ impl f64 {
}
}
}
- // SAFETY: `u64` is a plain old datatype so we can always... uh...
- // ...look, just pretend you forgot what you just read.
- // Stability concerns.
- let rt_u64_to_f64 = |rt| unsafe { mem::transmute::<u64, f64>(rt) };
+
+ #[inline(always)] // See https://github.com/rust-lang/compiler-builtins/issues/491
+ fn rt_u64_to_f64(rt: u64) -> f64 {
+ // SAFETY: `u64` is a plain old datatype so we can always... uh...
+ // ...look, just pretend you forgot what you just read.
+ // Stability concerns.
+ unsafe { mem::transmute::<u64, f64>(rt) }
+ }
// SAFETY: We use internal implementations that either always work or fail at compile time.
unsafe { intrinsics::const_eval_select((v,), ct_u64_to_f64, rt_u64_to_f64) }
}
@@ -1280,15 +1388,14 @@ impl f64 {
#[must_use = "method returns a new number and does not mutate the original value"]
#[stable(feature = "clamp", since = "1.50.0")]
#[inline]
- pub fn clamp(self, min: f64, max: f64) -> f64 {
+ pub fn clamp(mut self, min: f64, max: f64) -> f64 {
assert!(min <= max);
- let mut x = self;
- if x < min {
- x = min;
+ if self < min {
+ self = min;
}
- if x > max {
- x = max;
+ if self > max {
+ self = max;
}
- x
+ self
}
}
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index a66de19ba..e7deb728d 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1518,6 +1518,51 @@ macro_rules! int_impl {
(a as Self, b)
}
+ /// Calculates `self + rhs + carry` without the ability to overflow.
+ ///
+ /// Performs "signed ternary addition" which takes in an extra bit to add, and may return an
+ /// additional bit of overflow. This signed function is used only on the highest-ordered data,
+ /// for which the signed overflow result indicates whether the big integer overflowed or not.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(bigint_helper_methods)]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, false), (7, false));")]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, true), (8, false));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), (", stringify!($SelfT), "::MIN, true));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(0, true), (", stringify!($SelfT), "::MIN, true));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, true), (", stringify!($SelfT), "::MIN + 1, true));")]
+ #[doc = concat!("assert_eq!(",
+ stringify!($SelfT), "::MAX.carrying_add(", stringify!($SelfT), "::MAX, true), ",
+ "(-1, true));"
+ )]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.carrying_add(-1, true), (", stringify!($SelfT), "::MIN, false));")]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".carrying_add(", stringify!($SelfT), "::MAX, true), (", stringify!($SelfT), "::MIN, true));")]
+ /// ```
+ ///
+ /// If `carry` is false, this method is equivalent to [`overflowing_add`](Self::overflowing_add):
+ ///
+ /// ```
+ /// #![feature(bigint_helper_methods)]
+ #[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".carrying_add(2, false), 5_", stringify!($SelfT), ".overflowing_add(2));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), ", stringify!($SelfT), "::MAX.overflowing_add(1));")]
+ /// ```
+ #[unstable(feature = "bigint_helper_methods", issue = "85532")]
+ #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
+ // note: longer-term this should be done via an intrinsic.
+ // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
+ let (a, b) = self.overflowing_add(rhs);
+ let (c, d) = a.overflowing_add(carry as $SelfT);
+ (c, b != d)
+ }
+
/// Calculates `self` + `rhs` with an unsigned `rhs`
///
/// Returns a tuple of the addition along with a boolean indicating
@@ -1569,6 +1614,39 @@ macro_rules! int_impl {
(a as Self, b)
}
+ /// Calculates `self - rhs - borrow` without the ability to overflow.
+ ///
+ /// Performs "signed ternary subtraction" which takes in an extra bit to subtract, and may return an
+ /// additional bit of overflow. This signed function is used only on the highest-ordered data,
+ /// for which the signed overflow result indicates whether the big integer overflowed or not.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(bigint_helper_methods)]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, false), (3, false));")]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, true), (2, false));")]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, false), (-1, false));")]
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, true), (-2, false));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.borrowing_sub(1, true), (", stringify!($SelfT), "::MAX - 1, true));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.borrowing_sub(-1, false), (", stringify!($SelfT), "::MIN, true));")]
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.borrowing_sub(-1, true), (", stringify!($SelfT), "::MAX, false));")]
+ /// ```
+ #[unstable(feature = "bigint_helper_methods", issue = "85532")]
+ #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
+ // note: longer-term this should be done via an intrinsic.
+ // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
+ let (a, b) = self.overflowing_sub(rhs);
+ let (c, d) = a.overflowing_sub(borrow as $SelfT);
+ (c, b != d)
+ }
+
/// Calculates `self` - `rhs` with an unsigned `rhs`
///
/// Returns a tuple of the subtraction along with a boolean indicating
@@ -2204,7 +2282,7 @@ macro_rules! int_impl {
/// rounded down.
///
/// This method might not be optimized owing to implementation details;
- /// `log2` can produce results more efficiently for base 2, and `log10`
+ /// `ilog2` can produce results more efficiently for base 2, and `ilog10`
/// can produce results more efficiently for base 10.
///
/// # Panics
@@ -2217,7 +2295,7 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".log(5), 1);")]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".ilog(5), 1);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
@@ -2226,8 +2304,8 @@ macro_rules! int_impl {
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
- pub const fn log(self, base: Self) -> u32 {
- match self.checked_log(base) {
+ pub const fn ilog(self, base: Self) -> u32 {
+ match self.checked_ilog(base) {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
@@ -2250,7 +2328,7 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".log2(), 1);")]
+ #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".ilog2(), 1);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
@@ -2259,8 +2337,8 @@ macro_rules! int_impl {
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
- pub const fn log2(self) -> u32 {
- match self.checked_log2() {
+ pub const fn ilog2(self) -> u32 {
+ match self.checked_ilog2() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
@@ -2283,7 +2361,7 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".log10(), 1);")]
+ #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".ilog10(), 1);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
@@ -2292,8 +2370,8 @@ macro_rules! int_impl {
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
- pub const fn log10(self) -> u32 {
- match self.checked_log10() {
+ pub const fn ilog10(self) -> u32 {
+ match self.checked_ilog10() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
@@ -2311,20 +2389,20 @@ macro_rules! int_impl {
/// Returns `None` if the number is negative or zero, or if the base is not at least 2.
///
/// This method might not be optimized owing to implementation details;
- /// `checked_log2` can produce results more efficiently for base 2, and
- /// `checked_log10` can produce results more efficiently for base 10.
+ /// `checked_ilog2` can produce results more efficiently for base 2, and
+ /// `checked_ilog10` can produce results more efficiently for base 10.
///
/// # Examples
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_log(5), Some(1));")]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_ilog(5), Some(1));")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn checked_log(self, base: Self) -> Option<u32> {
+ pub const fn checked_ilog(self, base: Self) -> Option<u32> {
if self <= 0 || base <= 1 {
None
} else {
@@ -2333,7 +2411,7 @@ macro_rules! int_impl {
// Optimization for 128 bit wide integers.
if Self::BITS == 128 {
- let b = Self::log2(self) / (Self::log2(base) + 1);
+ let b = Self::ilog2(self) / (Self::ilog2(base) + 1);
n += b;
r /= base.pow(b as u32);
}
@@ -2354,13 +2432,13 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_log2(), Some(1));")]
+ #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_ilog2(), Some(1));")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn checked_log2(self) -> Option<u32> {
+ pub const fn checked_ilog2(self) -> Option<u32> {
if self <= 0 {
None
} else {
@@ -2378,13 +2456,13 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_log10(), Some(1));")]
+ #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_ilog10(), Some(1));")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn checked_log10(self) -> Option<u32> {
+ pub const fn checked_ilog10(self) -> Option<u32> {
if self > 0 {
Some(int_log10::$ActualT(self as $ActualT))
} else {
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index f481399fd..ab17aa0c8 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -3,6 +3,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::ascii;
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::intrinsics;
use crate::mem;
use crate::ops::{Add, Mul, Sub};
@@ -57,6 +59,16 @@ pub use wrapping::Wrapping;
#[cfg(not(no_fp_fmt_parse))]
pub use dec2flt::ParseFloatError;
+#[cfg(not(bootstrap))]
+#[cfg(not(no_fp_fmt_parse))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for ParseFloatError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ self.__description()
+ }
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
pub use error::ParseIntError;
@@ -623,7 +635,7 @@ impl u8 {
///
/// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
/// - U+003A ..= U+0040 `: ; < = > ? @`, or
- /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
+ /// - U+005B ..= U+0060 `` [ \ ] ^ _ ` ``, or
/// - U+007B ..= U+007E `{ | } ~`
///
/// # Examples
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 4de0a0cf5..532a09736 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -56,7 +56,7 @@ macro_rules! nonzero_integers {
pub const unsafe fn new_unchecked(n: $Int) -> Self {
// SAFETY: this is guaranteed to be safe by the caller.
unsafe {
- core::intrinsics::assert_unsafe_precondition!(n != 0);
+ core::intrinsics::assert_unsafe_precondition!((n: $Int) => n != 0);
Self(n)
}
}
@@ -309,8 +309,8 @@ macro_rules! nonzero_unsigned_operations {
( $( $Ty: ident($Int: ident); )+ ) => {
$(
impl $Ty {
- /// Add an unsigned integer to a non-zero value.
- /// Check for overflow and return [`None`] on overflow
+ /// Adds an unsigned integer to a non-zero value.
+ /// Checks for overflow and returns [`None`] on overflow.
/// As a consequence, the result cannot wrap to zero.
///
///
@@ -346,7 +346,7 @@ macro_rules! nonzero_unsigned_operations {
}
}
- /// Add an unsigned integer to a non-zero value.
+ /// Adds an unsigned integer to a non-zero value.
#[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
///
/// # Examples
@@ -377,7 +377,7 @@ macro_rules! nonzero_unsigned_operations {
unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
}
- /// Add an unsigned integer to a non-zero value,
+ /// Adds an unsigned integer to a non-zero value,
/// assuming overflow cannot occur.
/// Overflow is unchecked, and it is undefined behaviour to overflow
/// *even if the result would wrap to a non-zero value*.
@@ -409,7 +409,7 @@ macro_rules! nonzero_unsigned_operations {
}
/// Returns the smallest power of two greater than or equal to n.
- /// Check for overflow and return [`None`]
+ /// Checks for overflow and returns [`None`]
/// if the next power of two is greater than the type’s maximum value.
/// As a consequence, the result cannot wrap to zero.
///
@@ -450,7 +450,7 @@ macro_rules! nonzero_unsigned_operations {
/// Returns the base 2 logarithm of the number, rounded down.
///
/// This is the same operation as
- #[doc = concat!("[`", stringify!($Int), "::log2`],")]
+ #[doc = concat!("[`", stringify!($Int), "::ilog2`],")]
/// except that it has no failure cases to worry about
/// since this value can never be zero.
///
@@ -460,22 +460,22 @@ macro_rules! nonzero_unsigned_operations {
/// #![feature(int_log)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
- #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().log2(), 2);")]
- #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().log2(), 3);")]
- #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().log2(), 3);")]
+ #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().ilog2(), 2);")]
+ #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().ilog2(), 3);")]
+ #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().ilog2(), 3);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn log2(self) -> u32 {
+ pub const fn ilog2(self) -> u32 {
Self::BITS - 1 - self.leading_zeros()
}
/// Returns the base 10 logarithm of the number, rounded down.
///
/// This is the same operation as
- #[doc = concat!("[`", stringify!($Int), "::log10`],")]
+ #[doc = concat!("[`", stringify!($Int), "::ilog10`],")]
/// except that it has no failure cases to worry about
/// since this value can never be zero.
///
@@ -485,15 +485,15 @@ macro_rules! nonzero_unsigned_operations {
/// #![feature(int_log)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
- #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().log10(), 1);")]
- #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().log10(), 2);")]
- #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().log10(), 2);")]
+ #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().ilog10(), 1);")]
+ #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().ilog10(), 2);")]
+ #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().ilog10(), 2);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn log10(self) -> u32 {
+ pub const fn ilog10(self) -> u32 {
super::int_log10::$Int(self.0)
}
}
@@ -545,7 +545,7 @@ macro_rules! nonzero_signed_operations {
}
/// Checked absolute value.
- /// Check for overflow and returns [`None`] if
+ /// Checks for overflow and returns [`None`] if
#[doc = concat!("`self == ", stringify!($Int), "::MIN`.")]
/// The result cannot be zero.
///
@@ -740,8 +740,8 @@ macro_rules! nonzero_unsigned_signed_operations {
( $( $signedness:ident $Ty: ident($Int: ty); )+ ) => {
$(
impl $Ty {
- /// Multiply two non-zero integers together.
- /// Check for overflow and return [`None`] on overflow.
+ /// Multiplies two non-zero integers together.
+ /// Checks for overflow and returns [`None`] on overflow.
/// As a consequence, the result cannot wrap to zero.
///
/// # Examples
@@ -777,7 +777,7 @@ macro_rules! nonzero_unsigned_signed_operations {
}
}
- /// Multiply two non-zero integers together.
+ /// Multiplies two non-zero integers together.
#[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
///
/// # Examples
@@ -809,7 +809,7 @@ macro_rules! nonzero_unsigned_signed_operations {
unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
}
- /// Multiply two non-zero integers together,
+ /// Multiplies two non-zero integers together,
/// assuming overflow cannot occur.
/// Overflow is unchecked, and it is undefined behaviour to overflow
/// *even if the result would wrap to a non-zero value*.
@@ -849,8 +849,8 @@ macro_rules! nonzero_unsigned_signed_operations {
unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
}
- /// Raise non-zero value to an integer power.
- /// Check for overflow and return [`None`] on overflow.
+ /// Raises non-zero value to an integer power.
+ /// Checks for overflow and returns [`None`] on overflow.
/// As a consequence, the result cannot wrap to zero.
///
/// # Examples
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 733655442..46fd7f2d0 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -688,7 +688,7 @@ macro_rules! uint_impl {
/// rounded down.
///
/// This method might not be optimized owing to implementation details;
- /// `log2` can produce results more efficiently for base 2, and `log10`
+ /// `ilog2` can produce results more efficiently for base 2, and `ilog10`
/// can produce results more efficiently for base 10.
///
/// # Panics
@@ -700,7 +700,7 @@ macro_rules! uint_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".log(5), 1);")]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".ilog(5), 1);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
@@ -709,8 +709,8 @@ macro_rules! uint_impl {
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
- pub const fn log(self, base: Self) -> u32 {
- match self.checked_log(base) {
+ pub const fn ilog(self, base: Self) -> u32 {
+ match self.checked_ilog(base) {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
@@ -733,7 +733,7 @@ macro_rules! uint_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".log2(), 1);")]
+ #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".ilog2(), 1);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
@@ -742,8 +742,8 @@ macro_rules! uint_impl {
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
- pub const fn log2(self) -> u32 {
- match self.checked_log2() {
+ pub const fn ilog2(self) -> u32 {
+ match self.checked_ilog2() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
@@ -766,7 +766,7 @@ macro_rules! uint_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".log10(), 1);")]
+ #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".ilog10(), 1);")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
@@ -775,8 +775,8 @@ macro_rules! uint_impl {
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
- pub const fn log10(self) -> u32 {
- match self.checked_log10() {
+ pub const fn ilog10(self) -> u32 {
+ match self.checked_ilog10() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
@@ -794,20 +794,20 @@ macro_rules! uint_impl {
/// Returns `None` if the number is zero, or if the base is not at least 2.
///
/// This method might not be optimized owing to implementation details;
- /// `checked_log2` can produce results more efficiently for base 2, and
- /// `checked_log10` can produce results more efficiently for base 10.
+ /// `checked_ilog2` can produce results more efficiently for base 2, and
+ /// `checked_ilog10` can produce results more efficiently for base 10.
///
/// # Examples
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_log(5), Some(1));")]
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_ilog(5), Some(1));")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn checked_log(self, base: Self) -> Option<u32> {
+ pub const fn checked_ilog(self, base: Self) -> Option<u32> {
if self <= 0 || base <= 1 {
None
} else {
@@ -816,7 +816,7 @@ macro_rules! uint_impl {
// Optimization for 128 bit wide integers.
if Self::BITS == 128 {
- let b = Self::log2(self) / (Self::log2(base) + 1);
+ let b = Self::ilog2(self) / (Self::ilog2(base) + 1);
n += b;
r /= base.pow(b as u32);
}
@@ -837,15 +837,15 @@ macro_rules! uint_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_log2(), Some(1));")]
+ #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_ilog2(), Some(1));")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn checked_log2(self) -> Option<u32> {
+ pub const fn checked_ilog2(self) -> Option<u32> {
if let Some(x) = <$NonZeroT>::new(self) {
- Some(x.log2())
+ Some(x.ilog2())
} else {
None
}
@@ -859,15 +859,15 @@ macro_rules! uint_impl {
///
/// ```
/// #![feature(int_log)]
- #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_log10(), Some(1));")]
+ #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_ilog10(), Some(1));")]
/// ```
#[unstable(feature = "int_log", issue = "70887")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub const fn checked_log10(self) -> Option<u32> {
+ pub const fn checked_ilog10(self) -> Option<u32> {
if let Some(x) = <$NonZeroT>::new(self) {
- Some(x.log10())
+ Some(x.ilog10())
} else {
None
}
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index aa654aa55..de9ddb852 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -156,7 +156,7 @@ pub trait Drop {
/// handled by the compiler, but when using unsafe code, can sometimes occur
/// unintentionally, particularly when using [`ptr::drop_in_place`].
///
- /// [E0040]: ../../error-index.html#E0040
+ /// [E0040]: ../../error_codes/E0040.html
/// [`panic!`]: crate::panic!
/// [`mem::drop`]: drop
/// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
index c5a194b7d..8fdf22cf6 100644
--- a/library/core/src/ops/function.rs
+++ b/library/core/src/ops/function.rs
@@ -250,9 +250,10 @@ pub trait FnOnce<Args> {
mod impls {
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A, F: ?Sized> Fn<A> for &F
+ #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
+ impl<A, F: ?Sized> const Fn<A> for &F
where
- F: Fn<A>,
+ F: ~const Fn<A>,
{
extern "rust-call" fn call(&self, args: A) -> F::Output {
(**self).call(args)
@@ -260,9 +261,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A, F: ?Sized> FnMut<A> for &F
+ #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
+ impl<A, F: ?Sized> const FnMut<A> for &F
where
- F: Fn<A>,
+ F: ~const Fn<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(**self).call(args)
@@ -270,9 +272,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A, F: ?Sized> FnOnce<A> for &F
+ #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
+ impl<A, F: ?Sized> const FnOnce<A> for &F
where
- F: Fn<A>,
+ F: ~const Fn<A>,
{
type Output = F::Output;
@@ -282,9 +285,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A, F: ?Sized> FnMut<A> for &mut F
+ #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
+ impl<A, F: ?Sized> const FnMut<A> for &mut F
where
- F: FnMut<A>,
+ F: ~const FnMut<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(*self).call_mut(args)
@@ -292,9 +296,10 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<A, F: ?Sized> FnOnce<A> for &mut F
+ #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
+ impl<A, F: ?Sized> const FnOnce<A> for &mut F
where
- F: FnMut<A>,
+ F: ~const FnMut<A>,
{
type Output = F::Output;
extern "rust-call" fn call_once(self, args: A) -> F::Output {
diff --git a/library/core/src/ops/generator.rs b/library/core/src/ops/generator.rs
index b651b7b23..3ebd6f8cd 100644
--- a/library/core/src/ops/generator.rs
+++ b/library/core/src/ops/generator.rs
@@ -83,7 +83,7 @@ pub trait Generator<R = ()> {
/// `return` statement or implicitly as the last expression of a generator
/// literal. For example futures would use this as `Result<T, E>` as it
/// represents a completed future.
- #[lang = "generator_return"]
+ #[cfg_attr(bootstrap, lang = "generator_return")]
type Return;
/// Resumes the execution of this generator.
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index a3b148473..d29ae3561 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -677,7 +677,7 @@ pub enum Bound<T> {
impl<T> Bound<T> {
/// Converts from `&Bound<T>` to `Bound<&T>`.
#[inline]
- #[unstable(feature = "bound_as_ref", issue = "80996")]
+ #[stable(feature = "bound_as_ref_shared", since = "1.65.0")]
pub fn as_ref(&self) -> Bound<&T> {
match *self {
Included(ref x) => Included(x),
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
index 02f7f62bf..10f041344 100644
--- a/library/core/src/ops/try_trait.rs
+++ b/library/core/src/ops/try_trait.rs
@@ -222,7 +222,87 @@ pub trait Try: FromResidual {
/// Every `Try` type needs to be recreatable from its own associated
/// `Residual` type, but can also have additional `FromResidual` implementations
/// to support interconversion with other `Try` types.
-#[rustc_on_unimplemented(
+#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::result::Result<T, E>",
+ R = "std::option::Option<std::convert::Infallible>"
+ ),
+ message = "the `?` operator can only be used on `Result`s, not `Option`s, \
+ in {ItemContext} that returns `Result`",
+ label = "use `.ok_or(...)?` to provide an error compatible with `{Self}`",
+ parent_label = "this function returns a `Result`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::result::Result<T, E>",
+ ),
+ // There's a special error message in the trait selection code for
+ // `From` in `?`, so this is not shown for result-in-result errors,
+ // and thus it can be phrased more strongly than `ControlFlow`'s.
+ message = "the `?` operator can only be used on `Result`s \
+ in {ItemContext} that returns `Result`",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ parent_label = "this function returns a `Result`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::option::Option<T>",
+ R = "std::result::Result<T, E>",
+ ),
+ message = "the `?` operator can only be used on `Option`s, not `Result`s, \
+ in {ItemContext} that returns `Option`",
+ label = "use `.ok()?` if you want to discard the `{R}` error information",
+ parent_label = "this function returns an `Option`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::option::Option<T>",
+ ),
+ // `Option`-in-`Option` always works, as there's only one possible
+ // residual, so this can also be phrased strongly.
+ message = "the `?` operator can only be used on `Option`s \
+ in {ItemContext} that returns `Option`",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ parent_label = "this function returns an `Option`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::ops::ControlFlow<B, C>",
+ R = "std::ops::ControlFlow<B, C>",
+ ),
+ message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
+ can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ parent_label = "this function returns a `ControlFlow`",
+ note = "unlike `Result`, there's no `From`-conversion performed for `ControlFlow`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::ops::ControlFlow<B, C>",
+ // `R` is not a `ControlFlow`, as that case was matched previously
+ ),
+ message = "the `?` operator can only be used on `ControlFlow`s \
+ in {ItemContext} that returns `ControlFlow`",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ parent_label = "this function returns a `ControlFlow`",
+ ),
+ on(
+ all(from_desugaring = "QuestionMark"),
+ message = "the `?` operator can only be used in {ItemContext} \
+ that returns `Result` or `Option` \
+ (or another type that implements `{FromResidual}`)",
+ label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
+ parent_label = "this function should return `Result` or `Option` to accept `?`"
+ ),
+))]
+#[cfg_attr(bootstrap, rustc_on_unimplemented(
on(
all(
from_desugaring = "QuestionMark",
@@ -301,7 +381,7 @@ pub trait Try: FromResidual {
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
),
-)]
+))]
#[rustc_diagnostic_item = "FromResidual"]
#[unstable(feature = "try_trait_v2", issue = "84277")]
pub trait FromResidual<R = <Self as Try>::Residual> {
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index bca73cb77..934175863 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1189,6 +1189,12 @@ impl<T> Option<T> {
/// Returns [`None`] if the option is [`None`], otherwise returns `optb`.
///
+ /// Arguments passed to `and` are eagerly evaluated; if you are passing the
+ /// result of a function call, it is recommended to use [`and_then`], which is
+ /// lazily evaluated.
+ ///
+ /// [`and_then`]: Option::and_then
+ ///
/// # Examples
///
/// ```
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 7a575a88e..d4afe0f53 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -190,11 +190,11 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
right: &str,
args: Option<fmt::Arguments<'_>>,
) -> ! {
- // Use the Display implementation to display the pattern.
+ // The pattern is a string so it can be displayed directly.
struct Pattern<'a>(&'a str);
impl fmt::Debug for Pattern<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(self.0, f)
+ f.write_str(self.0)
}
}
assert_failed_inner(AssertKind::Match, &left, &Pattern(right), args);
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index b8e546164..242f44ade 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -801,11 +801,53 @@ mod prim_array {}
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
/// ```
+///
+/// ## Trait Implementations
+///
+/// Some traits are implemented for slices if the element type implements
+/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`].
+///
+/// ## Iteration
+///
+/// The slices implement `IntoIterator`. The iterator yields references to the
+/// slice elements.
+///
+/// ```
+/// let numbers: &[i32] = &[0, 1, 2];
+/// for n in numbers {
+/// println!("{n} is a number!");
+/// }
+/// ```
+///
+/// The mutable slice yields mutable references to the elements:
+///
+/// ```
+/// let mut scores: &mut [i32] = &mut [7, 8, 9];
+/// for score in scores {
+/// *score += 1;
+/// }
+/// ```
+///
+/// This iterator yields mutable references to the slice's elements, so while
+/// the element type of the slice is `i32`, the element type of the iterator is
+/// `&mut i32`.
+///
+/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
+/// iterators.
+/// * Further methods that return iterators are [`.split`], [`.splitn`],
+/// [`.chunks`], [`.windows`] and more.
+///
+/// [`Hash`]: core::hash::Hash
+/// [`.iter`]: slice::iter
+/// [`.iter_mut`]: slice::iter_mut
+/// [`.split`]: slice::split
+/// [`.splitn`]: slice::splitn
+/// [`.chunks`]: slice::chunks
+/// [`.windows`]: slice::windows
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_slice {}
#[doc(primitive = "str")]
-//
/// String slices.
///
/// *[See also the `std::str` module](crate::str).*
@@ -816,19 +858,22 @@ mod prim_slice {}
///
/// String slices are always valid UTF-8.
///
-/// # Examples
+/// # Basic Usage
///
/// String literals are string slices:
///
/// ```
-/// let hello = "Hello, world!";
-///
-/// // with an explicit type annotation
-/// let hello: &'static str = "Hello, world!";
+/// let hello_world = "Hello, World!";
/// ```
///
-/// They are `'static` because they're stored directly in the final binary, and
-/// so will be valid for the `'static` duration.
+/// Here we have declared a string slice initialized with a string literal.
+/// String literals have a static lifetime, which means the string `hello_world`
+/// is guaranteed to be valid for the duration of the entire program.
+/// We can explicitly specify `hello_world`'s lifetime as well:
+///
+/// ```
+/// let hello_world: &'static str = "Hello, world!";
+/// ```
///
/// # Representation
///
@@ -996,7 +1041,7 @@ impl<T> (T,) {}
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Clone> Clone for (T,) {
fn clone(&self) -> Self {
@@ -1007,7 +1052,7 @@ impl<T: Clone> Clone for (T,) {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Copy> Copy for (T,) {
// empty
@@ -1178,7 +1223,7 @@ mod prim_usize {}
#[doc(alias = "&")]
#[doc(alias = "&mut")]
//
-/// References, both shared and mutable.
+/// References, `&T` and `&mut T`.
///
/// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut`
/// operators on a value, or by using a [`ref`](../std/keyword.ref.html) or
@@ -1484,13 +1529,12 @@ mod prim_fn {}
// Required to make auto trait impls render.
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
#[doc(hidden)]
-#[cfg(not(bootstrap))]
impl<Ret, T> fn(T) -> Ret {}
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Clone for fn(T) -> Ret {
fn clone(&self) -> Self {
@@ -1501,7 +1545,7 @@ impl<Ret, T> Clone for fn(T) -> Ret {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Copy for fn(T) -> Ret {
// empty
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index e0655d68d..43e883b8b 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -36,7 +36,10 @@ impl<T: ?Sized> *const T {
pub const fn is_null(self) -> bool {
// Compare via a cast to a thin pointer, so fat pointers are only
// considering their "data" part for null-ness.
- (self as *const u8).guaranteed_eq(null())
+ match (self as *const u8).guaranteed_eq(null()) {
+ None => false,
+ Some(res) => res,
+ }
}
/// Casts to a pointer of another type.
@@ -95,8 +98,8 @@ impl<T: ?Sized> *const T {
///
/// This is a bit safer than `as` because it wouldn't silently change the type if the code is
/// refactored.
- #[unstable(feature = "ptr_const_cast", issue = "92675")]
- #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")]
+ #[stable(feature = "ptr_const_cast", since = "1.65.0")]
+ #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
pub const fn cast_mut(self) -> *mut T {
self as _
}
@@ -154,7 +157,7 @@ impl<T: ?Sized> *const T {
/// This is similar to `self as usize`, which semantically discards *provenance* and
/// *address-space* information. However, unlike `self as usize`, casting the returned address
/// back to a pointer yields [`invalid`][], which is undefined behavior to dereference. To
- /// properly restore the lost information and obtain a dereferencable pointer, use
+ /// properly restore the lost information and obtain a dereferenceable pointer, use
/// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
///
/// If using those APIs is not possible because there is no way to preserve a pointer with the
@@ -249,7 +252,7 @@ impl<T: ?Sized> *const T {
let offset = dest_addr.wrapping_sub(self_addr);
// This is the canonical desugarring of this operation
- self.cast::<u8>().wrapping_offset(offset).cast::<T>()
+ self.wrapping_byte_offset(offset)
}
/// Creates a new pointer by mapping `self`'s address to a new one.
@@ -559,6 +562,21 @@ impl<T: ?Sized> *const T {
from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
}
+ /// Masks out bits of the pointer according to a mask.
+ ///
+ /// This is convenience for `ptr.map_addr(|a| a & mask)`.
+ ///
+ /// For non-`Sized` pointees this operation changes only the data pointer,
+ /// leaving the metadata untouched.
+ #[cfg(not(bootstrap))]
+ #[unstable(feature = "ptr_mask", issue = "98290")]
+ #[must_use = "returns a new pointer rather than modifying its argument"]
+ #[inline(always)]
+ pub fn mask(self, mask: usize) -> *const T {
+ let this = intrinsics::ptr_mask(self.cast::<()>(), mask);
+ from_raw_parts::<T>(this, metadata(self))
+ }
+
/// Calculates the distance between two pointers. The returned value is in
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
///
@@ -641,7 +659,7 @@ impl<T: ?Sized> *const T {
/// }
/// ```
#[stable(feature = "ptr_offset_from", since = "1.47.0")]
- #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
+ #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn offset_from(self, origin: *const T) -> isize
@@ -740,9 +758,12 @@ impl<T: ?Sized> *const T {
where
T: Sized,
{
+ let this = self;
// SAFETY: The comparison has no side-effects, and the intrinsic
// does this check internally in the CTFE implementation.
- unsafe { assert_unsafe_precondition!(self >= origin) };
+ unsafe {
+ assert_unsafe_precondition!([T](this: *const T, origin: *const T) => this >= origin)
+ };
let pointee_size = mem::size_of::<T>();
assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
@@ -752,20 +773,16 @@ impl<T: ?Sized> *const T {
/// Returns whether two pointers are guaranteed to be equal.
///
- /// At runtime this function behaves like `self == other`.
+ /// At runtime this function behaves like `Some(self == other)`.
/// However, in some contexts (e.g., compile-time evaluation),
/// it is not always possible to determine equality of two pointers, so this function may
- /// spuriously return `false` for pointers that later actually turn out to be equal.
- /// But when it returns `true`, the pointers are guaranteed to be equal.
+ /// spuriously return `None` for pointers that later actually turn out to have its equality known.
+ /// But when it returns `Some`, the pointers' equality is guaranteed to be known.
///
- /// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
- /// comparisons for which both functions return `false`.
- ///
- /// [`guaranteed_ne`]: #method.guaranteed_ne
- ///
- /// The return value may change depending on the compiler version and unsafe code must not
+ /// The return value may change from `Some` to `None` and vice versa depending on the compiler
+ /// version and unsafe code must not
/// rely on the result of this function for soundness. It is suggested to only use this function
- /// for performance optimizations where spurious `false` return values by this function do not
+ /// for performance optimizations where spurious `None` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
@@ -774,29 +791,28 @@ impl<T: ?Sized> *const T {
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
- pub const fn guaranteed_eq(self, other: *const T) -> bool
+ pub const fn guaranteed_eq(self, other: *const T) -> Option<bool>
where
T: Sized,
{
- intrinsics::ptr_guaranteed_eq(self, other)
+ match intrinsics::ptr_guaranteed_cmp(self as _, other as _) {
+ 2 => None,
+ other => Some(other == 1),
+ }
}
- /// Returns whether two pointers are guaranteed to be unequal.
+ /// Returns whether two pointers are guaranteed to be inequal.
///
- /// At runtime this function behaves like `self != other`.
+ /// At runtime this function behaves like `Some(self == other)`.
/// However, in some contexts (e.g., compile-time evaluation),
- /// it is not always possible to determine the inequality of two pointers, so this function may
- /// spuriously return `false` for pointers that later actually turn out to be unequal.
- /// But when it returns `true`, the pointers are guaranteed to be unequal.
- ///
- /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
- /// comparisons for which both functions return `false`.
- ///
- /// [`guaranteed_eq`]: #method.guaranteed_eq
+ /// it is not always possible to determine inequality of two pointers, so this function may
+ /// spuriously return `None` for pointers that later actually turn out to have its inequality known.
+ /// But when it returns `Some`, the pointers' inequality is guaranteed to be known.
///
- /// The return value may change depending on the compiler version and unsafe code must not
+ /// The return value may change from `Some` to `None` and vice versa depending on the compiler
+ /// version and unsafe code must not
/// rely on the result of this function for soundness. It is suggested to only use this function
- /// for performance optimizations where spurious `false` return values by this function do not
+ /// for performance optimizations where spurious `None` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
@@ -805,11 +821,14 @@ impl<T: ?Sized> *const T {
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
- pub const fn guaranteed_ne(self, other: *const T) -> bool
+ pub const fn guaranteed_ne(self, other: *const T) -> Option<bool>
where
T: Sized,
{
- intrinsics::ptr_guaranteed_ne(self, other)
+ match self.guaranteed_eq(other) {
+ None => None,
+ Some(eq) => Some(!eq),
+ }
}
/// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
@@ -1267,20 +1286,21 @@ impl<T: ?Sized> *const T {
/// Accessing adjacent `u8` as `u16`
///
/// ```
- /// # fn foo(n: usize) {
- /// # use std::mem::align_of;
+ /// use std::mem::align_of;
+ ///
/// # unsafe {
- /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
- /// let ptr = x.as_ptr().add(n) as *const u8;
+ /// let x = [5_u8, 6, 7, 8, 9];
+ /// let ptr = x.as_ptr();
/// let offset = ptr.align_offset(align_of::<u16>());
- /// if offset < x.len() - n - 1 {
- /// let u16_ptr = ptr.add(offset) as *const u16;
- /// assert_ne!(*u16_ptr, 500);
+ ///
+ /// if offset < x.len() - 1 {
+ /// let u16_ptr = ptr.add(offset).cast::<u16>();
+ /// assert!(*u16_ptr == u16::from_ne_bytes([5, 6]) || *u16_ptr == u16::from_ne_bytes([6, 7]));
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
- /// # } }
+ /// # }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
@@ -1336,11 +1356,8 @@ impl<T: ?Sized> *const T {
panic!("is_aligned_to: align is not a power-of-two");
}
- // SAFETY: `is_power_of_two()` will return `false` for zero.
- unsafe { core::intrinsics::assume(align != 0) };
-
// Cast is needed for `T: !Sized`
- self.cast::<u8>().addr() % align == 0
+ self.cast::<u8>().addr() & align - 1 == 0
}
}
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index cd5edee04..8865c834c 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -180,7 +180,6 @@ pub struct DynMetadata<Dyn: ?Sized> {
phantom: crate::marker::PhantomData<Dyn>,
}
-#[cfg(not(bootstrap))]
extern "C" {
/// Opaque type for accessing vtables.
///
@@ -189,17 +188,6 @@ extern "C" {
type VTable;
}
-/// The common prefix of all vtables. It is followed by function pointers for trait methods.
-///
-/// Private implementation detail of `DynMetadata::size_of` etc.
-#[repr(C)]
-#[cfg(bootstrap)]
-struct VTable {
- drop_in_place: fn(*mut ()),
- size_of: usize,
- align_of: usize,
-}
-
impl<Dyn: ?Sized> DynMetadata<Dyn> {
/// Returns the size of the type associated with this vtable.
#[inline]
@@ -207,9 +195,6 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
// Note that "size stored in vtable" is *not* the same as "result of size_of_val_raw".
// Consider a reference like `&(i32, dyn Send)`: the vtable will only store the size of the
// `Send` part!
- #[cfg(bootstrap)]
- return self.vtable_ptr.size_of;
- #[cfg(not(bootstrap))]
// SAFETY: DynMetadata always contains a valid vtable pointer
return unsafe {
crate::intrinsics::vtable_size(self.vtable_ptr as *const VTable as *const ())
@@ -219,9 +204,6 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
/// Returns the alignment of the type associated with this vtable.
#[inline]
pub fn align_of(self) -> usize {
- #[cfg(bootstrap)]
- return self.vtable_ptr.align_of;
- #[cfg(not(bootstrap))]
// SAFETY: DynMetadata always contains a valid vtable pointer
return unsafe {
crate::intrinsics::vtable_align(self.vtable_ptr as *const VTable as *const ())
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 40e28e636..e976abed7 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -90,7 +90,7 @@
//! isn't *pointer*-sized but address-space/offset/allocation-sized (we'll probably continue
//! to conflate these notions). This would potentially make it possible to more efficiently
//! target platforms where pointers are larger than offsets, such as CHERI and maybe some
-//! segmented architecures.
+//! segmented architectures.
//!
//! ## Provenance
//!
@@ -172,7 +172,7 @@
//! a pointer to a usize is generally an operation which *only* extracts the address. It is
//! therefore *impossible* to construct a valid pointer from a usize because there is no way
//! to restore the address-space and provenance. In other words, pointer-integer-pointer
-//! roundtrips are not possible (in the sense that the resulting pointer is not dereferencable).
+//! roundtrips are not possible (in the sense that the resulting pointer is not dereferenceable).
//!
//! The key insight to making this model *at all* viable is the [`with_addr`][] method:
//!
@@ -272,7 +272,7 @@
//!
//! * Create an invalid pointer from just an address (see [`ptr::invalid`][]). This can
//! be used for sentinel values like `null` *or* to represent a tagged pointer that will
-//! never be dereferencable. In general, it is always sound for an integer to pretend
+//! never be dereferenceable. In general, it is always sound for an integer to pretend
//! to be a pointer "for fun" as long as you don't use operations on it which require
//! it to be valid (offset, read, write, etc).
//!
@@ -603,6 +603,7 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
#[must_use]
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn from_exposed_addr<T>(addr: usize) -> *const T
where
T: Sized,
@@ -639,6 +640,7 @@ where
#[must_use]
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T
where
T: Sized,
@@ -884,7 +886,7 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
// SAFETY: the caller must guarantee that `x` and `y` are
// valid for writes and properly aligned.
unsafe {
- assert_unsafe_precondition!(
+ assert_unsafe_precondition!([T](x: *mut T, y: *mut T, count: usize) =>
is_aligned_and_not_null(x)
&& is_aligned_and_not_null(y)
&& is_nonoverlapping(x, y, count)
@@ -981,7 +983,7 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
// and cannot overlap `src` since `dst` must point to a distinct
// allocated object.
unsafe {
- assert_unsafe_precondition!(is_aligned_and_not_null(dst));
+ assert_unsafe_precondition!([T](dst: *mut T) => is_aligned_and_not_null(dst));
mem::swap(&mut *dst, &mut src); // cannot overlap
}
src
@@ -1468,7 +1470,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
pub unsafe fn read_volatile<T>(src: *const T) -> T {
// SAFETY: the caller must uphold the safety contract for `volatile_load`.
unsafe {
- assert_unsafe_precondition!(is_aligned_and_not_null(src));
+ assert_unsafe_precondition!([T](src: *const T) => is_aligned_and_not_null(src));
intrinsics::volatile_load(src)
}
}
@@ -1539,7 +1541,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
// SAFETY: the caller must uphold the safety contract for `volatile_store`.
unsafe {
- assert_unsafe_precondition!(is_aligned_and_not_null(dst));
+ assert_unsafe_precondition!([T](dst: *mut T) => is_aligned_and_not_null(dst));
intrinsics::volatile_store(dst, src);
}
}
@@ -1834,7 +1836,7 @@ macro_rules! maybe_fnptr_doc {
$item
};
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for function pointers with up to twelve arguments."]
#[$meta]
$item
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index fc3dd2a9b..e277b8181 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -35,7 +35,10 @@ impl<T: ?Sized> *mut T {
pub const fn is_null(self) -> bool {
// Compare via a cast to a thin pointer, so fat pointers are only
// considering their "data" part for null-ness.
- (self as *mut u8).guaranteed_eq(null_mut())
+ match (self as *mut u8).guaranteed_eq(null_mut()) {
+ None => false,
+ Some(res) => res,
+ }
}
/// Casts to a pointer of another type.
@@ -100,8 +103,8 @@ impl<T: ?Sized> *mut T {
/// coercion.
///
/// [`cast_mut`]: #method.cast_mut
- #[unstable(feature = "ptr_const_cast", issue = "92675")]
- #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")]
+ #[stable(feature = "ptr_const_cast", since = "1.65.0")]
+ #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
pub const fn cast_const(self) -> *const T {
self as _
}
@@ -160,7 +163,7 @@ impl<T: ?Sized> *mut T {
/// This is similar to `self as usize`, which semantically discards *provenance* and
/// *address-space* information. However, unlike `self as usize`, casting the returned address
/// back to a pointer yields [`invalid`][], which is undefined behavior to dereference. To
- /// properly restore the lost information and obtain a dereferencable pointer, use
+ /// properly restore the lost information and obtain a dereferenceable pointer, use
/// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
///
/// If using those APIs is not possible because there is no way to preserve a pointer with the
@@ -255,7 +258,7 @@ impl<T: ?Sized> *mut T {
let offset = dest_addr.wrapping_sub(self_addr);
// This is the canonical desugarring of this operation
- self.cast::<u8>().wrapping_offset(offset).cast::<T>()
+ self.wrapping_byte_offset(offset)
}
/// Creates a new pointer by mapping `self`'s address to a new one.
@@ -575,6 +578,21 @@ impl<T: ?Sized> *mut T {
)
}
+ /// Masks out bits of the pointer according to a mask.
+ ///
+ /// This is convenience for `ptr.map_addr(|a| a & mask)`.
+ ///
+ /// For non-`Sized` pointees this operation changes only the data pointer,
+ /// leaving the metadata untouched.
+ #[cfg(not(bootstrap))]
+ #[unstable(feature = "ptr_mask", issue = "98290")]
+ #[must_use = "returns a new pointer rather than modifying its argument"]
+ #[inline(always)]
+ pub fn mask(self, mask: usize) -> *mut T {
+ let this = intrinsics::ptr_mask(self.cast::<()>(), mask) as *mut ();
+ from_raw_parts_mut::<T>(this, metadata(self))
+ }
+
/// Returns `None` if the pointer is null, or else returns a unique reference to
/// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_mut`]
/// must be used instead.
@@ -682,20 +700,16 @@ impl<T: ?Sized> *mut T {
/// Returns whether two pointers are guaranteed to be equal.
///
- /// At runtime this function behaves like `self == other`.
+ /// At runtime this function behaves like `Some(self == other)`.
/// However, in some contexts (e.g., compile-time evaluation),
/// it is not always possible to determine equality of two pointers, so this function may
- /// spuriously return `false` for pointers that later actually turn out to be equal.
- /// But when it returns `true`, the pointers are guaranteed to be equal.
+ /// spuriously return `None` for pointers that later actually turn out to have its equality known.
+ /// But when it returns `Some`, the pointers' equality is guaranteed to be known.
///
- /// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
- /// comparisons for which both functions return `false`.
- ///
- /// [`guaranteed_ne`]: #method.guaranteed_ne
- ///
- /// The return value may change depending on the compiler version and unsafe code might not
+ /// The return value may change from `Some` to `None` and vice versa depending on the compiler
+ /// version and unsafe code must not
/// rely on the result of this function for soundness. It is suggested to only use this function
- /// for performance optimizations where spurious `false` return values by this function do not
+ /// for performance optimizations where spurious `None` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
@@ -704,29 +718,25 @@ impl<T: ?Sized> *mut T {
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
- pub const fn guaranteed_eq(self, other: *mut T) -> bool
+ pub const fn guaranteed_eq(self, other: *mut T) -> Option<bool>
where
T: Sized,
{
- intrinsics::ptr_guaranteed_eq(self as *const _, other as *const _)
+ (self as *const T).guaranteed_eq(other as _)
}
- /// Returns whether two pointers are guaranteed to be unequal.
+ /// Returns whether two pointers are guaranteed to be inequal.
///
- /// At runtime this function behaves like `self != other`.
+ /// At runtime this function behaves like `Some(self == other)`.
/// However, in some contexts (e.g., compile-time evaluation),
- /// it is not always possible to determine the inequality of two pointers, so this function may
- /// spuriously return `false` for pointers that later actually turn out to be unequal.
- /// But when it returns `true`, the pointers are guaranteed to be unequal.
- ///
- /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
- /// comparisons for which both functions return `false`.
+ /// it is not always possible to determine inequality of two pointers, so this function may
+ /// spuriously return `None` for pointers that later actually turn out to have its inequality known.
+ /// But when it returns `Some`, the pointers' inequality is guaranteed to be known.
///
- /// [`guaranteed_eq`]: #method.guaranteed_eq
- ///
- /// The return value may change depending on the compiler version and unsafe code might not
+ /// The return value may change from `Some` to `None` and vice versa depending on the compiler
+ /// version and unsafe code must not
/// rely on the result of this function for soundness. It is suggested to only use this function
- /// for performance optimizations where spurious `false` return values by this function do not
+ /// for performance optimizations where spurious `None` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
@@ -735,11 +745,11 @@ impl<T: ?Sized> *mut T {
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
- pub const unsafe fn guaranteed_ne(self, other: *mut T) -> bool
+ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
where
T: Sized,
{
- intrinsics::ptr_guaranteed_ne(self as *const _, other as *const _)
+ (self as *const T).guaranteed_ne(other as _)
}
/// Calculates the distance between two pointers. The returned value is in
@@ -824,7 +834,7 @@ impl<T: ?Sized> *mut T {
/// }
/// ```
#[stable(feature = "ptr_offset_from", since = "1.47.0")]
- #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
+ #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn offset_from(self, origin: *const T) -> isize
@@ -1545,20 +1555,23 @@ impl<T: ?Sized> *mut T {
/// Accessing adjacent `u8` as `u16`
///
/// ```
- /// # fn foo(n: usize) {
- /// # use std::mem::align_of;
+ /// use std::mem::align_of;
+ ///
/// # unsafe {
- /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
- /// let ptr = x.as_ptr().add(n) as *const u8;
+ /// let mut x = [5_u8, 6, 7, 8, 9];
+ /// let ptr = x.as_mut_ptr();
/// let offset = ptr.align_offset(align_of::<u16>());
- /// if offset < x.len() - n - 1 {
- /// let u16_ptr = ptr.add(offset) as *const u16;
- /// assert_ne!(*u16_ptr, 500);
+ ///
+ /// if offset < x.len() - 1 {
+ /// let u16_ptr = ptr.add(offset).cast::<u16>();
+ /// *u16_ptr = 0;
+ ///
+ /// assert!(x == [0, 0, 7, 8, 9] || x == [5, 0, 0, 8, 9]);
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
- /// # } }
+ /// # }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
@@ -1614,11 +1627,8 @@ impl<T: ?Sized> *mut T {
panic!("is_aligned_to: align is not a power-of-two");
}
- // SAFETY: `is_power_of_two()` will return `false` for zero.
- unsafe { core::intrinsics::assume(align != 0) };
-
// Cast is needed for `T: !Sized`
- self.cast::<u8>().addr() % align == 0
+ self.cast::<u8>().addr() & align - 1 == 0
}
}
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 45b052c82..76eaa191f 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1285,6 +1285,11 @@ impl<T, E> Result<T, E> {
/// Returns `res` if the result is [`Ok`], otherwise returns the [`Err`] value of `self`.
///
+ /// Arguments passed to `and` are eagerly evaluated; if you are passing the
+ /// result of a function call, it is recommended to use [`and_then`], which is
+ /// lazily evaluated.
+ ///
+ /// [`and_then`]: Result::and_then
///
/// # Examples
///
@@ -1771,40 +1776,6 @@ impl<T, E> Result<Result<T, E>, E> {
}
}
-impl<T> Result<T, T> {
- /// Returns the [`Ok`] value if `self` is `Ok`, and the [`Err`] value if
- /// `self` is `Err`.
- ///
- /// In other words, this function returns the value (the `T`) of a
- /// `Result<T, T>`, regardless of whether or not that result is `Ok` or
- /// `Err`.
- ///
- /// This can be useful in conjunction with APIs such as
- /// [`Atomic*::compare_exchange`], or [`slice::binary_search`], but only in
- /// cases where you don't care if the result was `Ok` or not.
- ///
- /// [`Atomic*::compare_exchange`]: crate::sync::atomic::AtomicBool::compare_exchange
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(result_into_ok_or_err)]
- /// let ok: Result<u32, u32> = Ok(3);
- /// let err: Result<u32, u32> = Err(4);
- ///
- /// assert_eq!(ok.into_ok_or_err(), 3);
- /// assert_eq!(err.into_ok_or_err(), 4);
- /// ```
- #[inline]
- #[unstable(feature = "result_into_ok_or_err", reason = "newly added", issue = "82223")]
- pub const fn into_ok_or_err(self) -> T {
- match self {
- Ok(v) => v,
- Err(v) => v,
- }
- }
-}
-
// This is a separate function to reduce the code size of the methods
#[cfg(not(feature = "panic_immediate_abort"))]
#[inline(never)]
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 63715a6b8..5e5399acc 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -215,8 +215,6 @@ impl<'a> iter::DoubleEndedIterator for EscapeAscii<'a> {
}
}
#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
-impl<'a> iter::ExactSizeIterator for EscapeAscii<'a> {}
-#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
impl<'a> iter::FusedIterator for EscapeAscii<'a> {}
#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
impl<'a> fmt::Display for EscapeAscii<'a> {
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index fd7ecf3da..3403a5a86 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -48,10 +48,12 @@ const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
}
// FIXME const-hack
+#[track_caller]
fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! {
panic!("range start index {index} out of range for slice of length {len}");
}
+#[track_caller]
const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
panic!("slice start index is out of range for slice");
}
@@ -69,10 +71,12 @@ const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
}
// FIXME const-hack
+#[track_caller]
fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! {
panic!("range end index {index} out of range for slice of length {len}");
}
+#[track_caller]
const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
panic!("slice end index is out of range for slice");
}
@@ -88,10 +92,12 @@ const fn slice_index_order_fail(index: usize, end: usize) -> ! {
}
// FIXME const-hack
+#[track_caller]
fn slice_index_order_fail_rt(index: usize, end: usize) -> ! {
panic!("slice index starts at {index} but ends at {end}");
}
+#[track_caller]
const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! {
panic!("slice index start is larger than end");
}
@@ -217,21 +223,23 @@ unsafe impl<T> const SliceIndex<[T]> for usize {
#[inline]
unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+ let this = self;
// SAFETY: the caller guarantees that `slice` is not dangling, so it
// cannot be longer than `isize::MAX`. They also guarantee that
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
// so the call to `add` is safe.
unsafe {
- assert_unsafe_precondition!(self < slice.len());
+ assert_unsafe_precondition!([T](this: usize, slice: *const [T]) => this < slice.len());
slice.as_ptr().add(self)
}
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
+ let this = self;
// SAFETY: see comments for `get_unchecked` above.
unsafe {
- assert_unsafe_precondition!(self < slice.len());
+ assert_unsafe_precondition!([T](this: usize, slice: *mut [T]) => this < slice.len());
slice.as_mut_ptr().add(self)
}
}
@@ -276,22 +284,26 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
#[inline]
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ let this = ops::Range { start: self.start, end: self.end };
// SAFETY: the caller guarantees that `slice` is not dangling, so it
// cannot be longer than `isize::MAX`. They also guarantee that
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
// so the call to `add` is safe.
unsafe {
- assert_unsafe_precondition!(self.end >= self.start && self.end <= slice.len());
+ assert_unsafe_precondition!([T](this: ops::Range<usize>, slice: *const [T]) =>
+ this.end >= this.start && this.end <= slice.len());
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start)
}
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ let this = ops::Range { start: self.start, end: self.end };
// SAFETY: see comments for `get_unchecked` above.
unsafe {
- assert_unsafe_precondition!(self.end >= self.start && self.end <= slice.len());
+ assert_unsafe_precondition!([T](this: ops::Range<usize>, slice: *mut [T]) =>
+ this.end >= this.start && this.end <= slice.len());
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
}
}
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index f1e659309..395c56784 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -92,7 +92,7 @@ impl<'a, T> Iter<'a, T> {
assume(!ptr.is_null());
let end = if mem::size_of::<T>() == 0 {
- (ptr as *const u8).wrapping_add(slice.len()) as *const T
+ ptr.wrapping_byte_add(slice.len())
} else {
ptr.add(slice.len())
};
@@ -228,7 +228,7 @@ impl<'a, T> IterMut<'a, T> {
assume(!ptr.is_null());
let end = if mem::size_of::<T>() == 0 {
- (ptr as *mut u8).wrapping_add(slice.len()) as *mut T
+ ptr.wrapping_byte_add(slice.len())
} else {
ptr.add(slice.len())
};
@@ -2754,10 +2754,10 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
None => 0,
};
// SAFETY: This type ensures that self.v is a valid pointer with a correct len.
- // Therefore the bounds check in split_at_mut guarantess the split point is inbounds.
+ // Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
let (head, tail) = unsafe { self.v.split_at_mut(start) };
// SAFETY: This type ensures that self.v is a valid pointer with a correct len.
- // Therefore the bounds check in split_at_mut guarantess the split point is inbounds.
+ // Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
let (nth, _) = unsafe { tail.split_at_mut(end - start) };
self.v = head;
// SAFETY: Nothing else points to or will point to the contents of this slice.
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index c05242222..6c9e7574e 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -64,7 +64,7 @@ macro_rules! iterator {
// backwards by `n`. `n` must not exceed `self.len()`.
macro_rules! zst_shrink {
($self: ident, $n: ident) => {
- $self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T;
+ $self.end = $self.end.wrapping_byte_sub($n);
}
}
@@ -82,7 +82,7 @@ macro_rules! iterator {
// returning the old start.
// Unsafe because the offset must not exceed `self.len()`.
#[inline(always)]
- unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
+ unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T {
if mem::size_of::<T>() == 0 {
zst_shrink!(self, offset);
self.ptr.as_ptr()
@@ -90,7 +90,7 @@ macro_rules! iterator {
let old = self.ptr.as_ptr();
// SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
// so this new pointer is inside `self` and thus guaranteed to be non-null.
- self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().offset(offset)) };
+ self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().add(offset)) };
old
}
}
@@ -99,7 +99,7 @@ macro_rules! iterator {
// returning the new end.
// Unsafe because the offset must not exceed `self.len()`.
#[inline(always)]
- unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
+ unsafe fn pre_dec_end(&mut self, offset: usize) -> * $raw_mut T {
if mem::size_of::<T>() == 0 {
zst_shrink!(self, offset);
self.ptr.as_ptr()
@@ -107,7 +107,7 @@ macro_rules! iterator {
// SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
// which is guaranteed to not overflow an `isize`. Also, the resulting pointer
// is in bounds of `slice`, which fulfills the other requirements for `offset`.
- self.end = unsafe { self.end.offset(-offset) };
+ self.end = unsafe { self.end.sub(offset) };
self.end
}
}
@@ -180,7 +180,7 @@ macro_rules! iterator {
}
// SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
unsafe {
- self.post_inc_start(n as isize);
+ self.post_inc_start(n);
Some(next_unchecked!(self))
}
}
@@ -189,7 +189,7 @@ macro_rules! iterator {
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
let advance = cmp::min(len!(self), n);
// SAFETY: By construction, `advance` does not exceed `self.len()`.
- unsafe { self.post_inc_start(advance as isize) };
+ unsafe { self.post_inc_start(advance) };
if advance == n { Ok(()) } else { Err(advance) }
}
@@ -375,7 +375,7 @@ macro_rules! iterator {
}
// SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
unsafe {
- self.pre_dec_end(n as isize);
+ self.pre_dec_end(n);
Some(next_back_unchecked!(self))
}
}
@@ -384,7 +384,7 @@ macro_rules! iterator {
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
let advance = cmp::min(len!(self), n);
// SAFETY: By construction, `advance` does not exceed `self.len()`.
- unsafe { self.pre_dec_end(advance as isize) };
+ unsafe { self.pre_dec_end(advance) };
if advance == n { Ok(()) } else { Err(advance) }
}
}
diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs
index dffeaf6a8..7de1f48e6 100644
--- a/library/core/src/slice/memchr.rs
+++ b/library/core/src/slice/memchr.rs
@@ -16,35 +16,51 @@ const USIZE_BYTES: usize = mem::size_of::<usize>();
/// bytes where the borrow propagated all the way to the most significant
/// bit."
#[inline]
-fn contains_zero_byte(x: usize) -> bool {
+const fn contains_zero_byte(x: usize) -> bool {
x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
}
#[cfg(target_pointer_width = "16")]
#[inline]
-fn repeat_byte(b: u8) -> usize {
+const fn repeat_byte(b: u8) -> usize {
(b as usize) << 8 | b as usize
}
#[cfg(not(target_pointer_width = "16"))]
#[inline]
-fn repeat_byte(b: u8) -> usize {
+const fn repeat_byte(b: u8) -> usize {
(b as usize) * (usize::MAX / 255)
}
/// Returns the first index matching the byte `x` in `text`.
#[must_use]
#[inline]
-pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
- // Fast path for small slices
+pub const fn memchr(x: u8, text: &[u8]) -> Option<usize> {
+ // Fast path for small slices.
if text.len() < 2 * USIZE_BYTES {
- return text.iter().position(|elt| *elt == x);
+ return memchr_naive(x, text);
}
- memchr_general_case(x, text)
+ memchr_aligned(x, text)
}
-fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
+#[inline]
+const fn memchr_naive(x: u8, text: &[u8]) -> Option<usize> {
+ let mut i = 0;
+
+ // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`.
+ while i < text.len() {
+ if text[i] == x {
+ return Some(i);
+ }
+
+ i += 1;
+ }
+
+ None
+}
+
+const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> {
// Scan for a single byte value by reading two `usize` words at a time.
//
// Split `text` in three parts
@@ -59,7 +75,7 @@ fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
if offset > 0 {
offset = cmp::min(offset, len);
- if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
+ if let Some(index) = memchr_naive(x, &text[..offset]) {
return Some(index);
}
}
@@ -84,7 +100,8 @@ fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
}
// Find the byte after the point the body loop stopped.
- text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
+ // FIXME(const-hack): Use `?` instead.
+ if let Some(i) = memchr_naive(x, &text[offset..]) { Some(offset + i) } else { None }
}
/// Returns the last index matching the byte `x` in `text`.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index e6ca6ef82..6a7150d29 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -656,10 +656,11 @@ impl<T> [T] {
#[unstable(feature = "slice_swap_unchecked", issue = "88539")]
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
- let ptr = self.as_mut_ptr();
+ let this = self;
+ let ptr = this.as_mut_ptr();
// SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`
unsafe {
- assert_unsafe_precondition!(a < self.len() && b < self.len());
+ assert_unsafe_precondition!([T](a: usize, b: usize, this: &mut [T]) => a < this.len() && b < this.len());
ptr::swap(ptr.add(a), ptr.add(b));
}
}
@@ -674,8 +675,9 @@ impl<T> [T] {
/// assert!(v == [3, 2, 1]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_reverse", issue = "100784")]
#[inline]
- pub fn reverse(&mut self) {
+ pub const fn reverse(&mut self) {
let half_len = self.len() / 2;
let Range { start, end } = self.as_mut_ptr_range();
@@ -698,9 +700,9 @@ impl<T> [T] {
revswap(front_half, back_half, half_len);
#[inline]
- fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) {
- debug_assert_eq!(a.len(), n);
- debug_assert_eq!(b.len(), n);
+ const fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) {
+ debug_assert!(a.len() == n);
+ debug_assert!(b.len() == n);
// Because this function is first compiled in isolation,
// this check tells LLVM that the indexing below is
@@ -708,8 +710,10 @@ impl<T> [T] {
// lengths of the slices are known -- it's removed.
let (a, b) = (&mut a[..n], &mut b[..n]);
- for i in 0..n {
+ let mut i = 0;
+ while i < n {
mem::swap(&mut a[i], &mut b[n - 1 - i]);
+ i += 1;
}
}
}
@@ -969,9 +973,10 @@ impl<T> [T] {
#[inline]
#[must_use]
pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {
+ let this = self;
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
let new_len = unsafe {
- assert_unsafe_precondition!(N != 0 && self.len() % N == 0);
+ assert_unsafe_precondition!([T](this: &[T], N: usize) => N != 0 && this.len() % N == 0);
exact_div(self.len(), N)
};
// SAFETY: We cast a slice of `new_len * N` elements into
@@ -1108,10 +1113,11 @@ impl<T> [T] {
#[inline]
#[must_use]
pub unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {
+ let this = &*self;
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
let new_len = unsafe {
- assert_unsafe_precondition!(N != 0 && self.len() % N == 0);
- exact_div(self.len(), N)
+ assert_unsafe_precondition!([T](this: &[T], N: usize) => N != 0 && this.len() % N == 0);
+ exact_div(this.len(), N)
};
// SAFETY: We cast a slice of `new_len * N` elements into
// a slice of `new_len` many `N` elements chunks.
@@ -1538,13 +1544,14 @@ impl<T> [T] {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_slice_split_at_not_mut", issue = "101158")]
#[inline]
#[track_caller]
#[must_use]
- pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
+ pub const fn split_at(&self, mid: usize) -> (&[T], &[T]) {
assert!(mid <= self.len());
// SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
- // fulfills the requirements of `from_raw_parts_mut`.
+ // fulfills the requirements of `split_at_unchecked`.
unsafe { self.split_at_unchecked(mid) }
}
@@ -1623,11 +1630,19 @@ impl<T> [T] {
/// }
/// ```
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
+ #[rustc_const_unstable(feature = "slice_split_at_unchecked", issue = "76014")]
#[inline]
#[must_use]
- pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
+ pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
+ // HACK: the const function `from_raw_parts` is used to make this
+ // function const; previously the implementation used
+ // `(self.get_unchecked(..mid), self.get_unchecked(mid..))`
+
+ let len = self.len();
+ let ptr = self.as_ptr();
+
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
- unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) }
+ unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) }
}
/// Divides one mutable slice into two at an index, without doing bounds checking.
@@ -1675,7 +1690,7 @@ impl<T> [T] {
// `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
// is fine.
unsafe {
- assert_unsafe_precondition!(mid <= len);
+ assert_unsafe_precondition!((mid: usize, len: usize) => mid <= len);
(from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid))
}
}
@@ -2309,7 +2324,7 @@ impl<T> [T] {
}
/// Binary searches this slice for a given element.
- /// This behaves similary to [`contains`] if this slice is sorted.
+ /// This behaves similarly to [`contains`] if this slice is sorted.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
/// index of the matching element. If there are multiple matches, then any
@@ -2921,7 +2936,7 @@ impl<T> [T] {
let prev_ptr_write = ptr.add(next_write - 1);
if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
if next_read != next_write {
- let ptr_write = prev_ptr_write.offset(1);
+ let ptr_write = prev_ptr_write.add(1);
mem::swap(&mut *ptr_read, &mut *ptr_write);
}
next_write += 1;
@@ -3518,7 +3533,7 @@ impl<T> [T] {
// alignment targeted for U.
// `crate::ptr::align_offset` is called with a correctly aligned and
// valid pointer `ptr` (it comes from a reference to `self`) and with
- // a size that is a power of two (since it comes from the alignement for U),
+ // a size that is a power of two (since it comes from the alignment for U),
// satisfying its safety constraints.
let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::<U>()) };
if offset > self.len() {
@@ -4101,7 +4116,6 @@ impl<T, const N: usize> [[T; N]] {
}
}
-#[cfg(not(bootstrap))]
#[cfg(not(test))]
impl [f32] {
/// Sorts the slice of floats.
@@ -4131,7 +4145,6 @@ impl [f32] {
}
}
-#[cfg(not(bootstrap))]
#[cfg(not(test))]
impl [f64] {
/// Sorts the slice of floats.
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 107e71ab6..f1e8bc79b 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -90,7 +90,7 @@ use crate::ptr;
pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
unsafe {
- assert_unsafe_precondition!(
+ assert_unsafe_precondition!([T](data: *const T, len: usize) =>
is_aligned_and_not_null(data)
&& crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize
);
@@ -134,7 +134,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
unsafe {
- assert_unsafe_precondition!(
+ assert_unsafe_precondition!([T](data: *mut T, len: usize) =>
is_aligned_and_not_null(data)
&& crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize
);
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 6a201834b..c6c03c0b0 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -326,8 +326,8 @@ where
unsafe {
// Branchless comparison.
*end_l = i as u8;
- end_l = end_l.offset(!is_less(&*elem, pivot) as isize);
- elem = elem.offset(1);
+ end_l = end_l.add(!is_less(&*elem, pivot) as usize);
+ elem = elem.add(1);
}
}
}
@@ -352,9 +352,9 @@ where
// Plus, `block_r` was asserted to be less than `BLOCK` and `elem` will therefore at most be pointing to the beginning of the slice.
unsafe {
// Branchless comparison.
- elem = elem.offset(-1);
+ elem = elem.sub(1);
*end_r = i as u8;
- end_r = end_r.offset(is_less(&*elem, pivot) as isize);
+ end_r = end_r.add(is_less(&*elem, pivot) as usize);
}
}
}
@@ -365,12 +365,12 @@ where
if count > 0 {
macro_rules! left {
() => {
- l.offset(*start_l as isize)
+ l.add(usize::from(*start_l))
};
}
macro_rules! right {
() => {
- r.offset(-(*start_r as isize) - 1)
+ r.sub(usize::from(*start_r) + 1)
};
}
@@ -398,16 +398,16 @@ where
ptr::copy_nonoverlapping(right!(), left!(), 1);
for _ in 1..count {
- start_l = start_l.offset(1);
+ start_l = start_l.add(1);
ptr::copy_nonoverlapping(left!(), right!(), 1);
- start_r = start_r.offset(1);
+ start_r = start_r.add(1);
ptr::copy_nonoverlapping(right!(), left!(), 1);
}
ptr::copy_nonoverlapping(&tmp, right!(), 1);
mem::forget(tmp);
- start_l = start_l.offset(1);
- start_r = start_r.offset(1);
+ start_l = start_l.add(1);
+ start_r = start_r.add(1);
}
}
@@ -420,7 +420,7 @@ where
// safe. Otherwise, the debug assertions in the `is_done` case guarantee that
// `width(l, r) == block_l + block_r`, namely, that the block sizes have been adjusted to account
// for the smaller number of remaining elements.
- l = unsafe { l.offset(block_l as isize) };
+ l = unsafe { l.add(block_l) };
}
if start_r == end_r {
@@ -428,7 +428,7 @@ where
// SAFETY: Same argument as [block-width-guarantee]. Either this is a full block `2*BLOCK`-wide,
// or `block_r` has been adjusted for the last handful of elements.
- r = unsafe { r.offset(-(block_r as isize)) };
+ r = unsafe { r.sub(block_r) };
}
if is_done {
@@ -457,9 +457,9 @@ where
// - `offsets_l` contains valid offsets into `v` collected during the partitioning of
// the last block, so the `l.offset` calls are valid.
unsafe {
- end_l = end_l.offset(-1);
- ptr::swap(l.offset(*end_l as isize), r.offset(-1));
- r = r.offset(-1);
+ end_l = end_l.sub(1);
+ ptr::swap(l.add(usize::from(*end_l)), r.sub(1));
+ r = r.sub(1);
}
}
width(v.as_mut_ptr(), r)
@@ -470,9 +470,9 @@ where
while start_r < end_r {
// SAFETY: See the reasoning in [remaining-elements-safety].
unsafe {
- end_r = end_r.offset(-1);
- ptr::swap(l, r.offset(-(*end_r as isize) - 1));
- l = l.offset(1);
+ end_r = end_r.sub(1);
+ ptr::swap(l, r.sub(usize::from(*end_r) + 1));
+ l = l.add(1);
}
}
width(v.as_mut_ptr(), l)
diff --git a/library/core/src/str/error.rs b/library/core/src/str/error.rs
index 4e569fcc8..343889b69 100644
--- a/library/core/src/str/error.rs
+++ b/library/core/src/str/error.rs
@@ -1,5 +1,7 @@
//! Defines utf8 error type.
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt;
/// Errors which can occur when attempting to interpret a sequence of [`u8`]
@@ -122,6 +124,15 @@ impl fmt::Display for Utf8Error {
}
}
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for Utf8Error {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "invalid utf-8: corrupt contents"
+ }
+}
+
/// An error returned when parsing a `bool` using [`from_str`] fails
///
/// [`from_str`]: super::FromStr::from_str
@@ -136,3 +147,12 @@ impl fmt::Display for ParseBoolError {
"provided string was not `true` or `false`".fmt(f)
}
}
+
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for ParseBoolError {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "failed to parse bool"
+ }
+}
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index 6ec1c9390..59f873d12 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -1,51 +1,170 @@
-use crate::char;
-use crate::fmt::{self, Write};
-use crate::mem;
+use crate::fmt;
+use crate::fmt::Formatter;
+use crate::fmt::Write;
+use crate::iter::FusedIterator;
use super::from_utf8_unchecked;
use super::validations::utf8_char_width;
-/// Lossy UTF-8 string.
-#[unstable(feature = "str_internals", issue = "none")]
-pub struct Utf8Lossy {
- bytes: [u8],
+/// An item returned by the [`Utf8Chunks`] iterator.
+///
+/// A `Utf8Chunk` stores a sequence of [`u8`] up to the first broken character
+/// when decoding a UTF-8 string.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(utf8_chunks)]
+///
+/// use std::str::Utf8Chunks;
+///
+/// // An invalid UTF-8 string
+/// let bytes = b"foo\xF1\x80bar";
+///
+/// // Decode the first `Utf8Chunk`
+/// let chunk = Utf8Chunks::new(bytes).next().unwrap();
+///
+/// // The first three characters are valid UTF-8
+/// assert_eq!("foo", chunk.valid());
+///
+/// // The fourth character is broken
+/// assert_eq!(b"\xF1\x80", chunk.invalid());
+/// ```
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Utf8Chunk<'a> {
+ valid: &'a str,
+ invalid: &'a [u8],
}
-impl Utf8Lossy {
+impl<'a> Utf8Chunk<'a> {
+ /// Returns the next validated UTF-8 substring.
+ ///
+ /// This substring can be empty at the start of the string or between
+ /// broken UTF-8 characters.
#[must_use]
- pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy {
- // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required.
- unsafe { mem::transmute(bytes) }
+ #[unstable(feature = "utf8_chunks", issue = "99543")]
+ pub fn valid(&self) -> &'a str {
+ self.valid
}
- pub fn chunks(&self) -> Utf8LossyChunksIter<'_> {
- Utf8LossyChunksIter { source: &self.bytes }
+ /// Returns the invalid sequence that caused a failure.
+ ///
+ /// The returned slice will have a maximum length of 3 and starts after the
+ /// substring given by [`valid`]. Decoding will resume after this sequence.
+ ///
+ /// If empty, this is the last chunk in the string. If non-empty, an
+ /// unexpected byte was encountered or the end of the input was reached
+ /// unexpectedly.
+ ///
+ /// Lossy decoding would replace this sequence with [`U+FFFD REPLACEMENT
+ /// CHARACTER`].
+ ///
+ /// [`valid`]: Self::valid
+ /// [`U+FFFD REPLACEMENT CHARACTER`]: crate::char::REPLACEMENT_CHARACTER
+ #[must_use]
+ #[unstable(feature = "utf8_chunks", issue = "99543")]
+ pub fn invalid(&self) -> &'a [u8] {
+ self.invalid
}
}
-/// Iterator over lossy UTF-8 string
-#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[must_use]
+#[unstable(feature = "str_internals", issue = "none")]
+pub struct Debug<'a>(&'a [u8]);
+
#[unstable(feature = "str_internals", issue = "none")]
-#[allow(missing_debug_implementations)]
-pub struct Utf8LossyChunksIter<'a> {
+impl fmt::Debug for Debug<'_> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_char('"')?;
+
+ for chunk in Utf8Chunks::new(self.0) {
+ // Valid part.
+ // Here we partially parse UTF-8 again which is suboptimal.
+ {
+ let valid = chunk.valid();
+ let mut from = 0;
+ for (i, c) in valid.char_indices() {
+ let esc = c.escape_debug();
+ // If char needs escaping, flush backlog so far and write, else skip
+ if esc.len() != 1 {
+ f.write_str(&valid[from..i])?;
+ for c in esc {
+ f.write_char(c)?;
+ }
+ from = i + c.len_utf8();
+ }
+ }
+ f.write_str(&valid[from..])?;
+ }
+
+ // Broken parts of string as hex escape.
+ for &b in chunk.invalid() {
+ write!(f, "\\x{:02X}", b)?;
+ }
+ }
+
+ f.write_char('"')
+ }
+}
+
+/// An iterator used to decode a slice of mostly UTF-8 bytes to string slices
+/// ([`&str`]) and byte slices ([`&[u8]`][byteslice]).
+///
+/// If you want a simple conversion from UTF-8 byte slices to string slices,
+/// [`from_utf8`] is easier to use.
+///
+/// [byteslice]: slice
+/// [`from_utf8`]: super::from_utf8
+///
+/// # Examples
+///
+/// This can be used to create functionality similar to
+/// [`String::from_utf8_lossy`] without allocating heap memory:
+///
+/// ```
+/// #![feature(utf8_chunks)]
+///
+/// use std::str::Utf8Chunks;
+///
+/// fn from_utf8_lossy<F>(input: &[u8], mut push: F) where F: FnMut(&str) {
+/// for chunk in Utf8Chunks::new(input) {
+/// push(chunk.valid());
+///
+/// if !chunk.invalid().is_empty() {
+/// push("\u{FFFD}");
+/// }
+/// }
+/// }
+/// ```
+///
+/// [`String::from_utf8_lossy`]: ../../std/string/struct.String.html#method.from_utf8_lossy
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[derive(Clone)]
+pub struct Utf8Chunks<'a> {
source: &'a [u8],
}
-#[unstable(feature = "str_internals", issue = "none")]
-#[derive(PartialEq, Eq, Debug)]
-pub struct Utf8LossyChunk<'a> {
- /// Sequence of valid chars.
- /// Can be empty between broken UTF-8 chars.
- pub valid: &'a str,
- /// Single broken char, empty if none.
- /// Empty iff iterator item is last.
- pub broken: &'a [u8],
+impl<'a> Utf8Chunks<'a> {
+ /// Creates a new iterator to decode the bytes.
+ #[unstable(feature = "utf8_chunks", issue = "99543")]
+ pub fn new(bytes: &'a [u8]) -> Self {
+ Self { source: bytes }
+ }
+
+ #[doc(hidden)]
+ #[unstable(feature = "str_internals", issue = "none")]
+ pub fn debug(&self) -> Debug<'_> {
+ Debug(self.source)
+ }
}
-impl<'a> Iterator for Utf8LossyChunksIter<'a> {
- type Item = Utf8LossyChunk<'a>;
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+impl<'a> Iterator for Utf8Chunks<'a> {
+ type Item = Utf8Chunk<'a>;
- fn next(&mut self) -> Option<Utf8LossyChunk<'a>> {
+ fn next(&mut self) -> Option<Utf8Chunk<'a>> {
if self.source.is_empty() {
return None;
}
@@ -130,71 +249,22 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
// SAFETY: `valid_up_to <= i` because it is only ever assigned via
// `valid_up_to = i` and `i` only increases.
- let (valid, broken) = unsafe { inspected.split_at_unchecked(valid_up_to) };
+ let (valid, invalid) = unsafe { inspected.split_at_unchecked(valid_up_to) };
- Some(Utf8LossyChunk {
+ Some(Utf8Chunk {
// SAFETY: All bytes up to `valid_up_to` are valid UTF-8.
valid: unsafe { from_utf8_unchecked(valid) },
- broken,
+ invalid,
})
}
}
-impl fmt::Display for Utf8Lossy {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // If we're the empty string then our iterator won't actually yield
- // anything, so perform the formatting manually
- if self.bytes.is_empty() {
- return "".fmt(f);
- }
-
- for Utf8LossyChunk { valid, broken } in self.chunks() {
- // If we successfully decoded the whole chunk as a valid string then
- // we can return a direct formatting of the string which will also
- // respect various formatting flags if possible.
- if valid.len() == self.bytes.len() {
- assert!(broken.is_empty());
- return valid.fmt(f);
- }
-
- f.write_str(valid)?;
- if !broken.is_empty() {
- f.write_char(char::REPLACEMENT_CHARACTER)?;
- }
- }
- Ok(())
- }
-}
-
-impl fmt::Debug for Utf8Lossy {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_char('"')?;
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+impl FusedIterator for Utf8Chunks<'_> {}
- for Utf8LossyChunk { valid, broken } in self.chunks() {
- // Valid part.
- // Here we partially parse UTF-8 again which is suboptimal.
- {
- let mut from = 0;
- for (i, c) in valid.char_indices() {
- let esc = c.escape_debug();
- // If char needs escaping, flush backlog so far and write, else skip
- if esc.len() != 1 {
- f.write_str(&valid[from..i])?;
- for c in esc {
- f.write_char(c)?;
- }
- from = i + c.len_utf8();
- }
- }
- f.write_str(&valid[from..])?;
- }
-
- // Broken parts of string as hex escape.
- for &b in broken {
- write!(f, "\\x{:02x}", b)?;
- }
- }
-
- f.write_char('"')
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+impl fmt::Debug for Utf8Chunks<'_> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Utf8Chunks").field("source", &self.debug()).finish()
}
}
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index c4f2e283e..f673aa2a4 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -22,9 +22,9 @@ use crate::slice::{self, SliceIndex};
pub mod pattern;
-#[unstable(feature = "str_internals", issue = "none")]
-#[allow(missing_docs)]
-pub mod lossy;
+mod lossy;
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+pub use lossy::{Utf8Chunk, Utf8Chunks};
#[stable(feature = "rust1", since = "1.0.0")]
pub use converts::{from_utf8, from_utf8_unchecked};
@@ -91,10 +91,12 @@ const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
}
}
+#[track_caller]
const fn slice_error_fail_ct(_: &str, _: usize, _: usize) -> ! {
panic!("failed to slice string");
}
+#[track_caller]
fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
const MAX_DISPLAY_LENGTH: usize = 256;
let trunc_len = s.floor_char_boundary(MAX_DISPLAY_LENGTH);
@@ -2353,7 +2355,7 @@ impl str {
#[inline]
pub fn is_ascii(&self) -> bool {
// We can treat each byte as character here: all multibyte characters
- // start with a byte that is not in the ascii range, so we will stop
+ // start with a byte that is not in the ASCII range, so we will stop
// there already.
self.as_bytes().is_ascii()
}
@@ -2638,3 +2640,7 @@ impl_fn_for_zst! {
unsafe { from_utf8_unchecked(bytes) }
};
}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(bootstrap))]
+impl !crate::error::Error for &str {}
diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs
index 04bc66523..2acef432f 100644
--- a/library/core/src/str/validations.rs
+++ b/library/core/src/str/validations.rs
@@ -216,12 +216,12 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
// SAFETY: since `align - index` and `ascii_block_size` are
// multiples of `usize_bytes`, `block = ptr.add(index)` is
// always aligned with a `usize` so it's safe to dereference
- // both `block` and `block.offset(1)`.
+ // both `block` and `block.add(1)`.
unsafe {
let block = ptr.add(index) as *const usize;
// break if there is a nonascii byte
let zu = contains_nonascii(*block);
- let zv = contains_nonascii(*block.offset(1));
+ let zv = contains_nonascii(*block.add(1));
if zu || zv {
break;
}
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 5e2e0c4d8..3c96290fc 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -1554,8 +1554,8 @@ impl<T> AtomicPtr<T> {
/// Offsets the pointer's address by adding `val` *bytes*, returning the
/// previous pointer.
///
- /// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically
- /// perform `ptr = ptr.cast::<u8>().wrapping_add(val).cast::<T>()`.
+ /// This is equivalent to using [`wrapping_byte_add`] to atomically
+ /// perform `ptr = ptr.wrapping_byte_add(val)`.
///
/// `fetch_byte_add` takes an [`Ordering`] argument which describes the
/// memory ordering of this operation. All ordering modes are possible. Note
@@ -1565,8 +1565,7 @@ impl<T> AtomicPtr<T> {
/// **Note**: This method is only available on platforms that support atomic
/// operations on [`AtomicPtr`].
///
- /// [`wrapping_add`]: pointer::wrapping_add
- /// [`cast`]: pointer::cast
+ /// [`wrapping_byte_add`]: pointer::wrapping_byte_add
///
/// # Examples
///
@@ -1584,23 +1583,15 @@ impl<T> AtomicPtr<T> {
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_add(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Offsets the pointer's address by subtracting `val` *bytes*, returning the
/// previous pointer.
///
- /// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically
- /// perform `ptr = ptr.cast::<u8>().wrapping_sub(val).cast::<T>()`.
+ /// This is equivalent to using [`wrapping_byte_sub`] to atomically
+ /// perform `ptr = ptr.wrapping_byte_sub(val)`.
///
/// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
/// memory ordering of this operation. All ordering modes are possible. Note
@@ -1610,8 +1601,7 @@ impl<T> AtomicPtr<T> {
/// **Note**: This method is only available on platforms that support atomic
/// operations on [`AtomicPtr`].
///
- /// [`wrapping_sub`]: pointer::wrapping_sub
- /// [`cast`]: pointer::cast
+ /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub
///
/// # Examples
///
@@ -1628,16 +1618,8 @@ impl<T> AtomicPtr<T> {
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_sub(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Performs a bitwise "or" operation on the address of the current pointer,
@@ -1687,16 +1669,8 @@ impl<T> AtomicPtr<T> {
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_or(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Performs a bitwise "and" operation on the address of the current
@@ -1745,16 +1719,8 @@ impl<T> AtomicPtr<T> {
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_and(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Performs a bitwise "xor" operation on the address of the current
@@ -1801,16 +1767,8 @@ impl<T> AtomicPtr<T> {
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_xor(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
}
@@ -3073,30 +3031,22 @@ unsafe fn atomic_compare_exchange<T: Copy>(
let (val, ok) = unsafe {
match (success, failure) {
(Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
(Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
(Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
(Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
(AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
(AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
(SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
(SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
(SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
(_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
(_, Release) => panic!("there is no such thing as a release failure ordering"),
- #[cfg(bootstrap)]
- _ => panic!("a failure ordering can't be stronger than a success ordering"),
}
};
if ok { Ok(val) } else { Err(val) }
@@ -3116,30 +3066,22 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
let (val, ok) = unsafe {
match (success, failure) {
(Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
(Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
(Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
(Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
(AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
(AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
(SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
(SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
(SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
(_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
(_, Release) => panic!("there is no such thing as a release failure ordering"),
- #[cfg(bootstrap)]
- _ => panic!("a failure ordering can't be stronger than a success ordering"),
}
};
if ok { Ok(val) } else { Err(val) }
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 87d4a25af..60ecc9c0b 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -71,6 +71,12 @@ impl RawWaker {
/// pointer of a properly constructed [`RawWaker`] object from inside the
/// [`RawWaker`] implementation. Calling one of the contained functions using
/// any other `data` pointer will cause undefined behavior.
+///
+/// These functions must all be thread-safe (even though [`RawWaker`] is
+/// <code>\![Send] + \![Sync]</code>)
+/// because [`Waker`] is <code>[Send] + [Sync]</code>, and thus wakers may be moved to
+/// arbitrary threads or invoked by `&` reference. For example, this means that if the
+/// `clone` and `drop` functions manage a reference count, they must do so atomically.
#[stable(feature = "futures_api", since = "1.36.0")]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
@@ -110,6 +116,12 @@ impl RawWakerVTable {
/// Creates a new `RawWakerVTable` from the provided `clone`, `wake`,
/// `wake_by_ref`, and `drop` functions.
///
+ /// These functions must all be thread-safe (even though [`RawWaker`] is
+ /// <code>\![Send] + \![Sync]</code>)
+ /// because [`Waker`] is <code>[Send] + [Sync]</code>, and thus wakers may be moved to
+ /// arbitrary threads or invoked by `&` reference. For example, this means that if the
+ /// `clone` and `drop` functions manage a reference count, they must do so atomically.
+ ///
/// # `clone`
///
/// This function will be called when the [`RawWaker`] gets cloned, e.g. when
@@ -157,9 +169,9 @@ impl RawWakerVTable {
}
}
-/// The `Context` of an asynchronous task.
+/// The context of an asynchronous task.
///
-/// Currently, `Context` only serves to provide access to a `&Waker`
+/// Currently, `Context` only serves to provide access to a [`&Waker`](Waker)
/// which can be used to wake the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Context<'a> {
@@ -172,7 +184,7 @@ pub struct Context<'a> {
}
impl<'a> Context<'a> {
- /// Create a new `Context` from a `&Waker`.
+ /// Create a new `Context` from a [`&Waker`](Waker).
#[stable(feature = "futures_api", since = "1.36.0")]
#[must_use]
#[inline]
@@ -180,7 +192,7 @@ impl<'a> Context<'a> {
Context { waker, _marker: PhantomData }
}
- /// Returns a reference to the `Waker` for the current task.
+ /// Returns a reference to the [`Waker`] for the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
#[must_use]
#[inline]
@@ -202,7 +214,18 @@ impl fmt::Debug for Context<'_> {
/// This handle encapsulates a [`RawWaker`] instance, which defines the
/// executor-specific wakeup behavior.
///
-/// Implements [`Clone`], [`Send`], and [`Sync`].
+/// The typical life of a `Waker` is that it is constructed by an executor, wrapped in a
+/// [`Context`], then passed to [`Future::poll()`]. Then, if the future chooses to return
+/// [`Poll::Pending`], it must also store the waker somehow and call [`Waker::wake()`] when
+/// the future should be polled again.
+///
+/// Implements [`Clone`], [`Send`], and [`Sync`]; therefore, a waker may be invoked
+/// from any thread, including ones not in any way managed by the executor. For example,
+/// this might be done to wake a future when a blocking function call completes on another
+/// thread.
+///
+/// [`Future::poll()`]: core::future::Future::poll
+/// [`Poll::Pending`]: core::task::Poll::Pending
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
@@ -219,18 +242,21 @@ unsafe impl Sync for Waker {}
impl Waker {
/// Wake up the task associated with this `Waker`.
///
- /// As long as the runtime keeps running and the task is not finished, it is
- /// guaranteed that each invocation of `wake` (or `wake_by_ref`) will be followed
- /// by at least one `poll` of the task to which this `Waker` belongs. This makes
+ /// As long as the executor keeps running and the task is not finished, it is
+ /// guaranteed that each invocation of [`wake()`](Self::wake) (or
+ /// [`wake_by_ref()`](Self::wake_by_ref)) will be followed by at least one
+ /// [`poll()`] of the task to which this `Waker` belongs. This makes
/// it possible to temporarily yield to other tasks while running potentially
/// unbounded processing loops.
///
/// Note that the above implies that multiple wake-ups may be coalesced into a
- /// single `poll` invocation by the runtime.
+ /// single [`poll()`] invocation by the runtime.
///
/// Also note that yielding to competing tasks is not guaranteed: it is the
/// executor’s choice which task to run and the executor may choose to run the
/// current task again.
+ ///
+ /// [`poll()`]: crate::future::Future::poll
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn wake(self) {
@@ -250,8 +276,8 @@ impl Waker {
/// Wake up the task associated with this `Waker` without consuming the `Waker`.
///
- /// This is similar to `wake`, but may be slightly less efficient in the case
- /// where an owned `Waker` is available. This method should be preferred to
+ /// This is similar to [`wake()`](Self::wake), but may be slightly less efficient in
+ /// the case where an owned `Waker` is available. This method should be preferred to
/// calling `waker.clone().wake()`.
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
@@ -263,7 +289,7 @@ impl Waker {
unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
}
- /// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
+ /// Returns `true` if this `Waker` and another `Waker` would awake the same task.
///
/// This function works on a best-effort basis, and may return false even
/// when the `Waker`s would awaken the same task. However, if this function
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 756f1a166..4f29ecc0f 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -318,19 +318,11 @@ impl Duration {
/// assert_eq!(duration.as_secs(), 5);
/// ```
///
- /// To determine the total number of seconds represented by the `Duration`,
- /// use `as_secs` in combination with [`subsec_nanos`]:
- ///
- /// ```
- /// use std::time::Duration;
- ///
- /// let duration = Duration::new(5, 730023852);
- ///
- /// assert_eq!(5.730023852,
- /// duration.as_secs() as f64
- /// + duration.subsec_nanos() as f64 * 1e-9);
- /// ```
+ /// To determine the total number of seconds represented by the `Duration`
+ /// including the fractional part, use [`as_secs_f64`] or [`as_secs_f32`]
///
+ /// [`as_secs_f64`]: Duration::as_secs_f64
+ /// [`as_secs_f32`]: Duration::as_secs_f32
/// [`subsec_nanos`]: Duration::subsec_nanos
#[stable(feature = "duration", since = "1.3.0")]
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
@@ -1143,7 +1135,7 @@ impl fmt::Debug for Duration {
// 2. The postfix: can be "µs" so we have to count UTF8 characters.
let mut actual_w = prefix.len() + postfix.chars().count();
// 3. The integer part:
- if let Some(log) = integer_part.checked_log10() {
+ if let Some(log) = integer_part.checked_ilog10() {
// integer_part is > 0, so has length log10(x)+1
actual_w += 1 + log as usize;
} else {
@@ -1288,7 +1280,7 @@ macro_rules! try_from_secs {
let rem_msb = nanos_tmp & rem_msb_mask == 0;
let add_ns = !(rem_msb || (is_even && is_tie));
- // f32 does not have enough presicion to trigger the second branch
+ // f32 does not have enough precision to trigger the second branch
// since it can not represent numbers between 0.999_999_940_395 and 1.0.
let nanos = nanos + add_ns as u32;
if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
@@ -1307,9 +1299,9 @@ macro_rules! try_from_secs {
let rem_msb = nanos_tmp & rem_msb_mask == 0;
let add_ns = !(rem_msb || (is_even && is_tie));
- // f32 does not have enough presicion to trigger the second branch.
+ // f32 does not have enough precision to trigger the second branch.
// For example, it can not represent numbers between 1.999_999_880...
- // and 2.0. Bigger values result in even smaller presicion of the
+ // and 2.0. Bigger values result in even smaller precision of the
// fractional part.
let nanos = nanos + add_ns as u32;
if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index d189e6400..aa8a2425b 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -107,7 +107,7 @@ macro_rules! tuple_impls {
// Otherwise, it hides the docs entirely.
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index d2073f86c..7301da2af 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -1,7 +1,8 @@
///! This file is generated by src/tools/unicode-table-generator; do not edit manually!
+#[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
#[inline(always)]
-fn bitset_search<
+const fn bitset_search<
const N: usize,
const CHUNK_SIZE: usize,
const N1: usize,
@@ -17,14 +18,18 @@ fn bitset_search<
let bucket_idx = (needle / 64) as usize;
let chunk_map_idx = bucket_idx / CHUNK_SIZE;
let chunk_piece = bucket_idx % CHUNK_SIZE;
- let chunk_idx = if let Some(&v) = chunk_idx_map.get(chunk_map_idx) {
- v
+ // FIXME: const-hack: Revert to `slice::get` after `const_slice_index`
+ // feature stabilizes.
+ let chunk_idx = if chunk_map_idx < chunk_idx_map.len() {
+ chunk_idx_map[chunk_map_idx]
} else {
return false;
};
let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize;
- let word = if let Some(word) = bitset_canonical.get(idx) {
- *word
+ // FIXME: const-hack: Revert to `slice::get` after `const_slice_index`
+ // feature stabilizes.
+ let word = if idx < bitset_canonical.len() {
+ bitset_canonical[idx]
} else {
let (real_idx, mapping) = bitset_canonicalized[idx - bitset_canonical.len()];
let mut word = bitset_canonical[real_idx as usize];
@@ -318,14 +323,14 @@ pub mod grapheme_extend {
#[rustfmt::skip]
pub mod lowercase {
- static BITSET_CHUNKS_MAP: [u8; 123] = [
+ const BITSET_CHUNKS_MAP: &'static [u8; 123] = &[
14, 17, 0, 0, 9, 0, 0, 12, 13, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0,
3, 0, 0, 7,
];
- static BITSET_INDEX_CHUNKS: [[u8; 16]; 19] = [
+ const BITSET_INDEX_CHUNKS: &'static [[u8; 16]; 19] = &[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 55, 0],
@@ -346,7 +351,7 @@ pub mod lowercase {
[16, 49, 2, 20, 66, 9, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[63, 39, 54, 12, 73, 61, 18, 1, 6, 62, 71, 19, 68, 69, 3, 44],
];
- static BITSET_CANONICAL: [u64; 55] = [
+ const BITSET_CANONICAL: &'static [u64; 55] = &[
0b0000000000000000000000000000000000000000000000000000000000000000,
0b1111111111111111110000000000000000000000000011111111111111111111,
0b1010101010101010101010101010101010101010101010101010100000000010,
@@ -403,13 +408,14 @@ pub mod lowercase {
0b1110011111111111111111111111111111111111111111110000000000000000,
0b1110101111000000000000000000000000001111111111111111111111111100,
];
- static BITSET_MAPPING: [(u8, u8); 20] = [
+ const BITSET_MAPPING: &'static [(u8, u8); 20] = &[
(0, 64), (1, 188), (1, 183), (1, 176), (1, 109), (1, 124), (1, 126), (1, 66), (1, 70),
(1, 77), (2, 146), (2, 144), (2, 83), (3, 12), (3, 6), (4, 156), (4, 78), (5, 187),
(6, 132), (7, 93),
];
- pub fn lookup(c: char) -> bool {
+ #[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
+ pub const fn lookup(c: char) -> bool {
super::bitset_search(
c as u32,
&BITSET_CHUNKS_MAP,
@@ -454,14 +460,14 @@ pub mod n {
#[rustfmt::skip]
pub mod uppercase {
- static BITSET_CHUNKS_MAP: [u8; 125] = [
+ const BITSET_CHUNKS_MAP: &'static [u8; 125] = &[
12, 15, 6, 6, 0, 6, 6, 2, 4, 11, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 5, 6, 14, 6, 10, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 6, 6,
6, 6, 9, 6, 3,
];
- static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [
+ const BITSET_INDEX_CHUNKS: &'static [[u8; 16]; 17] = &[
[43, 43, 5, 34, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 5, 1],
[43, 43, 5, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
[43, 43, 39, 43, 43, 43, 43, 43, 17, 17, 62, 17, 42, 29, 24, 23],
@@ -480,7 +486,7 @@ pub mod uppercase {
[57, 19, 2, 18, 10, 47, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
[57, 37, 17, 27, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
];
- static BITSET_CANONICAL: [u64; 43] = [
+ const BITSET_CANONICAL: &'static [u64; 43] = &[
0b0000011111111111111111111111111000000000000000000000000000000000,
0b0000000000111111111111111111111111111111111111111111111111111111,
0b0101010101010101010101010101010101010101010101010101010000000001,
@@ -525,13 +531,14 @@ pub mod uppercase {
0b1111011111111111000000000000000000000000000000000000000000000000,
0b1111111100000000111111110000000000111111000000001111111100000000,
];
- static BITSET_MAPPING: [(u8, u8); 25] = [
+ const BITSET_MAPPING: &'static [(u8, u8); 25] = &[
(0, 187), (0, 177), (0, 171), (0, 167), (0, 164), (0, 32), (0, 47), (0, 51), (0, 121),
(0, 117), (0, 109), (1, 150), (1, 148), (1, 142), (1, 134), (1, 131), (1, 64), (2, 164),
(2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171),
];
- pub fn lookup(c: char) -> bool {
+ #[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
+ pub const fn lookup(c: char) -> bool {
super::bitset_search(
c as u32,
&BITSET_CHUNKS_MAP,
@@ -544,18 +551,26 @@ pub mod uppercase {
#[rustfmt::skip]
pub mod white_space {
- static SHORT_OFFSET_RUNS: [u32; 4] = [
- 5760, 18882560, 23080960, 40972289,
- ];
- static OFFSETS: [u8; 21] = [
- 9, 5, 18, 1, 100, 1, 26, 1, 0, 1, 0, 11, 29, 2, 5, 1, 47, 1, 0, 1, 0,
+ static WHITESPACE_MAP: [u8; 256] = [
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
+ #[inline]
pub fn lookup(c: char) -> bool {
- super::skip_search(
- c as u32,
- &SHORT_OFFSET_RUNS,
- &OFFSETS,
- )
+ match c as u32 >> 8 {
+ 0 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0,
+ 22 => c as u32 == 0x1680,
+ 32 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0,
+ 48 => c as u32 == 0x3000,
+ _ => false,
+ }
}
}
diff --git a/library/core/tests/alloc.rs b/library/core/tests/alloc.rs
index 8a5a06b34..3ceaeadce 100644
--- a/library/core/tests/alloc.rs
+++ b/library/core/tests/alloc.rs
@@ -1,4 +1,5 @@
use core::alloc::Layout;
+use core::mem::size_of;
use core::ptr::{self, NonNull};
#[test]
@@ -13,6 +14,49 @@ fn const_unchecked_layout() {
}
#[test]
+fn layout_round_up_to_align_edge_cases() {
+ const MAX_SIZE: usize = isize::MAX as usize;
+
+ for shift in 0..usize::BITS {
+ let align = 1_usize << shift;
+ let edge = (MAX_SIZE + 1) - align;
+ let low = edge.saturating_sub(10);
+ let high = edge.saturating_add(10);
+ assert!(Layout::from_size_align(low, align).is_ok());
+ assert!(Layout::from_size_align(high, align).is_err());
+ for size in low..=high {
+ assert_eq!(
+ Layout::from_size_align(size, align).is_ok(),
+ size.next_multiple_of(align) <= MAX_SIZE,
+ );
+ }
+ }
+}
+
+#[test]
+fn layout_array_edge_cases() {
+ for_type::<i64>();
+ for_type::<[i32; 0b10101]>();
+ for_type::<[u8; 0b1010101]>();
+
+ // Make sure ZSTs don't lead to divide-by-zero
+ assert_eq!(Layout::array::<()>(usize::MAX).unwrap(), Layout::from_size_align(0, 1).unwrap());
+
+ fn for_type<T>() {
+ const MAX_SIZE: usize = isize::MAX as usize;
+
+ let edge = (MAX_SIZE + 1) / size_of::<T>();
+ let low = edge.saturating_sub(10);
+ let high = edge.saturating_add(10);
+ assert!(Layout::array::<T>(low).is_ok());
+ assert!(Layout::array::<T>(high).is_err());
+ for n in low..=high {
+ assert_eq!(Layout::array::<T>(n).is_ok(), n * size_of::<T>() <= MAX_SIZE);
+ }
+ }
+}
+
+#[test]
fn layout_debug_shows_log2_of_alignment() {
// `Debug` is not stable, but here's what it does right now
let layout = Layout::from_size_align(24576, 8192).unwrap();
diff --git a/library/core/tests/any.rs b/library/core/tests/any.rs
index 8ed0c8880..9538b8139 100644
--- a/library/core/tests/any.rs
+++ b/library/core/tests/any.rs
@@ -142,7 +142,7 @@ impl Provider for SomeConcreteType {
demand
.provide_ref::<String>(&self.some_string)
.provide_ref::<str>(&self.some_string)
- .provide_value::<String>(|| "bye".to_owned());
+ .provide_value_with::<String>(|| "bye".to_owned());
}
}
diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs
index 13b12db20..94b031060 100644
--- a/library/core/tests/atomic.rs
+++ b/library/core/tests/atomic.rs
@@ -155,7 +155,7 @@ fn ptr_add_data() {
assert_eq!(atom.fetch_ptr_sub(1, SeqCst), n.wrapping_add(1));
assert_eq!(atom.load(SeqCst), n);
- let bytes_from_n = |b| n.cast::<u8>().wrapping_add(b).cast::<i64>();
+ let bytes_from_n = |b| n.wrapping_byte_add(b);
assert_eq!(atom.fetch_byte_add(1, SeqCst), n);
assert_eq!(atom.load(SeqCst), bytes_from_n(1));
diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs
index 152fed803..d874f0831 100644
--- a/library/core/tests/const_ptr.rs
+++ b/library/core/tests/const_ptr.rs
@@ -3,7 +3,7 @@ const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x
const fn unaligned_ptr() -> *const u16 {
// Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16
- unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 }
+ unsafe { DATA.as_ptr().byte_add(1) }
}
#[test]
@@ -67,7 +67,7 @@ fn write() {
const fn write_unaligned() -> [u16; 2] {
let mut two_aligned = [0u16; 2];
unsafe {
- let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
+ let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1);
ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
}
two_aligned
@@ -91,7 +91,7 @@ fn mut_ptr_write() {
const fn write_unaligned() -> [u16; 2] {
let mut two_aligned = [0u16; 2];
unsafe {
- let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
+ let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1);
unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
}
two_aligned
diff --git a/library/core/tests/iter/adapters/array_chunks.rs b/library/core/tests/iter/adapters/array_chunks.rs
new file mode 100644
index 000000000..4e9d89e1e
--- /dev/null
+++ b/library/core/tests/iter/adapters/array_chunks.rs
@@ -0,0 +1,179 @@
+use core::cell::Cell;
+use core::iter::{self, Iterator};
+
+use super::*;
+
+#[test]
+fn test_iterator_array_chunks_infer() {
+ let xs = [1, 1, 2, -2, 6, 0, 3, 1];
+ for [a, b, c] in xs.iter().copied().array_chunks() {
+ assert_eq!(a + b + c, 4);
+ }
+}
+
+#[test]
+fn test_iterator_array_chunks_clone_and_drop() {
+ let count = Cell::new(0);
+ let mut it = (0..5).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ assert_eq!(it.by_ref().count(), 1);
+ assert_eq!(count.get(), 3);
+ let mut it2 = it.clone();
+ assert_eq!(count.get(), 3);
+ assert_eq!(it.into_remainder().unwrap().len(), 2);
+ assert_eq!(count.get(), 5);
+ assert!(it2.next().is_none());
+ assert_eq!(it2.into_remainder().unwrap().len(), 2);
+ assert_eq!(count.get(), 7);
+}
+
+#[test]
+fn test_iterator_array_chunks_remainder() {
+ let mut it = (0..11).array_chunks::<4>();
+ assert_eq!(it.next(), Some([0, 1, 2, 3]));
+ assert_eq!(it.next(), Some([4, 5, 6, 7]));
+ assert_eq!(it.next(), None);
+ assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_size_hint() {
+ let it = (0..6).array_chunks::<1>();
+ assert_eq!(it.size_hint(), (6, Some(6)));
+
+ let it = (0..6).array_chunks::<3>();
+ assert_eq!(it.size_hint(), (2, Some(2)));
+
+ let it = (0..6).array_chunks::<5>();
+ assert_eq!(it.size_hint(), (1, Some(1)));
+
+ let it = (0..6).array_chunks::<7>();
+ assert_eq!(it.size_hint(), (0, Some(0)));
+
+ let it = (1..).array_chunks::<2>();
+ assert_eq!(it.size_hint(), (usize::MAX / 2, None));
+
+ let it = (1..).filter(|x| x % 2 != 0).array_chunks::<2>();
+ assert_eq!(it.size_hint(), (0, None));
+}
+
+#[test]
+fn test_iterator_array_chunks_count() {
+ let it = (0..6).array_chunks::<1>();
+ assert_eq!(it.count(), 6);
+
+ let it = (0..6).array_chunks::<3>();
+ assert_eq!(it.count(), 2);
+
+ let it = (0..6).array_chunks::<5>();
+ assert_eq!(it.count(), 1);
+
+ let it = (0..6).array_chunks::<7>();
+ assert_eq!(it.count(), 0);
+
+ let it = (0..6).filter(|x| x % 2 == 0).array_chunks::<2>();
+ assert_eq!(it.count(), 1);
+
+ let it = iter::empty::<i32>().array_chunks::<2>();
+ assert_eq!(it.count(), 0);
+
+ let it = [(); usize::MAX].iter().array_chunks::<2>();
+ assert_eq!(it.count(), usize::MAX / 2);
+}
+
+#[test]
+fn test_iterator_array_chunks_next_and_next_back() {
+ let mut it = (0..11).array_chunks::<3>();
+ assert_eq!(it.next(), Some([0, 1, 2]));
+ assert_eq!(it.next_back(), Some([6, 7, 8]));
+ assert_eq!(it.next(), Some([3, 4, 5]));
+ assert_eq!(it.next_back(), None);
+ assert_eq!(it.next(), None);
+ assert_eq!(it.next_back(), None);
+ assert_eq!(it.next(), None);
+ assert_eq!(it.into_remainder().unwrap().as_slice(), &[9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_rev_remainder() {
+ let mut it = (0..11).array_chunks::<4>();
+ {
+ let mut it = it.by_ref().rev();
+ assert_eq!(it.next(), Some([4, 5, 6, 7]));
+ assert_eq!(it.next(), Some([0, 1, 2, 3]));
+ assert_eq!(it.next(), None);
+ assert_eq!(it.next(), None);
+ }
+ assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_try_fold() {
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result: Result<_, ()> = it.by_ref().try_fold(0, |acc, _item| Ok(acc + 1));
+ assert_eq!(result, Ok(3));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 10);
+
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result = it.by_ref().try_fold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) });
+ assert_eq!(result, Err(2));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 9);
+}
+
+#[test]
+fn test_iterator_array_chunks_fold() {
+ let result = (1..11).array_chunks::<3>().fold(0, |acc, [a, b, c]| {
+ assert_eq!(acc + 1, a);
+ assert_eq!(acc + 2, b);
+ assert_eq!(acc + 3, c);
+ acc + 3
+ });
+ assert_eq!(result, 9);
+
+ let count = Cell::new(0);
+ let result =
+ (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().fold(0, |acc, _item| acc + 1);
+ assert_eq!(result, 3);
+ assert_eq!(count.get(), 10);
+}
+
+#[test]
+fn test_iterator_array_chunks_try_rfold() {
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result: Result<_, ()> = it.try_rfold(0, |acc, _item| Ok(acc + 1));
+ assert_eq!(result, Ok(3));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 10);
+
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result = it.try_rfold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) });
+ assert_eq!(result, Err(2));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 10);
+}
+
+#[test]
+fn test_iterator_array_chunks_rfold() {
+ let result = (1..11).array_chunks::<3>().rfold(0, |acc, [a, b, c]| {
+ assert_eq!(10 - (acc + 1), c);
+ assert_eq!(10 - (acc + 2), b);
+ assert_eq!(10 - (acc + 3), a);
+ acc + 3
+ });
+ assert_eq!(result, 9);
+
+ let count = Cell::new(0);
+ let result =
+ (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().rfold(0, |acc, _item| acc + 1);
+ assert_eq!(result, 3);
+ assert_eq!(count.get(), 10);
+}
diff --git a/library/core/tests/iter/adapters/by_ref_sized.rs b/library/core/tests/iter/adapters/by_ref_sized.rs
new file mode 100644
index 000000000..a9c066f0e
--- /dev/null
+++ b/library/core/tests/iter/adapters/by_ref_sized.rs
@@ -0,0 +1,20 @@
+use core::iter::*;
+
+#[test]
+fn test_iterator_by_ref_sized() {
+ let a = ['a', 'b', 'c', 'd'];
+
+ let mut s = String::from("Z");
+ let mut it = a.iter().copied();
+ ByRefSized(&mut it).take(2).for_each(|x| s.push(x));
+ assert_eq!(s, "Zab");
+ ByRefSized(&mut it).fold((), |(), x| s.push(x));
+ assert_eq!(s, "Zabcd");
+
+ let mut s = String::from("Z");
+ let mut it = a.iter().copied();
+ ByRefSized(&mut it).rev().take(2).for_each(|x| s.push(x));
+ assert_eq!(s, "Zdc");
+ ByRefSized(&mut it).rfold((), |(), x| s.push(x));
+ assert_eq!(s, "Zdcba");
+}
diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs
index f8ab8c9d4..690fd0c21 100644
--- a/library/core/tests/iter/adapters/flatten.rs
+++ b/library/core/tests/iter/adapters/flatten.rs
@@ -168,3 +168,45 @@ fn test_trusted_len_flatten() {
assert_trusted_len(&iter);
assert_eq!(iter.size_hint(), (20, Some(20)));
}
+
+#[test]
+fn test_flatten_count() {
+ let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
+
+ assert_eq!(it.clone().count(), 40);
+ it.advance_by(5).unwrap();
+ assert_eq!(it.clone().count(), 35);
+ it.advance_back_by(5).unwrap();
+ assert_eq!(it.clone().count(), 30);
+ it.advance_by(10).unwrap();
+ assert_eq!(it.clone().count(), 20);
+ it.advance_back_by(8).unwrap();
+ assert_eq!(it.clone().count(), 12);
+ it.advance_by(4).unwrap();
+ assert_eq!(it.clone().count(), 8);
+ it.advance_back_by(5).unwrap();
+ assert_eq!(it.clone().count(), 3);
+ it.advance_by(3).unwrap();
+ assert_eq!(it.clone().count(), 0);
+}
+
+#[test]
+fn test_flatten_last() {
+ let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
+
+ assert_eq!(it.clone().last(), Some(39));
+ it.advance_by(5).unwrap(); // 5..40
+ assert_eq!(it.clone().last(), Some(39));
+ it.advance_back_by(5).unwrap(); // 5..35
+ assert_eq!(it.clone().last(), Some(34));
+ it.advance_by(10).unwrap(); // 15..35
+ assert_eq!(it.clone().last(), Some(34));
+ it.advance_back_by(8).unwrap(); // 15..27
+ assert_eq!(it.clone().last(), Some(26));
+ it.advance_by(4).unwrap(); // 19..27
+ assert_eq!(it.clone().last(), Some(26));
+ it.advance_back_by(5).unwrap(); // 19..22
+ assert_eq!(it.clone().last(), Some(21));
+ it.advance_by(3).unwrap(); // 22..22
+ assert_eq!(it.clone().last(), None);
+}
diff --git a/library/core/tests/iter/adapters/mod.rs b/library/core/tests/iter/adapters/mod.rs
index 567d9fe49..ffd5f3857 100644
--- a/library/core/tests/iter/adapters/mod.rs
+++ b/library/core/tests/iter/adapters/mod.rs
@@ -1,3 +1,5 @@
+mod array_chunks;
+mod by_ref_sized;
mod chain;
mod cloned;
mod copied;
@@ -183,3 +185,25 @@ impl Clone for CountClone {
ret
}
}
+
+#[derive(Debug, Clone)]
+struct CountDrop<'a> {
+ dropped: bool,
+ count: &'a Cell<usize>,
+}
+
+impl<'a> CountDrop<'a> {
+ pub fn new(count: &'a Cell<usize>) -> Self {
+ Self { dropped: false, count }
+ }
+}
+
+impl Drop for CountDrop<'_> {
+ fn drop(&mut self) {
+ if self.dropped {
+ panic!("double drop");
+ }
+ self.dropped = true;
+ self.count.set(self.count.get() + 1);
+ }
+}
diff --git a/library/core/tests/iter/adapters/skip.rs b/library/core/tests/iter/adapters/skip.rs
index 65f235e86..754641834 100644
--- a/library/core/tests/iter/adapters/skip.rs
+++ b/library/core/tests/iter/adapters/skip.rs
@@ -201,3 +201,34 @@ fn test_skip_non_fused() {
// advance it further. `Unfuse` tests that this doesn't happen by panicking in that scenario.
let _ = non_fused.skip(20).next();
}
+
+#[test]
+fn test_skip_non_fused_nth_overflow() {
+ let non_fused = Unfuse::new(0..10);
+
+ // Ensures that calling skip and `nth` where the sum would overflow does not fail for non-fused
+ // iterators.
+ let _ = non_fused.skip(20).nth(usize::MAX);
+}
+
+#[test]
+fn test_skip_overflow_wrapping() {
+ // Test to ensure even on overflowing on `skip+nth` the correct amount of elements are yielded.
+ struct WrappingIterator(usize);
+
+ impl Iterator for WrappingIterator {
+ type Item = usize;
+
+ fn next(&mut self) -> core::option::Option<Self::Item> {
+ <Self as Iterator>::nth(self, 0)
+ }
+
+ fn nth(&mut self, nth: usize) -> core::option::Option<Self::Item> {
+ self.0 = self.0.wrapping_add(nth.wrapping_add(1));
+ Some(self.0)
+ }
+ }
+
+ let wrap = WrappingIterator(0);
+ assert_eq!(wrap.skip(20).nth(usize::MAX), Some(20));
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index db94368f6..4a0e162bc 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -3,6 +3,7 @@
#![feature(array_methods)]
#![feature(array_windows)]
#![feature(bench_black_box)]
+#![feature(bigint_helper_methods)]
#![feature(cell_update)]
#![feature(const_assume)]
#![feature(const_black_box)]
@@ -14,6 +15,7 @@
#![feature(const_maybe_uninit_assume_init_read)]
#![feature(const_nonnull_new)]
#![feature(const_num_from_num)]
+#![feature(const_pointer_byte_offsets)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_read)]
#![feature(const_ptr_write)]
@@ -61,6 +63,7 @@
#![feature(slice_partition_dedup)]
#![feature(int_log)]
#![feature(iter_advance_by)]
+#![feature(iter_array_chunks)]
#![feature(iter_collect_into)]
#![feature(iter_partition_in_place)]
#![feature(iter_intersperse)]
@@ -73,7 +76,7 @@
#![feature(const_pin)]
#![feature(never_type)]
#![feature(unwrap_infallible)]
-#![feature(result_into_ok_or_err)]
+#![feature(pointer_byte_offsets)]
#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(once_cell)]
@@ -96,6 +99,7 @@
#![feature(waker_getters)]
#![feature(slice_flatten)]
#![feature(provide_any)]
+#![feature(utf8_chunks)]
#![deny(unsafe_op_in_unsafe_fn)]
extern crate test;
diff --git a/library/core/tests/num/int_log.rs b/library/core/tests/num/int_log.rs
index dc3092e14..be203fb5c 100644
--- a/library/core/tests/num/int_log.rs
+++ b/library/core/tests/num/int_log.rs
@@ -1,166 +1,166 @@
-//! This tests the `Integer::{log,log2,log10}` methods. These tests are in a
+//! This tests the `Integer::{ilog,log2,log10}` methods. These tests are in a
//! separate file because there's both a large number of them, and not all tests
-//! can be run on Android. This is because in Android `log2` uses an imprecise
+//! can be run on Android. This is because in Android `ilog2` uses an imprecise
//! approximation:https://github.com/rust-lang/rust/blob/4825e12fc9c79954aa0fe18f5521efa6c19c7539/src/libstd/sys/unix/android.rs#L27-L53
#[test]
-fn checked_log() {
- assert_eq!(999u32.checked_log(10), Some(2));
- assert_eq!(1000u32.checked_log(10), Some(3));
- assert_eq!(555u32.checked_log(13), Some(2));
- assert_eq!(63u32.checked_log(4), Some(2));
- assert_eq!(64u32.checked_log(4), Some(3));
- assert_eq!(10460353203u64.checked_log(3), Some(21));
- assert_eq!(10460353202u64.checked_log(3), Some(20));
- assert_eq!(147808829414345923316083210206383297601u128.checked_log(3), Some(80));
- assert_eq!(147808829414345923316083210206383297600u128.checked_log(3), Some(79));
- assert_eq!(22528399544939174411840147874772641u128.checked_log(19683), Some(8));
- assert_eq!(22528399544939174411840147874772631i128.checked_log(19683), Some(7));
-
- assert_eq!(0u8.checked_log(4), None);
- assert_eq!(0u16.checked_log(4), None);
- assert_eq!(0i8.checked_log(4), None);
- assert_eq!(0i16.checked_log(4), None);
+fn checked_ilog() {
+ assert_eq!(999u32.checked_ilog(10), Some(2));
+ assert_eq!(1000u32.checked_ilog(10), Some(3));
+ assert_eq!(555u32.checked_ilog(13), Some(2));
+ assert_eq!(63u32.checked_ilog(4), Some(2));
+ assert_eq!(64u32.checked_ilog(4), Some(3));
+ assert_eq!(10460353203u64.checked_ilog(3), Some(21));
+ assert_eq!(10460353202u64.checked_ilog(3), Some(20));
+ assert_eq!(147808829414345923316083210206383297601u128.checked_ilog(3), Some(80));
+ assert_eq!(147808829414345923316083210206383297600u128.checked_ilog(3), Some(79));
+ assert_eq!(22528399544939174411840147874772641u128.checked_ilog(19683), Some(8));
+ assert_eq!(22528399544939174411840147874772631i128.checked_ilog(19683), Some(7));
+
+ assert_eq!(0u8.checked_ilog(4), None);
+ assert_eq!(0u16.checked_ilog(4), None);
+ assert_eq!(0i8.checked_ilog(4), None);
+ assert_eq!(0i16.checked_ilog(4), None);
#[cfg(not(miri))] // Miri is too slow
for i in i16::MIN..=0 {
- assert_eq!(i.checked_log(4), None);
+ assert_eq!(i.checked_ilog(4), None);
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=i16::MAX {
- assert_eq!(i.checked_log(13), Some((i as f32).log(13.0) as u32));
+ assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32));
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=u16::MAX {
- assert_eq!(i.checked_log(13), Some((i as f32).log(13.0) as u32));
+ assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32));
}
}
#[test]
-fn checked_log2() {
- assert_eq!(5u32.checked_log2(), Some(2));
- assert_eq!(0u64.checked_log2(), None);
- assert_eq!(128i32.checked_log2(), Some(7));
- assert_eq!((-55i16).checked_log2(), None);
+fn checked_ilog2() {
+ assert_eq!(5u32.checked_ilog2(), Some(2));
+ assert_eq!(0u64.checked_ilog2(), None);
+ assert_eq!(128i32.checked_ilog2(), Some(7));
+ assert_eq!((-55i16).checked_ilog2(), None);
- assert_eq!(0u8.checked_log2(), None);
- assert_eq!(0u16.checked_log2(), None);
- assert_eq!(0i8.checked_log2(), None);
- assert_eq!(0i16.checked_log2(), None);
+ assert_eq!(0u8.checked_ilog2(), None);
+ assert_eq!(0u16.checked_ilog2(), None);
+ assert_eq!(0i8.checked_ilog2(), None);
+ assert_eq!(0i16.checked_ilog2(), None);
for i in 1..=u8::MAX {
- assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32));
+ assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=u16::MAX {
- // Guard against Android's imprecise f32::log2 implementation.
+ // Guard against Android's imprecise f32::ilog2 implementation.
if i != 8192 && i != 32768 {
- assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32));
+ assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
}
}
for i in i8::MIN..=0 {
- assert_eq!(i.checked_log2(), None);
+ assert_eq!(i.checked_ilog2(), None);
}
for i in 1..=i8::MAX {
- assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32));
+ assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
}
#[cfg(not(miri))] // Miri is too slow
for i in i16::MIN..=0 {
- assert_eq!(i.checked_log2(), None);
+ assert_eq!(i.checked_ilog2(), None);
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=i16::MAX {
- // Guard against Android's imprecise f32::log2 implementation.
+ // Guard against Android's imprecise f32::ilog2 implementation.
if i != 8192 {
- assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32));
+ assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
}
}
}
-// Validate cases that fail on Android's imprecise float log2 implementation.
+// Validate cases that fail on Android's imprecise float ilog2 implementation.
#[test]
#[cfg(not(target_os = "android"))]
-fn checked_log2_not_android() {
- assert_eq!(8192u16.checked_log2(), Some((8192f32).log2() as u32));
- assert_eq!(32768u16.checked_log2(), Some((32768f32).log2() as u32));
- assert_eq!(8192i16.checked_log2(), Some((8192f32).log2() as u32));
+fn checked_ilog2_not_android() {
+ assert_eq!(8192u16.checked_ilog2(), Some((8192f32).log2() as u32));
+ assert_eq!(32768u16.checked_ilog2(), Some((32768f32).log2() as u32));
+ assert_eq!(8192i16.checked_ilog2(), Some((8192f32).log2() as u32));
}
#[test]
-fn checked_log10() {
- assert_eq!(0u8.checked_log10(), None);
- assert_eq!(0u16.checked_log10(), None);
- assert_eq!(0i8.checked_log10(), None);
- assert_eq!(0i16.checked_log10(), None);
+fn checked_ilog10() {
+ assert_eq!(0u8.checked_ilog10(), None);
+ assert_eq!(0u16.checked_ilog10(), None);
+ assert_eq!(0i8.checked_ilog10(), None);
+ assert_eq!(0i16.checked_ilog10(), None);
#[cfg(not(miri))] // Miri is too slow
for i in i16::MIN..=0 {
- assert_eq!(i.checked_log10(), None);
+ assert_eq!(i.checked_ilog10(), None);
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=i16::MAX {
- assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32));
+ assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32));
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=u16::MAX {
- assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32));
+ assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32));
}
#[cfg(not(miri))] // Miri is too slow
for i in 1..=100_000u32 {
- assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32));
+ assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32));
}
}
-macro_rules! log10_loop {
- ($T:ty, $log10_max:expr) => {
- assert_eq!(<$T>::MAX.log10(), $log10_max);
- for i in 0..=$log10_max {
+macro_rules! ilog10_loop {
+ ($T:ty, $ilog10_max:expr) => {
+ assert_eq!(<$T>::MAX.ilog10(), $ilog10_max);
+ for i in 0..=$ilog10_max {
let p = (10 as $T).pow(i as u32);
if p >= 10 {
- assert_eq!((p - 9).log10(), i - 1);
- assert_eq!((p - 1).log10(), i - 1);
+ assert_eq!((p - 9).ilog10(), i - 1);
+ assert_eq!((p - 1).ilog10(), i - 1);
}
- assert_eq!(p.log10(), i);
- assert_eq!((p + 1).log10(), i);
+ assert_eq!(p.ilog10(), i);
+ assert_eq!((p + 1).ilog10(), i);
if p >= 10 {
- assert_eq!((p + 9).log10(), i);
+ assert_eq!((p + 9).ilog10(), i);
}
- // also check `x.log(10)`
+ // also check `x.ilog(10)`
if p >= 10 {
- assert_eq!((p - 9).log(10), i - 1);
- assert_eq!((p - 1).log(10), i - 1);
+ assert_eq!((p - 9).ilog(10), i - 1);
+ assert_eq!((p - 1).ilog(10), i - 1);
}
- assert_eq!(p.log(10), i);
- assert_eq!((p + 1).log(10), i);
+ assert_eq!(p.ilog(10), i);
+ assert_eq!((p + 1).ilog(10), i);
if p >= 10 {
- assert_eq!((p + 9).log(10), i);
+ assert_eq!((p + 9).ilog(10), i);
}
}
};
}
#[test]
-fn log10_u8() {
- log10_loop! { u8, 2 }
+fn ilog10_u8() {
+ ilog10_loop! { u8, 2 }
}
#[test]
-fn log10_u16() {
- log10_loop! { u16, 4 }
+fn ilog10_u16() {
+ ilog10_loop! { u16, 4 }
}
#[test]
-fn log10_u32() {
- log10_loop! { u32, 9 }
+fn ilog10_u32() {
+ ilog10_loop! { u32, 9 }
}
#[test]
-fn log10_u64() {
- log10_loop! { u64, 19 }
+fn ilog10_u64() {
+ ilog10_loop! { u64, 19 }
}
#[test]
-fn log10_u128() {
- log10_loop! { u128, 38 }
+fn ilog10_u128() {
+ ilog10_loop! { u128, 38 }
}
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
index 8b84a78e6..18c55e43a 100644
--- a/library/core/tests/num/int_macros.rs
+++ b/library/core/tests/num/int_macros.rs
@@ -338,6 +338,32 @@ macro_rules! int_module {
assert_eq!(MIN.checked_next_multiple_of(-3), None);
assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN));
}
+
+ #[test]
+ fn test_carrying_add() {
+ assert_eq!($T::MAX.carrying_add(1, false), ($T::MIN, true));
+ assert_eq!($T::MAX.carrying_add(0, true), ($T::MIN, true));
+ assert_eq!($T::MAX.carrying_add(1, true), ($T::MIN + 1, true));
+ assert_eq!($T::MAX.carrying_add(-1, false), ($T::MAX - 1, false));
+ assert_eq!($T::MAX.carrying_add(-1, true), ($T::MAX, false)); // no intermediate overflow
+ assert_eq!($T::MIN.carrying_add(-1, false), ($T::MAX, true));
+ assert_eq!($T::MIN.carrying_add(-1, true), ($T::MIN, false)); // no intermediate overflow
+ assert_eq!((0 as $T).carrying_add($T::MAX, true), ($T::MIN, true));
+ assert_eq!((0 as $T).carrying_add($T::MIN, true), ($T::MIN + 1, false));
+ }
+
+ #[test]
+ fn test_borrowing_sub() {
+ assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
+ assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
+ assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
+ assert_eq!($T::MIN.borrowing_sub(-1, false), ($T::MIN + 1, false));
+ assert_eq!($T::MIN.borrowing_sub(-1, true), ($T::MIN, false)); // no intermediate overflow
+ assert_eq!($T::MAX.borrowing_sub(-1, false), ($T::MIN, true));
+ assert_eq!($T::MAX.borrowing_sub(-1, true), ($T::MAX, false)); // no intermediate overflow
+ assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true));
+ assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false));
+ }
}
};
}
diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs
index 93ae620c2..15ae9f232 100644
--- a/library/core/tests/num/uint_macros.rs
+++ b/library/core/tests/num/uint_macros.rs
@@ -230,6 +230,28 @@ macro_rules! uint_module {
assert_eq!((1 as $T).checked_next_multiple_of(0), None);
assert_eq!(MAX.checked_next_multiple_of(2), None);
}
+
+ #[test]
+ fn test_carrying_add() {
+ assert_eq!($T::MAX.carrying_add(1, false), (0, true));
+ assert_eq!($T::MAX.carrying_add(0, true), (0, true));
+ assert_eq!($T::MAX.carrying_add(1, true), (1, true));
+
+ assert_eq!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
+ assert_eq!($T::MIN.carrying_add(0, true), (1, false));
+ assert_eq!($T::MIN.carrying_add($T::MAX, true), (0, true));
+ }
+
+ #[test]
+ fn test_borrowing_sub() {
+ assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
+ assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
+ assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
+
+ assert_eq!($T::MAX.borrowing_sub($T::MAX, false), (0, false));
+ assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
+ assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
+ }
}
};
}
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index 12861794c..97a369810 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -650,7 +650,7 @@ fn thin_box() {
.unwrap_or_else(|| handle_alloc_error(layout))
.cast::<DynMetadata<T>>();
ptr.as_ptr().write(meta);
- ptr.cast::<u8>().as_ptr().add(offset).cast::<Value>().write(value);
+ ptr.as_ptr().byte_add(offset).cast::<Value>().write(value);
Self { ptr, phantom: PhantomData }
}
}
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index 103e8cc3a..50926da3c 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -96,15 +96,6 @@ fn test_unwrap_or() {
}
#[test]
-fn test_ok_or_err() {
- let ok: Result<isize, isize> = Ok(100);
- let err: Result<isize, isize> = Err(200);
-
- assert_eq!(ok.into_ok_or_err(), 100);
- assert_eq!(err.into_ok_or_err(), 200);
-}
-
-#[test]
fn test_unwrap_or_else() {
fn handler(msg: &'static str) -> isize {
if msg == "I got this." { 50 } else { panic!("BadBad") }
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 0656109e9..b8f6fe696 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -1197,7 +1197,6 @@ fn chunks_mut_are_send_and_sync() {
use std::slice::{ChunksExactMut, ChunksMut, RChunksExactMut, RChunksMut};
use std::sync::MutexGuard;
- #[allow(unused)]
fn assert_send_and_sync()
where
ChunksMut<'static, Cell<i32>>: Send,
@@ -1210,6 +1209,8 @@ fn chunks_mut_are_send_and_sync() {
RChunksExactMut<'static, MutexGuard<'static, u32>>: Sync,
{
}
+
+ assert_send_and_sync();
}
#[test]
diff --git a/library/core/tests/str_lossy.rs b/library/core/tests/str_lossy.rs
index d4b47a470..9d3f0b65f 100644
--- a/library/core/tests/str_lossy.rs
+++ b/library/core/tests/str_lossy.rs
@@ -1,85 +1,85 @@
-use core::str::lossy::*;
+use core::str::Utf8Chunks;
#[test]
fn chunks() {
- let mut iter = Utf8Lossy::from_bytes(b"hello").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
+ macro_rules! assert_chunks {
+ ( $string:expr, $(($valid:expr, $invalid:expr)),* $(,)? ) => {{
+ let mut iter = Utf8Chunks::new($string);
+ $(
+ let chunk = iter.next().expect("missing chunk");
+ assert_eq!($valid, chunk.valid());
+ assert_eq!($invalid, chunk.invalid());
+ )*
+ assert_eq!(None, iter.next());
+ }};
+ }
- let mut iter = Utf8Lossy::from_bytes("ศไทย中åŽViệt Nam".as_bytes()).chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "ศไทย中åŽViệt Nam", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-
- let mut iter = Utf8Lossy::from_bytes(b"Hello\xC2 There\xFF Goodbye").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC2" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xFF" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-
- let mut iter = Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC0" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xE6\x83" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-
- let mut iter = Utf8Lossy::from_bytes(b"\xF5foo\xF5\x80bar").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF5" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF5" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-
- let mut iter = Utf8Lossy::from_bytes(b"\xF1foo\xF1\x80bar\xF1\x80\x80baz").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF1" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF1\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF1\x80\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-
- let mut iter = Utf8Lossy::from_bytes(b"\xF4foo\xF4\x80bar\xF4\xBFbaz").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF4" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF4\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF4" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-
- let mut iter = Utf8Lossy::from_bytes(b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF0" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo\u{10000}bar", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
+ assert_chunks!(b"hello", ("hello", b""));
+ assert_chunks!("ศไทย中åŽViệt Nam".as_bytes(), ("ศไทย中åŽViệt Nam", b""));
+ assert_chunks!(
+ b"Hello\xC2 There\xFF Goodbye",
+ ("Hello", b"\xC2"),
+ (" There", b"\xFF"),
+ (" Goodbye", b""),
+ );
+ assert_chunks!(
+ b"Hello\xC0\x80 There\xE6\x83 Goodbye",
+ ("Hello", b"\xC0"),
+ ("", b"\x80"),
+ (" There", b"\xE6\x83"),
+ (" Goodbye", b""),
+ );
+ assert_chunks!(
+ b"\xF5foo\xF5\x80bar",
+ ("", b"\xF5"),
+ ("foo", b"\xF5"),
+ ("", b"\x80"),
+ ("bar", b""),
+ );
+ assert_chunks!(
+ b"\xF1foo\xF1\x80bar\xF1\x80\x80baz",
+ ("", b"\xF1"),
+ ("foo", b"\xF1\x80"),
+ ("bar", b"\xF1\x80\x80"),
+ ("baz", b""),
+ );
+ assert_chunks!(
+ b"\xF4foo\xF4\x80bar\xF4\xBFbaz",
+ ("", b"\xF4"),
+ ("foo", b"\xF4\x80"),
+ ("bar", b"\xF4"),
+ ("", b"\xBF"),
+ ("baz", b""),
+ );
+ assert_chunks!(
+ b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar",
+ ("", b"\xF0"),
+ ("", b"\x80"),
+ ("", b"\x80"),
+ ("", b"\x80"),
+ ("foo\u{10000}bar", b""),
+ );
// surrogates
- let mut iter = Utf8Lossy::from_bytes(b"\xED\xA0\x80foo\xED\xBF\xBFbar").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xED" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xA0" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xED" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next());
- assert_eq!(None, iter.next());
-}
-
-#[test]
-fn display() {
- assert_eq!(
- "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye",
- &Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
+ assert_chunks!(
+ b"\xED\xA0\x80foo\xED\xBF\xBFbar",
+ ("", b"\xED"),
+ ("", b"\xA0"),
+ ("", b"\x80"),
+ ("foo", b"\xED"),
+ ("", b"\xBF"),
+ ("", b"\xBF"),
+ ("bar", b""),
);
}
#[test]
fn debug() {
assert_eq!(
- "\"Hello\\xc0\\x80 There\\xe6\\x83 Goodbye\\u{10d4ea}\"",
+ "\"Hello\\xC0\\x80 There\\xE6\\x83 Goodbye\\u{10d4ea}\"",
&format!(
"{:?}",
- Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa")
- )
+ Utf8Chunks::new(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa").debug(),
+ ),
);
}
diff --git a/library/panic_abort/src/android.rs b/library/panic_abort/src/android.rs
index 18bb932f1..0fd824f8a 100644
--- a/library/panic_abort/src/android.rs
+++ b/library/panic_abort/src/android.rs
@@ -42,7 +42,7 @@ pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) {
return; // allocation failure
}
copy_nonoverlapping(msg.as_ptr(), buf as *mut u8, msg.len());
- buf.offset(msg.len() as isize).write(0);
+ buf.add(msg.len()).write(0);
let func = transmute::<usize, SetAbortMessageType>(func_addr);
func(buf);
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index 8801c670b..cba8ef25d 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -113,27 +113,11 @@ pub unsafe fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 {
// binaries, but it should never be called as we don't link in an unwinding
// runtime at all.
pub mod personalities {
- #[rustc_std_internal_symbol]
- #[cfg(not(any(
- all(target_family = "wasm", not(target_os = "emscripten")),
- all(target_os = "windows", target_env = "gnu", target_arch = "x86_64",),
- )))]
- pub extern "C" fn rust_eh_personality() {}
-
- // On x86_64-pc-windows-gnu we use our own personality function that needs
- // to return `ExceptionContinueSearch` as we're passing on all our frames.
- #[rustc_std_internal_symbol]
- #[cfg(all(target_os = "windows", target_env = "gnu", target_arch = "x86_64"))]
- pub extern "C" fn rust_eh_personality(
- _record: usize,
- _frame: usize,
- _context: usize,
- _dispatcher: usize,
- ) -> u32 {
- 1 // `ExceptionContinueSearch`
- }
+ // In the past this module used to contain stubs for the personality
+ // functions of various platforms, but these where removed when personality
+ // functions were moved to std.
- // Similar to above, this corresponds to the `eh_catch_typeinfo` lang item
+ // This corresponds to the `eh_catch_typeinfo` lang item
// that's only used on Emscripten currently.
//
// Since panics don't generate exceptions and foreign exceptions are
@@ -143,13 +127,4 @@ pub mod personalities {
#[allow(non_upper_case_globals)]
#[cfg(target_os = "emscripten")]
static rust_eh_catch_typeinfo: [usize; 2] = [0; 2];
-
- // These two are called by our startup objects on i686-pc-windows-gnu, but
- // they don't need to do anything so the bodies are nops.
- #[rustc_std_internal_symbol]
- #[cfg(all(target_os = "windows", target_env = "gnu", target_arch = "x86"))]
- pub extern "C" fn rust_eh_register_frames() {}
- #[rustc_std_internal_symbol]
- #[cfg(all(target_os = "windows", target_env = "gnu", target_arch = "x86"))]
- pub extern "C" fn rust_eh_unregister_frames() {}
}
diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs
index 1ee69ff9c..7c233c7c3 100644
--- a/library/panic_unwind/src/emcc.rs
+++ b/library/panic_unwind/src/emcc.rs
@@ -12,7 +12,6 @@ use core::intrinsics;
use core::mem;
use core::ptr;
use core::sync::atomic::{AtomicBool, Ordering};
-use libc::{self, c_int};
use unwind as uw;
// This matches the layout of std::type_info in C++
@@ -105,21 +104,6 @@ extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> *mut libc::c_void {
}
}
-// This is required by the compiler to exist (e.g., it's a lang item), but it's
-// never actually called by the compiler. Emscripten EH doesn't use a
-// personality function at all, it instead uses __cxa_find_matching_catch.
-// Wasm error handling would use __gxx_personality_wasm0.
-#[lang = "eh_personality"]
-unsafe extern "C" fn rust_eh_personality(
- _version: c_int,
- _actions: uw::_Unwind_Action,
- _exception_class: uw::_Unwind_Exception_Class,
- _exception_object: *mut uw::_Unwind_Exception,
- _context: *mut uw::_Unwind_Context,
-) -> uw::_Unwind_Reason_Code {
- core::intrinsics::abort()
-}
-
extern "C" {
fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void;
fn __cxa_begin_catch(thrown_exception: *mut libc::c_void) -> *mut libc::c_void;
diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs
index a59659231..261404e87 100644
--- a/library/panic_unwind/src/gcc.rs
+++ b/library/panic_unwind/src/gcc.rs
@@ -39,8 +39,6 @@
use alloc::boxed::Box;
use core::any::Any;
-use crate::dwarf::eh::{self, EHAction, EHContext};
-use libc::{c_int, uintptr_t};
use unwind as uw;
#[repr(C)]
@@ -89,263 +87,3 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
// M O Z \0 R U S T -- vendor, language
0x4d4f5a_00_52555354
}
-
-// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
-// and TargetLowering::getExceptionSelectorRegister() for each architecture,
-// then mapped to DWARF register numbers via register definition tables
-// (typically <arch>RegisterInfo.td, search for "DwarfRegNum").
-// See also https://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register.
-
-#[cfg(target_arch = "x86")]
-const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX
-
-#[cfg(target_arch = "x86_64")]
-const UNWIND_DATA_REG: (i32, i32) = (0, 1); // RAX, RDX
-
-#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
-const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1
-
-#[cfg(target_arch = "m68k")]
-const UNWIND_DATA_REG: (i32, i32) = (0, 1); // D0, D1
-
-#[cfg(any(target_arch = "mips", target_arch = "mips64"))]
-const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1
-
-#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
-const UNWIND_DATA_REG: (i32, i32) = (3, 4); // R3, R4 / X3, X4
-
-#[cfg(target_arch = "s390x")]
-const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7
-
-#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
-const UNWIND_DATA_REG: (i32, i32) = (24, 25); // I0, I1
-
-#[cfg(target_arch = "hexagon")]
-const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1
-
-#[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
-const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
-
-// The following code is based on GCC's C and C++ personality routines. For reference, see:
-// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
-// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
-
-cfg_if::cfg_if! {
- if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "watchos"), not(target_os = "netbsd")))] {
- // ARM EHABI personality routine.
- // https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
- //
- // iOS uses the default routine instead since it uses SjLj unwinding.
- #[lang = "eh_personality"]
- unsafe extern "C" fn rust_eh_personality(state: uw::_Unwind_State,
- exception_object: *mut uw::_Unwind_Exception,
- context: *mut uw::_Unwind_Context)
- -> uw::_Unwind_Reason_Code {
- let state = state as c_int;
- let action = state & uw::_US_ACTION_MASK as c_int;
- let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
- // Backtraces on ARM will call the personality routine with
- // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
- // we want to continue unwinding the stack, otherwise all our backtraces
- // would end at __rust_try
- if state & uw::_US_FORCE_UNWIND as c_int != 0 {
- return continue_unwind(exception_object, context);
- }
- true
- } else if action == uw::_US_UNWIND_FRAME_STARTING as c_int {
- false
- } else if action == uw::_US_UNWIND_FRAME_RESUME as c_int {
- return continue_unwind(exception_object, context);
- } else {
- return uw::_URC_FAILURE;
- };
-
- // The DWARF unwinder assumes that _Unwind_Context holds things like the function
- // and LSDA pointers, however ARM EHABI places them into the exception object.
- // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
- // take only the context pointer, GCC personality routines stash a pointer to
- // exception_object in the context, using location reserved for ARM's
- // "scratch register" (r12).
- uw::_Unwind_SetGR(context,
- uw::UNWIND_POINTER_REG,
- exception_object as uw::_Unwind_Ptr);
- // ...A more principled approach would be to provide the full definition of ARM's
- // _Unwind_Context in our libunwind bindings and fetch the required data from there
- // directly, bypassing DWARF compatibility functions.
-
- let eh_action = match find_eh_action(context) {
- Ok(action) => action,
- Err(_) => return uw::_URC_FAILURE,
- };
- if search_phase {
- match eh_action {
- EHAction::None |
- EHAction::Cleanup(_) => return continue_unwind(exception_object, context),
- EHAction::Catch(_) => {
- // EHABI requires the personality routine to update the
- // SP value in the barrier cache of the exception object.
- (*exception_object).private[5] =
- uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG);
- return uw::_URC_HANDLER_FOUND;
- }
- EHAction::Terminate => return uw::_URC_FAILURE,
- }
- } else {
- match eh_action {
- EHAction::None => return continue_unwind(exception_object, context),
- EHAction::Cleanup(lpad) |
- EHAction::Catch(lpad) => {
- uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0,
- exception_object as uintptr_t);
- uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
- uw::_Unwind_SetIP(context, lpad);
- return uw::_URC_INSTALL_CONTEXT;
- }
- EHAction::Terminate => return uw::_URC_FAILURE,
- }
- }
-
- // On ARM EHABI the personality routine is responsible for actually
- // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
- unsafe fn continue_unwind(exception_object: *mut uw::_Unwind_Exception,
- context: *mut uw::_Unwind_Context)
- -> uw::_Unwind_Reason_Code {
- if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
- uw::_URC_CONTINUE_UNWIND
- } else {
- uw::_URC_FAILURE
- }
- }
- // defined in libgcc
- extern "C" {
- fn __gnu_unwind_frame(exception_object: *mut uw::_Unwind_Exception,
- context: *mut uw::_Unwind_Context)
- -> uw::_Unwind_Reason_Code;
- }
- }
- } else {
- // Default personality routine, which is used directly on most targets
- // and indirectly on Windows x86_64 via SEH.
- unsafe extern "C" fn rust_eh_personality_impl(version: c_int,
- actions: uw::_Unwind_Action,
- _exception_class: uw::_Unwind_Exception_Class,
- exception_object: *mut uw::_Unwind_Exception,
- context: *mut uw::_Unwind_Context)
- -> uw::_Unwind_Reason_Code {
- if version != 1 {
- return uw::_URC_FATAL_PHASE1_ERROR;
- }
- let eh_action = match find_eh_action(context) {
- Ok(action) => action,
- Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
- };
- if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
- match eh_action {
- EHAction::None |
- EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
- EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
- EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
- }
- } else {
- match eh_action {
- EHAction::None => uw::_URC_CONTINUE_UNWIND,
- EHAction::Cleanup(lpad) |
- EHAction::Catch(lpad) => {
- uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0,
- exception_object as uintptr_t);
- uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
- uw::_Unwind_SetIP(context, lpad);
- uw::_URC_INSTALL_CONTEXT
- }
- EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
- }
- }
- }
-
- cfg_if::cfg_if! {
- if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
- // On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
- // handler data (aka LSDA) uses GCC-compatible encoding.
- #[lang = "eh_personality"]
- #[allow(nonstandard_style)]
- unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut uw::EXCEPTION_RECORD,
- establisherFrame: uw::LPVOID,
- contextRecord: *mut uw::CONTEXT,
- dispatcherContext: *mut uw::DISPATCHER_CONTEXT)
- -> uw::EXCEPTION_DISPOSITION {
- uw::_GCC_specific_handler(exceptionRecord,
- establisherFrame,
- contextRecord,
- dispatcherContext,
- rust_eh_personality_impl)
- }
- } else {
- // The personality routine for most of our targets.
- #[lang = "eh_personality"]
- unsafe extern "C" fn rust_eh_personality(version: c_int,
- actions: uw::_Unwind_Action,
- exception_class: uw::_Unwind_Exception_Class,
- exception_object: *mut uw::_Unwind_Exception,
- context: *mut uw::_Unwind_Context)
- -> uw::_Unwind_Reason_Code {
- rust_eh_personality_impl(version,
- actions,
- exception_class,
- exception_object,
- context)
- }
- }
- }
- }
-}
-
-unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
- let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
- let mut ip_before_instr: c_int = 0;
- let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
- let eh_context = EHContext {
- // The return address points 1 byte past the call instruction,
- // which could be in the next IP range in LSDA range table.
- //
- // `ip = -1` has special meaning, so use wrapping sub to allow for that
- ip: if ip_before_instr != 0 { ip } else { ip.wrapping_sub(1) },
- func_start: uw::_Unwind_GetRegionStart(context),
- get_text_start: &|| uw::_Unwind_GetTextRelBase(context),
- get_data_start: &|| uw::_Unwind_GetDataRelBase(context),
- };
- eh::find_eh_action(lsda, &eh_context)
-}
-
-// Frame unwind info registration
-//
-// Each module's image contains a frame unwind info section (usually
-// ".eh_frame"). When a module is loaded/unloaded into the process, the
-// unwinder must be informed about the location of this section in memory. The
-// methods of achieving that vary by the platform. On some (e.g., Linux), the
-// unwinder can discover unwind info sections on its own (by dynamically
-// enumerating currently loaded modules via the dl_iterate_phdr() API and
-// finding their ".eh_frame" sections); Others, like Windows, require modules
-// to actively register their unwind info sections via unwinder API.
-//
-// This module defines two symbols which are referenced and called from
-// rsbegin.rs to register our information with the GCC runtime. The
-// implementation of stack unwinding is (for now) deferred to libgcc_eh, however
-// Rust crates use these Rust-specific entry points to avoid potential clashes
-// with any GCC runtime.
-#[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))]
-pub mod eh_frame_registry {
- extern "C" {
- fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
- fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
- }
-
- #[rustc_std_internal_symbol]
- pub unsafe extern "C" fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8) {
- __register_frame_info(eh_frame_begin, object);
- }
-
- #[rustc_std_internal_symbol]
- pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8) {
- __deregister_frame_info(eh_frame_begin, object);
- }
-}
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index f9acb42c4..1eb4f3789 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -52,9 +52,6 @@ cfg_if::cfg_if! {
all(target_family = "unix", not(target_os = "espidf")),
all(target_vendor = "fortanix", target_env = "sgx"),
))] {
- // Rust runtime's startup objects depend on these symbols, so make them public.
- #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
- pub use real_imp::eh_frame_registry::*;
#[path = "gcc.rs"]
mod real_imp;
} else {
@@ -92,8 +89,6 @@ extern "C" {
fn __rust_foreign_exception() -> !;
}
-mod dwarf;
-
#[rustc_std_internal_symbol]
#[allow(improper_ctypes_definitions)]
pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) {
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 9f1eb411f..6b8d06568 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -256,7 +256,7 @@ cfg_if::cfg_if! {
}
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
- use core::intrinsics::atomic_store;
+ use core::intrinsics::atomic_store_seqcst;
// _CxxThrowException executes entirely on this stack frame, so there's no
// need to otherwise transfer `data` to the heap. We just pass a stack
@@ -288,20 +288,23 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
//
// In any case, we basically need to do something like this until we can
// express more operations in statics (and we may never be able to).
- atomic_store(&mut THROW_INFO.pmfnUnwind as *mut _ as *mut u32, ptr!(exception_cleanup) as u32);
- atomic_store(
+ atomic_store_seqcst(
+ &mut THROW_INFO.pmfnUnwind as *mut _ as *mut u32,
+ ptr!(exception_cleanup) as u32,
+ );
+ atomic_store_seqcst(
&mut THROW_INFO.pCatchableTypeArray as *mut _ as *mut u32,
ptr!(&CATCHABLE_TYPE_ARRAY as *const _) as u32,
);
- atomic_store(
+ atomic_store_seqcst(
&mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0] as *mut _ as *mut u32,
ptr!(&CATCHABLE_TYPE as *const _) as u32,
);
- atomic_store(
+ atomic_store_seqcst(
&mut CATCHABLE_TYPE.pType as *mut _ as *mut u32,
ptr!(&TYPE_DESCRIPTOR as *const _) as u32,
);
- atomic_store(
+ atomic_store_seqcst(
&mut CATCHABLE_TYPE.copyFunction as *mut _ as *mut u32,
ptr!(exception_copy) as u32,
);
@@ -323,13 +326,3 @@ pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
exception.data.take().unwrap()
}
}
-
-// This is required by the compiler to exist (e.g., it's a lang item), but
-// it's never actually called by the compiler because __C_specific_handler
-// or _except_handler3 is the personality function that is always used.
-// Hence this is just an aborting stub.
-#[lang = "eh_personality"]
-#[cfg(not(test))]
-fn rust_eh_personality() {
- core::intrinsics::abort()
-}
diff --git a/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs
index 65d3ce9be..2235f016c 100644
--- a/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs
@@ -70,7 +70,7 @@ impl_integer_intrinsic! {
impl ToBitMask<BitMask=u64> for Mask<_, 64>
}
-/// Returns the minimum numnber of bytes in a bitmask with `lanes` lanes.
+/// Returns the minimum number of bytes in a bitmask with `lanes` lanes.
#[cfg(feature = "generic_const_exprs")]
pub const fn bitmask_len(lanes: usize) -> usize {
(lanes + 7) / 8
diff --git a/library/portable-simd/crates/std_float/src/lib.rs b/library/portable-simd/crates/std_float/src/lib.rs
index 4bd4d4c05..4ac60b10c 100644
--- a/library/portable-simd/crates/std_float/src/lib.rs
+++ b/library/portable-simd/crates/std_float/src/lib.rs
@@ -1,9 +1,5 @@
#![cfg_attr(feature = "as_crate", no_std)] // We are std!
-#![cfg_attr(
- feature = "as_crate",
- feature(platform_intrinsics),
- feature(portable_simd)
-)]
+#![cfg_attr(feature = "as_crate", feature(platform_intrinsics), feature(portable_simd))]
#[cfg(not(feature = "as_crate"))]
use core::simd;
#[cfg(feature = "as_crate")]
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index 1516f084a..4461b2180 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -176,8 +176,6 @@ define_handles! {
FreeFunctions,
TokenStream,
SourceFile,
- MultiSpan,
- Diagnostic,
'interned:
Span,
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 5cde966bf..4c1e196b5 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -57,6 +57,7 @@ macro_rules! with_api {
fn track_env_var(var: &str, value: Option<&str>);
fn track_path(path: &str);
fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
+ fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>);
},
TokenStream {
fn drop($self: $S::TokenStream);
@@ -87,22 +88,6 @@ macro_rules! with_api {
fn path($self: &$S::SourceFile) -> String;
fn is_real($self: &$S::SourceFile) -> bool;
},
- MultiSpan {
- fn drop($self: $S::MultiSpan);
- fn new() -> $S::MultiSpan;
- fn push($self: &mut $S::MultiSpan, span: $S::Span);
- },
- Diagnostic {
- fn drop($self: $S::Diagnostic);
- fn new(level: Level, msg: &str, span: $S::MultiSpan) -> $S::Diagnostic;
- fn sub(
- $self: &mut $S::Diagnostic,
- level: Level,
- msg: &str,
- span: $S::MultiSpan,
- );
- fn emit($self: $S::Diagnostic);
- },
Span {
fn debug($self: $S::Span) -> String;
fn source_file($self: $S::Span) -> $S::SourceFile;
@@ -510,6 +495,18 @@ compound_traits!(
}
);
+#[derive(Clone, Debug)]
+pub struct Diagnostic<Span> {
+ pub level: Level,
+ pub message: String,
+ pub spans: Vec<Span>,
+ pub children: Vec<Diagnostic<Span>>,
+}
+
+compound_traits!(
+ struct Diagnostic<Span> { level, message, spans, children }
+);
+
/// Globals provided alongside the initial inputs for a macro expansion.
/// Provides values such as spans which are used frequently to avoid RPC.
#[derive(Clone)]
diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs
index e068ec60b..8202c40d6 100644
--- a/library/proc_macro/src/bridge/server.rs
+++ b/library/proc_macro/src/bridge/server.rs
@@ -2,6 +2,7 @@
use super::*;
+use std::cell::Cell;
use std::marker::PhantomData;
// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
@@ -11,8 +12,6 @@ pub trait Types {
type FreeFunctions: 'static;
type TokenStream: 'static + Clone;
type SourceFile: 'static + Clone;
- type MultiSpan: 'static;
- type Diagnostic: 'static;
type Span: 'static + Copy + Eq + Hash;
type Symbol: 'static;
}
@@ -145,6 +144,38 @@ pub trait ExecutionStrategy {
) -> Buffer;
}
+thread_local! {
+ /// While running a proc-macro with the same-thread executor, this flag will
+ /// be set, forcing nested proc-macro invocations (e.g. due to
+ /// `TokenStream::expand_expr`) to be run using a cross-thread executor.
+ ///
+ /// This is required as the thread-local state in the proc_macro client does
+ /// not handle being re-entered, and will invalidate all `Symbol`s when
+ /// entering a nested macro.
+ static ALREADY_RUNNING_SAME_THREAD: Cell<bool> = Cell::new(false);
+}
+
+/// Keep `ALREADY_RUNNING_SAME_THREAD` (see also its documentation)
+/// set to `true`, preventing same-thread reentrance.
+struct RunningSameThreadGuard(());
+
+impl RunningSameThreadGuard {
+ fn new() -> Self {
+ let already_running = ALREADY_RUNNING_SAME_THREAD.replace(true);
+ assert!(
+ !already_running,
+ "same-thread nesting (\"reentrance\") of proc macro executions is not supported"
+ );
+ RunningSameThreadGuard(())
+ }
+}
+
+impl Drop for RunningSameThreadGuard {
+ fn drop(&mut self) {
+ ALREADY_RUNNING_SAME_THREAD.set(false);
+ }
+}
+
pub struct MaybeCrossThread<P> {
cross_thread: bool,
marker: PhantomData<P>,
@@ -167,7 +198,7 @@ where
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Buffer {
- if self.cross_thread {
+ if self.cross_thread || ALREADY_RUNNING_SAME_THREAD.get() {
<CrossThread<P>>::new().run_bridge_and_client(
dispatcher,
input,
@@ -190,6 +221,8 @@ impl ExecutionStrategy for SameThread {
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Buffer {
+ let _guard = RunningSameThreadGuard::new();
+
let mut dispatch = |buf| dispatcher.dispatch(buf);
run_client(BridgeConfig {
diff --git a/library/proc_macro/src/diagnostic.rs b/library/proc_macro/src/diagnostic.rs
index 6e46dc036..5a209f7c7 100644
--- a/library/proc_macro/src/diagnostic.rs
+++ b/library/proc_macro/src/diagnostic.rs
@@ -161,22 +161,15 @@ impl Diagnostic {
/// Emit the diagnostic.
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub fn emit(self) {
- fn to_internal(spans: Vec<Span>) -> crate::bridge::client::MultiSpan {
- let mut multi_span = crate::bridge::client::MultiSpan::new();
- for span in spans {
- multi_span.push(span.0);
+ fn to_internal(diag: Diagnostic) -> crate::bridge::Diagnostic<crate::bridge::client::Span> {
+ crate::bridge::Diagnostic {
+ level: diag.level,
+ message: diag.message,
+ spans: diag.spans.into_iter().map(|s| s.0).collect(),
+ children: diag.children.into_iter().map(to_internal).collect(),
}
- multi_span
}
- let mut diag = crate::bridge::client::Diagnostic::new(
- self.level,
- &self.message[..],
- to_internal(self.spans),
- );
- for c in self.children {
- diag.sub(c.level, &c.message[..], to_internal(c.spans));
- }
- diag.emit();
+ crate::bridge::client::FreeFunctions::emit_diagnostic(to_internal(self));
}
}
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 8e478cd7b..495c1c5ae 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1353,12 +1353,7 @@ impl Literal {
/// Byte string literal.
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn byte_string(bytes: &[u8]) -> Literal {
- let string = bytes
- .iter()
- .cloned()
- .flat_map(std::ascii::escape_default)
- .map(Into::<char>::into)
- .collect::<String>();
+ let string = bytes.escape_ascii().to_string();
Literal::new(bridge::LitKind::ByteStr, &string, None)
}
diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs
index c6a4548ec..1df0c8970 100644
--- a/library/rtstartup/rsbegin.rs
+++ b/library/rtstartup/rsbegin.rs
@@ -35,6 +35,16 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
drop_in_place(to_drop);
}
+// Frame unwind info registration
+//
+// Each module's image contains a frame unwind info section (usually
+// ".eh_frame"). When a module is loaded/unloaded into the process, the
+// unwinder must be informed about the location of this section in memory. The
+// methods of achieving that vary by the platform. On some (e.g., Linux), the
+// unwinder can discover unwind info sections on its own (by dynamically
+// enumerating currently loaded modules via the dl_iterate_phdr() API and
+// finding their ".eh_frame" sections); Others, like Windows, require modules
+// to actively register their unwind info sections via unwinder API.
#[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))]
pub mod eh_frames {
#[no_mangle]
@@ -62,20 +72,19 @@ pub mod eh_frames {
}
// Unwind info registration/deregistration routines.
- // See the docs of libpanic_unwind.
extern "C" {
- fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8);
- fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8);
+ fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
+ fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
}
unsafe extern "C" fn init() {
// register unwind info on module startup
- rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
+ __register_frame_info(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
}
unsafe extern "C" fn uninit() {
// unregister on shutdown
- rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
+ __deregister_frame_info(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
}
// MinGW-specific init/uninit routine registration
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 229e546e0..324ecc804 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -39,10 +39,10 @@ rand = "0.7"
dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
[target.x86_64-fortanix-unknown-sgx.dependencies]
-fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
+fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
[target.'cfg(target_os = "hermit")'.dependencies]
-hermit-abi = { version = "0.2.0", features = ['rustc-dep-of-std'] }
+hermit-abi = { version = "0.2.6", features = ['rustc-dep-of-std'] }
[target.wasm32-wasi.dependencies]
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index a05e0db3a..61c1ff578 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -68,7 +68,10 @@ pub use alloc_crate::alloc::*;
/// The default memory allocator provided by the operating system.
///
/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
-/// plus related functions.
+/// plus related functions. However, it is not valid to mix use of the backing
+/// system allocator with `System`, as this implementation may include extra
+/// work, such as to serve alignment requests greater than the alignment
+/// provided directly by the backing system allocator.
///
/// This type implements the `GlobalAlloc` trait and Rust programs by default
/// work as if they had this definition:
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs
index 05e9b2eb6..5cf6ec817 100644
--- a/library/std/src/backtrace.rs
+++ b/library/std/src/backtrace.rs
@@ -9,12 +9,6 @@
//! implementing `std::error::Error`) to get a causal chain of where an error
//! was generated.
//!
-//! > **Note**: this module is unstable and is designed in [RFC 2504], and you
-//! > can learn more about its status in the [tracking issue].
-//!
-//! [RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md
-//! [tracking issue]: https://github.com/rust-lang/rust/issues/53487
-//!
//! ## Accuracy
//!
//! Backtraces are attempted to be as accurate as possible, but no guarantees
@@ -64,7 +58,7 @@
//! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime might not actually change
//! how backtraces are captured.
-#![unstable(feature = "backtrace", issue = "53487")]
+#![stable(feature = "backtrace", since = "1.65.0")]
#[cfg(test)]
mod tests;
@@ -110,6 +104,7 @@ use crate::vec::Vec;
/// previous point in time. In some instances the `Backtrace` type may
/// internally be empty due to configuration. For more information see
/// `Backtrace::capture`.
+#[stable(feature = "backtrace", since = "1.65.0")]
#[must_use]
pub struct Backtrace {
inner: Inner,
@@ -117,17 +112,21 @@ pub struct Backtrace {
/// The current status of a backtrace, indicating whether it was captured or
/// whether it is empty for some other reason.
+#[stable(feature = "backtrace", since = "1.65.0")]
#[non_exhaustive]
#[derive(Debug, PartialEq, Eq)]
pub enum BacktraceStatus {
/// Capturing a backtrace is not supported, likely because it's not
/// implemented for the current platform.
+ #[stable(feature = "backtrace", since = "1.65.0")]
Unsupported,
/// Capturing a backtrace has been disabled through either the
/// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables.
+ #[stable(feature = "backtrace", since = "1.65.0")]
Disabled,
/// A backtrace has been captured and the `Backtrace` should print
/// reasonable information when rendered.
+ #[stable(feature = "backtrace", since = "1.65.0")]
Captured,
}
@@ -174,6 +173,7 @@ enum BytesOrWide {
Wide(Vec<u16>),
}
+#[stable(feature = "backtrace", since = "1.65.0")]
impl fmt::Debug for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let capture = match &self.inner {
@@ -200,6 +200,7 @@ impl fmt::Debug for Backtrace {
}
}
+#[unstable(feature = "backtrace_frames", issue = "79676")]
impl fmt::Debug for BacktraceFrame {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dbg = fmt.debug_list();
@@ -288,6 +289,7 @@ impl Backtrace {
///
/// To forcibly capture a backtrace regardless of environment variables, use
/// the `Backtrace::force_capture` function.
+ #[stable(feature = "backtrace", since = "1.65.0")]
#[inline(never)] // want to make sure there's a frame here to remove
pub fn capture() -> Backtrace {
if !Backtrace::enabled() {
@@ -306,6 +308,7 @@ impl Backtrace {
/// Note that capturing a backtrace can be an expensive operation on some
/// platforms, so this should be used with caution in performance-sensitive
/// parts of code.
+ #[stable(feature = "backtrace", since = "1.65.0")]
#[inline(never)] // want to make sure there's a frame here to remove
pub fn force_capture() -> Backtrace {
Backtrace::create(Backtrace::force_capture as usize)
@@ -313,6 +316,8 @@ impl Backtrace {
/// Forcibly captures a disabled backtrace, regardless of environment
/// variable configuration.
+ #[stable(feature = "backtrace", since = "1.65.0")]
+ #[rustc_const_stable(feature = "backtrace", since = "1.65.0")]
pub const fn disabled() -> Backtrace {
Backtrace { inner: Inner::Disabled }
}
@@ -356,6 +361,7 @@ impl Backtrace {
/// Returns the status of this backtrace, indicating whether this backtrace
/// request was unsupported, disabled, or a stack trace was actually
/// captured.
+ #[stable(feature = "backtrace", since = "1.65.0")]
#[must_use]
pub fn status(&self) -> BacktraceStatus {
match self.inner {
@@ -375,6 +381,7 @@ impl<'a> Backtrace {
}
}
+#[stable(feature = "backtrace", since = "1.65.0")]
impl fmt::Display for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let capture = match &self.inner {
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index db811343f..9845d1faf 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -9,6 +9,8 @@ use crate::borrow::Borrow;
use crate::cell::Cell;
use crate::collections::TryReserveError;
use crate::collections::TryReserveErrorKind;
+#[cfg(not(bootstrap))]
+use crate::error::Error;
use crate::fmt::{self, Debug};
#[allow(deprecated)]
use crate::hash::{BuildHasher, Hash, Hasher, SipHasher13};
@@ -2158,6 +2160,15 @@ impl<'a, K: Debug, V: Debug> fmt::Display for OccupiedError<'a, K, V> {
}
}
+#[cfg(not(bootstrap))]
+#[unstable(feature = "map_try_insert", issue = "82766")]
+impl<'a, K: fmt::Debug, V: fmt::Debug> Error for OccupiedError<'a, K, V> {
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ "key already exists"
+ }
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> {
type Item = (&'a K, &'a V);
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index 7ebc41588..cb3032719 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -268,10 +268,13 @@ fn test_lots_of_insertions() {
// Try this a few times to make sure we never screw up the hashmap's
// internal state.
- for _ in 0..10 {
+ let loops = if cfg!(miri) { 2 } else { 10 };
+ for _ in 0..loops {
assert!(m.is_empty());
- for i in 1..1001 {
+ let count = if cfg!(miri) { 101 } else { 1001 };
+
+ for i in 1..count {
assert!(m.insert(i, i).is_none());
for j in 1..=i {
@@ -279,42 +282,42 @@ fn test_lots_of_insertions() {
assert_eq!(r, Some(&j));
}
- for j in i + 1..1001 {
+ for j in i + 1..count {
let r = m.get(&j);
assert_eq!(r, None);
}
}
- for i in 1001..2001 {
+ for i in count..(2 * count) {
assert!(!m.contains_key(&i));
}
// remove forwards
- for i in 1..1001 {
+ for i in 1..count {
assert!(m.remove(&i).is_some());
for j in 1..=i {
assert!(!m.contains_key(&j));
}
- for j in i + 1..1001 {
+ for j in i + 1..count {
assert!(m.contains_key(&j));
}
}
- for i in 1..1001 {
+ for i in 1..count {
assert!(!m.contains_key(&i));
}
- for i in 1..1001 {
+ for i in 1..count {
assert!(m.insert(i, i).is_none());
}
// remove backwards
- for i in (1..1001).rev() {
+ for i in (1..count).rev() {
assert!(m.remove(&i).is_some());
- for j in i..1001 {
+ for j in i..count {
assert!(!m.contains_key(&j));
}
@@ -817,6 +820,7 @@ fn test_retain() {
}
#[test]
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
fn test_try_reserve() {
let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index abff82788..5b6a415fa 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -239,7 +239,7 @@ impl<T, S> HashSet<T, S> {
///
/// If the returned iterator is dropped before being fully consumed, it
/// drops the remaining elements. The returned iterator keeps a mutable
- /// borrow on the vector to optimize its implementation.
+ /// borrow on the set to optimize its implementation.
///
/// # Examples
///
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index 722df119d..e45059595 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -1,175 +1,51 @@
-//! Interfaces for working with Errors.
-//!
-//! # Error Handling In Rust
-//!
-//! The Rust language provides two complementary systems for constructing /
-//! representing, reporting, propagating, reacting to, and discarding errors.
-//! These responsibilities are collectively known as "error handling." The
-//! components of the first system, the panic runtime and interfaces, are most
-//! commonly used to represent bugs that have been detected in your program. The
-//! components of the second system, `Result`, the error traits, and user
-//! defined types, are used to represent anticipated runtime failure modes of
-//! your program.
-//!
-//! ## The Panic Interfaces
-//!
-//! The following are the primary interfaces of the panic system and the
-//! responsibilities they cover:
-//!
-//! * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically)
-//! * [`PanicInfo`] (Reporting)
-//! * [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting)
-//! * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating)
-//!
-//! The following are the primary interfaces of the error system and the
-//! responsibilities they cover:
-//!
-//! * [`Result`] (Propagating, Reacting)
-//! * The [`Error`] trait (Reporting)
-//! * User defined types (Constructing / Representing)
-//! * [`match`] and [`downcast`] (Reacting)
-//! * The question mark operator ([`?`]) (Propagating)
-//! * The partially stable [`Try`] traits (Propagating, Constructing)
-//! * [`Termination`] (Reporting)
-//!
-//! ## Converting Errors into Panics
-//!
-//! The panic and error systems are not entirely distinct. Often times errors
-//! that are anticipated runtime failures in an API might instead represent bugs
-//! to a caller. For these situations the standard library provides APIs for
-//! constructing panics with an `Error` as it's source.
-//!
-//! * [`Result::unwrap`]
-//! * [`Result::expect`]
-//!
-//! These functions are equivalent, they either return the inner value if the
-//! `Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
-//! as the source. The only difference between them is that with `expect` you
-//! provide a panic error message to be printed alongside the source, whereas
-//! `unwrap` has a default message indicating only that you unwraped an `Err`.
-//!
-//! Of the two, `expect` is generally preferred since its `msg` field allows you
-//! to convey your intent and assumptions which makes tracking down the source
-//! of a panic easier. `unwrap` on the other hand can still be a good fit in
-//! situations where you can trivially show that a piece of code will never
-//! panic, such as `"127.0.0.1".parse::<std::net::IpAddr>().unwrap()` or early
-//! prototyping.
-//!
-//! # Common Message Styles
-//!
-//! There are two common styles for how people word `expect` messages. Using
-//! the message to present information to users encountering a panic
-//! ("expect as error message") or using the message to present information
-//! to developers debugging the panic ("expect as precondition").
-//!
-//! In the former case the expect message is used to describe the error that
-//! has occurred which is considered a bug. Consider the following example:
-//!
-//! ```should_panic
-//! // Read environment variable, panic if it is not present
-//! let path = std::env::var("IMPORTANT_PATH").unwrap();
-//! ```
-//!
-//! In the "expect as error message" style we would use expect to describe
-//! that the environment variable was not set when it should have been:
-//!
-//! ```should_panic
-//! let path = std::env::var("IMPORTANT_PATH")
-//! .expect("env variable `IMPORTANT_PATH` is not set");
-//! ```
-//!
-//! In the "expect as precondition" style, we would instead describe the
-//! reason we _expect_ the `Result` should be `Ok`. With this style we would
-//! prefer to write:
-//!
-//! ```should_panic
-//! let path = std::env::var("IMPORTANT_PATH")
-//! .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
-//! ```
-//!
-//! The "expect as error message" style does not work as well with the
-//! default output of the std panic hooks, and often ends up repeating
-//! information that is already communicated by the source error being
-//! unwrapped:
-//!
-//! ```text
-//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
-//! ```
-//!
-//! In this example we end up mentioning that an env variable is not set,
-//! followed by our source message that says the env is not present, the
-//! only additional information we're communicating is the name of the
-//! environment variable being checked.
-//!
-//! The "expect as precondition" style instead focuses on source code
-//! readability, making it easier to understand what must have gone wrong in
-//! situations where panics are being used to represent bugs exclusively.
-//! Also, by framing our expect in terms of what "SHOULD" have happened to
-//! prevent the source error, we end up introducing new information that is
-//! independent from our source error.
-//!
-//! ```text
-//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
-//! ```
-//!
-//! In this example we are communicating not only the name of the
-//! environment variable that should have been set, but also an explanation
-//! for why it should have been set, and we let the source error display as
-//! a clear contradiction to our expectation.
-//!
-//! **Hint**: If you're having trouble remembering how to phrase
-//! expect-as-precondition style error messages remember to focus on the word
-//! "should" as in "env variable should be set by blah" or "the given binary
-//! should be available and executable by the current user".
-//!
-//! [`panic_any`]: crate::panic::panic_any
-//! [`PanicInfo`]: crate::panic::PanicInfo
-//! [`catch_unwind`]: crate::panic::catch_unwind
-//! [`resume_unwind`]: crate::panic::resume_unwind
-//! [`downcast`]: crate::error::Error
-//! [`Termination`]: crate::process::Termination
-//! [`Try`]: crate::ops::Try
-//! [panic hook]: crate::panic::set_hook
-//! [`set_hook`]: crate::panic::set_hook
-//! [`take_hook`]: crate::panic::take_hook
-//! [panic-handler]: <https://doc.rust-lang.org/nomicon/panic-handler.html>
-//! [`match`]: ../../std/keyword.match.html
-//! [`?`]: ../../std/result/index.html#the-question-mark-operator-
-
+#![doc = include_str!("../../core/src/error.md")]
#![stable(feature = "rust1", since = "1.0.0")]
-// A note about crates and the facade:
-//
-// Originally, the `Error` trait was defined in libcore, and the impls
-// were scattered about. However, coherence objected to this
-// arrangement, because to create the blanket impls for `Box` required
-// knowing that `&str: !Error`, and we have no means to deal with that
-// sort of conflict just now. Therefore, for the time being, we have
-// moved the `Error` trait into libstd. As we evolve a sol'n to the
-// coherence challenge (e.g., specialization, neg impls, etc) we can
-// reconsider what crate these items belong in.
-
#[cfg(test)]
mod tests;
+#[cfg(bootstrap)]
use core::array;
+#[cfg(bootstrap)]
use core::convert::Infallible;
+#[cfg(bootstrap)]
use crate::alloc::{AllocError, LayoutError};
-use crate::any::{Demand, Provider, TypeId};
+#[cfg(bootstrap)]
+use crate::any::Demand;
+#[cfg(bootstrap)]
+use crate::any::{Provider, TypeId};
use crate::backtrace::Backtrace;
+#[cfg(bootstrap)]
use crate::borrow::Cow;
+#[cfg(bootstrap)]
use crate::cell;
+#[cfg(bootstrap)]
use crate::char;
-use crate::fmt::{self, Debug, Display, Write};
+#[cfg(bootstrap)]
+use crate::fmt::Debug;
+#[cfg(bootstrap)]
+use crate::fmt::Display;
+use crate::fmt::{self, Write};
+#[cfg(bootstrap)]
use crate::io;
+#[cfg(bootstrap)]
use crate::mem::transmute;
+#[cfg(bootstrap)]
use crate::num;
+#[cfg(bootstrap)]
use crate::str;
+#[cfg(bootstrap)]
use crate::string;
+#[cfg(bootstrap)]
use crate::sync::Arc;
+#[cfg(bootstrap)]
use crate::time;
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use core::error::Error;
+
/// `Error` is a trait representing the basic expectations for error values,
/// i.e., values of type `E` in [`Result<T, E>`].
///
@@ -182,14 +58,15 @@ use crate::time;
/// assert_eq!(err.to_string(), "invalid digit found in string");
/// ```
///
-/// Errors may provide cause chain information. [`Error::source()`] is generally
+/// Errors may provide cause information. [`Error::source()`] is generally
/// used when errors cross "abstraction boundaries". If one module must report
/// an error that is caused by an error from a lower-level module, it can allow
/// accessing that error via [`Error::source()`]. This makes it possible for the
/// high-level module to provide its own errors while also revealing some of the
-/// implementation for debugging via `source` chains.
+/// implementation for debugging.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
+#[cfg(bootstrap)]
pub trait Error: Debug + Display {
/// The lower-level source of this error, if any.
///
@@ -333,8 +210,8 @@ pub trait Error: Debug + Display {
/// }
///
/// impl std::error::Error for Error {
- /// fn provide<'a>(&'a self, req: &mut Demand<'a>) {
- /// req
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// demand
/// .provide_ref::<MyBacktrace>(&self.backtrace)
/// .provide_ref::<dyn std::error::Error + 'static>(&self.source);
/// }
@@ -352,13 +229,14 @@ pub trait Error: Debug + Display {
/// ```
#[unstable(feature = "error_generic_member_access", issue = "99301")]
#[allow(unused_variables)]
- fn provide<'a>(&'a self, req: &mut Demand<'a>) {}
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
}
+#[cfg(bootstrap)]
#[unstable(feature = "error_generic_member_access", issue = "99301")]
impl<'b> Provider for dyn Error + 'b {
- fn provide<'a>(&'a self, req: &mut Demand<'a>) {
- self.provide(req)
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ self.provide(demand)
}
}
@@ -370,6 +248,7 @@ mod private {
pub struct Internal;
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
/// Converts a type of [`Error`] into a box of dyn [`Error`].
@@ -402,6 +281,7 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
@@ -440,6 +320,7 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<dyn Error + Send + Sync> {
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
@@ -483,6 +364,7 @@ impl From<String> for Box<dyn Error + Send + Sync> {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "string_box_error", since = "1.6.0")]
impl From<String> for Box<dyn Error> {
/// Converts a [`String`] into a box of dyn [`Error`].
@@ -504,6 +386,7 @@ impl From<String> for Box<dyn Error> {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
@@ -527,6 +410,7 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "string_box_error", since = "1.6.0")]
impl From<&str> for Box<dyn Error> {
/// Converts a [`str`] into a box of dyn [`Error`].
@@ -548,6 +432,7 @@ impl From<&str> for Box<dyn Error> {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "cow_box_error", since = "1.22.0")]
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
@@ -569,6 +454,7 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "cow_box_error", since = "1.22.0")]
impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
/// Converts a [`Cow`] into a box of dyn [`Error`].
@@ -589,9 +475,11 @@ impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
}
}
+#[cfg(bootstrap)]
#[unstable(feature = "never_type", issue = "35121")]
impl Error for ! {}
+#[cfg(bootstrap)]
#[unstable(
feature = "allocator_api",
reason = "the precise API and guarantees it provides may be tweaked.",
@@ -599,9 +487,11 @@ impl Error for ! {}
)]
impl Error for AllocError {}
+#[cfg(bootstrap)]
#[stable(feature = "alloc_layout", since = "1.28.0")]
impl Error for LayoutError {}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::ParseBoolError {
#[allow(deprecated)]
@@ -610,6 +500,7 @@ impl Error for str::ParseBoolError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error {
#[allow(deprecated)]
@@ -618,6 +509,7 @@ impl Error for str::Utf8Error {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseIntError {
#[allow(deprecated)]
@@ -626,6 +518,7 @@ impl Error for num::ParseIntError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "try_from", since = "1.34.0")]
impl Error for num::TryFromIntError {
#[allow(deprecated)]
@@ -634,6 +527,7 @@ impl Error for num::TryFromIntError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "try_from", since = "1.34.0")]
impl Error for array::TryFromSliceError {
#[allow(deprecated)]
@@ -642,6 +536,7 @@ impl Error for array::TryFromSliceError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseFloatError {
#[allow(deprecated)]
@@ -650,6 +545,7 @@ impl Error for num::ParseFloatError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf8Error {
#[allow(deprecated)]
@@ -658,6 +554,7 @@ impl Error for string::FromUtf8Error {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf16Error {
#[allow(deprecated)]
@@ -666,6 +563,7 @@ impl Error for string::FromUtf16Error {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for Infallible {
fn description(&self) -> &str {
@@ -673,6 +571,7 @@ impl Error for Infallible {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for char::DecodeUtf16Error {
#[allow(deprecated)]
@@ -681,9 +580,11 @@ impl Error for char::DecodeUtf16Error {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "u8_from_char", since = "1.59.0")]
impl Error for char::TryFromCharError {}
+#[cfg(bootstrap)]
#[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: Debug + Ord, V: Debug> Error
for crate::collections::btree_map::OccupiedError<'a, K, V>
@@ -694,6 +595,7 @@ impl<'a, K: Debug + Ord, V: Debug> Error
}
}
+#[cfg(bootstrap)]
#[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedError<'a, K, V> {
#[allow(deprecated)]
@@ -702,6 +604,7 @@ impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedErr
}
}
+#[cfg(bootstrap)]
#[stable(feature = "box_error", since = "1.8.0")]
impl<T: Error> Error for Box<T> {
#[allow(deprecated, deprecated_in_future)]
@@ -719,6 +622,7 @@ impl<T: Error> Error for Box<T> {
}
}
+#[cfg(bootstrap)]
#[unstable(feature = "thin_box", issue = "92791")]
impl<T: ?Sized + crate::error::Error> crate::error::Error for crate::boxed::ThinBox<T> {
fn source(&self) -> Option<&(dyn crate::error::Error + 'static)> {
@@ -727,6 +631,7 @@ impl<T: ?Sized + crate::error::Error> crate::error::Error for crate::boxed::Thin
}
}
+#[cfg(bootstrap)]
#[stable(feature = "error_by_ref", since = "1.51.0")]
impl<'a, T: Error + ?Sized> Error for &'a T {
#[allow(deprecated, deprecated_in_future)]
@@ -743,11 +648,12 @@ impl<'a, T: Error + ?Sized> Error for &'a T {
Error::source(&**self)
}
- fn provide<'b>(&'b self, req: &mut Demand<'b>) {
- Error::provide(&**self, req);
+ fn provide<'b>(&'b self, demand: &mut Demand<'b>) {
+ Error::provide(&**self, demand);
}
}
+#[cfg(bootstrap)]
#[stable(feature = "arc_error", since = "1.52.0")]
impl<T: Error + ?Sized> Error for Arc<T> {
#[allow(deprecated, deprecated_in_future)]
@@ -764,11 +670,12 @@ impl<T: Error + ?Sized> Error for Arc<T> {
Error::source(&**self)
}
- fn provide<'a>(&'a self, req: &mut Demand<'a>) {
- Error::provide(&**self, req);
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ Error::provide(&**self, demand);
}
}
+#[cfg(bootstrap)]
#[stable(feature = "fmt_error", since = "1.11.0")]
impl Error for fmt::Error {
#[allow(deprecated)]
@@ -777,6 +684,7 @@ impl Error for fmt::Error {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "try_borrow", since = "1.13.0")]
impl Error for cell::BorrowError {
#[allow(deprecated)]
@@ -785,6 +693,7 @@ impl Error for cell::BorrowError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "try_borrow", since = "1.13.0")]
impl Error for cell::BorrowMutError {
#[allow(deprecated)]
@@ -793,6 +702,7 @@ impl Error for cell::BorrowMutError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "try_from", since = "1.34.0")]
impl Error for char::CharTryFromError {
#[allow(deprecated)]
@@ -801,6 +711,7 @@ impl Error for char::CharTryFromError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "char_from_str", since = "1.20.0")]
impl Error for char::ParseCharError {
#[allow(deprecated)]
@@ -809,12 +720,15 @@ impl Error for char::ParseCharError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "try_reserve", since = "1.57.0")]
impl Error for alloc::collections::TryReserveError {}
+#[cfg(bootstrap)]
#[unstable(feature = "duration_checked_float", issue = "83400")]
impl Error for time::FromFloatSecsError {}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for alloc::ffi::NulError {
#[allow(deprecated)]
@@ -823,6 +737,7 @@ impl Error for alloc::ffi::NulError {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl From<alloc::ffi::NulError> for io::Error {
/// Converts a [`alloc::ffi::NulError`] into a [`io::Error`].
@@ -831,6 +746,7 @@ impl From<alloc::ffi::NulError> for io::Error {
}
}
+#[cfg(bootstrap)]
#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
impl Error for core::ffi::FromBytesWithNulError {
#[allow(deprecated)]
@@ -839,12 +755,15 @@ impl Error for core::ffi::FromBytesWithNulError {
}
}
+#[cfg(bootstrap)]
#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
impl Error for core::ffi::FromBytesUntilNulError {}
+#[cfg(bootstrap)]
#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
impl Error for alloc::ffi::FromVecWithNulError {}
+#[cfg(bootstrap)]
#[stable(feature = "cstring_into", since = "1.7.0")]
impl Error for alloc::ffi::IntoStringError {
#[allow(deprecated)]
@@ -857,6 +776,7 @@ impl Error for alloc::ffi::IntoStringError {
}
}
+#[cfg(bootstrap)]
impl<'a> dyn Error + 'a {
/// Request a reference of type `T` as context about this error.
#[unstable(feature = "error_generic_member_access", issue = "99301")]
@@ -872,6 +792,7 @@ impl<'a> dyn Error + 'a {
}
// Copied from `any.rs`.
+#[cfg(bootstrap)]
impl dyn Error + 'static {
/// Returns `true` if the inner type is the same as `T`.
#[stable(feature = "error_downcast", since = "1.3.0")]
@@ -912,6 +833,7 @@ impl dyn Error + 'static {
}
}
+#[cfg(bootstrap)]
impl dyn Error + 'static + Send {
/// Forwards to the method defined on the type `dyn Error`.
#[stable(feature = "error_downcast", since = "1.3.0")]
@@ -947,6 +869,7 @@ impl dyn Error + 'static + Send {
}
}
+#[cfg(bootstrap)]
impl dyn Error + 'static + Send + Sync {
/// Forwards to the method defined on the type `dyn Error`.
#[stable(feature = "error_downcast", since = "1.3.0")]
@@ -982,6 +905,7 @@ impl dyn Error + 'static + Send + Sync {
}
}
+#[cfg(bootstrap)]
impl dyn Error {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
@@ -1041,7 +965,7 @@ impl dyn Error {
/// // let err : Box<Error> = b.into(); // or
/// let err = &b as &(dyn Error);
///
- /// let mut iter = err.chain();
+ /// let mut iter = err.sources();
///
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
@@ -1050,8 +974,19 @@ impl dyn Error {
/// ```
#[unstable(feature = "error_iter", issue = "58520")]
#[inline]
- pub fn chain(&self) -> Chain<'_> {
- Chain { current: Some(self) }
+ pub fn sources(&self) -> Sources<'_> {
+ // You may think this method would be better in the Error trait, and you'd be right.
+ // Unfortunately that doesn't work, not because of the object safety rules but because we
+ // save a reference to self in Sources below as a trait object. If this method was
+ // declared in Error, then self would have the type &T where T is some concrete type which
+ // implements Error. We would need to coerce self to have type &dyn Error, but that requires
+ // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error
+ // since that would forbid Error trait objects, and we can't put that bound on the method
+ // because that means the method can't be called on trait objects (we'd also need the
+ // 'static bound, but that isn't allowed because methods with bounds on Self other than
+ // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible.
+
+ Sources { current: Some(self) }
}
}
@@ -1061,12 +996,14 @@ impl dyn Error {
/// its sources, use `skip(1)`.
#[unstable(feature = "error_iter", issue = "58520")]
#[derive(Clone, Debug)]
-pub struct Chain<'a> {
+#[cfg(bootstrap)]
+pub struct Sources<'a> {
current: Option<&'a (dyn Error + 'static)>,
}
+#[cfg(bootstrap)]
#[unstable(feature = "error_iter", issue = "58520")]
-impl<'a> Iterator for Chain<'a> {
+impl<'a> Iterator for Sources<'a> {
type Item = &'a (dyn Error + 'static);
fn next(&mut self) -> Option<Self::Item> {
@@ -1076,6 +1013,7 @@ impl<'a> Iterator for Chain<'a> {
}
}
+#[cfg(bootstrap)]
impl dyn Error + Send {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
@@ -1089,6 +1027,7 @@ impl dyn Error + Send {
}
}
+#[cfg(bootstrap)]
impl dyn Error + Send + Sync {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
@@ -1104,8 +1043,8 @@ impl dyn Error + Send + Sync {
/// An error reporter that prints an error and its sources.
///
-/// Report also exposes configuration options for formatting the error chain, either entirely on a
-/// single line, or in multi-line format with each cause in the error chain on a new line.
+/// Report also exposes configuration options for formatting the error sources, either entirely on a
+/// single line, or in multi-line format with each source on a new line.
///
/// `Report` only requires that the wrapped error implement `Error`. It doesn't require that the
/// wrapped error be `Send`, `Sync`, or `'static`.
@@ -1246,7 +1185,7 @@ impl dyn Error + Send + Sync {
/// # Err(SuperError { source: SuperErrorSideKick })
/// # }
///
-/// fn main() -> Result<(), Report> {
+/// fn main() -> Result<(), Report<SuperError>> {
/// get_super_error()?;
/// Ok(())
/// }
@@ -1293,7 +1232,7 @@ impl dyn Error + Send + Sync {
/// # Err(SuperError { source: SuperErrorSideKick })
/// # }
///
-/// fn main() -> Result<(), Report> {
+/// fn main() -> Result<(), Report<SuperError>> {
/// get_super_error()
/// .map_err(Report::from)
/// .map_err(|r| r.pretty(true).show_backtrace(true))?;
@@ -1450,11 +1389,10 @@ impl<E> Report<E> {
///
/// **Note**: Report will search for the first `Backtrace` it can find starting from the
/// outermost error. In this example it will display the backtrace from the second error in the
- /// chain, `SuperErrorSideKick`.
+ /// sources, `SuperErrorSideKick`.
///
/// ```rust
/// #![feature(error_reporter)]
- /// #![feature(backtrace)]
/// #![feature(provide_any)]
/// #![feature(error_generic_member_access)]
/// # use std::error::Error;
@@ -1489,9 +1427,8 @@ impl<E> Report<E> {
/// }
///
/// impl Error for SuperErrorSideKick {
- /// fn provide<'a>(&'a self, req: &mut Demand<'a>) {
- /// req
- /// .provide_ref::<Backtrace>(&self.backtrace);
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ /// demand.provide_ref::<Backtrace>(&self.backtrace);
/// }
/// }
///
@@ -1548,7 +1485,7 @@ where
let backtrace = backtrace.or_else(|| {
self.error
.source()
- .map(|source| source.chain().find_map(|source| source.request_ref()))
+ .map(|source| source.sources().find_map(|source| source.request_ref()))
.flatten()
});
backtrace
@@ -1559,7 +1496,7 @@ where
fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.error)?;
- let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
+ let sources = self.error.source().into_iter().flat_map(<dyn Error>::sources);
for cause in sources {
write!(f, ": {cause}")?;
@@ -1580,73 +1517,7 @@ where
let multiple = cause.source().is_some();
- for (ind, error) in cause.chain().enumerate() {
- writeln!(f)?;
- let mut indented = Indented { inner: f };
- if multiple {
- write!(indented, "{ind: >4}: {error}")?;
- } else {
- write!(indented, " {error}")?;
- }
- }
- }
-
- if self.show_backtrace {
- let backtrace = self.backtrace();
-
- if let Some(backtrace) = backtrace {
- let backtrace = backtrace.to_string();
-
- f.write_str("\n\nStack backtrace:\n")?;
- f.write_str(backtrace.trim_end())?;
- }
- }
-
- Ok(())
- }
-}
-
-impl Report<Box<dyn Error>> {
- fn backtrace(&self) -> Option<&Backtrace> {
- // have to grab the backtrace on the first error directly since that error may not be
- // 'static
- let backtrace = self.error.request_ref();
- let backtrace = backtrace.or_else(|| {
- self.error
- .source()
- .map(|source| source.chain().find_map(|source| source.request_ref()))
- .flatten()
- });
- backtrace
- }
-
- /// Format the report as a single line.
- #[unstable(feature = "error_reporter", issue = "90172")]
- fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.error)?;
-
- let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
-
- for cause in sources {
- write!(f, ": {cause}")?;
- }
-
- Ok(())
- }
-
- /// Format the report as multiple lines, with each error cause on its own line.
- #[unstable(feature = "error_reporter", issue = "90172")]
- fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let error = &self.error;
-
- write!(f, "{error}")?;
-
- if let Some(cause) = error.source() {
- write!(f, "\n\nCaused by:")?;
-
- let multiple = cause.source().is_some();
-
- for (ind, error) in cause.chain().enumerate() {
+ for (ind, error) in cause.sources().enumerate() {
writeln!(f)?;
let mut indented = Indented { inner: f };
if multiple {
@@ -1683,17 +1554,6 @@ where
}
#[unstable(feature = "error_reporter", issue = "90172")]
-impl<'a, E> From<E> for Report<Box<dyn Error + 'a>>
-where
- E: Error + 'a,
-{
- fn from(error: E) -> Self {
- let error = box error;
- Report { error, show_backtrace: false, pretty: false }
- }
-}
-
-#[unstable(feature = "error_reporter", issue = "90172")]
impl<E> fmt::Display for Report<E>
where
E: Error,
@@ -1703,13 +1563,6 @@ where
}
}
-#[unstable(feature = "error_reporter", issue = "90172")]
-impl fmt::Display for Report<Box<dyn Error>> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
- }
-}
-
// This type intentionally outputs the same format for `Display` and `Debug`for
// situations where you unwrap a `Report` or return it from main.
#[unstable(feature = "error_reporter", issue = "90172")]
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 933b52b4d..3dd5b1250 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f32` single-precision floating point type.
+//! Constants for the `f32` single-precision floating point type.
//!
//! *[See also the `f32` primitive type](primitive@f32).*
//!
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
index 69fa203ff..4ec16c84a 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/src/f32/tests.rs
@@ -299,6 +299,84 @@ fn test_is_sign_negative() {
assert!((-f32::NAN).is_sign_negative());
}
+#[allow(unused_macros)]
+macro_rules! assert_f32_biteq {
+ ($left : expr, $right : expr) => {
+ let l: &f32 = &$left;
+ let r: &f32 = &$right;
+ let lb = l.to_bits();
+ let rb = r.to_bits();
+ assert_eq!(lb, rb, "float {} ({:#x}) is not equal to {} ({:#x})", *l, lb, *r, rb);
+ };
+}
+
+// Ignore test on x87 floating point, these platforms do not guarantee NaN
+// payloads are preserved and flush denormals to zero, failing the tests.
+#[cfg(not(target_arch = "x86"))]
+#[test]
+fn test_next_up() {
+ let tiny = f32::from_bits(1);
+ let tiny_up = f32::from_bits(2);
+ let max_down = f32::from_bits(0x7f7f_fffe);
+ let largest_subnormal = f32::from_bits(0x007f_ffff);
+ let smallest_normal = f32::from_bits(0x0080_0000);
+ assert_f32_biteq!(f32::NEG_INFINITY.next_up(), f32::MIN);
+ assert_f32_biteq!(f32::MIN.next_up(), -max_down);
+ assert_f32_biteq!((-1.0 - f32::EPSILON).next_up(), -1.0);
+ assert_f32_biteq!((-smallest_normal).next_up(), -largest_subnormal);
+ assert_f32_biteq!((-tiny_up).next_up(), -tiny);
+ assert_f32_biteq!((-tiny).next_up(), -0.0f32);
+ assert_f32_biteq!((-0.0f32).next_up(), tiny);
+ assert_f32_biteq!(0.0f32.next_up(), tiny);
+ assert_f32_biteq!(tiny.next_up(), tiny_up);
+ assert_f32_biteq!(largest_subnormal.next_up(), smallest_normal);
+ assert_f32_biteq!(1.0f32.next_up(), 1.0 + f32::EPSILON);
+ assert_f32_biteq!(f32::MAX.next_up(), f32::INFINITY);
+ assert_f32_biteq!(f32::INFINITY.next_up(), f32::INFINITY);
+
+ // Check that NaNs roundtrip.
+ let nan0 = f32::NAN;
+ let nan1 = f32::from_bits(f32::NAN.to_bits() ^ 0x002a_aaaa);
+ let nan2 = f32::from_bits(f32::NAN.to_bits() ^ 0x0055_5555);
+ assert_f32_biteq!(nan0.next_up(), nan0);
+ assert_f32_biteq!(nan1.next_up(), nan1);
+ assert_f32_biteq!(nan2.next_up(), nan2);
+}
+
+// Ignore test on x87 floating point, these platforms do not guarantee NaN
+// payloads are preserved and flush denormals to zero, failing the tests.
+#[cfg(not(target_arch = "x86"))]
+#[test]
+fn test_next_down() {
+ let tiny = f32::from_bits(1);
+ let tiny_up = f32::from_bits(2);
+ let max_down = f32::from_bits(0x7f7f_fffe);
+ let largest_subnormal = f32::from_bits(0x007f_ffff);
+ let smallest_normal = f32::from_bits(0x0080_0000);
+ assert_f32_biteq!(f32::NEG_INFINITY.next_down(), f32::NEG_INFINITY);
+ assert_f32_biteq!(f32::MIN.next_down(), f32::NEG_INFINITY);
+ assert_f32_biteq!((-max_down).next_down(), f32::MIN);
+ assert_f32_biteq!((-1.0f32).next_down(), -1.0 - f32::EPSILON);
+ assert_f32_biteq!((-largest_subnormal).next_down(), -smallest_normal);
+ assert_f32_biteq!((-tiny).next_down(), -tiny_up);
+ assert_f32_biteq!((-0.0f32).next_down(), -tiny);
+ assert_f32_biteq!((0.0f32).next_down(), -tiny);
+ assert_f32_biteq!(tiny.next_down(), 0.0f32);
+ assert_f32_biteq!(tiny_up.next_down(), tiny);
+ assert_f32_biteq!(smallest_normal.next_down(), largest_subnormal);
+ assert_f32_biteq!((1.0 + f32::EPSILON).next_down(), 1.0f32);
+ assert_f32_biteq!(f32::MAX.next_down(), max_down);
+ assert_f32_biteq!(f32::INFINITY.next_down(), f32::MAX);
+
+ // Check that NaNs roundtrip.
+ let nan0 = f32::NAN;
+ let nan1 = f32::from_bits(f32::NAN.to_bits() ^ 0x002a_aaaa);
+ let nan2 = f32::from_bits(f32::NAN.to_bits() ^ 0x0055_5555);
+ assert_f32_biteq!(nan0.next_down(), nan0);
+ assert_f32_biteq!(nan1.next_down(), nan1);
+ assert_f32_biteq!(nan2.next_down(), nan2);
+}
+
#[test]
fn test_mul_add() {
let nan: f32 = f32::NAN;
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index a9aa84f70..31351a879 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f64` double-precision floating point type.
+//! Constants for the `f64` double-precision floating point type.
//!
//! *[See also the `f64` primitive type](primitive@f64).*
//!
diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs
index 5c163cfe9..12baa68f4 100644
--- a/library/std/src/f64/tests.rs
+++ b/library/std/src/f64/tests.rs
@@ -289,6 +289,82 @@ fn test_is_sign_negative() {
assert!((-f64::NAN).is_sign_negative());
}
+#[allow(unused_macros)]
+macro_rules! assert_f64_biteq {
+ ($left : expr, $right : expr) => {
+ let l: &f64 = &$left;
+ let r: &f64 = &$right;
+ let lb = l.to_bits();
+ let rb = r.to_bits();
+ assert_eq!(lb, rb, "float {} ({:#x}) is not equal to {} ({:#x})", *l, lb, *r, rb);
+ };
+}
+
+// Ignore test on x87 floating point, these platforms do not guarantee NaN
+// payloads are preserved and flush denormals to zero, failing the tests.
+#[cfg(not(target_arch = "x86"))]
+#[test]
+fn test_next_up() {
+ let tiny = f64::from_bits(1);
+ let tiny_up = f64::from_bits(2);
+ let max_down = f64::from_bits(0x7fef_ffff_ffff_fffe);
+ let largest_subnormal = f64::from_bits(0x000f_ffff_ffff_ffff);
+ let smallest_normal = f64::from_bits(0x0010_0000_0000_0000);
+ assert_f64_biteq!(f64::NEG_INFINITY.next_up(), f64::MIN);
+ assert_f64_biteq!(f64::MIN.next_up(), -max_down);
+ assert_f64_biteq!((-1.0 - f64::EPSILON).next_up(), -1.0);
+ assert_f64_biteq!((-smallest_normal).next_up(), -largest_subnormal);
+ assert_f64_biteq!((-tiny_up).next_up(), -tiny);
+ assert_f64_biteq!((-tiny).next_up(), -0.0f64);
+ assert_f64_biteq!((-0.0f64).next_up(), tiny);
+ assert_f64_biteq!(0.0f64.next_up(), tiny);
+ assert_f64_biteq!(tiny.next_up(), tiny_up);
+ assert_f64_biteq!(largest_subnormal.next_up(), smallest_normal);
+ assert_f64_biteq!(1.0f64.next_up(), 1.0 + f64::EPSILON);
+ assert_f64_biteq!(f64::MAX.next_up(), f64::INFINITY);
+ assert_f64_biteq!(f64::INFINITY.next_up(), f64::INFINITY);
+
+ let nan0 = f64::NAN;
+ let nan1 = f64::from_bits(f64::NAN.to_bits() ^ 0x000a_aaaa_aaaa_aaaa);
+ let nan2 = f64::from_bits(f64::NAN.to_bits() ^ 0x0005_5555_5555_5555);
+ assert_f64_biteq!(nan0.next_up(), nan0);
+ assert_f64_biteq!(nan1.next_up(), nan1);
+ assert_f64_biteq!(nan2.next_up(), nan2);
+}
+
+// Ignore test on x87 floating point, these platforms do not guarantee NaN
+// payloads are preserved and flush denormals to zero, failing the tests.
+#[cfg(not(target_arch = "x86"))]
+#[test]
+fn test_next_down() {
+ let tiny = f64::from_bits(1);
+ let tiny_up = f64::from_bits(2);
+ let max_down = f64::from_bits(0x7fef_ffff_ffff_fffe);
+ let largest_subnormal = f64::from_bits(0x000f_ffff_ffff_ffff);
+ let smallest_normal = f64::from_bits(0x0010_0000_0000_0000);
+ assert_f64_biteq!(f64::NEG_INFINITY.next_down(), f64::NEG_INFINITY);
+ assert_f64_biteq!(f64::MIN.next_down(), f64::NEG_INFINITY);
+ assert_f64_biteq!((-max_down).next_down(), f64::MIN);
+ assert_f64_biteq!((-1.0f64).next_down(), -1.0 - f64::EPSILON);
+ assert_f64_biteq!((-largest_subnormal).next_down(), -smallest_normal);
+ assert_f64_biteq!((-tiny).next_down(), -tiny_up);
+ assert_f64_biteq!((-0.0f64).next_down(), -tiny);
+ assert_f64_biteq!((0.0f64).next_down(), -tiny);
+ assert_f64_biteq!(tiny.next_down(), 0.0f64);
+ assert_f64_biteq!(tiny_up.next_down(), tiny);
+ assert_f64_biteq!(smallest_normal.next_down(), largest_subnormal);
+ assert_f64_biteq!((1.0 + f64::EPSILON).next_down(), 1.0f64);
+ assert_f64_biteq!(f64::MAX.next_down(), max_down);
+ assert_f64_biteq!(f64::INFINITY.next_down(), f64::MAX);
+
+ let nan0 = f64::NAN;
+ let nan1 = f64::from_bits(f64::NAN.to_bits() ^ 0x000a_aaaa_aaaa_aaaa);
+ let nan2 = f64::from_bits(f64::NAN.to_bits() ^ 0x0005_5555_5555_5555);
+ assert_f64_biteq!(nan0.next_down(), nan0);
+ assert_f64_biteq!(nan1.next_down(), nan1);
+ assert_f64_biteq!(nan2.next_down(), nan2);
+}
+
#[test]
fn test_mul_add() {
let nan: f64 = f64::NAN;
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index a0a5c003d..80ed34157 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -290,7 +290,8 @@ impl OsString {
/// in the given `OsString`. The string may reserve more space to speculatively avoid
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional` if it returns `Ok(())`.
- /// Does nothing if capacity is already sufficient.
+ /// Does nothing if capacity is already sufficient. This method preserves
+ /// the contents even if an error occurs.
///
/// See the main `OsString` documentation information about encoding and capacity units.
///
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index c8e131b6e..c6c78dc39 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -13,13 +13,13 @@ mod tests;
use crate::ffi::OsString;
use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, Write};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
use crate::path::{Path, PathBuf};
use crate::sys::fs as fs_imp;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
use crate::time::SystemTime;
-/// A reference to an open file on the filesystem.
+/// An object providing access to an open file on the filesystem.
///
/// An instance of a `File` can be read and/or written depending on what options
/// it was opened with. Files also implement [`Seek`] to alter the logical cursor
@@ -377,6 +377,35 @@ impl File {
OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
}
+ /// Creates a new file in read-write mode; error if the file exists.
+ ///
+ /// This function will create a file if it does not exist, or return an error if it does. This
+ /// way, if the call succeeds, the file returned is guaranteed to be new.
+ ///
+ /// This option is useful because it is atomic. Otherwise between checking whether a file
+ /// exists and creating a new one, the file may have been created by another process (a TOCTOU
+ /// race condition / attack).
+ ///
+ /// This can also be written using
+ /// `File::options().read(true).write(true).create_new(true).open(...)`.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// #![feature(file_create_new)]
+ ///
+ /// use std::fs::File;
+ ///
+ /// fn main() -> std::io::Result<()> {
+ /// let mut f = File::create_new("foo.txt")?;
+ /// Ok(())
+ /// }
+ /// ```
+ #[unstable(feature = "file_create_new", issue = "none")]
+ pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {
+ OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())
+ }
+
/// Returns a new OpenOptions object.
///
/// This function returns a new OpenOptions object that you can use to
@@ -703,8 +732,8 @@ impl Read for File {
self.inner.read_vectored(bufs)
}
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- self.inner.read_buf(buf)
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ self.inner.read_buf(cursor)
}
#[inline]
@@ -755,8 +784,8 @@ impl Read for &File {
self.inner.read(buf)
}
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- self.inner.read_buf(buf)
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ self.inner.read_buf(cursor)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index f7fbaa9c2..4f339a18a 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -2,7 +2,7 @@ mod buffer;
use crate::fmt;
use crate::io::{
- self, BufRead, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
+ self, BorrowedCursor, BufRead, IoSliceMut, Read, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
};
use buffer::Buffer;
@@ -224,6 +224,14 @@ impl<R> BufReader<R> {
}
}
+// This is only used by a test which asserts that the initialization-tracking is correct.
+#[cfg(test)]
+impl<R> BufReader<R> {
+ pub fn initialized(&self) -> usize {
+ self.buf.initialized()
+ }
+}
+
impl<R: Seek> BufReader<R> {
/// Seeks relative to the current position. If the new position lies within the buffer,
/// the buffer will not be flushed, allowing for more efficient seeks.
@@ -266,21 +274,21 @@ impl<R: Read> Read for BufReader<R> {
Ok(nread)
}
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
- if self.buf.pos() == self.buf.filled() && buf.remaining() >= self.capacity() {
+ if self.buf.pos() == self.buf.filled() && cursor.capacity() >= self.capacity() {
self.discard_buffer();
- return self.inner.read_buf(buf);
+ return self.inner.read_buf(cursor);
}
- let prev = buf.filled_len();
+ let prev = cursor.written();
let mut rem = self.fill_buf()?;
- rem.read_buf(buf)?;
+ rem.read_buf(cursor.reborrow())?;
- self.consume(buf.filled_len() - prev); //slice impl of read_buf known to never unfill buf
+ self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf
Ok(())
}
diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs
index 8ae01f3b0..e9e29d60c 100644
--- a/library/std/src/io/buffered/bufreader/buffer.rs
+++ b/library/std/src/io/buffered/bufreader/buffer.rs
@@ -9,7 +9,7 @@
/// that user code which wants to do reads from a `BufReader` via `buffer` + `consume` can do so
/// without encountering any runtime bounds checks.
use crate::cmp;
-use crate::io::{self, Read, ReadBuf};
+use crate::io::{self, BorrowedBuf, Read};
use crate::mem::MaybeUninit;
pub struct Buffer {
@@ -20,13 +20,19 @@ pub struct Buffer {
// Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are
// initialized with bytes from a read.
filled: usize,
+ // This is the max number of bytes returned across all `fill_buf` calls. We track this so that we
+ // can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its
+ // defensive initialization as possible. Note that while this often the same as `filled`, it
+ // doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and
+ // omitting this is a huge perf regression for `Read` impls that do not.
+ initialized: usize,
}
impl Buffer {
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
let buf = Box::new_uninit_slice(capacity);
- Self { buf, pos: 0, filled: 0 }
+ Self { buf, pos: 0, filled: 0, initialized: 0 }
}
#[inline]
@@ -51,6 +57,12 @@ impl Buffer {
self.pos
}
+ // This is only used by a test which asserts that the initialization-tracking is correct.
+ #[cfg(test)]
+ pub fn initialized(&self) -> usize {
+ self.initialized
+ }
+
#[inline]
pub fn discard_buffer(&mut self) {
self.pos = 0;
@@ -93,12 +105,17 @@ impl Buffer {
if self.pos >= self.filled {
debug_assert!(self.pos == self.filled);
- let mut readbuf = ReadBuf::uninit(&mut self.buf);
+ let mut buf = BorrowedBuf::from(&mut *self.buf);
+ // SAFETY: `self.filled` bytes will always have been initialized.
+ unsafe {
+ buf.set_init(self.initialized);
+ }
- reader.read_buf(&mut readbuf)?;
+ reader.read_buf(buf.unfilled())?;
- self.filled = readbuf.filled_len();
self.pos = 0;
+ self.filled = buf.len();
+ self.initialized = buf.init_len();
}
Ok(self.buffer())
}
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs
index fe45b1326..f4e688eb9 100644
--- a/library/std/src/io/buffered/tests.rs
+++ b/library/std/src/io/buffered/tests.rs
@@ -1,5 +1,7 @@
use crate::io::prelude::*;
-use crate::io::{self, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, ReadBuf, SeekFrom};
+use crate::io::{
+ self, BorrowedBuf, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom,
+};
use crate::mem::MaybeUninit;
use crate::panic;
use crate::sync::atomic::{AtomicUsize, Ordering};
@@ -61,48 +63,48 @@ fn test_buffered_reader_read_buf() {
let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
let mut reader = BufReader::with_capacity(2, inner);
- let mut buf = [MaybeUninit::uninit(); 3];
- let mut buf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 3];
+ let mut buf: BorrowedBuf<'_> = buf.into();
- reader.read_buf(&mut buf).unwrap();
+ reader.read_buf(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), [5, 6, 7]);
assert_eq!(reader.buffer(), []);
- let mut buf = [MaybeUninit::uninit(); 2];
- let mut buf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 2];
+ let mut buf: BorrowedBuf<'_> = buf.into();
- reader.read_buf(&mut buf).unwrap();
+ reader.read_buf(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), [0, 1]);
assert_eq!(reader.buffer(), []);
- let mut buf = [MaybeUninit::uninit(); 1];
- let mut buf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1];
+ let mut buf: BorrowedBuf<'_> = buf.into();
- reader.read_buf(&mut buf).unwrap();
+ reader.read_buf(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), [2]);
assert_eq!(reader.buffer(), [3]);
- let mut buf = [MaybeUninit::uninit(); 3];
- let mut buf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 3];
+ let mut buf: BorrowedBuf<'_> = buf.into();
- reader.read_buf(&mut buf).unwrap();
+ reader.read_buf(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), [3]);
assert_eq!(reader.buffer(), []);
- reader.read_buf(&mut buf).unwrap();
+ reader.read_buf(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), [3, 4]);
assert_eq!(reader.buffer(), []);
buf.clear();
- reader.read_buf(&mut buf).unwrap();
+ reader.read_buf(buf.unfilled()).unwrap();
- assert_eq!(buf.filled_len(), 0);
+ assert!(buf.filled().is_empty());
}
#[test]
@@ -1037,3 +1039,27 @@ fn single_formatted_write() {
writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap();
assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]);
}
+
+#[test]
+fn bufreader_full_initialize() {
+ struct OneByteReader;
+ impl Read for OneByteReader {
+ fn read(&mut self, buf: &mut [u8]) -> crate::io::Result<usize> {
+ if buf.len() > 0 {
+ buf[0] = 0;
+ Ok(1)
+ } else {
+ Ok(0)
+ }
+ }
+ }
+ let mut reader = BufReader::new(OneByteReader);
+ // Nothing is initialized yet.
+ assert_eq!(reader.initialized(), 0);
+
+ let buf = reader.fill_buf().unwrap();
+ // We read one byte...
+ assert_eq!(buf.len(), 1);
+ // But we initialized the whole buffer!
+ assert_eq!(reader.initialized(), reader.capacity());
+}
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index 1a10245e4..38b98afff 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -1,4 +1,4 @@
-use super::{BufWriter, ErrorKind, Read, ReadBuf, Result, Write, DEFAULT_BUF_SIZE};
+use super::{BorrowedBuf, BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
use crate::mem::MaybeUninit;
/// Copies the entire contents of a reader into a writer.
@@ -97,37 +97,39 @@ impl<I: Write> BufferedCopySpec for BufWriter<I> {
loop {
let buf = writer.buffer_mut();
- let mut read_buf = ReadBuf::uninit(buf.spare_capacity_mut());
+ let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into();
- // SAFETY: init is either 0 or the initialized_len of the previous iteration
unsafe {
- read_buf.assume_init(init);
+ // SAFETY: init is either 0 or the init_len from the previous iteration.
+ read_buf.set_init(init);
}
if read_buf.capacity() >= DEFAULT_BUF_SIZE {
- match reader.read_buf(&mut read_buf) {
+ let mut cursor = read_buf.unfilled();
+ match reader.read_buf(cursor.reborrow()) {
Ok(()) => {
- let bytes_read = read_buf.filled_len();
+ let bytes_read = cursor.written();
if bytes_read == 0 {
return Ok(len);
}
- init = read_buf.initialized_len() - bytes_read;
+ init = read_buf.init_len() - bytes_read;
+ len += bytes_read as u64;
- // SAFETY: ReadBuf guarantees all of its filled bytes are init
+ // SAFETY: BorrowedBuf guarantees all of its filled bytes are init
unsafe { buf.set_len(buf.len() + bytes_read) };
- len += bytes_read as u64;
+
// Read again if the buffer still has enough capacity, as BufWriter itself would do
// This will occur if the reader returns short reads
- continue;
}
- Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+ Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
+ } else {
+ writer.flush_buf()?;
+ init = 0;
}
-
- writer.flush_buf()?;
}
}
}
@@ -136,13 +138,13 @@ fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
reader: &mut R,
writer: &mut W,
) -> Result<u64> {
- let mut buf = [MaybeUninit::uninit(); DEFAULT_BUF_SIZE];
- let mut buf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); DEFAULT_BUF_SIZE];
+ let mut buf: BorrowedBuf<'_> = buf.into();
let mut len = 0;
loop {
- match reader.read_buf(&mut buf) {
+ match reader.read_buf(buf.unfilled()) {
Ok(()) => {}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index f3fbfc447..d98ab021c 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -5,7 +5,7 @@ use crate::io::prelude::*;
use crate::alloc::Allocator;
use crate::cmp;
-use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
+use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
/// A `Cursor` wraps an in-memory buffer and provides it with a
/// [`Seek`] implementation.
@@ -323,12 +323,12 @@ where
Ok(n)
}
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- let prev_filled = buf.filled_len();
+ fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ let prev_written = cursor.written();
- Read::read_buf(&mut self.fill_buf()?, buf)?;
+ Read::read_buf(&mut self.fill_buf()?, cursor.reborrow())?;
- self.pos += (buf.filled_len() - prev_filled) as u64;
+ self.pos += (cursor.written() - prev_written) as u64;
Ok(())
}
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index ff7fdcae1..29b09fcc5 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -76,6 +76,15 @@ impl fmt::Debug for Error {
}
}
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<alloc::ffi::NulError> for Error {
+ /// Converts a [`alloc::ffi::NulError`] into a [`Error`].
+ fn from(_: alloc::ffi::NulError) -> Error {
+ const_io_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
+ }
+}
+
// Only derive debug in tests, to make sure it
// doesn't accidentally get printed.
#[cfg_attr(test, derive(Debug))]
@@ -564,6 +573,8 @@ impl Error {
/// println!("last OS error: {os_error:?}");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "GetLastError")]
+ #[doc(alias = "errno")]
#[must_use]
#[inline]
pub fn last_os_error() -> Error {
diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs
index 292bf4826..781ae03ad 100644
--- a/library/std/src/io/error/repr_bitpacked.rs
+++ b/library/std/src/io/error/repr_bitpacked.rs
@@ -269,10 +269,10 @@ where
}
TAG_SIMPLE_MESSAGE => ErrorData::SimpleMessage(&*ptr.cast::<SimpleMessage>().as_ptr()),
TAG_CUSTOM => {
- // It would be correct for us to use `ptr::sub` here (see the
+ // It would be correct for us to use `ptr::byte_sub` here (see the
// comment above the `wrapping_add` call in `new_custom` for why),
// but it isn't clear that it makes a difference, so we don't.
- let custom = ptr.as_ptr().cast::<u8>().wrapping_sub(TAG_CUSTOM).cast::<Custom>();
+ let custom = ptr.as_ptr().wrapping_byte_sub(TAG_CUSTOM).cast::<Custom>();
ErrorData::Custom(make_custom(custom))
}
_ => {
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 950725473..e5048dcc8 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -6,7 +6,7 @@ use crate::cmp;
use crate::collections::VecDeque;
use crate::fmt;
use crate::io::{
- self, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, Write,
+ self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
};
use crate::mem;
@@ -21,8 +21,8 @@ impl<R: Read + ?Sized> Read for &mut R {
}
#[inline]
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- (**self).read_buf(buf)
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ (**self).read_buf(cursor)
}
#[inline]
@@ -125,8 +125,8 @@ impl<R: Read + ?Sized> Read for Box<R> {
}
#[inline]
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- (**self).read_buf(buf)
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ (**self).read_buf(cursor)
}
#[inline]
@@ -249,11 +249,11 @@ impl Read for &[u8] {
}
#[inline]
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- let amt = cmp::min(buf.remaining(), self.len());
+ fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ let amt = cmp::min(cursor.capacity(), self.len());
let (a, b) = self.split_at(amt);
- buf.append(a);
+ cursor.append(a);
*self = b;
Ok(())
@@ -427,10 +427,10 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
}
#[inline]
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
let (ref mut front, _) = self.as_slices();
- let n = cmp::min(buf.remaining(), front.len());
- Read::read_buf(front, buf)?;
+ let n = cmp::min(cursor.capacity(), front.len());
+ Read::read_buf(front, cursor)?;
self.drain(..n);
Ok(())
}
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 96addbd1a..eeace2c43 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -278,7 +278,7 @@ pub use self::{
};
#[unstable(feature = "read_buf", issue = "78485")]
-pub use self::readbuf::ReadBuf;
+pub use self::readbuf::{BorrowedBuf, BorrowedCursor};
pub(crate) use error::const_io_error;
mod buffered;
@@ -362,29 +362,30 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>
buf.reserve(32); // buf is full, need more space
}
- let mut read_buf = ReadBuf::uninit(buf.spare_capacity_mut());
+ let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into();
// SAFETY: These bytes were initialized but not filled in the previous loop
unsafe {
- read_buf.assume_init(initialized);
+ read_buf.set_init(initialized);
}
- match r.read_buf(&mut read_buf) {
+ let mut cursor = read_buf.unfilled();
+ match r.read_buf(cursor.reborrow()) {
Ok(()) => {}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
- if read_buf.filled_len() == 0 {
+ if cursor.written() == 0 {
return Ok(buf.len() - start_len);
}
// store how much was initialized but not filled
- initialized = read_buf.initialized_len() - read_buf.filled_len();
- let new_len = read_buf.filled_len() + buf.len();
+ initialized = cursor.init_ref().len();
- // SAFETY: ReadBuf's invariants mean this much memory is init
+ // SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
unsafe {
+ let new_len = read_buf.filled().len() + buf.len();
buf.set_len(new_len);
}
@@ -461,12 +462,15 @@ pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [
}
}
-pub(crate) fn default_read_buf<F>(read: F, buf: &mut ReadBuf<'_>) -> Result<()>
+pub(crate) fn default_read_buf<F>(read: F, mut cursor: BorrowedCursor<'_>) -> Result<()>
where
F: FnOnce(&mut [u8]) -> Result<usize>,
{
- let n = read(buf.initialize_unfilled())?;
- buf.add_filled(n);
+ let n = read(cursor.ensure_init().init_mut())?;
+ unsafe {
+ // SAFETY: we initialised using `ensure_init` so there is no uninit data to advance to.
+ cursor.advance(n);
+ }
Ok(())
}
@@ -803,30 +807,30 @@ pub trait Read {
/// Pull some bytes from this source into the specified buffer.
///
- /// This is equivalent to the [`read`](Read::read) method, except that it is passed a [`ReadBuf`] rather than `[u8]` to allow use
+ /// This is equivalent to the [`read`](Read::read) method, except that it is passed a [`BorrowedCursor`] rather than `[u8]` to allow use
/// with uninitialized buffers. The new data will be appended to any existing contents of `buf`.
///
/// The default implementation delegates to `read`.
#[unstable(feature = "read_buf", issue = "78485")]
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
+ fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {
default_read_buf(|b| self.read(b), buf)
}
- /// Read the exact number of bytes required to fill `buf`.
+ /// Read the exact number of bytes required to fill `cursor`.
///
- /// This is equivalent to the [`read_exact`](Read::read_exact) method, except that it is passed a [`ReadBuf`] rather than `[u8]` to
+ /// This is equivalent to the [`read_exact`](Read::read_exact) method, except that it is passed a [`BorrowedCursor`] rather than `[u8]` to
/// allow use with uninitialized buffers.
#[unstable(feature = "read_buf", issue = "78485")]
- fn read_buf_exact(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
- while buf.remaining() > 0 {
- let prev_filled = buf.filled().len();
- match self.read_buf(buf) {
+ fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> Result<()> {
+ while cursor.capacity() > 0 {
+ let prev_written = cursor.written();
+ match self.read_buf(cursor.reborrow()) {
Ok(()) => {}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
- if buf.filled().len() == prev_filled {
+ if cursor.written() == prev_written {
return Err(Error::new(ErrorKind::UnexpectedEof, "failed to fill buffer"));
}
}
@@ -883,6 +887,10 @@ pub trait Read {
/// The yielded item is [`Ok`] if a byte was successfully read and [`Err`]
/// otherwise. EOF is mapped to returning [`None`] from this iterator.
///
+ /// The default implementation calls `read` for each byte,
+ /// which can be very inefficient for data that's not in memory,
+ /// such as [`File`]. Consider using a [`BufReader`] in such cases.
+ ///
/// # Examples
///
/// [`File`]s implement `Read`:
@@ -895,10 +903,11 @@ pub trait Read {
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
+ /// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
- /// let f = File::open("foo.txt")?;
+ /// let f = BufReader::new(File::open("foo.txt")?);
///
/// for byte in f.bytes() {
/// println!("{}", byte.unwrap());
@@ -1028,8 +1037,6 @@ pub trait Read {
/// # Examples
///
/// ```no_run
-/// #![feature(io_read_to_string)]
-///
/// # use std::io;
/// fn main() -> io::Result<()> {
/// let stdin = io::read_to_string(io::stdin())?;
@@ -1038,7 +1045,7 @@ pub trait Read {
/// Ok(())
/// }
/// ```
-#[unstable(feature = "io_read_to_string", issue = "80218")]
+#[stable(feature = "io_read_to_string", since = "1.65.0")]
pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
let mut buf = String::new();
reader.read_to_string(&mut buf)?;
@@ -2582,50 +2589,48 @@ impl<T: Read> Read for Take<T> {
Ok(n)
}
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
+ fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> Result<()> {
// Don't call into inner reader at all at EOF because it may still block
if self.limit == 0 {
return Ok(());
}
- let prev_filled = buf.filled_len();
-
- if self.limit <= buf.remaining() as u64 {
+ if self.limit <= buf.capacity() as u64 {
// if we just use an as cast to convert, limit may wrap around on a 32 bit target
let limit = cmp::min(self.limit, usize::MAX as u64) as usize;
- let extra_init = cmp::min(limit as usize, buf.initialized_len() - buf.filled_len());
+ let extra_init = cmp::min(limit as usize, buf.init_ref().len());
// SAFETY: no uninit data is written to ibuf
- let ibuf = unsafe { &mut buf.unfilled_mut()[..limit] };
+ let ibuf = unsafe { &mut buf.as_mut()[..limit] };
- let mut sliced_buf = ReadBuf::uninit(ibuf);
+ let mut sliced_buf: BorrowedBuf<'_> = ibuf.into();
// SAFETY: extra_init bytes of ibuf are known to be initialized
unsafe {
- sliced_buf.assume_init(extra_init);
+ sliced_buf.set_init(extra_init);
}
- self.inner.read_buf(&mut sliced_buf)?;
+ let mut cursor = sliced_buf.unfilled();
+ self.inner.read_buf(cursor.reborrow())?;
- let new_init = sliced_buf.initialized_len();
- let filled = sliced_buf.filled_len();
+ let new_init = cursor.init_ref().len();
+ let filled = sliced_buf.len();
- // sliced_buf / ibuf must drop here
+ // cursor / sliced_buf / ibuf must drop here
- // SAFETY: new_init bytes of buf's unfilled buffer have been initialized
unsafe {
- buf.assume_init(new_init);
+ // SAFETY: filled bytes have been filled and therefore initialized
+ buf.advance(filled);
+ // SAFETY: new_init bytes of buf's unfilled buffer have been initialized
+ buf.set_init(new_init);
}
- buf.add_filled(filled);
-
self.limit -= filled as u64;
} else {
- self.inner.read_buf(buf)?;
-
- //inner may unfill
- self.limit -= buf.filled_len().saturating_sub(prev_filled) as u64;
+ let written = buf.written();
+ self.inner.read_buf(buf.reborrow())?;
+ self.limit -= (buf.written() - written) as u64;
}
Ok(())
diff --git a/library/std/src/io/readbuf.rs b/library/std/src/io/readbuf.rs
index 78d1113f8..b1a84095f 100644
--- a/library/std/src/io/readbuf.rs
+++ b/library/std/src/io/readbuf.rs
@@ -5,9 +5,10 @@ mod tests;
use crate::cmp;
use crate::fmt::{self, Debug, Formatter};
-use crate::mem::MaybeUninit;
+use crate::io::{Result, Write};
+use crate::mem::{self, MaybeUninit};
-/// A wrapper around a byte buffer that is incrementally filled and initialized.
+/// A borrowed byte buffer which is incrementally filled and initialized.
///
/// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the
/// buffer that has been logically filled with data, a region that has been initialized at some point but not yet
@@ -20,230 +21,286 @@ use crate::mem::MaybeUninit;
/// [ filled | unfilled ]
/// [ initialized | uninitialized ]
/// ```
-pub struct ReadBuf<'a> {
- buf: &'a mut [MaybeUninit<u8>],
+///
+/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference
+/// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be
+/// directly written. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
+/// has write-only access to the unfilled portion of the buffer (you can think of it as a
+/// write-only iterator).
+///
+/// The lifetime `'data` is a bound on the lifetime of the underlying data.
+pub struct BorrowedBuf<'data> {
+ /// The buffer's underlying data.
+ buf: &'data mut [MaybeUninit<u8>],
+ /// The length of `self.buf` which is known to be filled.
filled: usize,
- initialized: usize,
+ /// The length of `self.buf` which is known to be initialized.
+ init: usize,
}
-impl Debug for ReadBuf<'_> {
+impl Debug for BorrowedBuf<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.debug_struct("ReadBuf")
- .field("init", &self.initialized())
+ f.debug_struct("BorrowedBuf")
+ .field("init", &self.init)
.field("filled", &self.filled)
.field("capacity", &self.capacity())
.finish()
}
}
-impl<'a> ReadBuf<'a> {
- /// Creates a new `ReadBuf` from a fully initialized buffer.
+/// Create a new `BorrowedBuf` from a fully initialized slice.
+impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> {
#[inline]
- pub fn new(buf: &'a mut [u8]) -> ReadBuf<'a> {
- let len = buf.len();
+ fn from(slice: &'data mut [u8]) -> BorrowedBuf<'data> {
+ let len = slice.len();
- ReadBuf {
- //SAFETY: initialized data never becoming uninitialized is an invariant of ReadBuf
- buf: unsafe { (buf as *mut [u8]).as_uninit_slice_mut().unwrap() },
+ BorrowedBuf {
+ // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
+ buf: unsafe { (slice as *mut [u8]).as_uninit_slice_mut().unwrap() },
filled: 0,
- initialized: len,
+ init: len,
}
}
+}
- /// Creates a new `ReadBuf` from a fully uninitialized buffer.
- ///
- /// Use `assume_init` if part of the buffer is known to be already initialized.
+/// Create a new `BorrowedBuf` from an uninitialized buffer.
+///
+/// Use `set_init` if part of the buffer is known to be already initialized.
+impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
#[inline]
- pub fn uninit(buf: &'a mut [MaybeUninit<u8>]) -> ReadBuf<'a> {
- ReadBuf { buf, filled: 0, initialized: 0 }
+ fn from(buf: &'data mut [MaybeUninit<u8>]) -> BorrowedBuf<'data> {
+ BorrowedBuf { buf, filled: 0, init: 0 }
}
+}
+impl<'data> BorrowedBuf<'data> {
/// Returns the total capacity of the buffer.
#[inline]
pub fn capacity(&self) -> usize {
self.buf.len()
}
+ /// Returns the length of the filled part of the buffer.
+ #[inline]
+ pub fn len(&self) -> usize {
+ self.filled
+ }
+
+ /// Returns the length of the initialized part of the buffer.
+ #[inline]
+ pub fn init_len(&self) -> usize {
+ self.init
+ }
+
/// Returns a shared reference to the filled portion of the buffer.
#[inline]
pub fn filled(&self) -> &[u8] {
- //SAFETY: We only slice the filled part of the buffer, which is always valid
+ // SAFETY: We only slice the filled part of the buffer, which is always valid
unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.filled]) }
}
- /// Returns a mutable reference to the filled portion of the buffer.
+ /// Returns a cursor over the unfilled part of the buffer.
#[inline]
- pub fn filled_mut(&mut self) -> &mut [u8] {
- //SAFETY: We only slice the filled part of the buffer, which is always valid
- unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[0..self.filled]) }
+ pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
+ BorrowedCursor {
+ start: self.filled,
+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
+ // lifetime covariantly is safe.
+ buf: unsafe {
+ mem::transmute::<&'this mut BorrowedBuf<'data>, &'this mut BorrowedBuf<'this>>(self)
+ },
+ }
}
- /// Returns a shared reference to the initialized portion of the buffer.
+ /// Clears the buffer, resetting the filled region to empty.
///
- /// This includes the filled portion.
+ /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
#[inline]
- pub fn initialized(&self) -> &[u8] {
- //SAFETY: We only slice the initialized part of the buffer, which is always valid
- unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.initialized]) }
+ pub fn clear(&mut self) -> &mut Self {
+ self.filled = 0;
+ self
}
- /// Returns a mutable reference to the initialized portion of the buffer.
+ /// Asserts that the first `n` bytes of the buffer are initialized.
///
- /// This includes the filled portion.
- #[inline]
- pub fn initialized_mut(&mut self) -> &mut [u8] {
- //SAFETY: We only slice the initialized part of the buffer, which is always valid
- unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[0..self.initialized]) }
- }
-
- /// Returns a mutable reference to the unfilled part of the buffer without ensuring that it has been fully
- /// initialized.
+ /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
+ /// bytes than are already known to be initialized.
///
/// # Safety
///
- /// The caller must not de-initialize portions of the buffer that have already been initialized.
+ /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
#[inline]
- pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
- &mut self.buf[self.filled..]
+ pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
+ self.init = cmp::max(self.init, n);
+ self
}
+}
- /// Returns a mutable reference to the uninitialized part of the buffer.
+/// A writeable view of the unfilled portion of a [`BorrowedBuf`](BorrowedBuf).
+///
+/// Provides access to the initialized and uninitialized parts of the underlying `BorrowedBuf`.
+/// Data can be written directly to the cursor by using [`append`](BorrowedCursor::append) or
+/// indirectly by getting a slice of part or all of the cursor and writing into the slice. In the
+/// indirect case, the caller must call [`advance`](BorrowedCursor::advance) after writing to inform
+/// the cursor how many bytes have been written.
+///
+/// Once data is written to the cursor, it becomes part of the filled portion of the underlying
+/// `BorrowedBuf` and can no longer be accessed or re-written by the cursor. I.e., the cursor tracks
+/// the unfilled part of the underlying `BorrowedBuf`.
+///
+/// The lifetime `'a` is a bound on the lifetime of the underlying buffer (which means it is a bound
+/// on the data in that buffer by transitivity).
+#[derive(Debug)]
+pub struct BorrowedCursor<'a> {
+ /// The underlying buffer.
+ // Safety invariant: we treat the type of buf as covariant in the lifetime of `BorrowedBuf` when
+ // we create a `BorrowedCursor`. This is only safe if we never replace `buf` by assigning into
+ // it, so don't do that!
+ buf: &'a mut BorrowedBuf<'a>,
+ /// The length of the filled portion of the underlying buffer at the time of the cursor's
+ /// creation.
+ start: usize,
+}
+
+impl<'a> BorrowedCursor<'a> {
+ /// Reborrow this cursor by cloning it with a smaller lifetime.
///
- /// It is safe to uninitialize any of these bytes.
+ /// Since a cursor maintains unique access to its underlying buffer, the borrowed cursor is
+ /// not accessible while the new cursor exists.
#[inline]
- pub fn uninitialized_mut(&mut self) -> &mut [MaybeUninit<u8>] {
- &mut self.buf[self.initialized..]
+ pub fn reborrow<'this>(&'this mut self) -> BorrowedCursor<'this> {
+ BorrowedCursor {
+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
+ // lifetime covariantly is safe.
+ buf: unsafe {
+ mem::transmute::<&'this mut BorrowedBuf<'a>, &'this mut BorrowedBuf<'this>>(
+ self.buf,
+ )
+ },
+ start: self.start,
+ }
}
- /// Returns a mutable reference to the unfilled part of the buffer, ensuring it is fully initialized.
- ///
- /// Since `ReadBuf` tracks the region of the buffer that has been initialized, this is effectively "free" after
- /// the first use.
+ /// Returns the available space in the cursor.
#[inline]
- pub fn initialize_unfilled(&mut self) -> &mut [u8] {
- // should optimize out the assertion
- self.initialize_unfilled_to(self.remaining())
+ pub fn capacity(&self) -> usize {
+ self.buf.capacity() - self.buf.filled
}
- /// Returns a mutable reference to the first `n` bytes of the unfilled part of the buffer, ensuring it is
- /// fully initialized.
- ///
- /// # Panics
+ /// Returns the number of bytes written to this cursor since it was created from a `BorrowedBuf`.
///
- /// Panics if `self.remaining()` is less than `n`.
+ /// Note that if this cursor is a reborrowed clone of another, then the count returned is the
+ /// count written via either cursor, not the count since the cursor was reborrowed.
#[inline]
- pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
- assert!(self.remaining() >= n);
-
- let extra_init = self.initialized - self.filled;
- // If we don't have enough initialized, do zeroing
- if n > extra_init {
- let uninit = n - extra_init;
- let unfilled = &mut self.uninitialized_mut()[0..uninit];
-
- for byte in unfilled.iter_mut() {
- byte.write(0);
- }
-
- // SAFETY: we just initialized uninit bytes, and the previous bytes were already init
- unsafe {
- self.assume_init(n);
- }
- }
-
- let filled = self.filled;
+ pub fn written(&self) -> usize {
+ self.buf.filled - self.start
+ }
- &mut self.initialized_mut()[filled..filled + n]
+ /// Returns a shared reference to the initialized portion of the cursor.
+ #[inline]
+ pub fn init_ref(&self) -> &[u8] {
+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
+ unsafe { MaybeUninit::slice_assume_init_ref(&self.buf.buf[self.buf.filled..self.buf.init]) }
}
- /// Returns the number of bytes at the end of the slice that have not yet been filled.
+ /// Returns a mutable reference to the initialized portion of the cursor.
#[inline]
- pub fn remaining(&self) -> usize {
- self.capacity() - self.filled
+ pub fn init_mut(&mut self) -> &mut [u8] {
+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
+ unsafe {
+ MaybeUninit::slice_assume_init_mut(&mut self.buf.buf[self.buf.filled..self.buf.init])
+ }
}
- /// Clears the buffer, resetting the filled region to empty.
+ /// Returns a mutable reference to the uninitialized part of the cursor.
///
- /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
+ /// It is safe to uninitialize any of these bytes.
#[inline]
- pub fn clear(&mut self) -> &mut Self {
- self.set_filled(0) // The assertion in `set_filled` is optimized out
+ pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+ &mut self.buf.buf[self.buf.init..]
}
- /// Increases the size of the filled region of the buffer.
- ///
- /// The number of initialized bytes is not changed.
+ /// Returns a mutable reference to the whole cursor.
///
- /// # Panics
+ /// # Safety
///
- /// Panics if the filled region of the buffer would become larger than the initialized region.
+ /// The caller must not uninitialize any bytes in the initialized portion of the cursor.
#[inline]
- pub fn add_filled(&mut self, n: usize) -> &mut Self {
- self.set_filled(self.filled + n)
+ pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+ &mut self.buf.buf[self.buf.filled..]
}
- /// Sets the size of the filled region of the buffer.
+ /// Advance the cursor by asserting that `n` bytes have been filled.
///
- /// The number of initialized bytes is not changed.
+ /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be
+ /// accessed via the underlying buffer. I.e., the buffer's filled portion grows by `n` elements
+ /// and its unfilled portion (and the capacity of this cursor) shrinks by `n` elements.
///
- /// Note that this can be used to *shrink* the filled region of the buffer in addition to growing it (for
- /// example, by a `Read` implementation that compresses data in-place).
- ///
- /// # Panics
+ /// # Safety
///
- /// Panics if the filled region of the buffer would become larger than the initialized region.
+ /// The caller must ensure that the first `n` bytes of the cursor have been properly
+ /// initialised.
+ #[inline]
+ pub unsafe fn advance(&mut self, n: usize) -> &mut Self {
+ self.buf.filled += n;
+ self.buf.init = cmp::max(self.buf.init, self.buf.filled);
+ self
+ }
+
+ /// Initializes all bytes in the cursor.
#[inline]
- pub fn set_filled(&mut self, n: usize) -> &mut Self {
- assert!(n <= self.initialized);
+ pub fn ensure_init(&mut self) -> &mut Self {
+ for byte in self.uninit_mut() {
+ byte.write(0);
+ }
+ self.buf.init = self.buf.capacity();
- self.filled = n;
self
}
- /// Asserts that the first `n` unfilled bytes of the buffer are initialized.
+ /// Asserts that the first `n` unfilled bytes of the cursor are initialized.
///
- /// `ReadBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
- /// bytes than are already known to be initialized.
+ /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when
+ /// called with fewer bytes than are already known to be initialized.
///
/// # Safety
///
- /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
+ /// The caller must ensure that the first `n` bytes of the buffer have already been initialized.
#[inline]
- pub unsafe fn assume_init(&mut self, n: usize) -> &mut Self {
- self.initialized = cmp::max(self.initialized, self.filled + n);
+ pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
+ self.buf.init = cmp::max(self.buf.init, self.buf.filled + n);
self
}
- /// Appends data to the buffer, advancing the written position and possibly also the initialized position.
+ /// Appends data to the cursor, advancing position within its buffer.
///
/// # Panics
///
- /// Panics if `self.remaining()` is less than `buf.len()`.
+ /// Panics if `self.capacity()` is less than `buf.len()`.
#[inline]
pub fn append(&mut self, buf: &[u8]) {
- assert!(self.remaining() >= buf.len());
+ assert!(self.capacity() >= buf.len());
// SAFETY: we do not de-initialize any of the elements of the slice
unsafe {
- MaybeUninit::write_slice(&mut self.unfilled_mut()[..buf.len()], buf);
+ MaybeUninit::write_slice(&mut self.as_mut()[..buf.len()], buf);
}
// SAFETY: We just added the entire contents of buf to the filled section.
unsafe {
- self.assume_init(buf.len());
+ self.set_init(buf.len());
}
- self.add_filled(buf.len());
+ self.buf.filled += buf.len();
}
+}
- /// Returns the amount of bytes that have been filled.
- #[inline]
- pub fn filled_len(&self) -> usize {
- self.filled
+impl<'a> Write for BorrowedCursor<'a> {
+ fn write(&mut self, buf: &[u8]) -> Result<usize> {
+ self.append(buf);
+ Ok(buf.len())
}
- /// Returns the amount of bytes that have been initialized.
- #[inline]
- pub fn initialized_len(&self) -> usize {
- self.initialized
+ fn flush(&mut self) -> Result<()> {
+ Ok(())
}
}
diff --git a/library/std/src/io/readbuf/tests.rs b/library/std/src/io/readbuf/tests.rs
index 3b7a5a56d..cc1b423f2 100644
--- a/library/std/src/io/readbuf/tests.rs
+++ b/library/std/src/io/readbuf/tests.rs
@@ -1,181 +1,175 @@
-use super::ReadBuf;
+use super::BorrowedBuf;
use crate::mem::MaybeUninit;
-/// Test that ReadBuf has the correct numbers when created with new
+/// Test that BorrowedBuf has the correct numbers when created with new
#[test]
fn new() {
- let mut buf = [0; 16];
- let rbuf = ReadBuf::new(&mut buf);
+ let buf: &mut [_] = &mut [0; 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
- assert_eq!(rbuf.filled_len(), 0);
- assert_eq!(rbuf.initialized_len(), 16);
+ assert_eq!(rbuf.filled().len(), 0);
+ assert_eq!(rbuf.init_len(), 16);
assert_eq!(rbuf.capacity(), 16);
- assert_eq!(rbuf.remaining(), 16);
+ assert_eq!(rbuf.unfilled().capacity(), 16);
}
-/// Test that ReadBuf has the correct numbers when created with uninit
+/// Test that BorrowedBuf has the correct numbers when created with uninit
#[test]
fn uninit() {
- let mut buf = [MaybeUninit::uninit(); 16];
- let rbuf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
- assert_eq!(rbuf.filled_len(), 0);
- assert_eq!(rbuf.initialized_len(), 0);
+ assert_eq!(rbuf.filled().len(), 0);
+ assert_eq!(rbuf.init_len(), 0);
assert_eq!(rbuf.capacity(), 16);
- assert_eq!(rbuf.remaining(), 16);
+ assert_eq!(rbuf.unfilled().capacity(), 16);
}
#[test]
fn initialize_unfilled() {
- let mut buf = [MaybeUninit::uninit(); 16];
- let mut rbuf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
- rbuf.initialize_unfilled();
+ rbuf.unfilled().ensure_init();
- assert_eq!(rbuf.initialized_len(), 16);
+ assert_eq!(rbuf.init_len(), 16);
}
#[test]
-fn initialize_unfilled_to() {
- let mut buf = [MaybeUninit::uninit(); 16];
- let mut rbuf = ReadBuf::uninit(&mut buf);
+fn addvance_filled() {
+ let buf: &mut [_] = &mut [0; 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
- rbuf.initialize_unfilled_to(8);
-
- assert_eq!(rbuf.initialized_len(), 8);
-
- rbuf.initialize_unfilled_to(4);
-
- assert_eq!(rbuf.initialized_len(), 8);
-
- rbuf.set_filled(8);
-
- rbuf.initialize_unfilled_to(6);
-
- assert_eq!(rbuf.initialized_len(), 14);
-
- rbuf.initialize_unfilled_to(8);
-
- assert_eq!(rbuf.initialized_len(), 16);
-}
-
-#[test]
-fn add_filled() {
- let mut buf = [0; 16];
- let mut rbuf = ReadBuf::new(&mut buf);
-
- rbuf.add_filled(1);
-
- assert_eq!(rbuf.filled_len(), 1);
- assert_eq!(rbuf.remaining(), 15);
-}
-
-#[test]
-#[should_panic]
-fn add_filled_panic() {
- let mut buf = [MaybeUninit::uninit(); 16];
- let mut rbuf = ReadBuf::uninit(&mut buf);
-
- rbuf.add_filled(1);
-}
-
-#[test]
-fn set_filled() {
- let mut buf = [0; 16];
- let mut rbuf = ReadBuf::new(&mut buf);
-
- rbuf.set_filled(16);
-
- assert_eq!(rbuf.filled_len(), 16);
- assert_eq!(rbuf.remaining(), 0);
-
- rbuf.set_filled(6);
-
- assert_eq!(rbuf.filled_len(), 6);
- assert_eq!(rbuf.remaining(), 10);
-}
-
-#[test]
-#[should_panic]
-fn set_filled_panic() {
- let mut buf = [MaybeUninit::uninit(); 16];
- let mut rbuf = ReadBuf::uninit(&mut buf);
+ unsafe {
+ rbuf.unfilled().advance(1);
+ }
- rbuf.set_filled(16);
+ assert_eq!(rbuf.filled().len(), 1);
+ assert_eq!(rbuf.unfilled().capacity(), 15);
}
#[test]
fn clear() {
- let mut buf = [255; 16];
- let mut rbuf = ReadBuf::new(&mut buf);
+ let buf: &mut [_] = &mut [255; 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
- rbuf.set_filled(16);
+ unsafe {
+ rbuf.unfilled().advance(16);
+ }
- assert_eq!(rbuf.filled_len(), 16);
- assert_eq!(rbuf.remaining(), 0);
+ assert_eq!(rbuf.filled().len(), 16);
+ assert_eq!(rbuf.unfilled().capacity(), 0);
rbuf.clear();
- assert_eq!(rbuf.filled_len(), 0);
- assert_eq!(rbuf.remaining(), 16);
+ assert_eq!(rbuf.filled().len(), 0);
+ assert_eq!(rbuf.unfilled().capacity(), 16);
- assert_eq!(rbuf.initialized(), [255; 16]);
+ assert_eq!(rbuf.unfilled().init_ref(), [255; 16]);
}
#[test]
-fn assume_init() {
- let mut buf = [MaybeUninit::uninit(); 16];
- let mut rbuf = ReadBuf::uninit(&mut buf);
+fn set_init() {
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
unsafe {
- rbuf.assume_init(8);
+ rbuf.set_init(8);
}
- assert_eq!(rbuf.initialized_len(), 8);
+ assert_eq!(rbuf.init_len(), 8);
- rbuf.add_filled(4);
+ unsafe {
+ rbuf.unfilled().advance(4);
+ }
unsafe {
- rbuf.assume_init(2);
+ rbuf.set_init(2);
}
- assert_eq!(rbuf.initialized_len(), 8);
+ assert_eq!(rbuf.init_len(), 8);
unsafe {
- rbuf.assume_init(8);
+ rbuf.set_init(8);
}
- assert_eq!(rbuf.initialized_len(), 12);
+ assert_eq!(rbuf.init_len(), 8);
}
#[test]
fn append() {
- let mut buf = [MaybeUninit::new(255); 16];
- let mut rbuf = ReadBuf::uninit(&mut buf);
+ let buf: &mut [_] = &mut [MaybeUninit::new(255); 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
- rbuf.append(&[0; 8]);
+ rbuf.unfilled().append(&[0; 8]);
- assert_eq!(rbuf.initialized_len(), 8);
- assert_eq!(rbuf.filled_len(), 8);
+ assert_eq!(rbuf.init_len(), 8);
+ assert_eq!(rbuf.filled().len(), 8);
assert_eq!(rbuf.filled(), [0; 8]);
rbuf.clear();
- rbuf.append(&[1; 16]);
+ rbuf.unfilled().append(&[1; 16]);
- assert_eq!(rbuf.initialized_len(), 16);
- assert_eq!(rbuf.filled_len(), 16);
+ assert_eq!(rbuf.init_len(), 16);
+ assert_eq!(rbuf.filled().len(), 16);
assert_eq!(rbuf.filled(), [1; 16]);
}
#[test]
-fn filled_mut() {
- let mut buf = [0; 16];
- let mut rbuf = ReadBuf::new(&mut buf);
+fn reborrow_written() {
+ let buf: &mut [_] = &mut [MaybeUninit::new(0); 32];
+ let mut buf: BorrowedBuf<'_> = buf.into();
+
+ let mut cursor = buf.unfilled();
+ cursor.append(&[1; 16]);
+
+ let mut cursor2 = cursor.reborrow();
+ cursor2.append(&[2; 16]);
+
+ assert_eq!(cursor2.written(), 32);
+ assert_eq!(cursor.written(), 32);
+
+ assert_eq!(buf.unfilled().written(), 0);
+ assert_eq!(buf.init_len(), 32);
+ assert_eq!(buf.filled().len(), 32);
+ let filled = buf.filled();
+ assert_eq!(&filled[..16], [1; 16]);
+ assert_eq!(&filled[16..], [2; 16]);
+}
+
+#[test]
+fn cursor_set_init() {
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
+ let mut rbuf: BorrowedBuf<'_> = buf.into();
+
+ unsafe {
+ rbuf.unfilled().set_init(8);
+ }
- rbuf.add_filled(8);
+ assert_eq!(rbuf.init_len(), 8);
+ assert_eq!(rbuf.unfilled().init_ref().len(), 8);
+ assert_eq!(rbuf.unfilled().init_mut().len(), 8);
+ assert_eq!(rbuf.unfilled().uninit_mut().len(), 8);
+ assert_eq!(unsafe { rbuf.unfilled().as_mut() }.len(), 16);
+
+ unsafe {
+ rbuf.unfilled().advance(4);
+ }
- let filled = rbuf.filled().to_vec();
+ unsafe {
+ rbuf.unfilled().set_init(2);
+ }
+
+ assert_eq!(rbuf.init_len(), 8);
+
+ unsafe {
+ rbuf.unfilled().set_init(8);
+ }
- assert_eq!(&*filled, &*rbuf.filled_mut());
+ assert_eq!(rbuf.init_len(), 12);
+ assert_eq!(rbuf.unfilled().init_ref().len(), 8);
+ assert_eq!(rbuf.unfilled().init_mut().len(), 8);
+ assert_eq!(rbuf.unfilled().uninit_mut().len(), 4);
+ assert_eq!(unsafe { rbuf.unfilled().as_mut() }.len(), 12);
}
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 4d3736f79..2dc12a18a 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -8,7 +8,6 @@ use crate::io::prelude::*;
use crate::cell::{Cell, RefCell};
use crate::fmt;
use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
-use crate::pin::Pin;
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock};
use crate::sys::stdio;
@@ -526,7 +525,7 @@ pub struct Stdout {
// FIXME: this should be LineWriter or BufWriter depending on the state of
// stdout (tty or not). Note that if this is not line buffered it
// should also flush-on-panic or some form of flush-on-abort.
- inner: Pin<&'static ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>>,
+ inner: &'static ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>,
}
/// A locked reference to the [`Stdout`] handle.
@@ -603,22 +602,27 @@ static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLo
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdout() -> Stdout {
Stdout {
- inner: Pin::static_ref(&STDOUT).get_or_init_pin(
- || unsafe { ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw()))) },
- |mutex| unsafe { mutex.init() },
- ),
+ inner: STDOUT
+ .get_or_init(|| ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw())))),
}
}
+// Flush the data and disable buffering during shutdown
+// by replacing the line writer by one with zero
+// buffering capacity.
pub fn cleanup() {
- if let Some(instance) = STDOUT.get() {
- // Flush the data and disable buffering during shutdown
- // by replacing the line writer by one with zero
- // buffering capacity.
+ let mut initialized = false;
+ let stdout = STDOUT.get_or_init(|| {
+ initialized = true;
+ ReentrantMutex::new(RefCell::new(LineWriter::with_capacity(0, stdout_raw())))
+ });
+
+ if !initialized {
+ // The buffer was previously initialized, overwrite it here.
// We use try_lock() instead of lock(), because someone
// might have leaked a StdoutLock, which would
// otherwise cause a deadlock here.
- if let Some(lock) = Pin::static_ref(instance).try_lock() {
+ if let Some(lock) = stdout.try_lock() {
*lock.borrow_mut() = LineWriter::with_capacity(0, stdout_raw());
}
}
@@ -761,7 +765,7 @@ impl fmt::Debug for StdoutLock<'_> {
/// standard library or via raw Windows API calls, will fail.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stderr {
- inner: Pin<&'static ReentrantMutex<RefCell<StderrRaw>>>,
+ inner: &'static ReentrantMutex<RefCell<StderrRaw>>,
}
/// A locked reference to the [`Stderr`] handle.
@@ -834,16 +838,12 @@ pub struct StderrLock<'a> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stderr() -> Stderr {
// Note that unlike `stdout()` we don't use `at_exit` here to register a
- // destructor. Stderr is not buffered , so there's no need to run a
+ // destructor. Stderr is not buffered, so there's no need to run a
// destructor for flushing the buffer
- static INSTANCE: OnceLock<ReentrantMutex<RefCell<StderrRaw>>> = OnceLock::new();
+ static INSTANCE: ReentrantMutex<RefCell<StderrRaw>> =
+ ReentrantMutex::new(RefCell::new(stderr_raw()));
- Stderr {
- inner: Pin::static_ref(&INSTANCE).get_or_init_pin(
- || unsafe { ReentrantMutex::new(RefCell::new(stderr_raw())) },
- |mutex| unsafe { mutex.init() },
- ),
- }
+ Stderr { inner: &INSTANCE }
}
impl Stderr {
@@ -986,12 +986,15 @@ pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
/// otherwise. `label` identifies the stream in a panic message.
///
/// This function is used to print error messages, so it takes extra
-/// care to avoid causing a panic when `local_s` is unusable.
-/// For instance, if the TLS key for the local stream is
-/// already destroyed, or if the local stream is locked by another
-/// thread, it will just fall back to the global stream.
+/// care to avoid causing a panic when `OUTPUT_CAPTURE` is unusable.
+/// For instance, if the TLS key for output capturing is already destroyed, or
+/// if the local stream is in use by another thread, it will just fall back to
+/// the global stream.
///
/// However, if the actual I/O causes an error, this function does panic.
+///
+/// Writing to non-blocking stdout/stderr can cause an error, which will lead
+/// this function to panic.
fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
where
T: Write,
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index f357f33ec..f4a886d88 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -1,4 +1,4 @@
-use super::{repeat, Cursor, ReadBuf, SeekFrom};
+use super::{repeat, BorrowedBuf, Cursor, SeekFrom};
use crate::cmp::{self, min};
use crate::io::{self, IoSlice, IoSliceMut};
use crate::io::{BufRead, BufReader, Read, Seek, Write};
@@ -94,7 +94,7 @@ fn read_to_end() {
assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
assert_eq!(v, b"1");
- let cap = 1024 * 1024;
+ let cap = if cfg!(miri) { 1024 } else { 1024 * 1024 };
let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
let mut v = Vec::new();
let (a, b) = data.split_at(data.len() / 2);
@@ -159,24 +159,24 @@ fn read_exact_slice() {
#[test]
fn read_buf_exact() {
- let mut buf = [0; 4];
- let mut buf = ReadBuf::new(&mut buf);
+ let buf: &mut [_] = &mut [0; 4];
+ let mut buf: BorrowedBuf<'_> = buf.into();
let mut c = Cursor::new(&b""[..]);
- assert_eq!(c.read_buf_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
+ assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
let mut c = Cursor::new(&b"123456789"[..]);
- c.read_buf_exact(&mut buf).unwrap();
+ c.read_buf_exact(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), b"1234");
buf.clear();
- c.read_buf_exact(&mut buf).unwrap();
+ c.read_buf_exact(buf.unfilled()).unwrap();
assert_eq!(buf.filled(), b"5678");
buf.clear();
- assert_eq!(c.read_buf_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
+ assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
}
#[test]
@@ -309,6 +309,7 @@ fn chain_zero_length_read_is_not_eof() {
#[bench]
#[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_read_to_end(b: &mut test::Bencher) {
b.iter(|| {
let mut lr = repeat(1).take(10000000);
@@ -614,10 +615,10 @@ fn bench_take_read(b: &mut test::Bencher) {
#[bench]
fn bench_take_read_buf(b: &mut test::Bencher) {
b.iter(|| {
- let mut buf = [MaybeUninit::uninit(); 64];
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 64];
- let mut rbuf = ReadBuf::uninit(&mut buf);
+ let mut buf: BorrowedBuf<'_> = buf.into();
- [255; 128].take(64).read_buf(&mut rbuf).unwrap();
+ [255; 128].take(64).read_buf(buf.unfilled()).unwrap();
});
}
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index c1300cd67..f076ee092 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -5,7 +5,7 @@ mod tests;
use crate::fmt;
use crate::io::{
- self, BufRead, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, SizeHint, Write,
+ self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
};
/// A reader which is always at EOF.
@@ -47,7 +47,7 @@ impl Read for Empty {
}
#[inline]
- fn read_buf(&mut self, _buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
Ok(())
}
}
@@ -130,21 +130,19 @@ impl Read for Repeat {
Ok(buf.len())
}
- fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
// SAFETY: No uninit bytes are being written
- for slot in unsafe { buf.unfilled_mut() } {
+ for slot in unsafe { buf.as_mut() } {
slot.write(self.byte);
}
- let remaining = buf.remaining();
+ let remaining = buf.capacity();
// SAFETY: the entire unfilled portion of buf has been initialized
unsafe {
- buf.assume_init(remaining);
+ buf.advance(remaining);
}
- buf.add_filled(remaining);
-
Ok(())
}
diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs
index 08972a59a..ce5e2c9da 100644
--- a/library/std/src/io/util/tests.rs
+++ b/library/std/src/io/util/tests.rs
@@ -1,7 +1,7 @@
use crate::cmp::{max, min};
use crate::io::prelude::*;
use crate::io::{
- copy, empty, repeat, sink, BufWriter, Empty, ReadBuf, Repeat, Result, SeekFrom, Sink,
+ copy, empty, repeat, sink, BorrowedBuf, BufWriter, Empty, Repeat, Result, SeekFrom, Sink,
DEFAULT_BUF_SIZE,
};
@@ -79,29 +79,29 @@ fn empty_reads() {
assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
- let mut buf = [];
- let mut buf = ReadBuf::uninit(&mut buf);
- e.read_buf(&mut buf).unwrap();
- assert_eq!(buf.filled_len(), 0);
- assert_eq!(buf.initialized_len(), 0);
-
- let mut buf = [MaybeUninit::uninit()];
- let mut buf = ReadBuf::uninit(&mut buf);
- e.read_buf(&mut buf).unwrap();
- assert_eq!(buf.filled_len(), 0);
- assert_eq!(buf.initialized_len(), 0);
-
- let mut buf = [MaybeUninit::uninit(); 1024];
- let mut buf = ReadBuf::uninit(&mut buf);
- e.read_buf(&mut buf).unwrap();
- assert_eq!(buf.filled_len(), 0);
- assert_eq!(buf.initialized_len(), 0);
-
- let mut buf = [MaybeUninit::uninit(); 1024];
- let mut buf = ReadBuf::uninit(&mut buf);
- e.by_ref().read_buf(&mut buf).unwrap();
- assert_eq!(buf.filled_len(), 0);
- assert_eq!(buf.initialized_len(), 0);
+ let buf: &mut [MaybeUninit<_>] = &mut [];
+ let mut buf: BorrowedBuf<'_> = buf.into();
+ e.read_buf(buf.unfilled()).unwrap();
+ assert_eq!(buf.len(), 0);
+ assert_eq!(buf.init_len(), 0);
+
+ let buf: &mut [_] = &mut [MaybeUninit::uninit()];
+ let mut buf: BorrowedBuf<'_> = buf.into();
+ e.read_buf(buf.unfilled()).unwrap();
+ assert_eq!(buf.len(), 0);
+ assert_eq!(buf.init_len(), 0);
+
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024];
+ let mut buf: BorrowedBuf<'_> = buf.into();
+ e.read_buf(buf.unfilled()).unwrap();
+ assert_eq!(buf.len(), 0);
+ assert_eq!(buf.init_len(), 0);
+
+ let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024];
+ let mut buf: BorrowedBuf<'_> = buf.into();
+ e.by_ref().read_buf(buf.unfilled()).unwrap();
+ assert_eq!(buf.len(), 0);
+ assert_eq!(buf.init_len(), 0);
}
#[test]
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 7157b5af0..a4b0522b0 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1921,7 +1921,7 @@ mod type_keyword {}
/// and [proposal]s exist to use `unsafe {}` blocks inside such functions when
/// making `unsafe` operations.
///
-/// See the [Rustnomicon] and the [Reference] for more informations.
+/// See the [Rustnomicon] and the [Reference] for more information.
///
/// # Examples
///
@@ -2113,7 +2113,7 @@ mod use_keyword {}
/// Add constraints that must be upheld to use an item.
///
/// `where` allows specifying constraints on lifetime and generic parameters.
-/// The [RFC] introducing `where` contains detailed informations about the
+/// The [RFC] introducing `where` contains detailed information about the
/// keyword.
///
/// # Examples
@@ -2355,7 +2355,7 @@ mod dyn_keyword {}
/// println!("f = {f} and i = {i}");
/// ```
///
-/// See the [Reference][union] for more informations on `union`s.
+/// See the [Reference][union] for more information on `union`s.
///
/// [`struct`]: keyword.struct.html
/// [union]: ../reference/items/unions.html
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 20d25a608..bc4f1b27c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -187,6 +187,7 @@
//! [rust-discord]: https://discord.gg/rust-lang
//! [array]: prim@array
//! [slice]: prim@slice
+
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
#![doc(
@@ -201,25 +202,35 @@
no_global_oom_handling,
not(no_global_oom_handling)
))]
+// To run libstd tests without x.py without ending up with two copies of libstd, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
+// miri-test-libstd also prefers to make std use the sysroot versions of the dependencies.
+#![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))]
// Don't link to std. We are std.
#![no_std]
+// Tell the compiler to link to either panic_abort or panic_unwind
+#![needs_panic_runtime]
+//
+// Lints:
#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]
#![allow(explicit_outlives_requirements)]
#![allow(unused_lifetimes)]
-// Tell the compiler to link to either panic_abort or panic_unwind
-#![needs_panic_runtime]
+#![deny(rustc::existing_doc_keyword)]
// Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
-#![cfg_attr(not(bootstrap), deny(ffi_unwind_calls))]
+#![deny(ffi_unwind_calls)]
// std may use features in a platform-specific way
#![allow(unused_features)]
+//
+// Features:
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
#![cfg_attr(
all(target_vendor = "fortanix", target_env = "sgx"),
feature(slice_index_methods, coerce_unsized, sgx_platform)
)]
-#![deny(rustc::existing_doc_keyword)]
//
// Language features:
#![feature(alloc_error_handler)]
@@ -241,11 +252,12 @@
#![feature(dropck_eyepatch)]
#![feature(exhaustive_patterns)]
#![feature(intra_doc_pointers)]
-#![feature(label_break_value)]
+#![cfg_attr(bootstrap, feature(label_break_value))]
#![feature(lang_items)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(linkage)]
+#![feature(link_cfg)]
#![feature(min_specialization)]
#![feature(must_not_suspend)]
#![feature(needs_panic_runtime)]
@@ -258,6 +270,7 @@
#![feature(staged_api)]
#![feature(thread_local)]
#![feature(try_blocks)]
+#![feature(utf8_chunks)]
//
// Library features (core):
#![feature(array_error_internals)]
@@ -269,10 +282,14 @@
#![feature(cstr_internals)]
#![feature(duration_checked_float)]
#![feature(duration_constants)]
+#![cfg_attr(not(bootstrap), feature(error_generic_member_access))]
+#![cfg_attr(not(bootstrap), feature(error_in_core))]
+#![cfg_attr(not(bootstrap), feature(error_iter))]
#![feature(exact_size_is_empty)]
#![feature(exclusive_wrapper)]
#![feature(extend_one)]
#![feature(float_minimum_maximum)]
+#![feature(float_next_up_down)]
#![feature(hasher_prefixfree_extras)]
#![feature(hashmap_internals)]
#![feature(int_error_internals)]
@@ -284,6 +301,8 @@
#![feature(panic_can_unwind)]
#![feature(panic_info_message)]
#![feature(panic_internals)]
+#![feature(pointer_byte_offsets)]
+#![feature(pointer_is_aligned)]
#![feature(portable_simd)]
#![feature(prelude_2024)]
#![feature(provide_any)]
@@ -294,6 +313,8 @@
#![feature(std_internals)]
#![feature(str_internals)]
#![feature(strict_provenance)]
+#![feature(maybe_uninit_uninit_array)]
+#![feature(const_maybe_uninit_uninit_array)]
//
// Library features (alloc):
#![feature(alloc_layout_extra)]
@@ -576,6 +597,7 @@ pub mod alloc;
// Private support modules
mod panicking;
+mod personality;
#[path = "../../backtrace/src/lib.rs"]
#[allow(dead_code, unused_attributes)]
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index 0cb21ef53..6e4ba1404 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -27,17 +27,31 @@ macro_rules! panic {
/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
/// immediately.
///
+/// The `print!` macro will lock the standard output on each call. If you call
+/// `print!` within a hot loop, this behavior may be the bottleneck of the loop.
+/// To avoid this, lock stdout with [`io::stdout().lock()`][lock]:
+/// ```
+/// use std::io::{stdout, Write};
+///
+/// let mut lock = stdout().lock();
+/// write!(lock, "hello world").unwrap();
+/// ```
+///
/// Use `print!` only for the primary output of your program. Use
/// [`eprint!`] instead to print error and progress messages.
///
/// [flush]: crate::io::Write::flush
/// [`println!`]: crate::println
/// [`eprint!`]: crate::eprint
+/// [lock]: crate::io::Stdout
///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
/// # Examples
///
/// ```
@@ -75,16 +89,30 @@ macro_rules! print {
/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
/// See [`std::fmt`] for more information.
///
+/// The `println!` macro will lock the standard output on each call. If you call
+/// `println!` within a hot loop, this behavior may be the bottleneck of the loop.
+/// To avoid this, lock stdout with [`io::stdout().lock()`][lock]:
+/// ```
+/// use std::io::{stdout, Write};
+///
+/// let mut lock = stdout().lock();
+/// writeln!(lock, "hello world").unwrap();
+/// ```
+///
/// Use `println!` only for the primary output of your program. Use
/// [`eprintln!`] instead to print error and progress messages.
///
/// [`std::fmt`]: crate::fmt
/// [`eprintln!`]: crate::eprintln
+/// [lock]: crate::io::Stdout
///
/// # Panics
///
/// Panics if writing to [`io::stdout`] fails.
///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
/// [`io::stdout`]: crate::io::stdout
///
/// # Examples
@@ -93,6 +121,8 @@ macro_rules! print {
/// println!(); // prints just a newline
/// println!("hello there!");
/// println!("format {} arguments", "some");
+/// let local_variable = "some";
+/// println!("format {local_variable} arguments");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -123,6 +153,9 @@ macro_rules! println {
///
/// Panics if writing to `io::stderr` fails.
///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
/// # Examples
///
/// ```
@@ -155,6 +188,9 @@ macro_rules! eprint {
///
/// Panics if writing to `io::stderr` fails.
///
+/// Writing to non-blocking stdout can cause an error, which will lead
+/// this macro to panic.
+///
/// # Examples
///
/// ```
diff --git a/library/std/src/net/display_buffer.rs b/library/std/src/net/display_buffer.rs
new file mode 100644
index 000000000..7aadf06e9
--- /dev/null
+++ b/library/std/src/net/display_buffer.rs
@@ -0,0 +1,40 @@
+use crate::fmt;
+use crate::mem::MaybeUninit;
+use crate::str;
+
+/// Used for slow path in `Display` implementations when alignment is required.
+pub struct DisplayBuffer<const SIZE: usize> {
+ buf: [MaybeUninit<u8>; SIZE],
+ len: usize,
+}
+
+impl<const SIZE: usize> DisplayBuffer<SIZE> {
+ #[inline]
+ pub const fn new() -> Self {
+ Self { buf: MaybeUninit::uninit_array(), len: 0 }
+ }
+
+ #[inline]
+ pub fn as_str(&self) -> &str {
+ // SAFETY: `buf` is only written to by the `fmt::Write::write_str` implementation
+ // which writes a valid UTF-8 string to `buf` and correctly sets `len`.
+ unsafe {
+ let s = MaybeUninit::slice_assume_init_ref(&self.buf[..self.len]);
+ str::from_utf8_unchecked(s)
+ }
+ }
+}
+
+impl<const SIZE: usize> fmt::Write for DisplayBuffer<SIZE> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ let bytes = s.as_bytes();
+
+ if let Some(buf) = self.buf.get_mut(self.len..(self.len + bytes.len())) {
+ MaybeUninit::write_slice(buf, bytes);
+ self.len += bytes.len();
+ Ok(())
+ } else {
+ Err(fmt::Error)
+ }
+ }
+}
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip_addr.rs
index 41ca9ba84..4f14fc280 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip_addr.rs
@@ -3,12 +3,13 @@
mod tests;
use crate::cmp::Ordering;
-use crate::fmt::{self, Write as FmtWrite};
-use crate::io::Write as IoWrite;
+use crate::fmt::{self, Write};
use crate::mem::transmute;
use crate::sys::net::netc as c;
use crate::sys_common::{FromInner, IntoInner};
+use super::display_buffer::DisplayBuffer;
+
/// An IP address, either IPv4 or IPv6.
///
/// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their
@@ -28,6 +29,7 @@ use crate::sys_common::{FromInner, IntoInner};
/// assert_eq!(localhost_v4.is_ipv6(), false);
/// assert_eq!(localhost_v4.is_ipv4(), true);
/// ```
+#[cfg_attr(not(test), rustc_diagnostic_item = "IpAddr")]
#[stable(feature = "ip_addr", since = "1.7.0")]
#[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub enum IpAddr {
@@ -71,6 +73,7 @@ pub enum IpAddr {
/// assert!("0xcb.0x0.0x71.0x00".parse::<Ipv4Addr>().is_err()); // all octets are in hex
/// ```
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Ipv4Addr")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Ipv4Addr {
octets: [u8; 4],
@@ -153,6 +156,7 @@ pub struct Ipv4Addr {
/// assert_eq!(localhost.is_loopback(), true);
/// ```
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Ipv6Addr")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Ipv6Addr {
octets: [u8; 16],
@@ -618,25 +622,31 @@ impl Ipv4Addr {
matches!(self.octets(), [169, 254, ..])
}
- /// Returns [`true`] if the address appears to be globally routable.
- /// See [iana-ipv4-special-registry][ipv4-sr].
+ /// Returns [`true`] if the address appears to be globally reachable
+ /// as specified by the [IANA IPv4 Special-Purpose Address Registry].
+ /// Whether or not an address is practically reachable will depend on your network configuration.
+ ///
+ /// Most IPv4 addresses are globally reachable;
+ /// unless they are specifically defined as *not* globally reachable.
///
- /// The following return [`false`]:
+ /// Non-exhaustive list of notable addresses that are not globally reachable:
///
- /// - private addresses (see [`Ipv4Addr::is_private()`])
- /// - the loopback address (see [`Ipv4Addr::is_loopback()`])
- /// - the link-local address (see [`Ipv4Addr::is_link_local()`])
- /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
- /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
- /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
- /// `0.0.0.0/8` block
- /// - addresses reserved for future protocols, except
- /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
- /// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`]
- /// - addresses reserved for networking devices benchmarking (see
- /// [`Ipv4Addr::is_benchmarking()`])
+ /// - The [unspecified address] ([`is_unspecified`](Ipv4Addr::is_unspecified))
+ /// - Addresses reserved for private use ([`is_private`](Ipv4Addr::is_private))
+ /// - Addresses in the shared address space ([`is_shared`](Ipv4Addr::is_shared))
+ /// - Loopback addresses ([`is_loopback`](Ipv4Addr::is_loopback))
+ /// - Link-local addresses ([`is_link_local`](Ipv4Addr::is_link_local))
+ /// - Addresses reserved for documentation ([`is_documentation`](Ipv4Addr::is_documentation))
+ /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv4Addr::is_benchmarking))
+ /// - Reserved addresses ([`is_reserved`](Ipv4Addr::is_reserved))
+ /// - The [broadcast address] ([`is_broadcast`](Ipv4Addr::is_broadcast))
///
- /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
+ /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv4 Special-Purpose Address Registry].
+ ///
+ /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
+ /// [unspecified address]: Ipv4Addr::UNSPECIFIED
+ /// [broadcast address]: Ipv4Addr::BROADCAST
+
///
/// # Examples
///
@@ -645,71 +655,61 @@ impl Ipv4Addr {
///
/// use std::net::Ipv4Addr;
///
- /// // private addresses are not global
+ /// // Most IPv4 addresses are globally reachable:
+ /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
+ ///
+ /// // However some addresses have been assigned a special meaning
+ /// // that makes them not globally reachable. Some examples are:
+ ///
+ /// // The unspecified address (`0.0.0.0`)
+ /// assert_eq!(Ipv4Addr::UNSPECIFIED.is_global(), false);
+ ///
+ /// // Addresses reserved for private use (`10.0.0.0/8`, `172.16.0.0/12`, 192.168.0.0/16)
/// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
/// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
/// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
///
- /// // the 0.0.0.0/8 block is not global
- /// assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
- /// // in particular, the unspecified address is not global
- /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
+ /// // Addresses in the shared address space (`100.64.0.0/10`)
+ /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
///
- /// // the loopback address is not global
- /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_global(), false);
+ /// // The loopback addresses (`127.0.0.0/8`)
+ /// assert_eq!(Ipv4Addr::LOCALHOST.is_global(), false);
///
- /// // link local addresses are not global
+ /// // Link-local addresses (`169.254.0.0/16`)
/// assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
///
- /// // the broadcast address is not global
- /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
- ///
- /// // the address space designated for documentation is not global
+ /// // Addresses reserved for documentation (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`)
/// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
/// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
/// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
///
- /// // shared addresses are not global
- /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
- ///
- /// // addresses reserved for protocol assignment are not global
- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
+ /// // Addresses reserved for benchmarking (`198.18.0.0/15`)
+ /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
///
- /// // addresses reserved for future use are not global
+ /// // Reserved addresses (`240.0.0.0/4`)
/// assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
///
- /// // addresses reserved for network devices benchmarking are not global
- /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
+ /// // The broadcast address (`255.255.255.255`)
+ /// assert_eq!(Ipv4Addr::BROADCAST.is_global(), false);
///
- /// // All the other addresses are global
- /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
- /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
+ /// // For a complete overview see the IANA IPv4 Special-Purpose Address Registry.
/// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[unstable(feature = "ip", issue = "27709")]
#[must_use]
#[inline]
pub const fn is_global(&self) -> bool {
- // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
- // globally routable addresses in the 192.0.0.0/24 range.
- if u32::from_be_bytes(self.octets()) == 0xc0000009
- || u32::from_be_bytes(self.octets()) == 0xc000000a
- {
- return true;
- }
- !self.is_private()
- && !self.is_loopback()
- && !self.is_link_local()
- && !self.is_broadcast()
- && !self.is_documentation()
- && !self.is_shared()
+ !(self.octets()[0] == 0 // "This network"
+ || self.is_private()
+ || self.is_shared()
+ || self.is_loopback()
+ || self.is_link_local()
// addresses reserved for future protocols (`192.0.0.0/24`)
- && !(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0)
- && !self.is_reserved()
- && !self.is_benchmarking()
- // Make sure the address is not in 0.0.0.0/8
- && self.octets()[0] != 0
+ ||(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0)
+ || self.is_documentation()
+ || self.is_benchmarking()
+ || self.is_reserved()
+ || self.is_broadcast())
}
/// Returns [`true`] if this address is part of the Shared Address Space defined in
@@ -991,21 +991,19 @@ impl From<Ipv6Addr> for IpAddr {
impl fmt::Display for Ipv4Addr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let octets = self.octets();
- // Fast Path: if there's no alignment stuff, write directly to the buffer
+
+ // If there are no alignment requirements, write the IP address directly to `f`.
+ // Otherwise, write it to a local buffer and then use `f.pad`.
if fmt.precision().is_none() && fmt.width().is_none() {
write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
} else {
- const IPV4_BUF_LEN: usize = 15; // Long enough for the longest possible IPv4 address
- let mut buf = [0u8; IPV4_BUF_LEN];
- let mut buf_slice = &mut buf[..];
+ const LONGEST_IPV4_ADDR: &str = "255.255.255.255";
- // Note: The call to write should never fail, hence the unwrap
- write!(buf_slice, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]).unwrap();
- let len = IPV4_BUF_LEN - buf_slice.len();
+ let mut buf = DisplayBuffer::<{ LONGEST_IPV4_ADDR.len() }>::new();
+ // Buffer is long enough for the longest possible IPv4 address, so this should never fail.
+ write!(buf, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]).unwrap();
- // This unsafe is OK because we know what is being written to the buffer
- let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
- fmt.pad(buf)
+ fmt.pad(buf.as_str())
}
}
}
@@ -1300,13 +1298,33 @@ impl Ipv6Addr {
u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
}
- /// Returns [`true`] if the address appears to be globally routable.
+ /// Returns [`true`] if the address appears to be globally reachable
+ /// as specified by the [IANA IPv6 Special-Purpose Address Registry].
+ /// Whether or not an address is practically reachable will depend on your network configuration.
///
- /// The following return [`false`]:
+ /// Most IPv6 addresses are globally reachable;
+ /// unless they are specifically defined as *not* globally reachable.
///
- /// - the loopback address
- /// - link-local and unique local unicast addresses
- /// - interface-, link-, realm-, admin- and site-local multicast addresses
+ /// Non-exhaustive list of notable addresses that are not globally reachable:
+ /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified))
+ /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback))
+ /// - IPv4-mapped addresses
+ /// - Addresses reserved for benchmarking
+ /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation))
+ /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local))
+ /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local))
+ ///
+ /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv6 Special-Purpose Address Registry].
+ ///
+ /// Note that an address having global scope is not the same as being globally reachable,
+ /// and there is no direct relation between the two concepts: There exist addresses with global scope
+ /// that are not globally reachable (for example unique local addresses),
+ /// and addresses that are globally reachable without having global scope
+ /// (multicast addresses with non-global scope).
+ ///
+ /// [IANA IPv6 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
+ /// [unspecified address]: Ipv6Addr::UNSPECIFIED
+ /// [loopback address]: Ipv6Addr::LOCALHOST
///
/// # Examples
///
@@ -1315,20 +1333,65 @@ impl Ipv6Addr {
///
/// use std::net::Ipv6Addr;
///
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
+ /// // Most IPv6 addresses are globally reachable:
+ /// assert_eq!(Ipv6Addr::new(0x26, 0, 0x1c9, 0, 0, 0xafc8, 0x10, 0x1).is_global(), true);
+ ///
+ /// // However some addresses have been assigned a special meaning
+ /// // that makes them not globally reachable. Some examples are:
+ ///
+ /// // The unspecified address (`::`)
+ /// assert_eq!(Ipv6Addr::UNSPECIFIED.is_global(), false);
+ ///
+ /// // The loopback address (`::1`)
+ /// assert_eq!(Ipv6Addr::LOCALHOST.is_global(), false);
+ ///
+ /// // IPv4-mapped addresses (`::ffff:0:0/96`)
+ /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), false);
+ ///
+ /// // Addresses reserved for benchmarking (`2001:2::/48`)
+ /// assert_eq!(Ipv6Addr::new(0x2001, 2, 0, 0, 0, 0, 0, 1,).is_global(), false);
+ ///
+ /// // Addresses reserved for documentation (`2001:db8::/32`)
+ /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1).is_global(), false);
+ ///
+ /// // Unique local addresses (`fc00::/7`)
+ /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 1).is_global(), false);
+ ///
+ /// // Unicast addresses with link-local scope (`fe80::/10`)
+ /// assert_eq!(Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 1).is_global(), false);
+ ///
+ /// // For a complete overview see the IANA IPv6 Special-Purpose Address Registry.
/// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[unstable(feature = "ip", issue = "27709")]
#[must_use]
#[inline]
pub const fn is_global(&self) -> bool {
- match self.multicast_scope() {
- Some(Ipv6MulticastScope::Global) => true,
- None => self.is_unicast_global(),
- _ => false,
- }
+ !(self.is_unspecified()
+ || self.is_loopback()
+ // IPv4-mapped Address (`::ffff:0:0/96`)
+ || matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
+ // IPv4-IPv6 Translat. (`64:ff9b:1::/48`)
+ || matches!(self.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
+ // Discard-Only Address Block (`100::/64`)
+ || matches!(self.segments(), [0x100, 0, 0, 0, _, _, _, _])
+ // IETF Protocol Assignments (`2001::/23`)
+ || (matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
+ && !(
+ // Port Control Protocol Anycast (`2001:1::1`)
+ u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
+ // Traversal Using Relays around NAT Anycast (`2001:1::2`)
+ || u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
+ // AMT (`2001:3::/32`)
+ || matches!(self.segments(), [0x2001, 3, _, _, _, _, _, _])
+ // AS112-v6 (`2001:4:112::/48`)
+ || matches!(self.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
+ // ORCHIDv2 (`2001:20::/28`)
+ || matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
+ ))
+ || self.is_documentation()
+ || self.is_unique_local()
+ || self.is_unicast_link_local())
}
/// Returns [`true`] if this is a unique local address (`fc00::/7`).
@@ -1525,6 +1588,7 @@ impl Ipv6Addr {
&& !self.is_unique_local()
&& !self.is_unspecified()
&& !self.is_documentation()
+ && !self.is_benchmarking()
}
/// Returns the address's multicast scope if the address is multicast.
@@ -1708,8 +1772,8 @@ impl Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for Ipv6Addr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // If there are no alignment requirements, write out the IP address to
- // f. Otherwise, write it to a local buffer, then use f.pad.
+ // If there are no alignment requirements, write the IP address directly to `f`.
+ // Otherwise, write it to a local buffer and then use `f.pad`.
if f.precision().is_none() && f.width().is_none() {
let segments = self.segments();
@@ -1780,22 +1844,13 @@ impl fmt::Display for Ipv6Addr {
}
}
} else {
- // Slow path: write the address to a local buffer, then use f.pad.
- // Defined recursively by using the fast path to write to the
- // buffer.
-
- // This is the largest possible size of an IPv6 address
- const IPV6_BUF_LEN: usize = (4 * 8) + 7;
- let mut buf = [0u8; IPV6_BUF_LEN];
- let mut buf_slice = &mut buf[..];
-
- // Note: This call to write should never fail, so unwrap is okay.
- write!(buf_slice, "{}", self).unwrap();
- let len = IPV6_BUF_LEN - buf_slice.len();
-
- // This is safe because we know exactly what can be in this buffer
- let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
- f.pad(buf)
+ const LONGEST_IPV6_ADDR: &str = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
+
+ let mut buf = DisplayBuffer::<{ LONGEST_IPV6_ADDR.len() }>::new();
+ // Buffer is long enough for the longest possible IPv6 address, so this should never fail.
+ write!(buf, "{}", self).unwrap();
+
+ f.pad(buf.as_str())
}
}
}
diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip_addr/tests.rs
index c29509331..7c3430b2b 100644
--- a/library/std/src/net/ip/tests.rs
+++ b/library/std/src/net/ip_addr/tests.rs
@@ -321,15 +321,15 @@ fn ip_properties() {
check!("fe80:ffff::");
check!("febf:ffff::");
check!("fec0::", global);
- check!("ff01::", multicast);
- check!("ff02::", multicast);
- check!("ff03::", multicast);
- check!("ff04::", multicast);
- check!("ff05::", multicast);
- check!("ff08::", multicast);
+ check!("ff01::", global | multicast);
+ check!("ff02::", global | multicast);
+ check!("ff03::", global | multicast);
+ check!("ff04::", global | multicast);
+ check!("ff05::", global | multicast);
+ check!("ff08::", global | multicast);
check!("ff0e::", global | multicast);
check!("2001:db8:85a3::8a2e:370:7334", doc);
- check!("2001:2::ac32:23ff:21", global | benchmarking);
+ check!("2001:2::ac32:23ff:21", benchmarking);
check!("102:304:506:708:90a:b0c:d0e:f10", global);
}
@@ -609,6 +609,60 @@ fn ipv6_properties() {
check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global);
+ check!(
+ "::ffff:127.0.0.1",
+ &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1],
+ unicast_global
+ );
+
+ check!(
+ "64:ff9b:1::",
+ &[0, 0x64, 0xff, 0x9b, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ unicast_global
+ );
+
+ check!("100::", &[0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
+
+ check!("2001::", &[0x20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
+
+ check!(
+ "2001:1::1",
+ &[0x20, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ global | unicast_global
+ );
+
+ check!(
+ "2001:1::2",
+ &[0x20, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
+ global | unicast_global
+ );
+
+ check!(
+ "2001:3::",
+ &[0x20, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ global | unicast_global
+ );
+
+ check!(
+ "2001:4:112::",
+ &[0x20, 1, 0, 4, 1, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ global | unicast_global
+ );
+
+ check!(
+ "2001:20::",
+ &[0x20, 1, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ global | unicast_global
+ );
+
+ check!("2001:30::", &[0x20, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
+
+ check!(
+ "2001:200::",
+ &[0x20, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ global | unicast_global
+ );
+
check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
check!(
@@ -666,21 +720,37 @@ fn ipv6_properties() {
check!(
"ff01::",
&[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- multicast_interface_local
+ multicast_interface_local | global
);
- check!("ff02::", &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_link_local);
+ check!(
+ "ff02::",
+ &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ multicast_link_local | global
+ );
- check!("ff03::", &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_realm_local);
+ check!(
+ "ff03::",
+ &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ multicast_realm_local | global
+ );
- check!("ff04::", &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_admin_local);
+ check!(
+ "ff04::",
+ &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ multicast_admin_local | global
+ );
- check!("ff05::", &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_site_local);
+ check!(
+ "ff05::",
+ &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ multicast_site_local | global
+ );
check!(
"ff08::",
&[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- multicast_organization_local
+ multicast_organization_local | global
);
check!(
@@ -698,7 +768,7 @@ fn ipv6_properties() {
check!(
"2001:2::ac32:23ff:21",
&[0x20, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0xac, 0x32, 0x23, 0xff, 0, 0x21],
- global | unicast_global | benchmarking
+ benchmarking
);
check!(
diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs
index e7a40bdaf..01e3db9de 100644
--- a/library/std/src/net/mod.rs
+++ b/library/std/src/net/mod.rs
@@ -24,11 +24,11 @@
use crate::io::{self, ErrorKind};
#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
+pub use self::ip_addr::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::parser::AddrParseError;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::socket_addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
pub use self::tcp::IntoIncoming;
#[stable(feature = "rust1", since = "1.0.0")]
@@ -36,12 +36,13 @@ pub use self::tcp::{Incoming, TcpListener, TcpStream};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::udp::UdpSocket;
-mod addr;
-mod ip;
+mod display_buffer;
+mod ip_addr;
mod parser;
+mod socket_addr;
mod tcp;
#[cfg(test)]
-mod test;
+pub(crate) mod test;
mod udp;
/// Possible values which can be passed to the [`TcpStream::shutdown`] method.
diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs
index 069b66099..a38031c48 100644
--- a/library/std/src/net/parser.rs
+++ b/library/std/src/net/parser.rs
@@ -39,8 +39,8 @@ struct Parser<'a> {
}
impl<'a> Parser<'a> {
- fn new(input: &'a str) -> Parser<'a> {
- Parser { state: input.as_bytes() }
+ fn new(input: &'a [u8]) -> Parser<'a> {
+ Parser { state: input }
}
/// Run a parser, and restore the pre-parse state if it fails.
@@ -273,32 +273,106 @@ impl<'a> Parser<'a> {
}
}
+impl IpAddr {
+ /// Parse an IP address from a slice of bytes.
+ ///
+ /// ```
+ /// #![feature(addr_parse_ascii)]
+ ///
+ /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
+ ///
+ /// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
+ /// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+ ///
+ /// assert_eq!(IpAddr::parse_ascii(b"127.0.0.1"), Ok(localhost_v4));
+ /// assert_eq!(IpAddr::parse_ascii(b"::1"), Ok(localhost_v6));
+ /// ```
+ #[unstable(feature = "addr_parse_ascii", issue = "101035")]
+ pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
+ Parser::new(b).parse_with(|p| p.read_ip_addr(), AddrKind::Ip)
+ }
+}
+
#[stable(feature = "ip_addr", since = "1.7.0")]
impl FromStr for IpAddr {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
- Parser::new(s).parse_with(|p| p.read_ip_addr(), AddrKind::Ip)
+ Self::parse_ascii(s.as_bytes())
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl FromStr for Ipv4Addr {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
+impl Ipv4Addr {
+ /// Parse an IPv4 address from a slice of bytes.
+ ///
+ /// ```
+ /// #![feature(addr_parse_ascii)]
+ ///
+ /// use std::net::Ipv4Addr;
+ ///
+ /// let localhost = Ipv4Addr::new(127, 0, 0, 1);
+ ///
+ /// assert_eq!(Ipv4Addr::parse_ascii(b"127.0.0.1"), Ok(localhost));
+ /// ```
+ #[unstable(feature = "addr_parse_ascii", issue = "101035")]
+ pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
// don't try to parse if too long
- if s.len() > 15 {
+ if b.len() > 15 {
Err(AddrParseError(AddrKind::Ipv4))
} else {
- Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4)
+ Parser::new(b).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4)
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
+impl FromStr for Ipv4Addr {
+ type Err = AddrParseError;
+ fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
+ Self::parse_ascii(s.as_bytes())
+ }
+}
+
+impl Ipv6Addr {
+ /// Parse an IPv6 address from a slice of bytes.
+ ///
+ /// ```
+ /// #![feature(addr_parse_ascii)]
+ ///
+ /// use std::net::Ipv6Addr;
+ ///
+ /// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
+ ///
+ /// assert_eq!(Ipv6Addr::parse_ascii(b"::1"), Ok(localhost));
+ /// ```
+ #[unstable(feature = "addr_parse_ascii", issue = "101035")]
+ pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
+ Parser::new(b).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv6Addr {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
- Parser::new(s).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6)
+ Self::parse_ascii(s.as_bytes())
+ }
+}
+
+impl SocketAddrV4 {
+ /// Parse an IPv4 socket address from a slice of bytes.
+ ///
+ /// ```
+ /// #![feature(addr_parse_ascii)]
+ ///
+ /// use std::net::{Ipv4Addr, SocketAddrV4};
+ ///
+ /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+ ///
+ /// assert_eq!(SocketAddrV4::parse_ascii(b"127.0.0.1:8080"), Ok(socket));
+ /// ```
+ #[unstable(feature = "addr_parse_ascii", issue = "101035")]
+ pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
+ Parser::new(b).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4)
}
}
@@ -306,7 +380,25 @@ impl FromStr for Ipv6Addr {
impl FromStr for SocketAddrV4 {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
- Parser::new(s).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4)
+ Self::parse_ascii(s.as_bytes())
+ }
+}
+
+impl SocketAddrV6 {
+ /// Parse an IPv6 socket address from a slice of bytes.
+ ///
+ /// ```
+ /// #![feature(addr_parse_ascii)]
+ ///
+ /// use std::net::{Ipv6Addr, SocketAddrV6};
+ ///
+ /// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
+ ///
+ /// assert_eq!(SocketAddrV6::parse_ascii(b"[2001:db8::1]:8080"), Ok(socket));
+ /// ```
+ #[unstable(feature = "addr_parse_ascii", issue = "101035")]
+ pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
+ Parser::new(b).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6)
}
}
@@ -314,7 +406,27 @@ impl FromStr for SocketAddrV4 {
impl FromStr for SocketAddrV6 {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
- Parser::new(s).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6)
+ Self::parse_ascii(s.as_bytes())
+ }
+}
+
+impl SocketAddr {
+ /// Parse a socket address from a slice of bytes.
+ ///
+ /// ```
+ /// #![feature(addr_parse_ascii)]
+ ///
+ /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
+ ///
+ /// let socket_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
+ /// let socket_v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8080);
+ ///
+ /// assert_eq!(SocketAddr::parse_ascii(b"127.0.0.1:8080"), Ok(socket_v4));
+ /// assert_eq!(SocketAddr::parse_ascii(b"[::1]:8080"), Ok(socket_v6));
+ /// ```
+ #[unstable(feature = "addr_parse_ascii", issue = "101035")]
+ pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
+ Parser::new(b).parse_with(|p| p.read_socket_addr(), AddrKind::Socket)
}
}
@@ -322,7 +434,7 @@ impl FromStr for SocketAddrV6 {
impl FromStr for SocketAddr {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
- Parser::new(s).parse_with(|p| p.read_socket_addr(), AddrKind::Socket)
+ Self::parse_ascii(s.as_bytes())
}
}
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/socket_addr.rs
index 53fee952a..33b0dfa03 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/socket_addr.rs
@@ -2,9 +2,9 @@
mod tests;
use crate::cmp::Ordering;
-use crate::fmt;
+use crate::fmt::{self, Write};
use crate::hash;
-use crate::io::{self, Write};
+use crate::io;
use crate::iter;
use crate::mem;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
@@ -15,6 +15,8 @@ use crate::sys_common::net::LookupHost;
use crate::sys_common::{FromInner, IntoInner};
use crate::vec;
+use super::display_buffer::DisplayBuffer;
+
/// An internet socket address, either IPv4 or IPv6.
///
/// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
@@ -616,25 +618,18 @@ impl fmt::Debug for SocketAddr {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for SocketAddrV4 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // Fast path: if there's no alignment stuff, write to the output buffer
- // directly
+ // If there are no alignment requirements, write the socket address directly to `f`.
+ // Otherwise, write it to a local buffer and then use `f.pad`.
if f.precision().is_none() && f.width().is_none() {
write!(f, "{}:{}", self.ip(), self.port())
} else {
- const IPV4_SOCKET_BUF_LEN: usize = (3 * 4) // the segments
- + 3 // the separators
- + 1 + 5; // the port
- let mut buf = [0; IPV4_SOCKET_BUF_LEN];
- let mut buf_slice = &mut buf[..];
-
- // Unwrap is fine because writing to a sufficiently-sized
- // buffer is infallible
- write!(buf_slice, "{}:{}", self.ip(), self.port()).unwrap();
- let len = IPV4_SOCKET_BUF_LEN - buf_slice.len();
-
- // This unsafe is OK because we know what is being written to the buffer
- let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
- f.pad(buf)
+ const LONGEST_IPV4_SOCKET_ADDR: &str = "255.255.255.255:65536";
+
+ let mut buf = DisplayBuffer::<{ LONGEST_IPV4_SOCKET_ADDR.len() }>::new();
+ // Buffer is long enough for the longest possible IPv4 socket address, so this should never fail.
+ write!(buf, "{}:{}", self.ip(), self.port()).unwrap();
+
+ f.pad(buf.as_str())
}
}
}
@@ -649,35 +644,26 @@ impl fmt::Debug for SocketAddrV4 {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for SocketAddrV6 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // Fast path: if there's no alignment stuff, write to the output
- // buffer directly
+ // If there are no alignment requirements, write the socket address directly to `f`.
+ // Otherwise, write it to a local buffer and then use `f.pad`.
if f.precision().is_none() && f.width().is_none() {
match self.scope_id() {
0 => write!(f, "[{}]:{}", self.ip(), self.port()),
scope_id => write!(f, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
}
} else {
- const IPV6_SOCKET_BUF_LEN: usize = (4 * 8) // The address
- + 7 // The colon separators
- + 2 // The brackets
- + 1 + 10 // The scope id
- + 1 + 5; // The port
-
- let mut buf = [0; IPV6_SOCKET_BUF_LEN];
- let mut buf_slice = &mut buf[..];
+ const LONGEST_IPV6_SOCKET_ADDR: &str =
+ "[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%4294967296]:65536";
+ let mut buf = DisplayBuffer::<{ LONGEST_IPV6_SOCKET_ADDR.len() }>::new();
match self.scope_id() {
- 0 => write!(buf_slice, "[{}]:{}", self.ip(), self.port()),
- scope_id => write!(buf_slice, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
+ 0 => write!(buf, "[{}]:{}", self.ip(), self.port()),
+ scope_id => write!(buf, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
}
- // Unwrap is fine because writing to a sufficiently-sized
- // buffer is infallible
+ // Buffer is long enough for the longest possible IPv6 socket address, so this should never fail.
.unwrap();
- let len = IPV6_SOCKET_BUF_LEN - buf_slice.len();
- // This unsafe is OK because we know what is being written to the buffer
- let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
- f.pad(buf)
+ f.pad(buf.as_str())
}
}
}
diff --git a/library/std/src/net/addr/tests.rs b/library/std/src/net/socket_addr/tests.rs
index 585a17451..15211f819 100644
--- a/library/std/src/net/addr/tests.rs
+++ b/library/std/src/net/socket_addr/tests.rs
@@ -52,6 +52,75 @@ fn to_socket_addr_string() {
}
#[test]
+fn ipv4_socket_addr_to_string() {
+ // Shortest possible IPv4 length.
+ assert_eq!(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0).to_string(), "0.0.0.0:0");
+
+ // Longest possible IPv4 length.
+ assert_eq!(
+ SocketAddrV4::new(Ipv4Addr::new(255, 255, 255, 255), u16::MAX).to_string(),
+ "255.255.255.255:65535"
+ );
+
+ // Test padding.
+ assert_eq!(
+ &format!("{:16}", SocketAddrV4::new(Ipv4Addr::new(1, 1, 1, 1), 53)),
+ "1.1.1.1:53 "
+ );
+ assert_eq!(
+ &format!("{:>16}", SocketAddrV4::new(Ipv4Addr::new(1, 1, 1, 1), 53)),
+ " 1.1.1.1:53"
+ );
+}
+
+#[test]
+fn ipv6_socket_addr_to_string() {
+ // IPv4-mapped address.
+ assert_eq!(
+ SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280), 8080, 0, 0)
+ .to_string(),
+ "[::ffff:192.0.2.128]:8080"
+ );
+
+ // IPv4-compatible address.
+ assert_eq!(
+ SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280), 8080, 0, 0).to_string(),
+ "[::192.0.2.128]:8080"
+ );
+
+ // IPv6 address with no zero segments.
+ assert_eq!(
+ SocketAddrV6::new(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15), 80, 0, 0).to_string(),
+ "[8:9:a:b:c:d:e:f]:80"
+ );
+
+ // Shortest possible IPv6 length.
+ assert_eq!(SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0).to_string(), "[::]:0");
+
+ // Longest possible IPv6 length.
+ assert_eq!(
+ SocketAddrV6::new(
+ Ipv6Addr::new(0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888),
+ u16::MAX,
+ u32::MAX,
+ u32::MAX,
+ )
+ .to_string(),
+ "[1111:2222:3333:4444:5555:6666:7777:8888%4294967295]:65535"
+ );
+
+ // Test padding.
+ assert_eq!(
+ &format!("{:22}", SocketAddrV6::new(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8), 9, 0, 0)),
+ "[1:2:3:4:5:6:7:8]:9 "
+ );
+ assert_eq!(
+ &format!("{:>22}", SocketAddrV6::new(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8), 9, 0, 0)),
+ " [1:2:3:4:5:6:7:8]:9"
+ );
+}
+
+#[test]
fn bind_udp_socket_bad() {
// rust-lang/rust#53957: This is a regression test for a parsing problem
// discovered as part of issue rust-lang/rust#23076, where we were
diff --git a/library/std/src/os/android/mod.rs b/library/std/src/os/android/mod.rs
index dbb0127f3..5adcb82b6 100644
--- a/library/std/src/os/android/mod.rs
+++ b/library/std/src/os/android/mod.rs
@@ -3,4 +3,5 @@
#![stable(feature = "raw_ext", since = "1.1.0")]
pub mod fs;
+pub mod net;
pub mod raw;
diff --git a/library/std/src/os/android/net.rs b/library/std/src/os/android/net.rs
new file mode 100644
index 000000000..ff96125c3
--- /dev/null
+++ b/library/std/src/os/android/net.rs
@@ -0,0 +1,4 @@
+//! Linux and Android-specific definitions for socket options.
+
+#![unstable(feature = "tcp_quickack", issue = "96256")]
+pub use crate::os::net::tcp::TcpStreamExt;
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index a463bc41d..71e33fb9e 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -104,7 +104,8 @@ impl BorrowedFd<'_> {
#[cfg(target_os = "espidf")]
let cmd = libc::F_DUPFD;
- let fd = cvt(unsafe { libc::fcntl(self.as_raw_fd(), cmd, 0) })?;
+ // Avoid using file descriptors below 3 as they are used for stdio
+ let fd = cvt(unsafe { libc::fcntl(self.as_raw_fd(), cmd, 3) })?;
Ok(unsafe { OwnedFd::from_raw_fd(fd) })
}
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 081915ed1..1b3d11042 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -14,7 +14,7 @@ use crate::os::wasi::io::OwnedFd;
use crate::sys_common::{AsInner, IntoInner};
/// Raw file descriptors.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;
@@ -23,7 +23,7 @@ pub type RawFd = raw::c_int;
/// This is only available on unix and WASI platforms and must be imported in
/// order to call the method. Windows platforms have a corresponding
/// `AsRawHandle` and `AsRawSocket` set of traits.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
/// Extracts the raw file descriptor.
@@ -59,7 +59,7 @@ pub trait AsRawFd {
/// A trait to express the ability to construct an object from a raw file
/// descriptor.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd {
/// Constructs a new instance of `Self` from the given raw file
@@ -103,7 +103,7 @@ pub trait FromRawFd {
/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor.
diff --git a/library/std/src/os/fortanix_sgx/mod.rs b/library/std/src/os/fortanix_sgx/mod.rs
index a40dabe19..39a42f4e1 100644
--- a/library/std/src/os/fortanix_sgx/mod.rs
+++ b/library/std/src/os/fortanix_sgx/mod.rs
@@ -26,10 +26,13 @@ pub mod usercalls {
free, insecure_time, launch_thread, read, read_alloc, send, wait, write,
};
pub use crate::sys::abi::usercalls::raw::{do_usercall, Usercalls as UsercallNrs};
+ pub use crate::sys::abi::usercalls::raw::{Register, RegisterArgument, ReturnValue};
// fortanix-sgx-abi re-exports
pub use crate::sys::abi::usercalls::raw::Error;
- pub use crate::sys::abi::usercalls::raw::{ByteBuffer, FifoDescriptor, Return, Usercall};
+ pub use crate::sys::abi::usercalls::raw::{
+ ByteBuffer, Cancel, FifoDescriptor, Return, Usercall,
+ };
pub use crate::sys::abi::usercalls::raw::{Fd, Result, Tcs};
pub use crate::sys::abi::usercalls::raw::{
EV_RETURNQ_NOT_EMPTY, EV_UNPARK, EV_USERCALLQ_NOT_FULL, FD_STDERR, FD_STDIN, FD_STDOUT,
diff --git a/library/std/src/os/linux/mod.rs b/library/std/src/os/linux/mod.rs
index 8e7776f66..c17053011 100644
--- a/library/std/src/os/linux/mod.rs
+++ b/library/std/src/os/linux/mod.rs
@@ -4,5 +4,6 @@
#![doc(cfg(target_os = "linux"))]
pub mod fs;
+pub mod net;
pub mod process;
pub mod raw;
diff --git a/library/std/src/os/linux/net.rs b/library/std/src/os/linux/net.rs
new file mode 100644
index 000000000..ff96125c3
--- /dev/null
+++ b/library/std/src/os/linux/net.rs
@@ -0,0 +1,4 @@
+//! Linux and Android-specific definitions for socket options.
+
+#![unstable(feature = "tcp_quickack", issue = "96256")]
+pub use crate::os::net::tcp::TcpStreamExt;
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 6fbaa42c7..18c64b510 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -148,3 +148,6 @@ pub mod vxworks;
#[cfg(any(unix, target_os = "wasi", doc))]
mod fd;
+
+#[cfg(any(target_os = "linux", target_os = "android", doc))]
+mod net;
diff --git a/library/std/src/os/net/mod.rs b/library/std/src/os/net/mod.rs
new file mode 100644
index 000000000..d6d84d24e
--- /dev/null
+++ b/library/std/src/os/net/mod.rs
@@ -0,0 +1,7 @@
+//! Linux and Android-specific definitions for socket options.
+
+#![unstable(feature = "tcp_quickack", issue = "96256")]
+#![doc(cfg(any(target_os = "linux", target_os = "android",)))]
+pub mod tcp;
+#[cfg(test)]
+mod tests;
diff --git a/library/std/src/os/net/tcp.rs b/library/std/src/os/net/tcp.rs
new file mode 100644
index 000000000..5e9ee65a4
--- /dev/null
+++ b/library/std/src/os/net/tcp.rs
@@ -0,0 +1,70 @@
+//! Linux and Android-specific tcp extensions to primitives in the [`std::net`] module.
+//!
+//! [`std::net`]: crate::net
+
+use crate::io;
+use crate::net;
+use crate::sealed::Sealed;
+use crate::sys_common::AsInner;
+
+/// Os-specific extensions for [`TcpStream`]
+///
+/// [`TcpStream`]: net::TcpStream
+#[unstable(feature = "tcp_quickack", issue = "96256")]
+pub trait TcpStreamExt: Sealed {
+ /// Enable or disable `TCP_QUICKACK`.
+ ///
+ /// This flag causes Linux to eagerly send ACKs rather than delaying them.
+ /// Linux may reset this flag after further operations on the socket.
+ ///
+ /// See [`man 7 tcp`](https://man7.org/linux/man-pages/man7/tcp.7.html) and
+ /// [TCP delayed acknowledgement](https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment)
+ /// for more information.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// #![feature(tcp_quickack)]
+ /// use std::net::TcpStream;
+ /// use std::os::linux::net::TcpStreamExt;
+ ///
+ /// let stream = TcpStream::connect("127.0.0.1:8080")
+ /// .expect("Couldn't connect to the server...");
+ /// stream.set_quickack(true).expect("set_quickack call failed");
+ /// ```
+ #[unstable(feature = "tcp_quickack", issue = "96256")]
+ fn set_quickack(&self, quickack: bool) -> io::Result<()>;
+
+ /// Gets the value of the `TCP_QUICKACK` option on this socket.
+ ///
+ /// For more information about this option, see [`TcpStreamExt::set_quickack`].
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// #![feature(tcp_quickack)]
+ /// use std::net::TcpStream;
+ /// use std::os::linux::net::TcpStreamExt;
+ ///
+ /// let stream = TcpStream::connect("127.0.0.1:8080")
+ /// .expect("Couldn't connect to the server...");
+ /// stream.set_quickack(true).expect("set_quickack call failed");
+ /// assert_eq!(stream.quickack().unwrap_or(false), true);
+ /// ```
+ #[unstable(feature = "tcp_quickack", issue = "96256")]
+ fn quickack(&self) -> io::Result<bool>;
+}
+
+#[unstable(feature = "tcp_quickack", issue = "96256")]
+impl Sealed for net::TcpStream {}
+
+#[unstable(feature = "tcp_quickack", issue = "96256")]
+impl TcpStreamExt for net::TcpStream {
+ fn set_quickack(&self, quickack: bool) -> io::Result<()> {
+ self.as_inner().as_inner().set_quickack(quickack)
+ }
+
+ fn quickack(&self) -> io::Result<bool> {
+ self.as_inner().as_inner().quickack()
+ }
+}
diff --git a/library/std/src/os/net/tests.rs b/library/std/src/os/net/tests.rs
new file mode 100644
index 000000000..4704e3156
--- /dev/null
+++ b/library/std/src/os/net/tests.rs
@@ -0,0 +1,29 @@
+#[cfg(any(target_os = "android", target_os = "linux",))]
+#[test]
+fn quickack() {
+ use crate::{
+ net::{test::next_test_ip4, TcpListener, TcpStream},
+ os::net::tcp::TcpStreamExt,
+ };
+
+ macro_rules! t {
+ ($e:expr) => {
+ match $e {
+ Ok(t) => t,
+ Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
+ }
+ };
+ }
+
+ let addr = next_test_ip4();
+ let _listener = t!(TcpListener::bind(&addr));
+
+ let stream = t!(TcpStream::connect(&("localhost", addr.port())));
+
+ t!(stream.set_quickack(false));
+ assert_eq!(false, t!(stream.quickack()));
+ t!(stream.set_quickack(true));
+ assert_eq!(true, t!(stream.quickack()));
+ t!(stream.set_quickack(false));
+ assert_eq!(false, t!(stream.quickack()));
+}
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 9aeae4b2c..094085e19 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -2,7 +2,7 @@ use crate::ffi::OsStr;
use crate::os::unix::ffi::OsStrExt;
use crate::path::Path;
use crate::sys::cvt;
-use crate::{ascii, fmt, io, mem, ptr};
+use crate::{fmt, io, mem, ptr};
// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
#[cfg(not(unix))]
@@ -64,18 +64,6 @@ enum AddressKind<'a> {
Abstract(&'a [u8]),
}
-struct AsciiEscaped<'a>(&'a [u8]);
-
-impl<'a> fmt::Display for AsciiEscaped<'a> {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(fmt, "\"")?;
- for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
- write!(fmt, "{}", byte as char)?;
- }
- write!(fmt, "\"")
- }
-}
-
/// An address associated with a Unix socket.
///
/// # Examples
@@ -329,7 +317,7 @@ impl SocketAddr {
crate::ptr::copy_nonoverlapping(
namespace.as_ptr(),
- addr.sun_path.as_mut_ptr().offset(1) as *mut u8,
+ addr.sun_path.as_mut_ptr().add(1) as *mut u8,
namespace.len(),
);
let len = (sun_path_offset(&addr) + 1 + namespace.len()) as libc::socklen_t;
@@ -343,7 +331,7 @@ impl fmt::Debug for SocketAddr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.address() {
AddressKind::Unnamed => write!(fmt, "(unnamed)"),
- AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
+ AddressKind::Abstract(name) => write!(fmt, "\"{}\" (abstract)", name.escape_ascii()),
AddressKind::Pathname(path) => write!(fmt, "{path:?} (pathname)"),
}
}
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 8008acfd1..f758f88d0 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -838,6 +838,31 @@ impl UnixDatagram {
self.0.passcred()
}
+ /// Set the id of the socket for network filtering purpose
+ ///
+ #[cfg_attr(
+ any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
+ doc = "```no_run"
+ )]
+ #[cfg_attr(
+ not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
+ doc = "```ignore"
+ )]
+ /// #![feature(unix_set_mark)]
+ /// use std::os::unix::net::UnixDatagram;
+ ///
+ /// fn main() -> std::io::Result<()> {
+ /// let sock = UnixDatagram::unbound()?;
+ /// sock.set_mark(32)?;
+ /// Ok(())
+ /// }
+ /// ```
+ #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
+ #[unstable(feature = "unix_set_mark", issue = "96467")]
+ pub fn set_mark(&self, mark: u32) -> io::Result<()> {
+ self.0.set_mark(mark)
+ }
+
/// Returns the value of the `SO_ERROR` option.
///
/// # Examples
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index 7c0d53950..02090afc8 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -73,9 +73,11 @@ impl UnixListener {
unsafe {
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
let (addr, len) = sockaddr_un(path.as_ref())?;
+ const backlog: libc::c_int =
+ if cfg!(any(target_os = "linux", target_os = "freebsd")) { -1 } else { 128 };
cvt(libc::bind(inner.as_inner().as_raw_fd(), &addr as *const _ as *const _, len as _))?;
- cvt(libc::listen(inner.as_inner().as_raw_fd(), 128))?;
+ cvt(libc::listen(inner.as_inner().as_raw_fd(), backlog))?;
Ok(UnixListener(inner))
}
@@ -109,12 +111,16 @@ impl UnixListener {
pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> {
unsafe {
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+ #[cfg(target_os = "linux")]
+ const backlog: libc::c_int = -1;
+ #[cfg(not(target_os = "linux"))]
+ const backlog: libc::c_int = 128;
cvt(libc::bind(
inner.as_raw_fd(),
&socket_addr.addr as *const _ as *const _,
socket_addr.len as _,
))?;
- cvt(libc::listen(inner.as_raw_fd(), 128))?;
+ cvt(libc::listen(inner.as_raw_fd(), backlog))?;
Ok(UnixListener(inner))
}
}
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index cc3a88587..dff8f6e85 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -427,6 +427,31 @@ impl UnixStream {
self.0.passcred()
}
+ /// Set the id of the socket for network filtering purpose
+ ///
+ #[cfg_attr(
+ any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
+ doc = "```no_run"
+ )]
+ #[cfg_attr(
+ not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
+ doc = "```ignore"
+ )]
+ /// #![feature(unix_set_mark)]
+ /// use std::os::unix::net::UnixStream;
+ ///
+ /// fn main() -> std::io::Result<()> {
+ /// let sock = UnixStream::connect("/tmp/sock")?;
+ /// sock.set_mark(32)?;
+ /// Ok(())
+ /// }
+ /// ```
+ #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
+ #[unstable(feature = "unix_set_mark", issue = "96467")]
+ pub fn set_mark(&self, mark: u32) -> io::Result<()> {
+ self.0.set_mark(mark)
+ }
+
/// Returns the value of the `SO_ERROR` option.
///
/// # Examples
diff --git a/library/std/src/os/wasi/io/fd.rs b/library/std/src/os/wasi/io/fd.rs
index 930aca887..75703af6a 100644
--- a/library/std/src/os/wasi/io/fd.rs
+++ b/library/std/src/os/wasi/io/fd.rs
@@ -1,9 +1,10 @@
//! Owned and borrowed file descriptors.
-#![unstable(feature = "wasi_ext", issue = "71213")]
+#![stable(feature = "io_safety_wasi", since = "1.65.0")]
// Tests for this module
#[cfg(test)]
mod tests;
+#[stable(feature = "io_safety_wasi", since = "1.65.0")]
pub use crate::os::fd::owned::*;
diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs
index 6c884e2ea..4f5cfbf9a 100644
--- a/library/std/src/os/wasi/io/mod.rs
+++ b/library/std/src/os/wasi/io/mod.rs
@@ -1,12 +1,12 @@
//! WASI-specific extensions to general I/O primitives.
#![deny(unsafe_op_in_unsafe_fn)]
-#![unstable(feature = "wasi_ext", issue = "71213")]
+#![stable(feature = "io_safety_wasi", since = "1.65.0")]
mod fd;
mod raw;
-#[unstable(feature = "wasi_ext", issue = "71213")]
+#[stable(feature = "io_safety_wasi", since = "1.65.0")]
pub use fd::*;
-#[unstable(feature = "wasi_ext", issue = "71213")]
+#[stable(feature = "io_safety_wasi", since = "1.65.0")]
pub use raw::*;
diff --git a/library/std/src/os/wasi/io/raw.rs b/library/std/src/os/wasi/io/raw.rs
index da3b36ada..4ac792ee8 100644
--- a/library/std/src/os/wasi/io/raw.rs
+++ b/library/std/src/os/wasi/io/raw.rs
@@ -1,20 +1,6 @@
//! WASI-specific extensions to general I/O primitives.
-#![unstable(feature = "wasi_ext", issue = "71213")]
+#![stable(feature = "io_safety_wasi", since = "1.65.0")]
-// NOTE: despite the fact that this module is unstable,
-// stable Rust had the capability to access the stable
-// re-exported items from os::fd::raw through this
-// unstable module.
-// In PR #95956 the stability checker was changed to check
-// all path segments of an item rather than just the last,
-// which caused the aforementioned stable usage to regress
-// (see issue #99502).
-// As a result, the items in os::fd::raw were given the
-// rustc_allowed_through_unstable_modules attribute.
-// No regression tests were added to ensure this property,
-// as CI is not configured to test wasm32-wasi.
-// If this module is stabilized,
-// you may want to remove those attributes
-// (assuming no other unstable modules need them).
+#[stable(feature = "io_safety_wasi", since = "1.65.0")]
pub use crate::os::fd::raw::*;
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 45bc56efb..c4f022de0 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -295,23 +295,22 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
return Some(style);
}
- // Setting environment variables for Fuchsia components isn't a standard
- // or easily supported workflow. For now, display backtraces by default.
- let format = if cfg!(target_os = "fuchsia") {
- BacktraceStyle::Full
- } else {
- crate::env::var_os("RUST_BACKTRACE")
- .map(|x| {
- if &x == "0" {
- BacktraceStyle::Off
- } else if &x == "full" {
- BacktraceStyle::Full
- } else {
- BacktraceStyle::Short
- }
- })
- .unwrap_or(BacktraceStyle::Off)
- };
+ let format = crate::env::var_os("RUST_BACKTRACE")
+ .map(|x| {
+ if &x == "0" {
+ BacktraceStyle::Off
+ } else if &x == "full" {
+ BacktraceStyle::Full
+ } else {
+ BacktraceStyle::Short
+ }
+ })
+ .unwrap_or(if cfg!(target_os = "fuchsia") {
+ // Fuchsia components default to full backtrace.
+ BacktraceStyle::Full
+ } else {
+ BacktraceStyle::Off
+ });
set_backtrace_style(format);
Some(format)
}
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index 351cf6988..dd307022c 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -1768,6 +1768,7 @@ fn test_windows_absolute() {
}
#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
let mut paths: Vec<_> =
@@ -1781,6 +1782,7 @@ fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
}
#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
@@ -1799,6 +1801,7 @@ fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
}
#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
let prefix = "my/home";
let paths: Vec<_> =
@@ -1817,6 +1820,7 @@ fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
}
#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
@@ -1835,6 +1839,7 @@ fn bench_path_hashset(b: &mut test::Bencher) {
}
#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset_miss(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
diff --git a/library/std/src/personality.rs b/library/std/src/personality.rs
new file mode 100644
index 000000000..63f0ad4f1
--- /dev/null
+++ b/library/std/src/personality.rs
@@ -0,0 +1,46 @@
+//! This module contains the implementation of the `eh_personality` lang item.
+//!
+//! The actual implementation is heavily dependent on the target since Rust
+//! tries to use the native stack unwinding mechanism whenever possible.
+//!
+//! This personality function is still required with `-C panic=abort` because
+//! it is used to catch foreign exceptions from `extern "C-unwind"` and turn
+//! them into aborts.
+//!
+//! Additionally, ARM EHABI uses the personality function when generating
+//! backtraces.
+
+mod dwarf;
+
+#[cfg(not(test))]
+cfg_if::cfg_if! {
+ if #[cfg(target_os = "emscripten")] {
+ mod emcc;
+ } else if #[cfg(target_env = "msvc")] {
+ // This is required by the compiler to exist (e.g., it's a lang item),
+ // but it's never actually called by the compiler because
+ // _CxxFrameHandler3 is the personality function that is always used.
+ // Hence this is just an aborting stub.
+ #[lang = "eh_personality"]
+ fn rust_eh_personality() {
+ core::intrinsics::abort()
+ }
+ } else if #[cfg(any(
+ all(target_family = "windows", target_env = "gnu"),
+ target_os = "psp",
+ target_os = "solid_asp3",
+ all(target_family = "unix", not(target_os = "espidf")),
+ all(target_vendor = "fortanix", target_env = "sgx"),
+ ))] {
+ mod gcc;
+ } else {
+ // Targets that don't support unwinding.
+ // - family=wasm
+ // - os=none ("bare metal" targets)
+ // - os=uefi
+ // - os=espidf
+ // - os=hermit
+ // - nvptx64-nvidia-cuda
+ // - arch=avr
+ }
+}
diff --git a/library/panic_unwind/src/dwarf/eh.rs b/library/std/src/personality/dwarf/eh.rs
index 7394feab8..8799137b7 100644
--- a/library/panic_unwind/src/dwarf/eh.rs
+++ b/library/std/src/personality/dwarf/eh.rs
@@ -11,7 +11,7 @@
#![allow(non_upper_case_globals)]
#![allow(unused)]
-use crate::dwarf::DwarfReader;
+use super::DwarfReader;
use core::mem;
pub const DW_EH_PE_omit: u8 = 0xFF;
@@ -75,7 +75,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
let call_site_encoding = reader.read::<u8>();
let call_site_table_length = reader.read_uleb128();
- let action_table = reader.ptr.offset(call_site_table_length as isize);
+ let action_table = reader.ptr.add(call_site_table_length as usize);
let ip = context.ip;
if !USING_SJLJ_EXCEPTIONS {
diff --git a/library/panic_unwind/src/dwarf/mod.rs b/library/std/src/personality/dwarf/mod.rs
index 652fbe95a..652fbe95a 100644
--- a/library/panic_unwind/src/dwarf/mod.rs
+++ b/library/std/src/personality/dwarf/mod.rs
diff --git a/library/panic_unwind/src/dwarf/tests.rs b/library/std/src/personality/dwarf/tests.rs
index 1644f3708..1644f3708 100644
--- a/library/panic_unwind/src/dwarf/tests.rs
+++ b/library/std/src/personality/dwarf/tests.rs
diff --git a/library/std/src/personality/emcc.rs b/library/std/src/personality/emcc.rs
new file mode 100644
index 000000000..f942bdf18
--- /dev/null
+++ b/library/std/src/personality/emcc.rs
@@ -0,0 +1,20 @@
+//! On Emscripten Rust panics are wrapped in C++ exceptions, so we just forward
+//! to `__gxx_personality_v0` which is provided by Emscripten.
+
+use libc::c_int;
+use unwind as uw;
+
+// This is required by the compiler to exist (e.g., it's a lang item), but it's
+// never actually called by the compiler. Emscripten EH doesn't use a
+// personality function at all, it instead uses __cxa_find_matching_catch.
+// Wasm error handling would use __gxx_personality_wasm0.
+#[lang = "eh_personality"]
+unsafe extern "C" fn rust_eh_personality(
+ _version: c_int,
+ _actions: uw::_Unwind_Action,
+ _exception_class: uw::_Unwind_Exception_Class,
+ _exception_object: *mut uw::_Unwind_Exception,
+ _context: *mut uw::_Unwind_Context,
+) -> uw::_Unwind_Reason_Code {
+ core::intrinsics::abort()
+}
diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs
new file mode 100644
index 000000000..7f0b0439c
--- /dev/null
+++ b/library/std/src/personality/gcc.rs
@@ -0,0 +1,279 @@
+//! Implementation of panics backed by libgcc/libunwind (in some form).
+//!
+//! For background on exception handling and stack unwinding please see
+//! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
+//! documents linked from it.
+//! These are also good reads:
+//! * <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html>
+//! * <https://monoinfinito.wordpress.com/series/exception-handling-in-c/>
+//! * <https://www.airs.com/blog/index.php?s=exception+frames>
+//!
+//! ## A brief summary
+//!
+//! Exception handling happens in two phases: a search phase and a cleanup
+//! phase.
+//!
+//! In both phases the unwinder walks stack frames from top to bottom using
+//! information from the stack frame unwind sections of the current process's
+//! modules ("module" here refers to an OS module, i.e., an executable or a
+//! dynamic library).
+//!
+//! For each stack frame, it invokes the associated "personality routine", whose
+//! address is also stored in the unwind info section.
+//!
+//! In the search phase, the job of a personality routine is to examine
+//! exception object being thrown, and to decide whether it should be caught at
+//! that stack frame. Once the handler frame has been identified, cleanup phase
+//! begins.
+//!
+//! In the cleanup phase, the unwinder invokes each personality routine again.
+//! This time it decides which (if any) cleanup code needs to be run for
+//! the current stack frame. If so, the control is transferred to a special
+//! branch in the function body, the "landing pad", which invokes destructors,
+//! frees memory, etc. At the end of the landing pad, control is transferred
+//! back to the unwinder and unwinding resumes.
+//!
+//! Once stack has been unwound down to the handler frame level, unwinding stops
+//! and the last personality routine transfers control to the catch block.
+
+use super::dwarf::eh::{self, EHAction, EHContext};
+use libc::{c_int, uintptr_t};
+use unwind as uw;
+
+// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
+// and TargetLowering::getExceptionSelectorRegister() for each architecture,
+// then mapped to DWARF register numbers via register definition tables
+// (typically <arch>RegisterInfo.td, search for "DwarfRegNum").
+// See also https://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register.
+
+#[cfg(target_arch = "x86")]
+const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX
+
+#[cfg(target_arch = "x86_64")]
+const UNWIND_DATA_REG: (i32, i32) = (0, 1); // RAX, RDX
+
+#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
+const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1
+
+#[cfg(target_arch = "m68k")]
+const UNWIND_DATA_REG: (i32, i32) = (0, 1); // D0, D1
+
+#[cfg(any(target_arch = "mips", target_arch = "mips64"))]
+const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1
+
+#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
+const UNWIND_DATA_REG: (i32, i32) = (3, 4); // R3, R4 / X3, X4
+
+#[cfg(target_arch = "s390x")]
+const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7
+
+#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
+const UNWIND_DATA_REG: (i32, i32) = (24, 25); // I0, I1
+
+#[cfg(target_arch = "hexagon")]
+const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1
+
+#[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
+const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
+
+// The following code is based on GCC's C and C++ personality routines. For reference, see:
+// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
+// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
+
+cfg_if::cfg_if! {
+ if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "watchos"), not(target_os = "netbsd")))] {
+ // ARM EHABI personality routine.
+ // https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
+ //
+ // iOS uses the default routine instead since it uses SjLj unwinding.
+ #[lang = "eh_personality"]
+ unsafe extern "C" fn rust_eh_personality(
+ state: uw::_Unwind_State,
+ exception_object: *mut uw::_Unwind_Exception,
+ context: *mut uw::_Unwind_Context,
+ ) -> uw::_Unwind_Reason_Code {
+ let state = state as c_int;
+ let action = state & uw::_US_ACTION_MASK as c_int;
+ let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
+ // Backtraces on ARM will call the personality routine with
+ // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
+ // we want to continue unwinding the stack, otherwise all our backtraces
+ // would end at __rust_try
+ if state & uw::_US_FORCE_UNWIND as c_int != 0 {
+ return continue_unwind(exception_object, context);
+ }
+ true
+ } else if action == uw::_US_UNWIND_FRAME_STARTING as c_int {
+ false
+ } else if action == uw::_US_UNWIND_FRAME_RESUME as c_int {
+ return continue_unwind(exception_object, context);
+ } else {
+ return uw::_URC_FAILURE;
+ };
+
+ // The DWARF unwinder assumes that _Unwind_Context holds things like the function
+ // and LSDA pointers, however ARM EHABI places them into the exception object.
+ // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
+ // take only the context pointer, GCC personality routines stash a pointer to
+ // exception_object in the context, using location reserved for ARM's
+ // "scratch register" (r12).
+ uw::_Unwind_SetGR(context, uw::UNWIND_POINTER_REG, exception_object as uw::_Unwind_Ptr);
+ // ...A more principled approach would be to provide the full definition of ARM's
+ // _Unwind_Context in our libunwind bindings and fetch the required data from there
+ // directly, bypassing DWARF compatibility functions.
+
+ let eh_action = match find_eh_action(context) {
+ Ok(action) => action,
+ Err(_) => return uw::_URC_FAILURE,
+ };
+ if search_phase {
+ match eh_action {
+ EHAction::None | EHAction::Cleanup(_) => {
+ return continue_unwind(exception_object, context);
+ }
+ EHAction::Catch(_) => {
+ // EHABI requires the personality routine to update the
+ // SP value in the barrier cache of the exception object.
+ (*exception_object).private[5] =
+ uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG);
+ return uw::_URC_HANDLER_FOUND;
+ }
+ EHAction::Terminate => return uw::_URC_FAILURE,
+ }
+ } else {
+ match eh_action {
+ EHAction::None => return continue_unwind(exception_object, context),
+ EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
+ uw::_Unwind_SetGR(
+ context,
+ UNWIND_DATA_REG.0,
+ exception_object as uintptr_t,
+ );
+ uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
+ uw::_Unwind_SetIP(context, lpad);
+ return uw::_URC_INSTALL_CONTEXT;
+ }
+ EHAction::Terminate => return uw::_URC_FAILURE,
+ }
+ }
+
+ // On ARM EHABI the personality routine is responsible for actually
+ // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
+ unsafe fn continue_unwind(
+ exception_object: *mut uw::_Unwind_Exception,
+ context: *mut uw::_Unwind_Context,
+ ) -> uw::_Unwind_Reason_Code {
+ if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
+ uw::_URC_CONTINUE_UNWIND
+ } else {
+ uw::_URC_FAILURE
+ }
+ }
+ // defined in libgcc
+ extern "C" {
+ fn __gnu_unwind_frame(
+ exception_object: *mut uw::_Unwind_Exception,
+ context: *mut uw::_Unwind_Context,
+ ) -> uw::_Unwind_Reason_Code;
+ }
+ }
+ } else {
+ // Default personality routine, which is used directly on most targets
+ // and indirectly on Windows x86_64 via SEH.
+ unsafe extern "C" fn rust_eh_personality_impl(
+ version: c_int,
+ actions: uw::_Unwind_Action,
+ _exception_class: uw::_Unwind_Exception_Class,
+ exception_object: *mut uw::_Unwind_Exception,
+ context: *mut uw::_Unwind_Context,
+ ) -> uw::_Unwind_Reason_Code {
+ if version != 1 {
+ return uw::_URC_FATAL_PHASE1_ERROR;
+ }
+ let eh_action = match find_eh_action(context) {
+ Ok(action) => action,
+ Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
+ };
+ if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
+ match eh_action {
+ EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
+ EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
+ EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
+ }
+ } else {
+ match eh_action {
+ EHAction::None => uw::_URC_CONTINUE_UNWIND,
+ EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
+ uw::_Unwind_SetGR(
+ context,
+ UNWIND_DATA_REG.0,
+ exception_object as uintptr_t,
+ );
+ uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
+ uw::_Unwind_SetIP(context, lpad);
+ uw::_URC_INSTALL_CONTEXT
+ }
+ EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
+ }
+ }
+ }
+
+ cfg_if::cfg_if! {
+ if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
+ // On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
+ // handler data (aka LSDA) uses GCC-compatible encoding.
+ #[lang = "eh_personality"]
+ #[allow(nonstandard_style)]
+ unsafe extern "C" fn rust_eh_personality(
+ exceptionRecord: *mut uw::EXCEPTION_RECORD,
+ establisherFrame: uw::LPVOID,
+ contextRecord: *mut uw::CONTEXT,
+ dispatcherContext: *mut uw::DISPATCHER_CONTEXT,
+ ) -> uw::EXCEPTION_DISPOSITION {
+ uw::_GCC_specific_handler(
+ exceptionRecord,
+ establisherFrame,
+ contextRecord,
+ dispatcherContext,
+ rust_eh_personality_impl,
+ )
+ }
+ } else {
+ // The personality routine for most of our targets.
+ #[lang = "eh_personality"]
+ unsafe extern "C" fn rust_eh_personality(
+ version: c_int,
+ actions: uw::_Unwind_Action,
+ exception_class: uw::_Unwind_Exception_Class,
+ exception_object: *mut uw::_Unwind_Exception,
+ context: *mut uw::_Unwind_Context,
+ ) -> uw::_Unwind_Reason_Code {
+ rust_eh_personality_impl(
+ version,
+ actions,
+ exception_class,
+ exception_object,
+ context,
+ )
+ }
+ }
+ }
+ }
+}
+
+unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
+ let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
+ let mut ip_before_instr: c_int = 0;
+ let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
+ let eh_context = EHContext {
+ // The return address points 1 byte past the call instruction,
+ // which could be in the next IP range in LSDA range table.
+ //
+ // `ip = -1` has special meaning, so use wrapping sub to allow for that
+ ip: if ip_before_instr != 0 { ip } else { ip.wrapping_sub(1) },
+ func_start: uw::_Unwind_GetRegionStart(context),
+ get_text_start: &|| uw::_Unwind_GetTextRelBase(context),
+ get_data_start: &|| uw::_Unwind_GetDataRelBase(context),
+ };
+ eh::find_eh_action(lsda, &eh_context)
+}
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index b8e546164..242f44ade 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -801,11 +801,53 @@ mod prim_array {}
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
/// ```
+///
+/// ## Trait Implementations
+///
+/// Some traits are implemented for slices if the element type implements
+/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`].
+///
+/// ## Iteration
+///
+/// The slices implement `IntoIterator`. The iterator yields references to the
+/// slice elements.
+///
+/// ```
+/// let numbers: &[i32] = &[0, 1, 2];
+/// for n in numbers {
+/// println!("{n} is a number!");
+/// }
+/// ```
+///
+/// The mutable slice yields mutable references to the elements:
+///
+/// ```
+/// let mut scores: &mut [i32] = &mut [7, 8, 9];
+/// for score in scores {
+/// *score += 1;
+/// }
+/// ```
+///
+/// This iterator yields mutable references to the slice's elements, so while
+/// the element type of the slice is `i32`, the element type of the iterator is
+/// `&mut i32`.
+///
+/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
+/// iterators.
+/// * Further methods that return iterators are [`.split`], [`.splitn`],
+/// [`.chunks`], [`.windows`] and more.
+///
+/// [`Hash`]: core::hash::Hash
+/// [`.iter`]: slice::iter
+/// [`.iter_mut`]: slice::iter_mut
+/// [`.split`]: slice::split
+/// [`.splitn`]: slice::splitn
+/// [`.chunks`]: slice::chunks
+/// [`.windows`]: slice::windows
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_slice {}
#[doc(primitive = "str")]
-//
/// String slices.
///
/// *[See also the `std::str` module](crate::str).*
@@ -816,19 +858,22 @@ mod prim_slice {}
///
/// String slices are always valid UTF-8.
///
-/// # Examples
+/// # Basic Usage
///
/// String literals are string slices:
///
/// ```
-/// let hello = "Hello, world!";
-///
-/// // with an explicit type annotation
-/// let hello: &'static str = "Hello, world!";
+/// let hello_world = "Hello, World!";
/// ```
///
-/// They are `'static` because they're stored directly in the final binary, and
-/// so will be valid for the `'static` duration.
+/// Here we have declared a string slice initialized with a string literal.
+/// String literals have a static lifetime, which means the string `hello_world`
+/// is guaranteed to be valid for the duration of the entire program.
+/// We can explicitly specify `hello_world`'s lifetime as well:
+///
+/// ```
+/// let hello_world: &'static str = "Hello, world!";
+/// ```
///
/// # Representation
///
@@ -996,7 +1041,7 @@ impl<T> (T,) {}
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Clone> Clone for (T,) {
fn clone(&self) -> Self {
@@ -1007,7 +1052,7 @@ impl<T: Clone> Clone for (T,) {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Copy> Copy for (T,) {
// empty
@@ -1178,7 +1223,7 @@ mod prim_usize {}
#[doc(alias = "&")]
#[doc(alias = "&mut")]
//
-/// References, both shared and mutable.
+/// References, `&T` and `&mut T`.
///
/// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut`
/// operators on a value, or by using a [`ref`](../std/keyword.ref.html) or
@@ -1484,13 +1529,12 @@ mod prim_fn {}
// Required to make auto trait impls render.
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
#[doc(hidden)]
-#[cfg(not(bootstrap))]
impl<Ret, T> fn(T) -> Ret {}
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Clone for fn(T) -> Ret {
fn clone(&self) -> Self {
@@ -1501,7 +1545,7 @@ impl<Ret, T> Clone for fn(T) -> Ret {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Copy for fn(T) -> Ret {
// empty
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index d6cba7e75..d91d4fa64 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -169,15 +169,15 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
pub struct Child {
pub(crate) handle: imp::Process,
- /// The handle for writing to the child's standard input (stdin), if it has
- /// been captured. To avoid partially moving
- /// the `child` and thus blocking yourself from calling
- /// functions on `child` while using `stdin`,
- /// you might find it helpful:
+ /// The handle for writing to the child's standard input (stdin), if it
+ /// has been captured. You might find it helpful to do
///
/// ```compile_fail,E0425
/// let stdin = child.stdin.take().unwrap();
/// ```
+ ///
+ /// to avoid partially moving the `child` and thus blocking yourself from calling
+ /// functions on `child` while using `stdin`.
#[stable(feature = "process", since = "1.0.0")]
pub stdin: Option<ChildStdin>,
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 663537a05..98f6cc7aa 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -72,10 +72,29 @@ macro_rules! rtunwrap {
// Runs before `main`.
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
+//
+// # The `sigpipe` parameter
+//
+// Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to
+// `SIG_IGN`. Applications have good reasons to want a different behavior
+// though, so there is a `#[unix_sigpipe = "..."]` attribute on `fn main()` that
+// can be used to select how `SIGPIPE` shall be setup (if changed at all) before
+// `fn main()` is called. See <https://github.com/rust-lang/rust/issues/97889>
+// for more info.
+//
+// The `sigpipe` parameter to this function gets its value via the code that
+// rustc generates to invoke `fn lang_start()`. The reason we have `sigpipe` for
+// all platforms and not only Unix, is because std is not allowed to have `cfg`
+// directives as this high level. See the module docs in
+// `src/tools/tidy/src/pal.rs` for more info. On all other platforms, `sigpipe`
+// has a value, but its value is ignored.
+//
+// Even though it is an `u8`, it only ever has 3 values. These are documented in
+// `compiler/rustc_session/src/config/sigpipe.rs`.
#[cfg_attr(test, allow(dead_code))]
-unsafe fn init(argc: isize, argv: *const *const u8) {
+unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
unsafe {
- sys::init(argc, argv);
+ sys::init(argc, argv, sigpipe);
let main_guard = sys::thread::guard::init();
// Next, set up the current Thread with the guard information we just
@@ -107,6 +126,7 @@ fn lang_start_internal(
main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),
argc: isize,
argv: *const *const u8,
+ sigpipe: u8,
) -> Result<isize, !> {
use crate::{mem, panic};
let rt_abort = move |e| {
@@ -124,7 +144,7 @@ fn lang_start_internal(
// prevent libstd from accidentally introducing a panic to these functions. Another is from
// user code from `main` or, more nefariously, as described in e.g. issue #86030.
// SAFETY: Only called once during runtime initialization.
- panic::catch_unwind(move || unsafe { init(argc, argv) }).map_err(rt_abort)?;
+ panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?;
let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
.map_err(move |e| {
mem::forget(e);
@@ -140,11 +160,16 @@ fn lang_start<T: crate::process::Termination + 'static>(
main: fn() -> T,
argc: isize,
argv: *const *const u8,
+ #[cfg(not(bootstrap))] sigpipe: u8,
) -> isize {
let Ok(v) = lang_start_internal(
&move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
argc,
argv,
+ #[cfg(bootstrap)]
+ 2, // Temporary inlining of sigpipe::DEFAULT until bootstrap stops being special
+ #[cfg(not(bootstrap))]
+ sigpipe,
);
v
}
diff --git a/library/std/src/sync/mpsc/mpsc_queue/tests.rs b/library/std/src/sync/mpsc/mpsc_queue/tests.rs
index 9f4f31ed0..34b2a9a98 100644
--- a/library/std/src/sync/mpsc/mpsc_queue/tests.rs
+++ b/library/std/src/sync/mpsc/mpsc_queue/tests.rs
@@ -13,7 +13,7 @@ fn test_full() {
#[test]
fn test() {
let nthreads = 8;
- let nmsgs = 1000;
+ let nmsgs = if cfg!(miri) { 100 } else { 1000 };
let q = Queue::new();
match q.pop() {
Empty => {}
diff --git a/library/std/src/sync/mpsc/spsc_queue/tests.rs b/library/std/src/sync/mpsc/spsc_queue/tests.rs
index 467ef3dbd..eb6d5c2cf 100644
--- a/library/std/src/sync/mpsc/spsc_queue/tests.rs
+++ b/library/std/src/sync/mpsc/spsc_queue/tests.rs
@@ -77,12 +77,13 @@ fn stress() {
}
unsafe fn stress_bound(bound: usize) {
+ let count = if cfg!(miri) { 1000 } else { 100000 };
let q = Arc::new(Queue::with_additions(bound, (), ()));
let (tx, rx) = channel();
let q2 = q.clone();
let _t = thread::spawn(move || {
- for _ in 0..100000 {
+ for _ in 0..count {
loop {
match q2.pop() {
Some(1) => break,
@@ -93,7 +94,7 @@ fn stress() {
}
tx.send(()).unwrap();
});
- for _ in 0..100000 {
+ for _ in 0..count {
q.push(1);
}
rx.recv().unwrap();
diff --git a/library/std/src/sync/mpsc/sync_tests.rs b/library/std/src/sync/mpsc/sync_tests.rs
index e58649bab..63c794369 100644
--- a/library/std/src/sync/mpsc/sync_tests.rs
+++ b/library/std/src/sync/mpsc/sync_tests.rs
@@ -113,23 +113,25 @@ fn chan_gone_concurrent() {
#[test]
fn stress() {
+ let count = if cfg!(miri) { 100 } else { 10000 };
let (tx, rx) = sync_channel::<i32>(0);
thread::spawn(move || {
- for _ in 0..10000 {
+ for _ in 0..count {
tx.send(1).unwrap();
}
});
- for _ in 0..10000 {
+ for _ in 0..count {
assert_eq!(rx.recv().unwrap(), 1);
}
}
#[test]
fn stress_recv_timeout_two_threads() {
+ let count = if cfg!(miri) { 100 } else { 10000 };
let (tx, rx) = sync_channel::<i32>(0);
thread::spawn(move || {
- for _ in 0..10000 {
+ for _ in 0..count {
tx.send(1).unwrap();
}
});
@@ -146,12 +148,12 @@ fn stress_recv_timeout_two_threads() {
}
}
- assert_eq!(recv_count, 10000);
+ assert_eq!(recv_count, count);
}
#[test]
fn stress_recv_timeout_shared() {
- const AMT: u32 = 1000;
+ const AMT: u32 = if cfg!(miri) { 100 } else { 1000 };
const NTHREADS: u32 = 8;
let (tx, rx) = sync_channel::<i32>(0);
let (dtx, drx) = sync_channel::<()>(0);
@@ -191,7 +193,7 @@ fn stress_recv_timeout_shared() {
#[test]
fn stress_shared() {
- const AMT: u32 = 1000;
+ const AMT: u32 = if cfg!(miri) { 100 } else { 1000 };
const NTHREADS: u32 = 8;
let (tx, rx) = sync_channel::<i32>(0);
let (dtx, drx) = sync_channel::<()>(0);
@@ -438,12 +440,13 @@ fn stream_send_recv_stress() {
#[test]
fn recv_a_lot() {
+ let count = if cfg!(miri) { 1000 } else { 10000 };
// Regression test that we don't run out of stack in scheduler context
- let (tx, rx) = sync_channel(10000);
- for _ in 0..10000 {
+ let (tx, rx) = sync_channel(count);
+ for _ in 0..count {
tx.send(()).unwrap();
}
- for _ in 0..10000 {
+ for _ in 0..count {
rx.recv().unwrap();
}
}
diff --git a/library/std/src/sync/mpsc/tests.rs b/library/std/src/sync/mpsc/tests.rs
index 4deb3e596..f6d0796f6 100644
--- a/library/std/src/sync/mpsc/tests.rs
+++ b/library/std/src/sync/mpsc/tests.rs
@@ -120,13 +120,14 @@ fn chan_gone_concurrent() {
#[test]
fn stress() {
+ let count = if cfg!(miri) { 100 } else { 10000 };
let (tx, rx) = channel::<i32>();
let t = thread::spawn(move || {
- for _ in 0..10000 {
+ for _ in 0..count {
tx.send(1).unwrap();
}
});
- for _ in 0..10000 {
+ for _ in 0..count {
assert_eq!(rx.recv().unwrap(), 1);
}
t.join().ok().expect("thread panicked");
@@ -134,7 +135,7 @@ fn stress() {
#[test]
fn stress_shared() {
- const AMT: u32 = 10000;
+ const AMT: u32 = if cfg!(miri) { 100 } else { 10000 };
const NTHREADS: u32 = 8;
let (tx, rx) = channel::<i32>();
@@ -504,12 +505,13 @@ fn very_long_recv_timeout_wont_panic() {
#[test]
fn recv_a_lot() {
+ let count = if cfg!(miri) { 1000 } else { 10000 };
// Regression test that we don't run out of stack in scheduler context
let (tx, rx) = channel();
- for _ in 0..10000 {
+ for _ in 0..count {
tx.send(()).unwrap();
}
- for _ in 0..10000 {
+ for _ in 0..count {
rx.recv().unwrap();
}
}
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index e0d13cd64..de851c8fb 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -192,6 +192,7 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
and cause Futures to not implement `Send`"]
#[stable(feature = "rust1", since = "1.0.0")]
#[clippy::has_significant_drop]
+#[cfg_attr(not(test), rustc_diagnostic_item = "MutexGuard")]
pub struct MutexGuard<'a, T: ?Sized + 'a> {
lock: &'a Mutex<T>,
poison: poison::Guard,
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 813516040..37413ec62 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -3,7 +3,6 @@ use crate::fmt;
use crate::marker::PhantomData;
use crate::mem::MaybeUninit;
use crate::panic::{RefUnwindSafe, UnwindSafe};
-use crate::pin::Pin;
use crate::sync::Once;
/// A synchronization primitive which can be written to only once.
@@ -223,60 +222,6 @@ impl<T> OnceLock<T> {
Ok(unsafe { self.get_unchecked() })
}
- /// Internal-only API that gets the contents of the cell, initializing it
- /// in two steps with `f` and `g` if the cell was empty.
- ///
- /// `f` is called to construct the value, which is then moved into the cell
- /// and given as a (pinned) mutable reference to `g` to finish
- /// initialization.
- ///
- /// This allows `g` to inspect an manipulate the value after it has been
- /// moved into its final place in the cell, but before the cell is
- /// considered initialized.
- ///
- /// # Panics
- ///
- /// If `f` or `g` panics, the panic is propagated to the caller, and the
- /// cell remains uninitialized.
- ///
- /// With the current implementation, if `g` panics, the value from `f` will
- /// not be dropped. This should probably be fixed if this is ever used for
- /// a type where this matters.
- ///
- /// It is an error to reentrantly initialize the cell from `f`. The exact
- /// outcome is unspecified. Current implementation deadlocks, but this may
- /// be changed to a panic in the future.
- pub(crate) fn get_or_init_pin<F, G>(self: Pin<&Self>, f: F, g: G) -> Pin<&T>
- where
- F: FnOnce() -> T,
- G: FnOnce(Pin<&mut T>),
- {
- if let Some(value) = self.get_ref().get() {
- // SAFETY: The inner value was already initialized, and will not be
- // moved anymore.
- return unsafe { Pin::new_unchecked(value) };
- }
-
- let slot = &self.value;
-
- // Ignore poisoning from other threads
- // If another thread panics, then we'll be able to run our closure
- self.once.call_once_force(|_| {
- let value = f();
- // SAFETY: We use the Once (self.once) to guarantee unique access
- // to the UnsafeCell (slot).
- let value: &mut T = unsafe { (&mut *slot.get()).write(value) };
- // SAFETY: The value has been written to its final place in
- // self.value. We do not to move it anymore, which we promise here
- // with a Pin<&mut T>.
- g(unsafe { Pin::new_unchecked(value) });
- });
-
- // SAFETY: The inner value has been initialized, and will not be moved
- // anymore.
- unsafe { Pin::new_unchecked(self.get_ref().get_unchecked()) }
- }
-
/// Consumes the `OnceLock`, returning the wrapped value. Returns
/// `None` if the cell was empty.
///
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 6e4a2cfc8..9ab781561 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -101,6 +101,7 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
and cause Futures to not implement `Send`"]
#[stable(feature = "rust1", since = "1.0.0")]
#[clippy::has_significant_drop]
+#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockReadGuard")]
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
// NB: we use a pointer instead of `&'a T` to avoid `noalias` violations, because a
// `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
@@ -130,6 +131,7 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
and cause Future's to not implement `Send`"]
#[stable(feature = "rust1", since = "1.0.0")]
#[clippy::has_significant_drop]
+#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockWriteGuard")]
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
lock: &'a RwLock<T>,
poison: poison::Guard,
diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs
index 08255c985..b5b3ad989 100644
--- a/library/std/src/sync/rwlock/tests.rs
+++ b/library/std/src/sync/rwlock/tests.rs
@@ -19,7 +19,7 @@ fn smoke() {
#[test]
fn frob() {
const N: u32 = 10;
- const M: usize = 1000;
+ const M: usize = if cfg!(miri) { 100 } else { 1000 };
let r = Arc::new(RwLock::new(()));
diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs
deleted file mode 100644
index 22059ca0d..000000000
--- a/library/std/src/sys/hermit/condvar.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-use crate::ffi::c_void;
-use crate::ptr;
-use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
-use crate::sys::hermit::abi;
-use crate::sys::locks::Mutex;
-use crate::sys_common::lazy_box::{LazyBox, LazyInit};
-use crate::time::Duration;
-
-// The implementation is inspired by Andrew D. Birrell's paper
-// "Implementing Condition Variables with Semaphores"
-
-pub struct Condvar {
- counter: AtomicUsize,
- sem1: *const c_void,
- sem2: *const c_void,
-}
-
-pub(crate) type MovableCondvar = LazyBox<Condvar>;
-
-impl LazyInit for Condvar {
- fn init() -> Box<Self> {
- Box::new(Self::new())
- }
-}
-
-unsafe impl Send for Condvar {}
-unsafe impl Sync for Condvar {}
-
-impl Condvar {
- pub fn new() -> Self {
- let mut condvar =
- Self { counter: AtomicUsize::new(0), sem1: ptr::null(), sem2: ptr::null() };
- unsafe {
- let _ = abi::sem_init(&mut condvar.sem1, 0);
- let _ = abi::sem_init(&mut condvar.sem2, 0);
- }
- condvar
- }
-
- pub unsafe fn notify_one(&self) {
- if self.counter.load(SeqCst) > 0 {
- self.counter.fetch_sub(1, SeqCst);
- abi::sem_post(self.sem1);
- abi::sem_timedwait(self.sem2, 0);
- }
- }
-
- pub unsafe fn notify_all(&self) {
- let counter = self.counter.swap(0, SeqCst);
- for _ in 0..counter {
- abi::sem_post(self.sem1);
- }
- for _ in 0..counter {
- abi::sem_timedwait(self.sem2, 0);
- }
- }
-
- pub unsafe fn wait(&self, mutex: &Mutex) {
- self.counter.fetch_add(1, SeqCst);
- mutex.unlock();
- abi::sem_timedwait(self.sem1, 0);
- abi::sem_post(self.sem2);
- mutex.lock();
- }
-
- pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
- self.counter.fetch_add(1, SeqCst);
- mutex.unlock();
- let millis = dur.as_millis().min(u32::MAX as u128) as u32;
-
- let res = if millis > 0 {
- abi::sem_timedwait(self.sem1, millis)
- } else {
- abi::sem_trywait(self.sem1)
- };
-
- abi::sem_post(self.sem2);
- mutex.lock();
- res == 0
- }
-}
-
-impl Drop for Condvar {
- fn drop(&mut self) {
- unsafe {
- let _ = abi::sem_destroy(self.sem1);
- let _ = abi::sem_destroy(self.sem2);
- }
- }
-}
diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index fa9a7fb19..f921839cf 100644
--- a/library/std/src/sys/hermit/fs.rs
+++ b/library/std/src/sys/hermit/fs.rs
@@ -2,7 +2,7 @@ use crate::ffi::{CStr, CString, OsString};
use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::io::{self, Error, ErrorKind};
-use crate::io::{IoSlice, IoSliceMut, ReadBuf, SeekFrom};
+use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
use crate::os::unix::ffi::OsStrExt;
use crate::path::{Path, PathBuf};
use crate::sys::cvt;
@@ -41,6 +41,9 @@ pub struct OpenOptions {
mode: i32,
}
+#[derive(Copy, Clone, Debug, Default)]
+pub struct FileTimes {}
+
pub struct FilePermissions(!);
pub struct FileType(!);
@@ -110,6 +113,11 @@ impl fmt::Debug for FilePermissions {
}
}
+impl FileTimes {
+ pub fn set_accessed(&mut self, _t: SystemTime) {}
+ pub fn set_modified(&mut self, _t: SystemTime) {}
+}
+
impl FileType {
pub fn is_dir(&self) -> bool {
self.0
@@ -312,8 +320,8 @@ impl File {
false
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- crate::io::default_read_buf(|buf| self.read(buf), buf)
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ crate::io::default_read_buf(|buf| self.read(buf), cursor)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
@@ -344,6 +352,10 @@ impl File {
pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
Err(Error::from_raw_os_error(22))
}
+
+ pub fn set_times(&self, _times: FileTimes) -> io::Result<()> {
+ Err(Error::from_raw_os_error(22))
+ }
}
impl DirBuilder {
diff --git a/library/std/src/sys/hermit/futex.rs b/library/std/src/sys/hermit/futex.rs
new file mode 100644
index 000000000..b64c174b0
--- /dev/null
+++ b/library/std/src/sys/hermit/futex.rs
@@ -0,0 +1,39 @@
+use super::abi;
+use crate::ptr::null;
+use crate::sync::atomic::AtomicU32;
+use crate::time::Duration;
+
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
+ // Calculate the timeout as a relative timespec.
+ //
+ // Overflows are rounded up to an infinite timeout (None).
+ let timespec = timeout.and_then(|dur| {
+ Some(abi::timespec {
+ tv_sec: dur.as_secs().try_into().ok()?,
+ tv_nsec: dur.subsec_nanos().into(),
+ })
+ });
+
+ let r = unsafe {
+ abi::futex_wait(
+ futex.as_mut_ptr(),
+ expected,
+ timespec.as_ref().map_or(null(), |t| t as *const abi::timespec),
+ abi::FUTEX_RELATIVE_TIMEOUT,
+ )
+ };
+
+ r != -abi::errno::ETIMEDOUT
+}
+
+#[inline]
+pub fn futex_wake(futex: &AtomicU32) -> bool {
+ unsafe { abi::futex_wake(futex.as_mut_ptr(), 1) > 0 }
+}
+
+#[inline]
+pub fn futex_wake_all(futex: &AtomicU32) {
+ unsafe {
+ abi::futex_wake(futex.as_mut_ptr(), i32::MAX);
+ }
+}
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 60b7a973c..827d82900 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -25,6 +25,7 @@ pub mod cmath;
pub mod env;
pub mod fd;
pub mod fs;
+pub mod futex;
#[path = "../unsupported/io.rs"]
pub mod io;
pub mod memchr;
@@ -45,14 +46,14 @@ pub mod thread_local_dtor;
pub mod thread_local_key;
pub mod time;
-mod condvar;
-mod mutex;
-mod rwlock;
-
+#[path = "../unix/locks"]
pub mod locks {
- pub use super::condvar::*;
- pub use super::mutex::*;
- pub use super::rwlock::*;
+ mod futex_condvar;
+ mod futex_mutex;
+ mod futex_rwlock;
+ pub(crate) use futex_condvar::MovableCondvar;
+ pub(crate) use futex_mutex::{MovableMutex, Mutex};
+ pub(crate) use futex_rwlock::{MovableRwLock, RwLock};
}
use crate::io::ErrorKind;
@@ -98,7 +99,7 @@ pub extern "C" fn __rust_abort() {
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
-pub unsafe fn init(argc: isize, argv: *const *const u8) {
+pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
let _ = net::init();
args::init(argc, argv);
}
diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
deleted file mode 100644
index eb15a04ff..000000000
--- a/library/std/src/sys/hermit/mutex.rs
+++ /dev/null
@@ -1,216 +0,0 @@
-use crate::cell::UnsafeCell;
-use crate::collections::VecDeque;
-use crate::hint;
-use crate::ops::{Deref, DerefMut, Drop};
-use crate::ptr;
-use crate::sync::atomic::{AtomicUsize, Ordering};
-use crate::sys::hermit::abi;
-
-/// This type provides a lock based on busy waiting to realize mutual exclusion
-///
-/// # Description
-///
-/// This structure behaves a lot like a common mutex. There are some differences:
-///
-/// - By using busy waiting, it can be used outside the runtime.
-/// - It is a so called ticket lock and is completely fair.
-#[cfg_attr(target_arch = "x86_64", repr(align(128)))]
-#[cfg_attr(not(target_arch = "x86_64"), repr(align(64)))]
-struct Spinlock<T: ?Sized> {
- queue: AtomicUsize,
- dequeue: AtomicUsize,
- data: UnsafeCell<T>,
-}
-
-unsafe impl<T: ?Sized + Send> Sync for Spinlock<T> {}
-unsafe impl<T: ?Sized + Send> Send for Spinlock<T> {}
-
-/// A guard to which the protected data can be accessed
-///
-/// When the guard falls out of scope it will release the lock.
-struct SpinlockGuard<'a, T: ?Sized + 'a> {
- dequeue: &'a AtomicUsize,
- data: &'a mut T,
-}
-
-impl<T> Spinlock<T> {
- pub const fn new(user_data: T) -> Spinlock<T> {
- Spinlock {
- queue: AtomicUsize::new(0),
- dequeue: AtomicUsize::new(1),
- data: UnsafeCell::new(user_data),
- }
- }
-
- #[inline]
- fn obtain_lock(&self) {
- let ticket = self.queue.fetch_add(1, Ordering::SeqCst) + 1;
- let mut counter: u16 = 0;
- while self.dequeue.load(Ordering::SeqCst) != ticket {
- counter += 1;
- if counter < 100 {
- hint::spin_loop();
- } else {
- counter = 0;
- unsafe {
- abi::yield_now();
- }
- }
- }
- }
-
- #[inline]
- pub unsafe fn lock(&self) -> SpinlockGuard<'_, T> {
- self.obtain_lock();
- SpinlockGuard { dequeue: &self.dequeue, data: &mut *self.data.get() }
- }
-}
-
-impl<T: ?Sized + Default> Default for Spinlock<T> {
- fn default() -> Spinlock<T> {
- Spinlock::new(Default::default())
- }
-}
-
-impl<'a, T: ?Sized> Deref for SpinlockGuard<'a, T> {
- type Target = T;
- fn deref(&self) -> &T {
- &*self.data
- }
-}
-
-impl<'a, T: ?Sized> DerefMut for SpinlockGuard<'a, T> {
- fn deref_mut(&mut self) -> &mut T {
- &mut *self.data
- }
-}
-
-impl<'a, T: ?Sized> Drop for SpinlockGuard<'a, T> {
- /// The dropping of the SpinlockGuard will release the lock it was created from.
- fn drop(&mut self) {
- self.dequeue.fetch_add(1, Ordering::SeqCst);
- }
-}
-
-/// Realize a priority queue for tasks
-struct PriorityQueue {
- queues: [Option<VecDeque<abi::Tid>>; abi::NO_PRIORITIES],
- prio_bitmap: u64,
-}
-
-impl PriorityQueue {
- pub const fn new() -> PriorityQueue {
- PriorityQueue {
- queues: [
- None, None, None, None, None, None, None, None, None, None, None, None, None, None,
- None, None, None, None, None, None, None, None, None, None, None, None, None, None,
- None, None, None,
- ],
- prio_bitmap: 0,
- }
- }
-
- /// Add a task id by its priority to the queue
- pub fn push(&mut self, prio: abi::Priority, id: abi::Tid) {
- let i: usize = prio.into().into();
- self.prio_bitmap |= (1 << i) as u64;
- if let Some(queue) = &mut self.queues[i] {
- queue.push_back(id);
- } else {
- let mut queue = VecDeque::new();
- queue.push_back(id);
- self.queues[i] = Some(queue);
- }
- }
-
- fn pop_from_queue(&mut self, queue_index: usize) -> Option<abi::Tid> {
- if let Some(queue) = &mut self.queues[queue_index] {
- let id = queue.pop_front();
-
- if queue.is_empty() {
- self.prio_bitmap &= !(1 << queue_index as u64);
- }
-
- id
- } else {
- None
- }
- }
-
- /// Pop the task handle with the highest priority from the queue
- pub fn pop(&mut self) -> Option<abi::Tid> {
- for i in 0..abi::NO_PRIORITIES {
- if self.prio_bitmap & (1 << i) != 0 {
- return self.pop_from_queue(i);
- }
- }
-
- None
- }
-}
-
-struct MutexInner {
- locked: bool,
- blocked_task: PriorityQueue,
-}
-
-impl MutexInner {
- pub const fn new() -> MutexInner {
- MutexInner { locked: false, blocked_task: PriorityQueue::new() }
- }
-}
-
-pub struct Mutex {
- inner: Spinlock<MutexInner>,
-}
-
-pub type MovableMutex = Mutex;
-
-unsafe impl Send for Mutex {}
-unsafe impl Sync for Mutex {}
-
-impl Mutex {
- pub const fn new() -> Mutex {
- Mutex { inner: Spinlock::new(MutexInner::new()) }
- }
-
- #[inline]
- pub unsafe fn init(&mut self) {}
-
- #[inline]
- pub unsafe fn lock(&self) {
- loop {
- let mut guard = self.inner.lock();
- if guard.locked == false {
- guard.locked = true;
- return;
- } else {
- let prio = abi::get_priority();
- let id = abi::getpid();
-
- guard.blocked_task.push(prio, id);
- abi::block_current_task();
- drop(guard);
- abi::yield_now();
- }
- }
- }
-
- #[inline]
- pub unsafe fn unlock(&self) {
- let mut guard = self.inner.lock();
- guard.locked = false;
- if let Some(tid) = guard.blocked_task.pop() {
- abi::wakeup_task(tid);
- }
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- let mut guard = self.inner.lock();
- if guard.locked == false {
- guard.locked = true;
- }
- guard.locked
- }
-}
diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs
index 745476171..8a13879d8 100644
--- a/library/std/src/sys/hermit/net.rs
+++ b/library/std/src/sys/hermit/net.rs
@@ -487,6 +487,4 @@ pub mod netc {
#[derive(Copy, Clone)]
pub struct sockaddr {}
-
- pub type socklen_t = usize;
}
diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs
deleted file mode 100644
index 9701bab1f..000000000
--- a/library/std/src/sys/hermit/rwlock.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-use crate::cell::UnsafeCell;
-use crate::sys::locks::{MovableCondvar, Mutex};
-use crate::sys_common::lazy_box::{LazyBox, LazyInit};
-
-pub struct RwLock {
- lock: Mutex,
- cond: MovableCondvar,
- state: UnsafeCell<State>,
-}
-
-pub type MovableRwLock = RwLock;
-
-enum State {
- Unlocked,
- Reading(usize),
- Writing,
-}
-
-unsafe impl Send for RwLock {}
-unsafe impl Sync for RwLock {}
-
-// This rwlock implementation is a relatively simple implementation which has a
-// condition variable for readers/writers as well as a mutex protecting the
-// internal state of the lock. A current downside of the implementation is that
-// unlocking the lock will notify *all* waiters rather than just readers or just
-// writers. This can cause lots of "thundering stampede" problems. While
-// hopefully correct this implementation is very likely to want to be changed in
-// the future.
-
-impl RwLock {
- pub const fn new() -> RwLock {
- RwLock {
- lock: Mutex::new(),
- cond: MovableCondvar::new(),
- state: UnsafeCell::new(State::Unlocked),
- }
- }
-
- #[inline]
- pub unsafe fn read(&self) {
- self.lock.lock();
- while !(*self.state.get()).inc_readers() {
- self.cond.wait(&self.lock);
- }
- self.lock.unlock();
- }
-
- #[inline]
- pub unsafe fn try_read(&self) -> bool {
- self.lock.lock();
- let ok = (*self.state.get()).inc_readers();
- self.lock.unlock();
- return ok;
- }
-
- #[inline]
- pub unsafe fn write(&self) {
- self.lock.lock();
- while !(*self.state.get()).inc_writers() {
- self.cond.wait(&self.lock);
- }
- self.lock.unlock();
- }
-
- #[inline]
- pub unsafe fn try_write(&self) -> bool {
- self.lock.lock();
- let ok = (*self.state.get()).inc_writers();
- self.lock.unlock();
- return ok;
- }
-
- #[inline]
- pub unsafe fn read_unlock(&self) {
- self.lock.lock();
- let notify = (*self.state.get()).dec_readers();
- self.lock.unlock();
- if notify {
- // FIXME: should only wake up one of these some of the time
- self.cond.notify_all();
- }
- }
-
- #[inline]
- pub unsafe fn write_unlock(&self) {
- self.lock.lock();
- (*self.state.get()).dec_writers();
- self.lock.unlock();
- // FIXME: should only wake up one of these some of the time
- self.cond.notify_all();
- }
-}
-
-impl State {
- fn inc_readers(&mut self) -> bool {
- match *self {
- State::Unlocked => {
- *self = State::Reading(1);
- true
- }
- State::Reading(ref mut cnt) => {
- *cnt += 1;
- true
- }
- State::Writing => false,
- }
- }
-
- fn inc_writers(&mut self) -> bool {
- match *self {
- State::Unlocked => {
- *self = State::Writing;
- true
- }
- State::Reading(_) | State::Writing => false,
- }
- }
-
- fn dec_readers(&mut self) -> bool {
- let zero = match *self {
- State::Reading(ref mut cnt) => {
- *cnt -= 1;
- *cnt == 0
- }
- State::Unlocked | State::Writing => invalid(),
- };
- if zero {
- *self = State::Unlocked;
- }
- zero
- }
-
- fn dec_writers(&mut self) {
- match *self {
- State::Writing => {}
- State::Unlocked | State::Reading(_) => invalid(),
- }
- *self = State::Unlocked;
- }
-}
-
-fn invalid() -> ! {
- panic!("inconsistent rwlock");
-}
diff --git a/library/std/src/sys/itron/mutex.rs b/library/std/src/sys/itron/mutex.rs
index 715e94c3b..085662e6d 100644
--- a/library/std/src/sys/itron/mutex.rs
+++ b/library/std/src/sys/itron/mutex.rs
@@ -31,12 +31,6 @@ impl Mutex {
Mutex { mtx: SpinIdOnceCell::new() }
}
- pub unsafe fn init(&mut self) {
- // Initialize `self.mtx` eagerly
- let id = new_mtx().unwrap_or_else(|e| fail(e, &"acre_mtx"));
- unsafe { self.mtx.set_unchecked((id, ())) };
- }
-
/// Get the inner mutex's ID, which is lazily created.
fn raw(&self) -> abi::ID {
match self.mtx.get_or_try_init(|| new_mtx().map(|id| (id, ()))) {
diff --git a/library/std/src/sys/sgx/abi/thread.rs b/library/std/src/sys/sgx/abi/thread.rs
index ef55b821a..2b23e368c 100644
--- a/library/std/src/sys/sgx/abi/thread.rs
+++ b/library/std/src/sys/sgx/abi/thread.rs
@@ -7,7 +7,11 @@ use fortanix_sgx_abi::Tcs;
#[unstable(feature = "sgx_platform", issue = "56975")]
pub fn current() -> Tcs {
extern "C" {
- fn get_tcs_addr() -> Tcs;
+ fn get_tcs_addr() -> *mut u8;
+ }
+ let addr = unsafe { get_tcs_addr() };
+ match Tcs::new(addr) {
+ Some(tcs) => tcs,
+ None => rtabort!("TCS must not be placed at address zero (this is a linker error)"),
}
- unsafe { get_tcs_addr() }
}
diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
index ea24fedd0..5409bd177 100644
--- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
@@ -56,6 +56,8 @@ unsafe impl UserSafeSized for Usercall {}
#[unstable(feature = "sgx_platform", issue = "56975")]
unsafe impl UserSafeSized for Return {}
#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl UserSafeSized for Cancel {}
+#[unstable(feature = "sgx_platform", issue = "56975")]
unsafe impl<T: UserSafeSized> UserSafeSized for [T; 2] {}
/// A type that can be represented in memory as one or more `UserSafeSized`s.
@@ -115,7 +117,7 @@ pub unsafe trait UserSafe {
/// * the pointer is null.
/// * the pointed-to range is not in user memory.
unsafe fn check_ptr(ptr: *const Self) {
- let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
+ let is_aligned = |p: *const u8| -> bool { p.is_aligned_to(Self::align_of()) };
assert!(is_aligned(ptr as *const u8));
assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr })));
@@ -305,6 +307,34 @@ where
}
}
+// Split a memory region ptr..ptr + len into three parts:
+// +--------+
+// | small0 | Chunk smaller than 8 bytes
+// +--------+
+// | big | Chunk 8-byte aligned, and size a multiple of 8 bytes
+// +--------+
+// | small1 | Chunk smaller than 8 bytes
+// +--------+
+fn region_as_aligned_chunks(ptr: *const u8, len: usize) -> (usize, usize, usize) {
+ let small0_size = if ptr as usize % 8 == 0 { 0 } else { 8 - ptr as usize % 8 };
+ let small1_size = (len - small0_size as usize) % 8;
+ let big_size = len - small0_size as usize - small1_size as usize;
+
+ (small0_size, big_size, small1_size)
+}
+
+unsafe fn copy_quadwords(src: *const u8, dst: *mut u8, len: usize) {
+ unsafe {
+ asm!(
+ "rep movsq (%rsi), (%rdi)",
+ inout("rcx") len / 8 => _,
+ inout("rdi") dst => _,
+ inout("rsi") src => _,
+ options(att_syntax, nostack, preserves_flags)
+ );
+ }
+}
+
/// Copies `len` bytes of data from enclave pointer `src` to userspace `dst`
///
/// This function mitigates stale data vulnerabilities by ensuring all writes to untrusted memory are either:
@@ -343,17 +373,6 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
}
}
- unsafe fn copy_aligned_quadwords_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
- unsafe {
- asm!(
- "rep movsq (%rsi), (%rdi)",
- inout("rcx") len / 8 => _,
- inout("rdi") dst => _,
- inout("rsi") src => _,
- options(att_syntax, nostack, preserves_flags)
- );
- }
- }
assert!(!src.is_null());
assert!(!dst.is_null());
assert!(is_enclave_range(src, len));
@@ -367,10 +386,10 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
unsafe {
copy_bytewise_to_userspace(src, dst, len);
}
- } else if len % 8 == 0 && dst as usize % 8 == 0 {
+ } else if len % 8 == 0 && dst.is_aligned_to(8) {
// Copying 8-byte aligned quadwords: copy quad word per quad word
unsafe {
- copy_aligned_quadwords_to_userspace(src, dst, len);
+ copy_quadwords(src, dst, len);
}
} else {
// Split copies into three parts:
@@ -381,20 +400,16 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
// +--------+
// | small1 | Chunk smaller than 8 bytes
// +--------+
+ let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len);
unsafe {
// Copy small0
- let small0_size = (8 - dst as usize % 8) as u8;
- let small0_src = src;
- let small0_dst = dst;
- copy_bytewise_to_userspace(small0_src as _, small0_dst, small0_size as _);
+ copy_bytewise_to_userspace(src, dst, small0_size as _);
// Copy big
- let small1_size = ((len - small0_size as usize) % 8) as u8;
- let big_size = len - small0_size as usize - small1_size as usize;
let big_src = src.offset(small0_size as _);
let big_dst = dst.offset(small0_size as _);
- copy_aligned_quadwords_to_userspace(big_src as _, big_dst, big_size);
+ copy_quadwords(big_src as _, big_dst, big_size);
// Copy small1
let small1_src = src.offset(big_size as isize + small0_size as isize);
@@ -404,6 +419,106 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
}
}
+/// Copies `len` bytes of data from userspace pointer `src` to enclave pointer `dst`
+///
+/// This function mitigates AEPIC leak vulnerabilities by ensuring all reads from untrusted memory are 8-byte aligned
+///
+/// # Panics
+/// This function panics if:
+///
+/// * The `src` pointer is null
+/// * The `dst` pointer is null
+/// * The `src` memory range is not in user memory
+/// * The `dst` memory range is not in enclave memory
+///
+/// # References
+/// - https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00657.html
+/// - https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/stale-data-read-from-xapic.html
+pub(crate) unsafe fn copy_from_userspace(src: *const u8, dst: *mut u8, len: usize) {
+ // Copies memory region `src..src + len` to the enclave at `dst`. The source memory region
+ // is:
+ // - strictly less than 8 bytes in size and may be
+ // - located at a misaligned memory location
+ fn copy_misaligned_chunk_to_enclave(src: *const u8, dst: *mut u8, len: usize) {
+ let mut tmp_buff = [0u8; 16];
+
+ unsafe {
+ // Compute an aligned memory region to read from
+ // +--------+ <-- aligned_src + aligned_len (8B-aligned)
+ // | pad1 |
+ // +--------+ <-- src + len (misaligned)
+ // | |
+ // | |
+ // | |
+ // +--------+ <-- src (misaligned)
+ // | pad0 |
+ // +--------+ <-- aligned_src (8B-aligned)
+ let pad0_size = src as usize % 8;
+ let aligned_src = src.sub(pad0_size);
+
+ let pad1_size = 8 - (src.add(len) as usize % 8);
+ let aligned_len = pad0_size + len + pad1_size;
+
+ debug_assert!(len < 8);
+ debug_assert_eq!(aligned_src as usize % 8, 0);
+ debug_assert_eq!(aligned_len % 8, 0);
+ debug_assert!(aligned_len <= 16);
+
+ // Copy the aligned buffer to a temporary buffer
+ // Note: copying from a slightly different memory location is a bit odd. In this case it
+ // can't lead to page faults or inadvertent copying from the enclave as we only ensured
+ // that the `src` pointer is aligned at an 8 byte boundary. As pages are 4096 bytes
+ // aligned, `aligned_src` must be on the same page as `src`. A similar argument can be made
+ // for `src + len`
+ copy_quadwords(aligned_src as _, tmp_buff.as_mut_ptr(), aligned_len);
+
+ // Copy the correct parts of the temporary buffer to the destination
+ ptr::copy(tmp_buff.as_ptr().add(pad0_size), dst, len);
+ }
+ }
+
+ assert!(!src.is_null());
+ assert!(!dst.is_null());
+ assert!(is_user_range(src, len));
+ assert!(is_enclave_range(dst, len));
+ assert!(!(src as usize).overflowing_add(len + 8).1);
+ assert!(!(dst as usize).overflowing_add(len + 8).1);
+
+ if len < 8 {
+ copy_misaligned_chunk_to_enclave(src, dst, len);
+ } else if len % 8 == 0 && src as usize % 8 == 0 {
+ // Copying 8-byte aligned quadwords: copy quad word per quad word
+ unsafe {
+ copy_quadwords(src, dst, len);
+ }
+ } else {
+ // Split copies into three parts:
+ // +--------+
+ // | small0 | Chunk smaller than 8 bytes
+ // +--------+
+ // | big | Chunk 8-byte aligned, and size a multiple of 8 bytes
+ // +--------+
+ // | small1 | Chunk smaller than 8 bytes
+ // +--------+
+ let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len);
+
+ unsafe {
+ // Copy small0
+ copy_misaligned_chunk_to_enclave(src, dst, small0_size);
+
+ // Copy big
+ let big_src = src.add(small0_size);
+ let big_dst = dst.add(small0_size);
+ copy_quadwords(big_src, big_dst, big_size);
+
+ // Copy small1
+ let small1_src = src.add(big_size + small0_size);
+ let small1_dst = dst.add(big_size + small0_size);
+ copy_misaligned_chunk_to_enclave(small1_src, small1_dst, small1_size);
+ }
+ }
+}
+
#[unstable(feature = "sgx_platform", issue = "56975")]
impl<T: ?Sized> UserRef<T>
where
@@ -468,7 +583,7 @@ where
pub fn copy_to_enclave(&self, dest: &mut T) {
unsafe {
assert_eq!(mem::size_of_val(dest), mem::size_of_val(&*self.0.get()));
- ptr::copy(
+ copy_from_userspace(
self.0.get() as *const T as *const u8,
dest as *mut T as *mut u8,
mem::size_of_val(dest),
@@ -494,7 +609,11 @@ where
{
/// Copies the value from user memory into enclave memory.
pub fn to_enclave(&self) -> T {
- unsafe { ptr::read(self.0.get()) }
+ unsafe {
+ let mut data: T = mem::MaybeUninit::uninit().assume_init();
+ copy_from_userspace(self.0.get() as _, &mut data as *mut T as _, mem::size_of::<T>());
+ data
+ }
}
}
diff --git a/library/std/src/sys/sgx/abi/usercalls/mod.rs b/library/std/src/sys/sgx/abi/usercalls/mod.rs
index 79d1db5e1..e19e84326 100644
--- a/library/std/src/sys/sgx/abi/usercalls/mod.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/mod.rs
@@ -292,12 +292,17 @@ fn check_os_error(err: Result) -> i32 {
}
}
-trait FromSgxResult {
+/// Translate the raw result of an SGX usercall.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait FromSgxResult {
+ /// Return type
type Return;
+ /// Translate the raw result of an SGX usercall.
fn from_sgx_result(self) -> IoResult<Self::Return>;
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl<T> FromSgxResult for (Result, T) {
type Return = T;
@@ -310,6 +315,7 @@ impl<T> FromSgxResult for (Result, T) {
}
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl FromSgxResult for Result {
type Return = ();
diff --git a/library/std/src/sys/sgx/abi/usercalls/raw.rs b/library/std/src/sys/sgx/abi/usercalls/raw.rs
index 4267b96cc..10c1456d4 100644
--- a/library/std/src/sys/sgx/abi/usercalls/raw.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/raw.rs
@@ -37,14 +37,23 @@ pub unsafe fn do_usercall(
(a, b)
}
-type Register = u64;
+/// A value passed or returned in a CPU register.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub type Register = u64;
-trait RegisterArgument {
+/// Translate a type from/to Register to be used as an argument.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait RegisterArgument {
+ /// Translate a Register to Self.
fn from_register(_: Register) -> Self;
+ /// Translate self to a Register.
fn into_register(self) -> Register;
}
-trait ReturnValue {
+/// Translate a pair of Registers to the raw usercall return value.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait ReturnValue {
+ /// Translate a pair of Registers to the raw usercall return value.
fn from_registers(call: &'static str, regs: (Register, Register)) -> Self;
}
@@ -68,6 +77,7 @@ macro_rules! define_usercalls {
macro_rules! define_ra {
(< $i:ident > $t:ty) => {
+ #[unstable(feature = "sgx_platform", issue = "56975")]
impl<$i> RegisterArgument for $t {
fn from_register(a: Register) -> Self {
a as _
@@ -78,6 +88,7 @@ macro_rules! define_ra {
}
};
($i:ty as $t:ty) => {
+ #[unstable(feature = "sgx_platform", issue = "56975")]
impl RegisterArgument for $t {
fn from_register(a: Register) -> Self {
a as $i as _
@@ -88,6 +99,7 @@ macro_rules! define_ra {
}
};
($t:ty) => {
+ #[unstable(feature = "sgx_platform", issue = "56975")]
impl RegisterArgument for $t {
fn from_register(a: Register) -> Self {
a as _
@@ -112,6 +124,7 @@ define_ra!(usize as isize);
define_ra!(<T> *const T);
define_ra!(<T> *mut T);
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl RegisterArgument for bool {
fn from_register(a: Register) -> bool {
if a != 0 { true } else { false }
@@ -121,6 +134,7 @@ impl RegisterArgument for bool {
}
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl<T: RegisterArgument> RegisterArgument for Option<NonNull<T>> {
fn from_register(a: Register) -> Option<NonNull<T>> {
NonNull::new(a as _)
@@ -130,12 +144,14 @@ impl<T: RegisterArgument> RegisterArgument for Option<NonNull<T>> {
}
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl ReturnValue for ! {
fn from_registers(call: &'static str, _regs: (Register, Register)) -> Self {
rtabort!("Usercall {call}: did not expect to be re-entered");
}
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl ReturnValue for () {
fn from_registers(call: &'static str, usercall_retval: (Register, Register)) -> Self {
rtassert!(usercall_retval.0 == 0);
@@ -144,6 +160,7 @@ impl ReturnValue for () {
}
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl<T: RegisterArgument> ReturnValue for T {
fn from_registers(call: &'static str, usercall_retval: (Register, Register)) -> Self {
rtassert!(usercall_retval.1 == 0);
@@ -151,6 +168,7 @@ impl<T: RegisterArgument> ReturnValue for T {
}
}
+#[unstable(feature = "sgx_platform", issue = "56975")]
impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self {
(T::from_register(regs.0), U::from_register(regs.1))
diff --git a/library/std/src/sys/sgx/abi/usercalls/tests.rs b/library/std/src/sys/sgx/abi/usercalls/tests.rs
index cbf7d7d54..58b8eb215 100644
--- a/library/std/src/sys/sgx/abi/usercalls/tests.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/tests.rs
@@ -1,8 +1,8 @@
-use super::alloc::copy_to_userspace;
use super::alloc::User;
+use super::alloc::{copy_from_userspace, copy_to_userspace};
#[test]
-fn test_copy_function() {
+fn test_copy_to_userspace_function() {
let mut src = [0u8; 100];
let mut dst = User::<[u8]>::uninitialized(100);
@@ -17,12 +17,38 @@ fn test_copy_function() {
dst.copy_from_enclave(&[0u8; 100]);
// Copy src[0..size] to dst + offset
- unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().offset(offset), size) };
+ unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().add(offset), size) };
// Verify copy
for byte in 0..size {
unsafe {
- assert_eq!(*dst.as_ptr().offset(offset + byte as isize), src[byte as usize]);
+ assert_eq!(*dst.as_ptr().add(offset + byte), src[byte as usize]);
+ }
+ }
+ }
+ }
+}
+
+#[test]
+fn test_copy_from_userspace_function() {
+ let mut dst = [0u8; 100];
+ let mut src = User::<[u8]>::uninitialized(100);
+
+ src.copy_from_enclave(&[0u8; 100]);
+
+ for size in 0..48 {
+ // For all possible alignment
+ for offset in 0..8 {
+ // overwrite complete dst
+ dst = [0u8; 100];
+
+ // Copy src[0..size] to dst + offset
+ unsafe { copy_from_userspace(src.as_ptr().offset(offset), dst.as_mut_ptr(), size) };
+
+ // Verify copy
+ for byte in 0..size {
+ unsafe {
+ assert_eq!(dst[byte as usize], *src.as_ptr().offset(offset + byte as isize));
}
}
}
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index 696400670..b1d32929e 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -47,7 +47,7 @@ pub mod locks {
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
-pub unsafe fn init(argc: isize, argv: *const *const u8) {
+pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
unsafe {
args::init(argc, argv);
}
diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs
index 513cd77fd..aa747d56b 100644
--- a/library/std/src/sys/sgx/mutex.rs
+++ b/library/std/src/sys/sgx/mutex.rs
@@ -21,9 +21,6 @@ impl Mutex {
}
#[inline]
- pub unsafe fn init(&mut self) {}
-
- #[inline]
pub unsafe fn lock(&self) {
let mut guard = self.inner.lock();
if *guard.lock_var() {
diff --git a/library/std/src/sys/solid/fs.rs b/library/std/src/sys/solid/fs.rs
index a2cbee4dc..969222253 100644
--- a/library/std/src/sys/solid/fs.rs
+++ b/library/std/src/sys/solid/fs.rs
@@ -2,7 +2,7 @@ use super::{abi, error};
use crate::{
ffi::{CStr, CString, OsStr, OsString},
fmt,
- io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom},
+ io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom},
mem::MaybeUninit,
os::raw::{c_int, c_short},
os::solid::ffi::OsStrExt,
@@ -77,6 +77,9 @@ pub struct OpenOptions {
custom_flags: i32,
}
+#[derive(Copy, Clone, Debug, Default)]
+pub struct FileTimes {}
+
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FilePermissions(c_short);
@@ -126,6 +129,11 @@ impl FilePermissions {
}
}
+impl FileTimes {
+ pub fn set_accessed(&mut self, _t: SystemTime) {}
+ pub fn set_modified(&mut self, _t: SystemTime) {}
+}
+
impl FileType {
pub fn is_dir(&self) -> bool {
self.is(abi::S_IFDIR)
@@ -358,13 +366,13 @@ impl File {
}
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
unsafe {
- let len = buf.remaining();
+ let len = cursor.capacity();
let mut out_num_bytes = MaybeUninit::uninit();
error::SolidError::err_if_negative(abi::SOLID_FS_Read(
self.fd.raw(),
- buf.unfilled_mut().as_mut_ptr() as *mut u8,
+ cursor.as_mut().as_mut_ptr() as *mut u8,
len,
out_num_bytes.as_mut_ptr(),
))
@@ -376,9 +384,7 @@ impl File {
// Safety: `num_bytes_read` bytes were written to the unfilled
// portion of the buffer
- buf.assume_init(num_bytes_read);
-
- buf.add_filled(num_bytes_read);
+ cursor.advance(num_bytes_read);
Ok(())
}
@@ -452,6 +458,10 @@ impl File {
pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
unsupported()
}
+
+ pub fn set_times(&self, _times: FileTimes) -> io::Result<()> {
+ unsupported()
+ }
}
impl Drop for File {
diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs
index 778a589d1..5867979a2 100644
--- a/library/std/src/sys/solid/mod.rs
+++ b/library/std/src/sys/solid/mod.rs
@@ -56,7 +56,7 @@ pub mod locks {
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
-pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
+pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
// SAFETY: must be called only once during runtime cleanup.
pub unsafe fn cleanup() {}
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index 30812dabb..dbaa3c33e 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -4,7 +4,7 @@
mod tests;
use crate::cmp;
-use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read};
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::sys::cvt;
use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -131,20 +131,19 @@ impl FileDesc {
}
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let ret = cvt(unsafe {
libc::read(
self.as_raw_fd(),
- buf.unfilled_mut().as_mut_ptr() as *mut libc::c_void,
- cmp::min(buf.remaining(), READ_LIMIT),
+ cursor.as_mut().as_mut_ptr() as *mut libc::c_void,
+ cmp::min(cursor.capacity(), READ_LIMIT),
)
})?;
// Safety: `ret` bytes were written to the initialized portion of the buffer
unsafe {
- buf.assume_init(ret as usize);
+ cursor.advance(ret as usize);
}
- buf.add_filled(ret as usize);
Ok(())
}
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index b5cc8038c..cc347e358 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -2,7 +2,7 @@ use crate::os::unix::prelude::*;
use crate::ffi::{CStr, CString, OsStr, OsString};
use crate::fmt;
-use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
+use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
use crate::mem;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
use crate::path::{Path, PathBuf};
@@ -544,11 +544,11 @@ impl Default for FileTimes {
fn default() -> Self {
// Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return
// an error in `set_times`.
- // ESP-IDF does not support `futimens` at all and the behavior for that OS is therefore
+ // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox.
- #[cfg(any(target_os = "redox", target_os = "espidf"))]
+ #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))]
let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 };
- #[cfg(not(any(target_os = "redox", target_os = "espidf")))]
+ #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ };
Self([omit; 2])
}
@@ -687,7 +687,11 @@ impl Iterator for ReadDir {
impl Drop for Dir {
fn drop(&mut self) {
let r = unsafe { libc::closedir(self.0) };
- debug_assert_eq!(r, 0);
+ assert!(
+ r == 0 || crate::io::Error::last_os_error().kind() == crate::io::ErrorKind::Interrupted,
+ "unexpected error during closedir: {:?}",
+ crate::io::Error::last_os_error()
+ );
}
}
@@ -825,6 +829,7 @@ impl DirEntry {
target_os = "fuchsia",
target_os = "redox"
)))]
+ #[cfg_attr(miri, allow(unused))]
fn name_cstr(&self) -> &CStr {
unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }
}
@@ -836,6 +841,7 @@ impl DirEntry {
target_os = "fuchsia",
target_os = "redox"
))]
+ #[cfg_attr(miri, allow(unused))]
fn name_cstr(&self) -> &CStr {
&self.name
}
@@ -1031,8 +1037,8 @@ impl File {
self.0.read_at(buf, offset)
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- self.0.read_buf(buf)
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ self.0.read_buf(cursor)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
@@ -1079,9 +1085,9 @@ impl File {
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
cfg_if::cfg_if! {
- if #[cfg(any(target_os = "redox", target_os = "espidf"))] {
+ if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
// Redox doesn't appear to support `UTIME_OMIT`.
- // ESP-IDF does not support `futimens` at all and the behavior for that OS is therefore
+ // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox.
drop(times);
Err(io::const_io_error!(
diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs
index ce427599c..117611ce4 100644
--- a/library/std/src/sys/unix/locks/fuchsia_mutex.rs
+++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs
@@ -86,9 +86,6 @@ impl Mutex {
}
#[inline]
- pub unsafe fn init(&mut self) {}
-
- #[inline]
pub unsafe fn try_lock(&self) -> bool {
let thread_self = zx_thread_self();
self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok()
@@ -138,7 +135,7 @@ impl Mutex {
}
}
- // The state has changed or a wakeup occured, try to lock the mutex.
+ // The state has changed or a wakeup occurred, try to lock the mutex.
match self.futex.compare_exchange(UNLOCKED, owned_state, Acquire, Relaxed) {
Ok(_) => return,
Err(updated) => state = updated,
diff --git a/library/std/src/sys/unix/locks/futex_mutex.rs b/library/std/src/sys/unix/locks/futex_mutex.rs
index 99ba86e5f..33b13dad4 100644
--- a/library/std/src/sys/unix/locks/futex_mutex.rs
+++ b/library/std/src/sys/unix/locks/futex_mutex.rs
@@ -20,9 +20,6 @@ impl Mutex {
}
#[inline]
- pub unsafe fn init(&mut self) {}
-
- #[inline]
pub unsafe fn try_lock(&self) -> bool {
self.futex.compare_exchange(0, 1, Acquire, Relaxed).is_ok()
}
@@ -53,7 +50,7 @@ impl Mutex {
// We avoid an unnecessary write if it as already set to 2,
// to be friendlier for the caches.
if state != 2 && self.futex.swap(2, Acquire) == 0 {
- // We changed it from 0 to 2, so we just succesfully locked it.
+ // We changed it from 0 to 2, so we just successfully locked it.
return;
}
diff --git a/library/std/src/sys/unix/locks/futex_rwlock.rs b/library/std/src/sys/unix/locks/futex_rwlock.rs
index b3bbbf743..0cc92244e 100644
--- a/library/std/src/sys/unix/locks/futex_rwlock.rs
+++ b/library/std/src/sys/unix/locks/futex_rwlock.rs
@@ -54,7 +54,7 @@ fn is_read_lockable(state: u32) -> bool {
// We don't allow read-locking if there's readers waiting, even if the lock is unlocked
// and there's no writers waiting. The only situation when this happens is after unlocking,
// at which point the unlocking thread might be waking up writers, which have priority over readers.
- // The unlocking thread will clear the readers waiting bit and wake up readers, if necssary.
+ // The unlocking thread will clear the readers waiting bit and wake up readers, if necessary.
state & MASK < MAX_READERS && !has_readers_waiting(state) && !has_writers_waiting(state)
}
diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs
index abf27e7db..4741c0c67 100644
--- a/library/std/src/sys/unix/locks/pthread_condvar.rs
+++ b/library/std/src/sys/unix/locks/pthread_condvar.rs
@@ -172,7 +172,7 @@ impl Condvar {
let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
let stable_now = Instant::now();
let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
- debug_assert_eq!(r, 0);
+ assert_eq!(r, 0, "unexpected error: {:?}", crate::io::Error::last_os_error());
let nsec = dur.subsec_nanos() as libc::c_long + (sys_now.tv_usec * 1000) as libc::c_long;
let extra = (nsec / 1_000_000_000) as libc::time_t;
diff --git a/library/std/src/sys/unix/locks/pthread_mutex.rs b/library/std/src/sys/unix/locks/pthread_mutex.rs
index 98afee69b..5964935dd 100644
--- a/library/std/src/sys/unix/locks/pthread_mutex.rs
+++ b/library/std/src/sys/unix/locks/pthread_mutex.rs
@@ -52,7 +52,7 @@ impl Mutex {
Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
}
#[inline]
- pub unsafe fn init(&mut self) {
+ unsafe fn init(&mut self) {
// Issue #33770
//
// A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 3d0d91460..c84e292ea 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -44,12 +44,13 @@ pub mod thread_parker;
pub mod time;
#[cfg(target_os = "espidf")]
-pub fn init(argc: isize, argv: *const *const u8) {}
+pub fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {}
#[cfg(not(target_os = "espidf"))]
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
-pub unsafe fn init(argc: isize, argv: *const *const u8) {
+// See `fn init()` in `library/std/src/rt.rs` for docs on `sigpipe`.
+pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
// The standard streams might be closed on application startup. To prevent
// std::io::{stdin, stdout,stderr} objects from using other unrelated file
// resources opened later, we reopen standards streams when they are closed.
@@ -61,8 +62,9 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
// want!
//
// Hence, we set SIGPIPE to ignore when the program starts up in order
- // to prevent this problem.
- reset_sigpipe();
+ // to prevent this problem. Add `#[unix_sigpipe = "..."]` above `fn main()` to
+ // alter this behavior.
+ reset_sigpipe(sigpipe);
stack_overflow::init();
args::init(argc, argv);
@@ -151,9 +153,31 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
}
}
- unsafe fn reset_sigpipe() {
+ unsafe fn reset_sigpipe(#[allow(unused_variables)] sigpipe: u8) {
#[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "horizon")))]
- rtassert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
+ {
+ // We don't want to add this as a public type to libstd, nor do we
+ // want to `include!` a file from the compiler (which would break
+ // Miri and xargo for example), so we choose to duplicate these
+ // constants from `compiler/rustc_session/src/config/sigpipe.rs`.
+ // See the other file for docs. NOTE: Make sure to keep them in
+ // sync!
+ mod sigpipe {
+ pub const INHERIT: u8 = 1;
+ pub const SIG_IGN: u8 = 2;
+ pub const SIG_DFL: u8 = 3;
+ }
+
+ let handler = match sigpipe {
+ sigpipe::INHERIT => None,
+ sigpipe::SIG_IGN => Some(libc::SIG_IGN),
+ sigpipe::SIG_DFL => Some(libc::SIG_DFL),
+ _ => unreachable!(),
+ };
+ if let Some(handler) = handler {
+ rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR);
+ }
+ }
}
}
@@ -295,8 +319,10 @@ pub fn abort_internal() -> ! {
cfg_if::cfg_if! {
if #[cfg(target_os = "android")] {
- #[link(name = "dl")]
- #[link(name = "log")]
+ #[link(name = "dl", kind = "static", modifiers = "-bundle",
+ cfg(target_feature = "crt-static"))]
+ #[link(name = "dl", cfg(not(target_feature = "crt-static")))]
+ #[link(name = "log", cfg(not(target_feature = "crt-static")))]
extern "C" {}
} else if #[cfg(target_os = "freebsd")] {
#[link(name = "execinfo")]
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index 462a45b01..b84bf8f92 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -393,6 +393,17 @@ impl Socket {
}
#[cfg(any(target_os = "android", target_os = "linux",))]
+ pub fn set_quickack(&self, quickack: bool) -> io::Result<()> {
+ setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int)
+ }
+
+ #[cfg(any(target_os = "android", target_os = "linux",))]
+ pub fn quickack(&self) -> io::Result<bool> {
+ let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?;
+ Ok(raw != 0)
+ }
+
+ #[cfg(any(target_os = "android", target_os = "linux",))]
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
}
@@ -427,6 +438,17 @@ impl Socket {
self.0.set_nonblocking(nonblocking)
}
+ #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))]
+ pub fn set_mark(&self, mark: u32) -> io::Result<()> {
+ #[cfg(target_os = "linux")]
+ let option = libc::SO_MARK;
+ #[cfg(target_os = "freebsd")]
+ let option = libc::SO_USER_COOKIE;
+ #[cfg(target_os = "openbsd")]
+ let option = libc::SO_RTABLE;
+ setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int)
+ }
+
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs
index ccbc18224..017e2af29 100644
--- a/library/std/src/sys/unix/os_str.rs
+++ b/library/std/src/sys/unix/os_str.rs
@@ -11,7 +11,7 @@ use crate::str;
use crate::sync::Arc;
use crate::sys_common::{AsInner, IntoInner};
-use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
+use core::str::Utf8Chunks;
#[cfg(test)]
#[path = "../unix/os_str/tests.rs"]
@@ -29,26 +29,32 @@ pub struct Slice {
}
impl fmt::Debug for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- // Writes out a valid unicode string with the correct escape sequences
-
- formatter.write_str("\"")?;
- for Utf8LossyChunk { valid, broken } in Utf8Lossy::from_bytes(&self.inner).chunks() {
- for c in valid.chars().flat_map(|c| c.escape_debug()) {
- formatter.write_char(c)?
- }
-
- for b in broken {
- write!(formatter, "\\x{:02X}", b)?;
- }
- }
- formatter.write_str("\"")
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&Utf8Chunks::new(&self.inner).debug(), f)
}
}
impl fmt::Display for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // If we're the empty string then our iterator won't actually yield
+ // anything, so perform the formatting manually
+ if self.inner.is_empty() {
+ return "".fmt(f);
+ }
+
+ for chunk in Utf8Chunks::new(&self.inner) {
+ let valid = chunk.valid();
+ // If we successfully decoded the whole chunk as a valid string then
+ // we can return a direct formatting of the string which will also
+ // respect various formatting flags if possible.
+ if chunk.invalid().is_empty() {
+ return valid.fmt(f);
+ }
+
+ f.write_str(valid)?;
+ f.write_char(char::REPLACEMENT_CHARACTER)?;
+ }
+ Ok(())
}
}
diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs
index 213277f01..22ba0c923 100644
--- a/library/std/src/sys/unix/os_str/tests.rs
+++ b/library/std/src/sys/unix/os_str/tests.rs
@@ -8,3 +8,11 @@ fn slice_debug_output() {
assert_eq!(output, expected);
}
+
+#[test]
+fn display() {
+ assert_eq!(
+ "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye",
+ Slice::from_u8_slice(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string(),
+ );
+}
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index bca1b65a7..2834ee0ac 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -45,11 +45,31 @@ cfg_if::cfg_if! {
}
#[allow(dead_code)]
pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
- use crate::{slice, mem};
+ use crate::{
+ mem::{align_of, size_of},
+ slice,
+ };
+ use libc::{c_ulong, sigset_t};
+
+ // The implementations from bionic (android libc) type pun `sigset_t` as an
+ // array of `c_ulong`. This works, but lets add a smoke check to make sure
+ // that doesn't change.
+ const _: () = assert!(
+ align_of::<c_ulong>() == align_of::<sigset_t>()
+ && (size_of::<sigset_t>() % size_of::<c_ulong>()) == 0
+ );
- let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
let bit = (signum - 1) as usize;
- raw[bit / 8] |= 1 << (bit % 8);
+ if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
+ crate::sys::unix::os::set_errno(libc::EINVAL);
+ return -1;
+ }
+ let raw = slice::from_raw_parts_mut(
+ set as *mut c_ulong,
+ size_of::<sigset_t>() / size_of::<c_ulong>(),
+ );
+ const LONG_BIT: usize = size_of::<c_ulong>() * 8;
+ raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);
return 0;
}
} else {
@@ -72,6 +92,7 @@ pub struct Command {
argv: Argv,
env: CommandEnv,
+ program_kind: ProgramKind,
cwd: Option<CString>,
uid: Option<uid_t>,
gid: Option<gid_t>,
@@ -128,15 +149,40 @@ pub enum Stdio {
Fd(FileDesc),
}
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum ProgramKind {
+ /// A program that would be looked up on the PATH (e.g. `ls`)
+ PathLookup,
+ /// A relative path (e.g. `my-dir/foo`, `../foo`, `./foo`)
+ Relative,
+ /// An absolute path.
+ Absolute,
+}
+
+impl ProgramKind {
+ fn new(program: &OsStr) -> Self {
+ if program.bytes().starts_with(b"/") {
+ Self::Absolute
+ } else if program.bytes().contains(&b'/') {
+ // If the program has more than one component in it, it is a relative path.
+ Self::Relative
+ } else {
+ Self::PathLookup
+ }
+ }
+}
+
impl Command {
#[cfg(not(target_os = "linux"))]
pub fn new(program: &OsStr) -> Command {
let mut saw_nul = false;
+ let program_kind = ProgramKind::new(program.as_ref());
let program = os2c(program, &mut saw_nul);
Command {
argv: Argv(vec![program.as_ptr(), ptr::null()]),
args: vec![program.clone()],
program,
+ program_kind,
env: Default::default(),
cwd: None,
uid: None,
@@ -154,11 +200,13 @@ impl Command {
#[cfg(target_os = "linux")]
pub fn new(program: &OsStr) -> Command {
let mut saw_nul = false;
+ let program_kind = ProgramKind::new(program.as_ref());
let program = os2c(program, &mut saw_nul);
Command {
argv: Argv(vec![program.as_ptr(), ptr::null()]),
args: vec![program.clone()],
program,
+ program_kind,
env: Default::default(),
cwd: None,
uid: None,
@@ -234,6 +282,11 @@ impl Command {
OsStr::from_bytes(self.program.as_bytes())
}
+ #[allow(dead_code)]
+ pub fn get_program_kind(&self) -> ProgramKind {
+ self.program_kind
+ }
+
pub fn get_args(&self) -> CommandArgs<'_> {
let mut iter = self.args.iter();
iter.next();
diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs
index 1956b3692..d176b3401 100644
--- a/library/std/src/sys/unix/process/process_common/tests.rs
+++ b/library/std/src/sys/unix/process/process_common/tests.rs
@@ -122,3 +122,27 @@ fn test_process_group_no_posix_spawn() {
t!(cat.wait());
}
}
+
+#[test]
+fn test_program_kind() {
+ let vectors = &[
+ ("foo", ProgramKind::PathLookup),
+ ("foo.out", ProgramKind::PathLookup),
+ ("./foo", ProgramKind::Relative),
+ ("../foo", ProgramKind::Relative),
+ ("dir/foo", ProgramKind::Relative),
+ // Note that paths on Unix can't contain / in them, so this is actually the directory "fo\\"
+ // followed by the file "o".
+ ("fo\\/o", ProgramKind::Relative),
+ ("/foo", ProgramKind::Absolute),
+ ("/dir/../foo", ProgramKind::Absolute),
+ ];
+
+ for (program, expected_kind) in vectors {
+ assert_eq!(
+ ProgramKind::new(program.as_ref()),
+ *expected_kind,
+ "actual != expected program kind for input {program}",
+ );
+ }
+}
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 75bb92437..26ae62817 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -453,7 +453,9 @@ impl Command {
// successfully launch the program, but erroneously return
// ENOENT when used with posix_spawn_file_actions_addchdir_np
// which was introduced in macOS 10.15.
- return Ok(None);
+ if self.get_program_kind() == ProgramKind::Relative {
+ return Ok(None);
+ }
}
match posix_spawn_file_actions_addchdir_np.get() {
Some(f) => Some((f, cwd)),
diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs
index bf4920488..a6fe07873 100644
--- a/library/std/src/sys/unix/rand.rs
+++ b/library/std/src/sys/unix/rand.rs
@@ -1,13 +1,13 @@
-use crate::mem;
-use crate::slice;
-
pub fn hashmap_random_keys() -> (u64, u64) {
- let mut v = (0, 0);
- unsafe {
- let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, mem::size_of_val(&v));
- imp::fill_bytes(view);
- }
- v
+ const KEY_LEN: usize = core::mem::size_of::<u64>();
+
+ let mut v = [0u8; KEY_LEN * 2];
+ imp::fill_bytes(&mut v);
+
+ let key1 = v[0..KEY_LEN].try_into().unwrap();
+ let key2 = v[KEY_LEN..].try_into().unwrap();
+
+ (u64::from_ne_bytes(key1), u64::from_ne_bytes(key2))
}
#[cfg(all(
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 36a3fa602..f6b627afc 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -116,11 +116,9 @@ impl Thread {
debug_assert_eq!(ret, 0);
}
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(target_os = "android")]
pub fn set_name(name: &CStr) {
const PR_SET_NAME: libc::c_int = 15;
- // pthread wrapper only appeared in glibc 2.12, so we use syscall
- // directly.
unsafe {
libc::prctl(
PR_SET_NAME,
@@ -132,6 +130,17 @@ impl Thread {
}
}
+ #[cfg(target_os = "linux")]
+ pub fn set_name(name: &CStr) {
+ const TASK_COMM_LEN: usize = 16;
+
+ unsafe {
+ // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20.
+ let name = truncate_cstr(name, TASK_COMM_LEN);
+ libc::pthread_setname_np(libc::pthread_self(), name.as_ptr());
+ }
+ }
+
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
pub fn set_name(name: &CStr) {
unsafe {
@@ -142,6 +151,7 @@ impl Thread {
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
pub fn set_name(name: &CStr) {
unsafe {
+ let name = truncate_cstr(name, libc::MAXTHREADNAMESIZE);
libc::pthread_setname_np(name.as_ptr());
}
}
@@ -271,6 +281,20 @@ impl Drop for Thread {
}
}
+#[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios", target_os = "watchos"))]
+fn truncate_cstr(cstr: &CStr, max_with_nul: usize) -> crate::borrow::Cow<'_, CStr> {
+ use crate::{borrow::Cow, ffi::CString};
+
+ if cstr.to_bytes_with_nul().len() > max_with_nul {
+ let bytes = cstr.to_bytes()[..max_with_nul - 1].to_vec();
+ // SAFETY: the non-nul bytes came straight from a CStr.
+ // (CString will add the terminating nul.)
+ Cow::Owned(unsafe { CString::from_vec_unchecked(bytes) })
+ } else {
+ Cow::Borrowed(cstr)
+ }
+}
+
pub fn available_parallelism() -> io::Result<NonZeroUsize> {
cfg_if::cfg_if! {
if #[cfg(any(
@@ -423,7 +447,7 @@ mod cgroups {
Some(b"") => Cgroup::V2,
Some(controllers)
if from_utf8(controllers)
- .is_ok_and(|c| c.split(",").any(|c| c == "cpu")) =>
+ .is_ok_and(|c| c.split(',').any(|c| c == "cpu")) =>
{
Cgroup::V1
}
diff --git a/library/std/src/sys/unix/thread_parker/mod.rs b/library/std/src/sys/unix/thread_parker/mod.rs
new file mode 100644
index 000000000..e2453580d
--- /dev/null
+++ b/library/std/src/sys/unix/thread_parker/mod.rs
@@ -0,0 +1,21 @@
+//! Thread parking on systems without futex support.
+
+#![cfg(not(any(
+ target_os = "linux",
+ target_os = "android",
+ all(target_os = "emscripten", target_feature = "atomics"),
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "dragonfly",
+ target_os = "fuchsia",
+)))]
+
+cfg_if::cfg_if! {
+ if #[cfg(target_os = "netbsd")] {
+ mod netbsd;
+ pub use netbsd::Parker;
+ } else {
+ mod pthread;
+ pub use pthread::Parker;
+ }
+}
diff --git a/library/std/src/sys/unix/thread_parker/netbsd.rs b/library/std/src/sys/unix/thread_parker/netbsd.rs
new file mode 100644
index 000000000..7657605b5
--- /dev/null
+++ b/library/std/src/sys/unix/thread_parker/netbsd.rs
@@ -0,0 +1,113 @@
+use crate::ffi::{c_int, c_void};
+use crate::pin::Pin;
+use crate::ptr::{null, null_mut};
+use crate::sync::atomic::{
+ AtomicU64,
+ Ordering::{Acquire, Relaxed, Release},
+};
+use crate::time::Duration;
+use libc::{_lwp_self, clockid_t, lwpid_t, time_t, timespec, CLOCK_MONOTONIC};
+
+extern "C" {
+ fn ___lwp_park60(
+ clock_id: clockid_t,
+ flags: c_int,
+ ts: *mut timespec,
+ unpark: lwpid_t,
+ hint: *const c_void,
+ unparkhint: *const c_void,
+ ) -> c_int;
+ fn _lwp_unpark(lwp: lwpid_t, hint: *const c_void) -> c_int;
+}
+
+/// The thread is not parked and the token is not available.
+///
+/// Zero cannot be a valid LWP id, since it is used as empty value for the unpark
+/// argument in _lwp_park.
+const EMPTY: u64 = 0;
+/// The token is available. Do not park anymore.
+const NOTIFIED: u64 = u64::MAX;
+
+pub struct Parker {
+ /// The parker state. Contains either one of the two state values above or the LWP
+ /// id of the parked thread.
+ state: AtomicU64,
+}
+
+impl Parker {
+ pub unsafe fn new(parker: *mut Parker) {
+ parker.write(Parker { state: AtomicU64::new(EMPTY) })
+ }
+
+ // Does not actually need `unsafe` or `Pin`, but the pthread implementation does.
+ pub unsafe fn park(self: Pin<&Self>) {
+ // If the token has already been made available, we can skip
+ // a bit of work, so check for it here.
+ if self.state.load(Acquire) != NOTIFIED {
+ let parked = _lwp_self() as u64;
+ let hint = self.state.as_mut_ptr().cast();
+ if self.state.compare_exchange(EMPTY, parked, Relaxed, Acquire).is_ok() {
+ // Loop to guard against spurious wakeups.
+ loop {
+ ___lwp_park60(0, 0, null_mut(), 0, hint, null());
+ if self.state.load(Acquire) == NOTIFIED {
+ break;
+ }
+ }
+ }
+ }
+
+ // At this point, the change to NOTIFIED has always been observed with acquire
+ // ordering, so we can just use a relaxed store here (instead of a swap).
+ self.state.store(EMPTY, Relaxed);
+ }
+
+ // Does not actually need `unsafe` or `Pin`, but the pthread implementation does.
+ pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
+ if self.state.load(Acquire) != NOTIFIED {
+ let parked = _lwp_self() as u64;
+ let hint = self.state.as_mut_ptr().cast();
+ let mut timeout = timespec {
+ // Saturate so that the operation will definitely time out
+ // (even if it is after the heat death of the universe).
+ tv_sec: dur.as_secs().try_into().ok().unwrap_or(time_t::MAX),
+ tv_nsec: dur.subsec_nanos().into(),
+ };
+
+ if self.state.compare_exchange(EMPTY, parked, Relaxed, Acquire).is_ok() {
+ // Timeout needs to be mutable since it is modified on NetBSD 9.0 and
+ // above.
+ ___lwp_park60(CLOCK_MONOTONIC, 0, &mut timeout, 0, hint, null());
+ // Use a swap to get acquire ordering even if the token was set after
+ // the timeout occurred.
+ self.state.swap(EMPTY, Acquire);
+ return;
+ }
+ }
+
+ self.state.store(EMPTY, Relaxed);
+ }
+
+ // Does not actually need `Pin`, but the pthread implementation does.
+ pub fn unpark(self: Pin<&Self>) {
+ let state = self.state.swap(NOTIFIED, Release);
+ if !matches!(state, EMPTY | NOTIFIED) {
+ let lwp = state as lwpid_t;
+ let hint = self.state.as_mut_ptr().cast();
+
+ // If the parking thread terminated and did not actually park, this will
+ // probably return an error, which is OK. In the worst case, another
+ // thread has received the same LWP id. It will then receive a spurious
+ // wakeup, but those are allowable per the API contract. The same reasoning
+ // applies if a timeout occurred before this call, but the state was not
+ // yet reset.
+
+ // SAFETY:
+ // The syscall has no invariants to hold. Only unsafe because it is an
+ // extern function.
+ unsafe {
+ _lwp_unpark(lwp, hint);
+ }
+ }
+ }
+}
diff --git a/library/std/src/sys/unix/thread_parker.rs b/library/std/src/sys/unix/thread_parker/pthread.rs
index ca1a7138f..3dfc0026e 100644
--- a/library/std/src/sys/unix/thread_parker.rs
+++ b/library/std/src/sys/unix/thread_parker/pthread.rs
@@ -1,15 +1,5 @@
//! Thread parking without `futex` using the `pthread` synchronization primitives.
-#![cfg(not(any(
- target_os = "linux",
- target_os = "android",
- all(target_os = "emscripten", target_feature = "atomics"),
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- target_os = "fuchsia",
-)))]
-
use crate::cell::UnsafeCell;
use crate::marker::PhantomPinned;
use crate::pin::Pin;
@@ -59,8 +49,8 @@ unsafe fn wait_timeout(
target_os = "espidf"
))]
let (now, dur) = {
- use super::time::SystemTime;
use crate::cmp::min;
+ use crate::sys::time::SystemTime;
// OSX implementation of `pthread_cond_timedwait` is buggy
// with super long durations. When duration is greater than
@@ -85,7 +75,7 @@ unsafe fn wait_timeout(
target_os = "espidf"
)))]
let (now, dur) = {
- use super::time::Timespec;
+ use crate::sys::time::Timespec;
(Timespec::now(libc::CLOCK_MONOTONIC), dur)
};
diff --git a/library/std/src/sys/unsupported/alloc.rs b/library/std/src/sys/unsupported/alloc.rs
index 8d5d0a2f5..d715ae454 100644
--- a/library/std/src/sys/unsupported/alloc.rs
+++ b/library/std/src/sys/unsupported/alloc.rs
@@ -1,15 +1,16 @@
use crate::alloc::{GlobalAlloc, Layout, System};
+use crate::ptr::null_mut;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
- 0 as *mut u8
+ null_mut()
}
#[inline]
unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
- 0 as *mut u8
+ null_mut()
}
#[inline]
@@ -17,6 +18,6 @@ unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
- 0 as *mut u8
+ null_mut()
}
}
diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs
index 4c9ade4a8..5cd9e57de 100644
--- a/library/std/src/sys/unsupported/common.rs
+++ b/library/std/src/sys/unsupported/common.rs
@@ -6,7 +6,7 @@ pub mod memchr {
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
-pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
+pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
diff --git a/library/std/src/sys/unsupported/fs.rs b/library/std/src/sys/unsupported/fs.rs
index 0e1a6257e..6ac1b5d2b 100644
--- a/library/std/src/sys/unsupported/fs.rs
+++ b/library/std/src/sys/unsupported/fs.rs
@@ -1,7 +1,7 @@
use crate::ffi::OsString;
use crate::fmt;
use crate::hash::{Hash, Hasher};
-use crate::io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
use crate::path::{Path, PathBuf};
use crate::sys::time::SystemTime;
use crate::sys::unsupported;
@@ -214,7 +214,7 @@ impl File {
self.0
}
- pub fn read_buf(&self, _buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.0
}
diff --git a/library/std/src/sys/unsupported/locks/mutex.rs b/library/std/src/sys/unsupported/locks/mutex.rs
index d7cb12e0c..2be0b34b9 100644
--- a/library/std/src/sys/unsupported/locks/mutex.rs
+++ b/library/std/src/sys/unsupported/locks/mutex.rs
@@ -17,9 +17,6 @@ impl Mutex {
}
#[inline]
- pub unsafe fn init(&mut self) {}
-
- #[inline]
pub unsafe fn lock(&self) {
assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex");
}
diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs
index 42a1ff730..633f17c05 100644
--- a/library/std/src/sys/unsupported/process.rs
+++ b/library/std/src/sys/unsupported/process.rs
@@ -200,6 +200,9 @@ impl<'a> Iterator for CommandArgs<'a> {
fn next(&mut self) -> Option<&'a OsStr> {
None
}
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, Some(0))
+ }
}
impl<'a> ExactSizeIterator for CommandArgs<'a> {}
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 6614ae397..510cf36b1 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -3,7 +3,7 @@
use super::fd::WasiFd;
use crate::ffi::{CStr, CString, OsStr, OsString};
use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
use crate::iter;
use crate::mem::{self, ManuallyDrop};
use crate::os::raw::c_int;
@@ -439,8 +439,8 @@ impl File {
true
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- crate::io::default_read_buf(|buf| self.read(buf), buf)
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ crate::io::default_read_buf(|buf| self.read(buf), cursor)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs
index 4cc0e4ed5..d2081771b 100644
--- a/library/std/src/sys/wasi/stdio.rs
+++ b/library/std/src/sys/wasi/stdio.rs
@@ -4,7 +4,7 @@ use super::fd::WasiFd;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::mem::ManuallyDrop;
use crate::os::raw;
-use crate::os::wasi::io::{AsRawFd, FromRawFd};
+use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd};
pub struct Stdin;
pub struct Stdout;
@@ -23,6 +23,13 @@ impl AsRawFd for Stdin {
}
}
+impl AsFd for Stdin {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ unsafe { BorrowedFd::borrow_raw(0) }
+ }
+}
+
impl io::Read for Stdin {
fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
self.read_vectored(&mut [IoSliceMut::new(data)])
@@ -51,6 +58,13 @@ impl AsRawFd for Stdout {
}
}
+impl AsFd for Stdout {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ unsafe { BorrowedFd::borrow_raw(1) }
+ }
+}
+
impl io::Write for Stdout {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
self.write_vectored(&[IoSlice::new(data)])
@@ -82,6 +96,13 @@ impl AsRawFd for Stderr {
}
}
+impl AsFd for Stderr {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ unsafe { BorrowedFd::borrow_raw(2) }
+ }
+}
+
impl io::Write for Stderr {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
self.write_vectored(&[IoSlice::new(data)])
diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs
index fdc81cdea..d53ea1600 100644
--- a/library/std/src/sys/windows/alloc.rs
+++ b/library/std/src/sys/windows/alloc.rs
@@ -16,6 +16,7 @@ mod tests;
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
+#[link(name = "kernel32")]
extern "system" {
// Get a handle to the default heap of the current process, or null if the operation fails.
//
@@ -168,7 +169,7 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 {
// SAFETY: Because the size and alignment of a header is <= `MIN_ALIGN` and `aligned`
// is aligned to at least `MIN_ALIGN` and has at least `MIN_ALIGN` bytes of padding before
// it, it is safe to write a header directly before it.
- unsafe { ptr::write((aligned as *mut Header).offset(-1), Header(ptr)) };
+ unsafe { ptr::write((aligned as *mut Header).sub(1), Header(ptr)) };
// SAFETY: The returned pointer does not point to the to the start of an allocated block,
// but there is a header readable directly before it containing the location of the start
@@ -213,7 +214,7 @@ unsafe impl GlobalAlloc for System {
// SAFETY: Because of the contract of `System`, `ptr` is guaranteed to be non-null
// and have a header readable directly before it.
- unsafe { ptr::read((ptr as *mut Header).offset(-1)).0 }
+ unsafe { ptr::read((ptr as *mut Header).sub(1)).0 }
}
};
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 478068c73..89d0ab59b 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -66,6 +66,7 @@ pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
pub type LPWSABUF = *mut WSABUF;
pub type LPWSAOVERLAPPED = *mut c_void;
pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void;
+pub type BCRYPT_ALG_HANDLE = LPVOID;
pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
pub type PLARGE_INTEGER = *mut c_longlong;
@@ -278,6 +279,7 @@ pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _;
pub const STATUS_PENDING: NTSTATUS = 0x103 as _;
pub const STATUS_END_OF_FILE: NTSTATUS = 0xC0000011_u32 as _;
pub const STATUS_NOT_IMPLEMENTED: NTSTATUS = 0xC0000002_u32 as _;
+pub const STATUS_NOT_SUPPORTED: NTSTATUS = 0xC00000BB_u32 as _;
// Equivalent to the `NT_SUCCESS` C preprocessor macro.
// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
@@ -285,7 +287,8 @@ pub fn nt_success(status: NTSTATUS) -> bool {
status >= 0
}
-pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
+// "RNG\0"
+pub const BCRYPT_RNG_ALGORITHM: &[u16] = &[b'R' as u16, b'N' as u16, b'G' as u16, 0];
#[repr(C)]
pub struct UNICODE_STRING {
@@ -455,6 +458,12 @@ pub enum FILE_INFO_BY_HANDLE_CLASS {
}
#[repr(C)]
+pub struct FILE_ATTRIBUTE_TAG_INFO {
+ pub FileAttributes: DWORD,
+ pub ReparseTag: DWORD,
+}
+
+#[repr(C)]
pub struct FILE_DISPOSITION_INFO {
pub DeleteFile: BOOLEAN,
}
@@ -501,6 +510,8 @@ pub struct FILE_END_OF_FILE_INFO {
pub EndOfFile: LARGE_INTEGER,
}
+/// NB: Use carefully! In general using this as a reference is likely to get the
+/// provenance wrong for the `rest` field!
#[repr(C)]
pub struct REPARSE_DATA_BUFFER {
pub ReparseTag: c_uint,
@@ -509,6 +520,8 @@ pub struct REPARSE_DATA_BUFFER {
pub rest: (),
}
+/// NB: Use carefully! In general using this as a reference is likely to get the
+/// provenance wrong for the `PathBuffer` field!
#[repr(C)]
pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
pub SubstituteNameOffset: c_ushort,
@@ -519,6 +532,8 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
pub PathBuffer: WCHAR,
}
+/// NB: Use carefully! In general using this as a reference is likely to get the
+/// provenance wrong for the `PathBuffer` field!
#[repr(C)]
pub struct MOUNT_POINT_REPARSE_BUFFER {
pub SubstituteNameOffset: c_ushort,
@@ -1217,11 +1232,18 @@ extern "system" {
// >= Vista / Server 2008
// https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
pub fn BCryptGenRandom(
- hAlgorithm: LPVOID,
+ hAlgorithm: BCRYPT_ALG_HANDLE,
pBuffer: *mut u8,
cbBuffer: ULONG,
dwFlags: ULONG,
) -> NTSTATUS;
+ pub fn BCryptOpenAlgorithmProvider(
+ phalgorithm: *mut BCRYPT_ALG_HANDLE,
+ pszAlgId: LPCWSTR,
+ pszimplementation: LPCWSTR,
+ dwflags: ULONG,
+ ) -> NTSTATUS;
+ pub fn BCryptCloseAlgorithmProvider(hAlgorithm: BCRYPT_ALG_HANDLE, dwFlags: ULONG) -> NTSTATUS;
}
// Functions that aren't available on every version of Windows that we support,
@@ -1251,17 +1273,14 @@ compat_fn_with_fallback! {
}
compat_fn_optional! {
- pub static SYNCH_API: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
-
- // >= Windows 8 / Server 2012
- // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress
+ crate::sys::compat::load_synch_functions();
pub fn WaitOnAddress(
Address: LPVOID,
CompareAddress: LPVOID,
AddressSize: SIZE_T,
dwMilliseconds: DWORD
- ) -> BOOL;
- pub fn WakeByAddressSingle(Address: LPVOID) -> ();
+ );
+ pub fn WakeByAddressSingle(Address: LPVOID);
}
compat_fn_with_fallback! {
diff --git a/library/std/src/sys/windows/cmath.rs b/library/std/src/sys/windows/cmath.rs
index 1a5421fac..43ab8c7ee 100644
--- a/library/std/src/sys/windows/cmath.rs
+++ b/library/std/src/sys/windows/cmath.rs
@@ -44,7 +44,7 @@ mod shims {
}
// On 32-bit x86 MSVC these functions aren't defined, so we just define shims
-// which promote everything fo f64, perform the calculation, and then demote
+// which promote everything to f64, perform the calculation, and then demote
// back to f32. While not precisely correct should be "correct enough" for now.
#[cfg(all(target_env = "msvc", target_arch = "x86"))]
mod shims {
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs
index ccc90177a..7dff81ecb 100644
--- a/library/std/src/sys/windows/compat.rs
+++ b/library/std/src/sys/windows/compat.rs
@@ -7,52 +7,66 @@
//! `GetModuleHandle` and `GetProcAddress` to look up DLL entry points at
//! runtime.
//!
-//! This implementation uses a static initializer to look up the DLL entry
-//! points. The CRT (C runtime) executes static initializers before `main`
-//! is called (for binaries) and before `DllMain` is called (for DLLs).
-//! This is the ideal time to look up DLL imports, because we are guaranteed
-//! that no other threads will attempt to call these entry points. Thus,
-//! we can look up the imports and store them in `static mut` fields
-//! without any synchronization.
+//! This is implemented simply by storing a function pointer in an atomic.
+//! Loading and calling this function will have little or no overhead
+//! compared with calling any other dynamically imported function.
//!
-//! This has an additional advantage: Because the DLL import lookup happens
-//! at module initialization, the cost of these lookups is deterministic,
-//! and is removed from the code paths that actually call the DLL imports.
-//! That is, there is no unpredictable "cache miss" that occurs when calling
-//! a DLL import. For applications that benefit from predictable delays,
-//! this is a benefit. This also eliminates the comparison-and-branch
-//! from the hot path.
-//!
-//! Currently, the standard library uses only a small number of dynamic
-//! DLL imports. If this number grows substantially, then the cost of
-//! performing all of the lookups at initialization time might become
-//! substantial.
-//!
-//! The mechanism of registering a static initializer with the CRT is
-//! documented in
-//! [CRT Initialization](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-160).
-//! It works by contributing a global symbol to the `.CRT$XCU` section.
-//! The linker builds a table of all static initializer functions.
-//! The CRT startup code then iterates that table, calling each
-//! initializer function.
-//!
-//! # **WARNING!!*
-//! The environment that a static initializer function runs in is highly
-//! constrained. There are **many** restrictions on what static initializers
-//! can safely do. Static initializer functions **MUST NOT** do any of the
-//! following (this list is not comprehensive):
-//! * touch any other static field that is used by a different static
-//! initializer, because the order that static initializers run in
-//! is not defined.
-//! * call `LoadLibrary` or any other function that acquires the DLL
-//! loader lock.
-//! * call any Rust function or CRT function that touches any static
-//! (global) state.
+//! The stored function pointer starts out as an importer function which will
+//! swap itself with the real function when it's called for the first time. If
+//! the real function can't be imported then a fallback function is used in its
+//! place. While this is low cost for the happy path (where the function is
+//! already loaded) it does mean there's some overhead the first time the
+//! function is called. In the worst case, multiple threads may all end up
+//! importing the same function unnecessarily.
use crate::ffi::{c_void, CStr};
use crate::ptr::NonNull;
+use crate::sync::atomic::Ordering;
use crate::sys::c;
+// This uses a static initializer to preload some imported functions.
+// The CRT (C runtime) executes static initializers before `main`
+// is called (for binaries) and before `DllMain` is called (for DLLs).
+//
+// It works by contributing a global symbol to the `.CRT$XCT` section.
+// The linker builds a table of all static initializer functions.
+// The CRT startup code then iterates that table, calling each
+// initializer function.
+//
+// NOTE: User code should instead use .CRT$XCU to reliably run after std's initializer.
+// If you're reading this and would like a guarantee here, please
+// file an issue for discussion; currently we don't guarantee any functionality
+// before main.
+// See https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170
+#[used]
+#[link_section = ".CRT$XCT"]
+static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
+
+/// Preload some imported functions.
+///
+/// Note that any functions included here will be unconditionally loaded in
+/// the final binary, regardless of whether or not they're actually used.
+///
+/// Therefore, this should be limited to `compat_fn_optional` functions which
+/// must be preloaded or any functions where lazier loading demonstrates a
+/// negative performance impact in practical situations.
+///
+/// Currently we only preload `WaitOnAddress` and `WakeByAddressSingle`.
+unsafe extern "C" fn init() {
+ // In an exe this code is executed before main() so is single threaded.
+ // In a DLL the system's loader lock will be held thereby synchronizing
+ // access. So the same best practices apply here as they do to running in DllMain:
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
+ //
+ // DO NOT do anything interesting or complicated in this function! DO NOT call
+ // any Rust functions or CRT functions if those functions touch any global state,
+ // because this function runs during global initialization. For example, DO NOT
+ // do any dynamic allocation, don't call LoadLibrary, etc.
+
+ // Attempt to preload the synch functions.
+ load_synch_functions();
+}
+
/// Helper macro for creating CStrs from literals and symbol names.
macro_rules! ansi_str {
(sym $ident:ident) => {{
@@ -85,39 +99,6 @@ pub(crate) const fn const_cstr_from_bytes(bytes: &'static [u8]) -> &'static CStr
unsafe { crate::ffi::CStr::from_bytes_with_nul_unchecked(bytes) }
}
-#[used]
-#[link_section = ".CRT$XCU"]
-static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
-
-/// This is where the magic preloading of symbols happens.
-///
-/// Note that any functions included here will be unconditionally included in
-/// the final binary, regardless of whether or not they're actually used.
-///
-/// Therefore, this is limited to `compat_fn_optional` functions which must be
-/// preloaded and any functions which may be more time sensitive, even for the first call.
-unsafe extern "C" fn init() {
- // There is no locking here. This code is executed before main() is entered, and
- // is guaranteed to be single-threaded.
- //
- // DO NOT do anything interesting or complicated in this function! DO NOT call
- // any Rust functions or CRT functions if those functions touch any global state,
- // because this function runs during global initialization. For example, DO NOT
- // do any dynamic allocation, don't call LoadLibrary, etc.
-
- if let Some(synch) = Module::new(c::SYNCH_API) {
- // These are optional and so we must manually attempt to load them
- // before they can be used.
- c::WaitOnAddress::preload(synch);
- c::WakeByAddressSingle::preload(synch);
- }
-
- if let Some(kernel32) = Module::new(c::KERNEL32) {
- // Preloading this means getting a precise time will be as fast as possible.
- c::GetSystemTimePreciseAsFileTime::preload(kernel32);
- }
-}
-
/// Represents a loaded module.
///
/// Note that the modules std depends on must not be unloaded.
@@ -151,7 +132,7 @@ impl Module {
macro_rules! compat_fn_with_fallback {
(pub static $module:ident: &CStr = $name:expr; $(
$(#[$meta:meta])*
- pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $fallback_body:block
+ $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $fallback_body:block
)*) => (
pub static $module: &CStr = $name;
$(
@@ -196,11 +177,6 @@ macro_rules! compat_fn_with_fallback {
$fallback_body
}
- #[allow(unused)]
- pub(in crate::sys) fn preload(module: Module) {
- load_from_module(Some(module));
- }
-
#[inline(always)]
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
let func: F = mem::transmute(PTR.load(Ordering::Relaxed));
@@ -208,66 +184,60 @@ macro_rules! compat_fn_with_fallback {
}
}
$(#[$meta])*
- pub use $symbol::call as $symbol;
+ $vis use $symbol::call as $symbol;
)*)
}
-/// A function that either exists or doesn't.
+/// Optionally loaded functions.
///
-/// NOTE: Optional functions must be preloaded in the `init` function above, or they will always be None.
+/// Actual loading of the function defers to $load_functions.
macro_rules! compat_fn_optional {
- (pub static $module:ident: &CStr = $name:expr; $(
- $(#[$meta:meta])*
- pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty;
- )*) => (
- pub static $module: &CStr = $name;
+ ($load_functions:expr;
$(
- $(#[$meta])*
- pub mod $symbol {
- #[allow(unused_imports)]
- use super::*;
- use crate::mem;
- use crate::sync::atomic::{AtomicPtr, Ordering};
- use crate::sys::compat::Module;
- use crate::ptr::{self, NonNull};
-
- type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
-
- /// `PTR` will either be `null()` or set to the loaded function.
- static PTR: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
-
- /// Only allow access to the function if it has loaded successfully.
- #[inline(always)]
- #[cfg(not(miri))]
- pub fn option() -> Option<F> {
- unsafe {
- NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| mem::transmute(f))
+ $(#[$meta:meta])*
+ $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) $(-> $rettype:ty)?;
+ )+) => (
+ $(
+ pub mod $symbol {
+ use super::*;
+ use crate::ffi::c_void;
+ use crate::mem;
+ use crate::ptr::{self, NonNull};
+ use crate::sync::atomic::{AtomicPtr, Ordering};
+
+ pub(in crate::sys) static PTR: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
+
+ type F = unsafe extern "system" fn($($argtype),*) $(-> $rettype)?;
+
+ #[inline(always)]
+ pub fn option() -> Option<F> {
+ // Miri does not understand the way we do preloading
+ // therefore load the function here instead.
+ #[cfg(miri)] $load_functions;
+ NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) })
}
}
+ )+
+ )
+}
- // Miri does not understand the way we do preloading
- // therefore load the function here instead.
- #[cfg(miri)]
- pub fn option() -> Option<F> {
- let mut func = NonNull::new(PTR.load(Ordering::Relaxed));
- if func.is_none() {
- unsafe { Module::new($module).map(preload) };
- func = NonNull::new(PTR.load(Ordering::Relaxed));
- }
- unsafe {
- func.map(|f| mem::transmute(f))
- }
- }
+/// Load all needed functions from "api-ms-win-core-synch-l1-2-0".
+pub(super) fn load_synch_functions() {
+ fn try_load() -> Option<()> {
+ const MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
+ const WAIT_ON_ADDRESS: &CStr = ansi_str!("WaitOnAddress");
+ const WAKE_BY_ADDRESS_SINGLE: &CStr = ansi_str!("WakeByAddressSingle");
+
+ // Try loading the library and all the required functions.
+ // If any step fails, then they all fail.
+ let library = unsafe { Module::new(MODULE_NAME) }?;
+ let wait_on_address = library.proc_address(WAIT_ON_ADDRESS)?;
+ let wake_by_address_single = library.proc_address(WAKE_BY_ADDRESS_SINGLE)?;
+
+ c::WaitOnAddress::PTR.store(wait_on_address.as_ptr(), Ordering::Relaxed);
+ c::WakeByAddressSingle::PTR.store(wake_by_address_single.as_ptr(), Ordering::Relaxed);
+ Some(())
+ }
- #[allow(unused)]
- pub(in crate::sys) fn preload(module: Module) {
- unsafe {
- static SYMBOL_NAME: &CStr = ansi_str!(sym $symbol);
- if let Some(f) = module.proc_address(SYMBOL_NAME) {
- PTR.store(f.as_ptr(), Ordering::Relaxed);
- }
- }
- }
- }
- )*)
+ try_load();
}
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index aed082b3e..155d0297e 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -2,8 +2,8 @@ use crate::os::windows::prelude::*;
use crate::ffi::OsString;
use crate::fmt;
-use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
-use crate::mem;
+use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
+use crate::mem::{self, MaybeUninit};
use crate::os::windows::io::{AsHandle, BorrowedHandle};
use crate::path::{Path, PathBuf};
use crate::ptr;
@@ -11,7 +11,7 @@ use crate::slice;
use crate::sync::Arc;
use crate::sys::handle::Handle;
use crate::sys::time::SystemTime;
-use crate::sys::{c, cvt};
+use crate::sys::{c, cvt, Align8};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::thread;
@@ -326,9 +326,15 @@ impl File {
cvt(c::GetFileInformationByHandle(self.handle.as_raw_handle(), &mut info))?;
let mut reparse_tag = 0;
if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
- let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- if let Ok((_, buf)) = self.reparse_point(&mut b) {
- reparse_tag = buf.ReparseTag;
+ let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
+ cvt(c::GetFileInformationByHandleEx(
+ self.handle.as_raw_handle(),
+ c::FileAttributeTagInfo,
+ ptr::addr_of_mut!(attr_tag).cast(),
+ mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
+ ))?;
+ if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+ reparse_tag = attr_tag.ReparseTag;
}
}
Ok(FileAttr {
@@ -389,9 +395,15 @@ impl File {
attr.file_size = info.AllocationSize as u64;
attr.number_of_links = Some(info.NumberOfLinks);
if attr.file_type().is_reparse_point() {
- let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- if let Ok((_, buf)) = self.reparse_point(&mut b) {
- attr.reparse_tag = buf.ReparseTag;
+ let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
+ cvt(c::GetFileInformationByHandleEx(
+ self.handle.as_raw_handle(),
+ c::FileAttributeTagInfo,
+ ptr::addr_of_mut!(attr_tag).cast(),
+ mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
+ ))?;
+ if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+ attr.reparse_tag = attr_tag.ReparseTag;
}
}
Ok(attr)
@@ -415,8 +427,8 @@ impl File {
self.handle.read_at(buf, offset)
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- self.handle.read_buf(buf)
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ self.handle.read_buf(cursor)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
@@ -458,38 +470,46 @@ impl File {
Ok(Self { handle: self.handle.try_clone()? })
}
- fn reparse_point<'a>(
+ // NB: returned pointer is derived from `space`, and has provenance to
+ // match. A raw pointer is returned rather than a reference in order to
+ // avoid narrowing provenance to the actual `REPARSE_DATA_BUFFER`.
+ fn reparse_point(
&self,
- space: &'a mut [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE],
- ) -> io::Result<(c::DWORD, &'a c::REPARSE_DATA_BUFFER)> {
+ space: &mut Align8<[MaybeUninit<u8>]>,
+ ) -> io::Result<(c::DWORD, *const c::REPARSE_DATA_BUFFER)> {
unsafe {
let mut bytes = 0;
cvt({
+ // Grab this in advance to avoid it invalidating the pointer
+ // we get from `space.0.as_mut_ptr()`.
+ let len = space.0.len();
c::DeviceIoControl(
self.handle.as_raw_handle(),
c::FSCTL_GET_REPARSE_POINT,
ptr::null_mut(),
0,
- space.as_mut_ptr() as *mut _,
- space.len() as c::DWORD,
+ space.0.as_mut_ptr().cast(),
+ len as c::DWORD,
&mut bytes,
ptr::null_mut(),
)
})?;
- Ok((bytes, &*(space.as_ptr() as *const c::REPARSE_DATA_BUFFER)))
+ const _: () = assert!(core::mem::align_of::<c::REPARSE_DATA_BUFFER>() <= 8);
+ Ok((bytes, space.0.as_ptr().cast::<c::REPARSE_DATA_BUFFER>()))
}
}
fn readlink(&self) -> io::Result<PathBuf> {
- let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ let mut space = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
let (_bytes, buf) = self.reparse_point(&mut space)?;
unsafe {
- let (path_buffer, subst_off, subst_len, relative) = match buf.ReparseTag {
+ let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag {
c::IO_REPARSE_TAG_SYMLINK => {
let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
- &buf.rest as *const _ as *const _;
+ ptr::addr_of!((*buf).rest).cast();
+ assert!(info.is_aligned());
(
- &(*info).PathBuffer as *const _ as *const u16,
+ ptr::addr_of!((*info).PathBuffer).cast::<u16>(),
(*info).SubstituteNameOffset / 2,
(*info).SubstituteNameLength / 2,
(*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0,
@@ -497,9 +517,10 @@ impl File {
}
c::IO_REPARSE_TAG_MOUNT_POINT => {
let info: *const c::MOUNT_POINT_REPARSE_BUFFER =
- &buf.rest as *const _ as *const _;
+ ptr::addr_of!((*buf).rest).cast();
+ assert!(info.is_aligned());
(
- &(*info).PathBuffer as *const _ as *const u16,
+ ptr::addr_of!((*info).PathBuffer).cast::<u16>(),
(*info).SubstituteNameOffset / 2,
(*info).SubstituteNameLength / 2,
false,
@@ -512,7 +533,7 @@ impl File {
));
}
};
- let subst_ptr = path_buffer.offset(subst_off as isize);
+ let subst_ptr = path_buffer.add(subst_off.into());
let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
// Absolute paths start with an NT internal namespace prefix `\??\`
// We should not let it leak through.
@@ -649,27 +670,31 @@ impl File {
/// A buffer for holding directory entries.
struct DirBuff {
- buffer: Vec<u8>,
+ buffer: Box<Align8<[MaybeUninit<u8>; Self::BUFFER_SIZE]>>,
}
impl DirBuff {
+ const BUFFER_SIZE: usize = 1024;
fn new() -> Self {
- const BUFFER_SIZE: usize = 1024;
- Self { buffer: vec![0_u8; BUFFER_SIZE] }
+ Self {
+ // Safety: `Align8<[MaybeUninit<u8>; N]>` does not need
+ // initialization.
+ buffer: unsafe { Box::new_uninit().assume_init() },
+ }
}
fn capacity(&self) -> usize {
- self.buffer.len()
+ self.buffer.0.len()
}
fn as_mut_ptr(&mut self) -> *mut u8 {
- self.buffer.as_mut_ptr().cast()
+ self.buffer.0.as_mut_ptr().cast()
}
/// Returns a `DirBuffIter`.
fn iter(&self) -> DirBuffIter<'_> {
DirBuffIter::new(self)
}
}
-impl AsRef<[u8]> for DirBuff {
- fn as_ref(&self) -> &[u8] {
- &self.buffer
+impl AsRef<[MaybeUninit<u8>]> for DirBuff {
+ fn as_ref(&self) -> &[MaybeUninit<u8>] {
+ &self.buffer.0
}
}
@@ -677,7 +702,7 @@ impl AsRef<[u8]> for DirBuff {
///
/// Currently only returns file names (UTF-16 encoded).
struct DirBuffIter<'a> {
- buffer: Option<&'a [u8]>,
+ buffer: Option<&'a [MaybeUninit<u8>]>,
cursor: usize,
}
impl<'a> DirBuffIter<'a> {
@@ -692,14 +717,21 @@ impl<'a> Iterator for DirBuffIter<'a> {
let buffer = &self.buffer?[self.cursor..];
// Get the name and next entry from the buffer.
- // SAFETY: The buffer contains a `FILE_ID_BOTH_DIR_INFO` struct but the
- // last field (the file name) is unsized. So an offset has to be
- // used to get the file name slice.
+ // SAFETY:
+ // - The buffer contains a `FILE_ID_BOTH_DIR_INFO` struct but the last
+ // field (the file name) is unsized. So an offset has to be used to
+ // get the file name slice.
+ // - The OS has guaranteed initialization of the fields of
+ // `FILE_ID_BOTH_DIR_INFO` and the trailing filename (for at least
+ // `FileNameLength` bytes)
let (name, is_directory, next_entry) = unsafe {
let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
+ // Guaranteed to be aligned in documentation for
+ // https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info
+ assert!(info.is_aligned());
let next_entry = (*info).NextEntryOffset as usize;
let name = crate::slice::from_raw_parts(
- (*info).FileName.as_ptr().cast::<u16>(),
+ ptr::addr_of!((*info).FileName).cast::<u16>(),
(*info).FileNameLength as usize / size_of::<u16>(),
);
let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
@@ -1337,18 +1369,19 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
let h = f.as_inner().as_raw_handle();
unsafe {
- let mut data = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- let db = data.as_mut_ptr() as *mut c::REPARSE_MOUNTPOINT_DATA_BUFFER;
- let buf = &mut (*db).ReparseTarget as *mut c::WCHAR;
+ let mut data = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
+ let data_ptr = data.0.as_mut_ptr();
+ let db = data_ptr.cast::<c::REPARSE_MOUNTPOINT_DATA_BUFFER>();
+ let buf = ptr::addr_of_mut!((*db).ReparseTarget).cast::<c::WCHAR>();
let mut i = 0;
// FIXME: this conversion is very hacky
let v = br"\??\";
let v = v.iter().map(|x| *x as u16);
for c in v.chain(original.as_os_str().encode_wide()) {
- *buf.offset(i) = c;
+ *buf.add(i) = c;
i += 1;
}
- *buf.offset(i) = 0;
+ *buf.add(i) = 0;
i += 1;
(*db).ReparseTag = c::IO_REPARSE_TAG_MOUNT_POINT;
(*db).ReparseTargetMaximumLength = (i * 2) as c::WORD;
@@ -1359,7 +1392,7 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
cvt(c::DeviceIoControl(
h as *mut _,
c::FSCTL_SET_REPARSE_POINT,
- data.as_ptr() as *mut _,
+ data_ptr.cast(),
(*db).ReparseDataLength + 8,
ptr::null_mut(),
0,
diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs
index e24b09cc9..ae33d48c6 100644
--- a/library/std/src/sys/windows/handle.rs
+++ b/library/std/src/sys/windows/handle.rs
@@ -4,7 +4,7 @@
mod tests;
use crate::cmp;
-use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read, ReadBuf};
+use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, Read};
use crate::mem;
use crate::os::windows::io::{
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
@@ -112,18 +112,16 @@ impl Handle {
}
}
- pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
- let res = unsafe {
- self.synchronous_read(buf.unfilled_mut().as_mut_ptr(), buf.remaining(), None)
- };
+ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+ let res =
+ unsafe { self.synchronous_read(cursor.as_mut().as_mut_ptr(), cursor.capacity(), None) };
match res {
Ok(read) => {
// Safety: `read` bytes were written to the initialized portion of the buffer
unsafe {
- buf.assume_init(read as usize);
+ cursor.advance(read as usize);
}
- buf.add_filled(read as usize);
Ok(())
}
diff --git a/library/std/src/sys/windows/locks/mutex.rs b/library/std/src/sys/windows/locks/mutex.rs
index f91e8f9f5..91207f5f4 100644
--- a/library/std/src/sys/windows/locks/mutex.rs
+++ b/library/std/src/sys/windows/locks/mutex.rs
@@ -37,8 +37,6 @@ impl Mutex {
pub const fn new() -> Mutex {
Mutex { srwlock: UnsafeCell::new(c::SRWLOCK_INIT) }
}
- #[inline]
- pub unsafe fn init(&mut self) {}
#[inline]
pub unsafe fn lock(&self) {
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index b3f6d2d0a..eab9b9612 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -2,6 +2,7 @@
use crate::ffi::{CStr, OsStr, OsString};
use crate::io::ErrorKind;
+use crate::mem::MaybeUninit;
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
use crate::path::PathBuf;
use crate::time::Duration;
@@ -47,7 +48,7 @@ cfg_if::cfg_if! {
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
-pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
+pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {
stack_overflow::init();
// Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
@@ -204,8 +205,8 @@ where
// This initial size also works around `GetFullPathNameW` returning
// incorrect size hints for some short paths:
// https://github.com/dylni/normpath/issues/5
- let mut stack_buf = [0u16; 512];
- let mut heap_buf = Vec::new();
+ let mut stack_buf: [MaybeUninit<u16>; 512] = MaybeUninit::uninit_array();
+ let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new();
unsafe {
let mut n = stack_buf.len();
loop {
@@ -214,6 +215,11 @@ where
} else {
let extra = n - heap_buf.len();
heap_buf.reserve(extra);
+ // We used `reserve` and not `reserve_exact`, so in theory we
+ // may have gotten more than requested. If so, we'd like to use
+ // it... so long as we won't cause overflow.
+ n = heap_buf.capacity().min(c::DWORD::MAX as usize);
+ // Safety: MaybeUninit<u16> does not need initialization
heap_buf.set_len(n);
&mut heap_buf[..]
};
@@ -228,13 +234,13 @@ where
// error" is still 0 then we interpret it as a 0 length buffer and
// not an actual error.
c::SetLastError(0);
- let k = match f1(buf.as_mut_ptr(), n as c::DWORD) {
+ let k = match f1(buf.as_mut_ptr().cast::<u16>(), n as c::DWORD) {
0 if c::GetLastError() == 0 => 0,
0 => return Err(crate::io::Error::last_os_error()),
n => n,
} as usize;
if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
- n *= 2;
+ n = n.saturating_mul(2).min(c::DWORD::MAX as usize);
} else if k > n {
n = k;
} else if k == n {
@@ -244,7 +250,9 @@ where
// Therefore k never equals n.
unreachable!();
} else {
- return Ok(f2(&buf[..k]));
+ // Safety: First `k` values are initialized.
+ let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]);
+ return Ok(f2(slice));
}
}
}
@@ -321,3 +329,11 @@ pub fn abort_internal() -> ! {
}
crate::intrinsics::abort();
}
+
+/// Align the inner value to 8 bytes.
+///
+/// This is enough for almost all of the buffers we're likely to work with in
+/// the Windows APIs we use.
+#[repr(C, align(8))]
+#[derive(Copy, Clone)]
+pub(crate) struct Align8<T: ?Sized>(pub T);
diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs
index bcac996c0..352337ba3 100644
--- a/library/std/src/sys/windows/os.rs
+++ b/library/std/src/sys/windows/os.rs
@@ -99,11 +99,11 @@ impl Iterator for Env {
}
let p = self.cur as *const u16;
let mut len = 0;
- while *p.offset(len) != 0 {
+ while *p.add(len) != 0 {
len += 1;
}
- let s = slice::from_raw_parts(p, len as usize);
- self.cur = self.cur.offset(len + 1);
+ let s = slice::from_raw_parts(p, len);
+ self.cur = self.cur.add(len + 1);
// Windows allows environment variables to start with an equals
// symbol (in any other position, this is the separator between
diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs
index 11883f150..4bdd8c505 100644
--- a/library/std/src/sys/windows/os_str.rs
+++ b/library/std/src/sys/windows/os_str.rs
@@ -164,9 +164,7 @@ impl Slice {
}
pub fn to_owned(&self) -> Buf {
- let mut buf = Wtf8Buf::with_capacity(self.inner.len());
- buf.push_wtf8(&self.inner);
- Buf { inner: buf }
+ Buf { inner: self.inner.to_owned() }
}
pub fn clone_into(&self, buf: &mut Buf) {
diff --git a/library/std/src/sys/windows/path/tests.rs b/library/std/src/sys/windows/path/tests.rs
index 6eab38cab..623c62361 100644
--- a/library/std/src/sys/windows/path/tests.rs
+++ b/library/std/src/sys/windows/path/tests.rs
@@ -105,7 +105,7 @@ fn test_parse_prefix_verbatim_device() {
assert_eq!(prefix, parse_prefix(r"\\?/C:\windows\system32\notepad.exe"));
}
-// See #93586 for more infomation.
+// See #93586 for more information.
#[test]
fn test_windows_prefix_components() {
use crate::path::Path;
diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs
index f8fd93a73..d6cd8f802 100644
--- a/library/std/src/sys/windows/rand.rs
+++ b/library/std/src/sys/windows/rand.rs
@@ -1,35 +1,126 @@
-use crate::io;
+//! # Random key generation
+//!
+//! This module wraps the RNG provided by the OS. There are a few different
+//! ways to interface with the OS RNG so it's worth exploring each of the options.
+//! Note that at the time of writing these all go through the (undocumented)
+//! `bcryptPrimitives.dll` but they use different route to get there.
+//!
+//! Originally we were using [`RtlGenRandom`], however that function is
+//! deprecated and warns it "may be altered or unavailable in subsequent versions".
+//!
+//! So we switched to [`BCryptGenRandom`] with the `BCRYPT_USE_SYSTEM_PREFERRED_RNG`
+//! flag to query and find the system configured RNG. However, this change caused a small
+//! but significant number of users to experience panics caused by a failure of
+//! this function. See [#94098].
+//!
+//! The current version changes this to use the `BCRYPT_RNG_ALG_HANDLE`
+//! [Pseudo-handle], which gets the default RNG algorithm without querying the
+//! system preference thus hopefully avoiding the previous issue.
+//! This is only supported on Windows 10+ so a fallback is used for older versions.
+//!
+//! [#94098]: https://github.com/rust-lang/rust/issues/94098
+//! [`RtlGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
+//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
+//! [Pseudo-handle]: https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-handles
use crate::mem;
use crate::ptr;
use crate::sys::c;
+/// Generates high quality secure random keys for use by [`HashMap`].
+///
+/// This is used to seed the default [`RandomState`].
+///
+/// [`HashMap`]: crate::collections::HashMap
+/// [`RandomState`]: crate::collections::hash_map::RandomState
pub fn hashmap_random_keys() -> (u64, u64) {
- let mut v = (0, 0);
- let ret = unsafe {
- c::BCryptGenRandom(
- ptr::null_mut(),
- &mut v as *mut _ as *mut u8,
- mem::size_of_val(&v) as c::ULONG,
- c::BCRYPT_USE_SYSTEM_PREFERRED_RNG,
- )
- };
- if ret != 0 { fallback_rng() } else { v }
+ Rng::open().and_then(|rng| rng.gen_random_keys()).unwrap_or_else(fallback_rng)
+}
+
+struct Rng(c::BCRYPT_ALG_HANDLE);
+impl Rng {
+ #[cfg(miri)]
+ fn open() -> Result<Self, c::NTSTATUS> {
+ const BCRYPT_RNG_ALG_HANDLE: c::BCRYPT_ALG_HANDLE = ptr::invalid_mut(0x81);
+ let _ = (
+ c::BCryptOpenAlgorithmProvider,
+ c::BCryptCloseAlgorithmProvider,
+ c::BCRYPT_RNG_ALGORITHM,
+ c::STATUS_NOT_SUPPORTED,
+ );
+ Ok(Self(BCRYPT_RNG_ALG_HANDLE))
+ }
+ #[cfg(not(miri))]
+ // Open a handle to the RNG algorithm.
+ fn open() -> Result<Self, c::NTSTATUS> {
+ use crate::sync::atomic::AtomicPtr;
+ use crate::sync::atomic::Ordering::{Acquire, Release};
+ const ERROR_VALUE: c::LPVOID = ptr::invalid_mut(usize::MAX);
+
+ // An atomic is used so we don't need to reopen the handle every time.
+ static HANDLE: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(ptr::null_mut());
+
+ let mut handle = HANDLE.load(Acquire);
+ // We use a sentinel value to designate an error occurred last time.
+ if handle == ERROR_VALUE {
+ Err(c::STATUS_NOT_SUPPORTED)
+ } else if handle.is_null() {
+ let status = unsafe {
+ c::BCryptOpenAlgorithmProvider(
+ &mut handle,
+ c::BCRYPT_RNG_ALGORITHM.as_ptr(),
+ ptr::null(),
+ 0,
+ )
+ };
+ if c::nt_success(status) {
+ // If another thread opens a handle first then use that handle instead.
+ let result = HANDLE.compare_exchange(ptr::null_mut(), handle, Release, Acquire);
+ if let Err(previous_handle) = result {
+ // Close our handle and return the previous one.
+ unsafe { c::BCryptCloseAlgorithmProvider(handle, 0) };
+ handle = previous_handle;
+ }
+ Ok(Self(handle))
+ } else {
+ HANDLE.store(ERROR_VALUE, Release);
+ Err(status)
+ }
+ } else {
+ Ok(Self(handle))
+ }
+ }
+
+ fn gen_random_keys(self) -> Result<(u64, u64), c::NTSTATUS> {
+ let mut v = (0, 0);
+ let status = unsafe {
+ let size = mem::size_of_val(&v).try_into().unwrap();
+ c::BCryptGenRandom(self.0, ptr::addr_of_mut!(v).cast(), size, 0)
+ };
+ if c::nt_success(status) { Ok(v) } else { Err(status) }
+ }
}
/// Generate random numbers using the fallback RNG function (RtlGenRandom)
#[cfg(not(target_vendor = "uwp"))]
#[inline(never)]
-fn fallback_rng() -> (u64, u64) {
+fn fallback_rng(rng_status: c::NTSTATUS) -> (u64, u64) {
let mut v = (0, 0);
let ret =
unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) };
- if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
+ if ret != 0 {
+ v
+ } else {
+ panic!(
+ "RNG broken: {rng_status:#x}, fallback RNG broken: {}",
+ crate::io::Error::last_os_error()
+ )
+ }
}
/// We can't use RtlGenRandom with UWP, so there is no fallback
#[cfg(target_vendor = "uwp")]
#[inline(never)]
-fn fallback_rng() -> (u64, u64) {
- panic!("fallback RNG broken: RtlGenRandom() not supported on UWP");
+fn fallback_rng(rng_status: c::NTSTATUS) -> (u64, u64) {
+ panic!("RNG broken: {rng_status:#x} fallback RNG broken: RtlGenRandom() not supported on UWP");
}
diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs
index a001d6b98..70c9b14a0 100644
--- a/library/std/src/sys/windows/stdio.rs
+++ b/library/std/src/sys/windows/stdio.rs
@@ -3,6 +3,7 @@
use crate::char::decode_utf16;
use crate::cmp;
use crate::io;
+use crate::mem::MaybeUninit;
use crate::os::windows::io::{FromRawHandle, IntoRawHandle};
use crate::ptr;
use crate::str;
@@ -169,13 +170,14 @@ fn write(
}
fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usize> {
- let mut utf16 = [0u16; MAX_BUFFER_SIZE / 2];
+ let mut utf16 = [MaybeUninit::<u16>::uninit(); MAX_BUFFER_SIZE / 2];
let mut len_utf16 = 0;
for (chr, dest) in utf8.encode_utf16().zip(utf16.iter_mut()) {
- *dest = chr;
+ *dest = MaybeUninit::new(chr);
len_utf16 += 1;
}
- let utf16 = &utf16[..len_utf16];
+ // Safety: We've initialized `len_utf16` values.
+ let utf16: &[u16] = unsafe { MaybeUninit::slice_assume_init_ref(&utf16[..len_utf16]) };
let mut written = write_u16s(handle, &utf16)?;
@@ -250,11 +252,14 @@ impl io::Read for Stdin {
return Ok(bytes_copied);
} else if buf.len() - bytes_copied < 4 {
// Not enough space to get a UTF-8 byte. We will use the incomplete UTF8.
- let mut utf16_buf = [0u16; 1];
+ let mut utf16_buf = [MaybeUninit::new(0); 1];
// Read one u16 character.
let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, 1, &mut self.surrogate)?;
// Read bytes, using the (now-empty) self.incomplete_utf8 as extra space.
- let read_bytes = utf16_to_utf8(&utf16_buf[..read], &mut self.incomplete_utf8.bytes)?;
+ let read_bytes = utf16_to_utf8(
+ unsafe { MaybeUninit::slice_assume_init_ref(&utf16_buf[..read]) },
+ &mut self.incomplete_utf8.bytes,
+ )?;
// Read in the bytes from incomplete_utf8 until the buffer is full.
self.incomplete_utf8.len = read_bytes as u8;
@@ -262,15 +267,18 @@ impl io::Read for Stdin {
bytes_copied += self.incomplete_utf8.read(&mut buf[bytes_copied..]);
Ok(bytes_copied)
} else {
- let mut utf16_buf = [0u16; MAX_BUFFER_SIZE / 2];
+ let mut utf16_buf = [MaybeUninit::<u16>::uninit(); MAX_BUFFER_SIZE / 2];
+
// In the worst case, a UTF-8 string can take 3 bytes for every `u16` of a UTF-16. So
// we can read at most a third of `buf.len()` chars and uphold the guarantee no data gets
// lost.
let amount = cmp::min(buf.len() / 3, utf16_buf.len());
let read =
read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?;
-
- match utf16_to_utf8(&utf16_buf[..read], buf) {
+ // Safety `read_u16s_fixup_surrogates` returns the number of items
+ // initialized.
+ let utf16s = unsafe { MaybeUninit::slice_assume_init_ref(&utf16_buf[..read]) };
+ match utf16_to_utf8(utf16s, buf) {
Ok(value) => return Ok(bytes_copied + value),
Err(e) => return Err(e),
}
@@ -283,14 +291,14 @@ impl io::Read for Stdin {
// This is a best effort, and might not work if we are not the only reader on Stdin.
fn read_u16s_fixup_surrogates(
handle: c::HANDLE,
- buf: &mut [u16],
+ buf: &mut [MaybeUninit<u16>],
mut amount: usize,
surrogate: &mut u16,
) -> io::Result<usize> {
// Insert possibly remaining unpaired surrogate from last read.
let mut start = 0;
if *surrogate != 0 {
- buf[0] = *surrogate;
+ buf[0] = MaybeUninit::new(*surrogate);
*surrogate = 0;
start = 1;
if amount == 1 {
@@ -303,7 +311,10 @@ fn read_u16s_fixup_surrogates(
let mut amount = read_u16s(handle, &mut buf[start..amount])? + start;
if amount > 0 {
- let last_char = buf[amount - 1];
+ // Safety: The returned `amount` is the number of values initialized,
+ // and it is not 0, so we know that `buf[amount - 1]` have been
+ // initialized.
+ let last_char = unsafe { buf[amount - 1].assume_init() };
if last_char >= 0xD800 && last_char <= 0xDBFF {
// high surrogate
*surrogate = last_char;
@@ -313,7 +324,8 @@ fn read_u16s_fixup_surrogates(
Ok(amount)
}
-fn read_u16s(handle: c::HANDLE, buf: &mut [u16]) -> io::Result<usize> {
+// Returns `Ok(n)` if it initialized `n` values in `buf`.
+fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usize> {
// Configure the `pInputControl` parameter to not only return on `\r\n` but also Ctrl-Z, the
// traditional DOS method to indicate end of character stream / user input (SUB).
// See #38274 and https://stackoverflow.com/questions/43836040/win-api-readconsole.
@@ -346,8 +358,9 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [u16]) -> io::Result<usize> {
}
break;
}
-
- if amount > 0 && buf[amount as usize - 1] == CTRL_Z {
+ // Safety: if `amount > 0`, then that many bytes were written, so
+ // `buf[amount as usize - 1]` has been initialized.
+ if amount > 0 && unsafe { buf[amount as usize - 1].assume_init() } == CTRL_Z {
amount -= 1;
}
Ok(amount as usize)
diff --git a/library/std/src/sys/windows/thread_local_dtor.rs b/library/std/src/sys/windows/thread_local_dtor.rs
index 25d1c6e8e..9707a95df 100644
--- a/library/std/src/sys/windows/thread_local_dtor.rs
+++ b/library/std/src/sys/windows/thread_local_dtor.rs
@@ -8,10 +8,14 @@
#[thread_local]
static mut DESTRUCTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new();
+// Ensure this can never be inlined because otherwise this may break in dylibs.
+// See #44391.
+#[inline(never)]
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
DESTRUCTORS.push((t, dtor));
}
+#[inline(never)] // See comment above
/// Runs destructors. This should not be called until thread exit.
pub unsafe fn run_keyless_dtors() {
// Drop all the destructors.
diff --git a/library/std/src/sys/windows/thread_parker.rs b/library/std/src/sys/windows/thread_parker.rs
index d876e0f6f..2f7ae863b 100644
--- a/library/std/src/sys/windows/thread_parker.rs
+++ b/library/std/src/sys/windows/thread_parker.rs
@@ -197,19 +197,17 @@ impl Parker {
// purpose, to make sure every unpark() has a release-acquire ordering
// with park().
if self.state.swap(NOTIFIED, Release) == PARKED {
- if let Some(wake_by_address_single) = c::WakeByAddressSingle::option() {
- unsafe {
+ unsafe {
+ if let Some(wake_by_address_single) = c::WakeByAddressSingle::option() {
wake_by_address_single(self.ptr());
- }
- } else {
- // If we run NtReleaseKeyedEvent before the waiting thread runs
- // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
- // If the waiting thread wakes up before we run NtReleaseKeyedEvent
- // (e.g. due to a timeout), this blocks until we do wake up a thread.
- // To prevent this thread from blocking indefinitely in that case,
- // park_impl() will, after seeing the state set to NOTIFIED after
- // waking up, call NtWaitForKeyedEvent again to unblock us.
- unsafe {
+ } else {
+ // If we run NtReleaseKeyedEvent before the waiting thread runs
+ // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
+ // If the waiting thread wakes up before we run NtReleaseKeyedEvent
+ // (e.g. due to a timeout), this blocks until we do wake up a thread.
+ // To prevent this thread from blocking indefinitely in that case,
+ // park_impl() will, after seeing the state set to NOTIFIED after
+ // waking up, call NtWaitForKeyedEvent again to unblock us.
c::NtReleaseKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
}
}
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 33d336c43..3ad802afa 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -10,7 +10,7 @@ use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use crate::ptr;
use crate::sys::net::netc as c;
use crate::sys::net::{cvt, cvt_gai, cvt_r, init, wrlen_t, Socket};
-use crate::sys_common::{FromInner, IntoInner};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::Duration;
use libc::{c_int, c_void};
@@ -345,6 +345,12 @@ impl TcpStream {
}
}
+impl AsInner<Socket> for TcpStream {
+ fn as_inner(&self) -> &Socket {
+ &self.inner
+ }
+}
+
impl FromInner<Socket> for TcpStream {
fn from_inner(socket: Socket) -> TcpStream {
TcpStream { inner: socket }
diff --git a/library/std/src/sys_common/remutex.rs b/library/std/src/sys_common/remutex.rs
index 8921af311..b448ae3a9 100644
--- a/library/std/src/sys_common/remutex.rs
+++ b/library/std/src/sys_common/remutex.rs
@@ -1,13 +1,11 @@
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;
+use super::mutex as sys;
use crate::cell::UnsafeCell;
-use crate::marker::PhantomPinned;
use crate::ops::Deref;
use crate::panic::{RefUnwindSafe, UnwindSafe};
-use crate::pin::Pin;
use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
-use crate::sys::locks as sys;
/// A re-entrant mutual exclusion
///
@@ -41,11 +39,10 @@ use crate::sys::locks as sys;
/// synchronization is left to the mutex, making relaxed memory ordering for
/// the `owner` field fine in all cases.
pub struct ReentrantMutex<T> {
- mutex: sys::Mutex,
+ mutex: sys::MovableMutex,
owner: AtomicUsize,
lock_count: UnsafeCell<u32>,
data: T,
- _pinned: PhantomPinned,
}
unsafe impl<T: Send> Send for ReentrantMutex<T> {}
@@ -68,39 +65,22 @@ impl<T> RefUnwindSafe for ReentrantMutex<T> {}
/// guarded data.
#[must_use = "if unused the ReentrantMutex will immediately unlock"]
pub struct ReentrantMutexGuard<'a, T: 'a> {
- lock: Pin<&'a ReentrantMutex<T>>,
+ lock: &'a ReentrantMutex<T>,
}
impl<T> !Send for ReentrantMutexGuard<'_, T> {}
impl<T> ReentrantMutex<T> {
/// Creates a new reentrant mutex in an unlocked state.
- ///
- /// # Unsafety
- ///
- /// This function is unsafe because it is required that `init` is called
- /// once this mutex is in its final resting place, and only then are the
- /// lock/unlock methods safe.
- pub const unsafe fn new(t: T) -> ReentrantMutex<T> {
+ pub const fn new(t: T) -> ReentrantMutex<T> {
ReentrantMutex {
- mutex: sys::Mutex::new(),
+ mutex: sys::MovableMutex::new(),
owner: AtomicUsize::new(0),
lock_count: UnsafeCell::new(0),
data: t,
- _pinned: PhantomPinned,
}
}
- /// Initializes this mutex so it's ready for use.
- ///
- /// # Unsafety
- ///
- /// Unsafe to call more than once, and must be called after this will no
- /// longer move in memory.
- pub unsafe fn init(self: Pin<&mut Self>) {
- self.get_unchecked_mut().mutex.init()
- }
-
/// Acquires a mutex, blocking the current thread until it is able to do so.
///
/// This function will block the caller until it is available to acquire the mutex.
@@ -113,15 +93,14 @@ impl<T> ReentrantMutex<T> {
/// If another user of this mutex panicked while holding the mutex, then
/// this call will return failure if the mutex would otherwise be
/// acquired.
- pub fn lock(self: Pin<&Self>) -> ReentrantMutexGuard<'_, T> {
+ pub fn lock(&self) -> ReentrantMutexGuard<'_, T> {
let this_thread = current_thread_unique_ptr();
- // Safety: We only touch lock_count when we own the lock,
- // and since self is pinned we can safely call the lock() on the mutex.
+ // Safety: We only touch lock_count when we own the lock.
unsafe {
if self.owner.load(Relaxed) == this_thread {
self.increment_lock_count();
} else {
- self.mutex.lock();
+ self.mutex.raw_lock();
self.owner.store(this_thread, Relaxed);
debug_assert_eq!(*self.lock_count.get(), 0);
*self.lock_count.get() = 1;
@@ -142,10 +121,9 @@ impl<T> ReentrantMutex<T> {
/// If another user of this mutex panicked while holding the mutex, then
/// this call will return failure if the mutex would otherwise be
/// acquired.
- pub fn try_lock(self: Pin<&Self>) -> Option<ReentrantMutexGuard<'_, T>> {
+ pub fn try_lock(&self) -> Option<ReentrantMutexGuard<'_, T>> {
let this_thread = current_thread_unique_ptr();
- // Safety: We only touch lock_count when we own the lock,
- // and since self is pinned we can safely call the try_lock on the mutex.
+ // Safety: We only touch lock_count when we own the lock.
unsafe {
if self.owner.load(Relaxed) == this_thread {
self.increment_lock_count();
@@ -179,12 +157,12 @@ impl<T> Deref for ReentrantMutexGuard<'_, T> {
impl<T> Drop for ReentrantMutexGuard<'_, T> {
#[inline]
fn drop(&mut self) {
- // Safety: We own the lock, and the lock is pinned.
+ // Safety: We own the lock.
unsafe {
*self.lock.lock_count.get() -= 1;
if *self.lock.lock_count.get() == 0 {
self.lock.owner.store(0, Relaxed);
- self.lock.mutex.unlock();
+ self.lock.mutex.raw_unlock();
}
}
}
diff --git a/library/std/src/sys_common/remutex/tests.rs b/library/std/src/sys_common/remutex/tests.rs
index 64873b850..8e97ce11c 100644
--- a/library/std/src/sys_common/remutex/tests.rs
+++ b/library/std/src/sys_common/remutex/tests.rs
@@ -1,18 +1,11 @@
-use crate::boxed::Box;
use crate::cell::RefCell;
-use crate::pin::Pin;
use crate::sync::Arc;
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
use crate::thread;
#[test]
fn smoke() {
- let m = unsafe {
- let mut m = Box::pin(ReentrantMutex::new(()));
- m.as_mut().init();
- m
- };
- let m = m.as_ref();
+ let m = ReentrantMutex::new(());
{
let a = m.lock();
{
@@ -29,20 +22,15 @@ fn smoke() {
#[test]
fn is_mutex() {
- let m = unsafe {
- // FIXME: Simplify this if Arc gets an Arc::get_pin_mut.
- let mut m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
- Pin::new_unchecked(Arc::get_mut_unchecked(&mut m)).init();
- Pin::new_unchecked(m)
- };
+ let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
let m2 = m.clone();
- let lock = m.as_ref().lock();
+ let lock = m.lock();
let child = thread::spawn(move || {
- let lock = m2.as_ref().lock();
+ let lock = m2.lock();
assert_eq!(*lock.borrow(), 4950);
});
for i in 0..100 {
- let lock = m.as_ref().lock();
+ let lock = m.lock();
*lock.borrow_mut() += i;
}
drop(lock);
@@ -51,22 +39,17 @@ fn is_mutex() {
#[test]
fn trylock_works() {
- let m = unsafe {
- // FIXME: Simplify this if Arc gets an Arc::get_pin_mut.
- let mut m = Arc::new(ReentrantMutex::new(()));
- Pin::new_unchecked(Arc::get_mut_unchecked(&mut m)).init();
- Pin::new_unchecked(m)
- };
+ let m = Arc::new(ReentrantMutex::new(()));
let m2 = m.clone();
- let _lock = m.as_ref().try_lock();
- let _lock2 = m.as_ref().try_lock();
+ let _lock = m.try_lock();
+ let _lock2 = m.try_lock();
thread::spawn(move || {
- let lock = m2.as_ref().try_lock();
+ let lock = m2.try_lock();
assert!(lock.is_none());
})
.join()
.unwrap();
- let _lock3 = m.as_ref().try_lock();
+ let _lock3 = m.try_lock();
}
pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
diff --git a/library/std/src/sys_common/thread_local_key.rs b/library/std/src/sys_common/thread_local_key.rs
index 70beebe86..032bf604d 100644
--- a/library/std/src/sys_common/thread_local_key.rs
+++ b/library/std/src/sys_common/thread_local_key.rs
@@ -69,8 +69,10 @@ use crate::sys_common::mutex::StaticMutex;
/// ```ignore (cannot-doctest-private-modules)
/// use tls::os::{StaticKey, INIT};
///
+/// // Use a regular global static to store the key.
/// static KEY: StaticKey = INIT;
///
+/// // The state provided via `get` and `set` is thread-local.
/// unsafe {
/// assert!(KEY.get().is_null());
/// KEY.set(1 as *mut u8);
diff --git a/library/std/src/sys_common/thread_local_key/tests.rs b/library/std/src/sys_common/thread_local_key/tests.rs
index 968738a41..6f32b858f 100644
--- a/library/std/src/sys_common/thread_local_key/tests.rs
+++ b/library/std/src/sys_common/thread_local_key/tests.rs
@@ -1,4 +1,5 @@
use super::{Key, StaticKey};
+use core::ptr;
fn assert_sync<T: Sync>() {}
fn assert_send<T: Send>() {}
@@ -12,8 +13,8 @@ fn smoke() {
let k2 = Key::new(None);
assert!(k1.get().is_null());
assert!(k2.get().is_null());
- k1.set(1 as *mut _);
- k2.set(2 as *mut _);
+ k1.set(ptr::invalid_mut(1));
+ k2.set(ptr::invalid_mut(2));
assert_eq!(k1.get() as usize, 1);
assert_eq!(k2.get() as usize, 2);
}
@@ -26,8 +27,8 @@ fn statik() {
unsafe {
assert!(K1.get().is_null());
assert!(K2.get().is_null());
- K1.set(1 as *mut _);
- K2.set(2 as *mut _);
+ K1.set(ptr::invalid_mut(1));
+ K2.set(ptr::invalid_mut(2));
assert_eq!(K1.get() as usize, 1);
assert_eq!(K2.get() as usize, 2);
}
diff --git a/library/std/src/sys_common/thread_parker/mod.rs b/library/std/src/sys_common/thread_parker/mod.rs
index cbd7832eb..f86a9a555 100644
--- a/library/std/src/sys_common/thread_parker/mod.rs
+++ b/library/std/src/sys_common/thread_parker/mod.rs
@@ -7,6 +7,7 @@ cfg_if::cfg_if! {
target_os = "openbsd",
target_os = "dragonfly",
target_os = "fuchsia",
+ target_os = "hermit",
))] {
mod futex;
pub use futex::Parker;
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 57fa49893..dd53767d4 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -89,6 +89,24 @@ impl CodePoint {
self.value
}
+ /// Returns the numeric value of the code point if it is a leading surrogate.
+ #[inline]
+ pub fn to_lead_surrogate(&self) -> Option<u16> {
+ match self.value {
+ lead @ 0xD800..=0xDBFF => Some(lead as u16),
+ _ => None,
+ }
+ }
+
+ /// Returns the numeric value of the code point if it is a trailing surrogate.
+ #[inline]
+ pub fn to_trail_surrogate(&self) -> Option<u16> {
+ match self.value {
+ trail @ 0xDC00..=0xDFFF => Some(trail as u16),
+ _ => None,
+ }
+ }
+
/// Optionally returns a Unicode scalar value for the code point.
///
/// Returns `None` if the code point is a surrogate (from U+D800 to U+DFFF).
@@ -117,6 +135,14 @@ impl CodePoint {
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct Wtf8Buf {
bytes: Vec<u8>,
+
+ /// Do we know that `bytes` holds a valid UTF-8 encoding? We can easily
+ /// know this if we're constructed from a `String` or `&str`.
+ ///
+ /// It is possible for `bytes` to have valid UTF-8 without this being
+ /// set, such as when we're concatenating `&Wtf8`'s and surrogates become
+ /// paired, as we don't bother to rescan the entire string.
+ is_known_utf8: bool,
}
impl ops::Deref for Wtf8Buf {
@@ -147,13 +173,13 @@ impl Wtf8Buf {
/// Creates a new, empty WTF-8 string.
#[inline]
pub fn new() -> Wtf8Buf {
- Wtf8Buf { bytes: Vec::new() }
+ Wtf8Buf { bytes: Vec::new(), is_known_utf8: true }
}
/// Creates a new, empty WTF-8 string with pre-allocated capacity for `capacity` bytes.
#[inline]
pub fn with_capacity(capacity: usize) -> Wtf8Buf {
- Wtf8Buf { bytes: Vec::with_capacity(capacity) }
+ Wtf8Buf { bytes: Vec::with_capacity(capacity), is_known_utf8: true }
}
/// Creates a WTF-8 string from a UTF-8 `String`.
@@ -163,7 +189,7 @@ impl Wtf8Buf {
/// Since WTF-8 is a superset of UTF-8, this always succeeds.
#[inline]
pub fn from_string(string: String) -> Wtf8Buf {
- Wtf8Buf { bytes: string.into_bytes() }
+ Wtf8Buf { bytes: string.into_bytes(), is_known_utf8: true }
}
/// Creates a WTF-8 string from a UTF-8 `&str` slice.
@@ -173,11 +199,12 @@ impl Wtf8Buf {
/// Since WTF-8 is a superset of UTF-8, this always succeeds.
#[inline]
pub fn from_str(str: &str) -> Wtf8Buf {
- Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()) }
+ Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()), is_known_utf8: true }
}
pub fn clear(&mut self) {
- self.bytes.clear()
+ self.bytes.clear();
+ self.is_known_utf8 = true;
}
/// Creates a WTF-8 string from a potentially ill-formed UTF-16 slice of 16-bit code units.
@@ -193,9 +220,11 @@ impl Wtf8Buf {
let surrogate = surrogate.unpaired_surrogate();
// Surrogates are known to be in the code point range.
let code_point = unsafe { CodePoint::from_u32_unchecked(surrogate as u32) };
+ // The string will now contain an unpaired surrogate.
+ string.is_known_utf8 = false;
// Skip the WTF-8 concatenation check,
// surrogate pairs are already decoded by decode_utf16
- string.push_code_point_unchecked(code_point)
+ string.push_code_point_unchecked(code_point);
}
}
}
@@ -203,7 +232,7 @@ impl Wtf8Buf {
}
/// Copied from String::push
- /// This does **not** include the WTF-8 concatenation check.
+ /// This does **not** include the WTF-8 concatenation check or `is_known_utf8` check.
fn push_code_point_unchecked(&mut self, code_point: CodePoint) {
let mut bytes = [0; 4];
let bytes = char::encode_utf8_raw(code_point.value, &mut bytes);
@@ -217,6 +246,9 @@ impl Wtf8Buf {
#[inline]
pub fn as_mut_slice(&mut self) -> &mut Wtf8 {
+ // Safety: `Wtf8` doesn't expose any way to mutate the bytes that would
+ // cause them to change from well-formed UTF-8 to ill-formed UTF-8,
+ // which would break the assumptions of the `is_known_utf8` field.
unsafe { Wtf8::from_mut_bytes_unchecked(&mut self.bytes) }
}
@@ -236,7 +268,8 @@ impl Wtf8Buf {
/// in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to avoid
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional`. Does nothing if
- /// capacity is already sufficient.
+ /// capacity is already sufficient. This method preserves the contents even
+ /// if an error occurs.
///
/// # Errors
///
@@ -313,7 +346,15 @@ impl Wtf8Buf {
self.push_char(decode_surrogate_pair(lead, trail));
self.bytes.extend_from_slice(other_without_trail_surrogate);
}
- _ => self.bytes.extend_from_slice(&other.bytes),
+ _ => {
+ // If we'll be pushing a string containing a surrogate, we may
+ // no longer have UTF-8.
+ if other.next_surrogate(0).is_some() {
+ self.is_known_utf8 = false;
+ }
+
+ self.bytes.extend_from_slice(&other.bytes);
+ }
}
}
@@ -330,13 +371,19 @@ impl Wtf8Buf {
/// like concatenating ill-formed UTF-16 strings effectively would.
#[inline]
pub fn push(&mut self, code_point: CodePoint) {
- if let trail @ 0xDC00..=0xDFFF = code_point.to_u32() {
+ if let Some(trail) = code_point.to_trail_surrogate() {
if let Some(lead) = (&*self).final_lead_surrogate() {
let len_without_lead_surrogate = self.len() - 3;
self.bytes.truncate(len_without_lead_surrogate);
- self.push_char(decode_surrogate_pair(lead, trail as u16));
+ self.push_char(decode_surrogate_pair(lead, trail));
return;
}
+
+ // We're pushing a trailing surrogate.
+ self.is_known_utf8 = false;
+ } else if code_point.to_lead_surrogate().is_some() {
+ // We're pushing a leading surrogate.
+ self.is_known_utf8 = false;
}
// No newly paired surrogates at the boundary.
@@ -363,9 +410,10 @@ impl Wtf8Buf {
/// (that is, if the string contains surrogates),
/// the original WTF-8 string is returned instead.
pub fn into_string(self) -> Result<String, Wtf8Buf> {
- match self.next_surrogate(0) {
- None => Ok(unsafe { String::from_utf8_unchecked(self.bytes) }),
- Some(_) => Err(self),
+ if self.is_known_utf8 || self.next_surrogate(0).is_none() {
+ Ok(unsafe { String::from_utf8_unchecked(self.bytes) })
+ } else {
+ Err(self)
}
}
@@ -375,6 +423,11 @@ impl Wtf8Buf {
///
/// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�â€)
pub fn into_string_lossy(mut self) -> String {
+ // Fast path: If we already have UTF-8, we can return it immediately.
+ if self.is_known_utf8 {
+ return unsafe { String::from_utf8_unchecked(self.bytes) };
+ }
+
let mut pos = 0;
loop {
match self.next_surrogate(pos) {
@@ -397,7 +450,7 @@ impl Wtf8Buf {
/// Converts a `Box<Wtf8>` into a `Wtf8Buf`.
pub fn from_box(boxed: Box<Wtf8>) -> Wtf8Buf {
let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
- Wtf8Buf { bytes: bytes.into_vec() }
+ Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false }
}
}
@@ -575,6 +628,11 @@ impl Wtf8 {
}
}
+ /// Creates an owned `Wtf8Buf` from a borrowed `Wtf8`.
+ pub fn to_owned(&self) -> Wtf8Buf {
+ Wtf8Buf { bytes: self.bytes.to_vec(), is_known_utf8: false }
+ }
+
/// Lossily converts the string to UTF-8.
/// Returns a UTF-8 `&str` slice if the contents are well-formed in UTF-8.
///
@@ -664,7 +722,8 @@ impl Wtf8 {
}
pub fn clone_into(&self, buf: &mut Wtf8Buf) {
- self.bytes.clone_into(&mut buf.bytes)
+ buf.is_known_utf8 = false;
+ self.bytes.clone_into(&mut buf.bytes);
}
/// Boxes this `Wtf8`.
@@ -704,12 +763,12 @@ impl Wtf8 {
#[inline]
pub fn to_ascii_lowercase(&self) -> Wtf8Buf {
- Wtf8Buf { bytes: self.bytes.to_ascii_lowercase() }
+ Wtf8Buf { bytes: self.bytes.to_ascii_lowercase(), is_known_utf8: false }
}
#[inline]
pub fn to_ascii_uppercase(&self) -> Wtf8Buf {
- Wtf8Buf { bytes: self.bytes.to_ascii_uppercase() }
+ Wtf8Buf { bytes: self.bytes.to_ascii_uppercase(), is_known_utf8: false }
}
#[inline]
diff --git a/library/std/src/sys_common/wtf8/tests.rs b/library/std/src/sys_common/wtf8/tests.rs
index 931996791..1a302d646 100644
--- a/library/std/src/sys_common/wtf8/tests.rs
+++ b/library/std/src/sys_common/wtf8/tests.rs
@@ -20,6 +20,36 @@ fn code_point_to_u32() {
}
#[test]
+fn code_point_to_lead_surrogate() {
+ fn c(value: u32) -> CodePoint {
+ CodePoint::from_u32(value).unwrap()
+ }
+ assert_eq!(c(0).to_lead_surrogate(), None);
+ assert_eq!(c(0xE9).to_lead_surrogate(), None);
+ assert_eq!(c(0xD800).to_lead_surrogate(), Some(0xD800));
+ assert_eq!(c(0xDBFF).to_lead_surrogate(), Some(0xDBFF));
+ assert_eq!(c(0xDC00).to_lead_surrogate(), None);
+ assert_eq!(c(0xDFFF).to_lead_surrogate(), None);
+ assert_eq!(c(0x1F4A9).to_lead_surrogate(), None);
+ assert_eq!(c(0x10FFFF).to_lead_surrogate(), None);
+}
+
+#[test]
+fn code_point_to_trail_surrogate() {
+ fn c(value: u32) -> CodePoint {
+ CodePoint::from_u32(value).unwrap()
+ }
+ assert_eq!(c(0).to_trail_surrogate(), None);
+ assert_eq!(c(0xE9).to_trail_surrogate(), None);
+ assert_eq!(c(0xD800).to_trail_surrogate(), None);
+ assert_eq!(c(0xDBFF).to_trail_surrogate(), None);
+ assert_eq!(c(0xDC00).to_trail_surrogate(), Some(0xDC00));
+ assert_eq!(c(0xDFFF).to_trail_surrogate(), Some(0xDFFF));
+ assert_eq!(c(0x1F4A9).to_trail_surrogate(), None);
+ assert_eq!(c(0x10FFFF).to_trail_surrogate(), None);
+}
+
+#[test]
fn code_point_from_char() {
assert_eq!(CodePoint::from_char('a').to_u32(), 0x61);
assert_eq!(CodePoint::from_char('💩').to_u32(), 0x1F4A9);
@@ -70,35 +100,66 @@ fn wtf8buf_from_string() {
#[test]
fn wtf8buf_from_wide() {
- assert_eq!(Wtf8Buf::from_wide(&[]).bytes, b"");
- assert_eq!(
- Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]).bytes,
- b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9"
- );
+ let buf = Wtf8Buf::from_wide(&[]);
+ assert_eq!(buf.bytes, b"");
+ assert!(buf.is_known_utf8);
+
+ let buf = Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xDCA9]);
+ assert_eq!(buf.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert!(buf.is_known_utf8);
+
+ let buf = Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]);
+ assert_eq!(buf.bytes, b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9");
+ assert!(!buf.is_known_utf8);
+
+ let buf = Wtf8Buf::from_wide(&[0xD800]);
+ assert_eq!(buf.bytes, b"\xED\xA0\x80");
+ assert!(!buf.is_known_utf8);
+
+ let buf = Wtf8Buf::from_wide(&[0xDBFF]);
+ assert_eq!(buf.bytes, b"\xED\xAF\xBF");
+ assert!(!buf.is_known_utf8);
+
+ let buf = Wtf8Buf::from_wide(&[0xDC00]);
+ assert_eq!(buf.bytes, b"\xED\xB0\x80");
+ assert!(!buf.is_known_utf8);
+
+ let buf = Wtf8Buf::from_wide(&[0xDFFF]);
+ assert_eq!(buf.bytes, b"\xED\xBF\xBF");
+ assert!(!buf.is_known_utf8);
}
#[test]
fn wtf8buf_push_str() {
let mut string = Wtf8Buf::new();
assert_eq!(string.bytes, b"");
+ assert!(string.is_known_utf8);
+
string.push_str("aé 💩");
assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert!(string.is_known_utf8);
}
#[test]
fn wtf8buf_push_char() {
let mut string = Wtf8Buf::from_str("aé ");
assert_eq!(string.bytes, b"a\xC3\xA9 ");
+ assert!(string.is_known_utf8);
+
string.push_char('💩');
assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert!(string.is_known_utf8);
}
#[test]
fn wtf8buf_push() {
let mut string = Wtf8Buf::from_str("aé ");
assert_eq!(string.bytes, b"a\xC3\xA9 ");
+ assert!(string.is_known_utf8);
+
string.push(CodePoint::from_char('💩'));
assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert!(string.is_known_utf8);
fn c(value: u32) -> CodePoint {
CodePoint::from_u32(value).unwrap()
@@ -106,37 +167,46 @@ fn wtf8buf_push() {
let mut string = Wtf8Buf::new();
string.push(c(0xD83D)); // lead
+ assert!(!string.is_known_utf8);
string.push(c(0xDCA9)); // trail
assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic!
let mut string = Wtf8Buf::new();
string.push(c(0xD83D)); // lead
+ assert!(!string.is_known_utf8);
string.push(c(0x20)); // not surrogate
string.push(c(0xDCA9)); // trail
assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
let mut string = Wtf8Buf::new();
string.push(c(0xD800)); // lead
+ assert!(!string.is_known_utf8);
string.push(c(0xDBFF)); // lead
assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF");
let mut string = Wtf8Buf::new();
string.push(c(0xD800)); // lead
+ assert!(!string.is_known_utf8);
string.push(c(0xE000)); // not surrogate
assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80");
let mut string = Wtf8Buf::new();
string.push(c(0xD7FF)); // not surrogate
+ assert!(string.is_known_utf8);
string.push(c(0xDC00)); // trail
+ assert!(!string.is_known_utf8);
assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80");
let mut string = Wtf8Buf::new();
string.push(c(0x61)); // not surrogate, < 3 bytes
+ assert!(string.is_known_utf8);
string.push(c(0xDC00)); // trail
+ assert!(!string.is_known_utf8);
assert_eq!(string.bytes, b"\x61\xED\xB0\x80");
let mut string = Wtf8Buf::new();
string.push(c(0xDC00)); // trail
+ assert!(!string.is_known_utf8);
assert_eq!(string.bytes, b"\xED\xB0\x80");
}
@@ -146,6 +216,7 @@ fn wtf8buf_push_wtf8() {
assert_eq!(string.bytes, b"a\xC3\xA9");
string.push_wtf8(Wtf8::from_str(" 💩"));
assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert!(string.is_known_utf8);
fn w(v: &[u8]) -> &Wtf8 {
unsafe { Wtf8::from_bytes_unchecked(v) }
@@ -161,37 +232,68 @@ fn wtf8buf_push_wtf8() {
string.push_wtf8(w(b" ")); // not surrogate
string.push_wtf8(w(b"\xED\xB2\xA9")); // trail
assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
+ assert!(!string.is_known_utf8);
let mut string = Wtf8Buf::new();
string.push_wtf8(w(b"\xED\xA0\x80")); // lead
string.push_wtf8(w(b"\xED\xAF\xBF")); // lead
assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF");
+ assert!(!string.is_known_utf8);
let mut string = Wtf8Buf::new();
string.push_wtf8(w(b"\xED\xA0\x80")); // lead
string.push_wtf8(w(b"\xEE\x80\x80")); // not surrogate
assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80");
+ assert!(!string.is_known_utf8);
let mut string = Wtf8Buf::new();
string.push_wtf8(w(b"\xED\x9F\xBF")); // not surrogate
string.push_wtf8(w(b"\xED\xB0\x80")); // trail
assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80");
+ assert!(!string.is_known_utf8);
let mut string = Wtf8Buf::new();
string.push_wtf8(w(b"a")); // not surrogate, < 3 bytes
string.push_wtf8(w(b"\xED\xB0\x80")); // trail
assert_eq!(string.bytes, b"\x61\xED\xB0\x80");
+ assert!(!string.is_known_utf8);
let mut string = Wtf8Buf::new();
string.push_wtf8(w(b"\xED\xB0\x80")); // trail
assert_eq!(string.bytes, b"\xED\xB0\x80");
+ assert!(!string.is_known_utf8);
}
#[test]
fn wtf8buf_truncate() {
let mut string = Wtf8Buf::from_str("aé");
+ assert!(string.is_known_utf8);
+
+ string.truncate(3);
+ assert_eq!(string.bytes, b"a\xC3\xA9");
+ assert!(string.is_known_utf8);
+
string.truncate(1);
assert_eq!(string.bytes, b"a");
+ assert!(string.is_known_utf8);
+
+ string.truncate(0);
+ assert_eq!(string.bytes, b"");
+ assert!(string.is_known_utf8);
+}
+
+#[test]
+fn wtf8buf_truncate_around_non_bmp() {
+ let mut string = Wtf8Buf::from_str("💩");
+ assert!(string.is_known_utf8);
+
+ string.truncate(4);
+ assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9");
+ assert!(string.is_known_utf8);
+
+ string.truncate(0);
+ assert_eq!(string.bytes, b"");
+ assert!(string.is_known_utf8);
}
#[test]
@@ -209,10 +311,36 @@ fn wtf8buf_truncate_fail_longer() {
}
#[test]
+#[should_panic]
+fn wtf8buf_truncate_splitting_non_bmp3() {
+ let mut string = Wtf8Buf::from_str("💩");
+ assert!(string.is_known_utf8);
+ string.truncate(3);
+}
+
+#[test]
+#[should_panic]
+fn wtf8buf_truncate_splitting_non_bmp2() {
+ let mut string = Wtf8Buf::from_str("💩");
+ assert!(string.is_known_utf8);
+ string.truncate(2);
+}
+
+#[test]
+#[should_panic]
+fn wtf8buf_truncate_splitting_non_bmp1() {
+ let mut string = Wtf8Buf::from_str("💩");
+ assert!(string.is_known_utf8);
+ string.truncate(1);
+}
+
+#[test]
fn wtf8buf_into_string() {
let mut string = Wtf8Buf::from_str("aé 💩");
+ assert!(string.is_known_utf8);
assert_eq!(string.clone().into_string(), Ok(String::from("aé 💩")));
string.push(CodePoint::from_u32(0xD800).unwrap());
+ assert!(!string.is_known_utf8);
assert_eq!(string.clone().into_string(), Err(string));
}
@@ -229,15 +357,33 @@ fn wtf8buf_from_iterator() {
fn f(values: &[u32]) -> Wtf8Buf {
values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>()
}
- assert_eq!(f(&[0x61, 0xE9, 0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert_eq!(
+ f(&[0x61, 0xE9, 0x20, 0x1F4A9]),
+ Wtf8Buf { bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(), is_known_utf8: true }
+ );
assert_eq!(f(&[0xD83D, 0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
- assert_eq!(f(&[0xD83D, 0x20, 0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
- assert_eq!(f(&[0xD800, 0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF");
- assert_eq!(f(&[0xD800, 0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80");
- assert_eq!(f(&[0xD7FF, 0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80");
- assert_eq!(f(&[0x61, 0xDC00]).bytes, b"\x61\xED\xB0\x80");
- assert_eq!(f(&[0xDC00]).bytes, b"\xED\xB0\x80");
+ assert_eq!(
+ f(&[0xD83D, 0x20, 0xDCA9]),
+ Wtf8Buf { bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ f(&[0xD800, 0xDBFF]),
+ Wtf8Buf { bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ f(&[0xD800, 0xE000]),
+ Wtf8Buf { bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ f(&[0xD7FF, 0xDC00]),
+ Wtf8Buf { bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ f(&[0x61, 0xDC00]),
+ Wtf8Buf { bytes: b"\x61\xED\xB0\x80".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(f(&[0xDC00]), Wtf8Buf { bytes: b"\xED\xB0\x80".to_vec(), is_known_utf8: false });
}
#[test]
@@ -251,15 +397,36 @@ fn wtf8buf_extend() {
string
}
- assert_eq!(e(&[0x61, 0xE9], &[0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+ assert_eq!(
+ e(&[0x61, 0xE9], &[0x20, 0x1F4A9]),
+ Wtf8Buf { bytes: b"a\xC3\xA9 \xF0\x9F\x92\xA9".to_vec(), is_known_utf8: true }
+ );
assert_eq!(e(&[0xD83D], &[0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
- assert_eq!(e(&[0xD83D, 0x20], &[0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
- assert_eq!(e(&[0xD800], &[0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF");
- assert_eq!(e(&[0xD800], &[0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80");
- assert_eq!(e(&[0xD7FF], &[0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80");
- assert_eq!(e(&[0x61], &[0xDC00]).bytes, b"\x61\xED\xB0\x80");
- assert_eq!(e(&[], &[0xDC00]).bytes, b"\xED\xB0\x80");
+ assert_eq!(
+ e(&[0xD83D, 0x20], &[0xDCA9]),
+ Wtf8Buf { bytes: b"\xED\xA0\xBD \xED\xB2\xA9".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ e(&[0xD800], &[0xDBFF]),
+ Wtf8Buf { bytes: b"\xED\xA0\x80\xED\xAF\xBF".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ e(&[0xD800], &[0xE000]),
+ Wtf8Buf { bytes: b"\xED\xA0\x80\xEE\x80\x80".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ e(&[0xD7FF], &[0xDC00]),
+ Wtf8Buf { bytes: b"\xED\x9F\xBF\xED\xB0\x80".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ e(&[0x61], &[0xDC00]),
+ Wtf8Buf { bytes: b"\x61\xED\xB0\x80".to_vec(), is_known_utf8: false }
+ );
+ assert_eq!(
+ e(&[], &[0xDC00]),
+ Wtf8Buf { bytes: b"\xED\xB0\x80".to_vec(), is_known_utf8: false }
+ );
}
#[test]
@@ -407,3 +574,93 @@ fn wtf8_encode_wide_size_hint() {
assert_eq!((0, Some(0)), iter.size_hint());
assert!(iter.next().is_none());
}
+
+#[test]
+fn wtf8_clone_into() {
+ let mut string = Wtf8Buf::new();
+ Wtf8::from_str("green").clone_into(&mut string);
+ assert_eq!(string.bytes, b"green");
+
+ let mut string = Wtf8Buf::from_str("green");
+ Wtf8::from_str("").clone_into(&mut string);
+ assert_eq!(string.bytes, b"");
+
+ let mut string = Wtf8Buf::from_str("red");
+ Wtf8::from_str("green").clone_into(&mut string);
+ assert_eq!(string.bytes, b"green");
+
+ let mut string = Wtf8Buf::from_str("green");
+ Wtf8::from_str("red").clone_into(&mut string);
+ assert_eq!(string.bytes, b"red");
+
+ let mut string = Wtf8Buf::from_str("green");
+ assert!(string.is_known_utf8);
+ unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").clone_into(&mut string) };
+ assert_eq!(string.bytes, b"\xED\xA0\x80");
+ assert!(!string.is_known_utf8);
+}
+
+#[test]
+fn wtf8_to_ascii_lowercase() {
+ let lowercase = Wtf8::from_str("").to_ascii_lowercase();
+ assert_eq!(lowercase.bytes, b"");
+
+ let lowercase = Wtf8::from_str("GrEeN gRaPeS! ðŸ‡").to_ascii_lowercase();
+ assert_eq!(lowercase.bytes, b"green grapes! \xf0\x9f\x8d\x87");
+
+ let lowercase = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_ascii_lowercase() };
+ assert_eq!(lowercase.bytes, b"\xED\xA0\x80");
+ assert!(!lowercase.is_known_utf8);
+}
+
+#[test]
+fn wtf8_to_ascii_uppercase() {
+ let uppercase = Wtf8::from_str("").to_ascii_uppercase();
+ assert_eq!(uppercase.bytes, b"");
+
+ let uppercase = Wtf8::from_str("GrEeN gRaPeS! ðŸ‡").to_ascii_uppercase();
+ assert_eq!(uppercase.bytes, b"GREEN GRAPES! \xf0\x9f\x8d\x87");
+
+ let uppercase = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_ascii_uppercase() };
+ assert_eq!(uppercase.bytes, b"\xED\xA0\x80");
+ assert!(!uppercase.is_known_utf8);
+}
+
+#[test]
+fn wtf8_make_ascii_lowercase() {
+ let mut lowercase = Wtf8Buf::from_str("");
+ lowercase.make_ascii_lowercase();
+ assert_eq!(lowercase.bytes, b"");
+
+ let mut lowercase = Wtf8Buf::from_str("GrEeN gRaPeS! ðŸ‡");
+ lowercase.make_ascii_lowercase();
+ assert_eq!(lowercase.bytes, b"green grapes! \xf0\x9f\x8d\x87");
+
+ let mut lowercase = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_owned() };
+ lowercase.make_ascii_lowercase();
+ assert_eq!(lowercase.bytes, b"\xED\xA0\x80");
+ assert!(!lowercase.is_known_utf8);
+}
+
+#[test]
+fn wtf8_make_ascii_uppercase() {
+ let mut uppercase = Wtf8Buf::from_str("");
+ uppercase.make_ascii_uppercase();
+ assert_eq!(uppercase.bytes, b"");
+
+ let mut uppercase = Wtf8Buf::from_str("GrEeN gRaPeS! ðŸ‡");
+ uppercase.make_ascii_uppercase();
+ assert_eq!(uppercase.bytes, b"GREEN GRAPES! \xf0\x9f\x8d\x87");
+
+ let mut uppercase = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_owned() };
+ uppercase.make_ascii_uppercase();
+ assert_eq!(uppercase.bytes, b"\xED\xA0\x80");
+ assert!(!uppercase.is_known_utf8);
+}
+
+#[test]
+fn wtf8_to_owned() {
+ let string = unsafe { Wtf8::from_bytes_unchecked(b"\xED\xA0\x80").to_owned() };
+ assert_eq!(string.bytes, b"\xED\xA0\x80");
+ assert!(!string.is_known_utf8);
+}
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index f4750cdf7..8aedfc4a6 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -1036,6 +1036,7 @@ pub mod fast {
}
#[doc(hidden)]
+#[cfg(not(target_thread_local))]
pub mod os {
use super::lazy::LazyKeyInner;
use crate::cell::Cell;
@@ -1044,6 +1045,8 @@ pub mod os {
use crate::ptr;
use crate::sys_common::thread_local_key::StaticKey as OsStaticKey;
+ /// Use a regular global static to store this key; the state provided will then be
+ /// thread-local.
pub struct Key<T> {
// OS-TLS key that we'll use to key off.
os: OsStaticKey,
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 44c8a50fd..ceea6986e 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -116,7 +116,7 @@
//! Threads are able to have associated names for identification purposes. By default, spawned
//! threads are unnamed. To specify a name for a thread, build the thread with [`Builder`] and pass
//! the desired thread name to [`Builder::name`]. To retrieve the thread name from within the
-//! thread, use [`Thread::name`]. A couple examples of where the name of a thread gets used:
+//! thread, use [`Thread::name`]. A couple of examples where the name of a thread gets used:
//!
//! * If a panic occurs in a named thread, the thread name will be printed in the panic message.
//! * The thread name is provided to the OS where applicable (e.g., `pthread_setname_np` in
@@ -170,7 +170,6 @@ use crate::ptr::addr_of_mut;
use crate::str;
use crate::sync::Arc;
use crate::sys::thread as imp;
-use crate::sys_common::mutex;
use crate::sys_common::thread;
use crate::sys_common::thread_info;
use crate::sys_common::thread_parker::Parker;
@@ -193,21 +192,31 @@ pub use scoped::{scope, Scope, ScopedJoinHandle};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::local::{AccessError, LocalKey};
-// The types used by the thread_local! macro to access TLS keys. Note that there
-// are two types, the "OS" type and the "fast" type. The OS thread local key
-// type is accessed via platform-specific API calls and is slow, while the fast
+// Select the type used by the thread_local! macro to access TLS keys. There
+// are three types: "static", "fast", "OS". The "OS" thread local key
+// type is accessed via platform-specific API calls and is slow, while the "fast"
// key type is accessed via code generated via LLVM, where TLS keys are set up
-// by the elf linker. Note that the OS TLS type is always available: on macOS
-// the standard library is compiled with support for older platform versions
-// where fast TLS was not available; end-user code is compiled with fast TLS
-// where available, but both are needed.
+// by the elf linker. "static" is for single-threaded platforms where a global
+// static is sufficient.
#[unstable(feature = "libstd_thread_internals", issue = "none")]
#[cfg(target_thread_local)]
+#[cfg(not(test))]
#[doc(hidden)]
pub use self::local::fast::Key as __FastLocalKeyInner;
#[unstable(feature = "libstd_thread_internals", issue = "none")]
+#[cfg(target_thread_local)]
+#[cfg(test)] // when building for tests, use real std's key
+pub use realstd::thread::__FastLocalKeyInner;
+
+#[unstable(feature = "libstd_thread_internals", issue = "none")]
+#[cfg(target_thread_local)]
+#[cfg(test)]
+pub use self::local::fast::Key as __FastLocalKeyInnerUnused; // we import this anyway to silence 'unused' warnings
+
+#[unstable(feature = "libstd_thread_internals", issue = "none")]
#[doc(hidden)]
+#[cfg(not(target_thread_local))]
pub use self::local::os::Key as __OsLocalKeyInner;
#[unstable(feature = "libstd_thread_internals", issue = "none")]
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
@@ -1033,24 +1042,48 @@ pub struct ThreadId(NonZeroU64);
impl ThreadId {
// Generate a new unique thread ID.
fn new() -> ThreadId {
- // It is UB to attempt to acquire this mutex reentrantly!
- static GUARD: mutex::StaticMutex = mutex::StaticMutex::new();
- static mut COUNTER: u64 = 1;
-
- unsafe {
- let guard = GUARD.lock();
-
- // If we somehow use up all our bits, panic so that we're not
- // covering up subtle bugs of IDs being reused.
- if COUNTER == u64::MAX {
- drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
- panic!("failed to generate unique thread ID: bitspace exhausted");
- }
-
- let id = COUNTER;
- COUNTER += 1;
+ #[cold]
+ fn exhausted() -> ! {
+ panic!("failed to generate unique thread ID: bitspace exhausted")
+ }
- ThreadId(NonZeroU64::new(id).unwrap())
+ cfg_if::cfg_if! {
+ if #[cfg(target_has_atomic = "64")] {
+ use crate::sync::atomic::{AtomicU64, Ordering::Relaxed};
+
+ static COUNTER: AtomicU64 = AtomicU64::new(0);
+
+ let mut last = COUNTER.load(Relaxed);
+ loop {
+ let Some(id) = last.checked_add(1) else {
+ exhausted();
+ };
+
+ match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) {
+ Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()),
+ Err(id) => last = id,
+ }
+ }
+ } else {
+ use crate::sys_common::mutex::StaticMutex;
+
+ // It is UB to attempt to acquire this mutex reentrantly!
+ static GUARD: StaticMutex = StaticMutex::new();
+ static mut COUNTER: u64 = 0;
+
+ unsafe {
+ let guard = GUARD.lock();
+
+ let Some(id) = COUNTER.checked_add(1) else {
+ drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
+ exhausted();
+ };
+
+ COUNTER = id;
+ drop(guard);
+ ThreadId(NonZeroU64::new(id).unwrap())
+ }
+ }
}
}
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index ec68b5291..777964f04 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -37,6 +37,37 @@ fn test_named_thread() {
.unwrap();
}
+#[cfg(any(
+ // Note: musl didn't add pthread_getname_np until 1.2.3
+ all(target_os = "linux", target_env = "gnu"),
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "watchos"
+))]
+#[test]
+fn test_named_thread_truncation() {
+ use crate::ffi::CStr;
+
+ let long_name = crate::iter::once("test_named_thread_truncation")
+ .chain(crate::iter::repeat(" yada").take(100))
+ .collect::<String>();
+
+ let result = Builder::new().name(long_name.clone()).spawn(move || {
+ // Rust remembers the full thread name itself.
+ assert_eq!(thread::current().name(), Some(long_name.as_str()));
+
+ // But the system is limited -- make sure we successfully set a truncation.
+ let mut buf = vec![0u8; long_name.len() + 1];
+ unsafe {
+ libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len());
+ }
+ let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
+ assert!(cstr.to_bytes().len() > 0);
+ assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
+ });
+ result.unwrap().join().unwrap();
+}
+
#[test]
#[should_panic]
fn test_invalid_named_thread() {
@@ -329,3 +360,22 @@ fn test_scoped_threads_nll() {
let x = 42_u8;
foo(&x);
}
+
+// Regression test for https://github.com/rust-lang/rust/issues/98498.
+#[test]
+#[cfg(miri)] // relies on Miri's data race detector
+fn scope_join_race() {
+ for _ in 0..100 {
+ let a_bool = AtomicBool::new(false);
+
+ thread::scope(|s| {
+ for _ in 0..5 {
+ s.spawn(|| a_bool.load(Ordering::Relaxed));
+ }
+
+ for _ in 0..5 {
+ s.spawn(|| a_bool.load(Ordering::Relaxed));
+ }
+ });
+ }
+}
diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs
index d710a5744..6229556c8 100644
--- a/library/std/src/time/tests.rs
+++ b/library/std/src/time/tests.rs
@@ -31,7 +31,8 @@ fn instant_monotonic_concurrent() -> crate::thread::Result<()> {
.map(|_| {
crate::thread::spawn(|| {
let mut old = Instant::now();
- for _ in 0..5_000_000 {
+ let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
+ for _ in 0..count {
let new = Instant::now();
assert!(new >= old);
old = new;
diff --git a/library/stdarch/CONTRIBUTING.md b/library/stdarch/CONTRIBUTING.md
index ebccd73ea..4212abcd7 100644
--- a/library/stdarch/CONTRIBUTING.md
+++ b/library/stdarch/CONTRIBUTING.md
@@ -9,7 +9,7 @@ $ cd stdarch
$ TARGET="<your-target-arch>" ci/run.sh
```
-Where `<your-target-arch>` is the target triple as used by `rustup`, e.g. `x86_x64-unknown-linux-gnu` (without any preceding `nightly-` or similar).
+Where `<your-target-arch>` is the target triple as used by `rustup`, e.g. `x86_64-unknown-linux-gnu` (without any preceding `nightly-` or similar).
Also remember that this repository requires the nightly channel of Rust!
The above tests do in fact require nightly rust to be the default on your system, to set that use `rustup default nightly` (and `rustup default stable` to revert).
diff --git a/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
index 49464dacf..2f99999da 100644
--- a/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
+++ b/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:21.10
+FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
diff --git a/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile
index 74181a4cb..b4cd0a68a 100644
--- a/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile
+++ b/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:21.10
+FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
diff --git a/library/stdarch/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile
index 1618db22f..b9b3c682e 100644
--- a/library/stdarch/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile
+++ b/library/stdarch/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:21.10
+FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates \
diff --git a/library/stdarch/ci/dox.sh b/library/stdarch/ci/dox.sh
index e70a32b2d..3e507b456 100755
--- a/library/stdarch/ci/dox.sh
+++ b/library/stdarch/ci/dox.sh
@@ -22,9 +22,6 @@ dox() {
rm -rf "target/doc/${arch}"
mkdir "target/doc/${arch}"
- export RUSTFLAGS="--cfg core_arch_docs"
- export RUSTDOCFLAGS="--cfg core_arch_docs"
-
cargo build --verbose --target "${target}" --manifest-path crates/core_arch/Cargo.toml
cargo build --verbose --target "${target}" --manifest-path crates/std_detect/Cargo.toml
@@ -32,16 +29,14 @@ dox() {
-o "target/doc/${arch}" crates/core_arch/src/lib.rs \
--edition=2018 \
--crate-name core_arch \
- --library-path "target/${target}/debug/deps" \
- --cfg core_arch_docs
+ --library-path "target/${target}/debug/deps"
rustdoc --verbose --target "${target}" \
-o "target/doc/${arch}" crates/std_detect/src/lib.rs \
--edition=2018 \
--crate-name std_detect \
--library-path "target/${target}/debug/deps" \
--extern cfg_if="$(ls target/"${target}"/debug/deps/libcfg_if-*.rlib)" \
- --extern libc="$(ls target/"${target}"/debug/deps/liblibc-*.rlib)" \
- --cfg core_arch_docs
+ --extern libc="$(ls target/"${target}"/debug/deps/liblibc-*.rlib)"
}
dox i686 i686-unknown-linux-gnu
diff --git a/library/stdarch/crates/core_arch/Cargo.toml b/library/stdarch/crates/core_arch/Cargo.toml
index 14b5479d1..e2b332af2 100644
--- a/library/stdarch/crates/core_arch/Cargo.toml
+++ b/library/stdarch/crates/core_arch/Cargo.toml
@@ -13,7 +13,6 @@ readme = "README.md"
keywords = ["core", "simd", "arch", "intrinsics"]
categories = ["hardware-support", "no-std"]
license = "MIT OR Apache-2.0"
-build = "build.rs"
edition = "2018"
[badges]
diff --git a/library/stdarch/crates/core_arch/build.rs b/library/stdarch/crates/core_arch/build.rs
deleted file mode 100644
index 4d65e9ddc..000000000
--- a/library/stdarch/crates/core_arch/build.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- println!("cargo:rustc-cfg=core_arch_docs");
-}
diff --git a/library/stdarch/crates/core_arch/src/aarch64/crc.rs b/library/stdarch/crates/core_arch/src/aarch64/crc.rs
index 6e8128534..ac3f8d815 100644
--- a/library/stdarch/crates/core_arch/src/aarch64/crc.rs
+++ b/library/stdarch/crates/core_arch/src/aarch64/crc.rs
@@ -10,6 +10,8 @@ extern "unadjusted" {
use stdarch_test::assert_instr;
/// CRC32 single round checksum for quad words (64 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(test, assert_instr(crc32x))]
@@ -18,6 +20,8 @@ pub unsafe fn __crc32d(crc: u32, data: u64) -> u32 {
}
/// CRC32-C single round checksum for quad words (64 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(test, assert_instr(crc32cx))]
diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
index 74ea2963c..ac05a0c23 100644
--- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
+++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
@@ -10,6 +10,8 @@ use super::*;
use stdarch_test::assert_instr;
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s8)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -23,6 +25,8 @@ pub unsafe fn veor3q_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s16)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -36,6 +40,8 @@ pub unsafe fn veor3q_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s32)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -49,6 +55,8 @@ pub unsafe fn veor3q_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -62,6 +70,8 @@ pub unsafe fn veor3q_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u8)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -75,6 +85,8 @@ pub unsafe fn veor3q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u16)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -88,6 +100,8 @@ pub unsafe fn veor3q_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u32)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -101,6 +115,8 @@ pub unsafe fn veor3q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x
}
/// Three-way exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(eor3))]
@@ -114,6 +130,8 @@ pub unsafe fn veor3q_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x
}
/// Absolute difference between the arguments of Floating
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fabd))]
@@ -128,6 +146,8 @@ pub unsafe fn vabd_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Absolute difference between the arguments of Floating
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fabd))]
@@ -142,6 +162,8 @@ pub unsafe fn vabdq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point absolute difference
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabds_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fabd))]
@@ -151,6 +173,8 @@ pub unsafe fn vabds_f32(a: f32, b: f32) -> f32 {
}
/// Floating-point absolute difference
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fabd))]
@@ -160,6 +184,8 @@ pub unsafe fn vabdd_f64(a: f64, b: f64) -> f64 {
}
/// Unsigned Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uabdl))]
@@ -171,6 +197,8 @@ pub unsafe fn vabdl_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
}
/// Unsigned Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uabdl))]
@@ -182,6 +210,8 @@ pub unsafe fn vabdl_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
}
/// Unsigned Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uabdl))]
@@ -193,6 +223,8 @@ pub unsafe fn vabdl_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
}
/// Signed Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sabdl))]
@@ -205,6 +237,8 @@ pub unsafe fn vabdl_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
}
/// Signed Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sabdl))]
@@ -217,6 +251,8 @@ pub unsafe fn vabdl_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
}
/// Signed Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sabdl))]
@@ -229,6 +265,8 @@ pub unsafe fn vabdl_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -238,6 +276,8 @@ pub unsafe fn vceq_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -247,6 +287,8 @@ pub unsafe fn vceqq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -256,6 +298,8 @@ pub unsafe fn vceq_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -265,6 +309,8 @@ pub unsafe fn vceqq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -274,6 +320,8 @@ pub unsafe fn vceq_p64(a: poly64x1_t, b: poly64x1_t) -> uint64x1_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -283,6 +331,8 @@ pub unsafe fn vceqq_p64(a: poly64x2_t, b: poly64x2_t) -> uint64x2_t {
}
/// Floating-point compare equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmeq))]
@@ -292,6 +342,8 @@ pub unsafe fn vceq_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmeq))]
@@ -301,6 +353,8 @@ pub unsafe fn vceqq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Compare bitwise equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -310,6 +364,8 @@ pub unsafe fn vceqd_s64(a: i64, b: i64) -> u64 {
}
/// Compare bitwise equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -319,6 +375,8 @@ pub unsafe fn vceqd_u64(a: u64, b: u64) -> u64 {
}
/// Floating-point compare equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -328,6 +386,8 @@ pub unsafe fn vceqs_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point compare equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -337,6 +397,8 @@ pub unsafe fn vceqd_f64(a: f64, b: f64) -> u64 {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -347,6 +409,8 @@ pub unsafe fn vceqz_s8(a: int8x8_t) -> uint8x8_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -357,6 +421,8 @@ pub unsafe fn vceqzq_s8(a: int8x16_t) -> uint8x16_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -367,6 +433,8 @@ pub unsafe fn vceqz_s16(a: int16x4_t) -> uint16x4_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -377,6 +445,8 @@ pub unsafe fn vceqzq_s16(a: int16x8_t) -> uint16x8_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -387,6 +457,8 @@ pub unsafe fn vceqz_s32(a: int32x2_t) -> uint32x2_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -397,6 +469,8 @@ pub unsafe fn vceqzq_s32(a: int32x4_t) -> uint32x4_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -407,6 +481,8 @@ pub unsafe fn vceqz_s64(a: int64x1_t) -> uint64x1_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -417,6 +493,8 @@ pub unsafe fn vceqzq_s64(a: int64x2_t) -> uint64x2_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -427,6 +505,8 @@ pub unsafe fn vceqz_p8(a: poly8x8_t) -> uint8x8_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -437,6 +517,8 @@ pub unsafe fn vceqzq_p8(a: poly8x16_t) -> uint8x16_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -447,6 +529,8 @@ pub unsafe fn vceqz_p64(a: poly64x1_t) -> uint64x1_t {
}
/// Signed compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -457,6 +541,8 @@ pub unsafe fn vceqzq_p64(a: poly64x2_t) -> uint64x2_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -467,6 +553,8 @@ pub unsafe fn vceqz_u8(a: uint8x8_t) -> uint8x8_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -477,6 +565,8 @@ pub unsafe fn vceqzq_u8(a: uint8x16_t) -> uint8x16_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -487,6 +577,8 @@ pub unsafe fn vceqz_u16(a: uint16x4_t) -> uint16x4_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -497,6 +589,8 @@ pub unsafe fn vceqzq_u16(a: uint16x8_t) -> uint16x8_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -507,6 +601,8 @@ pub unsafe fn vceqz_u32(a: uint32x2_t) -> uint32x2_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -517,6 +613,8 @@ pub unsafe fn vceqzq_u32(a: uint32x4_t) -> uint32x4_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -527,6 +625,8 @@ pub unsafe fn vceqz_u64(a: uint64x1_t) -> uint64x1_t {
}
/// Unsigned compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmeq))]
@@ -537,6 +637,8 @@ pub unsafe fn vceqzq_u64(a: uint64x2_t) -> uint64x2_t {
}
/// Floating-point compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmeq))]
@@ -547,6 +649,8 @@ pub unsafe fn vceqz_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmeq))]
@@ -557,6 +661,8 @@ pub unsafe fn vceqzq_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmeq))]
@@ -567,6 +673,8 @@ pub unsafe fn vceqz_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmeq))]
@@ -577,6 +685,8 @@ pub unsafe fn vceqzq_f64(a: float64x2_t) -> uint64x2_t {
}
/// Compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -586,6 +696,8 @@ pub unsafe fn vceqzd_s64(a: i64) -> u64 {
}
/// Compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -595,6 +707,8 @@ pub unsafe fn vceqzd_u64(a: u64) -> u64 {
}
/// Floating-point compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -604,6 +718,8 @@ pub unsafe fn vceqzs_f32(a: f32) -> u32 {
}
/// Floating-point compare bitwise equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -613,6 +729,8 @@ pub unsafe fn vceqzd_f64(a: f64) -> u64 {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
@@ -624,6 +742,8 @@ pub unsafe fn vtst_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
@@ -635,6 +755,8 @@ pub unsafe fn vtstq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
@@ -646,6 +768,8 @@ pub unsafe fn vtst_p64(a: poly64x1_t, b: poly64x1_t) -> uint64x1_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
@@ -657,6 +781,8 @@ pub unsafe fn vtstq_p64(a: poly64x2_t, b: poly64x2_t) -> uint64x2_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
@@ -668,6 +794,8 @@ pub unsafe fn vtst_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
@@ -679,6 +807,8 @@ pub unsafe fn vtstq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Compare bitwise test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(tst))]
@@ -688,6 +818,8 @@ pub unsafe fn vtstd_s64(a: i64, b: i64) -> u64 {
}
/// Compare bitwise test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(tst))]
@@ -697,6 +829,8 @@ pub unsafe fn vtstd_u64(a: u64, b: u64) -> u64 {
}
/// Signed saturating accumulate of unsigned value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqadds_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(suqadd))]
@@ -711,6 +845,8 @@ pub unsafe fn vuqadds_s32(a: i32, b: u32) -> i32 {
}
/// Signed saturating accumulate of unsigned value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(suqadd))]
@@ -725,6 +861,8 @@ pub unsafe fn vuqaddd_s64(a: i64, b: u64) -> i64 {
}
/// Signed saturating accumulate of unsigned value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(suqadd))]
@@ -734,6 +872,8 @@ pub unsafe fn vuqaddb_s8(a: i8, b: u8) -> i8 {
}
/// Signed saturating accumulate of unsigned value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(suqadd))]
@@ -743,6 +883,8 @@ pub unsafe fn vuqaddh_s16(a: i16, b: u16) -> i16 {
}
/// Floating-point absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fabs))]
@@ -752,6 +894,8 @@ pub unsafe fn vabs_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fabs))]
@@ -761,6 +905,8 @@ pub unsafe fn vabsq_f64(a: float64x2_t) -> float64x2_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -770,6 +916,8 @@ pub unsafe fn vcgt_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -779,6 +927,8 @@ pub unsafe fn vcgtq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhi))]
@@ -788,6 +938,8 @@ pub unsafe fn vcgt_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhi))]
@@ -797,6 +949,8 @@ pub unsafe fn vcgtq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Floating-point compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -806,6 +960,8 @@ pub unsafe fn vcgt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -815,6 +971,8 @@ pub unsafe fn vcgtq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -824,6 +982,8 @@ pub unsafe fn vcgtd_s64(a: i64, b: i64) -> u64 {
}
/// Compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -833,6 +993,8 @@ pub unsafe fn vcgtd_u64(a: u64, b: u64) -> u64 {
}
/// Floating-point compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgts_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -842,6 +1004,8 @@ pub unsafe fn vcgts_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -851,6 +1015,8 @@ pub unsafe fn vcgtd_f64(a: f64, b: f64) -> u64 {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -860,6 +1026,8 @@ pub unsafe fn vclt_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -869,6 +1037,8 @@ pub unsafe fn vcltq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhi))]
@@ -878,6 +1048,8 @@ pub unsafe fn vclt_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhi))]
@@ -887,6 +1059,8 @@ pub unsafe fn vcltq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Floating-point compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -896,6 +1070,8 @@ pub unsafe fn vclt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -905,6 +1081,8 @@ pub unsafe fn vcltq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -914,6 +1092,8 @@ pub unsafe fn vcltd_s64(a: i64, b: i64) -> u64 {
}
/// Compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -923,6 +1103,8 @@ pub unsafe fn vcltd_u64(a: u64, b: u64) -> u64 {
}
/// Floating-point compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclts_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -932,6 +1114,8 @@ pub unsafe fn vclts_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -941,6 +1125,8 @@ pub unsafe fn vcltd_f64(a: f64, b: f64) -> u64 {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -950,6 +1136,8 @@ pub unsafe fn vcle_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -959,6 +1147,8 @@ pub unsafe fn vcleq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
}
/// Compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcged_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -968,6 +1158,8 @@ pub unsafe fn vcged_s64(a: i64, b: i64) -> u64 {
}
/// Compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcged_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -977,6 +1169,8 @@ pub unsafe fn vcged_u64(a: u64, b: u64) -> u64 {
}
/// Floating-point compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcges_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -986,6 +1180,8 @@ pub unsafe fn vcges_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcged_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -995,6 +1191,8 @@ pub unsafe fn vcged_f64(a: f64, b: f64) -> u64 {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhs))]
@@ -1004,6 +1202,8 @@ pub unsafe fn vcle_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhs))]
@@ -1013,6 +1213,8 @@ pub unsafe fn vcleq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Floating-point compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1022,6 +1224,8 @@ pub unsafe fn vcle_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1031,6 +1235,8 @@ pub unsafe fn vcleq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcled_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -1040,6 +1246,8 @@ pub unsafe fn vcled_s64(a: i64, b: i64) -> u64 {
}
/// Compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcled_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -1049,6 +1257,8 @@ pub unsafe fn vcled_u64(a: u64, b: u64) -> u64 {
}
/// Floating-point compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcles_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1058,6 +1268,8 @@ pub unsafe fn vcles_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcled_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1067,6 +1279,8 @@ pub unsafe fn vcled_f64(a: f64, b: f64) -> u64 {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1076,6 +1290,8 @@ pub unsafe fn vcge_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1085,6 +1301,8 @@ pub unsafe fn vcgeq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhs))]
@@ -1094,6 +1312,8 @@ pub unsafe fn vcge_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmhs))]
@@ -1103,6 +1323,8 @@ pub unsafe fn vcgeq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Floating-point compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1112,6 +1334,8 @@ pub unsafe fn vcge_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1121,6 +1345,8 @@ pub unsafe fn vcgeq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1131,6 +1357,8 @@ pub unsafe fn vcgez_s8(a: int8x8_t) -> uint8x8_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1141,6 +1369,8 @@ pub unsafe fn vcgezq_s8(a: int8x16_t) -> uint8x16_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1151,6 +1381,8 @@ pub unsafe fn vcgez_s16(a: int16x4_t) -> uint16x4_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1161,6 +1393,8 @@ pub unsafe fn vcgezq_s16(a: int16x8_t) -> uint16x8_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1171,6 +1405,8 @@ pub unsafe fn vcgez_s32(a: int32x2_t) -> uint32x2_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1181,6 +1417,8 @@ pub unsafe fn vcgezq_s32(a: int32x4_t) -> uint32x4_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1191,6 +1429,8 @@ pub unsafe fn vcgez_s64(a: int64x1_t) -> uint64x1_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmge))]
@@ -1201,6 +1441,8 @@ pub unsafe fn vcgezq_s64(a: int64x2_t) -> uint64x2_t {
}
/// Floating-point compare greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1211,6 +1453,8 @@ pub unsafe fn vcgez_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1221,6 +1465,8 @@ pub unsafe fn vcgezq_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point compare greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1231,6 +1477,8 @@ pub unsafe fn vcgez_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmge))]
@@ -1241,6 +1489,8 @@ pub unsafe fn vcgezq_f64(a: float64x2_t) -> uint64x2_t {
}
/// Compare signed greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(eor))]
@@ -1250,6 +1500,8 @@ pub unsafe fn vcgezd_s64(a: i64) -> u64 {
}
/// Floating-point compare greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1259,6 +1511,8 @@ pub unsafe fn vcgezs_f32(a: f32) -> u32 {
}
/// Floating-point compare greater than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1268,6 +1522,8 @@ pub unsafe fn vcgezd_f64(a: f64) -> u64 {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1278,6 +1534,8 @@ pub unsafe fn vcgtz_s8(a: int8x8_t) -> uint8x8_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1288,6 +1546,8 @@ pub unsafe fn vcgtzq_s8(a: int8x16_t) -> uint8x16_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1298,6 +1558,8 @@ pub unsafe fn vcgtz_s16(a: int16x4_t) -> uint16x4_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1308,6 +1570,8 @@ pub unsafe fn vcgtzq_s16(a: int16x8_t) -> uint16x8_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1318,6 +1582,8 @@ pub unsafe fn vcgtz_s32(a: int32x2_t) -> uint32x2_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1328,6 +1594,8 @@ pub unsafe fn vcgtzq_s32(a: int32x4_t) -> uint32x4_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1338,6 +1606,8 @@ pub unsafe fn vcgtz_s64(a: int64x1_t) -> uint64x1_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1348,6 +1618,8 @@ pub unsafe fn vcgtzq_s64(a: int64x2_t) -> uint64x2_t {
}
/// Floating-point compare greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -1358,6 +1630,8 @@ pub unsafe fn vcgtz_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -1368,6 +1642,8 @@ pub unsafe fn vcgtzq_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point compare greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -1378,6 +1654,8 @@ pub unsafe fn vcgtz_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmgt))]
@@ -1388,6 +1666,8 @@ pub unsafe fn vcgtzq_f64(a: float64x2_t) -> uint64x2_t {
}
/// Compare signed greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -1397,6 +1677,8 @@ pub unsafe fn vcgtzd_s64(a: i64) -> u64 {
}
/// Floating-point compare greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1406,6 +1688,8 @@ pub unsafe fn vcgtzs_f32(a: f32) -> u32 {
}
/// Floating-point compare greater than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1415,6 +1699,8 @@ pub unsafe fn vcgtzd_f64(a: f64) -> u64 {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1425,6 +1711,8 @@ pub unsafe fn vclez_s8(a: int8x8_t) -> uint8x8_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1435,6 +1723,8 @@ pub unsafe fn vclezq_s8(a: int8x16_t) -> uint8x16_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1445,6 +1735,8 @@ pub unsafe fn vclez_s16(a: int16x4_t) -> uint16x4_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1455,6 +1747,8 @@ pub unsafe fn vclezq_s16(a: int16x8_t) -> uint16x8_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1465,6 +1759,8 @@ pub unsafe fn vclez_s32(a: int32x2_t) -> uint32x2_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1475,6 +1771,8 @@ pub unsafe fn vclezq_s32(a: int32x4_t) -> uint32x4_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1485,6 +1783,8 @@ pub unsafe fn vclez_s64(a: int64x1_t) -> uint64x1_t {
}
/// Compare signed less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmgt))]
@@ -1495,6 +1795,8 @@ pub unsafe fn vclezq_s64(a: int64x2_t) -> uint64x2_t {
}
/// Floating-point compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmle))]
@@ -1505,6 +1807,8 @@ pub unsafe fn vclez_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmle))]
@@ -1515,6 +1819,8 @@ pub unsafe fn vclezq_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmle))]
@@ -1525,6 +1831,8 @@ pub unsafe fn vclez_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmle))]
@@ -1535,6 +1843,8 @@ pub unsafe fn vclezq_f64(a: float64x2_t) -> uint64x2_t {
}
/// Compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmp))]
@@ -1544,6 +1854,8 @@ pub unsafe fn vclezd_s64(a: i64) -> u64 {
}
/// Floating-point compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1553,6 +1865,8 @@ pub unsafe fn vclezs_f32(a: f32) -> u32 {
}
/// Floating-point compare less than or equal to zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1562,6 +1876,8 @@ pub unsafe fn vclezd_f64(a: f64) -> u64 {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1572,6 +1888,8 @@ pub unsafe fn vcltz_s8(a: int8x8_t) -> uint8x8_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1582,6 +1900,8 @@ pub unsafe fn vcltzq_s8(a: int8x16_t) -> uint8x16_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1592,6 +1912,8 @@ pub unsafe fn vcltz_s16(a: int16x4_t) -> uint16x4_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1602,6 +1924,8 @@ pub unsafe fn vcltzq_s16(a: int16x8_t) -> uint16x8_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1612,6 +1936,8 @@ pub unsafe fn vcltz_s32(a: int32x2_t) -> uint32x2_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1622,6 +1948,8 @@ pub unsafe fn vcltzq_s32(a: int32x4_t) -> uint32x4_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1632,6 +1960,8 @@ pub unsafe fn vcltz_s64(a: int64x1_t) -> uint64x1_t {
}
/// Compare signed less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmlt))]
@@ -1642,6 +1972,8 @@ pub unsafe fn vcltzq_s64(a: int64x2_t) -> uint64x2_t {
}
/// Floating-point compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmlt))]
@@ -1652,6 +1984,8 @@ pub unsafe fn vcltz_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmlt))]
@@ -1662,6 +1996,8 @@ pub unsafe fn vcltzq_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmlt))]
@@ -1672,6 +2008,8 @@ pub unsafe fn vcltz_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmlt))]
@@ -1682,6 +2020,8 @@ pub unsafe fn vcltzq_f64(a: float64x2_t) -> uint64x2_t {
}
/// Compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(asr))]
@@ -1691,6 +2031,8 @@ pub unsafe fn vcltzd_s64(a: i64) -> u64 {
}
/// Floating-point compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1700,6 +2042,8 @@ pub unsafe fn vcltzs_f32(a: f32) -> u32 {
}
/// Floating-point compare less than zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcmp))]
@@ -1709,6 +2053,8 @@ pub unsafe fn vcltzd_f64(a: f64) -> u64 {
}
/// Floating-point absolute compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagt_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1723,6 +2069,8 @@ pub unsafe fn vcagt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point absolute compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1737,6 +2085,8 @@ pub unsafe fn vcagtq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Floating-point absolute compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagts_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1751,6 +2101,8 @@ pub unsafe fn vcagts_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point absolute compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1765,6 +2117,8 @@ pub unsafe fn vcagtd_f64(a: f64, b: f64) -> u64 {
}
/// Floating-point absolute compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcage_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1779,6 +2133,8 @@ pub unsafe fn vcage_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point absolute compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcageq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1793,6 +2149,8 @@ pub unsafe fn vcageq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Floating-point absolute compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcages_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1807,6 +2165,8 @@ pub unsafe fn vcages_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point absolute compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaged_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1821,6 +2181,8 @@ pub unsafe fn vcaged_f64(a: f64, b: f64) -> u64 {
}
/// Floating-point absolute compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalt_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1830,6 +2192,8 @@ pub unsafe fn vcalt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point absolute compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1839,6 +2203,8 @@ pub unsafe fn vcaltq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Floating-point absolute compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalts_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1848,6 +2214,8 @@ pub unsafe fn vcalts_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point absolute compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facgt))]
@@ -1857,6 +2225,8 @@ pub unsafe fn vcaltd_f64(a: f64, b: f64) -> u64 {
}
/// Floating-point absolute compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcale_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1866,6 +2236,8 @@ pub unsafe fn vcale_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
}
/// Floating-point absolute compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaleq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1875,6 +2247,8 @@ pub unsafe fn vcaleq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
}
/// Floating-point absolute compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcales_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1884,6 +2258,8 @@ pub unsafe fn vcales_f32(a: f32, b: f32) -> u32 {
}
/// Floating-point absolute compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaled_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(facge))]
@@ -1893,6 +2269,8 @@ pub unsafe fn vcaled_f64(a: f64, b: f64) -> u64 {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -1915,6 +2293,8 @@ pub unsafe fn vcopy_lane_s8<const LANE1: i32, const LANE2: i32>(a: int8x8_t, b:
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -1945,6 +2325,8 @@ pub unsafe fn vcopyq_laneq_s8<const LANE1: i32, const LANE2: i32>(a: int8x16_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -1963,6 +2345,8 @@ pub unsafe fn vcopy_lane_s16<const LANE1: i32, const LANE2: i32>(a: int16x4_t, b
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -1985,6 +2369,8 @@ pub unsafe fn vcopyq_laneq_s16<const LANE1: i32, const LANE2: i32>(a: int16x8_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2001,6 +2387,8 @@ pub unsafe fn vcopy_lane_s32<const LANE1: i32, const LANE2: i32>(a: int32x2_t, b
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2019,6 +2407,8 @@ pub unsafe fn vcopyq_laneq_s32<const LANE1: i32, const LANE2: i32>(a: int32x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2035,6 +2425,8 @@ pub unsafe fn vcopyq_laneq_s64<const LANE1: i32, const LANE2: i32>(a: int64x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2057,6 +2449,8 @@ pub unsafe fn vcopy_lane_u8<const LANE1: i32, const LANE2: i32>(a: uint8x8_t, b:
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2087,6 +2481,8 @@ pub unsafe fn vcopyq_laneq_u8<const LANE1: i32, const LANE2: i32>(a: uint8x16_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2105,6 +2501,8 @@ pub unsafe fn vcopy_lane_u16<const LANE1: i32, const LANE2: i32>(a: uint16x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2127,6 +2525,8 @@ pub unsafe fn vcopyq_laneq_u16<const LANE1: i32, const LANE2: i32>(a: uint16x8_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2143,6 +2543,8 @@ pub unsafe fn vcopy_lane_u32<const LANE1: i32, const LANE2: i32>(a: uint32x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2161,6 +2563,8 @@ pub unsafe fn vcopyq_laneq_u32<const LANE1: i32, const LANE2: i32>(a: uint32x4_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2177,6 +2581,8 @@ pub unsafe fn vcopyq_laneq_u64<const LANE1: i32, const LANE2: i32>(a: uint64x2_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2199,6 +2605,8 @@ pub unsafe fn vcopy_lane_p8<const LANE1: i32, const LANE2: i32>(a: poly8x8_t, b:
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2229,6 +2637,8 @@ pub unsafe fn vcopyq_laneq_p8<const LANE1: i32, const LANE2: i32>(a: poly8x16_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2247,6 +2657,8 @@ pub unsafe fn vcopy_lane_p16<const LANE1: i32, const LANE2: i32>(a: poly16x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2269,6 +2681,8 @@ pub unsafe fn vcopyq_laneq_p16<const LANE1: i32, const LANE2: i32>(a: poly16x8_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2285,6 +2699,8 @@ pub unsafe fn vcopyq_laneq_p64<const LANE1: i32, const LANE2: i32>(a: poly64x2_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2301,6 +2717,8 @@ pub unsafe fn vcopy_lane_f32<const LANE1: i32, const LANE2: i32>(a: float32x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2319,6 +2737,8 @@ pub unsafe fn vcopyq_laneq_f32<const LANE1: i32, const LANE2: i32>(a: float32x4_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2335,6 +2755,8 @@ pub unsafe fn vcopyq_laneq_f64<const LANE1: i32, const LANE2: i32>(a: float64x2_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2358,6 +2780,8 @@ pub unsafe fn vcopy_laneq_s8<const LANE1: i32, const LANE2: i32>(a: int8x8_t, b:
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2377,6 +2801,8 @@ pub unsafe fn vcopy_laneq_s16<const LANE1: i32, const LANE2: i32>(a: int16x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2394,6 +2820,8 @@ pub unsafe fn vcopy_laneq_s32<const LANE1: i32, const LANE2: i32>(a: int32x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2417,6 +2845,8 @@ pub unsafe fn vcopy_laneq_u8<const LANE1: i32, const LANE2: i32>(a: uint8x8_t, b
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2436,6 +2866,8 @@ pub unsafe fn vcopy_laneq_u16<const LANE1: i32, const LANE2: i32>(a: uint16x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2453,6 +2885,8 @@ pub unsafe fn vcopy_laneq_u32<const LANE1: i32, const LANE2: i32>(a: uint32x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2476,6 +2910,8 @@ pub unsafe fn vcopy_laneq_p8<const LANE1: i32, const LANE2: i32>(a: poly8x8_t, b
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2495,6 +2931,8 @@ pub unsafe fn vcopy_laneq_p16<const LANE1: i32, const LANE2: i32>(a: poly16x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2512,6 +2950,8 @@ pub unsafe fn vcopy_laneq_f32<const LANE1: i32, const LANE2: i32>(a: float32x2_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2543,6 +2983,8 @@ pub unsafe fn vcopyq_lane_s8<const LANE1: i32, const LANE2: i32>(a: int8x16_t, b
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2566,6 +3008,8 @@ pub unsafe fn vcopyq_lane_s16<const LANE1: i32, const LANE2: i32>(a: int16x8_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2585,6 +3029,8 @@ pub unsafe fn vcopyq_lane_s32<const LANE1: i32, const LANE2: i32>(a: int32x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2616,6 +3062,8 @@ pub unsafe fn vcopyq_lane_u8<const LANE1: i32, const LANE2: i32>(a: uint8x16_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2639,6 +3087,8 @@ pub unsafe fn vcopyq_lane_u16<const LANE1: i32, const LANE2: i32>(a: uint16x8_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2658,6 +3108,8 @@ pub unsafe fn vcopyq_lane_u32<const LANE1: i32, const LANE2: i32>(a: uint32x4_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2689,6 +3141,8 @@ pub unsafe fn vcopyq_lane_p8<const LANE1: i32, const LANE2: i32>(a: poly8x16_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
@@ -2712,6 +3166,8 @@ pub unsafe fn vcopyq_lane_p16<const LANE1: i32, const LANE2: i32>(a: poly16x8_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
@@ -2729,6 +3185,8 @@ pub unsafe fn vcopyq_lane_s64<const LANE1: i32, const LANE2: i32>(a: int64x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
@@ -2746,6 +3204,8 @@ pub unsafe fn vcopyq_lane_u64<const LANE1: i32, const LANE2: i32>(a: uint64x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
@@ -2763,6 +3223,8 @@ pub unsafe fn vcopyq_lane_p64<const LANE1: i32, const LANE2: i32>(a: poly64x2_t,
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
@@ -2782,6 +3244,8 @@ pub unsafe fn vcopyq_lane_f32<const LANE1: i32, const LANE2: i32>(a: float32x4_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
@@ -2799,6 +3263,8 @@ pub unsafe fn vcopyq_lane_f64<const LANE1: i32, const LANE2: i32>(a: float64x2_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -2808,6 +3274,8 @@ pub unsafe fn vcreate_f64(a: u64) -> float64x1_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf))]
@@ -2817,6 +3285,8 @@ pub unsafe fn vcvt_f64_s64(a: int64x1_t) -> float64x1_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf))]
@@ -2826,6 +3296,8 @@ pub unsafe fn vcvtq_f64_s64(a: int64x2_t) -> float64x2_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf))]
@@ -2835,6 +3307,8 @@ pub unsafe fn vcvt_f64_u64(a: uint64x1_t) -> float64x1_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf))]
@@ -2844,6 +3318,8 @@ pub unsafe fn vcvtq_f64_u64(a: uint64x2_t) -> float64x2_t {
}
/// Floating-point convert to higher precision long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtl))]
@@ -2853,6 +3329,8 @@ pub unsafe fn vcvt_f64_f32(a: float32x2_t) -> float64x2_t {
}
/// Floating-point convert to higher precision long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtl))]
@@ -2863,6 +3341,8 @@ pub unsafe fn vcvt_high_f64_f32(a: float32x4_t) -> float64x2_t {
}
/// Floating-point convert to lower precision narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtn))]
@@ -2872,6 +3352,8 @@ pub unsafe fn vcvt_f32_f64(a: float64x2_t) -> float32x2_t {
}
/// Floating-point convert to lower precision narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtn))]
@@ -2881,6 +3363,8 @@ pub unsafe fn vcvt_high_f32_f64(a: float32x2_t, b: float64x2_t) -> float32x4_t {
}
/// Floating-point convert to lower precision narrow, rounding to odd
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtx_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtxn))]
@@ -2895,6 +3379,8 @@ pub unsafe fn vcvtx_f32_f64(a: float64x2_t) -> float32x2_t {
}
/// Floating-point convert to lower precision narrow, rounding to odd
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtxd_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtxn))]
@@ -2904,6 +3390,8 @@ pub unsafe fn vcvtxd_f32_f64(a: f64) -> f32 {
}
/// Floating-point convert to lower precision narrow, rounding to odd
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtx_high_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtxn))]
@@ -2913,6 +3401,8 @@ pub unsafe fn vcvtx_high_f32_f64(a: float32x2_t, b: float64x2_t) -> float32x4_t
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf, N = 2))]
@@ -2929,6 +3419,8 @@ pub unsafe fn vcvt_n_f64_s64<const N: i32>(a: int64x1_t) -> float64x1_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf, N = 2))]
@@ -2945,6 +3437,8 @@ pub unsafe fn vcvtq_n_f64_s64<const N: i32>(a: int64x2_t) -> float64x2_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_f32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf, N = 2))]
@@ -2961,6 +3455,8 @@ pub unsafe fn vcvts_n_f32_s32<const N: i32>(a: i32) -> f32 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf, N = 2))]
@@ -2977,6 +3473,8 @@ pub unsafe fn vcvtd_n_f64_s64<const N: i32>(a: i64) -> f64 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf, N = 2))]
@@ -2993,6 +3491,8 @@ pub unsafe fn vcvt_n_f64_u64<const N: i32>(a: uint64x1_t) -> float64x1_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf, N = 2))]
@@ -3009,6 +3509,8 @@ pub unsafe fn vcvtq_n_f64_u64<const N: i32>(a: uint64x2_t) -> float64x2_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_f32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf, N = 2))]
@@ -3025,6 +3527,8 @@ pub unsafe fn vcvts_n_f32_u32<const N: i32>(a: u32) -> f32 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf, N = 2))]
@@ -3041,6 +3545,8 @@ pub unsafe fn vcvtd_n_f64_u64<const N: i32>(a: u64) -> f64 {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
@@ -3057,6 +3563,8 @@ pub unsafe fn vcvt_n_s64_f64<const N: i32>(a: float64x1_t) -> int64x1_t {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
@@ -3073,6 +3581,8 @@ pub unsafe fn vcvtq_n_s64_f64<const N: i32>(a: float64x2_t) -> int64x2_t {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
@@ -3089,6 +3599,8 @@ pub unsafe fn vcvts_n_s32_f32<const N: i32>(a: f32) -> i32 {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
@@ -3105,6 +3617,8 @@ pub unsafe fn vcvtd_n_s64_f64<const N: i32>(a: f64) -> i64 {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
@@ -3121,6 +3635,8 @@ pub unsafe fn vcvt_n_u64_f64<const N: i32>(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
@@ -3137,6 +3653,8 @@ pub unsafe fn vcvtq_n_u64_f64<const N: i32>(a: float64x2_t) -> uint64x2_t {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
@@ -3153,6 +3671,8 @@ pub unsafe fn vcvts_n_u32_f32<const N: i32>(a: f32) -> u32 {
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
@@ -3169,6 +3689,8 @@ pub unsafe fn vcvtd_n_u64_f64<const N: i32>(a: f64) -> u64 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_f32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf))]
@@ -3178,6 +3700,8 @@ pub unsafe fn vcvts_f32_s32(a: i32) -> f32 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(scvtf))]
@@ -3187,6 +3711,8 @@ pub unsafe fn vcvtd_f64_s64(a: i64) -> f64 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_f32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf))]
@@ -3196,6 +3722,8 @@ pub unsafe fn vcvts_f32_u32(a: u32) -> f32 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ucvtf))]
@@ -3205,6 +3733,8 @@ pub unsafe fn vcvtd_f64_u64(a: u64) -> f64 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs))]
@@ -3214,6 +3744,8 @@ pub unsafe fn vcvts_s32_f32(a: f32) -> i32 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs))]
@@ -3223,6 +3755,8 @@ pub unsafe fn vcvtd_s64_f64(a: f64) -> i64 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu))]
@@ -3232,6 +3766,8 @@ pub unsafe fn vcvts_u32_f32(a: f32) -> u32 {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu))]
@@ -3241,6 +3777,8 @@ pub unsafe fn vcvtd_u64_f64(a: f64) -> u64 {
}
/// Floating-point convert to signed fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs))]
@@ -3255,6 +3793,8 @@ pub unsafe fn vcvt_s64_f64(a: float64x1_t) -> int64x1_t {
}
/// Floating-point convert to signed fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzs))]
@@ -3269,6 +3809,8 @@ pub unsafe fn vcvtq_s64_f64(a: float64x2_t) -> int64x2_t {
}
/// Floating-point convert to unsigned fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu))]
@@ -3283,6 +3825,8 @@ pub unsafe fn vcvt_u64_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point convert to unsigned fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtzu))]
@@ -3297,6 +3841,8 @@ pub unsafe fn vcvtq_u64_f64(a: float64x2_t) -> uint64x2_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtas))]
@@ -3311,6 +3857,8 @@ pub unsafe fn vcvta_s32_f32(a: float32x2_t) -> int32x2_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtas))]
@@ -3325,6 +3873,8 @@ pub unsafe fn vcvtaq_s32_f32(a: float32x4_t) -> int32x4_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtas))]
@@ -3339,6 +3889,8 @@ pub unsafe fn vcvta_s64_f64(a: float64x1_t) -> int64x1_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtas))]
@@ -3353,6 +3905,8 @@ pub unsafe fn vcvtaq_s64_f64(a: float64x2_t) -> int64x2_t {
}
/// Floating-point convert to integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtas_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtas))]
@@ -3367,6 +3921,8 @@ pub unsafe fn vcvtas_s32_f32(a: f32) -> i32 {
}
/// Floating-point convert to integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtad_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtas))]
@@ -3381,6 +3937,8 @@ pub unsafe fn vcvtad_s64_f64(a: f64) -> i64 {
}
/// Floating-point convert to integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtas_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtau))]
@@ -3395,6 +3953,8 @@ pub unsafe fn vcvtas_u32_f32(a: f32) -> u32 {
}
/// Floating-point convert to integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtad_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtau))]
@@ -3409,6 +3969,8 @@ pub unsafe fn vcvtad_u64_f64(a: f64) -> u64 {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtns))]
@@ -3423,6 +3985,8 @@ pub unsafe fn vcvtn_s32_f32(a: float32x2_t) -> int32x2_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtns))]
@@ -3437,6 +4001,8 @@ pub unsafe fn vcvtnq_s32_f32(a: float32x4_t) -> int32x4_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtns))]
@@ -3451,6 +4017,8 @@ pub unsafe fn vcvtn_s64_f64(a: float64x1_t) -> int64x1_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtns))]
@@ -3465,6 +4033,8 @@ pub unsafe fn vcvtnq_s64_f64(a: float64x2_t) -> int64x2_t {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtns_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtns))]
@@ -3479,6 +4049,8 @@ pub unsafe fn vcvtns_s32_f32(a: f32) -> i32 {
}
/// Floating-point convert to signed integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnd_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtns))]
@@ -3493,6 +4065,8 @@ pub unsafe fn vcvtnd_s64_f64(a: f64) -> i64 {
}
/// Floating-point convert to signed integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtms))]
@@ -3507,6 +4081,8 @@ pub unsafe fn vcvtm_s32_f32(a: float32x2_t) -> int32x2_t {
}
/// Floating-point convert to signed integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtms))]
@@ -3521,6 +4097,8 @@ pub unsafe fn vcvtmq_s32_f32(a: float32x4_t) -> int32x4_t {
}
/// Floating-point convert to signed integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtms))]
@@ -3535,6 +4113,8 @@ pub unsafe fn vcvtm_s64_f64(a: float64x1_t) -> int64x1_t {
}
/// Floating-point convert to signed integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtms))]
@@ -3549,6 +4129,8 @@ pub unsafe fn vcvtmq_s64_f64(a: float64x2_t) -> int64x2_t {
}
/// Floating-point convert to signed integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtms_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtms))]
@@ -3563,6 +4145,8 @@ pub unsafe fn vcvtms_s32_f32(a: f32) -> i32 {
}
/// Floating-point convert to signed integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmd_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtms))]
@@ -3577,6 +4161,8 @@ pub unsafe fn vcvtmd_s64_f64(a: f64) -> i64 {
}
/// Floating-point convert to signed integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtps))]
@@ -3591,6 +4177,8 @@ pub unsafe fn vcvtp_s32_f32(a: float32x2_t) -> int32x2_t {
}
/// Floating-point convert to signed integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtps))]
@@ -3605,6 +4193,8 @@ pub unsafe fn vcvtpq_s32_f32(a: float32x4_t) -> int32x4_t {
}
/// Floating-point convert to signed integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtps))]
@@ -3619,6 +4209,8 @@ pub unsafe fn vcvtp_s64_f64(a: float64x1_t) -> int64x1_t {
}
/// Floating-point convert to signed integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtps))]
@@ -3633,6 +4225,8 @@ pub unsafe fn vcvtpq_s64_f64(a: float64x2_t) -> int64x2_t {
}
/// Floating-point convert to signed integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtps_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtps))]
@@ -3647,6 +4241,8 @@ pub unsafe fn vcvtps_s32_f32(a: f32) -> i32 {
}
/// Floating-point convert to signed integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpd_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtps))]
@@ -3661,6 +4257,8 @@ pub unsafe fn vcvtpd_s64_f64(a: f64) -> i64 {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtau))]
@@ -3675,6 +4273,8 @@ pub unsafe fn vcvta_u32_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtau))]
@@ -3689,6 +4289,8 @@ pub unsafe fn vcvtaq_u32_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtau))]
@@ -3703,6 +4305,8 @@ pub unsafe fn vcvta_u64_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtau))]
@@ -3717,6 +4321,8 @@ pub unsafe fn vcvtaq_u64_f64(a: float64x2_t) -> uint64x2_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtnu))]
@@ -3731,6 +4337,8 @@ pub unsafe fn vcvtn_u32_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtnu))]
@@ -3745,6 +4353,8 @@ pub unsafe fn vcvtnq_u32_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtnu))]
@@ -3759,6 +4369,8 @@ pub unsafe fn vcvtn_u64_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtnu))]
@@ -3773,6 +4385,8 @@ pub unsafe fn vcvtnq_u64_f64(a: float64x2_t) -> uint64x2_t {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtns_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtnu))]
@@ -3787,6 +4401,8 @@ pub unsafe fn vcvtns_u32_f32(a: f32) -> u32 {
}
/// Floating-point convert to unsigned integer, rounding to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnd_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtnu))]
@@ -3801,6 +4417,8 @@ pub unsafe fn vcvtnd_u64_f64(a: f64) -> u64 {
}
/// Floating-point convert to unsigned integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtmu))]
@@ -3815,6 +4433,8 @@ pub unsafe fn vcvtm_u32_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point convert to unsigned integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtmu))]
@@ -3829,6 +4449,8 @@ pub unsafe fn vcvtmq_u32_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point convert to unsigned integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtmu))]
@@ -3843,6 +4465,8 @@ pub unsafe fn vcvtm_u64_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point convert to unsigned integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtmu))]
@@ -3857,6 +4481,8 @@ pub unsafe fn vcvtmq_u64_f64(a: float64x2_t) -> uint64x2_t {
}
/// Floating-point convert to unsigned integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtms_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtmu))]
@@ -3871,6 +4497,8 @@ pub unsafe fn vcvtms_u32_f32(a: f32) -> u32 {
}
/// Floating-point convert to unsigned integer, rounding toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmd_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtmu))]
@@ -3885,6 +4513,8 @@ pub unsafe fn vcvtmd_u64_f64(a: f64) -> u64 {
}
/// Floating-point convert to unsigned integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtpu))]
@@ -3899,6 +4529,8 @@ pub unsafe fn vcvtp_u32_f32(a: float32x2_t) -> uint32x2_t {
}
/// Floating-point convert to unsigned integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtpu))]
@@ -3913,6 +4545,8 @@ pub unsafe fn vcvtpq_u32_f32(a: float32x4_t) -> uint32x4_t {
}
/// Floating-point convert to unsigned integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtpu))]
@@ -3927,6 +4561,8 @@ pub unsafe fn vcvtp_u64_f64(a: float64x1_t) -> uint64x1_t {
}
/// Floating-point convert to unsigned integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtpu))]
@@ -3941,6 +4577,8 @@ pub unsafe fn vcvtpq_u64_f64(a: float64x2_t) -> uint64x2_t {
}
/// Floating-point convert to unsigned integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtps_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtpu))]
@@ -3955,6 +4593,8 @@ pub unsafe fn vcvtps_u32_f32(a: f32) -> u32 {
}
/// Floating-point convert to unsigned integer, rounding toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpd_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fcvtpu))]
@@ -3969,6 +4609,8 @@ pub unsafe fn vcvtpd_u64_f64(a: f64) -> u64 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(dup, N = 1))]
@@ -3980,6 +4622,8 @@ pub unsafe fn vdupq_laneq_p64<const N: i32>(a: poly64x2_t) -> poly64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(dup, N = 0))]
@@ -3991,6 +4635,8 @@ pub unsafe fn vdupq_lane_p64<const N: i32>(a: poly64x1_t) -> poly64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(dup, N = 1))]
@@ -4002,6 +4648,8 @@ pub unsafe fn vdupq_laneq_f64<const N: i32>(a: float64x2_t) -> float64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(dup, N = 0))]
@@ -4013,6 +4661,8 @@ pub unsafe fn vdupq_lane_f64<const N: i32>(a: float64x1_t) -> float64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 0))]
@@ -4024,6 +4674,8 @@ pub unsafe fn vdup_lane_p64<const N: i32>(a: poly64x1_t) -> poly64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 0))]
@@ -4035,6 +4687,8 @@ pub unsafe fn vdup_lane_f64<const N: i32>(a: float64x1_t) -> float64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4046,6 +4700,8 @@ pub unsafe fn vdup_laneq_p64<const N: i32>(a: poly64x2_t) -> poly64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4057,6 +4713,8 @@ pub unsafe fn vdup_laneq_f64<const N: i32>(a: float64x2_t) -> float64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 4))]
@@ -4068,6 +4726,8 @@ pub unsafe fn vdupb_lane_s8<const N: i32>(a: int8x8_t) -> i8 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_laneq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 8))]
@@ -4079,6 +4739,8 @@ pub unsafe fn vdupb_laneq_s8<const N: i32>(a: int8x16_t) -> i8 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 2))]
@@ -4090,6 +4752,8 @@ pub unsafe fn vduph_lane_s16<const N: i32>(a: int16x4_t) -> i16 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 4))]
@@ -4101,6 +4765,8 @@ pub unsafe fn vduph_laneq_s16<const N: i32>(a: int16x8_t) -> i16 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4112,6 +4778,8 @@ pub unsafe fn vdups_lane_s32<const N: i32>(a: int32x2_t) -> i32 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 2))]
@@ -4123,6 +4791,8 @@ pub unsafe fn vdups_laneq_s32<const N: i32>(a: int32x4_t) -> i32 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 0))]
@@ -4134,6 +4804,8 @@ pub unsafe fn vdupd_lane_s64<const N: i32>(a: int64x1_t) -> i64 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_laneq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4145,6 +4817,8 @@ pub unsafe fn vdupd_laneq_s64<const N: i32>(a: int64x2_t) -> i64 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 4))]
@@ -4156,6 +4830,8 @@ pub unsafe fn vdupb_lane_u8<const N: i32>(a: uint8x8_t) -> u8 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_laneq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 8))]
@@ -4167,6 +4843,8 @@ pub unsafe fn vdupb_laneq_u8<const N: i32>(a: uint8x16_t) -> u8 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 2))]
@@ -4178,6 +4856,8 @@ pub unsafe fn vduph_lane_u16<const N: i32>(a: uint16x4_t) -> u16 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 4))]
@@ -4189,6 +4869,8 @@ pub unsafe fn vduph_laneq_u16<const N: i32>(a: uint16x8_t) -> u16 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4200,6 +4882,8 @@ pub unsafe fn vdups_lane_u32<const N: i32>(a: uint32x2_t) -> u32 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 2))]
@@ -4211,6 +4895,8 @@ pub unsafe fn vdups_laneq_u32<const N: i32>(a: uint32x4_t) -> u32 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 0))]
@@ -4222,6 +4908,8 @@ pub unsafe fn vdupd_lane_u64<const N: i32>(a: uint64x1_t) -> u64 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_laneq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4233,6 +4921,8 @@ pub unsafe fn vdupd_laneq_u64<const N: i32>(a: uint64x2_t) -> u64 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 4))]
@@ -4244,6 +4934,8 @@ pub unsafe fn vdupb_lane_p8<const N: i32>(a: poly8x8_t) -> p8 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_laneq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 8))]
@@ -4255,6 +4947,8 @@ pub unsafe fn vdupb_laneq_p8<const N: i32>(a: poly8x16_t) -> p8 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 2))]
@@ -4266,6 +4960,8 @@ pub unsafe fn vduph_lane_p16<const N: i32>(a: poly16x4_t) -> p16 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 4))]
@@ -4277,6 +4973,8 @@ pub unsafe fn vduph_laneq_p16<const N: i32>(a: poly16x8_t) -> p16 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4288,6 +4986,8 @@ pub unsafe fn vdups_lane_f32<const N: i32>(a: float32x2_t) -> f32 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 2))]
@@ -4299,6 +4999,8 @@ pub unsafe fn vdups_laneq_f32<const N: i32>(a: float32x4_t) -> f32 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 0))]
@@ -4310,6 +5012,8 @@ pub unsafe fn vdupd_lane_f64<const N: i32>(a: float64x1_t) -> f64 {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, N = 1))]
@@ -4321,6 +5025,8 @@ pub unsafe fn vdupd_laneq_f64<const N: i32>(a: float64x2_t) -> f64 {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ext, N = 1))]
@@ -4336,6 +5042,8 @@ pub unsafe fn vextq_p64<const N: i32>(a: poly64x2_t, b: poly64x2_t) -> poly64x2_
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ext, N = 1))]
@@ -4351,6 +5059,8 @@ pub unsafe fn vextq_f64<const N: i32>(a: float64x2_t, b: float64x2_t) -> float64
}
/// Floating-point multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -4360,6 +5070,8 @@ pub unsafe fn vmla_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float6
}
/// Floating-point multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -4369,6 +5081,8 @@ pub unsafe fn vmlaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float
}
/// Signed multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2))]
@@ -4380,6 +5094,8 @@ pub unsafe fn vmlal_high_s8(a: int16x8_t, b: int8x16_t, c: int8x16_t) -> int16x8
}
/// Signed multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2))]
@@ -4391,6 +5107,8 @@ pub unsafe fn vmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x
}
/// Signed multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2))]
@@ -4402,6 +5120,8 @@ pub unsafe fn vmlal_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x
}
/// Unsigned multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2))]
@@ -4413,6 +5133,8 @@ pub unsafe fn vmlal_high_u8(a: uint16x8_t, b: uint8x16_t, c: uint8x16_t) -> uint
}
/// Unsigned multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2))]
@@ -4424,6 +5146,8 @@ pub unsafe fn vmlal_high_u16(a: uint32x4_t, b: uint16x8_t, c: uint16x8_t) -> uin
}
/// Unsigned multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2))]
@@ -4435,6 +5159,8 @@ pub unsafe fn vmlal_high_u32(a: uint64x2_t, b: uint32x4_t, c: uint32x4_t) -> uin
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2))]
@@ -4444,6 +5170,8 @@ pub unsafe fn vmlal_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_t
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2))]
@@ -4453,6 +5181,8 @@ pub unsafe fn vmlal_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_t
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2))]
@@ -4462,6 +5192,8 @@ pub unsafe fn vmlal_high_n_u16(a: uint32x4_t, b: uint16x8_t, c: u16) -> uint32x4
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2))]
@@ -4471,6 +5203,8 @@ pub unsafe fn vmlal_high_n_u32(a: uint64x2_t, b: uint32x4_t, c: u32) -> uint64x2
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
@@ -4482,6 +5216,8 @@ pub unsafe fn vmlal_high_lane_s16<const LANE: i32>(a: int32x4_t, b: int16x8_t, c
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
@@ -4493,6 +5229,8 @@ pub unsafe fn vmlal_high_laneq_s16<const LANE: i32>(a: int32x4_t, b: int16x8_t,
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
@@ -4504,6 +5242,8 @@ pub unsafe fn vmlal_high_lane_s32<const LANE: i32>(a: int64x2_t, b: int32x4_t, c
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
@@ -4515,6 +5255,8 @@ pub unsafe fn vmlal_high_laneq_s32<const LANE: i32>(a: int64x2_t, b: int32x4_t,
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
@@ -4526,6 +5268,8 @@ pub unsafe fn vmlal_high_lane_u16<const LANE: i32>(a: uint32x4_t, b: uint16x8_t,
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
@@ -4537,6 +5281,8 @@ pub unsafe fn vmlal_high_laneq_u16<const LANE: i32>(a: uint32x4_t, b: uint16x8_t
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
@@ -4548,6 +5294,8 @@ pub unsafe fn vmlal_high_lane_u32<const LANE: i32>(a: uint64x2_t, b: uint32x4_t,
}
/// Multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
@@ -4559,6 +5307,8 @@ pub unsafe fn vmlal_high_laneq_u32<const LANE: i32>(a: uint64x2_t, b: uint32x4_t
}
/// Floating-point multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -4568,6 +5318,8 @@ pub unsafe fn vmls_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float6
}
/// Floating-point multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -4577,6 +5329,8 @@ pub unsafe fn vmlsq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float
}
/// Signed multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2))]
@@ -4588,6 +5342,8 @@ pub unsafe fn vmlsl_high_s8(a: int16x8_t, b: int8x16_t, c: int8x16_t) -> int16x8
}
/// Signed multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2))]
@@ -4599,6 +5355,8 @@ pub unsafe fn vmlsl_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x
}
/// Signed multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2))]
@@ -4610,6 +5368,8 @@ pub unsafe fn vmlsl_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x
}
/// Unsigned multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2))]
@@ -4621,6 +5381,8 @@ pub unsafe fn vmlsl_high_u8(a: uint16x8_t, b: uint8x16_t, c: uint8x16_t) -> uint
}
/// Unsigned multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2))]
@@ -4632,6 +5394,8 @@ pub unsafe fn vmlsl_high_u16(a: uint32x4_t, b: uint16x8_t, c: uint16x8_t) -> uin
}
/// Unsigned multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2))]
@@ -4643,6 +5407,8 @@ pub unsafe fn vmlsl_high_u32(a: uint64x2_t, b: uint32x4_t, c: uint32x4_t) -> uin
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2))]
@@ -4652,6 +5418,8 @@ pub unsafe fn vmlsl_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_t
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2))]
@@ -4661,6 +5429,8 @@ pub unsafe fn vmlsl_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_t
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2))]
@@ -4670,6 +5440,8 @@ pub unsafe fn vmlsl_high_n_u16(a: uint32x4_t, b: uint16x8_t, c: u16) -> uint32x4
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2))]
@@ -4679,6 +5451,8 @@ pub unsafe fn vmlsl_high_n_u32(a: uint64x2_t, b: uint32x4_t, c: u32) -> uint64x2
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
@@ -4690,6 +5464,8 @@ pub unsafe fn vmlsl_high_lane_s16<const LANE: i32>(a: int32x4_t, b: int16x8_t, c
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
@@ -4701,6 +5477,8 @@ pub unsafe fn vmlsl_high_laneq_s16<const LANE: i32>(a: int32x4_t, b: int16x8_t,
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
@@ -4712,6 +5490,8 @@ pub unsafe fn vmlsl_high_lane_s32<const LANE: i32>(a: int64x2_t, b: int32x4_t, c
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
@@ -4723,6 +5503,8 @@ pub unsafe fn vmlsl_high_laneq_s32<const LANE: i32>(a: int64x2_t, b: int32x4_t,
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
@@ -4734,6 +5516,8 @@ pub unsafe fn vmlsl_high_lane_u16<const LANE: i32>(a: uint32x4_t, b: uint16x8_t,
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
@@ -4745,6 +5529,8 @@ pub unsafe fn vmlsl_high_laneq_u16<const LANE: i32>(a: uint32x4_t, b: uint16x8_t
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
@@ -4756,6 +5542,8 @@ pub unsafe fn vmlsl_high_lane_u32<const LANE: i32>(a: uint64x2_t, b: uint32x4_t,
}
/// Multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
@@ -4767,6 +5555,8 @@ pub unsafe fn vmlsl_high_laneq_u32<const LANE: i32>(a: uint64x2_t, b: uint32x4_t
}
/// Extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(xtn2))]
@@ -4777,6 +5567,8 @@ pub unsafe fn vmovn_high_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
}
/// Extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(xtn2))]
@@ -4787,6 +5579,8 @@ pub unsafe fn vmovn_high_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t {
}
/// Extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(xtn2))]
@@ -4797,6 +5591,8 @@ pub unsafe fn vmovn_high_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t {
}
/// Extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(xtn2))]
@@ -4807,6 +5603,8 @@ pub unsafe fn vmovn_high_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_t {
}
/// Extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(xtn2))]
@@ -4817,6 +5615,8 @@ pub unsafe fn vmovn_high_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8_t {
}
/// Extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(xtn2))]
@@ -4827,6 +5627,8 @@ pub unsafe fn vmovn_high_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(neg))]
@@ -4836,6 +5638,8 @@ pub unsafe fn vneg_s64(a: int64x1_t) -> int64x1_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(neg))]
@@ -4845,6 +5649,8 @@ pub unsafe fn vnegq_s64(a: int64x2_t) -> int64x2_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(neg))]
@@ -4854,6 +5660,8 @@ pub unsafe fn vnegd_s64(a: i64) -> i64 {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fneg))]
@@ -4863,6 +5671,8 @@ pub unsafe fn vneg_f64(a: float64x1_t) -> float64x1_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fneg))]
@@ -4872,6 +5682,8 @@ pub unsafe fn vnegq_f64(a: float64x2_t) -> float64x2_t {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqneg))]
@@ -4886,6 +5698,8 @@ pub unsafe fn vqneg_s64(a: int64x1_t) -> int64x1_t {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqneg))]
@@ -4900,6 +5714,8 @@ pub unsafe fn vqnegq_s64(a: int64x2_t) -> int64x2_t {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqneg))]
@@ -4909,6 +5725,8 @@ pub unsafe fn vqnegb_s8(a: i8) -> i8 {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqneg))]
@@ -4918,6 +5736,8 @@ pub unsafe fn vqnegh_s16(a: i16) -> i16 {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegs_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqneg))]
@@ -4927,6 +5747,8 @@ pub unsafe fn vqnegs_s32(a: i32) -> i32 {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqneg))]
@@ -4936,6 +5758,8 @@ pub unsafe fn vqnegd_s64(a: i64) -> i64 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqsub))]
@@ -4947,6 +5771,8 @@ pub unsafe fn vqsubb_s8(a: i8, b: i8) -> i8 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqsub))]
@@ -4958,6 +5784,8 @@ pub unsafe fn vqsubh_s16(a: i16, b: i16) -> i16 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubb_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqsub))]
@@ -4969,6 +5797,8 @@ pub unsafe fn vqsubb_u8(a: u8, b: u8) -> u8 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubh_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqsub))]
@@ -4980,6 +5810,8 @@ pub unsafe fn vqsubh_u16(a: u16, b: u16) -> u16 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubs_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqsub))]
@@ -4994,6 +5826,8 @@ pub unsafe fn vqsubs_u32(a: u32, b: u32) -> u32 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqsub))]
@@ -5008,6 +5842,8 @@ pub unsafe fn vqsubd_u64(a: u64, b: u64) -> u64 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubs_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqsub))]
@@ -5022,6 +5858,8 @@ pub unsafe fn vqsubs_s32(a: i32, b: i32) -> i32 {
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqsub))]
@@ -5036,6 +5874,8 @@ pub unsafe fn vqsubd_s64(a: i64, b: i64) -> i64 {
}
/// Reverse bit order
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rbit))]
@@ -5050,6 +5890,8 @@ pub unsafe fn vrbit_s8(a: int8x8_t) -> int8x8_t {
}
/// Reverse bit order
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rbit))]
@@ -5064,6 +5906,8 @@ pub unsafe fn vrbitq_s8(a: int8x16_t) -> int8x16_t {
}
/// Reverse bit order
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rbit))]
@@ -5073,6 +5917,8 @@ pub unsafe fn vrbit_u8(a: uint8x8_t) -> uint8x8_t {
}
/// Reverse bit order
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rbit))]
@@ -5082,6 +5928,8 @@ pub unsafe fn vrbitq_u8(a: uint8x16_t) -> uint8x16_t {
}
/// Reverse bit order
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rbit))]
@@ -5091,6 +5939,8 @@ pub unsafe fn vrbit_p8(a: poly8x8_t) -> poly8x8_t {
}
/// Reverse bit order
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rbit))]
@@ -5100,6 +5950,8 @@ pub unsafe fn vrbitq_p8(a: poly8x16_t) -> poly8x16_t {
}
/// Floating-point round to integral exact, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintx))]
@@ -5114,6 +5966,8 @@ pub unsafe fn vrndx_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to integral exact, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintx))]
@@ -5128,6 +5982,8 @@ pub unsafe fn vrndxq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to integral exact, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintx))]
@@ -5142,6 +5998,8 @@ pub unsafe fn vrndx_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral exact, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintx))]
@@ -5156,6 +6014,8 @@ pub unsafe fn vrndxq_f64(a: float64x2_t) -> float64x2_t {
}
/// Floating-point round to integral, to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnda_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinta))]
@@ -5170,6 +6030,8 @@ pub unsafe fn vrnda_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to integral, to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndaq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinta))]
@@ -5184,6 +6046,8 @@ pub unsafe fn vrndaq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to integral, to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnda_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinta))]
@@ -5198,6 +6062,8 @@ pub unsafe fn vrnda_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral, to nearest with ties to away
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndaq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinta))]
@@ -5212,6 +6078,8 @@ pub unsafe fn vrndaq_f64(a: float64x2_t) -> float64x2_t {
}
/// Floating-point round to integral, to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintn))]
@@ -5226,6 +6094,8 @@ pub unsafe fn vrndn_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral, to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndnq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintn))]
@@ -5240,6 +6110,8 @@ pub unsafe fn vrndnq_f64(a: float64x2_t) -> float64x2_t {
}
/// Floating-point round to integral, to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndns_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintn))]
@@ -5254,6 +6126,8 @@ pub unsafe fn vrndns_f32(a: f32) -> f32 {
}
/// Floating-point round to integral, toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndm_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintm))]
@@ -5268,6 +6142,8 @@ pub unsafe fn vrndm_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to integral, toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndmq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintm))]
@@ -5282,6 +6158,8 @@ pub unsafe fn vrndmq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to integral, toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndm_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintm))]
@@ -5296,6 +6174,8 @@ pub unsafe fn vrndm_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral, toward minus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndmq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintm))]
@@ -5310,6 +6190,8 @@ pub unsafe fn vrndmq_f64(a: float64x2_t) -> float64x2_t {
}
/// Floating-point round to integral, toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndp_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintp))]
@@ -5324,6 +6206,8 @@ pub unsafe fn vrndp_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to integral, toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndpq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintp))]
@@ -5338,6 +6222,8 @@ pub unsafe fn vrndpq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to integral, toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndp_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintp))]
@@ -5352,6 +6238,8 @@ pub unsafe fn vrndp_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral, toward plus infinity
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndpq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintp))]
@@ -5366,6 +6254,8 @@ pub unsafe fn vrndpq_f64(a: float64x2_t) -> float64x2_t {
}
/// Floating-point round to integral, toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintz))]
@@ -5380,6 +6270,8 @@ pub unsafe fn vrnd_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to integral, toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintz))]
@@ -5394,6 +6286,8 @@ pub unsafe fn vrndq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to integral, toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintz))]
@@ -5408,6 +6302,8 @@ pub unsafe fn vrnd_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral, toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frintz))]
@@ -5422,6 +6318,8 @@ pub unsafe fn vrndq_f64(a: float64x2_t) -> float64x2_t {
}
/// Floating-point round to integral, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinti))]
@@ -5436,6 +6334,8 @@ pub unsafe fn vrndi_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to integral, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndiq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinti))]
@@ -5450,6 +6350,8 @@ pub unsafe fn vrndiq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to integral, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinti))]
@@ -5464,6 +6366,8 @@ pub unsafe fn vrndi_f64(a: float64x1_t) -> float64x1_t {
}
/// Floating-point round to integral, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndiq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frinti))]
@@ -5478,6 +6382,8 @@ pub unsafe fn vrndiq_f64(a: float64x2_t) -> float64x2_t {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqadd))]
@@ -5489,6 +6395,8 @@ pub unsafe fn vqaddb_s8(a: i8, b: i8) -> i8 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqadd))]
@@ -5500,6 +6408,8 @@ pub unsafe fn vqaddh_s16(a: i16, b: i16) -> i16 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddb_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqadd))]
@@ -5511,6 +6421,8 @@ pub unsafe fn vqaddb_u8(a: u8, b: u8) -> u8 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddh_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqadd))]
@@ -5522,6 +6434,8 @@ pub unsafe fn vqaddh_u16(a: u16, b: u16) -> u16 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadds_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqadd))]
@@ -5536,6 +6450,8 @@ pub unsafe fn vqadds_u32(a: u32, b: u32) -> u32 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqadd))]
@@ -5550,6 +6466,8 @@ pub unsafe fn vqaddd_u64(a: u64, b: u64) -> u64 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadds_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqadd))]
@@ -5564,6 +6482,8 @@ pub unsafe fn vqadds_s32(a: i32, b: i32) -> i32 {
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqadd))]
@@ -5578,6 +6498,8 @@ pub unsafe fn vqaddd_s64(a: i64, b: i64) -> i64 {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld1))]
@@ -5592,6 +6514,8 @@ pub unsafe fn vld1_f64_x2(a: *const f64) -> float64x1x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld1))]
@@ -5606,6 +6530,8 @@ pub unsafe fn vld1q_f64_x2(a: *const f64) -> float64x2x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld1))]
@@ -5620,6 +6546,8 @@ pub unsafe fn vld1_f64_x3(a: *const f64) -> float64x1x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld1))]
@@ -5634,6 +6562,8 @@ pub unsafe fn vld1q_f64_x3(a: *const f64) -> float64x2x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld1))]
@@ -5648,6 +6578,8 @@ pub unsafe fn vld1_f64_x4(a: *const f64) -> float64x1x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld1))]
@@ -5662,6 +6594,8 @@ pub unsafe fn vld1q_f64_x4(a: *const f64) -> float64x2x4_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2))]
@@ -5676,6 +6610,8 @@ pub unsafe fn vld2q_s64(a: *const i64) -> int64x2x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2))]
@@ -5685,6 +6621,8 @@ pub unsafe fn vld2q_u64(a: *const u64) -> uint64x2x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld2))]
@@ -5694,6 +6632,8 @@ pub unsafe fn vld2q_p64(a: *const p64) -> poly64x2x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -5708,6 +6648,8 @@ pub unsafe fn vld2_f64(a: *const f64) -> float64x1x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2))]
@@ -5722,6 +6664,8 @@ pub unsafe fn vld2q_f64(a: *const f64) -> float64x2x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2r))]
@@ -5736,6 +6680,8 @@ pub unsafe fn vld2q_dup_s64(a: *const i64) -> int64x2x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2r))]
@@ -5745,6 +6691,8 @@ pub unsafe fn vld2q_dup_u64(a: *const u64) -> uint64x2x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld2r))]
@@ -5754,6 +6702,8 @@ pub unsafe fn vld2q_dup_p64(a: *const p64) -> poly64x2x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2r))]
@@ -5768,6 +6718,8 @@ pub unsafe fn vld2_dup_f64(a: *const f64) -> float64x1x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2r))]
@@ -5782,6 +6734,8 @@ pub unsafe fn vld2q_dup_f64(a: *const f64) -> float64x2x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5798,6 +6752,8 @@ pub unsafe fn vld2q_lane_s8<const LANE: i32>(a: *const i8, b: int8x16x2_t) -> in
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5814,6 +6770,8 @@ pub unsafe fn vld2_lane_s64<const LANE: i32>(a: *const i64, b: int64x1x2_t) -> i
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5830,6 +6788,8 @@ pub unsafe fn vld2q_lane_s64<const LANE: i32>(a: *const i64, b: int64x2x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5841,6 +6801,8 @@ pub unsafe fn vld2_lane_p64<const LANE: i32>(a: *const p64, b: poly64x1x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5852,6 +6814,8 @@ pub unsafe fn vld2q_lane_p64<const LANE: i32>(a: *const p64, b: poly64x2x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5863,6 +6827,8 @@ pub unsafe fn vld2q_lane_u8<const LANE: i32>(a: *const u8, b: uint8x16x2_t) -> u
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5874,6 +6840,8 @@ pub unsafe fn vld2_lane_u64<const LANE: i32>(a: *const u64, b: uint64x1x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5885,6 +6853,8 @@ pub unsafe fn vld2q_lane_u64<const LANE: i32>(a: *const u64, b: uint64x2x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5896,6 +6866,8 @@ pub unsafe fn vld2q_lane_p8<const LANE: i32>(a: *const p8, b: poly8x16x2_t) -> p
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5912,6 +6884,8 @@ pub unsafe fn vld2_lane_f64<const LANE: i32>(a: *const f64, b: float64x1x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld2, LANE = 0))]
@@ -5928,6 +6902,8 @@ pub unsafe fn vld2q_lane_f64<const LANE: i32>(a: *const f64, b: float64x2x2_t) -
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3))]
@@ -5942,6 +6918,8 @@ pub unsafe fn vld3q_s64(a: *const i64) -> int64x2x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3))]
@@ -5951,6 +6929,8 @@ pub unsafe fn vld3q_u64(a: *const u64) -> uint64x2x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld3))]
@@ -5960,6 +6940,8 @@ pub unsafe fn vld3q_p64(a: *const p64) -> poly64x2x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -5974,6 +6956,8 @@ pub unsafe fn vld3_f64(a: *const f64) -> float64x1x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3))]
@@ -5988,6 +6972,8 @@ pub unsafe fn vld3q_f64(a: *const f64) -> float64x2x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3r))]
@@ -6002,6 +6988,8 @@ pub unsafe fn vld3q_dup_s64(a: *const i64) -> int64x2x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3r))]
@@ -6011,6 +6999,8 @@ pub unsafe fn vld3q_dup_u64(a: *const u64) -> uint64x2x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld3r))]
@@ -6020,6 +7010,8 @@ pub unsafe fn vld3q_dup_p64(a: *const p64) -> poly64x2x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3r))]
@@ -6034,6 +7026,8 @@ pub unsafe fn vld3_dup_f64(a: *const f64) -> float64x1x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3r))]
@@ -6048,6 +7042,8 @@ pub unsafe fn vld3q_dup_f64(a: *const f64) -> float64x2x3_t {
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6064,6 +7060,8 @@ pub unsafe fn vld3q_lane_s8<const LANE: i32>(a: *const i8, b: int8x16x3_t) -> in
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6080,6 +7078,8 @@ pub unsafe fn vld3_lane_s64<const LANE: i32>(a: *const i64, b: int64x1x3_t) -> i
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6096,6 +7096,8 @@ pub unsafe fn vld3q_lane_s64<const LANE: i32>(a: *const i64, b: int64x2x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6107,6 +7109,8 @@ pub unsafe fn vld3_lane_p64<const LANE: i32>(a: *const p64, b: poly64x1x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6118,6 +7122,8 @@ pub unsafe fn vld3q_lane_p64<const LANE: i32>(a: *const p64, b: poly64x2x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6129,6 +7135,8 @@ pub unsafe fn vld3q_lane_p8<const LANE: i32>(a: *const p8, b: poly8x16x3_t) -> p
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6140,6 +7148,8 @@ pub unsafe fn vld3q_lane_u8<const LANE: i32>(a: *const u8, b: uint8x16x3_t) -> u
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6151,6 +7161,8 @@ pub unsafe fn vld3_lane_u64<const LANE: i32>(a: *const u64, b: uint64x1x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6162,6 +7174,8 @@ pub unsafe fn vld3q_lane_u64<const LANE: i32>(a: *const u64, b: uint64x2x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6178,6 +7192,8 @@ pub unsafe fn vld3_lane_f64<const LANE: i32>(a: *const f64, b: float64x1x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld3, LANE = 0))]
@@ -6194,6 +7210,8 @@ pub unsafe fn vld3q_lane_f64<const LANE: i32>(a: *const f64, b: float64x2x3_t) -
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4))]
@@ -6208,6 +7226,8 @@ pub unsafe fn vld4q_s64(a: *const i64) -> int64x2x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4))]
@@ -6217,6 +7237,8 @@ pub unsafe fn vld4q_u64(a: *const u64) -> uint64x2x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld4))]
@@ -6226,6 +7248,8 @@ pub unsafe fn vld4q_p64(a: *const p64) -> poly64x2x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -6240,6 +7264,8 @@ pub unsafe fn vld4_f64(a: *const f64) -> float64x1x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4))]
@@ -6254,6 +7280,8 @@ pub unsafe fn vld4q_f64(a: *const f64) -> float64x2x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4r))]
@@ -6268,6 +7296,8 @@ pub unsafe fn vld4q_dup_s64(a: *const i64) -> int64x2x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4r))]
@@ -6277,6 +7307,8 @@ pub unsafe fn vld4q_dup_u64(a: *const u64) -> uint64x2x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld4r))]
@@ -6286,6 +7318,8 @@ pub unsafe fn vld4q_dup_p64(a: *const p64) -> poly64x2x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4r))]
@@ -6300,6 +7334,8 @@ pub unsafe fn vld4_dup_f64(a: *const f64) -> float64x1x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4r))]
@@ -6314,6 +7350,8 @@ pub unsafe fn vld4q_dup_f64(a: *const f64) -> float64x2x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6330,6 +7368,8 @@ pub unsafe fn vld4q_lane_s8<const LANE: i32>(a: *const i8, b: int8x16x4_t) -> in
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6346,6 +7386,8 @@ pub unsafe fn vld4_lane_s64<const LANE: i32>(a: *const i64, b: int64x1x4_t) -> i
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6362,6 +7404,8 @@ pub unsafe fn vld4q_lane_s64<const LANE: i32>(a: *const i64, b: int64x2x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6373,6 +7417,8 @@ pub unsafe fn vld4_lane_p64<const LANE: i32>(a: *const p64, b: poly64x1x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6384,6 +7430,8 @@ pub unsafe fn vld4q_lane_p64<const LANE: i32>(a: *const p64, b: poly64x2x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6395,6 +7443,8 @@ pub unsafe fn vld4q_lane_p8<const LANE: i32>(a: *const p8, b: poly8x16x4_t) -> p
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6406,6 +7456,8 @@ pub unsafe fn vld4q_lane_u8<const LANE: i32>(a: *const u8, b: uint8x16x4_t) -> u
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6417,6 +7469,8 @@ pub unsafe fn vld4_lane_u64<const LANE: i32>(a: *const u64, b: uint64x1x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6428,6 +7482,8 @@ pub unsafe fn vld4q_lane_u64<const LANE: i32>(a: *const u64, b: uint64x2x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6444,6 +7500,8 @@ pub unsafe fn vld4_lane_f64<const LANE: i32>(a: *const f64, b: float64x1x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ld4, LANE = 0))]
@@ -6460,6 +7518,8 @@ pub unsafe fn vld4q_lane_f64<const LANE: i32>(a: *const f64, b: float64x2x4_t) -
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, LANE = 0))]
@@ -6471,6 +7531,8 @@ pub unsafe fn vst1_lane_f64<const LANE: i32>(a: *mut f64, b: float64x1_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, LANE = 0))]
@@ -6482,6 +7544,8 @@ pub unsafe fn vst1q_lane_f64<const LANE: i32>(a: *mut f64, b: float64x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6496,6 +7560,8 @@ pub unsafe fn vst1_f64_x2(a: *mut f64, b: float64x1x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6510,6 +7576,8 @@ pub unsafe fn vst1q_f64_x2(a: *mut f64, b: float64x2x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6524,6 +7592,8 @@ pub unsafe fn vst1_f64_x3(a: *mut f64, b: float64x1x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6538,6 +7608,8 @@ pub unsafe fn vst1q_f64_x3(a: *mut f64, b: float64x2x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6552,6 +7624,8 @@ pub unsafe fn vst1_f64_x4(a: *mut f64, b: float64x1x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6566,6 +7640,8 @@ pub unsafe fn vst1q_f64_x4(a: *mut f64, b: float64x2x4_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2))]
@@ -6580,6 +7656,8 @@ pub unsafe fn vst2q_s64(a: *mut i64, b: int64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2))]
@@ -6589,6 +7667,8 @@ pub unsafe fn vst2q_u64(a: *mut u64, b: uint64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st2))]
@@ -6598,6 +7678,8 @@ pub unsafe fn vst2q_p64(a: *mut p64, b: poly64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st1))]
@@ -6612,6 +7694,8 @@ pub unsafe fn vst2_f64(a: *mut f64, b: float64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2))]
@@ -6626,6 +7710,8 @@ pub unsafe fn vst2q_f64(a: *mut f64, b: float64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6642,6 +7728,8 @@ pub unsafe fn vst2q_lane_s8<const LANE: i32>(a: *mut i8, b: int8x16x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6658,6 +7746,8 @@ pub unsafe fn vst2_lane_s64<const LANE: i32>(a: *mut i64, b: int64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6674,6 +7764,8 @@ pub unsafe fn vst2q_lane_s64<const LANE: i32>(a: *mut i64, b: int64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6685,6 +7777,8 @@ pub unsafe fn vst2q_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x16x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6696,6 +7790,8 @@ pub unsafe fn vst2_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6707,6 +7803,8 @@ pub unsafe fn vst2q_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6718,6 +7816,8 @@ pub unsafe fn vst2q_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x16x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6729,6 +7829,8 @@ pub unsafe fn vst2_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6740,6 +7842,8 @@ pub unsafe fn vst2q_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6756,6 +7860,8 @@ pub unsafe fn vst2_lane_f64<const LANE: i32>(a: *mut f64, b: float64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st2, LANE = 0))]
@@ -6772,6 +7878,8 @@ pub unsafe fn vst2q_lane_f64<const LANE: i32>(a: *mut f64, b: float64x2x2_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3))]
@@ -6786,6 +7894,8 @@ pub unsafe fn vst3q_s64(a: *mut i64, b: int64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3))]
@@ -6795,6 +7905,8 @@ pub unsafe fn vst3q_u64(a: *mut u64, b: uint64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st3))]
@@ -6804,6 +7916,8 @@ pub unsafe fn vst3q_p64(a: *mut p64, b: poly64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -6818,6 +7932,8 @@ pub unsafe fn vst3_f64(a: *mut f64, b: float64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3))]
@@ -6832,6 +7948,8 @@ pub unsafe fn vst3q_f64(a: *mut f64, b: float64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6848,6 +7966,8 @@ pub unsafe fn vst3q_lane_s8<const LANE: i32>(a: *mut i8, b: int8x16x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6864,6 +7984,8 @@ pub unsafe fn vst3_lane_s64<const LANE: i32>(a: *mut i64, b: int64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6880,6 +8002,8 @@ pub unsafe fn vst3q_lane_s64<const LANE: i32>(a: *mut i64, b: int64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6891,6 +8015,8 @@ pub unsafe fn vst3q_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x16x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6902,6 +8028,8 @@ pub unsafe fn vst3_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6913,6 +8041,8 @@ pub unsafe fn vst3q_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6924,6 +8054,8 @@ pub unsafe fn vst3q_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x16x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6935,6 +8067,8 @@ pub unsafe fn vst3_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6946,6 +8080,8 @@ pub unsafe fn vst3q_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6962,6 +8098,8 @@ pub unsafe fn vst3_lane_f64<const LANE: i32>(a: *mut f64, b: float64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st3, LANE = 0))]
@@ -6978,6 +8116,8 @@ pub unsafe fn vst3q_lane_f64<const LANE: i32>(a: *mut f64, b: float64x2x3_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4))]
@@ -6992,6 +8132,8 @@ pub unsafe fn vst4q_s64(a: *mut i64, b: int64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4))]
@@ -7001,6 +8143,8 @@ pub unsafe fn vst4q_u64(a: *mut u64, b: uint64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st4))]
@@ -7010,6 +8154,8 @@ pub unsafe fn vst4q_p64(a: *mut p64, b: poly64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -7024,6 +8170,8 @@ pub unsafe fn vst4_f64(a: *mut f64, b: float64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4))]
@@ -7038,6 +8186,8 @@ pub unsafe fn vst4q_f64(a: *mut f64, b: float64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7054,6 +8204,8 @@ pub unsafe fn vst4q_lane_s8<const LANE: i32>(a: *mut i8, b: int8x16x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7070,6 +8222,8 @@ pub unsafe fn vst4_lane_s64<const LANE: i32>(a: *mut i64, b: int64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7086,6 +8240,8 @@ pub unsafe fn vst4q_lane_s64<const LANE: i32>(a: *mut i64, b: int64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7097,6 +8253,8 @@ pub unsafe fn vst4q_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x16x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7108,6 +8266,8 @@ pub unsafe fn vst4_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7119,6 +8279,8 @@ pub unsafe fn vst4q_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7130,6 +8292,8 @@ pub unsafe fn vst4q_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x16x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7141,6 +8305,8 @@ pub unsafe fn vst4_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7152,6 +8318,8 @@ pub unsafe fn vst4q_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7168,6 +8336,8 @@ pub unsafe fn vst4_lane_f64<const LANE: i32>(a: *mut f64, b: float64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(st4, LANE = 0))]
@@ -7184,6 +8354,8 @@ pub unsafe fn vst4q_lane_f64<const LANE: i32>(a: *mut f64, b: float64x2x4_t) {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -7193,6 +8365,8 @@ pub unsafe fn vmul_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -7202,6 +8376,8 @@ pub unsafe fn vmulq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -7211,6 +8387,8 @@ pub unsafe fn vmul_n_f64(a: float64x1_t, b: f64) -> float64x1_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul))]
@@ -7220,6 +8398,8 @@ pub unsafe fn vmulq_n_f64(a: float64x2_t, b: f64) -> float64x2_t {
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7231,6 +8411,8 @@ pub unsafe fn vmul_lane_f64<const LANE: i32>(a: float64x1_t, b: float64x1_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7242,6 +8424,8 @@ pub unsafe fn vmul_laneq_f64<const LANE: i32>(a: float64x1_t, b: float64x2_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7253,6 +8437,8 @@ pub unsafe fn vmulq_lane_f64<const LANE: i32>(a: float64x2_t, b: float64x1_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7264,6 +8450,8 @@ pub unsafe fn vmulq_laneq_f64<const LANE: i32>(a: float64x2_t, b: float64x2_t) -
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuls_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7276,6 +8464,8 @@ pub unsafe fn vmuls_lane_f32<const LANE: i32>(a: f32, b: float32x2_t) -> f32 {
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuls_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7288,6 +8478,8 @@ pub unsafe fn vmuls_laneq_f32<const LANE: i32>(a: f32, b: float32x4_t) -> f32 {
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuld_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7300,6 +8492,8 @@ pub unsafe fn vmuld_lane_f64<const LANE: i32>(a: f64, b: float64x1_t) -> f64 {
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuld_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmul, LANE = 0))]
@@ -7312,6 +8506,8 @@ pub unsafe fn vmuld_laneq_f64<const LANE: i32>(a: f64, b: float64x2_t) -> f64 {
}
/// Signed multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2))]
@@ -7323,6 +8519,8 @@ pub unsafe fn vmull_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
}
/// Signed multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2))]
@@ -7334,6 +8532,8 @@ pub unsafe fn vmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
}
/// Signed multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2))]
@@ -7345,6 +8545,8 @@ pub unsafe fn vmull_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
}
/// Unsigned multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2))]
@@ -7356,6 +8558,8 @@ pub unsafe fn vmull_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
}
/// Unsigned multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2))]
@@ -7367,6 +8571,8 @@ pub unsafe fn vmull_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
}
/// Unsigned multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2))]
@@ -7378,6 +8584,8 @@ pub unsafe fn vmull_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
}
/// Polynomial multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(pmull))]
@@ -7392,6 +8600,8 @@ pub unsafe fn vmull_p64(a: p64, b: p64) -> p128 {
}
/// Polynomial multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(pmull))]
@@ -7403,6 +8613,8 @@ pub unsafe fn vmull_high_p8(a: poly8x16_t, b: poly8x16_t) -> poly16x8_t {
}
/// Polynomial multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(pmull))]
@@ -7412,6 +8624,8 @@ pub unsafe fn vmull_high_p64(a: poly64x2_t, b: poly64x2_t) -> p128 {
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2))]
@@ -7421,6 +8635,8 @@ pub unsafe fn vmull_high_n_s16(a: int16x8_t, b: i16) -> int32x4_t {
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2))]
@@ -7430,6 +8646,8 @@ pub unsafe fn vmull_high_n_s32(a: int32x4_t, b: i32) -> int64x2_t {
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2))]
@@ -7439,6 +8657,8 @@ pub unsafe fn vmull_high_n_u16(a: uint16x8_t, b: u16) -> uint32x4_t {
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2))]
@@ -7448,6 +8668,8 @@ pub unsafe fn vmull_high_n_u32(a: uint32x4_t, b: u32) -> uint64x2_t {
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2, LANE = 1))]
@@ -7459,6 +8681,8 @@ pub unsafe fn vmull_high_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x4_t) -
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2, LANE = 1))]
@@ -7470,6 +8694,8 @@ pub unsafe fn vmull_high_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t)
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2, LANE = 1))]
@@ -7481,6 +8707,8 @@ pub unsafe fn vmull_high_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x2_t) -
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(smull2, LANE = 1))]
@@ -7492,6 +8720,8 @@ pub unsafe fn vmull_high_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t)
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2, LANE = 1))]
@@ -7503,6 +8733,8 @@ pub unsafe fn vmull_high_lane_u16<const LANE: i32>(a: uint16x8_t, b: uint16x4_t)
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2, LANE = 1))]
@@ -7514,6 +8746,8 @@ pub unsafe fn vmull_high_laneq_u16<const LANE: i32>(a: uint16x8_t, b: uint16x8_t
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2, LANE = 1))]
@@ -7525,6 +8759,8 @@ pub unsafe fn vmull_high_lane_u32<const LANE: i32>(a: uint32x4_t, b: uint32x2_t)
}
/// Multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(umull2, LANE = 1))]
@@ -7536,6 +8772,8 @@ pub unsafe fn vmull_high_laneq_u32<const LANE: i32>(a: uint32x4_t, b: uint32x4_t
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx))]
@@ -7550,6 +8788,8 @@ pub unsafe fn vmulx_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx))]
@@ -7564,6 +8804,8 @@ pub unsafe fn vmulxq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx))]
@@ -7578,6 +8820,8 @@ pub unsafe fn vmulx_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx))]
@@ -7592,6 +8836,8 @@ pub unsafe fn vmulxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7603,6 +8849,8 @@ pub unsafe fn vmulx_lane_f64<const LANE: i32>(a: float64x1_t, b: float64x1_t) ->
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7614,6 +8862,8 @@ pub unsafe fn vmulx_laneq_f64<const LANE: i32>(a: float64x1_t, b: float64x2_t) -
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7625,6 +8875,8 @@ pub unsafe fn vmulx_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t) ->
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7636,6 +8888,8 @@ pub unsafe fn vmulx_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x4_t) -
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7647,6 +8901,8 @@ pub unsafe fn vmulxq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x2_t) -
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7658,6 +8914,8 @@ pub unsafe fn vmulxq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t)
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7669,6 +8927,8 @@ pub unsafe fn vmulxq_lane_f64<const LANE: i32>(a: float64x2_t, b: float64x1_t) -
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7680,6 +8940,8 @@ pub unsafe fn vmulxq_laneq_f64<const LANE: i32>(a: float64x2_t, b: float64x2_t)
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx))]
@@ -7694,6 +8956,8 @@ pub unsafe fn vmulxs_f32(a: f32, b: f32) -> f32 {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx))]
@@ -7708,6 +8972,8 @@ pub unsafe fn vmulxd_f64(a: f64, b: f64) -> f64 {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxs_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7719,6 +8985,8 @@ pub unsafe fn vmulxs_lane_f32<const LANE: i32>(a: f32, b: float32x2_t) -> f32 {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxs_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7730,6 +8998,8 @@ pub unsafe fn vmulxs_laneq_f32<const LANE: i32>(a: f32, b: float32x4_t) -> f32 {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxd_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7741,6 +9011,8 @@ pub unsafe fn vmulxd_lane_f64<const LANE: i32>(a: f64, b: float64x1_t) -> f64 {
}
/// Floating-point multiply extended
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxd_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
@@ -7752,6 +9024,8 @@ pub unsafe fn vmulxd_laneq_f64<const LANE: i32>(a: f64, b: float64x2_t) -> f64 {
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmadd))]
@@ -7766,6 +9040,8 @@ pub unsafe fn vfma_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float6
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla))]
@@ -7780,6 +9056,8 @@ pub unsafe fn vfmaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_n_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmadd))]
@@ -7789,6 +9067,8 @@ pub unsafe fn vfma_n_f64(a: float64x1_t, b: float64x1_t, c: f64) -> float64x1_t
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_n_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla))]
@@ -7798,6 +9078,8 @@ pub unsafe fn vfmaq_n_f64(a: float64x2_t, b: float64x2_t, c: f64) -> float64x2_t
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7809,6 +9091,8 @@ pub unsafe fn vfma_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7820,6 +9104,8 @@ pub unsafe fn vfma_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7831,6 +9117,8 @@ pub unsafe fn vfmaq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c:
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7842,6 +9130,8 @@ pub unsafe fn vfmaq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
@@ -7853,6 +9143,8 @@ pub unsafe fn vfma_lane_f64<const LANE: i32>(a: float64x1_t, b: float64x1_t, c:
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7864,6 +9156,8 @@ pub unsafe fn vfma_laneq_f64<const LANE: i32>(a: float64x1_t, b: float64x1_t, c:
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7875,6 +9169,8 @@ pub unsafe fn vfmaq_lane_f64<const LANE: i32>(a: float64x2_t, b: float64x2_t, c:
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7886,6 +9182,8 @@ pub unsafe fn vfmaq_laneq_f64<const LANE: i32>(a: float64x2_t, b: float64x2_t, c
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmas_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7903,6 +9201,8 @@ pub unsafe fn vfmas_lane_f32<const LANE: i32>(a: f32, b: f32, c: float32x2_t) ->
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmas_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7920,6 +9220,8 @@ pub unsafe fn vfmas_laneq_f32<const LANE: i32>(a: f32, b: f32, c: float32x4_t) -
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmad_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
@@ -7937,6 +9239,8 @@ pub unsafe fn vfmad_lane_f64<const LANE: i32>(a: f64, b: f64, c: float64x1_t) ->
}
/// Floating-point fused multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmad_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmla, LANE = 0))]
@@ -7954,6 +9258,8 @@ pub unsafe fn vfmad_laneq_f64<const LANE: i32>(a: f64, b: f64, c: float64x2_t) -
}
/// Floating-point fused multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmsub))]
@@ -7964,6 +9270,8 @@ pub unsafe fn vfms_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float6
}
/// Floating-point fused multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls))]
@@ -7974,6 +9282,8 @@ pub unsafe fn vfmsq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float
}
/// Floating-point fused Multiply-subtract to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_n_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmsub))]
@@ -7983,6 +9293,8 @@ pub unsafe fn vfms_n_f64(a: float64x1_t, b: float64x1_t, c: f64) -> float64x1_t
}
/// Floating-point fused Multiply-subtract to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_n_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls))]
@@ -7992,6 +9304,8 @@ pub unsafe fn vfmsq_n_f64(a: float64x2_t, b: float64x2_t, c: f64) -> float64x2_t
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8003,6 +9317,8 @@ pub unsafe fn vfms_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8014,6 +9330,8 @@ pub unsafe fn vfms_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8025,6 +9343,8 @@ pub unsafe fn vfmsq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c:
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8036,6 +9356,8 @@ pub unsafe fn vfmsq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
@@ -8047,6 +9369,8 @@ pub unsafe fn vfms_lane_f64<const LANE: i32>(a: float64x1_t, b: float64x1_t, c:
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8058,6 +9382,8 @@ pub unsafe fn vfms_laneq_f64<const LANE: i32>(a: float64x1_t, b: float64x1_t, c:
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8069,6 +9395,8 @@ pub unsafe fn vfmsq_lane_f64<const LANE: i32>(a: float64x2_t, b: float64x2_t, c:
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8080,6 +9408,8 @@ pub unsafe fn vfmsq_laneq_f64<const LANE: i32>(a: float64x2_t, b: float64x2_t, c
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmss_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8090,6 +9420,8 @@ pub unsafe fn vfmss_lane_f32<const LANE: i32>(a: f32, b: f32, c: float32x2_t) ->
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmss_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8100,6 +9432,8 @@ pub unsafe fn vfmss_laneq_f32<const LANE: i32>(a: f32, b: f32, c: float32x4_t) -
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsd_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
@@ -8110,6 +9444,8 @@ pub unsafe fn vfmsd_lane_f64<const LANE: i32>(a: f64, b: f64, c: float64x1_t) ->
}
/// Floating-point fused multiply-subtract to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsd_laneq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmls, LANE = 0))]
@@ -8120,6 +9456,8 @@ pub unsafe fn vfmsd_laneq_f64<const LANE: i32>(a: f64, b: f64, c: float64x2_t) -
}
/// Divide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdiv_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fdiv))]
@@ -8129,6 +9467,8 @@ pub unsafe fn vdiv_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Divide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdivq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fdiv))]
@@ -8138,6 +9478,8 @@ pub unsafe fn vdivq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Divide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdiv_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fdiv))]
@@ -8147,6 +9489,8 @@ pub unsafe fn vdiv_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Divide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdivq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fdiv))]
@@ -8156,6 +9500,8 @@ pub unsafe fn vdivq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fsub))]
@@ -8165,6 +9511,8 @@ pub unsafe fn vsub_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fsub))]
@@ -8174,6 +9522,8 @@ pub unsafe fn vsubq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -8183,6 +9533,8 @@ pub unsafe fn vsubd_s64(a: i64, b: i64) -> i64 {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -8192,6 +9544,8 @@ pub unsafe fn vsubd_u64(a: u64, b: u64) -> u64 {
}
/// Add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -8201,6 +9555,8 @@ pub unsafe fn vaddd_s64(a: i64, b: i64) -> i64 {
}
/// Add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -8210,6 +9566,8 @@ pub unsafe fn vaddd_u64(a: u64, b: u64) -> u64 {
}
/// Floating-point add across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(faddp))]
@@ -8224,6 +9582,8 @@ pub unsafe fn vaddv_f32(a: float32x2_t) -> f32 {
}
/// Floating-point add across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(faddp))]
@@ -8238,6 +9598,8 @@ pub unsafe fn vaddvq_f32(a: float32x4_t) -> f32 {
}
/// Floating-point add across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(faddp))]
@@ -8252,6 +9614,8 @@ pub unsafe fn vaddvq_f64(a: float64x2_t) -> f64 {
}
/// Signed Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(saddlv))]
@@ -8266,6 +9630,8 @@ pub unsafe fn vaddlv_s16(a: int16x4_t) -> i32 {
}
/// Signed Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(saddlv))]
@@ -8280,6 +9646,8 @@ pub unsafe fn vaddlvq_s16(a: int16x8_t) -> i32 {
}
/// Signed Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(saddlp))]
@@ -8294,6 +9662,8 @@ pub unsafe fn vaddlv_s32(a: int32x2_t) -> i64 {
}
/// Signed Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(saddlv))]
@@ -8308,6 +9678,8 @@ pub unsafe fn vaddlvq_s32(a: int32x4_t) -> i64 {
}
/// Unsigned Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uaddlv))]
@@ -8322,6 +9694,8 @@ pub unsafe fn vaddlv_u16(a: uint16x4_t) -> u32 {
}
/// Unsigned Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uaddlv))]
@@ -8336,6 +9710,8 @@ pub unsafe fn vaddlvq_u16(a: uint16x8_t) -> u32 {
}
/// Unsigned Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uaddlp))]
@@ -8350,6 +9726,8 @@ pub unsafe fn vaddlv_u32(a: uint32x2_t) -> u64 {
}
/// Unsigned Add Long across Vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uaddlv))]
@@ -8364,6 +9742,8 @@ pub unsafe fn vaddlvq_u32(a: uint32x4_t) -> u64 {
}
/// Signed Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ssubw))]
@@ -8374,6 +9754,8 @@ pub unsafe fn vsubw_high_s8(a: int16x8_t, b: int8x16_t) -> int16x8_t {
}
/// Signed Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ssubw))]
@@ -8384,6 +9766,8 @@ pub unsafe fn vsubw_high_s16(a: int32x4_t, b: int16x8_t) -> int32x4_t {
}
/// Signed Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ssubw))]
@@ -8394,6 +9778,8 @@ pub unsafe fn vsubw_high_s32(a: int64x2_t, b: int32x4_t) -> int64x2_t {
}
/// Unsigned Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usubw))]
@@ -8404,6 +9790,8 @@ pub unsafe fn vsubw_high_u8(a: uint16x8_t, b: uint8x16_t) -> uint16x8_t {
}
/// Unsigned Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usubw))]
@@ -8414,6 +9802,8 @@ pub unsafe fn vsubw_high_u16(a: uint32x4_t, b: uint16x8_t) -> uint32x4_t {
}
/// Unsigned Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usubw))]
@@ -8424,6 +9814,8 @@ pub unsafe fn vsubw_high_u32(a: uint64x2_t, b: uint32x4_t) -> uint64x2_t {
}
/// Signed Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ssubl))]
@@ -8437,6 +9829,8 @@ pub unsafe fn vsubl_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
}
/// Signed Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ssubl))]
@@ -8450,6 +9844,8 @@ pub unsafe fn vsubl_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
}
/// Signed Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ssubl))]
@@ -8463,6 +9859,8 @@ pub unsafe fn vsubl_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
}
/// Unsigned Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usubl))]
@@ -8476,6 +9874,8 @@ pub unsafe fn vsubl_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
}
/// Unsigned Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usubl))]
@@ -8489,6 +9889,8 @@ pub unsafe fn vsubl_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
}
/// Unsigned Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usubl))]
@@ -8502,6 +9904,8 @@ pub unsafe fn vsubl_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s8)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8515,6 +9919,8 @@ pub unsafe fn vbcaxq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s16)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8528,6 +9934,8 @@ pub unsafe fn vbcaxq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s32)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8541,6 +9949,8 @@ pub unsafe fn vbcaxq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8554,6 +9964,8 @@ pub unsafe fn vbcaxq_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u8)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8567,6 +9979,8 @@ pub unsafe fn vbcaxq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u16)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8580,6 +9994,8 @@ pub unsafe fn vbcaxq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u32)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8593,6 +10009,8 @@ pub unsafe fn vbcaxq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x
}
/// Bit clear and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(bcax))]
@@ -8606,6 +10024,8 @@ pub unsafe fn vbcaxq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x
}
/// Floating-point complex add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcadd_rot270_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcadd))]
@@ -8619,6 +10039,8 @@ pub unsafe fn vcadd_rot270_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Floating-point complex add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot270_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcadd))]
@@ -8632,6 +10054,8 @@ pub unsafe fn vcaddq_rot270_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Floating-point complex add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot270_f64)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcadd))]
@@ -8645,6 +10069,8 @@ pub unsafe fn vcaddq_rot270_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point complex add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcadd_rot90_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcadd))]
@@ -8658,6 +10084,8 @@ pub unsafe fn vcadd_rot90_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Floating-point complex add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot90_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcadd))]
@@ -8671,6 +10099,8 @@ pub unsafe fn vcaddq_rot90_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Floating-point complex add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot90_f64)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcadd))]
@@ -8684,6 +10114,8 @@ pub unsafe fn vcaddq_rot90_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8697,6 +10129,8 @@ pub unsafe fn vcmla_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8710,6 +10144,8 @@ pub unsafe fn vcmlaq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> floa
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_f64)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8723,6 +10159,8 @@ pub unsafe fn vcmlaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> floa
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8736,6 +10174,8 @@ pub unsafe fn vcmla_rot90_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) ->
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8749,6 +10189,8 @@ pub unsafe fn vcmlaq_rot90_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_f64)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8762,6 +10204,8 @@ pub unsafe fn vcmlaq_rot90_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8775,6 +10219,8 @@ pub unsafe fn vcmla_rot180_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8788,6 +10234,8 @@ pub unsafe fn vcmlaq_rot180_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t)
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_f64)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8801,6 +10249,8 @@ pub unsafe fn vcmlaq_rot180_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t)
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8814,6 +10264,8 @@ pub unsafe fn vcmla_rot270_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8827,6 +10279,8 @@ pub unsafe fn vcmlaq_rot270_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t)
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_f64)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla))]
@@ -8840,6 +10294,8 @@ pub unsafe fn vcmlaq_rot270_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t)
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8851,6 +10307,8 @@ pub unsafe fn vcmla_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8862,6 +10320,8 @@ pub unsafe fn vcmla_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8873,6 +10333,8 @@ pub unsafe fn vcmlaq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8884,6 +10346,8 @@ pub unsafe fn vcmlaq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t,
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8895,6 +10359,8 @@ pub unsafe fn vcmla_rot90_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8906,6 +10372,8 @@ pub unsafe fn vcmla_rot90_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8917,6 +10385,8 @@ pub unsafe fn vcmlaq_rot90_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8928,6 +10398,8 @@ pub unsafe fn vcmlaq_rot90_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8939,6 +10411,8 @@ pub unsafe fn vcmla_rot180_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8950,6 +10424,8 @@ pub unsafe fn vcmla_rot180_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8961,6 +10437,8 @@ pub unsafe fn vcmlaq_rot180_lane_f32<const LANE: i32>(a: float32x4_t, b: float32
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8972,6 +10450,8 @@ pub unsafe fn vcmlaq_rot180_laneq_f32<const LANE: i32>(a: float32x4_t, b: float3
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8983,6 +10463,8 @@ pub unsafe fn vcmla_rot270_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -8994,6 +10476,8 @@ pub unsafe fn vcmla_rot270_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_lane_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -9005,6 +10489,8 @@ pub unsafe fn vcmlaq_rot270_lane_f32<const LANE: i32>(a: float32x4_t, b: float32
}
/// Floating-point complex multiply accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_laneq_f32)
#[inline]
#[target_feature(enable = "neon,fcma")]
#[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
@@ -9016,6 +10502,8 @@ pub unsafe fn vcmlaq_rot270_laneq_f32<const LANE: i32>(a: float32x4_t, b: float3
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_s32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(sdot))]
@@ -9029,6 +10517,8 @@ pub unsafe fn vdot_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> int32x2_t {
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_s32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(sdot))]
@@ -9042,6 +10532,8 @@ pub unsafe fn vdotq_s32(a: int32x4_t, b: int8x16_t, c: int8x16_t) -> int32x4_t {
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_u32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(udot))]
@@ -9055,6 +10547,8 @@ pub unsafe fn vdot_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) -> uint32x2_t
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_u32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(udot))]
@@ -9068,6 +10562,8 @@ pub unsafe fn vdotq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_s32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(sdot, LANE = 0))]
@@ -9079,6 +10575,8 @@ pub unsafe fn vdot_lane_s32<const LANE: i32>(a: int32x2_t, b: int8x8_t, c: int8x
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_laneq_s32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(sdot, LANE = 0))]
@@ -9090,6 +10588,8 @@ pub unsafe fn vdot_laneq_s32<const LANE: i32>(a: int32x2_t, b: int8x8_t, c: int8
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_s32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(sdot, LANE = 0))]
@@ -9101,6 +10601,8 @@ pub unsafe fn vdotq_lane_s32<const LANE: i32>(a: int32x4_t, b: int8x16_t, c: int
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_laneq_s32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(sdot, LANE = 0))]
@@ -9112,6 +10614,8 @@ pub unsafe fn vdotq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int8x16_t, c: in
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_u32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(udot, LANE = 0))]
@@ -9123,6 +10627,8 @@ pub unsafe fn vdot_lane_u32<const LANE: i32>(a: uint32x2_t, b: uint8x8_t, c: uin
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_laneq_u32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(udot, LANE = 0))]
@@ -9134,6 +10640,8 @@ pub unsafe fn vdot_laneq_u32<const LANE: i32>(a: uint32x2_t, b: uint8x8_t, c: ui
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_u32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(udot, LANE = 0))]
@@ -9145,6 +10653,8 @@ pub unsafe fn vdotq_lane_u32<const LANE: i32>(a: uint32x4_t, b: uint8x16_t, c: u
}
/// Dot product arithmetic
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_laneq_u32)
#[inline]
#[target_feature(enable = "neon,dotprod")]
#[cfg_attr(test, assert_instr(udot, LANE = 0))]
@@ -9156,6 +10666,8 @@ pub unsafe fn vdotq_laneq_u32<const LANE: i32>(a: uint32x4_t, b: uint8x16_t, c:
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmax))]
@@ -9170,6 +10682,8 @@ pub unsafe fn vmax_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmax))]
@@ -9184,6 +10698,8 @@ pub unsafe fn vmaxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point Maximum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnm_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnm))]
@@ -9198,6 +10714,8 @@ pub unsafe fn vmaxnm_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Floating-point Maximum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnm))]
@@ -9212,6 +10730,8 @@ pub unsafe fn vmaxnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point maximum number across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmv_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9226,6 +10746,8 @@ pub unsafe fn vmaxnmv_f32(a: float32x2_t) -> f32 {
}
/// Floating-point maximum number across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmvq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9240,6 +10762,8 @@ pub unsafe fn vmaxnmvq_f64(a: float64x2_t) -> f64 {
}
/// Floating-point maximum number across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmvq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmv))]
@@ -9254,6 +10778,8 @@ pub unsafe fn vmaxnmvq_f32(a: float32x4_t) -> f32 {
}
/// Floating-point Maximum Number Pairwise (vector).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnm_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9268,6 +10794,8 @@ pub unsafe fn vpmaxnm_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Floating-point Maximum Number Pairwise (vector).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9282,6 +10810,8 @@ pub unsafe fn vpmaxnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point Maximum Number Pairwise (vector).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9296,6 +10826,8 @@ pub unsafe fn vpmaxnmq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Floating-point maximum number pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnms_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9310,6 +10842,8 @@ pub unsafe fn vpmaxnms_f32(a: float32x2_t) -> f32 {
}
/// Floating-point maximum number pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmqd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxnmp))]
@@ -9324,6 +10858,8 @@ pub unsafe fn vpmaxnmqd_f64(a: float64x2_t) -> f64 {
}
/// Floating-point maximum pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxp))]
@@ -9338,6 +10874,8 @@ pub unsafe fn vpmaxs_f32(a: float32x2_t) -> f32 {
}
/// Floating-point maximum pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxqd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmaxp))]
@@ -9352,6 +10890,8 @@ pub unsafe fn vpmaxqd_f64(a: float64x2_t) -> f64 {
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmin))]
@@ -9366,6 +10906,8 @@ pub unsafe fn vmin_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fmin))]
@@ -9380,6 +10922,8 @@ pub unsafe fn vminq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point Minimum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnm_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnm))]
@@ -9394,6 +10938,8 @@ pub unsafe fn vminnm_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Floating-point Minimum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnm))]
@@ -9408,6 +10954,8 @@ pub unsafe fn vminnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point minimum number across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmv_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9422,6 +10970,8 @@ pub unsafe fn vminnmv_f32(a: float32x2_t) -> f32 {
}
/// Floating-point minimum number across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmvq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9436,6 +10986,8 @@ pub unsafe fn vminnmvq_f64(a: float64x2_t) -> f64 {
}
/// Floating-point minimum number across vector
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmvq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmv))]
@@ -9450,6 +11002,8 @@ pub unsafe fn vminnmvq_f32(a: float32x4_t) -> f32 {
}
/// Vector move
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sxtl2))]
@@ -9460,6 +11014,8 @@ pub unsafe fn vmovl_high_s8(a: int8x16_t) -> int16x8_t {
}
/// Vector move
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sxtl2))]
@@ -9470,6 +11026,8 @@ pub unsafe fn vmovl_high_s16(a: int16x8_t) -> int32x4_t {
}
/// Vector move
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sxtl2))]
@@ -9480,6 +11038,8 @@ pub unsafe fn vmovl_high_s32(a: int32x4_t) -> int64x2_t {
}
/// Vector move
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uxtl2))]
@@ -9490,6 +11050,8 @@ pub unsafe fn vmovl_high_u8(a: uint8x16_t) -> uint16x8_t {
}
/// Vector move
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uxtl2))]
@@ -9500,6 +11062,8 @@ pub unsafe fn vmovl_high_u16(a: uint16x8_t) -> uint32x4_t {
}
/// Vector move
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uxtl2))]
@@ -9510,6 +11074,8 @@ pub unsafe fn vmovl_high_u32(a: uint32x4_t) -> uint64x2_t {
}
/// Floating-point add pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(faddp))]
@@ -9524,6 +11090,8 @@ pub unsafe fn vpaddq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Floating-point add pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(faddp))]
@@ -9538,6 +11106,8 @@ pub unsafe fn vpaddq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point add pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadds_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -9549,6 +11119,8 @@ pub unsafe fn vpadds_f32(a: float32x2_t) -> f32 {
}
/// Floating-point add pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -9560,6 +11132,8 @@ pub unsafe fn vpaddd_f64(a: float64x2_t) -> f64 {
}
/// Floating-point Minimum Number Pairwise (vector).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnm_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9574,6 +11148,8 @@ pub unsafe fn vpminnm_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Floating-point Minimum Number Pairwise (vector).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9588,6 +11164,8 @@ pub unsafe fn vpminnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point Minimum Number Pairwise (vector).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9602,6 +11180,8 @@ pub unsafe fn vpminnmq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Floating-point minimum number pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnms_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9616,6 +11196,8 @@ pub unsafe fn vpminnms_f32(a: float32x2_t) -> f32 {
}
/// Floating-point minimum number pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmqd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminnmp))]
@@ -9630,6 +11212,8 @@ pub unsafe fn vpminnmqd_f64(a: float64x2_t) -> f64 {
}
/// Floating-point minimum pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmins_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminp))]
@@ -9644,6 +11228,8 @@ pub unsafe fn vpmins_f32(a: float32x2_t) -> f32 {
}
/// Floating-point minimum pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminqd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fminp))]
@@ -9658,6 +11244,8 @@ pub unsafe fn vpminqd_f64(a: float64x2_t) -> f64 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmullh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull))]
@@ -9669,6 +11257,8 @@ pub unsafe fn vqdmullh_s16(a: i16, b: i16) -> i32 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulls_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull))]
@@ -9683,6 +11273,8 @@ pub unsafe fn vqdmulls_s32(a: i32, b: i32) -> i64 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2))]
@@ -9694,6 +11286,8 @@ pub unsafe fn vqdmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2))]
@@ -9705,6 +11299,8 @@ pub unsafe fn vqdmull_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2))]
@@ -9716,6 +11312,8 @@ pub unsafe fn vqdmull_high_n_s16(a: int16x8_t, b: i16) -> int32x4_t {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2))]
@@ -9727,6 +11325,8 @@ pub unsafe fn vqdmull_high_n_s32(a: int32x4_t, b: i32) -> int64x2_t {
}
/// Vector saturating doubling long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, N = 4))]
@@ -9739,6 +11339,8 @@ pub unsafe fn vqdmull_laneq_s16<const N: i32>(a: int16x4_t, b: int16x8_t) -> int
}
/// Vector saturating doubling long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, N = 2))]
@@ -9751,6 +11353,8 @@ pub unsafe fn vqdmull_laneq_s32<const N: i32>(a: int32x2_t, b: int32x4_t) -> int
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmullh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, N = 2))]
@@ -9763,6 +11367,8 @@ pub unsafe fn vqdmullh_lane_s16<const N: i32>(a: i16, b: int16x4_t) -> i32 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmullh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, N = 4))]
@@ -9775,6 +11381,8 @@ pub unsafe fn vqdmullh_laneq_s16<const N: i32>(a: i16, b: int16x8_t) -> i32 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulls_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, N = 1))]
@@ -9787,6 +11395,8 @@ pub unsafe fn vqdmulls_lane_s32<const N: i32>(a: i32, b: int32x2_t) -> i64 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulls_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, N = 2))]
@@ -9799,6 +11409,8 @@ pub unsafe fn vqdmulls_laneq_s32<const N: i32>(a: i32, b: int32x4_t) -> i64 {
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2, N = 2))]
@@ -9812,6 +11424,8 @@ pub unsafe fn vqdmull_high_lane_s16<const N: i32>(a: int16x8_t, b: int16x4_t) ->
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2, N = 1))]
@@ -9825,6 +11439,8 @@ pub unsafe fn vqdmull_high_lane_s32<const N: i32>(a: int32x4_t, b: int32x2_t) ->
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2, N = 4))]
@@ -9838,6 +11454,8 @@ pub unsafe fn vqdmull_high_laneq_s16<const N: i32>(a: int16x8_t, b: int16x8_t) -
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull2, N = 2))]
@@ -9851,6 +11469,8 @@ pub unsafe fn vqdmull_high_laneq_s32<const N: i32>(a: int32x4_t, b: int32x4_t) -
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2))]
@@ -9860,6 +11480,8 @@ pub unsafe fn vqdmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int3
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2))]
@@ -9869,6 +11491,8 @@ pub unsafe fn vqdmlal_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int6
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2))]
@@ -9878,6 +11502,8 @@ pub unsafe fn vqdmlal_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2))]
@@ -9887,6 +11513,8 @@ pub unsafe fn vqdmlal_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_
}
/// Vector widening saturating doubling multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal, N = 2))]
@@ -9898,6 +11526,8 @@ pub unsafe fn vqdmlal_laneq_s16<const N: i32>(a: int32x4_t, b: int16x4_t, c: int
}
/// Vector widening saturating doubling multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal, N = 1))]
@@ -9909,6 +11539,8 @@ pub unsafe fn vqdmlal_laneq_s32<const N: i32>(a: int64x2_t, b: int32x2_t, c: int
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
@@ -9920,6 +11552,8 @@ pub unsafe fn vqdmlal_high_lane_s16<const N: i32>(a: int32x4_t, b: int16x8_t, c:
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
@@ -9931,6 +11565,8 @@ pub unsafe fn vqdmlal_high_laneq_s16<const N: i32>(a: int32x4_t, b: int16x8_t, c
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
@@ -9942,6 +11578,8 @@ pub unsafe fn vqdmlal_high_lane_s32<const N: i32>(a: int64x2_t, b: int32x4_t, c:
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
@@ -9953,6 +11591,8 @@ pub unsafe fn vqdmlal_high_laneq_s32<const N: i32>(a: int64x2_t, b: int32x4_t, c
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlalh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull))]
@@ -9963,6 +11603,8 @@ pub unsafe fn vqdmlalh_s16(a: i32, b: i16, c: i16) -> i32 {
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlals_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull))]
@@ -9973,6 +11615,8 @@ pub unsafe fn vqdmlals_s32(a: i64, b: i32, c: i32) -> i64 {
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlalh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal, LANE = 0))]
@@ -9984,6 +11628,8 @@ pub unsafe fn vqdmlalh_lane_s16<const LANE: i32>(a: i32, b: i16, c: int16x4_t) -
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlalh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlal, LANE = 0))]
@@ -9995,6 +11641,8 @@ pub unsafe fn vqdmlalh_laneq_s16<const LANE: i32>(a: i32, b: i16, c: int16x8_t)
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlals_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, LANE = 0))]
@@ -10006,6 +11654,8 @@ pub unsafe fn vqdmlals_lane_s32<const LANE: i32>(a: i64, b: i32, c: int32x2_t) -
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlals_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, LANE = 0))]
@@ -10017,6 +11667,8 @@ pub unsafe fn vqdmlals_laneq_s32<const LANE: i32>(a: i64, b: i32, c: int32x4_t)
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2))]
@@ -10026,6 +11678,8 @@ pub unsafe fn vqdmlsl_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int3
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2))]
@@ -10035,6 +11689,8 @@ pub unsafe fn vqdmlsl_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int6
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2))]
@@ -10044,6 +11700,8 @@ pub unsafe fn vqdmlsl_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2))]
@@ -10053,6 +11711,8 @@ pub unsafe fn vqdmlsl_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_
}
/// Vector widening saturating doubling multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl, N = 2))]
@@ -10064,6 +11724,8 @@ pub unsafe fn vqdmlsl_laneq_s16<const N: i32>(a: int32x4_t, b: int16x4_t, c: int
}
/// Vector widening saturating doubling multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl, N = 1))]
@@ -10075,6 +11737,8 @@ pub unsafe fn vqdmlsl_laneq_s32<const N: i32>(a: int64x2_t, b: int32x2_t, c: int
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
@@ -10086,6 +11750,8 @@ pub unsafe fn vqdmlsl_high_lane_s16<const N: i32>(a: int32x4_t, b: int16x8_t, c:
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
@@ -10097,6 +11763,8 @@ pub unsafe fn vqdmlsl_high_laneq_s16<const N: i32>(a: int32x4_t, b: int16x8_t, c
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
@@ -10108,6 +11776,8 @@ pub unsafe fn vqdmlsl_high_lane_s32<const N: i32>(a: int64x2_t, b: int32x4_t, c:
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
@@ -10119,6 +11789,8 @@ pub unsafe fn vqdmlsl_high_laneq_s32<const N: i32>(a: int64x2_t, b: int32x4_t, c
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlslh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull))]
@@ -10129,6 +11801,8 @@ pub unsafe fn vqdmlslh_s16(a: i32, b: i16, c: i16) -> i32 {
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsls_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull))]
@@ -10139,6 +11813,8 @@ pub unsafe fn vqdmlsls_s32(a: i64, b: i32, c: i32) -> i64 {
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlslh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl, LANE = 0))]
@@ -10150,6 +11826,8 @@ pub unsafe fn vqdmlslh_lane_s16<const LANE: i32>(a: i32, b: i16, c: int16x4_t) -
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlslh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmlsl, LANE = 0))]
@@ -10161,6 +11839,8 @@ pub unsafe fn vqdmlslh_laneq_s16<const LANE: i32>(a: i32, b: i16, c: int16x8_t)
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsls_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, LANE = 0))]
@@ -10172,6 +11852,8 @@ pub unsafe fn vqdmlsls_lane_s32<const LANE: i32>(a: i64, b: i32, c: int32x2_t) -
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsls_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmull, LANE = 0))]
@@ -10183,6 +11865,8 @@ pub unsafe fn vqdmlsls_laneq_s32<const LANE: i32>(a: i64, b: i32, c: int32x4_t)
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh))]
@@ -10194,6 +11878,8 @@ pub unsafe fn vqdmulhh_s16(a: i16, b: i16) -> i16 {
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhs_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh))]
@@ -10205,6 +11891,8 @@ pub unsafe fn vqdmulhs_s32(a: i32, b: i32) -> i32 {
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, N = 2))]
@@ -10217,6 +11905,8 @@ pub unsafe fn vqdmulhh_lane_s16<const N: i32>(a: i16, b: int16x4_t) -> i16 {
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, N = 2))]
@@ -10229,6 +11919,8 @@ pub unsafe fn vqdmulhh_laneq_s16<const N: i32>(a: i16, b: int16x8_t) -> i16 {
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhs_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, N = 1))]
@@ -10241,6 +11933,8 @@ pub unsafe fn vqdmulhs_lane_s32<const N: i32>(a: i32, b: int32x2_t) -> i32 {
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhs_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, N = 1))]
@@ -10253,6 +11947,8 @@ pub unsafe fn vqdmulhs_laneq_s32<const N: i32>(a: i32, b: int32x4_t) -> i32 {
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
@@ -10264,6 +11960,8 @@ pub unsafe fn vqdmulh_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t) -> i
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
@@ -10275,6 +11973,8 @@ pub unsafe fn vqdmulhq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x4_t) ->
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
@@ -10286,6 +11986,8 @@ pub unsafe fn vqdmulh_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t) -> i
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
@@ -10297,6 +11999,8 @@ pub unsafe fn vqdmulhq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x2_t) ->
}
/// Saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtn))]
@@ -10306,6 +12010,8 @@ pub unsafe fn vqmovnh_s16(a: i16) -> i8 {
}
/// Saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovns_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtn))]
@@ -10315,6 +12021,8 @@ pub unsafe fn vqmovns_s32(a: i32) -> i16 {
}
/// Saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnh_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqxtn))]
@@ -10324,6 +12032,8 @@ pub unsafe fn vqmovnh_u16(a: u16) -> u8 {
}
/// Saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovns_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqxtn))]
@@ -10333,6 +12043,8 @@ pub unsafe fn vqmovns_u32(a: u32) -> u16 {
}
/// Saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtn))]
@@ -10347,6 +12059,8 @@ pub unsafe fn vqmovnd_s64(a: i64) -> i32 {
}
/// Saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqxtn))]
@@ -10361,6 +12075,8 @@ pub unsafe fn vqmovnd_u64(a: u64) -> u32 {
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtn2))]
@@ -10370,6 +12086,8 @@ pub unsafe fn vqmovn_high_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtn2))]
@@ -10379,6 +12097,8 @@ pub unsafe fn vqmovn_high_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t {
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtn2))]
@@ -10388,6 +12108,8 @@ pub unsafe fn vqmovn_high_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t {
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqxtn2))]
@@ -10397,6 +12119,8 @@ pub unsafe fn vqmovn_high_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_t {
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqxtn2))]
@@ -10406,6 +12130,8 @@ pub unsafe fn vqmovn_high_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8_t {
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqxtn2))]
@@ -10415,6 +12141,8 @@ pub unsafe fn vqmovn_high_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4_t {
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovunh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtun))]
@@ -10424,6 +12152,8 @@ pub unsafe fn vqmovunh_s16(a: i16) -> u8 {
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovuns_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtun))]
@@ -10433,6 +12163,8 @@ pub unsafe fn vqmovuns_s32(a: i32) -> u16 {
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovund_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtun))]
@@ -10442,6 +12174,8 @@ pub unsafe fn vqmovund_s64(a: i64) -> u32 {
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtun2))]
@@ -10451,6 +12185,8 @@ pub unsafe fn vqmovun_high_s16(a: uint8x8_t, b: int16x8_t) -> uint8x16_t {
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtun2))]
@@ -10460,6 +12196,8 @@ pub unsafe fn vqmovun_high_s32(a: uint16x4_t, b: int32x4_t) -> uint16x8_t {
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_high_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqxtun2))]
@@ -10469,6 +12207,8 @@ pub unsafe fn vqmovun_high_s64(a: uint32x2_t, b: int64x2_t) -> uint32x4_t {
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrdmulh))]
@@ -10478,6 +12218,8 @@ pub unsafe fn vqrdmulhh_s16(a: i16, b: i16) -> i16 {
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhs_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrdmulh))]
@@ -10487,6 +12229,8 @@ pub unsafe fn vqrdmulhs_s32(a: i32, b: i32) -> i32 {
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
@@ -10498,6 +12242,8 @@ pub unsafe fn vqrdmulhh_lane_s16<const LANE: i32>(a: i16, b: int16x4_t) -> i16 {
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
@@ -10509,6 +12255,8 @@ pub unsafe fn vqrdmulhh_laneq_s16<const LANE: i32>(a: i16, b: int16x8_t) -> i16
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhs_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
@@ -10520,6 +12268,8 @@ pub unsafe fn vqrdmulhs_lane_s32<const LANE: i32>(a: i32, b: int32x2_t) -> i32 {
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhs_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
@@ -10531,6 +12281,8 @@ pub unsafe fn vqrdmulhs_laneq_s32<const LANE: i32>(a: i32, b: int32x4_t) -> i32
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah))]
@@ -10545,6 +12297,8 @@ pub unsafe fn vqrdmlah_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah))]
@@ -10559,6 +12313,8 @@ pub unsafe fn vqrdmlahq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah))]
@@ -10573,6 +12329,8 @@ pub unsafe fn vqrdmlah_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah))]
@@ -10587,6 +12345,8 @@ pub unsafe fn vqrdmlahq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahh_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah))]
@@ -10599,6 +12359,8 @@ pub unsafe fn vqrdmlahh_s16(a: i16, b: i16, c: i16) -> i16 {
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahs_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah))]
@@ -10611,6 +12373,8 @@ pub unsafe fn vqrdmlahs_s32(a: i32, b: i32, c: i32) -> i32 {
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_lane_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10623,6 +12387,8 @@ pub unsafe fn vqrdmlah_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c:
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_laneq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10635,6 +12401,8 @@ pub unsafe fn vqrdmlah_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c:
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_lane_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10647,6 +12415,8 @@ pub unsafe fn vqrdmlahq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c:
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_laneq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10659,6 +12429,8 @@ pub unsafe fn vqrdmlahq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_lane_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10671,6 +12443,8 @@ pub unsafe fn vqrdmlah_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c:
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_laneq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10683,6 +12457,8 @@ pub unsafe fn vqrdmlah_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c:
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_lane_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10695,6 +12471,8 @@ pub unsafe fn vqrdmlahq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c:
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_laneq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10707,6 +12485,8 @@ pub unsafe fn vqrdmlahq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahh_lane_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10718,6 +12498,8 @@ pub unsafe fn vqrdmlahh_lane_s16<const LANE: i32>(a: i16, b: i16, c: int16x4_t)
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahh_laneq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10729,6 +12511,8 @@ pub unsafe fn vqrdmlahh_laneq_s16<const LANE: i32>(a: i16, b: i16, c: int16x8_t)
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahs_lane_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10740,6 +12524,8 @@ pub unsafe fn vqrdmlahs_lane_s32<const LANE: i32>(a: i32, b: i32, c: int32x2_t)
}
/// Signed saturating rounding doubling multiply accumulate returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahs_laneq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
@@ -10751,6 +12537,8 @@ pub unsafe fn vqrdmlahs_laneq_s32<const LANE: i32>(a: i32, b: i32, c: int32x4_t)
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh))]
@@ -10765,6 +12553,8 @@ pub unsafe fn vqrdmlsh_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh))]
@@ -10779,6 +12569,8 @@ pub unsafe fn vqrdmlshq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh))]
@@ -10793,6 +12585,8 @@ pub unsafe fn vqrdmlsh_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh))]
@@ -10807,6 +12601,8 @@ pub unsafe fn vqrdmlshq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshh_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh))]
@@ -10819,6 +12615,8 @@ pub unsafe fn vqrdmlshh_s16(a: i16, b: i16, c: i16) -> i16 {
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshs_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh))]
@@ -10831,6 +12629,8 @@ pub unsafe fn vqrdmlshs_s32(a: i32, b: i32, c: i32) -> i32 {
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_lane_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10843,6 +12643,8 @@ pub unsafe fn vqrdmlsh_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c:
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_laneq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10855,6 +12657,8 @@ pub unsafe fn vqrdmlsh_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c:
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_lane_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10867,6 +12671,8 @@ pub unsafe fn vqrdmlshq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c:
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_laneq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10879,6 +12685,8 @@ pub unsafe fn vqrdmlshq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_lane_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10891,6 +12699,8 @@ pub unsafe fn vqrdmlsh_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c:
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_laneq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10903,6 +12713,8 @@ pub unsafe fn vqrdmlsh_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c:
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_lane_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10915,6 +12727,8 @@ pub unsafe fn vqrdmlshq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c:
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_laneq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10927,6 +12741,8 @@ pub unsafe fn vqrdmlshq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshh_lane_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10938,6 +12754,8 @@ pub unsafe fn vqrdmlshh_lane_s16<const LANE: i32>(a: i16, b: i16, c: int16x4_t)
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshh_laneq_s16)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10949,6 +12767,8 @@ pub unsafe fn vqrdmlshh_laneq_s16<const LANE: i32>(a: i16, b: i16, c: int16x8_t)
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshs_lane_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10960,6 +12780,8 @@ pub unsafe fn vqrdmlshs_lane_s32<const LANE: i32>(a: i32, b: i32, c: int32x2_t)
}
/// Signed saturating rounding doubling multiply subtract returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshs_laneq_s32)
#[inline]
#[target_feature(enable = "rdm")]
#[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
@@ -10971,6 +12793,8 @@ pub unsafe fn vqrdmlshs_laneq_s32<const LANE: i32>(a: i32, b: i32, c: int32x4_t)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshls_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshl))]
@@ -10985,6 +12809,8 @@ pub unsafe fn vqrshls_s32(a: i32, b: i32) -> i32 {
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshld_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshl))]
@@ -10999,6 +12825,8 @@ pub unsafe fn vqrshld_s64(a: i64, b: i64) -> i64 {
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshl))]
@@ -11010,6 +12838,8 @@ pub unsafe fn vqrshlb_s8(a: i8, b: i8) -> i8 {
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshl))]
@@ -11021,6 +12851,8 @@ pub unsafe fn vqrshlh_s16(a: i16, b: i16) -> i16 {
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshls_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshl))]
@@ -11035,6 +12867,8 @@ pub unsafe fn vqrshls_u32(a: u32, b: i32) -> u32 {
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshld_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshl))]
@@ -11049,6 +12883,8 @@ pub unsafe fn vqrshld_u64(a: u64, b: i64) -> u64 {
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlb_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshl))]
@@ -11060,6 +12896,8 @@ pub unsafe fn vqrshlb_u8(a: u8, b: i8) -> u8 {
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlh_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshl))]
@@ -11071,6 +12909,8 @@ pub unsafe fn vqrshlh_u16(a: u16, b: i16) -> u16 {
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
@@ -11083,6 +12923,8 @@ pub unsafe fn vqrshrnh_n_s16<const N: i32>(a: i16) -> i8 {
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrns_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
@@ -11095,6 +12937,8 @@ pub unsafe fn vqrshrns_n_s32<const N: i32>(a: i32) -> i16 {
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnd_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
@@ -11107,6 +12951,8 @@ pub unsafe fn vqrshrnd_n_s64<const N: i32>(a: i64) -> i32 {
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrn2, N = 2))]
@@ -11118,6 +12964,8 @@ pub unsafe fn vqrshrn_high_n_s16<const N: i32>(a: int8x8_t, b: int16x8_t) -> int
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrn2, N = 2))]
@@ -11129,6 +12977,8 @@ pub unsafe fn vqrshrn_high_n_s32<const N: i32>(a: int16x4_t, b: int32x4_t) -> in
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrn2, N = 2))]
@@ -11140,6 +12990,8 @@ pub unsafe fn vqrshrn_high_n_s64<const N: i32>(a: int32x2_t, b: int64x2_t) -> in
}
/// Unsigned saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnh_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
@@ -11152,6 +13004,8 @@ pub unsafe fn vqrshrnh_n_u16<const N: i32>(a: u16) -> u8 {
}
/// Unsigned saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrns_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
@@ -11164,6 +13018,8 @@ pub unsafe fn vqrshrns_n_u32<const N: i32>(a: u32) -> u16 {
}
/// Unsigned saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnd_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
@@ -11176,6 +13032,8 @@ pub unsafe fn vqrshrnd_n_u64<const N: i32>(a: u64) -> u32 {
}
/// Unsigned saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshrn2, N = 2))]
@@ -11187,6 +13045,8 @@ pub unsafe fn vqrshrn_high_n_u16<const N: i32>(a: uint8x8_t, b: uint16x8_t) -> u
}
/// Unsigned saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshrn2, N = 2))]
@@ -11198,6 +13058,8 @@ pub unsafe fn vqrshrn_high_n_u32<const N: i32>(a: uint16x4_t, b: uint32x4_t) ->
}
/// Unsigned saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqrshrn2, N = 2))]
@@ -11209,6 +13071,8 @@ pub unsafe fn vqrshrn_high_n_u64<const N: i32>(a: uint32x2_t, b: uint64x2_t) ->
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrunh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
@@ -11221,6 +13085,8 @@ pub unsafe fn vqrshrunh_n_s16<const N: i32>(a: i16) -> u8 {
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshruns_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
@@ -11233,6 +13099,8 @@ pub unsafe fn vqrshruns_n_s32<const N: i32>(a: i32) -> u16 {
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrund_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
@@ -11245,6 +13113,8 @@ pub unsafe fn vqrshrund_n_s64<const N: i32>(a: i64) -> u32 {
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrun2, N = 2))]
@@ -11256,6 +13126,8 @@ pub unsafe fn vqrshrun_high_n_s16<const N: i32>(a: uint8x8_t, b: int16x8_t) -> u
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrun2, N = 2))]
@@ -11267,6 +13139,8 @@ pub unsafe fn vqrshrun_high_n_s32<const N: i32>(a: uint16x4_t, b: int32x4_t) ->
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_high_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqrshrun2, N = 2))]
@@ -11278,6 +13152,8 @@ pub unsafe fn vqrshrun_high_n_s64<const N: i32>(a: uint32x2_t, b: int64x2_t) ->
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl))]
@@ -11292,6 +13168,8 @@ pub unsafe fn vqshld_s64(a: i64, b: i64) -> i64 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl))]
@@ -11302,6 +13180,8 @@ pub unsafe fn vqshlb_s8(a: i8, b: i8) -> i8 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl))]
@@ -11312,6 +13192,8 @@ pub unsafe fn vqshlh_s16(a: i16, b: i16) -> i16 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl))]
@@ -11322,6 +13204,8 @@ pub unsafe fn vqshls_s32(a: i32, b: i32) -> i32 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl))]
@@ -11336,6 +13220,8 @@ pub unsafe fn vqshld_u64(a: u64, b: i64) -> u64 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl))]
@@ -11346,6 +13232,8 @@ pub unsafe fn vqshlb_u8(a: u8, b: i8) -> u8 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl))]
@@ -11356,6 +13244,8 @@ pub unsafe fn vqshlh_u16(a: u16, b: i16) -> u16 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl))]
@@ -11366,6 +13256,8 @@ pub unsafe fn vqshls_u32(a: u32, b: i32) -> u32 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl, N = 2))]
@@ -11377,6 +13269,8 @@ pub unsafe fn vqshlb_n_s8<const N: i32>(a: i8) -> i8 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl, N = 2))]
@@ -11388,6 +13282,8 @@ pub unsafe fn vqshlh_n_s16<const N: i32>(a: i16) -> i16 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl, N = 2))]
@@ -11399,6 +13295,8 @@ pub unsafe fn vqshls_n_s32<const N: i32>(a: i32) -> i32 {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshl, N = 2))]
@@ -11410,6 +13308,8 @@ pub unsafe fn vqshld_n_s64<const N: i32>(a: i64) -> i64 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl, N = 2))]
@@ -11421,6 +13321,8 @@ pub unsafe fn vqshlb_n_u8<const N: i32>(a: u8) -> u8 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl, N = 2))]
@@ -11432,6 +13334,8 @@ pub unsafe fn vqshlh_n_u16<const N: i32>(a: u16) -> u16 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl, N = 2))]
@@ -11443,6 +13347,8 @@ pub unsafe fn vqshls_n_u32<const N: i32>(a: u32) -> u32 {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshl, N = 2))]
@@ -11454,6 +13360,8 @@ pub unsafe fn vqshld_n_u64<const N: i32>(a: u64) -> u64 {
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlub_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshlu, N = 2))]
@@ -11465,6 +13373,8 @@ pub unsafe fn vqshlub_n_s8<const N: i32>(a: i8) -> u8 {
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshlu, N = 2))]
@@ -11476,6 +13386,8 @@ pub unsafe fn vqshluh_n_s16<const N: i32>(a: i16) -> u16 {
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlus_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshlu, N = 2))]
@@ -11487,6 +13399,8 @@ pub unsafe fn vqshlus_n_s32<const N: i32>(a: i32) -> u32 {
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlud_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshlu, N = 2))]
@@ -11498,6 +13412,8 @@ pub unsafe fn vqshlud_n_s64<const N: i32>(a: i64) -> u64 {
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnd_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrn, N = 2))]
@@ -11514,6 +13430,8 @@ pub unsafe fn vqshrnd_n_s64<const N: i32>(a: i64) -> i32 {
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrn, N = 2))]
@@ -11525,6 +13443,8 @@ pub unsafe fn vqshrnh_n_s16<const N: i32>(a: i16) -> i8 {
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrns_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrn, N = 2))]
@@ -11536,6 +13456,8 @@ pub unsafe fn vqshrns_n_s32<const N: i32>(a: i32) -> i16 {
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrn2, N = 2))]
@@ -11547,6 +13469,8 @@ pub unsafe fn vqshrn_high_n_s16<const N: i32>(a: int8x8_t, b: int16x8_t) -> int8
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrn2, N = 2))]
@@ -11558,6 +13482,8 @@ pub unsafe fn vqshrn_high_n_s32<const N: i32>(a: int16x4_t, b: int32x4_t) -> int
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrn2, N = 2))]
@@ -11569,6 +13495,8 @@ pub unsafe fn vqshrn_high_n_s64<const N: i32>(a: int32x2_t, b: int64x2_t) -> int
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnd_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshrn, N = 2))]
@@ -11585,6 +13513,8 @@ pub unsafe fn vqshrnd_n_u64<const N: i32>(a: u64) -> u32 {
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnh_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshrn, N = 2))]
@@ -11596,6 +13526,8 @@ pub unsafe fn vqshrnh_n_u16<const N: i32>(a: u16) -> u8 {
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrns_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshrn, N = 2))]
@@ -11607,6 +13539,8 @@ pub unsafe fn vqshrns_n_u32<const N: i32>(a: u32) -> u16 {
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshrn2, N = 2))]
@@ -11618,6 +13552,8 @@ pub unsafe fn vqshrn_high_n_u16<const N: i32>(a: uint8x8_t, b: uint16x8_t) -> ui
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshrn2, N = 2))]
@@ -11629,6 +13565,8 @@ pub unsafe fn vqshrn_high_n_u32<const N: i32>(a: uint16x4_t, b: uint32x4_t) -> u
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uqshrn2, N = 2))]
@@ -11640,6 +13578,8 @@ pub unsafe fn vqshrn_high_n_u64<const N: i32>(a: uint32x2_t, b: uint64x2_t) -> u
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrunh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrun, N = 2))]
@@ -11651,6 +13591,8 @@ pub unsafe fn vqshrunh_n_s16<const N: i32>(a: i16) -> u8 {
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshruns_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrun, N = 2))]
@@ -11662,6 +13604,8 @@ pub unsafe fn vqshruns_n_s32<const N: i32>(a: i32) -> u16 {
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrund_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrun, N = 2))]
@@ -11673,6 +13617,8 @@ pub unsafe fn vqshrund_n_s64<const N: i32>(a: i64) -> u32 {
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrun2, N = 2))]
@@ -11684,6 +13630,8 @@ pub unsafe fn vqshrun_high_n_s16<const N: i32>(a: uint8x8_t, b: int16x8_t) -> ui
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrun2, N = 2))]
@@ -11695,6 +13643,8 @@ pub unsafe fn vqshrun_high_n_s32<const N: i32>(a: uint16x4_t, b: int32x4_t) -> u
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_high_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqshrun2, N = 2))]
@@ -11706,6 +13656,8 @@ pub unsafe fn vqshrun_high_n_s64<const N: i32>(a: uint32x2_t, b: int64x2_t) -> u
}
/// Unsigned saturating accumulate of signed value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddb_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usqadd))]
@@ -11715,6 +13667,8 @@ pub unsafe fn vsqaddb_u8(a: u8, b: i8) -> u8 {
}
/// Unsigned saturating accumulate of signed value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddh_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usqadd))]
@@ -11724,6 +13678,8 @@ pub unsafe fn vsqaddh_u16(a: u16, b: i16) -> u16 {
}
/// Unsigned saturating accumulate of signed value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqadds_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usqadd))]
@@ -11738,6 +13694,8 @@ pub unsafe fn vsqadds_u32(a: u32, b: i32) -> u32 {
}
/// Unsigned saturating accumulate of signed value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(usqadd))]
@@ -11752,6 +13710,8 @@ pub unsafe fn vsqaddd_u64(a: u64, b: i64) -> u64 {
}
/// Calculates the square root of each lane.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrt_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fsqrt))]
@@ -11761,6 +13721,8 @@ pub unsafe fn vsqrt_f32(a: float32x2_t) -> float32x2_t {
}
/// Calculates the square root of each lane.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrtq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fsqrt))]
@@ -11770,6 +13732,8 @@ pub unsafe fn vsqrtq_f32(a: float32x4_t) -> float32x4_t {
}
/// Calculates the square root of each lane.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrt_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fsqrt))]
@@ -11779,6 +13743,8 @@ pub unsafe fn vsqrt_f64(a: float64x1_t) -> float64x1_t {
}
/// Calculates the square root of each lane.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrtq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(fsqrt))]
@@ -11788,6 +13754,8 @@ pub unsafe fn vsqrtq_f64(a: float64x2_t) -> float64x2_t {
}
/// Reciprocal square-root estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrte))]
@@ -11802,6 +13770,8 @@ pub unsafe fn vrsqrte_f64(a: float64x1_t) -> float64x1_t {
}
/// Reciprocal square-root estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrte))]
@@ -11816,6 +13786,8 @@ pub unsafe fn vrsqrteq_f64(a: float64x2_t) -> float64x2_t {
}
/// Reciprocal square-root estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtes_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrte))]
@@ -11830,6 +13802,8 @@ pub unsafe fn vrsqrtes_f32(a: f32) -> f32 {
}
/// Reciprocal square-root estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrted_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrte))]
@@ -11844,6 +13818,8 @@ pub unsafe fn vrsqrted_f64(a: f64) -> f64 {
}
/// Floating-point reciprocal square root step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrts_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrts))]
@@ -11858,6 +13834,8 @@ pub unsafe fn vrsqrts_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Floating-point reciprocal square root step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrts))]
@@ -11872,6 +13850,8 @@ pub unsafe fn vrsqrtsq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point reciprocal square root step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtss_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrts))]
@@ -11886,6 +13866,8 @@ pub unsafe fn vrsqrtss_f32(a: f32, b: f32) -> f32 {
}
/// Floating-point reciprocal square root step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frsqrts))]
@@ -11900,6 +13882,8 @@ pub unsafe fn vrsqrtsd_f64(a: f64, b: f64) -> f64 {
}
/// Reciprocal estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecpe))]
@@ -11914,6 +13898,8 @@ pub unsafe fn vrecpe_f64(a: float64x1_t) -> float64x1_t {
}
/// Reciprocal estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecpe))]
@@ -11928,6 +13914,8 @@ pub unsafe fn vrecpeq_f64(a: float64x2_t) -> float64x2_t {
}
/// Reciprocal estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpes_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecpe))]
@@ -11942,6 +13930,8 @@ pub unsafe fn vrecpes_f32(a: f32) -> f32 {
}
/// Reciprocal estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecped_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecpe))]
@@ -11956,6 +13946,8 @@ pub unsafe fn vrecped_f64(a: f64) -> f64 {
}
/// Floating-point reciprocal step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecps_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecps))]
@@ -11970,6 +13962,8 @@ pub unsafe fn vrecps_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
}
/// Floating-point reciprocal step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsq_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecps))]
@@ -11984,6 +13978,8 @@ pub unsafe fn vrecpsq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Floating-point reciprocal step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpss_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecps))]
@@ -11998,6 +13994,8 @@ pub unsafe fn vrecpss_f32(a: f32, b: f32) -> f32 {
}
/// Floating-point reciprocal step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecps))]
@@ -12012,6 +14010,8 @@ pub unsafe fn vrecpsd_f64(a: f64, b: f64) -> f64 {
}
/// Floating-point reciprocal exponent
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpxs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecpx))]
@@ -12026,6 +14026,8 @@ pub unsafe fn vrecpxs_f32(a: f32) -> f32 {
}
/// Floating-point reciprocal exponent
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpxd_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(frecpx))]
@@ -12040,6 +14042,8 @@ pub unsafe fn vrecpxd_f64(a: f64) -> f64 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12049,6 +14053,8 @@ pub unsafe fn vreinterpret_s64_p64(a: poly64x1_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12058,6 +14064,8 @@ pub unsafe fn vreinterpret_u64_p64(a: poly64x1_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12067,6 +14075,8 @@ pub unsafe fn vreinterpret_p64_s64(a: int64x1_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12076,6 +14086,8 @@ pub unsafe fn vreinterpret_p64_u64(a: uint64x1_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12085,6 +14097,8 @@ pub unsafe fn vreinterpretq_s64_p64(a: poly64x2_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12094,6 +14108,8 @@ pub unsafe fn vreinterpretq_u64_p64(a: poly64x2_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12103,6 +14119,8 @@ pub unsafe fn vreinterpretq_p64_s64(a: int64x2_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12112,6 +14130,8 @@ pub unsafe fn vreinterpretq_p64_u64(a: uint64x2_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12121,6 +14141,8 @@ pub unsafe fn vreinterpret_s8_f64(a: float64x1_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12130,6 +14152,8 @@ pub unsafe fn vreinterpret_s16_f64(a: float64x1_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12139,6 +14163,8 @@ pub unsafe fn vreinterpret_s32_f64(a: float64x1_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12148,6 +14174,8 @@ pub unsafe fn vreinterpret_s64_f64(a: float64x1_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12157,6 +14185,8 @@ pub unsafe fn vreinterpretq_s8_f64(a: float64x2_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12166,6 +14196,8 @@ pub unsafe fn vreinterpretq_s16_f64(a: float64x2_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12175,6 +14207,8 @@ pub unsafe fn vreinterpretq_s32_f64(a: float64x2_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12184,6 +14218,8 @@ pub unsafe fn vreinterpretq_s64_f64(a: float64x2_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12193,6 +14229,8 @@ pub unsafe fn vreinterpret_u8_f64(a: float64x1_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12202,6 +14240,8 @@ pub unsafe fn vreinterpret_u16_f64(a: float64x1_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12211,6 +14251,8 @@ pub unsafe fn vreinterpret_u32_f64(a: float64x1_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12220,6 +14262,8 @@ pub unsafe fn vreinterpret_u64_f64(a: float64x1_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12229,6 +14273,8 @@ pub unsafe fn vreinterpretq_u8_f64(a: float64x2_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12238,6 +14284,8 @@ pub unsafe fn vreinterpretq_u16_f64(a: float64x2_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12247,6 +14295,8 @@ pub unsafe fn vreinterpretq_u32_f64(a: float64x2_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12256,6 +14306,8 @@ pub unsafe fn vreinterpretq_u64_f64(a: float64x2_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12265,6 +14317,8 @@ pub unsafe fn vreinterpret_p8_f64(a: float64x1_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12274,6 +14328,8 @@ pub unsafe fn vreinterpret_p16_f64(a: float64x1_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12283,6 +14339,8 @@ pub unsafe fn vreinterpret_p64_f32(a: float32x2_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12292,6 +14350,8 @@ pub unsafe fn vreinterpret_p64_f64(a: float64x1_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12301,6 +14361,8 @@ pub unsafe fn vreinterpretq_p8_f64(a: float64x2_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12310,6 +14372,8 @@ pub unsafe fn vreinterpretq_p16_f64(a: float64x2_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12319,6 +14383,8 @@ pub unsafe fn vreinterpretq_p64_f32(a: float32x4_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12328,6 +14394,8 @@ pub unsafe fn vreinterpretq_p64_f64(a: float64x2_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12337,6 +14405,8 @@ pub unsafe fn vreinterpretq_p128_f64(a: float64x2_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12346,6 +14416,8 @@ pub unsafe fn vreinterpret_f64_s8(a: int8x8_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12355,6 +14427,8 @@ pub unsafe fn vreinterpret_f64_s16(a: int16x4_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12364,6 +14438,8 @@ pub unsafe fn vreinterpret_f64_s32(a: int32x2_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12373,6 +14449,8 @@ pub unsafe fn vreinterpret_f64_s64(a: int64x1_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12382,6 +14460,8 @@ pub unsafe fn vreinterpretq_f64_s8(a: int8x16_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12391,6 +14471,8 @@ pub unsafe fn vreinterpretq_f64_s16(a: int16x8_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12400,6 +14482,8 @@ pub unsafe fn vreinterpretq_f64_s32(a: int32x4_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12409,6 +14493,8 @@ pub unsafe fn vreinterpretq_f64_s64(a: int64x2_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12418,6 +14504,8 @@ pub unsafe fn vreinterpret_f64_p8(a: poly8x8_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12427,6 +14515,8 @@ pub unsafe fn vreinterpret_f64_u16(a: uint16x4_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12436,6 +14526,8 @@ pub unsafe fn vreinterpret_f64_u32(a: uint32x2_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12445,6 +14537,8 @@ pub unsafe fn vreinterpret_f64_u64(a: uint64x1_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12454,6 +14548,8 @@ pub unsafe fn vreinterpretq_f64_p8(a: poly8x16_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12463,6 +14559,8 @@ pub unsafe fn vreinterpretq_f64_u16(a: uint16x8_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12472,6 +14570,8 @@ pub unsafe fn vreinterpretq_f64_u32(a: uint32x4_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12481,6 +14581,8 @@ pub unsafe fn vreinterpretq_f64_u64(a: uint64x2_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12490,6 +14592,8 @@ pub unsafe fn vreinterpret_f64_u8(a: uint8x8_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12499,6 +14603,8 @@ pub unsafe fn vreinterpret_f64_p16(a: poly16x4_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12508,6 +14614,8 @@ pub unsafe fn vreinterpret_f64_p64(a: poly64x1_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12517,6 +14625,8 @@ pub unsafe fn vreinterpret_f32_p64(a: poly64x1_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12526,6 +14636,8 @@ pub unsafe fn vreinterpretq_f64_u8(a: uint8x16_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12535,6 +14647,8 @@ pub unsafe fn vreinterpretq_f64_p16(a: poly16x8_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12544,6 +14658,8 @@ pub unsafe fn vreinterpretq_f64_p64(a: poly64x2_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12553,6 +14669,8 @@ pub unsafe fn vreinterpretq_f32_p64(a: poly64x2_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p128)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12562,6 +14680,8 @@ pub unsafe fn vreinterpretq_f64_p128(a: p128) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12571,6 +14691,8 @@ pub unsafe fn vreinterpret_f64_f32(a: float32x2_t) -> float64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12580,6 +14702,8 @@ pub unsafe fn vreinterpret_f32_f64(a: float64x1_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12589,6 +14713,8 @@ pub unsafe fn vreinterpretq_f64_f32(a: float32x4_t) -> float64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop))]
@@ -12598,6 +14724,8 @@ pub unsafe fn vreinterpretq_f32_f64(a: float64x2_t) -> float32x4_t {
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshld_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(srshl))]
@@ -12612,6 +14740,8 @@ pub unsafe fn vrshld_s64(a: i64, b: i64) -> i64 {
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshld_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(urshl))]
@@ -12626,6 +14756,8 @@ pub unsafe fn vrshld_u64(a: u64, b: i64) -> u64 {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrd_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(srshr, N = 2))]
@@ -12637,6 +14769,8 @@ pub unsafe fn vrshrd_n_s64<const N: i32>(a: i64) -> i64 {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrd_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(urshr, N = 2))]
@@ -12648,6 +14782,8 @@ pub unsafe fn vrshrd_n_u64<const N: i32>(a: u64) -> u64 {
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rshrn2, N = 2))]
@@ -12659,6 +14795,8 @@ pub unsafe fn vrshrn_high_n_s16<const N: i32>(a: int8x8_t, b: int16x8_t) -> int8
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rshrn2, N = 2))]
@@ -12670,6 +14808,8 @@ pub unsafe fn vrshrn_high_n_s32<const N: i32>(a: int16x4_t, b: int32x4_t) -> int
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rshrn2, N = 2))]
@@ -12681,6 +14821,8 @@ pub unsafe fn vrshrn_high_n_s64<const N: i32>(a: int32x2_t, b: int64x2_t) -> int
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rshrn2, N = 2))]
@@ -12692,6 +14834,8 @@ pub unsafe fn vrshrn_high_n_u16<const N: i32>(a: uint8x8_t, b: uint16x8_t) -> ui
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rshrn2, N = 2))]
@@ -12703,6 +14847,8 @@ pub unsafe fn vrshrn_high_n_u32<const N: i32>(a: uint16x4_t, b: uint32x4_t) -> u
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rshrn2, N = 2))]
@@ -12714,6 +14860,8 @@ pub unsafe fn vrshrn_high_n_u64<const N: i32>(a: uint32x2_t, b: uint64x2_t) -> u
}
/// Signed rounding shift right and accumulate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsrad_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(srsra, N = 2))]
@@ -12726,6 +14874,8 @@ pub unsafe fn vrsrad_n_s64<const N: i32>(a: i64, b: i64) -> i64 {
}
/// Ungisned rounding shift right and accumulate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsrad_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ursra, N = 2))]
@@ -12738,6 +14888,8 @@ pub unsafe fn vrsrad_n_u64<const N: i32>(a: u64, b: u64) -> u64 {
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rsubhn2))]
@@ -12748,6 +14900,8 @@ pub unsafe fn vrsubhn_high_s16(a: int8x8_t, b: int16x8_t, c: int16x8_t) -> int8x
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rsubhn2))]
@@ -12758,6 +14912,8 @@ pub unsafe fn vrsubhn_high_s32(a: int16x4_t, b: int32x4_t, c: int32x4_t) -> int1
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rsubhn2))]
@@ -12768,6 +14924,8 @@ pub unsafe fn vrsubhn_high_s64(a: int32x2_t, b: int64x2_t, c: int64x2_t) -> int3
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rsubhn2))]
@@ -12778,6 +14936,8 @@ pub unsafe fn vrsubhn_high_u16(a: uint8x8_t, b: uint16x8_t, c: uint16x8_t) -> ui
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rsubhn2))]
@@ -12788,6 +14948,8 @@ pub unsafe fn vrsubhn_high_u32(a: uint16x4_t, b: uint32x4_t, c: uint32x4_t) -> u
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(rsubhn2))]
@@ -12798,6 +14960,8 @@ pub unsafe fn vrsubhn_high_u64(a: uint32x2_t, b: uint64x2_t, c: uint64x2_t) -> u
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, LANE = 0))]
@@ -12809,6 +14973,8 @@ pub unsafe fn vset_lane_f64<const LANE: i32>(a: f64, b: float64x1_t) -> float64x
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(nop, LANE = 0))]
@@ -12820,6 +14986,8 @@ pub unsafe fn vsetq_lane_f64<const LANE: i32>(a: f64, b: float64x2_t) -> float64
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshld_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sshl))]
@@ -12829,6 +14997,8 @@ pub unsafe fn vshld_s64(a: i64, b: i64) -> i64 {
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshld_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ushl))]
@@ -12838,6 +15008,8 @@ pub unsafe fn vshld_u64(a: u64, b: i64) -> u64 {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sshll2, N = 2))]
@@ -12850,6 +15022,8 @@ pub unsafe fn vshll_high_n_s8<const N: i32>(a: int8x16_t) -> int16x8_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sshll2, N = 2))]
@@ -12862,6 +15036,8 @@ pub unsafe fn vshll_high_n_s16<const N: i32>(a: int16x8_t) -> int32x4_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sshll2, N = 2))]
@@ -12874,6 +15050,8 @@ pub unsafe fn vshll_high_n_s32<const N: i32>(a: int32x4_t) -> int64x2_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ushll2, N = 2))]
@@ -12886,6 +15064,8 @@ pub unsafe fn vshll_high_n_u8<const N: i32>(a: uint8x16_t) -> uint16x8_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ushll2, N = 2))]
@@ -12898,6 +15078,8 @@ pub unsafe fn vshll_high_n_u16<const N: i32>(a: uint16x8_t) -> uint32x4_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(ushll2, N = 2))]
@@ -12910,6 +15092,8 @@ pub unsafe fn vshll_high_n_u32<const N: i32>(a: uint32x4_t) -> uint64x2_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(shrn2, N = 2))]
@@ -12921,6 +15105,8 @@ pub unsafe fn vshrn_high_n_s16<const N: i32>(a: int8x8_t, b: int16x8_t) -> int8x
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(shrn2, N = 2))]
@@ -12932,6 +15118,8 @@ pub unsafe fn vshrn_high_n_s32<const N: i32>(a: int16x4_t, b: int32x4_t) -> int1
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(shrn2, N = 2))]
@@ -12943,6 +15131,8 @@ pub unsafe fn vshrn_high_n_s64<const N: i32>(a: int32x2_t, b: int64x2_t) -> int3
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(shrn2, N = 2))]
@@ -12954,6 +15144,8 @@ pub unsafe fn vshrn_high_n_u16<const N: i32>(a: uint8x8_t, b: uint16x8_t) -> uin
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(shrn2, N = 2))]
@@ -12965,6 +15157,8 @@ pub unsafe fn vshrn_high_n_u32<const N: i32>(a: uint16x4_t, b: uint32x4_t) -> ui
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(shrn2, N = 2))]
@@ -12976,6 +15170,8 @@ pub unsafe fn vshrn_high_n_u64<const N: i32>(a: uint32x2_t, b: uint64x2_t) -> ui
}
/// SM3PARTW1
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3partw1q_u32)
#[inline]
#[target_feature(enable = "neon,sm4")]
#[cfg_attr(test, assert_instr(sm3partw1))]
@@ -12989,6 +15185,8 @@ pub unsafe fn vsm3partw1q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> ui
}
/// SM3PARTW2
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3partw2q_u32)
#[inline]
#[target_feature(enable = "neon,sm4")]
#[cfg_attr(test, assert_instr(sm3partw2))]
@@ -13002,6 +15200,8 @@ pub unsafe fn vsm3partw2q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> ui
}
/// SM3SS1
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3ss1q_u32)
#[inline]
#[target_feature(enable = "neon,sm4")]
#[cfg_attr(test, assert_instr(sm3ss1))]
@@ -13015,6 +15215,8 @@ pub unsafe fn vsm3ss1q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint3
}
/// SM4 key
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm4ekeyq_u32)
#[inline]
#[target_feature(enable = "neon,sm4")]
#[cfg_attr(test, assert_instr(sm4ekey))]
@@ -13028,6 +15230,8 @@ pub unsafe fn vsm4ekeyq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// SM4 encode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm4eq_u32)
#[inline]
#[target_feature(enable = "neon,sm4")]
#[cfg_attr(test, assert_instr(sm4e))]
@@ -13041,6 +15245,8 @@ pub unsafe fn vsm4eq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Rotate and exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrax1q_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(rax1))]
@@ -13054,6 +15260,8 @@ pub unsafe fn vrax1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// SHA512 hash update part 1
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512hq_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(sha512h))]
@@ -13067,6 +15275,8 @@ pub unsafe fn vsha512hq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint
}
/// SHA512 hash update part 2
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512h2q_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(sha512h2))]
@@ -13080,6 +15290,8 @@ pub unsafe fn vsha512h2q_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uin
}
/// SHA512 schedule update 0
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512su0q_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(sha512su0))]
@@ -13093,6 +15305,8 @@ pub unsafe fn vsha512su0q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// SHA512 schedule update 1
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512su1q_u64)
#[inline]
#[target_feature(enable = "neon,sha3")]
#[cfg_attr(test, assert_instr(sha512su1))]
@@ -13106,6 +15320,8 @@ pub unsafe fn vsha512su1q_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> ui
}
/// Floating-point round to 32-bit integer, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32x_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint32x))]
@@ -13119,6 +15335,8 @@ pub unsafe fn vrnd32x_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to 32-bit integer, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32xq_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint32x))]
@@ -13132,6 +15350,8 @@ pub unsafe fn vrnd32xq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to 32-bit integer toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32z_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint32z))]
@@ -13145,6 +15365,8 @@ pub unsafe fn vrnd32z_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to 32-bit integer toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32zq_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint32z))]
@@ -13158,6 +15380,8 @@ pub unsafe fn vrnd32zq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to 64-bit integer, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64x_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint64x))]
@@ -13171,6 +15395,8 @@ pub unsafe fn vrnd64x_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to 64-bit integer, using current rounding mode
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64xq_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint64x))]
@@ -13184,6 +15410,8 @@ pub unsafe fn vrnd64xq_f32(a: float32x4_t) -> float32x4_t {
}
/// Floating-point round to 64-bit integer toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64z_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint64z))]
@@ -13197,6 +15425,8 @@ pub unsafe fn vrnd64z_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point round to 64-bit integer toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64zq_f32)
#[inline]
#[target_feature(enable = "neon,frintts")]
#[cfg_attr(test, assert_instr(frint64z))]
@@ -13210,6 +15440,8 @@ pub unsafe fn vrnd64zq_f32(a: float32x4_t) -> float32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13219,6 +15451,8 @@ pub unsafe fn vtrn1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13228,6 +15462,8 @@ pub unsafe fn vtrn1q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13237,6 +15473,8 @@ pub unsafe fn vtrn1_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13246,6 +15484,8 @@ pub unsafe fn vtrn1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13255,6 +15495,8 @@ pub unsafe fn vtrn1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13264,6 +15506,8 @@ pub unsafe fn vtrn1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13273,6 +15517,8 @@ pub unsafe fn vtrn1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13282,6 +15528,8 @@ pub unsafe fn vtrn1_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13291,6 +15539,8 @@ pub unsafe fn vtrn1q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13300,6 +15550,8 @@ pub unsafe fn vtrn1q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13309,6 +15561,8 @@ pub unsafe fn vtrn1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13318,6 +15572,8 @@ pub unsafe fn vtrn1q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13327,6 +15583,8 @@ pub unsafe fn vtrn1_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13336,6 +15594,8 @@ pub unsafe fn vtrn1q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13345,6 +15605,8 @@ pub unsafe fn vtrn1_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13354,6 +15616,8 @@ pub unsafe fn vtrn1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13363,6 +15627,8 @@ pub unsafe fn vtrn1_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13372,6 +15638,8 @@ pub unsafe fn vtrn1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13381,6 +15649,8 @@ pub unsafe fn vtrn1q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn1))]
@@ -13390,6 +15660,8 @@ pub unsafe fn vtrn1q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13399,6 +15671,8 @@ pub unsafe fn vtrn1_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13408,6 +15682,8 @@ pub unsafe fn vtrn1q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13417,6 +15693,8 @@ pub unsafe fn vtrn2_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13426,6 +15704,8 @@ pub unsafe fn vtrn2q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13435,6 +15715,8 @@ pub unsafe fn vtrn2_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13444,6 +15726,8 @@ pub unsafe fn vtrn2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13453,6 +15737,8 @@ pub unsafe fn vtrn2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13462,6 +15748,8 @@ pub unsafe fn vtrn2_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13471,6 +15759,8 @@ pub unsafe fn vtrn2q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13480,6 +15770,8 @@ pub unsafe fn vtrn2_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13489,6 +15781,8 @@ pub unsafe fn vtrn2q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13498,6 +15792,8 @@ pub unsafe fn vtrn2q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13507,6 +15803,8 @@ pub unsafe fn vtrn2_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13516,6 +15814,8 @@ pub unsafe fn vtrn2q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13525,6 +15825,8 @@ pub unsafe fn vtrn2_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13534,6 +15836,8 @@ pub unsafe fn vtrn2q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13543,6 +15847,8 @@ pub unsafe fn vtrn2_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13552,6 +15858,8 @@ pub unsafe fn vtrn2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13561,6 +15869,8 @@ pub unsafe fn vtrn2_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13570,6 +15880,8 @@ pub unsafe fn vtrn2q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13579,6 +15891,8 @@ pub unsafe fn vtrn2q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(trn2))]
@@ -13588,6 +15902,8 @@ pub unsafe fn vtrn2q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13597,6 +15913,8 @@ pub unsafe fn vtrn2_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Transpose vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13606,6 +15924,8 @@ pub unsafe fn vtrn2q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13615,6 +15935,8 @@ pub unsafe fn vzip1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13624,6 +15946,8 @@ pub unsafe fn vzip1q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13633,6 +15957,8 @@ pub unsafe fn vzip1_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13642,6 +15968,8 @@ pub unsafe fn vzip1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13651,6 +15979,8 @@ pub unsafe fn vzip1_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13660,6 +15990,8 @@ pub unsafe fn vzip1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13669,6 +16001,8 @@ pub unsafe fn vzip1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13678,6 +16012,8 @@ pub unsafe fn vzip1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13687,6 +16023,8 @@ pub unsafe fn vzip1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13696,6 +16034,8 @@ pub unsafe fn vzip1_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13705,6 +16045,8 @@ pub unsafe fn vzip1q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13714,6 +16056,8 @@ pub unsafe fn vzip1_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13723,6 +16067,8 @@ pub unsafe fn vzip1q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13732,6 +16078,8 @@ pub unsafe fn vzip1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13741,6 +16089,8 @@ pub unsafe fn vzip1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13750,6 +16100,8 @@ pub unsafe fn vzip1q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13759,6 +16111,8 @@ pub unsafe fn vzip1_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13768,6 +16122,8 @@ pub unsafe fn vzip1q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13777,6 +16133,8 @@ pub unsafe fn vzip1q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13786,6 +16144,8 @@ pub unsafe fn vzip1_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13795,6 +16155,8 @@ pub unsafe fn vzip1q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -13804,6 +16166,8 @@ pub unsafe fn vzip1q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13813,6 +16177,8 @@ pub unsafe fn vzip2_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13822,6 +16188,8 @@ pub unsafe fn vzip2q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13831,6 +16199,8 @@ pub unsafe fn vzip2_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13840,6 +16210,8 @@ pub unsafe fn vzip2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13849,6 +16221,8 @@ pub unsafe fn vzip2_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13858,6 +16232,8 @@ pub unsafe fn vzip2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13867,6 +16243,8 @@ pub unsafe fn vzip2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13876,6 +16254,8 @@ pub unsafe fn vzip2_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13885,6 +16265,8 @@ pub unsafe fn vzip2q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13894,6 +16276,8 @@ pub unsafe fn vzip2_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13903,6 +16287,8 @@ pub unsafe fn vzip2q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13912,6 +16298,8 @@ pub unsafe fn vzip2_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13921,6 +16309,8 @@ pub unsafe fn vzip2q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13930,6 +16320,8 @@ pub unsafe fn vzip2q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13939,6 +16331,8 @@ pub unsafe fn vzip2_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13948,6 +16342,8 @@ pub unsafe fn vzip2q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13957,6 +16353,8 @@ pub unsafe fn vzip2_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13966,6 +16364,8 @@ pub unsafe fn vzip2q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13975,6 +16375,8 @@ pub unsafe fn vzip2q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13984,6 +16386,8 @@ pub unsafe fn vzip2_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -13993,6 +16397,8 @@ pub unsafe fn vzip2q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14002,6 +16408,8 @@ pub unsafe fn vzip2q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14011,6 +16419,8 @@ pub unsafe fn vuzp1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14020,6 +16430,8 @@ pub unsafe fn vuzp1q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14029,6 +16441,8 @@ pub unsafe fn vuzp1_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14038,6 +16452,8 @@ pub unsafe fn vuzp1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14047,6 +16463,8 @@ pub unsafe fn vuzp1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14056,6 +16474,8 @@ pub unsafe fn vuzp1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14065,6 +16485,8 @@ pub unsafe fn vuzp1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14074,6 +16496,8 @@ pub unsafe fn vuzp1_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14083,6 +16507,8 @@ pub unsafe fn vuzp1q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14092,6 +16518,8 @@ pub unsafe fn vuzp1q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14101,6 +16529,8 @@ pub unsafe fn vuzp1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14110,6 +16540,8 @@ pub unsafe fn vuzp1q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14119,6 +16551,8 @@ pub unsafe fn vuzp1_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14128,6 +16562,8 @@ pub unsafe fn vuzp1q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14137,6 +16573,8 @@ pub unsafe fn vuzp1_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14146,6 +16584,8 @@ pub unsafe fn vuzp1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14155,6 +16595,8 @@ pub unsafe fn vuzp1_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14164,6 +16606,8 @@ pub unsafe fn vuzp1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14173,6 +16617,8 @@ pub unsafe fn vuzp1q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp1))]
@@ -14182,6 +16628,8 @@ pub unsafe fn vuzp1q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14191,6 +16639,8 @@ pub unsafe fn vuzp1_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip1))]
@@ -14200,6 +16650,8 @@ pub unsafe fn vuzp1q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14209,6 +16661,8 @@ pub unsafe fn vuzp2_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14218,6 +16672,8 @@ pub unsafe fn vuzp2q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14227,6 +16683,8 @@ pub unsafe fn vuzp2_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14236,6 +16694,8 @@ pub unsafe fn vuzp2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14245,6 +16705,8 @@ pub unsafe fn vuzp2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14254,6 +16716,8 @@ pub unsafe fn vuzp2_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14263,6 +16727,8 @@ pub unsafe fn vuzp2q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14272,6 +16738,8 @@ pub unsafe fn vuzp2_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14281,6 +16749,8 @@ pub unsafe fn vuzp2q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14290,6 +16760,8 @@ pub unsafe fn vuzp2q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14299,6 +16771,8 @@ pub unsafe fn vuzp2_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14308,6 +16782,8 @@ pub unsafe fn vuzp2q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14317,6 +16793,8 @@ pub unsafe fn vuzp2_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14326,6 +16804,8 @@ pub unsafe fn vuzp2q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14335,6 +16815,8 @@ pub unsafe fn vuzp2_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14344,6 +16826,8 @@ pub unsafe fn vuzp2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14353,6 +16837,8 @@ pub unsafe fn vuzp2_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14362,6 +16848,8 @@ pub unsafe fn vuzp2q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14371,6 +16859,8 @@ pub unsafe fn vuzp2q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uzp2))]
@@ -14380,6 +16870,8 @@ pub unsafe fn vuzp2q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14389,6 +16881,8 @@ pub unsafe fn vuzp2_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_f64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(zip2))]
@@ -14398,6 +16892,8 @@ pub unsafe fn vuzp2q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
}
/// Unsigned Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uabal))]
@@ -14410,6 +16906,8 @@ pub unsafe fn vabal_high_u8(a: uint16x8_t, b: uint8x16_t, c: uint8x16_t) -> uint
}
/// Unsigned Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uabal))]
@@ -14422,6 +16920,8 @@ pub unsafe fn vabal_high_u16(a: uint32x4_t, b: uint16x8_t, c: uint16x8_t) -> uin
}
/// Unsigned Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(uabal))]
@@ -14434,6 +16934,8 @@ pub unsafe fn vabal_high_u32(a: uint64x2_t, b: uint32x4_t, c: uint32x4_t) -> uin
}
/// Signed Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sabal))]
@@ -14447,6 +16949,8 @@ pub unsafe fn vabal_high_s8(a: int16x8_t, b: int8x16_t, c: int8x16_t) -> int16x8
}
/// Signed Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sabal))]
@@ -14460,6 +16964,8 @@ pub unsafe fn vabal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x
}
/// Signed Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sabal))]
@@ -14473,6 +16979,8 @@ pub unsafe fn vabal_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqabs))]
@@ -14487,6 +16995,8 @@ pub unsafe fn vqabs_s64(a: int64x1_t) -> int64x1_t {
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqabs))]
@@ -14501,6 +17011,8 @@ pub unsafe fn vqabsq_s64(a: int64x2_t) -> int64x2_t {
}
/// Signed saturating absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsb_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqabs))]
@@ -14510,6 +17022,8 @@ pub unsafe fn vqabsb_s8(a: i8) -> i8 {
}
/// Signed saturating absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqabs))]
@@ -14519,6 +17033,8 @@ pub unsafe fn vqabsh_s16(a: i16) -> i16 {
}
/// Signed saturating absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabss_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqabs))]
@@ -14533,6 +17049,8 @@ pub unsafe fn vqabss_s32(a: i32) -> i32 {
}
/// Signed saturating absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sqabs))]
@@ -14547,6 +17065,8 @@ pub unsafe fn vqabsd_s64(a: i64) -> i64 {
}
/// Shift left and insert
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vslid_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sli, N = 2))]
@@ -14558,6 +17078,8 @@ pub unsafe fn vslid_n_s64<const N: i32>(a: i64, b: i64) -> i64 {
}
/// Shift left and insert
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vslid_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sli, N = 2))]
@@ -14569,6 +17091,8 @@ pub unsafe fn vslid_n_u64<const N: i32>(a: u64, b: u64) -> u64 {
}
/// Shift right and insert
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsrid_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sri, N = 2))]
@@ -14580,6 +17104,8 @@ pub unsafe fn vsrid_n_s64<const N: i32>(a: i64, b: i64) -> i64 {
}
/// Shift right and insert
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsrid_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(sri, N = 2))]
@@ -17603,18 +20129,18 @@ mod test {
#[simd_test(enable = "neon")]
unsafe fn test_vextq_p64() {
- let a: i64x2 = i64x2::new(0, 8);
- let b: i64x2 = i64x2::new(9, 11);
- let e: i64x2 = i64x2::new(8, 9);
+ let a: i64x2 = i64x2::new(1, 1);
+ let b: i64x2 = i64x2::new(2, 2);
+ let e: i64x2 = i64x2::new(1, 2);
let r: i64x2 = transmute(vextq_p64::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_f64() {
- let a: f64x2 = f64x2::new(0., 2.);
- let b: f64x2 = f64x2::new(3., 4.);
- let e: f64x2 = f64x2::new(2., 3.);
+ let a: f64x2 = f64x2::new(1., 1.);
+ let b: f64x2 = f64x2::new(2., 2.);
+ let e: f64x2 = f64x2::new(1., 2.);
let r: f64x2 = transmute(vextq_f64::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs
index 65ba527ee..9d9946b4f 100644
--- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs
+++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs
@@ -28,14 +28,17 @@ types! {
}
/// ARM-specific type containing two `float64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub struct float64x1x2_t(pub float64x1_t, pub float64x1_t);
/// ARM-specific type containing three `float64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub struct float64x1x3_t(pub float64x1_t, pub float64x1_t, pub float64x1_t);
/// ARM-specific type containing four `float64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub struct float64x1x4_t(
@@ -46,14 +49,17 @@ pub struct float64x1x4_t(
);
/// ARM-specific type containing two `float64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub struct float64x2x2_t(pub float64x2_t, pub float64x2_t);
/// ARM-specific type containing three `float64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub struct float64x2x3_t(pub float64x2_t, pub float64x2_t, pub float64x2_t);
/// ARM-specific type containing four `float64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub struct float64x2x4_t(
@@ -658,6 +664,8 @@ pub unsafe fn vld1q_p16(ptr: *const p16) -> poly16x8_t {
}
/// Load multiple single-element structures to one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ldr))]
@@ -667,6 +675,8 @@ pub unsafe fn vld1_p64(ptr: *const p64) -> poly64x1_t {
}
/// Load multiple single-element structures to one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(ldr))]
@@ -953,6 +963,8 @@ pub unsafe fn vst1q_p16(ptr: *mut p16, a: poly16x8_t) {
}
// Store multiple single-element structures from one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(str))]
@@ -963,6 +975,8 @@ pub unsafe fn vst1_p64(ptr: *mut p64, a: poly64x1_t) {
}
// Store multiple single-element structures from one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(str))]
@@ -1045,7 +1059,11 @@ pub unsafe fn vabsq_s64(a: int64x2_t) -> int64x2_t {
#[cfg_attr(test, assert_instr(bsl))]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub unsafe fn vbsl_f64(a: uint64x1_t, b: float64x1_t, c: float64x1_t) -> float64x1_t {
- simd_select(transmute::<_, int64x1_t>(a), b, c)
+ let not = int64x1_t(-1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
#[inline]
@@ -1053,7 +1071,11 @@ pub unsafe fn vbsl_f64(a: uint64x1_t, b: float64x1_t, c: float64x1_t) -> float64
#[cfg_attr(test, assert_instr(bsl))]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub unsafe fn vbsl_p64(a: poly64x1_t, b: poly64x1_t, c: poly64x1_t) -> poly64x1_t {
- simd_select(transmute::<_, int64x1_t>(a), b, c)
+ let not = int64x1_t(-1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
#[inline]
@@ -1061,7 +1083,11 @@ pub unsafe fn vbsl_p64(a: poly64x1_t, b: poly64x1_t, c: poly64x1_t) -> poly64x1_
#[cfg_attr(test, assert_instr(bsl))]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub unsafe fn vbslq_f64(a: uint64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t {
- simd_select(transmute::<_, int64x2_t>(a), b, c)
+ let not = int64x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
#[inline]
@@ -1069,7 +1095,11 @@ pub unsafe fn vbslq_f64(a: uint64x2_t, b: float64x2_t, c: float64x2_t) -> float6
#[cfg_attr(test, assert_instr(bsl))]
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
pub unsafe fn vbslq_p64(a: poly64x2_t, b: poly64x2_t, c: poly64x2_t) -> poly64x2_t {
- simd_select(transmute::<_, int64x2_t>(a), b, c)
+ let not = int64x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Signed saturating Accumulate of Unsigned value.
@@ -3365,7 +3395,10 @@ pub unsafe fn vsliq_n_p16<const N: i32>(a: poly16x8_t, b: poly16x8_t) -> poly16x
static_assert_imm4!(N);
transmute(vsliq_n_s16_(transmute(a), transmute(b), N))
}
+
/// Shift Left and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(sli, N = 1))]
@@ -3375,7 +3408,10 @@ pub unsafe fn vsli_n_p64<const N: i32>(a: poly64x1_t, b: poly64x1_t) -> poly64x1
static_assert!(N: i32 where N >= 0 && N <= 63);
transmute(vsli_n_s64_(transmute(a), transmute(b), N))
}
+
/// Shift Left and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(sli, N = 1))]
@@ -3585,7 +3621,10 @@ pub unsafe fn vsriq_n_p16<const N: i32>(a: poly16x8_t, b: poly16x8_t) -> poly16x
static_assert!(N: i32 where N >= 1 && N <= 16);
transmute(vsriq_n_s16_(transmute(a), transmute(b), N))
}
+
/// Shift Right and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(sri, N = 1))]
@@ -3595,7 +3634,10 @@ pub unsafe fn vsri_n_p64<const N: i32>(a: poly64x1_t, b: poly64x1_t) -> poly64x1
static_assert!(N: i32 where N >= 1 && N <= 64);
transmute(vsri_n_s64_(transmute(a), transmute(b), N))
}
+
/// Shift Right and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(sri, N = 1))]
@@ -5136,37 +5178,37 @@ mod tests {
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_f64() {
- let a = u64x1::new(u64::MAX);
- let b = f64x1::new(f64::MAX);
- let c = f64x1::new(f64::MIN);
- let e = f64x1::new(f64::MAX);
+ let a = u64x1::new(0x8000000000000000);
+ let b = f64x1::new(-1.23f64);
+ let c = f64x1::new(2.34f64);
+ let e = f64x1::new(-2.34f64);
let r: f64x1 = transmute(vbsl_f64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_p64() {
- let a = u64x1::new(u64::MAX);
+ let a = u64x1::new(1);
let b = u64x1::new(u64::MAX);
let c = u64x1::new(u64::MIN);
- let e = u64x1::new(u64::MAX);
+ let e = u64x1::new(1);
let r: u64x1 = transmute(vbsl_p64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_f64() {
- let a = u64x2::new(u64::MAX, 0);
- let b = f64x2::new(f64::MAX, f64::MAX);
- let c = f64x2::new(f64::MIN, f64::MIN);
- let e = f64x2::new(f64::MAX, f64::MIN);
+ let a = u64x2::new(1, 0x8000000000000000);
+ let b = f64x2::new(f64::MAX, -1.23f64);
+ let c = f64x2::new(f64::MIN, 2.34f64);
+ let e = f64x2::new(f64::MIN, -2.34f64);
let r: f64x2 = transmute(vbslq_f64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_p64() {
- let a = u64x2::new(u64::MAX, 0);
+ let a = u64x2::new(u64::MAX, 1);
let b = u64x2::new(u64::MAX, u64::MAX);
let c = u64x2::new(u64::MIN, u64::MIN);
- let e = u64x2::new(u64::MAX, u64::MIN);
+ let e = u64x2::new(u64::MAX, 1);
let r: u64x2 = transmute(vbslq_p64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
diff --git a/library/stdarch/crates/core_arch/src/arm/neon.rs b/library/stdarch/crates/core_arch/src/arm/neon.rs
index a0ad92c33..a6291c95c 100644
--- a/library/stdarch/crates/core_arch/src/arm/neon.rs
+++ b/library/stdarch/crates/core_arch/src/arm/neon.rs
@@ -289,6 +289,8 @@ pub unsafe fn vld1q_p16(ptr: *const p16) -> poly16x8_t {
}
/// Load multiple single-element structures to one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr(vldr))]
@@ -297,6 +299,8 @@ pub unsafe fn vld1_p64(ptr: *const p64) -> poly64x1_t {
}
/// Load multiple single-element structures to one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(test, assert_instr("vld1.64"))]
@@ -481,6 +485,8 @@ pub unsafe fn vst1q_p16(ptr: *mut p16, a: poly16x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64)
#[inline]
#[target_feature(enable = "neon,aes,v8")]
#[cfg_attr(test, assert_instr("vst1.64"))]
@@ -489,6 +495,8 @@ pub unsafe fn vst1_p64(ptr: *mut p64, a: poly64x1_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64)
#[inline]
#[target_feature(enable = "neon,aes,v8")]
#[cfg_attr(test, assert_instr("vst1.64"))]
@@ -1033,6 +1041,7 @@ pub unsafe fn vsli_n_p16<const N: i32>(a: poly16x4_t, b: poly16x4_t) -> poly16x4
int16x4_t(n, n, n, n),
))
}
+
/// Shift Left and Insert (immediate)
#[inline]
#[target_feature(enable = "neon,v7")]
@@ -1047,7 +1056,10 @@ pub unsafe fn vsliq_n_p16<const N: i32>(a: poly16x8_t, b: poly16x8_t) -> poly16x
int16x8_t(n, n, n, n, n, n, n, n),
))
}
+
/// Shift Left and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p64)
#[inline]
#[target_feature(enable = "neon,v7,aes")]
#[cfg_attr(test, assert_instr("vsli.64", N = 1))]
@@ -1060,7 +1072,10 @@ pub unsafe fn vsli_n_p64<const N: i32>(a: poly64x1_t, b: poly64x1_t) -> poly64x1
int64x1_t(N as i64),
))
}
+
/// Shift Left and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p64)
#[inline]
#[target_feature(enable = "neon,v7,aes")]
#[cfg_attr(test, assert_instr("vsli.64", N = 1))]
@@ -1317,7 +1332,10 @@ pub unsafe fn vsriq_n_p16<const N: i32>(a: poly16x8_t, b: poly16x8_t) -> poly16x
int16x8_t(n, n, n, n, n, n, n, n),
))
}
+
/// Shift Right and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p64)
#[inline]
#[target_feature(enable = "neon,v7,aes")]
#[cfg_attr(test, assert_instr("vsri.64", N = 1))]
@@ -1330,7 +1348,10 @@ pub unsafe fn vsri_n_p64<const N: i32>(a: poly64x1_t, b: poly64x1_t) -> poly64x1
int64x1_t(-N as i64),
))
}
+
/// Shift Right and Insert (immediate)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p64)
#[inline]
#[target_feature(enable = "neon,v7,aes")]
#[cfg_attr(test, assert_instr("vsri.64", N = 1))]
diff --git a/library/stdarch/crates/core_arch/src/arm/v7.rs b/library/stdarch/crates/core_arch/src/arm/v7.rs
index e7507f9b9..59beaf722 100644
--- a/library/stdarch/crates/core_arch/src/arm/v7.rs
+++ b/library/stdarch/crates/core_arch/src/arm/v7.rs
@@ -76,7 +76,6 @@ mod tests {
}
#[test]
- #[cfg(dont_compile_me)] // FIXME need to add `v7` upstream in rustc
fn _rbit_u32() {
unsafe {
assert_eq!(
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/crc.rs b/library/stdarch/crates/core_arch/src/arm_shared/crc.rs
index e0d0fbe35..779d1ed42 100644
--- a/library/stdarch/crates/core_arch/src/arm_shared/crc.rs
+++ b/library/stdarch/crates/core_arch/src/arm_shared/crc.rs
@@ -24,6 +24,8 @@ extern "unadjusted" {
use stdarch_test::assert_instr;
/// CRC32 single round checksum for bytes (8 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32b)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
@@ -33,6 +35,8 @@ pub unsafe fn __crc32b(crc: u32, data: u8) -> u32 {
}
/// CRC32 single round checksum for half words (16 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32h)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
@@ -42,6 +46,8 @@ pub unsafe fn __crc32h(crc: u32, data: u16) -> u32 {
}
/// CRC32 single round checksum for words (32 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32w)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
@@ -51,6 +57,8 @@ pub unsafe fn __crc32w(crc: u32, data: u32) -> u32 {
}
/// CRC32-C single round checksum for bytes (8 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cb)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
@@ -60,6 +68,8 @@ pub unsafe fn __crc32cb(crc: u32, data: u8) -> u32 {
}
/// CRC32-C single round checksum for half words (16 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32ch)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
@@ -69,6 +79,8 @@ pub unsafe fn __crc32ch(crc: u32, data: u16) -> u32 {
}
/// CRC32-C single round checksum for words (32 bits).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cw)
#[inline]
#[target_feature(enable = "crc")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/crypto.rs b/library/stdarch/crates/core_arch/src/arm_shared/crypto.rs
index 3e9515e59..060091136 100644
--- a/library/stdarch/crates/core_arch/src/arm_shared/crypto.rs
+++ b/library/stdarch/crates/core_arch/src/arm_shared/crypto.rs
@@ -52,6 +52,8 @@ extern "unadjusted" {
use stdarch_test::assert_instr;
/// AES single round encryption.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaeseq_u8)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "aes"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -61,6 +63,8 @@ pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
}
/// AES single round decryption.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesdq_u8)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "aes"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -70,6 +74,8 @@ pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
}
/// AES mix columns.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesmcq_u8)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "aes"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -79,6 +85,8 @@ pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
}
/// AES inverse mix columns.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesimcq_u8)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "aes"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -88,6 +96,8 @@ pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
}
/// SHA1 fixed rotate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1h_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -97,6 +107,8 @@ pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
}
/// SHA1 hash update accelerator, choose.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1cq_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -106,6 +118,8 @@ pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
}
/// SHA1 hash update accelerator, majority.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1mq_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -115,6 +129,8 @@ pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
}
/// SHA1 hash update accelerator, parity.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1pq_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -124,6 +140,8 @@ pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
}
/// SHA1 schedule update accelerator, first part.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1su0q_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -133,6 +151,8 @@ pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_
}
/// SHA1 schedule update accelerator, second part.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1su1q_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -142,6 +162,8 @@ pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t
}
/// SHA256 hash update accelerator.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256hq_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -155,6 +177,8 @@ pub unsafe fn vsha256hq_u32(
}
/// SHA256 hash update accelerator, upper part.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256h2q_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -168,6 +192,8 @@ pub unsafe fn vsha256h2q_u32(
}
/// SHA256 schedule update accelerator, first part.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256su0q_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
@@ -177,6 +203,8 @@ pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t
}
/// SHA256 schedule update accelerator, second part.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256su1q_u32)
#[inline]
#[cfg_attr(not(target_arch = "arm"), target_feature(enable = "sha2"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs
index d69fbd8e8..ac2709744 100644
--- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs
+++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs
@@ -10,6 +10,8 @@ use super::*;
use stdarch_test::assert_instr;
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21,6 +23,8 @@ pub unsafe fn vand_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -32,6 +36,8 @@ pub unsafe fn vandq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -43,6 +49,8 @@ pub unsafe fn vand_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -54,6 +62,8 @@ pub unsafe fn vandq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -65,6 +75,8 @@ pub unsafe fn vand_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -76,6 +88,8 @@ pub unsafe fn vandq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -87,6 +101,8 @@ pub unsafe fn vand_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -98,6 +114,8 @@ pub unsafe fn vandq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -109,6 +127,8 @@ pub unsafe fn vand_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -120,6 +140,8 @@ pub unsafe fn vandq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -131,6 +153,8 @@ pub unsafe fn vand_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -142,6 +166,8 @@ pub unsafe fn vandq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -153,6 +179,8 @@ pub unsafe fn vand_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -164,6 +192,8 @@ pub unsafe fn vandq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -175,6 +205,8 @@ pub unsafe fn vand_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Vector bitwise and
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -186,6 +218,8 @@ pub unsafe fn vandq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -197,6 +231,8 @@ pub unsafe fn vorr_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -208,6 +244,8 @@ pub unsafe fn vorrq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -219,6 +257,8 @@ pub unsafe fn vorr_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -230,6 +270,8 @@ pub unsafe fn vorrq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -241,6 +283,8 @@ pub unsafe fn vorr_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -252,6 +296,8 @@ pub unsafe fn vorrq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -263,6 +309,8 @@ pub unsafe fn vorr_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -274,6 +322,8 @@ pub unsafe fn vorrq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -285,6 +335,8 @@ pub unsafe fn vorr_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -296,6 +348,8 @@ pub unsafe fn vorrq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -307,6 +361,8 @@ pub unsafe fn vorr_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -318,6 +374,8 @@ pub unsafe fn vorrq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -329,6 +387,8 @@ pub unsafe fn vorr_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -340,6 +400,8 @@ pub unsafe fn vorrq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -351,6 +413,8 @@ pub unsafe fn vorr_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Vector bitwise or (immediate, inclusive)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -362,6 +426,8 @@ pub unsafe fn vorrq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -373,6 +439,8 @@ pub unsafe fn veor_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -384,6 +452,8 @@ pub unsafe fn veorq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -395,6 +465,8 @@ pub unsafe fn veor_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -406,6 +478,8 @@ pub unsafe fn veorq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -417,6 +491,8 @@ pub unsafe fn veor_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -428,6 +504,8 @@ pub unsafe fn veorq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -439,6 +517,8 @@ pub unsafe fn veor_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -450,6 +530,8 @@ pub unsafe fn veorq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -461,6 +543,8 @@ pub unsafe fn veor_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -472,6 +556,8 @@ pub unsafe fn veorq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -483,6 +569,8 @@ pub unsafe fn veor_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -494,6 +582,8 @@ pub unsafe fn veorq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -505,6 +595,8 @@ pub unsafe fn veor_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -516,6 +608,8 @@ pub unsafe fn veorq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -527,6 +621,8 @@ pub unsafe fn veor_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Vector bitwise exclusive or (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -538,6 +634,8 @@ pub unsafe fn veorq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -555,6 +653,8 @@ vabd_s8_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -572,6 +672,8 @@ vabdq_s8_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -589,6 +691,8 @@ vabd_s16_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -606,6 +710,8 @@ vabdq_s16_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -623,6 +729,8 @@ vabd_s32_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -640,6 +748,8 @@ vabdq_s32_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -657,6 +767,8 @@ vabd_u8_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -674,6 +786,8 @@ vabdq_u8_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -691,6 +805,8 @@ vabd_u16_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -708,6 +824,8 @@ vabdq_u16_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -725,6 +843,8 @@ vabd_u32_(a, b)
}
/// Absolute difference between the arguments
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -742,6 +862,8 @@ vabdq_u32_(a, b)
}
/// Absolute difference between the arguments of Floating
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -759,6 +881,8 @@ vabd_f32_(a, b)
}
/// Absolute difference between the arguments of Floating
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -776,6 +900,8 @@ vabdq_f32_(a, b)
}
/// Unsigned Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -787,6 +913,8 @@ pub unsafe fn vabdl_u8(a: uint8x8_t, b: uint8x8_t) -> uint16x8_t {
}
/// Unsigned Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -798,6 +926,8 @@ pub unsafe fn vabdl_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4_t {
}
/// Unsigned Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -809,6 +939,8 @@ pub unsafe fn vabdl_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2_t {
}
/// Signed Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -821,6 +953,8 @@ pub unsafe fn vabdl_s8(a: int8x8_t, b: int8x8_t) -> int16x8_t {
}
/// Signed Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -833,6 +967,8 @@ pub unsafe fn vabdl_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
}
/// Signed Absolute difference Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -845,6 +981,8 @@ pub unsafe fn vabdl_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -856,6 +994,8 @@ pub unsafe fn vceq_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -867,6 +1007,8 @@ pub unsafe fn vceqq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -878,6 +1020,8 @@ pub unsafe fn vceq_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -889,6 +1033,8 @@ pub unsafe fn vceqq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -900,6 +1046,8 @@ pub unsafe fn vceq_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -911,6 +1059,8 @@ pub unsafe fn vceqq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -922,6 +1072,8 @@ pub unsafe fn vceq_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -933,6 +1085,8 @@ pub unsafe fn vceqq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -944,6 +1098,8 @@ pub unsafe fn vceq_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -955,6 +1111,8 @@ pub unsafe fn vceqq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -966,6 +1124,8 @@ pub unsafe fn vceq_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -977,6 +1137,8 @@ pub unsafe fn vceqq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -988,6 +1150,8 @@ pub unsafe fn vceq_p8(a: poly8x8_t, b: poly8x8_t) -> uint8x8_t {
}
/// Compare bitwise Equal (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -999,6 +1163,8 @@ pub unsafe fn vceqq_p8(a: poly8x16_t, b: poly8x16_t) -> uint8x16_t {
}
/// Floating-point compare equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1010,6 +1176,8 @@ pub unsafe fn vceq_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1021,6 +1189,8 @@ pub unsafe fn vceqq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1034,6 +1204,8 @@ pub unsafe fn vtst_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1047,6 +1219,8 @@ pub unsafe fn vtstq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1060,6 +1234,8 @@ pub unsafe fn vtst_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1073,6 +1249,8 @@ pub unsafe fn vtstq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1086,6 +1264,8 @@ pub unsafe fn vtst_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1099,6 +1279,8 @@ pub unsafe fn vtstq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1112,6 +1294,8 @@ pub unsafe fn vtst_p8(a: poly8x8_t, b: poly8x8_t) -> uint8x8_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1125,6 +1309,8 @@ pub unsafe fn vtstq_p8(a: poly8x16_t, b: poly8x16_t) -> uint8x16_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1138,6 +1324,8 @@ pub unsafe fn vtst_p16(a: poly16x4_t, b: poly16x4_t) -> uint16x4_t {
}
/// Signed compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1151,6 +1339,8 @@ pub unsafe fn vtstq_p16(a: poly16x8_t, b: poly16x8_t) -> uint16x8_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1164,6 +1354,8 @@ pub unsafe fn vtst_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1177,6 +1369,8 @@ pub unsafe fn vtstq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1190,6 +1384,8 @@ pub unsafe fn vtst_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1203,6 +1399,8 @@ pub unsafe fn vtstq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1216,6 +1414,8 @@ pub unsafe fn vtst_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Unsigned compare bitwise Test bits nonzero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1229,6 +1429,8 @@ pub unsafe fn vtstq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Floating-point absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1240,6 +1442,8 @@ pub unsafe fn vabs_f32(a: float32x2_t) -> float32x2_t {
}
/// Floating-point absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1251,6 +1455,8 @@ pub unsafe fn vabsq_f32(a: float32x4_t) -> float32x4_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1262,6 +1468,8 @@ pub unsafe fn vcgt_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1273,6 +1481,8 @@ pub unsafe fn vcgtq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1284,6 +1494,8 @@ pub unsafe fn vcgt_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1295,6 +1507,8 @@ pub unsafe fn vcgtq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1306,6 +1520,8 @@ pub unsafe fn vcgt_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
}
/// Compare signed greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1317,6 +1533,8 @@ pub unsafe fn vcgtq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1328,6 +1546,8 @@ pub unsafe fn vcgt_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1339,6 +1559,8 @@ pub unsafe fn vcgtq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1350,6 +1572,8 @@ pub unsafe fn vcgt_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1361,6 +1585,8 @@ pub unsafe fn vcgtq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1372,6 +1598,8 @@ pub unsafe fn vcgt_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Compare unsigned highe
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1383,6 +1611,8 @@ pub unsafe fn vcgtq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Floating-point compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1394,6 +1624,8 @@ pub unsafe fn vcgt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1405,6 +1637,8 @@ pub unsafe fn vcgtq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1416,6 +1650,8 @@ pub unsafe fn vclt_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1427,6 +1663,8 @@ pub unsafe fn vcltq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1438,6 +1676,8 @@ pub unsafe fn vclt_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1449,6 +1689,8 @@ pub unsafe fn vcltq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1460,6 +1702,8 @@ pub unsafe fn vclt_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
}
/// Compare signed less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1471,6 +1715,8 @@ pub unsafe fn vcltq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1482,6 +1728,8 @@ pub unsafe fn vclt_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1493,6 +1741,8 @@ pub unsafe fn vcltq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1504,6 +1754,8 @@ pub unsafe fn vclt_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1515,6 +1767,8 @@ pub unsafe fn vcltq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1526,6 +1780,8 @@ pub unsafe fn vclt_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Compare unsigned less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1537,6 +1793,8 @@ pub unsafe fn vcltq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Floating-point compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1548,6 +1806,8 @@ pub unsafe fn vclt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1559,6 +1819,8 @@ pub unsafe fn vcltq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1570,6 +1832,8 @@ pub unsafe fn vcle_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1581,6 +1845,8 @@ pub unsafe fn vcleq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1592,6 +1858,8 @@ pub unsafe fn vcle_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1603,6 +1871,8 @@ pub unsafe fn vcleq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1614,6 +1884,8 @@ pub unsafe fn vcle_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
}
/// Compare signed less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1625,6 +1897,8 @@ pub unsafe fn vcleq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1636,6 +1910,8 @@ pub unsafe fn vcle_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1647,6 +1923,8 @@ pub unsafe fn vcleq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1658,6 +1936,8 @@ pub unsafe fn vcle_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1669,6 +1949,8 @@ pub unsafe fn vcleq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1680,6 +1962,8 @@ pub unsafe fn vcle_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Compare unsigned less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1691,6 +1975,8 @@ pub unsafe fn vcleq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Floating-point compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1702,6 +1988,8 @@ pub unsafe fn vcle_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1713,6 +2001,8 @@ pub unsafe fn vcleq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1724,6 +2014,8 @@ pub unsafe fn vcge_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1735,6 +2027,8 @@ pub unsafe fn vcgeq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1746,6 +2040,8 @@ pub unsafe fn vcge_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1757,6 +2053,8 @@ pub unsafe fn vcgeq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1768,6 +2066,8 @@ pub unsafe fn vcge_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
}
/// Compare signed greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1779,6 +2079,8 @@ pub unsafe fn vcgeq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1790,6 +2092,8 @@ pub unsafe fn vcge_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1801,6 +2105,8 @@ pub unsafe fn vcgeq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1812,6 +2118,8 @@ pub unsafe fn vcge_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1823,6 +2131,8 @@ pub unsafe fn vcgeq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1834,6 +2144,8 @@ pub unsafe fn vcge_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Compare unsigned greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1845,6 +2157,8 @@ pub unsafe fn vcgeq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Floating-point compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1856,6 +2170,8 @@ pub unsafe fn vcge_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1867,6 +2183,8 @@ pub unsafe fn vcgeq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1884,6 +2202,8 @@ vcls_s8_(a)
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1901,6 +2221,8 @@ vclsq_s8_(a)
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1918,6 +2240,8 @@ vcls_s16_(a)
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1935,6 +2259,8 @@ vclsq_s16_(a)
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1952,6 +2278,8 @@ vcls_s32_(a)
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1969,6 +2297,8 @@ vclsq_s32_(a)
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1980,6 +2310,8 @@ pub unsafe fn vcls_u8(a: uint8x8_t) -> int8x8_t {
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1991,6 +2323,8 @@ pub unsafe fn vclsq_u8(a: uint8x16_t) -> int8x16_t {
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2002,6 +2336,8 @@ pub unsafe fn vcls_u16(a: uint16x4_t) -> int16x4_t {
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2013,6 +2349,8 @@ pub unsafe fn vclsq_u16(a: uint16x8_t) -> int16x8_t {
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2024,6 +2362,8 @@ pub unsafe fn vcls_u32(a: uint32x2_t) -> int32x2_t {
}
/// Count leading sign bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2035,6 +2375,8 @@ pub unsafe fn vclsq_u32(a: uint32x4_t) -> int32x4_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2046,6 +2388,8 @@ pub unsafe fn vclz_s8(a: int8x8_t) -> int8x8_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2057,6 +2401,8 @@ pub unsafe fn vclzq_s8(a: int8x16_t) -> int8x16_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2068,6 +2414,8 @@ pub unsafe fn vclz_s16(a: int16x4_t) -> int16x4_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2079,6 +2427,8 @@ pub unsafe fn vclzq_s16(a: int16x8_t) -> int16x8_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2090,6 +2440,8 @@ pub unsafe fn vclz_s32(a: int32x2_t) -> int32x2_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2101,6 +2453,8 @@ pub unsafe fn vclzq_s32(a: int32x4_t) -> int32x4_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2112,6 +2466,8 @@ pub unsafe fn vclz_u8(a: uint8x8_t) -> uint8x8_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2123,6 +2479,8 @@ pub unsafe fn vclzq_u8(a: uint8x16_t) -> uint8x16_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2134,6 +2492,8 @@ pub unsafe fn vclz_u16(a: uint16x4_t) -> uint16x4_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2145,6 +2505,8 @@ pub unsafe fn vclzq_u16(a: uint16x8_t) -> uint16x8_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2156,6 +2518,8 @@ pub unsafe fn vclz_u32(a: uint32x2_t) -> uint32x2_t {
}
/// Count leading zero bits
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2167,6 +2531,8 @@ pub unsafe fn vclzq_u32(a: uint32x4_t) -> uint32x4_t {
}
/// Floating-point absolute compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagt_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2184,6 +2550,8 @@ vcagt_f32_(a, b)
}
/// Floating-point absolute compare greater than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2201,6 +2569,8 @@ vcagtq_f32_(a, b)
}
/// Floating-point absolute compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcage_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2218,6 +2588,8 @@ vcage_f32_(a, b)
}
/// Floating-point absolute compare greater than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcageq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2235,6 +2607,8 @@ vcageq_f32_(a, b)
}
/// Floating-point absolute compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalt_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2246,6 +2620,8 @@ pub unsafe fn vcalt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point absolute compare less than
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2257,6 +2633,8 @@ pub unsafe fn vcaltq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Floating-point absolute compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcale_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2268,6 +2646,8 @@ pub unsafe fn vcale_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
}
/// Floating-point absolute compare less than or equal
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaleq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2279,6 +2659,8 @@ pub unsafe fn vcaleq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2290,6 +2672,8 @@ pub unsafe fn vcreate_s8(a: u64) -> int8x8_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2301,6 +2685,8 @@ pub unsafe fn vcreate_s16(a: u64) -> int16x4_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2312,6 +2698,8 @@ pub unsafe fn vcreate_s32(a: u64) -> int32x2_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2323,6 +2711,8 @@ pub unsafe fn vcreate_s64(a: u64) -> int64x1_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2334,6 +2724,8 @@ pub unsafe fn vcreate_u8(a: u64) -> uint8x8_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2345,6 +2737,8 @@ pub unsafe fn vcreate_u16(a: u64) -> uint16x4_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2356,6 +2750,8 @@ pub unsafe fn vcreate_u32(a: u64) -> uint32x2_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2367,6 +2763,8 @@ pub unsafe fn vcreate_u64(a: u64) -> uint64x1_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2378,6 +2776,8 @@ pub unsafe fn vcreate_p8(a: u64) -> poly8x8_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2389,6 +2789,8 @@ pub unsafe fn vcreate_p16(a: u64) -> poly16x4_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -2400,6 +2802,8 @@ pub unsafe fn vcreate_p64(a: u64) -> poly64x1_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2411,6 +2815,8 @@ pub unsafe fn vcreate_f32(a: u64) -> float32x2_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2422,6 +2828,8 @@ pub unsafe fn vcvt_f32_s32(a: int32x2_t) -> float32x2_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2433,6 +2841,8 @@ pub unsafe fn vcvtq_f32_s32(a: int32x4_t) -> float32x4_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2444,6 +2854,8 @@ pub unsafe fn vcvt_f32_u32(a: uint32x2_t) -> float32x2_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2455,6 +2867,8 @@ pub unsafe fn vcvtq_f32_u32(a: uint32x4_t) -> float32x4_t {
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2471,6 +2885,8 @@ vcvt_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2488,6 +2904,8 @@ vcvt_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2504,6 +2922,8 @@ vcvtq_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2521,6 +2941,8 @@ vcvtq_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_u32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2537,6 +2959,8 @@ vcvt_n_f32_u32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_u32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2554,6 +2978,8 @@ vcvt_n_f32_u32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_u32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2570,6 +2996,8 @@ vcvtq_n_f32_u32_(a, N)
}
/// Fixed-point convert to floating-point
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_u32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2587,6 +3015,8 @@ vcvtq_n_f32_u32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s32_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2603,6 +3033,8 @@ vcvt_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s32_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2620,6 +3052,8 @@ vcvt_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s32_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2636,6 +3070,8 @@ vcvtq_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s32_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2653,6 +3089,8 @@ vcvtq_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u32_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2669,6 +3107,8 @@ vcvt_n_u32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u32_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2686,6 +3126,8 @@ vcvt_n_u32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u32_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -2702,6 +3144,8 @@ vcvtq_n_u32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u32_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -2719,6 +3163,8 @@ vcvtq_n_u32_f32_(a, N)
}
/// Floating-point convert to signed fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2736,6 +3182,8 @@ vcvt_s32_f32_(a)
}
/// Floating-point convert to signed fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2753,6 +3201,8 @@ vcvtq_s32_f32_(a)
}
/// Floating-point convert to unsigned fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2770,6 +3220,8 @@ vcvt_u32_f32_(a)
}
/// Floating-point convert to unsigned fixed-point, rounding toward zero
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2787,6 +3239,8 @@ vcvtq_u32_f32_(a)
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2800,6 +3254,8 @@ pub unsafe fn vdup_lane_s8<const N: i32>(a: int8x8_t) -> int8x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2813,6 +3269,8 @@ pub unsafe fn vdupq_laneq_s8<const N: i32>(a: int8x16_t) -> int8x16_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2826,6 +3284,8 @@ pub unsafe fn vdup_lane_s16<const N: i32>(a: int16x4_t) -> int16x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2839,6 +3299,8 @@ pub unsafe fn vdupq_laneq_s16<const N: i32>(a: int16x8_t) -> int16x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2852,6 +3314,8 @@ pub unsafe fn vdup_lane_s32<const N: i32>(a: int32x2_t) -> int32x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2865,6 +3329,8 @@ pub unsafe fn vdupq_laneq_s32<const N: i32>(a: int32x4_t) -> int32x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2878,6 +3344,8 @@ pub unsafe fn vdup_laneq_s8<const N: i32>(a: int8x16_t) -> int8x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2891,6 +3359,8 @@ pub unsafe fn vdup_laneq_s16<const N: i32>(a: int16x8_t) -> int16x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2904,6 +3374,8 @@ pub unsafe fn vdup_laneq_s32<const N: i32>(a: int32x4_t) -> int32x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2917,6 +3389,8 @@ pub unsafe fn vdupq_lane_s8<const N: i32>(a: int8x8_t) -> int8x16_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2930,6 +3404,8 @@ pub unsafe fn vdupq_lane_s16<const N: i32>(a: int16x4_t) -> int16x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2943,6 +3419,8 @@ pub unsafe fn vdupq_lane_s32<const N: i32>(a: int32x2_t) -> int32x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2956,6 +3434,8 @@ pub unsafe fn vdup_lane_u8<const N: i32>(a: uint8x8_t) -> uint8x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2969,6 +3449,8 @@ pub unsafe fn vdupq_laneq_u8<const N: i32>(a: uint8x16_t) -> uint8x16_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2982,6 +3464,8 @@ pub unsafe fn vdup_lane_u16<const N: i32>(a: uint16x4_t) -> uint16x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -2995,6 +3479,8 @@ pub unsafe fn vdupq_laneq_u16<const N: i32>(a: uint16x8_t) -> uint16x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3008,6 +3494,8 @@ pub unsafe fn vdup_lane_u32<const N: i32>(a: uint32x2_t) -> uint32x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3021,6 +3509,8 @@ pub unsafe fn vdupq_laneq_u32<const N: i32>(a: uint32x4_t) -> uint32x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3034,6 +3524,8 @@ pub unsafe fn vdup_laneq_u8<const N: i32>(a: uint8x16_t) -> uint8x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3047,6 +3539,8 @@ pub unsafe fn vdup_laneq_u16<const N: i32>(a: uint16x8_t) -> uint16x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3060,6 +3554,8 @@ pub unsafe fn vdup_laneq_u32<const N: i32>(a: uint32x4_t) -> uint32x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3073,6 +3569,8 @@ pub unsafe fn vdupq_lane_u8<const N: i32>(a: uint8x8_t) -> uint8x16_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3086,6 +3584,8 @@ pub unsafe fn vdupq_lane_u16<const N: i32>(a: uint16x4_t) -> uint16x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3099,6 +3599,8 @@ pub unsafe fn vdupq_lane_u32<const N: i32>(a: uint32x2_t) -> uint32x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3112,6 +3614,8 @@ pub unsafe fn vdup_lane_p8<const N: i32>(a: poly8x8_t) -> poly8x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3125,6 +3629,8 @@ pub unsafe fn vdupq_laneq_p8<const N: i32>(a: poly8x16_t) -> poly8x16_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3138,6 +3644,8 @@ pub unsafe fn vdup_lane_p16<const N: i32>(a: poly16x4_t) -> poly16x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3151,6 +3659,8 @@ pub unsafe fn vdupq_laneq_p16<const N: i32>(a: poly16x8_t) -> poly16x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3164,6 +3674,8 @@ pub unsafe fn vdup_laneq_p8<const N: i32>(a: poly8x16_t) -> poly8x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3177,6 +3689,8 @@ pub unsafe fn vdup_laneq_p16<const N: i32>(a: poly16x8_t) -> poly16x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3190,6 +3704,8 @@ pub unsafe fn vdupq_lane_p8<const N: i32>(a: poly8x8_t) -> poly8x16_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3203,6 +3719,8 @@ pub unsafe fn vdupq_lane_p16<const N: i32>(a: poly16x4_t) -> poly16x8_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3216,6 +3734,8 @@ pub unsafe fn vdupq_laneq_s64<const N: i32>(a: int64x2_t) -> int64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3229,6 +3749,8 @@ pub unsafe fn vdupq_lane_s64<const N: i32>(a: int64x1_t) -> int64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3242,6 +3764,8 @@ pub unsafe fn vdupq_laneq_u64<const N: i32>(a: uint64x2_t) -> uint64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3255,6 +3779,8 @@ pub unsafe fn vdupq_lane_u64<const N: i32>(a: uint64x1_t) -> uint64x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3268,6 +3794,8 @@ pub unsafe fn vdup_lane_f32<const N: i32>(a: float32x2_t) -> float32x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3281,6 +3809,8 @@ pub unsafe fn vdupq_laneq_f32<const N: i32>(a: float32x4_t) -> float32x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3294,6 +3824,8 @@ pub unsafe fn vdup_laneq_f32<const N: i32>(a: float32x4_t) -> float32x2_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3307,6 +3839,8 @@ pub unsafe fn vdupq_lane_f32<const N: i32>(a: float32x2_t) -> float32x4_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3320,6 +3854,8 @@ pub unsafe fn vdup_lane_s64<const N: i32>(a: int64x1_t) -> int64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3333,6 +3869,8 @@ pub unsafe fn vdup_lane_u64<const N: i32>(a: uint64x1_t) -> uint64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3346,6 +3884,8 @@ pub unsafe fn vdup_laneq_s64<const N: i32>(a: int64x2_t) -> int64x1_t {
}
/// Set all vector lanes to the same value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3359,11 +3899,13 @@ pub unsafe fn vdup_laneq_u64<const N: i32>(a: uint64x2_t) -> uint64x1_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 4))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 4))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 7))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vext_s8<const N: i32>(a: int8x8_t, b: int8x8_t) -> int8x8_t {
@@ -3382,11 +3924,13 @@ pub unsafe fn vext_s8<const N: i32>(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 8))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 8))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 15))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 15))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_s8<const N: i32>(a: int8x16_t, b: int8x16_t) -> int8x16_t {
@@ -3413,11 +3957,13 @@ pub unsafe fn vextq_s8<const N: i32>(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 2))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 2))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 3))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vext_s16<const N: i32>(a: int16x4_t, b: int16x4_t) -> int16x4_t {
@@ -3432,11 +3978,13 @@ pub unsafe fn vext_s16<const N: i32>(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 4))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 4))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 7))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_s16<const N: i32>(a: int16x8_t, b: int16x8_t) -> int16x8_t {
@@ -3455,6 +4003,8 @@ pub unsafe fn vextq_s16<const N: i32>(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3472,11 +4022,13 @@ pub unsafe fn vext_s32<const N: i32>(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 2))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 2))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 3))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_s32<const N: i32>(a: int32x4_t, b: int32x4_t) -> int32x4_t {
@@ -3491,11 +4043,13 @@ pub unsafe fn vextq_s32<const N: i32>(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 4))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 4))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 7))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vext_u8<const N: i32>(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
@@ -3514,11 +4068,13 @@ pub unsafe fn vext_u8<const N: i32>(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 8))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 8))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 15))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 15))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_u8<const N: i32>(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
@@ -3545,11 +4101,13 @@ pub unsafe fn vextq_u8<const N: i32>(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 2))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 2))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 3))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vext_u16<const N: i32>(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
@@ -3564,11 +4122,13 @@ pub unsafe fn vext_u16<const N: i32>(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 4))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 4))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 7))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_u16<const N: i32>(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
@@ -3587,6 +4147,8 @@ pub unsafe fn vextq_u16<const N: i32>(a: uint16x8_t, b: uint16x8_t) -> uint16x8_
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3604,11 +4166,13 @@ pub unsafe fn vext_u32<const N: i32>(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 2))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 2))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 3))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_u32<const N: i32>(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
@@ -3623,11 +4187,13 @@ pub unsafe fn vextq_u32<const N: i32>(a: uint32x4_t, b: uint32x4_t) -> uint32x4_
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 4))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 4))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 7))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vext_p8<const N: i32>(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
@@ -3646,11 +4212,13 @@ pub unsafe fn vext_p8<const N: i32>(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 8))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 8))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 15))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 15))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_p8<const N: i32>(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
@@ -3677,11 +4245,13 @@ pub unsafe fn vextq_p8<const N: i32>(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 2))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 2))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 3))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vext_p16<const N: i32>(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
@@ -3696,11 +4266,13 @@ pub unsafe fn vext_p16<const N: i32>(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 4))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 4))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 7))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_p16<const N: i32>(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
@@ -3719,6 +4291,8 @@ pub unsafe fn vextq_p16<const N: i32>(a: poly16x8_t, b: poly16x8_t) -> poly16x8_
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3736,6 +4310,8 @@ pub unsafe fn vextq_s64<const N: i32>(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3753,6 +4329,8 @@ pub unsafe fn vextq_u64<const N: i32>(a: uint64x2_t, b: uint64x2_t) -> uint64x2_
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3770,11 +4348,13 @@ pub unsafe fn vext_f32<const N: i32>(a: float32x2_t, b: float32x2_t) -> float32x
}
/// Extract vector from pair of vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
-#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 2))]
-#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 2))]
+#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
+#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ext, N = 3))]
#[rustc_legacy_const_generics(2)]
#[cfg_attr(target_arch = "aarch64", stable(feature = "neon_intrinsics", since = "1.59.0"))]
pub unsafe fn vextq_f32<const N: i32>(a: float32x4_t, b: float32x4_t) -> float32x4_t {
@@ -3789,6 +4369,8 @@ pub unsafe fn vextq_f32<const N: i32>(a: float32x4_t, b: float32x4_t) -> float32
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3800,6 +4382,8 @@ pub unsafe fn vmla_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3811,6 +4395,8 @@ pub unsafe fn vmlaq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3822,6 +4408,8 @@ pub unsafe fn vmla_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3833,6 +4421,8 @@ pub unsafe fn vmlaq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3844,6 +4434,8 @@ pub unsafe fn vmla_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3855,6 +4447,8 @@ pub unsafe fn vmlaq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3866,6 +4460,8 @@ pub unsafe fn vmla_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3877,6 +4473,8 @@ pub unsafe fn vmlaq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3888,6 +4486,8 @@ pub unsafe fn vmla_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3899,6 +4499,8 @@ pub unsafe fn vmlaq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3910,6 +4512,8 @@ pub unsafe fn vmla_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_
}
/// Multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3921,6 +4525,8 @@ pub unsafe fn vmlaq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4
}
/// Floating-point multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3932,6 +4538,8 @@ pub unsafe fn vmla_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float3
}
/// Floating-point multiply-add to accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3943,6 +4551,8 @@ pub unsafe fn vmlaq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3954,6 +4564,8 @@ pub unsafe fn vmla_n_s16(a: int16x4_t, b: int16x4_t, c: i16) -> int16x4_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3965,6 +4577,8 @@ pub unsafe fn vmlaq_n_s16(a: int16x8_t, b: int16x8_t, c: i16) -> int16x8_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3976,6 +4590,8 @@ pub unsafe fn vmla_n_s32(a: int32x2_t, b: int32x2_t, c: i32) -> int32x2_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3987,6 +4603,8 @@ pub unsafe fn vmlaq_n_s32(a: int32x4_t, b: int32x4_t, c: i32) -> int32x4_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3998,6 +4616,8 @@ pub unsafe fn vmla_n_u16(a: uint16x4_t, b: uint16x4_t, c: u16) -> uint16x4_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4009,6 +4629,8 @@ pub unsafe fn vmlaq_n_u16(a: uint16x8_t, b: uint16x8_t, c: u16) -> uint16x8_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4020,6 +4642,8 @@ pub unsafe fn vmla_n_u32(a: uint32x2_t, b: uint32x2_t, c: u32) -> uint32x2_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4031,6 +4655,8 @@ pub unsafe fn vmlaq_n_u32(a: uint32x4_t, b: uint32x4_t, c: u32) -> uint32x4_t {
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4042,6 +4668,8 @@ pub unsafe fn vmla_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4053,6 +4681,8 @@ pub unsafe fn vmlaq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4066,6 +4696,8 @@ pub unsafe fn vmla_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c: int1
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4079,6 +4711,8 @@ pub unsafe fn vmla_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c: int
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4092,6 +4726,8 @@ pub unsafe fn vmlaq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c: int
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4105,6 +4741,8 @@ pub unsafe fn vmlaq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c: in
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4118,6 +4756,8 @@ pub unsafe fn vmla_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c: int3
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4131,6 +4771,8 @@ pub unsafe fn vmla_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c: int
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4144,6 +4786,8 @@ pub unsafe fn vmlaq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c: int
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4157,6 +4801,8 @@ pub unsafe fn vmlaq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c: in
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4170,6 +4816,8 @@ pub unsafe fn vmla_lane_u16<const LANE: i32>(a: uint16x4_t, b: uint16x4_t, c: ui
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4183,6 +4831,8 @@ pub unsafe fn vmla_laneq_u16<const LANE: i32>(a: uint16x4_t, b: uint16x4_t, c: u
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4196,6 +4846,8 @@ pub unsafe fn vmlaq_lane_u16<const LANE: i32>(a: uint16x8_t, b: uint16x8_t, c: u
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4209,6 +4861,8 @@ pub unsafe fn vmlaq_laneq_u16<const LANE: i32>(a: uint16x8_t, b: uint16x8_t, c:
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4222,6 +4876,8 @@ pub unsafe fn vmla_lane_u32<const LANE: i32>(a: uint32x2_t, b: uint32x2_t, c: ui
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4235,6 +4891,8 @@ pub unsafe fn vmla_laneq_u32<const LANE: i32>(a: uint32x2_t, b: uint32x2_t, c: u
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4248,6 +4906,8 @@ pub unsafe fn vmlaq_lane_u32<const LANE: i32>(a: uint32x4_t, b: uint32x4_t, c: u
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4261,6 +4921,8 @@ pub unsafe fn vmlaq_laneq_u32<const LANE: i32>(a: uint32x4_t, b: uint32x4_t, c:
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4274,6 +4936,8 @@ pub unsafe fn vmla_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4287,6 +4951,8 @@ pub unsafe fn vmla_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4300,6 +4966,8 @@ pub unsafe fn vmlaq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c:
}
/// Vector multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4313,6 +4981,8 @@ pub unsafe fn vmlaq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c
}
/// Signed multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4324,6 +4994,8 @@ pub unsafe fn vmlal_s8(a: int16x8_t, b: int8x8_t, c: int8x8_t) -> int16x8_t {
}
/// Signed multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4335,6 +5007,8 @@ pub unsafe fn vmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
}
/// Signed multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4346,6 +5020,8 @@ pub unsafe fn vmlal_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
}
/// Unsigned multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4357,6 +5033,8 @@ pub unsafe fn vmlal_u8(a: uint16x8_t, b: uint8x8_t, c: uint8x8_t) -> uint16x8_t
}
/// Unsigned multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4368,6 +5046,8 @@ pub unsafe fn vmlal_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4_t) -> uint32x4
}
/// Unsigned multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4379,6 +5059,8 @@ pub unsafe fn vmlal_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2_t) -> uint64x2
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4390,6 +5072,8 @@ pub unsafe fn vmlal_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4401,6 +5085,8 @@ pub unsafe fn vmlal_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4412,6 +5098,8 @@ pub unsafe fn vmlal_n_u16(a: uint32x4_t, b: uint16x4_t, c: u16) -> uint32x4_t {
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4423,6 +5111,8 @@ pub unsafe fn vmlal_n_u32(a: uint64x2_t, b: uint32x2_t, c: u32) -> uint64x2_t {
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4436,6 +5126,8 @@ pub unsafe fn vmlal_lane_s16<const LANE: i32>(a: int32x4_t, b: int16x4_t, c: int
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4449,6 +5141,8 @@ pub unsafe fn vmlal_laneq_s16<const LANE: i32>(a: int32x4_t, b: int16x4_t, c: in
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4462,6 +5156,8 @@ pub unsafe fn vmlal_lane_s32<const LANE: i32>(a: int64x2_t, b: int32x2_t, c: int
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4475,6 +5171,8 @@ pub unsafe fn vmlal_laneq_s32<const LANE: i32>(a: int64x2_t, b: int32x2_t, c: in
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4488,6 +5186,8 @@ pub unsafe fn vmlal_lane_u16<const LANE: i32>(a: uint32x4_t, b: uint16x4_t, c: u
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4501,6 +5201,8 @@ pub unsafe fn vmlal_laneq_u16<const LANE: i32>(a: uint32x4_t, b: uint16x4_t, c:
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4514,6 +5216,8 @@ pub unsafe fn vmlal_lane_u32<const LANE: i32>(a: uint64x2_t, b: uint32x2_t, c: u
}
/// Vector widening multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4527,6 +5231,8 @@ pub unsafe fn vmlal_laneq_u32<const LANE: i32>(a: uint64x2_t, b: uint32x2_t, c:
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4538,6 +5244,8 @@ pub unsafe fn vmls_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4549,6 +5257,8 @@ pub unsafe fn vmlsq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4560,6 +5270,8 @@ pub unsafe fn vmls_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4571,6 +5283,8 @@ pub unsafe fn vmlsq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4582,6 +5296,8 @@ pub unsafe fn vmls_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4593,6 +5309,8 @@ pub unsafe fn vmlsq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4604,6 +5322,8 @@ pub unsafe fn vmls_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4615,6 +5335,8 @@ pub unsafe fn vmlsq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4626,6 +5348,8 @@ pub unsafe fn vmls_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4637,6 +5361,8 @@ pub unsafe fn vmlsq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4648,6 +5374,8 @@ pub unsafe fn vmls_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_
}
/// Multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4659,6 +5387,8 @@ pub unsafe fn vmlsq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4
}
/// Floating-point multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4670,6 +5400,8 @@ pub unsafe fn vmls_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float3
}
/// Floating-point multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4681,6 +5413,8 @@ pub unsafe fn vmlsq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4692,6 +5426,8 @@ pub unsafe fn vmls_n_s16(a: int16x4_t, b: int16x4_t, c: i16) -> int16x4_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4703,6 +5439,8 @@ pub unsafe fn vmlsq_n_s16(a: int16x8_t, b: int16x8_t, c: i16) -> int16x8_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4714,6 +5452,8 @@ pub unsafe fn vmls_n_s32(a: int32x2_t, b: int32x2_t, c: i32) -> int32x2_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4725,6 +5465,8 @@ pub unsafe fn vmlsq_n_s32(a: int32x4_t, b: int32x4_t, c: i32) -> int32x4_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4736,6 +5478,8 @@ pub unsafe fn vmls_n_u16(a: uint16x4_t, b: uint16x4_t, c: u16) -> uint16x4_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4747,6 +5491,8 @@ pub unsafe fn vmlsq_n_u16(a: uint16x8_t, b: uint16x8_t, c: u16) -> uint16x8_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4758,6 +5504,8 @@ pub unsafe fn vmls_n_u32(a: uint32x2_t, b: uint32x2_t, c: u32) -> uint32x2_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4769,6 +5517,8 @@ pub unsafe fn vmlsq_n_u32(a: uint32x4_t, b: uint32x4_t, c: u32) -> uint32x4_t {
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4780,6 +5530,8 @@ pub unsafe fn vmls_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4791,6 +5543,8 @@ pub unsafe fn vmlsq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4804,6 +5558,8 @@ pub unsafe fn vmls_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c: int1
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4817,6 +5573,8 @@ pub unsafe fn vmls_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t, c: int
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4830,6 +5588,8 @@ pub unsafe fn vmlsq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c: int
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4843,6 +5603,8 @@ pub unsafe fn vmlsq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t, c: in
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4856,6 +5618,8 @@ pub unsafe fn vmls_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c: int3
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4869,6 +5633,8 @@ pub unsafe fn vmls_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t, c: int
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4882,6 +5648,8 @@ pub unsafe fn vmlsq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c: int
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4895,6 +5663,8 @@ pub unsafe fn vmlsq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t, c: in
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4908,6 +5678,8 @@ pub unsafe fn vmls_lane_u16<const LANE: i32>(a: uint16x4_t, b: uint16x4_t, c: ui
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4921,6 +5693,8 @@ pub unsafe fn vmls_laneq_u16<const LANE: i32>(a: uint16x4_t, b: uint16x4_t, c: u
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4934,6 +5708,8 @@ pub unsafe fn vmlsq_lane_u16<const LANE: i32>(a: uint16x8_t, b: uint16x8_t, c: u
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4947,6 +5723,8 @@ pub unsafe fn vmlsq_laneq_u16<const LANE: i32>(a: uint16x8_t, b: uint16x8_t, c:
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4960,6 +5738,8 @@ pub unsafe fn vmls_lane_u32<const LANE: i32>(a: uint32x2_t, b: uint32x2_t, c: ui
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4973,6 +5753,8 @@ pub unsafe fn vmls_laneq_u32<const LANE: i32>(a: uint32x2_t, b: uint32x2_t, c: u
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4986,6 +5768,8 @@ pub unsafe fn vmlsq_lane_u32<const LANE: i32>(a: uint32x4_t, b: uint32x4_t, c: u
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -4999,6 +5783,8 @@ pub unsafe fn vmlsq_laneq_u32<const LANE: i32>(a: uint32x4_t, b: uint32x4_t, c:
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5012,6 +5798,8 @@ pub unsafe fn vmls_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5025,6 +5813,8 @@ pub unsafe fn vmls_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t, c:
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5038,6 +5828,8 @@ pub unsafe fn vmlsq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c:
}
/// Vector multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5051,6 +5843,8 @@ pub unsafe fn vmlsq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t, c
}
/// Signed multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5062,6 +5856,8 @@ pub unsafe fn vmlsl_s8(a: int16x8_t, b: int8x8_t, c: int8x8_t) -> int16x8_t {
}
/// Signed multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5073,6 +5869,8 @@ pub unsafe fn vmlsl_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
}
/// Signed multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5084,6 +5882,8 @@ pub unsafe fn vmlsl_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
}
/// Unsigned multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5095,6 +5895,8 @@ pub unsafe fn vmlsl_u8(a: uint16x8_t, b: uint8x8_t, c: uint8x8_t) -> uint16x8_t
}
/// Unsigned multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5106,6 +5908,8 @@ pub unsafe fn vmlsl_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4_t) -> uint32x4
}
/// Unsigned multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5117,6 +5921,8 @@ pub unsafe fn vmlsl_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2_t) -> uint64x2
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5128,6 +5934,8 @@ pub unsafe fn vmlsl_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5139,6 +5947,8 @@ pub unsafe fn vmlsl_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5150,6 +5960,8 @@ pub unsafe fn vmlsl_n_u16(a: uint32x4_t, b: uint16x4_t, c: u16) -> uint32x4_t {
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5161,6 +5973,8 @@ pub unsafe fn vmlsl_n_u32(a: uint64x2_t, b: uint32x2_t, c: u32) -> uint64x2_t {
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5174,6 +5988,8 @@ pub unsafe fn vmlsl_lane_s16<const LANE: i32>(a: int32x4_t, b: int16x4_t, c: int
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5187,6 +6003,8 @@ pub unsafe fn vmlsl_laneq_s16<const LANE: i32>(a: int32x4_t, b: int16x4_t, c: in
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5200,6 +6018,8 @@ pub unsafe fn vmlsl_lane_s32<const LANE: i32>(a: int64x2_t, b: int32x2_t, c: int
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5213,6 +6033,8 @@ pub unsafe fn vmlsl_laneq_s32<const LANE: i32>(a: int64x2_t, b: int32x2_t, c: in
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5226,6 +6048,8 @@ pub unsafe fn vmlsl_lane_u16<const LANE: i32>(a: uint32x4_t, b: uint16x4_t, c: u
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5239,6 +6063,8 @@ pub unsafe fn vmlsl_laneq_u16<const LANE: i32>(a: uint32x4_t, b: uint16x4_t, c:
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5252,6 +6078,8 @@ pub unsafe fn vmlsl_lane_u32<const LANE: i32>(a: uint64x2_t, b: uint32x2_t, c: u
}
/// Vector widening multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5265,6 +6093,8 @@ pub unsafe fn vmlsl_laneq_u32<const LANE: i32>(a: uint64x2_t, b: uint32x2_t, c:
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5276,6 +6106,8 @@ pub unsafe fn vneg_s8(a: int8x8_t) -> int8x8_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5287,6 +6119,8 @@ pub unsafe fn vnegq_s8(a: int8x16_t) -> int8x16_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5298,6 +6132,8 @@ pub unsafe fn vneg_s16(a: int16x4_t) -> int16x4_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5309,6 +6145,8 @@ pub unsafe fn vnegq_s16(a: int16x8_t) -> int16x8_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5320,6 +6158,8 @@ pub unsafe fn vneg_s32(a: int32x2_t) -> int32x2_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5331,6 +6171,8 @@ pub unsafe fn vnegq_s32(a: int32x4_t) -> int32x4_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5342,6 +6184,8 @@ pub unsafe fn vneg_f32(a: float32x2_t) -> float32x2_t {
}
/// Negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5353,6 +6197,8 @@ pub unsafe fn vnegq_f32(a: float32x4_t) -> float32x4_t {
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5370,6 +6216,8 @@ vqneg_s8_(a)
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5387,6 +6235,8 @@ vqnegq_s8_(a)
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5404,6 +6254,8 @@ vqneg_s16_(a)
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5421,6 +6273,8 @@ vqnegq_s16_(a)
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5438,6 +6292,8 @@ vqneg_s32_(a)
}
/// Signed saturating negate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5455,6 +6311,8 @@ vqnegq_s32_(a)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5472,6 +6330,8 @@ vqsub_u8_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5489,6 +6349,8 @@ vqsubq_u8_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5506,6 +6368,8 @@ vqsub_u16_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5523,6 +6387,8 @@ vqsubq_u16_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5540,6 +6406,8 @@ vqsub_u32_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5557,6 +6425,8 @@ vqsubq_u32_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5574,6 +6444,8 @@ vqsub_u64_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5591,6 +6463,8 @@ vqsubq_u64_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5608,6 +6482,8 @@ vqsub_s8_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5625,6 +6501,8 @@ vqsubq_s8_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5642,6 +6520,8 @@ vqsub_s16_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5659,6 +6539,8 @@ vqsubq_s16_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5676,6 +6558,8 @@ vqsub_s32_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5693,6 +6577,8 @@ vqsubq_s32_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5710,6 +6596,8 @@ vqsub_s64_(a, b)
}
/// Saturating subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5727,6 +6615,8 @@ vqsubq_s64_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5744,6 +6634,8 @@ vhadd_u8_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5761,6 +6653,8 @@ vhaddq_u8_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5778,6 +6672,8 @@ vhadd_u16_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5795,6 +6691,8 @@ vhaddq_u16_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5812,6 +6710,8 @@ vhadd_u32_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5829,6 +6729,8 @@ vhaddq_u32_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5846,6 +6748,8 @@ vhadd_s8_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5863,6 +6767,8 @@ vhaddq_s8_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5880,6 +6786,8 @@ vhadd_s16_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5897,6 +6805,8 @@ vhaddq_s16_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5914,6 +6824,8 @@ vhadd_s32_(a, b)
}
/// Halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5931,6 +6843,8 @@ vhaddq_s32_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5948,6 +6862,8 @@ vrhadd_u8_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5965,6 +6881,8 @@ vrhaddq_u8_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5982,6 +6900,8 @@ vrhadd_u16_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -5999,6 +6919,8 @@ vrhaddq_u16_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6016,6 +6938,8 @@ vrhadd_u32_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6033,6 +6957,8 @@ vrhaddq_u32_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6050,6 +6976,8 @@ vrhadd_s8_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6067,6 +6995,8 @@ vrhaddq_s8_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6084,6 +7014,8 @@ vrhadd_s16_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6101,6 +7033,8 @@ vrhaddq_s16_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6118,6 +7052,8 @@ vrhadd_s32_(a, b)
}
/// Rounding halving add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6135,6 +7071,8 @@ vrhaddq_s32_(a, b)
}
/// Floating-point round to integral, to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
@@ -6152,6 +7090,8 @@ vrndn_f32_(a)
}
/// Floating-point round to integral, to nearest with ties to even
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndnq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
@@ -6169,6 +7109,8 @@ vrndnq_f32_(a)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6186,6 +7128,8 @@ vqadd_u8_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6203,6 +7147,8 @@ vqaddq_u8_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6220,6 +7166,8 @@ vqadd_u16_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6237,6 +7185,8 @@ vqaddq_u16_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6254,6 +7204,8 @@ vqadd_u32_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6271,6 +7223,8 @@ vqaddq_u32_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6288,6 +7242,8 @@ vqadd_u64_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6305,6 +7261,8 @@ vqaddq_u64_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6322,6 +7280,8 @@ vqadd_s8_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6339,6 +7299,8 @@ vqaddq_s8_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6356,6 +7318,8 @@ vqadd_s16_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6373,6 +7337,8 @@ vqaddq_s16_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6390,6 +7356,8 @@ vqadd_s32_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6407,6 +7375,8 @@ vqaddq_s32_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6424,6 +7394,8 @@ vqadd_s64_(a, b)
}
/// Saturating add
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6441,6 +7413,8 @@ vqaddq_s64_(a, b)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6458,6 +7432,8 @@ vld1_s8_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6475,6 +7451,8 @@ vld1_s16_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6492,6 +7470,8 @@ vld1_s32_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6509,6 +7489,8 @@ vld1_s64_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6526,6 +7508,8 @@ vld1q_s8_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6543,6 +7527,8 @@ vld1q_s16_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6560,6 +7546,8 @@ vld1q_s32_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6577,6 +7565,8 @@ vld1q_s64_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6594,6 +7584,8 @@ vld1_s8_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6611,6 +7603,8 @@ vld1_s16_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6628,6 +7622,8 @@ vld1_s32_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6645,6 +7641,8 @@ vld1_s64_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6662,6 +7660,8 @@ vld1q_s8_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6679,6 +7679,8 @@ vld1q_s16_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6696,6 +7698,8 @@ vld1q_s32_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6713,6 +7717,8 @@ vld1q_s64_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6730,6 +7736,8 @@ vld1_s8_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6747,6 +7755,8 @@ vld1_s16_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6764,6 +7774,8 @@ vld1_s32_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6781,6 +7793,8 @@ vld1_s64_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6798,6 +7812,8 @@ vld1q_s8_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6815,6 +7831,8 @@ vld1q_s16_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6832,6 +7850,8 @@ vld1q_s32_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6849,6 +7869,8 @@ vld1q_s64_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6860,6 +7882,8 @@ pub unsafe fn vld1_u8_x2(a: *const u8) -> uint8x8x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6871,6 +7895,8 @@ pub unsafe fn vld1_u16_x2(a: *const u16) -> uint16x4x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6882,6 +7908,8 @@ pub unsafe fn vld1_u32_x2(a: *const u32) -> uint32x2x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6893,6 +7921,8 @@ pub unsafe fn vld1_u64_x2(a: *const u64) -> uint64x1x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6904,6 +7934,8 @@ pub unsafe fn vld1q_u8_x2(a: *const u8) -> uint8x16x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6915,6 +7947,8 @@ pub unsafe fn vld1q_u16_x2(a: *const u16) -> uint16x8x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6926,6 +7960,8 @@ pub unsafe fn vld1q_u32_x2(a: *const u32) -> uint32x4x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6937,6 +7973,8 @@ pub unsafe fn vld1q_u64_x2(a: *const u64) -> uint64x2x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6948,6 +7986,8 @@ pub unsafe fn vld1_u8_x3(a: *const u8) -> uint8x8x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6959,6 +7999,8 @@ pub unsafe fn vld1_u16_x3(a: *const u16) -> uint16x4x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6970,6 +8012,8 @@ pub unsafe fn vld1_u32_x3(a: *const u32) -> uint32x2x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6981,6 +8025,8 @@ pub unsafe fn vld1_u64_x3(a: *const u64) -> uint64x1x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -6992,6 +8038,8 @@ pub unsafe fn vld1q_u8_x3(a: *const u8) -> uint8x16x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7003,6 +8051,8 @@ pub unsafe fn vld1q_u16_x3(a: *const u16) -> uint16x8x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7014,6 +8064,8 @@ pub unsafe fn vld1q_u32_x3(a: *const u32) -> uint32x4x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7025,6 +8077,8 @@ pub unsafe fn vld1q_u64_x3(a: *const u64) -> uint64x2x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7036,6 +8090,8 @@ pub unsafe fn vld1_u8_x4(a: *const u8) -> uint8x8x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7047,6 +8103,8 @@ pub unsafe fn vld1_u16_x4(a: *const u16) -> uint16x4x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7058,6 +8116,8 @@ pub unsafe fn vld1_u32_x4(a: *const u32) -> uint32x2x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7069,6 +8129,8 @@ pub unsafe fn vld1_u64_x4(a: *const u64) -> uint64x1x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7080,6 +8142,8 @@ pub unsafe fn vld1q_u8_x4(a: *const u8) -> uint8x16x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7091,6 +8155,8 @@ pub unsafe fn vld1q_u16_x4(a: *const u16) -> uint16x8x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7102,6 +8168,8 @@ pub unsafe fn vld1q_u32_x4(a: *const u32) -> uint32x4x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7113,6 +8181,8 @@ pub unsafe fn vld1q_u64_x4(a: *const u64) -> uint64x2x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7124,6 +8194,8 @@ pub unsafe fn vld1_p8_x2(a: *const p8) -> poly8x8x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7135,6 +8207,8 @@ pub unsafe fn vld1_p8_x3(a: *const p8) -> poly8x8x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7146,6 +8220,8 @@ pub unsafe fn vld1_p8_x4(a: *const p8) -> poly8x8x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7157,6 +8233,8 @@ pub unsafe fn vld1q_p8_x2(a: *const p8) -> poly8x16x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7168,6 +8246,8 @@ pub unsafe fn vld1q_p8_x3(a: *const p8) -> poly8x16x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7179,6 +8259,8 @@ pub unsafe fn vld1q_p8_x4(a: *const p8) -> poly8x16x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7190,6 +8272,8 @@ pub unsafe fn vld1_p16_x2(a: *const p16) -> poly16x4x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7201,6 +8285,8 @@ pub unsafe fn vld1_p16_x3(a: *const p16) -> poly16x4x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7212,6 +8298,8 @@ pub unsafe fn vld1_p16_x4(a: *const p16) -> poly16x4x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7223,6 +8311,8 @@ pub unsafe fn vld1q_p16_x2(a: *const p16) -> poly16x8x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7234,6 +8324,8 @@ pub unsafe fn vld1q_p16_x3(a: *const p16) -> poly16x8x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7245,6 +8337,8 @@ pub unsafe fn vld1q_p16_x4(a: *const p16) -> poly16x8x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64_x2)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7256,6 +8350,8 @@ pub unsafe fn vld1_p64_x2(a: *const p64) -> poly64x1x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64_x3)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7267,6 +8363,8 @@ pub unsafe fn vld1_p64_x3(a: *const p64) -> poly64x1x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64_x4)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7278,6 +8376,8 @@ pub unsafe fn vld1_p64_x4(a: *const p64) -> poly64x1x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x2)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7289,6 +8389,8 @@ pub unsafe fn vld1q_p64_x2(a: *const p64) -> poly64x2x2_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x3)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7300,6 +8402,8 @@ pub unsafe fn vld1q_p64_x3(a: *const p64) -> poly64x2x3_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x4)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7311,6 +8415,8 @@ pub unsafe fn vld1q_p64_x4(a: *const p64) -> poly64x2x4_t {
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7328,6 +8434,8 @@ vld1_f32_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7345,6 +8453,8 @@ vld1q_f32_x2_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7362,6 +8472,8 @@ vld1_f32_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7379,6 +8491,8 @@ vld1q_f32_x3_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7396,6 +8510,8 @@ vld1_f32_x4_(a)
}
/// Load multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7413,6 +8529,8 @@ vld1q_f32_x4_(a)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7427,6 +8545,8 @@ vld2_s8_(a as *const i8, 1)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7442,6 +8562,8 @@ vld2_s8_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7456,6 +8578,8 @@ vld2_s16_(a as *const i8, 2)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7471,6 +8595,8 @@ vld2_s16_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7485,6 +8611,8 @@ vld2_s32_(a as *const i8, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7500,6 +8628,8 @@ vld2_s32_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7514,6 +8644,8 @@ vld2q_s8_(a as *const i8, 1)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7529,6 +8661,8 @@ vld2q_s8_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7543,6 +8677,8 @@ vld2q_s16_(a as *const i8, 2)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7558,6 +8694,8 @@ vld2q_s16_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7572,6 +8710,8 @@ vld2q_s32_(a as *const i8, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7587,6 +8727,8 @@ vld2q_s32_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7601,6 +8743,8 @@ vld2_s64_(a as *const i8, 8)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7616,6 +8760,8 @@ vld2_s64_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7627,6 +8773,8 @@ pub unsafe fn vld2_u8(a: *const u8) -> uint8x8x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7638,6 +8786,8 @@ pub unsafe fn vld2_u16(a: *const u16) -> uint16x4x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7649,6 +8799,8 @@ pub unsafe fn vld2_u32(a: *const u32) -> uint32x2x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7660,6 +8812,8 @@ pub unsafe fn vld2q_u8(a: *const u8) -> uint8x16x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7671,6 +8825,8 @@ pub unsafe fn vld2q_u16(a: *const u16) -> uint16x8x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7682,6 +8838,8 @@ pub unsafe fn vld2q_u32(a: *const u32) -> uint32x4x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7693,6 +8851,8 @@ pub unsafe fn vld2_p8(a: *const p8) -> poly8x8x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7704,6 +8864,8 @@ pub unsafe fn vld2_p16(a: *const p16) -> poly16x4x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7715,6 +8877,8 @@ pub unsafe fn vld2q_p8(a: *const p8) -> poly8x16x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7726,6 +8890,8 @@ pub unsafe fn vld2q_p16(a: *const p16) -> poly16x8x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -7737,6 +8903,8 @@ pub unsafe fn vld2_u64(a: *const u64) -> uint64x1x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -7748,6 +8916,8 @@ pub unsafe fn vld2_p64(a: *const p64) -> poly64x1x2_t {
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7762,6 +8932,8 @@ vld2_f32_(a as *const i8, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7777,6 +8949,8 @@ vld2_f32_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7791,6 +8965,8 @@ vld2q_f32_(a as *const i8, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7806,6 +8982,8 @@ vld2q_f32_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7820,6 +8998,8 @@ vld2_dup_s8_(a as *const i8, 1)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7835,6 +9015,8 @@ vld2_dup_s8_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7849,6 +9031,8 @@ vld2_dup_s16_(a as *const i8, 2)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7864,6 +9048,8 @@ vld2_dup_s16_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7878,6 +9064,8 @@ vld2_dup_s32_(a as *const i8, 4)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7893,6 +9081,8 @@ vld2_dup_s32_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7907,6 +9097,8 @@ vld2q_dup_s8_(a as *const i8, 1)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7922,6 +9114,8 @@ vld2q_dup_s8_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7936,6 +9130,8 @@ vld2q_dup_s16_(a as *const i8, 2)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7951,6 +9147,8 @@ vld2q_dup_s16_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7965,6 +9163,8 @@ vld2q_dup_s32_(a as *const i8, 4)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -7980,6 +9180,8 @@ vld2q_dup_s32_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -7994,6 +9196,8 @@ vld2_dup_s64_(a as *const i8, 8)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8009,6 +9213,8 @@ vld2_dup_s64_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8020,6 +9226,8 @@ pub unsafe fn vld2_dup_u8(a: *const u8) -> uint8x8x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8031,6 +9239,8 @@ pub unsafe fn vld2_dup_u16(a: *const u16) -> uint16x4x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8042,6 +9252,8 @@ pub unsafe fn vld2_dup_u32(a: *const u32) -> uint32x2x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8053,6 +9265,8 @@ pub unsafe fn vld2q_dup_u8(a: *const u8) -> uint8x16x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8064,6 +9278,8 @@ pub unsafe fn vld2q_dup_u16(a: *const u16) -> uint16x8x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8075,6 +9291,8 @@ pub unsafe fn vld2q_dup_u32(a: *const u32) -> uint32x4x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8086,6 +9304,8 @@ pub unsafe fn vld2_dup_p8(a: *const p8) -> poly8x8x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8097,6 +9317,8 @@ pub unsafe fn vld2_dup_p16(a: *const p16) -> poly16x4x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8108,6 +9330,8 @@ pub unsafe fn vld2q_dup_p8(a: *const p8) -> poly8x16x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8119,6 +9343,8 @@ pub unsafe fn vld2q_dup_p16(a: *const p16) -> poly16x8x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8130,6 +9356,8 @@ pub unsafe fn vld2_dup_u64(a: *const u64) -> uint64x1x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -8141,6 +9369,8 @@ pub unsafe fn vld2_dup_p64(a: *const p64) -> poly64x1x2_t {
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8155,6 +9385,8 @@ vld2_dup_f32_(a as *const i8, 4)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8170,6 +9402,8 @@ vld2_dup_f32_(a as _)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8184,6 +9418,8 @@ vld2q_dup_f32_(a as *const i8, 4)
}
/// Load single 2-element structure and replicate to all lanes of two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8199,6 +9435,8 @@ vld2q_dup_f32_(a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8215,6 +9453,8 @@ vld2_lane_s8_(a as _, b.0, b.1, LANE, 1)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8232,6 +9472,8 @@ vld2_lane_s8_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8248,6 +9490,8 @@ vld2_lane_s16_(a as _, b.0, b.1, LANE, 2)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8265,6 +9509,8 @@ vld2_lane_s16_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8281,6 +9527,8 @@ vld2_lane_s32_(a as _, b.0, b.1, LANE, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8298,6 +9546,8 @@ vld2_lane_s32_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8314,6 +9564,8 @@ vld2q_lane_s16_(a as _, b.0, b.1, LANE, 2)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8331,6 +9583,8 @@ vld2q_lane_s16_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8347,6 +9601,8 @@ vld2q_lane_s32_(a as _, b.0, b.1, LANE, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8364,6 +9620,8 @@ vld2q_lane_s32_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8377,6 +9635,8 @@ pub unsafe fn vld2_lane_u8<const LANE: i32>(a: *const u8, b: uint8x8x2_t) -> uin
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8390,6 +9650,8 @@ pub unsafe fn vld2_lane_u16<const LANE: i32>(a: *const u16, b: uint16x4x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8403,6 +9665,8 @@ pub unsafe fn vld2_lane_u32<const LANE: i32>(a: *const u32, b: uint32x2x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8416,6 +9680,8 @@ pub unsafe fn vld2q_lane_u16<const LANE: i32>(a: *const u16, b: uint16x8x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8429,6 +9695,8 @@ pub unsafe fn vld2q_lane_u32<const LANE: i32>(a: *const u32, b: uint32x4x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8442,6 +9710,8 @@ pub unsafe fn vld2_lane_p8<const LANE: i32>(a: *const p8, b: poly8x8x2_t) -> pol
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8455,6 +9725,8 @@ pub unsafe fn vld2_lane_p16<const LANE: i32>(a: *const p16, b: poly16x4x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8468,6 +9740,8 @@ pub unsafe fn vld2q_lane_p16<const LANE: i32>(a: *const p16, b: poly16x8x2_t) ->
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8484,6 +9758,8 @@ vld2_lane_f32_(a as _, b.0, b.1, LANE, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8501,6 +9777,8 @@ vld2_lane_f32_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8517,6 +9795,8 @@ vld2q_lane_f32_(a as _, b.0, b.1, LANE, 4)
}
/// Load multiple 2-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8534,6 +9814,8 @@ vld2q_lane_f32_(b.0, b.1, LANE as i64, a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8548,6 +9830,8 @@ vld3_s8_(a as *const i8, 1)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8563,6 +9847,8 @@ vld3_s8_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8577,6 +9863,8 @@ vld3_s16_(a as *const i8, 2)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8592,6 +9880,8 @@ vld3_s16_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8606,6 +9896,8 @@ vld3_s32_(a as *const i8, 4)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8621,6 +9913,8 @@ vld3_s32_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8635,6 +9929,8 @@ vld3q_s8_(a as *const i8, 1)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8650,6 +9946,8 @@ vld3q_s8_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8664,6 +9962,8 @@ vld3q_s16_(a as *const i8, 2)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8679,6 +9979,8 @@ vld3q_s16_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8693,6 +9995,8 @@ vld3q_s32_(a as *const i8, 4)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8708,6 +10012,8 @@ vld3q_s32_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8722,6 +10028,8 @@ vld3_s64_(a as *const i8, 8)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8737,6 +10045,8 @@ vld3_s64_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8748,6 +10058,8 @@ pub unsafe fn vld3_u8(a: *const u8) -> uint8x8x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8759,6 +10071,8 @@ pub unsafe fn vld3_u16(a: *const u16) -> uint16x4x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8770,6 +10084,8 @@ pub unsafe fn vld3_u32(a: *const u32) -> uint32x2x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8781,6 +10097,8 @@ pub unsafe fn vld3q_u8(a: *const u8) -> uint8x16x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8792,6 +10110,8 @@ pub unsafe fn vld3q_u16(a: *const u16) -> uint16x8x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8803,6 +10123,8 @@ pub unsafe fn vld3q_u32(a: *const u32) -> uint32x4x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8814,6 +10136,8 @@ pub unsafe fn vld3_p8(a: *const p8) -> poly8x8x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8825,6 +10149,8 @@ pub unsafe fn vld3_p16(a: *const p16) -> poly16x4x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8836,6 +10162,8 @@ pub unsafe fn vld3q_p8(a: *const p8) -> poly8x16x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8847,6 +10175,8 @@ pub unsafe fn vld3q_p16(a: *const p16) -> poly16x8x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -8858,6 +10188,8 @@ pub unsafe fn vld3_u64(a: *const u64) -> uint64x1x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -8869,6 +10201,8 @@ pub unsafe fn vld3_p64(a: *const p64) -> poly64x1x3_t {
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8883,6 +10217,8 @@ vld3_f32_(a as *const i8, 4)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8898,6 +10234,8 @@ vld3_f32_(a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8912,6 +10250,8 @@ vld3q_f32_(a as *const i8, 4)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8927,6 +10267,8 @@ vld3q_f32_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8941,6 +10283,8 @@ vld3_dup_s8_(a as *const i8, 1)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8956,6 +10300,8 @@ vld3_dup_s8_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8970,6 +10316,8 @@ vld3_dup_s16_(a as *const i8, 2)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -8985,6 +10333,8 @@ vld3_dup_s16_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -8999,6 +10349,8 @@ vld3_dup_s32_(a as *const i8, 4)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9014,6 +10366,8 @@ vld3_dup_s32_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9028,6 +10382,8 @@ vld3q_dup_s8_(a as *const i8, 1)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9043,6 +10399,8 @@ vld3q_dup_s8_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9057,6 +10415,8 @@ vld3q_dup_s16_(a as *const i8, 2)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9072,6 +10432,8 @@ vld3q_dup_s16_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9086,6 +10448,8 @@ vld3q_dup_s32_(a as *const i8, 4)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9101,6 +10465,8 @@ vld3q_dup_s32_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9115,6 +10481,8 @@ vld3_dup_s64_(a as *const i8, 8)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9130,6 +10498,8 @@ vld3_dup_s64_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9141,6 +10511,8 @@ pub unsafe fn vld3_dup_u8(a: *const u8) -> uint8x8x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9152,6 +10524,8 @@ pub unsafe fn vld3_dup_u16(a: *const u16) -> uint16x4x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9163,6 +10537,8 @@ pub unsafe fn vld3_dup_u32(a: *const u32) -> uint32x2x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9174,6 +10550,8 @@ pub unsafe fn vld3q_dup_u8(a: *const u8) -> uint8x16x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9185,6 +10563,8 @@ pub unsafe fn vld3q_dup_u16(a: *const u16) -> uint16x8x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9196,6 +10576,8 @@ pub unsafe fn vld3q_dup_u32(a: *const u32) -> uint32x4x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9207,6 +10589,8 @@ pub unsafe fn vld3_dup_p8(a: *const p8) -> poly8x8x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9218,6 +10602,8 @@ pub unsafe fn vld3_dup_p16(a: *const p16) -> poly16x4x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9229,6 +10615,8 @@ pub unsafe fn vld3q_dup_p8(a: *const p8) -> poly8x16x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9240,6 +10628,8 @@ pub unsafe fn vld3q_dup_p16(a: *const p16) -> poly16x8x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9251,6 +10641,8 @@ pub unsafe fn vld3_dup_u64(a: *const u64) -> uint64x1x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -9262,6 +10654,8 @@ pub unsafe fn vld3_dup_p64(a: *const p64) -> poly64x1x3_t {
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9276,6 +10670,8 @@ vld3_dup_f32_(a as *const i8, 4)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9291,6 +10687,8 @@ vld3_dup_f32_(a as _)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9305,6 +10703,8 @@ vld3q_dup_f32_(a as *const i8, 4)
}
/// Load single 3-element structure and replicate to all lanes of three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9320,6 +10720,8 @@ vld3q_dup_f32_(a as _)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9336,6 +10738,8 @@ vld3_lane_s8_(a as _, b.0, b.1, b.2, LANE, 1)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9353,6 +10757,8 @@ vld3_lane_s8_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9369,6 +10775,8 @@ vld3_lane_s16_(a as _, b.0, b.1, b.2, LANE, 2)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9386,6 +10794,8 @@ vld3_lane_s16_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9402,6 +10812,8 @@ vld3_lane_s32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9419,6 +10831,8 @@ vld3_lane_s32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9435,6 +10849,8 @@ vld3q_lane_s16_(a as _, b.0, b.1, b.2, LANE, 2)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9452,6 +10868,8 @@ vld3q_lane_s16_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9468,6 +10886,8 @@ vld3q_lane_s32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Load multiple 3-element structures to two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9485,6 +10905,8 @@ vld3q_lane_s32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9498,6 +10920,8 @@ pub unsafe fn vld3_lane_u8<const LANE: i32>(a: *const u8, b: uint8x8x3_t) -> uin
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9511,6 +10935,8 @@ pub unsafe fn vld3_lane_u16<const LANE: i32>(a: *const u16, b: uint16x4x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9524,6 +10950,8 @@ pub unsafe fn vld3_lane_u32<const LANE: i32>(a: *const u32, b: uint32x2x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9537,6 +10965,8 @@ pub unsafe fn vld3q_lane_u16<const LANE: i32>(a: *const u16, b: uint16x8x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9550,6 +10980,8 @@ pub unsafe fn vld3q_lane_u32<const LANE: i32>(a: *const u32, b: uint32x4x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9563,6 +10995,8 @@ pub unsafe fn vld3_lane_p8<const LANE: i32>(a: *const p8, b: poly8x8x3_t) -> pol
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9576,6 +11010,8 @@ pub unsafe fn vld3_lane_p16<const LANE: i32>(a: *const p16, b: poly16x4x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9589,6 +11025,8 @@ pub unsafe fn vld3q_lane_p16<const LANE: i32>(a: *const p16, b: poly16x8x3_t) ->
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9605,6 +11043,8 @@ vld3_lane_f32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9622,6 +11062,8 @@ vld3_lane_f32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9638,6 +11080,8 @@ vld3q_lane_f32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Load multiple 3-element structures to three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9655,6 +11099,8 @@ vld3q_lane_f32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9669,6 +11115,8 @@ vld4_s8_(a as *const i8, 1)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9684,6 +11132,8 @@ vld4_s8_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9698,6 +11148,8 @@ vld4_s16_(a as *const i8, 2)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9713,6 +11165,8 @@ vld4_s16_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9727,6 +11181,8 @@ vld4_s32_(a as *const i8, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9742,6 +11198,8 @@ vld4_s32_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9756,6 +11214,8 @@ vld4q_s8_(a as *const i8, 1)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9771,6 +11231,8 @@ vld4q_s8_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9785,6 +11247,8 @@ vld4q_s16_(a as *const i8, 2)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9800,6 +11264,8 @@ vld4q_s16_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9814,6 +11280,8 @@ vld4q_s32_(a as *const i8, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9829,6 +11297,8 @@ vld4q_s32_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -9843,6 +11313,8 @@ vld4_s64_(a as *const i8, 8)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -9858,6 +11330,8 @@ vld4_s64_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9869,6 +11343,8 @@ pub unsafe fn vld4_u8(a: *const u8) -> uint8x8x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9880,6 +11356,8 @@ pub unsafe fn vld4_u16(a: *const u16) -> uint16x4x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9891,6 +11369,8 @@ pub unsafe fn vld4_u32(a: *const u32) -> uint32x2x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9902,6 +11382,8 @@ pub unsafe fn vld4q_u8(a: *const u8) -> uint8x16x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9913,6 +11395,8 @@ pub unsafe fn vld4q_u16(a: *const u16) -> uint16x8x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9924,6 +11408,8 @@ pub unsafe fn vld4q_u32(a: *const u32) -> uint32x4x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9935,6 +11421,8 @@ pub unsafe fn vld4_p8(a: *const p8) -> poly8x8x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9946,6 +11434,8 @@ pub unsafe fn vld4_p16(a: *const p16) -> poly16x4x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9957,6 +11447,8 @@ pub unsafe fn vld4q_p8(a: *const p8) -> poly8x16x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9968,6 +11460,8 @@ pub unsafe fn vld4q_p16(a: *const p16) -> poly16x8x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -9979,6 +11473,8 @@ pub unsafe fn vld4_u64(a: *const u64) -> uint64x1x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -9990,6 +11486,8 @@ pub unsafe fn vld4_p64(a: *const p64) -> poly64x1x4_t {
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10004,6 +11502,8 @@ vld4_f32_(a as *const i8, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10019,6 +11519,8 @@ vld4_f32_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10033,6 +11535,8 @@ vld4q_f32_(a as *const i8, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10048,6 +11552,8 @@ vld4q_f32_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10062,6 +11568,8 @@ vld4_dup_s8_(a as *const i8, 1)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10077,6 +11585,8 @@ vld4_dup_s8_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10091,6 +11601,8 @@ vld4_dup_s16_(a as *const i8, 2)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10106,6 +11618,8 @@ vld4_dup_s16_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10120,6 +11634,8 @@ vld4_dup_s32_(a as *const i8, 4)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10135,6 +11651,8 @@ vld4_dup_s32_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10149,6 +11667,8 @@ vld4q_dup_s8_(a as *const i8, 1)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10164,6 +11684,8 @@ vld4q_dup_s8_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10178,6 +11700,8 @@ vld4q_dup_s16_(a as *const i8, 2)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10193,6 +11717,8 @@ vld4q_dup_s16_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10207,6 +11733,8 @@ vld4q_dup_s32_(a as *const i8, 4)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10222,6 +11750,8 @@ vld4q_dup_s32_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10236,6 +11766,8 @@ vld4_dup_s64_(a as *const i8, 8)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10251,6 +11783,8 @@ vld4_dup_s64_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10262,6 +11796,8 @@ pub unsafe fn vld4_dup_u8(a: *const u8) -> uint8x8x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10273,6 +11809,8 @@ pub unsafe fn vld4_dup_u16(a: *const u16) -> uint16x4x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10284,6 +11822,8 @@ pub unsafe fn vld4_dup_u32(a: *const u32) -> uint32x2x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10295,6 +11835,8 @@ pub unsafe fn vld4q_dup_u8(a: *const u8) -> uint8x16x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10306,6 +11848,8 @@ pub unsafe fn vld4q_dup_u16(a: *const u16) -> uint16x8x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10317,6 +11861,8 @@ pub unsafe fn vld4q_dup_u32(a: *const u32) -> uint32x4x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10328,6 +11874,8 @@ pub unsafe fn vld4_dup_p8(a: *const p8) -> poly8x8x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10339,6 +11887,8 @@ pub unsafe fn vld4_dup_p16(a: *const p16) -> poly16x4x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10350,6 +11900,8 @@ pub unsafe fn vld4q_dup_p8(a: *const p8) -> poly8x16x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10361,6 +11913,8 @@ pub unsafe fn vld4q_dup_p16(a: *const p16) -> poly16x8x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10372,6 +11926,8 @@ pub unsafe fn vld4_dup_u64(a: *const u64) -> uint64x1x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -10383,6 +11939,8 @@ pub unsafe fn vld4_dup_p64(a: *const p64) -> poly64x1x4_t {
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10397,6 +11955,8 @@ vld4_dup_f32_(a as *const i8, 4)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10412,6 +11972,8 @@ vld4_dup_f32_(a as _)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10426,6 +11988,8 @@ vld4q_dup_f32_(a as *const i8, 4)
}
/// Load single 4-element structure and replicate to all lanes of four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10441,6 +12005,8 @@ vld4q_dup_f32_(a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10457,6 +12023,8 @@ vld4_lane_s8_(a as _, b.0, b.1, b.2, b.3, LANE, 1)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10474,6 +12042,8 @@ vld4_lane_s8_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10490,6 +12060,8 @@ vld4_lane_s16_(a as _, b.0, b.1, b.2, b.3, LANE, 2)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10507,6 +12079,8 @@ vld4_lane_s16_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10523,6 +12097,8 @@ vld4_lane_s32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10540,6 +12116,8 @@ vld4_lane_s32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10556,6 +12134,8 @@ vld4q_lane_s16_(a as _, b.0, b.1, b.2, b.3, LANE, 2)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10573,6 +12153,8 @@ vld4q_lane_s16_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10589,6 +12171,8 @@ vld4q_lane_s32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10606,6 +12190,8 @@ vld4q_lane_s32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10619,6 +12205,8 @@ pub unsafe fn vld4_lane_u8<const LANE: i32>(a: *const u8, b: uint8x8x4_t) -> uin
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10632,6 +12220,8 @@ pub unsafe fn vld4_lane_u16<const LANE: i32>(a: *const u16, b: uint16x4x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10645,6 +12235,8 @@ pub unsafe fn vld4_lane_u32<const LANE: i32>(a: *const u32, b: uint32x2x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10658,6 +12250,8 @@ pub unsafe fn vld4q_lane_u16<const LANE: i32>(a: *const u16, b: uint16x8x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10671,6 +12265,8 @@ pub unsafe fn vld4q_lane_u32<const LANE: i32>(a: *const u32, b: uint32x4x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10684,6 +12280,8 @@ pub unsafe fn vld4_lane_p8<const LANE: i32>(a: *const p8, b: poly8x8x4_t) -> pol
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10697,6 +12295,8 @@ pub unsafe fn vld4_lane_p16<const LANE: i32>(a: *const p16, b: poly16x4x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10710,6 +12310,8 @@ pub unsafe fn vld4q_lane_p16<const LANE: i32>(a: *const p16, b: poly16x8x4_t) ->
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10726,6 +12328,8 @@ vld4_lane_f32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10743,6 +12347,8 @@ vld4_lane_f32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -10759,6 +12365,8 @@ vld4q_lane_f32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Load multiple 4-element structures to four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -10776,6 +12384,8 @@ vld4q_lane_f32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10789,6 +12399,8 @@ pub unsafe fn vst1_lane_s8<const LANE: i32>(a: *mut i8, b: int8x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10802,6 +12414,8 @@ pub unsafe fn vst1_lane_s16<const LANE: i32>(a: *mut i16, b: int16x4_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10815,6 +12429,8 @@ pub unsafe fn vst1_lane_s32<const LANE: i32>(a: *mut i32, b: int32x2_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10828,6 +12444,8 @@ pub unsafe fn vst1_lane_s64<const LANE: i32>(a: *mut i64, b: int64x1_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10841,6 +12459,8 @@ pub unsafe fn vst1q_lane_s8<const LANE: i32>(a: *mut i8, b: int8x16_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10854,6 +12474,8 @@ pub unsafe fn vst1q_lane_s16<const LANE: i32>(a: *mut i16, b: int16x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10867,6 +12489,8 @@ pub unsafe fn vst1q_lane_s32<const LANE: i32>(a: *mut i32, b: int32x4_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10880,6 +12504,8 @@ pub unsafe fn vst1q_lane_s64<const LANE: i32>(a: *mut i64, b: int64x2_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10893,6 +12519,8 @@ pub unsafe fn vst1_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10906,6 +12534,8 @@ pub unsafe fn vst1_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x4_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10919,6 +12549,8 @@ pub unsafe fn vst1_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x2_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10932,6 +12564,8 @@ pub unsafe fn vst1_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x1_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10945,6 +12579,8 @@ pub unsafe fn vst1q_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x16_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10958,6 +12594,8 @@ pub unsafe fn vst1q_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10971,6 +12609,8 @@ pub unsafe fn vst1q_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x4_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10984,6 +12624,8 @@ pub unsafe fn vst1q_lane_u64<const LANE: i32>(a: *mut u64, b: uint64x2_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -10997,6 +12639,8 @@ pub unsafe fn vst1_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11010,6 +12654,8 @@ pub unsafe fn vst1_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x4_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11023,6 +12669,8 @@ pub unsafe fn vst1q_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x16_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11036,6 +12684,8 @@ pub unsafe fn vst1q_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x8_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -11049,6 +12699,8 @@ pub unsafe fn vst1_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x1_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -11062,6 +12714,8 @@ pub unsafe fn vst1q_lane_p64<const LANE: i32>(a: *mut p64, b: poly64x2_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11075,6 +12729,8 @@ pub unsafe fn vst1_lane_f32<const LANE: i32>(a: *mut f32, b: float32x2_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11088,6 +12744,8 @@ pub unsafe fn vst1q_lane_f32<const LANE: i32>(a: *mut f32, b: float32x4_t) {
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11102,6 +12760,8 @@ vst1_s8_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11117,6 +12777,8 @@ vst1_s8_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11131,6 +12793,8 @@ vst1_s16_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11146,6 +12810,8 @@ vst1_s16_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11160,6 +12826,8 @@ vst1_s32_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11175,6 +12843,8 @@ vst1_s32_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11189,6 +12859,8 @@ vst1_s64_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11204,6 +12876,8 @@ vst1_s64_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11218,6 +12892,8 @@ vst1q_s8_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11233,6 +12909,8 @@ vst1q_s8_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11247,6 +12925,8 @@ vst1q_s16_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11262,6 +12942,8 @@ vst1q_s16_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11276,6 +12958,8 @@ vst1q_s32_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11291,6 +12975,8 @@ vst1q_s32_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11305,6 +12991,8 @@ vst1q_s64_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11320,6 +13008,8 @@ vst1q_s64_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11334,6 +13024,8 @@ vst1_s8_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11349,6 +13041,8 @@ vst1_s8_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11363,6 +13057,8 @@ vst1_s16_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11378,6 +13074,8 @@ vst1_s16_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11392,6 +13090,8 @@ vst1_s32_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11407,6 +13107,8 @@ vst1_s32_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11421,6 +13123,8 @@ vst1_s64_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11436,6 +13140,8 @@ vst1_s64_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11450,6 +13156,8 @@ vst1q_s8_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11465,6 +13173,8 @@ vst1q_s8_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11479,6 +13189,8 @@ vst1q_s16_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11494,6 +13206,8 @@ vst1q_s16_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11508,6 +13222,8 @@ vst1q_s32_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11523,6 +13239,8 @@ vst1q_s32_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11537,6 +13255,8 @@ vst1q_s64_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11552,6 +13272,8 @@ vst1q_s64_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11566,6 +13288,8 @@ vst1_s8_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11581,6 +13305,8 @@ vst1_s8_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11595,6 +13321,8 @@ vst1_s16_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11610,6 +13338,8 @@ vst1_s16_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11624,6 +13354,8 @@ vst1_s32_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11639,6 +13371,8 @@ vst1_s32_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11653,6 +13387,8 @@ vst1_s64_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11668,6 +13404,8 @@ vst1_s64_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11682,6 +13420,8 @@ vst1q_s8_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11697,6 +13437,8 @@ vst1q_s8_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11711,6 +13453,8 @@ vst1q_s16_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11726,6 +13470,8 @@ vst1q_s16_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11740,6 +13486,8 @@ vst1q_s32_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11755,6 +13503,8 @@ vst1q_s32_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -11769,6 +13519,8 @@ vst1q_s64_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures from one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -11784,6 +13536,8 @@ vst1q_s64_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11795,6 +13549,8 @@ pub unsafe fn vst1_u8_x2(a: *mut u8, b: uint8x8x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11806,6 +13562,8 @@ pub unsafe fn vst1_u16_x2(a: *mut u16, b: uint16x4x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11817,6 +13575,8 @@ pub unsafe fn vst1_u32_x2(a: *mut u32, b: uint32x2x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11828,6 +13588,8 @@ pub unsafe fn vst1_u64_x2(a: *mut u64, b: uint64x1x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11839,6 +13601,8 @@ pub unsafe fn vst1q_u8_x2(a: *mut u8, b: uint8x16x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11850,6 +13614,8 @@ pub unsafe fn vst1q_u16_x2(a: *mut u16, b: uint16x8x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11861,6 +13627,8 @@ pub unsafe fn vst1q_u32_x2(a: *mut u32, b: uint32x4x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11872,6 +13640,8 @@ pub unsafe fn vst1q_u64_x2(a: *mut u64, b: uint64x2x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11883,6 +13653,8 @@ pub unsafe fn vst1_u8_x3(a: *mut u8, b: uint8x8x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11894,6 +13666,8 @@ pub unsafe fn vst1_u16_x3(a: *mut u16, b: uint16x4x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11905,6 +13679,8 @@ pub unsafe fn vst1_u32_x3(a: *mut u32, b: uint32x2x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11916,6 +13692,8 @@ pub unsafe fn vst1_u64_x3(a: *mut u64, b: uint64x1x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11927,6 +13705,8 @@ pub unsafe fn vst1q_u8_x3(a: *mut u8, b: uint8x16x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11938,6 +13718,8 @@ pub unsafe fn vst1q_u16_x3(a: *mut u16, b: uint16x8x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11949,6 +13731,8 @@ pub unsafe fn vst1q_u32_x3(a: *mut u32, b: uint32x4x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11960,6 +13744,8 @@ pub unsafe fn vst1q_u64_x3(a: *mut u64, b: uint64x2x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11971,6 +13757,8 @@ pub unsafe fn vst1_u8_x4(a: *mut u8, b: uint8x8x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11982,6 +13770,8 @@ pub unsafe fn vst1_u16_x4(a: *mut u16, b: uint16x4x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -11993,6 +13783,8 @@ pub unsafe fn vst1_u32_x4(a: *mut u32, b: uint32x2x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12004,6 +13796,8 @@ pub unsafe fn vst1_u64_x4(a: *mut u64, b: uint64x1x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12015,6 +13809,8 @@ pub unsafe fn vst1q_u8_x4(a: *mut u8, b: uint8x16x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12026,6 +13822,8 @@ pub unsafe fn vst1q_u16_x4(a: *mut u16, b: uint16x8x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12037,6 +13835,8 @@ pub unsafe fn vst1q_u32_x4(a: *mut u32, b: uint32x4x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12048,6 +13848,8 @@ pub unsafe fn vst1q_u64_x4(a: *mut u64, b: uint64x2x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12059,6 +13861,8 @@ pub unsafe fn vst1_p8_x2(a: *mut p8, b: poly8x8x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12070,6 +13874,8 @@ pub unsafe fn vst1_p8_x3(a: *mut p8, b: poly8x8x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12081,6 +13887,8 @@ pub unsafe fn vst1_p8_x4(a: *mut p8, b: poly8x8x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12092,6 +13900,8 @@ pub unsafe fn vst1q_p8_x2(a: *mut p8, b: poly8x16x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12103,6 +13913,8 @@ pub unsafe fn vst1q_p8_x3(a: *mut p8, b: poly8x16x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12114,6 +13926,8 @@ pub unsafe fn vst1q_p8_x4(a: *mut p8, b: poly8x16x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12125,6 +13939,8 @@ pub unsafe fn vst1_p16_x2(a: *mut p16, b: poly16x4x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12136,6 +13952,8 @@ pub unsafe fn vst1_p16_x3(a: *mut p16, b: poly16x4x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12147,6 +13965,8 @@ pub unsafe fn vst1_p16_x4(a: *mut p16, b: poly16x4x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16_x2)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12158,6 +13978,8 @@ pub unsafe fn vst1q_p16_x2(a: *mut p16, b: poly16x8x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16_x3)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12169,6 +13991,8 @@ pub unsafe fn vst1q_p16_x3(a: *mut p16, b: poly16x8x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16_x4)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12180,6 +14004,8 @@ pub unsafe fn vst1q_p16_x4(a: *mut p16, b: poly16x8x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64_x2)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12191,6 +14017,8 @@ pub unsafe fn vst1_p64_x2(a: *mut p64, b: poly64x1x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64_x3)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12202,6 +14030,8 @@ pub unsafe fn vst1_p64_x3(a: *mut p64, b: poly64x1x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64_x4)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12213,6 +14043,8 @@ pub unsafe fn vst1_p64_x4(a: *mut p64, b: poly64x1x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64_x2)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12224,6 +14056,8 @@ pub unsafe fn vst1q_p64_x2(a: *mut p64, b: poly64x2x2_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64_x3)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12235,6 +14069,8 @@ pub unsafe fn vst1q_p64_x3(a: *mut p64, b: poly64x2x3_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64_x4)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12246,6 +14082,8 @@ pub unsafe fn vst1q_p64_x4(a: *mut p64, b: poly64x2x4_t) {
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12260,6 +14098,8 @@ vst1_f32_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12275,6 +14115,8 @@ vst1_f32_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x2)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12289,6 +14131,8 @@ vst1q_f32_x2_(a, b.0, b.1)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x2)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12304,6 +14148,8 @@ vst1q_f32_x2_(b.0, b.1, a)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12318,6 +14164,8 @@ vst1_f32_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12333,6 +14181,8 @@ vst1_f32_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x3)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12347,6 +14197,8 @@ vst1q_f32_x3_(a, b.0, b.1, b.2)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x3)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12362,6 +14214,8 @@ vst1q_f32_x3_(b.0, b.1, b.2, a)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12376,6 +14230,8 @@ vst1_f32_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12391,6 +14247,8 @@ vst1_f32_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x4)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12405,6 +14263,8 @@ vst1q_f32_x4_(a, b.0, b.1, b.2, b.3)
}
/// Store multiple single-element structures to one, two, three, or four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x4)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12420,6 +14280,8 @@ vst1q_f32_x4_(b.0, b.1, b.2, b.3, a)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12434,6 +14296,8 @@ vst2_s8_(a as _, b.0, b.1, 1)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12449,6 +14313,8 @@ vst2_s8_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12463,6 +14329,8 @@ vst2_s16_(a as _, b.0, b.1, 2)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12478,6 +14346,8 @@ vst2_s16_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12492,6 +14362,8 @@ vst2_s32_(a as _, b.0, b.1, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12507,6 +14379,8 @@ vst2_s32_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12521,6 +14395,8 @@ vst2q_s8_(a as _, b.0, b.1, 1)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12536,6 +14412,8 @@ vst2q_s8_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12550,6 +14428,8 @@ vst2q_s16_(a as _, b.0, b.1, 2)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12565,6 +14445,8 @@ vst2q_s16_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12579,6 +14461,8 @@ vst2q_s32_(a as _, b.0, b.1, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12594,6 +14478,8 @@ vst2q_s32_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12608,6 +14494,8 @@ vst2_s64_(a as _, b.0, b.1, 8)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12623,6 +14511,8 @@ vst2_s64_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12634,6 +14524,8 @@ pub unsafe fn vst2_u8(a: *mut u8, b: uint8x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12645,6 +14537,8 @@ pub unsafe fn vst2_u16(a: *mut u16, b: uint16x4x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12656,6 +14550,8 @@ pub unsafe fn vst2_u32(a: *mut u32, b: uint32x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12667,6 +14563,8 @@ pub unsafe fn vst2q_u8(a: *mut u8, b: uint8x16x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12678,6 +14576,8 @@ pub unsafe fn vst2q_u16(a: *mut u16, b: uint16x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12689,6 +14589,8 @@ pub unsafe fn vst2q_u32(a: *mut u32, b: uint32x4x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12700,6 +14602,8 @@ pub unsafe fn vst2_p8(a: *mut p8, b: poly8x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12711,6 +14615,8 @@ pub unsafe fn vst2_p16(a: *mut p16, b: poly16x4x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12722,6 +14628,8 @@ pub unsafe fn vst2q_p8(a: *mut p8, b: poly8x16x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12733,6 +14641,8 @@ pub unsafe fn vst2q_p16(a: *mut p16, b: poly16x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12744,6 +14654,8 @@ pub unsafe fn vst2_u64(a: *mut u64, b: uint64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -12755,6 +14667,8 @@ pub unsafe fn vst2_p64(a: *mut p64, b: poly64x1x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12769,6 +14683,8 @@ vst2_f32_(a as _, b.0, b.1, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12784,6 +14700,8 @@ vst2_f32_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12798,6 +14716,8 @@ vst2q_f32_(a as _, b.0, b.1, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12813,6 +14733,8 @@ vst2q_f32_(b.0, b.1, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12829,6 +14751,8 @@ vst2_lane_s8_(a as _, b.0, b.1, LANE, 1)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12846,6 +14770,8 @@ vst2_lane_s8_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12862,6 +14788,8 @@ vst2_lane_s16_(a as _, b.0, b.1, LANE, 2)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12879,6 +14807,8 @@ vst2_lane_s16_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12895,6 +14825,8 @@ vst2_lane_s32_(a as _, b.0, b.1, LANE, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12912,6 +14844,8 @@ vst2_lane_s32_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12928,6 +14862,8 @@ vst2q_lane_s16_(a as _, b.0, b.1, LANE, 2)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12945,6 +14881,8 @@ vst2q_lane_s16_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -12961,6 +14899,8 @@ vst2q_lane_s32_(a as _, b.0, b.1, LANE, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -12978,6 +14918,8 @@ vst2q_lane_s32_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -12991,6 +14933,8 @@ pub unsafe fn vst2_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13004,6 +14948,8 @@ pub unsafe fn vst2_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x4x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13017,6 +14963,8 @@ pub unsafe fn vst2_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x2x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13030,6 +14978,8 @@ pub unsafe fn vst2q_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13043,6 +14993,8 @@ pub unsafe fn vst2q_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x4x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13056,6 +15008,8 @@ pub unsafe fn vst2_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13069,6 +15023,8 @@ pub unsafe fn vst2_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x4x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13082,6 +15038,8 @@ pub unsafe fn vst2q_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x8x2_t) {
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13098,6 +15056,8 @@ vst2_lane_f32_(a as _, b.0, b.1, LANE, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13115,6 +15075,8 @@ vst2_lane_f32_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13131,6 +15093,8 @@ vst2q_lane_f32_(a as _, b.0, b.1, LANE, 4)
}
/// Store multiple 2-element structures from two registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13148,6 +15112,8 @@ vst2q_lane_f32_(b.0, b.1, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13162,6 +15128,8 @@ vst3_s8_(a as _, b.0, b.1, b.2, 1)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13177,6 +15145,8 @@ vst3_s8_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13191,6 +15161,8 @@ vst3_s16_(a as _, b.0, b.1, b.2, 2)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13206,6 +15178,8 @@ vst3_s16_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13220,6 +15194,8 @@ vst3_s32_(a as _, b.0, b.1, b.2, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13235,6 +15211,8 @@ vst3_s32_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13249,6 +15227,8 @@ vst3q_s8_(a as _, b.0, b.1, b.2, 1)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13264,6 +15244,8 @@ vst3q_s8_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13278,6 +15260,8 @@ vst3q_s16_(a as _, b.0, b.1, b.2, 2)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13293,6 +15277,8 @@ vst3q_s16_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13307,6 +15293,8 @@ vst3q_s32_(a as _, b.0, b.1, b.2, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13322,6 +15310,8 @@ vst3q_s32_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13336,6 +15326,8 @@ vst3_s64_(a as _, b.0, b.1, b.2, 8)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13351,6 +15343,8 @@ vst3_s64_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13362,6 +15356,8 @@ pub unsafe fn vst3_u8(a: *mut u8, b: uint8x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13373,6 +15369,8 @@ pub unsafe fn vst3_u16(a: *mut u16, b: uint16x4x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13384,6 +15382,8 @@ pub unsafe fn vst3_u32(a: *mut u32, b: uint32x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13395,6 +15395,8 @@ pub unsafe fn vst3q_u8(a: *mut u8, b: uint8x16x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13406,6 +15408,8 @@ pub unsafe fn vst3q_u16(a: *mut u16, b: uint16x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13417,6 +15421,8 @@ pub unsafe fn vst3q_u32(a: *mut u32, b: uint32x4x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13428,6 +15434,8 @@ pub unsafe fn vst3_p8(a: *mut p8, b: poly8x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13439,6 +15447,8 @@ pub unsafe fn vst3_p16(a: *mut p16, b: poly16x4x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13450,6 +15460,8 @@ pub unsafe fn vst3q_p8(a: *mut p8, b: poly8x16x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13461,6 +15473,8 @@ pub unsafe fn vst3q_p16(a: *mut p16, b: poly16x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13472,6 +15486,8 @@ pub unsafe fn vst3_u64(a: *mut u64, b: uint64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -13483,6 +15499,8 @@ pub unsafe fn vst3_p64(a: *mut p64, b: poly64x1x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13497,6 +15515,8 @@ vst3_f32_(a as _, b.0, b.1, b.2, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13512,6 +15532,8 @@ vst3_f32_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13526,6 +15548,8 @@ vst3q_f32_(a as _, b.0, b.1, b.2, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13541,6 +15565,8 @@ vst3q_f32_(b.0, b.1, b.2, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13557,6 +15583,8 @@ vst3_lane_s8_(a as _, b.0, b.1, b.2, LANE, 1)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13574,6 +15602,8 @@ vst3_lane_s8_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13590,6 +15620,8 @@ vst3_lane_s16_(a as _, b.0, b.1, b.2, LANE, 2)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13607,6 +15639,8 @@ vst3_lane_s16_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13623,6 +15657,8 @@ vst3_lane_s32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13640,6 +15676,8 @@ vst3_lane_s32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13656,6 +15694,8 @@ vst3q_lane_s16_(a as _, b.0, b.1, b.2, LANE, 2)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13673,6 +15713,8 @@ vst3q_lane_s16_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13689,6 +15731,8 @@ vst3q_lane_s32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13706,6 +15750,8 @@ vst3q_lane_s32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13719,6 +15765,8 @@ pub unsafe fn vst3_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13732,6 +15780,8 @@ pub unsafe fn vst3_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x4x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13745,6 +15795,8 @@ pub unsafe fn vst3_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x2x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13758,6 +15810,8 @@ pub unsafe fn vst3q_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13771,6 +15825,8 @@ pub unsafe fn vst3q_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x4x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13784,6 +15840,8 @@ pub unsafe fn vst3_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13797,6 +15855,8 @@ pub unsafe fn vst3_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x4x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -13810,6 +15870,8 @@ pub unsafe fn vst3q_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x8x3_t) {
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13826,6 +15888,8 @@ vst3_lane_f32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13843,6 +15907,8 @@ vst3_lane_f32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13859,6 +15925,8 @@ vst3q_lane_f32_(a as _, b.0, b.1, b.2, LANE, 4)
}
/// Store multiple 3-element structures from three registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13876,6 +15944,8 @@ vst3q_lane_f32_(b.0, b.1, b.2, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13890,6 +15960,8 @@ vst4_s8_(a as _, b.0, b.1, b.2, b.3, 1)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13905,6 +15977,8 @@ vst4_s8_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13919,6 +15993,8 @@ vst4_s16_(a as _, b.0, b.1, b.2, b.3, 2)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13934,6 +16010,8 @@ vst4_s16_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13948,6 +16026,8 @@ vst4_s32_(a as _, b.0, b.1, b.2, b.3, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13963,6 +16043,8 @@ vst4_s32_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -13977,6 +16059,8 @@ vst4q_s8_(a as _, b.0, b.1, b.2, b.3, 1)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -13992,6 +16076,8 @@ vst4q_s8_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14006,6 +16092,8 @@ vst4q_s16_(a as _, b.0, b.1, b.2, b.3, 2)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14021,6 +16109,8 @@ vst4q_s16_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14035,6 +16125,8 @@ vst4q_s32_(a as _, b.0, b.1, b.2, b.3, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14050,6 +16142,8 @@ vst4q_s32_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14064,6 +16158,8 @@ vst4_s64_(a as _, b.0, b.1, b.2, b.3, 8)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14079,6 +16175,8 @@ vst4_s64_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14090,6 +16188,8 @@ pub unsafe fn vst4_u8(a: *mut u8, b: uint8x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14101,6 +16201,8 @@ pub unsafe fn vst4_u16(a: *mut u16, b: uint16x4x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14112,6 +16214,8 @@ pub unsafe fn vst4_u32(a: *mut u32, b: uint32x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14123,6 +16227,8 @@ pub unsafe fn vst4q_u8(a: *mut u8, b: uint8x16x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14134,6 +16240,8 @@ pub unsafe fn vst4q_u16(a: *mut u16, b: uint16x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14145,6 +16253,8 @@ pub unsafe fn vst4q_u32(a: *mut u32, b: uint32x4x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14156,6 +16266,8 @@ pub unsafe fn vst4_p8(a: *mut p8, b: poly8x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14167,6 +16279,8 @@ pub unsafe fn vst4_p16(a: *mut p16, b: poly16x4x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14178,6 +16292,8 @@ pub unsafe fn vst4q_p8(a: *mut p8, b: poly8x16x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14189,6 +16305,8 @@ pub unsafe fn vst4q_p16(a: *mut p16, b: poly16x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14200,6 +16318,8 @@ pub unsafe fn vst4_u64(a: *mut u64, b: uint64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -14211,6 +16331,8 @@ pub unsafe fn vst4_p64(a: *mut p64, b: poly64x1x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14225,6 +16347,8 @@ vst4_f32_(a as _, b.0, b.1, b.2, b.3, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14240,6 +16364,8 @@ vst4_f32_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14254,6 +16380,8 @@ vst4q_f32_(a as _, b.0, b.1, b.2, b.3, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14269,6 +16397,8 @@ vst4q_f32_(b.0, b.1, b.2, b.3, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14285,6 +16415,8 @@ vst4_lane_s8_(a as _, b.0, b.1, b.2, b.3, LANE, 1)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14302,6 +16434,8 @@ vst4_lane_s8_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14318,6 +16452,8 @@ vst4_lane_s16_(a as _, b.0, b.1, b.2, b.3, LANE, 2)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14335,6 +16471,8 @@ vst4_lane_s16_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14351,6 +16489,8 @@ vst4_lane_s32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14368,6 +16508,8 @@ vst4_lane_s32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14384,6 +16526,8 @@ vst4q_lane_s16_(a as _, b.0, b.1, b.2, b.3, LANE, 2)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14401,6 +16545,8 @@ vst4q_lane_s16_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14417,6 +16563,8 @@ vst4q_lane_s32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14434,6 +16582,8 @@ vst4q_lane_s32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14447,6 +16597,8 @@ pub unsafe fn vst4_lane_u8<const LANE: i32>(a: *mut u8, b: uint8x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14460,6 +16612,8 @@ pub unsafe fn vst4_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x4x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14473,6 +16627,8 @@ pub unsafe fn vst4_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x2x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14486,6 +16642,8 @@ pub unsafe fn vst4q_lane_u16<const LANE: i32>(a: *mut u16, b: uint16x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14499,6 +16657,8 @@ pub unsafe fn vst4q_lane_u32<const LANE: i32>(a: *mut u32, b: uint32x4x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14512,6 +16672,8 @@ pub unsafe fn vst4_lane_p8<const LANE: i32>(a: *mut p8, b: poly8x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14525,6 +16687,8 @@ pub unsafe fn vst4_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x4x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14538,6 +16702,8 @@ pub unsafe fn vst4q_lane_p16<const LANE: i32>(a: *mut p16, b: poly16x8x4_t) {
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14554,6 +16720,8 @@ vst4_lane_f32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14571,6 +16739,8 @@ vst4_lane_f32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -14587,6 +16757,8 @@ vst4q_lane_f32_(a as _, b.0, b.1, b.2, b.3, LANE, 4)
}
/// Store multiple 4-element structures from four registers
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -14604,6 +16776,8 @@ vst4q_lane_f32_(b.0, b.1, b.2, b.3, LANE as i64, a as _)
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14615,6 +16789,8 @@ pub unsafe fn vmul_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14626,6 +16802,8 @@ pub unsafe fn vmulq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14637,6 +16815,8 @@ pub unsafe fn vmul_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14648,6 +16828,8 @@ pub unsafe fn vmulq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14659,6 +16841,8 @@ pub unsafe fn vmul_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14670,6 +16854,8 @@ pub unsafe fn vmulq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14681,6 +16867,8 @@ pub unsafe fn vmul_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14692,6 +16880,8 @@ pub unsafe fn vmulq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14703,6 +16893,8 @@ pub unsafe fn vmul_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14714,6 +16906,8 @@ pub unsafe fn vmulq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14725,6 +16919,8 @@ pub unsafe fn vmul_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14736,6 +16932,8 @@ pub unsafe fn vmulq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Polynomial multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14753,6 +16951,8 @@ vmul_p8_(a, b)
}
/// Polynomial multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14770,6 +16970,8 @@ vmulq_p8_(a, b)
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14781,6 +16983,8 @@ pub unsafe fn vmul_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14792,6 +16996,8 @@ pub unsafe fn vmulq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14803,6 +17009,8 @@ pub unsafe fn vmul_n_s16(a: int16x4_t, b: i16) -> int16x4_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14814,6 +17022,8 @@ pub unsafe fn vmulq_n_s16(a: int16x8_t, b: i16) -> int16x8_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14825,6 +17035,8 @@ pub unsafe fn vmul_n_s32(a: int32x2_t, b: i32) -> int32x2_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14836,6 +17048,8 @@ pub unsafe fn vmulq_n_s32(a: int32x4_t, b: i32) -> int32x4_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14847,6 +17061,8 @@ pub unsafe fn vmul_n_u16(a: uint16x4_t, b: u16) -> uint16x4_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14858,6 +17074,8 @@ pub unsafe fn vmulq_n_u16(a: uint16x8_t, b: u16) -> uint16x8_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14869,6 +17087,8 @@ pub unsafe fn vmul_n_u32(a: uint32x2_t, b: u32) -> uint32x2_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14880,6 +17100,8 @@ pub unsafe fn vmulq_n_u32(a: uint32x4_t, b: u32) -> uint32x4_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14891,6 +17113,8 @@ pub unsafe fn vmul_n_f32(a: float32x2_t, b: f32) -> float32x2_t {
}
/// Vector multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14902,6 +17126,8 @@ pub unsafe fn vmulq_n_f32(a: float32x4_t, b: f32) -> float32x4_t {
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14915,6 +17141,8 @@ pub unsafe fn vmul_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t) -> int1
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14928,6 +17156,8 @@ pub unsafe fn vmul_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x8_t) -> int
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14941,6 +17171,8 @@ pub unsafe fn vmulq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x4_t) -> int
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14954,6 +17186,8 @@ pub unsafe fn vmulq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t) -> in
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14967,6 +17201,8 @@ pub unsafe fn vmul_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t) -> int3
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14980,6 +17216,8 @@ pub unsafe fn vmul_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x4_t) -> int
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -14993,6 +17231,8 @@ pub unsafe fn vmulq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x2_t) -> int
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15006,6 +17246,8 @@ pub unsafe fn vmulq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t) -> in
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15019,6 +17261,8 @@ pub unsafe fn vmul_lane_u16<const LANE: i32>(a: uint16x4_t, b: uint16x4_t) -> ui
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15032,6 +17276,8 @@ pub unsafe fn vmul_laneq_u16<const LANE: i32>(a: uint16x4_t, b: uint16x8_t) -> u
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15045,6 +17291,8 @@ pub unsafe fn vmulq_lane_u16<const LANE: i32>(a: uint16x8_t, b: uint16x4_t) -> u
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15058,6 +17306,8 @@ pub unsafe fn vmulq_laneq_u16<const LANE: i32>(a: uint16x8_t, b: uint16x8_t) ->
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15071,6 +17321,8 @@ pub unsafe fn vmul_lane_u32<const LANE: i32>(a: uint32x2_t, b: uint32x2_t) -> ui
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15084,6 +17336,8 @@ pub unsafe fn vmul_laneq_u32<const LANE: i32>(a: uint32x2_t, b: uint32x4_t) -> u
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15097,6 +17351,8 @@ pub unsafe fn vmulq_lane_u32<const LANE: i32>(a: uint32x4_t, b: uint32x2_t) -> u
}
/// Multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15110,6 +17366,8 @@ pub unsafe fn vmulq_laneq_u32<const LANE: i32>(a: uint32x4_t, b: uint32x4_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15123,6 +17381,8 @@ pub unsafe fn vmul_lane_f32<const LANE: i32>(a: float32x2_t, b: float32x2_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15136,6 +17396,8 @@ pub unsafe fn vmul_laneq_f32<const LANE: i32>(a: float32x2_t, b: float32x4_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15149,6 +17411,8 @@ pub unsafe fn vmulq_lane_f32<const LANE: i32>(a: float32x4_t, b: float32x2_t) ->
}
/// Floating-point multiply
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15162,6 +17426,8 @@ pub unsafe fn vmulq_laneq_f32<const LANE: i32>(a: float32x4_t, b: float32x4_t) -
}
/// Signed multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15179,6 +17445,8 @@ vmull_s8_(a, b)
}
/// Signed multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15196,6 +17464,8 @@ vmull_s16_(a, b)
}
/// Signed multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15213,6 +17483,8 @@ vmull_s32_(a, b)
}
/// Unsigned multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15230,6 +17502,8 @@ vmull_u8_(a, b)
}
/// Unsigned multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15247,6 +17521,8 @@ vmull_u16_(a, b)
}
/// Unsigned multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15264,6 +17540,8 @@ vmull_u32_(a, b)
}
/// Polynomial multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15281,6 +17559,8 @@ vmull_p8_(a, b)
}
/// Vector long multiply with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15292,6 +17572,8 @@ pub unsafe fn vmull_n_s16(a: int16x4_t, b: i16) -> int32x4_t {
}
/// Vector long multiply with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15303,6 +17585,8 @@ pub unsafe fn vmull_n_s32(a: int32x2_t, b: i32) -> int64x2_t {
}
/// Vector long multiply with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15314,6 +17598,8 @@ pub unsafe fn vmull_n_u16(a: uint16x4_t, b: u16) -> uint32x4_t {
}
/// Vector long multiply with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15325,6 +17611,8 @@ pub unsafe fn vmull_n_u32(a: uint32x2_t, b: u32) -> uint64x2_t {
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15338,6 +17626,8 @@ pub unsafe fn vmull_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t) -> int
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15351,6 +17641,8 @@ pub unsafe fn vmull_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x8_t) -> in
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15364,6 +17656,8 @@ pub unsafe fn vmull_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t) -> int
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15377,6 +17671,8 @@ pub unsafe fn vmull_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x4_t) -> in
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15390,6 +17686,8 @@ pub unsafe fn vmull_lane_u16<const LANE: i32>(a: uint16x4_t, b: uint16x4_t) -> u
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15403,6 +17701,8 @@ pub unsafe fn vmull_laneq_u16<const LANE: i32>(a: uint16x4_t, b: uint16x8_t) ->
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15416,6 +17716,8 @@ pub unsafe fn vmull_lane_u32<const LANE: i32>(a: uint32x2_t, b: uint32x2_t) -> u
}
/// Vector long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15429,6 +17731,8 @@ pub unsafe fn vmull_laneq_u32<const LANE: i32>(a: uint32x2_t, b: uint32x4_t) ->
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15446,6 +17750,8 @@ vfma_f32_(b, c, a)
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15463,6 +17769,8 @@ vfmaq_f32_(b, c, a)
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15474,6 +17782,8 @@ pub unsafe fn vfma_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t
}
/// Floating-point fused Multiply-Add to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15485,6 +17795,8 @@ pub unsafe fn vfmaq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t
}
/// Floating-point fused multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15497,6 +17809,8 @@ pub unsafe fn vfms_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float3
}
/// Floating-point fused multiply-subtract from accumulator
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15509,6 +17823,8 @@ pub unsafe fn vfmsq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float
}
/// Floating-point fused Multiply-subtract to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15520,6 +17836,8 @@ pub unsafe fn vfms_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t
}
/// Floating-point fused Multiply-subtract to accumulator(vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_n_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
@@ -15531,6 +17849,8 @@ pub unsafe fn vfmsq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15542,6 +17862,8 @@ pub unsafe fn vsub_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15553,6 +17875,8 @@ pub unsafe fn vsubq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15564,6 +17888,8 @@ pub unsafe fn vsub_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15575,6 +17901,8 @@ pub unsafe fn vsubq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15586,6 +17914,8 @@ pub unsafe fn vsub_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15597,6 +17927,8 @@ pub unsafe fn vsubq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15608,6 +17940,8 @@ pub unsafe fn vsub_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15619,6 +17953,8 @@ pub unsafe fn vsubq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15630,6 +17966,8 @@ pub unsafe fn vsub_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15641,6 +17979,8 @@ pub unsafe fn vsubq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15652,6 +17992,8 @@ pub unsafe fn vsub_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15663,6 +18005,8 @@ pub unsafe fn vsubq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15674,6 +18018,8 @@ pub unsafe fn vsub_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15685,6 +18031,8 @@ pub unsafe fn vsubq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15696,6 +18044,8 @@ pub unsafe fn vsub_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15707,6 +18057,8 @@ pub unsafe fn vsubq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15718,6 +18070,8 @@ pub unsafe fn vsub_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
}
/// Subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15729,6 +18083,8 @@ pub unsafe fn vsubq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15740,6 +18096,8 @@ pub unsafe fn vadd_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15751,6 +18109,8 @@ pub unsafe fn vadd_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15762,6 +18122,8 @@ pub unsafe fn vaddq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15773,6 +18135,8 @@ pub unsafe fn vaddq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15784,6 +18148,8 @@ pub unsafe fn vadd_p64(a: poly64x1_t, b: poly64x1_t) -> poly64x1_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15795,6 +18161,8 @@ pub unsafe fn vaddq_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
}
/// Bitwise exclusive OR
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p128)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15806,6 +18174,8 @@ pub unsafe fn vaddq_p128(a: p128, b: p128) -> p128 {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15818,6 +18188,8 @@ pub unsafe fn vsubhn_s16(a: int16x8_t, b: int16x8_t) -> int8x8_t {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15830,6 +18202,8 @@ pub unsafe fn vsubhn_s32(a: int32x4_t, b: int32x4_t) -> int16x4_t {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15842,6 +18216,8 @@ pub unsafe fn vsubhn_s64(a: int64x2_t, b: int64x2_t) -> int32x2_t {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15854,6 +18230,8 @@ pub unsafe fn vsubhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15866,6 +18244,8 @@ pub unsafe fn vsubhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15878,6 +18258,8 @@ pub unsafe fn vsubhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15890,6 +18272,8 @@ pub unsafe fn vsubhn_high_s16(a: int8x8_t, b: int16x8_t, c: int16x8_t) -> int8x1
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15902,6 +18286,8 @@ pub unsafe fn vsubhn_high_s32(a: int16x4_t, b: int32x4_t, c: int32x4_t) -> int16
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15914,6 +18300,8 @@ pub unsafe fn vsubhn_high_s64(a: int32x2_t, b: int64x2_t, c: int64x2_t) -> int32
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15926,6 +18314,8 @@ pub unsafe fn vsubhn_high_u16(a: uint8x8_t, b: uint16x8_t, c: uint16x8_t) -> uin
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15938,6 +18328,8 @@ pub unsafe fn vsubhn_high_u32(a: uint16x4_t, b: uint32x4_t, c: uint32x4_t) -> ui
}
/// Subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15950,6 +18342,8 @@ pub unsafe fn vsubhn_high_u64(a: uint32x2_t, b: uint64x2_t, c: uint64x2_t) -> ui
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15967,6 +18361,8 @@ vhsub_u8_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -15984,6 +18380,8 @@ vhsubq_u8_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16001,6 +18399,8 @@ vhsub_u16_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16018,6 +18418,8 @@ vhsubq_u16_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16035,6 +18437,8 @@ vhsub_u32_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16052,6 +18456,8 @@ vhsubq_u32_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16069,6 +18475,8 @@ vhsub_s8_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16086,6 +18494,8 @@ vhsubq_s8_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16103,6 +18513,8 @@ vhsub_s16_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16120,6 +18532,8 @@ vhsubq_s16_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16137,6 +18551,8 @@ vhsub_s32_(a, b)
}
/// Signed halving subtract
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16154,6 +18570,8 @@ vhsubq_s32_(a, b)
}
/// Signed Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16165,6 +18583,8 @@ pub unsafe fn vsubw_s8(a: int16x8_t, b: int8x8_t) -> int16x8_t {
}
/// Signed Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16176,6 +18596,8 @@ pub unsafe fn vsubw_s16(a: int32x4_t, b: int16x4_t) -> int32x4_t {
}
/// Signed Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16187,6 +18609,8 @@ pub unsafe fn vsubw_s32(a: int64x2_t, b: int32x2_t) -> int64x2_t {
}
/// Unsigned Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16198,6 +18622,8 @@ pub unsafe fn vsubw_u8(a: uint16x8_t, b: uint8x8_t) -> uint16x8_t {
}
/// Unsigned Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16209,6 +18635,8 @@ pub unsafe fn vsubw_u16(a: uint32x4_t, b: uint16x4_t) -> uint32x4_t {
}
/// Unsigned Subtract Wide
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16220,6 +18648,8 @@ pub unsafe fn vsubw_u32(a: uint64x2_t, b: uint32x2_t) -> uint64x2_t {
}
/// Signed Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16233,6 +18663,8 @@ pub unsafe fn vsubl_s8(a: int8x8_t, b: int8x8_t) -> int16x8_t {
}
/// Signed Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16246,6 +18678,8 @@ pub unsafe fn vsubl_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
}
/// Signed Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16259,6 +18693,8 @@ pub unsafe fn vsubl_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
}
/// Unsigned Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16272,6 +18708,8 @@ pub unsafe fn vsubl_u8(a: uint8x8_t, b: uint8x8_t) -> uint16x8_t {
}
/// Unsigned Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16285,6 +18723,8 @@ pub unsafe fn vsubl_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4_t {
}
/// Unsigned Subtract Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16298,6 +18738,8 @@ pub unsafe fn vsubl_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2_t {
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16315,6 +18757,8 @@ vmax_s8_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16332,6 +18776,8 @@ vmaxq_s8_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16349,6 +18795,8 @@ vmax_s16_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16366,6 +18814,8 @@ vmaxq_s16_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16383,6 +18833,8 @@ vmax_s32_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16400,6 +18852,8 @@ vmaxq_s32_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16417,6 +18871,8 @@ vmax_u8_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16434,6 +18890,8 @@ vmaxq_u8_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16451,6 +18909,8 @@ vmax_u16_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16468,6 +18928,8 @@ vmaxq_u16_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16485,6 +18947,8 @@ vmax_u32_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16502,6 +18966,8 @@ vmaxq_u32_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16519,6 +18985,8 @@ vmax_f32_(a, b)
}
/// Maximum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16536,6 +19004,8 @@ vmaxq_f32_(a, b)
}
/// Floating-point Maximum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnm_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
@@ -16553,6 +19023,8 @@ vmaxnm_f32_(a, b)
}
/// Floating-point Maximum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
@@ -16570,6 +19042,8 @@ vmaxnmq_f32_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16587,6 +19061,8 @@ vmin_s8_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16604,6 +19080,8 @@ vminq_s8_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16621,6 +19099,8 @@ vmin_s16_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16638,6 +19118,8 @@ vminq_s16_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16655,6 +19137,8 @@ vmin_s32_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16672,6 +19156,8 @@ vminq_s32_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16689,6 +19175,8 @@ vmin_u8_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16706,6 +19194,8 @@ vminq_u8_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16723,6 +19213,8 @@ vmin_u16_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16740,6 +19232,8 @@ vminq_u16_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16757,6 +19251,8 @@ vmin_u32_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16774,6 +19270,8 @@ vminq_u32_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16791,6 +19289,8 @@ vmin_f32_(a, b)
}
/// Minimum (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16808,6 +19308,8 @@ vminq_f32_(a, b)
}
/// Floating-point Minimum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnm_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
@@ -16825,6 +19327,8 @@ vminnm_f32_(a, b)
}
/// Floating-point Minimum Number (vector)
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
@@ -16842,6 +19346,8 @@ vminnmq_f32_(a, b)
}
/// Floating-point add pairwise
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16859,6 +19365,8 @@ vpadd_f32_(a, b)
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16876,6 +19384,8 @@ vqdmull_s16_(a, b)
}
/// Signed saturating doubling multiply long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16893,6 +19403,8 @@ vqdmull_s32_(a, b)
}
/// Vector saturating doubling long multiply with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16904,6 +19416,8 @@ pub unsafe fn vqdmull_n_s16(a: int16x4_t, b: i16) -> int32x4_t {
}
/// Vector saturating doubling long multiply with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16915,6 +19429,8 @@ pub unsafe fn vqdmull_n_s32(a: int32x2_t, b: i32) -> int64x2_t {
}
/// Vector saturating doubling long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16929,6 +19445,8 @@ pub unsafe fn vqdmull_lane_s16<const N: i32>(a: int16x4_t, b: int16x4_t) -> int3
}
/// Vector saturating doubling long multiply by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16943,6 +19461,8 @@ pub unsafe fn vqdmull_lane_s32<const N: i32>(a: int32x2_t, b: int32x2_t) -> int6
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16954,6 +19474,8 @@ pub unsafe fn vqdmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t
}
/// Signed saturating doubling multiply-add long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16965,6 +19487,8 @@ pub unsafe fn vqdmlal_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t
}
/// Vector widening saturating doubling multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16976,6 +19500,8 @@ pub unsafe fn vqdmlal_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
}
/// Vector widening saturating doubling multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -16987,6 +19513,8 @@ pub unsafe fn vqdmlal_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
}
/// Vector widening saturating doubling multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17000,6 +19528,8 @@ pub unsafe fn vqdmlal_lane_s16<const N: i32>(a: int32x4_t, b: int16x4_t, c: int1
}
/// Vector widening saturating doubling multiply accumulate with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17013,6 +19543,8 @@ pub unsafe fn vqdmlal_lane_s32<const N: i32>(a: int64x2_t, b: int32x2_t, c: int3
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17024,6 +19556,8 @@ pub unsafe fn vqdmlsl_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t
}
/// Signed saturating doubling multiply-subtract long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17035,6 +19569,8 @@ pub unsafe fn vqdmlsl_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t
}
/// Vector widening saturating doubling multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17046,6 +19582,8 @@ pub unsafe fn vqdmlsl_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
}
/// Vector widening saturating doubling multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17057,6 +19595,8 @@ pub unsafe fn vqdmlsl_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
}
/// Vector widening saturating doubling multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17070,6 +19610,8 @@ pub unsafe fn vqdmlsl_lane_s16<const N: i32>(a: int32x4_t, b: int16x4_t, c: int1
}
/// Vector widening saturating doubling multiply subtract with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17083,6 +19625,8 @@ pub unsafe fn vqdmlsl_lane_s32<const N: i32>(a: int64x2_t, b: int32x2_t, c: int3
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17100,6 +19644,8 @@ vqdmulh_s16_(a, b)
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17117,6 +19663,8 @@ vqdmulhq_s16_(a, b)
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17134,6 +19682,8 @@ vqdmulh_s32_(a, b)
}
/// Signed saturating doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17151,6 +19701,8 @@ vqdmulhq_s32_(a, b)
}
/// Vector saturating doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17163,6 +19715,8 @@ pub unsafe fn vqdmulh_n_s16(a: int16x4_t, b: i16) -> int16x4_t {
}
/// Vector saturating doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17175,6 +19729,8 @@ pub unsafe fn vqdmulh_n_s32(a: int32x2_t, b: i32) -> int32x2_t {
}
/// Vector saturating doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17187,6 +19743,8 @@ pub unsafe fn vqdmulhq_n_s16(a: int16x8_t, b: i16) -> int16x8_t {
}
/// Vector saturating doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17199,6 +19757,8 @@ pub unsafe fn vqdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t {
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17212,6 +19772,8 @@ pub unsafe fn vqdmulhq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t) ->
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17225,6 +19787,8 @@ pub unsafe fn vqdmulh_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x8_t) ->
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17238,6 +19802,8 @@ pub unsafe fn vqdmulhq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t) ->
}
/// Vector saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17251,6 +19817,8 @@ pub unsafe fn vqdmulh_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x4_t) ->
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17268,6 +19836,8 @@ vqmovn_s16_(a)
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17285,6 +19855,8 @@ vqmovn_s32_(a)
}
/// Signed saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17302,6 +19874,8 @@ vqmovn_s64_(a)
}
/// Unsigned saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17319,6 +19893,8 @@ vqmovn_u16_(a)
}
/// Unsigned saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17336,6 +19912,8 @@ vqmovn_u32_(a)
}
/// Unsigned saturating extract narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17353,6 +19931,8 @@ vqmovn_u64_(a)
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17370,6 +19950,8 @@ vqmovun_s16_(a)
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17387,6 +19969,8 @@ vqmovun_s32_(a)
}
/// Signed saturating extract unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17404,6 +19988,8 @@ vqmovun_s64_(a)
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17421,6 +20007,8 @@ vqrdmulh_s16_(a, b)
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17438,6 +20026,8 @@ vqrdmulhq_s16_(a, b)
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17455,6 +20045,8 @@ vqrdmulh_s32_(a, b)
}
/// Signed saturating rounding doubling multiply returning high half
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17472,6 +20064,8 @@ vqrdmulhq_s32_(a, b)
}
/// Vector saturating rounding doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17483,6 +20077,8 @@ pub unsafe fn vqrdmulh_n_s16(a: int16x4_t, b: i16) -> int16x4_t {
}
/// Vector saturating rounding doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17494,6 +20090,8 @@ pub unsafe fn vqrdmulhq_n_s16(a: int16x8_t, b: i16) -> int16x8_t {
}
/// Vector saturating rounding doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17505,6 +20103,8 @@ pub unsafe fn vqrdmulh_n_s32(a: int32x2_t, b: i32) -> int32x2_t {
}
/// Vector saturating rounding doubling multiply high with scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17516,6 +20116,8 @@ pub unsafe fn vqrdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t {
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17530,6 +20132,8 @@ pub unsafe fn vqrdmulh_lane_s16<const LANE: i32>(a: int16x4_t, b: int16x4_t) ->
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17544,6 +20148,8 @@ pub unsafe fn vqrdmulh_laneq_s16<const LANE: i32>(a: int16x4_t, b: int16x8_t) ->
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17558,6 +20164,8 @@ pub unsafe fn vqrdmulhq_lane_s16<const LANE: i32>(a: int16x8_t, b: int16x4_t) ->
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_laneq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17572,6 +20180,8 @@ pub unsafe fn vqrdmulhq_laneq_s16<const LANE: i32>(a: int16x8_t, b: int16x8_t) -
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17586,6 +20196,8 @@ pub unsafe fn vqrdmulh_lane_s32<const LANE: i32>(a: int32x2_t, b: int32x2_t) ->
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17600,6 +20212,8 @@ pub unsafe fn vqrdmulh_laneq_s32<const LANE: i32>(a: int32x2_t, b: int32x4_t) ->
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17614,6 +20228,8 @@ pub unsafe fn vqrdmulhq_lane_s32<const LANE: i32>(a: int32x4_t, b: int32x2_t) ->
}
/// Vector rounding saturating doubling multiply high by scalar
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_laneq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17628,6 +20244,8 @@ pub unsafe fn vqrdmulhq_laneq_s32<const LANE: i32>(a: int32x4_t, b: int32x4_t) -
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17645,6 +20263,8 @@ vqrshl_s8_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17662,6 +20282,8 @@ vqrshlq_s8_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17679,6 +20301,8 @@ vqrshl_s16_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17696,6 +20320,8 @@ vqrshlq_s16_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17713,6 +20339,8 @@ vqrshl_s32_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17730,6 +20358,8 @@ vqrshlq_s32_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17747,6 +20377,8 @@ vqrshl_s64_(a, b)
}
/// Signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17764,6 +20396,8 @@ vqrshlq_s64_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17781,6 +20415,8 @@ vqrshl_u8_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17798,6 +20434,8 @@ vqrshlq_u8_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17815,6 +20453,8 @@ vqrshl_u16_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17832,6 +20472,8 @@ vqrshlq_u16_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17849,6 +20491,8 @@ vqrshl_u32_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17866,6 +20510,8 @@ vqrshlq_u32_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17883,6 +20529,8 @@ vqrshl_u64_(a, b)
}
/// Unsigned signed saturating rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -17900,6 +20548,8 @@ vqrshlq_u64_(a, b)
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -17916,6 +20566,8 @@ vqrshrn_n_s16_(a, int16x8_t(-N as i16, -N as i16, -N as i16, -N as i16, -N as i1
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -17933,6 +20585,8 @@ vqrshrn_n_s16_(a, N)
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -17949,6 +20603,8 @@ vqrshrn_n_s32_(a, int32x4_t(-N as i32, -N as i32, -N as i32, -N as i32))
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -17966,6 +20622,8 @@ vqrshrn_n_s32_(a, N)
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -17982,6 +20640,8 @@ vqrshrn_n_s64_(a, int64x2_t(-N as i64, -N as i64))
}
/// Signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -17999,6 +20659,8 @@ vqrshrn_n_s64_(a, N)
}
/// Unsigned signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18015,6 +20677,8 @@ vqrshrn_n_u16_(a, uint16x8_t(-N as u16, -N as u16, -N as u16, -N as u16, -N as u
}
/// Unsigned signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18032,6 +20696,8 @@ vqrshrn_n_u16_(a, N)
}
/// Unsigned signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18048,6 +20714,8 @@ vqrshrn_n_u32_(a, uint32x4_t(-N as u32, -N as u32, -N as u32, -N as u32))
}
/// Unsigned signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18065,6 +20733,8 @@ vqrshrn_n_u32_(a, N)
}
/// Unsigned signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18081,6 +20751,8 @@ vqrshrn_n_u64_(a, uint64x2_t(-N as u64, -N as u64))
}
/// Unsigned signed saturating rounded shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18098,6 +20770,8 @@ vqrshrn_n_u64_(a, N)
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18114,6 +20788,8 @@ vqrshrun_n_s16_(a, int16x8_t(-N as i16, -N as i16, -N as i16, -N as i16, -N as i
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18131,6 +20807,8 @@ vqrshrun_n_s16_(a, N)
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18147,6 +20825,8 @@ vqrshrun_n_s32_(a, int32x4_t(-N as i32, -N as i32, -N as i32, -N as i32))
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18164,6 +20844,8 @@ vqrshrun_n_s32_(a, N)
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18180,6 +20862,8 @@ vqrshrun_n_s64_(a, int64x2_t(-N as i64, -N as i64))
}
/// Signed saturating rounded shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18197,6 +20881,8 @@ vqrshrun_n_s64_(a, N)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18214,6 +20900,8 @@ vqshl_s8_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18231,6 +20919,8 @@ vqshlq_s8_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18248,6 +20938,8 @@ vqshl_s16_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18265,6 +20957,8 @@ vqshlq_s16_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18282,6 +20976,8 @@ vqshl_s32_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18299,6 +20995,8 @@ vqshlq_s32_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18316,6 +21014,8 @@ vqshl_s64_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18333,6 +21033,8 @@ vqshlq_s64_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18350,6 +21052,8 @@ vqshl_u8_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18367,6 +21071,8 @@ vqshlq_u8_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18384,6 +21090,8 @@ vqshl_u16_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18401,6 +21109,8 @@ vqshlq_u16_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18418,6 +21128,8 @@ vqshl_u32_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18435,6 +21147,8 @@ vqshlq_u32_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18452,6 +21166,8 @@ vqshl_u64_(a, b)
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18469,6 +21185,8 @@ vqshlq_u64_(a, b)
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18482,6 +21200,8 @@ pub unsafe fn vqshl_n_s8<const N: i32>(a: int8x8_t) -> int8x8_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18495,6 +21215,8 @@ pub unsafe fn vqshlq_n_s8<const N: i32>(a: int8x16_t) -> int8x16_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18508,6 +21230,8 @@ pub unsafe fn vqshl_n_s16<const N: i32>(a: int16x4_t) -> int16x4_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18521,6 +21245,8 @@ pub unsafe fn vqshlq_n_s16<const N: i32>(a: int16x8_t) -> int16x8_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18534,6 +21260,8 @@ pub unsafe fn vqshl_n_s32<const N: i32>(a: int32x2_t) -> int32x2_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18547,6 +21275,8 @@ pub unsafe fn vqshlq_n_s32<const N: i32>(a: int32x4_t) -> int32x4_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18560,6 +21290,8 @@ pub unsafe fn vqshl_n_s64<const N: i32>(a: int64x1_t) -> int64x1_t {
}
/// Signed saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18573,6 +21305,8 @@ pub unsafe fn vqshlq_n_s64<const N: i32>(a: int64x2_t) -> int64x2_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18586,6 +21320,8 @@ pub unsafe fn vqshl_n_u8<const N: i32>(a: uint8x8_t) -> uint8x8_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18599,6 +21335,8 @@ pub unsafe fn vqshlq_n_u8<const N: i32>(a: uint8x16_t) -> uint8x16_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18612,6 +21350,8 @@ pub unsafe fn vqshl_n_u16<const N: i32>(a: uint16x4_t) -> uint16x4_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18625,6 +21365,8 @@ pub unsafe fn vqshlq_n_u16<const N: i32>(a: uint16x8_t) -> uint16x8_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18638,6 +21380,8 @@ pub unsafe fn vqshl_n_u32<const N: i32>(a: uint32x2_t) -> uint32x2_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18651,6 +21395,8 @@ pub unsafe fn vqshlq_n_u32<const N: i32>(a: uint32x4_t) -> uint32x4_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18664,6 +21410,8 @@ pub unsafe fn vqshl_n_u64<const N: i32>(a: uint64x1_t) -> uint64x1_t {
}
/// Unsigned saturating shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -18677,6 +21425,8 @@ pub unsafe fn vqshlq_n_u64<const N: i32>(a: uint64x2_t) -> uint64x2_t {
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18693,6 +21443,8 @@ vqshlu_n_s8_(a, int8x8_t(N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18710,6 +21462,8 @@ vqshlu_n_s8_(a, int8x8_t(N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18726,6 +21480,8 @@ vqshlu_n_s16_(a, int16x4_t(N as i16, N as i16, N as i16, N as i16))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18743,6 +21499,8 @@ vqshlu_n_s16_(a, int16x4_t(N as i16, N as i16, N as i16, N as i16))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18759,6 +21517,8 @@ vqshlu_n_s32_(a, int32x2_t(N as i32, N as i32))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18776,6 +21536,8 @@ vqshlu_n_s32_(a, int32x2_t(N as i32, N as i32))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18792,6 +21554,8 @@ vqshlu_n_s64_(a, int64x1_t(N as i64))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18809,6 +21573,8 @@ vqshlu_n_s64_(a, int64x1_t(N as i64))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18825,6 +21591,8 @@ vqshluq_n_s8_(a, int8x16_t(N as i8, N as i8, N as i8, N as i8, N as i8, N as i8,
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18842,6 +21610,8 @@ vqshluq_n_s8_(a, int8x16_t(N as i8, N as i8, N as i8, N as i8, N as i8, N as i8,
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18858,6 +21628,8 @@ vqshluq_n_s16_(a, int16x8_t(N as i16, N as i16, N as i16, N as i16, N as i16, N
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18875,6 +21647,8 @@ vqshluq_n_s16_(a, int16x8_t(N as i16, N as i16, N as i16, N as i16, N as i16, N
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18891,6 +21665,8 @@ vqshluq_n_s32_(a, int32x4_t(N as i32, N as i32, N as i32, N as i32))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18908,6 +21684,8 @@ vqshluq_n_s32_(a, int32x4_t(N as i32, N as i32, N as i32, N as i32))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18924,6 +21702,8 @@ vqshluq_n_s64_(a, int64x2_t(N as i64, N as i64))
}
/// Signed saturating shift left unsigned
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18941,6 +21721,8 @@ vqshluq_n_s64_(a, int64x2_t(N as i64, N as i64))
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18957,6 +21739,8 @@ vqshrn_n_s16_(a, int16x8_t(-N as i16, -N as i16, -N as i16, -N as i16, -N as i16
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -18974,6 +21758,8 @@ vqshrn_n_s16_(a, N)
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -18990,6 +21776,8 @@ vqshrn_n_s32_(a, int32x4_t(-N as i32, -N as i32, -N as i32, -N as i32))
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19007,6 +21795,8 @@ vqshrn_n_s32_(a, N)
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19023,6 +21813,8 @@ vqshrn_n_s64_(a, int64x2_t(-N as i64, -N as i64))
}
/// Signed saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19040,6 +21832,8 @@ vqshrn_n_s64_(a, N)
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19056,6 +21850,8 @@ vqshrn_n_u16_(a, uint16x8_t(-N as u16, -N as u16, -N as u16, -N as u16, -N as u1
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19073,6 +21869,8 @@ vqshrn_n_u16_(a, N)
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19089,6 +21887,8 @@ vqshrn_n_u32_(a, uint32x4_t(-N as u32, -N as u32, -N as u32, -N as u32))
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19106,6 +21906,8 @@ vqshrn_n_u32_(a, N)
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19122,6 +21924,8 @@ vqshrn_n_u64_(a, uint64x2_t(-N as u64, -N as u64))
}
/// Unsigned saturating shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19139,6 +21943,8 @@ vqshrn_n_u64_(a, N)
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19155,6 +21961,8 @@ vqshrun_n_s16_(a, int16x8_t(-N as i16, -N as i16, -N as i16, -N as i16, -N as i1
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19172,6 +21980,8 @@ vqshrun_n_s16_(a, N)
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19188,6 +21998,8 @@ vqshrun_n_s32_(a, int32x4_t(-N as i32, -N as i32, -N as i32, -N as i32))
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19205,6 +22017,8 @@ vqshrun_n_s32_(a, N)
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -19221,6 +22035,8 @@ vqshrun_n_s64_(a, int64x2_t(-N as i64, -N as i64))
}
/// Signed saturating shift right unsigned narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -19238,6 +22054,8 @@ vqshrun_n_s64_(a, N)
}
/// Reciprocal square-root estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19255,6 +22073,8 @@ vrsqrte_f32_(a)
}
/// Reciprocal square-root estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19272,6 +22092,8 @@ vrsqrteq_f32_(a)
}
/// Unsigned reciprocal square root estimate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19289,6 +22111,8 @@ vrsqrte_u32_(a)
}
/// Unsigned reciprocal square root estimate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19306,6 +22130,8 @@ vrsqrteq_u32_(a)
}
/// Floating-point reciprocal square root step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrts_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19323,6 +22149,8 @@ vrsqrts_f32_(a, b)
}
/// Floating-point reciprocal square root step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19340,6 +22168,8 @@ vrsqrtsq_f32_(a, b)
}
/// Reciprocal estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19357,6 +22187,8 @@ vrecpe_f32_(a)
}
/// Reciprocal estimate.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19374,6 +22206,8 @@ vrecpeq_f32_(a)
}
/// Unsigned reciprocal estimate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19391,6 +22225,8 @@ vrecpe_u32_(a)
}
/// Unsigned reciprocal estimate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19408,6 +22244,8 @@ vrecpeq_u32_(a)
}
/// Floating-point reciprocal step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecps_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19425,6 +22263,8 @@ vrecps_f32_(a, b)
}
/// Floating-point reciprocal step
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19442,6 +22282,8 @@ vrecpsq_f32_(a, b)
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19453,6 +22295,8 @@ pub unsafe fn vreinterpret_s8_u8(a: uint8x8_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19464,6 +22308,8 @@ pub unsafe fn vreinterpret_s8_p8(a: poly8x8_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19475,6 +22321,8 @@ pub unsafe fn vreinterpret_s16_p16(a: poly16x4_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19486,6 +22334,8 @@ pub unsafe fn vreinterpret_s16_u16(a: uint16x4_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19497,6 +22347,8 @@ pub unsafe fn vreinterpret_s32_u32(a: uint32x2_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19508,6 +22360,8 @@ pub unsafe fn vreinterpret_s64_u64(a: uint64x1_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19519,6 +22373,8 @@ pub unsafe fn vreinterpretq_s8_u8(a: uint8x16_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19530,6 +22386,8 @@ pub unsafe fn vreinterpretq_s8_p8(a: poly8x16_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19541,6 +22399,8 @@ pub unsafe fn vreinterpretq_s16_p16(a: poly16x8_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19552,6 +22412,8 @@ pub unsafe fn vreinterpretq_s16_u16(a: uint16x8_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19563,6 +22425,8 @@ pub unsafe fn vreinterpretq_s32_u32(a: uint32x4_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19574,6 +22438,8 @@ pub unsafe fn vreinterpretq_s64_u64(a: uint64x2_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19585,6 +22451,8 @@ pub unsafe fn vreinterpret_u8_p8(a: poly8x8_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19596,6 +22464,8 @@ pub unsafe fn vreinterpret_u8_s8(a: int8x8_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19607,6 +22477,8 @@ pub unsafe fn vreinterpret_u16_p16(a: poly16x4_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19618,6 +22490,8 @@ pub unsafe fn vreinterpret_u16_s16(a: int16x4_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19629,6 +22503,8 @@ pub unsafe fn vreinterpret_u32_s32(a: int32x2_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19640,6 +22516,8 @@ pub unsafe fn vreinterpret_u64_s64(a: int64x1_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19651,6 +22529,8 @@ pub unsafe fn vreinterpretq_u8_p8(a: poly8x16_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19662,6 +22542,8 @@ pub unsafe fn vreinterpretq_u8_s8(a: int8x16_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19673,6 +22555,8 @@ pub unsafe fn vreinterpretq_u16_p16(a: poly16x8_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19684,6 +22568,8 @@ pub unsafe fn vreinterpretq_u16_s16(a: int16x8_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19695,6 +22581,8 @@ pub unsafe fn vreinterpretq_u32_s32(a: int32x4_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19706,6 +22594,8 @@ pub unsafe fn vreinterpretq_u64_s64(a: int64x2_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19717,6 +22607,8 @@ pub unsafe fn vreinterpret_p8_s8(a: int8x8_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19728,6 +22620,8 @@ pub unsafe fn vreinterpret_p8_u8(a: uint8x8_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19739,6 +22633,8 @@ pub unsafe fn vreinterpret_p16_s16(a: int16x4_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19750,6 +22646,8 @@ pub unsafe fn vreinterpret_p16_u16(a: uint16x4_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19761,6 +22659,8 @@ pub unsafe fn vreinterpretq_p8_s8(a: int8x16_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19772,6 +22672,8 @@ pub unsafe fn vreinterpretq_p8_u8(a: uint8x16_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19783,6 +22685,8 @@ pub unsafe fn vreinterpretq_p16_s16(a: int16x8_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19794,6 +22698,8 @@ pub unsafe fn vreinterpretq_p16_u16(a: uint16x8_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19805,6 +22711,8 @@ pub unsafe fn vreinterpret_s8_s16(a: int16x4_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19816,6 +22724,8 @@ pub unsafe fn vreinterpret_s8_u16(a: uint16x4_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19827,6 +22737,8 @@ pub unsafe fn vreinterpret_s8_p16(a: poly16x4_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19838,6 +22750,8 @@ pub unsafe fn vreinterpret_s16_s32(a: int32x2_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19849,6 +22763,8 @@ pub unsafe fn vreinterpret_s16_u32(a: uint32x2_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19860,6 +22776,8 @@ pub unsafe fn vreinterpret_s32_s64(a: int64x1_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19871,6 +22789,8 @@ pub unsafe fn vreinterpret_s32_u64(a: uint64x1_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19882,6 +22802,8 @@ pub unsafe fn vreinterpretq_s8_s16(a: int16x8_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19893,6 +22815,8 @@ pub unsafe fn vreinterpretq_s8_u16(a: uint16x8_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19904,6 +22828,8 @@ pub unsafe fn vreinterpretq_s8_p16(a: poly16x8_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19915,6 +22841,8 @@ pub unsafe fn vreinterpretq_s16_s32(a: int32x4_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19926,6 +22854,8 @@ pub unsafe fn vreinterpretq_s16_u32(a: uint32x4_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19937,6 +22867,8 @@ pub unsafe fn vreinterpretq_s32_s64(a: int64x2_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19948,6 +22880,8 @@ pub unsafe fn vreinterpretq_s32_u64(a: uint64x2_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19959,6 +22893,8 @@ pub unsafe fn vreinterpret_u8_p16(a: poly16x4_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19970,6 +22906,8 @@ pub unsafe fn vreinterpret_u8_s16(a: int16x4_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19981,6 +22919,8 @@ pub unsafe fn vreinterpret_u8_u16(a: uint16x4_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -19992,6 +22932,8 @@ pub unsafe fn vreinterpret_u16_s32(a: int32x2_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20003,6 +22945,8 @@ pub unsafe fn vreinterpret_u16_u32(a: uint32x2_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20014,6 +22958,8 @@ pub unsafe fn vreinterpret_u32_s64(a: int64x1_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20025,6 +22971,8 @@ pub unsafe fn vreinterpret_u32_u64(a: uint64x1_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20036,6 +22984,8 @@ pub unsafe fn vreinterpretq_u8_p16(a: poly16x8_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20047,6 +22997,8 @@ pub unsafe fn vreinterpretq_u8_s16(a: int16x8_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20058,6 +23010,8 @@ pub unsafe fn vreinterpretq_u8_u16(a: uint16x8_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20069,6 +23023,8 @@ pub unsafe fn vreinterpretq_u16_s32(a: int32x4_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20080,6 +23036,8 @@ pub unsafe fn vreinterpretq_u16_u32(a: uint32x4_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20091,6 +23049,8 @@ pub unsafe fn vreinterpretq_u32_s64(a: int64x2_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20102,6 +23062,8 @@ pub unsafe fn vreinterpretq_u32_u64(a: uint64x2_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20113,6 +23075,8 @@ pub unsafe fn vreinterpret_p8_p16(a: poly16x4_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20124,6 +23088,8 @@ pub unsafe fn vreinterpret_p8_s16(a: int16x4_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20135,6 +23101,8 @@ pub unsafe fn vreinterpret_p8_u16(a: uint16x4_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20146,6 +23114,8 @@ pub unsafe fn vreinterpret_p16_s32(a: int32x2_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20157,6 +23127,8 @@ pub unsafe fn vreinterpret_p16_u32(a: uint32x2_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20168,6 +23140,8 @@ pub unsafe fn vreinterpretq_p8_p16(a: poly16x8_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20179,6 +23153,8 @@ pub unsafe fn vreinterpretq_p8_s16(a: int16x8_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20190,6 +23166,8 @@ pub unsafe fn vreinterpretq_p8_u16(a: uint16x8_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20201,6 +23179,8 @@ pub unsafe fn vreinterpretq_p16_s32(a: int32x4_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20212,6 +23192,8 @@ pub unsafe fn vreinterpretq_p16_u32(a: uint32x4_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20223,6 +23205,8 @@ pub unsafe fn vreinterpret_s32_p64(a: poly64x1_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20234,6 +23218,8 @@ pub unsafe fn vreinterpret_u32_p64(a: poly64x1_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20245,6 +23231,8 @@ pub unsafe fn vreinterpretq_s32_p64(a: poly64x2_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20256,6 +23244,8 @@ pub unsafe fn vreinterpretq_u32_p64(a: poly64x2_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20267,6 +23257,8 @@ pub unsafe fn vreinterpretq_s64_p128(a: p128) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20278,6 +23270,8 @@ pub unsafe fn vreinterpretq_u64_p128(a: p128) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20289,6 +23283,8 @@ pub unsafe fn vreinterpretq_p64_p128(a: p128) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20300,6 +23296,8 @@ pub unsafe fn vreinterpret_s16_p8(a: poly8x8_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20311,6 +23309,8 @@ pub unsafe fn vreinterpret_s16_s8(a: int8x8_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20322,6 +23322,8 @@ pub unsafe fn vreinterpret_s16_u8(a: uint8x8_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20333,6 +23335,8 @@ pub unsafe fn vreinterpret_s32_p16(a: poly16x4_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20344,6 +23348,8 @@ pub unsafe fn vreinterpret_s32_s16(a: int16x4_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20355,6 +23361,8 @@ pub unsafe fn vreinterpret_s32_u16(a: uint16x4_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20366,6 +23374,8 @@ pub unsafe fn vreinterpret_s64_s32(a: int32x2_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20377,6 +23387,8 @@ pub unsafe fn vreinterpret_s64_u32(a: uint32x2_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20388,6 +23400,8 @@ pub unsafe fn vreinterpretq_s16_p8(a: poly8x16_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20399,6 +23413,8 @@ pub unsafe fn vreinterpretq_s16_s8(a: int8x16_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20410,6 +23426,8 @@ pub unsafe fn vreinterpretq_s16_u8(a: uint8x16_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20421,6 +23439,8 @@ pub unsafe fn vreinterpretq_s32_p16(a: poly16x8_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20432,6 +23452,8 @@ pub unsafe fn vreinterpretq_s32_s16(a: int16x8_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20443,6 +23465,8 @@ pub unsafe fn vreinterpretq_s32_u16(a: uint16x8_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20454,6 +23478,8 @@ pub unsafe fn vreinterpretq_s64_s32(a: int32x4_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20465,6 +23491,8 @@ pub unsafe fn vreinterpretq_s64_u32(a: uint32x4_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20476,6 +23504,8 @@ pub unsafe fn vreinterpret_u16_p8(a: poly8x8_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20487,6 +23517,8 @@ pub unsafe fn vreinterpret_u16_s8(a: int8x8_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20498,6 +23530,8 @@ pub unsafe fn vreinterpret_u16_u8(a: uint8x8_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20509,6 +23543,8 @@ pub unsafe fn vreinterpret_u32_p16(a: poly16x4_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20520,6 +23556,8 @@ pub unsafe fn vreinterpret_u32_s16(a: int16x4_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20531,6 +23569,8 @@ pub unsafe fn vreinterpret_u32_u16(a: uint16x4_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20542,6 +23582,8 @@ pub unsafe fn vreinterpret_u64_s32(a: int32x2_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20553,6 +23595,8 @@ pub unsafe fn vreinterpret_u64_u32(a: uint32x2_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20564,6 +23608,8 @@ pub unsafe fn vreinterpretq_u16_p8(a: poly8x16_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20575,6 +23621,8 @@ pub unsafe fn vreinterpretq_u16_s8(a: int8x16_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20586,6 +23634,8 @@ pub unsafe fn vreinterpretq_u16_u8(a: uint8x16_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20597,6 +23647,8 @@ pub unsafe fn vreinterpretq_u32_p16(a: poly16x8_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20608,6 +23660,8 @@ pub unsafe fn vreinterpretq_u32_s16(a: int16x8_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20619,6 +23673,8 @@ pub unsafe fn vreinterpretq_u32_u16(a: uint16x8_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20630,6 +23686,8 @@ pub unsafe fn vreinterpretq_u64_s32(a: int32x4_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20641,6 +23699,8 @@ pub unsafe fn vreinterpretq_u64_u32(a: uint32x4_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20652,6 +23712,8 @@ pub unsafe fn vreinterpret_p16_p8(a: poly8x8_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20663,6 +23725,8 @@ pub unsafe fn vreinterpret_p16_s8(a: int8x8_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20674,6 +23738,8 @@ pub unsafe fn vreinterpret_p16_u8(a: uint8x8_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20685,6 +23751,8 @@ pub unsafe fn vreinterpretq_p16_p8(a: poly8x16_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20696,6 +23764,8 @@ pub unsafe fn vreinterpretq_p16_s8(a: int8x16_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20707,6 +23777,8 @@ pub unsafe fn vreinterpretq_p16_u8(a: uint8x16_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s32)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20718,6 +23790,8 @@ pub unsafe fn vreinterpret_p64_s32(a: int32x2_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u32)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20729,6 +23803,8 @@ pub unsafe fn vreinterpret_p64_u32(a: uint32x2_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s32)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20740,6 +23816,8 @@ pub unsafe fn vreinterpretq_p64_s32(a: int32x4_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u32)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20751,6 +23829,8 @@ pub unsafe fn vreinterpretq_p64_u32(a: uint32x4_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20762,6 +23842,8 @@ pub unsafe fn vreinterpretq_p128_s64(a: int64x2_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20773,6 +23855,8 @@ pub unsafe fn vreinterpretq_p128_u64(a: uint64x2_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -20784,6 +23868,8 @@ pub unsafe fn vreinterpretq_p128_p64(a: poly64x2_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20795,6 +23881,8 @@ pub unsafe fn vreinterpret_s8_s32(a: int32x2_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20806,6 +23894,8 @@ pub unsafe fn vreinterpret_s8_u32(a: uint32x2_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20817,6 +23907,8 @@ pub unsafe fn vreinterpret_s16_s64(a: int64x1_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20828,6 +23920,8 @@ pub unsafe fn vreinterpret_s16_u64(a: uint64x1_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20839,6 +23933,8 @@ pub unsafe fn vreinterpretq_s8_s32(a: int32x4_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20850,6 +23946,8 @@ pub unsafe fn vreinterpretq_s8_u32(a: uint32x4_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20861,6 +23959,8 @@ pub unsafe fn vreinterpretq_s16_s64(a: int64x2_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20872,6 +23972,8 @@ pub unsafe fn vreinterpretq_s16_u64(a: uint64x2_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20883,6 +23985,8 @@ pub unsafe fn vreinterpret_u8_s32(a: int32x2_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20894,6 +23998,8 @@ pub unsafe fn vreinterpret_u8_u32(a: uint32x2_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20905,6 +24011,8 @@ pub unsafe fn vreinterpret_u16_s64(a: int64x1_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20916,6 +24024,8 @@ pub unsafe fn vreinterpret_u16_u64(a: uint64x1_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20927,6 +24037,8 @@ pub unsafe fn vreinterpretq_u8_s32(a: int32x4_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20938,6 +24050,8 @@ pub unsafe fn vreinterpretq_u8_u32(a: uint32x4_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20949,6 +24063,8 @@ pub unsafe fn vreinterpretq_u16_s64(a: int64x2_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20960,6 +24076,8 @@ pub unsafe fn vreinterpretq_u16_u64(a: uint64x2_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20971,6 +24089,8 @@ pub unsafe fn vreinterpret_p8_s32(a: int32x2_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20982,6 +24102,8 @@ pub unsafe fn vreinterpret_p8_u32(a: uint32x2_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -20993,6 +24115,8 @@ pub unsafe fn vreinterpret_p16_s64(a: int64x1_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21004,6 +24128,8 @@ pub unsafe fn vreinterpret_p16_u64(a: uint64x1_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21015,6 +24141,8 @@ pub unsafe fn vreinterpretq_p8_s32(a: int32x4_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21026,6 +24154,8 @@ pub unsafe fn vreinterpretq_p8_u32(a: uint32x4_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21037,6 +24167,8 @@ pub unsafe fn vreinterpretq_p16_s64(a: int64x2_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21048,6 +24180,8 @@ pub unsafe fn vreinterpretq_p16_u64(a: uint64x2_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21059,6 +24193,8 @@ pub unsafe fn vreinterpret_s16_p64(a: poly64x1_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21070,6 +24206,8 @@ pub unsafe fn vreinterpret_u16_p64(a: poly64x1_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21081,6 +24219,8 @@ pub unsafe fn vreinterpret_p16_p64(a: poly64x1_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21092,6 +24232,8 @@ pub unsafe fn vreinterpretq_s16_p64(a: poly64x2_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21103,6 +24245,8 @@ pub unsafe fn vreinterpretq_u16_p64(a: poly64x2_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21114,6 +24258,8 @@ pub unsafe fn vreinterpretq_p16_p64(a: poly64x2_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21125,6 +24271,8 @@ pub unsafe fn vreinterpretq_s32_p128(a: p128) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21136,6 +24284,8 @@ pub unsafe fn vreinterpretq_u32_p128(a: p128) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21147,6 +24297,8 @@ pub unsafe fn vreinterpret_s32_p8(a: poly8x8_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21158,6 +24310,8 @@ pub unsafe fn vreinterpret_s32_s8(a: int8x8_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21169,6 +24323,8 @@ pub unsafe fn vreinterpret_s32_u8(a: uint8x8_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21180,6 +24336,8 @@ pub unsafe fn vreinterpret_s64_p16(a: poly16x4_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21191,6 +24349,8 @@ pub unsafe fn vreinterpret_s64_s16(a: int16x4_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21202,6 +24362,8 @@ pub unsafe fn vreinterpret_s64_u16(a: uint16x4_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21213,6 +24375,8 @@ pub unsafe fn vreinterpretq_s32_p8(a: poly8x16_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21224,6 +24388,8 @@ pub unsafe fn vreinterpretq_s32_s8(a: int8x16_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21235,6 +24401,8 @@ pub unsafe fn vreinterpretq_s32_u8(a: uint8x16_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21246,6 +24414,8 @@ pub unsafe fn vreinterpretq_s64_p16(a: poly16x8_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21257,6 +24427,8 @@ pub unsafe fn vreinterpretq_s64_s16(a: int16x8_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21268,6 +24440,8 @@ pub unsafe fn vreinterpretq_s64_u16(a: uint16x8_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21279,6 +24453,8 @@ pub unsafe fn vreinterpret_u32_p8(a: poly8x8_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21290,6 +24466,8 @@ pub unsafe fn vreinterpret_u32_s8(a: int8x8_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21301,6 +24479,8 @@ pub unsafe fn vreinterpret_u32_u8(a: uint8x8_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21312,6 +24492,8 @@ pub unsafe fn vreinterpret_u64_p16(a: poly16x4_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21323,6 +24505,8 @@ pub unsafe fn vreinterpret_u64_s16(a: int16x4_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21334,6 +24518,8 @@ pub unsafe fn vreinterpret_u64_u16(a: uint16x4_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21345,6 +24531,8 @@ pub unsafe fn vreinterpretq_u32_p8(a: poly8x16_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21356,6 +24544,8 @@ pub unsafe fn vreinterpretq_u32_s8(a: int8x16_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21367,6 +24557,8 @@ pub unsafe fn vreinterpretq_u32_u8(a: uint8x16_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21378,6 +24570,8 @@ pub unsafe fn vreinterpretq_u64_p16(a: poly16x8_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21389,6 +24583,8 @@ pub unsafe fn vreinterpretq_u64_s16(a: int16x8_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21400,6 +24596,8 @@ pub unsafe fn vreinterpretq_u64_u16(a: uint16x8_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_p16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21411,6 +24609,8 @@ pub unsafe fn vreinterpret_p64_p16(a: poly16x4_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21422,6 +24622,8 @@ pub unsafe fn vreinterpret_p64_s16(a: int16x4_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21433,6 +24635,8 @@ pub unsafe fn vreinterpret_p64_u16(a: uint16x4_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21444,6 +24648,8 @@ pub unsafe fn vreinterpretq_p64_p16(a: poly16x8_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21455,6 +24661,8 @@ pub unsafe fn vreinterpretq_p64_s16(a: int16x8_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21466,6 +24674,8 @@ pub unsafe fn vreinterpretq_p64_u16(a: uint16x8_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s32)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21477,6 +24687,8 @@ pub unsafe fn vreinterpretq_p128_s32(a: int32x4_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u32)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21488,6 +24700,8 @@ pub unsafe fn vreinterpretq_p128_u32(a: uint32x4_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21499,6 +24713,8 @@ pub unsafe fn vreinterpret_s8_s64(a: int64x1_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21510,6 +24726,8 @@ pub unsafe fn vreinterpret_s8_u64(a: uint64x1_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21521,6 +24739,8 @@ pub unsafe fn vreinterpret_u8_s64(a: int64x1_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21532,6 +24752,8 @@ pub unsafe fn vreinterpret_u8_u64(a: uint64x1_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21543,6 +24765,8 @@ pub unsafe fn vreinterpret_p8_s64(a: int64x1_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21554,6 +24778,8 @@ pub unsafe fn vreinterpret_p8_u64(a: uint64x1_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21565,6 +24791,8 @@ pub unsafe fn vreinterpretq_s8_s64(a: int64x2_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21576,6 +24804,8 @@ pub unsafe fn vreinterpretq_s8_u64(a: uint64x2_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21587,6 +24817,8 @@ pub unsafe fn vreinterpretq_u8_s64(a: int64x2_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21598,6 +24830,8 @@ pub unsafe fn vreinterpretq_u8_u64(a: uint64x2_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21609,6 +24843,8 @@ pub unsafe fn vreinterpretq_p8_s64(a: int64x2_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21620,6 +24856,8 @@ pub unsafe fn vreinterpretq_p8_u64(a: uint64x2_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21631,6 +24869,8 @@ pub unsafe fn vreinterpret_s8_p64(a: poly64x1_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21642,6 +24882,8 @@ pub unsafe fn vreinterpret_u8_p64(a: poly64x1_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21653,6 +24895,8 @@ pub unsafe fn vreinterpret_p8_p64(a: poly64x1_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21664,6 +24908,8 @@ pub unsafe fn vreinterpretq_s8_p64(a: poly64x2_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21675,6 +24921,8 @@ pub unsafe fn vreinterpretq_u8_p64(a: poly64x2_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21686,6 +24934,8 @@ pub unsafe fn vreinterpretq_p8_p64(a: poly64x2_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21697,6 +24947,8 @@ pub unsafe fn vreinterpretq_s16_p128(a: p128) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21708,6 +24960,8 @@ pub unsafe fn vreinterpretq_u16_p128(a: p128) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21719,6 +24973,8 @@ pub unsafe fn vreinterpretq_p16_p128(a: p128) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21730,6 +24986,8 @@ pub unsafe fn vreinterpret_s64_p8(a: poly8x8_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21741,6 +24999,8 @@ pub unsafe fn vreinterpret_s64_s8(a: int8x8_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21752,6 +25012,8 @@ pub unsafe fn vreinterpret_s64_u8(a: uint8x8_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21763,6 +25025,8 @@ pub unsafe fn vreinterpret_u64_p8(a: poly8x8_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21774,6 +25038,8 @@ pub unsafe fn vreinterpret_u64_s8(a: int8x8_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21785,6 +25051,8 @@ pub unsafe fn vreinterpret_u64_u8(a: uint8x8_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21796,6 +25064,8 @@ pub unsafe fn vreinterpretq_s64_p8(a: poly8x16_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21807,6 +25077,8 @@ pub unsafe fn vreinterpretq_s64_s8(a: int8x16_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21818,6 +25090,8 @@ pub unsafe fn vreinterpretq_s64_u8(a: uint8x16_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21829,6 +25103,8 @@ pub unsafe fn vreinterpretq_u64_p8(a: poly8x16_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21840,6 +25116,8 @@ pub unsafe fn vreinterpretq_u64_s8(a: int8x16_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -21851,6 +25129,8 @@ pub unsafe fn vreinterpretq_u64_u8(a: uint8x16_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_p8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21862,6 +25142,8 @@ pub unsafe fn vreinterpret_p64_p8(a: poly8x8_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21873,6 +25155,8 @@ pub unsafe fn vreinterpret_p64_s8(a: int8x8_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21884,6 +25168,8 @@ pub unsafe fn vreinterpret_p64_u8(a: uint8x8_t) -> poly64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21895,6 +25181,8 @@ pub unsafe fn vreinterpretq_p64_p8(a: poly8x16_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21906,6 +25194,8 @@ pub unsafe fn vreinterpretq_p64_s8(a: int8x16_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21917,6 +25207,8 @@ pub unsafe fn vreinterpretq_p64_u8(a: uint8x16_t) -> poly64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21928,6 +25220,8 @@ pub unsafe fn vreinterpretq_p128_s16(a: int16x8_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21939,6 +25233,8 @@ pub unsafe fn vreinterpretq_p128_u16(a: uint16x8_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p16)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21950,6 +25246,8 @@ pub unsafe fn vreinterpretq_p128_p16(a: poly16x8_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21961,6 +25259,8 @@ pub unsafe fn vreinterpretq_p128_s8(a: int8x16_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21972,6 +25272,8 @@ pub unsafe fn vreinterpretq_p128_u8(a: uint8x16_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p8)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21983,6 +25285,8 @@ pub unsafe fn vreinterpretq_p128_p8(a: poly8x16_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -21994,6 +25298,8 @@ pub unsafe fn vreinterpretq_s8_p128(a: p128) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -22005,6 +25311,8 @@ pub unsafe fn vreinterpretq_u8_p128(a: p128) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p128)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -22016,6 +25324,8 @@ pub unsafe fn vreinterpretq_p8_p128(a: p128) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22027,6 +25337,8 @@ pub unsafe fn vreinterpret_s8_f32(a: float32x2_t) -> int8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22038,6 +25350,8 @@ pub unsafe fn vreinterpret_s16_f32(a: float32x2_t) -> int16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22049,6 +25363,8 @@ pub unsafe fn vreinterpret_s32_f32(a: float32x2_t) -> int32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22060,6 +25376,8 @@ pub unsafe fn vreinterpret_s64_f32(a: float32x2_t) -> int64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22071,6 +25389,8 @@ pub unsafe fn vreinterpretq_s8_f32(a: float32x4_t) -> int8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22082,6 +25402,8 @@ pub unsafe fn vreinterpretq_s16_f32(a: float32x4_t) -> int16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22093,6 +25415,8 @@ pub unsafe fn vreinterpretq_s32_f32(a: float32x4_t) -> int32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22104,6 +25428,8 @@ pub unsafe fn vreinterpretq_s64_f32(a: float32x4_t) -> int64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22115,6 +25441,8 @@ pub unsafe fn vreinterpret_u8_f32(a: float32x2_t) -> uint8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22126,6 +25454,8 @@ pub unsafe fn vreinterpret_u16_f32(a: float32x2_t) -> uint16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22137,6 +25467,8 @@ pub unsafe fn vreinterpret_u32_f32(a: float32x2_t) -> uint32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22148,6 +25480,8 @@ pub unsafe fn vreinterpret_u64_f32(a: float32x2_t) -> uint64x1_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22159,6 +25493,8 @@ pub unsafe fn vreinterpretq_u8_f32(a: float32x4_t) -> uint8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22170,6 +25506,8 @@ pub unsafe fn vreinterpretq_u16_f32(a: float32x4_t) -> uint16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22181,6 +25519,8 @@ pub unsafe fn vreinterpretq_u32_f32(a: float32x4_t) -> uint32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22192,6 +25532,8 @@ pub unsafe fn vreinterpretq_u64_f32(a: float32x4_t) -> uint64x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22203,6 +25545,8 @@ pub unsafe fn vreinterpret_p8_f32(a: float32x2_t) -> poly8x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22214,6 +25558,8 @@ pub unsafe fn vreinterpret_p16_f32(a: float32x2_t) -> poly16x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22225,6 +25571,8 @@ pub unsafe fn vreinterpretq_p8_f32(a: float32x4_t) -> poly8x16_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22236,6 +25584,8 @@ pub unsafe fn vreinterpretq_p16_f32(a: float32x4_t) -> poly16x8_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22247,6 +25597,8 @@ pub unsafe fn vreinterpretq_p128_f32(a: float32x4_t) -> p128 {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22258,6 +25610,8 @@ pub unsafe fn vreinterpret_f32_s8(a: int8x8_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22269,6 +25623,8 @@ pub unsafe fn vreinterpret_f32_s16(a: int16x4_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22280,6 +25636,8 @@ pub unsafe fn vreinterpret_f32_s32(a: int32x2_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22291,6 +25649,8 @@ pub unsafe fn vreinterpret_f32_s64(a: int64x1_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22302,6 +25662,8 @@ pub unsafe fn vreinterpretq_f32_s8(a: int8x16_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22313,6 +25675,8 @@ pub unsafe fn vreinterpretq_f32_s16(a: int16x8_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22324,6 +25688,8 @@ pub unsafe fn vreinterpretq_f32_s32(a: int32x4_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22335,6 +25701,8 @@ pub unsafe fn vreinterpretq_f32_s64(a: int64x2_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22346,6 +25714,8 @@ pub unsafe fn vreinterpret_f32_u8(a: uint8x8_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22357,6 +25727,8 @@ pub unsafe fn vreinterpret_f32_u16(a: uint16x4_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22368,6 +25740,8 @@ pub unsafe fn vreinterpret_f32_u32(a: uint32x2_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22379,6 +25753,8 @@ pub unsafe fn vreinterpret_f32_u64(a: uint64x1_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22390,6 +25766,8 @@ pub unsafe fn vreinterpretq_f32_u8(a: uint8x16_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22401,6 +25779,8 @@ pub unsafe fn vreinterpretq_f32_u16(a: uint16x8_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22412,6 +25792,8 @@ pub unsafe fn vreinterpretq_f32_u32(a: uint32x4_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22423,6 +25805,8 @@ pub unsafe fn vreinterpretq_f32_u64(a: uint64x2_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22434,6 +25818,8 @@ pub unsafe fn vreinterpret_f32_p8(a: poly8x8_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22445,6 +25831,8 @@ pub unsafe fn vreinterpret_f32_p16(a: poly16x4_t) -> float32x2_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22456,6 +25844,8 @@ pub unsafe fn vreinterpretq_f32_p8(a: poly8x16_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22467,6 +25857,8 @@ pub unsafe fn vreinterpretq_f32_p16(a: poly16x8_t) -> float32x4_t {
}
/// Vector reinterpret cast operation
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p128)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22478,6 +25870,8 @@ pub unsafe fn vreinterpretq_f32_p128(a: p128) -> float32x4_t {
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22495,6 +25889,8 @@ vrshl_s8_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22512,6 +25908,8 @@ vrshlq_s8_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22529,6 +25927,8 @@ vrshl_s16_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22546,6 +25946,8 @@ vrshlq_s16_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22563,6 +25965,8 @@ vrshl_s32_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22580,6 +25984,8 @@ vrshlq_s32_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22597,6 +26003,8 @@ vrshl_s64_(a, b)
}
/// Signed rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22614,6 +26022,8 @@ vrshlq_s64_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22631,6 +26041,8 @@ vrshl_u8_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22648,6 +26060,8 @@ vrshlq_u8_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22665,6 +26079,8 @@ vrshl_u16_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22682,6 +26098,8 @@ vrshlq_u16_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22699,6 +26117,8 @@ vrshl_u32_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22716,6 +26136,8 @@ vrshlq_u32_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22733,6 +26155,8 @@ vrshl_u64_(a, b)
}
/// Unsigned rounding shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22750,6 +26174,8 @@ vrshlq_u64_(a, b)
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22763,6 +26189,8 @@ pub unsafe fn vrshr_n_s8<const N: i32>(a: int8x8_t) -> int8x8_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22776,6 +26204,8 @@ pub unsafe fn vrshrq_n_s8<const N: i32>(a: int8x16_t) -> int8x16_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22789,6 +26219,8 @@ pub unsafe fn vrshr_n_s16<const N: i32>(a: int16x4_t) -> int16x4_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22802,6 +26234,8 @@ pub unsafe fn vrshrq_n_s16<const N: i32>(a: int16x8_t) -> int16x8_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22815,6 +26249,8 @@ pub unsafe fn vrshr_n_s32<const N: i32>(a: int32x2_t) -> int32x2_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22828,6 +26264,8 @@ pub unsafe fn vrshrq_n_s32<const N: i32>(a: int32x4_t) -> int32x4_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22841,6 +26279,8 @@ pub unsafe fn vrshr_n_s64<const N: i32>(a: int64x1_t) -> int64x1_t {
}
/// Signed rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22854,6 +26294,8 @@ pub unsafe fn vrshrq_n_s64<const N: i32>(a: int64x2_t) -> int64x2_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22867,6 +26309,8 @@ pub unsafe fn vrshr_n_u8<const N: i32>(a: uint8x8_t) -> uint8x8_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22880,6 +26324,8 @@ pub unsafe fn vrshrq_n_u8<const N: i32>(a: uint8x16_t) -> uint8x16_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22893,6 +26339,8 @@ pub unsafe fn vrshr_n_u16<const N: i32>(a: uint16x4_t) -> uint16x4_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22906,6 +26354,8 @@ pub unsafe fn vrshrq_n_u16<const N: i32>(a: uint16x8_t) -> uint16x8_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22919,6 +26369,8 @@ pub unsafe fn vrshr_n_u32<const N: i32>(a: uint32x2_t) -> uint32x2_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22932,6 +26384,8 @@ pub unsafe fn vrshrq_n_u32<const N: i32>(a: uint32x4_t) -> uint32x4_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22945,6 +26399,8 @@ pub unsafe fn vrshr_n_u64<const N: i32>(a: uint64x1_t) -> uint64x1_t {
}
/// Unsigned rounding shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -22958,6 +26414,8 @@ pub unsafe fn vrshrq_n_u64<const N: i32>(a: uint64x2_t) -> uint64x2_t {
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s16)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -22974,6 +26432,8 @@ vrshrn_n_s16_(a, int16x8_t(-N as i16, -N as i16, -N as i16, -N as i16, -N as i16
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s16)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -22991,6 +26451,8 @@ vrshrn_n_s16_(a, N)
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s32)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -23007,6 +26469,8 @@ vrshrn_n_s32_(a, int32x4_t(-N as i32, -N as i32, -N as i32, -N as i32))
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s32)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -23024,6 +26488,8 @@ vrshrn_n_s32_(a, N)
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s64)
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
@@ -23040,6 +26506,8 @@ vrshrn_n_s64_(a, int64x2_t(-N as i64, -N as i64))
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s64)
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
@@ -23057,6 +26525,8 @@ vrshrn_n_s64_(a, N)
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23070,6 +26540,8 @@ pub unsafe fn vrshrn_n_u16<const N: i32>(a: uint16x8_t) -> uint8x8_t {
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23083,6 +26555,8 @@ pub unsafe fn vrshrn_n_u32<const N: i32>(a: uint32x4_t) -> uint16x4_t {
}
/// Rounding shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23096,6 +26570,8 @@ pub unsafe fn vrshrn_n_u64<const N: i32>(a: uint64x2_t) -> uint32x2_t {
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23109,6 +26585,8 @@ pub unsafe fn vrsra_n_s8<const N: i32>(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23122,6 +26600,8 @@ pub unsafe fn vrsraq_n_s8<const N: i32>(a: int8x16_t, b: int8x16_t) -> int8x16_t
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23135,6 +26615,8 @@ pub unsafe fn vrsra_n_s16<const N: i32>(a: int16x4_t, b: int16x4_t) -> int16x4_t
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23148,6 +26630,8 @@ pub unsafe fn vrsraq_n_s16<const N: i32>(a: int16x8_t, b: int16x8_t) -> int16x8_
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23161,6 +26645,8 @@ pub unsafe fn vrsra_n_s32<const N: i32>(a: int32x2_t, b: int32x2_t) -> int32x2_t
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23174,6 +26660,8 @@ pub unsafe fn vrsraq_n_s32<const N: i32>(a: int32x4_t, b: int32x4_t) -> int32x4_
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23187,6 +26675,8 @@ pub unsafe fn vrsra_n_s64<const N: i32>(a: int64x1_t, b: int64x1_t) -> int64x1_t
}
/// Signed rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23200,6 +26690,8 @@ pub unsafe fn vrsraq_n_s64<const N: i32>(a: int64x2_t, b: int64x2_t) -> int64x2_
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23213,6 +26705,8 @@ pub unsafe fn vrsra_n_u8<const N: i32>(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23226,6 +26720,8 @@ pub unsafe fn vrsraq_n_u8<const N: i32>(a: uint8x16_t, b: uint8x16_t) -> uint8x1
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23239,6 +26735,8 @@ pub unsafe fn vrsra_n_u16<const N: i32>(a: uint16x4_t, b: uint16x4_t) -> uint16x
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23252,6 +26750,8 @@ pub unsafe fn vrsraq_n_u16<const N: i32>(a: uint16x8_t, b: uint16x8_t) -> uint16
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23265,6 +26765,8 @@ pub unsafe fn vrsra_n_u32<const N: i32>(a: uint32x2_t, b: uint32x2_t) -> uint32x
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23278,6 +26780,8 @@ pub unsafe fn vrsraq_n_u32<const N: i32>(a: uint32x4_t, b: uint32x4_t) -> uint32
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23291,6 +26795,8 @@ pub unsafe fn vrsra_n_u64<const N: i32>(a: uint64x1_t, b: uint64x1_t) -> uint64x
}
/// Unsigned rounding shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23304,6 +26810,8 @@ pub unsafe fn vrsraq_n_u64<const N: i32>(a: uint64x2_t, b: uint64x2_t) -> uint64
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23321,6 +26829,8 @@ vrsubhn_s16_(a, b)
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23338,6 +26848,8 @@ vrsubhn_s32_(a, b)
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23355,6 +26867,8 @@ vrsubhn_s64_(a, b)
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23366,6 +26880,8 @@ pub unsafe fn vrsubhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23377,6 +26893,8 @@ pub unsafe fn vrsubhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
}
/// Rounding subtract returning high narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23388,6 +26906,8 @@ pub unsafe fn vrsubhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23401,6 +26921,8 @@ pub unsafe fn vset_lane_s8<const LANE: i32>(a: i8, b: int8x8_t) -> int8x8_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23414,6 +26936,8 @@ pub unsafe fn vset_lane_s16<const LANE: i32>(a: i16, b: int16x4_t) -> int16x4_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23427,6 +26951,8 @@ pub unsafe fn vset_lane_s32<const LANE: i32>(a: i32, b: int32x2_t) -> int32x2_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23440,6 +26966,8 @@ pub unsafe fn vset_lane_s64<const LANE: i32>(a: i64, b: int64x1_t) -> int64x1_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23453,6 +26981,8 @@ pub unsafe fn vset_lane_u8<const LANE: i32>(a: u8, b: uint8x8_t) -> uint8x8_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23466,6 +26996,8 @@ pub unsafe fn vset_lane_u16<const LANE: i32>(a: u16, b: uint16x4_t) -> uint16x4_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23479,6 +27011,8 @@ pub unsafe fn vset_lane_u32<const LANE: i32>(a: u32, b: uint32x2_t) -> uint32x2_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23492,6 +27026,8 @@ pub unsafe fn vset_lane_u64<const LANE: i32>(a: u64, b: uint64x1_t) -> uint64x1_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23505,6 +27041,8 @@ pub unsafe fn vset_lane_p8<const LANE: i32>(a: p8, b: poly8x8_t) -> poly8x8_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23518,6 +27056,8 @@ pub unsafe fn vset_lane_p16<const LANE: i32>(a: p16, b: poly16x4_t) -> poly16x4_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -23531,6 +27071,8 @@ pub unsafe fn vset_lane_p64<const LANE: i32>(a: p64, b: poly64x1_t) -> poly64x1_
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23544,6 +27086,8 @@ pub unsafe fn vsetq_lane_s8<const LANE: i32>(a: i8, b: int8x16_t) -> int8x16_t {
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23557,6 +27101,8 @@ pub unsafe fn vsetq_lane_s16<const LANE: i32>(a: i16, b: int16x8_t) -> int16x8_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23570,6 +27116,8 @@ pub unsafe fn vsetq_lane_s32<const LANE: i32>(a: i32, b: int32x4_t) -> int32x4_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23583,6 +27131,8 @@ pub unsafe fn vsetq_lane_s64<const LANE: i32>(a: i64, b: int64x2_t) -> int64x2_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23596,6 +27146,8 @@ pub unsafe fn vsetq_lane_u8<const LANE: i32>(a: u8, b: uint8x16_t) -> uint8x16_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23609,6 +27161,8 @@ pub unsafe fn vsetq_lane_u16<const LANE: i32>(a: u16, b: uint16x8_t) -> uint16x8
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23622,6 +27176,8 @@ pub unsafe fn vsetq_lane_u32<const LANE: i32>(a: u32, b: uint32x4_t) -> uint32x4
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23635,6 +27191,8 @@ pub unsafe fn vsetq_lane_u64<const LANE: i32>(a: u64, b: uint64x2_t) -> uint64x2
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23648,6 +27206,8 @@ pub unsafe fn vsetq_lane_p8<const LANE: i32>(a: p8, b: poly8x16_t) -> poly8x16_t
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23661,6 +27221,8 @@ pub unsafe fn vsetq_lane_p16<const LANE: i32>(a: p16, b: poly16x8_t) -> poly16x8
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "aes,v8"))]
@@ -23674,6 +27236,8 @@ pub unsafe fn vsetq_lane_p64<const LANE: i32>(a: p64, b: poly64x2_t) -> poly64x2
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23687,6 +27251,8 @@ pub unsafe fn vset_lane_f32<const LANE: i32>(a: f32, b: float32x2_t) -> float32x
}
/// Insert vector element from another vector element
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23700,6 +27266,8 @@ pub unsafe fn vsetq_lane_f32<const LANE: i32>(a: f32, b: float32x4_t) -> float32
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23717,6 +27285,8 @@ vshl_s8_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23734,6 +27304,8 @@ vshlq_s8_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23751,6 +27323,8 @@ vshl_s16_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23768,6 +27342,8 @@ vshlq_s16_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23785,6 +27361,8 @@ vshl_s32_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23802,6 +27380,8 @@ vshlq_s32_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23819,6 +27399,8 @@ vshl_s64_(a, b)
}
/// Signed Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23836,6 +27418,8 @@ vshlq_s64_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23853,6 +27437,8 @@ vshl_u8_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23870,6 +27456,8 @@ vshlq_u8_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23887,6 +27475,8 @@ vshl_u16_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23904,6 +27494,8 @@ vshlq_u16_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23921,6 +27513,8 @@ vshl_u32_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23938,6 +27532,8 @@ vshlq_u32_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23955,6 +27551,8 @@ vshl_u64_(a, b)
}
/// Unsigned Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23972,6 +27570,8 @@ vshlq_u64_(a, b)
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23985,6 +27585,8 @@ pub unsafe fn vshl_n_s8<const N: i32>(a: int8x8_t) -> int8x8_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -23998,6 +27600,8 @@ pub unsafe fn vshlq_n_s8<const N: i32>(a: int8x16_t) -> int8x16_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24011,6 +27615,8 @@ pub unsafe fn vshl_n_s16<const N: i32>(a: int16x4_t) -> int16x4_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24024,6 +27630,8 @@ pub unsafe fn vshlq_n_s16<const N: i32>(a: int16x8_t) -> int16x8_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24037,6 +27645,8 @@ pub unsafe fn vshl_n_s32<const N: i32>(a: int32x2_t) -> int32x2_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24050,6 +27660,8 @@ pub unsafe fn vshlq_n_s32<const N: i32>(a: int32x4_t) -> int32x4_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24063,6 +27675,8 @@ pub unsafe fn vshl_n_u8<const N: i32>(a: uint8x8_t) -> uint8x8_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24076,6 +27690,8 @@ pub unsafe fn vshlq_n_u8<const N: i32>(a: uint8x16_t) -> uint8x16_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24089,6 +27705,8 @@ pub unsafe fn vshl_n_u16<const N: i32>(a: uint16x4_t) -> uint16x4_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24102,6 +27720,8 @@ pub unsafe fn vshlq_n_u16<const N: i32>(a: uint16x8_t) -> uint16x8_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24115,6 +27735,8 @@ pub unsafe fn vshl_n_u32<const N: i32>(a: uint32x2_t) -> uint32x2_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24128,6 +27750,8 @@ pub unsafe fn vshlq_n_u32<const N: i32>(a: uint32x4_t) -> uint32x4_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24141,6 +27765,8 @@ pub unsafe fn vshl_n_s64<const N: i32>(a: int64x1_t) -> int64x1_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24154,6 +27780,8 @@ pub unsafe fn vshlq_n_s64<const N: i32>(a: int64x2_t) -> int64x2_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24167,6 +27795,8 @@ pub unsafe fn vshl_n_u64<const N: i32>(a: uint64x1_t) -> uint64x1_t {
}
/// Shift left
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24180,6 +27810,8 @@ pub unsafe fn vshlq_n_u64<const N: i32>(a: uint64x2_t) -> uint64x2_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24193,6 +27825,8 @@ pub unsafe fn vshll_n_s8<const N: i32>(a: int8x8_t) -> int16x8_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24206,6 +27840,8 @@ pub unsafe fn vshll_n_s16<const N: i32>(a: int16x4_t) -> int32x4_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24219,6 +27855,8 @@ pub unsafe fn vshll_n_s32<const N: i32>(a: int32x2_t) -> int64x2_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24232,6 +27870,8 @@ pub unsafe fn vshll_n_u8<const N: i32>(a: uint8x8_t) -> uint16x8_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24245,6 +27885,8 @@ pub unsafe fn vshll_n_u16<const N: i32>(a: uint16x4_t) -> uint32x4_t {
}
/// Signed shift left long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24258,6 +27900,8 @@ pub unsafe fn vshll_n_u32<const N: i32>(a: uint32x2_t) -> uint64x2_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24272,6 +27916,8 @@ pub unsafe fn vshr_n_s8<const N: i32>(a: int8x8_t) -> int8x8_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24286,6 +27932,8 @@ pub unsafe fn vshrq_n_s8<const N: i32>(a: int8x16_t) -> int8x16_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24300,6 +27948,8 @@ pub unsafe fn vshr_n_s16<const N: i32>(a: int16x4_t) -> int16x4_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24314,6 +27964,8 @@ pub unsafe fn vshrq_n_s16<const N: i32>(a: int16x8_t) -> int16x8_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24328,6 +27980,8 @@ pub unsafe fn vshr_n_s32<const N: i32>(a: int32x2_t) -> int32x2_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24342,6 +27996,8 @@ pub unsafe fn vshrq_n_s32<const N: i32>(a: int32x4_t) -> int32x4_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24356,6 +28012,8 @@ pub unsafe fn vshr_n_s64<const N: i32>(a: int64x1_t) -> int64x1_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24370,6 +28028,8 @@ pub unsafe fn vshrq_n_s64<const N: i32>(a: int64x2_t) -> int64x2_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24384,6 +28044,8 @@ pub unsafe fn vshr_n_u8<const N: i32>(a: uint8x8_t) -> uint8x8_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24398,6 +28060,8 @@ pub unsafe fn vshrq_n_u8<const N: i32>(a: uint8x16_t) -> uint8x16_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24412,6 +28076,8 @@ pub unsafe fn vshr_n_u16<const N: i32>(a: uint16x4_t) -> uint16x4_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24426,6 +28092,8 @@ pub unsafe fn vshrq_n_u16<const N: i32>(a: uint16x8_t) -> uint16x8_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24440,6 +28108,8 @@ pub unsafe fn vshr_n_u32<const N: i32>(a: uint32x2_t) -> uint32x2_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24454,6 +28124,8 @@ pub unsafe fn vshrq_n_u32<const N: i32>(a: uint32x4_t) -> uint32x4_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24468,6 +28140,8 @@ pub unsafe fn vshr_n_u64<const N: i32>(a: uint64x1_t) -> uint64x1_t {
}
/// Shift right
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24482,6 +28156,8 @@ pub unsafe fn vshrq_n_u64<const N: i32>(a: uint64x2_t) -> uint64x2_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24495,6 +28171,8 @@ pub unsafe fn vshrn_n_s16<const N: i32>(a: int16x8_t) -> int8x8_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24508,6 +28186,8 @@ pub unsafe fn vshrn_n_s32<const N: i32>(a: int32x4_t) -> int16x4_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24521,6 +28201,8 @@ pub unsafe fn vshrn_n_s64<const N: i32>(a: int64x2_t) -> int32x2_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24534,6 +28216,8 @@ pub unsafe fn vshrn_n_u16<const N: i32>(a: uint16x8_t) -> uint8x8_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24547,6 +28231,8 @@ pub unsafe fn vshrn_n_u32<const N: i32>(a: uint32x4_t) -> uint16x4_t {
}
/// Shift right narrow
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24560,6 +28246,8 @@ pub unsafe fn vshrn_n_u64<const N: i32>(a: uint64x2_t) -> uint32x2_t {
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24573,6 +28261,8 @@ pub unsafe fn vsra_n_s8<const N: i32>(a: int8x8_t, b: int8x8_t) -> int8x8_t {
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24586,6 +28276,8 @@ pub unsafe fn vsraq_n_s8<const N: i32>(a: int8x16_t, b: int8x16_t) -> int8x16_t
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24599,6 +28291,8 @@ pub unsafe fn vsra_n_s16<const N: i32>(a: int16x4_t, b: int16x4_t) -> int16x4_t
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24612,6 +28306,8 @@ pub unsafe fn vsraq_n_s16<const N: i32>(a: int16x8_t, b: int16x8_t) -> int16x8_t
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24625,6 +28321,8 @@ pub unsafe fn vsra_n_s32<const N: i32>(a: int32x2_t, b: int32x2_t) -> int32x2_t
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24638,6 +28336,8 @@ pub unsafe fn vsraq_n_s32<const N: i32>(a: int32x4_t, b: int32x4_t) -> int32x4_t
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24651,6 +28351,8 @@ pub unsafe fn vsra_n_s64<const N: i32>(a: int64x1_t, b: int64x1_t) -> int64x1_t
}
/// Signed shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24664,6 +28366,8 @@ pub unsafe fn vsraq_n_s64<const N: i32>(a: int64x2_t, b: int64x2_t) -> int64x2_t
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24677,6 +28381,8 @@ pub unsafe fn vsra_n_u8<const N: i32>(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24690,6 +28396,8 @@ pub unsafe fn vsraq_n_u8<const N: i32>(a: uint8x16_t, b: uint8x16_t) -> uint8x16
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24703,6 +28411,8 @@ pub unsafe fn vsra_n_u16<const N: i32>(a: uint16x4_t, b: uint16x4_t) -> uint16x4
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24716,6 +28426,8 @@ pub unsafe fn vsraq_n_u16<const N: i32>(a: uint16x8_t, b: uint16x8_t) -> uint16x
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24729,6 +28441,8 @@ pub unsafe fn vsra_n_u32<const N: i32>(a: uint32x2_t, b: uint32x2_t) -> uint32x2
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24742,6 +28456,8 @@ pub unsafe fn vsraq_n_u32<const N: i32>(a: uint32x4_t, b: uint32x4_t) -> uint32x
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24755,6 +28471,8 @@ pub unsafe fn vsra_n_u64<const N: i32>(a: uint64x1_t, b: uint64x1_t) -> uint64x1
}
/// Unsigned shift right and accumulate
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u64)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24768,6 +28486,8 @@ pub unsafe fn vsraq_n_u64<const N: i32>(a: uint64x2_t, b: uint64x2_t) -> uint64x
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24781,6 +28501,8 @@ pub unsafe fn vtrn_s8(a: int8x8_t, b: int8x8_t) -> int8x8x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24794,6 +28516,8 @@ pub unsafe fn vtrn_s16(a: int16x4_t, b: int16x4_t) -> int16x4x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24807,6 +28531,8 @@ pub unsafe fn vtrnq_s8(a: int8x16_t, b: int8x16_t) -> int8x16x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24820,6 +28546,8 @@ pub unsafe fn vtrnq_s16(a: int16x8_t, b: int16x8_t) -> int16x8x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24833,6 +28561,8 @@ pub unsafe fn vtrnq_s32(a: int32x4_t, b: int32x4_t) -> int32x4x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24846,6 +28576,8 @@ pub unsafe fn vtrn_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24859,6 +28591,8 @@ pub unsafe fn vtrn_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24872,6 +28606,8 @@ pub unsafe fn vtrnq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24885,6 +28621,8 @@ pub unsafe fn vtrnq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24898,6 +28636,8 @@ pub unsafe fn vtrnq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24911,6 +28651,8 @@ pub unsafe fn vtrn_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24924,6 +28666,8 @@ pub unsafe fn vtrn_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24937,6 +28681,8 @@ pub unsafe fn vtrnq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24950,6 +28696,8 @@ pub unsafe fn vtrnq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24963,6 +28711,8 @@ pub unsafe fn vtrn_s32(a: int32x2_t, b: int32x2_t) -> int32x2x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24976,6 +28726,8 @@ pub unsafe fn vtrn_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -24989,6 +28741,8 @@ pub unsafe fn vtrn_f32(a: float32x2_t, b: float32x2_t) -> float32x2x2_t {
}
/// Transpose elements
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25002,6 +28756,8 @@ pub unsafe fn vtrnq_f32(a: float32x4_t, b: float32x4_t) -> float32x4x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25015,6 +28771,8 @@ pub unsafe fn vzip_s8(a: int8x8_t, b: int8x8_t) -> int8x8x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25028,6 +28786,8 @@ pub unsafe fn vzip_s16(a: int16x4_t, b: int16x4_t) -> int16x4x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25041,6 +28801,8 @@ pub unsafe fn vzip_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25054,6 +28816,8 @@ pub unsafe fn vzip_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25067,6 +28831,8 @@ pub unsafe fn vzip_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25080,6 +28846,8 @@ pub unsafe fn vzip_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25093,6 +28861,8 @@ pub unsafe fn vzip_s32(a: int32x2_t, b: int32x2_t) -> int32x2x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25106,6 +28876,8 @@ pub unsafe fn vzip_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25119,6 +28891,8 @@ pub unsafe fn vzipq_s8(a: int8x16_t, b: int8x16_t) -> int8x16x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25132,6 +28906,8 @@ pub unsafe fn vzipq_s16(a: int16x8_t, b: int16x8_t) -> int16x8x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25145,6 +28921,8 @@ pub unsafe fn vzipq_s32(a: int32x4_t, b: int32x4_t) -> int32x4x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25158,6 +28936,8 @@ pub unsafe fn vzipq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25171,6 +28951,8 @@ pub unsafe fn vzipq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25184,6 +28966,8 @@ pub unsafe fn vzipq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25197,6 +28981,8 @@ pub unsafe fn vzipq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25210,6 +28996,8 @@ pub unsafe fn vzipq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25223,6 +29011,8 @@ pub unsafe fn vzip_f32(a: float32x2_t, b: float32x2_t) -> float32x2x2_t {
}
/// Zip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25236,6 +29026,8 @@ pub unsafe fn vzipq_f32(a: float32x4_t, b: float32x4_t) -> float32x4x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25249,6 +29041,8 @@ pub unsafe fn vuzp_s8(a: int8x8_t, b: int8x8_t) -> int8x8x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25262,6 +29056,8 @@ pub unsafe fn vuzp_s16(a: int16x4_t, b: int16x4_t) -> int16x4x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25275,6 +29071,8 @@ pub unsafe fn vuzpq_s8(a: int8x16_t, b: int8x16_t) -> int8x16x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25288,6 +29086,8 @@ pub unsafe fn vuzpq_s16(a: int16x8_t, b: int16x8_t) -> int16x8x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25301,6 +29101,8 @@ pub unsafe fn vuzpq_s32(a: int32x4_t, b: int32x4_t) -> int32x4x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25314,6 +29116,8 @@ pub unsafe fn vuzp_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25327,6 +29131,8 @@ pub unsafe fn vuzp_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25340,6 +29146,8 @@ pub unsafe fn vuzpq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25353,6 +29161,8 @@ pub unsafe fn vuzpq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25366,6 +29176,8 @@ pub unsafe fn vuzpq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25379,6 +29191,8 @@ pub unsafe fn vuzp_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25392,6 +29206,8 @@ pub unsafe fn vuzp_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_p8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25405,6 +29221,8 @@ pub unsafe fn vuzpq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_p16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25418,6 +29236,8 @@ pub unsafe fn vuzpq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25431,6 +29251,8 @@ pub unsafe fn vuzp_s32(a: int32x2_t, b: int32x2_t) -> int32x2x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25444,6 +29266,8 @@ pub unsafe fn vuzp_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25457,6 +29281,8 @@ pub unsafe fn vuzp_f32(a: float32x2_t, b: float32x2_t) -> float32x2x2_t {
}
/// Unzip vectors
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_f32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25470,6 +29296,8 @@ pub unsafe fn vuzpq_f32(a: float32x4_t, b: float32x4_t) -> float32x4x2_t {
}
/// Unsigned Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_u8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25482,6 +29310,8 @@ pub unsafe fn vabal_u8(a: uint16x8_t, b: uint8x8_t, c: uint8x8_t) -> uint16x8_t
}
/// Unsigned Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_u16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25494,6 +29324,8 @@ pub unsafe fn vabal_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4_t) -> uint32x4
}
/// Unsigned Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_u32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25506,6 +29338,8 @@ pub unsafe fn vabal_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2_t) -> uint64x2
}
/// Signed Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25519,6 +29353,8 @@ pub unsafe fn vabal_s8(a: int16x8_t, b: int8x8_t, c: int8x8_t) -> int16x8_t {
}
/// Signed Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25532,6 +29368,8 @@ pub unsafe fn vabal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
}
/// Signed Absolute difference and Accumulate Long
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25545,6 +29383,8 @@ pub unsafe fn vabal_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25562,6 +29402,8 @@ vqabs_s8_(a)
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s8)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25579,6 +29421,8 @@ vqabsq_s8_(a)
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25596,6 +29440,8 @@ vqabs_s16_(a)
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s16)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25613,6 +29459,8 @@ vqabsq_s16_(a)
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -25630,6 +29478,8 @@ vqabs_s32_(a)
}
/// Singned saturating Absolute value
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s32)
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -28096,181 +31946,181 @@ mod test {
#[simd_test(enable = "neon")]
unsafe fn test_vext_s8() {
- let a: i8x8 = i8x8::new(0, 8, 8, 9, 8, 9, 9, 11);
- let b: i8x8 = i8x8::new(9, 11, 14, 15, 16, 17, 18, 19);
- let e: i8x8 = i8x8::new(8, 9, 9, 11, 9, 11, 14, 15);
- let r: i8x8 = transmute(vext_s8::<4>(transmute(a), transmute(b)));
+ let a: i8x8 = i8x8::new(1, 1, 1, 1, 1, 1, 1, 1);
+ let b: i8x8 = i8x8::new(2, 2, 2, 2, 2, 2, 2, 2);
+ let e: i8x8 = i8x8::new(1, 2, 2, 2, 2, 2, 2, 2);
+ let r: i8x8 = transmute(vext_s8::<7>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_s8() {
- let a: i8x16 = i8x16::new(0, 8, 8, 9, 8, 9, 9, 11, 8, 9, 9, 11, 9, 11, 14, 15);
- let b: i8x16 = i8x16::new(9, 11, 14, 15, 16, 17, 18, 19, 0, 8, 8, 9, 8, 9, 9, 11);
- let e: i8x16 = i8x16::new(8, 9, 9, 11, 9, 11, 14, 15, 9, 11, 14, 15, 16, 17, 18, 19);
- let r: i8x16 = transmute(vextq_s8::<8>(transmute(a), transmute(b)));
+ let a: i8x16 = i8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+ let b: i8x16 = i8x16::new(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
+ let e: i8x16 = i8x16::new(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
+ let r: i8x16 = transmute(vextq_s8::<15>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_s16() {
- let a: i16x4 = i16x4::new(0, 8, 8, 9);
- let b: i16x4 = i16x4::new(9, 11, 14, 15);
- let e: i16x4 = i16x4::new(8, 9, 9, 11);
- let r: i16x4 = transmute(vext_s16::<2>(transmute(a), transmute(b)));
+ let a: i16x4 = i16x4::new(1, 1, 1, 1);
+ let b: i16x4 = i16x4::new(2, 2, 2, 2);
+ let e: i16x4 = i16x4::new(1, 2, 2, 2);
+ let r: i16x4 = transmute(vext_s16::<3>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_s16() {
- let a: i16x8 = i16x8::new(0, 8, 8, 9, 8, 9, 9, 11);
- let b: i16x8 = i16x8::new(9, 11, 14, 15, 16, 17, 18, 19);
- let e: i16x8 = i16x8::new(8, 9, 9, 11, 9, 11, 14, 15);
- let r: i16x8 = transmute(vextq_s16::<4>(transmute(a), transmute(b)));
+ let a: i16x8 = i16x8::new(1, 1, 1, 1, 1, 1, 1, 1);
+ let b: i16x8 = i16x8::new(2, 2, 2, 2, 2, 2, 2, 2);
+ let e: i16x8 = i16x8::new(1, 2, 2, 2, 2, 2, 2, 2);
+ let r: i16x8 = transmute(vextq_s16::<7>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_s32() {
- let a: i32x2 = i32x2::new(0, 8);
- let b: i32x2 = i32x2::new(9, 11);
- let e: i32x2 = i32x2::new(8, 9);
+ let a: i32x2 = i32x2::new(1, 1);
+ let b: i32x2 = i32x2::new(2, 2);
+ let e: i32x2 = i32x2::new(1, 2);
let r: i32x2 = transmute(vext_s32::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_s32() {
- let a: i32x4 = i32x4::new(0, 8, 8, 9);
- let b: i32x4 = i32x4::new(9, 11, 14, 15);
- let e: i32x4 = i32x4::new(8, 9, 9, 11);
- let r: i32x4 = transmute(vextq_s32::<2>(transmute(a), transmute(b)));
+ let a: i32x4 = i32x4::new(1, 1, 1, 1);
+ let b: i32x4 = i32x4::new(2, 2, 2, 2);
+ let e: i32x4 = i32x4::new(1, 2, 2, 2);
+ let r: i32x4 = transmute(vextq_s32::<3>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_u8() {
- let a: u8x8 = u8x8::new(0, 8, 8, 9, 8, 9, 9, 11);
- let b: u8x8 = u8x8::new(9, 11, 14, 15, 16, 17, 18, 19);
- let e: u8x8 = u8x8::new(8, 9, 9, 11, 9, 11, 14, 15);
- let r: u8x8 = transmute(vext_u8::<4>(transmute(a), transmute(b)));
+ let a: u8x8 = u8x8::new(1, 1, 1, 1, 1, 1, 1, 1);
+ let b: u8x8 = u8x8::new(2, 2, 2, 2, 2, 2, 2, 2);
+ let e: u8x8 = u8x8::new(1, 2, 2, 2, 2, 2, 2, 2);
+ let r: u8x8 = transmute(vext_u8::<7>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_u8() {
- let a: u8x16 = u8x16::new(0, 8, 8, 9, 8, 9, 9, 11, 8, 9, 9, 11, 9, 11, 14, 15);
- let b: u8x16 = u8x16::new(9, 11, 14, 15, 16, 17, 18, 19, 0, 8, 8, 9, 8, 9, 9, 11);
- let e: u8x16 = u8x16::new(8, 9, 9, 11, 9, 11, 14, 15, 9, 11, 14, 15, 16, 17, 18, 19);
- let r: u8x16 = transmute(vextq_u8::<8>(transmute(a), transmute(b)));
+ let a: u8x16 = u8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+ let b: u8x16 = u8x16::new(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
+ let e: u8x16 = u8x16::new(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
+ let r: u8x16 = transmute(vextq_u8::<15>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_u16() {
- let a: u16x4 = u16x4::new(0, 8, 8, 9);
- let b: u16x4 = u16x4::new(9, 11, 14, 15);
- let e: u16x4 = u16x4::new(8, 9, 9, 11);
- let r: u16x4 = transmute(vext_u16::<2>(transmute(a), transmute(b)));
+ let a: u16x4 = u16x4::new(1, 1, 1, 1);
+ let b: u16x4 = u16x4::new(2, 2, 2, 2);
+ let e: u16x4 = u16x4::new(1, 2, 2, 2);
+ let r: u16x4 = transmute(vext_u16::<3>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_u16() {
- let a: u16x8 = u16x8::new(0, 8, 8, 9, 8, 9, 9, 11);
- let b: u16x8 = u16x8::new(9, 11, 14, 15, 16, 17, 18, 19);
- let e: u16x8 = u16x8::new(8, 9, 9, 11, 9, 11, 14, 15);
- let r: u16x8 = transmute(vextq_u16::<4>(transmute(a), transmute(b)));
+ let a: u16x8 = u16x8::new(1, 1, 1, 1, 1, 1, 1, 1);
+ let b: u16x8 = u16x8::new(2, 2, 2, 2, 2, 2, 2, 2);
+ let e: u16x8 = u16x8::new(1, 2, 2, 2, 2, 2, 2, 2);
+ let r: u16x8 = transmute(vextq_u16::<7>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_u32() {
- let a: u32x2 = u32x2::new(0, 8);
- let b: u32x2 = u32x2::new(9, 11);
- let e: u32x2 = u32x2::new(8, 9);
+ let a: u32x2 = u32x2::new(1, 1);
+ let b: u32x2 = u32x2::new(2, 2);
+ let e: u32x2 = u32x2::new(1, 2);
let r: u32x2 = transmute(vext_u32::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_u32() {
- let a: u32x4 = u32x4::new(0, 8, 8, 9);
- let b: u32x4 = u32x4::new(9, 11, 14, 15);
- let e: u32x4 = u32x4::new(8, 9, 9, 11);
- let r: u32x4 = transmute(vextq_u32::<2>(transmute(a), transmute(b)));
+ let a: u32x4 = u32x4::new(1, 1, 1, 1);
+ let b: u32x4 = u32x4::new(2, 2, 2, 2);
+ let e: u32x4 = u32x4::new(1, 2, 2, 2);
+ let r: u32x4 = transmute(vextq_u32::<3>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_p8() {
- let a: i8x8 = i8x8::new(0, 8, 8, 9, 8, 9, 9, 11);
- let b: i8x8 = i8x8::new(9, 11, 14, 15, 16, 17, 18, 19);
- let e: i8x8 = i8x8::new(8, 9, 9, 11, 9, 11, 14, 15);
- let r: i8x8 = transmute(vext_p8::<4>(transmute(a), transmute(b)));
+ let a: i8x8 = i8x8::new(1, 1, 1, 1, 1, 1, 1, 1);
+ let b: i8x8 = i8x8::new(2, 2, 2, 2, 2, 2, 2, 2);
+ let e: i8x8 = i8x8::new(1, 2, 2, 2, 2, 2, 2, 2);
+ let r: i8x8 = transmute(vext_p8::<7>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_p8() {
- let a: i8x16 = i8x16::new(0, 8, 8, 9, 8, 9, 9, 11, 8, 9, 9, 11, 9, 11, 14, 15);
- let b: i8x16 = i8x16::new(9, 11, 14, 15, 16, 17, 18, 19, 0, 8, 8, 9, 8, 9, 9, 11);
- let e: i8x16 = i8x16::new(8, 9, 9, 11, 9, 11, 14, 15, 9, 11, 14, 15, 16, 17, 18, 19);
- let r: i8x16 = transmute(vextq_p8::<8>(transmute(a), transmute(b)));
+ let a: i8x16 = i8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+ let b: i8x16 = i8x16::new(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
+ let e: i8x16 = i8x16::new(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
+ let r: i8x16 = transmute(vextq_p8::<15>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_p16() {
- let a: i16x4 = i16x4::new(0, 8, 8, 9);
- let b: i16x4 = i16x4::new(9, 11, 14, 15);
- let e: i16x4 = i16x4::new(8, 9, 9, 11);
- let r: i16x4 = transmute(vext_p16::<2>(transmute(a), transmute(b)));
+ let a: i16x4 = i16x4::new(1, 1, 1, 1);
+ let b: i16x4 = i16x4::new(2, 2, 2, 2);
+ let e: i16x4 = i16x4::new(1, 2, 2, 2);
+ let r: i16x4 = transmute(vext_p16::<3>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_p16() {
- let a: i16x8 = i16x8::new(0, 8, 8, 9, 8, 9, 9, 11);
- let b: i16x8 = i16x8::new(9, 11, 14, 15, 16, 17, 18, 19);
- let e: i16x8 = i16x8::new(8, 9, 9, 11, 9, 11, 14, 15);
- let r: i16x8 = transmute(vextq_p16::<4>(transmute(a), transmute(b)));
+ let a: i16x8 = i16x8::new(1, 1, 1, 1, 1, 1, 1, 1);
+ let b: i16x8 = i16x8::new(2, 2, 2, 2, 2, 2, 2, 2);
+ let e: i16x8 = i16x8::new(1, 2, 2, 2, 2, 2, 2, 2);
+ let r: i16x8 = transmute(vextq_p16::<7>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_s64() {
- let a: i64x2 = i64x2::new(0, 8);
- let b: i64x2 = i64x2::new(9, 11);
- let e: i64x2 = i64x2::new(8, 9);
+ let a: i64x2 = i64x2::new(1, 1);
+ let b: i64x2 = i64x2::new(2, 2);
+ let e: i64x2 = i64x2::new(1, 2);
let r: i64x2 = transmute(vextq_s64::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_u64() {
- let a: u64x2 = u64x2::new(0, 8);
- let b: u64x2 = u64x2::new(9, 11);
- let e: u64x2 = u64x2::new(8, 9);
+ let a: u64x2 = u64x2::new(1, 1);
+ let b: u64x2 = u64x2::new(2, 2);
+ let e: u64x2 = u64x2::new(1, 2);
let r: u64x2 = transmute(vextq_u64::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vext_f32() {
- let a: f32x2 = f32x2::new(0., 2.);
- let b: f32x2 = f32x2::new(3., 4.);
- let e: f32x2 = f32x2::new(2., 3.);
+ let a: f32x2 = f32x2::new(1., 1.);
+ let b: f32x2 = f32x2::new(2., 2.);
+ let e: f32x2 = f32x2::new(1., 2.);
let r: f32x2 = transmute(vext_f32::<1>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vextq_f32() {
- let a: f32x4 = f32x4::new(0., 2., 2., 3.);
- let b: f32x4 = f32x4::new(3., 4., 5., 6.);
- let e: f32x4 = f32x4::new(2., 3., 3., 4.);
- let r: f32x4 = transmute(vextq_f32::<2>(transmute(a), transmute(b)));
+ let a: f32x4 = f32x4::new(1., 1., 1., 1.);
+ let b: f32x4 = f32x4::new(2., 2., 2., 2.);
+ let e: f32x4 = f32x4::new(1., 2., 2., 2.);
+ let r: f32x4 = transmute(vextq_f32::<3>(transmute(a), transmute(b)));
assert_eq!(r, e);
}
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs
index 952d1ca2e..043f7ed51 100644
--- a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs
+++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs
@@ -106,6 +106,7 @@ types! {
}
/// ARM-specific type containing two `int8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -113,6 +114,7 @@ types! {
)]
pub struct int8x8x2_t(pub int8x8_t, pub int8x8_t);
/// ARM-specific type containing three `int8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -120,6 +122,7 @@ pub struct int8x8x2_t(pub int8x8_t, pub int8x8_t);
)]
pub struct int8x8x3_t(pub int8x8_t, pub int8x8_t, pub int8x8_t);
/// ARM-specific type containing four `int8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -128,6 +131,7 @@ pub struct int8x8x3_t(pub int8x8_t, pub int8x8_t, pub int8x8_t);
pub struct int8x8x4_t(pub int8x8_t, pub int8x8_t, pub int8x8_t, pub int8x8_t);
/// ARM-specific type containing two `int8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -135,6 +139,7 @@ pub struct int8x8x4_t(pub int8x8_t, pub int8x8_t, pub int8x8_t, pub int8x8_t);
)]
pub struct int8x16x2_t(pub int8x16_t, pub int8x16_t);
/// ARM-specific type containing three `int8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -142,6 +147,7 @@ pub struct int8x16x2_t(pub int8x16_t, pub int8x16_t);
)]
pub struct int8x16x3_t(pub int8x16_t, pub int8x16_t, pub int8x16_t);
/// ARM-specific type containing four `int8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -150,6 +156,7 @@ pub struct int8x16x3_t(pub int8x16_t, pub int8x16_t, pub int8x16_t);
pub struct int8x16x4_t(pub int8x16_t, pub int8x16_t, pub int8x16_t, pub int8x16_t);
/// ARM-specific type containing two `uint8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -157,6 +164,7 @@ pub struct int8x16x4_t(pub int8x16_t, pub int8x16_t, pub int8x16_t, pub int8x16_
)]
pub struct uint8x8x2_t(pub uint8x8_t, pub uint8x8_t);
/// ARM-specific type containing three `uint8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -164,6 +172,7 @@ pub struct uint8x8x2_t(pub uint8x8_t, pub uint8x8_t);
)]
pub struct uint8x8x3_t(pub uint8x8_t, pub uint8x8_t, pub uint8x8_t);
/// ARM-specific type containing four `uint8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -172,6 +181,7 @@ pub struct uint8x8x3_t(pub uint8x8_t, pub uint8x8_t, pub uint8x8_t);
pub struct uint8x8x4_t(pub uint8x8_t, pub uint8x8_t, pub uint8x8_t, pub uint8x8_t);
/// ARM-specific type containing two `uint8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -179,6 +189,7 @@ pub struct uint8x8x4_t(pub uint8x8_t, pub uint8x8_t, pub uint8x8_t, pub uint8x8_
)]
pub struct uint8x16x2_t(pub uint8x16_t, pub uint8x16_t);
/// ARM-specific type containing three `uint8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -186,6 +197,7 @@ pub struct uint8x16x2_t(pub uint8x16_t, pub uint8x16_t);
)]
pub struct uint8x16x3_t(pub uint8x16_t, pub uint8x16_t, pub uint8x16_t);
/// ARM-specific type containing four `uint8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -199,6 +211,7 @@ pub struct uint8x16x4_t(
);
/// ARM-specific type containing two `poly8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -206,6 +219,7 @@ pub struct uint8x16x4_t(
)]
pub struct poly8x8x2_t(pub poly8x8_t, pub poly8x8_t);
/// ARM-specific type containing three `poly8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -213,6 +227,7 @@ pub struct poly8x8x2_t(pub poly8x8_t, pub poly8x8_t);
)]
pub struct poly8x8x3_t(pub poly8x8_t, pub poly8x8_t, pub poly8x8_t);
/// ARM-specific type containing four `poly8x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -221,6 +236,7 @@ pub struct poly8x8x3_t(pub poly8x8_t, pub poly8x8_t, pub poly8x8_t);
pub struct poly8x8x4_t(pub poly8x8_t, pub poly8x8_t, pub poly8x8_t, pub poly8x8_t);
/// ARM-specific type containing two `poly8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -228,6 +244,7 @@ pub struct poly8x8x4_t(pub poly8x8_t, pub poly8x8_t, pub poly8x8_t, pub poly8x8_
)]
pub struct poly8x16x2_t(pub poly8x16_t, pub poly8x16_t);
/// ARM-specific type containing three `poly8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -235,6 +252,7 @@ pub struct poly8x16x2_t(pub poly8x16_t, pub poly8x16_t);
)]
pub struct poly8x16x3_t(pub poly8x16_t, pub poly8x16_t, pub poly8x16_t);
/// ARM-specific type containing four `poly8x16_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -248,6 +266,7 @@ pub struct poly8x16x4_t(
);
/// ARM-specific type containing two `int16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -255,6 +274,7 @@ pub struct poly8x16x4_t(
)]
pub struct int16x4x2_t(pub int16x4_t, pub int16x4_t);
/// ARM-specific type containing three `int16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -262,6 +282,7 @@ pub struct int16x4x2_t(pub int16x4_t, pub int16x4_t);
)]
pub struct int16x4x3_t(pub int16x4_t, pub int16x4_t, pub int16x4_t);
/// ARM-specific type containing four `int16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -270,6 +291,7 @@ pub struct int16x4x3_t(pub int16x4_t, pub int16x4_t, pub int16x4_t);
pub struct int16x4x4_t(pub int16x4_t, pub int16x4_t, pub int16x4_t, pub int16x4_t);
/// ARM-specific type containing two `int16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -277,6 +299,7 @@ pub struct int16x4x4_t(pub int16x4_t, pub int16x4_t, pub int16x4_t, pub int16x4_
)]
pub struct int16x8x2_t(pub int16x8_t, pub int16x8_t);
/// ARM-specific type containing three `int16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -284,6 +307,7 @@ pub struct int16x8x2_t(pub int16x8_t, pub int16x8_t);
)]
pub struct int16x8x3_t(pub int16x8_t, pub int16x8_t, pub int16x8_t);
/// ARM-specific type containing four `int16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -292,6 +316,7 @@ pub struct int16x8x3_t(pub int16x8_t, pub int16x8_t, pub int16x8_t);
pub struct int16x8x4_t(pub int16x8_t, pub int16x8_t, pub int16x8_t, pub int16x8_t);
/// ARM-specific type containing two `uint16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -299,6 +324,7 @@ pub struct int16x8x4_t(pub int16x8_t, pub int16x8_t, pub int16x8_t, pub int16x8_
)]
pub struct uint16x4x2_t(pub uint16x4_t, pub uint16x4_t);
/// ARM-specific type containing three `uint16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -306,6 +332,7 @@ pub struct uint16x4x2_t(pub uint16x4_t, pub uint16x4_t);
)]
pub struct uint16x4x3_t(pub uint16x4_t, pub uint16x4_t, pub uint16x4_t);
/// ARM-specific type containing four `uint16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -319,6 +346,7 @@ pub struct uint16x4x4_t(
);
/// ARM-specific type containing two `uint16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -326,6 +354,7 @@ pub struct uint16x4x4_t(
)]
pub struct uint16x8x2_t(pub uint16x8_t, pub uint16x8_t);
/// ARM-specific type containing three `uint16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -333,6 +362,7 @@ pub struct uint16x8x2_t(pub uint16x8_t, pub uint16x8_t);
)]
pub struct uint16x8x3_t(pub uint16x8_t, pub uint16x8_t, pub uint16x8_t);
/// ARM-specific type containing four `uint16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -346,6 +376,7 @@ pub struct uint16x8x4_t(
);
/// ARM-specific type containing two `poly16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -353,6 +384,7 @@ pub struct uint16x8x4_t(
)]
pub struct poly16x4x2_t(pub poly16x4_t, pub poly16x4_t);
/// ARM-specific type containing three `poly16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -360,6 +392,7 @@ pub struct poly16x4x2_t(pub poly16x4_t, pub poly16x4_t);
)]
pub struct poly16x4x3_t(pub poly16x4_t, pub poly16x4_t, pub poly16x4_t);
/// ARM-specific type containing four `poly16x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -373,6 +406,7 @@ pub struct poly16x4x4_t(
);
/// ARM-specific type containing two `poly16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -380,6 +414,7 @@ pub struct poly16x4x4_t(
)]
pub struct poly16x8x2_t(pub poly16x8_t, pub poly16x8_t);
/// ARM-specific type containing three `poly16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -387,6 +422,7 @@ pub struct poly16x8x2_t(pub poly16x8_t, pub poly16x8_t);
)]
pub struct poly16x8x3_t(pub poly16x8_t, pub poly16x8_t, pub poly16x8_t);
/// ARM-specific type containing four `poly16x8_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -400,6 +436,7 @@ pub struct poly16x8x4_t(
);
/// ARM-specific type containing two `int32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -407,6 +444,7 @@ pub struct poly16x8x4_t(
)]
pub struct int32x2x2_t(pub int32x2_t, pub int32x2_t);
/// ARM-specific type containing three `int32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -414,6 +452,7 @@ pub struct int32x2x2_t(pub int32x2_t, pub int32x2_t);
)]
pub struct int32x2x3_t(pub int32x2_t, pub int32x2_t, pub int32x2_t);
/// ARM-specific type containing four `int32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -422,6 +461,7 @@ pub struct int32x2x3_t(pub int32x2_t, pub int32x2_t, pub int32x2_t);
pub struct int32x2x4_t(pub int32x2_t, pub int32x2_t, pub int32x2_t, pub int32x2_t);
/// ARM-specific type containing two `int32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -429,6 +469,7 @@ pub struct int32x2x4_t(pub int32x2_t, pub int32x2_t, pub int32x2_t, pub int32x2_
)]
pub struct int32x4x2_t(pub int32x4_t, pub int32x4_t);
/// ARM-specific type containing three `int32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -436,6 +477,7 @@ pub struct int32x4x2_t(pub int32x4_t, pub int32x4_t);
)]
pub struct int32x4x3_t(pub int32x4_t, pub int32x4_t, pub int32x4_t);
/// ARM-specific type containing four `int32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -444,6 +486,7 @@ pub struct int32x4x3_t(pub int32x4_t, pub int32x4_t, pub int32x4_t);
pub struct int32x4x4_t(pub int32x4_t, pub int32x4_t, pub int32x4_t, pub int32x4_t);
/// ARM-specific type containing two `uint32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -451,6 +494,7 @@ pub struct int32x4x4_t(pub int32x4_t, pub int32x4_t, pub int32x4_t, pub int32x4_
)]
pub struct uint32x2x2_t(pub uint32x2_t, pub uint32x2_t);
/// ARM-specific type containing three `uint32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -458,6 +502,7 @@ pub struct uint32x2x2_t(pub uint32x2_t, pub uint32x2_t);
)]
pub struct uint32x2x3_t(pub uint32x2_t, pub uint32x2_t, pub uint32x2_t);
/// ARM-specific type containing four `uint32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -471,6 +516,7 @@ pub struct uint32x2x4_t(
);
/// ARM-specific type containing two `uint32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -478,6 +524,7 @@ pub struct uint32x2x4_t(
)]
pub struct uint32x4x2_t(pub uint32x4_t, pub uint32x4_t);
/// ARM-specific type containing three `uint32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -485,6 +532,7 @@ pub struct uint32x4x2_t(pub uint32x4_t, pub uint32x4_t);
)]
pub struct uint32x4x3_t(pub uint32x4_t, pub uint32x4_t, pub uint32x4_t);
/// ARM-specific type containing four `uint32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -498,6 +546,7 @@ pub struct uint32x4x4_t(
);
/// ARM-specific type containing two `float32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -505,6 +554,7 @@ pub struct uint32x4x4_t(
)]
pub struct float32x2x2_t(pub float32x2_t, pub float32x2_t);
/// ARM-specific type containing three `float32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -512,6 +562,7 @@ pub struct float32x2x2_t(pub float32x2_t, pub float32x2_t);
)]
pub struct float32x2x3_t(pub float32x2_t, pub float32x2_t, pub float32x2_t);
/// ARM-specific type containing four `float32x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -525,6 +576,7 @@ pub struct float32x2x4_t(
);
/// ARM-specific type containing two `float32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -532,6 +584,7 @@ pub struct float32x2x4_t(
)]
pub struct float32x4x2_t(pub float32x4_t, pub float32x4_t);
/// ARM-specific type containing three `float32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -539,6 +592,7 @@ pub struct float32x4x2_t(pub float32x4_t, pub float32x4_t);
)]
pub struct float32x4x3_t(pub float32x4_t, pub float32x4_t, pub float32x4_t);
/// ARM-specific type containing four `float32x4_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -552,6 +606,7 @@ pub struct float32x4x4_t(
);
/// ARM-specific type containing four `int64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -559,6 +614,7 @@ pub struct float32x4x4_t(
)]
pub struct int64x1x2_t(pub int64x1_t, pub int64x1_t);
/// ARM-specific type containing four `int64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -566,6 +622,7 @@ pub struct int64x1x2_t(pub int64x1_t, pub int64x1_t);
)]
pub struct int64x1x3_t(pub int64x1_t, pub int64x1_t, pub int64x1_t);
/// ARM-specific type containing four `int64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -574,6 +631,7 @@ pub struct int64x1x3_t(pub int64x1_t, pub int64x1_t, pub int64x1_t);
pub struct int64x1x4_t(pub int64x1_t, pub int64x1_t, pub int64x1_t, pub int64x1_t);
/// ARM-specific type containing four `int64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -581,6 +639,7 @@ pub struct int64x1x4_t(pub int64x1_t, pub int64x1_t, pub int64x1_t, pub int64x1_
)]
pub struct int64x2x2_t(pub int64x2_t, pub int64x2_t);
/// ARM-specific type containing four `int64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -588,6 +647,7 @@ pub struct int64x2x2_t(pub int64x2_t, pub int64x2_t);
)]
pub struct int64x2x3_t(pub int64x2_t, pub int64x2_t, pub int64x2_t);
/// ARM-specific type containing four `int64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -596,6 +656,7 @@ pub struct int64x2x3_t(pub int64x2_t, pub int64x2_t, pub int64x2_t);
pub struct int64x2x4_t(pub int64x2_t, pub int64x2_t, pub int64x2_t, pub int64x2_t);
/// ARM-specific type containing four `uint64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -603,6 +664,7 @@ pub struct int64x2x4_t(pub int64x2_t, pub int64x2_t, pub int64x2_t, pub int64x2_
)]
pub struct uint64x1x2_t(pub uint64x1_t, pub uint64x1_t);
/// ARM-specific type containing four `uint64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -610,6 +672,7 @@ pub struct uint64x1x2_t(pub uint64x1_t, pub uint64x1_t);
)]
pub struct uint64x1x3_t(pub uint64x1_t, pub uint64x1_t, pub uint64x1_t);
/// ARM-specific type containing four `uint64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -623,6 +686,7 @@ pub struct uint64x1x4_t(
);
/// ARM-specific type containing four `uint64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -630,6 +694,7 @@ pub struct uint64x1x4_t(
)]
pub struct uint64x2x2_t(pub uint64x2_t, pub uint64x2_t);
/// ARM-specific type containing four `uint64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -637,6 +702,7 @@ pub struct uint64x2x2_t(pub uint64x2_t, pub uint64x2_t);
)]
pub struct uint64x2x3_t(pub uint64x2_t, pub uint64x2_t, pub uint64x2_t);
/// ARM-specific type containing four `uint64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -650,6 +716,7 @@ pub struct uint64x2x4_t(
);
/// ARM-specific type containing four `poly64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -657,6 +724,7 @@ pub struct uint64x2x4_t(
)]
pub struct poly64x1x2_t(pub poly64x1_t, pub poly64x1_t);
/// ARM-specific type containing four `poly64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -664,6 +732,7 @@ pub struct poly64x1x2_t(pub poly64x1_t, pub poly64x1_t);
)]
pub struct poly64x1x3_t(pub poly64x1_t, pub poly64x1_t, pub poly64x1_t);
/// ARM-specific type containing four `poly64x1_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -677,6 +746,7 @@ pub struct poly64x1x4_t(
);
/// ARM-specific type containing four `poly64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -684,6 +754,7 @@ pub struct poly64x1x4_t(
)]
pub struct poly64x2x2_t(pub poly64x2_t, pub poly64x2_t);
/// ARM-specific type containing four `poly64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -691,6 +762,7 @@ pub struct poly64x2x2_t(pub poly64x2_t, pub poly64x2_t);
)]
pub struct poly64x2x3_t(pub poly64x2_t, pub poly64x2_t, pub poly64x2_t);
/// ARM-specific type containing four `poly64x2_t` vectors.
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
target_arch = "aarch64",
@@ -1212,6 +1284,8 @@ pub unsafe fn vld1q_lane_p16<const LANE: i32>(ptr: *const p16, src: poly16x8_t)
}
/// Load one single-element structure to one lane of one register.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1228,6 +1302,8 @@ pub unsafe fn vld1_lane_p64<const LANE: i32>(ptr: *const p64, src: poly64x1_t) -
}
/// Load one single-element structure to one lane of one register.
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1603,6 +1679,8 @@ pub unsafe fn vld1_dup_f32(ptr: *const f32) -> float32x2_t {
}
/// Load one single-element structure and Replicate to all lanes (of one register).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -1624,6 +1702,8 @@ pub unsafe fn vld1_dup_p64(ptr: *const p64) -> poly64x1_t {
}
/// Load one single-element structure and Replicate to all lanes (of one register).
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_p64)
#[inline]
#[target_feature(enable = "neon,aes")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
@@ -3733,7 +3813,11 @@ pub unsafe fn vbicq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_s8(a: uint8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
- simd_select(transmute::<_, int8x8_t>(a), b, c)
+ let not = int8x8_t(-1, -1, -1, -1, -1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3747,7 +3831,11 @@ pub unsafe fn vbsl_s8(a: uint8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_s16(a: uint16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
- simd_select(transmute::<_, int16x4_t>(a), b, c)
+ let not = int16x4_t(-1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3761,7 +3849,11 @@ pub unsafe fn vbsl_s16(a: uint16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_s32(a: uint32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
- simd_select(transmute::<_, int32x2_t>(a), b, c)
+ let not = int32x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3775,7 +3867,11 @@ pub unsafe fn vbsl_s32(a: uint32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_s64(a: uint64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t {
- simd_select(transmute::<_, int64x1_t>(a), b, c)
+ let not = int64x1_t(-1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3789,7 +3885,11 @@ pub unsafe fn vbsl_s64(a: uint64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
- simd_select(transmute::<_, int8x8_t>(a), b, c)
+ let not = int8x8_t(-1, -1, -1, -1, -1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3803,7 +3903,11 @@ pub unsafe fn vbsl_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_t {
- simd_select(transmute::<_, int16x4_t>(a), b, c)
+ let not = int16x4_t(-1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3817,7 +3921,11 @@ pub unsafe fn vbsl_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_t {
- simd_select(transmute::<_, int32x2_t>(a), b, c)
+ let not = int32x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3831,7 +3939,11 @@ pub unsafe fn vbsl_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_u64(a: uint64x1_t, b: uint64x1_t, c: uint64x1_t) -> uint64x1_t {
- simd_select(transmute::<_, int64x1_t>(a), b, c)
+ let not = int64x1_t(-1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3845,7 +3957,11 @@ pub unsafe fn vbsl_u64(a: uint64x1_t, b: uint64x1_t, c: uint64x1_t) -> uint64x1_
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_f32(a: uint32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t {
- simd_select(transmute::<_, int32x2_t>(a), b, c)
+ let not = int32x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3859,7 +3975,11 @@ pub unsafe fn vbsl_f32(a: uint32x2_t, b: float32x2_t, c: float32x2_t) -> float32
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_p8(a: uint8x8_t, b: poly8x8_t, c: poly8x8_t) -> poly8x8_t {
- simd_select(transmute::<_, int8x8_t>(a), b, c)
+ let not = int8x8_t(-1, -1, -1, -1, -1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select.
@@ -3873,7 +3993,11 @@ pub unsafe fn vbsl_p8(a: uint8x8_t, b: poly8x8_t, c: poly8x8_t) -> poly8x8_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbsl_p16(a: uint16x4_t, b: poly16x4_t, c: poly16x4_t) -> poly16x4_t {
- simd_select(transmute::<_, int16x4_t>(a), b, c)
+ let not = int16x4_t(-1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3887,7 +4011,13 @@ pub unsafe fn vbsl_p16(a: uint16x4_t, b: poly16x4_t, c: poly16x4_t) -> poly16x4_
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_s8(a: uint8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
- simd_select(transmute::<_, int8x16_t>(a), b, c)
+ let not = int8x16_t(
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ );
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3901,7 +4031,11 @@ pub unsafe fn vbslq_s8(a: uint8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_s16(a: uint16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
- simd_select(transmute::<_, int16x8_t>(a), b, c)
+ let not = int16x8_t(-1, -1, -1, -1, -1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3915,7 +4049,11 @@ pub unsafe fn vbslq_s16(a: uint16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_s32(a: uint32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
- simd_select(transmute::<_, int32x4_t>(a), b, c)
+ let not = int32x4_t(-1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3929,7 +4067,11 @@ pub unsafe fn vbslq_s32(a: uint32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_s64(a: uint64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t {
- simd_select(transmute::<_, int64x2_t>(a), b, c)
+ let not = int64x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3943,7 +4085,13 @@ pub unsafe fn vbslq_s64(a: uint64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
- simd_select(transmute::<_, int8x16_t>(a), b, c)
+ let not = int8x16_t(
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ );
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3957,7 +4105,11 @@ pub unsafe fn vbslq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
- simd_select(transmute::<_, int16x8_t>(a), b, c)
+ let not = int16x8_t(-1, -1, -1, -1, -1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3971,7 +4123,11 @@ pub unsafe fn vbslq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
- simd_select(transmute::<_, int32x4_t>(a), b, c)
+ let not = int32x4_t(-1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3985,7 +4141,11 @@ pub unsafe fn vbslq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_t {
- simd_select(transmute::<_, int64x2_t>(a), b, c)
+ let not = int64x2_t(-1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -3999,7 +4159,13 @@ pub unsafe fn vbslq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_p8(a: uint8x16_t, b: poly8x16_t, c: poly8x16_t) -> poly8x16_t {
- simd_select(transmute::<_, int8x16_t>(a), b, c)
+ let not = int8x16_t(
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ );
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -4013,7 +4179,11 @@ pub unsafe fn vbslq_p8(a: uint8x16_t, b: poly8x16_t, c: poly8x16_t) -> poly8x16_
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_p16(a: uint16x8_t, b: poly16x8_t, c: poly16x8_t) -> poly16x8_t {
- simd_select(transmute::<_, int16x8_t>(a), b, c)
+ let not = int16x8_t(-1, -1, -1, -1, -1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Bitwise Select. (128-bit)
@@ -4027,7 +4197,11 @@ pub unsafe fn vbslq_p16(a: uint16x8_t, b: poly16x8_t, c: poly16x8_t) -> poly16x8
stable(feature = "neon_intrinsics", since = "1.59.0")
)]
pub unsafe fn vbslq_f32(a: uint32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t {
- simd_select(transmute::<_, int32x4_t>(a), b, c)
+ let not = int32x4_t(-1, -1, -1, -1);
+ transmute(simd_or(
+ simd_and(a, transmute(b)),
+ simd_and(simd_xor(a, transmute(not)), transmute(c)),
+ ))
}
/// Vector bitwise inclusive OR NOT
@@ -9206,7 +9380,7 @@ mod tests {
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_s8() {
- let a = u8x8::new(u8::MAX, 0, u8::MAX, 0, u8::MAX, 0, u8::MAX, 0);
+ let a = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, 0, u8::MAX, 0);
let b = i8x8::new(
i8::MAX,
i8::MAX,
@@ -9229,9 +9403,9 @@ mod tests {
);
let e = i8x8::new(
i8::MAX,
- i8::MIN,
+ i8::MIN | 1,
i8::MAX,
- i8::MIN,
+ i8::MIN | 2,
i8::MAX,
i8::MIN,
i8::MAX,
@@ -9242,34 +9416,34 @@ mod tests {
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_s16() {
- let a = u16x4::new(u16::MAX, 0, u16::MAX, 0);
+ let a = u16x4::new(u16::MAX, 0, 1, 2);
let b = i16x4::new(i16::MAX, i16::MAX, i16::MAX, i16::MAX);
let c = i16x4::new(i16::MIN, i16::MIN, i16::MIN, i16::MIN);
- let e = i16x4::new(i16::MAX, i16::MIN, i16::MAX, i16::MIN);
+ let e = i16x4::new(i16::MAX, i16::MIN, i16::MIN | 1, i16::MIN | 2);
let r: i16x4 = transmute(vbsl_s16(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_s32() {
- let a = u32x2::new(u32::MAX, u32::MIN);
+ let a = u32x2::new(u32::MAX, 1);
let b = i32x2::new(i32::MAX, i32::MAX);
let c = i32x2::new(i32::MIN, i32::MIN);
- let e = i32x2::new(i32::MAX, i32::MIN);
+ let e = i32x2::new(i32::MAX, i32::MIN | 1);
let r: i32x2 = transmute(vbsl_s32(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_s64() {
- let a = u64x1::new(u64::MAX);
+ let a = u64x1::new(1);
let b = i64x1::new(i64::MAX);
let c = i64x1::new(i64::MIN);
- let e = i64x1::new(i64::MAX);
+ let e = i64x1::new(i64::MIN | 1);
let r: i64x1 = transmute(vbsl_s64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_u8() {
- let a = u8x8::new(u8::MAX, 0, u8::MAX, 0, u8::MAX, 0, u8::MAX, 0);
+ let a = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, 0, u8::MAX, 0);
let b = u8x8::new(
u8::MAX,
u8::MAX,
@@ -9290,58 +9464,49 @@ mod tests {
u8::MIN,
u8::MIN,
);
- let e = u8x8::new(
- u8::MAX,
- u8::MIN,
- u8::MAX,
- u8::MIN,
- u8::MAX,
- u8::MIN,
- u8::MAX,
- u8::MIN,
- );
+ let e = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, u8::MIN, u8::MAX, u8::MIN);
let r: u8x8 = transmute(vbsl_u8(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_u16() {
- let a = u16x4::new(u16::MAX, 0, u16::MAX, 0);
+ let a = u16x4::new(u16::MAX, 0, 1, 2);
let b = u16x4::new(u16::MAX, u16::MAX, u16::MAX, u16::MAX);
let c = u16x4::new(u16::MIN, u16::MIN, u16::MIN, u16::MIN);
- let e = u16x4::new(u16::MAX, u16::MIN, u16::MAX, u16::MIN);
+ let e = u16x4::new(u16::MAX, 0, 1, 2);
let r: u16x4 = transmute(vbsl_u16(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_u32() {
- let a = u32x2::new(u32::MAX, 0);
+ let a = u32x2::new(u32::MAX, 2);
let b = u32x2::new(u32::MAX, u32::MAX);
let c = u32x2::new(u32::MIN, u32::MIN);
- let e = u32x2::new(u32::MAX, u32::MIN);
+ let e = u32x2::new(u32::MAX, 2);
let r: u32x2 = transmute(vbsl_u32(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_u64() {
- let a = u64x1::new(u64::MAX);
+ let a = u64x1::new(2);
let b = u64x1::new(u64::MAX);
let c = u64x1::new(u64::MIN);
- let e = u64x1::new(u64::MAX);
+ let e = u64x1::new(2);
let r: u64x1 = transmute(vbsl_u64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_f32() {
- let a = u32x2::new(u32::MAX, 0);
- let b = f32x2::new(f32::MAX, f32::MAX);
- let c = f32x2::new(f32::MIN, f32::MIN);
- let e = f32x2::new(f32::MAX, f32::MIN);
+ let a = u32x2::new(1, 0x80000000);
+ let b = f32x2::new(8388609f32, -1.23f32);
+ let c = f32x2::new(2097152f32, 2.34f32);
+ let e = f32x2::new(2097152.25f32, -2.34f32);
let r: f32x2 = transmute(vbsl_f32(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_p8() {
- let a = u8x8::new(u8::MAX, 0, u8::MAX, 0, u8::MAX, 0, u8::MAX, 0);
+ let a = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, 0, u8::MAX, 0);
let b = u8x8::new(
u8::MAX,
u8::MAX,
@@ -9362,25 +9527,16 @@ mod tests {
u8::MIN,
u8::MIN,
);
- let e = u8x8::new(
- u8::MAX,
- u8::MIN,
- u8::MAX,
- u8::MIN,
- u8::MAX,
- u8::MIN,
- u8::MAX,
- u8::MIN,
- );
+ let e = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, u8::MIN, u8::MAX, u8::MIN);
let r: u8x8 = transmute(vbsl_p8(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbsl_p16() {
- let a = u16x4::new(u16::MAX, 0, u16::MAX, 0);
+ let a = u16x4::new(u16::MAX, 0, 1, 2);
let b = u16x4::new(u16::MAX, u16::MAX, u16::MAX, u16::MAX);
let c = u16x4::new(u16::MIN, u16::MIN, u16::MIN, u16::MIN);
- let e = u16x4::new(u16::MAX, u16::MIN, u16::MAX, u16::MIN);
+ let e = u16x4::new(u16::MAX, 0, 1, 2);
let r: u16x4 = transmute(vbsl_p16(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
@@ -9388,9 +9544,9 @@ mod tests {
unsafe fn test_vbslq_s8() {
let a = u8x16::new(
u8::MAX,
- 0,
+ 1,
u8::MAX,
- 0,
+ 2,
u8::MAX,
0,
u8::MAX,
@@ -9442,9 +9598,9 @@ mod tests {
);
let e = i8x16::new(
i8::MAX,
- i8::MIN,
+ i8::MIN | 1,
i8::MAX,
- i8::MIN,
+ i8::MIN | 2,
i8::MAX,
i8::MIN,
i8::MAX,
@@ -9463,7 +9619,7 @@ mod tests {
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_s16() {
- let a = u16x8::new(u16::MAX, 0, u16::MAX, 0, u16::MAX, 0, u16::MAX, 0);
+ let a = u16x8::new(u16::MAX, 1, u16::MAX, 2, u16::MAX, 0, u16::MAX, 0);
let b = i16x8::new(
i16::MAX,
i16::MAX,
@@ -9486,9 +9642,9 @@ mod tests {
);
let e = i16x8::new(
i16::MAX,
- i16::MIN,
+ i16::MIN | 1,
i16::MAX,
- i16::MIN,
+ i16::MIN | 2,
i16::MAX,
i16::MIN,
i16::MAX,
@@ -9499,19 +9655,19 @@ mod tests {
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_s32() {
- let a = u32x4::new(u32::MAX, 0, u32::MAX, 0);
+ let a = u32x4::new(u32::MAX, 1, u32::MAX, 2);
let b = i32x4::new(i32::MAX, i32::MAX, i32::MAX, i32::MAX);
let c = i32x4::new(i32::MIN, i32::MIN, i32::MIN, i32::MIN);
- let e = i32x4::new(i32::MAX, i32::MIN, i32::MAX, i32::MIN);
+ let e = i32x4::new(i32::MAX, i32::MIN | 1, i32::MAX, i32::MIN | 2);
let r: i32x4 = transmute(vbslq_s32(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_s64() {
- let a = u64x2::new(u64::MAX, 0);
+ let a = u64x2::new(u64::MAX, 1);
let b = i64x2::new(i64::MAX, i64::MAX);
let c = i64x2::new(i64::MIN, i64::MIN);
- let e = i64x2::new(i64::MAX, i64::MIN);
+ let e = i64x2::new(i64::MAX, i64::MIN | 1);
let r: i64x2 = transmute(vbslq_s64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
@@ -9519,9 +9675,9 @@ mod tests {
unsafe fn test_vbslq_u8() {
let a = u8x16::new(
u8::MAX,
- 0,
+ 1,
u8::MAX,
- 0,
+ 2,
u8::MAX,
0,
u8::MAX,
@@ -9573,9 +9729,9 @@ mod tests {
);
let e = u8x16::new(
u8::MAX,
- u8::MIN,
+ 1,
u8::MAX,
- u8::MIN,
+ 2,
u8::MAX,
u8::MIN,
u8::MAX,
@@ -9594,7 +9750,7 @@ mod tests {
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_u16() {
- let a = u16x8::new(u16::MAX, 0, u16::MAX, 0, u16::MAX, 0, u16::MAX, 0);
+ let a = u16x8::new(u16::MAX, 1, u16::MAX, 2, u16::MAX, 0, u16::MAX, 0);
let b = u16x8::new(
u16::MAX,
u16::MAX,
@@ -9617,9 +9773,9 @@ mod tests {
);
let e = u16x8::new(
u16::MAX,
- u16::MIN,
+ 1,
u16::MAX,
- u16::MIN,
+ 2,
u16::MAX,
u16::MIN,
u16::MAX,
@@ -9630,28 +9786,28 @@ mod tests {
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_u32() {
- let a = u32x4::new(u32::MAX, 0, u32::MAX, 0);
+ let a = u32x4::new(u32::MAX, 1, u32::MAX, 2);
let b = u32x4::new(u32::MAX, u32::MAX, u32::MAX, u32::MAX);
let c = u32x4::new(u32::MIN, u32::MIN, u32::MIN, u32::MIN);
- let e = u32x4::new(u32::MAX, u32::MIN, u32::MAX, u32::MIN);
+ let e = u32x4::new(u32::MAX, 1, u32::MAX, 2);
let r: u32x4 = transmute(vbslq_u32(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_u64() {
- let a = u64x2::new(u64::MAX, 0);
+ let a = u64x2::new(u64::MAX, 1);
let b = u64x2::new(u64::MAX, u64::MAX);
let c = u64x2::new(u64::MIN, u64::MIN);
- let e = u64x2::new(u64::MAX, u64::MIN);
+ let e = u64x2::new(u64::MAX, 1);
let r: u64x2 = transmute(vbslq_u64(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_f32() {
- let a = u32x4::new(u32::MAX, 0, u32::MAX, 0);
- let b = f32x4::new(f32::MAX, f32::MAX, f32::MAX, f32::MAX);
- let c = f32x4::new(f32::MIN, f32::MIN, f32::MIN, f32::MIN);
- let e = f32x4::new(f32::MAX, f32::MIN, f32::MAX, f32::MIN);
+ let a = u32x4::new(u32::MAX, 0, 1, 0x80000000);
+ let b = f32x4::new(-1.23f32, -1.23f32, 8388609f32, -1.23f32);
+ let c = f32x4::new(2.34f32, 2.34f32, 2097152f32, 2.34f32);
+ let e = f32x4::new(-1.23f32, 2.34f32, 2097152.25f32, -2.34f32);
let r: f32x4 = transmute(vbslq_f32(transmute(a), transmute(b), transmute(c)));
assert_eq!(r, e);
}
@@ -9659,9 +9815,9 @@ mod tests {
unsafe fn test_vbslq_p8() {
let a = u8x16::new(
u8::MAX,
- 0,
+ 1,
u8::MAX,
- 0,
+ 2,
u8::MAX,
0,
u8::MAX,
@@ -9713,9 +9869,9 @@ mod tests {
);
let e = u8x16::new(
u8::MAX,
- u8::MIN,
+ 1,
u8::MAX,
- u8::MIN,
+ 2,
u8::MAX,
u8::MIN,
u8::MAX,
@@ -9734,7 +9890,7 @@ mod tests {
}
#[simd_test(enable = "neon")]
unsafe fn test_vbslq_p16() {
- let a = u16x8::new(u16::MAX, 0, u16::MAX, 0, u16::MAX, 0, u16::MAX, 0);
+ let a = u16x8::new(u16::MAX, 1, u16::MAX, 2, u16::MAX, 0, u16::MAX, 0);
let b = u16x8::new(
u16::MAX,
u16::MAX,
@@ -9757,9 +9913,9 @@ mod tests {
);
let e = u16x8::new(
u16::MAX,
- u16::MIN,
+ 1,
u16::MAX,
- u16::MIN,
+ 2,
u16::MAX,
u16::MIN,
u16::MAX,
diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs
index 8b2be39dc..70344c88b 100644
--- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs
+++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs
@@ -51,6 +51,8 @@ types! {
#[allow(improper_ctypes)]
extern "C" {
+ #[link_name = "llvm.ppc.altivec.lvx"]
+ fn lvx(p: *const i8) -> vector_unsigned_int;
#[link_name = "llvm.ppc.altivec.vperm"]
fn vperm(
a: vector_signed_int,
@@ -442,8 +444,7 @@ mod sealed {
#[inline(always)]
unsafe fn load(off: i32, p: *const i8) -> u32x4 {
let addr = p.offset(off as isize);
-
- *(addr as *const u32x4)
+ transmute(lvx(addr))
}
pub trait VectorLd {
diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs
index 081609ece..24f9c0301 100644
--- a/library/stdarch/crates/core_arch/src/x86/avx2.rs
+++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs
@@ -1195,7 +1195,7 @@ pub unsafe fn _mm_mask_i32gather_epi64<const SCALE: i32>(
/// Returns values from `slice` at offsets determined by `offsets * scale`,
/// where
-/// `scale` should be 1, 2, 4 and 8.
+/// `scale` should be 1, 2, 4 or 8.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_i32gather_epi64)
#[inline]
diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs
index 47d565cea..49d78ed60 100644
--- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs
+++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs
@@ -8545,9 +8545,6 @@ pub unsafe fn _mm_movm_epi8(k: __mmask16) -> __m128i {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kadd_mask32&expand=3207)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(all(test, target_arch = "x86"), assert_instr(add))]
-#[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(lea))] // generate normal lea/add code instead of kaddd
- //llvm.x86.avx512.kadd.d
pub unsafe fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
transmute(a + b)
}
@@ -8557,9 +8554,6 @@ pub unsafe fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kadd_mask64&expand=3208)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(all(test, target_arch = "x86"), assert_instr(add))]
-#[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(lea))] // generate normal lea/add code instead of kaddd
- //llvm.x86.avx512.kadd.d
pub unsafe fn _kadd_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
transmute(a + b)
}
@@ -8569,7 +8563,6 @@ pub unsafe fn _kadd_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kand_mask32&expand=3213)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(and))] // generate normal and code instead of kandd
pub unsafe fn _kand_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
transmute(a & b)
}
@@ -8579,7 +8572,6 @@ pub unsafe fn _kand_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kand_mask64&expand=3214)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(and))] // generate normal and code instead of kandq
pub unsafe fn _kand_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
transmute(a & b)
}
@@ -8607,7 +8599,6 @@ pub unsafe fn _knot_mask64(a: __mmask64) -> __mmask64 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kandn_mask32&expand=3219)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(not))] // generate normal and code instead of kandnd
pub unsafe fn _kandn_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
transmute(_knot_mask32(a) & b)
}
@@ -8617,7 +8608,6 @@ pub unsafe fn _kandn_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kandn_mask64&expand=3220)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(not))] // generate normal and code instead of kandnq
pub unsafe fn _kandn_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
transmute(_knot_mask64(a) & b)
}
@@ -8627,7 +8617,6 @@ pub unsafe fn _kandn_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kor_mask32&expand=3240)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(or))] // generate normal and code instead of kord
pub unsafe fn _kor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
transmute(a | b)
}
@@ -8637,7 +8626,6 @@ pub unsafe fn _kor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kor_mask64&expand=3241)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(or))] // generate normal and code instead of korq
pub unsafe fn _kor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
transmute(a | b)
}
@@ -8647,7 +8635,6 @@ pub unsafe fn _kor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kxor_mask32&expand=3292)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(xor))] // generate normal and code instead of kxord
pub unsafe fn _kxor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
transmute(a ^ b)
}
@@ -8657,7 +8644,6 @@ pub unsafe fn _kxor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kxor_mask64&expand=3293)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(xor))] // generate normal and code instead of kxorq
pub unsafe fn _kxor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
transmute(a ^ b)
}
@@ -8667,7 +8653,6 @@ pub unsafe fn _kxor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kxnor_mask32&expand=3286)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(xor))] // generate normal and code instead of kxnord
pub unsafe fn _kxnor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
transmute(_knot_mask32(a ^ b))
}
@@ -8677,7 +8662,6 @@ pub unsafe fn _kxnor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 {
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_kxnor_mask64&expand=3287)
#[inline]
#[target_feature(enable = "avx512bw")]
-#[cfg_attr(test, assert_instr(xor))] // generate normal and code instead of kxnorq
pub unsafe fn _kxnor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 {
transmute(_knot_mask64(a ^ b))
}
diff --git a/library/stdarch/crates/core_arch/src/x86/avx512gfni.rs b/library/stdarch/crates/core_arch/src/x86/avx512gfni.rs
index d8ac5c29c..66fd1c2e1 100644
--- a/library/stdarch/crates/core_arch/src/x86/avx512gfni.rs
+++ b/library/stdarch/crates/core_arch/src/x86/avx512gfni.rs
@@ -829,21 +829,21 @@ mod tests {
#[target_feature(enable = "sse2")]
unsafe fn load_m128i_word<T>(data: &[T], word_index: usize) -> __m128i {
let byte_offset = word_index * 16 / size_of::<T>();
- let pointer = data.as_ptr().offset(byte_offset as isize) as *const __m128i;
+ let pointer = data.as_ptr().add(byte_offset) as *const __m128i;
_mm_loadu_si128(black_box(pointer))
}
#[target_feature(enable = "avx")]
unsafe fn load_m256i_word<T>(data: &[T], word_index: usize) -> __m256i {
let byte_offset = word_index * 32 / size_of::<T>();
- let pointer = data.as_ptr().offset(byte_offset as isize) as *const __m256i;
+ let pointer = data.as_ptr().add(byte_offset) as *const __m256i;
_mm256_loadu_si256(black_box(pointer))
}
#[target_feature(enable = "avx512f")]
unsafe fn load_m512i_word<T>(data: &[T], word_index: usize) -> __m512i {
let byte_offset = word_index * 64 / size_of::<T>();
- let pointer = data.as_ptr().offset(byte_offset as isize) as *const i32;
+ let pointer = data.as_ptr().add(byte_offset) as *const i32;
_mm512_loadu_si512(black_box(pointer))
}
diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs
index 2c4295ef6..03c3a14a5 100644
--- a/library/stdarch/crates/core_arch/src/x86/sse.rs
+++ b/library/stdarch/crates/core_arch/src/x86/sse.rs
@@ -1185,9 +1185,9 @@ pub unsafe fn _mm_loadu_ps(p: *const f32) -> __m128 {
///
/// ```text
/// let a0 = *p;
-/// let a1 = *p.offset(1);
-/// let a2 = *p.offset(2);
-/// let a3 = *p.offset(3);
+/// let a1 = *p.add(1);
+/// let a2 = *p.add(2);
+/// let a3 = *p.add(3);
/// __m128::new(a3, a2, a1, a0)
/// ```
///
@@ -1241,9 +1241,9 @@ pub unsafe fn _mm_store_ss(p: *mut f32, a: __m128) {
/// ```text
/// let x = a.extract(0);
/// *p = x;
-/// *p.offset(1) = x;
-/// *p.offset(2) = x;
-/// *p.offset(3) = x;
+/// *p.add(1) = x;
+/// *p.add(2) = x;
+/// *p.add(3) = x;
/// ```
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps)
@@ -1317,9 +1317,9 @@ pub unsafe fn _mm_storeu_ps(p: *mut f32, a: __m128) {
///
/// ```text
/// *p = a.extract(3);
-/// *p.offset(1) = a.extract(2);
-/// *p.offset(2) = a.extract(1);
-/// *p.offset(3) = a.extract(0);
+/// *p.add(1) = a.extract(2);
+/// *p.add(2) = a.extract(1);
+/// *p.add(3) = a.extract(0);
/// ```
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps)
@@ -3006,9 +3006,9 @@ mod tests {
let unalignment = (p as usize) & 0xf;
if unalignment != 0 {
- let delta = ((16 - unalignment) >> 2) as isize;
+ let delta = (16 - unalignment) >> 2;
fixup = delta as f32;
- p = p.offset(delta);
+ p = p.add(delta);
}
let r = _mm_load_ps(p);
@@ -3019,7 +3019,7 @@ mod tests {
#[simd_test(enable = "sse")]
unsafe fn test_mm_loadu_ps() {
let vals = &[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
- let p = vals.as_ptr().offset(3);
+ let p = vals.as_ptr().add(3);
let r = _mm_loadu_ps(black_box(p));
assert_eq_m128(r, _mm_setr_ps(4.0, 5.0, 6.0, 7.0));
}
@@ -3036,9 +3036,9 @@ mod tests {
let unalignment = (p as usize) & 0xf;
if unalignment != 0 {
- let delta = ((16 - unalignment) >> 2) as isize;
+ let delta = (16 - unalignment) >> 2;
fixup = delta as f32;
- p = p.offset(delta);
+ p = p.add(delta);
}
let r = _mm_loadr_ps(p);
@@ -3057,7 +3057,7 @@ mod tests {
unsafe fn test_mm_store_ss() {
let mut vals = [0.0f32; 8];
let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
- _mm_store_ss(vals.as_mut_ptr().offset(1), a);
+ _mm_store_ss(vals.as_mut_ptr().add(1), a);
assert_eq!(vals[0], 0.0);
assert_eq!(vals[1], 1.0);
@@ -3152,7 +3152,7 @@ mod tests {
// Make sure p is **not** aligned to 16-byte boundary
if (p as usize) & 0xf == 0 {
ofs = 1;
- p = p.offset(1);
+ p = p.add(1);
}
_mm_storeu_ps(p, *black_box(&a));
diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs
index 5a9120042..d82b8641f 100644
--- a/library/stdarch/crates/core_arch/src/x86/sse2.rs
+++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs
@@ -4518,7 +4518,7 @@ mod tests {
// Make sure p is **not** aligned to 16-byte boundary
if (p as usize) & 0xf == 0 {
ofs = 1;
- p = p.offset(1);
+ p = p.add(1);
}
_mm_storeu_pd(p, *black_box(&a));
@@ -4606,7 +4606,7 @@ mod tests {
let mut offset = 0;
if (d as usize) & 0xf == 0 {
offset = 1;
- d = d.offset(offset as isize);
+ d = d.add(offset);
}
let r = _mm_loadu_pd(d);
diff --git a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
index 391daed20..a262932af 100644
--- a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
+++ b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
@@ -34,11 +34,11 @@ use stdarch_test::assert_instr;
/// support `cmpxchg16b` and the program enters an execution path that
/// eventually would reach this function the behavior is undefined.
///
-/// The `success` ordering must also be stronger or equal to `failure`, or this
-/// function call is undefined. See the `Atomic*` documentation's
-/// `compare_exchange` function for more information. When `compare_exchange`
-/// panics, this is undefined behavior. Currently this function aborts the
-/// process with an undefined instruction.
+/// The failure ordering must be [`Ordering::SeqCst`], [`Ordering::Acquire`] or
+/// [`Ordering::Relaxed`], or this function call is undefined. See the `Atomic*`
+/// documentation's `compare_exchange` function for more information. When
+/// `compare_exchange` panics, this is undefined behavior. Currently this
+/// function aborts the process with an undefined instruction.
#[inline]
#[cfg_attr(test, assert_instr(cmpxchg16b, success = Ordering::SeqCst, failure = Ordering::SeqCst))]
#[target_feature(enable = "cmpxchg16b")]
@@ -54,15 +54,21 @@ pub unsafe fn cmpxchg16b(
debug_assert!(dst as usize % 16 == 0);
let (val, _ok) = match (success, failure) {
- (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
- (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
- (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
- (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
- (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
- (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
- (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
- (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
- (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
+ (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
+ (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
+ (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
+ (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
+ (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
+ (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
+ (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
+ (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
+ (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
+ (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
+ (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
+ (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
+ (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
+ (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
+ (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
// The above block is all copied from libcore, and this statement is
// also copied from libcore except that it's a panic in libcore and we
diff --git a/library/stdarch/crates/intrinsic-test/missing_aarch64.txt b/library/stdarch/crates/intrinsic-test/missing_aarch64.txt
index 56ec274b5..93fc126e5 100644
--- a/library/stdarch/crates/intrinsic-test/missing_aarch64.txt
+++ b/library/stdarch/crates/intrinsic-test/missing_aarch64.txt
@@ -67,20 +67,6 @@ vrnd64xq_f64
vrnd64z_f64
vrnd64zq_f64
-# Takes too long to compile tests
-vcopyq_laneq_u8
-vcopyq_laneq_s8
-vcopyq_laneq_p8
-vcopyq_lane_u8
-vcopyq_lane_s8
-vcopyq_lane_p8
-vcopy_laneq_u8
-vcopy_laneq_s8
-vcopy_laneq_p8
-vcopy_lane_u8
-vcopy_lane_s8
-vcopy_lane_p8
-
# QEMU 6.0 doesn't support these instructions
vmmlaq_s32
vmmlaq_u32
diff --git a/library/stdarch/crates/intrinsic-test/src/argument.rs b/library/stdarch/crates/intrinsic-test/src/argument.rs
index f4cb77992..798854c03 100644
--- a/library/stdarch/crates/intrinsic-test/src/argument.rs
+++ b/library/stdarch/crates/intrinsic-test/src/argument.rs
@@ -1,6 +1,6 @@
use std::ops::Range;
-use crate::types::IntrinsicType;
+use crate::types::{IntrinsicType, TypeKind};
use crate::Language;
/// An argument for the intrinsic.
@@ -90,49 +90,108 @@ impl ArgumentList {
.join(", ")
}
- /// Creates a line that initializes this argument for C code.
- /// e.g. `int32x2_t a = { 0x1, 0x2 };`
- pub fn init_random_values_c(&self, pass: usize) -> String {
+ /// Creates a line for each argument that initializes an array for C from which `loads` argument
+ /// values can be loaded as a sliding window.
+ /// e.g `const int32x2_t a_vals = {0x3effffff, 0x3effffff, 0x3f7fffff}`, if loads=2.
+ pub fn gen_arglists_c(&self, loads: u32) -> String {
self.iter()
.filter_map(|arg| {
(!arg.has_constraint()).then(|| {
format!(
- "{ty} {name} = {{ {values} }};",
- ty = arg.to_c_type(),
+ "const {ty} {name}_vals[] = {{ {values} }};",
+ ty = arg.ty.c_scalar_type(),
name = arg.name,
- values = arg.ty.populate_random(pass, &Language::C)
+ values = arg.ty.populate_random(loads, &Language::C)
)
})
})
.collect::<Vec<_>>()
- .join("\n ")
+ .join("\n")
}
- /// Creates a line that initializes this argument for Rust code.
- /// e.g. `let a = transmute([0x1, 0x2]);`
- pub fn init_random_values_rust(&self, pass: usize) -> String {
+ /// Creates a line for each argument that initializes an array for Rust from which `loads` argument
+ /// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20] = [...];`
+ pub fn gen_arglists_rust(&self, loads: u32) -> String {
self.iter()
.filter_map(|arg| {
(!arg.has_constraint()).then(|| {
- if arg.is_simd() {
- format!(
- "let {name} = ::std::mem::transmute([{values}]);",
- name = arg.name,
- values = arg.ty.populate_random(pass, &Language::Rust),
- )
- } else {
- format!(
- "let {name} = {value};",
- name = arg.name,
- value = arg.ty.populate_random(pass, &Language::Rust)
- )
- }
+ format!(
+ "const {upper_name}_VALS: [{ty}; {load_size}] = unsafe{{ [{values}] }};",
+ upper_name = arg.name.to_uppercase(),
+ ty = arg.ty.rust_scalar_type(),
+ load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1,
+ values = arg.ty.populate_random(loads, &Language::Rust)
+ )
+ })
+ })
+ .collect::<Vec<_>>()
+ .join("\n")
+ }
+
+ /// Creates a line for each argument that initalizes the argument from an array [arg]_vals at
+ /// an offset i using a load intrinsic, in C.
+ /// e.g `uint8x8_t a = vld1_u8(&a_vals[i]);`
+ pub fn load_values_c(&self, p64_armv7_workaround: bool) -> String {
+ self.iter()
+ .filter_map(|arg| {
+ // The ACLE doesn't support 64-bit polynomial loads on Armv7
+ // This and the cast are a workaround for this
+ let armv7_p64 = if let TypeKind::Poly = arg.ty.kind() {
+ p64_armv7_workaround
+ } else {
+ false
+ };
+
+ (!arg.has_constraint()).then(|| {
+ format!(
+ "{ty} {name} = {open_cast}{load}(&{name}_vals[i]){close_cast};",
+ ty = arg.to_c_type(),
+ name = arg.name,
+ load = if arg.is_simd() {
+ arg.ty.get_load_function(p64_armv7_workaround)
+ } else {
+ "*".to_string()
+ },
+ open_cast = if armv7_p64 {
+ format!("cast<{}>(", arg.to_c_type())
+ } else {
+ "".to_string()
+ },
+ close_cast = if armv7_p64 {
+ ")".to_string()
+ } else {
+ "".to_string()
+ }
+ )
})
})
.collect::<Vec<_>>()
.join("\n ")
}
+ /// Creates a line for each argument that initalizes the argument from array [ARG]_VALS at
+ /// an offset i using a load intrinsic, in Rust.
+ /// e.g `let a = vld1_u8(A_VALS.as_ptr().offset(i));`
+ pub fn load_values_rust(&self) -> String {
+ self.iter()
+ .filter_map(|arg| {
+ (!arg.has_constraint()).then(|| {
+ format!(
+ "let {name} = {load}({upper_name}_VALS.as_ptr().offset(i));",
+ name = arg.name,
+ upper_name = arg.name.to_uppercase(),
+ load = if arg.is_simd() {
+ arg.ty.get_load_function(false)
+ } else {
+ "*".to_string()
+ },
+ )
+ })
+ })
+ .collect::<Vec<_>>()
+ .join("\n ")
+ }
+
pub fn iter(&self) -> std::slice::Iter<'_, Argument> {
self.args.iter()
}
diff --git a/library/stdarch/crates/intrinsic-test/src/intrinsic.rs b/library/stdarch/crates/intrinsic-test/src/intrinsic.rs
index 2b7130440..e0645a36b 100644
--- a/library/stdarch/crates/intrinsic-test/src/intrinsic.rs
+++ b/library/stdarch/crates/intrinsic-test/src/intrinsic.rs
@@ -20,8 +20,9 @@ pub struct Intrinsic {
impl Intrinsic {
/// Generates a std::cout for the intrinsics results that will match the
- /// rust debug output format for the return type.
- pub fn print_result_c(&self, index: usize, additional: &str) -> String {
+ /// rust debug output format for the return type. The generated line assumes
+ /// there is an int i in scope which is the current pass number.
+ pub fn print_result_c(&self, additional: &str) -> String {
let lanes = if self.results.num_vectors() > 1 {
(0..self.results.num_vectors())
.map(|vector| {
@@ -72,7 +73,7 @@ impl Intrinsic {
};
format!(
- r#"std::cout << "Result {additional}-{idx}: {ty}" << std::fixed << std::setprecision(150) << {lanes} << "{close}" << std::endl;"#,
+ r#"std::cout << "Result {additional}-" << i+1 << ": {ty}" << std::fixed << std::setprecision(150) << {lanes} << "{close}" << std::endl;"#,
ty = if self.results.is_simd() {
format!("{}(", self.results.c_type())
} else {
@@ -81,11 +82,31 @@ impl Intrinsic {
close = if self.results.is_simd() { ")" } else { "" },
lanes = lanes,
additional = additional,
- idx = index,
)
}
- pub fn generate_pass_rust(&self, index: usize, additional: &str) -> String {
+ pub fn generate_loop_c(
+ &self,
+ additional: &str,
+ passes: u32,
+ p64_armv7_workaround: bool,
+ ) -> String {
+ format!(
+ r#" {{
+ for (int i=0; i<{passes}; i++) {{
+ {loaded_args}
+ auto __return_value = {intrinsic_call}({args});
+ {print_result}
+ }}
+ }}"#,
+ loaded_args = self.arguments.load_values_c(p64_armv7_workaround),
+ intrinsic_call = self.name,
+ args = self.arguments.as_call_param_c(),
+ print_result = self.print_result_c(additional)
+ )
+ }
+
+ pub fn generate_loop_rust(&self, additional: &str, passes: u32) -> String {
let constraints = self.arguments.as_constraint_parameters_rust();
let constraints = if !constraints.is_empty() {
format!("::<{}>", constraints)
@@ -94,32 +115,20 @@ impl Intrinsic {
};
format!(
- r#"
- unsafe {{
- {initialized_args}
- let res = {intrinsic_call}{const}({args});
- println!("Result {additional}-{idx}: {{:.150?}}", res);
- }}"#,
- initialized_args = self.arguments.init_random_values_rust(index),
- intrinsic_call = self.name,
- args = self.arguments.as_call_param_rust(),
- additional = additional,
- idx = index,
- const = constraints,
- )
- }
-
- pub fn generate_pass_c(&self, index: usize, additional: &str) -> String {
- format!(
r#" {{
- {initialized_args}
- auto __return_value = {intrinsic_call}({args});
- {print_result}
+ for i in 0..{passes} {{
+ unsafe {{
+ {loaded_args}
+ let __return_value = {intrinsic_call}{const}({args});
+ println!("Result {additional}-{{}}: {{:.150?}}", i+1, __return_value);
+ }}
+ }}
}}"#,
- initialized_args = self.arguments.init_random_values_c(index),
+ loaded_args = self.arguments.load_values_rust(),
intrinsic_call = self.name,
- args = self.arguments.as_call_param_c(),
- print_result = self.print_result_c(index, additional)
+ const = constraints,
+ args = self.arguments.as_call_param_rust(),
+ additional = additional,
)
}
}
diff --git a/library/stdarch/crates/intrinsic-test/src/main.rs b/library/stdarch/crates/intrinsic-test/src/main.rs
index 1b58da2fd..43f2df08b 100644
--- a/library/stdarch/crates/intrinsic-test/src/main.rs
+++ b/library/stdarch/crates/intrinsic-test/src/main.rs
@@ -23,13 +23,21 @@ mod intrinsic;
mod types;
mod values;
+// The number of times each intrinsic will be called.
+const PASSES: u32 = 20;
+
#[derive(Debug, PartialEq)]
pub enum Language {
Rust,
C,
}
-fn gen_code_c(intrinsic: &Intrinsic, constraints: &[&Argument], name: String) -> String {
+fn gen_code_c(
+ intrinsic: &Intrinsic,
+ constraints: &[&Argument],
+ name: String,
+ p64_armv7_workaround: bool,
+) -> String {
if let Some((current, constraints)) = constraints.split_last() {
let range = current
.constraints
@@ -47,19 +55,25 @@ fn gen_code_c(intrinsic: &Intrinsic, constraints: &[&Argument], name: String) ->
name = current.name,
ty = current.ty.c_type(),
val = i,
- pass = gen_code_c(intrinsic, constraints, format!("{}-{}", name, i))
+ pass = gen_code_c(
+ intrinsic,
+ constraints,
+ format!("{}-{}", name, i),
+ p64_armv7_workaround
+ )
)
})
.collect()
} else {
- (1..20)
- .map(|idx| intrinsic.generate_pass_c(idx, &name))
- .collect::<Vec<_>>()
- .join("\n")
+ intrinsic.generate_loop_c(&name, PASSES, p64_armv7_workaround)
}
}
-fn generate_c_program(header_files: &[&str], intrinsic: &Intrinsic) -> String {
+fn generate_c_program(
+ header_files: &[&str],
+ intrinsic: &Intrinsic,
+ p64_armv7_workaround: bool,
+) -> String {
let constraints = intrinsic
.arguments
.iter()
@@ -75,7 +89,7 @@ fn generate_c_program(header_files: &[&str], intrinsic: &Intrinsic) -> String {
template<typename T1, typename T2> T1 cast(T2 x) {{
static_assert(sizeof(T1) == sizeof(T2), "sizeof T1 and T2 must be the same");
- T1 ret = 0;
+ T1 ret{{}};
memcpy(&ret, &x, sizeof(T1));
return ret;
}}
@@ -95,6 +109,8 @@ std::ostream& operator<<(std::ostream& os, poly128_t value) {{
}}
#endif
+{arglists}
+
int main(int argc, char **argv) {{
{passes}
return 0;
@@ -104,7 +120,13 @@ int main(int argc, char **argv) {{
.map(|header| format!("#include <{}>", header))
.collect::<Vec<_>>()
.join("\n"),
- passes = gen_code_c(intrinsic, constraints.as_slice(), Default::default()),
+ arglists = intrinsic.arguments.gen_arglists_c(PASSES),
+ passes = gen_code_c(
+ intrinsic,
+ constraints.as_slice(),
+ Default::default(),
+ p64_armv7_workaround
+ ),
)
}
@@ -131,10 +153,7 @@ fn gen_code_rust(intrinsic: &Intrinsic, constraints: &[&Argument], name: String)
})
.collect()
} else {
- (1..20)
- .map(|idx| intrinsic.generate_pass_rust(idx, &name))
- .collect::<Vec<_>>()
- .join("\n")
+ intrinsic.generate_loop_rust(&name, PASSES)
}
}
@@ -153,11 +172,14 @@ fn generate_rust_program(intrinsic: &Intrinsic, a32: bool) -> String {
#![allow(non_upper_case_globals)]
use core_arch::arch::{target_arch}::*;
+{arglists}
+
fn main() {{
{passes}
}}
"#,
target_arch = if a32 { "arm" } else { "aarch64" },
+ arglists = intrinsic.arguments.gen_arglists_rust(PASSES),
passes = gen_code_rust(intrinsic, &constraints, Default::default())
)
}
@@ -203,7 +225,7 @@ fn build_c(intrinsics: &Vec<Intrinsic>, compiler: &str, a32: bool) -> bool {
let c_filename = format!(r#"c_programs/{}.cpp"#, i.name);
let mut file = File::create(&c_filename).unwrap();
- let c_code = generate_c_program(&["arm_neon.h", "arm_acle.h"], &i);
+ let c_code = generate_c_program(&["arm_neon.h", "arm_acle.h"], &i, a32);
file.write_all(c_code.into_bytes().as_slice()).unwrap();
compile_c(&c_filename, &i, compiler, a32)
})
@@ -259,7 +281,7 @@ path = "{intrinsic}/main.rs""#,
.current_dir("rust_programs")
.arg("-c")
.arg(format!(
- "cargo {toolchain} build --target {target}",
+ "cargo {toolchain} build --target {target} --release",
toolchain = toolchain,
target = if a32 {
"armv7-unknown-linux-gnueabihf"
@@ -407,7 +429,7 @@ fn compare_outputs(intrinsics: &Vec<Intrinsic>, toolchain: &str, runner: &str, a
.current_dir("rust_programs")
.arg("-c")
.arg(format!(
- "cargo {toolchain} run --target {target} --bin {intrinsic}",
+ "cargo {toolchain} run --target {target} --bin {intrinsic} --release",
intrinsic = intrinsic.name,
toolchain = toolchain,
target = if a32 {
diff --git a/library/stdarch/crates/intrinsic-test/src/types.rs b/library/stdarch/crates/intrinsic-test/src/types.rs
index e51e61649..dd23586e7 100644
--- a/library/stdarch/crates/intrinsic-test/src/types.rs
+++ b/library/stdarch/crates/intrinsic-test/src/types.rs
@@ -1,7 +1,7 @@
use std::fmt;
use std::str::FromStr;
-use crate::values::values_for_pass;
+use crate::values::value_for_array;
use crate::Language;
#[derive(Debug, PartialEq, Copy, Clone)]
@@ -160,8 +160,7 @@ impl IntrinsicType {
}
}
- #[allow(unused)]
- fn c_scalar_type(&self) -> String {
+ pub fn c_scalar_type(&self) -> String {
format!(
"{prefix}{bits}_t",
prefix = self.kind().c_prefix(),
@@ -169,7 +168,7 @@ impl IntrinsicType {
)
}
- fn rust_scalar_type(&self) -> String {
+ pub fn rust_scalar_type(&self) -> String {
format!(
"{prefix}{bits}",
prefix = self.kind().rust_prefix(),
@@ -289,18 +288,19 @@ impl IntrinsicType {
}
}
- /// Generates a comma list of values that can be used to initialize an
- /// argument for the intrinsic call.
+ /// Generates a comma list of values that can be used to initialize the array that
+ /// an argument for the intrinsic call is loaded from.
/// This is determistic based on the pass number.
///
- /// * `pass`: The pass index, i.e. the iteration index for the call to an intrinsic
+ /// * `loads`: The number of values that need to be loaded from the argument array
+ /// * e.g for argument type uint32x2, loads=2 results in a string representing 4 32-bit values
///
/// Returns a string such as
/// * `0x1, 0x7F, 0xFF` if `language` is `Language::C`
/// * `0x1 as _, 0x7F as _, 0xFF as _` if `language` is `Language::Rust`
- pub fn populate_random(&self, pass: usize, language: &Language) -> String {
+ pub fn populate_random(&self, loads: u32, language: &Language) -> String {
match self {
- IntrinsicType::Ptr { child, .. } => child.populate_random(pass, language),
+ IntrinsicType::Ptr { child, .. } => child.populate_random(loads, language),
IntrinsicType::Type {
bit_len: Some(bit_len),
kind,
@@ -308,11 +308,11 @@ impl IntrinsicType {
vec_len,
..
} if kind == &TypeKind::Int || kind == &TypeKind::UInt || kind == &TypeKind::Poly => (0
- ..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1)))
+ ..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1))
.map(|i| {
format!(
"{}{}",
- values_for_pass(*bit_len, i, pass),
+ value_for_array(*bit_len, i),
match language {
&Language::Rust => format!(" as {ty} ", ty = self.rust_scalar_type()),
&Language::C => String::from(""),
@@ -327,15 +327,15 @@ impl IntrinsicType {
simd_len,
vec_len,
..
- } => (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1)))
+ } => (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1))
.map(|i| {
format!(
"{}({})",
match language {
- &Language::Rust => "f32::from_bits",
+ &Language::Rust => "std::mem::transmute",
&Language::C => "cast<float, uint32_t>",
},
- values_for_pass(32, i, pass),
+ value_for_array(32, i),
)
})
.collect::<Vec<_>>()
@@ -346,15 +346,15 @@ impl IntrinsicType {
simd_len,
vec_len,
..
- } => (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1)))
+ } => (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1))
.map(|i| {
format!(
"{}({}{})",
match language {
- &Language::Rust => "f64::from_bits",
+ &Language::Rust => "std::mem::transmute",
&Language::C => "cast<double, uint64_t>",
},
- values_for_pass(64, i, pass),
+ value_for_array(64, i),
match language {
&Language::Rust => " as u64",
&Language::C => "",
@@ -368,10 +368,9 @@ impl IntrinsicType {
}
/// Determines the load function for this type.
- #[allow(unused)]
- pub fn get_load_function(&self) -> String {
+ pub fn get_load_function(&self, armv7_p64_workaround: bool) -> String {
match self {
- IntrinsicType::Ptr { child, .. } => child.get_load_function(),
+ IntrinsicType::Ptr { child, .. } => child.get_load_function(armv7_p64_workaround),
IntrinsicType::Type {
kind: k,
bit_len: Some(bl),
@@ -379,7 +378,7 @@ impl IntrinsicType {
vec_len,
..
} => {
- let quad = if (simd_len.unwrap_or(1) * bl) > 64 {
+ let quad = if simd_len.unwrap_or(1) * bl > 64 {
"q"
} else {
""
@@ -390,7 +389,8 @@ impl IntrinsicType {
TypeKind::UInt => "u",
TypeKind::Int => "s",
TypeKind::Float => "f",
- TypeKind::Poly => "p",
+ // The ACLE doesn't support 64-bit polynomial loads on Armv7
+ TypeKind::Poly => if armv7_p64_workaround && *bl == 64 {"s"} else {"p"},
x => todo!("get_load_function TypeKind: {:#?}", x),
},
size = bl,
diff --git a/library/stdarch/crates/intrinsic-test/src/values.rs b/library/stdarch/crates/intrinsic-test/src/values.rs
index 4565edca0..64b4d9fc9 100644
--- a/library/stdarch/crates/intrinsic-test/src/values.rs
+++ b/library/stdarch/crates/intrinsic-test/src/values.rs
@@ -1,9 +1,8 @@
-/// Gets a hex constant value for a single lane in in a determistic way
+/// Gets a hex constant value for a single value in the argument values array in a determistic way
/// * `bits`: The number of bits for the type, only 8, 16, 32, 64 are valid values
-/// * `simd`: The index of the simd lane we are generating for
-/// * `pass`: The index of the pass we are generating the values for
-pub fn values_for_pass(bits: u32, simd: u32, pass: usize) -> String {
- let index = pass + (simd as usize);
+/// * `index`: The position in the array we are generating for
+pub fn value_for_array(bits: u32, index: u32) -> String {
+ let index = index as usize;
if bits == 8 {
format!("{:#X}", VALUES_8[index % VALUES_8.len()])
diff --git a/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs
index f32f961ae..5f46c7696 100644
--- a/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs
@@ -72,7 +72,8 @@ features! {
@FEATURE: #[stable(feature = "simd_aarch64", since = "1.60.0")] pmull: "pmull";
/// FEAT_PMULL (Polynomial Multiply)
@FEATURE: #[stable(feature = "simd_aarch64", since = "1.60.0")] fp: "fp";
- /// FEAT_FP (Floating point support)
+ implied by target_features: ["neon"];
+ /// FEAT_FP (Floating point support) - Implied by `neon` target_feature
@FEATURE: #[stable(feature = "simd_aarch64", since = "1.60.0")] fp16: "fp16";
/// FEAT_FP16 (Half-float support)
@FEATURE: #[stable(feature = "simd_aarch64", since = "1.60.0")] sve: "sve";
diff --git a/library/stdarch/crates/std_detect/src/detect/macros.rs b/library/stdarch/crates/std_detect/src/detect/macros.rs
index 7548c9780..a467f9db6 100644
--- a/library/stdarch/crates/std_detect/src/detect/macros.rs
+++ b/library/stdarch/crates/std_detect/src/detect/macros.rs
@@ -1,3 +1,15 @@
+#[macro_export]
+#[allow_internal_unstable(stdsimd)]
+macro_rules! detect_feature {
+ ($feature:tt, $feature_lit:tt) => {
+ $crate::detect_feature!($feature, $feature_lit : $feature_lit)
+ };
+ ($feature:tt, $feature_lit:tt : $($target_feature_lit:tt),*) => {
+ $(cfg!(target_feature = $target_feature_lit) ||)*
+ $crate::detect::__is_feature_detected::$feature()
+ };
+}
+
#[allow(unused)]
macro_rules! features {
(
@@ -7,7 +19,9 @@ macro_rules! features {
@MACRO_ATTRS: $(#[$macro_attrs:meta])*
$(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; )*
$(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
- $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt; $(#[$feature_comment:meta])*)*
+ $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt;
+ $(implied by target_features: [$($target_feature_lit:tt),*];)?
+ $(#[$feature_comment:meta])*)*
) => {
#[macro_export]
$(#[$macro_attrs])*
@@ -17,12 +31,11 @@ macro_rules! features {
macro_rules! $macro_name {
$(
($feature_lit) => {
- cfg!(target_feature = $feature_lit) ||
- $crate::detect::__is_feature_detected::$feature()
+ $crate::detect_feature!($feature, $feature_lit $(: $($target_feature_lit),*)?)
};
)*
$(
- ($bind_feature) => { $macro_name!($feature_impl) };
+ ($bind_feature) => { $crate::$macro_name!($feature_impl) };
)*
$(
($nort_feature) => {
@@ -35,7 +48,7 @@ macro_rules! features {
};
)*
($t:tt,) => {
- $macro_name!($t);
+ $crate::$macro_name!($t);
};
($t:tt) => {
compile_error!(
@@ -66,7 +79,7 @@ macro_rules! features {
};
)*
$(
- ($bind_feature) => { $macro_name!($feature_impl) };
+ ($bind_feature) => { $crate::$macro_name!($feature_impl) };
)*
$(
($nort_feature) => {
@@ -79,7 +92,7 @@ macro_rules! features {
};
)*
($t:tt,) => {
- $macro_name!($t);
+ $crate::$macro_name!($t);
};
($t:tt) => {
compile_error!(
diff --git a/library/stdarch/crates/stdarch-gen/neon.spec b/library/stdarch/crates/stdarch-gen/neon.spec
index 68a50fbe9..95fbc354c 100644
--- a/library/stdarch/crates/stdarch-gen/neon.spec
+++ b/library/stdarch/crates/stdarch-gen/neon.spec
@@ -1570,10 +1570,10 @@ name = vext
constn = N
multi_fn = static_assert_imm-out_exp_len-N
multi_fn = matchn-out_exp_len-N, simd_shuffle-out_len-!, a, b, {asc-n-out_len}
-a = 0, 8, 8, 9, 8, 9, 9, 11, 8, 9, 9, 11, 9, 11, 14, 15
-b = 9, 11, 14, 15, 16, 17, 18, 19, 0, 8, 8, 9, 8, 9, 9, 11
-n = HFLEN
-validate 8, 9, 9, 11, 9, 11, 14, 15, 9, 11, 14, 15, 16, 17, 18, 19
+a = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+b = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+n = LEN_M1
+validate 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
arm = "vext.8"
aarch64 = ext
@@ -1584,10 +1584,10 @@ name = vext
constn = N
multi_fn = static_assert_imm-out_exp_len-N
multi_fn = matchn-out_exp_len-N, simd_shuffle-out_len-!, a, b, {asc-n-out_len}
-a = 0, 8, 8, 9, 8, 9, 9, 11, 8, 9, 9, 11, 9, 11, 14, 15
-b = 9, 11, 14, 15, 16, 17, 18, 19, 0, 8, 8, 9, 8, 9, 9, 11
-n = HFLEN
-validate 8, 9, 9, 11, 9, 11, 14, 15, 9, 11, 14, 15, 16, 17, 18, 19
+a = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+b = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+n = LEN_M1
+validate 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
aarch64 = ext
generate poly64x2_t
@@ -1600,10 +1600,10 @@ name = vext
constn = N
multi_fn = static_assert_imm-out_exp_len-N
multi_fn = matchn-out_exp_len-N, simd_shuffle-out_len-!, a, b, {asc-n-out_len}
-a = 0., 2., 2., 3.
-b = 3., 4., 5., 6.,
-n = HFLEN
-validate 2., 3., 3., 4.
+a = 1., 1., 1., 1.
+b = 2., 2., 2., 2.,
+n = LEN_M1
+validate 1., 2., 2., 2.
aarch64 = ext
generate float64x2_t
diff --git a/library/stdarch/crates/stdarch-gen/src/main.rs b/library/stdarch/crates/stdarch-gen/src/main.rs
index a2ae250a7..d2f865753 100644
--- a/library/stdarch/crates/stdarch-gen/src/main.rs
+++ b/library/stdarch/crates/stdarch-gen/src/main.rs
@@ -856,6 +856,40 @@ fn type_len_str(t: &str) -> &'static str {
}
}
+fn type_len_minus_one_str(t: &str) -> &'static str {
+ match t {
+ "int8x8_t" => "7",
+ "int8x16_t" => "15",
+ "int16x4_t" => "3",
+ "int16x8_t" => "7",
+ "int32x2_t" => "1",
+ "int32x4_t" => "3",
+ "int64x1_t" => "0",
+ "int64x2_t" => "1",
+ "uint8x8_t" => "7",
+ "uint8x16_t" => "15",
+ "uint16x4_t" => "3",
+ "uint16x8_t" => "7",
+ "uint32x2_t" => "1",
+ "uint32x4_t" => "3",
+ "uint64x1_t" => "0",
+ "uint64x2_t" => "1",
+ "float16x4_t" => "3",
+ "float16x8_t" => "7",
+ "float32x2_t" => "1",
+ "float32x4_t" => "3",
+ "float64x1_t" => "0",
+ "float64x2_t" => "1",
+ "poly8x8_t" => "7",
+ "poly8x16_t" => "15",
+ "poly16x4_t" => "3",
+ "poly16x8_t" => "7",
+ "poly64x1_t" => "0",
+ "poly64x2_t" => "1",
+ _ => panic!("unknown type: {}", t),
+ }
+}
+
fn type_half_len_str(t: &str) -> &'static str {
match t {
"int8x8_t" => "4",
@@ -901,6 +935,7 @@ fn map_val<'v>(t: &str, v: &'v str) -> &'v str {
"BITS_M1" => bits_minus_one(t),
"HFBITS" => half_bits(t),
"LEN" => type_len_str(t),
+ "LEN_M1" => type_len_minus_one_str(t),
"HFLEN" => type_half_len_str(t),
o => o,
}
@@ -971,6 +1006,15 @@ fn is_vstx(name: &str) -> bool {
&& (s[1].starts_with("s") || s[1].starts_with("f"))
}
+fn create_doc_string(comment_string: &str, fn_name: &str) -> String {
+ format!(
+ r#"{}
+///
+/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/{})"#,
+ comment_string, fn_name
+ )
+}
+
#[allow(clippy::too_many_arguments)]
fn gen_aarch64(
current_comment: &str,
@@ -1374,6 +1418,7 @@ fn gen_aarch64(
RDM => String::from("\n#[stable(feature = \"rdm_intrinsics\", since = \"1.62.0\")]"),
_ => String::new(),
};
+ let function_doc = create_doc_string(current_comment, &name);
let function = format!(
r#"
{}
@@ -1384,7 +1429,7 @@ fn gen_aarch64(
{}
}}
"#,
- current_comment,
+ function_doc,
current_target,
current_aarch64,
const_assert,
@@ -2342,6 +2387,7 @@ fn gen_arm(
RDM => String::from("\n#[stable(feature = \"rdm_intrinsics\", since = \"1.62.0\")]"),
_ => String::new(),
};
+ let function_doc = create_doc_string(current_comment, &name);
format!(
r#"
{}
@@ -2358,13 +2404,13 @@ fn gen_arm(
#[cfg_attr(test, assert_instr({}{}))]{}{}
{}
"#,
- current_comment,
+ function_doc,
current_target_arm,
expand_intrinsic(&current_arm, in_t[1]),
const_assert,
const_legacy,
call_arm,
- current_comment,
+ function_doc,
current_target_aarch64,
expand_intrinsic(&current_aarch64, in_t[1]),
const_assert,
@@ -2410,6 +2456,7 @@ fn gen_arm(
RDM => String::from("\n#[cfg_attr(target_arch = \"aarch64\", stable(feature = \"rdm_intrinsics\", since = \"1.62.0\"))]"),
_ => String::new(),
};
+ let function_doc = create_doc_string(current_comment, &name);
format!(
r#"
{}
@@ -2420,7 +2467,7 @@ fn gen_arm(
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr({}{}))]{}{}
{}
"#,
- current_comment,
+ function_doc,
current_target_aarch64,
current_target_arm,
expand_intrinsic(&current_arm, in_t[1]),
diff --git a/library/stdarch/examples/hex.rs b/library/stdarch/examples/hex.rs
index 812836d66..d982a71b9 100644
--- a/library/stdarch/examples/hex.rs
+++ b/library/stdarch/examples/hex.rs
@@ -76,7 +76,7 @@ unsafe fn hex_encode_avx2<'a>(mut src: &[u8], dst: &'a mut [u8]) -> Result<&'a s
let ascii_a = _mm256_set1_epi8((b'a' - 9 - 1) as i8);
let and4bits = _mm256_set1_epi8(0xf);
- let mut i = 0_isize;
+ let mut i = 0_usize;
while src.len() >= 32 {
let invec = _mm256_loadu_si256(src.as_ptr() as *const _);
@@ -96,18 +96,17 @@ unsafe fn hex_encode_avx2<'a>(mut src: &[u8], dst: &'a mut [u8]) -> Result<&'a s
let res2 = _mm256_unpackhi_epi8(masked2, masked1);
// Store everything into the right destination now
- let base = dst.as_mut_ptr().offset(i * 2);
- let base1 = base.offset(0) as *mut _;
- let base2 = base.offset(16) as *mut _;
- let base3 = base.offset(32) as *mut _;
- let base4 = base.offset(48) as *mut _;
+ let base = dst.as_mut_ptr().add(i * 2);
+ let base1 = base.add(0) as *mut _;
+ let base2 = base.add(16) as *mut _;
+ let base3 = base.add(32) as *mut _;
+ let base4 = base.add(48) as *mut _;
_mm256_storeu2_m128i(base3, base1, res1);
_mm256_storeu2_m128i(base4, base2, res2);
src = &src[32..];
i += 32;
}
- let i = i as usize;
let _ = hex_encode_sse41(src, &mut dst[i * 2..]);
Ok(str::from_utf8_unchecked(&dst[..src.len() * 2 + i * 2]))
@@ -122,7 +121,7 @@ unsafe fn hex_encode_sse41<'a>(mut src: &[u8], dst: &'a mut [u8]) -> Result<&'a
let ascii_a = _mm_set1_epi8((b'a' - 9 - 1) as i8);
let and4bits = _mm_set1_epi8(0xf);
- let mut i = 0_isize;
+ let mut i = 0_usize;
while src.len() >= 16 {
let invec = _mm_loadu_si128(src.as_ptr() as *const _);
@@ -141,13 +140,12 @@ unsafe fn hex_encode_sse41<'a>(mut src: &[u8], dst: &'a mut [u8]) -> Result<&'a
let res1 = _mm_unpacklo_epi8(masked2, masked1);
let res2 = _mm_unpackhi_epi8(masked2, masked1);
- _mm_storeu_si128(dst.as_mut_ptr().offset(i * 2) as *mut _, res1);
- _mm_storeu_si128(dst.as_mut_ptr().offset(i * 2 + 16) as *mut _, res2);
+ _mm_storeu_si128(dst.as_mut_ptr().add(i * 2) as *mut _, res1);
+ _mm_storeu_si128(dst.as_mut_ptr().add(i * 2 + 16) as *mut _, res2);
src = &src[16..];
i += 16;
}
- let i = i as usize;
let _ = hex_encode_fallback(src, &mut dst[i * 2..]);
Ok(str::from_utf8_unchecked(&dst[..src.len() * 2 + i * 2]))
@@ -163,7 +161,7 @@ unsafe fn hex_encode_simd128<'a>(mut src: &[u8], dst: &'a mut [u8]) -> Result<&'
let ascii_a = u8x16_splat(b'a' - 9 - 1);
let and4bits = u8x16_splat(0xf);
- let mut i = 0_isize;
+ let mut i = 0_usize;
while src.len() >= 16 {
let invec = v128_load(src.as_ptr() as *const _);
@@ -189,13 +187,12 @@ unsafe fn hex_encode_simd128<'a>(mut src: &[u8], dst: &'a mut [u8]) -> Result<&'
masked2, masked1,
);
- v128_store(dst.as_mut_ptr().offset(i * 2) as *mut _, res1);
- v128_store(dst.as_mut_ptr().offset(i * 2 + 16) as *mut _, res2);
+ v128_store(dst.as_mut_ptr().add(i * 2) as *mut _, res1);
+ v128_store(dst.as_mut_ptr().add(i * 2 + 16) as *mut _, res2);
src = &src[16..];
i += 16;
}
- let i = i as usize;
let _ = hex_encode_fallback(src, &mut dst[i * 2..]);
Ok(str::from_utf8_unchecked(&dst[..src.len() * 2 + i * 2]))
diff --git a/library/test/src/stats.rs b/library/test/src/stats.rs
index 40b05704b..b33b08012 100644
--- a/library/test/src/stats.rs
+++ b/library/test/src/stats.rs
@@ -14,7 +14,7 @@ pub trait Stats {
/// Sum of the samples.
///
/// Note: this method sacrifices performance at the altar of accuracy
- /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
+ /// Depends on IEEE 754 arithmetic guarantees. See proof of correctness at:
/// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric
/// Predicates"][paper]
///
diff --git a/library/test/src/term/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs
index 694473f52..355859019 100644
--- a/library/test/src/term/terminfo/mod.rs
+++ b/library/test/src/term/terminfo/mod.rs
@@ -80,6 +80,17 @@ impl TermInfo {
/// Creates a TermInfo for the named terminal.
pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
+ if cfg!(miri) {
+ // Avoid all the work of parsing the terminfo (it's pretty slow under Miri), and just
+ // assume that the standard color codes work (like e.g. the 'colored' crate).
+ return Ok(TermInfo {
+ names: Default::default(),
+ bools: Default::default(),
+ numbers: Default::default(),
+ strings: Default::default(),
+ });
+ }
+
get_dbpath_for_term(name)
.ok_or_else(|| {
Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
@@ -119,6 +130,12 @@ pub(crate) struct TerminfoTerminal<T> {
impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
let color = self.dim_if_necessary(color);
+ if cfg!(miri) && color < 8 {
+ // The Miri logic for this only works for the most basic 8 colors, which we just assume
+ // the terminal will support. (`num_colors` is always 0 in Miri, so higher colors will
+ // just fail. But libtest doesn't use any higher colors anyway.)
+ return write!(self.out, "\x1B[3{color}m").and(Ok(true));
+ }
if self.num_colors > color {
return self.apply_cap("setaf", &[Param::Number(color as i32)]);
}
@@ -126,6 +143,9 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
}
fn reset(&mut self) -> io::Result<bool> {
+ if cfg!(miri) {
+ return write!(self.out, "\x1B[0m").and(Ok(true));
+ }
// are there any terminals that have color/attrs and not sgr0?
// Try falling back to sgr, then op
let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
diff --git a/library/unwind/build.rs b/library/unwind/build.rs
index f88e6a924..31af39025 100644
--- a/library/unwind/build.rs
+++ b/library/unwind/build.rs
@@ -2,8 +2,14 @@ use std::env;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
- let target = env::var("TARGET").expect("TARGET was not set");
+ println!("cargo:rerun-if-env-changed=CARGO_CFG_MIRI");
+
+ if env::var_os("CARGO_CFG_MIRI").is_some() {
+ // Miri doesn't need the linker flags or a libunwind build.
+ return;
+ }
+ let target = env::var("TARGET").expect("TARGET was not set");
if target.contains("android") {
let build = cc::Build::new();
@@ -13,13 +19,8 @@ fn main() {
let has_unwind = build.is_flag_supported("-lunwind").expect("Unable to invoke compiler");
if has_unwind {
- println!("cargo:rustc-link-lib=unwind");
- } else {
- println!("cargo:rustc-link-lib=gcc");
+ println!("cargo:rustc-cfg=feature=\"system-llvm-libunwind\"");
}
-
- // Android's unwinding library depends on dl_iterate_phdr in `libdl`.
- println!("cargo:rustc-link-lib=dl");
} else if target.contains("freebsd") {
println!("cargo:rustc-link-lib=gcc_s");
} else if target.contains("netbsd") {
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 4a6ba6e10..46fe50cb9 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -55,6 +55,26 @@ cfg_if::cfg_if! {
}
}
+#[cfg(target_os = "android")]
+cfg_if::cfg_if! {
+ if #[cfg(feature = "llvm-libunwind")] {
+ compile_error!("`llvm-libunwind` is not supported for Android targets");
+ } else if #[cfg(feature = "system-llvm-libunwind")] {
+ #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
+ #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
+ extern "C" {}
+ } else {
+ #[link(name = "gcc", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
+ #[link(name = "gcc", cfg(not(target_feature = "crt-static")))]
+ extern "C" {}
+ }
+}
+// Android's unwinding library depends on dl_iterate_phdr in `libdl`.
+#[cfg(target_os = "android")]
+#[link(name = "dl", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
+#[link(name = "dl", cfg(not(target_feature = "crt-static")))]
+extern "C" {}
+
// When building with crt-static, we get `gcc_eh` from the `libc` crate, since
// glibc needs it, and needs it listed later on the linker command line. We
// don't want to duplicate it here.
diff --git a/src/README.md b/src/README.md
index 9752bc3f6..3d2e6acd5 100644
--- a/src/README.md
+++ b/src/README.md
@@ -2,7 +2,7 @@ This directory contains the source code of the rust project, including:
- The test suite
- The bootstrapping build system
-- Various submodules for tools, like rustdoc, rls, etc.
+- Various submodules for tools, like cargo, miri, etc.
For more information on how various parts of the compiler work, see the [rustc dev guide].
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 664ffa1dd..84c06fdce 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -53,7 +53,6 @@ dependencies = [
"hex",
"ignore",
"libc",
- "num_cpus",
"once_cell",
"opener",
"pretty_assertions",
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 84f6aaf99..95e711737 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -38,7 +38,6 @@ test = false
cmake = "0.1.38"
fd-lock = "3.0.6"
filetime = "0.2"
-num_cpus = "1.0"
getopts = "0.2.19"
cc = "1.0.69"
libc = "0.2"
@@ -68,6 +67,7 @@ features = [
"psapi",
"impl-default",
"timezoneapi",
+ "winbase",
]
[dev-dependencies]
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 40a3cc6d1..e96f8b0d3 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -25,10 +25,11 @@ use std::time::Instant;
fn main() {
let args = env::args_os().skip(1).collect::<Vec<_>>();
+ let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str());
// Detect whether or not we're a build script depending on whether --target
// is passed (a bit janky...)
- let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str());
+ let target = arg("--target");
let version = args.iter().find(|w| &**w == "-vV");
let verbose = match env::var("RUSTC_VERBOSE") {
@@ -59,8 +60,7 @@ fn main() {
cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
// Get the name of the crate we're compiling, if any.
- let crate_name =
- args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str());
+ let crate_name = arg("--crate-name");
if let Some(crate_name) = crate_name {
if let Some(target) = env::var_os("RUSTC_TIME") {
@@ -106,6 +106,15 @@ fn main() {
{
cmd.arg("-C").arg("panic=abort");
}
+
+ // `-Ztls-model=initial-exec` must not be applied to proc-macros, see
+ // issue https://github.com/rust-lang/rust/issues/100530
+ if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok()
+ && arg("--crate-type") != Some("proc-macro")
+ && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure"))
+ {
+ cmd.arg("-Ztls-model=initial-exec");
+ }
} else {
// FIXME(rust-lang/cargo#5754) we shouldn't be using special env vars
// here, but rather Cargo should know what flags to pass rustc itself.
@@ -130,10 +139,8 @@ fn main() {
// Cargo doesn't pass RUSTFLAGS to proc_macros:
// https://github.com/rust-lang/cargo/issues/4423
// Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
- // We also declare that the flag is expected, which is mainly needed for
- // later stages so that they don't warn about #[cfg(bootstrap)],
- // but enabling it for stage 0 too lets any warnings, if they occur,
- // occur more early on, e.g. about #[cfg(bootstrap = "foo")].
+ // We also declare that the flag is expected, which we need to do to not
+ // get warnings about it being unexpected.
if stage == "0" {
cmd.arg("--cfg=bootstrap");
}
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 87c1d22e7..e69cab956 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -11,6 +11,7 @@ include!("../dylib_util.rs");
fn main() {
let args = env::args_os().skip(1).collect::<Vec<_>>();
+ let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set");
let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set");
let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
@@ -62,6 +63,16 @@ fn main() {
cmd.arg("-Clink-arg=-Wl,--threads=1");
}
}
+ // Cargo doesn't pass RUSTDOCFLAGS to proc_macros:
+ // https://github.com/rust-lang/cargo/issues/4423
+ // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
+ // We also declare that the flag is expected, which we need to do to not
+ // get warnings about it being unexpected.
+ if stage == "0" {
+ cmd.arg("--cfg=bootstrap");
+ }
+ cmd.arg("-Zunstable-options");
+ cmd.arg("--check-cfg=values(bootstrap)");
if verbose > 1 {
eprintln!(
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 03eec02a8..cc08ae5f9 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -85,7 +85,7 @@ def _download(path, url, probably_big, verbose, exception):
option = "-#"
else:
option = "-s"
- # If curl is not present on Win32, we shoud not sys.exit
+ # If curl is not present on Win32, we should not sys.exit
# but raise `CalledProcessError` or `OSError` instead
require(["curl", "--version"], exception=platform_is_win32)
run(["curl", option,
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 0ab4824ac..14e8ebd68 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -647,9 +647,9 @@ impl<'a> Builder<'a> {
test::CrateRustdocJsonTypes,
test::Linkcheck,
test::TierCheck,
+ test::ReplacePlaceholderTest,
test::Cargotest,
test::Cargo,
- test::Rls,
test::RustAnalyzer,
test::ErrorIndex,
test::Distcheck,
@@ -736,7 +736,6 @@ impl<'a> Builder<'a> {
install::Docs,
install::Std,
install::Cargo,
- install::Rls,
install::RustAnalyzer,
install::Rustfmt,
install::RustDemangler,
@@ -746,7 +745,12 @@ impl<'a> Builder<'a> {
install::Src,
install::Rustc
),
- Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0),
+ Kind::Run => describe!(
+ run::ExpandYamlAnchors,
+ run::BuildManifest,
+ run::BumpStage0,
+ run::ReplaceVersionPlaceholder,
+ ),
// These commands either don't use paths, or they're special-cased in Build::build()
Kind::Clean | Kind::Format | Kind::Setup => vec![],
}
@@ -942,7 +946,7 @@ impl<'a> Builder<'a> {
};
patchelf.args(&[OsString::from("--set-rpath"), rpath_entries]);
if !fname.extension().map_or(false, |ext| ext == "so") {
- // Finally, set the corret .interp for binaries
+ // Finally, set the correct .interp for binaries
let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker");
// FIXME: can we support utf8 here? `args` doesn't accept Vec<u8>, only OsString ...
let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path))));
@@ -958,7 +962,7 @@ impl<'a> Builder<'a> {
let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
// While bootstrap itself only supports http and https downloads, downstream forks might
// need to download components from other protocols. The match allows them adding more
- // protocols without worrying about merge conficts if we change the HTTP implementation.
+ // protocols without worrying about merge conflicts if we change the HTTP implementation.
match url.split_once("://").map(|(proto, _)| proto) {
Some("http") | Some("https") => {
self.download_http_with_retries(&tempfile, url, help_on_error)
@@ -1759,23 +1763,21 @@ impl<'a> Builder<'a> {
},
);
- if !target.contains("windows") {
- let needs_unstable_opts = target.contains("linux")
- || target.contains("solaris")
- || target.contains("windows")
- || target.contains("bsd")
- || target.contains("dragonfly")
- || target.contains("illumos");
+ let split_debuginfo_is_stable = target.contains("linux")
+ || target.contains("apple")
+ || (target.contains("msvc")
+ && self.config.rust_split_debuginfo == SplitDebuginfo::Packed)
+ || (target.contains("windows")
+ && self.config.rust_split_debuginfo == SplitDebuginfo::Off);
- if needs_unstable_opts {
- rustflags.arg("-Zunstable-options");
- }
- match self.config.rust_split_debuginfo {
- SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"),
- SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"),
- SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"),
- };
+ if !split_debuginfo_is_stable {
+ rustflags.arg("-Zunstable-options");
}
+ match self.config.rust_split_debuginfo {
+ SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"),
+ SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"),
+ SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"),
+ };
if self.config.cmd.bless() {
// Bless `expect!` tests.
@@ -1850,7 +1852,7 @@ impl<'a> Builder<'a> {
// so we can't use it by default in general, but we can use it for tools
// and our own internal libraries.
if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") {
- rustflags.arg("-Ztls-model=initial-exec");
+ cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1");
}
if self.config.incremental {
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index c084e77d3..280eba75f 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -547,7 +547,6 @@ mod dist {
config.stage = 0;
config.cmd = Subcommand::Test {
paths: vec!["library/std".into()],
- skip: vec![],
test_args: vec![],
rustc_args: vec![],
fail_fast: true,
@@ -618,7 +617,6 @@ mod dist {
let mut config = configure(&["A"], &["A"]);
config.cmd = Subcommand::Test {
paths: vec![],
- skip: vec![],
test_args: vec![],
rustc_args: vec![],
fail_fast: true,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 4e1e8ef9d..5c085bedf 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -457,7 +457,7 @@ tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InT
// rejected.
tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
tool_check_step!(Miri, "src/tools/miri", SourceType::Submodule);
-tool_check_step!(Rls, "src/tools/rls", SourceType::Submodule);
+tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index dd2b9d593..c13e83f6c 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -658,7 +658,12 @@ impl Step for Rustc {
// With LLD, we can use ICF (identical code folding) to reduce the executable size
// of librustc_driver/rustc and to improve i-cache utilization.
- if builder.config.use_lld {
+ //
+ // -Wl,[link options] doesn't work on MSVC. However, /OPT:ICF (technically /OPT:REF,ICF)
+ // is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
+ // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
+ // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
+ if builder.config.use_lld && !compiler.host.contains("msvc") {
cargo.rustflag("-Clink-args=-Wl,--icf=all");
}
@@ -1276,7 +1281,9 @@ impl Step for Assemble {
compiler: build_compiler,
target: target_compiler.host,
});
- builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe("ld", target_compiler.host)));
+ for name in crate::LLD_FILE_NAMES {
+ builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(name, target_compiler.host)));
+ }
}
if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) {
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 4325a237c..f1a150e0f 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -388,6 +388,7 @@ impl PartialEq<&str> for TargetSelection {
pub struct Target {
/// Some(path to llvm-config) if using an external LLVM.
pub llvm_config: Option<PathBuf>,
+ pub llvm_has_rust_patches: Option<bool>,
/// Some(path to FileCheck) if one was specified.
pub llvm_filecheck: Option<PathBuf>,
pub llvm_libunwind: Option<LlvmLibunwind>,
@@ -733,6 +734,7 @@ define_config! {
default_linker: Option<PathBuf> = "default-linker",
linker: Option<String> = "linker",
llvm_config: Option<String> = "llvm-config",
+ llvm_has_rust_patches: Option<bool> = "llvm-has-rust-patches",
llvm_filecheck: Option<String> = "llvm-filecheck",
llvm_libunwind: Option<String> = "llvm-libunwind",
android_ndk: Option<String> = "android-ndk",
@@ -990,42 +992,7 @@ impl Config {
config.llvm_from_ci = match llvm.download_ci_llvm {
Some(StringOrBool::String(s)) => {
assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s);
- // This is currently all tier 1 targets and tier 2 targets with host tools
- // (since others may not have CI artifacts)
- // https://doc.rust-lang.org/rustc/platform-support.html#tier-1
- // FIXME: this is duplicated in bootstrap.py
- let supported_platforms = [
- // tier 1
- "aarch64-unknown-linux-gnu",
- "i686-pc-windows-gnu",
- "i686-pc-windows-msvc",
- "i686-unknown-linux-gnu",
- "x86_64-unknown-linux-gnu",
- "x86_64-apple-darwin",
- "x86_64-pc-windows-gnu",
- "x86_64-pc-windows-msvc",
- // tier 2 with host tools
- "aarch64-apple-darwin",
- "aarch64-pc-windows-msvc",
- "aarch64-unknown-linux-musl",
- "arm-unknown-linux-gnueabi",
- "arm-unknown-linux-gnueabihf",
- "armv7-unknown-linux-gnueabihf",
- "mips-unknown-linux-gnu",
- "mips64-unknown-linux-gnuabi64",
- "mips64el-unknown-linux-gnuabi64",
- "mipsel-unknown-linux-gnu",
- "powerpc-unknown-linux-gnu",
- "powerpc64-unknown-linux-gnu",
- "powerpc64le-unknown-linux-gnu",
- "riscv64gc-unknown-linux-gnu",
- "s390x-unknown-linux-gnu",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-illumos",
- "x86_64-unknown-linux-musl",
- "x86_64-unknown-netbsd",
- ];
- supported_platforms.contains(&&*config.build.triple)
+ crate::native::is_ci_llvm_available(&config, llvm_assertions.unwrap_or(false))
}
Some(StringOrBool::Bool(b)) => b,
None => false,
@@ -1144,6 +1111,7 @@ impl Config {
if let Some(ref s) = cfg.llvm_config {
target.llvm_config = Some(config.src.join(s));
}
+ target.llvm_has_rust_patches = cfg.llvm_has_rust_patches;
if let Some(ref s) = cfg.llvm_filecheck {
target.llvm_filecheck = Some(config.src.join(s));
}
@@ -1176,6 +1144,7 @@ impl Config {
if config.llvm_from_ci {
let triple = &config.build.triple;
+ let ci_llvm_bin = config.ci_llvm_root().join("bin");
let mut build_target = config
.target_config
.entry(config.build)
@@ -1183,7 +1152,6 @@ impl Config {
check_ci_llvm!(build_target.llvm_config);
check_ci_llvm!(build_target.llvm_filecheck);
- let ci_llvm_bin = config.out.join(&*config.build.triple).join("ci-llvm/bin");
build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", config.build)));
build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build)));
}
@@ -1312,11 +1280,21 @@ impl Config {
git
}
- pub(crate) fn artifact_channel(&self, commit: &str) -> String {
+ pub(crate) fn artifact_version_part(&self, commit: &str) -> String {
let mut channel = self.git();
channel.arg("show").arg(format!("{}:src/ci/channel", commit));
let channel = output(&mut channel);
- channel.trim().to_owned()
+
+ let mut version = self.git();
+ version.arg("show").arg(format!("{}:src/version", commit));
+ let version = output(&mut version);
+
+ match channel.trim() {
+ "stable" => version.trim().to_owned(),
+ "beta" => channel.trim().to_owned(),
+ "nightly" => channel.trim().to_owned(),
+ other => unreachable!("{:?} is not recognized as a valid channel", other),
+ }
}
/// Try to find the relative path of `bindir`, otherwise return it in full.
@@ -1445,7 +1423,11 @@ impl Config {
.get(&target)
.and_then(|t| t.llvm_libunwind)
.or(self.llvm_libunwind_default)
- .unwrap_or(LlvmLibunwind::No)
+ .unwrap_or(if target.contains("fuchsia") {
+ LlvmLibunwind::InTree
+ } else {
+ LlvmLibunwind::No
+ })
}
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
@@ -1461,7 +1443,7 @@ fn set<T>(field: &mut T, val: Option<T>) {
fn threads_from_config(v: u32) -> u32 {
match v {
- 0 => num_cpus::get() as u32,
+ 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32,
n => n,
}
}
@@ -1554,7 +1536,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> {
fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
- let channel = builder.config.artifact_channel(commit);
+ let version = builder.config.artifact_version_part(commit);
let host = builder.config.build.triple;
let bin_root = builder.out.join(host).join("ci-rustc");
let rustc_stamp = bin_root.join(".rustc-stamp");
@@ -1563,13 +1545,13 @@ fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
if bin_root.exists() {
t!(fs::remove_dir_all(&bin_root));
}
- let filename = format!("rust-std-{channel}-{host}.tar.xz");
+ let filename = format!("rust-std-{version}-{host}.tar.xz");
let pattern = format!("rust-std-{host}");
download_ci_component(builder, filename, &pattern, commit);
- let filename = format!("rustc-{channel}-{host}.tar.xz");
+ let filename = format!("rustc-{version}-{host}.tar.xz");
download_ci_component(builder, filename, "rustc", commit);
// download-rustc doesn't need its own cargo, it can just use beta's.
- let filename = format!("rustc-dev-{channel}-{host}.tar.xz");
+ let filename = format!("rustc-dev-{version}-{host}.tar.xz");
download_ci_component(builder, filename, "rustc-dev", commit);
builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 6291b204e..1a59b3958 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -423,8 +423,11 @@ impl Step for Rustc {
let gcc_lld_src_dir = src_dir.join("gcc-ld");
let gcc_lld_dst_dir = dst_dir.join("gcc-ld");
t!(fs::create_dir(&gcc_lld_dst_dir));
- let exe_name = exe("ld", compiler.host);
- builder.copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name));
+ for name in crate::LLD_FILE_NAMES {
+ let exe_name = exe(name, compiler.host);
+ builder
+ .copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name));
+ }
}
// Man pages
@@ -1018,10 +1021,7 @@ impl Step for Rls {
let rls = builder
.ensure(tool::Rls { compiler, target, extra_features: Vec::new() })
- .or_else(|| {
- missing_tool("RLS", builder.build.config.missing_tools);
- None
- })?;
+ .expect("rls expected to build");
let mut tarball = Tarball::new(builder, "rls", &target.triple);
tarball.set_overlay(OverlayKind::RLS);
@@ -1226,17 +1226,10 @@ impl Step for Rustfmt {
let rustfmt = builder
.ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() })
- .or_else(|| {
- missing_tool("Rustfmt", builder.build.config.missing_tools);
- None
- })?;
+ .expect("rustfmt expected to build - essential tool");
let cargofmt = builder
.ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() })
- .or_else(|| {
- missing_tool("Cargofmt", builder.build.config.missing_tools);
- None
- })?;
-
+ .expect("cargo fmt expected to build - essential tool");
let mut tarball = Tarball::new(builder, "rustfmt", &target.triple);
tarball.set_overlay(OverlayKind::Rustfmt);
tarball.is_preview(true);
@@ -1419,7 +1412,7 @@ impl Step for Extended {
let xform = |p: &Path| {
let mut contents = t!(fs::read_to_string(p));
- for tool in &["rust-demangler", "rls", "rust-analyzer", "miri", "rustfmt"] {
+ for tool in &["rust-demangler", "rust-analyzer", "miri", "rustfmt"] {
if !built_tools.contains(tool) {
contents = filter(&contents, tool);
}
@@ -1459,7 +1452,7 @@ impl Step for Extended {
prepare("rust-std");
prepare("rust-analysis");
prepare("clippy");
- for tool in &["rust-docs", "rust-demangler", "rls", "rust-analyzer", "miri"] {
+ for tool in &["rust-docs", "rust-demangler", "rust-analyzer", "miri"] {
if built_tools.contains(tool) {
prepare(tool);
}
@@ -1495,8 +1488,6 @@ impl Step for Extended {
builder.create_dir(&exe.join(name));
let dir = if name == "rust-std" || name == "rust-analysis" {
format!("{}-{}", name, target.triple)
- } else if name == "rls" {
- "rls-preview".to_string()
} else if name == "rust-analyzer" {
"rust-analyzer-preview".to_string()
} else if name == "clippy" {
@@ -1520,7 +1511,7 @@ impl Step for Extended {
prepare("rust-docs");
prepare("rust-std");
prepare("clippy");
- for tool in &["rust-demangler", "rls", "rust-analyzer", "miri"] {
+ for tool in &["rust-demangler", "rust-analyzer", "miri"] {
if built_tools.contains(tool) {
prepare(tool);
}
@@ -1604,25 +1595,6 @@ impl Step for Extended {
.arg("-out")
.arg(exe.join("StdGroup.wxs")),
);
- if built_tools.contains("rls") {
- builder.run(
- Command::new(&heat)
- .current_dir(&exe)
- .arg("dir")
- .arg("rls")
- .args(&heat_flags)
- .arg("-cg")
- .arg("RlsGroup")
- .arg("-dr")
- .arg("Rls")
- .arg("-var")
- .arg("var.RlsDir")
- .arg("-out")
- .arg(exe.join("RlsGroup.wxs"))
- .arg("-t")
- .arg(etc.join("msi/remove-duplicates.xsl")),
- );
- }
if built_tools.contains("rust-analyzer") {
builder.run(
Command::new(&heat)
@@ -1754,9 +1726,6 @@ impl Step for Extended {
if built_tools.contains("rust-demangler") {
cmd.arg("-dRustDemanglerDir=rust-demangler");
}
- if built_tools.contains("rls") {
- cmd.arg("-dRlsDir=rls");
- }
if built_tools.contains("rust-analyzer") {
cmd.arg("-dRustAnalyzerDir=rust-analyzer");
}
@@ -1779,9 +1748,6 @@ impl Step for Extended {
if built_tools.contains("rust-demangler") {
candle("RustDemanglerGroup.wxs".as_ref());
}
- if built_tools.contains("rls") {
- candle("RlsGroup.wxs".as_ref());
- }
if built_tools.contains("rust-analyzer") {
candle("RustAnalyzerGroup.wxs".as_ref());
}
@@ -1819,9 +1785,6 @@ impl Step for Extended {
.arg("ClippyGroup.wixobj")
.current_dir(&exe);
- if built_tools.contains("rls") {
- cmd.arg("RlsGroup.wixobj");
- }
if built_tools.contains("rust-analyzer") {
cmd.arg("RustAnalyzerGroup.wixobj");
}
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 2852442d0..f909ecc0a 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -793,7 +793,7 @@ impl Step for ErrorIndex {
t!(fs::create_dir_all(&out));
let mut index = tool::ErrorIndex::command(builder);
index.arg("html");
- index.arg(out.join("error-index.html"));
+ index.arg(out);
index.arg(&builder.version);
builder.run(&mut index);
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 80b3bcce8..789da7481 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -80,6 +80,7 @@ pub struct Flags {
pub llvm_profile_generate: bool,
}
+#[derive(Debug)]
#[cfg_attr(test, derive(Clone))]
pub enum Subcommand {
Build {
@@ -115,7 +116,6 @@ pub enum Subcommand {
compare_mode: Option<String>,
pass: Option<String>,
run: Option<String>,
- skip: Vec<String>,
test_args: Vec<String>,
rustc_args: Vec<String>,
fail_fast: bool,
@@ -220,7 +220,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
let j_msg = format!(
"number of jobs to run in parallel; \
defaults to {} (this host's logical CPU count)",
- num_cpus::get()
+ std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get)
);
opts.optopt("j", "jobs", &j_msg, "JOBS");
opts.optflag("h", "help", "print this help message");
@@ -568,7 +568,6 @@ Arguments:
compare_mode: matches.opt_str("compare-mode"),
pass: matches.opt_str("pass"),
run: matches.opt_str("run"),
- skip: matches.opt_strs("skip"),
test_args: matches.opt_strs("test-args"),
rustc_args: matches.opt_strs("rustc-args"),
fail_fast: !matches.opt_present("no-fail-fast"),
@@ -708,16 +707,6 @@ impl Subcommand {
let mut args = vec![];
match *self {
- Subcommand::Test { ref skip, .. } => {
- for s in skip {
- args.push("--skip");
- args.push(s.as_str());
- }
- }
- _ => (),
- };
-
- match *self {
Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => {
args.extend(test_args.iter().flat_map(|s| s.split_whitespace()))
}
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 6e49f39ff..d34aa15c5 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -182,15 +182,6 @@ install!((self, builder, _config),
.expect("missing cargo");
install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball);
};
- Rls, alias = "rls", Self::should_build(_config), only_hosts: true, {
- if let Some(tarball) = builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }) {
- install_sh(builder, "rls", self.compiler.stage, Some(self.target), &tarball);
- } else {
- builder.info(
- &format!("skipping Install RLS stage{} ({})", self.compiler.stage, self.target),
- );
- }
- };
RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) =
builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index d265277b4..cc0cf12bd 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -112,6 +112,7 @@ use std::path::{Path, PathBuf};
use std::process::Command;
use std::str;
+use config::Target;
use filetime::FileTime;
use once_cell::sync::OnceCell;
@@ -186,6 +187,9 @@ const LLVM_TOOLS: &[&str] = &[
"opt", // used to optimize LLVM bytecode
];
+/// LLD file names for all flavors.
+const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
+
pub const VERSION: usize = 2;
/// Extra --check-cfg to add when building
@@ -273,7 +277,6 @@ pub struct Build {
bootstrap_out: PathBuf,
rust_info: channel::GitInfo,
cargo_info: channel::GitInfo,
- rls_info: channel::GitInfo,
rust_analyzer_info: channel::GitInfo,
clippy_info: channel::GitInfo,
miri_info: channel::GitInfo,
@@ -412,7 +415,6 @@ impl Build {
let ignore_git = config.ignore_git;
let rust_info = channel::GitInfo::new(ignore_git, &src);
let cargo_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/cargo"));
- let rls_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/rls"));
let rust_analyzer_info =
channel::GitInfo::new(ignore_git, &src.join("src/tools/rust-analyzer"));
let clippy_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/clippy"));
@@ -490,7 +492,6 @@ impl Build {
rust_info,
cargo_info,
- rls_info,
rust_analyzer_info,
clippy_info,
miri_info,
@@ -542,7 +543,6 @@ impl Build {
let rust_submodules = [
"src/tools/rust-installer",
"src/tools/cargo",
- "src/tools/rls",
"src/tools/miri",
"library/backtrace",
"library/stdarch",
@@ -843,12 +843,13 @@ impl Build {
///
/// If no custom `llvm-config` was specified then Rust's llvm will be used.
fn is_rust_llvm(&self, target: TargetSelection) -> bool {
- if self.config.llvm_from_ci && target == self.config.build {
- return true;
- }
-
match self.config.target_config.get(&target) {
- Some(ref c) => c.llvm_config.is_none(),
+ Some(Target { llvm_has_rust_patches: Some(patched), .. }) => *patched,
+ Some(Target { llvm_config, .. }) => {
+ // If the user set llvm-config we assume Rust is not patched,
+ // but first check to see if it was configured by llvm-from-ci.
+ (self.config.llvm_from_ci && target == self.config.build) || llvm_config.is_none()
+ }
None => true,
}
}
@@ -1013,7 +1014,9 @@ impl Build {
/// Returns the number of parallel jobs that have been configured for this
/// build.
fn jobs(&self) -> u32 {
- self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32)
+ self.config.jobs.unwrap_or_else(|| {
+ std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
+ })
}
fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> {
@@ -1636,14 +1639,12 @@ fn chmod(_path: &Path, _perms: u32) {}
/// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.)
/// If the test is running and code is an error code, it will cause a panic.
fn detail_exit(code: i32) -> ! {
- // Successful exit
- if code == 0 {
- std::process::exit(0);
- }
- if cfg!(test) {
+ // if in test and code is an error code, panic with status code provided
+ if cfg!(test) && code != 0 {
panic!("status code: {}", code);
} else {
- std::panic::resume_unwind(Box::new(code));
+ //otherwise,exit with provided status code
+ std::process::exit(code);
}
}
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 5a1f2e704..9a08a7be0 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -66,16 +66,21 @@ TESTS_IN_2 := \
src/test/ui \
src/tools/linkchecker
+## MSVC native builders
+
+# these intentionally don't use `$(BOOTSTRAP)` so we can test the shebang on Windows
ci-subset-1:
- $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2:%=--exclude %)
+ $(Q)$(CFG_SRC_DIR)/x.py test --stage 2 $(TESTS_IN_2:%=--exclude %)
ci-subset-2:
- $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2)
+ $(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 $(TESTS_IN_2)
+
+## MingW native builders
TESTS_IN_MINGW_2 := \
src/test/ui
ci-mingw-subset-1:
- $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
+ $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
ci-mingw-subset-2:
$(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2)
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 4d548dbb6..fc3bfaf1b 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -114,23 +114,20 @@ pub fn prebuilt_llvm_config(
Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() })
}
-pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
- let config = &builder.config;
- if !config.llvm_from_ci {
- return;
- }
+/// This retrieves the LLVM sha we *want* to use, according to git history.
+pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String {
let mut rev_list = config.git();
rev_list.args(&[
PathBuf::from("rev-list"),
- format!("--author={}", builder.config.stage0_metadata.config.git_merge_commit_email).into(),
+ format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
"-n1".into(),
"--first-parent".into(),
"HEAD".into(),
"--".into(),
- builder.src.join("src/llvm-project"),
- builder.src.join("src/bootstrap/download-ci-llvm-stamp"),
+ config.src.join("src/llvm-project"),
+ config.src.join("src/bootstrap/download-ci-llvm-stamp"),
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
- builder.src.join("src/version"),
+ config.src.join("src/version"),
]);
let llvm_sha = output(&mut rev_list);
let llvm_sha = llvm_sha.trim();
@@ -143,8 +140,82 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
panic!();
}
+ llvm_sha.to_owned()
+}
+
+/// Returns whether the CI-found LLVM is currently usable.
+///
+/// This checks both the build triple platform to confirm we're usable at all,
+/// and then verifies if the current HEAD matches the detected LLVM SHA head,
+/// in which case LLVM is indicated as not available.
+pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool) -> bool {
+ // This is currently all tier 1 targets and tier 2 targets with host tools
+ // (since others may not have CI artifacts)
+ // https://doc.rust-lang.org/rustc/platform-support.html#tier-1
+ let supported_platforms = [
+ // tier 1
+ "aarch64-unknown-linux-gnu",
+ "i686-pc-windows-gnu",
+ "i686-pc-windows-msvc",
+ "i686-unknown-linux-gnu",
+ "x86_64-unknown-linux-gnu",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-gnu",
+ "x86_64-pc-windows-msvc",
+ // tier 2 with host tools
+ "aarch64-apple-darwin",
+ "aarch64-pc-windows-msvc",
+ "aarch64-unknown-linux-musl",
+ "arm-unknown-linux-gnueabi",
+ "arm-unknown-linux-gnueabihf",
+ "armv7-unknown-linux-gnueabihf",
+ "mips-unknown-linux-gnu",
+ "mips64-unknown-linux-gnuabi64",
+ "mips64el-unknown-linux-gnuabi64",
+ "mipsel-unknown-linux-gnu",
+ "powerpc-unknown-linux-gnu",
+ "powerpc64-unknown-linux-gnu",
+ "powerpc64le-unknown-linux-gnu",
+ "riscv64gc-unknown-linux-gnu",
+ "s390x-unknown-linux-gnu",
+ "x86_64-unknown-freebsd",
+ "x86_64-unknown-illumos",
+ "x86_64-unknown-linux-musl",
+ "x86_64-unknown-netbsd",
+ ];
+ if !supported_platforms.contains(&&*config.build.triple) {
+ return false;
+ }
+
+ let triple = &*config.build.triple;
+ if (triple == "aarch64-unknown-linux-gnu" || triple.contains("i686")) && asserts {
+ // No alt builder for aarch64-unknown-linux-gnu today.
+ return false;
+ }
+
+ if crate::util::CiEnv::is_ci() {
+ let llvm_sha = detect_llvm_sha(config);
+ let head_sha = output(config.git().arg("rev-parse").arg("HEAD"));
+ let head_sha = head_sha.trim();
+ if llvm_sha == head_sha {
+ eprintln!(
+ "Detected LLVM as non-available: running in CI and modified LLVM in this change"
+ );
+ return false;
+ }
+ }
+
+ true
+}
+
+pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
+ let config = &builder.config;
+ if !config.llvm_from_ci {
+ return;
+ }
let llvm_root = config.ci_llvm_root();
let llvm_stamp = llvm_root.join(".llvm-stamp");
+ let llvm_sha = detect_llvm_sha(&config);
let key = format!("{}{}", llvm_sha, config.llvm_assertions);
if program_out_of_date(&llvm_stamp, &key) && !config.dry_run {
download_ci_llvm(builder, &llvm_sha);
@@ -189,8 +260,8 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) {
} else {
&builder.config.stage0_metadata.config.artifacts_server
};
- let channel = builder.config.artifact_channel(llvm_sha);
- let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple);
+ let version = builder.config.artifact_version_part(llvm_sha);
+ let filename = format!("rust-dev-{}-{}.tar.xz", version, builder.build.build.triple);
let tarball = rustc_cache.join(&filename);
if !tarball.exists() {
let help_on_error = "error: failed to download llvm from ci
@@ -325,6 +396,9 @@ impl Step for Llvm {
cfg.define("LLVM_PROFDATA_FILE", &path);
}
+ // Disable zstd to avoid a dependency on libzstd.so.
+ cfg.define("LLVM_ENABLE_ZSTD", "OFF");
+
if target != "aarch64-apple-darwin" && !target.contains("windows") {
cfg.define("LLVM_ENABLE_ZLIB", "ON");
} else {
@@ -358,12 +432,13 @@ impl Step for Llvm {
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
}
- if target.starts_with("riscv") && !target.contains("freebsd") {
+ if target.starts_with("riscv") && !target.contains("freebsd") && !target.contains("openbsd")
+ {
// RISC-V GCC erroneously requires linking against
// `libatomic` when using 1-byte and 2-byte C++
// atomics but the LLVM build system check cannot
// detect this. Therefore it is set manually here.
- // FreeBSD uses Clang as its system compiler and
+ // Some BSD uses Clang as its system compiler and
// provides no libatomic in its base system so does
// not want this.
ldflags.exe.push(" -latomic");
@@ -512,11 +587,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
let version = output(cmd.arg("--version"));
let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
- if major >= 12 {
+ if major >= 13 {
return;
}
}
- panic!("\n\nbad LLVM version: {}, need >=12.0\n\n", version)
+ panic!("\n\nbad LLVM version: {}, need >=13.0\n\n", version)
}
fn configure_cmake(
@@ -563,7 +638,7 @@ fn configure_cmake(
if target.contains("darwin") {
// Make sure that CMake does not build universal binaries on macOS.
- // Explicitly specifiy the one single target architecture.
+ // Explicitly specify the one single target architecture.
if target.starts_with("aarch64") {
// macOS uses a different name for building arm64
cfg.define("CMAKE_OSX_ARCHITECTURES", "arm64");
diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs
index 25abe7a72..511872903 100644
--- a/src/bootstrap/run.rs
+++ b/src/bootstrap/run.rs
@@ -103,3 +103,25 @@ impl Step for BumpStage0 {
builder.run(&mut cmd);
}
}
+
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct ReplaceVersionPlaceholder;
+
+impl Step for ReplaceVersionPlaceholder {
+ type Output = ();
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/replace-version-placeholder")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(ReplaceVersionPlaceholder);
+ }
+
+ fn run(self, builder: &Builder<'_>) -> Self::Output {
+ let mut cmd = builder.tool_cmd(Tool::ReplaceVersionPlaceholder);
+ cmd.arg(&builder.src);
+ builder.run(&mut cmd);
+ }
+}
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index a5a39a5a3..eb7da1bda 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -11,7 +11,7 @@ use std::{
io::{self, Write},
};
-#[derive(Clone, Copy, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Profile {
Compiler,
Codegen,
diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs
index 7b0c029c1..e30067a5c 100644
--- a/src/bootstrap/tarball.rs
+++ b/src/bootstrap/tarball.rs
@@ -50,11 +50,7 @@ impl OverlayKind {
OverlayKind::RustDemangler => {
&["src/tools/rust-demangler/README.md", "LICENSE-APACHE", "LICENSE-MIT"]
}
- OverlayKind::RLS => &[
- "src/tools/rls/README.md",
- "src/tools/rls/LICENSE-APACHE",
- "src/tools/rls/LICENSE-MIT",
- ],
+ OverlayKind::RLS => &["src/tools/rls/README.md", "LICENSE-APACHE", "LICENSE-MIT"],
OverlayKind::RustAnalyzer => &[
"src/tools/rust-analyzer/README.md",
"src/tools/rust-analyzer/LICENSE-APACHE",
@@ -78,7 +74,7 @@ impl OverlayKind {
OverlayKind::Rustfmt => {
builder.rustfmt_info.version(builder, &builder.release_num("rustfmt"))
}
- OverlayKind::RLS => builder.rls_info.version(builder, &builder.release_num("rls")),
+ OverlayKind::RLS => builder.release(&builder.release_num("rls")),
OverlayKind::RustAnalyzer => builder
.rust_analyzer_info
.version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")),
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index c0fa8c9ac..dd41f8453 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -300,57 +300,6 @@ impl Step for Cargo {
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Rls {
- stage: u32,
- host: TargetSelection,
-}
-
-impl Step for Rls {
- type Output = ();
- const ONLY_HOSTS: bool = true;
-
- fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/tools/rls")
- }
-
- fn make_run(run: RunConfig<'_>) {
- run.builder.ensure(Rls { stage: run.builder.top_stage, host: run.target });
- }
-
- /// Runs `cargo test` for the rls.
- fn run(self, builder: &Builder<'_>) {
- let stage = self.stage;
- let host = self.host;
- let compiler = builder.compiler(stage, host);
-
- let build_result =
- builder.ensure(tool::Rls { compiler, target: self.host, extra_features: Vec::new() });
- if build_result.is_none() {
- eprintln!("failed to test rls: could not build");
- return;
- }
-
- let mut cargo = tool::prepare_tool_cargo(
- builder,
- compiler,
- Mode::ToolRustc,
- host,
- "test",
- "src/tools/rls",
- SourceType::Submodule,
- &[],
- );
-
- cargo.add_rustc_lib_path(builder, compiler);
- cargo.arg("--").args(builder.config.cmd.test_args());
-
- if try_run(builder, &mut cargo.into()) {
- builder.save_toolstate("rls", ToolState::TestPass);
- }
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct RustAnalyzer {
stage: u32,
host: TargetSelection,
@@ -628,6 +577,10 @@ impl Step for Miri {
cargo.env("MIRI_HOST_SYSROOT", sysroot);
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
cargo.env("MIRI", miri);
+ // propagate --bless
+ if builder.config.cmd.bless() {
+ cargo.env("MIRI_BLESS", "Gesundheit");
+ }
cargo.arg("--").args(builder.config.cmd.test_args());
@@ -901,7 +854,10 @@ fn get_browser_ui_test_version_inner(npm: &Path, global: bool) -> Option<String>
.output()
.map(|output| String::from_utf8_lossy(&output.stdout).into_owned())
.unwrap_or(String::new());
- lines.lines().find_map(|l| l.split(":browser-ui-test@").skip(1).next()).map(|v| v.to_owned())
+ lines
+ .lines()
+ .find_map(|l| l.split(':').nth(1)?.strip_prefix("browser-ui-test@"))
+ .map(|v| v.to_owned())
}
fn get_browser_ui_test_version(npm: &Path) -> Option<String> {
@@ -920,6 +876,11 @@ fn compare_browser_ui_test_version(installed_version: &str, src: &Path) {
one used in the CI (`{}`)",
installed_version, v
);
+ eprintln!(
+ "You can install this version using `npm update browser-ui-test` or by using \
+ `npm install browser-ui-test@{}`",
+ v,
+ );
}
}
Err(e) => eprintln!("Couldn't find the CI browser-ui-test version: {:?}", e),
@@ -1381,6 +1342,8 @@ note: if you're sure you want to do this, please open an issue as to why. In the
let json_compiler = compiler.with_stage(0);
cmd.arg("--jsondocck-path")
.arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target }));
+ cmd.arg("--jsondoclint-path")
+ .arg(builder.ensure(tool::JsonDocLint { compiler: json_compiler, target }));
}
if mode == "run-make" {
@@ -1487,6 +1450,11 @@ note: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--run-clang-based-tests-with").arg(clang_exe);
}
+ for exclude in &builder.config.exclude {
+ cmd.arg("--skip");
+ cmd.arg(&exclude.path);
+ }
+
// Get paths from cmd args
let paths = match &builder.config.cmd {
Subcommand::Test { ref paths, .. } => &paths[..],
@@ -1501,7 +1469,15 @@ note: if you're sure you want to do this, please open an issue as to why. In the
test_args.append(&mut builder.config.cmd.test_args());
- cmd.args(&test_args);
+ // On Windows, replace forward slashes in test-args by backslashes
+ // so the correct filters are passed to libtest
+ if cfg!(windows) {
+ let test_args_win: Vec<String> =
+ test_args.iter().map(|s| s.replace("/", "\\")).collect();
+ cmd.args(&test_args_win);
+ } else {
+ cmd.args(&test_args);
+ }
if builder.is_verbose() {
cmd.arg("--verbose");
@@ -2509,6 +2485,43 @@ impl Step for TierCheck {
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct ReplacePlaceholderTest;
+
+impl Step for ReplacePlaceholderTest {
+ type Output = ();
+ const ONLY_HOSTS: bool = true;
+ const DEFAULT: bool = true;
+
+ /// Ensure the version placeholder replacement tool builds
+ fn run(self, builder: &Builder<'_>) {
+ builder.info("build check for version replacement placeholder");
+
+ // Test the version placeholder replacement tool itself.
+ let bootstrap_host = builder.config.build;
+ let compiler = builder.compiler(0, bootstrap_host);
+ let cargo = tool::prepare_tool_cargo(
+ builder,
+ compiler,
+ Mode::ToolBootstrap,
+ bootstrap_host,
+ "test",
+ "src/tools/replace-version-placeholder",
+ SourceType::InTree,
+ &[],
+ );
+ try_run(builder, &mut cargo.into());
+ }
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/replace-version-placeholder")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(Self);
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct LintDocs {
pub compiler: Compiler,
pub target: TargetSelection,
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 06fa5039f..7d4ed24b6 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -376,8 +376,10 @@ bootstrap_tool!(
ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors";
LintDocs, "src/tools/lint-docs", "lint-docs";
JsonDocCk, "src/tools/jsondocck", "jsondocck";
+ JsonDocLint, "src/tools/jsondoclint", "jsondoclint";
HtmlChecker, "src/tools/html-checker", "html-checker";
BumpStage0, "src/tools/bump-stage0", "bump-stage0";
+ ReplaceVersionPlaceholder, "src/tools/replace-version-placeholder", "replace-version-placeholder";
);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
@@ -778,12 +780,10 @@ impl Step for RustAnalyzerProcMacroSrv {
macro_rules! tool_extended {
(($sel:ident, $builder:ident),
$($name:ident,
- $toolstate:ident,
$path:expr,
$tool_name:expr,
stable = $stable:expr,
$(in_tree = $in_tree:expr,)?
- $(submodule = $submodule:literal,)?
$(tool_std = $tool_std:literal,)?
$extra_deps:block;)+) => {
$(
@@ -828,7 +828,6 @@ macro_rules! tool_extended {
#[allow(unused_mut)]
fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
$extra_deps
- $( $builder.update_submodule(&Path::new("src").join("tools").join($submodule)); )?
$builder.ensure(ToolBuild {
compiler: $sel.compiler,
target: $sel.target,
@@ -854,24 +853,17 @@ macro_rules! tool_extended {
// Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
// invoke Cargo to build bootstrap. See the comment there for more details.
tool_extended!((self, builder),
- Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
- CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
- Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
- Miri, miri, "src/tools/miri", "miri", stable=false, {};
- CargoMiri, miri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {};
- Rls, rls, "src/tools/rls", "rls", stable=true, {
- builder.ensure(Clippy {
- compiler: self.compiler,
- target: self.target,
- extra_features: Vec::new(),
- });
- self.extra_features.push("clippy".to_owned());
- };
+ Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
+ CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
+ Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
+ Miri, "src/tools/miri", "miri", stable=false, {};
+ CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {};
+ Rls, "src/tools/rls", "rls", stable=true, {};
// FIXME: tool_std is not quite right, we shouldn't allow nightly features.
// But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
// and this is close enough for now.
- RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
- Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
+ RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
+ Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
);
impl<'a> Builder<'a> {
diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index 2cfeae7dc..f3a6759ab 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -69,7 +69,6 @@ static STABLE_TOOLS: &[(&str, &str)] = &[
("reference", "src/doc/reference"),
("rust-by-example", "src/doc/rust-by-example"),
("edition-guide", "src/doc/edition-guide"),
- ("rls", "src/tools/rls"),
];
// These tools are permitted to not build on the beta/stable channels.
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 1895e2901..0ebabbd5c 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -197,9 +197,11 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
ptr::null_mut(),
);
- let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize];
- let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER;
- let buf = &mut (*db).ReparseTarget as *mut u16;
+ #[repr(C, align(8))]
+ struct Align8<T>(T);
+ let mut data = Align8([0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]);
+ let db = data.0.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER;
+ let buf = core::ptr::addr_of_mut!((*db).ReparseTarget) as *mut u16;
let mut i = 0;
// FIXME: this conversion is very hacky
let v = br"\??\";
@@ -219,7 +221,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
let res = DeviceIoControl(
h as *mut _,
FSCTL_SET_REPARSE_POINT,
- data.as_ptr() as *mut _,
+ db.cast(),
(*db).ReparseDataLength + 8,
ptr::null_mut(),
0,
@@ -258,6 +260,10 @@ impl CiEnv {
}
}
+ pub fn is_ci() -> bool {
+ Self::current() != CiEnv::None
+ }
+
/// If in a CI environment, forces the command to run with colors.
pub fn force_coloring_in_ci(self, cmd: &mut Command) {
if self != CiEnv::None {
diff --git a/src/ci/docker/host-x86_64/arm-android/Dockerfile b/src/ci/docker/host-x86_64/arm-android/Dockerfile
index 43cdbbe92..7a875c960 100644
--- a/src/ci/docker/host-x86_64/arm-android/Dockerfile
+++ b/src/ci/docker/host-x86_64/arm-android/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
+ARG DEBIAN_FRONTEND=noninteractive
COPY scripts/android-base-apt-get.sh /scripts/
RUN sh /scripts/android-base-apt-get.sh
@@ -13,7 +14,7 @@ RUN dpkg --add-architecture i386 && \
libgl1-mesa-glx \
libpulse0 \
libstdc++6:i386 \
- openjdk-9-jre-headless \
+ openjdk-8-jre-headless \
tzdata \
wget \
python3
@@ -36,8 +37,5 @@ ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target $TARGETS
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
COPY scripts/android-start-emulator.sh /scripts/
ENTRYPOINT ["/scripts/android-start-emulator.sh"]
diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
index e2dbc7cfd..69f88e495 100644
--- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
@@ -78,6 +78,8 @@ RUN curl -O https://ci-mirrors.rust-lang.org/rustc/vexpress-v2p-ca15-tc1.dtb
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
+COPY static/gitconfig /etc/gitconfig
+
ENV RUST_CONFIGURE_ARGS --qemu-armhf-rootfs=/tmp/rootfs
ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target arm-unknown-linux-gnueabihf
diff --git a/src/ci/docker/host-x86_64/dist-android/Dockerfile b/src/ci/docker/host-x86_64/dist-android/Dockerfile
index 2f0496d7d..2328db4ab 100644
--- a/src/ci/docker/host-x86_64/dist-android/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-android/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
COPY scripts/android-base-apt-get.sh /scripts/
RUN sh /scripts/android-base-apt-get.sh
@@ -38,6 +38,3 @@ ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
index c98fc7dcf..b0d65428e 100644
--- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
@@ -36,7 +36,8 @@ RUN /scripts/cmake.sh
ENV RUST_CONFIGURE_ARGS \
--musl-root-i586=/musl-i586 \
--musl-root-i686=/musl-i686 \
- --disable-docs
+ --disable-docs \
+ --set llvm.allow-old-toolchain
# Newer binutils broke things on some vms/distros (i.e., linking against
# unknown relocs disabled by the following flag), so we need to go out of our
diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
index b0f06569a..948fa40dd 100644
--- a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
@@ -26,5 +26,6 @@ RUN /scripts/cmake.sh
ENV HOSTS=mips-unknown-linux-gnu
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
+ --set llvm.allow-old-toolchain
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
index 245c28e1f..fd15dbd22 100644
--- a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
@@ -25,5 +25,6 @@ RUN /scripts/cmake.sh
ENV HOSTS=mips64-unknown-linux-gnuabi64
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
+ --set llvm.allow-old-toolchain
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
index 03998c888..376bdfb4a 100644
--- a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
@@ -26,5 +26,6 @@ RUN /scripts/cmake.sh
ENV HOSTS=mips64el-unknown-linux-gnuabi64
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
+ --set llvm.allow-old-toolchain
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
index 586172706..70c8b2a96 100644
--- a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
@@ -25,5 +25,6 @@ RUN /scripts/cmake.sh
ENV HOSTS=mipsel-unknown-linux-gnu
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
+ --set llvm.allow-old-toolchain
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 6f9980dbc..126c292b3 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -32,10 +32,16 @@ RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main'
ENV \
AR_x86_64_fuchsia=x86_64-fuchsia-ar \
CC_x86_64_fuchsia=x86_64-fuchsia-clang \
+ CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \
CXX_x86_64_fuchsia=x86_64-fuchsia-clang++ \
+ CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \
+ LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -L/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib" \
AR_aarch64_fuchsia=aarch64-fuchsia-ar \
CC_aarch64_fuchsia=aarch64-fuchsia-clang \
+ CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \
CXX_aarch64_fuchsia=aarch64-fuchsia-clang++ \
+ CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \
+ LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot -L/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/lib" \
AR_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-ar \
CC_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-gcc \
CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \
@@ -89,14 +95,14 @@ RUN sh /scripts/sccache.sh
ENV CARGO_TARGET_X86_64_FUCHSIA_AR /usr/local/bin/llvm-ar
ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \
--C link-arg=--sysroot=/usr/local/x86_64-fuchsia \
--C link-arg=-L/usr/local/x86_64-fuchsia/lib \
--C link-arg=-L/usr/local/lib/x86_64-fuchsia/lib
+-C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot \
+-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot/lib \
+-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib
ENV CARGO_TARGET_AARCH64_FUCHSIA_AR /usr/local/bin/llvm-ar
ENV CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS \
--C link-arg=--sysroot=/usr/local/aarch64-fuchsia \
--C link-arg=-L/usr/local/aarch64-fuchsia/lib \
--C link-arg=-L/usr/local/lib/aarch64-fuchsia/lib
+-C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot \
+-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot/lib \
+-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/lib
ENV TARGETS=x86_64-fuchsia
ENV TARGETS=$TARGETS,aarch64-fuchsia
diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-fuchsia-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-fuchsia-toolchain.sh
index 73acdf5be..80db92577 100755
--- a/src/ci/docker/host-x86_64/dist-various-2/build-fuchsia-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-various-2/build-fuchsia-toolchain.sh
@@ -3,52 +3,58 @@
set -ex
source shared.sh
-ZIRCON=e9a26dbc70d631029f8ee9763103910b7e3a2fe1
-
-mkdir -p zircon
-pushd zircon > /dev/null
-
-# Download sources
-git init
-git remote add origin https://github.com/rust-lang-nursery/mirror-google-fuchsia-zircon
-git fetch --depth=1 origin $ZIRCON
-git reset --hard FETCH_HEAD
-
-# Download toolchain
-./scripts/download-toolchain
-chmod -R a+rx prebuilt/downloads/clang+llvm-x86_64-linux
-cp -a prebuilt/downloads/clang+llvm-x86_64-linux/. /usr/local
-
-build() {
- local arch="$1"
-
- case "${arch}" in
- x86_64) tgt="zircon-pc-x86-64" ;;
- aarch64) tgt="zircon-qemu-arm64" ;;
- esac
-
- hide_output make -j$(getconf _NPROCESSORS_ONLN) $tgt
- dst=/usr/local/${arch}-fuchsia
- mkdir -p $dst
- cp -a build-${tgt}/sysroot/include $dst/
- cp -a build-${tgt}/sysroot/lib $dst/
+FUCHSIA_SDK_URL=https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64
+FUCHSIA_SDK_ID=4xjxrGUrDbQ6_zJwj6cDN1IbWsWV5aCQXC_zO_Hu0XkC
+FUCHSIA_SDK_SHA256=e318f1ac652b0db43aff32708fa70337521b5ac595e5a0905c2ff33bf1eed179
+FUCHSIA_SDK_USR_DIR=/usr/local/core-linux-amd64-fuchsia-sdk
+CLANG_DOWNLOAD_URL=\
+https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64
+CLANG_DOWNLOAD_ID=vU0vNjSihOV4Q6taQYCpy03JXGiCyVwxen3rFMNMIgsC
+CLANG_DOWNLOAD_SHA256=bd4d2f3634a284e57843ab5a4180a9cb4dc95c6882c95c317a7deb14c34c220b
+
+install_clang() {
+ mkdir -p clang_download
+ pushd clang_download > /dev/null
+
+ # Download clang+llvm
+ curl -LO "${CLANG_DOWNLOAD_URL}/+/${CLANG_DOWNLOAD_ID}"
+ echo "$(echo ${CLANG_DOWNLOAD_SHA256}) ${CLANG_DOWNLOAD_ID}" | sha256sum --check --status
+ unzip -qq ${CLANG_DOWNLOAD_ID} -d clang-linux-amd64
+
+ # Other dists currently depend on our Clang... moving into /usr/local for other
+ # dist usage instead of a Fuchsia /usr/local directory
+ chmod -R 777 clang-linux-amd64/.
+ cp -a clang-linux-amd64/. /usr/local
+
+ # CFLAGS and CXXFLAGS env variables in main Dockerfile handle sysroot linking
+ for arch in x86_64 aarch64; do
+ for tool in clang clang++; do
+ ln -s /usr/local/bin/${tool} /usr/local/bin/${arch}-fuchsia-${tool}
+ done
+ ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-fuchsia-ar
+ done
+
+ popd > /dev/null
+ rm -rf clang_download
}
-# Build sysroot
-for arch in x86_64 aarch64; do
- build ${arch}
-done
-
-popd > /dev/null
-rm -rf zircon
-
-for arch in x86_64 aarch64; do
- for tool in clang clang++; do
- cat >/usr/local/bin/${arch}-fuchsia-${tool} <<EOF
-#!/bin/sh
-${tool} --target=${arch}-fuchsia --sysroot=/usr/local/${arch}-fuchsia "\$@"
-EOF
- chmod +x /usr/local/bin/${arch}-fuchsia-${tool}
- done
- ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-fuchsia-ar
-done
+install_zircon_libs() {
+ mkdir -p zircon
+ pushd zircon > /dev/null
+
+ # Download Fuchsia SDK (with Zircon libs)
+ curl -LO "${FUCHSIA_SDK_URL}/+/${FUCHSIA_SDK_ID}"
+ echo "$(echo ${FUCHSIA_SDK_SHA256}) ${FUCHSIA_SDK_ID}" | sha256sum --check --status
+ unzip -qq ${FUCHSIA_SDK_ID} -d core-linux-amd64
+
+ # Moving SDK into Docker's user-space
+ mkdir -p ${FUCHSIA_SDK_USR_DIR}
+ chmod -R 777 core-linux-amd64/.
+ cp -r core-linux-amd64/* ${FUCHSIA_SDK_USR_DIR}
+
+ popd > /dev/null
+ rm -rf zircon
+}
+
+hide_output install_clang
+hide_output install_zircon_libs
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
index 1025f5bce..fa780e1e4 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
@@ -4,7 +4,7 @@ set -ex
source shared.sh
-LLVM=llvmorg-14.0.5
+LLVM=llvmorg-15.0.0
mkdir llvm-project
cd llvm-project
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
index 92bdc9811..fed4be4c3 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
@@ -21,5 +21,6 @@ ENV \
ENV HOSTS=x86_64-unknown-netbsd
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
+ --set llvm.allow-old-toolchain
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
index 0182ebb8b..dd74726f8 100644
--- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
+ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
g++-multilib \
make \
@@ -20,9 +21,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
RUN mkdir -p /config
RUN echo "[rust]" > /config/nopt-std-config.toml
RUN echo "optimize = false" >> /config/nopt-std-config.toml
diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
index feaab819b..0c36cfd66 100644
--- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
+ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
g++-multilib \
make \
@@ -20,9 +21,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu
# Exclude some tests that are unlikely to be platform specific, to speed up
# this slow job.
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 9ee84f420..52a777615 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -1,4 +1,7 @@
FROM ubuntu:18.04
+# FIXME: when bumping the version, remove the Python 3.6-specific changes in
+# the reuse-requirements.in file, regenerate reuse-requirements.txt and remove
+# this comment.
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
@@ -8,6 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
python3 \
+ python3-pip \
+ python3-pkg-resources \
git \
cmake \
sudo \
@@ -27,6 +32,9 @@ RUN npm install eslint@8.6.0 -g
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
+COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
+RUN pip3 install --no-deps --require-hashes -r /tmp/reuse-requirements.txt
+
COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
@@ -37,9 +45,11 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
python3 ../x.py test --stage 0 src/tools/compiletest && \
python3 ../x.py test --stage 2 src/tools/tidy && \
python3 ../x.py test --stage 0 core alloc std test proc_macro && \
- python3 ../x.py doc --stage 0 library/test && \
+ # Build both public and internal documentation.
+ RUSTDOCFLAGS="--document-private-items" python3 ../x.py doc --stage 0 library/test && \
/scripts/validate-toolstate.sh && \
/scripts/validate-error-codes.sh && \
+ reuse lint && \
# Runs checks to ensure that there are no ES5 issues in our JS code.
es-check es6 ../src/librustdoc/html/static/js/*.js && \
eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js
diff --git a/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in
new file mode 100644
index 000000000..4964f40aa
--- /dev/null
+++ b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in
@@ -0,0 +1,22 @@
+# This is the template for reuse-requirements.txt.
+#
+# The pip-tools project is used to generate the file again. To install it, the
+# recommended way is to:
+#
+# - Install pipx from https://github.com/pypa/pipx
+# - Run `pipx install pip-tools`
+#
+# Once pip-tools is installed, run this command to regenerate the .txt file:
+#
+# pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
+#
+
+reuse
+
+# Some packages dropped support for Python 3.6, which is the version used in
+# this builder (due to Ubuntu 18.04). This should be removed once we bump the
+# Ubuntu version of the builder.
+jinja2 < 3.1
+markupsafe < 2.1
+requests < 2.28
+setuptools < 59.7
diff --git a/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt
new file mode 100644
index 000000000..10a5f7387
--- /dev/null
+++ b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt
@@ -0,0 +1,145 @@
+#
+# This file is autogenerated by pip-compile with python 3.10
+# To update, run:
+#
+# pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
+#
+binaryornot==0.4.4 \
+ --hash=sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061 \
+ --hash=sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4
+ # via reuse
+boolean-py==3.8 \
+ --hash=sha256:cc24e20f985d60cd4a3a5a1c0956dd12611159d32a75081dabd0c9ab981acaa4 \
+ --hash=sha256:d75da0fd0354425fa64f6bbc6cec6ae1485d0eec3447b73187ff8cbf9b572e26
+ # via
+ # license-expression
+ # reuse
+certifi==2022.6.15 \
+ --hash=sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d \
+ --hash=sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412
+ # via requests
+chardet==5.0.0 \
+ --hash=sha256:0368df2bfd78b5fc20572bb4e9bb7fb53e2c094f60ae9993339e8671d0afb8aa \
+ --hash=sha256:d3e64f022d254183001eccc5db4040520c0f23b1a3f33d6413e099eb7f126557
+ # via
+ # binaryornot
+ # python-debian
+charset-normalizer==2.0.12 \
+ --hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \
+ --hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df
+ # via requests
+idna==3.3 \
+ --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
+ --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
+ # via requests
+jinja2==3.0.3 \
+ --hash=sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8 \
+ --hash=sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7
+ # via
+ # -r reuse-requirements.in
+ # reuse
+license-expression==21.6.14 \
+ --hash=sha256:324246eed8e138b4139fefdc0e9dc4161d5075e3929e56983966d37298dca30e \
+ --hash=sha256:9de87a427c9a449eee7913472fb9ed03b63036295547369fdbf95f76a8b924b2
+ # via
+ # -r reuse-requirements.in
+ # reuse
+markupsafe==2.0.1 \
+ --hash=sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298 \
+ --hash=sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64 \
+ --hash=sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b \
+ --hash=sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194 \
+ --hash=sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567 \
+ --hash=sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff \
+ --hash=sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724 \
+ --hash=sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74 \
+ --hash=sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646 \
+ --hash=sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35 \
+ --hash=sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6 \
+ --hash=sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a \
+ --hash=sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6 \
+ --hash=sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad \
+ --hash=sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26 \
+ --hash=sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38 \
+ --hash=sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac \
+ --hash=sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7 \
+ --hash=sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6 \
+ --hash=sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047 \
+ --hash=sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75 \
+ --hash=sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f \
+ --hash=sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b \
+ --hash=sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135 \
+ --hash=sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8 \
+ --hash=sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a \
+ --hash=sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a \
+ --hash=sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1 \
+ --hash=sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9 \
+ --hash=sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864 \
+ --hash=sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914 \
+ --hash=sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee \
+ --hash=sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f \
+ --hash=sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18 \
+ --hash=sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8 \
+ --hash=sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2 \
+ --hash=sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d \
+ --hash=sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b \
+ --hash=sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b \
+ --hash=sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86 \
+ --hash=sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6 \
+ --hash=sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f \
+ --hash=sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb \
+ --hash=sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833 \
+ --hash=sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28 \
+ --hash=sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e \
+ --hash=sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415 \
+ --hash=sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902 \
+ --hash=sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f \
+ --hash=sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d \
+ --hash=sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9 \
+ --hash=sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d \
+ --hash=sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145 \
+ --hash=sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066 \
+ --hash=sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c \
+ --hash=sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1 \
+ --hash=sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a \
+ --hash=sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207 \
+ --hash=sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f \
+ --hash=sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53 \
+ --hash=sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd \
+ --hash=sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134 \
+ --hash=sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85 \
+ --hash=sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9 \
+ --hash=sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5 \
+ --hash=sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94 \
+ --hash=sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509 \
+ --hash=sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51 \
+ --hash=sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872
+ # via
+ # -r reuse-requirements.in
+ # jinja2
+python-debian==0.1.44 \
+ --hash=sha256:11bd6f01c46da57982bdd66dd595e2d240feb32a85de3fd37c452102fd0337ab \
+ --hash=sha256:65592fe3b64f6c6c93d94e2d2599db5e0c22831d3bcff07cb7b96d3840b1333e
+ # via reuse
+requests==2.26.0 \
+ --hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
+ --hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
+ # via
+ # -r reuse-requirements.in
+ # reuse
+reuse==1.0.0 \
+ --hash=sha256:db3022be2d87f69c8f508b928023de3026f454ce17d01e22f770f7147ac1e8d4 \
+ --hash=sha256:e2605e796311c424465d741ea2a1e1ad03bbb90b921d74750119c331ca5af46e
+ # via -r reuse-requirements.in
+urllib3==1.26.10 \
+ --hash=sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec \
+ --hash=sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6
+ # via requests
+
+# The following packages are considered to be unsafe in a requirements file:
+setuptools==59.6.0 \
+ --hash=sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373 \
+ --hash=sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e
+ # via
+ # -r reuse-requirements.in
+ # reuse
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index 4d554a285..b75e2f085 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -30,6 +30,10 @@ WORKDIR /
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
+# We are disabling CI LLVM since this builder needs to build LLD, which is
+# currently unsupported when downloading pre-built LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
ENV RUST_CONFIGURE_ARGS \
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
--set build.nodejs=/node-v15.14.0-linux-x64/bin/node \
diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile
index 878c4e341..9e37c2822 100644
--- a/src/ci/docker/host-x86_64/wasm32/Dockerfile
+++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile
@@ -48,6 +48,8 @@ ENV TARGETS=wasm32-unknown-emscripten
# Use -O1 optimizations in the link step to reduce time spent optimizing.
ENV EMCC_CFLAGS=-O1
+COPY static/gitconfig /etc/gitconfig
+
# Emscripten installation is user-specific
ENV NO_CHANGE_USER=1
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
index ee3cd092f..d55d5b56a 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
+ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
make \
@@ -23,8 +24,5 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
ENV RUST_CHECK_TARGET check-aux
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
index 13d440423..739045248 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
@@ -31,6 +31,9 @@ RUN sh /scripts/sccache.sh
ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1
ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
+# llvm.use-linker conflicts with downloading CI LLVM
+ENV NO_DOWNLOAD_CI_LLVM 1
+
ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
--enable-debug \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
index 09d9cda02..80a004501 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
+ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
make \
@@ -19,8 +20,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
+# We are disabling CI LLVM since distcheck is an offline build.
+ENV NO_DOWNLOAD_CI_LLVM 1
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --set rust.ignore-git=false
ENV SCRIPT python3 ../x.py --stage 2 test distcheck
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-12-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
index c2f3a16d2..23f2215c2 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-12-stage1/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:20.04
+FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -14,8 +14,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
cmake \
sudo \
gdb \
- llvm-12-tools \
- llvm-12-dev \
+ llvm-13-tools \
+ llvm-13-dev \
libedit-dev \
libssl-dev \
pkg-config \
@@ -26,10 +26,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-# using llvm-link-shared due to libffi issues -- see #34486
+# We are disabling CI LLVM since this builder is intentionally using a host
+# LLVM, rather than the typical src/llvm-project LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
+# Using llvm-link-shared due to libffi issues -- see #34486
ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
- --llvm-root=/usr/lib/llvm-12 \
+ --llvm-root=/usr/lib/llvm-13 \
--enable-llvm-link-shared \
--set rust.thin-lto-import-instr-limit=10
@@ -41,4 +45,4 @@ ENV SCRIPT python2.7 ../x.py --stage 1 test --exclude src/tools/tidy && \
# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
# despite having different output on 32-bit vs 64-bit targets.
python2.7 ../x.py --stage 1 test src/test/mir-opt \
- --host='' --target=i686-unknown-linux-gnu \ No newline at end of file
+ --host='' --target=i686-unknown-linux-gnu
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-12/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
index df1fbc29c..8f6831bc5 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-12/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
@@ -1,6 +1,8 @@
-FROM ubuntu:20.04
+FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
+
+# NOTE: intentionally installs both python2 and python3 so we can test support for both.
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
gcc-multilib \
@@ -10,12 +12,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
python2.7 \
+ python3.9 \
git \
cmake \
sudo \
gdb \
- llvm-12-tools \
- llvm-12-dev \
+ llvm-13-tools \
+ llvm-13-dev \
libedit-dev \
libssl-dev \
pkg-config \
@@ -23,31 +26,44 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xz-utils \
nodejs
+# Install powershell so we can test x.ps1 on Linux
+RUN apt-get update && \
+ apt-get install -y apt-transport-https software-properties-common && \
+ curl -s "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" > packages-microsoft-prod.deb && \
+ dpkg -i packages-microsoft-prod.deb && \
+ apt-get update && \
+ apt-get install -y powershell
+
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-# using llvm-link-shared due to libffi issues -- see #34486
+# We are disabling CI LLVM since this builder is intentionally using a host
+# LLVM, rather than the typical src/llvm-project LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
+# Using llvm-link-shared due to libffi issues -- see #34486
ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
- --llvm-root=/usr/lib/llvm-12 \
+ --llvm-root=/usr/lib/llvm-13 \
--enable-llvm-link-shared \
--set rust.thin-lto-import-instr-limit=10
-ENV SCRIPT python2.7 ../x.py --stage 2 test --exclude src/tools/tidy && \
+# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
+ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \
# Run the `mir-opt` tests again but this time for a 32-bit target.
# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
# both 32-bit and 64-bit outputs updated by the PR author, before
# the PR is approved and tested for merging.
# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
# despite having different output on 32-bit vs 64-bit targets.
- python2.7 ../x.py --stage 2 test src/test/mir-opt \
+ ../x --stage 2 test src/test/mir-opt \
--host='' --target=i686-unknown-linux-gnu && \
# Run the UI test suite again, but in `--pass=check` mode
#
# This is intended to make sure that both `--pass=check` continues to
# work.
#
- python2.7 ../x.py --stage 2 test src/test/ui --pass=check \
+ ../x.ps1 --stage 2 test src/test/ui --pass=check \
--host='' --target=i686-unknown-linux-gnu && \
# Run tidy at the very end, after all the other tests.
python2.7 ../x.py --stage 2 test src/tools/tidy
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 2358091a6..4350ca205 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
+ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
make \
@@ -27,6 +28,7 @@ RUN apt-get install -y \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
+ libgbm1 \
libgcc1 \
libgconf-2-4 \
libgdk-pixbuf2.0-0 \
@@ -59,13 +61,10 @@ RUN apt-get install -y \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
COPY host-x86_64/x86_64-gnu-tools/checktools.sh /tmp/
-RUN curl -sL https://nodejs.org/dist/v14.4.0/node-v14.4.0-linux-x64.tar.xz | tar -xJ
-ENV NODE_FOLDER=/node-v14.4.0-linux-x64/bin
+RUN curl -sL https://nodejs.org/dist/v14.20.0/node-v14.20.0-linux-x64.tar.xz | tar -xJ
+ENV NODE_FOLDER=/node-v14.20.0-linux-x64/bin
ENV PATH="$NODE_FOLDER:${PATH}"
COPY host-x86_64/x86_64-gnu-tools/browser-ui-test.version /tmp/
@@ -85,4 +84,5 @@ ENV RUST_CONFIGURE_ARGS \
--save-toolstates=/tmp/toolstate/toolstates.json
ENV SCRIPT /tmp/checktools.sh ../x.py && \
- NODE_PATH=`npm root -g` python3 ../x.py test src/test/rustdoc-gui --stage 2
+ NODE_PATH=`npm root -g` python3 ../x.py test src/test/rustdoc-gui --stage 2 \
+ --test-args "'--no-sandbox --jobs 1'"
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index bae256fd5..2774f8587 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.9.7 \ No newline at end of file
+0.10.0 \ No newline at end of file
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 412efe5c4..0fb8f41a7 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -14,7 +14,6 @@ python3 "$X_PY" test --stage 2 --no-fail-fast \
src/doc/rust-by-example \
src/doc/embedded-book \
src/doc/edition-guide \
- src/tools/rls \
src/tools/miri \
set -e
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 93b4f435d..69d4916e5 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -213,7 +213,16 @@ else
args="$args --volume $HOME/.cargo:/cargo"
args="$args --volume $HOME/rustsrc:$HOME/rustsrc"
args="$args --volume /tmp/toolstate:/tmp/toolstate"
- args="$args --env LOCAL_USER_ID=`id -u`"
+
+ id=$(id -u)
+ if [[ "$id" != 0 && "$(docker -v)" =~ ^podman ]]; then
+ # Rootless podman creates a separate user namespace, where an inner
+ # LOCAL_USER_ID will map to a different subuid range on the host.
+ # The "keep-id" mode maps the current UID directly into the container.
+ args="$args --env NO_CHANGE_USER=1 --userns=keep-id"
+ else
+ args="$args --env LOCAL_USER_ID=$id"
+ fi
fi
if [ "$dev" = "1" ]
diff --git a/src/ci/docker/scripts/android-base-apt-get.sh b/src/ci/docker/scripts/android-base-apt-get.sh
index f1761f806..22e2e243e 100644
--- a/src/ci/docker/scripts/android-base-apt-get.sh
+++ b/src/ci/docker/scripts/android-base-apt-get.sh
@@ -10,6 +10,7 @@ apt-get install -y --no-install-recommends \
g++ \
git \
libssl-dev \
+ libncurses5 \
make \
ninja-build \
pkg-config \
diff --git a/src/ci/docker/static/gitconfig b/src/ci/docker/static/gitconfig
new file mode 100644
index 000000000..6bad35f01
--- /dev/null
+++ b/src/ci/docker/static/gitconfig
@@ -0,0 +1,2 @@
+[safe]
+directory = *
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 3ad4e3f97..6e4b0b0c2 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -284,7 +284,7 @@ jobs:
- name: mingw-check
<<: *job-linux-xl
- - name: x86_64-gnu-llvm-12
+ - name: x86_64-gnu-llvm-13
<<: *job-linux-xl
- name: x86_64-gnu-tools
@@ -431,12 +431,12 @@ jobs:
- name: x86_64-gnu-distcheck
<<: *job-linux-xl
- - name: x86_64-gnu-llvm-12
+ - name: x86_64-gnu-llvm-13
env:
RUST_BACKTRACE: 1
<<: *job-linux-xl
- - name: x86_64-gnu-llvm-12-stage1
+ - name: x86_64-gnu-llvm-13-stage1
env:
RUST_BACKTRACE: 1
<<: *job-linux-xl
@@ -596,29 +596,51 @@ jobs:
- name: i686-mingw-1
env:
- RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
+ RUST_CONFIGURE_ARGS: >-
+ --build=i686-pc-windows-gnu
+ --set llvm.allow-old-toolchain
SCRIPT: make ci-mingw-subset-1
+ # We are intentionally allowing an old toolchain on this builder (and that's
+ # incompatible with LLVM downloads today).
+ NO_DOWNLOAD_CI_LLVM: 1
CUSTOM_MINGW: 1
<<: *job-windows-xl
- name: i686-mingw-2
env:
- RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
+ RUST_CONFIGURE_ARGS: >-
+ --build=i686-pc-windows-gnu
+ --set llvm.allow-old-toolchain
SCRIPT: make ci-mingw-subset-2
+ # We are intentionally allowing an old toolchain on this builder (and that's
+ # incompatible with LLVM downloads today).
+ NO_DOWNLOAD_CI_LLVM: 1
CUSTOM_MINGW: 1
<<: *job-windows-xl
- name: x86_64-mingw-1
env:
SCRIPT: make ci-mingw-subset-1
- RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-profiler
+ RUST_CONFIGURE_ARGS: >-
+ --build=x86_64-pc-windows-gnu
+ --enable-profiler
+ --set llvm.allow-old-toolchain
+ # We are intentionally allowing an old toolchain on this builder (and that's
+ # incompatible with LLVM downloads today).
+ NO_DOWNLOAD_CI_LLVM: 1
CUSTOM_MINGW: 1
<<: *job-windows-xl
- name: x86_64-mingw-2
env:
SCRIPT: make ci-mingw-subset-2
- RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-profiler
+ RUST_CONFIGURE_ARGS: >-
+ --build=x86_64-pc-windows-gnu
+ --enable-profiler
+ --set llvm.allow-old-toolchain
+ # We are intentionally allowing an old toolchain on this builder (and that's
+ # incompatible with LLVM downloads today).
+ NO_DOWNLOAD_CI_LLVM: 1
CUSTOM_MINGW: 1
<<: *job-windows-xl
@@ -654,8 +676,7 @@ jobs:
--enable-full-tools
--enable-profiler
SCRIPT: python x.py dist
- # RLS does not build for aarch64-pc-windows-msvc. See rust-lang/rls#1693
- DIST_REQUIRE_ALL_TOOLS: 0
+ DIST_REQUIRE_ALL_TOOLS: 1
# Hack around this SDK version, because it doesn't work with clang.
# See https://github.com/rust-lang/rust/issues/88796
WINDOWS_SDK_20348_HACK: 1
@@ -663,7 +684,14 @@ jobs:
- name: dist-i686-mingw
env:
- RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler
+ RUST_CONFIGURE_ARGS: >-
+ --build=i686-pc-windows-gnu
+ --enable-full-tools
+ --enable-profiler
+ --set llvm.allow-old-toolchain
+ # We are intentionally allowing an old toolchain on this builder (and that's
+ # incompatible with LLVM downloads today).
+ NO_DOWNLOAD_CI_LLVM: 1
SCRIPT: python x.py dist
CUSTOM_MINGW: 1
DIST_REQUIRE_ALL_TOOLS: 1
@@ -672,7 +700,14 @@ jobs:
- name: dist-x86_64-mingw
env:
SCRIPT: python x.py dist
- RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler
+ RUST_CONFIGURE_ARGS: >-
+ --build=x86_64-pc-windows-gnu
+ --enable-full-tools
+ --enable-profiler
+ --set llvm.allow-old-toolchain
+ # We are intentionally allowing an old toolchain on this builder (and that's
+ # incompatible with LLVM downloads today).
+ NO_DOWNLOAD_CI_LLVM: 1
CUSTOM_MINGW: 1
DIST_REQUIRE_ALL_TOOLS: 1
<<: *job-windows-xl
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 6545475d9..9a247fb60 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -11,6 +11,16 @@ if [ "$NO_CHANGE_USER" = "" ]; then
useradd --shell /bin/bash -u $LOCAL_USER_ID -o -c "" -m user
export HOME=/home/user
unset LOCAL_USER_ID
+
+ # Ensure that runners are able to execute git commands in the worktree,
+ # overriding the typical git protections. In our docker container we're running
+ # as root, while the user owning the checkout is not root.
+ # This is only necessary when we change the user, otherwise we should
+ # already be running with the right user.
+ #
+ # For NO_CHANGE_USER done in the small number of Dockerfiles affected.
+ echo -e '[safe]\n\tdirectory = *' > /home/user/gitconfig
+
exec su --preserve-environment -c "env PATH=$PATH \"$0\"" user
fi
fi
@@ -102,6 +112,18 @@ else
fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
+
+ # We enable this for non-dist builders, since those aren't trying to produce
+ # fresh binaries. We currently don't entirely support distributing a fresh
+ # copy of the compiler (including llvm tools, etc.) if we haven't actually
+ # built LLVM, since not everything necessary is copied into the
+ # local-usage-only LLVM artifacts. If that changes, this could maybe be made
+ # true for all builds. In practice it's probably a good idea to keep building
+ # LLVM continuously on at least some builders to ensure it works, though.
+ # (And PGO is its own can of worms).
+ if [ "$NO_DOWNLOAD_CI_LLVM" = "" ]; then
+ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.download-ci-llvm=if-available"
+ fi
fi
if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]; then
diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh
index 0bc8a0389..02b72625d 100755
--- a/src/ci/scripts/install-clang.sh
+++ b/src/ci/scripts/install-clang.sh
@@ -61,6 +61,10 @@ elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then
7z x -oclang-rust/ "LLVM-${LLVM_VERSION}-win64.exe"
ciCommandSetEnv RUST_CONFIGURE_ARGS \
"${RUST_CONFIGURE_ARGS} --set llvm.clang-cl=$(pwd)/clang-rust/bin/clang-cl.exe"
+
+ # Disable downloading CI LLVM on this builder;
+ # setting up clang-cl just above conflicts with the default if-available option.
+ ciCommandSetEnv NO_DOWNLOAD_CI_LLVM 1
fi
if isWindows; then
diff --git a/src/doc/book/2018-edition/book.toml b/src/doc/book/2018-edition/book.toml
index 9c71e2a91..03b59090b 100644
--- a/src/doc/book/2018-edition/book.toml
+++ b/src/doc/book/2018-edition/book.toml
@@ -3,5 +3,5 @@ title = "The Rust Programming Language"
author = "Steve Klabnik and Carol Nichols, with Contributions from the Rust Community"
[output.html]
-additional-css = ["ferris.css", "src/theme/2018-edition.css"]
+additional-css = ["ferris.css"]
additional-js = ["ferris.js"]
diff --git a/src/doc/book/2018-edition/src/theme/2018-edition.css b/src/doc/book/2018-edition/src/theme/2018-edition.css
deleted file mode 100644
index b1dcf9364..000000000
--- a/src/doc/book/2018-edition/src/theme/2018-edition.css
+++ /dev/null
@@ -1,9 +0,0 @@
-span.caption {
- font-size: .8em;
- font-weight: 600;
-}
-
-span.caption code {
- font-size: 0.875em;
- font-weight: 400;
-}
diff --git a/src/doc/book/2018-edition/src/theme/index.hbs b/src/doc/book/2018-edition/src/theme/index.hbs
deleted file mode 100644
index f3f1b52fa..000000000
--- a/src/doc/book/2018-edition/src/theme/index.hbs
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="{{ language }}" class="no-js">
- <head>
- <!-- Book generated using mdBook -->
- <meta charset="UTF-8">
- <title>Outdated link: {{ title }}</title>
- <meta name="robots" content="noindex,follow">
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
-
- <base href="{{ path_to_root }}">
-
- <link rel="stylesheet" href="book.css">
- <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
- <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
-
- <link rel="stylesheet" href="highlight.css">
- <link rel="stylesheet" href="tomorrow-night.css">
- <link rel="stylesheet" href="ayu-highlight.css">
-
- <!-- Custom theme stylesheets -->
- {{#each additional_css}}
- <link rel="stylesheet" href="{{this}}">
- {{/each}}
- </head>
- <body class="light">
- <div id="page-wrapper" class="page-wrapper">
- <div class="page">
- {{> header}}
- <div id="content" class="content">
- <main>
- {{{ content }}}
- </main>
- </div>
- </div>
- </div>
- </body>
-</html>
diff --git a/src/doc/book/listings/ch20-web-server/listing-20-24/src/lib.rs b/src/doc/book/listings/ch20-web-server/listing-20-24/src/lib.rs
index 55e8fef8f..28c0dea26 100644
--- a/src/doc/book/listings/ch20-web-server/listing-20-24/src/lib.rs
+++ b/src/doc/book/listings/ch20-web-server/listing-20-24/src/lib.rs
@@ -70,7 +70,9 @@ struct Worker {
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(move || loop {
- match receiver.lock().unwrap().recv() {
+ let message = receiver.lock().unwrap().recv();
+
+ match message {
Ok(job) => {
println!("Worker {id} got a job; executing.");
diff --git a/src/doc/book/src/ch01-03-hello-cargo.md b/src/doc/book/src/ch01-03-hello-cargo.md
index 135eacd2f..9979e76dd 100644
--- a/src/doc/book/src/ch01-03-hello-cargo.md
+++ b/src/doc/book/src/ch01-03-hello-cargo.md
@@ -66,6 +66,8 @@ name = "hello_cargo"
version = "0.1.0"
edition = "2021"
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
[dependencies]
```
diff --git a/src/doc/book/src/ch06-02-match.md b/src/doc/book/src/ch06-02-match.md
index a24936829..2dfe6c34b 100644
--- a/src/doc/book/src/ch06-02-match.md
+++ b/src/doc/book/src/ch06-02-match.md
@@ -17,7 +17,7 @@ the value falls into the associated code block to be used during execution.
Speaking of coins, let’s use them as an example using `match`! We can write a
function that takes an unknown United States coin and, in a similar way as the
-counting machine, determines which coin it is and return its value in cents, as
+counting machine, determines which coin it is and returns its value in cents, as
shown here in Listing 6-3.
```rust
diff --git a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
index 61931f08d..347ef9aa7 100644
--- a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
+++ b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
@@ -524,7 +524,7 @@ returns integers from executables to be compatible with this convention.
The `main` function may return any types that implement [the
`std::process::Termination` trait][termination]<!-- ignore -->, which contains
-a function `report` that returns an `ExitCode` Consult the standard library
+a function `report` that returns an `ExitCode`. Consult the standard library
documentation for more information on implementing the `Termination` trait for
your own types.
diff --git a/src/doc/book/src/ch20-02-multithreaded.md b/src/doc/book/src/ch20-02-multithreaded.md
index bd1dc25ab..5a4a50ac0 100644
--- a/src/doc/book/src/ch20-02-multithreaded.md
+++ b/src/doc/book/src/ch20-02-multithreaded.md
@@ -387,7 +387,7 @@ 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.
+they’re responsible for taking those orders and fulfilling 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
diff --git a/src/doc/book/src/title-page.md b/src/doc/book/src/title-page.md
index 47226dc84..ed55a6839 100644
--- a/src/doc/book/src/title-page.md
+++ b/src/doc/book/src/title-page.md
@@ -20,3 +20,7 @@ Press][nsprust].
[editions]: appendix-05-editions.html
[nsprust]: https://nostarch.com/rust
[translations]: appendix-06-translation.html
+
+> **🚨 Want a more interactive learning experience? Try out a different version
+> of the Rust Book, featuring: quizzes, highlighting, visualizations, and
+> more**: <https://rust-book.cs.brown.edu>
diff --git a/src/doc/edition-guide/README.md b/src/doc/edition-guide/README.md
index 559498257..3f3994381 100644
--- a/src/doc/edition-guide/README.md
+++ b/src/doc/edition-guide/README.md
@@ -8,8 +8,8 @@ online](https://doc.rust-lang.org/nightly/edition-guide/).
## License
-The Edition Guide is dual licensed under `MIT`/`Apache2`, just like Rust itself.
-See the `LICENSE-*` files in this repository for more details.
+The Rust Edition Guide is dual licensed under `MIT`/`Apache2`, just like Rust
+itself. See the `LICENSE-*` files in this repository for more details.
## Building locally
diff --git a/src/doc/edition-guide/book.toml b/src/doc/edition-guide/book.toml
index 8d8b26322..7841b647d 100644
--- a/src/doc/edition-guide/book.toml
+++ b/src/doc/edition-guide/book.toml
@@ -2,7 +2,7 @@
authors = ["The Rust Project Developers"]
multilingual = false
src = "src"
-title = "The Edition Guide"
+title = "The Rust Edition Guide"
[output.html]
git-repository-url = "https://github.com/rust-lang/edition-guide"
diff --git a/src/doc/edition-guide/src/SUMMARY.md b/src/doc/edition-guide/src/SUMMARY.md
index dac77913b..9ac69923f 100644
--- a/src/doc/edition-guide/src/SUMMARY.md
+++ b/src/doc/edition-guide/src/SUMMARY.md
@@ -1,4 +1,4 @@
-# The Edition Guide
+# The Rust Edition Guide
[Introduction](introduction.md)
diff --git a/src/doc/edition-guide/src/editions/creating-a-new-project.md b/src/doc/edition-guide/src/editions/creating-a-new-project.md
index 319d6996c..8ec71d67e 100644
--- a/src/doc/edition-guide/src/editions/creating-a-new-project.md
+++ b/src/doc/edition-guide/src/editions/creating-a-new-project.md
@@ -1,12 +1,12 @@
# Creating a new project
-When you create a new project with Cargo, it will automatically add
-configuration for the latest edition:
+A new project created with Cargo is configured to use the latest edition by
+default:
```console
-> cargo new foo
+$ cargo new foo
Created binary (application) `foo` project
-> cat foo/Cargo.toml
+$ cat foo/Cargo.toml
[package]
name = "foo"
version = "0.1.0"
@@ -15,11 +15,41 @@ edition = "2021"
[dependencies]
```
-That `edition = "2021"` setting will configure your package to use Rust 2021.
-No more configuration needed!
+That `edition = "2021"` setting configures your package to be built using the
+Rust 2021 edition. No further configuration needed!
-If you'd prefer to use an older edition, you can change the value in that
-key, for example:
+You can use the `--edition <YEAR>` option of `cargo new` to create the project
+using some specific edition. For example, creating a new project to use the
+Rust 2018 edition could be done like this:
+
+```console
+$ cargo new --edition 2018 foo
+ Created binary (application) `foo` project
+$ cat foo/Cargo.toml
+[package]
+name = "foo"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+```
+
+Don't worry about accidentally using an invalid year for the edition; the
+`cargo new` invocation will not accept an invalid edition year value:
+
+```console
+$ cargo new --edition 2019 foo
+error: "2019" isn't a valid value for '--edition <YEAR>'
+ [possible values: 2015, 2018, 2021]
+
+ Did you mean "2018"?
+
+For more information try --help
+```
+
+You can change the value of the `edition` key by simply editing the
+`Cargo.toml` file. For example, to cause your package to be built using the
+Rust 2015 edition, you would set the key as in the following example:
```toml
[package]
@@ -29,5 +59,3 @@ edition = "2015"
[dependencies]
```
-
-This will build your package in Rust 2015.
diff --git a/src/doc/edition-guide/src/editions/index.md b/src/doc/edition-guide/src/editions/index.md
index e12285c49..b5480e809 100644
--- a/src/doc/edition-guide/src/editions/index.md
+++ b/src/doc/edition-guide/src/editions/index.md
@@ -1,6 +1,8 @@
# What are Editions?
-The release of Rust 1.0 established
+The release of Rust 1.0
+([in May 2015](https://blog.rust-lang.org/2015/05/15/Rust-1.0.html))
+established
["stability without stagnation"](https://blog.rust-lang.org/2014/10/30/Stability.html)
as a core Rust deliverable.
Ever since the 1.0 release,
@@ -51,11 +53,11 @@ there might be some corner cases where manual changes are still required.
The tooling tries hard to avoid changes
to semantics that could affect the correctness or performance of the code.
-In addition to tooling, we also maintain this Edition Migration Guide that covers
+In addition to tooling, we also maintain this Rust Edition Guide that covers
the changes that are part of an edition.
This guide describes each change and gives pointers to where you can learn more about it.
It also covers any corner cases or details you should be aware of.
-This guide serves both as an overview of the edition
+This guide serves as an overview of editions,
+as a migration guide for specific editions,
and as a quick troubleshooting reference
if you encounter problems with the automated tooling.
-
diff --git a/src/doc/edition-guide/src/introduction.md b/src/doc/edition-guide/src/introduction.md
index c23508b2f..a36a620a8 100644
--- a/src/doc/edition-guide/src/introduction.md
+++ b/src/doc/edition-guide/src/introduction.md
@@ -1,6 +1,6 @@
# Introduction
-Welcome to the Rust Edition Guide! "Editions" are Rust's way of introducing
+Welcome to The Rust Edition Guide! "Editions" are Rust's way of introducing
changes into the language that would not otherwise be backwards
compatible.
diff --git a/src/doc/index.md b/src/doc/index.md
index b77790e33..744c7f709 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -101,7 +101,7 @@ accomplishing various tasks.
Many of Rust's errors come with error codes, and you can request extended
diagnostics from the compiler on those errors. You can also [read them
-here](error-index.html), if you prefer to read them that way.
+here](error_codes/index.html), if you prefer to read them that way.
# Master Rust
diff --git a/src/doc/nomicon/src/lifetime-mismatch.md b/src/doc/nomicon/src/lifetime-mismatch.md
index 0494d492a..1da2d285c 100644
--- a/src/doc/nomicon/src/lifetime-mismatch.md
+++ b/src/doc/nomicon/src/lifetime-mismatch.md
@@ -76,7 +76,7 @@ care about, but the lifetime system is too coarse-grained to handle that.
The following code fails to compile, because Rust sees that a variable, `map`,
is borrowed twice, and can not infer that the first borrow stops to be needed
before the second one occurs. This is caused by Rust conservatively falling back
-to using a whole scope for the first borow. This will eventually get fixed.
+to using a whole scope for the first borrow. This will eventually get fixed.
```rust,compile_fail
# use std::collections::HashMap;
diff --git a/src/doc/nomicon/src/lifetimes.md b/src/doc/nomicon/src/lifetimes.md
index ef86b7b53..f55ea8c2a 100644
--- a/src/doc/nomicon/src/lifetimes.md
+++ b/src/doc/nomicon/src/lifetimes.md
@@ -55,7 +55,7 @@ likely desugar to the following:
let y: &'b i32 = &'b x;
'c: {
// ditto on 'c
- let z: &'c &'b i32 = &'c y;
+ let z: &'c &'b i32 = &'c y; // "a reference to a reference to an i32" (with lifetimes annotated)
}
}
}
diff --git a/src/doc/nomicon/src/other-reprs.md b/src/doc/nomicon/src/other-reprs.md
index 93da7297e..228b22bda 100644
--- a/src/doc/nomicon/src/other-reprs.md
+++ b/src/doc/nomicon/src/other-reprs.md
@@ -56,24 +56,26 @@ compiled as normal.)
## repr(transparent)
-This can only be used on structs with a single non-zero-sized field (there may
-be additional zero-sized fields). The effect is that the layout and ABI of the
-whole struct is guaranteed to be the same as that one field.
+`#[repr(transparent)]` can only be used on a struct or single-variant enum that has a single non-zero-sized field (there may be additional zero-sized fields).
+The effect is that the layout and ABI of the whole struct/enum is guaranteed to be the same as that one field.
+
+> NOTE: There's a `transparent_unions` nightly feature to apply `repr(transparent)` to unions,
+> but it hasn't been stabilized due to design concerns. See the [tracking issue][issue-60405] for more details.
The goal is to make it possible to transmute between the single field and the
-struct. An example of that is [`UnsafeCell`], which can be transmuted into
+struct/enum. An example of that is [`UnsafeCell`], which can be transmuted into
the type it wraps ([`UnsafeCell`] also uses the unstable [no_niche][no-niche-pull],
so its ABI is not actually guaranteed to be the same when nested in other types).
-Also, passing the struct through FFI where the inner field type is expected on
-the other side is guaranteed to work. In particular, this is necessary for `struct
-Foo(f32)` to always have the same ABI as `f32`.
+Also, passing the struct/enum through FFI where the inner field type is expected on
+the other side is guaranteed to work. In particular, this is necessary for
+`struct Foo(f32)` or `enum Foo { Bar(f32) }` to always have the same ABI as `f32`.
This repr is only considered part of the public ABI of a type if either the single
field is `pub`, or if its layout is documented in prose. Otherwise, the layout should
not be relied upon by other crates.
-More details are in the [RFC][rfc-transparent].
+More details are in the [RFC 1758][rfc-transparent] and the [RFC 2645][rfc-transparent-unions-enums].
## repr(u*), repr(i*)
@@ -153,8 +155,10 @@ This is a modifier on `repr(C)` and `repr(Rust)`. It is incompatible with
[unsafe code guidelines]: https://rust-lang.github.io/unsafe-code-guidelines/layout.html
[drop flags]: drop-flags.html
[ub loads]: https://github.com/rust-lang/rust/issues/27060
+[issue-60405]: https://github.com/rust-lang/rust/issues/60405
[`UnsafeCell`]: ../std/cell/struct.UnsafeCell.html
[rfc-transparent]: https://github.com/rust-lang/rfcs/blob/master/text/1758-repr-transparent.md
+[rfc-transparent-unions-enums]: https://rust-lang.github.io/rfcs/2645-transparent-unions.html
[really-tagged]: https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md
[rust-bindgen]: https://rust-lang.github.io/rust-bindgen/
[cbindgen]: https://github.com/eqrion/cbindgen
diff --git a/src/doc/reference/book.toml b/src/doc/reference/book.toml
index 2bc218fe4..19b9afc79 100644
--- a/src/doc/reference/book.toml
+++ b/src/doc/reference/book.toml
@@ -6,6 +6,7 @@ author = "The Rust Project Developers"
[output.html]
additional-css = ["theme/reference.css"]
git-repository-url = "https://github.com/rust-lang/reference/"
+edit-url-template = "https://github.com/rust-lang/reference/edit/master/{path}"
[output.html.redirect]
"/expressions/enum-variant-expr.html" = "struct-expr.html"
diff --git a/src/doc/reference/src/attributes/testing.md b/src/doc/reference/src/attributes/testing.md
index 63df999ad..2c3b29286 100644
--- a/src/doc/reference/src/attributes/testing.md
+++ b/src/doc/reference/src/attributes/testing.md
@@ -12,9 +12,8 @@ functions are only compiled when in test mode. Test functions must be free,
monomorphic functions that take no arguments, and the return type must implement the [`Termination`] trait, for example:
* `()`
-* `Result<(), E> where E: Debug`
+* `Result<T, E> where T: Termination, E: Debug`
* `!`
-<!-- * Result<!, E> where E: Debug` -->
<!-- If the previous section needs updating (from "must take no arguments"
onwards, also update it in the crates-and-source-files.md file -->
diff --git a/src/doc/reference/src/attributes/type_system.md b/src/doc/reference/src/attributes/type_system.md
index 729069d26..71b0243a6 100644
--- a/src/doc/reference/src/attributes/type_system.md
+++ b/src/doc/reference/src/attributes/type_system.md
@@ -127,6 +127,14 @@ match message {
}
```
+It's also not allowed to cast non-exhaustive types from foreign crates.
+```rust, ignore
+use othercrate::NonExhaustiveEnum;
+
+// Cannot cast a non-exhaustive enum outside of its defining crate.
+let _ = NonExhaustiveEnum::default() as u8;
+```
+
Non-exhaustive types are always considered inhabited in downstream crates.
[_MetaWord_]: ../attributes.md#meta-item-attribute-syntax
diff --git a/src/doc/reference/src/crates-and-source-files.md b/src/doc/reference/src/crates-and-source-files.md
index 6922b0ee3..8d54c3f6b 100644
--- a/src/doc/reference/src/crates-and-source-files.md
+++ b/src/doc/reference/src/crates-and-source-files.md
@@ -123,10 +123,9 @@ fn main() -> impl std::process::Termination {
>
> * `()`
> * [`!`]
+> * [`Infallible`]
> * [`ExitCode`]
-> * `Result<(), E> where E: Debug`
-> * `Result<Infallible, E> where E: Debug`
-<!-- > * Result<!, E> where E: Debug` -->
+> * `Result<T, E> where T: Termination, E: Debug`
<!-- If the previous section needs updating (from "must take no arguments"
onwards, also update it in the testing.md file -->
@@ -165,6 +164,7 @@ or `_` (U+005F) characters.
[_shebang_]: https://en.wikipedia.org/wiki/Shebang_(Unix)
[_utf8 byte order mark_]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
[`ExitCode`]: ../std/process/struct.ExitCode.html
+[`Infallible`]: ../std/convert/enum.Infallible.html
[`Termination`]: ../std/process/trait.Termination.html
[attribute]: attributes.md
[attributes]: attributes.md
diff --git a/src/doc/rust-by-example/book.toml b/src/doc/rust-by-example/book.toml
index 19db456b6..61fb4057f 100644
--- a/src/doc/rust-by-example/book.toml
+++ b/src/doc/rust-by-example/book.toml
@@ -6,6 +6,7 @@ author = "The Rust Community"
[output.html.playpen]
editable = true
editor = "ace"
+line-numbers = true
[output.html.fold]
enable = true
diff --git a/src/doc/rust-by-example/src/SUMMARY.md b/src/doc/rust-by-example/src/SUMMARY.md
index 223a5d8dd..9d7001690 100644
--- a/src/doc/rust-by-example/src/SUMMARY.md
+++ b/src/doc/rust-by-example/src/SUMMARY.md
@@ -219,4 +219,4 @@
- [Meta](meta.md)
- [Documentation](meta/doc.md)
- - [Playpen](meta/playpen.md)
+ - [Playground](meta/playground.md)
diff --git a/src/doc/rust-by-example/src/error/option_unwrap/defaults.md b/src/doc/rust-by-example/src/error/option_unwrap/defaults.md
index c998ad9ad..eb515aee6 100644
--- a/src/doc/rust-by-example/src/error/option_unwrap/defaults.md
+++ b/src/doc/rust-by-example/src/error/option_unwrap/defaults.md
@@ -8,7 +8,7 @@ The is more than one way to unpack an `Option` and fall back on a default if it
`or()`is chainable and eagerly evaluates its argument, as is shown in the following example. Note that because `or`'s arguments are evaluated eagerly, the variable passed to `or` is moved.
-```
+```rust,editable
#[derive(Debug)]
enum Fruit { Apple, Orange, Banana, Kiwi, Lemon }
@@ -33,7 +33,7 @@ fn main() {
Another alternative is to use `or_else`, which is also chainable, and evaluates lazily, as is shown in the following example:
-```
+```rust,editable
#[derive(Debug)]
enum Fruit { Apple, Orange, Banana, Kiwi, Lemon }
@@ -58,11 +58,11 @@ fn main() {
}
```
-## `get_or_insert()` evaluates eagerly, modifies empty value im place
+## `get_or_insert()` evaluates eagerly, modifies empty value in place
To make sure that an `Option` contains a value, we can use `get_or_insert` to modify it in place with a fallback value, as is shown in the following example. Note that `get_or_insert` eagerly evaluaes its parameter, so variable `apple` is moved:
-```
+```rust,editable
#[derive(Debug)]
enum Fruit { Apple, Orange, Banana, Kiwi, Lemon }
@@ -79,10 +79,10 @@ fn main() {
}
```
-## `get_or_insert_with()` evaluates lazily, modifies empty value im place
+## `get_or_insert_with()` evaluates lazily, modifies empty value in place
Instead of explicitly providing a value to fall back on, we can pass a closure to `get_or_insert_with`, as follows:
-```
+```rust,editable
#[derive(Debug)]
enum Fruit { Apple, Orange, Banana, Kiwi, Lemon }
diff --git a/src/doc/rust-by-example/src/flow_control.md b/src/doc/rust-by-example/src/flow_control.md
index c8a2f9ed8..79ef7e1f6 100644
--- a/src/doc/rust-by-example/src/flow_control.md
+++ b/src/doc/rust-by-example/src/flow_control.md
@@ -1,4 +1,4 @@
# Flow of Control
-An essential part of any programming languages are ways to modify control flow:
+An integral part of any programming language are ways to modify control flow:
`if`/`else`, `for`, and others. Let's talk about them in Rust.
diff --git a/src/doc/rust-by-example/src/hello/print.md b/src/doc/rust-by-example/src/hello/print.md
index 34dc9f0dd..c28dd9125 100644
--- a/src/doc/rust-by-example/src/hello/print.md
+++ b/src/doc/rust-by-example/src/hello/print.md
@@ -31,18 +31,20 @@ fn main() {
// Different formatting can be invoked by specifying the format character after a
// `:`.
- println!("Base 10 repr: {}", 69420);
- println!("Base 2 (binary) repr: {:b}", 69420);
- println!("Base 8 (octal) repr: {:o}", 69420);
- println!("Base 16 (hexadecimal) repr: {:x}", 69420);
- println!("Base 16 (hexadecimal) repr: {:X}", 69420);
-
- // You can right-align text with a specified width. This will output
- // " 1". 4 white spaces and a "1", for a total width of 5.
+ println!("Base 10: {}", 69420); //69420
+ println!("Base 2 (binary): {:b}", 69420); //10000111100101100
+ println!("Base 8 (octal): {:o}", 69420); //207454
+ println!("Base 16 (hexadecimal): {:x}", 69420); //10f2c
+ println!("Base 16 (hexadecimal): {:X}", 69420); //10F2C
+
+
+ // You can right-justify text with a specified width. This will
+ // output " 1". (Four white spaces and a "1", for a total width of 5.)
println!("{number:>5}", number=1);
- // You can pad numbers with extra zeroes. This will output "00001".
- println!("{number:0>5}", number=1);
+ // You can pad numbers with extra zeroes,
+ //and left-adjust by flipping the sign. This will output "10000".
+ println!("{number:0<5}", number=1);
// You can use named arguments in the format specifier by appending a `$`
println!("{number:0>width$}", number=1, width=5);
diff --git a/src/doc/rust-by-example/src/meta.md b/src/doc/rust-by-example/src/meta.md
index 367c7e121..8fcea1df0 100644
--- a/src/doc/rust-by-example/src/meta.md
+++ b/src/doc/rust-by-example/src/meta.md
@@ -6,7 +6,7 @@ everyone. These topics include:
- [Documentation][doc]: Generate library documentation for users via the included
`rustdoc`.
-- [Playpen][playpen]: Integrate the Rust Playpen (also known as the Rust Playground) in your documentation.
+- [Playground][playground]: Integrate the Rust Playground in your documentation.
[doc]: meta/doc.md
-[playpen]: meta/playpen.md
+[playground]: meta/playground.md
diff --git a/src/doc/rust-by-example/src/meta/doc.md b/src/doc/rust-by-example/src/meta/doc.md
index 63e0b4101..e9e51186f 100644
--- a/src/doc/rust-by-example/src/meta/doc.md
+++ b/src/doc/rust-by-example/src/meta/doc.md
@@ -44,7 +44,7 @@ impl Person {
/// Gives a friendly hello!
///
- /// Says "Hello, [name]" to the `Person` it is called on.
+ /// Says "Hello, [name](Person::name)" to the `Person` it is called on.
pub fn hello(& self) {
println!("Hello, {}!", self.name);
}
diff --git a/src/doc/rust-by-example/src/meta/playpen.md b/src/doc/rust-by-example/src/meta/playground.md
index a125f139d..7fcfad1a7 100644
--- a/src/doc/rust-by-example/src/meta/playpen.md
+++ b/src/doc/rust-by-example/src/meta/playground.md
@@ -1,6 +1,6 @@
-# Playpen
+# Playground
-The [Rust Playpen](https://github.com/rust-lang/rust-playpen) is a way to experiment with Rust code through a web interface. This project is now commonly referred to as [Rust Playground](https://play.rust-lang.org/).
+The [Rust Playground](https://play.rust-lang.org/) is a way to experiment with Rust code through a web interface.
## Using it with `mdbook`
@@ -35,11 +35,11 @@ You may have noticed in some of the [official Rust docs][official-rust-docs] a b
### See also:
- [The Rust Playground][rust-playground]
-- [The next-gen playpen][next-gen-playpen]
+- [rust-playground][rust-playground]
- [The rustdoc Book][rustdoc-book]
[rust-playground]: https://play.rust-lang.org/
-[next-gen-playpen]: https://github.com/integer32llc/rust-playground/
+[rust-playground]: https://github.com/integer32llc/rust-playground/
[mdbook]: https://github.com/rust-lang/mdBook
[official-rust-docs]: https://doc.rust-lang.org/core/
[rustdoc-book]: https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html
diff --git a/src/doc/rust-by-example/src/std_misc/threads/testcase_mapreduce.md b/src/doc/rust-by-example/src/std_misc/threads/testcase_mapreduce.md
index 28075164f..ee25b1661 100644
--- a/src/doc/rust-by-example/src/std_misc/threads/testcase_mapreduce.md
+++ b/src/doc/rust-by-example/src/std_misc/threads/testcase_mapreduce.md
@@ -17,9 +17,11 @@ its tiny block of digits, and subsequently we will sum the intermediate sums pro
thread.
Note that, although we're passing references across thread boundaries, Rust understands that we're
-only passing read-only references, and that thus no unsafety or data races can occur. Because
-we're `move`-ing the data segments into the thread, Rust will also ensure the data is kept alive
-until the threads exit, so no dangling pointers occur.
+only passing read-only references, and that thus no unsafety or data races can occur. Also because
+the references we're passing have `'static` lifetimes, Rust understands that our data won't be
+destroyed while these threads are still running. (When you need to share non-`static` data between
+threads, you can use a smart pointer like `Arc` to keep the data alive and avoid non-`static`
+lifetimes.)
```rust,editable
use std::thread;
diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml
index 51dc8ecb0..c86ec5638 100644
--- a/src/doc/rustc-dev-guide/book.toml
+++ b/src/doc/rustc-dev-guide/book.toml
@@ -15,7 +15,7 @@ command = "mdbook-mermaid"
[output.html]
git-repository-url = "https://github.com/rust-lang/rustc-dev-guide"
-edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/tree/master/{path}?mode=edit"
+edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/edit/master/{path}"
additional-js = ["mermaid.min.js", "mermaid-init.js"]
[output.html.fold]
diff --git a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
index bbea2bf38..70fce8b1c 100644
--- a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
+++ b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
@@ -3,9 +3,11 @@ use std::{
convert::TryInto as _,
env, fmt, fs,
path::{Path, PathBuf},
+ process,
+ str::FromStr,
};
-use chrono::{Datelike as _, TimeZone as _, Utc};
+use chrono::{Datelike as _, Month, TimeZone as _, Utc};
use glob::glob;
use regex::Regex;
@@ -38,12 +40,18 @@ impl fmt::Display for Date {
fn make_date_regex() -> Regex {
Regex::new(
r"(?x) # insignificant whitespace mode
- <!--\s*
- [dD]ate:\s*
- (?P<y>\d{4}) # year
- -
- (?P<m>\d{2}) # month
- \s*-->",
+ (<!--\s*
+ date-check:\s*
+ (?P<m1>[[:alpha:]]+)\s+
+ (?P<y1>\d{4})\s*-->
+ )
+ |
+ (<!--\s*
+ date-check\s*-->\s+
+ (?P<m2>[[:alpha:]]+)\s+
+ (?P<y2>\d{4})\b
+ )
+ ",
)
.unwrap()
}
@@ -52,15 +60,22 @@ fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)>
let mut line = 1;
let mut end_of_last_cap = 0;
date_regex
- .captures_iter(&text)
- .map(|cap| {
- (
- cap.get(0).unwrap().range(),
- Date {
- year: cap["y"].parse().unwrap(),
- month: cap["m"].parse().unwrap(),
- },
- )
+ .captures_iter(text)
+ .filter_map(|cap| {
+ if let (Some(month), Some(year), None, None) | (None, None, Some(month), Some(year)) = (
+ cap.name("m1"),
+ cap.name("y1"),
+ cap.name("m2"),
+ cap.name("y2"),
+ ) {
+ let year = year.as_str().parse().expect("year");
+ let month = Month::from_str(month.as_str())
+ .expect("month")
+ .number_from_month();
+ Some((cap.get(0).expect("all").range(), Date { year, month }))
+ } else {
+ None
+ }
})
.map(|(byte_range, date)| {
line += text[end_of_last_cap..byte_range.end]
@@ -110,9 +125,12 @@ fn filter_dates(
}
fn main() {
- let root_dir = env::args()
- .nth(1)
- .expect("expect root Markdown directory as CLI argument");
+ let mut args = env::args();
+ if args.len() == 1 {
+ eprintln!("error: expected root Markdown directory as CLI argument");
+ process::exit(1);
+ }
+ let root_dir = args.nth(1).unwrap();
let root_dir_path = Path::new(&root_dir);
let glob_pat = format!("{}/**/*.md", root_dir);
let today_chrono = Utc::today();
@@ -136,7 +154,7 @@ fn main() {
up-to-date. Each date should be updated (in the Markdown file where it appears) to \
use the current month ({current_month}), or removed if the docs it annotates are not \
expected to fall out of date quickly.",
- current_month = current_month
+ current_month = today_chrono.format("%B %Y"),
);
println!();
println!(
@@ -153,7 +171,7 @@ fn main() {
for (path, dates) in dates_by_file {
println!(
"- [ ] {}",
- path.strip_prefix(&root_dir_path).unwrap().display()
+ path.strip_prefix(&root_dir_path).unwrap_or(&path).display(),
);
for (line, date) in dates {
println!(" - [ ] line {}: {}", line, date);
@@ -182,61 +200,153 @@ mod tests {
#[test]
fn test_date_regex() {
- let regex = make_date_regex();
- assert!(regex.is_match("foo <!-- date: 2021-01 --> bar"));
+ let regex = &make_date_regex();
+ assert!(regex.is_match("<!-- date-check: jan 2021 -->"));
+ assert!(regex.is_match("<!-- date-check: january 2021 -->"));
+ assert!(regex.is_match("<!-- date-check: Jan 2021 -->"));
+ assert!(regex.is_match("<!-- date-check: January 2021 -->"));
+ assert!(regex.is_match("<!-- date-check --> jan 2021"));
+ assert!(regex.is_match("<!-- date-check --> january 2021"));
+ assert!(regex.is_match("<!-- date-check --> Jan 2021"));
+ assert!(regex.is_match("<!-- date-check --> January 2021"));
+
+ assert!(regex.is_match("<!-- date-check --> jan 2021 "));
+ assert!(regex.is_match("<!-- date-check --> jan 2021."));
}
#[test]
- fn test_date_regex_capitalized() {
- let regex = make_date_regex();
- assert!(regex.is_match("foo <!-- Date: 2021-08 --> bar"));
+ fn test_date_regex_fail() {
+ let regexes = &make_date_regex();
+ assert!(!regexes.is_match("<!-- date-check: jan 221 -->"));
+ assert!(!regexes.is_match("<!-- date-check: jan 20221 -->"));
+ assert!(!regexes.is_match("<!-- date-check: 01 2021 -->"));
+ assert!(!regexes.is_match("<!-- date-check --> jan 221"));
+ assert!(!regexes.is_match("<!-- date-check --> jan 20222"));
+ assert!(!regexes.is_match("<!-- date-check --> 01 2021"));
}
#[test]
fn test_collect_dates_from_file() {
- let text = "Test1\n<!-- date: 2021-01 -->\nTest2\nFoo<!-- date: 2021-02 \
- -->\nTest3\nTest4\nFoo<!-- date: 2021-03 -->Bar\n<!-- date: 2021-04 \
- -->\nTest5\nTest6\nTest7\n<!-- date: \n\n2021-05 -->\nTest8
+ let text = r"
+Test1
+<!-- date-check: jan 2021 -->
+Test2
+Foo<!-- date-check: february 2021
+-->
+Test3
+Test4
+Foo<!-- date-check: Mar 2021 -->Bar
+<!-- date-check:April 2021
+-->
+Test5
+Test6
+Test7
+<!-- date-check:
+
+may 2021 -->
+Test8
+Test1
+<!-- date-check --> jan 2021
+Test2
+Foo<!-- date-check
+--> february 2021
+Test3
+Test4
+Foo<!-- date-check --> mar 2021 Bar
+<!-- date-check
+--> apr 2021
+Test5
+Test6
+Test7
+<!-- date-check
+
+ --> may 2021
+Test8
+ <!--
+ date-check
+ --> june 2021.
";
assert_eq!(
collect_dates_from_file(&make_date_regex(), text),
vec![
(
- 2,
+ 3,
+ Date {
+ year: 2021,
+ month: 1,
+ }
+ ),
+ (
+ 6,
+ Date {
+ year: 2021,
+ month: 2,
+ }
+ ),
+ (
+ 9,
+ Date {
+ year: 2021,
+ month: 3,
+ }
+ ),
+ (
+ 11,
+ Date {
+ year: 2021,
+ month: 4,
+ }
+ ),
+ (
+ 17,
+ Date {
+ year: 2021,
+ month: 5,
+ }
+ ),
+ (
+ 20,
Date {
year: 2021,
month: 1,
}
),
(
- 4,
+ 23,
Date {
year: 2021,
month: 2,
}
),
(
- 7,
+ 26,
Date {
year: 2021,
month: 3,
}
),
(
- 8,
+ 28,
Date {
year: 2021,
month: 4,
}
),
(
- 14,
+ 34,
Date {
year: 2021,
month: 5,
}
),
- ]
+ (
+ 38,
+ Date {
+ year: 2021,
+ month: 6,
+ }
+ ),
+ ],
);
}
}
diff --git a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
index 271e6a16f..ea50cd754 100644
--- a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
+++ b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
@@ -2,15 +2,12 @@
<!-- toc -->
-As of <!-- date: 2021-10 --> October 2021, `rustc_codegen_ssa` provides an
+As of <!-- date-check --> Aug 2022, `rustc_codegen_ssa` provides an
abstract interface for all backends to implement, to allow other codegen
backends (e.g. [Cranelift]).
[Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/HEAD/cranelift
-> The following is a copy/paste of a README from the rust-lang/rust repo.
-> Please submit a PR if it needs updating.
-
# Refactoring of `rustc_codegen_llvm`
by Denis Merigoux, October 23rd 2018
diff --git a/src/doc/rustc-dev-guide/src/backend/codegen.md b/src/doc/rustc-dev-guide/src/backend/codegen.md
index 1a6c2fa76..5feea5202 100644
--- a/src/doc/rustc-dev-guide/src/backend/codegen.md
+++ b/src/doc/rustc-dev-guide/src/backend/codegen.md
@@ -1,13 +1,16 @@
# Code generation
-Code generation or "codegen" is the part of the compiler that actually
-generates an executable binary. Usually, rustc uses LLVM for code generation;
-there is also support for [Cranelift]. The key is that rustc doesn't implement
-codegen itself. It's worth noting, though, that in the Rust source code, many
-parts of the backend have `codegen` in their names (there are no hard
-boundaries).
-
-[Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/HEAD/cranelift
+Code generation (or "codegen") is the part of the compiler
+that actually generates an executable binary.
+Usually, rustc uses LLVM for code generation,
+bu there is also support for [Cranelift] and [GCC].
+The key is that rustc doesn't implement codegen itself.
+It's worth noting, though, that in the Rust source code,
+many parts of the backend have `codegen` in their names
+(there are no hard boundaries).
+
+[Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/main/cranelift
+[GCC]: https://github.com/rust-lang/rustc_codegen_gcc
> NOTE: If you are looking for hints on how to debug code generation bugs,
> please see [this section of the debugging chapter][debugging].
diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
index 0de0767b6..81ebbbb40 100644
--- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
+++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -43,7 +43,7 @@ the branch we're already using. The steps for this are:
1. Make sure the bugfix is in upstream LLVM.
2. Identify the branch that rustc is currently using. The `src/llvm-project`
submodule is always pinned to a branch of the
- [rust-lang/llvm-project](https://github.com/rust-lang/llvm-project) repository.
+ [rust-lang/llvm-project repository].
3. Fork the rust-lang/llvm-project repository
4. Check out the appropriate branch (typically named `rustc/a.b-yyyy-mm-dd`)
5. Cherry-pick the upstream commit onto the branch
@@ -66,8 +66,8 @@ Example PRs look like:
## Feature updates
-> Note that this information is as of the time of this writing <!-- date:
-2021-10 --> (October 2021). The process for updating LLVM changes with
+> Note that this information is as of the time of this writing, <!--
+date-check --> October 2021. The process for updating LLVM changes with
practically all LLVM updates, so this may be out of date!
Unlike bugfixes, updating to pick up a new feature of LLVM typically requires a
@@ -146,9 +146,6 @@ easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating
interested in trying out the new LLVM can benefit from work you've done to
update the C++ bindings.
-[rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project
-[`llvm-wrapper`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_llvm/llvm-wrapper
-
### Caveats and gotchas
Ideally the above instructions are pretty smooth, but here's some caveats to
@@ -161,8 +158,6 @@ keep in mind while going through them:
* Creating branches is a privileged operation on GitHub, so you'll need someone
with write access to create the branches for you most likely.
-[wg-llvm]: https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm
-
## New LLVM Release Updates
Updating to a new release of LLVM is very similar to the "feature updates"
@@ -172,7 +167,7 @@ section above is generally around branch naming. The sequence of events
typically looks like:
1. LLVM announces that its latest release version has branched. This will show
- up as a branch in https://github.com/llvm/llvm-project typically named
+ up as a branch in the [llvm/llvm-project repository] typically named
`release/$N.x` where `$N` is the version of LLVM that's being released.
2. We then follow the "feature updates" section above to create a new branch of
@@ -192,3 +187,8 @@ typically looks like:
to create a new branch in the rust-lang/llvm-project repository, this time
with a new date. The commit history should look much cleaner as just a few
Rust-specific commits stacked on top of stock LLVM's release branch.
+
+[rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project
+[llvm/llvm-project repository]: https://github.com/llvm/llvm-project
+[`llvm-wrapper`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_llvm/llvm-wrapper
+[wg-llvm]: https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
index c7c107e1e..e236e0124 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
@@ -94,7 +94,7 @@ member constraints come in.
## Choices are always lifetime parameters
At present, the "choice" regions from a member constraint are always lifetime
-parameters from the current function. As of <!-- date: 2021-10 --> October 2021,
+parameters from the current function. As of <!-- date-check --> October 2021,
this falls out from the placement of impl Trait, though in the future it may not
be the case. We take some advantage of this fact, as it simplifies the current
code. In particular, we don't have to consider a case like `'0 member of ['1,
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping.md b/src/doc/rustc-dev-guide/src/building/bootstrapping.md
index fd54de20c..939c47f1b 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping.md
@@ -18,7 +18,34 @@ rustc, then uses it to compile the new compiler.
## Stages of bootstrapping
-Compiling `rustc` is done in stages.
+Compiling `rustc` is done in stages. Here's a diagram, adapted from Joshua Nelson's
+[talk on bootstrapping][rustconf22-talk] at RustConf 2022, with detailed explanations below.
+
+The `A`, `B`, `C`, and `D` show the ordering of the stages of bootstrapping.
+<span style="background-color: lightblue; color: black">Blue</span> nodes are downloaded,
+<span style="background-color: yellow; color: black">yellow</span> nodes are built with the
+stage0 compiler, and
+<span style="background-color: lightgreen; color: black">green</span> nodes are built with the
+stage1 compiler.
+
+[rustconf22-talk]: https://rustconf.com/schedule#bootstrapping-the-once-and-future-compiler
+
+```mermaid
+graph TD
+ s0c["stage0 compiler (1.63)"]:::downloaded -->|A| s0l("stage0 std (1.64)"):::with-s0c;
+ s0c & s0l --- stepb[ ]:::empty;
+ stepb -->|B| s0ca["stage0 compiler artifacts (1.64)"]:::with-s0c;
+ s0ca -->|copy| s1c["stage1 compiler (1.64)"]:::with-s0c;
+ s1c -->|C| s1l("stage1 std (1.64)"):::with-s1c;
+ s1c & s1l --- stepd[ ]:::empty;
+ stepd -->|D| s1ca["stage1 compiler artifacts (1.64)"]:::with-s1c;
+ s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c;
+
+ classDef empty width:0px,height:0px;
+ classDef downloaded fill: lightblue;
+ classDef with-s0c fill: yellow;
+ classDef with-s1c fill: lightgreen;
+```
### Stage 0
diff --git a/src/doc/rustc-dev-guide/src/building/prerequisites.md b/src/doc/rustc-dev-guide/src/building/prerequisites.md
index a5ab23d91..0783e82ee 100644
--- a/src/doc/rustc-dev-guide/src/building/prerequisites.md
+++ b/src/doc/rustc-dev-guide/src/building/prerequisites.md
@@ -12,7 +12,8 @@ Before building the compiler, you need the following things installed:
If building LLVM from source (the default), you'll need additional tools:
-* `g++` 5.1 or later, `clang++` 3.5 or later, or MSVC 2017 or later.
+* `g++`, `clang++`, or MSVC with versions listed on <!-- date-check: Aug 2022 -->
+ [LLVM's documentation](https://releases.llvm.org/13.0.0/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library)
* `ninja`, or GNU `make` 3.81 or later (ninja is recommended, especially on Windows)
* `cmake` 3.13.4 or later
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 1c2229335..3e077977d 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -22,7 +22,7 @@ You can also install the hook as a step of running `./x.py setup`!
a file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt`
commands, but you can override these commands to use more adapted versions
of these tools when hacking on `rustc`. For example, for Visual Studio Code,
-you can write: <!-- date: 2022-04 --><!-- the date comment is for the edition below -->
+you can write: <!-- date-check: apr 2022 --><!-- the date comment is for the edition below -->
```JSON
{
diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md
index 8f46e896e..35458b55c 100644
--- a/src/doc/rustc-dev-guide/src/compiler-debugging.md
+++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md
@@ -16,9 +16,36 @@ set `debug = true` in your config.toml.
Setting `debug = true` turns on many different debug options (e.g., `debug-assertions`,
`debug-logging`, etc.) which can be individually tweaked if you want to, but many people
-simply set `debug = true`. Check out the comments in config.toml.example for more info.
+simply set `debug = true`.
-You will need to rebuild the compiler once you've changed any configuration options.
+If you want to use GDB to debug rustc, please set `config.toml` with options:
+
+```toml
+[rust]
+debug = true
+debuginfo-level = 2
+```
+
+> NOTE:
+> This will use a lot of disk space
+> (upwards of <!-- date-check Aug 2022 --> 35GB),
+> and will take a lot more compile time.
+> With `debuginfo-level = 1` (the default when `debug = true`),
+> you will be able to track the execution path,
+> but will lose the symbol information for debugging.
+
+The default configuration will enable `symbol-mangling-version` v0.
+This requires at least GDB v10.2,
+otherwise you need to disable new symbol-mangling-version in `config.toml`.
+
+```toml
+[rust]
+new-symbol-mangling = false
+```
+
+> See the comments in `config.toml.example` for more info.
+
+You will need to rebuild the compiler after changing any configuration option.
## `-Z` flags
diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md
index 45f8c9033..e59bb0a77 100644
--- a/src/doc/rustc-dev-guide/src/contributing.md
+++ b/src/doc/rustc-dev-guide/src/contributing.md
@@ -437,17 +437,35 @@ Just a few things to keep in mind:
the project.
- The date the comment was added, e.g. instead of writing _"Currently, ..."_
- or _"As of now, ..."_, consider writing
- _"As of January 2021, ..."_.
- Try to format the date as `<MONTH> <YEAR>` to ease search.
+ or _"As of now, ..."_,
+ consider adding the date, in one of the following formats:
+ - Jan 2021
+ - January 2021
+ - jan 2021
+ - january 2021
- - Additionally, include a machine-readable comment of the form `<!-- date:
- 2022-04 -->` (if the current month is April 2022). We have an automated
- tool that uses these (in `ci/date-check`).
+ There is a CI action (in `~/.github/workflows/date-check.yml`)
+ that generates a monthly issue with any of these that are over 6 months old.
- So, for the month of April 2022, the comment would look like: `As of <!--
- date: 2022-04 --> April 2022`. Make sure to put the comment *between* `as of`
- and `April 2022`; see [PR #1066][rdg#1066] for the rationale.
+ For the action to pick the date,
+ add a special annotation before specifying the date:
+
+ ```md
+ <!-- date-check --> Jul 2022
+ ```
+
+ Example:
+
+ ```md
+ As of <!-- date-check --> Jul 2022, the foo did the bar.
+ ```
+
+ For cases where the date should not be part of the visible rendered output,
+ use the following instead:
+
+ ```md
+ <!-- date-check: Jul 2022 -->
+ ```
- A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide
further explanation for the change process or a way to verify that the information is not
@@ -459,7 +477,6 @@ Just a few things to keep in mind:
[rdg]: https://rustc-dev-guide.rust-lang.org/
[rdgrepo]: https://github.com/rust-lang/rustc-dev-guide
-[rdg#1066]: https://github.com/rust-lang/rustc-dev-guide/pull/1066
## Issue Triage
diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md
index 15d125377..0d5f17b99 100644
--- a/src/doc/rustc-dev-guide/src/conventions.md
+++ b/src/doc/rustc-dev-guide/src/conventions.md
@@ -14,14 +14,14 @@ special config, so this may result in different style from normal [`rustfmt`].
Therefore, formatting this repository using `cargo fmt` is not recommended.
Instead, formatting should be done using `./x.py fmt`. It's a good habit to run
-`./x.py fmt` before every commit, as this reduces conflicts later.
+`./x.py fmt` before every commit, as this reduces conflicts later.
Formatting is checked by the `tidy` script. It runs automatically when you do
`./x.py test` and can be run in isolation with `./x.py fmt --check`.
If you want to use format-on-save in your editor, the pinned version of
`rustfmt` is built under `build/<target>/stage0/bin/rustfmt`. You'll have to
-pass the <!-- date: 2022-04 --> `--edition=2021` argument yourself when calling
+pass the <!-- date-check: April 2022 --> `--edition=2021` argument yourself when calling
`rustfmt` directly.
[fmt]: https://github.com/rust-dev-tools/fmt-rfcs
diff --git a/src/doc/rustc-dev-guide/src/crates-io.md b/src/doc/rustc-dev-guide/src/crates-io.md
index 8c8fd0c38..f012c5bb5 100644
--- a/src/doc/rustc-dev-guide/src/crates-io.md
+++ b/src/doc/rustc-dev-guide/src/crates-io.md
@@ -1,20 +1,20 @@
# crates.io Dependencies
The Rust compiler supports building with some dependencies from `crates.io`.
-For example, `log` and `env_logger` come from `crates.io`.
+Examples are `log` and `env_logger`.
-In general, you should avoid adding dependencies to the compiler for several
-reasons:
+In general,
+you should avoid adding dependencies to the compiler for several reasons:
-- The dependency may not be high quality or well-maintained, whereas we want
- the compiler to be high-quality.
+- The dependency may not be of high quality or well-maintained.
- The dependency may not be using a compatible license.
- The dependency may have transitive dependencies that have one of the above
problems.
-As of <!-- date: 2022-02 --> February 2022, there is no official policy for vetting
-new dependencies to the compiler. Generally, new dependencies are not added
-to the compiler unless there is a good reason to do so.
+As of <!-- date-check --> Aug 2022,
+there is no official policy for vetting new dependencies to the compiler.
+Decisions are made on a case-by-case basis,
+during code review.
## Permitted dependencies
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 b6b6e0fa9..dcaba533e 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
@@ -1,4 +1,5 @@
# Diagnostic Items
+
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
@@ -7,7 +8,8 @@ rustc has introduced diagnostic items that are used to identify types via
[`Symbol`]s.
## Finding diagnostic items
-Diagnostic items are added to items inside `rustc`/`std`/`core` with the
+
+Diagnostic items are added to items inside `rustc`/`std`/`core`/`alloc` 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
@@ -19,12 +21,15 @@ errors during tests. A definition often looks like this:
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).
+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
+[*Using Diagnostic Items*](#using-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
@@ -43,45 +48,55 @@ 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 <!-- date: 2022-02 --> 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.
+2. <!-- date-check: Aug 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.)
+Now you can create a pull request with your changes. :tada:
+
+> NOTE:
+> 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.
+
+Diagnostic items don't have a naming convention yet.
+Following are some guidelines that should be used in future,
+but might differ from existing names:
+
+* Types, traits, and enums are named using UpperCamelCase
+ (Examples: `Iterator` and `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`)
+ `snake_case` with one important (export) module as a prefix
+ (Examples: `mem_swap` and `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.
+ Diagnostic items were added to avoid the usage of paths,
+ and using them on modules would therefore most likely 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<DefId>`. 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.
+instance when compiling with `#[no_std]`.
+All the following examples are based on [`DefId`]s and their usage.
### Example: Checking for a type
+
```rust
use rustc_span::symbol::sym;
@@ -96,6 +111,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
```
### 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.
@@ -112,6 +128,7 @@ 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
@@ -119,13 +136,15 @@ 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
-This lists some related issues. These are probably only interesting to people
+
+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
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
index f28350e03..f456474c7 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
@@ -17,45 +17,43 @@ shown below:
```rust,ignore
#[derive(SessionDiagnostic)]
-#[error(typeck::field_already_declared, code = "E0124")]
+#[diag(typeck::field_already_declared, code = "E0124")]
pub struct FieldAlreadyDeclared {
pub field_name: Ident,
#[primary_span]
#[label]
pub span: Span,
- #[label = "previous-decl-label"]
+ #[label(typeck::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.
+has to have one attribute, `#[diag(...)]`, applied to the struct itself.
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 provide a slug as the first
-positional argument (a path to an item in `rustc_errors::fluent::*`). A 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 and how slug
-items are generated.
+`#[diag(..)]` must provide a slug as the first positional argument (a path to an
+item in `rustc_errors::fluent::*`). A 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 and how slug items are generated.
In our example, the Fluent message for the "field already declared" diagnostic
looks like this:
```fluent
-typeck-field-already-declared =
+typeck_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
- .previous-decl-label = `{$field_name}` first declared here
+ .previous_decl_label = `{$field_name}` first declared here
```
-`typeck-field-already-declared` is the slug from our example and is followed
+`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
@@ -75,10 +73,10 @@ 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
+`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).
+(e.g. `previous_decl_label` in our example).
Other types have special behavior when used in a `SessionDiagnostic` derive:
@@ -95,38 +93,35 @@ 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 = "...")]`
+- `#[suggestion(slug, code = "...", applicability = "...")]`
+- `#[suggestion_hidden(slug, code = "...", applicability = "...")]`
+- `#[suggestion_short(slug, code = "...", applicability = "...")]`
+- `#[suggestion_verbose(slug, 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`.
+MachineApplicability)` field. Similarly to other field attributes, the slug
+specifies the Fluent attribute with the message and defaults to the equivalent
+of `.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 {
+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")
- );
+ let mut diag = sess.struct_err(rustc_errors::fluent::typeck::field_already_declared);
diag.set_span(self.span);
diag.span_label(
self.span,
- rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "label")
+ rustc_errors::fluent::typeck::label
);
diag.span_label(
self.prev_span,
- rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "previous-decl-label")
+ rustc_errors::fluent::typeck::previous_decl_label
);
diag
}
@@ -146,12 +141,13 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
```
### Reference
-`#[derive(SessionDiagnostic)]` supports the following attributes:
+`#[derive(SessionDiagnostic)]` and `#[derive(LintDiagnostic)]` support the
+following attributes:
-- `#[error(slug, code = "...")]` or `#[warning(slug, code = "...")]`
+- `#[diag(slug, code = "...")]`
- _Applied to struct._
- _Mandatory_
- - Defines the struct to be representing an error or a warning.
+ - Defines the text and error code to be associated with the diagnostic.
- Slug (_Mandatory_)
- Uniquely identifies the diagnostic and corresponds to its Fluent message,
mandatory.
@@ -164,34 +160,48 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
- See [translation documentation](./translation.md).
- `code = "..."` (_Optional_)
- Specifies the error code.
-- `#[note]` or `#[note = "..."]` (_Optional_)
+- `#[note]` or `#[note(slug)]` (_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`.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.note`.
- If applied to a `Span` field, creates a spanned note.
-- `#[help]` or `#[help = "..."]` (_Optional_)
+- `#[help]` or `#[help(slug)]` (_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`.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.help`.
- If applied to a `Span` field, creates a spanned help.
-- `#[label]` or `#[label = "..."]` (_Optional_)
+- `#[label]` or `#[label(slug)]` (_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 = "...")]`
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.label`.
+- `#[warn_]` or `#[warn_(slug)]` (_Optional_)
+ - _Applied to `Span` fields._
+ - Adds a warning subdiagnostic.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.warn`.
+- `#[suggestion{,_hidden,_short,_verbose}(slug, 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`.
+ - Slug (_Mandatory_)
+ - A path to an item in `rustc_errors::fluent`. Always in a module starting
+ with a Fluent resource name (which is typically the name of the crate
+ that the diagnostic is from), e.g.
+ `rustc_errors::fluent::typeck::field_already_declared`
+ (`rustc_errors::fluent` is implicit in the attribute, so just
+ `typeck::field_already_declared`). Fluent attributes for all messages
+ exist as top-level items in that module (so `typeck_message.attr` is just
+ `typeck::attr`).
+ - See [translation documentation](./translation.md).
+ - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or
+ - `.suggestion` in Fluent).
- `code = "..."` (_Mandatory_)
- Value is a format string indicating the code to be suggested as a
replacement.
@@ -203,7 +213,7 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
`#[derive(SessionSubdiagnostic)]`)._
- Adds the subdiagnostic represented by the subdiagnostic struct.
- `#[primary_span]` (_Optional_)
- - _Applied to `Span` fields._
+ - _Applied to `Span` fields on `SessionSubdiagnostic`s. Not used for `LintDiagnostic`s._
- Indicates the primary span of the diagnostic.
- `#[skip_arg]` (_Optional_)
- _Applied to any field._
@@ -258,9 +268,9 @@ 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_default_return_type = expected `()` because of default return type
-typeck-expected-return-type = expected `{$expected}` because of return type
+typeck_expected_return_type = expected `{$expected}` because of return type
```
Using the `#[primary_span]` attribute on a field (with type `Span`) will denote
@@ -276,16 +286,17 @@ Like `SessionDiagnostic`, `SessionSubdiagnostic` supports `Option<T>` and
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 = "...")]`
+- `#[suggestion(..., code = "...", applicability = "...")]`
+- `#[suggestion_hidden(..., code = "...", applicability = "...")]`
+- `#[suggestion_short(..., code = "...", applicability = "...")]`
+- `#[suggestion_verbose(..., 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`.
+- The first positional argument specifies the path to a item in
+ `rustc_errors::fluent` corresponding to the Fluent attribute with the message
+ and defaults to the equivalent of `.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.
@@ -304,11 +315,11 @@ impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> {
use rustc_errors::{Applicability, IntoDiagnosticArg};
match self {
ExpectedReturnTypeLabel::Unit { span } => {
- diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-default-return-type"))
+ diag.span_label(span, rustc_errors::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"))
+ diag.span_label(span, rustc_errors::fluent::typeck::expected_return_type)
}
}
@@ -338,14 +349,22 @@ diagnostic struct.
(`rustc_errors::fluent` is implicit in the attribute, so just
`typeck::field_already_declared`).
- See [translation documentation](./translation.md).
-- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion{,_hidden,_short,_verbose}(slug, 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`.
+ - Slug (_Mandatory_)
+ - A path to an item in `rustc_errors::fluent`. Always in a module starting
+ with a Fluent resource name (which is typically the name of the crate
+ that the diagnostic is from), e.g.
+ `rustc_errors::fluent::typeck::field_already_declared`
+ (`rustc_errors::fluent` is implicit in the attribute, so just
+ `typeck::field_already_declared`). Fluent attributes for all messages
+ exist as top-level items in that module (so `typeck_message.attr` is just
+ `typeck::attr`).
+ - See [translation documentation](./translation.md).
+ - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or
+ - `.suggestion` in Fluent).
- `code = "..."` (_Mandatory_)
- Value is a format string indicating the code to be suggested as a
replacement.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
index 39007f8d1..33d9646f6 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
@@ -1,4 +1,5 @@
# Lints
+
This page documents some of the machinery around lint registration and how we
run lints in the compiler.
@@ -8,6 +9,7 @@ everything rotates. It's not available during the early parts of compilation
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."
@@ -15,11 +17,18 @@ 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`.
+[`&rustc_lint_defs::Lint`].
+
+First, we have the lint declarations themselves,
+and this is where the name and default lint level and other metadata come from.
+These are normally defined by way of the [`declare_lint!`] macro,
+which boils down to a static with type [`&rustc_lint_defs::Lint`]
+(although this may change in the future,
+as the macro is somewhat unwieldy to add new fields to,
+like all macros).
-As of <!-- date: 2022-02 --> 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).
+As of <!-- date-check --> Aug 2022,
+we lint against direct declarations without the use of the macro.
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
@@ -34,8 +43,10 @@ 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.
+
+In [`rustc_interface::register_plugins`],
+the [`LintStore`] is created,
+and all lints are registered.
There are four 'sources' of lints:
@@ -61,6 +72,7 @@ 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`.
@@ -73,16 +85,20 @@ 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.
-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`].
+These are primarily described in two places,
+`rustc_lint_defs::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.
+
+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
@@ -94,6 +110,7 @@ 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
@@ -102,6 +119,7 @@ best way for drivers to get access to this is by overriding the
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
@@ -121,3 +139,4 @@ approach, it is beneficial to do so for performance reasons.
[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_lint.html
[`declare_tool_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_tool_lint.html
[`register_lints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html#structfield.register_lints
+[`&rustc_lint_defs::Lint`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/struct.Lint.html
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md
index 5c078ffb3..5bb37fbc2 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md
@@ -32,23 +32,23 @@ 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
+typeck_address_of_temporary_taken = cannot take address of a temporary
```
-In the above example, `typeck-address-of-temporary-taken` is the identifier for
+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
+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
`.<attribute-name>` syntax). In the above example, `label` is an attribute of
-`typeck-address-of-temporary-taken` which corresponds to the message for the
+`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
@@ -56,7 +56,7 @@ 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 =
+typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
```
@@ -67,6 +67,13 @@ discussed in detail later).
You can consult the [Fluent] documentation for other usage examples of Fluent
and its syntax.
+### Guideline for message naming
+Usually, fluent uses `-` for separating words inside a message name. However,
+`_` is accepted by fluent as well. As `_` fits Rust's use cases better, due to
+the identifiers on the Rust side using `_` as well, inside rustc, `-` is not
+allowed for separating words, and instead `_` is recommended. The only exception
+is for leading `-`s, for message names like `-passes_see_issue`.
+
### 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
@@ -106,10 +113,10 @@ fluent_messages! {
For example, given the following Fluent...
```fluent
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
- .label-previous-use = first use of `{$ident}`
+ .label_previous_use = first use of `{$ident}`
```
...then the `fluent_messages` macro will generate:
@@ -122,11 +129,11 @@ pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
mod fluent_generated {
mod typeck {
pub const field_multiply_specified_in_initializer: DiagnosticMessage =
- DiagnosticMessage::new("typeck-field-multiply-specified-in-initializer");
+ 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");
+ SubdiagnosticMessage::attr("previous_use_label");
}
}
```
@@ -217,7 +224,7 @@ 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 <!-- date: 2022-06 --> June 2022, there are no locale bundles
+As of <!-- date-check --> June 2022, there are no locale bundles
distributed with the compiler, but mechanisms are implemented for loading
bundles.
diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md
index f16c22d93..5899753ba 100644
--- a/src/doc/rustc-dev-guide/src/git.md
+++ b/src/doc/rustc-dev-guide/src/git.md
@@ -157,9 +157,12 @@ no changes added to commit (use "git add" and/or "git commit -a")
These changes are not changes to files: they are changes to submodules (more on
this [later](#git-submodules)). To get rid of those, run `git submodule update`
(or run any `x.py` command, which will automatically update the submodules).
-Note that there is (as of <!-- date: 2022-02 --> February 2022) a [bug][#77620] if you use
-worktrees, submodules, and `x.py` in a commit hook. If you run into an error
-like:
+Note that,
+as of <!-- date-check --> Aug 2022,
+there is a [bug][#77620] if you use worktrees,
+submodules, and `x.py` in a commit hook.
+If you run into an error like the following,
+it's not anything you did wrong:
```
error: failed to read `/home/joshua/rustc-worktree/src/tools/miri/cargo-miri/Cargo.toml`
@@ -167,7 +170,8 @@ error: failed to read `/home/joshua/rustc-worktree/src/tools/miri/cargo-miri/Car
Caused by:
No such file or directory (os error 2)
```
-it's not anything you did wrong. There is a workaround in [the issue][#77620-workaround].
+
+There is a workaround in [the issue][#77620-workaround].
[#77620]: https://github.com/rust-lang/rust/issues/77620
[#77620-workaround]: https://github.com/rust-lang/rust/issues/77620#issuecomment-705228229
diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
index ea4bdfca6..b186f4820 100644
--- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
+++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
@@ -222,9 +222,10 @@ properly-configured variables in LLVM IR, according to very specific
details of the [_LLVM Coverage Mapping Format_][coverage-mapping-format]
(Version 6).[^llvm-and-covmap-versions]
-[^llvm-and-covmap-versions]: The Rust compiler (as of <!-- date: 2021-12 -->
-December 2021) supports _LLVM Coverage Mapping Format_ Version 5 or 6. Version 5
-was introduced in _LLVM 12_, which is (as of this writing) the minimum LLVM
+[^llvm-and-covmap-versions]: The Rust compiler (as of <!-- date-check --> December 2021)
+supports _LLVM Coverage Mapping Format_ Version 5 or 6. Version 5
+was introduced in _LLVM 12_,
+which is (as of <!-- date-check: December 2021--> this writing) the minimum LLVM
version supported by the current version of Rust. Version 6 was introduced in
_LLVM 13_, which is currently the default LLVM version for Rust. The Rust
compiler will automatically use the most up-to-date coverage mapping format
diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md
index 2be072dd2..956f56828 100644
--- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md
+++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md
@@ -14,9 +14,9 @@ This declares an opaque type named `Foo`, of which the only information is that
it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`,
but nothing else (regardless of whether it implements any other traits).
-Since there needs to be a concrete background type, you can (as of <!-- date:
-2021-01 --> January 2021) express that type by using the opaque type in a
-"defining use site".
+Since there needs to be a concrete background type,
+you can (as of <!-- date-check --> January 2021) express that type
+by using the opaque type in a "defining use site".
```rust,ignore
struct Struct;
diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md
index de6c88e7e..c7da92542 100644
--- a/src/doc/rustc-dev-guide/src/overview.md
+++ b/src/doc/rustc-dev-guide/src/overview.md
@@ -292,7 +292,7 @@ Moreover, the compiler wasn't originally built to use a query system; the query
system has been retrofitted into the compiler, so parts of it are not query-fied
yet. Also, LLVM isn't our code, so that isn't querified either. The plan is to
eventually query-fy all of the steps listed in the previous section,
-but as of <!-- date: 2021-11 --> November 2021, only the steps between HIR and
+but as of <!-- date-check --> November 2021, only the steps between HIR and
LLVM IR are query-fied. That is, lexing, parsing, name resolution, and macro
expansion are done all at once for the whole program.
diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md
index 4aa13d781..e93f51dbb 100644
--- a/src/doc/rustc-dev-guide/src/parallel-rustc.md
+++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md
@@ -1,34 +1,116 @@
# Parallel Compilation
-As of <!-- date: 2022-05 --> May 2022, The only stage of the compiler
-that is already parallel is codegen. The nightly compiler implements query evaluation,
-but there is still a lot of work to be done. The lack of parallelism at other stages
-also represents an opportunity for improving compiler performance. One can try out the current
-parallel compiler work by enabling it in the `config.toml`.
+As of <!-- date-check --> August 2022, the only stage of the compiler that
+is already parallel is codegen. Some parts of the compiler already have
+parallel implementations, such as query evaluation, type check and
+monomorphization, but the general version of the compiler does not include
+these parallelization functions. **To try out the current parallel compiler**,
+one can install rustc from source code with `parallel-compiler = true` in
+the `config.toml`.
+
+The lack of parallelism at other stages (for example, macro expansion) also
+represents an opportunity for improving compiler performance.
These next few sections describe where and how parallelism is currently used,
and the current status of making parallel compilation the default in `rustc`.
-The underlying thread-safe data-structures used in the parallel compiler
-can be found in the `rustc_data_structures::sync` module. Some of these data structures
-use the `parking_lot` crate as well.
-
## Codegen
-There are two underlying thread safe data structures used in code generation:
-
-- `Lrc`
- - Which is an [`Arc`][Arc] if `parallel_compiler` is true, and a [`Rc`][Rc]
- if it is not.
-- `MetadataRef` -> [`OwningRef<Box<dyn Erased + Send + Sync>, [u8]>`][OwningRef]
- - This data structure is specific to `rustc`.
-
During [monomorphization][monomorphization] the compiler splits up all the code to
be generated into smaller chunks called _codegen units_. These are then generated by
independent instances of LLVM running in parallel. At the end, the linker
is run to combine all the codegen units together into one binary. This process
occurs in the `rustc_codegen_ssa::base` module.
+## Data Structures
+
+The underlying thread-safe data-structures used in the parallel compiler
+can be found in the `rustc_data_structures::sync` module. These data structures
+are implemented diferently depending on whether `parallel-compiler` is true.
+
+| data structure | parallel | non-parallel |
+| -------------------------------- | --------------------------------------------------- | ------------ |
+| Lrc | std::sync::Arc | std::rc::Rc |
+| Weak | std::sync::Weak | std::rc::Weak |
+| Atomic{Bool}/{Usize}/{U32}/{U64} | std::sync::atomic::Atomic{Bool}/{Usize}/{U32}/{U64} | (std::cell::Cell<bool/usize/u32/u64>) |
+| OnceCell | std::sync::OnceLock | std::cell::OnceCell |
+| Lock\<T> | (parking_lot::Mutex\<T>) | (std::cell::RefCell) |
+| RwLock\<T> | (parking_lot::RwLock\<T>) | (std::cell::RefCell) |
+| MTRef<'a, T> | &'a T | &'a mut T |
+| MTLock\<T> | (Lock\<T>) | (T) |
+| ReadGuard | parking_lot::RwLockReadGuard | std::cell::Ref |
+| MappedReadGuard | parking_lot::MappedRwLockReadGuard | std::cell::Ref |
+| WriteGuard | parking_lot::RwLockWriteGuard | std::cell::RefMut |
+| MappedWriteGuard | parking_lot::MappedRwLockWriteGuard | std::cell::RefMut |
+| LockGuard | parking_lot::MutexGuard | std::cell::RefMut |
+| MappedLockGuard | parking_lot::MappedMutexGuard | std::cell::RefMut |
+| MetadataRef | [`OwningRef<Box<dyn Erased + Send + Sync>, [u8]>`][OwningRef] | [`OwningRef<Box<dyn Erased>, [u8]>`][OwningRef] |
+
+- These thread-safe data structures interspersed during compilation can
+ cause a lot of lock contention, which actually degrades performance as the
+ number of threads increases beyond 4. This inspires us to audit the use
+ of these data structures, leading to either refactoring to reduce use of
+ shared state, or persistent documentation covering invariants, atomicity,
+ and lock orderings.
+
+- On the other hand, we still need to figure out what other invariants
+ during compilation might not hold in parallel compilation.
+
+### WorkLocal
+
+`WorkLocal` is a special data structure implemented for parallel compiler.
+It holds worker-locals values for each thread in a thread pool. You can only
+access the worker local value through the Deref impl on the thread pool it
+was constructed on. It will panic otherwise.
+
+`WorkLocal` is used to implement the `Arena` allocator in the parallel
+environment, which is critical in parallel queries. Its implementation
+is located in the `rustc-rayon-core::worker_local` module. However, in the
+non-parallel compiler, it is implemented as `(OneThread<T>)`, whose `T`
+can be accessed directly through `Deref::deref`.
+
+## Parallel Iterator
+
+The parallel iterators provided by the [`rayon`] crate are easy ways
+to implement parallelism. In the current implementation of the parallel
+compiler we use a custom [fork][rustc-rayon] of [`rayon`] to run tasks in parallel.
+
+Some iterator functions are implemented to run loops in parallel
+when `parallel-compiler` is true.
+
+| Function(Omit `Send` and `Sync`) | Introduction | Owning Module |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------- |
+| **par_iter**<T: IntoParallelIterator>(t: T) -> T::Iter | generate a parallel iterator | rustc_data_structure::sync |
+| **par_for_each_in**<T: IntoParallelIterator>(t: T, for_each: impl Fn(T::Item)) | generate a parallel iterator and run `for_each` on each element | rustc_data_structure::sync |
+| **Map::par_body_owners**(self, f: impl Fn(LocalDefId)) | run `f` on all hir owners in the crate | rustc_middle::hir::map |
+| **Map::par_for_each_module**(self, f: impl Fn(LocalDefId)) | run `f` on all modules and sub modules in the crate | rustc_middle::hir::map |
+| **ModuleItems::par_items**(&self, f: impl Fn(ItemId)) | run `f` on all items in the module | rustc_middle::hir |
+| **ModuleItems::par_trait_items**(&self, f: impl Fn(TraitItemId)) | run `f` on all trait items in the module | rustc_middle::hir |
+| **ModuleItems::par_impl_items**(&self, f: impl Fn(ImplItemId)) | run `f` on all impl items in the module | rustc_middle::hir |
+| **ModuleItems::par_foreign_items**(&self, f: impl Fn(ForeignItemId)) | run `f` on all foreign items in the module | rustc_middle::hir |
+
+There are a lot of loops in the compiler which can possibly be
+parallelized using these functions. As of <!-- date-check--> August
+2022, scenarios where the parallel iterator function has been used
+are as follows:
+
+| caller | scenario | callee |
+| ------------------------------------------------------- | ------------------------------------------------------------ | ------------------------ |
+| rustc_metadata::rmeta::encoder::prefetch_mir | Prefetch queries which will be needed later by metadata encoding | par_iter |
+| rustc_monomorphize::collector::collect_crate_mono_items | Collect monomorphized items reachable from non-generic items | par_for_each_in |
+| rustc_interface::passes::analysis | Check the validity of the match statements | Map::par_body_owners |
+| rustc_interface::passes::analysis | MIR borrow check | Map::par_body_owners |
+| rustc_typeck::check::typeck_item_bodies | Type check | Map::par_body_owners |
+| rustc_interface::passes::hir_id_validator::check_crate | Check the validity of hir | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Check the validity of loops body, attributes, naked functions, unstable abi, const bodys | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Liveness and intrinsic checking of MIR | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Deathness checking | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Privacy checking | Map::par_for_each_module |
+| rustc_lint::late::check_crate | Run per-module lints | Map::par_for_each_module |
+| rustc_typeck::check_crate | Well-formedness checking | Map::par_for_each_module |
+
+There are still many loops that have the potential to use parallel iterators.
+
## Query System
The query model has some properties that make it actually feasible to evaluate
@@ -48,44 +130,22 @@ When a query `foo` is evaluated, the cache table for `foo` is locked.
start evaluating.
- If there *is* another query invocation for the same key in progress, we
release the lock, and just block the thread until the other invocation has
- computed the result we are waiting for. This cannot deadlock because, as
- mentioned before, query invocations form a DAG. Some threads will always make
- progress.
+ computed the result we are waiting for. **Cycle error detection** in the parallel
+ compiler requires more complex logic than in single-threaded mode. When
+ worker threads in parallel queries stop making progress due to interdependence,
+ the compiler uses an extra thread *(named deadlock handler)* to detect, remove and
+ report the cycle error.
+
+Parallel query still has a lot of work to do, most of which is related to
+the previous `Data Structures` and `Parallel Iterators`. See [this tracking issue][tracking].
## Rustdoc
-As of <!-- date: 2022-05--> May 2022, there are still a number of steps
+As of <!-- date-check--> May 2022, there are still a number of steps
to complete before rustdoc rendering can be made parallel. More details on
this issue can be found [here][parallel-rustdoc].
-## Current Status
-
-As of <!-- date: 2022-05 --> May 2022, work on explicitly parallelizing the
-compiler has stalled. There is a lot of design and correctness work that needs
-to be done.
-
-These are the basic ideas in the effort to make `rustc` parallel:
-
-- There are a lot of loops in the compiler that just iterate over all items in
- a crate. These can possibly be parallelized.
-- We can use (a custom fork of) [`rayon`] to run tasks in parallel. The custom
- fork allows the execution of DAGs of tasks, not just trees.
-- There are currently a lot of global data structures that need to be made
- thread-safe. A key strategy here has been converting interior-mutable
- data-structures (e.g. `Cell`) into their thread-safe siblings (e.g. `Mutex`).
-
-[`rayon`]: https://crates.io/crates/rayon
-
-As of <!-- date: 2022-05 --> May 2022, much of this effort is on hold due
-to lack of manpower. We have a working prototype with promising performance
-gains in many cases. However, there are two blockers:
-
-- It's not clear what invariants need to be upheld that might not hold in the
- face of concurrency. An auditing effort was underway, but seems to have
- stalled at some point.
-
-- There is a lot of lock contention, which actually degrades performance as the
- number of threads increases beyond 4.
+## Resources
Here are some resources that can be used to learn more (note that some of them
are a bit out of date):
@@ -93,8 +153,9 @@ are a bit out of date):
- [This IRLO thread by Zoxc, one of the pioneers of the effort][irlo0]
- [This list of interior mutability in the compiler by nikomatsakis][imlist]
- [This IRLO thread by alexchricton about performance][irlo1]
-- [This tracking issue][tracking]
+[`rayon`]: https://crates.io/crates/rayon
+[rustc-rayon]: https://github.com/rust-lang/rustc-rayon
[irlo0]: https://internals.rust-lang.org/t/parallelizing-rustc-using-rayon/6606
[imlist]: https://github.com/nikomatsakis/rustc-parallelization/blob/master/interior-mutability-list.md
[irlo1]: https://internals.rust-lang.org/t/help-test-parallel-rustc/11503
diff --git a/src/doc/rustc-dev-guide/src/part-5-intro.md b/src/doc/rustc-dev-guide/src/part-5-intro.md
index 4b7c25797..faa12f484 100644
--- a/src/doc/rustc-dev-guide/src/part-5-intro.md
+++ b/src/doc/rustc-dev-guide/src/part-5-intro.md
@@ -1,54 +1,57 @@
# From MIR to Binaries
-All of the preceding chapters of this guide have one thing in common: we never
-generated any executable machine code at all! With this chapter, all of that
-changes.
+All of the preceding chapters of this guide have one thing in common:
+we never generated any executable machine code at all!
+With this chapter, all of that changes.
-So far, we've shown how the compiler can take raw source code in text format
-and transform it into [MIR]. We have also shown how the compiler does various
-analyses on the code to detect things like type or lifetime errors. Now, we
-will finally take the MIR and produce some executable machine code.
+So far,
+we've shown how the compiler can take raw source code in text format
+and transform it into [MIR].
+We have also shown how the compiler does various
+analyses on the code to detect things like type or lifetime errors.
+Now, we will finally take the MIR and produce some executable machine code.
[MIR]: ./mir/index.md
-> NOTE: This part of a compiler is often called the _backend_. The term is a bit
-> overloaded because in the compiler source, it usually refers to the "codegen
-> backend" (i.e. LLVM or Cranelift). Usually, when you see the word "backend"
-> in this part, we are referring to the "codegen backend".
+> NOTE: This part of a compiler is often called the _backend_.
+> The term is a bit overloaded because in the compiler source,
+> it usually refers to the "codegen backend" (i.e. LLVM, Cranelift, or GCC).
+> Usually, when you see the word "backend" in this part,
+> we are referring to the "codegen backend".
So what do we need to do?
-0. First, we need to collect the set of things to generate code for. In
- particular, we need to find out which concrete types to substitute for
- generic ones, since we need to generate code for the concrete types.
- Generating code for the concrete types (i.e. emitting a copy of the code for
- each concrete type) is called _monomorphization_, so the process of
- collecting all the concrete types is called _monomorphization collection_.
+0. First, we need to collect the set of things to generate code for.
+ In particular,
+ we need to find out which concrete types to substitute for generic ones,
+ since we need to generate code for the concrete types.
+ Generating code for the concrete types
+ (i.e. emitting a copy of the code for each concrete type) is called _monomorphization_,
+ so the process of collecting all the concrete types is called _monomorphization collection_.
1. Next, we need to actually lower the MIR to a codegen IR
(usually LLVM IR) for each concrete type we collected.
-2. Finally, we need to invoke LLVM or Cranelift, which runs a bunch of
- optimization passes, generates executable code, and links together an
- executable binary.
+2. Finally, we need to invoke the codegen backend,
+ which runs a bunch of optimization passes,
+ generates executable code,
+ and links together an executable binary.
[codegen1]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html
The code for codegen is actually a bit complex due to a few factors:
-- Support for multiple codegen backends (LLVM and Cranelift). We try to share as much
- backend code between them as possible, so a lot of it is generic over the
- codegen implementation. This means that there are often a lot of layers of
- abstraction.
+- Support for multiple codegen backends (LLVM, Cranelift, and GCC).
+ We try to share as much backend code between them as possible,
+ so a lot of it is generic over the codegen implementation.
+ This means that there are often a lot of layers of abstraction.
- Codegen happens asynchronously in another thread for performance.
-- The actual codegen is done by a third-party library (either LLVM or Cranelift).
+- The actual codegen is done by a third-party library (either of the 3 backends).
-Generally, the [`rustc_codegen_ssa`][ssa] crate contains backend-agnostic code
-(i.e. independent of LLVM or Cranelift), while the [`rustc_codegen_llvm`][llvm]
-crate contains code specific to LLVM codegen.
+Generally, the [`rustc_codegen_ssa`][ssa] crate contains backend-agnostic code,
+while the [`rustc_codegen_llvm`][llvm] crate contains code specific to LLVM codegen.
[ssa]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html
[llvm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/index.html
At a very high level, the entry point is
-[`rustc_codegen_ssa::base::codegen_crate`][codegen1]. This function starts the
-process discussed in the rest of this chapter.
-
+[`rustc_codegen_ssa::base::codegen_crate`][codegen1].
+This function starts the process discussed in the rest of this chapter.
diff --git a/src/doc/rustc-dev-guide/src/profiling.md b/src/doc/rustc-dev-guide/src/profiling.md
index ada497d88..e1666e237 100644
--- a/src/doc/rustc-dev-guide/src/profiling.md
+++ b/src/doc/rustc-dev-guide/src/profiling.md
@@ -108,6 +108,6 @@ The llvm-lines output is affected by several options.
MIR optimizations have little impact. Compared to the default `RUSTFLAGS="-Z
mir-opt-level=1"`, level 0 adds 0.3GB and level 2 removes 0.2GB.
-As of <!-- date: 2022-07 --> July 2022,
+As of <!-- date-check --> July 2022,
inlining happens in LLVM and GCC codegen backends,
missing only in the Cranelift one.
diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
index b84a5dac4..8a08f1e04 100644
--- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
@@ -76,7 +76,7 @@ executed, no results are cached. But the context already provides access to
"input" data, i.e. pieces of immutable data that were computed before the
context was created and that queries can access to do their computations.
-As of <!-- date: 2021-01 --> January 2021, this input data consists mainly of
+As of <!-- date-check --> January 2021, this input data consists mainly of
the HIR map, upstream crate metadata, and the command-line options the compiler
was invoked with; but in the future inputs will just consist of command-line
options and a list of source files -- the HIR map will itself be provided by a
diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md
index 95e570dfc..3d60059bd 100644
--- a/src/doc/rustc-dev-guide/src/query.md
+++ b/src/doc/rustc-dev-guide/src/query.md
@@ -3,7 +3,7 @@
<!-- toc -->
As described in [the high-level overview of the compiler][hl], the Rust compiler
-is still (as of <!-- date: 2021-07 --> July 2021) transitioning from a
+is still (as of <!-- date-check --> July 2021) transitioning from a
traditional "pass-based" setup to a "demand-driven" system. The compiler query
system is the key to rustc's demand-driven organization.
The idea is pretty simple. Instead of entirely independent passes
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 327415e5a..5ce93c3df 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
@@ -7,7 +7,7 @@
To get diagnostics from the compiler,
configure `rustc_interface::Config` to output diagnostic to a buffer,
and run `TyCtxt.analysis`. The following was tested
-with <!-- date: 2022-06 --> `nightly-2022-06-05` (See [here][example]
+with <!-- date-check: June 2022 --> `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
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 d70264fe4..ce53f3861 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 was tested with <!-- date: 2022-06 --> `nightly-2022-06-05`
+The following was tested with <!-- date-check: June 2022 --> `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
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
index 91bb0c358..f21c8725c 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
@@ -66,7 +66,7 @@ these passes, please let us know!)
[44136]: https://github.com/rust-lang/rust/issues/44136
-Here is the list of passes as of <!-- date: 2022-05 --> May 2022:
+Here is the list of passes as of <!-- date-check --> May 2022:
- `calculate-doc-coverage` calculates information used for the `--show-coverage`
flag.
diff --git a/src/doc/rustc-dev-guide/src/salsa.md b/src/doc/rustc-dev-guide/src/salsa.md
index afa01eda2..872308e78 100644
--- a/src/doc/rustc-dev-guide/src/salsa.md
+++ b/src/doc/rustc-dev-guide/src/salsa.md
@@ -9,7 +9,7 @@ want to watch [Salsa In More
Depth](https://www.youtube.com/watch?v=i_IhACacPRY), also by Niko
Matsakis.
-> As of <!-- date: 2022-04 --> April 2022, although Salsa is inspired by
+> As of <!-- date-check --> April 2022, although Salsa is inspired by
> (among other things) rustc's query system, it is not used directly in rustc.
> It _is_ used in chalk and extensively in `rust-analyzer`, but there are no
> medium or long-term concrete plans to integrate it into the compiler.
diff --git a/src/doc/rustc-dev-guide/src/stabilization_guide.md b/src/doc/rustc-dev-guide/src/stabilization_guide.md
index 454cd0f27..0ac19293b 100644
--- a/src/doc/rustc-dev-guide/src/stabilization_guide.md
+++ b/src/doc/rustc-dev-guide/src/stabilization_guide.md
@@ -99,24 +99,6 @@ require steps beyond what this guide talks about.
Note: Before we stabilize any feature, it's the rule that it
should appear in the documentation.
-### Determining the stabilization version
-
-The version in which the feature will be stabilized *must* match
-the value of [the `src/version` file in `master`][src-version] when the PR is merged.
-
-It's worth checking [the version schedule on the Forge][forge-versions] to see whether
-changes are coming soon. You'll usually use the version labelled "Nightly".
-"Nightly" is two versions higher than the current stable release,
-since what's currently in beta will be the next stable release,
-and any changes you're making now will be in the one after that.
-
-No PR is merged instantly, so you'll want to be careful around release time.
-The version bump happens [the Friday before][forge-release-process] the stable release,
-not the same time as the release. So if you're opening a PR shortly before then,
-be prepared to update the version, or consider just opening it for one version
-higher than the current nightly, with a note saying not to merge until
-after the upcoming version bump.
-
### Updating the feature-gate listing
There is a central listing of feature-gates in
@@ -127,7 +109,7 @@ to stabilize, something like (this example is taken from
```rust,ignore
// pub(restricted) visibilities (RFC 1422)
-(active, pub_restricted, "1.9.0", Some(32409)),
+(active, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
```
The above line should be moved down to the area for "accepted"
@@ -136,11 +118,13 @@ When it is done, it should look like:
```rust,ignore
// pub(restricted) visibilities (RFC 1422)
-(accepted, pub_restricted, "1.31.0", Some(32409)),
+(accepted, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
// note that we changed this
```
-(The version here is the one discussed in the previous section.)
+(Even though you will encounter version numbers in the file of past changes,
+you should not put the rustc version you expect your stabilization to happen in,
+but instead `CURRENT_RUSTC_VERSION`)
### Removing existing uses of the feature-gate
diff --git a/src/doc/rustc-dev-guide/src/test-implementation.md b/src/doc/rustc-dev-guide/src/test-implementation.md
index 09a66cdc9..1b8247005 100644
--- a/src/doc/rustc-dev-guide/src/test-implementation.md
+++ b/src/doc/rustc-dev-guide/src/test-implementation.md
@@ -155,5 +155,4 @@ $ rustc my_mod.rs -Z unpretty=hir
[TestDesc]: https://doc.rust-lang.org/test/struct.TestDesc.html
[Symbol]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
[Ident]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Ident.html
-[eRFC]: https://github.com/rust-lang/rfcs/blob/master/text/2318-custom-test-frameworks.md
[rustc_ast]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_ast
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index 5c3dcf54b..70cef2ad3 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -452,7 +452,7 @@ fn main() {
## Revisions
-Certain classes of tests support "revisions" (as of <!-- date: 2022-07 --> July 2022,
+Certain classes of tests support "revisions" (as of <!-- date-check --> July 2022,
this includes UI, assembly, codegen, debuginfo, incremental, and rustdoc UI tests,
though incremental tests are somewhat different).
Revisions allow a single test file to be used for multiple tests.
diff --git a/src/doc/rustc-dev-guide/src/the-parser.md b/src/doc/rustc-dev-guide/src/the-parser.md
index ff43220c1..0d37704e8 100644
--- a/src/doc/rustc-dev-guide/src/the-parser.md
+++ b/src/doc/rustc-dev-guide/src/the-parser.md
@@ -1,6 +1,6 @@
# Lexing and Parsing
-As of <!-- date: 2021-01 --> January 2021, the lexer and parser are undergoing
+As of <!-- date-check --> January 2021, the lexer and parser are undergoing
refactoring to allow extracting them into libraries.
The very first thing the compiler does is take the program (in Unicode
@@ -35,9 +35,10 @@ The main entrypoint to the parser is via the various `parse_*` functions and oth
the token stream, and then execute the parser to get a `Crate` (the root AST
node).
-To minimise the amount of copying that is done, both the `StringReader` and
-`Parser` have lifetimes which bind them to the parent `ParseSess`. This contains
-all the information needed while parsing, as well as the `SourceMap` itself.
+To minimize the amount of copying that is done,
+both [`StringReader`] and [`Parser`] have lifetimes which bind them to the parent `ParseSess`.
+This contains all the information needed while parsing,
+as well as the [`SourceMap`] itself.
Note that while parsing, we may encounter macro definitions or invocations. We
set these aside to be expanded (see [this chapter](./macro-expansion.md)).
@@ -52,9 +53,9 @@ Code for lexical analysis is split between two crates:
constituting tokens. Although it is popular to implement lexers as generated
finite state machines, the lexer in `rustc_lexer` is hand-written.
-- [`StringReader`] from [`rustc_ast`][rustc_ast] integrates `rustc_lexer` with `rustc`
- specific data structures. Specifically, it adds `Span` information to tokens
- returned by `rustc_lexer` and interns identifiers.
+- [`StringReader`] integrates `rustc_lexer` with data structures specific to `rustc`.
+ Specifically,
+ it adds `Span` information to tokens returned by `rustc_lexer` and interns identifiers.
[rustc_ast]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/index.html
[rustc_errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
@@ -64,7 +65,7 @@ Code for lexical analysis is split between two crates:
[rustc_parse]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[parser_lib]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/index.html
-[`Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/parse/parser/struct.Parser.html
+[`Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html
[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html
[visit module]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/index.html
[sourcefile]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.SourceFile.html
diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md
index 4f8e6512c..2a811be3d 100644
--- a/src/doc/rustc-dev-guide/src/thir.md
+++ b/src/doc/rustc-dev-guide/src/thir.md
@@ -4,7 +4,7 @@
The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for
"High-Level Abstract IR", is another IR used by rustc that is generated after
-[type checking]. It is (as of <!-- date: 2022-04 --> April 2022) only used for
+[type checking]. It is (as of <!-- date-check --> April 2022) only used for
[MIR construction] and [exhaustiveness checking]. There is also
[an experimental unsafety checker][thir-unsafeck] that operates on the THIR as a replacement for
the current MIR unsafety checker, and can be used instead of the MIR unsafety checker by passing
@@ -47,9 +47,19 @@ which is useful to keep peak memory in check. Having a THIR representation of
all bodies of a crate in memory at the same time would be very heavy.
You can get a debug representation of the THIR by passing the `-Zunpretty=thir-tree` flag
-to `rustc`. Here is how a function with just the statement `let x = 1 + 2;` gets represented in
-THIR:
+to `rustc`.
+
+To demonstrate, let's use the following example:
+
```rust
+fn main() {
+ let x = 1 + 2;
+}
+```
+
+Here is how that gets represented in THIR (as of <!-- date-check --> Aug 2022):
+
+```rust,no_run
Thir {
// no match arms
arms: [],
@@ -57,57 +67,73 @@ Thir {
// expression 0, a literal with a value of 1
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:14 (#0),
kind: Literal {
- literal: Const {
- ty: i32,
- val: Value(Scalar(0x00000001)),
+ lit: Spanned {
+ node: Int(
+ 1,
+ Unsuffixed,
+ ),
+ span: oneplustwo.rs:2:13: 2:14 (#0),
},
- user_ty: None,
- const_id: None,
+ neg: false,
},
},
// expression 1, scope surronding literal 1
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:14 (#0),
kind: Scope {
- region_scope: Node(1),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 1,
- }),
// reference to expression 0 above
+ region_scope: Node(3),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 3,
+ },
+ ),
value: e0,
},
},
// expression 2, literal 2
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:17: 2:18 (#0),
kind: Literal {
- literal: Const {
- ty: i32,
- val: Value(Scalar(0x00000002)),
+ lit: Spanned {
+ node: Int(
+ 2,
+ Unsuffixed,
+ ),
+ span: oneplustwo.rs:2:17: 2:18 (#0),
},
- user_ty: None,
- const_id: None,
+ neg: false,
},
},
// expression 3, scope surrounding literal 2
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:17: 2:18 (#0),
kind: Scope {
- region_scope: Node(2),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 2,
- }),
+ region_scope: Node(4),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 4,
+ },
+ ),
// reference to expression 2 above
value: e2,
},
@@ -115,7 +141,9 @@ Thir {
// expression 4, represents 1 + 2
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:18 (#0),
kind: Binary {
op: Add,
@@ -127,30 +155,38 @@ Thir {
// expression 5, scope surronding expression 4
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:18 (#0),
kind: Scope {
- region_scope: Node(3),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 3,
- }),
+ region_scope: Node(5),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 5,
+ },
+ ),
value: e4,
},
},
// expression 6, block around statement
Expr {
ty: (),
- temp_lifetime: Some(Node(8)),
+ temp_lifetime: Some(
+ Node(9),
+ ),
span: oneplustwo.rs:1:11: 3:2 (#0),
kind: Block {
body: Block {
targeted_by_break: false,
- region_scope: Node(7),
+ region_scope: Node(8),
opt_destruction_scope: None,
span: oneplustwo.rs:1:11: 3:2 (#0),
// reference to statement 0 below
- stmts: [ s0 ],
+ stmts: [
+ s0,
+ ],
expr: None,
safety_mode: Safe,
},
@@ -160,25 +196,29 @@ Thir {
Expr {
ty: (),
temp_lifetime: Some(
- Node(8),
+ Node(9),
),
span: oneplustwo.rs:1:11: 3:2 (#0),
kind: Scope {
- region_scope: Node(8),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 8,
- }),
+ region_scope: Node(9),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 9,
+ },
+ ),
value: e6,
},
},
// destruction scope around expression 7
Expr {
ty: (),
- temp_lifetime: Some(Node(8)),
+ temp_lifetime: Some(
+ Node(9),
+ ),
span: oneplustwo.rs:1:11: 3:2 (#0),
kind: Scope {
- region_scope: Destruction(8),
+ region_scope: Destruction(9),
lint_level: Inherited,
value: e7,
},
@@ -188,8 +228,8 @@ Thir {
// let statement
Stmt {
kind: Let {
- remainder_scope: Remainder { block: 7, first_statement_index: 0},
- init_scope: Node(6),
+ remainder_scope: Remainder { block: 8, first_statement_index: 0},
+ init_scope: Node(1),
pattern: Pat {
ty: i32,
span: oneplustwo.rs:2:9: 2:10 (#0),
@@ -197,22 +237,31 @@ Thir {
mutability: Not,
name: "x",
mode: ByValue,
- var: HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 5,
- },
+ var: LocalVarId(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 7,
+ },
+ ),
ty: i32,
subpattern: None,
is_primary: true,
},
},
- initializer: Some(e5),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 4,
- }),
+ initializer: Some(
+ e5,
+ ),
+ else_block: None,
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 6,
+ },
+ ),
},
- opt_destruction_scope: Some(Destruction(6)),
+ opt_destruction_scope: Some(
+ Destruction(1),
+ ),
},
],
}
diff --git a/src/doc/rustc-dev-guide/src/traits/chalk.md b/src/doc/rustc-dev-guide/src/traits/chalk.md
index d4045c460..78deb3675 100644
--- a/src/doc/rustc-dev-guide/src/traits/chalk.md
+++ b/src/doc/rustc-dev-guide/src/traits/chalk.md
@@ -1,7 +1,7 @@
# Chalk-based trait solving
-[Chalk][chalk] is an experimental trait solver for Rust that is (as of <!--
-date: 2022-05 --> May 2022) under development by the [Types team].
+[Chalk][chalk] is an experimental trait solver for Rust that is
+(as of <!-- date-check --> 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, drop by on the rust-lang Zulip in the [`#t-types`]
diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md
index c22ee6de6..195fe6050 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 <!-- date: 2022-05 --> May 2022, this amounts to unifying
+_matching_. As of <!-- date-check --> 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-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md
index 4be9211ee..10f1dd5ef 100644
--- a/src/doc/rustc-dev-guide/src/type-inference.md
+++ b/src/doc/rustc-dev-guide/src/type-inference.md
@@ -45,11 +45,9 @@ tcx.infer_ctxt().enter(|infcx| {
})
```
-Within the closure, `infcx` has the type `InferCtxt<'cx, 'tcx>` for some
-fresh `'cx`, while `'tcx` is the same as outside the inference context.
-(Again, see the [`ty` chapter][ty-ch] for more details on this setup.)
-
-[ty-ch]: ty.html
+Within the closure,
+`infcx` has the type `InferCtxt<'a, 'tcx>` for some fresh `'a`,
+while `'tcx` is the same as outside the inference context.
The `tcx.infer_ctxt` method actually returns a builder, which means
there are some kinds of configuration you can do before the `infcx` is
@@ -72,7 +70,7 @@ inference works, or perhaps this blog post on
[Unification in the Chalk project]: http://smallcultfollowing.com/babysteps/blog/2017/03/25/unification-in-chalk-part-1/
All told, the inference context stores five kinds of inference variables
-(as of <!-- date: 2021-06 --> June 2021):
+(as of <!-- date-check --> June 2021):
- Type variables, which come in three varieties:
- General type variables (the most common). These can be unified with any
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index d168af60c..d9d430c20 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -18,6 +18,8 @@
- [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
- [\*-apple-watchos\*](platform-support/apple-watchos.md)
- [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
+ - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
+ - [armv4t-none-eabi](platform-support/armv4t-none-eabi.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)
diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md
index 0ae9e53af..38fd5c969 100644
--- a/src/doc/rustc/src/instrument-coverage.md
+++ b/src/doc/rustc/src/instrument-coverage.md
@@ -97,7 +97,17 @@ $ echo "{some: 'thing'}" | target/debug/examples/formatjson5 -
}
```
-After running this program, a new file, `default.profraw`, should be in the current working directory. It's often preferable to set a specific file name or path. You can change the output file using the environment variable `LLVM_PROFILE_FILE`:
+After running this program, a new file named like `default_11699812450447639123_0_20944` should be in the current working directory.
+A new, unique file name will be generated each time the program is run to avoid overwriting previous data.
+
+```shell
+$ echo "{some: 'thing'}" | target/debug/examples/formatjson5 -
+...
+$ ls default_*.profraw
+default_11699812450447639123_0_20944.profraw
+```
+
+You can also set a specific file name or path for the generated `.profraw` files by using the environment variable `LLVM_PROFILE_FILE`:
```shell
$ echo "{some: 'thing'}" \
@@ -115,6 +125,9 @@ If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing
- `%Nm` - the instrumented binary’s signature: The runtime creates a pool of N raw profiles, used for on-line profile merging. The runtime takes care of selecting a raw profile from the pool, locking it, and updating it before the program exits. `N` must be between `1` and `9`, and defaults to `1` if omitted (with simply `%m`).
- `%c` - Does not add anything to the filename, but enables a mode (on some platforms, including Darwin) in which profile counter updates are continuously synced to a file. This means that if the instrumented program crashes, or is killed by a signal, perfect coverage information can still be recovered.
+In the first example above, the value `11699812450447639123_0` in the generated filename is the instrumented binary's signature,
+which replaced the `%m` pattern and the value `20944` is the process ID of the binary being executed.
+
## Installing LLVM coverage tools
LLVM's supplies two tools—`llvm-profdata` and `llvm-cov`—that process coverage data and generate reports. There are several ways to find and/or install these tools, but note that the coverage mapping data generated by the Rust compiler requires LLVM version 12 or higher, and processing the *raw* data may require exactly the LLVM version used by the compiler. (`llvm-cov --version` typically shows the tool's LLVM version number, and `rustc --verbose --version` shows the version of LLVM used by the Rust compiler.)
@@ -181,11 +194,10 @@ A typical use case for coverage analysis is test coverage. Rust's source-based c
The following example (using the [`json5format`] crate, for demonstration purposes) show how to generate and analyze coverage results for all tests in a crate.
-Since `cargo test` both builds and runs the tests, we set both the additional `RUSTFLAGS`, to add the `-C instrument-coverage` flag, and `LLVM_PROFILE_FILE`, to set a custom filename for the raw profiling data generated during the test runs. Since there may be more than one test binary, apply `%m` in the filename pattern. This generates unique names for each test binary. (Otherwise, each executed test binary would overwrite the coverage results from the previous binary.)
+Since `cargo test` both builds and runs the tests, we set the additional `RUSTFLAGS`, to add the `-C instrument-coverage` flag.
```shell
$ RUSTFLAGS="-C instrument-coverage" \
- LLVM_PROFILE_FILE="json5format-%m.profraw" \
cargo test --tests
```
@@ -210,7 +222,7 @@ test result: ok. 31 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
You should have one or more `.profraw` files now, one for each test binary. Run the `profdata` tool to merge them:
```shell
-$ llvm-profdata merge -sparse json5format-*.profraw -o json5format.profdata
+$ llvm-profdata merge -sparse default_*.profraw -o json5format.profdata
```
Then run the `cov` tool, with the `profdata` file and all test binaries:
@@ -230,6 +242,8 @@ $ llvm-cov show \
--Xdemangler=rustfilt | less -R
```
+> **Note**: If overriding the default `profraw` file name via the `LLVM_PROFILE_FILE` environment variable, it's highly recommended to use the `%m` and `%p` special pattern strings to generate unique file names in the case of more than a single test binary being executed.
+
> **Note**: The command line option `--ignore-filename-regex=/.cargo/registry`, which excludes the sources for dependencies from the coverage results.\_
### Tips for listing the binaries automatically
@@ -271,9 +285,8 @@ To include doc tests in the coverage results, drop the `--tests` flag, and apply
```bash
$ RUSTFLAGS="-C instrument-coverage" \
RUSTDOCFLAGS="-C instrument-coverage -Z unstable-options --persist-doctests target/debug/doctestbins" \
- LLVM_PROFILE_FILE="json5format-%m.profraw" \
cargo test
-$ llvm-profdata merge -sparse json5format-*.profraw -o json5format.profdata
+$ llvm-profdata merge -sparse default_*.profraw -o json5format.profdata
```
The `-Z unstable-options --persist-doctests` flag is required, to save the test binaries
@@ -302,8 +315,7 @@ $ llvm-cov report \
> version without doc tests, include:
- The `cargo test ... --no-run` command is updated with the same environment variables
- and flags used to _build_ the tests, _including_ the doc tests. (`LLVM_PROFILE_FILE`
- is only used when _running_ the tests.)
+ and flags used to _build_ the tests, _including_ the doc tests.
- The file glob pattern `target/debug/doctestbins/*/rust_out` adds the `rust_out`
binaries generated for doc tests (note, however, that some `rust_out` files may not
be executable binaries).
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
index 9c644dd40..b1854b22a 100644
--- a/src/doc/rustc/src/linker-plugin-lto.md
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -30,7 +30,7 @@ Using `rustc` directly:
# Compile the Rust staticlib
rustc --crate-type=staticlib -Clinker-plugin-lto -Copt-level=2 ./lib.rs
# Compile the C code with `-flto=thin`
-clang -c -O2 -flto=thin -o main.o ./main.c
+clang -c -O2 -flto=thin -o cmain.o ./cmain.c
# Link everything, making sure that we use an appropriate linker
clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o
```
@@ -41,7 +41,7 @@ Using `cargo`:
# Compile the Rust staticlib
RUSTFLAGS="-Clinker-plugin-lto" cargo build --release
# Compile the C code with `-flto=thin`
-clang -c -O2 -flto=thin -o main.o ./main.c
+clang -c -O2 -flto=thin -o cmain.o ./cmain.c
# Link everything, making sure that we use an appropriate linker
clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o
```
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 01489e9aa..3a6963ebc 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -213,7 +213,7 @@ target | std | host | notes
[`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
`aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore
-`aarch64-unknown-uefi` | * | | ARM64 UEFI
+[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | ARM64 UEFI
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
`aarch64-unknown-netbsd` | ✓ | ✓ |
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
@@ -223,6 +223,8 @@ target | std | host | notes
`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
+[`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | ARM BE8 the default ARM big-endian architecture since [ARMv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en).
+`armv4t-none-eabi` | * | | ARMv4T A32
`armv4t-unknown-linux-gnueabi` | ? | |
`armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc
`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
@@ -249,7 +251,7 @@ target | std | host | notes
`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
`i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2
[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD
-`i686-unknown-uefi` | * | | 32-bit UEFI
+[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 32-bit UEFI
`i686-uwp-windows-gnu` | ? | |
`i686-uwp-windows-msvc` | ? | |
`i686-wrs-vxworks` | ? | |
@@ -276,6 +278,7 @@ target | std | host | notes
`powerpc64-unknown-linux-musl` | ? | |
`powerpc64-wrs-vxworks` | ? | |
`powerpc64le-unknown-linux-musl` | ? | |
+[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64
`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)
@@ -283,6 +286,7 @@ target | std | host | notes
`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)
+[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
`s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, MUSL)
`sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux
`sparc64-unknown-netbsd` | ✓ | ✓ | NetBSD/sparc64
@@ -304,7 +308,7 @@ target | std | host | notes
`x86_64-unknown-l4re-uclibc` | ? | |
`x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules
[`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD
-`x86_64-unknown-uefi` | * | | 64-bit UEFI
+[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 64-bit UEFI
`x86_64-uwp-windows-gnu` | ✓ | |
`x86_64-uwp-windows-msvc` | ✓ | |
`x86_64-wrs-vxworks` | ? | |
diff --git a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md
new file mode 100644
index 000000000..507631cdc
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md
@@ -0,0 +1,74 @@
+# armeb-unknown-linux-gnueabi
+**Tier: 3**
+
+Target for cross-compiling Linux user-mode applications targetting the ARM BE8 architecture.
+
+## Overview
+BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian ARM systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats).
+
+## History
+BE8 architecture is the default big-endian architecture for ARM since [ARMv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). It's predecessor, used for ARMv4 and ARMv5 devices was [BE32](https://developer.arm.com/documentation/dui0474/j/linker-command-line-options/--be32). On ARMv6 architecture, endianness can be configured via [system registers](https://developer.arm.com/documentation/ddi0290/g/unaligned-and-mixed-endian-data-access-support/mixed-endian-access-support/interaction-between-the-bus-protocol-and-the-core-endianness). However, BE32 was withdrawn for [ARMv7](https://developer.arm.com/documentation/ddi0406/cb/Appendixes/Deprecated-and-Obsolete-Features/Obsolete-features/Support-for-BE-32-endianness-model) onwards.
+
+## Target Maintainers
+* [@WorksButNotTested](https://github.com/WorksButNotTested)
+
+## Requirements
+The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard ARM configuration).
+
+## Target definition
+The target definition can be seen [here](https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the ARMv8 core. Though this can likely be modified as required.
+
+## Building the target
+Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target.
+
+Therefore, you can build Rust with support for the target by adding it to the target list in config.toml, a sample configuration is shown below. It is expected that the user already have a working GNU compiler toolchain and update the paths accordingly.
+
+```toml
+[llvm]
+download-ci-llvm = false
+skip-rebuild = true
+optimize = true
+ninja = true
+targets = "ARM;X86"
+clang = false
+
+[build]
+target = ["x86_64-unknown-linux-gnu", "armeb-unknown-linux-gnueabi"]
+docs = false
+docs-minification = false
+compiler-docs = false
+[install]
+prefix = "/home/user/x-tools/rust/"
+
+[rust]
+debug-logging=true
+backtrace = true
+incremental = true
+
+[target.x86_64-unknown-linux-gnu]
+
+[dist]
+
+[target.armeb-unknown-linux-gnueabi]
+cc = "/home/user/x-tools/armeb-unknown-linux-gnueabi/bin/armeb-unknown-linux-gnueabi-gcc"
+cxx = "/home/user/x-tools/armeb-unknown-linux-gnueabi/bin/armeb-unknown-linux-gnueabi-g++"
+ar = "/home/user/x-tools/armeb-unknown-linux-gnueabi/bin/armeb-unknown-linux-gnueabi-ar"
+ranlib = "/home/user/x-tools/armeb-unknown-linux-gnueabi/bin/armeb-unknown-linux-gnueabi-ranlib"
+linker = "/home/user/x-tools/armeb-unknown-linux-gnueabi/bin/armeb-unknown-linux-gnueabi-gcc"
+llvm-config = "/home/user/x-tools/clang/bin/llvm-config"
+llvm-filecheck = "/home/user/x-tools/clang/bin/FileCheck"
+```
+
+## Building Rust programs
+
+The following `.cargo/config` is needed inside any project directory to build for the BE8 target:
+
+```toml
+[build]
+target = "armeb-unknown-linux-gnueabi"
+
+[target.armeb-unknown-linux-gnueabi]
+linker = "armeb-unknown-linux-gnueabi-gcc"
+```
+
+Note that it is expected that the user has a suitable linker from the GNU toolchain.
diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
new file mode 100644
index 000000000..cf831e159
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
@@ -0,0 +1,70 @@
+# armv4t-none-eabi
+
+Tier 3
+
+Bare-metal target for any cpu in the ARMv4T architecture family, supporting
+ARM/Thumb code interworking (aka `a32`/`t32`), with ARM code as the default code
+generation.
+
+In particular this supports the Gameboy Advance (GBA), but there's nothing GBA
+specific with this target, so any ARMv4T device should work fine.
+
+## Target Maintainers
+
+* [@Lokathor](https://github.com/lokathor)
+
+## Requirements
+
+The target is cross-compiled, and uses static linking.
+
+The linker that comes with rustc cannot link for this platform (the platform is
+too old). You will need the `arm-none-eabi-ld` linker from a GNU Binutils
+targeting ARM. This can be obtained for Windows/Mac/Linux from the [ARM
+Developer Website][arm-dev], or possibly from your OS's package manager.
+
+[arm-dev]: https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain
+
+This target doesn't provide a linker script, you'll need to bring your own
+according to the specific device you want to target. Pass
+`-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use
+`your_script.ld` during linking.
+
+## Building Rust Programs
+
+Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target.
+
+Just use the `build-std` nightly cargo feature to build the `core` library. You
+can pass this as a command line argument to cargo, or your `.cargo/config.toml`
+file might include the following lines:
+
+```toml
+[unstable]
+build-std = ["core"]
+```
+
+Most of `core` should work as expected, with the following notes:
+* the target is "soft float", so `f32` and `f64` operations are emulated in
+ software.
+* integer division is also emulated in software.
+* the target is old enough that it doesn't have atomic instructions.
+
+Rust programs are output as ELF files.
+
+For running on hardware, you'll generally need to extract the "raw" program code
+out of the ELF and into a file of its own. The `objcopy` program provided as
+part of the GNU Binutils can do this:
+
+```shell
+arm-none-eabi-objcopy --output-target binary [in_file] [out_file]
+```
+
+## Testing
+
+This is a cross-compiled target that you will need to emulate during testing.
+
+Because this is a device-agnostic target, and the exact emulator that you'll
+need depends on the specific device you want to run your code on.
+
+For example, when programming for the Gameboy Advance, the
+[mgba-test-runner](https://github.com/agbrs/agb) program could be used to make a
+normal set of rust tests be run within the `mgba` emulator.
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 61bd1b425..1ff6003c1 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -5,14 +5,10 @@
[Fuchsia] is a modern open source operating system that's simple, secure,
updatable, and performant.
-[Fuchsia]: https://fuchsia.dev/
-
## Target maintainers
The [Fuchsia team]:
-[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
-
- Tyler Mandry ([@tmandry](https://github.com/tmandry))
- Dan Johnson ([@computerdruid](https://github.com/computerdruid))
- David Koloski ([@djkoloski](https://github.com/djkoloski))
@@ -24,27 +20,174 @@ the members reported by the API. The API should be considered to be
authoritative if this occurs. Instead of pinging individual members, use
`@rustbot ping fuchsia` to contact the team on GitHub.
+## Table of contents
+
+1. [Requirements](#requirements)
+1. [Walkthrough structure](#walkthrough-structure)
+1. [Compiling a Rust binary targeting Fuchsia](#compiling-a-rust-binary-targeting-fuchsia)
+ 1. [Targeting Fuchsia with rustup and cargo](#targeting-fuchsia-with-rustup-and-cargo)
+ 1. [Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)
+1. [Creating a Fuchsia package](#creating-a-fuchsia-package)
+ 1. [Creating a Fuchsia component](#creating-a-fuchsia-component)
+ 1. [Building a Fuchsia package](#building-a-fuchsia-package)
+1. [Publishing a Fuchsia package](#publishing-a-fuchsia-package)
+ 1. [Creating a Fuchsia package repository](#creating-a-fuchsia-package-repository)
+ 1. [Publishing Fuchsia package to repository](#publishing-fuchsia-package-to-repository)
+1. [Running a Fuchsia component on an emulator](#running-a-fuchsia-component-on-an-emulator)
+ 1. [Starting the Fuchsia emulator](#starting-the-fuchsia-emulator)
+ 1. [Watching emulator logs](#watching-emulator-logs)
+ 1. [Serving a Fuchsia package](#serving-a-fuchsia-package)
+ 1. [Running a Fuchsia component](#running-a-fuchsia-component)
+1. [`.gitignore` extensions](#gitignore-extensions)
+1. [Testing](#testing)
+ 1. [Running unit tests](#running-unit-tests)
+ 1. [Running the compiler test suite](#running-the-compiler-test-suite)
+1. [Debugging](#debugging)
+ 1. [`zxdb`](#zxdb)
+ 1. [Attaching `zxdb`](#attaching-zxdb)
+ 1. [Using `zxdb`](#using-zxdb)
+ 1. [Displaying source code in `zxdb`](#displaying-source-code-in-zxdb)
+
## Requirements
-This target is cross-compiled from a host environment. Development may be done
-from the [source tree] or using the Fuchsia SDK.
+This target is cross-compiled from a host environment. You will need a recent
+copy of the [Fuchsia SDK], which provides the tools, libraries, and binaries
+required to build and link programs for Fuchsia.
-[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
+Development may also be done from the [source tree].
-Fuchsia targets support std and follow the `sysv64` calling convention on
+Fuchsia targets support `std` and follow the `sysv64` calling convention on
x86_64. Fuchsia binaries use the ELF file format.
-## Building the target
+## Walkthrough structure
+
+This walkthrough will cover:
+
+1. Compiling a Rust binary targeting Fuchsia.
+1. Building a Fuchsia package.
+1. Publishing and running a Fuchsia package to a Fuchsia emulator.
+
+For the purposes of this walkthrough, we will only target `x86_64-fuchsia`.
+
+## Compiling a Rust binary targeting Fuchsia
+
+Today, there are two main ways to build a Rust binary targeting Fuchsia
+using the Fuchsia SDK:
+1. Allow [rustup] to handle the installation of Fuchsia targets for you.
+1. Build a toolchain locally that can target Fuchsia.
+
+### Targeting Fuchsia with rustup and cargo
+
+The easiest way to build a Rust binary targeting Fuchsia is by allowing [rustup]
+to handle the installation of Fuchsia targets for you. This can be done by issuing
+the following commands:
+
+```sh
+rustup target add x86_64-fuchsia
+rustup target add aarch64-fuchsia
+```
+
+After installing our Fuchsia targets, we can now compile a Rust binary that targets
+Fuchsia.
+
+To create our Rust project, we can issue a standard `cargo` command as follows:
+
+**From base working directory**
+```sh
+cargo new hello_fuchsia
+```
+
+The rest of this walkthrough will take place from `hello_fuchsia`, so we can
+change into that directory now:
+
+```sh
+cd hello_fuchsia
+```
+
+*Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
+directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
+
+We can edit our `src/main.rs` to include a test as follows:
+
+**`src/main.rs`**
+```rust
+fn main() {
+ println!("Hello Fuchsia!");
+}
+
+#[test]
+fn it_works() {
+ assert_eq!(2 + 2, 4);
+}
+```
+
+In addition to the standard workspace created, we will want to create a
+`.cargo/config.toml` file to link necessary libraries
+during compilation:
+
+**`.cargo/config.toml`**
+```txt
+[target.x86_64-fuchsia]
+
+rustflags = [
+ "-Lnative=<SDK_PATH>/arch/x64/lib",
+ "-Lnative=<SDK_PATH>/arch/x64/sysroot/lib"
+]
+```
+
+*Note: Make sure to fill out `<SDK_PATH>` with the path to the downloaded [Fuchsia SDK].*
+
+These options configure the following:
+
+* `-Lnative=${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
+ the SDK
+* `-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia sysroot
+ libraries from the SDK
+
+In total, our new project will look like:
+
+**Current directory structure**
+```txt
+hello_fuchsia/
+┣┠src/
+┃ ┗┠main.rs
+┣┠Cargo.toml
+â”—â” .cargo/
+ â”—â” config.toml
+```
+
+Finally, we can build our rust binary as:
+
+```sh
+cargo build --target x86_64-fuchsia
+```
+
+Now we have a Rust binary at `target/x86_64-fuchsia/debug/hello_fuchsia`,
+targeting our desired Fuchsia target.
+
+**Current directory structure**
+```txt
+hello_fuchsia/
+┣┠src/
+┃ ┗┠main.rs
+┣┠target/
+┃ ┗┠x86_64-fuchsia/
+┃ ┗┠debug/
+┃ ┗┠hello_fuchsia
+┣┠Cargo.toml
+â”—â” .cargo/
+ â”—â” config.toml
+```
+
+### Targeting Fuchsia with a compiler built from source
+
+An alternative to the first workflow is to target Fuchsia by using
+`rustc` built from source.
Before building Rust for Fuchsia, you'll need a clang toolchain that supports
Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
Rust for Fuchsia.
-You'll also need a recent copy of the [Fuchsia SDK], which provides the tools
-and binaries required to build and link programs for Fuchsia.
-
-[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
-
x86-64 and AArch64 Fuchsia targets can be enabled using the following
configuration.
@@ -53,12 +196,6 @@ In `config.toml`, add:
```toml
[build]
target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"]
-
-[target.x86_64-fuchsia]
-llvm-libunwind = "in-tree"
-
-[target.aarch64-fuchsia]
-llvm-libunwind = "in-tree"
```
Additionally, the following environment variables must be configured (for
@@ -81,15 +218,21 @@ export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/
These can be run together in a shell environment by executing
`(source config-env.sh && ./x.py install)`.
-## Building Rust programs
+Once `rustc` is installed, we can create a new working directory to work from,
+`hello_fuchsia` along with `hello_fuchsia/src`:
-After compiling Rust binaries, you'll need to build a component, package it, and
-serve it to a Fuchsia device or emulator. All of this can be done using the
-Fuchsia SDK.
+```sh
+mkdir hello_fuchsia
+cd hello_fuchsia
+mkdir src
+```
+
+*Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
+directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
-As an example, we'll compile and run this simple program on a Fuchsia emulator:
+There, we can create a new file named `src/hello_fuchsia.rs`:
-**`hello_fuchsia.rs`**
+**`src/hello_fuchsia.rs`**
```rust
fn main() {
println!("Hello Fuchsia!");
@@ -101,45 +244,113 @@ fn it_works() {
}
```
-Create a new file named `hello_fuchsia.rs` and fill out its contents with that
-code.
+**Current directory structure**
+```txt
+hello_fuchsia/
+â”—â” src/
+ â”—â” hello_fuchsia.rs
+```
+
+Using your freshly installed `rustc`, you can compile a binary for Fuchsia using
+the following options:
+
+* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
+ platform of your choice
+* `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
+ the SDK
+* `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia sysroot
+ libraries from the SDK
-### Create a package
+Putting it all together:
+```sh
+# Configure these for the Fuchsia target of your choice
+TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
+ARCH="<x64|aarch64>"
+
+rustc \
+ --target ${TARGET_ARCH} \
+ -Lnative=${SDK_PATH}/arch/${ARCH}/lib \
+ -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib \
+ --out-dir bin src/hello_fuchsia.rs
+```
+
+**Current directory structure**
+```txt
+hello_fuchsia/
+┣┠src/
+┃ ┗┠hello_fuchsia.rs
+â”—â” bin/
+ â”—â” hello_fuchsia
+```
+
+## Creating a Fuchsia package
+
+Before moving on, double check your directory structure:
+
+**Current directory structure**
+```txt
+hello_fuchsia/
+┣┠src/ (if using rustc)
+┃ ┗┠hello_fuchsia.rs ...
+┣┠bin/ ...
+┃ ┗┠hello_fuchsia ...
+┣┠src/ (if using cargo)
+┃ ┗┠main.rs ...
+â”—â” target/ ...
+ â”—â” x86_64-fuchsia/ ...
+ â”—â” debug/ ...
+ â”—â” hello_fuchsia ...
+```
+
+With our Rust binary built, we can move to creating a Fuchsia package.
On Fuchsia, a package is the unit of distribution for software. We'll need to
create a new package directory where we will place files like our finished
-binary and any data it may need. The working directory will have this layout:
+binary and any data it may need.
+
+To start, make the `pkg`, and `pkg/meta` directories:
+
+```sh
+mkdir pkg
+mkdir pkg/meta
+```
+**Current directory structure**
```txt
-hello_fuchsia.rs
-hello_fuchsia.cml
-package
-┣┠bin
-┃ ┗┠hello_fuchsia
-┣┠meta
-┃ ┣┠package
-┃ ┗┠hello_fuchsia.cm
-â”—â” hello_fuchsia.manifest
+hello_fuchsia/
+â”—â” pkg/
+ â”—â” meta/
```
-Make the `package`, `package/bin`, and `package/meta` directories and create the
-following files inside:
+Now, create the following files inside:
-**`package/meta/package`**
+**`pkg/meta/package`**
```json
-{"name":"hello_fuchsia","version":0}
+{
+ "name": "hello_fuchsia",
+ "version": "0"
+}
```
The `package` file describes our package's name and version number. Every
package must contain one.
-**`package/hello_fuchsia.manifest`**
+**`pkg/hello_fuchsia.manifest` if using cargo**
+```txt
+bin/hello_fuchsia=target/x86_64-fuchsia/debug/hello_fuchsia
+lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
+lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
+meta/package=pkg/meta/package
+meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
+```
+
+**`pkg/hello_fuchsia.manifest` if using rustc**
```txt
-bin/hello_fuchsia=package/bin/hello_fuchsia
+bin/hello_fuchsia=bin/hello_fuchsia
lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
-meta/package=package/meta/package
-meta/hello_fuchsia.cm=package/meta/hello_fuchsia.cm
+meta/package=pkg/meta/package
+meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
```
*Note: Relative manifest paths are resolved starting from the working directory
@@ -147,42 +358,26 @@ of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
SDK.*
The `.manifest` file will be used to describe the contents of the package by
-relating their location when installed to their location on the file system. You
-can use this to make a package pull files from other places, but for this
-example we'll just be placing everything in the `package` directory.
-
-### Compiling a binary
-
-Using your freshly compiled `rustc`, you can compile a binary for Fuchsia using
-the following options:
+relating their location when installed to their location on the file system. The
+`bin/hello_fuchsia=` entry will be different depending on how your Rust binary
+was built, so choose accordingly.
-* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
- platform of your choice
-* `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
- the SDK
-* `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel
- libraries from the SDK
-
-Putting it all together:
-
-```sh
-# Configure these for the Fuchsia target of your choice
-TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
-ARCH="<x64|aarch64>"
-
-rustc --target ${TARGET_ARCH} -Lnative=${SDK_PATH}/arch/${ARCH}/lib -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib -o package/bin/hello_fuchsia hello_fuchsia.rs
+**Current directory structure**
+```txt
+hello_fuchsia/
+â”—â” pkg/
+ ┣┠meta/
+ ┃ ┗┠package
+ â”—â” hello_fuchsia.manifest
```
-### Bulding a component
+### Creating a Fuchsia component
-On Fuchsia, components require a component manifest written in Fuchia's markup
+On Fuchsia, components require a component manifest written in Fuchsia's markup
language called CML. The Fuchsia devsite contains an [overview of CML] and a
[reference for the file format]. Here's a basic one that can run our single binary:
-[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
-[reference for the file format]: https://fuchsia.dev/reference/cml
-
-**`hello_fuchsia.cml`**
+**`pkg/hello_fuchsia.cml`**
```txt
{
include: [ "syslog/client.shard.cml" ],
@@ -193,43 +388,154 @@ language called CML. The Fuchsia devsite contains an [overview of CML] and a
}
```
+**Current directory structure**
+```txt
+hello_fuchsia/
+â”—â” pkg/
+ ┣┠meta/
+ ┃ ┗┠package
+ ┣┠hello_fuchsia.manifest
+ â”—â” hello_fuchsia.cml
+```
+
Now we can compile that CML into a component manifest:
```sh
-${SDK_PATH}/tools/${ARCH}/cmc compile hello_fuchsia.cml --includepath ${SDK_PATH}/pkg -o package/meta/hello_fuchsia.cm
+${SDK_PATH}/tools/${ARCH}/cmc compile \
+ pkg/hello_fuchsia.cml \
+ --includepath ${SDK_PATH}/pkg \
+ -o pkg/meta/hello_fuchsia.cm
```
-`--includepath` tells the compiler where to look for `include`s from our CML.
-In our case, we're only using `syslog/client.shard.cml`.
+*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
+In our case, we're only using `syslog/client.shard.cml`.*
-### Building and publishing a package
+**Current directory structure**
+```txt
+hello_fuchsia/
+â”—â” pkg/
+ ┣┠meta/
+ ┃ ┣┠package
+ ┃ ┗┠hello_fuchsia.cm
+ ┣┠hello_fuchsia.manifest
+ â”—â” hello_fuchsia.cml
+```
-Next, we'll build our package as defined by our manifest:
+### Building a Fuchsia package
+
+Next, we'll build a package manifest as defined by our manifest:
```sh
-${SDK_PATH}/tools/${ARCH}/pm -o hello_fuchsia -m package/hello_fuchsia.manifest build -output-package-manifest hello_fuchsia_manifest
+${SDK_PATH}/tools/${ARCH}/pm \
+ -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 | awk -F ' ' '{print $2}') \
+ -o pkg/hello_fuchsia_manifest \
+ -m pkg/hello_fuchsia.manifest \
+ build \
+ -output-package-manifest pkg/hello_fuchsia_package_manifest
+```
+
+This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
+publish directly to a repository.
+
+**Current directory structure**
+```txt
+hello_fuchsia/
+â”—â” pkg/
+ ┣┠meta/
+ ┃ ┣┠package
+ ┃ ┗┠hello_fuchsia.cm
+ ┣┠hello_fuchsia_manifest/
+ ┃ ┗┠...
+ ┣┠hello_fuchsia.manifest
+ ┣┠hello_fuchsia.cml
+ â”—â” hello_fuchsia_package_manifest
```
-This will produce `hello_fuchsia_manifest` which is a package manifest we can
-publish directly to a repository. We can set up that repository with:
+We are now ready to publish the package.
+
+## Publishing a Fuchsia package
+
+With our package and component manifests setup,
+we can now publish our package. The first step will
+be to create a Fuchsia package repository to publish
+to.
+
+### Creating a Fuchsia package repository
+
+We can set up our repository with:
```sh
-${SDK_PATH}/tools/${ARCH}/pm newrepo -repo repo
+${SDK_PATH}/tools/${ARCH}/pm newrepo \
+ -repo pkg/repo
```
-And then publish our new package to that repository with:
+**Current directory structure**
+```txt
+hello_fuchsia/
+â”—â” pkg/
+ ┣┠meta/
+ ┃ ┣┠package
+ ┃ ┗┠hello_fuchsia.cm
+ ┣┠hello_fuchsia_manifest/
+ ┃ ┗┠...
+ ┣┠repo/
+ ┃ ┗┠...
+ ┣┠hello_fuchsia.manifest
+ ┣┠hello_fuchsia.cml
+ â”—â” hello_fuchsia_package_manifest
+```
+
+## Publishing Fuchsia package to repository
+
+We can publish our new package to that repository with:
```sh
-${SDK_PATH}/tools/${ARCH}/pm publish -repo repo -lp -f <(echo "hello_fuchsia_manifest")
+${SDK_PATH}/tools/${ARCH}/pm publish \
+ -repo pkg/repo \
+ -lp -f <(echo "pkg/hello_fuchsia_package_manifest")
```
-Then we can add it to `ffx`'s package server as `hello-fuchsia` using:
+Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
```sh
-${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm repo -r hello-fuchsia
+${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
+ pkg/repo \
+ -r hello-fuchsia
+```
+
+## Running a Fuchsia component on an emulator
+
+At this point, we are ready to run our Fuchsia
+component. For reference, our final directory
+structure will look like:
+
+**Final directory structure**
+```txt
+hello_fuchsia/
+┣┠src/ (if using rustc)
+┃ ┗┠hello_fuchsia.rs ...
+┣┠bin/ ...
+┃ ┗┠hello_fuchsia ...
+┣┠src/ (if using cargo)
+┃ ┗┠main.rs ...
+┣┠target/ ...
+┃ ┗┠x86_64-fuchsia/ ...
+┃ ┗┠debug/ ...
+┃ ┗┠hello_fuchsia ...
+â”—â” pkg/
+ ┣┠meta/
+ ┃ ┣┠package
+ ┃ ┗┠hello_fuchsia.cm
+ ┣┠hello_fuchsia_manifest/
+ ┃ ┗┠...
+ ┣┠repo/
+ ┃ ┗┠...
+ ┣┠hello_fuchsia.manifest
+ ┣┠hello_fuchsia.cml
+ â”—â” hello_fuchsia_package_manifest
```
-### Starting the emulator
+### Starting the Fuchsia emulator
Start a Fuchsia emulator in a new terminal using:
@@ -238,39 +544,85 @@ ${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
```
-Then, once the emulator has been started:
+### Watching emulator logs
+
+Once the emulator is running, open a separate terminal to watch the emulator logs:
+
+**In separate terminal**
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx log \
+ --since now
+```
+
+### Serving a Fuchsia package
+
+Now, start a package repository server to serve our
+package to the emulator:
```sh
-${SDK_PATH}/tools/${ARCH}/ffx target repository register
+${SDK_PATH}/tools/${ARCH}/ffx repository server start
```
-And watch the logs from the emulator in a separate terminal:
+Once the repository server is up and running, register it with the target Fuchsia system running in the emulator:
```sh
-${SDK_PATH}/tools/${ARCH}/ffx log --since now
+${SDK_PATH}/tools/${ARCH}/ffx target repository register \
+ --repository hello-fuchsia
```
+### Running a Fuchsia component
+
Finally, run the component:
```sh
-${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
+${SDK_PATH}/tools/${ARCH}/ffx component run \
+ /core/ffx-laboratory:hello_fuchsia \
+ fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
```
On reruns of the component, the `--recreate` argument may also need to be
passed.
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx component run \
+ --recreate \
+ /core/ffx-laboratory:hello_fuchsia \
+ fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
+```
+
+## `.gitignore` extensions
+
+Optionally, we can create/extend our `.gitignore` file to ignore files and
+directories that are not helpful to track:
+
+```txt
+pkg/repo
+pkg/meta/hello_fuchsia.cm
+pkg/hello_fuchsia_manifest
+pkg/hello_fuchsia_package_manifest
+```
+
## Testing
### Running unit tests
-Tests can be run in the same way as a regular binary, simply by passing `--test`
-to the `rustc` invocation and then repackaging and rerunning. The test harness
-will run the applicable unit tests.
+Tests can be run in the same way as a regular binary.
+
+* If using `cargo`, you can simply pass `test --no-run`
+to the `cargo` invocation and then repackage and rerun the Fuchsia package. From our previous example,
+this would look like `cargo test --target x86_64-fuchsia --no-run`, and moving the executable
+binary path found from the line `Executable unittests src/main.rs (target/x86_64-fuchsia/debug/deps/hello_fuchsia-<HASH>)`
+into `pkg/hello_fuchsia.manifest`.
+
+* If using the compiled `rustc`, you can simply pass `--test`
+to the `rustc` invocation and then repackage and rerun the Fuchsia package.
+
+The test harness will run the applicable unit tests.
Often when testing, you may want to pass additional command line arguments to
your binary. Additional arguments can be set in the component manifest:
-**`hello_fuchsia.cml`**
+**`pkg/hello_fuchsia.cml`**
```txt
{
include: [ "syslog/client.shard.cml" ],
@@ -285,11 +637,148 @@ your binary. Additional arguments can be set in the component manifest:
This will pass the argument `it_works` to the binary, filtering the tests to
only those tests that match the pattern. There are many more configuration
options available in CML including environment variables. More documentation is
-available on the [Fuchsia devsite](https://fuchsia.dev/reference/cml).
+available on the [Fuchsia devsite].
### Running the compiler test suite
Running the Rust test suite on Fuchsia is [not currently supported], but work is
underway to enable it.
+## Debugging
+
+### `zxdb`
+
+Debugging components running on a Fuchsia emulator can be done using the
+console-mode debugger: [zxdb]. We will demonstrate attaching necessary symbol
+paths to debug our `hello-fuchsia` component.
+
+### Attaching `zxdb`
+
+In a separate terminal, issue the following command from our `hello_fuchsia`
+directory to launch `zxdb`:
+
+**In separate terminal**
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
+ --symbol-path target/x86_64-fuchsia/debug
+```
+
+* `--symbol-path` gets required symbol paths, which are
+necessary for stepping through your program.
+
+The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can
+display Rust and/or Fuchsia source code in your debugging session.
+
+### Using `zxdb`
+
+Once launched, you will be presented with the window:
+
+```sh
+Connecting (use "disconnect" to cancel)...
+Connected successfully.
+👉 To get started, try "status" or "help".
+[zxdb]
+```
+
+To attach to our program, we can run:
+
+```sh
+[zxdb] attach hello_fuchsia
+```
+
+**Expected output**
+```sh
+Waiting for process matching "hello_fuchsia".
+Type "filter" to see the current filters.
+```
+
+Next, we can create a breakpoint at main using "b main":
+
+```sh
+[zxdb] b main
+```
+
+**Expected output**
+```sh
+Created Breakpoint 1 @ main
+```
+
+Finally, we can re-run the "hello_fuchsia" component from our original
+terminal:
+
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx component run \
+ --recreate \
+ fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
+```
+
+Once our component is running, our `zxdb` window will stop execution
+in our main as desired:
+
+**Expected output**
+```txt
+Breakpoint 1 now matching 1 addrs for main
+🛑 on bp 1 hello_fuchsia::main() • main.rs:2
+ 1 fn main() {
+ â–¶ 2 println!("Hello Fuchsia!");
+ 3 }
+ 4
+[zxdb]
+```
+
+`zxdb` has similar commands to other debuggers like [gdb].
+To list the available commands, run "help" in the
+`zxdb` window or visit [the zxdb documentation].
+
+```sh
+[zxdb] help
+```
+
+**Expected output**
+```sh
+Help!
+
+ Type "help <command>" for command-specific help.
+
+Other help topics (see "help <topic>")
+...
+```
+
+### Displaying source code in `zxdb`
+
+By default, the debugger will not be able to display
+source code while debugging. For our user code, we displayed
+source code by pointing our debugger to our debug binary via
+the `--symbol-path` arg. To display library source code in
+the debugger, you must provide paths to the source using
+`--build-dir`. For example, to display the Rust and Fuchsia
+source code:
+
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
+ --symbol-path target/x86_64-fuchsia/debug \
+ --build-dir ${RUST_SRC_PATH}/rust \
+ --build-dir ${FUCHSIA_SRC_PATH}/fuchsia/out/default
+```
+
+ * `--build-dir` links against source code paths, which
+ are not strictly necessary for debugging, but is a nice-to-have
+ for displaying source code in `zxdb`.
+
+ Linking to a Fuchsia checkout can help with debugging Fuchsia libraries,
+ such as [fdio].
+
+[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
+[Fuchsia]: https://fuchsia.dev/
+[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
+[rustup]: https://rustup.rs/
+[cargo]: https://doc.rust-lang.org/cargo/
+[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
+[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
+[reference for the file format]: https://fuchsia.dev/reference/cml
+[Fuchsia devsite]: https://fuchsia.dev/reference/cml
[not currently supported]: https://fxbug.dev/105393
+[zxdb]: https://fuchsia.dev/fuchsia-src/development/debugger
+[gdb]: https://www.sourceware.org/gdb/
+[the zxdb documentation]: https://fuchsia.dev/fuchsia-src/development/debugger
+[fdio]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fdio/
diff --git a/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md
index d325ba334..b18a125f3 100644
--- a/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md
+++ b/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md
@@ -87,7 +87,7 @@ Rust programs can be built for that target:
rustc --target m68k-unknown-linux-gnu your-code.rs
```
-Very simple progams can be run using the `qemu-m68k-static` program:
+Very simple programs can be run using the `qemu-m68k-static` program:
```text
$ qemu-m68k-static your-code
diff --git a/src/doc/rustc/src/platform-support/openbsd.md b/src/doc/rustc/src/platform-support/openbsd.md
index b2ac776ea..4ce80157d 100644
--- a/src/doc/rustc/src/platform-support/openbsd.md
+++ b/src/doc/rustc/src/platform-support/openbsd.md
@@ -12,6 +12,8 @@ The target names follow this format: `$ARCH-unknown-openbsd`, where `$ARCH` spec
|--------------------------------|-------------|------------------|
| `aarch64-unknown-openbsd` | libc++ | [64-bit ARM systems](https://www.openbsd.org/arm64.html) |
| `i686-unknown-openbsd` | libc++ | [Standard PC and clones based on the Intel i386 architecture and compatible processors](https://www.openbsd.org/i386.html) |
+| `powerpc64-unknown-openbsd` | libc++ | [IBM POWER-based PowerNV systems](https://www.openbsd.org/powerpc64.html) |
+| `riscv64gc-unknown-openbsd` | libc++ | [64-bit RISC-V systems](https://www.openbsd.org/riscv64.html) |
| `sparc64-unknown-openbsd` | estdc++ | [Sun UltraSPARC and Fujitsu SPARC64 systems](https://www.openbsd.org/sparc64.html) |
| `x86_64-unknown-openbsd` | libc++ | [AMD64-based systems](https://www.openbsd.org/amd64.html) |
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 721c234c6..fb0cea05d 100644
--- a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md
+++ b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md
@@ -25,7 +25,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.
+For cross-compilation I recommend using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain, one change that seems necessary beside configuring cross 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 available so I won't describe them here.
## Building Rust programs
diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md
index 8f90d9c74..295dec0f0 100644
--- a/src/doc/rustc/src/platform-support/unknown-uefi.md
+++ b/src/doc/rustc/src/platform-support/unknown-uefi.md
@@ -133,7 +133,7 @@ There are 3 common ways to compile native C code for UEFI targets:
- Use native Windows targets. This means compiling your C code for the Windows
platform as if it was the UEFI platform. This works for static libraries, but
needs adjustments when linking into an UEFI executable. You can, however,
- link such static libraries seemlessly into rust code compiled for UEFI
+ link such static libraries seamlessly into rust code compiled for UEFI
targets. Be wary of any includes that are not specifically suitable for UEFI
targets (especially the C standard library includes are not always
compatible). Freestanding compilations are recommended to avoid
diff --git a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md
index 021b904de..6932e6a57 100644
--- a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md
+++ b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md
@@ -30,7 +30,7 @@ is 8-bytes large as well as pointers. The tradeoff, though, is that the maximum
memory size is now the full 64-bit address space instead of the 4GB as limited
by the 32-bit address space for `wasm32-unknown-unknown`.
-This target is not a stable target. The [memory64] WebAssembly proposal is stil
+This target is not a stable target. The [memory64] WebAssembly proposal is still
in-progress and not standardized. This means that there are not many engines
which implement the `memory64` feature and if they do they're likely behind a
flag, for example:
diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml
index 45405a117..dfa685785 100644
--- a/src/doc/rustdoc/book.toml
+++ b/src/doc/rustdoc/book.toml
@@ -6,5 +6,9 @@ title = "The rustdoc book"
git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc"
[output.html.redirect]
+"/what-to-include.html" = "write-documentation/what-to-include.html"
"/the-doc-attribute.html" = "write-documentation/the-doc-attribute.html"
+"/linking-to-items-by-name.html" = "write-documentation/linking-to-items-by-name.html"
"/documentation-tests.html" = "write-documentation/documentation-tests.html"
+"/website-features.html" = "advanced-features.html#custom-search-engines"
+"/passes.html" = "deprecated-features.html#passes"
diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
index bfa92e7d3..321992f7b 100644
--- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md
+++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
@@ -143,7 +143,7 @@ fn do_features() {}
#[cfg(has_feathers = "zapping")] // This is expected as "has_feathers" was provided in names()
// and because no value checking was enable for "has_feathers"
- // no warning is emited for the value "zapping"
+ // no warning is emitted for the value "zapping"
fn do_zapping() {}
#[cfg(has_mumble_frotz)] // This is UNEXPECTED because names checking is enable and
diff --git a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md
index 977d25852..3890a12b7 100644
--- a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md
+++ b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md
@@ -8,7 +8,7 @@ This flag will rewrite absolute paths under the current working directory,
replacing the current working directory prefix with a specified value.
The given value may be absolute or relative, or empty. This switch takes
-precidence over `--remap-path-prefix` in case they would both match a given
+precedence over `--remap-path-prefix` in case they would both match a given
path.
This flag helps to produce deterministic output, by removing the current working
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
index 7f7549aaf..b33405f18 100644
--- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md
+++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -9,17 +9,17 @@ The tracking issues for this feature are:
This feature allows for use of one of following sanitizers:
-* [AddressSanitizer][clang-asan] a fast memory error detector.
-* [ControlFlowIntegrity][clang-cfi] LLVM Control Flow Integrity (CFI) provides
+* [AddressSanitizer](#addresssanitizer) a fast memory error detector.
+* [ControlFlowIntegrity](#controlflowintegrity) LLVM Control Flow Integrity (CFI) provides
forward-edge control flow protection.
-* [HWAddressSanitizer][clang-hwasan] a memory error detector similar to
+* [HWAddressSanitizer](#hwaddresssanitizer) a memory error detector similar to
AddressSanitizer, but based on partial hardware assistance.
-* [LeakSanitizer][clang-lsan] a run-time memory leak detector.
-* [MemorySanitizer][clang-msan] a detector of uninitialized reads.
-* [MemTagSanitizer][clang-memtag] fast memory error detector based on
+* [LeakSanitizer](#leaksanitizer) a run-time memory leak detector.
+* [MemorySanitizer](#memorysanitizer) a detector of uninitialized reads.
+* [MemTagSanitizer](#memtagsanitizer) fast memory error detector based on
Armv8.5-A Memory Tagging Extension.
-* [ShadowCallStack][clang-scs] provides backward-edge control flow protection.
-* [ThreadSanitizer][clang-tsan] a fast data race detector.
+* [ShadowCallStack](#shadowcallstack) provides backward-edge control flow protection.
+* [ThreadSanitizer](#threadsanitizer) a fast data race detector.
To enable a sanitizer compile with `-Zsanitizer=address`,`-Zsanitizer=cfi`,
`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`,
@@ -58,6 +58,8 @@ AddressSanitizer works with non-instrumented code although it will impede its
ability to detect some bugs. It is not expected to produce false positive
reports.
+See the [Clang AddressSanitizer documentation][clang-asan] for more details.
+
## Examples
Stack buffer overflow:
@@ -204,6 +206,8 @@ tracking issue [#89653](https://github.com/rust-lang/rust/issues/89653)).
LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto).
+See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details.
+
## Example
```text
@@ -430,6 +434,8 @@ HWAddressSanitizer requires `tagged-globals` target feature to instrument
globals. To enable this target feature compile with `-C
target-feature=+tagged-globals`
+See the [Clang HWAddressSanitizer documentation][clang-hwasan] for more details.
+
## Example
Heap buffer overflow:
@@ -507,6 +513,8 @@ LeakSanitizer is supported on the following targets:
* `x86_64-apple-darwin`
* `x86_64-unknown-linux-gnu`
+See the [Clang LeakSanitizer documentation][clang-lsan] for more details.
+
# MemorySanitizer
MemorySanitizer is detector of uninitialized reads.
@@ -521,6 +529,8 @@ MemorySanitizer requires all program code to be instrumented. C/C++ dependencies
need to be recompiled using Clang with `-fsanitize=memory` option. Failing to
achieve that will result in false positive reports.
+See the [Clang MemorySanitizer documentation][clang-msan] for more details.
+
## Example
Detecting the use of uninitialized memory. The `-Zbuild-std` flag rebuilds and
@@ -569,7 +579,7 @@ MemTagSanitizer is supported on the following targets:
MemTagSanitizer requires hardware support and the `mte` target feature.
To enable this target feature compile with `-C target-feature="+mte"`.
-More information can be found in the associated [LLVM documentation](https://llvm.org/docs/MemTagSanitizer.html).
+See the [LLVM MemTagSanitizer documentation][llvm-memtag] for more details.
# ShadowCallStack
@@ -581,7 +591,9 @@ ShadowCallStack can be enabled with `-Zsanitizer=shadow-call-stack` option and i
* `aarch64-linux-android`
-A runtime must be provided by the application or operating system. See the [LLVM documentation][clang-scs] for further details.
+A runtime must be provided by the application or operating system.
+
+See the [Clang ShadowCallStack documentation][clang-scs] for more details.
# ThreadSanitizer
@@ -604,6 +616,8 @@ can lead to false positive reports.
ThreadSanitizer does not support atomic fences `std::sync::atomic::fence`,
nor synchronization performed using inline assembly code.
+See the [Clang ThreadSanitizer documentation][clang-tsan] for more details.
+
## Example
```rust
@@ -673,6 +687,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT
* [HWAddressSanitizer in Clang][clang-hwasan]
* [LeakSanitizer in Clang][clang-lsan]
* [MemorySanitizer in Clang][clang-msan]
+* [MemTagSanitizer in LLVM][llvm-memtag]
* [ThreadSanitizer in Clang][clang-tsan]
[clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html
@@ -682,3 +697,4 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT
[clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html
[clang-scs]: https://clang.llvm.org/docs/ShadowCallStack.html
[clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html
+[llvm-memtag]: https://llvm.org/docs/MemTagSanitizer.html
diff --git a/src/doc/unstable-book/src/language-features/raw-dylib.md b/src/doc/unstable-book/src/language-features/raw-dylib.md
index 23fc5b305..5fd208ae7 100644
--- a/src/doc/unstable-book/src/language-features/raw-dylib.md
+++ b/src/doc/unstable-book/src/language-features/raw-dylib.md
@@ -26,9 +26,9 @@ fn main() {
## Limitations
-Currently, this feature is only supported on `-windows-msvc` targets. Non-Windows platforms don't have import
-libraries, and an incompatibility between LLVM and the BFD linker means that it is not currently supported on
-`-windows-gnu` targets.
+This feature is unstable for the `x86` architecture, and stable for all other architectures.
-On the `i686-pc-windows-msvc` target, this feature supports only the `cdecl`, `stdcall`, `system`, and `fastcall`
-calling conventions.
+This feature is only supported on Windows.
+
+On the `x86` architecture, this feature supports only the `cdecl`, `stdcall`, `system`, `fastcall`, and
+`vectorcall` calling conventions.
diff --git a/src/doc/unstable-book/src/language-features/unix-sigpipe.md b/src/doc/unstable-book/src/language-features/unix-sigpipe.md
new file mode 100644
index 000000000..aa39b6eb2
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/unix-sigpipe.md
@@ -0,0 +1,54 @@
+# `unix_sigpipe`
+
+The tracking issue for this feature is: [#97889]
+
+[#97889]: https://github.com/rust-lang/rust/issues/97889
+
+---
+
+The `#[unix_sigpipe = "..."]` attribute on `fn main()` can be used to specify how libstd shall setup `SIGPIPE` on Unix platforms before invoking `fn main()`. This attribute is ignored on non-Unix targets. There are three variants:
+* `#[unix_sigpipe = "inherit"]`
+* `#[unix_sigpipe = "sig_dfl"]`
+* `#[unix_sigpipe = "sig_ign"]`
+
+## `#[unix_sigpipe = "inherit"]`
+
+Leave `SIGPIPE` untouched before entering `fn main()`. Unless the parent process has changed the default `SIGPIPE` handler from `SIG_DFL` to something else, this will behave the same as `#[unix_sigpipe = "sig_dfl"]`.
+
+## `#[unix_sigpipe = "sig_dfl"]`
+
+Set the `SIGPIPE` handler to `SIG_DFL`. This will result in your program getting killed if it tries to write to a closed pipe. This is normally what you want if your program produces textual output.
+
+### Example
+
+```rust,no_run
+#![feature(unix_sigpipe)]
+#[unix_sigpipe = "sig_dfl"]
+fn main() { loop { println!("hello world"); } }
+```
+
+```bash
+% ./main | head -n 1
+hello world
+```
+
+## `#[unix_sigpipe = "sig_ign"]`
+
+Set the `SIGPIPE` handler to `SIG_IGN` before invoking `fn main()`. This will result in `ErrorKind::BrokenPipe` errors if you program tries to write to a closed pipe. This is normally what you want if you for example write socket servers, socket clients, or pipe peers.
+
+This is what libstd has done by default since 2014. Omitting `#[unix_sigpipe = "..."]` is the same as having `#[unix_sigpipe = "sig_ign"]`.
+
+### Example
+
+```rust,no_run
+#![feature(unix_sigpipe)]
+#[unix_sigpipe = "sig_ign"]
+fn main() { loop { println!("hello world"); } }
+```
+
+```bash
+% ./main | head -n 1
+hello world
+thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1016:9
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+```
diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py
deleted file mode 100644
index 343dd0387..000000000
--- a/src/etc/check_missing_items.py
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/env python
-
-# This test ensures that every ID in the produced json actually resolves to an item either in
-# `index` or `paths`. It DOES NOT check that the structure of the produced json is actually in
-# any way correct, for example an empty map would pass.
-
-# FIXME: Better error output
-
-import sys
-import json
-
-crate = json.load(open(sys.argv[1], encoding="utf-8"))
-
-
-def get_local_item(item_id):
- if item_id in crate["index"]:
- return crate["index"][item_id]
- print("Missing local ID:", item_id)
- sys.exit(1)
-
-
-# local IDs have to be in `index`, external ones can sometimes be in `index` but otherwise have
-# to be in `paths`
-def valid_id(item_id):
- return item_id in crate["index"] or item_id[0] != "0" and item_id in crate["paths"]
-
-
-def check_generics(generics):
- for param in generics["params"]:
- check_generic_param(param)
- for where_predicate in generics["where_predicates"]:
- if "bound_predicate" in where_predicate:
- pred = where_predicate["bound_predicate"]
- check_type(pred["type"])
- for bound in pred["bounds"]:
- check_generic_bound(bound)
- elif "region_predicate" in where_predicate:
- pred = where_predicate["region_predicate"]
- for bound in pred["bounds"]:
- check_generic_bound(bound)
- elif "eq_predicate" in where_predicate:
- pred = where_predicate["eq_predicate"]
- check_type(pred["rhs"])
- check_type(pred["lhs"])
-
-
-def check_generic_param(param):
- if "type" in param["kind"]:
- ty = param["kind"]["type"]
- if ty["default"]:
- check_type(ty["default"])
- elif "const" in param["kind"]:
- check_type(param["kind"]["const"])
-
-
-def check_generic_bound(bound):
- if "trait_bound" in bound:
- for param in bound["trait_bound"]["generic_params"]:
- check_generic_param(param)
- check_type(bound["trait_bound"]["trait"])
-
-
-def check_decl(decl):
- for (_name, ty) in decl["inputs"]:
- check_type(ty)
- if decl["output"]:
- check_type(decl["output"])
-
-
-def check_type(ty):
- if ty["kind"] == "resolved_path":
- for bound in ty["inner"]["param_names"]:
- check_generic_bound(bound)
- args = ty["inner"]["args"]
- if args:
- if "angle_bracketed" in args:
- for arg in args["angle_bracketed"]["args"]:
- if "type" in arg:
- check_type(arg["type"])
- elif "const" in arg:
- check_type(arg["const"]["type"])
- for binding in args["angle_bracketed"]["bindings"]:
- if "equality" in binding["binding"]:
- term = binding["binding"]["equality"]
- if "type" in term: check_type(term["type"])
- elif "const" in term: check_type(term["const"])
- elif "constraint" in binding["binding"]:
- for bound in binding["binding"]["constraint"]:
- check_generic_bound(bound)
- elif "parenthesized" in args:
- for ty in args["parenthesized"]["inputs"]:
- check_type(ty)
- if args["parenthesized"]["output"]:
- check_type(args["parenthesized"]["output"])
- if not valid_id(ty["inner"]["id"]):
- print("Type contained an invalid ID:", ty["inner"]["id"])
- sys.exit(1)
- elif ty["kind"] == "tuple":
- for ty in ty["inner"]:
- check_type(ty)
- elif ty["kind"] == "slice":
- check_type(ty["inner"])
- elif ty["kind"] == "impl_trait":
- for bound in ty["inner"]:
- check_generic_bound(bound)
- elif ty["kind"] in ("raw_pointer", "borrowed_ref", "array"):
- check_type(ty["inner"]["type"])
- elif ty["kind"] == "function_pointer":
- for param in ty["inner"]["generic_params"]:
- check_generic_param(param)
- check_decl(ty["inner"]["decl"])
- elif ty["kind"] == "qualified_path":
- check_type(ty["inner"]["self_type"])
- check_type(ty["inner"]["trait"])
-
-
-work_list = set([crate["root"]])
-visited = work_list.copy()
-
-while work_list:
- current = work_list.pop()
- visited.add(current)
- item = get_local_item(current)
- # check intradoc links
- for (_name, link) in item["links"].items():
- if not valid_id(link):
- print("Intra-doc link contains invalid ID:", link)
-
- # check all fields that reference types such as generics as well as nested items
- # (modules, structs, traits, and enums)
- if item["kind"] == "module":
- work_list |= set(item["inner"]["items"]) - visited
- elif item["kind"] == "struct":
- check_generics(item["inner"]["generics"])
- work_list |= (
- set(item["inner"]["fields"]) | set(item["inner"]["impls"])
- ) - visited
- elif item["kind"] == "struct_field":
- check_type(item["inner"])
- elif item["kind"] == "enum":
- check_generics(item["inner"]["generics"])
- work_list |= (
- set(item["inner"]["variants"]) | set(item["inner"]["impls"])
- ) - visited
- elif item["kind"] == "variant":
- if item["inner"]["variant_kind"] == "tuple":
- for ty in item["inner"]["variant_inner"]:
- check_type(ty)
- elif item["inner"]["variant_kind"] == "struct":
- work_list |= set(item["inner"]["variant_inner"]) - visited
- elif item["kind"] in ("function", "method"):
- check_generics(item["inner"]["generics"])
- check_decl(item["inner"]["decl"])
- elif item["kind"] in ("static", "constant", "assoc_const"):
- check_type(item["inner"]["type"])
- elif item["kind"] == "typedef":
- check_type(item["inner"]["type"])
- check_generics(item["inner"]["generics"])
- elif item["kind"] == "opaque_ty":
- check_generics(item["inner"]["generics"])
- for bound in item["inner"]["bounds"]:
- check_generic_bound(bound)
- elif item["kind"] == "trait_alias":
- check_generics(item["inner"]["params"])
- for bound in item["inner"]["bounds"]:
- check_generic_bound(bound)
- elif item["kind"] == "trait":
- check_generics(item["inner"]["generics"])
- for bound in item["inner"]["bounds"]:
- check_generic_bound(bound)
- work_list |= (
- set(item["inner"]["items"]) | set(item["inner"]["implementations"])
- ) - visited
- elif item["kind"] == "impl":
- check_generics(item["inner"]["generics"])
- if item["inner"]["trait"]:
- check_type(item["inner"]["trait"])
- if item["inner"]["blanket_impl"]:
- check_type(item["inner"]["blanket_impl"])
- check_type(item["inner"]["for"])
- for assoc_item in item["inner"]["items"]:
- if not valid_id(assoc_item):
- print("Impl block referenced a missing ID:", assoc_item)
- sys.exit(1)
- elif item["kind"] == "assoc_type":
- for bound in item["inner"]["bounds"]:
- check_generic_bound(bound)
- if item["inner"]["default"]:
- check_type(item["inner"]["default"])
diff --git a/src/etc/cpu-usage-over-time-plot.sh b/src/etc/cpu-usage-over-time-plot.sh
index 1c3425591..2617378ba 100755
--- a/src/etc/cpu-usage-over-time-plot.sh
+++ b/src/etc/cpu-usage-over-time-plot.sh
@@ -15,7 +15,7 @@
# Improvements to this script are greatly appreciated!
if [[ $# != 2 ]]; then
- echo "expected 2 arguments, recieved $#"
+ echo "expected 2 arguments, received $#"
echo "example usage: './src/etc/cpu-usage-over-time-plot.sh \
7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c \
x86_64-gnu'"
diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py
index 292e91b4d..8171cb4e9 100644
--- a/src/etc/gdb_lookup.py
+++ b/src/etc/gdb_lookup.py
@@ -89,4 +89,7 @@ def lookup(valobj):
if rust_type == RustType.STD_REF_CELL:
return StdRefCellProvider(valobj)
+ if rust_type == RustType.STD_NONZERO_NUMBER:
+ return StdNonZeroNumberProvider(valobj)
+
return None
diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py
index 0a52b8c97..c351c3450 100644
--- a/src/etc/gdb_providers.py
+++ b/src/etc/gdb_providers.py
@@ -231,6 +231,17 @@ class StdRefCellProvider:
yield "borrow", self.borrow
+class StdNonZeroNumberProvider:
+ def __init__(self, valobj):
+ fields = valobj.type.fields()
+ assert len(fields) == 1
+ field = list(fields)[0]
+ self.value = str(valobj[field.name])
+
+ def to_string(self):
+ return self.value
+
+
# Yields children (in a provider's sense of the word) for a BTreeMap.
def children_of_btree_map(map):
# Yields each key/value pair in the node and in any child nodes.
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index d02ac9d9c..c97fb4b80 100644
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -41,15 +41,15 @@ There are a number of supported commands:
`PATH` is relative to the output directory. It can be given as `-`
which repeats the most recently used `PATH`.
-* `@has PATH PATTERN` and `@matches PATH PATTERN` checks for
- the occurrence of the given pattern `PATTERN` in the specified file.
+* `@hasraw PATH PATTERN` and `@matchesraw PATH PATTERN` checks
+ for the occurrence of the given pattern `PATTERN` in the specified file.
Only one occurrence of the pattern is enough.
- For `@has`, `PATTERN` is a whitespace-normalized (every consecutive
+ For `@hasraw`, `PATTERN` is a whitespace-normalized (every consecutive
whitespace being replaced by one single space character) string.
The entire file is also whitespace-normalized including newlines.
- For `@matches`, `PATTERN` is a Python-supported regular expression.
+ For `@matchesraw`, `PATTERN` is a Python-supported regular expression.
The file remains intact but the regexp is matched without the `MULTILINE`
and `IGNORECASE` options. You can still use a prefix `(?m)` or `(?i)`
to override them, and `\A` and `\Z` for definitely matching
@@ -386,7 +386,7 @@ def check_tree_attr(tree, path, attr, pat, regexp):
return ret
-# Returns the number of occurences matching the regex (`regexp`) and the text (`pat`).
+# Returns the number of occurrences matching the regex (`regexp`) and the text (`pat`).
def check_tree_text(tree, path, pat, regexp, stop_at_first):
path = normalize_xpath(path)
match_count = 0
@@ -542,19 +542,23 @@ ERR_COUNT = 0
def check_command(c, cache):
try:
cerr = ""
- if c.cmd == 'has' or c.cmd == 'matches': # string test
- regexp = (c.cmd == 'matches')
- if len(c.args) == 1 and not regexp: # @has <path> = file existence
+ if c.cmd in ['has', 'hasraw', 'matches', 'matchesraw']: # string test
+ regexp = c.cmd.startswith('matches')
+
+ # @has <path> = file existence
+ if len(c.args) == 1 and not regexp and 'raw' not in c.cmd:
try:
cache.get_file(c.args[0])
ret = True
except FailedCheck as err:
cerr = str(err)
ret = False
- elif len(c.args) == 2: # @has/matches <path> <pat> = string test
+ # @hasraw/matchesraw <path> <pat> = string test
+ elif len(c.args) == 2 and 'raw' in c.cmd:
cerr = "`PATTERN` did not match"
ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp)
- elif len(c.args) == 3: # @has/matches <path> <pat> <match> = XML tree test
+ # @has/matches <path> <pat> <match> = XML tree test
+ elif len(c.args) == 3 and 'raw' not in c.cmd:
cerr = "`XPATH PATTERN` did not match"
ret = get_nb_matching_elements(cache, c, regexp, True) != 0
else:
diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs
index a182bc406..0aa0784e5 100644
--- a/src/etc/installer/msi/rust.wxs
+++ b/src/etc/installer/msi/rust.wxs
@@ -170,10 +170,6 @@
<Directory Id="Docs" Name="." />
<Directory Id="Cargo" Name="." />
<Directory Id="Std" Name="." />
- <!-- tool-rls-start -->
- <Directory Id="Rls" Name="." />
- <Directory Id="Analysis" Name="." />
- <!-- tool-rls-end -->
</Directory>
</Directory>
@@ -277,16 +273,6 @@
<ComponentRef Id="PathEnvPerMachine" />
<ComponentRef Id="PathEnvPerUser" />
</Feature>
- <!-- tool-rls-start -->
- <Feature Id="RLS"
- Title="RLS, the Rust Language Server"
- Display="7"
- Level="2"
- AllowAdvertise="no">
- <ComponentGroupRef Id="RlsGroup" />
- <ComponentGroupRef Id="AnalysisGroup" />
- </Feature>
- <!-- tool-rls-end -->
<UIRef Id="RustUI" />
</Product>
diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml
index 077ee1751..64f6bab9b 100644
--- a/src/etc/installer/pkg/Distribution.xml
+++ b/src/etc/installer/pkg/Distribution.xml
@@ -16,9 +16,6 @@
<line choice="rust-std"/>
<line choice="cargo"/>
<line choice="rust-docs"/>
- <!-- tool-rls-start -->
- <line choice="rls"/>
- <!-- tool-rls-end -->
</line>
<line choice="uninstall" />
</choices-outline>
@@ -64,24 +61,10 @@
>
<pkg-ref id="org.rust-lang.rust-docs"/>
</choice>
- <!-- tool-rls-start -->
- <choice id="rls" visible="true"
- title="RLS" description="RLS, the Rust Language Server"
- selected="(!choices.uninstall.selected &amp;&amp; choices['rls'].selected) || (choices.uninstall.selected &amp;&amp; choices.install.selected)"
- start_selected="false"
- >
- <pkg-ref id="org.rust-lang.rls"/>
- <pkg-ref id="org.rust-lang.rust-analysis"/>
- </choice>
- <!-- tool-rls-end -->
<pkg-ref id="org.rust-lang.rustc" version="0" onConclusion="none">rustc.pkg</pkg-ref>
<pkg-ref id="org.rust-lang.cargo" version="0" onConclusion="none">cargo.pkg</pkg-ref>
<pkg-ref id="org.rust-lang.rust-docs" version="0" onConclusion="none">rust-docs.pkg</pkg-ref>
<pkg-ref id="org.rust-lang.rust-std" version="0" onConclusion="none">rust-std.pkg</pkg-ref>
- <!-- tool-rls-start -->
- <pkg-ref id="org.rust-lang.rls" version="0" onConclusion="none">rls.pkg</pkg-ref>
- <!-- tool-rls-end -->
- <pkg-ref id="org.rust-lang.rust-analysis" version="0" onConclusion="none">rust-analysis.pkg</pkg-ref>
<pkg-ref id="org.rust-lang.uninstall" version="0" onConclusion="none">uninstall.pkg</pkg-ref>
<background file="rust-logo.png" mime-type="image/png"
alignment="bottomleft"/>
diff --git a/src/etc/lldb_commands b/src/etc/lldb_commands
index 4a1204ccc..ed66ecf30 100644
--- a/src/etc/lldb_commands
+++ b/src/etc/lldb_commands
@@ -15,4 +15,5 @@ type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)C
type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Ref<.+>$" --category Rust
type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust
type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust
+type summary add -F lldb_lookup.summary_lookup -e -x -h "^core::num::([a-z_]+::)*NonZero.+$" --category Rust
type category enable Rust
diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py
index 3cee51982..bca9c2ae1 100644
--- a/src/etc/lldb_lookup.py
+++ b/src/etc/lldb_lookup.py
@@ -55,6 +55,9 @@ def summary_lookup(valobj, dict):
if rust_type == RustType.STD_REF_CELL:
return StdRefSummaryProvider(valobj, dict)
+ if rust_type == RustType.STD_NONZERO_NUMBER:
+ return StdNonZeroNumberSummaryProvider(valobj, dict)
+
return ""
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index 35ac07f0d..8a9927e7d 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -739,3 +739,11 @@ class StdRefSyntheticProvider:
def has_children(self):
# type: () -> bool
return True
+
+
+def StdNonZeroNumberSummaryProvider(valobj, _dict):
+ # type: (SBValue, dict) -> str
+ objtype = valobj.GetType()
+ field = objtype.GetFieldAtIndex(0)
+ element = valobj.GetChildMemberWithName(field.name)
+ return element.GetValue()
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 558536fa6..277e57aaf 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="str">
<DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
@@ -150,76 +150,189 @@
</Expand>
</Type>
- <!-- Directly tagged enums. $T1 is the type name -->
- <Type Name="enum$&lt;*&gt;">
- <Intrinsic Name="tag" Expression="discriminant" />
- <DisplayString Condition="tag() == 0">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 1" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 2" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 3" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 4" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 5" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 6" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 7" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 8" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 9" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 10" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 11" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 12" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 13" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 14" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 15" Optional="true">{tag(),en}</DisplayString>
+ <!--
+ This is the visualizer for all enums. It takes care of selecting the active variant.
+ See `compiler\rustc_codegen_llvm\src\debuginfo\metadata\enums\cpp_like.rs` for more information.
+ -->
+ <Type Name="enum2$&lt;*&gt;">
+ <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+ have to do a different check -->
+ <Intrinsic Name="in_range" Expression="(begin &lt;= end) ? ((x &gt;= begin) &amp;&amp; (x &lt;= end)) : ((x &gt;= begin) || (x &lt;= end))">
+ <Parameter Name="x" Type="unsigned __int64" />
+ <Parameter Name="begin" Type="unsigned __int64" />
+ <Parameter Name="end" Type="unsigned __int64" />
+ </Intrinsic>
- <Expand>
- <Synthetic Name="[variant]">
- <DisplayString>{tag(),en}</DisplayString>
- </Synthetic>
- <ExpandedItem Condition="tag() == 0">variant0</ExpandedItem>
- <ExpandedItem Condition="tag() == 1" Optional="true">variant1</ExpandedItem>
- <ExpandedItem Condition="tag() == 2" Optional="true">variant2</ExpandedItem>
- <ExpandedItem Condition="tag() == 3" Optional="true">variant3</ExpandedItem>
- <ExpandedItem Condition="tag() == 4" Optional="true">variant4</ExpandedItem>
- <ExpandedItem Condition="tag() == 5" Optional="true">variant5</ExpandedItem>
- <ExpandedItem Condition="tag() == 6" Optional="true">variant6</ExpandedItem>
- <ExpandedItem Condition="tag() == 7" Optional="true">variant7</ExpandedItem>
- <ExpandedItem Condition="tag() == 8" Optional="true">variant8</ExpandedItem>
- <ExpandedItem Condition="tag() == 9" Optional="true">variant9</ExpandedItem>
- <ExpandedItem Condition="tag() == 10" Optional="true">variant10</ExpandedItem>
- <ExpandedItem Condition="tag() == 11" Optional="true">variant11</ExpandedItem>
- <ExpandedItem Condition="tag() == 12" Optional="true">variant12</ExpandedItem>
- <ExpandedItem Condition="tag() == 13" Optional="true">variant13</ExpandedItem>
- <ExpandedItem Condition="tag() == 14" Optional="true">variant14</ExpandedItem>
- <ExpandedItem Condition="tag() == 15" Optional="true">variant15</ExpandedItem>
- </Expand>
- </Type>
+ <Intrinsic Name="eq128" Expression="(x_hi == y_hi) &amp;&amp; (x_lo == y_lo)">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="y_hi" Type="unsigned __int64" />
+ <Parameter Name="y_lo" Type="unsigned __int64" />
+ </Intrinsic>
- <!-- Single variant enums. $T1 is the name of the enum, $T2 is the name of the variant -->
- <Type Name="enum$&lt;*, *&gt;">
- <DisplayString>{"$T2",sb}</DisplayString>
- <Expand>
- <Synthetic Name="[variant]">
- <DisplayString>{"$T2",sb}</DisplayString>
- </Synthetic>
- <ExpandedItem>$T2</ExpandedItem>
- </Expand>
- </Type>
+ <Intrinsic Name="lt128" Expression="(x_hi &lt; y_hi) || ((x_hi == y_hi) &amp;&amp; (x_lo &lt; y_lo))">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="y_hi" Type="unsigned __int64" />
+ <Parameter Name="y_lo" Type="unsigned __int64" />
+ </Intrinsic>
- <!-- Niche-layout enums. $T1 is the name of the enum, $T2 is the low value of the dataful
- variant tag, $T3 is the high value of the dataful variant tag, $T4 is the name of
- the dataful variant -->
- <Type Name="enum$&lt;*, *, *, *&gt;">
- <Intrinsic Name="tag" Expression="discriminant" />
- <Intrinsic Name="is_dataful" Expression="tag() &gt;= $T2 &amp;&amp; tag() &lt;= $T3" />
- <DisplayString Condition="is_dataful()">{"$T4",sb}({dataful_variant})</DisplayString>
- <DisplayString Condition="!is_dataful()">{discriminant,en}</DisplayString>
- <Expand>
- <ExpandedItem Condition="is_dataful()">dataful_variant</ExpandedItem>
- <Synthetic Condition="is_dataful()" Name="[variant]">
- <DisplayString>{"$T4",sb}</DisplayString>
- </Synthetic>
- <Synthetic Condition="!is_dataful()" Name="[variant]">
- <DisplayString>{discriminant,en}</DisplayString>
- </Synthetic>
+ <Intrinsic Name="lt_or_eq128" Expression="((x_hi == y_hi) &amp;&amp; (x_lo == y_lo)) || lt128(x_hi, x_lo, y_hi, y_lo)">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="y_hi" Type="unsigned __int64" />
+ <Parameter Name="y_lo" Type="unsigned __int64" />
+ </Intrinsic>
+
+ <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+ have to do a different check -->
+ <Intrinsic Name="in_range128" Expression="(lt_or_eq128(begin_hi, begin_lo, end_hi, end_lo)) ?
+ (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) &amp;&amp; lt_or_eq128(x_hi, x_lo, end_hi, end_lo)) :
+ (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) || lt_or_eq128(x_hi, x_lo, end_hi, end_lo))">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="begin_hi" Type="unsigned __int64" />
+ <Parameter Name="begin_lo" Type="unsigned __int64" />
+ <Parameter Name="end_hi" Type="unsigned __int64" />
+ <Parameter Name="end_lo" Type="unsigned __int64" />
+ </Intrinsic>
+
+ <DisplayString Condition="tag == variant0.DISCR_EXACT" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant1.DISCR_EXACT" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant2.DISCR_EXACT" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant3.DISCR_EXACT" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant4.DISCR_EXACT" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant5.DISCR_EXACT" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant6.DISCR_EXACT" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant7.DISCR_EXACT" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant8.DISCR_EXACT" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant9.DISCR_EXACT" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant10.DISCR_EXACT" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant11.DISCR_EXACT" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant12.DISCR_EXACT" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant13.DISCR_EXACT" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant14.DISCR_EXACT" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant15.DISCR_EXACT" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <DisplayString Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <Expand HideRawView="true">
+ <ExpandedItem Condition="tag == variant0.DISCR_EXACT" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant1.DISCR_EXACT" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant2.DISCR_EXACT" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant3.DISCR_EXACT" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant4.DISCR_EXACT" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant5.DISCR_EXACT" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant6.DISCR_EXACT" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant7.DISCR_EXACT" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant8.DISCR_EXACT" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant9.DISCR_EXACT" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant10.DISCR_EXACT" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant11.DISCR_EXACT" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant12.DISCR_EXACT" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant13.DISCR_EXACT" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant14.DISCR_EXACT" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant15.DISCR_EXACT" Optional="true">variant15.value</ExpandedItem>
+
+ <ExpandedItem Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">variant15.value</ExpandedItem>
+
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">variant15.value</ExpandedItem>
+
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">variant15.value</ExpandedItem>
</Expand>
</Type>
</AutoVisualizer>
diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis
index 912418fa7..bf6c02b91 100644
--- a/src/etc/natvis/liballoc.natvis
+++ b/src/etc/natvis/liballoc.natvis
@@ -185,12 +185,4 @@
</ArrayItems>
</Expand>
</Type>
-
- <Type Name="alloc::borrow::Cow&lt;*&gt;">
- <DisplayString Condition="RUST$ENUM$DISR == 0x0">Borrowed({__0})</DisplayString>
- <DisplayString Condition="RUST$ENUM$DISR == 0x1">Owned({__0})</DisplayString>
- <Expand>
- <Item Name="[value]" ExcludeView="simple">__0</Item>
- </Expand>
- </Type>
</AutoVisualizer>
diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh
index 5f5b48bc1..be7de3eba 100755
--- a/src/etc/pre-push.sh
+++ b/src/etc/pre-push.sh
@@ -10,7 +10,7 @@ set -Eeuo pipefail
# https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570
unset GIT_DIR
ROOT_DIR="$(git rev-parse --show-toplevel)"
-COMMAND="$ROOT_DIR/x.py test tidy --bless"
+COMMAND="$ROOT_DIR/x.py test tidy"
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
COMMAND="python $COMMAND"
diff --git a/src/etc/rust_types.py b/src/etc/rust_types.py
index bbc945a7d..bf512bc99 100644
--- a/src/etc/rust_types.py
+++ b/src/etc/rust_types.py
@@ -31,6 +31,7 @@ class RustType(object):
STD_REF = "StdRef"
STD_REF_MUT = "StdRefMut"
STD_REF_CELL = "StdRefCell"
+ STD_NONZERO_NUMBER = "StdNonZeroNumber"
STD_STRING_REGEX = re.compile(r"^(alloc::(\w+::)+)String$")
@@ -49,6 +50,7 @@ STD_CELL_REGEX = re.compile(r"^(core::(\w+::)+)Cell<.+>$")
STD_REF_REGEX = re.compile(r"^(core::(\w+::)+)Ref<.+>$")
STD_REF_MUT_REGEX = re.compile(r"^(core::(\w+::)+)RefMut<.+>$")
STD_REF_CELL_REGEX = re.compile(r"^(core::(\w+::)+)RefCell<.+>$")
+STD_NONZERO_NUMBER_REGEX = re.compile(r"^core::num::([a-z_]+::)*NonZero.+$")
TUPLE_ITEM_REGEX = re.compile(r"__\d+$")
@@ -72,6 +74,7 @@ STD_TYPE_TO_REGEX = {
RustType.STD_REF_MUT: STD_REF_MUT_REGEX,
RustType.STD_REF_CELL: STD_REF_CELL_REGEX,
RustType.STD_CELL: STD_CELL_REGEX,
+ RustType.STD_NONZERO_NUMBER: STD_NONZERO_NUMBER_REGEX,
}
def is_tuple_fields(fields):
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index ddaa7438e..7bc35c7d5 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -10,18 +10,19 @@ path = "lib.rs"
arrayvec = { version = "0.7", default-features = false }
askama = { version = "0.11", default-features = false, features = ["config"] }
atty = "0.2"
+itertools = "0.10.1"
+minifier = "0.2.2"
+once_cell = "1.10.0"
pulldown-cmark = { version = "0.9.2", default-features = false }
-minifier = "0.2.1"
-serde = { version = "1.0", features = ["derive"] }
+regex = "1"
+rustdoc-json-types = { path = "../rustdoc-json-types" }
serde_json = "1.0"
+serde = { version = "1.0", features = ["derive"] }
smallvec = "1.8.1"
tempfile = "3"
-itertools = "0.10.1"
-regex = "1"
-rustdoc-json-types = { path = "../rustdoc-json-types" }
+thin-vec = "0.2.8"
tracing = "0.1"
tracing-tree = "0.2.0"
-once_cell = "1.10.0"
[dependencies.tracing-subscriber]
version = "0.3.3"
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index af33c1a6a..175472797 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -123,7 +123,7 @@ where
kind: Box::new(ImplItem(Box::new(Impl {
unsafety: hir::Unsafety::Normal,
generics: new_generics,
- trait_: Some(clean_trait_ref_with_bindings(self.cx, trait_ref, &[])),
+ trait_: Some(clean_trait_ref_with_bindings(self.cx, trait_ref, ThinVec::new())),
for_: clean_middle_ty(ty, self.cx, None),
items: Vec::new(),
polarity,
@@ -476,7 +476,7 @@ where
let mut ty_to_fn: FxHashMap<Type, (PolyTrait, Option<Type>)> = Default::default();
for p in clean_where_predicates {
- let (orig_p, p) = (p, p.clean(self.cx));
+ let (orig_p, p) = (p, clean_predicate(p, self.cx));
if p.is_none() {
continue;
}
@@ -525,8 +525,8 @@ where
GenericBound::TraitBound(ref mut p, _) => {
// Insert regions into the for_generics hash map first, to ensure
// that we don't end up with duplicate bounds (e.g., for<'b, 'b>)
- for_generics.extend(p.generic_params.clone());
- p.generic_params = for_generics.into_iter().collect();
+ for_generics.extend(p.generic_params.drain(..));
+ p.generic_params.extend(for_generics);
self.is_fn_trait(&p.trait_)
}
_ => false,
@@ -551,13 +551,15 @@ where
}
WherePredicate::EqPredicate { lhs, rhs } => {
match lhs {
- Type::QPath { ref assoc, ref self_type, ref trait_, .. } => {
+ Type::QPath(box QPathData {
+ ref assoc, ref self_type, ref trait_, ..
+ }) => {
let ty = &*self_type;
let mut new_trait = trait_.clone();
if self.is_fn_trait(trait_) && assoc.name == sym::Output {
ty_to_fn
- .entry(*ty.clone())
+ .entry(ty.clone())
.and_modify(|e| {
*e = (e.0.clone(), Some(rhs.ty().unwrap().clone()))
})
@@ -582,7 +584,7 @@ where
// to 'T: Iterator<Item=u8>'
GenericArgs::AngleBracketed { ref mut bindings, .. } => {
bindings.push(TypeBinding {
- assoc: *assoc.clone(),
+ assoc: assoc.clone(),
kind: TypeBindingKind::Equality { term: rhs },
});
}
@@ -596,7 +598,7 @@ where
}
}
- let bounds = ty_to_bounds.entry(*ty.clone()).or_default();
+ let bounds = ty_to_bounds.entry(ty.clone()).or_default();
bounds.insert(GenericBound::TraitBound(
PolyTrait { trait_: new_trait, generic_params: Vec::new() },
@@ -613,7 +615,7 @@ where
));
// Avoid creating any new duplicate bounds later in the outer
// loop
- ty_to_traits.entry(*ty.clone()).or_default().insert(trait_.clone());
+ ty_to_traits.entry(ty.clone()).or_default().insert(trait_.clone());
}
_ => panic!("Unexpected LHS {:?} for {:?}", lhs, item_def_id),
}
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 01dd95e6e..cc734389e 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -115,12 +115,12 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
),
// FIXME(eddyb) compute both `trait_` and `for_` from
// the post-inference `trait_ref`, as it's more accurate.
- trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref.0, &[])),
+ trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref.0, ThinVec::new())),
for_: clean_middle_ty(ty.0, cx, None),
items: cx.tcx
.associated_items(impl_def_id)
.in_definition_order()
- .map(|x| x.clean(cx))
+ .map(|x| clean_middle_assoc_item(x, cx))
.collect::<Vec<_>>(),
polarity: ty::ImplPolarity::Positive,
kind: ImplKind::Blanket(Box::new(clean_middle_ty(trait_ref.0.self_ty(), cx, None))),
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 58d0aedb0..df0e9f7cc 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -3,9 +3,10 @@
use std::iter::once;
use std::sync::Arc;
+use thin_vec::ThinVec;
+
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::thin_vec::ThinVec;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
@@ -16,15 +17,14 @@ use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
use crate::clean::{
- self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty,
- clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def,
- clean_visibility, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, Type, Visibility,
+ self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item,
+ clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty,
+ clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
+ ImplKind, ItemId, Type, Visibility,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
-type Attrs<'hir> = &'hir [ast::Attribute];
-
/// Attempt to inline a definition into this AST.
///
/// This function will fetch the definition specified, and if it is
@@ -45,7 +45,7 @@ pub(crate) fn try_inline(
import_def_id: Option<DefId>,
res: Res,
name: Symbol,
- attrs: Option<Attrs<'_>>,
+ attrs: Option<&[ast::Attribute]>,
visited: &mut FxHashSet<DefId>,
) -> Option<Vec<clean::Item>> {
let did = res.opt_def_id()?;
@@ -61,7 +61,7 @@ pub(crate) fn try_inline(
Res::Def(DefKind::Trait, did) => {
record_extern_fqn(cx, did, ItemType::Trait);
build_impls(cx, Some(parent_module), did, attrs, &mut ret);
- clean::TraitItem(build_external_trait(cx, did))
+ clean::TraitItem(Box::new(build_external_trait(cx, did)))
}
Res::Def(DefKind::Fn, did) => {
record_extern_fqn(cx, did, ItemType::Function);
@@ -171,7 +171,7 @@ pub(crate) fn try_inline_glob(
}
}
-pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> {
+pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast::Attribute] {
cx.tcx.get_attrs_unchecked(did)
}
@@ -217,7 +217,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
// which causes methods to have a `pub` prefix, which is invalid since items in traits
// can not have a visibility prefix. Thus we override the visibility here manually.
// See https://github.com/rust-lang/rust/issues/81274
- clean::Item { visibility: Visibility::Inherited, ..item.clean(cx) }
+ clean::Item { visibility: Visibility::Inherited, ..clean_middle_assoc_item(item, cx) }
})
.collect();
@@ -286,7 +286,7 @@ pub(crate) fn build_impls(
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
did: DefId,
- attrs: Option<Attrs<'_>>,
+ attrs: Option<&[ast::Attribute]>,
ret: &mut Vec<clean::Item>,
) {
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls");
@@ -296,14 +296,29 @@ pub(crate) fn build_impls(
for &did in tcx.inherent_impls(did).iter() {
build_impl(cx, parent_module, did, attrs, ret);
}
+
+ // This pretty much exists expressly for `dyn Error` traits that exist in the `alloc` crate.
+ // See also:
+ //
+ // * https://github.com/rust-lang/rust/issues/103170 — where it didn't used to get documented
+ // * https://github.com/rust-lang/rust/pull/99917 — where the feature got used
+ // * https://github.com/rust-lang/rust/issues/53487 — overall tracking issue for Error
+ if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
+ use rustc_middle::ty::fast_reject::SimplifiedTypeGen::*;
+ let type_ =
+ if tcx.is_trait(did) { TraitSimplifiedType(did) } else { AdtSimplifiedType(did) };
+ for &did in tcx.incoherent_impls(type_) {
+ build_impl(cx, parent_module, did, attrs, ret);
+ }
+ }
}
/// `parent_module` refers to the parent of the re-export, not the original item
-fn merge_attrs(
+pub(crate) fn merge_attrs(
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
- old_attrs: Attrs<'_>,
- new_attrs: Option<Attrs<'_>>,
+ old_attrs: &[ast::Attribute],
+ new_attrs: Option<&[ast::Attribute]>,
) -> (clean::Attributes, Option<Arc<clean::cfg::Cfg>>) {
// NOTE: If we have additional attributes (from a re-export),
// always insert them first. This ensure that re-export
@@ -330,7 +345,7 @@ pub(crate) fn build_impl(
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
did: DefId,
- attrs: Option<Attrs<'_>>,
+ attrs: Option<&[ast::Attribute]>,
ret: &mut Vec<clean::Item>,
) {
if !cx.inlined.insert(did.into()) {
@@ -426,9 +441,9 @@ pub(crate) fn build_impl(
true
}
})
- .map(|item| item.clean(cx))
+ .map(|item| clean_impl_item(item, cx))
.collect::<Vec<_>>(),
- impl_.generics.clean(cx),
+ clean_generics(impl_.generics, cx),
),
None => (
tcx.associated_items(did)
@@ -452,7 +467,7 @@ pub(crate) fn build_impl(
item.visibility(tcx).is_public()
}
})
- .map(|item| item.clean(cx))
+ .map(|item| clean_middle_assoc_item(item, cx))
.collect::<Vec<_>>(),
clean::enter_impl_trait(cx, |cx| {
clean_ty_generics(cx, tcx.generics_of(did), predicates)
@@ -460,7 +475,7 @@ pub(crate) fn build_impl(
),
};
let polarity = tcx.impl_polarity(did);
- let trait_ = associated_trait.map(|t| clean_trait_ref_with_bindings(cx, t, &[]));
+ let trait_ = associated_trait.map(|t| clean_trait_ref_with_bindings(cx, t, ThinVec::new()));
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
super::build_deref_target_impls(cx, &trait_items, ret);
}
@@ -671,7 +686,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
g.where_predicates.retain(|pred| match pred {
clean::WherePredicate::BoundPredicate {
- ty: clean::QPath { self_type: box clean::Generic(ref s), trait_, .. },
+ ty: clean::QPath(box clean::QPathData { self_type: clean::Generic(ref s), trait_, .. }),
bounds,
..
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 929f5f89b..c8875c272 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -33,7 +33,8 @@ use std::collections::hash_map::Entry;
use std::collections::BTreeMap;
use std::default::Default;
use std::hash::Hash;
-use std::{mem, vec};
+use std::mem;
+use thin_vec::ThinVec;
use crate::core::{self, DocContext, ImplTraitParam};
use crate::formats::item_type::ItemType;
@@ -44,128 +45,126 @@ use utils::*;
pub(crate) use self::types::*;
pub(crate) use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res};
-pub(crate) trait Clean<'tcx, T> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> T;
-}
+pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
+ let mut items: Vec<Item> = vec![];
+ let mut inserted = FxHashSet::default();
+ items.extend(doc.foreigns.iter().map(|(item, renamed)| {
+ let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
+ if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
+ inserted.insert((item.type_(), name));
+ }
+ item
+ }));
+ items.extend(doc.mods.iter().filter_map(|x| {
+ if !inserted.insert((ItemType::Module, x.name)) {
+ return None;
+ }
+ let item = clean_doc_module(x, cx);
+ if item.attrs.lists(sym::doc).has_word(sym::hidden) {
+ // Hidden modules are stripped at a later stage.
+ // If a hidden module has the same name as a visible one, we want
+ // to keep both of them around.
+ inserted.remove(&(ItemType::Module, x.name));
+ }
+ Some(item)
+ }));
-impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
- let mut items: Vec<Item> = vec![];
- 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 {
+ // 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(doc.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 && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
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.
-
- let span = Span::new({
- let where_outer = self.where_outer(cx.tcx);
- let sm = cx.sess().source_map();
- let outer = sm.lookup_char_pos(where_outer.lo());
- let inner = sm.lookup_char_pos(self.where_inner.lo());
- if outer.file.start_pos == inner.file.start_pos {
- // mod foo { ... }
- where_outer
- } else {
- // mod foo; (and a separate SourceFile for the contents)
- self.where_inner
- }
- });
+ }
+ v
+ }));
+ items.extend(doc.items.iter().flat_map(|(item, renamed)| {
+ // Now we actually lower the imports, skipping everything else.
+ if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
+ let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
+ 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.
+
+ let span = Span::new({
+ let where_outer = doc.where_outer(cx.tcx);
+ let sm = cx.sess().source_map();
+ let outer = sm.lookup_char_pos(where_outer.lo());
+ let inner = sm.lookup_char_pos(doc.where_inner.lo());
+ if outer.file.start_pos == inner.file.start_pos {
+ // mod foo { ... }
+ where_outer
+ } else {
+ // mod foo; (and a separate SourceFile for the contents)
+ doc.where_inner
+ }
+ });
- Item::from_hir_id_and_parts(
- self.id,
- Some(self.name),
- ModuleItem(Module { items, span }),
- cx,
- )
- }
+ Item::from_hir_id_and_parts(doc.id, Some(doc.name), ModuleItem(Module { items, span }), cx)
}
-impl<'tcx> Clean<'tcx, Option<GenericBound>> for hir::GenericBound<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> Option<GenericBound> {
- Some(match *self {
- hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
- hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
- let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
-
- let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder();
-
- let generic_args = generic_args.clean(cx);
- let GenericArgs::AngleBracketed { bindings, .. } = generic_args
- else {
- bug!("clean: parenthesized `GenericBound::LangItemTrait`");
- };
+fn clean_generic_bound<'tcx>(
+ bound: &hir::GenericBound<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> Option<GenericBound> {
+ Some(match *bound {
+ hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
+ hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
+ let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
+
+ let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder();
+
+ let generic_args = clean_generic_args(generic_args, cx);
+ let GenericArgs::AngleBracketed { bindings, .. } = generic_args
+ else {
+ bug!("clean: parenthesized `GenericBound::LangItemTrait`");
+ };
- let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, &bindings);
- GenericBound::TraitBound(
- PolyTrait { trait_, generic_params: vec![] },
- hir::TraitBoundModifier::None,
- )
+ let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, bindings);
+ GenericBound::TraitBound(
+ PolyTrait { trait_, generic_params: vec![] },
+ hir::TraitBoundModifier::None,
+ )
+ }
+ hir::GenericBound::Trait(ref t, modifier) => {
+ // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
+ if modifier == hir::TraitBoundModifier::MaybeConst
+ && cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap())
+ {
+ return None;
}
- hir::GenericBound::Trait(ref t, modifier) => {
- // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
- if modifier == hir::TraitBoundModifier::MaybeConst
- && cx.tcx.lang_items().destruct_trait()
- == Some(t.trait_ref.trait_def_id().unwrap())
- {
- return None;
- }
- GenericBound::TraitBound(t.clean(cx), modifier)
- }
- })
- }
+ GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier)
+ }
+ })
}
pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
cx: &mut DocContext<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
- bindings: &[TypeBinding],
+ bindings: ThinVec<TypeBinding>,
) -> Path {
let kind = cx.tcx.def_kind(trait_ref.def_id).into();
if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
span_bug!(cx.tcx.def_span(trait_ref.def_id), "`TraitRef` had unexpected kind {:?}", kind);
}
inline::record_extern_fqn(cx, trait_ref.def_id, kind);
- let path = external_path(cx, trait_ref.def_id, true, bindings.to_vec(), trait_ref.substs);
+ let path = external_path(cx, trait_ref.def_id, true, bindings, trait_ref.substs);
debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs);
@@ -175,7 +174,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
fn clean_poly_trait_ref_with_bindings<'tcx>(
cx: &mut DocContext<'tcx>,
poly_trait_ref: ty::PolyTraitRef<'tcx>,
- bindings: &[TypeBinding],
+ bindings: ThinVec<TypeBinding>,
) -> GenericBound {
let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap();
@@ -200,16 +199,10 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
)
}
-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, &[])
- }
-}
-
-fn clean_lifetime<'tcx>(lifetime: hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime {
+fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime {
let def = cx.tcx.named_region(lifetime.hir_id);
if let Some(
- rl::Region::EarlyBound(_, node_id)
+ rl::Region::EarlyBound(node_id)
| rl::Region::LateBound(_, _, node_id)
| rl::Region::Free(_, node_id),
) = def
@@ -257,7 +250,6 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Life
| ty::ReFree(..)
| ty::ReVar(..)
| ty::RePlaceholder(..)
- | ty::ReEmpty(_)
| ty::ReErased => {
debug!("cannot clean region {:?}", region);
None
@@ -265,66 +257,68 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Life
}
}
-impl<'tcx> Clean<'tcx, Option<WherePredicate>> for hir::WherePredicate<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> Option<WherePredicate> {
- if !self.in_where_clause() {
- return None;
- }
- Some(match *self {
- hir::WherePredicate::BoundPredicate(ref wbp) => {
- let bound_params = wbp
- .bound_generic_params
- .iter()
- .map(|param| {
- // Higher-ranked params must be lifetimes.
- // Higher-ranked lifetimes can't have bounds.
- assert_matches!(
- param,
- hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. }
- );
- Lifetime(param.name.ident().name)
- })
- .collect();
- WherePredicate::BoundPredicate {
- ty: clean_ty(wbp.bounded_ty, cx),
- bounds: wbp.bounds.iter().filter_map(|x| x.clean(cx)).collect(),
- bound_params,
- }
+fn clean_where_predicate<'tcx>(
+ predicate: &hir::WherePredicate<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> Option<WherePredicate> {
+ if !predicate.in_where_clause() {
+ return None;
+ }
+ Some(match *predicate {
+ hir::WherePredicate::BoundPredicate(ref wbp) => {
+ let bound_params = wbp
+ .bound_generic_params
+ .iter()
+ .map(|param| {
+ // Higher-ranked params must be lifetimes.
+ // Higher-ranked lifetimes can't have bounds.
+ assert_matches!(
+ param,
+ hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. }
+ );
+ Lifetime(param.name.ident().name)
+ })
+ .collect();
+ WherePredicate::BoundPredicate {
+ ty: clean_ty(wbp.bounded_ty, cx),
+ bounds: wbp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
+ bound_params,
}
+ }
- hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
- lifetime: clean_lifetime(wrp.lifetime, cx),
- bounds: wrp.bounds.iter().filter_map(|x| x.clean(cx)).collect(),
- },
+ hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
+ lifetime: clean_lifetime(wrp.lifetime, cx),
+ bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
+ },
- hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate {
- lhs: clean_ty(wrp.lhs_ty, cx),
- rhs: clean_ty(wrp.rhs_ty, cx).into(),
- },
- })
- }
+ hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate {
+ lhs: clean_ty(wrp.lhs_ty, cx),
+ rhs: clean_ty(wrp.rhs_ty, cx).into(),
+ },
+ })
}
-impl<'tcx> Clean<'tcx, Option<WherePredicate>> for ty::Predicate<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> Option<WherePredicate> {
- let bound_predicate = self.kind();
- match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(pred) => {
- clean_poly_trait_predicate(bound_predicate.rebind(pred), cx)
- }
- ty::PredicateKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred),
- ty::PredicateKind::TypeOutlives(pred) => clean_type_outlives_predicate(pred, cx),
- ty::PredicateKind::Projection(pred) => Some(clean_projection_predicate(pred, cx)),
- ty::PredicateKind::ConstEvaluatable(..) => None,
- ty::PredicateKind::WellFormed(..) => None,
-
- ty::PredicateKind::Subtype(..)
- | ty::PredicateKind::Coerce(..)
- | ty::PredicateKind::ObjectSafe(..)
- | ty::PredicateKind::ClosureKind(..)
- | ty::PredicateKind::ConstEquate(..)
- | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
+pub(crate) fn clean_predicate<'tcx>(
+ predicate: ty::Predicate<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> Option<WherePredicate> {
+ let bound_predicate = predicate.kind();
+ match bound_predicate.skip_binder() {
+ ty::PredicateKind::Trait(pred) => {
+ clean_poly_trait_predicate(bound_predicate.rebind(pred), cx)
}
+ ty::PredicateKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred),
+ ty::PredicateKind::TypeOutlives(pred) => clean_type_outlives_predicate(pred, cx),
+ ty::PredicateKind::Projection(pred) => Some(clean_projection_predicate(pred, cx)),
+ ty::PredicateKind::ConstEvaluatable(..) => None,
+ ty::PredicateKind::WellFormed(..) => None,
+
+ ty::PredicateKind::Subtype(..)
+ | ty::PredicateKind::Coerce(..)
+ | ty::PredicateKind::ObjectSafe(..)
+ | ty::PredicateKind::ClosureKind(..)
+ | ty::PredicateKind::ConstEquate(..)
+ | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
}
}
@@ -342,7 +336,7 @@ fn clean_poly_trait_predicate<'tcx>(
let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref);
Some(WherePredicate::BoundPredicate {
ty: clean_middle_ty(poly_trait_ref.skip_binder().self_ty(), cx, None),
- bounds: vec![poly_trait_ref.clean(cx)],
+ bounds: vec![clean_poly_trait_ref_with_bindings(cx, poly_trait_ref, ThinVec::new())],
bound_params: Vec::new(),
})
}
@@ -352,10 +346,6 @@ fn clean_region_outlives_predicate<'tcx>(
) -> Option<WherePredicate> {
let ty::OutlivesPredicate(a, b) = pred;
- if a.is_empty() && b.is_empty() {
- return None;
- }
-
Some(WherePredicate::RegionPredicate {
lifetime: clean_middle_region(a).expect("failed to clean lifetime"),
bounds: vec![GenericBound::Outlives(
@@ -370,10 +360,6 @@ fn clean_type_outlives_predicate<'tcx>(
) -> Option<WherePredicate> {
let ty::OutlivesPredicate(ty, lt) = pred;
- if lt.is_empty() {
- return None;
- }
-
Some(WherePredicate::BoundPredicate {
ty: clean_middle_ty(ty, cx, None),
bounds: vec![GenericBound::Outlives(
@@ -384,9 +370,9 @@ fn clean_type_outlives_predicate<'tcx>(
}
fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
- match term {
- ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
- ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)),
+ match term.unpack() {
+ ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
+ ty::TermKind::Const(c) => Term::Constant(clean_middle_const(c, cx)),
}
}
@@ -417,7 +403,7 @@ fn clean_projection<'tcx>(
def_id: Option<DefId>,
) -> Type {
let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
- let trait_ = clean_trait_ref_with_bindings(cx, lifted.trait_ref(cx.tcx), &[]);
+ let trait_ = clean_trait_ref_with_bindings(cx, lifted.trait_ref(cx.tcx), ThinVec::new());
let self_type = clean_middle_ty(ty.self_ty(), cx, None);
let self_def_id = if let Some(def_id) = def_id {
cx.tcx.opt_parent(def_id).or(Some(def_id))
@@ -425,12 +411,12 @@ fn clean_projection<'tcx>(
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)),
+ Type::QPath(Box::new(QPathData {
+ assoc: projection_to_path_segment(ty, cx),
should_show_cast,
- self_type: Box::new(self_type),
+ self_type,
trait_,
- }
+ }))
}
fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type: &Type) -> bool {
@@ -509,7 +495,7 @@ fn clean_generic_param<'tcx>(
.filter(|bp| !bp.in_where_clause)
.flat_map(|bp| bp.bounds)
.map(|bound| match bound {
- hir::GenericBound::Outlives(lt) => clean_lifetime(*lt, cx),
+ hir::GenericBound::Outlives(lt) => clean_lifetime(lt, cx),
_ => panic!(),
})
.collect()
@@ -524,7 +510,7 @@ fn clean_generic_param<'tcx>(
.bounds_for_param(did)
.filter(|bp| bp.origin != PredicateOrigin::WhereClause)
.flat_map(|bp| bp.bounds)
- .filter_map(|x| x.clean(cx))
+ .filter_map(|x| clean_generic_bound(x, cx))
.collect()
} else {
Vec::new()
@@ -572,65 +558,68 @@ 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()
- .filter(|param| is_impl_trait(param))
- .map(|param| {
- let param = clean_generic_param(cx, Some(self), param);
- match param.kind {
- GenericParamDefKind::Lifetime { .. } => unreachable!(),
- GenericParamDefKind::Type { did, ref bounds, .. } => {
- cx.impl_trait_bounds.insert(did.into(), bounds.clone());
- }
- GenericParamDefKind::Const { .. } => unreachable!(),
+pub(crate) fn clean_generics<'tcx>(
+ gens: &hir::Generics<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> Generics {
+ let impl_trait_params = gens
+ .params
+ .iter()
+ .filter(|param| is_impl_trait(param))
+ .map(|param| {
+ let param = clean_generic_param(cx, Some(gens), param);
+ match param.kind {
+ GenericParamDefKind::Lifetime { .. } => unreachable!(),
+ GenericParamDefKind::Type { did, ref bounds, .. } => {
+ cx.impl_trait_bounds.insert(did.into(), bounds.clone());
}
- param
- })
- .collect::<Vec<_>>();
+ GenericParamDefKind::Const { .. } => unreachable!(),
+ }
+ param
+ })
+ .collect::<Vec<_>>();
- let mut params = Vec::with_capacity(self.params.len());
- for p in self.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
- let p = clean_generic_param(cx, Some(self), p);
- params.push(p);
- }
- params.extend(impl_trait_params);
+ let mut params = Vec::with_capacity(gens.params.len());
+ for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
+ let p = clean_generic_param(cx, Some(gens), p);
+ params.push(p);
+ }
+ params.extend(impl_trait_params);
- let mut generics = Generics {
- params,
- where_predicates: self.predicates.iter().filter_map(|x| x.clean(cx)).collect(),
- };
+ let mut generics = Generics {
+ params,
+ where_predicates: gens
+ .predicates
+ .iter()
+ .filter_map(|x| clean_where_predicate(x, cx))
+ .collect(),
+ };
- // Some duplicates are generated for ?Sized bounds between type params and where
- // predicates. The point in here is to move the bounds definitions from type params
- // to where predicates when such cases occur.
- for where_pred in &mut generics.where_predicates {
- match *where_pred {
- WherePredicate::BoundPredicate {
- ty: Generic(ref name), ref mut bounds, ..
- } => {
- if bounds.is_empty() {
- for param in &mut generics.params {
- match param.kind {
- GenericParamDefKind::Lifetime { .. } => {}
- GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
- if &param.name == name {
- mem::swap(bounds, ty_bounds);
- break;
- }
+ // Some duplicates are generated for ?Sized bounds between type params and where
+ // predicates. The point in here is to move the bounds definitions from type params
+ // to where predicates when such cases occur.
+ for where_pred in &mut generics.where_predicates {
+ match *where_pred {
+ WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds, .. } => {
+ if bounds.is_empty() {
+ for param in &mut generics.params {
+ match param.kind {
+ GenericParamDefKind::Lifetime { .. } => {}
+ GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
+ if &param.name == name {
+ mem::swap(bounds, ty_bounds);
+ break;
}
- GenericParamDefKind::Const { .. } => {}
}
+ GenericParamDefKind::Const { .. } => {}
}
}
}
- _ => continue,
}
+ _ => continue,
}
- generics
}
+ generics
}
fn clean_ty_generics<'tcx>(
@@ -701,7 +690,7 @@ fn clean_ty_generics<'tcx>(
if let Some(param_idx) = param_idx {
if let Some(b) = impl_trait.get_mut(&param_idx.into()) {
- let p: WherePredicate = p.clean(cx)?;
+ let p: WherePredicate = clean_predicate(*p, cx)?;
b.extend(
p.get_bounds()
@@ -758,7 +747,7 @@ fn clean_ty_generics<'tcx>(
// Now that `cx.impl_trait_bounds` is populated, we can process
// remaining predicates which could contain `impl Trait`.
let mut where_predicates =
- where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::<Vec<_>>();
+ where_predicates.into_iter().flat_map(|p| clean_predicate(*p, cx)).collect::<Vec<_>>();
// Type parameters have a Sized bound by default unless removed with
// ?Sized. Scan through the predicates and mark any type parameter with
@@ -896,9 +885,12 @@ fn clean_function<'tcx>(
) -> Box<Function> {
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
- let generics = generics.clean(cx);
+ let generics = clean_generics(generics, cx);
let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id);
- let decl = clean_fn_decl_with_args(cx, sig.decl, args);
+ let mut decl = clean_fn_decl_with_args(cx, sig.decl, args);
+ if sig.header.is_async() {
+ decl.output = decl.sugared_async_return_type();
+ }
(generics, decl)
});
Box::new(Function { decl, generics })
@@ -994,305 +986,307 @@ fn clean_trait_ref<'tcx>(trait_ref: &hir::TraitRef<'tcx>, cx: &mut DocContext<'t
path
}
-impl<'tcx> Clean<'tcx, PolyTrait> for hir::PolyTraitRef<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> PolyTrait {
- PolyTrait {
- trait_: clean_trait_ref(&self.trait_ref, cx),
- generic_params: self
- .bound_generic_params
- .iter()
- .filter(|p| !is_elided_lifetime(p))
- .map(|x| clean_generic_param(cx, None, x))
- .collect(),
- }
+fn clean_poly_trait_ref<'tcx>(
+ poly_trait_ref: &hir::PolyTraitRef<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> PolyTrait {
+ PolyTrait {
+ trait_: clean_trait_ref(&poly_trait_ref.trait_ref, cx),
+ generic_params: poly_trait_ref
+ .bound_generic_params
+ .iter()
+ .filter(|p| !is_elided_lifetime(p))
+ .map(|x| clean_generic_param(cx, None, x))
+ .collect(),
}
}
-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(ty, Some(default)) => AssocConstItem(
- clean_ty(ty, cx),
- ConstantKind::Local { def_id: local_did, body: default },
- ),
- hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)),
- hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
- let m = clean_function(cx, sig, self.generics, body);
- MethodItem(m, None)
- }
- hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
- let (generics, decl) = enter_impl_trait(cx, |cx| {
- // NOTE: generics must be cleaned before args
- let generics = self.generics.clean(cx);
- let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names);
- let decl = clean_fn_decl_with_args(cx, sig.decl, args);
- (generics, decl)
- });
- TyMethodItem(Box::new(Function { decl, generics }))
- }
- hir::TraitItemKind::Type(bounds, Some(default)) => {
- let generics = enter_impl_trait(cx, |cx| self.generics.clean(cx));
- let bounds = bounds.iter().filter_map(|x| x.clean(cx)).collect();
- let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, default), cx, None);
- AssocTypeItem(
- Box::new(Typedef {
- type_: clean_ty(default, cx),
- generics,
- item_type: Some(item_type),
- }),
- bounds,
- )
- }
- hir::TraitItemKind::Type(bounds, None) => {
- let generics = enter_impl_trait(cx, |cx| self.generics.clean(cx));
- let bounds = bounds.iter().filter_map(|x| x.clean(cx)).collect();
- TyAssocTypeItem(Box::new(generics), bounds)
- }
- };
- let what_rustc_thinks =
- Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx);
- // Trait items always inherit the trait's visibility -- we don't want to show `pub`.
- Item { visibility: Inherited, ..what_rustc_thinks }
- })
- }
+fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
+ let local_did = trait_item.def_id.to_def_id();
+ cx.with_param_env(local_did, |cx| {
+ let inner = match trait_item.kind {
+ hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem(
+ clean_ty(ty, cx),
+ ConstantKind::Local { def_id: local_did, body: default },
+ ),
+ hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)),
+ hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
+ let m = clean_function(cx, sig, trait_item.generics, body);
+ MethodItem(m, None)
+ }
+ hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
+ let (generics, decl) = enter_impl_trait(cx, |cx| {
+ // NOTE: generics must be cleaned before args
+ let generics = clean_generics(trait_item.generics, cx);
+ let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names);
+ let decl = clean_fn_decl_with_args(cx, sig.decl, args);
+ (generics, decl)
+ });
+ TyMethodItem(Box::new(Function { decl, generics }))
+ }
+ hir::TraitItemKind::Type(bounds, Some(default)) => {
+ let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
+ let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
+ let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, default), cx, None);
+ AssocTypeItem(
+ Box::new(Typedef {
+ type_: clean_ty(default, cx),
+ generics,
+ item_type: Some(item_type),
+ }),
+ bounds,
+ )
+ }
+ hir::TraitItemKind::Type(bounds, None) => {
+ let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
+ let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
+ TyAssocTypeItem(Box::new(generics), bounds)
+ }
+ };
+ let what_rustc_thinks =
+ Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx);
+ // Trait items always inherit the trait's visibility -- we don't want to show `pub`.
+ Item { visibility: Inherited, ..what_rustc_thinks }
+ })
}
-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(ty, expr) => {
- let default = ConstantKind::Local { def_id: local_did, body: expr };
- AssocConstItem(clean_ty(ty, cx), default)
- }
- hir::ImplItemKind::Fn(ref sig, body) => {
- let m = clean_function(cx, sig, self.generics, body);
- let defaultness = cx.tcx.impl_defaultness(self.def_id);
- MethodItem(m, Some(defaultness))
- }
- hir::ImplItemKind::TyAlias(hir_ty) => {
- let type_ = clean_ty(hir_ty, cx);
- let generics = self.generics.clean(cx);
- let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
- AssocTypeItem(
- Box::new(Typedef { type_, generics, item_type: Some(item_type) }),
- Vec::new(),
- )
- }
- };
+pub(crate) fn clean_impl_item<'tcx>(
+ impl_: &hir::ImplItem<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> Item {
+ let local_did = impl_.def_id.to_def_id();
+ cx.with_param_env(local_did, |cx| {
+ let inner = match impl_.kind {
+ hir::ImplItemKind::Const(ty, expr) => {
+ let default = ConstantKind::Local { def_id: local_did, body: expr };
+ AssocConstItem(clean_ty(ty, cx), default)
+ }
+ hir::ImplItemKind::Fn(ref sig, body) => {
+ let m = clean_function(cx, sig, impl_.generics, body);
+ let defaultness = cx.tcx.impl_defaultness(impl_.def_id);
+ MethodItem(m, Some(defaultness))
+ }
+ hir::ImplItemKind::TyAlias(hir_ty) => {
+ let type_ = clean_ty(hir_ty, cx);
+ let generics = clean_generics(impl_.generics, cx);
+ let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
+ AssocTypeItem(
+ Box::new(Typedef { type_, generics, item_type: Some(item_type) }),
+ Vec::new(),
+ )
+ }
+ };
- let mut what_rustc_thinks =
- Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx);
+ let mut what_rustc_thinks =
+ Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx);
- let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(self.def_id));
+ let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(impl_.def_id));
- // Trait impl items always inherit the impl's visibility --
- // we don't want to show `pub`.
- if impl_ref.is_some() {
- what_rustc_thinks.visibility = Inherited;
- }
+ // Trait impl items always inherit the impl's visibility --
+ // we don't want to show `pub`.
+ if impl_ref.is_some() {
+ what_rustc_thinks.visibility = Inherited;
+ }
- what_rustc_thinks
- })
- }
+ what_rustc_thinks
+ })
}
-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 => {
- let ty = clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id));
+pub(crate) fn clean_middle_assoc_item<'tcx>(
+ assoc_item: &ty::AssocItem,
+ cx: &mut DocContext<'tcx>,
+) -> Item {
+ let tcx = cx.tcx;
+ let kind = match assoc_item.kind {
+ ty::AssocKind::Const => {
+ let ty = clean_middle_ty(tcx.type_of(assoc_item.def_id), cx, Some(assoc_item.def_id));
- let provided = match self.container {
- ty::ImplContainer => true,
- ty::TraitContainer => tcx.impl_defaultness(self.def_id).has_value(),
- };
- if provided {
- AssocConstItem(ty, ConstantKind::Extern { def_id: self.def_id })
- } else {
- TyAssocConstItem(ty)
- }
+ let provided = match assoc_item.container {
+ ty::ImplContainer => true,
+ ty::TraitContainer => tcx.impl_defaultness(assoc_item.def_id).has_value(),
+ };
+ if provided {
+ AssocConstItem(ty, ConstantKind::Extern { def_id: assoc_item.def_id })
+ } else {
+ TyAssocConstItem(ty)
}
- ty::AssocKind::Fn => {
- let generics = clean_ty_generics(
- cx,
- tcx.generics_of(self.def_id),
- tcx.explicit_predicates_of(self.def_id),
- );
- let sig = tcx.fn_sig(self.def_id);
- let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(self.def_id), sig);
-
- if self.fn_has_self_parameter {
- let self_ty = match self.container {
- ty::ImplContainer => tcx.type_of(self.container_id(tcx)),
- ty::TraitContainer => tcx.types.self_param,
- };
- let self_arg_ty = sig.input(0).skip_binder();
- if self_arg_ty == self_ty {
- decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
- } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
- if ty == self_ty {
- match decl.inputs.values[0].type_ {
- BorrowedRef { ref mut type_, .. } => {
- **type_ = Generic(kw::SelfUpper)
- }
- _ => unreachable!(),
- }
+ }
+ ty::AssocKind::Fn => {
+ let generics = clean_ty_generics(
+ cx,
+ tcx.generics_of(assoc_item.def_id),
+ tcx.explicit_predicates_of(assoc_item.def_id),
+ );
+ let sig = tcx.fn_sig(assoc_item.def_id);
+ let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
+
+ if assoc_item.fn_has_self_parameter {
+ let self_ty = match assoc_item.container {
+ ty::ImplContainer => tcx.type_of(assoc_item.container_id(tcx)),
+ ty::TraitContainer => tcx.types.self_param,
+ };
+ let self_arg_ty = sig.input(0).skip_binder();
+ if self_arg_ty == self_ty {
+ decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
+ } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
+ if ty == self_ty {
+ match decl.inputs.values[0].type_ {
+ BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
+ _ => unreachable!(),
}
}
}
+ }
- let provided = match self.container {
- ty::ImplContainer => true,
- ty::TraitContainer => self.defaultness(tcx).has_value(),
+ let provided = match assoc_item.container {
+ ty::ImplContainer => true,
+ ty::TraitContainer => assoc_item.defaultness(tcx).has_value(),
+ };
+ if provided {
+ let defaultness = match assoc_item.container {
+ ty::ImplContainer => Some(assoc_item.defaultness(tcx)),
+ ty::TraitContainer => None,
};
- if provided {
- let defaultness = match self.container {
- ty::ImplContainer => Some(self.defaultness(tcx)),
- ty::TraitContainer => None,
- };
- MethodItem(Box::new(Function { generics, decl }), defaultness)
- } else {
- TyMethodItem(Box::new(Function { generics, decl }))
- }
+ MethodItem(Box::new(Function { generics, decl }), defaultness)
+ } else {
+ TyMethodItem(Box::new(Function { generics, decl }))
}
- ty::AssocKind::Type => {
- let my_name = self.name;
-
- fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool {
- match (&param.kind, arg) {
- (GenericParamDefKind::Type { .. }, GenericArg::Type(Type::Generic(ty)))
- if *ty == param.name =>
- {
- true
- }
- (
- GenericParamDefKind::Lifetime { .. },
- GenericArg::Lifetime(Lifetime(lt)),
- ) if *lt == param.name => true,
- (GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => {
- match &c.kind {
- ConstantKind::TyConst { expr } => expr == param.name.as_str(),
- _ => false,
- }
- }
- _ => false,
+ }
+ ty::AssocKind::Type => {
+ let my_name = assoc_item.name;
+
+ fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool {
+ match (&param.kind, arg) {
+ (GenericParamDefKind::Type { .. }, GenericArg::Type(Type::Generic(ty)))
+ if *ty == param.name =>
+ {
+ true
+ }
+ (GenericParamDefKind::Lifetime { .. }, GenericArg::Lifetime(Lifetime(lt)))
+ if *lt == param.name =>
+ {
+ true
}
+ (GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind {
+ ConstantKind::TyConst { expr } => expr == param.name.as_str(),
+ _ => false,
+ },
+ _ => false,
}
+ }
- if let ty::TraitContainer = self.container {
- let bounds = tcx.explicit_item_bounds(self.def_id);
- let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
- let mut generics =
- clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates);
- // Filter out the bounds that are (likely?) directly attached to the associated type,
- // as opposed to being located in the where clause.
- let mut bounds = generics
- .where_predicates
- .drain_filter(|pred| match *pred {
- WherePredicate::BoundPredicate {
- ty: QPath { ref assoc, ref self_type, ref trait_, .. },
- ..
- } => {
- if assoc.name != my_name {
- return false;
- }
- if trait_.def_id() != self.container_id(tcx) {
- return false;
- }
- match **self_type {
- Generic(ref s) if *s == kw::SelfUpper => {}
- _ => return false,
- }
- match &assoc.args {
- GenericArgs::AngleBracketed { args, bindings } => {
- if !bindings.is_empty()
- || generics
- .params
- .iter()
- .zip(args.iter())
- .any(|(param, arg)| !param_eq_arg(param, arg))
- {
- return false;
- }
- }
- GenericArgs::Parenthesized { .. } => {
- // The only time this happens is if we're inside the rustdoc for Fn(),
- // which only has one associated type, which is not a GAT, so whatever.
+ if let ty::TraitContainer = assoc_item.container {
+ let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
+ let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
+ let mut generics =
+ clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), predicates);
+ // Filter out the bounds that are (likely?) directly attached to the associated type,
+ // as opposed to being located in the where clause.
+ let mut bounds = generics
+ .where_predicates
+ .drain_filter(|pred| match *pred {
+ WherePredicate::BoundPredicate {
+ ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }),
+ ..
+ } => {
+ if assoc.name != my_name {
+ return false;
+ }
+ if trait_.def_id() != assoc_item.container_id(tcx) {
+ return false;
+ }
+ match *self_type {
+ Generic(ref s) if *s == kw::SelfUpper => {}
+ _ => return false,
+ }
+ match &assoc.args {
+ GenericArgs::AngleBracketed { args, bindings } => {
+ if !bindings.is_empty()
+ || generics
+ .params
+ .iter()
+ .zip(args.iter())
+ .any(|(param, arg)| !param_eq_arg(param, arg))
+ {
+ return false;
}
}
- true
- }
- _ => false,
- })
- .flat_map(|pred| {
- if let WherePredicate::BoundPredicate { bounds, .. } = pred {
- bounds
- } else {
- unreachable!()
+ GenericArgs::Parenthesized { .. } => {
+ // The only time this happens is if we're inside the rustdoc for Fn(),
+ // which only has one associated type, which is not a GAT, so whatever.
+ }
}
- })
- .collect::<Vec<_>>();
- // Our Sized/?Sized bound didn't get handled when creating the generics
- // because we didn't actually get our whole set of bounds until just now
- // (some of them may have come from the trait). If we do have a sized
- // bound, we remove it, and if we don't then we add the `?Sized` bound
- // at the end.
- match bounds.iter().position(|b| b.is_sized_bound(cx)) {
- Some(i) => {
- bounds.remove(i);
+ true
}
- None => bounds.push(GenericBound::maybe_sized(cx)),
+ _ => false,
+ })
+ .flat_map(|pred| {
+ if let WherePredicate::BoundPredicate { bounds, .. } = pred {
+ bounds
+ } else {
+ unreachable!()
+ }
+ })
+ .collect::<Vec<_>>();
+ // Our Sized/?Sized bound didn't get handled when creating the generics
+ // because we didn't actually get our whole set of bounds until just now
+ // (some of them may have come from the trait). If we do have a sized
+ // bound, we remove it, and if we don't then we add the `?Sized` bound
+ // at the end.
+ match bounds.iter().position(|b| b.is_sized_bound(cx)) {
+ Some(i) => {
+ bounds.remove(i);
}
+ None => bounds.push(GenericBound::maybe_sized(cx)),
+ }
- if tcx.impl_defaultness(self.def_id).has_value() {
- AssocTypeItem(
- Box::new(Typedef {
- type_: clean_middle_ty(
- tcx.type_of(self.def_id),
- cx,
- Some(self.def_id),
- ),
- generics,
- // FIXME: should we obtain the Type from HIR and pass it on here?
- item_type: None,
- }),
- bounds,
- )
- } else {
- TyAssocTypeItem(Box::new(generics), bounds)
- }
- } else {
- // FIXME: when could this happen? Associated items in inherent impls?
+ if tcx.impl_defaultness(assoc_item.def_id).has_value() {
AssocTypeItem(
Box::new(Typedef {
- type_: clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)),
- generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
+ type_: clean_middle_ty(
+ tcx.type_of(assoc_item.def_id),
+ cx,
+ Some(assoc_item.def_id),
+ ),
+ generics,
+ // FIXME: should we obtain the Type from HIR and pass it on here?
item_type: None,
}),
- Vec::new(),
+ bounds,
)
+ } else {
+ TyAssocTypeItem(Box::new(generics), bounds)
}
+ } else {
+ // FIXME: when could this happen? Associated items in inherent impls?
+ AssocTypeItem(
+ Box::new(Typedef {
+ type_: clean_middle_ty(
+ tcx.type_of(assoc_item.def_id),
+ cx,
+ Some(assoc_item.def_id),
+ ),
+ generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
+ item_type: None,
+ }),
+ Vec::new(),
+ )
}
- };
+ }
+ };
- let mut what_rustc_thinks =
- Item::from_def_id_and_parts(self.def_id, Some(self.name), kind, cx);
+ let mut what_rustc_thinks =
+ Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx);
- let impl_ref = tcx.impl_trait_ref(tcx.parent(self.def_id));
+ let impl_ref = tcx.impl_trait_ref(tcx.parent(assoc_item.def_id));
- // Trait impl items always inherit the impl's visibility --
- // we don't want to show `pub`.
- if impl_ref.is_some() {
- what_rustc_thinks.visibility = Visibility::Inherited;
- }
-
- what_rustc_thinks
+ // Trait impl items always inherit the impl's visibility --
+ // we don't want to show `pub`.
+ if impl_ref.is_some() {
+ what_rustc_thinks.visibility = Visibility::Inherited;
}
+
+ what_rustc_thinks
}
fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type {
@@ -1328,18 +1322,18 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
let trait_def = cx.tcx.associated_item(p.res.def_id()).container_id(cx.tcx);
let trait_ = self::Path {
res: Res::Def(DefKind::Trait, trait_def),
- segments: trait_segments.iter().map(|x| x.clean(cx)).collect(),
+ segments: trait_segments.iter().map(|x| clean_path_segment(x, cx)).collect(),
};
register_res(cx, trait_.res);
let self_def_id = DefId::local(qself.hir_id.owner.local_def_index);
let self_type = clean_ty(qself, cx);
let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type);
- Type::QPath {
- assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)),
+ Type::QPath(Box::new(QPathData {
+ assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx),
should_show_cast,
- self_type: Box::new(self_type),
+ self_type,
trait_,
- }
+ }))
}
hir::QPath::TypeRelative(qself, segment) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
@@ -1354,12 +1348,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
let self_def_id = res.opt_def_id();
let self_type = clean_ty(qself, cx);
let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
- Type::QPath {
- assoc: Box::new(segment.clean(cx)),
+ Type::QPath(Box::new(QPathData {
+ assoc: clean_path_segment(segment, cx),
should_show_cast,
- self_type: Box::new(self_type),
+ self_type,
trait_,
- }
+ }))
}
hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
}
@@ -1398,7 +1392,7 @@ fn maybe_expand_private_type_alias<'tcx>(
}
_ => None,
});
- if let Some(lt) = lifetime.cloned() {
+ if let Some(lt) = lifetime {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let cleaned =
if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };
@@ -1498,22 +1492,22 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
Array(Box::new(clean_ty(ty, cx)), length)
}
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
- TyKind::OpaqueDef(item_id, _) => {
+ TyKind::OpaqueDef(item_id, _, _) => {
let item = cx.tcx.hir().item(item_id);
if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
- ImplTrait(ty.bounds.iter().filter_map(|x| x.clean(cx)).collect())
+ ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
} else {
unreachable!()
}
}
TyKind::Path(_) => clean_qpath(ty, cx),
TyKind::TraitObject(bounds, ref lifetime, _) => {
- let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect();
+ let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
let lifetime =
if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
DynTrait(bounds, lifetime)
}
- TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))),
+ TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
TyKind::Infer | TyKind::Err => Infer,
TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind),
@@ -1598,21 +1592,22 @@ pub(crate) fn clean_middle_ty<'tcx>(
AdtKind::Enum => ItemType::Enum,
};
inline::record_extern_fqn(cx, did, kind);
- let path = external_path(cx, did, false, vec![], substs);
+ let path = external_path(cx, did, false, ThinVec::new(), 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());
+ let path = external_path(cx, did, false, ThinVec::new(), InternalSubsts::empty());
Type::Path { path }
}
- ty::Dynamic(obj, ref reg) => {
+ 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()
+ let mut dids = obj.auto_traits();
+ let did = obj
+ .principal_def_id()
+ .or_else(|| dids.next())
.unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", this));
let substs = match obj.principal() {
Some(principal) => principal.skip_binder().substs,
@@ -1623,19 +1618,18 @@ pub(crate) fn clean_middle_ty<'tcx>(
inline::record_extern_fqn(cx, did, ItemType::Trait);
let lifetime = clean_middle_region(*reg);
- 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);
- }
+ let mut bounds = dids
+ .map(|did| {
+ let empty = cx.tcx.intern_substs(&[]);
+ let path = external_path(cx, did, false, ThinVec::new(), empty);
+ inline::record_extern_fqn(cx, did, ItemType::Trait);
+ PolyTrait { trait_: path, generic_params: Vec::new() }
+ })
+ .collect::<Vec<_>>();
- let mut bindings = vec![];
- for pb in obj.projection_bounds() {
- bindings.push(TypeBinding {
+ let bindings = obj
+ .projection_bounds()
+ .map(|pb| TypeBinding {
assoc: projection_to_path_segment(
pb.skip_binder()
.lift_to_tcx(cx.tcx)
@@ -1649,8 +1643,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
kind: TypeBindingKind::Equality {
term: clean_middle_term(pb.skip_binder().term, cx),
},
- });
- }
+ })
+ .collect();
let path = external_path(cx, did, false, bindings, substs);
bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() });
@@ -1703,7 +1697,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
}
}
- let bindings: Vec<_> = bounds
+ let bindings: ThinVec<_> = bounds
.iter()
.filter_map(|bound| {
if let ty::PredicateKind::Projection(proj) = bound.kind().skip_binder()
@@ -1724,7 +1718,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
})
.collect();
- Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, &bindings))
+ Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings))
})
.collect::<Vec<_>>();
bounds.extend(regions);
@@ -1783,21 +1777,19 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
}
-pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility {
+pub(crate) fn clean_visibility(vis: ty::Visibility<DefId>) -> Visibility {
match vis {
ty::Visibility::Public => Visibility::Public,
- // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private',
- // while rustdoc really does mean inherited. That means that for enum variants, such as
- // `pub enum E { V }`, `V` will be marked as `Public` by `ty`, but as `Inherited` by rustdoc.
- // Various parts of clean override `tcx.visibility` explicitly to make sure this distinction is captured.
- ty::Visibility::Invisible => Visibility::Inherited,
ty::Visibility::Restricted(module) => Visibility::Restricted(module),
}
}
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
let kind = match variant.ctor_kind {
- CtorKind::Const => Variant::CLike,
+ CtorKind::Const => Variant::CLike(match variant.discr {
+ ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
+ ty::VariantDiscr::Relative(_) => None,
+ }),
CtorKind::Fn => Variant::Tuple(
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
),
@@ -1814,6 +1806,7 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont
fn clean_variant_data<'tcx>(
variant: &hir::VariantData<'tcx>,
+ disr_expr: &Option<hir::AnonConst>,
cx: &mut DocContext<'tcx>,
) -> Variant {
match variant {
@@ -1824,66 +1817,75 @@ fn clean_variant_data<'tcx>(
hir::VariantData::Tuple(..) => {
Variant::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())
}
- hir::VariantData::Unit(..) => Variant::CLike,
+ hir::VariantData::Unit(..) => Variant::CLike(disr_expr.map(|disr| Discriminant {
+ expr: Some(disr.body),
+ value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(),
+ })),
}
}
fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
- Path { res: path.res, segments: path.segments.iter().map(|x| x.clean(cx)).collect() }
+ Path {
+ res: path.res,
+ segments: path.segments.iter().map(|x| clean_path_segment(x, cx)).collect(),
+ }
}
-impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs {
- if self.parenthesized {
- let output = clean_ty(self.bindings[0].ty(), cx);
- let output =
- if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
- let inputs = self.inputs().iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
- GenericArgs::Parenthesized { inputs, output }
- } else {
- let args = self
- .args
- .iter()
- .map(|arg| match arg {
- hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
- GenericArg::Lifetime(clean_lifetime(*lt, cx))
- }
- hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
- hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
- hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))),
- hir::GenericArg::Infer(_inf) => GenericArg::Infer,
- })
- .collect::<Vec<_>>()
- .into();
- let bindings =
- self.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::<Vec<_>>().into();
- GenericArgs::AngleBracketed { args, bindings }
- }
+fn clean_generic_args<'tcx>(
+ generic_args: &hir::GenericArgs<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> GenericArgs {
+ if generic_args.parenthesized {
+ let output = clean_ty(generic_args.bindings[0].ty(), cx);
+ let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
+ let inputs =
+ generic_args.inputs().iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
+ GenericArgs::Parenthesized { inputs, output }
+ } else {
+ let args = generic_args
+ .args
+ .iter()
+ .map(|arg| match arg {
+ hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
+ GenericArg::Lifetime(clean_lifetime(*lt, cx))
+ }
+ hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
+ hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
+ hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))),
+ hir::GenericArg::Infer(_inf) => GenericArg::Infer,
+ })
+ .collect::<Vec<_>>()
+ .into();
+ let bindings =
+ generic_args.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::<ThinVec<_>>();
+ GenericArgs::AngleBracketed { args, bindings }
}
}
-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) }
- }
+fn clean_path_segment<'tcx>(
+ path: &hir::PathSegment<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> PathSegment {
+ PathSegment { name: path.ident.name, args: clean_generic_args(path.args(), cx) }
}
-impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> BareFunctionDecl {
- let (generic_params, decl) = enter_impl_trait(cx, |cx| {
- // NOTE: generics must be cleaned before args
- let generic_params = self
- .generic_params
- .iter()
- .filter(|p| !is_elided_lifetime(p))
- .map(|x| clean_generic_param(cx, None, x))
- .collect();
- let args = clean_args_from_types_and_names(cx, self.decl.inputs, self.param_names);
- let decl = clean_fn_decl_with_args(cx, self.decl, args);
- (generic_params, decl)
- });
- BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
- }
+fn clean_bare_fn_ty<'tcx>(
+ bare_fn: &hir::BareFnTy<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> BareFunctionDecl {
+ let (generic_params, decl) = enter_impl_trait(cx, |cx| {
+ // NOTE: generics must be cleaned before args
+ let generic_params = bare_fn
+ .generic_params
+ .iter()
+ .filter(|p| !is_elided_lifetime(p))
+ .map(|x| clean_generic_param(cx, None, x))
+ .collect();
+ let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_names);
+ let decl = clean_fn_decl_with_args(cx, bare_fn.decl, args);
+ (generic_params, decl)
+ });
+ BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
}
fn clean_maybe_renamed_item<'tcx>(
@@ -1905,33 +1907,33 @@ fn clean_maybe_renamed_item<'tcx>(
kind: ConstantKind::Local { body: body_id, def_id },
}),
ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
- bounds: ty.bounds.iter().filter_map(|x| x.clean(cx)).collect(),
- generics: ty.generics.clean(cx),
+ bounds: ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
+ generics: clean_generics(ty.generics, cx),
}),
ItemKind::TyAlias(hir_ty, generics) => {
let rustdoc_ty = clean_ty(hir_ty, cx);
let ty = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
TypedefItem(Box::new(Typedef {
type_: rustdoc_ty,
- generics: generics.clean(cx),
+ generics: clean_generics(generics, cx),
item_type: Some(ty),
}))
}
ItemKind::Enum(ref def, generics) => EnumItem(Enum {
- variants: def.variants.iter().map(|v| v.clean(cx)).collect(),
- generics: generics.clean(cx),
+ variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
+ generics: clean_generics(generics, cx),
}),
ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias {
- generics: generics.clean(cx),
- bounds: bounds.iter().filter_map(|x| x.clean(cx)).collect(),
+ generics: clean_generics(generics, cx),
+ bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
}),
ItemKind::Union(ref variant_data, generics) => UnionItem(Union {
- generics: generics.clean(cx),
+ generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
ItemKind::Struct(ref variant_data, generics) => StructItem(Struct {
struct_type: CtorKind::from_hir(variant_data),
- generics: generics.clean(cx),
+ generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
ItemKind::Impl(impl_) => return clean_impl(impl_, item.hir_id(), cx),
@@ -1946,15 +1948,17 @@ fn clean_maybe_renamed_item<'tcx>(
})
}
ItemKind::Trait(_, _, generics, bounds, item_ids) => {
- let items =
- item_ids.iter().map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)).collect();
+ let items = item_ids
+ .iter()
+ .map(|ti| clean_trait_item(cx.tcx.hir().trait_item(ti.id), cx))
+ .collect();
- TraitItem(Trait {
+ TraitItem(Box::new(Trait {
def_id,
items,
- generics: generics.clean(cx),
- bounds: bounds.iter().filter_map(|x| x.clean(cx)).collect(),
- })
+ generics: clean_generics(generics, cx),
+ bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
+ }))
}
ItemKind::ExternCrate(orig_name) => {
return clean_extern_crate(item, name, orig_name, cx);
@@ -1969,14 +1973,12 @@ fn clean_maybe_renamed_item<'tcx>(
})
}
-impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
- let kind = VariantItem(clean_variant_data(&self.data, cx));
- let what_rustc_thinks =
- Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
- // don't show `pub` for variants, which are always public
- Item { visibility: Inherited, ..what_rustc_thinks }
- }
+fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
+ let kind = VariantItem(clean_variant_data(&variant.data, &variant.disr_expr, cx));
+ let what_rustc_thinks =
+ Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx);
+ // don't show `pub` for variants, which are always public
+ Item { visibility: Inherited, ..what_rustc_thinks }
}
fn clean_impl<'tcx>(
@@ -1987,8 +1989,11 @@ fn clean_impl<'tcx>(
let tcx = cx.tcx;
let mut ret = Vec::new();
let trait_ = impl_.of_trait.as_ref().map(|t| clean_trait_ref(t, cx));
- let items =
- impl_.items.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
+ let items = impl_
+ .items
+ .iter()
+ .map(|ii| clean_impl_item(tcx.hir().impl_item(ii.id), cx))
+ .collect::<Vec<_>>();
let def_id = tcx.hir().local_def_id(hir_id);
// If this impl block is an implementation of the Deref trait, then we
@@ -2005,7 +2010,7 @@ fn clean_impl<'tcx>(
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Box::new(Impl {
unsafety: impl_.unsafety,
- generics: impl_.generics.clean(cx),
+ generics: clean_generics(impl_.generics, cx),
trait_,
for_,
items,
@@ -2106,8 +2111,8 @@ fn clean_use_statement<'tcx>(
// `pub(super)` or higher. If the current module is the top level
// module, there isn't really a parent module, which makes the results
// meaningless. In this case, we make sure the answer is `false`.
- let is_visible_from_parent_mod = visibility.is_accessible_from(parent_mod.to_def_id(), cx.tcx)
- && !current_mod.is_top_level_module();
+ let is_visible_from_parent_mod =
+ visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module();
if pub_underscore {
if let Some(ref inline) = inline_attr {
@@ -2202,7 +2207,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
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);
+ let generics = clean_generics(generics, cx);
let args = clean_args_from_types_and_names(cx, decl.inputs, names);
let decl = clean_fn_decl_with_args(cx, decl, args);
(generics, decl)
@@ -2229,13 +2234,16 @@ fn clean_type_binding<'tcx>(
cx: &mut DocContext<'tcx>,
) -> TypeBinding {
TypeBinding {
- assoc: PathSegment { name: type_binding.ident.name, args: type_binding.gen_args.clean(cx) },
+ assoc: PathSegment {
+ name: type_binding.ident.name,
+ args: clean_generic_args(type_binding.gen_args, cx),
+ },
kind: match type_binding.kind {
hir::TypeBindingKind::Equality { ref term } => {
TypeBindingKind::Equality { term: clean_hir_term(term, cx) }
}
hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint {
- bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
+ bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(),
},
},
}
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 0e6de842c..f973fd088 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -8,6 +8,7 @@ use std::sync::OnceLock as OnceCell;
use std::{cmp, fmt, iter};
use arrayvec::ArrayVec;
+use thin_vec::ThinVec;
use rustc_ast::attr;
use rustc_ast::util::comments::beautify_doc_string;
@@ -15,7 +16,6 @@ use rustc_ast::{self as ast, AttrStyle};
use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
use rustc_const_eval::const_eval::is_unstable_const_fn;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::thin_vec::ThinVec;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -415,29 +415,28 @@ impl Item {
.unwrap_or(false)
}
- pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Span {
+ pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option<Span> {
let kind = match &*self.kind {
ItemKind::StrippedItem(k) => k,
_ => &*self.kind,
};
match kind {
- ItemKind::ModuleItem(Module { span, .. }) => *span,
- ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
+ ItemKind::ModuleItem(Module { span, .. }) => Some(*span),
+ ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => None,
ItemKind::ImplItem(box Impl { kind: ImplKind::Blanket(_), .. }) => {
if let ItemId::Blanket { impl_id, .. } = self.item_id {
- rustc_span(impl_id, tcx)
+ Some(rustc_span(impl_id, tcx))
} else {
panic!("blanket impl item has non-blanket ID")
}
}
- _ => {
- self.item_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
- }
+ _ => self.item_id.as_def_id().map(|did| rustc_span(did, tcx)),
}
}
pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span {
- crate::passes::span_of_attrs(&self.attrs).unwrap_or_else(|| self.span(tcx).inner())
+ crate::passes::span_of_attrs(&self.attrs)
+ .unwrap_or_else(|| self.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()))
}
/// Finds the `doc` attribute as a NameValue and returns the corresponding
@@ -483,7 +482,7 @@ impl Item {
cx: &mut DocContext<'_>,
cfg: Option<Arc<Cfg>>,
) -> Item {
- trace!("name={:?}, def_id={:?}", name, def_id);
+ trace!("name={:?}, def_id={:?} cfg={:?}", name, def_id, cfg);
// Primitives and Keywords are written in the source code as private modules.
// The modules need to be private so that nobody actually uses them, but the
@@ -511,7 +510,7 @@ impl Item {
.get(&self.item_id)
.map_or(&[][..], |v| v.as_slice())
.iter()
- .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| {
+ .filter_map(|ItemLink { link: s, link_text, page_id: did, ref fragment }| {
debug!(?did);
if let Ok((mut href, ..)) = href(*did, cx) {
debug!(?href);
@@ -728,7 +727,7 @@ pub(crate) enum ItemKind {
OpaqueTyItem(OpaqueTy),
StaticItem(Static),
ConstantItem(Constant),
- TraitItem(Trait),
+ TraitItem(Box<Trait>),
TraitAliasItem(TraitAlias),
ImplItem(Box<Impl>),
/// A required method in a trait declaration meaning it's only a function signature.
@@ -802,6 +801,31 @@ impl ItemKind {
| KeywordItem => [].iter(),
}
}
+
+ /// Returns `true` if this item does not appear inside an impl block.
+ pub(crate) fn is_non_assoc(&self) -> bool {
+ matches!(
+ self,
+ StructItem(_)
+ | UnionItem(_)
+ | EnumItem(_)
+ | TraitItem(_)
+ | ModuleItem(_)
+ | ExternCrateItem { .. }
+ | FunctionItem(_)
+ | TypedefItem(_)
+ | OpaqueTyItem(_)
+ | StaticItem(_)
+ | ConstantItem(_)
+ | TraitAliasItem(_)
+ | ForeignFunctionItem(_)
+ | ForeignStaticItem(_)
+ | ForeignTypeItem
+ | MacroItem(_)
+ | ProcMacroItem(_)
+ | PrimitiveItem(_)
+ )
+ }
}
#[derive(Clone, Debug)]
@@ -821,8 +845,6 @@ pub(crate) trait AttributesExt {
fn inner_docs(&self) -> bool;
- fn other_attrs(&self) -> Vec<ast::Attribute>;
-
fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>>;
}
@@ -849,10 +871,6 @@ impl AttributesExt for [ast::Attribute] {
self.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == AttrStyle::Inner)
}
- fn other_attrs(&self) -> Vec<ast::Attribute> {
- self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect()
- }
-
fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
let sess = tcx.sess;
let doc_cfg_active = tcx.features().doc_cfg;
@@ -1116,7 +1134,10 @@ pub(crate) struct ItemLink {
/// This may not be the same as `link` if there was a disambiguator
/// in an intra-doc link (e.g. \[`fn@f`\])
pub(crate) link_text: String,
- pub(crate) did: DefId,
+ /// The `DefId` of the Item whose **HTML Page** contains the item being
+ /// linked to. This will be different to `item_id` on item's that don't
+ /// have their own page, such as struct fields and enum variants.
+ pub(crate) page_id: DefId,
/// The url fragment to append to the link
pub(crate) fragment: Option<UrlFragment>,
}
@@ -1137,7 +1158,7 @@ pub struct RenderedLink {
#[derive(Clone, Debug, Default)]
pub(crate) struct Attributes {
pub(crate) doc_strings: Vec<DocFragment>,
- pub(crate) other_attrs: Vec<ast::Attribute>,
+ pub(crate) other_attrs: ast::AttrVec,
}
impl Attributes {
@@ -1180,7 +1201,7 @@ impl Attributes {
doc_only: bool,
) -> Attributes {
let mut doc_strings = Vec::new();
- let mut other_attrs = Vec::new();
+ let mut other_attrs = ast::AttrVec::new();
for (attr, parent_module) in attrs {
if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
trace!("got doc_str={doc_str:?}");
@@ -1285,7 +1306,7 @@ impl 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);
+ let path = external_path(cx, did, false, ThinVec::new(), empty);
inline::record_extern_fqn(cx, did, ItemType::Trait);
GenericBound::TraitBound(
PolyTrait { trait_: path, generic_params: Vec::new() },
@@ -1557,13 +1578,7 @@ pub(crate) enum Type {
BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> },
/// A qualified path to an associated item: `<Type as Trait>::Name`
- QPath {
- assoc: Box<PathSegment>,
- self_type: Box<Type>,
- /// FIXME: compute this field on demand.
- should_show_cast: bool,
- trait_: Path,
- },
+ QPath(Box<QPathData>),
/// A type that is inferred: `_`
Infer,
@@ -1661,8 +1676,8 @@ impl Type {
}
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()))
+ if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self {
+ Some((self_type, trait_.def_id(), assoc.clone()))
} else {
None
}
@@ -1686,7 +1701,7 @@ impl Type {
Slice(..) => PrimitiveType::Slice,
Array(..) => PrimitiveType::Array,
RawPointer(..) => PrimitiveType::RawPointer,
- QPath { ref self_type, .. } => return self_type.inner_def_id(cache),
+ QPath(box QPathData { ref self_type, .. }) => return self_type.inner_def_id(cache),
Generic(_) | Infer | ImplTrait(_) => return None,
};
cache.and_then(|c| Primitive(t).def_id(c))
@@ -1700,6 +1715,15 @@ impl Type {
}
}
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub(crate) struct QPathData {
+ pub assoc: PathSegment,
+ pub self_type: Type,
+ /// FIXME: compute this field on demand.
+ pub should_show_cast: bool,
+ pub trait_: Path,
+}
+
/// A primitive (aka, builtin) type.
///
/// This represents things like `i32`, `str`, etc.
@@ -2077,7 +2101,7 @@ impl Enum {
#[derive(Clone, Debug)]
pub(crate) enum Variant {
- CLike,
+ CLike(Option<Discriminant>),
Tuple(Vec<Item>),
Struct(VariantStruct),
}
@@ -2086,11 +2110,31 @@ impl Variant {
pub(crate) fn has_stripped_entries(&self) -> Option<bool> {
match *self {
Self::Struct(ref struct_) => Some(struct_.has_stripped_entries()),
- Self::CLike | Self::Tuple(_) => None,
+ Self::CLike(..) | Self::Tuple(_) => None,
}
}
}
+#[derive(Clone, Debug)]
+pub(crate) struct Discriminant {
+ // In the case of cross crate re-exports, we don't have the nessesary information
+ // to reconstruct the expression of the discriminant, only the value.
+ pub(super) expr: Option<BodyId>,
+ pub(super) value: DefId,
+}
+
+impl Discriminant {
+ /// Will be `None` in the case of cross-crate reexports, and may be
+ /// simplified
+ pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option<String> {
+ self.expr.map(|body| print_const_expr(tcx, body))
+ }
+ /// Will always be a machine readable number, without underscores or suffixes.
+ pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> String {
+ print_evaluated_const(tcx, self.value, false).unwrap()
+ }
+}
+
/// Small wrapper around [`rustc_span::Span`] that adds helper methods
/// and enforces calling [`rustc_span::Span::source_callsite()`].
#[derive(Copy, Clone, Debug)]
@@ -2109,14 +2153,6 @@ impl Span {
self.0
}
- pub(crate) fn dummy() -> Self {
- Self(rustc_span::DUMMY_SP)
- }
-
- pub(crate) fn is_dummy(&self) -> bool {
- self.0.is_dummy()
- }
-
pub(crate) fn filename(&self, sess: &Session) -> FileName {
sess.source_map().span_to_filename(self.0)
}
@@ -2325,7 +2361,7 @@ impl ConstantKind {
match *self {
ConstantKind::TyConst { .. } | ConstantKind::Anonymous { .. } => None,
ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => {
- print_evaluated_const(tcx, def_id)
+ print_evaluated_const(tcx, def_id, true)
}
}
}
@@ -2495,14 +2531,16 @@ impl SubstParam {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
+ use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
- rustc_data_structures::static_assert_size!(Crate, 72); // frequently moved by-value
- rustc_data_structures::static_assert_size!(DocFragment, 32);
- rustc_data_structures::static_assert_size!(GenericArg, 80);
- rustc_data_structures::static_assert_size!(GenericArgs, 32);
- rustc_data_structures::static_assert_size!(GenericParamDef, 56);
- rustc_data_structures::static_assert_size!(Item, 56);
- rustc_data_structures::static_assert_size!(ItemKind, 112);
- rustc_data_structures::static_assert_size!(PathSegment, 40);
- rustc_data_structures::static_assert_size!(Type, 72);
+ static_assert_size!(Crate, 72); // frequently moved by-value
+ static_assert_size!(DocFragment, 32);
+ #[cfg(not(bootstrap))]
+ static_assert_size!(GenericArg, 56);
+ static_assert_size!(GenericArgs, 32);
+ static_assert_size!(GenericParamDef, 56);
+ static_assert_size!(Item, 56);
+ static_assert_size!(ItemKind, 96);
+ static_assert_size!(PathSegment, 40);
+ static_assert_size!(Type, 56);
}
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 43e71e90a..3eaedaf10 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -2,9 +2,9 @@ use crate::clean::auto_trait::AutoTraitFinder;
use crate::clean::blanket_impl::BlanketImplFinder;
use crate::clean::render_macro_matchers::render_macro_matcher;
use crate::clean::{
- clean_middle_const, clean_middle_region, clean_middle_ty, inline, Clean, Crate, ExternalCrate,
- Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, PathSegment,
- Primitive, PrimitiveType, Type, TypeBinding, Visibility,
+ clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
+ ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
+ PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
@@ -12,7 +12,6 @@ use crate::visit_lib::LibEmbargoVisitor;
use rustc_ast as ast;
use rustc_ast::tokenstream::TokenTree;
-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};
@@ -23,6 +22,7 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_span::symbol::{kw, sym, Symbol};
use std::fmt::Write as _;
use std::mem;
+use thin_vec::ThinVec;
#[cfg(test)]
mod tests;
@@ -37,7 +37,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
// Clean the crate, translating the entire librustc_ast AST to one that is
// understood by rustdoc.
- let mut module = module.clean(cx);
+ let mut module = clean_doc_module(&module, cx);
match *module.kind {
ItemKind::ModuleItem(ref module) => {
@@ -102,7 +102,7 @@ fn external_generic_args<'tcx>(
cx: &mut DocContext<'tcx>,
did: DefId,
has_self: bool,
- bindings: Vec<TypeBinding>,
+ bindings: ThinVec<TypeBinding>,
substs: SubstsRef<'tcx>,
) -> GenericArgs {
let args = substs_to_args(cx, substs, has_self);
@@ -112,7 +112,7 @@ fn external_generic_args<'tcx>(
// The trait's first substitution is the one after self, if there is one.
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(t, cx, None)).collect::<Vec<_>>().into(),
- _ => return GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() },
+ _ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
@@ -130,7 +130,7 @@ pub(super) fn external_path<'tcx>(
cx: &mut DocContext<'tcx>,
did: DefId,
has_self: bool,
- bindings: Vec<TypeBinding>,
+ bindings: ThinVec<TypeBinding>,
substs: SubstsRef<'tcx>,
) -> Path {
let def_kind = cx.tcx.def_kind(did);
@@ -235,14 +235,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
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() {
+ assert_eq!(promoted, ());
+ let s = if let Some(def) = def.as_local() {
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did))
} else {
inline::print_inlined_const(cx.tcx, def.did)
};
- if let Some(promoted) = promoted {
- s.push_str(&format!("::{:?}", promoted))
- }
+
s
}
_ => {
@@ -261,7 +260,11 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
}
}
-pub(crate) fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String> {
+pub(crate) fn print_evaluated_const(
+ tcx: TyCtxt<'_>,
+ def_id: DefId,
+ underscores_and_type: bool,
+) -> Option<String> {
tcx.const_eval_poly(def_id).ok().and_then(|val| {
let ty = tcx.type_of(def_id);
match (val, ty.kind()) {
@@ -269,7 +272,7 @@ pub(crate) fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<St
(ConstValue::Scalar(_), &ty::Adt(_, _)) => None,
(ConstValue::Scalar(_), _) => {
let const_ = mir::ConstantKind::from_value(val, ty);
- Some(print_const_with_custom_print_scalar(tcx, const_))
+ Some(print_const_with_custom_print_scalar(tcx, const_, underscores_and_type))
}
_ => None,
}
@@ -302,23 +305,35 @@ fn format_integer_with_underscore_sep(num: &str) -> String {
.collect()
}
-fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: mir::ConstantKind<'_>) -> String {
+fn print_const_with_custom_print_scalar(
+ tcx: TyCtxt<'_>,
+ ct: mir::ConstantKind<'_>,
+ underscores_and_type: bool,
+) -> 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, ct.ty().kind()) {
(mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Uint(ui)) => {
- format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str())
+ if underscores_and_type {
+ format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str())
+ } else {
+ int.to_string()
+ }
}
(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()),
- i.name_str()
- )
+ if underscores_and_type {
+ format!(
+ "{}{}",
+ format_integer_with_underscore_sep(&sign_extended_data.to_string()),
+ i.name_str()
+ )
+ } else {
+ sign_extended_data.to_string()
+ }
}
_ => ct.to_string(),
}
@@ -475,30 +490,14 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
use DefKind::*;
debug!("register_res({:?})", res);
- let (did, kind) = match res {
- // These should be added to the cache using `record_extern_fqn`.
+ let (kind, did) = match res {
Res::Def(
kind @ (AssocTy | AssocFn | AssocConst | Variant | Fn | TyAlias | Enum | Trait | Struct
| Union | Mod | ForeignTy | Const | Static(_) | Macro(..) | TraitAlias),
- i,
- ) => (i, kind.into()),
- // This is part of a trait definition or trait impl; document the trait.
- Res::SelfTy { trait_: Some(trait_def_id), alias_to: _ } => (trait_def_id, ItemType::Trait),
- // This is an inherent impl or a type definition; it doesn't have its own page.
- Res::SelfTy { trait_: None, alias_to: Some((item_def_id, _)) } => return item_def_id,
- Res::SelfTy { trait_: None, alias_to: None }
- | Res::PrimTy(_)
- | Res::ToolMod
- | Res::SelfCtor(_)
- | Res::Local(_)
- | Res::NonMacroAttr(_)
- | Res::Err => return res.def_id(),
- Res::Def(
- TyParam | ConstParam | Ctor(..) | ExternCrate | Use | ForeignMod | AnonConst
- | InlineConst | OpaqueTy | Field | LifetimeParam | GlobalAsm | Impl | Closure
- | Generator,
- id,
- ) => return id,
+ did,
+ ) => (kind.into(), did),
+
+ _ => panic!("register_res: unexpected {:?}", res),
};
if did.is_local() {
return did;
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 8a8cc272e..932533db0 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -412,7 +412,13 @@ impl Options {
let to_check = matches.opt_strs("check-theme");
if !to_check.is_empty() {
- let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes());
+ let paths = match theme::load_css_paths(static_files::themes::LIGHT) {
+ Ok(p) => p,
+ Err(e) => {
+ diag.struct_err(&e.to_string()).emit();
+ return Err(1);
+ }
+ };
let mut errors = 0;
println!("rustdoc: [check-theme] Starting tests! (Ignoring all other arguments)");
@@ -547,7 +553,13 @@ impl Options {
let mut themes = Vec::new();
if matches.opt_present("theme") {
- let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes());
+ let paths = match theme::load_css_paths(static_files::themes::LIGHT) {
+ Ok(p) => p,
+ Err(e) => {
+ diag.struct_err(&e.to_string()).emit();
+ return Err(1);
+ }
+ };
for (theme_file, theme_s) in
matches.opt_strs("theme").iter().map(|s| (PathBuf::from(&s), s.to_owned()))
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 35964e3ba..20ae102bc 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1289,14 +1289,9 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
});
}
- fn visit_variant(
- &mut self,
- v: &'hir hir::Variant<'_>,
- g: &'hir hir::Generics<'_>,
- item_id: hir::HirId,
- ) {
+ fn visit_variant(&mut self, v: &'hir hir::Variant<'_>) {
self.visit_testable(v.ident.to_string(), v.id, v.span, |this| {
- intravisit::walk_variant(this, v, g, item_id);
+ intravisit::walk_variant(this, v);
});
}
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 6b7e67e2c..ed702f5c4 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -46,7 +46,7 @@ pub(crate) trait DocFolder: Sized {
let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
VariantItem(Variant::Tuple(fields))
}
- Variant::CLike => VariantItem(Variant::CLike),
+ Variant::CLike(disr) => VariantItem(Variant::CLike(disr)),
},
ExternCrateItem { src: _ }
| ImportItem(_)
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 2b2691e53..86392610d 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -227,7 +227,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
if let clean::TraitItem(ref t) = *item.kind {
self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| {
clean::TraitWithExtraInfo {
- trait_: t.clone(),
+ trait_: *t.clone(),
is_notable: item.attrs.has_doc_flag(sym::notable_trait),
}
});
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index 0a7ee2005..f21e60a64 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -135,6 +135,7 @@ impl From<DefKind> for ItemType {
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
+ | DefKind::ImplTraitPlaceholder
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 36a47b05c..b499e186c 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -152,7 +152,7 @@ impl Buffer {
}
}
-fn comma_sep<T: fmt::Display>(
+pub(crate) fn comma_sep<T: fmt::Display>(
items: impl Iterator<Item = T>,
space_after_comma: bool,
) -> impl fmt::Display {
@@ -349,8 +349,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
let where_preds = comma_sep(where_predicates, false);
let clause = if f.alternate() {
if ending == Ending::Newline {
- // add a space so stripping <br> tags and breaking spaces still renders properly
- format!(" where{where_preds}, ")
+ format!(" where{where_preds},")
} else {
format!(" where{where_preds}")
}
@@ -364,20 +363,16 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
if ending == Ending::Newline {
let mut clause = "&nbsp;".repeat(indent.saturating_sub(1));
- // add a space so stripping <br> tags and breaking spaces still renders properly
- write!(
- clause,
- " <span class=\"where fmt-newline\">where{where_preds},&nbsp;</span>"
- )?;
+ write!(clause, "<span class=\"where fmt-newline\">where{where_preds},</span>")?;
clause
} else {
// insert a <br> tag after a single space but before multiple spaces at the start
if indent == 0 {
- format!(" <br><span class=\"where\">where{where_preds}</span>")
+ format!("<br><span class=\"where\">where{where_preds}</span>")
} else {
let mut clause = br_with_padding;
- clause.truncate(clause.len() - 5 * "&nbsp;".len());
- write!(clause, " <span class=\"where\">where{where_preds}</span>")?;
+ clause.truncate(clause.len() - 4 * "&nbsp;".len());
+ write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
clause
}
}
@@ -592,7 +587,7 @@ fn generate_macro_def_id_path(
}
})
.collect();
- let relative = fqp.iter().map(|elem| elem.to_string());
+ let mut 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) {
@@ -612,7 +607,7 @@ fn generate_macro_def_id_path(
let mut path = if is_macro_2 {
once(crate_name.clone()).chain(relative).collect()
} else {
- vec![crate_name.clone(), relative.last().unwrap()]
+ vec![crate_name.clone(), relative.next_back().unwrap()]
};
if path.len() < 2 {
// The minimum we can have is the crate name followed by the macro name. If shorter, then
@@ -1079,7 +1074,12 @@ fn fmt_type<'cx>(
write!(f, "impl {}", print_generic_bounds(bounds, cx))
}
}
- clean::QPath { ref assoc, ref self_type, ref trait_, should_show_cast } => {
+ clean::QPath(box clean::QPathData {
+ 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))?
@@ -1305,22 +1305,19 @@ impl clean::FnDecl {
/// <br>Used to determine line-wrapping.
/// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
/// necessary.
- /// * `asyncness`: Whether the function is async or not.
pub(crate) fn full_print<'a, 'tcx: 'a>(
&'a self,
header_len: usize,
indent: usize,
- asyncness: hir::IsAsync,
cx: &'a Context<'tcx>,
) -> impl fmt::Display + 'a + Captures<'tcx> {
- display_fn(move |f| self.inner_full_print(header_len, indent, asyncness, f, cx))
+ display_fn(move |f| self.inner_full_print(header_len, indent, f, cx))
}
fn inner_full_print(
&self,
header_len: usize,
indent: usize,
- asyncness: hir::IsAsync,
f: &mut fmt::Formatter<'_>,
cx: &Context<'_>,
) -> fmt::Result {
@@ -1385,15 +1382,9 @@ impl clean::FnDecl {
args_plain.push_str(", ...");
}
- let arrow_plain;
- let arrow = if let hir::IsAsync::Async = asyncness {
- let output = self.sugared_async_return_type();
- arrow_plain = format!("{:#}", output.print(cx));
- if f.alternate() { arrow_plain.clone() } else { format!("{}", output.print(cx)) }
- } else {
- arrow_plain = format!("{:#}", self.output.print(cx));
- if f.alternate() { arrow_plain.clone() } else { format!("{}", self.output.print(cx)) }
- };
+ let arrow_plain = format!("{:#}", self.output.print(cx));
+ let arrow =
+ if f.alternate() { arrow_plain.clone() } else { format!("{}", self.output.print(cx)) };
let declaration_len = header_len + args_plain.len() + arrow_plain.len();
let output = if declaration_len > 80 {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 05547ea15..8922bf377 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -29,31 +29,74 @@ pub(crate) struct HrefContext<'a, 'b, 'c> {
/// 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.
pub(crate) root_path: &'c str,
+ /// This field is used to calculate precise local URLs.
+ pub(crate) current_href: &'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.
+#[derive(Default)]
pub(crate) struct DecorationInfo(pub(crate) FxHashMap<&'static str, Vec<(u32, u32)>>);
-/// Highlights `src`, returning the HTML output.
-pub(crate) fn render_with_highlighting(
+#[derive(Eq, PartialEq, Clone, Copy)]
+pub(crate) enum Tooltip {
+ Ignore,
+ CompileFail,
+ ShouldPanic,
+ Edition(Edition),
+ None,
+}
+
+/// Highlights `src` as an inline example, returning the HTML output.
+pub(crate) fn render_example_with_highlighting(
src: &str,
out: &mut Buffer,
- class: Option<&str>,
+ tooltip: Tooltip,
playground_button: Option<&str>,
- tooltip: Option<(Option<Edition>, &str)>,
- edition: Edition,
- extra_content: Option<Buffer>,
- href_context: Option<HrefContext<'_, '_, '_>>,
- decoration_info: Option<DecorationInfo>,
) {
- debug!("highlighting: ================\n{}\n==============", src);
- if let Some((edition_info, class)) = tooltip {
+ write_header(out, "rust-example-rendered", None, tooltip);
+ write_code(out, src, None, None);
+ write_footer(out, playground_button);
+}
+
+/// Highlights `src` as a macro, returning the HTML output.
+pub(crate) fn render_macro_with_highlighting(src: &str, out: &mut Buffer) {
+ write_header(out, "macro", None, Tooltip::None);
+ write_code(out, src, None, None);
+ write_footer(out, None);
+}
+
+/// Highlights `src` as a source code page, returning the HTML output.
+pub(crate) fn render_source_with_highlighting(
+ src: &str,
+ out: &mut Buffer,
+ line_numbers: Buffer,
+ href_context: HrefContext<'_, '_, '_>,
+ decoration_info: DecorationInfo,
+) {
+ write_header(out, "", Some(line_numbers), Tooltip::None);
+ write_code(out, src, Some(href_context), Some(decoration_info));
+ write_footer(out, None);
+}
+
+fn write_header(out: &mut Buffer, class: &str, extra_content: Option<Buffer>, tooltip: Tooltip) {
+ write!(
+ out,
+ "<div class=\"example-wrap{}\">",
+ match tooltip {
+ Tooltip::Ignore => " ignore",
+ Tooltip::CompileFail => " compile_fail",
+ Tooltip::ShouldPanic => " should_panic",
+ Tooltip::Edition(_) => " edition",
+ Tooltip::None => "",
+ },
+ );
+
+ if tooltip != Tooltip::None {
write!(
out,
- "<div class='information'><div class='tooltip {}'{}>ⓘ</div></div>",
- class,
- if let Some(edition_info) = edition_info {
+ "<div class='tooltip'{}>ⓘ</div>",
+ if let Tooltip::Edition(edition_info) = tooltip {
format!(" data-edition=\"{}\"", edition_info)
} else {
String::new()
@@ -61,24 +104,115 @@ pub(crate) fn render_with_highlighting(
);
}
- write_header(out, class, extra_content);
- write_code(out, src, edition, href_context, decoration_info);
- write_footer(out, playground_button);
-}
-
-fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buffer>) {
- write!(out, "<div class=\"example-wrap\">");
if let Some(extra) = extra_content {
out.push_buffer(extra);
}
- if let Some(class) = class {
- write!(out, "<pre class=\"rust {}\">", class);
- } else {
+ if class.is_empty() {
write!(out, "<pre class=\"rust\">");
+ } else {
+ write!(out, "<pre class=\"rust {class}\">");
}
write!(out, "<code>");
}
+/// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None`
+/// basically (since it's `Option<Class>`). The following rules apply:
+///
+/// * If two `Class` have the same variant, then they can be merged.
+/// * If the other `Class` is unclassified and only contains white characters (backline,
+/// whitespace, etc), it can be merged.
+/// * `Class::Ident` is considered the same as unclassified (because it doesn't have an associated
+/// CSS class).
+fn can_merge(class1: Option<Class>, class2: Option<Class>, text: &str) -> bool {
+ match (class1, class2) {
+ (Some(c1), Some(c2)) => c1.is_equal_to(c2),
+ (Some(Class::Ident(_)), None) | (None, Some(Class::Ident(_))) => true,
+ (Some(_), None) | (None, Some(_)) => text.trim().is_empty(),
+ (None, None) => true,
+ }
+}
+
+/// This type is used as a conveniency to prevent having to pass all its fields as arguments into
+/// the various functions (which became its methods).
+struct TokenHandler<'a, 'b, 'c, 'd, 'e> {
+ out: &'a mut Buffer,
+ /// It contains the closing tag and the associated `Class`.
+ closing_tags: Vec<(&'static str, Class)>,
+ /// This is used because we don't automatically generate the closing tag on `ExitSpan` in
+ /// case an `EnterSpan` event with the same class follows.
+ pending_exit_span: Option<Class>,
+ /// `current_class` and `pending_elems` are used to group HTML elements with same `class`
+ /// attributes to reduce the DOM size.
+ current_class: Option<Class>,
+ /// We need to keep the `Class` for each element because it could contain a `Span` which is
+ /// used to generate links.
+ pending_elems: Vec<(&'b str, Option<Class>)>,
+ href_context: Option<HrefContext<'c, 'd, 'e>>,
+}
+
+impl<'a, 'b, 'c, 'd, 'e> TokenHandler<'a, 'b, 'c, 'd, 'e> {
+ fn handle_exit_span(&mut self) {
+ // We can't get the last `closing_tags` element using `pop()` because `closing_tags` is
+ // being used in `write_pending_elems`.
+ let class = self.closing_tags.last().expect("ExitSpan without EnterSpan").1;
+ // We flush everything just in case...
+ self.write_pending_elems(Some(class));
+
+ exit_span(self.out, self.closing_tags.pop().expect("ExitSpan without EnterSpan").0);
+ self.pending_exit_span = None;
+ }
+
+ /// Write all the pending elements sharing a same (or at mergeable) `Class`.
+ ///
+ /// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged
+ /// with the elements' class, then we simply write the elements since the `ExitSpan` event will
+ /// close the tag.
+ ///
+ /// Otherwise, if there is only one pending element, we let the `string` function handle both
+ /// opening and closing the tag, otherwise we do it into this function.
+ ///
+ /// It returns `true` if `current_class` must be set to `None` afterwards.
+ fn write_pending_elems(&mut self, current_class: Option<Class>) -> bool {
+ if self.pending_elems.is_empty() {
+ return false;
+ }
+ if let Some((_, parent_class)) = self.closing_tags.last() &&
+ can_merge(current_class, Some(*parent_class), "")
+ {
+ for (text, class) in self.pending_elems.iter() {
+ string(self.out, Escape(text), *class, &self.href_context, false);
+ }
+ } else {
+ // We only want to "open" the tag ourselves if we have more than one pending and if the
+ // current parent tag is not the same as our pending content.
+ let close_tag = if self.pending_elems.len() > 1 && current_class.is_some() {
+ Some(enter_span(self.out, current_class.unwrap(), &self.href_context))
+ } else {
+ None
+ };
+ for (text, class) in self.pending_elems.iter() {
+ string(self.out, Escape(text), *class, &self.href_context, close_tag.is_none());
+ }
+ if let Some(close_tag) = close_tag {
+ exit_span(self.out, close_tag);
+ }
+ }
+ self.pending_elems.clear();
+ true
+ }
+}
+
+impl<'a, 'b, 'c, 'd, 'e> Drop for TokenHandler<'a, 'b, 'c, 'd, 'e> {
+ /// When leaving, we need to flush all pending data to not have missing content.
+ fn drop(&mut self) {
+ if self.pending_exit_span.is_some() {
+ self.handle_exit_span();
+ } else {
+ self.write_pending_elems(self.current_class);
+ }
+ }
+}
+
/// Convert the given `src` source code into HTML by adding classes for highlighting.
///
/// This code is used to render code blocks (in the documentation) as well as the source code pages.
@@ -93,27 +227,74 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
fn write_code(
out: &mut Buffer,
src: &str,
- edition: Edition,
href_context: Option<HrefContext<'_, '_, '_>>,
decoration_info: Option<DecorationInfo>,
) {
// 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();
+ let mut token_handler = TokenHandler {
+ out,
+ closing_tags: Vec::new(),
+ pending_exit_span: None,
+ current_class: None,
+ pending_elems: Vec::new(),
+ href_context,
+ };
+
Classifier::new(
&src,
- edition,
- href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP),
+ token_handler.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, &href_context),
+ Highlight::Token { text, class } => {
+ // If we received a `ExitSpan` event and then have a non-compatible `Class`, we
+ // need to close the `<span>`.
+ let need_current_class_update = if let Some(pending) = token_handler.pending_exit_span &&
+ !can_merge(Some(pending), class, text) {
+ token_handler.handle_exit_span();
+ true
+ // If the two `Class` are different, time to flush the current content and start
+ // a new one.
+ } else if !can_merge(token_handler.current_class, class, text) {
+ token_handler.write_pending_elems(token_handler.current_class);
+ true
+ } else {
+ token_handler.current_class.is_none()
+ };
+
+ if need_current_class_update {
+ token_handler.current_class = class.map(Class::dummy);
+ }
+ token_handler.pending_elems.push((text, class));
+ }
Highlight::EnterSpan { class } => {
- closing_tags.push(enter_span(out, class, &href_context))
+ let mut should_add = true;
+ if let Some(pending_exit_span) = token_handler.pending_exit_span {
+ if class.is_equal_to(pending_exit_span) {
+ should_add = false;
+ } else {
+ token_handler.handle_exit_span();
+ }
+ } else {
+ // We flush everything just in case...
+ if token_handler.write_pending_elems(token_handler.current_class) {
+ token_handler.current_class = None;
+ }
+ }
+ if should_add {
+ let closing_tag = enter_span(token_handler.out, class, &token_handler.href_context);
+ token_handler.closing_tags.push((closing_tag, class));
+ }
+
+ token_handler.current_class = None;
+ token_handler.pending_exit_span = None;
}
Highlight::ExitSpan => {
- exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan"))
+ token_handler.current_class = None;
+ token_handler.pending_exit_span =
+ Some(token_handler.closing_tags.last().as_ref().expect("ExitSpan without EnterSpan").1);
}
};
});
@@ -130,15 +311,15 @@ enum Class {
DocComment,
Attribute,
KeyWord,
- // Keywords that do pointer/reference stuff.
+ /// Keywords that do pointer/reference stuff.
RefKeyWord,
Self_(Span),
- Op,
Macro(Span),
MacroNonTerminal,
String,
Number,
Bool,
+ /// `Ident` isn't rendered in the HTML but we still need it for the `Span` it contains.
Ident(Span),
Lifetime,
PreludeTy,
@@ -148,6 +329,31 @@ enum Class {
}
impl Class {
+ /// It is only looking at the variant, not the variant content.
+ ///
+ /// It is used mostly to group multiple similar HTML elements into one `<span>` instead of
+ /// multiple ones.
+ fn is_equal_to(self, other: Self) -> bool {
+ match (self, other) {
+ (Self::Self_(_), Self::Self_(_))
+ | (Self::Macro(_), Self::Macro(_))
+ | (Self::Ident(_), Self::Ident(_)) => true,
+ (Self::Decoration(c1), Self::Decoration(c2)) => c1 == c2,
+ (x, y) => x == y,
+ }
+ }
+
+ /// If `self` contains a `Span`, it'll be replaced with `DUMMY_SP` to prevent creating links
+ /// on "empty content" (because of the attributes merge).
+ fn dummy(self) -> Self {
+ match self {
+ Self::Self_(_) => Self::Self_(DUMMY_SP),
+ Self::Macro(_) => Self::Macro(DUMMY_SP),
+ Self::Ident(_) => Self::Ident(DUMMY_SP),
+ s => s,
+ }
+ }
+
/// Returns the css class expected by rustdoc for each `Class`.
fn as_html(self) -> &'static str {
match self {
@@ -157,13 +363,12 @@ impl Class {
Class::KeyWord => "kw",
Class::RefKeyWord => "kw-2",
Class::Self_(_) => "self",
- Class::Op => "op",
Class::Macro(_) => "macro",
Class::MacroNonTerminal => "macro-nonterminal",
Class::String => "string",
Class::Number => "number",
Class::Bool => "bool-val",
- Class::Ident(_) => "ident",
+ Class::Ident(_) => "",
Class::Lifetime => "lifetime",
Class::PreludeTy => "prelude-ty",
Class::PreludeVal => "prelude-val",
@@ -182,7 +387,6 @@ impl Class {
| Self::Attribute
| Self::KeyWord
| Self::RefKeyWord
- | Self::Op
| Self::MacroNonTerminal
| Self::String
| Self::Number
@@ -220,7 +424,7 @@ impl<'a> Iterator for TokenIter<'a> {
}
/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
-fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool) -> Option<Class> {
+fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option<Class> {
let ignore: &[&str] =
if allow_path_keywords { &["self", "Self", "super", "crate"] } else { &["self", "Self"] };
if ignore.iter().any(|k| *k == text) {
@@ -229,7 +433,7 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
Some(match text {
"ref" | "mut" => Class::RefKeyWord,
"false" | "true" => Class::Bool,
- _ if Symbol::intern(text).is_reserved(|| edition) => Class::KeyWord,
+ _ if Symbol::intern(text).is_reserved(|| Edition::Edition2021) => Class::KeyWord,
_ => return None,
})
}
@@ -250,7 +454,7 @@ impl<'a> PeekIter<'a> {
fn new(iter: TokenIter<'a>) -> Self {
Self { stored: VecDeque::new(), peek_pos: 0, iter }
}
- /// Returns the next item after the current one. It doesn't interfer with `peek_next` output.
+ /// Returns the next item after the current one. It doesn't interfere with `peek_next` output.
fn peek(&mut self) -> Option<&(TokenKind, &'a str)> {
if self.stored.is_empty() {
if let Some(next) = self.iter.next() {
@@ -259,7 +463,7 @@ impl<'a> PeekIter<'a> {
}
self.stored.front()
}
- /// Returns the next item after the last one peeked. It doesn't interfer with `peek` output.
+ /// Returns the next item after the last one peeked. It doesn't interfere with `peek` output.
fn peek_next(&mut self) -> Option<&(TokenKind, &'a str)> {
self.peek_pos += 1;
if self.peek_pos - 1 < self.stored.len() {
@@ -311,7 +515,6 @@ struct Classifier<'a> {
in_attribute: bool,
in_macro: bool,
in_macro_nonterminal: bool,
- edition: Edition,
byte_pos: u32,
file_span: Span,
src: &'a str,
@@ -321,12 +524,7 @@ struct Classifier<'a> {
impl<'a> Classifier<'a> {
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
/// file span which will be used later on by the `span_correspondance_map`.
- fn new(
- src: &str,
- edition: Edition,
- file_span: Span,
- decoration_info: Option<DecorationInfo>,
- ) -> Classifier<'_> {
+ fn new(src: &str, file_span: Span, decoration_info: Option<DecorationInfo>) -> Classifier<'_> {
let tokens = PeekIter::new(TokenIter { src });
let decorations = decoration_info.map(Decorations::new);
Classifier {
@@ -334,7 +532,6 @@ impl<'a> Classifier<'a> {
in_attribute: false,
in_macro: false,
in_macro_nonterminal: false,
- edition,
byte_pos: 0,
file_span,
src,
@@ -354,7 +551,6 @@ impl<'a> Classifier<'a> {
let start = self.byte_pos as usize;
let mut pos = start;
let mut has_ident = false;
- let edition = self.edition;
loop {
let mut nb = 0;
@@ -376,7 +572,7 @@ impl<'a> Classifier<'a> {
if let Some((None, text)) = self.tokens.peek().map(|(token, text)| {
if *token == TokenKind::Ident {
- let class = get_real_ident_class(text, edition, true);
+ let class = get_real_ident_class(text, true);
(class, text)
} else {
// Doesn't matter which Class we put in here...
@@ -494,7 +690,7 @@ impl<'a> Classifier<'a> {
// or a reference or pointer type. Unless, of course, it looks like
// a logical and or a multiplication operator: `&&` or `* `.
TokenKind::Star => match self.tokens.peek() {
- Some((TokenKind::Whitespace, _)) => Class::Op,
+ Some((TokenKind::Whitespace, _)) => return no_highlight(sink),
Some((TokenKind::Ident, "mut")) => {
self.next();
sink(Highlight::Token { text: "*mut", class: Some(Class::RefKeyWord) });
@@ -510,15 +706,15 @@ impl<'a> Classifier<'a> {
TokenKind::And => match self.tokens.peek() {
Some((TokenKind::And, _)) => {
self.next();
- sink(Highlight::Token { text: "&&", class: Some(Class::Op) });
+ sink(Highlight::Token { text: "&&", class: None });
return;
}
Some((TokenKind::Eq, _)) => {
self.next();
- sink(Highlight::Token { text: "&=", class: Some(Class::Op) });
+ sink(Highlight::Token { text: "&=", class: None });
return;
}
- Some((TokenKind::Whitespace, _)) => Class::Op,
+ Some((TokenKind::Whitespace, _)) => return no_highlight(sink),
Some((TokenKind::Ident, "mut")) => {
self.next();
sink(Highlight::Token { text: "&mut", class: Some(Class::RefKeyWord) });
@@ -531,7 +727,7 @@ impl<'a> Classifier<'a> {
TokenKind::Eq => match lookahead {
Some(TokenKind::Eq) => {
self.next();
- sink(Highlight::Token { text: "==", class: Some(Class::Op) });
+ sink(Highlight::Token { text: "==", class: None });
return;
}
Some(TokenKind::Gt) => {
@@ -539,7 +735,7 @@ impl<'a> Classifier<'a> {
sink(Highlight::Token { text: "=>", class: None });
return;
}
- _ => Class::Op,
+ _ => return no_highlight(sink),
},
TokenKind::Minus if lookahead == Some(TokenKind::Gt) => {
self.next();
@@ -556,7 +752,7 @@ impl<'a> Classifier<'a> {
| TokenKind::Percent
| TokenKind::Bang
| TokenKind::Lt
- | TokenKind::Gt => Class::Op,
+ | TokenKind::Gt => return no_highlight(sink),
// Miscellaneous, no highlighting.
TokenKind::Dot
@@ -634,7 +830,7 @@ impl<'a> Classifier<'a> {
sink(Highlight::Token { text, class: None });
return;
}
- TokenKind::Ident => match get_real_ident_class(text, self.edition, false) {
+ TokenKind::Ident => match get_real_ident_class(text, false) {
None => match text {
"Option" | "Result" => Class::PreludeTy,
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
@@ -682,7 +878,7 @@ fn enter_span(
klass: Class,
href_context: &Option<HrefContext<'_, '_, '_>>,
) -> &'static str {
- string_without_closing_tag(out, "", Some(klass), href_context).expect(
+ string_without_closing_tag(out, "", Some(klass), href_context, true).expect(
"internal error: enter_span was called with Some(klass) but did not return a \
closing HTML tag",
)
@@ -714,8 +910,10 @@ fn string<T: Display>(
text: T,
klass: Option<Class>,
href_context: &Option<HrefContext<'_, '_, '_>>,
+ open_tag: bool,
) {
- if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context) {
+ if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context, open_tag)
+ {
out.write_str(closing_tag);
}
}
@@ -734,6 +932,7 @@ fn string_without_closing_tag<T: Display>(
text: T,
klass: Option<Class>,
href_context: &Option<HrefContext<'_, '_, '_>>,
+ open_tag: bool,
) -> Option<&'static str> {
let Some(klass) = klass
else {
@@ -742,6 +941,10 @@ fn string_without_closing_tag<T: Display>(
};
let Some(def_span) = klass.get_span()
else {
+ if !open_tag {
+ write!(out, "{}", text);
+ return None;
+ }
write!(out, "<span class=\"{}\">{}", klass.as_html(), text);
return Some("</span>");
};
@@ -765,6 +968,7 @@ fn string_without_closing_tag<T: Display>(
path
});
}
+
if let Some(href_context) = href_context {
if let Some(href) =
href_context.context.shared.span_correspondance_map.get(&def_span).and_then(|href| {
@@ -775,9 +979,9 @@ fn string_without_closing_tag<T: Display>(
// a link to their definition can be generated using this:
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
match href {
- LinkFromSrc::Local(span) => context
- .href_from_span(*span, true)
- .map(|s| format!("{}{}", href_context.root_path, s)),
+ LinkFromSrc::Local(span) => {
+ context.href_from_span_relative(*span, href_context.current_href)
+ }
LinkFromSrc::External(def_id) => {
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
.ok()
@@ -793,12 +997,33 @@ fn string_without_closing_tag<T: Display>(
}
})
{
- write!(out, "<a class=\"{}\" href=\"{}\">{}", klass.as_html(), href, text_s);
+ if !open_tag {
+ // We're already inside an element which has the same klass, no need to give it
+ // again.
+ write!(out, "<a href=\"{}\">{}", href, text_s);
+ } else {
+ let klass_s = klass.as_html();
+ if klass_s.is_empty() {
+ write!(out, "<a href=\"{}\">{}", href, text_s);
+ } else {
+ write!(out, "<a class=\"{}\" href=\"{}\">{}", klass_s, href, text_s);
+ }
+ }
return Some("</a>");
}
}
- write!(out, "<span class=\"{}\">{}", klass.as_html(), text_s);
- Some("</span>")
+ if !open_tag {
+ write!(out, "{}", text_s);
+ return None;
+ }
+ let klass_s = klass.as_html();
+ if klass_s.is_empty() {
+ write!(out, "{}", text_s);
+ Some("")
+ } else {
+ write!(out, "<span class=\"{}\">{}", klass_s, text_s);
+ Some("</span>")
+ }
}
#[cfg(test)]
diff --git a/src/librustdoc/html/highlight/fixtures/decorations.html b/src/librustdoc/html/highlight/fixtures/decorations.html
index 45f567880..ebf29f9cb 100644
--- a/src/librustdoc/html/highlight/fixtures/decorations.html
+++ b/src/librustdoc/html/highlight/fixtures/decorations.html
@@ -1,2 +1,4 @@
-<span class="example"><span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="number">1</span>;</span>
-<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="number">2</span>; \ No newline at end of file
+<span class="example"><span class="kw">let </span>x = <span class="number">1</span>;
+<span class="kw">let </span>y = <span class="number">2</span>;
+</span><span class="example2"><span class="kw">let </span>z = <span class="number">3</span>;
+</span><span class="kw">let </span>a = <span class="number">4</span>; \ No newline at end of file
diff --git a/src/librustdoc/html/highlight/fixtures/dos_line.html b/src/librustdoc/html/highlight/fixtures/dos_line.html
index 1c8dbffe7..30b50ca7c 100644
--- a/src/librustdoc/html/highlight/fixtures/dos_line.html
+++ b/src/librustdoc/html/highlight/fixtures/dos_line.html
@@ -1,3 +1,3 @@
-<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">foo</span>() {
+<span class="kw">pub fn </span>foo() {
<span class="macro">println!</span>(<span class="string">&quot;foo&quot;</span>);
}
diff --git a/src/librustdoc/html/highlight/fixtures/highlight.html b/src/librustdoc/html/highlight/fixtures/highlight.html
index abc2db179..9f73e03f9 100644
--- a/src/librustdoc/html/highlight/fixtures/highlight.html
+++ b/src/librustdoc/html/highlight/fixtures/highlight.html
@@ -1,4 +1,4 @@
-<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::a::foo</span>;
-<span class="kw">use</span> <span class="ident"><span class="self">self</span>::whatever</span>;
-<span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="ident"><span class="kw">super</span>::b::foo</span>;
-<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="ident"><span class="self">Self</span>::whatever</span>; \ No newline at end of file
+<span class="kw">use </span><span class="kw">crate</span>::a::foo;
+<span class="kw">use </span><span class="self">self</span>::whatever;
+<span class="kw">let </span>x = <span class="kw">super</span>::b::foo;
+<span class="kw">let </span>y = <span class="self">Self</span>::whatever; \ No newline at end of file
diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html
index b117a12e3..4a5a3cf60 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.html
+++ b/src/librustdoc/html/highlight/fixtures/sample.html
@@ -8,30 +8,31 @@
.lifetime { color: #B76514; }
.question-mark { color: #ff9011; }
</style>
-<pre><code><span class="attribute">#![<span class="ident">crate_type</span> <span class="op">=</span> <span class="string">&quot;lib&quot;</span>]</span>
+<pre><code><span class="attribute">#![crate_type = <span class="string">&quot;lib&quot;</span>]
-<span class="kw">use</span> <span class="ident">std::path</span>::{<span class="ident">Path</span>, <span class="ident">PathBuf</span>};
+</span><span class="kw">use </span>std::path::{Path, PathBuf};
-<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">&quot;linux&quot;</span>)]</span>
-<span class="kw">fn</span> <span class="ident">main</span>() -&gt; () {
- <span class="kw">let</span> <span class="ident">foo</span> <span class="op">=</span> <span class="bool-val">true</span> <span class="op">&amp;&amp;</span> <span class="bool-val">false</span> <span class="op">|</span><span class="op">|</span> <span class="bool-val">true</span>;
- <span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">*const</span> () <span class="op">=</span> <span class="number">0</span>;
- <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="ident">foo</span>;
- <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="op">&amp;&amp;</span><span class="ident">foo</span>;
- <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">*</span><span class="ident">foo</span>;
- <span class="macro">mac!</span>(<span class="ident">foo</span>, <span class="kw-2">&amp;mut</span> <span class="ident">bar</span>);
- <span class="macro">assert!</span>(<span class="self">self</span>.<span class="ident">length</span> <span class="op">&lt;</span> <span class="ident">N</span> <span class="op">&amp;&amp;</span> <span class="ident">index</span> <span class="op">&lt;</span><span class="op">=</span> <span class="self">self</span>.<span class="ident">length</span>);
- <span class="ident">::std::env::var</span>(<span class="string">&quot;gateau&quot;</span>).<span class="ident">is_ok</span>();
- <span class="attribute">#[<span class="ident">rustfmt::skip</span>]</span>
- <span class="kw">let</span> <span class="ident">s</span>:<span class="ident">std::path::PathBuf</span> <span class="op">=</span> <span class="ident">std::path::PathBuf::new</span>();
- <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">String::new</span>();
+<span class="attribute">#[cfg(target_os = <span class="string">&quot;linux&quot;</span>)]
+#[cfg(target_os = <span class="string">&quot;windows&quot;</span>)]
+</span><span class="kw">fn </span>main() -&gt; () {
+ <span class="kw">let </span>foo = <span class="bool-val">true </span>&amp;&amp; <span class="bool-val">false </span>|| <span class="bool-val">true</span>;
+ <span class="kw">let _</span>: <span class="kw-2">*const </span>() = <span class="number">0</span>;
+ <span class="kw">let _ </span>= <span class="kw-2">&amp;</span>foo;
+ <span class="kw">let _ </span>= &amp;&amp;foo;
+ <span class="kw">let _ </span>= <span class="kw-2">*</span>foo;
+ <span class="macro">mac!</span>(foo, <span class="kw-2">&amp;mut </span>bar);
+ <span class="macro">assert!</span>(<span class="self">self</span>.length &lt; N &amp;&amp; index &lt;= <span class="self">self</span>.length);
+ ::std::env::var(<span class="string">&quot;gateau&quot;</span>).is_ok();
+ <span class="attribute">#[rustfmt::skip]
+ </span><span class="kw">let </span>s:std::path::PathBuf = std::path::PathBuf::new();
+ <span class="kw">let </span><span class="kw-2">mut </span>s = String::new();
- <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">s</span> {
- <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> =&gt; {}
+ <span class="kw">match </span><span class="kw-2">&amp;</span>s {
+ <span class="kw-2">ref mut </span>x =&gt; {}
}
}
-<span class="macro">macro_rules!</span> <span class="ident">bar</span> {
- (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) =&gt; {};
+<span class="macro">macro_rules! </span>bar {
+ (<span class="macro-nonterminal">$foo</span>:tt) =&gt; {};
}
</code></pre>
diff --git a/src/librustdoc/html/highlight/fixtures/sample.rs b/src/librustdoc/html/highlight/fixtures/sample.rs
index fbfdc6767..ef85b566c 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.rs
+++ b/src/librustdoc/html/highlight/fixtures/sample.rs
@@ -3,6 +3,7 @@
use std::path::{Path, PathBuf};
#[cfg(target_os = "linux")]
+#[cfg(target_os = "windows")]
fn main() -> () {
let foo = true && false || true;
let _: *const () = 0;
diff --git a/src/librustdoc/html/highlight/fixtures/union.html b/src/librustdoc/html/highlight/fixtures/union.html
index c0acf31a0..9f8915282 100644
--- a/src/librustdoc/html/highlight/fixtures/union.html
+++ b/src/librustdoc/html/highlight/fixtures/union.html
@@ -1,8 +1,8 @@
-<span class="kw">union</span> <span class="ident">Foo</span> {
- <span class="ident">i</span>: <span class="ident">i8</span>,
- <span class="ident">u</span>: <span class="ident">i8</span>,
+<span class="kw">union </span>Foo {
+ i: i8,
+ u: i8,
}
-<span class="kw">fn</span> <span class="ident">main</span>() {
- <span class="kw">let</span> <span class="ident">union</span> <span class="op">=</span> <span class="number">0</span>;
+<span class="kw">fn </span>main() {
+ <span class="kw">let </span>union = <span class="number">0</span>;
}
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index 1fea7e983..a5e633df4 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -3,7 +3,6 @@ use crate::html::format::Buffer;
use expect_test::expect_file;
use rustc_data_structures::fx::FxHashMap;
use rustc_span::create_default_session_globals_then;
-use rustc_span::edition::Edition;
const STYLE: &str = r#"
<style>
@@ -23,7 +22,7 @@ fn test_html_highlighting() {
let src = include_str!("fixtures/sample.rs");
let html = {
let mut out = Buffer::new();
- write_code(&mut out, src, Edition::Edition2018, None, None);
+ write_code(&mut out, src, None, None);
format!("{}<pre><code>{}</code></pre>\n", STYLE, out.into_inner())
};
expect_file!["fixtures/sample.html"].assert_eq(&html);
@@ -37,7 +36,7 @@ fn test_dos_backline() {
println!(\"foo\");\r\n\
}\r\n";
let mut html = Buffer::new();
- write_code(&mut html, src, Edition::Edition2018, None, None);
+ write_code(&mut html, src, None, None);
expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner());
});
}
@@ -51,7 +50,7 @@ let x = super::b::foo;
let y = Self::whatever;";
let mut html = Buffer::new();
- write_code(&mut html, src, Edition::Edition2018, None, None);
+ write_code(&mut html, src, None, None);
expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner());
});
}
@@ -61,7 +60,7 @@ fn test_union_highlighting() {
create_default_session_globals_then(|| {
let src = include_str!("fixtures/union.rs");
let mut html = Buffer::new();
- write_code(&mut html, src, Edition::Edition2018, None, None);
+ write_code(&mut html, src, None, None);
expect_file!["fixtures/union.html"].assert_eq(&html.into_inner());
});
}
@@ -70,12 +69,15 @@ fn test_union_highlighting() {
fn test_decorations() {
create_default_session_globals_then(|| {
let src = "let x = 1;
-let y = 2;";
+let y = 2;
+let z = 3;
+let a = 4;";
let mut decorations = FxHashMap::default();
- decorations.insert("example", vec![(0, 10)]);
+ decorations.insert("example", vec![(0, 10), (11, 21)]);
+ decorations.insert("example2", vec![(22, 32)]);
let mut html = Buffer::new();
- write_code(&mut html, src, Edition::Edition2018, None, Some(DecorationInfo(decorations)));
+ write_code(&mut html, src, None, Some(DecorationInfo(decorations)));
expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner());
});
}
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 52a2effca..43d07d4a5 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -330,34 +330,27 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
});
let tooltip = if ignore != Ignore::None {
- Some((None, "ignore"))
+ highlight::Tooltip::Ignore
} else if compile_fail {
- Some((None, "compile_fail"))
+ highlight::Tooltip::CompileFail
} else if should_panic {
- Some((None, "should_panic"))
+ highlight::Tooltip::ShouldPanic
} else if explicit_edition {
- Some((Some(edition), "edition"))
+ highlight::Tooltip::Edition(edition)
} else {
- None
+ highlight::Tooltip::None
};
// insert newline to clearly separate it from the
// previous block so we can shorten the html output
let mut s = Buffer::new();
s.push_str("\n");
- highlight::render_with_highlighting(
+
+ highlight::render_example_with_highlighting(
&text,
&mut s,
- Some(&format!(
- "rust-example-rendered{}",
- if let Some((_, class)) = tooltip { format!(" {}", class) } else { String::new() }
- )),
- playground_button.as_deref(),
tooltip,
- edition,
- None,
- None,
- None,
+ playground_button.as_deref(),
);
Some(Event::Html(s.into_inner().into()))
}
@@ -1126,7 +1119,11 @@ impl MarkdownSummaryLine<'_> {
let mut s = String::new();
- html::push_html(&mut s, LinkReplacer::new(SummaryLine::new(p), links));
+ let without_paragraphs = LinkReplacer::new(SummaryLine::new(p), links).filter(|event| {
+ !matches!(event, Event::Start(Tag::Paragraph) | Event::End(Tag::Paragraph))
+ });
+
+ html::push_html(&mut s, without_paragraphs);
s
}
@@ -1446,6 +1443,8 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
map.insert("not-displayed".into(), 1);
map.insert("alternative-display".into(), 1);
map.insert("search".into(), 1);
+ map.insert("crate-search".into(), 1);
+ map.insert("crate-search-div".into(), 1);
// This is the list of IDs used in HTML generated in Rust (including the ones
// used in tera template files).
map.insert("mainThemeStyle".into(), 1);
@@ -1453,7 +1452,6 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
map.insert("settings-menu".into(), 1);
map.insert("help-button".into(), 1);
map.insert("main-content".into(), 1);
- map.insert("crate-search".into(), 1);
map.insert("toggle-all-docs".into(), 1);
map.insert("all-types".into(), 1);
map.insert("default-settings".into(), 1);
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 2ed7a6f1b..62def4a94 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -31,6 +31,7 @@ use crate::formats::FormatRenderer;
use crate::html::escape::Escape;
use crate::html::format::{join_with_double_colon, Buffer};
use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
+use crate::html::url_parts_builder::UrlPartsBuilder;
use crate::html::{layout, sources};
use crate::scrape_examples::AllCallLocations;
use crate::try_err;
@@ -71,7 +72,7 @@ pub(crate) struct Context<'tcx> {
}
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(not(windows), target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Context<'_>, 128);
/// Shared mutable state used in [`Context`] and elsewhere.
@@ -301,13 +302,10 @@ impl<'tcx> Context<'tcx> {
/// may happen, for example, with externally inlined items where the source
/// of their crate documentation isn't known.
pub(super) fn src_href(&self, item: &clean::Item) -> Option<String> {
- self.href_from_span(item.span(self.tcx()), true)
+ self.href_from_span(item.span(self.tcx())?, true)
}
pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
- if span.is_dummy() {
- return None;
- }
let mut root = self.root_path();
let mut path = String::new();
let cnum = span.cnum(self.sess());
@@ -373,6 +371,35 @@ impl<'tcx> Context<'tcx> {
anchor = anchor
))
}
+
+ pub(crate) fn href_from_span_relative(
+ &self,
+ span: clean::Span,
+ relative_to: &str,
+ ) -> Option<String> {
+ self.href_from_span(span, false).map(|s| {
+ let mut url = UrlPartsBuilder::new();
+ let mut dest_href_parts = s.split('/');
+ let mut cur_href_parts = relative_to.split('/');
+ for (cur_href_part, dest_href_part) in (&mut cur_href_parts).zip(&mut dest_href_parts) {
+ if cur_href_part != dest_href_part {
+ url.push(dest_href_part);
+ break;
+ }
+ }
+ for dest_href_part in dest_href_parts {
+ url.push(dest_href_part);
+ }
+ let loline = span.lo(self.sess()).line;
+ let hiline = span.hi(self.sess()).line;
+ format!(
+ "{}{}#{}",
+ "../".repeat(cur_href_parts.count()),
+ url.finish(),
+ if loline == hiline { loline.to_string() } else { format!("{loline}-{hiline}") }
+ )
+ })
+ }
}
/// Generates the documentation for `crate` into the directory `dst`
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index a262c8f7d..1e6f20d2b 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -191,12 +191,6 @@ impl StylePath {
}
}
-fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) {
- if let Some(l) = cx.src_href(item) {
- write!(buf, "<a class=\"srclink\" href=\"{}\">source</a>", l)
- }
-}
-
#[derive(Debug, Eq, PartialEq, Hash)]
struct ItemEntry {
url: String,
@@ -522,7 +516,14 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<Strin
(cfg, _) => cfg.as_deref().cloned(),
};
- debug!("Portability {:?} - {:?} = {:?}", item.cfg, parent.and_then(|p| p.cfg.as_ref()), cfg);
+ debug!(
+ "Portability {:?} {:?} (parent: {:?}) - {:?} = {:?}",
+ item.name,
+ item.cfg,
+ parent,
+ parent.and_then(|p| p.cfg.as_ref()),
+ cfg
+ );
Some(format!("<div class=\"stab portability\">{}</div>", cfg?.render_long_html()))
}
@@ -569,7 +570,10 @@ fn short_item_info(
message.push_str(&format!(": {}", html.into_string()));
}
extra_info.push(format!(
- "<div class=\"stab deprecated\"><span class=\"emoji\">👎</span> {}</div>",
+ "<div class=\"stab deprecated\">\
+ <span class=\"emoji\">👎</span>\
+ <span>{}</span>\
+ </div>",
message,
));
}
@@ -582,8 +586,9 @@ fn short_item_info(
.filter(|stab| stab.feature != sym::rustc_private)
.map(|stab| (stab.level, stab.feature))
{
- let mut message =
- "<span class=\"emoji\">🔬</span> This is a nightly-only experimental API.".to_owned();
+ let mut message = "<span class=\"emoji\">🔬</span>\
+ <span>This is a nightly-only experimental API."
+ .to_owned();
let mut feature = format!("<code>{}</code>", Escape(feature.as_str()));
if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue) {
@@ -594,7 +599,7 @@ fn short_item_info(
));
}
- message.push_str(&format!(" ({})", feature));
+ message.push_str(&format!(" ({})</span>", feature));
extra_info.push(format!("<div class=\"stab unstable\">{}</div>", message));
}
@@ -608,10 +613,10 @@ 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(
+pub(crate) fn render_impls(
cx: &mut Context<'_>,
w: &mut Buffer,
- impls: &[&&Impl],
+ impls: &[&Impl],
containing_item: &clean::Item,
toggle_open_by_default: bool,
) {
@@ -816,7 +821,7 @@ fn assoc_method(
href = href,
name = name,
generics = g.print(cx),
- decl = d.full_print(header_len, indent, header.asyncness, cx),
+ decl = d.full_print(header_len, indent, cx),
notable_traits = notable_traits_decl(d, cx),
where_clause = print_where_clause(g, cx, indent, end_newline),
)
@@ -836,12 +841,13 @@ fn assoc_method(
/// Note that it is possible for an unstable function to be const-stable. In that case, the span
/// will include the const-stable version, but no stable version will be emitted, as a natural
/// consequence of the above rules.
-fn render_stability_since_raw(
+fn render_stability_since_raw_with_extra(
w: &mut Buffer,
ver: Option<Symbol>,
const_stability: Option<ConstStability>,
containing_ver: Option<Symbol>,
containing_const_ver: Option<Symbol>,
+ extra_class: &str,
) -> bool {
let stable_version = ver.filter(|inner| !inner.is_empty() && Some(*inner) != containing_ver);
@@ -889,12 +895,30 @@ fn render_stability_since_raw(
}
if !stability.is_empty() {
- write!(w, r#"<span class="since" title="{}">{}</span>"#, title, stability);
+ write!(w, r#"<span class="since{extra_class}" title="{title}">{stability}</span>"#);
}
!stability.is_empty()
}
+#[inline]
+fn render_stability_since_raw(
+ w: &mut Buffer,
+ ver: Option<Symbol>,
+ const_stability: Option<ConstStability>,
+ containing_ver: Option<Symbol>,
+ containing_const_ver: Option<Symbol>,
+) -> bool {
+ render_stability_since_raw_with_extra(
+ w,
+ ver,
+ const_stability,
+ containing_ver,
+ containing_const_ver,
+ "",
+ )
+}
+
fn render_assoc_item(
w: &mut Buffer,
item: &clean::Item,
@@ -1001,6 +1025,47 @@ impl<'a> AssocItemLink<'a> {
}
}
+fn write_impl_section_heading(w: &mut Buffer, title: &str, id: &str) {
+ write!(
+ w,
+ "<h2 id=\"{id}\" class=\"small-section-header\">\
+ {title}\
+ <a href=\"#{id}\" class=\"anchor\"></a>\
+ </h2>"
+ );
+}
+
+pub(crate) fn render_all_impls(
+ w: &mut Buffer,
+ cx: &mut Context<'_>,
+ containing_item: &clean::Item,
+ concrete: &[&Impl],
+ synthetic: &[&Impl],
+ blanket_impl: &[&Impl],
+) {
+ let mut impls = Buffer::empty_from(w);
+ render_impls(cx, &mut impls, concrete, containing_item, true);
+ let impls = impls.into_inner();
+ if !impls.is_empty() {
+ write_impl_section_heading(w, "Trait Implementations", "trait-implementations");
+ write!(w, "<div id=\"trait-implementations-list\">{}</div>", impls);
+ }
+
+ if !synthetic.is_empty() {
+ write_impl_section_heading(w, "Auto Trait Implementations", "synthetic-implementations");
+ w.write_str("<div id=\"synthetic-implementations-list\">");
+ render_impls(cx, w, synthetic, containing_item, false);
+ w.write_str("</div>");
+ }
+
+ if !blanket_impl.is_empty() {
+ write_impl_section_heading(w, "Blanket Implementations", "blanket-implementations");
+ w.write_str("<div id=\"blanket-implementations-list\">");
+ render_impls(cx, w, blanket_impl, containing_item, false);
+ w.write_str("</div>");
+ }
+}
+
fn render_assoc_items(
w: &mut Buffer,
cx: &mut Context<'_>,
@@ -1030,12 +1095,7 @@ fn render_assoc_items_inner(
let mut tmp_buf = Buffer::empty_from(w);
let (render_mode, id) = match what {
AssocItemRender::All => {
- tmp_buf.write_str(
- "<h2 id=\"implementations\" class=\"small-section-header\">\
- Implementations\
- <a href=\"#implementations\" class=\"anchor\"></a>\
- </h2>",
- );
+ write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations");
(RenderMode::Normal, "implementations-list".to_owned())
}
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
@@ -1044,15 +1104,14 @@ fn render_assoc_items_inner(
if let Some(def_id) = type_.def_id(cx.cache()) {
cx.deref_id_map.insert(def_id, id.clone());
}
- write!(
- tmp_buf,
- "<h2 id=\"{id}\" class=\"small-section-header\">\
- <span>Methods from {trait_}&lt;Target = {type_}&gt;</span>\
- <a href=\"#{id}\" class=\"anchor\"></a>\
- </h2>",
- id = id,
- trait_ = trait_.print(cx),
- type_ = type_.print(cx),
+ write_impl_section_heading(
+ &mut tmp_buf,
+ &format!(
+ "<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
+ trait_ = trait_.print(cx),
+ type_ = type_.print(cx),
+ ),
+ &id,
);
(RenderMode::ForDeref { mut_: deref_mut_ }, cx.derive_id(id))
}
@@ -1099,49 +1158,12 @@ fn render_assoc_items_inner(
return;
}
- let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
- traits.iter().partition(|t| t.inner_impl().kind.is_auto());
- let (blanket_impl, concrete): (Vec<&&Impl>, _) =
+ let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
+ traits.into_iter().partition(|t| t.inner_impl().kind.is_auto());
+ let (blanket_impl, concrete): (Vec<&Impl>, _) =
concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
- let mut impls = Buffer::empty_from(w);
- render_impls(cx, &mut impls, &concrete, containing_item, true);
- let impls = impls.into_inner();
- if !impls.is_empty() {
- write!(
- w,
- "<h2 id=\"trait-implementations\" class=\"small-section-header\">\
- Trait Implementations\
- <a href=\"#trait-implementations\" class=\"anchor\"></a>\
- </h2>\
- <div id=\"trait-implementations-list\">{}</div>",
- impls
- );
- }
-
- if !synthetic.is_empty() {
- w.write_str(
- "<h2 id=\"synthetic-implementations\" class=\"small-section-header\">\
- Auto Trait Implementations\
- <a href=\"#synthetic-implementations\" class=\"anchor\"></a>\
- </h2>\
- <div id=\"synthetic-implementations-list\">",
- );
- render_impls(cx, w, &synthetic, containing_item, false);
- w.write_str("</div>");
- }
-
- if !blanket_impl.is_empty() {
- w.write_str(
- "<h2 id=\"blanket-implementations\" class=\"small-section-header\">\
- Blanket Implementations\
- <a href=\"#blanket-implementations\" class=\"anchor\"></a>\
- </h2>\
- <div id=\"blanket-implementations-list\">",
- );
- render_impls(cx, w, &blanket_impl, containing_item, false);
- w.write_str("</div>");
- }
+ render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl);
}
}
@@ -1550,6 +1572,15 @@ fn render_impl(
rendering_params: ImplRenderingParameters,
) {
for trait_item in &t.items {
+ // Skip over any default trait items that are impossible to call
+ // (e.g. if it has a `Self: Sized` bound on an unsized type).
+ if let Some(impl_def_id) = parent.item_id.as_def_id()
+ && let Some(trait_item_def_id) = trait_item.item_id.as_def_id()
+ && cx.tcx().is_impossible_method((impl_def_id, trait_item_def_id))
+ {
+ continue;
+ }
+
let n = trait_item.name;
if i.items.iter().any(|m| m.name == n) {
continue;
@@ -1668,23 +1699,29 @@ fn render_rightside(
RenderMode::Normal => (item.const_stability(tcx), containing_item.const_stable_since(tcx)),
RenderMode::ForDeref { .. } => (None, None),
};
+ let src_href = cx.src_href(item);
+ let has_src_ref = src_href.is_some();
let mut rightside = Buffer::new();
- let has_stability = render_stability_since_raw(
+ let has_stability = render_stability_since_raw_with_extra(
&mut rightside,
item.stable_since(tcx),
const_stability,
containing_item.stable_since(tcx),
const_stable_since,
+ if has_src_ref { "" } else { " rightside" },
);
- let mut srclink = Buffer::empty_from(w);
- write_srclink(cx, item, &mut srclink);
- if has_stability && !srclink.is_empty() {
- rightside.write_str(" · ");
+ if let Some(l) = src_href {
+ if has_stability {
+ write!(rightside, " · <a class=\"srclink\" href=\"{}\">source</a>", l)
+ } else {
+ write!(rightside, "<a class=\"srclink rightside\" href=\"{}\">source</a>", l)
+ }
}
- rightside.push_buffer(srclink);
- if !rightside.is_empty() {
+ if has_stability && has_src_ref {
write!(w, "<span class=\"rightside\">{}</span>", rightside.into_inner());
+ } else {
+ w.push_buffer(rightside);
}
}
@@ -1700,8 +1737,8 @@ pub(crate) fn render_impl_summary(
// in documentation pages for trait with automatic implementations like "Send" and "Sync".
aliases: &[String],
) {
- let id =
- cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx));
+ let inner_impl = i.inner_impl();
+ let id = cx.derive_id(get_id_for_impl(&inner_impl.for_, inner_impl.trait_.as_ref(), cx));
let aliases = if aliases.is_empty() {
String::new()
} else {
@@ -1713,9 +1750,9 @@ pub(crate) fn render_impl_summary(
write!(w, "<h3 class=\"code-header in-band\">");
if let Some(use_absolute) = use_absolute {
- write!(w, "{}", i.inner_impl().print(use_absolute, cx));
+ write!(w, "{}", inner_impl.print(use_absolute, cx));
if show_def_docs {
- for it in &i.inner_impl().items {
+ for it in &inner_impl.items {
if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
w.write_str("<span class=\"where fmt-newline\"> ");
assoc_type(
@@ -1733,11 +1770,11 @@ pub(crate) fn render_impl_summary(
}
}
} else {
- write!(w, "{}", i.inner_impl().print(false, cx));
+ write!(w, "{}", inner_impl.print(false, cx));
}
write!(w, "</h3>");
- let is_trait = i.inner_impl().trait_.is_some();
+ let is_trait = inner_impl.trait_.is_some();
if is_trait {
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
write!(w, "<span class=\"item-info\">{}</span>", portability);
@@ -1931,6 +1968,70 @@ fn small_url_encode(s: String) -> String {
}
}
+pub(crate) fn sidebar_render_assoc_items(
+ cx: &Context<'_>,
+ out: &mut Buffer,
+ id_map: &mut IdMap,
+ concrete: Vec<&Impl>,
+ synthetic: Vec<&Impl>,
+ blanket_impl: Vec<&Impl>,
+) {
+ let format_impls = |impls: Vec<&Impl>, id_map: &mut IdMap| {
+ let mut links = FxHashSet::default();
+
+ let mut ret = impls
+ .iter()
+ .filter_map(|it| {
+ let trait_ = it.inner_impl().trait_.as_ref()?;
+ let encoded =
+ id_map.derive(get_id_for_impl(&it.inner_impl().for_, Some(trait_), cx));
+
+ let i_display = format!("{:#}", trait_.print(cx));
+ let out = Escape(&i_display);
+ let prefix = match it.inner_impl().polarity {
+ ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+ ty::ImplPolarity::Negative => "!",
+ };
+ let generated = format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
+ if links.insert(generated.clone()) { Some(generated) } else { None }
+ })
+ .collect::<Vec<String>>();
+ ret.sort();
+ ret
+ };
+
+ let concrete_format = format_impls(concrete, id_map);
+ let synthetic_format = format_impls(synthetic, id_map);
+ let blanket_format = format_impls(blanket_impl, id_map);
+
+ if !concrete_format.is_empty() {
+ print_sidebar_block(
+ out,
+ "trait-implementations",
+ "Trait Implementations",
+ concrete_format.iter(),
+ );
+ }
+
+ if !synthetic_format.is_empty() {
+ print_sidebar_block(
+ out,
+ "synthetic-implementations",
+ "Auto Trait Implementations",
+ synthetic_format.iter(),
+ );
+ }
+
+ if !blanket_format.is_empty() {
+ print_sidebar_block(
+ out,
+ "blanket-implementations",
+ "Blanket Implementations",
+ blanket_format.iter(),
+ );
+ }
+}
+
fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
let did = it.item_id.expect_def_id();
let cache = cx.cache();
@@ -1976,68 +2077,15 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
{
let mut derefs = FxHashSet::default();
derefs.insert(did);
- sidebar_deref_methods(cx, out, impl_, v, &mut derefs);
+ sidebar_deref_methods(cx, out, impl_, v, &mut derefs, &mut used_links);
}
- let format_impls = |impls: Vec<&Impl>, id_map: &mut IdMap| {
- let mut links = FxHashSet::default();
-
- let mut ret = impls
- .iter()
- .filter_map(|it| {
- let trait_ = it.inner_impl().trait_.as_ref()?;
- let encoded =
- id_map.derive(get_id_for_impl(&it.inner_impl().for_, Some(trait_), cx));
-
- let i_display = format!("{:#}", trait_.print(cx));
- let out = Escape(&i_display);
- let prefix = match it.inner_impl().polarity {
- ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
- ty::ImplPolarity::Negative => "!",
- };
- let generated = format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
- if links.insert(generated.clone()) { Some(generated) } else { None }
- })
- .collect::<Vec<String>>();
- ret.sort();
- ret
- };
-
let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
v.iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_auto());
let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) =
concrete.into_iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_blanket());
- let concrete_format = format_impls(concrete, &mut id_map);
- let synthetic_format = format_impls(synthetic, &mut id_map);
- let blanket_format = format_impls(blanket_impl, &mut id_map);
-
- if !concrete_format.is_empty() {
- print_sidebar_block(
- out,
- "trait-implementations",
- "Trait Implementations",
- concrete_format.iter(),
- );
- }
-
- if !synthetic_format.is_empty() {
- print_sidebar_block(
- out,
- "synthetic-implementations",
- "Auto Trait Implementations",
- synthetic_format.iter(),
- );
- }
-
- if !blanket_format.is_empty() {
- print_sidebar_block(
- out,
- "blanket-implementations",
- "Blanket Implementations",
- blanket_format.iter(),
- );
- }
+ sidebar_render_assoc_items(cx, out, &mut id_map, concrete, synthetic, blanket_impl);
}
}
}
@@ -2048,6 +2096,7 @@ fn sidebar_deref_methods(
impl_: &Impl,
v: &[Impl],
derefs: &mut FxHashSet<DefId>,
+ used_links: &mut FxHashSet<String>,
) {
let c = cx.cache();
@@ -2080,13 +2129,10 @@ fn sidebar_deref_methods(
.and_then(|did| c.impls.get(&did));
if let Some(impls) = inner_impl {
debug!("found inner_impl: {:?}", impls);
- let mut used_links = FxHashSet::default();
let mut ret = impls
.iter()
.filter(|i| i.inner_impl().trait_.is_none())
- .flat_map(|i| {
- get_methods(i.inner_impl(), true, &mut used_links, deref_mut, cx.tcx())
- })
+ .flat_map(|i| get_methods(i.inner_impl(), true, used_links, deref_mut, cx.tcx()))
.collect::<Vec<_>>();
if !ret.is_empty() {
let id = if let Some(target_def_id) = real_target.def_id(c) {
@@ -2115,7 +2161,14 @@ fn sidebar_deref_methods(
.map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait())
.unwrap_or(false)
}) {
- sidebar_deref_methods(cx, out, target_deref_impl, target_impls, derefs);
+ sidebar_deref_methods(
+ cx,
+ out,
+ target_deref_impl,
+ target_impls,
+ derefs,
+ used_links,
+ );
}
}
}
@@ -2302,9 +2355,54 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
buf.push_str("</section>")
}
+/// Returns the list of implementations for the primitive reference type, filtering out any
+/// implementations that are on concrete or partially generic types, only keeping implementations
+/// of the form `impl<T> Trait for &T`.
+pub(crate) fn get_filtered_impls_for_reference<'a>(
+ shared: &'a Rc<SharedContext<'_>>,
+ it: &clean::Item,
+) -> (Vec<&'a Impl>, Vec<&'a Impl>, Vec<&'a Impl>) {
+ let def_id = it.item_id.expect_def_id();
+ // If the reference primitive is somehow not defined, exit early.
+ let Some(v) = shared.cache.impls.get(&def_id) else { return (Vec::new(), Vec::new(), Vec::new()) };
+ // Since there is no "direct implementation" on the reference primitive type, we filter out
+ // every implementation which isn't a trait implementation.
+ let traits = v.iter().filter(|i| i.inner_impl().trait_.is_some());
+ let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
+ traits.partition(|t| t.inner_impl().kind.is_auto());
+
+ let (blanket_impl, concrete): (Vec<&Impl>, _) =
+ concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
+ // Now we keep only references over full generic types.
+ let concrete: Vec<_> = concrete
+ .into_iter()
+ .filter(|t| match t.inner_impl().for_ {
+ clean::Type::BorrowedRef { ref type_, .. } => type_.is_full_generic(),
+ _ => false,
+ })
+ .collect();
+
+ (concrete, synthetic, blanket_impl)
+}
+
fn sidebar_primitive(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
let mut sidebar = Buffer::new();
- sidebar_assoc_items(cx, &mut sidebar, it);
+
+ if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) {
+ sidebar_assoc_items(cx, &mut sidebar, it);
+ } else {
+ let shared = Rc::clone(&cx.shared);
+ let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&shared, it);
+
+ sidebar_render_assoc_items(
+ cx,
+ &mut sidebar,
+ &mut IdMap::new(),
+ concrete,
+ synthetic,
+ blanket_impl,
+ );
+ }
if !sidebar.is_empty() {
write!(buf, "<section>{}</section>", sidebar.into_inner());
@@ -2614,8 +2712,8 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
clean::Type::BorrowedRef { type_, .. } => {
work.push_back(*type_);
}
- clean::Type::QPath { self_type, trait_, .. } => {
- work.push_back(*self_type);
+ clean::Type::QPath(box clean::QPathData { self_type, trait_, .. }) => {
+ work.push_back(self_type);
process_path(trait_.def_id());
}
_ => {}
@@ -2668,7 +2766,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
let contents = match fs::read_to_string(&path) {
Ok(contents) => contents,
Err(err) => {
- let span = item.span(tcx).inner();
+ let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner());
tcx.sess
.span_err(span, &format!("failed to read file {}: {}", path.display(), err));
return false;
@@ -2764,11 +2862,10 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
sources::print_src(
w,
contents_subset,
- call_data.edition,
file_span,
cx,
&root_path,
- Some(highlight::DecorationInfo(decoration_info)),
+ highlight::DecorationInfo(decoration_info),
sources::SourceContext::Embedded { offset: line_min },
);
write!(w, "</div></div>");
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 99cf42919..cfa450942 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -16,10 +16,10 @@ use std::fmt;
use std::rc::Rc;
use super::{
- collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_section,
- notable_traits_decl, render_assoc_item, render_assoc_items, render_attributes_in_code,
- render_attributes_in_pre, render_impl, render_stability_since_raw, write_srclink,
- AssocItemLink, Context, ImplRenderingParameters,
+ collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
+ item_ty_to_section, notable_traits_decl, render_all_impls, render_assoc_item,
+ render_assoc_items, render_attributes_in_code, render_attributes_in_pre, render_impl,
+ render_rightside, render_stability_since_raw, AssocItemLink, Context, ImplRenderingParameters,
};
use crate::clean;
use crate::config::ModuleSorting;
@@ -371,16 +371,21 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
}
clean::ImportKind::Glob => String::new(),
};
+ let stab_tags = stab_tags.unwrap_or_default();
+ let (stab_tags_before, stab_tags_after) = if stab_tags.is_empty() {
+ ("", "")
+ } else {
+ ("<div class=\"item-right docblock-short\">", "</div>")
+ };
write!(
w,
"<div class=\"item-left {stab}{add}import-item\"{id}>\
<code>{vis}{imp}</code>\
</div>\
- <div class=\"item-right docblock-short\">{stab_tags}</div>",
+ {stab_tags_before}{stab_tags}{stab_tags_after}",
stab = stab.unwrap_or_default(),
vis = myitem.visibility.print_with_space(myitem.item_id, cx),
imp = import.print(cx),
- stab_tags = stab_tags.unwrap_or_default(),
);
w.write_str(ITEM_TABLE_ROW_CLOSE);
}
@@ -412,6 +417,12 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
let doc_value = myitem.doc_value().unwrap_or_default();
w.write_str(ITEM_TABLE_ROW_OPEN);
+ let docs = MarkdownSummaryLine(&doc_value, &myitem.links(cx)).into_string();
+ let (docs_before, docs_after) = if docs.is_empty() {
+ ("", "")
+ } else {
+ ("<div class=\"item-right docblock-short\">", "</div>")
+ };
write!(
w,
"<div class=\"item-left {stab}{add}module-item\">\
@@ -420,11 +431,10 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
{unsafety_flag}\
{stab_tags}\
</div>\
- <div class=\"item-right docblock-short\">{docs}</div>",
+ {docs_before}{docs}{docs_after}",
name = myitem.name.unwrap(),
visibility_emoji = visibility_emoji,
stab_tags = extra_info_tags(myitem, item, cx.tcx()),
- docs = MarkdownSummaryLine(&doc_value, &myitem.links(cx)).into_string(),
class = myitem.type_(),
add = add,
stab = stab.unwrap_or_default(),
@@ -477,7 +487,7 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->
(cfg, _) => cfg.as_deref().cloned(),
};
- debug!("Portability {:?} - {:?} = {:?}", item.cfg, parent.cfg, cfg);
+ debug!("Portability name={:?} {:?} - {:?} = {:?}", item.name, item.cfg, parent.cfg, cfg);
if let Some(ref cfg) = cfg {
tags += &tag_html("portability", &cfg.render_long_plain(), &cfg.render_short_html());
}
@@ -520,7 +530,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
name = name,
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline),
- decl = f.decl.full_print(header_len, 0, header.asyncness, cx),
+ decl = f.decl.full_print(header_len, 0, cx),
notable_traits = notable_traits_decl(&f.decl, cx),
);
});
@@ -709,14 +719,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
write!(w, "<details class=\"rustdoc-toggle\" open><summary>");
}
write!(w, "<div id=\"{}\" class=\"method has-srclink\">", id);
- write!(w, "<div class=\"rightside\">");
-
- let has_stability = render_stability_since(w, m, t, cx.tcx());
- if has_stability {
- w.write_str(" · ");
- }
- write_srclink(cx, m, w);
- write!(w, "</div>");
+ render_rightside(w, cx, m, t, RenderMode::Normal);
write!(w, "<h4 class=\"code-header\">");
render_assoc_item(
w,
@@ -994,7 +997,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
// So C's HTML will have something like this:
//
// ```html
- // <script type="text/javascript" src="/implementors/A/trait.Foo.js"
+ // <script src="/implementors/A/trait.Foo.js"
// data-ignore-extern-crates="A,B" async></script>
// ```
//
@@ -1020,9 +1023,11 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
.map(|cnum| cx.shared.tcx.crate_name(cnum).to_string())
.collect::<Vec<_>>()
.join(",");
+ let (extern_before, extern_after) =
+ if extern_crates.is_empty() { ("", "") } else { (" data-ignore-extern-crates=\"", "\"") };
write!(
w,
- "<script type=\"text/javascript\" src=\"{src}\" data-ignore-extern-crates=\"{extern_crates}\" async></script>",
+ "<script src=\"{src}\"{extern_before}{extern_crates}{extern_after} async></script>",
src = js_src_path.finish(),
);
}
@@ -1198,7 +1203,8 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
let name = v.name.unwrap();
match *v.kind {
clean::VariantItem(ref var) => match var {
- clean::Variant::CLike => write!(w, "{}", name),
+ // FIXME(#101337): Show discriminant
+ clean::Variant::CLike(..) => write!(w, "{}", name),
clean::Variant::Tuple(ref s) => {
write!(w, "{}(", name);
print_tuple_struct_fields(w, cx, s);
@@ -1260,7 +1266,13 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
w.write_str(")");
}
w.write_str("</code>");
- render_stability_since(w, variant, it, cx.tcx());
+ render_stability_since_raw(
+ w,
+ variant.stable_since(cx.tcx()),
+ variant.const_stability(cx.tcx()),
+ it.stable_since(cx.tcx()),
+ it.const_stable_since(cx.tcx()),
+ );
w.write_str("</h3>");
use crate::clean::Variant;
@@ -1322,17 +1334,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) {
wrap_into_docblock(w, |w| {
- highlight::render_with_highlighting(
- &t.source,
- w,
- Some("macro"),
- None,
- None,
- it.span(cx.tcx()).inner().edition(),
- None,
- None,
- None,
- );
+ highlight::render_macro_with_highlighting(&t.source, w);
});
document(w, cx, it, None, HeadingOffset::H2)
}
@@ -1370,8 +1372,18 @@ fn item_proc_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, m: &c
}
fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
+ let def_id = it.item_id.expect_def_id();
document(w, cx, it, None, HeadingOffset::H2);
- render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All)
+ if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) {
+ render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
+ } else {
+ // We handle the "reference" primitive type on its own because we only want to list
+ // implementations on generic types.
+ let shared = Rc::clone(&cx.shared);
+ let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&shared, it);
+
+ render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl);
+ }
}
fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) {
@@ -1601,21 +1613,6 @@ where
w.write_str("</code></pre>");
}
-fn render_stability_since(
- w: &mut Buffer,
- item: &clean::Item,
- containing_item: &clean::Item,
- tcx: TyCtxt<'_>,
-) -> bool {
- render_stability_since_raw(
- w,
- item.stable_since(tcx),
- item.const_stability(tcx),
- containing_item.stable_since(tcx),
- containing_item.const_stable_since(tcx),
- )
-}
-
fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl, cx: &Context<'_>) -> Ordering {
let lhss = format!("{}", lhs.inner_impl().print(false, cx));
let rhss = format!("{}", rhs.inner_impl().print(false, cx));
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index d672f0bb5..8eb9c07f8 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -544,10 +544,15 @@ fn get_fn_inputs_and_outputs<'tcx>(
(true, _) => (Some(impl_self), &func.generics),
(_, true) => (Some(impl_self), impl_generics),
(false, false) => {
- let mut params = func.generics.params.clone();
- params.extend(impl_generics.params.clone());
- let mut where_predicates = func.generics.where_predicates.clone();
- where_predicates.extend(impl_generics.where_predicates.clone());
+ let params =
+ func.generics.params.iter().chain(&impl_generics.params).cloned().collect();
+ let where_predicates = func
+ .generics
+ .where_predicates
+ .iter()
+ .chain(&impl_generics.where_predicates)
+ .cloned()
+ .collect();
combined_generics = clean::Generics { params, where_predicates };
(Some(impl_self), &combined_generics)
}
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 34d590fb2..151ec2b28 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -166,25 +166,23 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
if let ExprKind::MethodCall(segment, ..) = expr.kind {
- if let Some(hir_id) = segment.hir_id {
- let hir = self.tcx.hir();
- let body_id = hir.enclosing_body_owner(hir_id);
- // FIXME: this is showing error messages for parts of the code that are not
- // compiled (because of cfg)!
- //
- // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352
- let typeck_results = self.tcx.typeck_body(
- hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"),
+ let hir = self.tcx.hir();
+ let body_id = hir.enclosing_body_owner(segment.hir_id);
+ // FIXME: this is showing error messages for parts of the code that are not
+ // compiled (because of cfg)!
+ //
+ // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352
+ let typeck_results = self
+ .tcx
+ .typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"));
+ if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
+ self.matches.insert(
+ segment.ident.span,
+ match hir.span_if_local(def_id) {
+ Some(span) => LinkFromSrc::Local(clean::Span::new(span)),
+ None => LinkFromSrc::External(def_id),
+ },
);
- if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
- self.matches.insert(
- segment.ident.span,
- match hir.span_if_local(def_id) {
- Some(span) => LinkFromSrc::Local(clean::Span::new(span)),
- None => LinkFromSrc::External(def_id),
- },
- );
- }
}
} else if self.handle_macro(expr.span) {
// We don't want to go deeper into the macro.
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 6fb41ff32..fc4d46fe6 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -1,5 +1,4 @@
use std::ffi::OsStr;
-use std::fmt::Write;
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, BufReader};
@@ -10,7 +9,8 @@ use std::sync::LazyLock as Lazy;
use itertools::Itertools;
use rustc_data_structures::flock;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use serde::Serialize;
+use serde::ser::SerializeSeq;
+use serde::{Serialize, Serializer};
use super::{collect_paths_for_type, ensure_trailing_slash, Context, BASIC_KEYWORDS};
use crate::clean::Crate;
@@ -284,25 +284,43 @@ pub(super) fn write_shared(
cx.write_shared(SharedResource::Unversioned { name }, contents, &options.emit)?;
}
- fn collect(path: &Path, krate: &str, key: &str) -> io::Result<(Vec<String>, Vec<String>)> {
+ /// Read a file and return all lines that match the `"{crate}":{data},` format,
+ /// and return a tuple `(Vec<DataString>, Vec<CrateNameString>)`.
+ ///
+ /// This forms the payload of files that look like this:
+ ///
+ /// ```javascript
+ /// var data = {
+ /// "{crate1}":{data},
+ /// "{crate2}":{data}
+ /// };
+ /// use_data(data);
+ /// ```
+ ///
+ /// The file needs to be formatted so that *only crate data lines start with `"`*.
+ fn collect(path: &Path, krate: &str) -> io::Result<(Vec<String>, Vec<String>)> {
let mut ret = Vec::new();
let mut krates = Vec::new();
if path.exists() {
- let prefix = format!(r#"{}["{}"]"#, key, krate);
+ let prefix = format!("\"{}\"", krate);
for line in BufReader::new(File::open(path)?).lines() {
let line = line?;
- if !line.starts_with(key) {
+ if !line.starts_with('"') {
continue;
}
if line.starts_with(&prefix) {
continue;
}
- ret.push(line.to_string());
+ if line.ends_with(',') {
+ ret.push(line[..line.len() - 1].to_string());
+ } else {
+ // No comma (it's the case for the last added crate line)
+ ret.push(line.to_string());
+ }
krates.push(
- line[key.len() + 2..]
- .split('"')
- .next()
+ line.split('"')
+ .find(|s| !s.is_empty())
.map(|s| s.to_owned())
.unwrap_or_else(String::new),
);
@@ -311,6 +329,20 @@ pub(super) fn write_shared(
Ok((ret, krates))
}
+ /// Read a file and return all lines that match the <code>"{crate}":{data},\</code> format,
+ /// and return a tuple `(Vec<DataString>, Vec<CrateNameString>)`.
+ ///
+ /// This forms the payload of files that look like this:
+ ///
+ /// ```javascript
+ /// var data = JSON.parse('{\
+ /// "{crate1}":{data},\
+ /// "{crate2}":{data}\
+ /// }');
+ /// use_data(data);
+ /// ```
+ ///
+ /// The file needs to be formatted so that *only crate data lines start with `"`*.
fn collect_json(path: &Path, krate: &str) -> io::Result<(Vec<String>, Vec<String>)> {
let mut ret = Vec::new();
let mut krates = Vec::new();
@@ -526,13 +558,27 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
},
};
- #[derive(Serialize)]
struct Implementor {
text: String,
synthetic: bool,
types: Vec<String>,
}
+ impl Serialize for Implementor {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut seq = serializer.serialize_seq(None)?;
+ seq.serialize_element(&self.text)?;
+ if self.synthetic {
+ seq.serialize_element(&1)?;
+ seq.serialize_element(&self.types)?;
+ }
+ seq.end()
+ }
+ }
+
let implementors = imps
.iter()
.filter_map(|imp| {
@@ -563,9 +609,9 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
}
let implementors = format!(
- r#"implementors["{}"] = {};"#,
+ r#""{}":{}"#,
krate.name(cx.tcx()),
- serde_json::to_string(&implementors).unwrap()
+ serde_json::to_string(&implementors).expect("failed serde conversion"),
);
let mut mydst = dst.clone();
@@ -576,16 +622,15 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
mydst.push(&format!("{}.{}.js", remote_item_type, remote_path[remote_path.len() - 1]));
let (mut all_implementors, _) =
- try_err!(collect(&mydst, krate.name(cx.tcx()).as_str(), "implementors"), &mydst);
+ try_err!(collect(&mydst, krate.name(cx.tcx()).as_str()), &mydst);
all_implementors.push(implementors);
// Sort the implementors by crate so the file will be generated
// identically even with rustdoc running in parallel.
all_implementors.sort();
- let mut v = String::from("(function() {var implementors = {};\n");
- for implementor in &all_implementors {
- writeln!(v, "{}", *implementor).unwrap();
- }
+ let mut v = String::from("(function() {var implementors = {\n");
+ v.push_str(&all_implementors.join(",\n"));
+ v.push_str("\n};");
v.push_str(
"if (window.register_implementors) {\
window.register_implementors(implementors);\
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index d0fd637ba..2e2bee78b 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -11,7 +11,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
-use rustc_span::edition::Edition;
use rustc_span::source_map::FileName;
use std::ffi::OsStr;
@@ -54,6 +53,7 @@ impl LocalSourcesCollector<'_, '_> {
fn add_local_source(&mut self, item: &clean::Item) {
let sess = self.tcx.sess;
let span = item.span(self.tcx);
+ let Some(span) = span else { return };
// skip all synthetic "files"
if !is_real_and_local(span, sess) {
return;
@@ -110,6 +110,7 @@ impl DocVisitor for SourceCollector<'_, '_> {
let tcx = self.cx.tcx();
let span = item.span(tcx);
+ let Some(span) = span else { return };
let sess = tcx.sess;
// If we're not rendering sources, there's nothing to do.
@@ -213,11 +214,10 @@ impl SourceCollector<'_, '_> {
print_src(
buf,
contents,
- cx.shared.edition(),
file_span,
cx,
&root_path,
- None,
+ highlight::DecorationInfo::default(),
SourceContext::Standalone,
)
},
@@ -266,11 +266,10 @@ pub(crate) enum SourceContext {
pub(crate) fn print_src(
buf: &mut Buffer,
s: &str,
- edition: Edition,
file_span: rustc_span::Span,
context: &Context<'_>,
root_path: &str,
- decoration_info: Option<highlight::DecorationInfo>,
+ decoration_info: highlight::DecorationInfo,
source_context: SourceContext,
) {
let lines = s.lines().count();
@@ -289,15 +288,14 @@ pub(crate) fn print_src(
}
}
line_numbers.write_str("</pre>");
- highlight::render_with_highlighting(
+ let current_href = &context
+ .href_from_span(clean::Span::new(file_span), false)
+ .expect("only local crates should have sources emitted");
+ highlight::render_source_with_highlighting(
s,
buf,
- None,
- None,
- None,
- edition,
- Some(line_numbers),
- Some(highlight::HrefContext { context, file_span, root_path }),
+ line_numbers,
+ highlight::HrefContext { context, file_span, root_path, current_href },
decoration_info,
);
}
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 83fe14550..bb35970eb 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -197,26 +197,18 @@ h4.code-header {
position: relative;
}
-div.impl-items > div {
- padding-left: 0;
-}
-
h1, h2, h3, h4, h5, h6,
.sidebar,
.mobile-topbar,
a.source,
.search-input,
.search-results .result-name,
-.content table td:first-child > a,
.item-left > a,
.out-of-band,
span.since,
-#source-sidebar, #sidebar-toggle,
details.rustdoc-toggle > summary::before,
-div.impl-items > div:not(.docblock):not(.item-info),
.content ul.crate a.crate,
a.srclink,
-#main-content > .since,
#help-button > button,
details.rustdoc-toggle.top-doc > summary,
details.rustdoc-toggle.top-doc > summary::before,
@@ -230,7 +222,6 @@ details.rustdoc-toggle.non-exhaustive > summary::before,
font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif;
}
-h1, h2, h3, h4,
a#toggle-all-docs,
a.anchor,
.small-section-header a,
@@ -250,6 +241,51 @@ pre.rust a,
color: var(--main-color);
}
+.content span.enum, .content a.enum,
+.content span.struct, .content a.struct,
+.content span.union, .content a.union,
+.content span.primitive, .content a.primitive,
+.content span.type, .content a.type,
+.content span.foreigntype, .content a.foreigntype {
+ color: var(--type-link-color);
+}
+
+.content span.trait, .content a.trait,
+.content span.traitalias, .content a.traitalias {
+ color: var(--trait-link-color);
+}
+
+.content span.associatedtype, .content a.associatedtype,
+.content span.constant, .content a.constant,
+.content span.static, .content a.static {
+ color: var(--assoc-item-link-color);
+}
+
+.content span.fn, .content a.fn,
+.content .fnname,
+.content span.method, .content a.method,
+.content span.tymethod, .content a.tymethod {
+ color: var(--function-link-color);
+}
+
+.content span.attr, .content a.attr,
+.content span.derive, .content a.derive,
+.content span.macro, .content a.macro {
+ color: var(--macro-link-color);
+}
+
+.content span.mod, .content a.mod, .block a.current.mod {
+ color: var(--mod-link-color);
+}
+
+.content span.keyword, .content a.keyword {
+ color: var(--keyword-link-color);
+}
+
+a {
+ color: var(--link-color);
+}
+
ol, ul {
padding-left: 24px;
}
@@ -354,19 +390,8 @@ img {
max-width: 100%;
}
-li {
- position: relative;
-}
-
.source .content {
- max-width: none;
overflow: visible;
- margin-left: 0px;
-}
-
-nav.sub {
- position: relative;
- font-size: 1rem;
}
.sub-container {
@@ -515,9 +540,6 @@ nav.sub {
font-weight: 500;
}
-.block {
- padding: 0;
-}
.block ul, .block li {
padding: 0;
margin: 0;
@@ -608,19 +630,10 @@ h2.location a {
margin: 0;
}
-#search {
- position: relative;
-}
-
.search-loading {
text-align: center;
}
-#results > table {
- width: 100%;
- table-layout: fixed;
-}
-
.content > .example-wrap pre.line-numbers {
position: relative;
-webkit-user-select: none;
@@ -635,19 +648,12 @@ h2.location a {
.docblock-short {
overflow-wrap: break-word;
overflow-wrap: anywhere;
-}
-.docblock-short p {
- display: inline;
-}
-
-.docblock-short p {
overflow: hidden;
text-overflow: ellipsis;
- margin: 0;
}
/* Wrap non-pre code blocks (`text`) but not (```text```). */
.docblock > :not(pre) > code,
-.docblock-short > :not(pre) > code {
+.docblock-short > code {
white-space: pre-wrap;
}
@@ -672,7 +678,7 @@ h2.location a {
position: relative;
}
-.docblock > :not(.information):not(.more-examples-toggle) {
+.docblock > :not(.more-examples-toggle):not(.example-wrap) {
max-width: 100%;
overflow-x: auto;
}
@@ -693,8 +699,13 @@ h2.location a {
flex-grow: 1;
margin: 0px;
padding: 0px;
+ /* We use overflow-wrap: break-word for Safari, which doesn't recognize
+ `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */
overflow-wrap: break-word;
+ /* Then override it with `anywhere`, which is required to make non-Safari browsers break
+ more aggressively when we want them to. */
overflow-wrap: anywhere;
+ background-color: var(--main-background-color);
}
.in-band > code, .in-band > .code-header {
@@ -709,18 +720,6 @@ pre, .rustdoc.source .example-wrap {
#main-content {
position: relative;
}
-#main-content > .since {
- top: inherit;
-}
-
-.content table:not(.table-display) {
- border-spacing: 0 5px;
-}
-.content td { vertical-align: top; }
-.content td:first-child { padding-right: 20px; }
-.content td p:first-child { margin-top: 0; }
-.content td h1, .content td h2 { margin-left: 0; font-size: 1.125rem; }
-.content tr:first-child td { border-top: 0; }
.docblock table {
margin: .5em 0;
@@ -731,17 +730,14 @@ pre, .rustdoc.source .example-wrap {
.docblock table td {
padding: .5em;
- border: 1px dashed;
+ border: 1px dashed var(--border-color);
+ vertical-align: top;
}
.docblock table th {
padding: .5em;
text-align: left;
- border: 1px solid;
-}
-
-.fields + table {
- margin-bottom: 1em;
+ border: 1px solid var(--border-color);
}
.content .item-list {
@@ -749,16 +745,6 @@ pre, .rustdoc.source .example-wrap {
padding: 0;
}
-.content .multi-column {
- -moz-column-count: 5;
- -moz-column-gap: 2.5em;
- -webkit-column-count: 5;
- -webkit-column-gap: 2.5em;
- column-count: 5;
- column-gap: 2.5em;
-}
-.content .multi-column li { width: 100%; display: inline-block; }
-
.content > .methods > .method {
font-size: 1rem;
position: relative;
@@ -771,25 +757,6 @@ pre, .rustdoc.source .example-wrap {
font-size: 0.875rem;
}
-.content .methods > div:not(.notable-traits):not(.method) {
- margin-left: 40px;
- margin-bottom: 15px;
-}
-
-.content .docblock > .impl-items {
- margin-left: 20px;
- margin-top: -34px;
-}
-.content .docblock >.impl-items .table-display {
- margin: 0;
-}
-.content .docblock >.impl-items table td {
- padding: 0;
-}
-.content .docblock > .impl-items .table-display, .impl-items table td {
- border: none;
-}
-
.item-info {
display: block;
}
@@ -803,58 +770,29 @@ pre, .rustdoc.source .example-wrap {
margin-left: 24px;
}
-.sub-variant > div > .item-info {
- margin-top: initial;
-}
-
.content .impl-items .docblock, .content .impl-items .item-info {
margin-bottom: .6em;
}
-.content .impl-items > .item-info {
- margin-left: 40px;
-}
-
-.methods > .item-info, .content .impl-items > .item-info {
- margin-top: -8px;
-}
-
-.impl-items {
- flex-basis: 100%;
-}
-
#main-content > .item-info {
margin-top: 0;
margin-left: 0;
}
nav.sub {
+ position: relative;
+ font-size: 1rem;
flex-grow: 1;
margin-bottom: 25px;
}
.source nav.sub {
margin-left: 32px;
}
-nav.main {
- padding: 20px 0;
- text-align: center;
-}
-nav.main .current {
- border-top: 1px solid;
- border-bottom: 1px solid;
-}
-nav.main .separator {
- border: 1px solid;
- display: inline-block;
- height: 23px;
- margin: 0 20px;
-}
nav.sum { text-align: right; }
nav.sub form { display: inline; }
a {
text-decoration: none;
- background: transparent;
}
.small-section-header {
@@ -942,40 +880,77 @@ table,
position: relative;
display: flex;
height: 34px;
+ margin-top: 4px;
}
.search-container > * {
height: 100%;
}
.search-results-title {
- display: inline;
+ margin-top: 0;
+ white-space: nowrap;
+ /* flex layout allows shrinking the <select> appropriately if it becomes too large */
+ display: inline-flex;
+ max-width: 100%;
+ /* make things look like in a line, despite the fact that we're using a layout
+ with boxes (i.e. from the flex layout) */
+ align-items: baseline;
}
-#search-settings {
- font-size: 1.5rem;
- font-weight: 500;
- margin-bottom: 20px;
+#crate-search-div {
+ display: inline-block;
+ /* ensures that 100% in properties of #crate-search-div:after
+ are relative to the size of this div */
+ position: relative;
+ /* allows this div (and with it the <select>-element "#crate-search") to be shrunk */
+ min-width: 5em;
}
#crate-search {
min-width: 115px;
- margin-top: 5px;
- padding-left: 0.15em;
+ padding: 0;
+ /* keep these two in sync with "@-moz-document url-prefix()" below */
+ padding-left: 4px;
padding-right: 23px;
- border: 1px solid;
+ /* prevents the <select> from overflowing the containing div in case it's shrunk */
+ max-width: 100%;
+ /* contents can overflow because of max-width limit, then show ellipsis */
+ text-overflow: ellipsis;
+ border: 1px solid var(--border-color);
border-radius: 4px;
outline: none;
cursor: pointer;
-moz-appearance: none;
-webkit-appearance: none;
/* Removes default arrow from firefox */
+ text-indent: 0.01px;
+ background-color: var(--main-background-color);
+}
+/* cancel stylistic differences in padding in firefox
+for "appearance: none"-style (or equivalent) <select>s */
+@-moz-document url-prefix() {
+ #crate-search {
+ padding-left: 0px; /* == 4px - 4px */
+ padding-right: 19px; /* == 23px - 4px */
+ }
+}
+/* pseudo-element for holding the dropdown-arrow image; needs to be a separate thing
+so that we can apply CSS-filters to change the arrow color in themes */
+#crate-search-div::after {
+ /* lets clicks through! */
+ pointer-events: none;
+ /* completely covers the underlying div */
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ content: "";
background-repeat: no-repeat;
- background-color: transparent;
background-size: 20px;
- background-position: calc(100% - 1px) 56%;
+ background-position: calc(100% - 2px) 56%;
+ /* image is black color, themes should apply a "filter" property to change the color */
background-image: /* AUTOREPLACE: */url("down-arrow.svg");
- max-width: 100%;
- text-overflow: ellipsis;
}
-.search-container {
- margin-top: 4px;
+#crate-search > option {
+ font-size: 1rem;
}
.search-input {
/* Override Normalize.css: it has a rule that sets
@@ -988,11 +963,15 @@ table,
-moz-box-sizing: border-box !important;
box-sizing: border-box !important;
outline: none;
- border: 1px solid;
+ border: 1px solid var(--border-color);
border-radius: 2px;
padding: 8px;
font-size: 1rem;
width: 100%;
+ background-color: var(--button-background-color);
+}
+.search-input:focus {
+ border-color: var(--search-input-focused-border-color);
}
.search-results {
@@ -1015,7 +994,6 @@ table,
.search-results > a {
display: block;
- width: 100%;
/* A little margin ensures the browser's outlining of focused links has room to display. */
margin-left: 2px;
margin-right: 2px;
@@ -1034,12 +1012,6 @@ table,
padding-right: 1em;
}
-.search-results .result-name > span {
- display: inline-block;
- margin: 0;
- font-weight: normal;
-}
-
.popover {
font-size: 1rem;
position: absolute;
@@ -1048,7 +1020,7 @@ table,
display: block;
margin-top: 7px;
border-radius: 3px;
- border: 1px solid;
+ border: 1px solid var(--border-color);
font-size: 1rem;
}
@@ -1057,7 +1029,7 @@ table,
content: '';
position: absolute;
right: 11px;
- border: solid;
+ border: solid var(--border-color);
border-width: 1px 1px 0 0;
display: inline-block;
padding: 4px;
@@ -1093,13 +1065,13 @@ table,
text-align: center;
display: block;
margin: 10px 0;
- border-bottom: 1px solid;
+ border-bottom: 1px solid var(--border-color);
padding-bottom: 4px;
margin-bottom: 6px;
}
#help-button span.bottom {
clear: both;
- border-top: 1px solid;
+ border-top: 1px solid var(--border-color);
}
.side-by-side {
text-align: initial;
@@ -1133,6 +1105,7 @@ table,
.stab .emoji {
font-size: 1.25rem;
+ margin-right: 0.3rem;
}
/* Black one-pixel outline around emoji shapes */
@@ -1170,36 +1143,125 @@ table,
padding-left: 12px;
padding-right: 2px;
position: initial;
+ float: right;
+}
+
+.rightside:not(a),
+.out-of-band {
+ color: var(--right-side-color);
}
+
.impl-items .srclink, .impl .srclink, .methods .srclink {
/* Override header settings otherwise it's too bold */
font-weight: normal;
font-size: 1rem;
}
-.rightside {
- float: right;
+td.summary-column {
+ width: 100%;
}
-.variants_table {
- width: 100%;
+.summary {
+ padding-right: 0px;
}
-.variants_table tbody tr td:first-child {
- width: 1%; /* make the variant name as small as possible */
+pre.rust .question-mark {
+ font-weight: bold;
}
-td.summary-column {
- width: 100%;
+.example-wrap.compile_fail,
+.example-wrap.should_panic {
+ border-left: 2px solid var(--codeblock-error-color);
}
-.summary {
- padding-right: 0px;
+.ignore.example-wrap {
+ border-left: 2px solid var(--codeblock-ignore-color);
}
-pre.rust .question-mark {
+.example-wrap.compile_fail:hover,
+.example-wrap.should_panic:hover {
+ border-left: 2px solid var(--codeblock-error-hover-color);
+}
+
+.example-wrap.ignore:hover {
+ border-left: 2px solid var(--codeblock-ignore-hover-color);
+}
+
+.example-wrap.compile_fail .tooltip,
+.example-wrap.should_panic .tooltip {
+ color: var(--codeblock-error-color);
+}
+
+.example-wrap.ignore .tooltip {
+ color: var(--codeblock-ignore-color);
+}
+
+.example-wrap.compile_fail:hover .tooltip,
+.example-wrap.should_panic:hover .tooltip {
+ color: var(--codeblock-error-hover-color);
+}
+
+.example-wrap.ignore:hover .tooltip {
+ color: var(--codeblock-ignore-hover-color);
+}
+
+.example-wrap .tooltip {
+ position: absolute;
+ display: block;
+ cursor: pointer;
+ left: -25px;
+ top: 5px;
+}
+
+.example-wrap .tooltip::after {
+ display: none;
+ text-align: center;
+ padding: 5px 3px 3px 3px;
+ border-radius: 6px;
+ margin-left: 5px;
+ font-size: 1rem;
+ border: 1px solid var(--border-color);
+ position: absolute;
+ width: max-content;
+ top: -2px;
+ z-index: 1;
+}
+
+.example-wrap .tooltip::before {
+ content: " ";
+ position: absolute;
+ top: 50%;
+ left: 16px;
+ margin-top: -5px;
+ border-width: 5px;
+ border-style: solid;
+ display: none;
+ z-index: 1;
+}
+
+.example-wrap.ignore .tooltip::after {
+ content: "This example is not tested";
+}
+.example-wrap.compile_fail .tooltip::after {
+ content: "This example deliberately fails to compile";
+}
+.example-wrap.should_panic .tooltip::after {
+ content: "This example panics";
+}
+.example-wrap.edition .tooltip::after {
+ content: "This code runs with edition " attr(data-edition);
+}
+
+.example-wrap .tooltip:hover::before, .example-wrap .tooltip:hover::after {
+ display: inline;
+}
+
+.example-wrap.compile_fail .tooltip,
+.example-wrap.should_panic .tooltip,
+.example-wrap.ignore .tooltip {
font-weight: bold;
+ font-size: 1.25rem;
}
a.test-arrow {
@@ -1216,12 +1278,13 @@ a.test-arrow {
.example-wrap:hover .test-arrow {
visibility: visible;
}
-a.test-arrow:hover{
+a.test-arrow:hover {
text-decoration: none;
}
.code-attribute {
font-weight: 300;
+ color: var(--code-attribute-color);
}
.item-spacer {
@@ -1230,7 +1293,6 @@ a.test-arrow:hover{
}
.out-of-band > span.since {
- position: initial;
font-size: 1.25rem;
}
@@ -1258,12 +1320,6 @@ h3.variant {
margin-left: 24px;
}
-.toggle-label {
- display: inline-block;
- margin-left: 4px;
- margin-top: 3px;
-}
-
:target > code, :target > .code-header {
opacity: 1;
}
@@ -1272,61 +1328,6 @@ h3.variant {
padding-right: 3px;
}
-.information {
- position: absolute;
- left: -25px;
- margin-top: 7px;
- z-index: 1;
-}
-
-.tooltip {
- position: relative;
- display: inline-block;
- cursor: pointer;
-}
-
-.tooltip::after {
- display: none;
- text-align: center;
- padding: 5px 3px 3px 3px;
- border-radius: 6px;
- margin-left: 5px;
- font-size: 1rem;
-}
-
-.tooltip.ignore::after {
- content: "This example is not tested";
-}
-.tooltip.compile_fail::after {
- content: "This example deliberately fails to compile";
-}
-.tooltip.should_panic::after {
- content: "This example panics";
-}
-.tooltip.edition::after {
- content: "This code runs with edition " attr(data-edition);
-}
-
-.tooltip::before {
- content: " ";
- position: absolute;
- top: 50%;
- left: 16px;
- margin-top: -5px;
- border-width: 5px;
- border-style: solid;
- display: none;
-}
-
-.tooltip:hover::before, .tooltip:hover::after {
- display: inline;
-}
-
-.tooltip.compile_fail, .tooltip.should_panic, .tooltip.ignore {
- font-weight: bold;
- font-size: 1.25rem;
-}
-
.notable-traits-tooltip {
display: inline-block;
cursor: pointer;
@@ -1368,7 +1369,7 @@ h3.variant {
display: block;
}
-.notable-traits .docblock code.content{
+.notable-traits .docblock code.content {
margin: 0;
padding: 0;
font-size: 1.25rem;
@@ -1402,27 +1403,19 @@ pre.rust {
}
#titles {
- height: 35px;
+ display: flex;
+ flex-direction: row;
+ gap: 1px;
+ margin-bottom: 4px;
}
#titles > button {
- float: left;
- width: 33.3%;
text-align: center;
font-size: 1.125rem;
cursor: pointer;
border: 0;
border-top: 2px solid;
-}
-
-#titles > button:first-child:last-child {
- margin-right: 1px;
- width: calc(100% - 1px);
-}
-
-#titles > button:not(:last-child) {
- margin-right: 1px;
- width: calc(33.3% - 1px);
+ flex: 1;
}
#titles > button > div.count {
@@ -1457,7 +1450,7 @@ pre.rust {
#source-sidebar > .title {
font-size: 1.5rem;
text-align: center;
- border-bottom: 1px solid;
+ border-bottom: 1px solid var(--border-color);
margin-bottom: 6px;
}
#sidebar-toggle > button {
@@ -1483,23 +1476,29 @@ pre.rust {
outline: none;
}
-#copy-path {
- height: 34px;
-}
#settings-menu > a, #help-button > button, #copy-path {
padding: 5px;
width: 33px;
- border: 1px solid;
+ border: 1px solid var(--border-color);
border-radius: 2px;
cursor: pointer;
}
-#settings-menu {
- padding: 0;
-}
+
#settings-menu > a, #help-button > button {
padding: 5px;
height: 100%;
display: block;
+ background-color: var(--button-background-color);
+}
+
+#copy-path {
+ color: var(--copy-path-button-color);
+}
+#copy-path > img {
+ filter: var(--copy-path-img-filter);
+}
+#copy-path:hover > img {
+ filter: var(--copy-path-img-hover-filter);
}
@keyframes rotating {
@@ -1542,85 +1541,25 @@ input:checked + .slider {
}
#copy-path {
- background: initial;
+ height: 34px;
+ background-color: var(--main-background-color);
margin-left: 10px;
padding: 0;
padding-left: 2px;
border: 0;
}
-#theme-choices {
- display: none;
- position: absolute;
- left: 0;
- top: 28px;
- border: 1px solid;
- border-radius: 3px;
- z-index: 1;
- cursor: pointer;
-}
-
-#theme-choices > button {
- border: none;
- width: 100%;
- padding: 4px 8px;
- text-align: center;
- background: rgba(0,0,0,0);
- overflow-wrap: normal;
-}
-
-#theme-choices > button:not(:first-child) {
- border-top: 1px solid;
-}
-
kbd {
display: inline-block;
padding: 3px 5px;
font: 15px monospace;
line-height: 10px;
vertical-align: middle;
- border: solid 1px;
+ border: solid 1px var(--border-color);
border-radius: 3px;
cursor: default;
}
-.hidden-by-impl-hider,
-.hidden-by-usual-hider {
- /* important because of conflicting rule for small screens */
- display: none !important;
-}
-
-#implementations-list > h3 > span.in-band {
- width: 100%;
-}
-
-.table-display {
- width: 100%;
- border: 0;
- border-collapse: collapse;
- border-spacing: 0;
- font-size: 1rem;
-}
-
-.table-display tr td:first-child {
- padding-right: 0;
-}
-
-.table-display tr td:last-child {
- float: right;
-}
-.table-display .out-of-band {
- position: relative;
- font-size: 1.125rem;
- display: block;
-}
-
-.table-display td:hover .anchor {
- display: block;
- top: 2px;
- left: -5px;
-}
-
#main-content > ul {
padding-left: 10px;
}
@@ -1681,6 +1620,12 @@ details.rustdoc-toggle > summary::before {
opacity: .5;
}
+details.rustdoc-toggle > summary.hideme > span,
+details.rustdoc-toggle > summary::before,
+.more-examples-toggle summary, .more-examples-toggle .hide-more {
+ color: var(--toggles-color);
+}
+
/* Screen readers see the text version at the end the line.
Visual readers see the icon at the start of the line, but small and transparent. */
details.rustdoc-toggle > summary::after {
@@ -1785,7 +1730,7 @@ in storage.js plus the media query with (max-width: 700px)
to prevent an overlay between the "collapse toggle" and the information tooltip.
However, it's not needed with smaller screen width because the doc/code block is always put
"one line" below. */
- .docblock > .information:first-child > .tooltip {
+ .docblock > .example-wrap:first-child .tooltip {
margin-top: 16px;
}
@@ -1826,7 +1771,6 @@ in storage.js plus the media query with (min-width: 701px)
padding-top: 0px;
}
- .rustdoc,
.main-heading {
flex-direction: column;
}
@@ -1852,10 +1796,6 @@ in storage.js plus the media query with (min-width: 701px)
display: none;
}
- .sidebar-elems {
- margin-top: 1em;
- }
-
.sidebar {
position: fixed;
top: 45px;
@@ -1949,13 +1889,10 @@ in storage.js plus the media query with (min-width: 701px)
}
.sidebar-elems {
+ margin-top: 1em;
background-color: var(--sidebar-background-color);
}
- .source nav:not(.sidebar).sub {
- margin-left: 32px;
- }
-
.content {
margin-left: 0px;
}
@@ -1964,28 +1901,12 @@ in storage.js plus the media query with (min-width: 701px)
margin-top: 10px;
}
- #search {
- margin-left: 0;
- padding: 0;
- }
-
.anchor {
display: none !important;
}
- .notable-traits {
- position: absolute;
- left: -22px;
- top: 24px;
- }
-
#titles > button > div.count {
- float: left;
- width: 100%;
- }
-
- #titles {
- height: 50px;
+ display: block;
}
/* Because of ios, we need to actually have a full height sidebar title so the
@@ -2092,6 +2013,11 @@ in storage.js plus the media query with (min-width: 701px)
#main-content > div > details.rustdoc-toggle > summary::before {
left: -11px;
}
+
+ /* Align summary-nested and unnested item-info gizmos. */
+ .content .impl-items > .item-info {
+ margin-left: 34px;
+ }
}
@media print {
@@ -2111,15 +2037,6 @@ in storage.js plus the media query with (min-width: 701px)
}
@media (max-width: 464px) {
- #titles, #titles > button {
- height: 73px;
- }
-
- #main-content > table:not(.table-display) td {
- word-break: break-word;
- width: 50%;
- }
-
#crate-search {
border-radius: 4px;
}
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index c42cac59b..e7a898e9f 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -14,6 +14,27 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--scrollbar-thumb-background-color: #5c6773;
--scrollbar-color: #5c6773 #24292f;
--headings-border-bottom-color: #5c6773;
+ --border-color: #5c6773;
+ --button-background-color: #141920;
+ --right-side-color: grey;
+ --code-attribute-color: #999;
+ --toggles-color: #999;
+ --search-input-focused-border-color: #5c6773; /* Same as `--border-color`. */
+ --copy-path-button-color: #fff;
+ --copy-path-img-filter: invert(70%);
+ --copy-path-img-hover-filter: invert(100%);
+ --codeblock-error-hover-color: rgb(255, 0, 0);
+ --codeblock-error-color: rgba(255, 0, 0, .5);
+ --codeblock-ignore-hover-color: rgb(255, 142, 0);
+ --codeblock-ignore-color: rgba(255, 142, 0, .6);
+ --type-link-color: #ffa0a5;
+ --trait-link-color: #39afd7;
+ --assoc-item-link-color: #39afd7;
+ --function-link-color: #fdd687;
+ --macro-link-color: #a37acc;
+ --keyword-link-color: #39afd7;
+ --mod-link-color: #39afd7;
+ --link-color: #39afd7;
}
.slider {
@@ -36,10 +57,6 @@ h4 {
border: none;
}
-.in-band {
- background-color: #0f1419;
-}
-
.docblock code {
color: #ffb454;
}
@@ -49,7 +66,7 @@ h4 {
.docblock pre > code, pre > code {
color: #e6e1cf;
}
-span code {
+.item-info code {
color: #e6e1cf;
}
.docblock a > code {
@@ -84,17 +101,14 @@ pre, .rustdoc.source .example-wrap {
border-right: 1px solid #ffb44c;
}
-.docblock table td, .docblock table th {
- border-color: #5c6773;
-}
-
.search-results a:hover {
- background-color: #777;
+ color: #fff !important;
+ background-color: #3c3c3c;
}
.search-results a:focus {
- color: #000 !important;
- background-color: #c6afb3;
+ color: #fff !important;
+ background-color: #3c3c3c;
}
.search-results a {
color: #0096cf;
@@ -105,97 +119,37 @@ pre, .rustdoc.source .example-wrap {
.content .item-info::before { color: #ccc; }
-.content span.foreigntype, .content a.foreigntype { color: #ffa0a5; }
-.content span.union, .content a.union { color: #ffa0a5; }
-.content span.constant, .content a.constant,
-.content span.static, .content a.static { color: #39AFD7; }
-.content span.primitive, .content a.primitive { color: #ffa0a5; }
-.content span.traitalias, .content a.traitalias { color: #39AFD7; }
-.content span.keyword, .content a.keyword { color: #39AFD7; }
-
-.content span.externcrate, .content span.mod, .content a.mod {
- color: #39AFD7;
-}
-.content span.struct, .content a.struct {
- color: #ffa0a5;
-}
-.content span.enum, .content a.enum {
- color: #ffa0a5;
-}
-.content span.trait, .content a.trait {
- color: #39AFD7;
-}
-.content span.type, .content a.type {
- color: #39AFD7;
-}
-.content span.type,
-.content a.type,
-.block a.current.type { color: #39AFD7; }
-.content span.associatedtype,
-.content a.associatedtype,
-.block a.current.associatedtype { color: #39AFD7; }
-.content span.fn, .content a.fn, .content span.method,
-.content a.method, .content span.tymethod,
-.content a.tymethod, .content .fnname {
- color: #fdd687;
-}
-.content span.attr, .content a.attr, .content span.derive,
-.content a.derive, .content span.macro, .content a.macro {
- color: #a37acc;
-}
-
.sidebar a { color: #53b1db; }
.sidebar a.current.type { color: #53b1db; }
-.sidebar a.current.associatedtype { color: #53b1db; }
pre.rust .comment { color: #788797; }
pre.rust .doccomment { color: #a1ac88; }
-nav.main .current {
- border-top-color: #5c6773;
- border-bottom-color: #5c6773;
-}
-nav.main .separator {
- border: 1px solid #5c6773;
-}
-a {
- color: #39AFD7;
-}
-
.sidebar h2 a,
.sidebar h3 a {
color: white;
}
-.search-results a {
- color: #0096cf;
-}
body.source .example-wrap pre.rust a {
background: #333;
}
-details.rustdoc-toggle > summary.hideme > span,
-details.rustdoc-toggle > summary::before {
- color: #999;
-}
-
details.rustdoc-toggle > summary::before {
filter: invert(100%);
}
-#crate-search, .search-input {
- background-color: #141920;
- border-color: #424c57;
+#crate-search-div::after {
+ /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
+ filter: invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);
}
-
-#crate-search {
- /* Without the `!important`, the border-color is ignored for `<select>`...
- It cannot be in the group above because `.search-input` has a different border color on
- hover. */
- border-color: #424c57 !important;
+#crate-search:hover, #crate-search:focus {
+ border-color: #e0e0e0 !important;
+}
+#crate-search-div:hover::after, #crate-search-div:focus-within::after {
+ filter: invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);
}
.search-input {
- color: #ffffff;
+ color: #fff;
}
.module-item .stab,
@@ -203,20 +157,9 @@ details.rustdoc-toggle > summary::before {
color: #000;
}
-/* Created this empty rule to satisfy the theme checks. */
-.stab.empty-impl {}
-.stab.must_implement {}
-
-.stab.unstable,
-.stab.deprecated,
-.stab.portability,
-.stab.empty-impl,
-.stab.must_implement {
+.stab {
color: #c5c5c5;
background: #314559 !important;
- border-style: none !important;
- border-radius: 4px;
- padding: 3px 6px 3px 6px;
}
.stab.portability > code {
@@ -224,11 +167,6 @@ details.rustdoc-toggle > summary::before {
background: none;
}
-.rightside,
-.out-of-band {
- color: grey;
-}
-
.result-name .primitive > i, .result-name .keyword > i {
color: #788797;
}
@@ -239,7 +177,7 @@ details.rustdoc-toggle > summary::before {
pre.rust .number, pre.rust .string { color: #b8cc52; }
pre.rust .kw, pre.rust .kw-2, pre.rust .prelude-ty,
pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .op, pre.rust .lifetime { color: #ff7733; }
+pre.rust .lifetime { color: #ff7733; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #a37acc; }
pre.rust .question-mark {
color: #ff9011;
@@ -251,9 +189,6 @@ pre.rust .self {
pre.rust .attribute {
color: #e6e1cf;
}
-pre.rust .attribute .ident, pre.rust .attribute .op {
- color: #e6e1cf;
-}
.example-wrap > pre.line-number {
color: #5c67736e;
@@ -272,64 +207,11 @@ a.test-arrow:hover {
color: #c5c5c5;
}
-.toggle-label,
-.code-attribute {
- color: #999;
-}
-
:target {
background: rgba(255, 236, 164, 0.06);
border-right: 3px solid rgba(255, 180, 76, 0.85);
}
-pre.compile_fail {
- border-left: 2px solid rgba(255,0,0,.4);
-}
-
-pre.compile_fail:hover, .information:hover + pre.compile_fail {
- border-left: 2px solid #f00;
-}
-
-pre.should_panic {
- border-left: 2px solid rgba(255,0,0,.4);
-}
-
-pre.should_panic:hover, .information:hover + pre.should_panic {
- border-left: 2px solid #f00;
-}
-
-pre.ignore {
- border-left: 2px solid rgba(255,142,0,.6);
-}
-
-pre.ignore:hover, .information:hover + pre.ignore {
- border-left: 2px solid #ff9200;
-}
-
-.tooltip.compile_fail {
- color: rgba(255,0,0,.5);
-}
-
-.information > .compile_fail:hover {
- color: #f00;
-}
-
-.tooltip.should_panic {
- color: rgba(255,0,0,.5);
-}
-
-.information > .should_panic:hover {
- color: #f00;
-}
-
-.tooltip.ignore {
- color: rgba(255,142,0,.6);
-}
-
-.information > .ignore:hover {
- color: #ff9200;
-}
-
.search-failed a {
color: #39AFD7;
}
@@ -337,7 +219,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
.tooltip::after {
background-color: #314559;
color: #c5c5c5;
- border: 1px solid #5c6773;
}
.tooltip::before {
@@ -346,11 +227,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
.notable-traits-tooltiptext {
background-color: #314559;
- border-color: #5c6773;
-}
-
-.notable-traits-tooltiptext .notable {
- border-bottom-color: #5c6773;
}
#titles > button.selected {
@@ -378,38 +254,11 @@ individually rather than as a group) */
/* FIXME: these rules should be at the bottom of the file but currently must be
above the `@media (max-width: 700px)` rules due to a bug in the css checker */
/* see https://github.com/rust-lang/rust/pull/71237#issuecomment-618170143 */
-.search-input:focus {}
-.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,
-.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro {}
-.content span.struct,.content a.struct,.block a.current.struct {}
-#titles>button:hover,#titles>button.selected {}
-.content span.typedef,.content a.typedef,.block a.current.typedef {}
-.content span.union,.content a.union,.block a.current.union {}
pre.rust .lifetime {}
-.stab.unstable {}
-h2,
-h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {}
-.content span.enum,.content a.enum,.block a.current.enum {}
-.content span.constant,.content a.constant,.block a.current.constant,.content span.static,
-.content a.static, .block a.current.static {}
-.content span.keyword,.content a.keyword,.block a.current.keyword {}
-pre.rust .comment {}
-.content span.traitalias,.content a.traitalias,.block a.current.traitalias {}
-.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,
-.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,
-.content .fnname {}
pre.rust .kw {}
-pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,
-pre.rust .attribute .ident {}
-.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype {}
-pre.rust .doccomment {}
-.stab.deprecated {}
-.content a.attr,.content a.derive,.content a.macro {}
-.stab.portability {}
-.content span.primitive,.content a.primitive,.block a.current.primitive {}
-.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod {}
-pre.rust .kw-2,pre.rust .prelude-ty {}
-.content span.trait,.content a.trait,.block a.current.trait {}
+#titles > button:hover, #titles > button.selected {}
+pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {}
+pre.rust .kw-2, pre.rust .prelude-ty {}
.search-results a:focus span {}
a.result-trait:focus {}
@@ -445,32 +294,18 @@ a.result-keyword:focus {}
.sidebar a.current.constant
.sidebar a.current.static {}
.sidebar a.current.primitive {}
-.sidebar a.current.externcrate
-.sidebar a.current.mod {}
.sidebar a.current.trait {}
.sidebar a.current.traitalias {}
-.sidebar a.current.fn,
-.sidebar a.current.method,
-.sidebar a.current.tymethod {}
+.sidebar a.current.fn {}
.sidebar a.current.keyword {}
-@media (max-width: 700px) {
- .sidebar-elems {
- border-right-color: #5c6773;
- }
-}
-
kbd {
color: #c5c5c5;
background-color: #314559;
- border-color: #5c6773;
- border-bottom-color: #5c6773;
box-shadow: inset 0 -1px 0 #5c6773;
}
#settings-menu > a, #help-button > button {
- border-color: #5c6773;
- background-color: #0f1419;
color: #fff;
}
@@ -478,39 +313,11 @@ kbd {
filter: invert(100);
}
-.popover, .popover::before,
-#help-button span.top, #help-button span.bottom {
- border-color: #5c6773;
-}
-
-#copy-path {
- color: #fff;
-}
-#copy-path > img {
- filter: invert(70%);
-}
-#copy-path:hover > img {
- filter: invert(100%);
-}
-
#settings-menu > a:hover, #settings-menu > a:focus,
#help-button > button:hover, #help-button > button:focus {
border-color: #e0e0e0;
}
-#theme-choices {
- border-color: #5c6773;
- background-color: #0f1419;
-}
-
-#theme-choices > button:not(:first-child) {
- border-top-color: #5c6773;
-}
-
-#theme-choices > button:hover, #theme-choices > button:focus {
- background-color: rgba(110, 110, 110, 0.33);
-}
-
.search-results .result-name span.alias {
color: #c5c5c5;
}
@@ -520,7 +327,6 @@ kbd {
#source-sidebar > .title {
color: #fff;
- border-bottom-color: #5c6773;
}
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
@@ -540,9 +346,6 @@ kbd {
border-color: white;
color: white;
}
-.more-examples-toggle summary, .more-examples-toggle .hide-more {
- color: #999;
-}
.scraped-example .example-wrap .rust span.highlight {
background: rgb(91, 59, 1);
}
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index a550eb1c1..07a1ed8b7 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -9,6 +9,27 @@
--scrollbar-thumb-background-color: rgba(32, 34, 37, .6);
--scrollbar-color: rgba(32,34,37,.6) #5a5a5a;
--headings-border-bottom-color: #d2d2d2;
+ --border-color: #e0e0e0;
+ --button-background-color: #f0f0f0;
+ --right-side-color: grey;
+ --code-attribute-color: #999;
+ --toggles-color: #999;
+ --search-input-focused-border-color: #008dfd;
+ --copy-path-button-color: #999;
+ --copy-path-img-filter: invert(50%);
+ --copy-path-img-hover-filter: invert(65%);
+ --codeblock-error-hover-color: rgb(255, 0, 0);
+ --codeblock-error-color: rgba(255, 0, 0, .5);
+ --codeblock-ignore-hover-color: rgb(255, 142, 0);
+ --codeblock-ignore-color: rgba(255, 142, 0, .6);
+ --type-link-color: #2dbfb8;
+ --trait-link-color: #b78cf2;
+ --assoc-item-link-color: #d2991d;
+ --function-link-color: #2bab63;
+ --macro-link-color: #09bd00;
+ --keyword-link-color: #d2991d;
+ --mod-link-color: #d2991d;
+ --link-color: #d2991d;
}
.slider {
@@ -21,10 +42,6 @@ input:focus + .slider {
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
}
-.in-band {
- background-color: #353535;
-}
-
.rust-logo {
filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
@@ -42,10 +59,6 @@ input:focus + .slider {
background-color: #0a042f !important;
}
-.docblock table td, .docblock table th {
- border-color: #ddd;
-}
-
.search-results a:hover {
background-color: #777;
}
@@ -78,35 +91,10 @@ a.result-keyword:focus { background-color: #884719; }
.content .item-info::before { color: #ccc; }
-.content span.enum, .content a.enum, .block a.current.enum { color: #2dbfb8; }
-.content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; }
-.content span.type, .content a.type, .block a.current.type { color: #2dbfb8; }
-.content span.associatedtype,
-.content a.associatedtype,
-.block a.current.associatedtype { color: #D2991D; }
-.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #2dbfb8; }
-.content span.attr, .content a.attr, .block a.current.attr,
-.content span.derive, .content a.derive, .block a.current.derive,
-.content span.macro, .content a.macro, .block a.current.macro { color: #09bd00; }
-.content span.union, .content a.union, .block a.current.union { color: #2dbfb8; }
-.content span.constant, .content a.constant, .block a.current.constant,
-.content span.static, .content a.static, .block a.current.static { color: #D2991D; }
-.content span.primitive, .content a.primitive, .block a.current.primitive { color: #2dbfb8; }
-.content span.externcrate,
-.content span.mod, .content a.mod, .block a.current.mod { color: #D2991D; }
-.content span.trait, .content a.trait, .block a.current.trait { color: #b78cf2; }
-.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #b78cf2; }
-.content span.fn, .content a.fn, .block a.current.fn,
-.content span.method, .content a.method, .block a.current.method,
-.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
-.content .fnname{ color: #2BAB63; }
-.content span.keyword, .content a.keyword, .block a.current.keyword { color: #D2991D; }
-
.sidebar a { color: #fdbf35; }
.sidebar a.current.enum { color: #12ece2; }
.sidebar a.current.struct { color: #12ece2; }
.sidebar a.current.type { color: #12ece2; }
-.sidebar a.current.associatedtype { color: #fdbf35; }
.sidebar a.current.foreigntype { color: #12ece2; }
.sidebar a.current.attr,
.sidebar a.current.derive,
@@ -115,74 +103,42 @@ a.result-keyword:focus { background-color: #884719; }
.sidebar a.current.constant
.sidebar a.current.static { color: #fdbf35; }
.sidebar a.current.primitive { color: #12ece2; }
-.sidebar a.current.externcrate
-.sidebar a.current.mod { color: #fdbf35; }
.sidebar a.current.trait { color: #cca7ff; }
.sidebar a.current.traitalias { color: #cca7ff; }
-.sidebar a.current.fn,
-.sidebar a.current.method,
-.sidebar a.current.tymethod { color: #32d479; }
+.sidebar a.current.fn { color: #32d479; }
.sidebar a.current.keyword { color: #fdbf35; }
pre.rust .comment { color: #8d8d8b; }
pre.rust .doccomment { color: #8ca375; }
-nav.main .current {
- border-top-color: #eee;
- border-bottom-color: #eee;
-}
-nav.main .separator {
- border-color: #eee;
-}
-
-a {
- color: #D2991D;
-}
-
body.source .example-wrap pre.rust a {
background: #333;
}
-details.rustdoc-toggle > summary.hideme > span,
-details.rustdoc-toggle > summary::before {
- color: #999;
-}
-
details.rustdoc-toggle > summary::before {
filter: invert(100%);
}
-#crate-search, .search-input {
+.search-input {
color: #111;
- background-color: #f0f0f0;
- border-color: #f0f0f0;
}
-#crate-search {
- /* Without the `!important`, the border-color is ignored for `<select>`...
- It cannot be in the group above because `.search-input` has a different border color on
- hover. */
- border-color: #f0f0f0 !important;
+#crate-search-div::after {
+ /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
+ filter: invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);
}
-
-.search-input {
- border-color: #e0e0e0;
+#crate-search:hover, #crate-search:focus {
+ border-color: #2196f3 !important;
}
-
-.search-input:focus {
- border-color: #008dfd;
+#crate-search-div:hover::after, #crate-search-div:focus-within::after {
+ filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
}
-.stab.empty-impl { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; }
-.stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; }
-.stab.deprecated { background: #ffc4c4; border-color: #db7b7b; color: #2f2f2f; }
-.stab.must_implement { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; }
-.stab.portability { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; }
-.stab.portability > code { background: none; }
+.stab { background: #314559; }
-.rightside,
-.out-of-band {
- color: grey;
+.stab.portability > code {
+ color: #e6e1cf;
+ background: none;
}
.line-numbers :target { background-color: transparent; }
@@ -192,7 +148,7 @@ pre.rust .kw { color: #ab8ac1; }
pre.rust .kw-2, pre.rust .prelude-ty { color: #769acb; }
pre.rust .number, pre.rust .string { color: #83a300; }
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .attribute, pre.rust .attribute .ident { color: #ee6868; }
+pre.rust .attribute { color: #ee6868; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
pre.rust .lifetime { color: #d97f26; }
pre.rust .question-mark {
@@ -212,64 +168,11 @@ a.test-arrow:hover{
background-color: #4e8bca;
}
-.toggle-label,
-.code-attribute {
- color: #999;
-}
-
:target {
background-color: #494a3d;
border-right: 3px solid #bb7410;
}
-pre.compile_fail {
- border-left: 2px solid rgba(255,0,0,.8);
-}
-
-pre.compile_fail:hover, .information:hover + pre.compile_fail {
- border-left: 2px solid #f00;
-}
-
-pre.should_panic {
- border-left: 2px solid rgba(255,0,0,.8);
-}
-
-pre.should_panic:hover, .information:hover + pre.should_panic {
- border-left: 2px solid #f00;
-}
-
-pre.ignore {
- border-left: 2px solid rgba(255,142,0,.6);
-}
-
-pre.ignore:hover, .information:hover + pre.ignore {
- border-left: 2px solid #ff9200;
-}
-
-.tooltip.compile_fail {
- color: rgba(255,0,0,.8);
-}
-
-.information > .compile_fail:hover {
- color: #f00;
-}
-
-.tooltip.should_panic {
- color: rgba(255,0,0,.8);
-}
-
-.information > .should_panic:hover {
- color: #f00;
-}
-
-.tooltip.ignore {
- color: rgba(255,142,0,.6);
-}
-
-.information > .ignore:hover {
- color: #ff9200;
-}
-
.search-failed a {
color: #0089ff;
}
@@ -286,11 +189,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
.notable-traits-tooltiptext {
background-color: #111;
- border-color: #777;
-}
-
-.notable-traits-tooltiptext .notable {
- border-bottom-color: #d2d2d2;
}
#titles > button:not(.selected) {
@@ -307,23 +205,13 @@ pre.ignore:hover, .information:hover + pre.ignore {
color: #888;
}
-@media (max-width: 700px) {
- .sidebar-elems {
- border-right-color: #000;
- }
-}
-
kbd {
color: #000;
background-color: #fafbfc;
- border-color: #d1d5da;
- border-bottom-color: #c6cbd1;
box-shadow: inset 0 -1px 0 #c6cbd1;
}
#settings-menu > a, #help-button > button {
- border-color: #e0e0e0;
- background: #f0f0f0;
color: #000;
}
@@ -332,34 +220,6 @@ kbd {
border-color: #ffb900;
}
-.popover, .popover::before,
-#help-button span.top, #help-button span.bottom {
- border-color: #d2d2d2;
-}
-
-#copy-path {
- color: #999;
-}
-#copy-path > img {
- filter: invert(50%);
-}
-#copy-path:hover > img {
- filter: invert(65%);
-}
-
-#theme-choices {
- border-color: #e0e0e0;
- background-color: #353535;
-}
-
-#theme-choices > button:not(:first-child) {
- border-top-color: #e0e0e0;
-}
-
-#theme-choices > button:hover, #theme-choices > button:focus {
- background-color: #4e4e4e;
-}
-
.search-results .result-name span.alias {
color: #fff;
}
@@ -367,9 +227,6 @@ kbd {
color: #ccc;
}
-#source-sidebar > .title {
- border-bottom-color: #ccc;
-}
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
background-color: #444;
@@ -386,9 +243,6 @@ kbd {
border-color: white;
color: white;
}
-.more-examples-toggle summary, .more-examples-toggle .hide-more {
- color: #999;
-}
.scraped-example .example-wrap .rust span.highlight {
background: rgb(91, 59, 1);
}
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index b751acff1..64335f629 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -9,6 +9,27 @@
--scrollbar-thumb-background-color: rgba(36, 37, 39, 0.6);
--scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9;
--headings-border-bottom-color: #ddd;
+ --border-color: #e0e0e0;
+ --button-background-color: #fff;
+ --right-side-color: grey;
+ --code-attribute-color: #999;
+ --toggles-color: #999;
+ --search-input-focused-border-color: #66afe9;
+ --copy-path-button-color: #999;
+ --copy-path-img-filter: invert(50%);
+ --copy-path-img-hover-filter: invert(35%);
+ --codeblock-error-hover-color: rgb(255, 0, 0);
+ --codeblock-error-color: rgba(255, 0, 0, .5);
+ --codeblock-ignore-hover-color: rgb(255, 142, 0);
+ --codeblock-ignore-color: rgba(255, 142, 0, .6);
+ --type-link-color: #ad378a;
+ --trait-link-color: #6e4fc9;
+ --assoc-item-link-color: #3873ad;
+ --function-link-color: #ad7c37;
+ --macro-link-color: #068000;
+ --keyword-link-color: #3873ad;
+ --mod-link-color: #3873ad;
+ --link-color: #3873ad;
}
.slider {
@@ -21,10 +42,6 @@ input:focus + .slider {
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
}
-.in-band {
- background-color: white;
-}
-
.rust-logo {
/* This rule exists to force other themes to explicitly style the logo.
* Rustdoc has a custom linter for this purpose.
@@ -41,10 +58,6 @@ input:focus + .slider {
background-color: #FDFFD3 !important;
}
-.docblock table td, .docblock table th {
- border-color: #ddd;
-}
-
.search-results a:hover {
background-color: #ddd;
}
@@ -77,35 +90,10 @@ a.result-keyword:focus { background-color: #afc6e4; }
.content .item-info::before { color: #ccc; }
-.content span.enum, .content a.enum, .block a.current.enum { color: #AD378A; }
-.content span.struct, .content a.struct, .block a.current.struct { color: #AD378A; }
-.content span.type, .content a.type, .block a.current.type { color: #AD378A; }
-.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #3873AD; }
-.content span.associatedtype,
-.content a.associatedtype,
-.block a.current.associatedtype { color: #3873AD; }
-.content span.attr, .content a.attr, .block a.current.attr,
-.content span.derive, .content a.derive, .block a.current.derive,
-.content span.macro, .content a.macro, .block a.current.macro { color: #068000; }
-.content span.union, .content a.union, .block a.current.union { color: #AD378A; }
-.content span.constant, .content a.constant, .block a.current.constant,
-.content span.static, .content a.static, .block a.current.static { color: #3873AD; }
-.content span.primitive, .content a.primitive, .block a.current.primitive { color: #AD378A; }
-.content span.externcrate,
-.content span.mod, .content a.mod, .block a.current.mod { color: #3873AD; }
-.content span.trait, .content a.trait, .block a.current.trait { color: #6E4FC9; }
-.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #5137AD; }
-.content span.fn, .content a.fn, .block a.current.fn,
-.content span.method, .content a.method, .block a.current.method,
-.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
-.content .fnname { color: #AD7C37; }
-.content span.keyword, .content a.keyword, .block a.current.keyword { color: #3873AD; }
-
.sidebar a { color: #356da4; }
.sidebar a.current.enum { color: #a63283; }
.sidebar a.current.struct { color: #a63283; }
.sidebar a.current.type { color: #a63283; }
-.sidebar a.current.associatedtype { color: #356da4; }
.sidebar a.current.foreigntype { color: #356da4; }
.sidebar a.current.attr,
.sidebar a.current.derive,
@@ -114,64 +102,29 @@ a.result-keyword:focus { background-color: #afc6e4; }
.sidebar a.current.constant
.sidebar a.current.static { color: #356da4; }
.sidebar a.current.primitive { color: #a63283; }
-.sidebar a.current.externcrate
-.sidebar a.current.mod { color: #356da4; }
.sidebar a.current.trait { color: #6849c3; }
.sidebar a.current.traitalias { color: #4b349e; }
-.sidebar a.current.fn,
-.sidebar a.current.method,
-.sidebar a.current.tymethod { color: #a67736; }
+.sidebar a.current.fn { color: #a67736; }
.sidebar a.current.keyword { color: #356da4; }
-nav.main .current {
- border-top-color: #000;
- border-bottom-color: #000;
-}
-nav.main .separator {
- border: 1px solid #000;
-}
-
-a {
- color: #3873AD;
-}
-
body.source .example-wrap pre.rust a {
background: #eee;
}
-details.rustdoc-toggle > summary.hideme > span,
-details.rustdoc-toggle > summary::before {
- color: #999;
+#crate-search-div::after {
+ /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
+ filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);
}
-
-#crate-search, .search-input {
- background-color: white;
- border-color: #e0e0e0;
-}
-
-#crate-search {
- /* Without the `!important`, the border-color is ignored for `<select>`...
- It cannot be in the group above because `.search-input` has a different border color on
- hover. */
- border-color: #e0e0e0 !important;
+#crate-search:hover, #crate-search:focus {
+ border-color: #717171 !important;
}
-
-.search-input:focus {
- border-color: #66afe9;
+#crate-search-div:hover::after, #crate-search-div:focus-within::after {
+ filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);
}
-.stab.empty-impl { background: #FFF5D6; border-color: #FFC600; }
-.stab.unstable { background: #FFF5D6; border-color: #FFC600; }
-.stab.deprecated { background: #ffc4c4; border-color: #db7b7b; }
-.stab.must_implement { background: #F3DFFF; border-color: #b07bdb; }
-.stab.portability { background: #F3DFFF; border-color: #b07bdb; }
+.stab { background: #FFF5D6; border-color: #FFC600; }
.stab.portability > code { background: none; }
-.rightside,
-.out-of-band {
- color: grey;
-}
-
.line-numbers :target { background-color: transparent; }
/* Code highlighting */
@@ -179,7 +132,7 @@ pre.rust .kw { color: #8959A8; }
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
pre.rust .number, pre.rust .string { color: #718C00; }
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
+pre.rust .attribute { color: #C82829; }
pre.rust .comment { color: #8E908C; }
pre.rust .doccomment { color: #4D4D4C; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
@@ -201,64 +154,11 @@ a.test-arrow:hover{
background-color: #4e8bca;
}
-.toggle-label,
-.code-attribute {
- color: #999;
-}
-
:target {
background: #FDFFD3;
border-right: 3px solid #AD7C37;
}
-pre.compile_fail {
- border-left: 2px solid rgba(255,0,0,.5);
-}
-
-pre.compile_fail:hover, .information:hover + pre.compile_fail {
- border-left: 2px solid #f00;
-}
-
-pre.should_panic {
- border-left: 2px solid rgba(255,0,0,.5);
-}
-
-pre.should_panic:hover, .information:hover + pre.should_panic {
- border-left: 2px solid #f00;
-}
-
-pre.ignore {
- border-left: 2px solid rgba(255,142,0,.6);
-}
-
-pre.ignore:hover, .information:hover + pre.ignore {
- border-left: 2px solid #ff9200;
-}
-
-.tooltip.compile_fail {
- color: rgba(255,0,0,.5);
-}
-
-.information > .compile_fail:hover {
- color: #f00;
-}
-
-.tooltip.should_panic {
- color: rgba(255,0,0,.5);
-}
-
-.information > .should_panic:hover {
- color: #f00;
-}
-
-.tooltip.ignore {
- color: rgba(255,142,0,.6);
-}
-
-.information > .ignore:hover {
- color: #ff9200;
-}
-
.search-failed a {
color: #3873AD;
}
@@ -274,11 +174,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
.notable-traits-tooltiptext {
background-color: #eee;
- border-color: #999;
-}
-
-.notable-traits-tooltiptext .notable {
- border-bottom-color: #DDDDDD;
}
#titles > button:not(.selected) {
@@ -295,58 +190,17 @@ pre.ignore:hover, .information:hover + pre.ignore {
color: #888;
}
-@media (max-width: 700px) {
- .sidebar-elems {
- border-right-color: #000;
- }
-}
-
kbd {
color: #000;
background-color: #fafbfc;
- border-color: #d1d5da;
- border-bottom-color: #c6cbd1;
box-shadow: inset 0 -1px 0 #c6cbd1;
}
-#settings-menu > a, #help-button > button {
- border-color: #e0e0e0;
- background-color: #fff;
-}
-
#settings-menu > a:hover, #settings-menu > a:focus,
#help-button > button:hover, #help-button > button:focus {
border-color: #717171;
}
-.popover, .popover::before,
-#help-button span.top, #help-button span.bottom {
- border-color: #DDDDDD;
-}
-
-#copy-path {
- color: #999;
-}
-#copy-path > img {
- filter: invert(50%);
-}
-#copy-path:hover > img {
- filter: invert(35%);
-}
-
-#theme-choices {
- border-color: #ccc;
- background-color: #fff;
-}
-
-#theme-choices > button:not(:first-child) {
- border-top-color: #e0e0e0;
-}
-
-#theme-choices > button:hover, #theme-choices > button:focus {
- background-color: #eee;
-}
-
.search-results .result-name span.alias {
color: #000;
}
@@ -354,9 +208,6 @@ kbd {
color: #999;
}
-#source-sidebar > .title {
- border-bottom-color: #ccc;
-}
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
background-color: #E0E0E0;
@@ -372,9 +223,6 @@ kbd {
border-color: black;
color: black;
}
-.more-examples-toggle summary, .more-examples-toggle .hide-more {
- color: #999;
-}
.scraped-example .example-wrap .rust span.highlight {
background: #fcffd6;
}
diff --git a/src/librustdoc/html/static/images/down-arrow.svg b/src/librustdoc/html/static/images/down-arrow.svg
index 35437e77a..5d76a64e9 100644
--- a/src/librustdoc/html/static/images/down-arrow.svg
+++ b/src/librustdoc/html/static/images/down-arrow.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="128" height="128" enable-background="new 0 0 128 128" version="1.1" viewBox="-30 -20 176 176" xml:space="preserve"><g><line x1="111" x2="64" y1="40.5" y2="87.499" fill="none" stroke="#2F3435" stroke-linecap="square" stroke-miterlimit="10" stroke-width="12"/><line x1="64" x2="17" y1="87.499" y2="40.5" fill="none" stroke="#2F3435" stroke-linecap="square" stroke-miterlimit="10" stroke-width="12"/></g></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="128" height="128" enable-background="new 0 0 128 128" version="1.1" viewBox="-30 -20 176 176" xml:space="preserve"><g><line x1="111" x2="64" y1="40.5" y2="87.499" fill="none" stroke="#000000" stroke-linecap="square" stroke-miterlimit="10" stroke-width="12"/><line x1="64" x2="17" y1="87.499" y2="40.5" fill="none" stroke="#000000" stroke-linecap="square" stroke-miterlimit="10" stroke-width="12"/></g></svg> \ No newline at end of file
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 0702b2b0b..6e9660ddc 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -348,8 +348,7 @@ function loadCss(cssFileName) {
function onHashChange(ev) {
// If we're in mobile mode, we should hide the sidebar in any case.
- const sidebar = document.getElementsByClassName("sidebar")[0];
- removeClass(sidebar, "shown");
+ hideSidebar();
handleHashes(ev);
}
@@ -501,6 +500,10 @@ function loadCss(cssFileName) {
const synthetic_implementors = document.getElementById("synthetic-implementors-list");
const inlined_types = new Set();
+ const TEXT_IDX = 0;
+ const SYNTHETIC_IDX = 1;
+ const TYPES_IDX = 2;
+
if (synthetic_implementors) {
// This `inlined_types` variable is used to avoid having the same implementation
// showing up twice. For example "String" in the "Sync" doc page.
@@ -525,9 +528,9 @@ function loadCss(cssFileName) {
// We don't want to include impls from this JS file, when the HTML already has them.
// The current crate should always be ignored. Other crates that should also be
// ignored are included in the attribute `data-ignore-extern-crates`.
- const ignoreExternCrates = document
- .querySelector("script[data-ignore-extern-crates]")
- .getAttribute("data-ignore-extern-crates");
+ const script = document
+ .querySelector("script[data-ignore-extern-crates]");
+ const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : "";
for (const lib of libs) {
if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) {
continue;
@@ -536,10 +539,12 @@ function loadCss(cssFileName) {
struct_loop:
for (const struct of structs) {
- const list = struct.synthetic ? synthetic_implementors : implementors;
+ const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors;
- if (struct.synthetic) {
- for (const struct_type of struct.types) {
+ // The types list is only used for synthetic impls.
+ // If this changes, `main.js` and `write_shared.rs` both need changed.
+ if (struct[SYNTHETIC_IDX]) {
+ for (const struct_type of struct[TYPES_IDX]) {
if (inlined_types.has(struct_type)) {
continue struct_loop;
}
@@ -548,7 +553,7 @@ function loadCss(cssFileName) {
}
const code = document.createElement("h3");
- code.innerHTML = struct.text;
+ code.innerHTML = struct[TEXT_IDX];
addClass(code, "code-header");
addClass(code, "in-band");
@@ -694,9 +699,8 @@ function loadCss(cssFileName) {
(function() {
// To avoid checking on "rustdoc-line-numbers" value on every loop...
- let lineNumbersFunc = () => {};
if (getSettingValue("line-numbers") === "true") {
- lineNumbersFunc = x => {
+ onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => {
const count = x.textContent.split("\n").length;
const elems = [];
for (let i = 0; i < count; ++i) {
@@ -706,33 +710,54 @@ function loadCss(cssFileName) {
addClass(node, "line-number");
node.innerHTML = elems.join("\n");
x.parentNode.insertBefore(node, x);
- };
+ });
}
- onEachLazy(document.getElementsByClassName("rust-example-rendered"), e => {
- if (hasClass(e, "compile_fail")) {
- e.addEventListener("mouseover", function() {
- this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
- });
- e.addEventListener("mouseout", function() {
- this.parentElement.previousElementSibling.childNodes[0].style.color = "";
- });
- } else if (hasClass(e, "ignore")) {
- e.addEventListener("mouseover", function() {
- this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
- });
- e.addEventListener("mouseout", function() {
- this.parentElement.previousElementSibling.childNodes[0].style.color = "";
- });
- }
- lineNumbersFunc(e);
- });
}());
+ let oldSidebarScrollPosition = null;
+
+ function showSidebar() {
+ if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
+ // This is to keep the scroll position on mobile.
+ oldSidebarScrollPosition = window.scrollY;
+ document.body.style.width = `${document.body.offsetWidth}px`;
+ document.body.style.position = "fixed";
+ document.body.style.top = `-${oldSidebarScrollPosition}px`;
+ document.querySelector(".mobile-topbar").style.top = `${oldSidebarScrollPosition}px`;
+ document.querySelector(".mobile-topbar").style.position = "relative";
+ } else {
+ oldSidebarScrollPosition = null;
+ }
+ const sidebar = document.getElementsByClassName("sidebar")[0];
+ addClass(sidebar, "shown");
+ }
+
function hideSidebar() {
+ if (oldSidebarScrollPosition !== null) {
+ // This is to keep the scroll position on mobile.
+ document.body.style.width = "";
+ document.body.style.position = "";
+ document.body.style.top = "";
+ document.querySelector(".mobile-topbar").style.top = "";
+ document.querySelector(".mobile-topbar").style.position = "";
+ // The scroll position is lost when resetting the style, hence why we store it in
+ // `oldSidebarScrollPosition`.
+ window.scrollTo(0, oldSidebarScrollPosition);
+ oldSidebarScrollPosition = null;
+ }
const sidebar = document.getElementsByClassName("sidebar")[0];
removeClass(sidebar, "shown");
}
+ window.addEventListener("resize", () => {
+ if (window.innerWidth >= window.RUSTDOC_MOBILE_BREAKPOINT &&
+ oldSidebarScrollPosition !== null) {
+ // If the user opens the sidebar in "mobile" mode, and then grows the browser window,
+ // we need to switch away from mobile mode and make the main content area scrollable.
+ hideSidebar();
+ }
+ });
+
function handleClick(id, f) {
const elem = document.getElementById(id);
if (elem) {
@@ -775,9 +800,9 @@ function loadCss(cssFileName) {
sidebar_menu_toggle.addEventListener("click", () => {
const sidebar = document.getElementsByClassName("sidebar")[0];
if (!hasClass(sidebar, "shown")) {
- addClass(sidebar, "shown");
+ showSidebar();
} else {
- removeClass(sidebar, "shown");
+ hideSidebar();
}
});
}
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 75c7bd45a..d04ec357c 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -429,9 +429,9 @@ function initSearch(rawSearchIndex) {
}
const posBefore = parserState.pos;
getNextElem(query, parserState, elems, endChar === ">");
- // This case can be encountered if `getNextElem` encounted a "stop character" right from
- // the start. For example if you have `,,` or `<>`. In this case, we simply move up the
- // current position to continue the parsing.
+ // This case can be encountered if `getNextElem` encountered a "stop character" right
+ // from the start. For example if you have `,,` or `<>`. In this case, we simply move up
+ // the current position to continue the parsing.
if (posBefore === parserState.pos) {
parserState.pos += 1;
}
@@ -581,7 +581,7 @@ function initSearch(rawSearchIndex) {
const elem = document.getElementById("crate-search");
if (elem &&
- elem.value !== "All crates" &&
+ elem.value !== "all crates" &&
hasOwnPropertyRustdoc(rawSearchIndex, elem.value)
) {
return elem.value;
@@ -1551,12 +1551,6 @@ function initSearch(rawSearchIndex) {
return [displayPath, href];
}
- function escape(content) {
- const h1 = document.createElement("h1");
- h1.textContent = content;
- return h1.innerHTML;
- }
-
function pathSplitter(path) {
const tmp = "<span>" + path.replace(/::/g, "::</span><span>");
if (tmp.endsWith("<span>")) {
@@ -1710,22 +1704,15 @@ function initSearch(rawSearchIndex) {
let crates = "";
const crates_list = Object.keys(rawSearchIndex);
if (crates_list.length > 1) {
- crates = " in <select id=\"crate-search\"><option value=\"All crates\">" +
- "All crates</option>";
+ crates = " in&nbsp;<div id=\"crate-search-div\"><select id=\"crate-search\">" +
+ "<option value=\"all crates\">all crates</option>";
for (const c of crates_list) {
crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`;
}
- crates += "</select>";
- }
-
- let typeFilter = "";
- if (results.query.typeFilter !== NO_TYPE_FILTER) {
- typeFilter = " (type: " + escape(itemTypes[results.query.typeFilter]) + ")";
+ crates += "</select></div>";
}
- let output = "<div id=\"search-settings\">" +
- `<h1 class="search-results-title">Results for ${escape(results.query.userQuery)}` +
- `${typeFilter}</h1>${crates}</div>`;
+ let output = `<h1 class="search-results-title">Results${crates}</h1>`;
if (results.query.error !== null) {
output += `<h3>Query parser error: "${results.query.error}".</h3>`;
output += "<div id=\"titles\">" +
@@ -2245,7 +2232,7 @@ function initSearch(rawSearchIndex) {
}
function updateCrate(ev) {
- if (ev.target.value === "All crates") {
+ if (ev.target.value === "all crates") {
// If we don't remove it from the URL, it'll be picked up again by the search.
const params = searchState.getQueryStringParams();
const query = searchState.input.value.trim();
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index c45d61429..06d15d9e5 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -10,7 +10,7 @@
(function() {
const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
-let oldScrollPosition = 0;
+let oldScrollPosition = null;
const NAME_OFFSET = 0;
const DIRS_OFFSET = 1;
@@ -75,18 +75,21 @@ function toggleSidebar() {
oldScrollPosition = window.scrollY;
document.body.style.position = "fixed";
document.body.style.top = `-${oldScrollPosition}px`;
+ } else {
+ oldScrollPosition = null;
}
addClass(document.documentElement, "source-sidebar-expanded");
child.innerText = "<";
updateLocalStorage("source-sidebar-show", "true");
} else {
- if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
+ if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT && oldScrollPosition !== null) {
// This is to keep the scroll position on mobile.
document.body.style.position = "";
document.body.style.top = "";
// The scroll position is lost when resetting the style, hence why we store it in
- // `oldScroll`.
+ // `oldScrollPosition`.
window.scrollTo(0, oldScrollPosition);
+ oldScrollPosition = null;
}
removeClass(document.documentElement, "source-sidebar-expanded");
child.innerText = ">";
@@ -94,6 +97,17 @@ function toggleSidebar() {
}
}
+window.addEventListener("resize", () => {
+ if (window.innerWidth >= window.RUSTDOC_MOBILE_BREAKPOINT && oldScrollPosition !== null) {
+ // If the user opens the sidebar in "mobile" mode, and then grows the browser window,
+ // we need to switch away from mobile mode and make the main content area scrollable.
+ document.body.style.position = "";
+ document.body.style.top = "";
+ window.scrollTo(0, oldScrollPosition);
+ oldScrollPosition = null;
+ }
+});
+
function createSidebarToggle() {
const sidebarToggle = document.createElement("div");
sidebarToggle.id = "sidebar-toggle";
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 8e25f6764..7caffeae3 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -13,13 +13,13 @@
<link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceCodePro-Regular.ttf.woff2"> {#- -#}
<link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceSerif4-Bold.ttf.woff2"> {#- -#}
<link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceCodePro-Semibold.ttf.woff2"> {#- -#}
- <link rel="stylesheet" type="text/css" {# -#}
+ <link rel="stylesheet" {# -#}
href="{{static_root_path|safe}}normalize{{page.resource_suffix}}.css"> {#- -#}
- <link rel="stylesheet" type="text/css" {# -#}
+ <link rel="stylesheet" {# -#}
href="{{static_root_path|safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
id="mainThemeStyle"> {#- -#}
{%- for theme in themes -%}
- <link rel="stylesheet" type="text/css" {# -#}
+ <link rel="stylesheet" {# -#}
href="{{static_root_path|safe}}{{theme}}{{page.resource_suffix}}.css" {# -#}
{%- if theme == "light" -%}
id="themeStyle"
@@ -51,7 +51,7 @@
href="{{static_root_path|safe}}noscript{{page.resource_suffix}}.css"> {#- -#}
</noscript> {#- -#}
{%- if layout.css_file_extension.is_some() -%}
- <link rel="stylesheet" type="text/css" {# -#}
+ <link rel="stylesheet" {# -#}
href="{{static_root_path|safe}}theme{{page.resource_suffix}}.css"> {#- -#}
{%- endif -%}
{%- if !layout.favicon.is_empty() -%}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 716a4c9ea..49a31f5f1 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -19,6 +19,7 @@ use crate::clean::utils::print_const_expr;
use crate::clean::{self, ItemId};
use crate::formats::item_type::ItemType;
use crate::json::JsonRenderer;
+use crate::passes::collect_intra_doc_links::UrlFragment;
impl JsonRenderer<'_> {
pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
@@ -29,8 +30,14 @@ impl JsonRenderer<'_> {
.get(&item.item_id)
.into_iter()
.flatten()
- .map(|clean::ItemLink { link, did, .. }| {
- (link.clone(), from_item_id((*did).into(), self.tcx))
+ .map(|clean::ItemLink { link, page_id, fragment, .. }| {
+ let id = match fragment {
+ Some(UrlFragment::Item(frag_id)) => *frag_id,
+ // FIXME: Pass the `UserWritten` segment to JSON consumer.
+ Some(UrlFragment::UserWritten(_)) | None => *page_id,
+ };
+
+ (link.clone(), from_item_id(id.into(), self.tcx))
})
.collect();
let docs = item.attrs.collapsed_doc_value();
@@ -46,10 +53,14 @@ impl JsonRenderer<'_> {
clean::KeywordItem => return None,
clean::StrippedItem(ref inner) => {
match &**inner {
- // We document non-empty stripped modules as with `Module::is_stripped` set to
+ // We document stripped modules as with `Module::is_stripped` set to
// `true`, to prevent contained items from being orphaned for downstream users,
// as JSON does no inlining.
- clean::ModuleItem(m) if !m.items.is_empty() => from_clean_item(item, self.tcx),
+ clean::ModuleItem(_)
+ if self.imported_items.contains(&item_id.expect_def_id()) =>
+ {
+ from_clean_item(item, self.tcx)
+ }
_ => return None,
}
}
@@ -59,7 +70,7 @@ impl JsonRenderer<'_> {
id: from_item_id_with_name(item_id, self.tcx, name),
crate_id: item_id.krate().as_u32(),
name: name.map(|sym| sym.to_string()),
- span: self.convert_span(span),
+ span: span.and_then(|span| self.convert_span(span)),
visibility: self.convert_visibility(visibility),
docs,
attrs,
@@ -119,6 +130,16 @@ where
}
}
+impl<I, T, U> FromWithTcx<I> for Vec<U>
+where
+ I: IntoIterator<Item = T>,
+ U: FromWithTcx<T>,
+{
+ fn from_tcx(f: I, tcx: TyCtxt<'_>) -> Vec<U> {
+ f.into_iter().map(|x| x.into_tcx(tcx)).collect()
+ }
+}
+
pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
#[rustfmt::skip]
let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
@@ -130,11 +151,11 @@ impl FromWithTcx<clean::GenericArgs> for GenericArgs {
use clean::GenericArgs::*;
match args {
AngleBracketed { args, bindings } => GenericArgs::AngleBracketed {
- args: args.into_vec().into_iter().map(|a| a.into_tcx(tcx)).collect(),
- bindings: bindings.into_iter().map(|a| a.into_tcx(tcx)).collect(),
+ args: args.into_vec().into_tcx(tcx),
+ bindings: bindings.into_tcx(tcx),
},
Parenthesized { inputs, output } => GenericArgs::Parenthesized {
- inputs: inputs.into_vec().into_iter().map(|a| a.into_tcx(tcx)).collect(),
+ inputs: inputs.into_vec().into_tcx(tcx),
output: output.map(|a| (*a).into_tcx(tcx)),
},
}
@@ -145,7 +166,7 @@ impl FromWithTcx<clean::GenericArg> for GenericArg {
fn from_tcx(arg: clean::GenericArg, tcx: TyCtxt<'_>) -> Self {
use clean::GenericArg::*;
match arg {
- Lifetime(l) => GenericArg::Lifetime(l.0.to_string()),
+ Lifetime(l) => GenericArg::Lifetime(convert_lifetime(l)),
Type(t) => GenericArg::Type(t.into_tcx(tcx)),
Const(box c) => GenericArg::Const(c.into_tcx(tcx)),
Infer => GenericArg::Infer,
@@ -177,9 +198,7 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
use clean::TypeBindingKind::*;
match kind {
Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)),
- Constraint { bounds } => {
- TypeBindingKind::Constraint(bounds.into_iter().map(|a| a.into_tcx(tcx)).collect())
- }
+ Constraint { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
}
}
}
@@ -240,11 +259,11 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)),
FunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)),
ForeignFunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)),
- TraitItem(t) => ItemEnum::Trait(t.into_tcx(tcx)),
+ TraitItem(t) => ItemEnum::Trait((*t).into_tcx(tcx)),
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, header.unwrap(), tcx)),
TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, header.unwrap(), tcx)),
- ImplItem(i) => ItemEnum::Impl(i.into_tcx(tcx)),
+ ImplItem(i) => ItemEnum::Impl((*i).into_tcx(tcx)),
StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
ForeignTypeItem => ItemEnum::ForeignType,
@@ -260,12 +279,12 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
}
TyAssocTypeItem(g, b) => ItemEnum::AssocType {
generics: (*g).into_tcx(tcx),
- bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ bounds: b.into_tcx(tcx),
default: None,
},
AssocTypeItem(t, b) => ItemEnum::AssocType {
generics: t.generics.into_tcx(tcx),
- bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ bounds: b.into_tcx(tcx),
default: Some(t.item_type.unwrap_or(t.type_).into_tcx(tcx)),
},
// `convert_item` early returns `None` for stripped items and keywords.
@@ -292,11 +311,19 @@ impl FromWithTcx<clean::Struct> for Struct {
fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self {
let fields_stripped = struct_.has_stripped_entries();
let clean::Struct { struct_type, generics, fields } = struct_;
+
+ let kind = match struct_type {
+ CtorKind::Fn => StructKind::Tuple(ids_keeping_stripped(fields, tcx)),
+ CtorKind::Const => {
+ assert!(fields.is_empty());
+ StructKind::Unit
+ }
+ CtorKind::Fictive => StructKind::Plain { fields: ids(fields, tcx), fields_stripped },
+ };
+
Struct {
- struct_type: from_ctor_kind(struct_type),
+ kind,
generics: generics.into_tcx(tcx),
- fields_stripped,
- fields: ids(fields, tcx),
impls: Vec::new(), // Added in JsonRenderer::item
}
}
@@ -315,14 +342,6 @@ impl FromWithTcx<clean::Union> for Union {
}
}
-pub(crate) fn from_ctor_kind(struct_type: CtorKind) -> StructType {
- match struct_type {
- CtorKind::Fictive => StructType::Plain,
- CtorKind::Fn => StructType::Tuple,
- CtorKind::Const => StructType::Unit,
- }
-}
-
pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> Header {
Header {
async_: header.is_async(),
@@ -347,15 +366,15 @@ fn convert_abi(a: RustcAbi) -> Abi {
}
}
+fn convert_lifetime(l: clean::Lifetime) -> String {
+ l.0.to_string()
+}
+
impl FromWithTcx<clean::Generics> for Generics {
fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self {
Generics {
- params: generics.params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
- where_predicates: generics
- .where_predicates
- .into_iter()
- .map(|x| x.into_tcx(tcx))
- .collect(),
+ params: generics.params.into_tcx(tcx),
+ where_predicates: generics.where_predicates.into_tcx(tcx),
}
}
}
@@ -374,10 +393,10 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
use clean::GenericParamDefKind::*;
match kind {
Lifetime { outlives } => GenericParamDefKind::Lifetime {
- outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(),
+ outlives: outlives.into_iter().map(convert_lifetime).collect(),
},
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
- bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ bounds: bounds.into_tcx(tcx),
default: default.map(|x| (*x).into_tcx(tcx)),
synthetic,
},
@@ -395,7 +414,7 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
match predicate {
BoundPredicate { ty, bounds, bound_params } => WherePredicate::BoundPredicate {
type_: ty.into_tcx(tcx),
- bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ bounds: bounds.into_tcx(tcx),
generic_params: bound_params
.into_iter()
.map(|x| GenericParamDef {
@@ -405,8 +424,8 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
.collect(),
},
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
- lifetime: lifetime.0.to_string(),
- bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ lifetime: convert_lifetime(lifetime),
+ bounds: bounds.into_tcx(tcx),
},
EqPredicate { lhs, rhs } => {
WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) }
@@ -420,15 +439,13 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
use clean::GenericBound::*;
match bound {
TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
- // FIXME: should `trait_` be a clean::Path equivalent in JSON?
- let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
GenericBound::TraitBound {
- trait_,
- generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ trait_: trait_.into_tcx(tcx),
+ generic_params: generic_params.into_tcx(tcx),
modifier: from_trait_bound_modifier(modifier),
}
}
- Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()),
+ Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
}
}
}
@@ -447,64 +464,49 @@ pub(crate) fn from_trait_bound_modifier(
impl FromWithTcx<clean::Type> for Type {
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
use clean::Type::{
- Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive,
- QPath, RawPointer, Slice, Tuple,
+ Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
+ RawPointer, Slice, Tuple,
};
match ty {
- clean::Type::Path { path } => Type::ResolvedPath {
- name: path.whole_name(),
- id: from_item_id(path.def_id().into(), tcx),
- args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
- param_names: Vec::new(),
- },
- DynTrait(mut bounds, lt) => {
- let first_trait = bounds.remove(0).trait_;
-
- Type::ResolvedPath {
- name: first_trait.whole_name(),
- id: from_item_id(first_trait.def_id().into(), tcx),
- args: first_trait
- .segments
- .last()
- .map(|args| Box::new(args.clone().args.into_tcx(tcx))),
- param_names: bounds
- .into_iter()
- .map(|t| {
- clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None)
- })
- .chain(lt.map(clean::GenericBound::Outlives))
- .map(|bound| bound.into_tcx(tcx))
- .collect(),
- }
- }
+ clean::Type::Path { path } => Type::ResolvedPath(path.into_tcx(tcx)),
+ clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
+ lifetime: lt.map(convert_lifetime),
+ traits: bounds.into_tcx(tcx),
+ }),
Generic(s) => Type::Generic(s.to_string()),
Primitive(p) => Type::Primitive(p.as_sym().to_string()),
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
- Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
+ Tuple(t) => Type::Tuple(t.into_tcx(tcx)),
Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))),
Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s },
- ImplTrait(g) => Type::ImplTrait(g.into_iter().map(|x| x.into_tcx(tcx)).collect()),
+ ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)),
Infer => Type::Infer,
RawPointer(mutability, type_) => Type::RawPointer {
mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)),
},
BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef {
- lifetime: lifetime.map(|l| l.0.to_string()),
+ lifetime: lifetime.map(convert_lifetime),
mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)),
},
- QPath { assoc, self_type, trait_, .. } => {
- // FIXME: should `trait_` be a clean::Path equivalent in JSON?
- let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
- Type::QualifiedPath {
- name: assoc.name.to_string(),
- args: Box::new(assoc.args.clone().into_tcx(tcx)),
- self_type: Box::new((*self_type).into_tcx(tcx)),
- trait_: Box::new(trait_),
- }
- }
+ QPath(box clean::QPathData { assoc, self_type, trait_, .. }) => Type::QualifiedPath {
+ name: assoc.name.to_string(),
+ args: Box::new(assoc.args.into_tcx(tcx)),
+ self_type: Box::new(self_type.into_tcx(tcx)),
+ trait_: trait_.into_tcx(tcx),
+ },
+ }
+ }
+}
+
+impl FromWithTcx<clean::Path> for Path {
+ fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
+ Path {
+ name: path.whole_name(),
+ id: from_item_id(path.def_id().into(), tcx),
+ args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
}
}
}
@@ -528,7 +530,7 @@ impl FromWithTcx<clean::BareFunctionDecl> for FunctionPointer {
async_: false,
abi: convert_abi(abi),
},
- generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ generic_params: generic_params.into_tcx(tcx),
decl: decl.into_tcx(tcx),
}
}
@@ -562,18 +564,25 @@ impl FromWithTcx<clean::Trait> for Trait {
is_unsafe,
items: ids(items, tcx),
generics: generics.into_tcx(tcx),
- bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ bounds: bounds.into_tcx(tcx),
implementations: Vec::new(), // Added in JsonRenderer::item
}
}
}
-impl FromWithTcx<Box<clean::Impl>> for Impl {
- fn from_tcx(impl_: Box<clean::Impl>, tcx: TyCtxt<'_>) -> Self {
+impl FromWithTcx<clean::PolyTrait> for PolyTrait {
+ fn from_tcx(
+ clean::PolyTrait { trait_, generic_params }: clean::PolyTrait,
+ tcx: TyCtxt<'_>,
+ ) -> Self {
+ PolyTrait { trait_: trait_.into_tcx(tcx), generic_params: generic_params.into_tcx(tcx) }
+ }
+}
+
+impl FromWithTcx<clean::Impl> for Impl {
+ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
let provided_trait_methods = impl_.provided_trait_methods(tcx);
- let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = *impl_;
- // FIXME: should `trait_` be a clean::Path equivalent in JSON?
- let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
+ let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
// FIXME: use something like ImplKind in JSON?
let (synthetic, blanket_impl) = match kind {
clean::ImplKind::Normal | clean::ImplKind::FakeVaradic => (false, None),
@@ -591,7 +600,7 @@ impl FromWithTcx<Box<clean::Impl>> for Impl {
.into_iter()
.map(|x| x.to_string())
.collect(),
- trait_,
+ trait_: trait_.map(|path| path.into_tcx(tcx)),
for_: for_.into_tcx(tcx),
items: ids(items, tcx),
negative: negative_polarity,
@@ -642,38 +651,28 @@ impl FromWithTcx<clean::Enum> for Enum {
}
}
-impl FromWithTcx<clean::VariantStruct> for Struct {
- fn from_tcx(struct_: clean::VariantStruct, tcx: TyCtxt<'_>) -> Self {
- let fields_stripped = struct_.has_stripped_entries();
- let clean::VariantStruct { struct_type, fields } = struct_;
- Struct {
- struct_type: from_ctor_kind(struct_type),
- generics: Generics { params: vec![], where_predicates: vec![] },
- fields_stripped,
- fields: ids(fields, tcx),
- impls: Vec::new(),
- }
- }
-}
-
impl FromWithTcx<clean::Variant> for Variant {
fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self {
use clean::Variant::*;
match variant {
- CLike => Variant::Plain,
- Tuple(fields) => Variant::Tuple(
- fields
- .into_iter()
- .map(|f| {
- if let clean::StructFieldItem(ty) = *f.kind {
- ty.into_tcx(tcx)
- } else {
- unreachable!()
- }
- })
- .collect(),
- ),
- Struct(s) => Variant::Struct(ids(s.fields, tcx)),
+ CLike(disr) => Variant::Plain(disr.map(|disr| disr.into_tcx(tcx))),
+ Tuple(fields) => Variant::Tuple(ids_keeping_stripped(fields, tcx)),
+ Struct(s) => Variant::Struct {
+ fields_stripped: s.has_stripped_entries(),
+ fields: ids(s.fields, tcx),
+ },
+ }
+ }
+}
+
+impl FromWithTcx<clean::Discriminant> for Discriminant {
+ fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self {
+ Discriminant {
+ // expr is only none if going throught the inlineing path, which gets
+ // `rustc_middle` types, not `rustc_hir`, but because JSON never inlines
+ // the expr is always some.
+ expr: disr.expr(tcx).unwrap(),
+ value: disr.value(tcx),
}
}
}
@@ -681,24 +680,18 @@ impl FromWithTcx<clean::Variant> for Variant {
impl FromWithTcx<clean::Import> for Import {
fn from_tcx(import: clean::Import, tcx: TyCtxt<'_>) -> Self {
use clean::ImportKind::*;
- match import.kind {
- Simple(s) => Import {
- source: import.source.path.whole_name(),
- name: s.to_string(),
- id: import.source.did.map(ItemId::from).map(|i| from_item_id(i, tcx)),
- glob: false,
- },
- Glob => Import {
- source: import.source.path.whole_name(),
- name: import
- .source
- .path
- .last_opt()
- .unwrap_or_else(|| Symbol::intern("*"))
- .to_string(),
- id: import.source.did.map(ItemId::from).map(|i| from_item_id(i, tcx)),
- glob: true,
- },
+ let (name, glob) = match import.kind {
+ Simple(s) => (s.to_string(), false),
+ Glob => (
+ import.source.path.last_opt().unwrap_or_else(|| Symbol::intern("*")).to_string(),
+ true,
+ ),
+ };
+ Import {
+ source: import.source.path.whole_name(),
+ name,
+ id: import.source.did.map(ItemId::from).map(|i| from_item_id(i, tcx)),
+ glob,
}
}
}
@@ -730,10 +723,7 @@ impl FromWithTcx<Box<clean::Typedef>> for Typedef {
impl FromWithTcx<clean::OpaqueTy> for OpaqueTy {
fn from_tcx(opaque: clean::OpaqueTy, tcx: TyCtxt<'_>) -> Self {
- OpaqueTy {
- bounds: opaque.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
- generics: opaque.generics.into_tcx(tcx),
- }
+ OpaqueTy { bounds: opaque.bounds.into_tcx(tcx), generics: opaque.generics.into_tcx(tcx) }
}
}
@@ -749,10 +739,7 @@ impl FromWithTcx<clean::Static> for Static {
impl FromWithTcx<clean::TraitAlias> for TraitAlias {
fn from_tcx(alias: clean::TraitAlias, tcx: TyCtxt<'_>) -> Self {
- TraitAlias {
- generics: alias.generics.into_tcx(tcx),
- params: alias.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
- }
+ TraitAlias { generics: alias.generics.into_tcx(tcx), params: alias.bounds.into_tcx(tcx) }
}
}
@@ -796,3 +783,19 @@ fn ids(items: impl IntoIterator<Item = clean::Item>, tcx: TyCtxt<'_>) -> Vec<Id>
.map(|i| from_item_id_with_name(i.item_id, tcx, i.name))
.collect()
}
+
+fn ids_keeping_stripped(
+ items: impl IntoIterator<Item = clean::Item>,
+ tcx: TyCtxt<'_>,
+) -> Vec<Option<Id>> {
+ items
+ .into_iter()
+ .map(|i| {
+ if !i.is_stripped() && !i.is_keyword() {
+ Some(from_item_id_with_name(i.item_id, tcx, i.name))
+ } else {
+ None
+ }
+ })
+ .collect()
+}
diff --git a/src/librustdoc/json/import_finder.rs b/src/librustdoc/json/import_finder.rs
new file mode 100644
index 000000000..c5c687df7
--- /dev/null
+++ b/src/librustdoc/json/import_finder.rs
@@ -0,0 +1,38 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_hir::def_id::DefId;
+
+use crate::{
+ clean::{self, Import, ImportSource, Item},
+ fold::DocFolder,
+};
+
+/// Get the id's of all items that are `pub use`d in the crate.
+///
+/// We need this to know if a stripped module is `pub use mod::*`, to decide
+/// if it needs to be kept in the index, despite being stripped.
+///
+/// See [#100973](https://github.com/rust-lang/rust/issues/100973) and
+/// [#101103](https://github.com/rust-lang/rust/issues/101103) for times when
+/// this information is needed.
+pub(crate) fn get_imports(krate: clean::Crate) -> (clean::Crate, FxHashSet<DefId>) {
+ let mut finder = ImportFinder { imported: FxHashSet::default() };
+ let krate = finder.fold_crate(krate);
+ (krate, finder.imported)
+}
+
+struct ImportFinder {
+ imported: FxHashSet<DefId>,
+}
+
+impl DocFolder for ImportFinder {
+ fn fold_item(&mut self, i: Item) -> Option<Item> {
+ match *i.kind {
+ clean::ImportItem(Import { source: ImportSource { did: Some(did), .. }, .. }) => {
+ self.imported.insert(did);
+ Some(i)
+ }
+
+ _ => Some(self.fold_item_recur(i)),
+ }
+ }
+}
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 6364d00d0..5e8f5f6fe 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -5,6 +5,7 @@
//! docs for usage and details.
mod conversions;
+mod import_finder;
use std::cell::RefCell;
use std::fs::{create_dir_all, File};
@@ -12,7 +13,7 @@ use std::io::{BufWriter, Write};
use std::path::PathBuf;
use std::rc::Rc;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
@@ -39,6 +40,7 @@ pub(crate) struct JsonRenderer<'tcx> {
/// The directory where the blob will be written to.
out_path: PathBuf,
cache: Rc<Cache>,
+ imported_items: FxHashSet<DefId>,
}
impl<'tcx> JsonRenderer<'tcx> {
@@ -99,6 +101,7 @@ impl<'tcx> JsonRenderer<'tcx> {
}
fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
+ debug!("Adding foreign trait items");
Rc::clone(&self.cache)
.traits
.iter()
@@ -106,7 +109,10 @@ impl<'tcx> JsonRenderer<'tcx> {
// only need to synthesize items for external traits
if !id.is_local() {
let trait_item = &trait_item.trait_;
- trait_item.items.clone().into_iter().for_each(|i| self.item(i).unwrap());
+ for item in &trait_item.items {
+ trace!("Adding subitem to {id:?}: {:?}", item.item_id);
+ self.item(item.clone()).unwrap();
+ }
let item_id = from_item_id(id.into(), self.tcx);
Some((
item_id.clone(),
@@ -157,12 +163,16 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
tcx: TyCtxt<'tcx>,
) -> Result<(Self, clean::Crate), Error> {
debug!("Initializing json renderer");
+
+ let (krate, imported_items) = import_finder::get_imports(krate);
+
Ok((
JsonRenderer {
tcx,
index: Rc::new(RefCell::new(FxHashMap::default())),
out_path: options.output,
cache: Rc::new(cache),
+ imported_items,
},
krate,
))
@@ -176,7 +186,9 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
/// the hashmap because certain items (traits and types) need to have their mappings for trait
/// implementations filled out before they're inserted.
fn item(&mut self, item: clean::Item) -> Result<(), Error> {
- trace!("rendering {} {:?}", item.type_(), item.name);
+ let item_type = item.type_();
+ let item_name = item.name;
+ trace!("rendering {} {:?}", item_type, item_name);
// Flatten items that recursively store other items. We include orphaned items from
// stripped modules and etc that are otherwise reachable.
@@ -209,11 +221,11 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
}
types::ItemEnum::Method(_)
+ | types::ItemEnum::Module(_)
| types::ItemEnum::AssocConst { .. }
| types::ItemEnum::AssocType { .. }
| types::ItemEnum::PrimitiveType(_) => true,
- types::ItemEnum::Module(_)
- | types::ItemEnum::ExternCrate { .. }
+ types::ItemEnum::ExternCrate { .. }
| types::ItemEnum::Import(_)
| types::ItemEnum::StructField(_)
| types::ItemEnum::Variant(_)
@@ -245,6 +257,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
}
}
+ trace!("done rendering {} {:?}", item_type, item_name);
Ok(())
}
@@ -255,14 +268,20 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
fn after_krate(&mut self) -> Result<(), Error> {
debug!("Done with crate");
+ debug!("Adding Primitve impls");
for primitive in Rc::clone(&self.cache).primitive_locations.values() {
self.get_impls(*primitive);
}
let e = ExternalCrate { crate_num: LOCAL_CRATE };
+ // FIXME(adotinthevoid): Remove this, as it's not consistant with not
+ // inlining foreign items.
+ let foreign_trait_items = self.get_trait_items();
let mut index = (*self.index).clone().into_inner();
- index.extend(self.get_trait_items());
+ index.extend(foreign_trait_items);
+
+ debug!("Constructing Output");
// This needs to be the default HashMap for compatibility with the public interface for
// rustdoc-json-types
#[allow(rustc::default_hash_types)]
@@ -274,10 +293,9 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
paths: self
.cache
.paths
- .clone()
- .into_iter()
- .chain(self.cache.external_paths.clone().into_iter())
- .map(|(k, (path, kind))| {
+ .iter()
+ .chain(&self.cache.external_paths)
+ .map(|(&k, &(ref path, kind))| {
(
from_item_id(k.into(), self.tcx),
types::ItemSummary {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 92380d124..14d695582 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -9,14 +9,14 @@
#![feature(control_flow_enum)]
#![feature(drain_filter)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(test)]
#![feature(never_type)]
#![feature(once_cell)]
#![feature(type_ascription)]
#![feature(iter_intersperse)]
#![feature(type_alias_impl_trait)]
-#![feature(generic_associated_types)]
+#![cfg_attr(bootstrap, feature(generic_associated_types))]
#![recursion_limit = "256"]
#![warn(rustc::internal)]
#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index 240aec52c..e76c19a61 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -64,9 +64,13 @@ where
}
macro_rules! declare_rustdoc_lint {
- ($(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)?) => {
+ (
+ $(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)?
+ $(@feature_gate = $gate:expr;)?
+ ) => {
declare_tool_lint! {
$(#[$attr])* pub rustdoc::$name, $level, $descr
+ $(, @feature_gate = $gate;)?
}
}
}
@@ -123,7 +127,8 @@ declare_rustdoc_lint! {
/// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples
MISSING_DOC_CODE_EXAMPLES,
Allow,
- "detects publicly-exported items without code samples in their documentation"
+ "detects publicly-exported items without code samples in their documentation",
+ @feature_gate = rustc_span::symbol::sym::rustdoc_missing_doc_code_examples;
}
declare_rustdoc_lint! {
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index 4c6e3eb04..48835abf9 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -215,7 +215,6 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> {
None,
);
- let filename = i.span(self.ctx.tcx).filename(self.ctx.sess());
let has_doc_example = tests.found_tests != 0;
// The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
// would presumably panic if a fake `DefIndex` were passed.
@@ -261,13 +260,16 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> {
let should_have_docs = !should_be_ignored
&& (level != lint::Level::Allow || matches!(source, LintLevelSource::Default));
- debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
- self.items.entry(filename).or_default().count_item(
- has_docs,
- has_doc_example,
- should_have_doc_example(self.ctx, i),
- should_have_docs,
- );
+ if let Some(span) = i.span(self.ctx.tcx) {
+ let filename = span.filename(self.ctx.sess());
+ debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
+ self.items.entry(filename).or_default().count_item(
+ has_docs,
+ has_doc_example,
+ should_have_doc_example(self.ctx, i),
+ should_have_docs,
+ );
+ }
}
}
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 0172ef570..381ac7a5d 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,7 +1,8 @@
//! Validates syntax inside Rust code blocks (\`\`\`rust).
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::{
- emitter::Emitter, Applicability, Diagnostic, Handler, LazyFallbackBundle, LintDiagnosticBuilder,
+ emitter::Emitter, translation::Translate, Applicability, Diagnostic, Handler,
+ LazyFallbackBundle, LintDiagnosticBuilder,
};
use rustc_parse::parse_stream_from_source_str;
use rustc_session::parse::ParseSess;
@@ -181,6 +182,16 @@ struct BufferEmitter {
fallback_bundle: LazyFallbackBundle,
}
+impl Translate for BufferEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+ None
+ }
+
+ fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+ &**self.fallback_bundle
+ }
+}
+
impl Emitter for BufferEmitter {
fn emit_diagnostic(&mut self, diag: &Diagnostic) {
let mut buffer = self.buffer.borrow_mut();
@@ -194,12 +205,4 @@ impl Emitter for BufferEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}
-
- fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
- None
- }
-
- fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
- &**self.fallback_bundle
- }
}
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index e86f90833..55d5f303d 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -117,7 +117,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
find_testable_code(dox, &mut tests, ErrorCodes::No, false, None);
- if tests.found_tests == 0 && cx.tcx.sess.is_nightly_build() {
+ if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples {
if should_have_doc_example(cx, item) {
debug!("reporting error for {:?} (hir_id={:?})", item, hir_id);
let sp = item.attr_span(cx.tcx);
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 7d7a63c53..b2a41bfa4 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -223,6 +223,9 @@ enum MalformedGenerics {
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(crate) enum UrlFragment {
Item(DefId),
+ /// A part of a page that isn't a rust item.
+ ///
+ /// Eg: `[Vector Examples](std::vec::Vec#examples)`
UserWritten(String),
}
@@ -477,7 +480,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
// If there's no `::`, it's not an associated item.
// So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
.ok_or_else(|| {
- debug!("found no `::`, assumming {} was correctly not in scope", item_name);
+ debug!("found no `::`, assuming {} was correctly not in scope", item_name);
UnresolvedPath {
item_id,
module_id,
@@ -750,7 +753,7 @@ fn resolve_associated_trait_item<'a>(
///
/// This is just a wrapper around [`TyCtxt::impl_item_implementor_ids()`] and
/// [`TyCtxt::associated_item()`] (with some helpful logging added).
-#[instrument(level = "debug", skip(tcx))]
+#[instrument(level = "debug", skip(tcx), ret)]
fn trait_assoc_to_impl_assoc_item<'tcx>(
tcx: TyCtxt<'tcx>,
impl_id: DefId,
@@ -760,9 +763,7 @@ fn trait_assoc_to_impl_assoc_item<'tcx>(
debug!(?trait_to_impl_assoc_map);
let impl_assoc_id = *trait_to_impl_assoc_map.get(&trait_assoc_id)?;
debug!(?impl_assoc_id);
- let impl_assoc = tcx.associated_item(impl_assoc_id);
- debug!(?impl_assoc);
- Some(impl_assoc)
+ Some(tcx.associated_item(impl_assoc_id))
}
/// Given a type, return all trait impls in scope in `module` for that type.
@@ -1129,7 +1130,7 @@ impl LinkCollector<'_, '_> {
Some(ItemLink {
link: ori_link.link.clone(),
link_text: link_text.clone(),
- did: res.def_id(self.cx.tcx),
+ page_id: res.def_id(self.cx.tcx),
fragment,
})
}
@@ -1148,11 +1149,12 @@ impl LinkCollector<'_, '_> {
item,
&diag_info,
)?;
- let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
+
+ let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
Some(ItemLink {
link: ori_link.link.clone(),
link_text: link_text.clone(),
- did: id,
+ page_id,
fragment,
})
}
@@ -1256,7 +1258,7 @@ impl LinkCollector<'_, '_> {
&mut self,
key: ResolutionInfo,
diag: DiagnosticInfo<'_>,
- // If errors are cached then they are only reported on first ocurrence
+ // If errors are cached then they are only reported on first occurrence
// which we want in some cases but not in others.
cache_errors: bool,
) -> Option<(Res, Option<UrlFragment>)> {
@@ -1807,8 +1809,8 @@ fn resolution_failure(
}
return;
}
- Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
- | Static(_) => "associated item",
+ Trait | TyAlias | ForeignTy | OpaqueTy | ImplTraitPlaceholder
+ | TraitAlias | TyParam | Static(_) => "associated item",
Impl | GlobalAsm => unreachable!("not a path"),
}
} else {
@@ -1893,7 +1895,7 @@ fn disambiguator_error(
diag_info.link_range = disambiguator_range;
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| {
let msg = format!(
- "see {}/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
+ "see {}/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
crate::DOC_RUST_LANG_ORG_CHANNEL
);
diag.note(&msg);
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index f3a3c853c..885dadb32 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -94,6 +94,34 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option<usize> {
if current_pos == end_pos { None } else { Some(current_pos) }
}
+fn extract_path_forward(text: &str, start_pos: usize) -> Option<usize> {
+ use rustc_lexer::{is_id_continue, is_id_start};
+ let mut current_pos = start_pos;
+ loop {
+ if current_pos < text.len() && text[current_pos..].starts_with("::") {
+ current_pos += 2;
+ } else {
+ break;
+ }
+ let mut chars = text[current_pos..].chars();
+ if let Some(c) = chars.next() {
+ if is_id_start(c) {
+ current_pos += c.len_utf8();
+ } else {
+ break;
+ }
+ }
+ while let Some(c) = chars.next() {
+ if is_id_continue(c) {
+ current_pos += c.len_utf8();
+ } else {
+ break;
+ }
+ }
+ }
+ if current_pos == start_pos { None } else { Some(current_pos) }
+}
+
fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool {
// https://spec.commonmark.org/0.30/#raw-html
//
@@ -218,19 +246,68 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
// If a tag looks like `<this>`, it might actually be a generic.
// We don't try to detect stuff `<like, this>` because that's not valid HTML,
// and we don't try to detect stuff `<like this>` because that's not valid Rust.
- if let Some(Some(generics_start)) = (is_open_tag
- && dox[..range.end].ends_with('>'))
+ let mut generics_end = range.end;
+ if let Some(Some(mut generics_start)) = (is_open_tag
+ && dox[..generics_end].ends_with('>'))
.then(|| extract_path_backwards(&dox, range.start))
{
+ while generics_start != 0
+ && generics_end < dox.len()
+ && dox.as_bytes()[generics_start - 1] == b'<'
+ && dox.as_bytes()[generics_end] == b'>'
+ {
+ generics_end += 1;
+ generics_start -= 1;
+ if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
+ generics_start = new_start;
+ }
+ if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+ generics_end = new_end;
+ }
+ }
+ if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+ generics_end = new_end;
+ }
let generics_sp = match super::source_span_for_markdown_range(
tcx,
&dox,
- &(generics_start..range.end),
+ &(generics_start..generics_end),
&item.attrs,
) {
Some(sp) => sp,
None => item.attr_span(tcx),
};
+ // Sometimes, we only extract part of a path. For example, consider this:
+ //
+ // <[u32] as IntoIter<u32>>::Item
+ // ^^^^^ unclosed HTML tag `u32`
+ //
+ // We don't have any code for parsing fully-qualified trait paths.
+ // In theory, we could add it, but doing it correctly would require
+ // parsing the entire path grammar, which is problematic because of
+ // overlap between the path grammar and Markdown.
+ //
+ // The example above shows that ambiguity. Is `[u32]` intended to be an
+ // intra-doc link to the u32 primitive, or is it intended to be a slice?
+ //
+ // If the below conditional were removed, we would suggest this, which is
+ // not what the user probably wants.
+ //
+ // <[u32] as `IntoIter<u32>`>::Item
+ //
+ // We know that the user actually wants to wrap the whole thing in a code
+ // block, but the only reason we know that is because `u32` does not, in
+ // fact, implement IntoIter. If the example looks like this:
+ //
+ // <[Vec<i32>] as IntoIter<i32>::Item
+ //
+ // The ideal fix would be significantly different.
+ if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
+ || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
+ {
+ diag.emit();
+ return;
+ }
// multipart form is chosen here because ``Vec<i32>`` would be confusing.
diag.multipart_suggestion(
"try marking as source code",
@@ -278,7 +355,7 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
for (event, range) in p {
match event {
Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
- Event::Html(text) | Event::Text(text) if !in_code_block => {
+ Event::Html(text) if !in_code_block => {
extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
}
Event::End(Tag::CodeBlock(_)) => in_code_block = false,
diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs
index 0c5d83655..765f7c61b 100644
--- a/src/librustdoc/passes/propagate_doc_cfg.rs
+++ b/src/librustdoc/passes/propagate_doc_cfg.rs
@@ -2,29 +2,74 @@
use std::sync::Arc;
use crate::clean::cfg::Cfg;
-use crate::clean::{Crate, Item};
+use crate::clean::inline::{load_attrs, merge_attrs};
+use crate::clean::{Crate, Item, ItemKind};
use crate::core::DocContext;
use crate::fold::DocFolder;
use crate::passes::Pass;
+use rustc_hir::def_id::LocalDefId;
+
pub(crate) const PROPAGATE_DOC_CFG: Pass = Pass {
name: "propagate-doc-cfg",
run: propagate_doc_cfg,
description: "propagates `#[doc(cfg(...))]` to child items",
};
-pub(crate) fn propagate_doc_cfg(cr: Crate, _: &mut DocContext<'_>) -> Crate {
- CfgPropagator { parent_cfg: None }.fold_crate(cr)
+pub(crate) fn propagate_doc_cfg(cr: Crate, cx: &mut DocContext<'_>) -> Crate {
+ CfgPropagator { parent_cfg: None, parent: None, cx }.fold_crate(cr)
}
-struct CfgPropagator {
+struct CfgPropagator<'a, 'tcx> {
parent_cfg: Option<Arc<Cfg>>,
+ parent: Option<LocalDefId>,
+ cx: &'a mut DocContext<'tcx>,
+}
+
+impl<'a, 'tcx> CfgPropagator<'a, 'tcx> {
+ // Some items need to merge their attributes with their parents' otherwise a few of them
+ // (mostly `cfg` ones) will be missing.
+ fn merge_with_parent_attributes(&mut self, item: &mut Item) {
+ let check_parent = match &*item.kind {
+ // impl blocks can be in different modules with different cfg and we need to get them
+ // as well.
+ ItemKind::ImplItem(_) => false,
+ kind if kind.is_non_assoc() => true,
+ _ => return,
+ };
+
+ let Some(def_id) = item.item_id.as_def_id().and_then(|def_id| def_id.as_local())
+ else { return };
+
+ let hir = self.cx.tcx.hir();
+ let hir_id = hir.local_def_id_to_hir_id(def_id);
+
+ if check_parent {
+ let expected_parent = hir.get_parent_item(hir_id);
+ // If parents are different, it means that `item` is a reexport and we need
+ // to compute the actual `cfg` by iterating through its "real" parents.
+ if self.parent == Some(expected_parent) {
+ return;
+ }
+ }
+
+ let mut attrs = Vec::new();
+ for (parent_hir_id, _) in hir.parent_iter(hir_id) {
+ if let Some(def_id) = hir.opt_local_def_id(parent_hir_id) {
+ attrs.extend_from_slice(load_attrs(self.cx, def_id.to_def_id()));
+ }
+ }
+ let (_, cfg) = merge_attrs(self.cx, None, item.attrs.other_attrs.as_slice(), Some(&attrs));
+ item.cfg = cfg;
+ }
}
-impl DocFolder for CfgPropagator {
+impl<'a, 'tcx> DocFolder for CfgPropagator<'a, 'tcx> {
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
let old_parent_cfg = self.parent_cfg.clone();
+ self.merge_with_parent_attributes(&mut item);
+
let new_cfg = match (self.parent_cfg.take(), item.cfg.take()) {
(None, None) => None,
(Some(rc), None) | (None, Some(rc)) => Some(rc),
@@ -37,8 +82,15 @@ impl DocFolder for CfgPropagator {
self.parent_cfg = new_cfg.clone();
item.cfg = new_cfg;
+ let old_parent =
+ if let Some(def_id) = item.item_id.as_def_id().and_then(|def_id| def_id.as_local()) {
+ self.parent.replace(def_id)
+ } else {
+ self.parent.take()
+ };
let result = self.fold_item_recur(item);
self.parent_cfg = old_parent_cfg;
+ self.parent = old_parent;
Some(result)
}
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 533e2ce46..9914edf30 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -17,6 +17,7 @@ pub(crate) const STRIP_HIDDEN: Pass = Pass {
/// Strip items marked `#[doc(hidden)]`
pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
let mut retained = ItemIdSet::default();
+ let is_json_output = cx.output_format.is_json() && !cx.show_coverage;
// strip all #[doc(hidden)] items
let krate = {
@@ -25,7 +26,12 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
};
// strip all impls referencing stripped items
- let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache };
+ let mut stripper = ImplStripper {
+ retained: &retained,
+ cache: &cx.cache,
+ is_json_output,
+ document_private: cx.render_options.document_private,
+ };
stripper.fold_crate(krate)
}
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index 9ba841a31..f3aa3c7ce 100644
--- a/src/librustdoc/passes/strip_private.rs
+++ b/src/librustdoc/passes/strip_private.rs
@@ -17,6 +17,7 @@ pub(crate) const STRIP_PRIVATE: Pass = Pass {
pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
// This stripper collects all *retained* nodes.
let mut retained = ItemIdSet::default();
+ let is_json_output = cx.output_format.is_json() && !cx.show_coverage;
// strip all private items
{
@@ -24,12 +25,17 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
retained: &mut retained,
access_levels: &cx.cache.access_levels,
update_retained: true,
- is_json_output: cx.output_format.is_json() && !cx.show_coverage,
+ is_json_output,
};
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
}
// strip all impls referencing private items
- let mut stripper = ImplStripper { retained: &retained, cache: &cx.cache };
+ let mut stripper = ImplStripper {
+ retained: &retained,
+ cache: &cx.cache,
+ is_json_output,
+ document_private: cx.render_options.document_private,
+ };
stripper.fold_crate(krate)
}
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 0d419042a..a9d768f01 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -14,17 +14,19 @@ pub(crate) struct Stripper<'a> {
pub(crate) is_json_output: bool,
}
-impl<'a> Stripper<'a> {
- // We need to handle this differently for the JSON output because some non exported items could
- // be used in public API. And so, we need these items as well. `is_exported` only checks if they
- // are in the public API, which is not enough.
- #[inline]
- fn is_item_reachable(&self, item_id: ItemId) -> bool {
- if self.is_json_output {
- self.access_levels.is_reachable(item_id.expect_def_id())
- } else {
- self.access_levels.is_exported(item_id.expect_def_id())
- }
+// We need to handle this differently for the JSON output because some non exported items could
+// be used in public API. And so, we need these items as well. `is_exported` only checks if they
+// are in the public API, which is not enough.
+#[inline]
+fn is_item_reachable(
+ is_json_output: bool,
+ access_levels: &AccessLevels<DefId>,
+ item_id: ItemId,
+) -> bool {
+ if is_json_output {
+ access_levels.is_reachable(item_id.expect_def_id())
+ } else {
+ access_levels.is_exported(item_id.expect_def_id())
}
}
@@ -61,7 +63,9 @@ impl<'a> DocFolder for Stripper<'a> {
| clean::MacroItem(..)
| clean::ForeignTypeItem => {
let item_id = i.item_id;
- if item_id.is_local() && !self.is_item_reachable(item_id) {
+ if item_id.is_local()
+ && !is_item_reachable(self.is_json_output, self.access_levels, item_id)
+ {
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
return None;
}
@@ -84,7 +88,17 @@ impl<'a> DocFolder for Stripper<'a> {
}
// handled in the `strip-priv-imports` pass
- clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
+ clean::ExternCrateItem { .. } => {}
+ clean::ImportItem(ref imp) => {
+ // Because json doesn't inline imports from private modules, we need to mark
+ // the imported item as retained so it's impls won't be stripped.
+ //
+ // FIXME: Is it necessary to check for json output here: See
+ // https://github.com/rust-lang/rust/pull/100325#discussion_r941495215
+ if let Some(did) = imp.source.did && self.is_json_output {
+ self.retained.insert(did.into());
+ }
+ }
clean::ImplItem(..) => {}
@@ -133,6 +147,8 @@ impl<'a> DocFolder for Stripper<'a> {
pub(crate) struct ImplStripper<'a> {
pub(crate) retained: &'a ItemIdSet,
pub(crate) cache: &'a Cache,
+ pub(crate) is_json_output: bool,
+ pub(crate) document_private: bool,
}
impl<'a> DocFolder for ImplStripper<'a> {
@@ -140,8 +156,27 @@ impl<'a> DocFolder for ImplStripper<'a> {
if let clean::ImplItem(ref imp) = *i.kind {
// Impl blocks can be skipped if they are: empty; not a trait impl; and have no
// documentation.
- if imp.trait_.is_none() && imp.items.is_empty() && i.doc_value().is_none() {
- return None;
+ //
+ // There is one special case: if the impl block contains only private items.
+ if imp.trait_.is_none() {
+ // If the only items present are private ones and we're not rendering private items,
+ // we don't document it.
+ if !imp.items.is_empty()
+ && !self.document_private
+ && imp.items.iter().all(|i| {
+ let item_id = i.item_id;
+ item_id.is_local()
+ && !is_item_reachable(
+ self.is_json_output,
+ &self.cache.access_levels,
+ item_id,
+ )
+ })
+ {
+ return None;
+ } else if imp.items.is_empty() && i.doc_value().is_none() {
+ return None;
+ }
}
if let Some(did) = imp.for_.def_id(self.cache) {
if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 0d9684025..ca86ac89e 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -159,7 +159,7 @@ where
return;
}
}
- hir::ExprKind::MethodCall(path, _, call_span) => {
+ hir::ExprKind::MethodCall(path, _, _, call_span) => {
let types = tcx.typeck(ex.hir_id.owner);
let Some(def_id) = types.type_dependent_def_id(ex.hir_id) else {
trace!("type_dependent_def_id({}) = None", ex.hir_id);
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index 0118d7dd2..e7a26cb34 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -1,271 +1,252 @@
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxHashMap;
+use std::collections::hash_map::Entry;
use std::fs;
-use std::hash::{Hash, Hasher};
+use std::iter::Peekable;
use std::path::Path;
+use std::str::Chars;
use rustc_errors::Handler;
#[cfg(test)]
mod tests;
-#[derive(Debug, Clone, Eq)]
+#[derive(Debug)]
pub(crate) struct CssPath {
- pub(crate) name: String,
- pub(crate) children: FxHashSet<CssPath>,
-}
-
-// This PartialEq implementation IS NOT COMMUTATIVE!!!
-//
-// The order is very important: the second object must have all first's rules.
-// However, the first is not required to have all of the second's rules.
-impl PartialEq for CssPath {
- fn eq(&self, other: &CssPath) -> bool {
- if self.name != other.name {
- false
- } else {
- for child in &self.children {
- if !other.children.iter().any(|c| child == c) {
- return false;
- }
- }
- true
+ pub(crate) rules: FxHashMap<String, String>,
+ pub(crate) children: FxHashMap<String, CssPath>,
+}
+
+/// When encountering a `"` or a `'`, returns the whole string, including the quote characters.
+fn get_string(iter: &mut Peekable<Chars<'_>>, string_start: char, buffer: &mut String) {
+ buffer.push(string_start);
+ while let Some(c) = iter.next() {
+ buffer.push(c);
+ if c == '\\' {
+ iter.next();
+ } else if c == string_start {
+ break;
}
}
}
-impl Hash for CssPath {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.name.hash(state);
- for x in &self.children {
- x.hash(state);
+fn get_inside_paren(
+ iter: &mut Peekable<Chars<'_>>,
+ paren_start: char,
+ paren_end: char,
+ buffer: &mut String,
+) {
+ buffer.push(paren_start);
+ while let Some(c) = iter.next() {
+ handle_common_chars(c, buffer, iter);
+ if c == paren_end {
+ break;
}
}
}
-impl CssPath {
- fn new(name: String) -> CssPath {
- CssPath { name, children: FxHashSet::default() }
+/// Skips a `/*` comment.
+fn skip_comment(iter: &mut Peekable<Chars<'_>>) {
+ while let Some(c) = iter.next() {
+ if c == '*' && iter.next() == Some('/') {
+ break;
+ }
}
}
-/// All variants contain the position they occur.
-#[derive(Debug, Clone, Copy)]
-enum Events {
- StartLineComment(usize),
- StartComment(usize),
- EndComment(usize),
- InBlock(usize),
- OutBlock(usize),
-}
-
-impl Events {
- fn get_pos(&self) -> usize {
- match *self {
- Events::StartLineComment(p)
- | Events::StartComment(p)
- | Events::EndComment(p)
- | Events::InBlock(p)
- | Events::OutBlock(p) => p,
+/// Skips a line comment (`//`).
+fn skip_line_comment(iter: &mut Peekable<Chars<'_>>) {
+ while let Some(c) = iter.next() {
+ if c == '\n' {
+ break;
}
}
-
- fn is_comment(&self) -> bool {
- matches!(
- self,
- Events::StartLineComment(_) | Events::StartComment(_) | Events::EndComment(_)
- )
- }
}
-fn previous_is_line_comment(events: &[Events]) -> bool {
- matches!(events.last(), Some(&Events::StartLineComment(_)))
-}
-
-fn is_line_comment(pos: usize, v: &[u8], events: &[Events]) -> bool {
- if let Some(&Events::StartComment(_)) = events.last() {
- return false;
+fn handle_common_chars(c: char, buffer: &mut String, iter: &mut Peekable<Chars<'_>>) {
+ match c {
+ '"' | '\'' => get_string(iter, c, buffer),
+ '/' if iter.peek() == Some(&'*') => skip_comment(iter),
+ '/' if iter.peek() == Some(&'/') => skip_line_comment(iter),
+ '(' => get_inside_paren(iter, c, ')', buffer),
+ '[' => get_inside_paren(iter, c, ']', buffer),
+ _ => buffer.push(c),
}
- v[pos + 1] == b'/'
}
-fn load_css_events(v: &[u8]) -> Vec<Events> {
- let mut pos = 0;
- let mut events = Vec::with_capacity(100);
-
- while pos + 1 < v.len() {
- match v[pos] {
- b'/' if v[pos + 1] == b'*' => {
- events.push(Events::StartComment(pos));
- pos += 1;
- }
- b'/' if is_line_comment(pos, v, &events) => {
- events.push(Events::StartLineComment(pos));
- pos += 1;
- }
- b'\n' if previous_is_line_comment(&events) => {
- events.push(Events::EndComment(pos));
- }
- b'*' if v[pos + 1] == b'/' => {
- events.push(Events::EndComment(pos + 2));
- pos += 1;
- }
- b'{' if !previous_is_line_comment(&events) => {
- if let Some(&Events::StartComment(_)) = events.last() {
- pos += 1;
- continue;
- }
- events.push(Events::InBlock(pos + 1));
- }
- b'}' if !previous_is_line_comment(&events) => {
- if let Some(&Events::StartComment(_)) = events.last() {
- pos += 1;
- continue;
- }
- events.push(Events::OutBlock(pos + 1));
- }
- _ => {}
+/// Returns a CSS property name. Ends when encountering a `:` character.
+///
+/// If the `:` character isn't found, returns `None`.
+///
+/// If a `{` character is encountered, returns an error.
+fn parse_property_name(iter: &mut Peekable<Chars<'_>>) -> Result<Option<String>, String> {
+ let mut content = String::new();
+
+ while let Some(c) = iter.next() {
+ match c {
+ ':' => return Ok(Some(content.trim().to_owned())),
+ '{' => return Err("Unexpected `{` in a `{}` block".to_owned()),
+ '}' => break,
+ _ => handle_common_chars(c, &mut content, iter),
}
- pos += 1;
}
- events
-}
-
-fn get_useful_next(events: &[Events], pos: &mut usize) -> Option<Events> {
- while *pos < events.len() {
- if !events[*pos].is_comment() {
- return Some(events[*pos]);
+ Ok(None)
+}
+
+/// Try to get the value of a CSS property (the `#fff` in `color: #fff`). It'll stop when it
+/// encounters a `{` or a `;` character.
+///
+/// It returns the value string and a boolean set to `true` if the value is ended with a `}` because
+/// it means that the parent block is done and that we should notify the parent caller.
+fn parse_property_value(iter: &mut Peekable<Chars<'_>>) -> (String, bool) {
+ let mut value = String::new();
+ let mut out_block = false;
+
+ while let Some(c) = iter.next() {
+ match c {
+ ';' => break,
+ '}' => {
+ out_block = true;
+ break;
+ }
+ _ => handle_common_chars(c, &mut value, iter),
}
- *pos += 1;
}
- None
+ (value.trim().to_owned(), out_block)
}
-fn get_previous_positions(events: &[Events], mut pos: usize) -> Vec<usize> {
- let mut ret = Vec::with_capacity(3);
+/// This is used to parse inside a CSS `{}` block. If we encounter a new `{` inside it, we consider
+/// it as a new block and therefore recurse into `parse_rules`.
+fn parse_rules(
+ content: &str,
+ selector: String,
+ iter: &mut Peekable<Chars<'_>>,
+ paths: &mut FxHashMap<String, CssPath>,
+) -> Result<(), String> {
+ let mut rules = FxHashMap::default();
+ let mut children = FxHashMap::default();
- ret.push(events[pos].get_pos());
- if pos > 0 {
- pos -= 1;
- }
loop {
- if pos < 1 || !events[pos].is_comment() {
- let x = events[pos].get_pos();
- if *ret.last().unwrap() != x {
- ret.push(x);
- } else {
- ret.push(0);
+ // If the parent isn't a "normal" CSS selector, we only expect sub-selectors and not CSS
+ // properties.
+ if selector.starts_with('@') {
+ parse_selectors(content, iter, &mut children)?;
+ break;
+ }
+ let rule = match parse_property_name(iter)? {
+ Some(r) => {
+ if r.is_empty() {
+ return Err(format!("Found empty rule in selector `{selector}`"));
+ }
+ r
+ }
+ None => break,
+ };
+ let (value, out_block) = parse_property_value(iter);
+ if value.is_empty() {
+ return Err(format!("Found empty value for rule `{rule}` in selector `{selector}`"));
+ }
+ match rules.entry(rule) {
+ Entry::Occupied(mut o) => {
+ *o.get_mut() = value;
+ }
+ Entry::Vacant(v) => {
+ v.insert(value);
}
+ }
+ if out_block {
break;
}
- ret.push(events[pos].get_pos());
- pos -= 1;
- }
- if ret.len() & 1 != 0 && events[pos].is_comment() {
- ret.push(0);
}
- ret.iter().rev().cloned().collect()
-}
-
-fn build_rule(v: &[u8], positions: &[usize]) -> String {
- minifier::css::minify(
- &positions
- .chunks(2)
- .map(|x| ::std::str::from_utf8(&v[x[0]..x[1]]).unwrap_or(""))
- .collect::<String>()
- .trim()
- .chars()
- .filter_map(|c| match c {
- '\n' | '\t' => Some(' '),
- '/' | '{' | '}' => None,
- c => Some(c),
- })
- .collect::<String>()
- .split(' ')
- .filter(|s| !s.is_empty())
- .intersperse(" ")
- .collect::<String>(),
- )
- .map(|css| css.to_string())
- .unwrap_or_else(|_| String::new())
-}
-
-fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> FxHashSet<CssPath> {
- let mut paths = Vec::with_capacity(50);
- while *pos < events.len() {
- if let Some(Events::OutBlock(_)) = get_useful_next(events, pos) {
- *pos += 1;
- break;
+ match paths.entry(selector) {
+ Entry::Occupied(mut o) => {
+ let v = o.get_mut();
+ for (key, value) in rules.into_iter() {
+ v.rules.insert(key, value);
+ }
+ for (sel, child) in children.into_iter() {
+ v.children.insert(sel, child);
+ }
}
- if let Some(Events::InBlock(_)) = get_useful_next(events, pos) {
- paths.push(CssPath::new(build_rule(v, &get_previous_positions(events, *pos))));
- *pos += 1;
+ Entry::Vacant(v) => {
+ v.insert(CssPath { rules, children });
}
- while let Some(Events::InBlock(_)) = get_useful_next(events, pos) {
- if let Some(ref mut path) = paths.last_mut() {
- for entry in inner(v, events, pos).iter() {
- path.children.insert(entry.clone());
- }
+ }
+ Ok(())
+}
+
+pub(crate) fn parse_selectors(
+ content: &str,
+ iter: &mut Peekable<Chars<'_>>,
+ paths: &mut FxHashMap<String, CssPath>,
+) -> Result<(), String> {
+ let mut selector = String::new();
+
+ while let Some(c) = iter.next() {
+ match c {
+ '{' => {
+ let s = minifier::css::minify(selector.trim()).map(|s| s.to_string())?;
+ parse_rules(content, s, iter, paths)?;
+ selector.clear();
}
- }
- if let Some(Events::OutBlock(_)) = get_useful_next(events, pos) {
- *pos += 1;
+ '}' => break,
+ ';' => selector.clear(), // We don't handle inline selectors like `@import`.
+ _ => handle_common_chars(c, &mut selector, iter),
}
}
- paths.iter().cloned().collect()
-}
-
-pub(crate) fn load_css_paths(v: &[u8]) -> CssPath {
- let events = load_css_events(v);
- let mut pos = 0;
-
- let mut parent = CssPath::new("parent".to_owned());
- parent.children = inner(v, &events, &mut pos);
- parent
-}
-
-pub(crate) fn get_differences(against: &CssPath, other: &CssPath, v: &mut Vec<String>) {
- if against.name == other.name {
- for child in &against.children {
- let mut found = false;
- let mut found_working = false;
- let mut tmp = Vec::new();
-
- for other_child in &other.children {
- if child.name == other_child.name {
- if child != other_child {
- get_differences(child, other_child, &mut tmp);
- } else {
- found_working = true;
+ Ok(())
+}
+
+/// The entry point to parse the CSS rules. Every time we encounter a `{`, we then parse the rules
+/// inside it.
+pub(crate) fn load_css_paths(content: &str) -> Result<FxHashMap<String, CssPath>, String> {
+ let mut iter = content.chars().peekable();
+ let mut paths = FxHashMap::default();
+
+ parse_selectors(content, &mut iter, &mut paths)?;
+ Ok(paths)
+}
+
+pub(crate) fn get_differences(
+ origin: &FxHashMap<String, CssPath>,
+ against: &FxHashMap<String, CssPath>,
+ v: &mut Vec<String>,
+) {
+ for (selector, entry) in origin.iter() {
+ match against.get(selector) {
+ Some(a) => {
+ get_differences(&entry.children, &a.children, v);
+ if selector == ":root" {
+ // We need to check that all variables have been set.
+ for rule in entry.rules.keys() {
+ if !a.rules.contains_key(rule) {
+ v.push(format!(" Missing CSS variable `{rule}` in `:root`"));
+ }
}
- found = true;
- break;
}
}
- if !found {
- v.push(format!(" Missing \"{}\" rule", child.name));
- } else if !found_working {
- v.extend(tmp.iter().cloned());
- }
+ None => v.push(format!(" Missing rule `{selector}`")),
}
}
}
pub(crate) fn test_theme_against<P: AsRef<Path>>(
f: &P,
- against: &CssPath,
+ origin: &FxHashMap<String, CssPath>,
diag: &Handler,
) -> (bool, Vec<String>) {
- let data = match fs::read(f) {
+ let against = match fs::read_to_string(f)
+ .map_err(|e| e.to_string())
+ .and_then(|data| load_css_paths(&data))
+ {
Ok(c) => c,
Err(e) => {
- diag.struct_err(&e.to_string()).emit();
+ diag.struct_err(&e).emit();
return (false, vec![]);
}
};
- let paths = load_css_paths(&data);
let mut ret = vec![];
- get_differences(against, &paths, &mut ret);
+ get_differences(origin, &against, &mut ret);
(true, ret)
}
diff --git a/src/librustdoc/theme/tests.rs b/src/librustdoc/theme/tests.rs
index ae8f43c6d..08a174d27 100644
--- a/src/librustdoc/theme/tests.rs
+++ b/src/librustdoc/theme/tests.rs
@@ -44,11 +44,7 @@ rule j end {}
"#;
let mut ret = Vec::new();
- get_differences(
- &load_css_paths(against.as_bytes()),
- &load_css_paths(text.as_bytes()),
- &mut ret,
- );
+ get_differences(&load_css_paths(against).unwrap(), &load_css_paths(text).unwrap(), &mut ret);
assert!(ret.is_empty());
}
@@ -61,46 +57,45 @@ a
c // sdf
d {}
"#;
- let paths = load_css_paths(text.as_bytes());
- assert!(paths.children.contains(&CssPath::new("a b c d".to_owned())));
+ let paths = load_css_paths(text).unwrap();
+ assert!(paths.contains_key(&"a b c d".to_owned()));
}
#[test]
fn test_comparison() {
- let x = r#"
-a {
- b {
- c {}
- }
+ let origin = r#"
+@a {
+ b {}
+ c {}
}
"#;
- let y = r#"
-a {
+ let against = r#"
+@a {
b {}
}
"#;
- let against = load_css_paths(y.as_bytes());
- let other = load_css_paths(x.as_bytes());
+ let origin = load_css_paths(origin).unwrap();
+ let against = load_css_paths(against).unwrap();
let mut ret = Vec::new();
- get_differences(&against, &other, &mut ret);
+ get_differences(&against, &origin, &mut ret);
assert!(ret.is_empty());
- get_differences(&other, &against, &mut ret);
- assert_eq!(ret, vec![" Missing \"c\" rule".to_owned()]);
+ get_differences(&origin, &against, &mut ret);
+ assert_eq!(ret, vec![" Missing rule `c`".to_owned()]);
}
#[test]
fn check_empty_css() {
- let events = load_css_events(&[]);
- assert_eq!(events.len(), 0);
+ let paths = load_css_paths("").unwrap();
+ assert_eq!(paths.len(), 0);
}
#[test]
fn check_invalid_css() {
- let events = load_css_events(b"*");
- assert_eq!(events.len(), 0);
+ let paths = load_css_paths("*").unwrap();
+ assert_eq!(paths.len(), 0);
}
#[test]
@@ -108,10 +103,85 @@ fn test_with_minification() {
let text = include_str!("../html/static/css/themes/dark.css");
let minified = minifier::css::minify(&text).expect("CSS minification failed").to_string();
- let against = load_css_paths(text.as_bytes());
- let other = load_css_paths(minified.as_bytes());
+ let against = load_css_paths(text).unwrap();
+ let other = load_css_paths(&minified).unwrap();
+
+ let mut ret = Vec::new();
+ get_differences(&against, &other, &mut ret);
+ assert!(ret.is_empty());
+}
+
+#[test]
+fn test_media() {
+ let text = r#"
+@media (min-width: 701px) {
+ a:hover {
+ color: #fff;
+ }
+
+ b {
+ x: y;
+ }
+}
+
+@media (max-width: 1001px) {
+ b {
+ x: y;
+ }
+}
+"#;
+
+ let paths = load_css_paths(text).unwrap();
+ let p = paths.get("@media (min-width:701px)");
+ assert!(p.is_some());
+ let p = p.unwrap();
+ assert!(p.children.get("a:hover").is_some());
+ assert!(p.children.get("b").is_some());
+
+ let p = paths.get("@media (max-width:1001px)");
+ assert!(p.is_some());
+ let p = p.unwrap();
+ assert!(p.children.get("b").is_some());
+}
+
+#[test]
+fn test_css_variables() {
+ let x = r#"
+:root {
+ --a: #fff;
+}
+"#;
+
+ let y = r#"
+:root {
+ --a: #fff;
+ --b: #fff;
+}
+"#;
+
+ let against = load_css_paths(x).unwrap();
+ let other = load_css_paths(y).unwrap();
let mut ret = Vec::new();
get_differences(&against, &other, &mut ret);
assert!(ret.is_empty());
+ get_differences(&other, &against, &mut ret);
+ assert_eq!(ret, vec![" Missing CSS variable `--b` in `:root`".to_owned()]);
+}
+
+#[test]
+fn test_weird_rule_value() {
+ let x = r#"
+a[text=("a")] {
+ b: url({;}.png);
+ c: #fff
+}
+"#;
+
+ let paths = load_css_paths(&x).unwrap();
+ let p = paths.get("a[text=(\"a\")]");
+ assert!(p.is_some());
+ let p = p.unwrap();
+ assert_eq!(p.rules.get("b"), Some(&"url({;}.png)".to_owned()));
+ assert_eq!(p.rules.get("c"), Some(&"#fff".to_owned()));
}
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
index 0bb41977c..c40274394 100644
--- a/src/librustdoc/visit.rs
+++ b/src/librustdoc/visit.rs
@@ -20,7 +20,7 @@ pub(crate) trait DocVisitor: Sized {
VariantItem(i) => match i {
Variant::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)),
Variant::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)),
- Variant::CLike => {}
+ Variant::CLike(_) => {}
},
ExternCrateItem { src: _ }
| ImportItem(_)
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ca7a20bf3..c27ac0ac4 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -164,8 +164,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public();
for &i in m.item_ids {
let item = self.cx.tcx.hir().item(i);
+ if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
+ continue;
+ }
self.visit_item(item, None, &mut om);
}
+ for &i in m.item_ids {
+ let item = self.cx.tcx.hir().item(i);
+ // To match the way import precedence works, visit glob imports last.
+ // Later passes in rustdoc will de-duplicate by name and kind, so if glob-
+ // imported items appear last, then they'll be the ones that get discarded.
+ if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
+ self.visit_item(item, None, &mut om);
+ }
+ }
self.inside_public_path = orig_inside_public_path;
om
}
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 761e94c7e..fb1830426 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -9,7 +9,7 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
/// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 16;
+pub const FORMAT_VERSION: u32 = 21;
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
@@ -116,6 +116,35 @@ pub enum Visibility {
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct DynTrait {
+ /// All the traits implemented. One of them is the vtable, and the rest must be auto traits.
+ pub traits: Vec<PolyTrait>,
+ /// The lifetime of the whole dyn object
+ /// ```text
+ /// dyn Debug + 'static
+ /// ^^^^^^^
+ /// |
+ /// this part
+ /// ```
+ pub lifetime: Option<String>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+/// A trait and potential HRTBs
+pub struct PolyTrait {
+ #[serde(rename = "trait")]
+ pub trait_: Path,
+ /// Used for Higher-Rank Trait Bounds (HRTBs)
+ /// ```text
+ /// dyn for<'a> Fn() -> &'a i32"
+ /// ^^^^^^^
+ /// |
+ /// this part
+ /// ```
+ pub generic_params: Vec<GenericParamDef>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GenericArgs {
/// <'a, 32, B: Copy, C = u32>
@@ -260,14 +289,40 @@ pub struct Union {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Struct {
- pub struct_type: StructType,
+ pub kind: StructKind,
pub generics: Generics,
- pub fields_stripped: bool,
- pub fields: Vec<Id>,
pub impls: Vec<Id>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum StructKind {
+ /// A struct with no fields and no parentheses.
+ ///
+ /// ```rust
+ /// pub struct Unit;
+ /// ```
+ Unit,
+ /// A struct with unnamed fields.
+ ///
+ /// ```rust
+ /// pub struct TupleStruct(i32);
+ /// pub struct EmptyTupleStruct();
+ /// ```
+ ///
+ /// All [`Id`]'s will point to [`ItemEnum::StructField`]. Private and
+ /// `#[doc(hidden)]` fields will be given as `None`
+ Tuple(Vec<Option<Id>>),
+ /// A struct with nammed fields.
+ ///
+ /// ```rust
+ /// pub struct PlainStruct { x: i32 }
+ /// pub struct EmptyPlainStruct {}
+ /// ```
+ Plain { fields: Vec<Id>, fields_stripped: bool },
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Enum {
pub generics: Generics,
pub variants_stripped: bool,
@@ -279,17 +334,53 @@ pub struct Enum {
#[serde(rename_all = "snake_case")]
#[serde(tag = "variant_kind", content = "variant_inner")]
pub enum Variant {
- Plain,
- Tuple(Vec<Type>),
- Struct(Vec<Id>),
+ /// A variant with no parentheses, and possible discriminant.
+ ///
+ /// ```rust
+ /// enum Demo {
+ /// PlainVariant,
+ /// PlainWithDiscriminant = 1,
+ /// }
+ /// ```
+ Plain(Option<Discriminant>),
+ /// A variant with unnamed fields.
+ ///
+ /// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
+ /// instead of being ommited, because order matters.
+ ///
+ /// ```rust
+ /// enum Demo {
+ /// TupleVariant(i32),
+ /// EmptyTupleVariant(),
+ /// }
+ /// ```
+ Tuple(Vec<Option<Id>>),
+ /// A variant with named fields.
+ ///
+ /// ```rust
+ /// enum Demo {
+ /// StructVariant { x: i32 },
+ /// EmptyStructVariant {},
+ /// }
+ /// ```
+ Struct { fields: Vec<Id>, fields_stripped: bool },
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-pub enum StructType {
- Plain,
- Tuple,
- Unit,
+pub struct Discriminant {
+ /// The expression that produced the discriminant.
+ ///
+ /// Unlike `value`, this preserves the original formatting (eg suffixes,
+ /// hexadecimal, and underscores), making it unsuitable to be machine
+ /// interpreted.
+ ///
+ /// In some cases, when the value is to complex, this may be `"{ _ }"`.
+ /// When this occurs is unstable, and may change without notice.
+ pub expr: String,
+ /// The numerical value of the discriminant. Stored as a string due to
+ /// JSON's poor support for large integers, and the fact that it would need
+ /// to store from [`i128::MIN`] to [`u128::MAX`].
+ pub value: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
@@ -395,7 +486,7 @@ pub enum WherePredicate {
type_: Type,
bounds: Vec<GenericBound>,
/// Used for Higher-Rank Trait Bounds (HRTBs)
- /// ```plain
+ /// ```text
/// where for<'a> &'a T: Iterator,"
/// ^^^^^^^
/// |
@@ -418,9 +509,9 @@ pub enum WherePredicate {
pub enum GenericBound {
TraitBound {
#[serde(rename = "trait")]
- trait_: Type,
+ trait_: Path,
/// Used for Higher-Rank Trait Bounds (HRTBs)
- /// ```plain
+ /// ```text
/// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
/// ^^^^^^^^^^^
/// |
@@ -451,16 +542,12 @@ pub enum Term {
#[serde(rename_all = "snake_case")]
#[serde(tag = "kind", content = "inner")]
pub enum Type {
- /// Structs, enums, and traits
- ResolvedPath {
- name: String,
- id: Id,
- args: Option<Box<GenericArgs>>,
- param_names: Vec<GenericBound>,
- },
+ /// Structs, enums, and unions
+ ResolvedPath(Path),
+ DynTrait(DynTrait),
/// Parameterized types
Generic(String),
- /// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples
+ /// Built in numberic (i*, u*, f*) types, bool, and char
Primitive(String),
/// `extern "ABI" fn`
FunctionPointer(Box<FunctionPointer>),
@@ -497,15 +584,29 @@ pub enum Type {
args: Box<GenericArgs>,
self_type: Box<Type>,
#[serde(rename = "trait")]
- trait_: Box<Type>,
+ trait_: Path,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct Path {
+ pub name: String,
+ pub id: Id,
+ /// Generic arguments to the type
+ /// ```test
+ /// std::borrow::Cow<'static, str>
+ /// ^^^^^^^^^^^^^^
+ /// |
+ /// this part
+ /// ```
+ pub args: Option<Box<GenericArgs>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FunctionPointer {
pub decl: FnDecl,
/// Used for Higher-Rank Trait Bounds (HRTBs)
- /// ```plain
+ /// ```text
/// for<'c> fn(val: &'c i32) -> i32
/// ^^^^^^^
/// |
@@ -544,7 +645,7 @@ pub struct Impl {
pub generics: Generics,
pub provided_trait_methods: Vec<String>,
#[serde(rename = "trait")]
- pub trait_: Option<Type>,
+ pub trait_: Option<Path>,
#[serde(rename = "for")]
pub for_: Type,
pub items: Vec<Id>,
@@ -561,8 +662,11 @@ pub struct Import {
/// May be different from the last segment of `source` when renaming imports:
/// `use source as name;`
pub name: String,
- /// The ID of the item being imported.
- pub id: Option<Id>, // FIXME is this actually ever None?
+ /// The ID of the item being imported. Will be `None` in case of re-exports of primitives:
+ /// ```rust
+ /// pub use i32 as my_i32;
+ /// ```
+ pub id: Option<Id>,
/// Whether this import uses a glob: `use source::*;`
pub glob: bool,
}
diff --git a/src/rustdoc-json-types/tests.rs b/src/rustdoc-json-types/tests.rs
index e7f6447ed..399ff54b2 100644
--- a/src/rustdoc-json-types/tests.rs
+++ b/src/rustdoc-json-types/tests.rs
@@ -3,10 +3,8 @@ use super::*;
#[test]
fn test_struct_info_roundtrip() {
let s = ItemEnum::Struct(Struct {
- struct_type: StructType::Plain,
generics: Generics { params: vec![], where_predicates: vec![] },
- fields_stripped: false,
- fields: vec![],
+ kind: StructKind::Plain { fields: vec![], fields_stripped: false },
impls: vec![],
});
diff --git a/src/stage0.json b/src/stage0.json
index 8f8bd15b5..a54fd5496 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -17,292 +17,292 @@
"tool is executed."
],
"compiler": {
- "date": "2022-08-11",
- "version": "1.63.0"
+ "date": "2022-09-22",
+ "version": "1.64.0"
},
"rustfmt": null,
"checksums_sha256": {
- "dist/2022-08-11/cargo-1.63.0-aarch64-apple-darwin.tar.gz": "4ae53dd1a0c059ba4a02a728c9250c785e39bd4f51550e2d3040e96457db4731",
- "dist/2022-08-11/cargo-1.63.0-aarch64-apple-darwin.tar.xz": "fc9eb10567ad9b477180d40669c4e6f8edc48f54083689f4a0b4a49db1815b37",
- "dist/2022-08-11/cargo-1.63.0-aarch64-pc-windows-msvc.tar.gz": "8015f61613ff5540a62e1aa405f2f1af574530bd5d16d2dedd9c25db895cb42e",
- "dist/2022-08-11/cargo-1.63.0-aarch64-pc-windows-msvc.tar.xz": "7709efc6ef885a5e3922ed4769da78b48db13742a0ff178112b0a00193444b41",
- "dist/2022-08-11/cargo-1.63.0-aarch64-unknown-linux-gnu.tar.gz": "4e359ffb5ef7cb69014d1c7c9a9ccdd2efa1220551f09f52aac16777eb75f01b",
- "dist/2022-08-11/cargo-1.63.0-aarch64-unknown-linux-gnu.tar.xz": "4313ab44dccba4faed20db4aacc16def405773d1676e79d3e65ced4b99d710d4",
- "dist/2022-08-11/cargo-1.63.0-aarch64-unknown-linux-musl.tar.gz": "4cdb73c7b6a5618d3b3b9c1b5361a9d80ddb9f00b3b7ecdddccc774fd644963a",
- "dist/2022-08-11/cargo-1.63.0-aarch64-unknown-linux-musl.tar.xz": "2b9dc58653b17dcff716007730d649b313879d8d5f41b3d0d2e65745ac2bc7c8",
- "dist/2022-08-11/cargo-1.63.0-arm-unknown-linux-gnueabi.tar.gz": "09405d9c79c133f7be749f15f248e7a9eb96508123d9c6549f2c287d60208391",
- "dist/2022-08-11/cargo-1.63.0-arm-unknown-linux-gnueabi.tar.xz": "36ed529c12b3f40ac5bdcb3d60dbf6b08a9792c434889f8b04dc6e62ef5edd40",
- "dist/2022-08-11/cargo-1.63.0-arm-unknown-linux-gnueabihf.tar.gz": "e07eb5f2ec8c913c4c06157de16cf15b2b392b3c0cdf79a5c00b3903f3d40b50",
- "dist/2022-08-11/cargo-1.63.0-arm-unknown-linux-gnueabihf.tar.xz": "b8151b965c41d879bf4c63bdedaed86c566f3c0c1cea52f32b364dbc7cbf5ed0",
- "dist/2022-08-11/cargo-1.63.0-armv7-unknown-linux-gnueabihf.tar.gz": "aa3be47cb33e3ccd1a9ebf9f7dbc47780121fd5e88ae5dbdd4adc35ddb3a1f14",
- "dist/2022-08-11/cargo-1.63.0-armv7-unknown-linux-gnueabihf.tar.xz": "f0589e33a111fda548033ce59727890243b528de3c28d4316dd03c3075cc07b4",
- "dist/2022-08-11/cargo-1.63.0-i686-pc-windows-gnu.tar.gz": "aa4c45f4f845a1a8be641e36ae4dae3a2ca2400ba03d9881caa5dc1cbf7c16a1",
- "dist/2022-08-11/cargo-1.63.0-i686-pc-windows-gnu.tar.xz": "177070e32a08fe50220136e27f8964286f86ae054f3b27fdb65ec50a7732b5af",
- "dist/2022-08-11/cargo-1.63.0-i686-pc-windows-msvc.tar.gz": "a8de56d2e823209212cb50f82c2d457869f99a9760b10222ea2c55ace0407c7b",
- "dist/2022-08-11/cargo-1.63.0-i686-pc-windows-msvc.tar.xz": "a516feb1ee6e622ec7ed7c789ffd4b37266126870fbba63027b114fa4095f515",
- "dist/2022-08-11/cargo-1.63.0-i686-unknown-linux-gnu.tar.gz": "8a157b8899797b3224742ad51e91f21f903f3523513b1a70ba78f60fc7f595ce",
- "dist/2022-08-11/cargo-1.63.0-i686-unknown-linux-gnu.tar.xz": "6f2c109fc38ed8ccadcdcccf51d11505651ca9e12c396ab46ac1dbb55265b792",
- "dist/2022-08-11/cargo-1.63.0-mips-unknown-linux-gnu.tar.gz": "bbac98b4109b0e18e1958763b2940121fde88727452ae40b8244f78a7631c6e4",
- "dist/2022-08-11/cargo-1.63.0-mips-unknown-linux-gnu.tar.xz": "8674d6adef07f916f4903b5c5afdf06c1ef460d560f58283181634b43031fd24",
- "dist/2022-08-11/cargo-1.63.0-mips64-unknown-linux-gnuabi64.tar.gz": "ca4971d2007cc42970c16f86fca2fc241112c09f0ee48e00c8c37ff786b32386",
- "dist/2022-08-11/cargo-1.63.0-mips64-unknown-linux-gnuabi64.tar.xz": "31b8ed9cc3ac85a89de527053fab4fcab40e120a09fe1a5035cef56b813243e3",
- "dist/2022-08-11/cargo-1.63.0-mips64el-unknown-linux-gnuabi64.tar.gz": "d8ea53d8812ac4b47bf66dd217a7a294e57677368eeed988cac949a835dbf482",
- "dist/2022-08-11/cargo-1.63.0-mips64el-unknown-linux-gnuabi64.tar.xz": "5874dc596fe7ca520a95f86c30472920f1ae463f9e79abc79d9b6c56ad4868c0",
- "dist/2022-08-11/cargo-1.63.0-mipsel-unknown-linux-gnu.tar.gz": "f0eb0cdd3294b6a9af74cc5e532dc52963f2410e8818b0b99c51bffc3ee9775a",
- "dist/2022-08-11/cargo-1.63.0-mipsel-unknown-linux-gnu.tar.xz": "26aa2cfe1340577330e70eedcb0e6c63f8679568010c455118426113ceefe75b",
- "dist/2022-08-11/cargo-1.63.0-powerpc-unknown-linux-gnu.tar.gz": "7b9c9ac082a30d73bb1af477d82bb41457795c6fa9543f772a3f2cda295196c1",
- "dist/2022-08-11/cargo-1.63.0-powerpc-unknown-linux-gnu.tar.xz": "a033ebd9ba50635e0f94f50d7603d3b6a101c4ebd4b3906f35e74d81c42e25cd",
- "dist/2022-08-11/cargo-1.63.0-powerpc64-unknown-linux-gnu.tar.gz": "43628c84ed50503aa4fc1001b25c8a81bed3607b3c32a6432391f47938e8009f",
- "dist/2022-08-11/cargo-1.63.0-powerpc64-unknown-linux-gnu.tar.xz": "a9363aed729e92750d84f8002ba23e379900cf4f2791e740b9a23dd9bfd60d9f",
- "dist/2022-08-11/cargo-1.63.0-powerpc64le-unknown-linux-gnu.tar.gz": "c094228d41798a5d36cb83b01c9300a466d7e3f09dad4dc70555f88fa32ae0c3",
- "dist/2022-08-11/cargo-1.63.0-powerpc64le-unknown-linux-gnu.tar.xz": "a4cdc00a42fd767bf5a296f7126d9db22a0a609cd956bbf0cb3eae882add1be7",
- "dist/2022-08-11/cargo-1.63.0-riscv64gc-unknown-linux-gnu.tar.gz": "3d9047de9b9b1cf689a77a4999cbc50700a7895893e4345ca56790955b4e3b60",
- "dist/2022-08-11/cargo-1.63.0-riscv64gc-unknown-linux-gnu.tar.xz": "5f7991bf45ba1c89a5889761b23ced1ec19ced06bea1cdb1f5a537b3f49b487f",
- "dist/2022-08-11/cargo-1.63.0-s390x-unknown-linux-gnu.tar.gz": "734b5feb37dc0ff057c3d5bf570c0448ee250807fc315d0846fdfa1656ce0937",
- "dist/2022-08-11/cargo-1.63.0-s390x-unknown-linux-gnu.tar.xz": "28bf3ced72a2f18cc314d0d3ba8c3a7b4c0b7b596c21c9737e200f466c2b2d4a",
- "dist/2022-08-11/cargo-1.63.0-x86_64-apple-darwin.tar.gz": "91fe0d3477036b0630b09db2a9ef340c29b8be56c48ed244428e2490043ca841",
- "dist/2022-08-11/cargo-1.63.0-x86_64-apple-darwin.tar.xz": "6d245f3426815e07b423ce86db59f135a4347f66fa6ca78f4e3d9128e66eca57",
- "dist/2022-08-11/cargo-1.63.0-x86_64-pc-windows-gnu.tar.gz": "afe961d359857ba02d55834be07128e67c710227c0ee6b3702c1e7c51b193c7f",
- "dist/2022-08-11/cargo-1.63.0-x86_64-pc-windows-gnu.tar.xz": "79dad8fd0d6352c9c5d174c77efc538e769448ec2b734d5377b688fb5ebd5ad2",
- "dist/2022-08-11/cargo-1.63.0-x86_64-pc-windows-msvc.tar.gz": "5b1d2d8ef410f218f1ecf5e853bd218cf6f40e3b3f46b04f477875c125821956",
- "dist/2022-08-11/cargo-1.63.0-x86_64-pc-windows-msvc.tar.xz": "5e7eb636ac2632a2c729b07fee84a3c37ede355b352dd36778b304d5f322e6f4",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-freebsd.tar.gz": "ad9503079dde6499f6a7d85f44a931189a84220ad845dc13979c48e04a28ec62",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-freebsd.tar.xz": "2f5128a4ec2caf81a45c37906045eb9e9f43b99e86ab8a4a6d24d41264b763d6",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-illumos.tar.gz": "e6e63fe89e8ba8ceb91a2ab6e9969440dd53282ba9a2d9a11b53e915a188457f",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-illumos.tar.xz": "73338ad4d6c06906a6dff9632e2b49f54222e93b2606db0112423ef047fa7811",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-linux-gnu.tar.gz": "43445b2131cefa466943ed4867876f5835fcb17243a18e1db1c8231417a1b27e",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-linux-gnu.tar.xz": "f370d12e4c11f0c835becb738bcf00d363f29b76f8b424b4dcb005abcf15fc9a",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-linux-musl.tar.gz": "43b6b236d5e3ccaea3afad43d13bb3d0c7628a22024f770d143a7949b298f3dc",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-linux-musl.tar.xz": "6f6ce044832a2433c250f4f27a61f69081e2b0f7e4e1f141492c2ce99ee8511e",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-netbsd.tar.gz": "a967a8a620da6acc69f894466d3b54ec6be566b360f5ccb85d2cabd74715f133",
- "dist/2022-08-11/cargo-1.63.0-x86_64-unknown-netbsd.tar.xz": "e51269a30f6575af4f1b9facd60c873c6cc2c41576616fcefb53cfc071da8299",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-apple-darwin.tar.gz": "d7a49553f5385f8f39abd6179500690bd120cc36ee504076bce777f2fa32d02b",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-apple-darwin.tar.xz": "98b07c535a60d3c60eda821378157aca8e604f1b8023b94310f97656c9c4a598",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-apple-ios-sim.tar.gz": "b709fc1828ddb49e846e320f4453e0f3ac62f7e9ec92ff9e653d7d7b14d0919f",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-apple-ios-sim.tar.xz": "28ab36102ceecc92b4e8ad207af8266ce36ba1e93fa08400e79ced07af6ba5a8",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-apple-ios.tar.gz": "f1afdb6ff40ea27644ab699cbf4f6788236f1fc7f0cfb501126d6598af26acb4",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-apple-ios.tar.xz": "140f2f640f6962973b52725d0034e3e002b81694c2509af11591d0482a2d21b1",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-fuchsia.tar.gz": "d97cb62d0ece952cbe5ce9667893ea7570b40fb4747bf898848709f77347a301",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-fuchsia.tar.xz": "d17dae06ff1f6d4be89cfccc640129b954d09d185aecda876874420478c8ab4a",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-linux-android.tar.gz": "99bf807bc6e3e6977e542cb5acc73451db94f593f72b23ddd9288030a5e80620",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-linux-android.tar.xz": "017c821be5bdf68bd2bfbf71412ab5bff5d3928bd435d8aacc9e774f28a517a1",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-pc-windows-msvc.tar.gz": "3cc2ba54a862119ff73cf5be81f3ec7d41a66abc4e2433602b59cbe73430027c",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-pc-windows-msvc.tar.xz": "48e78d7686e16a8961d8445c6524c43313e57c6a899f8c49e9094618932941ee",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-linux-gnu.tar.gz": "4afce4152945642fb4c1a7fa44ffe396f98ce094108ffe29b1833413e8eed49d",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-linux-gnu.tar.xz": "f1d93b3d48258f701687c63ef9b226c07329fb92c2c5559283258687f958e9d0",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-linux-musl.tar.gz": "0f3d44e3432ed152d5ad9759741bcc8844386af3286beb6dc856323d7f56565c",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-linux-musl.tar.xz": "f8facb978bdc56ac6ffbcfb26e9f42762a820990013a5c6278c5e86cea039d44",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-none-softfloat.tar.gz": "1f3f6db05e53219b3da05a1810f9d2ec8f8037330859031d876d585e67f76ef1",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-none-softfloat.tar.xz": "4205bbf7823ed599532a83ca4009e07c06bd12edaad0e9df7da793976e69b89a",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-none.tar.gz": "ce4cc98ac5319ae8c89a9e64e78d16361c9151b9e26fd89ef040a0d378126b83",
- "dist/2022-08-11/rust-std-1.63.0-aarch64-unknown-none.tar.xz": "0c0222349fb35e67b08d9a7e0686e84e1086c57bd01bccb2c9133e017402466b",
- "dist/2022-08-11/rust-std-1.63.0-arm-linux-androideabi.tar.gz": "aa4f5e6d1cd8c0c36574d92d1b395a7e1fbf65cff67501a6598807e5b68215a7",
- "dist/2022-08-11/rust-std-1.63.0-arm-linux-androideabi.tar.xz": "601fa7b9b7cb2c71e4634b38a445fc2747cb9a4cbebd49cf86b367bda7b6c922",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-gnueabi.tar.gz": "55e59d256f7b00681ac039c110cebba016f82acacd1f3bf8942cd76887d0f8a8",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-gnueabi.tar.xz": "a9af1e5b034f90f7dbc656649a80a19df68a5c59041b237b32e3d6a3f192a014",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-gnueabihf.tar.gz": "6cb1493e1b0bc981c59b2457d76e16f330b0543737cda969246b377e4520c45c",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-gnueabihf.tar.xz": "d3fc53cbe6c3e0aa51bbf6d7ff6e3f66ca812ae07e6871187da91432f1e57dff",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-musleabi.tar.gz": "e4d3e9367cdd8bfa640edd2d1289aa38aa840e13797cef64d6d507a04e0cf059",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-musleabi.tar.xz": "f59d4576ae438f29300a7cfe554a9a53e9845949c1ba67245cca9ecd3020d45a",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-musleabihf.tar.gz": "a929d4eab6d355481033b2a650090223648bfec9e1b5a8c4d82b1be6103d9e86",
- "dist/2022-08-11/rust-std-1.63.0-arm-unknown-linux-musleabihf.tar.xz": "ecb3d96c3d2d02548b1c718da9030bcfda7194d1b26497524eee3dfe1fa94886",
- "dist/2022-08-11/rust-std-1.63.0-armebv7r-none-eabi.tar.gz": "93324ab170fd3da508bcfd82eaa9e058f9c11575d1a993233bb12431e29f4c7f",
- "dist/2022-08-11/rust-std-1.63.0-armebv7r-none-eabi.tar.xz": "facb17ff877c956c2c50adb967a9c577c6dda8ab198786f7d2b49401b34fed53",
- "dist/2022-08-11/rust-std-1.63.0-armebv7r-none-eabihf.tar.gz": "dbea28b81e014ce626e3d099e5419dec0bf8507a156be1fdbfc30f8f43850729",
- "dist/2022-08-11/rust-std-1.63.0-armebv7r-none-eabihf.tar.xz": "53b1a446c1003fc576f0b6403654d5740448c076d13718cb1501403bb06b9d82",
- "dist/2022-08-11/rust-std-1.63.0-armv5te-unknown-linux-gnueabi.tar.gz": "cfb04fd59ba012538500da9e9ff5ef1cbf6940c1414cd71dd5a6225f798f1a90",
- "dist/2022-08-11/rust-std-1.63.0-armv5te-unknown-linux-gnueabi.tar.xz": "46eced3c6942c09c8c347aa59f83deeeee882ab176f35c0587b598e6b5feb96f",
- "dist/2022-08-11/rust-std-1.63.0-armv5te-unknown-linux-musleabi.tar.gz": "b28460e19e127903f11baa562f91d665b8687c77d3ab5e9bdd5158f1060b4738",
- "dist/2022-08-11/rust-std-1.63.0-armv5te-unknown-linux-musleabi.tar.xz": "db9d2b48853990b618e8c01d978fabab2c92793a24c68a137c473b8f8bdcc26b",
- "dist/2022-08-11/rust-std-1.63.0-armv7-linux-androideabi.tar.gz": "4ea9faa0d941ab507d8bac7e488ec95ff4782b41e9bee51a64e74f129e0c3b07",
- "dist/2022-08-11/rust-std-1.63.0-armv7-linux-androideabi.tar.xz": "75ab1a07e25ee87e04ecad8cb7dafd47b992ee76d4240a058c24e34554d3a666",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-gnueabi.tar.gz": "621e8ed23a9dd67b29e4abb7609be507742ac97761115921a514243670a1a7d0",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-gnueabi.tar.xz": "d1dc8bb095a076603739dba52acf2bcb97c2faacaa75b4b0bc4fddd1b8265324",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-gnueabihf.tar.gz": "998c9a1af2fce446f37b77d6400a32fb3097def293d2f73faedd0d0cafd42a33",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-gnueabihf.tar.xz": "dfddaf8a1503ae6042f2f15260df834789789d9144cad073476145483ee363b4",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-musleabi.tar.gz": "4fa8836da676ba198609dfd7ce7526c6cd1108075722a35cf70a62e02119db79",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-musleabi.tar.xz": "12517be06a99f50e5a48fb354869d1166d5eb3613a1fb09b15c8dc34ddbb6900",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-musleabihf.tar.gz": "d37ae049dca59b174db5b54a1c157b54c8cc49396699e135f5fad9d306568ac9",
- "dist/2022-08-11/rust-std-1.63.0-armv7-unknown-linux-musleabihf.tar.xz": "f7011f83d7e826d8ad09be36ebd3920aab65b14cda35ab106abbd6a6876c6b7f",
- "dist/2022-08-11/rust-std-1.63.0-armv7a-none-eabi.tar.gz": "f439b588dd23d5dbdb1f7d21a50d92f62dfd9c9322d2af29369569b4fedf0fcb",
- "dist/2022-08-11/rust-std-1.63.0-armv7a-none-eabi.tar.xz": "d28e3d507a8ca5b07e08d15ca21bc7febb8661d4cac21a9908e72ba812c34299",
- "dist/2022-08-11/rust-std-1.63.0-armv7r-none-eabi.tar.gz": "083fabac1676d651286122ab53643cd8532d455269313db709811a79c95d6cbd",
- "dist/2022-08-11/rust-std-1.63.0-armv7r-none-eabi.tar.xz": "59533c8f933be9113468958090a53796045c38effe16bba148cd82fa05b98f54",
- "dist/2022-08-11/rust-std-1.63.0-armv7r-none-eabihf.tar.gz": "e741683f9f2ba11dc0698ab9d2968e75b76140fa43e91b5f04419a74bea90567",
- "dist/2022-08-11/rust-std-1.63.0-armv7r-none-eabihf.tar.xz": "72e1ff544e0da89943f8d42771462eaf1169b7f3c77795e879a68f0eadbaf4c2",
- "dist/2022-08-11/rust-std-1.63.0-asmjs-unknown-emscripten.tar.gz": "3525a65087ab1e05224af41026865fd14252568e38f0b6311b64a7ad6cedf634",
- "dist/2022-08-11/rust-std-1.63.0-asmjs-unknown-emscripten.tar.xz": "5358d5a070cc37ebddc018dfc74a6a627c3653f1b0e98d28fab8f054d4e4a56c",
- "dist/2022-08-11/rust-std-1.63.0-i586-pc-windows-msvc.tar.gz": "d8c4f71584139cbcf2c15c9d4c0033c70e4ea871a630e33d44ba1d6a342ff5bf",
- "dist/2022-08-11/rust-std-1.63.0-i586-pc-windows-msvc.tar.xz": "d860d3372cc32d3a38c4216ae96bbc74a71bf9fcf3566f03cf0e95a0ccba511a",
- "dist/2022-08-11/rust-std-1.63.0-i586-unknown-linux-gnu.tar.gz": "e768e9dbde2dec04fcab5a49752160f459f0ad48f35b6adf659cf509de5f4848",
- "dist/2022-08-11/rust-std-1.63.0-i586-unknown-linux-gnu.tar.xz": "a0b437df2a39fdfda953b9e4061db250eb61a124d9029f92f02a82d533a8272d",
- "dist/2022-08-11/rust-std-1.63.0-i586-unknown-linux-musl.tar.gz": "99078c8e4e792c9868dbc7795c6e141cb69ed31107cb952cd7d39b126fd1dd16",
- "dist/2022-08-11/rust-std-1.63.0-i586-unknown-linux-musl.tar.xz": "8e15e3c9273b763961985c3139b81831b36ec9e07b5a342100439793ba7f7f1c",
- "dist/2022-08-11/rust-std-1.63.0-i686-linux-android.tar.gz": "cab6a7810cacd0f7cab065fa71159e94c714e1017dd99406e1c2d32341f8413f",
- "dist/2022-08-11/rust-std-1.63.0-i686-linux-android.tar.xz": "c7b7954f26a3d60302b11208638223c92d91e11cb101a0d09a87e8329f6fe778",
- "dist/2022-08-11/rust-std-1.63.0-i686-pc-windows-gnu.tar.gz": "efdfc9cc6caeab824bd4e0cc31936c07a31f4a7e81c8fee6fc9263432d1dfe77",
- "dist/2022-08-11/rust-std-1.63.0-i686-pc-windows-gnu.tar.xz": "7f0768ebd1e88ea5bcf8c63f28b56c9efc71e6e66a67a2f4efc59bd430691870",
- "dist/2022-08-11/rust-std-1.63.0-i686-pc-windows-msvc.tar.gz": "648a23e13c4e51026456679822c91a69ea11b637f5dbd9e896e79aadd05cd573",
- "dist/2022-08-11/rust-std-1.63.0-i686-pc-windows-msvc.tar.xz": "ef966bbbbe286026720d4622943ca0e129706c11c085f2346e585853d01a51a6",
- "dist/2022-08-11/rust-std-1.63.0-i686-unknown-freebsd.tar.gz": "be4d6dd63f9e963905257406625f6c387d37407ce0207924d6d249b51557581e",
- "dist/2022-08-11/rust-std-1.63.0-i686-unknown-freebsd.tar.xz": "9085e6c14c4ec7639141526fecdaafc8dd682ffe4ed886b489cd4df73484d16c",
- "dist/2022-08-11/rust-std-1.63.0-i686-unknown-linux-gnu.tar.gz": "5df51e9119d49addbf78ca6fbaf78a869f7aea46853a8fdfe339d543d0d88c3b",
- "dist/2022-08-11/rust-std-1.63.0-i686-unknown-linux-gnu.tar.xz": "3177d3a159b4fcd54bca93d09ff1a903689a64ed4037699de372e685d12d4335",
- "dist/2022-08-11/rust-std-1.63.0-i686-unknown-linux-musl.tar.gz": "6b49b27fabf4dbeaa2a52d69b7f3312a4a2fdf109d7570a681cedbc563c8d0b6",
- "dist/2022-08-11/rust-std-1.63.0-i686-unknown-linux-musl.tar.xz": "df6683ce2fcc239415c8fd54e54f11e4f6d9f499ce7efb084735303d49f42544",
- "dist/2022-08-11/rust-std-1.63.0-mips-unknown-linux-gnu.tar.gz": "0e235151b2f33a03a4717b2e9f3644a3d3ef502844545fea3645214403ac143a",
- "dist/2022-08-11/rust-std-1.63.0-mips-unknown-linux-gnu.tar.xz": "b7aadc94a719a9cc076795efa62f881206218e69845e8f733f149e3d32e8854d",
- "dist/2022-08-11/rust-std-1.63.0-mips-unknown-linux-musl.tar.gz": "a2b35c7b2e0eed0ab3a03dace3a37af6fe79b47c94b03b182a4c2f37ffdba494",
- "dist/2022-08-11/rust-std-1.63.0-mips-unknown-linux-musl.tar.xz": "2b923df9c078b60f15333909d49d8fc62658b087715f2be96a2174f6c7678f7d",
- "dist/2022-08-11/rust-std-1.63.0-mips64-unknown-linux-gnuabi64.tar.gz": "2d845ba67101c5b1e20dff96e43fcaa5a80bdfc2c24898998c399648c7bf77a1",
- "dist/2022-08-11/rust-std-1.63.0-mips64-unknown-linux-gnuabi64.tar.xz": "7685fd0854bafed5b0c40348fc1aabb27eeacd8d0f886205264a5e5fcd37a072",
- "dist/2022-08-11/rust-std-1.63.0-mips64-unknown-linux-muslabi64.tar.gz": "de745d67de012d0a48123d11693e591d885dd2054f414014b75ac0edaed74412",
- "dist/2022-08-11/rust-std-1.63.0-mips64-unknown-linux-muslabi64.tar.xz": "a767bda3e133672ad94aa00d92943023dc2883319ed906076528bd56d8f094ea",
- "dist/2022-08-11/rust-std-1.63.0-mips64el-unknown-linux-gnuabi64.tar.gz": "de8266fb73173147f9cce7b86ae36c840084f914ea47a724abc3fe950587b348",
- "dist/2022-08-11/rust-std-1.63.0-mips64el-unknown-linux-gnuabi64.tar.xz": "7c3b4669b56c8ac9d728b7257c61d3f04cf55b439b8a0122531996e6433aed41",
- "dist/2022-08-11/rust-std-1.63.0-mips64el-unknown-linux-muslabi64.tar.gz": "2cbc1bae8d3927b4e4b08693c7341fdd635656dfd1ea67cf6d7aba25277c8cb0",
- "dist/2022-08-11/rust-std-1.63.0-mips64el-unknown-linux-muslabi64.tar.xz": "542c8f1374a19382d3cb71bb6bca0142501e12e0586135db1bc7f0f0efdee03d",
- "dist/2022-08-11/rust-std-1.63.0-mipsel-unknown-linux-gnu.tar.gz": "696c84c83cb22c3019ff18cdc21fc5206bc7e56d4f51c86e26dc4ebfaf952aa5",
- "dist/2022-08-11/rust-std-1.63.0-mipsel-unknown-linux-gnu.tar.xz": "29a8b51d49435778f4bbff4a6e4c0d38e8ed318f3f357fc542d38311af84da8b",
- "dist/2022-08-11/rust-std-1.63.0-mipsel-unknown-linux-musl.tar.gz": "72f414830f443b80e4657147bdf152526456488385c0d5761cd5783825d2c51a",
- "dist/2022-08-11/rust-std-1.63.0-mipsel-unknown-linux-musl.tar.xz": "1d48e7fd169c1f6ec1f1035d87b4e897fe8ca4c0dc927cd7249f91c851b999dc",
- "dist/2022-08-11/rust-std-1.63.0-nvptx64-nvidia-cuda.tar.gz": "2074c788294f5717a18cd6d8872cf1a1c7e4e0f88c1455a30b83ec43e22b0a2a",
- "dist/2022-08-11/rust-std-1.63.0-nvptx64-nvidia-cuda.tar.xz": "b25d018f07a75336e613786579d233e13b521d57f5c2acc0abdfd115f5b1385d",
- "dist/2022-08-11/rust-std-1.63.0-powerpc-unknown-linux-gnu.tar.gz": "460dbad0c90b35c3adda748d62efb568c8bb7703c8ce489a4da05c75c594a841",
- "dist/2022-08-11/rust-std-1.63.0-powerpc-unknown-linux-gnu.tar.xz": "a25719c0ad2a5e7f52eed87b75cb76c4a52b8dc6e24b4bef16ed7fb9133e5b42",
- "dist/2022-08-11/rust-std-1.63.0-powerpc64-unknown-linux-gnu.tar.gz": "0cb3d97a8d930a0b326a74caa1b7b34c50d823ca09179764e2941a335cba3a9d",
- "dist/2022-08-11/rust-std-1.63.0-powerpc64-unknown-linux-gnu.tar.xz": "8e302aab7d47f0287869ad2a5bd4fdb74b194f8e40f1c269d0dd320edc3e0782",
- "dist/2022-08-11/rust-std-1.63.0-powerpc64le-unknown-linux-gnu.tar.gz": "cf3680185267b0f844faa83939ed367d126d241a200299dcbdb0fbb615ca202b",
- "dist/2022-08-11/rust-std-1.63.0-powerpc64le-unknown-linux-gnu.tar.xz": "3ae0b74ba428c569fcecebbb09060ad0bd434a5f1fc9ffd1329b56941a897b6e",
- "dist/2022-08-11/rust-std-1.63.0-riscv32i-unknown-none-elf.tar.gz": "a3562cc6fdede574b61b0a084cf57a92fceeefcf28daef59ff67ae5471b6ba61",
- "dist/2022-08-11/rust-std-1.63.0-riscv32i-unknown-none-elf.tar.xz": "ef0061f089c051176c7e6b40949b40105b3d3c40ca07aac3aeaec5b7718ba3db",
- "dist/2022-08-11/rust-std-1.63.0-riscv32imac-unknown-none-elf.tar.gz": "9ad1d55f0a752d537c46cc7b2e5db3165bf729be100195a26935f89636793d38",
- "dist/2022-08-11/rust-std-1.63.0-riscv32imac-unknown-none-elf.tar.xz": "c0a1478afeb2dfe2f8ce7905357f33785b200576d40f8a1b3cfe5d52bab13d2b",
- "dist/2022-08-11/rust-std-1.63.0-riscv32imc-unknown-none-elf.tar.gz": "56ab5b52a614f626f3314369994632f9589dcb895e312b0a3190a2b1b75e7943",
- "dist/2022-08-11/rust-std-1.63.0-riscv32imc-unknown-none-elf.tar.xz": "74162759759f9e81658dac1c45161711b0e95e7777e487dea542b7857e189531",
- "dist/2022-08-11/rust-std-1.63.0-riscv64gc-unknown-linux-gnu.tar.gz": "81c86715aaaf53f9f12b63a6f1e88f4fe933e05d9f3b29c8616fb077f12a9a18",
- "dist/2022-08-11/rust-std-1.63.0-riscv64gc-unknown-linux-gnu.tar.xz": "bd6a4b8445cb1205ea1de19310bc442627d7bbc7d84fa49953f15235abb08f4d",
- "dist/2022-08-11/rust-std-1.63.0-riscv64gc-unknown-none-elf.tar.gz": "08efb1f462384927884fe0750fbae2edbdf27db0f9174288dba635bcc710c932",
- "dist/2022-08-11/rust-std-1.63.0-riscv64gc-unknown-none-elf.tar.xz": "3aaa19c83b4e5a7eb44d52884e3f132f1deef2d5811e0f6ed5ced4c7220498db",
- "dist/2022-08-11/rust-std-1.63.0-riscv64imac-unknown-none-elf.tar.gz": "9a845619b1009e40d2d69cfeb40fd13ebd0bbb894ec069f2eb401d4a4f38948e",
- "dist/2022-08-11/rust-std-1.63.0-riscv64imac-unknown-none-elf.tar.xz": "be622a4df96dc571d4b8617a6de63e472a0312559c5f92f64abab07459247ae1",
- "dist/2022-08-11/rust-std-1.63.0-s390x-unknown-linux-gnu.tar.gz": "c384892517cd302fd48d918fa8035bd55a3e8037f5e97ecc9d4ff52a8de96d38",
- "dist/2022-08-11/rust-std-1.63.0-s390x-unknown-linux-gnu.tar.xz": "f37095d2501981d1e7606649d49b4bd282d3e60d6ce540cb46e03db946ff1406",
- "dist/2022-08-11/rust-std-1.63.0-sparc64-unknown-linux-gnu.tar.gz": "428821e52291c9a71d165844620181fd8c7c082da54ca132f8bbdd63227300b1",
- "dist/2022-08-11/rust-std-1.63.0-sparc64-unknown-linux-gnu.tar.xz": "4343b442b2670b274e7352b7cfa8893d90348a40663524b7f319b9cce5d4ef78",
- "dist/2022-08-11/rust-std-1.63.0-sparcv9-sun-solaris.tar.gz": "0f877270a29f3e41b676c6995f0bfcd660ae22e3de6c6570f812fcc82cebef03",
- "dist/2022-08-11/rust-std-1.63.0-sparcv9-sun-solaris.tar.xz": "9ca9346aa172488aa0e8a3967478f9ed9ff88aee91b80b061e1513b9c4bb243a",
- "dist/2022-08-11/rust-std-1.63.0-thumbv6m-none-eabi.tar.gz": "35d7d9e515f662defcbc6e1968e5951a59fedaaaf54ac20b319a22fe72636166",
- "dist/2022-08-11/rust-std-1.63.0-thumbv6m-none-eabi.tar.xz": "abf8a27b8950756a5a967ff9932371f60607599d0a521ac62bf5e113ccdc241a",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7em-none-eabi.tar.gz": "810937d37cfd9ddaa837ad05d669a0d70d6260ae38b078673c6896ede11b2968",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7em-none-eabi.tar.xz": "b27101231816f703b44b74f89ba97637765af906471622bf4d594b19f15b461e",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7em-none-eabihf.tar.gz": "9e9f8887e7a985dd6f9e1f916d7c1cf3f78c28cf2eec1bb4c33a4e001d5f05b0",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7em-none-eabihf.tar.xz": "07f90c8c9ae00f07fbc80954f466364d73a1b9a0723547248b9b7a28b4430be5",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7m-none-eabi.tar.gz": "ca1d06387fccee5bad4eaba9433123b735cf2220830ec5fa51f6ee3198e4118b",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7m-none-eabi.tar.xz": "5d01e518beb50a00c168a2664e98671633413f67d437b383b606f001c9b90b07",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7neon-linux-androideabi.tar.gz": "9819001fbd7cb73abcab5599551659b92c1159986ddbd31f85c55b959609a737",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7neon-linux-androideabi.tar.xz": "34be6278ae95b8603a1eb0e54ec8dfc13633d3d8bf8682bce1a5066cbd6dc7ac",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "212fba32e5dbb630250666bc8bbd26fd41f6b4baeae38e7594955ffb66684a55",
- "dist/2022-08-11/rust-std-1.63.0-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "006d32c10741a28aa5433620e126840411f64d7cb21003689297571780419c83",
- "dist/2022-08-11/rust-std-1.63.0-thumbv8m.base-none-eabi.tar.gz": "2e742c8ccdfac2c049218b9e128ba7dd415439acd1af087dd43934222e1adc62",
- "dist/2022-08-11/rust-std-1.63.0-thumbv8m.base-none-eabi.tar.xz": "76b5c40c2758f54ff72a08043fd07402307fc26d5866e08f92673f131bbbf667",
- "dist/2022-08-11/rust-std-1.63.0-thumbv8m.main-none-eabi.tar.gz": "3cefb77bb6050cc7eb52d5c21670a530d85a95364f81136686cfc1d2b5c8b7aa",
- "dist/2022-08-11/rust-std-1.63.0-thumbv8m.main-none-eabi.tar.xz": "df9b6bd63c0194a7a08065f7b09b4c1f2e6e4f961acf80fb26b6e72acf107ca4",
- "dist/2022-08-11/rust-std-1.63.0-thumbv8m.main-none-eabihf.tar.gz": "0f7fc9575bf361bb4f506ae08a576250b1f66fab17311c1ef58c51e25d282502",
- "dist/2022-08-11/rust-std-1.63.0-thumbv8m.main-none-eabihf.tar.xz": "b3d203d107e92a5a82ddd79716d07263099653f10340ad56a3748a67d58f8d10",
- "dist/2022-08-11/rust-std-1.63.0-wasm32-unknown-emscripten.tar.gz": "115710692bfcc2cf3113d341936853c2df3f15e02b26f47f284f81baaf466e15",
- "dist/2022-08-11/rust-std-1.63.0-wasm32-unknown-emscripten.tar.xz": "33bef9ef0cfd29725c20bbf96dda23779e012981bd82d045dba6b4954a47a0f5",
- "dist/2022-08-11/rust-std-1.63.0-wasm32-unknown-unknown.tar.gz": "0ba89f8bd8a563c4af34060d0261cb6ffbd11cca1277797510ebfece91ec7cb5",
- "dist/2022-08-11/rust-std-1.63.0-wasm32-unknown-unknown.tar.xz": "4fe359d61dff870157639d320e61c5e61c9e220cd71214f44337b50b9733de59",
- "dist/2022-08-11/rust-std-1.63.0-wasm32-wasi.tar.gz": "79ba7355da31da483b2a1e22367ad5bee21d216a3095ae9e19f5ce38fd580b5d",
- "dist/2022-08-11/rust-std-1.63.0-wasm32-wasi.tar.xz": "c8b2a9d116db93cfed3373f1fcd5cc8b40669154e3fe0b2e37a76783492ae9b2",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-apple-darwin.tar.gz": "a8653b57d0efbccf3e95953cfb9c7a2ddaa68ba789edc8378c5b0b8200cc3be5",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-apple-darwin.tar.xz": "2f870140d7dbf313bd612692c93a020e285d70557cb093eee20f38af2d11138c",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-apple-ios.tar.gz": "657a3b902cefc5875c24d70003a8f3d2bb947c1b5ab733606cdbff1b328e6567",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-apple-ios.tar.xz": "a99ee9d0cb6996c87271b85167f3d32372d872de8f0e0eba66b621c63637f500",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-fortanix-unknown-sgx.tar.gz": "db9cc01a4b2fb4cf20c468b1c31e9044308b08307b3c174395582b0df3d8a06e",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-fortanix-unknown-sgx.tar.xz": "081aba0f04c9f6a97cbb4128130845eb27b5bf8e4b91265424bae2273cc16582",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-fuchsia.tar.gz": "d47fb677095993b529c0c50220c7a49b3c7f6e0fda37680f5eb4904aa4fc987c",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-fuchsia.tar.xz": "47afbb3386dbc70edd457c0a02d320ae9736f13ecfc4f3cf6dfa01cdaccb9ea2",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-linux-android.tar.gz": "1c30a10348489ddc81de6f59623ed1215f7879c39e2316971ddf3e58852c601f",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-linux-android.tar.xz": "ab23a403d46bbfc57cfdb7b417604998d1bbdc5a92c04bb6d3ab526cf0e4377c",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-pc-solaris.tar.gz": "424bb356d00f4a9af14a1c569130cac5c50ef01d1755638d7cb84476988f5d50",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-pc-solaris.tar.xz": "df46139105af476cfb1c054710c366c996b3b639e91eb052cb12f3b43742e9a9",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-pc-windows-gnu.tar.gz": "aa6486ea84917e58dd87ea72a40175f717271024372482871a58c72089ff1e5d",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-pc-windows-gnu.tar.xz": "f9e54c4da66daf532ae3ad0ae3c3e859bdeef1126d9830fe57ceb520b9e1d3cd",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-pc-windows-msvc.tar.gz": "e72b994d365e02242f2ef50cca73019c5c7ec57f55585b4f02e819a5cfd204f1",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-pc-windows-msvc.tar.xz": "3b336cb1a423f37fa9fd1927a311f1daf32ebfc0e48cb430178995c942bc4fa3",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-sun-solaris.tar.gz": "36077daae393c924a2b580a027c1279acde776f283b5995be784189953307afb",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-sun-solaris.tar.xz": "0cafc9fb8bd290729055243848455934e029f5ebfbaa32ea5b9a42df2c7cffdf",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-freebsd.tar.gz": "9f8e178831660036f918376a84c7e98f53a3fa5ed2a297a9b56f805774968d7a",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-freebsd.tar.xz": "f35fd4780a421f661e30996b1fc02a99747c88e0ae598f8db374dafcc296c182",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-illumos.tar.gz": "3a7486e443fc9f472543f9cff463af30c3f6f9b8f8cdddb53c6bae6a1201f0e3",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-illumos.tar.xz": "1a553f1e51e4745187333d5acdd526a190b0a08a5df348e54f83aedd1403a757",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-linux-gnu.tar.gz": "4211c28e3359e915c116524aeb13a728dfd1e8889d1b01d32ed64b2995534eae",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-linux-gnu.tar.xz": "993c2c17bf76ac626bfb5b17bddce65fbdfc14f70d183f33773de0cd12df46d2",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-linux-gnux32.tar.gz": "d5fa082ab33d175f9cb8f0966062b857a6ac4cc563898b484f19fdfa96f30a86",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-linux-gnux32.tar.xz": "29cbad48625985ccc86c080c089998feee526b009862aed2037dbcb43f502829",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-linux-musl.tar.gz": "5d754e45cc659e616d2866e1ddb6142d75b7793acfd550c142b83d5170cdff58",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-linux-musl.tar.xz": "6fcfa4f9a51d35bf2c5c92ac15c688baa8c98d9fded05ab6abfdae85cb5aed8c",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-netbsd.tar.gz": "655e5a3e7ef75e52d40d931cb9fc6c887af4387d6b09f0d1a07cbee60d7ff46f",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-netbsd.tar.xz": "2bb125b0bdbfae9bb0d89673d553ef94f9c256d649034f41a5654602afbec0c3",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-none.tar.gz": "28a83473f6c0df030dfe76501e202dc0345a7f3430531c8aa25edf748086089c",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-none.tar.xz": "ac294009701ec2aff9291303efac3b7955f84b50e3dda0668f0a9e577f19e85f",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-redox.tar.gz": "f285617c83071d72c45b7227090f1745398e846303e6c49394785a4e88eaf0a5",
- "dist/2022-08-11/rust-std-1.63.0-x86_64-unknown-redox.tar.xz": "1b2004449b8f0d646df1f21f64ebcf3b0e5c2383088abdf10627fb31a4287e10",
- "dist/2022-08-11/rustc-1.63.0-aarch64-apple-darwin.tar.gz": "521e392d218cc2610c530d5b380e68fb91161ca598b55a7dac93fd04228caf62",
- "dist/2022-08-11/rustc-1.63.0-aarch64-apple-darwin.tar.xz": "630dca8e83d93a64b734693a1ece88c3881ef979c5c711174bc029bb2fb517e2",
- "dist/2022-08-11/rustc-1.63.0-aarch64-pc-windows-msvc.tar.gz": "e1cea7bfa2812d6f084bec8b86d740be6139b95623fd02c2345ecf5810ef4a00",
- "dist/2022-08-11/rustc-1.63.0-aarch64-pc-windows-msvc.tar.xz": "e1bef789dba424a56690ca3e54f4ae7f674441df7a04baef16a929b32ea843b2",
- "dist/2022-08-11/rustc-1.63.0-aarch64-unknown-linux-gnu.tar.gz": "a4189dda06098813fb1e08861deae8993c809051c3c716b6aefe3793f5f0fb5e",
- "dist/2022-08-11/rustc-1.63.0-aarch64-unknown-linux-gnu.tar.xz": "d78799bb8f4177877f97b9051c9cba1fd85173f2e9cecab9486388fc6fa66259",
- "dist/2022-08-11/rustc-1.63.0-aarch64-unknown-linux-musl.tar.gz": "8ea10281826193f3be19db68995805b5a098cb76f74de18bda09642d44cfcc64",
- "dist/2022-08-11/rustc-1.63.0-aarch64-unknown-linux-musl.tar.xz": "93dfb20c91f3aa00b31bbad099c8a42badb0b2bd1ebbd4d94eaf196d5c8a193e",
- "dist/2022-08-11/rustc-1.63.0-arm-unknown-linux-gnueabi.tar.gz": "4c8f7000a1662e0bc2d1e5153d56784c2fafadfc0306d26dfd3e902c568b50b1",
- "dist/2022-08-11/rustc-1.63.0-arm-unknown-linux-gnueabi.tar.xz": "160fe42e612742455993afc2b9f0a15e3d820ad3283cc7a2b77a3401cdd6403b",
- "dist/2022-08-11/rustc-1.63.0-arm-unknown-linux-gnueabihf.tar.gz": "63eab3494123b67b7b0cccca5689e430ab0c62200c48b96892afc6cd0ebfa4e6",
- "dist/2022-08-11/rustc-1.63.0-arm-unknown-linux-gnueabihf.tar.xz": "2f5424c84f7c26f03ec17246854e84d3e8d90e3a8405f2c3a55d4728bbce8c9e",
- "dist/2022-08-11/rustc-1.63.0-armv7-unknown-linux-gnueabihf.tar.gz": "0e0347051ba9530ccdba8fdafd394a52c4623fe4f9d1ee53f6f5d66f4fd2c25d",
- "dist/2022-08-11/rustc-1.63.0-armv7-unknown-linux-gnueabihf.tar.xz": "86d2e4641f038071c015557e506129d6ec3325902bf4d4a40c7463d0ea92560a",
- "dist/2022-08-11/rustc-1.63.0-i686-pc-windows-gnu.tar.gz": "139099ee54787b13830f55155936e3f80a61b480e35e9133a99551f2648dd471",
- "dist/2022-08-11/rustc-1.63.0-i686-pc-windows-gnu.tar.xz": "60eb72b1b55c6fd25ae030a5d7aad47c9397675639323ae03a754476e95d37bc",
- "dist/2022-08-11/rustc-1.63.0-i686-pc-windows-msvc.tar.gz": "9e1c3ac7afc988bcee8c4150c4675b250cadc8e71b48e66e17c7a3a49bea54d2",
- "dist/2022-08-11/rustc-1.63.0-i686-pc-windows-msvc.tar.xz": "40b7ced5f88165cd33c818443f5196758e172892796cb04306a2817caf7db921",
- "dist/2022-08-11/rustc-1.63.0-i686-unknown-linux-gnu.tar.gz": "4b7ec3ebbc32fd269775367b3dd800f53bec91ffcc33e7e1f6cd98f81bc4095f",
- "dist/2022-08-11/rustc-1.63.0-i686-unknown-linux-gnu.tar.xz": "11d3729f0343a069e9e59531745170cb0b6ce68f73848699564ea0bbcbf2c02f",
- "dist/2022-08-11/rustc-1.63.0-mips-unknown-linux-gnu.tar.gz": "632684709f15776f5924ab35dd783a06f32e051a232cff601e1ec206669345c0",
- "dist/2022-08-11/rustc-1.63.0-mips-unknown-linux-gnu.tar.xz": "e1a7b53d580608663faf8dea9494b6d170eb4c37535691db7a6d7761ecb6770d",
- "dist/2022-08-11/rustc-1.63.0-mips64-unknown-linux-gnuabi64.tar.gz": "9c2a0a3e55d48ec153090cfb1fff027d52a8a98f65847e8e03d5ce795663f80d",
- "dist/2022-08-11/rustc-1.63.0-mips64-unknown-linux-gnuabi64.tar.xz": "8ee05d6baec21af7e525ac2b76e974d149785a78fd9094bc05972e12ab3e12b0",
- "dist/2022-08-11/rustc-1.63.0-mips64el-unknown-linux-gnuabi64.tar.gz": "772c06eaecfbebb00015928063868eb18d3f06ef42957002f62337cfcce801cf",
- "dist/2022-08-11/rustc-1.63.0-mips64el-unknown-linux-gnuabi64.tar.xz": "9a2231729e5f8a4c2a98946cd958c2f8cde2691ba3c3c570ab13996bc1e22f99",
- "dist/2022-08-11/rustc-1.63.0-mipsel-unknown-linux-gnu.tar.gz": "f3b0a195531726bd4d71af9a6013cca30a0a5da1000609a8c7b518c2a4dcac83",
- "dist/2022-08-11/rustc-1.63.0-mipsel-unknown-linux-gnu.tar.xz": "b428acd489842ddf186680e6b6cd3f05d67ac0f91896c07a5425f8835842c14b",
- "dist/2022-08-11/rustc-1.63.0-powerpc-unknown-linux-gnu.tar.gz": "303df3e1c0365c9db24b2347e2059d38ff61be8cd42fd50dbfcec8debbe25109",
- "dist/2022-08-11/rustc-1.63.0-powerpc-unknown-linux-gnu.tar.xz": "7a99dd6a7f30b8a8f85d95f47fa77084a48c7ebc94092978daa3563268a4b15b",
- "dist/2022-08-11/rustc-1.63.0-powerpc64-unknown-linux-gnu.tar.gz": "f3634a6f894c3e7affc2ba9f5d50bc9737ef321f5e03a54e5cb0402b7ce25382",
- "dist/2022-08-11/rustc-1.63.0-powerpc64-unknown-linux-gnu.tar.xz": "57b1060e5143190c110613afc8a3ce22f2b210953b20d00f59dc9e139a50bf75",
- "dist/2022-08-11/rustc-1.63.0-powerpc64le-unknown-linux-gnu.tar.gz": "2be8d980d07d2a0f7a38da72037dca4f8b5a7cf23b3376794ca29eb7bd04b2fe",
- "dist/2022-08-11/rustc-1.63.0-powerpc64le-unknown-linux-gnu.tar.xz": "b3dc2c082e76b5effe0b158aac3831830168a1a6980b39347c355e49be63fcca",
- "dist/2022-08-11/rustc-1.63.0-riscv64gc-unknown-linux-gnu.tar.gz": "a639533bcf140f30499ad6668a4851d8da50658711e8df273033e4d1f7b70f2d",
- "dist/2022-08-11/rustc-1.63.0-riscv64gc-unknown-linux-gnu.tar.xz": "83464d74ad470e7bb56d9478537014768bccb298ca82bc3279f482784461e13f",
- "dist/2022-08-11/rustc-1.63.0-s390x-unknown-linux-gnu.tar.gz": "4fa295954caf0c5935b1b0c7abe3584c26b2d009e10e2797922190baf76795c9",
- "dist/2022-08-11/rustc-1.63.0-s390x-unknown-linux-gnu.tar.xz": "99c6f145d3058ff5f17ef9c82ab44860bbf057b20a991c68c711d414d9ca2cb6",
- "dist/2022-08-11/rustc-1.63.0-x86_64-apple-darwin.tar.gz": "47cd3aac451fe69a131d452023578d6da2fe954b4a90b2d65177c217628f2faa",
- "dist/2022-08-11/rustc-1.63.0-x86_64-apple-darwin.tar.xz": "013af630df1136febf784c91f61d04f501226acc3b08b099b17456c62e0bd42c",
- "dist/2022-08-11/rustc-1.63.0-x86_64-pc-windows-gnu.tar.gz": "23e024504e151a32df68727071530c7b98901955fc64145556cd5e9a86b80d7e",
- "dist/2022-08-11/rustc-1.63.0-x86_64-pc-windows-gnu.tar.xz": "96753ac4c10c44568968cdae44f20d674527622d771faf3760d1bc6204fb43a5",
- "dist/2022-08-11/rustc-1.63.0-x86_64-pc-windows-msvc.tar.gz": "258e22e8b6500038b421ed328dd844856409b78a3c76585b02b6d22b62dd818d",
- "dist/2022-08-11/rustc-1.63.0-x86_64-pc-windows-msvc.tar.xz": "c953562b6ce63b2cd8d36dcc3d6c598ca430b041573961e942ce978ee7e68522",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-freebsd.tar.gz": "1b2f4143b4c9b3d22d1c0f7bf34b965f4a37f8d88c7c8fbe6478b997ca18a801",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-freebsd.tar.xz": "13f55761f1fe00e04046bfa37e01dd66c10d33dfc66b8790e284eeb0a6e8da62",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-illumos.tar.gz": "dad416871d07e7ba761c2a7891e72c471e7a3f3d0c62fc2aed2ba2e89603b552",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-illumos.tar.xz": "4e20cfbeb15e5a36b3e6879da47cb2e801f4e0236bb3bbc9b970eb6179c85588",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-linux-gnu.tar.gz": "c5bb7656557bf6451b2c53b18b6d092814fcba922ff2ffa4f704a41d79595f2d",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-linux-gnu.tar.xz": "bdab9d9afa5c329c40f9ba568364815237fab8426477c12bfabad35ffc484ab5",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-linux-musl.tar.gz": "91b3fd3883fff758ccff5349cf7960caa567b02ee0911dd6beaeed1f45b3e3bc",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-linux-musl.tar.xz": "b6566a9b1dafe03cf4a01b58b2db0e14a0044ae5773736827882bd549108277e",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-netbsd.tar.gz": "1ae4d4963fe0aed9c4bb9f83b4a9618eca4be8f1569688f9a0f3b8d9600eb042",
- "dist/2022-08-11/rustc-1.63.0-x86_64-unknown-netbsd.tar.xz": "cab27034f77005ef7b5c58e4a765e391c730f847d9203c68920e83e970d6a4ab"
+ "dist/2022-09-22/cargo-1.64.0-aarch64-apple-darwin.tar.gz": "dbb26b73baefc8351a7024f307445758fe1e9c18d83000358c02b80a5b1003b3",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-apple-darwin.tar.xz": "8d987d76039b730086ee303710d93f3ff2abcfe3cb74505d8e68c9f72edaa812",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-pc-windows-msvc.tar.gz": "6b86e2b51fa4471358e128369baff21a216815e90eb3ff70af7271e64438da0a",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-pc-windows-msvc.tar.xz": "dc174319e5750d6489fd45d982a5dd9d7305845e9aaaa809bef9f445f1c2c219",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-unknown-linux-gnu.tar.gz": "a2079bad79c054facecd149bafb645c321047fd9e4d2aa500607b2450654b209",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-unknown-linux-gnu.tar.xz": "103d69e4f2f49f5a6309d7d195747b31f94cf707f90fb49cf76039a5ce6295c7",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-unknown-linux-musl.tar.gz": "f589c0e8c0472128e88f751429b5e697b5605e2105e3571016400f98f47c1b54",
+ "dist/2022-09-22/cargo-1.64.0-aarch64-unknown-linux-musl.tar.xz": "aff8dedcaa02b5059dd59f8c5644ed87b8c9c72be90c578044fe5755ca841418",
+ "dist/2022-09-22/cargo-1.64.0-arm-unknown-linux-gnueabi.tar.gz": "f497f70e3154d78399487c75934734a13efdb64d5ba8fe7fcd4d28740cece688",
+ "dist/2022-09-22/cargo-1.64.0-arm-unknown-linux-gnueabi.tar.xz": "79e703e1e0355ef3d268d13f778b2c85ada0dee9d5067fb94f5fca20c6d09c53",
+ "dist/2022-09-22/cargo-1.64.0-arm-unknown-linux-gnueabihf.tar.gz": "40e6d068d84a110c74c63dbd9bc457c8e9d8c520bb75c64b2b4f1a269378a003",
+ "dist/2022-09-22/cargo-1.64.0-arm-unknown-linux-gnueabihf.tar.xz": "d73428a73d9234c9f4f6412025ca827a667b2d6e8dc61e1852725784d8d3136d",
+ "dist/2022-09-22/cargo-1.64.0-armv7-unknown-linux-gnueabihf.tar.gz": "a12455495aa39006f2cf83c9f86b7ecc4b188f98e683a99134c97eeb217b66bf",
+ "dist/2022-09-22/cargo-1.64.0-armv7-unknown-linux-gnueabihf.tar.xz": "ecd2e5f4c08bbda72ad2936bfdd521d9a641d311e71e8ace44b00570f068b819",
+ "dist/2022-09-22/cargo-1.64.0-i686-pc-windows-gnu.tar.gz": "2e73350bbe2e8c5fa27893e57704e37d6c6d8ef5d548a7bbe0d24615468f5158",
+ "dist/2022-09-22/cargo-1.64.0-i686-pc-windows-gnu.tar.xz": "3596f78c51024eda28adc8be508ad084e1e6dfb71d8a0bce00a67cfc592ec5ad",
+ "dist/2022-09-22/cargo-1.64.0-i686-pc-windows-msvc.tar.gz": "55b9d1a121410a5f3c755012ec4a55ee6f7c270a958c7a506c14542095a793bf",
+ "dist/2022-09-22/cargo-1.64.0-i686-pc-windows-msvc.tar.xz": "64711cbcc71906184427f501399ebe304e95a42f2f773d251cdd6bb1a148dc94",
+ "dist/2022-09-22/cargo-1.64.0-i686-unknown-linux-gnu.tar.gz": "da713a9521c857d87bfebc1e2b1da01e9882d11fa6cb1c2ebbf38b1b0a15bbcc",
+ "dist/2022-09-22/cargo-1.64.0-i686-unknown-linux-gnu.tar.xz": "e2e20a16f5db52cd6b773c94225b03880743544ff2f317dd857cf0dceac6ab57",
+ "dist/2022-09-22/cargo-1.64.0-mips-unknown-linux-gnu.tar.gz": "a935deca822265d1b341682324743c95213346a650eecdf7c8493eecd233ba72",
+ "dist/2022-09-22/cargo-1.64.0-mips-unknown-linux-gnu.tar.xz": "3227f9957542bc2b8ef6605e24cd27a16ab76ae318d86d18f4e99ffcf17aaae4",
+ "dist/2022-09-22/cargo-1.64.0-mips64-unknown-linux-gnuabi64.tar.gz": "4bdf7a09474588dd647e9007ca0fcce13bf8784f20e940442c0649c40b5402d0",
+ "dist/2022-09-22/cargo-1.64.0-mips64-unknown-linux-gnuabi64.tar.xz": "4b4c950e95755b39ef64b720913482f3a61daceb4e8a57fe8812f92b4c2bc76f",
+ "dist/2022-09-22/cargo-1.64.0-mips64el-unknown-linux-gnuabi64.tar.gz": "e49b9e758768533b47470765eb2b4cc3cdc378460677daeaff62638e711b957b",
+ "dist/2022-09-22/cargo-1.64.0-mips64el-unknown-linux-gnuabi64.tar.xz": "252d0edd035601ed2fb633093780a9bbd957ed7abf276cc48e805e6cdedc76cd",
+ "dist/2022-09-22/cargo-1.64.0-mipsel-unknown-linux-gnu.tar.gz": "26c870ab447656d4c5610c73af7bbd400dc06dad0fd90c7558206c4ab4783928",
+ "dist/2022-09-22/cargo-1.64.0-mipsel-unknown-linux-gnu.tar.xz": "42ffc698db364e1d8a1b1c20e87ba0aadf2a0103f411a76fa277de84fe8139a5",
+ "dist/2022-09-22/cargo-1.64.0-powerpc-unknown-linux-gnu.tar.gz": "112820998ab4b1a20a2bac39963ee50e49adf4d3eac22b0f8af4d7b55044ae9a",
+ "dist/2022-09-22/cargo-1.64.0-powerpc-unknown-linux-gnu.tar.xz": "d2e075eba43c29fe493d7b9d5b951ead3f0a61fd8c7d7fa795547fd02827cb5b",
+ "dist/2022-09-22/cargo-1.64.0-powerpc64-unknown-linux-gnu.tar.gz": "8a5f37a0a50cc516772af9c1b56a4f159c1b90b4ec64470313afa9ad7ffb1552",
+ "dist/2022-09-22/cargo-1.64.0-powerpc64-unknown-linux-gnu.tar.xz": "82787ee0f4951227eff08ea0127d4454ea2a56fe1f06ecca6de7823bcb3be647",
+ "dist/2022-09-22/cargo-1.64.0-powerpc64le-unknown-linux-gnu.tar.gz": "19df9e098ba8a2a6d6120a1340b40dfcaf4cbb5b0c1294d76665e75555bffdd4",
+ "dist/2022-09-22/cargo-1.64.0-powerpc64le-unknown-linux-gnu.tar.xz": "ba7188b2c7890e61bf58d3aa9e94c323fec375f67cf03841bbcc0f6c800fe6ad",
+ "dist/2022-09-22/cargo-1.64.0-riscv64gc-unknown-linux-gnu.tar.gz": "f5ebe9cf9237845051bfcb173101eb15c45b651d79b0d7982b11b3c7cd08832d",
+ "dist/2022-09-22/cargo-1.64.0-riscv64gc-unknown-linux-gnu.tar.xz": "b94e262dec82b7cacf3baa77f35601c82d389ad338d118b42da4d23e26240760",
+ "dist/2022-09-22/cargo-1.64.0-s390x-unknown-linux-gnu.tar.gz": "a5f14599f7ca4c641c27b9fa5bbdfbeb5f92eb8f66101b7474f04ff78df4950d",
+ "dist/2022-09-22/cargo-1.64.0-s390x-unknown-linux-gnu.tar.xz": "7c01b6af89c18437778ef410cb98c948493bd6070c4b81e7f38f3c25ae1c6a52",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-apple-darwin.tar.gz": "e032116e22f6d3a4cb078f21031794e88f2a87f066625b8eb7623777e42d6eca",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-apple-darwin.tar.xz": "9dd507854410d20cd8b75b296e319bb5a62f9b1c2cb6c2b043c32de96eb5cc35",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-pc-windows-gnu.tar.gz": "dc029ae8045adc561ccab8a981be89c5eda83162ffcc0c43a1dd7d9c903b2e09",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-pc-windows-gnu.tar.xz": "287c49c9a9cfb51f9bb758ee3586cb3542aa1c0651f088cba4e6eb4ba8e87741",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-pc-windows-msvc.tar.gz": "b197c91ef9ddd98f1ae129e4f108d9d2b48350dc377300047cbb19c63a6fc641",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-pc-windows-msvc.tar.xz": "38d75dbba91dc1dbf35898c5845ee29d6f6ec69b44516220930b4c7e8719bd0a",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-freebsd.tar.gz": "36e86a67fa943d324ce7b977d967ae16ad012ac0aa0b7625db61a16c8f25c2d1",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-freebsd.tar.xz": "6a78d94aed814a9ff3bc650d0ff0ac7ee1eb1595819e672bc7e66d658149d808",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-illumos.tar.gz": "360ebcca8247099bffae548a1c09449c8dc4516918d4f18f7ba09ef650b7775c",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-illumos.tar.xz": "f7ac58bbf283c8c6fcb3648bb18601e0c7c30f6613177b400485f39dc4552044",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-linux-gnu.tar.gz": "12c2e61bf7de8b37c16d0323972a6085f9e01ee6d716549dd1ef4a92481b0610",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-linux-gnu.tar.xz": "21434d83a30ad3fa4e4831487c5574a20b07dd57d213b26e1246290c57d4ec41",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-linux-musl.tar.gz": "fffd3e692f39c28a0392d17ee2f5695f53141e34c0bf8bbb7cdc0ef9fd3ad791",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-linux-musl.tar.xz": "01d06176fd894b9299ed4f5b78e87d78a9a25b9ba803d3f8c50b7a4ea21d8807",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-netbsd.tar.gz": "cb2b26b0081cefdf87e977d7ba3b82687b15f79d875188c6028a3f25f5601a4f",
+ "dist/2022-09-22/cargo-1.64.0-x86_64-unknown-netbsd.tar.xz": "302402ff74a8cf51d22808723d3ed3fee2b6cd765677023d2f380c34f2c6f719",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-apple-darwin.tar.gz": "808d3b83211e45cabdf59a19a72565e13d45bba79053ae8210d51eb05500e5fb",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-apple-darwin.tar.xz": "ed79f61b3d8b4ea3ffcb78fb9952cc3b199d646d057827bb3bfa5247489f21cd",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-apple-ios-sim.tar.gz": "24f8b2121f4d342eb9d21b926a34bd7960c34275ce9bee4e77c67969a2780ca9",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-apple-ios-sim.tar.xz": "2e1193d20d85265def6e4e525b32f197b7bec6047f22c43f0df15d8e4aae1ff0",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-apple-ios.tar.gz": "aa6513954fe168aa158fb5f6074037d252e4c8fd9bec5c4894dd68c8be4c8fdd",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-apple-ios.tar.xz": "6c1b63340ba2aa051eea47d09b1c79c817538144140672f6f11be8cefa241501",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-fuchsia.tar.gz": "5ffb190975f5936800e128d1a41ca8a9974acad2ce80d1b45620a259860e6ffe",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-fuchsia.tar.xz": "d69cb543c339c5830b3e65a4bf754b8540a5e57044be44fd34580b1dbe9da0ec",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-linux-android.tar.gz": "b56deb8930974159f1027f884b8a4756e392765189a27f6d80e95519d206b9d1",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-linux-android.tar.xz": "b6395b3bd2be7787672366482e134dbf64a9418aa5011b2090ed906cd3c0a060",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-pc-windows-msvc.tar.gz": "708e7a144c3f7895a80e87cd3f59083ba72d2f5670da550f5dfb843385214c95",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-pc-windows-msvc.tar.xz": "9fd1b3bad839f01c7b8c5075c34dfe8d0c1a9fd7139cd7aedf7144cabfc610e7",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-linux-gnu.tar.gz": "2b425658f84793d5bbf00ce545f410ec6454add202cce27a718d81e0233e7007",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-linux-gnu.tar.xz": "40abc9ec4f86ff0e37ba176e4c68dfa708e9857bb0372169c865367593127566",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-linux-musl.tar.gz": "fc74d1ddc8a12d7a58a40534b10297e249c972e39943a7cb514ac72032c5fcd8",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-linux-musl.tar.xz": "2438f7116711b2c65b60d59662ad333cc5f66868ec34498777ed764103f4d4a3",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-none-softfloat.tar.gz": "6697319c1011268dd73c9140655a04321d52b257dc381da374db68fb990cfc42",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-none-softfloat.tar.xz": "ea09ce9479411883444011727cdc9655748f4fe199d16a547a6464a68c45beb9",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-none.tar.gz": "a32b5b222fc43fd791d62c4c1bebb9a41d2783934e3f27f7bdb692342cca2502",
+ "dist/2022-09-22/rust-std-1.64.0-aarch64-unknown-none.tar.xz": "241a7335982e67b510fe48d33acce068c2dda88c20b321d3fe87cb3625239f5f",
+ "dist/2022-09-22/rust-std-1.64.0-arm-linux-androideabi.tar.gz": "4fa112179b4df1bbf5922c4e68e7c8fa87770ee1bec951e39761cc5f0e504e29",
+ "dist/2022-09-22/rust-std-1.64.0-arm-linux-androideabi.tar.xz": "da0d33bee214073dff52914e2f9cfa4a6ecea6a1035ffae71c4338f5bcaa02e8",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-gnueabi.tar.gz": "f7ca0fc92aab9f1a8c44ec180c7e10018138ca7e9b507bec085d03d9fd3a73e9",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-gnueabi.tar.xz": "9e7dc879ce647d0b5c7423dcfea1438d64ea2e0764895b5cb9b3258ab0ecf8dd",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-gnueabihf.tar.gz": "30ea300372033c2886d61ac59a7532f8d0e4665f548c6e90d8fd25a57f89ee9f",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-gnueabihf.tar.xz": "07fbe4ef51f33e7954e25c433522da224b10c6f7353f612713669a4fc58704e8",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-musleabi.tar.gz": "0f6e4f77289cfa8eb415c037449f59ce359dbef9a161c78ba8474c8405fbd50b",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-musleabi.tar.xz": "f0d24e63e2687af229ea1472650bf5dd5a50d7706062b47a73413e28101fccf1",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-musleabihf.tar.gz": "21990412baeade16a29a7b82e2734460e3fae144abd4eee1bb31848ac94ad30b",
+ "dist/2022-09-22/rust-std-1.64.0-arm-unknown-linux-musleabihf.tar.xz": "9955ac8be9828e0400c16a1c0388a769401dc8e732d099ffada156867cab08fb",
+ "dist/2022-09-22/rust-std-1.64.0-armebv7r-none-eabi.tar.gz": "a6c849f95edf97d2fceabee5cf21963062ce2d840794acf28a427128430ca01f",
+ "dist/2022-09-22/rust-std-1.64.0-armebv7r-none-eabi.tar.xz": "d8bee2d8337bb67ab604961a61e117d09d93b500dc8bea17c85f2f349bf18ad2",
+ "dist/2022-09-22/rust-std-1.64.0-armebv7r-none-eabihf.tar.gz": "74296a66735011527c129e5885105398479b2dbdc98b2ff516c655681354ca86",
+ "dist/2022-09-22/rust-std-1.64.0-armebv7r-none-eabihf.tar.xz": "39ef3482b47b6218cf811ef53662385b8c52ef91930acc60685a3e334126d02c",
+ "dist/2022-09-22/rust-std-1.64.0-armv5te-unknown-linux-gnueabi.tar.gz": "7bcea2b201ebc61748760e5004d4451944191391129d3cd47cdbc909aeb0c3be",
+ "dist/2022-09-22/rust-std-1.64.0-armv5te-unknown-linux-gnueabi.tar.xz": "af9b36ce5ad613112f83f085840e1f2c5f58ec7b72d8dbf9e833883105699a37",
+ "dist/2022-09-22/rust-std-1.64.0-armv5te-unknown-linux-musleabi.tar.gz": "d38f38f2f31fb099c1360e5ef81fd3159b09ddf0bfd8b555cfb07acc08be5547",
+ "dist/2022-09-22/rust-std-1.64.0-armv5te-unknown-linux-musleabi.tar.xz": "5246edd6be26f10d11a3100d3e74f460c2cfbdabb417e4cc8225ce2b82c485ce",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-linux-androideabi.tar.gz": "997cb016441d53f45e8bb9c7c7aca1926275c384505f33c1b713e695e3532ae4",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-linux-androideabi.tar.xz": "8bcb6ad1ef04154191be993135b604ce344bcc0645f235d87027c05abe9de8fb",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-gnueabi.tar.gz": "89ef5effad1ed58610582b35db06670b01a7a491ac43856c8d6d179b37814e7e",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-gnueabi.tar.xz": "eca7608caa6b8fb31467b4524292e86f854ebd06fcff29f58f5fc860b664c711",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-gnueabihf.tar.gz": "9cda1ef1d14372d7c5288cc69c9b5e9f211f5bebf7da22fae6d6ca8fc06ed687",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-gnueabihf.tar.xz": "ef1820f55b341ed1a78cadbd3564f9f8800f99bbfb7533821ef5f90ba2c21e87",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-musleabi.tar.gz": "bbff558e98be89b530dc5f6aca35e5b9661fb221bd2a199b7de6cf971dc60ab4",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-musleabi.tar.xz": "742fac589f1bc1a0ddd857e32b317e2b673c40adb8ef6dfc3516563ba9bc839f",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-musleabihf.tar.gz": "bb233eb7c5dd2f8ae50c4874aea1a8b2e9965f92d184c4e6574f6db45f3c0562",
+ "dist/2022-09-22/rust-std-1.64.0-armv7-unknown-linux-musleabihf.tar.xz": "a31b9284ca3e864343fdad900fc877cc14e00de32dcde7326023372720cd4b09",
+ "dist/2022-09-22/rust-std-1.64.0-armv7a-none-eabi.tar.gz": "1074c419524eab1e6b73c54e62a30b50f0557025e30372316965218cba515858",
+ "dist/2022-09-22/rust-std-1.64.0-armv7a-none-eabi.tar.xz": "3cc35863989cb5b1e236ae79600649ef5bc460233afb11d806dfb2c028c14e09",
+ "dist/2022-09-22/rust-std-1.64.0-armv7r-none-eabi.tar.gz": "df7efe69bfdc3e284550ef75f4617a9d0b5f02157fe19ec3306e81d719959970",
+ "dist/2022-09-22/rust-std-1.64.0-armv7r-none-eabi.tar.xz": "c8091d6ad014fc9608a51f942ebd0d67c2fbfa186133e4054cb162c6a03ab3f0",
+ "dist/2022-09-22/rust-std-1.64.0-armv7r-none-eabihf.tar.gz": "258d0df03c1ad69a194510c3bfc22dbdeeedbfc881d16e83dd86cbee60d4c952",
+ "dist/2022-09-22/rust-std-1.64.0-armv7r-none-eabihf.tar.xz": "52ddc8560c87303b887eb852a7b742c59cee240500bbdbf3069eb7258f9a9e35",
+ "dist/2022-09-22/rust-std-1.64.0-asmjs-unknown-emscripten.tar.gz": "71c28ab0421fcc9d045a19eb67778c9c4b9d64a37e076fe94621c1d84bbdb97b",
+ "dist/2022-09-22/rust-std-1.64.0-asmjs-unknown-emscripten.tar.xz": "6443813cc696cba8155c1cbfe8eb46ef1846c4609f6887e8d883b0a3a045167d",
+ "dist/2022-09-22/rust-std-1.64.0-i586-pc-windows-msvc.tar.gz": "c5ae8faf7a3c8f94a962f460c44b7fb155f0ccc9b98447c21ed63798276cb25c",
+ "dist/2022-09-22/rust-std-1.64.0-i586-pc-windows-msvc.tar.xz": "ce02bcf63aad651ddaa05a5034704d2e8c8cf064bca94acff5ce96c0fcda07b9",
+ "dist/2022-09-22/rust-std-1.64.0-i586-unknown-linux-gnu.tar.gz": "82779e550c600d664063c935a5fb52fa1c5e3ba840fe1bf01a48ee9757f6b640",
+ "dist/2022-09-22/rust-std-1.64.0-i586-unknown-linux-gnu.tar.xz": "791aafcfb41c342783bc3c8cdb57ac61453fc02eee185f15c275716f419556f3",
+ "dist/2022-09-22/rust-std-1.64.0-i586-unknown-linux-musl.tar.gz": "a649905b57cff932ae3d8955c410398c225ff2cd9d80da8076eb19d5338cb1e7",
+ "dist/2022-09-22/rust-std-1.64.0-i586-unknown-linux-musl.tar.xz": "0cb3b0848cd31bd68ac82cd138c6345e5348f5af3dcc1f13275ee019a0895c59",
+ "dist/2022-09-22/rust-std-1.64.0-i686-linux-android.tar.gz": "445755849a1469147316bc496a02ae198f293d537b3a95040d9c3892cf41d37b",
+ "dist/2022-09-22/rust-std-1.64.0-i686-linux-android.tar.xz": "b7185e6b963235734acb092d0cef6cc77d5799e659fcd1e1543fea62351ef51e",
+ "dist/2022-09-22/rust-std-1.64.0-i686-pc-windows-gnu.tar.gz": "08648a4175ed8f211f9ac7beedb171b9074d041e10b89db45cd45d42af88d854",
+ "dist/2022-09-22/rust-std-1.64.0-i686-pc-windows-gnu.tar.xz": "a05610fccaacbcbdc7c872280f73ae0999666058cfba409dffcab3f2cc64d6f6",
+ "dist/2022-09-22/rust-std-1.64.0-i686-pc-windows-msvc.tar.gz": "e0871d7e01d404498bb457c2f96143b844f2cf886a546c505a8bff640940e785",
+ "dist/2022-09-22/rust-std-1.64.0-i686-pc-windows-msvc.tar.xz": "a18e2b009dac092f6410a4e66d5c22e81e525c7f9cb91296553ed8832fe35d33",
+ "dist/2022-09-22/rust-std-1.64.0-i686-unknown-freebsd.tar.gz": "575ce3a32df08254e0c2ada462c950647a85861c0e1ec18d1b83b17c82d9717b",
+ "dist/2022-09-22/rust-std-1.64.0-i686-unknown-freebsd.tar.xz": "d0ae58443104554e4636ffccde22a09d7ec360749f6638cc06d1cd22eaaa2f4d",
+ "dist/2022-09-22/rust-std-1.64.0-i686-unknown-linux-gnu.tar.gz": "50b32b772e2eb993dea89011fd800c291889c05ce615e45d9a260ee568661069",
+ "dist/2022-09-22/rust-std-1.64.0-i686-unknown-linux-gnu.tar.xz": "c80c57df63517d6171c061e6c095b794593172a3abefa9b4202992706bda12e5",
+ "dist/2022-09-22/rust-std-1.64.0-i686-unknown-linux-musl.tar.gz": "2898a1b2a3c28201d2da4e470bc64c261e6eb61531fbdeeb963b3dbef4d958ec",
+ "dist/2022-09-22/rust-std-1.64.0-i686-unknown-linux-musl.tar.xz": "b193faf2e37951bf1ac6c3f2d4bd4fe84971a2f56f22e66323cccd142df54156",
+ "dist/2022-09-22/rust-std-1.64.0-mips-unknown-linux-gnu.tar.gz": "1649e72798f14336c25019cf0d5e800016f9087e9e703749c456e1293178f01d",
+ "dist/2022-09-22/rust-std-1.64.0-mips-unknown-linux-gnu.tar.xz": "45baef38fbfadf21d4e603554c49d62525d1dff887e4ea7045b1fc88feb81663",
+ "dist/2022-09-22/rust-std-1.64.0-mips-unknown-linux-musl.tar.gz": "bc18714aa6ab30d3b53cb166a3126fd3a1876b4c53aeba1741b9227400e49968",
+ "dist/2022-09-22/rust-std-1.64.0-mips-unknown-linux-musl.tar.xz": "993b3e003feaa966466509ea9161106978ef7c874877461b4ca1a9936032b25b",
+ "dist/2022-09-22/rust-std-1.64.0-mips64-unknown-linux-gnuabi64.tar.gz": "8d876d6b783697d306240414cfea4c1ebca8f97b77a70f32aba5cea41f205756",
+ "dist/2022-09-22/rust-std-1.64.0-mips64-unknown-linux-gnuabi64.tar.xz": "a2d2e2d274105054303adfd9ecb75ea2fba36a228ab23a669c609062f4db0035",
+ "dist/2022-09-22/rust-std-1.64.0-mips64-unknown-linux-muslabi64.tar.gz": "a51ecd555b7374eba850b47ddc83c0a6a288a547ce14c90629c0077c0297c023",
+ "dist/2022-09-22/rust-std-1.64.0-mips64-unknown-linux-muslabi64.tar.xz": "83981de8b57719d714d59b55f3749d8c6ff10588d8d6c7d7ae371bfb668a7b5b",
+ "dist/2022-09-22/rust-std-1.64.0-mips64el-unknown-linux-gnuabi64.tar.gz": "2f7632305068706e09c02421856bc8bba5bf28c197dea418a7d076d1d6f35cb9",
+ "dist/2022-09-22/rust-std-1.64.0-mips64el-unknown-linux-gnuabi64.tar.xz": "8ec026244400bac48d918230a0c99aa2c31ff33d6cc4d18552228509ca58c074",
+ "dist/2022-09-22/rust-std-1.64.0-mips64el-unknown-linux-muslabi64.tar.gz": "d707d6e9e58921ea6c2a57882fc32dc5e2a74003ca0a30c9460e5d88c8b07e5f",
+ "dist/2022-09-22/rust-std-1.64.0-mips64el-unknown-linux-muslabi64.tar.xz": "97f40ad383014955448f7917abba7a547d1ddd205746641d3e9c3f730cbd129e",
+ "dist/2022-09-22/rust-std-1.64.0-mipsel-unknown-linux-gnu.tar.gz": "6f0e5498ab6505e3f4312249fc369eded48b9d4f33f910eee438936ad5d25758",
+ "dist/2022-09-22/rust-std-1.64.0-mipsel-unknown-linux-gnu.tar.xz": "7dbcf969fc6717215796079437cf073a8ef7df95b77ded4654009c8379c91e0a",
+ "dist/2022-09-22/rust-std-1.64.0-mipsel-unknown-linux-musl.tar.gz": "eabb79f49167d03e1c5ee4f047316d84db5d50e3224aa6168765a5f5db0afe93",
+ "dist/2022-09-22/rust-std-1.64.0-mipsel-unknown-linux-musl.tar.xz": "288dd07746b0ece185753e784c7e97f2f01984e9302ef46a4ff71db665002637",
+ "dist/2022-09-22/rust-std-1.64.0-nvptx64-nvidia-cuda.tar.gz": "32d865ba8c5b3a61ae0393fa021ebd15d14a515723879a3c494b7b7320f325ff",
+ "dist/2022-09-22/rust-std-1.64.0-nvptx64-nvidia-cuda.tar.xz": "fbf12642d1df994db8e2e25d50f3c1a567b6b9379c53c1151afe2e3c6871022c",
+ "dist/2022-09-22/rust-std-1.64.0-powerpc-unknown-linux-gnu.tar.gz": "61d228cb732ddb85802465781b69ed20719314adde5863805cdcac9c3cc1336f",
+ "dist/2022-09-22/rust-std-1.64.0-powerpc-unknown-linux-gnu.tar.xz": "6b29ebec4cd705760db634717cf6df68a9a377d52c25def30f5a2e2641a83279",
+ "dist/2022-09-22/rust-std-1.64.0-powerpc64-unknown-linux-gnu.tar.gz": "4a96801730f61b8b116553ec7c3572b56b03836b59220b3f2b2736e8428a92e3",
+ "dist/2022-09-22/rust-std-1.64.0-powerpc64-unknown-linux-gnu.tar.xz": "dc0352fdcf7f8b4fcb551d63001738ee120ea2a0fcc7d55db11f1f87eba90b3e",
+ "dist/2022-09-22/rust-std-1.64.0-powerpc64le-unknown-linux-gnu.tar.gz": "362dc9a7bc63d222598878d8d36dbd9008a1bb05cf389a90eeac28a76f55cdae",
+ "dist/2022-09-22/rust-std-1.64.0-powerpc64le-unknown-linux-gnu.tar.xz": "ef697469b2a3ea8897f49b70e3be0c7aaca3f26fd3234812113e2e85cafac738",
+ "dist/2022-09-22/rust-std-1.64.0-riscv32i-unknown-none-elf.tar.gz": "a6e4f4e61a84a7dce3554f6daea4854e9897f6affd7d0a4de279912a06f30a99",
+ "dist/2022-09-22/rust-std-1.64.0-riscv32i-unknown-none-elf.tar.xz": "6966de249e5b0ac3bf10489baad41a55f29f777dd6d44f76e2ae950ba40cbb41",
+ "dist/2022-09-22/rust-std-1.64.0-riscv32imac-unknown-none-elf.tar.gz": "111900d8e3325bb770b18a43cefb101c47ca9c4aece41c494ead994cfc14c007",
+ "dist/2022-09-22/rust-std-1.64.0-riscv32imac-unknown-none-elf.tar.xz": "5ba51e00b3352b9e207e0f66c890962b7c2111bda9b9f2d786c3e3f10a9c3011",
+ "dist/2022-09-22/rust-std-1.64.0-riscv32imc-unknown-none-elf.tar.gz": "164efc3ec05976883ffba2d52a62243a1c67582d359e301e4a1f6bd83141a747",
+ "dist/2022-09-22/rust-std-1.64.0-riscv32imc-unknown-none-elf.tar.xz": "527bd3c4ec7f68c246046463f56c7071862079c5857e465d2b365de92d4bd81b",
+ "dist/2022-09-22/rust-std-1.64.0-riscv64gc-unknown-linux-gnu.tar.gz": "5b8e8e67ae67ac74699b976043615f029f487c4148fdca4cb33fe7fe90192860",
+ "dist/2022-09-22/rust-std-1.64.0-riscv64gc-unknown-linux-gnu.tar.xz": "284b09a96d4cdbb96827914a318f9c41e2b207c0afeae76b9f0e3830d2ef2d4d",
+ "dist/2022-09-22/rust-std-1.64.0-riscv64gc-unknown-none-elf.tar.gz": "bd04973eb7e8061a55fe27c3fd14a29e1cac143714d323ef4c4c480c4df1df76",
+ "dist/2022-09-22/rust-std-1.64.0-riscv64gc-unknown-none-elf.tar.xz": "eac6ca401809e0b94ace04ae255525bf972ad5cdc1f8775d401e166c4b688a0d",
+ "dist/2022-09-22/rust-std-1.64.0-riscv64imac-unknown-none-elf.tar.gz": "55bfb141b8ae992e3ac1066b264f7a8609d10e2223079ecf503928fd1d138272",
+ "dist/2022-09-22/rust-std-1.64.0-riscv64imac-unknown-none-elf.tar.xz": "74af2d8a944a1d57f27c002710ef9ba8e6f434d524ae27ba482f8ce7b5474f0c",
+ "dist/2022-09-22/rust-std-1.64.0-s390x-unknown-linux-gnu.tar.gz": "b8c75287bd02dab135199fb760ed8adefa0bea44fd678421dd383582d3af8c28",
+ "dist/2022-09-22/rust-std-1.64.0-s390x-unknown-linux-gnu.tar.xz": "939db2384f543325cc8a2423ab53e28623b9e9762dacea1e2010cf894d3e6ab1",
+ "dist/2022-09-22/rust-std-1.64.0-sparc64-unknown-linux-gnu.tar.gz": "49d65f9a5bb57325fc3075ed37687e89ace44e2d2d5f1eed97ec3a4a4de1aae5",
+ "dist/2022-09-22/rust-std-1.64.0-sparc64-unknown-linux-gnu.tar.xz": "3551f014fe1839e68e7b06eeb1b3f67869bef9c4849da9c9c01a7b8c3e32ebf2",
+ "dist/2022-09-22/rust-std-1.64.0-sparcv9-sun-solaris.tar.gz": "4fe9b47445348a7251d0b09708f3c29fd424714e9d50a1a3f6ace492e2149b49",
+ "dist/2022-09-22/rust-std-1.64.0-sparcv9-sun-solaris.tar.xz": "d5782d4352ed363011ff896fe89a6ef576e9206e0abb30255fb84cd1707b40aa",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv6m-none-eabi.tar.gz": "d73733335ae6554f42471bfc86c27c1e461401f0c3604514bbaa50f59b3e071f",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv6m-none-eabi.tar.xz": "419dc37e5fad24e5ff41e21b207bda1ef0c5aa94291fea4620c27f8be6d5f3bc",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7em-none-eabi.tar.gz": "90657346d888b1be2f3d7a6491603daaff804016cd45391945456dc0e3c39448",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7em-none-eabi.tar.xz": "b9e77f24e5f37a0789a1e9d84813cee643f4677ff1272e4c01699d74cd42c8dd",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7em-none-eabihf.tar.gz": "53a0dbe3446ec6d5fd20f595c96519c068939e0acea209f958b457c4c0ce7dbf",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7em-none-eabihf.tar.xz": "e5b653284e38c75b1799a9dc21a174e313d65bd19b88f6022f2009be6e404cc7",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7m-none-eabi.tar.gz": "3e27b5f8cfc2be73edc963529a92a077bc47d6a08518ab279a5de1cd02e6ccb5",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7m-none-eabi.tar.xz": "078100e6d739a786be141f387780f42d0d7a248803c66e51341d3ec8cf8ef269",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7neon-linux-androideabi.tar.gz": "8c677b7e69a9e0c2c67c8fb9d12075c573ef9a7f1f4c00d6f326f4ca9bc33b17",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7neon-linux-androideabi.tar.xz": "49ad860fd9dd866f3b1a698c5b05a1b7a61bc6fcd75cbba1d61aec13c797d0c4",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "320efa58b6066e0b640b9b93330f89f27a14cce490d8a5eafe33f1d3949de5f1",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "31397ee504b3d30854d70915d445d8d04361480b3297ce19069056d6009055b8",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv8m.base-none-eabi.tar.gz": "d22c9248d92c1b09f7069ee02e85a6441a3751943d928b791e812890fbf9b2f2",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv8m.base-none-eabi.tar.xz": "6a9b3358c082cb2a4fbbe7e784a3e49e80fdd126fd773aa95d510c444bd5cf7f",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv8m.main-none-eabi.tar.gz": "3e94e4e529d5e1df27c23273fda38c6ad8e3d14e67278ece262cb7b74eeeab7d",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv8m.main-none-eabi.tar.xz": "c57e0033ed685123d1a751f6b22569ad004ff2cb4c67c90c87aad7ba4b236851",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv8m.main-none-eabihf.tar.gz": "09330542b62b03c82e56d5404bb79e9e88af9a693faeeb5bcdad1735df6c8ddf",
+ "dist/2022-09-22/rust-std-1.64.0-thumbv8m.main-none-eabihf.tar.xz": "3834fc11d573847a74558124768c22e9c3d879be04f196d273bdf678513926b4",
+ "dist/2022-09-22/rust-std-1.64.0-wasm32-unknown-emscripten.tar.gz": "547457d0adef92008116afd1635b8abfd10fa7fd8d969223443dc905086a9e4b",
+ "dist/2022-09-22/rust-std-1.64.0-wasm32-unknown-emscripten.tar.xz": "d46d12e7b145c292f36eb1cbe87fdcdad03785431d1b1775b804efba6c0dfd2e",
+ "dist/2022-09-22/rust-std-1.64.0-wasm32-unknown-unknown.tar.gz": "1ecd99d7c8d568156957fcccb2d064eb8e1be3c309e216ce74c65ea549994d73",
+ "dist/2022-09-22/rust-std-1.64.0-wasm32-unknown-unknown.tar.xz": "0be660957c1367d554f9d3649538a26ebffdf2d24d5dc48630c4e4372df6809e",
+ "dist/2022-09-22/rust-std-1.64.0-wasm32-wasi.tar.gz": "d9bd33196e84f70dd67f60181aeee94a081406cac401c4ee613c16f82b99d963",
+ "dist/2022-09-22/rust-std-1.64.0-wasm32-wasi.tar.xz": "388219deb87b5f6f673cc29fbadac4679c3c8d368147abba3c91e5491b09ca86",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-apple-darwin.tar.gz": "eb2f7c51f63973765f01efe509ccd2f26345d4bf0d77695adb4198a0899ae648",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-apple-darwin.tar.xz": "db5909b4b7544b2e1a5651c2d33be8a378e89ffee6b00d247c7cd2c5d115d83b",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-apple-ios.tar.gz": "7091a4133c652cc118e0b46116cbaf649777e79d1c91ae99151b6d390cfee45b",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-apple-ios.tar.xz": "1093cec3252ce6a9b742b961bf4490b2474dbf1d9614834381631c6bd016ba28",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-fortanix-unknown-sgx.tar.gz": "ae65fbd896e8d6ede58d72c86c6070570a63f6505fa1c6a5aed803419a53d1b0",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-fortanix-unknown-sgx.tar.xz": "ad10d74a47ec79b3300be10da2bb5bd3ba4b83f24be7c52e15f8d914578a1515",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-fuchsia.tar.gz": "4666bcd6009b9f1575ae9fed9bc7b0d9f00822fcd5c2dd9e55b6eed4222481c1",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-fuchsia.tar.xz": "c174539e3fee336168d88349d5fd0b77225bbc00f795a34de83cff7cbfcf40b8",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-linux-android.tar.gz": "9ea4213afa6c9b850116c18f2c461e105a5f907a96a057d3646040bfd22df180",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-linux-android.tar.xz": "80560adee5b2fefcde2a4179764d4e01972c2469da0f8b899bede69dfe649bf6",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-pc-solaris.tar.gz": "711364829736f94401b05f5e2bd85ff48234c01fa17fa92fc593e937436c7934",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-pc-solaris.tar.xz": "a4f68e996b83fb29fea28fcd4b0480c6df482408439f6b134dd87f47f2c03412",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-pc-windows-gnu.tar.gz": "dcf87f97432adf7228e907b551d9b73f1ab16f79dc5da0724a227b7ffdaf57b4",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-pc-windows-gnu.tar.xz": "af605be7aca0d4425863776331b0cf428c2f7fdbce899faea4cf2f09c12750ad",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-pc-windows-msvc.tar.gz": "a374306ef4ac906a777e0631a5749d44360ff7cbe91a0df45c67a74ab2c0b7ba",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-pc-windows-msvc.tar.xz": "a075b165891b8f707da80f7ca316bd328abcba95727ca91ee504e9131a335224",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-sun-solaris.tar.gz": "904860bea5b3d578bbecf71000f7ae8c6034a959a0e6aba92aa29b4555741e6b",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-sun-solaris.tar.xz": "8004c8b1cf3aa1874ff6a163f15a4cdae3dd3eea35ef0182468285af342248d2",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-freebsd.tar.gz": "c91edba781ba56f35f2dba56a268d41866ea9bb5f6ffb9d342635f66b836898b",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-freebsd.tar.xz": "70878bf98440f616b14b325235c8e4434b65524532da335dc44474b19b6ebf80",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-illumos.tar.gz": "7dafef8daa72c7ed37208fa017d6b574e5c453cf6a291184ca94806a71705523",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-illumos.tar.xz": "3e7103ff4ab8263f6890b6726f33f08898541fa4ef7fa9c69d8afa39bde53181",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-linux-gnu.tar.gz": "4d4c2715f816bc8ae82c2a5904106fd4dfd668dbd9a98492c8cd388bff9b0b5c",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-linux-gnu.tar.xz": "6ace34bcbba9557aa2fc3a0515c3da4a83ca24d7d45506c5e1b32f589fa38a8b",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-linux-gnux32.tar.gz": "99a0f82b626aee1ff0c2d0425a78398e2fe1ee448a63e45437bd0d0b6c5f21d8",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-linux-gnux32.tar.xz": "14155beea7c65833fa4bc2a6baac52ae8f83c51dce7edf4797658c617d4865cc",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-linux-musl.tar.gz": "243770414216f5c1891778a7bf0b865d28da1d49bfafdbfb45091aa1dfead9bc",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-linux-musl.tar.xz": "29af13a882abbe797fadd43afcb75bce2e2304438db9e21a3e64a2e9100501fb",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-netbsd.tar.gz": "e5b69cbdf7137e53d332ddbd0f6b6d22dc52163d4f50e81318ea01f82c67e5d8",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-netbsd.tar.xz": "bd4fdf598005d11f20db8fbd773f1c7124ba51ab373b35903e4a6750661dbd0c",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-none.tar.gz": "86e479e7ce264f3099dbf89eaabfef85ea7152f492cf14c23b90c05559014de3",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-none.tar.xz": "f48ab8a410a9142cdb9929c80475df6fde5d0c11b976785307e9a1e8b2044e56",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-redox.tar.gz": "65c5abdcad56554294ad7a4bec4124fc65e633ab76e50323c1079aaf33c62a56",
+ "dist/2022-09-22/rust-std-1.64.0-x86_64-unknown-redox.tar.xz": "d8ae246352669df7aec4b43d2bb11fe095da4596533425424827c98a7d93fd4e",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-apple-darwin.tar.gz": "cc68733a81b1bac45bfcccb38412bcfb5c8d0abc3aa246fa9bebff7cf2be4826",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-apple-darwin.tar.xz": "6a040850c3c11d6a9aa3bf3544929009c9d1cfc3c7bf82799bed58c481b7745b",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-pc-windows-msvc.tar.gz": "152871f56d2c3dba43b069bbd0ddc9b1817965375144fea1d16242553f83cc1b",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-pc-windows-msvc.tar.xz": "121074f8bc41a58b0ec7e9e25dc8445f8c10f035cc320da9e97b2a521368cb7e",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-unknown-linux-gnu.tar.gz": "2347730846c1608619c100d41b8d292da002c050575eb8ab7885d478531baeaa",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-unknown-linux-gnu.tar.xz": "8f10b379bcc8caaab983b7d04a3f105dae42f95718f231b46d7e68685d239191",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-unknown-linux-musl.tar.gz": "af05a237f766d8d6828533ee169e19ed9886afa966c1a83546be6fa7e820310e",
+ "dist/2022-09-22/rustc-1.64.0-aarch64-unknown-linux-musl.tar.xz": "880784ec231629e5244f3a9b80e49c60fdef9e360f519bcb9e2b1bf0ccfd24b5",
+ "dist/2022-09-22/rustc-1.64.0-arm-unknown-linux-gnueabi.tar.gz": "9674c7794817e764e1bf55cfcfd5991f0c285a609137b960a24b75cce3fd7a9b",
+ "dist/2022-09-22/rustc-1.64.0-arm-unknown-linux-gnueabi.tar.xz": "cf060d16c7aeb4e1c9515488f3a3514821439c044176c2c38987540351ceea36",
+ "dist/2022-09-22/rustc-1.64.0-arm-unknown-linux-gnueabihf.tar.gz": "c0184fd0c9657b091809fa9de0ce6eaa923891f9cb7f39af7cb3606d0eb1fb90",
+ "dist/2022-09-22/rustc-1.64.0-arm-unknown-linux-gnueabihf.tar.xz": "03475c9ee448e3e14bd3e7e75bcc61d2fed4c4a21f02d80c5574b9c2a859cc0f",
+ "dist/2022-09-22/rustc-1.64.0-armv7-unknown-linux-gnueabihf.tar.gz": "81fdf1207dc5abb420d1e6c0f95f68ec717b183ee5c8dc25860f8e4432be7723",
+ "dist/2022-09-22/rustc-1.64.0-armv7-unknown-linux-gnueabihf.tar.xz": "455ce33dd2894c451d921b5a1ca259732ab0b2e03a3bbc88a25b4d8d0f0833b0",
+ "dist/2022-09-22/rustc-1.64.0-i686-pc-windows-gnu.tar.gz": "c5333399aeb53dfcfd57ec79c245c2f0d4bd1ba3813fcdcfb9d4eb97857927d9",
+ "dist/2022-09-22/rustc-1.64.0-i686-pc-windows-gnu.tar.xz": "8c27aca6ebd973e41e0c402ed040be9e1bcd24c2127f6b1968fa6c40796b3ca3",
+ "dist/2022-09-22/rustc-1.64.0-i686-pc-windows-msvc.tar.gz": "2b02f2e6bf7650890ddcd88e7cd15a6cc0a494b8653fcd788cda2127139e1224",
+ "dist/2022-09-22/rustc-1.64.0-i686-pc-windows-msvc.tar.xz": "9a6257350a25c3d5d18d9f9ae937cb5ed7f46f070e698546ab11f5d9e8d85d96",
+ "dist/2022-09-22/rustc-1.64.0-i686-unknown-linux-gnu.tar.gz": "bd805a90ec93aa1fd3f7b1d1f9339ac336c1350a31cb39f0506ba4da793bd3ef",
+ "dist/2022-09-22/rustc-1.64.0-i686-unknown-linux-gnu.tar.xz": "3d604e150c469461a64c17b6d26f96a5a3d6975246c92cd13ee9bc6e4df0aaeb",
+ "dist/2022-09-22/rustc-1.64.0-mips-unknown-linux-gnu.tar.gz": "ae5608caed9915aaa693b541106eb5e7f730deaad82694f7b699b41cee52f0f1",
+ "dist/2022-09-22/rustc-1.64.0-mips-unknown-linux-gnu.tar.xz": "cb857587dfbbee9d2605093835a9dd261e021b37a87c42a6382224175c0493d1",
+ "dist/2022-09-22/rustc-1.64.0-mips64-unknown-linux-gnuabi64.tar.gz": "8210e115343aac16e73cb938e8b2b0ed5131937db966b6fb600c0674a9c648f9",
+ "dist/2022-09-22/rustc-1.64.0-mips64-unknown-linux-gnuabi64.tar.xz": "6d489dedcc82f201b356ed2ae8db91614eca8344791efe38b5d07b434a32bfc1",
+ "dist/2022-09-22/rustc-1.64.0-mips64el-unknown-linux-gnuabi64.tar.gz": "5c108a9bfd8ac42d7cc7eadc76dc0a3c2b07c625c0603a0eb8d82b55d6957915",
+ "dist/2022-09-22/rustc-1.64.0-mips64el-unknown-linux-gnuabi64.tar.xz": "9a2249057665460324a8c0dd9c269d783ecee69e2f513412be6cf9fad5d8f14a",
+ "dist/2022-09-22/rustc-1.64.0-mipsel-unknown-linux-gnu.tar.gz": "6c338844bbda27edee4284fb7acf4b48b7d5ada3f2f5b0236af8a90a704bf17e",
+ "dist/2022-09-22/rustc-1.64.0-mipsel-unknown-linux-gnu.tar.xz": "aeb1e24596ac507f1facf2d91cf8abdbd8a9e27da79820e5258be1024c5d8514",
+ "dist/2022-09-22/rustc-1.64.0-powerpc-unknown-linux-gnu.tar.gz": "8c43c6868fe824b35d01357da91c111545f5143810d3ef5cd1e7e9d20ba2214f",
+ "dist/2022-09-22/rustc-1.64.0-powerpc-unknown-linux-gnu.tar.xz": "5f4de96bff2937fc0a64a216604c7af765af94460a1f283330eddc610d91271b",
+ "dist/2022-09-22/rustc-1.64.0-powerpc64-unknown-linux-gnu.tar.gz": "cb494af7e7cbbd8032f4f59cc0dbba1bb355adb3e5280a45a3b03e72451ed11e",
+ "dist/2022-09-22/rustc-1.64.0-powerpc64-unknown-linux-gnu.tar.xz": "f58b7797371087800e4cb89807e7f346cc6eea9ab82a85e6f1088ad8369b01f2",
+ "dist/2022-09-22/rustc-1.64.0-powerpc64le-unknown-linux-gnu.tar.gz": "f22636dcac8b16ad357da3a3f36382b277cb3fafbee9b34d7aecd9db3db40d9c",
+ "dist/2022-09-22/rustc-1.64.0-powerpc64le-unknown-linux-gnu.tar.xz": "11630fc51fffe722e52f649357b5948c24b5305cfb61a8114527234e054451c4",
+ "dist/2022-09-22/rustc-1.64.0-riscv64gc-unknown-linux-gnu.tar.gz": "3a59336edcb5e33a3532168cc672f140ea43277229c84955dd5ba7a856006c3f",
+ "dist/2022-09-22/rustc-1.64.0-riscv64gc-unknown-linux-gnu.tar.xz": "5f3e69a185c7246773948ac97c053cf135d81ffdbf926d10a3339de93424f26b",
+ "dist/2022-09-22/rustc-1.64.0-s390x-unknown-linux-gnu.tar.gz": "0555443cc4b7a69896171f2d886a8a2ab1ce91cff0763f7aafbc9567b0929815",
+ "dist/2022-09-22/rustc-1.64.0-s390x-unknown-linux-gnu.tar.xz": "ac3facab7a17d7e7105178275b3186276e58a5202d91f451aa06cca2d0322bca",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-apple-darwin.tar.gz": "1201a655352c1a3ec6cd754e458d12eb0d69afdd1608b2813998d7bda1bb9dff",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-apple-darwin.tar.xz": "ea2e44d239492c1426b93c6b071d309a11f100bd0c76f92169883c8f27a567ca",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-pc-windows-gnu.tar.gz": "7dd40101913c9fdd707d92dae6ad709d90367aa4bc5e43bfc593fd5447666c01",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-pc-windows-gnu.tar.xz": "d38c3404648c1840861da51eb915d42c4c6ab7d12b456e9990dc7dec6521810f",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-pc-windows-msvc.tar.gz": "eb69517a2e0e5d93bdd27e24a8cf9a5fd0af8ed7bce0409bb19df8a007509a7d",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-pc-windows-msvc.tar.xz": "6a86e668a6111dfa72bff4e06d51b1264b92c9ac20ce7d64dc878f7e03a3fa5b",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-freebsd.tar.gz": "a6293ae73f2cf18f07c550a972135cef89979b9f6972e322596898058df6828a",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-freebsd.tar.xz": "2bfff1f69355252de14f6288bd78922f6d3bf93c4540708d22b6aeb9d7262fe4",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-illumos.tar.gz": "4b714e075756d29f6d1c57ce55a13d2d2788709fb4c55efa66f1a168ca94a1e1",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-illumos.tar.xz": "57f1be16d52a1843aceb8df7a882bdaae96606dc06c3af5e463b5c5c9ea11f84",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-linux-gnu.tar.gz": "5923a063408f2db09a0035da4ec699ee1ee35eb62c09c473c882ad77c42da0d0",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-linux-gnu.tar.xz": "1f5756a03119853b53358018c5b1592940a2354c3c9f84ee7faf684e3478f8f0",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-linux-musl.tar.gz": "e7570860b932a6950631ca5a0c4658787a3c56bbab701ba5a4162a7a23a37fff",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-linux-musl.tar.xz": "5177d749b5dcc74596e314b73c5f3f3eabed8b3e207f812f229fbf0682c162ae",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-netbsd.tar.gz": "29689b4eff49d494ef56850cd22130dbd098928829c72a0b5423a02aada846a4",
+ "dist/2022-09-22/rustc-1.64.0-x86_64-unknown-netbsd.tar.xz": "0b6b9e0580078b30a9795b9b116197e7cd2e873c20107dffdb4f775cd4155264"
}
}
diff --git a/src/test/assembly/aarch64-pointer-auth.rs b/src/test/assembly/aarch64-pointer-auth.rs
index 27e289086..da14cd026 100644
--- a/src/test/assembly/aarch64-pointer-auth.rs
+++ b/src/test/assembly/aarch64-pointer-auth.rs
@@ -1,6 +1,5 @@
// Test that PAC instructions are emitted when branch-protection is specified.
-// min-llvm-version: 10.0.1
// assembly-output: emit-asm
// compile-flags: --target aarch64-unknown-linux-gnu
// compile-flags: -Z branch-protection=pac-ret,leaf
diff --git a/src/test/assembly/asm/avr-modifiers.rs b/src/test/assembly/asm/avr-modifiers.rs
index aba4c982c..ffdc8f2e3 100644
--- a/src/test/assembly/asm/avr-modifiers.rs
+++ b/src/test/assembly/asm/avr-modifiers.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0
// assembly-output: emit-asm
// compile-flags: --target avr-unknown-gnu-atmega328
// needs-llvm-components: avr
diff --git a/src/test/assembly/asm/avr-types.rs b/src/test/assembly/asm/avr-types.rs
index 53a601e51..58bf1ad9e 100644
--- a/src/test/assembly/asm/avr-types.rs
+++ b/src/test/assembly/asm/avr-types.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0
// assembly-output: emit-asm
// compile-flags: --target avr-unknown-gnu-atmega328
// needs-llvm-components: avr
diff --git a/src/test/assembly/asm/bpf-types.rs b/src/test/assembly/asm/bpf-types.rs
index 3428d93fb..f894644cc 100644
--- a/src/test/assembly/asm/bpf-types.rs
+++ b/src/test/assembly/asm/bpf-types.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0
// assembly-output: emit-asm
// compile-flags: --target bpfel-unknown-none -C target_feature=+alu32
// needs-llvm-components: bpf
diff --git a/src/test/assembly/asm/msp430-types.rs b/src/test/assembly/asm/msp430-types.rs
index 6cfb86e27..4fa2e8081 100644
--- a/src/test/assembly/asm/msp430-types.rs
+++ b/src/test/assembly/asm/msp430-types.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0
// assembly-output: emit-asm
// compile-flags: --target msp430-none-elf
// needs-llvm-components: msp430
diff --git a/src/test/assembly/asm/powerpc-types.rs b/src/test/assembly/asm/powerpc-types.rs
index b8859c07e..0ca890849 100644
--- a/src/test/assembly/asm/powerpc-types.rs
+++ b/src/test/assembly/asm/powerpc-types.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 12.0.1
// revisions: powerpc powerpc64
// assembly-output: emit-asm
//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
diff --git a/src/test/assembly/stack-protector/stack-protector-target-support.rs b/src/test/assembly/stack-protector/stack-protector-target-support.rs
index 5ba46d082..2fb62e93e 100644
--- a/src/test/assembly/stack-protector/stack-protector-target-support.rs
+++ b/src/test/assembly/stack-protector/stack-protector-target-support.rs
@@ -156,7 +156,6 @@
// [r74] needs-llvm-components: x86
// [r75] compile-flags:--target x86_64-fortanix-unknown-sgx
// [r75] needs-llvm-components: x86
-// [r75] min-llvm-version: 11.0.0
// [r76] compile-flags:--target x86_64-fuchsia
// [r76] needs-llvm-components: x86
// [r77] compile-flags:--target x86_64-linux-android
diff --git a/src/test/assembly/x86_64-floating-point-clamp.rs b/src/test/assembly/x86_64-floating-point-clamp.rs
new file mode 100644
index 000000000..0f3b465d0
--- /dev/null
+++ b/src/test/assembly/x86_64-floating-point-clamp.rs
@@ -0,0 +1,25 @@
+// Floating-point clamp is designed to be implementable as max+min,
+// so check to make sure that's what it's actually emitting.
+
+// assembly-output: emit-asm
+// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
+// only-x86_64
+
+// CHECK-LABEL: clamp_demo:
+#[no_mangle]
+pub fn clamp_demo(a: f32, x: f32, y: f32) -> f32 {
+ // CHECK: maxss
+ // CHECK: minss
+ a.clamp(x, y)
+}
+
+// CHECK-LABEL: clamp12_demo:
+#[no_mangle]
+pub fn clamp12_demo(a: f32) -> f32 {
+ // CHECK: movss xmm1
+ // CHECK-NEXT: maxss xmm1, xmm0
+ // CHECK-NEXT: movss xmm0
+ // CHECK-NEXT: minss xmm0, xmm1
+ // CHECK: ret
+ a.clamp(1.0, 2.0)
+}
diff --git a/src/test/auxiliary/rust_test_helpers.c b/src/test/auxiliary/rust_test_helpers.c
index 92b7dd4b7..977ea487a 100644
--- a/src/test/auxiliary/rust_test_helpers.c
+++ b/src/test/auxiliary/rust_test_helpers.c
@@ -1,6 +1,7 @@
// Helper functions used only in tests
#include <stdint.h>
+#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
@@ -415,3 +416,14 @@ rust_dbg_unpack_option_u64u64(struct U8TaggedEnumOptionU64U64 o, uint64_t *a, ui
return 0;
}
}
+
+uint16_t issue_97463_leak_uninit_data(uint32_t a, uint32_t b, uint32_t c) {
+ struct bloc { uint16_t a; uint16_t b; uint16_t c; };
+ struct bloc *data = malloc(sizeof(struct bloc));
+
+ data->a = a & 0xFFFF;
+ data->b = b & 0xFFFF;
+ data->c = c & 0xFFFF;
+
+ return data->b; /* leak data */
+}
diff --git a/src/test/codegen/README.md b/src/test/codegen/README.md
index 00de55eea..8f2daaafc 100644
--- a/src/test/codegen/README.md
+++ b/src/test/codegen/README.md
@@ -1,2 +1,24 @@
The files here use the LLVM FileCheck framework, documented at
<https://llvm.org/docs/CommandGuide/FileCheck.html>.
+
+One extension worth noting is the use of revisions as custom prefixes for
+FileCheck. If your codegen test has different behavior based on the chosen
+target or different compiler flags that you want to exercise, you can use a
+revisions annotation, like so:
+
+```rust
+// revisions: aaa bbb
+// [bbb] compile-flags: --flags-for-bbb
+```
+
+After specifying those variations, you can write different expected, or
+explicitly *unexpected* output by using `<prefix>-SAME:` and `<prefix>-NOT:`,
+like so:
+
+```rust
+// CHECK: expected code
+// aaa-SAME: emitted-only-for-aaa
+// aaa-NOT: emitted-only-for-bbb
+// bbb-NOT: emitted-only-for-aaa
+// bbb-SAME: emitted-only-for-bbb
+```
diff --git a/src/test/codegen/abi-repr-ext.rs b/src/test/codegen/abi-repr-ext.rs
index 2b34eaf94..23ade3c72 100644
--- a/src/test/codegen/abi-repr-ext.rs
+++ b/src/test/codegen/abi-repr-ext.rs
@@ -1,6 +1,32 @@
// compile-flags: -O
-#![crate_type="lib"]
+// revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv
+
+//[x86_64] compile-flags: --target x86_64-unknown-uefi
+//[x86_64] needs-llvm-components: x86
+//[i686] compile-flags: --target i686-unknown-linux-musl
+//[i686] needs-llvm-components: x86
+//[aarch64-windows] compile-flags: --target aarch64-pc-windows-msvc
+//[aarch64-windows] needs-llvm-components: aarch64
+//[aarch64-linux] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64-linux] needs-llvm-components: aarch64
+//[aarch64-apple] compile-flags: --target aarch64-apple-darwin
+//[aarch64-apple] needs-llvm-components: aarch64
+//[arm] compile-flags: --target armv7r-none-eabi
+//[arm] needs-llvm-components: arm
+//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
+//[riscv] needs-llvm-components: riscv
+
+// See bottom of file for a corresponding C source file that is meant to yield
+// equivalent declarations.
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
#[repr(i8)]
pub enum Type {
@@ -8,7 +34,23 @@ pub enum Type {
Type2 = 1
}
-// CHECK: define{{( dso_local)?}} noundef signext i8 @test()
+// To accommodate rust#97800, one might consider writing the below as:
+//
+// `define{{( dso_local)?}} noundef{{( signext)?}} i8 @test()`
+//
+// but based on rust#80556, it seems important to actually check for the
+// presence of the `signext` for those targets where we expect it.
+
+// CHECK: define{{( dso_local)?}} noundef
+// x86_64-SAME: signext
+// aarch64-apple-SAME: signext
+// aarch64-windows-NOT: signext
+// aarch64-linux-NOT: signext
+// arm-SAME: signext
+// riscv-SAME: signext
+// CHECK-SAME: i8 @test()
+
+
#[no_mangle]
pub extern "C" fn test() -> Type {
Type::Type1
diff --git a/src/test/codegen/asm-may_unwind.rs b/src/test/codegen/asm-may_unwind.rs
index bf4202764..c97933035 100644
--- a/src/test/codegen/asm-may_unwind.rs
+++ b/src/test/codegen/asm-may_unwind.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0.0
// compile-flags: -O
// only-x86_64
diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs
index efb345fa9..909cd0062 100644
--- a/src/test/codegen/async-fn-debug-awaitee-field.rs
+++ b/src/test/codegen/async-fn-debug-awaitee-field.rs
@@ -12,11 +12,11 @@ async fn async_fn_test() {
}
// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
-// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
fn main() {
let _fn = async_fn_test();
diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs
index 8995605e3..73c652c9d 100644
--- a/src/test/codegen/async-fn-debug-msvc.rs
+++ b/src/test/codegen/async-fn-debug-msvc.rs
@@ -16,7 +16,7 @@ async fn async_fn_test() {
// FIXME: No way to reliably check the filename.
-// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
+// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
@@ -36,16 +36,17 @@ async fn async_fn_test() {
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 14,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], file: !2, baseType: [[VARIANT:![0-9]*]],
// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
-// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
fn main() {
diff --git a/src/test/codegen/atomic-operations-llvm-12.rs b/src/test/codegen/atomic-operations-llvm-12.rs
deleted file mode 100644
index bd4c63dcf..000000000
--- a/src/test/codegen/atomic-operations-llvm-12.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-// Code generation of atomic operations for LLVM 12
-// ignore-llvm-version: 13 - 99
-// compile-flags: -O
-#![crate_type = "lib"]
-
-use std::sync::atomic::{AtomicI32, Ordering::*};
-
-// CHECK-LABEL: @compare_exchange
-#[no_mangle]
-pub fn compare_exchange(a: &AtomicI32) {
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 10 monotonic monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 11 acquire acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 12 seq_cst seq_cst
- let _ = a.compare_exchange(0, 10, Relaxed, Relaxed);
- let _ = a.compare_exchange(0, 11, Relaxed, Acquire);
- let _ = a.compare_exchange(0, 12, Relaxed, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 20 release monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 21 acq_rel acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 22 seq_cst seq_cst
- let _ = a.compare_exchange(0, 20, Release, Relaxed);
- let _ = a.compare_exchange(0, 21, Release, Acquire);
- let _ = a.compare_exchange(0, 22, Release, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 30 acquire monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 31 acquire acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 32 seq_cst seq_cst
- let _ = a.compare_exchange(0, 30, Acquire, Relaxed);
- let _ = a.compare_exchange(0, 31, Acquire, Acquire);
- let _ = a.compare_exchange(0, 32, Acquire, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 40 acq_rel monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 41 acq_rel acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 42 seq_cst seq_cst
- let _ = a.compare_exchange(0, 40, AcqRel, Relaxed);
- let _ = a.compare_exchange(0, 41, AcqRel, Acquire);
- let _ = a.compare_exchange(0, 42, AcqRel, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 50 seq_cst monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 51 seq_cst acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 52 seq_cst seq_cst
- let _ = a.compare_exchange(0, 50, SeqCst, Relaxed);
- let _ = a.compare_exchange(0, 51, SeqCst, Acquire);
- let _ = a.compare_exchange(0, 52, SeqCst, SeqCst);
-}
-
-// CHECK-LABEL: @compare_exchange_weak
-#[no_mangle]
-pub fn compare_exchange_weak(w: &AtomicI32) {
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 10 monotonic monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 11 acquire acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 12 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 10, Relaxed, Relaxed);
- let _ = w.compare_exchange_weak(1, 11, Relaxed, Acquire);
- let _ = w.compare_exchange_weak(1, 12, Relaxed, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 20 release monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 21 acq_rel acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 22 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 20, Release, Relaxed);
- let _ = w.compare_exchange_weak(1, 21, Release, Acquire);
- let _ = w.compare_exchange_weak(1, 22, Release, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 30 acquire monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 31 acquire acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 32 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 30, Acquire, Relaxed);
- let _ = w.compare_exchange_weak(1, 31, Acquire, Acquire);
- let _ = w.compare_exchange_weak(1, 32, Acquire, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 40 acq_rel monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 41 acq_rel acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 42 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 40, AcqRel, Relaxed);
- let _ = w.compare_exchange_weak(1, 41, AcqRel, Acquire);
- let _ = w.compare_exchange_weak(1, 42, AcqRel, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 50 seq_cst monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 51 seq_cst acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 52 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 50, SeqCst, Relaxed);
- let _ = w.compare_exchange_weak(1, 51, SeqCst, Acquire);
- let _ = w.compare_exchange_weak(1, 52, SeqCst, SeqCst);
-}
diff --git a/src/test/codegen/atomic-operations.rs b/src/test/codegen/atomic-operations.rs
index 771cf5872..d2bc618df 100644
--- a/src/test/codegen/atomic-operations.rs
+++ b/src/test/codegen/atomic-operations.rs
@@ -1,5 +1,4 @@
// Code generation of atomic operations.
-// min-llvm-version: 13.0
// compile-flags: -O
#![crate_type = "lib"]
diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs
index 530164edd..a038dfe76 100644
--- a/src/test/codegen/avr/avr-func-addrspace.rs
+++ b/src/test/codegen/avr/avr-func-addrspace.rs
@@ -77,7 +77,7 @@ fn update_bar_value() {
}
}
-// CHECK: define void @test(){{.+}}addrspace(1)
+// CHECK: define dso_local void @test(){{.+}}addrspace(1)
#[no_mangle]
pub extern "C" fn test() {
let mut buf = 7;
diff --git a/src/test/codegen/branch-protection.rs b/src/test/codegen/branch-protection.rs
index b23073778..994c71b26 100644
--- a/src/test/codegen/branch-protection.rs
+++ b/src/test/codegen/branch-protection.rs
@@ -1,7 +1,6 @@
// Test that the correct module flags are emitted with different branch protection flags.
// revisions: BTI PACRET LEAF BKEY NONE
-// min-llvm-version: 12.0.0
// needs-llvm-components: aarch64
// [BTI] compile-flags: -Z branch-protection=bti
// [PACRET] compile-flags: -Z branch-protection=pac-ret
diff --git a/src/test/codegen/debug-vtable.rs b/src/test/codegen/debug-vtable.rs
index b9cb4f93d..bdd312878 100644
--- a/src/test/codegen/debug-vtable.rs
+++ b/src/test/codegen/debug-vtable.rs
@@ -46,7 +46,7 @@
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::bar::{closure_env#0} as core::ops::function::FnOnce<(core::option::Option<&dyn core::ops::function::Fn<(), Output=()>>)>>::{vtable}"
-// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$"
+// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum2$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > > > > > >::vtable$"
// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::generic_closure::{closure_env#0}<bool> as core::ops::function::FnOnce<()>>::{vtable}"
// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::generic_closure::closure_env$0<bool>, core::ops::function::FnOnce<tuple$<> > >::vtable$
diff --git a/src/test/codegen/external-no-mangle-statics.rs b/src/test/codegen/external-no-mangle-statics.rs
index 6274434cd..c6ecb7aa9 100644
--- a/src/test/codegen/external-no-mangle-statics.rs
+++ b/src/test/codegen/external-no-mangle-statics.rs
@@ -1,12 +1,11 @@
// revisions: lib staticlib
// ignore-emscripten default visibility is hidden
// compile-flags: -O
+// [lib] compile-flags: --crate-type lib
+// [staticlib] compile-flags: --crate-type staticlib
// `#[no_mangle]`d static variables always have external linkage, i.e., no `internal` in their
// definitions
-#![cfg_attr(lib, crate_type = "lib")]
-#![cfg_attr(staticlib, crate_type = "staticlib")]
-
// CHECK: @A = local_unnamed_addr constant
#[no_mangle]
static A: u8 = 0;
diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs
index 033da80be..9d70ccdef 100644
--- a/src/test/codegen/generator-debug-msvc.rs
+++ b/src/test/codegen/generator-debug-msvc.rs
@@ -20,18 +20,18 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// FIXME: No way to reliably check the filename.
-// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<generator_debug_msvc::generator_test::generator_env$0>"
+// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<generator_debug_msvc::generator_test::generator_env$0>"
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant1", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant2", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant3", scope: [[GEN]],
@@ -40,16 +40,18 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 17,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
+// CHECK: [[VARIANT_WRAPPER]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Variant4", scope: [[GEN]],
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], {{.*}}, baseType: [[VARIANT:![0-9]*]],
// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
-// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
fn main() {
diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs
index 9c9f5518b..3ec860f2c 100644
--- a/src/test/codegen/generator-debug.rs
+++ b/src/test/codegen/generator-debug.rs
@@ -33,11 +33,11 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
diff --git a/src/test/codegen/instrument-coverage.rs b/src/test/codegen/instrument-coverage.rs
new file mode 100644
index 000000000..78f8875a2
--- /dev/null
+++ b/src/test/codegen/instrument-coverage.rs
@@ -0,0 +1,17 @@
+// Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR.
+
+// needs-profiler-support
+// compile-flags: -Cinstrument-coverage
+
+// CHECK: @__llvm_profile_filename = {{.*}}"default_%m_%p.profraw\00"{{.*}}
+
+#![crate_type="lib"]
+
+#[inline(never)]
+fn some_function() {
+
+}
+
+pub fn some_other_function() {
+ some_function();
+}
diff --git a/src/test/codegen/intrinsics/mask.rs b/src/test/codegen/intrinsics/mask.rs
new file mode 100644
index 000000000..2e984db1b
--- /dev/null
+++ b/src/test/codegen/intrinsics/mask.rs
@@ -0,0 +1,11 @@
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+// CHECK-LABEL: @mask_ptr
+// CHECK-SAME: [[WORD:i[0-9]+]] %mask
+#[no_mangle]
+pub fn mask_ptr(ptr: *const u16, mask: usize) -> *const u16 {
+ // CHECK: call
+ // CHECK-SAME: @llvm.ptrmask.{{p0|p0i8}}.[[WORD]]({{ptr|i8\*}} {{%ptr|%0}}, [[WORD]] %mask)
+ core::intrinsics::ptr_mask(ptr, mask)
+}
diff --git a/src/test/codegen/issue-34634.rs b/src/test/codegen/issue-34634.rs
index 6c18adbcb..f53fa240c 100644
--- a/src/test/codegen/issue-34634.rs
+++ b/src/test/codegen/issue-34634.rs
@@ -1,5 +1,5 @@
// Test that `wrapping_div` only checks divisor once.
-// This test checks that there is only a single compare agains -1 and -1 is not present as a
+// This test checks that there is only a single compare against -1 and -1 is not present as a
// switch case (the second check present until rustc 1.12).
// This test also verifies that a single panic call is generated (for the division by zero case).
diff --git a/src/test/codegen/issue-85872-multiple-reverse.rs b/src/test/codegen/issue-85872-multiple-reverse.rs
new file mode 100644
index 000000000..591a1aca7
--- /dev/null
+++ b/src/test/codegen/issue-85872-multiple-reverse.rs
@@ -0,0 +1,20 @@
+// min-llvm-version: 15.0.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn u16_be_to_arch(mut data: [u8; 2]) -> [u8; 2] {
+ // CHECK-LABEL: @u16_be_to_arch
+ // CHECK: @llvm.bswap.i16
+ data.reverse();
+ data
+}
+
+#[no_mangle]
+pub fn u32_be_to_arch(mut data: [u8; 4]) -> [u8; 4] {
+ // CHECK-LABEL: @u32_be_to_arch
+ // CHECK: @llvm.bswap.i32
+ data.reverse();
+ data
+}
diff --git a/src/test/codegen/issue-96274.rs b/src/test/codegen/issue-96274.rs
new file mode 100644
index 000000000..28bfcce0d
--- /dev/null
+++ b/src/test/codegen/issue-96274.rs
@@ -0,0 +1,17 @@
+// min-llvm-version: 15.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+#![feature(inline_const)]
+
+use std::mem::MaybeUninit;
+
+pub fn maybe_uninit() -> [MaybeUninit<u8>; 3000] {
+ // CHECK-NOT: memset
+ [MaybeUninit::uninit(); 3000]
+}
+
+pub fn maybe_uninit_const<T>() -> [MaybeUninit<T>; 8192] {
+ // CHECK-NOT: memset
+ [const { MaybeUninit::uninit() }; 8192]
+}
diff --git a/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs b/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs
new file mode 100644
index 000000000..7da29cd79
--- /dev/null
+++ b/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs
@@ -0,0 +1,19 @@
+// min-llvm-version: 15.0.0
+// ignore-debug: The debug assertions get in the way
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// There should be no calls to panic / len_mismatch_fail.
+
+#[no_mangle]
+pub fn test(a: &mut [u8], offset: usize, bytes: &[u8]) {
+ // CHECK-LABEL: @test(
+ // CHECK-NOT: call
+ // CHECK: call void @llvm.memcpy
+ // CHECK-NOT: call
+ // CHECK: }
+ if let Some(dst) = a.get_mut(offset..offset + bytes.len()) {
+ dst.copy_from_slice(bytes);
+ }
+}
diff --git a/src/test/codegen/layout-size-checks.rs b/src/test/codegen/layout-size-checks.rs
new file mode 100644
index 000000000..d067cc10a
--- /dev/null
+++ b/src/test/codegen/layout-size-checks.rs
@@ -0,0 +1,31 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+
+use std::alloc::Layout;
+
+type RGB48 = [u16; 3];
+
+// CHECK-LABEL: @layout_array_rgb48
+#[no_mangle]
+pub fn layout_array_rgb48(n: usize) -> Layout {
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: icmp ugt i64 %n, 1537228672809129301
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: mul nuw nsw i64 %n, 6
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ Layout::array::<RGB48>(n).unwrap()
+}
+
+// CHECK-LABEL: @layout_array_i32
+#[no_mangle]
+pub fn layout_array_i32(n: usize) -> Layout {
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: icmp ugt i64 %n, 2305843009213693951
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: shl nuw nsw i64 %n, 2
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ Layout::array::<i32>(n).unwrap()
+}
diff --git a/src/test/codegen/mem-replace-direct-memcpy.rs b/src/test/codegen/mem-replace-direct-memcpy.rs
index 8095d309f..b41ef538d 100644
--- a/src/test/codegen/mem-replace-direct-memcpy.rs
+++ b/src/test/codegen/mem-replace-direct-memcpy.rs
@@ -1,15 +1,3 @@
-// ignore-test
-
-// WHY IS THIS TEST BEING IGNORED:
-//
-// This test depends on characteristics of how the stdlib was compiled,
-// namely that sufficient inlining occurred to ensure that the call to
-// `std::mem::replace` boils down to just two calls of `llvm.memcpy`.
-//
-// But the MIR inlining policy is in flux as of 1.64-beta, and the intermittent
-// breakage of this test that results is causing problems for people trying to
-// do development.
-
// This test ensures that `mem::replace::<T>` only ever calls `@llvm.memcpy`
// with `size_of::<T>()` as the size, and never goes through any wrapper that
// may e.g. multiply `size_of::<T>()` with a variable "count" (which is only
diff --git a/src/test/codegen/merge-functions.rs b/src/test/codegen/merge-functions.rs
index 5eefc0f98..8e8fe5c96 100644
--- a/src/test/codegen/merge-functions.rs
+++ b/src/test/codegen/merge-functions.rs
@@ -1,7 +1,10 @@
-// compile-flags: -O
+// min-llvm-version: 14.0
+// revisions: O Os
+//[Os] compile-flags: -Copt-level=s
+//[O] compile-flags: -O
#![crate_type = "lib"]
-// CHECK: @func2 = {{.*}}alias{{.*}}@func1
+// CHECK: @func{{2|1}} = {{.*}}alias{{.*}}@func{{1|2}}
#[no_mangle]
pub fn func1(c: char) -> bool {
diff --git a/src/test/codegen/mir-inlined-line-numbers.rs b/src/test/codegen/mir-inlined-line-numbers.rs
new file mode 100644
index 000000000..19d83f0ee
--- /dev/null
+++ b/src/test/codegen/mir-inlined-line-numbers.rs
@@ -0,0 +1,25 @@
+// compile-flags: -O -g
+
+#![crate_type = "lib"]
+
+#[inline(always)]
+fn foo() {
+ bar();
+}
+
+#[inline(never)]
+#[no_mangle]
+fn bar() {
+ panic!();
+}
+
+#[no_mangle]
+pub fn example() {
+ foo();
+}
+
+// CHECK-LABEL: @example
+// CHECK: tail call void @bar(), !dbg [[DBG_ID:![0-9]+]]
+// CHECK: [[DBG_ID]] = !DILocation(line: 7,
+// CHECK-SAME: inlinedAt: [[INLINE_ID:![0-9]+]])
+// CHECK: [[INLINE_ID]] = !DILocation(line: 18,
diff --git a/src/test/codegen/pic-relocation-model.rs b/src/test/codegen/pic-relocation-model.rs
index 6e1d5a6c3..602a08067 100644
--- a/src/test/codegen/pic-relocation-model.rs
+++ b/src/test/codegen/pic-relocation-model.rs
@@ -10,7 +10,10 @@ pub fn call_foreign_fn() -> u8 {
}
}
-// CHECK: declare zeroext i8 @foreign_fn()
+// (Allow but do not require `zeroext` here, because it is not worth effort to
+// spell out which targets have it and which ones do not; see rust#97800.)
+
+// CHECK: declare{{( zeroext)?}} i8 @foreign_fn()
extern "C" {fn foreign_fn() -> u8;}
-// CHECK: !{i32 7, !"PIC Level", i32 2}
+// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2}
diff --git a/src/test/codegen/pie-relocation-model.rs b/src/test/codegen/pie-relocation-model.rs
index a843202a9..ec44edc06 100644
--- a/src/test/codegen/pie-relocation-model.rs
+++ b/src/test/codegen/pie-relocation-model.rs
@@ -18,5 +18,5 @@ pub fn call_foreign_fn() -> u8 {
// CHECK: declare zeroext i8 @foreign_fn()
extern "C" {fn foreign_fn() -> u8;}
-// CHECK: !{i32 7, !"PIC Level", i32 2}
+// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2}
// CHECK: !{i32 7, !"PIE Level", i32 2}
diff --git a/src/test/codegen/some-abis-do-extend-params-to-32-bits.rs b/src/test/codegen/some-abis-do-extend-params-to-32-bits.rs
new file mode 100644
index 000000000..7fc34af3d
--- /dev/null
+++ b/src/test/codegen/some-abis-do-extend-params-to-32-bits.rs
@@ -0,0 +1,204 @@
+// compile-flags: -Cno-prepopulate-passes
+
+// revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv
+
+//[x86_64] compile-flags: --target x86_64-unknown-uefi
+//[x86_64] needs-llvm-components: x86
+//[i686] compile-flags: --target i686-unknown-linux-musl
+//[i686] needs-llvm-components: x86
+//[aarch64-windows] compile-flags: --target aarch64-pc-windows-msvc
+//[aarch64-windows] needs-llvm-components: aarch64
+//[aarch64-linux] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64-linux] needs-llvm-components: aarch64
+//[aarch64-apple] compile-flags: --target aarch64-apple-darwin
+//[aarch64-apple] needs-llvm-components: aarch64
+//[arm] compile-flags: --target armv7r-none-eabi
+//[arm] needs-llvm-components: arm
+//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
+//[riscv] needs-llvm-components: riscv
+
+// See bottom of file for a corresponding C source file that is meant to yield
+// equivalent declarations.
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
+
+// The patterns in this file are written in the style of a table to make the
+// uniformities and distinctions more apparent.
+//
+// ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING
+// ============================== =======================
+// x86_64: void @c_arg_u8(i8 zeroext %_a)
+// i686: void @c_arg_u8(i8 zeroext %_a)
+// aarch64-apple: void @c_arg_u8(i8 zeroext %_a)
+// aarch64-windows: void @c_arg_u8(i8 %_a)
+// aarch64-linux: void @c_arg_u8(i8 %_a)
+// arm: void @c_arg_u8(i8 zeroext %_a)
+// riscv: void @c_arg_u8(i8 zeroext %_a)
+#[no_mangle] pub extern "C" fn c_arg_u8(_a: u8) { }
+
+// x86_64: void @c_arg_u16(i16 zeroext %_a)
+// i686: void @c_arg_u16(i16 zeroext %_a)
+// aarch64-apple: void @c_arg_u16(i16 zeroext %_a)
+// aarch64-windows: void @c_arg_u16(i16 %_a)
+// aarch64-linux: void @c_arg_u16(i16 %_a)
+// arm: void @c_arg_u16(i16 zeroext %_a)
+// riscv: void @c_arg_u16(i16 zeroext %_a)
+#[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) { }
+
+// x86_64: void @c_arg_u32(i32 %_a)
+// i686: void @c_arg_u32(i32 %_a)
+// aarch64-apple: void @c_arg_u32(i32 %_a)
+// aarch64-windows: void @c_arg_u32(i32 %_a)
+// aarch64-linux: void @c_arg_u32(i32 %_a)
+// arm: void @c_arg_u32(i32 %_a)
+// riscv: void @c_arg_u32(i32 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) { }
+
+// x86_64: void @c_arg_u64(i64 %_a)
+// i686: void @c_arg_u64(i64 %_a)
+// aarch64-apple: void @c_arg_u64(i64 %_a)
+// aarch64-windows: void @c_arg_u64(i64 %_a)
+// aarch64-linux: void @c_arg_u64(i64 %_a)
+// arm: void @c_arg_u64(i64 %_a)
+// riscv: void @c_arg_u64(i64 %_a)
+#[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) { }
+
+// x86_64: void @c_arg_i8(i8 signext %_a)
+// i686: void @c_arg_i8(i8 signext %_a)
+// aarch64-apple: void @c_arg_i8(i8 signext %_a)
+// aarch64-windows: void @c_arg_i8(i8 %_a)
+// aarch64-linux: void @c_arg_i8(i8 %_a)
+// arm: void @c_arg_i8(i8 signext %_a)
+// riscv: void @c_arg_i8(i8 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_i8(_a: i8) { }
+
+// x86_64: void @c_arg_i16(i16 signext %_a)
+// i686: void @c_arg_i16(i16 signext %_a)
+// aarch64-apple: void @c_arg_i16(i16 signext %_a)
+// aarch64-windows: void @c_arg_i16(i16 %_a)
+// aarch64-linux: void @c_arg_i16(i16 %_a)
+// arm: void @c_arg_i16(i16 signext %_a)
+// riscv: void @c_arg_i16(i16 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) { }
+
+// x86_64: void @c_arg_i32(i32 %_a)
+// i686: void @c_arg_i32(i32 %_a)
+// aarch64-apple: void @c_arg_i32(i32 %_a)
+// aarch64-windows: void @c_arg_i32(i32 %_a)
+// aarch64-linux: void @c_arg_i32(i32 %_a)
+// arm: void @c_arg_i32(i32 %_a)
+// riscv: void @c_arg_i32(i32 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) { }
+
+// x86_64: void @c_arg_i64(i64 %_a)
+// i686: void @c_arg_i64(i64 %_a)
+// aarch64-apple: void @c_arg_i64(i64 %_a)
+// aarch64-windows: void @c_arg_i64(i64 %_a)
+// aarch64-linux: void @c_arg_i64(i64 %_a)
+// arm: void @c_arg_i64(i64 %_a)
+// riscv: void @c_arg_i64(i64 %_a)
+#[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) { }
+
+// x86_64: zeroext i8 @c_ret_u8()
+// i686: zeroext i8 @c_ret_u8()
+// aarch64-apple: zeroext i8 @c_ret_u8()
+// aarch64-windows: i8 @c_ret_u8()
+// aarch64-linux: i8 @c_ret_u8()
+// arm: zeroext i8 @c_ret_u8()
+// riscv: zeroext i8 @c_ret_u8()
+#[no_mangle] pub extern "C" fn c_ret_u8() -> u8 { 0 }
+
+// x86_64: zeroext i16 @c_ret_u16()
+// i686: zeroext i16 @c_ret_u16()
+// aarch64-apple: zeroext i16 @c_ret_u16()
+// aarch64-windows: i16 @c_ret_u16()
+// aarch64-linux: i16 @c_ret_u16()
+// arm: zeroext i16 @c_ret_u16()
+// riscv: zeroext i16 @c_ret_u16()
+#[no_mangle] pub extern "C" fn c_ret_u16() -> u16 { 0 }
+
+// x86_64: i32 @c_ret_u32()
+// i686: i32 @c_ret_u32()
+// aarch64-apple: i32 @c_ret_u32()
+// aarch64-windows: i32 @c_ret_u32()
+// aarch64-linux: i32 @c_ret_u32()
+// arm: i32 @c_ret_u32()
+// riscv: signext i32 @c_ret_u32()
+#[no_mangle] pub extern "C" fn c_ret_u32() -> u32 { 0 }
+
+// x86_64: i64 @c_ret_u64()
+// i686: i64 @c_ret_u64()
+// aarch64-apple: i64 @c_ret_u64()
+// aarch64-windows: i64 @c_ret_u64()
+// aarch64-linux: i64 @c_ret_u64()
+// arm: i64 @c_ret_u64()
+// riscv: i64 @c_ret_u64()
+#[no_mangle] pub extern "C" fn c_ret_u64() -> u64 { 0 }
+
+// x86_64: signext i8 @c_ret_i8()
+// i686: signext i8 @c_ret_i8()
+// aarch64-apple: signext i8 @c_ret_i8()
+// aarch64-windows: i8 @c_ret_i8()
+// aarch64-linux: i8 @c_ret_i8()
+// arm: signext i8 @c_ret_i8()
+// riscv: signext i8 @c_ret_i8()
+#[no_mangle] pub extern "C" fn c_ret_i8() -> i8 { 0 }
+
+// x86_64: signext i16 @c_ret_i16()
+// i686: signext i16 @c_ret_i16()
+// aarch64-apple: signext i16 @c_ret_i16()
+// aarch64-windows: i16 @c_ret_i16()
+// aarch64-linux: i16 @c_ret_i16()
+// arm: signext i16 @c_ret_i16()
+// riscv: signext i16 @c_ret_i16()
+#[no_mangle] pub extern "C" fn c_ret_i16() -> i16 { 0 }
+
+// x86_64: i32 @c_ret_i32()
+// i686: i32 @c_ret_i32()
+// aarch64-apple: i32 @c_ret_i32()
+// aarch64-windows: i32 @c_ret_i32()
+// aarch64-linux: i32 @c_ret_i32()
+// arm: i32 @c_ret_i32()
+// riscv: signext i32 @c_ret_i32()
+#[no_mangle] pub extern "C" fn c_ret_i32() -> i32 { 0 }
+
+// x86_64: i64 @c_ret_i64()
+// i686: i64 @c_ret_i64()
+// aarch64-apple: i64 @c_ret_i64()
+// aarch64-windows: i64 @c_ret_i64()
+// aarch64-linux: i64 @c_ret_i64()
+// arm: i64 @c_ret_i64()
+// riscv: i64 @c_ret_i64()
+#[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0 }
+
+const C_SOURCE_FILE: &'static str = r##"
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+void c_arg_u8(uint8_t _a) { }
+void c_arg_u16(uint16_t _a) { }
+void c_arg_u32(uint32_t _a) { }
+void c_arg_u64(uint64_t _a) { }
+
+void c_arg_i8(int8_t _a) { }
+void c_arg_i16(int16_t _a) { }
+void c_arg_i32(int32_t _a) { }
+void c_arg_i64(int64_t _a) { }
+
+uint8_t c_ret_u8() { return 0; }
+uint16_t c_ret_u16() { return 0; }
+uint32_t c_ret_u32() { return 0; }
+uint64_t c_ret_u64() { return 0; }
+
+int8_t c_ret_i8() { return 0; }
+int16_t c_ret_i16() { return 0; }
+int32_t c_ret_i32() { return 0; }
+int64_t c_ret_i64() { return 0; }
+"##;
diff --git a/src/test/codegen/try_question_mark_nop.rs b/src/test/codegen/try_question_mark_nop.rs
new file mode 100644
index 000000000..d23938776
--- /dev/null
+++ b/src/test/codegen/try_question_mark_nop.rs
@@ -0,0 +1,54 @@
+// min-llvm-version: 15.0
+// compile-flags: -O -Z merge-functions=disabled --edition=2021
+// only-x86_64
+
+#![crate_type = "lib"]
+#![feature(try_blocks)]
+
+// These are now NOPs in LLVM 15, presumably thanks to nikic's change mentioned in
+// <https://github.com/rust-lang/rust/issues/85133#issuecomment-1072168354>.
+// Unfortunately, as of 2022-08-17 they're not yet nops for `u64`s nor `Option`.
+
+use std::ops::ControlFlow::{self, Continue, Break};
+
+// CHECK-LABEL: @result_nop_match_32
+#[no_mangle]
+pub fn result_nop_match_32(x: Result<i32, u32>) -> Result<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ match x {
+ Ok(x) => Ok(x),
+ Err(x) => Err(x),
+ }
+}
+
+// CHECK-LABEL: @result_nop_traits_32
+#[no_mangle]
+pub fn result_nop_traits_32(x: Result<i32, u32>) -> Result<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ try {
+ x?
+ }
+}
+
+// CHECK-LABEL: @control_flow_nop_match_32
+#[no_mangle]
+pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ match x {
+ Continue(x) => Continue(x),
+ Break(x) => Break(x),
+ }
+}
+
+// CHECK-LABEL: @control_flow_nop_traits_32
+#[no_mangle]
+pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ try {
+ x?
+ }
+}
diff --git a/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs b/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
index 1fe048068..c092e28a0 100644
--- a/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `aapcs` and
+// Test that `nounwind` attributes are correctly applied to exported `aapcs` and
// `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
index e817d5715..8447bbeb1 100644
--- a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
+++ b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
@@ -1,6 +1,6 @@
// compile-flags: -C panic=abort
-// Test that `nounwind` atributes are also applied to extern `C-unwind` Rust functions
+// Test that `nounwind` attributes are also applied to extern `C-unwind` Rust functions
// when the code is compiled with `panic=abort`.
#![crate_type = "lib"]
diff --git a/src/test/codegen/unwind-abis/c-unwind-abi.rs b/src/test/codegen/unwind-abis/c-unwind-abi.rs
index f15765367..e258dbcac 100644
--- a/src/test/codegen/unwind-abis/c-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/c-unwind-abi.rs
@@ -1,6 +1,6 @@
// compile-flags: -C opt-level=0
-// Test that `nounwind` atributes are correctly applied to exported `C` and `C-unwind` extern
+// Test that `nounwind` attributes are correctly applied to exported `C` and `C-unwind` extern
// functions. `C-unwind` functions MUST NOT have this attribute. We disable optimizations above
// to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs b/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
index 52e0d2d6e..19a722883 100644
--- a/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
@@ -1,6 +1,6 @@
// compile-flags: -C opt-level=0
-// Test that `nounwind` atributes are correctly applied to exported `cdecl` and
+// Test that `nounwind` attributes are correctly applied to exported `cdecl` and
// `cdecl-unwind` extern functions. `cdecl-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs b/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
index ed23235eb..b74099a5d 100644
--- a/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `fastcall` and
+// Test that `nounwind` attributes are correctly applied to exported `fastcall` and
// `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs
index 9a4b3d3b4..106d593b2 100644
--- a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs
+++ b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs
@@ -3,7 +3,7 @@
#![crate_type = "lib"]
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
// CHECK: Function Attrs:{{.*}}nounwind
// CHECK-NEXT: @foo
diff --git a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
index 2783c83d3..c1c5bbdda 100644
--- a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
+++ b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
@@ -3,7 +3,7 @@
#![crate_type = "lib"]
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
extern "C" {
fn bar();
diff --git a/src/test/codegen/unwind-abis/nounwind.rs b/src/test/codegen/unwind-abis/nounwind.rs
index cfc140361..c46d71733 100644
--- a/src/test/codegen/unwind-abis/nounwind.rs
+++ b/src/test/codegen/unwind-abis/nounwind.rs
@@ -4,7 +4,7 @@
#![crate_type = "lib"]
#![feature(c_unwind)]
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
// CHECK: Function Attrs:{{.*}}nounwind
// CHECK-NEXT: @foo
diff --git a/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs b/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
index f1dff27ad..8eff0719f 100644
--- a/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `stdcall` and `stdcall-unwind`
+// Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind`
// extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable
// optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/system-unwind-abi.rs b/src/test/codegen/unwind-abis/system-unwind-abi.rs
index c4d513283..2591c1d48 100644
--- a/src/test/codegen/unwind-abis/system-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/system-unwind-abi.rs
@@ -1,6 +1,6 @@
// compile-flags: -C opt-level=0
-// Test that `nounwind` atributes are correctly applied to exported `system` and `system-unwind`
+// Test that `nounwind` attributes are correctly applied to exported `system` and `system-unwind`
// extern functions. `system-unwind` functions MUST NOT have this attribute. We disable
// optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs b/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
index a38736f2a..694fde17c 100644
--- a/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `sysv64` and
+// Test that `nounwind` attributes are correctly applied to exported `sysv64` and
// `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs b/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
index d2cf041b7..7e81367fc 100644
--- a/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `thiscall` and
+// Test that `nounwind` attributes are correctly applied to exported `thiscall` and
// `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs b/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
index 0fb9612a5..d7eca2a97 100644
--- a/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `vectorcall` and
+// Test that `nounwind` attributes are correctly applied to exported `vectorcall` and
// `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute.
// We disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/win64-unwind-abi.rs b/src/test/codegen/unwind-abis/win64-unwind-abi.rs
index 5d8482da6..6591348c3 100644
--- a/src/test/codegen/unwind-abis/win64-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/win64-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `win64` and
+// Test that `nounwind` attributes are correctly applied to exported `win64` and
// `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-extern-exports.rs b/src/test/codegen/unwind-extern-exports.rs
index c939235fb..6ac3c079f 100644
--- a/src/test/codegen/unwind-extern-exports.rs
+++ b/src/test/codegen/unwind-extern-exports.rs
@@ -5,7 +5,7 @@
#![feature(c_unwind)]
// Make sure these all do *not* get the attribute.
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
// CHECK-NOT: nounwind
// "C" ABI
diff --git a/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs b/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs
new file mode 100644
index 000000000..413f61201
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs
@@ -0,0 +1,61 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are not replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` is active, `-Zdebug-macros` is provided and `#[collapse_debuginfo]` not
+// being used.
+
+// compile-flags:-g -Zdebug-macros
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:continue
+
+fn one() {
+ println!("one");
+}
+fn two() {
+ println!("two");
+}
+fn three() {
+ println!("three");
+}
+fn four() {
+ println!("four");
+}
+
+macro_rules! outer {
+ ($b:block) => {
+ one(); // #loc1
+ inner!();
+ $b
+ };
+}
+
+macro_rules! inner {
+ () => {
+ two(); // #loc2
+ };
+}
+
+fn main() {
+ let ret = 0; // #break
+ outer!({
+ three(); // #loc3
+ four(); // #loc4
+ });
+ std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/collapse-debuginfo-no-attr.rs b/src/test/debuginfo/collapse-debuginfo-no-attr.rs
new file mode 100644
index 000000000..230c8795b
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-no-attr.rs
@@ -0,0 +1,60 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are not replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` feature is active and the attribute is not provided.
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:continue
+
+fn one() {
+ println!("one");
+}
+fn two() {
+ println!("two");
+}
+fn three() {
+ println!("three");
+}
+fn four() {
+ println!("four");
+}
+
+macro_rules! outer {
+ ($b:block) => {
+ one(); // #loc1
+ inner!();
+ $b
+ };
+}
+
+macro_rules! inner {
+ () => {
+ two(); // #loc2
+ };
+}
+
+fn main() {
+ let ret = 0; // #break
+ outer!({
+ three(); // #loc3
+ four(); // #loc4
+ });
+ std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs b/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs
new file mode 100644
index 000000000..183cf537e
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs
@@ -0,0 +1,63 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are not replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` is active and `-Zdebug-macros` is provided, despite `#[collapse_debuginfo]`
+// being used.
+
+// compile-flags:-g -Zdebug-macros
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:continue
+
+fn one() {
+ println!("one");
+}
+fn two() {
+ println!("two");
+}
+fn three() {
+ println!("three");
+}
+fn four() {
+ println!("four");
+}
+
+#[collapse_debuginfo]
+macro_rules! outer {
+ ($b:block) => {
+ one(); // #loc1
+ inner!();
+ $b
+ };
+}
+
+#[collapse_debuginfo]
+macro_rules! inner {
+ () => {
+ two(); // #loc2
+ };
+}
+
+fn main() {
+ let ret = 0; // #break
+ outer!({
+ three(); // #loc3
+ four(); // #loc4
+ });
+ std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/collapse-debuginfo-with-attr.rs b/src/test/debuginfo/collapse-debuginfo-with-attr.rs
new file mode 100644
index 000000000..34d03c18b
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-with-attr.rs
@@ -0,0 +1,59 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` feature is active and the attribute is provided.
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:continue
+
+fn one() {
+ println!("one");
+}
+fn two() {
+ println!("two");
+}
+fn three() {
+ println!("three");
+}
+fn four() {
+ println!("four");
+}
+
+#[collapse_debuginfo]
+macro_rules! outer {
+ ($b:block) => {
+ one();
+ inner!();
+ $b
+ };
+}
+
+#[collapse_debuginfo]
+macro_rules! inner {
+ () => {
+ two();
+ };
+}
+
+fn main() {
+ let ret = 0; // #break
+ outer!({ // #loc1
+ three(); // #loc2
+ four(); // #loc3
+ });
+ std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs
index d6d7e5b44..11c4ae2f6 100644
--- a/src/test/debuginfo/generator-objects.rs
+++ b/src/test/debuginfo/generator-objects.rs
@@ -41,31 +41,26 @@
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Unresumed [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Unresumed
+// cdb-check: b : Unresumed [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 5 [Type: int *]
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Suspend0 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Suspend0
+// cdb-check: b : Suspend0 [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] c : 6 [Type: int]
// cdb-check: [+0x[...]] d : 7 [Type: int]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 5 [Type: int *]
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Suspend1 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Suspend1
+// cdb-check: b : Suspend1 [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] c : 7 [Type: int]
// cdb-check: [+0x[...]] d : 8 [Type: int]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *]
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Returned [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [<Raw View>] [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Returned
+// cdb-check: b : Returned [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *]
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs
index a153a9a42..7f1be6f27 100644
--- a/src/test/debuginfo/msvc-pretty-enums.rs
+++ b/src/test/debuginfo/msvc-pretty-enums.rs
@@ -4,69 +4,141 @@
// cdb-command: g
// cdb-command: dx a
-// cdb-check:a : Some({...}) [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [variant] : Some
+// cdb-check:a : Some [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
// cdb-check: [+0x000] __0 : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-command: dx b
-// cdb-check:b : None [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [variant] : None
+// cdb-check:b : None [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
// cdb-command: dx c
-// cdb-check:c : Tag1 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [<Raw View>] [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [variant] : Tag1
+// cdb-check:c : Tag1 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
// cdb-command: dx d
-// cdb-check:d : Data({...}) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [<Raw View>] [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [variant] : Data
+// cdb-check:d : Data [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
// cdb-check: [+0x000] my_data : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-command: dx e
-// cdb-check:e : Tag2 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [<Raw View>] [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [variant] : Tag2
+// cdb-check:e : Tag2 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
// cdb-command: dx f
-// cdb-check:f : Some({...}) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [variant] : Some
+// cdb-check:f : Some [Type: enum2$<core::option::Option<ref$<u32> > >]
// cdb-check: [+0x000] __0 : 0x[...] : 0x1 [Type: unsigned int *]
// cdb-command: dx g
-// cdb-check:g : None [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [variant] : None
+// cdb-check:g : None [Type: enum2$<core::option::Option<ref$<u32> > >]
// cdb-command: dx h
-// cdb-check:h : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [variant] : Some
+// cdb-check:h : Some [Type: enum2$<core::option::Option<u32> >]
// cdb-check: [+0x004] __0 : 0xc [Type: unsigned int]
// cdb-command: dx i
-// cdb-check:i : None [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [variant] : None
+// cdb-check:i : None [Type: enum2$<core::option::Option<u32> >]
// cdb-command: dx j
// cdb-check:j : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-command: dx k
-// cdb-check:k : Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [variant] : Some
+// cdb-check:k : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
// cdb-check: [+0x000] __0 : "IAMA optional string!" [Type: alloc::string::String]
// cdb-command: dx l
-// cdb-check:l : Ok [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check: [<Raw View>] [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check: [variant] : Ok
+// cdb-check:l : Ok [Type: enum2$<core::result::Result<u32,enum2$<msvc_pretty_enums::Empty> > >]
// cdb-check: [+0x000] __0 : 0x2a [Type: unsigned int]
+// cdb-command: dx niche128_some
+// cdb-check: niche128_some : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
+// cdb-check: [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128]
+
+// cdb-command: dx niche128_none
+// cdb-check: niche128_none : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+
+// cdb-command: dx wrapping_niche128_untagged
+// cdb-check: wrapping_niche128_untagged : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check: [+0x[...]] __0 [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none1
+// cdb-check: wrapping_niche128_none1 : Y [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check: [+0x[...]] __0 [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none2
+// cdb-check: wrapping_niche128_none2 : Z [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check: [+0x[...]] __0 [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx direct_tag_128_a,d
+// cdb-check: direct_tag_128_a,d : A [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check: [+0x[...]] __0 : 42 [Type: unsigned int]
+
+// cdb-command: dx direct_tag_128_b,d
+// cdb-check: direct_tag_128_b,d : B [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check: [+0x[...]] __0 : 137 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_some,d
+// cdb-check: niche_w_fields_1_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check: [+0x[...]] __0 : 0x[...] : 77 [Type: unsigned char *]
+// cdb-check: [+0x[...]] __1 : 7 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_none,d
+// cdb-check: niche_w_fields_1_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check: [+0x[...]] __0 : 99 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_2_some,d
+// cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check: [+0x[...]] __0 : 800 [Type: core::num::nonzero::NonZeroU32]
+// cdb-check: [+0x[...]] __1 : 900 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_2_none,d
+// cdb-check: niche_w_fields_2_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check: [+0x[...]] __0 : 1000 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_3_some,d
+// cdb-check: niche_w_fields_3_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 137 [Type: unsigned char]
+// cdb-check: [+0x[...]] __1 : true [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche1,d
+// cdb-check: niche_w_fields_3_niche1,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 12 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche2,d
+// cdb-check: niche_w_fields_3_niche2,d : C [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : false [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche3,d
+// cdb-check: niche_w_fields_3_niche3,d : D [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 34 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche4,d
+// cdb-check: niche_w_fields_3_niche4,d : E [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 56 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche5,d
+// cdb-check: niche_w_fields_3_niche5,d : F [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+
+// cdb-command: dx -r3 niche_w_fields_std_result_ok,d
+// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: [+0x[...]] __0 [Type: alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>]
+// cdb-check: [+0x[...]] data_ptr : [...]
+// cdb-check: [+0x[...]] length : 3 [...]
+
+// cdb-command: dx -r3 niche_w_fields_std_result_err,d
+// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: [+0x[...]] __0 : 789 [Type: unsigned __int64]
+
+// cdb-command: dx -r2 arbitrary_discr1,d
+// cdb-check: arbitrary_discr1,d : Abc [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check: [+0x[...]] __0 : 1234 [Type: unsigned int]
+
+// cdb-command: dx -r2 arbitrary_discr2,d
+// cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check: [+0x[...]] __0 : 5678 [Type: unsigned int]
+
+#![feature(rustc_attrs)]
+#![feature(repr128)]
+#![feature(arbitrary_enum_discriminant)]
+
+use std::num::{NonZeroI128, NonZeroU32};
+
pub enum CStyleEnum {
Low = 2,
High = 16,
@@ -80,6 +152,51 @@ pub enum NicheLayoutEnum {
pub enum Empty {}
+// The following three types will use a niche layout once
+// https://github.com/rust-lang/rust/pull/94075 is merged:
+enum NicheLayoutWithFields1<'a> {
+ A(&'a u8, u32),
+ B(u32),
+}
+
+enum NicheLayoutWithFields2 {
+ A(NonZeroU32, u64),
+ B(u64),
+}
+
+enum NicheLayoutWithFields3 {
+ A(u8, bool),
+ B(u8),
+ C(bool),
+ D(u8),
+ E(u8),
+ F,
+}
+
+#[rustc_layout_scalar_valid_range_start(340282366920938463463374607431768211454)]
+#[rustc_layout_scalar_valid_range_end(1)]
+#[repr(transparent)]
+struct Wrapping128(u128);
+
+// #[rustc_layout(debug)]
+enum Wrapping128Niche {
+ X(Wrapping128),
+ Y,
+ Z,
+}
+
+#[repr(i128)]
+enum DirectTag128 {
+ A(u32),
+ B(u32),
+}
+
+#[repr(u32)]
+enum ArbitraryDiscr {
+ Abc(u32) = 1000,
+ Def(u32) = 5000_000,
+}
+
fn main() {
let a = Some(CStyleEnum::Low);
let b = Option::<CStyleEnum>::None;
@@ -93,6 +210,35 @@ fn main() {
let j = CStyleEnum::High;
let k = Some("IAMA optional string!".to_string());
let l = Result::<u32, Empty>::Ok(42);
+ let niche128_some = Some(NonZeroI128::new(123456).unwrap());
+ let niche128_none: Option<NonZeroI128> = None;
+
+ let wrapping_niche128_untagged =
+ unsafe { Wrapping128Niche::X(Wrapping128(340282366920938463463374607431768211454)) };
+ let wrapping_niche128_none1 = Wrapping128Niche::Y;
+ let wrapping_niche128_none2 = Wrapping128Niche::Z;
+
+ let direct_tag_128_a = DirectTag128::A(42);
+ let direct_tag_128_b = DirectTag128::B(137);
+
+ let niche_w_fields_1_some = NicheLayoutWithFields1::A(&77, 7);
+ let niche_w_fields_1_none = NicheLayoutWithFields1::B(99);
+
+ let niche_w_fields_2_some = NicheLayoutWithFields2::A(NonZeroU32::new(800).unwrap(), 900);
+ let niche_w_fields_2_none = NicheLayoutWithFields2::B(1000);
+
+ let niche_w_fields_3_some = NicheLayoutWithFields3::A(137, true);
+ let niche_w_fields_3_niche1 = NicheLayoutWithFields3::B(12);
+ let niche_w_fields_3_niche2 = NicheLayoutWithFields3::C(false);
+ let niche_w_fields_3_niche3 = NicheLayoutWithFields3::D(34);
+ let niche_w_fields_3_niche4 = NicheLayoutWithFields3::E(56);
+ let niche_w_fields_3_niche5 = NicheLayoutWithFields3::F;
+
+ let niche_w_fields_std_result_ok: Result<Box<[u8]>, u64> = Ok(vec![1, 2, 3].into());
+ let niche_w_fields_std_result_err: Result<Box<[u8]>, u64> = Err(789);
+
+ let arbitrary_discr1 = ArbitraryDiscr::Abc(1234);
+ let arbitrary_discr2 = ArbitraryDiscr::Def(5678);
zzz(); // #break
}
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
index 3846fb42f..9630952cb 100644
--- a/src/test/debuginfo/msvc-scalarpair-params.rs
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -18,12 +18,10 @@
// cdb-command: g
// cdb-command: dx o1
-// cdb-check:o1 : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [variant] : Some
+// cdb-check:o1 : Some [Type: enum2$<core::option::Option<u32> >]
// cdb-check: [+0x004] __0 : 0x4d2 [Type: [...]]
// cdb-command: dx o2
-// cdb-check:o2 : Some [Type: enum$<core::option::Option<u64> >]
-// cdb-check: [variant] : Some
+// cdb-check:o2 : Some [Type: enum2$<core::option::Option<u64> >]
// cdb-check: [+0x008] __0 : 0x162e [Type: unsigned __int64]
// cdb-command: g
@@ -89,7 +87,7 @@ fn slice(s: &[u8]) {
zzz(); // #break
}
-fn zzz() { }
+fn zzz() {}
fn main() {
range(10..12, 20..30);
diff --git a/src/test/debuginfo/mutex.rs b/src/test/debuginfo/mutex.rs
index 00dccf5f9..314ba40b0 100644
--- a/src/test/debuginfo/mutex.rs
+++ b/src/test/debuginfo/mutex.rs
@@ -20,19 +20,20 @@
// cdb-check: [<Raw View>] [Type: core::cell::UnsafeCell<i32>]
//
-// cdb-command:dx lock,d
-// cdb-check:lock,d : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
-// cdb-check: [variant] : Ok
+// cdb-command:dx _lock,d
+// cdb-check:_lock,d : Ok [Type: enum2$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum2$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> > > > >]
// cdb-check: [...] __0 [Type: std::sync::mutex::MutexGuard<i32>]
use std::sync::Mutex;
-#[allow(unused_variables)]
-fn main()
-{
+fn main() {
let m = Mutex::new(0);
- let lock = m.try_lock();
+ let _lock = m.try_lock();
+
+ println!("this line avoids an `Ambiguous symbol error` while setting the breakpoint");
+
zzz(); // #break
}
+#[inline(never)]
fn zzz() {}
diff --git a/src/test/debuginfo/numeric-types.rs b/src/test/debuginfo/numeric-types.rs
index 2eae9239b..c41c9ee21 100644
--- a/src/test/debuginfo/numeric-types.rs
+++ b/src/test/debuginfo/numeric-types.rs
@@ -1,6 +1,7 @@
-// only-cdb
// compile-flags:-g
+// min-gdb-version: 8.1
+
// Tests the visualizations for `NonZero{I,U}{8,16,32,64,128,size}`, `Wrapping<T>` and
// `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`.
@@ -153,6 +154,90 @@
// cdb-check:a_usize : 0x400 [Type: core::sync::atomic::AtomicUsize]
// cdb-check: [<Raw View>] [Type: core::sync::atomic::AtomicUsize]
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+
+// gdb-command:print/d nz_i8
+// gdb-check:[...]$1 = 11
+
+// gdb-command:print nz_i16
+// gdb-check:[...]$2 = 22
+
+// gdb-command:print nz_i32
+// gdb-check:[...]$3 = 33
+
+// gdb-command:print nz_i64
+// gdb-check:[...]$4 = 44
+
+// gdb-command:print nz_i128
+// gdb-check:[...]$5 = 55
+
+// gdb-command:print nz_isize
+// gdb-check:[...]$6 = 66
+
+// gdb-command:print/d nz_u8
+// gdb-check:[...]$7 = 77
+
+// gdb-command:print nz_u16
+// gdb-check:[...]$8 = 88
+
+// gdb-command:print nz_u32
+// gdb-check:[...]$9 = 99
+
+// gdb-command:print nz_u64
+// gdb-check:[...]$10 = 100
+
+// gdb-command:print nz_u128
+// gdb-check:[...]$11 = 111
+
+// gdb-command:print nz_usize
+// gdb-check:[...]$12 = 122
+
+
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:run
+
+// lldb-command:print/d nz_i8
+// lldb-check:[...]$0 = 11 { __0 = 11 }
+
+// lldb-command:print nz_i16
+// lldb-check:[...]$1 = 22 { __0 = 22 }
+
+// lldb-command:print nz_i32
+// lldb-check:[...]$2 = 33 { __0 = 33 }
+
+// lldb-command:print nz_i64
+// lldb-check:[...]$3 = 44 { __0 = 44 }
+
+// lldb-command:print nz_i128
+// lldb-check:[...]$4 = 55 { __0 = 55 }
+
+// lldb-command:print nz_isize
+// lldb-check:[...]$5 = 66 { __0 = 66 }
+
+// lldb-command:print/d nz_u8
+// lldb-check:[...]$6 = 77 { __0 = 77 }
+
+// lldb-command:print nz_u16
+// lldb-check:[...]$7 = 88 { __0 = 88 }
+
+// lldb-command:print nz_u32
+// lldb-check:[...]$8 = 99 { __0 = 99 }
+
+// lldb-command:print nz_u64
+// lldb-check:[...]$9 = 100 { __0 = 100 }
+
+// lldb-command:print nz_u128
+// lldb-check:[...]$10 = 111 { __0 = 111 }
+
+// lldb-command:print nz_usize
+// lldb-check:[...]$11 = 122 { __0 = 122 }
+
+
use std::num::*;
use std::sync::atomic::*;
diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs
index 55a4ecc1c..a51b37205 100644
--- a/src/test/debuginfo/pretty-std.rs
+++ b/src/test/debuginfo/pretty-std.rs
@@ -39,7 +39,6 @@
// gdb-command: print some_string
// gdb-check:$8 = Some = {"IAMA "...}
-
// === LLDB TESTS ==================================================================================
// lldb-command: run
@@ -65,7 +64,6 @@
// lldb-command: print os_string
// lldb-check:[...]$6 = "IAMA OS string 😃"[...]
-
// === CDB TESTS ==================================================================================
// cdb-command: g
@@ -118,20 +116,17 @@
// cdb-check: [chars] : "IAMA OS string [...]"
// cdb-command: dx some
-// cdb-check:some : Some [Type: enum$<core::option::Option<i16> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<i16> >]
-// cdb-check: [variant] : Some
+// cdb-check:some : Some [Type: enum2$<core::option::Option<i16> >]
+// cdb-check: [<Raw View>] [Type: enum2$<core::option::Option<i16> >]
// cdb-check: [+0x002] __0 : 8 [Type: short]
// cdb-command: dx none
-// cdb-check:none : None [Type: enum$<core::option::Option<i64> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<i64> >]
-// cdb-check: [variant] : None
+// cdb-check:none : None [Type: enum2$<core::option::Option<i64> >]
+// cdb-check: [<Raw View>] [Type: enum2$<core::option::Option<i64> >]
// cdb-command: dx some_string
-// cdb-check:some_string : Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [variant] : Some
+// cdb-check:some_string : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
+// cdb-check: [<Raw View>] [Type: enum2$<core::option::Option<alloc::string::String> >]
// cdb-check: [+0x000] __0 : "IAMA optional string!" [Type: alloc::string::String]
// cdb-command: dx linkedlist
@@ -153,7 +148,6 @@ use std::collections::{LinkedList, VecDeque};
use std::ffi::OsString;
fn main() {
-
// &[]
let slice: &[i32] = &[0, 1, 2, 3];
@@ -188,4 +182,6 @@ fn main() {
zzz(); // #break
}
-fn zzz() { () }
+fn zzz() {
+ ()
+}
diff --git a/src/test/debuginfo/result-types.rs b/src/test/debuginfo/result-types.rs
index c0d905a6a..cdac47a78 100644
--- a/src/test/debuginfo/result-types.rs
+++ b/src/test/debuginfo/result-types.rs
@@ -7,15 +7,14 @@
// cdb-command: g
// cdb-command: dx x,d
-// cdb-check:x,d : Ok [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:x,d : Ok [Type: enum2$<core::result::Result<i32,str> >]
// cdb-check: [...] __0 : -3 [Type: int]
// cdb-command: dx y
-// cdb-check:y : Err [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:y : Err [Type: enum2$<core::result::Result<i32,str> >]
// cdb-check: [...] __0 : "Some error message" [Type: str]
-fn main()
-{
+fn main() {
let x: Result<i32, &str> = Ok(-3);
assert_eq!(x.is_ok(), true);
@@ -25,4 +24,6 @@ fn main()
zzz(); // #break.
}
-fn zzz() { () }
+fn zzz() {
+ ()
+}
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index b040a6e74..9cc99d776 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -175,51 +175,51 @@
// 0-sized structs appear to be optimized away in some cases, so only check the structs that do
// actually appear.
// cdb-command:dv /t *_struct
-// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
+// cdb-check:struct type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
// ENUMS
// cdb-command:dv /t *_enum_*
-// cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...]
-// cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...]
-// cdb-check:union enum$<type_names::mod1::Enum2> simple_enum_3 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_1 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_2 = [...]
+// cdb-check:union enum2$<type_names::mod1::Enum2> simple_enum_3 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
// TUPLES
// cdb-command:dv /t tuple*
-// cdb-check:struct tuple$<u32,type_names::Struct1,enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
-// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum$<type_names::mod1::Enum2>,char> tuple2 = [...]
+// cdb-check:struct tuple$<u32,type_names::Struct1,enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
+// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum2$<type_names::mod1::Enum2>,char> tuple2 = [...]
// BOX
// cdb-command:dv /t box*
// cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
-// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum2$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
// REFERENCES
// cdb-command:dv /t *ref*
// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
// cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
-// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
// RAW POINTERS
// cdb-command:dv /t *_ptr*
// cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
// cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_mut$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_mut$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
// cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
// cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_const$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_const$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
// VECTORS
// cdb-command:dv /t *vec*
// cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
// cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
// cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
-// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
+// cdb-check:struct alloc::vec::Vec<enum2$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
// cdb-command:dv /t slice*
// cdb-check:struct slice$<usize> slice1 = [...]
-// cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
+// cdb-check:struct slice$<enum2$<type_names::mod1::Enum2> > slice2 = [...]
// TRAITS
// cdb-command:dv /t *_trait
@@ -238,16 +238,16 @@
// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
// cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
// cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >),usize> rust_fn = [...]
// cdb-command:dv /t *_function*
// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
// cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
// cdb-check:Return Type: void
-// cdb-check:Parameter Types: enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>
+// cdb-check:Parameter Types: enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >
// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn_with_return_value")
// cdb-check:Return Type: usize
// cdb-check:Parameter Types: f64
diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs
index b466cfdd5..0f8898c38 100644
--- a/src/test/incremental/hashes/enum_defs.rs
+++ b/src/test/incremental/hashes/enum_defs.rs
@@ -504,9 +504,9 @@ enum EnumAddLifetimeBoundToParameter<'a, T> {
}
#[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
#[rustc_clean(cfg="cfail3")]
-#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
#[rustc_clean(cfg="cfail6")]
enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
Variant1(T),
@@ -559,9 +559,9 @@ enum EnumAddLifetimeBoundToParameterWhere<'a, T> {
}
#[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
#[rustc_clean(cfg="cfail3")]
-#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
#[rustc_clean(cfg="cfail6")]
enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
Variant1(T),
diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs
index 1988f3f35..c453eeceb 100644
--- a/src/test/incremental/hashes/trait_defs.rs
+++ b/src/test/incremental/hashes/trait_defs.rs
@@ -1066,9 +1066,9 @@ trait TraitAddTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T> { }
#[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")]
trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T: 'a> { }
@@ -1144,9 +1144,9 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0 + Refer
trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a> { }
#[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")]
trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a + 'b> { }
@@ -1201,9 +1201,9 @@ trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0
trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> { }
#[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")]
trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> where T: 'a { }
@@ -1254,9 +1254,9 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T>
trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a { }
#[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")]
trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a + 'b { }
diff --git a/src/test/incremental/hygiene/load_cached_hygiene.rs b/src/test/incremental/hygiene/load_cached_hygiene.rs
index 812414141..355d33458 100644
--- a/src/test/incremental/hygiene/load_cached_hygiene.rs
+++ b/src/test/incremental/hygiene/load_cached_hygiene.rs
@@ -2,7 +2,7 @@
// compile-flags: -Z query-dep-graph
// aux-build:cached_hygiene.rs
-// This tests the folllowing scenario
+// This tests the following scenario
// 1. A foreign crate is compiled with incremental compilation.
// This causes hygiene information to be saved to the incr cache.
// 2. One function is the foreign crate is modified. This causes the
diff --git a/src/test/incremental/issue-100521-change-struct-name-assocty.rs b/src/test/incremental/issue-100521-change-struct-name-assocty.rs
new file mode 100644
index 000000000..7f8d1e608
--- /dev/null
+++ b/src/test/incremental/issue-100521-change-struct-name-assocty.rs
@@ -0,0 +1,65 @@
+// revisions: rpass1 rpass2
+
+pub fn foo() {
+ bar();
+ baz::<()>();
+}
+
+fn bar()
+where
+ <() as Table>::AllColumns:,
+{
+}
+
+fn baz<W>()
+where
+ W: AsQuery,
+ <W as AsQuery>::Query:,
+{
+}
+
+trait AsQuery {
+ type Query;
+}
+
+trait UnimplementedTrait {}
+
+impl<T> AsQuery for T
+where
+ T: UnimplementedTrait,
+{
+ type Query = ();
+}
+
+struct Wrapper<Expr>(Expr);
+
+impl<Ret> AsQuery for Wrapper<Ret> {
+ type Query = ();
+}
+
+impl AsQuery for ()
+where
+ Wrapper<<() as Table>::AllColumns>: AsQuery,
+{
+ type Query = ();
+}
+
+trait Table {
+ type AllColumns;
+}
+
+#[cfg(rpass1)]
+impl Table for () {
+ type AllColumns = Checksum1;
+}
+#[cfg(rpass1)]
+struct Checksum1;
+
+#[cfg(rpass2)]
+impl Table for () {
+ type AllColumns = Checksum2;
+}
+#[cfg(rpass2)]
+struct Checksum2;
+
+fn main() {}
diff --git a/src/test/incremental/issue-49043.rs b/src/test/incremental/issue-49043.rs
index 50d8fb869..8d13718b8 100644
--- a/src/test/incremental/issue-49043.rs
+++ b/src/test/incremental/issue-49043.rs
@@ -1,5 +1,5 @@
// Regression test for hashing involving canonical variables. In this
-// test -- which has an intensional error -- the type of the value
+// test -- which has an intentional error -- the type of the value
// being dropped winds up including a type variable. Canonicalization
// would then produce a `?0` which -- in turn -- triggered an ICE in
// hashing.
diff --git a/src/test/incremental/split_debuginfo_cached.rs b/src/test/incremental/split_debuginfo_cached.rs
index 25c802d5a..ba8385f89 100644
--- a/src/test/incremental/split_debuginfo_cached.rs
+++ b/src/test/incremental/split_debuginfo_cached.rs
@@ -6,8 +6,8 @@
// only-x86_64-unknown-linux-gnu
// revisions:rpass1 rpass2
-// [rpass1]compile-flags: -g -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split
-// [rpass2]compile-flags: -g -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split
+// [rpass1]compile-flags: -g -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split
+// [rpass2]compile-flags: -g -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split
#![feature(rustc_attrs)]
// For `rpass2`, nothing has changed so everything should re-used.
diff --git a/src/test/incremental/split_debuginfo_mode.rs b/src/test/incremental/split_debuginfo_mode.rs
index f2533e414..edc1a80d3 100644
--- a/src/test/incremental/split_debuginfo_mode.rs
+++ b/src/test/incremental/split_debuginfo_mode.rs
@@ -6,10 +6,10 @@
// only-x86_64-unknown-linux-gnu
// revisions:rpass1 rpass2 rpass3 rpass4
-// [rpass1]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on
-// [rpass2]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on
-// [rpass3]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=on
-// [rpass4]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=off
+// [rpass1]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on
+// [rpass2]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on
+// [rpass3]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=on
+// [rpass4]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=off
#![feature(rustc_attrs)]
// For rpass2 we change -Csplit-debuginfo and thus expect every CGU to be recompiled
diff --git a/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs b/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs
index 4d48a5f0a..95f3b8ae4 100644
--- a/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs
+++ b/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs
@@ -3,7 +3,7 @@
// rust-lang/rust#69798:
//
-// This is analgous to cgu_invalidated_when_import_added, but it covers a
+// This is analogous to cgu_invalidated_when_import_added, but it covers a
// problem uncovered where a change to the *export* set caused a link failure
// when reusing post-LTO optimized object code.
diff --git a/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs b/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs
index e85b4856f..e86ebd354 100644
--- a/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs
+++ b/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs
@@ -3,7 +3,7 @@
// rust-lang/rust#69798:
//
-// This is analgous to cgu_invalidated_when_export_added, but it covers the
+// This is analogous to cgu_invalidated_when_export_added, but it covers the
// other direction. This is analogous to cgu_invalidated_when_import_added: we
// include it, because it may uncover bugs in variant implementation strategies.
diff --git a/src/test/mir-opt/README.md b/src/test/mir-opt/README.md
index a0550466c..0721d9f70 100644
--- a/src/test/mir-opt/README.md
+++ b/src/test/mir-opt/README.md
@@ -14,6 +14,18 @@ presence of pointers in constants or other bit width dependent things. In that c
to your test, causing separate files to be generated for 32bit and 64bit systems.
+## Unit testing
+
+If you are only testing the behavior of a particular mir-opt pass on some specific input (as is
+usually the case), you should add
+
+```
+// unit-test: PassName
+```
+
+to the top of the file. This makes sure that other passes don't run which means you'll get the input
+you expected and your test won't break when other code changes.
+
## Emit a diff of the mir for a specific optimization
This is what you want most often when you want to see how an optimization changes the MIR.
diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array-index-is-temporary.rs
index 0e4c486e4..e7bde81d4 100644
--- a/src/test/mir-opt/array-index-is-temporary.rs
+++ b/src/test/mir-opt/array-index-is-temporary.rs
@@ -7,7 +7,7 @@ unsafe fn foo(z: *mut usize) -> u32 {
99
}
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
fn main() {
let mut x = [42, 43, 44];
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir
deleted file mode 100644
index 27f883ed3..000000000
--- a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir
+++ /dev/null
@@ -1,64 +0,0 @@
-// MIR for `main` after SimplifyCfg-elaborate-drops
-
-fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11
- let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
- let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
- let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
- let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
- let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- scope 1 {
- debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
- let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
- scope 2 {
- debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
- let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
- scope 3 {
- debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
- scope 4 {
- }
- }
- }
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
- _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29
- StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
- _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18
- StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
- StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32
- StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
- StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
- _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
- _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27
- // mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24
- // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) }
- }
-
- bb1: {
- StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27
- StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
- _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
- _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- }
-
- bb2: {
- _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29
- StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29
- StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30
- _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2
- StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
- StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
- StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
- return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2
- }
-}
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
index 27f883ed3..27f883ed3 100644
--- a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir
+++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
diff --git a/src/test/mir-opt/asm_unwind_panic_abort.rs b/src/test/mir-opt/asm_unwind_panic_abort.rs
index 8201d5434..ad8f9398e 100644
--- a/src/test/mir-opt/asm_unwind_panic_abort.rs
+++ b/src/test/mir-opt/asm_unwind_panic_abort.rs
@@ -1,7 +1,6 @@
//! Tests that unwinding from an asm block is caught and forced to abort
//! when `-C panic=abort`.
-// min-llvm-version: 13.0.0
// only-x86_64
// compile-flags: -C panic=abort
// no-prefer-dynamic
diff --git a/src/test/mir-opt/bool_compare.rs b/src/test/mir-opt/bool_compare.rs
index 3ff046325..4435bf5b0 100644
--- a/src/test/mir-opt/bool_compare.rs
+++ b/src/test/mir-opt/bool_compare.rs
@@ -1,3 +1,5 @@
+// unit-test: InstCombine
+
// EMIT_MIR bool_compare.opt1.InstCombine.diff
fn opt1(x: bool) -> u32 {
if x != true { 0 } else { 1 }
diff --git a/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff
deleted file mode 100644
index c73150f94..000000000
--- a/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `norm2` before InstCombine
-+ // MIR for `norm2` after InstCombine
-
- fn norm2(_1: [f32; 2]) -> f32 {
- debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11
- let mut _0: f32; // return place in scope 0 at $DIR/combine_array_len.rs:+0:26: +0:29
- let _2: f32; // in scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10
- let _3: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
- let mut _4: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
- let mut _5: bool; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
- let _7: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:15: +2:16
- let mut _8: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17
- let mut _9: bool; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17
- let mut _10: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:8
- let mut _11: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:6
- let mut _12: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:7: +3:8
- let mut _13: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:14
- let mut _14: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:12
- let mut _15: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:13: +3:14
- scope 1 {
- debug a => _2; // in scope 1 at $DIR/combine_array_len.rs:+1:9: +1:10
- let _6: f32; // in scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10
- scope 2 {
- debug b => _6; // in scope 2 at $DIR/combine_array_len.rs:+2:9: +2:10
- }
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
- _3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16
-- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
-+ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
- _5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
- }
-
- bb1: {
- _2 = _1[_3]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17
- StorageDead(_3); // scope 0 at $DIR/combine_array_len.rs:+1:17: +1:18
- StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10
- StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16
- _7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16
-- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
-+ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
- _9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
- }
-
- bb2: {
- _6 = _1[_7]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17
- StorageDead(_7); // scope 1 at $DIR/combine_array_len.rs:+2:17: +2:18
- StorageLive(_10); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8
- StorageLive(_11); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6
- _11 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6
- StorageLive(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
- _12 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
- _10 = Mul(move _11, move _12); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8
- StorageDead(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
- StorageDead(_11); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8
- StorageLive(_13); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14
- StorageLive(_14); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12
- _14 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12
- StorageLive(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
- _15 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
- _13 = Mul(move _14, move _15); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14
- StorageDead(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
- StorageDead(_14); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
- _0 = Add(move _10, move _13); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:14
- StorageDead(_13); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
- StorageDead(_10); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14
- StorageDead(_6); // scope 1 at $DIR/combine_array_len.rs:+4:1: +4:2
- StorageDead(_2); // scope 0 at $DIR/combine_array_len.rs:+4:1: +4:2
- return; // scope 0 at $DIR/combine_array_len.rs:+4:2: +4:2
- }
- }
-
diff --git a/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.diff
index c73150f94..c73150f94 100644
--- a/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff
+++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.diff
diff --git a/src/test/mir-opt/combine_array_len.rs b/src/test/mir-opt/combine_array_len.rs
index 93490c14f..3ef3bd09a 100644
--- a/src/test/mir-opt/combine_array_len.rs
+++ b/src/test/mir-opt/combine_array_len.rs
@@ -1,4 +1,4 @@
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// unit-test: InstCombine
// EMIT_MIR combine_array_len.norm2.InstCombine.diff
fn norm2(x: [f32; 2]) -> f32 {
diff --git a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
index 833d620cc..bde2f04fa 100644
--- a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
+++ b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
@@ -4,63 +4,63 @@
fn <impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone(_1: &MyThing<T>) -> MyThing<T> {
debug self => _1; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
let mut _0: MyThing<T>; // return place in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
- let mut _2: T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
- let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
- let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
- let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
- let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
- let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ let mut _2: T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
bb0: {
- StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
-- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
-+ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
- _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9
+ StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
++ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
// mir::Constant
// + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9
// + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:8: +2:9
- StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
- StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
- StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
- _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
-- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
-- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
+ StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9
+ StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+ _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
- // mir::Constant
- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11
- // + literal: Const { ty: for<'r> fn(&'r u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) }
-+ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
-+ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
-+ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11
++ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
}
bb2: {
- StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:10: +3:11
- StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
- StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
- StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
- _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
-- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
-- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
+ StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11
+ StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+ _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
- // mir::Constant
- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16
- // + literal: Const { ty: for<'r> fn(&'r [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) }
-+ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
-+ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
-+ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16
++ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
}
bb3: {
- StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:15: +4:16
+ StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16
Deinit(_0); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
(_0.0: T) = move _2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
(_0.1: u64) = move _5; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15
diff --git a/src/test/mir-opt/const_goto.rs b/src/test/mir-opt/const_goto.rs
index 939902e70..6f84f186b 100644
--- a/src/test/mir-opt/const_goto.rs
+++ b/src/test/mir-opt/const_goto.rs
@@ -1,3 +1,5 @@
+// unit-test: ConstGoto
+
pub enum Foo {
A,
B,
diff --git a/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
index 2b09ef786..81c356cb1 100644
--- a/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
+++ b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
@@ -17,7 +17,7 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/const_goto_storage.rs:+1:9: +1:12
- StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
-- nop; // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
+- Deinit(_2); // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23
- StorageLive(_3); // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10
- StorageLive(_4); // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76
- StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52
diff --git a/src/test/mir-opt/const_goto_storage.rs b/src/test/mir-opt/const_goto_storage.rs
index 4ef68e7e1..459599c73 100644
--- a/src/test/mir-opt/const_goto_storage.rs
+++ b/src/test/mir-opt/const_goto_storage.rs
@@ -1,3 +1,5 @@
+// unit-test: ConstGoto
+
// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff
fn match_nested_if() -> bool {
let val = match () {
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index f58ba56b9..248abb8fd 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -17,7 +17,7 @@
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
-+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
++ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
@@ -40,11 +40,11 @@
- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:45
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:45
}
- }
-
diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
index deb467977..90920fbe7 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
@@ -12,6 +12,6 @@ static BOP: &i32 = {
_1 = &_2; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
_0 = &(*_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:22: +0:23
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:17
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:24
}
}
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index 5300f555f..8ce895fe7 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -19,7 +19,7 @@
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
-+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
++ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
@@ -42,11 +42,11 @@
- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:56
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28
+ resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:56
}
}
-
diff --git a/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
index 836443bf4..04378dbf3 100644
--- a/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
@@ -24,7 +24,7 @@
+ _1 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28
StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28
StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29
- nop; // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2
return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/aggregate.rs b/src/test/mir-opt/const_prop/aggregate.rs
index 7a3b26a73..493d0508a 100644
--- a/src/test/mir-opt/const_prop/aggregate.rs
+++ b/src/test/mir-opt/const_prop/aggregate.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -O
// EMIT_MIR aggregate.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
index bb9abdd10..439b2a3e1 100644
--- a/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
@@ -18,11 +18,12 @@
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30
StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32
_3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32
- _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _4 = Len(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
-+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
}
bb1: {
@@ -30,7 +31,7 @@
+ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
- nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/array_index.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
index bb9abdd10..439b2a3e1 100644
--- a/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
@@ -18,11 +18,12 @@
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30
StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32
_3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32
- _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _4 = Len(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
-+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
}
bb1: {
@@ -30,7 +31,7 @@
+ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
- nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/array_index.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/array_index.rs b/src/test/mir-opt/const_prop/array_index.rs
index 2c5254b5d..d31c2827b 100644
--- a/src/test/mir-opt/const_prop/array_index.rs
+++ b/src/test/mir-opt/const_prop/array_index.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR array_index.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
index 45134a3fd..bea32a67e 100644
--- a/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
@@ -24,10 +24,9 @@
StorageLive(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
- _3 = _1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
-- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+ _4 = const true; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
-+ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
}
bb1: {
@@ -38,14 +37,13 @@
+ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
-+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
}
bb2: {
-- _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
-+ _2 = Div(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
- nop; // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2
+ _0 = const (); // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2
StorageDead(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
StorageDead(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
return; // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:2: +3:2
diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
index 6f39209b9..a6fd325ec 100644
--- a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
+++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff
#[allow(unconditional_panic)]
fn main() {
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
index 553488838..c27b19679 100644
--- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
@@ -25,7 +25,7 @@
StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
- _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
// mir::Constant
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
// + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
index 553488838..c27b19679 100644
--- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
@@ -25,7 +25,7 @@
StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
- _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
// mir::Constant
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
// + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs
index 57164e3e7..c7b609949 100644
--- a/src/test/mir-opt/const_prop/boolean_identities.rs
+++ b/src/test/mir-opt/const_prop/boolean_identities.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -O -Zmir-opt-level=4
// EMIT_MIR boolean_identities.test.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
index f2d4bee1b..5ec421eb2 100644
--- a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
@@ -12,8 +12,6 @@
let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
- let mut _10: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
- let mut _11: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
scope 1 {
debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10
}
@@ -26,28 +24,23 @@
StorageLive(_3); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
- _4 = SizeOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22
- _5 = AlignOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22
-- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+ _4 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+ _5 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
-+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+ _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
// mir::Constant
- // + span: $DIR/boxes.rs:12:14: 12:22
+ // + span: $DIR/boxes.rs:13:14: 13:22
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
}
bb1: {
StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
_7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
- StorageLive(_8); // scope 0 at $DIR/boxes.rs:+1:19: +1:21
_8 = (((_7.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:19: +1:21
(*_8) = const 42_i32; // scope 0 at $DIR/boxes.rs:+1:19: +1:21
- StorageDead(_8); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
_3 = move _7; // scope 0 at $DIR/boxes.rs:+1:14: +1:22
StorageDead(_7); // scope 0 at $DIR/boxes.rs:+1:21: +1:22
- StorageLive(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
_9 = (((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
_2 = (*_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
- StorageDead(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:26
_1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:26
StorageDead(_2); // scope 0 at $DIR/boxes.rs:+1:25: +1:26
drop(_3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/boxes.rs:+1:26: +1:27
@@ -55,7 +48,7 @@
bb2: {
StorageDead(_3); // scope 0 at $DIR/boxes.rs:+1:26: +1:27
- nop; // scope 0 at $DIR/boxes.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/boxes.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/boxes.rs:+2:1: +2:2
return; // scope 0 at $DIR/boxes.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/boxes.rs b/src/test/mir-opt/const_prop/boxes.rs
index fea666a44..d287830db 100644
--- a/src/test/mir-opt/const_prop/boxes.rs
+++ b/src/test/mir-opt/const_prop/boxes.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -O
// ignore-emscripten compiled with panic=abort by default
// ignore-wasm32
diff --git a/src/test/mir-opt/const_prop/cast.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
index 5698a612f..e040a4b3a 100644
--- a/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
@@ -19,7 +19,7 @@
StorageLive(_2); // scope 1 at $DIR/cast.rs:+3:9: +3:10
- _2 = const 42_u32 as u8 (Misc); // scope 1 at $DIR/cast.rs:+3:13: +3:24
+ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24
- nop; // scope 0 at $DIR/cast.rs:+0:11: +4:2
+ _0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +4:2
StorageDead(_2); // scope 1 at $DIR/cast.rs:+4:1: +4:2
StorageDead(_1); // scope 0 at $DIR/cast.rs:+4:1: +4:2
return; // scope 0 at $DIR/cast.rs:+4:2: +4:2
diff --git a/src/test/mir-opt/const_prop/cast.rs b/src/test/mir-opt/const_prop/cast.rs
index 680cab007..984086eda 100644
--- a/src/test/mir-opt/const_prop/cast.rs
+++ b/src/test/mir-opt/const_prop/cast.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// EMIT_MIR cast.main.ConstProp.diff
fn main() {
diff --git a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
index 5e33d0542..96d0d2566 100644
--- a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
@@ -20,7 +20,7 @@
bb1: {
- _1 = move (_2.0: u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ _1 = const 2_u32; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
- nop; // scope 0 at $DIR/checked_add.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/checked_add.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/checked_add.rs:+2:1: +2:2
return; // scope 0 at $DIR/checked_add.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/checked_add.rs b/src/test/mir-opt/const_prop/checked_add.rs
index 08d59b6fb..b9860da4c 100644
--- a/src/test/mir-opt/const_prop/checked_add.rs
+++ b/src/test/mir-opt/const_prop/checked_add.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -C overflow-checks=on
// EMIT_MIR checked_add.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
index c21b24591..bea7114c7 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
@@ -16,9 +16,9 @@
StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
- _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ _3 = const _; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
// mir::Constant
- // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
+ // + span: $DIR/const_prop_fails_gracefully.rs:8:13: 8:16
// + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
_2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
_1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:39
@@ -29,14 +29,14 @@
_5 = _1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
_4 = read(move _5) -> bb1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
// mir::Constant
- // + span: $DIR/const_prop_fails_gracefully.rs:8:5: 8:9
+ // + span: $DIR/const_prop_fails_gracefully.rs:9:5: 9:9
// + literal: Const { ty: fn(usize) {read}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:11: +3:12
StorageDead(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:12: +3:13
- nop; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2
+ _0 = const (); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2
StorageDead(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:1: +4:2
return; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:2: +4:2
}
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
index 8bd68527f..0a3dcbd38 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
#[inline(never)]
fn read(_: usize) { }
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs
index aa4ce19f6..7dbe8e734 100644
--- a/src/test/mir-opt/const_prop/control-flow-simplification.rs
+++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs
@@ -1,10 +1,11 @@
+// unit-test: ConstProp
// compile-flags: -Zmir-opt-level=1
-trait NeedsDrop:Sized{
- const NEEDS:bool=std::mem::needs_drop::<Self>();
+trait NeedsDrop: Sized {
+ const NEEDS: bool = std::mem::needs_drop::<Self>();
}
-impl<This> NeedsDrop for This{}
+impl<This> NeedsDrop for This {}
// EMIT_MIR control_flow_simplification.hello.ConstProp.diff
// EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
index 5f4df0d88..a07bdd998 100644
--- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
@@ -8,9 +8,8 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
-- _1 = const <bool as NeedsDrop>::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ _1 = const _; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
-+ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
}
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
index 5b4ecaa80..6b29bb59c 100644
--- a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
@@ -44,7 +44,7 @@
_1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68
StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68
StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69
- nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
index 5b4ecaa80..6b29bb59c 100644
--- a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
@@ -44,7 +44,7 @@
_1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68
StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68
StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69
- nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/discriminant.rs b/src/test/mir-opt/const_prop/discriminant.rs
index 67538b3c7..fdd67ca8a 100644
--- a/src/test/mir-opt/const_prop/discriminant.rs
+++ b/src/test/mir-opt/const_prop/discriminant.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -O
// FIXME(wesleywiser): Ideally, we could const-prop away all of this and just be left with
diff --git a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
index 2e1e32545..948bb7f56 100644
--- a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
@@ -18,14 +18,14 @@
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:25
+ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
-+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
}
bb1: {
- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
StorageDead(_2); // scope 0 at $DIR/indirect.rs:+1:28: +1:29
- nop; // scope 0 at $DIR/indirect.rs:+0:11: +2:2
+ _0 = const (); // scope 0 at $DIR/indirect.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/indirect.rs:+2:1: +2:2
return; // scope 0 at $DIR/indirect.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/const_prop/indirect.rs b/src/test/mir-opt/const_prop/indirect.rs
index 37217ca81..44916cbfe 100644
--- a/src/test/mir-opt/const_prop/indirect.rs
+++ b/src/test/mir-opt/const_prop/indirect.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -C overflow-checks=on
// EMIT_MIR indirect.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue-66971.rs
index 81eccae46..6ca03438e 100644
--- a/src/test/mir-opt/const_prop/issue-66971.rs
+++ b/src/test/mir-opt/const_prop/issue-66971.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -Z mir-opt-level=3
// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue-67019.rs
index c78b8b971..ffc6fa1f2 100644
--- a/src/test/mir-opt/const_prop/issue-67019.rs
+++ b/src/test/mir-opt/const_prop/issue-67019.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
// compile-flags: -Z mir-opt-level=3
// This used to ICE in const-prop
diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
index b3d5980aa..9d541dcab 100644
--- a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
@@ -19,7 +19,7 @@
StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:+1:21: +1:22
_1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
// mir::Constant
- // + span: $DIR/issue-66971.rs:16:5: 16:11
+ // + span: $DIR/issue-66971.rs:17:5: 17:11
// + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value(<ZST>) }
}
diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
index 8330b5052..b79d81476 100644
--- a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
@@ -20,7 +20,7 @@
StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:+1:18: +1:19
_1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
// mir::Constant
- // + span: $DIR/issue-67019.rs:11:5: 11:9
+ // + span: $DIR/issue-67019.rs:12:5: 12:9
// + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value(<ZST>) }
}
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs
index b0ecdf181..c839f92f2 100644
--- a/src/test/mir-opt/const_prop/mult_by_zero.rs
+++ b/src/test/mir-opt/const_prop/mult_by_zero.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O -Zmir-opt-level=4
// EMIT_MIR mult_by_zero.test.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/mutable_variable.rs b/src/test/mir-opt/const_prop/mutable_variable.rs
index 801e7a9fc..cb01719dd 100644
--- a/src/test/mir-opt/const_prop/mutable_variable.rs
+++ b/src/test/mir-opt/const_prop/mutable_variable.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
// EMIT_MIR mutable_variable.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
index e0b4b77ba..d4ff8d890 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
index 79ac497c7..9060f7e9b 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
index c678f7b03..6eda503c1 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
@@ -16,7 +16,7 @@
StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
_1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:29: +1:34
// mir::Constant
- // + span: $DIR/mutable_variable_aggregate_partial_read.rs:5:29: 5:32
+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:29: 6:32
// + literal: Const { ty: fn() -> (i32, i32) {foo}, val: Value(<ZST>) }
}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
index 9bb62b897..cb59509ff 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
// EMIT_MIR mutable_variable_aggregate_partial_read.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
index 4c2ba9a09..eb3a7bc96 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
@@ -25,7 +25,7 @@
StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
_4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
// mir::Constant
- // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19
+ // + span: $DIR/mutable_variable_no_prop.rs:10:13: 10:19
// + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) }
_3 = (*_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
_1 = move _3; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
index 4126fb3c6..8c23c5fcf 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
static mut STATIC: u32 = 42;
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
index 5328792b3..186a95373 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
@@ -25,7 +25,7 @@
StorageLive(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
_1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:13: +1:18
// mir::Constant
- // + span: $DIR/mutable_variable_unprop_assign.rs:5:13: 5:16
+ // + span: $DIR/mutable_variable_unprop_assign.rs:6:13: 6:16
// + literal: Const { ty: fn() -> i32 {foo}, val: Value(<ZST>) }
}
@@ -41,7 +41,8 @@
StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
_4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
- _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
+- _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
++ _5 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2
StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
index 13f1b3f47..b077cfd3e 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
// EMIT_MIR mutable_variable_unprop_assign.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
index 17265b7eb..c0fbd2558 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable.rs
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -C overflow-checks=on
struct Point {
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
index 89f43d751..b9c283a54 100644
--- a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
@@ -18,7 +18,7 @@
StorageLive(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
_3 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
// mir::Constant
- // + span: $DIR/read_immutable_static.rs:7:13: 7:16
+ // + span: $DIR/read_immutable_static.rs:8:13: 8:16
// + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
- _2 = (*_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ _2 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
@@ -26,7 +26,7 @@
StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
_5 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
// mir::Constant
- // + span: $DIR/read_immutable_static.rs:7:19: 7:22
+ // + span: $DIR/read_immutable_static.rs:8:19: 8:22
// + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
- _4 = (*_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
- _1 = Add(move _2, move _4); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.rs b/src/test/mir-opt/const_prop/read_immutable_static.rs
index 8a5f12c6f..4f7afe6ca 100644
--- a/src/test/mir-opt/const_prop/read_immutable_static.rs
+++ b/src/test/mir-opt/const_prop/read_immutable_static.rs
@@ -1,3 +1,4 @@
+// unit-test
// compile-flags: -O
static FOO: u8 = 2;
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
index c8b09220f..09ce67ff1 100644
--- a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
@@ -11,7 +11,7 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
- _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
// mir::Constant
// + span: $DIR/ref_deref.rs:5:6: 5:10
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
index d141d2cf8..902cd7850 100644
--- a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
+++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
@@ -14,7 +14,7 @@
- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
-+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
++ _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ // mir::Constant
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
index f0c89caea..ec3d90433 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
@@ -11,9 +11,9 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
- _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _4 = const _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
// mir::Constant
- // + span: $DIR/ref_deref_project.rs:5:6: 5:17
+ // + span: $DIR/ref_deref_project.rs:6:6: 6:17
// + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
_2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
index d25540287..cd0616e65 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
@@ -14,9 +14,9 @@
- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
-+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
++ _4 = const _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ // mir::Constant
-+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
++ // + span: $DIR/ref_deref_project.rs:6:6: 6:17
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs
index c7cc73651..659c11d9b 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project.rs
+++ b/src/test/mir-opt/const_prop/ref_deref_project.rs
@@ -1,3 +1,4 @@
+// unit-test
// EMIT_MIR ref_deref_project.main.PromoteTemps.diff
// EMIT_MIR ref_deref_project.main.ConstProp.diff
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
index 0ebfbca21..624376769 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -19,7 +19,7 @@
StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
- _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
// mir::Constant
// + span: $DIR/slice_len.rs:5:6: 5:19
// + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
index 0ebfbca21..624376769 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -19,7 +19,7 @@
StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
- _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
// mir::Constant
// + span: $DIR/slice_len.rs:5:6: 5:19
// + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff
index 300f0d5dc..b5f98233b 100644
--- a/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff
+++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff
@@ -6,7 +6,7 @@
let mut _0: (); // return place in scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:25
bb0: {
- Retag([fn entry] _1); // scope 0 at $DIR/provenance_soundness.rs:+0:1: +0:27
+ Retag([fn entry] _1); // scope 0 at $DIR/provenance_soundness.rs:+0:11: +0:13
_0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:27
return; // scope 0 at $DIR/provenance_soundness.rs:+0:27: +0:27
}
diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs
index 342e22243..ee59402af 100644
--- a/src/test/mir-opt/deaggregator_test.rs
+++ b/src/test/mir-opt/deaggregator_test.rs
@@ -1,3 +1,5 @@
+// unit-test: Deaggregator
+
struct Baz {
x: usize,
y: f32,
diff --git a/src/test/mir-opt/deaggregator_test_enum.rs b/src/test/mir-opt/deaggregator_test_enum.rs
index 02b63a1f5..ea402dafd 100644
--- a/src/test/mir-opt/deaggregator_test_enum.rs
+++ b/src/test/mir-opt/deaggregator_test_enum.rs
@@ -1,3 +1,5 @@
+// unit-test: Deaggregator
+
enum Baz {
Empty,
Foo { x: usize },
diff --git a/src/test/mir-opt/deaggregator_test_enum_2.rs b/src/test/mir-opt/deaggregator_test_enum_2.rs
index 489854ff0..955c31732 100644
--- a/src/test/mir-opt/deaggregator_test_enum_2.rs
+++ b/src/test/mir-opt/deaggregator_test_enum_2.rs
@@ -1,3 +1,4 @@
+// unit-test: Deaggregator
// Test that deaggregate fires in more than one basic block
enum Foo {
diff --git a/src/test/mir-opt/deaggregator_test_multiple.rs b/src/test/mir-opt/deaggregator_test_multiple.rs
index 9730b9aa8..46305fe21 100644
--- a/src/test/mir-opt/deaggregator_test_multiple.rs
+++ b/src/test/mir-opt/deaggregator_test_multiple.rs
@@ -1,3 +1,4 @@
+// unit-test: Deaggregator
// Test that deaggregate fires more than once per block
enum Foo {
diff --git a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
index 01864ba24..53f977de5 100644
--- a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
+++ b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
@@ -7,101 +7,94 @@
let mut _2: &[u8]; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
let mut _3: &str; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
let mut _4: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
- let mut _5: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
- let mut _6: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
- let mut _7: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
- scope 1 (inlined core::str::<impl str>::as_bytes) { // at $DIR/deduplicate_blocks.rs:3:11: 3:23
- debug self => _3; // in scope 1 at $SRC_DIR/core/src/str/mod.rs:LL:COL
- let mut _8: &str; // in scope 1 at $SRC_DIR/core/src/str/mod.rs:LL:COL
- scope 2 {
- }
- }
+ let mut _5: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ let mut _6: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ let mut _7: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ let mut _8: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ let mut _9: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
bb0: {
StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
- _3 = _1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
- StorageLive(_8); // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
- _8 = _3; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
-- _2 = transmute::<&str, &[u8]>(move _8) -> bb14; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
-+ _2 = transmute::<&str, &[u8]>(move _8) -> bb12; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
+ _3 = &(*_1); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
+ _2 = core::str::<impl str>::as_bytes(move _3) -> bb1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
// mir::Constant
- // + span: $SRC_DIR/core/src/str/mod.rs:LL:COL
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&str) -> &[u8] {transmute::<&str, &[u8]>}, val: Value(<ZST>) }
+ // + span: $DIR/deduplicate_blocks.rs:5:13: 5:21
+ // + literal: Const { ty: for<'r> fn(&'r str) -> &'r [u8] {core::str::<impl str>::as_bytes}, val: Value(<ZST>) }
}
bb1: {
- switchInt((*_2)[0 of 4]) -> [47_u8: bb2, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23
+ _7 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ _8 = const 4_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ _9 = Ge(move _7, move _8); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ switchInt(move _9) -> [false: bb6, otherwise: bb2]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
}
bb2: {
- switchInt((*_2)[1 of 4]) -> [47_u8: bb3, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ switchInt((*_2)[0 of 4]) -> [47_u8: bb3, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
}
bb3: {
- switchInt((*_2)[2 of 4]) -> [47_u8: bb4, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ switchInt((*_2)[1 of 4]) -> [47_u8: bb4, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
}
bb4: {
-- switchInt((*_2)[3 of 4]) -> [47_u8: bb10, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
-+ switchInt((*_2)[3 of 4]) -> [47_u8: bb9, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ switchInt((*_2)[2 of 4]) -> [47_u8: bb5, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
}
bb5: {
- _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
- _5 = Ge(move _4, const 3_usize); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
- switchInt(move _5) -> [false: bb9, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+- switchInt((*_2)[3 of 4]) -> [47_u8: bb11, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
++ switchInt((*_2)[3 of 4]) -> [47_u8: bb10, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
}
bb6: {
- switchInt((*_2)[0 of 3]) -> [47_u8: bb7, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ _5 = const 3_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ _6 = Ge(move _4, move _5); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
+ switchInt(move _6) -> [false: bb10, otherwise: bb7]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31
}
bb7: {
- switchInt((*_2)[1 of 3]) -> [47_u8: bb8, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ switchInt((*_2)[0 of 3]) -> [47_u8: bb8, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
}
bb8: {
-- switchInt((*_2)[2 of 3]) -> [47_u8: bb11, 33_u8: bb12, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
-+ switchInt((*_2)[2 of 3]) -> [47_u8: bb10, 33_u8: bb10, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ switchInt((*_2)[1 of 3]) -> [47_u8: bb9, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
}
bb9: {
+- switchInt((*_2)[2 of 3]) -> [47_u8: bb12, 33_u8: bb13, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
++ switchInt((*_2)[2 of 3]) -> [47_u8: bb11, 33_u8: bb11, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23
+ }
+
+ bb10: {
- _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
-- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19
- }
-
-- bb10: {
+- bb11: {
_0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
-- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
-+ goto -> bb11; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46
}
-- bb11: {
+- bb12: {
- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
-- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39
- }
-
-- bb12: {
-+ bb10: {
- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
-- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
-+ goto -> bb11; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
- }
-
- bb13: {
+ bb11: {
- StorageDead(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+7:1: +7:2
- return; // scope 0 at $DIR/deduplicate_blocks.rs:+7:2: +7:2
+ _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
+- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39
}
- bb14: {
+ bb12: {
- StorageDead(_8); // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL
- StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23
- _6 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
- _7 = Ge(move _6, const 4_usize); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
- switchInt(move _7) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37
+ StorageDead(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/deduplicate_blocks.rs:+7:2: +7:2
}
}
diff --git a/src/test/mir-opt/deduplicate_blocks.rs b/src/test/mir-opt/deduplicate_blocks.rs
index f8f7361dc..2b9eed99e 100644
--- a/src/test/mir-opt/deduplicate_blocks.rs
+++ b/src/test/mir-opt/deduplicate_blocks.rs
@@ -1,3 +1,5 @@
+// unit-test: DeduplicateBlocks
+
// EMIT_MIR deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff
pub const fn is_line_doc_comment_2(s: &str) -> bool {
match s.as_bytes() {
diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
index de0c03bb7..c353c375a 100644
--- a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
@@ -28,14 +28,14 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
- _14 = const main::promoted[0]; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
+ _14 = const _; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
// mir::Constant
- // + span: $DIR/derefer_complex_case.rs:5:17: 5:26
+ // + span: $DIR/derefer_complex_case.rs:6:17: 6:26
// + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) }
_2 = &(*_14); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
_1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> bb1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26
// mir::Constant
- // + span: $DIR/derefer_complex_case.rs:5:17: 5:26
+ // + span: $DIR/derefer_complex_case.rs:6:17: 6:26
// + literal: Const { ty: fn(&[i32; 2]) -> <&[i32; 2] as IntoIterator>::IntoIter {<&[i32; 2] as IntoIterator>::into_iter}, val: Value(<ZST>) }
}
@@ -55,7 +55,7 @@
_8 = &mut (*_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
_7 = <std::slice::Iter<i32> as Iterator>::next(move _8) -> bb3; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
// mir::Constant
- // + span: $DIR/derefer_complex_case.rs:5:17: 5:26
+ // + span: $DIR/derefer_complex_case.rs:6:17: 6:26
// + literal: Const { ty: for<'r> fn(&'r mut std::slice::Iter<i32>) -> Option<<std::slice::Iter<i32> as Iterator>::Item> {<std::slice::Iter<i32> as Iterator>::next}, val: Value(<ZST>) }
}
@@ -68,15 +68,13 @@
bb4: {
StorageLive(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
- _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
-+ StorageLive(_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
+ _15 = deref_copy ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
+ _12 = (*_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13
-+ StorageDead(_15); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37
StorageLive(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37
_13 = _12; // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37
_6 = std::mem::drop::<i32>(move _13) -> bb7; // scope 2 at $DIR/derefer_complex_case.rs:+1:29: +1:38
// mir::Constant
- // + span: $DIR/derefer_complex_case.rs:5:29: 5:33
+ // + span: $DIR/derefer_complex_case.rs:6:29: 6:33
// + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) }
}
diff --git a/src/test/mir-opt/derefer_complex_case.rs b/src/test/mir-opt/derefer_complex_case.rs
index 48bec3907..dc48cee95 100644
--- a/src/test/mir-opt/derefer_complex_case.rs
+++ b/src/test/mir-opt/derefer_complex_case.rs
@@ -1,3 +1,4 @@
+// unit-test: Derefer
// EMIT_MIR derefer_complex_case.main.Derefer.diff
// ignore-wasm32
diff --git a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
index ce6ffaa56..3540df308 100644
--- a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
@@ -17,7 +17,7 @@
_3 = AlignOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12
// mir::Constant
- // + span: $DIR/derefer_inline_test.rs:10:5: 10:12
+ // + span: $DIR/derefer_inline_test.rs:11:5: 11:12
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
}
@@ -26,7 +26,7 @@
_5 = ShallowInitBox(move _4, std::boxed::Box<u32>); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12
(*_5) = f() -> [return: bb2, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:+1:9: +1:12
// mir::Constant
- // + span: $DIR/derefer_inline_test.rs:10:9: 10:10
+ // + span: $DIR/derefer_inline_test.rs:11:9: 11:10
// + literal: Const { ty: fn() -> Box<u32> {f}, val: Value(<ZST>) }
}
diff --git a/src/test/mir-opt/derefer_inline_test.rs b/src/test/mir-opt/derefer_inline_test.rs
index 191a8cbbe..cc06a7dd8 100644
--- a/src/test/mir-opt/derefer_inline_test.rs
+++ b/src/test/mir-opt/derefer_inline_test.rs
@@ -1,3 +1,4 @@
+// unit-test: Derefer
// EMIT_MIR derefer_inline_test.main.Derefer.diff
// ignore-wasm32 compiled with panic=abort by default
diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
index 0a56ee5e4..60f7b9d56 100644
--- a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
@@ -32,7 +32,7 @@
StorageLive(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10
_1 = foo() -> bb1; // scope 0 at $DIR/derefer_terminator_test.rs:+1:13: +1:18
// mir::Constant
- // + span: $DIR/derefer_terminator_test.rs:5:13: 5:16
+ // + span: $DIR/derefer_terminator_test.rs:6:13: 6:16
// + literal: Const { ty: fn() -> bool {foo}, val: Value(<ZST>) }
}
@@ -40,7 +40,7 @@
StorageLive(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10
_2 = foo() -> bb2; // scope 1 at $DIR/derefer_terminator_test.rs:+2:13: +2:18
// mir::Constant
- // + span: $DIR/derefer_terminator_test.rs:6:13: 6:16
+ // + span: $DIR/derefer_terminator_test.rs:7:13: 7:16
// + literal: Const { ty: fn() -> bool {foo}, val: Value(<ZST>) }
}
@@ -55,25 +55,18 @@
_5 = &_6; // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21
_4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22
- switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
-+ StorageLive(_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ _10 = deref_copy (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
-+ StorageLive(_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ _11 = deref_copy (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
-+ StorageDead(_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
-+ StorageLive(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ _12 = deref_copy (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
-+ StorageDead(_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
+ switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
}
bb3: {
-+ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
_3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20
goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20
}
bb4: {
-+ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22
StorageLive(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23
_8 = const 5_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+4:26: +4:27
_3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+4:17: +4:29
diff --git a/src/test/mir-opt/derefer_terminator_test.rs b/src/test/mir-opt/derefer_terminator_test.rs
index 787b14ae7..d6750c29d 100644
--- a/src/test/mir-opt/derefer_terminator_test.rs
+++ b/src/test/mir-opt/derefer_terminator_test.rs
@@ -1,3 +1,4 @@
+// unit-test: Derefer
// EMIT_MIR derefer_terminator_test.main.Derefer.diff
// ignore-wasm32
diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff
index 6c2047e21..87306d818 100644
--- a/src/test/mir-opt/derefer_test.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_test.main.Derefer.diff
@@ -33,16 +33,12 @@
StorageDead(_3); // scope 1 at $DIR/derefer_test.rs:+2:28: +2:29
StorageLive(_4); // scope 2 at $DIR/derefer_test.rs:+3:9: +3:10
- _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
-+ StorageLive(_6); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
+ _6 = deref_copy (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
+ _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26
-+ StorageDead(_6); // scope 3 at $DIR/derefer_test.rs:+4:9: +4:10
StorageLive(_5); // scope 3 at $DIR/derefer_test.rs:+4:9: +4:10
- _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
-+ StorageLive(_7); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
+ _7 = deref_copy (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
+ _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26
-+ StorageDead(_7); // scope 0 at $DIR/derefer_test.rs:+0:11: +5:2
_0 = const (); // scope 0 at $DIR/derefer_test.rs:+0:11: +5:2
StorageDead(_5); // scope 3 at $DIR/derefer_test.rs:+5:1: +5:2
StorageDead(_4); // scope 2 at $DIR/derefer_test.rs:+5:1: +5:2
diff --git a/src/test/mir-opt/derefer_test.rs b/src/test/mir-opt/derefer_test.rs
index 2ebc0d343..fad0fe8eb 100644
--- a/src/test/mir-opt/derefer_test.rs
+++ b/src/test/mir-opt/derefer_test.rs
@@ -1,3 +1,4 @@
+// unit-test: Derefer
// EMIT_MIR derefer_test.main.Derefer.diff
fn main() {
let mut a = (42,43);
diff --git a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
index e2dceecfd..3e40db118 100644
--- a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
@@ -57,28 +57,16 @@
StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:28: +4:29
StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:+5:9: +5:10
- _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
-+ StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
+ _10 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
-+ StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
+ _11 = deref_copy ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
-+ StorageDead(_10); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
-+ StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
+ _12 = deref_copy ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
-+ StorageDead(_11); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
+ _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30
-+ StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10
StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10
- _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
-+ StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
+ _13 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
-+ StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
+ _14 = deref_copy ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
-+ StorageDead(_13); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
-+ StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
+ _15 = deref_copy ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
-+ StorageDead(_14); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
+ _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30
-+ StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +7:2
_0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +7:2
StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
StorageDead(_8); // scope 4 at $DIR/derefer_test_multiple.rs:+7:1: +7:2
diff --git a/src/test/mir-opt/derefer_test_multiple.rs b/src/test/mir-opt/derefer_test_multiple.rs
index a27363447..0b3888b07 100644
--- a/src/test/mir-opt/derefer_test_multiple.rs
+++ b/src/test/mir-opt/derefer_test_multiple.rs
@@ -1,3 +1,4 @@
+// unit-test: Derefer
// EMIT_MIR derefer_test_multiple.main.Derefer.diff
fn main () {
let mut a = (42, 43);
diff --git a/src/test/mir-opt/dest-prop/union.rs b/src/test/mir-opt/dest-prop/union.rs
index 68c834dfb..eb6cb09fc 100644
--- a/src/test/mir-opt/dest-prop/union.rs
+++ b/src/test/mir-opt/dest-prop/union.rs
@@ -1,4 +1,4 @@
-//! Tests that we can propogate into places that are projections into unions
+//! Tests that we can propagate into places that are projections into unions
// compile-flags: -Zunsound-mir-opts
fn val() -> u32 {
1
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.rs b/src/test/mir-opt/early_otherwise_branch_68867.rs
index ca298e921..a6a56f3a9 100644
--- a/src/test/mir-opt/early_otherwise_branch_68867.rs
+++ b/src/test/mir-opt/early_otherwise_branch_68867.rs
@@ -1,4 +1,6 @@
-// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
+// unit-test: EarlyOtherwiseBranch
+
+// FIXME: This test was broken by the derefer change.
// example from #68867
type CSSFloat = f32;
@@ -11,7 +13,6 @@ pub enum ViewportPercentageLength {
}
// EMIT_MIR early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
-// EMIT_MIR early_otherwise_branch_68867.try_sum EarlyOtherwiseBranch.before SimplifyConstCondition-final.after
#[no_mangle]
pub extern "C" fn try_sum(
x: &ViewportPercentageLength,
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
deleted file mode 100644
index 4e6852ad7..000000000
--- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
+++ /dev/null
@@ -1,344 +0,0 @@
-- // MIR for `try_sum` before EarlyOtherwiseBranch
-+ // MIR for `try_sum` after SimplifyConstCondition-final
-
- fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result<ViewportPercentageLength, ()> {
- debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+1:5: +1:6
- debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+2:5: +2:10
- let mut _0: std::result::Result<ViewportPercentageLength, ()>; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:+3:6: +3:42
- let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
- let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
- let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
- let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:21: +6:30
- let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:21: +7:30
- let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:23: +8:34
- let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:23: +9:34
- let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:11: +6:18
- let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
- let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
- let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
- let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
- let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
- let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
- let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
- let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
- let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
- let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
- let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
- let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
- let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:14: +10:28
- let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
- let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- scope 1 {
-- debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
-- debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
-+ debug one => _15; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
-+ debug other => _16; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- }
- scope 2 {
-- debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
-- debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
-+ debug one => _20; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
-+ debug other => _21; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- }
- scope 3 {
-- debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
-- debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
-+ debug one => _25; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
-+ debug other => _26; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- }
- scope 4 {
-- debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
-- debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
-+ debug one => _30; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
-+ debug other => _31; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- }
-
- bb0: {
-- StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
-- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
-- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
-- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
-+ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
- StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
- _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
- Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
-- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
-- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
- StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- }
-
- bb1: {
- StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- }
-
- bb2: {
- StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
- Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
- discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
- StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
-- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
-- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
- }
-
- bb3: {
- StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- }
-
- bb4: {
- StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- }
-
- bb5: {
- StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
- }
-
- bb6: {
-- StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
-- _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
-+ _15 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
-- StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
-- _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
-+ _16 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
-- StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
-- StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
-- _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
-- StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
-- _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
-- _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
-- StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
-- StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
-- Deinit(_3); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
-- ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
-- discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
-- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
-- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
-- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
-+ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
-+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
-+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
-+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
- }
-
- bb7: {
-- StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
-- _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
-+ _20 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
-- StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
-- _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
-+ _21 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
-- StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
-- StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
-- _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
-- StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
-- _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
-- _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
-- StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
-- StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
-- Deinit(_3); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
-- ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
-- discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
-- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
-- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
-- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
-+ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
-+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
-+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
-+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
- }
-
- bb8: {
-- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
-- _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
-+ _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
-- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
-- _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
-+ _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
-- StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
-- StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
-- _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
-- StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
-- _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
-- _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
-- StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
-- StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
-- Deinit(_3); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
-- ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
-- discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
-- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
-- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
-- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
-+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
-+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
-+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
-+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
- }
-
- bb9: {
-- StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
-- _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
-+ _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
-- StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
-- _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
-+ _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
-- StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
-- StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
-- _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
-- StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
-- _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
-- _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
-- StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
-- StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
-- Deinit(_3); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
-- ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
-- discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
-- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
-- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
-- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
-+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
-+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
-+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
-+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
- }
-
- bb10: {
- Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
-- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
- discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
-- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
-- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
-+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
- }
- }
-
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
index 2519f79f8..6bc025bb5 100644
--- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
+++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
@@ -78,68 +78,54 @@
(_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
- StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb1: {
- StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb2: {
StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
+ Deinit(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
+ ((_0 as Err).0: ()) = move _33; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
bb3: {
- StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb4: {
- StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb5: {
- StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb6: {
StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
_39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
_12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
_40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
_13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
_15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
@@ -159,15 +145,11 @@
bb7: {
StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
_41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
_17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
_42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
_18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
_20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
@@ -187,15 +169,11 @@
bb8: {
StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
_43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
_22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
_44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
_23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
_25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
@@ -215,15 +193,11 @@
bb9: {
StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
_45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
_27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
_46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
_28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
_30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
@@ -247,6 +221,10 @@
discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
+ }
+
+ bb11: {
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
}
diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
index 3d7b3f75a..9e089b01b 100644
--- a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
+++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
@@ -16,10 +16,8 @@
}
bb1: {
- StorageLive(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
_4 = deref_copy (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
_2 = discriminant((*_4)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
- StorageDead(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31
}
diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
index afca2fd29..59ec80915 100644
--- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
@@ -3,11 +3,15 @@
fn bar(_1: Bar) -> usize {
debug bar => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
- let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let _2: Bar; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
- _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _3 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
index c79596d78..f6903c1ec 100644
--- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
@@ -3,11 +3,15 @@
fn boo(_1: Boo) -> usize {
debug boo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
- let mut _2: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let _2: Boo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _3: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
- _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _3 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
index 8ced136db..98e1f8e11 100644
--- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
@@ -4,8 +4,9 @@ fn droppy() -> () {
let mut _0: (); // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13
let _1: (); // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
let _2: Droppy; // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
- let mut _4: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
- let _5: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ let _4: Droppy; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+ let mut _5: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+ let _6: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
scope 1 {
debug x => _2; // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14
scope 2 {
@@ -16,7 +17,7 @@ fn droppy() -> () {
}
}
scope 4 {
- debug z => _5; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
+ debug z => _6; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
}
bb0: {
@@ -25,30 +26,41 @@ fn droppy() -> () {
_2 = Droppy::C; // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26
FakeRead(ForLet(None), _2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
StorageLive(_3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
- _4 = discriminant(_2); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
- _3 = move _4 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ StorageLive(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+ _4 = move _2; // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+ _5 = discriminant(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _3 = move _5 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
_1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6
- drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ drop(_2) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
}
- bb1: {
+ bb2: {
StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
- StorageLive(_5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
- _5 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
- FakeRead(ForLet(None), _5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ StorageLive(_6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ _6 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
+ FakeRead(ForLet(None), _6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
_0 = const (); // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2
- drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ drop(_6) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
}
- bb2: {
- StorageDead(_5); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ bb3: {
+ StorageDead(_6); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2
}
- bb3 (cleanup): {
+ bb4 (cleanup): {
+ drop(_2) -> bb5; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+ }
+
+ bb5 (cleanup): {
resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2
}
}
diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
index 39d6adeba..aaa2d2646 100644
--- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
@@ -3,11 +3,15 @@
fn foo(_1: Foo) -> usize {
debug foo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
- let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let _2: Foo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
- _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _0 = move _3 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/equal_true.rs b/src/test/mir-opt/equal_true.rs
index 994cd194a..717d10c6d 100644
--- a/src/test/mir-opt/equal_true.rs
+++ b/src/test/mir-opt/equal_true.rs
@@ -1,3 +1,5 @@
+// unit-test InstCombine
+
// EMIT_MIR equal_true.opt.InstCombine.diff
fn opt(x: bool) -> i32 {
diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
index d39145973..96716a39a 100644
--- a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
@@ -8,13 +8,13 @@ fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 {
let mut _4: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
let mut _5: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
let mut _6: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
- let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:21
- let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:78
+ let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:11
+ let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:58
let mut _9: u32; // in scope 0 at $DIR/exponential-or.rs:+2:83: +2:84
let mut _10: u32; // in scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
scope 1 {
- debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:21
- debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:78
+ debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:11
+ debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:58
}
bb0: {
@@ -61,10 +61,10 @@ fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 {
}
bb9: {
- StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21
- _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21
- StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78
- _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78
+ StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11
+ _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11
+ StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58
+ _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58
StorageLive(_9); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84
_9 = _7; // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84
StorageLive(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
index 09765c7b9..c718138b6 100644
--- a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
+++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
@@ -15,21 +15,21 @@
} */
fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 10:17]) -> () {
- let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
- let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15
let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14
let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14
let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:18: +0:18
- let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
- let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
scope 1 {
debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15
}
bb0: {
- _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
- switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb1: {
@@ -44,11 +44,11 @@ fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 1
}
bb3: {
- return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb4 (cleanup): {
- resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb5 (cleanup): {
@@ -57,11 +57,11 @@ fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 1
}
bb6: {
- return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb7: {
- goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb8: {
@@ -69,16 +69,16 @@ fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 1
}
bb9: {
- goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb10: {
- StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
- StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
- goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
bb11: {
- return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17
+ return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
}
}
diff --git a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
index cb6ed3321..3184343f2 100644
--- a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
+++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
@@ -21,15 +21,13 @@ yields ()
bb0: {
StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
- Deinit(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23
- (_3.0: i32) = const 5_i32; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23
+ _3 = Foo(const 5_i32); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23
StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
- Deinit(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23
- (_4.0: i32) = const 6_i32; // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23
+ _4 = Bar(const 6_i32); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23
StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- Deinit(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- _5 = yield(move _6) -> [resume: bb1, drop: bb5]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ _6 = (); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
}
bb1: {
@@ -38,7 +36,7 @@ yields ()
StorageLive(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
StorageLive(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
_8 = move _3; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
- _7 = take::<Foo>(move _8) -> [return: bb2, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
+ _7 = take::<Foo>(move _8) -> [return: bb2, unwind: bb10]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
// mir::Constant
// + span: $DIR/generator-storage-dead-unwind.rs:26:9: 26:13
// + literal: Const { ty: fn(Foo) {take::<Foo>}, val: Value(<ZST>) }
@@ -50,7 +48,7 @@ yields ()
StorageLive(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
StorageLive(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
_10 = move _4; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
- _9 = take::<Bar>(move _10) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
+ _9 = take::<Bar>(move _10) -> [return: bb3, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
// mir::Constant
// + span: $DIR/generator-storage-dead-unwind.rs:27:9: 27:13
// + literal: Const { ty: fn(Bar) {take::<Bar>}, val: Value(<ZST>) }
@@ -61,54 +59,66 @@ yields ()
StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17
_0 = const (); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +6:6
StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> [return: bb4, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ goto -> bb4; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
}
bb4: {
- return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:18: +0:18
+ StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
}
bb5: {
+ return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:6: +6:6
+ }
+
+ bb6: {
StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14
StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15
StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_3) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
}
- bb6: {
+ bb7: {
StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
}
- bb7: {
- generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18
+ bb8: {
+ generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +6:6
}
- bb8 (cleanup): {
+ bb9 (cleanup): {
StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16
StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17
- goto -> bb10; // scope 2 at no-location
+ goto -> bb12; // scope 2 at no-location
}
- bb9 (cleanup): {
+ bb10 (cleanup): {
+ goto -> bb11; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
+ }
+
+ bb11 (cleanup): {
StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17
- goto -> bb10; // scope 2 at no-location
+ goto -> bb12; // scope 2 at no-location
}
- bb10 (cleanup): {
+ bb12 (cleanup): {
StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ goto -> bb13; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ }
+
+ bb13 (cleanup): {
StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
}
- bb11 (cleanup): {
- resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18
+ bb14 (cleanup): {
+ resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +6:6
}
- bb12 (cleanup): {
+ bb15 (cleanup): {
StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
}
}
diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
index 62e7d7b2d..07aeeaae0 100644
--- a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
+++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
@@ -16,29 +16,29 @@
fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> {
debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19
- let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
let _3: HasDrop; // in scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15
let mut _4: !; // in scope 0 at $DIR/generator-tiny.rs:+2:9: +5:10
- let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
let _6: u8; // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18
let mut _7: (); // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18
let _8: (); // in scope 0 at $DIR/generator-tiny.rs:+4:13: +4:21
let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:+0:25: +0:25
let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19
- let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
scope 1 {
debug _d => (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator-tiny.rs:+1:13: +1:15
}
bb0: {
- _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
- switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
}
bb1: {
- _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
nop; // scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15
- Deinit((((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop)); // scope 0 at $DIR/generator-tiny.rs:+1:18: +1:25
+ (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator-tiny.rs:+1:18: +1:25
StorageLive(_4); // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
}
@@ -46,7 +46,7 @@ fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24
bb2: {
StorageLive(_6); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
StorageLive(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- Deinit(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ _7 = (); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
Deinit(_0); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
discriminant(_0) = 0; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
@@ -71,14 +71,14 @@ fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24
}
bb5: {
- StorageLive(_4); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
- StorageLive(_6); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
- StorageLive(_7); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
- _6 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
- goto -> bb3; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ StorageLive(_4); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ StorageLive(_6); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ StorageLive(_7); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ _6 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ goto -> bb3; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
}
bb6: {
- unreachable; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24
+ unreachable; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
}
}
diff --git a/src/test/mir-opt/inline/cycle.g.Inline.diff b/src/test/mir-opt/inline/cycle.g.Inline.diff
index 59f34d379..5f3ee467c 100644
--- a/src/test/mir-opt/inline/cycle.g.Inline.diff
+++ b/src/test/mir-opt/inline/cycle.g.Inline.diff
@@ -6,10 +6,10 @@
let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:12
+ let mut _2: fn() {main}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:12
+ scope 1 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12
-+ debug g => _2; // in scope 1 at $DIR/cycle.rs:+0:6: +0:7
-+ let _3: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
-+ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:+0:5: +0:6
-+ let mut _5: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ debug g => _2; // in scope 1 at $DIR/cycle.rs:5:6: 5:7
++ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
++ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6
++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
+ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
+ }
+ }
@@ -25,10 +25,10 @@
- // mir::Constant
// + span: $DIR/cycle.rs:12:7: 12:11
// + literal: Const { ty: fn() {main}, val: Value(<ZST>) }
-+ StorageLive(_3); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
-+ StorageLive(_4); // scope 1 at $DIR/cycle.rs:+0:5: +0:6
-+ _4 = &_2; // scope 1 at $DIR/cycle.rs:+0:5: +0:6
-+ StorageLive(_5); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8
+ _3 = move (*_4)() -> [return: bb4, unwind: bb2]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL
}
@@ -40,18 +40,18 @@
+ }
+
+ bb2 (cleanup): {
-+ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+
+ bb3 (cleanup): {
-+ resume; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
+ }
+
+ bb4: {
-+ StorageDead(_5); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
-+ StorageDead(_4); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
-+ StorageDead(_3); // scope 1 at $DIR/cycle.rs:+0:8: +0:9
-+ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
}
}
diff --git a/src/test/mir-opt/inline/cycle.main.Inline.diff b/src/test/mir-opt/inline/cycle.main.Inline.diff
index 6def7c3ee..8b4099b9d 100644
--- a/src/test/mir-opt/inline/cycle.main.Inline.diff
+++ b/src/test/mir-opt/inline/cycle.main.Inline.diff
@@ -6,17 +6,17 @@
let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:9
+ let mut _2: fn() {g}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:9
+ scope 1 (inlined f::<fn() {g}>) { // at $DIR/cycle.rs:17:5: 17:9
-+ debug g => _2; // in scope 1 at $DIR/cycle.rs:+0:6: +0:7
-+ let _3: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
-+ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:+0:5: +0:6
-+ let mut _5: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8
++ debug g => _2; // in scope 1 at $DIR/cycle.rs:5:6: 5:7
++ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
++ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6
++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
+ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) { // at $DIR/cycle.rs:6:5: 6:8
+ scope 3 (inlined g) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
-+ let mut _6: fn() {main}; // in scope 3 at $DIR/cycle.rs:+0:5: +0:12
++ let mut _6: fn() {main}; // in scope 3 at $DIR/cycle.rs:12:5: 12:12
+ scope 4 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12
-+ debug g => _6; // in scope 4 at $DIR/cycle.rs:+0:6: +0:7
-+ let _7: (); // in scope 4 at $DIR/cycle.rs:+0:5: +0:8
-+ let mut _8: &fn() {main}; // in scope 4 at $DIR/cycle.rs:+0:5: +0:6
++ debug g => _6; // in scope 4 at $DIR/cycle.rs:5:6: 5:7
++ let _7: (); // in scope 4 at $DIR/cycle.rs:6:5: 6:8
++ let mut _8: &fn() {main}; // in scope 4 at $DIR/cycle.rs:6:5: 6:6
+ scope 5 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
+ }
+ }
@@ -35,14 +35,14 @@
- // mir::Constant
// + span: $DIR/cycle.rs:17:7: 17:8
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
-+ StorageLive(_3); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
-+ StorageLive(_4); // scope 1 at $DIR/cycle.rs:+0:5: +0:6
-+ _4 = &_2; // scope 1 at $DIR/cycle.rs:+0:5: +0:6
-+ StorageLive(_5); // scope 1 at $DIR/cycle.rs:+0:5: +0:8
-+ StorageLive(_6); // scope 3 at $DIR/cycle.rs:+0:5: +0:12
-+ StorageLive(_7); // scope 4 at $DIR/cycle.rs:+0:5: +0:8
-+ StorageLive(_8); // scope 4 at $DIR/cycle.rs:+0:5: +0:6
-+ _8 = &_6; // scope 4 at $DIR/cycle.rs:+0:5: +0:6
++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6
++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ StorageLive(_6); // scope 3 at $DIR/cycle.rs:12:5: 12:12
++ StorageLive(_7); // scope 4 at $DIR/cycle.rs:6:5: 6:8
++ StorageLive(_8); // scope 4 at $DIR/cycle.rs:6:5: 6:6
++ _8 = &_6; // scope 4 at $DIR/cycle.rs:6:5: 6:6
+ _7 = move (*_8)() -> [return: bb4, unwind: bb2]; // scope 5 at $SRC_DIR/core/src/ops/function.rs:LL:COL
}
@@ -54,21 +54,21 @@
+ }
+
+ bb2 (cleanup): {
-+ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+
+ bb3 (cleanup): {
-+ resume; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
+ }
+
+ bb4: {
-+ StorageDead(_8); // scope 4 at $DIR/cycle.rs:+0:7: +0:8
-+ StorageDead(_7); // scope 4 at $DIR/cycle.rs:+0:8: +0:9
-+ StorageDead(_6); // scope 3 at $DIR/cycle.rs:+0:5: +0:12
-+ StorageDead(_5); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
-+ StorageDead(_4); // scope 1 at $DIR/cycle.rs:+0:7: +0:8
-+ StorageDead(_3); // scope 1 at $DIR/cycle.rs:+0:8: +0:9
-+ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:+0:1: +0:2
++ StorageDead(_8); // scope 4 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_7); // scope 4 at $DIR/cycle.rs:6:8: 6:9
++ StorageDead(_6); // scope 3 at $DIR/cycle.rs:12:5: 12:12
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
}
}
diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
index 8eae04c4d..4b50ba950 100644
--- a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
+++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
@@ -10,12 +10,12 @@
scope 1 {
debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+1:9: +1:10
+ scope 2 (inlined try_execute_query::<<Q as Query>::C>) { // at $DIR/dyn-trait.rs:34:5: 34:25
-+ debug c => _4; // in scope 2 at $DIR/dyn-trait.rs:+0:36: +0:37
-+ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
-+ let mut _6: &<Q as Query>::C; // in scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
++ debug c => _4; // in scope 2 at $DIR/dyn-trait.rs:26:36: 26:37
++ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++ let mut _6: &<Q as Query>::C; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
+ scope 3 (inlined mk_cycle::<<Q as Query>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
-+ debug c => _5; // in scope 3 at $DIR/dyn-trait.rs:+0:27: +0:28
-+ let mut _7: &dyn Cache<V = <Q as Query>::V>; // in scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
++ debug c => _5; // in scope 3 at $DIR/dyn-trait.rs:20:27: 20:28
++ let mut _7: &dyn Cache<V = <Q as Query>::V>; // in scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
+ }
+ }
}
@@ -36,14 +36,14 @@
StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24
_4 = &(*_2); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24
- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn-trait.rs:+2:5: +2:25
-+ StorageLive(_5); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
-+ StorageLive(_6); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
-+ _6 = _4; // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
-+ _5 = move _6 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
-+ StorageDead(_6); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15
-+ StorageLive(_7); // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
-+ _7 = _5; // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
-+ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22
++ StorageLive(_5); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++ StorageLive(_6); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++ _6 = _4; // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++ _5 = move _6 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++ StorageDead(_6); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++ StorageLive(_7); // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
++ _7 = _5; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
++ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
// mir::Constant
- // + span: $DIR/dyn-trait.rs:34:5: 34:22
- // + literal: Const { ty: for<'r> fn(&'r <Q as Query>::C) {try_execute_query::<<Q as Query>::C>}, val: Value(<ZST>) }
@@ -52,8 +52,8 @@
}
bb2: {
-+ StorageDead(_7); // scope 3 at $DIR/dyn-trait.rs:+0:21: +0:22
-+ StorageDead(_5); // scope 2 at $DIR/dyn-trait.rs:+0:15: +0:16
++ StorageDead(_7); // scope 3 at $DIR/dyn-trait.rs:21:21: 21:22
++ StorageDead(_5); // scope 2 at $DIR/dyn-trait.rs:27:15: 27:16
StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+2:24: +2:25
StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+3:1: +3:2
return; // scope 0 at $DIR/dyn-trait.rs:+3:2: +3:2
diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
index e7c5972f4..58c05b9f5 100644
--- a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
+++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
@@ -7,8 +7,8 @@
let mut _2: &dyn Cache<V = <C as Cache>::V>; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
let mut _3: &C; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
+ scope 1 (inlined mk_cycle::<<C as Cache>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
-+ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+0:27: +0:28
-+ let mut _4: &dyn Cache<V = <C as Cache>::V>; // in scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
++ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:20:27: 20:28
++ let mut _4: &dyn Cache<V = <C as Cache>::V>; // in scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
+ }
bb0: {
@@ -18,9 +18,9 @@
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:16
-+ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
-+ _4 = _2; // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
-+ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22
++ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
++ _4 = _2; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
++ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
// mir::Constant
- // + span: $DIR/dyn-trait.rs:27:5: 27:13
- // + literal: Const { ty: for<'r> fn(&'r (dyn Cache<V = <C as Cache>::V> + 'r)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) }
@@ -29,7 +29,7 @@
}
bb1: {
-+ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+0:21: +0:22
++ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:21:21: 21:22
StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:15: +1:16
return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs
index 049a97816..232bcc7b2 100644
--- a/src/test/mir-opt/inline/inline-into-box-place.rs
+++ b/src/test/mir-opt/inline/inline-into-box-place.rs
@@ -1,7 +1,7 @@
// ignore-endian-big
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: -Z mir-opt-level=4
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
#![feature(box_syntax)]
// EMIT_MIR inline_into_box_place.main.Inline.diff
fn main() {
diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
index 630225258..b27425fb1 100644
--- a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
@@ -9,10 +9,10 @@ fn bar() -> bool {
scope 1 {
debug f => _1; // in scope 1 at $DIR/inline-any-operand.rs:+1:9: +1:10
scope 2 (inlined foo) { // at $DIR/inline-any-operand.rs:12:5: 12:13
- debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:+6:8: +6:9
- debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:+6:16: +6:17
- let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6
- let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:16:8: 16:9
+ debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:16:16: 16:17
+ let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6
+ let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
}
}
@@ -28,13 +28,13 @@ fn bar() -> bool {
_3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
_4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6
- _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6
- StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
- _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
- _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:11
- StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
- StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11
+ StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6
+ _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6
+ StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
+ _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
+ _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:11
+ StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
+ StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:12: +2:13
diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
index d60b06460..a2234e7c1 100644
--- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
@@ -19,8 +19,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:17: +0:18
let mut _10: i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
let mut _11: T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:17
- let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:17
+ let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:24
}
}
@@ -45,15 +45,11 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
StorageLive(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
_9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
- StorageLive(_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
_12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
_10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
- StorageDead(_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- StorageLive(_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
_13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
_11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- StorageDead(_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
(_0.0: i32) = move _10; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
(_0.1: T) = move _11; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
index b1c476362..a4d706de0 100644
--- a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
+++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
@@ -14,7 +14,7 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
-+ _1 = <C as Call>::call() -> bb1; // scope 3 at $DIR/inline-cycle.rs:+23:9: +23:28
++ _1 = <C as Call>::call() -> bb1; // scope 3 at $DIR/inline-cycle.rs:36:9: 36:28
// mir::Constant
- // + span: $DIR/inline-cycle.rs:14:5: 14:22
+ // + span: $DIR/inline-cycle.rs:36:9: 36:26
diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
index dc890a365..b1a5b62ef 100644
--- a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
+++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
@@ -6,13 +6,13 @@
let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
+ let mut _2: fn() {f}; // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
+ scope 1 (inlined call::<fn() {f}>) { // at $DIR/inline-cycle.rs:49:5: 49:12
-+ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:+5:22: +5:23
-+ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
-+ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6
-+ let mut _5: (); // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
++ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:53:22: 53:23
++ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
++ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:6
++ let mut _5: (); // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
+ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline-cycle.rs:54:5: 54:8
+ scope 3 (inlined f) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
-+ let _6: (); // in scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12
++ let _6: (); // in scope 3 at $DIR/inline-cycle.rs:59:5: 59:12
+ }
+ }
+ }
@@ -26,12 +26,12 @@
- // + span: $DIR/inline-cycle.rs:49:5: 49:9
+ // + span: $DIR/inline-cycle.rs:49:10: 49:11
+ // + literal: Const { ty: fn() {f}, val: Value(<ZST>) }
-+ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
-+ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6
-+ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6
-+ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8
-+ StorageLive(_6); // scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12
-+ _6 = call::<fn() {f}>(f) -> bb1; // scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12
++ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
++ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:6
++ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:54:5: 54:6
++ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
++ StorageLive(_6); // scope 3 at $DIR/inline-cycle.rs:59:5: 59:12
++ _6 = call::<fn() {f}>(f) -> bb1; // scope 3 at $DIR/inline-cycle.rs:59:5: 59:12
+ // mir::Constant
+ // + span: $DIR/inline-cycle.rs:59:5: 59:9
// + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) }
@@ -42,10 +42,10 @@
}
bb1: {
-+ StorageDead(_6); // scope 3 at $DIR/inline-cycle.rs:+11:12: +11:13
-+ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:+6:7: +6:8
-+ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:+6:7: +6:8
-+ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:+6:8: +6:9
++ StorageDead(_6); // scope 3 at $DIR/inline-cycle.rs:59:12: 59:13
++ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:54:7: 54:8
++ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:54:7: 54:8
++ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:54:8: 54:9
+ StorageDead(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:12: +1:13
_0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2
diff --git a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
index 082f57e59..fc5d57ce8 100644
--- a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
@@ -16,7 +16,7 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
-+ _1 = <C as Call>::call() -> bb1; // scope 4 at $DIR/inline-cycle-generic.rs:+23:9: +23:28
++ _1 = <C as Call>::call() -> bb1; // scope 4 at $DIR/inline-cycle-generic.rs:31:9: 31:28
// mir::Constant
- // + span: $DIR/inline-cycle-generic.rs:9:5: 9:22
+ // + span: $DIR/inline-cycle-generic.rs:31:9: 31:26
diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
index 6b24b3e16..cef4cfc67 100644
--- a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
+++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
@@ -18,7 +18,7 @@
+ }
+
+ bb1: {
-+ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:+32:5: +32:12
++ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:39:5: 39:12
}
}
diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
index 8759f3d02..6569ab24c 100644
--- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
+++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
@@ -6,19 +6,19 @@
let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22
-+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:+5:36: +5:37
-+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:+6:9: +6:10
-+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14
-+ let mut _5: (); // in scope 1 at $DIR/inline-diverging.rs:+6:13: +6:16
-+ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:+7:13: +7:14
-+ let mut _8: (); // in scope 1 at $DIR/inline-diverging.rs:+7:13: +7:16
-+ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:+8:6: +8:7
-+ let mut _10: !; // in scope 1 at $DIR/inline-diverging.rs:+8:9: +8:10
++ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37
++ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
++ let mut _5: (); // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14
++ let mut _8: (); // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:16
++ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7
++ let mut _10: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10
+ scope 2 {
-+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:+6:9: +6:10
-+ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:+7:9: +7:10
++ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10
++ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10
+ scope 3 {
-+ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:+7:9: +7:10
++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10
+ }
+ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16
+ scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
@@ -42,15 +42,15 @@
- // mir::Constant
// + span: $DIR/inline-diverging.rs:22:16: 22:21
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) }
-+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:+6:9: +6:10
-+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14
-+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14
-+ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:16
-+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:+18:5: +18:12
++ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
++ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
++ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
+ }
+
+ bb1: {
-+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:+18:5: +18:12
++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
}
}
diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
index c7c2759cc..0b992e3c3 100644
--- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
@@ -24,15 +24,15 @@
+ }
+ }
+ scope 6 (inlined g::{closure#0}) { // at $DIR/inline-generator.rs:9:14: 9:46
-+ debug a => _11; // in scope 6 at $DIR/inline-generator.rs:+7:6: +7:7
-+ let mut _8: i32; // in scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
-+ let mut _9: bool; // in scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
-+ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:+7:9: +7:9
-+ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:+7:6: +7:7
-+ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ debug a => _11; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7
++ let mut _8: i32; // in scope 6 at $DIR/inline-generator.rs:15:17: 15:39
++ let mut _9: bool; // in scope 6 at $DIR/inline-generator.rs:15:20: 15:21
++ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:15:9: 15:9
++ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7
++ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
+ }
bb0: {
@@ -47,8 +47,8 @@
- }
-
- bb1: {
-+ Deinit(_4); // scope 2 at $DIR/inline-generator.rs:+7:5: +7:41
-+ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:+7:5: +7:41
++ Deinit(_4); // scope 2 at $DIR/inline-generator.rs:15:5: 15:41
++ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:15:5: 15:41
_3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
- // mir::Constant
@@ -75,17 +75,13 @@
+ _7 = const false; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ StorageLive(_12); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ StorageLive(_13); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ StorageDead(_13); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
}
- bb3: {
+ bb1: {
-+ StorageDead(_12); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageDead(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageDead(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageDead(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
@@ -102,55 +98,51 @@
+ }
+
+ bb3: {
-+ _11 = move _7; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
-+ StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
-+ _9 = _11; // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
-+ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21
++ _11 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:17: 15:39
++ StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:15:20: 15:21
++ _9 = _11; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21
++ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21
+ }
+
+ bb4: {
-+ _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:+7:24: +7:25
-+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
++ _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:15:24: 15:25
++ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39
+ }
+
+ bb5: {
-+ _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:+7:35: +7:37
-+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39
++ _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:15:35: 15:37
++ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39
+ }
+
+ bb6: {
-+ StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:+7:38: +7:39
-+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ StorageLive(_14); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ StorageDead(_14); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39
-+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:+7:11: +7:39
++ StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39
++ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
++ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
++ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
++ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
++ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39
+ }
+
+ bb7: {
-+ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ _10 = move _7; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
-+ StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:+7:38: +7:39
-+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ StorageLive(_15); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ StorageDead(_15); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8
-+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:+7:8: +7:8
++ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ _10 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39
++ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
++ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
++ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
++ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
++ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
++ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41
+ }
+
+ bb8: {
-+ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
+ }
+
+ bb9: {
-+ unreachable; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8
++ unreachable; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
}
}
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
deleted file mode 100644
index deaba70e0..000000000
--- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
+++ /dev/null
@@ -1,86 +0,0 @@
-- // MIR for `main` before Inline
-+ // MIR for `main` after Inline
-
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11
- let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
- let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
- let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-+ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- scope 1 {
- debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
- }
- scope 2 {
- }
-+ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
-+ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
- _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- // mir::Constant
- // + span: $DIR/inline-into-box-place.rs:8:29: 8:43
- // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
- }
-
- bb1: {
- StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
- // mir::Constant
-- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
-- // + user_ty: UserType(1)
-- // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
-- }
--
-- bb2: {
-+ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ // + user_ty: UserType(0)
-+ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
-+ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
- _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
-- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
-+ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
- }
-
-- bb3: {
-+ bb2: {
- StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
- return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2
- }
-
-- bb4 (cleanup): {
-- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
-- // mir::Constant
-- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
-- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
-- }
--
-- bb5 (cleanup): {
-+ bb3 (cleanup): {
- resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2
- }
- }
-
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff
index deaba70e0..7e017373b 100644
--- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff
@@ -10,15 +10,14 @@
let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-+ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
scope 1 {
debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
}
scope 2 {
}
+ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
-+ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ let mut _9: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ }
bb0: {
@@ -34,13 +33,12 @@
bb1: {
StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
_5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
_7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ _9 = const _; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
// mir::Constant
- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
- // + user_ty: UserType(1)
@@ -51,16 +49,15 @@
+ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
-+ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
++ Deinit((*_8)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
_1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
_0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
-- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
+- drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
+ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
}
@@ -71,16 +68,15 @@
}
- bb4 (cleanup): {
-- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
-- // mir::Constant
-- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
-- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
++ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2
- }
-
- bb5 (cleanup): {
-+ bb3 (cleanup): {
- resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2
+- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+- // mir::Constant
+- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
+- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
}
}
diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
index 275493066..361b02715 100644
--- a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
@@ -5,9 +5,9 @@ fn main() -> () {
let _1: (); // in scope 0 at $DIR/inline-options.rs:+1:5: +1:18
let _2: (); // in scope 0 at $DIR/inline-options.rs:+2:5: +2:21
scope 1 (inlined inlined::<u32>) { // at $DIR/inline-options.rs:10:5: 10:21
- let _3: (); // in scope 1 at $DIR/inline-options.rs:+8:23: +8:26
- let _4: (); // in scope 1 at $DIR/inline-options.rs:+8:28: +8:31
- let _5: (); // in scope 1 at $DIR/inline-options.rs:+8:33: +8:36
+ let _3: (); // in scope 1 at $DIR/inline-options.rs:16:23: 16:26
+ let _4: (); // in scope 1 at $DIR/inline-options.rs:16:28: 16:31
+ let _5: (); // in scope 1 at $DIR/inline-options.rs:16:33: 16:36
}
bb0: {
@@ -21,33 +21,33 @@ fn main() -> () {
bb1: {
StorageDead(_1); // scope 0 at $DIR/inline-options.rs:+1:18: +1:19
StorageLive(_2); // scope 0 at $DIR/inline-options.rs:+2:5: +2:21
- StorageLive(_3); // scope 1 at $DIR/inline-options.rs:+8:23: +8:26
- _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:+8:23: +8:26
+ StorageLive(_3); // scope 1 at $DIR/inline-options.rs:16:23: 16:26
+ _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:16:23: 16:26
// mir::Constant
// + span: $DIR/inline-options.rs:16:23: 16:24
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_3); // scope 1 at $DIR/inline-options.rs:+8:26: +8:27
- StorageLive(_4); // scope 1 at $DIR/inline-options.rs:+8:28: +8:31
- _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:+8:28: +8:31
+ StorageDead(_3); // scope 1 at $DIR/inline-options.rs:16:26: 16:27
+ StorageLive(_4); // scope 1 at $DIR/inline-options.rs:16:28: 16:31
+ _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:16:28: 16:31
// mir::Constant
// + span: $DIR/inline-options.rs:16:28: 16:29
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
}
bb3: {
- StorageDead(_4); // scope 1 at $DIR/inline-options.rs:+8:31: +8:32
- StorageLive(_5); // scope 1 at $DIR/inline-options.rs:+8:33: +8:36
- _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:+8:33: +8:36
+ StorageDead(_4); // scope 1 at $DIR/inline-options.rs:16:31: 16:32
+ StorageLive(_5); // scope 1 at $DIR/inline-options.rs:16:33: 16:36
+ _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:16:33: 16:36
// mir::Constant
// + span: $DIR/inline-options.rs:16:33: 16:34
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
}
bb4: {
- StorageDead(_5); // scope 1 at $DIR/inline-options.rs:+8:36: +8:37
+ StorageDead(_5); // scope 1 at $DIR/inline-options.rs:16:36: 16:37
StorageDead(_2); // scope 0 at $DIR/inline-options.rs:+2:21: +2:22
_0 = const (); // scope 0 at $DIR/inline-options.rs:+0:11: +3:2
return; // scope 0 at $DIR/inline-options.rs:+3:2: +3:2
diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
index 768608564..cabc1a920 100644
--- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
@@ -15,10 +15,10 @@ fn bar() -> bool {
let mut _9: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
let mut _10: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
scope 2 (inlined foo) { // at $DIR/inline-retag.rs:12:5: 12:15
- debug x => _3; // in scope 2 at $DIR/inline-retag.rs:+6:8: +6:9
- debug y => _6; // in scope 2 at $DIR/inline-retag.rs:+6:17: +6:18
- let mut _11: i32; // in scope 2 at $DIR/inline-retag.rs:+7:5: +7:7
- let mut _12: i32; // in scope 2 at $DIR/inline-retag.rs:+7:11: +7:13
+ debug x => _3; // in scope 2 at $DIR/inline-retag.rs:16:8: 16:9
+ debug y => _6; // in scope 2 at $DIR/inline-retag.rs:16:17: 16:18
+ let mut _11: i32; // in scope 2 at $DIR/inline-retag.rs:17:5: 17:7
+ let mut _12: i32; // in scope 2 at $DIR/inline-retag.rs:17:11: 17:13
}
}
@@ -32,7 +32,7 @@ fn bar() -> bool {
_2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ _10 = const _; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
// mir::Constant
// + span: $DIR/inline-retag.rs:12:7: 12:9
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) }
@@ -43,7 +43,7 @@ fn bar() -> bool {
Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ _9 = const _; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
// mir::Constant
// + span: $DIR/inline-retag.rs:12:11: 12:14
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) }
@@ -52,15 +52,15 @@ fn bar() -> bool {
Retag(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
_6 = &(*_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
Retag(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- Retag(_3); // scope 2 at $DIR/inline-retag.rs:+6:1: +8:2
- Retag(_6); // scope 2 at $DIR/inline-retag.rs:+6:1: +8:2
- StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:7
- _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:7
- StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:+7:11: +7:13
- _12 = (*_6); // scope 2 at $DIR/inline-retag.rs:+7:11: +7:13
- _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:13
- StorageDead(_12); // scope 2 at $DIR/inline-retag.rs:+7:12: +7:13
- StorageDead(_11); // scope 2 at $DIR/inline-retag.rs:+7:12: +7:13
+ Retag(_3); // scope 2 at $DIR/inline-retag.rs:16:8: 16:9
+ Retag(_6); // scope 2 at $DIR/inline-retag.rs:16:17: 16:18
+ StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7
+ _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7
+ StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13
+ _12 = (*_6); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13
+ _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline-retag.rs:17:5: 17:13
+ StorageDead(_12); // scope 2 at $DIR/inline-retag.rs:17:12: 17:13
+ StorageDead(_11); // scope 2 at $DIR/inline-retag.rs:17:12: 17:13
StorageDead(_6); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
StorageDead(_3); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
StorageDead(_2); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
diff --git a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
index 106291b36..fdf2a1e1f 100644
--- a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
@@ -19,7 +19,7 @@
- }
-
- bb1: {
-+ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:+10:31: +10:34
++ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:14:31: 14:34
_0 = const (); // scope 0 at $DIR/inline-specialization.rs:+0:11: +2:2
StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:+2:1: +2:2
return; // scope 0 at $DIR/inline-specialization.rs:+2:2: +2:2
diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
index 116ae4e36..b8896430d 100644
--- a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
@@ -6,8 +6,8 @@ fn test2(_1: &dyn X) -> bool {
let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
let mut _3: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
scope 1 (inlined test) { // at $DIR/inline-trait-method_2.rs:5:5: 5:12
- debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:+5:9: +5:10
- let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
+ debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:9:9: 9:10
+ let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
}
bb0: {
@@ -16,16 +16,16 @@ fn test2(_1: &dyn X) -> bool {
_3 = &(*_1); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
_2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
StorageDead(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
- _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
- _0 = <dyn X as X>::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10
+ StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
+ _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
+ _0 = <dyn X as X>::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
// mir::Constant
// + span: $DIR/inline-trait-method_2.rs:10:7: 10:8
// + literal: Const { ty: for<'r> fn(&'r dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:+6:9: +6:10
+ StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:9: 10:10
StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:11: +1:12
return; // scope 0 at $DIR/inline-trait-method_2.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
index 4006dd15a..06d442ae8 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -21,13 +21,9 @@ fn b(_1: &mut Box<T>) -> &mut T {
_4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageLive(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageLive(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_8 = (((_7.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_6 = &mut (*_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageDead(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageDead(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
index e516269c1..d5f06c54a 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -15,13 +15,9 @@ fn d(_1: &Box<T>) -> &T {
StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
_3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- StorageDead(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
diff --git a/src/test/mir-opt/inline/polymorphic-recursion.rs b/src/test/mir-opt/inline/polymorphic-recursion.rs
new file mode 100644
index 000000000..7388722b7
--- /dev/null
+++ b/src/test/mir-opt/inline/polymorphic-recursion.rs
@@ -0,0 +1,25 @@
+// Make sure that the MIR inliner does not loop indefinitely on polymorphic recursion.
+// compile-flags: --crate-type lib
+
+// Randomize `def_path_hash` by defining them under a module with different names
+macro_rules! emit {
+ ($($m:ident)*) => {$(
+ pub mod $m {
+ pub trait Tr { type Next: Tr; }
+
+ pub fn hoge<const N: usize, T: Tr>() {
+ inner::<N, T>();
+ }
+
+ #[inline(always)]
+ fn inner<const N: usize, T: Tr>()
+ {
+ inner::<N, T::Next>();
+ inner::<N, T::Next>();
+ }
+ }
+ )*};
+}
+
+// Increase the chance of triggering the bug
+emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19);
diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
index b78ef36ea..a3cee3ecf 100644
--- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
@@ -5,7 +5,7 @@
let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:+0:13: +0:17
bb0: {
-+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:20:1 - 22:2; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
_0 = const true; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +1:9
return; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2
}
diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
index 0490c0df2..81d552823 100644
--- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,12 +8,12 @@
let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:+2:18: +4:10
bb0: {
-+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 10:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:11:1 - 11:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
}
bb1: {
-+ Coverage::Expression(4294967295) = 1 + 2 for /the/src/instrument_coverage.rs:11:5 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
++ Coverage::Expression(4294967295) = 1 + 2 for /the/src/instrument_coverage.rs:12:5 - 13:17; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
falseUnwind -> [real: bb2, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
}
@@ -21,7 +21,7 @@
StorageLive(_2); // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17
_2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17
// mir::Constant
- // + span: /the/src/instrument_coverage.rs:12:12: 12:15
+ // + span: /the/src/instrument_coverage.rs:13:12: 13:15
// + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) }
}
@@ -30,15 +30,15 @@
}
bb4: {
-+ Coverage::Expression(4294967293) = 4294967294 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
-+ Coverage::Expression(4294967294) = 4294967295 - 2 for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
++ Coverage::Expression(4294967293) = 4294967294 + 0 for /the/src/instrument_coverage.rs:17:1 - 17:2; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
++ Coverage::Expression(4294967294) = 4294967295 - 2 for /the/src/instrument_coverage.rs:14:13 - 14:18; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
_0 = const (); // scope 0 at /the/src/instrument_coverage.rs:+3:13: +3:18
StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10
return; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2
}
bb5: {
-+ Coverage::Counter(2) for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:15:10 - 15:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
_1 = const (); // scope 0 at /the/src/instrument_coverage.rs:+4:10: +4:10
StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10
goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6
diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs
index a748f2c5c..7f6a0a0eb 100644
--- a/src/test/mir-opt/instrument_coverage.rs
+++ b/src/test/mir-opt/instrument_coverage.rs
@@ -1,6 +1,7 @@
// Test that `-C instrument-coverage` injects Coverage statements. The Coverage Counter statements
// are later converted into LLVM instrprof.increment intrinsics, during codegen.
+// unit-test: InstrumentCoverage
// needs-profiler-support
// ignore-windows
// compile-flags: -C instrument-coverage --remap-path-prefix={{src-base}}=/the/src
diff --git a/src/test/mir-opt/issue-101867.rs b/src/test/mir-opt/issue-101867.rs
new file mode 100644
index 000000000..931396e21
--- /dev/null
+++ b/src/test/mir-opt/issue-101867.rs
@@ -0,0 +1,9 @@
+#![cfg_attr(bootstrap, feature(let_else))]
+
+// EMIT_MIR issue_101867.main.mir_map.0.mir
+fn main() {
+ let x: Option<u8> = Some(1);
+ let Some(y) = x else {
+ panic!();
+ };
+}
diff --git a/src/test/mir-opt/issue-101973.rs b/src/test/mir-opt/issue-101973.rs
new file mode 100644
index 000000000..216659a23
--- /dev/null
+++ b/src/test/mir-opt/issue-101973.rs
@@ -0,0 +1,20 @@
+// compile-flags: -O -C debug-assertions=on
+// This needs inlining followed by ConstProp to reproduce, so we cannot use "unit-test".
+
+#[inline]
+pub fn imm8(x: u32) -> u32 {
+ let mut out = 0u32;
+ out |= (x >> 0) & 0xff;
+ out
+}
+
+// EMIT_MIR issue_101973.inner.ConstProp.diff
+#[inline(never)]
+pub fn inner(fields: u32) -> i64 {
+ imm8(fields).rotate_right(((fields >> 8) & 0xf) << 1) as i32 as i64
+}
+
+fn main() {
+ let val = inner(0xe32cf20f);
+ assert_eq!(val as u64, 0xfffffffff0000000);
+}
diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs
index 5c34d8e68..cbd8633a3 100644
--- a/src/test/mir-opt/issue-41697.rs
+++ b/src/test/mir-opt/issue-41697.rs
@@ -13,7 +13,7 @@ trait Foo {
fn get(&self) -> [u8; 2];
}
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
impl Foo for [u8; 1+1] {
fn get(&self) -> [u8; 2] {
diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue-72181.rs
index 844d53a4b..ebb5f5042 100644
--- a/src/test/mir-opt/issue-72181.rs
+++ b/src/test/mir-opt/issue-72181.rs
@@ -11,14 +11,14 @@ union Foo {
b: Never
}
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR issue_72181.foo.mir_map.0.mir
fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
// EMIT_MIR issue_72181.bar.mir_map.0.mir
fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR issue_72181.main.mir_map.0.mir
fn main() {
let _ = mem::size_of::<Foo>();
diff --git a/src/test/mir-opt/issue-73223.rs b/src/test/mir-opt/issue-73223.rs
index 703b87612..be114cab7 100644
--- a/src/test/mir-opt/issue-73223.rs
+++ b/src/test/mir-opt/issue-73223.rs
@@ -8,6 +8,5 @@ fn main() {
assert_eq!(split, 1);
}
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff
-// EMIT_MIR issue_73223.main.PreCodegen.diff
diff --git a/src/test/mir-opt/issue-91633.rs b/src/test/mir-opt/issue-91633.rs
new file mode 100644
index 000000000..8f6601985
--- /dev/null
+++ b/src/test/mir-opt/issue-91633.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Z mir-opt-level=0
+// EMIT_MIR issue_91633.hey.mir_map.0.mir
+fn hey<T> (it: &[T])
+ where
+ [T] : std::ops::Index<usize>,
+ {
+ let _ = &it[0];
+ }
+
+// EMIT_MIR issue_91633.bar.mir_map.0.mir
+fn bar<T> (it: Box<[T]>)
+ where
+ [T] : std::ops::Index<usize>,
+ {
+ let _ = it[0];
+ }
+
+// EMIT_MIR issue_91633.fun.mir_map.0.mir
+fn fun<T> (it: &[T]) -> &T
+ {
+ let f = &it[0];
+ f
+ }
+
+// EMIT_MIR issue_91633.foo.mir_map.0.mir
+fn foo<T: Clone> (it: Box<[T]>) -> T
+ {
+ let f = it[0].clone();
+ f
+ }
+ fn main(){}
diff --git a/src/test/mir-opt/issue_101867.main.mir_map.0.mir b/src/test/mir-opt/issue_101867.main.mir_map.0.mir
new file mode 100644
index 000000000..98501ac8c
--- /dev/null
+++ b/src/test/mir-opt/issue_101867.main.mir_map.0.mir
@@ -0,0 +1,75 @@
+// MIR for `main` 0 mir_map
+
+| User Type Annotations
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue-101867.rs:5:12: 5:22, inferred_ty: std::option::Option<u8>
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue-101867.rs:5:12: 5:22, inferred_ty: std::option::Option<u8>
+|
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-101867.rs:+0:11: +0:11
+ let _1: std::option::Option<u8> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-101867.rs:+1:9: +1:10
+ let mut _2: !; // in scope 0 at $DIR/issue-101867.rs:+2:26: +4:6
+ let _3: (); // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ let mut _6: isize; // in scope 0 at $DIR/issue-101867.rs:+2:9: +2:16
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/issue-101867.rs:+1:9: +1:10
+ let _5: u8; // in scope 1 at $DIR/issue-101867.rs:+2:14: +2:15
+ scope 2 {
+ debug y => _5; // in scope 2 at $DIR/issue-101867.rs:+2:14: +2:15
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-101867.rs:+1:9: +1:10
+ _1 = Option::<u8>::Some(const 1_u8); // scope 0 at $DIR/issue-101867.rs:+1:25: +1:32
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-101867.rs:+1:9: +1:10
+ AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-101867.rs:+1:12: +1:22
+ StorageLive(_5); // scope 1 at $DIR/issue-101867.rs:+2:14: +2:15
+ FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20
+ _6 = discriminant(_1); // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20
+ switchInt(move _6) -> [1_isize: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-101867.rs:+2:9: +2:16
+ }
+
+ bb1: {
+ StorageLive(_3); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ StorageLive(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ _4 = begin_panic::<&str>(const "explicit panic") -> bb7; // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb2: {
+ StorageDead(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ StorageDead(_3); // scope 1 at $DIR/issue-101867.rs:+3:16: +3:17
+ unreachable; // scope 1 at $DIR/issue-101867.rs:+2:26: +4:6
+ }
+
+ bb3: {
+ goto -> bb6; // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20
+ }
+
+ bb4: {
+ falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue-101867.rs:+2:9: +2:16
+ }
+
+ bb5: {
+ _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue-101867.rs:+2:14: +2:15
+ _0 = const (); // scope 0 at $DIR/issue-101867.rs:+0:11: +5:2
+ StorageDead(_5); // scope 1 at $DIR/issue-101867.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/issue-101867.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue-101867.rs:+5:2: +5:2
+ }
+
+ bb6: {
+ StorageDead(_5); // scope 1 at $DIR/issue-101867.rs:+5:1: +5:2
+ goto -> bb1; // scope 0 at $DIR/issue-101867.rs:+0:11: +5:2
+ }
+
+ bb7 (cleanup): {
+ resume; // scope 0 at $DIR/issue-101867.rs:+0:1: +5:2
+ }
+}
diff --git a/src/test/mir-opt/issue_101973.inner.ConstProp.diff b/src/test/mir-opt/issue_101973.inner.ConstProp.diff
new file mode 100644
index 000000000..89733a9a2
--- /dev/null
+++ b/src/test/mir-opt/issue_101973.inner.ConstProp.diff
@@ -0,0 +1,100 @@
+- // MIR for `inner` before ConstProp
++ // MIR for `inner` after ConstProp
+
+ fn inner(_1: u32) -> i64 {
+ debug fields => _1; // in scope 0 at $DIR/issue-101973.rs:+0:14: +0:20
+ let mut _0: i64; // return place in scope 0 at $DIR/issue-101973.rs:+0:30: +0:33
+ let mut _2: i32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
+ let mut _3: u32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:58
+ let mut _4: u32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:17
+ let mut _5: u32; // in scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
+ let mut _6: u32; // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ let mut _7: u32; // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
+ let mut _8: u32; // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ let mut _9: u32; // in scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
+ let mut _10: (u32, bool); // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ let mut _11: (u32, bool); // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ scope 1 (inlined imm8) { // at $DIR/issue-101973.rs:14:5: 14:17
+ debug x => _5; // in scope 1 at $DIR/issue-101973.rs:5:13: 5:14
+ let mut _12: u32; // in scope 1 at $DIR/issue-101973.rs:7:12: 7:27
+ let mut _13: u32; // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20
+ let mut _14: u32; // in scope 1 at $DIR/issue-101973.rs:7:13: 7:14
+ let mut _15: (u32, bool); // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20
+ scope 2 {
+ debug out => _4; // in scope 2 at $DIR/issue-101973.rs:6:9: 6:16
+ }
+ }
+ scope 3 (inlined core::num::<impl u32>::rotate_right) { // at $DIR/issue-101973.rs:14:5: 14:58
+ debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ let mut _16: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ let mut _17: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
+ StorageLive(_3); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:58
+ StorageLive(_4); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:17
+ StorageLive(_5); // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
+ _5 = _1; // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
+ _4 = const 0_u32; // scope 1 at $DIR/issue-101973.rs:6:19: 6:23
+ StorageLive(_12); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27
+ StorageLive(_13); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+ StorageLive(_14); // scope 2 at $DIR/issue-101973.rs:7:13: 7:14
+ _14 = _5; // scope 2 at $DIR/issue-101973.rs:7:13: 7:14
+ _15 = CheckedShr(_14, const 0_i32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+ assert(!move (_15.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+ }
+
+ bb1: {
+ _8 = move (_10.0: u32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ StorageDead(_9); // scope 0 at $DIR/issue-101973.rs:+1:44: +1:45
+ _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
+ StorageDead(_8); // scope 0 at $DIR/issue-101973.rs:+1:51: +1:52
+ _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ }
+
+ bb2: {
+ _6 = move (_11.0: u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ StorageDead(_7); // scope 0 at $DIR/issue-101973.rs:+1:56: +1:57
+ StorageLive(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _16 = _4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageLive(_17); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _17 = _6; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _3 = rotate_right::<u32>(move _16, move _17) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::<u32>}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ _13 = move (_15.0: u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+ StorageDead(_14); // scope 2 at $DIR/issue-101973.rs:7:19: 7:20
+ _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27
+ StorageDead(_13); // scope 2 at $DIR/issue-101973.rs:7:26: 7:27
+ _4 = BitOr(_4, move _12); // scope 2 at $DIR/issue-101973.rs:7:5: 7:27
+ StorageDead(_12); // scope 2 at $DIR/issue-101973.rs:7:26: 7:27
+ StorageDead(_5); // scope 0 at $DIR/issue-101973.rs:+1:16: +1:17
+ StorageLive(_6); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ StorageLive(_7); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
+ StorageLive(_8); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ StorageLive(_9); // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
+ _9 = _1; // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
+ _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ }
+
+ bb4: {
+ StorageDead(_17); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageDead(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageDead(_6); // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58
+ StorageDead(_4); // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58
+ _2 = move _3 as i32 (Misc); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
+ StorageDead(_3); // scope 0 at $DIR/issue-101973.rs:+1:64: +1:65
+ _0 = move _2 as i64 (Misc); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:72
+ StorageDead(_2); // scope 0 at $DIR/issue-101973.rs:+1:71: +1:72
+ return; // scope 0 at $DIR/issue-101973.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir
deleted file mode 100644
index 047b24db4..000000000
--- a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir
+++ /dev/null
@@ -1,20 +0,0 @@
-// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
-
-<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
- let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
-
- bb0: {
- _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- }
-
- bb1: {
- _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- }
-
- bb2 (cleanup): {
- resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- }
-}
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
index 047b24db4..047b24db4 100644
--- a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir
+++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir
deleted file mode 100644
index 972ce1d50..000000000
--- a/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,17 +0,0 @@
-// MIR for `bar` 0 mir_map
-
-fn bar(_1: [(Never, u32); 1]) -> u32 {
- let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
- let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
- scope 1 {
- debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
- _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
- _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
- StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
- return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
- }
-}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir
index 972ce1d50..972ce1d50 100644
--- a/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir
deleted file mode 100644
index 534f131ea..000000000
--- a/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,27 +0,0 @@
-// MIR for `foo` 0 mir_map
-
-fn foo(_1: [(Never, u32); 1]) -> u32 {
- debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
- let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
- let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
- let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
- _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
- _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- }
-
- bb1: {
- _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
- StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
- return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
- }
-
- bb2 (cleanup): {
- resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
- }
-}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir
index 534f131ea..534f131ea 100644
--- a/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir
deleted file mode 100644
index 425906f84..000000000
--- a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,62 +0,0 @@
-// MIR for `main` 0 mir_map
-
-fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
- let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
- let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
- let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
- let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
- let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
- let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
- let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
- scope 1 {
- let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
- scope 2 {
- debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
- scope 3 {
- }
- scope 4 {
- }
- }
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
- _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
- // mir::Constant
- // + span: $DIR/issue-72181.rs:24:13: 24:32
- // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
- }
-
- bb1: {
- StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
- StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
- StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
- _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
- StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
- _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
- _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
- StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
- StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
- FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
- StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
- StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
- _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
- _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
- _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
- }
-
- bb2: {
- _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
- StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
- StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
- _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
- StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
- return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
- }
-
- bb3 (cleanup): {
- resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
- }
-}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.mir
index 425906f84..425906f84 100644
--- a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/issue_72181.main.mir_map.0.mir
diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
deleted file mode 100644
index be8e86a83..000000000
--- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
+++ /dev/null
@@ -1,117 +0,0 @@
-- // MIR for `main` before PreCodegen
-+ // MIR for `main` after PreCodegen
-
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
- let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 1 {
- debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
- let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- scope 3 {
- debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
- let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 4 {
- debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 5 {
- debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
- }
- }
- }
- scope 2 {
- debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
- StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
- _7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb1: {
- StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
- }
-
- bb2: {
- StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
- StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
- }
- }
-
diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
deleted file mode 100644
index be8e86a83..000000000
--- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
+++ /dev/null
@@ -1,117 +0,0 @@
-- // MIR for `main` before PreCodegen
-+ // MIR for `main` after PreCodegen
-
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
- let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 1 {
- debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
- let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- scope 3 {
- debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
- let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 4 {
- debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 5 {
- debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
- }
- }
- }
- scope 2 {
- debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
- StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
- _7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb1: {
- StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
- }
-
- bb2: {
- StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
- StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
- }
- }
-
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
deleted file mode 100644
index 50948180f..000000000
--- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
+++ /dev/null
@@ -1,157 +0,0 @@
-- // MIR for `main` before SimplifyArmIdentity
-+ // MIR for `main` after SimplifyArmIdentity
-
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
- let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
- let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
- let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
- let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
- let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 1 {
- debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
- let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- scope 3 {
- debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
- let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 4 {
- debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 5 {
- debug kind => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
- }
- }
- }
- scope 2 {
- debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- goto -> bb2; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
- }
-
- bb1: {
- nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
- StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
- StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
- }
-
- bb2: {
- StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
- StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
- _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
- Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
- ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
- discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
- StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
- StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
- _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _13 = (_9.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _14 = (_9.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- switchInt(move _15) -> [false: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb3: {
- StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
- StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
- // mir::Constant
- // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
- }
-
- bb4: {
- nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
- StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
- StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
- }
- }
-
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
index 50948180f..76d8d9396 100644
--- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
+++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
@@ -55,7 +55,7 @@
((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
_3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- goto -> bb2; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
+ goto -> bb3; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
}
bb1: {
@@ -66,6 +66,10 @@
}
bb2: {
+ unreachable; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ }
+
+ bb3: {
StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
_4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
_1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
@@ -83,7 +87,7 @@
StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _28 = const _; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
@@ -108,10 +112,10 @@
StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- switchInt(move _15) -> [false: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _15) -> [false: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
- bb3: {
+ bb4: {
StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -141,7 +145,7 @@
// + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
}
- bb4: {
+ bb5: {
nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
diff --git a/src/test/mir-opt/issue_91633.bar.mir_map.0.mir b/src/test/mir-opt/issue_91633.bar.mir_map.0.mir
new file mode 100644
index 000000000..f5092d2ac
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.bar.mir_map.0.mir
@@ -0,0 +1,39 @@
+// MIR for `bar` 0 mir_map
+
+fn bar(_1: Box<[T]>) -> () {
+ debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
+ let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+ let mut _3: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+ StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+ _3 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+ _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+ // mir::Constant
+ // + span: $DIR/issue-91633.rs:15:14: 15:19
+ // + literal: Const { ty: for<'r> fn(&'r [T], usize) -> &'r <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:18: +4:19
+ StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+ }
+
+ bb2: {
+ return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
+ }
+
+ bb3 (cleanup): {
+ drop(_1) -> bb4; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+ }
+
+ bb4 (cleanup): {
+ resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
+ }
+}
diff --git a/src/test/mir-opt/issue_91633.foo.mir_map.0.mir b/src/test/mir-opt/issue_91633.foo.mir_map.0.mir
new file mode 100644
index 000000000..2e8b0feed
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.foo.mir_map.0.mir
@@ -0,0 +1,57 @@
+// MIR for `foo` 0 mir_map
+
+fn foo(_1: Box<[T]>) -> T {
+ debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:19: +0:21
+ let mut _0: T; // return place in scope 0 at $DIR/issue-91633.rs:+0:36: +0:37
+ let _2: T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+ let mut _3: &T; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+ let _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
+ let mut _5: usize; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ scope 1 {
+ debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+ StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+ StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
+ _4 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
+ _5 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ _6 = Lt(_4, _5); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ }
+
+ bb1: {
+ _3 = &(*_1)[_4]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+ _2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+ // mir::Constant
+ // + span: $DIR/issue-91633.rs:28:20: 28:25
+ // + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+2:26: +2:27
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+ StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+2:27: +2:28
+ _0 = move _2; // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
+ drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ }
+
+ bb4: {
+ return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
+ }
+
+ bb5 (cleanup): {
+ drop(_1) -> bb6; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ }
+
+ bb6 (cleanup): {
+ resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
+ }
+}
diff --git a/src/test/mir-opt/issue_91633.fun.mir_map.0.mir b/src/test/mir-opt/issue_91633.fun.mir_map.0.mir
new file mode 100644
index 000000000..ded9a4cf7
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.fun.mir_map.0.mir
@@ -0,0 +1,35 @@
+// MIR for `fun` 0 mir_map
+
+fn fun(_1: &[T]) -> &T {
+ debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
+ let mut _0: &T; // return place in scope 0 at $DIR/issue-91633.rs:+0:25: +0:27
+ let _2: &T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+ let _3: usize; // in scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
+ let mut _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ let mut _5: bool; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ scope 1 {
+ debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+ StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
+ _3 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
+ _4 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ _5 = Lt(_3, _4); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ }
+
+ bb1: {
+ _2 = &(*_1)[_3]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:20
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+ _0 = &(*_2); // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
+ StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
+ }
+}
diff --git a/src/test/mir-opt/issue_91633.hey.mir_map.0.mir b/src/test/mir-opt/issue_91633.hey.mir_map.0.mir
new file mode 100644
index 000000000..74f4a5a97
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.hey.mir_map.0.mir
@@ -0,0 +1,35 @@
+// MIR for `hey` 0 mir_map
+
+fn hey(_1: &[T]) -> () {
+ debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
+ let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
+ let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+ let mut _4: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
+ StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+ StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+ _4 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+ _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+ // mir::Constant
+ // + span: $DIR/issue-91633.rs:7:15: 7:20
+ // + literal: Const { ty: for<'r> fn(&'r [T], usize) -> &'r <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
+ _2 = &(*_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
+ StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:20: +4:21
+ _0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
+ StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+ return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
+ }
+
+ bb2 (cleanup): {
+ resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
+ }
+}
diff --git a/src/test/mir-opt/issue_99325.main.mir_map.0.mir b/src/test/mir-opt/issue_99325.main.mir_map.0.mir
index 5bca9f0ea..8659ddfdb 100644
--- a/src/test/mir-opt/issue_99325.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_99325.main.mir_map.0.mir
@@ -2,7 +2,7 @@
| User Type Annotations
| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: None }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: () }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15
diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
index 86b38d4b7..f46c10711 100644
--- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
+++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
@@ -55,7 +55,6 @@ fn num_to_digit(_1: char) -> u32 {
bb2: {
StorageDead(_4); // scope 0 at $DIR/issue-59352.rs:+2:40: +2:41
- StorageLive(_10); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:50
_10 = discriminant(_3); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
switchInt(move _10) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
}
@@ -73,11 +72,9 @@ fn num_to_digit(_1: char) -> u32 {
bb5: {
_6 = &_7; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
StorageDead(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- StorageLive(_9); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
_9 = discriminant((*_6)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
StorageLive(_12); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_12 = move _9; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_9); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
StorageDead(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
StorageDead(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
StorageDead(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
@@ -102,7 +99,6 @@ fn num_to_digit(_1: char) -> u32 {
bb8: {
_0 = move ((_3 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
- StorageDead(_10); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:50
StorageDead(_3); // scope 0 at $DIR/issue-59352.rs:+2:49: +2:50
goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63
}
diff --git a/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff
deleted file mode 100644
index 2589c9f28..000000000
--- a/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff
+++ /dev/null
@@ -1,66 +0,0 @@
-- // MIR for `array_bound` before InstCombine
-+ // MIR for `array_bound` after InstCombine
-
- fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
- debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
- debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
- let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
- let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-
- bb0: {
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-+ _7 = _2; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- _11 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
-- _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- }
-
- bb1: {
- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- }
-
- bb2: {
- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
- goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
- }
-
- bb3: {
- _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
- goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
- }
-
- bb4: {
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
- return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff
deleted file mode 100644
index 8312db6b3..000000000
--- a/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff
+++ /dev/null
@@ -1,70 +0,0 @@
-- // MIR for `array_bound` before SimplifyLocals
-+ // MIR for `array_bound` after SimplifyLocals
-
- fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
- debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
- debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
- let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
- let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-+ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-
- bb0: {
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
- _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- }
-
- bb1: {
-- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-+ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-+ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- }
-
- bb2: {
-- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
-+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
- goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
- }
-
- bb3: {
- _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
- goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
- }
-
- bb4: {
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
- return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff
deleted file mode 100644
index 401d4bac6..000000000
--- a/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff
+++ /dev/null
@@ -1,79 +0,0 @@
-- // MIR for `array_bound_mut` before InstCombine
-+ // MIR for `array_bound_mut` after InstCombine
-
- fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
- debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
- debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
- let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
- let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
- let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-
- bb0: {
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- _14 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
-- _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- }
-
- bb1: {
- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- }
-
- bb2: {
- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
- goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
- }
-
- bb3: {
- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
- _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-- _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-+ _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- _13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- }
-
- bb4: {
- (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
- _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
- goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
- }
-
- bb5: {
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
- return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff
deleted file mode 100644
index 4f241d7c9..000000000
--- a/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff
+++ /dev/null
@@ -1,93 +0,0 @@
-- // MIR for `array_bound_mut` before SimplifyLocals
-+ // MIR for `array_bound_mut` after SimplifyLocals
-
- fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
- debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
- debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
- let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
- let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-- let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-- let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-- let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-+ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ let _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-+ let mut _10: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-+ let mut _11: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-
- bb0: {
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
- StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
- _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
-- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
- switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
- }
-
- bb1: {
-- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-+ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
-+ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- }
-
- bb2: {
-- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
-+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
-+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
- goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
- }
-
- bb3: {
-- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-- _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-- _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-- _13 = Lt(const 0_usize, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-+ StorageLive(_9); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-+ _9 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
-+ _10 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-+ _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
-+ assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- }
-
- bb4: {
-- (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
-- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
-+ (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
-+ StorageDead(_9); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
- _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
- goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
- }
-
- bb5: {
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
- return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff
deleted file mode 100644
index 26f45be17..000000000
--- a/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff
+++ /dev/null
@@ -1,27 +0,0 @@
-- // MIR for `array_len` before InstCombine
-+ // MIR for `array_len` after InstCombine
-
- fn array_len(_1: &[u8; N]) -> usize {
- debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
- let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-+ _3 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
-- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
- return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff
deleted file mode 100644
index 09d571d20..000000000
--- a/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff
+++ /dev/null
@@ -1,22 +0,0 @@
-- // MIR for `array_len` before SimplifyLocals
-+ // MIR for `array_len` after SimplifyLocals
-
- fn array_len(_1: &[u8; N]) -> usize {
- debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
- let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
-- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-
- bb0: {
-- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
- _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
- return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff
deleted file mode 100644
index 843da758d..000000000
--- a/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `array_len_by_value` before InstCombine
-+ // MIR for `array_len_by_value` after InstCombine
-
- fn array_len_by_value(_1: [u8; N]) -> usize {
- debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
- let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
-- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
- return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff
deleted file mode 100644
index dc1c00b69..000000000
--- a/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff
+++ /dev/null
@@ -1,22 +0,0 @@
-- // MIR for `array_len_by_value` before SimplifyLocals
-+ // MIR for `array_len_by_value` after SimplifyLocals
-
- fn array_len_by_value(_1: [u8; N]) -> usize {
- debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
- let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
-- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-
- bb0: {
-- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
- _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
-- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
- return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
- }
- }
-
diff --git a/src/test/mir-opt/lower_array_len.rs b/src/test/mir-opt/lower_array_len.rs
index fc12ee75f..ea0224b21 100644
--- a/src/test/mir-opt/lower_array_len.rs
+++ b/src/test/mir-opt/lower_array_len.rs
@@ -1,8 +1,7 @@
-// compile-flags: -Z mir-opt-level=4
+// unit-test: NormalizeArrayLen
+// compile-flags: -Zmir-enable-passes=+LowerSliceLenCalls
// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.diff
-// EMIT_MIR lower_array_len.array_bound.SimplifyLocals.diff
-// EMIT_MIR lower_array_len.array_bound.InstCombine.diff
pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
if index < slice.len() {
slice[index]
@@ -12,8 +11,6 @@ pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
}
// EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff
-// EMIT_MIR lower_array_len.array_bound_mut.SimplifyLocals.diff
-// EMIT_MIR lower_array_len.array_bound_mut.InstCombine.diff
pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
if index < slice.len() {
slice[index]
@@ -25,15 +22,11 @@ pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8
}
// EMIT_MIR lower_array_len.array_len.NormalizeArrayLen.diff
-// EMIT_MIR lower_array_len.array_len.SimplifyLocals.diff
-// EMIT_MIR lower_array_len.array_len.InstCombine.diff
pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
arr.len()
}
// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.diff
-// EMIT_MIR lower_array_len.array_len_by_value.SimplifyLocals.diff
-// EMIT_MIR lower_array_len.array_len_by_value.InstCombine.diff
pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
arr.len()
}
diff --git a/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
new file mode 100644
index 000000000..2c6c93cb1
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
@@ -0,0 +1,49 @@
+// MIR for `array_bound` after PreCodegen
+
+fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:36: +0:41
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:50: +0:55
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:70: +0:72
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ let _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
+ _6 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
+ _7 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ }
+
+ bb2: {
+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+3:5: +3:6
+ goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
+ }
+
+ bb3: {
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:11
+ goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
+ }
+
+ bb4: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:2: +6:2
+ }
+}
diff --git a/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
new file mode 100644
index 000000000..aee3a8242
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
@@ -0,0 +1,62 @@
+// MIR for `array_bound_mut` after PreCodegen
+
+fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
+ debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:40: +0:45
+ debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:54: +0:59
+ let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:78: +0:80
+ let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ let _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let _9: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ let mut _10: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ let mut _11: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ _4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
+ StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+ switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
+ _6 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
+ _7 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ }
+
+ bb2: {
+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+3:5: +3:6
+ goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
+ }
+
+ bb3: {
+ StorageLive(_9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ _9 = const 0_usize; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ _10 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ }
+
+ bb4: {
+ (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
+ StorageDead(_9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
+ _0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:9: +6:11
+ goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
+ }
+
+ bb5: {
+ StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+8:2: +8:2
+ }
+}
diff --git a/src/test/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir
new file mode 100644
index 000000000..4b19f6795
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir
@@ -0,0 +1,11 @@
+// MIR for `array_len` after PreCodegen
+
+fn array_len(_1: &[u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:34: +0:37
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:52: +0:57
+
+ bb0: {
+ _0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
new file mode 100644
index 000000000..4dc0ba9a2
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
@@ -0,0 +1,11 @@
+// MIR for `array_len_by_value` after PreCodegen
+
+fn array_len_by_value(_1: [u8; N]) -> usize {
+ debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:43: +0:46
+ let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:60: +0:65
+
+ bb0: {
+ _0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14
+ return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/lower_array_len_e2e.rs b/src/test/mir-opt/lower_array_len_e2e.rs
new file mode 100644
index 000000000..49b35d509
--- /dev/null
+++ b/src/test/mir-opt/lower_array_len_e2e.rs
@@ -0,0 +1,39 @@
+// compile-flags: -Z mir-opt-level=4
+
+// EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir
+pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ 42
+ }
+}
+
+// EMIT_MIR lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
+pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
+ if index < slice.len() {
+ slice[index]
+ } else {
+ slice[0] = 42;
+
+ 42
+ }
+}
+
+// EMIT_MIR lower_array_len_e2e.array_len.PreCodegen.after.mir
+pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
+ arr.len()
+}
+
+// EMIT_MIR lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
+pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
+ arr.len()
+}
+
+fn main() {
+ let _ = array_bound(3, &[0, 1, 2, 3]);
+ let mut tmp = [0, 1, 2, 3, 4];
+ let _ = array_bound_mut(3, &mut [0, 1, 2, 3]);
+ let _ = array_len(&[0]);
+ let _ = array_len_by_value([0, 2]);
+}
diff --git a/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
index 5c635e222..3389db733 100644
--- a/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
@@ -7,7 +7,7 @@
bb0: {
- _0 = std::intrinsics::min_align_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:19:5: 19:40
+- // + span: $DIR/lower_intrinsics.rs:21:5: 21:40
- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(<ZST>) }
+ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
diff --git a/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff
new file mode 100644
index 000000000..d9898d8e0
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff
@@ -0,0 +1,26 @@
+- // MIR for `assume` before LowerIntrinsics
++ // MIR for `assume` after LowerIntrinsics
+
+ fn assume() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17
+ let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+- _1 = std::intrinsics::assume(const true) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:72:9: 72:32
+- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value(<ZST>) }
++ assume(const true); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38
+ }
+
+ bb1: {
+ StorageDead(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:38: +2:39
+ _0 = const (); // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +3:6
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
index 8a80de32f..a648e5d67 100644
--- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
@@ -31,7 +31,7 @@
_3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
- _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:74:5: 74:41
+- // + span: $DIR/lower_intrinsics.rs:49:5: 49:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> <T as DiscriminantKind>::Discriminant {discriminant_value::<T>}, val: Value(<ZST>) }
+ _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
@@ -44,15 +44,15 @@
StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
- _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
+ _19 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
// mir::Constant
- // + span: $DIR/lower_intrinsics.rs:75:42: 75:44
+ // + span: $DIR/lower_intrinsics.rs:50:42: 50:44
// + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) }
_7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
_6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
- _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:75:5: 75:41
+- // + span: $DIR/lower_intrinsics.rs:50:5: 50:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> <i32 as DiscriminantKind>::Discriminant {discriminant_value::<i32>}, val: Value(<ZST>) }
+ _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
@@ -65,15 +65,15 @@
StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
- _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
+ _18 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
// mir::Constant
- // + span: $DIR/lower_intrinsics.rs:76:42: 76:45
+ // + span: $DIR/lower_intrinsics.rs:51:42: 51:45
// + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) }
_11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
_10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:76:5: 76:41
+- // + span: $DIR/lower_intrinsics.rs:51:5: 51:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as DiscriminantKind>::Discriminant {discriminant_value::<()>}, val: Value(<ZST>) }
+ _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+ goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
@@ -86,15 +86,15 @@
StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
- _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
+ _17 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
// mir::Constant
- // + span: $DIR/lower_intrinsics.rs:77:42: 77:47
+ // + span: $DIR/lower_intrinsics.rs:52:42: 52:47
// + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) }
_15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
_14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
- _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:77:5: 77:41
+- // + span: $DIR/lower_intrinsics.rs:52:5: 52:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> <E as DiscriminantKind>::Discriminant {discriminant_value::<E>}, val: Value(<ZST>) }
+ _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+ goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
@@ -105,11 +105,15 @@
StorageDead(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49
StorageDead(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49
_0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:30: +5:2
- drop(_1) -> bb5; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2
+ drop(_1) -> [return: bb5, unwind: bb6]; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2
}
bb5: {
return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2
}
+
+ bb6 (cleanup): {
+ resume; // scope 0 at $DIR/lower_intrinsics.rs:+0:1: +5:2
+ }
}
diff --git a/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
new file mode 100644
index 000000000..4fb6752b6
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
@@ -0,0 +1,72 @@
+- // MIR for `f_copy_nonoverlapping` before LowerIntrinsics
++ // MIR for `f_copy_nonoverlapping` after LowerIntrinsics
+
+ fn f_copy_nonoverlapping() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:32
+ let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+ let _3: (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+ let mut _4: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+ let mut _5: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ let mut _6: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ let _7: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ let mut _8: *mut i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+ let mut _9: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ let mut _10: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ let mut _11: &mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ scope 1 {
+ debug src => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+ let mut _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+ scope 2 {
+ debug dst => _2; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+ scope 3 {
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12
+ Deinit(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:15: +1:17
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16
+ Deinit(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:19: +2:21
+ StorageLive(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+ StorageLive(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+ StorageLive(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ StorageLive(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ StorageLive(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ _7 = &_1; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ _6 = &raw const (*_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33
+ _5 = _6; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45
+ _4 = move _5 as *const i32 (Misc); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59
+ StorageDead(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:58: +4:59
+ StorageLive(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+ StorageLive(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ StorageLive(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ StorageLive(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ _11 = &mut _2; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ _10 = &raw mut (*_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69
+ _9 = _10; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79
+ _8 = move _9 as *mut i32 (Misc); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91
+ StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91
+- _3 = copy_nonoverlapping::<i32>(move _4, move _8, const 0_usize) -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+- // mir::Constant
+- // + span: $DIR/lower_intrinsics.rs:65:9: 65:28
+- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::<i32>}, val: Value(<ZST>) }
++ copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
++ goto -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95
+ }
+
+ bb1: {
+ StorageDead(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95
+ StorageDead(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95
+ StorageDead(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ StorageDead(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96
+ _0 = const (); // scope 3 at $DIR/lower_intrinsics.rs:+3:5: +5:6
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/lower_intrinsics.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
index e6a2f6512..4cbbc02c9 100644
--- a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
@@ -11,7 +11,7 @@
_2 = move _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
- _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:24:5: 24:29
+- // + span: $DIR/lower_intrinsics.rs:26:5: 26:29
- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(<ZST>) }
+ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
diff --git a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
index 1ab2f2a0a..d8cd5f59a 100644
--- a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
@@ -13,7 +13,7 @@
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18
_1 = std::intrinsics::size_of::<T>; // scope 0 at $DIR/lower_intrinsics.rs:+2:21: +2:51
// mir::Constant
- // + span: $DIR/lower_intrinsics.rs:62:21: 62:51
+ // + span: $DIR/lower_intrinsics.rs:37:21: 37:51
// + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
_2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs
index eab51b65f..66dae0e46 100644
--- a/src/test/mir-opt/lower_intrinsics.rs
+++ b/src/test/mir-opt/lower_intrinsics.rs
@@ -1,5 +1,7 @@
-// compile-flags: -Cpanic=abort
-#![feature(core_intrinsics)]
+// unit-test: LowerIntrinsics
+// ignore-wasm32 compiled with panic=abort by default
+
+#![feature(core_intrinsics, intrinsics)]
#![crate_type = "lib"]
// EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff
@@ -29,33 +31,6 @@ pub fn unreachable() -> ! {
unsafe { core::intrinsics::unreachable() };
}
-// EMIT_MIR lower_intrinsics.f_unit.PreCodegen.before.mir
-pub fn f_unit() {
- f_dispatch(());
-}
-
-
-// EMIT_MIR lower_intrinsics.f_u64.PreCodegen.before.mir
-pub fn f_u64() {
- f_dispatch(0u64);
-}
-
-#[inline(always)]
-pub fn f_dispatch<T>(t: T) {
- if std::mem::size_of::<T>() == 0 {
- f_zst(t);
- } else {
- f_non_zst(t);
- }
-}
-
-#[inline(never)]
-pub fn f_zst<T>(_t: T) {
-}
-
-#[inline(never)]
-pub fn f_non_zst<T>(_t: T) {}
-
// EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff
pub fn non_const<T>() -> usize {
// Check that lowering works with non-const operand as a func.
@@ -76,3 +51,24 @@ pub fn discriminant<T>(t: T) {
core::intrinsics::discriminant_value(&());
core::intrinsics::discriminant_value(&E::B);
}
+
+extern "rust-intrinsic" {
+ // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
+pub fn f_copy_nonoverlapping() {
+ let src = ();
+ let mut dst = ();
+ unsafe {
+ copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
+ }
+}
+
+// EMIT_MIR lower_intrinsics.assume.LowerIntrinsics.diff
+pub fn assume() {
+ unsafe {
+ std::intrinsics::assume(true);
+ }
+}
diff --git a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
index 11b27976b..cf0ab73a5 100644
--- a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
@@ -7,7 +7,7 @@
bb0: {
- _0 = std::intrinsics::size_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:14:5: 14:35
+- // + span: $DIR/lower_intrinsics.rs:16:5: 16:35
- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
+ _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
diff --git a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
index ac077e85b..6f17d4451 100644
--- a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
@@ -14,7 +14,7 @@
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
- _3 = std::intrinsics::unreachable(); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:29:14: 29:43
+- // + span: $DIR/lower_intrinsics.rs:31:14: 31:43
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(<ZST>) }
+ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
}
diff --git a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
index e0a5416b2..22ef75fd8 100644
--- a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
@@ -32,7 +32,7 @@
_5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49
- _3 = wrapping_add::<i32>(move _4, move _5) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:7:14: 7:44
+- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::<i32>}, val: Value(<ZST>) }
+ _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
@@ -48,7 +48,7 @@
_8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49
- _6 = wrapping_sub::<i32>(move _7, move _8) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:8:14: 8:44
+- // + span: $DIR/lower_intrinsics.rs:10:14: 10:44
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::<i32>}, val: Value(<ZST>) }
+ _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
+ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
@@ -64,7 +64,7 @@
_11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49
- _9 = wrapping_mul::<i32>(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
- // mir::Constant
-- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44
+- // + span: $DIR/lower_intrinsics.rs:11:14: 11:44
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::<i32>}, val: Value(<ZST>) }
+ _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
+ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
diff --git a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
index 9e4de2ac0..8e185323e 100644
--- a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir
+++ b/src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
@@ -1,32 +1,32 @@
-// MIR for `f_u64` before PreCodegen
+// MIR for `f_u64` after PreCodegen
fn f_u64() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:16: +0:16
- let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
- scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics.rs:40:5: 40:21
- debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+5:22: +5:23
- let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21
- let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20
- scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16
+ let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21
+ debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
+ let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
+ let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
+ scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
- _1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
- StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21
- StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20
- _3 = move _1; // scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20
- _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ _1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
+ StorageLive(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
+ _3 = move _1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
+ _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
// mir::Constant
- // + span: $DIR/lower_intrinsics.rs:48:9: 48:18
+ // + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18
// + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+9:20: +9:21
- StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+9:21: +9:22
- StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
- return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ StorageDead(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:20: 23:21
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:21: 23:22
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
+ return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
index 9a6c0457f..a5b396ca0 100644
--- a/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir
+++ b/src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
@@ -1,30 +1,30 @@
-// MIR for `f_unit` before PreCodegen
+// MIR for `f_unit` after PreCodegen
fn f_unit() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17
- let mut _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18
- scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics.rs:34:5: 34:19
- debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+11:22: +11:23
- let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17
- let mut _3: (); // in scope 1 at $DIR/lower_intrinsics.rs:+13:15: +13:16
- scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32
+ let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:17: +0:17
+ let mut _1: (); // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
+ scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19
+ debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
+ let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
+ let mut _3: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:15: 21:16
+ scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18
- StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17
- StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+13:15: +13:16
- _2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17
+ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
+ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
+ StorageLive(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:15: 21:16
+ _2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
// mir::Constant
- // + span: $DIR/lower_intrinsics.rs:46:9: 46:14
+ // + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14
// + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+13:16: +13:17
- StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+13:17: +13:18
- StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:18: +1:19
- return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
+ StorageDead(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:16: 21:17
+ StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:17: 21:18
+ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:18: +1:19
+ return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/lower_intrinsics_e2e.rs b/src/test/mir-opt/lower_intrinsics_e2e.rs
new file mode 100644
index 000000000..872ef59b0
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics_e2e.rs
@@ -0,0 +1,32 @@
+// Checks that we do not have any branches in the MIR for the two tested functions.
+
+// compile-flags: -Cpanic=abort
+#![feature(core_intrinsics)]
+#![crate_type = "lib"]
+
+// EMIT_MIR lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
+pub fn f_unit() {
+ f_dispatch(());
+}
+
+
+// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
+pub fn f_u64() {
+ f_dispatch(0u64);
+}
+
+#[inline(always)]
+pub fn f_dispatch<T>(t: T) {
+ if std::mem::size_of::<T>() == 0 {
+ f_zst(t);
+ } else {
+ f_non_zst(t);
+ }
+}
+
+#[inline(never)]
+pub fn f_zst<T>(_t: T) {
+}
+
+#[inline(never)]
+pub fn f_non_zst<T>(_t: T) {}
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
index c05ed00f7..b193a8d76 100644
--- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
+++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
@@ -51,7 +51,7 @@ fn full_tested_match() -> () {
bb5: {
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
- _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _11 = const _; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
// mir::Constant
// + span: $DIR/match_false_edges.rs:14:14: 14:15
// + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff
deleted file mode 100644
index 2005c10ef..000000000
--- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff
+++ /dev/null
@@ -1,88 +0,0 @@
-- // MIR for `bar` before MatchBranchSimplification
-+ // MIR for `bar` after MatchBranchSimplification
-
- fn bar(_1: i32) -> (bool, bool, bool, bool) {
- debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9
- let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43
- let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
- let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
- let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
- let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
- let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
- let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
-+ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
- scope 1 {
- debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
- let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
- scope 2 {
- debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
- let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
- scope 3 {
- debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
- let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
- scope 4 {
- debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
- }
- }
- }
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10
- StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10
- StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10
- StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10
- StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6
-- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
-- }
--
-- bb1: {
-- _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21
-- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
-- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
-- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
-- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
-- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
-- }
--
-- bb2: {
-- _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22
-- _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
-+ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
-+ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
-+ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22
-+ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22
- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21
-- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
-- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
-- }
--
-- bb3: {
-+ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12
- StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+21:6: +21:7
- StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
- _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7
- StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
- _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10
- StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
- _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13
- StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
- _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16
- Deinit(_0); // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
- (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
- (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
- (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
- (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17
- StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
- StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
- StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
- StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17
- StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
- StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
- StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+24:1: +24:2
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+24:2: +24:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff
index 2005c10ef..f9eeb1ea5 100644
--- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff
+++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff
@@ -41,7 +41,7 @@
- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
-- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
+- Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- }
-
@@ -54,7 +54,7 @@
+ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21
-- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
+ Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
- }
-
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff
deleted file mode 100644
index b7862e567..000000000
--- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-- // MIR for `foo` before MatchBranchSimplification
-+ // MIR for `foo` after MatchBranchSimplification
-
- fn foo(_1: Option<()>) -> () {
- debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
- let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
- let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
-+ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
-- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-- }
--
-- bb1: {
-- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-- }
--
-- bb2: {
-- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-- }
--
-- bb3: {
-+ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff
deleted file mode 100644
index b7862e567..000000000
--- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-- // MIR for `foo` before MatchBranchSimplification
-+ // MIR for `foo` after MatchBranchSimplification
-
- fn foo(_1: Option<()>) -> () {
- debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
- let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
- let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
-+ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
-- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-- }
--
-- bb1: {
-- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-- }
--
-- bb2: {
-- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-- }
--
-- bb3: {
-+ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-+ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
new file mode 100644
index 000000000..0b40b3be8
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
@@ -0,0 +1,55 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+
+ fn foo(_1: Option<()>) -> () {
+ debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
+ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
+ let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
++ let mut _4: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
+- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _4 = move _3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb1: {
+- _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb2: {
+- _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb3: {
+- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+- }
+-
+- bb4: {
+ Deinit(_0); // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ }
+
+- bb5: {
++ bb2: {
+ _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ }
+
+- bb6: {
++ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir
deleted file mode 100644
index a36ec8de4..000000000
--- a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `foo` before PreCodegen
-
-fn foo(_1: Option<()>) -> () {
- debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
- let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
-
- bb0: {
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
- }
-}
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir
deleted file mode 100644
index a36ec8de4..000000000
--- a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `foo` before PreCodegen
-
-fn foo(_1: Option<()>) -> () {
- debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
- let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
-
- bb0: {
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
- }
-}
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff
deleted file mode 100644
index 672c6b34e..000000000
--- a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff
+++ /dev/null
@@ -1,42 +0,0 @@
-- // MIR for `match_nested_if` before MatchBranchSimplification
-+ // MIR for `match_nested_if` after MatchBranchSimplification
-
- fn match_nested_if() -> bool {
- let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
- let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
- let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- scope 1 {
- debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
- StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-- }
--
-- bb1: {
-+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
-- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
-- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
-- }
--
-- bb2: {
-- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
-- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-- }
--
-- bb3: {
-+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
- StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff
deleted file mode 100644
index 672c6b34e..000000000
--- a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff
+++ /dev/null
@@ -1,42 +0,0 @@
-- // MIR for `match_nested_if` before MatchBranchSimplification
-+ // MIR for `match_nested_if` after MatchBranchSimplification
-
- fn match_nested_if() -> bool {
- let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
- let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
- let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- scope 1 {
- debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
- StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-- }
--
-- bb1: {
-+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
-+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
-- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
-- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
-- }
--
-- bb2: {
-- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
-- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-- }
--
-- bb3: {
-+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
-+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
- StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
- return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
new file mode 100644
index 000000000..b8c7722cd
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
@@ -0,0 +1,113 @@
+- // MIR for `match_nested_if` before MatchBranchSimplification
++ // MIR for `match_nested_if` after MatchBranchSimplification
+
+ fn match_nested_if() -> bool {
+ let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
+ let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ let mut _2: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ scope 1 {
+ debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
+ StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+ Deinit(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+- }
+-
+- bb1: {
+- _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+- }
+-
+- bb2: {
+- _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
+- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+- }
+-
+- bb3: {
++ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ _7 = move _6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
++ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
++ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
+- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+- }
+-
+- bb4: {
+- _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+- }
+-
+- bb5: {
+- _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
+- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+- }
+-
+- bb6: {
++ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++ _8 = move _5; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
++ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
++ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
+- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+- }
+-
+- bb7: {
+- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
+- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+- }
+-
+- bb8: {
+- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
+- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+- }
+-
+- bb9: {
+- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+- }
+-
+- bb10: {
++ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ _9 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
++ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
++ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
++ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
+- }
+-
+- bb11: {
+- StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+- StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
+- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+- }
+-
+- bb12: {
++ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
++ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
+ _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
+ StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
+ return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2
+ }
+ }
+
diff --git a/src/test/mir-opt/matches_reduce_branches.rs b/src/test/mir-opt/matches_reduce_branches.rs
index 51be3884d..a81d5f7b4 100644
--- a/src/test/mir-opt/matches_reduce_branches.rs
+++ b/src/test/mir-opt/matches_reduce_branches.rs
@@ -1,6 +1,7 @@
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// unit-test: MatchBranchSimplification
+
+
// EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff
-// EMIT_MIR matches_reduce_branches.foo.PreCodegen.before.mir
// EMIT_MIR matches_reduce_branches.bar.MatchBranchSimplification.diff
// EMIT_MIR matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff
deleted file mode 100644
index c42657b38..000000000
--- a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff
+++ /dev/null
@@ -1,28 +0,0 @@
-- // MIR for `exhaustive_match` before MatchBranchSimplification
-+ // MIR for `exhaustive_match` after MatchBranchSimplification
-
- fn exhaustive_match(_1: E) -> u8 {
- debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26
- let mut _0: u8; // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36
- let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
- }
-
- bb1: {
- _0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
- }
-
- bb2: {
- _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
- }
-
- bb3: {
- return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
index c42657b38..1b4dddc1d 100644
--- a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff
+++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
@@ -8,20 +8,24 @@
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
}
bb1: {
_0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
}
bb2: {
- _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ unreachable; // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
}
bb3: {
+ _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb4: {
return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff
deleted file mode 100644
index a4ff2e437..000000000
--- a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff
+++ /dev/null
@@ -1,28 +0,0 @@
-- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
-+ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
-
- fn exhaustive_match_i8(_1: E) -> i8 {
- debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29
- let mut _0: i8; // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39
- let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
- }
-
- bb1: {
- _0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
- }
-
- bb2: {
- _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
- }
-
- bb3: {
- return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
index a4ff2e437..6e734852e 100644
--- a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff
+++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
@@ -8,20 +8,24 @@
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12
}
bb1: {
_0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18
}
bb2: {
- _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
- goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ unreachable; // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12
}
bb3: {
+ _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18
+ }
+
+ bb4: {
return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/matches_u8.rs b/src/test/mir-opt/matches_u8.rs
index 78373be48..422c3a95e 100644
--- a/src/test/mir-opt/matches_u8.rs
+++ b/src/test/mir-opt/matches_u8.rs
@@ -1,4 +1,6 @@
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// unit-test: MatchBranchSimplification
+
+
// EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff
// EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
index cbfdf8c5d..0ab9d712d 100644
--- a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
+++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
@@ -13,11 +13,10 @@
| '_#2r | U0 | {bb0[0..=1], '_#2r}
| '_#3r | U0 | {bb0[0..=1], '_#3r}
| '_#4r | U0 | {bb0[0..=1], '_#4r}
-| '_#5r | U0 | {}
-| '_#6r | U0 | {bb0[0..=1], '_#1r}
-| '_#7r | U0 | {bb0[0..=1], '_#2r}
-| '_#8r | U0 | {bb0[0..=1], '_#1r}
-| '_#9r | U0 | {bb0[0..=1], '_#3r}
+| '_#5r | U0 | {bb0[0..=1], '_#1r}
+| '_#6r | U0 | {bb0[0..=1], '_#2r}
+| '_#7r | U0 | {bb0[0..=1], '_#1r}
+| '_#8r | U0 | {bb0[0..=1], '_#3r}
|
| Inference Constraints
| '_#0r live at {bb0[0..=1]}
@@ -25,16 +24,16 @@
| '_#2r live at {bb0[0..=1]}
| '_#3r live at {bb0[0..=1]}
| '_#4r live at {bb0[0..=1]}
-| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
-| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
-| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
-| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
-| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
-| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
-| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
-| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
+| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
+| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
+| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
+| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
+| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
+| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
+| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
+| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
|
-fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool {
+fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {
debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:26: +0:27
debug x => _2; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:42: +0:43
debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55
diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
index 55e7faf9e..36705d18e 100644
--- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
+++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -7,19 +7,18 @@
| Inferred Region Values
| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r}
| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r}
-| '_#2r | U0 | {}
-| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]}
-| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]}
-| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]}
+| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]}
+| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]}
+| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]}
|
| Inference Constraints
| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
-| '_#3r live at {bb1[0]}
-| '_#4r live at {bb1[1..=3]}
-| '_#5r live at {bb1[4..=7], bb2[0..=2]}
-| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
-| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
+| '_#2r live at {bb1[0]}
+| '_#3r live at {bb1[1..=3]}
+| '_#4r live at {bb1[4..=7], bb2[0..=2]}
+| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
+| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
|
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11
@@ -33,10 +32,10 @@ fn main() -> () {
let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
scope 1 {
debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
scope 2 {
debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
scope 3 {
debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
}
@@ -56,7 +55,7 @@ fn main() -> () {
}
bb1: {
- _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
+ _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
_6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
index 2647c9433..4f6256a67 100644
--- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
+++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -7,19 +7,18 @@
| Inferred Region Values
| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r}
| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r}
-| '_#2r | U0 | {}
-| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]}
-| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]}
-| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]}
+| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]}
+| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]}
+| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]}
|
| Inference Constraints
| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]}
-| '_#3r live at {bb1[0]}
-| '_#4r live at {bb1[1..=3]}
-| '_#5r live at {bb1[4..=7], bb2[0..=2]}
-| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
-| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
+| '_#2r live at {bb1[0]}
+| '_#3r live at {bb1[1..=3]}
+| '_#4r live at {bb1[4..=7], bb2[0..=2]}
+| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
+| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
|
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11
@@ -33,10 +32,10 @@ fn main() -> () {
let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
scope 1 {
debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
scope 2 {
debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
scope 3 {
debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
}
@@ -56,7 +55,7 @@ fn main() -> () {
}
bb1: {
- _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
+ _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
_6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
diff --git a/src/test/mir-opt/not_equal_false.rs b/src/test/mir-opt/not_equal_false.rs
index 5fbb848dc..2ae03da40 100644
--- a/src/test/mir-opt/not_equal_false.rs
+++ b/src/test/mir-opt/not_equal_false.rs
@@ -1,3 +1,4 @@
+// unit-test: InstCombine
// EMIT_MIR not_equal_false.opt.InstCombine.diff
fn opt(x: bool) -> u32 {
diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs
index 6c2e265d5..cb6524260 100644
--- a/src/test/mir-opt/packed-struct-drop-aligned.rs
+++ b/src/test/mir-opt/packed-struct-drop-aligned.rs
@@ -1,6 +1,6 @@
// ignore-wasm32-bare compiled with panic=abort by default
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
fn main() {
let mut x = Packed(Aligned(Droppy(0)));
diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir
deleted file mode 100644
index c3874d3b3..000000000
--- a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir
+++ /dev/null
@@ -1,55 +0,0 @@
-// MIR for `main` after SimplifyCfg-elaborate-drops
-
-fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11
- let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
- let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- scope 1 {
- debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
- StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- _2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42
- _1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
- StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43
- StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- _4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
- StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- }
-
- bb1: {
- StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
- return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2
- }
-
- bb2 (cleanup): {
- resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2
- }
-
- bb3 (cleanup): {
- (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
- }
-
- bb4: {
- StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
- _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2
- drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
- }
-}
diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
index c3874d3b3..f9ed1036f 100644
--- a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir
+++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
@@ -16,15 +16,20 @@ fn main() -> () {
StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- _2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ Deinit(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
+ Deinit(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
+ (_2.0: Droppy) = move _3; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42
- _1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
+ Deinit(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
+ (_1.0: Aligned) = move _2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43
StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- _4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ Deinit(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
+ Deinit(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
+ (_4.0: Droppy) = move _5; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
_6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
index 750aaa88b..99667aabd 100644
--- a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
+++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
@@ -23,13 +23,6 @@
scope 3 {
debug i => _12; // in scope 3 at $DIR/remove_storage_markers.rs:+2:9: +2:10
}
- scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<i32>>::next) { // at $DIR/remove_storage_markers.rs:8:14: 8:19
- debug self => _8; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
- let mut _14: &mut std::ops::Range<i32>; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
- }
- }
- scope 4 (inlined <std::ops::Range<i32> as IntoIterator>::into_iter) { // at $DIR/remove_storage_markers.rs:8:14: 8:19
- debug self => _3; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
}
@@ -41,29 +34,39 @@
Deinit(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
(_3.0: i32) = const 0_i32; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
(_3.1: i32) = const 10_i32; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- _2 = move _3; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ _2 = <std::ops::Range<i32> as IntoIterator>::into_iter(move _3) -> bb1; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ // mir::Constant
+ // + span: $DIR/remove_storage_markers.rs:10:14: 10:19
+ // + literal: Const { ty: fn(std::ops::Range<i32>) -> <std::ops::Range<i32> as IntoIterator>::IntoIter {<std::ops::Range<i32> as IntoIterator>::into_iter}, val: Value(<ZST>) }
+ }
+
+ bb1: {
- StorageDead(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:18: +2:19
- StorageLive(_4); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
_4 = move _2; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- goto -> bb1; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ goto -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
}
- bb1: {
+ bb2: {
- StorageLive(_6); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- StorageLive(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- StorageLive(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- StorageLive(_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
_9 = &mut _4; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
_8 = &mut (*_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
-- StorageLive(_14); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
- _14 = &mut (*_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
- _7 = <std::ops::Range<i32> as iter::range::RangeIteratorImpl>::spec_next(move _14) -> bb4; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+ _7 = <std::ops::Range<i32> as Iterator>::next(move _8) -> bb3; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
// mir::Constant
- // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
- // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range<i32>) -> Option<<std::ops::Range<i32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<i32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
+ // + span: $DIR/remove_storage_markers.rs:10:14: 10:19
+ // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range<i32>) -> Option<<std::ops::Range<i32> as Iterator>::Item> {<std::ops::Range<i32> as Iterator>::next}, val: Value(<ZST>) }
}
- bb2: {
+ bb3: {
+- StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19
+ _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ }
+
+ bb4: {
- StorageLive(_12); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
_12 = ((_7 as Some).0: i32); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10
- StorageLive(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17
@@ -76,10 +79,14 @@
- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
_5 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
- goto -> bb1; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
+ goto -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
}
- bb3: {
+ bb5: {
+ unreachable; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
+ }
+
+ bb6: {
_0 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6
- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6
@@ -89,12 +96,5 @@
- StorageDead(_1); // scope 0 at $DIR/remove_storage_markers.rs:+5:1: +5:2
return; // scope 0 at $DIR/remove_storage_markers.rs:+5:2: +5:2
}
-
- bb4: {
-- StorageDead(_14); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
-- StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19
- _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- switchInt(move _10) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19
- }
}
diff --git a/src/test/mir-opt/remove_storage_markers.rs b/src/test/mir-opt/remove_storage_markers.rs
index c144d3ff7..f00b82691 100644
--- a/src/test/mir-opt/remove_storage_markers.rs
+++ b/src/test/mir-opt/remove_storage_markers.rs
@@ -1,3 +1,5 @@
+// unit-test: RemoveStorageMarkers
+
// Checks that storage markers are removed at opt-level=0.
//
// compile-flags: -C opt-level=0 -Coverflow-checks=off
diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.rs b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
index 7a6f86b80..8b9de9b4d 100644
--- a/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
+++ b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Zmir-opt-level=3
+// unit-test: RemoveZsts
// Ensure RemoveZsts doesn't remove ZST assignments to union fields,
// which causes problems in Miri.
diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
index 451d0fe4c..899bb67fb 100644
--- a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
@@ -80,7 +80,7 @@ fn array_casts() -> () {
_7 = _2; // scope 3 at $DIR/retag.rs:+3:15: +3:16
_6 = ptr::mut_ptr::<impl *mut usize>::add(move _7, const 1_usize) -> bb1; // scope 3 at $DIR/retag.rs:+3:15: +3:23
// mir::Constant
- // + span: $DIR/retag.rs:60:17: 60:20
+ // + span: $DIR/retag.rs:61:17: 61:20
// + literal: Const { ty: unsafe fn(*mut usize, usize) -> *mut usize {ptr::mut_ptr::<impl *mut usize>::add}, val: Value(<ZST>) }
}
@@ -111,7 +111,7 @@ fn array_casts() -> () {
_17 = _9; // scope 6 at $DIR/retag.rs:+7:26: +7:27
_16 = ptr::const_ptr::<impl *const usize>::add(move _17, const 1_usize) -> bb2; // scope 6 at $DIR/retag.rs:+7:26: +7:34
// mir::Constant
- // + span: $DIR/retag.rs:64:28: 64:31
+ // + span: $DIR/retag.rs:65:28: 65:31
// + literal: Const { ty: unsafe fn(*const usize, usize) -> *const usize {ptr::const_ptr::<impl *const usize>::add}, val: Value(<ZST>) }
}
@@ -121,14 +121,16 @@ fn array_casts() -> () {
_14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ (_13.1: &usize) = move _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -154,7 +156,8 @@ fn array_casts() -> () {
bb3: {
StorageLive(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _27 = core::panicking::AssertKind::Eq; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_27) = 0; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -171,7 +174,8 @@ fn array_casts() -> () {
_32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ discriminant(_34) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
diff --git a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
index 60c0f336e..96fc7e649 100644
--- a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
@@ -9,14 +9,14 @@ fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 {
}
bb0: {
- Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:31: +0:48
- Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:31: +0:48
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:31: +3:6
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:32: +0:33
StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:13: +1:15
_3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19
Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19
- _0 = _2; // scope 1 at $DIR/retag.rs:+2:9: +2:10
+ _0 = &(*_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10
Retag(_0); // scope 1 at $DIR/retag.rs:+2:9: +2:10
StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6
- return; // scope 0 at $DIR/retag.rs:+0:48: +0:48
+ return; // scope 0 at $DIR/retag.rs:+3:6: +3:6
}
}
diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
index ae6b5cfe2..7212de52f 100644
--- a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
@@ -62,7 +62,8 @@ fn main() -> () {
StorageLive(_3); // scope 1 at $DIR/retag.rs:+3:13: +3:14
StorageLive(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36
StorageLive(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24
- _5 = Test(const 0_i32); // scope 1 at $DIR/retag.rs:+3:17: +3:24
+ Deinit(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24
+ (_5.0: i32) = const 0_i32; // scope 1 at $DIR/retag.rs:+3:17: +3:24
_4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36
Retag(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36
StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
@@ -73,7 +74,7 @@ fn main() -> () {
Retag([2phase] _6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
_3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:+3:17: +3:36
// mir::Constant
- // + span: $DIR/retag.rs:32:25: 32:28
+ // + span: $DIR/retag.rs:33:25: 33:28
// + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x mut i32) -> &'x mut i32 {Test::foo}, val: Value(<ZST>) }
}
@@ -111,14 +112,7 @@ fn main() -> () {
StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:5: +8:6
StorageLive(_13); // scope 1 at $DIR/retag.rs:+11:9: +11:10
StorageLive(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
- _14 = [closure@main::{closure#0}]; // scope 1 at $DIR/retag.rs:+11:31: +14:6
- // closure
- // + def_id: DefId(0:14 ~ retag[4622]::main::{closure#0})
- // + substs: [
- // i8,
- // for<'r> extern "rust-call" fn((&'r i32,)) -> &'r i32,
- // (),
- // ]
+ Deinit(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
Retag(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6
_13 = move _14 as for<'r> fn(&'r i32) -> &'r i32 (Pointer(ClosureFnPointer(Normal))); // scope 1 at $DIR/retag.rs:+11:31: +14:6
StorageDead(_14); // scope 1 at $DIR/retag.rs:+11:47: +11:48
@@ -142,14 +136,15 @@ fn main() -> () {
StorageLive(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24
StorageLive(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
StorageLive(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12
- _21 = Test(const 0_i32); // scope 7 at $DIR/retag.rs:+18:5: +18:12
+ Deinit(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12
+ (_21.0: i32) = const 0_i32; // scope 7 at $DIR/retag.rs:+18:5: +18:12
_20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24
Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
- _28 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:+18:21: +18:23
+ _28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23
// mir::Constant
- // + span: $DIR/retag.rs:47:21: 47:23
+ // + span: $DIR/retag.rs:48:21: 48:23
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
_23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
@@ -158,7 +153,7 @@ fn main() -> () {
Retag(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
_19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:+18:5: +18:24
// mir::Constant
- // + span: $DIR/retag.rs:47:13: 47:20
+ // + span: $DIR/retag.rs:48:13: 48:20
// + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x i32) -> &'x i32 {Test::foo_shr}, val: Value(<ZST>) }
}
@@ -182,7 +177,7 @@ fn main() -> () {
StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18
_27 = array_casts() -> bb6; // scope 8 at $DIR/retag.rs:+23:5: +23:18
// mir::Constant
- // + span: $DIR/retag.rs:52:5: 52:16
+ // + span: $DIR/retag.rs:53:5: 53:16
// + literal: Const { ty: fn() {array_casts}, val: Value(<ZST>) }
}
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index 13568b822..86deb0e7c 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -1,3 +1,4 @@
+// unit-test: AddRetag
// ignore-wasm32-bare compiled with panic=abort by default
// ignore-tidy-linelength
// compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats
diff --git a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
index e395fdb27..08fd655ae 100644
--- a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
@@ -1,14 +1,14 @@
-// MIR for `<impl at $DIR/retag.rs:11:1: 11:10>::foo` after SimplifyCfg-elaborate-drops
+// MIR for `<impl at $DIR/retag.rs:12:1: 12:10>::foo` after SimplifyCfg-elaborate-drops
-fn <impl at $DIR/retag.rs:11:1: 11:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32 {
+fn <impl at $DIR/retag.rs:12:1: 12:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32 {
debug self => _1; // in scope 0 at $DIR/retag.rs:+0:16: +0:21
debug x => _2; // in scope 0 at $DIR/retag.rs:+0:23: +0:24
let mut _0: &mut i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:53
let mut _3: &mut i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:10
bb0: {
- Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6
- Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:16: +0:21
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24
StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
_3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10
Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
diff --git a/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
index e609166de..f32a84e4c 100644
--- a/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
@@ -1,13 +1,13 @@
-// MIR for `<impl at $DIR/retag.rs:11:1: 11:10>::foo_shr` after SimplifyCfg-elaborate-drops
+// MIR for `<impl at $DIR/retag.rs:12:1: 12:10>::foo_shr` after SimplifyCfg-elaborate-drops
-fn <impl at $DIR/retag.rs:11:1: 11:10>::foo_shr(_1: &Test, _2: &i32) -> &i32 {
+fn <impl at $DIR/retag.rs:12:1: 12:10>::foo_shr(_1: &Test, _2: &i32) -> &i32 {
debug self => _1; // in scope 0 at $DIR/retag.rs:+0:20: +0:25
debug x => _2; // in scope 0 at $DIR/retag.rs:+0:27: +0:28
let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:49
bb0: {
- Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6
- Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6
+ Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:20: +0:25
+ Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:27: +0:28
_0 = _2; // scope 0 at $DIR/retag.rs:+1:9: +1:10
Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10
return; // scope 0 at $DIR/retag.rs:+2:6: +2:6
diff --git a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff
deleted file mode 100644
index 3a11e45ca..000000000
--- a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff
+++ /dev/null
@@ -1,145 +0,0 @@
-- // MIR for `identity` before ConstProp
-+ // MIR for `identity` after ConstProp
-
- fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
- debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
- let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
- let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- scope 1 {
- debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
- scope 2 {
- scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
- debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 9 {
- debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
- debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
- }
- }
- }
- }
- scope 3 {
- debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
- scope 4 {
- }
- }
- scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
- debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _14: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 6 {
- debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- }
- scope 7 {
- debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- }
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- StorageLive(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- }
-
- bb1: {
- StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
- ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
- discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
- StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
- }
-
- bb2: {
- StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
- StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
- }
-
- bb3: {
- StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+ _5 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+ switchInt(const 1_isize) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- }
-
- bb4: {
- unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- }
-
- bb5: {
- StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+ _5 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+ switchInt(const 0_isize) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- }
- }
-
diff --git a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir
deleted file mode 100644
index 952ef22d4..000000000
--- a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir
+++ /dev/null
@@ -1,127 +0,0 @@
-// MIR for `identity` after PreCodegen
-
-fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
- debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14
- let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53
- let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- let _5: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- let mut _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- scope 1 {
- debug residual => _5; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
- scope 2 {
- scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
- debug residual => _6; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- let _14: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _15: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 9 {
- debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
- debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
- }
- }
- }
- }
- scope 3 {
- debug val => _7; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
- scope 4 {
- }
- }
- scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
- debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _8: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let _9: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _10: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _12: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- let mut _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 6 {
- debug v => _9; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- }
- scope 7 {
- debug e => _11; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- }
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- StorageLive(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- _8 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- switchInt(move _8) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- }
-
- bb1: {
- StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- _11 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- _13 = move _11; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_12 as Err).0: i32) = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_12) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _12; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageLive(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- _5 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageLive(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- _6 = _5; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageLive(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- _14 = move ((_6 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- _16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- _15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_0 as Err).0: i32) = move _15; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageDead(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
- StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
- }
-
- bb2: {
- unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- }
-
- bb3: {
- StorageLive(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- _9 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageLive(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- _10 = move _9; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_3 as Continue).0: i32) = move _10; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- _7 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- _2 = _7; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
- ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
- discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
- StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
- }
-}
diff --git a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
index 8453d5341..f25b3ce72 100644
--- a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
+++ b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
@@ -15,7 +15,7 @@
scope 1 {
debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
scope 2 {
- scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:25:8: 25:10
debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
@@ -34,7 +34,7 @@
scope 4 {
}
}
- scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
+ scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:25:8: 25:10
debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
@@ -55,17 +55,15 @@
StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
_4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
- StorageLive(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
_10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-- switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-+ switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+- switchInt(move _10) -> [0_isize: bb7, 1_isize: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++ switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
}
bb1: {
-- StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-- switchInt(move _5) -> [0_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
- }
-
- bb2: {
@@ -83,6 +81,11 @@
- bb3: {
+ bb2: {
+ unreachable; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ }
+
+- bb4: {
++ bb3: {
StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
_6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
@@ -106,8 +109,8 @@
return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
}
-- bb4: {
-+ bb3: {
+- bb5: {
++ bb4: {
StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
_13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
@@ -123,19 +126,18 @@
StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-+ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
}
-- bb5: {
-+ bb4: {
+- bb6: {
++ bb5: {
unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
}
-- bb6: {
-+ bb5: {
+- bb7: {
++ bb6: {
StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
_11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
@@ -146,10 +148,9 @@
StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-+ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-+ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
++ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
}
}
diff --git a/src/test/mir-opt/separate_const_switch.rs b/src/test/mir-opt/separate_const_switch.rs
index 5d82acf4d..c809e5629 100644
--- a/src/test/mir-opt/separate_const_switch.rs
+++ b/src/test/mir-opt/separate_const_switch.rs
@@ -4,8 +4,6 @@
use std::ops::ControlFlow;
// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff
-// EMIT_MIR separate_const_switch.too_complex.ConstProp.diff
-// EMIT_MIR separate_const_switch.too_complex.PreCodegen.after.mir
fn too_complex(x: Result<i32, usize>) -> Option<i32> {
// The pass should break the outer match into
// two blocks that only have one parent each.
@@ -23,8 +21,6 @@ fn too_complex(x: Result<i32, usize>) -> Option<i32> {
}
// EMIT_MIR separate_const_switch.identity.SeparateConstSwitch.diff
-// EMIT_MIR separate_const_switch.identity.ConstProp.diff
-// EMIT_MIR separate_const_switch.identity.PreCodegen.after.mir
fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
Ok(x?)
}
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff
deleted file mode 100644
index de9f45c3d..000000000
--- a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff
+++ /dev/null
@@ -1,95 +0,0 @@
-- // MIR for `too_complex` before ConstProp
-+ // MIR for `too_complex` after ConstProp
-
- fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
- debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
- let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
- let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
- let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
- let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
- let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
- let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
- let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43
- let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33
- let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
- let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
- let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
- scope 1 {
- debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
- }
- scope 2 {
- debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
- }
- scope 3 {
- debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
- }
- scope 4 {
- debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
- _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
- }
-
- bb1: {
- StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
- _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
- StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
- _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
- Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
- ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
- discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
- StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44
- StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
-- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-- switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-+ _8 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-+ switchInt(const 1_isize) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
- }
-
- bb2: {
- StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
- _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
- StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
- _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
- Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
- ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
- discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
- StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
-- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-- switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-+ _8 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-+ switchInt(const 0_isize) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
- }
-
- bb3: {
- StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
- _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
- Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
- discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
- StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
- goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
- }
-
- bb4: {
- StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
- _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
- StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
- _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
- Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
- ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
- discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
- StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
- StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
- goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
- }
-
- bb5: {
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
- }
- }
-
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir
deleted file mode 100644
index 1009225b7..000000000
--- a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir
+++ /dev/null
@@ -1,69 +0,0 @@
-// MIR for `too_complex` after PreCodegen
-
-fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
- debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17
- let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53
- let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
- let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18
- let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
- let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45
- let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
- let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
- let mut _8: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43
- let _9: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
- scope 1 {
- debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17
- }
- scope 2 {
- debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18
- }
- scope 3 {
- debug v => _7; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32
- }
- scope 4 {
- debug r => _9; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
- _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
- }
-
- bb1: {
- StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
- StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
- StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
- Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
- discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
- StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
- }
-
- bb2: {
- StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
- _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
- StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
- _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
- Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
- ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
- discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
- StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
- StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
- _7 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
- StorageLive(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
- _8 = _7; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
- Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
- ((_0 as Some).0: i32) = move _8; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
- discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
- StorageDead(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
- StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
- }
-
- bb3: {
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
- }
-}
diff --git a/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
index 3ab1c572a..437979081 100644
--- a/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
+++ b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
@@ -30,7 +30,7 @@
bb0: {
StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
_3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
+ switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16
}
bb1: {
@@ -43,12 +43,16 @@
discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44
StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
-- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
+- goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
+ _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-+ switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
++ switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
}
bb2: {
+ unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16
+ }
+
+ bb3: {
StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
_4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
@@ -58,28 +62,33 @@
discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
-- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+- goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
- }
-
-- bb3: {
+- bb4: {
_8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
-- switchInt(move _8) -> [0_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
-+ switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
+- switchInt(move _8) -> [0_isize: bb7, 1_isize: bb5, otherwise: bb6]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
++ switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6
}
-- bb4: {
-+ bb3: {
+- bb5: {
++ bb4: {
StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
_11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29
Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38
StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
-- goto -> bb6; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
-+ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
+- goto -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
++ goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38
}
-- bb5: {
-+ bb4: {
+- bb6: {
++ bb5: {
+ unreachable; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6
+ }
+
+- bb7: {
++ bb6: {
StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
_9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
@@ -89,12 +98,12 @@
discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
-- goto -> bb6; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
-+ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+- goto -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
++ goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
}
-- bb6: {
-+ bb5: {
+- bb8: {
++ bb7: {
StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2
return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2
}
diff --git a/src/test/mir-opt/simple-match.rs b/src/test/mir-opt/simple-match.rs
index 44adc55b6..103033c4e 100644
--- a/src/test/mir-opt/simple-match.rs
+++ b/src/test/mir-opt/simple-match.rs
@@ -1,6 +1,6 @@
// Test that we don't generate unnecessarily large MIR for very simple matches
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR simple_match.match_bool.mir_map.0.mir
fn match_bool(x: bool) -> usize {
match x {
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir
deleted file mode 100644
index 3bef6aa05..000000000
--- a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,29 +0,0 @@
-// MIR for `match_bool` 0 mir_map
-
-fn match_bool(_1: bool) -> usize {
- debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
- let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
-
- bb0: {
- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
- switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
- }
-
- bb1: {
- falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
- }
-
- bb2: {
- _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
- goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
- }
-
- bb3: {
- _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
- goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
- }
-
- bb4: {
- return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
- }
-}
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir
index 3bef6aa05..3bef6aa05 100644
--- a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir
diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify-arm-identity.rs
index bedc86bba..cf6ff57aa 100644
--- a/src/test/mir-opt/simplify-arm-identity.rs
+++ b/src/test/mir-opt/simplify-arm-identity.rs
@@ -4,6 +4,9 @@
// compile-flags: -Zmir-opt-level=3
// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// This pass is broken since deaggregation changed
+// ignore-test
+
enum Src {
Foo(u8),
Bar,
diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify-arm.rs
index f7dcaa134..c247872e2 100644
--- a/src/test/mir-opt/simplify-arm.rs
+++ b/src/test/mir-opt/simplify-arm.rs
@@ -6,6 +6,9 @@
// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff
+// This pass is broken since deaggregation changed
+// ignore-test
+
fn id(o: Option<u8>) -> Option<u8> {
match o {
Some(v) => Some(v),
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
index 179994544..39b7911d4 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
+++ b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
@@ -1,3 +1,4 @@
+// unit-test: SimplifyLocals
// compile-flags: -C overflow-checks=no
fn use_zst(_: ((), ())) {}
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
index 84f57decc..d09bd92c4 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Zunsound-mir-opts
+// unit-test: SimplifyLocals
fn map(x: Option<Box<()>>) -> Option<Box<()>> {
match x {
@@ -11,5 +11,4 @@ fn main() {
map(None);
}
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
diff --git a/src/test/mir-opt/simplify-locals.rs b/src/test/mir-opt/simplify-locals.rs
index f6bf396cd..89d9391f8 100644
--- a/src/test/mir-opt/simplify-locals.rs
+++ b/src/test/mir-opt/simplify-locals.rs
@@ -1,6 +1,6 @@
// unit-test: SimplifyLocals
-#![feature(box_syntax)]
+
#![feature(thread_local)]
#[derive(Copy, Clone)]
diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff
deleted file mode 100644
index 9c3ad4b4d..000000000
--- a/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,46 +0,0 @@
-- // MIR for `id` before SimplifyArmIdentity
-+ // MIR for `id` after SimplifyArmIdentity
-
- fn id(_1: Option<u8>) -> Option<u8> {
- debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8
- let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35
- let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16
- let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
- let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26
- scope 1 {
- debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15
- }
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
- }
-
- bb1: {
- Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- }
-
- bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
- _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
- Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
- ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
- discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
- }
-
- bb4: {
- return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff
deleted file mode 100644
index 7b3a69936..000000000
--- a/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff
+++ /dev/null
@@ -1,46 +0,0 @@
-- // MIR for `id` before SimplifyBranchSame
-+ // MIR for `id` after SimplifyBranchSame
-
- fn id(_1: Option<u8>) -> Option<u8> {
- debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8
- let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35
- let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16
- let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
- let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26
- scope 1 {
- debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15
- }
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
- }
-
- bb1: {
- Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- }
-
- bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
- _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
- Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
- ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
- discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
- }
-
- bb4: {
- return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff
deleted file mode 100644
index 31d8453ce..000000000
--- a/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,58 +0,0 @@
-- // MIR for `id_result` before SimplifyArmIdentity
-+ // MIR for `id_result` after SimplifyArmIdentity
-
- fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> {
- debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15
- let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52
- let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14
- let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
- let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22
- let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
- let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24
- scope 1 {
- debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13
- }
- scope 2 {
- debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14
- }
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
- }
-
- bb1: {
- StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
- _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
- StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
- _6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
- Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
- ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
- discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
- StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25
- StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- }
-
- bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
- _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
- Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
- ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
- }
-
- bb4: {
- return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff
deleted file mode 100644
index 3692ebf74..000000000
--- a/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff
+++ /dev/null
@@ -1,58 +0,0 @@
-- // MIR for `id_result` before SimplifyBranchSame
-+ // MIR for `id_result` after SimplifyBranchSame
-
- fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> {
- debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15
- let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52
- let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14
- let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
- let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22
- let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
- let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24
- scope 1 {
- debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13
- }
- scope 2 {
- debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14
- }
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
- }
-
- bb1: {
- StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
- _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
- StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
- _6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
- Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
- ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
- discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
- StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25
- StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
- }
-
- bb3: {
- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
- _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
- Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
- ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23
- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
- }
-
- bb4: {
- return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
index 452cc8a9c..cff9afc38 100644
--- a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
@@ -23,14 +23,14 @@
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
- debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:+0:21: +0:22
+ debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22
}
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
- debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:+0:22: +0:23
+ debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23
}
bb0: {
@@ -38,7 +38,7 @@
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
_4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
- _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:+0:5: +0:6
+ _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6
StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
@@ -72,9 +72,9 @@
_9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
- ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:+0:9: +0:10
- Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10
+ Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
index 5d7d4ba7c..9d38b9350 100644
--- a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
+++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
@@ -23,14 +23,14 @@
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
- debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:+0:21: +0:22
+ debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22
}
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
- debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:+0:22: +0:23
+ debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23
}
bb0: {
@@ -38,7 +38,7 @@
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
_4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
- _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:+0:5: +0:6
+ _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6
StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
@@ -72,9 +72,9 @@
_9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
- ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:+0:9: +0:10
- Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10
+ Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
diff --git a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff
deleted file mode 100644
index 118f5dd0a..000000000
--- a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff
+++ /dev/null
@@ -1,61 +0,0 @@
-- // MIR for `main` before SimplifyArmIdentity
-+ // MIR for `main` after SimplifyArmIdentity
-
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11
- let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
- let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
- let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20
- let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
- scope 1 {
- debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
- let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- scope 2 {
- }
- scope 3 {
- debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- }
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
- Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
- ((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
- discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
- StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
- _3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
- goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25
- }
-
- bb1: {
- Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- ((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- }
-
- bb2: {
- unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
- }
-
- bb3: {
- StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
- _5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
- Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
- ((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
- discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
- StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
- StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
- goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
- }
-
- bb4: {
- StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7
- nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2
- StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff
deleted file mode 100644
index 118f5dd0a..000000000
--- a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff
+++ /dev/null
@@ -1,61 +0,0 @@
-- // MIR for `main` before SimplifyArmIdentity
-+ // MIR for `main` after SimplifyArmIdentity
-
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11
- let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
- let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
- let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20
- let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
- scope 1 {
- debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
- let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- scope 2 {
- }
- scope 3 {
- debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- }
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
- Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
- ((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
- discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
- StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
- _3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
- goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25
- }
-
- bb1: {
- Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- ((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
- }
-
- bb2: {
- unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
- }
-
- bb3: {
- StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
- StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
- _5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
- Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
- ((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
- discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
- StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
- StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
- goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
- }
-
- bb4: {
- StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7
- nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2
- StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
index da2f6fc44..b41527ba0 100644
--- a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
@@ -16,29 +16,53 @@
- let mut _11: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
+ let _1: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+ let mut _2: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-+ let _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
++ let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
++ let mut _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
++ let _5: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
++ let mut _6: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
++ let mut _7: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
++ let mut _8: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
scope 1 {
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
- StorageLive(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
+- Deinit(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
- StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
+- Deinit(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
+- Deinit(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
+- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
+- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
- StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28
- StorageDead(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28
- StorageDead(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:28: +1:29
- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
- StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
- StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
+- Deinit(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
- StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
+- Deinit(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
+- Deinit(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
+- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
+- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
- StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
- StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+ StorageLive(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
++ StorageLive(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
++ Deinit(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
++ StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
++ Deinit(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
++ Deinit(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
++ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
++ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
++ StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
++ StorageDead(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
+ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
// mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12
+ // + span: $DIR/simplify-locals-removes-unused-consts.rs:15:5: 15:12
// + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(<ZST>) }
}
@@ -49,22 +73,36 @@
- StorageLive(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
+- Deinit(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
+- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
+- _10 = (_11.0: u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
+- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34
-- _8 = use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+ StorageDead(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22
+ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23
-+ StorageLive(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
-+ _3 = use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
++ StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
++ StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
++ StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
++ StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
++ Deinit(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
++ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
++ StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34
++ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
// mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:11
+ // + span: $DIR/simplify-locals-removes-unused-consts.rs:17:5: 17:11
// + literal: Const { ty: fn(u8) {use_u8}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35
- StorageDead(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
-- StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
-+ StorageDead(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
++ StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35
+ StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
++ StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
+ _0 = const (); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +5:2
return; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff
deleted file mode 100644
index c6895fa41..000000000
--- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff
+++ /dev/null
@@ -1,39 +0,0 @@
-- // MIR for `map` before SimplifyLocals
-+ // MIR for `map` after SimplifyLocals
-
- fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
- debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
- let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
-- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
-- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
-- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
-- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
-- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- scope 1 {
- debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- }
-
- bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
- }
-
- bb1: {
- ((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
- discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
- }
-
- bb2: {
- Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
- }
-
- bb3: {
- return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
index c6895fa41..51d26b08b 100644
--- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff
+++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
@@ -5,34 +5,47 @@
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
-- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
-- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
+ let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
scope 1 {
- debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
}
bb0: {
+- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
_2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
}
bb1: {
- ((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
+ _4 = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
+ ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
+ StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
+ StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
+ goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
}
bb2: {
+ unreachable; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+ }
+
+ bb3: {
Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
- goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
}
- bb3: {
+ bb4: {
+- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs
deleted file mode 100644
index 15e351e7d..000000000
--- a/src/test/mir-opt/simplify_try.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// compile-flags: -Zunsound-mir-opts
-// EMIT_MIR simplify_try.try_identity.SimplifyArmIdentity.diff
-// EMIT_MIR simplify_try.try_identity.SimplifyBranchSame.after.mir
-// EMIT_MIR simplify_try.try_identity.SimplifyLocals.after.mir
-// EMIT_MIR simplify_try.try_identity.DestinationPropagation.diff
-
-
-fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
- r
-}
-
-fn from_error<T, E>(e: E) -> Result<T, E> {
- Err(e)
-}
-
-// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
-// so the relevant desugar is copied inline in order to keep the test testing the same thing.
-// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
-// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
-fn try_identity(x: Result<u32, i32>) -> Result<u32, i32> {
- let y = match into_result(x) {
- Err(e) => return from_error(From::from(e)),
- Ok(v) => v,
- };
- Ok(y)
-}
-
-fn main() {
- let _ = try_identity(Ok(0));
-}
diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
index d81d23c1c..83b91309b 100644
--- a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
+++ b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
@@ -24,7 +24,7 @@
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
}
}
scope 3 {
@@ -32,8 +32,8 @@
+ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
-+ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
++ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
}
bb0: {
@@ -41,16 +41,16 @@
- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
+- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
+ _3 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+ nop; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
++ nop; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
+ nop; // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
}
bb1: {
@@ -80,6 +80,10 @@
}
bb2: {
+ unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ }
+
+ bb3: {
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
nop; // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
@@ -87,9 +91,9 @@
nop; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
nop; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- nop; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ nop; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
index 853b95cc6..e025ae7c5 100644
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
@@ -23,14 +23,14 @@
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
}
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
}
bb0: {
@@ -38,10 +38,10 @@
StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
_4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
+ _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
}
bb1: {
@@ -61,6 +61,10 @@
}
bb2: {
+ unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ }
+
+ bb3: {
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
@@ -68,9 +72,9 @@
_9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
index 10799cd92..eb5af2227 100644
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
+++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
@@ -22,14 +22,14 @@ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
}
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
}
bb0: {
@@ -37,10 +37,10 @@ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
_4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6
+ _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
}
bb1: {
@@ -60,6 +60,10 @@ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
}
bb2: {
+ unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ }
+
+ bb3: {
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
@@ -67,9 +71,9 @@ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
_9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
index f8c9034f7..1efa8a67e 100644
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
@@ -17,20 +17,20 @@ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
debug t => _6; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _5; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22
+ debug e => _5; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
}
}
scope 3 {
debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
- debug r => _2; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23
+ debug r => _2; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
}
bb0: {
_2 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
_3 = discriminant(_2); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _3) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
+ switchInt(move _3) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
}
bb1: {
@@ -41,12 +41,16 @@ fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
}
bb2: {
+ unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
+ }
+
+ bb3: {
StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
StorageLive(_5); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
StorageLive(_6); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
StorageDead(_6); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11
+ Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
+ discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
StorageDead(_5); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs
index 0fd32906d..344c1af2c 100644
--- a/src/test/mir-opt/slice-drop-shim.rs
+++ b/src/test/mir-opt/slice-drop-shim.rs
@@ -1,6 +1,6 @@
// compile-flags: -Zmir-opt-level=0
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
// EMIT_MIR core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
fn main() {
let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_);
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir
deleted file mode 100644
index b4b317e84..000000000
--- a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir
+++ /dev/null
@@ -1,101 +0,0 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
-
-fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
- let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-
- bb0: {
- goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb1: {
- return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb2 (cleanup): {
- resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb3 (cleanup): {
- _5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb4 (cleanup): {
- _6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb5: {
- _7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb6: {
- _8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb7: {
- _4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb8: {
- goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb9 (cleanup): {
- _11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb10 (cleanup): {
- _12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb11: {
- _13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb12: {
- _14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb13: {
- _15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb14: {
- goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb15: {
- _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-}
diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
index b4b317e84..b4b317e84 100644
--- a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir
+++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
index bc9e91420..e50067ea2 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
+++ b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
@@ -198,6 +198,6 @@ static XXX: &Foo = {
_0 = &(*_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2
StorageDead(_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2
StorageDead(_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2
- return; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:1: +0:25
+ return; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:1: +18:3
}
}
diff --git a/src/test/mir-opt/storage_ranges.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir
index 812eb3b82..8e10e70f1 100644
--- a/src/test/mir-opt/storage_ranges.main.nll.0.mir
+++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir
@@ -7,16 +7,15 @@
| Inferred Region Values
| '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r}
| '_#1r | U0 | {bb0[0..=22], '_#1r}
-| '_#2r | U0 | {}
-| '_#3r | U0 | {bb0[10..=11]}
-| '_#4r | U0 | {bb0[11]}
+| '_#2r | U0 | {bb0[10..=11]}
+| '_#3r | U0 | {bb0[11]}
|
| Inference Constraints
| '_#0r live at {bb0[0..=22]}
| '_#1r live at {bb0[0..=22]}
-| '_#3r live at {bb0[10]}
-| '_#4r live at {bb0[11]}
-| '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
+| '_#2r live at {bb0[10]}
+| '_#3r live at {bb0[11]}
+| '_#2r: '_#3r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
|
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11
diff --git a/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
new file mode 100644
index 000000000..330929c58
--- /dev/null
+++ b/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
@@ -0,0 +1,96 @@
+// MIR for `new` after PreCodegen
+
+fn new(_1: Result<T, E>) -> Result<T, E> {
+ debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
+ let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
+ let mut _2: T; // in scope 0 at $DIR/try_identity_e2e.rs:+2:9: +10:10
+ let mut _3: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ let mut _4: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
+ let _5: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ let mut _6: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49
+ let _7: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ let mut _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47
+ let mut _9: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
+ let _10: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ let _11: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ let mut _12: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+ scope 1 {
+ debug v => _5; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ }
+ scope 2 {
+ debug e => _7; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ }
+ scope 3 {
+ debug v => _10; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ }
+ scope 4 {
+ debug e => _11; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +10:10
+ StorageLive(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ _4 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
+ switchInt(move _4) -> [0_isize: bb2, 1_isize: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20
+ }
+
+ bb1: {
+ StorageLive(_7); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ _7 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ StorageLive(_8); // scope 2 at $DIR/try_identity_e2e.rs:+5:46: +5:47
+ _8 = move _7; // scope 2 at $DIR/try_identity_e2e.rs:+5:46: +5:47
+ Deinit(_3); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ ((_3 as Break).0: E) = move _8; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ discriminant(_3) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ StorageDead(_8); // scope 2 at $DIR/try_identity_e2e.rs:+5:47: +5:48
+ StorageDead(_7); // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48
+ _9 = discriminant(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ switchInt(move _9) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
+ }
+
+ bb2: {
+ StorageLive(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ _5 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ StorageLive(_6); // scope 1 at $DIR/try_identity_e2e.rs:+4:48: +4:49
+ _6 = move _5; // scope 1 at $DIR/try_identity_e2e.rs:+4:48: +4:49
+ Deinit(_3); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ ((_3 as Continue).0: T) = move _6; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ discriminant(_3) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ StorageDead(_6); // scope 1 at $DIR/try_identity_e2e.rs:+4:49: +4:50
+ StorageDead(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50
+ _9 = discriminant(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ switchInt(move _9) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
+ }
+
+ bb3: {
+ StorageLive(_11); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ _11 = move ((_3 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ StorageLive(_12); // scope 4 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+ _12 = move _11; // scope 4 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+ Deinit(_0); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ ((_0 as Err).0: E) = move _12; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ discriminant(_0) = 1; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ StorageDead(_12); // scope 4 at $DIR/try_identity_e2e.rs:+9:50: +9:51
+ StorageDead(_11); // scope 0 at $DIR/try_identity_e2e.rs:+9:50: +9:51
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+11:5: +11:6
+ StorageDead(_3); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ }
+
+ bb4: {
+ unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ }
+
+ bb5: {
+ StorageLive(_10); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ _10 = move ((_3 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ _2 = move _10; // scope 3 at $DIR/try_identity_e2e.rs:+8:41: +8:42
+ StorageDead(_10); // scope 0 at $DIR/try_identity_e2e.rs:+8:41: +8:42
+ Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ ((_0 as Ok).0: T) = move _2; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+11:5: +11:6
+ StorageDead(_3); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ }
+}
diff --git a/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
new file mode 100644
index 000000000..18d3e0fb2
--- /dev/null
+++ b/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
@@ -0,0 +1,53 @@
+// MIR for `old` after PreCodegen
+
+fn old(_1: Result<T, E>) -> Result<T, E> {
+ debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
+ let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
+ let mut _2: T; // in scope 0 at $DIR/try_identity_e2e.rs:+2:9: +5:10
+ let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
+ let _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ let _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ let mut _6: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+ scope 1 {
+ debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ }
+ scope 2 {
+ debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +5:10
+ _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
+ switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ StorageLive(_6); // scope 2 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+ _6 = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+ Deinit(_0); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ ((_0 as Err).0: E) = move _6; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ discriminant(_0) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ StorageDead(_6); // scope 2 at $DIR/try_identity_e2e.rs:+4:35: +4:36
+ StorageDead(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:35: +4:36
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+6:5: +6:6
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
+ }
+
+ bb2: {
+ unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ _2 = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+3:22: +3:23
+ StorageDead(_4); // scope 0 at $DIR/try_identity_e2e.rs:+3:22: +3:23
+ Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ ((_0 as Ok).0: T) = move _2; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+6:5: +6:6
+ return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
+ }
+}
diff --git a/src/test/mir-opt/try_identity_e2e.rs b/src/test/mir-opt/try_identity_e2e.rs
new file mode 100644
index 000000000..00cb80f50
--- /dev/null
+++ b/src/test/mir-opt/try_identity_e2e.rs
@@ -0,0 +1,34 @@
+// Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings
+// of that syntax.
+
+use std::ops::ControlFlow;
+
+// EMIT_MIR try_identity_e2e.new.PreCodegen.after.mir
+fn new<T, E>(x: Result<T, E>) -> Result<T, E> {
+ Ok(
+ match {
+ match x {
+ Ok(v) => ControlFlow::Continue(v),
+ Err(e) => ControlFlow::Break(e),
+ }
+ } {
+ ControlFlow::Continue(v) => v,
+ ControlFlow::Break(e) => return Err(e),
+ }
+ )
+}
+
+// EMIT_MIR try_identity_e2e.old.PreCodegen.after.mir
+fn old<T, E>(x: Result<T, E>) -> Result<T, E> {
+ Ok(
+ match x {
+ Ok(v) => v,
+ Err(e) => return Err(e),
+ }
+ )
+}
+
+fn main() {
+ let _ = new::<(), ()>(Ok(()));
+ let _ = old::<(), ()>(Ok(()));
+}
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
index 6e9a8b4d9..6a5021139 100644
--- a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
+++ b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
@@ -15,9 +15,9 @@ fn move_out_by_subslice() -> () {
let mut _11: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26
scope 1 {
debug a => _1; // in scope 1 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
- let _12: [std::boxed::Box<i32>; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ let _12: [std::boxed::Box<i32>; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12
scope 4 {
- debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:12
}
}
scope 2 {
@@ -77,8 +77,8 @@ fn move_out_by_subslice() -> () {
bb6: {
StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27
FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10
- StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
- _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17
+ StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12
+ _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12
_0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +3:2
drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2
}
diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
index 34c38d24c..6ed53643f 100644
--- a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
@@ -11,8 +11,6 @@ fn process_never(_1: *const !) -> () {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14
- StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:+2:1: +2:2
unreachable; // scope 0 at $DIR/uninhabited-enum.rs:+0:39: +2:2
}
}
diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
index 3d860dac3..4aa5ba007 100644
--- a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+++ b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -18,6 +18,10 @@ fn main() -> () {
Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
_3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ switchInt(move _3) -> [2_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
+ }
+
+ bb1: {
StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
_5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
// mir::Constant
@@ -32,10 +36,14 @@ fn main() -> () {
Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
_8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
- switchInt(move _8) -> [4_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
+ switchInt(move _8) -> [4_isize: bb5, 5_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
}
- bb1: {
+ bb2: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ }
+
+ bb3: {
StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
_9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
// mir::Constant
@@ -43,18 +51,22 @@ fn main() -> () {
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
- goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ goto -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
}
- bb2: {
+ bb4: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ }
+
+ bb5: {
_6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
// mir::Constant
// + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ goto -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
}
- bb3: {
+ bb6: {
StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
_0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2
diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
index 023f6ae32..c3d356aed 100644
--- a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
+++ b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff
@@ -19,8 +19,8 @@
Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
_3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
-- switchInt(move _3) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
-+ switchInt(move _3) -> bb1; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
+- switchInt(move _3) -> [0_isize: bb3, 1_isize: bb4, 2_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
++ switchInt(move _3) -> [2_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19
}
bb1: {
@@ -31,18 +31,22 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24
StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
- goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
+ goto -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24
}
bb2: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19
+ }
+
+ bb3: {
_1 = const "A(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
// mir::Constant
// + span: $DIR/uninhabited_enum_branching.rs:21:24: 21:34
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
+ goto -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34
}
- bb3: {
+ bb4: {
StorageLive(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
_4 = const "B(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
// mir::Constant
@@ -50,10 +54,10 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_1 = &(*_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34
StorageDead(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34
- goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34
+ goto -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34
}
- bb4: {
+ bb5: {
StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7
StorageLive(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6
@@ -61,10 +65,10 @@
Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
_8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
- switchInt(move _8) -> [4_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
+ switchInt(move _8) -> [4_isize: bb8, 5_isize: bb6, otherwise: bb7]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19
}
- bb5: {
+ bb6: {
StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
_9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
// mir::Constant
@@ -72,18 +76,22 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24
StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
- goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
+ goto -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24
}
- bb6: {
+ bb7: {
+ unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19
+ }
+
+ bb8: {
_6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
// mir::Constant
// + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
+ goto -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24
}
- bb7: {
+ bb9: {
StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7
_0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
index a5e7f5269..ec5612ad7 100644
--- a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+++ b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -32,7 +32,7 @@ fn main() -> () {
StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
_4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
_5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
- switchInt(move _5) -> [2_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
+ switchInt(move _5) -> [2_isize: bb3, 3_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
}
bb1: {
@@ -43,10 +43,14 @@ fn main() -> () {
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
- goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ goto -> bb4; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
}
bb2: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ }
+
+ bb3: {
StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
_7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
// mir::Constant
@@ -54,18 +58,18 @@ fn main() -> () {
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
- goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ goto -> bb4; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
}
- bb3: {
+ bb4: {
StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
_10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
- switchInt(move _10) -> [2_isize: bb5, otherwise: bb4]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
+ switchInt(move _10) -> [2_isize: bb7, 3_isize: bb5, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
}
- bb4: {
+ bb5: {
StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
_13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
// mir::Constant
@@ -73,10 +77,14 @@ fn main() -> () {
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
- goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ goto -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
}
- bb5: {
+ bb6: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+ }
+
+ bb7: {
StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
_12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
// mir::Constant
@@ -84,10 +92,10 @@ fn main() -> () {
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
- goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ goto -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
}
- bb6: {
+ bb8: {
StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7
_0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2
StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
index 157518491..77b358a48 100644
--- a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
+++ b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
@@ -33,8 +33,8 @@
StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
_4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
_5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
-- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
-+ switchInt(move _5) -> [2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
+- switchInt(move _5) -> [0_isize: bb3, 1_isize: bb4, 2_isize: bb5, 3_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
++ switchInt(move _5) -> [2_isize: bb5, 3_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22
}
bb1: {
@@ -45,18 +45,22 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24
StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
- goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24
}
bb2: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22
+ }
+
+ bb3: {
_3 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
// mir::Constant
// + span: $DIR/uninhabited_enum_branching2.rs:22:24: 22:34
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34
}
- bb3: {
+ bb4: {
StorageLive(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
_6 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
// mir::Constant
@@ -64,10 +68,10 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_3 = &(*_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34
StorageDead(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34
- goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34
}
- bb4: {
+ bb5: {
StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
_7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
// mir::Constant
@@ -75,19 +79,19 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24
StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
- goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
+ goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24
}
- bb5: {
+ bb6: {
StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7
StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6
_10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
-- switchInt(move _10) -> [0_isize: bb7, 1_isize: bb8, 2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
-+ switchInt(move _10) -> [2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
+- switchInt(move _10) -> [0_isize: bb9, 1_isize: bb10, 2_isize: bb11, 3_isize: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
++ switchInt(move _10) -> [2_isize: bb11, 3_isize: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21
}
- bb6: {
+ bb7: {
StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
_13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
// mir::Constant
@@ -95,18 +99,22 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24
StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
- goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
+ goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24
}
- bb7: {
+ bb8: {
+ unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21
+ }
+
+ bb9: {
_9 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
// mir::Constant
// + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
+ goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34
}
- bb8: {
+ bb10: {
StorageLive(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
_11 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
// mir::Constant
@@ -114,10 +122,10 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_9 = &(*_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34
StorageDead(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34
- goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34
+ goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34
}
- bb9: {
+ bb11: {
StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
_12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
// mir::Constant
@@ -125,10 +133,10 @@
// + literal: Const { ty: &str, val: Value(Slice(..)) }
_9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24
StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
- goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
+ goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24
}
- bb10: {
+ bb12: {
StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7
_0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2
StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2
diff --git a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
index 52d9543e9..9cd4b8ccf 100644
--- a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
@@ -28,7 +28,7 @@
bb1: {
_2 = discriminant(_1); // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
- switchInt(move _2) -> [1_isize: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
-+ goto -> bb2; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
++ switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20
}
bb2: {
@@ -39,9 +39,10 @@
- StorageLive(_6); // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
- _6 = const true; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
-- }
--
-- bb3: {
++ unreachable; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16
+ }
+
+ bb3: {
- _4 = const 21_i32; // scope 2 at $DIR/unreachable.rs:+5:13: +5:20
- _5 = const (); // scope 2 at $DIR/unreachable.rs:+4:17: +6:10
- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10
diff --git a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
index 3d31553c4..afd6b00aa 100644
--- a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
@@ -29,8 +29,7 @@
bb1: {
_3 = discriminant(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
-- switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
-+ switchInt(move _3) -> [1_isize: bb2, otherwise: bb5]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
+ switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22
}
bb2: {
@@ -39,13 +38,11 @@
StorageLive(_5); // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10
StorageLive(_6); // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
_6 = _1; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
-- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
-+ goto -> bb3; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
+ switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13
}
bb3: {
-- _5 = loop_forever() -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27
-+ _5 = loop_forever() -> bb4; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27
+ _5 = loop_forever() -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27
// mir::Constant
// + span: $DIR/unreachable_diverging.rs:16:13: 16:25
// + literal: Const { ty: fn() {loop_forever}, val: Value(<ZST>) }
@@ -54,17 +51,17 @@
bb4: {
- _5 = const (); // scope 2 at $DIR/unreachable_diverging.rs:+5:10: +5:10
- goto -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10
-- }
--
-- bb5: {
- StorageDead(_6); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
- StorageDead(_5); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
- StorageLive(_7); // scope 2 at $DIR/unreachable_diverging.rs:+6:9: +6:22
++ unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10
+ }
+
+ bb5: {
+- StorageDead(_6); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
+- StorageDead(_5); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10
+- StorageLive(_7); // scope 2 at $DIR/unreachable_diverging.rs:+6:9: +6:22
unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+6:15: +6:19
}
-- bb6: {
-+ bb5: {
+ bb6: {
_0 = const (); // scope 1 at $DIR/unreachable_diverging.rs:+7:6: +7:6
StorageDead(_1); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2
StorageDead(_2); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs
index 670f61cd5..9ef3d8647 100644
--- a/src/test/mir-opt/unusual-item-types.rs
+++ b/src/test/mir-opt/unusual-item-types.rs
@@ -1,7 +1,7 @@
// Test that we don't ICE when trying to dump MIR for unusual item types and
// that we don't create filenames containing `<` and `>`
// compile-flags: -Zmir-opt-level=0
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
struct A;
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir
deleted file mode 100644
index a72e00ecd..000000000
--- a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `E::V::{constant#0}` 0 mir_map
-
-E::V::{constant#0}: isize = {
- let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
-
- bb0: {
- _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
- }
-}
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir
index a72e00ecd..a72e00ecd 100644
--- a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir
deleted file mode 100644
index 0686af46e..000000000
--- a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,12 +0,0 @@
-// MIR for `Test::X` 0 mir_map
-
-fn Test::X(_1: usize) -> Test {
- let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
-
- bb0: {
- Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- }
-}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
index 0686af46e..0686af46e 100644
--- a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir
deleted file mode 100644
index 7ffd242e0..000000000
--- a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir
+++ /dev/null
@@ -1,39 +0,0 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
-
-fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
- let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
-
- bb0: {
- goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb1: {
- return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb2 (cleanup): {
- resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb3: {
- goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb4 (cleanup): {
- drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb5: {
- drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- }
-
- bb6: {
- _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
- // mir::Constant
- // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) }
- }
-}
diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
index 7ffd242e0..7ffd242e0 100644
--- a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir
+++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir
deleted file mode 100644
index f7bc8d58f..000000000
--- a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
-
-const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
- let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
-
- bb0: {
- _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:35
- }
-}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
index f7bc8d58f..5579d25a1 100644
--- a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir
+++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
@@ -5,6 +5,6 @@ const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 =
bb0: {
_0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:35
+ return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:40
}
}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
deleted file mode 100644
index eef701114..000000000
--- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
+++ /dev/null
@@ -1,55 +0,0 @@
-- // MIR for `change_loop_body` before ConstProp
-+ // MIR for `change_loop_body` after ConstProp
-
- fn change_loop_body() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
- let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
- let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2
- let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32
- let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25
- let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6
- let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
- let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
- let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6
- scope 1 {
- debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
- scope 2 {
- }
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
- _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19
- StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
- Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
- discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32
-- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-+ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
-+ switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
- }
-
- bb1: {
- switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25
- }
-
- bb2: {
- _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15
- nop; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
- goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14
- }
-
- bb3: {
- StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
- nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6
- StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
- goto -> bb4; // scope 1 at no-location
- }
-
- bb4: {
- StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6
- StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
- return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff
index eef701114..eef701114 100644
--- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
deleted file mode 100644
index 15b0aece8..000000000
--- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
+++ /dev/null
@@ -1,17 +0,0 @@
-// MIR for `change_loop_body` after PreCodegen
-
-fn change_loop_body() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27
- let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
- scope 1 {
- debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15
- scope 2 {
- }
- }
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15
- StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2
- return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2
- }
-}
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir
index 15b0aece8..15b0aece8 100644
--- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir
diff --git a/src/test/mir-opt/while_let_loops.rs b/src/test/mir-opt/while_let_loops.rs
index f320a218c..fc56cd698 100644
--- a/src/test/mir-opt/while_let_loops.rs
+++ b/src/test/mir-opt/while_let_loops.rs
@@ -1,6 +1,5 @@
// EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff
// EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
pub fn change_loop_body() {
let mut _x = 0;
diff --git a/src/test/pretty/gat-bounds.rs b/src/test/pretty/gat-bounds.rs
index 8877c6cc9..0a361a383 100644
--- a/src/test/pretty/gat-bounds.rs
+++ b/src/test/pretty/gat-bounds.rs
@@ -3,8 +3,6 @@
// pretty-compare-only
-#![feature(generic_associated_types)]
-
trait X {
type Y<T>: Trait where Self: Sized;
}
diff --git a/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile b/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile
index 4a9b3d709..adc9e3d09 100644
--- a/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile
+++ b/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that if we build `b` against a version of `a` that has one set
# of types, it will not run with a dylib that has a different set of
diff --git a/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile b/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile
index eb6ad9bd1..735d91bd2 100644
--- a/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile
+++ b/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling
diff --git a/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile
index c14006cc2..60d9c7c37 100644
--- a/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile
+++ b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that -A warnings makes the 'empty trait list for derive' warning go away
OUT=$(shell $(RUSTC) foo.rs -A warnings 2>&1 | grep "warning" )
diff --git a/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile
index 3eecaf931..1ce8d0ec2 100644
--- a/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile
+++ b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that -A warnings makes the 'empty trait list for derive' warning go away
DEP=$(shell $(RUSTC) bar.rs)
diff --git a/src/test/run-make-fulldeps/archive-duplicate-names/Makefile b/src/test/run-make-fulldeps/archive-duplicate-names/Makefile
index 93711c41d..bbdcd2a34 100644
--- a/src/test/run-make-fulldeps/archive-duplicate-names/Makefile
+++ b/src/test/run-make-fulldeps/archive-duplicate-names/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
mkdir $(TMPDIR)/a
diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile b/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile
index 5b5d620ef..513311c82 100644
--- a/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile
+++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --crate-type=staticlib nonclike.rs
diff --git a/src/test/run-make-fulldeps/atomic-lock-free/Makefile b/src/test/run-make-fulldeps/atomic-lock-free/Makefile
index 9e8b4fabf..37e59624a 100644
--- a/src/test/run-make-fulldeps/atomic-lock-free/Makefile
+++ b/src/test/run-make-fulldeps/atomic-lock-free/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# This tests ensure that atomic types are never lowered into runtime library calls that are not
# guaranteed to be lock-free.
diff --git a/src/test/run-make-fulldeps/bare-outfile/Makefile b/src/test/run-make-fulldeps/bare-outfile/Makefile
index baa4c1c02..858466e94 100644
--- a/src/test/run-make-fulldeps/bare-outfile/Makefile
+++ b/src/test/run-make-fulldeps/bare-outfile/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
cp foo.rs $(TMPDIR)
diff --git a/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile b/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile
index c524610bf..ac6877892 100644
--- a/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile
+++ b/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-macos
#
diff --git a/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile b/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile
index 91343e73e..c65d648b9 100644
--- a/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile
+++ b/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-macos
#
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile
index 98e112a37..2a371b545 100644
--- a/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile
+++ b/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(TMPDIR)/$(call BIN,bar)
$(call RUN,bar)
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile
index 687b59ac0..d38bcef30 100644
--- a/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile
+++ b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-freebsd
# FIXME
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile
index f124ca2ab..9ce2a34e6 100644
--- a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile
+++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) checkrust.rs
diff --git a/src/test/run-make-fulldeps/c-static-dylib/Makefile b/src/test/run-make-fulldeps/c-static-dylib/Makefile
index f88786857..5b78005e3 100644
--- a/src/test/run-make-fulldeps/c-static-dylib/Makefile
+++ b/src/test/run-make-fulldeps/c-static-dylib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,cfoo)
$(RUSTC) foo.rs -C prefer-dynamic
diff --git a/src/test/run-make-fulldeps/c-static-rlib/Makefile b/src/test/run-make-fulldeps/c-static-rlib/Makefile
index be22b2728..11a3cf194 100644
--- a/src/test/run-make-fulldeps/c-static-rlib/Makefile
+++ b/src/test/run-make-fulldeps/c-static-rlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,cfoo)
$(RUSTC) foo.rs
diff --git a/src/test/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile b/src/test/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile
index a8515c533..134f000d4 100644
--- a/src/test/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile
+++ b/src/test/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: archive
# Compile `main.rs`, which will link into our library, and run it.
diff --git a/src/test/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile b/src/test/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile
index 9553b7aee..e93ec99da 100644
--- a/src/test/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile
+++ b/src/test/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,add)
$(RUSTC) main.rs
diff --git a/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile b/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile
index fead197ce..82351e220 100644
--- a/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile
+++ b/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
echo a | $(CGREP) a
diff --git a/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile b/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile
index 23491d814..324791af8 100644
--- a/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile
+++ b/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile
@@ -1,7 +1,7 @@
# Test that allocator-related symbols don't show up as exported from a cdylib as
# they're internal to Rust and not part of the public ABI.
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# FIXME: The __rdl_ and __rust_ symbol still remains, no matter using MSVC or GNU
diff --git a/src/test/run-make-fulldeps/codegen-options-parsing/Makefile b/src/test/run-make-fulldeps/codegen-options-parsing/Makefile
index f1410b69b..b063593c9 100644
--- a/src/test/run-make-fulldeps/codegen-options-parsing/Makefile
+++ b/src/test/run-make-fulldeps/codegen-options-parsing/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
#Option taking a number
diff --git a/src/test/run-make-fulldeps/compile-stdin/Makefile b/src/test/run-make-fulldeps/compile-stdin/Makefile
index 1442224cf..be1554869 100644
--- a/src/test/run-make-fulldeps/compile-stdin/Makefile
+++ b/src/test/run-make-fulldeps/compile-stdin/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
echo 'fn main(){}' | $(RUSTC) -
diff --git a/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile
index bd7f62d5c..d4ff7d8da 100644
--- a/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile
+++ b/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
mkdir -p $(TMPDIR)/a $(TMPDIR)/b
diff --git a/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile
index e22b937a0..c16bf7af6 100644
--- a/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile
+++ b/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(TMPDIR)/libnative.a
mkdir -p $(TMPDIR)/crate
diff --git a/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile
index 0cf5d1855..74917570a 100644
--- a/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile
+++ b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-windows-gnu
diff --git a/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile b/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile
index f79e4c3f4..d083aaa66 100644
--- a/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile
+++ b/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --edition=2021 --crate-type=rlib ../../../../library/core/src/lib.rs --cfg no_fp_fmt_parse
diff --git a/src/test/run-make-fulldeps/crate-data-smoke/Makefile b/src/test/run-make-fulldeps/crate-data-smoke/Makefile
index 1afda4574..a453f65ff 100644
--- a/src/test/run-make-fulldeps/crate-data-smoke/Makefile
+++ b/src/test/run-make-fulldeps/crate-data-smoke/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
[ `$(RUSTC) --print crate-name crate.rs` = "foo" ]
diff --git a/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile b/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile
index 091508cd8..4f25a865e 100644
--- a/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile
+++ b/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# Ensure that crates compiled with different rustc versions cannot
# be dynamically linked.
diff --git a/src/test/run-make-fulldeps/crate-name-priority/Makefile b/src/test/run-make-fulldeps/crate-name-priority/Makefile
index 17ecb33ab..08a07c325 100644
--- a/src/test/run-make-fulldeps/crate-name-priority/Makefile
+++ b/src/test/run-make-fulldeps/crate-name-priority/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
index 3ca2a8afa..acaebf439 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
@@ -3,7 +3,7 @@
# This test makes sure that cross-language inlining actually works by checking
# the generated machine code.
--include ../tools.mk
+include ../tools.mk
all: cpp-executable rust-executable
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile
index f8efeca56..70085d9bd 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile
@@ -5,7 +5,7 @@
# can be executed without anything crashing. It does not test whether PGO or
# xLTO have any specific effect on the generated code.
--include ../tools.mk
+include ../tools.mk
COMMON_FLAGS=-Copt-level=3 -Ccodegen-units=1
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile
index f70b411d7..6f1caa31a 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore windows due to libLLVM being present in PATH and the PATH and library path being the same
# (so fixing it is harder). See #57765 for context
diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile
index b4394cb5b..92058f952 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile
@@ -1,5 +1,5 @@
--include ../tools.mk
+include ../tools.mk
# ignore windows due to libLLVM being present in PATH and the PATH and library path being the same
# (so fixing it is harder). See #57765 for context
diff --git a/src/test/run-make-fulldeps/debug-assertions/Makefile b/src/test/run-make-fulldeps/debug-assertions/Makefile
index 76ada90f1..73beb4b03 100644
--- a/src/test/run-make-fulldeps/debug-assertions/Makefile
+++ b/src/test/run-make-fulldeps/debug-assertions/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) debug.rs -C debug-assertions=no
diff --git a/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile
index 2fd84639f..b4dc44ad2 100644
--- a/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile
+++ b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs --emit dep-info
diff --git a/src/test/run-make-fulldeps/dep-info-spaces/Makefile b/src/test/run-make-fulldeps/dep-info-spaces/Makefile
index 339a751ff..0cfe513e4 100644
--- a/src/test/run-make-fulldeps/dep-info-spaces/Makefile
+++ b/src/test/run-make-fulldeps/dep-info-spaces/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# ignore-freebsd
diff --git a/src/test/run-make-fulldeps/dep-info/Makefile b/src/test/run-make-fulldeps/dep-info/Makefile
index afb9db177..c76f43a8e 100644
--- a/src/test/run-make-fulldeps/dep-info/Makefile
+++ b/src/test/run-make-fulldeps/dep-info/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# ignore-freebsd
diff --git a/src/test/run-make-fulldeps/dylib-chain/Makefile b/src/test/run-make-fulldeps/dylib-chain/Makefile
index a33177197..1139822f4 100644
--- a/src/test/run-make-fulldeps/dylib-chain/Makefile
+++ b/src/test/run-make-fulldeps/dylib-chain/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) m1.rs -C prefer-dynamic
diff --git a/src/test/run-make-fulldeps/emit-stack-sizes/Makefile b/src/test/run-make-fulldeps/emit-stack-sizes/Makefile
index d27028948..f636ebd28 100644
--- a/src/test/run-make-fulldeps/emit-stack-sizes/Makefile
+++ b/src/test/run-make-fulldeps/emit-stack-sizes/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# ignore-macos
diff --git a/src/test/run-make-fulldeps/emit/Makefile b/src/test/run-make-fulldeps/emit/Makefile
index e0b57107e..78e68bd61 100644
--- a/src/test/run-make-fulldeps/emit/Makefile
+++ b/src/test/run-make-fulldeps/emit/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -Copt-level=0 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs
diff --git a/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile
index fef12c4da..0eae41d72 100644
--- a/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile
+++ b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs --crate-type staticlib
diff --git a/src/test/run-make-fulldeps/error-writing-dependencies/Makefile b/src/test/run-make-fulldeps/error-writing-dependencies/Makefile
index cbc96901a..a5d30a647 100644
--- a/src/test/run-make-fulldeps/error-writing-dependencies/Makefile
+++ b/src/test/run-make-fulldeps/error-writing-dependencies/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
# Let's get a nice error message
diff --git a/src/test/run-make-fulldeps/exit-code/Makefile b/src/test/run-make-fulldeps/exit-code/Makefile
index 007f19852..3ffaafe90 100644
--- a/src/test/run-make-fulldeps/exit-code/Makefile
+++ b/src/test/run-make-fulldeps/exit-code/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) success.rs; [ $$? -eq 0 ]
diff --git a/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile b/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile
index b84e93075..54596c2f0 100644
--- a/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile
+++ b/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) lib.rs
diff --git a/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile b/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile
index 81930e969..a8f142a64 100644
--- a/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Attempt to build this dependency tree:
#
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
index 38d1d5bb8..a0b7c15ed 100644
--- a/src/test/run-make-fulldeps/extern-flag-fun/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=rlib
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/Makefile b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
index 4849fc62f..0f23815b6 100644
--- a/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test mixing pathless --extern with paths.
diff --git a/src/test/run-make-fulldeps/extern-flag-rename-transitive/Makefile b/src/test/run-make-fulldeps/extern-flag-rename-transitive/Makefile
index 4354209a7..d16a8e208 100644
--- a/src/test/run-make-fulldeps/extern-flag-rename-transitive/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-rename-transitive/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs
diff --git a/src/test/run-make-fulldeps/extern-fn-generic/Makefile b/src/test/run-make-fulldeps/extern-fn-generic/Makefile
index cf897dba1..71746fb10 100644
--- a/src/test/run-make-fulldeps/extern-fn-generic/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-generic/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) testcrate.rs
diff --git a/src/test/run-make-fulldeps/extern-fn-mangle/Makefile b/src/test/run-make-fulldeps/extern-fn-mangle/Makefile
index 042048ec2..4f5d026f2 100644
--- a/src/test/run-make-fulldeps/extern-fn-mangle/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-mangle/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) test.rs
diff --git a/src/test/run-make-fulldeps/extern-fn-reachable/Makefile b/src/test/run-make-fulldeps/extern-fn-reachable/Makefile
index 9231a2b35..05bdb8d65 100644
--- a/src/test/run-make-fulldeps/extern-fn-reachable/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-reachable/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows-msvc
diff --git a/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile
index 042048ec2..4f5d026f2 100644
--- a/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) test.rs
diff --git a/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile b/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile
index 8977e14c3..1fa708950 100644
--- a/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,ctest)
$(RUSTC) test.rs
diff --git a/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile
index 042048ec2..4f5d026f2 100644
--- a/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) test.rs
diff --git a/src/test/run-make-fulldeps/extern-fn-with-union/Makefile b/src/test/run-make-fulldeps/extern-fn-with-union/Makefile
index 71a5407e8..40bae923e 100644
--- a/src/test/run-make-fulldeps/extern-fn-with-union/Makefile
+++ b/src/test/run-make-fulldeps/extern-fn-with-union/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,ctest)
$(RUSTC) testcrate.rs
diff --git a/src/test/run-make-fulldeps/extern-multiple-copies/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies/Makefile
index 1631aa806..00668a6bc 100644
--- a/src/test/run-make-fulldeps/extern-multiple-copies/Makefile
+++ b/src/test/run-make-fulldeps/extern-multiple-copies/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo1.rs
diff --git a/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile
index 567d7e78a..84de2ebf3 100644
--- a/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile
+++ b/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo1.rs
diff --git a/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile b/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile
index 7d063a4c8..c57b062cd 100644
--- a/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile
+++ b/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) libc.rs -Cmetadata=foo
diff --git a/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
index e46390a9d..470448cf5 100644
--- a/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
+++ b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -C extra-filename=bar foo.rs -C save-temps
diff --git a/src/test/run-make-fulldeps/foreign-double-unwind/Makefile b/src/test/run-make-fulldeps/foreign-double-unwind/Makefile
index 27cf4d19c..ea2fe9ff8 100644
--- a/src/test/run-make-fulldeps/foreign-double-unwind/Makefile
+++ b/src/test/run-make-fulldeps/foreign-double-unwind/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: foo
$(call RUN,foo) | $(CGREP) -v unreachable
diff --git a/src/test/run-make-fulldeps/foreign-exceptions/Makefile b/src/test/run-make-fulldeps/foreign-exceptions/Makefile
index 7eba52f3c..38fe2773d 100644
--- a/src/test/run-make-fulldeps/foreign-exceptions/Makefile
+++ b/src/test/run-make-fulldeps/foreign-exceptions/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: foo
$(call RUN,foo)
diff --git a/src/test/run-make-fulldeps/fpic/Makefile b/src/test/run-make-fulldeps/fpic/Makefile
index a3d0190ee..5986de366 100644
--- a/src/test/run-make-fulldeps/fpic/Makefile
+++ b/src/test/run-make-fulldeps/fpic/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# ignore-macos
diff --git a/src/test/run-make-fulldeps/glibc-staticlib-args/Makefile b/src/test/run-make-fulldeps/glibc-staticlib-args/Makefile
index ad841ec61..39e64bacf 100644
--- a/src/test/run-make-fulldeps/glibc-staticlib-args/Makefile
+++ b/src/test/run-make-fulldeps/glibc-staticlib-args/Makefile
@@ -1,7 +1,7 @@
# only-gnu
# only-linux
--include ../tools.mk
+include ../tools.mk
# This ensures that std::env::args works in a library called from C on glibc Linux.
diff --git a/src/test/run-make-fulldeps/hir-tree/Makefile b/src/test/run-make-fulldeps/hir-tree/Makefile
index 3412c8ce1..b0450ea4b 100644
--- a/src/test/run-make-fulldeps/hir-tree/Makefile
+++ b/src/test/run-make-fulldeps/hir-tree/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that hir-tree output doesn't crash and includes
# the string constant we would expect to see.
diff --git a/src/test/run-make-fulldeps/include_bytes_deps/Makefile b/src/test/run-make-fulldeps/include_bytes_deps/Makefile
index f91af88ef..696dfd207 100644
--- a/src/test/run-make-fulldeps/include_bytes_deps/Makefile
+++ b/src/test/run-make-fulldeps/include_bytes_deps/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-freebsd
diff --git a/src/test/run-make-fulldeps/incr-add-rust-src-component/Makefile b/src/test/run-make-fulldeps/incr-add-rust-src-component/Makefile
index 371f94715..5c1d953cc 100644
--- a/src/test/run-make-fulldeps/incr-add-rust-src-component/Makefile
+++ b/src/test/run-make-fulldeps/incr-add-rust-src-component/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# rust-lang/rust#70924: Test that if we add rust-src component in between two
# incremental compiles, the compiler does not ICE on the second.
diff --git a/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile
index 0cab955f6..9945821db 100644
--- a/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile
+++ b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2
diff --git a/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile b/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile
index 0a50859cd..dc5b55a99 100644
--- a/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile
+++ b/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# The rust crate foo will link to the native library foo, while the rust crate
# bar will link to the native library bar. There is also a dependency between
diff --git a/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
index 203772856..3c4dade0f 100644
--- a/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
+++ b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows-msvc
#
diff --git a/src/test/run-make-fulldeps/invalid-library/Makefile b/src/test/run-make-fulldeps/invalid-library/Makefile
index de463a330..910d9af7b 100644
--- a/src/test/run-make-fulldeps/invalid-library/Makefile
+++ b/src/test/run-make-fulldeps/invalid-library/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
touch $(TMPDIR)/lib.rmeta
diff --git a/src/test/run-make-fulldeps/invalid-staticlib/Makefile b/src/test/run-make-fulldeps/invalid-staticlib/Makefile
index 3a91902cc..3f0f74ce3 100644
--- a/src/test/run-make-fulldeps/invalid-staticlib/Makefile
+++ b/src/test/run-make-fulldeps/invalid-staticlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
touch $(TMPDIR)/libfoo.a
diff --git a/src/test/run-make-fulldeps/issue-11908/Makefile b/src/test/run-make-fulldeps/issue-11908/Makefile
index cf6572c27..47005537e 100644
--- a/src/test/run-make-fulldeps/issue-11908/Makefile
+++ b/src/test/run-make-fulldeps/issue-11908/Makefile
@@ -5,7 +5,7 @@
# and then our aux-built libraries will collide with liburl (they have
# the same version listed)
--include ../tools.mk
+include ../tools.mk
all:
mkdir $(TMPDIR)/other
diff --git a/src/test/run-make-fulldeps/issue-14500/Makefile b/src/test/run-make-fulldeps/issue-14500/Makefile
index 0c0e331da..52550e570 100644
--- a/src/test/run-make-fulldeps/issue-14500/Makefile
+++ b/src/test/run-make-fulldeps/issue-14500/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test to make sure that reachable extern fns are always available in final
# productcs, including when LTO is used. In this test, the `foo` crate has a
diff --git a/src/test/run-make-fulldeps/issue-14698/Makefile b/src/test/run-make-fulldeps/issue-14698/Makefile
index dbe8317db..a1cfb5aba 100644
--- a/src/test/run-make-fulldeps/issue-14698/Makefile
+++ b/src/test/run-make-fulldeps/issue-14698/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
TMP=fake TMPDIR=fake $(RUSTC) foo.rs 2>&1 | $(CGREP) "couldn't create a temp dir:"
diff --git a/src/test/run-make-fulldeps/issue-15460/Makefile b/src/test/run-make-fulldeps/issue-15460/Makefile
index 846805686..1648d0c0c 100644
--- a/src/test/run-make-fulldeps/issue-15460/Makefile
+++ b/src/test/run-make-fulldeps/issue-15460/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,foo)
$(RUSTC) foo.rs -C extra-filename=-383hf8 -C prefer-dynamic
diff --git a/src/test/run-make-fulldeps/issue-18943/Makefile b/src/test/run-make-fulldeps/issue-18943/Makefile
index bef70a0ed..fc40d756d 100644
--- a/src/test/run-make-fulldeps/issue-18943/Makefile
+++ b/src/test/run-make-fulldeps/issue-18943/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Regression test for ICE #18943 when compiling as lib
diff --git a/src/test/run-make-fulldeps/issue-19371/Makefile b/src/test/run-make-fulldeps/issue-19371/Makefile
index 9f3ec7846..994e50801 100644
--- a/src/test/run-make-fulldeps/issue-19371/Makefile
+++ b/src/test/run-make-fulldeps/issue-19371/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# This test ensures that rustc compile_input can be called twice in one task
# without causing a panic.
diff --git a/src/test/run-make-fulldeps/issue-20626/Makefile b/src/test/run-make-fulldeps/issue-20626/Makefile
index 0487b2404..f76f31e79 100644
--- a/src/test/run-make-fulldeps/issue-20626/Makefile
+++ b/src/test/run-make-fulldeps/issue-20626/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test output to be four
# The original error only occurred when printing, not when comparing using assert!
diff --git a/src/test/run-make-fulldeps/issue-22131/Makefile b/src/test/run-make-fulldeps/issue-22131/Makefile
index d76aaf5c1..770f4b04e 100644
--- a/src/test/run-make-fulldeps/issue-22131/Makefile
+++ b/src/test/run-make-fulldeps/issue-22131/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: foo.rs
$(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs
diff --git a/src/test/run-make-fulldeps/issue-24445/Makefile b/src/test/run-make-fulldeps/issue-24445/Makefile
index f7ad238af..2a12226a6 100644
--- a/src/test/run-make-fulldeps/issue-24445/Makefile
+++ b/src/test/run-make-fulldeps/issue-24445/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-linux
diff --git a/src/test/run-make-fulldeps/issue-25581/Makefile b/src/test/run-make-fulldeps/issue-25581/Makefile
index 042048ec2..4f5d026f2 100644
--- a/src/test/run-make-fulldeps/issue-25581/Makefile
+++ b/src/test/run-make-fulldeps/issue-25581/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) test.rs
diff --git a/src/test/run-make-fulldeps/issue-26006/Makefile b/src/test/run-make-fulldeps/issue-26006/Makefile
index dd023c32b..0ff073020 100644
--- a/src/test/run-make-fulldeps/issue-26006/Makefile
+++ b/src/test/run-make-fulldeps/issue-26006/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
diff --git a/src/test/run-make-fulldeps/issue-26092/Makefile b/src/test/run-make-fulldeps/issue-26092/Makefile
index 885f45a02..96822e769 100644
--- a/src/test/run-make-fulldeps/issue-26092/Makefile
+++ b/src/test/run-make-fulldeps/issue-26092/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# This test ensures that rustc does not panic with `-o ""` option.
diff --git a/src/test/run-make-fulldeps/issue-28595/Makefile b/src/test/run-make-fulldeps/issue-28595/Makefile
index 61e9d0c65..30a1d9c56 100644
--- a/src/test/run-make-fulldeps/issue-28595/Makefile
+++ b/src/test/run-make-fulldeps/issue-28595/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,a) $(call NATIVE_STATICLIB,b)
$(RUSTC) a.rs
diff --git a/src/test/run-make-fulldeps/issue-28766/Makefile b/src/test/run-make-fulldeps/issue-28766/Makefile
index 1f47ef15b..96d0bdc2b 100644
--- a/src/test/run-make-fulldeps/issue-28766/Makefile
+++ b/src/test/run-make-fulldeps/issue-28766/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -O foo.rs
diff --git a/src/test/run-make-fulldeps/issue-30063/Makefile b/src/test/run-make-fulldeps/issue-30063/Makefile
index a76051dc8..e4ede598f 100644
--- a/src/test/run-make-fulldeps/issue-30063/Makefile
+++ b/src/test/run-make-fulldeps/issue-30063/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
rm -f $(TMPDIR)/foo-output
diff --git a/src/test/run-make-fulldeps/issue-33329/Makefile b/src/test/run-make-fulldeps/issue-33329/Makefile
index 591e4e3dd..9c149440d 100644
--- a/src/test/run-make-fulldeps/issue-33329/Makefile
+++ b/src/test/run-make-fulldeps/issue-33329/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --target x86_64_unknown-linux-musl main.rs 2>&1 | $(CGREP) \
diff --git a/src/test/run-make-fulldeps/issue-35164/Makefile b/src/test/run-make-fulldeps/issue-35164/Makefile
index a95125c56..38aa6f126 100644
--- a/src/test/run-make-fulldeps/issue-35164/Makefile
+++ b/src/test/run-make-fulldeps/issue-35164/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) main.rs --error-format json 2>&1 | $(CGREP) -e '"byte_start":23\b' '"byte_end":29\b'
diff --git a/src/test/run-make-fulldeps/issue-37839/Makefile b/src/test/run-make-fulldeps/issue-37839/Makefile
index f17ce537f..de50bd713 100644
--- a/src/test/run-make-fulldeps/issue-37839/Makefile
+++ b/src/test/run-make-fulldeps/issue-37839/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) a.rs && $(RUSTC) b.rs
diff --git a/src/test/run-make-fulldeps/issue-37893/Makefile b/src/test/run-make-fulldeps/issue-37893/Makefile
index 27b69baf9..33a60830e 100644
--- a/src/test/run-make-fulldeps/issue-37893/Makefile
+++ b/src/test/run-make-fulldeps/issue-37893/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) a.rs && $(RUSTC) b.rs && $(RUSTC) c.rs
diff --git a/src/test/run-make-fulldeps/issue-38237/Makefile b/src/test/run-make-fulldeps/issue-38237/Makefile
index 0a681401b..75121d040 100644
--- a/src/test/run-make-fulldeps/issue-38237/Makefile
+++ b/src/test/run-make-fulldeps/issue-38237/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs; $(RUSTC) bar.rs
diff --git a/src/test/run-make-fulldeps/issue-40535/Makefile b/src/test/run-make-fulldeps/issue-40535/Makefile
index 49db1d43e..155c88252 100644
--- a/src/test/run-make-fulldeps/issue-40535/Makefile
+++ b/src/test/run-make-fulldeps/issue-40535/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# The ICE occurred in the following situation:
# * `foo` declares `extern crate bar, baz`, depends only on `bar` (forgetting `baz` in `Cargo.toml`)
diff --git a/src/test/run-make-fulldeps/issue-46239/Makefile b/src/test/run-make-fulldeps/issue-46239/Makefile
index 698a605f7..a93ef3212 100644
--- a/src/test/run-make-fulldeps/issue-46239/Makefile
+++ b/src/test/run-make-fulldeps/issue-46239/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) main.rs -C opt-level=1
diff --git a/src/test/run-make-fulldeps/issue-47551/Makefile b/src/test/run-make-fulldeps/issue-47551/Makefile
index f4495e6b6..5a6ac7257 100644
--- a/src/test/run-make-fulldeps/issue-47551/Makefile
+++ b/src/test/run-make-fulldeps/issue-47551/Makefile
@@ -1,7 +1,7 @@
# only-linux
# ignore-32bit
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) eh_frame-terminator.rs
diff --git a/src/test/run-make-fulldeps/issue-47551/eh_frame-terminator.rs b/src/test/run-make-fulldeps/issue-47551/eh_frame-terminator.rs
index 2f740dc4f..a2c7a31b7 100644
--- a/src/test/run-make-fulldeps/issue-47551/eh_frame-terminator.rs
+++ b/src/test/run-make-fulldeps/issue-47551/eh_frame-terminator.rs
@@ -1,6 +1,5 @@
// run-pass
-#![feature(backtrace)]
#[derive(Clone, Copy)]
struct Foo {
array: [u64; 10240],
diff --git a/src/test/run-make-fulldeps/issue-51671/Makefile b/src/test/run-make-fulldeps/issue-51671/Makefile
index ba3d3b710..1d1d370d3 100644
--- a/src/test/run-make-fulldeps/issue-51671/Makefile
+++ b/src/test/run-make-fulldeps/issue-51671/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows-msvc
diff --git a/src/test/run-make-fulldeps/issue-53964/Makefile b/src/test/run-make-fulldeps/issue-53964/Makefile
index c56beb52f..6bd830213 100644
--- a/src/test/run-make-fulldeps/issue-53964/Makefile
+++ b/src/test/run-make-fulldeps/issue-53964/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) panic.rs
diff --git a/src/test/run-make-fulldeps/issue-64153/Makefile b/src/test/run-make-fulldeps/issue-64153/Makefile
index 9c0c3fe6e..f42ea620f 100644
--- a/src/test/run-make-fulldeps/issue-64153/Makefile
+++ b/src/test/run-make-fulldeps/issue-64153/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# `llvm-objdump`'s output looks different on windows than on other platforms.
# It should be enough to check on Unix platforms, so:
@@ -19,7 +19,7 @@ all:
# Dump all the symbols from the staticlib into `syms`
"$(LLVM_BIN_DIR)"/llvm-objdump -t $(TMPDIR)/libdownstream.a > $(TMPDIR)/syms
# Count the global instances of `issue64153_test_function`. There'll be 2
- # if the `upstream` object file got erronously included twice.
+ # if the `upstream` object file got erroneously included twice.
# The line we are testing for with the regex looks something like:
# 0000000000000000 g F .text.issue64153_test_function 00000023 issue64153_test_function
grep -c -e "[[:space:]]g[[:space:]]*F[[:space:]].*issue64153_test_function" $(TMPDIR)/syms > $(TMPDIR)/count
diff --git a/src/test/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile b/src/test/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile
index 2f16ad328..13983f4ff 100644
--- a/src/test/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile
+++ b/src/test/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile
@@ -6,7 +6,7 @@
# The test links a rust static library into a shared library, and checks that
# the linker doesn't have to flag the resulting file as containing TEXTRELs.
--include ../tools.mk
+include ../tools.mk
# only-linux
diff --git a/src/test/run-make-fulldeps/issue-69368/Makefile b/src/test/run-make-fulldeps/issue-69368/Makefile
index dbb044d8f..41770475d 100644
--- a/src/test/run-make-fulldeps/issue-69368/Makefile
+++ b/src/test/run-make-fulldeps/issue-69368/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that previously triggered a linker failure with root cause
# similar to one found in the issue #69368.
diff --git a/src/test/run-make-fulldeps/issue-69368/a.rs b/src/test/run-make-fulldeps/issue-69368/a.rs
index 7d339c5a5..a54f42955 100644
--- a/src/test/run-make-fulldeps/issue-69368/a.rs
+++ b/src/test/run-make-fulldeps/issue-69368/a.rs
@@ -19,3 +19,8 @@ extern "C" fn __rust_drop_panic() -> ! {
extern "C" fn __rust_foreign_exception() -> ! {
loop {}
}
+
+#[lang = "eh_personality"]
+fn eh_personality() {
+ loop {}
+}
diff --git a/src/test/run-make-fulldeps/issue-7349/Makefile b/src/test/run-make-fulldeps/issue-7349/Makefile
index 9658b99e3..dc073b77f 100644
--- a/src/test/run-make-fulldeps/issue-7349/Makefile
+++ b/src/test/run-make-fulldeps/issue-7349/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test to make sure that inner functions within a polymorphic outer function
# don't get re-codegened when the outer function is monomorphized. The test
diff --git a/src/test/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile b/src/test/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile
index 157edb20c..879ce1743 100644
--- a/src/test/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile
+++ b/src/test/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile
@@ -3,7 +3,7 @@
# This test makes sure the embed bitcode in elf created with
# lto-embed-bitcode=optimized is valid llvm BC module.
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) test.rs --target $(TARGET) -Clink-arg=-fuse-ld=lld -Clinker-plugin-lto -Clinker=$(CLANG) -Clink-arg=-Wl,--plugin-opt=-lto-embed-bitcode=optimized -Zemit-thin-lto=no
diff --git a/src/test/run-make-fulldeps/issue-97463-abi-param-passing/Makefile b/src/test/run-make-fulldeps/issue-97463-abi-param-passing/Makefile
new file mode 100644
index 000000000..db1b53e15
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-97463-abi-param-passing/Makefile
@@ -0,0 +1,14 @@
+-include ../tools.mk
+
+# ignore-msvc
+
+# The issue exercised by this test, rust-lang/rust#97463, explicitly needs `-O`
+# flags (like `-O3`) to reproduce. Thus, we call $(CC) instead of nicer
+# alternatives provided by tools.mk like using `COMPILE_OBJ` or using a
+# `NATIVE_STATICLIB` dependency.
+
+all:
+ $(CC) -c -O3 -o $(TMPDIR)/bad.o bad.c
+ $(AR) rcs $(TMPDIR)/libbad.a $(TMPDIR)/bad.o
+ $(RUSTC) param_passing.rs -L$(TMPDIR) -lbad -C opt-level=3
+ $(call RUN,param_passing)
diff --git a/src/test/run-make-fulldeps/issue-97463-abi-param-passing/bad.c b/src/test/run-make-fulldeps/issue-97463-abi-param-passing/bad.c
new file mode 100644
index 000000000..013314ab2
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-97463-abi-param-passing/bad.c
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+
+struct bloc {
+ uint16_t a;
+ uint16_t b;
+ uint16_t c;
+};
+
+uint16_t c_read_value(uint32_t a, uint32_t b, uint32_t c) {
+ struct bloc *data = malloc(sizeof(struct bloc));
+
+ data->a = a & 0xFFFF;
+ data->b = b & 0xFFFF;
+ data->c = c & 0xFFFF;
+
+ printf("C struct: a = %u, b = %u, c = %u\n",
+ (unsigned) data->a, (unsigned) data->b, (unsigned) data->c);
+ printf("C function returns %u\n", (unsigned) data->b);
+
+ return data->b; /* leak data */
+}
diff --git a/src/test/run-make-fulldeps/issue-97463-abi-param-passing/param_passing.rs b/src/test/run-make-fulldeps/issue-97463-abi-param-passing/param_passing.rs
new file mode 100644
index 000000000..c11f3cc72
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-97463-abi-param-passing/param_passing.rs
@@ -0,0 +1,38 @@
+// NOTE: Exposing the bug encoded in this test is sensitive to
+// LLVM optimization choices. See additional note below for an
+// example.
+
+#[link(name = "bad")]
+extern "C" {
+ pub fn c_read_value(a: u32, b: u32, c: u32) -> u16;
+}
+
+fn main() {
+ const C1: usize = 0x327b23c6;
+ const C2: usize = C1 & 0xFFFF;
+
+ let r1: usize = 0x0;
+ let r2: usize = C1;
+ let r3: usize = 0x0;
+ let value: u16 = unsafe { c_read_value(r1 as u32, r2 as u32, r3 as u32) };
+
+ // NOTE: as an example of the sensitivity of this test to optimization choices,
+ // uncommenting this block of code makes the bug go away on pnkfelix's machine.
+ // (But observing via `dbg!` doesn't hide the bug. At least sometimes.)
+ /*
+ println!("{}", value);
+ println!("{}", value as usize);
+ println!("{}", usize::from(value));
+ println!("{}", (value as usize) & 0xFFFF);
+ */
+
+ let d1 = value;
+ let d2 = value as usize;
+ let d3 = usize::from(value);
+ let d4 = (value as usize) & 0xFFFF;
+
+ let d = (&d1, &d2, &d3, &d4);
+ let d_ = (d1, d2, d3, d4);
+
+ assert_eq!(((&(C2 as u16), &C2, &C2, &C2), (C2 as u16, C2, C2, C2)), (d, d_));
+}
diff --git a/src/test/run-make-fulldeps/issue64319/Makefile b/src/test/run-make-fulldeps/issue64319/Makefile
index 5592f5a71..ee0d177ab 100644
--- a/src/test/run-make-fulldeps/issue64319/Makefile
+++ b/src/test/run-make-fulldeps/issue64319/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# Different optimization levels imply different values for `-Zshare-generics`,
# so try out a whole bunch of combinations to make sure everything is compatible
diff --git a/src/test/run-make-fulldeps/issues-41478-43796/Makefile b/src/test/run-make-fulldeps/issues-41478-43796/Makefile
index f9735253a..e451cb031 100644
--- a/src/test/run-make-fulldeps/issues-41478-43796/Makefile
+++ b/src/test/run-make-fulldeps/issues-41478-43796/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
# Work in /tmp, because we need to create the `save-analysis-temp` folder.
diff --git a/src/test/run-make-fulldeps/libs-through-symlinks/Makefile b/src/test/run-make-fulldeps/libs-through-symlinks/Makefile
index 8be2e234f..45deaecb8 100644
--- a/src/test/run-make-fulldeps/libs-through-symlinks/Makefile
+++ b/src/test/run-make-fulldeps/libs-through-symlinks/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
diff --git a/src/test/run-make-fulldeps/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile
index 67b5fc2ed..37b6cb9e2 100644
--- a/src/test/run-make-fulldeps/libtest-json/Makefile
+++ b/src/test/run-make-fulldeps/libtest-json/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test expected libtest's JSON output
diff --git a/src/test/run-make-fulldeps/link-arg/Makefile b/src/test/run-make-fulldeps/link-arg/Makefile
index 0360ede76..103527c3e 100644
--- a/src/test/run-make-fulldeps/link-arg/Makefile
+++ b/src/test/run-make-fulldeps/link-arg/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
RUSTC_FLAGS = -C link-arg="-lfoo" -C link-arg="-lbar" --print link-args
all:
diff --git a/src/test/run-make-fulldeps/link-args-order/Makefile b/src/test/run-make-fulldeps/link-args-order/Makefile
index f94e882cc..c562cc1b3 100644
--- a/src/test/run-make-fulldeps/link-args-order/Makefile
+++ b/src/test/run-make-fulldeps/link-args-order/Makefile
@@ -1,6 +1,6 @@
# ignore-msvc
--include ../tools.mk
+include ../tools.mk
RUSTC_FLAGS = -C linker-flavor=ld -C link-arg=a -C link-args="b c" -C link-args="d e" -C link-arg=f
RUSTC_FLAGS_PRE = -C linker-flavor=ld -Z pre-link-arg=a -Z pre-link-args="b c" -Z pre-link-args="d e" -Z pre-link-arg=f
diff --git a/src/test/run-make-fulldeps/link-cfg/Makefile b/src/test/run-make-fulldeps/link-cfg/Makefile
index 2701b4a59..0b25ccded 100644
--- a/src/test/run-make-fulldeps/link-cfg/Makefile
+++ b/src/test/run-make-fulldeps/link-cfg/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call DYLIB,return1) $(call DYLIB,return2) $(call NATIVE_STATICLIB,return3)
ls $(TMPDIR)
diff --git a/src/test/run-make-fulldeps/link-dedup/Makefile b/src/test/run-make-fulldeps/link-dedup/Makefile
index 4e7ce0f02..5c9603352 100644
--- a/src/test/run-make-fulldeps/link-dedup/Makefile
+++ b/src/test/run-make-fulldeps/link-dedup/Makefile
@@ -1,6 +1,6 @@
# ignore-msvc
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) depa.rs
diff --git a/src/test/run-make-fulldeps/link-path-order/Makefile b/src/test/run-make-fulldeps/link-path-order/Makefile
index eeea0e371..ed7c299e6 100644
--- a/src/test/run-make-fulldeps/link-path-order/Makefile
+++ b/src/test/run-make-fulldeps/link-path-order/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Verifies that the -L arguments given to the linker is in the same order
# as the -L arguments on the rustc command line.
diff --git a/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile b/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile
index 4befbe144..7cc54e40a 100644
--- a/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile
+++ b/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,foo)
$(RUSTC) bar.rs
diff --git a/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile
index debe9e938..a38f4fe5d 100644
--- a/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile
+++ b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs -g
diff --git a/src/test/run-make-fulldeps/long-linker-command-lines/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines/Makefile
index 5876fbc94..00199ca97 100644
--- a/src/test/run-make-fulldeps/long-linker-command-lines/Makefile
+++ b/src/test/run-make-fulldeps/long-linker-command-lines/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs -g -O
diff --git a/src/test/run-make-fulldeps/longjmp-across-rust/Makefile b/src/test/run-make-fulldeps/longjmp-across-rust/Makefile
index 9d71ed8fc..848638d82 100644
--- a/src/test/run-make-fulldeps/longjmp-across-rust/Makefile
+++ b/src/test/run-make-fulldeps/longjmp-across-rust/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,foo)
$(RUSTC) main.rs
diff --git a/src/test/run-make-fulldeps/ls-metadata/Makefile b/src/test/run-make-fulldeps/ls-metadata/Makefile
index fc3f5bce0..e0f916a24 100644
--- a/src/test/run-make-fulldeps/ls-metadata/Makefile
+++ b/src/test/run-make-fulldeps/ls-metadata/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs
diff --git a/src/test/run-make-fulldeps/lto-dylib-dep/Makefile b/src/test/run-make-fulldeps/lto-dylib-dep/Makefile
index ab8ee6c2e..41487b23c 100644
--- a/src/test/run-make-fulldeps/lto-dylib-dep/Makefile
+++ b/src/test/run-make-fulldeps/lto-dylib-dep/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that we don't run into an assertion when using a Rust dylib dependency
# while compiling with full LTO.
diff --git a/src/test/run-make-fulldeps/lto-empty/Makefile b/src/test/run-make-fulldeps/lto-empty/Makefile
index 345d10bc4..b4345ba18 100644
--- a/src/test/run-make-fulldeps/lto-empty/Makefile
+++ b/src/test/run-make-fulldeps/lto-empty/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: cdylib-fat cdylib-thin
diff --git a/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile
index 25afad92a..e576ee37c 100644
--- a/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile
+++ b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar)
$(RUSTC) lib1.rs
diff --git a/src/test/run-make-fulldeps/lto-readonly-lib/Makefile b/src/test/run-make-fulldeps/lto-readonly-lib/Makefile
index 0afbbc345..a20ecea88 100644
--- a/src/test/run-make-fulldeps/lto-readonly-lib/Makefile
+++ b/src/test/run-make-fulldeps/lto-readonly-lib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) lib.rs
diff --git a/src/test/run-make-fulldeps/lto-smoke-c/Makefile b/src/test/run-make-fulldeps/lto-smoke-c/Makefile
index 0f61f5de9..7c6ee3be8 100644
--- a/src/test/run-make-fulldeps/lto-smoke-c/Makefile
+++ b/src/test/run-make-fulldeps/lto-smoke-c/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Apparently older versions of GCC segfault if -g is passed...
CC := $(CC:-g=)
diff --git a/src/test/run-make-fulldeps/lto-smoke/Makefile b/src/test/run-make-fulldeps/lto-smoke/Makefile
index 9b1dc2550..8bce708b4 100644
--- a/src/test/run-make-fulldeps/lto-smoke/Makefile
+++ b/src/test/run-make-fulldeps/lto-smoke/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: noparam bool_true bool_false thin fat
diff --git a/src/test/run-make-fulldeps/manual-crate-name/Makefile b/src/test/run-make-fulldeps/manual-crate-name/Makefile
index 1d1419997..c00e20c7c 100644
--- a/src/test/run-make-fulldeps/manual-crate-name/Makefile
+++ b/src/test/run-make-fulldeps/manual-crate-name/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --crate-name foo bar.rs
diff --git a/src/test/run-make-fulldeps/manual-link/Makefile b/src/test/run-make-fulldeps/manual-link/Makefile
index dccf0d99b..401f6eb44 100644
--- a/src/test/run-make-fulldeps/manual-link/Makefile
+++ b/src/test/run-make-fulldeps/manual-link/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(TMPDIR)/libbar.a
$(RUSTC) foo.rs -lstatic=bar
diff --git a/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
index e7268311b..ca0ab8e9e 100644
--- a/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
+++ b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Modelled after ui/changing-crates.rs test, but this one puts
# more than one (mismatching) candidate crate into the search path,
diff --git a/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile
index 3ffbba944..dc6b10f4e 100644
--- a/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile
+++ b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs -C metadata=a -C extra-filename=-a
diff --git a/src/test/run-make-fulldeps/min-global-align/Makefile b/src/test/run-make-fulldeps/min-global-align/Makefile
index 621027470..82f38749e 100644
--- a/src/test/run-make-fulldeps/min-global-align/Makefile
+++ b/src/test/run-make-fulldeps/min-global-align/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-linux
diff --git a/src/test/run-make-fulldeps/mismatching-target-triples/Makefile b/src/test/run-make-fulldeps/mismatching-target-triples/Makefile
index 1636e41b0..409388e04 100644
--- a/src/test/run-make-fulldeps/mismatching-target-triples/Makefile
+++ b/src/test/run-make-fulldeps/mismatching-target-triples/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Issue #10814
#
diff --git a/src/test/run-make-fulldeps/missing-crate-dependency/Makefile b/src/test/run-make-fulldeps/missing-crate-dependency/Makefile
index b5a5bf492..7c271ab8a 100644
--- a/src/test/run-make-fulldeps/missing-crate-dependency/Makefile
+++ b/src/test/run-make-fulldeps/missing-crate-dependency/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --crate-type=rlib crateA.rs
diff --git a/src/test/run-make-fulldeps/mixing-deps/Makefile b/src/test/run-make-fulldeps/mixing-deps/Makefile
index 0e52d4a8b..956e704ee 100644
--- a/src/test/run-make-fulldeps/mixing-deps/Makefile
+++ b/src/test/run-make-fulldeps/mixing-deps/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) both.rs -C prefer-dynamic
diff --git a/src/test/run-make-fulldeps/mixing-formats/Makefile b/src/test/run-make-fulldeps/mixing-formats/Makefile
index 48257669b..b27e54257 100644
--- a/src/test/run-make-fulldeps/mixing-formats/Makefile
+++ b/src/test/run-make-fulldeps/mixing-formats/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Testing various mixings of rlibs and dylibs. Makes sure that it's possible to
# link an rlib to a dylib. The dependency tree among the file looks like:
diff --git a/src/test/run-make-fulldeps/mixing-libs/Makefile b/src/test/run-make-fulldeps/mixing-libs/Makefile
index babeeef16..39cc0708c 100644
--- a/src/test/run-make-fulldeps/mixing-libs/Makefile
+++ b/src/test/run-make-fulldeps/mixing-libs/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) rlib.rs
diff --git a/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile b/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile
index 1095a047d..a5f019f24 100644
--- a/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile
+++ b/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs -Copt-level=z 2>&1
diff --git a/src/test/run-make-fulldeps/multiple-emits/Makefile b/src/test/run-make-fulldeps/multiple-emits/Makefile
index e12642283..d1f297644 100644
--- a/src/test/run-make-fulldeps/multiple-emits/Makefile
+++ b/src/test/run-make-fulldeps/multiple-emits/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out 2>&1
diff --git a/src/test/run-make-fulldeps/no-builtins-lto/Makefile b/src/test/run-make-fulldeps/no-builtins-lto/Makefile
index 2e41be39d..c8f05d991 100644
--- a/src/test/run-make-fulldeps/no-builtins-lto/Makefile
+++ b/src/test/run-make-fulldeps/no-builtins-lto/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
# Compile a `#![no_builtins]` rlib crate
diff --git a/src/test/run-make-fulldeps/no-duplicate-libs/Makefile b/src/test/run-make-fulldeps/no-duplicate-libs/Makefile
index 13d8366c6..b05aff782 100644
--- a/src/test/run-make-fulldeps/no-duplicate-libs/Makefile
+++ b/src/test/run-make-fulldeps/no-duplicate-libs/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
ifdef IS_MSVC
# FIXME(#27979)
diff --git a/src/test/run-make-fulldeps/no-intermediate-extras/Makefile b/src/test/run-make-fulldeps/no-intermediate-extras/Makefile
index 258cbf04c..4116aac1b 100644
--- a/src/test/run-make-fulldeps/no-intermediate-extras/Makefile
+++ b/src/test/run-make-fulldeps/no-intermediate-extras/Makefile
@@ -1,6 +1,6 @@
# Regression test for issue #10973
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --crate-type=rlib --test foo.rs
diff --git a/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile b/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile
index 903349152..effcfc94c 100644
--- a/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile
+++ b/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# check that rustc builds all crate_type attributes
# delete rlib
diff --git a/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile
index 74e5dcfcf..45221356c 100644
--- a/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile
+++ b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
cp foo.rs $(TMPDIR)/foo.rs
diff --git a/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile b/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile
index 6377038b7..33069c06f 100644
--- a/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile
+++ b/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
cp foo.rs $(TMPDIR)/foo
diff --git a/src/test/run-make-fulldeps/output-type-permutations/Makefile b/src/test/run-make-fulldeps/output-type-permutations/Makefile
index b6e0cbaf5..791606c64 100644
--- a/src/test/run-make-fulldeps/output-type-permutations/Makefile
+++ b/src/test/run-make-fulldeps/output-type-permutations/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs --crate-type=rlib,dylib,staticlib
diff --git a/src/test/run-make-fulldeps/output-with-hyphens/Makefile b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
index 69a286f0b..365fb6e59 100644
--- a/src/test/run-make-fulldeps/output-with-hyphens/Makefile
+++ b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo-bar.rs --crate-type bin
diff --git a/src/test/run-make-fulldeps/override-aliased-flags/Makefile b/src/test/run-make-fulldeps/override-aliased-flags/Makefile
index bea610eeb..186b8c7c8 100644
--- a/src/test/run-make-fulldeps/override-aliased-flags/Makefile
+++ b/src/test/run-make-fulldeps/override-aliased-flags/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# FIXME: it would be good to check that it's actually the rightmost flags
# that are used when multiple flags are specified, but I can't think of a
diff --git a/src/test/run-make-fulldeps/panic-impl-transitive/Makefile b/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
index 1714578b2..c3192efcb 100644
--- a/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# NOTE we use --emit=llvm-ir to avoid running the linker (linking will fail because there's no main
# in this crate)
diff --git a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile
index f3d935786..42d3c977f 100644
--- a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile
+++ b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) nonclike.rs -L$(TMPDIR) -ltest
diff --git a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
index 9773e3f1f..c60206a1f 100644
--- a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
+++ b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
@@ -4,7 +4,7 @@
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
--include ../tools.mk
+include ../tools.mk
# For some very small programs GNU ld seems to not properly handle
# instrumentation sections correctly. Neither Gold nor LLD have that problem.
diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
index a7d5c5616..3f2f6a838 100644
--- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
@@ -4,7 +4,7 @@
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
--include ../tools.mk
+include ../tools.mk
COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)"
diff --git a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
index 425bfc28a..7f72b11b6 100644
--- a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
@@ -1,6 +1,6 @@
# needs-profiler-support
--include ../tools.mk
+include ../tools.mk
COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)"
diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile
index 6533355be..4623a7495 100644
--- a/src/test/run-make-fulldeps/pgo-gen/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen/Makefile
@@ -4,7 +4,7 @@
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
--include ../tools.mk
+include ../tools.mk
COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)"
diff --git a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
index c0195dcbb..45302215c 100644
--- a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
+++ b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
@@ -4,7 +4,7 @@
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
--include ../tools.mk
+include ../tools.mk
all:
# We don't compile `opaque` with either optimizations or instrumentation.
diff --git a/src/test/run-make-fulldeps/pgo-use/Makefile b/src/test/run-make-fulldeps/pgo-use/Makefile
index d7863c9c5..3bac9b77a 100644
--- a/src/test/run-make-fulldeps/pgo-use/Makefile
+++ b/src/test/run-make-fulldeps/pgo-use/Makefile
@@ -4,7 +4,7 @@
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
--include ../tools.mk
+include ../tools.mk
# This test makes sure that PGO profiling data leads to cold functions being
# marked as `cold` and hot functions with `inlinehint`.
diff --git a/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile b/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile
index d0e22cfef..7acea0380 100644
--- a/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile
+++ b/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-aarch64
diff --git a/src/test/run-make-fulldeps/prefer-dylib/Makefile b/src/test/run-make-fulldeps/prefer-dylib/Makefile
index bd44feecf..3817ca195 100644
--- a/src/test/run-make-fulldeps/prefer-dylib/Makefile
+++ b/src/test/run-make-fulldeps/prefer-dylib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=dylib --crate-type=rlib -C prefer-dynamic
diff --git a/src/test/run-make-fulldeps/prefer-rlib/Makefile b/src/test/run-make-fulldeps/prefer-rlib/Makefile
index c6a239eef..adc345d76 100644
--- a/src/test/run-make-fulldeps/prefer-rlib/Makefile
+++ b/src/test/run-make-fulldeps/prefer-rlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=dylib --crate-type=rlib
diff --git a/src/test/run-make-fulldeps/pretty-expanded/Makefile b/src/test/run-make-fulldeps/pretty-expanded/Makefile
index e721c5afd..5a0097a83 100644
--- a/src/test/run-make-fulldeps/pretty-expanded/Makefile
+++ b/src/test/run-make-fulldeps/pretty-expanded/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -o $(TMPDIR)/input.expanded.rs -Zunpretty=expanded input.rs
diff --git a/src/test/run-make-fulldeps/pretty-print-to-file/Makefile b/src/test/run-make-fulldeps/pretty-print-to-file/Makefile
index b224c52fc..ca11b8c47 100644
--- a/src/test/run-make-fulldeps/pretty-print-to-file/Makefile
+++ b/src/test/run-make-fulldeps/pretty-print-to-file/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -o $(TMPDIR)/input.out -Zunpretty=normal input.rs
diff --git a/src/test/run-make-fulldeps/print-cfg/Makefile b/src/test/run-make-fulldeps/print-cfg/Makefile
index 5472baae3..126f5768c 100644
--- a/src/test/run-make-fulldeps/print-cfg/Makefile
+++ b/src/test/run-make-fulldeps/print-cfg/Makefile
@@ -1,6 +1,6 @@
# needs-llvm-components: x86 arm
--include ../tools.mk
+include ../tools.mk
all: default
$(RUSTC) --target x86_64-pc-windows-gnu --print cfg | $(CGREP) windows
diff --git a/src/test/run-make-fulldeps/print-target-list/Makefile b/src/test/run-make-fulldeps/print-target-list/Makefile
index 5f10f2aa3..f23c40d42 100644
--- a/src/test/run-make-fulldeps/print-target-list/Makefile
+++ b/src/test/run-make-fulldeps/print-target-list/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Checks that all the targets returned by `rustc --print target-list` are valid
# target specifications
diff --git a/src/test/run-make-fulldeps/profile/Makefile b/src/test/run-make-fulldeps/profile/Makefile
index 04d382b47..fffc051ad 100644
--- a/src/test/run-make-fulldeps/profile/Makefile
+++ b/src/test/run-make-fulldeps/profile/Makefile
@@ -1,6 +1,6 @@
# needs-profiler-support
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -g -Z profile test.rs
diff --git a/src/test/run-make-fulldeps/prune-link-args/Makefile b/src/test/run-make-fulldeps/prune-link-args/Makefile
index 3589f98e7..a359dc5ae 100644
--- a/src/test/run-make-fulldeps/prune-link-args/Makefile
+++ b/src/test/run-make-fulldeps/prune-link-args/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
diff --git a/src/test/run-make-fulldeps/redundant-libs/Makefile b/src/test/run-make-fulldeps/redundant-libs/Makefile
index e09841fb4..b2dff05d1 100644
--- a/src/test/run-make-fulldeps/redundant-libs/Makefile
+++ b/src/test/run-make-fulldeps/redundant-libs/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows-msvc
diff --git a/src/test/run-make-fulldeps/relocation-model/Makefile b/src/test/run-make-fulldeps/relocation-model/Makefile
index 485ecbb4b..a31dbfd91 100644
--- a/src/test/run-make-fulldeps/relocation-model/Makefile
+++ b/src/test/run-make-fulldeps/relocation-model/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: others
$(RUSTC) -C relocation-model=dynamic-no-pic foo.rs
diff --git a/src/test/run-make-fulldeps/relro-levels/Makefile b/src/test/run-make-fulldeps/relro-levels/Makefile
index aacb5acb7..6176fc1a5 100644
--- a/src/test/run-make-fulldeps/relro-levels/Makefile
+++ b/src/test/run-make-fulldeps/relro-levels/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-linux
#
diff --git a/src/test/run-make-fulldeps/remap-path-prefix/Makefile b/src/test/run-make-fulldeps/remap-path-prefix/Makefile
index 86785c595..2a7378fdf 100644
--- a/src/test/run-make-fulldeps/remap-path-prefix/Makefile
+++ b/src/test/run-make-fulldeps/remap-path-prefix/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
diff --git a/src/test/run-make-fulldeps/reproducible-build-2/Makefile b/src/test/run-make-fulldeps/reproducible-build-2/Makefile
index fd94516fb..1df5e102c 100644
--- a/src/test/run-make-fulldeps/reproducible-build-2/Makefile
+++ b/src/test/run-make-fulldeps/reproducible-build-2/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-musl
# ignore-windows
diff --git a/src/test/run-make-fulldeps/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile
index adccc1535..642a48081 100644
--- a/src/test/run-make-fulldeps/reproducible-build/Makefile
+++ b/src/test/run-make-fulldeps/reproducible-build/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-musl
# Objects are reproducible but their path is not.
diff --git a/src/test/run-make-fulldeps/resolve-rename/Makefile b/src/test/run-make-fulldeps/resolve-rename/Makefile
index 4b0c36d01..00f83a5d6 100644
--- a/src/test/run-make-fulldeps/resolve-rename/Makefile
+++ b/src/test/run-make-fulldeps/resolve-rename/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -C extra-filename=-hash foo.rs
diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile
index f3d935786..42d3c977f 100644
--- a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile
+++ b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,test)
$(RUSTC) nonclike.rs -L$(TMPDIR) -ltest
diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile b/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile
index 5b5d620ef..513311c82 100644
--- a/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile
+++ b/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) --crate-type=staticlib nonclike.rs
diff --git a/src/test/run-make-fulldeps/rlib-chain/Makefile b/src/test/run-make-fulldeps/rlib-chain/Makefile
index 30b6811a3..236943a2a 100644
--- a/src/test/run-make-fulldeps/rlib-chain/Makefile
+++ b/src/test/run-make-fulldeps/rlib-chain/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) m1.rs
diff --git a/src/test/run-make-fulldeps/rustdoc-determinism/Makefile b/src/test/run-make-fulldeps/rustdoc-determinism/Makefile
index 0534c2c38..a3ef16906 100644
--- a/src/test/run-make-fulldeps/rustdoc-determinism/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-determinism/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Assert that the search index is generated deterministically, regardless of the
# order that crates are documented in.
diff --git a/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
index c9d41f0ec..2dc30f56b 100644
--- a/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that hir-tree output doesn't crash and includes
# the string constant we would expect to see.
diff --git a/src/test/run-make-fulldeps/rustdoc-io-error/Makefile b/src/test/run-make-fulldeps/rustdoc-io-error/Makefile
index f95fa88d4..27f5ecf94 100644
--- a/src/test/run-make-fulldeps/rustdoc-io-error/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-io-error/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# This test verifies that rustdoc doesn't ICE when it encounters an IO error
# while generating files. Ideally this would be a rustdoc-ui test, so we could
diff --git a/src/test/run-make-fulldeps/rustdoc-map-file/Makefile b/src/test/run-make-fulldeps/rustdoc-map-file/Makefile
index ce977fa0c..5cbf7747a 100644
--- a/src/test/run-make-fulldeps/rustdoc-map-file/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-map-file/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTDOC) -Z unstable-options --generate-redirect-map foo.rs -o "$(TMPDIR)/out"
diff --git a/src/test/run-make-fulldeps/rustdoc-output-path/Makefile b/src/test/run-make-fulldeps/rustdoc-output-path/Makefile
index 8ce1c6995..8f5cda9e5 100644
--- a/src/test/run-make-fulldeps/rustdoc-output-path/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-output-path/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTDOC) -o "$(TMPDIR)/foo/bar/doc" foo.rs
diff --git a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile
index 4934e875d..c857aa4b9 100644
--- a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foobar_macro --crate-type dylib --print file-names -)
diff --git a/src/test/run-make-fulldeps/rustdoc-themes/Makefile b/src/test/run-make-fulldeps/rustdoc-themes/Makefile
index f3d07b25c..a6d9a43ad 100644
--- a/src/test/run-make-fulldeps/rustdoc-themes/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-themes/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that rustdoc will properly load in a theme file and display it in the theme selector.
diff --git a/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
index e72fe5a50..691585268 100644
--- a/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
@@ -1,7 +1,7 @@
# needs-sanitizer-support
# needs-sanitizer-address
--include ../tools.mk
+include ../tools.mk
LOG := $(TMPDIR)/log.txt
diff --git a/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
index b9a3f8295..b0a91e5b1 100644
--- a/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
@@ -1,7 +1,7 @@
# needs-sanitizer-support
# needs-sanitizer-address
--include ../tools.mk
+include ../tools.mk
LOG := $(TMPDIR)/log.txt
diff --git a/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
index 4894f65b1..7b1a286ed 100644
--- a/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
@@ -1,7 +1,7 @@
# needs-sanitizer-support
# needs-sanitizer-address
--include ../tools.mk
+include ../tools.mk
# This test first builds a staticlib with AddressSanitizer and checks that
# linking it to an executable fails due to the missing sanitizer runtime.
diff --git a/src/test/run-make-fulldeps/save-analysis-fail/Makefile b/src/test/run-make-fulldeps/save-analysis-fail/Makefile
index f29f907cf..69a2b2746 100644
--- a/src/test/run-make-fulldeps/save-analysis-fail/Makefile
+++ b/src/test/run-make-fulldeps/save-analysis-fail/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: code
krate2: krate2.rs
$(RUSTC) $<
diff --git a/src/test/run-make-fulldeps/save-analysis-fail/foo.rs b/src/test/run-make-fulldeps/save-analysis-fail/foo.rs
index 94879c2a6..c5a70605e 100644
--- a/src/test/run-make-fulldeps/save-analysis-fail/foo.rs
+++ b/src/test/run-make-fulldeps/save-analysis-fail/foo.rs
@@ -1,5 +1,4 @@
#![crate_name = "test"]
-#![feature(box_syntax)]
#![feature(rustc_private)]
extern crate rustc_graphviz;
@@ -261,9 +260,9 @@ fn hello<X: SomeTrait>((z, a): (u32, String), ex: X) {
let x = 32.0f32;
let _ = (x + ((x * x) + 1.0).sqrt()).ln();
- let s: Box<SomeTrait> = box some_fields { field1: 43 };
- let s2: Box<some_fields> = box some_fields { field1: 43 };
- let s3 = box nofields;
+ let s: Box<SomeTrait> = Box::new(some_fields { field1: 43 });
+ let s2: Box<some_fields> = Box::new(some_fields { field1: 43 });
+ let s3 = Box::new(nofields);
s.Method(43);
s3.Method(43);
@@ -317,7 +316,7 @@ mod macro_use_test {
fn main() {
// foo
- let s = box some_fields { field1: 43 };
+ let s = Box::new(some_fields { field1: 43 });
hello((43, "a".to_string()), *s);
sub::sub2::hello();
sub2::sub3::hello();
@@ -345,17 +344,17 @@ fn main() {
let s4: msalias::nested_struct = sub::sub2::nested_struct { field2: 55 };
let s4: msalias::nested_struct = sub2::nested_struct { field2: 55 };
println(&s2.field1.to_string());
- let s5: MyType = box some_fields { field1: 55 };
+ let s5: MyType = Box::new(some_fields { field1: 55 });
let s = SameDir::SameStruct { name: "Bob".to_string() };
let s = SubDir::SubStruct { name: "Bob".to_string() };
- let s6: SomeEnum = SomeEnum::MyTypes(box s2.clone(), s5);
+ let s6: SomeEnum = SomeEnum::MyTypes(Box::new(s2.clone()), s5);
let s7: SomeEnum = SomeEnum::Strings("one", "two", "three");
matchSomeEnum(s6);
matchSomeEnum(s7);
let s8: SomeOtherEnum = SomeOtherEnum::SomeConst2;
matchSomeOtherEnum(s8);
let s9: SomeStructEnum =
- SomeStructEnum::EnumStruct2 { f1: box some_fields { field1: 10 }, f2: box s2 };
+ SomeStructEnum::EnumStruct2 { f1: Box::new(some_fields { field1: 10 }), f2: Box::new(s2) };
matchSomeStructEnum(s9);
for x in &vec![1, 2, 3] {
diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
index 36288c4b8..30f57034b 100644
--- a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
+++ b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: extern_absolute_paths.rs krate2
$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 --extern krate2
diff --git a/src/test/run-make-fulldeps/save-analysis/Makefile b/src/test/run-make-fulldeps/save-analysis/Makefile
index 7296fb9cc..b8b6be13d 100644
--- a/src/test/run-make-fulldeps/save-analysis/Makefile
+++ b/src/test/run-make-fulldeps/save-analysis/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: code
krate2: krate2.rs
$(RUSTC) $<
diff --git a/src/test/run-make-fulldeps/save-analysis/foo.rs b/src/test/run-make-fulldeps/save-analysis/foo.rs
index dd7067503..74aaabfbf 100644
--- a/src/test/run-make-fulldeps/save-analysis/foo.rs
+++ b/src/test/run-make-fulldeps/save-analysis/foo.rs
@@ -1,5 +1,4 @@
#![crate_name = "test"]
-#![feature(box_syntax)]
#![feature(rustc_private)]
#![feature(associated_type_defaults)]
@@ -255,9 +254,9 @@ fn hello<X: SomeTrait>((z, a): (u32, String), ex: X) {
let x = 32.0f32;
let _ = (x + ((x * x) + 1.0).sqrt()).ln();
- let s: Box<SomeTrait> = box some_fields { field1: 43 };
- let s2: Box<some_fields> = box some_fields { field1: 43 };
- let s3 = box nofields;
+ let s: Box<SomeTrait> = Box::new(some_fields { field1: 43 });
+ let s2: Box<some_fields> = Box::new(some_fields { field1: 43 });
+ let s3 = Box::new(nofields);
s.Method(43);
s3.Method(43);
@@ -311,7 +310,7 @@ mod macro_use_test {
fn main() {
// foo
- let s = box some_fields { field1: 43 };
+ let s = Box::new(some_fields { field1: 43 });
hello((43, "a".to_string()), *s);
sub::sub2::hello();
sub2::sub3::hello();
@@ -339,17 +338,17 @@ fn main() {
let s4: msalias::nested_struct = sub::sub2::nested_struct { field2: 55 };
let s4: msalias::nested_struct = sub2::nested_struct { field2: 55 };
println(&s2.field1.to_string());
- let s5: MyType = box some_fields { field1: 55 };
+ let s5: MyType = Box::new(some_fields { field1: 55 });
let s = SameDir::SameStruct { name: "Bob".to_string() };
let s = SubDir::SubStruct { name: "Bob".to_string() };
- let s6: SomeEnum = SomeEnum::MyTypes(box s2.clone(), s5);
+ let s6: SomeEnum = SomeEnum::MyTypes(Box::new(s2.clone()), s5);
let s7: SomeEnum = SomeEnum::Strings("one", "two", "three");
matchSomeEnum(s6);
matchSomeEnum(s7);
let s8: SomeOtherEnum = SomeOtherEnum::SomeConst2;
matchSomeOtherEnum(s8);
let s9: SomeStructEnum =
- SomeStructEnum::EnumStruct2 { f1: box some_fields { field1: 10 }, f2: box s2 };
+ SomeStructEnum::EnumStruct2 { f1: Box::new(some_fields { field1: 10 }), f2: Box::new(s2) };
matchSomeStructEnum(s9);
for x in &vec![1, 2, 3] {
diff --git a/src/test/run-make-fulldeps/separate-link-fail/Makefile b/src/test/run-make-fulldeps/separate-link-fail/Makefile
index c759f42a2..bfd18fbf9 100644
--- a/src/test/run-make-fulldeps/separate-link-fail/Makefile
+++ b/src/test/run-make-fulldeps/separate-link-fail/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
echo 'fn main(){}' > $(TMPDIR)/main.rs
diff --git a/src/test/run-make-fulldeps/separate-link/Makefile b/src/test/run-make-fulldeps/separate-link/Makefile
index 060484e89..3ccdb6275 100644
--- a/src/test/run-make-fulldeps/separate-link/Makefile
+++ b/src/test/run-make-fulldeps/separate-link/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
echo 'fn main(){}' | $(RUSTC) -Z no-link -
diff --git a/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile b/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile
index 77d1d71e9..df289d0b0 100644
--- a/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile
+++ b/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Check that cross-crate inlined items are inlined in all compilation units
# that refer to them, and not in any other compilation units.
diff --git a/src/test/run-make-fulldeps/sepcomp-inlining/Makefile b/src/test/run-make-fulldeps/sepcomp-inlining/Makefile
index 1d20d9400..327aeb75e 100644
--- a/src/test/run-make-fulldeps/sepcomp-inlining/Makefile
+++ b/src/test/run-make-fulldeps/sepcomp-inlining/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that #[inline] functions still get inlined across compilation unit
# boundaries. Compilation should produce three IR files, but only the two
diff --git a/src/test/run-make-fulldeps/sepcomp-separate/Makefile b/src/test/run-make-fulldeps/sepcomp-separate/Makefile
index 5b8bdb0fa..62cf54a88 100644
--- a/src/test/run-make-fulldeps/sepcomp-separate/Makefile
+++ b/src/test/run-make-fulldeps/sepcomp-separate/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Test that separate compilation actually puts code into separate compilation
# units. `foo.rs` defines `magic_fn` in three different modules, which should
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/Makefile b/src/test/run-make-fulldeps/share-generics-dylib/Makefile
index 282cb2461..065fb574c 100644
--- a/src/test/run-make-fulldeps/share-generics-dylib/Makefile
+++ b/src/test/run-make-fulldeps/share-generics-dylib/Makefile
@@ -9,7 +9,7 @@
#
# This is regression test for https://github.com/rust-lang/rust/issues/67276.
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
COMMON_ARGS=-Cprefer-dynamic -Zshare-generics=yes -Ccodegen-units=1 -Csymbol-mangling-version=v0
diff --git a/src/test/run-make-fulldeps/simd-ffi/Makefile b/src/test/run-make-fulldeps/simd-ffi/Makefile
index e9c974a01..297353470 100644
--- a/src/test/run-make-fulldeps/simd-ffi/Makefile
+++ b/src/test/run-make-fulldeps/simd-ffi/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
TARGETS =
ifeq ($(filter arm,$(LLVM_COMPONENTS)),arm)
diff --git a/src/test/run-make-fulldeps/simple-dylib/Makefile b/src/test/run-make-fulldeps/simple-dylib/Makefile
index 26730820f..5dda5d66d 100644
--- a/src/test/run-make-fulldeps/simple-dylib/Makefile
+++ b/src/test/run-make-fulldeps/simple-dylib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=dylib -C prefer-dynamic
$(RUSTC) foo.rs
diff --git a/src/test/run-make-fulldeps/simple-rlib/Makefile b/src/test/run-make-fulldeps/simple-rlib/Makefile
index 7b156cb87..d912b8a7b 100644
--- a/src/test/run-make-fulldeps/simple-rlib/Makefile
+++ b/src/test/run-make-fulldeps/simple-rlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=rlib
$(RUSTC) foo.rs
diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile
index e2dc64d8c..1032f3408 100644
--- a/src/test/run-make-fulldeps/split-debuginfo/Makefile
+++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: off packed unpacked
@@ -29,14 +29,19 @@ unpacked:
[ ! -d $(TMPDIR)/foo.dSYM ]
else
ifdef IS_WINDOWS
-# Windows only supports =off
+# Windows only supports =packed
off:
packed:
unpacked:
else
-# If disabled, don't run dsymutil
+ifeq ($(UNAME),Linux)
+ UNSTABLEOPTS :=
+else
+ UNSTABLEOPTS := -Zunstable-options
+endif
+
off:
- $(RUSTC) foo.rs -g -C split-debuginfo=off -Z unstable-options
+ $(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off
[ ! -f $(TMPDIR)/*.dwp ]
[ ! -f $(TMPDIR)/*.dwo ]
@@ -47,12 +52,12 @@ off:
packed: packed-split packed-single
packed-split:
- $(RUSTC) foo.rs -g -C split-debuginfo=packed -Z unstable-options -Zsplit-dwarf-kind=split
+ $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split
ls $(TMPDIR)/*.dwp
rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo
packed-single:
- $(RUSTC) foo.rs -g -C split-debuginfo=packed -Z unstable-options -Zsplit-dwarf-kind=single
+ $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single
ls $(TMPDIR)/*.dwp
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm -rf $(TMPDIR)/*.dwp
@@ -60,37 +65,37 @@ packed-single:
packed-remapped: packed-remapped-split packed-remapped-single
packed-remapped-split:
- $(RUSTC) -Z unstable-options -C split-debuginfo=packed -C debuginfo=2 \
+ $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
packed-remapped-single:
- $(RUSTC) -Z unstable-options -C split-debuginfo=packed -C debuginfo=2 \
+ $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
packed-crosscrate: packed-crosscrate-split packed-crosscrate-single
packed-crosscrate-split:
- $(RUSTC) --crate-type lib -Z unstable-options -C split-debuginfo=packed \
+ $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \
-Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs
ls $(TMPDIR)/*.rlib
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
- $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options -C split-debuginfo=packed \
- -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs
+ $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \
+ -C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs
rm $(TMPDIR)/*.dwo
rm $(TMPDIR)/main.dwp
rm $(TMPDIR)/$(call BIN,main)
packed-crosscrate-single:
- $(RUSTC) --crate-type lib -Z unstable-options -C split-debuginfo=packed \
+ $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \
-Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs
ls $(TMPDIR)/*.rlib
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
- $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options -C split-debuginfo=packed \
- -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs
+ $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \
+ -C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/main.dwp
rm $(TMPDIR)/$(call BIN,main)
@@ -98,23 +103,23 @@ packed-crosscrate-single:
unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single
unpacked-split:
- $(RUSTC) foo.rs -g -C split-debuginfo=unpacked -Z unstable-options -Zsplit-dwarf-kind=split
+ $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
ls $(TMPDIR)/*.dwo
rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo
unpacked-single:
- $(RUSTC) foo.rs -g -C split-debuginfo=unpacked -Z unstable-options -Zsplit-dwarf-kind=single
+ $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
unpacked-remapped-split:
- $(RUSTC) -Z unstable-options -C split-debuginfo=unpacked -C debuginfo=2 \
+ $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
unpacked-remapped-single:
- $(RUSTC) -Z unstable-options -C split-debuginfo=unpacked -C debuginfo=2 \
+ $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
endif
diff --git a/src/test/run-make-fulldeps/stable-symbol-names/Makefile b/src/test/run-make-fulldeps/stable-symbol-names/Makefile
index 451af809b..bbfb8e388 100644
--- a/src/test/run-make-fulldeps/stable-symbol-names/Makefile
+++ b/src/test/run-make-fulldeps/stable-symbol-names/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# The following command will:
# 1. dump the symbols of a library using `nm`
diff --git a/src/test/run-make-fulldeps/static-dylib-by-default/Makefile b/src/test/run-make-fulldeps/static-dylib-by-default/Makefile
index 6409aa66a..eedd0b320 100644
--- a/src/test/run-make-fulldeps/static-dylib-by-default/Makefile
+++ b/src/test/run-make-fulldeps/static-dylib-by-default/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
TO_LINK := $(call DYLIB,bar)
ifdef IS_MSVC
diff --git a/src/test/run-make-fulldeps/static-extern-type/Makefile b/src/test/run-make-fulldeps/static-extern-type/Makefile
index 5879fc0ce..e9aa95e63 100644
--- a/src/test/run-make-fulldeps/static-extern-type/Makefile
+++ b/src/test/run-make-fulldeps/static-extern-type/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all: $(call NATIVE_STATICLIB,define-foo)
$(RUSTC) -ldefine-foo use-foo.rs
diff --git a/src/test/run-make-fulldeps/static-unwinding/Makefile b/src/test/run-make-fulldeps/static-unwinding/Makefile
index cb0397442..9c755d4ab 100644
--- a/src/test/run-make-fulldeps/static-unwinding/Makefile
+++ b/src/test/run-make-fulldeps/static-unwinding/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) lib.rs
diff --git a/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile b/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile
index 92a278825..fcbf87758 100644
--- a/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile
+++ b/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(AR) crus $(TMPDIR)/libfoo.a foo.rs
diff --git a/src/test/run-make-fulldeps/std-core-cycle/Makefile b/src/test/run-make-fulldeps/std-core-cycle/Makefile
index ce3b2d46b..4f2528637 100644
--- a/src/test/run-make-fulldeps/std-core-cycle/Makefile
+++ b/src/test/run-make-fulldeps/std-core-cycle/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
ifeq ($(UNAME),Darwin)
FLAGS :=
diff --git a/src/test/run-make-fulldeps/stdin-non-utf8/Makefile b/src/test/run-make-fulldeps/stdin-non-utf8/Makefile
index 7948c4426..709d4cf14 100644
--- a/src/test/run-make-fulldeps/stdin-non-utf8/Makefile
+++ b/src/test/run-make-fulldeps/stdin-non-utf8/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
cp non-utf8 $(TMPDIR)/non-utf.rs
diff --git a/src/test/run-make-fulldeps/suspicious-library/Makefile b/src/test/run-make-fulldeps/suspicious-library/Makefile
index 12f437075..2af9e85c2 100644
--- a/src/test/run-make-fulldeps/suspicious-library/Makefile
+++ b/src/test/run-make-fulldeps/suspicious-library/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs -C prefer-dynamic
diff --git a/src/test/run-make-fulldeps/symbols-include-type-name/Makefile b/src/test/run-make-fulldeps/symbols-include-type-name/Makefile
index 0850a2633..ac26a852e 100644
--- a/src/test/run-make-fulldeps/symbols-include-type-name/Makefile
+++ b/src/test/run-make-fulldeps/symbols-include-type-name/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# Check that symbol names for methods include type names, instead of <impl>.
diff --git a/src/test/run-make-fulldeps/symlinked-extern/Makefile b/src/test/run-make-fulldeps/symlinked-extern/Makefile
index e5061fdde..058f43e85 100644
--- a/src/test/run-make-fulldeps/symlinked-extern/Makefile
+++ b/src/test/run-make-fulldeps/symlinked-extern/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# `ln` is actually `cp` on msys.
diff --git a/src/test/run-make-fulldeps/symlinked-libraries/Makefile b/src/test/run-make-fulldeps/symlinked-libraries/Makefile
index 618ae87bf..576bf7e54 100644
--- a/src/test/run-make-fulldeps/symlinked-libraries/Makefile
+++ b/src/test/run-make-fulldeps/symlinked-libraries/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# `ln` is actually `cp` on msys.
diff --git a/src/test/run-make-fulldeps/symlinked-rlib/Makefile b/src/test/run-make-fulldeps/symlinked-rlib/Makefile
index 996989ce4..49d3f220a 100644
--- a/src/test/run-make-fulldeps/symlinked-rlib/Makefile
+++ b/src/test/run-make-fulldeps/symlinked-rlib/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows
# `ln` is actually `cp` on msys.
diff --git a/src/test/run-make-fulldeps/target-cpu-native/Makefile b/src/test/run-make-fulldeps/target-cpu-native/Makefile
index d152e9f76..eb3ca1e13 100644
--- a/src/test/run-make-fulldeps/target-cpu-native/Makefile
+++ b/src/test/run-make-fulldeps/target-cpu-native/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-linux
# only-x86_64
diff --git a/src/test/run-make-fulldeps/target-specs/Makefile b/src/test/run-make-fulldeps/target-specs/Makefile
index fb95ee553..a33f5368e 100644
--- a/src/test/run-make-fulldeps/target-specs/Makefile
+++ b/src/test/run-make-fulldeps/target-specs/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) foo.rs --target=my-awesome-platform.json --crate-type=lib --emit=asm
$(CGREP) -v morestack < $(TMPDIR)/foo.s
diff --git a/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile
index 9868fc1d4..451f03d66 100644
--- a/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile
+++ b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# The target used below doesn't support atomic CAS operations. Verify that's the case
all:
diff --git a/src/test/run-make-fulldeps/test-harness/Makefile b/src/test/run-make-fulldeps/test-harness/Makefile
index 39477c07c..1fe059b07 100644
--- a/src/test/run-make-fulldeps/test-harness/Makefile
+++ b/src/test/run-make-fulldeps/test-harness/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
# check that #[cfg_attr(..., ignore)] does the right thing.
diff --git a/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile
index 802b3df46..9f4be7126 100644
--- a/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile
+++ b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
# compile two different versions of crateA
diff --git a/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile
index 838b1a271..6ae53afad 100644
--- a/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile
+++ b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-freebsd
# ignore-openbsd
diff --git a/src/test/run-make-fulldeps/use-suggestions-rust-2018/Makefile b/src/test/run-make-fulldeps/use-suggestions-rust-2018/Makefile
index fc39691c5..37cd6283c 100644
--- a/src/test/run-make-fulldeps/use-suggestions-rust-2018/Makefile
+++ b/src/test/run-make-fulldeps/use-suggestions-rust-2018/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) ep-nested-lib.rs
diff --git a/src/test/run-make-fulldeps/used-cdylib-macos/Makefile b/src/test/run-make-fulldeps/used-cdylib-macos/Makefile
index 4828d9c8a..38a4c31c7 100644
--- a/src/test/run-make-fulldeps/used-cdylib-macos/Makefile
+++ b/src/test/run-make-fulldeps/used-cdylib-macos/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-macos
#
diff --git a/src/test/run-make-fulldeps/used/Makefile b/src/test/run-make-fulldeps/used/Makefile
index 4d9044729..e80eb9e40 100644
--- a/src/test/run-make-fulldeps/used/Makefile
+++ b/src/test/run-make-fulldeps/used/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# ignore-windows-msvc
diff --git a/src/test/run-make-fulldeps/version/Makefile b/src/test/run-make-fulldeps/version/Makefile
index 23e14a9cb..3a130545d 100644
--- a/src/test/run-make-fulldeps/version/Makefile
+++ b/src/test/run-make-fulldeps/version/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) -V
diff --git a/src/test/run-make-fulldeps/volatile-intrinsics/Makefile b/src/test/run-make-fulldeps/volatile-intrinsics/Makefile
index acbadbef9..2a78c7b9c 100644
--- a/src/test/run-make-fulldeps/volatile-intrinsics/Makefile
+++ b/src/test/run-make-fulldeps/volatile-intrinsics/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
# The tests must pass...
diff --git a/src/test/run-make-fulldeps/weird-output-filenames/Makefile b/src/test/run-make-fulldeps/weird-output-filenames/Makefile
index f161fe9f8..d3a34e3b4 100644
--- a/src/test/run-make-fulldeps/weird-output-filenames/Makefile
+++ b/src/test/run-make-fulldeps/weird-output-filenames/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
cp foo.rs $(TMPDIR)/.foo.rs
diff --git a/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile b/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile
index f6adb6d76..8960020fe 100644
--- a/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile
+++ b/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-windows
diff --git a/src/test/run-make-fulldeps/windows-spawn/Makefile b/src/test/run-make-fulldeps/windows-spawn/Makefile
index c09ce8109..b6cdb169b 100644
--- a/src/test/run-make-fulldeps/windows-spawn/Makefile
+++ b/src/test/run-make-fulldeps/windows-spawn/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
# only-windows
diff --git a/src/test/run-make-fulldeps/windows-subsystem/Makefile b/src/test/run-make-fulldeps/windows-subsystem/Makefile
index 34fb5db32..78c4e2ac1 100644
--- a/src/test/run-make-fulldeps/windows-subsystem/Makefile
+++ b/src/test/run-make-fulldeps/windows-subsystem/Makefile
@@ -1,4 +1,4 @@
--include ../tools.mk
+include ../tools.mk
all:
$(RUSTC) windows.rs
diff --git a/src/test/run-make/const_fn_mir/Makefile b/src/test/run-make/const_fn_mir/Makefile
index 2aa0bc9d4..ad5695093 100644
--- a/src/test/run-make/const_fn_mir/Makefile
+++ b/src/test/run-make/const_fn_mir/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) main.rs --emit=mir -o "$(TMPDIR)"/dump.mir
diff --git a/src/test/run-make/coverage-llvmir/filecheck.testprog.txt b/src/test/run-make/coverage-llvmir/filecheck.testprog.txt
index 7a5f21922..c943261d7 100644
--- a/src/test/run-make/coverage-llvmir/filecheck.testprog.txt
+++ b/src/test/run-make/coverage-llvmir/filecheck.testprog.txt
@@ -9,7 +9,7 @@ CHECK-SAME: section "[[INSTR_PROF_COVFUN]]"[[COMDAT_IF_SUPPORTED]], align 8
CHECK: @__llvm_coverage_mapping = private constant
CHECK-SAME: section "[[INSTR_PROF_COVMAP]]", align 8
-WINDOWS: @__llvm_profile_runtime = external global i32
+WINDOWS: @__llvm_profile_runtime = external{{.*}}global i32
CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
CHECK-SAME: section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
diff --git a/src/test/run-make/coverage-reports/Makefile b/src/test/run-make/coverage-reports/Makefile
index 4e75672f2..6fc2a6bad 100644
--- a/src/test/run-make/coverage-reports/Makefile
+++ b/src/test/run-make/coverage-reports/Makefile
@@ -60,7 +60,7 @@ endif
# for now, but it is effectively ignored for all tests that don't include this file anyway.
#
# (Note that it's also possible the `_counters.<test>.txt` and `<test>.json` files (if generated)
-# may order results from multiple files inconsistently, which might also have to be accomodated
+# may order results from multiple files inconsistently, which might also have to be accommodated
# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
# appear to be normalized to `/` in those files, thankfully.)
LLVM_COV_IGNORE_FILES=\
@@ -75,7 +75,7 @@ ifdef RUSTC_BLESS_TEST
rm -f expected_*
endif
--include clear_expected_if_blessed
+include clear_expected_if_blessed
%: $(SOURCEDIR)/lib/%.rs
# Compile the test library with coverage instrumentation
@@ -157,7 +157,7 @@ else
# `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation
# with `llvm-cov show`. When reporting coverage for multiple instantiations of a generic function,
# with different type substitutions, `llvm-cov show` prints these in a non-deterministic order,
- # breaking the `diff` comparision.
+ # breaking the `diff` comparison.
#
# A partial workaround is implemented below, with `diff --ignore-matching-lines=RE`
# to ignore each line prefixing each generic instantiation coverage code region.
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make/coverage-reports/expected_show_coverage.async.txt
index 2f69adbd8..87ccb6c43 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.async.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.async.txt
@@ -55,7 +55,7 @@
53| 1| 1 // This line appears covered, but the 1-character expression span covering the `1`
^0
54| 1| // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
- 55| 1| // `fn j()` executes the open brace for the funciton body, followed by the function's
+ 55| 1| // `fn j()` executes the open brace for the function body, followed by the function's
56| 1| // first executable statement, `match x`. Inner function declarations are not
57| 1| // "visible" to the MIR for `j()`, so the code region counts all lines between the
58| 1| // open brace and the first statement as executed, which is, in a sense, true.
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt
index 09ad276aa..e463099a5 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt
@@ -37,7 +37,7 @@
37| 0| countdown = 10;
38| 0| }
39| 0| "alt string 2".to_owned()
- 40| | };
+ 40| 0| };
41| 1| println!(
42| 1| "The string or alt: {}"
43| 1| ,
@@ -79,7 +79,7 @@
79| 0| countdown = 10;
80| 1| }
81| 1| "alt string 4".to_owned()
- 82| | };
+ 82| 1| };
83| 1| println!(
84| 1| "The string or alt: {}"
85| 1| ,
@@ -101,7 +101,7 @@
101| 0| countdown = 10;
102| 5| }
103| 5| format!("'{}'", val)
- 104| | };
+ 104| 5| };
105| 1| println!(
106| 1| "Repeated, quoted string: {:?}"
107| 1| ,
@@ -125,7 +125,7 @@
125| 0| countdown = 10;
126| 0| }
127| 0| "closure should be unused".to_owned()
- 128| | };
+ 128| 0| };
129| |
130| 1| let mut countdown = 10;
131| 1| let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
@@ -177,7 +177,7 @@
173| 0| println!(
174| 0| "not called: {}",
175| 0| if is_true { "check" } else { "me" }
- 176| | )
+ 176| 0| )
177| | ;
178| |
179| 1| let short_used_not_covered_closure_line_break_block_embedded_branch =
@@ -187,7 +187,7 @@
183| 0| "not called: {}",
184| 0| if is_true { "check" } else { "me" }
185| | )
- 186| | }
+ 186| 0| }
187| | ;
188| |
189| 1| let short_used_covered_closure_line_break_no_block_embedded_branch =
@@ -196,7 +196,7 @@
192| 1| "not called: {}",
193| 1| if is_true { "check" } else { "me" }
^0
- 194| | )
+ 194| 1| )
195| | ;
196| |
197| 1| let short_used_covered_closure_line_break_block_embedded_branch =
@@ -207,7 +207,7 @@
202| 1| if is_true { "check" } else { "me" }
^0
203| | )
- 204| | }
+ 204| 1| }
205| | ;
206| |
207| 1| if is_false {
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
index 7ae0e9788..732de6526 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
@@ -23,12 +23,6 @@
22| 1|//! ```
23| 2|//! #[derive(Debug, PartialEq)]
^1
- ------------------
- | Unexecuted instantiation: <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::ne
- ------------------
- | <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::eq:
- | 23| 2|//! #[derive(Debug, PartialEq)]
- ------------------
24| 1|//! struct SomeError {
25| 1|//! msg: String,
26| 1|//! }
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.generator.txt b/src/test/run-make/coverage-reports/expected_show_coverage.generator.txt
index d70e12e41..0fb3808ff 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.generator.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.generator.txt
@@ -18,7 +18,7 @@
17| 1| let mut generator = || {
18| 1| yield get_u32(is_true);
19| 1| return "foo";
- 20| | };
+ 20| 1| };
21| |
22| 1| match Pin::new(&mut generator).resume(()) {
23| 1| GeneratorState::Yielded(Ok(1)) => {}
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt b/src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt
index effdef80e..a59fe1146 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt
@@ -6,7 +6,7 @@
6| 1|
7| 1| let f = |x: bool| {
8| | debug_assert!(
- 9| | x
+ 9| 0| x
10| | );
11| 1| };
12| 1| f(false);
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
index de32c88b7..25c74ab2e 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
@@ -2,12 +2,6 @@
2| |
3| 3|#[derive(Debug, PartialEq, Eq)]
^2
- ------------------
- | <issue_83601::Foo as core::cmp::PartialEq>::eq:
- | 3| 2|#[derive(Debug, PartialEq, Eq)]
- ------------------
- | Unexecuted instantiation: <issue_83601::Foo as core::cmp::PartialEq>::ne
- ------------------
4| |struct Foo(u32);
5| |
6| 1|fn main() {
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
index f24f7c694..4a60432c1 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
@@ -2,12 +2,6 @@
2| |
3| |// expect-exit-status-101
4| 21|#[derive(PartialEq, Eq)]
- ------------------
- | <issue_84561::Foo as core::cmp::PartialEq>::eq:
- | 4| 21|#[derive(PartialEq, Eq)]
- ------------------
- | Unexecuted instantiation: <issue_84561::Foo as core::cmp::PartialEq>::ne
- ------------------
5| |struct Foo(u32);
6| 1|fn test3() {
7| 1| let is_true = std::env::args().len() == 1;
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt b/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
index fc2666533..a77175af6 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
@@ -3,11 +3,6 @@
3| |
4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
^0 ^0 ^0 ^1 ^1 ^0^0
- ------------------
- | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::ne
- ------------------
- | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::eq
- ------------------
5| |pub struct Version {
6| | major: usize,
7| | minor: usize,
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
index dab31cbf4..748343885 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
@@ -61,12 +61,12 @@
46| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
47| 4|}
------------------
- | used_inline_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+ | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>:
| 45| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 47| 2|}
------------------
- | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+ | used_inline_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 45| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 47| 2|}
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt b/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt
index 60a8d943f..6e2f23ee7 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt
@@ -8,7 +8,7 @@
8| 1| let mut generator = || {
9| 1| yield 1;
10| 1| return "foo"
- 11| | };
+ 11| 1| };
12| |
13| 1| match Pin::new(&mut generator).resume(()) {
14| 1| GeneratorState::Yielded(1) => {}
@@ -24,7 +24,7 @@
24| 1| yield 2;
25| 0| yield 3;
26| 0| return "foo"
- 27| | };
+ 27| 0| };
28| |
29| 1| match Pin::new(&mut generator).resume(()) {
30| 1| GeneratorState::Yielded(1) => {}
diff --git a/src/test/run-make/coverage/async.rs b/src/test/run-make/coverage/async.rs
index a6e387747..efd9e62d6 100644
--- a/src/test/run-make/coverage/async.rs
+++ b/src/test/run-make/coverage/async.rs
@@ -52,7 +52,7 @@ fn j(x: u8) {
if x == 8 {
1 // This line appears covered, but the 1-character expression span covering the `1`
// is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
- // `fn j()` executes the open brace for the funciton body, followed by the function's
+ // `fn j()` executes the open brace for the function body, followed by the function's
// first executable statement, `match x`. Inner function declarations are not
// "visible" to the MIR for `j()`, so the code region counts all lines between the
// open brace and the first statement as executed, which is, in a sense, true.
diff --git a/src/test/run-make/dep-graph/Makefile b/src/test/run-make/dep-graph/Makefile
index 88916022c..ae97b1672 100644
--- a/src/test/run-make/dep-graph/Makefile
+++ b/src/test/run-make/dep-graph/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# ignore-cross-compile
diff --git a/src/test/run-make/emit-named-files/Makefile b/src/test/run-make/emit-named-files/Makefile
index 03eb83b97..e081fa479 100644
--- a/src/test/run-make/emit-named-files/Makefile
+++ b/src/test/run-make/emit-named-files/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUT=$(TMPDIR)/emit
diff --git a/src/test/run-make/emit-path-unhashed/Makefile b/src/test/run-make/emit-path-unhashed/Makefile
index b6b2d8af6..c144d4aa9 100644
--- a/src/test/run-make/emit-path-unhashed/Makefile
+++ b/src/test/run-make/emit-path-unhashed/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUT=$(TMPDIR)/emit
diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile
index 9f46883be..09b4c29c1 100644
--- a/src/test/run-make/emit-shared-files/Makefile
+++ b/src/test/run-make/emit-shared-files/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
INVOCATION_ONLY = $(TMPDIR)/invocation-only
TOOLCHAIN_ONLY = $(TMPDIR)/toolchain-only
diff --git a/src/test/run-make/env-dep-info/Makefile b/src/test/run-make/env-dep-info/Makefile
index 25d9a31c2..1675a61b1 100644
--- a/src/test/run-make/env-dep-info/Makefile
+++ b/src/test/run-make/env-dep-info/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
# instead of hardcoding them everywhere they're needed.
diff --git a/src/test/run-make/export-executable-symbols/Makefile b/src/test/run-make/export-executable-symbols/Makefile
index 5006f9cb8..daa77c99d 100644
--- a/src/test/run-make/export-executable-symbols/Makefile
+++ b/src/test/run-make/export-executable-symbols/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# ignore-wasm32
# ignore-wasm64
diff --git a/src/test/run-make/fmt-write-bloat/Makefile b/src/test/run-make/fmt-write-bloat/Makefile
index 26e08086a..07e6e025e 100644
--- a/src/test/run-make/fmt-write-bloat/Makefile
+++ b/src/test/run-make/fmt-write-bloat/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# ignore-windows
diff --git a/src/test/run-make/issue-10971-temps-dir/Makefile b/src/test/run-make/issue-10971-temps-dir/Makefile
index 5ce271926..e589bbffe 100644
--- a/src/test/run-make/issue-10971-temps-dir/Makefile
+++ b/src/test/run-make/issue-10971-temps-dir/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# Regression test for issue #10971
# Running two invocations in parallel would overwrite each other's temp files.
diff --git a/src/test/run-make/issue-47384/Makefile b/src/test/run-make/issue-47384/Makefile
index f10365f8c..0aadf6c88 100644
--- a/src/test/run-make/issue-47384/Makefile
+++ b/src/test/run-make/issue-47384/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-linux
# ignore-cross-compile
diff --git a/src/test/run-make/issue-71519/Makefile b/src/test/run-make/issue-71519/Makefile
index 636665ec1..16d9a56e6 100644
--- a/src/test/run-make/issue-71519/Makefile
+++ b/src/test/run-make/issue-71519/Makefile
@@ -1,5 +1,6 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
+# ignore-msvc
# needs-rust-lld
all:
RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Z gcc-ld=lld -C link-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
diff --git a/src/test/run-make/issue-85401-static-mir/Makefile b/src/test/run-make/issue-85401-static-mir/Makefile
new file mode 100644
index 000000000..99590166b
--- /dev/null
+++ b/src/test/run-make/issue-85401-static-mir/Makefile
@@ -0,0 +1,16 @@
+include ../../run-make-fulldeps/tools.mk
+
+# Regression test for issue #85401
+# Verify that we do not ICE when trying to access MIR for statics,
+# but emit an error when linking.
+
+OUTPUT_FILE := $(TMPDIR)/build-output
+
+all:
+ $(RUSTC) --crate-type rlib --crate-name foo -Crelocation-model=pic --edition=2018 foo.rs -Zalways-encode-mir=yes --emit metadata -o $(TMPDIR)/libfoo.rmeta
+ $(RUSTC) --crate-type rlib --crate-name bar -Crelocation-model=pic --edition=2018 bar.rs -o $(TMPDIR)/libbar.rlib --extern=foo=$(TMPDIR)/libfoo.rmeta
+ $(RUSTC) --crate-type bin --crate-name baz -Crelocation-model=pic --edition=2018 baz.rs -o $(TMPDIR)/baz -L $(TMPDIR) --extern=bar=$(TMPDIR)/libbar.rlib > $(OUTPUT_FILE) 2>&1; [ $$? -eq 1 ]
+ cat $(OUTPUT_FILE)
+ $(CGREP) 'crate `foo` required to be available in rlib format, but was not found in this form' < $(OUTPUT_FILE)
+ # -v tests are fragile, hopefully this text won't change
+ $(CGREP) -v "internal compiler error" < $(OUTPUT_FILE)
diff --git a/src/test/run-make/issue-85401-static-mir/bar.rs b/src/test/run-make/issue-85401-static-mir/bar.rs
new file mode 100644
index 000000000..15b12ecf3
--- /dev/null
+++ b/src/test/run-make/issue-85401-static-mir/bar.rs
@@ -0,0 +1,4 @@
+pub fn bar() {
+ println!("bar {}", foo::FOO);
+ foo::foo();
+}
diff --git a/src/test/run-make/issue-85401-static-mir/baz.rs b/src/test/run-make/issue-85401-static-mir/baz.rs
new file mode 100644
index 000000000..2ff4c51e5
--- /dev/null
+++ b/src/test/run-make/issue-85401-static-mir/baz.rs
@@ -0,0 +1,3 @@
+fn main() {
+ bar::bar()
+}
diff --git a/src/test/run-make/issue-85401-static-mir/foo.rs b/src/test/run-make/issue-85401-static-mir/foo.rs
new file mode 100644
index 000000000..d064c4546
--- /dev/null
+++ b/src/test/run-make/issue-85401-static-mir/foo.rs
@@ -0,0 +1,5 @@
+pub static FOO: &str = "foo";
+
+pub fn foo() {
+ println!("foo");
+}
diff --git a/src/test/run-make/issue-85441/Makefile b/src/test/run-make/issue-85441/Makefile
index c7ae708c1..f04b07d51 100644
--- a/src/test/run-make/issue-85441/Makefile
+++ b/src/test/run-make/issue-85441/Makefile
@@ -1,6 +1,6 @@
# only-windows-msvc
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# Tests that WS2_32.dll is not unnecessarily linked, see issue #85441
diff --git a/src/test/run-make/issue-88756-default-output/Makefile b/src/test/run-make/issue-88756-default-output/Makefile
index cacbcbf39..275c35c26 100644
--- a/src/test/run-make/issue-88756-default-output/Makefile
+++ b/src/test/run-make/issue-88756-default-output/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(BARE_RUSTDOC) 2>&1 | sed -E 's@/nightly/|/beta/|/stable/|/1\.[0-9]+\.[0-9]+/@/$$CHANNEL/@g' | diff - output-default.stdout
diff --git a/src/test/run-make/issue-96498/Makefile b/src/test/run-make/issue-96498/Makefile
index eae6400ae..ce2b1b1ff 100644
--- a/src/test/run-make/issue-96498/Makefile
+++ b/src/test/run-make/issue-96498/Makefile
@@ -1,7 +1,7 @@
# only-windows
# needs-rust-lld
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# Ensure that LLD can link
all:
diff --git a/src/test/run-make/libtest-thread-limit/Makefile b/src/test/run-make/libtest-thread-limit/Makefile
index 29c1bc71d..d43a89e60 100644
--- a/src/test/run-make/libtest-thread-limit/Makefile
+++ b/src/test/run-make/libtest-thread-limit/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-linux
diff --git a/src/test/run-make/llvm-outputs/Makefile b/src/test/run-make/llvm-outputs/Makefile
index d7f67577b..a3f25eba0 100644
--- a/src/test/run-make/llvm-outputs/Makefile
+++ b/src/test/run-make/llvm-outputs/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir
diff --git a/src/test/run-make/native-link-modifier-bundle/Makefile b/src/test/run-make/native-link-modifier-bundle/Makefile
index e4b0f74ac..7c78d7783 100644
--- a/src/test/run-make/native-link-modifier-bundle/Makefile
+++ b/src/test/run-make/native-link-modifier-bundle/Makefile
@@ -1,7 +1,7 @@
# ignore-cross-compile
# ignore-windows-msvc
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# We're using the llvm-nm instead of the system nm to ensure it is compatible
# with the LLVM bitcode generated by rustc.
diff --git a/src/test/run-make/native-link-modifier-whole-archive/Makefile b/src/test/run-make/native-link-modifier-whole-archive/Makefile
index 967cb065c..f26bd864c 100644
--- a/src/test/run-make/native-link-modifier-whole-archive/Makefile
+++ b/src/test/run-make/native-link-modifier-whole-archive/Makefile
@@ -8,7 +8,7 @@
# that code would never make it into the final executable and we'd thus be missing some
# of the output.
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all: $(TMPDIR)/$(call BIN,directly_linked) \
$(TMPDIR)/$(call BIN,directly_linked_test_plus_whole_archive) \
diff --git a/src/test/run-make/pass-linker-flags-from-dep/Makefile b/src/test/run-make/pass-linker-flags-from-dep/Makefile
index 365216b4c..b9426326a 100644
--- a/src/test/run-make/pass-linker-flags-from-dep/Makefile
+++ b/src/test/run-make/pass-linker-flags-from-dep/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
# Build deps
diff --git a/src/test/run-make/pass-linker-flags/Makefile b/src/test/run-make/pass-linker-flags/Makefile
index 02b1e2179..a3efb8df6 100644
--- a/src/test/run-make/pass-linker-flags/Makefile
+++ b/src/test/run-make/pass-linker-flags/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) rs.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/Makefile b/src/test/run-make/raw-dylib-alt-calling-convention/Makefile
index a254285ab..03f8778d2 100644
--- a/src/test/run-make/raw-dylib-alt-calling-convention/Makefile
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/Makefile
@@ -3,7 +3,7 @@
# only-x86
# only-windows
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) --crate-type lib --crate-name raw_dylib_alt_calling_convention_test lib.rs
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/extern.c b/src/test/run-make/raw-dylib-alt-calling-convention/extern.c
index 0c4d12af9..344d4a6bf 100644
--- a/src/test/run-make/raw-dylib-alt-calling-convention/extern.c
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/extern.c
@@ -70,6 +70,11 @@ __declspec(dllexport) void __stdcall stdcall_fn_9(uint8_t x, double y) {
fflush(stdout);
}
+__declspec(dllexport) void __stdcall stdcall_fn_10(int i) {
+ printf("stdcall_fn_10(%d)\n", i);
+ fflush(stdout);
+}
+
__declspec(dllexport) void __fastcall fastcall_fn_1(int i) {
printf("fastcall_fn_1(%d)\n", i);
fflush(stdout);
@@ -122,6 +127,11 @@ __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
fflush(stdout);
}
+__declspec(dllexport) void __fastcall fastcall_fn_10(int i) {
+ printf("fastcall_fn_10(%d)\n", i);
+ fflush(stdout);
+}
+
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
#ifdef _MSC_VER
__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
@@ -175,4 +185,9 @@ __declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) {
printf("vectorcall_fn_9(%d, %.1f)\n", x, y);
fflush(stdout);
}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_10(int i) {
+ printf("vectorcall_fn_10(%d)\n", i);
+ fflush(stdout);
+}
#endif
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs b/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
index b5e9415b2..22f222c12 100644
--- a/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
@@ -1,5 +1,5 @@
-#![feature(raw_dylib)]
#![feature(abi_vectorcall)]
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[repr(C)]
#[derive(Clone)]
@@ -32,6 +32,8 @@ extern "stdcall" {
fn stdcall_fn_7(a: S2, b: i32);
fn stdcall_fn_8(a: S3, b: S3);
fn stdcall_fn_9(x: u8, y: f64);
+ #[link_name = "stdcall_fn_10"]
+ fn stdcall_fn_10_renamed(i: i32);
}
#[link(name = "extern", kind = "raw-dylib")]
@@ -45,6 +47,8 @@ extern "fastcall" {
fn fastcall_fn_7(a: S2, b: i32);
fn fastcall_fn_8(a: S3, b: S3);
fn fastcall_fn_9(x: u8, y: f64);
+ #[link_name = "fastcall_fn_10"]
+ fn fastcall_fn_10_renamed(i: i32);
}
#[cfg(target_env = "msvc")]
@@ -59,6 +63,8 @@ extern "vectorcall" {
fn vectorcall_fn_7(a: S2, b: i32);
fn vectorcall_fn_8(a: S3, b: S3);
fn vectorcall_fn_9(x: u8, y: f64);
+ #[link_name = "vectorcall_fn_10"]
+ fn vectorcall_fn_10_renamed(i: i32);
}
pub fn library_function(run_msvc_only: bool) {
@@ -73,6 +79,7 @@ pub fn library_function(run_msvc_only: bool) {
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
stdcall_fn_9(1, 3.0);
+ stdcall_fn_10_renamed(19);
fastcall_fn_1(14);
fastcall_fn_2(16, 3.5);
@@ -81,6 +88,7 @@ pub fn library_function(run_msvc_only: bool) {
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
fastcall_fn_9(1, 3.0);
+ fastcall_fn_10_renamed(19);
} else {
// FIXME: 91167
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
@@ -100,6 +108,7 @@ pub fn library_function(run_msvc_only: bool) {
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3);
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
vectorcall_fn_9(1, 3.0);
+ vectorcall_fn_10_renamed(19);
}
}
}
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/output.msvc.txt b/src/test/run-make/raw-dylib-alt-calling-convention/output.msvc.txt
index 9ddd1b110..a216835c4 100644
--- a/src/test/run-make/raw-dylib-alt-calling-convention/output.msvc.txt
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/output.msvc.txt
@@ -9,3 +9,4 @@ vectorcall_fn_6(S { x: 10, y: 12 })
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3)
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
vectorcall_fn_9(1, 3.0)
+vectorcall_fn_10(19)
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/output.txt b/src/test/run-make/raw-dylib-alt-calling-convention/output.txt
index 348bad63e..7622d3161 100644
--- a/src/test/run-make/raw-dylib-alt-calling-convention/output.txt
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/output.txt
@@ -7,6 +7,7 @@ stdcall_fn_6(S { x: 10, y: 12 })
stdcall_fn_7(S2 { x: 15, y: 16 }, 3)
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
stdcall_fn_9(1, 3.0)
+stdcall_fn_10(19)
fastcall_fn_1(14)
fastcall_fn_2(16, 3.5)
fastcall_fn_3(3.5)
@@ -14,3 +15,4 @@ fastcall_fn_4(1, 2, 3.0)
fastcall_fn_6(S { x: 10, y: 12 })
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
fastcall_fn_9(1, 3.0)
+fastcall_fn_10(19)
diff --git a/src/test/run-make/raw-dylib-c/Makefile b/src/test/run-make/raw-dylib-c/Makefile
index 713f66507..f47ab24f4 100644
--- a/src/test/run-make/raw-dylib-c/Makefile
+++ b/src/test/run-make/raw-dylib-c/Makefile
@@ -2,7 +2,7 @@
# only-windows
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
diff --git a/src/test/run-make/raw-dylib-c/extern_1.c b/src/test/run-make/raw-dylib-c/extern_1.c
index 72737c086..5d695547d 100644
--- a/src/test/run-make/raw-dylib-c/extern_1.c
+++ b/src/test/run-make/raw-dylib-c/extern_1.c
@@ -1,5 +1,7 @@
#include <stdio.h>
+__declspec(dllexport) int extern_variable = 0;
+
__declspec(dllexport) void extern_fn_1() {
printf("extern_fn_1\n");
fflush(stdout);
@@ -10,7 +12,17 @@ __declspec(dllexport) void extern_fn_2() {
fflush(stdout);
}
+__declspec(dllexport) void print_extern_variable() {
+ printf("extern_variable value: %d\n", extern_variable);
+ fflush(stdout);
+}
+
__declspec(dllexport) void extern_fn_with_long_name() {
printf("extern_fn_with_long_name; got the rename\n");
fflush(stdout);
}
+
+__declspec(dllexport) void extern_fn_4() {
+ printf("extern_fn_4\n");
+ fflush(stdout);
+}
diff --git a/src/test/run-make/raw-dylib-c/lib.rs b/src/test/run-make/raw-dylib-c/lib.rs
index 58f7ccb38..005ffcdda 100644
--- a/src/test/run-make/raw-dylib-c/lib.rs
+++ b/src/test/run-make/raw-dylib-c/lib.rs
@@ -12,12 +12,23 @@ extern {
pub fn library_function() {
#[link(name = "extern_1", kind = "raw-dylib")]
- extern { fn extern_fn_2(); }
+ extern {
+ fn extern_fn_2();
+ fn print_extern_variable();
+ static mut extern_variable: i32;
+ #[link_name = "extern_fn_4"]
+ fn extern_fn_4_renamed();
+ }
unsafe {
extern_fn_1();
extern_fn_2();
extern_fn_3();
+ extern_fn_4_renamed();
+ extern_variable = 42;
+ print_extern_variable();
+ extern_variable = -42;
+ print_extern_variable();
}
}
diff --git a/src/test/run-make/raw-dylib-c/output.txt b/src/test/run-make/raw-dylib-c/output.txt
index 7800cba18..cc970cef7 100644
--- a/src/test/run-make/raw-dylib-c/output.txt
+++ b/src/test/run-make/raw-dylib-c/output.txt
@@ -1,3 +1,6 @@
extern_fn_1
extern_fn_2; didn't get the rename
extern_fn_3
+extern_fn_4
+extern_variable value: 42
+extern_variable value: -42
diff --git a/src/test/run-make/raw-dylib-import-name-type/Makefile b/src/test/run-make/raw-dylib-import-name-type/Makefile
new file mode 100644
index 000000000..fcc60e88e
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/Makefile
@@ -0,0 +1,22 @@
+# Test the behavior of #[link(.., kind = "raw-dylib")] with alternative calling conventions.
+
+# only-x86
+# only-windows
+
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
+ $(call COMPILE_OBJ,"$(TMPDIR)"/extern.obj,extern.c)
+ifdef IS_MSVC
+ $(CC) "$(TMPDIR)"/extern.obj extern.msvc.def -link -dll -out:"$(TMPDIR)"/extern.dll -noimplib
+else
+ $(CC) "$(TMPDIR)"/extern.obj extern.gnu.def --no-leading-underscore -shared -o "$(TMPDIR)"/extern.dll
+endif
+ "$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
+
+ifdef RUSTC_BLESS_TEST
+ cp "$(TMPDIR)"/output.txt output.txt
+else
+ $(DIFF) output.txt "$(TMPDIR)"/output.txt
+endif
diff --git a/src/test/run-make/raw-dylib-import-name-type/driver.rs b/src/test/run-make/raw-dylib-import-name-type/driver.rs
new file mode 100644
index 000000000..a38849fc8
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/driver.rs
@@ -0,0 +1,125 @@
+#![feature(raw_dylib)]
+#![feature(abi_vectorcall)]
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "C" {
+ fn cdecl_fn_undecorated(i: i32);
+ #[link_name = "cdecl_fn_undecorated2"]
+ fn cdecl_fn_undecorated_renamed(i: i32);
+ static mut extern_variable_undecorated: i32;
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "C" {
+ fn cdecl_fn_noprefix(i: i32);
+ static mut extern_variable_noprefix: i32;
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "C" {
+ fn cdecl_fn_decorated(i: i32);
+ static mut extern_variable_decorated: i32;
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "stdcall" {
+ fn stdcall_fn_undecorated(i: i32);
+ #[link_name = "stdcall_fn_undecorated2"]
+ fn stdcall_fn_undecorated_renamed(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "stdcall" {
+ fn stdcall_fn_noprefix(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "stdcall" {
+ fn stdcall_fn_decorated(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "fastcall" {
+ fn fastcall_fn_undecorated(i: i32);
+ #[link_name = "fastcall_fn_undecorated2"]
+ fn fastcall_fn_undecorated_renamed(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "fastcall" {
+ fn fastcall_fn_noprefix(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "fastcall" {
+ fn fastcall_fn_decorated(i: i32);
+}
+
+#[cfg(target_env = "msvc")]
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "vectorcall" {
+ fn vectorcall_fn_undecorated(i: i32);
+ #[link_name = "vectorcall_fn_undecorated2"]
+ fn vectorcall_fn_undecorated_renamed(i: i32);
+}
+
+#[cfg(target_env = "msvc")]
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "vectorcall" {
+ fn vectorcall_fn_noprefix(i: i32);
+}
+
+#[cfg(target_env = "msvc")]
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "vectorcall" {
+ fn vectorcall_fn_decorated(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib")]
+extern {
+ fn print_extern_variable_undecorated();
+ fn print_extern_variable_noprefix();
+ fn print_extern_variable_decorated();
+}
+
+pub fn main() {
+ unsafe {
+ cdecl_fn_undecorated(1);
+ cdecl_fn_undecorated_renamed(10);
+ cdecl_fn_noprefix(2);
+ cdecl_fn_decorated(3);
+
+ stdcall_fn_undecorated(4);
+ stdcall_fn_undecorated_renamed(14);
+ stdcall_fn_noprefix(5);
+ stdcall_fn_decorated(6);
+
+ fastcall_fn_undecorated(7);
+ fastcall_fn_undecorated_renamed(17);
+ fastcall_fn_noprefix(8);
+ fastcall_fn_decorated(9);
+
+ extern_variable_undecorated = 42;
+ print_extern_variable_undecorated();
+ extern_variable_noprefix = 43;
+ print_extern_variable_noprefix();
+ extern_variable_decorated = 44;
+ print_extern_variable_decorated();
+
+ // GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
+ #[cfg(target_env = "msvc")]
+ {
+ vectorcall_fn_undecorated(10);
+ vectorcall_fn_undecorated_renamed(20);
+ vectorcall_fn_noprefix(11);
+ vectorcall_fn_decorated(12);
+ }
+ #[cfg(not(target_env = "msvc"))]
+ {
+ println!("vectorcall_fn_undecorated(10)");
+ println!("vectorcall_fn_undecorated2(20)");
+ println!("vectorcall_fn_noprefix(11)");
+ println!("vectorcall_fn_decorated(12)");
+ }
+ }
+}
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.c b/src/test/run-make/raw-dylib-import-name-type/extern.c
new file mode 100644
index 000000000..195126d51
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void _cdecl cdecl_fn_undecorated(int i) {
+ printf("cdecl_fn_undecorated(%d)\n", i);
+ fflush(stdout);
+}
+
+void _cdecl cdecl_fn_undecorated2(int i) {
+ printf("cdecl_fn_undecorated2(%d)\n", i);
+ fflush(stdout);
+}
+
+void _cdecl cdecl_fn_noprefix(int i) {
+ printf("cdecl_fn_noprefix(%d)\n", i);
+ fflush(stdout);
+}
+
+void _cdecl cdecl_fn_decorated(int i) {
+ printf("cdecl_fn_decorated(%d)\n", i);
+ fflush(stdout);
+}
+
+void __stdcall stdcall_fn_undecorated(int i) {
+ printf("stdcall_fn_undecorated(%d)\n", i);
+ fflush(stdout);
+}
+
+void __stdcall stdcall_fn_undecorated2(int i) {
+ printf("stdcall_fn_undecorated2(%d)\n", i);
+ fflush(stdout);
+}
+
+void __stdcall stdcall_fn_noprefix(int i) {
+ printf("stdcall_fn_noprefix(%d)\n", i);
+ fflush(stdout);
+}
+
+void __stdcall stdcall_fn_decorated(int i) {
+ printf("stdcall_fn_decorated(%d)\n", i);
+ fflush(stdout);
+}
+
+void __fastcall fastcall_fn_undecorated(int i) {
+ printf("fastcall_fn_undecorated(%d)\n", i);
+ fflush(stdout);
+}
+
+void __fastcall fastcall_fn_undecorated2(int i) {
+ printf("fastcall_fn_undecorated2(%d)\n", i);
+ fflush(stdout);
+}
+
+void __fastcall fastcall_fn_noprefix(int i) {
+ printf("fastcall_fn_noprefix(%d)\n", i);
+ fflush(stdout);
+}
+
+void __fastcall fastcall_fn_decorated(int i) {
+ printf("fastcall_fn_decorated(%d)\n", i);
+ fflush(stdout);
+}
+
+int extern_variable_undecorated = 0;
+__declspec(dllexport) void print_extern_variable_undecorated() {
+ printf("extern_variable_undecorated value: %d\n", extern_variable_undecorated);
+ fflush(stdout);
+}
+
+int extern_variable_noprefix = 0;
+__declspec(dllexport) void print_extern_variable_noprefix() {
+ printf("extern_variable_noprefix value: %d\n", extern_variable_noprefix);
+ fflush(stdout);
+}
+
+int extern_variable_decorated = 0;
+__declspec(dllexport) void print_extern_variable_decorated() {
+ printf("extern_variable_decorated value: %d\n", extern_variable_decorated);
+ fflush(stdout);
+}
+
+// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
+#ifdef _MSC_VER
+void __vectorcall vectorcall_fn_undecorated(int i) {
+ printf("vectorcall_fn_undecorated(%d)\n", i);
+ fflush(stdout);
+}
+
+void __vectorcall vectorcall_fn_undecorated2(int i) {
+ printf("vectorcall_fn_undecorated2(%d)\n", i);
+ fflush(stdout);
+}
+
+void __vectorcall vectorcall_fn_noprefix(int i) {
+ printf("vectorcall_fn_noprefix(%d)\n", i);
+ fflush(stdout);
+}
+
+void __vectorcall vectorcall_fn_decorated(int i) {
+ printf("vectorcall_fn_decorated(%d)\n", i);
+ fflush(stdout);
+}
+#endif
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def b/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
new file mode 100644
index 000000000..a523c959a
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
@@ -0,0 +1,21 @@
+LIBRARY extern
+EXPORTS
+ cdecl_fn_undecorated
+ cdecl_fn_undecorated2
+ cdecl_fn_noprefix
+ cdecl_fn_decorated
+ stdcall_fn_undecorated
+ stdcall_fn_undecorated2
+ stdcall_fn_noprefix@4
+ fastcall_fn_undecorated
+ fastcall_fn_undecorated2
+ @fastcall_fn_decorated@4
+
+ ;ld doesn't handle fully-decorated stdcall, or no-prefix fastcall
+ _stdcall_fn_decorated@4=stdcall_fn_decorated@4
+ fastcall_fn_noprefix@4=@fastcall_fn_noprefix@4
+
+ ;Variables are never decorated
+ extern_variable_undecorated
+ extern_variable_noprefix
+ extern_variable_decorated
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def b/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
new file mode 100644
index 000000000..dbff32d4c
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
@@ -0,0 +1,25 @@
+LIBRARY extern
+EXPORTS
+ cdecl_fn_undecorated
+ cdecl_fn_undecorated2
+ cdecl_fn_noprefix
+ cdecl_fn_decorated
+ stdcall_fn_undecorated
+ stdcall_fn_undecorated2
+ _stdcall_fn_decorated@4
+ fastcall_fn_undecorated
+ fastcall_fn_undecorated2
+ @fastcall_fn_decorated@4
+ vectorcall_fn_undecorated
+ vectorcall_fn_undecorated2
+ vectorcall_fn_decorated@@4
+ vectorcall_fn_noprefix@@4
+
+ ;MSVC doesn't seem to recognize the "no prefix" syntax.
+ stdcall_fn_noprefix@4=_stdcall_fn_noprefix@4
+ fastcall_fn_noprefix@4=@fastcall_fn_noprefix@4
+
+ ;Variables are never decorated
+ extern_variable_undecorated
+ extern_variable_noprefix
+ extern_variable_decorated
diff --git a/src/test/run-make/raw-dylib-import-name-type/output.txt b/src/test/run-make/raw-dylib-import-name-type/output.txt
new file mode 100644
index 000000000..707faf403
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/output.txt
@@ -0,0 +1,19 @@
+cdecl_fn_undecorated(1)
+cdecl_fn_undecorated2(10)
+cdecl_fn_noprefix(2)
+cdecl_fn_decorated(3)
+stdcall_fn_undecorated(4)
+stdcall_fn_undecorated2(14)
+stdcall_fn_noprefix(5)
+stdcall_fn_decorated(6)
+fastcall_fn_undecorated(7)
+fastcall_fn_undecorated2(17)
+fastcall_fn_noprefix(8)
+fastcall_fn_decorated(9)
+extern_variable_undecorated value: 42
+extern_variable_noprefix value: 43
+extern_variable_decorated value: 44
+vectorcall_fn_undecorated(10)
+vectorcall_fn_undecorated2(20)
+vectorcall_fn_noprefix(11)
+vectorcall_fn_decorated(12)
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/Makefile b/src/test/run-make/raw-dylib-inline-cross-dylib/Makefile
new file mode 100644
index 000000000..9e603f958
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/Makefile
@@ -0,0 +1,31 @@
+# Regression test for calling an inline function that uses a raw-dylib function.
+
+# only-windows
+
+include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(RUSTC) --crate-type dylib --crate-name raw_dylib_test lib.rs -C prefer-dynamic
+ $(RUSTC) --crate-type dylib --crate-name raw_dylib_test_wrapper lib_wrapper.rs -C prefer-dynamic
+ $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" -C prefer-dynamic
+ # Make sure we don't find an import to the functions we expect to be inlined.
+ "$(LLVM_BIN_DIR)"/llvm-objdump -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function"
+ "$(LLVM_BIN_DIR)"/llvm-objdump -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function_calls_inline"
+ # Make sure we do find an import to the functions we expect to be imported.
+ "$(LLVM_BIN_DIR)"/llvm-objdump -p $(TMPDIR)/driver.exe | $(CGREP) -e "library_function"
+ $(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c)
+ $(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c)
+ifdef IS_MSVC
+ $(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll -noimplib
+ $(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll -noimplib
+else
+ $(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll
+ $(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll
+endif
+ $(call RUN,driver) > "$(TMPDIR)"/output.txt
+
+ifdef RUSTC_BLESS_TEST
+ cp "$(TMPDIR)"/output.txt output.txt
+else
+ $(DIFF) output.txt "$(TMPDIR)"/output.txt
+endif
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs b/src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs
new file mode 100644
index 000000000..f72ded7d9
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs
@@ -0,0 +1,21 @@
+#![feature(raw_dylib)]
+
+extern crate raw_dylib_test;
+extern crate raw_dylib_test_wrapper;
+
+#[link(name = "extern_2", kind = "raw-dylib")]
+extern {
+ fn extern_fn_2();
+}
+
+fn main() {
+ // NOTE: The inlined call to `extern_fn_2` links against the function in extern_2.dll instead
+ // of extern_1.dll since raw-dylib symbols from the current crate are passed to the linker
+ // first, so any ambiguous names will prefer the current crate's definition.
+ raw_dylib_test::inline_library_function();
+ raw_dylib_test::library_function();
+ raw_dylib_test_wrapper::inline_library_function_calls_inline();
+ unsafe {
+ extern_fn_2();
+ }
+}
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c
new file mode 100644
index 000000000..e5baaf5f0
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+__declspec(dllexport) void extern_fn_1() {
+ printf("extern_fn_1\n");
+ fflush(stdout);
+}
+
+__declspec(dllexport) void extern_fn_2() {
+ printf("extern_fn_2 in extern_1\n");
+ fflush(stdout);
+}
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c
new file mode 100644
index 000000000..30aa46922
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+__declspec(dllexport) void extern_fn_2() {
+ printf("extern_fn_2 in extern_2\n");
+ fflush(stdout);
+}
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs b/src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs
new file mode 100644
index 000000000..00c2c1c42
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs
@@ -0,0 +1,21 @@
+#![feature(raw_dylib)]
+
+#[link(name = "extern_1", kind = "raw-dylib")]
+extern {
+ fn extern_fn_1();
+ fn extern_fn_2();
+}
+
+#[inline]
+pub fn inline_library_function() {
+ unsafe {
+ extern_fn_1();
+ extern_fn_2();
+ }
+}
+
+pub fn library_function() {
+ unsafe {
+ extern_fn_2();
+ }
+}
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs b/src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs
new file mode 100644
index 000000000..47191b8de
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs
@@ -0,0 +1,6 @@
+extern crate raw_dylib_test;
+
+#[inline]
+pub fn inline_library_function_calls_inline() {
+ raw_dylib_test::inline_library_function();
+}
diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/output.txt b/src/test/run-make/raw-dylib-inline-cross-dylib/output.txt
new file mode 100644
index 000000000..e7009baa0
--- /dev/null
+++ b/src/test/run-make/raw-dylib-inline-cross-dylib/output.txt
@@ -0,0 +1,6 @@
+extern_fn_1
+extern_fn_2 in extern_2
+extern_fn_2 in extern_1
+extern_fn_1
+extern_fn_2 in extern_2
+extern_fn_2 in extern_2
diff --git a/src/test/run-make/raw-dylib-link-ordinal/Makefile b/src/test/run-make/raw-dylib-link-ordinal/Makefile
index c9baa3c1e..b55a94dbc 100644
--- a/src/test/run-make/raw-dylib-link-ordinal/Makefile
+++ b/src/test/run-make/raw-dylib-link-ordinal/Makefile
@@ -2,7 +2,7 @@
# only-windows
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
diff --git a/src/test/run-make/raw-dylib-link-ordinal/exporter.c b/src/test/run-make/raw-dylib-link-ordinal/exporter.c
index a9dd6da66..aabf32ff1 100644
--- a/src/test/run-make/raw-dylib-link-ordinal/exporter.c
+++ b/src/test/run-make/raw-dylib-link-ordinal/exporter.c
@@ -3,3 +3,10 @@
void exported_function() {
printf("exported_function\n");
}
+
+int exported_variable = 0;
+
+void print_exported_variable() {
+ printf("exported_variable value: %d\n", exported_variable);
+ fflush(stdout);
+}
diff --git a/src/test/run-make/raw-dylib-link-ordinal/exporter.def b/src/test/run-make/raw-dylib-link-ordinal/exporter.def
index 1a4b4c941..5d87c580a 100644
--- a/src/test/run-make/raw-dylib-link-ordinal/exporter.def
+++ b/src/test/run-make/raw-dylib-link-ordinal/exporter.def
@@ -1,3 +1,5 @@
LIBRARY exporter
EXPORTS
exported_function @13 NONAME
+ exported_variable @5 NONAME
+ print_exported_variable @9 NONAME
diff --git a/src/test/run-make/raw-dylib-link-ordinal/lib.rs b/src/test/run-make/raw-dylib-link-ordinal/lib.rs
index 20609caa5..bb25ac64c 100644
--- a/src/test/run-make/raw-dylib-link-ordinal/lib.rs
+++ b/src/test/run-make/raw-dylib-link-ordinal/lib.rs
@@ -1,13 +1,21 @@
-#![feature(raw_dylib)]
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "exporter", kind = "raw-dylib")]
extern {
#[link_ordinal(13)]
fn imported_function();
+ #[link_ordinal(5)]
+ static mut imported_variable: i32;
+ #[link_ordinal(9)]
+ fn print_imported_variable();
}
pub fn library_function() {
unsafe {
imported_function();
+ imported_variable = 42;
+ print_imported_variable();
+ imported_variable = -42;
+ print_imported_variable();
}
}
diff --git a/src/test/run-make/raw-dylib-link-ordinal/output.txt b/src/test/run-make/raw-dylib-link-ordinal/output.txt
index 2d0ed60f2..a4b2031d9 100644
--- a/src/test/run-make/raw-dylib-link-ordinal/output.txt
+++ b/src/test/run-make/raw-dylib-link-ordinal/output.txt
@@ -1 +1,3 @@
exported_function
+exported_variable value: 42
+exported_variable value: -42
diff --git a/src/test/run-make/raw-dylib-stdcall-ordinal/Makefile b/src/test/run-make/raw-dylib-stdcall-ordinal/Makefile
index 3360a97b5..b9deb7729 100644
--- a/src/test/run-make/raw-dylib-stdcall-ordinal/Makefile
+++ b/src/test/run-make/raw-dylib-stdcall-ordinal/Makefile
@@ -3,7 +3,7 @@
# only-x86
# only-windows
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
diff --git a/src/test/run-make/raw-dylib-stdcall-ordinal/lib.rs b/src/test/run-make/raw-dylib-stdcall-ordinal/lib.rs
index 07dd3d7be..b7921396a 100644
--- a/src/test/run-make/raw-dylib-stdcall-ordinal/lib.rs
+++ b/src/test/run-make/raw-dylib-stdcall-ordinal/lib.rs
@@ -1,4 +1,4 @@
-#![feature(raw_dylib)]
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "exporter", kind = "raw-dylib")]
extern "stdcall" {
diff --git a/src/test/run-make/remap-path-prefix-dwarf/Makefile b/src/test/run-make/remap-path-prefix-dwarf/Makefile
index 561a343d6..fbaea7b68 100644
--- a/src/test/run-make/remap-path-prefix-dwarf/Makefile
+++ b/src/test/run-make/remap-path-prefix-dwarf/Makefile
@@ -6,7 +6,7 @@
SRC_DIR := $(abspath .)
SRC_DIR_PARENT := $(abspath ..)
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all: \
abs_input_outside_working_dir \
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile b/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
new file mode 100644
index 000000000..4574cf17f
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
@@ -0,0 +1,22 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Make sure -Zpacked_bundled_libs is compatible with verbatim.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all:
+ # Build strange-named dep.
+ $(RUSTC) native_dep.rs --crate-type=staticlib -o $(TMPDIR)/native_dep.ext
+
+ $(RUSTC) rust_dep.rs --crate-type=rlib -Zpacked_bundled_libs
+ $(NM) $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "U.*native_f1"
+ $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) "native_dep.ext"
+
+ # Make sure compiler doesn't use files, that it shouldn't know about.
+ rm $(TMPDIR)/native_dep.ext
+
+ $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib -Zpacked_bundled_libs
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs
new file mode 100644
index 000000000..8d2b8a285
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs
@@ -0,0 +1,5 @@
+extern crate rust_dep;
+
+pub fn main() {
+ rust_dep::rust_dep();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs
new file mode 100644
index 000000000..321a8237e
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub fn native_f1() -> i32 {
+ return 1;
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs
new file mode 100644
index 000000000..d99dda05c
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs
@@ -0,0 +1,11 @@
+#![feature(native_link_modifiers_verbatim)]
+#[link(name = "native_dep.ext", kind = "static", modifiers = "+verbatim")]
+extern "C" {
+ fn native_f1() -> i32;
+}
+
+pub fn rust_dep() {
+ unsafe {
+ assert!(native_f1() == 1);
+ }
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/Makefile b/src/test/run-make/rlib-format-packed-bundled-libs/Makefile
new file mode 100644
index 000000000..0b991ac42
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/Makefile
@@ -0,0 +1,34 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Make sure rlib format with -Zpacked_bundled_libs is correct.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3)
+ $(RUSTC) rust_dep_up.rs --crate-type=rlib -Zpacked_bundled_libs
+ $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f2"
+ $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f3"
+ $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "T.*rust_dep_up"
+ $(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_2"
+ $(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_3"
+ $(RUSTC) rust_dep_local.rs --extern rlib=$(TMPDIR)/librust_dep_up.rlib -Zpacked_bundled_libs --crate-type=rlib
+ $(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "U.*native_f1"
+ $(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "T.*rust_dep_local"
+ $(AR) t $(TMPDIR)/librust_dep_local.rlib | $(CGREP) "native_dep_1"
+
+ # Make sure compiler doesn't use files, that it shouldn't know about.
+ rm $(TMPDIR)/*native_dep_*
+
+ $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_local.rlib -o $(TMPDIR)/main.exe -Zpacked_bundled_libs --print link-args | $(CGREP) -e "native_dep_1.*native_dep_2.*native_dep_3"
+
+ifndef IS_MSVC
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f1"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f2"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f3"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_local"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_up"
+endif
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/main.rs b/src/test/run-make/rlib-format-packed-bundled-libs/main.rs
new file mode 100644
index 000000000..042a4879f
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/main.rs
@@ -0,0 +1,4 @@
+extern crate rust_dep_local;
+pub fn main() {
+ rust_dep_local::rust_dep_local();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c
new file mode 100644
index 000000000..07be8562c
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c
@@ -0,0 +1 @@
+int native_f1() { return 1; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c
new file mode 100644
index 000000000..a1b94e40d
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c
@@ -0,0 +1 @@
+int native_f2() { return 2; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c
new file mode 100644
index 000000000..f81f397a4
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c
@@ -0,0 +1 @@
+int native_f3() { return 3; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs
new file mode 100644
index 000000000..8280c7d6c
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs
@@ -0,0 +1,13 @@
+#[link(name = "native_dep_1", kind = "static")]
+extern "C" {
+ fn native_f1() -> i32;
+}
+
+extern crate rust_dep_up;
+
+pub fn rust_dep_local() {
+ unsafe {
+ assert!(native_f1() == 1);
+ }
+ rust_dep_up::rust_dep_up();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs
new file mode 100644
index 000000000..edcd7c521
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs
@@ -0,0 +1,13 @@
+#[link(name = "native_dep_2", kind = "static")]
+#[link(name = "native_dep_3", kind = "static")]
+extern "C" {
+ fn native_f2() -> i32;
+ fn native_f3() -> i32;
+}
+
+pub fn rust_dep_up() {
+ unsafe {
+ assert!(native_f2() == 2);
+ assert!(native_f3() == 3);
+ }
+}
diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make/rustc-macro-dep-files/Makefile
index a08a63fb4..6ae659db2 100644
--- a/src/test/run-make/rustc-macro-dep-files/Makefile
+++ b/src/test/run-make/rustc-macro-dep-files/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
# instead of hardcoding them everywhere they're needed.
diff --git a/src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile b/src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile
index dce8b83ee..7786ff762 100644
--- a/src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile
+++ b/src/test/run-make/rustdoc-scrape-examples-invalid-expr/Makefile
@@ -1,5 +1,5 @@
deps := ex
--include ../rustdoc-scrape-examples-multiple/scrape.mk
+include ../rustdoc-scrape-examples-multiple/scrape.mk
all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-multiple/Makefile b/src/test/run-make/rustdoc-scrape-examples-multiple/Makefile
index 897805e44..453a7d4bc 100644
--- a/src/test/run-make/rustdoc-scrape-examples-multiple/Makefile
+++ b/src/test/run-make/rustdoc-scrape-examples-multiple/Makefile
@@ -1,5 +1,5 @@
deps := ex ex2
--include ./scrape.mk
+include ./scrape.mk
all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk b/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
index d49b6c1f2..7a28d2145 100644
--- a/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
+++ b/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
diff --git a/src/test/run-make/rustdoc-scrape-examples-ordering/Makefile b/src/test/run-make/rustdoc-scrape-examples-ordering/Makefile
index 339d539bf..bf45b8148 100644
--- a/src/test/run-make/rustdoc-scrape-examples-ordering/Makefile
+++ b/src/test/run-make/rustdoc-scrape-examples-ordering/Makefile
@@ -1,5 +1,5 @@
deps := ex1 ex2
--include ../rustdoc-scrape-examples-multiple/scrape.mk
+include ../rustdoc-scrape-examples-multiple/scrape.mk
all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-remap/Makefile b/src/test/run-make/rustdoc-scrape-examples-remap/Makefile
index dce8b83ee..7786ff762 100644
--- a/src/test/run-make/rustdoc-scrape-examples-remap/Makefile
+++ b/src/test/run-make/rustdoc-scrape-examples-remap/Makefile
@@ -1,5 +1,5 @@
deps := ex
--include ../rustdoc-scrape-examples-multiple/scrape.mk
+include ../rustdoc-scrape-examples-multiple/scrape.mk
all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/Makefile b/src/test/run-make/rustdoc-scrape-examples-test/Makefile
index 9f80a8d96..1235ead67 100644
--- a/src/test/run-make/rustdoc-scrape-examples-test/Makefile
+++ b/src/test/run-make/rustdoc-scrape-examples-test/Makefile
@@ -1,6 +1,6 @@
extra_flags := --scrape-tests
deps := ex
--include ../rustdoc-scrape-examples-multiple/scrape.mk
+include ../rustdoc-scrape-examples-multiple/scrape.mk
all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-whitespace/Makefile b/src/test/run-make/rustdoc-scrape-examples-whitespace/Makefile
index dce8b83ee..7786ff762 100644
--- a/src/test/run-make/rustdoc-scrape-examples-whitespace/Makefile
+++ b/src/test/run-make/rustdoc-scrape-examples-whitespace/Makefile
@@ -1,5 +1,5 @@
deps := ex
--include ../rustdoc-scrape-examples-multiple/scrape.mk
+include ../rustdoc-scrape-examples-multiple/scrape.mk
all: scrape
diff --git a/src/test/run-make/rustdoc-with-out-dir-option/Makefile b/src/test/run-make/rustdoc-with-out-dir-option/Makefile
index f79fce8ee..b3c3f5230 100644
--- a/src/test/run-make/rustdoc-with-out-dir-option/Makefile
+++ b/src/test/run-make/rustdoc-with-out-dir-option/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
diff --git a/src/test/run-make/rustdoc-with-output-option/Makefile b/src/test/run-make/rustdoc-with-output-option/Makefile
index 654f96725..02093a35c 100644
--- a/src/test/run-make/rustdoc-with-output-option/Makefile
+++ b/src/test/run-make/rustdoc-with-output-option/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
diff --git a/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile b/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile
index 1e9ba71de..dc5056a86 100644
--- a/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile
+++ b/src/test/run-make/rustdoc-with-short-out-dir-option/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
diff --git a/src/test/run-make/static-pie/Makefile b/src/test/run-make/static-pie/Makefile
index 945ec1724..e71770636 100644
--- a/src/test/run-make/static-pie/Makefile
+++ b/src/test/run-make/static-pie/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-x86_64
# only-linux
diff --git a/src/test/run-make/thumb-none-cortex-m/Makefile b/src/test/run-make/thumb-none-cortex-m/Makefile
index 13385369e..aa046af95 100644
--- a/src/test/run-make/thumb-none-cortex-m/Makefile
+++ b/src/test/run-make/thumb-none-cortex-m/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# How to run this
# $ ./x.py clean
diff --git a/src/test/run-make/thumb-none-qemu/Makefile b/src/test/run-make/thumb-none-qemu/Makefile
index ab8b90e15..328758d41 100644
--- a/src/test/run-make/thumb-none-qemu/Makefile
+++ b/src/test/run-make/thumb-none-qemu/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-thumb
diff --git a/src/test/run-make/track-path-dep-info/Makefile b/src/test/run-make/track-path-dep-info/Makefile
index 465d37447..ee853943f 100644
--- a/src/test/run-make/track-path-dep-info/Makefile
+++ b/src/test/run-make/track-path-dep-info/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
# instead of hardcoding them everywhere they're needed.
diff --git a/src/test/run-make/track-pgo-dep-info/Makefile b/src/test/run-make/track-pgo-dep-info/Makefile
new file mode 100644
index 000000000..60b59c04a
--- /dev/null
+++ b/src/test/run-make/track-pgo-dep-info/Makefile
@@ -0,0 +1,26 @@
+# needs-profiler-support
+# ignore-windows-gnu
+
+-include ../../run-make-fulldeps/tools.mk
+
+# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
+# instead of hardcoding them everywhere they're needed.
+ifeq ($(IS_MUSL_HOST),1)
+ADDITIONAL_ARGS := $(RUSTFLAGS)
+endif
+
+all:
+ # Generate PGO profiles
+ $(BARE_RUSTC) $(ADDITIONAL_ARGS) -Cprofile-generate=$(TMPDIR)/profiles --out-dir $(TMPDIR) main.rs
+ $(TMPDIR)/main
+
+ # Merge profiles
+ "$(LLVM_BIN_DIR)/llvm-profdata" merge \
+ -o "$(TMPDIR)/merged.profdata" \
+ "$(TMPDIR)/profiles" || exit 1
+
+ # Use the profile
+ $(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata --emit dep-info main.rs
+
+ # Check that profile file is in depinfo
+ $(CGREP) "merged.profdata" < $(TMPDIR)/main.d
diff --git a/src/test/run-make/track-pgo-dep-info/main.rs b/src/test/run-make/track-pgo-dep-info/main.rs
new file mode 100644
index 000000000..f328e4d9d
--- /dev/null
+++ b/src/test/run-make/track-pgo-dep-info/main.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/test/run-make/translation/Makefile b/src/test/run-make/translation/Makefile
index bfff75e7a..20e86c7f9 100644
--- a/src/test/run-make/translation/Makefile
+++ b/src/test/run-make/translation/Makefile
@@ -9,16 +9,29 @@ FAKEROOT=$(TMPDIR)/fakeroot
all: normal custom sysroot
-normal: basic-translation.rs
+# Check that the test works normally, using the built-in fallback bundle.
+normal: test.rs
$(RUSTC) $< 2>&1 | grep "struct literal body without path"
-custom: basic-translation.rs basic-translation.ftl
- $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/basic-translation.ftl 2>&1 | grep "this is a test message"
+# Check that a primary bundle can be loaded and will be preferentially used
+# where possible.
+custom: test.rs working.ftl
+ $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/working.ftl 2>&1 | grep "this is a test message"
+
+# Check that a primary bundle with a broken message (e.g. a interpolated
+# variable is missing) will use the fallback bundle.
+missing: test.rs missing.ftl
+ $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/missing.ftl 2>&1 | grep "struct literal body without path"
+
+# Check that a primary bundle without the desired message will use the fallback
+# bundle.
+broken: test.rs broken.ftl
+ $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/broken.ftl 2>&1 | grep "struct literal body without path"
# Check that a locale can be loaded from the sysroot given a language
# identifier by making a local copy of the sysroot and adding the custom locale
# to it.
-sysroot: basic-translation.rs basic-translation.ftl
+sysroot: test.rs working.ftl
mkdir $(FAKEROOT)
ln -s $(SYSROOT)/* $(FAKEROOT)
rm -f $(FAKEROOT)/lib
@@ -31,7 +44,7 @@ sysroot: basic-translation.rs basic-translation.ftl
mkdir $(FAKEROOT)/lib/rustlib/src
ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src
mkdir -p $(FAKEROOT)/share/locale/zh-CN/
- ln -s $(CURDIR)/basic-translation.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
+ ln -s $(CURDIR)/working.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
$(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "this is a test message"
# Check that the compiler errors out when the sysroot requested cannot be
@@ -43,7 +56,7 @@ sysroot-missing:
# Check that the compiler errors out when the sysroot requested cannot be
# found. This test might start failing if there actually exists a Klingon
# translation of rustc's error messages.
-sysroot-invalid: basic-translation.rs basic-translation.ftl
+sysroot-invalid: test.rs working.ftl
mkdir $(FAKEROOT)
ln -s $(SYSROOT)/* $(FAKEROOT)
rm -f $(FAKEROOT)/lib
diff --git a/src/test/run-make/translation/basic-translation.ftl b/src/test/run-make/translation/basic-translation.ftl
deleted file mode 100644
index 4681b879c..000000000
--- a/src/test/run-make/translation/basic-translation.ftl
+++ /dev/null
@@ -1,2 +0,0 @@
-parser-struct-literal-body-without-path = this is a test message
- .suggestion = this is a test suggestion
diff --git a/src/test/run-make/translation/broken.ftl b/src/test/run-make/translation/broken.ftl
new file mode 100644
index 000000000..4e3585835
--- /dev/null
+++ b/src/test/run-make/translation/broken.ftl
@@ -0,0 +1,3 @@
+# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
+parser_struct_literal_body_without_path = this is a {$foo} message
+ .suggestion = this is a test suggestion
diff --git a/src/test/run-make/translation/missing.ftl b/src/test/run-make/translation/missing.ftl
new file mode 100644
index 000000000..77bbda357
--- /dev/null
+++ b/src/test/run-make/translation/missing.ftl
@@ -0,0 +1,3 @@
+# `parser_struct_literal_body_without_path` isn't provided by this resource at all, so the
+# fallback should be used.
+foo = bar
diff --git a/src/test/run-make/translation/basic-translation.rs b/src/test/run-make/translation/test.rs
index b8f5bff31..b8f5bff31 100644
--- a/src/test/run-make/translation/basic-translation.rs
+++ b/src/test/run-make/translation/test.rs
diff --git a/src/test/run-make/translation/working.ftl b/src/test/run-make/translation/working.ftl
new file mode 100644
index 000000000..d5ea86738
--- /dev/null
+++ b/src/test/run-make/translation/working.ftl
@@ -0,0 +1,2 @@
+parser_struct_literal_body_without_path = this is a test message
+ .suggestion = this is a test suggestion
diff --git a/src/test/run-make/unstable-flag-required/Makefile b/src/test/run-make/unstable-flag-required/Makefile
index b8769d5f6..d3a734fae 100644
--- a/src/test/run-make/unstable-flag-required/Makefile
+++ b/src/test/run-make/unstable-flag-required/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
all:
$(RUSTDOC) --output-format=json x.html 2>&1 | diff - output-format-json.stderr
diff --git a/src/test/run-make/wasm-abi/Makefile b/src/test/run-make/wasm-abi/Makefile
index 61fc4e8f5..e713ca187 100644
--- a/src/test/run-make/wasm-abi/Makefile
+++ b/src/test/run-make/wasm-abi/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-custom-section/Makefile b/src/test/run-make/wasm-custom-section/Makefile
index 2f48b8525..92b0802e3 100644
--- a/src/test/run-make/wasm-custom-section/Makefile
+++ b/src/test/run-make/wasm-custom-section/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-custom-sections-opt/Makefile b/src/test/run-make/wasm-custom-sections-opt/Makefile
index 76698c0aa..e5b45d963 100644
--- a/src/test/run-make/wasm-custom-sections-opt/Makefile
+++ b/src/test/run-make/wasm-custom-sections-opt/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-export-all-symbols/Makefile b/src/test/run-make/wasm-export-all-symbols/Makefile
index 7e47ba485..834f4d258 100644
--- a/src/test/run-make/wasm-export-all-symbols/Makefile
+++ b/src/test/run-make/wasm-export-all-symbols/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-import-module/Makefile b/src/test/run-make/wasm-import-module/Makefile
index fe63e66f2..18cef16aa 100644
--- a/src/test/run-make/wasm-import-module/Makefile
+++ b/src/test/run-make/wasm-import-module/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-panic-small/Makefile b/src/test/run-make/wasm-panic-small/Makefile
index 68397e4bc..2af9f7135 100644
--- a/src/test/run-make/wasm-panic-small/Makefile
+++ b/src/test/run-make/wasm-panic-small/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-spurious-import/Makefile b/src/test/run-make/wasm-spurious-import/Makefile
index 1bb59dc1b..6f50e6e55 100644
--- a/src/test/run-make/wasm-spurious-import/Makefile
+++ b/src/test/run-make/wasm-spurious-import/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-stringify-ints-small/Makefile b/src/test/run-make/wasm-stringify-ints-small/Makefile
index 01e1c6b0c..2fa2c954d 100644
--- a/src/test/run-make/wasm-stringify-ints-small/Makefile
+++ b/src/test/run-make/wasm-stringify-ints-small/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
ifeq ($(TARGET),wasm32-unknown-unknown)
all:
diff --git a/src/test/run-make/wasm-symbols-different-module/Makefile b/src/test/run-make/wasm-symbols-different-module/Makefile
index bb6a5d3c9..9e657222d 100644
--- a/src/test/run-make/wasm-symbols-different-module/Makefile
+++ b/src/test/run-make/wasm-symbols-different-module/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-symbols-not-exported/Makefile b/src/test/run-make/wasm-symbols-not-exported/Makefile
index 62bd0f087..60b0dee00 100644
--- a/src/test/run-make/wasm-symbols-not-exported/Makefile
+++ b/src/test/run-make/wasm-symbols-not-exported/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/wasm-symbols-not-imported/Makefile b/src/test/run-make/wasm-symbols-not-imported/Makefile
index 7a923375c..dc7618c19 100644
--- a/src/test/run-make/wasm-symbols-not-imported/Makefile
+++ b/src/test/run-make/wasm-symbols-not-imported/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
# only-wasm32-bare
diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
index 6a04d3439..84dcd2393 100644
--- a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
+++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
@@ -1,4 +1,4 @@
--include ../../run-make-fulldeps/tools.mk
+include ../../run-make-fulldeps/tools.mk
#only-x86_64-fortanix-unknown-sgx
diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh
index 54645e9e2..944343df6 100644
--- a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh
+++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh
@@ -45,7 +45,7 @@ check cc_plus_one_cxx cc_plus_one_cxx.checks
check cc_plus_one_cxx_asm cc_plus_one_cxx_asm.checks
check cc_plus_one_asm cc_plus_one_asm.checks \
|| echo "warning: the cc crate forwards assembly files to the CC compiler." \
- "Clang uses its own intergrated assembler, which does not include the LVI passes."
+ "Clang uses its own integrated assembler, which does not include the LVI passes."
check cmake_plus_one_c cmake_plus_one_c.checks
check cmake_plus_one_c_asm cmake_plus_one_c_asm.checks
diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
index f29bc50e8..f7ef92df8 100644
--- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
+++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
@@ -28,7 +28,7 @@ fn main() {
{
let e = E::C;
assert_eq!(e as u32, 2);
- assert_eq!(FLAG.load(Ordering::SeqCst), 0);
+ assert_eq!(FLAG.load(Ordering::SeqCst), 1);
}
assert_eq!(FLAG.load(Ordering::SeqCst), 1);
}
diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
index fb2b4d476..dfc094abe 100644
--- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
+++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
@@ -2,8 +2,6 @@
// schedule cleanups when auto borrowing trait objects.
// This program should be valgrind clean.
-#![feature(box_syntax)]
-
static mut DROP_RAN: bool = false;
struct Foo;
@@ -19,7 +17,7 @@ impl Trait for Foo {}
pub fn main() {
{
- let _x: &Trait = &*(box Foo as Box<Trait>);
+ let _x: &Trait = &*(Box::new(Foo) as Box<Trait>);
}
unsafe {
assert!(DROP_RAN);
diff --git a/src/test/run-pass-valgrind/coerce-match.rs b/src/test/run-pass-valgrind/coerce-match.rs
index a4ba5427d..5b78f1ec7 100644
--- a/src/test/run-pass-valgrind/coerce-match.rs
+++ b/src/test/run-pass-valgrind/coerce-match.rs
@@ -2,15 +2,18 @@
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
pub fn main() {
- let _: Box<[isize]> =
- if true { let b: Box<_> = box [1, 2, 3]; b } else { let b: Box<_> = box [1]; b };
+ let _: Box<[isize]> = if true {
+ let b: Box<_> = Box::new([1, 2, 3]);
+ b
+ } else {
+ let b: Box<_> = Box::new([1]);
+ b
+ };
let _: Box<[isize]> = match true {
- true => { let b: Box<_> = box [1, 2, 3]; b }
- false => { let b: Box<_> = box [1]; b }
+ true => { let b: Box<_> = Box::new([1, 2, 3]); b }
+ false => { let b: Box<_> = Box::new([1]); b }
};
// Check we don't get over-keen at propagating coercions in the case of casts.
diff --git a/src/test/rustdoc-gui/anchors.goml b/src/test/rustdoc-gui/anchors.goml
index 84b8bbd1b..3ad62c721 100644
--- a/src/test/rustdoc-gui/anchors.goml
+++ b/src/test/rustdoc-gui/anchors.goml
@@ -1,6 +1,5 @@
// This test is to ensure that the anchors (`§`) have the expected color and position.
-goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
-show-text: true
+goto: file://|DOC_PATH|/staged_api/struct.Foo.html
// This is needed to ensure that the text color is computed.
show-text: true
@@ -13,10 +12,31 @@ reload:
assert-css: ("#toggle-all-docs", {"color": "rgb(0, 0, 0)"})
assert-css: (".fqn .in-band a:nth-of-type(1)", {"color": "rgb(0, 0, 0)"})
assert-css: (".fqn .in-band a:nth-of-type(2)", {"color": "rgb(173, 55, 138)"})
-assert-css: (".srclink", {"color": "rgb(56, 115, 173)"})
+assert-css: (
+ ".rightside .srclink",
+ {"color": "rgb(56, 115, 173)", "text-decoration": "none solid rgb(56, 115, 173)"},
+ ALL,
+)
+compare-elements-css: (".rightside .srclink", ".rightside.srclink", ["color", "text-decoration"])
+compare-elements-css: (".main-heading .srclink", ".rightside.srclink", ["color", "text-decoration"])
move-cursor-to: ".main-heading .srclink"
-assert-css: (".srclink", {"text-decoration": "underline solid rgb(56, 115, 173)"})
+assert-css: (
+ ".main-heading .srclink",
+ {"color": "rgb(56, 115, 173)", "text-decoration": "underline solid rgb(56, 115, 173)"},
+)
+move-cursor-to: ".impl-items .rightside .srclink"
+assert-css: (
+ ".impl-items .rightside .srclink",
+ {"color": "rgb(56, 115, 173)", "text-decoration": "none solid rgb(56, 115, 173)"},
+)
+move-cursor-to: ".impl-items .rightside.srclink"
+assert-css: (
+ ".impl-items .rightside.srclink",
+ {"color": "rgb(56, 115, 173)", "text-decoration": "none solid rgb(56, 115, 173)"},
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
assert-css: ("#top-doc-prose-title", {"color": "rgb(0, 0, 0)"})
@@ -32,3 +52,103 @@ move-cursor-to: "#impl-HeavilyDocumentedStruct"
assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": "rgb(0, 0, 0)"})
assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
+
+//
+// We do the same checks with the dark theme now.
+//
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+goto: file://|DOC_PATH|/staged_api/struct.Foo.html
+
+assert-css: ("#toggle-all-docs", {"color": "rgb(221, 221, 221)"})
+assert-css: (".fqn .in-band a:nth-of-type(1)", {"color": "rgb(221, 221, 221)"})
+assert-css: (".fqn .in-band a:nth-of-type(2)", {"color": "rgb(45, 191, 184)"})
+assert-css: (
+ ".rightside .srclink",
+ {"color": "rgb(210, 153, 29)", "text-decoration": "none solid rgb(210, 153, 29)"},
+ ALL,
+)
+compare-elements-css: (".rightside .srclink", ".rightside.srclink", ["color", "text-decoration"])
+compare-elements-css: (".main-heading .srclink", ".rightside.srclink", ["color", "text-decoration"])
+
+move-cursor-to: ".main-heading .srclink"
+assert-css: (
+ ".main-heading .srclink",
+ {"color": "rgb(210, 153, 29)", "text-decoration": "underline solid rgb(210, 153, 29)"},
+)
+move-cursor-to: ".impl-items .rightside .srclink"
+assert-css: (
+ ".impl-items .rightside .srclink",
+ {"color": "rgb(210, 153, 29)", "text-decoration": "none solid rgb(210, 153, 29)"},
+)
+move-cursor-to: ".impl-items .rightside.srclink"
+assert-css: (
+ ".impl-items .rightside.srclink",
+ {"color": "rgb(210, 153, 29)", "text-decoration": "none solid rgb(210, 153, 29)"},
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+
+assert-css: ("#top-doc-prose-title", {"color": "rgb(221, 221, 221)"})
+
+assert-css: (".sidebar a", {"color": "rgb(253, 191, 53)"})
+assert-css: (".in-band a", {"color": "rgb(221, 221, 221)"})
+
+// We move the cursor over the "Implementations" title so the anchor is displayed.
+move-cursor-to: "h2#implementations"
+assert-css: ("h2#implementations a.anchor", {"color": "rgb(221, 221, 221)"})
+
+// Same thing with the impl block title.
+move-cursor-to: "#impl-HeavilyDocumentedStruct"
+assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": "rgb(221, 221, 221)"})
+
+assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
+
+//
+// We do the same checks with the ayu theme now.
+//
+local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
+goto: file://|DOC_PATH|/staged_api/struct.Foo.html
+
+assert-css: ("#toggle-all-docs", {"color": "rgb(197, 197, 197)"})
+assert-css: (".fqn .in-band a:nth-of-type(1)", {"color": "rgb(255, 255, 255)"})
+assert-css: (".fqn .in-band a:nth-of-type(2)", {"color": "rgb(255, 160, 165)"})
+assert-css: (
+ ".rightside .srclink",
+ {"color": "rgb(57, 175, 215)", "text-decoration": "none solid rgb(57, 175, 215)"},
+ ALL,
+)
+compare-elements-css: (".rightside .srclink", ".rightside.srclink", ["color", "text-decoration"])
+compare-elements-css: (".main-heading .srclink", ".rightside.srclink", ["color", "text-decoration"])
+
+move-cursor-to: ".main-heading .srclink"
+assert-css: (
+ ".main-heading .srclink",
+ {"color": "rgb(57, 175, 215)", "text-decoration": "underline solid rgb(57, 175, 215)"},
+)
+move-cursor-to: ".impl-items .rightside .srclink"
+assert-css: (
+ ".impl-items .rightside .srclink",
+ {"color": "rgb(57, 175, 215)", "text-decoration": "none solid rgb(57, 175, 215)"},
+)
+move-cursor-to: ".impl-items .rightside.srclink"
+assert-css: (
+ ".impl-items .rightside.srclink",
+ {"color": "rgb(57, 175, 215)", "text-decoration": "none solid rgb(57, 175, 215)"},
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+
+assert-css: ("#top-doc-prose-title", {"color": "rgb(255, 255, 255)"})
+
+assert-css: (".sidebar a", {"color": "rgb(83, 177, 219)"})
+assert-css: (".in-band a", {"color": "rgb(255, 255, 255)"})
+
+// We move the cursor over the "Implementations" title so the anchor is displayed.
+move-cursor-to: "h2#implementations"
+assert-css: ("h2#implementations a.anchor", {"color": "rgb(197, 197, 197)"})
+
+// Same thing with the impl block title.
+move-cursor-to: "#impl-HeavilyDocumentedStruct"
+assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": "rgb(197, 197, 197)"})
+
+assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
diff --git a/src/test/rustdoc-gui/check_info_sign_position.goml b/src/test/rustdoc-gui/check_info_sign_position.goml
index 3bed7a0a0..47a78f02f 100644
--- a/src/test/rustdoc-gui/check_info_sign_position.goml
+++ b/src/test/rustdoc-gui/check_info_sign_position.goml
@@ -4,8 +4,8 @@ goto: file://|DOC_PATH|/test_docs/index.html
goto: ./fn.check_list_code_block.html
// If the codeblock is the first element of the docblock, the information tooltip must have
// have some top margin to avoid going over the toggle (the "[+]").
-assert-css: (".docblock > .information > .compile_fail", { "margin-top": "16px" })
+assert-css: (".docblock > .example-wrap.compile_fail .tooltip", { "margin-top": "16px" })
// Checks that the other codeblocks don't have this top margin.
-assert-css: ("ol > li > .information > .compile_fail", { "margin-top": "0px" })
-assert-css: ("ol > li > .information > .ignore", { "margin-top": "0px" })
-assert-css: (".docblock > .information > .ignore", { "margin-top": "0px" })
+assert-css: ("ol > li > .example-wrap.compile_fail .tooltip", { "margin-top": "0px" })
+assert-css: ("ol > li > .example-wrap.ignore .tooltip", { "margin-top": "0px" })
+assert-css: (".docblock > .example-wrap.ignore .tooltip", { "margin-top": "0px" })
diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml
index 200569a28..8d399a9a5 100644
--- a/src/test/rustdoc-gui/code-tags.goml
+++ b/src/test/rustdoc-gui/code-tags.goml
@@ -1,9 +1,9 @@
// This test ensures that items and documentation code blocks are wrapped in <pre><code>
goto: file://|DOC_PATH|/test_docs/fn.foo.html
size: (1080, 600)
-// There should be three doc codeblocks
+// There should be four doc codeblocks.
// Check that their content is inside <pre><code>
-assert-count: (".example-wrap pre > code", 3)
+assert-count: (".example-wrap pre > code", 4)
// Check that function signature is inside <pre><code>
assert: "pre.rust.fn > code"
diff --git a/src/test/rustdoc-gui/codeblock-tooltip.goml b/src/test/rustdoc-gui/codeblock-tooltip.goml
new file mode 100644
index 000000000..21a9e120c
--- /dev/null
+++ b/src/test/rustdoc-gui/codeblock-tooltip.goml
@@ -0,0 +1,96 @@
+// Checking the colors of the codeblocks tooltips.
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+show-text: true
+
+// Dark theme.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+
+// compile_fail block
+assert-css: (".docblock .example-wrap.compile_fail .tooltip", {"color": "rgba(255, 0, 0, 0.5)"})
+assert-css: (".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"})
+
+move-cursor-to: ".docblock .example-wrap.compile_fail"
+
+assert-css: (".docblock .example-wrap.compile_fail .tooltip", {"color": "rgb(255, 0, 0)"})
+assert-css: (".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgb(255, 0, 0)"})
+
+// should_panic block
+assert-css: (".docblock .example-wrap.should_panic .tooltip", {"color": "rgba(255, 0, 0, 0.5)"})
+assert-css: (".docblock .example-wrap.should_panic", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"})
+
+move-cursor-to: ".docblock .example-wrap.should_panic"
+
+assert-css: (".docblock .example-wrap.should_panic .tooltip", {"color": "rgb(255, 0, 0)"})
+assert-css: (".docblock .example-wrap.should_panic", {"border-left": "2px solid rgb(255, 0, 0)"})
+
+// ignore block
+assert-css: (".docblock .example-wrap.ignore .tooltip", {"color": "rgba(255, 142, 0, 0.6)"})
+assert-css: (".docblock .example-wrap.ignore", {"border-left": "2px solid rgba(255, 142, 0, 0.6)"})
+
+move-cursor-to: ".docblock .example-wrap.ignore"
+
+assert-css: (".docblock .example-wrap.ignore .tooltip", {"color": "rgb(255, 142, 0)"})
+assert-css: (".docblock .example-wrap.ignore", {"border-left": "2px solid rgb(255, 142, 0)"})
+
+
+// Light theme.
+local-storage: {"rustdoc-theme": "light"}
+reload:
+
+assert-css: (".docblock .example-wrap.compile_fail .tooltip", {"color": "rgba(255, 0, 0, 0.5)"})
+assert-css: (".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"})
+
+move-cursor-to: ".docblock .example-wrap.compile_fail"
+
+assert-css: (".docblock .example-wrap.compile_fail .tooltip", {"color": "rgb(255, 0, 0)"})
+assert-css: (".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgb(255, 0, 0)"})
+
+// should_panic block
+assert-css: (".docblock .example-wrap.should_panic .tooltip", {"color": "rgba(255, 0, 0, 0.5)"})
+assert-css: (".docblock .example-wrap.should_panic", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"})
+
+move-cursor-to: ".docblock .example-wrap.should_panic"
+
+assert-css: (".docblock .example-wrap.should_panic .tooltip", {"color": "rgb(255, 0, 0)"})
+assert-css: (".docblock .example-wrap.should_panic", {"border-left": "2px solid rgb(255, 0, 0)"})
+
+// ignore block
+assert-css: (".docblock .example-wrap.ignore .tooltip", {"color": "rgba(255, 142, 0, 0.6)"})
+assert-css: (".docblock .example-wrap.ignore", {"border-left": "2px solid rgba(255, 142, 0, 0.6)"})
+
+move-cursor-to: ".docblock .example-wrap.ignore"
+
+assert-css: (".docblock .example-wrap.ignore .tooltip", {"color": "rgb(255, 142, 0)"})
+assert-css: (".docblock .example-wrap.ignore", {"border-left": "2px solid rgb(255, 142, 0)"})
+
+
+// Ayu theme.
+local-storage: {"rustdoc-theme": "ayu"}
+reload:
+
+assert-css: (".docblock .example-wrap.compile_fail .tooltip", {"color": "rgba(255, 0, 0, 0.5)"})
+assert-css: (".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"})
+
+move-cursor-to: ".docblock .example-wrap.compile_fail"
+
+assert-css: (".docblock .example-wrap.compile_fail .tooltip", {"color": "rgb(255, 0, 0)"})
+assert-css: (".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgb(255, 0, 0)"})
+
+// should_panic block
+assert-css: (".docblock .example-wrap.should_panic .tooltip", {"color": "rgba(255, 0, 0, 0.5)"})
+assert-css: (".docblock .example-wrap.should_panic", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"})
+
+move-cursor-to: ".docblock .example-wrap.should_panic"
+
+assert-css: (".docblock .example-wrap.should_panic .tooltip", {"color": "rgb(255, 0, 0)"})
+assert-css: (".docblock .example-wrap.should_panic", {"border-left": "2px solid rgb(255, 0, 0)"})
+
+// ignore block
+assert-css: (".docblock .example-wrap.ignore .tooltip", {"color": "rgba(255, 142, 0, 0.6)"})
+assert-css: (".docblock .example-wrap.ignore", {"border-left": "2px solid rgba(255, 142, 0, 0.6)"})
+
+move-cursor-to: ".docblock .example-wrap.ignore"
+
+assert-css: (".docblock .example-wrap.ignore .tooltip", {"color": "rgb(255, 142, 0)"})
+assert-css: (".docblock .example-wrap.ignore", {"border-left": "2px solid rgb(255, 142, 0)"})
diff --git a/src/test/rustdoc-gui/docblock-table-overflow.goml b/src/test/rustdoc-gui/docblock-table-overflow.goml
index af76d2ea4..7f97cf220 100644
--- a/src/test/rustdoc-gui/docblock-table-overflow.goml
+++ b/src/test/rustdoc-gui/docblock-table-overflow.goml
@@ -6,7 +6,7 @@ size: (1100, 800)
compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["scrollWidth"])
assert-property: (".top-doc .docblock", {"scrollWidth": "801"})
// However, since there is overflow in the <table>, its scroll width is bigger.
-assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
+assert-property: (".top-doc .docblock table", {"scrollWidth": "1572"})
// Checking it works on other doc blocks as well...
@@ -18,4 +18,4 @@ compare-elements-property: (
)
assert-property: ("#implementations-list > details .docblock", {"scrollWidth": "801"})
// However, since there is overflow in the <table>, its scroll width is bigger.
-assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1573"})
+assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1572"})
diff --git a/src/test/rustdoc-gui/docblock-table.goml b/src/test/rustdoc-gui/docblock-table.goml
new file mode 100644
index 000000000..7263156ab
--- /dev/null
+++ b/src/test/rustdoc-gui/docblock-table.goml
@@ -0,0 +1,4 @@
+goto: file://|DOC_PATH|/test_docs/doc_block_table/struct.DocBlockTable.html#method.func
+
+compare-elements-css: (".impl-items .docblock table th", ".top-doc .docblock table th", ["border"])
+compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock table td", ["border"])
diff --git a/src/test/rustdoc-gui/headings.goml b/src/test/rustdoc-gui/headings.goml
index 8c2c3df15..ed07e777b 100644
--- a/src/test/rustdoc-gui/headings.goml
+++ b/src/test/rustdoc-gui/headings.goml
@@ -247,12 +247,12 @@ assert-css: (
local-storage: {"rustdoc-theme": "light"}
goto: file://|DOC_PATH|/staged_api/struct.Foo.html
-assert-css: (".since", {"color": "rgb(128, 128, 128)"})
+assert-css: (".since", {"color": "rgb(128, 128, 128)"}, ALL)
local-storage: {"rustdoc-theme": "dark"}
reload:
-assert-css: (".since", {"color": "rgb(128, 128, 128)"})
+assert-css: (".since", {"color": "rgb(128, 128, 128)"}, ALL)
local-storage: {"rustdoc-theme": "ayu"}
reload:
-assert-css: (".since", {"color": "rgb(128, 128, 128)"})
+assert-css: (".since", {"color": "rgb(128, 128, 128)"}, ALL)
diff --git a/src/test/rustdoc-gui/item-info-alignment.goml b/src/test/rustdoc-gui/item-info-alignment.goml
new file mode 100644
index 000000000..4d7b5045f
--- /dev/null
+++ b/src/test/rustdoc-gui/item-info-alignment.goml
@@ -0,0 +1,10 @@
+// This test ensures that the "item-info" looks about the same
+// whether or not it's inside a toggle.
+goto: file://|DOC_PATH|/lib2/struct.ItemInfoAlignmentTest.html
+
+// First, we try it in "desktop" mode.
+size: (1200, 870)
+compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ("x"))
+// Next, we try it in "mobile" mode (max-width: 700px).
+size: (650, 650)
+compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ("x"))
diff --git a/src/test/rustdoc-gui/item-summary-table.goml b/src/test/rustdoc-gui/item-summary-table.goml
index 6bf4e288c..4bff32b3d 100644
--- a/src/test/rustdoc-gui/item-summary-table.goml
+++ b/src/test/rustdoc-gui/item-summary-table.goml
@@ -3,4 +3,4 @@ goto: file://|DOC_PATH|/lib2/summary_table/index.html
// We check that we picked the right item first.
assert-text: (".item-table .item-left", "Foo")
// Then we check that its summary is empty.
-assert-text: (".item-table .item-right", "")
+assert-false: ".item-table .item-right"
diff --git a/src/test/rustdoc-gui/label-next-to-symbol.goml b/src/test/rustdoc-gui/label-next-to-symbol.goml
index ca3994a08..4b4cea262 100644
--- a/src/test/rustdoc-gui/label-next-to-symbol.goml
+++ b/src/test/rustdoc-gui/label-next-to-symbol.goml
@@ -7,14 +7,14 @@ size: (1080, 600)
assert: (".stab.deprecated")
assert: (".stab.portability")
-// make sure that deprecated and portability are different colours
+// make sure that deprecated and portability have the right colors
assert-css: (
".item-table .item-left .stab.deprecated",
- { "background-color": "rgb(255, 196, 196)" },
+ { "background-color": "rgb(255, 245, 214)" },
)
assert-css: (
".item-table .item-left .stab.portability",
- { "background-color": "rgb(243, 223, 255)" },
+ { "background-color": "rgb(255, 245, 214)" },
)
// table like view
@@ -31,15 +31,9 @@ compare-elements-position: (
)
// Ensure no wrap
-compare-elements-position-near: (
- "//*[@class='item-left module-item']//a[text()='replaced_function']",
- "//*[@class='item-right docblock-short']//p[text()='a thing with a label']",
- {"y": 2},
-)
-// compare parent elements
compare-elements-position: (
"//*[@class='item-left module-item']//a[text()='replaced_function']/..",
- "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..",
+ "//*[@class='item-right docblock-short'][text()='a thing with a label']",
("y"),
)
@@ -51,7 +45,7 @@ assert-css: (".item-right.docblock-short", { "padding-left": "32px" })
compare-elements-position-near: (
"//*[@class='item-left module-item']//a[text()='replaced_function']",
".item-left .stab.deprecated",
- {"y": 1},
+ {"y": 2},
)
compare-elements-position: (
".item-left .stab.deprecated",
@@ -60,19 +54,13 @@ compare-elements-position: (
)
// Ensure wrap
-compare-elements-position-near-false: (
- "//*[@class='item-left module-item']//a[text()='replaced_function']",
- "//*[@class='item-right docblock-short']//p[text()='a thing with a label']",
- {"y": 12},
-)
-// compare parent elements
compare-elements-position-false: (
"//*[@class='item-left module-item']//a[text()='replaced_function']/..",
- "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..",
+ "//*[@class='item-right docblock-short'][text()='a thing with a label']",
("y"),
)
compare-elements-position-false: (
".item-left .stab.deprecated",
- "//*[@class='item-right docblock-short']//p[text()='a thing with a label']",
+ "//*[@class='item-right docblock-short'][text()='a thing with a label']",
("y"),
)
diff --git a/src/test/rustdoc-gui/links-color.goml b/src/test/rustdoc-gui/links-color.goml
new file mode 100644
index 000000000..69c5b4a67
--- /dev/null
+++ b/src/test/rustdoc-gui/links-color.goml
@@ -0,0 +1,85 @@
+// This test checks links colors.
+goto: file://|DOC_PATH|/test_docs/index.html
+
+// This is needed so that the text color is computed.
+show-text: true
+
+// Ayu theme
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (".item-table .mod", {"color": "rgb(57, 175, 215)"}, ALL)
+assert-css: (".item-table .macro", {"color": "rgb(163, 122, 204)"}, ALL)
+assert-css: (".item-table .struct", {"color": "rgb(255, 160, 165)"}, ALL)
+assert-css: (".item-table .enum", {"color": "rgb(255, 160, 165)"}, ALL)
+assert-css: (".item-table .trait", {"color": "rgb(57, 175, 215)"}, ALL)
+assert-css: (".item-table .fn", {"color": "rgb(253, 214, 135)"}, ALL)
+assert-css: (".item-table .type", {"color": "rgb(255, 160, 165)"}, ALL)
+assert-css: (".item-table .union", {"color": "rgb(255, 160, 165)"}, ALL)
+assert-css: (".item-table .keyword", {"color": "rgb(57, 175, 215)"}, ALL)
+
+assert-css: (
+ ".sidebar-elems a:not(.current)",
+ {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"},
+ ALL,
+)
+assert-css: (
+ ".sidebar-elems a.current",
+ {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)", "font-weight": "500"},
+ ALL,
+)
+
+
+// Dark theme
+local-storage: {"rustdoc-theme": "dark"}
+reload:
+
+assert-css: (".item-table .mod", {"color": "rgb(210, 153, 29)"}, ALL)
+assert-css: (".item-table .macro", {"color": "rgb(9, 189, 0)"}, ALL)
+assert-css: (".item-table .struct", {"color": "rgb(45, 191, 184)"}, ALL)
+assert-css: (".item-table .enum", {"color": "rgb(45, 191, 184)"}, ALL)
+assert-css: (".item-table .trait", {"color": "rgb(183, 140, 242)"}, ALL)
+assert-css: (".item-table .fn", {"color": "rgb(43, 171, 99)"}, ALL)
+assert-css: (".item-table .type", {"color": "rgb(45, 191, 184)"}, ALL)
+assert-css: (".item-table .union", {"color": "rgb(45, 191, 184)"}, ALL)
+assert-css: (".item-table .keyword", {"color": "rgb(210, 153, 29)"}, ALL)
+
+assert-css: (
+ ".sidebar-elems a:not(.current)",
+ {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"},
+ ALL,
+)
+assert-css: (
+ ".sidebar-elems a.current",
+ {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)", "font-weight": "500"},
+ ALL,
+)
+
+
+// Light theme
+local-storage: {"rustdoc-theme": "light"}
+reload:
+
+assert-css: (".item-table .mod", {"color": "rgb(56, 115, 173)"}, ALL)
+assert-css: (".item-table .macro", {"color": "rgb(6, 128, 0)"}, ALL)
+assert-css: (".item-table .struct", {"color": "rgb(173, 55, 138)"}, ALL)
+assert-css: (".item-table .enum", {"color": "rgb(173, 55, 138)"}, ALL)
+assert-css: (".item-table .trait", {"color": "rgb(110, 79, 201)"}, ALL)
+assert-css: (".item-table .fn", {"color": "rgb(173, 124, 55)"}, ALL)
+assert-css: (".item-table .type", {"color": "rgb(173, 55, 138)"}, ALL)
+assert-css: (".item-table .union", {"color": "rgb(173, 55, 138)"}, ALL)
+assert-css: (".item-table .keyword", {"color": "rgb(56, 115, 173)"}, ALL)
+
+assert-css: (
+ ".sidebar-elems a:not(.current)",
+ {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"},
+ ALL,
+)
+assert-css: (
+ ".sidebar-elems a.current",
+ {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)", "font-weight": "500"},
+ ALL,
+)
diff --git a/src/test/rustdoc-gui/overflow-tooltip-information.goml b/src/test/rustdoc-gui/overflow-tooltip-information.goml
index 7ef85a4c4..f481f82c2 100644
--- a/src/test/rustdoc-gui/overflow-tooltip-information.goml
+++ b/src/test/rustdoc-gui/overflow-tooltip-information.goml
@@ -2,7 +2,7 @@
// have overflow and max-width CSS rules set because they create a bug in firefox on
// mac. For more information: https://github.com/rust-lang/rust/issues/89185
goto: file://|DOC_PATH|/test_docs/fn.foo.html
-assert-css: (".docblock > .information", {
+assert-css: (".docblock > .example-wrap .tooltip", {
"overflow-x": "visible",
"max-width": "none"
}, ALL)
diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml
index 54f3790a7..71d514648 100644
--- a/src/test/rustdoc-gui/pocket-menu.goml
+++ b/src/test/rustdoc-gui/pocket-menu.goml
@@ -56,7 +56,7 @@ reload:
click: "#help-button"
assert-css: (
"#help-button .popover",
- {"display": "block", "border-color": "rgb(210, 210, 210)"},
+ {"display": "block", "border-color": "rgb(224, 224, 224)"},
)
compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
@@ -71,7 +71,7 @@ reload:
click: "#help-button"
assert-css: (
"#help-button .popover",
- {"display": "block", "border-color": "rgb(221, 221, 221)"},
+ {"display": "block", "border-color": "rgb(224, 224, 224)"},
)
compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml
index d645e2370..35d7ca480 100644
--- a/src/test/rustdoc-gui/search-filter.goml
+++ b/src/test/rustdoc-gui/search-filter.goml
@@ -40,7 +40,7 @@ press-key: "ArrowUp"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#titles"
-assert-property: ("#crate-search", {"value": "All crates"})
+assert-property: ("#crate-search", {"value": "all crates"})
// Checking that the URL parameter is taken into account for crate filtering.
goto: file://|DOC_PATH|/test_docs/index.html?search=test&filter-crate=lib2
@@ -48,8 +48,8 @@ wait-for: "#crate-search"
assert-property: ("#crate-search", {"value": "lib2"})
assert-false: "#results .externcrate"
-// Checking that the text for the "title" is correct (the "All" comes from the "<select>").
-assert-text: ("#search-settings", "Results for test in All", STARTS_WITH)
+// Checking that the text for the "title" is correct (the "all crates" comes from the "<select>").
+assert-text: (".search-results-title", "Results in all crates", STARTS_WITH)
// Checking the display of the crate filter.
// We start with the light theme.
@@ -69,15 +69,15 @@ click: "#settings-menu"
wait-for: "#settings"
click: "#theme-dark"
wait-for-css: ("#crate-search", {
- "border": "1px solid rgb(240, 240, 240)",
- "color": "rgb(17, 17, 17)",
- "background-color": "rgb(240, 240, 240)",
+ "border": "1px solid rgb(224, 224, 224)",
+ "color": "rgb(221, 221, 221)",
+ "background-color": "rgb(53, 53, 53)",
})
// And finally we check the ayu theme.
click: "#theme-ayu"
wait-for-css: ("#crate-search", {
- "border": "1px solid rgb(66, 76, 87)",
- "color": "rgb(197, 197, 197)",
- "background-color": "rgb(20, 25, 32)",
+ "border": "1px solid rgb(92, 103, 115)",
+ "color": "rgb(255, 255, 255)",
+ "background-color": "rgb(15, 20, 25)",
})
diff --git a/src/test/rustdoc-gui/search-form-elements.goml b/src/test/rustdoc-gui/search-form-elements.goml
new file mode 100644
index 000000000..1c64974e9
--- /dev/null
+++ b/src/test/rustdoc-gui/search-form-elements.goml
@@ -0,0 +1,243 @@
+// This test ensures that the elements in ".search-form" have the expected display.
+goto: file://|DOC_PATH|/test_docs/index.html
+show-text: true
+
+// Ayu theme
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".search-input",
+ {
+ "border-color": "rgb(92, 103, 115)",
+ "background-color": "rgb(20, 25, 32)",
+ "color": "rgb(255, 255, 255)",
+ },
+)
+focus: ".search-input"
+// Nothing should change.
+assert-css: (
+ ".search-input",
+ {
+ "border-color": "rgb(92, 103, 115)",
+ "background-color": "rgb(20, 25, 32)",
+ "color": "rgb(255, 255, 255)",
+ },
+)
+
+assert-css: (
+ "#help-button",
+ {"border-color": "rgb(197, 197, 197)"},
+)
+assert-css: (
+ "#help-button > button",
+ {
+ "color": "rgb(255, 255, 255)",
+ "border-color": "rgb(92, 103, 115)",
+ "background-color": "rgb(20, 25, 32)",
+ },
+)
+move-cursor-to: "#help-button"
+assert-css: (
+ "#help-button:hover",
+ {"border-color": "rgb(197, 197, 197)"},
+)
+// Only "border-color" should change.
+assert-css: (
+ "#help-button:hover > button",
+ {
+ "color": "rgb(255, 255, 255)",
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(20, 25, 32)",
+ },
+)
+
+assert-css: (
+ "#settings-menu",
+ {"border-color": "rgb(197, 197, 197)"},
+)
+assert-css: (
+ "#settings-menu > a",
+ {
+ "color": "rgb(255, 255, 255)",
+ "border-color": "rgb(92, 103, 115)",
+ "background-color": "rgb(20, 25, 32)",
+ },
+)
+move-cursor-to: "#settings-menu"
+assert-css: (
+ "#settings-menu:hover",
+ {"border-color": "rgb(197, 197, 197)"},
+)
+// Only "border-color" should change.
+assert-css: (
+ "#settings-menu:hover > a",
+ {
+ "color": "rgb(255, 255, 255)",
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(20, 25, 32)",
+ },
+)
+
+// Dark theme
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".search-input",
+ {
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(240, 240, 240)",
+ "color": "rgb(17, 17, 17)",
+ },
+)
+focus: ".search-input"
+// Only "border-color" should change.
+assert-css: (
+ ".search-input",
+ {
+ "border-color": "rgb(0, 141, 253)",
+ "background-color": "rgb(240, 240, 240)",
+ "color": "rgb(17, 17, 17)",
+ },
+)
+
+assert-css: (
+ "#help-button",
+ {"border-color": "rgb(221, 221, 221)"},
+)
+assert-css: (
+ "#help-button > button",
+ {
+ "color": "rgb(0, 0, 0)",
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(240, 240, 240)",
+ },
+)
+move-cursor-to: "#help-button"
+assert-css: (
+ "#help-button:hover",
+ {"border-color": "rgb(221, 221, 221)"},
+)
+// Only "border-color" should change.
+assert-css: (
+ "#help-button:hover > button",
+ {
+ "color": "rgb(0, 0, 0)",
+ "border-color": "rgb(255, 185, 0)",
+ "background-color": "rgb(240, 240, 240)",
+ },
+)
+
+assert-css: (
+ "#settings-menu",
+ {"border-color": "rgb(221, 221, 221)"},
+)
+assert-css: (
+ "#settings-menu > a",
+ {
+ "color": "rgb(0, 0, 0)",
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(240, 240, 240)",
+ },
+)
+move-cursor-to: "#settings-menu"
+assert-css: (
+ "#settings-menu:hover",
+ {"border-color": "rgb(221, 221, 221)"},
+)
+// Only "border-color" should change.
+assert-css: (
+ "#settings-menu:hover > a",
+ {
+ "color": "rgb(0, 0, 0)",
+ "border-color": "rgb(255, 185, 0)",
+ "background-color": "rgb(240, 240, 240)",
+ },
+)
+
+// Light theme
+local-storage: {
+ "rustdoc-theme": "light",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".search-input",
+ {
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(255, 255, 255)",
+ "color": "rgb(0, 0, 0)",
+ },
+)
+focus: ".search-input"
+// Nothing should change.
+assert-css: (
+ ".search-input",
+ {
+ "border-color": "rgb(102, 175, 233)",
+ "background-color": "rgb(255, 255, 255)",
+ "color": "rgb(0, 0, 0)",
+ },
+)
+
+assert-css: (
+ "#help-button",
+ {"border-color": "rgb(0, 0, 0)"},
+)
+assert-css: (
+ "#help-button > button",
+ {
+ "color": "rgb(0, 0, 0)",
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(255, 255, 255)",
+ },
+)
+move-cursor-to: "#help-button"
+assert-css: (
+ "#help-button:hover",
+ {"border-color": "rgb(0, 0, 0)"},
+)
+// Only "border-color" should change.
+assert-css: (
+ "#help-button:hover > button",
+ {
+ "color": "rgb(0, 0, 0)",
+ "border-color": "rgb(113, 113, 113)",
+ "background-color": "rgb(255, 255, 255)",
+ },
+)
+
+assert-css: (
+ "#settings-menu",
+ {"border-color": "rgb(0, 0, 0)"},
+)
+assert-css: (
+ "#settings-menu > a",
+ {
+ "color": "rgb(56, 115, 173)",
+ "border-color": "rgb(224, 224, 224)",
+ "background-color": "rgb(255, 255, 255)",
+ },
+)
+move-cursor-to: "#settings-menu"
+assert-css: (
+ "#settings-menu:hover",
+ {"border-color": "rgb(0, 0, 0)"},
+)
+// Only "border-color" should change.
+assert-css: (
+ "#settings-menu:hover > a",
+ {
+ "color": "rgb(56, 115, 173)",
+ "border-color": "rgb(113, 113, 113)",
+ "background-color": "rgb(255, 255, 255)",
+ },
+)
diff --git a/src/test/rustdoc-gui/search-input.goml b/src/test/rustdoc-gui/search-input.goml
deleted file mode 100644
index 44123b702..000000000
--- a/src/test/rustdoc-gui/search-input.goml
+++ /dev/null
@@ -1,23 +0,0 @@
-// Ensures that the search input border color changes on focus.
-goto: file://|DOC_PATH|/test_docs/index.html
-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
-reload:
-
-assert-css: (".search-input", {"border-color": "rgb(224, 224, 224)"})
-click: ".search-input"
-focus: ".search-input"
-assert-css: (".search-input", {"border-color": "rgb(0, 141, 253)"})
-
-local-storage: {"rustdoc-theme": "light"}
-reload:
-
-assert-css: (".search-input", {"border-color": "rgb(224, 224, 224)"})
-click: ".search-input"
-assert-css: (".search-input", {"border-color": "rgb(102, 175, 233)"})
-
-local-storage: {"rustdoc-theme": "ayu"}
-reload:
-
-assert-css: (".search-input", {"border-color": "rgb(66, 76, 87)"})
-click: ".search-input"
-assert-css: (".search-input", {"border-color": "rgb(66, 76, 87)"})
diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml
index 9a49ae2c6..c4b5fdf53 100644
--- a/src/test/rustdoc-gui/search-result-color.goml
+++ b/src/test/rustdoc-gui/search-result-color.goml
@@ -7,7 +7,6 @@ show-text: true
// Ayu theme
local-storage: {
"rustdoc-theme": "ayu",
- "rustdoc-preferred-dark-theme": "ayu",
"rustdoc-use-system-theme": "false",
}
reload:
@@ -23,16 +22,82 @@ assert-css: (
{"color": "rgb(0, 150, 207)"},
)
-// Checking the color for "keyword".
+// Checking the color of "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
{"color": "rgb(120, 135, 151)"},
)
+// Checking the color of "keyword".
+assert-css: (
+ ".result-name .keyword",
+ {"color": "rgb(57, 175, 215)"},
+ ALL,
+)
+// Check the color of "struct".
+assert-css: (
+ ".result-name .struct",
+ {"color": "rgb(255, 160, 165)"},
+ ALL,
+)
+// Check the color of "associated type".
+assert-css: (
+ ".result-name .associatedtype",
+ {"color": "rgb(57, 175, 215)"},
+ ALL,
+)
+// Check the color of "type method".
+assert-css: (
+ ".result-name .tymethod",
+ {"color": "rgb(253, 214, 135)"},
+ ALL,
+)
+// Check the color of "method".
+assert-css: (
+ ".result-name .method",
+ {"color": "rgb(253, 214, 135)"},
+ ALL,
+)
+// Check the color of "struct field".
+assert-css: (
+ ".result-name .structfield",
+ {"color": "rgb(0, 150, 207)"},
+ ALL,
+)
+// Check the color of "macro".
+assert-css: (
+ ".result-name .macro",
+ {"color": "rgb(163, 122, 204)"},
+ ALL,
+)
+// Check the color of "fn".
+assert-css: (
+ ".result-name .fn",
+ {"color": "rgb(253, 214, 135)"},
+ ALL,
+)
+
+// Checking the `<a>` container.
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+ {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+ ALL,
+)
+
+// Checking color and background on hover.
+move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']",
+ {"color": "rgb(255, 255, 255)"},
+)
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+ {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+
// Dark theme
local-storage: {
"rustdoc-theme": "dark",
- "rustdoc-preferred-dark-theme": "dark",
"rustdoc-use-system-theme": "false",
}
reload:
@@ -54,6 +119,72 @@ assert-css: (
{"color": "rgb(221, 221, 221)"},
)
+// Checking the color of "keyword".
+assert-css: (
+ ".result-name .keyword",
+ {"color": "rgb(210, 153, 29)"},
+ ALL,
+)
+// Check the color of "struct".
+assert-css: (
+ ".result-name .struct",
+ {"color": "rgb(45, 191, 184)"},
+ ALL,
+)
+// Check the color of "associated type".
+assert-css: (
+ ".result-name .associatedtype",
+ {"color": "rgb(210, 153, 29)"},
+ ALL,
+)
+// Check the color of "type method".
+assert-css: (
+ ".result-name .tymethod",
+ {"color": "rgb(43, 171, 99)"},
+ ALL,
+)
+// Check the color of "method".
+assert-css: (
+ ".result-name .method",
+ {"color": "rgb(43, 171, 99)"},
+ ALL,
+)
+// Check the color of "struct field".
+assert-css: (
+ ".result-name .structfield",
+ {"color": "rgb(221, 221, 221)"},
+ ALL,
+)
+// Check the color of "macro".
+assert-css: (
+ ".result-name .macro",
+ {"color": "rgb(9, 189, 0)"},
+ ALL,
+)
+// Check the color of "fn".
+assert-css: (
+ ".result-name .fn",
+ {"color": "rgb(43, 171, 99)"},
+ ALL,
+)
+
+// Checking the `<a>` container.
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+
+// Checking color and background on hover.
+move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']",
+ {"color": "rgb(221, 221, 221)"},
+)
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(119, 119, 119)"},
+)
+
// Light theme
local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
reload:
@@ -75,13 +206,78 @@ assert-css: (
{"color": "rgb(0, 0, 0)"},
)
+// Checking the color of "keyword".
+assert-css: (
+ ".result-name .keyword",
+ {"color": "rgb(56, 115, 173)"},
+ ALL,
+)
+// Check the color of "struct".
+assert-css: (
+ ".result-name .struct",
+ {"color": "rgb(173, 55, 138)"},
+ ALL,
+)
+// Check the color of "associated type".
+assert-css: (
+ ".result-name .associatedtype",
+ {"color": "rgb(56, 115, 173)"},
+ ALL,
+)
+// Check the color of "type method".
+assert-css: (
+ ".result-name .tymethod",
+ {"color": "rgb(173, 124, 55)"},
+ ALL,
+)
+// Check the color of "method".
+assert-css: (
+ ".result-name .method",
+ {"color": "rgb(173, 124, 55)"},
+ ALL,
+)
+// Check the color of "struct field".
+assert-css: (
+ ".result-name .structfield",
+ {"color": "rgb(0, 0, 0)"},
+ ALL,
+)
+// Check the color of "macro".
+assert-css: (
+ ".result-name .macro",
+ {"color": "rgb(6, 128, 0)"},
+ ALL,
+)
+// Check the color of "fn".
+assert-css: (
+ ".result-name .fn",
+ {"color": "rgb(173, 124, 55)"},
+ ALL,
+)
+
+// Checking the `<a>` container.
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+
+// Checking color and background on hover.
+move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']",
+ {"color": "rgb(0, 0, 0)"},
+)
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(221, 221, 221)"},
+)
+
// Check the alias more specifically in the dark theme.
goto: file://|DOC_PATH|/test_docs/index.html
// We set the theme so we're sure that the correct values will be used, whatever the computer
// this test is running on.
local-storage: {
"rustdoc-theme": "dark",
- "rustdoc-preferred-dark-theme": "dark",
"rustdoc-use-system-theme": "false",
}
// If the text isn't displayed, the browser doesn't compute color style correctly...
diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml
index 8464ba7c2..efbbfb925 100644
--- a/src/test/rustdoc-gui/search-result-display.goml
+++ b/src/test/rustdoc-gui/search-result-display.goml
@@ -4,26 +4,25 @@ size: (900, 1000)
write: (".search-input", "test")
// To be SURE that the search will be run.
press-key: 'Enter'
-wait-for: "#search-settings"
+wait-for: "#crate-search"
// The width is returned by "getComputedStyle" which returns the exact number instead of the
// CSS rule which is "50%"...
-assert-css: (".search-results div.desc", {"width": "295px"})
+assert-css: (".search-results div.desc", {"width": "293px"})
size: (600, 100)
// As counter-intuitive as it may seem, in this width, the width is "100%", which is why
// when computed it's larger.
-assert-css: (".search-results div.desc", {"width": "570px"})
+assert-css: (".search-results div.desc", {"width": "566px"})
+
+// The result set is all on one line.
+assert-css: (".search-results .result-name > span", {"display": "inline"})
// Check that the crate filter `<select>` is correctly handled when it goes to next line.
// To do so we need to update the length of one of its `<option>`.
size: (900, 900)
-// First we check the current width and position.
-assert-css: ("#crate-search", {"width": "218px"})
-compare-elements-position-near: (
- "#crate-search",
- "#search-settings .search-results-title",
- {"y": 5},
-)
+// First we check the current width, height and position.
+assert-css: ("#crate-search", {"width": "223px"})
+assert-css: (".search-results-title", {"height": "44px", "width": "336px"})
// Then we update the text of one of the `<option>`.
text: (
@@ -31,12 +30,8 @@ text: (
"sdjfaksdjfaksjdbfkadsbfkjsadbfkdsbkfbsadkjfbkdsabfkadsfkjdsafa",
)
-// Then we compare again.
-assert-css: ("#crate-search", {"width": "640px"})
-compare-elements-position-near-false: (
- "#crate-search",
- "#search-settings .search-results-title",
- {"y": 5},
-)
-// And we check that the `<select>` isn't bigger than its container.
+// Then we compare again to confirm the height didn't change.
+assert-css: ("#crate-search", {"width": "527px"})
+assert-css: (".search-results-title", {"height": "44px", "width": "640px"})
+// And we check that the `<select>` isn't bigger than its container (".search-results-title").
assert-css: ("#search", {"width": "640px"})
diff --git a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml
new file mode 100644
index 000000000..dc50185f0
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml
@@ -0,0 +1,31 @@
+// This test ensures that the mobile sidebar preserves scroll position.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+// Switching to "mobile view" by reducing the width to 600px.
+size: (600, 600)
+assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+
+// Scroll down.
+scroll-to: "//h2[@id='blanket-implementations']"
+assert-window-property: {"pageYOffset": "643"}
+
+// Open the sidebar menu.
+click: ".sidebar-menu-toggle"
+wait-for-css: (".sidebar", {"left": "0px"})
+
+// We are no longer "scrolled". It's important that the user can't
+// scroll the body at all, but these test scripts are run only in Chrome,
+// and we need to use a more complicated solution to this problem because
+// of Mobile Safari...
+assert-window-property: {"pageYOffset": "0"}
+
+// Close the sidebar menu. Make sure the scroll position gets restored.
+click: ".sidebar-menu-toggle"
+wait-for-css: (".sidebar", {"left": "-1000px"})
+assert-window-property: {"pageYOffset": "643"}
+
+// Now test that scrollability returns when the browser window is just resized.
+click: ".sidebar-menu-toggle"
+wait-for-css: (".sidebar", {"left": "0px"})
+assert-window-property: {"pageYOffset": "0"}
+size: (900, 600)
+assert-window-property: {"pageYOffset": "643"}
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
index fa322574f..4321efcdb 100644
--- a/src/test/rustdoc-gui/sidebar-source-code-display.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -224,14 +224,25 @@ click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// We scroll to line 117 to change the scroll position.
scroll-to: '//*[@id="117"]'
-assert-window-property: {"pageYOffset": "2519"}
+assert-window-property: {"pageYOffset": "2542"}
// Expanding the sidebar...
click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "500px"})
click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// The "scrollTop" property should be the same.
-assert-window-property: {"pageYOffset": "2519"}
+assert-window-property: {"pageYOffset": "2542"}
+
+// We now check that the scroll position is restored if the window is resized.
+size: (500, 700)
+click: "#sidebar-toggle"
+wait-for-css: ("#source-sidebar", {"visibility": "visible"})
+assert-window-property: {"pageYOffset": "0"}
+size: (900, 900)
+assert-window-property: {"pageYOffset": "2542"}
+size: (500, 700)
+click: "#sidebar-toggle"
+wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
// We now check that opening the sidebar and clicking a link will close it.
// The behavior here on mobile is different than the behavior on desktop,
diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
index 87f91be3a..24aecc70d 100644
--- a/src/test/rustdoc-gui/src/lib2/lib.rs
+++ b/src/test/rustdoc-gui/src/lib2/lib.rs
@@ -38,11 +38,14 @@ pub trait Trait {
#[deprecated = "Whatever [`Foo`](#tadam)"]
fn foo() {}
+ fn fooo();
}
impl Trait for Foo {
type X = u32;
const Y: u32 = 0;
+
+ fn fooo() {}
}
impl implementors::Whatever for Foo {
@@ -143,3 +146,40 @@ pub struct LongItemInfo2;
/// Some docs.
#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
impl SimpleTrait for LongItemInfo2 {}
+
+pub struct WhereWhitespace<T>;
+
+impl<T> WhereWhitespace<T> {
+ pub fn new<F>(f: F) -> Self
+ where
+ F: FnMut() -> i32,
+ {}
+}
+
+impl<K, T> Whitespace<&K> for WhereWhitespace<T>
+where
+ K: std::fmt::Debug,
+{
+ type Output = WhereWhitespace<T>;
+ fn index(&self, _key: &K) -> &Self::Output {
+ self
+ }
+}
+
+pub trait Whitespace<Idx>
+where
+ Idx: ?Sized,
+{
+ type Output;
+ fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub struct ItemInfoAlignmentTest;
+
+impl ItemInfoAlignmentTest {
+ /// This method has docs
+ #[deprecated]
+ pub fn foo() {}
+ #[deprecated]
+ pub fn bar() {}
+}
diff --git a/src/test/rustdoc-gui/src/staged_api/Cargo.toml b/src/test/rustdoc-gui/src/staged_api/Cargo.toml
index 117c4134e..b231be6ee 100644
--- a/src/test/rustdoc-gui/src/staged_api/Cargo.toml
+++ b/src/test/rustdoc-gui/src/staged_api/Cargo.toml
@@ -7,5 +7,6 @@ edition = "2021"
path = "lib.rs"
[features]
-default = ["some_feature"]
+default = ["some_feature", "some_other_feature"]
some_feature = []
+some_other_feature = []
diff --git a/src/test/rustdoc-gui/src/staged_api/lib.rs b/src/test/rustdoc-gui/src/staged_api/lib.rs
index 0cb460f03..5934593a8 100644
--- a/src/test/rustdoc-gui/src/staged_api/lib.rs
+++ b/src/test/rustdoc-gui/src/staged_api/lib.rs
@@ -7,4 +7,6 @@ pub struct Foo {}
impl Foo {
#[stable(feature = "some_feature", since = "1.3.5")]
pub fn bar() {}
+ #[stable(feature = "some_other_feature", since = "1.3.6")]
+ pub fn yo() {}
}
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index 1b26aaecb..4eedf7f15 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -28,6 +28,12 @@ use std::fmt;
/// Let's say I'm just some text will ya?
/// ```
///
+/// A failing to run one:
+///
+/// ```should_panic
+/// panic!("tadam");
+/// ```
+///
/// An inlined `code`!
pub fn foo() {}
@@ -293,3 +299,29 @@ pub mod details {
/// </details>
pub struct Details;
}
+
+pub mod doc_block_table {
+
+ pub trait DocBlockTableTrait {
+ fn func();
+ }
+
+ /// Struct doc.
+ ///
+ /// | header1 | header2 |
+ /// |--------------------------|--------------------------|
+ /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum |
+ pub struct DocBlockTable {}
+
+ impl DocBlockTableTrait for DocBlockTable {
+ /// Trait impl func doc for struct.
+ ///
+ /// | header1 | header2 |
+ /// |--------------------------|--------------------------|
+ /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum |
+ fn func() {
+ println!();
+ }
+ }
+
+}
diff --git a/src/test/rustdoc-gui/toggle-click-deadspace.goml b/src/test/rustdoc-gui/toggle-click-deadspace.goml
index 4a328c9f9..8c3a0bf5b 100644
--- a/src/test/rustdoc-gui/toggle-click-deadspace.goml
+++ b/src/test/rustdoc-gui/toggle-click-deadspace.goml
@@ -4,7 +4,10 @@ goto: file://|DOC_PATH|/lib2/struct.Foo.html
assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""})
click: "h4.code-header" // This is the position of "pub" in "pub fn a_method"
assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""})
-click: ".impl-items .rustdoc-toggle summary::before" // This is the position of "[-]" next to that pub fn.
+click-with-offset: (
+ ".impl-items .rustdoc-toggle summary",
+ {"x": -24, "y": 8}, // This is the position of "[-]" next to that pub fn.
+)
assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""})
// Click the "Trait" part of "impl Trait" and verify it navigates.
diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml
index 22212a317..9a46908f9 100644
--- a/src/test/rustdoc-gui/type-declation-overflow.goml
+++ b/src/test/rustdoc-gui/type-declation-overflow.goml
@@ -32,6 +32,6 @@ assert-property: (".item-decl pre", {"scrollWidth": "950"})
size: (600, 600)
goto: file://|DOC_PATH|/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html
// It shouldn't have an overflow in the topbar either.
-assert-property: (".mobile-topbar .location", {"scrollWidth": "492"})
-assert-property: (".mobile-topbar .location", {"clientWidth": "492"})
+assert-property: (".mobile-topbar .location", {"scrollWidth": "500"})
+assert-property: (".mobile-topbar .location", {"clientWidth": "500"})
assert-css: (".mobile-topbar .location", {"overflow-x": "hidden"})
diff --git a/src/test/rustdoc-gui/where-whitespace.goml b/src/test/rustdoc-gui/where-whitespace.goml
new file mode 100644
index 000000000..1a3ff1f49
--- /dev/null
+++ b/src/test/rustdoc-gui/where-whitespace.goml
@@ -0,0 +1,27 @@
+// This test ensures that the where conditions are correctly displayed.
+goto: file://|DOC_PATH|/lib2/trait.Whitespace.html
+show-text: true
+// First, we check in the trait definition if the where clause is "on its own" (not on the same
+// line than "pub trait Whitespace<Idx>").
+compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y"))
+// And that the code following it isn't on the same line either.
+compare-elements-position-false: (".item-decl .fnname", ".where.fmt-newline", ("y"))
+
+goto: file://|DOC_PATH|/lib2/struct.WhereWhitespace.html
+// We make the screen a bit wider to ensure that the trait impl is on one line.
+size: (915, 915)
+
+compare-elements-position-false: ("#method\.new .fnname", "#method\.new .where.fmt-newline", ("y"))
+// We ensure that both the trait name and the struct name are on the same line in
+// "impl<K, T> Whitespace<&K> for WhereWhitespace<T>".
+compare-elements-position: (
+ "#trait-implementations-list .impl h3 .trait",
+ "#trait-implementations-list .impl h3 .struct",
+ ("y"),
+)
+// And we now check that the where condition isn't on the same line.
+compare-elements-position-false: (
+ "#trait-implementations-list .impl h3 .trait",
+ "#trait-implementations-list .impl h3 .where.fmt-newline",
+ ("y"),
+)
diff --git a/src/test/rustdoc-json/assoc_items.rs b/src/test/rustdoc-json/assoc_items.rs
index 2ee64c9f6..6d7f6bb96 100644
--- a/src/test/rustdoc-json/assoc_items.rs
+++ b/src/test/rustdoc-json/assoc_items.rs
@@ -1,29 +1,37 @@
#![no_std]
-// @has assoc_items.json
-
pub struct Simple;
impl Simple {
- // @has - "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
+ // @is "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
pub const CONSTANT: usize = 0;
}
pub trait EasyToImpl {
- // @has - "$.index[*][?(@.name=='ToDeclare')].kind" \"assoc_type\"
- // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default" null
+ // @is "$.index[*][?(@.docs=='ToDeclare trait')].kind" \"assoc_type\"
+ // @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.default" null
+ // @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.bounds" []
+ /// ToDeclare trait
type ToDeclare;
- // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].kind" \"assoc_const\"
- // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" null
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].kind" \"assoc_const\"
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.default" null
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.type.kind" '"primitive"'
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.type.inner" '"usize"'
+ /// AN_ATTRIBUTE trait
const AN_ATTRIBUTE: usize;
}
impl EasyToImpl for Simple {
- // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default.kind" \"primitive\"
- // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default.inner" \"usize\"
+ // @is "$.index[*][?(@.docs=='ToDeclare impl')].kind" '"assoc_type"'
+ // @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.default.kind" \"primitive\"
+ // @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.default.inner" \"usize\"
+ /// ToDeclare impl
type ToDeclare = usize;
- // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.kind" \"primitive\"
- // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.inner" \"usize\"
- // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" \"12\"
+
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].kind" '"assoc_const"'
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.type.kind" \"primitive\"
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.type.inner" \"usize\"
+ // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.default" \"12\"
+ /// AN_ATTRIBUTE impl
const AN_ATTRIBUTE: usize = 12;
}
diff --git a/src/test/rustdoc-json/assoc_type.rs b/src/test/rustdoc-json/assoc_type.rs
index 716bb3d28..edc1f73c8 100644
--- a/src/test/rustdoc-json/assoc_type.rs
+++ b/src/test/rustdoc-json/assoc_type.rs
@@ -1,10 +1,9 @@
// Regression test for <https://github.com/rust-lang/rust/issues/98547>.
-// @has assoc_type.json
-// @has - "$.index[*][?(@.name=='Trait')]"
-// @has - "$.index[*][?(@.name=='AssocType')]"
-// @has - "$.index[*][?(@.name=='S')]"
-// @has - "$.index[*][?(@.name=='S2')]"
+// @has "$.index[*][?(@.name=='Trait')]"
+// @has "$.index[*][?(@.name=='AssocType')]"
+// @has "$.index[*][?(@.name=='S')]"
+// @has "$.index[*][?(@.name=='S2')]"
pub trait Trait {
type AssocType;
diff --git a/src/test/rustdoc-json/blanket_impls.rs b/src/test/rustdoc-json/blanket_impls.rs
index edf1a9fe2..c5cc87ca1 100644
--- a/src/test/rustdoc-json/blanket_impls.rs
+++ b/src/test/rustdoc-json/blanket_impls.rs
@@ -2,8 +2,7 @@
#![no_std]
-// @has blanket_impls.json
-// @has - "$.index[*][?(@.name=='Error')].kind" \"assoc_type\"
-// @has - "$.index[*][?(@.name=='Error')].inner.default.kind" \"resolved_path\"
-// @has - "$.index[*][?(@.name=='Error')].inner.default.inner.name" \"Infallible\"
+// @has "$.index[*][?(@.name=='Error')].kind" \"assoc_type\"
+// @has "$.index[*][?(@.name=='Error')].inner.default.kind" \"resolved_path\"
+// @has "$.index[*][?(@.name=='Error')].inner.default.inner.name" \"Infallible\"
pub struct ForBlanketTryFromImpl;
diff --git a/src/test/rustdoc-json/doc_hidden_failure.rs b/src/test/rustdoc-json/doc_hidden_failure.rs
index 5c4ccf996..6573166c4 100644
--- a/src/test/rustdoc-json/doc_hidden_failure.rs
+++ b/src/test/rustdoc-json/doc_hidden_failure.rs
@@ -14,7 +14,7 @@ mod auto {
}
}
-// @count doc_hidden_failure.json "$.index[*][?(@.name=='builders')]" 2
+// @count "$.index[*][?(@.name=='builders')]" 2
pub use auto::*;
pub mod builders {
diff --git a/src/test/rustdoc-json/enums/discriminant/basic.rs b/src/test/rustdoc-json/enums/discriminant/basic.rs
new file mode 100644
index 000000000..8c221615a
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/basic.rs
@@ -0,0 +1,12 @@
+#[repr(i8)]
+pub enum Ordering {
+ // @is "$.index[*][?(@.name=='Less')].inner.variant_inner.expr" '"-1"'
+ // @is "$.index[*][?(@.name=='Less')].inner.variant_inner.value" '"-1"'
+ Less = -1,
+ // @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.expr" '"0"'
+ // @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.value" '"0"'
+ Equal = 0,
+ // @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.expr" '"1"'
+ // @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.value" '"1"'
+ Greater = 1,
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/expr.rs b/src/test/rustdoc-json/enums/discriminant/expr.rs
new file mode 100644
index 000000000..235b0b473
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/expr.rs
@@ -0,0 +1,39 @@
+pub enum Foo {
+ // @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.value" '"0"'
+ // @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.expr" '"{ _ }"'
+ Addition = 0 + 0,
+ // @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.value" '"1"'
+ // @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.expr" '"0b1"'
+ Bin = 0b1,
+ // @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.value" '"2"'
+ // @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.expr" '"0o2"'
+ Oct = 0o2,
+ // @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.value" '"3"'
+ // @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.expr" '"THREE"'
+ PubConst = THREE,
+ // @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.value" '"4"'
+ // @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.expr" '"0x4"'
+ Hex = 0x4,
+ // @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.value" '"5"'
+ // @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.expr" '"{ _ }"'
+ Cast = 5 as isize,
+ // @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.value" '"6"'
+ // @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.expr" '"{ _ }"'
+ PubCall = six(),
+ // @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.value" '"7"'
+ // @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.expr" '"{ _ }"'
+ PrivCall = seven(),
+ // @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.value" '"8"'
+ // @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.expr" '"EIGHT"'
+ PrivConst = EIGHT,
+}
+
+pub const THREE: isize = 3;
+const EIGHT: isize = 8;
+
+pub const fn six() -> isize {
+ 6
+}
+const fn seven() -> isize {
+ 7
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/limits.rs b/src/test/rustdoc-json/enums/discriminant/limits.rs
new file mode 100644
index 000000000..8df73d78d
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/limits.rs
@@ -0,0 +1,43 @@
+// ignore-tidy-linelength
+#![feature(repr128)]
+#![allow(incomplete_features)]
+
+#[repr(u64)]
+pub enum U64 {
+ // @is "$.index[*][?(@.name=='U64Min')].inner.variant_inner.value" '"0"'
+ // @is "$.index[*][?(@.name=='U64Min')].inner.variant_inner.expr" '"u64::MIN"'
+ U64Min = u64::MIN,
+ // @is "$.index[*][?(@.name=='U64Max')].inner.variant_inner.value" '"18446744073709551615"'
+ // @is "$.index[*][?(@.name=='U64Max')].inner.variant_inner.expr" '"u64::MAX"'
+ U64Max = u64::MAX,
+}
+
+#[repr(i64)]
+pub enum I64 {
+ // @is "$.index[*][?(@.name=='I64Min')].inner.variant_inner.value" '"-9223372036854775808"'
+ // @is "$.index[*][?(@.name=='I64Min')].inner.variant_inner.expr" '"i64::MIN"'
+ I64Min = i64::MIN,
+ // @is "$.index[*][?(@.name=='I64Max')].inner.variant_inner.value" '"9223372036854775807"'
+ // @is "$.index[*][?(@.name=='I64Max')].inner.variant_inner.expr" '"i64::MAX"'
+ I64Max = i64::MAX,
+}
+
+#[repr(u128)]
+pub enum U128 {
+ // @is "$.index[*][?(@.name=='U128Min')].inner.variant_inner.value" '"0"'
+ // @is "$.index[*][?(@.name=='U128Min')].inner.variant_inner.expr" '"u128::MIN"'
+ U128Min = u128::MIN,
+ // @is "$.index[*][?(@.name=='U128Max')].inner.variant_inner.value" '"340282366920938463463374607431768211455"'
+ // @is "$.index[*][?(@.name=='U128Max')].inner.variant_inner.expr" '"u128::MAX"'
+ U128Max = u128::MAX,
+}
+
+#[repr(i128)]
+pub enum I128 {
+ // @is "$.index[*][?(@.name=='I128Min')].inner.variant_inner.value" '"-170141183460469231731687303715884105728"'
+ // @is "$.index[*][?(@.name=='I128Min')].inner.variant_inner.expr" '"i128::MIN"'
+ I128Min = i128::MIN,
+ // @is "$.index[*][?(@.name=='I128Max')].inner.variant_inner.value" '"170141183460469231731687303715884105727"'
+ // @is "$.index[*][?(@.name=='I128Max')].inner.variant_inner.expr" '"i128::MAX"'
+ I128Max = i128::MAX,
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
new file mode 100644
index 000000000..3417baa07
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
@@ -0,0 +1,15 @@
+#[repr(u32)]
+pub enum Foo {
+ // @is "$.index[*][?(@.name=='Basic')].inner.variant_inner.value" '"0"'
+ // @is "$.index[*][?(@.name=='Basic')].inner.variant_inner.expr" '"0"'
+ Basic = 0,
+ // @is "$.index[*][?(@.name=='Suffix')].inner.variant_inner.value" '"10"'
+ // @is "$.index[*][?(@.name=='Suffix')].inner.variant_inner.expr" '"10u32"'
+ Suffix = 10u32,
+ // @is "$.index[*][?(@.name=='Underscore')].inner.variant_inner.value" '"100"'
+ // @is "$.index[*][?(@.name=='Underscore')].inner.variant_inner.expr" '"1_0_0"'
+ Underscore = 1_0_0,
+ // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant_inner.value" '"1000"'
+ // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant_inner.expr" '"1_0_0_0u32"'
+ SuffixUnderscore = 1_0_0_0u32,
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
new file mode 100644
index 000000000..6af944a22
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
@@ -0,0 +1,10 @@
+pub enum Foo {
+ // @is "$.index[*][?(@.name=='Has')].inner.variant_inner" '{"expr":"0", "value":"0"}'
+ Has = 0,
+ // @is "$.index[*][?(@.name=='Doesnt')].inner.variant_inner" null
+ Doesnt,
+ // @is "$.index[*][?(@.name=='AlsoDoesnt')].inner.variant_inner" null
+ AlsoDoesnt,
+ // @is "$.index[*][?(@.name=='AlsoHas')].inner.variant_inner" '{"expr":"44", "value":"44"}'
+ AlsoHas = 44,
+}
diff --git a/src/test/rustdoc-json/enums/field_hidden.rs b/src/test/rustdoc-json/enums/field_hidden.rs
new file mode 100644
index 000000000..e6310cc3b
--- /dev/null
+++ b/src/test/rustdoc-json/enums/field_hidden.rs
@@ -0,0 +1,13 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/100529>.
+
+#![no_core]
+#![feature(no_core)]
+
+// @has "$.index[*][?(@.name=='ParseError')]"
+// @has "$.index[*][?(@.name=='UnexpectedEndTag')]"
+// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_kind" '"tuple"'
+// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_inner" [null]
+
+pub enum ParseError {
+ UnexpectedEndTag(#[doc(hidden)] u32),
+}
diff --git a/src/test/rustdoc-json/enums/kind.rs b/src/test/rustdoc-json/enums/kind.rs
new file mode 100644
index 000000000..e9ea3ae23
--- /dev/null
+++ b/src/test/rustdoc-json/enums/kind.rs
@@ -0,0 +1,37 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+pub enum Foo {
+ // @set Unit = "$.index[*][?(@.name=='Unit')].id"
+ // @is "$.index[*][?(@.name=='Unit')].inner.variant_kind" '"plain"'
+ // @is "$.index[*][?(@.name=='Unit')].inner.variant_inner" null
+ Unit,
+ // @set Named = "$.index[*][?(@.name=='Named')].id"
+ // @is "$.index[*][?(@.name=='Named')].inner.variant_kind" '"struct"'
+ // @is "$.index[*][?(@.name=='Named')].inner.variant_inner" '{"fields": [], "fields_stripped": false}'
+ Named {},
+ // @set Tuple = "$.index[*][?(@.name=='Tuple')].id"
+ // @is "$.index[*][?(@.name=='Tuple')].inner.variant_kind" '"tuple"'
+ // @is "$.index[*][?(@.name=='Tuple')].inner.variant_inner" []
+ Tuple(),
+ // @set NamedField = "$.index[*][?(@.name=='NamedField')].id"
+ // @set x = "$.index[*][?(@.name=='x' && @.kind=='struct_field')].id"
+ // @is "$.index[*][?(@.name=='NamedField')].inner.variant_kind" '"struct"'
+ // @is "$.index[*][?(@.name=='NamedField')].inner.variant_inner.fields[*]" $x
+ // @is "$.index[*][?(@.name=='NamedField')].inner.variant_inner.fields_stripped" false
+ NamedField { x: i32 },
+ // @set TupleField = "$.index[*][?(@.name=='TupleField')].id"
+ // @is "$.index[*][?(@.name=='TupleField')].inner.variant_kind" '"tuple"'
+ // @set tup_field = "$.index[*][?(@.name=='0' && @.kind=='struct_field')].id"
+ // @is "$.index[*][?(@.name=='TupleField')].inner.variant_inner[*]" $tup_field
+ TupleField(i32),
+}
+
+// @is "$.index[*][?(@.name=='Foo')].inner.variants[0]" $Unit
+// @is "$.index[*][?(@.name=='Foo')].inner.variants[1]" $Named
+// @is "$.index[*][?(@.name=='Foo')].inner.variants[2]" $Tuple
+// @is "$.index[*][?(@.name=='Foo')].inner.variants[3]" $NamedField
+// @is "$.index[*][?(@.name=='Foo')].inner.variants[4]" $TupleField
+// @count "$.index[*][?(@.name=='Foo')].inner.variants[*]" 5
diff --git a/src/test/rustdoc-json/enums/struct_field_hidden.rs b/src/test/rustdoc-json/enums/struct_field_hidden.rs
new file mode 100644
index 000000000..f612a34a4
--- /dev/null
+++ b/src/test/rustdoc-json/enums/struct_field_hidden.rs
@@ -0,0 +1,17 @@
+pub enum Foo {
+ Variant {
+ #[doc(hidden)]
+ a: i32,
+ // @set b = "$.index[*][?(@.name=='b')].id"
+ b: i32,
+ #[doc(hidden)]
+ x: i32,
+ // @set y = "$.index[*][?(@.name=='y')].id"
+ y: i32,
+ },
+ // @is "$.index[*][?(@.name=='Variant')].inner.variant_kind" '"struct"'
+ // @is "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields_stripped" true
+ // @is "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields[0]" $b
+ // @is "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields[1]" $y
+ // @count "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields[*]" 2
+}
diff --git a/src/test/rustdoc-json/enums/tuple_fields_hidden.rs b/src/test/rustdoc-json/enums/tuple_fields_hidden.rs
new file mode 100644
index 000000000..f546eaa0d
--- /dev/null
+++ b/src/test/rustdoc-json/enums/tuple_fields_hidden.rs
@@ -0,0 +1,94 @@
+#![feature(no_core)]
+#![no_core]
+
+// @set 1.1.0 = "$.index[*][?(@.docs=='1.1.0')].id"
+// @set 2.1.0 = "$.index[*][?(@.docs=='2.1.0')].id"
+// @set 2.1.1 = "$.index[*][?(@.docs=='2.1.1')].id"
+// @set 2.2.1 = "$.index[*][?(@.docs=='2.2.1')].id"
+// @set 2.3.0 = "$.index[*][?(@.docs=='2.3.0')].id"
+// @set 3.1.1 = "$.index[*][?(@.docs=='3.1.1')].id"
+// @set 3.1.2 = "$.index[*][?(@.docs=='3.1.2')].id"
+// @set 3.2.0 = "$.index[*][?(@.docs=='3.2.0')].id"
+// @set 3.2.2 = "$.index[*][?(@.docs=='3.2.2')].id"
+// @set 3.3.0 = "$.index[*][?(@.docs=='3.3.0')].id"
+// @set 3.3.1 = "$.index[*][?(@.docs=='3.3.1')].id"
+
+pub enum EnumWithStrippedTupleVariants {
+ // @is "$.index[*][?(@.name=='None')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='None')].inner.variant_inner[*]" 0
+ None(),
+
+ // @is "$.index[*][?(@.name=='One')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='One')].inner.variant_inner[*]" 1
+ // @is "$.index[*][?(@.name=='One')].inner.variant_inner[0]" $1.1.0
+ One(/** 1.1.0*/ bool),
+ // @is "$.index[*][?(@.name=='OneHidden')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='OneHidden')].inner.variant_inner[*]" 1
+ // @is "$.index[*][?(@.name=='OneHidden')].inner.variant_inner[0]" null
+ OneHidden(#[doc(hidden)] bool),
+
+ // @is "$.index[*][?(@.name=='Two')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='Two')].inner.variant_inner[*]" 2
+ // @is "$.index[*][?(@.name=='Two')].inner.variant_inner[0]" $2.1.0
+ // @is "$.index[*][?(@.name=='Two')].inner.variant_inner[1]" $2.1.1
+ Two(/** 2.1.0*/ bool, /** 2.1.1*/ bool),
+ // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_inner[*]" 2
+ // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_inner[0]" null
+ // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_inner[1]" $2.2.1
+ TwoLeftHidden(#[doc(hidden)] bool, /** 2.2.1*/ bool),
+ // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_inner[*]" 2
+ // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_inner[0]" $2.3.0
+ // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_inner[1]" null
+ TwoRightHidden(/** 2.3.0*/ bool, #[doc(hidden)] bool),
+ // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_inner[*]" 2
+ // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_inner[0]" null
+ // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_inner[1]" null
+ TwoBothHidden(#[doc(hidden)] bool, #[doc(hidden)] bool),
+
+ // @is "$.index[*][?(@.name=='Three1')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='Three1')].inner.variant_inner[*]" 3
+ // @is "$.index[*][?(@.name=='Three1')].inner.variant_inner[0]" null
+ // @is "$.index[*][?(@.name=='Three1')].inner.variant_inner[1]" $3.1.1
+ // @is "$.index[*][?(@.name=='Three1')].inner.variant_inner[2]" $3.1.2
+ Three1(#[doc(hidden)] bool, /** 3.1.1*/ bool, /** 3.1.2*/ bool),
+ // @is "$.index[*][?(@.name=='Three2')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='Three2')].inner.variant_inner[*]" 3
+ // @is "$.index[*][?(@.name=='Three2')].inner.variant_inner[0]" $3.2.0
+ // @is "$.index[*][?(@.name=='Three2')].inner.variant_inner[1]" null
+ // @is "$.index[*][?(@.name=='Three2')].inner.variant_inner[2]" $3.2.2
+ Three2(/** 3.2.0*/ bool, #[doc(hidden)] bool, /** 3.2.2*/ bool),
+ // @is "$.index[*][?(@.name=='Three3')].inner.variant_kind" '"tuple"'
+ // @count "$.index[*][?(@.name=='Three3')].inner.variant_inner[*]" 3
+ // @is "$.index[*][?(@.name=='Three3')].inner.variant_inner[0]" $3.3.0
+ // @is "$.index[*][?(@.name=='Three3')].inner.variant_inner[1]" $3.3.1
+ // @is "$.index[*][?(@.name=='Three3')].inner.variant_inner[2]" null
+ Three3(/** 3.3.0*/ bool, /** 3.3.1*/ bool, #[doc(hidden)] bool),
+}
+
+
+// @is "$.index[*][?(@.docs=='1.1.0')].name" '"0"'
+// @is "$.index[*][?(@.docs=='2.1.0')].name" '"0"'
+// @is "$.index[*][?(@.docs=='2.1.1')].name" '"1"'
+// @is "$.index[*][?(@.docs=='2.2.1')].name" '"1"'
+// @is "$.index[*][?(@.docs=='2.3.0')].name" '"0"'
+// @is "$.index[*][?(@.docs=='3.1.1')].name" '"1"'
+// @is "$.index[*][?(@.docs=='3.1.2')].name" '"2"'
+// @is "$.index[*][?(@.docs=='3.2.0')].name" '"0"'
+// @is "$.index[*][?(@.docs=='3.2.2')].name" '"2"'
+// @is "$.index[*][?(@.docs=='3.3.0')].name" '"0"'
+// @is "$.index[*][?(@.docs=='3.3.1')].name" '"1"'
+
+// @is "$.index[*][?(@.docs=='1.1.0')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='2.1.0')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='2.1.1')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='2.2.1')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='2.3.0')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='3.1.1')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='3.1.2')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='3.2.0')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='3.2.2')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='3.3.0')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='3.3.1')].inner" '{"kind": "primitive", "inner": "bool"}'
diff --git a/src/test/rustdoc-json/enums/variant_struct.rs b/src/test/rustdoc-json/enums/variant_struct.rs
index fcd92887c..23b854d8d 100644
--- a/src/test/rustdoc-json/enums/variant_struct.rs
+++ b/src/test/rustdoc-json/enums/variant_struct.rs
@@ -1,9 +1,9 @@
-// @has variant_struct.json "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\"
+// @is "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\"
pub enum EnumStruct {
- // @has - "$.index[*][?(@.name=='VariantS')].inner.variant_kind" \"struct\"
- // @has - "$.index[*][?(@.name=='x')].kind" \"struct_field\"
- // @has - "$.index[*][?(@.name=='y')].kind" \"struct_field\"
+ // @is "$.index[*][?(@.name=='VariantS')].inner.variant_kind" \"struct\"
+ // @is "$.index[*][?(@.name=='x')].kind" \"struct_field\"
+ // @is "$.index[*][?(@.name=='y')].kind" \"struct_field\"
VariantS {
x: u32,
y: String,
diff --git a/src/test/rustdoc-json/enums/variant_tuple_struct.rs b/src/test/rustdoc-json/enums/variant_tuple_struct.rs
index ac3e72e29..b71ec47a8 100644
--- a/src/test/rustdoc-json/enums/variant_tuple_struct.rs
+++ b/src/test/rustdoc-json/enums/variant_tuple_struct.rs
@@ -1,8 +1,8 @@
-// @has variant_tuple_struct.json "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\"
+// @is "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\"
pub enum EnumTupleStruct {
- // @has - "$.index[*][?(@.name=='VariantA')].inner.variant_kind" \"tuple\"
- // @has - "$.index[*][?(@.name=='0')].kind" \"struct_field\"
- // @has - "$.index[*][?(@.name=='1')].kind" \"struct_field\"
+ // @is "$.index[*][?(@.name=='VariantA')].inner.variant_kind" \"tuple\"
+ // @is "$.index[*][?(@.name=='0')].kind" \"struct_field\"
+ // @is "$.index[*][?(@.name=='1')].kind" \"struct_field\"
VariantA(u32, String),
}
diff --git a/src/test/rustdoc-json/fn_pointer/abi.rs b/src/test/rustdoc-json/fn_pointer/abi.rs
index eef20e60a..3c1a453d1 100644
--- a/src/test/rustdoc-json/fn_pointer/abi.rs
+++ b/src/test/rustdoc-json/fn_pointer/abi.rs
@@ -3,23 +3,23 @@
#![feature(abi_vectorcall)]
#![feature(c_unwind)]
-// @is abi.json "$.index[*][?(@.name=='AbiRust')].inner.type.inner.header.abi" \"Rust\"
+// @is "$.index[*][?(@.name=='AbiRust')].inner.type.inner.header.abi" \"Rust\"
pub type AbiRust = fn();
-// @is - "$.index[*][?(@.name=='AbiC')].inner.type.inner.header.abi" '{"C": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='AbiC')].inner.type.inner.header.abi" '{"C": {"unwind": false}}'
pub type AbiC = extern "C" fn();
-// @is - "$.index[*][?(@.name=='AbiSystem')].inner.type.inner.header.abi" '{"System": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='AbiSystem')].inner.type.inner.header.abi" '{"System": {"unwind": false}}'
pub type AbiSystem = extern "system" fn();
-// @is - "$.index[*][?(@.name=='AbiCUnwind')].inner.type.inner.header.abi" '{"C": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='AbiCUnwind')].inner.type.inner.header.abi" '{"C": {"unwind": true}}'
pub type AbiCUnwind = extern "C-unwind" fn();
-// @is - "$.index[*][?(@.name=='AbiSystemUnwind')].inner.type.inner.header.abi" '{"System": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='AbiSystemUnwind')].inner.type.inner.header.abi" '{"System": {"unwind": true}}'
pub type AbiSystemUnwind = extern "system-unwind" fn();
-// @is - "$.index[*][?(@.name=='AbiVecorcall')].inner.type.inner.header.abi.Other" '"\"vectorcall\""'
+// @is "$.index[*][?(@.name=='AbiVecorcall')].inner.type.inner.header.abi.Other" '"\"vectorcall\""'
pub type AbiVecorcall = extern "vectorcall" fn();
-// @is - "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.type.inner.header.abi.Other" '"\"vectorcall-unwind\""'
+// @is "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.type.inner.header.abi.Other" '"\"vectorcall-unwind\""'
pub type AbiVecorcallUnwind = extern "vectorcall-unwind" fn();
diff --git a/src/test/rustdoc-json/fn_pointer/generics.rs b/src/test/rustdoc-json/fn_pointer/generics.rs
index 646f720e6..a93b01ac2 100644
--- a/src/test/rustdoc-json/fn_pointer/generics.rs
+++ b/src/test/rustdoc-json/fn_pointer/generics.rs
@@ -3,12 +3,12 @@
#![feature(no_core)]
#![no_core]
-// @count generics.json "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[*]" 1
-// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][0]" '"val"'
-// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].inner.lifetime" \"\'c\"
-// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.output" '{ "kind": "primitive", "inner": "i32" }'
-// @count - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[*]" 1
-// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].name" \"\'c\"
-// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][0]" '"val"'
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].inner.lifetime" \"\'c\"
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.output" '{ "kind": "primitive", "inner": "i32" }'
+// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].name" \"\'c\"
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
pub type WithHigherRankTraitBounds = for<'c> fn(val: &'c i32) -> i32;
diff --git a/src/test/rustdoc-json/fn_pointer/qualifiers.rs b/src/test/rustdoc-json/fn_pointer/qualifiers.rs
index 381922085..bd65bb3ee 100644
--- a/src/test/rustdoc-json/fn_pointer/qualifiers.rs
+++ b/src/test/rustdoc-json/fn_pointer/qualifiers.rs
@@ -1,9 +1,9 @@
-// @is qualifiers.json "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.unsafe" false
-// @is - "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.const" false
-// @is - "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.async" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.const" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.async" false
pub type FnPointer = fn();
-// @is - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.unsafe" true
-// @is - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.const" false
-// @is - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.async" false
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.const" false
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.async" false
pub type UnsafePointer = unsafe fn();
diff --git a/src/test/rustdoc-json/fns/abi.rs b/src/test/rustdoc-json/fns/abi.rs
index 16b579130..0e8b78bc0 100644
--- a/src/test/rustdoc-json/fns/abi.rs
+++ b/src/test/rustdoc-json/fns/abi.rs
@@ -3,23 +3,23 @@
#![feature(abi_vectorcall)]
#![feature(c_unwind)]
-// @is abi.json "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
+// @is "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
pub fn abi_rust() {}
-// @is - "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
pub extern "C" fn abi_c() {}
-// @is - "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
pub extern "system" fn abi_system() {}
-// @is - "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
pub extern "C-unwind" fn abi_c_unwind() {}
-// @is - "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
pub extern "system-unwind" fn abi_system_unwind() {}
-// @is - "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+// @is "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
pub extern "vectorcall" fn abi_vectorcall() {}
-// @is - "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+// @is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {}
diff --git a/src/test/rustdoc-json/fns/async_return.rs b/src/test/rustdoc-json/fns/async_return.rs
new file mode 100644
index 000000000..b89781ca9
--- /dev/null
+++ b/src/test/rustdoc-json/fns/async_return.rs
@@ -0,0 +1,36 @@
+// edition:2021
+// ignore-tidy-linelength
+
+// Regression test for <https://github.com/rust-lang/rust/issues/101199>
+
+use std::future::Future;
+
+// @is "$.index[*][?(@.name=='get_int')].inner.decl.output" '{"inner": "i32", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='get_int')].inner.header.async" false
+pub fn get_int() -> i32 {
+ 42
+}
+
+// @is "$.index[*][?(@.name=='get_int_async')].inner.decl.output" '{"inner": "i32", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='get_int_async')].inner.header.async" true
+pub async fn get_int_async() -> i32 {
+ 42
+}
+
+// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.kind" '"impl_trait"'
+// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.inner[0].trait_bound.trait.name" '"Future"'
+// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].name" '"Output"'
+// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].binding.equality.type" '{"inner": "i32", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='get_int_future')].inner.header.async" false
+pub fn get_int_future() -> impl Future<Output = i32> {
+ async { 42 }
+}
+
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.kind" '"impl_trait"'
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.inner[0].trait_bound.trait.name" '"Future"'
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].name" '"Output"'
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].binding.equality.type" '{"inner": "i32", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.header.async" true
+pub async fn get_int_future_async() -> impl Future<Output = i32> {
+ async { 42 }
+}
diff --git a/src/test/rustdoc-json/fns/generic_args.rs b/src/test/rustdoc-json/fns/generic_args.rs
index 69150443c..eec295efe 100644
--- a/src/test/rustdoc-json/fns/generic_args.rs
+++ b/src/test/rustdoc-json/fns/generic_args.rs
@@ -3,65 +3,65 @@
#![feature(no_core)]
#![no_core]
-// @set foo = generic_args.json "$.index[*][?(@.name=='Foo')].id"
+// @set foo = "$.index[*][?(@.name=='Foo')].id"
pub trait Foo {}
-// @set generic_foo = generic_args.json "$.index[*][?(@.name=='GenericFoo')].id"
+// @set generic_foo = "$.index[*][?(@.name=='GenericFoo')].id"
pub trait GenericFoo<'a> {}
-// @is - "$.index[*][?(@.name=='generics')].inner.generics.where_predicates" "[]"
-// @count - "$.index[*][?(@.name=='generics')].inner.generics.params[*]" 1
-// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
-// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
-// @count - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" '$foo'
-// @count - "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
-// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
-// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
-// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].inner" '"F"'
+// @is "$.index[*][?(@.name=='generics')].inner.generics.where_predicates" "[]"
+// @count "$.index[*][?(@.name=='generics')].inner.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
+// @is "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
+// @count "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
+// @is "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo'
+// @count "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
+// @is "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
+// @is "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].inner" '"F"'
pub fn generics<F: Foo>(f: F) {}
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
-// @count - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $foo
-// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $foo
+// @is "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
+// @count "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
+// @is "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo
+// @count "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
+// @is "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
+// @count "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
+// @is "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $foo
pub fn impl_trait(f: impl Foo) {}
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].name" '"F"'
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "synthetic": false}}'
-// @count - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[*]" 3
-// @is - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][0]" '"f"'
-// @is - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].kind" '"generic"'
-// @is - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].inner" '"F"'
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[*]" 3
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].name" '"F"'
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "synthetic": false}}'
+// @count "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[*]" 3
+// @is "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][0]" '"f"'
+// @is "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].kind" '"generic"'
+// @is "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].inner" '"F"'
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[*]" 3
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.inner.id" $generic_foo
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.generic_params" "[]"
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.generic_params" "[]"
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
-// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
+// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
+// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
pub fn where_clase<F, G, H>(f: F, g: G, h: H)
where
F: Foo,
diff --git a/src/test/rustdoc-json/fns/generic_returns.rs b/src/test/rustdoc-json/fns/generic_returns.rs
index 1a0f33fe3..a9bc2d5d7 100644
--- a/src/test/rustdoc-json/fns/generic_returns.rs
+++ b/src/test/rustdoc-json/fns/generic_returns.rs
@@ -3,15 +3,15 @@
#![feature(no_core)]
#![no_core]
-// @count generic_returns.json "$.index[*][?(@.name=='generic_returns')].inner.items[*]" 2
+// @count "$.index[*][?(@.name=='generic_returns')].inner.items[*]" 2
-// @set foo = - "$.index[*][?(@.name=='Foo')].id"
+// @set foo = "$.index[*][?(@.name=='Foo')].id"
pub trait Foo {}
-// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
-// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
-// @count - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
-// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.inner.id" $foo
+// @is "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
+// @is "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
+// @count "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
+// @is "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.id" $foo
pub fn get_foo() -> impl Foo {
Fooer {}
}
diff --git a/src/test/rustdoc-json/fns/generics.rs b/src/test/rustdoc-json/fns/generics.rs
index e777fabaa..7b70ff1df 100644
--- a/src/test/rustdoc-json/fns/generics.rs
+++ b/src/test/rustdoc-json/fns/generics.rs
@@ -3,24 +3,24 @@
#![feature(no_core)]
#![no_core]
-// @set wham_id = generics.json "$.index[*][?(@.name=='Wham')].id"
+// @set wham_id = "$.index[*][?(@.name=='Wham')].id"
pub trait Wham {}
-// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
-// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
-// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
-// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
-// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
-// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
+// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
+// @count "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
+// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
+// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
+// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
pub fn one_generic_param_fn<T: Wham>(w: T) {}
-// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
-// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
-// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
-// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
-// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
-// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
-// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
-// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
+// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
+// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
+// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $wham_id
pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
diff --git a/src/test/rustdoc-json/fns/qualifiers.rs b/src/test/rustdoc-json/fns/qualifiers.rs
index 5cb3b43e6..7ff542900 100644
--- a/src/test/rustdoc-json/fns/qualifiers.rs
+++ b/src/test/rustdoc-json/fns/qualifiers.rs
@@ -1,33 +1,33 @@
// edition:2018
-// @is qualifiers.json "$.index[*][?(@.name=='nothing_fn')].inner.header.async" false
-// @is - "$.index[*][?(@.name=='nothing_fn')].inner.header.const" false
-// @is - "$.index[*][?(@.name=='nothing_fn')].inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='nothing_fn')].inner.header.async" false
+// @is "$.index[*][?(@.name=='nothing_fn')].inner.header.const" false
+// @is "$.index[*][?(@.name=='nothing_fn')].inner.header.unsafe" false
pub fn nothing_fn() {}
-// @is - "$.index[*][?(@.name=='unsafe_fn')].inner.header.async" false
-// @is - "$.index[*][?(@.name=='unsafe_fn')].inner.header.const" false
-// @is - "$.index[*][?(@.name=='unsafe_fn')].inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='unsafe_fn')].inner.header.async" false
+// @is "$.index[*][?(@.name=='unsafe_fn')].inner.header.const" false
+// @is "$.index[*][?(@.name=='unsafe_fn')].inner.header.unsafe" true
pub unsafe fn unsafe_fn() {}
-// @is - "$.index[*][?(@.name=='const_fn')].inner.header.async" false
-// @is - "$.index[*][?(@.name=='const_fn')].inner.header.const" true
-// @is - "$.index[*][?(@.name=='const_fn')].inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='const_fn')].inner.header.async" false
+// @is "$.index[*][?(@.name=='const_fn')].inner.header.const" true
+// @is "$.index[*][?(@.name=='const_fn')].inner.header.unsafe" false
pub const fn const_fn() {}
-// @is - "$.index[*][?(@.name=='async_fn')].inner.header.async" true
-// @is - "$.index[*][?(@.name=='async_fn')].inner.header.const" false
-// @is - "$.index[*][?(@.name=='async_fn')].inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='async_fn')].inner.header.async" true
+// @is "$.index[*][?(@.name=='async_fn')].inner.header.const" false
+// @is "$.index[*][?(@.name=='async_fn')].inner.header.unsafe" false
pub async fn async_fn() {}
-// @is - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.async" true
-// @is - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.const" false
-// @is - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.async" true
+// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.const" false
+// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.unsafe" true
pub async unsafe fn async_unsafe_fn() {}
-// @is - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.async" false
-// @is - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.const" true
-// @is - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.async" false
+// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.const" true
+// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.unsafe" true
pub const unsafe fn const_unsafe_fn() {}
// It's impossible for a function to be both const and async, so no test for that
diff --git a/src/test/rustdoc-json/generic-associated-types/gats.rs b/src/test/rustdoc-json/generic-associated-types/gats.rs
index 368ff8d8d..e5809783a 100644
--- a/src/test/rustdoc-json/generic-associated-types/gats.rs
+++ b/src/test/rustdoc-json/generic-associated-types/gats.rs
@@ -1,44 +1,42 @@
// ignore-tidy-linelength
#![no_core]
-#![feature(generic_associated_types, lang_items, no_core)]
+#![feature(lang_items, no_core)]
#[lang = "sized"]
pub trait Sized {}
pub trait Display {}
-// @has gats.json
pub trait LendingIterator {
- // @count - "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*]" 1
- // @is - "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*].name" \"\'a\"
- // @count - "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*]" 1
- // @is - "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.type.inner" \"Self\"
- // @is - "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\"
- // @count - "$.index[*][?(@.name=='LendingItem')].inner.bounds[*]" 1
+ // @count "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*]" 1
+ // @is "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*].name" \"\'a\"
+ // @count "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*]" 1
+ // @is "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.type.inner" \"Self\"
+ // @is "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\"
+ // @count "$.index[*][?(@.name=='LendingItem')].inner.bounds[*]" 1
type LendingItem<'a>: Display
where
Self: 'a;
- // @is - "$.index[*][?(@.name=='lending_next')].inner.decl.output.kind" \"qualified_path\"
- // @count - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 1
- // @count - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
- // @is - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.self_type.inner" \"Self\"
- // @is - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.name" \"LendingItem\"
+ // @is "$.index[*][?(@.name=='lending_next')].inner.decl.output.kind" \"qualified_path\"
+ // @count "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 1
+ // @count "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
+ // @is "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.self_type.inner" \"Self\"
+ // @is "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.name" \"LendingItem\"
fn lending_next<'a>(&'a self) -> Self::LendingItem<'a>;
}
-// @has gats.json
pub trait Iterator {
- // @count - "$.index[*][?(@.name=='Item')].inner.generics.params[*]" 0
- // @count - "$.index[*][?(@.name=='Item')].inner.generics.where_predicates[*]" 0
- // @count - "$.index[*][?(@.name=='Item')].inner.bounds[*]" 1
+ // @count "$.index[*][?(@.name=='Item')].inner.generics.params[*]" 0
+ // @count "$.index[*][?(@.name=='Item')].inner.generics.where_predicates[*]" 0
+ // @count "$.index[*][?(@.name=='Item')].inner.bounds[*]" 1
type Item: Display;
- // @is - "$.index[*][?(@.name=='next')].inner.decl.output.kind" \"qualified_path\"
- // @count - "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 0
- // @count - "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
- // @is - "$.index[*][?(@.name=='next')].inner.decl.output.inner.self_type.inner" \"Self\"
- // @is - "$.index[*][?(@.name=='next')].inner.decl.output.inner.name" \"Item\"
+ // @is "$.index[*][?(@.name=='next')].inner.decl.output.kind" \"qualified_path\"
+ // @count "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 0
+ // @count "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
+ // @is "$.index[*][?(@.name=='next')].inner.decl.output.inner.self_type.inner" \"Self\"
+ // @is "$.index[*][?(@.name=='next')].inner.decl.output.inner.name" \"Item\"
fn next<'a>(&'a self) -> Self::Item;
}
diff --git a/src/test/rustdoc-json/generic_impl.rs b/src/test/rustdoc-json/generic_impl.rs
index ac68ba578..31f41d0f3 100644
--- a/src/test/rustdoc-json/generic_impl.rs
+++ b/src/test/rustdoc-json/generic_impl.rs
@@ -1,9 +1,8 @@
// Regression test for <https://github.com/rust-lang/rust/issues/97986>.
-// @has generic_impl.json
-// @has - "$.index[*][?(@.name=='f')]"
-// @has - "$.index[*][?(@.name=='AssocTy')]"
-// @has - "$.index[*][?(@.name=='AssocConst')]"
+// @has "$.index[*][?(@.name=='f')]"
+// @has "$.index[*][?(@.name=='AssocTy')]"
+// @has "$.index[*][?(@.name=='AssocConst')]"
pub mod m {
pub struct S;
diff --git a/src/test/rustdoc-json/glob_import.rs b/src/test/rustdoc-json/glob_import.rs
index d7ac952d1..00051b121 100644
--- a/src/test/rustdoc-json/glob_import.rs
+++ b/src/test/rustdoc-json/glob_import.rs
@@ -4,9 +4,8 @@
#![no_std]
#![no_core]
-// @has glob_import.json
-// @has - "$.index[*][?(@.name=='glob')]"
-// @has - "$.index[*][?(@.kind=='import')].inner.name" \"*\"
+// @has "$.index[*][?(@.name=='glob')]"
+// @has "$.index[*][?(@.kind=='import')].inner.name" \"*\"
mod m1 {
diff --git a/src/test/rustdoc-json/impls/auto.rs b/src/test/rustdoc-json/impls/auto.rs
new file mode 100644
index 000000000..50d852414
--- /dev/null
+++ b/src/test/rustdoc-json/impls/auto.rs
@@ -0,0 +1,18 @@
+#![feature(no_core, auto_traits, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub auto trait Bar {}
+
+/// has span
+impl Foo {
+ pub fn baz(&self) {}
+}
+
+// Testing spans, so all tests below code
+// @is "$.index[*][?(@.kind=='impl' && @.inner.synthetic==true)].span" null
+// @is "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
+// @is "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
+pub struct Foo;
diff --git a/src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs b/src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs
new file mode 100644
index 000000000..832d0fce5
--- /dev/null
+++ b/src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs
@@ -0,0 +1 @@
+pub struct ForeignStruct;
diff --git a/src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs b/src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs
new file mode 100644
index 000000000..2c81bee61
--- /dev/null
+++ b/src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs
@@ -0,0 +1 @@
+pub trait ForeignTrait {}
diff --git a/src/test/rustdoc-json/impls/blanket_with_local.rs b/src/test/rustdoc-json/impls/blanket_with_local.rs
index a3d55b35f..2fb4a84b9 100644
--- a/src/test/rustdoc-json/impls/blanket_with_local.rs
+++ b/src/test/rustdoc-json/impls/blanket_with_local.rs
@@ -1,11 +1,11 @@
// Test for the ICE in rust/83718
// A blanket impl plus a local type together shouldn't result in mismatched ID issues
-// @has blanket_with_local.json "$.index[*][?(@.name=='Load')]"
+// @has "$.index[*][?(@.name=='Load')]"
pub trait Load {
- // @has - "$.index[*][?(@.name=='load')]"
+ // @has "$.index[*][?(@.name=='load')]"
fn load() {}
- // @has - "$.index[*][?(@.name=='write')]"
+ // @has "$.index[*][?(@.name=='write')]"
fn write(self) {}
}
@@ -14,5 +14,5 @@ impl<P> Load for P {
fn write(self) {}
}
-// @has - "$.index[*][?(@.name=='Wrapper')]"
+// @has "$.index[*][?(@.name=='Wrapper')]"
pub struct Wrapper {}
diff --git a/src/test/rustdoc-json/impls/foreign_for_local.rs b/src/test/rustdoc-json/impls/foreign_for_local.rs
new file mode 100644
index 000000000..290c2d571
--- /dev/null
+++ b/src/test/rustdoc-json/impls/foreign_for_local.rs
@@ -0,0 +1,18 @@
+// aux-build: foreign_trait.rs
+extern crate foreign_trait;
+
+/// ForeignTrait id hack
+pub use foreign_trait::ForeignTrait as _;
+// @set ForeignTrait = "$.index[*][?(@.docs=='ForeignTrait id hack')].inner.id"
+
+pub struct LocalStruct;
+// @set LocalStruct = "$.index[*][?(@.name=='LocalStruct')].id"
+
+/// foreign for local
+impl foreign_trait::ForeignTrait for LocalStruct {}
+
+// @set impl = "$.index[*][?(@.docs=='foreign for local')].id"
+// @is "$.index[*][?(@.docs=='foreign for local')].inner.for.inner.id" $LocalStruct
+// @is "$.index[*][?(@.docs=='foreign for local')].inner.trait.id" $ForeignTrait
+
+// @has "$.index[*][?(@.name=='LocalStruct')].inner.impls[*]" $impl
diff --git a/src/test/rustdoc-json/impls/import_from_private.rs b/src/test/rustdoc-json/impls/import_from_private.rs
new file mode 100644
index 000000000..856f7c701
--- /dev/null
+++ b/src/test/rustdoc-json/impls/import_from_private.rs
@@ -0,0 +1,22 @@
+// https://github.com/rust-lang/rust/issues/100252
+
+#![feature(no_core)]
+#![no_core]
+
+mod bar {
+ // @set baz = "$.index[*][?(@.kind=='struct')].id"
+ pub struct Baz;
+ // @set impl = "$.index[*][?(@.kind=='impl')].id"
+ impl Baz {
+ // @set doit = "$.index[*][?(@.kind=='method')].id"
+ pub fn doit() {}
+ }
+}
+
+// @set import = "$.index[*][?(@.kind=='import')].id"
+pub use bar::Baz;
+
+// @is "$.index[*][?(@.kind=='module')].inner.items[*]" $import
+// @is "$.index[*][?(@.kind=='import')].inner.id" $baz
+// @is "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
+// @is "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
diff --git a/src/test/rustdoc-json/impls/local_for_foreign.rs b/src/test/rustdoc-json/impls/local_for_foreign.rs
new file mode 100644
index 000000000..74f2f08b5
--- /dev/null
+++ b/src/test/rustdoc-json/impls/local_for_foreign.rs
@@ -0,0 +1,18 @@
+// aux-build: foreign_struct.rs
+extern crate foreign_struct;
+
+/// ForeignStruct id hack
+pub use foreign_struct::ForeignStruct as _;
+// @set ForeignStruct = "$.index[*][?(@.docs=='ForeignStruct id hack')].inner.id"
+
+pub trait LocalTrait {}
+// @set LocalTrait = "$.index[*][?(@.name=='LocalTrait')].id"
+
+/// local for foreign
+impl LocalTrait for foreign_struct::ForeignStruct {}
+
+// @set impl = "$.index[*][?(@.docs=='local for foreign')].id"
+// @is "$.index[*][?(@.docs=='local for foreign')].inner.trait.id" $LocalTrait
+// @is "$.index[*][?(@.docs=='local for foreign')].inner.for.inner.id" $ForeignStruct
+
+// @is "$.index[*][?(@.name=='LocalTrait')].inner.implementations[*]" $impl
diff --git a/src/test/rustdoc-json/impls/local_for_local.rs b/src/test/rustdoc-json/impls/local_for_local.rs
new file mode 100644
index 000000000..93dedb7ec
--- /dev/null
+++ b/src/test/rustdoc-json/impls/local_for_local.rs
@@ -0,0 +1,15 @@
+#![feature(no_core)]
+#![no_core]
+
+// @set struct = "$.index[*][?(@.name=='Struct')].id"
+pub struct Struct;
+// @set trait = "$.index[*][?(@.name=='Trait')].id"
+pub trait Trait {}
+// @set impl = "$.index[*][?(@.docs=='impl')].id"
+/// impl
+impl Trait for Struct {}
+
+// @is "$.index[*][?(@.name=='Struct')].inner.impls[*]" $impl
+// @is "$.index[*][?(@.name=='Trait')].inner.implementations[*]" $impl
+// @is "$.index[*][?(@.docs=='impl')].inner.trait.id" $trait
+// @is "$.index[*][?(@.docs=='impl')].inner.for.inner.id" $struct
diff --git a/src/test/rustdoc-json/impls/local_for_local_primitive.rs b/src/test/rustdoc-json/impls/local_for_local_primitive.rs
new file mode 100644
index 000000000..38e7e2658
--- /dev/null
+++ b/src/test/rustdoc-json/impls/local_for_local_primitive.rs
@@ -0,0 +1,21 @@
+#![feature(no_core)]
+#![feature(rustdoc_internals)]
+#![no_core]
+
+// @set Local = "$.index[*][?(@.name=='Local')].id"
+pub trait Local {}
+
+// @is "$.index[*][?(@.docs=='Local for bool')].inner.trait.id" $Local
+// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.kind" '"primitive"'
+// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.inner" '"bool"'
+/// Local for bool
+impl Local for bool {}
+
+// @set impl = "$.index[*][?(@.docs=='Local for bool')].id"
+// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl
+
+// FIXME(#101695): Test bool's `impls` include "Local for bool"
+// @has "$.index[*][?(@.name=='bool')]"
+#[doc(primitive = "bool")]
+/// Boolean docs
+mod prim_bool {}
diff --git a/src/test/rustdoc-json/impls/local_for_primitive.rs b/src/test/rustdoc-json/impls/local_for_primitive.rs
new file mode 100644
index 000000000..7702a526f
--- /dev/null
+++ b/src/test/rustdoc-json/impls/local_for_primitive.rs
@@ -0,0 +1,7 @@
+// @set local = "$.index[*][?(@.name=='Local')]"
+pub trait Local {}
+
+// @set impl = "$.index[*][?(@.docs=='local for bool')].id"
+// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl
+/// local for bool
+impl Local for bool {}
diff --git a/src/test/rustdoc-json/intra-doc-links/non_page.rs b/src/test/rustdoc-json/intra-doc-links/non_page.rs
new file mode 100644
index 000000000..73c5334bb
--- /dev/null
+++ b/src/test/rustdoc-json/intra-doc-links/non_page.rs
@@ -0,0 +1,34 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/101531>,
+// where links where to the item who's HTML page had the item linked to.
+
+//! [`Struct::struct_field`]
+//! [`Enum::Variant`]
+//! [`Trait::AssocType`]
+//! [`Trait::ASSOC_CONST`]
+//! [`Trait::method`]
+
+// @set struct_field = "$.index[*][?(@.name=='struct_field')].id"
+// @set Variant = "$.index[*][?(@.name=='Variant')].id"
+// @set AssocType = "$.index[*][?(@.name=='AssocType')].id"
+// @set ASSOC_CONST = "$.index[*][?(@.name=='ASSOC_CONST')].id"
+// @set method = "$.index[*][?(@.name=='method')].id"
+
+// @is "$.index[*][?(@.name=='non_page')].links['`Struct::struct_field`']" $struct_field
+// @is "$.index[*][?(@.name=='non_page')].links['`Enum::Variant`']" $Variant
+// @is "$.index[*][?(@.name=='non_page')].links['`Trait::AssocType`']" $AssocType
+// @is "$.index[*][?(@.name=='non_page')].links['`Trait::ASSOC_CONST`']" $ASSOC_CONST
+// @is "$.index[*][?(@.name=='non_page')].links['`Trait::method`']" $method
+
+pub struct Struct {
+ pub struct_field: i32,
+}
+
+pub enum Enum {
+ Variant(),
+}
+
+pub trait Trait {
+ const ASSOC_CONST: i32;
+ type AssocType;
+ fn method();
+}
diff --git a/src/test/rustdoc-json/intra-doc-links/user_written.rs b/src/test/rustdoc-json/intra-doc-links/user_written.rs
new file mode 100644
index 000000000..6871dfea4
--- /dev/null
+++ b/src/test/rustdoc-json/intra-doc-links/user_written.rs
@@ -0,0 +1,8 @@
+//! For motivation, see [the reasons](foo#reasons)
+
+/// # Reasons
+/// To test rustdoc json
+pub fn foo() {}
+
+// @set foo = "$.index[*][?(@.name=='foo')].id"
+// @is "$.index[*][?(@.name=='user_written')].links['foo#reasons']" $foo
diff --git a/src/test/rustdoc-json/keyword.rs b/src/test/rustdoc-json/keyword.rs
index 78a843aca..3446b212c 100644
--- a/src/test/rustdoc-json/keyword.rs
+++ b/src/test/rustdoc-json/keyword.rs
@@ -6,16 +6,15 @@
#![feature(rustdoc_internals)]
#![no_std]
-// @has keyword.json
-// @!has - "$.index[*][?(@.name=='match')]"
-// @has - "$.index[*][?(@.name=='foo')]"
+// @!has "$.index[*][?(@.name=='match')]"
+// @has "$.index[*][?(@.name=='foo')]"
#[doc(keyword = "match")]
/// this is a test!
pub mod foo {}
-// @!has - "$.index[*][?(@.name=='hello')]"
-// @!has - "$.index[*][?(@.name=='bar')]"
+// @!has "$.index[*][?(@.name=='hello')]"
+// @!has "$.index[*][?(@.name=='bar')]"
#[doc(keyword = "hello")]
/// hello
mod bar {}
diff --git a/src/test/rustdoc-json/lifetime/longest.rs b/src/test/rustdoc-json/lifetime/longest.rs
index 95b99599e..326dab8e5 100644
--- a/src/test/rustdoc-json/lifetime/longest.rs
+++ b/src/test/rustdoc-json/lifetime/longest.rs
@@ -3,30 +3,30 @@
#![feature(no_core)]
#![no_core]
-// @is longest.json "$.index[*][?(@.name=='longest')].inner.generics.params[0].name" \"\'a\"
-// @is - "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind" '{"lifetime": {"outlives": []}}'
-// @is - "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind" '{"lifetime": {"outlives": []}}'
-// @count - "$.index[*][?(@.name=='longest')].inner.generics.params[*]" 1
-// @is - "$.index[*][?(@.name=='longest')].inner.generics.where_predicates" []
+// @is "$.index[*][?(@.name=='longest')].inner.generics.params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind" '{"lifetime": {"outlives": []}}'
+// @is "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind" '{"lifetime": {"outlives": []}}'
+// @count "$.index[*][?(@.name=='longest')].inner.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='longest')].inner.generics.where_predicates" []
-// @count - "$.index[*][?(@.name=='longest')].inner.decl.inputs[*]" 2
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][0]" '"l"'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][0]" '"r"'
+// @count "$.index[*][?(@.name=='longest')].inner.decl.inputs[*]" 2
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][0]" '"l"'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][0]" '"r"'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.mutable" false
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.type" '{"inner": "str", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.mutable" false
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.type" '{"inner": "str", "kind": "primitive"}'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.lifetime" \"\'a\"
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.mutable" false
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.type" '{"inner": "str", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.mutable" false
+// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.type" '{"inner": "str", "kind": "primitive"}'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.inner.lifetime" \"\'a\"
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.inner.mutable" false
-// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.inner.type" '{"inner": "str", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.output.kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='longest')].inner.decl.output.inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.decl.output.inner.mutable" false
+// @is "$.index[*][?(@.name=='longest')].inner.decl.output.inner.type" '{"inner": "str", "kind": "primitive"}'
pub fn longest<'a>(l: &'a str, r: &'a str) -> &'a str {
if l.len() > r.len() { l } else { r }
diff --git a/src/test/rustdoc-json/lifetime/outlives.rs b/src/test/rustdoc-json/lifetime/outlives.rs
index 096dd7f7a..e15a533ef 100644
--- a/src/test/rustdoc-json/lifetime/outlives.rs
+++ b/src/test/rustdoc-json/lifetime/outlives.rs
@@ -3,21 +3,21 @@
#![feature(no_core)]
#![no_core]
-// @count outlives.json "$.index[*][?(@.name=='foo')].inner.generics.params[*]" 3
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.where_predicates" []
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[0].name" \"\'a\"
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[1].name" \"\'b\"
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[2].name" '"T"'
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[0].kind.lifetime.outlives" []
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[1].kind.lifetime.outlives" [\"\'a\"]
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.default" null
-// @count - "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[0].outlives" \"\'b\"
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.mutable" false
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.lifetime" \"\'b\"
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.mutable" false
-// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.type" '{"inner": "T", "kind": "generic"}'
+// @count "$.index[*][?(@.name=='foo')].inner.generics.params[*]" 3
+// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates" []
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[1].name" \"\'b\"
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[2].name" '"T"'
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[0].kind.lifetime.outlives" []
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[1].kind.lifetime.outlives" [\"\'a\"]
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.default" null
+// @count "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[*]" 1
+// @is "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[0].outlives" \"\'b\"
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.mutable" false
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.lifetime" \"\'b\"
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.mutable" false
+// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.type" '{"inner": "T", "kind": "generic"}'
pub fn foo<'a, 'b: 'a, T: 'b>(_: &'a &'b T) {}
diff --git a/src/test/rustdoc-json/methods/abi.rs b/src/test/rustdoc-json/methods/abi.rs
index 07b01d03b..4c97d97ce 100644
--- a/src/test/rustdoc-json/methods/abi.rs
+++ b/src/test/rustdoc-json/methods/abi.rs
@@ -5,51 +5,51 @@
#![feature(no_core)]
#![no_core]
-// @has abi.json "$.index[*][?(@.name=='Foo')]"
+// @has "$.index[*][?(@.name=='Foo')]"
pub struct Foo;
impl Foo {
- // @is - "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
+ // @is "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
pub fn abi_rust() {}
- // @is - "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+ // @is "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
pub extern "C" fn abi_c() {}
- // @is - "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+ // @is "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
pub extern "system" fn abi_system() {}
- // @is - "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+ // @is "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
pub extern "C-unwind" fn abi_c_unwind() {}
- // @is - "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+ // @is "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
pub extern "system-unwind" fn abi_system_unwind() {}
- // @is - "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+ // @is "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
pub extern "vectorcall" fn abi_vectorcall() {}
- // @is - "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+ // @is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {}
}
pub trait Bar {
- // @is - "$.index[*][?(@.name=='trait_abi_rust')].inner.header.abi" \"Rust\"
+ // @is "$.index[*][?(@.name=='trait_abi_rust')].inner.header.abi" \"Rust\"
fn trait_abi_rust() {}
- // @is - "$.index[*][?(@.name=='trait_abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+ // @is "$.index[*][?(@.name=='trait_abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
extern "C" fn trait_abi_c() {}
- // @is - "$.index[*][?(@.name=='trait_abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+ // @is "$.index[*][?(@.name=='trait_abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
extern "system" fn trait_abi_system() {}
- // @is - "$.index[*][?(@.name=='trait_abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+ // @is "$.index[*][?(@.name=='trait_abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
extern "C-unwind" fn trait_abi_c_unwind() {}
- // @is - "$.index[*][?(@.name=='trait_abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+ // @is "$.index[*][?(@.name=='trait_abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
extern "system-unwind" fn trait_abi_system_unwind() {}
- // @is - "$.index[*][?(@.name=='trait_abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+ // @is "$.index[*][?(@.name=='trait_abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
extern "vectorcall" fn trait_abi_vectorcall() {}
- // @is - "$.index[*][?(@.name=='trait_abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+ // @is "$.index[*][?(@.name=='trait_abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
extern "vectorcall-unwind" fn trait_abi_vectorcall_unwind() {}
}
diff --git a/src/test/rustdoc-json/methods/qualifiers.rs b/src/test/rustdoc-json/methods/qualifiers.rs
index af36d36b6..b9a5e5601 100644
--- a/src/test/rustdoc-json/methods/qualifiers.rs
+++ b/src/test/rustdoc-json/methods/qualifiers.rs
@@ -3,34 +3,34 @@
pub struct Foo;
impl Foo {
- // @is qualifiers.json "$.index[*][?(@.name=='const_meth')].inner.header.async" false
- // @is - "$.index[*][?(@.name=='const_meth')].inner.header.const" true
- // @is - "$.index[*][?(@.name=='const_meth')].inner.header.unsafe" false
+ // @is "$.index[*][?(@.name=='const_meth')].inner.header.async" false
+ // @is "$.index[*][?(@.name=='const_meth')].inner.header.const" true
+ // @is "$.index[*][?(@.name=='const_meth')].inner.header.unsafe" false
pub const fn const_meth() {}
- // @is - "$.index[*][?(@.name=='nothing_meth')].inner.header.async" false
- // @is - "$.index[*][?(@.name=='nothing_meth')].inner.header.const" false
- // @is - "$.index[*][?(@.name=='nothing_meth')].inner.header.unsafe" false
+ // @is "$.index[*][?(@.name=='nothing_meth')].inner.header.async" false
+ // @is "$.index[*][?(@.name=='nothing_meth')].inner.header.const" false
+ // @is "$.index[*][?(@.name=='nothing_meth')].inner.header.unsafe" false
pub fn nothing_meth() {}
- // @is - "$.index[*][?(@.name=='unsafe_meth')].inner.header.async" false
- // @is - "$.index[*][?(@.name=='unsafe_meth')].inner.header.const" false
- // @is - "$.index[*][?(@.name=='unsafe_meth')].inner.header.unsafe" true
+ // @is "$.index[*][?(@.name=='unsafe_meth')].inner.header.async" false
+ // @is "$.index[*][?(@.name=='unsafe_meth')].inner.header.const" false
+ // @is "$.index[*][?(@.name=='unsafe_meth')].inner.header.unsafe" true
pub unsafe fn unsafe_meth() {}
- // @is - "$.index[*][?(@.name=='async_meth')].inner.header.async" true
- // @is - "$.index[*][?(@.name=='async_meth')].inner.header.const" false
- // @is - "$.index[*][?(@.name=='async_meth')].inner.header.unsafe" false
+ // @is "$.index[*][?(@.name=='async_meth')].inner.header.async" true
+ // @is "$.index[*][?(@.name=='async_meth')].inner.header.const" false
+ // @is "$.index[*][?(@.name=='async_meth')].inner.header.unsafe" false
pub async fn async_meth() {}
- // @is - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.async" true
- // @is - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.const" false
- // @is - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.unsafe" true
+ // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.async" true
+ // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.const" false
+ // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.unsafe" true
pub async unsafe fn async_unsafe_meth() {}
- // @is - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.async" false
- // @is - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.const" true
- // @is - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.unsafe" true
+ // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.async" false
+ // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.const" true
+ // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.unsafe" true
pub const unsafe fn const_unsafe_meth() {}
// It's impossible for a method to be both const and async, so no test for that
diff --git a/src/test/rustdoc-json/nested.rs b/src/test/rustdoc-json/nested.rs
index b0e717d8a..ee2d2efa9 100644
--- a/src/test/rustdoc-json/nested.rs
+++ b/src/test/rustdoc-json/nested.rs
@@ -1,30 +1,31 @@
// edition:2018
// compile-flags: --crate-version 1.0.0
-// @is nested.json "$.crate_version" \"1.0.0\"
-// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
-// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
-// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1
+// @is "$.crate_version" \"1.0.0\"
+// @is "$.index[*][?(@.name=='nested')].kind" \"module\"
+// @is "$.index[*][?(@.name=='nested')].inner.is_crate" true
-// @is nested.json "$.index[*][?(@.name=='l1')].kind" \"module\"
-// @is - "$.index[*][?(@.name=='l1')].inner.is_crate" false
-// @count - "$.index[*][?(@.name=='l1')].inner.items[*]" 2
-pub mod l1 {
+// @set l1_id = "$.index[*][?(@.name=='l1')].id"
+// @ismany "$.index[*][?(@.name=='nested')].inner.items[*]" $l1_id
- // @is nested.json "$.index[*][?(@.name=='l3')].kind" \"module\"
- // @is - "$.index[*][?(@.name=='l3')].inner.is_crate" false
- // @count - "$.index[*][?(@.name=='l3')].inner.items[*]" 1
- // @set l3_id = - "$.index[*][?(@.name=='l3')].id"
- // @has - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id
+// @is "$.index[*][?(@.name=='l1')].kind" \"module\"
+// @is "$.index[*][?(@.name=='l1')].inner.is_crate" false
+pub mod l1 {
+ // @is "$.index[*][?(@.name=='l3')].kind" \"module\"
+ // @is "$.index[*][?(@.name=='l3')].inner.is_crate" false
+ // @set l3_id = "$.index[*][?(@.name=='l3')].id"
pub mod l3 {
- // @is nested.json "$.index[*][?(@.name=='L4')].kind" \"struct\"
- // @is - "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
- // @set l4_id = - "$.index[*][?(@.name=='L4')].id"
- // @has - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
+ // @is "$.index[*][?(@.name=='L4')].kind" \"struct\"
+ // @is "$.index[*][?(@.name=='L4')].inner.kind" \"unit\"
+ // @set l4_id = "$.index[*][?(@.name=='L4')].id"
+ // @ismany "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
pub struct L4;
}
- // @is nested.json "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
- // @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
+ // @is "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
+ // @is "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
+ // @is "$.index[*][?(@.inner.source=='l3::L4')].inner.id" $l4_id
+ // @set l4_use_id = "$.index[*][?(@.inner.source=='l3::L4')].id"
pub use l3::L4;
}
+// @ismany "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id $l4_use_id
diff --git a/src/test/rustdoc-json/output_generics.rs b/src/test/rustdoc-json/output_generics.rs
index d80656c7f..04b1a358f 100644
--- a/src/test/rustdoc-json/output_generics.rs
+++ b/src/test/rustdoc-json/output_generics.rs
@@ -2,12 +2,11 @@
// This is a regression test for #98009.
-// @has output_generics.json
-// @has - "$.index[*][?(@.name=='this_compiles')]"
-// @has - "$.index[*][?(@.name=='this_does_not')]"
-// @has - "$.index[*][?(@.name=='Events')]"
-// @has - "$.index[*][?(@.name=='Other')]"
-// @has - "$.index[*][?(@.name=='Trait')]"
+// @has "$.index[*][?(@.name=='this_compiles')]"
+// @has "$.index[*][?(@.name=='this_does_not')]"
+// @has "$.index[*][?(@.name=='Events')]"
+// @has "$.index[*][?(@.name=='Other')]"
+// @has "$.index[*][?(@.name=='Trait')]"
struct Events<R>(R);
diff --git a/src/test/rustdoc-json/primitive.rs b/src/test/rustdoc-json/primitive.rs
index b84c2f7c6..6454dd7f5 100644
--- a/src/test/rustdoc-json/primitive.rs
+++ b/src/test/rustdoc-json/primitive.rs
@@ -5,10 +5,16 @@
#[doc(primitive = "usize")]
mod usize {}
-// @set local_crate_id = primitive.json "$.index[*][?(@.name=='primitive')].crate_id"
+// @set local_crate_id = "$.index[*][?(@.name=='primitive')].crate_id"
-// @has - "$.index[*][?(@.name=='log10')]"
-// @!is - "$.index[*][?(@.name=='log10')].crate_id" $local_crate_id
-// @has - "$.index[*][?(@.name=='checked_add')]"
-// @!is - "$.index[*][?(@.name=='checked_add')]" $local_crate_id
-// @!has - "$.index[*][?(@.name=='is_ascii_uppercase')]"
+// @has "$.index[*][?(@.name=='ilog10')]"
+// @!is "$.index[*][?(@.name=='ilog10')].crate_id" $local_crate_id
+// @has "$.index[*][?(@.name=='checked_add')]"
+// @!is "$.index[*][?(@.name=='checked_add')]" $local_crate_id
+// @!has "$.index[*][?(@.name=='is_ascii_uppercase')]"
+
+// @is "$.index[*][?(@.kind=='import' && @.inner.name=='my_i32')].inner.id" null
+pub use i32 as my_i32;
+
+// @is "$.index[*][?(@.kind=='import' && @.inner.name=='u32')].inner.id" null
+pub use u32;
diff --git a/src/test/rustdoc-json/primitive_overloading.rs b/src/test/rustdoc-json/primitive_overloading.rs
index a10d5a837..56b35cd14 100644
--- a/src/test/rustdoc-json/primitive_overloading.rs
+++ b/src/test/rustdoc-json/primitive_overloading.rs
@@ -7,9 +7,8 @@
#![no_core]
-// @has primitive_overloading.json
-// @has - "$.index[*][?(@.name=='usize')]"
-// @has - "$.index[*][?(@.name=='prim')]"
+// @has "$.index[*][?(@.name=='usize')]"
+// @has "$.index[*][?(@.name=='prim')]"
#[doc(primitive = "usize")]
/// This is the built-in type `usize`.
diff --git a/src/test/rustdoc-json/primitives.rs b/src/test/rustdoc-json/primitives.rs
index fd04f04da..8024044bc 100644
--- a/src/test/rustdoc-json/primitives.rs
+++ b/src/test/rustdoc-json/primitives.rs
@@ -1,22 +1,22 @@
#![feature(never_type)]
-// @has primitives.json "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
-// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
+// @is "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
+// @is "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
pub type PrimNever = !;
-// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
-// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
+// @is "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
+// @is "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
pub type PrimStr = str;
-// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
-// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
+// @is "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
+// @is "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
pub type PrimBool = bool;
-// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
-// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
+// @is "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
+// @is "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
pub type PrimChar = char;
-// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
-// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
+// @is "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
+// @is "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
pub type PrimU8 = u8;
diff --git a/src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs b/src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs
new file mode 100644
index 000000000..f076feb71
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs
@@ -0,0 +1,11 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/100531>
+
+#![feature(no_core)]
+#![no_core]
+
+#![crate_name = "export_extern_crate_as_self"]
+
+// ignore-tidy-linelength
+
+// @is "$.index[*][?(@.kind=='module')].name" \"export_extern_crate_as_self\"
+pub extern crate self as export_extern_crate_as_self; // Must be the same name as the crate already has
diff --git a/src/test/rustdoc-json/reexport/glob_collision.rs b/src/test/rustdoc-json/reexport/glob_collision.rs
new file mode 100644
index 000000000..f91144dbf
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/glob_collision.rs
@@ -0,0 +1,28 @@
+// Regression test for https://github.com/rust-lang/rust/issues/100973
+
+#![feature(no_core)]
+#![no_core]
+
+// @set m1 = "$.index[*][?(@.name == 'm1' && @.kind == 'module')].id"
+// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.items" []
+// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.is_stripped" true
+mod m1 {
+ pub fn f() {}
+}
+// @set m2 = "$.index[*][?(@.name == 'm2' && @.kind == 'module')].id"
+// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.items" []
+// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.is_stripped" true
+mod m2 {
+ pub fn f(_: u8) {}
+}
+
+// @set m1_use = "$.index[*][?(@.inner.name=='m1')].id"
+// @is "$.index[*][?(@.inner.name=='m1')].inner.id" $m1
+// @is "$.index[*][?(@.inner.name=='m1')].inner.glob" true
+pub use m1::*;
+// @set m2_use = "$.index[*][?(@.inner.name=='m2')].id"
+// @is "$.index[*][?(@.inner.name=='m2')].inner.id" $m2
+// @is "$.index[*][?(@.inner.name=='m2')].inner.glob" true
+pub use m2::*;
+
+// @ismany "$.index[*][?(@.inner.is_crate==true)].inner.items[*]" $m1_use $m2_use
diff --git a/src/test/rustdoc-json/reexport/glob_empty_mod.rs b/src/test/rustdoc-json/reexport/glob_empty_mod.rs
new file mode 100644
index 000000000..da6822835
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/glob_empty_mod.rs
@@ -0,0 +1,8 @@
+// Regression test for https://github.com/rust-lang/rust/issues/100973
+
+// @is "$.index[*][?(@.name=='m1' && @.kind == 'module')].inner.is_stripped" true
+// @set m1 = "$.index[*][?(@.name=='m1')].id"
+mod m1 {}
+
+// @is "$.index[*][?(@.inner.name=='m1' && @.kind=='import')].inner.id" $m1
+pub use m1::*;
diff --git a/src/test/rustdoc-json/reexport/glob_extern.rs b/src/test/rustdoc-json/reexport/glob_extern.rs
index ba1cfd8a0..7a1e8c11f 100644
--- a/src/test/rustdoc-json/reexport/glob_extern.rs
+++ b/src/test/rustdoc-json/reexport/glob_extern.rs
@@ -3,16 +3,21 @@
#![no_core]
#![feature(no_core)]
-// @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
-// @is glob_extern.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+// @is "$.index[*][?(@.name=='mod1')].kind" \"module\"
+// @is "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
mod mod1 {
extern "C" {
- // @has - "$.index[*][?(@.name=='public_fn')].id"
+ // @set public_fn_id = "$.index[*][?(@.name=='public_fn')].id"
pub fn public_fn();
- // @!has - "$.index[*][?(@.name=='private_fn')]"
+ // @!has "$.index[*][?(@.name=='private_fn')]"
fn private_fn();
}
+ // @ismany "$.index[*][?(@.name=='mod1')].inner.items[*]" $public_fn_id
+ // @set mod1_id = "$.index[*][?(@.name=='mod1')].id"
}
-// @is - "$.index[*][?(@.kind=='import')].inner.glob" true
+// @is "$.index[*][?(@.kind=='import')].inner.glob" true
+// @is "$.index[*][?(@.kind=='import')].inner.id" $mod1_id
+// @set use_id = "$.index[*][?(@.kind=='import')].id"
+// @ismany "$.index[*][?(@.name=='glob_extern')].inner.items[*]" $use_id
pub use mod1::*;
diff --git a/src/test/rustdoc-json/reexport/glob_private.rs b/src/test/rustdoc-json/reexport/glob_private.rs
index e6a44748c..3a83a2081 100644
--- a/src/test/rustdoc-json/reexport/glob_private.rs
+++ b/src/test/rustdoc-json/reexport/glob_private.rs
@@ -3,30 +3,31 @@
#![no_core]
#![feature(no_core)]
-// @is glob_private.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
-// @is glob_private.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+// @is "$.index[*][?(@.name=='mod1')].kind" \"module\"
+// @is "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
mod mod1 {
- // @is - "$.index[*][?(@.name=='mod2')].kind" \"module\"
- // @is - "$.index[*][?(@.name=='mod2')].inner.is_stripped" "true"
+ // @is "$.index[*][?(@.name=='mod2')].kind" \"module\"
+ // @is "$.index[*][?(@.name=='mod2')].inner.is_stripped" "true"
mod mod2 {
- // @set m2pub_id = - "$.index[*][?(@.name=='Mod2Public')].id"
+ // @set m2pub_id = "$.index[*][?(@.name=='Mod2Public')].id"
pub struct Mod2Public;
- // @!has - "$.index[*][?(@.name=='Mod2Private')]"
+ // @!has "$.index[*][?(@.name=='Mod2Private')]"
struct Mod2Private;
}
- // @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')]"
+ // @set mod2_use_id = "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')].id"
pub use self::mod2::*;
- // @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
+ // @set m1pub_id = "$.index[*][?(@.name=='Mod1Public')].id"
pub struct Mod1Public;
- // @!has - "$.index[*][?(@.name=='Mod1Private')]"
+ // @!has "$.index[*][?(@.name=='Mod1Private')]"
struct Mod1Private;
}
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')]"
+// @set mod1_use_id = "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')].id"
pub use mod1::*;
-// @has - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
-// @has - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id
+// @ismany "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
+// @ismany "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id $mod2_use_id
+// @ismany "$.index[*][?(@.name=='glob_private')].inner.items[*]" $mod1_use_id
diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod.rs b/src/test/rustdoc-json/reexport/in_root_and_mod.rs
index 7bf10a986..7b97ebf21 100644
--- a/src/test/rustdoc-json/reexport/in_root_and_mod.rs
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod.rs
@@ -1,17 +1,16 @@
#![feature(no_core)]
#![no_core]
-// @is in_root_and_mod.json "$.index[*][?(@.name=='foo')].kind" \"module\"
-// @is in_root_and_mod.json "$.index[*][?(@.name=='foo')].inner.is_stripped" "true"
+// @!has "$.index[*][?(@.name=='foo')]"
mod foo {
- // @has - "$.index[*][?(@.name=='Foo')]"
+ // @has "$.index[*][?(@.name=='Foo')]"
pub struct Foo;
}
-// @has - "$.index[*][?(@.kind=='import' && @.inner.source=='foo::Foo')]"
+// @has "$.index[*][?(@.kind=='import' && @.inner.source=='foo::Foo')]"
pub use foo::Foo;
pub mod bar {
- // @has - "$.index[*][?(@.kind=='import' && @.inner.source=='crate::foo::Foo')]"
+ // @has "$.index[*][?(@.kind=='import' && @.inner.source=='crate::foo::Foo')]"
pub use crate::foo::Foo;
}
diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
index 2daadf762..f6d932d92 100644
--- a/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
@@ -2,19 +2,19 @@
#![no_core]
pub mod foo {
- // @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
- // @has - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
+ // @set bar_id = "$.index[*][?(@.name=='Bar')].id"
+ // @ismany "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
pub struct Bar;
}
-// @set root_import_id = - "$.index[*][?(@.inner.source=='foo::Bar')].id"
-// @is - "$.index[*][?(@.inner.source=='foo::Bar')].inner.id" $bar_id
-// @has - "$.index[*][?(@.name=='in_root_and_mod_pub')].inner.items[*]" $root_import_id
+// @set root_import_id = "$.index[*][?(@.inner.source=='foo::Bar')].id"
+// @is "$.index[*][?(@.inner.source=='foo::Bar')].inner.id" $bar_id
+// @has "$.index[*][?(@.name=='in_root_and_mod_pub')].inner.items[*]" $root_import_id
pub use foo::Bar;
pub mod baz {
- // @set baz_import_id = - "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
- // @is - "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
- // @has - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
+ // @set baz_import_id = "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
+ // @is "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
+ // @ismany "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
pub use crate::foo::Bar;
}
diff --git a/src/test/rustdoc-json/reexport/macro.rs b/src/test/rustdoc-json/reexport/macro.rs
index b86614ffb..b4882100f 100644
--- a/src/test/rustdoc-json/reexport/macro.rs
+++ b/src/test/rustdoc-json/reexport/macro.rs
@@ -3,15 +3,13 @@
#![no_core]
#![feature(no_core)]
-// @count macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" 2
-
-// @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
-// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id
+// @set repro_id = "$.index[*][?(@.name=='repro')].id"
#[macro_export]
macro_rules! repro {
() => {};
}
-// @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
-// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro2_id
+// @set repro2_id = "$.index[*][?(@.inner.name=='repro2')].id"
pub use crate::repro as repro2;
+
+// @ismany "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id $repro2_id
diff --git a/src/test/rustdoc-json/reexport/mod_not_included.rs b/src/test/rustdoc-json/reexport/mod_not_included.rs
new file mode 100644
index 000000000..7b7600ef2
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/mod_not_included.rs
@@ -0,0 +1,14 @@
+// Regression test for https://github.com/rust-lang/rust/issues/101103
+
+#![feature(no_core)]
+#![no_core]
+
+mod m1 {
+ pub fn x() {}
+}
+
+pub use m1::x;
+
+// @has "$.index[*][?(@.name=='x' && @.kind=='function')]"
+// @has "$.index[*][?(@.kind=='import' && @.inner.name=='x')].inner.source" '"m1::x"'
+// @!has "$.index[*][?(@.name=='m1')]"
diff --git a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
index 327b0f45f..687a3b2ac 100644
--- a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
+++ b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
@@ -1,18 +1,28 @@
// aux-build:pub-struct.rs
+// ignore-tidy-linelength
-// Test for the ICE in rust/83057
-// Am external type re-exported with different attributes shouldn't cause an error
+// Test for the ICE in https://github.com/rust-lang/rust/issues/83057
+// An external type re-exported with different attributes shouldn't cause an error
#![no_core]
#![feature(no_core)]
extern crate pub_struct as foo;
-
#[doc(inline)]
+
+// @set crate_use_id = "$.index[*][?(@.docs=='Hack A')].id"
+// @set foo_id = "$.index[*][?(@.docs=='Hack A')].inner.id"
+/// Hack A
pub use foo::Foo;
+// @set bar_id = "$.index[*][?(@.name=='bar')].id"
pub mod bar {
+ // @is "$.index[*][?(@.docs=='Hack B')].inner.id" $foo_id
+ // @set bar_use_id = "$.index[*][?(@.docs=='Hack B')].id"
+ // @ismany "$.index[*][?(@.name=='bar')].inner.items[*]" $bar_use_id
+ /// Hack B
pub use foo::Foo;
}
-// @count private_twice_one_inline.json "$.index[*][?(@.kind=='import')]" 2
+// @ismany "$.index[*][?(@.kind=='import')].id" $crate_use_id $bar_use_id
+// @ismany "$.index[*][?(@.name=='private_twice_one_inline')].inner.items[*]" $bar_id $crate_use_id
diff --git a/src/test/rustdoc-json/reexport/private_two_names.rs b/src/test/rustdoc-json/reexport/private_two_names.rs
index 36d6a50d3..9858538a9 100644
--- a/src/test/rustdoc-json/reexport/private_two_names.rs
+++ b/src/test/rustdoc-json/reexport/private_two_names.rs
@@ -1,17 +1,22 @@
-// Test for the ICE in rust/83720
+// ignore-tidy-linelength
+
+// Test for the ICE in https://github.com/rust-lang/rust/issues/83720
// A pub-in-private type re-exported under two different names shouldn't cause an error
#![no_core]
#![feature(no_core)]
-// @is private_two_names.json "$.index[*][?(@.name=='style')].kind" \"module\"
-// @is private_two_names.json "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
+// @!has "$.index[*][?(@.name=='style')]"
mod style {
- // @has - "$.index[*](?(@.name=='Color'))"
+ // @set color_struct_id = "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
pub struct Color;
}
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')]"
+// @is "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].inner.id" $color_struct_id
+// @set color_export_id = "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].id"
pub use style::Color;
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')]"
+// @is "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].inner.id" $color_struct_id
+// @set colour_export_id = "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].id"
pub use style::Color as Colour;
+
+// @ismany "$.index[*][?(@.name=='private_two_names')].inner.items[*]" $color_export_id $colour_export_id
diff --git a/src/test/rustdoc-json/reexport/rename_private.rs b/src/test/rustdoc-json/reexport/rename_private.rs
index 2476399bd..8fd850f9b 100644
--- a/src/test/rustdoc-json/reexport/rename_private.rs
+++ b/src/test/rustdoc-json/reexport/rename_private.rs
@@ -3,12 +3,11 @@
#![no_core]
#![feature(no_core)]
-// @is rename_private.json "$.index[*][?(@.name=='inner')].kind" \"module\"
-// @is rename_private.json "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
+// @!has "$.index[*][?(@.kind=='inner')]"
mod inner {
- // @has - "$.index[*][?(@.name=='Public')]"
+ // @has "$.index[*][?(@.name=='Public')]"
pub struct Public;
}
-// @is - "$.index[*][?(@.kind=='import')].inner.name" \"NewName\"
+// @is "$.index[*][?(@.kind=='import')].inner.name" \"NewName\"
pub use inner::Public as NewName;
diff --git a/src/test/rustdoc-json/reexport/rename_public.rs b/src/test/rustdoc-json/reexport/rename_public.rs
index 2dd438d22..e30907fe2 100644
--- a/src/test/rustdoc-json/reexport/rename_public.rs
+++ b/src/test/rustdoc-json/reexport/rename_public.rs
@@ -3,15 +3,15 @@
#![no_core]
#![feature(no_core)]
-// @set inner_id = rename_public.json "$.index[*][?(@.name=='inner')].id"
-// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id
+// @set inner_id = "$.index[*][?(@.name=='inner')].id"
pub mod inner {
- // @set public_id = - "$.index[*][?(@.name=='Public')].id"
- // @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+ // @set public_id = "$.index[*][?(@.name=='Public')].id"
+ // @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
pub struct Public;
}
-// @set import_id = - "$.index[*][?(@.inner.name=='NewName')].id"
-// @!has - "$.index[*][?(@.inner.name=='Public')]"
-// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $import_id
-// @is - "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
+// @set import_id = "$.index[*][?(@.inner.name=='NewName')].id"
+// @!has "$.index[*][?(@.inner.name=='Public')]"
+// @is "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
pub use inner::Public as NewName;
+
+// @ismany "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id $import_id
diff --git a/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
index eedddd6a7..880dbdc44 100644
--- a/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
+++ b/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
@@ -1,15 +1,21 @@
+// ignore-tidy-linelength
+
// Regression test for <https://github.com/rust-lang/rust/issues/97432>.
#![feature(no_core)]
#![no_std]
#![no_core]
-// @has same_type_reexported_more_than_once.json
-// @has - "$.index[*][?(@.name=='Trait')]"
-pub use inner::Trait;
-// @has - "$.index[*].inner[?(@.name=='Reexport')].id"
-pub use inner::Trait as Reexport;
-
mod inner {
+ // @set trait_id = "$.index[*][?(@.name=='Trait')].id"
pub trait Trait {}
}
+
+// @set export_id = "$.index[*][?(@.inner.name=='Trait')].id"
+// @is "$.index[*][?(@.inner.name=='Trait')].inner.id" $trait_id
+pub use inner::Trait;
+// @set reexport_id = "$.index[*][?(@.inner.name=='Reexport')].id"
+// @is "$.index[*][?(@.inner.name=='Reexport')].inner.id" $trait_id
+pub use inner::Trait as Reexport;
+
+// @ismany "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.items[*]" $reexport_id $export_id
diff --git a/src/test/rustdoc-json/reexport/simple_private.rs b/src/test/rustdoc-json/reexport/simple_private.rs
index 5ec13e403..d058ce059 100644
--- a/src/test/rustdoc-json/reexport/simple_private.rs
+++ b/src/test/rustdoc-json/reexport/simple_private.rs
@@ -2,14 +2,15 @@
#![no_core]
#![feature(no_core)]
-// @is simple_private.json "$.index[*][?(@.name=='inner')].kind" \"module\"
-// @is simple_private.json "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
+// @!has "$.index[*][?(@.name=='inner')]"
mod inner {
- // @set pub_id = - "$.index[*][?(@.name=='Public')].id"
+ // @set pub_id = "$.index[*][?(@.name=='Public')].id"
pub struct Public;
}
-// @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
+// @is "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
+// @is "$.index[*][?(@.kind=='import')].inner.id" $pub_id
+// @set use_id = "$.index[*][?(@.kind=='import')].id"
pub use inner::Public;
-// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
+// @ismany "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id
diff --git a/src/test/rustdoc-json/reexport/simple_public.rs b/src/test/rustdoc-json/reexport/simple_public.rs
index 2e4de301f..e64a0dcb7 100644
--- a/src/test/rustdoc-json/reexport/simple_public.rs
+++ b/src/test/rustdoc-json/reexport/simple_public.rs
@@ -3,16 +3,16 @@
#![no_core]
#![feature(no_core)]
-// @set inner_id = simple_public.json "$.index[*][?(@.name=='inner')].id"
-// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $inner_id
+// @set inner_id = "$.index[*][?(@.name=='inner')].id"
pub mod inner {
- // @set public_id = - "$.index[*][?(@.name=='Public')].id"
- // @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+ // @set public_id = "$.index[*][?(@.name=='Public')].id"
+ // @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
pub struct Public;
}
-// @set import_id = - "$.index[*][?(@.inner.name=='Public')].id"
-// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id
-// @is - "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
+// @set import_id = "$.index[*][?(@.inner.name=='Public')].id"
+// @is "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
pub use inner::Public;
+
+// @ismany "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id $inner_id
diff --git a/src/test/rustdoc-json/return_private.rs b/src/test/rustdoc-json/return_private.rs
index 6b324d009..a8d1fae30 100644
--- a/src/test/rustdoc-json/return_private.rs
+++ b/src/test/rustdoc-json/return_private.rs
@@ -8,8 +8,8 @@ mod secret {
pub struct Secret;
}
-// @is return_private.json "$.index[*][?(@.name=='get_secret')].kind" \"function\"
-// @is return_private.json "$.index[*][?(@.name=='get_secret')].inner.decl.output.inner.name" \"secret::Secret\"
+// @is "$.index[*][?(@.name=='get_secret')].kind" \"function\"
+// @is "$.index[*][?(@.name=='get_secret')].inner.decl.output.inner.name" \"secret::Secret\"
pub fn get_secret() -> secret::Secret {
secret::Secret
}
diff --git a/src/test/rustdoc-json/stripped_modules.rs b/src/test/rustdoc-json/stripped_modules.rs
index 91f9f02ad..d2664b49e 100644
--- a/src/test/rustdoc-json/stripped_modules.rs
+++ b/src/test/rustdoc-json/stripped_modules.rs
@@ -1,20 +1,20 @@
#![no_core]
#![feature(no_core)]
-// @!has stripped_modules.json "$.index[*][?(@.name=='no_pub_inner')]"
+// @!has "$.index[*][?(@.name=='no_pub_inner')]"
mod no_pub_inner {
fn priv_inner() {}
}
-// @!has - "$.index[*][?(@.name=='pub_inner_unreachable')]"
+// @!has "$.index[*][?(@.name=='pub_inner_unreachable')]"
mod pub_inner_unreachable {
- // @!has - "$.index[*][?(@.name=='pub_inner_1')]"
+ // @!has "$.index[*][?(@.name=='pub_inner_1')]"
pub fn pub_inner_1() {}
}
-// @has - "$.index[*][?(@.name=='pub_inner_reachable')]"
+// @!has "$.index[*][?(@.name=='pub_inner_reachable')]"
mod pub_inner_reachable {
- // @has - "$.index[*][?(@.name=='pub_inner_2')]"
+ // @has "$.index[*][?(@.name=='pub_inner_2')]"
pub fn pub_inner_2() {}
}
diff --git a/src/test/rustdoc-json/structs/plain_all_pub.rs b/src/test/rustdoc-json/structs/plain_all_pub.rs
new file mode 100644
index 000000000..b86ab93c2
--- /dev/null
+++ b/src/test/rustdoc-json/structs/plain_all_pub.rs
@@ -0,0 +1,11 @@
+pub struct Demo {
+ pub x: i32,
+ pub y: i32,
+}
+
+// @set x = "$.index[*][?(@.name=='x')].id"
+// @set y = "$.index[*][?(@.name=='y')].id"
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[1]" $y
+// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 2
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" false
diff --git a/src/test/rustdoc-json/structs/plain_doc_hidden.rs b/src/test/rustdoc-json/structs/plain_doc_hidden.rs
new file mode 100644
index 000000000..7800b55a4
--- /dev/null
+++ b/src/test/rustdoc-json/structs/plain_doc_hidden.rs
@@ -0,0 +1,11 @@
+pub struct Demo {
+ pub x: i32,
+ #[doc(hidden)]
+ pub y: i32,
+}
+
+// @set x = "$.index[*][?(@.name=='x')].id"
+// @!has "$.index[*][?(@.name=='y')].id"
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
+// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 1
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" true
diff --git a/src/test/rustdoc-json/structs/plain_empty.rs b/src/test/rustdoc-json/structs/plain_empty.rs
index a251caf4b..1d01b8bc1 100644
--- a/src/test/rustdoc-json/structs/plain_empty.rs
+++ b/src/test/rustdoc-json/structs/plain_empty.rs
@@ -1,6 +1,5 @@
-// @has plain_empty.json "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='PlainEmpty')].kind" \"struct\"
-// @has - "$.index[*][?(@.name=='PlainEmpty')].inner.struct_type" \"plain\"
-// @has - "$.index[*][?(@.name=='PlainEmpty')].inner.fields_stripped" false
-// @has - "$.index[*][?(@.name=='PlainEmpty')].inner.fields" []
+// @is "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='PlainEmpty')].kind" \"struct\"
+// @is "$.index[*][?(@.name=='PlainEmpty')].inner.kind.plain.fields_stripped" false
+// @is "$.index[*][?(@.name=='PlainEmpty')].inner.kind.plain.fields" []
pub struct PlainEmpty {}
diff --git a/src/test/rustdoc-json/structs/plain_pub_priv.rs b/src/test/rustdoc-json/structs/plain_pub_priv.rs
new file mode 100644
index 000000000..9b771224d
--- /dev/null
+++ b/src/test/rustdoc-json/structs/plain_pub_priv.rs
@@ -0,0 +1,9 @@
+pub struct Demo {
+ pub x: i32,
+ y: i32,
+}
+
+// @set x = "$.index[*][?(@.name=='x')].id"
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
+// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 1
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" true
diff --git a/src/test/rustdoc-json/structs/tuple.rs b/src/test/rustdoc-json/structs/tuple.rs
index 4e510b398..6bdb753ee 100644
--- a/src/test/rustdoc-json/structs/tuple.rs
+++ b/src/test/rustdoc-json/structs/tuple.rs
@@ -1,5 +1,4 @@
-// @has tuple.json "$.index[*][?(@.name=='Tuple')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='Tuple')].kind" \"struct\"
-// @has - "$.index[*][?(@.name=='Tuple')].inner.struct_type" \"tuple\"
-// @has - "$.index[*][?(@.name=='Tuple')].inner.fields_stripped" true
+// @is "$.index[*][?(@.name=='Tuple')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='Tuple')].kind" \"struct\"
+// @is "$.index[*][?(@.name=='Tuple')].inner.kind.tuple" '[null, null]'
pub struct Tuple(u32, String);
diff --git a/src/test/rustdoc-json/structs/tuple_empty.rs b/src/test/rustdoc-json/structs/tuple_empty.rs
new file mode 100644
index 000000000..0ad6a8954
--- /dev/null
+++ b/src/test/rustdoc-json/structs/tuple_empty.rs
@@ -0,0 +1,2 @@
+// @is "$.index[*][?(@.name=='TupleUnit')].inner.kind.tuple" []
+pub struct TupleUnit();
diff --git a/src/test/rustdoc-json/structs/tuple_pub_priv.rs b/src/test/rustdoc-json/structs/tuple_pub_priv.rs
new file mode 100644
index 000000000..9d5a1d1c8
--- /dev/null
+++ b/src/test/rustdoc-json/structs/tuple_pub_priv.rs
@@ -0,0 +1,13 @@
+pub struct Demo(
+ i32,
+ /// field
+ pub i32,
+ #[doc(hidden)] i32,
+);
+
+// @set field = "$.index[*][?(@.docs=='field')].id"
+
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.tuple[0]" null
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.tuple[1]" $field
+// @is "$.index[*][?(@.name=='Demo')].inner.kind.tuple[2]" null
+// @count "$.index[*][?(@.name=='Demo')].inner.kind.tuple[*]" 3
diff --git a/src/test/rustdoc-json/structs/unit.rs b/src/test/rustdoc-json/structs/unit.rs
index 559d3068d..265709717 100644
--- a/src/test/rustdoc-json/structs/unit.rs
+++ b/src/test/rustdoc-json/structs/unit.rs
@@ -1,5 +1,4 @@
-// @has unit.json "$.index[*][?(@.name=='Unit')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='Unit')].kind" \"struct\"
-// @has - "$.index[*][?(@.name=='Unit')].inner.struct_type" \"unit\"
-// @has - "$.index[*][?(@.name=='Unit')].inner.fields" []
+// @is "$.index[*][?(@.name=='Unit')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='Unit')].kind" \"struct\"
+// @is "$.index[*][?(@.name=='Unit')].inner.kind" \"unit\"
pub struct Unit;
diff --git a/src/test/rustdoc-json/structs/with_generics.rs b/src/test/rustdoc-json/structs/with_generics.rs
index 65cfe7eff..00474800a 100644
--- a/src/test/rustdoc-json/structs/with_generics.rs
+++ b/src/test/rustdoc-json/structs/with_generics.rs
@@ -1,13 +1,13 @@
use std::collections::HashMap;
-// @has with_generics.json "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='WithGenerics')].kind" \"struct\"
-// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].name" \"T\"
-// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].kind.type"
-// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].name" \"U\"
-// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].kind.type"
-// @has - "$.index[*][?(@.name=='WithGenerics')].inner.struct_type" \"plain\"
-// @has - "$.index[*][?(@.name=='WithGenerics')].inner.fields_stripped" true
+// @is "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='WithGenerics')].kind" \"struct\"
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].name" \"T\"
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].kind.type.bounds" []
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].name" \"U\"
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].kind.type.bounds" []
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.kind.plain.fields_stripped" true
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.kind.plain.fields" []
pub struct WithGenerics<T, U> {
stuff: Vec<T>,
things: HashMap<U, U>,
diff --git a/src/test/rustdoc-json/structs/with_primitives.rs b/src/test/rustdoc-json/structs/with_primitives.rs
index 9e64317ec..9c5a37f39 100644
--- a/src/test/rustdoc-json/structs/with_primitives.rs
+++ b/src/test/rustdoc-json/structs/with_primitives.rs
@@ -1,9 +1,9 @@
-// @has with_primitives.json "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\"
-// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\"
-// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" []
-// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.struct_type" \"plain\"
-// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.fields_stripped" true
+// @is "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\"
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" []
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.kind.plain.fields_stripped" true
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.kind.plain.fields" []
pub struct WithPrimitives<'a> {
num: u32,
s: &'a str,
diff --git a/src/test/rustdoc-json/traits/has_body.rs b/src/test/rustdoc-json/traits/has_body.rs
index 44dacb1ee..a57cb97d4 100644
--- a/src/test/rustdoc-json/traits/has_body.rs
+++ b/src/test/rustdoc-json/traits/has_body.rs
@@ -1,21 +1,21 @@
-// @has has_body.json "$.index[*][?(@.name=='Foo')]"
+// @has "$.index[*][?(@.name=='Foo')]"
pub trait Foo {
- // @has - "$.index[*][?(@.name=='no_self')].inner.has_body" false
+ // @is "$.index[*][?(@.name=='no_self')].inner.has_body" false
fn no_self();
- // @has - "$.index[*][?(@.name=='move_self')].inner.has_body" false
+ // @is "$.index[*][?(@.name=='move_self')].inner.has_body" false
fn move_self(self);
- // @has - "$.index[*][?(@.name=='ref_self')].inner.has_body" false
+ // @is "$.index[*][?(@.name=='ref_self')].inner.has_body" false
fn ref_self(&self);
- // @has - "$.index[*][?(@.name=='no_self_def')].inner.has_body" true
+ // @is "$.index[*][?(@.name=='no_self_def')].inner.has_body" true
fn no_self_def() {}
- // @has - "$.index[*][?(@.name=='move_self_def')].inner.has_body" true
+ // @is "$.index[*][?(@.name=='move_self_def')].inner.has_body" true
fn move_self_def(self) {}
- // @has - "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true
+ // @is "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true
fn ref_self_def(&self) {}
}
pub trait Bar: Clone {
- // @has - "$.index[*][?(@.name=='method')].inner.has_body" false
+ // @is "$.index[*][?(@.name=='method')].inner.has_body" false
fn method(&self, param: usize);
}
diff --git a/src/test/rustdoc-json/traits/implementors.rs b/src/test/rustdoc-json/traits/implementors.rs
index f7f03d987..db3fe5df7 100644
--- a/src/test/rustdoc-json/traits/implementors.rs
+++ b/src/test/rustdoc-json/traits/implementors.rs
@@ -1,19 +1,19 @@
#![feature(no_core)]
#![no_core]
-// @set wham = implementors.json "$.index[*][?(@.name=='Wham')].id"
-// @count - "$.index[*][?(@.name=='Wham')].inner.implementations[*]" 1
-// @set gmWham = - "$.index[*][?(@.name=='Wham')].inner.implementations[0]"
+// @set wham = "$.index[*][?(@.name=='Wham')].id"
+// @count "$.index[*][?(@.name=='Wham')].inner.implementations[*]" 1
+// @set gmWham = "$.index[*][?(@.name=='Wham')].inner.implementations[0]"
pub trait Wham {}
-// @count - "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[*]" 1
-// @is - "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[0]" $gmWham
-// @set gm = - "$.index[*][?(@.name=='Wham')].id"
+// @count "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[*]" 1
+// @is "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[0]" $gmWham
+// @set gm = "$.index[*][?(@.name=='Wham')].id"
// jsonpath_lib isnt expressive enough (for now) to get the "impl" item, so we
// just check it isn't pointing to the type, but when you port to jsondocck-ng
// check what the impl item is
-// @!is - "$.index[*][?(@.name=='Wham')].inner.implementations[0]" $gm
+// @!is "$.index[*][?(@.name=='Wham')].inner.implementations[0]" $gm
pub struct GeorgeMichael {}
impl Wham for GeorgeMichael {}
diff --git a/src/test/rustdoc-json/traits/supertrait.rs b/src/test/rustdoc-json/traits/supertrait.rs
index 486a8e713..4048fdd74 100644
--- a/src/test/rustdoc-json/traits/supertrait.rs
+++ b/src/test/rustdoc-json/traits/supertrait.rs
@@ -4,23 +4,23 @@
#![feature(lang_items)]
#![no_core]
-// @set loud_id = supertrait.json "$.index[*][?(@.name=='Loud')].id"
+// @set loud_id = "$.index[*][?(@.name=='Loud')].id"
pub trait Loud {}
-// @set very_loud_id = - "$.index[*][?(@.name=='VeryLoud')].id"
-// @count - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.inner.id" $loud_id
+// @set very_loud_id = "$.index[*][?(@.name=='VeryLoud')].id"
+// @count "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
+// @is "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.id" $loud_id
pub trait VeryLoud: Loud {}
-// @set sounds_good_id = - "$.index[*][?(@.name=='SoundsGood')].id"
+// @set sounds_good_id = "$.index[*][?(@.name=='SoundsGood')].id"
pub trait SoundsGood {}
-// @count - "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
-// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.inner.id" $very_loud_id
-// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.inner.id" $sounds_good_id
+// @count "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
+// @is "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.id" $very_loud_id
+// @is "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.id" $sounds_good_id
pub trait MetalBand: VeryLoud + SoundsGood {}
-// @count - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
-// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.inner.id" $very_loud_id
-// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.inner.id" $sounds_good_id
+// @count "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
+// @is "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.id" $very_loud_id
+// @is "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.id" $sounds_good_id
pub trait DnabLatem: SoundsGood + VeryLoud {}
diff --git a/src/test/rustdoc-json/traits/uses_extern_trait.rs b/src/test/rustdoc-json/traits/uses_extern_trait.rs
new file mode 100644
index 000000000..430dd1543
--- /dev/null
+++ b/src/test/rustdoc-json/traits/uses_extern_trait.rs
@@ -0,0 +1,7 @@
+#![no_std]
+pub fn drop_default<T: core::default::Default>(_x: T) {}
+
+// FIXME(adotinthevoid): Theses shouldn't be here
+// @has "$.index[*][?(@.name=='Debug')]"
+// @set Debug_fmt = "$.index[*][?(@.name=='Debug')].inner.items[*]"
+// @has "$.index[*][?(@.name=='fmt')].id" $Debug_fmt
diff --git a/src/test/rustdoc-json/type/dyn.rs b/src/test/rustdoc-json/type/dyn.rs
index f53dc03f4..eaf249252 100644
--- a/src/test/rustdoc-json/type/dyn.rs
+++ b/src/test/rustdoc-json/type/dyn.rs
@@ -1,21 +1,46 @@
// ignore-tidy-linelength
+use std::fmt::Debug;
-// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items" 1
-// @set sync_int_gen = - "$.index[*][?(@.name=='SyncIntGen')].id"
-// @is - "$.index[*][?(@.name=='dyn')].inner.items[0]" $sync_int_gen
+// @count "$.index[*][?(@.name=='dyn')].inner.items[*]" 3
+// @set sync_int_gen = "$.index[*][?(@.name=='SyncIntGen')].id"
+// @set ref_fn = "$.index[*][?(@.name=='RefFn')].id"
+// @set weird_order = "$.index[*][?(@.name=='WeirdOrder')].id"
+// @ismany "$.index[*][?(@.name=='dyn')].inner.items[*]" $sync_int_gen $ref_fn $weird_order
-// @is - "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}'
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.kind" \"resolved_path\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.name" \"Box\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.bindings" []
-// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args" 1
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.name" \"Fn\"
-// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[*]" 3
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[0].trait_bound.trait.inner.name" \"Send\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[1].trait_bound.trait.inner.name" \"Sync\"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[2]" "{\"outlives\": \"'static\"}"
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
+// @is "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\"
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}'
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.kind" \"resolved_path\"
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.name" \"Box\"
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.bindings" []
+// @count "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args" 1
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"dyn_trait\"
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.lifetime" \"\'static\"
+// @count "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[*]" 3
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].generic_params" []
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].generic_params" []
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].generic_params" []
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Fn"'
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Send"'
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.name" '"Sync"'
+// @is "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>;
+
+// @is "$.index[*][?(@.name=='RefFn')].kind" \"typedef\"
+// @is "$.index[*][?(@.name=='RefFn')].inner.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.mutable" 'false'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.lifetime" "\"'a\""
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.kind" '"dyn_trait"'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.lifetime" null
+// @count "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[*]" 1
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.name" '"Fn"'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].inner.lifetime" "\"'b\""
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.inner.lifetime" "\"'b\""
+pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32;
+
+// @is "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Send"'
+// @is "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Debug"'
+pub type WeirdOrder = Box<dyn Send + Debug>;
diff --git a/src/test/rustdoc-json/type/extern.rs b/src/test/rustdoc-json/type/extern.rs
new file mode 100644
index 000000000..d287d5ebe
--- /dev/null
+++ b/src/test/rustdoc-json/type/extern.rs
@@ -0,0 +1,10 @@
+#![feature(extern_types)]
+
+extern {
+ /// No inner information
+ pub type Foo;
+}
+
+// @is "$.index[*][?(@.docs=='No inner information')].name" '"Foo"'
+// @is "$.index[*][?(@.docs=='No inner information')].kind" '"foreign_type"'
+// @!has "$.index[*][?(@.docs=='No inner information')].inner"
diff --git a/src/test/rustdoc-json/type/fn_lifetime.rs b/src/test/rustdoc-json/type/fn_lifetime.rs
index e0d1e9649..d7216ec76 100644
--- a/src/test/rustdoc-json/type/fn_lifetime.rs
+++ b/src/test/rustdoc-json/type/fn_lifetime.rs
@@ -1,28 +1,27 @@
// ignore-tidy-linelength
-// @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
+// @is "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
-// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*]" 1
-// @is - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
-// @has - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
-// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
-// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
-// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.kind" \"function_pointer\"
-// @count - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.generic_params[*]" 0
-// @count - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*]" 1
-// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
-// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
+// @ismany "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
+// @has "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
+// @count "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
+// @count "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
+// @is "$.index[*][?(@.name=='GenericFn')].inner.type.kind" \"function_pointer\"
+// @count "$.index[*][?(@.name=='GenericFn')].inner.type.inner.generic_params[*]" 0
+// @count "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
pub type GenericFn<'a> = fn(&'a i32) -> &'a i32;
-// @is fn_lifetime.json "$.index[*][?(@.name=='ForAll')].kind" \"typedef\"
-// @count - "$.index[*][?(@.name=='ForAll')].inner.generics.params[*]" 0
-// @count - "$.index[*][?(@.name=='ForAll')].inner.generics.where_predicates[*]" 0
-// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*]" 1
-// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].name" \"\'a\"
-// @has - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime"
-// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime.outlives[*]" 0
-// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*]" 1
-// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
-// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='ForAll')].kind" \"typedef\"
+// @count "$.index[*][?(@.name=='ForAll')].inner.generics.params[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.generics.where_predicates[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].name" \"\'a\"
+// @has "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime"
+// @count "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime.outlives[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
pub type ForAll = for<'a> fn(&'a i32) -> &'a i32;
diff --git a/src/test/rustdoc-json/type/generic_default.rs b/src/test/rustdoc-json/type/generic_default.rs
index b6bb6dcc5..9c6d4540b 100644
--- a/src/test/rustdoc-json/type/generic_default.rs
+++ b/src/test/rustdoc-json/type/generic_default.rs
@@ -1,33 +1,33 @@
// ignore-tidy-linelength
-// @set result = generic_default.json "$.index[*][?(@.name=='Result')].id"
+// @set result = "$.index[*][?(@.name=='Result')].id"
pub enum Result<T, E> {
Ok(T),
Err(E),
}
-// @set my_error = - "$.index[*][?(@.name=='MyError')].id"
+// @set my_error = "$.index[*][?(@.name=='MyError')].id"
pub struct MyError {}
-// @is - "$.index[*][?(@.name=='MyResult')].kind" \"typedef\"
-// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.where_predicates[*]" 0
-// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[*]" 2
-// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].name" \"T\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].name" \"E\"
-// @has - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type"
-// @has - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type"
-// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.bounds[*]" 0
-// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.bounds[*]" 0
-// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.default" null
-// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.kind" \"resolved_path\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.id" $my_error
-// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.name" \"MyError\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.kind" \"resolved_path\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.id" $result
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.name" \"Result\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.bindings" []
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"generic\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.kind" \"generic\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.inner" \"T\"
-// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.inner" \"E\"
+// @is "$.index[*][?(@.name=='MyResult')].kind" \"typedef\"
+// @count "$.index[*][?(@.name=='MyResult')].inner.generics.where_predicates[*]" 0
+// @count "$.index[*][?(@.name=='MyResult')].inner.generics.params[*]" 2
+// @is "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].name" \"T\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].name" \"E\"
+// @has "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type"
+// @has "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type"
+// @count "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.bounds[*]" 0
+// @count "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.bounds[*]" 0
+// @is "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.default" null
+// @is "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.kind" \"resolved_path\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.id" $my_error
+// @is "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.name" \"MyError\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.kind" \"resolved_path\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.id" $result
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.name" \"Result\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.bindings" []
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"generic\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.kind" \"generic\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.inner" \"T\"
+// @is "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.inner" \"E\"
pub type MyResult<T, E = MyError> = Result<T, E>;
diff --git a/src/test/rustdoc-json/type/hrtb.rs b/src/test/rustdoc-json/type/hrtb.rs
new file mode 100644
index 000000000..2c4ee00d4
--- /dev/null
+++ b/src/test/rustdoc-json/type/hrtb.rs
@@ -0,0 +1,24 @@
+// ignore-tidy-linelength
+
+// @is "$.index[*][?(@.name=='genfn')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F","kind": "generic"}'
+// @is "$.index[*][?(@.name=='genfn')].inner.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+pub fn genfn<F>(f: F)
+where
+ for<'a, 'b> F: Fn(&'a i32, &'b i32),
+{
+ let zero = 0;
+ f(&zero, &zero);
+}
+
+// @is "$.index[*][?(@.name=='dynfn')].inner.generics" '{"params": [], "where_predicates": []}'
+// @is "$.index[*][?(@.name=='dynfn')].inner.generics" '{"params": [], "where_predicates": []}'
+// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.kind" '"dyn_trait"'
+// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.lifetime" null
+// @count "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[*]" 1
+// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.name" '"Fn"'
+pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) {
+ let zero = 0;
+ f(&zero, &zero);
+}
diff --git a/src/test/rustdoc-json/unions/impl.rs b/src/test/rustdoc-json/unions/impl.rs
index 0388b4a8c..4454a69ec 100644
--- a/src/test/rustdoc-json/unions/impl.rs
+++ b/src/test/rustdoc-json/unions/impl.rs
@@ -1,15 +1,15 @@
#![no_std]
-// @has impl.json "$.index[*][?(@.name=='Ux')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='Ux')].kind" \"union\"
+// @is "$.index[*][?(@.name=='Ux')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='Ux')].kind" \"union\"
pub union Ux {
a: u32,
b: u64
}
-// @has - "$.index[*][?(@.name=='Num')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='Num')].kind" \"trait\"
+// @is "$.index[*][?(@.name=='Num')].visibility" \"public\"
+// @is "$.index[*][?(@.name=='Num')].kind" \"trait\"
pub trait Num {}
-// @count - "$.index[*][?(@.name=='Ux')].inner.impls" 1
+// @count "$.index[*][?(@.name=='Ux')].inner.impls" 1
impl Num for Ux {}
diff --git a/src/test/rustdoc-json/unions/union.rs b/src/test/rustdoc-json/unions/union.rs
index ac2eb7977..c9df2b81c 100644
--- a/src/test/rustdoc-json/unions/union.rs
+++ b/src/test/rustdoc-json/unions/union.rs
@@ -1,7 +1,15 @@
-// @has union.json "$.index[*][?(@.name=='Union')].visibility" \"public\"
-// @has - "$.index[*][?(@.name=='Union')].kind" \"union\"
-// @!has - "$.index[*][?(@.name=='Union')].inner.struct_type"
+// @has "$.index[*][?(@.name=='Union')].visibility" \"public\"
+// @has "$.index[*][?(@.name=='Union')].kind" \"union\"
+// @!has "$.index[*][?(@.name=='Union')].inner.struct_type"
+// @set Union = "$.index[*][?(@.name=='Union')].id"
pub union Union {
int: i32,
float: f32,
}
+
+
+// @is "$.index[*][?(@.name=='make_int_union')].inner.decl.output.kind" '"resolved_path"'
+// @is "$.index[*][?(@.name=='make_int_union')].inner.decl.output.inner.id" $Union
+pub fn make_int_union(int: i32) -> Union {
+ Union { int }
+}
diff --git a/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs
index 2355d6a3d..c5e1759ee 100644
--- a/src/test/rustdoc-ui/check-fail.rs
+++ b/src/test/rustdoc-ui/check-fail.rs
@@ -1,5 +1,6 @@
// compile-flags: -Z unstable-options --check
+#![feature(rustdoc_missing_doc_code_examples)]
#![deny(missing_docs)]
#![deny(rustdoc::all)]
diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr
index 5d46dc720..217b89d93 100644
--- a/src/test/rustdoc-ui/check-fail.stderr
+++ b/src/test/rustdoc-ui/check-fail.stderr
@@ -1,30 +1,30 @@
error: missing documentation for a function
- --> $DIR/check-fail.rs:11:1
+ --> $DIR/check-fail.rs:12:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/check-fail.rs:3:9
+ --> $DIR/check-fail.rs:4:9
|
LL | #![deny(missing_docs)]
| ^^^^^^^^^^^^
error: missing code example in this documentation
- --> $DIR/check-fail.rs:11:1
+ --> $DIR/check-fail.rs:12:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/check-fail.rs:4:9
+ --> $DIR/check-fail.rs:5:9
|
LL | #![deny(rustdoc::all)]
| ^^^^^^^^^^^^
= note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]`
error: unknown attribute `testharness`. Did you mean `test_harness`?
- --> $DIR/check-fail.rs:6:1
+ --> $DIR/check-fail.rs:7:1
|
LL | / //! ```rust,testharness
LL | |
@@ -36,7 +36,7 @@ LL | | //! ```
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: unknown attribute `testharness`. Did you mean `test_harness`?
- --> $DIR/check-fail.rs:15:1
+ --> $DIR/check-fail.rs:16:1
|
LL | / /// hello
LL | |
diff --git a/src/test/rustdoc-ui/check.rs b/src/test/rustdoc-ui/check.rs
index 2b44ba24b..f70b03361 100644
--- a/src/test/rustdoc-ui/check.rs
+++ b/src/test/rustdoc-ui/check.rs
@@ -2,9 +2,11 @@
// compile-flags: -Z unstable-options --check
// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
-#![warn(missing_docs)]
+#![feature(rustdoc_missing_doc_code_examples)]
//~^ WARN
//~^^ WARN
+
+#![warn(missing_docs)]
#![warn(rustdoc::all)]
pub fn foo() {}
diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr
index 06e607fbe..78ae65d31 100644
--- a/src/test/rustdoc-ui/check.stderr
+++ b/src/test/rustdoc-ui/check.stderr
@@ -1,22 +1,23 @@
warning: missing documentation for the crate
--> $DIR/check.rs:5:1
|
-LL | / #![warn(missing_docs)]
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
LL | |
LL | |
-LL | | #![warn(rustdoc::all)]
+LL | |
+... |
LL | |
LL | | pub fn foo() {}
| |_______________^
|
note: the lint level is defined here
- --> $DIR/check.rs:5:9
+ --> $DIR/check.rs:9:9
|
LL | #![warn(missing_docs)]
| ^^^^^^^^^^^^
warning: missing documentation for a function
- --> $DIR/check.rs:10:1
+ --> $DIR/check.rs:12:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | pub fn foo() {}
warning: no documentation found for this crate's top-level module
|
note: the lint level is defined here
- --> $DIR/check.rs:8:9
+ --> $DIR/check.rs:10:9
|
LL | #![warn(rustdoc::all)]
| ^^^^^^^^^^^^
@@ -35,10 +36,11 @@ LL | #![warn(rustdoc::all)]
warning: missing code example in this documentation
--> $DIR/check.rs:5:1
|
-LL | / #![warn(missing_docs)]
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | |
LL | |
LL | |
-LL | | #![warn(rustdoc::all)]
+... |
LL | |
LL | | pub fn foo() {}
| |_______________^
@@ -46,7 +48,7 @@ LL | | pub fn foo() {}
= note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]`
warning: missing code example in this documentation
- --> $DIR/check.rs:10:1
+ --> $DIR/check.rs:12:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.rs b/src/test/rustdoc-ui/doc-without-codeblock.rs
index 315fca195..86d7c83d3 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.rs
+++ b/src/test/rustdoc-ui/doc-without-codeblock.rs
@@ -1,4 +1,5 @@
-#![deny(rustdoc::missing_doc_code_examples)] //~ ERROR missing code example in this documentation
+#![feature(rustdoc_missing_doc_code_examples)] //~ ERROR missing code example in this documentation
+#![deny(rustdoc::missing_doc_code_examples)]
/// Some docs.
//~^ ERROR missing code example in this documentation
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr
index 1c1380441..ebf2a2d54 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.stderr
+++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr
@@ -1,35 +1,35 @@
error: missing code example in this documentation
--> $DIR/doc-without-codeblock.rs:1:1
|
-LL | / #![deny(rustdoc::missing_doc_code_examples)]
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | | #![deny(rustdoc::missing_doc_code_examples)]
LL | |
LL | | /// Some docs.
-LL | |
... |
LL | | }
LL | | }
| |_^
|
note: the lint level is defined here
- --> $DIR/doc-without-codeblock.rs:1:9
+ --> $DIR/doc-without-codeblock.rs:2:9
|
LL | #![deny(rustdoc::missing_doc_code_examples)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing code example in this documentation
- --> $DIR/doc-without-codeblock.rs:7:1
+ --> $DIR/doc-without-codeblock.rs:8:1
|
LL | /// And then, the princess died.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing code example in this documentation
- --> $DIR/doc-without-codeblock.rs:10:5
+ --> $DIR/doc-without-codeblock.rs:11:5
|
LL | /// Or maybe not because she saved herself!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing code example in this documentation
- --> $DIR/doc-without-codeblock.rs:3:1
+ --> $DIR/doc-without-codeblock.rs:4:1
|
LL | /// Some docs.
| ^^^^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs
new file mode 100644
index 000000000..daba69868
--- /dev/null
+++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs
@@ -0,0 +1,10 @@
+#![deny(unknown_lints)]
+//~^ NOTE defined here
+
+#![allow(rustdoc::missing_doc_code_examples)]
+//~^ ERROR unknown lint
+//~| ERROR unknown lint
+//~| NOTE lint is unstable
+//~| NOTE lint is unstable
+//~| NOTE see issue
+//~| NOTE see issue
diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
new file mode 100644
index 000000000..517e08aa7
--- /dev/null
+++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
@@ -0,0 +1,29 @@
+error: unknown lint: `rustdoc::missing_doc_code_examples`
+ --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1
+ |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9
+ |
+LL | #![deny(unknown_lints)]
+ | ^^^^^^^^^^^^^
+ = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+ = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+ = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
+
+error: unknown lint: `rustdoc::missing_doc_code_examples`
+ --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1
+ |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+ = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+ = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
+
+error: Compilation failed, aborting rustdoc
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
index d280e6497..bb8572eae 100644
--- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator `bar`
--> $DIR/unknown-disambiguator.rs:4:35
@@ -18,7 +18,7 @@ error: unknown disambiguator `bar`
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:10:34
@@ -26,7 +26,7 @@ error: unknown disambiguator `foo`
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:10:48
@@ -34,7 +34,7 @@ error: unknown disambiguator `foo`
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator ``
--> $DIR/unknown-disambiguator.rs:7:31
@@ -42,7 +42,7 @@ error: unknown disambiguator ``
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
| ^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator ``
--> $DIR/unknown-disambiguator.rs:7:57
@@ -50,7 +50,7 @@ error: unknown disambiguator ``
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
| ^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: aborting due to 6 previous errors
diff --git a/src/test/rustdoc-ui/invalid-html-tags.rs b/src/test/rustdoc-ui/invalid-html-tags.rs
index 0f9d2e4b3..317f1fd1d 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.rs
+++ b/src/test/rustdoc-ui/invalid-html-tags.rs
@@ -114,3 +114,10 @@ pub fn k() {}
/// Web Components style </unopened-tag>
//~^ ERROR unopened HTML tag `unopened-tag`
pub fn m() {}
+
+/// backslashed \<a href="">
+pub fn no_error_1() {}
+
+/// backslashed \<<a href="">
+//~^ ERROR unclosed HTML tag `a`
+pub fn p() {}
diff --git a/src/test/rustdoc-ui/invalid-html-tags.stderr b/src/test/rustdoc-ui/invalid-html-tags.stderr
index 24a455576..9c2bfcf2c 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.stderr
+++ b/src/test/rustdoc-ui/invalid-html-tags.stderr
@@ -94,5 +94,11 @@ error: unclosed HTML tag `dashed-tags`
LL | /// Web Components style <dashed-tags>
| ^^^^^^^^^^^^^
-error: aborting due to 15 previous errors
+error: unclosed HTML tag `a`
+ --> $DIR/invalid-html-tags.rs:121:19
+ |
+LL | /// backslashed \<<a href="">
+ | ^^
+
+error: aborting due to 16 previous errors
diff --git a/src/test/rustdoc-ui/issue-101076.rs b/src/test/rustdoc-ui/issue-101076.rs
new file mode 100644
index 000000000..648f99029
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-101076.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+const _: () = {
+ #[macro_export]
+ macro_rules! first_macro {
+ () => {}
+ }
+ mod foo {
+ #[macro_export]
+ macro_rules! second_macro {
+ () => {}
+ }
+ }
+};
diff --git a/src/test/rustdoc-ui/lint-group.rs b/src/test/rustdoc-ui/lint-group.rs
index 61555a6e6..09aca6d2b 100644
--- a/src/test/rustdoc-ui/lint-group.rs
+++ b/src/test/rustdoc-ui/lint-group.rs
@@ -1,3 +1,5 @@
+#![feature(rustdoc_missing_doc_code_examples)]
+
//! Documenting the kinds of lints emitted by rustdoc.
//!
//! ```
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr
index e28600160..5336c0445 100644
--- a/src/test/rustdoc-ui/lint-group.stderr
+++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -1,18 +1,18 @@
error: missing code example in this documentation
- --> $DIR/lint-group.rs:16:1
+ --> $DIR/lint-group.rs:18:1
|
LL | /// wait, this doesn't have a doctest?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/lint-group.rs:7:9
+ --> $DIR/lint-group.rs:9:9
|
LL | #![deny(rustdoc::all)]
| ^^^^^^^^^^^^
= note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]`
error: documentation test in private item
- --> $DIR/lint-group.rs:19:1
+ --> $DIR/lint-group.rs:21:1
|
LL | / /// wait, this *does* have a doctest?
LL | | ///
@@ -24,13 +24,13 @@ LL | | /// ```
= note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]`
error: missing code example in this documentation
- --> $DIR/lint-group.rs:26:1
+ --> $DIR/lint-group.rs:28:1
|
LL | /// <unknown>
| ^^^^^^^^^^^^^
error: unresolved link to `error`
- --> $DIR/lint-group.rs:9:29
+ --> $DIR/lint-group.rs:11:29
|
LL | /// what up, let's make an [error]
| ^^^^^ no item named `error` in scope
@@ -39,7 +39,7 @@ LL | /// what up, let's make an [error]
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unclosed HTML tag `unknown`
- --> $DIR/lint-group.rs:26:5
+ --> $DIR/lint-group.rs:28:5
|
LL | /// <unknown>
| ^^^^^^^^^
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
index fac6342cd..40f35728d 100644
--- a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
@@ -1,3 +1,4 @@
+#![feature(rustdoc_missing_doc_code_examples)]
#![deny(missing_docs)]
#![deny(rustdoc::missing_doc_code_examples)]
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
index 9e51ecd2b..f93312501 100644
--- a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
@@ -1,35 +1,35 @@
error: missing code example in this documentation
- --> $DIR/lint-missing-doc-code-example.rs:19:1
+ --> $DIR/lint-missing-doc-code-example.rs:20:1
|
LL | pub mod module1 {
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/lint-missing-doc-code-example.rs:2:9
+ --> $DIR/lint-missing-doc-code-example.rs:3:9
|
LL | #![deny(rustdoc::missing_doc_code_examples)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing code example in this documentation
- --> $DIR/lint-missing-doc-code-example.rs:37:3
+ --> $DIR/lint-missing-doc-code-example.rs:38:3
|
LL | /// doc
| ^^^^^^^
error: missing code example in this documentation
- --> $DIR/lint-missing-doc-code-example.rs:49:1
+ --> $DIR/lint-missing-doc-code-example.rs:50:1
|
LL | /// Doc
| ^^^^^^^
error: missing code example in this documentation
- --> $DIR/lint-missing-doc-code-example.rs:56:1
+ --> $DIR/lint-missing-doc-code-example.rs:57:1
|
LL | /// Doc
| ^^^^^^^
error: missing code example in this documentation
- --> $DIR/lint-missing-doc-code-example.rs:63:1
+ --> $DIR/lint-missing-doc-code-example.rs:64:1
|
LL | /// Doc
| ^^^^^^^
diff --git a/src/test/rustdoc-ui/normalize-cycle.rs b/src/test/rustdoc-ui/normalize-cycle.rs
index f48cad373..14ffac1e1 100644
--- a/src/test/rustdoc-ui/normalize-cycle.rs
+++ b/src/test/rustdoc-ui/normalize-cycle.rs
@@ -1,5 +1,5 @@
// check-pass
-// Regresion test for <https://github.com/rust-lang/rust/issues/79459>.
+// Regression test for <https://github.com/rust-lang/rust/issues/79459>.
pub trait Query {}
pub trait AsQuery {
diff --git a/src/test/rustdoc-ui/rustc-check-passes.rs b/src/test/rustdoc-ui/rustc-check-passes.rs
index 731cc8ba6..56d59164d 100644
--- a/src/test/rustdoc-ui/rustc-check-passes.rs
+++ b/src/test/rustdoc-ui/rustc-check-passes.rs
@@ -1,4 +1,4 @@
-#![feature(box_syntax)]
-#![feature(box_syntax)] //~ ERROR
+#![feature(rustdoc_internals)]
+#![feature(rustdoc_internals)] //~ ERROR
pub fn foo() {}
diff --git a/src/test/rustdoc-ui/rustc-check-passes.stderr b/src/test/rustdoc-ui/rustc-check-passes.stderr
index 9707895ff..83f4e87c6 100644
--- a/src/test/rustdoc-ui/rustc-check-passes.stderr
+++ b/src/test/rustdoc-ui/rustc-check-passes.stderr
@@ -1,8 +1,8 @@
-error[E0636]: the feature `box_syntax` has already been declared
+error[E0636]: the feature `rustdoc_internals` has already been declared
--> $DIR/rustc-check-passes.rs:2:12
|
-LL | #![feature(box_syntax)]
- | ^^^^^^^^^^
+LL | #![feature(rustdoc_internals)]
+ | ^^^^^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs
index 744b3071f..476e3b2d4 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs
@@ -8,6 +8,48 @@ pub struct ConstGeneric;
// HTML tags cannot contain commas, so no error.
pub struct MultipleGenerics;
+/// This <[u32] as Iterator<Item>> thing!
+//~^ERROR unclosed HTML tag `Item`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+//
+// The important part is that we don't produce any *wrong* suggestions.
+// While several other examples below are added to make sure we don't
+// produce suggestions when given complex paths, this example is the actual
+// reason behind not just using the real path parser. It's ambiguous: there's
+// no way to locally reason out whether that `[u32]` is intended to be a slice
+// or an intra-doc link.
+pub struct FullyQualifiedPathsDoNotCount;
+
+/// This <Vec as IntoIter>::Iter thing!
+//~^ERROR unclosed HTML tag `Vec`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount1;
+
+/// This Vec<Vec as IntoIter>::Iter thing!
+//~^ERROR unclosed HTML tag `Vec`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount2;
+
+/// This Vec<Vec as IntoIter> thing!
+//~^ERROR unclosed HTML tag `Vec`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount3;
+
+/// This Vec<Vec<i32> as IntoIter> thing!
+//~^ERROR unclosed HTML tag `i32`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount4;
+
/// This Vec<i32 class="test"> thing!
//~^ERROR unclosed HTML tag `i32`
// HTML attributes shouldn't be treated as Rust syntax, so no suggestions.
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr
index 832b8b2ca..3856a2513 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr
@@ -1,8 +1,8 @@
-error: unclosed HTML tag `i32`
- --> $DIR/html-as-generics-no-suggestions.rs:11:13
+error: unclosed HTML tag `Item`
+ --> $DIR/html-as-generics-no-suggestions.rs:11:28
|
-LL | /// This Vec<i32 class="test"> thing!
- | ^^^^
+LL | /// This <[u32] as Iterator<Item>> thing!
+ | ^^^^^^
|
note: the lint level is defined here
--> $DIR/html-as-generics-no-suggestions.rs:1:9
@@ -10,29 +10,59 @@ note: the lint level is defined here
LL | #![deny(rustdoc::invalid_html_tags)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
+error: unclosed HTML tag `Vec`
+ --> $DIR/html-as-generics-no-suggestions.rs:25:10
+ |
+LL | /// This <Vec as IntoIter>::Iter thing!
+ | ^^^^
+
+error: unclosed HTML tag `Vec`
+ --> $DIR/html-as-generics-no-suggestions.rs:32:13
+ |
+LL | /// This Vec<Vec as IntoIter>::Iter thing!
+ | ^^^^
+
+error: unclosed HTML tag `Vec`
+ --> $DIR/html-as-generics-no-suggestions.rs:39:13
+ |
+LL | /// This Vec<Vec as IntoIter> thing!
+ | ^^^^
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics-no-suggestions.rs:46:17
+ |
+LL | /// This Vec<Vec<i32> as IntoIter> thing!
+ | ^^^^^
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics-no-suggestions.rs:53:13
+ |
+LL | /// This Vec<i32 class="test"> thing!
+ | ^^^^
+
error: unopened HTML tag `i32`
- --> $DIR/html-as-generics-no-suggestions.rs:20:13
+ --> $DIR/html-as-generics-no-suggestions.rs:62:13
|
LL | /// This Vec</i32> thing!
| ^^^^^^
error: unclosed HTML tag `i32`
- --> $DIR/html-as-generics-no-suggestions.rs:25:13
+ --> $DIR/html-as-generics-no-suggestions.rs:67:13
|
LL | /// This 123<i32> thing!
| ^^^^^
error: unclosed HTML tag `i32`
- --> $DIR/html-as-generics-no-suggestions.rs:30:14
+ --> $DIR/html-as-generics-no-suggestions.rs:72:14
|
LL | /// This Vec:<i32> thing!
| ^^^^^
error: unclosed HTML tag `i32`
- --> $DIR/html-as-generics-no-suggestions.rs:35:39
+ --> $DIR/html-as-generics-no-suggestions.rs:77:39
|
LL | /// This [link](https://rust-lang.org)<i32> thing!
| ^^^^^
-error: aborting due to 5 previous errors
+error: aborting due to 10 previous errors
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed
index c0a0de24c..07c8c9ff2 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed
@@ -30,3 +30,43 @@ pub struct BareTurbofish;
//~^ERROR unclosed HTML tag `i32`
//~|HELP try marking as source
pub struct Nested;
+
+/// Nested generics `Vec<Vec<u32>>`
+//~^ ERROR unclosed HTML tag `u32`
+//~|HELP try marking as source
+pub struct NestedGenerics;
+
+/// Generics with path `Vec<i32>::Iter`
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct GenericsWithPath;
+
+/// Generics with path `<Vec<i32>>::Iter`
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath;
+
+/// Generics with path `Vec<Vec<i32>>::Iter`
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath2;
+
+/// Generics with bump `<Vec<i32>>`s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump;
+
+/// Generics with bump `Vec<Vec<i32>>`s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump2;
+
+/// Generics with punct `<Vec<i32>>`!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct;
+
+/// Generics with punct `Vec<Vec<i32>>`!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct2;
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.rs b/src/test/rustdoc-ui/suggestions/html-as-generics.rs
index 0b6009b0e..cdd652f39 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics.rs
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics.rs
@@ -30,3 +30,43 @@ pub struct BareTurbofish;
//~^ERROR unclosed HTML tag `i32`
//~|HELP try marking as source
pub struct Nested;
+
+/// Nested generics Vec<Vec<u32>>
+//~^ ERROR unclosed HTML tag `u32`
+//~|HELP try marking as source
+pub struct NestedGenerics;
+
+/// Generics with path Vec<i32>::Iter
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct GenericsWithPath;
+
+/// Generics with path <Vec<i32>>::Iter
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath;
+
+/// Generics with path Vec<Vec<i32>>::Iter
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath2;
+
+/// Generics with bump <Vec<i32>>s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump;
+
+/// Generics with bump Vec<Vec<i32>>s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump2;
+
+/// Generics with punct <Vec<i32>>!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct;
+
+/// Generics with punct Vec<Vec<i32>>!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct2;
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr
index df54b7126..211dd4210 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr
@@ -69,5 +69,93 @@ help: try marking as source code
LL | /// This <span>`Vec::<i32>`</span> thing!
| + +
-error: aborting due to 6 previous errors
+error: unclosed HTML tag `u32`
+ --> $DIR/html-as-generics.rs:34:28
+ |
+LL | /// Nested generics Vec<Vec<u32>>
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Nested generics `Vec<Vec<u32>>`
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:39:27
+ |
+LL | /// Generics with path Vec<i32>::Iter
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with path `Vec<i32>::Iter`
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:44:28
+ |
+LL | /// Generics with path <Vec<i32>>::Iter
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with path `<Vec<i32>>::Iter`
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:49:31
+ |
+LL | /// Generics with path Vec<Vec<i32>>::Iter
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with path `Vec<Vec<i32>>::Iter`
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:54:28
+ |
+LL | /// Generics with bump <Vec<i32>>s
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with bump `<Vec<i32>>`s
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:59:31
+ |
+LL | /// Generics with bump Vec<Vec<i32>>s
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with bump `Vec<Vec<i32>>`s
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:64:29
+ |
+LL | /// Generics with punct <Vec<i32>>!
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with punct `<Vec<i32>>`!
+ | + +
+
+error: unclosed HTML tag `i32`
+ --> $DIR/html-as-generics.rs:69:32
+ |
+LL | /// Generics with punct Vec<Vec<i32>>!
+ | ^^^^^
+ |
+help: try marking as source code
+ |
+LL | /// Generics with punct `Vec<Vec<i32>>`!
+ | + +
+
+error: aborting due to 14 previous errors
diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout
index 6dc412315..749abe364 100644
--- a/src/test/rustdoc-ui/z-help.stdout
+++ b/src/test/rustdoc-ui/z-help.stdout
@@ -38,6 +38,7 @@
-Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
-Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes)
-Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries
+ -Z extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no)
-Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
-Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
-Z fuel=val -- set the optimization fuel quota for a crate
@@ -53,6 +54,7 @@
-Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
-Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
-Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
+ -Z inline-llvm=val -- enable LLVM inlining (default: yes)
-Z inline-mir=val -- enable MIR inlining (default: no)
-Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
-Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
@@ -96,6 +98,7 @@
-Z oom=val -- panic strategy for out-of-memory handling
-Z osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
-Z diagnostic-width=val -- set the current output width for diagnostic truncation
+ -Z packed-bundled-libs=val -- change rlib format to store native libraries as archives
-Z panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
-Z panic-in-drop=val -- panic strategy for panics in drops
-Z parse-only=val -- parse only; do not compile, assemble, or link (default: no)
diff --git a/src/test/rustdoc/all.rs b/src/test/rustdoc/all.rs
index a95d6c462..4c8d02310 100644
--- a/src/test/rustdoc/all.rs
+++ b/src/test/rustdoc/all.rs
@@ -24,5 +24,5 @@ mod private_module {
}
// @has foo/all.html '//a[@href="struct.ReexportedStruct.html"]' 'ReexportedStruct'
-// @!has foo/all.html 'private_module'
+// @!hasraw foo/all.html 'private_module'
pub use private_module::ReexportedStruct;
diff --git a/src/test/rustdoc/anchors.no_const_anchor.html b/src/test/rustdoc/anchors.no_const_anchor.html
index 98f47e530..4da1ffead 100644
--- a/src/test/rustdoc/anchors.no_const_anchor.html
+++ b/src/test/rustdoc/anchors.no_const_anchor.html
@@ -1 +1 @@
-<div id="associatedconstant.YOLO" class="method has-srclink"><div class="rightside"><a class="srclink" href="../src/foo/anchors.rs.html#16">source</a></div><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></div>
+<div id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></div> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_const_anchor2.html b/src/test/rustdoc/anchors.no_const_anchor2.html
index 6d37e8e5e..c00251976 100644
--- a/src/test/rustdoc/anchors.no_const_anchor2.html
+++ b/src/test/rustdoc/anchors.no_const_anchor2.html
@@ -1 +1 @@
-<section id="associatedconstant.X" class="associatedconstant has-srclink"><span class="rightside"><a class="srclink" href="../src/foo/anchors.rs.html#42">source</a></span><h4 class="code-header">pub const <a href="#associatedconstant.X" class="constant">X</a>: <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a> = 0i32</h4></section>
+<section id="associatedconstant.X" class="associatedconstant has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#42">source</a><h4 class="code-header">pub const <a href="#associatedconstant.X" class="constant">X</a>: <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a> = 0i32</h4></section> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_method_anchor.html b/src/test/rustdoc/anchors.no_method_anchor.html
index f46d3090e..521fdcb78 100644
--- a/src/test/rustdoc/anchors.no_method_anchor.html
+++ b/src/test/rustdoc/anchors.no_method_anchor.html
@@ -1 +1 @@
-<section id="method.new" class="method has-srclink"><span class="rightside"><a class="srclink" href="../src/foo/anchors.rs.html#48">source</a></span><h4 class="code-header">pub fn <a href="#method.new" class="fnname">new</a>() -&gt; Self</h4></section> \ No newline at end of file
+<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fnname">new</a>() -&gt; Self</h4></section> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_trait_method_anchor.html b/src/test/rustdoc/anchors.no_trait_method_anchor.html
index 445a7bb56..6b78c7c81 100644
--- a/src/test/rustdoc/anchors.no_trait_method_anchor.html
+++ b/src/test/rustdoc/anchors.no_trait_method_anchor.html
@@ -1 +1 @@
-<div id="method.bar" class="method has-srclink"><div class="rightside"><a class="srclink" href="../src/foo/anchors.rs.html#23">source</a></div><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></div> \ No newline at end of file
+<div id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></div> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_tymethod_anchor.html b/src/test/rustdoc/anchors.no_tymethod_anchor.html
index bb0771b10..c08f4427c 100644
--- a/src/test/rustdoc/anchors.no_tymethod_anchor.html
+++ b/src/test/rustdoc/anchors.no_tymethod_anchor.html
@@ -1 +1 @@
-<div id="tymethod.foo" class="method has-srclink"><div class="rightside"><a class="srclink" href="../src/foo/anchors.rs.html#20">source</a></div><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></div> \ No newline at end of file
+<div id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></div> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_type_anchor.html b/src/test/rustdoc/anchors.no_type_anchor.html
index d317eb500..ba8e65443 100644
--- a/src/test/rustdoc/anchors.no_type_anchor.html
+++ b/src/test/rustdoc/anchors.no_type_anchor.html
@@ -1 +1 @@
-<div id="associatedtype.T" class="method has-srclink"><div class="rightside"><a class="srclink" href="../src/foo/anchors.rs.html#13">source</a></div><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></div> \ No newline at end of file
+<div id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></div> \ No newline at end of file
diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs
index a79e93145..97b7739b4 100644
--- a/src/test/rustdoc/assoc-consts.rs
+++ b/src/test/rustdoc/assoc-consts.rs
@@ -5,7 +5,7 @@ pub trait Foo {
const FOO: usize = 12 + 1;
// @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
const FOO_NO_DEFAULT: bool;
- // @!has - FOO_HIDDEN
+ // @!hasraw - FOO_HIDDEN
#[doc(hidden)]
const FOO_HIDDEN: u8 = 0;
}
@@ -18,7 +18,7 @@ impl Foo for Bar {
const FOO: usize = 12;
// @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
const FOO_NO_DEFAULT: bool = false;
- // @!has - FOO_HIDDEN
+ // @!hasraw - FOO_HIDDEN
#[doc(hidden)]
const FOO_HIDDEN: u8 = 0;
}
@@ -50,9 +50,9 @@ impl Bar {
}
impl Bar {
- // @!has assoc_consts/struct.Bar.html 'BAR_PRIVATE'
+ // @!hasraw assoc_consts/struct.Bar.html 'BAR_PRIVATE'
const BAR_PRIVATE: char = 'a';
- // @!has assoc_consts/struct.Bar.html 'BAR_HIDDEN'
+ // @!hasraw assoc_consts/struct.Bar.html 'BAR_HIDDEN'
#[doc(hidden)]
pub const BAR_HIDDEN: &'static str = "a";
}
diff --git a/src/test/rustdoc/auxiliary/incoherent-impl-types.rs b/src/test/rustdoc/auxiliary/incoherent-impl-types.rs
new file mode 100644
index 000000000..fc51e42e5
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/incoherent-impl-types.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_has_incoherent_inherent_impls]
+pub trait FooTrait {}
+
+#[rustc_has_incoherent_inherent_impls]
+pub struct FooStruct;
diff --git a/src/test/rustdoc/cfg_doc_reexport.rs b/src/test/rustdoc/cfg_doc_reexport.rs
new file mode 100644
index 000000000..addb6709d
--- /dev/null
+++ b/src/test/rustdoc/cfg_doc_reexport.rs
@@ -0,0 +1,33 @@
+#![feature(doc_cfg)]
+#![feature(no_core)]
+
+#![crate_name = "foo"]
+#![no_core]
+
+// @has 'foo/index.html'
+// @has - '//*[@class="item-left module-item"]/*[@class="stab portability"]' 'foobar'
+// @has - '//*[@class="item-left module-item"]/*[@class="stab portability"]' 'bar'
+
+#[doc(cfg(feature = "foobar"))]
+mod imp_priv {
+ // @has 'foo/struct.BarPriv.html'
+ // @has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
+ // 'Available on crate feature foobar only.'
+ pub struct BarPriv {}
+ impl BarPriv {
+ pub fn test() {}
+ }
+}
+#[doc(cfg(feature = "foobar"))]
+pub use crate::imp_priv::*;
+
+pub mod bar {
+ // @has 'foo/bar/struct.Bar.html'
+ // @has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
+ // 'Available on crate feature bar only.'
+ #[doc(cfg(feature = "bar"))]
+ pub struct Bar;
+}
+
+#[doc(cfg(feature = "bar"))]
+pub use bar::Bar;
diff --git a/src/test/rustdoc/check-source-code-urls-to-def-std.rs b/src/test/rustdoc/check-source-code-urls-to-def-std.rs
index 3396b234a..e12d8445f 100644
--- a/src/test/rustdoc/check-source-code-urls-to-def-std.rs
+++ b/src/test/rustdoc/check-source-code-urls-to-def-std.rs
@@ -9,7 +9,7 @@ fn babar() {}
// @has - '//a[@href="{{channel}}/std/primitive.u32.html"]' 'u32'
// @has - '//a[@href="{{channel}}/std/primitive.str.html"]' 'str'
// @has - '//a[@href="{{channel}}/std/primitive.bool.html"]' 'bool'
-// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def-std.rs.html#7"]' 'babar'
+// @has - '//a[@href="#7"]' 'babar'
pub fn foo(a: u32, b: &str, c: String) {
let x = 12;
let y: bool = true;
@@ -31,12 +31,12 @@ macro_rules! data {
pub fn another_foo() {
// This is known limitation: if the macro doesn't generate anything, the visitor
// can't find any item or anything that could tell us that it comes from expansion.
- // @!has - '//a[@href="../../src/foo/check-source-code-urls-to-def-std.rs.html#19"]' 'yolo!'
+ // @!has - '//a[@href="#19"]' 'yolo!'
yolo!();
// @has - '//a[@href="{{channel}}/std/macro.eprintln.html"]' 'eprintln!'
eprintln!();
- // @has - '//a[@href="../../src/foo/check-source-code-urls-to-def-std.rs.html#27-29"]' 'data!'
+ // @has - '//a[@href="#27-29"]' 'data!'
let x = data!(4);
- // @has - '//a[@href="../../src/foo/check-source-code-urls-to-def-std.rs.html#23-25"]' 'bar!'
+ // @has - '//a[@href="#23-25"]' 'bar!'
bar!(x);
}
diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs
index ec44e1bc6..d00a3e355 100644
--- a/src/test/rustdoc/check-source-code-urls-to-def.rs
+++ b/src/test/rustdoc/check-source-code-urls-to-def.rs
@@ -10,14 +10,14 @@ extern crate source_code;
// @has 'src/foo/check-source-code-urls-to-def.rs.html'
-// @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#1-17"]' 'bar'
+// @has - '//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar'
#[path = "auxiliary/source-code-bar.rs"]
pub mod bar;
-// @count - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#5"]' 4
+// @count - '//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4
use bar::Bar;
-// @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#13"]' 'self'
-// @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14"]' 'Trait'
+// @has - '//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self'
+// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait'
use bar::sub::{self, Trait};
pub struct Foo;
@@ -31,26 +31,26 @@ fn babar() {}
// @has - '//a/@href' '/struct.String.html'
// @has - '//a/@href' '/primitive.u32.html'
// @has - '//a/@href' '/primitive.str.html'
-// @count - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#23"]' 5
+// @count - '//a[@href="#23"]' 5
// @has - '//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) {
let x = 12;
let y: Foo = Foo;
let z: Bar = bar::Bar { field: Foo };
babar();
- // @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#26"]' 'hello'
+ // @has - '//a[@href="#26"]' 'hello'
y.hello();
}
-// @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait'
-// @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14"]' 'Trait'
+// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait'
+// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait'
pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V, b: bool) {}
pub trait AnotherTrait {}
pub trait WhyNot {}
-// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#49"]' 'AnotherTrait'
-// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#50"]' 'WhyNot'
+// @has - '//a[@href="#49"]' 'AnotherTrait'
+// @has - '//a[@href="#50"]' 'WhyNot'
pub fn foo3<T, V>(t: &T, v: &V)
where
T: AnotherTrait,
@@ -59,7 +59,7 @@ where
pub trait AnotherTrait2 {}
-// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#60"]' 'AnotherTrait2'
+// @has - '//a[@href="#60"]' 'AnotherTrait2'
pub fn foo4() {
let x: Vec<AnotherTrait2> = Vec::new();
}
diff --git a/src/test/rustdoc/codeblock-title.rs b/src/test/rustdoc/codeblock-title.rs
index 140c5b3a6..b9b0b0d1a 100644
--- a/src/test/rustdoc/codeblock-title.rs
+++ b/src/test/rustdoc/codeblock-title.rs
@@ -1,8 +1,8 @@
#![crate_name = "foo"]
-// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]' "ⓘ"
-// @has foo/fn.bar.html '//*[@class="tooltip ignore"]' "ⓘ"
-// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]' "ⓘ"
+// @has foo/fn.bar.html '//*[@class="example-wrap compile_fail"]/*[@class="tooltip"]' "ⓘ"
+// @has foo/fn.bar.html '//*[@class="example-wrap ignore"]/*[@class="tooltip"]' "ⓘ"
+// @has foo/fn.bar.html '//*[@class="example-wrap should_panic"]/*[@class="tooltip"]' "ⓘ"
// @has foo/fn.bar.html '//*[@data-edition="2018"]' "ⓘ"
/// foo
diff --git a/src/test/rustdoc/const-display.rs b/src/test/rustdoc/const-display.rs
index 8455dd9ef..594501b22 100644
--- a/src/test/rustdoc/const-display.rs
+++ b/src/test/rustdoc/const-display.rs
@@ -20,7 +20,7 @@ pub const fn foo() -> u32 { 42 }
pub const unsafe fn foo_unsafe() -> u32 { 42 }
// @has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
#[unstable(feature = "humans", issue = "none")]
pub const fn foo2() -> u32 { 42 }
@@ -32,7 +32,7 @@ pub const fn bar2() -> u32 { 42 }
// @has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
#[unstable(feature = "foo2", issue = "none")]
pub const unsafe fn foo2_gated() -> u32 { 42 }
@@ -43,7 +43,7 @@ pub const unsafe fn foo2_gated() -> u32 { 42 }
pub const unsafe fn bar2_gated() -> u32 { 42 }
// @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
pub const unsafe fn bar_not_gated() -> u32 { 42 }
pub struct Foo;
diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs
index 352a8e646..87d2f29e2 100644
--- a/src/test/rustdoc/const-generics/const-generics-docs.rs
+++ b/src/test/rustdoc/const-generics/const-generics-docs.rs
@@ -31,12 +31,12 @@ impl Trait<{1 + 2}> for u8 {}
impl<const N: usize> Trait<N> for [u8; N] {}
// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
-// 'pub struct Foo<const N: usize> where u8: Trait<N>'
+// 'pub struct Foo<const N: usize>where u8: Trait<N>'
pub struct Foo<const N: usize> where u8: Trait<N>;
// @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
pub struct Bar<T, const N: usize>([T; N]);
-// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
+// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M>where u8: Trait<M>'
impl<const M: usize> Foo<M> where u8: Trait<M> {
// @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
pub const FOO_ASSOC: usize = M + 13;
@@ -50,14 +50,14 @@ impl<const M: usize> Foo<M> where u8: Trait<M> {
// @has foo/struct.Bar.html '//*[@id="impl-Bar%3Cu8%2C%20M%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
impl<const M: usize> Bar<u8, M> {
// @has - '//*[@id="method.hey"]' \
- // 'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'
+ // 'pub fn hey<const N: usize>(&self) -> Foo<N>where u8: Trait<N>'
pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N> {
Foo
}
}
// @has foo/fn.test.html '//pre[@class="rust fn"]' \
-// 'pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N>'
+// 'pub fn test<const N: usize>() -> impl Trait<N>where u8: Trait<N>'
pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
2u8
}
diff --git a/src/test/rustdoc/deprecated-impls.rs b/src/test/rustdoc/deprecated-impls.rs
index efd250ce9..e419d2631 100644
--- a/src/test/rustdoc/deprecated-impls.rs
+++ b/src/test/rustdoc/deprecated-impls.rs
@@ -5,8 +5,8 @@ pub struct Foo0;
impl Foo0 {
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.1: fn_with_doc'
- // @has - 'fn_with_doc short'
- // @has - 'fn_with_doc full'
+ // @hasraw - 'fn_with_doc short'
+ // @hasraw - 'fn_with_doc full'
/// fn_with_doc short
///
/// fn_with_doc full
@@ -52,8 +52,8 @@ pub struct Foo1;
impl Bar for Foo1 {
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
- // @has - 'fn_empty_with_doc_impl short'
- // @has - 'fn_empty_with_doc_impl full'
+ // @hasraw - 'fn_empty_with_doc_impl short'
+ // @hasraw - 'fn_empty_with_doc_impl full'
/// fn_empty_with_doc_impl short
///
/// fn_empty_with_doc_impl full
@@ -63,8 +63,8 @@ impl Bar for Foo1 {
fn fn_empty_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
- // @has - 'fn_def_with_doc_impl short'
- // @has - 'fn_def_with_doc_impl full'
+ // @hasraw - 'fn_def_with_doc_impl short'
+ // @hasraw - 'fn_def_with_doc_impl full'
/// fn_def_with_doc_impl short
///
/// fn_def_with_doc_impl full
@@ -74,8 +74,8 @@ impl Bar for Foo1 {
fn fn_def_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
- // @has - 'fn_def_def_with_doc short'
- // @!has - 'fn_def_def_with_doc full'
+ // @hasraw - 'fn_def_def_with_doc short'
+ // @!hasraw - 'fn_def_def_with_doc full'
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
}
@@ -85,34 +85,34 @@ pub struct Foo2;
impl Bar for Foo2 {
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
- // @has - 'fn_empty_with_doc short'
- // @!has - 'fn_empty_with_doc full'
+ // @hasraw - 'fn_empty_with_doc short'
+ // @!hasraw - 'fn_empty_with_doc full'
fn fn_empty_with_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.4: fn_empty_without_doc'
- // @has - 'fn_empty_without_doc_impl short'
- // @has - 'fn_empty_without_doc_impl full'
+ // @hasraw - 'fn_empty_without_doc_impl short'
+ // @hasraw - 'fn_empty_without_doc_impl full'
/// fn_empty_without_doc_impl short
///
/// fn_empty_without_doc_impl full
fn fn_empty_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
- // @has - 'fn_def_with_doc short'
- // @!has - 'fn_def_with_doc full'
+ // @hasraw - 'fn_def_with_doc short'
+ // @!hasraw - 'fn_def_with_doc full'
fn fn_def_with_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.6: fn_def_without_doc'
- // @has - 'fn_def_without_doc_impl short'
- // @has - 'fn_def_without_doc_impl full'
+ // @hasraw - 'fn_def_without_doc_impl short'
+ // @hasraw - 'fn_def_without_doc_impl full'
/// fn_def_without_doc_impl short
///
/// fn_def_without_doc_impl full
fn fn_def_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
- // @has - 'fn_def_def_with_doc short'
- // @!has - 'fn_def_def_with_doc full'
+ // @hasraw - 'fn_def_def_with_doc short'
+ // @!hasraw - 'fn_def_def_with_doc full'
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
}
diff --git a/src/test/rustdoc/doc_auto_cfg_nested_impl.rs b/src/test/rustdoc/doc_auto_cfg_nested_impl.rs
new file mode 100644
index 000000000..4d73e0d82
--- /dev/null
+++ b/src/test/rustdoc/doc_auto_cfg_nested_impl.rs
@@ -0,0 +1,24 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/101129>.
+
+#![feature(doc_auto_cfg)]
+#![crate_type = "lib"]
+#![crate_name = "foo"]
+
+pub struct S;
+pub trait MyTrait1 {}
+pub trait MyTrait2 {}
+
+// @has foo/struct.S.html
+// @has - '//*[@id="impl-MyTrait1-for-S"]//*[@class="stab portability"]' \
+// 'Available on non-crate feature coolstuff only.'
+#[cfg(not(feature = "coolstuff"))]
+impl MyTrait1 for S {}
+
+#[cfg(not(feature = "coolstuff"))]
+mod submod {
+ use crate::{S, MyTrait2};
+ // This impl should also have the `not(feature = "coolstuff")`.
+ // @has - '//*[@id="impl-MyTrait2-for-S"]//*[@class="stab portability"]' \
+ // 'Available on non-crate feature coolstuff only.'
+ impl MyTrait2 for S {}
+}
diff --git a/src/test/rustdoc/elided-lifetime.rs b/src/test/rustdoc/elided-lifetime.rs
index 5a32554f9..006132ef8 100644
--- a/src/test/rustdoc/elided-lifetime.rs
+++ b/src/test/rustdoc/elided-lifetime.rs
@@ -3,7 +3,7 @@
// rust-lang/rust#75225
//
// Since Rust 2018 we encourage writing out <'_> explicitly to make it clear
-// that borrowing is occuring. Make sure rustdoc is following the same idiom.
+// that borrowing is occurring. Make sure rustdoc is following the same idiom.
#![crate_name = "foo"]
@@ -11,33 +11,33 @@ pub struct Ref<'a>(&'a u32);
type ARef<'a> = Ref<'a>;
// @has foo/fn.test1.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
pub fn test1(a: &u32) -> Ref {
Ref(a)
}
// @has foo/fn.test2.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
pub fn test2(a: &u32) -> Ref<'_> {
Ref(a)
}
// @has foo/fn.test3.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
pub fn test3(a: &u32) -> ARef {
Ref(a)
}
// @has foo/fn.test4.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
pub fn test4(a: &u32) -> ARef<'_> {
Ref(a)
}
// Ensure external paths in inlined docs also display elided lifetime
// @has foo/bar/fn.test5.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
// @has foo/bar/fn.test6.html
-// @matches - "Ref</a>&lt;'_&gt;"
+// @matchesraw - "Ref</a>&lt;'_&gt;"
#[doc(inline)]
pub extern crate bar;
diff --git a/src/test/rustdoc/empty-impl-block-private-with-doc.rs b/src/test/rustdoc/empty-impl-block-private-with-doc.rs
new file mode 100644
index 000000000..439719961
--- /dev/null
+++ b/src/test/rustdoc/empty-impl-block-private-with-doc.rs
@@ -0,0 +1,44 @@
+// compile-flags: --document-private-items
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![crate_name = "foo"]
+
+// @has 'foo/struct.Foo.html'
+pub struct Foo;
+
+// There are 3 impl blocks with public item and one that should not be displayed
+// by default because it only contains private items (but not in this case because
+// we used `--document-private-items`).
+// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 4
+
+// Impl block only containing private items should not be displayed unless the
+// `--document-private-items` flag is used.
+/// Private
+impl Foo {
+ const BAR: u32 = 0;
+ type FOO = i32;
+ fn hello() {}
+}
+
+// But if any element of the impl block is public, it should be displayed.
+/// Not private
+impl Foo {
+ pub const BAR: u32 = 0;
+ type FOO = i32;
+ fn hello() {}
+}
+
+/// Not private
+impl Foo {
+ const BAR: u32 = 0;
+ pub type FOO = i32;
+ fn hello() {}
+}
+
+/// Not private
+impl Foo {
+ const BAR: u32 = 0;
+ type FOO = i32;
+ pub fn hello() {}
+}
diff --git a/src/test/rustdoc/empty-impl-block-private.rs b/src/test/rustdoc/empty-impl-block-private.rs
new file mode 100644
index 000000000..5caf02065
--- /dev/null
+++ b/src/test/rustdoc/empty-impl-block-private.rs
@@ -0,0 +1,40 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![crate_name = "foo"]
+
+// @has 'foo/struct.Foo.html'
+pub struct Foo;
+
+// There are 3 impl blocks with public item and one that should not be displayed
+// because it only contains private items.
+// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 3
+
+// Impl block only containing private items should not be displayed.
+/// Private
+impl Foo {
+ const BAR: u32 = 0;
+ type FOO = i32;
+ fn hello() {}
+}
+
+// But if any element of the impl block is public, it should be displayed.
+/// Not private
+impl Foo {
+ pub const BAR: u32 = 0;
+ type FOO = i32;
+ fn hello() {}
+}
+
+/// Not private
+impl Foo {
+ const BAR: u32 = 0;
+ pub type FOO = i32;
+ fn hello() {}
+}
+
+/// Not private
+impl Foo {
+ const BAR: u32 = 0;
+ type FOO = i32;
+ pub fn hello() {}
+}
diff --git a/src/test/rustdoc/empty-mod-private.rs b/src/test/rustdoc/empty-mod-private.rs
index c2a98049a..147e11e58 100644
--- a/src/test/rustdoc/empty-mod-private.rs
+++ b/src/test/rustdoc/empty-mod-private.rs
@@ -1,16 +1,16 @@
// compile-flags: --document-private-items
// @has 'empty_mod_private/index.html' '//a[@href="foo/index.html"]' 'foo'
-// @has 'empty_mod_private/sidebar-items.js' 'foo'
+// @hasraw 'empty_mod_private/sidebar-items.js' 'foo'
// @matches 'empty_mod_private/foo/index.html' '//h1' 'Module empty_mod_private::foo'
mod foo {}
// @has 'empty_mod_private/index.html' '//a[@href="bar/index.html"]' 'bar'
-// @has 'empty_mod_private/sidebar-items.js' 'bar'
+// @hasraw 'empty_mod_private/sidebar-items.js' 'bar'
// @matches 'empty_mod_private/bar/index.html' '//h1' 'Module empty_mod_private::bar'
mod bar {
// @has 'empty_mod_private/bar/index.html' '//a[@href="baz/index.html"]' 'baz'
- // @has 'empty_mod_private/bar/sidebar-items.js' 'baz'
+ // @hasraw 'empty_mod_private/bar/sidebar-items.js' 'baz'
// @matches 'empty_mod_private/bar/baz/index.html' '//h1' 'Module empty_mod_private::bar::baz'
mod baz {}
}
diff --git a/src/test/rustdoc/empty-mod-public.rs b/src/test/rustdoc/empty-mod-public.rs
index d097fcf83..c0bac4021 100644
--- a/src/test/rustdoc/empty-mod-public.rs
+++ b/src/test/rustdoc/empty-mod-public.rs
@@ -1,14 +1,14 @@
// @has 'empty_mod_public/index.html' '//a[@href="foo/index.html"]' 'foo'
-// @has 'empty_mod_public/sidebar-items.js' 'foo'
+// @hasraw 'empty_mod_public/sidebar-items.js' 'foo'
// @matches 'empty_mod_public/foo/index.html' '//h1' 'Module empty_mod_public::foo'
pub mod foo {}
// @has 'empty_mod_public/index.html' '//a[@href="bar/index.html"]' 'bar'
-// @has 'empty_mod_public/sidebar-items.js' 'bar'
+// @hasraw 'empty_mod_public/sidebar-items.js' 'bar'
// @matches 'empty_mod_public/bar/index.html' '//h1' 'Module empty_mod_public::bar'
pub mod bar {
// @has 'empty_mod_public/bar/index.html' '//a[@href="baz/index.html"]' 'baz'
- // @has 'empty_mod_public/bar/sidebar-items.js' 'baz'
+ // @hasraw 'empty_mod_public/bar/sidebar-items.js' 'baz'
// @matches 'empty_mod_public/bar/baz/index.html' '//h1' 'Module empty_mod_public::bar::baz'
pub mod baz {}
}
diff --git a/src/test/rustdoc/empty-section.rs b/src/test/rustdoc/empty-section.rs
index 665aa38b1..d8241ab96 100644
--- a/src/test/rustdoc/empty-section.rs
+++ b/src/test/rustdoc/empty-section.rs
@@ -5,7 +5,7 @@
pub struct Foo;
// @has foo/struct.Foo.html
-// @!has - 'Auto Trait Implementations'
+// @!hasraw - 'Auto Trait Implementations'
impl !Send for Foo {}
impl !Sync for Foo {}
impl !std::marker::Unpin for Foo {}
diff --git a/src/test/rustdoc/ensure-src-link.rs b/src/test/rustdoc/ensure-src-link.rs
index 9f8b0277e..c65387080 100644
--- a/src/test/rustdoc/ensure-src-link.rs
+++ b/src/test/rustdoc/ensure-src-link.rs
@@ -2,5 +2,5 @@
// This test ensures that the [src] link is present on traits items.
-// @has foo/trait.Iterator.html '//*[@id="method.zip"]//a[@class="srclink"]' "source"
+// @has foo/trait.Iterator.html '//*[@id="method.zip"]//a[@class="srclink rightside"]' "source"
pub use std::iter::Iterator;
diff --git a/src/test/rustdoc/generic-associated-types/gats.rs b/src/test/rustdoc/generic-associated-types/gats.rs
index ae981b949..bcead3115 100644
--- a/src/test/rustdoc/generic-associated-types/gats.rs
+++ b/src/test/rustdoc/generic-associated-types/gats.rs
@@ -1,9 +1,8 @@
#![crate_name = "foo"]
-#![feature(generic_associated_types)]
// @has foo/trait.LendingIterator.html
pub trait LendingIterator {
- // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a"
+ // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a"
type Item<'a> where Self: 'a;
// @has - '//*[@id="tymethod.next"]//h4[@class="code-header"]' \
@@ -24,7 +23,7 @@ impl LendingIterator for () {
pub struct Infinite<T>(T);
// @has foo/trait.LendingIterator.html
-// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a = &'a T"
+// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a = &'a T"
impl<T> LendingIterator for Infinite<T> {
type Item<'a> where Self: 'a = &'a T;
diff --git a/src/test/rustdoc/generic-associated-types/issue-94683.rs b/src/test/rustdoc/generic-associated-types/issue-94683.rs
index 38ecf5283..985c7e983 100644
--- a/src/test/rustdoc/generic-associated-types/issue-94683.rs
+++ b/src/test/rustdoc/generic-associated-types/issue-94683.rs
@@ -1,5 +1,4 @@
#![crate_name = "foo"]
-#![feature(generic_associated_types)]
pub trait Trait {
type Gat<'a>;
@@ -8,6 +7,6 @@ pub trait Trait {
// Make sure that the elided lifetime shows up
// @has foo/type.T.html
-// @has - "pub type T = "
-// @has - "&lt;'_&gt;"
+// @hasraw - "pub type T = "
+// @hasraw - "&lt;'_&gt;"
pub type T = fn(&<() as Trait>::Gat<'_>);
diff --git a/src/test/rustdoc/glob-shadowing-const.rs b/src/test/rustdoc/glob-shadowing-const.rs
new file mode 100644
index 000000000..5b786cf53
--- /dev/null
+++ b/src/test/rustdoc/glob-shadowing-const.rs
@@ -0,0 +1,20 @@
+// https://github.com/rust-lang/rust/pull/83872#issuecomment-820101008
+#![crate_name="foo"]
+
+mod sub4 {
+ /// 0
+ pub const X: usize = 0;
+ pub mod inner {
+ pub use super::*;
+ /// 1
+ pub const X: usize = 1;
+ }
+}
+
+#[doc(inline)]
+pub use sub4::inner::*;
+
+// @has 'foo/index.html'
+// @has - '//div[@class="item-right docblock-short"]' '1'
+// @!has - '//div[@class="item-right docblock-short"]' '0'
+fn main() { assert_eq!(X, 1); }
diff --git a/src/test/rustdoc/glob-shadowing.rs b/src/test/rustdoc/glob-shadowing.rs
new file mode 100644
index 000000000..66a31c42b
--- /dev/null
+++ b/src/test/rustdoc/glob-shadowing.rs
@@ -0,0 +1,86 @@
+// @has 'glob_shadowing/index.html'
+// @count - '//div[@class="item-left module-item"]' 6
+// @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe'
+// @has - '//div[@class="item-right docblock-short"]' 'sub2::describe'
+
+// @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe2'
+
+// @!has - '//div[@class="item-right docblock-short"]' 'sub1::prelude'
+// @has - '//div[@class="item-right docblock-short"]' 'mod::prelude'
+
+// @has - '//div[@class="item-right docblock-short"]' 'sub1::Foo (struct)'
+// @has - '//div[@class="item-right docblock-short"]' 'mod::Foo (function)'
+
+// @has - '//div[@class="item-right docblock-short"]' 'sub4::inner::X'
+
+// @has 'glob_shadowing/fn.describe.html'
+// @has - '//div[@class="docblock"]' 'sub2::describe'
+
+mod sub1 {
+ // this should be shadowed by sub2::describe
+ /// sub1::describe
+ pub fn describe() -> &'static str {
+ "sub1::describe"
+ }
+
+ // this should be shadowed by mod::prelude
+ /// sub1::prelude
+ pub mod prelude {
+ }
+
+ // this should *not* be shadowed, because sub1::Foo and mod::Foo are in different namespaces
+ /// sub1::Foo (struct)
+ pub struct Foo;
+
+ // this should be shadowed,
+ // because both sub1::describe2 and sub3::describe2 are from glob reexport
+ /// sub1::describe2
+ pub fn describe2() -> &'static str {
+ "sub1::describe2"
+ }
+}
+
+mod sub2 {
+ /// sub2::describe
+ pub fn describe() -> &'static str {
+ "sub2::describe"
+ }
+}
+
+mod sub3 {
+ // this should be shadowed
+ // because both sub1::describe2 and sub3::describe2 are from glob reexport
+ /// sub3::describe2
+ pub fn describe2() -> &'static str {
+ "sub3::describe2"
+ }
+}
+
+mod sub4 {
+ // this should be shadowed by sub4::inner::X
+ /// sub4::X
+ pub const X: usize = 0;
+ pub mod inner {
+ pub use super::*;
+ /// sub4::inner::X
+ pub const X: usize = 1;
+ }
+}
+
+/// mod::Foo (function)
+pub fn Foo() {}
+
+#[doc(inline)]
+pub use sub2::describe;
+
+#[doc(inline)]
+pub use sub1::*;
+
+#[doc(inline)]
+pub use sub3::*;
+
+#[doc(inline)]
+pub use sub4::inner::*;
+
+/// mod::prelude
+pub mod prelude {}
diff --git a/src/test/rustdoc/hidden-impls.rs b/src/test/rustdoc/hidden-impls.rs
index 8f33a6604..26e2e0e06 100644
--- a/src/test/rustdoc/hidden-impls.rs
+++ b/src/test/rustdoc/hidden-impls.rs
@@ -11,7 +11,7 @@ pub mod __hidden {
}
// @has foo/trait.Clone.html
-// @!has - 'Foo'
+// @!hasraw - 'Foo'
// @has implementors/core/clone/trait.Clone.js
-// @!has - 'Foo'
+// @!hasraw - 'Foo'
pub use std::clone::Clone;
diff --git a/src/test/rustdoc/hidden-line.rs b/src/test/rustdoc/hidden-line.rs
index f2f6173d2..00a05a7c2 100644
--- a/src/test/rustdoc/hidden-line.rs
+++ b/src/test/rustdoc/hidden-line.rs
@@ -15,5 +15,5 @@
/// ```
pub fn foo() {}
-// @!has hidden_line/fn.foo.html invisible
+// @!hasraw hidden_line/fn.foo.html invisible
// @matches - //pre "#\[derive\(PartialEq\)\] // Bar"
diff --git a/src/test/rustdoc/hidden-methods.rs b/src/test/rustdoc/hidden-methods.rs
index 27181d489..543d8f768 100644
--- a/src/test/rustdoc/hidden-methods.rs
+++ b/src/test/rustdoc/hidden-methods.rs
@@ -17,13 +17,13 @@ pub mod hidden {
}
// @has foo/struct.Foo.html
-// @!has - 'Methods'
+// @!hasraw - 'Methods'
// @!has - '//code' 'impl Foo'
-// @!has - 'this_should_be_hidden'
+// @!hasraw - 'this_should_be_hidden'
pub use hidden::Foo;
// @has foo/struct.Bar.html
-// @!has - 'Methods'
+// @!hasraw - 'Methods'
// @!has - '//code' 'impl Bar'
-// @!has - 'this_should_be_hidden'
+// @!hasraw - 'this_should_be_hidden'
pub use hidden::Bar;
diff --git a/src/test/rustdoc/hide-unstable-trait.rs b/src/test/rustdoc/hide-unstable-trait.rs
index c30d6ed7b..0bf7cabc4 100644
--- a/src/test/rustdoc/hide-unstable-trait.rs
+++ b/src/test/rustdoc/hide-unstable-trait.rs
@@ -5,7 +5,7 @@
extern crate unstable_trait;
-// @has foo/struct.Foo.html 'bar'
-// @has foo/struct.Foo.html 'bar2'
+// @hasraw foo/struct.Foo.html 'bar'
+// @hasraw foo/struct.Foo.html 'bar2'
#[doc(inline)]
pub use unstable_trait::Foo;
diff --git a/src/test/rustdoc/higher-ranked-trait-bounds.rs b/src/test/rustdoc/higher-ranked-trait-bounds.rs
index b75b8de52..59b5b6e57 100644
--- a/src/test/rustdoc/higher-ranked-trait-bounds.rs
+++ b/src/test/rustdoc/higher-ranked-trait-bounds.rs
@@ -4,7 +4,7 @@
pub trait Trait<'x> {}
// @has foo/fn.test1.html
-// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
+// @has - '//pre' "pub fn test1<T>()where for<'a> &'a T: Iterator,"
pub fn test1<T>()
where
for<'a> &'a T: Iterator,
@@ -12,7 +12,7 @@ where
}
// @has foo/fn.test2.html
-// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: Trait<'b>,"
+// @has - '//pre' "pub fn test2<T>()where for<'a, 'b> &'a T: Trait<'b>,"
pub fn test2<T>()
where
for<'a, 'b> &'a T: Trait<'b>,
@@ -20,7 +20,7 @@ where
}
// @has foo/fn.test3.html
-// @has - '//pre' "pub fn test3<F>() where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
+// @has - '//pre' "pub fn test3<F>()where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
pub fn test3<F>()
where
F: for<'a, 'b> Fn(&'a u8, &'b u8),
@@ -38,7 +38,7 @@ pub struct Foo<'a> {
// @has - '//span[@id="structfield.some_trait"]' "some_trait: &'a dyn for<'b> Trait<'b>"
impl<'a> Foo<'a> {
- // @has - '//h4[@class="code-header"]' "pub fn bar<T>() where T: Trait<'a>,"
+ // @has - '//h4[@class="code-header"]' "pub fn bar<T>()where T: Trait<'a>,"
pub fn bar<T>()
where
T: Trait<'a>,
diff --git a/src/test/rustdoc/impl-parts-crosscrate.rs b/src/test/rustdoc/impl-parts-crosscrate.rs
index 6c5e79d5a..34733f1f8 100644
--- a/src/test/rustdoc/impl-parts-crosscrate.rs
+++ b/src/test/rustdoc/impl-parts-crosscrate.rs
@@ -12,9 +12,9 @@ pub struct Bar<T> { t: T }
// full impl string. Instead, just make sure something from each part
// is mentioned.
-// @has implementors/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
-// @has - Send
-// @has - !AnAutoTrait
-// @has - Copy
+// @hasraw implementors/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
+// @hasraw - Send
+// @hasraw - !AnAutoTrait
+// @hasraw - Copy
impl<T: Send> !rustdoc_impl_parts_crosscrate::AnAutoTrait for Bar<T>
where T: Copy {}
diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs
index 249158c1a..b1481e1f2 100644
--- a/src/test/rustdoc/impl-parts.rs
+++ b/src/test/rustdoc/impl-parts.rs
@@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {}
pub struct Foo<T> { field: T }
// @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync,"
+// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
// @has impl_parts/trait.AnAutoTrait.html '//*[@class="item-list"]//h3[@class="code-header in-band"]' \
-// "impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync,"
+// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {}
diff --git a/src/test/rustdoc/impl-trait-alias.rs b/src/test/rustdoc/impl-trait-alias.rs
index 54c3f856d..4f681c78e 100644
--- a/src/test/rustdoc/impl-trait-alias.rs
+++ b/src/test/rustdoc/impl-trait-alias.rs
@@ -3,11 +3,11 @@
trait MyTrait {}
impl MyTrait for i32 {}
-// @has impl_trait_alias/type.Foo.html 'Foo'
+// @hasraw impl_trait_alias/type.Foo.html 'Foo'
/// debug type
pub type Foo = impl MyTrait;
-// @has impl_trait_alias/fn.foo.html 'foo'
+// @hasraw impl_trait_alias/fn.foo.html 'foo'
/// debug function
pub fn foo() -> Foo {
1
diff --git a/src/test/rustdoc/impossible-default.rs b/src/test/rustdoc/impossible-default.rs
new file mode 100644
index 000000000..24d6e3bda
--- /dev/null
+++ b/src/test/rustdoc/impossible-default.rs
@@ -0,0 +1,20 @@
+#![crate_name = "foo"]
+
+// Check that default trait items that are impossible to satisfy
+
+pub trait Foo {
+ fn needs_sized(&self)
+ where
+ Self: Sized,
+ {}
+
+ fn no_needs_sized(&self) {}
+}
+
+// @!has foo/struct.Bar.html '//*[@id="method.needs_sized"]//h4[@class="code-header"]' \
+// "fn needs_sized"
+// @has foo/struct.Bar.html '//*[@id="method.no_needs_sized"]//h4[@class="code-header"]' \
+// "fn no_needs_sized"
+pub struct Bar([u8]);
+
+impl Foo for Bar {}
diff --git a/src/test/rustdoc/infinite-redirection.rs b/src/test/rustdoc/infinite-redirection.rs
index 96a43323c..f037a8e1a 100644
--- a/src/test/rustdoc/infinite-redirection.rs
+++ b/src/test/rustdoc/infinite-redirection.rs
@@ -7,7 +7,7 @@
// @has 'foo/builders/struct.ActionRowBuilder.html'
// @has - '//*[@id="synthetic-implementations"]' 'Auto Trait Implementations'
-// And that the link in the module is targetting it.
+// And that the link in the module is targeting it.
// @has 'foo/builders/index.html'
// @has - '//a[@href="struct.ActionRowBuilder.html"]' 'ActionRowBuilder'
diff --git a/src/test/rustdoc/inline_cross/add-docs.rs b/src/test/rustdoc/inline_cross/add-docs.rs
index 8f0c4e5e6..a1124d209 100644
--- a/src/test/rustdoc/inline_cross/add-docs.rs
+++ b/src/test/rustdoc/inline_cross/add-docs.rs
@@ -4,6 +4,6 @@ extern crate inner;
// @has add_docs/struct.MyStruct.html
-// @has add_docs/struct.MyStruct.html "Doc comment from ‘pub use’, Doc comment from definition"
+// @hasraw add_docs/struct.MyStruct.html "Doc comment from ‘pub use’, Doc comment from definition"
/// Doc comment from 'pub use',
pub use inner::MyStruct;
diff --git a/src/test/rustdoc/inline_cross/assoc-items.rs b/src/test/rustdoc/inline_cross/assoc-items.rs
index 231805a52..811827a17 100644
--- a/src/test/rustdoc/inline_cross/assoc-items.rs
+++ b/src/test/rustdoc/inline_cross/assoc-items.rs
@@ -7,10 +7,10 @@
extern crate assoc_items;
// @has foo/struct.MyStruct.html
-// @!has - 'PrivateConst'
+// @!hasraw - 'PrivateConst'
// @has - '//*[@id="associatedconstant.PublicConst"]' 'pub const PublicConst: u8'
// @has - '//*[@class="docblock"]' 'docs for PublicConst'
-// @!has - 'private_method'
+// @!hasraw - 'private_method'
// @has - '//*[@id="method.public_method"]' 'pub fn public_method()'
// @has - '//*[@class="docblock"]' 'docs for public_method'
// @has - '//*[@id="associatedconstant.ConstNoDefault"]' 'const ConstNoDefault: i16'
diff --git a/src/test/rustdoc/inline_cross/hidden-use.rs b/src/test/rustdoc/inline_cross/hidden-use.rs
index 97715737f..28a4f4bac 100644
--- a/src/test/rustdoc/inline_cross/hidden-use.rs
+++ b/src/test/rustdoc/inline_cross/hidden-use.rs
@@ -5,8 +5,8 @@
extern crate rustdoc_hidden;
// @has hidden_use/index.html
-// @!has - 'rustdoc_hidden'
-// @!has - 'Bar'
+// @!hasraw - 'rustdoc_hidden'
+// @!hasraw - 'Bar'
// @!has hidden_use/struct.Bar.html
#[doc(hidden)]
pub use rustdoc_hidden::Bar;
diff --git a/src/test/rustdoc/inline_cross/proc_macro.rs b/src/test/rustdoc/inline_cross/proc_macro.rs
index 532a295c0..a46550865 100644
--- a/src/test/rustdoc/inline_cross/proc_macro.rs
+++ b/src/test/rustdoc/inline_cross/proc_macro.rs
@@ -12,25 +12,25 @@ extern crate some_macros;
// @has proc_macro/derive.SomeDerive.html
// @has proc_macro/macro.some_proc_macro.html
-// @has - 'a proc-macro that swallows its input and does nothing.'
+// @hasraw - 'a proc-macro that swallows its input and does nothing.'
pub use some_macros::some_proc_macro;
// @has proc_macro/macro.reexported_macro.html
-// @has - 'Doc comment from the original crate'
+// @hasraw - 'Doc comment from the original crate'
pub use some_macros::reexported_macro;
// @has proc_macro/attr.some_proc_attr.html
-// @has - 'a proc-macro attribute that passes its item through verbatim.'
+// @hasraw - 'a proc-macro attribute that passes its item through verbatim.'
pub use some_macros::some_proc_attr;
// @has proc_macro/derive.SomeDerive.html
-// @has - 'a derive attribute that adds nothing to its input.'
+// @hasraw - 'a derive attribute that adds nothing to its input.'
pub use some_macros::SomeDerive;
// @has proc_macro/attr.first_attr.html
-// @has - 'Generated doc comment'
+// @hasraw - 'Generated doc comment'
pub use some_macros::first_attr;
// @has proc_macro/attr.second_attr.html
-// @has - 'Generated doc comment'
+// @hasraw - 'Generated doc comment'
pub use some_macros::second_attr;
diff --git a/src/test/rustdoc/inline_local/glob-extern-document-private-items.rs b/src/test/rustdoc/inline_local/glob-extern-document-private-items.rs
index a2f0d65ef..8e1089d60 100644
--- a/src/test/rustdoc/inline_local/glob-extern-document-private-items.rs
+++ b/src/test/rustdoc/inline_local/glob-extern-document-private-items.rs
@@ -12,14 +12,14 @@ mod mod1 {
pub use mod1::*;
// @has foo/index.html
-// @has - "mod1"
-// @has - "public_fn"
-// @!has - "private_fn"
+// @hasraw - "mod1"
+// @hasraw - "public_fn"
+// @!hasraw - "private_fn"
// @has foo/fn.public_fn.html
// @!has foo/fn.private_fn.html
// @has foo/mod1/index.html
-// @has - "public_fn"
-// @has - "private_fn"
+// @hasraw - "public_fn"
+// @hasraw - "private_fn"
// @has foo/mod1/fn.public_fn.html
// @has foo/mod1/fn.private_fn.html
diff --git a/src/test/rustdoc/inline_local/glob-extern.rs b/src/test/rustdoc/inline_local/glob-extern.rs
index 686e55de3..c592a4db1 100644
--- a/src/test/rustdoc/inline_local/glob-extern.rs
+++ b/src/test/rustdoc/inline_local/glob-extern.rs
@@ -10,9 +10,9 @@ mod mod1 {
pub use mod1::*;
// @has foo/index.html
-// @!has - "mod1"
-// @has - "public_fn"
-// @!has - "private_fn"
+// @!hasraw - "mod1"
+// @hasraw - "public_fn"
+// @!hasraw - "private_fn"
// @has foo/fn.public_fn.html
// @!has foo/fn.private_fn.html
diff --git a/src/test/rustdoc/inline_local/glob-private-document-private-items.rs b/src/test/rustdoc/inline_local/glob-private-document-private-items.rs
index f16d21ecd..d8cbd4234 100644
--- a/src/test/rustdoc/inline_local/glob-private-document-private-items.rs
+++ b/src/test/rustdoc/inline_local/glob-private-document-private-items.rs
@@ -15,31 +15,31 @@ mod mod1 {
pub use mod1::*;
// @has foo/index.html
-// @has - "mod1"
-// @has - "Mod1Public"
-// @!has - "Mod1Private"
-// @!has - "mod2"
-// @has - "Mod2Public"
-// @!has - "Mod2Private"
+// @hasraw - "mod1"
+// @hasraw - "Mod1Public"
+// @!hasraw - "Mod1Private"
+// @!hasraw - "mod2"
+// @hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
// @has foo/struct.Mod1Public.html
// @!has foo/struct.Mod1Private.html
// @has foo/struct.Mod2Public.html
// @!has foo/struct.Mod2Private.html
// @has foo/mod1/index.html
-// @has - "mod2"
-// @has - "Mod1Public"
-// @has - "Mod1Private"
-// @!has - "Mod2Public"
-// @!has - "Mod2Private"
+// @hasraw - "mod2"
+// @hasraw - "Mod1Public"
+// @hasraw - "Mod1Private"
+// @!hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
// @has foo/mod1/struct.Mod1Public.html
// @has foo/mod1/struct.Mod1Private.html
// @!has foo/mod1/struct.Mod2Public.html
// @!has foo/mod1/struct.Mod2Private.html
// @has foo/mod1/mod2/index.html
-// @has - "Mod2Public"
-// @has - "Mod2Private"
+// @hasraw - "Mod2Public"
+// @hasraw - "Mod2Private"
// @has foo/mod1/mod2/struct.Mod2Public.html
// @has foo/mod1/mod2/struct.Mod2Private.html
diff --git a/src/test/rustdoc/inline_local/glob-private.rs b/src/test/rustdoc/inline_local/glob-private.rs
index d294d590e..303f1d610 100644
--- a/src/test/rustdoc/inline_local/glob-private.rs
+++ b/src/test/rustdoc/inline_local/glob-private.rs
@@ -13,12 +13,12 @@ mod mod1 {
pub use mod1::*;
// @has foo/index.html
-// @!has - "mod1"
-// @has - "Mod1Public"
-// @!has - "Mod1Private"
-// @!has - "mod2"
-// @has - "Mod2Public"
-// @!has - "Mod2Private"
+// @!hasraw - "mod1"
+// @hasraw - "Mod1Public"
+// @!hasraw - "Mod1Private"
+// @!hasraw - "mod2"
+// @hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
// @has foo/struct.Mod1Public.html
// @!has foo/struct.Mod1Private.html
// @has foo/struct.Mod2Public.html
diff --git a/src/test/rustdoc/inline_local/hidden-use.rs b/src/test/rustdoc/inline_local/hidden-use.rs
index a972d376a..de512fb26 100644
--- a/src/test/rustdoc/inline_local/hidden-use.rs
+++ b/src/test/rustdoc/inline_local/hidden-use.rs
@@ -3,8 +3,8 @@ mod private {
}
// @has hidden_use/index.html
-// @!has - 'private'
-// @!has - 'Foo'
+// @!hasraw - 'private'
+// @!hasraw - 'Foo'
// @!has hidden_use/struct.Foo.html
#[doc(hidden)]
pub use private::Foo;
diff --git a/src/test/rustdoc/inline_local/macro_by_example.rs b/src/test/rustdoc/inline_local/macro_by_example.rs
index dacc7cfb3..5c33c0037 100644
--- a/src/test/rustdoc/inline_local/macro_by_example.rs
+++ b/src/test/rustdoc/inline_local/macro_by_example.rs
@@ -7,7 +7,7 @@ macro_rules! foo {
// @has macro_by_example/macros/index.html
pub mod macros {
- // @!has - 'pub use foo as bar;'
+ // @!hasraw - 'pub use foo as bar;'
// @has macro_by_example/macros/macro.bar.html
// @has - '//*[@class="docblock"]' 'docs for foo'
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.2.3: text'
diff --git a/src/test/rustdoc/inline_local/please_inline.rs b/src/test/rustdoc/inline_local/please_inline.rs
index 48539361f..e4429ef33 100644
--- a/src/test/rustdoc/inline_local/please_inline.rs
+++ b/src/test/rustdoc/inline_local/please_inline.rs
@@ -4,7 +4,7 @@ pub mod foo {
// @has please_inline/a/index.html
pub mod a {
- // @!has - 'pub use foo::'
+ // @!hasraw - 'pub use foo::'
// @has please_inline/a/struct.Foo.html
#[doc(inline)]
pub use foo::Foo;
@@ -12,7 +12,7 @@ pub mod a {
// @has please_inline/b/index.html
pub mod b {
- // @has - 'pub use foo::'
+ // @hasraw - 'pub use foo::'
// @!has please_inline/b/struct.Foo.html
#[feature(inline)]
pub use foo::Foo;
diff --git a/src/test/rustdoc/internal.rs b/src/test/rustdoc/internal.rs
index f316eb24a..caad43a08 100644
--- a/src/test/rustdoc/internal.rs
+++ b/src/test/rustdoc/internal.rs
@@ -3,13 +3,15 @@
// Check that the unstable marker is not added for "rustc_private".
// @!matches internal/index.html \
-// '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]'
+// '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]' \
+// ''
// @!matches internal/index.html \
-// '//*[@class="item-right docblock-short"]/span[@class="stab internal"]'
+// '//*[@class="item-right docblock-short"]/span[@class="stab internal"]' \
+// ''
// @matches - '//*[@class="item-right docblock-short"]' 'Docs'
-// @!has internal/struct.S.html '//*[@class="stab unstable"]'
-// @!has internal/struct.S.html '//*[@class="stab internal"]'
+// @!has internal/struct.S.html '//*[@class="stab unstable"]' ''
+// @!has internal/struct.S.html '//*[@class="stab internal"]' ''
/// Docs
pub struct S;
diff --git a/src/test/rustdoc/intra-doc/assoc-reexport-super.rs b/src/test/rustdoc/intra-doc/assoc-reexport-super.rs
new file mode 100644
index 000000000..a7bc1c6a2
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/assoc-reexport-super.rs
@@ -0,0 +1,20 @@
+// Regression test for #93205
+
+#![crate_name = "foo"]
+
+mod generated {
+ pub struct MyNewType;
+ impl MyNewType {
+ pub const FOO: Self = Self;
+ }
+}
+
+pub use generated::MyNewType;
+
+mod prelude {
+ impl super::MyNewType {
+ /// An alias for [`Self::FOO`].
+ // @has 'foo/struct.MyNewType.html' '//a[@href="struct.MyNewType.html#associatedconstant.FOO"]' 'Self::FOO'
+ pub const FOO2: Self = Self::FOO;
+ }
+}
diff --git a/src/test/rustdoc/intra-doc/extern-type.rs b/src/test/rustdoc/intra-doc/extern-type.rs
index ab088ab78..5440f582d 100644
--- a/src/test/rustdoc/intra-doc/extern-type.rs
+++ b/src/test/rustdoc/intra-doc/extern-type.rs
@@ -25,11 +25,11 @@ impl G<usize> for ExternType {
}
// @has 'extern_type/foreigntype.ExternType.html'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
// 'href="foreigntype.ExternType.html#method.f"'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
// 'href="foreigntype.ExternType.html#method.test"'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
// 'href="foreigntype.ExternType.html#method.g"'
/// See also [ExternType::f]
/// See also [ExternType::test]
diff --git a/src/test/rustdoc/issue-100620.rs b/src/test/rustdoc/issue-100620.rs
new file mode 100644
index 000000000..097666eb5
--- /dev/null
+++ b/src/test/rustdoc/issue-100620.rs
@@ -0,0 +1,19 @@
+pub trait Bar<S> {}
+
+pub trait Qux<T> {}
+
+pub trait Foo<T, S> {
+ fn bar()
+ where
+ T: Bar<S>,
+ {
+ }
+}
+
+pub struct Concrete;
+
+impl<S> Foo<(), S> for Concrete {}
+
+impl<T, S> Bar<S> for T where S: Qux<T> {}
+
+impl<T, S> Qux<T> for S where T: Bar<S> {}
diff --git a/src/test/rustdoc/issue-100679-sidebar-links-deref.rs b/src/test/rustdoc/issue-100679-sidebar-links-deref.rs
new file mode 100644
index 000000000..f09d23206
--- /dev/null
+++ b/src/test/rustdoc/issue-100679-sidebar-links-deref.rs
@@ -0,0 +1,30 @@
+#![crate_name="foo"]
+
+pub struct Vec;
+
+pub struct Slice;
+
+impl std::ops::Deref for Vec {
+ type Target = Slice;
+ fn deref(&self) -> &Slice {
+ &Slice
+ }
+}
+
+// @has foo/struct.Vec.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.is_empty"]' \
+// "is_empty"
+impl Vec {
+ pub fn is_empty(&self) -> bool {
+ true
+ }
+}
+
+// @has foo/struct.Vec.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.is_empty-1"]' \
+// "is_empty"
+// @has foo/struct.Slice.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.is_empty"]' \
+// "is_empty"
+impl Slice {
+ pub fn is_empty(&self) -> bool {
+ true
+ }
+}
diff --git a/src/test/rustdoc/issue-101743-bold-tag.rs b/src/test/rustdoc/issue-101743-bold-tag.rs
new file mode 100644
index 000000000..631181fec
--- /dev/null
+++ b/src/test/rustdoc/issue-101743-bold-tag.rs
@@ -0,0 +1,19 @@
+// Regression test for https://github.com/rust-lang/rust/issues/101743
+
+#![crate_name="foo"]
+
+pub type Word = usize;
+pub struct Repr<const B: usize>([i32; B]);
+pub struct IBig(usize);
+
+pub const fn base_as_ibig<const B: Word>() -> IBig {
+ IBig(B)
+}
+
+impl<const B: Word> Repr<B> {
+ // If we change back to rendering the value of consts, check this doesn't add
+ // a <b> tag, but escapes correctly
+
+ // @has foo/struct.Repr.html '//section[@id="associatedconstant.BASE"]/h4' '= _'
+ pub const BASE: IBig = base_as_ibig::<B>();
+}
diff --git a/src/test/rustdoc/issue-16265-1.rs b/src/test/rustdoc/issue-16265-1.rs
index ec007e36b..2fda637a6 100644
--- a/src/test/rustdoc/issue-16265-1.rs
+++ b/src/test/rustdoc/issue-16265-1.rs
@@ -1,6 +1,6 @@
pub struct Foo;
-// @has issue_16265_1/traits/index.html 'source'
+// @hasraw issue_16265_1/traits/index.html 'source'
pub mod traits {
impl PartialEq for super::Foo {
fn eq(&self, _: &super::Foo) -> bool {
diff --git a/src/test/rustdoc/issue-16265-2.rs b/src/test/rustdoc/issue-16265-2.rs
index d5cd18d9d..c3eb35617 100644
--- a/src/test/rustdoc/issue-16265-2.rs
+++ b/src/test/rustdoc/issue-16265-2.rs
@@ -1,4 +1,4 @@
-// @has issue_16265_2/index.html 'source'
+// @hasraw issue_16265_2/index.html 'source'
trait Y {}
impl Y for Option<u32> {}
diff --git a/src/test/rustdoc/issue-20727-4.rs b/src/test/rustdoc/issue-20727-4.rs
index 84fc6f94a..643f93875 100644
--- a/src/test/rustdoc/issue-20727-4.rs
+++ b/src/test/rustdoc/issue-20727-4.rs
@@ -25,7 +25,7 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
pub mod reexport {
// @has issue_20727_4/reexport/trait.Index.html
- // @has - '//*[@class="rust trait"]' 'trait Index<Idx> where Idx: ?Sized, {'
+ // @has - '//*[@class="rust trait"]' 'trait Index<Idx>where Idx: ?Sized,{'
// @has - '//*[@class="rust trait"]' 'type Output: ?Sized'
// @has - '//*[@class="rust trait"]' \
// 'fn index(&self, index: Idx) -> &Self::Output'
@@ -33,7 +33,7 @@ pub mod reexport {
// @has issue_20727_4/reexport/trait.IndexMut.html
// @has - '//*[@class="rust trait"]' \
- // 'trait IndexMut<Idx>: Index<Idx> where Idx: ?Sized, {'
+ // 'trait IndexMut<Idx>: Index<Idx>where Idx: ?Sized,{'
// @has - '//*[@class="rust trait"]' \
// 'fn index_mut(&mut self, index: Idx) -> &mut Self::Output;'
pub use issue_20727::IndexMut;
diff --git a/src/test/rustdoc/issue-21801.rs b/src/test/rustdoc/issue-21801.rs
index 2a586b6ff..29d2ec64c 100644
--- a/src/test/rustdoc/issue-21801.rs
+++ b/src/test/rustdoc/issue-21801.rs
@@ -5,5 +5,5 @@ extern crate issue_21801;
// @has issue_21801/struct.Foo.html
// @has - '//*[@id="method.new"]' \
-// 'fn new<F>(f: F) -> Foo where F: FnMut() -> i32'
+// 'fn new<F>(f: F) -> Foowhere F: FnMut() -> i32'
pub use issue_21801::Foo;
diff --git a/src/test/rustdoc/issue-23511.rs b/src/test/rustdoc/issue-23511.rs
index 2d2a7908f..7576ebb03 100644
--- a/src/test/rustdoc/issue-23511.rs
+++ b/src/test/rustdoc/issue-23511.rs
@@ -6,7 +6,7 @@ pub mod str {
#![doc(primitive = "str")]
impl str {
- // @has search-index.js foo
+ // @hasraw search-index.js foo
#[rustc_allow_incoherent_impl]
pub fn foo(&self) {}
}
diff --git a/src/test/rustdoc/issue-23812.rs b/src/test/rustdoc/issue-23812.rs
index 5dac8d87b..08fd1833b 100644
--- a/src/test/rustdoc/issue-23812.rs
+++ b/src/test/rustdoc/issue-23812.rs
@@ -16,10 +16,10 @@ doc! {
}
// @has issue_23812/Foo/index.html
-// @has - 'Outer comment'
-// @!has - '/// Outer comment'
-// @has - 'Inner comment'
-// @!has - '//! Inner comment'
+// @hasraw - 'Outer comment'
+// @!hasraw - '/// Outer comment'
+// @hasraw - 'Inner comment'
+// @!hasraw - '//! Inner comment'
doc! {
@@ -30,7 +30,7 @@ doc! {
}
// @has issue_23812/Bar/index.html
-// @has - 'Outer block comment'
-// @!has - '/** Outer block comment */'
-// @has - 'Inner block comment'
-// @!has - '/*! Inner block comment */'
+// @hasraw - 'Outer block comment'
+// @!hasraw - '/** Outer block comment */'
+// @hasraw - 'Inner block comment'
+// @!hasraw - '/*! Inner block comment */'
diff --git a/src/test/rustdoc/issue-27104.rs b/src/test/rustdoc/issue-27104.rs
index b74c3eb78..9f2fd9071 100644
--- a/src/test/rustdoc/issue-27104.rs
+++ b/src/test/rustdoc/issue-27104.rs
@@ -3,8 +3,8 @@
// ignore-cross-compile
// @has issue_27104/index.html
-// @!has - 'extern crate std'
-// @!has - 'use std::prelude::'
+// @!hasraw - 'extern crate std'
+// @!hasraw - 'use std::prelude::'
-// @has - 'pub extern crate empty'
+// @hasraw - 'pub extern crate empty'
pub extern crate empty;
diff --git a/src/test/rustdoc/issue-27759.rs b/src/test/rustdoc/issue-27759.rs
index f3739dafd..65e0f7cb8 100644
--- a/src/test/rustdoc/issue-27759.rs
+++ b/src/test/rustdoc/issue-27759.rs
@@ -4,11 +4,11 @@
#![unstable(feature="test", issue="27759")]
// @has issue_27759/unstable/index.html
-// @has - '<code>test</code>&nbsp;<a href="http://issue_url/27759">#27759</a>'
+// @hasraw - '<code>test</code>&nbsp;<a href="http://issue_url/27759">#27759</a>'
#[unstable(feature="test", issue="27759")]
pub mod unstable {
// @has issue_27759/unstable/fn.issue.html
- // @has - '<code>test_function</code>&nbsp;<a href="http://issue_url/12345">#12345</a>'
+ // @hasraw - '<code>test_function</code>&nbsp;<a href="http://issue_url/12345">#12345</a>'
#[unstable(feature="test_function", issue="12345")]
pub fn issue() {}
}
diff --git a/src/test/rustdoc/issue-29503.rs b/src/test/rustdoc/issue-29503.rs
index 635c3175f..134821e1e 100644
--- a/src/test/rustdoc/issue-29503.rs
+++ b/src/test/rustdoc/issue-29503.rs
@@ -5,7 +5,7 @@ pub trait MyTrait {
fn my_string(&self) -> String;
}
-// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for T where T: Debug"
+// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for Twhere T: Debug"
impl<T> MyTrait for T
where
T: fmt::Debug,
diff --git a/src/test/rustdoc/issue-29584.rs b/src/test/rustdoc/issue-29584.rs
index 28e1efec6..4364a9649 100644
--- a/src/test/rustdoc/issue-29584.rs
+++ b/src/test/rustdoc/issue-29584.rs
@@ -4,5 +4,5 @@
extern crate issue_29584;
// @has issue_29584/struct.Foo.html
-// @!has - 'impl Bar for'
+// @!hasraw - 'impl Bar for'
pub use issue_29584::Foo;
diff --git a/src/test/rustdoc/issue-31899.rs b/src/test/rustdoc/issue-31899.rs
index e7a8ee239..3eee37446 100644
--- a/src/test/rustdoc/issue-31899.rs
+++ b/src/test/rustdoc/issue-31899.rs
@@ -1,8 +1,8 @@
// @has issue_31899/index.html
-// @has - 'Make this line a bit longer.'
-// @!has - 'rust rust-example-rendered'
-// @!has - 'use ndarray::arr2'
-// @!has - 'prohibited'
+// @hasraw - 'Make this line a bit longer.'
+// @!hasraw - 'rust rust-example-rendered'
+// @!hasraw - 'use ndarray::arr2'
+// @!hasraw - 'prohibited'
/// A tuple or fixed size array that can be used to index an array.
/// Make this line a bit longer.
diff --git a/src/test/rustdoc/issue-32374.rs b/src/test/rustdoc/issue-32374.rs
index 01f955381..8d2c27cf3 100644
--- a/src/test/rustdoc/issue-32374.rs
+++ b/src/test/rustdoc/issue-32374.rs
@@ -8,20 +8,24 @@
// 'Experimental'
// @matches issue_32374/index.html '//*[@class="item-right docblock-short"]/text()' 'Docs'
-// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \
-// '👎 Deprecated since 1.0.0: text'
-// @has - '<code>test</code>&nbsp;<a href="https://issue_url/32374">#32374</a>'
+// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]/span' '👎'
+// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]/span' \
+// 'Deprecated since 1.0.0: text'
+// @hasraw - '<code>test</code>&nbsp;<a href="https://issue_url/32374">#32374</a>'
+// @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' '🔬'
// @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' \
-// '🔬 This is a nightly-only experimental API. \(test\s#32374\)$'
+// 'This is a nightly-only experimental API. \(test\s#32374\)$'
/// Docs
#[deprecated(since = "1.0.0", note = "text")]
#[unstable(feature = "test", issue = "32374")]
pub struct T;
+// @has issue_32374/struct.U.html '//*[@class="stab deprecated"]' '👎'
// @has issue_32374/struct.U.html '//*[@class="stab deprecated"]' \
-// '👎 Deprecated since 1.0.0: deprecated'
+// 'Deprecated since 1.0.0: deprecated'
+// @has issue_32374/struct.U.html '//*[@class="stab unstable"]' '🔬'
// @has issue_32374/struct.U.html '//*[@class="stab unstable"]' \
-// '🔬 This is a nightly-only experimental API. (test #32374)'
+// 'This is a nightly-only experimental API. (test #32374)'
#[deprecated(since = "1.0.0", note = "deprecated")]
#[unstable(feature = "test", issue = "32374", reason = "unstable")]
pub struct U;
diff --git a/src/test/rustdoc/issue-32395.rs b/src/test/rustdoc/issue-32395.rs
index 13468c153..5552300f9 100644
--- a/src/test/rustdoc/issue-32395.rs
+++ b/src/test/rustdoc/issue-32395.rs
@@ -3,13 +3,13 @@
// ignore-cross-compile
// @has variant_struct/enum.Foo.html
-// @!has - 'pub qux'
-// @!has - 'pub(crate) qux'
-// @!has - 'pub Bar'
+// @!hasraw - 'pub qux'
+// @!hasraw - 'pub(crate) qux'
+// @!hasraw - 'pub Bar'
extern crate variant_struct;
// @has issue_32395/enum.Foo.html
-// @!has - 'pub qux'
-// @!has - 'pub(crate) qux'
-// @!has - 'pub Bar'
+// @!hasraw - 'pub qux'
+// @!hasraw - 'pub(crate) qux'
+// @!hasraw - 'pub Bar'
pub use variant_struct::Foo;
diff --git a/src/test/rustdoc/issue-34473.rs b/src/test/rustdoc/issue-34473.rs
index d96301f3a..37da3dd19 100644
--- a/src/test/rustdoc/issue-34473.rs
+++ b/src/test/rustdoc/issue-34473.rs
@@ -5,7 +5,7 @@ mod second {
}
// @has foo/index.html
-// @!has - SomeTypeWithLongName
+// @!hasraw - SomeTypeWithLongName
// @has foo/struct.SomeType.html
// @!has foo/struct.SomeTypeWithLongName.html
pub use second::{SomeTypeWithLongName as SomeType};
diff --git a/src/test/rustdoc/issue-34928.rs b/src/test/rustdoc/issue-34928.rs
index 4184086f6..91b677574 100644
--- a/src/test/rustdoc/issue-34928.rs
+++ b/src/test/rustdoc/issue-34928.rs
@@ -2,5 +2,5 @@
pub trait Bar {}
-// @has foo/struct.Foo.html '//pre' 'pub struct Foo<T>(pub T) where T: Bar;'
+// @has foo/struct.Foo.html '//pre' 'pub struct Foo<T>(pub T)where T: Bar;'
pub struct Foo<T>(pub T) where T: Bar;
diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html
new file mode 100644
index 000000000..89987491d
--- /dev/null
+++ b/src/test/rustdoc/issue-41783.codeblock.html
@@ -0,0 +1,5 @@
+<code># single
+## double
+### triple
+<span class="attribute">#[outer]
+#![inner]</span></code>
diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs
index cb9b9b153..87267a750 100644
--- a/src/test/rustdoc/issue-41783.rs
+++ b/src/test/rustdoc/issue-41783.rs
@@ -1,11 +1,11 @@
// @has issue_41783/struct.Foo.html
-// @!has - 'space'
-// @!has - 'comment'
-// @has - '# <span class="ident">single'
-// @has - '## <span class="ident">double</span>'
-// @has - '### <span class="ident">triple</span>'
-// @has - '<span class="attribute">#[<span class="ident">outer</span>]</span>'
-// @has - '<span class="attribute">#![<span class="ident">inner</span>]</span>'
+// @!hasraw - 'space'
+// @!hasraw - 'comment'
+// @hasraw - '<span class="attribute">#[outer]'
+// @!hasraw - '<span class="attribute">#[outer]</span>'
+// @hasraw - '#![inner]</span>'
+// @!hasraw - '<span class="attribute">#![inner]</span>'
+// @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code'
/// ```no_run
/// # # space
diff --git a/src/test/rustdoc/issue-50159.rs b/src/test/rustdoc/issue-50159.rs
index d88c29217..43fb705f5 100644
--- a/src/test/rustdoc/issue-50159.rs
+++ b/src/test/rustdoc/issue-50159.rs
@@ -11,8 +11,8 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
}
// @has issue_50159/struct.Switch.html
-// @has - '//h3[@class="code-header in-band"]' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
-// @has - '//h3[@class="code-header in-band"]' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
+// @has - '//h3[@class="code-header in-band"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
+// @has - '//h3[@class="code-header in-band"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
pub struct Switch<B: Signal> {
diff --git a/src/test/rustdoc/issue-51236.rs b/src/test/rustdoc/issue-51236.rs
index ee11ccc68..aa5890a84 100644
--- a/src/test/rustdoc/issue-51236.rs
+++ b/src/test/rustdoc/issue-51236.rs
@@ -8,7 +8,7 @@ pub mod traits {
// @has issue_51236/struct.Owned.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Owned<T> where <T as Owned<'static>>::Reader: Send"
+// "impl<T> Send for Owned<T>where <T as Owned<'static>>::Reader: Send"
pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,
}
diff --git a/src/test/rustdoc/issue-53689.rs b/src/test/rustdoc/issue-53689.rs
index 52ce4159d..832140e06 100644
--- a/src/test/rustdoc/issue-53689.rs
+++ b/src/test/rustdoc/issue-53689.rs
@@ -5,7 +5,7 @@
extern crate issue_53689;
// @has foo/trait.MyTrait.html
-// @!has - 'MyStruct'
+// @!hasraw - 'MyStruct'
// @count - '//*[h3="impl<T> MyTrait for T"]' 1
pub trait MyTrait {}
diff --git a/src/test/rustdoc/issue-54705.rs b/src/test/rustdoc/issue-54705.rs
index bedaf5c4d..ce0f85d25 100644
--- a/src/test/rustdoc/issue-54705.rs
+++ b/src/test/rustdoc/issue-54705.rs
@@ -1,13 +1,11 @@
pub trait ScopeHandle<'scope> {}
-
-
// @has issue_54705/struct.ScopeFutureContents.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'scope, S> Send for ScopeFutureContents<'scope, S> where S: Sync"
+// "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync"
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S> where S: Sync"
+// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync"
pub struct ScopeFutureContents<'scope, S>
where S: ScopeHandle<'scope>,
{
diff --git a/src/test/rustdoc/issue-61592.rs b/src/test/rustdoc/issue-61592.rs
index aef038c07..4b6c37b94 100644
--- a/src/test/rustdoc/issue-61592.rs
+++ b/src/test/rustdoc/issue-61592.rs
@@ -5,11 +5,11 @@ extern crate foo;
// @has issue_61592/index.html
// @has - '//a[@href="#reexports"]' 'Re-exports'
// @has - '//code' 'pub use foo::FooTrait as _;'
-// @!has - '//a[@href="trait._.html"]'
+// @!has - '//a[@href="trait._.html"]' ''
pub use foo::FooTrait as _;
// @has issue_61592/index.html
// @has - '//a[@href="#reexports"]' 'Re-exports'
// @has - '//code' 'pub use foo::FooStruct as _;'
-// @!has - '//a[@href="struct._.html"]'
+// @!has - '//a[@href="struct._.html"]' ''
pub use foo::FooStruct as _;
diff --git a/src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs b/src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs
new file mode 100644
index 000000000..d3a7a870b
--- /dev/null
+++ b/src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+pub mod sub {
+ pub struct Item;
+
+ pub mod prelude {
+ pub use super::Item;
+ }
+}
+
+#[doc(inline)]
+pub use sub::*;
+
+// @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1
+// @count foo/prelude/index.html '//div[@class="item-row"]' 0
+pub mod prelude {}
diff --git a/src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs b/src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs
new file mode 100644
index 000000000..b83692509
--- /dev/null
+++ b/src/test/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+pub mod sub {
+ pub struct Item;
+
+ pub mod prelude {
+ pub use super::Item;
+ }
+}
+
+// @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1
+// @count foo/prelude/index.html '//div[@class="item-row"]' 0
+pub mod prelude {}
+
+#[doc(inline)]
+pub use sub::*;
diff --git a/src/test/rustdoc/issue-89852.rs b/src/test/rustdoc/issue-89852.rs
index 45544dbee..4f2da5e07 100644
--- a/src/test/rustdoc/issue-89852.rs
+++ b/src/test/rustdoc/issue-89852.rs
@@ -3,8 +3,8 @@
#![no_core]
#![feature(no_core)]
-// @matches 'issue_89852/sidebar-items.js' '"repro"'
-// @!matches 'issue_89852/sidebar-items.js' '"repro".*"repro"'
+// @matchesraw 'issue_89852/sidebar-items.js' '"repro"'
+// @!matchesraw 'issue_89852/sidebar-items.js' '"repro".*"repro"'
#[macro_export]
macro_rules! repro {
diff --git a/src/test/rustdoc/issue-98697.rs b/src/test/rustdoc/issue-98697.rs
index 83e08094c..a8841f137 100644
--- a/src/test/rustdoc/issue-98697.rs
+++ b/src/test/rustdoc/issue-98697.rs
@@ -8,7 +8,7 @@
extern crate issue_98697_reexport_with_anonymous_lifetime;
-// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>() where F: Fn(&str)'
+// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>()where F: Fn(&str)'
// @!has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'for<'
pub use issue_98697_reexport_with_anonymous_lifetime::repro;
diff --git a/src/test/rustdoc/link-title-escape.rs b/src/test/rustdoc/link-title-escape.rs
index 01aa8d00b..7a322ea6d 100644
--- a/src/test/rustdoc/link-title-escape.rs
+++ b/src/test/rustdoc/link-title-escape.rs
@@ -6,4 +6,4 @@
//!
//! [foo]: url 'title & <stuff> & "things"'
-// @has 'foo/index.html' 'title &amp; &lt;stuff&gt; &amp; &quot;things&quot;'
+// @hasraw 'foo/index.html' 'title &amp; &lt;stuff&gt; &amp; &quot;things&quot;'
diff --git a/src/test/rustdoc/macro-document-private-duplicate.rs b/src/test/rustdoc/macro-document-private-duplicate.rs
index 7576c1326..d3cf7e140 100644
--- a/src/test/rustdoc/macro-document-private-duplicate.rs
+++ b/src/test/rustdoc/macro-document-private-duplicate.rs
@@ -4,21 +4,21 @@
// (yes, that's a thing), rustdoc lists both of them on the index page,
// but only documents the first one on the page for the macro.
// Fortunately, this can only happen in document private items mode,
-// but it still isn't ideal beahvior.
+// but it still isn't ideal behavior.
//
// See https://github.com/rust-lang/rust/pull/88019#discussion_r693920453
//
// compile-flags: --document-private-items
-// @has macro_document_private_duplicate/index.html 'Doc 1.'
-// @has macro_document_private_duplicate/macro.a_macro.html 'Doc 1.'
+// @hasraw macro_document_private_duplicate/index.html 'Doc 1.'
+// @hasraw macro_document_private_duplicate/macro.a_macro.html 'Doc 1.'
/// Doc 1.
macro_rules! a_macro {
() => ()
}
-// @has macro_document_private_duplicate/index.html 'Doc 2.'
-// @!has macro_document_private_duplicate/macro.a_macro.html 'Doc 2.'
+// @hasraw macro_document_private_duplicate/index.html 'Doc 2.'
+// @!hasraw macro_document_private_duplicate/macro.a_macro.html 'Doc 2.'
/// Doc 2.
macro_rules! a_macro {
() => ()
diff --git a/src/test/rustdoc/macro-private-not-documented.rs b/src/test/rustdoc/macro-private-not-documented.rs
index ae8b0e722..f135a3a9c 100644
--- a/src/test/rustdoc/macro-private-not-documented.rs
+++ b/src/test/rustdoc/macro-private-not-documented.rs
@@ -6,13 +6,13 @@
// This is a regression text for issue #88453.
#![feature(decl_macro)]
-// @!has macro_private_not_documented/index.html 'a_macro'
+// @!hasraw macro_private_not_documented/index.html 'a_macro'
// @!has macro_private_not_documented/macro.a_macro.html
macro_rules! a_macro {
() => ()
}
-// @!has macro_private_not_documented/index.html 'another_macro'
+// @!hasraw macro_private_not_documented/index.html 'another_macro'
// @!has macro_private_not_documented/macro.another_macro.html
macro another_macro {
() => ()
diff --git a/src/test/rustdoc/macro_rules-matchers.rs b/src/test/rustdoc/macro_rules-matchers.rs
index efc3b21e6..96f4126c7 100644
--- a/src/test/rustdoc/macro_rules-matchers.rs
+++ b/src/test/rustdoc/macro_rules-matchers.rs
@@ -5,32 +5,27 @@
// @has 'foo/macro.todo.html'
// @has - '//span[@class="macro"]' 'macro_rules!'
-// @has - '//span[@class="ident"]' 'todo'
-// Note: the only op is the `+`
-// @count - '//pre[@class="rust macro"]//span[@class="op"]' 1
+// @hasraw - ' todo {'
-// @has - '{ () =&gt; { ... }; ($('
+// @hasraw - '{ () =&gt; { ... }; ($('
// @has - '//span[@class="macro-nonterminal"]' '$'
// @has - '//span[@class="macro-nonterminal"]' 'arg'
-// @has - ':'
-// @has - '//span[@class="ident"]' 'tt'
-// @has - '),'
-// @has - '//span[@class="op"]' '+'
-// @has - ') =&gt; { ... }; }'
+// @hasraw - ':tt)+'
+// @hasraw - ') =&gt; { ... }; }'
pub use std::todo;
mod mod1 {
// @has 'foo/macro.macro1.html'
- // @has - 'macro_rules!'
- // @has - 'macro1'
- // @has - '{ () =&gt; { ... }; ($('
+ // @hasraw - 'macro_rules!'
+ // @hasraw - 'macro1'
+ // @hasraw - '{ () =&gt; { ... }; ($('
// @has - '//span[@class="macro-nonterminal"]' '$'
// @has - '//span[@class="macro-nonterminal"]' 'arg'
- // @has - ':'
- // @has - 'expr'
- // @has - '),'
- // @has - '+'
- // @has - ') =&gt; { ... }; }'
+ // @hasraw - ':'
+ // @hasraw - 'expr'
+ // @hasraw - '),'
+ // @hasraw - '+'
+ // @hasraw - ') =&gt; { ... }; }'
#[macro_export]
macro_rules! macro1 {
() => {};
diff --git a/src/test/rustdoc/markdown-summaries.rs b/src/test/rustdoc/markdown-summaries.rs
index b843e28e7..31e7072b5 100644
--- a/src/test/rustdoc/markdown-summaries.rs
+++ b/src/test/rustdoc/markdown-summaries.rs
@@ -7,21 +7,21 @@
//!
//! [link]: https://example.com
-// @has search-index.js 'This <em>summary</em> has a link and <code>code</code>.'
-// @!has - 'second paragraph'
+// @hasraw search-index.js 'This <em>summary</em> has a link and <code>code</code>.'
+// @!hasraw - 'second paragraph'
/// This `code` will be rendered in a code tag.
///
/// This text should not be rendered.
pub struct Sidebar;
-// @has search-index.js 'This <code>code</code> will be rendered in a code tag.'
-// @has summaries/sidebar-items.js 'This `code` will be rendered in a code tag.'
-// @!has - 'text should not be rendered'
+// @hasraw search-index.js 'This <code>code</code> will be rendered in a code tag.'
+// @hasraw summaries/sidebar-items.js 'This `code` will be rendered in a code tag.'
+// @!hasraw - 'text should not be rendered'
/// ```text
/// this block should not be rendered
/// ```
pub struct Sidebar2;
-// @!has summaries/sidebar-items.js 'block should not be rendered'
+// @!hasraw summaries/sidebar-items.js 'block should not be rendered'
diff --git a/src/test/rustdoc/masked.rs b/src/test/rustdoc/masked.rs
index c7ad690d6..80d5b99c0 100644
--- a/src/test/rustdoc/masked.rs
+++ b/src/test/rustdoc/masked.rs
@@ -7,24 +7,24 @@
#[doc(masked)]
extern crate masked;
-// @!has 'search-index.js' 'masked_method'
+// @!hasraw 'search-index.js' 'masked_method'
-// @!has 'foo/struct.String.html' 'MaskedTrait'
-// @!has 'foo/struct.String.html' 'masked_method'
+// @!hasraw 'foo/struct.String.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.String.html' 'masked_method'
pub use std::string::String;
-// @!has 'foo/trait.Clone.html' 'MaskedStruct'
+// @!hasraw 'foo/trait.Clone.html' 'MaskedStruct'
pub use std::clone::Clone;
-// @!has 'foo/struct.MyStruct.html' 'MaskedTrait'
-// @!has 'foo/struct.MyStruct.html' 'masked_method'
+// @!hasraw 'foo/struct.MyStruct.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.MyStruct.html' 'masked_method'
pub struct MyStruct;
impl masked::MaskedTrait for MyStruct {
fn masked_method() {}
}
-// @!has 'foo/trait.MyTrait.html' 'MaskedStruct'
+// @!hasraw 'foo/trait.MyTrait.html' 'MaskedStruct'
pub trait MyTrait {}
impl MyTrait for masked::MaskedStruct {}
diff --git a/src/test/rustdoc/module-impls.rs b/src/test/rustdoc/module-impls.rs
index 198b3446c..852f444e9 100644
--- a/src/test/rustdoc/module-impls.rs
+++ b/src/test/rustdoc/module-impls.rs
@@ -2,4 +2,4 @@
pub use std::marker::Send;
-// @!has foo/index.html 'Implementations'
+// @!hasraw foo/index.html 'Implementations'
diff --git a/src/test/rustdoc/nested-modules.rs b/src/test/rustdoc/nested-modules.rs
index 1596f4674..12234d2cf 100644
--- a/src/test/rustdoc/nested-modules.rs
+++ b/src/test/rustdoc/nested-modules.rs
@@ -7,22 +7,22 @@ mod a_module {
pub mod a_nested_module {
// @has aCrate/a_nested_module/index.html '//a[@href="fn.a_nested_public_function.html"]' 'a_nested_public_function'
- // @has aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
+ // @hasraw aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
pub fn a_nested_public_function() {}
// @has aCrate/a_nested_module/index.html '//a[@href="fn.another_nested_public_function.html"]' 'another_nested_public_function'
- // @has aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
+ // @hasraw aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
pub use a_nested_module::a_nested_public_function as another_nested_public_function;
}
- // @!has aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
+ // @!hasraw aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
pub use a_nested_module::a_nested_public_function as yet_another_nested_public_function;
- // @!has aCrate/a_nested_module/index.html 'one_last_nested_public_function'
+ // @!hasraw aCrate/a_nested_module/index.html 'one_last_nested_public_function'
pub use a_nested_module::another_nested_public_function as one_last_nested_public_function;
}
-// @!has aCrate/index.html 'a_module'
+// @!hasraw aCrate/index.html 'a_module'
// @has aCrate/index.html '//a[@href="a_nested_module/index.html"]' 'a_nested_module'
pub use a_module::a_nested_module;
@@ -36,7 +36,7 @@ pub use a_module::{
};
// @has aCrate/index.html '//a[@href="fn.private_function.html"]' 'private_function'
-// @!has aCrate/fn.private_function.html 'a_module'
+// @!hasraw aCrate/fn.private_function.html 'a_module'
// @has aCrate/index.html '//a[@href="fn.other_private_function.html"]' 'other_private_function'
-// @!has aCrate/fn.other_private_function.html 'a_module'
+// @!hasraw aCrate/fn.other_private_function.html 'a_module'
pub use a_module::{other_private_function, private_function};
diff --git a/src/test/rustdoc/no-crate-filter.rs b/src/test/rustdoc/no-crate-filter.rs
index c694d1456..b2f899064 100644
--- a/src/test/rustdoc/no-crate-filter.rs
+++ b/src/test/rustdoc/no-crate-filter.rs
@@ -2,5 +2,5 @@
// compile-flags: -Z unstable-options --disable-per-crate-search
-// @!has 'foo/struct.Foo.html' '//*[id="crate-search"]'
+// @!has 'foo/struct.Foo.html' '//*[id="crate-search"]' ''
pub struct Foo;
diff --git a/src/test/rustdoc/primitive-reference.rs b/src/test/rustdoc/primitive-reference.rs
new file mode 100644
index 000000000..5c1193406
--- /dev/null
+++ b/src/test/rustdoc/primitive-reference.rs
@@ -0,0 +1,37 @@
+#![crate_name = "foo"]
+
+#![feature(rustdoc_internals)]
+
+// @has foo/index.html
+// @has - '//h2[@id="primitives"]' 'Primitive Types'
+// @has - '//a[@href="primitive.reference.html"]' 'reference'
+// @has - '//div[@class="sidebar-elems"]//li/a' 'Primitive Types'
+// @has - '//div[@class="sidebar-elems"]//li/a/@href' '#primitives'
+// @has foo/primitive.reference.html
+// @has - '//a[@class="primitive"]' 'reference'
+// @has - '//span[@class="in-band"]' 'Primitive Type reference'
+// @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
+
+// There should be only one implementation listed.
+// @count - '//*[@class="impl has-srclink"]' 1
+// @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header in-band"]' \
+// 'impl<A, B> Foo<&A> for &B'
+#[doc(primitive = "reference")]
+/// this is a test!
+mod reference {}
+
+pub struct Bar;
+
+// This implementation should **not** show up.
+impl<T> From<&T> for Bar {
+ fn from(s: &T) -> Self {
+ Bar
+ }
+}
+
+pub trait Foo<T> {
+ fn stuff(&self, other: &T) {}
+}
+
+// This implementation should show up.
+impl<A, B> Foo<&A> for &B {}
diff --git a/src/test/rustdoc/primitive-slice-auto-trait.rs b/src/test/rustdoc/primitive-slice-auto-trait.rs
index b3f511bc1..7f8f74ff4 100644
--- a/src/test/rustdoc/primitive-slice-auto-trait.rs
+++ b/src/test/rustdoc/primitive-slice-auto-trait.rs
@@ -7,8 +7,8 @@
// @has - '//span[@class="in-band"]' 'Primitive Type slice'
// @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
-// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T] where T: Send'
-// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T] where T: Sync'
+// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T]where T: Send'
+// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T]where T: Sync'
#[doc(primitive = "slice")]
/// this is a test!
mod slice_prim {}
diff --git a/src/test/rustdoc/recursive-deref.rs b/src/test/rustdoc/recursive-deref.rs
index a7504fbcc..2ab9d44be 100644
--- a/src/test/rustdoc/recursive-deref.rs
+++ b/src/test/rustdoc/recursive-deref.rs
@@ -51,7 +51,7 @@ impl G {
// @has recursive_deref/struct.D.html '//h3[@class="code-header in-band"]' 'impl Deref for D'
// We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
impl Deref for D {
type Target = E;
@@ -62,7 +62,7 @@ impl Deref for D {
// @has recursive_deref/struct.E.html '//h3[@class="code-header in-band"]' 'impl Deref for E'
// We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
impl Deref for E {
type Target = F;
@@ -73,7 +73,7 @@ impl Deref for E {
// @has recursive_deref/struct.F.html '//h3[@class="code-header in-band"]' 'impl Deref for F'
// We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
impl Deref for F {
type Target = G;
@@ -101,7 +101,7 @@ impl I {
}
// @has recursive_deref/struct.H.html '//h3[@class="code-header in-band"]' 'impl Deref for H'
-// @!has '-' '//*[@id="deref-methods-I"]'
+// @!has '-' '//*[@id="deref-methods-I"]' ''
impl Deref for H {
type Target = I;
diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs
index e2b232a6e..599c429a6 100644
--- a/src/test/rustdoc/remove-url-from-headings.rs
+++ b/src/test/rustdoc/remove-url-from-headings.rs
@@ -1,7 +1,7 @@
#![crate_name = "foo"]
// @has foo/fn.foo.html
-// @!has - '//a[@href="http://a.a"]'
+// @!has - '//a[@href="http://a.a"]' ''
// @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere'
// @has - '//a[@href="#another-one-urg"]' 'Another one urg'
diff --git a/src/test/rustdoc/rustc-incoherent-impls.rs b/src/test/rustdoc/rustc-incoherent-impls.rs
new file mode 100644
index 000000000..3fdefbecc
--- /dev/null
+++ b/src/test/rustdoc/rustc-incoherent-impls.rs
@@ -0,0 +1,28 @@
+// aux-build:incoherent-impl-types.rs
+// build-aux-docs
+
+#![crate_name = "foo"]
+#![feature(rustc_attrs)]
+
+extern crate incoherent_impl_types;
+
+// The only way this actually shows up is if the type gets inlined.
+#[doc(inline)]
+pub use incoherent_impl_types::FooTrait;
+
+// @has foo/trait.FooTrait.html
+// @count - '//section[@id="method.do_something"]' 1
+impl dyn FooTrait {
+ #[rustc_allow_incoherent_impl]
+ pub fn do_something() {}
+}
+
+#[doc(inline)]
+pub use incoherent_impl_types::FooStruct;
+
+// @has foo/struct.FooStruct.html
+// @count - '//section[@id="method.do_something"]' 1
+impl FooStruct {
+ #[rustc_allow_incoherent_impl]
+ pub fn do_something() {}
+}
diff --git a/src/test/rustdoc/search-index-summaries.rs b/src/test/rustdoc/search-index-summaries.rs
index dd9c1a0b4..efd366405 100644
--- a/src/test/rustdoc/search-index-summaries.rs
+++ b/src/test/rustdoc/search-index-summaries.rs
@@ -1,8 +1,8 @@
#![crate_name = "foo"]
-// @has 'search-index.js' 'Foo short link.'
-// @!has - 'www.example.com'
-// @!has - 'More Foo.'
+// @hasraw 'search-index.js' 'Foo short link.'
+// @!hasraw - 'www.example.com'
+// @!hasraw - 'More Foo.'
/// Foo short [link](https://www.example.com/).
///
diff --git a/src/test/rustdoc/search-index.rs b/src/test/rustdoc/search-index.rs
index f1b78f172..d1d05eb88 100644
--- a/src/test/rustdoc/search-index.rs
+++ b/src/test/rustdoc/search-index.rs
@@ -2,25 +2,25 @@
use std::ops::Deref;
-// @has search-index.js Foo
+// @hasraw search-index.js Foo
pub use private::Foo;
mod private {
pub struct Foo;
impl Foo {
- pub fn test_method() {} // @has - test_method
- fn priv_method() {} // @!has - priv_method
+ pub fn test_method() {} // @hasraw - test_method
+ fn priv_method() {} // @!hasraw - priv_method
}
pub trait PrivateTrait {
- fn trait_method(&self) {} // @!has - priv_method
+ fn trait_method(&self) {} // @!hasraw - priv_method
}
}
pub struct Bar;
impl Deref for Bar {
- // @!has search-index.js Target
+ // @!hasraw search-index.js Target
type Target = Bar;
fn deref(&self) -> &Bar { self }
}
diff --git a/src/test/rustdoc/short-docblock-codeblock.rs b/src/test/rustdoc/short-docblock-codeblock.rs
index c6b318b06..3c5fa7b36 100644
--- a/src/test/rustdoc/short-docblock-codeblock.rs
+++ b/src/test/rustdoc/short-docblock-codeblock.rs
@@ -1,8 +1,6 @@
#![crate_name = "foo"]
-// @has foo/index.html '//*[@class="item-right docblock-short"]' ""
-// @!has foo/index.html '//*[@class="item-right docblock-short"]' "Some text."
-// @!has foo/index.html '//*[@class="item-right docblock-short"]' "let x = 12;"
+// @count foo/index.html '//*[@class="item-right docblock-short"]' 0
/// ```
/// let x = 12;
diff --git a/src/test/rustdoc/short-docblock.rs b/src/test/rustdoc/short-docblock.rs
index 17c44eab0..1a8a689be 100644
--- a/src/test/rustdoc/short-docblock.rs
+++ b/src/test/rustdoc/short-docblock.rs
@@ -1,7 +1,7 @@
#![crate_name = "foo"]
-// @has foo/index.html '//*[@class="item-right docblock-short"]/p' 'fooo'
-// @!has foo/index.html '//*[@class="item-right docblock-short"]/p/h1' 'fooo'
+// @has foo/index.html '//*[@class="item-right docblock-short"]' 'fooo'
+// @!has foo/index.html '//*[@class="item-right docblock-short"]/h1' 'fooo'
// @has foo/fn.foo.html '//h2[@id="fooo"]/a[@href="#fooo"]' 'fooo'
/// # fooo
@@ -9,8 +9,8 @@
/// foo
pub fn foo() {}
-// @has foo/index.html '//*[@class="item-right docblock-short"]/p' 'mooood'
-// @!has foo/index.html '//*[@class="item-right docblock-short"]/p/h2' 'mooood'
+// @has foo/index.html '//*[@class="item-right docblock-short"]' 'mooood'
+// @!has foo/index.html '//*[@class="item-right docblock-short"]/h2' 'mooood'
// @has foo/foo/index.html '//h3[@id="mooood"]/a[@href="#mooood"]' 'mooood'
/// ## mooood
@@ -18,7 +18,7 @@ pub fn foo() {}
/// foo mod
pub mod foo {}
-// @has foo/index.html '//*[@class="item-right docblock-short"]/p/a[@href=\
+// @has foo/index.html '//*[@class="item-right docblock-short"]/a[@href=\
// "https://nougat.world"]/code' 'nougat'
/// [`nougat`](https://nougat.world)
diff --git a/src/test/rustdoc/show-const-contents.rs b/src/test/rustdoc/show-const-contents.rs
index 48b608859..69e742ee7 100644
--- a/src/test/rustdoc/show-const-contents.rs
+++ b/src/test/rustdoc/show-const-contents.rs
@@ -1,57 +1,57 @@
// Test that the contents of constants are displayed as part of the
// documentation.
-// @has show_const_contents/constant.CONST_S.html 'show this'
-// @!has show_const_contents/constant.CONST_S.html '; //'
+// @hasraw show_const_contents/constant.CONST_S.html 'show this'
+// @!hasraw show_const_contents/constant.CONST_S.html '; //'
pub const CONST_S: &'static str = "show this";
-// @has show_const_contents/constant.CONST_I32.html '= 42;'
-// @!has show_const_contents/constant.CONST_I32.html '; //'
+// @hasraw show_const_contents/constant.CONST_I32.html '= 42;'
+// @!hasraw show_const_contents/constant.CONST_I32.html '; //'
pub const CONST_I32: i32 = 42;
-// @has show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
-// @!has show_const_contents/constant.CONST_I32_HEX.html '; //'
+// @hasraw show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
+// @!hasraw show_const_contents/constant.CONST_I32_HEX.html '; //'
pub const CONST_I32_HEX: i32 = 0x42;
-// @has show_const_contents/constant.CONST_NEG_I32.html '= -42;'
-// @!has show_const_contents/constant.CONST_NEG_I32.html '; //'
+// @hasraw show_const_contents/constant.CONST_NEG_I32.html '= -42;'
+// @!hasraw show_const_contents/constant.CONST_NEG_I32.html '; //'
pub const CONST_NEG_I32: i32 = -42;
-// @has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
-// @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
+// @hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
+// @!hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;
-// @has show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
+// @hasraw show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
pub const CONST_CALC_I32: i32 = 42 + 1;
-// @!has show_const_contents/constant.CONST_REF_I32.html '= &42;'
-// @!has show_const_contents/constant.CONST_REF_I32.html '; //'
+// @!hasraw show_const_contents/constant.CONST_REF_I32.html '= &42;'
+// @!hasraw show_const_contents/constant.CONST_REF_I32.html '; //'
pub const CONST_REF_I32: &'static i32 = &42;
-// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
+// @hasraw show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
pub const CONST_I32_MAX: i32 = i32::MAX;
-// @!has show_const_contents/constant.UNIT.html '= ();'
-// @!has show_const_contents/constant.UNIT.html '; //'
+// @!hasraw show_const_contents/constant.UNIT.html '= ();'
+// @!hasraw show_const_contents/constant.UNIT.html '; //'
pub const UNIT: () = ();
pub struct MyType(i32);
-// @!has show_const_contents/constant.MY_TYPE.html '= MyType(42);'
-// @!has show_const_contents/constant.MY_TYPE.html '; //'
+// @!hasraw show_const_contents/constant.MY_TYPE.html '= MyType(42);'
+// @!hasraw show_const_contents/constant.MY_TYPE.html '; //'
pub const MY_TYPE: MyType = MyType(42);
pub struct MyTypeWithStr(&'static str);
-// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
-// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
+// @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
+// @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");
-// @has show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
-// @has show_const_contents/constant.PI.html '; // 3.14159274f32'
+// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
+// @hasraw show_const_contents/constant.PI.html '; // 3.14159274f32'
pub use std::f32::consts::PI;
-// @has show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
+// @hasraw show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
#[allow(deprecated, deprecated_in_future)]
pub use std::i32::MAX;
@@ -61,7 +61,7 @@ macro_rules! int_module {
)
}
-// @has show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
+// @hasraw show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
int_module!(i16);
// @has show_const_contents/constant.ESCAPE.html //pre '= r#"<script>alert("ESCAPE");</script>"#;'
diff --git a/src/test/rustdoc/sized_trait.rs b/src/test/rustdoc/sized_trait.rs
index 9d2c19677..36718ebe1 100644
--- a/src/test/rustdoc/sized_trait.rs
+++ b/src/test/rustdoc/sized_trait.rs
@@ -1,13 +1,13 @@
#![crate_name = "foo"]
// @has foo/struct.Bar.html
-// @!has - '//*[@id="impl-Sized"]'
+// @!has - '//*[@id="impl-Sized"]' ''
pub struct Bar {
a: u16,
}
// @has foo/struct.Foo.html
-// @!has - '//*[@id="impl-Sized"]'
+// @!has - '//*[@id="impl-Sized"]' ''
pub struct Foo<T: ?Sized>(T);
// @has foo/struct.Unsized.html
diff --git a/src/test/rustdoc/sort-modules-by-appearance.rs b/src/test/rustdoc/sort-modules-by-appearance.rs
index 5be6b9826..b5cc8bc83 100644
--- a/src/test/rustdoc/sort-modules-by-appearance.rs
+++ b/src/test/rustdoc/sort-modules-by-appearance.rs
@@ -9,5 +9,5 @@ pub mod module_c {}
pub mod module_a {}
-// @matches 'sort_modules_by_appearance/index.html' '(?s)module_b.*module_c.*module_a'
-// @matches 'sort_modules_by_appearance/sidebar-items.js' '"module_b".*"module_c".*"module_a"'
+// @matchesraw 'sort_modules_by_appearance/index.html' '(?s)module_b.*module_c.*module_a'
+// @matchesraw 'sort_modules_by_appearance/sidebar-items.js' '"module_b".*"module_c".*"module_a"'
diff --git a/src/test/rustdoc/source-file.rs b/src/test/rustdoc/source-file.rs
index 968899dab..4e1664790 100644
--- a/src/test/rustdoc/source-file.rs
+++ b/src/test/rustdoc/source-file.rs
@@ -1,5 +1,5 @@
#![crate_name = "foo"]
-// @has source-files.js source-file.rs
+// @hasraw source-files.js source-file.rs
pub struct Foo;
diff --git a/src/test/rustdoc/src-links-auto-impls.rs b/src/test/rustdoc/src-links-auto-impls.rs
index 69be9aa8d..313a4b118 100644
--- a/src/test/rustdoc/src-links-auto-impls.rs
+++ b/src/test/rustdoc/src-links-auto-impls.rs
@@ -6,7 +6,7 @@
// @has - '//*[@id="impl-Sync-for-Unsized"]/h3[@class="code-header in-band"]' 'impl Sync for Unsized'
// @!has - '//*[@id="impl-Sync-for-Unsized"]//a[@class="srclink"]' 'source'
// @has - '//*[@id="impl-Any-for-Unsized"]/h3[@class="code-header in-band"]' 'impl<T> Any for T'
-// @has - '//*[@id="impl-Any-for-Unsized"]//a[@class="srclink"]' 'source'
+// @has - '//*[@id="impl-Any-for-Unsized"]//a[@class="srclink rightside"]' 'source'
pub struct Unsized {
data: [u8],
}
diff --git a/src/test/rustdoc/static-root-path.rs b/src/test/rustdoc/static-root-path.rs
index f1d49b9fc..08c055c5b 100644
--- a/src/test/rustdoc/static-root-path.rs
+++ b/src/test/rustdoc/static-root-path.rs
@@ -1,18 +1,18 @@
// compile-flags:-Z unstable-options --static-root-path /cache/
// @has static_root_path/struct.SomeStruct.html
-// @matches - '"/cache/main\.js"'
-// @!matches - '"\.\./main\.js"'
-// @matches - 'data-root-path="\.\./"'
-// @!matches - '"/cache/search-index\.js"'
+// @matchesraw - '"/cache/main\.js"'
+// @!matchesraw - '"\.\./main\.js"'
+// @matchesraw - 'data-root-path="\.\./"'
+// @!matchesraw - '"/cache/search-index\.js"'
pub struct SomeStruct;
// @has src/static_root_path/static-root-path.rs.html
-// @matches - '"/cache/source-script\.js"'
-// @!matches - '"\.\./\.\./source-script\.js"'
-// @matches - '"\.\./\.\./source-files.js"'
-// @!matches - '"/cache/source-files\.js"'
+// @matchesraw - '"/cache/source-script\.js"'
+// @!matchesraw - '"\.\./\.\./source-script\.js"'
+// @matchesraw - '"\.\./\.\./source-files.js"'
+// @!matchesraw - '"/cache/source-files\.js"'
// @has settings.html
-// @matches - '/cache/settings\.js'
-// @!matches - '\./settings\.js'
+// @matchesraw - '/cache/settings\.js'
+// @!matchesraw - '\./settings\.js'
diff --git a/src/test/rustdoc/synthetic_auto/basic.rs b/src/test/rustdoc/synthetic_auto/basic.rs
index 54c54fdbf..19138fd1a 100644
--- a/src/test/rustdoc/synthetic_auto/basic.rs
+++ b/src/test/rustdoc/synthetic_auto/basic.rs
@@ -1,6 +1,6 @@
// @has basic/struct.Foo.html
-// @has - '//h3[@class="code-header in-band"]' 'impl<T> Send for Foo<T> where T: Send'
-// @has - '//h3[@class="code-header in-band"]' 'impl<T> Sync for Foo<T> where T: Sync'
+// @has - '//h3[@class="code-header in-band"]' 'impl<T> Send for Foo<T>where T: Send'
+// @has - '//h3[@class="code-header in-band"]' 'impl<T> Sync for Foo<T>where T: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl has-srclink"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
pub struct Foo<T> {
diff --git a/src/test/rustdoc/synthetic_auto/complex.rs b/src/test/rustdoc/synthetic_auto/complex.rs
index f9017b90c..39f78983d 100644
--- a/src/test/rustdoc/synthetic_auto/complex.rs
+++ b/src/test/rustdoc/synthetic_auto/complex.rs
@@ -21,7 +21,7 @@ mod foo {
// @has complex/struct.NotOuter.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
+// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \
// -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"
pub use foo::{Foo, Inner as NotInner, MyTrait as NotMyTrait, Outer as NotOuter};
diff --git a/src/test/rustdoc/synthetic_auto/lifetimes.rs b/src/test/rustdoc/synthetic_auto/lifetimes.rs
index ee1393f97..0c94850e7 100644
--- a/src/test/rustdoc/synthetic_auto/lifetimes.rs
+++ b/src/test/rustdoc/synthetic_auto/lifetimes.rs
@@ -10,10 +10,10 @@ where
// @has lifetimes/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Send for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
+// "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Sync for Foo<'c, K> where K: Sync"
+// "impl<'c, K> Sync for Foo<'c, K>where K: Sync"
pub struct Foo<'c, K: 'c> {
inner_field: Inner<'c, K>,
}
diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs
index 49bad1622..35047e3e8 100644
--- a/src/test/rustdoc/synthetic_auto/manual.rs
+++ b/src/test/rustdoc/synthetic_auto/manual.rs
@@ -1,6 +1,6 @@
// @has manual/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// 'impl<T> Sync for Foo<T> where T: Sync'
+// 'impl<T> Sync for Foo<T>where T: Sync'
//
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// 'impl<T> Send for Foo<T>'
diff --git a/src/test/rustdoc/synthetic_auto/nested.rs b/src/test/rustdoc/synthetic_auto/nested.rs
index 69edbee61..09587bcc3 100644
--- a/src/test/rustdoc/synthetic_auto/nested.rs
+++ b/src/test/rustdoc/synthetic_auto/nested.rs
@@ -10,10 +10,10 @@ where
// @has nested/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// 'impl<T> Send for Foo<T> where T: Copy'
+// 'impl<T> Send for Foo<T>where T: Copy'
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// 'impl<T> Sync for Foo<T> where T: Sync'
+// 'impl<T> Sync for Foo<T>where T: Sync'
pub struct Foo<T> {
inner_field: Inner<T>,
}
diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs
index 16ab876e8..41375decc 100644
--- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs
+++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs
@@ -10,7 +10,7 @@ where
// @has no_redundancy/struct.Outer.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Outer<T> where T: Send + Copy"
+// "impl<T> Send for Outer<T>where T: Send + Copy"
pub struct Outer<T> {
inner_field: Inner<T>,
}
diff --git a/src/test/rustdoc/synthetic_auto/project.rs b/src/test/rustdoc/synthetic_auto/project.rs
index 8b0205825..e80b1b1dc 100644
--- a/src/test/rustdoc/synthetic_auto/project.rs
+++ b/src/test/rustdoc/synthetic_auto/project.rs
@@ -24,10 +24,10 @@ where
// @has project/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Send for Foo<'c, K> where K: MyTrait<MyItem = bool>, 'c: 'static"
+// "impl<'c, K> Send for Foo<'c, K>where K: MyTrait<MyItem = bool>, 'c: 'static"
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Sync for Foo<'c, K> where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
+// "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
// 'c: 'static,"
pub struct Foo<'c, K: 'c> {
inner_field: Inner<'c, K>,
diff --git a/src/test/rustdoc/synthetic_auto/self-referential.rs b/src/test/rustdoc/synthetic_auto/self-referential.rs
index ccef901b1..d15a8de7d 100644
--- a/src/test/rustdoc/synthetic_auto/self-referential.rs
+++ b/src/test/rustdoc/synthetic_auto/self-referential.rs
@@ -24,6 +24,6 @@ impl<T> Pattern for Wrapper<T> {
// @has self_referential/struct.WriteAndThen.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<P1> Send for WriteAndThen<P1> where <P1 as Pattern>::Value: Send"
+// "impl<P1> Send for WriteAndThen<P1>where <P1 as Pattern>::Value: Send"
pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
where P1: Pattern;
diff --git a/src/test/rustdoc/synthetic_auto/static-region.rs b/src/test/rustdoc/synthetic_auto/static-region.rs
index 36e985144..08e956731 100644
--- a/src/test/rustdoc/synthetic_auto/static-region.rs
+++ b/src/test/rustdoc/synthetic_auto/static-region.rs
@@ -4,7 +4,7 @@ pub trait OwnedTrait<'a> {
// @has static_region/struct.Owned.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Owned<T> where <T as OwnedTrait<'static>>::Reader: Send"
+// "impl<T> Send for Owned<T>where <T as OwnedTrait<'static>>::Reader: Send"
pub struct Owned<T> where T: OwnedTrait<'static> {
marker: <T as OwnedTrait<'static>>::Reader,
}
diff --git a/src/test/rustdoc/table-in-docblock.rs b/src/test/rustdoc/table-in-docblock.rs
index 858b58919..194f49f16 100644
--- a/src/test/rustdoc/table-in-docblock.rs
+++ b/src/test/rustdoc/table-in-docblock.rs
@@ -2,7 +2,7 @@
// @has foo/struct.Foo.html
// @count - '//*[@class="docblock"]/div/table' 2
-// @!has - '//*[@class="docblock"]/table'
+// @!has - '//*[@class="docblock"]/table' ''
/// | hello | hello2 |
/// | ----- | ------ |
/// | data | data2 |
diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs
index c1df4613e..dbaf195e1 100644
--- a/src/test/rustdoc/toggle-item-contents.rs
+++ b/src/test/rustdoc/toggle-item-contents.rs
@@ -62,7 +62,7 @@ pub struct PrivStruct {
}
// @has 'toggle_item_contents/enum.Enum.html'
-// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]' ''
pub enum Enum {
A, B, C,
D {
@@ -72,7 +72,7 @@ pub enum Enum {
}
// @has 'toggle_item_contents/enum.EnumStructVariant.html'
-// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]' ''
pub enum EnumStructVariant {
A, B, C,
D {
diff --git a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs
index b5a97c610..fba594c38 100644
--- a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs
+++ b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs
@@ -59,7 +59,7 @@ pub struct MyStruct;
// We check that associated items with default values aren't generated in the implementors list.
impl MyTrait for (u8, u8) {
- // @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]'
+ // @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]' ''
type Assoc = bool;
fn trait_function(&self) {}
}
diff --git a/src/test/rustdoc/trait-impl.rs b/src/test/rustdoc/trait-impl.rs
index 4f7e2dfe3..195cdf009 100644
--- a/src/test/rustdoc/trait-impl.rs
+++ b/src/test/rustdoc/trait-impl.rs
@@ -21,26 +21,26 @@ pub trait Trait {
pub struct Struct;
impl Trait for Struct {
- // @has trait_impl/struct.Struct.html '//*[@id="method.a"]/../../div[@class="docblock"]/p' 'Some long docs'
- // @!has - '//*[@id="method.a"]/../../div[@class="docblock"]/p' 'link will be added'
- // @has - '//*[@id="method.a"]/../../div[@class="docblock"]/p/a' 'Read more'
- // @has - '//*[@id="method.a"]/../../div[@class="docblock"]/p/a/@href' 'trait.Trait.html#tymethod.a'
+ // @has trait_impl/struct.Struct.html '//*[@id="method.a"]/../../div[@class="docblock"]' 'Some long docs'
+ // @!has - '//*[@id="method.a"]/../../div[@class="docblock"]' 'link will be added'
+ // @has - '//*[@id="method.a"]/../../div[@class="docblock"]/a' 'Read more'
+ // @has - '//*[@id="method.a"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.a'
fn a() {}
- // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/p' 'These docs contain'
- // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/p/a' 'reference link'
- // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/p/a/@href' 'https://example.com'
- // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/p/a' 'Read more'
- // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/p/a/@href' 'trait.Trait.html#tymethod.b'
+ // @has - '//*[@id="method.b"]/../../div[@class="docblock"]' 'These docs contain'
+ // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'reference link'
+ // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'https://example.com'
+ // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'Read more'
+ // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.b'
fn b() {}
- // @!has - '//*[@id="method.c"]/../../div[@class="docblock"]/p' 'code block'
+ // @!has - '//*[@id="method.c"]/../../div[@class="docblock"]' 'code block'
// @has - '//*[@id="method.c"]/../../div[@class="docblock"]/a' 'Read more'
// @has - '//*[@id="method.c"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.c'
fn c() {}
- // @has - '//*[@id="method.d"]/../../div[@class="docblock"]/p' 'Escaped formatting a*b*c* works'
- // @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/p/em'
+ // @has - '//*[@id="method.d"]/../../div[@class="docblock"]' 'Escaped formatting a*b*c* works'
+ // @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/em' ''
fn d() {}
// @has - '//*[@id="impl-Trait-for-Struct"]/h3//a/@href' 'trait.Trait.html'
diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs
index 31426131b..66bb40932 100644
--- a/src/test/rustdoc/tuple-struct-fields-doc.rs
+++ b/src/test/rustdoc/tuple-struct-fields-doc.rs
@@ -5,7 +5,7 @@
// @has - '//h3[@class="sidebar-title"]/a[@href="#fields"]' 'Tuple Fields'
// @has - '//*[@id="structfield.0"]' '0: u32'
// @has - '//*[@id="main-content"]/div[@class="docblock"]' 'hello'
-// @!has - '//*[@id="structfield.1"]'
+// @!has - '//*[@id="structfield.1"]' ''
// @has - '//*[@id="structfield.2"]' '2: char'
// @has - '//*[@id="structfield.3"]' '3: i8'
// @has - '//*[@id="main-content"]/div[@class="docblock"]' 'not hello'
diff --git a/src/test/rustdoc/type-layout-flag-required.rs b/src/test/rustdoc/type-layout-flag-required.rs
index a01fbd229..6bb5e10f8 100644
--- a/src/test/rustdoc/type-layout-flag-required.rs
+++ b/src/test/rustdoc/type-layout-flag-required.rs
@@ -1,4 +1,4 @@
// Tests that `--show-type-layout` is required in order to show layout info.
-// @!has type_layout_flag_required/struct.Foo.html 'Size: '
+// @!hasraw type_layout_flag_required/struct.Foo.html 'Size: '
pub struct Foo(usize);
diff --git a/src/test/rustdoc/type-layout.rs b/src/test/rustdoc/type-layout.rs
index e5c6e9dc3..5e0a0411a 100644
--- a/src/test/rustdoc/type-layout.rs
+++ b/src/test/rustdoc/type-layout.rs
@@ -1,84 +1,84 @@
// compile-flags: --show-type-layout -Z unstable-options
-// @has type_layout/struct.Foo.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.Foo.html 'Size: '
+// @hasraw - ' bytes'
// @has - '//*[@id="layout"]/a[@href="#layout"]' ''
pub struct Foo {
pub a: usize,
b: Vec<String>,
}
-// @has type_layout/enum.Bar.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/enum.Bar.html 'Size: '
+// @hasraw - ' bytes'
pub enum Bar<'a> {
A(String),
B(&'a str, (std::collections::HashMap<String, usize>, Foo)),
}
-// @has type_layout/union.Baz.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/union.Baz.html 'Size: '
+// @hasraw - ' bytes'
pub union Baz {
a: &'static str,
b: usize,
c: &'static [u8],
}
-// @has type_layout/struct.X.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.X.html 'Size: '
+// @hasraw - ' bytes'
pub struct X(usize);
-// @has type_layout/struct.Y.html 'Size: '
-// @has - '1 byte'
-// @!has - ' bytes'
+// @hasraw type_layout/struct.Y.html 'Size: '
+// @hasraw - '1 byte'
+// @!hasraw - ' bytes'
pub struct Y(u8);
-// @has type_layout/struct.Z.html 'Size: '
-// @has - '0 bytes'
+// @hasraw type_layout/struct.Z.html 'Size: '
+// @hasraw - '0 bytes'
pub struct Z;
// We can't compute layout for generic types.
-// @has type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
-// @!has - 'Size: '
+// @hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
+// @!hasraw - 'Size: '
pub struct Generic<T>(T);
// We *can*, however, compute layout for types that are only generic over lifetimes,
// because lifetimes are a type-system construct.
-// @has type_layout/struct.GenericLifetimes.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.GenericLifetimes.html 'Size: '
+// @hasraw - ' bytes'
pub struct GenericLifetimes<'a>(&'a str);
-// @has type_layout/struct.Unsized.html 'Size: '
-// @has - '(unsized)'
+// @hasraw type_layout/struct.Unsized.html 'Size: '
+// @hasraw - '(unsized)'
pub struct Unsized([u8]);
-// @has type_layout/type.TypeAlias.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/type.TypeAlias.html 'Size: '
+// @hasraw - ' bytes'
pub type TypeAlias = X;
-// @has type_layout/type.GenericTypeAlias.html 'Size: '
-// @has - '8 bytes'
+// @hasraw type_layout/type.GenericTypeAlias.html 'Size: '
+// @hasraw - '8 bytes'
pub type GenericTypeAlias = (Generic<(u32, ())>, Generic<u32>);
// Regression test for the rustdoc equivalent of #85103.
-// @has type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
+// @hasraw type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
pub type Edges<'a, E> = std::borrow::Cow<'a, [E]>;
-// @!has type_layout/trait.MyTrait.html 'Size: '
+// @!hasraw type_layout/trait.MyTrait.html 'Size: '
pub trait MyTrait {}
-// @has type_layout/enum.Variants.html 'Size: '
-// @has - '2 bytes'
-// @has - '<code>A</code>: 0 bytes'
-// @has - '<code>B</code>: 1 byte'
+// @hasraw type_layout/enum.Variants.html 'Size: '
+// @hasraw - '2 bytes'
+// @hasraw - '<code>A</code>: 0 bytes'
+// @hasraw - '<code>B</code>: 1 byte'
pub enum Variants {
A,
B(u8),
}
-// @has type_layout/enum.WithNiche.html 'Size: '
+// @hasraw type_layout/enum.WithNiche.html 'Size: '
// @has - //p '4 bytes'
-// @has - '<code>None</code>: 0 bytes'
-// @has - '<code>Some</code>: 4 bytes'
+// @hasraw - '<code>None</code>: 0 bytes'
+// @hasraw - '<code>Some</code>: 4 bytes'
pub enum WithNiche {
None,
Some(std::num::NonZeroU32),
diff --git a/src/test/rustdoc/typedef.rs b/src/test/rustdoc/typedef.rs
index 4ecd62cde..b68ec4557 100644
--- a/src/test/rustdoc/typedef.rs
+++ b/src/test/rustdoc/typedef.rs
@@ -11,7 +11,7 @@ impl MyStruct {
// @has typedef/type.MyAlias.html
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' 'impl MyAlias'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' 'impl MyTrait for MyAlias'
-// @has - 'Alias docstring'
+// @hasraw - 'Alias docstring'
// @has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias'
// @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods'
// @has - '//*[@class="sidebar"]//a[@href="#trait-implementations"]' 'Trait Implementations'
diff --git a/src/test/rustdoc/universal-impl-trait.rs b/src/test/rustdoc/universal-impl-trait.rs
index b10b1b865..f5eabda59 100644
--- a/src/test/rustdoc/universal-impl-trait.rs
+++ b/src/test/rustdoc/universal-impl-trait.rs
@@ -5,15 +5,15 @@ use std::borrow::Borrow;
// @has foo/fn.foo.html
// @has - //pre 'foo('
-// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
-// @matches - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
+// @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
+// @matchesraw - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
pub fn foo(_x: impl Clone, _y: i32, _z: (impl Copy, impl Clone)) {
}
pub trait Trait {
// @has foo/trait.Trait.html
- // @has - 'method</a>('
- // @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+ // @hasraw - 'method</a>('
+ // @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
fn method(&self, _x: impl std::fmt::Debug) {
}
}
@@ -22,30 +22,30 @@ pub struct S<T>(T);
impl<T> S<T> {
// @has foo/struct.S.html
- // @has - 'bar</a>('
- // @matches - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
+ // @hasraw - 'bar</a>('
+ // @matchesraw - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
pub fn bar(_bar: impl Copy) {
}
- // @has - 'baz</a>('
- // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
+ // @hasraw - 'baz</a>('
+ // @matchesraw - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
pub fn baz(_baz: S<impl Clone>) {
}
- // @has - 'qux</a>('
- // @matches - 'trait\.Read\.html'
+ // @hasraw - 'qux</a>('
+ // @matchesraw - 'trait\.Read\.html'
pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) {
}
}
-// @has - 'method</a>('
-// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+// @hasraw - 'method</a>('
+// @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
impl<T> Trait for S<T> {}
// @has foo/fn.much_universe.html
-// @matches - 'T:.+Borrow.+impl .+trait\.Trait\.html'
-// @matches - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
-// @matches - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
+// @matchesraw - 'T:.+Borrow.+impl .+trait\.Trait\.html'
+// @matchesraw - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
+// @matchesraw - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
pub fn much_universe<
T: Borrow<impl Trait>,
U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
diff --git a/src/test/rustdoc/version-separator-without-source.rs b/src/test/rustdoc/version-separator-without-source.rs
index ae866deba..04ea46a7f 100644
--- a/src/test/rustdoc/version-separator-without-source.rs
+++ b/src/test/rustdoc/version-separator-without-source.rs
@@ -16,7 +16,7 @@ pub fn foo() {}
pub struct Bar;
impl Bar {
- // @has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0'
+ // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0'
// @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0 ·'
#[stable(feature = "foobar", since = "2.0")]
pub fn bar() {}
diff --git a/src/test/rustdoc/where-clause-order.rs b/src/test/rustdoc/where-clause-order.rs
index 3150a8ea0..b8502e10a 100644
--- a/src/test/rustdoc/where-clause-order.rs
+++ b/src/test/rustdoc/where-clause-order.rs
@@ -7,7 +7,7 @@ where
}
// @has 'foo/trait.SomeTrait.html'
-// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
+// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)
where
A: PartialOrd<A> + PartialEq<A>,
diff --git a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
index 54026ff03..542a3337b 100644
--- a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
+++ b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
@@ -1,3 +1,8 @@
<div class="docblock item-decl"><pre class="rust trait"><code>pub trait TraitWhere {
- type <a href="#associatedtype.Item" class="associatedtype">Item</a>&lt;'a&gt;<br />&#160;&#160;&#160; <span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: 'a</span>;
+ type <a href="#associatedtype.Item" class="associatedtype">Item</a>&lt;'a&gt;<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: 'a</span>;
+
+ fn <a href="#method.func" class="fnname">func</a>(self)<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
+ { ... }
+<span class="item-spacer" /> fn <a href="#method.lines" class="fnname">lines</a>(self) -&gt; <a class="struct" href="{{channel}}/std/io/struct.Lines.html" title="struct std::io::Lines">Lines</a>&lt;Self&gt;<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
+ { ... }
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/rustdoc/where.rs b/src/test/rustdoc/where.rs
index 50a5722fb..7a6c0db23 100644
--- a/src/test/rustdoc/where.rs
+++ b/src/test/rustdoc/where.rs
@@ -1,19 +1,20 @@
-#![feature(generic_associated_types)]
#![crate_name = "foo"]
+use std::io::Lines;
+
pub trait MyTrait { fn dummy(&self) { } }
-// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_) where A: MyTrait"
+// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_)where A: MyTrait"
pub struct Alpha<A>(A) where A: MyTrait;
-// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B> where B: MyTrait"
+// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B>where B: MyTrait"
pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
-// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>() where C: MyTrait"
+// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>()where C: MyTrait"
pub fn charlie<C>() where C: MyTrait {}
pub struct Delta<D>(D);
// @has foo/struct.Delta.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<D> Delta<D> where D: MyTrait"
+// "impl<D> Delta<D>where D: MyTrait"
impl<D> Delta<D> where D: MyTrait {
pub fn delta() {}
}
@@ -30,22 +31,32 @@ where
// @snapshot SWhere_TraitWhere_item-decl - '//div[@class="docblock item-decl"]'
pub trait TraitWhere {
type Item<'a> where Self: 'a;
+
+ fn func(self)
+ where
+ Self: Sized
+ {}
+
+ fn lines(self) -> Lines<Self>
+ where
+ Self: Sized,
+ { todo!() }
}
// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<E> MyTrait for Echo<E> where E: MyTrait"
+// "impl<E> MyTrait for Echo<E>where E: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
-// "impl<E> MyTrait for Echo<E> where E: MyTrait"
-impl<E> MyTrait for Echo<E> where E: MyTrait {}
+// "impl<E> MyTrait for Echo<E>where E: MyTrait"
+impl<E> MyTrait for Echo<E>where E: MyTrait {}
pub enum Foxtrot<F> { Foxtrot1(F) }
// @has foo/enum.Foxtrot.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
+// "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
-// "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
-impl<F> MyTrait for Foxtrot<F> where F: MyTrait {}
+// "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
+impl<F> MyTrait for Foxtrot<F>where F: MyTrait {}
// @has foo/type.Golf.html '//pre[@class="rust typedef"]' \
-// "type Golf<T> where T: Clone, = (T, T)"
+// "type Golf<T>where T: Clone, = (T, T)"
pub type Golf<T> where T: Clone = (T, T);
diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
index 802b867a3..03ad3ca82 100644
--- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
+++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
@@ -21,7 +21,7 @@ use rustc_span::source_map;
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
- reg.lint_store.register_late_pass(|| Box::new(MissingAllowedAttrPass));
+ reg.lint_store.register_late_pass(|_| Box::new(MissingAllowedAttrPass));
}
declare_lint! {
diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
index bc153faa8..a3b570ad8 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
@@ -74,7 +74,7 @@ fn __rustc_plugin_registrar(reg: &mut Registry) {
&CRATE_NOT_GREY,
&CRATE_NOT_GREEN,
]);
- reg.lint_store.register_late_pass(|| Box::new(PassOkay));
- reg.lint_store.register_late_pass(|| Box::new(PassRedBlue));
- reg.lint_store.register_late_pass(|| Box::new(PassGreyGreen));
+ reg.lint_store.register_late_pass(|_| Box::new(PassOkay));
+ reg.lint_store.register_late_pass(|_| Box::new(PassRedBlue));
+ reg.lint_store.register_late_pass(|_| Box::new(PassGreyGreen));
}
diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
index 29d0abfbe..0b1534939 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
@@ -39,5 +39,5 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
- reg.lint_store.register_late_pass(|| Box::new(Pass));
+ reg.lint_store.register_late_pass(|_| Box::new(Pass));
}
diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
index 691cfb97d..2d41b5f30 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
@@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]);
- reg.lint_store.register_late_pass(|| Box::new(Pass));
+ reg.lint_store.register_late_pass(|_| Box::new(Pass));
reg.lint_store.register_group(
true,
"lint_me",
diff --git a/src/test/ui-fulldeps/fluent-messages/duplicate-a-b.ftl b/src/test/ui-fulldeps/fluent-messages/duplicate-a-b.ftl
new file mode 100644
index 000000000..9407c5170
--- /dev/null
+++ b/src/test/ui-fulldeps/fluent-messages/duplicate-a-b.ftl
@@ -0,0 +1 @@
+a_b_key = Value
diff --git a/src/test/ui-fulldeps/fluent-messages/duplicate-a.ftl b/src/test/ui-fulldeps/fluent-messages/duplicate-a.ftl
index fd9976b5a..9407c5170 100644
--- a/src/test/ui-fulldeps/fluent-messages/duplicate-a.ftl
+++ b/src/test/ui-fulldeps/fluent-messages/duplicate-a.ftl
@@ -1 +1 @@
-key = Value
+a_b_key = Value
diff --git a/src/test/ui-fulldeps/fluent-messages/duplicate-b.ftl b/src/test/ui-fulldeps/fluent-messages/duplicate-b.ftl
deleted file mode 100644
index fd9976b5a..000000000
--- a/src/test/ui-fulldeps/fluent-messages/duplicate-b.ftl
+++ /dev/null
@@ -1 +0,0 @@
-key = Value
diff --git a/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
new file mode 100644
index 000000000..016cbeef6
--- /dev/null
+++ b/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
@@ -0,0 +1,2 @@
+label_with_hyphens_some_slug = hi
+ .label-has-hyphens = test
diff --git a/src/test/ui-fulldeps/fluent-messages/missing-crate-name.ftl b/src/test/ui-fulldeps/fluent-messages/missing-crate-name.ftl
new file mode 100644
index 000000000..9bd035c1b
--- /dev/null
+++ b/src/test/ui-fulldeps/fluent-messages/missing-crate-name.ftl
@@ -0,0 +1,2 @@
+with-hyphens = 1234
+test-crate_foo = abcd
diff --git a/src/test/ui-fulldeps/fluent-messages/missing-message.ftl b/src/test/ui-fulldeps/fluent-messages/missing-message.ftl
index 372b1a2e4..74b2aa1d4 100644
--- a/src/test/ui-fulldeps/fluent-messages/missing-message.ftl
+++ b/src/test/ui-fulldeps/fluent-messages/missing-message.ftl
@@ -1 +1 @@
-missing-message =
+missing_message =
diff --git a/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
new file mode 100644
index 000000000..86ba9a268
--- /dev/null
+++ b/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
@@ -0,0 +1 @@
+slug_with_hyphens_this-slug-has-hyphens = hi
diff --git a/src/test/ui-fulldeps/fluent-messages/test.rs b/src/test/ui-fulldeps/fluent-messages/test.rs
index 0390a0785..256857e52 100644
--- a/src/test/ui-fulldeps/fluent-messages/test.rs
+++ b/src/test/ui-fulldeps/fluent-messages/test.rs
@@ -50,8 +50,26 @@ mod duplicate {
fluent_messages! {
a => "./duplicate-a.ftl",
- b => "./duplicate-b.ftl",
-//~^ ERROR overrides existing message: `key`
+ a_b => "./duplicate-a-b.ftl",
+//~^ ERROR overrides existing message: `a_b_key`
+ }
+}
+
+mod slug_with_hyphens {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ slug_with_hyphens => "./slug-with-hyphens.ftl",
+//~^ ERROR name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character
+ }
+}
+
+mod label_with_hyphens {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ label_with_hyphens => "./label-with-hyphens.ftl",
+//~^ ERROR attribute `label-has-hyphens` contains a '-' character
}
}
@@ -62,5 +80,18 @@ mod valid {
valid => "./valid.ftl",
}
- use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, valid::valid};
+ use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, valid::key};
+}
+
+mod missing_crate_name {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ test_crate => "./missing-crate-name.ftl",
+//~^ ERROR name `test-crate_foo` contains a '-' character
+//~| ERROR name `with-hyphens` contains a '-' character
+//~| ERROR name `with-hyphens` does not start with the crate name
+ }
+
+ use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate::{foo, with_hyphens}};
}
diff --git a/src/test/ui-fulldeps/fluent-messages/test.stderr b/src/test/ui-fulldeps/fluent-messages/test.stderr
index 526bca43f..26d87430a 100644
--- a/src/test/ui-fulldeps/fluent-messages/test.stderr
+++ b/src/test/ui-fulldeps/fluent-messages/test.stderr
@@ -22,24 +22,64 @@ LL | missing_message => "./missing-message.ftl",
|
= help: see additional errors emitted
-error: expected a message field for "missing-message"
+error: expected a message field for "missing_message"
--> ./missing-message.ftl:1:1
|
-1 | missing-message =
- | ^^^^^^^^^^^^^^^^^^
+1 | missing_message =
+ | ^^^^^^^^^^^^^^^^^
|
-error: overrides existing message: `key`
- --> $DIR/test.rs:53:9
+error: overrides existing message: `a_b_key`
+ --> $DIR/test.rs:53:16
|
-LL | b => "./duplicate-b.ftl",
- | ^
+LL | a_b => "./duplicate-a-b.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^
|
help: previously defined in this resource
- --> $DIR/test.rs:52:9
+ --> $DIR/test.rs:52:14
|
LL | a => "./duplicate-a.ftl",
- | ^
+ | ^^^^^^^^^^^^^^^^^^^
-error: aborting due to 4 previous errors
+error: name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character
+ --> $DIR/test.rs:62:30
+ |
+LL | slug_with_hyphens => "./slug-with-hyphens.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: attribute `label-has-hyphens` contains a '-' character
+ --> $DIR/test.rs:71:31
+ |
+LL | label_with_hyphens => "./label-with-hyphens.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: name `with-hyphens` contains a '-' character
+ --> $DIR/test.rs:90:23
+ |
+LL | test_crate => "./missing-crate-name.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: name `with-hyphens` does not start with the crate name
+ --> $DIR/test.rs:90:23
+ |
+LL | test_crate => "./missing-crate-name.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: prepend `test_crate_` to the slug name: `test_crate_with_hyphens`
+
+error: name `test-crate_foo` contains a '-' character
+ --> $DIR/test.rs:90:23
+ |
+LL | test_crate => "./missing-crate-name.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: aborting due to 9 previous errors
diff --git a/src/test/ui-fulldeps/fluent-messages/valid.ftl b/src/test/ui-fulldeps/fluent-messages/valid.ftl
index 0eee4a02b..549274306 100644
--- a/src/test/ui-fulldeps/fluent-messages/valid.ftl
+++ b/src/test/ui-fulldeps/fluent-messages/valid.ftl
@@ -1 +1 @@
-valid = Valid!
+valid_key = Valid!
diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
index d6f63d44b..e9e809fa4 100644
--- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
@@ -1,6 +1,7 @@
// compile-flags: -Z unstable-options
#![crate_type = "lib"]
+#![feature(rustc_attrs)]
#![feature(rustc_private)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
@@ -10,13 +11,15 @@ extern crate rustc_macros;
extern crate rustc_session;
extern crate rustc_span;
-use rustc_errors::{AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, fluent};
+use rustc_errors::{
+ AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, fluent
+};
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
-use rustc_session::{parse::ParseSess, SessionDiagnostic};
+use rustc_session::SessionDiagnostic;
use rustc_span::Span;
#[derive(SessionDiagnostic)]
-#[error(parser::expect_path)]
+#[diag(parser::expect_path)]
struct DeriveSessionDiagnostic {
#[primary_span]
span: Span,
@@ -32,8 +35,8 @@ struct Note {
pub struct UntranslatableInSessionDiagnostic;
impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for UntranslatableInSessionDiagnostic {
- fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- sess.struct_err("untranslatable diagnostic")
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ handler.struct_err("untranslatable diagnostic")
//~^ ERROR diagnostics should be created using translatable messages
}
}
@@ -41,8 +44,8 @@ impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for UntranslatableInSessionDiagn
pub struct TranslatableInSessionDiagnostic;
impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for TranslatableInSessionDiagnostic {
- fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- sess.struct_err(fluent::parser::expect_path)
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ handler.struct_err(fluent::parser::expect_path)
}
}
@@ -63,11 +66,18 @@ impl AddSubdiagnostic for TranslatableInAddSubdiagnostic {
}
}
-pub fn make_diagnostics<'a>(sess: &'a ParseSess) {
- let _diag = sess.struct_err(fluent::parser::expect_path);
+pub fn make_diagnostics<'a>(handler: &'a Handler) {
+ let _diag = handler.struct_err(fluent::parser::expect_path);
//~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
- let _diag = sess.struct_err("untranslatable diagnostic");
+ let _diag = handler.struct_err("untranslatable diagnostic");
//~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
//~^^ ERROR diagnostics should be created using translatable messages
}
+
+// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted.
+
+#[rustc_lint_diagnostics]
+pub fn skipped_because_of_annotation<'a>(handler: &'a Handler) {
+ let _diag = handler.struct_err("untranslatable diagnostic"); // okay!
+}
diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr
index bae78ffdc..e5c5bc2e9 100644
--- a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr
+++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr
@@ -1,44 +1,44 @@
error: diagnostics should be created using translatable messages
- --> $DIR/diagnostics.rs:36:14
+ --> $DIR/diagnostics.rs:39:17
|
-LL | sess.struct_err("untranslatable diagnostic")
- | ^^^^^^^^^^
+LL | handler.struct_err("untranslatable diagnostic")
+ | ^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/diagnostics.rs:5:9
+ --> $DIR/diagnostics.rs:6:9
|
LL | #![deny(rustc::untranslatable_diagnostic)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: diagnostics should be created using translatable messages
- --> $DIR/diagnostics.rs:53:14
+ --> $DIR/diagnostics.rs:56:14
|
LL | diag.note("untranslatable diagnostic");
| ^^^^
error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
- --> $DIR/diagnostics.rs:67:22
+ --> $DIR/diagnostics.rs:70:25
|
-LL | let _diag = sess.struct_err(fluent::parser::expect_path);
- | ^^^^^^^^^^
+LL | let _diag = handler.struct_err(fluent::parser::expect_path);
+ | ^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/diagnostics.rs:6:9
+ --> $DIR/diagnostics.rs:7:9
|
LL | #![deny(rustc::diagnostic_outside_of_impl)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
- --> $DIR/diagnostics.rs:70:22
+ --> $DIR/diagnostics.rs:73:25
|
-LL | let _diag = sess.struct_err("untranslatable diagnostic");
- | ^^^^^^^^^^
+LL | let _diag = handler.struct_err("untranslatable diagnostic");
+ | ^^^^^^^^^^
error: diagnostics should be created using translatable messages
- --> $DIR/diagnostics.rs:70:22
+ --> $DIR/diagnostics.rs:73:25
|
-LL | let _diag = sess.struct_err("untranslatable diagnostic");
- | ^^^^^^^^^^
+LL | let _diag = handler.struct_err("untranslatable diagnostic");
+ | ^^^^^^^^^^
error: aborting due to 5 previous errors
diff --git a/src/test/ui-fulldeps/issue-15778-pass.rs b/src/test/ui-fulldeps/issue-15778-pass.rs
deleted file mode 100644
index c031dbc71..000000000
--- a/src/test/ui-fulldeps/issue-15778-pass.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// check-pass
-// aux-build:lint-for-crate-rpass.rs
-// ignore-stage1
-// compile-flags: -D crate-not-okay
-
-#![feature(plugin, register_attr, custom_inner_attributes)]
-
-#![register_attr(
- crate_okay,
- crate_blue,
- crate_red,
- crate_grey,
- crate_green,
-)]
-
-#![plugin(lint_for_crate_rpass)] //~ WARNING compiler plugins are deprecated
-#![crate_okay]
-#![crate_blue]
-#![crate_red]
-#![crate_grey]
-#![crate_green]
-
-fn main() {}
diff --git a/src/test/ui-fulldeps/issue-15778-pass.stderr b/src/test/ui-fulldeps/issue-15778-pass.stderr
deleted file mode 100644
index a9d9721ac..000000000
--- a/src/test/ui-fulldeps/issue-15778-pass.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/issue-15778-pass.rs:16:1
- |
-LL | #![plugin(lint_for_crate_rpass)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index a679b7b4e..da6a84bf3 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -30,7 +30,6 @@ use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
use rustc_ast::ptr::P;
use rustc_ast::*;
use rustc_ast_pretty::pprust;
-use rustc_data_structures::thin_vec::ThinVec;
use rustc_parse::new_parser_from_source_str;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;
@@ -47,7 +46,7 @@ fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
// Helper functions for building exprs
fn expr(kind: ExprKind) -> P<Expr> {
- P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: ThinVec::new(), tokens: None })
+ P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None })
}
fn make_x() -> P<Expr> {
@@ -196,7 +195,7 @@ impl MutVisitor for AddParens {
id: DUMMY_NODE_ID,
kind: ExprKind::Paren(e),
span: DUMMY_SP,
- attrs: ThinVec::new(),
+ attrs: AttrVec::new(),
tokens: None,
})
});
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index 0a210cbdc..c1c109ac1 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -2,7 +2,7 @@
// Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
// normalize-stderr-test "the following other types implement trait `IntoDiagnosticArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr"
-
+// normalize-stderr-test "diagnostic_builder\.rs:[0-9]+:[0-9]+" -> "diagnostic_builder.rs:LL:CC"
// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
// changing the output of this test. Since SessionDiagnostic is strictly internal to the compiler
// the test is just ignored on stable and beta:
@@ -28,15 +28,15 @@ use rustc_errors::{Applicability, MultiSpan};
extern crate rustc_session;
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct Hello {}
#[derive(SessionDiagnostic)]
-#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct HelloWarn {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
//~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
enum SessionDiagnosticOnEnum {
Foo,
@@ -44,54 +44,54 @@ enum SessionDiagnosticOnEnum {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[error = "E0123"]
-//~^ ERROR `#[error = ...]` is not a valid attribute
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag = "E0123"]
+//~^ ERROR `#[diag = ...]` is not a valid attribute
struct WrongStructAttrStyle {}
#[derive(SessionDiagnostic)]
#[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
//~^ ERROR `#[nonsense(...)]` is not a valid attribute
-//~^^ ERROR diagnostic kind not specified
+//~^^ ERROR diagnostic slug not specified
//~^^^ ERROR cannot find attribute `nonsense` in this scope
struct InvalidStructAttr {}
#[derive(SessionDiagnostic)]
-#[error("E0123")]
-//~^ ERROR `#[error("...")]` is not a valid attribute
+#[diag("E0123")]
+//~^ ERROR `#[diag("...")]` is not a valid attribute
//~^^ ERROR diagnostic slug not specified
struct InvalidLitNestedAttr {}
#[derive(SessionDiagnostic)]
-#[error(nonsense, code = "E0123")]
+#[diag(nonsense, code = "E0123")]
//~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
struct InvalidNestedStructAttr {}
#[derive(SessionDiagnostic)]
-#[error(nonsense("foo"), code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense(...))]` is not a valid attribute
+#[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense(...))]` is not a valid attribute
//~^^ ERROR diagnostic slug not specified
struct InvalidNestedStructAttr1 {}
#[derive(SessionDiagnostic)]
-#[error(nonsense = "...", code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute
+#[diag(nonsense = "...", code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
//~^^ ERROR diagnostic slug not specified
struct InvalidNestedStructAttr2 {}
#[derive(SessionDiagnostic)]
-#[error(nonsense = 4, code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute
+#[diag(nonsense = 4, code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
//~^^ ERROR diagnostic slug not specified
struct InvalidNestedStructAttr3 {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(slug = ...)]` is not a valid attribute
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(slug = ...)]` is not a valid attribute
struct InvalidNestedStructAttr4 {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct WrongPlaceField {
#[suggestion = "bar"]
//~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -99,45 +99,36 @@ struct WrongPlaceField {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
//~^ ERROR specified multiple times
//~^^ ERROR specified multiple times
-//~^^^ ERROR specified multiple times
-struct ErrorSpecifiedTwice {}
+struct DiagSpecifiedTwice {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
-//~^ ERROR specified multiple times
-//~^^ ERROR specified multiple times
-//~^^^ ERROR specified multiple times
-struct WarnSpecifiedAfterError {}
-
-#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
//~^ ERROR specified multiple times
struct CodeSpecifiedTwice {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
-//~^ ERROR `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
+#[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
+//~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
struct SlugSpecifiedTwice {}
#[derive(SessionDiagnostic)]
-struct KindNotProvided {} //~ ERROR diagnostic kind not specified
+struct KindNotProvided {} //~ ERROR diagnostic slug not specified
#[derive(SessionDiagnostic)]
-#[error(code = "E0456")]
+#[diag(code = "E0456")]
//~^ ERROR diagnostic slug not specified
struct SlugNotProvided {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound)]
+#[diag(typeck::ambiguous_lifetime_bound)]
struct CodeNotProvided {}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct MessageWrongType {
#[primary_span]
//~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -145,7 +136,7 @@ struct MessageWrongType {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct InvalidPathFieldAttr {
#[nonsense]
//~^ ERROR `#[nonsense]` is not a valid attribute
@@ -154,7 +145,7 @@ struct InvalidPathFieldAttr {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithField {
name: String,
#[label(typeck::label)]
@@ -162,7 +153,7 @@ struct ErrorWithField {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithMessageAppliedToField {
#[label(typeck::label)]
//~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -170,7 +161,7 @@ struct ErrorWithMessageAppliedToField {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithNonexistentField {
#[suggestion(typeck::suggestion, code = "{name}")]
//~^ ERROR `name` doesn't refer to a field on this type
@@ -179,7 +170,7 @@ struct ErrorWithNonexistentField {
#[derive(SessionDiagnostic)]
//~^ ERROR invalid format string: expected `'}'`
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorMissingClosingBrace {
#[suggestion(typeck::suggestion, code = "{name")]
suggestion: (Span, Applicability),
@@ -189,7 +180,7 @@ struct ErrorMissingClosingBrace {
#[derive(SessionDiagnostic)]
//~^ ERROR invalid format string: unmatched `}`
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorMissingOpeningBrace {
#[suggestion(typeck::suggestion, code = "name}")]
suggestion: (Span, Applicability),
@@ -198,14 +189,14 @@ struct ErrorMissingOpeningBrace {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelOnSpan {
#[label(typeck::label)]
sp: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelOnNonSpan {
#[label(typeck::label)]
//~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -213,7 +204,7 @@ struct LabelOnNonSpan {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct Suggest {
#[suggestion(typeck::suggestion, code = "This is the suggested code")]
#[suggestion_short(typeck::suggestion, code = "This is the suggested code")]
@@ -223,14 +214,14 @@ struct Suggest {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithoutCode {
#[suggestion(typeck::suggestion)]
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithBadKey {
#[suggestion(nonsense = "bar")]
//~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
@@ -238,7 +229,7 @@ struct SuggestWithBadKey {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithShorthandMsg {
#[suggestion(msg = "bar")]
//~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
@@ -246,21 +237,21 @@ struct SuggestWithShorthandMsg {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithoutMsg {
#[suggestion(code = "bar")]
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithTypesSwapped {
#[suggestion(typeck::suggestion, code = "This is suggested code")]
suggestion: (Applicability, Span),
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithWrongTypeApplicabilityOnly {
#[suggestion(typeck::suggestion, code = "This is suggested code")]
//~^ ERROR wrong field type for suggestion
@@ -268,14 +259,14 @@ struct SuggestWithWrongTypeApplicabilityOnly {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithSpanOnly {
#[suggestion(typeck::suggestion, code = "This is suggested code")]
suggestion: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithDuplicateSpanAndApplicability {
#[suggestion(typeck::suggestion, code = "This is suggested code")]
//~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span`
@@ -283,7 +274,7 @@ struct SuggestWithDuplicateSpanAndApplicability {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithDuplicateApplicabilityAndSpan {
#[suggestion(typeck::suggestion, code = "This is suggested code")]
//~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
@@ -291,7 +282,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct WrongKindOfAnnotation {
#[label = "bar"]
//~^ ERROR `#[label = ...]` is not a valid attribute
@@ -299,7 +290,7 @@ struct WrongKindOfAnnotation {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct OptionsInErrors {
#[label(typeck::label)]
label: Option<Span>,
@@ -308,7 +299,7 @@ struct OptionsInErrors {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
struct MoveOutOfBorrowError<'tcx> {
name: Ident,
ty: Ty<'tcx>,
@@ -322,7 +313,7 @@ struct MoveOutOfBorrowError<'tcx> {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithLifetime<'a> {
#[label(typeck::label)]
span: Span,
@@ -330,7 +321,7 @@ struct ErrorWithLifetime<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithDefaultLabelAttr<'a> {
#[label]
span: Span,
@@ -339,7 +330,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
#[derive(SessionDiagnostic)]
//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ArgFieldWithoutSkip {
#[primary_span]
span: Span,
@@ -347,7 +338,7 @@ struct ArgFieldWithoutSkip {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ArgFieldWithSkip {
#[primary_span]
span: Span,
@@ -358,56 +349,56 @@ struct ArgFieldWithSkip {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedNote {
#[note]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedNoteCustom {
#[note(typeck::note)]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[note]
struct ErrorWithNote {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[note(typeck::note)]
struct ErrorWithNoteCustom {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedHelp {
#[help]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedHelpCustom {
#[help(typeck::help)]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[help]
struct ErrorWithHelp {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[help(typeck::help)]
struct ErrorWithHelpCustom {
val: String,
@@ -415,34 +406,34 @@ struct ErrorWithHelpCustom {
#[derive(SessionDiagnostic)]
#[help]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithHelpWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
#[help(typeck::help)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithHelpCustomWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
#[note]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithNoteWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
#[note(typeck::note)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithNoteCustomWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ApplicabilityInBoth {
#[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
//~^ ERROR applicability cannot be set in both the field and attribute
@@ -450,7 +441,7 @@ struct ApplicabilityInBoth {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct InvalidApplicability {
#[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
//~^ ERROR invalid applicability
@@ -458,14 +449,14 @@ struct InvalidApplicability {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ValidApplicability {
#[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
suggestion: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct NoApplicability {
#[suggestion(typeck::suggestion, code = "...")]
suggestion: Span,
@@ -476,14 +467,14 @@ struct NoApplicability {
struct Note;
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound)]
+#[diag(typeck::ambiguous_lifetime_bound)]
struct Subdiagnostic {
#[subdiagnostic]
note: Note,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct VecField {
#[primary_span]
#[label]
@@ -491,7 +482,7 @@ struct VecField {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct UnitField {
#[primary_span]
spans: Span,
@@ -502,7 +493,7 @@ struct UnitField {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct OptUnitField {
#[primary_span]
spans: Span,
@@ -513,7 +504,7 @@ struct OptUnitField {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelWithTrailingPath {
#[label(typeck::label, foo)]
//~^ ERROR `#[label(...)]` is not a valid attribute
@@ -521,7 +512,7 @@ struct LabelWithTrailingPath {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelWithTrailingNameValue {
#[label(typeck::label, foo = "...")]
//~^ ERROR `#[label(...)]` is not a valid attribute
@@ -529,40 +520,64 @@ struct LabelWithTrailingNameValue {
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelWithTrailingList {
#[label(typeck::label, foo("..."))]
//~^ ERROR `#[label(...)]` is not a valid attribute
span: Span,
}
-#[derive(SessionDiagnostic)]
-#[lint(typeck::ambiguous_lifetime_bound)]
-//~^ ERROR only `#[error(..)]` and `#[warning(..)]` are supported
-struct LintsBad {
-}
-
#[derive(LintDiagnostic)]
-#[lint(typeck::ambiguous_lifetime_bound)]
+#[diag(typeck::ambiguous_lifetime_bound)]
struct LintsGood {
}
#[derive(LintDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound)]
-//~^ ERROR only `#[lint(..)]` is supported
-struct ErrorsBad {
+#[diag(typeck::ambiguous_lifetime_bound)]
+struct PrimarySpanOnLint {
+ #[primary_span]
+ //~^ ERROR `#[primary_span]` is not a valid attribute
+ span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithMultiSpan {
#[primary_span]
span: MultiSpan,
}
#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[warn_]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[warning]
struct ErrorWithWarn {
val: String,
}
+
+#[derive(SessionDiagnostic)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[error(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `error` in this scope
+struct ErrorAttribute {}
+
+#[derive(SessionDiagnostic)]
+#[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[warn_(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `warn_` in this scope
+struct WarnAttribute {}
+
+#[derive(SessionDiagnostic)]
+#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `lint` in this scope
+struct LintAttributeOnSessionDiag {}
+
+#[derive(LintDiagnostic)]
+#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `lint` in this scope
+struct LintAttributeOnLintDiag {}
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index c1080aa24..ab5c28fe4 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,7 +1,7 @@
error: `#[derive(SessionDiagnostic)]` can only be used on structs
--> $DIR/diagnostic-derive.rs:39:1
|
-LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
LL | |
LL | | enum SessionDiagnosticOnEnum {
LL | | Foo,
@@ -9,11 +9,11 @@ LL | | Bar,
LL | | }
| |_^
-error: `#[error = ...]` is not a valid attribute
+error: `#[diag = ...]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:48:1
|
-LL | #[error = "E0123"]
- | ^^^^^^^^^^^^^^^^^^
+LL | #[diag = "E0123"]
+ | ^^^^^^^^^^^^^^^^^
error: `#[nonsense(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:53:1
@@ -21,9 +21,9 @@ error: `#[nonsense(...)]` is not a valid attribute
LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: only `error`, `warning`, `help`, `note` and `warn_` are valid attributes
+ = help: only `diag`, `help`, `note` and `warning` are valid attributes
-error: diagnostic kind not specified
+error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:53:1
|
LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
@@ -33,89 +33,89 @@ LL | |
LL | | struct InvalidStructAttr {}
| |___________________________^
|
- = help: use the `#[error(...)]` attribute to create an error
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
-error: `#[error("...")]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:60:9
+error: `#[diag("...")]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:60:8
|
-LL | #[error("E0123")]
- | ^^^^^^^
+LL | #[diag("E0123")]
+ | ^^^^^^^
|
= help: first argument of the attribute should be the diagnostic slug
error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:60:1
|
-LL | / #[error("E0123")]
+LL | / #[diag("E0123")]
LL | |
LL | |
LL | | struct InvalidLitNestedAttr {}
| |______________________________^
|
- = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
-error: `#[error(nonsense(...))]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:71:9
+error: `#[diag(nonsense(...))]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:71:8
|
-LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^^^^
+LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^^^^
|
= help: first argument of the attribute should be the diagnostic slug
error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:71:1
|
-LL | / #[error(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
LL | |
LL | |
LL | | struct InvalidNestedStructAttr1 {}
| |__________________________________^
|
- = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
-error: `#[error(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:77:9
+error: `#[diag(nonsense = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:77:8
|
-LL | #[error(nonsense = "...", code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^^^^^
+LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^^^^^
|
= help: first argument of the attribute should be the diagnostic slug
error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:77:1
|
-LL | / #[error(nonsense = "...", code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")]
LL | |
LL | |
LL | | struct InvalidNestedStructAttr2 {}
| |__________________________________^
|
- = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
-error: `#[error(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:83:9
+error: `#[diag(nonsense = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:83:8
|
-LL | #[error(nonsense = 4, code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^
+LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
|
= help: first argument of the attribute should be the diagnostic slug
error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:83:1
|
-LL | / #[error(nonsense = 4, code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")]
LL | |
LL | |
LL | | struct InvalidNestedStructAttr3 {}
| |__________________________________^
|
- = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
-error: `#[error(slug = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:89:59
+error: `#[diag(slug = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:89:58
|
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
|
= help: only `code` is a valid nested attributes following the slug
@@ -128,119 +128,71 @@ LL | #[suggestion = "bar"]
error: specified multiple times
--> $DIR/diagnostic-derive.rs:103:1
|
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: previously specified here
- --> $DIR/diagnostic-derive.rs:102:1
- |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: specified multiple times
- --> $DIR/diagnostic-derive.rs:103:1
- |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/diagnostic-derive.rs:102:1
|
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: specified multiple times
- --> $DIR/diagnostic-derive.rs:103:50
- |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
- | ^^^^^^^
- |
-note: previously specified here
- --> $DIR/diagnostic-derive.rs:102:50
- |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
- | ^^^^^^^
-
-error: specified multiple times
- --> $DIR/diagnostic-derive.rs:111:1
- |
-LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: previously specified here
- --> $DIR/diagnostic-derive.rs:110:1
- |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: specified multiple times
- --> $DIR/diagnostic-derive.rs:111:1
- |
-LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: previously specified here
- --> $DIR/diagnostic-derive.rs:110:1
- |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:111:52
+ --> $DIR/diagnostic-derive.rs:103:49
|
-LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
- | ^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:110:50
+ --> $DIR/diagnostic-derive.rs:102:49
|
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
- | ^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:118:66
+ --> $DIR/diagnostic-derive.rs:109:65
|
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
- | ^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+ | ^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:118:50
+ --> $DIR/diagnostic-derive.rs:109:49
|
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
- | ^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+ | ^^^^^^^
-error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:123:43
+error: `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:114:42
|
-LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: diagnostic kind not specified
- --> $DIR/diagnostic-derive.rs:128:1
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:119:1
|
LL | struct KindNotProvided {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: use the `#[error(...)]` attribute to create an error
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
error: diagnostic slug not specified
- --> $DIR/diagnostic-derive.rs:131:1
+ --> $DIR/diagnostic-derive.rs:122:1
|
-LL | / #[error(code = "E0456")]
+LL | / #[diag(code = "E0456")]
LL | |
LL | | struct SlugNotProvided {}
| |_________________________^
|
- = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
- --> $DIR/diagnostic-derive.rs:142:5
+ --> $DIR/diagnostic-derive.rs:133:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: `#[nonsense]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:150:5
+ --> $DIR/diagnostic-derive.rs:141:5
|
LL | #[nonsense]
| ^^^^^^^^^^^
@@ -248,19 +200,19 @@ LL | #[nonsense]
= help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes
error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
- --> $DIR/diagnostic-derive.rs:167:5
+ --> $DIR/diagnostic-derive.rs:158:5
|
LL | #[label(typeck::label)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: `name` doesn't refer to a field on this type
- --> $DIR/diagnostic-derive.rs:175:45
+ --> $DIR/diagnostic-derive.rs:166:45
|
LL | #[suggestion(typeck::suggestion, code = "{name}")]
| ^^^^^^^^
error: invalid format string: expected `'}'` but string was terminated
- --> $DIR/diagnostic-derive.rs:180:16
+ --> $DIR/diagnostic-derive.rs:171:16
|
LL | #[derive(SessionDiagnostic)]
| - ^ expected `'}'` in format string
@@ -271,7 +223,7 @@ LL | #[derive(SessionDiagnostic)]
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: invalid format string: unmatched `}` found
- --> $DIR/diagnostic-derive.rs:190:15
+ --> $DIR/diagnostic-derive.rs:181:15
|
LL | #[derive(SessionDiagnostic)]
| ^ unmatched `}` in format string
@@ -280,13 +232,13 @@ LL | #[derive(SessionDiagnostic)]
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
- --> $DIR/diagnostic-derive.rs:210:5
+ --> $DIR/diagnostic-derive.rs:201:5
|
LL | #[label(typeck::label)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: `#[suggestion(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:235:18
+ --> $DIR/diagnostic-derive.rs:226:18
|
LL | #[suggestion(nonsense = "bar")]
| ^^^^^^^^^^^^^^^^
@@ -294,7 +246,7 @@ LL | #[suggestion(nonsense = "bar")]
= help: only `message`, `code` and `applicability` are valid field attributes
error: `#[suggestion(msg = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:243:18
+ --> $DIR/diagnostic-derive.rs:234:18
|
LL | #[suggestion(msg = "bar")]
| ^^^^^^^^^^^
@@ -302,7 +254,7 @@ LL | #[suggestion(msg = "bar")]
= help: only `message`, `code` and `applicability` are valid field attributes
error: wrong field type for suggestion
- --> $DIR/diagnostic-derive.rs:265:5
+ --> $DIR/diagnostic-derive.rs:256:5
|
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
LL | |
@@ -312,7 +264,7 @@ LL | | suggestion: Applicability,
= help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
error: type of field annotated with `#[suggestion(...)]` contains more than one `Span`
- --> $DIR/diagnostic-derive.rs:280:5
+ --> $DIR/diagnostic-derive.rs:271:5
|
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
LL | |
@@ -320,7 +272,7 @@ LL | | suggestion: (Span, Span, Applicability),
| |___________________________________________^
error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
- --> $DIR/diagnostic-derive.rs:288:5
+ --> $DIR/diagnostic-derive.rs:279:5
|
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
LL | |
@@ -328,62 +280,128 @@ LL | | suggestion: (Applicability, Applicability, Span),
| |____________________________________________________^
error: `#[label = ...]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:296:5
+ --> $DIR/diagnostic-derive.rs:287:5
|
LL | #[label = "bar"]
| ^^^^^^^^^^^^^^^^
error: applicability cannot be set in both the field and attribute
- --> $DIR/diagnostic-derive.rs:447:52
+ --> $DIR/diagnostic-derive.rs:438:52
|
LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid applicability
- --> $DIR/diagnostic-derive.rs:455:52
+ --> $DIR/diagnostic-derive.rs:446:52
|
LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[label(...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:518:5
+ --> $DIR/diagnostic-derive.rs:509:5
|
LL | #[label(typeck::label, foo)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[label(...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:526:5
+ --> $DIR/diagnostic-derive.rs:517:5
|
LL | #[label(typeck::label, foo = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[label(...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:534:5
+ --> $DIR/diagnostic-derive.rs:525:5
|
LL | #[label(typeck::label, foo("..."))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: only `#[error(..)]` and `#[warning(..)]` are supported
- --> $DIR/diagnostic-derive.rs:540:1
+error: `#[primary_span]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:538:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: the `primary_span` field attribute is not valid for lint diagnostics
+
+error: `#[error(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:558:1
|
-LL | / #[lint(typeck::ambiguous_lifetime_bound)]
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `error` and `lint` have been replaced by `diag`
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:558:1
+ |
+LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
LL | |
-LL | | struct LintsBad {
-LL | | }
- | |_^
+LL | |
+LL | |
+LL | | struct ErrorAttribute {}
+ | |________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+
+error: `#[warn_(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:565:1
+ |
+LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: use the `#[error(...)]` attribute to create a error
+ = help: `warn_` have been replaced by `warning`
-error: only `#[lint(..)]` is supported
- --> $DIR/diagnostic-derive.rs:551:1
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:565:1
|
-LL | / #[error(typeck::ambiguous_lifetime_bound)]
+LL | / #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
LL | |
-LL | | struct ErrorsBad {
-LL | | }
- | |_^
+LL | |
+LL | |
+LL | | struct WarnAttribute {}
+ | |_______________________^
|
- = help: use the `#[lint(...)]` attribute to create a lint
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+
+error: `#[lint(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:572:1
+ |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `error` and `lint` have been replaced by `diag`
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:572:1
+ |
+LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct LintAttributeOnSessionDiag {}
+ | |____________________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+
+error: `#[lint(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:579:1
+ |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `error` and `lint` have been replaced by `diag`
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:579:1
+ |
+LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct LintAttributeOnLintDiag {}
+ | |_________________________________^
+ |
+ = help: specify the slug as the first argument to the attribute, such as `#[diag(typeck::example_error)]`
error: cannot find attribute `nonsense` in this scope
--> $DIR/diagnostic-derive.rs:53:3
@@ -392,32 +410,56 @@ LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
| ^^^^^^^^
error: cannot find attribute `nonsense` in this scope
- --> $DIR/diagnostic-derive.rs:150:7
+ --> $DIR/diagnostic-derive.rs:141:7
|
LL | #[nonsense]
| ^^^^^^^^
+error: cannot find attribute `error` in this scope
+ --> $DIR/diagnostic-derive.rs:558:3
+ |
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^
+
+error: cannot find attribute `warn_` in this scope
+ --> $DIR/diagnostic-derive.rs:565:3
+ |
+LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^ help: a built-in attribute with a similar name exists: `warn`
+
+error: cannot find attribute `lint` in this scope
+ --> $DIR/diagnostic-derive.rs:572:3
+ |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^ help: a built-in attribute with a similar name exists: `link`
+
+error: cannot find attribute `lint` in this scope
+ --> $DIR/diagnostic-derive.rs:579:3
+ |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^ help: a built-in attribute with a similar name exists: `link`
+
error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
- --> $DIR/diagnostic-derive.rs:66:9
+ --> $DIR/diagnostic-derive.rs:66:8
|
-LL | #[error(nonsense, code = "E0123")]
- | ^^^^^^^^ not found in `rustc_errors::fluent`
+LL | #[diag(nonsense, code = "E0123")]
+ | ^^^^^^^^ not found in `rustc_errors::fluent`
error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
- --> $DIR/diagnostic-derive.rs:340:10
+ --> $DIR/diagnostic-derive.rs:331:10
|
LL | #[derive(SessionDiagnostic)]
| ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
|
= help: normalized in stderr
note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
- --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:539:19
+ --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
|
LL | arg: impl IntoDiagnosticArg,
| ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg`
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 48 previous errors
+error: aborting due to 55 previous errors
Some errors have detailed explanations: E0277, E0425.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
index 16da25c40..812ca0c72 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
@@ -167,8 +167,8 @@ enum P {
#[derive(SessionSubdiagnostic)]
enum Q {
#[bar]
-//~^ ERROR `#[bar]` is not a valid attribute
-//~^^ ERROR cannot find attribute `bar` in this scope
+ //~^ ERROR `#[bar]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@@ -179,8 +179,8 @@ enum Q {
#[derive(SessionSubdiagnostic)]
enum R {
#[bar = "..."]
-//~^ ERROR `#[bar = ...]` is not a valid attribute
-//~^^ ERROR cannot find attribute `bar` in this scope
+ //~^ ERROR `#[bar = ...]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@@ -191,8 +191,8 @@ enum R {
#[derive(SessionSubdiagnostic)]
enum S {
#[bar = 4]
-//~^ ERROR `#[bar = ...]` is not a valid attribute
-//~^^ ERROR cannot find attribute `bar` in this scope
+ //~^ ERROR `#[bar = ...]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@@ -203,8 +203,8 @@ enum S {
#[derive(SessionSubdiagnostic)]
enum T {
#[bar("...")]
-//~^ ERROR `#[bar("...")]` is not a valid attribute
-//~^^ ERROR cannot find attribute `bar` in this scope
+ //~^ ERROR `#[bar(...)]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@@ -215,7 +215,7 @@ enum T {
#[derive(SessionSubdiagnostic)]
enum U {
#[label(code = "...")]
-//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
+ //~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
A {
#[primary_span]
span: Span,
@@ -232,7 +232,7 @@ enum V {
var: String,
},
B {
-//~^ ERROR subdiagnostic kind not specified
+ //~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
var: String,
@@ -309,11 +309,7 @@ union AC {
#[derive(SessionSubdiagnostic)]
#[label(parser::add_paren)]
-//~^ NOTE previously specified here
-//~^^ NOTE previously specified here
#[label(parser::add_paren)]
-//~^ ERROR specified multiple times
-//~^^ ERROR specified multiple times
struct AD {
#[primary_span]
span: Span,
@@ -331,16 +327,16 @@ struct AE {
#[label(parser::add_paren)]
struct AF {
#[primary_span]
-//~^ NOTE previously specified here
+ //~^ NOTE previously specified here
span_a: Span,
#[primary_span]
-//~^ ERROR specified multiple times
+ //~^ ERROR specified multiple times
span_b: Span,
}
#[derive(SessionSubdiagnostic)]
struct AG {
-//~^ ERROR subdiagnostic kind not specified
+ //~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
}
@@ -392,27 +388,25 @@ struct AK {
#[primary_span]
span: Span,
#[applicability]
-//~^ NOTE previously specified here
+ //~^ NOTE previously specified here
applicability_a: Applicability,
#[applicability]
-//~^ ERROR specified multiple times
+ //~^ ERROR specified multiple times
applicability_b: Applicability,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
-//~^ ERROR suggestion without `applicability`
struct AL {
#[primary_span]
span: Span,
#[applicability]
-//~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability`
+ //~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability`
applicability: Span,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
-//~^ ERROR suggestion without `applicability`
struct AM {
#[primary_span]
span: Span,
@@ -448,8 +442,7 @@ struct AQ;
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
-//~^ ERROR suggestion without `applicability`
-//~^^ ERROR suggestion without `#[primary_span]` field
+//~^ ERROR suggestion without `#[primary_span]` field
struct AR {
var: String,
}
@@ -510,13 +503,129 @@ enum AX {
}
#[derive(SessionSubdiagnostic)]
-#[warn_(parser::add_paren)]
-struct AY {
-}
+#[warning(parser::add_paren)]
+struct AY {}
#[derive(SessionSubdiagnostic)]
-#[warn_(parser::add_paren)]
+#[warning(parser::add_paren)]
struct AZ {
#[primary_span]
span: Span,
}
+
+#[derive(SessionSubdiagnostic)]
+#[suggestion(parser::add_paren, code = "...")]
+//~^ ERROR suggestion without `#[primary_span]` field
+struct BA {
+ #[suggestion_part]
+ //~^ ERROR `#[suggestion_part]` is not a valid attribute
+ span: Span,
+ #[suggestion_part(code = "...")]
+ //~^ ERROR `#[suggestion_part(...)]` is not a valid attribute
+ span2: Span,
+ #[applicability]
+ applicability: Applicability,
+ var: String,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
+//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
+//~| ERROR `code` is not a valid nested attribute of a `multipart_suggestion` attribute
+struct BBa {
+ var: String,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+struct BBb {
+ #[suggestion_part]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span1: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+struct BBc {
+ #[suggestion_part()]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span1: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren)]
+//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
+struct BC {
+ #[primary_span]
+ //~^ ERROR `#[primary_span]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren)]
+struct BD {
+ #[suggestion_part]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span1: Span,
+ #[suggestion_part()]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span2: Span,
+ #[suggestion_part(foo = "bar")]
+ //~^ ERROR `#[suggestion_part(foo = ...)]` is not a valid attribute
+ span4: Span,
+ #[suggestion_part(code = "...")]
+ //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ s1: String,
+ #[suggestion_part()]
+ //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ s2: String,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+struct BE {
+ #[suggestion_part(code = "...", code = ",,,")]
+ //~^ ERROR specified multiple times
+ //~| NOTE previously specified here
+ span: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+struct BF {
+ #[suggestion_part(code = "(")]
+ first: Span,
+ #[suggestion_part(code = ")")]
+ second: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren)]
+struct BG {
+ #[applicability]
+ appl: Applicability,
+ #[suggestion_part(code = "(")]
+ first: Span,
+ #[suggestion_part(code = ")")]
+ second: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+//~^ NOTE previously specified here
+struct BH {
+ #[applicability]
+ //~^ ERROR specified multiple times
+ appl: Applicability,
+ #[suggestion_part(code = "(")]
+ first: Span,
+ #[suggestion_part(code = ")")]
+ second: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+struct BI {
+ #[suggestion_part(code = "")]
+ spans: Vec<Span>,
+}
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
index a289c4fff..0a0247e89 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
@@ -65,16 +65,16 @@ LL | #[label()]
| ^^^^^^^^^^
error: `code` is not a valid nested attribute of a `label` attribute
- --> $DIR/subdiagnostic-derive.rs:137:1
+ --> $DIR/subdiagnostic-derive.rs:137:28
|
LL | #[label(parser::add_paren, code = "...")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^
error: `applicability` is not a valid nested attribute of a `label` attribute
- --> $DIR/subdiagnostic-derive.rs:146:1
+ --> $DIR/subdiagnostic-derive.rs:146:28
|
LL | #[label(parser::add_paren, applicability = "machine-applicable")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsupported type attribute for subdiagnostic enum
--> $DIR/subdiagnostic-derive.rs:155:1
@@ -100,13 +100,11 @@ error: `#[bar = ...]` is not a valid attribute
LL | #[bar = 4]
| ^^^^^^^^^^
-error: `#[bar("...")]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:205:11
+error: `#[bar(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:205:5
|
LL | #[bar("...")]
- | ^^^^^
- |
- = help: first argument of the attribute should be the diagnostic slug
+ | ^^^^^^^^^^^^^
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
--> $DIR/subdiagnostic-derive.rs:217:5
@@ -163,6 +161,8 @@ error: `#[bar(...)]` is not a valid attribute
|
LL | #[bar("...")]
| ^^^^^^^^^^^^^
+ |
+ = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
error: unexpected unsupported untagged union
--> $DIR/subdiagnostic-derive.rs:304:1
@@ -174,32 +174,8 @@ LL | | b: u64
LL | | }
| |_^
-error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:314:1
- |
-LL | #[label(parser::add_paren)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:311:1
- |
-LL | #[label(parser::add_paren)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:314:1
- |
-LL | #[label(parser::add_paren)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:311:1
- |
-LL | #[label(parser::add_paren)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
error: `#[label(parser::add_paren)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:323:28
+ --> $DIR/subdiagnostic-derive.rs:319:28
|
LL | #[label(parser::add_paren, parser::add_paren)]
| ^^^^^^^^^^^^^^^^^
@@ -207,133 +183,225 @@ LL | #[label(parser::add_paren, parser::add_paren)]
= help: a diagnostic slug must be the first argument to the attribute
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:336:5
+ --> $DIR/subdiagnostic-derive.rs:332:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:333:5
+ --> $DIR/subdiagnostic-derive.rs:329:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: subdiagnostic kind not specified
- --> $DIR/subdiagnostic-derive.rs:342:8
+ --> $DIR/subdiagnostic-derive.rs:338:8
|
LL | struct AG {
| ^^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:379:47
+ --> $DIR/subdiagnostic-derive.rs:375:47
|
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
| ^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:379:33
+ --> $DIR/subdiagnostic-derive.rs:375:33
|
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
| ^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:397:5
+ --> $DIR/subdiagnostic-derive.rs:393:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:394:5
+ --> $DIR/subdiagnostic-derive.rs:390:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
- --> $DIR/subdiagnostic-derive.rs:408:5
+ --> $DIR/subdiagnostic-derive.rs:403:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
-error: suggestion without `applicability`
- --> $DIR/subdiagnostic-derive.rs:403:1
+error: suggestion without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:416:1
|
-LL | / #[suggestion(parser::add_paren, code = "...")]
-LL | |
-LL | | struct AL {
-LL | | #[primary_span]
-... |
-LL | | applicability: Span,
-LL | | }
- | |_^
+LL | #[suggestion(parser::add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: suggestion without `applicability`
- --> $DIR/subdiagnostic-derive.rs:414:1
+error: invalid applicability
+ --> $DIR/subdiagnostic-derive.rs:426:46
+ |
+LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: suggestion without `#[primary_span]` field
+ --> $DIR/subdiagnostic-derive.rs:444:1
|
LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
-LL | | struct AM {
-LL | | #[primary_span]
-LL | | span: Span,
+LL | | struct AR {
+LL | | var: String,
LL | | }
| |_^
-error: suggestion without `code = "..."`
- --> $DIR/subdiagnostic-derive.rs:422:1
+error: unsupported type attribute for subdiagnostic enum
+ --> $DIR/subdiagnostic-derive.rs:458:1
+ |
+LL | #[label]
+ | ^^^^^^^^
+
+error: `var` doesn't refer to a field on this type
+ --> $DIR/subdiagnostic-derive.rs:478:39
+ |
+LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
+ | ^^^^^^^
+
+error: `var` doesn't refer to a field on this type
+ --> $DIR/subdiagnostic-derive.rs:497:43
+ |
+LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
+ | ^^^^^^^
+
+error: `#[suggestion_part]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:520:5
+ |
+LL | #[suggestion_part]
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
+
+error: `#[suggestion_part(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:523:5
+ |
+LL | #[suggestion_part(code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-LL | / #[suggestion(parser::add_paren)]
+ = help: `#[suggestion_part(...)]` is only valid in multipart suggestions
+
+error: suggestion without `#[primary_span]` field
+ --> $DIR/subdiagnostic-derive.rs:517:1
+ |
+LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
-LL | | struct AN {
-LL | | #[primary_span]
+LL | | struct BA {
+LL | | #[suggestion_part]
... |
-LL | | applicability: Applicability,
+LL | | var: String,
LL | | }
| |_^
-error: invalid applicability
- --> $DIR/subdiagnostic-derive.rs:432:46
+error: `code` is not a valid nested attribute of a `multipart_suggestion` attribute
+ --> $DIR/subdiagnostic-derive.rs:532:43
|
-LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
- | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^
-error: suggestion without `applicability`
- --> $DIR/subdiagnostic-derive.rs:450:1
+error: multipart suggestion without any `#[suggestion_part(...)]` fields
+ --> $DIR/subdiagnostic-derive.rs:532:1
|
-LL | / #[suggestion(parser::add_paren, code = "...")]
+LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
LL | |
LL | |
-LL | | struct AR {
+LL | | struct BBa {
LL | | var: String,
LL | | }
| |_^
-error: suggestion without `#[primary_span]` field
- --> $DIR/subdiagnostic-derive.rs:450:1
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:542:5
|
-LL | / #[suggestion(parser::add_paren, code = "...")]
+LL | #[suggestion_part]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:550:5
+ |
+LL | #[suggestion_part()]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: `#[primary_span]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:559:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
+
+error: multipart suggestion without any `#[suggestion_part(...)]` fields
+ --> $DIR/subdiagnostic-derive.rs:556:1
+ |
+LL | / #[multipart_suggestion(parser::add_paren)]
LL | |
+LL | | struct BC {
+LL | | #[primary_span]
LL | |
-LL | | struct AR {
-LL | | var: String,
+LL | | span: Span,
LL | | }
| |_^
-error: unsupported type attribute for subdiagnostic enum
- --> $DIR/subdiagnostic-derive.rs:465:1
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:567:5
|
-LL | #[label]
- | ^^^^^^^^
+LL | #[suggestion_part]
+ | ^^^^^^^^^^^^^^^^^^
-error: `var` doesn't refer to a field on this type
- --> $DIR/subdiagnostic-derive.rs:485:39
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:570:5
|
-LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
- | ^^^^^^^
+LL | #[suggestion_part()]
+ | ^^^^^^^^^^^^^^^^^^^^
-error: `var` doesn't refer to a field on this type
- --> $DIR/subdiagnostic-derive.rs:504:43
+error: `#[suggestion_part(foo = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:573:23
|
-LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
- | ^^^^^^^
+LL | #[suggestion_part(foo = "bar")]
+ | ^^^^^^^^^^^
+ |
+ = help: `code` is the only valid nested attribute
+
+error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/subdiagnostic-derive.rs:576:5
+ |
+LL | #[suggestion_part(code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/subdiagnostic-derive.rs:579:5
+ |
+LL | #[suggestion_part()]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:587:37
+ |
+LL | #[suggestion_part(code = "...", code = ",,,")]
+ | ^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:587:23
+ |
+LL | #[suggestion_part(code = "...", code = ",,,")]
+ | ^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:617:5
+ |
+LL | #[applicability]
+ | ^^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:614:43
+ |
+LL | #[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot find attribute `foo` in this scope
--> $DIR/subdiagnostic-derive.rs:63:3
@@ -395,6 +463,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
LL | #[label(slug)]
| ^^^^ not found in `rustc_errors::fluent`
-error: aborting due to 52 previous errors
+error: aborting due to 63 previous errors
For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/abi/issues/issue-97463-broken-abi-leaked-uninit-data.rs b/src/test/ui/abi/issues/issue-97463-broken-abi-leaked-uninit-data.rs
new file mode 100644
index 000000000..fba880d4f
--- /dev/null
+++ b/src/test/ui/abi/issues/issue-97463-broken-abi-leaked-uninit-data.rs
@@ -0,0 +1,39 @@
+// run-pass
+// ignore-wasm
+#![allow(dead_code)]
+#![allow(improper_ctypes)]
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+ pub fn issue_97463_leak_uninit_data(a: u32, b: u32, c: u32) -> u16;
+}
+
+fn main() {
+ const C1: usize = 0x327b23c6;
+ const C2: usize = C1 & 0xFFFF;
+
+ let r1: usize = 0x0;
+ let r2: usize = C1;
+ let r3: usize = 0x0;
+ let value: u16 = unsafe { issue_97463_leak_uninit_data(r1 as u32, r2 as u32, r3 as u32) };
+
+ // NOTE: as an example of the sensitivity of this test to optimization choices,
+ // uncommenting this block of code makes the bug go away on pnkfelix's machine.
+ // (But observing via `dbg!` doesn't hide the bug. At least sometimes.)
+ /*
+ println!("{}", value);
+ println!("{}", value as usize);
+ println!("{}", usize::from(value));
+ println!("{}", (value as usize) & 0xFFFF);
+ */
+
+ let d1 = value;
+ let d2 = value as usize;
+ let d3 = usize::from(value);
+ let d4 = (value as usize) & 0xFFFF;
+
+ let d = (&d1, &d2, &d3, &d4);
+ let d_ = (d1, d2, d3, d4);
+
+ assert_eq!(((&(C2 as u16), &C2, &C2, &C2), (C2 as u16, C2, C2, C2)), (d, d_));
+}
diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
index 54b7c8bb9..851da231a 100644
--- a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
+++ b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
@@ -86,7 +86,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
// Because we are compiling this code with `-C panic=abort`, this wouldn't normally be needed.
// However, `core` and `alloc` are both compiled with `-C panic=unwind`, which means that functions
-// in these libaries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
+// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
// unwind. So, for this test case we will define the symbol.
#[lang = "eh_personality"]
extern fn rust_eh_personality() {}
diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs
index ffa331a99..30ce0f162 100644
--- a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs
+++ b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs
@@ -73,7 +73,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
// Because we are compiling this code with `-C panic=abort`, this wouldn't normally be needed.
// However, `core` and `alloc` are both compiled with `-C panic=unwind`, which means that functions
-// in these libaries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
+// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
// unwind. So, for this test case we will define the symbol.
#[lang = "eh_personality"]
extern fn rust_eh_personality() {}
diff --git a/src/test/ui/argument-suggestions/basic.stderr b/src/test/ui/argument-suggestions/basic.stderr
index c495ad6b8..b118ce1bd 100644
--- a/src/test/ui/argument-suggestions/basic.stderr
+++ b/src/test/ui/argument-suggestions/basic.stderr
@@ -26,7 +26,7 @@ LL | fn extra() {}
help: remove the extra argument
|
LL | extra();
- | ~~~~~~~
+ | ~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/basic.rs:22:5
@@ -42,7 +42,7 @@ LL | fn missing(_i: u32) {}
help: provide the argument
|
LL | missing(/* u32 */);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/basic.rs:23:5
@@ -60,7 +60,7 @@ LL | fn swapped(_i: u32, _s: &str) {}
help: swap these arguments
|
LL | swapped(1, "");
- | ~~~~~~~~~~~~~~
+ | ~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/basic.rs:24:5
@@ -79,7 +79,7 @@ LL | fn permuted(_x: X, _y: Y, _z: Z) {}
help: reorder these arguments
|
LL | permuted(X {}, Y {}, Z {});
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error[E0057]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/basic.rs:27:5
@@ -95,7 +95,7 @@ LL | let closure = |x| x;
help: provide the argument
|
LL | closure(/* value */);
- | ~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error: aborting due to 6 previous errors
diff --git a/src/test/ui/argument-suggestions/complex.stderr b/src/test/ui/argument-suggestions/complex.stderr
index fa030a8f4..205a85298 100644
--- a/src/test/ui/argument-suggestions/complex.stderr
+++ b/src/test/ui/argument-suggestions/complex.stderr
@@ -8,11 +8,11 @@ note: function defined here
--> $DIR/complex.rs:11:4
|
LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
- | ^^^^^^^ ------- -------- ----- ----- ----- ----- ----- ------
+ | ^^^^^^^ ------- -------- ----- ----- ----- ----- ----- -----
help: did you mean
|
LL | complex(/* u32 */, &"", /* E */, F::X2, G{}, X {}, Y {}, Z {});
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/exotic-calls.stderr b/src/test/ui/argument-suggestions/exotic-calls.stderr
index ca93ecc4e..0580e53c5 100644
--- a/src/test/ui/argument-suggestions/exotic-calls.stderr
+++ b/src/test/ui/argument-suggestions/exotic-calls.stderr
@@ -12,7 +12,7 @@ LL | fn foo<T: Fn()>(t: T) {
help: remove the extra argument
|
LL | t();
- | ~~~
+ | ~~
error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:7:5
@@ -28,7 +28,7 @@ LL | fn bar(t: impl Fn()) {
help: remove the extra argument
|
LL | t();
- | ~~~
+ | ~~
error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:16:5
@@ -44,7 +44,7 @@ LL | fn baz() -> impl Fn() {
help: remove the extra argument
|
LL | baz()()
- |
+ | ~~
error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:22:5
@@ -60,7 +60,7 @@ LL | let x = || {};
help: remove the extra argument
|
LL | x();
- | ~~~
+ | ~~
error: aborting due to 4 previous errors
diff --git a/src/test/ui/argument-suggestions/extra_arguments.stderr b/src/test/ui/argument-suggestions/extra_arguments.stderr
index 32b1e1573..48787b0c3 100644
--- a/src/test/ui/argument-suggestions/extra_arguments.stderr
+++ b/src/test/ui/argument-suggestions/extra_arguments.stderr
@@ -12,7 +12,7 @@ LL | fn empty() {}
help: remove the extra argument
|
LL | empty();
- | ~~~~~~~
+ | ~~
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:9:3
@@ -28,7 +28,7 @@ LL | fn one_arg(_a: i32) {}
help: remove the extra argument
|
LL | one_arg(1);
- | ~~~~~~~~~~
+ | ~~~
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:10:3
@@ -44,7 +44,7 @@ LL | fn one_arg(_a: i32) {}
help: remove the extra argument
|
LL | one_arg(1);
- | ~~~~~~~~~~
+ | ~~~
error[E0061]: this function takes 1 argument but 3 arguments were supplied
--> $DIR/extra_arguments.rs:11:3
@@ -62,7 +62,7 @@ LL | fn one_arg(_a: i32) {}
help: remove the extra arguments
|
LL | one_arg(1);
- | ~~~~~~~~~~
+ | ~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:13:3
@@ -78,7 +78,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
help: remove the extra argument
|
LL | two_arg_same(1, 1);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:14:3
@@ -94,7 +94,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
help: remove the extra argument
|
LL | two_arg_same(1, 1);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:16:3
@@ -110,7 +110,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
help: remove the extra argument
|
LL | two_arg_diff(1, "");
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:17:3
@@ -126,7 +126,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
help: remove the extra argument
|
LL | two_arg_diff(1, "");
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~
error[E0061]: this function takes 2 arguments but 4 arguments were supplied
--> $DIR/extra_arguments.rs:18:3
@@ -144,7 +144,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
help: remove the extra arguments
|
LL | two_arg_diff(1, "");
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~
error[E0061]: this function takes 2 arguments but 4 arguments were supplied
--> $DIR/extra_arguments.rs:19:3
@@ -162,7 +162,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
help: remove the extra arguments
|
LL | two_arg_diff(1, "");
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:22:3
@@ -178,7 +178,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
help: remove the extra argument
|
LL | two_arg_same(1, 1);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:23:3
@@ -194,7 +194,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
help: remove the extra argument
|
LL | two_arg_diff(1, "");
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:24:3
@@ -213,7 +213,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
help: remove the extra argument
|
LL | two_arg_same(1, 1);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:30:3
@@ -232,7 +232,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
help: remove the extra argument
|
LL | two_arg_diff(1, "");
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~
error: aborting due to 14 previous errors
diff --git a/src/test/ui/argument-suggestions/invalid_arguments.stderr b/src/test/ui/argument-suggestions/invalid_arguments.stderr
index 33f27d48f..303f08695 100644
--- a/src/test/ui/argument-suggestions/invalid_arguments.stderr
+++ b/src/test/ui/argument-suggestions/invalid_arguments.stderr
@@ -24,7 +24,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:6:4
|
LL | fn two_arg_same(_a: i32, _b: i32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:17:16
@@ -38,7 +38,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:6:4
|
LL | fn two_arg_same(_a: i32, _b: i32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:18:3
@@ -66,7 +66,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:7:4
|
LL | fn two_arg_diff(_a: i32, _b: f32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:20:16
@@ -80,7 +80,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:7:4
|
LL | fn two_arg_diff(_a: i32, _b: f32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:21:3
@@ -108,7 +108,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
- | ^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:25:21
@@ -122,7 +122,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
- | ^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:26:26
@@ -136,7 +136,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
- | ^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^ --------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:28:3
@@ -207,7 +207,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
- | ^^^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:35:23
@@ -221,7 +221,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
- | ^^^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:36:26
@@ -235,7 +235,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
- | ^^^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^^^ --------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:38:3
diff --git a/src/test/ui/argument-suggestions/issue-100478.rs b/src/test/ui/argument-suggestions/issue-100478.rs
new file mode 100644
index 000000000..6bef6ad10
--- /dev/null
+++ b/src/test/ui/argument-suggestions/issue-100478.rs
@@ -0,0 +1,52 @@
+use std::sync::Arc;
+macro_rules! GenT {
+ ($name:tt) => {
+ #[derive(Default, Debug)]
+ struct $name {
+ #[allow(unused)]
+ val: i32,
+ }
+
+ impl $name {
+ #[allow(unused)]
+ fn new(val: i32) -> Self {
+ $name { val }
+ }
+ }
+ };
+}
+
+GenT!(T1);
+GenT!(T2);
+GenT!(T3);
+GenT!(T4);
+GenT!(T5);
+GenT!(T6);
+GenT!(T7);
+GenT!(T8);
+
+#[allow(unused)]
+fn foo(p1: T1, p2: Arc<T2>, p3: T3, p4: Arc<T4>, p5: T5, p6: T6, p7: T7, p8: Arc<T8>) {}
+fn three_diff(_a: T1, _b: T2, _c: T3) {}
+fn four_shuffle(_a: T1, _b: T2, _c: T3, _d: T4) {}
+
+fn main() {
+ three_diff(T2::new(0)); //~ ERROR this function takes
+ four_shuffle(T3::default(), T4::default(), T1::default(), T2::default()); //~ ERROR 35:5: 35:17: arguments to this function are incorrect [E0308]
+ four_shuffle(T3::default(), T2::default(), T1::default(), T3::default()); //~ ERROR 36:5: 36:17: arguments to this function are incorrect [E0308]
+
+ let p1 = T1::new(0);
+ let p2 = Arc::new(T2::new(0));
+ let p3 = T3::new(0);
+ let p4 = Arc::new(T4::new(1));
+ let p5 = T5::new(0);
+ let p6 = T6::new(0);
+ let p7 = T7::new(0);
+ let p8 = Arc::default();
+
+ foo(
+ //~^ 47:5: 47:8: this function takes 8 arguments but 7 arguments were supplied [E0061]
+ p1, //p2,
+ p3, p4, p5, p6, p7, p8,
+ );
+}
diff --git a/src/test/ui/argument-suggestions/issue-100478.stderr b/src/test/ui/argument-suggestions/issue-100478.stderr
new file mode 100644
index 000000000..df02a312c
--- /dev/null
+++ b/src/test/ui/argument-suggestions/issue-100478.stderr
@@ -0,0 +1,81 @@
+error[E0061]: this function takes 3 arguments but 1 argument was supplied
+ --> $DIR/issue-100478.rs:34:5
+ |
+LL | three_diff(T2::new(0));
+ | ^^^^^^^^^^------------
+ | ||
+ | |an argument of type `T1` is missing
+ | an argument of type `T3` is missing
+ |
+note: function defined here
+ --> $DIR/issue-100478.rs:30:4
+ |
+LL | fn three_diff(_a: T1, _b: T2, _c: T3) {}
+ | ^^^^^^^^^^ ------ ------ ------
+help: provide the arguments
+ |
+LL | three_diff(/* T1 */, T2::new(0), /* T3 */);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/issue-100478.rs:35:5
+ |
+LL | four_shuffle(T3::default(), T4::default(), T1::default(), T2::default());
+ | ^^^^^^^^^^^^ ------------- ------------- ------------- ------------- expected `T4`, found `T2`
+ | | | |
+ | | | expected `T3`, found `T1`
+ | | expected `T2`, found `T4`
+ | expected `T1`, found `T3`
+ |
+note: function defined here
+ --> $DIR/issue-100478.rs:31:4
+ |
+LL | fn four_shuffle(_a: T1, _b: T2, _c: T3, _d: T4) {}
+ | ^^^^^^^^^^^^ ------ ------ ------ ------
+help: did you mean
+ |
+LL | four_shuffle(T1::default(), T2::default(), T3::default(), T4::default());
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/issue-100478.rs:36:5
+ |
+LL | four_shuffle(T3::default(), T2::default(), T1::default(), T3::default());
+ | ^^^^^^^^^^^^ ------------- ------------- ------------- expected struct `T4`, found struct `T3`
+ | | |
+ | | expected `T3`, found `T1`
+ | expected `T1`, found `T3`
+ |
+note: function defined here
+ --> $DIR/issue-100478.rs:31:4
+ |
+LL | fn four_shuffle(_a: T1, _b: T2, _c: T3, _d: T4) {}
+ | ^^^^^^^^^^^^ ------ ------ ------ ------
+help: swap these arguments
+ |
+LL | four_shuffle(T1::default(), T2::default(), T3::default(), /* T4 */);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 8 arguments but 7 arguments were supplied
+ --> $DIR/issue-100478.rs:47:5
+ |
+LL | foo(
+ | ^^^
+...
+LL | p3, p4, p5, p6, p7, p8,
+ | -- an argument of type `Arc<T2>` is missing
+ |
+note: function defined here
+ --> $DIR/issue-100478.rs:29:4
+ |
+LL | fn foo(p1: T1, p2: Arc<T2>, p3: T3, p4: Arc<T4>, p5: T5, p6: T6, p7: T7, p8: Arc<T8>) {}
+ | ^^^ ------ ----------- ------ ----------- ------ ------ ------ -----------
+help: provide the argument
+ |
+LL | foo(p1, /* Arc<T2> */, p3, p4, p5, p6, p7, p8);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/issue-101097.rs b/src/test/ui/argument-suggestions/issue-101097.rs
new file mode 100644
index 000000000..7994d3cd9
--- /dev/null
+++ b/src/test/ui/argument-suggestions/issue-101097.rs
@@ -0,0 +1,21 @@
+struct A;
+struct B;
+struct C;
+struct D;
+
+fn f(
+ a1: A,
+ a2: A,
+ b1: B,
+ b2: B,
+ c1: C,
+ c2: C,
+) {}
+
+fn main() {
+ f(C, A, A, A, B, B, C); //~ ERROR this function takes 6 arguments but 7 arguments were supplied [E0061]
+ f(C, C, A, A, B, B); //~ ERROR arguments to this function are incorrect [E0308]
+ f(A, A, D, D, B, B); //~ arguments to this function are incorrect [E0308]
+ f(C, C, B, B, A, A); //~ arguments to this function are incorrect [E0308]
+ f(C, C, A, B, A, A); //~ arguments to this function are incorrect [E0308]
+}
diff --git a/src/test/ui/argument-suggestions/issue-101097.stderr b/src/test/ui/argument-suggestions/issue-101097.stderr
new file mode 100644
index 000000000..096f8c226
--- /dev/null
+++ b/src/test/ui/argument-suggestions/issue-101097.stderr
@@ -0,0 +1,160 @@
+error[E0061]: this function takes 6 arguments but 7 arguments were supplied
+ --> $DIR/issue-101097.rs:16:5
+ |
+LL | f(C, A, A, A, B, B, C);
+ | ^ - - - - expected `C`, found `B`
+ | | | |
+ | | | argument of type `A` unexpected
+ | | expected `B`, found `A`
+ | expected `A`, found `C`
+ |
+note: function defined here
+ --> $DIR/issue-101097.rs:6:4
+ |
+LL | fn f(
+ | ^
+LL | a1: A,
+ | -----
+LL | a2: A,
+ | -----
+LL | b1: B,
+ | -----
+LL | b2: B,
+ | -----
+LL | c1: C,
+ | -----
+LL | c2: C,
+ | -----
+help: did you mean
+ |
+LL | f(A, A, B, B, C, C);
+ | ~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/issue-101097.rs:17:5
+ |
+LL | f(C, C, A, A, B, B);
+ | ^
+ |
+note: function defined here
+ --> $DIR/issue-101097.rs:6:4
+ |
+LL | fn f(
+ | ^
+LL | a1: A,
+ | -----
+LL | a2: A,
+ | -----
+LL | b1: B,
+ | -----
+LL | b2: B,
+ | -----
+LL | c1: C,
+ | -----
+LL | c2: C,
+ | -----
+help: did you mean
+ |
+LL | f(A, A, B, B, C, C);
+ | ~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/issue-101097.rs:18:5
+ |
+LL | f(A, A, D, D, B, B);
+ | ^ - - ---- two arguments of type `C` and `C` are missing
+ | | |
+ | | argument of type `D` unexpected
+ | argument of type `D` unexpected
+ |
+note: function defined here
+ --> $DIR/issue-101097.rs:6:4
+ |
+LL | fn f(
+ | ^
+LL | a1: A,
+ | -----
+LL | a2: A,
+ | -----
+LL | b1: B,
+ | -----
+LL | b2: B,
+ | -----
+LL | c1: C,
+ | -----
+LL | c2: C,
+ | -----
+help: did you mean
+ |
+LL | f(A, A, B, B, /* C */, /* C */);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/issue-101097.rs:19:5
+ |
+LL | f(C, C, B, B, A, A);
+ | ^ - - - - expected `C`, found `A`
+ | | | |
+ | | | expected `C`, found `A`
+ | | expected `A`, found `C`
+ | expected `A`, found `C`
+ |
+note: function defined here
+ --> $DIR/issue-101097.rs:6:4
+ |
+LL | fn f(
+ | ^
+LL | a1: A,
+ | -----
+LL | a2: A,
+ | -----
+LL | b1: B,
+ | -----
+LL | b2: B,
+ | -----
+LL | c1: C,
+ | -----
+LL | c2: C,
+ | -----
+help: did you mean
+ |
+LL | f(A, A, B, B, C, C);
+ | ~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/issue-101097.rs:20:5
+ |
+LL | f(C, C, A, B, A, A);
+ | ^ - - - - - expected `C`, found `A`
+ | | | | |
+ | | | | expected `C`, found `A`
+ | | | expected struct `B`, found struct `A`
+ | | expected `A`, found `C`
+ | expected `A`, found `C`
+ |
+note: function defined here
+ --> $DIR/issue-101097.rs:6:4
+ |
+LL | fn f(
+ | ^
+LL | a1: A,
+ | -----
+LL | a2: A,
+ | -----
+LL | b1: B,
+ | -----
+LL | b2: B,
+ | -----
+LL | c1: C,
+ | -----
+LL | c2: C,
+ | -----
+help: did you mean
+ |
+LL | f(A, A, /* B */, B, C, C);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/issue-96638.stderr b/src/test/ui/argument-suggestions/issue-96638.stderr
index 8af31b8b7..4d18b97c9 100644
--- a/src/test/ui/argument-suggestions/issue-96638.stderr
+++ b/src/test/ui/argument-suggestions/issue-96638.stderr
@@ -2,7 +2,9 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/issue-96638.rs:8:5
|
LL | f(&x, "");
- | ^ -- an argument of type `usize` is missing
+ | ^ -- -- expected `usize`, found `&str`
+ | |
+ | an argument of type `usize` is missing
|
note: function defined here
--> $DIR/issue-96638.rs:1:4
@@ -12,7 +14,7 @@ LL | fn f(_: usize, _: &usize, _: usize) {}
help: provide the argument
|
LL | f(/* usize */, &x, /* usize */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/issue-97197.stderr b/src/test/ui/argument-suggestions/issue-97197.stderr
index ac54adc5e..de221ba1f 100644
--- a/src/test/ui/argument-suggestions/issue-97197.stderr
+++ b/src/test/ui/argument-suggestions/issue-97197.stderr
@@ -12,7 +12,7 @@ LL | pub fn g(a1: (), a2: bool, a3: bool, a4: bool, a5: bool, a6: ()) -> () {}
help: provide the arguments
|
LL | g((), /* bool */, /* bool */, /* bool */, /* bool */, ());
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/issue-97484.stderr b/src/test/ui/argument-suggestions/issue-97484.stderr
index 9589e919c..caa50f14b 100644
--- a/src/test/ui/argument-suggestions/issue-97484.stderr
+++ b/src/test/ui/argument-suggestions/issue-97484.stderr
@@ -2,8 +2,9 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied
--> $DIR/issue-97484.rs:12:5
|
LL | foo(&&A, B, C, D, E, F, G);
- | ^^^ - - - argument of type `F` unexpected
- | | |
+ | ^^^ - - - - argument of type `F` unexpected
+ | | | |
+ | | | expected `&E`, found struct `E`
| | argument of type `C` unexpected
| argument of type `B` unexpected
|
@@ -19,7 +20,7 @@ LL | foo(&&A, B, C, D, &E, F, G);
help: remove the extra arguments
|
LL | foo(&&A, D, /* &E */, G);
- | ~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/issue-98894.stderr b/src/test/ui/argument-suggestions/issue-98894.stderr
index 0c8b94901..f64a83ab7 100644
--- a/src/test/ui/argument-suggestions/issue-98894.stderr
+++ b/src/test/ui/argument-suggestions/issue-98894.stderr
@@ -12,7 +12,7 @@ LL | (|_, ()| ())(if true {} else {return;});
help: provide the argument
|
LL | (|_, ()| ())(if true {} else {return;}, ());
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/issue-98897.stderr b/src/test/ui/argument-suggestions/issue-98897.stderr
index 8f0d98d09..f2c47d353 100644
--- a/src/test/ui/argument-suggestions/issue-98897.stderr
+++ b/src/test/ui/argument-suggestions/issue-98897.stderr
@@ -12,7 +12,7 @@ LL | (|_, ()| ())([return, ()]);
help: provide the argument
|
LL | (|_, ()| ())([return, ()], ());
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/issue-99482.stderr b/src/test/ui/argument-suggestions/issue-99482.stderr
index bc005e82a..bcf36e37c 100644
--- a/src/test/ui/argument-suggestions/issue-99482.stderr
+++ b/src/test/ui/argument-suggestions/issue-99482.stderr
@@ -12,7 +12,7 @@ LL | let f = |_: (), f: fn()| f;
help: provide the argument
|
LL | let _f = f((), main);
- | ~~~~~~~~~~~
+ | ~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/argument-suggestions/missing_arguments.stderr b/src/test/ui/argument-suggestions/missing_arguments.stderr
index 2509d22d7..ba9ece040 100644
--- a/src/test/ui/argument-suggestions/missing_arguments.stderr
+++ b/src/test/ui/argument-suggestions/missing_arguments.stderr
@@ -12,7 +12,7 @@ LL | fn one_arg(_a: i32) {}
help: provide the argument
|
LL | one_arg(/* i32 */);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~
error[E0061]: this function takes 2 arguments but 0 arguments were supplied
--> $DIR/missing_arguments.rs:14:3
@@ -28,7 +28,7 @@ LL | fn two_same(_a: i32, _b: i32) {}
help: provide the arguments
|
LL | two_same(/* i32 */, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:15:3
@@ -44,7 +44,7 @@ LL | fn two_same(_a: i32, _b: i32) {}
help: provide the argument
|
LL | two_same(1, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~
error[E0061]: this function takes 2 arguments but 0 arguments were supplied
--> $DIR/missing_arguments.rs:16:3
@@ -60,7 +60,7 @@ LL | fn two_diff(_a: i32, _b: f32) {}
help: provide the arguments
|
LL | two_diff(/* i32 */, /* f32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:17:3
@@ -76,7 +76,7 @@ LL | fn two_diff(_a: i32, _b: f32) {}
help: provide the argument
|
LL | two_diff(1, /* f32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:18:3
@@ -92,7 +92,7 @@ LL | fn two_diff(_a: i32, _b: f32) {}
help: provide the argument
|
LL | two_diff(/* i32 */, 1.0);
- | ~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 0 arguments were supplied
--> $DIR/missing_arguments.rs:21:3
@@ -108,7 +108,7 @@ LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
help: provide the arguments
|
LL | three_same(/* i32 */, /* i32 */, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:22:3
@@ -124,7 +124,7 @@ LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
help: provide the arguments
|
LL | three_same(1, /* i32 */, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/missing_arguments.rs:23:3
@@ -140,7 +140,7 @@ LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
help: provide the argument
|
LL | three_same(1, 1, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/missing_arguments.rs:26:3
@@ -156,7 +156,7 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
help: provide the argument
|
LL | three_diff(/* i32 */, 1.0, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/missing_arguments.rs:27:3
@@ -172,7 +172,7 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
help: provide the argument
|
LL | three_diff(1, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/missing_arguments.rs:28:3
@@ -188,7 +188,7 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
help: provide the argument
|
LL | three_diff(1, 1.0, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:29:3
@@ -204,7 +204,7 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
help: provide the arguments
|
LL | three_diff(/* i32 */, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:30:3
@@ -223,7 +223,7 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
help: provide the arguments
|
LL | three_diff(/* i32 */, 1.0, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 1 argument was supplied
--> $DIR/missing_arguments.rs:31:3
@@ -239,7 +239,7 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
help: provide the arguments
|
LL | three_diff(1, /* f32 */, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 4 arguments but 0 arguments were supplied
--> $DIR/missing_arguments.rs:34:3
@@ -255,7 +255,7 @@ LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
help: provide the arguments
|
LL | four_repeated(/* i32 */, /* f32 */, /* f32 */, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 4 arguments but 2 arguments were supplied
--> $DIR/missing_arguments.rs:35:3
@@ -271,7 +271,7 @@ LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
help: provide the arguments
|
LL | four_repeated(1, /* f32 */, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 5 arguments but 0 arguments were supplied
--> $DIR/missing_arguments.rs:38:3
@@ -287,7 +287,7 @@ LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
help: provide the arguments
|
LL | complex(/* i32 */, /* f32 */, /* i32 */, /* f32 */, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 5 arguments but 2 arguments were supplied
--> $DIR/missing_arguments.rs:39:3
@@ -303,7 +303,7 @@ LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
help: provide the arguments
|
LL | complex(1, /* f32 */, /* i32 */, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 19 previous errors
diff --git a/src/test/ui/argument-suggestions/mixed_cases.stderr b/src/test/ui/argument-suggestions/mixed_cases.stderr
index a52a30d78..8c525db1a 100644
--- a/src/test/ui/argument-suggestions/mixed_cases.stderr
+++ b/src/test/ui/argument-suggestions/mixed_cases.stderr
@@ -14,7 +14,7 @@ LL | fn two_args(_a: i32, _b: f32) {}
help: remove the extra argument
|
LL | two_args(1, /* f32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 4 arguments were supplied
--> $DIR/mixed_cases.rs:11:3
@@ -33,7 +33,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: did you mean
|
LL | three_args(1, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/mixed_cases.rs:14:3
@@ -52,7 +52,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: provide the argument
|
LL | three_args(1, /* f32 */, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/mixed_cases.rs:17:3
@@ -70,7 +70,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: did you mean
|
LL | three_args(1, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/mixed_cases.rs:20:3
@@ -89,7 +89,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: swap these arguments
|
LL | three_args(1, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/mixed_cases.rs:23:3
@@ -109,7 +109,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: did you mean
|
LL | three_args(1, /* f32 */, "");
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error: aborting due to 6 previous errors
diff --git a/src/test/ui/argument-suggestions/permuted_arguments.stderr b/src/test/ui/argument-suggestions/permuted_arguments.stderr
index f16d22860..655807a7f 100644
--- a/src/test/ui/argument-suggestions/permuted_arguments.stderr
+++ b/src/test/ui/argument-suggestions/permuted_arguments.stderr
@@ -15,7 +15,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: reorder these arguments
|
LL | three_args(1, 1.0, "");
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/permuted_arguments.rs:12:3
@@ -36,7 +36,7 @@ LL | fn many_args(_a: i32, _b: f32, _c: &str, _d: X, _e: Y) {}
help: reorder these arguments
|
LL | many_args(1, 1.0, "", X {}, Y {});
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/argument-suggestions/swapped_arguments.stderr b/src/test/ui/argument-suggestions/swapped_arguments.stderr
index a90792d0c..dabf5e952 100644
--- a/src/test/ui/argument-suggestions/swapped_arguments.stderr
+++ b/src/test/ui/argument-suggestions/swapped_arguments.stderr
@@ -14,7 +14,7 @@ LL | fn two_args(_a: i32, _b: f32) {}
help: swap these arguments
|
LL | two_args(1, 1.0);
- | ~~~~~~~~~~~~~~~~
+ | ~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/swapped_arguments.rs:9:3
@@ -32,7 +32,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: swap these arguments
|
LL | three_args(1, 1.0, "");
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/swapped_arguments.rs:10:3
@@ -50,7 +50,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: swap these arguments
|
LL | three_args(1, 1.0, "");
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/swapped_arguments.rs:11:3
@@ -68,7 +68,7 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
help: swap these arguments
|
LL | three_args(1, 1.0, "");
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~
error[E0308]: arguments to this function are incorrect
--> $DIR/swapped_arguments.rs:13:3
@@ -88,7 +88,7 @@ LL | fn four_args(_a: i32, _b: f32, _c: &str, _d: X) {}
help: did you mean
|
LL | four_args(1, 1.0, "", X {});
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~
error: aborting due to 5 previous errors
diff --git a/src/test/ui/argument-suggestions/too-long.rs b/src/test/ui/argument-suggestions/too-long.rs
new file mode 100644
index 000000000..7ec56afae
--- /dev/null
+++ b/src/test/ui/argument-suggestions/too-long.rs
@@ -0,0 +1,41 @@
+struct Qux;
+
+impl Qux {
+ fn foo(
+ &self,
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+ e: i32,
+ f: i32,
+ g: i32,
+ h: i32,
+ i: i32,
+ j: i32,
+ k: i32,
+ l: i32,
+ ) {
+ }
+}
+
+fn what(
+ qux: &Qux,
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+ e: i32,
+ f: &i32,
+ g: i32,
+ h: i32,
+ i: i32,
+ j: i32,
+ k: i32,
+ l: i32,
+) {
+ qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/argument-suggestions/too-long.stderr b/src/test/ui/argument-suggestions/too-long.stderr
new file mode 100644
index 000000000..bd430194c
--- /dev/null
+++ b/src/test/ui/argument-suggestions/too-long.stderr
@@ -0,0 +1,24 @@
+error[E0308]: mismatched types
+ --> $DIR/too-long.rs:37:28
+ |
+LL | qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
+ | --- ^ expected `i32`, found `&i32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: associated function defined here
+ --> $DIR/too-long.rs:4:8
+ |
+LL | fn foo(
+ | ^^^
+...
+LL | f: i32,
+ | ------
+help: consider dereferencing the borrow
+ |
+LL | qux.foo(a, b, c, d, e, *f, g, h, i, j, k, l);
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.rs b/src/test/ui/argument-suggestions/two-mismatch-notes.rs
new file mode 100644
index 000000000..1309041ab
--- /dev/null
+++ b/src/test/ui/argument-suggestions/two-mismatch-notes.rs
@@ -0,0 +1,11 @@
+#[derive(Copy, Clone)]
+struct Wrapper<T>(T);
+
+fn foo(_: fn(i32), _: Wrapper<i32>) {}
+
+fn f(_: u32) {}
+
+fn main() {
+ let w = Wrapper::<isize>(1isize);
+ foo(f, w); //~ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr
new file mode 100644
index 000000000..7873cf964
--- /dev/null
+++ b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr
@@ -0,0 +1,29 @@
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/two-mismatch-notes.rs:10:5
+ |
+LL | foo(f, w);
+ | ^^^
+ |
+note: expected `i32`, found `u32`
+ --> $DIR/two-mismatch-notes.rs:10:9
+ |
+LL | foo(f, w);
+ | ^
+ = note: expected fn pointer `fn(i32)`
+ found fn item `fn(u32) {f}`
+note: expected `i32`, found `isize`
+ --> $DIR/two-mismatch-notes.rs:10:12
+ |
+LL | foo(f, w);
+ | ^
+ = note: expected struct `Wrapper<i32>`
+ found struct `Wrapper<isize>`
+note: function defined here
+ --> $DIR/two-mismatch-notes.rs:4:4
+ |
+LL | fn foo(_: fn(i32), _: Wrapper<i32>) {}
+ | ^^^ ---------- ---------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/suggest-array-length.fixed b/src/test/ui/array-slice-vec/suggest-array-length.fixed
new file mode 100644
index 000000000..867c18a7d
--- /dev/null
+++ b/src/test/ui/array-slice-vec/suggest-array-length.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+#![allow(unused_variables, dead_code, non_upper_case_globals)]
+
+fn main() {
+ const Foo: [i32; 3] = [1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ const REF_FOO: &[u8; 1] = &[1];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let foo: [i32; 3] = [1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let bar: [i32; 3] = [0; 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let ref_foo: &[i32; 3] = &[1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let ref_bar: &[i32; 3] = &[0; 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let multiple_ref_foo: &&[i32; 3] = &&[1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+}
diff --git a/src/test/ui/array-slice-vec/suggest-array-length.rs b/src/test/ui/array-slice-vec/suggest-array-length.rs
new file mode 100644
index 000000000..f66b3d4a8
--- /dev/null
+++ b/src/test/ui/array-slice-vec/suggest-array-length.rs
@@ -0,0 +1,26 @@
+// run-rustfix
+#![allow(unused_variables, dead_code, non_upper_case_globals)]
+
+fn main() {
+ const Foo: [i32; _] = [1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ const REF_FOO: &[u8; _] = &[1];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let foo: [i32; _] = [1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let bar: [i32; _] = [0; 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let ref_foo: &[i32; _] = &[1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let ref_bar: &[i32; _] = &[0; 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+ let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
+ //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
+ //~| ERROR using `_` for array lengths is unstable
+}
diff --git a/src/test/ui/array-slice-vec/suggest-array-length.stderr b/src/test/ui/array-slice-vec/suggest-array-length.stderr
new file mode 100644
index 000000000..16c90a047
--- /dev/null
+++ b/src/test/ui/array-slice-vec/suggest-array-length.stderr
@@ -0,0 +1,108 @@
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:11:20
+ |
+LL | let foo: [i32; _] = [1, 2, 3];
+ | ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:14:20
+ |
+LL | let bar: [i32; _] = [0; 3];
+ | ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:17:25
+ |
+LL | let ref_foo: &[i32; _] = &[1, 2, 3];
+ | ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:20:25
+ |
+LL | let ref_bar: &[i32; _] = &[0; 3];
+ | ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:23:35
+ |
+LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
+ | ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:5:22
+ |
+LL | const Foo: [i32; _] = [1, 2, 3];
+ | ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/suggest-array-length.rs:8:26
+ |
+LL | const REF_FOO: &[u8; _] = &[1];
+ | ^ `_` not allowed here
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:5:22
+ |
+LL | const Foo: [i32; _] = [1, 2, 3];
+ | ^ help: consider specifying the array length: `3`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:8:26
+ |
+LL | const REF_FOO: &[u8; _] = &[1];
+ | ^ help: consider specifying the array length: `1`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:11:20
+ |
+LL | let foo: [i32; _] = [1, 2, 3];
+ | ^ help: consider specifying the array length: `3`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:14:20
+ |
+LL | let bar: [i32; _] = [0; 3];
+ | ^ help: consider specifying the array length: `3`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:17:25
+ |
+LL | let ref_foo: &[i32; _] = &[1, 2, 3];
+ | ^ help: consider specifying the array length: `3`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:20:25
+ |
+LL | let ref_bar: &[i32; _] = &[0; 3];
+ | ^ help: consider specifying the array length: `3`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/suggest-array-length.rs:23:35
+ |
+LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
+ | ^ help: consider specifying the array length: `3`
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/asm/aarch64/may_unwind.rs b/src/test/ui/asm/aarch64/may_unwind.rs
index ac8cc6202..dfd891b42 100644
--- a/src/test/ui/asm/aarch64/may_unwind.rs
+++ b/src/test/ui/asm/aarch64/may_unwind.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0.0
// only-aarch64
// run-pass
// needs-asm-support
diff --git a/src/test/ui/asm/aarch64/type-check-3.stderr b/src/test/ui/asm/aarch64/type-check-3.stderr
index b320abdc0..49292982e 100644
--- a/src/test/ui/asm/aarch64/type-check-3.stderr
+++ b/src/test/ui/asm/aarch64/type-check-3.stderr
@@ -5,8 +5,8 @@ LL | asm!("{}", in(reg) 0u8);
| ^^ --- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:50:15
@@ -14,8 +14,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(reg) 0u16);
| ^^ ---- for this argument
|
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:52:15
@@ -23,8 +23,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(reg) 0i32);
| ^^ ---- for this argument
|
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:54:15
@@ -32,8 +32,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(reg) 0f32);
| ^^ ---- for this argument
|
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:57:15
@@ -41,8 +41,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(vreg) 0i16);
| ^^ ---- for this argument
|
- = help: use the `h` modifier to have the register formatted as `h0`
- = help: or use the `v` modifier to keep the default formatting of `v0`
+ = help: use `{0:h}` to have the register formatted as `h0`
+ = help: or use `{0:v}` to keep the default formatting of `v0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:59:15
@@ -50,8 +50,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(vreg) 0f32);
| ^^ ---- for this argument
|
- = help: use the `s` modifier to have the register formatted as `s0`
- = help: or use the `v` modifier to keep the default formatting of `v0`
+ = help: use `{0:s}` to have the register formatted as `s0`
+ = help: or use `{0:v}` to keep the default formatting of `v0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:61:15
@@ -59,8 +59,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(vreg) 0f64);
| ^^ ---- for this argument
|
- = help: use the `d` modifier to have the register formatted as `d0`
- = help: or use the `v` modifier to keep the default formatting of `v0`
+ = help: use `{0:d}` to have the register formatted as `d0`
+ = help: or use `{0:v}` to keep the default formatting of `v0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:63:15
@@ -68,8 +68,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(vreg_low16) 0f64);
| ^^ ---- for this argument
|
- = help: use the `d` modifier to have the register formatted as `d0`
- = help: or use the `v` modifier to keep the default formatting of `v0`
+ = help: use `{0:d}` to have the register formatted as `d0`
+ = help: or use `{0:v}` to keep the default formatting of `v0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:66:15
@@ -77,8 +77,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{0} {0}", in(reg) 0i16);
| ^^^ ^^^ ---- for this argument
|
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:68:15
@@ -86,8 +86,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{0} {0:x}", in(reg) 0i16);
| ^^^ ---- for this argument
|
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
error: type `i128` cannot be used with this register class
--> $DIR/type-check-3.rs:73:28
diff --git a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
index 7ef93e15f..5dac693cc 100644
--- a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
@@ -190,8 +190,8 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^^^^ --- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
error: aborting due to 21 previous errors; 1 warning emitted
diff --git a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
index 7ef93e15f..5dac693cc 100644
--- a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
@@ -190,8 +190,8 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^^^^ --- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
- = help: use the `w` modifier to have the register formatted as `w0`
- = help: or use the `x` modifier to keep the default formatting of `x0`
+ = help: use `{0:w}` to have the register formatted as `w0`
+ = help: or use `{0:x}` to keep the default formatting of `x0`
error: aborting due to 21 previous errors; 1 warning emitted
diff --git a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
index 250bc3be4..b29b74bac 100644
--- a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
@@ -190,8 +190,8 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^^^^ --- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
- = help: use the `e` modifier to have the register formatted as `eax`
- = help: or use the `r` modifier to keep the default formatting of `rax`
+ = help: use `{0:e}` to have the register formatted as `eax`
+ = help: or use `{0:r}` to keep the default formatting of `rax`
error: aborting due to 21 previous errors; 1 warning emitted
diff --git a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
index 250bc3be4..b29b74bac 100644
--- a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
@@ -190,8 +190,8 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^^^^ --- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
- = help: use the `e` modifier to have the register formatted as `eax`
- = help: or use the `r` modifier to keep the default formatting of `rax`
+ = help: use `{0:e}` to have the register formatted as `eax`
+ = help: or use `{0:r}` to keep the default formatting of `rax`
error: aborting due to 21 previous errors; 1 warning emitted
diff --git a/src/test/ui/asm/may_unwind.rs b/src/test/ui/asm/may_unwind.rs
index 117c0a63a..b9479c44b 100644
--- a/src/test/ui/asm/may_unwind.rs
+++ b/src/test/ui/asm/may_unwind.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0.0
// run-pass
// needs-asm-support
diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr
index 1828066b6..f90967fbe 100644
--- a/src/test/ui/asm/naked-functions.stderr
+++ b/src/test/ui/asm/naked-functions.stderr
@@ -57,13 +57,11 @@ LL | a + 1
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:33:1
|
-LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 {
-LL | |
-LL | | a + 1
- | | ----- non-asm is unsupported in naked functions
-LL | |
-LL | | }
- | |_^
+LL | pub unsafe extern "C" fn inc(a: u32) -> u32 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | a + 1
+ | ----- non-asm is unsupported in naked functions
error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:42:31
@@ -82,12 +80,11 @@ LL | asm!("/* {0} */", in(reg) a, options(noreturn));
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:48:1
|
-LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
-LL | |
-LL | | (|| a + 1)()
- | | ------------ non-asm is unsupported in naked functions
-LL | | }
- | |_^
+LL | pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | (|| a + 1)()
+ | ------------ non-asm is unsupported in naked functions
error[E0787]: only `const` and `sym` operands are supported in naked functions
--> $DIR/naked-functions.rs:65:10
@@ -124,30 +121,25 @@ LL | sym G, options(noreturn),
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:54:1
|
-LL | / pub unsafe extern "C" fn unsupported_operands() {
-LL | |
-LL | | let mut a = 0usize;
- | | ------------------- non-asm is unsupported in naked functions
-LL | | let mut b = 0usize;
- | | ------------------- non-asm is unsupported in naked functions
-LL | | let mut c = 0usize;
- | | ------------------- non-asm is unsupported in naked functions
-LL | | let mut d = 0usize;
- | | ------------------- non-asm is unsupported in naked functions
-LL | | let mut e = 0usize;
- | | ------------------- non-asm is unsupported in naked functions
-... |
-LL | | );
-LL | | }
- | |_^
+LL | pub unsafe extern "C" fn unsupported_operands() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | let mut a = 0usize;
+ | ------------------- non-asm is unsupported in naked functions
+LL | let mut b = 0usize;
+ | ------------------- non-asm is unsupported in naked functions
+LL | let mut c = 0usize;
+ | ------------------- non-asm is unsupported in naked functions
+LL | let mut d = 0usize;
+ | ------------------- non-asm is unsupported in naked functions
+LL | let mut e = 0usize;
+ | ------------------- non-asm is unsupported in naked functions
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:77:1
|
-LL | / pub extern "C" fn missing_assembly() {
-LL | |
-LL | | }
- | |_^
+LL | pub extern "C" fn missing_assembly() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:84:5
@@ -185,20 +177,17 @@ LL | asm!("", options(noreturn));
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:82:1
|
-LL | / pub extern "C" fn too_many_asm_blocks() {
-LL | |
-LL | | asm!("");
-LL | |
-LL | | asm!("");
- | | -------- multiple asm blocks are unsupported in naked functions
-LL | |
-LL | | asm!("");
- | | -------- multiple asm blocks are unsupported in naked functions
-LL | |
-LL | | asm!("", options(noreturn));
- | | --------------------------- multiple asm blocks are unsupported in naked functions
-LL | | }
- | |_^
+LL | pub extern "C" fn too_many_asm_blocks() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | asm!("");
+ | -------- multiple asm blocks are unsupported in naked functions
+LL |
+LL | asm!("");
+ | -------- multiple asm blocks are unsupported in naked functions
+LL |
+LL | asm!("", options(noreturn));
+ | --------------------------- multiple asm blocks are unsupported in naked functions
error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:97:11
@@ -211,13 +200,11 @@ LL | *&y
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:95:5
|
-LL | / pub extern "C" fn inner(y: usize) -> usize {
-LL | |
-LL | | *&y
- | | --- non-asm is unsupported in naked functions
-LL | |
-LL | | }
- | |_____^
+LL | pub extern "C" fn inner(y: usize) -> usize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | *&y
+ | --- non-asm is unsupported in naked functions
error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags`
--> $DIR/naked-functions.rs:105:5
@@ -249,18 +236,18 @@ LL | asm!("", options(noreturn, may_unwind));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: Rust ABI is unsupported in naked functions
- --> $DIR/naked-functions.rs:124:15
+ --> $DIR/naked-functions.rs:124:1
|
LL | pub unsafe fn default_abi() {
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(undefined_naked_function_abi)]` on by default
warning: Rust ABI is unsupported in naked functions
- --> $DIR/naked-functions.rs:130:15
+ --> $DIR/naked-functions.rs:130:1
|
LL | pub unsafe fn rust_abi() {
- | ^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:170:1
diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr
index 162ff1d32..184513965 100644
--- a/src/test/ui/asm/type-check-1.stderr
+++ b/src/test/ui/asm/type-check-1.stderr
@@ -106,7 +106,7 @@ error[E0308]: mismatched types
--> $DIR/type-check-1.rs:60:26
|
LL | asm!("{}", const 0 as *mut u8);
- | ^^^^^^^^^^^^ expected integer, found *-ptr
+ | ^^^^^^^^^^^^ expected integer, found `*mut u8`
|
= note: expected type `{integer}`
found raw pointer `*mut u8`
@@ -133,7 +133,7 @@ error[E0308]: mismatched types
--> $DIR/type-check-1.rs:78:25
|
LL | global_asm!("{}", const 0 as *mut u8);
- | ^^^^^^^^^^^^ expected integer, found *-ptr
+ | ^^^^^^^^^^^^ expected integer, found `*mut u8`
|
= note: expected type `{integer}`
found raw pointer `*mut u8`
diff --git a/src/test/ui/asm/unpretty-expanded.rs b/src/test/ui/asm/unpretty-expanded.rs
new file mode 100644
index 000000000..6128f49b8
--- /dev/null
+++ b/src/test/ui/asm/unpretty-expanded.rs
@@ -0,0 +1,3 @@
+// check-pass
+// compile-flags: -Zunpretty=expanded
+core::arch::global_asm!("x: .byte 42");
diff --git a/src/test/ui/asm/unpretty-expanded.stdout b/src/test/ui/asm/unpretty-expanded.stdout
new file mode 100644
index 000000000..15b60d155
--- /dev/null
+++ b/src/test/ui/asm/unpretty-expanded.stdout
@@ -0,0 +1,9 @@
+#![feature(prelude_import)]
+#![no_std]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+// check-pass
+// compile-flags: -Zunpretty=expanded
+global_asm! ("x: .byte 42");
diff --git a/src/test/ui/asm/x86_64/may_unwind.rs b/src/test/ui/asm/x86_64/may_unwind.rs
index 9844d63f0..2f5d1a360 100644
--- a/src/test/ui/asm/x86_64/may_unwind.rs
+++ b/src/test/ui/asm/x86_64/may_unwind.rs
@@ -1,7 +1,7 @@
-// min-llvm-version: 13.0.0
// only-x86_64
// run-pass
// needs-asm-support
+// needs-unwind
#![feature(asm_sym, asm_unwind)]
diff --git a/src/test/ui/asm/x86_64/sym.rs b/src/test/ui/asm/x86_64/sym.rs
index 622365bc7..447e11e6e 100644
--- a/src/test/ui/asm/x86_64/sym.rs
+++ b/src/test/ui/asm/x86_64/sym.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 12.0.1
// only-x86_64
// only-linux
// needs-asm-support
diff --git a/src/test/ui/asm/x86_64/type-check-3.stderr b/src/test/ui/asm/x86_64/type-check-3.stderr
index b38ea8cc4..366038fea 100644
--- a/src/test/ui/asm/x86_64/type-check-3.stderr
+++ b/src/test/ui/asm/x86_64/type-check-3.stderr
@@ -45,8 +45,8 @@ LL | asm!("{0} {0}", in(reg) 0i16);
| ^^^ ^^^ ---- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
- = help: use the `x` modifier to have the register formatted as `ax`
- = help: or use the `r` modifier to keep the default formatting of `rax`
+ = help: use `{0:x}` to have the register formatted as `ax`
+ = help: or use `{0:r}` to keep the default formatting of `rax`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:36:15
@@ -54,8 +54,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{0} {0:x}", in(reg) 0i16);
| ^^^ ---- for this argument
|
- = help: use the `x` modifier to have the register formatted as `ax`
- = help: or use the `r` modifier to keep the default formatting of `rax`
+ = help: use `{0:x}` to have the register formatted as `ax`
+ = help: or use `{0:r}` to keep the default formatting of `rax`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:38:15
@@ -63,8 +63,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(reg) 0i32);
| ^^ ---- for this argument
|
- = help: use the `e` modifier to have the register formatted as `eax`
- = help: or use the `r` modifier to keep the default formatting of `rax`
+ = help: use `{0:e}` to have the register formatted as `eax`
+ = help: or use `{0:r}` to keep the default formatting of `rax`
warning: formatting may not be suitable for sub-register argument
--> $DIR/type-check-3.rs:41:15
@@ -72,8 +72,8 @@ warning: formatting may not be suitable for sub-register argument
LL | asm!("{}", in(ymm_reg) 0i64);
| ^^ ---- for this argument
|
- = help: use the `x` modifier to have the register formatted as `xmm0`
- = help: or use the `y` modifier to keep the default formatting of `ymm0`
+ = help: use `{0:x}` to have the register formatted as `xmm0`
+ = help: or use `{0:y}` to keep the default formatting of `ymm0`
error: type `i8` cannot be used with this register class
--> $DIR/type-check-3.rs:52:28
diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr
index 582473905..c4cd9c2a4 100644
--- a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr
+++ b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr
@@ -2,13 +2,13 @@ error[E0391]: cycle detected when const-evaluating + checking `Tr::A`
--> $DIR/defaults-cyclic-fail.rs:5:5
|
LL | const A: u8 = Self::B;
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `Tr::B`...
--> $DIR/defaults-cyclic-fail.rs:8:5
|
LL | const B: u8 = Self::A;
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle
note: cycle used when const-evaluating + checking `main::promoted[1]`
--> $DIR/defaults-cyclic-fail.rs:16:16
diff --git a/src/test/ui/associated-consts/issue-102335-const.rs b/src/test/ui/associated-consts/issue-102335-const.rs
new file mode 100644
index 000000000..f60cb92da
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-102335-const.rs
@@ -0,0 +1,12 @@
+#![feature(associated_const_equality)]
+
+trait T {
+ type A: S<C<X = 0i32> = 34>;
+ //~^ ERROR associated type bindings are not allowed here
+}
+
+trait S {
+ const C: i32;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-consts/issue-102335-const.stderr b/src/test/ui/associated-consts/issue-102335-const.stderr
new file mode 100644
index 000000000..531d15c59
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-102335-const.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-102335-const.rs:4:17
+ |
+LL | type A: S<C<X = 0i32> = 34>;
+ | ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
index 51a50cfda..c8c57bccb 100644
--- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
+++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
@@ -13,7 +13,7 @@ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
|
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
index b9d1808fe..76ed8d4a6 100644
--- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
+++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
@@ -13,7 +13,7 @@ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
|
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
index 271e69206..6a98f08f3 100644
--- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
+++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
@@ -13,7 +13,7 @@ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
|
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
diff --git a/src/test/ui/associated-type-bounds/binder-on-bound.rs b/src/test/ui/associated-type-bounds/binder-on-bound.rs
index 0b4b24b98..6cba45129 100644
--- a/src/test/ui/associated-type-bounds/binder-on-bound.rs
+++ b/src/test/ui/associated-type-bounds/binder-on-bound.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Trait {
type Bound<'a>;
}
diff --git a/src/test/ui/associated-type-bounds/binder-on-bound.stderr b/src/test/ui/associated-type-bounds/binder-on-bound.stderr
index 3432672e0..f71f72bfb 100644
--- a/src/test/ui/associated-type-bounds/binder-on-bound.stderr
+++ b/src/test/ui/associated-type-bounds/binder-on-bound.stderr
@@ -1,5 +1,5 @@
error: `for<...>` is not allowed on associated type bounds
- --> $DIR/binder-on-bound.rs:7:22
+ --> $DIR/binder-on-bound.rs:5:22
|
LL | fn foo() where Trait<for<'a> Bound<'a> = &'a ()> {
| ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/associated-type-bounds/elision.rs b/src/test/ui/associated-type-bounds/elision.rs
index 4a5339399..d00def571 100644
--- a/src/test/ui/associated-type-bounds/elision.rs
+++ b/src/test/ui/associated-type-bounds/elision.rs
@@ -1,7 +1,7 @@
#![feature(associated_type_bounds)]
#![feature(anonymous_lifetime_in_impl_trait)]
-// The same thing should happen for constaints in dyn trait.
+// The same thing should happen for constraints in dyn trait.
fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
//~^ ERROR missing lifetime specifier
//~| ERROR mismatched types
diff --git a/src/test/ui/associated-type-bounds/issue-102335-ty.rs b/src/test/ui/associated-type-bounds/issue-102335-ty.rs
new file mode 100644
index 000000000..363df73c1
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/issue-102335-ty.rs
@@ -0,0 +1,12 @@
+trait T {
+ type A: S<C<i32 = u32> = ()>;
+ //~^ ERROR associated type bindings are not allowed here
+}
+
+trait Q {}
+
+trait S {
+ type C: Q;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-type-bounds/issue-102335-ty.stderr b/src/test/ui/associated-type-bounds/issue-102335-ty.stderr
new file mode 100644
index 000000000..8777b2965
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/issue-102335-ty.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-102335-ty.rs:2:17
+ |
+LL | type A: S<C<i32 = u32> = ()>;
+ | ^^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/associated-type-bounds/issue-79949.rs b/src/test/ui/associated-type-bounds/issue-79949.rs
index 9f924f1fd..9dd37f981 100644
--- a/src/test/ui/associated-type-bounds/issue-79949.rs
+++ b/src/test/ui/associated-type-bounds/issue-79949.rs
@@ -2,7 +2,6 @@
#![allow(incomplete_features)]
#![feature(associated_type_bounds)]
-#![feature(generic_associated_types)]
trait MP {
type T<'a>;
diff --git a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
index b904ad102..e761c6c62 100644
--- a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
@@ -10,7 +10,7 @@ note: function defined here
--> $DIR/associated-type-projection-from-supertrait.rs:25:4
|
LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
- | ^^^^ ---- ---------------
+ | ^^^^ ---------------
error[E0308]: mismatched types
--> $DIR/associated-type-projection-from-supertrait.rs:28:23
@@ -24,7 +24,7 @@ note: function defined here
--> $DIR/associated-type-projection-from-supertrait.rs:25:4
|
LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
- | ^^^^ ---- ---------------
+ | ^^^^ ---------------
error[E0308]: mismatched types
--> $DIR/associated-type-projection-from-supertrait.rs:32:28
@@ -38,7 +38,7 @@ note: associated function defined here
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
|
LL | fn chip_paint(&self, c: Self::Color) { }
- | ^^^^^^^^^^ ----- --------------
+ | ^^^^^^^^^^ --------------
error[E0308]: mismatched types
--> $DIR/associated-type-projection-from-supertrait.rs:33:28
@@ -52,7 +52,7 @@ note: associated function defined here
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
|
LL | fn chip_paint(&self, c: Self::Color) { }
- | ^^^^^^^^^^ ----- --------------
+ | ^^^^^^^^^^ --------------
error: aborting due to 4 previous errors
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
index 0cccc6b38..a777e064f 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
@@ -1,8 +1,10 @@
error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:19
|
LL | fn b() { blue_car(ModelT); }
- | ^^^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+ | -------- ^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Blue`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40
@@ -16,10 +18,12 @@ LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
| ^^^^^^^^^^ required by this bound in `blue_car`
error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:20
|
LL | fn c() { black_car(ModelU); }
- | ^^^^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+ | --------- ^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Black`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index bed63a5e6..fbe1a1ee8 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -14,10 +14,12 @@ LL | fn foo2<I: Foo<A = Bar>>(x: I) {
| +++++++++
error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
- --> $DIR/associated-types-eq-3.rs:38:5
+ --> $DIR/associated-types-eq-3.rs:38:10
|
LL | foo1(a);
- | ^^^^ type mismatch resolving `<isize as Foo>::A == Bar`
+ | ---- ^ type mismatch resolving `<isize as Foo>::A == Bar`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Bar`
--> $DIR/associated-types-eq-3.rs:12:14
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr
index b306ae273..6cff403b3 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -1,8 +1,8 @@
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
- --> $DIR/associated-types-eq-hr.rs:87:5
+ --> $DIR/associated-types-eq-hr.rs:87:11
|
LL | foo::<UintStruct>();
- | ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
+ | ^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
|
note: expected this to be `&isize`
--> $DIR/associated-types-eq-hr.rs:26:14
@@ -21,10 +21,10 @@ LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
| ^^^^^^^^^^^^^ required by this bound in `foo`
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
- --> $DIR/associated-types-eq-hr.rs:91:5
+ --> $DIR/associated-types-eq-hr.rs:91:11
|
LL | bar::<IntStruct>();
- | ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
+ | ^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
|
note: expected this to be `&usize`
--> $DIR/associated-types-eq-hr.rs:14:14
diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
index 6552c8be7..389cc7bed 100644
--- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-for-unimpl-trait.rs:10:40
+ --> $DIR/associated-types-for-unimpl-trait.rs:10:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
- | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
index a67cf9928..b1708b96e 100644
--- a/src/test/ui/associated-types/associated-types-issue-20346.stderr
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -1,11 +1,13 @@
error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
- --> $DIR/associated-types-issue-20346.rs:34:5
+ --> $DIR/associated-types-issue-20346.rs:34:36
|
LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
| - this type parameter
...
LL | is_iterator_of::<Option<T>, _>(&adapter);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+ | ------------------------------ ^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Option<T>`
--> $DIR/associated-types-issue-20346.rs:23:17
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
index 922cf88a0..89cdba524 100644
--- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
@@ -1,8 +1,10 @@
error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
- --> $DIR/associated-types-multiple-types-one-trait.rs:13:5
+ --> $DIR/associated-types-multiple-types-one-trait.rs:13:12
|
LL | want_y(t);
- | ^^^^^^ expected `i32`, found associated type
+ | ------ ^ expected `i32`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected type `i32`
found associated type `<T as Foo>::Y`
@@ -17,10 +19,12 @@ LL | fn have_x_want_y<T:Foo<X=u32, Y = i32>>(t: &T)
| +++++++++
error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
- --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
+ --> $DIR/associated-types-multiple-types-one-trait.rs:18:12
|
LL | want_x(t);
- | ^^^^^^ expected `u32`, found associated type
+ | ------ ^ expected `u32`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected type `u32`
found associated type `<T as Foo>::X`
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
index b2ee1b5e6..1feaa612e 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-bound.rs:11:21
+ --> $DIR/associated-types-no-suitable-bound.rs:11:5
|
LL | fn uhoh<T>(foo: <T as Get>::Value) {}
- | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
index 2e40dbd06..cc3ed5561 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
+ --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
- | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
index bd3ee2abd..18f2830d8 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -1,14 +1,14 @@
error[E0277]: the trait bound `(T, U): Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
+ --> $DIR/associated-types-no-suitable-supertrait.rs:22:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
- | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
+ --> $DIR/associated-types-no-suitable-supertrait.rs:17:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
- | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
index 109feb8e9..26b9f4b3a 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
@@ -4,5 +4,5 @@ trait I32Iterator = Iterator<Item = i32>;
fn main() {
let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
- //~^ ERROR type mismatch
+ //~^ ERROR expected `std::vec::IntoIter<u32>` to be an iterator that yields `i32`, but it yields `u32`
}
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
index dbd9a44ed..2d25f68de 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == i32`
+error[E0271]: expected `std::vec::IntoIter<u32>` to be an iterator that yields `i32`, but it yields `u32`
--> $DIR/associated-types-overridden-binding-2.rs:6:43
|
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
diff --git a/src/test/ui/associated-types/associated-types-path-2.rs b/src/test/ui/associated-types/associated-types-path-2.rs
index c993e1d27..00066efcc 100644
--- a/src/test/ui/associated-types/associated-types-path-2.rs
+++ b/src/test/ui/associated-types/associated-types-path-2.rs
@@ -29,12 +29,14 @@ pub fn f1_uint_uint() {
f1(2u32, 4u32);
//~^ ERROR `u32: Foo` is not satisfied
//~| ERROR `u32: Foo` is not satisfied
+ //~| ERROR `u32: Foo` is not satisfied
}
pub fn f1_uint_int() {
f1(2u32, 4i32);
//~^ ERROR `u32: Foo` is not satisfied
//~| ERROR `u32: Foo` is not satisfied
+ //~| ERROR `u32: Foo` is not satisfied
}
pub fn f2_int() {
diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr
index 1d0b84d31..206f49024 100644
--- a/src/test/ui/associated-types/associated-types-path-2.stderr
+++ b/src/test/ui/associated-types/associated-types-path-2.stderr
@@ -10,17 +10,19 @@ note: function defined here
--> $DIR/associated-types-path-2.rs:13:8
|
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
- | ^^ ---- -------
+ | ^^ -------
help: change the type of the numeric literal from `i32` to `u32`
|
LL | f1(2i32, 4u32);
| ~~~
error[E0277]: the trait bound `u32: Foo` is not satisfied
- --> $DIR/associated-types-path-2.rs:29:5
+ --> $DIR/associated-types-path-2.rs:29:8
|
LL | f1(2u32, 4u32);
- | ^^ the trait `Foo` is not implemented for `u32`
+ | -- ^^^^ the trait `Foo` is not implemented for `u32`
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `f1`
@@ -30,6 +32,14 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
| ^^^ required by this bound in `f1`
error[E0277]: the trait bound `u32: Foo` is not satisfied
+ --> $DIR/associated-types-path-2.rs:29:5
+ |
+LL | f1(2u32, 4u32);
+ | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
+ |
+ = help: the trait `Foo` is implemented for `i32`
+
+error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:14
|
LL | f1(2u32, 4u32);
@@ -38,7 +48,7 @@ LL | f1(2u32, 4u32);
= help: the trait `Foo` is implemented for `i32`
error[E0277]: the trait bound `u32: Foo` is not satisfied
- --> $DIR/associated-types-path-2.rs:35:8
+ --> $DIR/associated-types-path-2.rs:36:8
|
LL | f1(2u32, 4i32);
| -- ^^^^ the trait `Foo` is not implemented for `u32`
@@ -53,7 +63,15 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
| ^^^ required by this bound in `f1`
error[E0277]: the trait bound `u32: Foo` is not satisfied
- --> $DIR/associated-types-path-2.rs:35:14
+ --> $DIR/associated-types-path-2.rs:36:5
+ |
+LL | f1(2u32, 4i32);
+ | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
+ |
+ = help: the trait `Foo` is implemented for `i32`
+
+error[E0277]: the trait bound `u32: Foo` is not satisfied
+ --> $DIR/associated-types-path-2.rs:36:14
|
LL | f1(2u32, 4i32);
| ^^^^ the trait `Foo` is not implemented for `u32`
@@ -61,7 +79,7 @@ LL | f1(2u32, 4i32);
= help: the trait `Foo` is implemented for `i32`
error[E0308]: mismatched types
- --> $DIR/associated-types-path-2.rs:41:18
+ --> $DIR/associated-types-path-2.rs:43:18
|
LL | let _: i32 = f2(2i32);
| --- ^^^^^^^^ expected `i32`, found `u32`
@@ -73,7 +91,7 @@ help: you can convert a `u32` to an `i32` and panic if the converted value doesn
LL | let _: i32 = f2(2i32).try_into().unwrap();
| ++++++++++++++++++++
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
index 2e67c2194..66d59bccd 100644
--- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
+ --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5
|
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
- | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/associated-types/defaults-suitability.stderr b/src/test/ui/associated-types/defaults-suitability.stderr
index 43541c5df..eadad4cd5 100644
--- a/src/test/ui/associated-types/defaults-suitability.stderr
+++ b/src/test/ui/associated-types/defaults-suitability.stderr
@@ -39,7 +39,7 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
LL | type Bar: Clone = Vec<T>;
| ^^^^^^ the trait `Clone` is not implemented for `T`
|
- = note: required because of the requirements on the impl of `Clone` for `Vec<T>`
+ = note: required for `Vec<T>` to implement `Clone`
note: required by a bound in `Foo::Bar`
--> $DIR/defaults-suitability.rs:28:15
|
@@ -83,7 +83,7 @@ error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`
|
- = note: required because of the requirements on the impl of `Clone` for `Vec<<Self as Foo2<T>>::Baz>`
+ = note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo2::Bar`
--> $DIR/defaults-suitability.rs:65:15
|
@@ -100,7 +100,7 @@ error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`
|
- = note: required because of the requirements on the impl of `Clone` for `Vec<<Self as Foo25<T>>::Baz>`
+ = note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo25::Bar`
--> $DIR/defaults-suitability.rs:74:15
|
diff --git a/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr b/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr
deleted file mode 100644
index 8b2b87223..000000000
--- a/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/higher-ranked-projection.rs:25:5
- |
-LL | foo(());
- | ^^^^^^^ one type is more general than the other
- |
- = note: expected reference `&'a ()`
- found reference `&()`
-note: the lifetime requirement is introduced here
- --> $DIR/higher-ranked-projection.rs:16:33
- |
-LL | where for<'a> &'a T: Mirror<Image=U>
- | ^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr b/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr
deleted file mode 100644
index 217392aa3..000000000
--- a/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown debugging option: `borrowck`
-
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
index e007f5a16..a85edd7a0 100644
--- a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
+++ b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
@@ -5,13 +5,13 @@ LL | impl X<'_> for u32
| ^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`hr_associated_type_bound_2`)
-note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
+note: required for `u32` to implement `for<'b> X<'b>`
--> $DIR/hr-associated-type-bound-2.rs:11:6
|
LL | impl X<'_> for u32
| ^^^^^ ^^^
= note: 128 redundant requirements hidden
- = note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
+ = note: required for `u32` to implement `for<'b> X<'b>`
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
index 939c9bbdb..6661347e4 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-1.stderr
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
@@ -4,13 +4,13 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: required because of the requirements on the impl of `Grault` for `(T,)`
+note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-1.rs:15:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Grault` for `(T,)`
+ = note: required for `(T,)` to implement `Grault`
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.stderr b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
index d02ed2cac..ec4ffe27c 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-2.stderr
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: required because of the requirements on the impl of `Grault` for `(T,)`
+note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-2.rs:7:17
|
LL | impl<T: Grault> Grault for (T,)
diff --git a/src/test/ui/associated-types/issue-22560.stderr b/src/test/ui/associated-types/issue-22560.stderr
index 700923c1b..2b88cf0b4 100644
--- a/src/test/ui/associated-types/issue-22560.stderr
+++ b/src/test/ui/associated-types/issue-22560.stderr
@@ -1,25 +1,3 @@
-error[E0393]: the type parameter `Rhs` must be explicitly specified
- --> $DIR/issue-22560.rs:9:23
- |
-LL | trait Sub<Rhs=Self> {
- | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
- | ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
- |
- = note: because of the default `Self` reference, type parameters must be specified on object types
-
-error[E0393]: the type parameter `Rhs` must be explicitly specified
- --> $DIR/issue-22560.rs:9:17
- |
-LL | trait Add<Rhs=Self> {
- | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
- | ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
- |
- = note: because of the default `Self` reference, type parameters must be specified on object types
-
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/issue-22560.rs:9:23
|
@@ -28,7 +6,7 @@ LL | type Test = dyn Add + Sub;
| |
| first non-auto trait
|
- = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}`
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}`
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
@@ -50,6 +28,28 @@ help: specify the associated types
LL | type Test = dyn Add<Output = Type> + Sub<Output = Type>;
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/issue-22560.rs:9:17
+ |
+LL | trait Add<Rhs=Self> {
+ | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/issue-22560.rs:9:23
+ |
+LL | trait Sub<Rhs=Self> {
+ | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0191, E0225, E0393.
diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
index 22daaf329..a14a273b3 100644
--- a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
+++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
@@ -1,10 +1,8 @@
error[E0277]: the trait bound `T: Copy` is not satisfied
- --> $DIR/issue-27675-unchecked-bounds.rs:15:31
+ --> $DIR/issue-27675-unchecked-bounds.rs:15:12
|
LL | copy::<dyn Setup<From=T>>(t)
- | ------------------------- ^ the trait `Copy` is not implemented for `T`
- | |
- | required by a bound introduced by this call
+ | ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
note: required by a bound in `copy`
--> $DIR/issue-27675-unchecked-bounds.rs:10:12
diff --git a/src/test/ui/associated-types/issue-44153.stderr b/src/test/ui/associated-types/issue-44153.stderr
index 200efbe02..9c92f19d8 100644
--- a/src/test/ui/associated-types/issue-44153.stderr
+++ b/src/test/ui/associated-types/issue-44153.stderr
@@ -9,7 +9,7 @@ note: expected this to be `&()`
|
LL | type Element = ();
| ^^
-note: required because of the requirements on the impl of `Visit` for `()`
+note: required for `()` to implement `Visit`
--> $DIR/issue-44153.rs:13:10
|
LL | impl<'a> Visit for () where
diff --git a/src/test/ui/associated-types/issue-59324.rs b/src/test/ui/associated-types/issue-59324.rs
index 162f9e00e..9e68e9e77 100644
--- a/src/test/ui/associated-types/issue-59324.rs
+++ b/src/test/ui/associated-types/issue-59324.rs
@@ -15,9 +15,9 @@ pub trait ThriftService<Bug: NotFoo>:
{
fn get_service(
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
+ //~| ERROR the trait bound `Bug: Foo` is not satisfied
&self,
) -> Self::AssocType;
- //~^ the trait bound `Bug: Foo` is not satisfied
}
fn with_factory<H>(factory: dyn ThriftService<()>) {}
diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr
index a84b599b5..62cf1f37a 100644
--- a/src/test/ui/associated-types/issue-59324.stderr
+++ b/src/test/ui/associated-types/issue-59324.stderr
@@ -20,7 +20,7 @@ LL | |
LL | |
LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
... |
-LL | |
+LL | | ) -> Self::AssocType;
LL | | }
| |_^ the trait `Foo` is not implemented for `Bug`
|
@@ -34,6 +34,7 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
LL | / fn get_service(
LL | |
+LL | |
LL | | &self,
LL | | ) -> Self::AssocType;
| |_________________________^ the trait `Foo` is not implemented for `Bug`
@@ -44,16 +45,20 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
| +++++
error[E0277]: the trait bound `(): Foo` is not satisfied
- --> $DIR/issue-59324.rs:23:29
+ --> $DIR/issue-59324.rs:23:1
|
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
- | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
error[E0277]: the trait bound `Bug: Foo` is not satisfied
- --> $DIR/issue-59324.rs:19:10
+ --> $DIR/issue-59324.rs:16:5
|
-LL | ) -> Self::AssocType;
- | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
+LL | / fn get_service(
+LL | |
+LL | |
+LL | | &self,
+LL | | ) -> Self::AssocType;
+ | |_________________________^ the trait `Foo` is not implemented for `Bug`
|
help: consider further restricting this bound
|
diff --git a/src/test/ui/associated-types/issue-62200.rs b/src/test/ui/associated-types/issue-62200.rs
index 9d18690e9..499bbd6b6 100644
--- a/src/test/ui/associated-types/issue-62200.rs
+++ b/src/test/ui/associated-types/issue-62200.rs
@@ -10,6 +10,7 @@ impl T<'_> for S {
fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
//~^ ERROR binding for associated type `Output` references an anonymous lifetime
-//~^^ NOTE lifetimes appearing in an associated type are not considered constrained
+//~| NOTE lifetimes appearing in an associated or opaque type are not considered constrained
+//~| NOTE consider introducing a named lifetime parameter
fn main() {}
diff --git a/src/test/ui/associated-types/issue-62200.stderr b/src/test/ui/associated-types/issue-62200.stderr
index f14cd81fd..04f0728f5 100644
--- a/src/test/ui/associated-types/issue-62200.stderr
+++ b/src/test/ui/associated-types/issue-62200.stderr
@@ -4,7 +4,8 @@ error[E0582]: binding for associated type `Output` references an anonymous lifet
LL | fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
| ^^^^^^^^^^^^^^^
|
- = note: lifetimes appearing in an associated type are not considered constrained
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/issue-65774-1.stderr b/src/test/ui/associated-types/issue-65774-1.stderr
index 419de689c..3b294d65d 100644
--- a/src/test/ui/associated-types/issue-65774-1.stderr
+++ b/src/test/ui/associated-types/issue-65774-1.stderr
@@ -18,7 +18,7 @@ LL | let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(
| ^^^^^^^ the trait `MyDisplay` is not implemented for `T`
|
= help: the trait `MyDisplay` is implemented for `&'a mut T`
-note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
+note: required for `&mut T` to implement `MyDisplay`
--> $DIR/issue-65774-1.rs:5:24
|
LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr
index 8db4a49da..f24423dd1 100644
--- a/src/test/ui/associated-types/issue-87261.stderr
+++ b/src/test/ui/associated-types/issue-87261.stderr
@@ -1,8 +1,10 @@
error[E0271]: type mismatch resolving `<A as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:56:5
+ --> $DIR/issue-87261.rs:56:19
|
LL | accepts_trait(a);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<A as Trait>::Associated`
@@ -17,10 +19,12 @@ LL | A: Trait<Associated = ()> + 'static,
| +++++++++++++++++
error[E0271]: type mismatch resolving `<B as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:59:5
+ --> $DIR/issue-87261.rs:59:19
|
LL | accepts_trait(b);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<B as Trait>::Associated`
@@ -33,10 +37,12 @@ LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<C as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:62:5
+ --> $DIR/issue-87261.rs:62:19
|
LL | accepts_trait(c);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<C as Trait>::Associated`
@@ -51,10 +57,12 @@ LL | C: Trait<Associated = ()> + Foo,
| +++++++++++++++++
error[E0271]: type mismatch resolving `<D as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:65:5
+ --> $DIR/issue-87261.rs:65:19
|
LL | accepts_trait(d);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<D as Trait>::Associated`
@@ -67,10 +75,12 @@ LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:68:5
+ --> $DIR/issue-87261.rs:68:27
|
LL | accepts_generic_trait(e);
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<E as GenericTrait<()>>::Associated`
@@ -85,10 +95,12 @@ LL | E: GenericTrait<(), Associated = ()> + 'static,
| +++++++++++++++++
error[E0271]: type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:71:5
+ --> $DIR/issue-87261.rs:71:27
|
LL | accepts_generic_trait(f);
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<F as GenericTrait<()>>::Associated`
@@ -103,10 +115,12 @@ LL | F: GenericTrait<(), Associated = ()> + Foo,
| +++++++++++++++++
error[E0271]: type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:74:5
+ --> $DIR/issue-87261.rs:74:27
|
LL | accepts_generic_trait(g);
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<G as GenericTrait<()>>::Associated`
@@ -119,13 +133,15 @@ LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:79:5
+ --> $DIR/issue-87261.rs:79:19
|
LL | fn returns_opaque() -> impl Trait + 'static {
| -------------------- the found opaque type
...
LL | accepts_trait(returns_opaque());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl Trait as Trait>::Associated`
@@ -140,13 +156,15 @@ LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:82:5
+ --> $DIR/issue-87261.rs:82:19
|
LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
| --------------------------- the found opaque type
...
LL | accepts_trait(returns_opaque_derived());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl DerivedTrait as Trait>::Associated`
@@ -161,13 +179,15 @@ LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:85:5
+ --> $DIR/issue-87261.rs:85:19
|
LL | fn returns_opaque_foo() -> impl Trait + Foo {
| ---------------- the found opaque type
...
LL | accepts_trait(returns_opaque_foo());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl Trait + Foo as Trait>::Associated`
@@ -182,13 +202,15 @@ LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:88:5
+ --> $DIR/issue-87261.rs:88:19
|
LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
| ----------------------- the found opaque type
...
LL | accepts_trait(returns_opaque_derived_foo());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl DerivedTrait + Foo as Trait>::Associated`
@@ -201,13 +223,15 @@ LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:91:5
+ --> $DIR/issue-87261.rs:91:27
|
LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
| ------------------------------- the found opaque type
...
LL | accepts_generic_trait(returns_opaque_generic());
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated`
@@ -222,13 +246,15 @@ LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'st
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:94:5
+ --> $DIR/issue-87261.rs:94:27
|
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
| --------------------------- the found opaque type
...
LL | accepts_generic_trait(returns_opaque_generic_foo());
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated`
@@ -243,13 +269,15 @@ LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> +
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:97:5
+ --> $DIR/issue-87261.rs:97:27
|
LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
| ---------------------------------------- the found opaque type
...
LL | accepts_generic_trait(returns_opaque_generic_duplicate());
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated`
diff --git a/src/test/ui/associated-types/substs-ppaux.normal.stderr b/src/test/ui/associated-types/substs-ppaux.normal.stderr
index 085c56870..3f180cf4f 100644
--- a/src/test/ui/associated-types/substs-ppaux.normal.stderr
+++ b/src/test/ui/associated-types/substs-ppaux.normal.stderr
@@ -11,7 +11,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>();
| ++
@@ -29,7 +29,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
| ++
@@ -47,7 +47,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz();
| ++
@@ -77,7 +77,7 @@ LL | <str as Foo<u8>>::bar;
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
-note: required because of the requirements on the impl of `Foo<'_, '_, u8>` for `str`
+note: required for `str` to implement `Foo<'_, '_, u8>`
--> $DIR/substs-ppaux.rs:11:17
|
LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
diff --git a/src/test/ui/associated-types/substs-ppaux.verbose.stderr b/src/test/ui/associated-types/substs-ppaux.verbose.stderr
index b831f3b7a..16dd29de2 100644
--- a/src/test/ui/associated-types/substs-ppaux.verbose.stderr
+++ b/src/test/ui/associated-types/substs-ppaux.verbose.stderr
@@ -11,7 +11,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>();
| ++
@@ -29,7 +29,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
| ++
@@ -47,7 +47,7 @@ LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz();
| ++
@@ -77,7 +77,7 @@ LL | <str as Foo<u8>>::bar;
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
-note: required because of the requirements on the impl of `Foo<'_#0r, '_#1r, u8>` for `str`
+note: required for `str` to implement `Foo<'_#0r, '_#1r, u8>`
--> $DIR/substs-ppaux.rs:11:17
|
LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
diff --git a/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr b/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr
new file mode 100644
index 000000000..3be7f370d
--- /dev/null
+++ b/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr
@@ -0,0 +1,110 @@
+error: future cannot be sent between threads safely
+ --> $DIR/async-await-let-else.rs:48:13
+ |
+LL | is_send(foo(Some(true)));
+ | ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
+ |
+ = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+ --> $DIR/async-await-let-else.rs:11:14
+ |
+LL | let r = Rc::new(());
+ | - has type `Rc<()>` which is not `Send`
+LL | bar().await
+ | ^^^^^^ await occurs here, with `r` maybe used later
+LL | };
+ | - `r` is later dropped here
+note: required by a bound in `is_send`
+ --> $DIR/async-await-let-else.rs:19:15
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ^^^^ required by this bound in `is_send`
+
+error[E0277]: `Rc<()>` cannot be sent between threads safely
+ --> $DIR/async-await-let-else.rs:50:13
+ |
+LL | async fn foo2(x: Option<bool>) {
+ | - within this `impl Future<Output = ()>`
+...
+LL | is_send(foo2(Some(true)));
+ | ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: required because it's used within this `async fn` body
+ --> $DIR/async-await-let-else.rs:27:29
+ |
+LL | async fn bar2<T>(_: T) -> ! {
+ | _____________________________^
+LL | | panic!()
+LL | | }
+ | |_^
+ = note: required because it captures the following types: `ResumeTy`, `Option<bool>`, `impl Future<Output = !>`, `()`
+note: required because it's used within this `async fn` body
+ --> $DIR/async-await-let-else.rs:21:32
+ |
+LL | async fn foo2(x: Option<bool>) {
+ | ________________________________^
+LL | | let Some(_) = x else {
+LL | | bar2(Rc::new(())).await
+LL | | };
+LL | | }
+ | |_^
+note: required by a bound in `is_send`
+ --> $DIR/async-await-let-else.rs:19:15
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ^^^^ required by this bound in `is_send`
+
+error: future cannot be sent between threads safely
+ --> $DIR/async-await-let-else.rs:52:13
+ |
+LL | is_send(foo3(Some(true)));
+ | ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
+ |
+ = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+ --> $DIR/async-await-let-else.rs:33:28
+ |
+LL | (Rc::new(()), bar().await);
+ | ----------- ^^^^^^ await occurs here, with `Rc::new(())` maybe used later
+ | |
+ | has type `Rc<()>` which is not `Send`
+note: `Rc::new(())` is later dropped here
+ --> $DIR/async-await-let-else.rs:33:35
+ |
+LL | (Rc::new(()), bar().await);
+ | ^
+note: required by a bound in `is_send`
+ --> $DIR/async-await-let-else.rs:19:15
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ^^^^ required by this bound in `is_send`
+
+error: future cannot be sent between threads safely
+ --> $DIR/async-await-let-else.rs:54:13
+ |
+LL | is_send(foo4(Some(true)));
+ | ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
+ |
+ = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+ --> $DIR/async-await-let-else.rs:41:14
+ |
+LL | let r = Rc::new(());
+ | - has type `Rc<()>` which is not `Send`
+LL | bar().await;
+ | ^^^^^^ await occurs here, with `r` maybe used later
+...
+LL | };
+ | - `r` is later dropped here
+note: required by a bound in `is_send`
+ --> $DIR/async-await-let-else.rs:19:15
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ^^^^ required by this bound in `is_send`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/async-await-let-else.stderr b/src/test/ui/async-await/async-await-let-else.no-drop-tracking.stderr
index 4d23e27c4..7f93563e2 100644
--- a/src/test/ui/async-await/async-await-let-else.stderr
+++ b/src/test/ui/async-await/async-await-let-else.no-drop-tracking.stderr
@@ -1,12 +1,12 @@
error: future cannot be sent between threads safely
- --> $DIR/async-await-let-else.rs:45:13
+ --> $DIR/async-await-let-else.rs:48:13
|
LL | is_send(foo(Some(true)));
| ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await
- --> $DIR/async-await-let-else.rs:8:14
+ --> $DIR/async-await-let-else.rs:11:14
|
LL | let r = Rc::new(());
| - has type `Rc<()>` which is not `Send`
@@ -15,67 +15,67 @@ LL | bar().await
LL | };
| - `r` is later dropped here
note: required by a bound in `is_send`
- --> $DIR/async-await-let-else.rs:16:15
+ --> $DIR/async-await-let-else.rs:19:15
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`
error: future cannot be sent between threads safely
- --> $DIR/async-await-let-else.rs:47:13
+ --> $DIR/async-await-let-else.rs:50:13
|
LL | is_send(foo2(Some(true)));
| ^^^^^^^^^^^^^^^^ future returned by `foo2` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await
- --> $DIR/async-await-let-else.rs:20:26
+ --> $DIR/async-await-let-else.rs:23:26
|
LL | bar2(Rc::new(())).await
| ----------- ^^^^^^ await occurs here, with `Rc::new(())` maybe used later
| |
| has type `Rc<()>` which is not `Send`
LL | };
- | - `Rc::new(())` is later dropped here
+ | - `Rc::new(())` is later dropped here
note: required by a bound in `is_send`
- --> $DIR/async-await-let-else.rs:16:15
+ --> $DIR/async-await-let-else.rs:19:15
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`
error: future cannot be sent between threads safely
- --> $DIR/async-await-let-else.rs:49:13
+ --> $DIR/async-await-let-else.rs:52:13
|
LL | is_send(foo3(Some(true)));
| ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await
- --> $DIR/async-await-let-else.rs:30:28
+ --> $DIR/async-await-let-else.rs:33:28
|
LL | (Rc::new(()), bar().await);
| ----------- ^^^^^^ await occurs here, with `Rc::new(())` maybe used later
| |
| has type `Rc<()>` which is not `Send`
note: `Rc::new(())` is later dropped here
- --> $DIR/async-await-let-else.rs:30:35
+ --> $DIR/async-await-let-else.rs:33:35
|
LL | (Rc::new(()), bar().await);
| ^
note: required by a bound in `is_send`
- --> $DIR/async-await-let-else.rs:16:15
+ --> $DIR/async-await-let-else.rs:19:15
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`
error: future cannot be sent between threads safely
- --> $DIR/async-await-let-else.rs:51:13
+ --> $DIR/async-await-let-else.rs:54:13
|
LL | is_send(foo4(Some(true)));
| ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await
- --> $DIR/async-await-let-else.rs:38:14
+ --> $DIR/async-await-let-else.rs:41:14
|
LL | let r = Rc::new(());
| - has type `Rc<()>` which is not `Send`
@@ -85,7 +85,7 @@ LL | bar().await;
LL | };
| - `r` is later dropped here
note: required by a bound in `is_send`
- --> $DIR/async-await-let-else.rs:16:15
+ --> $DIR/async-await-let-else.rs:19:15
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`
diff --git a/src/test/ui/async-await/async-await-let-else.rs b/src/test/ui/async-await/async-await-let-else.rs
index 7ea07ae9a..3fb2142b9 100644
--- a/src/test/ui/async-await/async-await-let-else.rs
+++ b/src/test/ui/async-await/async-await-let-else.rs
@@ -1,5 +1,8 @@
// edition:2021
-#![feature(let_else)]
+// revisions: drop-tracking no-drop-tracking
+// [drop-tracking] compile-flags: -Zdrop-tracking=yes
+// [no-drop-tracking] compile-flags: -Zdrop-tracking=no
+
use std::rc::Rc;
async fn foo(x: Option<bool>) {
@@ -43,11 +46,11 @@ async fn foo4(x: Option<bool>) {
fn main() {
is_send(foo(Some(true)));
- //~^ ERROR future cannot be sent between threads safely
+ //~^ ERROR cannot be sent between threads safely
is_send(foo2(Some(true)));
- //~^ ERROR future cannot be sent between threads safely
+ //~^ ERROR cannot be sent between threads safely
is_send(foo3(Some(true)));
- //~^ ERROR future cannot be sent between threads safely
+ //~^ ERROR cannot be sent between threads safely
is_send(foo4(Some(true)));
- //~^ ERROR future cannot be sent between threads safely
+ //~^ ERROR cannot be sent between threads safely
}
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
index b831d6102..446212ca7 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
@@ -15,7 +15,7 @@ fn return_targets_async_block_not_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
- //~^ ERROR type mismatch
+ //~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
}
async fn return_targets_async_block_not_async_fn() -> u8 {
@@ -24,7 +24,7 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
- //~^ ERROR type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
+ //~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
}
fn no_break_in_async_block() {
@@ -42,7 +42,9 @@ fn no_break_in_async_block_even_with_outer_loop() {
}
struct MyErr;
-fn err() -> Result<u8, MyErr> { Err(MyErr) }
+fn err() -> Result<u8, MyErr> {
+ Err(MyErr)
+}
fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
//~^ ERROR mismatched types
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index e58876896..2a08d5d6c 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -31,7 +31,7 @@ LL | |
LL | | }
| |_^ expected `u8`, found `()`
-error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
+error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
LL | let _: &dyn Future<Output = ()> = &block;
@@ -47,7 +47,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
| |
| implicitly returns `()` as its body has no tail or `return` expression
-error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
+error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
LL | let _: &dyn Future<Output = ()> = &block;
@@ -56,7 +56,7 @@ LL | let _: &dyn Future<Output = ()> = &block;
= note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
error[E0308]: mismatched types
- --> $DIR/async-block-control-flow-static-semantics.rs:47:44
+ --> $DIR/async-block-control-flow-static-semantics.rs:49:44
|
LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
| ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
@@ -67,7 +67,7 @@ LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/async-block-control-flow-static-semantics.rs:56:50
+ --> $DIR/async-block-control-flow-static-semantics.rs:58:50
|
LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
| ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
diff --git a/src/test/ui/async-await/async-trait-fn.rs b/src/test/ui/async-await/async-trait-fn.rs
index e2062e827..0ea685986 100644
--- a/src/test/ui/async-await/async-trait-fn.rs
+++ b/src/test/ui/async-await/async-trait-fn.rs
@@ -1,8 +1,11 @@
// edition:2018
trait T {
async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
+ //~^ ERROR mismatched types
async fn bar(&self) {} //~ ERROR functions in traits cannot be declared `async`
+ //~^ ERROR mismatched types
async fn baz() { //~ ERROR functions in traits cannot be declared `async`
+ //~^ ERROR mismatched types
// Nested item must not ICE.
fn a() {}
}
diff --git a/src/test/ui/async-await/async-trait-fn.stderr b/src/test/ui/async-await/async-trait-fn.stderr
index 1eb8969a8..e5c584e31 100644
--- a/src/test/ui/async-await/async-trait-fn.stderr
+++ b/src/test/ui/async-await/async-trait-fn.stderr
@@ -2,40 +2,89 @@ error[E0706]: functions in traits cannot be declared `async`
--> $DIR/async-trait-fn.rs:3:5
|
LL | async fn foo() {}
- | -----^^^^^^^^^^^^
+ | -----^^^^^^^^^
| |
| `async` because of this
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/async-trait-fn.rs:4:5
+ --> $DIR/async-trait-fn.rs:5:5
|
LL | async fn bar(&self) {}
- | -----^^^^^^^^^^^^^^^^^
+ | -----^^^^^^^^^^^^^^
| |
| `async` because of this
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/async-trait-fn.rs:5:5
+ --> $DIR/async-trait-fn.rs:7:5
+ |
+LL | async fn baz() {
+ | -----^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error[E0308]: mismatched types
+ --> $DIR/async-trait-fn.rs:3:20
+ |
+LL | async fn foo() {}
+ | ^^ expected associated type, found opaque type
+ |
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+ |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
+ |
+ = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/async-trait-fn.rs:3:20>)
+ found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
+error[E0308]: mismatched types
+ --> $DIR/async-trait-fn.rs:5:25
+ |
+LL | async fn bar(&self) {}
+ | ^^ expected associated type, found opaque type
+ |
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+ |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
+ |
+ = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/async-trait-fn.rs:5:25>)
+ found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
+error[E0308]: mismatched types
+ --> $DIR/async-trait-fn.rs:7:20
|
LL | async fn baz() {
- | ^----
- | |
- | _____`async` because of this
- | |
+ | ____________________^
+LL | |
LL | | // Nested item must not ICE.
LL | | fn a() {}
LL | | }
- | |_____^
+ | |_____^ expected associated type, found opaque type
|
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+ |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
+ |
+ = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/async-trait-fn.rs:7:20>)
+ found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
-For more information about this error, try `rustc --explain E0706`.
+Some errors have detailed explanations: E0308, E0706.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
index e5dc9c8a5..22a61dcd2 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
@@ -16,7 +16,8 @@ impl Foo {
trait Bar {
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
- //~^ ERROR functions in traits cannot be declared `async`
+ //~^ ERROR functions in traits cannot be declared `async`
+ //~| ERROR mismatched types
}
fn main() {
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index 35f9c581c..8c2902d9b 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -53,7 +53,7 @@ LL | async fn foo() {}
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
error[E0670]: `async fn` is not permitted in Rust 2015
- --> $DIR/edition-deny-async-fns-2015.rs:36:9
+ --> $DIR/edition-deny-async-fns-2015.rs:37:9
|
LL | async fn bar() {}
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -62,7 +62,7 @@ LL | async fn bar() {}
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
error[E0670]: `async fn` is not permitted in Rust 2015
- --> $DIR/edition-deny-async-fns-2015.rs:26:9
+ --> $DIR/edition-deny-async-fns-2015.rs:27:9
|
LL | async fn foo() {}
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -71,7 +71,7 @@ LL | async fn foo() {}
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
error[E0670]: `async fn` is not permitted in Rust 2015
- --> $DIR/edition-deny-async-fns-2015.rs:31:13
+ --> $DIR/edition-deny-async-fns-2015.rs:32:13
|
LL | async fn bar() {}
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -83,14 +83,30 @@ error[E0706]: functions in traits cannot be declared `async`
--> $DIR/edition-deny-async-fns-2015.rs:18:5
|
LL | async fn foo() {}
- | -----^^^^^^^^^^^^
+ | -----^^^^^^^^^
| |
| `async` because of this
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
-error: aborting due to 10 previous errors
+error[E0308]: mismatched types
+ --> $DIR/edition-deny-async-fns-2015.rs:18:20
+ |
+LL | async fn foo() {}
+ | ^^ expected associated type, found opaque type
+ |
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+ |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
+ |
+ = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/edition-deny-async-fns-2015.rs:18:20>)
+ found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
+error: aborting due to 11 previous errors
-Some errors have detailed explanations: E0670, E0706.
-For more information about an error, try `rustc --explain E0670`.
+Some errors have detailed explanations: E0308, E0670, E0706.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr
index 3be8c5520..2494c3feb 100644
--- a/src/test/ui/async-await/generator-desc.stderr
+++ b/src/test/ui/async-await/generator-desc.stderr
@@ -42,7 +42,7 @@ note: function defined here
--> $DIR/generator-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
- | ^^^ ----- -----
+ | ^^^ -----
error[E0308]: mismatched types
--> $DIR/generator-desc.rs:14:26
@@ -67,7 +67,7 @@ note: function defined here
--> $DIR/generator-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
- | ^^^ ----- -----
+ | ^^^ -----
error: aborting due to 3 previous errors
diff --git a/src/test/ui/async-await/issue-101715.rs b/src/test/ui/async-await/issue-101715.rs
new file mode 100644
index 000000000..1be5d0248
--- /dev/null
+++ b/src/test/ui/async-await/issue-101715.rs
@@ -0,0 +1,17 @@
+// edition:2018
+
+struct S;
+
+impl S {
+ fn very_long_method_name_the_longest_method_name_in_the_whole_universe(self) {}
+}
+
+async fn foo() {
+ S.very_long_method_name_the_longest_method_name_in_the_whole_universe()
+ .await
+ //~^ error: `()` is not a future
+ //~| help: remove the `.await`
+ //~| help: the trait `Future` is not implemented for `()`
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-101715.stderr b/src/test/ui/async-await/issue-101715.stderr
new file mode 100644
index 000000000..a0e8d2a89
--- /dev/null
+++ b/src/test/ui/async-await/issue-101715.stderr
@@ -0,0 +1,16 @@
+error[E0277]: `()` is not a future
+ --> $DIR/issue-101715.rs:11:9
+ |
+LL | .await
+ | ^^^^^^
+ | |
+ | `()` is not a future
+ | help: remove the `.await`
+ |
+ = help: the trait `Future` is not implemented for `()`
+ = note: () must be a future or must implement `IntoFuture` to be awaited
+ = note: required for `()` to implement `IntoFuture`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr
index d631e6dc7..f609e3636 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.stderr
+++ b/src/test/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr
@@ -1,12 +1,12 @@
error: future cannot be sent between threads safely
- --> $DIR/issue-64130-4-async-move.rs:15:17
+ --> $DIR/issue-64130-4-async-move.rs:19:17
|
LL | pub fn foo() -> impl Future + Send {
| ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
note: future is not `Send` as this value is used across an await
- --> $DIR/issue-64130-4-async-move.rs:21:31
+ --> $DIR/issue-64130-4-async-move.rs:25:31
|
LL | match client.status() {
| ------ has type `&Client` which is not `Send`
@@ -17,7 +17,7 @@ LL | let _x = get().await;
LL | }
| - `client` is later dropped here
help: consider moving this into a `let` binding to create a shorter lived borrow
- --> $DIR/issue-64130-4-async-move.rs:19:15
+ --> $DIR/issue-64130-4-async-move.rs:23:15
|
LL | match client.status() {
| ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr b/src/test/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
new file mode 100644
index 000000000..f609e3636
--- /dev/null
+++ b/src/test/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
@@ -0,0 +1,26 @@
+error: future cannot be sent between threads safely
+ --> $DIR/issue-64130-4-async-move.rs:19:17
+ |
+LL | pub fn foo() -> impl Future + Send {
+ | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
+ |
+ = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
+note: future is not `Send` as this value is used across an await
+ --> $DIR/issue-64130-4-async-move.rs:25:31
+ |
+LL | match client.status() {
+ | ------ has type `&Client` which is not `Send`
+LL | 200 => {
+LL | let _x = get().await;
+ | ^^^^^^ await occurs here, with `client` maybe used later
+...
+LL | }
+ | - `client` is later dropped here
+help: consider moving this into a `let` binding to create a shorter lived borrow
+ --> $DIR/issue-64130-4-async-move.rs:23:15
+ |
+LL | match client.status() {
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.rs b/src/test/ui/async-await/issue-64130-4-async-move.rs
index 2538f3435..a38428fc0 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.rs
+++ b/src/test/ui/async-await/issue-64130-4-async-move.rs
@@ -1,4 +1,8 @@
// edition:2018
+// revisions: no_drop_tracking drop_tracking
+// [drop_tracking] check-pass
+// [drop_tracking] compile-flags: -Zdrop-tracking=yes
+// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
use std::any::Any;
use std::future::Future;
@@ -10,16 +14,16 @@ impl Client {
}
}
-async fn get() { }
+async fn get() {}
pub fn foo() -> impl Future + Send {
- //~^ ERROR future cannot be sent between threads safely
+ //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
let client = Client(Box::new(true));
async move {
match client.status() {
200 => {
let _x = get().await;
- },
+ }
_ => (),
}
}
diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
index 01c0d3225..af99b608c 100644
--- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr
+++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
@@ -1,8 +1,12 @@
error: future cannot be sent between threads safely
- --> $DIR/issue-67252-unnamed-future.rs:18:5
+ --> $DIR/issue-67252-unnamed-future.rs:18:11
|
-LL | spawn(async {
- | ^^^^^ future created by async block is not `Send`
+LL | spawn(async {
+ | ___________^
+LL | | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
+LL | | AFuture.await;
+LL | | });
+ | |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await
diff --git a/src/test/ui/async-await/issue-68112.drop_tracking.stderr b/src/test/ui/async-await/issue-68112.drop_tracking.stderr
new file mode 100644
index 000000000..c915164cf
--- /dev/null
+++ b/src/test/ui/async-await/issue-68112.drop_tracking.stderr
@@ -0,0 +1,79 @@
+error: future cannot be sent between threads safely
+ --> $DIR/issue-68112.rs:37:18
+ |
+LL | require_send(send_fut);
+ | ^^^^^^^^ future created by async block is not `Send`
+ |
+ = help: the trait `Sync` is not implemented for `RefCell<i32>`
+note: future is not `Send` as it awaits another future which is not `Send`
+ --> $DIR/issue-68112.rs:34:17
+ |
+LL | let _ = non_send_fut.await;
+ | ^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
+note: required by a bound in `require_send`
+ --> $DIR/issue-68112.rs:14:25
+ |
+LL | fn require_send(_: impl Send) {}
+ | ^^^^ required by this bound in `require_send`
+
+error: future cannot be sent between threads safely
+ --> $DIR/issue-68112.rs:46:18
+ |
+LL | require_send(send_fut);
+ | ^^^^^^^^ future created by async block is not `Send`
+ |
+ = help: the trait `Sync` is not implemented for `RefCell<i32>`
+note: future is not `Send` as it awaits another future which is not `Send`
+ --> $DIR/issue-68112.rs:43:17
+ |
+LL | let _ = make_non_send_future1().await;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
+note: required by a bound in `require_send`
+ --> $DIR/issue-68112.rs:14:25
+ |
+LL | fn require_send(_: impl Send) {}
+ | ^^^^ required by this bound in `require_send`
+
+error[E0277]: `RefCell<i32>` cannot be shared between threads safely
+ --> $DIR/issue-68112.rs:65:18
+ |
+LL | require_send(send_fut);
+ | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Sync` is not implemented for `RefCell<i32>`
+ = note: required for `Arc<RefCell<i32>>` to implement `Send`
+note: required because it's used within this `async fn` body
+ --> $DIR/issue-68112.rs:50:31
+ |
+LL | async fn ready2<T>(t: T) -> T {
+ | _______________________________^
+LL | | t
+LL | | }
+ | |_^
+note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
+ --> $DIR/issue-68112.rs:53:31
+ |
+LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `Ready<i32>`
+note: required because it's used within this `async` block
+ --> $DIR/issue-68112.rs:60:26
+ |
+LL | let send_fut = async {
+ | __________________________^
+LL | | let non_send_fut = make_non_send_future2();
+LL | | let _ = non_send_fut.await;
+LL | | ready(0).await;
+LL | | };
+ | |_____^
+note: required by a bound in `require_send`
+ --> $DIR/issue-68112.rs:14:25
+ |
+LL | fn require_send(_: impl Send) {}
+ | ^^^^ required by this bound in `require_send`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr
index 4285fbbec..11b7d1aaa 100644
--- a/src/test/ui/async-await/issue-68112.stderr
+++ b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr
@@ -1,60 +1,65 @@
error: future cannot be sent between threads safely
- --> $DIR/issue-68112.rs:34:5
+ --> $DIR/issue-68112.rs:37:18
|
LL | require_send(send_fut);
- | ^^^^^^^^^^^^ future created by async block is not `Send`
+ | ^^^^^^^^ future created by async block is not `Send`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
note: future is not `Send` as it awaits another future which is not `Send`
- --> $DIR/issue-68112.rs:31:17
+ --> $DIR/issue-68112.rs:34:17
|
LL | let _ = non_send_fut.await;
| ^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
note: required by a bound in `require_send`
- --> $DIR/issue-68112.rs:11:25
+ --> $DIR/issue-68112.rs:14:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely
- --> $DIR/issue-68112.rs:43:5
+ --> $DIR/issue-68112.rs:46:18
|
LL | require_send(send_fut);
- | ^^^^^^^^^^^^ future created by async block is not `Send`
+ | ^^^^^^^^ future created by async block is not `Send`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
note: future is not `Send` as it awaits another future which is not `Send`
- --> $DIR/issue-68112.rs:40:17
+ --> $DIR/issue-68112.rs:43:17
|
LL | let _ = make_non_send_future1().await;
| ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
note: required by a bound in `require_send`
- --> $DIR/issue-68112.rs:11:25
+ --> $DIR/issue-68112.rs:14:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error[E0277]: `RefCell<i32>` cannot be shared between threads safely
- --> $DIR/issue-68112.rs:60:5
+ --> $DIR/issue-68112.rs:65:18
|
LL | require_send(send_fut);
- | ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
- = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
+ = note: required for `Arc<RefCell<i32>>` to implement `Send`
note: required because it's used within this `async fn` body
- --> $DIR/issue-68112.rs:47:31
+ --> $DIR/issue-68112.rs:50:31
|
-LL | async fn ready2<T>(t: T) -> T { t }
- | ^^^^^
+LL | async fn ready2<T>(t: T) -> T {
+ | _______________________________^
+LL | | t
+LL | | }
+ | |_^
note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
- --> $DIR/issue-68112.rs:48:31
+ --> $DIR/issue-68112.rs:53:31
|
LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `i32`, `Ready<i32>`
note: required because it's used within this `async` block
- --> $DIR/issue-68112.rs:55:26
+ --> $DIR/issue-68112.rs:60:26
|
LL | let send_fut = async {
| __________________________^
@@ -64,7 +69,7 @@ LL | | ready(0).await;
LL | | };
| |_____^
note: required by a bound in `require_send`
- --> $DIR/issue-68112.rs:11:25
+ --> $DIR/issue-68112.rs:14:25
|
LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
diff --git a/src/test/ui/async-await/issue-68112.rs b/src/test/ui/async-await/issue-68112.rs
index bfabf81d1..9c705137a 100644
--- a/src/test/ui/async-await/issue-68112.rs
+++ b/src/test/ui/async-await/issue-68112.rs
@@ -1,10 +1,13 @@
// edition:2018
+// revisions: no_drop_tracking drop_tracking
+// [drop_tracking] compile-flags: -Zdrop-tracking=yes
+// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
use std::{
- future::Future,
cell::RefCell,
- sync::Arc,
+ future::Future,
pin::Pin,
+ sync::Arc,
task::{Context, Poll},
};
@@ -44,7 +47,9 @@ fn test1_no_let() {
//~^ ERROR future cannot be sent between threads
}
-async fn ready2<T>(t: T) -> T { t }
+async fn ready2<T>(t: T) -> T {
+ t
+}
fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
ready2(Arc::new(RefCell::new(0)))
}
diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr
index a88bce6cc..d3cf57d3b 100644
--- a/src/test/ui/async-await/issue-70594.stderr
+++ b/src/test/ui/async-await/issue-70594.stderr
@@ -22,16 +22,14 @@ error[E0277]: `()` is not a future
--> $DIR/issue-70594.rs:4:11
|
LL | [1; ().await];
- | ^^^^^^ `()` is not a future
+ | ^^^^^^
+ | |
+ | `()` is not a future
+ | help: remove the `.await`
|
= help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited
- = note: required because of the requirements on the impl of `IntoFuture` for `()`
-help: remove the `.await`
- |
-LL - [1; ().await];
-LL + [1; ()];
- |
+ = note: required for `()` to implement `IntoFuture`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
index 2ce7309e1..198de7bf7 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
+++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
@@ -1,18 +1,18 @@
error[E0277]: `Sender<i32>` cannot be shared between threads safely
- --> $DIR/issue-70935-complex-spans.rs:12:45
+ --> $DIR/issue-70935-complex-spans.rs:13:45
|
LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
| ^^^^^^^^^^^^^^^^^^ `Sender<i32>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Sender<i32>`
- = note: required because of the requirements on the impl of `Send` for `&Sender<i32>`
+ = note: required for `&Sender<i32>` to implement `Send`
note: required because it's used within this closure
- --> $DIR/issue-70935-complex-spans.rs:16:13
+ --> $DIR/issue-70935-complex-spans.rs:17:13
|
LL | baz(|| async{
| ^^
note: required because it's used within this `async fn` body
- --> $DIR/issue-70935-complex-spans.rs:9:67
+ --> $DIR/issue-70935-complex-spans.rs:10:67
|
LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
| ___________________________________________________________________^
@@ -20,7 +20,7 @@ LL | | }
| |_^
= note: required because it captures the following types: `ResumeTy`, `impl for<'r, 's, 't0> Future<Output = ()>`, `()`
note: required because it's used within this `async` block
- --> $DIR/issue-70935-complex-spans.rs:15:16
+ --> $DIR/issue-70935-complex-spans.rs:16:16
|
LL | async move {
| ________________^
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.normal.stderr b/src/test/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
index 2b81b4000..34b31198e 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.normal.stderr
+++ b/src/test/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
@@ -1,12 +1,12 @@
error: future cannot be sent between threads safely
- --> $DIR/issue-70935-complex-spans.rs:12:45
+ --> $DIR/issue-70935-complex-spans.rs:13:45
|
LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
| ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: the trait `Sync` is not implemented for `Sender<i32>`
note: future is not `Send` as this value is used across an await
- --> $DIR/issue-70935-complex-spans.rs:18:11
+ --> $DIR/issue-70935-complex-spans.rs:19:11
|
LL | baz(|| async{
| _____________-
@@ -14,9 +14,9 @@ LL | | foo(tx.clone());
LL | | }).await;
| | - ^^^^^^ await occurs here, with the value maybe used later
| |_________|
- | has type `[closure@$DIR/issue-70935-complex-spans.rs:16:13: 16:15]` which is not `Send`
+ | has type `[closure@$DIR/issue-70935-complex-spans.rs:17:13: 17:15]` which is not `Send`
note: the value is later dropped here
- --> $DIR/issue-70935-complex-spans.rs:18:17
+ --> $DIR/issue-70935-complex-spans.rs:19:17
|
LL | }).await;
| ^
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs
index 48847cdf9..b6d17f93a 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.rs
+++ b/src/test/ui/async-await/issue-70935-complex-spans.rs
@@ -1,5 +1,6 @@
// edition:2018
-// revisions: normal drop_tracking
+// revisions: no_drop_tracking drop_tracking
+// [no_drop_tracking]compile-flags:-Zdrop-tracking=no
// [drop_tracking]compile-flags:-Zdrop-tracking
// #70935: Check if we do not emit snippet
// with newlines which lead complex diagnostics.
@@ -10,7 +11,7 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
}
fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
- //[normal]~^ ERROR future cannot be sent between threads safely
+ //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
//[drop_tracking]~^^ ERROR `Sender<i32>` cannot be shared between threads
async move {
baz(|| async{
diff --git a/src/test/ui/async-await/issue-73137.rs b/src/test/ui/async-await/issue-73137.rs
index c43ce2cad..dcbe7765a 100644
--- a/src/test/ui/async-await/issue-73137.rs
+++ b/src/test/ui/async-await/issue-73137.rs
@@ -2,6 +2,9 @@
// run-pass
// edition:2018
+// revisions: normal drop-tracking
+// [normal]compile-flags: -Zdrop-tracking=no
+// [drop-tracking]compile-flags: -Zdrop-tracking
#![allow(dead_code)]
use std::future::Future;
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 5cbbf89a2..222afb2c7 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -28,16 +28,14 @@ error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
--> $DIR/issue-62009-1.rs:12:15
|
LL | (|_| 2333).await;
- | ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
+ | ^^^^^^
+ | |
+ | `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
+ | help: remove the `.await`
|
- = help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
+ = help: the trait `Future` is not implemented for closure `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
= note: [closure@$DIR/issue-62009-1.rs:12:6: 12:9] must be a future or must implement `IntoFuture` to be awaited
- = note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
-help: remove the `.await`
- |
-LL - (|_| 2333).await;
-LL + (|_| 2333);
- |
+ = note: required for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` to implement `IntoFuture`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
index b23093001..a72350377 100644
--- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
+++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
@@ -1,29 +1,33 @@
error: future cannot be sent between threads safely
- --> $DIR/issue-65436-raw-ptr-not-send.rs:12:5
+ --> $DIR/issue-65436-raw-ptr-not-send.rs:16:17
|
-LL | assert_send(async {
- | ^^^^^^^^^^^ future created by async block is not `Send`
+LL | assert_send(async {
+ | _________________^
+LL | |
+LL | | bar(Foo(std::ptr::null())).await;
+LL | | })
+ | |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
- --> $DIR/issue-65436-raw-ptr-not-send.rs:14:35
+ --> $DIR/issue-65436-raw-ptr-not-send.rs:18:35
|
LL | bar(Foo(std::ptr::null())).await;
| ---------------- ^^^^^^ await occurs here, with `std::ptr::null()` maybe used later
| |
| has type `*const u8` which is not `Send`
note: `std::ptr::null()` is later dropped here
- --> $DIR/issue-65436-raw-ptr-not-send.rs:14:41
+ --> $DIR/issue-65436-raw-ptr-not-send.rs:18:41
|
LL | bar(Foo(std::ptr::null())).await;
| ^
help: consider moving this into a `let` binding to create a shorter lived borrow
- --> $DIR/issue-65436-raw-ptr-not-send.rs:14:13
+ --> $DIR/issue-65436-raw-ptr-not-send.rs:18:13
|
LL | bar(Foo(std::ptr::null())).await;
| ^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `assert_send`
- --> $DIR/issue-65436-raw-ptr-not-send.rs:9:19
+ --> $DIR/issue-65436-raw-ptr-not-send.rs:13:19
|
LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send`
diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
index 3a814b475..91edbc10d 100644
--- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
+++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
@@ -1,4 +1,8 @@
// edition:2018
+// revisions: no_drop_tracking drop_tracking
+// [drop_tracking] check-pass
+// [drop_tracking] compile-flags: -Zdrop-tracking=yes
+// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
struct Foo(*const u8);
@@ -10,7 +14,7 @@ fn assert_send<T: Send>(_: T) {}
fn main() {
assert_send(async {
- //~^ ERROR future cannot be sent between threads safely
+ //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
bar(Foo(std::ptr::null())).await;
})
}
diff --git a/src/test/ui/async-await/issues/issue-95307.stderr b/src/test/ui/async-await/issues/issue-95307.stderr
index 60fca71eb..1c12f1e48 100644
--- a/src/test/ui/async-await/issues/issue-95307.stderr
+++ b/src/test/ui/async-await/issues/issue-95307.stderr
@@ -8,6 +8,14 @@ LL | async fn new() -> [u8; _];
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+ --> $DIR/issue-95307.rs:7:28
+ |
+LL | async fn new() -> [u8; _];
+ | ^ `_` not allowed here
error[E0658]: using `_` for array lengths is unstable
--> $DIR/issue-95307.rs:7:28
@@ -18,12 +26,6 @@ LL | async fn new() -> [u8; _];
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
-error: in expressions, `_` can only be used on the left-hand side of an assignment
- --> $DIR/issue-95307.rs:7:28
- |
-LL | async fn new() -> [u8; _];
- | ^ `_` not allowed here
-
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0658, E0706.
diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
new file mode 100644
index 000000000..17b4ef7bd
--- /dev/null
+++ b/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
@@ -0,0 +1,35 @@
+error[E0277]: `NotSend` cannot be sent between threads safely
+ --> $DIR/partial-drop-partial-reinit.rs:9:16
+ |
+LL | gimme_send(foo());
+ | ---------- ^^^^^ `NotSend` cannot be sent between threads safely
+ | |
+ | required by a bound introduced by this call
+...
+LL | async fn foo() {
+ | - within this `impl Future<Output = ()>`
+ |
+ = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
+ = note: required because it appears within the type `(NotSend,)`
+ = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `()`, `impl Future<Output = ()>`
+note: required because it's used within this `async fn` body
+ --> $DIR/partial-drop-partial-reinit.rs:31:16
+ |
+LL | async fn foo() {
+ | ________________^
+LL | |
+LL | |
+LL | | let mut x = (NotSend {},);
+... |
+LL | | bar().await;
+LL | | }
+ | |_^
+note: required by a bound in `gimme_send`
+ --> $DIR/partial-drop-partial-reinit.rs:17:18
+ |
+LL | fn gimme_send<T: Send>(t: T) {
+ | ^^^^ required by this bound in `gimme_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr
index 05f535834..34d8a159f 100644
--- a/src/test/ui/async-await/partial-drop-partial-reinit.stderr
+++ b/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr
@@ -1,5 +1,5 @@
error[E0277]: `NotSend` cannot be sent between threads safely
- --> $DIR/partial-drop-partial-reinit.rs:6:16
+ --> $DIR/partial-drop-partial-reinit.rs:9:16
|
LL | gimme_send(foo());
| ---------- ^^^^^ `NotSend` cannot be sent between threads safely
@@ -13,7 +13,7 @@ LL | async fn foo() {
= note: required because it appears within the type `(NotSend,)`
= note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future<Output = ()>`, `()`
note: required because it's used within this `async fn` body
- --> $DIR/partial-drop-partial-reinit.rs:28:16
+ --> $DIR/partial-drop-partial-reinit.rs:31:16
|
LL | async fn foo() {
| ________________^
@@ -25,7 +25,7 @@ LL | | bar().await;
LL | | }
| |_^
note: required by a bound in `gimme_send`
- --> $DIR/partial-drop-partial-reinit.rs:14:18
+ --> $DIR/partial-drop-partial-reinit.rs:17:18
|
LL | fn gimme_send<T: Send>(t: T) {
| ^^^^ required by this bound in `gimme_send`
diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.rs b/src/test/ui/async-await/partial-drop-partial-reinit.rs
index fe0fce7af..7d097e72f 100644
--- a/src/test/ui/async-await/partial-drop-partial-reinit.rs
+++ b/src/test/ui/async-await/partial-drop-partial-reinit.rs
@@ -1,4 +1,7 @@
// edition:2021
+// revisions: no_drop_tracking drop_tracking
+// [drop_tracking] compile-flags: -Zdrop-tracking=yes
+// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
#![feature(negative_impls)]
#![allow(unused)]
@@ -12,8 +15,8 @@ fn main() {
}
fn gimme_send<T: Send>(t: T) {
-//~^ NOTE required by this bound
-//~| NOTE required by a bound
+ //~^ NOTE required by this bound
+ //~| NOTE required by a bound
drop(t);
}
@@ -26,8 +29,8 @@ impl Drop for NotSend {
impl !Send for NotSend {}
async fn foo() {
-//~^ NOTE used within this `async fn` body
-//~| NOTE within this `impl Future
+ //~^ NOTE used within this `async fn` body
+ //~| NOTE within this `impl Future
let mut x = (NotSend {},);
drop(x.0);
x.0 = NotSend {};
diff --git a/src/test/ui/async-await/unnecessary-await.stderr b/src/test/ui/async-await/unnecessary-await.stderr
index e7e61c2ba..dc3089336 100644
--- a/src/test/ui/async-await/unnecessary-await.stderr
+++ b/src/test/ui/async-await/unnecessary-await.stderr
@@ -8,7 +8,7 @@ LL | boo().await;
|
= help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited
- = note: required because of the requirements on the impl of `IntoFuture` for `()`
+ = note: required for `()` to implement `IntoFuture`
help: remove the `.await`
|
LL - boo().await;
diff --git a/src/test/ui/attempted-access-non-fatal.rs b/src/test/ui/attempted-access-non-fatal.rs
index e50c1f23c..15deb9e2f 100644
--- a/src/test/ui/attempted-access-non-fatal.rs
+++ b/src/test/ui/attempted-access-non-fatal.rs
@@ -3,4 +3,8 @@ fn main() {
let x = 0;
let _ = x.foo; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
let _ = x.bar; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+ let _ = 0.f; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+ let _ = 2.l; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+ let _ = 12.F; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+ let _ = 34.L; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
}
diff --git a/src/test/ui/attempted-access-non-fatal.stderr b/src/test/ui/attempted-access-non-fatal.stderr
index 5b7db0e9d..bff669727 100644
--- a/src/test/ui/attempted-access-non-fatal.stderr
+++ b/src/test/ui/attempted-access-non-fatal.stderr
@@ -10,6 +10,50 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | let _ = x.bar;
| ^^^
-error: aborting due to 2 previous errors
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/attempted-access-non-fatal.rs:6:15
+ |
+LL | let _ = 0.f;
+ | ^
+ |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f32` suffix
+ |
+LL | let _ = 0.0f32;
+ | ~~~~
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/attempted-access-non-fatal.rs:7:15
+ |
+LL | let _ = 2.l;
+ | ^
+ |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
+ |
+LL | let _ = 2.0f64;
+ | ~~~~
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/attempted-access-non-fatal.rs:8:16
+ |
+LL | let _ = 12.F;
+ | ^
+ |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f32` suffix
+ |
+LL | let _ = 12.0f32;
+ | ~~~~
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/attempted-access-non-fatal.rs:9:16
+ |
+LL | let _ = 34.L;
+ | ^
+ |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
+ |
+LL | let _ = 34.0f64;
+ | ~~~~
+
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0610`.
diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.rs b/src/test/ui/attributes/collapse-debuginfo-invalid.rs
new file mode 100644
index 000000000..42d8982c1
--- /dev/null
+++ b/src/test/ui/attributes/collapse-debuginfo-invalid.rs
@@ -0,0 +1,110 @@
+#![feature(collapse_debuginfo)]
+#![feature(stmt_expr_attributes)]
+#![feature(type_alias_impl_trait)]
+#![no_std]
+
+// Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions.
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+extern crate std;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+use std::collections::HashMap;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+static FOO: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+const BAR: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+fn foo() {
+ let _ = #[collapse_debuginfo] || { };
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ let _ = 3;
+ let _ = #[collapse_debuginfo] 3;
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ match (3, 4) {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ _ => (),
+ }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+mod bar {
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type Map = HashMap<u32, u32>;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+enum Foo {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ Variant,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+struct Bar {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ field: u32,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+union Qux {
+ a: u32,
+ b: u16
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+trait Foobar {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ type Bar;
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type AFoobar = impl Foobar;
+
+impl Foobar for Bar {
+ type Bar = u32;
+}
+
+fn constraining() -> AFoobar {
+ Bar { field: 3 }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+impl Bar {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ const FOO: u32 = 3;
+
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ fn bar(&self) {}
+}
+
+#[collapse_debuginfo]
+macro_rules! finally {
+ ($e:expr) => { $e }
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.stderr b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr
new file mode 100644
index 000000000..01c476091
--- /dev/null
+++ b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -0,0 +1,222 @@
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:8:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | extern crate std;
+ | ----------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:12:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | use std::collections::HashMap;
+ | ------------------------------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:16:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | static FOO: u32 = 3;
+ | -------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:20:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const BAR: u32 = 3;
+ | ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:24:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / fn foo() {
+LL | | let _ = #[collapse_debuginfo] || { };
+LL | |
+LL | | #[collapse_debuginfo]
+... |
+LL | | }
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:27:13
+ |
+LL | let _ = #[collapse_debuginfo] || { };
+ | ^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:29:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | let _ = 3;
+ | ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:32:13
+ |
+LL | let _ = #[collapse_debuginfo] 3;
+ | ^^^^^^^^^^^^^^^^^^^^^ - not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:35:9
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | _ => (),
+ | ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:41:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / mod bar {
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:46:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type Map = HashMap<u32, u32>;
+ | ----------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:50:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / enum Foo {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | Variant,
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:53:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | Variant,
+ | ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:58:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / struct Bar {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | field: u32,
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:61:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | field: u32,
+ | ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:66:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / union Qux {
+LL | | a: u32,
+LL | | b: u16
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:73:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / trait Foobar {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | type Bar;
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:81:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type AFoobar = impl Foobar;
+ | --------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:93:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / impl Bar {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | const FOO: u32 = 3;
+... |
+LL | | fn bar(&self) {}
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:76:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type Bar;
+ | --------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:96:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const FOO: u32 = 3;
+ | ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:100:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | fn bar(&self) {}
+ | ---------------- not a macro definition
+
+error: aborting due to 22 previous errors
+
diff --git a/src/test/ui/attributes/issue-100631.rs b/src/test/ui/attributes/issue-100631.rs
new file mode 100644
index 000000000..0fefcf83f
--- /dev/null
+++ b/src/test/ui/attributes/issue-100631.rs
@@ -0,0 +1,8 @@
+// issue #100631, make sure `TyCtxt::get_attr` only called by case that compiler
+// can reasonably deal with multiple attributes.
+// `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`.
+#[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084]
+#[repr(C)]
+enum Foo {}
+
+fn main() {}
diff --git a/src/test/ui/attributes/issue-100631.stderr b/src/test/ui/attributes/issue-100631.stderr
new file mode 100644
index 000000000..caa5351dd
--- /dev/null
+++ b/src/test/ui/attributes/issue-100631.stderr
@@ -0,0 +1,12 @@
+error[E0084]: unsupported representation for zero-variant enum
+ --> $DIR/issue-100631.rs:4:1
+ |
+LL | #[repr(C)]
+ | ^^^^^^^^^^
+LL | #[repr(C)]
+LL | enum Foo {}
+ | -------- zero-variant enum
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0084`.
diff --git a/src/test/ui/attributes/issue-90873.stderr b/src/test/ui/attributes/issue-90873.stderr
index 0852bb7ca..894ec8341 100644
--- a/src/test/ui/attributes/issue-90873.stderr
+++ b/src/test/ui/attributes/issue-90873.stderr
@@ -34,10 +34,10 @@ LL | #![a={impl std::ops::Neg for i8 {}}]
| ^ consider adding a `main` function to `$DIR/issue-90873.rs`
error: missing type for `static` item
- --> $DIR/issue-90873.rs:1:16
+ --> $DIR/issue-90873.rs:1:17
|
LL | #![u=||{static d=||1;}]
- | ^ help: provide a type for the item: `d: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to 6 previous errors
diff --git a/src/test/ui/attributes/register-attr-tool-fail.rs b/src/test/ui/attributes/register-attr-tool-fail.rs
deleted file mode 100644
index 84736be84..000000000
--- a/src/test/ui/attributes/register-attr-tool-fail.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![feature(register_attr)]
-#![feature(register_tool)]
-
-#![register_attr] //~ ERROR malformed `register_attr` attribute input
-#![register_tool] //~ ERROR malformed `register_tool` attribute input
-
-#![register_attr(a::b)] //~ ERROR `register_attr` only accepts identifiers
-#![register_tool(a::b)] //~ ERROR `register_tool` only accepts identifiers
-
-#![register_attr(attr, attr)] //~ ERROR attribute `attr` was already registered
-#![register_tool(tool, tool)] //~ ERROR tool `tool` was already registered
-
-fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-fail.stderr b/src/test/ui/attributes/register-attr-tool-fail.stderr
deleted file mode 100644
index 8f6977cb5..000000000
--- a/src/test/ui/attributes/register-attr-tool-fail.stderr
+++ /dev/null
@@ -1,42 +0,0 @@
-error: `register_attr` only accepts identifiers
- --> $DIR/register-attr-tool-fail.rs:7:18
- |
-LL | #![register_attr(a::b)]
- | ^^^^ not an identifier
-
-error: attribute `attr` was already registered
- --> $DIR/register-attr-tool-fail.rs:10:24
- |
-LL | #![register_attr(attr, attr)]
- | ---- ^^^^
- | |
- | already registered here
-
-error: `register_tool` only accepts identifiers
- --> $DIR/register-attr-tool-fail.rs:8:18
- |
-LL | #![register_tool(a::b)]
- | ^^^^ not an identifier
-
-error: tool `tool` was already registered
- --> $DIR/register-attr-tool-fail.rs:11:24
- |
-LL | #![register_tool(tool, tool)]
- | ---- ^^^^
- | |
- | already registered here
-
-error: malformed `register_attr` attribute input
- --> $DIR/register-attr-tool-fail.rs:4:1
- |
-LL | #![register_attr]
- | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_attr(attr1, attr2, ...)]`
-
-error: malformed `register_tool` attribute input
- --> $DIR/register-attr-tool-fail.rs:5:1
- |
-LL | #![register_tool]
- | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_tool(tool1, tool2, ...)]`
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/attributes/register-attr-tool-import.rs b/src/test/ui/attributes/register-attr-tool-import.rs
deleted file mode 100644
index d3502c71f..000000000
--- a/src/test/ui/attributes/register-attr-tool-import.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// edition:2018
-// compile-flags: -Zsave-analysis
-// ~^ Also regression test for #69588
-
-#![feature(register_attr)]
-#![feature(register_tool)]
-
-#![register_attr(attr)]
-#![register_tool(tool)]
-
-use attr as renamed_attr; // OK
-use tool as renamed_tool; // OK
-
-#[renamed_attr] //~ ERROR cannot use an explicitly registered attribute through an import
-#[renamed_tool::attr] //~ ERROR cannot use a tool module through an import
- //~| ERROR cannot use a tool module through an import
-fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-import.stderr b/src/test/ui/attributes/register-attr-tool-import.stderr
deleted file mode 100644
index 90b7e169a..000000000
--- a/src/test/ui/attributes/register-attr-tool-import.stderr
+++ /dev/null
@@ -1,38 +0,0 @@
-error: cannot use an explicitly registered attribute through an import
- --> $DIR/register-attr-tool-import.rs:14:3
- |
-LL | #[renamed_attr]
- | ^^^^^^^^^^^^
- |
-note: the explicitly registered attribute imported here
- --> $DIR/register-attr-tool-import.rs:11:5
- |
-LL | use attr as renamed_attr; // OK
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: cannot use a tool module through an import
- --> $DIR/register-attr-tool-import.rs:15:3
- |
-LL | #[renamed_tool::attr]
- | ^^^^^^^^^^^^
- |
-note: the tool module imported here
- --> $DIR/register-attr-tool-import.rs:12:5
- |
-LL | use tool as renamed_tool; // OK
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: cannot use a tool module through an import
- --> $DIR/register-attr-tool-import.rs:15:3
- |
-LL | #[renamed_tool::attr]
- | ^^^^^^^^^^^^
- |
-note: the tool module imported here
- --> $DIR/register-attr-tool-import.rs:12:5
- |
-LL | use tool as renamed_tool; // OK
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/attributes/register-attr-tool-prelude.rs b/src/test/ui/attributes/register-attr-tool-prelude.rs
deleted file mode 100644
index d217a8146..000000000
--- a/src/test/ui/attributes/register-attr-tool-prelude.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#![feature(register_attr)]
-#![feature(register_tool)]
-
-#![register_attr(attr)]
-#![register_tool(tool)]
-
-#[no_implicit_prelude]
-mod m {
- #[attr] //~ ERROR cannot find attribute `attr` in this scope
- #[tool::attr] //~ ERROR failed to resolve: use of undeclared crate or module `tool`
- fn check() {}
-}
-
-fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-prelude.stderr b/src/test/ui/attributes/register-attr-tool-prelude.stderr
deleted file mode 100644
index 905b66120..000000000
--- a/src/test/ui/attributes/register-attr-tool-prelude.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0433]: failed to resolve: use of undeclared crate or module `tool`
- --> $DIR/register-attr-tool-prelude.rs:10:7
- |
-LL | #[tool::attr]
- | ^^^^ use of undeclared crate or module `tool`
-
-error: cannot find attribute `attr` in this scope
- --> $DIR/register-attr-tool-prelude.rs:9:7
- |
-LL | #[attr]
- | ^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/attributes/register-attr-tool-unused.rs b/src/test/ui/attributes/register-attr-tool-unused.rs
deleted file mode 100644
index 680614656..000000000
--- a/src/test/ui/attributes/register-attr-tool-unused.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![deny(unused)]
-
-#![feature(register_attr)]
-#![feature(register_tool)]
-
-#[register_attr(attr)] //~ ERROR crate-level attribute should be an inner attribute
-#[register_tool(tool)] //~ ERROR crate-level attribute should be an inner attribute
-fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-unused.stderr b/src/test/ui/attributes/register-attr-tool-unused.stderr
deleted file mode 100644
index 8d2e1b6bc..000000000
--- a/src/test/ui/attributes/register-attr-tool-unused.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/register-attr-tool-unused.rs:6:1
- |
-LL | #[register_attr(attr)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/register-attr-tool-unused.rs:1:9
- |
-LL | #![deny(unused)]
- | ^^^^^^
- = note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]`
-
-error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/register-attr-tool-unused.rs:7:1
- |
-LL | #[register_tool(tool)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/attributes/register-attr-tool.rs b/src/test/ui/attributes/register-attr-tool.rs
deleted file mode 100644
index ee9da74d4..000000000
--- a/src/test/ui/attributes/register-attr-tool.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// check-pass
-// compile-flags: --cfg foo
-
-#![feature(register_attr)]
-#![feature(register_tool)]
-
-#![register_attr(attr)]
-#![register_tool(tool)]
-#![register_tool(rustfmt, clippy)] // OK
-#![cfg_attr(foo, register_attr(conditional_attr))]
-#![cfg_attr(foo, register_tool(conditional_tool))]
-
-#[attr]
-#[tool::attr]
-#[rustfmt::attr]
-#[clippy::attr]
-#[conditional_attr]
-#[conditional_tool::attr]
-fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs b/src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
new file mode 100644
index 000000000..e8b4fe7ae
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
@@ -0,0 +1,31 @@
+#![feature(rustc_private)]
+extern crate libc;
+
+/// So tests don't have to bring libc in scope themselves
+pub enum SignalHandler {
+ Ignore,
+ Default,
+}
+
+/// Helper to assert that [`libc::SIGPIPE`] has the expected signal handler.
+pub fn assert_sigpipe_handler(expected_handler: SignalHandler) {
+ #[cfg(unix)]
+ #[cfg(not(any(
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "horizon",
+ target_os = "android",
+ )))]
+ {
+ let prev = unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN) };
+
+ let expected = match expected_handler {
+ SignalHandler::Ignore => libc::SIG_IGN,
+ SignalHandler::Default => libc::SIG_DFL,
+ };
+ assert_eq!(prev, expected);
+
+ // Unlikely to matter, but restore the old value anyway
+ unsafe { libc::signal(libc::SIGPIPE, prev); };
+ }
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
new file mode 100644
index 000000000..d6d020c52
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+#![unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute cannot be used at crate level
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
new file mode 100644
index 000000000..a1fb4d678
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
@@ -0,0 +1,13 @@
+error: `unix_sigpipe` attribute cannot be used at crate level
+ --> $DIR/unix_sigpipe-crate.rs:2:1
+ |
+LL | #![unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: perhaps you meant to use an outer attribute
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
new file mode 100644
index 000000000..294cb3852
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
@@ -0,0 +1,5 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_ign"]
+#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
new file mode 100644
index 000000000..2362c17a0
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
@@ -0,0 +1,14 @@
+error: multiple `unix_sigpipe` attributes
+ --> $DIR/unix_sigpipe-duplicates.rs:4:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unix_sigpipe-duplicates.rs:3:1
+ |
+LL | #[unix_sigpipe = "sig_ign"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs
new file mode 100644
index 000000000..0a42a5b5e
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_ign"]
+fn main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "sig_ign"] is active, so the legacy behavior of ignoring
+ // SIGPIPE shall be in effect
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
new file mode 100644
index 000000000..4f8648077
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"]
+fn main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "inherit"] is active, so SIGPIPE shall NOT be ignored,
+ // instead the default handler shall be installed. (We assume that the
+ // process that runs these tests have the default handler.)
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs
new file mode 100644
index 000000000..b5ebc07a0
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe(inherit)] //~ error: malformed `unix_sigpipe` attribute input
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr
new file mode 100644
index 000000000..59a87e139
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr
@@ -0,0 +1,15 @@
+error: malformed `unix_sigpipe` attribute input
+ --> $DIR/unix_sigpipe-list.rs:3:1
+ |
+LL | #[unix_sigpipe(inherit)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: the following are the possible correct uses
+ |
+LL | #[unix_sigpipe = "inherit|sig_ign|sig_dfl"]
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | #[unix_sigpipe]
+ | ~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
new file mode 100644
index 000000000..cde6719fc
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
@@ -0,0 +1,6 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+fn f() {}
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
new file mode 100644
index 000000000..c4b81118c
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+ --> $DIR/unix_sigpipe-non-main-fn.rs:3:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
new file mode 100644
index 000000000..16f727639
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
@@ -0,0 +1,8 @@
+#![feature(unix_sigpipe)]
+
+mod m {
+ #[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on root `fn main()`
+ fn main() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
new file mode 100644
index 000000000..a04f605ed
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on root `fn main()`
+ --> $DIR/unix_sigpipe-non-root-main.rs:4:5
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
new file mode 100644
index 000000000..100b4ce9f
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
@@ -0,0 +1,9 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+fn main() {
+ extern crate sigpipe_utils;
+
+ // SIGPIPE shall be ignored since #[unix_sigpipe = "..."] is not used
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs
new file mode 100644
index 000000000..b5adc2e55
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+fn main() {
+ extern crate sigpipe_utils;
+
+ // Only #![feature(unix_sigpipe)] is enabled, not #[unix_sigpipe = "..."].
+ // This shall not change any behavior, so we still expect SIGPIPE to be
+ // ignored
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
new file mode 100644
index 000000000..6befb9e95
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
@@ -0,0 +1,15 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+#![feature(rustc_attrs)]
+
+#[unix_sigpipe = "sig_dfl"]
+#[rustc_main]
+fn rustc_main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE handler shall be
+ // SIG_DFL. Note that we have a #[rustc_main], but it should still work.
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
new file mode 100644
index 000000000..238c0d57a
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_dfl"]
+fn main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE shall NOT be ignored, instead
+ // the default handler shall be installed
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
new file mode 100644
index 000000000..64fd5ec4f
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
@@ -0,0 +1,6 @@
+#![feature(start)]
+#![feature(unix_sigpipe)]
+
+#[start]
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+fn custom_start(argc: isize, argv: *const *const u8) -> isize { 0 }
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
new file mode 100644
index 000000000..2c9ce479b
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+ --> $DIR/unix_sigpipe-start.rs:5:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
new file mode 100644
index 000000000..a5e47cfeb
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
@@ -0,0 +1,6 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+struct S;
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
new file mode 100644
index 000000000..c56ee60bb
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+ --> $DIR/unix_sigpipe-struct.rs:3:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
new file mode 100644
index 000000000..4ec25de00
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "wrong"] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
new file mode 100644
index 000000000..a66e45aa2
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
@@ -0,0 +1,8 @@
+error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+ --> $DIR/unix_sigpipe-wrong.rs:3:1
+ |
+LL | #[unix_sigpipe = "wrong"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs
new file mode 100644
index 000000000..7bf1c7350
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr
new file mode 100644
index 000000000..1b1eda825
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr
@@ -0,0 +1,8 @@
+error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+ --> $DIR/unix_sigpipe.rs:3:1
+ |
+LL | #[unix_sigpipe]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr
index eb8447ff0..e28830507 100644
--- a/src/test/ui/auto-ref-slice-plus-ref.stderr
+++ b/src/test/ui/auto-ref-slice-plus-ref.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in th
--> $DIR/auto-ref-slice-plus-ref.rs:7:7
|
LL | a.test_mut();
- | ^^^^^^^^ help: there is an associated function with a similar name: `get_mut`
+ | ^^^^^^^^ help: there is a method with a similar name: `get_mut`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `MyIter` defines an item `test_mut`, perhaps you need to implement it
diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr
index 7d6bf58f5..0c4970a72 100644
--- a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr
+++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)`
- --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5
+ --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:18
|
LL | is_mytrait::<(MyS2, MyS)>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
+ | ^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
|
= note: required because it appears within the type `(MyS2, MyS)`
note: required by a bound in `is_mytrait`
diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
index 985cdce12..ce7095664 100644
--- a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
+++ b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `u32: Signed` is not satisfied
- --> $DIR/typeck-default-trait-impl-precedence.rs:19:5
+ --> $DIR/typeck-default-trait-impl-precedence.rs:19:20
|
LL | is_defaulted::<&'static u32>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
+ | ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
|
= help: the trait `Signed` is implemented for `i32`
-note: required because of the requirements on the impl of `Defaulted` for `&'static u32`
+note: required for `&'static u32` to implement `Defaulted`
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
|
LL | impl<'a,T:Signed> Defaulted for &'a T { }
diff --git a/src/test/ui/backtrace-apple-no-dsymutil.rs b/src/test/ui/backtrace-apple-no-dsymutil.rs
index d32ad11a1..3844ebcfd 100644
--- a/src/test/ui/backtrace-apple-no-dsymutil.rs
+++ b/src/test/ui/backtrace-apple-no-dsymutil.rs
@@ -4,8 +4,6 @@
// compile-flags:-g -Csplit-debuginfo=unpacked
// only-macos
-#![feature(backtrace)]
-
use std::process::Command;
use std::str;
diff --git a/src/test/ui/binop/binary-op-on-double-ref.stderr b/src/test/ui/binop/binary-op-on-double-ref.stderr
index 1651f70d5..34826d2f4 100644
--- a/src/test/ui/binop/binary-op-on-double-ref.stderr
+++ b/src/test/ui/binop/binary-op-on-double-ref.stderr
@@ -6,7 +6,7 @@ LL | x % 2 == 0
| |
| &&{integer}
|
-help: `%` can be used on `{integer}`, you can dereference `x`
+help: `%` can be used on `&{integer}` if you dereference the left-hand side
|
LL | *x % 2 == 0
| +
diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr
index 68303b842..097a14f26 100644
--- a/src/test/ui/binop/issue-77910-1.stderr
+++ b/src/test/ui/binop/issue-77910-1.stderr
@@ -18,7 +18,7 @@ LL | fn foo(s: &i32) -> &i32 {
LL | assert_eq!(foo, y);
| ^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}`
+ = help: the trait `Debug` is not implemented for fn item `for<'r> fn(&'r i32) -> &'r i32 {foo}`
= help: use parentheses to call the function: `foo(s)`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/test/ui/binop/issue-77910-2.stderr b/src/test/ui/binop/issue-77910-2.stderr
index 5477a5762..a334bd856 100644
--- a/src/test/ui/binop/issue-77910-2.stderr
+++ b/src/test/ui/binop/issue-77910-2.stderr
@@ -5,6 +5,11 @@ LL | if foo == y {}
| --- ^^ - _
| |
| for<'r> fn(&'r i32) -> &'r i32 {foo}
+ |
+help: use parentheses to call this function
+ |
+LL | if foo(/* &i32 */) == y {}
+ | ++++++++++++
error: aborting due to previous error
diff --git a/src/test/ui/block-result/issue-22645.stderr b/src/test/ui/block-result/issue-22645.stderr
index 31663e8e8..28debd60a 100644
--- a/src/test/ui/block-result/issue-22645.stderr
+++ b/src/test/ui/block-result/issue-22645.stderr
@@ -5,7 +5,7 @@ LL | b + 3
| ^ the trait `Scalar` is not implemented for `{integer}`
|
= help: the trait `Scalar` is implemented for `f64`
-note: required because of the requirements on the impl of `Add<{integer}>` for `Bob`
+note: required for `Bob` to implement `Add<{integer}>`
--> $DIR/issue-22645.rs:8:19
|
LL | impl<RHS: Scalar> Add <RHS> for Bob {
diff --git a/src/test/ui/block-result/issue-3563.stderr b/src/test/ui/block-result/issue-3563.stderr
index 5255e48be..be551f6e8 100644
--- a/src/test/ui/block-result/issue-3563.stderr
+++ b/src/test/ui/block-result/issue-3563.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `b` found for reference `&Self` in the current sco
--> $DIR/issue-3563.rs:3:17
|
LL | || self.b()
- | ^ help: there is an associated function with a similar name: `a`
+ | ^ help: there is a method with a similar name: `a`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr
index d4f819308..1fd1eb128 100644
--- a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr
+++ b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr
@@ -23,7 +23,7 @@ LL | fn bindings_after_at_slice_patterns_move_binding(x: [String; 4]) {
| - move occurs because `x` has type `[String; 4]`, which does not implement the `Copy` trait
LL | match x {
LL | a @ [.., _] => (),
- | ----------- value moved here
+ | - value moved here
...
LL | &x;
| ^^ value borrowed here after move
@@ -32,7 +32,7 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as muta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:28:5
|
LL | ref mut foo @ [.., _] => Some(foo),
- | --------------------- mutable borrow occurs here
+ | ----------- mutable borrow occurs here
...
LL | &x;
| ^^ immutable borrow occurs here
@@ -44,7 +44,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:50:5
|
LL | [ref foo @ .., ref bar] => Some(foo),
- | ------------ immutable borrow occurs here
+ | ------- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -56,7 +56,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:62:5
|
LL | ref foo @ [.., ref bar] => Some(foo),
- | ----------------------- immutable borrow occurs here
+ | ------- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -71,7 +71,7 @@ LL | fn bindings_after_at_or_patterns_move(x: Option<Test>) {
| - move occurs because `x` has type `Option<Test>`, which does not implement the `Copy` trait
LL | match x {
LL | foo @ Some(Test::Foo | Test::Bar) => (),
- | ---------------------------------
+ | ---
| |
| value moved here
| value moved here
@@ -83,7 +83,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:86:5
|
LL | ref foo @ Some(Test::Foo | Test::Bar) => Some(foo),
- | ------------------------------------- immutable borrow occurs here
+ | ------- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -95,7 +95,7 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as muta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:98:5
|
LL | ref mut foo @ Some(Test::Foo | Test::Bar) => Some(foo),
- | ----------------------------------------- mutable borrow occurs here
+ | ----------- mutable borrow occurs here
...
LL | &x;
| ^^ immutable borrow occurs here
@@ -107,7 +107,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:112:5
|
LL | ref foo @ Some(box ref s) => Some(foo),
- | ------------------------- immutable borrow occurs here
+ | ------- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -122,7 +122,7 @@ LL | fn bindings_after_at_slice_patterns_or_patterns_moves(x: [Option<Test>; 4])
| - move occurs because `x` has type `[Option<Test>; 4]`, which does not implement the `Copy` trait
LL | match x {
LL | a @ [.., Some(Test::Foo | Test::Bar)] => (),
- | -------------------------------------
+ | -
| |
| value moved here
| value moved here
@@ -134,7 +134,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:144:5
|
LL | ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(a),
- | ------------------------------------------------- immutable borrow occurs here
+ | ----- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -146,7 +146,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:156:5
|
LL | ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(b),
- | ---------- immutable borrow occurs here
+ | ----- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -158,7 +158,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:170:5
|
LL | [_, ref a @ Some(box ref b), ..] => Some(a),
- | ----------------------- immutable borrow occurs here
+ | ----- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -170,7 +170,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:186:5
|
LL | [_, ref a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a),
- | ------------------------------------------- immutable borrow occurs here
+ | ----- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
@@ -182,7 +182,7 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as muta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:200:5
|
LL | [_, ref mut a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a),
- | ----------------------------------------------- mutable borrow occurs here
+ | --------- mutable borrow occurs here
...
LL | &x;
| ^^ immutable borrow occurs here
@@ -194,7 +194,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:214:5
|
LL | ref a @ [_, ref b @ Some(box Test::Foo | box Test::Bar), ..] => Some(a),
- | ------------------------------------------------------------ immutable borrow occurs here
+ | ----- immutable borrow occurs here
...
LL | &mut x;
| ^^^^^^ mutable borrow occurs here
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
index f909dbc40..2c1b9c10d 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -36,6 +36,10 @@ LL | | }
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
+help: consider adding 'move' keyword before the nested closure
+ |
+LL | move || {
+ | ++++
error[E0503]: cannot use `f.x` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:37:9
@@ -196,7 +200,7 @@ LL | let x = &mut v;
| ------ borrow of `v` occurs here
LL | match v {
LL | &[x @ ..] => println!("{:?}", x),
- | ^^^^^^ use of borrowed `v`
+ | ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
@@ -208,7 +212,7 @@ LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | &[_, x @ ..] => println!("{:?}", x),
- | ^^^^^^ use of borrowed `v`
+ | ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
@@ -220,7 +224,7 @@ LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | &[x @ .., _] => println!("{:?}", x),
- | ^^^^^^ use of borrowed `v`
+ | ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
@@ -232,7 +236,7 @@ LL | let x = &mut v;
| ------ borrow of `v` occurs here
...
LL | &[_, x @ .., _] => println!("{:?}", x),
- | ^^^^^^ use of borrowed `v`
+ | ^ use of borrowed `v`
...
LL | drop(x);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
index 3249aae8f..346b82a26 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
@@ -79,7 +79,7 @@ error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-match.rs:89:11
|
LL | [_y @ .., _, _] => {}
- | ------- value moved here
+ | -- value moved here
...
LL | [(_x, _), _, _] => {}
| ^^ value used here after move
@@ -90,7 +90,7 @@ error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-match.rs:99:15
|
LL | [_, _, _y @ ..] => {}
- | ------- value moved here
+ | -- value moved here
...
LL | [.., (_x, _)] => {}
| ^^ value used here after move
@@ -101,7 +101,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-match.rs:110:11
|
LL | [x @ .., _] => {}
- | ------ value partially moved here
+ | - value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
index c19800226..6c6a25c25 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
@@ -68,7 +68,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11
|
LL | [_, _y @ ..] => {}
- | ------- value partially moved here
+ | -- value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
@@ -79,7 +79,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11
|
LL | [_y @ .., _] => {}
- | ------- value partially moved here
+ | -- value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
@@ -90,7 +90,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11
|
LL | [x @ .., _, _] => {}
- | ------ value partially moved here
+ | - value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
index 8f2da9d20..77702e145 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
@@ -79,7 +79,7 @@ error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use-match.rs:89:11
|
LL | [_y @ .., _, _] => {}
- | ------- value moved here
+ | -- value moved here
...
LL | [(ref _x, _), _, _] => {}
| ^^^^^^ value borrowed here after move
@@ -90,7 +90,7 @@ error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use-match.rs:99:15
|
LL | [_, _, _y @ ..] => {}
- | ------- value moved here
+ | -- value moved here
...
LL | [.., (ref _x, _)] => {}
| ^^^^^^ value borrowed here after move
@@ -101,7 +101,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:110:11
|
LL | [x @ .., _] => {}
- | ------ value partially moved here
+ | - value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
@@ -134,7 +134,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:139:5
|
LL | [_, _, _x @ ..] => {}
- | ------- value partially moved here
+ | -- value partially moved here
LL | }
LL | a[0] = Default::default();
| ^^^^ value used here after partial move
@@ -145,7 +145,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:147:5
|
LL | [_, _, _x @ ..] => {}
- | ------- value partially moved here
+ | -- value partially moved here
LL | }
LL | a[0].1 = Default::default();
| ^^^^ value used here after partial move
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
index 4b27f03dc..6cc2c2f7a 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
@@ -68,7 +68,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11
|
LL | [_, _y @ ..] => {}
- | ------- value partially moved here
+ | -- value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
@@ -79,7 +79,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11
|
LL | [_y @ .., _] => {}
- | ------- value partially moved here
+ | -- value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
@@ -90,7 +90,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11
|
LL | [x @ .., _, _] => {}
- | ------ value partially moved here
+ | - value partially moved here
LL | }
LL | match a {
| ^ value used here after partial move
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
index b0bad6e99..9add7553a 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
@@ -34,7 +34,7 @@ error[E0382]: borrow of partially moved value: `a`
LL | let [_x, _, _] = a;
| -- value partially moved here
LL | let [ref _y @ .., _, _] = a;
- | ^^^^^^^^^^^ value borrowed here after partial move
+ | ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
@@ -44,7 +44,7 @@ error[E0382]: borrow of partially moved value: `a`
LL | let [.., _x] = a;
| -- value partially moved here
LL | let [_, _, ref _y @ ..] = a;
- | ^^^^^^^^^^^ value borrowed here after partial move
+ | ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
@@ -54,7 +54,7 @@ error[E0382]: borrow of partially moved value: `a`
LL | let [(_x, _), _, _] = a;
| -- value partially moved here
LL | let [ref _y @ .., _, _] = a;
- | ^^^^^^^^^^^ value borrowed here after partial move
+ | ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
@@ -64,7 +64,7 @@ error[E0382]: borrow of partially moved value: `a`
LL | let [.., (_x, _)] = a;
| -- value partially moved here
LL | let [_, _, ref _y @ ..] = a;
- | ^^^^^^^^^^^ value borrowed here after partial move
+ | ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
@@ -72,7 +72,7 @@ error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use.rs:54:11
|
LL | let [_y @ .., _, _] = a;
- | ------- value moved here
+ | -- value moved here
LL | let [(ref _x, _), _, _] = a;
| ^^^^^^ value borrowed here after move
|
@@ -82,7 +82,7 @@ error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use.rs:60:15
|
LL | let [_, _, _y @ ..] = a;
- | ------- value moved here
+ | -- value moved here
LL | let [.., (ref _x, _)] = a;
| ^^^^^^ value borrowed here after move
|
@@ -92,9 +92,9 @@ error[E0382]: borrow of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:68:13
|
LL | let [x @ .., _] = a;
- | ------ value partially moved here
+ | - value partially moved here
LL | let [_, ref _y @ ..] = a;
- | ^^^^^^^^^^^ value borrowed here after partial move
+ | ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
@@ -122,7 +122,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:88:5
|
LL | let [_, _, _x @ ..] = a;
- | ------- value partially moved here
+ | -- value partially moved here
LL | a[0] = Default::default();
| ^^^^ value used here after partial move
|
@@ -132,7 +132,7 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:94:5
|
LL | let [_, _, _x @ ..] = a;
- | ------- value partially moved here
+ | -- value partially moved here
LL | a[0].1 = Default::default();
| ^^^^ value used here after partial move
|
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
index 1fc2b292b..363effcfe 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
@@ -34,7 +34,7 @@ error[E0382]: use of partially moved value: `a`
LL | let [_x, _, _] = a;
| -- value partially moved here
LL | let [_y @ .., _, _] = a;
- | ^^^^^^^ value used here after partial move
+ | ^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
@@ -44,7 +44,7 @@ error[E0382]: use of partially moved value: `a`
LL | let [.., _x] = a;
| -- value partially moved here
LL | let [_, _, _y @ ..] = a;
- | ^^^^^^^ value used here after partial move
+ | ^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
@@ -54,7 +54,7 @@ error[E0382]: use of partially moved value: `a`
LL | let [(_x, _), _, _] = a;
| -- value partially moved here
LL | let [_y @ .., _, _] = a;
- | ^^^^^^^ value used here after partial move
+ | ^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
@@ -64,7 +64,7 @@ error[E0382]: use of partially moved value: `a`
LL | let [.., (_x, _)] = a;
| -- value partially moved here
LL | let [_, _, _y @ ..] = a;
- | ^^^^^^^ value used here after partial move
+ | ^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
@@ -72,7 +72,7 @@ error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array.rs:54:11
|
LL | let [_y @ .., _, _] = a;
- | ------- value moved here
+ | -- value moved here
LL | let [(_x, _), _, _] = a;
| ^^ value used here after move
|
@@ -82,7 +82,7 @@ error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array.rs:60:15
|
LL | let [_, _, _y @ ..] = a;
- | ------- value moved here
+ | -- value moved here
LL | let [.., (_x, _)] = a;
| ^^ value used here after move
|
@@ -92,9 +92,9 @@ error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array.rs:68:13
|
LL | let [x @ .., _] = a;
- | ------ value partially moved here
+ | - value partially moved here
LL | let [_, _y @ ..] = a;
- | ^^^^^^^ value used here after partial move
+ | ^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr
index b8ac7a3a4..f4324110c 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr
@@ -57,7 +57,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
LL | let [ref first, ref second, ..] = *s;
| ---------- immutable borrow occurs here
LL | let [_, ref mut tail @ ..] = *s;
- | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+ | ^^^^^^^^^^^^ mutable borrow occurs here
LL | nop(&[first, second]);
| ------ immutable borrow later used here
@@ -67,7 +67,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
LL | let [.., ref second, ref first] = *s;
| ---------- immutable borrow occurs here
LL | let [ref mut tail @ .., _] = *s;
- | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+ | ^^^^^^^^^^^^ mutable borrow occurs here
LL | nop(&[first, second]);
| ------ immutable borrow later used here
@@ -75,9 +75,9 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
--> $DIR/borrowck-slice-pattern-element-loan-array.rs:46:10
|
LL | let [_, ref s1 @ ..] = *s;
- | ----------- immutable borrow occurs here
+ | ------ immutable borrow occurs here
LL | let [ref mut s2 @ .., _, _] = *s;
- | ^^^^^^^^^^^^^^^ mutable borrow occurs here
+ | ^^^^^^^^^^ mutable borrow occurs here
LL | nop_subslice(s1);
| -- immutable borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr
index d3388e071..f9a63bd49 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr
@@ -88,7 +88,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
LL | if let [ref first, ref second, ..] = *s {
| ---------- immutable borrow occurs here
LL | if let [_, ref mut tail @ ..] = *s {
- | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+ | ^^^^^^^^^^^^ mutable borrow occurs here
LL | nop(&[first, second]);
| ------ immutable borrow later used here
@@ -98,7 +98,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
LL | if let [.., ref second, ref first] = *s {
| ---------- immutable borrow occurs here
LL | if let [ref mut tail @ .., _] = *s {
- | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+ | ^^^^^^^^^^^^ mutable borrow occurs here
LL | nop(&[first, second]);
| ------ immutable borrow later used here
@@ -106,9 +106,9 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
--> $DIR/borrowck-slice-pattern-element-loan-slice.rs:65:17
|
LL | if let [_, _, _, ref s1 @ ..] = *s {
- | ----------- immutable borrow occurs here
+ | ------ immutable borrow occurs here
LL | if let [ref mut s2 @ .., _, _, _] = *s {
- | ^^^^^^^^^^^^^^^ mutable borrow occurs here
+ | ^^^^^^^^^^ mutable borrow occurs here
LL | nop_subslice(s1);
| -- immutable borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
index ff70ba9fc..0ac7df944 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
@@ -2,7 +2,7 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed
--> $DIR/borrowck-vec-pattern-move-tail.rs:8:5
|
LL | [1, 2, ref tail @ ..] => tail,
- | ------------- borrow of `a[_]` occurs here
+ | -------- borrow of `a[_]` occurs here
...
LL | a[2] = 0;
| ^^^^^^^^ assignment to borrowed `a[_]` occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index ddd89afe5..c3bcb7de6 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -14,7 +14,7 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed
--> $DIR/borrowck-vec-pattern-nesting.rs:23:13
|
LL | &mut [ref _b @ ..] => {
- | ----------- borrow of `vec[_]` occurs here
+ | ------ borrow of `vec[_]` occurs here
LL |
LL | vec[0] = Box::new(4);
| ^^^^^^ assignment to borrowed `vec[_]` occurs here
diff --git a/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs
new file mode 100644
index 000000000..524459291
--- /dev/null
+++ b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let mut vec: Vec<i32> = Vec::new();
+ let closure = move || {
+ vec.clear();
+ let mut iter = vec.iter();
+ move || { iter.next() } //~ ERROR captured variable cannot escape `FnMut` closure bod
+ };
+}
diff --git a/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr
new file mode 100644
index 000000000..78ca090fe
--- /dev/null
+++ b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr
@@ -0,0 +1,18 @@
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs:6:9
+ |
+LL | let mut vec: Vec<i32> = Vec::new();
+ | ------- variable defined here
+LL | let closure = move || {
+ | - inferred to be a `FnMut` closure
+LL | vec.clear();
+ | --- variable captured here
+LL | let mut iter = vec.iter();
+LL | move || { iter.next() }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/borrowck/index-mut-help.rs b/src/test/ui/borrowck/index-mut-help.rs
index d57ef975d..35266e113 100644
--- a/src/test/ui/borrowck/index-mut-help.rs
+++ b/src/test/ui/borrowck/index-mut-help.rs
@@ -1,10 +1,9 @@
// When mutably indexing a type that implements `Index` but not `IndexMut`, a
// special 'help' message is added to the output.
+use std::collections::HashMap;
fn main() {
- use std::collections::HashMap;
-
let mut map = HashMap::new();
map.insert("peter", "23".to_string());
diff --git a/src/test/ui/borrowck/index-mut-help.stderr b/src/test/ui/borrowck/index-mut-help.stderr
index 057c6ee15..f42d7e015 100644
--- a/src/test/ui/borrowck/index-mut-help.stderr
+++ b/src/test/ui/borrowck/index-mut-help.stderr
@@ -1,26 +1,39 @@
error[E0596]: cannot borrow data in an index of `HashMap<&str, String>` as mutable
- --> $DIR/index-mut-help.rs:11:5
+ --> $DIR/index-mut-help.rs:10:5
|
LL | map["peter"].clear();
| ^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `HashMap<&str, String>`
+help: to modify a `HashMap<&str, String>` use `.get_mut()`
+ |
+LL | map.get_mut("peter").map(|val| val.clear());
+ | ~~~~~~~~~ ~~~~~~~~~~~~~~~ +
error[E0594]: cannot assign to data in an index of `HashMap<&str, String>`
- --> $DIR/index-mut-help.rs:12:5
+ --> $DIR/index-mut-help.rs:11:5
|
LL | map["peter"] = "0".to_string();
| ^^^^^^^^^^^^ cannot assign
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `HashMap<&str, String>`
+help: to modify a `HashMap<&str, String>`, use `.get_mut()`, `.insert()` or the entry API
+ |
+LL | map.insert("peter", "0".to_string());
+ | ~~~~~~~~ ~ +
+LL | map.get_mut("peter").map(|val| { *val = "0".to_string(); });
+ | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ++++
+LL | let val = map.entry("peter").or_insert("0".to_string());
+ | +++++++++ ~~~~~~~ ~~~~~~~~~~~~ +
error[E0596]: cannot borrow data in an index of `HashMap<&str, String>` as mutable
- --> $DIR/index-mut-help.rs:13:13
+ --> $DIR/index-mut-help.rs:12:13
|
LL | let _ = &mut map["peter"];
| ^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `HashMap<&str, String>`
+ = help: to modify a `HashMap<&str, String>`, use `.get_mut()`, `.insert()` or the entry API
error: aborting due to 3 previous errors
diff --git a/src/test/ui/borrowck/issue-101119.rs b/src/test/ui/borrowck/issue-101119.rs
new file mode 100644
index 000000000..64e52eaac
--- /dev/null
+++ b/src/test/ui/borrowck/issue-101119.rs
@@ -0,0 +1,16 @@
+struct State;
+
+fn once(_: impl FnOnce()) {}
+
+fn fill_memory_blocks_mt(state: &mut State) {
+ loop {
+ once(move || {
+ //~^ ERROR use of moved value: `state`
+ fill_segment(state);
+ });
+ }
+}
+
+fn fill_segment(_: &mut State) {}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/issue-101119.stderr b/src/test/ui/borrowck/issue-101119.stderr
new file mode 100644
index 000000000..a22afdc67
--- /dev/null
+++ b/src/test/ui/borrowck/issue-101119.stderr
@@ -0,0 +1,15 @@
+error[E0382]: use of moved value: `state`
+ --> $DIR/issue-101119.rs:7:14
+ |
+LL | fn fill_memory_blocks_mt(state: &mut State) {
+ | ----- move occurs because `state` has type `&mut State`, which does not implement the `Copy` trait
+LL | loop {
+LL | once(move || {
+ | ^^^^^^^ value moved into closure here, in previous iteration of loop
+LL |
+LL | fill_segment(state);
+ | ----- use occurs due to use in closure
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr b/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr
index d98b3bae4..f0b574846 100644
--- a/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr
+++ b/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr
@@ -10,6 +10,10 @@ LL | || f() // The `nested` closure
| ^^^^^^ returning this value requires that `'1` must outlive `'2`
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
+help: consider adding 'move' keyword before the nested closure
+ |
+LL | move || f() // The `nested` closure
+ | ++++
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/issue-64453.stderr b/src/test/ui/borrowck/issue-64453.stderr
index 1f8a1acb8..245c3a40e 100644
--- a/src/test/ui/borrowck/issue-64453.stderr
+++ b/src/test/ui/borrowck/issue-64453.stderr
@@ -14,6 +14,7 @@ LL | static settings_dir: String = format!("");
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0507]: cannot move out of static item `settings_dir`
diff --git a/src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs b/src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs
new file mode 100644
index 000000000..95847d8d3
--- /dev/null
+++ b/src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs
@@ -0,0 +1,14 @@
+fn foo1(s: &str) -> impl Iterator<Item = String> + '_ {
+ None.into_iter()
+ .flat_map(move |()| s.chars().map(|c| format!("{}{}", c, s)))
+ //~^ ERROR captured variable cannot escape `FnMut` closure body
+ //~| HELP consider adding 'move' keyword before the nested closure
+}
+
+fn foo2(s: &str) -> impl Sized + '_ {
+ move |()| s.chars().map(|c| format!("{}{}", c, s))
+ //~^ ERROR lifetime may not live long enough
+ //~| HELP consider adding 'move' keyword before the nested closure
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr b/src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr
new file mode 100644
index 000000000..2eae614a2
--- /dev/null
+++ b/src/test/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr
@@ -0,0 +1,37 @@
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-95079-missing-move-in-nested-closure.rs:3:29
+ |
+LL | fn foo1(s: &str) -> impl Iterator<Item = String> + '_ {
+ | - variable defined here
+LL | None.into_iter()
+LL | .flat_map(move |()| s.chars().map(|c| format!("{}{}", c, s)))
+ | - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | | |
+ | | returns a reference to a captured variable which escapes the closure body
+ | | variable captured here
+ | inferred to be a `FnMut` closure
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+help: consider adding 'move' keyword before the nested closure
+ |
+LL | .flat_map(move |()| s.chars().map(move |c| format!("{}{}", c, s)))
+ | ++++
+
+error: lifetime may not live long enough
+ --> $DIR/issue-95079-missing-move-in-nested-closure.rs:9:15
+ |
+LL | move |()| s.chars().map(|c| format!("{}{}", c, s))
+ | --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
+ | | |
+ | | return type of closure `Map<Chars<'_>, [closure@$DIR/issue-95079-missing-move-in-nested-closure.rs:9:29: 9:32]>` contains a lifetime `'2`
+ | lifetime `'1` represents this closure's body
+ |
+ = note: closure implements `Fn`, so references to captured variables can't escape the closure
+help: consider adding 'move' keyword before the nested closure
+ |
+LL | move |()| s.chars().map(move |c| format!("{}{}", c, s))
+ | ++++
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
index af26169c8..b1af090ae 100644
--- a/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
+++ b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
@@ -5,6 +5,7 @@ LL | cb.map(|cb| cb());
| ^^^--------------
| | |
| | `*cb` moved due to this method call
+ | help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait
|
note: this function takes ownership of the receiver `self`, which moves `*cb`
@@ -12,10 +13,6 @@ note: this function takes ownership of the receiver `self`, which moves `*cb`
|
LL | pub const fn map<U, F>(self, f: F) -> Option<U>
| ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
- |
-LL | cb.as_ref().map(|cb| cb());
- | +++++++++
error[E0596]: cannot borrow `*cb` as mutable, as it is behind a `&` reference
--> $DIR/suggest-as-ref-on-mut-closure.rs:12:26
diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
index 3d395d1f2..da238205b 100644
--- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
+++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
@@ -131,13 +131,13 @@ fn coerce_index_op() {
let mut i = I(10);
i[i[3]] = 4;
//~^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
- // Shoud be accepted with g2p
+ // Should be accepted with g2p
i[3] = i[4];
i[i[3]] = i[4];
//~^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
- // Shoud be accepted with g2p
+ // Should be accepted with g2p
}
fn main() {
diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs
index e0f4afa75..0463e22b3 100644
--- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs
+++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs
@@ -40,6 +40,6 @@ fn main() {
//
// (At least in theory; part of the reason this test fails is that
// the constructed MIR throws in extra &mut reborrows which
- // flummoxes our attmpt to delay the activation point here.)
+ // flummoxes our attempt to delay the activation point here.)
delay.push(2);
}
diff --git a/src/test/ui/btreemap/btreemap-index-mut.rs b/src/test/ui/btreemap/btreemap-index-mut.rs
new file mode 100644
index 000000000..62972acab
--- /dev/null
+++ b/src/test/ui/btreemap/btreemap-index-mut.rs
@@ -0,0 +1,6 @@
+use std::collections::BTreeMap;
+
+fn main() {
+ let mut map = BTreeMap::<u32, u32>::new();
+ map[&0] = 1; //~ ERROR cannot assign
+}
diff --git a/src/test/ui/btreemap/btreemap-index-mut.stderr b/src/test/ui/btreemap/btreemap-index-mut.stderr
new file mode 100644
index 000000000..26f2a4c4b
--- /dev/null
+++ b/src/test/ui/btreemap/btreemap-index-mut.stderr
@@ -0,0 +1,19 @@
+error[E0594]: cannot assign to data in an index of `BTreeMap<u32, u32>`
+ --> $DIR/btreemap-index-mut.rs:5:5
+ |
+LL | map[&0] = 1;
+ | ^^^^^^^^^^^ cannot assign
+ |
+ = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `BTreeMap<u32, u32>`
+help: to modify a `BTreeMap<u32, u32>`, use `.get_mut()`, `.insert()` or the entry API
+ |
+LL | map.insert(&0, 1);
+ | ~~~~~~~~ ~ +
+LL | map.get_mut(&0).map(|val| { *val = 1; });
+ | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ++++
+LL | let val = map.entry(&0).or_insert(1);
+ | +++++++++ ~~~~~~~ ~~~~~~~~~~~~ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/c-variadic/issue-86053-1.stderr b/src/test/ui/c-variadic/issue-86053-1.stderr
index 5d119bb85..60b379faf 100644
--- a/src/test/ui/c-variadic/issue-86053-1.stderr
+++ b/src/test/ui/c-variadic/issue-86053-1.stderr
@@ -44,19 +44,19 @@ error: `...` must be the last argument of a C-variadic function
--> $DIR/issue-86053-1.rs:11:12
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
- | ^^^^
+ | ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/issue-86053-1.rs:11:12
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
- | ^^^^
+ | ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/issue-86053-1.rs:11:36
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
- | ^^^^
+ | ^^^
error[E0412]: cannot find type `F` in this scope
--> $DIR/issue-86053-1.rs:11:48
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 176bec819..2ffb80f7e 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -18,7 +18,7 @@ LL | fn foo(f: isize, x: u8, ...);
help: provide the arguments
|
LL | foo(/* isize */, /* u8 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~
error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
--> $DIR/variadic-ffi-1.rs:21:9
@@ -34,7 +34,7 @@ LL | fn foo(f: isize, x: u8, ...);
help: provide the argument
|
LL | foo(1, /* u8 */);
- | ~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/variadic-ffi-1.rs:23:56
diff --git a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs
index 6cb2ff9d8..1f23dadc4 100644
--- a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs
+++ b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs
@@ -1,7 +1,6 @@
// check-fail
// compile-flags:--cfg foo
-#![deny(warnings)]
#![cfg_attr(foo, crate_type="bin")]
//~^ERROR `crate_type` within
//~| WARN this was previously accepted
diff --git a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr
index 5609f8e9d..b52535ffd 100644
--- a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr
+++ b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr
@@ -1,20 +1,15 @@
error: `crate_type` within an `#![cfg_attr] attribute is deprecated`
- --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:5:18
+ --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:4:18
|
LL | #![cfg_attr(foo, crate_type="bin")]
| ^^^^^^^^^^^^^^^^
|
-note: the lint level is defined here
- --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:4:9
- |
-LL | #![deny(warnings)]
- | ^^^^^^^^
- = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` implied by `#[deny(warnings)]`
+ = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #91632 <https://github.com/rust-lang/rust/issues/91632>
error: `crate_name` within an `#![cfg_attr] attribute is deprecated`
- --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:10:18
+ --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:9:18
|
LL | #![cfg_attr(foo, crate_name="bar")]
| ^^^^^^^^^^^^^^^^
@@ -23,7 +18,7 @@ LL | #![cfg_attr(foo, crate_name="bar")]
= note: for more information, see issue #91632 <https://github.com/rust-lang/rust/issues/91632>
error: `crate_type` within an `#![cfg_attr] attribute is deprecated`
- --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:5:18
+ --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:4:18
|
LL | #![cfg_attr(foo, crate_type="bin")]
| ^^^^^^^^^^^^^^^^
@@ -32,7 +27,7 @@ LL | #![cfg_attr(foo, crate_type="bin")]
= note: for more information, see issue #91632 <https://github.com/rust-lang/rust/issues/91632>
error: `crate_name` within an `#![cfg_attr] attribute is deprecated`
- --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:10:18
+ --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:9:18
|
LL | #![cfg_attr(foo, crate_name="bar")]
| ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs
index dd83a03fd..eeeefcfb7 100644
--- a/src/test/ui/chalkify/type_wf.rs
+++ b/src/test/ui/chalkify/type_wf.rs
@@ -15,8 +15,8 @@ fn main() {
x: 5,
};
- let s = S { //~ ERROR the trait bound `{float}: Foo` is not satisfied
- x: 5.0,
+ let s = S {
+ x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied
};
let s = S {
diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr
index 7f8566082..6e8daf635 100644
--- a/src/test/ui/chalkify/type_wf.stderr
+++ b/src/test/ui/chalkify/type_wf.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `{float}: Foo` is not satisfied
- --> $DIR/type_wf.rs:18:13
+ --> $DIR/type_wf.rs:19:12
|
-LL | let s = S {
- | ^ the trait `Foo` is not implemented for `{float}`
+LL | x: 5.0,
+ | ^^^ the trait `Foo` is not implemented for `{float}`
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `S`
diff --git a/src/test/ui/check-cfg/allow-at-crate-level.rs b/src/test/ui/check-cfg/allow-at-crate-level.rs
new file mode 100644
index 000000000..ce3383a29
--- /dev/null
+++ b/src/test/ui/check-cfg/allow-at-crate-level.rs
@@ -0,0 +1,8 @@
+// This test check that #![allow(unexpected_cfgs)] works with --cfg
+//
+// check-pass
+// compile-flags: --cfg=unexpected --check-cfg=names() -Z unstable-options
+
+#![allow(unexpected_cfgs)]
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr b/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr
index bdfbc3d54..8fadcc1f9 100644
--- a/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr
+++ b/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr
@@ -1,2 +1,2 @@
-error: invalid `--check-cfg` argument: `names("NOT_IDENT")` (`names()` arguments must be simple identifers)
+error: invalid `--check-cfg` argument: `names("NOT_IDENT")` (`names()` arguments must be simple identifiers)
diff --git a/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr b/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr
index b25882baa..061d3f0e9 100644
--- a/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr
+++ b/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr
@@ -1,2 +1,2 @@
-error: invalid `--check-cfg` argument: `values("NOT_IDENT")` (`values()` first argument must be a simple identifer)
+error: invalid `--check-cfg` argument: `values("NOT_IDENT")` (`values()` first argument must be a simple identifier)
diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr
index 6cce31d33..7db2aadec 100644
--- a/src/test/ui/check-cfg/invalid-cfg-value.stderr
+++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr
@@ -15,5 +15,9 @@ LL | #[cfg(feature = "rand")]
|
= note: expected values for `feature` are: full, serde
-warning: 2 warnings emitted
+warning: unexpected condition value `rand` for condition name `feature`
+ |
+ = help: was set with `--cfg` but isn't in the `--check-cfg` expected values
+
+warning: 3 warnings emitted
diff --git a/src/test/ui/check-cfg/mix.rs b/src/test/ui/check-cfg/mix.rs
index 8e3d20d50..4e488fc03 100644
--- a/src/test/ui/check-cfg/mix.rs
+++ b/src/test/ui/check-cfg/mix.rs
@@ -3,7 +3,7 @@
// we correctly lint on the `cfg!` macro and `cfg_attr` attribute.
//
// check-pass
-// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" -Z unstable-options
+// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" --cfg unknown_name -Z unstable-options
#[cfg(windows)]
fn do_windows_stuff() {}
diff --git a/src/test/ui/check-cfg/mix.stderr b/src/test/ui/check-cfg/mix.stderr
index e51b75b3d..9cf887ec7 100644
--- a/src/test/ui/check-cfg/mix.stderr
+++ b/src/test/ui/check-cfg/mix.stderr
@@ -28,6 +28,14 @@ warning: unexpected `cfg` condition name
LL | #[cfg_attr(uu, test)]
| ^^
+warning: unexpected condition value `bar` for condition name `feature`
+ |
+ = help: was set with `--cfg` but isn't in the `--check-cfg` expected values
+
+warning: unexpected `unknown_name` as condition name
+ |
+ = help: was set with `--cfg` but isn't in the `--check-cfg` expected names
+
warning: unexpected `cfg` condition name
--> $DIR/mix.rs:35:10
|
@@ -170,5 +178,5 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
|
= note: expected values for `feature` are: foo
-warning: 25 warnings emitted
+warning: 27 warnings emitted
diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr
index b28cf0d6b..3c193ca34 100644
--- a/src/test/ui/check-static-values-constraints.stderr
+++ b/src/test/ui/check-static-values-constraints.stderr
@@ -22,6 +22,7 @@ LL | field2: SafeEnum::Variant4("str".to_string())
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error[E0010]: allocations are not allowed in statics
--> $DIR/check-static-values-constraints.rs:94:5
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
index 26f47eb68..284fc1c21 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -25,8 +25,8 @@ error[E0308]: mismatched types
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
| ^ one type is more general than the other
|
- = note: expected fn pointer `for<'r> fn(&'r u32)`
- found fn pointer `fn(&u32)`
+ = note: expected fn pointer `fn(&u32)`
+ found fn pointer `for<'r> fn(&'r u32)`
error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:39:50
@@ -34,8 +34,8 @@ error[E0308]: mismatched types
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
| ^ one type is more general than the other
|
- = note: expected fn pointer `fn(&'x u32)`
- found fn pointer `for<'r> fn(&'r u32)`
+ = note: expected fn pointer `for<'r> fn(&'r u32)`
+ found fn pointer `fn(&u32)`
error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:48:50
@@ -43,8 +43,8 @@ error[E0308]: mismatched types
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
| ^ one type is more general than the other
|
- = note: expected fn pointer `fn(&u32)`
- found fn pointer `for<'r> fn(&'r u32)`
+ = note: expected fn pointer `for<'r> fn(&'r u32)`
+ found fn pointer `fn(&u32)`
error: aborting due to 5 previous errors
diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
index db7586bee..d5432755c 100644
--- a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
+++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
@@ -6,7 +6,7 @@ LL | with_closure(|x: u32, y| {});
|
help: consider giving this closure parameter an explicit type
|
-LL | with_closure(|x: u32, y: B| {});
+LL | with_closure(|x: u32, y: _| {});
| +++
error: aborting due to previous error
diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.stderr b/src/test/ui/closure_context/issue-26046-fn-mut.stderr
index 74d3c4977..f744b71c2 100644
--- a/src/test/ui/closure_context/issue-26046-fn-mut.stderr
+++ b/src/test/ui/closure_context/issue-26046-fn-mut.stderr
@@ -8,6 +8,8 @@ LL | num += 1;
...
LL | Box::new(closure)
| ----------------- the requirement to implement `Fn` derives from here
+ |
+ = note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()`
error: aborting due to previous error
diff --git a/src/test/ui/closure_context/issue-26046-fn-once.stderr b/src/test/ui/closure_context/issue-26046-fn-once.stderr
index 473e8e841..34f94f9dc 100644
--- a/src/test/ui/closure_context/issue-26046-fn-once.stderr
+++ b/src/test/ui/closure_context/issue-26046-fn-once.stderr
@@ -8,6 +8,8 @@ LL | vec
...
LL | Box::new(closure)
| ----------------- the requirement to implement `Fn` derives from here
+ |
+ = note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec<u8>`
error: aborting due to previous error
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
index 93131b2ac..f97e60daf 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -68,7 +68,7 @@ fn arrays_5() {
arr[1] += 10;
};
- // c will capture `arr` completely, therefore we cannot borrow other indecies
+ // c will capture `arr` completely, therefore we cannot borrow other indices
// into the array.
println!("{:#?}", &arr[3..2]);
//~^ ERROR: cannot borrow `arr` as immutable because it is also borrowed as mutable
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
index bcde35983..309c63e52 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
@@ -7,7 +7,15 @@ LL | let [_, _s] = s;
| - closure is `FnOnce` because it moves the variable `s` out of its environment
LL | };
LL | expect_fn(c);
- | --------- the requirement to implement `Fn` derives from here
+ | --------- - the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `expect_fn`
+ --> $DIR/closure-origin-array-diagnostics.rs:5:17
+ |
+LL | fn expect_fn<F: Fn()>(_f: F) {}
+ | ^^^^ required by this bound in `expect_fn`
error: aborting due to previous error
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
index df33c4f1f..3e77635f9 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
@@ -7,7 +7,15 @@ LL | let s = s.1;
| --- closure is `FnOnce` because it moves the variable `s.1` out of its environment
LL | };
LL | expect_fn(c);
- | --------- the requirement to implement `Fn` derives from here
+ | --------- - the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `expect_fn`
+ --> $DIR/closure-origin-tuple-diagnostics.rs:5:17
+ |
+LL | fn expect_fn<F: Fn()>(_f: F) {}
+ | ^^^^ required by this bound in `expect_fn`
error: aborting due to previous error
diff --git a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
index 318673ef8..972c24c23 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
+++ b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
@@ -24,7 +24,7 @@ fn main() {
let _a = || { match l1 { L1::A => (), L1::B => () } };
// (except if the match is already non-exhaustive)
let _b = || { match l1 { L1::A => () } };
- //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
+ //~^ ERROR: non-exhaustive patterns: `L1::B` not covered [E0004]
// l2 should not be captured as it is a non-exhaustive SingleVariant
// defined in this crate
diff --git a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
index e0678bc71..3a5fad154 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `B` not covered
+error[E0004]: non-exhaustive patterns: `L1::B` not covered
--> $DIR/non-exhaustive-match.rs:26:25
|
LL | let _b = || { match l1 { L1::A => () } };
- | ^^ pattern `B` not covered
+ | ^^ pattern `L1::B` not covered
|
note: `L1` defined here
--> $DIR/non-exhaustive-match.rs:12:14
@@ -12,8 +12,8 @@ LL | enum L1 { A, B }
= note: the matched value is of type `L1`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
-LL | let _b = || { match l1 { L1::A => (), B => todo!() } };
- | ++++++++++++++
+LL | let _b = || { match l1 { L1::A => (), L1::B => todo!() } };
+ | ++++++++++++++++++
error[E0004]: non-exhaustive patterns: type `E1` is non-empty
--> $DIR/non-exhaustive-match.rs:37:25
diff --git a/src/test/ui/closures/2229_closure_analysis/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/repr_packed.rs
index 3ed780f51..f23670f63 100644
--- a/src/test/ui/closures/2229_closure_analysis/repr_packed.rs
+++ b/src/test/ui/closures/2229_closure_analysis/repr_packed.rs
@@ -31,7 +31,7 @@ fn test_alignment_not_affected() {
c();
}
-// `String`, `u16` are not aligned at a one byte boundry and are thus affected by repr(packed).
+// `String`, `u16` are not aligned at a one byte boundary and are thus affected by repr(packed).
//
// Here we test that the closure doesn't capture a reference point to `foo.x` but
// rather capture `foo` entirely.
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
index 2c828aed5..f8752fe1c 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
@@ -1,8 +1,8 @@
// edition:2021
// run-pass
-// Test that ByValue captures compile sucessefully especially when the captures are
-// derefenced within the closure.
+// Test that ByValue captures compile successfully especially when the captures are
+// dereferenced within the closure.
#[derive(Debug, Default)]
struct SomeLargeType;
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr
index 40274c883..cf8bd7a0a 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr
@@ -1,8 +1,8 @@
-warning: unused variable: `t2`
- --> $DIR/destructure-pattern-closure-within-closure.rs:13:21
+warning: unused variable: `g2`
+ --> $DIR/destructure-pattern-closure-within-closure.rs:10:17
|
-LL | let (_, t2) = t;
- | ^^ help: if this is intentional, prefix it with an underscore: `_t2`
+LL | let (_, g2) = g;
+ | ^^ help: if this is intentional, prefix it with an underscore: `_g2`
|
note: the lint level is defined here
--> $DIR/destructure-pattern-closure-within-closure.rs:3:9
@@ -11,11 +11,11 @@ LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
-warning: unused variable: `g2`
- --> $DIR/destructure-pattern-closure-within-closure.rs:10:17
+warning: unused variable: `t2`
+ --> $DIR/destructure-pattern-closure-within-closure.rs:13:21
|
-LL | let (_, g2) = g;
- | ^^ help: if this is intentional, prefix it with an underscore: `_g2`
+LL | let (_, t2) = t;
+ | ^^ help: if this is intentional, prefix it with an underscore: `_t2`
warning: 2 warnings emitted
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
index 88a9816a0..03400e0ee 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
@@ -1,7 +1,7 @@
// edition:2021
// run-pass
-// Tests that if a closure uses indivual fields of the same object
+// Tests that if a closure uses individual fields of the same object
// then that case is handled properly.
#![allow(unused)]
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
index b8e464031..624e0ff22 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
@@ -1,10 +1,10 @@
// edition:2021
// run-pass
-// Test that closures can catpure paths that are more precise than just one level
+// Test that closures can capture paths that are more precise than just one level
// from the root variable.
//
-// If the closures can handle such precison we should be able to mutate one path in the closure
+// If the closures can handle such precision we should be able to mutate one path in the closure
// while being able to mutate another path outside the closure, where the two paths are disjoint
// after applying two projections on the root variable.
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
index 11a324d8a..bd8addd37 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
@@ -3,7 +3,7 @@
#![allow(unused)]
-// If the closures can handle such precison we should be able to read one path in the closure
+// If the closures can handle such precision we should be able to read one path in the closure
// while being able mutate another path outside the closure, where the two paths are disjoint
// after applying two projections on the root variable.
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs
index bb784774b..a85335438 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs
@@ -5,7 +5,7 @@
// that is captured by the closure
// More specifically we test that the if the mutable reference isn't root variable of a capture
-// but rather accessed while acessing the precise capture.
+// but rather accessed while accessing the precise capture.
fn mut_tuple() {
let mut t = (10, 10);
diff --git a/src/test/ui/closures/binder/disallow-const.rs b/src/test/ui/closures/binder/disallow-const.rs
new file mode 100644
index 000000000..72ad6185d
--- /dev/null
+++ b/src/test/ui/closures/binder/disallow-const.rs
@@ -0,0 +1,6 @@
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+ for<const N: i32> || -> () {};
+ //~^ ERROR only lifetime parameters can be used in this context
+}
diff --git a/src/test/ui/closures/binder/disallow-const.stderr b/src/test/ui/closures/binder/disallow-const.stderr
new file mode 100644
index 000000000..3c3b43d8c
--- /dev/null
+++ b/src/test/ui/closures/binder/disallow-const.stderr
@@ -0,0 +1,8 @@
+error: only lifetime parameters can be used in this context
+ --> $DIR/disallow-const.rs:4:15
+ |
+LL | for<const N: i32> || -> () {};
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/closures/binder/disallow-ty.rs b/src/test/ui/closures/binder/disallow-ty.rs
new file mode 100644
index 000000000..bbe3d8488
--- /dev/null
+++ b/src/test/ui/closures/binder/disallow-ty.rs
@@ -0,0 +1,6 @@
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+ for<T> || -> () {};
+ //~^ ERROR only lifetime parameters can be used in this context
+}
diff --git a/src/test/ui/closures/binder/disallow-ty.stderr b/src/test/ui/closures/binder/disallow-ty.stderr
new file mode 100644
index 000000000..51b6773ed
--- /dev/null
+++ b/src/test/ui/closures/binder/disallow-ty.stderr
@@ -0,0 +1,8 @@
+error: only lifetime parameters can be used in this context
+ --> $DIR/disallow-ty.rs:4:9
+ |
+LL | for<T> || -> () {};
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index 1086cfa29..a2ca06b4e 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -1,11 +1,17 @@
error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
- --> $DIR/closure-move-sync.rs:6:13
+ --> $DIR/closure-move-sync.rs:6:27
|
-LL | let t = thread::spawn(|| {
- | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
+LL | let t = thread::spawn(|| {
+ | _____________-------------_^
+ | | |
+ | | required by a bound introduced by this call
+LL | | recv.recv().unwrap();
+LL | |
+LL | | });
+ | |_____^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
- = note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
+ = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send`
note: required because it's used within this closure
--> $DIR/closure-move-sync.rs:6:27
|
@@ -18,13 +24,15 @@ LL | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `Sender<()>` cannot be shared between threads safely
- --> $DIR/closure-move-sync.rs:18:5
+ --> $DIR/closure-move-sync.rs:18:19
|
LL | thread::spawn(|| tx.send(()).unwrap());
- | ^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `Sender<()>`
- = note: required because of the requirements on the impl of `Send` for `&Sender<()>`
+ = note: required for `&Sender<()>` to implement `Send`
note: required because it's used within this closure
--> $DIR/closure-move-sync.rs:18:19
|
diff --git a/src/test/ui/closures/closure-wrong-kind.stderr b/src/test/ui/closures/closure-wrong-kind.stderr
index 35caf71a5..9ea55d764 100644
--- a/src/test/ui/closures/closure-wrong-kind.stderr
+++ b/src/test/ui/closures/closure-wrong-kind.stderr
@@ -6,7 +6,15 @@ LL | let closure = |_| foo(x);
| |
| this closure implements `FnOnce`, not `Fn`
LL | bar(closure);
- | --- the requirement to implement `Fn` derives from here
+ | --- ------- the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `bar`
+ --> $DIR/closure-wrong-kind.rs:6:11
+ |
+LL | fn bar<T: Fn(u32)>(_: T) {}
+ | ^^^^^^^ required by this bound in `bar`
error: aborting due to previous error
diff --git a/src/test/ui/closures/coerce-unsafe-to-closure.stderr b/src/test/ui/closures/coerce-unsafe-to-closure.stderr
index bd095c2d8..6ce63e829 100644
--- a/src/test/ui/closures/coerce-unsafe-to-closure.stderr
+++ b/src/test/ui/closures/coerce-unsafe-to-closure.stderr
@@ -6,7 +6,7 @@ LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
| |
| required by a bound introduced by this call
|
- = help: the trait `FnOnce<(&str,)>` is not implemented for `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+ = help: the trait `FnOnce<(&str,)>` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `Option::<T>::map`
--> $SRC_DIR/core/src/option.rs:LL:COL
diff --git a/src/test/ui/closures/issue-10398.rs b/src/test/ui/closures/issue-10398.rs
index 0405b2d01..f76d09cd0 100644
--- a/src/test/ui/closures/issue-10398.rs
+++ b/src/test/ui/closures/issue-10398.rs
@@ -1,7 +1,5 @@
-#![feature(box_syntax)]
-
fn main() {
- let x: Box<_> = box 1;
+ let x: Box<_> = Box::new(1);
let f = move|| {
let _a = x;
drop(x);
diff --git a/src/test/ui/closures/issue-10398.stderr b/src/test/ui/closures/issue-10398.stderr
index 8d9faf324..423b79daf 100644
--- a/src/test/ui/closures/issue-10398.stderr
+++ b/src/test/ui/closures/issue-10398.stderr
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `x`
- --> $DIR/issue-10398.rs:7:14
+ --> $DIR/issue-10398.rs:5:14
|
LL | let _a = x;
| - value moved here
diff --git a/src/test/ui/closures/issue-52437.rs b/src/test/ui/closures/issue-52437.rs
index f79a0bd35..6ac5380a5 100644
--- a/src/test/ui/closures/issue-52437.rs
+++ b/src/test/ui/closures/issue-52437.rs
@@ -2,5 +2,4 @@ fn main() {
[(); &(&'static: loop { |x| {}; }) as *const _ as usize]
//~^ ERROR: invalid label name `'static`
//~| ERROR: type annotations needed
- //~| ERROR mismatched types
}
diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr
index 38d9d08ce..4c24a54bb 100644
--- a/src/test/ui/closures/issue-52437.stderr
+++ b/src/test/ui/closures/issue-52437.stderr
@@ -15,15 +15,6 @@ help: consider giving this closure parameter an explicit type
LL | [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize]
| +++
-error[E0308]: mismatched types
- --> $DIR/issue-52437.rs:2:5
- |
-LL | fn main() {
- | - expected `()` because of default return type
-LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[(); _]`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0282, E0308.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/closures/issue-6801.rs b/src/test/ui/closures/issue-6801.rs
index 694d86feb..cecb08f00 100644
--- a/src/test/ui/closures/issue-6801.rs
+++ b/src/test/ui/closures/issue-6801.rs
@@ -2,7 +2,7 @@
// transferring ownership of the box before invoking the stack
// closure results in a crash.
-#![feature(box_syntax)]
+
fn twice(x: Box<usize>) -> usize {
*x * 2
@@ -13,7 +13,7 @@ fn invoke<F>(f: F) where F: FnOnce() -> usize {
}
fn main() {
- let x : Box<usize> = box 9;
+ let x : Box<usize> = Box::new(9);
let sq = || { *x * *x };
twice(x); //~ ERROR: cannot move out of
diff --git a/src/test/ui/closures/issue-84128.rs b/src/test/ui/closures/issue-84128.rs
index f81d7cfaa..30733871b 100644
--- a/src/test/ui/closures/issue-84128.rs
+++ b/src/test/ui/closures/issue-84128.rs
@@ -1,5 +1,5 @@
// test for issue 84128
-// missing suggestion for similar ADT type with diffetent generic paramenter
+// missing suggestion for similar ADT type with diffetent generic parameter
// on closure ReturnNoExpression
struct Foo<T>(T);
diff --git a/src/test/ui/closures/issue-84128.stderr b/src/test/ui/closures/issue-84128.stderr
index 09c44d261..59607afec 100644
--- a/src/test/ui/closures/issue-84128.stderr
+++ b/src/test/ui/closures/issue-84128.stderr
@@ -6,11 +6,6 @@ LL | Foo(())
| |
| arguments to this struct are incorrect
|
-note: return type inferred to be `{integer}` here
- --> $DIR/issue-84128.rs:10:20
- |
-LL | return Foo(0);
- | ^^^^^^
note: tuple struct defined here
--> $DIR/issue-84128.rs:5:8
|
diff --git a/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr b/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr
index fdaf353fe..3ab7c66d1 100644
--- a/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr
+++ b/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr
@@ -2,7 +2,7 @@ error[E0382]: use of moved value: `c`
--> $DIR/closure-print-generic-verbose-1.rs:17:5
|
LL | let c = to_fn_once(move|| {
- | - move occurs because `c` has type `[f<T>::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'_#10r str>, T)]`, which does not implement the `Copy` trait
+ | - move occurs because `c` has type `[f<T>::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'_#9r str>, T)]`, which does not implement the `Copy` trait
...
LL | c();
| --- `c` moved due to this call
diff --git a/src/test/ui/codegen/issue-101585-128bit-repeat.rs b/src/test/ui/codegen/issue-101585-128bit-repeat.rs
new file mode 100644
index 000000000..c6a686597
--- /dev/null
+++ b/src/test/ui/codegen/issue-101585-128bit-repeat.rs
@@ -0,0 +1,14 @@
+// Regression test for issue 101585.
+// run-pass
+
+fn main() {
+ fn min_array_ok() -> [i128; 1] {
+ [i128::MIN]
+ }
+ assert_eq!(min_array_ok(), [-170141183460469231731687303715884105728i128]);
+
+ fn min_array_nok() -> [i128; 1] {
+ [i128::MIN; 1]
+ }
+ assert_eq!(min_array_nok(), [-170141183460469231731687303715884105728i128]);
+}
diff --git a/src/test/ui/codegen/issue-99551.rs b/src/test/ui/codegen/issue-99551.rs
new file mode 100644
index 000000000..f24874c99
--- /dev/null
+++ b/src/test/ui/codegen/issue-99551.rs
@@ -0,0 +1,21 @@
+// build-pass
+#![feature(trait_upcasting)]
+#![allow(incomplete_features)]
+
+pub trait A {}
+pub trait B {}
+
+pub trait C: A + B {}
+impl<X: A + B> C for X {}
+
+pub fn test<'a, T>(view: T) -> Option<&'a mut dyn B>
+where
+ T: IntoIterator<Item = &'a mut dyn B>,
+{
+ return Some(view.into_iter().next().unwrap());
+}
+
+fn main() {
+ let mut a: Vec<Box<dyn C>> = Vec::new();
+ test(a.iter_mut().map(|c| c.as_mut() as &mut dyn B));
+}
diff --git a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
index 36551e5af..5cbdef218 100644
--- a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
+++ b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
@@ -12,7 +12,7 @@ note: function defined here
--> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
|
LL | fn test<T>(_a: T, _b: T) {}
- | ^^^^ ----- -----
+ | ^^^^ -----
error: aborting due to previous error
diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr
index add8f14cf..1207dc7e7 100644
--- a/src/test/ui/coercion/coerce-to-bang.stderr
+++ b/src/test/ui/coercion/coerce-to-bang.stderr
@@ -12,7 +12,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:18:13
@@ -28,7 +28,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:26:12
@@ -44,7 +44,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:36:12
@@ -60,7 +60,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:45:12
@@ -76,7 +76,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:50:21
diff --git a/src/test/ui/coercion/issue-101066.rs b/src/test/ui/coercion/issue-101066.rs
new file mode 100644
index 000000000..b658ed1e9
--- /dev/null
+++ b/src/test/ui/coercion/issue-101066.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+use std::convert::TryFrom;
+
+pub trait FieldElement {
+ type Integer: TryFrom<usize, Error = std::num::TryFromIntError>;
+
+ fn valid_integer_try_from<N>(i: N) -> Result<Self::Integer, ()>
+ where
+ Self::Integer: TryFrom<N>,
+ {
+ Self::Integer::try_from(i).map_err(|_| ())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/coherence/auxiliary/trait-with-const-param.rs b/src/test/ui/coherence/auxiliary/trait-with-const-param.rs
new file mode 100644
index 000000000..a44eb14f8
--- /dev/null
+++ b/src/test/ui/coherence/auxiliary/trait-with-const-param.rs
@@ -0,0 +1 @@
+pub trait Trait<const N: usize, T> {}
diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs
index 159788b1b..3acf0d8d3 100644
--- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs
+++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs
@@ -1,12 +1,17 @@
-#![feature(negative_impls)]
+// revisions: stock with_negative_coherence
+//[with_negative_coherence] check-pass
-// FIXME: this should compile
+#![feature(negative_impls)]
+#![cfg_attr(with_negative_coherence, feature(with_negative_coherence))]
trait MyPredicate<'a> {}
-impl<'a, T> !MyPredicate<'a> for &T where T: 'a {}
+
+impl<'a, T> !MyPredicate<'a> for &'a T where T: 'a {}
+
trait MyTrait<'a> {}
+
impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
impl<'a, T> MyTrait<'a> for &'a T {}
-//~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_`
+//[stock]~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_`
fn main() {}
diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
index 263bd19b4..097cc4e0f 100644
--- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr
+++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
@@ -1,5 +1,5 @@
error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
- --> $DIR/coherence-negative-outlives-lifetimes.rs:9:1
+ --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
|
LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
| ---------------------------------------------- first implementation here
diff --git a/src/test/ui/coherence/const-generics-orphan-check-ok.rs b/src/test/ui/coherence/const-generics-orphan-check-ok.rs
new file mode 100644
index 000000000..217e8aed2
--- /dev/null
+++ b/src/test/ui/coherence/const-generics-orphan-check-ok.rs
@@ -0,0 +1,28 @@
+// check-pass
+// aux-build:trait-with-const-param.rs
+extern crate trait_with_const_param;
+use trait_with_const_param::*;
+
+// Trivial case, const param after local type.
+struct Local1;
+impl<const N: usize, T> Trait<N, T> for Local1 {}
+
+// Concrete consts behave the same as foreign types,
+// so this also trivially works.
+impl Trait<3, Local1> for i32 {}
+
+// This case isn't as trivial as we would forbid type
+// parameters here, we do allow const parameters though.
+//
+// The reason that type parameters are forbidden for
+// `impl<T> Trait<T, LocalInA> for i32 {}` is that another
+// downstream crate can add `impl<T> Trait<LocalInB, T> for i32`.
+// As these two impls would overlap we forbid any impls which
+// have a type parameter in front of a local type.
+//
+// With const parameters this issue does not exist as there are no
+// constants local to another downstream crate.
+struct Local2;
+impl<const N: usize> Trait<N, Local2> for i32 {}
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.rs b/src/test/ui/coherence/issue-100191-2.rs
new file mode 100644
index 000000000..1c8316f87
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191-2.rs
@@ -0,0 +1,12 @@
+//~ ERROR overflow evaluating the requirement `T: Trait<_>`
+
+#![feature(specialization, with_negative_coherence)]
+#![allow(incomplete_features)]
+
+pub trait Trait<T> {}
+
+default impl<T, U> Trait<T> for U {}
+
+impl<T> Trait<<T as Iterator>::Item> for T {}
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.stderr b/src/test/ui/coherence/issue-100191-2.stderr
new file mode 100644
index 000000000..d50c220bc
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191-2.stderr
@@ -0,0 +1,14 @@
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_100191_2`)
+note: required for `T` to implement `Trait<_>`
+ --> $DIR/issue-100191-2.rs:8:20
+ |
+LL | default impl<T, U> Trait<T> for U {}
+ | ^^^^^^^^ ^
+ = note: 128 redundant requirements hidden
+ = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/coherence/issue-100191.rs b/src/test/ui/coherence/issue-100191.rs
new file mode 100644
index 000000000..e8597fde5
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191.rs
@@ -0,0 +1,21 @@
+#![crate_type = "lib"]
+#![feature(specialization, with_negative_coherence)]
+#![allow(incomplete_features)]
+
+trait X {}
+trait Y: X {}
+trait Z {
+ type Assoc: Y;
+}
+struct A<T>(T);
+
+impl<T> Y for T where T: X {}
+impl<T: X> Z for A<T> {
+ type Assoc = T;
+}
+
+// this impl is invalid, but causes an ICE anyway
+impl<T> From<<A<T> as Z>::Assoc> for T {}
+//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191.stderr b/src/test/ui/coherence/issue-100191.stderr
new file mode 100644
index 000000000..1adb0f1e4
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+ --> $DIR/issue-100191.rs:18:6
+ |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+ | ^ type parameter `T` must be used as the type parameter for some local type
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+ = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/command/command-current-dir.rs b/src/test/ui/command/command-current-dir.rs
index 91d8e4f38..69a0b486d 100644
--- a/src/test/ui/command/command-current-dir.rs
+++ b/src/test/ui/command/command-current-dir.rs
@@ -18,7 +18,7 @@ fn main() {
let exe = me.file_name().unwrap();
let cwd = me.parent().unwrap();
eprintln!("cwd={:?}", cwd);
- // Change directory to where the exectuable is located, since this test
+ // Change directory to where the executable is located, since this test
// fundamentally needs to use relative paths. In some cases (like
// remote-test-server), the current_dir can be somewhere else, so make
// sure it is something we can use. We assume we can write to this
diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
index a057fd19b..d4bd673b8 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
@@ -50,7 +50,9 @@ error[E0565]: literal in `cfg` predicate value must be a string
--> $DIR/cfg-attr-syntax-validation.rs:25:11
|
LL | #[cfg(a = b"hi")]
- | ^^^^^ help: consider removing the prefix: `"hi"`
+ | -^^^^
+ | |
+ | help: consider removing the prefix
error: expected unsuffixed literal or identifier, found `concat!("nonexistent")`
--> $DIR/cfg-attr-syntax-validation.rs:30:25
diff --git a/src/test/ui/const-generics/argument_order.stderr b/src/test/ui/const-generics/argument_order.stderr
index 6b33dffb4..99122c6f5 100644
--- a/src/test/ui/const-generics/argument_order.stderr
+++ b/src/test/ui/const-generics/argument_order.stderr
@@ -1,4 +1,4 @@
-error: lifetime parameters must be declared prior to const parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/argument_order.rs:6:32
|
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
@@ -11,7 +11,7 @@ LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
| ^^^^^^^
|
= note: lifetime arguments must be provided before type arguments
- = help: reorder the arguments: lifetimes, then consts: `<'a, 'b, N, T, M, U>`
+ = help: reorder the arguments: lifetimes, then type and consts: `<'a, 'b, N, T, M, U>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs
index da06aca30..cb1cebe1f 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.rs
+++ b/src/test/ui/const-generics/const-param-before-other-params.rs
@@ -1,5 +1,5 @@
fn bar<const X: u8, 'a>(_: &'a ()) {
- //~^ ERROR lifetime parameters must be declared prior to const parameters
+ //~^ ERROR lifetime parameters must be declared prior to type and const parameters
}
fn foo<const X: u8, T>(_: &T) {}
diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr
index 607d20c4a..2c7a47bbc 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.stderr
+++ b/src/test/ui/const-generics/const-param-before-other-params.stderr
@@ -1,4 +1,4 @@
-error: lifetime parameters must be declared prior to const parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/const-param-before-other-params.rs:1:21
|
LL | fn bar<const X: u8, 'a>(_: &'a ()) {
diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr
index e8826ce43..61b355118 100644
--- a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr
+++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | Foo::<10, 12>
| ^^^^^^^^^^^^^ expected `11`, found `12`
|
- = note: expected type `11`
- found type `12`
+ = note: expected constant `11`
+ found constant `12`
error: aborting due to previous error
diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr
index d5a3071b7..e83f89a60 100644
--- a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr
+++ b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | Foo::<N, { N + 2 }>
| ^^^^^^^^^^^^^^^^^^^ expected `{ N + 1 }`, found `{ N + 2 }`
|
- = note: expected type `{ N + 1 }`
- found type `{ N + 2 }`
+ = note: expected constant `{ N + 1 }`
+ found constant `{ N + 2 }`
error: aborting due to previous error
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
index 578938db4..beaf7fc60 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
@@ -1,9 +1,9 @@
// Checks that lifetimes cannot be interspersed between consts and types.
struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
-//~^ Error lifetime parameters must be declared prior to const parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-//~^ Error lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
fn main() {}
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
index e27976deb..5cff61dd9 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
@@ -1,10 +1,10 @@
-error: lifetime parameters must be declared prior to const parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/intermixed-lifetime.rs:3:28
|
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/intermixed-lifetime.rs:6:37
|
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
index da087ffc3..f928fc9e7 100644
--- a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
+++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
@@ -1,4 +1,4 @@
struct Foo<const M: usize = 10, 'a>(&'a u32);
-//~^ Error lifetime parameters must be declared prior to const parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
fn main() {}
diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
index 55f5a5353..ba08b4646 100644
--- a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
+++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
@@ -1,4 +1,4 @@
-error: lifetime parameters must be declared prior to const parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/param-order-err-pretty-prints-default.rs:1:33
|
LL | struct Foo<const M: usize = 10, 'a>(&'a u32);
diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
index a9c185e5f..0e8334d03 100644
--- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
+++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
@@ -2,9 +2,7 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied
--> $DIR/trait_objects_fail.rs:26:9
|
LL | foo(&10_u32);
- | --- ^^^^^^^ the trait `Trait` is not implemented for `u32`
- | |
- | required by a bound introduced by this call
+ | ^^^^^^^ the trait `Trait` is not implemented for `u32`
|
= help: the trait `Trait<2>` is implemented for `u32`
= note: required for the cast from `u32` to the object type `dyn Trait`
@@ -13,9 +11,7 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
--> $DIR/trait_objects_fail.rs:28:9
|
LL | bar(&true);
- | --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
- | |
- | required by a bound introduced by this call
+ | ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
|
= help: the trait `Traitor<2, 3>` is implemented for `bool`
= note: required for the cast from `bool` to the object type `dyn Traitor<_>`
diff --git a/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr b/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr
index a9f9787d8..e3bf38b70 100644
--- a/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr
+++ b/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr
@@ -4,7 +4,7 @@ error[E0401]: can't use generic parameters from outer function
LL | fn foo<const X: u32>() {
| - const parameter from outer function
LL | fn bar() -> u32 {
- | --- try adding a local generic parameter in this method instead
+ | - help: try using a local generic parameter instead: `<X>`
LL | X
| ^ use of generic parameter from outer function
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
index ababb27a8..ada1050d3 100644
--- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -1,11 +1,11 @@
error: unconstrained generic constant
- --> $DIR/abstract-const-as-cast-3.rs:17:5
+ --> $DIR/abstract-const-as-cast-3.rs:17:19
|
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -22,17 +22,22 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
|
- = note: expected type `{ N as u128 }`
- found type `{ O as u128 }`
+ = note: expected constant `{ N as u128 }`
+ found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:14:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl::assert_impl`
error: unconstrained generic constant
- --> $DIR/abstract-const-as-cast-3.rs:20:5
+ --> $DIR/abstract-const-as-cast-3.rs:20:19
|
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -49,8 +54,13 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
|
- = note: expected type `{ N as _ }`
- found type `{ O as u128 }`
+ = note: expected constant `{ N as _ }`
+ found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:14:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl::assert_impl`
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:23:5
@@ -58,8 +68,13 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
|
- = note: expected type `12`
- found type `13`
+ = note: expected constant `12`
+ found constant `13`
+note: required by a bound in `use_trait_impl::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:14:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl::assert_impl`
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:25:5
@@ -67,17 +82,22 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
|
- = note: expected type `13`
- found type `14`
+ = note: expected constant `13`
+ found constant `14`
+note: required by a bound in `use_trait_impl::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:14:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl::assert_impl`
error: unconstrained generic constant
- --> $DIR/abstract-const-as-cast-3.rs:35:5
+ --> $DIR/abstract-const-as-cast-3.rs:35:19
|
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -94,17 +114,22 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
|
- = note: expected type `{ N as u128 }`
- found type `{ O as u128 }`
+ = note: expected constant `{ N as u128 }`
+ found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:32:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
error: unconstrained generic constant
- --> $DIR/abstract-const-as-cast-3.rs:38:5
+ --> $DIR/abstract-const-as-cast-3.rs:38:19
|
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -121,8 +146,13 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
|
- = note: expected type `{ N as _ }`
- found type `{ O as u128 }`
+ = note: expected constant `{ N as _ }`
+ found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:32:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:41:5
@@ -130,8 +160,13 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
|
- = note: expected type `12`
- found type `13`
+ = note: expected constant `12`
+ found constant `13`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:32:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:43:5
@@ -139,8 +174,13 @@ error[E0308]: mismatched types
LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
|
- = note: expected type `13`
- found type `14`
+ = note: expected constant `13`
+ found constant `14`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:32:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
error: aborting due to 12 previous errors
diff --git a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
index 2aeb9b961..83a2f3740 100644
--- a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | [0; size_of::<Foo<T>>()]
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::<T>()`, found `size_of::<Foo<T>>()`
|
- = note: expected type `size_of::<T>()`
- found type `size_of::<Foo<T>>()`
+ = note: expected constant `size_of::<T>()`
+ found constant `size_of::<Foo<T>>()`
error: unconstrained generic constant
--> $DIR/different-fn.rs:10:9
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-100217.rs b/src/test/ui/const-generics/generic_const_exprs/issue-100217.rs
new file mode 100644
index 000000000..acdc348a3
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-100217.rs
@@ -0,0 +1,42 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait TraitOne {
+ const MY_NUM: usize;
+ type MyErr: std::fmt::Debug;
+
+ fn do_one_stuff(arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr>;
+}
+
+trait TraitTwo {
+ fn do_two_stuff();
+}
+
+impl<O: TraitOne> TraitTwo for O
+where
+ [(); Self::MY_NUM]:,
+{
+ fn do_two_stuff() {
+ O::do_one_stuff([5; Self::MY_NUM]).unwrap()
+ }
+}
+
+struct Blargotron;
+
+#[derive(Debug)]
+struct ErrTy<const N: usize>([(); N]);
+
+impl TraitOne for Blargotron {
+ const MY_NUM: usize = 3;
+ type MyErr = ErrTy<{ Self::MY_NUM }>;
+
+ fn do_one_stuff(_arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr> {
+ Ok(())
+ }
+}
+
+fn main() {
+ Blargotron::do_two_stuff();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-100360.rs b/src/test/ui/const-generics/generic_const_exprs/issue-100360.rs
new file mode 100644
index 000000000..5572f1f88
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-100360.rs
@@ -0,0 +1,13 @@
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+fn foo<const B: &'static bool>(arg: &'static bool) -> bool {
+ B == arg
+}
+
+fn main() {
+ foo::<{ &true }>(&false);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
index f2ae361dc..0742db398 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | ArrayHolder([0; Self::SIZE])
| ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
|
- = note: expected type `X`
- found type `Self::SIZE`
+ = note: expected constant `X`
+ found constant `Self::SIZE`
error: unconstrained generic constant
--> $DIR/issue-62504.rs:18:25
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
index 7a083733a..c3e2f8e16 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
@@ -2,7 +2,9 @@ error[E0423]: expected value, found type parameter `T`
--> $DIR/issue-69654.rs:5:25
|
LL | impl<T> Bar<T> for [u8; T] {}
- | ^ not a value
+ | - ^ not a value
+ | |
+ | found this type parameter
error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied
--> $DIR/issue-69654.rs:17:10
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
index d536f6fd1..f2fddfbfb 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
@@ -4,8 +4,15 @@ error[E0308]: mismatched types
LL | let x: Arr<{usize::MAX}> = Arr {};
| ^^^^^^^^^^^^^^^^^ expected `false`, found `true`
|
- = note: expected type `false`
- found type `true`
+ = note: expected constant `false`
+ found constant `true`
+note: required by a bound in `Arr`
+ --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
+ |
+LL | struct Arr<const N: usize>
+ | --- required by a bound in this
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^^^^^^ required by this bound in `Arr`
error[E0308]: mismatched types
--> $DIR/issue-72819-generic-in-const-eval.rs:20:32
@@ -13,8 +20,15 @@ error[E0308]: mismatched types
LL | let x: Arr<{usize::MAX}> = Arr {};
| ^^^ expected `false`, found `true`
|
- = note: expected type `false`
- found type `true`
+ = note: expected constant `false`
+ found constant `true`
+note: required by a bound in `Arr`
+ --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
+ |
+LL | struct Arr<const N: usize>
+ | --- required by a bound in this
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^^^^^^ required by this bound in `Arr`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-73298.rs b/src/test/ui/const-generics/generic_const_exprs/issue-73298.rs
new file mode 100644
index 000000000..3c59e1b79
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-73298.rs
@@ -0,0 +1,23 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+use std::convert::AsMut;
+use std::default::Default;
+
+trait Foo: Sized {
+ type Baz: Default + AsMut<[u8]>;
+ fn bar() {
+ Self::Baz::default().as_mut();
+ }
+}
+
+impl Foo for () {
+ type Baz = [u8; 1 * 1];
+ //type Baz = [u8; 1];
+}
+
+fn main() {
+ <() as Foo>::bar();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-82268.rs b/src/test/ui/const-generics/generic_const_exprs/issue-82268.rs
new file mode 100644
index 000000000..d08fc5beb
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-82268.rs
@@ -0,0 +1,73 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait Collate<Op> {
+ type Pass;
+ type Fail;
+
+ fn collate(self) -> (Self::Pass, Self::Fail);
+}
+
+impl<Op> Collate<Op> for () {
+ type Pass = ();
+ type Fail = ();
+
+ fn collate(self) -> ((), ()) {
+ ((), ())
+ }
+}
+
+trait CollateStep<X, Prev> {
+ type Pass;
+ type Fail;
+ fn collate_step(x: X, prev: Prev) -> (Self::Pass, Self::Fail);
+}
+
+impl<X, P, F> CollateStep<X, (P, F)> for () {
+ type Pass = (X, P);
+ type Fail = F;
+
+ fn collate_step(x: X, (p, f): (P, F)) -> ((X, P), F) {
+ ((x, p), f)
+ }
+}
+
+struct CollateOpImpl<const MASK: u32>;
+trait CollateOpStep {
+ type NextOp;
+ type Apply;
+}
+
+impl<const MASK: u32> CollateOpStep for CollateOpImpl<MASK>
+where
+ CollateOpImpl<{ MASK >> 1 }>: Sized,
+{
+ type NextOp = CollateOpImpl<{ MASK >> 1 }>;
+ type Apply = ();
+}
+
+impl<H, T, Op: CollateOpStep> Collate<Op> for (H, T)
+where
+ T: Collate<Op::NextOp>,
+ Op::Apply: CollateStep<H, (T::Pass, T::Fail)>,
+{
+ type Pass = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Pass;
+ type Fail = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Fail;
+
+ fn collate(self) -> (Self::Pass, Self::Fail) {
+ <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::collate_step(self.0, self.1.collate())
+ }
+}
+
+fn collate<X, const MASK: u32>(x: X) -> (X::Pass, X::Fail)
+where
+ X: Collate<CollateOpImpl<MASK>>,
+{
+ x.collate()
+}
+
+fn main() {
+ dbg!(collate::<_, 5>(("Hello", (42, ('!', ())))));
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
index 0332e82fe..b693023f1 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
@@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait
LL | fn size(&self) -> [usize; DIM] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
|
- = note: expected type `Self::DIM`
- found type `DIM`
+ = note: expected constant `Self::DIM`
+ found constant `DIM`
error: unconstrained generic constant
--> $DIR/issue-83765.rs:32:24
@@ -26,8 +26,8 @@ error[E0308]: mismatched types
LL | self.reference.size()
| ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
|
- = note: expected type `DIM`
- found type `Self::DIM`
+ = note: expected constant `DIM`
+ found constant `Self::DIM`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83972.rs b/src/test/ui/const-generics/generic_const_exprs/issue-83972.rs
new file mode 100644
index 000000000..0063719b8
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-83972.rs
@@ -0,0 +1,38 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+pub trait Foo {
+ fn foo(&self);
+}
+
+pub struct FooImpl<const N: usize>;
+impl<const N: usize> Foo for FooImpl<N> {
+ fn foo(&self) {}
+}
+
+pub trait Bar: 'static {
+ type Foo: Foo;
+ fn get() -> &'static Self::Foo;
+}
+
+struct BarImpl;
+impl Bar for BarImpl {
+ type Foo = FooImpl<
+ {
+ { 4 }
+ },
+ >;
+ fn get() -> &'static Self::Foo {
+ &FooImpl
+ }
+}
+
+pub fn boom<B: Bar>() {
+ B::get().foo();
+}
+
+fn main() {
+ boom::<BarImpl>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-84669.rs b/src/test/ui/const-generics/generic_const_exprs/issue-84669.rs
new file mode 100644
index 000000000..3933ff20a
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-84669.rs
@@ -0,0 +1,30 @@
+// build-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ type Output;
+
+ fn foo() -> Self::Output;
+}
+
+impl Foo for [u8; 3] {
+ type Output = [u8; 1 + 2];
+
+ fn foo() -> [u8; 3] {
+ [1u8; 3]
+ }
+}
+
+fn bug<const N: usize>()
+where
+ [u8; N]: Foo,
+ <[u8; N] as Foo>::Output: AsRef<[u8]>,
+{
+ <[u8; N]>::foo().as_ref();
+}
+
+fn main() {
+ bug::<3>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
index d45dfde9a..09bcb0860 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -7,12 +7,12 @@ LL | writes_to_specific_path(&cap);
| required by a bound introduced by this call
|
= help: the trait `Delegates<U>` is implemented for `T`
-note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+note: required for `&C` to implement `Contains<(), true>`
--> $DIR/issue-85848.rs:21:12
|
LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
-note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+note: required for `&C` to implement `Delegates<()>`
--> $DIR/issue-85848.rs:12:12
|
LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
@@ -32,12 +32,12 @@ LL | writes_to_specific_path(&cap);
| required by a bound introduced by this call
|
= help: try adding a `where` bound using this expression: `where [(); { contains::<T, U>() }]:`
-note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+note: required for `&C` to implement `Contains<(), true>`
--> $DIR/issue-85848.rs:21:12
|
LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
-note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+note: required for `&C` to implement `Delegates<()>`
--> $DIR/issue-85848.rs:12:12
|
LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
@@ -54,8 +54,8 @@ error[E0308]: mismatched types
LL | writes_to_specific_path(&cap);
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `{ contains::<T, U>() }`
|
- = note: expected type `true`
- found type `{ contains::<T, U>() }`
+ = note: expected constant `true`
+ found constant `{ contains::<T, U>() }`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-86710.rs b/src/test/ui/const-generics/generic_const_exprs/issue-86710.rs
new file mode 100644
index 000000000..bdd8a21b3
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-86710.rs
@@ -0,0 +1,73 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+use std::marker::PhantomData;
+
+fn main() {
+ let x = FooImpl::<BarImpl<1>> { phantom: PhantomData };
+ let _ = x.foo::<BarImpl<1>>();
+}
+
+trait Foo<T>
+where
+ T: Bar,
+{
+ fn foo<U>(&self)
+ where
+ T: Operation<U>,
+ <T as Operation<U>>::Output: Bar;
+}
+
+struct FooImpl<T>
+where
+ T: Bar,
+{
+ phantom: PhantomData<T>,
+}
+
+impl<T> Foo<T> for FooImpl<T>
+where
+ T: Bar,
+{
+ fn foo<U>(&self)
+ where
+ T: Operation<U>,
+ <T as Operation<U>>::Output: Bar,
+ {
+ <<T as Operation<U>>::Output as Bar>::error_occurs_here();
+ }
+}
+
+trait Bar {
+ fn error_occurs_here();
+}
+
+struct BarImpl<const N: usize>;
+
+impl<const N: usize> Bar for BarImpl<N> {
+ fn error_occurs_here() {}
+}
+
+trait Operation<Rhs> {
+ type Output;
+}
+
+//// Part-A: This causes error.
+impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N>
+where
+ BarImpl<{ N + M }>: Sized,
+{
+ type Output = BarImpl<{ N + M }>;
+}
+
+//// Part-B: This doesn't cause error.
+// impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> {
+// type Output = BarImpl<M>;
+// }
+
+//// Part-C: This also doesn't cause error.
+// impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> {
+// type Output = BarImpl<{ M }>;
+// }
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-89851.rs b/src/test/ui/const-generics/generic_const_exprs/issue-89851.rs
new file mode 100644
index 000000000..cde849d90
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-89851.rs
@@ -0,0 +1,12 @@
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+pub const BAR: () = ice::<"">();
+pub const fn ice<const N: &'static str>() {
+ &10;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs
new file mode 100644
index 000000000..e7c8e4f66
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs
@@ -0,0 +1,24 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait True {}
+
+struct Is<const V: bool>;
+
+impl True for Is<true> {}
+
+fn g<T>()
+//~^ NOTE required by a bound in this
+where
+ Is<{ std::mem::size_of::<T>() == 0 }>: True,
+ //~^ NOTE required by a bound in `g`
+ //~| NOTE required by this bound in `g`
+{
+}
+
+fn main() {
+ g::<usize>();
+ //~^ ERROR mismatched types
+ //~| NOTE expected `false`, found `true`
+ //~| NOTE expected constant `false`
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr
new file mode 100644
index 000000000..a253ec676
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/obligation-cause.rs:20:5
+ |
+LL | g::<usize>();
+ | ^^^^^^^^^^ expected `false`, found `true`
+ |
+ = note: expected constant `false`
+ found constant `true`
+note: required by a bound in `g`
+ --> $DIR/obligation-cause.rs:13:44
+ |
+LL | fn g<T>()
+ | - required by a bound in this
+...
+LL | Is<{ std::mem::size_of::<T>() == 0 }>: True,
+ | ^^^^ required by this bound in `g`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
index b1b359619..d955b4f96 100644
--- a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
+++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
@@ -2,15 +2,22 @@ error[E0107]: this associated function takes 0 generic arguments but 1 generic a
--> $DIR/invalid-const-arg-for-type-param.rs:6:23
|
LL | let _: u32 = 5i32.try_into::<32>().unwrap();
- | ^^^^^^^^------ help: remove these generics
- | |
- | expected 0 generic arguments
+ | ^^^^^^^^ expected 0 generic arguments
|
note: associated function defined here, with 0 generic parameters
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn try_into(self) -> Result<T, Self::Error>;
| ^^^^^^^^
+help: consider moving this generic argument to the `TryInto` trait, which takes up to 1 argument
+ |
+LL | let _: u32 = TryInto::<32>::try_into(5i32).unwrap();
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+help: remove these generics
+ |
+LL - let _: u32 = 5i32.try_into::<32>().unwrap();
+LL + let _: u32 = 5i32.try_into().unwrap();
+ |
error[E0599]: no method named `f` found for struct `S` in the current scope
--> $DIR/invalid-const-arg-for-type-param.rs:9:7
diff --git a/src/test/ui/const-generics/issue-103243.rs b/src/test/ui/const-generics/issue-103243.rs
new file mode 100644
index 000000000..78c73522b
--- /dev/null
+++ b/src/test/ui/const-generics/issue-103243.rs
@@ -0,0 +1,37 @@
+// build-pass
+
+pub trait CSpace<const N: usize>: Sized {
+ type Traj;
+}
+
+pub trait FullTrajectory<T, S1, const N: usize> {}
+
+pub struct Const<const R: usize>;
+
+pub trait Obstacle<CS, const N: usize>
+where
+ CS: CSpace<N>,
+{
+ fn trajectory_free<FT, S1>(&self, t: &FT)
+ where
+ FT: FullTrajectory<CS::Traj, S1, N>;
+}
+
+// -----
+
+const N: usize = 4;
+
+struct ObstacleSpace2df32;
+
+impl<CS> Obstacle<CS, N> for ObstacleSpace2df32
+where
+ CS: CSpace<N>,
+{
+ fn trajectory_free<TF, S1>(&self, t: &TF)
+ where
+ TF: FullTrajectory<CS::Traj, S1, N>,
+ {
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-100313.rs b/src/test/ui/const-generics/issues/issue-100313.rs
new file mode 100644
index 000000000..4e9d3626a
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-100313.rs
@@ -0,0 +1,21 @@
+#![allow(incomplete_features)]
+#![feature(const_mut_refs)]
+#![feature(adt_const_params)]
+
+struct T<const B: &'static bool>;
+
+impl <const B: &'static bool> T<B> {
+ const fn set_false(&self) {
+ unsafe {
+ *(B as *const bool as *mut bool) = false;
+ //~^ ERROR evaluation of constant value failed [E0080]
+ }
+ }
+}
+
+const _: () = {
+ let x = T::<{&true}>;
+ x.set_false();
+};
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-100313.stderr b/src/test/ui/const-generics/issues/issue-100313.stderr
new file mode 100644
index 000000000..f3ce357c2
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-100313.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-100313.rs:10:13
+ |
+LL | *(B as *const bool as *mut bool) = false;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | writing to alloc7 which is read-only
+ | inside `T::<&true>::set_false` at $DIR/issue-100313.rs:10:13
+...
+LL | x.set_false();
+ | ------------- inside `_` at $DIR/issue-100313.rs:18:5
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/issues/issue-73260.stderr b/src/test/ui/const-generics/issues/issue-73260.stderr
index f1fc50e6e..7670032e5 100644
--- a/src/test/ui/const-generics/issues/issue-73260.stderr
+++ b/src/test/ui/const-generics/issues/issue-73260.stderr
@@ -4,8 +4,16 @@ error[E0308]: mismatched types
LL | let x: Arr<{usize::MAX}> = Arr {};
| ^^^^^^^^^^^^^^^^^ expected `false`, found `true`
|
- = note: expected type `false`
- found type `true`
+ = note: expected constant `false`
+ found constant `true`
+note: required by a bound in `Arr`
+ --> $DIR/issue-73260.rs:6:37
+ |
+LL | struct Arr<const N: usize>
+ | --- required by a bound in this
+LL | where
+LL | Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^^^^^^ required by this bound in `Arr`
error[E0308]: mismatched types
--> $DIR/issue-73260.rs:16:32
@@ -13,8 +21,16 @@ error[E0308]: mismatched types
LL | let x: Arr<{usize::MAX}> = Arr {};
| ^^^ expected `false`, found `true`
|
- = note: expected type `false`
- found type `true`
+ = note: expected constant `false`
+ found constant `true`
+note: required by a bound in `Arr`
+ --> $DIR/issue-73260.rs:6:37
+ |
+LL | struct Arr<const N: usize>
+ | --- required by a bound in this
+LL | where
+LL | Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^^^^^^ required by this bound in `Arr`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/const-generics/issues/issue-79674.stderr b/src/test/ui/const-generics/issues/issue-79674.stderr
index 8c029289c..02b48b55f 100644
--- a/src/test/ui/const-generics/issues/issue-79674.stderr
+++ b/src/test/ui/const-generics/issues/issue-79674.stderr
@@ -4,8 +4,16 @@ error[E0308]: mismatched types
LL | requires_distinct("str", 12);
| ^^^^^^^^^^^^^^^^^ expected `true`, found `false`
|
- = note: expected type `true`
- found type `false`
+ = note: expected constant `true`
+ found constant `false`
+note: required by a bound in `requires_distinct`
+ --> $DIR/issue-79674.rs:23:37
+ |
+LL | fn requires_distinct<A, B>(_a: A, _b: B) where
+ | ----------------- required by a bound in this
+LL | A: MiniTypeId, B: MiniTypeId,
+LL | Lift<{is_same_type::<A, B>()}>: IsFalse {}
+ | ^^^^^^^ required by this bound in `requires_distinct`
error: aborting due to previous error
diff --git a/src/test/ui/const-generics/issues/issue-83466.rs b/src/test/ui/const-generics/issues/issue-83466.rs
index c488a663f..73c930101 100644
--- a/src/test/ui/const-generics/issues/issue-83466.rs
+++ b/src/test/ui/const-generics/issues/issue-83466.rs
@@ -1,5 +1,5 @@
// regression test for #83466- tests that generic arg mismatch errors between
-// consts and types are not supressed when there are explicit late bound lifetimes
+// consts and types are not suppressed when there are explicit late bound lifetimes
struct S;
impl S {
diff --git a/src/test/ui/const-generics/issues/issue-83765.stderr b/src/test/ui/const-generics/issues/issue-83765.stderr
index 28ddddf1b..d5f914f46 100644
--- a/src/test/ui/const-generics/issues/issue-83765.stderr
+++ b/src/test/ui/const-generics/issues/issue-83765.stderr
@@ -4,13 +4,13 @@ error[E0391]: cycle detected when resolving instance `<LazyUpdim<T, { T::DIM },
LL | const DIM: usize;
| ^^^^^^^^^^^^^^^^
|
-note: ...which requires checking if `TensorDimension` fulfills its obligations...
+note: ...which requires computing candidate for `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>`...
--> $DIR/issue-83765.rs:4:1
|
LL | trait TensorDimension {
| ^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires resolving instance `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>::DIM`, completing the cycle
-note: cycle used when checking if `TensorDimension` fulfills its obligations
+note: cycle used when computing candidate for `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>`
--> $DIR/issue-83765.rs:4:1
|
LL | trait TensorDimension {
diff --git a/src/test/ui/const-generics/issues/issue-87493.stderr b/src/test/ui/const-generics/issues/issue-87493.stderr
index f998c1187..653afae21 100644
--- a/src/test/ui/const-generics/issues/issue-87493.stderr
+++ b/src/test/ui/const-generics/issues/issue-87493.stderr
@@ -13,15 +13,17 @@ error[E0107]: this trait takes 0 generic arguments but 1 generic argument was su
--> $DIR/issue-87493.rs:8:8
|
LL | T: MyTrait<Assoc == S::Assoc>,
- | ^^^^^^^ ----------------- help: replace the generic bound with the associated type: `Assoc = Assoc == S::Assoc`
- | |
- | expected 0 generic arguments
+ | ^^^^^^^ expected 0 generic arguments
|
note: trait defined here, with 0 generic parameters
--> $DIR/issue-87493.rs:1:11
|
LL | pub trait MyTrait {
| ^^^^^^^
+help: replace the generic bound with the associated type
+ |
+LL | T: MyTrait<Assoc = Assoc == S::Assoc>,
+ | +++++++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
index f5396b838..be92429e3 100644
--- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
@@ -22,19 +22,14 @@ error[E0308]: mismatched types
LL | get_flag::<42, 0x5ad>();
| ^^^^^ expected `char`, found `u8`
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:38:21
+error[E0080]: evaluation of constant value failed
+ --> $DIR/invalid-patterns.rs:38:32
|
LL | get_flag::<false, { unsafe { char_raw.character } }>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:40:14
+ --> $DIR/invalid-patterns.rs:41:14
|
LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@@ -45,7 +40,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:42:14
+ --> $DIR/invalid-patterns.rs:43:14
|
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@@ -55,16 +50,11 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
42 │ B
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:42:47
+error[E0080]: evaluation of constant value failed
+ --> $DIR/invalid-patterns.rs:43:58
|
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 8 previous errors
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
index f5396b838..be92429e3 100644
--- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
@@ -22,19 +22,14 @@ error[E0308]: mismatched types
LL | get_flag::<42, 0x5ad>();
| ^^^^^ expected `char`, found `u8`
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:38:21
+error[E0080]: evaluation of constant value failed
+ --> $DIR/invalid-patterns.rs:38:32
|
LL | get_flag::<false, { unsafe { char_raw.character } }>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:40:14
+ --> $DIR/invalid-patterns.rs:41:14
|
LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@@ -45,7 +40,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:42:14
+ --> $DIR/invalid-patterns.rs:43:14
|
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@@ -55,16 +50,11 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
42 │ B
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/invalid-patterns.rs:42:47
+error[E0080]: evaluation of constant value failed
+ --> $DIR/invalid-patterns.rs:43:58
|
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 8 previous errors
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
index 682e0eced..13b2cca2f 100644
--- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
@@ -36,10 +36,12 @@ fn main() {
get_flag::<false, { unsafe { char_raw.character } }>();
- //~^ ERROR it is undefined behavior
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
//~^ ERROR it is undefined behavior
get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
- //~^ ERROR it is undefined behavior
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
//~| ERROR it is undefined behavior
}
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
index 486506239..b6a22df74 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
+++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4`
|
- = note: expected type `2`
- found type `4`
+ = note: expected constant `2`
+ found constant `4`
error[E0308]: mismatched types
--> $DIR/types-mismatch-const-args.rs:16:41
diff --git a/src/test/ui/consts/assert-type-intrinsics.rs b/src/test/ui/consts/assert-type-intrinsics.rs
index 38e5c454e..3ce3e1bdb 100644
--- a/src/test/ui/consts/assert-type-intrinsics.rs
+++ b/src/test/ui/consts/assert-type-intrinsics.rs
@@ -13,10 +13,10 @@ fn main() {
const _BAD1: () = unsafe {
MaybeUninit::<!>::uninit().assume_init();
};
- const _BAD2: () = unsafe {
+ const _BAD2: () = {
intrinsics::assert_uninit_valid::<bool>();
};
- const _BAD3: () = unsafe {
+ const _BAD3: () = {
intrinsics::assert_zero_valid::<&'static i32>();
};
}
diff --git a/src/test/ui/consts/assert-type-intrinsics.stderr b/src/test/ui/consts/assert-type-intrinsics.stderr
index f3b9170d4..6eab10197 100644
--- a/src/test/ui/consts/assert-type-intrinsics.stderr
+++ b/src/test/ui/consts/assert-type-intrinsics.stderr
@@ -13,7 +13,7 @@ LL | MaybeUninit::<!>::uninit().assume_init();
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:17:9
|
-LL | const _BAD2: () = unsafe {
+LL | const _BAD2: () = {
| ---------------
LL | intrinsics::assert_uninit_valid::<bool>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
@@ -24,7 +24,7 @@ LL | intrinsics::assert_uninit_valid::<bool>();
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:20:9
|
-LL | const _BAD3: () = unsafe {
+LL | const _BAD3: () = {
| ---------------
LL | intrinsics::assert_zero_valid::<&'static i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
@@ -51,7 +51,7 @@ Future breakage diagnostic:
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:17:9
|
-LL | const _BAD2: () = unsafe {
+LL | const _BAD2: () = {
| ---------------
LL | intrinsics::assert_uninit_valid::<bool>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
@@ -64,7 +64,7 @@ Future breakage diagnostic:
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:20:9
|
-LL | const _BAD3: () = unsafe {
+LL | const _BAD3: () = {
| ---------------
LL | intrinsics::assert_zero_valid::<&'static i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
diff --git a/src/test/ui/consts/const-block-const-bound.stderr b/src/test/ui/consts/const-block-const-bound.stderr
index 87ca771e5..b9c4d8866 100644
--- a/src/test/ui/consts/const-block-const-bound.stderr
+++ b/src/test/ui/consts/const-block-const-bound.stderr
@@ -2,7 +2,7 @@ error[E0277]: can't drop `UnconstDrop` in const contexts
--> $DIR/const-block-const-bound.rs:20:11
|
LL | f(UnconstDrop);
- | - ^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
+ | - ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop`
| |
| required by a bound introduced by this call
|
@@ -23,7 +23,7 @@ error[E0277]: can't drop `NonDrop` in const contexts
--> $DIR/const-block-const-bound.rs:22:11
|
LL | f(NonDrop);
- | - ^^^^^^^ expected an implementor of trait `~const Destruct`
+ | - ^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
index 5306fed22..ee352700c 100644
--- a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
+++ b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
LL | let _: [Option<Bar>; 2] = [no_copy(); 2];
| ^^^^^^^^^ the trait `Copy` is not implemented for `Bar`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+ = note: required for `Option<Bar>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
= help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];`
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
diff --git a/src/test/ui/consts/const-blocks/migrate-fail.stderr b/src/test/ui/consts/const-blocks/migrate-fail.stderr
index 803281c07..928ffd083 100644
--- a/src/test/ui/consts/const-blocks/migrate-fail.stderr
+++ b/src/test/ui/consts/const-blocks/migrate-fail.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^ the trait `Copy` is not implemented for `Bar`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+ = note: required for `Option<Bar>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
help: consider annotating `Bar` with `#[derive(Copy)]`
|
@@ -17,7 +17,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^ the trait `Copy` is not implemented for `Bar`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+ = note: required for `Option<Bar>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
help: consider annotating `Bar` with `#[derive(Copy)]`
|
diff --git a/src/test/ui/consts/const-blocks/nll-fail.stderr b/src/test/ui/consts/const-blocks/nll-fail.stderr
index 8841af15d..fede00845 100644
--- a/src/test/ui/consts/const-blocks/nll-fail.stderr
+++ b/src/test/ui/consts/const-blocks/nll-fail.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^ the trait `Copy` is not implemented for `Bar`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+ = note: required for `Option<Bar>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
help: consider annotating `Bar` with `#[derive(Copy)]`
|
@@ -17,7 +17,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^ the trait `Copy` is not implemented for `Bar`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+ = note: required for `Option<Bar>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
help: consider annotating `Bar` with `#[derive(Copy)]`
|
diff --git a/src/test/ui/consts/const-blocks/trait-error.stderr b/src/test/ui/consts/const-blocks/trait-error.stderr
index ece200ad1..b11dd4b80 100644
--- a/src/test/ui/consts/const-blocks/trait-error.stderr
+++ b/src/test/ui/consts/const-blocks/trait-error.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
LL | [Foo(String::new()); 4];
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
-note: required because of the requirements on the impl of `Copy` for `Foo<String>`
+note: required for `Foo<String>` to implement `Copy`
--> $DIR/trait-error.rs:1:10
|
LL | #[derive(Copy, Clone)]
diff --git a/src/test/ui/consts/const-err4.32bit.stderr b/src/test/ui/consts/const-err4.32bit.stderr
index a55384783..1cbf78173 100644
--- a/src/test/ui/consts/const-err4.32bit.stderr
+++ b/src/test/ui/consts/const-err4.32bit.stderr
@@ -1,13 +1,8 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/const-err4.rs:9:11
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-err4.rs:9:21
|
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-err4.64bit.stderr b/src/test/ui/consts/const-err4.64bit.stderr
index 66bfc30c3..1cbf78173 100644
--- a/src/test/ui/consts/const-err4.64bit.stderr
+++ b/src/test/ui/consts/const-err4.64bit.stderr
@@ -1,13 +1,8 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/const-err4.rs:9:11
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-err4.rs:9:21
|
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 8) {
- __ __ __ __ __ __ __ __ │ ░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-err4.rs b/src/test/ui/consts/const-err4.rs
index f0625faa8..107dc3f82 100644
--- a/src/test/ui/consts/const-err4.rs
+++ b/src/test/ui/consts/const-err4.rs
@@ -7,7 +7,8 @@ union Foo {
enum Bar {
Boo = [unsafe { Foo { b: () }.a }; 4][3],
- //~^ ERROR it is undefined behavior to use this value
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
}
fn main() {
diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
index b7b00f7d7..12d5b7bd6 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
@@ -54,19 +54,14 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/const-pointer-values-in-various-types.rs:46:5
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:46:47
|
LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 16, align: 8) {
- __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:49:43
+ --> $DIR/const-pointer-values-in-various-types.rs:50:43
|
LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -77,7 +72,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:53:45
+ --> $DIR/const-pointer-values-in-various-types.rs:54:45
|
LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -88,7 +83,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:57:45
+ --> $DIR/const-pointer-values-in-various-types.rs:58:45
|
LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -99,7 +94,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:61:45
+ --> $DIR/const-pointer-values-in-various-types.rs:62:45
|
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -109,19 +104,14 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/const-pointer-values-in-various-types.rs:65:5
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:66:47
|
LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 16, align: 8) {
- __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:68:45
+ --> $DIR/const-pointer-values-in-various-types.rs:70:45
|
LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -132,7 +122,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:72:45
+ --> $DIR/const-pointer-values-in-various-types.rs:74:45
|
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -143,7 +133,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:76:47
+ --> $DIR/const-pointer-values-in-various-types.rs:78:47
|
LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -154,7 +144,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:80:47
+ --> $DIR/const-pointer-values-in-various-types.rs:82:47
|
LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -165,7 +155,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:84:39
+ --> $DIR/const-pointer-values-in-various-types.rs:86:39
|
LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -176,7 +166,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:88:41
+ --> $DIR/const-pointer-values-in-various-types.rs:90:41
|
LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -187,7 +177,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:92:41
+ --> $DIR/const-pointer-values-in-various-types.rs:94:41
|
LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -198,7 +188,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:96:41
+ --> $DIR/const-pointer-values-in-various-types.rs:98:41
|
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -209,7 +199,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:100:43
+ --> $DIR/const-pointer-values-in-various-types.rs:102:43
|
LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -220,7 +210,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:104:39
+ --> $DIR/const-pointer-values-in-various-types.rs:106:39
|
LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -231,7 +221,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:108:41
+ --> $DIR/const-pointer-values-in-various-types.rs:110:41
|
LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -242,7 +232,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:112:41
+ --> $DIR/const-pointer-values-in-various-types.rs:114:41
|
LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -253,7 +243,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:116:41
+ --> $DIR/const-pointer-values-in-various-types.rs:118:41
|
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -264,7 +254,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:120:43
+ --> $DIR/const-pointer-values-in-various-types.rs:122:43
|
LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -275,7 +265,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:124:41
+ --> $DIR/const-pointer-values-in-various-types.rs:126:41
|
LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -286,7 +276,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:128:41
+ --> $DIR/const-pointer-values-in-various-types.rs:130:41
|
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -297,7 +287,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:132:43
+ --> $DIR/const-pointer-values-in-various-types.rs:134:43
|
LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -308,7 +298,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:136:43
+ --> $DIR/const-pointer-values-in-various-types.rs:138:43
|
LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -388,7 +378,7 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:49:43
+ --> $DIR/const-pointer-values-in-various-types.rs:50:43
|
LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -401,7 +391,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:53:45
+ --> $DIR/const-pointer-values-in-various-types.rs:54:45
|
LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -414,7 +404,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:57:45
+ --> $DIR/const-pointer-values-in-various-types.rs:58:45
|
LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -427,7 +417,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:61:45
+ --> $DIR/const-pointer-values-in-various-types.rs:62:45
|
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -440,7 +430,7 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:68:45
+ --> $DIR/const-pointer-values-in-various-types.rs:70:45
|
LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -453,7 +443,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:72:45
+ --> $DIR/const-pointer-values-in-various-types.rs:74:45
|
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -466,7 +456,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:76:47
+ --> $DIR/const-pointer-values-in-various-types.rs:78:47
|
LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -479,7 +469,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:80:47
+ --> $DIR/const-pointer-values-in-various-types.rs:82:47
|
LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -492,7 +482,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:84:39
+ --> $DIR/const-pointer-values-in-various-types.rs:86:39
|
LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -505,7 +495,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:88:41
+ --> $DIR/const-pointer-values-in-various-types.rs:90:41
|
LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -518,7 +508,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:92:41
+ --> $DIR/const-pointer-values-in-various-types.rs:94:41
|
LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -531,7 +521,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:96:41
+ --> $DIR/const-pointer-values-in-various-types.rs:98:41
|
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -544,7 +534,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:100:43
+ --> $DIR/const-pointer-values-in-various-types.rs:102:43
|
LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -557,7 +547,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:104:39
+ --> $DIR/const-pointer-values-in-various-types.rs:106:39
|
LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -570,7 +560,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:108:41
+ --> $DIR/const-pointer-values-in-various-types.rs:110:41
|
LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -583,7 +573,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:112:41
+ --> $DIR/const-pointer-values-in-various-types.rs:114:41
|
LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -596,7 +586,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:116:41
+ --> $DIR/const-pointer-values-in-various-types.rs:118:41
|
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -609,7 +599,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:120:43
+ --> $DIR/const-pointer-values-in-various-types.rs:122:43
|
LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -622,7 +612,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:124:41
+ --> $DIR/const-pointer-values-in-various-types.rs:126:41
|
LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -635,7 +625,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:128:41
+ --> $DIR/const-pointer-values-in-various-types.rs:130:41
|
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -648,7 +638,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:132:43
+ --> $DIR/const-pointer-values-in-various-types.rs:134:43
|
LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -661,7 +651,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/const-pointer-values-in-various-types.rs:136:43
+ --> $DIR/const-pointer-values-in-various-types.rs:138:43
|
LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs
index f10a67392..f6a5e4d3c 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs
@@ -44,7 +44,8 @@ fn main() {
//~| WARN this was previously accepted by the compiler but is being phased out
const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
- //~^ ERROR it is undefined behavior to use this value
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
//~^ ERROR any use of this value will cause an error
@@ -63,7 +64,8 @@ fn main() {
//~| WARN this was previously accepted by the compiler but is being phased out
const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
- //~^ ERROR it is undefined behavior to use this value
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
//~^ ERROR any use of this value will cause an error
diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
index f1a780926..a0f4519ea 100644
--- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
+++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:8:1
|
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
- | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized bytes, but expected initialized bytes
+ | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
index 2eb401226..d2bffa425 100644
--- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
+++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:8:1
|
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
- | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized bytes, but expected initialized bytes
+ | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
diff --git a/src/test/ui/consts/const-eval/issue-91827-extern-types.rs b/src/test/ui/consts/const-eval/issue-91827-extern-types.rs
index e1f5e8ae1..43c99799f 100644
--- a/src/test/ui/consts/const-eval/issue-91827-extern-types.rs
+++ b/src/test/ui/consts/const-eval/issue-91827-extern-types.rs
@@ -3,7 +3,6 @@
// Test that we can handle unsized types with an extern type tail part.
// Regression test for issue #91827.
-#![feature(const_ptr_offset_from)]
#![feature(extern_types)]
use std::ptr::addr_of;
diff --git a/src/test/ui/consts/const-eval/ub-enum-overwrite.rs b/src/test/ui/consts/const-eval/ub-enum-overwrite.rs
index c56778492..086a1001d 100644
--- a/src/test/ui/consts/const-eval/ub-enum-overwrite.rs
+++ b/src/test/ui/consts/const-eval/ub-enum-overwrite.rs
@@ -6,12 +6,13 @@ enum E {
}
const _: u8 = {
- //~^ ERROR is undefined behavior
let mut e = E::A(1);
let p = if let E::A(x) = &mut e { x as *mut u8 } else { unreachable!() };
// Make sure overwriting `e` uninitializes other bytes
e = E::B;
unsafe { *p }
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
};
fn main() {}
diff --git a/src/test/ui/consts/const-eval/ub-enum-overwrite.stderr b/src/test/ui/consts/const-eval/ub-enum-overwrite.stderr
index 8560112ae..5750212b4 100644
--- a/src/test/ui/consts/const-eval/ub-enum-overwrite.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum-overwrite.stderr
@@ -1,13 +1,8 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum-overwrite.rs:8:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum-overwrite.rs:13:14
|
-LL | const _: u8 = {
- | ^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 1, align: 1) {
- __ │ ░
- }
+LL | unsafe { *p }
+ | ^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
index ce3bc9474..752fd01f3 100644
--- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
@@ -65,19 +65,14 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:59:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:59:42
|
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: any use of this value will cause an error
- --> $DIR/ub-enum.rs:63:1
+ --> $DIR/ub-enum.rs:64:1
|
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -88,7 +83,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:81:1
+ --> $DIR/ub-enum.rs:82:1
|
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
@@ -99,7 +94,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:83:1
+ --> $DIR/ub-enum.rs:84:1
|
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
@@ -110,7 +105,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:91:1
+ --> $DIR/ub-enum.rs:92:1
|
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@@ -121,13 +116,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-enum.rs:96:77
+ --> $DIR/ub-enum.rs:97:77
|
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-enum.rs:98:77
+ --> $DIR/ub-enum.rs:99:77
|
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
@@ -189,7 +184,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-enum.rs:63:1
+ --> $DIR/ub-enum.rs:64:1
|
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
index d8fc20c98..3f1546a27 100644
--- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
@@ -65,19 +65,14 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:59:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:59:42
|
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 8) {
- __ __ __ __ __ __ __ __ │ ░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: any use of this value will cause an error
- --> $DIR/ub-enum.rs:63:1
+ --> $DIR/ub-enum.rs:64:1
|
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -88,7 +83,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:81:1
+ --> $DIR/ub-enum.rs:82:1
|
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
@@ -99,7 +94,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:83:1
+ --> $DIR/ub-enum.rs:84:1
|
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
@@ -110,7 +105,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:91:1
+ --> $DIR/ub-enum.rs:92:1
|
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@@ -121,13 +116,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-enum.rs:96:77
+ --> $DIR/ub-enum.rs:97:77
|
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-enum.rs:98:77
+ --> $DIR/ub-enum.rs:99:77
|
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
@@ -189,7 +184,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-enum.rs:63:1
+ --> $DIR/ub-enum.rs:64:1
|
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs
index d8d2a499b..d8dc6d057 100644
--- a/src/test/ui/consts/const-eval/ub-enum.rs
+++ b/src/test/ui/consts/const-eval/ub-enum.rs
@@ -57,7 +57,8 @@ union MaybeUninit<T: Copy> {
init: T,
}
const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
-//~^ ERROR is undefined behavior
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
// Pointer value in an enum with a niche that is not just 0.
const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
@@ -92,7 +93,7 @@ const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute
//~^ ERROR is undefined behavior
// All variants are uninhabited but also have data.
-// Use `0` as constant to make behavior endianess-independent.
+// Use `0` as constant to make behavior endianness-independent.
const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
//~^ ERROR evaluation of constant value failed
const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
diff --git a/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr b/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr
index 8eece9e30..6100a98d1 100644
--- a/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr
@@ -1,35 +1,20 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-int-array.rs:14:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:16:9
|
-LL | const UNINIT_INT_0: [u32; 3] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 12, align: 4) {
- __ __ __ __ 01 00 00 00 02 00 00 00 │ ░░░░........
- }
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-int-array.rs:23:1
- |
-LL | const UNINIT_INT_1: [u32; 3] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized bytes
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:31:13
|
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 12, align: 4) {
- 00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░.
- }
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-int-array.rs:43:1
- |
-LL | const UNINIT_INT_2: [u32; 3] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized bytes
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:57:13
|
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 12, align: 4) {
- 00 00 00 00 01 01 01 01 02 02 02 __ │ ...........░
- }
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/const-eval/ub-int-array.64bit.stderr b/src/test/ui/consts/const-eval/ub-int-array.64bit.stderr
index 8eece9e30..6100a98d1 100644
--- a/src/test/ui/consts/const-eval/ub-int-array.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-int-array.64bit.stderr
@@ -1,35 +1,20 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-int-array.rs:14:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:16:9
|
-LL | const UNINIT_INT_0: [u32; 3] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 12, align: 4) {
- __ __ __ __ 01 00 00 00 02 00 00 00 │ ░░░░........
- }
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-int-array.rs:23:1
- |
-LL | const UNINIT_INT_1: [u32; 3] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized bytes
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:31:13
|
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 12, align: 4) {
- 00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░.
- }
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-int-array.rs:43:1
- |
-LL | const UNINIT_INT_2: [u32; 3] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized bytes
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:57:13
|
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 12, align: 4) {
- 00 00 00 00 01 01 01 01 02 02 02 __ │ ...........░
- }
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/const-eval/ub-int-array.rs b/src/test/ui/consts/const-eval/ub-int-array.rs
index 1221f71d1..cb85e3b01 100644
--- a/src/test/ui/consts/const-eval/ub-int-array.rs
+++ b/src/test/ui/consts/const-eval/ub-int-array.rs
@@ -12,17 +12,15 @@ union MaybeUninit<T: Copy> {
}
const UNINIT_INT_0: [u32; 3] = unsafe {
-//~^ ERROR it is undefined behavior to use this value
-//~| constructing invalid value at [0]: encountered uninitialized bytes
[
MaybeUninit { uninit: () }.init,
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
1,
2,
]
};
const UNINIT_INT_1: [u32; 3] = unsafe {
-//~^ ERROR it is undefined behavior to use this value
-//~| constructing invalid value at [1]: encountered uninitialized bytes
mem::transmute(
[
0u8,
@@ -31,6 +29,8 @@ const UNINIT_INT_1: [u32; 3] = unsafe {
0u8,
1u8,
MaybeUninit { uninit: () }.init,
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
1u8,
1u8,
2u8,
@@ -41,8 +41,6 @@ const UNINIT_INT_1: [u32; 3] = unsafe {
)
};
const UNINIT_INT_2: [u32; 3] = unsafe {
-//~^ ERROR it is undefined behavior to use this value
-//~| constructing invalid value at [2]: encountered uninitialized bytes
mem::transmute(
[
0u8,
@@ -57,6 +55,8 @@ const UNINIT_INT_2: [u32; 3] = unsafe {
2u8,
2u8,
MaybeUninit { uninit: () }.init,
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
]
)
};
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
index d450a814c..693c0e99b 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
@@ -37,19 +37,14 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
00 00 00 00 │ ....
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:33:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-nonnull.rs:33:36
|
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 1, align: 1) {
- __ │ ░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:41:1
+ --> $DIR/ub-nonnull.rs:42:1
|
LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
@@ -60,7 +55,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:47:1
+ --> $DIR/ub-nonnull.rs:48:1
|
LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
index ed0d91aab..d22191213 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
@@ -37,19 +37,14 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
00 00 00 00 00 00 00 00 │ ........
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:33:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-nonnull.rs:33:36
|
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 1, align: 1) {
- __ │ ░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:41:1
+ --> $DIR/ub-nonnull.rs:42:1
|
LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
@@ -60,7 +55,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:47:1
+ --> $DIR/ub-nonnull.rs:48:1
|
LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs
index 259707b80..777c6d988 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.rs
+++ b/src/test/ui/consts/const-eval/ub-nonnull.rs
@@ -31,7 +31,8 @@ union MaybeUninit<T: Copy> {
init: T,
}
const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
// Also test other uses of rustc_layout_scalar_valid_range_start
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
index e86b37929..3e93219c8 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
@@ -116,19 +116,14 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
39 05 00 00 │ 9...
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:53:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:53:41
|
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:56:1
+ --> $DIR/ub-ref-ptr.rs:57:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@@ -138,19 +133,14 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
00 00 00 00 │ ....
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:58:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:59:38
|
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a proper pointer or integer value
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 4, align: 4) {
- __ __ __ __ │ ░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:60:1
+ --> $DIR/ub-ref-ptr.rs:62:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@@ -161,7 +151,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:62:1
+ --> $DIR/ub-ref-ptr.rs:64:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
index eeec2dc4b..bc2aa12a2 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
@@ -116,19 +116,14 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
39 05 00 00 00 00 00 00 │ 9.......
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:53:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:53:41
|
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 8) {
- __ __ __ __ __ __ __ __ │ ░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:56:1
+ --> $DIR/ub-ref-ptr.rs:57:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@@ -138,19 +133,14 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
00 00 00 00 00 00 00 00 │ ........
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:58:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:59:38
|
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a proper pointer or integer value
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 8) {
- __ __ __ __ __ __ __ __ │ ░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:60:1
+ --> $DIR/ub-ref-ptr.rs:62:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@@ -161,7 +151,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:62:1
+ --> $DIR/ub-ref-ptr.rs:64:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.rs b/src/test/ui/consts/const-eval/ub-ref-ptr.rs
index d0216f746..c62848f70 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.rs
@@ -51,12 +51,14 @@ const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
//~^ ERROR it is undefined behavior to use this value
const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
//~^ ERROR it is undefined behavior to use this value
const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
//~^ ERROR it is undefined behavior to use this value
const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index c4f0e3ab4..4cd974e7b 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -76,19 +76,14 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni
╾─allocN─╼ 01 00 00 00 │ ╾──╼....
}
-error[E0080]: it is undefined behavior to use this value
+error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:63:1
|
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized reference
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 4) {
- 2a 00 00 00 __ __ __ __ │ *...░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:69:1
+ --> $DIR/ub-wide-ptr.rs:70:1
|
LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
@@ -99,7 +94,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:72:1
+ --> $DIR/ub-wide-ptr.rs:73:1
|
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
@@ -110,7 +105,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:75:1
+ --> $DIR/ub-wide-ptr.rs:76:1
|
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -121,7 +116,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:79:1
+ --> $DIR/ub-wide-ptr.rs:80:1
|
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
@@ -132,7 +127,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:82:1
+ --> $DIR/ub-wide-ptr.rs:83:1
|
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -143,7 +138,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:87:1
+ --> $DIR/ub-wide-ptr.rs:88:1
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
@@ -154,7 +149,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:87:40
+ --> $DIR/ub-wide-ptr.rs:88:40
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -163,7 +158,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:95:1
+ --> $DIR/ub-wide-ptr.rs:96:1
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
@@ -174,7 +169,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:95:42
+ --> $DIR/ub-wide-ptr.rs:96:42
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -183,7 +178,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:100:1
+ --> $DIR/ub-wide-ptr.rs:101:1
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
@@ -194,7 +189,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:100:42
+ --> $DIR/ub-wide-ptr.rs:101:42
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -202,19 +197,14 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:109:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:110:1
|
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 4) {
- 2a 00 00 00 __ __ __ __ │ *...░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:117:1
+ --> $DIR/ub-wide-ptr.rs:119:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@@ -225,7 +215,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:121:1
+ --> $DIR/ub-wide-ptr.rs:123:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@@ -236,7 +226,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:125:1
+ --> $DIR/ub-wide-ptr.rs:127:1
|
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
@@ -247,25 +237,25 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:128:57
+ --> $DIR/ub-wide-ptr.rs:130:57
|
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:131:57
+ --> $DIR/ub-wide-ptr.rs:133:57
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:134:56
+ --> $DIR/ub-wide-ptr.rs:136:56
|
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:137:1
+ --> $DIR/ub-wide-ptr.rs:139:1
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@@ -276,7 +266,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:142:1
+ --> $DIR/ub-wide-ptr.rs:144:1
|
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@@ -286,17 +276,27 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼
}
-error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:147:62
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:149:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾allocN─╼ 00 00 00 00 │ ╾──╼....
+ }
-error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:150:65
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:151:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼
+ }
error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:157:5
@@ -341,7 +341,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:75:1
+ --> $DIR/ub-wide-ptr.rs:76:1
|
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -354,7 +354,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:82:1
+ --> $DIR/ub-wide-ptr.rs:83:1
|
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -367,7 +367,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:87:40
+ --> $DIR/ub-wide-ptr.rs:88:40
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -378,7 +378,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:95:42
+ --> $DIR/ub-wide-ptr.rs:96:42
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -389,7 +389,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:100:42
+ --> $DIR/ub-wide-ptr.rs:101:42
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index d6c612bb4..1d84b7bce 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -76,19 +76,14 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni
╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
}
-error[E0080]: it is undefined behavior to use this value
+error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:63:1
|
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized reference
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 16, align: 8) {
- __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:69:1
+ --> $DIR/ub-wide-ptr.rs:70:1
|
LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
@@ -99,7 +94,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:72:1
+ --> $DIR/ub-wide-ptr.rs:73:1
|
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
@@ -110,7 +105,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:75:1
+ --> $DIR/ub-wide-ptr.rs:76:1
|
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -121,7 +116,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:79:1
+ --> $DIR/ub-wide-ptr.rs:80:1
|
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
@@ -132,7 +127,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:82:1
+ --> $DIR/ub-wide-ptr.rs:83:1
|
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -143,7 +138,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:87:1
+ --> $DIR/ub-wide-ptr.rs:88:1
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
@@ -154,7 +149,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:87:40
+ --> $DIR/ub-wide-ptr.rs:88:40
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -163,7 +158,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:95:1
+ --> $DIR/ub-wide-ptr.rs:96:1
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
@@ -174,7 +169,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:95:42
+ --> $DIR/ub-wide-ptr.rs:96:42
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -183,7 +178,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:100:1
+ --> $DIR/ub-wide-ptr.rs:101:1
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
@@ -194,7 +189,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
}
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:100:42
+ --> $DIR/ub-wide-ptr.rs:101:42
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -202,19 +197,14 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:109:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:110:1
|
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 16, align: 8) {
- __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:117:1
+ --> $DIR/ub-wide-ptr.rs:119:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@@ -225,7 +215,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:121:1
+ --> $DIR/ub-wide-ptr.rs:123:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@@ -236,7 +226,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:125:1
+ --> $DIR/ub-wide-ptr.rs:127:1
|
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
@@ -247,25 +237,25 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:128:57
+ --> $DIR/ub-wide-ptr.rs:130:57
|
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:131:57
+ --> $DIR/ub-wide-ptr.rs:133:57
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:134:56
+ --> $DIR/ub-wide-ptr.rs:136:56
|
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:137:1
+ --> $DIR/ub-wide-ptr.rs:139:1
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@@ -276,7 +266,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:142:1
+ --> $DIR/ub-wide-ptr.rs:144:1
|
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@@ -286,17 +276,27 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
}
-error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:147:62
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:149:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾──────allocN───────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
-error[E0080]: evaluation of constant value failed
- --> $DIR/ub-wide-ptr.rs:150:65
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:151:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
+ }
error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:157:5
@@ -341,7 +341,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:75:1
+ --> $DIR/ub-wide-ptr.rs:76:1
|
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -354,7 +354,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:82:1
+ --> $DIR/ub-wide-ptr.rs:83:1
|
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -367,7 +367,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:87:40
+ --> $DIR/ub-wide-ptr.rs:88:40
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -378,7 +378,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:95:42
+ --> $DIR/ub-wide-ptr.rs:96:42
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@@ -389,7 +389,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ub-wide-ptr.rs:100:42
+ --> $DIR/ub-wide-ptr.rs:101:42
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index a0377ab1e..788403a6d 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -61,7 +61,8 @@ const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::
const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) };
// bad slice: length uninit
const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
let uninit_len = MaybeUninit::<usize> { uninit: () };
mem::transmute((42, uninit_len))
};
@@ -107,7 +108,8 @@ const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) };
const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw
const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw
const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
let uninit_len = MaybeUninit::<usize> { uninit: () };
mem::transmute((42, uninit_len))
};
@@ -145,11 +147,9 @@ const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool
// # raw trait object
const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
-//~^ ERROR evaluation of constant value failed
-//~| null pointer
+//~^ ERROR it is undefined behavior to use this value
const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
-//~^ ERROR evaluation of constant value failed
-//~| does not point to a vtable
+//~^ ERROR it is undefined behavior to use this value
const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw
// Const eval fails for these, so they need to be statics to error.
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs
index a1e48cac4..d88bf2a84 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.rs
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs
@@ -26,7 +26,8 @@ const fn read_field2() -> Field2 {
const fn read_field3() -> Field3 {
const FIELD3: Field3 = unsafe { UNION.field3 };
- //~^ ERROR it is undefined behavior to use this value
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
FIELD3
//~^ ERROR erroneous constant used [E0080]
}
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
index c512e6825..00964489e 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
@@ -1,16 +1,11 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-const-eval-field.rs:28:5
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-const-eval-field.rs:28:37
|
LL | const FIELD3: Field3 = unsafe { UNION.field3 };
- | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 8) {
- __ __ __ __ __ __ __ __ │ ░░░░░░░░
- }
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: erroneous constant used
- --> $DIR/union-const-eval-field.rs:30:5
+ --> $DIR/union-const-eval-field.rs:31:5
|
LL | FIELD3
| ^^^^^^ referenced constant has errors
diff --git a/src/test/ui/consts/const-eval/union-ice.rs b/src/test/ui/consts/const-eval/union-ice.rs
index 4189619b2..dd970a355 100644
--- a/src/test/ui/consts/const-eval/union-ice.rs
+++ b/src/test/ui/consts/const-eval/union-ice.rs
@@ -11,11 +11,15 @@ union DummyUnion {
const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
-const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value
+const FIELD3: Field3 = unsafe { UNION.field3 };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
-const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to use this value
+const FIELD_PATH: Struct = Struct {
a: 42,
b: unsafe { UNION.field3 },
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
};
struct Struct {
@@ -23,10 +27,12 @@ struct Struct {
b: Field3,
}
-const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR it is undefined behavior to use this value
+const FIELD_PATH2: Struct2 = Struct2 {
b: [
21,
unsafe { UNION.field3 },
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
23,
24,
],
diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr
index 21a545509..bd39a0551 100644
--- a/src/test/ui/consts/const-eval/union-ice.stderr
+++ b/src/test/ui/consts/const-eval/union-ice.stderr
@@ -1,37 +1,20 @@
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ice.rs:14:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ice.rs:14:33
|
LL | const FIELD3: Field3 = unsafe { UNION.field3 };
- | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 8) {
- __ __ __ __ __ __ __ __ │ ░░░░░░░░
- }
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ice.rs:16:1
- |
-LL | const FIELD_PATH: Struct = Struct {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .b: encountered uninitialized bytes, but expected initialized bytes
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ice.rs:20:17
|
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 16, align: 8) {
- __ __ __ __ __ __ __ __ 2a __ __ __ __ __ __ __ │ ░░░░░░░░*░░░░░░░
- }
+LL | b: unsafe { UNION.field3 },
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ice.rs:26:1
- |
-LL | const FIELD_PATH2: Struct2 = Struct2 {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .b[1]: encountered uninitialized bytes
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ice.rs:33:18
|
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 40, align: 8) {
- 0x00 │ 15 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░
- 0x10 │ 17 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 │ ................
- 0x20 │ 2a __ __ __ __ __ __ __ │ *░░░░░░░
- }
+LL | unsafe { UNION.field3 },
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/const-eval/union-ub.32bit.stderr b/src/test/ui/consts/const-eval/union-ub.32bit.stderr
index baf682596..38ded4d65 100644
--- a/src/test/ui/consts/const-eval/union-ub.32bit.stderr
+++ b/src/test/ui/consts/const-eval/union-ub.32bit.stderr
@@ -9,16 +9,11 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
2a │ *
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub.rs:35:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ub.rs:35:36
|
LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a boolean
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 1, align: 1) {
- __ │ ░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 2 previous errors
diff --git a/src/test/ui/consts/const-eval/union-ub.64bit.stderr b/src/test/ui/consts/const-eval/union-ub.64bit.stderr
index baf682596..38ded4d65 100644
--- a/src/test/ui/consts/const-eval/union-ub.64bit.stderr
+++ b/src/test/ui/consts/const-eval/union-ub.64bit.stderr
@@ -9,16 +9,11 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
2a │ *
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub.rs:35:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ub.rs:35:36
|
LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a boolean
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 1, align: 1) {
- __ │ ░
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: aborting due to 2 previous errors
diff --git a/src/test/ui/consts/const-eval/union-ub.rs b/src/test/ui/consts/const-eval/union-ub.rs
index c1bfe69a7..bb29edcf8 100644
--- a/src/test/ui/consts/const-eval/union-ub.rs
+++ b/src/test/ui/consts/const-eval/union-ub.rs
@@ -33,7 +33,8 @@ union Bar {
const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
//~^ ERROR it is undefined behavior to use this value
const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
// The value is not valid for any union variant, but that's fine
// unions are just a convenient way to transmute bits around
diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr
index d6e993a10..01f2f4895 100644
--- a/src/test/ui/consts/const-float-bits-reject-conv.stderr
+++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr
@@ -10,16 +10,6 @@ LL | panic!("const-eval error: cannot use f32::to_bits on a
LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
| -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL
|
- ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
-LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
- | ------------------------------------------------------------------ inside `<fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32} as FnOnce<(f32,)>>::call_once - shim(fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
- ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
-LL | called_in_const.call_once(arg)
- | ------------------------------ inside `const_eval_select::<(f32,), fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32}, [closure@core::f32::<impl f32>::to_bits::{closure#0}], u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
::: $DIR/const-float-bits-reject-conv.rs:27:30
|
LL | const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
@@ -39,16 +29,6 @@ LL | panic!("const-eval error: cannot use f32::to_bits on a
LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
| -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL
|
- ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
-LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
- | ------------------------------------------------------------------ inside `<fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32} as FnOnce<(f32,)>>::call_once - shim(fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
- ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
-LL | called_in_const.call_once(arg)
- | ------------------------------ inside `const_eval_select::<(f32,), fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32}, [closure@core::f32::<impl f32>::to_bits::{closure#0}], u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
::: $DIR/const-float-bits-reject-conv.rs:28:30
|
LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
@@ -117,16 +97,6 @@ LL | panic!("const-eval error: cannot use f64::to_bits on a
LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
| -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL
|
- ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
-LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
- | ------------------------------------------------------------------ inside `<fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64} as FnOnce<(f64,)>>::call_once - shim(fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
- ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
-LL | called_in_const.call_once(arg)
- | ------------------------------ inside `const_eval_select::<(f64,), fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64}, [closure@core::f64::<impl f64>::to_bits::{closure#0}], u64>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
::: $DIR/const-float-bits-reject-conv.rs:54:30
|
LL | const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
@@ -146,16 +116,6 @@ LL | panic!("const-eval error: cannot use f64::to_bits on a
LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
| -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL
|
- ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
-LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
- | ------------------------------------------------------------------ inside `<fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64} as FnOnce<(f64,)>>::call_once - shim(fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
- ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
-LL | called_in_const.call_once(arg)
- | ------------------------------ inside `const_eval_select::<(f64,), fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64}, [closure@core::f64::<impl f64>::to_bits::{closure#0}], u64>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
- |
::: $DIR/const-float-bits-reject-conv.rs:55:30
|
LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
diff --git a/src/test/ui/consts/const-points-to-static.32bit.stderr b/src/test/ui/consts/const-points-to-static.32bit.stderr
index 97825dd0e..c7a435a1e 100644
--- a/src/test/ui/consts/const-points-to-static.32bit.stderr
+++ b/src/test/ui/consts/const-points-to-static.32bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-points-to-static.rs:6:1
|
LL | const TEST: &u8 = &MY_STATIC;
- | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
diff --git a/src/test/ui/consts/const-points-to-static.64bit.stderr b/src/test/ui/consts/const-points-to-static.64bit.stderr
index 0d4a5a8ce..4d5b8eac5 100644
--- a/src/test/ui/consts/const-points-to-static.64bit.stderr
+++ b/src/test/ui/consts/const-points-to-static.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-points-to-static.rs:6:1
|
LL | const TEST: &u8 = &MY_STATIC;
- | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
diff --git a/src/test/ui/consts/const_in_pattern/incomplete-slice.rs b/src/test/ui/consts/const_in_pattern/incomplete-slice.rs
new file mode 100644
index 000000000..e1ccda71d
--- /dev/null
+++ b/src/test/ui/consts/const_in_pattern/incomplete-slice.rs
@@ -0,0 +1,15 @@
+#[derive(PartialEq)]
+enum E {
+ A,
+}
+
+const E_SL: &[E] = &[E::A];
+
+fn main() {
+ match &[][..] {
+ //~^ ERROR non-exhaustive patterns: `&_` not covered [E0004]
+ E_SL => {}
+ //~^ WARN to use a constant of type `E` in a pattern, `E` must be annotated with `#[derive(PartialEq, Eq)]`
+ //~| WARN this was previously accepted by the compiler but is being phased out
+ }
+}
diff --git a/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr b/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr
new file mode 100644
index 000000000..0ff708371
--- /dev/null
+++ b/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr
@@ -0,0 +1,26 @@
+warning: to use a constant of type `E` in a pattern, `E` must be annotated with `#[derive(PartialEq, Eq)]`
+ --> $DIR/incomplete-slice.rs:11:9
+ |
+LL | E_SL => {}
+ | ^^^^
+ |
+ = note: `#[warn(indirect_structural_match)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+
+error[E0004]: non-exhaustive patterns: `&_` not covered
+ --> $DIR/incomplete-slice.rs:9:11
+ |
+LL | match &[][..] {
+ | ^^^^^^^ pattern `&_` not covered
+ |
+ = note: the matched value is of type `&[E]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ E_SL => {}
+LL + &_ => todo!()
+ |
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs
new file mode 100644
index 000000000..86fbadb94
--- /dev/null
+++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs
@@ -0,0 +1,45 @@
+// revisions: no_flag with_flag
+// [no_flag] check-pass
+// [with_flag] compile-flags: -Zextra-const-ub-checks
+#![feature(const_ptr_read)]
+
+use std::mem::transmute;
+
+const INVALID_BOOL: () = unsafe {
+ let _x: bool = transmute(3u8);
+ //[with_flag]~^ ERROR: evaluation of constant value failed
+ //[with_flag]~| invalid value
+};
+
+const INVALID_PTR_IN_INT: () = unsafe {
+ let _x: usize = transmute(&3u8);
+ //[with_flag]~^ ERROR: any use of this value will cause an error
+ //[with_flag]~| previously accepted
+};
+
+const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
+ let x: &[u8] = &[0; 32];
+ let _x: (usize, usize) = transmute(x);
+ //[with_flag]~^ ERROR: any use of this value will cause an error
+ //[with_flag]~| previously accepted
+};
+
+const UNALIGNED_PTR: () = unsafe {
+ let _x: &u32 = transmute(&[0u8; 4]);
+ //[with_flag]~^ ERROR: evaluation of constant value failed
+ //[with_flag]~| invalid value
+};
+
+const UNALIGNED_READ: () = {
+ INNER; //[with_flag]~ERROR any use of this value will cause an error
+ //[with_flag]~| previously accepted
+ // There is an error here but its span is in the standard library so we cannot match it...
+ // so we have this in a *nested* const, such that the *outer* const fails to use it.
+ const INNER: () = unsafe {
+ let x = &[0u8; 4];
+ let ptr = x.as_ptr().cast::<u32>();
+ ptr.read();
+ };
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
new file mode 100644
index 000000000..793725d3b
--- /dev/null
+++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
@@ -0,0 +1,117 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/detect-extra-ub.rs:9:20
+ |
+LL | let _x: bool = transmute(3u8);
+ | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
+
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:15:21
+ |
+LL | const INVALID_PTR_IN_INT: () = unsafe {
+ | ----------------------------
+LL | let _x: usize = transmute(&3u8);
+ | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:22:30
+ |
+LL | const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
+ | ------------------------------------------
+LL | let x: &[u8] = &[0; 32];
+LL | let _x: (usize, usize) = transmute(x);
+ | ^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/detect-extra-ub.rs:28:20
+ |
+LL | let _x: &u32 = transmute(&[0u8; 4]);
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
+
+error[E0080]: evaluation of constant value failed
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | accessing memory with alignment 1, but alignment 4 is required
+ | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+ ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { read(self) }
+ | ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+ ::: $DIR/detect-extra-ub.rs:41:9
+ |
+LL | ptr.read();
+ | ---------- inside `INNER` at $DIR/detect-extra-ub.rs:41:9
+
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:34:5
+ |
+LL | const UNALIGNED_READ: () = {
+ | ------------------------
+LL | INNER;
+ | ^^^^^ referenced constant has errors
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:15:21
+ |
+LL | const INVALID_PTR_IN_INT: () = unsafe {
+ | ----------------------------
+LL | let _x: usize = transmute(&3u8);
+ | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:22:30
+ |
+LL | const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
+ | ------------------------------------------
+LL | let x: &[u8] = &[0; 32];
+LL | let _x: (usize, usize) = transmute(x);
+ | ^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:34:5
+ |
+LL | const UNALIGNED_READ: () = {
+ | ------------------------
+LL | INNER;
+ | ^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/extra-const-ub/issue-100771.rs b/src/test/ui/consts/extra-const-ub/issue-100771.rs
new file mode 100644
index 000000000..a32960328
--- /dev/null
+++ b/src/test/ui/consts/extra-const-ub/issue-100771.rs
@@ -0,0 +1,20 @@
+// check-pass
+// compile-flags: -Zextra-const-ub-checks
+
+#[derive(PartialEq, Eq, Copy, Clone)]
+#[repr(packed)]
+struct Foo {
+ field: (i64, u32, u32, u32),
+}
+
+const FOO: Foo = Foo {
+ field: (5, 6, 7, 8),
+};
+
+fn main() {
+ match FOO {
+ Foo { field: (5, 6, 7, 8) } => {},
+ FOO => unreachable!(),
+ _ => unreachable!(),
+ }
+}
diff --git a/src/test/ui/consts/extra-const-ub/issue-101034.rs b/src/test/ui/consts/extra-const-ub/issue-101034.rs
new file mode 100644
index 000000000..e0de705c4
--- /dev/null
+++ b/src/test/ui/consts/extra-const-ub/issue-101034.rs
@@ -0,0 +1,17 @@
+// check-pass
+// compile-flags: -Zextra-const-ub-checks
+
+#[repr(packed)]
+pub struct Foo {
+ bar: u8,
+ baa: [u32; 1],
+}
+
+const FOOMP: Foo = Foo {
+ bar: 0,
+ baa: [69; 1],
+};
+
+fn main() {
+ let _val = FOOMP;
+}
diff --git a/src/test/ui/consts/issue-32829-2.stderr b/src/test/ui/consts/issue-32829-2.stderr
index b94bdc0e3..0fec35818 100644
--- a/src/test/ui/consts/issue-32829-2.stderr
+++ b/src/test/ui/consts/issue-32829-2.stderr
@@ -13,6 +13,7 @@ LL | invalid();
| ^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error[E0015]: cannot call non-const fn `invalid` in statics
--> $DIR/issue-32829-2.rs:54:9
@@ -21,6 +22,7 @@ LL | invalid();
| ^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/issue-36163.stderr b/src/test/ui/consts/issue-36163.stderr
index 4797d10b7..9ac6c984c 100644
--- a/src/test/ui/consts/issue-36163.stderr
+++ b/src/test/ui/consts/issue-36163.stderr
@@ -8,7 +8,7 @@ note: ...which requires const-evaluating + checking `A`...
--> $DIR/issue-36163.rs:1:1
|
LL | const A: isize = Foo::B as isize;
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating + checking `Foo::B::{constant#0}`, completing the cycle
note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}`
--> $DIR/issue-36163.rs:4:9
diff --git a/src/test/ui/consts/issue-miri-1910.rs b/src/test/ui/consts/issue-miri-1910.rs
index 2b23626e3..29e0ea950 100644
--- a/src/test/ui/consts/issue-miri-1910.rs
+++ b/src/test/ui/consts/issue-miri-1910.rs
@@ -1,4 +1,5 @@
// error-pattern unable to turn pointer into raw bytes
+// normalize-stderr-test: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC"
#![feature(const_ptr_read)]
const C: () = unsafe {
diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr
index d953c7819..0f0539e09 100644
--- a/src/test/ui/consts/issue-miri-1910.stderr
+++ b/src/test/ui/consts/issue-miri-1910.stderr
@@ -4,12 +4,12 @@ error: any use of this value will cause an error
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
- | unable to turn pointer into raw bytes
+ | unable to copy parts of a pointer from memory at ALLOC
| inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
| inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
- | inside `C` at $DIR/issue-miri-1910.rs:7:5
+ | inside `C` at $DIR/issue-miri-1910.rs:8:5
|
- ::: $DIR/issue-miri-1910.rs:4:1
+ ::: $DIR/issue-miri-1910.rs:5:1
|
LL | const C: () = unsafe {
| -----------
@@ -29,12 +29,12 @@ error: any use of this value will cause an error
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
- | unable to turn pointer into raw bytes
+ | unable to copy parts of a pointer from memory at ALLOC
| inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
| inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
- | inside `C` at $DIR/issue-miri-1910.rs:7:5
+ | inside `C` at $DIR/issue-miri-1910.rs:8:5
|
- ::: $DIR/issue-miri-1910.rs:4:1
+ ::: $DIR/issue-miri-1910.rs:5:1
|
LL | const C: () = unsafe {
| -----------
diff --git a/src/test/ui/consts/mir_check_nonconst.stderr b/src/test/ui/consts/mir_check_nonconst.stderr
index 2bac995ee..1e0652722 100644
--- a/src/test/ui/consts/mir_check_nonconst.stderr
+++ b/src/test/ui/consts/mir_check_nonconst.stderr
@@ -5,6 +5,7 @@ LL | static foo: Foo = bar();
| ^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error: aborting due to previous error
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr
index b3ad81e49..14173ac9f 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:11:1
|
LL | const REF_INTERIOR_MUT: &usize = {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:18:1
|
LL | const READ_IMMUT: &usize = {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr
index 24bd07092..e7e51a418 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:11:1
|
LL | const REF_INTERIOR_MUT: &usize = {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
@@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:18:1
|
LL | const READ_IMMUT: &usize = {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
index 20a96b57f..3a22b0689 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:12:1
|
LL | const SLICE_MUT: &[u8; 1] = {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:17:1
|
LL | const U8_MUT: &u8 = {
- | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
index dfa0f76ba..39c874d64 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:12:1
|
LL | const SLICE_MUT: &[u8; 1] = {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
@@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:17:1
|
LL | const U8_MUT: &u8 = {
- | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable
+ | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
diff --git a/src/test/ui/consts/miri_unleashed/ptr_arith.rs b/src/test/ui/consts/miri_unleashed/ptr_arith.rs
index 13e6af36e..6a19b2945 100644
--- a/src/test/ui/consts/miri_unleashed/ptr_arith.rs
+++ b/src/test/ui/consts/miri_unleashed/ptr_arith.rs
@@ -8,7 +8,7 @@
static PTR_INT_CAST: () = {
let x = &0 as *const _ as usize;
//~^ ERROR could not evaluate static initializer
- //~| "exposing pointers" needs an rfc before being allowed inside constants
+ //~| exposing pointers
let _v = x == x;
};
@@ -19,4 +19,7 @@ static PTR_INT_TRANSMUTE: () = unsafe {
//~| unable to turn pointer into raw bytes
};
+// I'd love to test pointer comparison, but that is not possible since
+// their `PartialEq` impl is non-`const`.
+
fn main() {}
diff --git a/src/test/ui/consts/miri_unleashed/ptr_arith.stderr b/src/test/ui/consts/miri_unleashed/ptr_arith.stderr
index f67ac4802..e0c4fa175 100644
--- a/src/test/ui/consts/miri_unleashed/ptr_arith.stderr
+++ b/src/test/ui/consts/miri_unleashed/ptr_arith.stderr
@@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer
--> $DIR/ptr_arith.rs:9:13
|
LL | let x = &0 as *const _ as usize;
- | ^^^^^^^^^^^^^^^^^^^^^^^ "exposing pointers" needs an rfc before being allowed inside constants
+ | ^^^^^^^^^^^^^^^^^^^^^^^ exposing pointers is not possible at compile-time
error[E0080]: could not evaluate static initializer
--> $DIR/ptr_arith.rs:17:14
diff --git a/src/test/ui/consts/miri_unleashed/slice_eq.rs b/src/test/ui/consts/miri_unleashed/slice_eq.rs
index fd843105d..83e10bf12 100644
--- a/src/test/ui/consts/miri_unleashed/slice_eq.rs
+++ b/src/test/ui/consts/miri_unleashed/slice_eq.rs
@@ -4,14 +4,10 @@
#![feature(const_raw_ptr_comparison)]
const EMPTY_SLICE: &[i32] = &[];
-const EMPTY_EQ: bool = EMPTY_SLICE.as_ptr().guaranteed_eq(&[] as *const _);
-const EMPTY_EQ2: bool = EMPTY_SLICE.as_ptr().guaranteed_ne(&[] as *const _);
-const EMPTY_NE: bool = EMPTY_SLICE.as_ptr().guaranteed_ne(&[1] as *const _);
-const EMPTY_NE2: bool = EMPTY_SLICE.as_ptr().guaranteed_eq(&[1] as *const _);
+const EMPTY_EQ: Option<bool> = EMPTY_SLICE.as_ptr().guaranteed_eq(&[] as *const _);
+const EMPTY_EQ2: Option<bool> = EMPTY_SLICE.as_ptr().guaranteed_eq(&[1] as *const _);
fn main() {
- assert!(!EMPTY_EQ);
- assert!(!EMPTY_EQ2);
- assert!(!EMPTY_NE);
- assert!(!EMPTY_NE2);
+ assert!(EMPTY_EQ.is_none());
+ assert!(EMPTY_EQ2.is_none());
}
diff --git a/src/test/ui/consts/offset.rs b/src/test/ui/consts/offset.rs
index f9ddda554..b2c663fe6 100644
--- a/src/test/ui/consts/offset.rs
+++ b/src/test/ui/consts/offset.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(const_ptr_offset_from)]
use std::ptr;
#[repr(C)]
diff --git a/src/test/ui/consts/offset_from.rs b/src/test/ui/consts/offset_from.rs
index b53718316..465147041 100644
--- a/src/test/ui/consts/offset_from.rs
+++ b/src/test/ui/consts/offset_from.rs
@@ -1,6 +1,5 @@
// run-pass
-#![feature(const_ptr_offset_from)]
#![feature(const_ptr_sub_ptr)]
#![feature(ptr_sub_ptr)]
diff --git a/src/test/ui/consts/offset_from_ub.rs b/src/test/ui/consts/offset_from_ub.rs
index 1f29a6905..51163e650 100644
--- a/src/test/ui/consts/offset_from_ub.rs
+++ b/src/test/ui/consts/offset_from_ub.rs
@@ -1,4 +1,4 @@
-#![feature(const_ptr_offset_from)]
+#![feature(const_ptr_sub_ptr)]
#![feature(core_intrinsics)]
use std::intrinsics::{ptr_offset_from, ptr_offset_from_unsigned};
diff --git a/src/test/ui/consts/ptr_comparisons.rs b/src/test/ui/consts/ptr_comparisons.rs
index 20233db09..0a3c2d4be 100644
--- a/src/test/ui/consts/ptr_comparisons.rs
+++ b/src/test/ui/consts/ptr_comparisons.rs
@@ -14,38 +14,30 @@ const FOO: &usize = &42;
macro_rules! check {
(eq, $a:expr, $b:expr) => {
pub const _: () =
- assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));
+ assert!(std::intrinsics::ptr_guaranteed_cmp($a as *const u8, $b as *const u8) == 1);
};
(ne, $a:expr, $b:expr) => {
pub const _: () =
- assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));
+ assert!(std::intrinsics::ptr_guaranteed_cmp($a as *const u8, $b as *const u8) == 0);
};
- (!eq, $a:expr, $b:expr) => {
+ (!, $a:expr, $b:expr) => {
pub const _: () =
- assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));
- };
- (!ne, $a:expr, $b:expr) => {
- pub const _: () =
- assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));
+ assert!(std::intrinsics::ptr_guaranteed_cmp($a as *const u8, $b as *const u8) == 2);
};
}
check!(eq, 0, 0);
check!(ne, 0, 1);
-check!(!eq, 0, 1);
-check!(!ne, 0, 0);
check!(ne, FOO as *const _, 0);
-check!(!eq, FOO as *const _, 0);
+check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0);
+check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
+
// We want pointers to be equal to themselves, but aren't checking this yet because
// there are some open questions (e.g. whether function pointers to the same function
// compare equal, they don't necessarily at runtime).
// The case tested here should work eventually, but does not work yet.
-check!(!eq, FOO as *const _, FOO as *const _);
-check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0);
-check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0);
+check!(!, FOO as *const _, FOO as *const _);
-check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
-check!(!eq, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
///////////////////////////////////////////////////////////////////////////////
// If any of the below start compiling, make sure to add a `check` test for it.
diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr
index 1d47f243f..3de2aba5b 100644
--- a/src/test/ui/consts/ptr_comparisons.stderr
+++ b/src/test/ui/consts/ptr_comparisons.stderr
@@ -7,19 +7,19 @@ LL | unsafe { intrinsics::offset(self, count) }
| out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds
| inside `ptr::const_ptr::<impl *const usize>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/ptr_comparisons.rs:58:34
+ ::: $DIR/ptr_comparisons.rs:50:34
|
LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
- | ------------------------------- inside `_` at $DIR/ptr_comparisons.rs:58:34
+ | ------------------------------- inside `_` at $DIR/ptr_comparisons.rs:50:34
error[E0080]: evaluation of constant value failed
- --> $DIR/ptr_comparisons.rs:61:33
+ --> $DIR/ptr_comparisons.rs:53:33
|
LL | unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: alloc3 has size $WORD, so pointer to 1000 bytes starting at offset 0 is out-of-bounds
error: any use of this value will cause an error
- --> $DIR/ptr_comparisons.rs:65:27
+ --> $DIR/ptr_comparisons.rs:57:27
|
LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -31,7 +31,7 @@ LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) +
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error
- --> $DIR/ptr_comparisons.rs:70:27
+ --> $DIR/ptr_comparisons.rs:62:27
|
LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -46,7 +46,7 @@ error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0080`.
Future incompatibility report: Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ptr_comparisons.rs:65:27
+ --> $DIR/ptr_comparisons.rs:57:27
|
LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -59,7 +59,7 @@ LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) +
Future breakage diagnostic:
error: any use of this value will cause an error
- --> $DIR/ptr_comparisons.rs:70:27
+ --> $DIR/ptr_comparisons.rs:62:27
|
LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
diff --git a/src/test/ui/consts/unnormalized-param-env.rs b/src/test/ui/consts/unnormalized-param-env.rs
new file mode 100644
index 000000000..a7bbe4db9
--- /dev/null
+++ b/src/test/ui/consts/unnormalized-param-env.rs
@@ -0,0 +1,31 @@
+// check-pass
+
+pub trait CSpace<const N: usize> {
+ type Traj;
+}
+
+pub struct Const<const R: usize>;
+
+pub trait Obstacle<CS, const N: usize> {
+ fn trajectory_free<FT, S1>(&self, t: &FT)
+ where
+ CS::Traj: Sized,
+ CS: CSpace<N>;
+}
+
+// -----
+
+const N: usize = 4;
+
+struct ObstacleSpace2df32;
+
+impl<CS> Obstacle<CS, N> for ObstacleSpace2df32 {
+ fn trajectory_free<TF, S1>(&self, t: &TF)
+ where
+ CS::Traj: Sized,
+ CS: CSpace<N>,
+ {
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs
index b2edc1a1f..6175b7df1 100644
--- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs
+++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs
@@ -3,7 +3,6 @@
trait Foo<X = Box<dyn Foo>> {
//~^ ERROR cycle detected
- //~| ERROR cycle detected
}
fn main() { }
diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
index d4976a0f9..9d715f494 100644
--- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
+++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
@@ -10,30 +10,11 @@ note: cycle used when collecting item types in top-level module
|
LL | / trait Foo<X = Box<dyn Foo>> {
LL | |
-LL | |
-LL | | }
-LL | |
-LL | | fn main() { }
- | |_____________^
-
-error[E0391]: cycle detected when computing type of `Foo::X`
- --> $DIR/cycle-trait-default-type-trait.rs:4:23
- |
-LL | trait Foo<X = Box<dyn Foo>> {
- | ^^^
- |
- = note: ...which immediately requires computing type of `Foo::X` again
-note: cycle used when collecting item types in top-level module
- --> $DIR/cycle-trait-default-type-trait.rs:4:1
- |
-LL | / trait Foo<X = Box<dyn Foo>> {
-LL | |
-LL | |
LL | | }
LL | |
LL | | fn main() { }
| |_____________^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs b/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
index 043011b33..ff764015d 100644
--- a/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
+++ b/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
@@ -1,6 +1,7 @@
// build-pass
+// only-linux
//
-// compile-flags: -g --emit=llvm-ir -Zunstable-options -Csplit-debuginfo=unpacked
+// compile-flags: -g --emit=llvm-ir -Csplit-debuginfo=unpacked
//
// Make sure that we don't explode with an error if we don't actually end up emitting any `dwo`s,
// as would be the case if we don't actually codegen anything.
diff --git a/src/test/ui/deprecation/deprecation-sanity.stderr b/src/test/ui/deprecation/deprecation-sanity.stderr
index 973c672df..8b2b480d1 100644
--- a/src/test/ui/deprecation/deprecation-sanity.stderr
+++ b/src/test/ui/deprecation/deprecation-sanity.stderr
@@ -44,7 +44,9 @@ error[E0565]: literal in `deprecated` value must be a string
--> $DIR/deprecation-sanity.rs:19:25
|
LL | #[deprecated(note = b"test")]
- | ^^^^^^^ help: consider removing the prefix: `"test"`
+ | -^^^^^^
+ | |
+ | help: consider removing the prefix
error[E0565]: item in `deprecated` must be a key/value pair
--> $DIR/deprecation-sanity.rs:22:18
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
index d66faa086..67a27729d 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
@@ -7,7 +7,6 @@ struct Error;
enum Enum {
A {
x: Error //~ ERROR
-//~^ ERROR
}
}
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
index f655600b7..9953154fd 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
LL | #[derive(PartialEq)]
|
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
- --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
- |
-LL | #[derive(PartialEq)]
- | --------- in this derive macro expansion
-...
-LL | x: Error
- | ^^^^^^^^
- |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
- --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:4:1
- |
-LL | struct Error;
- | ^^^^^^^^^^^^ must implement `PartialEq<_>`
- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
- |
-LL | #[derive(PartialEq)]
- |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.rs b/src/test/ui/derives/derives-span-PartialEq-enum.rs
index 66edf460b..0becc7e0d 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.rs
@@ -7,8 +7,7 @@ struct Error;
enum Enum {
A(
Error //~ ERROR
-//~^ ERROR
- )
+ )
}
fn main() {}
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
index ce4b00bfb..7c1304523 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
LL | #[derive(PartialEq)]
|
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
- --> $DIR/derives-span-PartialEq-enum.rs:9:6
- |
-LL | #[derive(PartialEq)]
- | --------- in this derive macro expansion
-...
-LL | Error
- | ^^^^^
- |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
- --> $DIR/derives-span-PartialEq-enum.rs:4:1
- |
-LL | struct Error;
- | ^^^^^^^^^^^^ must implement `PartialEq<_>`
- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
- |
-LL | #[derive(PartialEq)]
- |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.rs b/src/test/ui/derives/derives-span-PartialEq-struct.rs
index ce5c67af7..c92ef5fad 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.rs
@@ -6,7 +6,6 @@ struct Error;
#[derive(PartialEq)]
struct Struct {
x: Error //~ ERROR
-//~^ ERROR
}
fn main() {}
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
index c5c8f255f..ba3d6ced3 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
LL | #[derive(PartialEq)]
|
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
- --> $DIR/derives-span-PartialEq-struct.rs:8:5
- |
-LL | #[derive(PartialEq)]
- | --------- in this derive macro expansion
-LL | struct Struct {
-LL | x: Error
- | ^^^^^^^^
- |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
- --> $DIR/derives-span-PartialEq-struct.rs:4:1
- |
-LL | struct Error;
- | ^^^^^^^^^^^^ must implement `PartialEq<_>`
- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
- |
-LL | #[derive(PartialEq)]
- |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
index eaa628311..10ac347aa 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
@@ -6,7 +6,6 @@ struct Error;
#[derive(PartialEq)]
struct Struct(
Error //~ ERROR
-//~^ ERROR
);
fn main() {}
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
index f5d609cb3..ab0b56a9e 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
LL | #[derive(PartialEq)]
|
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
- --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
- |
-LL | #[derive(PartialEq)]
- | --------- in this derive macro expansion
-LL | struct Struct(
-LL | Error
- | ^^^^^
- |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
- --> $DIR/derives-span-PartialEq-tuple-struct.rs:4:1
- |
-LL | struct Error;
- | ^^^^^^^^^^^^ must implement `PartialEq<_>`
- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
- |
-LL | #[derive(PartialEq)]
- |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr
index 13097edf0..80e2dd7fe 100644
--- a/src/test/ui/derives/deriving-copyclone.stderr
+++ b/src/test/ui/derives/deriving-copyclone.stderr
@@ -2,11 +2,11 @@ error[E0277]: the trait bound `B<C>: Copy` is not satisfied
--> $DIR/deriving-copyclone.rs:31:13
|
LL | is_copy(B { a: 1, b: C });
- | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy`
+ | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B<C>`
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Copy` for `B<C>`
+note: required for `B<C>` to implement `Copy`
--> $DIR/deriving-copyclone.rs:9:10
|
LL | #[derive(Copy, Clone)]
@@ -26,11 +26,11 @@ error[E0277]: the trait bound `B<C>: Clone` is not satisfied
--> $DIR/deriving-copyclone.rs:32:14
|
LL | is_clone(B { a: 1, b: C });
- | -------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
+ | -------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `B<C>`
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Clone` for `B<C>`
+note: required for `B<C>` to implement `Clone`
--> $DIR/deriving-copyclone.rs:9:16
|
LL | #[derive(Copy, Clone)]
@@ -50,11 +50,11 @@ error[E0277]: the trait bound `B<D>: Copy` is not satisfied
--> $DIR/deriving-copyclone.rs:35:13
|
LL | is_copy(B { a: 1, b: D });
- | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy`
+ | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B<D>`
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Copy` for `B<D>`
+note: required for `B<D>` to implement `Copy`
--> $DIR/deriving-copyclone.rs:9:10
|
LL | #[derive(Copy, Clone)]
diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.rs b/src/test/ui/derives/deriving-no-inner-impl-error-message.rs
index 39e41a59e..b3ce31bf0 100644
--- a/src/test/ui/derives/deriving-no-inner-impl-error-message.rs
+++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.rs
@@ -3,7 +3,6 @@ struct NoCloneOrEq;
#[derive(PartialEq)]
struct E {
x: NoCloneOrEq //~ ERROR binary operation `==` cannot be applied to type `NoCloneOrEq`
- //~^ ERROR binary operation `!=` cannot be applied to type `NoCloneOrEq`
}
#[derive(Clone)]
struct C {
diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
index 7875f0723..ef8c44caa 100644
--- a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
+++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
@@ -18,28 +18,8 @@ help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]`
LL | #[derive(PartialEq)]
|
-error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq`
- --> $DIR/deriving-no-inner-impl-error-message.rs:5:5
- |
-LL | #[derive(PartialEq)]
- | --------- in this derive macro expansion
-LL | struct E {
-LL | x: NoCloneOrEq
- | ^^^^^^^^^^^^^^
- |
-note: an implementation of `PartialEq<_>` might be missing for `NoCloneOrEq`
- --> $DIR/deriving-no-inner-impl-error-message.rs:1:1
- |
-LL | struct NoCloneOrEq;
- | ^^^^^^^^^^^^^^^^^^ must implement `PartialEq<_>`
- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]`
- |
-LL | #[derive(PartialEq)]
- |
-
error[E0277]: the trait bound `NoCloneOrEq: Clone` is not satisfied
- --> $DIR/deriving-no-inner-impl-error-message.rs:10:5
+ --> $DIR/deriving-no-inner-impl-error-message.rs:9:5
|
LL | #[derive(Clone)]
| ----- in this derive macro expansion
@@ -53,7 +33,7 @@ help: consider annotating `NoCloneOrEq` with `#[derive(Clone)]`
LL | #[derive(Clone)]
|
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0369.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/deriving/deriving-all-codegen.rs b/src/test/ui/deriving/deriving-all-codegen.rs
index aef79ae8a..ba7809413 100644
--- a/src/test/ui/deriving/deriving-all-codegen.rs
+++ b/src/test/ui/deriving/deriving-all-codegen.rs
@@ -85,7 +85,7 @@ enum Mixed {
P,
Q,
R(u32),
- S { d1: u32, d2: u32 },
+ S { d1: Option<u32>, d2: Option<i32> },
}
// An enum with no fieldless variants. Note that `Default` cannot be derived
diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout
index 21fe663f0..56efc2a59 100644
--- a/src/test/ui/deriving/deriving-all-codegen.stdout
+++ b/src/test/ui/deriving/deriving-all-codegen.stdout
@@ -122,10 +122,6 @@ impl ::core::cmp::PartialEq for Point {
fn eq(&self, other: &Point) -> bool {
self.x == other.x && self.y == other.y
}
- #[inline]
- fn ne(&self, other: &Point) -> bool {
- self.x != other.x || self.y != other.y
- }
}
impl ::core::marker::StructuralEq for Point {}
#[automatically_derived]
@@ -239,13 +235,6 @@ impl ::core::cmp::PartialEq for Big {
self.b6 == other.b6 && self.b7 == other.b7 &&
self.b8 == other.b8
}
- #[inline]
- fn ne(&self, other: &Big) -> bool {
- self.b1 != other.b1 || self.b2 != other.b2 || self.b3 != other.b3 ||
- self.b4 != other.b4 || self.b5 != other.b5 ||
- self.b6 != other.b6 || self.b7 != other.b7 ||
- self.b8 != other.b8
- }
}
impl ::core::marker::StructuralEq for Big {}
#[automatically_derived]
@@ -361,8 +350,6 @@ impl ::core::marker::StructuralPartialEq for Unsized {}
impl ::core::cmp::PartialEq for Unsized {
#[inline]
fn eq(&self, other: &Unsized) -> bool { self.0 == other.0 }
- #[inline]
- fn ne(&self, other: &Unsized) -> bool { self.0 != other.0 }
}
impl ::core::marker::StructuralEq for Unsized {}
#[automatically_derived]
@@ -428,8 +415,6 @@ impl ::core::marker::StructuralPartialEq for PackedCopy {}
impl ::core::cmp::PartialEq for PackedCopy {
#[inline]
fn eq(&self, other: &PackedCopy) -> bool { { self.0 } == { other.0 } }
- #[inline]
- fn ne(&self, other: &PackedCopy) -> bool { { self.0 } != { other.0 } }
}
impl ::core::marker::StructuralEq for PackedCopy {}
#[automatically_derived]
@@ -503,12 +488,6 @@ impl ::core::cmp::PartialEq for PackedNonCopy {
let Self(ref __self_1_0) = *other;
*__self_0_0 == *__self_1_0
}
- #[inline]
- fn ne(&self, other: &PackedNonCopy) -> bool {
- let Self(ref __self_0_0) = *self;
- let Self(ref __self_1_0) = *other;
- *__self_0_0 != *__self_1_0
- }
}
impl ::core::marker::StructuralEq for PackedNonCopy {}
#[automatically_derived]
@@ -638,13 +617,6 @@ impl ::core::cmp::PartialEq for Enum1 {
*__self_0 == *__arg1_0,
}
}
- #[inline]
- fn ne(&self, other: &Enum1) -> bool {
- match (self, other) {
- (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
- *__self_0 != *__arg1_0,
- }
- }
}
impl ::core::marker::StructuralEq for Enum1 {}
#[automatically_derived]
@@ -817,8 +789,8 @@ enum Mixed {
Q,
R(u32),
S {
- d1: u32,
- d2: u32,
+ d1: Option<u32>,
+ d2: Option<i32>,
},
}
#[automatically_derived]
@@ -826,6 +798,8 @@ impl ::core::clone::Clone for Mixed {
#[inline]
fn clone(&self) -> Mixed {
let _: ::core::clone::AssertParamIsClone<u32>;
+ let _: ::core::clone::AssertParamIsClone<Option<u32>>;
+ let _: ::core::clone::AssertParamIsClone<Option<i32>>;
*self
}
}
@@ -883,20 +857,6 @@ impl ::core::cmp::PartialEq for Mixed {
_ => true,
}
}
- #[inline]
- fn ne(&self, other: &Mixed) -> bool {
- let __self_tag = ::core::intrinsics::discriminant_value(self);
- let __arg1_tag = ::core::intrinsics::discriminant_value(other);
- __self_tag != __arg1_tag ||
- match (self, other) {
- (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
- *__self_0 != *__arg1_0,
- (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
- d1: __arg1_0, d2: __arg1_1 }) =>
- *__self_0 != *__arg1_0 || *__self_1 != *__arg1_1,
- _ => false,
- }
- }
}
impl ::core::marker::StructuralEq for Mixed {}
#[automatically_derived]
@@ -906,6 +866,8 @@ impl ::core::cmp::Eq for Mixed {
#[no_coverage]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<u32>;
+ let _: ::core::cmp::AssertParamIsEq<Option<u32>>;
+ let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
}
}
#[automatically_derived]
@@ -1023,21 +985,6 @@ impl ::core::cmp::PartialEq for Fielded {
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
- #[inline]
- fn ne(&self, other: &Fielded) -> bool {
- let __self_tag = ::core::intrinsics::discriminant_value(self);
- let __arg1_tag = ::core::intrinsics::discriminant_value(other);
- __self_tag != __arg1_tag ||
- match (self, other) {
- (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
- *__self_0 != *__arg1_0,
- (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
- *__self_0 != *__arg1_0,
- (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
- *__self_0 != *__arg1_0,
- _ => unsafe { ::core::intrinsics::unreachable() }
- }
- }
}
impl ::core::marker::StructuralEq for Fielded {}
#[automatically_derived]
diff --git a/src/test/ui/deriving/issue-103157.rs b/src/test/ui/deriving/issue-103157.rs
new file mode 100644
index 000000000..52b4c7898
--- /dev/null
+++ b/src/test/ui/deriving/issue-103157.rs
@@ -0,0 +1,12 @@
+// check-fail
+
+#[derive(PartialEq, Eq)]
+pub enum Value {
+ Boolean(Option<bool>),
+ Float(Option<f64>), //~ ERROR the trait bound `f64: Eq` is not satisfied
+}
+
+fn main() {
+ let a = Value::Float(Some(f64::NAN));
+ assert!(a == a);
+}
diff --git a/src/test/ui/deriving/issue-103157.stderr b/src/test/ui/deriving/issue-103157.stderr
new file mode 100644
index 000000000..ee3528fe1
--- /dev/null
+++ b/src/test/ui/deriving/issue-103157.stderr
@@ -0,0 +1,30 @@
+error[E0277]: the trait bound `f64: Eq` is not satisfied
+ --> $DIR/issue-103157.rs:6:11
+ |
+LL | #[derive(PartialEq, Eq)]
+ | -- in this derive macro expansion
+...
+LL | Float(Option<f64>),
+ | ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64`
+ |
+ = help: the following other types implement trait `Eq`:
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ u128
+ u16
+ and 4 others
+ = note: required for `Option<f64>` to implement `Eq`
+note: required by a bound in `AssertParamIsEq`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub struct AssertParamIsEq<T: Eq + ?Sized> {
+ | ^^ required by this bound in `AssertParamIsEq`
+ = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/deriving/issue-89188-gat-hrtb.rs b/src/test/ui/deriving/issue-89188-gat-hrtb.rs
index abd85a616..e8118f0c6 100644
--- a/src/test/ui/deriving/issue-89188-gat-hrtb.rs
+++ b/src/test/ui/deriving/issue-89188-gat-hrtb.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait CallWithShim: Sized {
type Shim<'s>
where
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
index 26764bc0e..b69fcd5d3 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
- --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:8
+ --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:12
|
LL | f1.foo(1usize);
- | ^^^ the trait `Foo<usize>` is not implemented for `Bar`
+ | --- ^^^^^^ the trait `Foo<usize>` is not implemented for `Bar`
+ | |
+ | required by a bound introduced by this call
|
= help: the following other types implement trait `Foo<A>`:
<Bar as Foo<i32>>
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
index bb175367e..5e0e4a011 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
- --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:8
+ --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:12
|
LL | f1.foo(1usize);
- | ^^^ the trait `Foo<usize>` is not implemented for `Bar`
+ | --- ^^^^^^ the trait `Foo<usize>` is not implemented for `Bar`
+ | |
+ | required by a bound introduced by this call
|
= help: the following other types implement trait `Foo<A>`:
<Bar as Foo<i16>>
diff --git a/src/test/ui/did_you_mean/use_instead_of_import.fixed b/src/test/ui/did_you_mean/use_instead_of_import.fixed
index 87d453e15..a8aae76f4 100644
--- a/src/test/ui/did_you_mean/use_instead_of_import.fixed
+++ b/src/test/ui/did_you_mean/use_instead_of_import.fixed
@@ -6,10 +6,18 @@ use std::{
rc::Rc,
};
+use std::time::Duration;
+//~^ ERROR expected item, found `require`
+
+use std::time::Instant;
+//~^ ERROR expected item, found `include`
+
pub use std::io;
//~^ ERROR expected item, found `using`
fn main() {
let x = Rc::new(1);
let _ = write!(io::stdout(), "{:?}", x);
+ let _ = Duration::new(5, 0);
+ let _ = Instant::now();
}
diff --git a/src/test/ui/did_you_mean/use_instead_of_import.rs b/src/test/ui/did_you_mean/use_instead_of_import.rs
index 59e837323..2db7c2407 100644
--- a/src/test/ui/did_you_mean/use_instead_of_import.rs
+++ b/src/test/ui/did_you_mean/use_instead_of_import.rs
@@ -6,10 +6,18 @@ import std::{
rc::Rc,
};
+require std::time::Duration;
+//~^ ERROR expected item, found `require`
+
+include std::time::Instant;
+//~^ ERROR expected item, found `include`
+
pub using std::io;
//~^ ERROR expected item, found `using`
fn main() {
let x = Rc::new(1);
let _ = write!(io::stdout(), "{:?}", x);
+ let _ = Duration::new(5, 0);
+ let _ = Instant::now();
}
diff --git a/src/test/ui/did_you_mean/use_instead_of_import.stderr b/src/test/ui/did_you_mean/use_instead_of_import.stderr
index b22954af8..2aac8f68c 100644
--- a/src/test/ui/did_you_mean/use_instead_of_import.stderr
+++ b/src/test/ui/did_you_mean/use_instead_of_import.stderr
@@ -4,11 +4,23 @@ error: expected item, found `import`
LL | import std::{
| ^^^^^^ help: items are imported using the `use` keyword
+error: expected item, found `require`
+ --> $DIR/use_instead_of_import.rs:9:1
+ |
+LL | require std::time::Duration;
+ | ^^^^^^^ help: items are imported using the `use` keyword
+
+error: expected item, found `include`
+ --> $DIR/use_instead_of_import.rs:12:1
+ |
+LL | include std::time::Instant;
+ | ^^^^^^^ help: items are imported using the `use` keyword
+
error: expected item, found `using`
- --> $DIR/use_instead_of_import.rs:9:5
+ --> $DIR/use_instead_of_import.rs:15:5
|
LL | pub using std::io;
| ^^^^^ help: items are imported using the `use` keyword
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
diff --git a/src/test/ui/drop/drop-foreign-fundamental.rs b/src/test/ui/drop/drop-foreign-fundamental.rs
new file mode 100644
index 000000000..c43df40d6
--- /dev/null
+++ b/src/test/ui/drop/drop-foreign-fundamental.rs
@@ -0,0 +1,23 @@
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Whatever<T>(T);
+
+impl<T> Deref for Whatever<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+struct A;
+
+impl Drop for Pin<Whatever<A>> {
+ //~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
+ fn drop(&mut self) {}
+}
+
+fn main() {
+ let x = Pin::new(Whatever(1.0f32));
+}
diff --git a/src/test/ui/drop/drop-foreign-fundamental.stderr b/src/test/ui/drop/drop-foreign-fundamental.stderr
new file mode 100644
index 000000000..fbd1ba085
--- /dev/null
+++ b/src/test/ui/drop/drop-foreign-fundamental.stderr
@@ -0,0 +1,9 @@
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
+ --> $DIR/drop-foreign-fundamental.rs:16:15
+ |
+LL | impl Drop for Pin<Whatever<A>> {
+ | ^^^^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0120`.
diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs
new file mode 100644
index 000000000..e42150dcc
--- /dev/null
+++ b/src/test/ui/drop/drop_order.rs
@@ -0,0 +1,145 @@
+// run-pass
+
+use std::cell::RefCell;
+use std::convert::TryInto;
+
+#[derive(Default)]
+struct DropOrderCollector(RefCell<Vec<u32>>);
+
+struct LoudDrop<'a>(&'a DropOrderCollector, u32);
+
+impl Drop for LoudDrop<'_> {
+ fn drop(&mut self) {
+ println!("{}", self.1);
+ self.0.0.borrow_mut().push(self.1);
+ }
+}
+
+impl DropOrderCollector {
+ fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
+ Some(LoudDrop(self, n))
+ }
+
+ fn loud_drop(&self, n: u32) -> LoudDrop {
+ LoudDrop(self, n)
+ }
+
+ fn print(&self, n: u32) {
+ println!("{}", n);
+ self.0.borrow_mut().push(n)
+ }
+
+ fn if_(&self) {
+ if self.option_loud_drop(1).is_some() {
+ self.print(2);
+ }
+
+ if self.option_loud_drop(3).is_none() {
+ unreachable!();
+ } else if self.option_loud_drop(4).is_some() {
+ self.print(5);
+ }
+
+ if {
+ if self.option_loud_drop(7).is_some() && self.option_loud_drop(6).is_some() {
+ self.loud_drop(8);
+ true
+ } else {
+ false
+ }
+ } {
+ self.print(9);
+ }
+ }
+
+ fn if_let(&self) {
+ if let None = self.option_loud_drop(2) {
+ unreachable!();
+ } else {
+ self.print(1);
+ }
+
+ if let Some(_) = self.option_loud_drop(4) {
+ self.print(3);
+ }
+
+ if let Some(_d) = self.option_loud_drop(6) {
+ self.print(5);
+ }
+ }
+
+ fn match_(&self) {
+ match self.option_loud_drop(2) {
+ _any => self.print(1),
+ }
+
+ match self.option_loud_drop(4) {
+ _ => self.print(3),
+ }
+
+ match self.option_loud_drop(6) {
+ Some(_) => self.print(5),
+ _ => unreachable!(),
+ }
+
+ match {
+ let _ = self.loud_drop(7);
+ let _d = self.loud_drop(9);
+ self.print(8);
+ ()
+ } {
+ () => self.print(10),
+ }
+
+ match {
+ match self.option_loud_drop(14) {
+ _ => {
+ self.print(11);
+ self.option_loud_drop(13)
+ }
+ }
+ } {
+ _ => self.print(12),
+ }
+
+ match {
+ loop {
+ break match self.option_loud_drop(16) {
+ _ => {
+ self.print(15);
+ self.option_loud_drop(18)
+ }
+ };
+ }
+ } {
+ _ => self.print(17),
+ }
+ }
+
+ fn assert_sorted(self) {
+ assert!(
+ self.0
+ .into_inner()
+ .into_iter()
+ .enumerate()
+ .all(|(idx, item)| idx + 1 == item.try_into().unwrap())
+ );
+ }
+}
+
+fn main() {
+ println!("-- if --");
+ let collector = DropOrderCollector::default();
+ collector.if_();
+ collector.assert_sorted();
+
+ println!("-- if let --");
+ let collector = DropOrderCollector::default();
+ collector.if_let();
+ collector.assert_sorted();
+
+ println!("-- match --");
+ let collector = DropOrderCollector::default();
+ collector.match_();
+ collector.assert_sorted();
+}
diff --git a/src/test/ui/dropck/drop-on-non-struct.rs b/src/test/ui/dropck/drop-on-non-struct.rs
index ef5e18126..145eab126 100644
--- a/src/test/ui/dropck/drop-on-non-struct.rs
+++ b/src/test/ui/dropck/drop-on-non-struct.rs
@@ -1,5 +1,5 @@
impl<'a> Drop for &'a mut isize {
- //~^ ERROR the `Drop` trait may only be implemented for structs, enums, and unions
+ //~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
//~^^ ERROR E0117
fn drop(&mut self) {
println!("kaboom");
@@ -8,8 +8,7 @@ impl<'a> Drop for &'a mut isize {
impl Drop for Nonexistent {
//~^ ERROR cannot find type `Nonexistent`
- fn drop(&mut self) { }
+ fn drop(&mut self) {}
}
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/dropck/drop-on-non-struct.stderr b/src/test/ui/dropck/drop-on-non-struct.stderr
index e52728f37..e8fbe5e97 100644
--- a/src/test/ui/dropck/drop-on-non-struct.stderr
+++ b/src/test/ui/dropck/drop-on-non-struct.stderr
@@ -15,11 +15,11 @@ LL | impl<'a> Drop for &'a mut isize {
|
= note: define and implement a trait or new type instead
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
--> $DIR/drop-on-non-struct.rs:1:19
|
LL | impl<'a> Drop for &'a mut isize {
- | ^^^^^^^^^^^^^ must be a struct, enum, or union
+ | ^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
error: aborting due to 3 previous errors
diff --git a/src/test/ui/dst/dst-bad-coercions.stderr b/src/test/ui/dst/dst-bad-coercions.stderr
index 01f862ed5..0d6f4d020 100644
--- a/src/test/ui/dst/dst-bad-coercions.stderr
+++ b/src/test/ui/dst/dst-bad-coercions.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/dst-bad-coercions.rs:14:17
|
LL | let y: &S = x;
- | -- ^ expected `&S`, found *-ptr
+ | -- ^ expected `&S`, found `*const S`
| |
| expected due to this
|
@@ -13,7 +13,7 @@ error[E0308]: mismatched types
--> $DIR/dst-bad-coercions.rs:15:21
|
LL | let y: &dyn T = x;
- | ------ ^ expected `&dyn T`, found *-ptr
+ | ------ ^ expected `&dyn T`, found `*const S`
| |
| expected due to this
|
@@ -24,7 +24,7 @@ error[E0308]: mismatched types
--> $DIR/dst-bad-coercions.rs:19:17
|
LL | let y: &S = x;
- | -- ^ expected `&S`, found *-ptr
+ | -- ^ expected `&S`, found `*mut S`
| |
| expected due to this
|
@@ -35,7 +35,7 @@ error[E0308]: mismatched types
--> $DIR/dst-bad-coercions.rs:20:21
|
LL | let y: &dyn T = x;
- | ------ ^ expected `&dyn T`, found *-ptr
+ | ------ ^ expected `&dyn T`, found `*mut S`
| |
| expected due to this
|
diff --git a/src/test/ui/dst/dst-rvalue.rs b/src/test/ui/dst/dst-rvalue.rs
index b52a95a70..fbb32cac1 100644
--- a/src/test/ui/dst/dst-rvalue.rs
+++ b/src/test/ui/dst/dst-rvalue.rs
@@ -1,12 +1,10 @@
// Check that dynamically sized rvalues are forbidden
-#![feature(box_syntax)]
-
pub fn main() {
- let _x: Box<str> = box *"hello world";
+ let _x: Box<str> = Box::new(*"hello world");
//~^ ERROR E0277
let array: &[isize] = &[1, 2, 3];
- let _x: Box<[isize]> = box *array;
+ let _x: Box<[isize]> = Box::new(*array);
//~^ ERROR E0277
}
diff --git a/src/test/ui/dst/dst-rvalue.stderr b/src/test/ui/dst/dst-rvalue.stderr
index 15830636b..727f4d843 100644
--- a/src/test/ui/dst/dst-rvalue.stderr
+++ b/src/test/ui/dst/dst-rvalue.stderr
@@ -1,20 +1,32 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
- --> $DIR/dst-rvalue.rs:6:28
+ --> $DIR/dst-rvalue.rs:4:33
|
-LL | let _x: Box<str> = box *"hello world";
- | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+LL | let _x: Box<str> = Box::new(*"hello world");
+ | -------- ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `str`
- = note: the type of a box expression must have a statically known size
+note: required by a bound in `Box::<T>::new`
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ |
+LL | impl<T> Box<T> {
+ | ^ required by this bound in `Box::<T>::new`
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
- --> $DIR/dst-rvalue.rs:10:32
+ --> $DIR/dst-rvalue.rs:8:37
|
-LL | let _x: Box<[isize]> = box *array;
- | ^^^^^^ doesn't have a size known at compile-time
+LL | let _x: Box<[isize]> = Box::new(*array);
+ | -------- ^^^^^^ doesn't have a size known at compile-time
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `[isize]`
- = note: the type of a box expression must have a statically known size
+note: required by a bound in `Box::<T>::new`
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ |
+LL | impl<T> Box<T> {
+ | ^ required by this bound in `Box::<T>::new`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
index 34699bb26..e7db68693 100644
--- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -13,9 +13,8 @@ LL | #[deny(bare_trait_objects)]
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
- |
+LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-2018-edition-lint.rs:4:35
@@ -27,9 +26,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
- |
+LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-2018-edition-lint.rs:17:14
@@ -41,9 +39,8 @@ LL | let _x: &SomeTrait = todo!();
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - let _x: &SomeTrait = todo!();
-LL + let _x: &dyn SomeTrait = todo!();
- |
+LL | let _x: &dyn SomeTrait = todo!();
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-2018-edition-lint.rs:4:17
@@ -55,9 +52,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
- |
+LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-2018-edition-lint.rs:4:17
@@ -69,9 +65,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
- |
+LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-2018-edition-lint.rs:4:35
@@ -83,9 +78,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
- |
+LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/dyn-2018-edition-lint.rs:4:35
@@ -97,9 +91,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
- |
+LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
+ | +++
error: aborting due to 7 previous errors
diff --git a/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr b/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr
index 9e212c77d..08ee77116 100644
--- a/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr
+++ b/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr
@@ -6,9 +6,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
|
help: add `dyn` keyword before this trait
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
- |
+LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
+ | +++
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/dyn-2021-edition-error.rs:3:35
@@ -18,9 +17,8 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
|
help: add `dyn` keyword before this trait
|
-LL - fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-LL + fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
- |
+LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
+ | +++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
index 9bc603fba..261c2d574 100644
--- a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
+++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
@@ -13,9 +13,8 @@ LL | #![deny(bare_trait_objects)]
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - <fmt::Debug>::fmt(self, f)
-LL + <dyn fmt::Debug>::fmt(self, f)
- |
+LL | <dyn fmt::Debug>::fmt(self, f)
+ | +++
error: aborting due to previous error
diff --git a/src/test/ui/dyn-star/const.rs b/src/test/ui/dyn-star/const.rs
new file mode 100644
index 000000000..e49caf649
--- /dev/null
+++ b/src/test/ui/dyn-star/const.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(dyn_star)]
+#![allow(unused, incomplete_features)]
+
+use std::fmt::Debug;
+
+fn make_dyn_star() {
+ let i = 42usize;
+ let dyn_i: dyn* Debug = i as dyn* Debug;
+}
+
+fn main() {
+ make_dyn_star();
+}
diff --git a/src/test/ui/dyn-star/drop.rs b/src/test/ui/dyn-star/drop.rs
new file mode 100644
index 000000000..46b232f3d
--- /dev/null
+++ b/src/test/ui/dyn-star/drop.rs
@@ -0,0 +1,23 @@
+// run-pass
+// check-run-results
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+#[derive(Debug)]
+struct Foo(usize);
+
+impl Drop for Foo {
+ fn drop(&mut self) {
+ println!("destructor called");
+ }
+}
+
+fn make_dyn_star(i: Foo) {
+ let _dyn_i: dyn* Debug = i as dyn* Debug;
+}
+
+fn main() {
+ make_dyn_star(Foo(42));
+}
diff --git a/src/test/ui/dyn-star/drop.run.stdout b/src/test/ui/dyn-star/drop.run.stdout
new file mode 100644
index 000000000..dadb33ccf
--- /dev/null
+++ b/src/test/ui/dyn-star/drop.run.stdout
@@ -0,0 +1 @@
+destructor called
diff --git a/src/test/ui/dyn-star/error.rs b/src/test/ui/dyn-star/error.rs
new file mode 100644
index 000000000..33eff80a5
--- /dev/null
+++ b/src/test/ui/dyn-star/error.rs
@@ -0,0 +1,13 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {}
+
+fn make_dyn_star() {
+ let i = 42;
+ let dyn_i: dyn* Foo = i as dyn* Foo; //~ ERROR trait bound `{integer}: Foo` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/error.stderr b/src/test/ui/dyn-star/error.stderr
new file mode 100644
index 000000000..d612ccc63
--- /dev/null
+++ b/src/test/ui/dyn-star/error.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `{integer}: Foo` is not satisfied
+ --> $DIR/error.rs:10:27
+ |
+LL | let dyn_i: dyn* Foo = i as dyn* Foo;
+ | ^ the trait `Foo` is not implemented for `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/feature-gate-dyn_star.rs b/src/test/ui/dyn-star/feature-gate-dyn_star.rs
new file mode 100644
index 000000000..4756661cf
--- /dev/null
+++ b/src/test/ui/dyn-star/feature-gate-dyn_star.rs
@@ -0,0 +1,9 @@
+// Feature gate test for dyn_star
+
+/// dyn* is not necessarily the final surface syntax (if we have one at all),
+/// but for now we will support it to aid in writing tests independently.
+pub fn dyn_star_parameter(_: &dyn* Send) {
+ //~^ dyn* trait objects are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/feature-gate-dyn_star.stderr b/src/test/ui/dyn-star/feature-gate-dyn_star.stderr
new file mode 100644
index 000000000..2767e9478
--- /dev/null
+++ b/src/test/ui/dyn-star/feature-gate-dyn_star.stderr
@@ -0,0 +1,12 @@
+error[E0658]: dyn* trait objects are unstable
+ --> $DIR/feature-gate-dyn_star.rs:5:31
+ |
+LL | pub fn dyn_star_parameter(_: &dyn* Send) {
+ | ^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(dyn_star)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/dyn-star/make-dyn-star.rs b/src/test/ui/dyn-star/make-dyn-star.rs
new file mode 100644
index 000000000..708ffa25d
--- /dev/null
+++ b/src/test/ui/dyn-star/make-dyn-star.rs
@@ -0,0 +1,13 @@
+// run-pass
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn make_dyn_star(i: usize) {
+ let _dyn_i: dyn* Debug = i as dyn* Debug;
+}
+
+fn main() {
+ make_dyn_star(42);
+}
diff --git a/src/test/ui/dyn-star/method.rs b/src/test/ui/dyn-star/method.rs
new file mode 100644
index 000000000..d04958ca2
--- /dev/null
+++ b/src/test/ui/dyn-star/method.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ fn get(&self) -> usize;
+}
+
+impl Foo for usize {
+ fn get(&self) -> usize {
+ *self
+ }
+}
+
+fn invoke_dyn_star(i: dyn* Foo) -> usize {
+ i.get()
+}
+
+fn make_and_invoke_dyn_star(i: usize) -> usize {
+ let dyn_i: dyn* Foo = i as dyn* Foo;
+ invoke_dyn_star(dyn_i)
+}
+
+fn main() {
+ println!("{}", make_and_invoke_dyn_star(42));
+}
diff --git a/src/test/ui/dyn-star/syntax.rs b/src/test/ui/dyn-star/syntax.rs
new file mode 100644
index 000000000..618c72562
--- /dev/null
+++ b/src/test/ui/dyn-star/syntax.rs
@@ -0,0 +1,11 @@
+// Make sure we can parse the `dyn* Trait` syntax
+//
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+pub fn dyn_star_parameter(_: dyn* Send) {
+}
+
+fn main() {}
diff --git a/src/test/ui/dynamically-sized-types/dst-struct.rs b/src/test/ui/dynamically-sized-types/dst-struct.rs
index 25ec07b88..5da9381f8 100644
--- a/src/test/ui/dynamically-sized-types/dst-struct.rs
+++ b/src/test/ui/dynamically-sized-types/dst-struct.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
struct Fat<T: ?Sized> {
f1: isize,
@@ -111,7 +110,7 @@ pub fn main() {
assert_eq!((*f2)[1], 2);
// Nested Box.
- let f1 : Box<Fat<[isize; 3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+ let f1 : Box<Fat<[isize; 3]>> = Box::new(Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] });
foo(&*f1);
let f2 : Box<Fat<[isize]>> = f1;
foo(&*f2);
diff --git a/src/test/ui/dynamically-sized-types/dst-trait.rs b/src/test/ui/dynamically-sized-types/dst-trait.rs
index ec6bc7219..7ac6f0392 100644
--- a/src/test/ui/dynamically-sized-types/dst-trait.rs
+++ b/src/test/ui/dynamically-sized-types/dst-trait.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
struct Fat<T: ?Sized> {
f1: isize,
diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs
index 01b99134a..3de2b1a78 100644
--- a/src/test/ui/empty/empty-never-array.rs
+++ b/src/test/ui/empty/empty-never-array.rs
@@ -8,7 +8,7 @@ enum Helper<T, U> {
fn transmute<T, U>(t: T) -> U {
let Helper::U(u) = Helper::T(t, []);
- //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered
+ //~^ ERROR refutable pattern in local binding: `Helper::T(_, _)` not covered
u
}
diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr
index 909aa73a7..adf782743 100644
--- a/src/test/ui/empty/empty-never-array.stderr
+++ b/src/test/ui/empty/empty-never-array.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
+error[E0005]: refutable pattern in local binding: `Helper::T(_, _)` not covered
--> $DIR/empty-never-array.rs:10:9
|
LL | let Helper::U(u) = Helper::T(t, []);
- | ^^^^^^^^^^^^ pattern `T(_, _)` not covered
+ | ^^^^^^^^^^^^ pattern `Helper::T(_, _)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -18,7 +18,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let u = if let Helper::U(u) = Helper::T(t, []) { u } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Helper::U(u) = Helper::T(t, []) else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/enum/enum-discrim-autosizing.rs b/src/test/ui/enum/enum-discrim-autosizing.rs
index 27fab1bb5..fc94d281c 100644
--- a/src/test/ui/enum/enum-discrim-autosizing.rs
+++ b/src/test/ui/enum/enum-discrim-autosizing.rs
@@ -6,9 +6,9 @@
enum Eu64 {
//~^ ERROR discriminant value `0` assigned more than once
Au64 = 0,
- //~^NOTE first assignment of `0`
+ //~^NOTE `0` assigned here
Bu64 = 0x8000_0000_0000_0000
- //~^NOTE second assignment of `0` (overflowed from `9223372036854775808`)
+ //~^NOTE `0` (overflowed from `9223372036854775808`) assigned here
}
fn main() {}
diff --git a/src/test/ui/enum/enum-discrim-autosizing.stderr b/src/test/ui/enum/enum-discrim-autosizing.stderr
index eacea86d6..be3d7c64e 100644
--- a/src/test/ui/enum/enum-discrim-autosizing.stderr
+++ b/src/test/ui/enum/enum-discrim-autosizing.stderr
@@ -5,10 +5,10 @@ LL | enum Eu64 {
| ^^^^^^^^^
LL |
LL | Au64 = 0,
- | - first assignment of `0`
+ | - `0` assigned here
LL |
LL | Bu64 = 0x8000_0000_0000_0000
- | --------------------- second assignment of `0` (overflowed from `9223372036854775808`)
+ | --------------------- `0` (overflowed from `9223372036854775808`) assigned here
error: aborting due to previous error
diff --git a/src/test/ui/env-funky-keys.rs b/src/test/ui/env-funky-keys.rs
index 4548d3339..46e20d8c6 100644
--- a/src/test/ui/env-funky-keys.rs
+++ b/src/test/ui/env-funky-keys.rs
@@ -6,6 +6,7 @@
// ignore-emscripten no execve
// ignore-sgx no execve
// ignore-vxworks no execve
+// ignore-fuchsia no 'execve'
// no-prefer-dynamic
#![feature(rustc_private)]
diff --git a/src/test/ui/error-codes/E0004.stderr b/src/test/ui/error-codes/E0004.stderr
index 8ba151d9e..4ac8c904f 100644
--- a/src/test/ui/error-codes/E0004.stderr
+++ b/src/test/ui/error-codes/E0004.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `HastaLaVistaBaby` not covered
+error[E0004]: non-exhaustive patterns: `Terminator::HastaLaVistaBaby` not covered
--> $DIR/E0004.rs:9:11
|
LL | match x {
- | ^ pattern `HastaLaVistaBaby` not covered
+ | ^ pattern `Terminator::HastaLaVistaBaby` not covered
|
note: `Terminator` defined here
--> $DIR/E0004.rs:2:5
@@ -15,7 +15,7 @@ LL | HastaLaVistaBaby,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Terminator::TalkToMyHand => {}
-LL + HastaLaVistaBaby => todo!()
+LL + Terminator::HastaLaVistaBaby => todo!()
|
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr
index f01a77bd3..de8e6bac4 100644
--- a/src/test/ui/error-codes/E0005.stderr
+++ b/src/test/ui/error-codes/E0005.stderr
@@ -19,7 +19,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let y = if let Some(y) = x { y } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Some(y) = x else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr
index 2307f52c9..bea226f09 100644
--- a/src/test/ui/error-codes/E0057.stderr
+++ b/src/test/ui/error-codes/E0057.stderr
@@ -12,7 +12,7 @@ LL | let f = |x| x * 3;
help: provide the argument
|
LL | let a = f(/* value */);
- | ~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/E0057.rs:5:13
@@ -28,7 +28,7 @@ LL | let f = |x| x * 3;
help: remove the extra argument
|
LL | let c = f(2);
- | ~~~~
+ | ~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/error-codes/E0060.stderr b/src/test/ui/error-codes/E0060.stderr
index 644fd5983..934a18d89 100644
--- a/src/test/ui/error-codes/E0060.stderr
+++ b/src/test/ui/error-codes/E0060.stderr
@@ -12,7 +12,7 @@ LL | fn printf(_: *const u8, ...) -> u32;
help: provide the argument
|
LL | unsafe { printf(/* *const u8 */); }
- | ~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0061.stderr b/src/test/ui/error-codes/E0061.stderr
index fa55db092..fa4ccbe66 100644
--- a/src/test/ui/error-codes/E0061.stderr
+++ b/src/test/ui/error-codes/E0061.stderr
@@ -12,7 +12,7 @@ LL | fn f(a: u16, b: &str) {}
help: provide the argument
|
LL | f(0, /* &str */);
- | ~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/E0061.rs:9:5
@@ -28,7 +28,7 @@ LL | fn f2(a: u16) {}
help: provide the argument
|
LL | f2(/* u16 */);
- | ~~~~~~~~~~~~~
+ | ~~~~~~~~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/error-codes/E0081.rs b/src/test/ui/error-codes/E0081.rs
index 5aa6a7863..f53fda864 100644
--- a/src/test/ui/error-codes/E0081.rs
+++ b/src/test/ui/error-codes/E0081.rs
@@ -1,9 +1,9 @@
enum Enum {
//~^ ERROR discriminant value `3` assigned more than once
P = 3,
- //~^ NOTE first assignment of `3`
+ //~^ NOTE `3` assigned here
X = 3,
- //~^ NOTE second assignment of `3`
+ //~^ NOTE `3` assigned here
Y = 5
}
@@ -11,20 +11,43 @@ enum Enum {
enum EnumOverflowRepr {
//~^ ERROR discriminant value `1` assigned more than once
P = 257,
- //~^ NOTE first assignment of `1` (overflowed from `257`)
+ //~^ NOTE `1` (overflowed from `257`) assigned here
X = 513,
- //~^ NOTE second assignment of `1` (overflowed from `513`)
+ //~^ NOTE `1` (overflowed from `513`) assigned here
}
#[repr(i8)]
enum NegDisEnum {
//~^ ERROR discriminant value `-1` assigned more than once
First = -1,
- //~^ NOTE first assignment of `-1`
+ //~^ NOTE `-1` assigned here
Second = -2,
- //~^ NOTE assigned discriminant for `Last` was incremented from this discriminant
+ //~^ NOTE discriminant for `Last` incremented from this startpoint (`Second` + 1 variant later => `Last` = -1)
Last,
- //~^ NOTE second assignment of `-1`
+ //~^ NOTE `-1` assigned here
+}
+
+enum MultipleDuplicates {
+ //~^ ERROR discriminant value `0` assigned more than once
+ //~^^ ERROR discriminant value `-2` assigned more than once
+ V0,
+ //~^ NOTE `0` assigned here
+ V1 = 0,
+ //~^ NOTE `0` assigned here
+ V2,
+ V3,
+ V4 = 0,
+ //~^ NOTE `0` assigned here
+ V5 = -2,
+ //~^ NOTE discriminant for `V7` incremented from this startpoint (`V5` + 2 variants later => `V7` = 0)
+ //~^^ NOTE `-2` assigned here
+ V6,
+ V7,
+ //~^ NOTE `0` assigned here
+ V8 = -3,
+ //~^ NOTE discriminant for `V9` incremented from this startpoint (`V8` + 1 variant later => `V9` = -2)
+ V9,
+ //~^ NOTE `-2` assigned here
}
fn main() {
diff --git a/src/test/ui/error-codes/E0081.stderr b/src/test/ui/error-codes/E0081.stderr
index ff6113646..64562fefc 100644
--- a/src/test/ui/error-codes/E0081.stderr
+++ b/src/test/ui/error-codes/E0081.stderr
@@ -5,10 +5,10 @@ LL | enum Enum {
| ^^^^^^^^^
LL |
LL | P = 3,
- | - first assignment of `3`
+ | - `3` assigned here
LL |
LL | X = 3,
- | - second assignment of `3`
+ | - `3` assigned here
error[E0081]: discriminant value `1` assigned more than once
--> $DIR/E0081.rs:11:1
@@ -17,10 +17,10 @@ LL | enum EnumOverflowRepr {
| ^^^^^^^^^^^^^^^^^^^^^
LL |
LL | P = 257,
- | --- first assignment of `1` (overflowed from `257`)
+ | --- `1` (overflowed from `257`) assigned here
LL |
LL | X = 513,
- | --- second assignment of `1` (overflowed from `513`)
+ | --- `1` (overflowed from `513`) assigned here
error[E0081]: discriminant value `-1` assigned more than once
--> $DIR/E0081.rs:20:1
@@ -29,14 +29,50 @@ LL | enum NegDisEnum {
| ^^^^^^^^^^^^^^^
LL |
LL | First = -1,
- | -- first assignment of `-1`
+ | -- `-1` assigned here
LL |
LL | Second = -2,
- | ----------- assigned discriminant for `Last` was incremented from this discriminant
+ | ----------- discriminant for `Last` incremented from this startpoint (`Second` + 1 variant later => `Last` = -1)
LL |
LL | Last,
- | ---- second assignment of `-1`
+ | ---- `-1` assigned here
-error: aborting due to 3 previous errors
+error[E0081]: discriminant value `0` assigned more than once
+ --> $DIR/E0081.rs:30:1
+ |
+LL | enum MultipleDuplicates {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | V0,
+ | -- `0` assigned here
+LL |
+LL | V1 = 0,
+ | - `0` assigned here
+...
+LL | V4 = 0,
+ | - `0` assigned here
+LL |
+LL | V5 = -2,
+ | ------- discriminant for `V7` incremented from this startpoint (`V5` + 2 variants later => `V7` = 0)
+...
+LL | V7,
+ | -- `0` assigned here
+
+error[E0081]: discriminant value `-2` assigned more than once
+ --> $DIR/E0081.rs:30:1
+ |
+LL | enum MultipleDuplicates {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | V5 = -2,
+ | -- `-2` assigned here
+...
+LL | V8 = -3,
+ | ------- discriminant for `V9` incremented from this startpoint (`V8` + 1 variant later => `V9` = -2)
+LL |
+LL | V9,
+ | -- `-2` assigned here
+
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0081`.
diff --git a/src/test/ui/error-codes/E0107.stderr b/src/test/ui/error-codes/E0107.stderr
index 5ca03b45d..03430f8fa 100644
--- a/src/test/ui/error-codes/E0107.stderr
+++ b/src/test/ui/error-codes/E0107.stderr
@@ -142,7 +142,7 @@ LL | pub trait T {
help: replace the generic bounds with the associated types
|
LL | fn trait_bound_generic<I: T<A = u8, B = u16>>(_i: I) {
- | ~~~~~~ ~~~~~~~
+ | +++ +++
error: aborting due to 10 previous errors
diff --git a/src/test/ui/error-codes/E0117.rs b/src/test/ui/error-codes/E0117.rs
index 22b486573..406d24e36 100644
--- a/src/test/ui/error-codes/E0117.rs
+++ b/src/test/ui/error-codes/E0117.rs
@@ -1,4 +1,4 @@
impl Drop for u32 {} //~ ERROR E0117
-//~| ERROR the `Drop` trait may only be implemented for structs, enums, and unions
+//~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
fn main() {}
diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr
index 76d9f5cc0..f144aa9f7 100644
--- a/src/test/ui/error-codes/E0117.stderr
+++ b/src/test/ui/error-codes/E0117.stderr
@@ -9,11 +9,11 @@ LL | impl Drop for u32 {}
|
= note: define and implement a trait or new type instead
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
--> $DIR/E0117.rs:1:15
|
LL | impl Drop for u32 {}
- | ^^^ must be a struct, enum, or union
+ | ^^^ must be a struct, enum, or union in the current crate
error: aborting due to 2 previous errors
diff --git a/src/test/ui/error-codes/E0120.stderr b/src/test/ui/error-codes/E0120.stderr
index 6c306455e..75778f1f9 100644
--- a/src/test/ui/error-codes/E0120.stderr
+++ b/src/test/ui/error-codes/E0120.stderr
@@ -1,8 +1,8 @@
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
--> $DIR/E0120.rs:3:15
|
LL | impl Drop for dyn MyTrait {
- | ^^^^^^^^^^^ must be a struct, enum, or union
+ | ^^^^^^^^^^^ must be a struct, enum, or union in the current crate
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0271.stderr b/src/test/ui/error-codes/E0271.stderr
index 9c9c7237d..1e2f43834 100644
--- a/src/test/ui/error-codes/E0271.stderr
+++ b/src/test/ui/error-codes/E0271.stderr
@@ -1,8 +1,10 @@
error[E0271]: type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
- --> $DIR/E0271.rs:10:5
+ --> $DIR/E0271.rs:10:9
|
LL | foo(3_i8);
- | ^^^ type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
+ | --- ^^^^ type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `u32`
--> $DIR/E0271.rs:7:43
diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr
index dfffbb182..87cfaa489 100644
--- a/src/test/ui/error-codes/E0275.stderr
+++ b/src/test/ui/error-codes/E0275.stderr
@@ -5,13 +5,13 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
-note: required because of the requirements on the impl of `Foo` for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
--> $DIR/E0275.rs:5:9
|
LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^ ^
= note: 127 redundant requirements hidden
- = note: required because of the requirements on the impl of `Foo` for `Bar<T>`
+ = note: required for `Bar<T>` to implement `Foo`
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0277-2.stderr b/src/test/ui/error-codes/E0277-2.stderr
index ca2cb8842..a2abf3793 100644
--- a/src/test/ui/error-codes/E0277-2.stderr
+++ b/src/test/ui/error-codes/E0277-2.stderr
@@ -1,8 +1,8 @@
error[E0277]: `*const u8` cannot be sent between threads safely
- --> $DIR/E0277-2.rs:16:5
+ --> $DIR/E0277-2.rs:16:15
|
LL | is_send::<Foo>();
- | ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
+ | ^^^ `*const u8` cannot be sent between threads safely
|
= help: within `Foo`, the trait `Send` is not implemented for `*const u8`
note: required because it appears within the type `Baz`
diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr
index 81715621d..b0e2ef5b6 100644
--- a/src/test/ui/error-codes/E0401.stderr
+++ b/src/test/ui/error-codes/E0401.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
LL | fn foo<T>(x: T) {
| - type parameter from outer function
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
- | --------------------------- ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `T,`
error[E0401]: can't use generic parameters from outer function
--> $DIR/E0401.rs:9:16
@@ -15,7 +15,7 @@ LL | fn foo<T>(x: T) {
| - type parameter from outer function
...
LL | fn baz<U,
- | --- try adding a local generic parameter in this method instead
+ | - help: try using a local generic parameter instead: `T,`
...
LL | (y: T) {
| ^ use of generic parameter from outer function
diff --git a/src/test/ui/error-codes/E0565-2.stderr b/src/test/ui/error-codes/E0565-2.stderr
index bb30bd7be..097871bd3 100644
--- a/src/test/ui/error-codes/E0565-2.stderr
+++ b/src/test/ui/error-codes/E0565-2.stderr
@@ -2,7 +2,9 @@ error[E0565]: literal in `deprecated` value must be a string
--> $DIR/E0565-2.rs:2:22
|
LL | #[deprecated(since = b"1.29", note = "hi")]
- | ^^^^^^^ help: consider removing the prefix: `"1.29"`
+ | -^^^^^^
+ | |
+ | help: consider removing the prefix
error: aborting due to previous error
diff --git a/src/test/ui/explore-issue-38412.stderr b/src/test/ui/explore-issue-38412.stderr
index e3f82137a..08dadb4db 100644
--- a/src/test/ui/explore-issue-38412.stderr
+++ b/src/test/ui/explore-issue-38412.stderr
@@ -43,19 +43,19 @@ LL | t.2;
= note: see issue #38412 <https://github.com/rust-lang/rust/issues/38412> for more information
= help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable
-error[E0616]: field `3` of struct `Tuple` is private
+error[E0616]: field `3` of struct `pub_and_stability::Tuple` is private
--> $DIR/explore-issue-38412.rs:36:7
|
LL | t.3;
| ^ private field
-error[E0616]: field `4` of struct `Tuple` is private
+error[E0616]: field `4` of struct `pub_and_stability::Tuple` is private
--> $DIR/explore-issue-38412.rs:37:7
|
LL | t.4;
| ^ private field
-error[E0616]: field `5` of struct `Tuple` is private
+error[E0616]: field `5` of struct `pub_and_stability::Tuple` is private
--> $DIR/explore-issue-38412.rs:38:7
|
LL | t.5;
diff --git a/src/test/ui/expr/if/if-branch-types.stderr b/src/test/ui/expr/if/if-branch-types.stderr
index 14f02163a..d2bba8821 100644
--- a/src/test/ui/expr/if/if-branch-types.stderr
+++ b/src/test/ui/expr/if/if-branch-types.stderr
@@ -5,6 +5,11 @@ LL | let x = if true { 10i32 } else { 10u32 };
| ----- ^^^^^ expected `i32`, found `u32`
| |
| expected because of this
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | let x = if true { 10i32 } else { 10i32 };
+ | ~~~
error: aborting due to previous error
diff --git a/src/test/ui/expr/if/if-else-type-mismatch.stderr b/src/test/ui/expr/if/if-else-type-mismatch.stderr
index 9fa190d6c..f1fffdb1e 100644
--- a/src/test/ui/expr/if/if-else-type-mismatch.stderr
+++ b/src/test/ui/expr/if/if-else-type-mismatch.stderr
@@ -10,6 +10,11 @@ LL | | 2u32
| | ^^^^ expected `i32`, found `u32`
LL | | };
| |_____- `if` and `else` have incompatible types
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 2i32
+ | ~~~
error[E0308]: `if` and `else` have incompatible types
--> $DIR/if-else-type-mismatch.rs:8:38
@@ -18,6 +23,11 @@ LL | let _ = if true { 42i32 } else { 42u32 };
| ----- ^^^^^ expected `i32`, found `u32`
| |
| expected because of this
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | let _ = if true { 42i32 } else { 42i32 };
+ | ~~~
error[E0308]: `if` and `else` have incompatible types
--> $DIR/if-else-type-mismatch.rs:13:9
diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr
index 8d6713261..a79caced1 100644
--- a/src/test/ui/extern/extern-types-unsized.stderr
+++ b/src/test/ui/extern/extern-types-unsized.stderr
@@ -16,10 +16,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++
error[E0277]: the size for values of type `A` cannot be known at compilation time
- --> $DIR/extern-types-unsized.rs:25:5
+ --> $DIR/extern-types-unsized.rs:25:20
|
LL | assert_sized::<Foo>();
- | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | ^^^ doesn't have a size known at compile-time
|
= help: within `Foo`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Foo`
@@ -38,10 +38,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++
error[E0277]: the size for values of type `A` cannot be known at compilation time
- --> $DIR/extern-types-unsized.rs:28:5
+ --> $DIR/extern-types-unsized.rs:28:20
|
LL | assert_sized::<Bar<A>>();
- | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | ^^^^^^ doesn't have a size known at compile-time
|
= help: within `Bar<A>`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Bar<A>`
@@ -60,10 +60,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++
error[E0277]: the size for values of type `A` cannot be known at compilation time
- --> $DIR/extern-types-unsized.rs:31:5
+ --> $DIR/extern-types-unsized.rs:31:20
|
LL | assert_sized::<Bar<Bar<A>>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `Bar<Bar<A>>`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Bar<A>`
diff --git a/src/test/ui/extern/extern-wrong-value-type.stderr b/src/test/ui/extern/extern-wrong-value-type.stderr
index c6f0d5df9..ff2934a2b 100644
--- a/src/test/ui/extern/extern-wrong-value-type.stderr
+++ b/src/test/ui/extern/extern-wrong-value-type.stderr
@@ -6,7 +6,7 @@ LL | is_fn(f);
| |
| required by a bound introduced by this call
|
- = help: the trait `Fn<()>` is not implemented for `extern "C" fn() {f}`
+ = help: the trait `Fn<()>` is not implemented for fn item `extern "C" fn() {f}`
= note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `is_fn`
--> $DIR/extern-wrong-value-type.rs:4:28
diff --git a/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs
new file mode 100644
index 000000000..f73bf579f
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs
@@ -0,0 +1,7 @@
+#[collapse_debuginfo]
+//~^ ERROR the `#[collapse_debuginfo]` attribute is an experimental feature
+macro_rules! foo {
+ ($e:expr) => { $e }
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr
new file mode 100644
index 000000000..2cbde893a
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[collapse_debuginfo]` attribute is an experimental feature
+ --> $DIR/feature-gate-collapse_debuginfo.rs:1:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #100758 <https://github.com/rust-lang/rust/issues/100758> for more information
+ = help: add `#![feature(collapse_debuginfo)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
index f8349391a..5ced344f1 100644
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
+++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
@@ -19,7 +19,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let _x = if let Ok(_x) = foo() { _x } else { todo!() };
| +++++++++++ +++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Ok(_x) = foo() else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
index 49eede479..56123a983 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
+++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
@@ -1,33 +1,24 @@
-error[E0658]: using `_` for array lengths is unstable
+error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/feature-gate-generic_arg_infer.rs:11:27
|
LL | let _x: [u8; 3] = [0; _];
- | ^
- |
- = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
- = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+ | ^ `_` not allowed here
error: in expressions, `_` can only be used on the left-hand side of an assignment
- --> $DIR/feature-gate-generic_arg_infer.rs:11:27
+ --> $DIR/feature-gate-generic_arg_infer.rs:14:18
|
-LL | let _x: [u8; 3] = [0; _];
- | ^ `_` not allowed here
+LL | let _y: [u8; _] = [0; 3];
+ | ^ `_` not allowed here
error[E0658]: using `_` for array lengths is unstable
--> $DIR/feature-gate-generic_arg_infer.rs:14:18
|
LL | let _y: [u8; _] = [0; 3];
- | ^
+ | ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
-error: in expressions, `_` can only be used on the left-hand side of an assignment
- --> $DIR/feature-gate-generic_arg_infer.rs:14:18
- |
-LL | let _y: [u8; _] = [0; 3];
- | ^ `_` not allowed here
-
error[E0747]: type provided when a constant was expected
--> $DIR/feature-gate-generic_arg_infer.rs:20:20
|
@@ -37,6 +28,15 @@ LL | let _x = foo::<_>([1,2]);
= help: const arguments cannot yet be inferred with `_`
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+error[E0658]: using `_` for array lengths is unstable
+ --> $DIR/feature-gate-generic_arg_infer.rs:11:27
+ |
+LL | let _x: [u8; 3] = [0; _];
+ | ^
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0658, E0747.
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs b/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs
deleted file mode 100644
index c5c134514..000000000
--- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use std::ops::Deref;
-
-trait PointerFamily<U> {
- type Pointer<T>: Deref<Target = T>;
- //~^ ERROR generic associated types are unstable
- type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
- //~^ ERROR generic associated types are unstable
- //~| ERROR where clauses on associated types are unstable
-}
-
-struct Foo;
-
-impl PointerFamily<u32> for Foo {
- type Pointer<Usize> = Box<Usize>;
- //~^ ERROR generic associated types are unstable
- type Pointer2<U32> = Box<U32>;
- //~^ ERROR generic associated types are unstable
- //~| ERROR the trait bound `U32: Clone` is not satisfied
-}
-
-trait Bar {
- type Assoc where Self: Sized;
- //~^ ERROR where clauses on associated types are unstable
-}
-
-impl Bar for Foo {
- type Assoc = Foo where Self: Sized;
- //~^ ERROR where clauses on associated types are unstable
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr
deleted file mode 100644
index 12a40ff0a..000000000
--- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr
+++ /dev/null
@@ -1,78 +0,0 @@
-error[E0658]: generic associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:4:5
- |
-LL | type Pointer<T>: Deref<Target = T>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: generic associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:6:5
- |
-LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: where clauses on associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:6:5
- |
-LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: generic associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:14:5
- |
-LL | type Pointer<Usize> = Box<Usize>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: generic associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:16:5
- |
-LL | type Pointer2<U32> = Box<U32>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: where clauses on associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:22:5
- |
-LL | type Assoc where Self: Sized;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: where clauses on associated types are unstable
- --> $DIR/feature-gate-generic_associated_types.rs:27:5
- |
-LL | type Assoc = Foo where Self: Sized;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0277]: the trait bound `U32: Clone` is not satisfied
- --> $DIR/feature-gate-generic_associated_types.rs:16:26
- |
-LL | type Pointer2<U32> = Box<U32>;
- | ^^^^^^^^ the trait `Clone` is not implemented for `U32`
- |
-help: consider restricting type parameter `U32`
- |
-LL | type Pointer2<U32: std::clone::Clone> = Box<U32>;
- | +++++++++++++++++++
-
-error: aborting due to 8 previous errors
-
-Some errors have detailed explanations: E0277, E0658.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs
index 258b8cd35..7842d44ac 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs
+++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// This feature doesn't *currently* fire on any specific code; it's just a
// behavior change. Future changes might.
#[rustc_error] //~ the
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr
index 6a5eba38c..bb1622628 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr
+++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr
@@ -1,5 +1,5 @@
error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
- --> $DIR/feature-gate-generic_associated_types_extended.rs:5:1
+ --> $DIR/feature-gate-generic_associated_types_extended.rs:3:1
|
LL | #[rustc_error]
| ^^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-label_break_value.rs b/src/test/ui/feature-gates/feature-gate-label_break_value.rs
deleted file mode 100644
index 6fc38f455..000000000
--- a/src/test/ui/feature-gates/feature-gate-label_break_value.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub fn main() {
- 'a: { //~ ERROR labels on blocks are unstable
- break 'a;
- }
-}
diff --git a/src/test/ui/feature-gates/feature-gate-label_break_value.stderr b/src/test/ui/feature-gates/feature-gate-label_break_value.stderr
deleted file mode 100644
index 4b43fdc59..000000000
--- a/src/test/ui/feature-gates/feature-gate-label_break_value.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: labels on blocks are unstable
- --> $DIR/feature-gate-label_break_value.rs:2:5
- |
-LL | 'a: {
- | ^^
- |
- = note: see issue #48594 <https://github.com/rust-lang/rust/issues/48594> for more information
- = help: add `#![feature(label_break_value)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-let_else.rs b/src/test/ui/feature-gates/feature-gate-let_else.rs
deleted file mode 100644
index 3f04a9dab..000000000
--- a/src/test/ui/feature-gates/feature-gate-let_else.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
- let Some(x) = Some(1) else { //~ ERROR `let...else` statements are unstable
- return;
- };
-}
diff --git a/src/test/ui/feature-gates/feature-gate-let_else.stderr b/src/test/ui/feature-gates/feature-gate-let_else.stderr
deleted file mode 100644
index 862526041..000000000
--- a/src/test/ui/feature-gates/feature-gate-let_else.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0658]: `let...else` statements are unstable
- --> $DIR/feature-gate-let_else.rs:2:5
- |
-LL | / let Some(x) = Some(1) else {
-LL | | return;
-LL | | };
- | |______^
- |
- = note: see issue #87335 <https://github.com/rust-lang/rust/issues/87335> for more information
- = help: add `#![feature(let_else)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs
index 29a6e1f8a..9b646060a 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs
@@ -21,7 +21,7 @@ fn main() {
Foo::A => {}
Foo::B => {}
}
- //~^^^^ ERROR non-exhaustive patterns: `C` not covered
+ //~^^^^ ERROR non-exhaustive patterns: `Foo::C` not covered
match Foo::A {
Foo::A => {}
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
index dbeef6c2d..3de08e215 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
@@ -99,11 +99,11 @@ LL | #[warn(non_exhaustive_omitted_patterns)]
= note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
-error[E0004]: non-exhaustive patterns: `C` not covered
+error[E0004]: non-exhaustive patterns: `Foo::C` not covered
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:20:11
|
LL | match Foo::A {
- | ^^^^^^ pattern `C` not covered
+ | ^^^^^^ pattern `Foo::C` not covered
|
note: `Foo` defined here
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:12:15
@@ -116,7 +116,7 @@ LL | A, B, C,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Foo::B => {}
-LL + C => todo!()
+LL + Foo::C => todo!()
|
error: aborting due to previous error; 10 warnings emitted
diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
index 72cb4cc84..d76c697fe 100644
--- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
+++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
@@ -13,10 +13,10 @@ LL | trait NonObjectSafe1: Sized {}
| this trait cannot be made into an object...
error[E0038]: the trait `NonObjectSafe2` cannot be made into an object
- --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36
+ --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:45
|
LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe2` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe2` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-object_safe_for_dispatch.rs:7:8
@@ -50,10 +50,10 @@ LL | fn foo<T>(&self);
= help: consider moving `foo` to another trait
error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
- --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35
+ --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:47
|
LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-object_safe_for_dispatch.rs:15:22
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs
index 518aa20dd..fc47a9061 100644
--- a/src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs
@@ -1,8 +1,12 @@
+// only-x86
#[link(name = "foo")]
extern "C" {
#[link_ordinal(42)]
- //~^ ERROR: the `#[link_ordinal]` attribute is an experimental feature
+ //~^ ERROR: `#[link_ordinal]` is unstable on x86
fn foo();
+ #[link_ordinal(5)]
+ //~^ ERROR: `#[link_ordinal]` is unstable on x86
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr
index dbee5f316..0e900760d 100644
--- a/src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr
@@ -1,5 +1,5 @@
-error[E0658]: the `#[link_ordinal]` attribute is an experimental feature
- --> $DIR/feature-gate-raw-dylib-2.rs:3:5
+error[E0658]: `#[link_ordinal]` is unstable on x86
+ --> $DIR/feature-gate-raw-dylib-2.rs:4:5
|
LL | #[link_ordinal(42)]
| ^^^^^^^^^^^^^^^^^^^
@@ -7,6 +7,15 @@ LL | #[link_ordinal(42)]
= note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
= help: add `#![feature(raw_dylib)]` to the crate attributes to enable
-error: aborting due to previous error
+error[E0658]: `#[link_ordinal]` is unstable on x86
+ --> $DIR/feature-gate-raw-dylib-2.rs:7:5
+ |
+LL | #[link_ordinal(5)]
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = help: add `#![feature(raw_dylib)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs
new file mode 100644
index 000000000..295f502d6
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs
@@ -0,0 +1,8 @@
+// only-windows
+// only-x86
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+//~^ ERROR link kind `raw-dylib` is unstable on x86
+//~| ERROR import name type is unstable
+extern "C" {}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr
new file mode 100644
index 000000000..d6b165b76
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr
@@ -0,0 +1,21 @@
+error[E0658]: link kind `raw-dylib` is unstable on x86
+ --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:29
+ |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+ | ^^^^^^^^^^^
+ |
+ = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = help: add `#![feature(raw_dylib)]` to the crate attributes to enable
+
+error[E0658]: import name type is unstable
+ --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:61
+ |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+ | ^^^^^^^^^^^
+ |
+ = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = help: add `#![feature(raw_dylib)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib.rs
index f894f517b..291cca8fd 100644
--- a/src/test/ui/feature-gates/feature-gate-raw-dylib.rs
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib.rs
@@ -1,6 +1,7 @@
// only-windows
+// only-x86
#[link(name = "foo", kind = "raw-dylib")]
-//~^ ERROR: link kind `raw-dylib` is unstable
+//~^ ERROR: link kind `raw-dylib` is unstable on x86
extern "C" {}
fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib.stderr
index ca7a61f64..f02241e49 100644
--- a/src/test/ui/feature-gates/feature-gate-raw-dylib.stderr
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib.stderr
@@ -1,5 +1,5 @@
-error[E0658]: link kind `raw-dylib` is unstable
- --> $DIR/feature-gate-raw-dylib.rs:2:29
+error[E0658]: link kind `raw-dylib` is unstable on x86
+ --> $DIR/feature-gate-raw-dylib.rs:3:29
|
LL | #[link(name = "foo", kind = "raw-dylib")]
| ^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-register_attr.rs b/src/test/ui/feature-gates/feature-gate-register_attr.rs
deleted file mode 100644
index 36dce2aa7..000000000
--- a/src/test/ui/feature-gates/feature-gate-register_attr.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![register_attr(attr)] //~ ERROR the `#[register_attr]` attribute is an experimental feature
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-register_attr.stderr b/src/test/ui/feature-gates/feature-gate-register_attr.stderr
deleted file mode 100644
index 8ca3845d2..000000000
--- a/src/test/ui/feature-gates/feature-gate-register_attr.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: the `#[register_attr]` attribute is an experimental feature
- --> $DIR/feature-gate-register_attr.rs:1:1
- |
-LL | #![register_attr(attr)]
- | ^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #66080 <https://github.com/rust-lang/rust/issues/66080> for more information
- = help: add `#![feature(register_attr)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs
new file mode 100644
index 000000000..de7966c66
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs
@@ -0,0 +1,5 @@
+trait Foo {
+ fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
new file mode 100644
index 000000000..36177bbe1
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
@@ -0,0 +1,12 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+ --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:2:17
+ |
+LL | fn bar() -> impl Sized;
+ | ^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/feature-gates/feature-gate-unix_sigpipe.rs b/src/test/ui/feature-gates/feature-gate-unix_sigpipe.rs
new file mode 100644
index 000000000..46dc3f6cc
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-unix_sigpipe.rs
@@ -0,0 +1,4 @@
+#![crate_type = "bin"]
+
+#[unix_sigpipe = "inherit"] //~ the `#[unix_sigpipe]` attribute is an experimental feature
+fn main () {}
diff --git a/src/test/ui/feature-gates/feature-gate-unix_sigpipe.stderr b/src/test/ui/feature-gates/feature-gate-unix_sigpipe.stderr
new file mode 100644
index 000000000..cf3284467
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-unix_sigpipe.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[unix_sigpipe]` attribute is an experimental feature
+ --> $DIR/feature-gate-unix_sigpipe.rs:3:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #97889 <https://github.com/rust-lang/rust/issues/97889> for more information
+ = help: add `#![feature(unix_sigpipe)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs
new file mode 100644
index 000000000..49f1cba71
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs
@@ -0,0 +1,30 @@
+// check-fail
+// This file is used to test the behavior of the early-pass syntax warnings.
+// If macro syntax is stabilized, replace with a different unstable syntax.
+
+macro a() {}
+//~^ ERROR: `macro` is experimental
+
+#[cfg(FALSE)]
+macro b() {}
+
+macro_rules! identity {
+ ($($x:tt)*) => ($($x)*);
+}
+
+identity! {
+ macro c() {}
+ //~^ ERROR: `macro` is experimental
+}
+
+#[cfg(FALSE)]
+identity! {
+ macro d() {} // No error
+}
+
+identity! {
+ #[cfg(FALSE)]
+ macro e() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr
new file mode 100644
index 000000000..49550d811
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr
@@ -0,0 +1,21 @@
+error[E0658]: `macro` is experimental
+ --> $DIR/soft-syntax-gates-with-errors.rs:5:1
+ |
+LL | macro a() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+ = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+
+error[E0658]: `macro` is experimental
+ --> $DIR/soft-syntax-gates-with-errors.rs:16:5
+ |
+LL | macro c() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+ = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs
new file mode 100644
index 000000000..ca4ad2320
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs
@@ -0,0 +1,26 @@
+// check-pass
+// This file is used to test the behavior of the early-pass syntax warnings.
+// If macro syntax is stabilized, replace with a different unstable syntax.
+
+#[cfg(FALSE)]
+macro b() {}
+//~^ WARN: `macro` is experimental
+//~| WARN: unstable syntax
+
+macro_rules! identity {
+ ($($x:tt)*) => ($($x)*);
+}
+
+#[cfg(FALSE)]
+identity! {
+ macro d() {} // No error
+}
+
+identity! {
+ #[cfg(FALSE)]
+ macro e() {}
+ //~^ WARN: `macro` is experimental
+ //~| WARN: unstable syntax
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr
new file mode 100644
index 000000000..3d9c22e54
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr
@@ -0,0 +1,24 @@
+warning: `macro` is experimental
+ --> $DIR/soft-syntax-gates-without-errors.rs:6:1
+ |
+LL | macro b() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+ = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: `macro` is experimental
+ --> $DIR/soft-syntax-gates-without-errors.rs:21:5
+ |
+LL | macro e() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+ = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/fmt/ifmt-bad-arg.rs b/src/test/ui/fmt/ifmt-bad-arg.rs
index 84f4cc7f4..f00cb05c9 100644
--- a/src/test/ui/fmt/ifmt-bad-arg.rs
+++ b/src/test/ui/fmt/ifmt-bad-arg.rs
@@ -94,4 +94,6 @@ tenth number: {}",
// doesn't exist.
println!("{:.*}");
//~^ ERROR 2 positional arguments in format string, but no arguments were given
+ println!("{:.0$}");
+ //~^ ERROR 1 positional argument in format string, but no arguments were given
}
diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr
index 5439ee173..dbb4bc6d9 100644
--- a/src/test/ui/fmt/ifmt-bad-arg.stderr
+++ b/src/test/ui/fmt/ifmt-bad-arg.stderr
@@ -273,6 +273,17 @@ LL | println!("{:.*}");
= note: positional arguments are zero-based
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
+error: 1 positional argument in format string, but no arguments were given
+ --> $DIR/ifmt-bad-arg.rs:97:15
+ |
+LL | println!("{:.0$}");
+ | ^^---^
+ | |
+ | this precision flag expects an `usize` argument at position 0, but no arguments were given
+ |
+ = note: positional arguments are zero-based
+ = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
+
error[E0425]: cannot find value `foo` in this scope
--> $DIR/ifmt-bad-arg.rs:27:18
|
@@ -339,7 +350,7 @@ LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
| ^^^^^^^^^^
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 37 previous errors
+error: aborting due to 38 previous errors
Some errors have detailed explanations: E0308, E0425.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/fmt/ifmt-unimpl.stderr b/src/test/ui/fmt/ifmt-unimpl.stderr
index dbcb2eb66..0e34f9135 100644
--- a/src/test/ui/fmt/ifmt-unimpl.stderr
+++ b/src/test/ui/fmt/ifmt-unimpl.stderr
@@ -14,7 +14,7 @@ LL | format!("{:X}", "3");
NonZeroI8
NonZeroIsize
and 21 others
- = note: required because of the requirements on the impl of `UpperHex` for `&str`
+ = note: required for `&str` to implement `UpperHex`
note: required by a bound in `ArgumentV1::<'a>::new_upper_hex`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index 7c7a3c884..3ed040c3a 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -1,14 +1,16 @@
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
- --> $DIR/send-sync.rs:8:5
+ --> $DIR/send-sync.rs:8:10
|
LL | send(format_args!("{:?}", c));
- | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely
+ | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
|
= help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque`
= note: required because it appears within the type `&core::fmt::Opaque`
= note: required because it appears within the type `ArgumentV1<'_>`
= note: required because it appears within the type `[ArgumentV1<'_>]`
- = note: required because of the requirements on the impl of `Send` for `&[ArgumentV1<'_>]`
+ = note: required for `&[ArgumentV1<'_>]` to implement `Send`
= note: required because it appears within the type `Arguments<'_>`
note: required by a bound in `send`
--> $DIR/send-sync.rs:1:12
@@ -17,10 +19,12 @@ LL | fn send<T: Send>(_: T) {}
| ^^^^ required by this bound in `send`
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
- --> $DIR/send-sync.rs:9:5
+ --> $DIR/send-sync.rs:9:10
|
LL | sync(format_args!("{:?}", c));
- | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely
+ | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
|
= help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque`
= note: required because it appears within the type `&core::fmt::Opaque`
diff --git a/src/test/ui/fn/fn-compare-mismatch.stderr b/src/test/ui/fn/fn-compare-mismatch.stderr
index 096440225..df838cb11 100644
--- a/src/test/ui/fn/fn-compare-mismatch.stderr
+++ b/src/test/ui/fn/fn-compare-mismatch.stderr
@@ -6,14 +6,10 @@ LL | let x = f == g;
| |
| fn() {f}
|
-help: you might have forgotten to call this function
+help: use parentheses to call these
|
-LL | let x = f() == g;
- | ++
-help: you might have forgotten to call this function
- |
-LL | let x = f == g();
- | ++
+LL | let x = f() == g();
+ | ++ ++
error[E0308]: mismatched types
--> $DIR/fn-compare-mismatch.rs:4:18
diff --git a/src/test/ui/fn/fn-item-type.stderr b/src/test/ui/fn/fn-item-type.stderr
index ecc6485d6..f03a47d5c 100644
--- a/src/test/ui/fn/fn-item-type.stderr
+++ b/src/test/ui/fn/fn-item-type.stderr
@@ -15,7 +15,7 @@ note: function defined here
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:22:19
@@ -34,7 +34,7 @@ note: function defined here
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:29:23
@@ -53,7 +53,7 @@ note: function defined here
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:38:26
@@ -72,7 +72,7 @@ note: function defined here
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:45:19
@@ -90,7 +90,7 @@ note: function defined here
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error: aborting due to 5 previous errors
diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr
index ea88e401b..2a674d3c1 100644
--- a/src/test/ui/fn/fn-trait-formatting.stderr
+++ b/src/test/ui/fn/fn-trait-formatting.stderr
@@ -8,6 +8,10 @@ LL | let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
|
= note: expected unit type `()`
found struct `Box<dyn FnOnce(isize)>`
+help: use parentheses to call this trait object
+ |
+LL | let _: () = (Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>)(/* isize */);
+ | + ++++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-trait-formatting.rs:10:17
@@ -19,6 +23,10 @@ LL | let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>
|
= note: expected unit type `()`
found struct `Box<dyn Fn(isize, isize)>`
+help: use parentheses to call this trait object
+ |
+LL | let _: () = (Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>)(/* isize */, /* isize */);
+ | + +++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-trait-formatting.rs:14:17
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs
index 5a92bcd37..5d9245556 100644
--- a/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.rs
@@ -1,4 +1,4 @@
-// check-pass
+// check-fail
trait Trait {
type Type;
@@ -17,6 +17,7 @@ where
fn g<'a, 'b>() {
f::<'a, 'b>(());
+ //~^ ERROR lifetime may not live long enough
}
fn main() {}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.stderr
new file mode 100644
index 000000000..0c3df04ea
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-2.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/implied-bounds-unnorm-associated-type-2.rs:19:5
+ |
+LL | fn g<'a, 'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | f::<'a, 'b>(());
+ | ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+ = note: requirement occurs because of a function pointer to `f`
+ = note: the function `f` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs
index dc25ac086..888f74cf6 100644
--- a/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.rs
@@ -1,6 +1,4 @@
-// check-fail
-// See issue #91899. If we treat unnormalized args as WF, `Self` can also be a
-// source of unsoundness.
+// check-pass
pub trait Yokeable<'a>: 'static {
type Output: 'a;
@@ -17,7 +15,6 @@ pub trait ZeroCopyFrom<C: ?Sized>: for<'a> Yokeable<'a> {
impl<T> ZeroCopyFrom<[T]> for &'static [T] {
fn zero_copy_from<'b>(cart: &'b [T]) -> &'b [T] {
- //~^ the parameter
cart
}
}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr
deleted file mode 100644
index 95cf4fb16..000000000
--- a/src/test/ui/fn/implied-bounds-unnorm-associated-type-3.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/implied-bounds-unnorm-associated-type-3.rs:19:5
- |
-LL | fn zero_copy_from<'b>(cart: &'b [T]) -> &'b [T] {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `[T]` will meet its required lifetime bounds
- |
-help: consider adding an explicit lifetime bound...
- |
-LL | impl<T: 'static> ZeroCopyFrom<[T]> for &'static [T] {
- | +++++++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-4.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type-4.rs
new file mode 100644
index 000000000..12859252c
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-4.rs
@@ -0,0 +1,24 @@
+// A regression test for #98543
+
+trait Trait {
+ type Type;
+}
+
+impl<T> Trait for T {
+ type Type = ();
+}
+
+fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str
+where
+ &'a &'b (): Trait, // <- adding this bound is the change from #91068
+{
+ s
+}
+
+fn main() {
+ let x = String::from("Hello World!");
+ let y = f(&x, ());
+ drop(x);
+ //~^ ERROR cannot move out of `x` because it is borrowed
+ println!("{}", y);
+}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-4.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type-4.stderr
new file mode 100644
index 000000000..fcbaa91d1
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-4.stderr
@@ -0,0 +1,14 @@
+error[E0505]: cannot move out of `x` because it is borrowed
+ --> $DIR/implied-bounds-unnorm-associated-type-4.rs:21:10
+ |
+LL | let y = f(&x, ());
+ | -- borrow of `x` occurs here
+LL | drop(x);
+ | ^ move out of `x` occurs here
+LL |
+LL | println!("{}", y);
+ | - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-5.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type-5.rs
new file mode 100644
index 000000000..2a9a6a8cc
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-5.rs
@@ -0,0 +1,23 @@
+trait Trait<'a>: 'a {
+ type Type;
+}
+
+// if the `T: 'a` bound gets implied we would probably get ub here again
+impl<'a, T> Trait<'a> for T {
+ //~^ ERROR the parameter type `T` may not live long enough
+ type Type = ();
+}
+
+fn f<'a, 'b>(s: &'b str, _: <&'b () as Trait<'a>>::Type) -> &'a str
+where
+ &'b (): Trait<'a>,
+{
+ s
+}
+
+fn main() {
+ let x = String::from("Hello World!");
+ let y = f(&x, ());
+ drop(x);
+ println!("{}", y);
+}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type-5.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type-5.stderr
new file mode 100644
index 000000000..458756a3d
--- /dev/null
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type-5.stderr
@@ -0,0 +1,19 @@
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/implied-bounds-unnorm-associated-type-5.rs:6:13
+ |
+LL | impl<'a, T> Trait<'a> for T {
+ | ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+ |
+note: ...that is required by this bound
+ --> $DIR/implied-bounds-unnorm-associated-type-5.rs:1:18
+ |
+LL | trait Trait<'a>: 'a {
+ | ^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<'a, T: 'a> Trait<'a> for T {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs b/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
index 04b6f4dd8..d58d25036 100644
--- a/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
@@ -1,6 +1,6 @@
// check-fail
-// See issue #91068. Types in the substs of an associated type can't be implied
-// to be WF, since they don't actually have to be constructed.
+// See issue #91068. We check that the unnormalized associated types in
+// function signatures are implied
trait Trait {
type Type;
@@ -12,12 +12,12 @@ impl<T> Trait for T {
fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
s
- //~^ ERROR lifetime may not live long enough
}
fn main() {
let x = String::from("Hello World!");
let y = f(&x, ());
drop(x);
+ //~^ ERROR cannot move out of `x` because it is borrowed
println!("{}", y);
}
diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
index 8096f0838..e35f46e44 100644
--- a/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
+++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
@@ -1,14 +1,14 @@
-error: lifetime may not live long enough
- --> $DIR/implied-bounds-unnorm-associated-type.rs:14:5
+error[E0505]: cannot move out of `x` because it is borrowed
+ --> $DIR/implied-bounds-unnorm-associated-type.rs:20:10
|
-LL | fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
- | -- -- lifetime `'b` defined here
- | |
- | lifetime `'a` defined here
-LL | s
- | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
- |
- = help: consider adding the following bound: `'b: 'a`
+LL | let y = f(&x, ());
+ | -- borrow of `x` occurs here
+LL | drop(x);
+ | ^ move out of `x` occurs here
+LL |
+LL | println!("{}", y);
+ | - borrow later used here
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0505`.
diff --git a/src/test/ui/for-loop-while/break-while-condition.stderr b/src/test/ui/for-loop-while/break-while-condition.stderr
index 6960c4fd8..e79f6a75f 100644
--- a/src/test/ui/for-loop-while/break-while-condition.stderr
+++ b/src/test/ui/for-loop-while/break-while-condition.stderr
@@ -31,6 +31,14 @@ LL | | }
|
= note: expected type `!`
found unit type `()`
+note: the function expects a value to always be returned, but loops might run zero times
+ --> $DIR/break-while-condition.rs:24:13
+ |
+LL | while false {
+ | ^^^^^^^^^^^ this might have zero elements to iterate on
+LL | return
+ | ------ if the loop doesn't execute, this value would never get returned
+ = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
error: aborting due to 3 previous errors
diff --git a/src/test/ui/for-loop-while/label_break_value.rs b/src/test/ui/for-loop-while/label_break_value.rs
index ca9d71a7a..10992c505 100644
--- a/src/test/ui/for-loop-while/label_break_value.rs
+++ b/src/test/ui/for-loop-while/label_break_value.rs
@@ -1,7 +1,6 @@
// run-pass
#![allow(dead_code)]
#![allow(unused_assignments)]
-#![feature(label_break_value)]
// Test control flow to follow label_break_value semantics
fn label_break(a: bool, b: bool) -> u32 {
diff --git a/src/test/ui/for-loop-while/label_break_value_invalid.rs b/src/test/ui/for-loop-while/label_break_value_invalid.rs
index 149bf17b8..fcf2e0f29 100644
--- a/src/test/ui/for-loop-while/label_break_value_invalid.rs
+++ b/src/test/ui/for-loop-while/label_break_value_invalid.rs
@@ -1,5 +1,4 @@
#![crate_type = "lib"]
-#![feature(label_break_value)]
fn lbv_macro_test_hygiene_respected() {
macro_rules! mac2 {
diff --git a/src/test/ui/for-loop-while/label_break_value_invalid.stderr b/src/test/ui/for-loop-while/label_break_value_invalid.stderr
index 7182b8f59..f6999c4ab 100644
--- a/src/test/ui/for-loop-while/label_break_value_invalid.stderr
+++ b/src/test/ui/for-loop-while/label_break_value_invalid.stderr
@@ -1,5 +1,5 @@
error[E0426]: use of undeclared label `'a`
- --> $DIR/label_break_value_invalid.rs:7:19
+ --> $DIR/label_break_value_invalid.rs:6:19
|
LL | break 'a $val;
| ^^ undeclared label `'a`
@@ -10,7 +10,7 @@ LL | mac2!(2);
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0426]: use of undeclared label `'a`
- --> $DIR/label_break_value_invalid.rs:29:19
+ --> $DIR/label_break_value_invalid.rs:28:19
|
LL | let x: u8 = mac3!('b: {
| -- a label with a similar name is reachable
@@ -22,7 +22,7 @@ LL | break 'a 3;
| help: try using similarly named label: `'b`
error[E0426]: use of undeclared label `'a`
- --> $DIR/label_break_value_invalid.rs:34:29
+ --> $DIR/label_break_value_invalid.rs:33:29
|
LL | let x: u8 = mac3!(break 'a 4);
| ^^ undeclared label `'a`
diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs
index 86a1c1a34..b086128d2 100644
--- a/src/test/ui/for/for-c-in-str.rs
+++ b/src/test/ui/for/for-c-in-str.rs
@@ -5,7 +5,7 @@ fn main() {
//~^ ERROR `&str` is not an iterator
//~| NOTE `&str` is not an iterator
//~| HELP the trait `Iterator` is not implemented for `&str`
- //~| NOTE required because of the requirements on the impl of `IntoIterator` for `&str`
+ //~| NOTE required for `&str` to implement `IntoIterator`
//~| NOTE in this expansion of desugaring of `for` loop
//~| NOTE in this expansion of desugaring of `for` loop
//~| NOTE in this expansion of desugaring of `for` loop
diff --git a/src/test/ui/for/for-c-in-str.stderr b/src/test/ui/for/for-c-in-str.stderr
index 07ddc8ea7..959a7c43f 100644
--- a/src/test/ui/for/for-c-in-str.stderr
+++ b/src/test/ui/for/for-c-in-str.stderr
@@ -5,7 +5,7 @@ LL | for c in "asdf" {
| ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
|
= help: the trait `Iterator` is not implemented for `&str`
- = note: required because of the requirements on the impl of `IntoIterator` for `&str`
+ = note: required for `&str` to implement `IntoIterator`
error: aborting due to previous error
diff --git a/src/test/ui/for/for-loop-bogosity.stderr b/src/test/ui/for/for-loop-bogosity.stderr
index 0bdd75b35..9bf8056e8 100644
--- a/src/test/ui/for/for-loop-bogosity.stderr
+++ b/src/test/ui/for/for-loop-bogosity.stderr
@@ -5,7 +5,7 @@ LL | for x in bogus {
| ^^^^^ `MyStruct` is not an iterator
|
= help: the trait `Iterator` is not implemented for `MyStruct`
- = note: required because of the requirements on the impl of `IntoIterator` for `MyStruct`
+ = note: required for `MyStruct` to implement `IntoIterator`
error: aborting due to previous error
diff --git a/src/test/ui/functions-closures/fn-help-with-err.rs b/src/test/ui/functions-closures/fn-help-with-err.rs
index 3d2bcb8ad..49a514a8b 100644
--- a/src/test/ui/functions-closures/fn-help-with-err.rs
+++ b/src/test/ui/functions-closures/fn-help-with-err.rs
@@ -1,16 +1,28 @@
// This test case checks the behavior of typeck::check::method::suggest::is_fn on Ty::Error.
+
+struct Foo;
+
+trait Bar {
+ //~^ NOTE `Bar` defines an item `bar`, perhaps you need to implement it
+ //~| NOTE `Bar` defines an item `bar`, perhaps you need to implement it
+ fn bar(&self) {}
+}
+
+impl Bar for Foo {}
+
fn main() {
let arc = std::sync::Arc::new(oops);
//~^ ERROR cannot find value `oops` in this scope
//~| NOTE not found
- // The error "note: this is a function, perhaps you wish to call it" MUST NOT appear.
- arc.blablabla();
- //~^ ERROR no method named `blablabla`
+ arc.bar();
+ //~^ ERROR no method named `bar`
//~| NOTE method not found
- let arc2 = std::sync::Arc::new(|| 1);
- // The error "note: this is a function, perhaps you wish to call it" SHOULD appear
- arc2.blablabla();
- //~^ ERROR no method named `blablabla`
+ //~| HELP items from traits can only be used if the trait is implemented and in scope
+
+ let arc2 = std::sync::Arc::new(|| Foo);
+ arc2.bar();
+ //~^ ERROR no method named `bar`
//~| NOTE method not found
- //~| NOTE this is a function, perhaps you wish to call it
+ //~| HELP items from traits can only be used if the trait is implemented and in scope
+ //~| HELP use parentheses to call this closure
}
diff --git a/src/test/ui/functions-closures/fn-help-with-err.stderr b/src/test/ui/functions-closures/fn-help-with-err.stderr
index 06e29daef..229666621 100644
--- a/src/test/ui/functions-closures/fn-help-with-err.stderr
+++ b/src/test/ui/functions-closures/fn-help-with-err.stderr
@@ -1,22 +1,38 @@
error[E0425]: cannot find value `oops` in this scope
- --> $DIR/fn-help-with-err.rs:3:35
+ --> $DIR/fn-help-with-err.rs:14:35
|
LL | let arc = std::sync::Arc::new(oops);
| ^^^^ not found in this scope
-error[E0599]: no method named `blablabla` found for struct `Arc<_>` in the current scope
- --> $DIR/fn-help-with-err.rs:7:9
+error[E0599]: no method named `bar` found for struct `Arc<_>` in the current scope
+ --> $DIR/fn-help-with-err.rs:17:9
|
-LL | arc.blablabla();
- | ^^^^^^^^^ method not found in `Arc<_>`
+LL | arc.bar();
+ | ^^^ method not found in `Arc<_>`
+ |
+ = help: items from traits can only be used if the trait is implemented and in scope
+note: `Bar` defines an item `bar`, perhaps you need to implement it
+ --> $DIR/fn-help-with-err.rs:5:1
+ |
+LL | trait Bar {
+ | ^^^^^^^^^
-error[E0599]: no method named `blablabla` found for struct `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:38]>` in the current scope
- --> $DIR/fn-help-with-err.rs:12:10
+error[E0599]: no method named `bar` found for struct `Arc<[closure@$DIR/fn-help-with-err.rs:22:36: 22:38]>` in the current scope
+ --> $DIR/fn-help-with-err.rs:23:10
+ |
+LL | arc2.bar();
+ | ^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:22:36: 22:38]>`
+ |
+ = help: items from traits can only be used if the trait is implemented and in scope
+note: `Bar` defines an item `bar`, perhaps you need to implement it
+ --> $DIR/fn-help-with-err.rs:5:1
+ |
+LL | trait Bar {
+ | ^^^^^^^^^
+help: use parentheses to call this closure
|
-LL | arc2.blablabla();
- | ---- ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:38]>`
- | |
- | this is a function, perhaps you wish to call it
+LL | arc2().bar();
+ | ++
error: aborting due to 3 previous errors
diff --git a/src/test/ui/generator/clone-impl-async.rs b/src/test/ui/generator/clone-impl-async.rs
new file mode 100644
index 000000000..83c51526b
--- /dev/null
+++ b/src/test/ui/generator/clone-impl-async.rs
@@ -0,0 +1,71 @@
+// edition:2021
+// gate-test-generator_clone
+// Verifies that feature(generator_clone) doesn't allow async blocks to be cloned/copied.
+
+#![feature(generators, generator_clone)]
+
+use std::future::ready;
+
+struct NonClone;
+
+fn main() {
+ let inner_non_clone = async {
+ let non_clone = NonClone;
+ let () = ready(()).await;
+ drop(non_clone);
+ };
+ check_copy(&inner_non_clone);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ check_clone(&inner_non_clone);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+
+ let non_clone = NonClone;
+ let outer_non_clone = async move {
+ drop(non_clone);
+ };
+ check_copy(&outer_non_clone);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ check_clone(&outer_non_clone);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+
+ let maybe_copy_clone = async move {};
+ check_copy(&maybe_copy_clone);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ check_clone(&maybe_copy_clone);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+
+ let inner_non_clone_fn = the_inner_non_clone_fn();
+ check_copy(&inner_non_clone_fn);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ check_clone(&inner_non_clone_fn);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+
+ let outer_non_clone_fn = the_outer_non_clone_fn(NonClone);
+ check_copy(&outer_non_clone_fn);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ check_clone(&outer_non_clone_fn);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+
+ let maybe_copy_clone_fn = the_maybe_copy_clone_fn();
+ check_copy(&maybe_copy_clone_fn);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ check_clone(&maybe_copy_clone_fn);
+ //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+}
+
+async fn the_inner_non_clone_fn() {
+ let non_clone = NonClone;
+ let () = ready(()).await;
+ drop(non_clone);
+}
+
+async fn the_outer_non_clone_fn(non_clone: NonClone) {
+ let () = ready(()).await;
+ drop(non_clone);
+}
+
+async fn the_maybe_copy_clone_fn() {
+}
+
+fn check_copy<T: Copy>(_x: &T) {}
+fn check_clone<T: Clone>(_x: &T) {}
diff --git a/src/test/ui/generator/clone-impl-async.stderr b/src/test/ui/generator/clone-impl-async.stderr
new file mode 100644
index 000000000..cbb58d2af
--- /dev/null
+++ b/src/test/ui/generator/clone-impl-async.stderr
@@ -0,0 +1,171 @@
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ --> $DIR/clone-impl-async.rs:17:16
+ |
+LL | check_copy(&inner_non_clone);
+ | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-async.rs:70:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ --> $DIR/clone-impl-async.rs:19:17
+ |
+LL | check_clone(&inner_non_clone);
+ | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-async.rs:71:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ --> $DIR/clone-impl-async.rs:26:16
+ |
+LL | check_copy(&outer_non_clone);
+ | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-async.rs:70:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ --> $DIR/clone-impl-async.rs:28:17
+ |
+LL | check_clone(&outer_non_clone);
+ | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-async.rs:71:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ --> $DIR/clone-impl-async.rs:32:16
+ |
+LL | check_copy(&maybe_copy_clone);
+ | ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-async.rs:70:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ --> $DIR/clone-impl-async.rs:34:17
+ |
+LL | check_clone(&maybe_copy_clone);
+ | ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-async.rs:71:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ --> $DIR/clone-impl-async.rs:38:16
+ |
+LL | check_copy(&inner_non_clone_fn);
+ | ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-async.rs:70:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ --> $DIR/clone-impl-async.rs:40:17
+ |
+LL | check_clone(&inner_non_clone_fn);
+ | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-async.rs:71:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ --> $DIR/clone-impl-async.rs:44:16
+ |
+LL | check_copy(&outer_non_clone_fn);
+ | ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-async.rs:70:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ --> $DIR/clone-impl-async.rs:46:17
+ |
+LL | check_clone(&outer_non_clone_fn);
+ | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-async.rs:71:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ --> $DIR/clone-impl-async.rs:50:16
+ |
+LL | check_copy(&maybe_copy_clone_fn);
+ | ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-async.rs:70:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ --> $DIR/clone-impl-async.rs:52:17
+ |
+LL | check_clone(&maybe_copy_clone_fn);
+ | ----------- ^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-async.rs:71:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/clone-impl-static.rs b/src/test/ui/generator/clone-impl-static.rs
new file mode 100644
index 000000000..55ed0f281
--- /dev/null
+++ b/src/test/ui/generator/clone-impl-static.rs
@@ -0,0 +1,17 @@
+// gate-test-generator_clone
+// Verifies that static generators cannot be cloned/copied.
+
+#![feature(generators, generator_clone)]
+
+fn main() {
+ let gen = static move || {
+ yield;
+ };
+ check_copy(&gen);
+ //~^ ERROR Copy` is not satisfied
+ check_clone(&gen);
+ //~^ ERROR Clone` is not satisfied
+}
+
+fn check_copy<T: Copy>(_x: &T) {}
+fn check_clone<T: Clone>(_x: &T) {}
diff --git a/src/test/ui/generator/clone-impl-static.stderr b/src/test/ui/generator/clone-impl-static.stderr
new file mode 100644
index 000000000..cbadf6f15
--- /dev/null
+++ b/src/test/ui/generator/clone-impl-static.stderr
@@ -0,0 +1,31 @@
+error[E0277]: the trait bound `[static generator@$DIR/clone-impl-static.rs:7:15: 7:29]: Copy` is not satisfied
+ --> $DIR/clone-impl-static.rs:10:16
+ |
+LL | check_copy(&gen);
+ | ---------- ^^^^ the trait `Copy` is not implemented for `[static generator@$DIR/clone-impl-static.rs:7:15: 7:29]`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl-static.rs:16:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `[static generator@$DIR/clone-impl-static.rs:7:15: 7:29]: Clone` is not satisfied
+ --> $DIR/clone-impl-static.rs:12:17
+ |
+LL | check_clone(&gen);
+ | ----------- ^^^^ the trait `Clone` is not implemented for `[static generator@$DIR/clone-impl-static.rs:7:15: 7:29]`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl-static.rs:17:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/clone-impl.rs b/src/test/ui/generator/clone-impl.rs
new file mode 100644
index 000000000..cbfd65a53
--- /dev/null
+++ b/src/test/ui/generator/clone-impl.rs
@@ -0,0 +1,73 @@
+// gate-test-generator_clone
+// Verifies that non-static generators can be cloned/copied if all their upvars and locals held
+// across awaits can be cloned/copied.
+
+#![feature(generators, generator_clone)]
+
+struct NonClone;
+
+fn main() {
+ let copyable: u32 = 123;
+ let clonable_0: Vec<u32> = Vec::new();
+ let clonable_1: Vec<u32> = Vec::new();
+ let non_clonable: NonClone = NonClone;
+
+ let gen_copy_0 = move || {
+ yield;
+ drop(copyable);
+ };
+ check_copy(&gen_copy_0);
+ check_clone(&gen_copy_0);
+ let gen_copy_1 = move || {
+ /*
+ let v = vec!['a'];
+ let n = NonClone;
+ drop(v);
+ drop(n);
+ */
+ yield;
+ let v = vec!['a'];
+ let n = NonClone;
+ drop(n);
+ drop(copyable);
+ };
+ check_copy(&gen_copy_1);
+ check_clone(&gen_copy_1);
+ let gen_clone_0 = move || {
+ let v = vec!['a'];
+ yield;
+ drop(v);
+ drop(clonable_0);
+ };
+ check_copy(&gen_clone_0);
+ //~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
+ //~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
+ check_clone(&gen_clone_0);
+ let gen_clone_1 = move || {
+ let v = vec!['a'];
+ /*
+ let n = NonClone;
+ drop(n);
+ */
+ yield;
+ let n = NonClone;
+ drop(n);
+ drop(v);
+ drop(clonable_1);
+ };
+ check_copy(&gen_clone_1);
+ //~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
+ //~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
+ check_clone(&gen_clone_1);
+ let gen_non_clone = move || {
+ yield;
+ drop(non_clonable);
+ };
+ check_copy(&gen_non_clone);
+ //~^ ERROR the trait bound `NonClone: Copy` is not satisfied
+ check_clone(&gen_non_clone);
+ //~^ ERROR the trait bound `NonClone: Clone` is not satisfied
+}
+
+fn check_copy<T: Copy>(_x: &T) {}
+fn check_clone<T: Clone>(_x: &T) {}
diff --git a/src/test/ui/generator/clone-impl.stderr b/src/test/ui/generator/clone-impl.stderr
new file mode 100644
index 000000000..a92646b19
--- /dev/null
+++ b/src/test/ui/generator/clone-impl.stderr
@@ -0,0 +1,142 @@
+error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `[generator@$DIR/clone-impl.rs:36:23: 36:30]`
+ --> $DIR/clone-impl.rs:42:16
+ |
+LL | let gen_clone_0 = move || {
+ | ------- within this `[generator@$DIR/clone-impl.rs:36:23: 36:30]`
+...
+LL | check_copy(&gen_clone_0);
+ | ^^^^^^^^^^^^ within `[generator@$DIR/clone-impl.rs:36:23: 36:30]`, the trait `Copy` is not implemented for `Vec<u32>`
+ |
+note: captured value does not implement `Copy`
+ --> $DIR/clone-impl.rs:40:14
+ |
+LL | drop(clonable_0);
+ | ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl.rs:72:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `[generator@$DIR/clone-impl.rs:36:23: 36:30]`
+ --> $DIR/clone-impl.rs:42:16
+ |
+LL | let gen_clone_0 = move || {
+ | ------- within this `[generator@$DIR/clone-impl.rs:36:23: 36:30]`
+...
+LL | check_copy(&gen_clone_0);
+ | ^^^^^^^^^^^^ within `[generator@$DIR/clone-impl.rs:36:23: 36:30]`, the trait `Copy` is not implemented for `Vec<char>`
+ |
+note: generator does not implement `Copy` as this value is used across a yield
+ --> $DIR/clone-impl.rs:38:9
+ |
+LL | let v = vec!['a'];
+ | - has type `Vec<char>` which does not implement `Copy`
+LL | yield;
+ | ^^^^^ yield occurs here, with `v` maybe used later
+...
+LL | };
+ | - `v` is later dropped here
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl.rs:72:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `[generator@$DIR/clone-impl.rs:46:23: 46:30]`
+ --> $DIR/clone-impl.rs:58:16
+ |
+LL | let gen_clone_1 = move || {
+ | ------- within this `[generator@$DIR/clone-impl.rs:46:23: 46:30]`
+...
+LL | check_copy(&gen_clone_1);
+ | ^^^^^^^^^^^^ within `[generator@$DIR/clone-impl.rs:46:23: 46:30]`, the trait `Copy` is not implemented for `Vec<u32>`
+ |
+note: captured value does not implement `Copy`
+ --> $DIR/clone-impl.rs:56:14
+ |
+LL | drop(clonable_1);
+ | ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl.rs:72:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `[generator@$DIR/clone-impl.rs:46:23: 46:30]`
+ --> $DIR/clone-impl.rs:58:16
+ |
+LL | let gen_clone_1 = move || {
+ | ------- within this `[generator@$DIR/clone-impl.rs:46:23: 46:30]`
+...
+LL | check_copy(&gen_clone_1);
+ | ^^^^^^^^^^^^ within `[generator@$DIR/clone-impl.rs:46:23: 46:30]`, the trait `Copy` is not implemented for `Vec<char>`
+ |
+note: generator does not implement `Copy` as this value is used across a yield
+ --> $DIR/clone-impl.rs:52:9
+ |
+LL | let v = vec!['a'];
+ | - has type `Vec<char>` which does not implement `Copy`
+...
+LL | yield;
+ | ^^^^^ yield occurs here, with `v` maybe used later
+...
+LL | };
+ | - `v` is later dropped here
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl.rs:72:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+
+error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `[generator@$DIR/clone-impl.rs:62:25: 62:32]`
+ --> $DIR/clone-impl.rs:66:16
+ |
+LL | let gen_non_clone = move || {
+ | ------- within this `[generator@$DIR/clone-impl.rs:62:25: 62:32]`
+...
+LL | check_copy(&gen_non_clone);
+ | ^^^^^^^^^^^^^^ within `[generator@$DIR/clone-impl.rs:62:25: 62:32]`, the trait `Copy` is not implemented for `NonClone`
+ |
+note: captured value does not implement `Copy`
+ --> $DIR/clone-impl.rs:64:14
+ |
+LL | drop(non_clonable);
+ | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy`
+note: required by a bound in `check_copy`
+ --> $DIR/clone-impl.rs:72:18
+ |
+LL | fn check_copy<T: Copy>(_x: &T) {}
+ | ^^^^ required by this bound in `check_copy`
+help: consider annotating `NonClone` with `#[derive(Copy)]`
+ |
+LL | #[derive(Copy)]
+ |
+
+error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `[generator@$DIR/clone-impl.rs:62:25: 62:32]`
+ --> $DIR/clone-impl.rs:68:17
+ |
+LL | let gen_non_clone = move || {
+ | ------- within this `[generator@$DIR/clone-impl.rs:62:25: 62:32]`
+...
+LL | check_clone(&gen_non_clone);
+ | ^^^^^^^^^^^^^^ within `[generator@$DIR/clone-impl.rs:62:25: 62:32]`, the trait `Clone` is not implemented for `NonClone`
+ |
+note: captured value does not implement `Clone`
+ --> $DIR/clone-impl.rs:64:14
+ |
+LL | drop(non_clonable);
+ | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone`
+note: required by a bound in `check_clone`
+ --> $DIR/clone-impl.rs:73:19
+ |
+LL | fn check_clone<T: Clone>(_x: &T) {}
+ | ^^^^^ required by this bound in `check_clone`
+help: consider annotating `NonClone` with `#[derive(Clone)]`
+ |
+LL | #[derive(Clone)]
+ |
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/drop-tracking-parent-expression.stderr b/src/test/ui/generator/drop-tracking-parent-expression.stderr
index 522a300b3..fbf5d6e07 100644
--- a/src/test/ui/generator/drop-tracking-parent-expression.stderr
+++ b/src/test/ui/generator/drop-tracking-parent-expression.stderr
@@ -1,8 +1,8 @@
error: generator cannot be sent between threads safely
- --> $DIR/drop-tracking-parent-expression.rs:24:13
+ --> $DIR/drop-tracking-parent-expression.rs:24:25
|
LL | assert_send(g);
- | ^^^^^^^^^^^ generator is not `Send`
+ | ^ generator is not `Send`
...
LL | / type_combinations!(
LL | | // OK
@@ -41,10 +41,10 @@ LL | fn assert_send<T: Send>(_thing: T) {}
= note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generator cannot be sent between threads safely
- --> $DIR/drop-tracking-parent-expression.rs:24:13
+ --> $DIR/drop-tracking-parent-expression.rs:24:25
|
LL | assert_send(g);
- | ^^^^^^^^^^^ generator is not `Send`
+ | ^ generator is not `Send`
...
LL | / type_combinations!(
LL | | // OK
@@ -83,10 +83,10 @@ LL | fn assert_send<T: Send>(_thing: T) {}
= note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generator cannot be sent between threads safely
- --> $DIR/drop-tracking-parent-expression.rs:24:13
+ --> $DIR/drop-tracking-parent-expression.rs:24:25
|
LL | assert_send(g);
- | ^^^^^^^^^^^ generator is not `Send`
+ | ^ generator is not `Send`
...
LL | / type_combinations!(
LL | | // OK
diff --git a/src/test/ui/generator/drop-yield-twice.stderr b/src/test/ui/generator/drop-yield-twice.stderr
index 5bc6ea560..0808a2c85 100644
--- a/src/test/ui/generator/drop-yield-twice.stderr
+++ b/src/test/ui/generator/drop-yield-twice.stderr
@@ -1,8 +1,14 @@
error: generator cannot be sent between threads safely
- --> $DIR/drop-yield-twice.rs:7:5
+ --> $DIR/drop-yield-twice.rs:7:17
|
-LL | assert_send(|| {
- | ^^^^^^^^^^^ generator is not `Send`
+LL | assert_send(|| {
+ | _________________^
+LL | | let guard = Foo(42);
+LL | | yield;
+LL | | drop(guard);
+LL | | yield;
+LL | | })
+ | |_____^ generator is not `Send`
|
= help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield
diff --git a/src/test/ui/generator/generator-yielding-or-returning-itself.stderr b/src/test/ui/generator/generator-yielding-or-returning-itself.stderr
index 2a39a08ee..8f5d2429a 100644
--- a/src/test/ui/generator/generator-yielding-or-returning-itself.stderr
+++ b/src/test/ui/generator/generator-yielding-or-returning-itself.stderr
@@ -1,8 +1,15 @@
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36]`
- --> $DIR/generator-yielding-or-returning-itself.rs:15:5
+ --> $DIR/generator-yielding-or-returning-itself.rs:15:34
|
-LL | want_cyclic_generator_return(|| {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+LL | want_cyclic_generator_return(|| {
+ | _____----------------------------_^
+ | | |
+ | | required by a bound introduced by this call
+LL | |
+LL | | if false { yield None.unwrap(); }
+LL | | None.unwrap()
+LL | | })
+ | |_____^ cyclic type of infinite size
|
= note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix,
@@ -17,10 +24,17 @@ LL | where T: Generator<Yield = (), Return = T>
| ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return`
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35]`
- --> $DIR/generator-yielding-or-returning-itself.rs:28:5
+ --> $DIR/generator-yielding-or-returning-itself.rs:28:33
|
-LL | want_cyclic_generator_yield(|| {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+LL | want_cyclic_generator_yield(|| {
+ | _____---------------------------_^
+ | | |
+ | | required by a bound introduced by this call
+LL | |
+LL | | if false { yield None.unwrap(); }
+LL | | None.unwrap()
+LL | | })
+ | |_____^ cyclic type of infinite size
|
= note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix,
diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs
index 3fcef773b..21026f45c 100644
--- a/src/test/ui/generator/issue-68112.rs
+++ b/src/test/ui/generator/issue-68112.rs
@@ -63,7 +63,8 @@ fn test2() {
require_send(send_gen);
//~^ ERROR `RefCell<i32>` cannot be shared between threads safely
//~| NOTE `RefCell<i32>` cannot be shared between threads safely
- //~| NOTE requirements on the impl
+ //~| NOTE required for
+ //~| NOTE required by a bound introduced by this call
//~| NOTE captures the following types
}
diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr
index 1d5b97e98..eb99d42c9 100644
--- a/src/test/ui/generator/issue-68112.stderr
+++ b/src/test/ui/generator/issue-68112.stderr
@@ -1,8 +1,8 @@
error: generator cannot be sent between threads safely
- --> $DIR/issue-68112.rs:40:5
+ --> $DIR/issue-68112.rs:40:18
|
LL | require_send(send_gen);
- | ^^^^^^^^^^^^ generator is not `Send`
+ | ^^^^^^^^ generator is not `Send`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
note: generator is not `Send` as this value is used across a yield
@@ -23,13 +23,15 @@ LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error[E0277]: `RefCell<i32>` cannot be shared between threads safely
- --> $DIR/issue-68112.rs:63:5
+ --> $DIR/issue-68112.rs:63:18
|
LL | require_send(send_gen);
- | ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
- = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
+ = note: required for `Arc<RefCell<i32>>` to implement `Send`
note: required because it's used within this generator
--> $DIR/issue-68112.rs:48:5
|
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index 0b31bb4fd..a821c57b9 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -1,11 +1,18 @@
error[E0277]: `Cell<i32>` cannot be shared between threads safely
- --> $DIR/not-send-sync.rs:16:5
+ --> $DIR/not-send-sync.rs:16:17
|
-LL | assert_send(|| {
- | ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
+LL | assert_send(|| {
+ | _____-----------_^
+ | | |
+ | | required by a bound introduced by this call
+LL | |
+LL | | drop(&a);
+LL | | yield;
+LL | | });
+ | |_____^ `Cell<i32>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Cell<i32>`
- = note: required because of the requirements on the impl of `Send` for `&Cell<i32>`
+ = note: required for `&Cell<i32>` to implement `Send`
note: required because it's used within this generator
--> $DIR/not-send-sync.rs:16:17
|
@@ -18,10 +25,15 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send`
error: generator cannot be shared between threads safely
- --> $DIR/not-send-sync.rs:9:5
- |
-LL | assert_sync(|| {
- | ^^^^^^^^^^^ generator is not `Sync`
+ --> $DIR/not-send-sync.rs:9:17
+ |
+LL | assert_sync(|| {
+ | _________________^
+LL | |
+LL | | let a = Cell::new(2);
+LL | | yield;
+LL | | });
+ | |_____^ generator is not `Sync`
|
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell<i32>`
note: generator is not `Sync` as this value is used across a yield
diff --git a/src/test/ui/generator/partial-drop.stderr b/src/test/ui/generator/partial-drop.stderr
index 1004fc64d..9baafe54e 100644
--- a/src/test/ui/generator/partial-drop.stderr
+++ b/src/test/ui/generator/partial-drop.stderr
@@ -1,8 +1,15 @@
error: generator cannot be sent between threads safely
- --> $DIR/partial-drop.rs:14:5
+ --> $DIR/partial-drop.rs:14:17
|
-LL | assert_send(|| {
- | ^^^^^^^^^^^ generator is not `Send`
+LL | assert_send(|| {
+ | _________________^
+LL | |
+LL | | // FIXME: it would be nice to make this work.
+LL | | let guard = Bar { foo: Foo, x: 42 };
+LL | | drop(guard.foo);
+LL | | yield;
+LL | | });
+ | |_____^ generator is not `Send`
|
= help: within `[generator@$DIR/partial-drop.rs:14:17: 14:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield
@@ -22,10 +29,17 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send`
error: generator cannot be sent between threads safely
- --> $DIR/partial-drop.rs:22:5
+ --> $DIR/partial-drop.rs:22:17
|
-LL | assert_send(|| {
- | ^^^^^^^^^^^ generator is not `Send`
+LL | assert_send(|| {
+ | _________________^
+LL | |
+LL | | // FIXME: it would be nice to make this work.
+LL | | let guard = Bar { foo: Foo, x: 42 };
+... |
+LL | | yield;
+LL | | });
+ | |_____^ generator is not `Send`
|
= help: within `[generator@$DIR/partial-drop.rs:22:17: 22:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield
@@ -45,10 +59,17 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send`
error: generator cannot be sent between threads safely
- --> $DIR/partial-drop.rs:32:5
+ --> $DIR/partial-drop.rs:32:17
|
-LL | assert_send(|| {
- | ^^^^^^^^^^^ generator is not `Send`
+LL | assert_send(|| {
+ | _________________^
+LL | |
+LL | | // FIXME: it would be nice to make this work.
+LL | | let guard = Bar { foo: Foo, x: 42 };
+... |
+LL | | yield;
+LL | | });
+ | |_____^ generator is not `Send`
|
= help: within `[generator@$DIR/partial-drop.rs:32:17: 32:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield
diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr
index 5b61f1e8f..3a83021dd 100644
--- a/src/test/ui/generator/print/generator-print-verbose-1.stderr
+++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr
@@ -1,8 +1,8 @@
error: generator cannot be sent between threads safely
- --> $DIR/generator-print-verbose-1.rs:37:5
+ --> $DIR/generator-print-verbose-1.rs:37:18
|
LL | require_send(send_gen);
- | ^^^^^^^^^^^^ generator is not `Send`
+ | ^^^^^^^^ generator is not `Send`
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
note: generator is not `Send` as this value is used across a yield
@@ -21,13 +21,15 @@ LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send`
error[E0277]: `RefCell<i32>` cannot be shared between threads safely
- --> $DIR/generator-print-verbose-1.rs:56:5
+ --> $DIR/generator-print-verbose-1.rs:56:18
|
LL | require_send(send_gen);
- | ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
- = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
+ = note: required for `Arc<RefCell<i32>>` to implement `Send`
note: required because it's used within this generator
--> $DIR/generator-print-verbose-1.rs:42:5
|
diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr
index eb79d2e6e..909e49c38 100644
--- a/src/test/ui/generator/print/generator-print-verbose-2.stderr
+++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr
@@ -1,11 +1,18 @@
error[E0277]: `Cell<i32>` cannot be shared between threads safely
- --> $DIR/generator-print-verbose-2.rs:19:5
+ --> $DIR/generator-print-verbose-2.rs:19:17
|
-LL | assert_send(|| {
- | ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
+LL | assert_send(|| {
+ | _____-----------_^
+ | | |
+ | | required by a bound introduced by this call
+LL | |
+LL | | drop(&a);
+LL | | yield;
+LL | | });
+ | |_____^ `Cell<i32>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Cell<i32>`
- = note: required because of the requirements on the impl of `Send` for `&'_#4r Cell<i32>`
+ = note: required for `&'_#4r Cell<i32>` to implement `Send`
note: required because it's used within this generator
--> $DIR/generator-print-verbose-2.rs:19:17
|
@@ -18,10 +25,15 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send`
error: generator cannot be shared between threads safely
- --> $DIR/generator-print-verbose-2.rs:12:5
- |
-LL | assert_sync(|| {
- | ^^^^^^^^^^^ generator is not `Sync`
+ --> $DIR/generator-print-verbose-2.rs:12:17
+ |
+LL | assert_sync(|| {
+ | _________________^
+LL | |
+LL | | let a = Cell::new(2);
+LL | | yield;
+LL | | });
+ | |_____^ generator is not `Sync`
|
= help: within `[main::{closure#0} upvar_tys=() {Cell<i32>, ()}]`, the trait `Sync` is not implemented for `Cell<i32>`
note: generator is not `Sync` as this value is used across a yield
diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr
index 7938fc809..b98da1ed8 100644
--- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr
+++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr
@@ -11,6 +11,12 @@ note: return type inferred to be `Result<{integer}, _>` here
|
LL | return Ok(6);
| ^^^^^
+help: try wrapping the expression in a variant of `Result`
+ |
+LL | Ok(5)
+ | +++ +
+LL | Err(5)
+ | ++++ +
error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:7:5: 7:7] as Generator>::Return == i32`
--> $DIR/type-mismatch-signature-deduction.rs:5:13
diff --git a/src/test/ui/generator/yield-outside-generator-issue-78653.stderr b/src/test/ui/generator/yield-outside-generator-issue-78653.stderr
index ee1afbe5b..dcfb21174 100644
--- a/src/test/ui/generator/yield-outside-generator-issue-78653.stderr
+++ b/src/test/ui/generator/yield-outside-generator-issue-78653.stderr
@@ -12,7 +12,7 @@ LL | yield || for i in 0 { }
|
= help: the trait `Iterator` is not implemented for `{integer}`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
+ = note: required for `{integer}` to implement `IntoIterator`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/generic-associated-types/anonymize-bound-vars.rs b/src/test/ui/generic-associated-types/anonymize-bound-vars.rs
index 1ec9c6998..eb7a12412 100644
--- a/src/test/ui/generic-associated-types/anonymize-bound-vars.rs
+++ b/src/test/ui/generic-associated-types/anonymize-bound-vars.rs
@@ -1,7 +1,6 @@
// check-pass
//
// regression test for #98702
-#![feature(generic_associated_types)]
trait Foo {
type Assoc<T>;
diff --git a/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs b/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs
index 0e8e14852..21a9b3b89 100644
--- a/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs
+++ b/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
use std::{future::Future, pin::Pin};
pub trait Foo {
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.rs b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.rs
new file mode 100644
index 000000000..719d1bd5a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.rs
@@ -0,0 +1,35 @@
+// check-fail
+// known-bug
+
+// This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for
+// all 'a where I::Item<'a> is WF", but really means "for all 'a possible"
+
+use std::fmt::Debug;
+
+pub trait LendingIterator {
+ type Item<'this>
+ where
+ Self: 'this;
+}
+
+pub struct WindowsMut<'x> {
+ slice: &'x (),
+}
+
+impl<'y> LendingIterator for WindowsMut<'y> {
+ type Item<'this> = &'this mut () where 'y: 'this;
+}
+
+fn print_items<I>(_iter: I)
+where
+ I: LendingIterator,
+ for<'a> I::Item<'a>: Debug,
+{
+}
+
+fn main() {
+ let slice = &mut ();
+ //~^ temporary value dropped while borrowed
+ let windows = WindowsMut { slice };
+ print_items::<WindowsMut<'_>>(windows);
+}
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
new file mode 100644
index 000000000..414999881
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
@@ -0,0 +1,20 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/hrtb-implied-1.rs:31:22
+ |
+LL | let slice = &mut ();
+ | ^^ creates a temporary which is freed while still in use
+...
+LL | print_items::<WindowsMut<'_>>(windows);
+ | -------------------------------------- argument requires that borrow lasts for `'static`
+LL | }
+ | - temporary value is freed at the end of this statement
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/hrtb-implied-1.rs:26:26
+ |
+LL | for<'a> I::Item<'a>: Debug,
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-2.rs b/src/test/ui/generic-associated-types/bugs/hrtb-implied-2.rs
new file mode 100644
index 000000000..8e6c5348e
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-2.rs
@@ -0,0 +1,40 @@
+// check-fail
+// known-bug
+
+// This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for
+// all 'a where I::Item<'a> is WF", but really means "for all 'a possible"
+
+trait LendingIterator: Sized {
+ type Item<'a>
+ where
+ Self: 'a;
+ fn next(&mut self) -> Self::Item<'_>;
+}
+fn fails<I: LendingIterator, F>(iter: &mut I, f: F) -> bool
+where
+ F: FnMut(I::Item<'_>),
+{
+ let mut iter2 = Eat(iter, f);
+ let _next = iter2.next();
+ //~^ borrowed data escapes
+ true
+}
+impl<I: LendingIterator> LendingIterator for &mut I {
+ type Item<'a> = I::Item<'a> where Self:'a;
+ fn next(&mut self) -> Self::Item<'_> {
+ (**self).next()
+ }
+}
+
+struct Eat<I, F>(I, F);
+impl<I: LendingIterator, F> Iterator for Eat<I, F>
+where
+ F: FnMut(I::Item<'_>),
+{
+ type Item = ();
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-2.stderr b/src/test/ui/generic-associated-types/bugs/hrtb-implied-2.stderr
new file mode 100644
index 000000000..1ee270398
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-2.stderr
@@ -0,0 +1,22 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/hrtb-implied-2.rs:18:17
+ |
+LL | fn fails<I: LendingIterator, F>(iter: &mut I, f: F) -> bool
+ | ---- - let's call the lifetime of this reference `'1`
+ | |
+ | `iter` is a reference that is only valid in the function body
+...
+LL | let _next = iter2.next();
+ | ^^^^^^^^^^^^
+ | |
+ | `iter` escapes the function body here
+ | argument requires that `'1` must outlive `'static`
+ |
+ = note: requirement occurs because of a mutable reference to `Eat<&mut I, F>`
+ = note: mutable references are invariant over their type parameter
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+ = note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-3.rs b/src/test/ui/generic-associated-types/bugs/hrtb-implied-3.rs
new file mode 100644
index 000000000..bc9e6c8ae
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-3.rs
@@ -0,0 +1,23 @@
+trait LendingIterator {
+ type Item<'a>
+ where
+ Self: 'a;
+}
+
+impl LendingIterator for &str {
+ type Item<'a> = () where Self:'a;
+}
+
+fn trivial_bound<I>(_: I)
+where
+ I: LendingIterator,
+ for<'a> I::Item<'a>: Sized,
+{
+}
+
+fn fails(iter: &str) {
+ trivial_bound(iter);
+ //~^ borrowed data escapes
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-3.stderr b/src/test/ui/generic-associated-types/bugs/hrtb-implied-3.stderr
new file mode 100644
index 000000000..c67e02437
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-3.stderr
@@ -0,0 +1,22 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/hrtb-implied-3.rs:19:5
+ |
+LL | fn fails(iter: &str) {
+ | ---- - let's call the lifetime of this reference `'1`
+ | |
+ | `iter` is a reference that is only valid in the function body
+LL | trivial_bound(iter);
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | `iter` escapes the function body here
+ | argument requires that `'1` must outlive `'static`
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/hrtb-implied-3.rs:14:26
+ |
+LL | for<'a> I::Item<'a>: Sized,
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
index 14f27aff1..f6aa6b36e 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -3,8 +3,6 @@
// This should pass, but it requires `Sized` to be coinductive.
-#![feature(generic_associated_types)]
-
trait Allocator {
type Allocated<T>;
}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
index 487b83dfa..9a0f332ed 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
@@ -1,11 +1,11 @@
error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
- --> $DIR/issue-80626.rs:14:10
+ --> $DIR/issue-80626.rs:12:10
|
LL | Next(A::Allocated<Self>)
| ^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `Allocator::Allocated`
- --> $DIR/issue-80626.rs:9:20
+ --> $DIR/issue-80626.rs:7:20
|
LL | type Allocated<T>;
| ^ required by this bound in `Allocator::Allocated`
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.rs b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
index fb62c10a9..3a2d758e7 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-86218.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
@@ -3,7 +3,6 @@
// This should pass, but seems to run into a TAIT issue.
-#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
pub trait Stream {
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
index fbf1c8f95..de1b464a4 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
@@ -1,17 +1,17 @@
error[E0477]: the type `<() as Yay<&'a ()>>::InnerStream<'s>` does not fulfill the required lifetime
- --> $DIR/issue-86218.rs:23:28
+ --> $DIR/issue-86218.rs:22:28
|
LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must outlive the lifetime `'s` as defined here as required by this binding
- --> $DIR/issue-86218.rs:23:22
+ --> $DIR/issue-86218.rs:22:22
|
LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
| ^^
error: unconstrained opaque type
- --> $DIR/issue-86218.rs:23:28
+ --> $DIR/issue-86218.rs:22:28
|
LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.rs b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
index 0844d84c3..80737a798 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87735.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
@@ -3,8 +3,6 @@
// This should pass, but we need an extension of implied bounds (probably).
-#![feature(generic_associated_types)]
-
pub trait AsRef2 {
type Output<'a> where Self: 'a;
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.stderr b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
index 0a18b5f0c..ebe2054ce 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
@@ -1,5 +1,5 @@
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
- --> $DIR/issue-87735.rs:27:13
+ --> $DIR/issue-87735.rs:25:13
|
LL | impl<'b, T, U> AsRef2 for Foo<T>
| ^ unconstrained type parameter
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.rs b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
deleted file mode 100644
index a3d00ee03..000000000
--- a/src/test/ui/generic-associated-types/bugs/issue-87748.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// check-fail
-// known-bug: #87748
-
-// This should pass, but unnormalized input args aren't treated as implied.
-
-#![feature(generic_associated_types)]
-
-trait MyTrait {
- type Assoc<'a, 'b> where 'b: 'a;
- fn do_sth(arg: Self::Assoc<'_, '_>);
-}
-
-struct Foo;
-
-impl MyTrait for Foo {
- type Assoc<'a, 'b> = u32 where 'b: 'a;
-
- fn do_sth(_: u32) {}
- // fn do_sth(_: Self::Assoc<'static, 'static>) {}
- // fn do_sth(_: Self::Assoc<'_, '_>) {}
-}
-
-fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
deleted file mode 100644
index ac197dfe6..000000000
--- a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0478]: lifetime bound not satisfied
- --> $DIR/issue-87748.rs:18:5
- |
-LL | fn do_sth(_: u32) {}
- | ^^^^^^^^^^^^^^^^^
- |
-note: lifetime parameter instantiated with the anonymous lifetime as defined here
- --> $DIR/issue-87748.rs:18:5
- |
-LL | fn do_sth(_: u32) {}
- | ^^^^^^^^^^^^^^^^^
-note: but lifetime parameter must outlive the anonymous lifetime as defined here
- --> $DIR/issue-87748.rs:18:5
- |
-LL | fn do_sth(_: u32) {}
- | ^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
index efa487d62..cda722d2f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
@@ -3,8 +3,6 @@
// This should pass.
-#![feature(generic_associated_types)]
-
use std::fmt::Debug;
trait Foo {
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
index 5d1aff011..5e94db9b0 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
@@ -1,5 +1,5 @@
error[E0275]: overflow evaluating the requirement `<Bar as Foo>::Ass == _`
- --> $DIR/issue-87755.rs:18:16
+ --> $DIR/issue-87755.rs:16:16
|
LL | type Ass = Bar;
| ^^^
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.rs b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
index a8a111c99..56237e387 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87803.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
@@ -4,8 +4,6 @@
// This should pass, but using a type alias vs a reference directly
// changes late-bound -> early-bound.
-#![feature(generic_associated_types)]
-
trait Scanner {
type Input<'a>;
type Token<'a>;
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
index c81c051d3..fe2abdedb 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
@@ -1,5 +1,5 @@
error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration
- --> $DIR/issue-87803.rs:22:12
+ --> $DIR/issue-87803.rs:20:12
|
LL | fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>;
| ---- lifetimes in impl do not match this method in trait
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.rs b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
index 5493b9b93..8f8cc4523 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88382.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
@@ -3,8 +3,6 @@
// This should pass, but has a missed normalization due to HRTB.
-#![feature(generic_associated_types)]
-
trait Iterable {
type Iterator<'a> where Self: 'a;
fn iter(&self) -> Self::Iterator<'_>;
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
index 7210895b7..c5fd58096 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
@@ -1,5 +1,5 @@
error[E0631]: type mismatch in function arguments
- --> $DIR/issue-88382.rs:28:40
+ --> $DIR/issue-88382.rs:26:40
|
LL | do_something(SomeImplementation(), test);
| ------------ ^^^^ expected due to this
@@ -12,7 +12,7 @@ LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
= note: expected function signature `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
found function signature `for<'a, 'r> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _`
note: required by a bound in `do_something`
- --> $DIR/issue-88382.rs:22:48
+ --> $DIR/issue-88382.rs:20:48
|
LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.rs b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
index f1c3b2269..224e696ad 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88460.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
@@ -3,8 +3,6 @@
// This should pass, but has a missed normalization due to HRTB.
-#![feature(generic_associated_types)]
-
pub trait Marker {}
pub trait Trait {
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
index 98c304cc9..6612c4b49 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
@@ -1,12 +1,14 @@
error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
- --> $DIR/issue-88460.rs:30:5
+ --> $DIR/issue-88460.rs:28:10
|
LL | test(Foo);
- | ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
+ | ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Marker` is implemented for `()`
note: required by a bound in `test`
- --> $DIR/issue-88460.rs:17:27
+ --> $DIR/issue-88460.rs:15:27
|
LL | fn test<T>(value: T)
| ---- required by a bound in this
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.rs b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
index 15363ad04..99397744f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88526.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
@@ -3,8 +3,6 @@
// This should pass, but requires more logic.
-#![feature(generic_associated_types)]
-
trait A {
type I<'a>;
}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.stderr b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
index 127c889bf..56857c655 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
@@ -1,5 +1,5 @@
error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates
- --> $DIR/issue-88526.rs:27:13
+ --> $DIR/issue-88526.rs:25:13
|
LL | impl<'q, Q, I, F> A for TestB<Q, F>
| ^ unconstrained type parameter
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.rs b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
index 79c28b0d2..012aa8df2 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-89008.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
@@ -5,7 +5,6 @@
// This should pass, but seems to run into a TAIT bug.
#![feature(type_alias_impl_trait)]
-#![feature(generic_associated_types)]
use std::future::Future;
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
index 50844fdc1..3f72734ef 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
@@ -1,5 +1,5 @@
error[E0271]: type mismatch resolving `<Empty<_> as Stream>::Item == Repr`
- --> $DIR/issue-89008.rs:39:43
+ --> $DIR/issue-89008.rs:38:43
|
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Empty<_> as Stream>::Item == Repr`
@@ -7,7 +7,7 @@ LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
| this type parameter
|
note: expected this to be `()`
- --> $DIR/issue-89008.rs:18:17
+ --> $DIR/issue-89008.rs:17:17
|
LL | type Item = ();
| ^^
diff --git a/src/test/ui/generic-associated-types/issue-91762.rs b/src/test/ui/generic-associated-types/bugs/issue-91762.rs
index b259a3c6e..796935cc0 100644
--- a/src/test/ui/generic-associated-types/issue-91762.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-91762.rs
@@ -1,13 +1,12 @@
// check-fail
+// known-bug
-// FIXME(generic_associated_types): We almost certaintly want this to pass, but
+// We almost certaintly want this to pass, but
// it's particularly difficult currently, because we need a way of specifying
// that `<Self::Base as Functor>::With<T> = Self` without using that when we have
// a `U`. See `https://github.com/rust-lang/rust/pull/92728` for a (hacky)
// solution. This might be better to just wait for Chalk.
-#![feature(generic_associated_types)]
-
pub trait Functor {
type With<T>;
diff --git a/src/test/ui/generic-associated-types/issue-91762.stderr b/src/test/ui/generic-associated-types/bugs/issue-91762.stderr
index c2785fee3..1272c8b8a 100644
--- a/src/test/ui/generic-associated-types/issue-91762.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-91762.stderr
@@ -1,5 +1,5 @@
error[E0282]: type annotations needed
- --> $DIR/issue-91762.rs:25:15
+ --> $DIR/issue-91762.rs:24:15
|
LL | ret = <Self::Base as Functor>::fmap(arg);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `fmap`
diff --git a/src/test/ui/generic-associated-types/collections-project-default.rs b/src/test/ui/generic-associated-types/collections-project-default.rs
index 157e1b1d2..e08aa18cf 100644
--- a/src/test/ui/generic-associated-types/collections-project-default.rs
+++ b/src/test/ui/generic-associated-types/collections-project-default.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
// A Collection trait and collection families. Based on
diff --git a/src/test/ui/generic-associated-types/collections-project-default.stderr b/src/test/ui/generic-associated-types/collections-project-default.stderr
index 22fbc0271..5701017dc 100644
--- a/src/test/ui/generic-associated-types/collections-project-default.stderr
+++ b/src/test/ui/generic-associated-types/collections-project-default.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/collections-project-default.rs:59:5
+ --> $DIR/collections-project-default.rs:58:5
|
LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
| ------------------------------------ expected `<C as Collection<i32>>::Sibling<f32>` because of return type
diff --git a/src/test/ui/generic-associated-types/collections.rs b/src/test/ui/generic-associated-types/collections.rs
index 1c00aa73f..15f429afb 100644
--- a/src/test/ui/generic-associated-types/collections.rs
+++ b/src/test/ui/generic-associated-types/collections.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
// A Collection trait and collection families. Based on
diff --git a/src/test/ui/generic-associated-types/collectivity-regression.rs b/src/test/ui/generic-associated-types/collectivity-regression.rs
index fb7368439..54154f9d1 100644
--- a/src/test/ui/generic-associated-types/collectivity-regression.rs
+++ b/src/test/ui/generic-associated-types/collectivity-regression.rs
@@ -1,7 +1,5 @@
// Regression test from https://github.com/rust-lang/rust/pull/98109
-#![feature(generic_associated_types)]
-
pub trait Get {
type Value<'a>
where
diff --git a/src/test/ui/generic-associated-types/collectivity-regression.stderr b/src/test/ui/generic-associated-types/collectivity-regression.stderr
index a858dd7fd..1dbe1e2cb 100644
--- a/src/test/ui/generic-associated-types/collectivity-regression.stderr
+++ b/src/test/ui/generic-associated-types/collectivity-regression.stderr
@@ -1,5 +1,5 @@
error: `T` does not live long enough
- --> $DIR/collectivity-regression.rs:15:5
+ --> $DIR/collectivity-regression.rs:13:5
|
LL | / || {
LL | |
diff --git a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
index afde5f376..c5f9a25a6 100644
--- a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
+++ b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(generic_associated_types)]
// This test unsures that with_opt_const_param returns the
// def_id of the N param in the Foo::Assoc GAT.
diff --git a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
index 51046be79..cd7941ed9 100644
--- a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
+++ b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(generic_associated_types)]
// This test unsures that with_opt_const_param returns the
// def_id of the N param in the Foo::Assoc GAT.
diff --git a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
index 457fe27b3..db61fc080 100644
--- a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
+++ b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(generic_associated_types)]
// This test unsures that with_opt_const_param returns the
// def_id of the N param in the Bar::Assoc GAT.
diff --git a/src/test/ui/generic-associated-types/const_params_have_right_type.rs b/src/test/ui/generic-associated-types/const_params_have_right_type.rs
index 6bed8e3af..d2cb12697 100644
--- a/src/test/ui/generic-associated-types/const_params_have_right_type.rs
+++ b/src/test/ui/generic-associated-types/const_params_have_right_type.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Trait {
type Foo<const N: u8>;
}
diff --git a/src/test/ui/generic-associated-types/const_params_have_right_type.stderr b/src/test/ui/generic-associated-types/const_params_have_right_type.stderr
index 89c993dee..fdedd3bf5 100644
--- a/src/test/ui/generic-associated-types/const_params_have_right_type.stderr
+++ b/src/test/ui/generic-associated-types/const_params_have_right_type.stderr
@@ -1,5 +1,5 @@
error[E0053]: type `Foo` has an incompatible generic parameter for trait `Trait`
- --> $DIR/const_params_have_right_type.rs:8:14
+ --> $DIR/const_params_have_right_type.rs:6:14
|
LL | trait Trait {
| -----
diff --git a/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
index e315ee842..c78a54997 100644
--- a/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
+++ b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
@@ -1,7 +1,5 @@
// Test that correct syntax is used in suggestion to constrain associated type
-#![feature(generic_associated_types)]
-
trait X {
type Y<T>;
}
diff --git a/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
index 957ae5d29..96c4330fe 100644
--- a/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
+++ b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/constraint-assoc-type-suggestion.rs:12:23
+ --> $DIR/constraint-assoc-type-suggestion.rs:10:23
|
LL | let b: Vec<i32> = a;
| -------- ^ expected struct `Vec`, found associated type
diff --git a/src/test/ui/generic-associated-types/construct_with_other_type.rs b/src/test/ui/generic-associated-types/construct_with_other_type.rs
index 060804269..5cb07f558 100644
--- a/src/test/ui/generic-associated-types/construct_with_other_type.rs
+++ b/src/test/ui/generic-associated-types/construct_with_other_type.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// check-pass
use std::ops::Deref;
diff --git a/src/test/ui/generic-associated-types/cross-crate-bounds.stderr b/src/test/ui/generic-associated-types/cross-crate-bounds.stderr
index c4009dd96..c81cd7e77 100644
--- a/src/test/ui/generic-associated-types/cross-crate-bounds.stderr
+++ b/src/test/ui/generic-associated-types/cross-crate-bounds.stderr
@@ -5,7 +5,7 @@ LL | type Bar = ();
| ^^ the trait `AsRef<()>` is not implemented for `()`
|
note: required by a bound in `foo_defn::Foo::Bar`
- --> $DIR/auxiliary/foo_defn.rs:6:15
+ --> $DIR/auxiliary/foo_defn.rs:4:15
|
LL | type Bar: AsRef<()>;
| ^^^^^^^^^ required by this bound in `foo_defn::Foo::Bar`
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.rs b/src/test/ui/generic-associated-types/elided-in-expr-position.rs
index 482d0d5c0..e40093305 100644
--- a/src/test/ui/generic-associated-types/elided-in-expr-position.rs
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![allow(unused)]
pub trait Trait {
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
index b395a1cfd..20f35c3c1 100644
--- a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `Trait::Assoc`
- --> $DIR/elided-in-expr-position.rs:10:26
+ --> $DIR/elided-in-expr-position.rs:9:26
|
LL | fn g(&self) -> Self::Assoc;
| ^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/elided-in-expr-position.rs:5:10
+ --> $DIR/elided-in-expr-position.rs:4:10
|
LL | type Assoc<'a> where Self: 'a;
| ^^^^^ --
@@ -15,13 +15,13 @@ LL | fn g(&self) -> Self::Assoc<'a>;
| ~~~~~~~~~
error[E0107]: missing generics for associated type `Trait::Assoc`
- --> $DIR/elided-in-expr-position.rs:32:26
+ --> $DIR/elided-in-expr-position.rs:31:26
|
LL | fn g(&self) -> Self::Assoc {
| ^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/elided-in-expr-position.rs:5:10
+ --> $DIR/elided-in-expr-position.rs:4:10
|
LL | type Assoc<'a> where Self: 'a;
| ^^^^^ --
diff --git a/src/test/ui/generic-associated-types/empty_generics.rs b/src/test/ui/generic-associated-types/empty_generics.rs
index 772b7f2b4..964c2972d 100644
--- a/src/test/ui/generic-associated-types/empty_generics.rs
+++ b/src/test/ui/generic-associated-types/empty_generics.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Foo {
type Bar<,>;
//~^ ERROR expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
diff --git a/src/test/ui/generic-associated-types/empty_generics.stderr b/src/test/ui/generic-associated-types/empty_generics.stderr
index ac22bfc08..b753181cf 100644
--- a/src/test/ui/generic-associated-types/empty_generics.stderr
+++ b/src/test/ui/generic-associated-types/empty_generics.stderr
@@ -1,5 +1,5 @@
error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
- --> $DIR/empty_generics.rs:4:14
+ --> $DIR/empty_generics.rs:2:14
|
LL | trait Foo {
| - while parsing this item list starting here
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr
index 3da7794b3..614c4a34c 100644
--- a/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
- --> $DIR/lending_iterator.rs:14:45
+ --> $DIR/lending_iterator.rs:13:45
|
LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
| ------------------------------------------------------------------------ definition of `from_iter` from trait
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator.rs b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
index ede164766..247761dd0 100644
--- a/src/test/ui/generic-associated-types/extended/lending_iterator.rs
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
@@ -2,7 +2,6 @@
//[base] check-fail
//[extended] check-pass
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
index 6c2a624ca..f6b0b644e 100644
--- a/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
- --> $DIR/lending_iterator_2.rs:14:45
+ --> $DIR/lending_iterator_2.rs:13:45
|
LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
| ------------------------------------------------------------------------ definition of `from_iter` from trait
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
index 3c4a2184d..eb9c0456a 100644
--- a/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
@@ -2,7 +2,6 @@
//[base] check-fail
//[extended] check-pass
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs
deleted file mode 100644
index c1d68812e..000000000
--- a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is
-// missing the feature gate.
-
-struct Foo;
-
-trait MyTrait {
- type Item<T>;
- //~^ ERROR generic associated types are unstable [E0658]
-}
-
-impl MyTrait for Foo {
- type Item<T> = T;
- //~^ ERROR generic associated types are unstable [E0658]
-}
-
-fn main() { }
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr
deleted file mode 100644
index 34f536dbe..000000000
--- a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0658]: generic associated types are unstable
- --> $DIR/gat-dont-ice-on-absent-feature-2.rs:7:5
- |
-LL | type Item<T>;
- | ^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0658]: generic associated types are unstable
- --> $DIR/gat-dont-ice-on-absent-feature-2.rs:12:5
- |
-LL | type Item<T> = T;
- | ^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs
deleted file mode 100644
index e8fc47d2a..000000000
--- a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is
-// missing the feature gate.
-
-struct Foo;
-
-impl Iterator for Foo {
- type Item<'b> = &'b Foo;
- //~^ ERROR generic associated types are unstable [E0658]
- //~| ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-fn main() { }
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr
deleted file mode 100644
index ec36886f7..000000000
--- a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0658]: generic associated types are unstable
- --> $DIR/gat-dont-ice-on-absent-feature.rs:7:5
- |
-LL | type Item<'b> = &'b Foo;
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
- --> $DIR/gat-dont-ice-on-absent-feature.rs:7:14
- |
-LL | type Item<'b> = &'b Foo;
- | ^^^^ lifetimes do not match type in trait
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0195, E0658.
-For more information about an error, try `rustc --explain E0195`.
diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
index f542a7f54..86b164ba7 100644
--- a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'x>;
}
diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
index 1792d8db2..b77f10084 100644
--- a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
@@ -1,5 +1,5 @@
error[E0261]: use of undeclared lifetime name `'x`
- --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:8:35
+ --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:35
|
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
| ^^ undeclared lifetime
@@ -15,7 +15,7 @@ LL | fn _f<'x>(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
| ++++
error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types
- --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:8:33
+ --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33
|
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
| ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr
index c2054f64e..fd54faaf3 100644
--- a/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr
@@ -1,11 +1,11 @@
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/gat-in-trait-path.rs:27:17
+ --> $DIR/gat-in-trait-path.rs:26:17
|
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/gat-in-trait-path.rs:11:10
+ --> $DIR/gat-in-trait-path.rs:10:10
|
LL | trait Foo {
| --- this trait cannot be made into an object...
diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.rs b/src/test/ui/generic-associated-types/gat-in-trait-path.rs
index c82450ccf..c55f5a726 100644
--- a/src/test/ui/generic-associated-types/gat-in-trait-path.rs
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path.rs
@@ -2,7 +2,6 @@
//[base] check-fail
//[extended] check-pass
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/gat-incomplete-warning.rs b/src/test/ui/generic-associated-types/gat-incomplete-warning.rs
deleted file mode 100644
index 607ea1759..000000000
--- a/src/test/ui/generic-associated-types/gat-incomplete-warning.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// run-pass
-
-#![feature(generic_associated_types)]
-
-fn main() {}
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
index dbf7e02ae..d00c036fb 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
+++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Foo {
type F<'a>;
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr
index dad0dae6a..cb2b9f32b 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr
+++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr
@@ -1,5 +1,5 @@
error[E0403]: the name `T1` is already used for a generic parameter in this item's generic parameters
- --> $DIR/gat-trait-path-generic-type-arg.rs:11:12
+ --> $DIR/gat-trait-path-generic-type-arg.rs:9:12
|
LL | impl <T, T1> Foo for T {
| -- first use of `T1`
@@ -8,13 +8,13 @@ LL | type F<T1> = &[u8];
| ^^ already used
error[E0637]: `&` without an explicit lifetime name cannot be used here
- --> $DIR/gat-trait-path-generic-type-arg.rs:11:18
+ --> $DIR/gat-trait-path-generic-type-arg.rs:9:18
|
LL | type F<T1> = &[u8];
| ^ explicit lifetime name needed here
error[E0207]: the type parameter `T1` is not constrained by the impl trait, self type, or predicates
- --> $DIR/gat-trait-path-generic-type-arg.rs:9:10
+ --> $DIR/gat-trait-path-generic-type-arg.rs:7:10
|
LL | impl <T, T1> Foo for T {
| ^^ unconstrained type parameter
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
index 9864787f0..83b86f04a 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
+++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
index aeb9238de..452dfefd1 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
+++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `X::Y`
- --> $DIR/gat-trait-path-missing-lifetime.rs:10:20
+ --> $DIR/gat-trait-path-missing-lifetime.rs:8:20
|
LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/gat-trait-path-missing-lifetime.rs:4:8
+ --> $DIR/gat-trait-path-missing-lifetime.rs:2:8
|
LL | type Y<'a>;
| ^ --
@@ -15,13 +15,13 @@ LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
| ~~~~~
error[E0107]: missing generics for associated type `X::Y`
- --> $DIR/gat-trait-path-missing-lifetime.rs:10:20
+ --> $DIR/gat-trait-path-missing-lifetime.rs:8:20
|
LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/gat-trait-path-missing-lifetime.rs:4:8
+ --> $DIR/gat-trait-path-missing-lifetime.rs:2:8
|
LL | type Y<'a>;
| ^ --
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
index c55b0530c..9eb069637 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
+++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
}
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index 162214063..e55a21e19 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -1,11 +1,11 @@
error: lifetime in trait object type must be followed by `+`
- --> $DIR/gat-trait-path-parenthesised-args.rs:7:29
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:29
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^^
error: parenthesized generic arguments cannot be used in associated type constraints
- --> $DIR/gat-trait-path-parenthesised-args.rs:7:27
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^^^^^
@@ -16,7 +16,7 @@ LL | fn foo<'a>(arg: Box<dyn X<Y<'a> = &'a ()>>) {}
| ~ ~
error: parenthesized generic arguments cannot be used in associated type constraints
- --> $DIR/gat-trait-path-parenthesised-args.rs:14:27
+ --> $DIR/gat-trait-path-parenthesised-args.rs:12:27
|
LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
| ^--
@@ -24,13 +24,13 @@ LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
| help: remove these parentheses
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/gat-trait-path-parenthesised-args.rs:7:27
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/gat-trait-path-parenthesised-args.rs:4:8
+ --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
|
LL | type Y<'a>;
| ^ --
@@ -40,7 +40,7 @@ LL | fn foo<'a>(arg: Box<dyn X<Y('a, 'a) = &'a ()>>) {}
| +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
- --> $DIR/gat-trait-path-parenthesised-args.rs:7:27
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^---- help: remove these generics
@@ -48,19 +48,19 @@ LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| expected 0 generic arguments
|
note: associated type defined here, with 0 generic parameters
- --> $DIR/gat-trait-path-parenthesised-args.rs:4:8
+ --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
|
LL | type Y<'a>;
| ^
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/gat-trait-path-parenthesised-args.rs:14:27
+ --> $DIR/gat-trait-path-parenthesised-args.rs:12:27
|
LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/gat-trait-path-parenthesised-args.rs:4:8
+ --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
|
LL | type Y<'a>;
| ^ --
diff --git a/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs
index d7c4dbda2..fdc5a7267 100644
--- a/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs
+++ b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(generic_associated_types)]
-
pub trait X {
type Y<'a> where Self: 'a;
fn m(&self) -> Self::Y<'_>;
diff --git a/src/test/ui/generic-associated-types/generic-associated-types-where.rs b/src/test/ui/generic-associated-types/generic-associated-types-where.rs
index 2ecbc8c59..bbdfffafe 100644
--- a/src/test/ui/generic-associated-types/generic-associated-types-where.rs
+++ b/src/test/ui/generic-associated-types/generic-associated-types-where.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// Checking the interaction with this other feature
#![feature(associated_type_defaults)]
diff --git a/src/test/ui/generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
index e866b3bab..9a745c099 100644
--- a/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
+++ b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
@@ -1,5 +1,5 @@
error[E0277]: `T` doesn't implement `std::fmt::Display`
- --> $DIR/generic-associated-types-where.rs:20:22
+ --> $DIR/generic-associated-types-where.rs:18:22
|
LL | type Assoc2<T> = Vec<T>;
| ^^^^^^ `T` cannot be formatted with the default formatter
@@ -11,7 +11,7 @@ LL | type Assoc2<T: std::fmt::Display> = Vec<T>;
| +++++++++++++++++++
error[E0276]: impl has stricter requirements than trait
- --> $DIR/generic-associated-types-where.rs:22:38
+ --> $DIR/generic-associated-types-where.rs:20:38
|
LL | type Assoc3<T>;
| -------------- definition of `Assoc3` from trait
diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
index 43058f7eb..2cb218bf8 100644
--- a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
+++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
use std::ops::Deref;
trait Iterable {
diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
index a4bb36190..396ff15ab 100644
--- a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
+++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
@@ -1,5 +1,5 @@
error[E0261]: use of undeclared lifetime name `'b`
- --> $DIR/generic_associated_type_undeclared_lifetimes.rs:8:37
+ --> $DIR/generic_associated_type_undeclared_lifetimes.rs:6:37
|
LL | + Deref<Target = Self::Item<'b>>;
| ^^ undeclared lifetime
@@ -19,7 +19,7 @@ LL | trait Iterable<'b> {
| ++++
error[E0261]: use of undeclared lifetime name `'undeclared`
- --> $DIR/generic_associated_type_undeclared_lifetimes.rs:11:41
+ --> $DIR/generic_associated_type_undeclared_lifetimes.rs:9:41
|
LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
| ^^^^^^^^^^^ undeclared lifetime
diff --git a/src/test/ui/generic-associated-types/impl_bounds.rs b/src/test/ui/generic-associated-types/impl_bounds.rs
index ec1d171c0..01165fceb 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.rs
+++ b/src/test/ui/generic-associated-types/impl_bounds.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
trait Foo {
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index ce79c635a..442d4f336 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
- --> $DIR/impl_bounds.rs:15:39
+ --> $DIR/impl_bounds.rs:14:39
|
LL | type A<'a> where Self: 'a;
| ---------- definition of `A` from trait
@@ -8,7 +8,7 @@ LL | type A<'a> = (&'a ()) where Self: 'static;
| ^^^^^^^ impl has extra requirement `T: 'static`
error[E0276]: impl has stricter requirements than trait
- --> $DIR/impl_bounds.rs:17:48
+ --> $DIR/impl_bounds.rs:16:48
|
LL | type B<'a, 'b> where 'a: 'b;
| -------------- definition of `B` from trait
@@ -17,7 +17,7 @@ LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
| ^^ impl has extra requirement `'b: 'a`
error[E0478]: lifetime bound not satisfied
- --> $DIR/impl_bounds.rs:17:22
+ --> $DIR/impl_bounds.rs:16:22
|
LL | type B<'a, 'b> where 'a: 'b;
| -------------- definition of `B` from trait
@@ -26,29 +26,29 @@ LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
| ^^^^^^^^^^^^^^^ - help: try copying this clause from the trait: `, 'a: 'b`
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
- --> $DIR/impl_bounds.rs:17:12
+ --> $DIR/impl_bounds.rs:16:12
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
| ^^
note: but lifetime parameter must outlive the lifetime `'b` as defined here
- --> $DIR/impl_bounds.rs:17:16
+ --> $DIR/impl_bounds.rs:16:16
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
| ^^
error[E0277]: the trait bound `T: Copy` is not satisfied
- --> $DIR/impl_bounds.rs:20:33
+ --> $DIR/impl_bounds.rs:19:33
|
LL | type C = String where Self: Copy;
| ^^^^ the trait `Copy` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
- --> $DIR/impl_bounds.rs:11:10
+note: required for `Fooy<T>` to implement `Copy`
+ --> $DIR/impl_bounds.rs:10:10
|
LL | #[derive(Copy, Clone)]
| ^^^^
note: the requirement `Fooy<T>: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type
- --> $DIR/impl_bounds.rs:7:10
+ --> $DIR/impl_bounds.rs:6:10
|
LL | trait Foo {
| --- in this trait
@@ -62,18 +62,18 @@ LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
| +++++++++++++++++++
error[E0277]: the trait bound `T: Copy` is not satisfied
- --> $DIR/impl_bounds.rs:22:24
+ --> $DIR/impl_bounds.rs:21:24
|
LL | fn d() where Self: Copy {}
| ^^^^ the trait `Copy` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
- --> $DIR/impl_bounds.rs:11:10
+note: required for `Fooy<T>` to implement `Copy`
+ --> $DIR/impl_bounds.rs:10:10
|
LL | #[derive(Copy, Clone)]
| ^^^^
note: the requirement `Fooy<T>: Copy` appears on the `impl`'s method `d` but not on the corresponding trait's method
- --> $DIR/impl_bounds.rs:8:8
+ --> $DIR/impl_bounds.rs:7:8
|
LL | trait Foo {
| --- in this trait
diff --git a/src/test/ui/generic-associated-types/impl_bounds_ok.rs b/src/test/ui/generic-associated-types/impl_bounds_ok.rs
index 4df8235d9..88f829ea2 100644
--- a/src/test/ui/generic-associated-types/impl_bounds_ok.rs
+++ b/src/test/ui/generic-associated-types/impl_bounds_ok.rs
@@ -1,6 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
trait Foo {
diff --git a/src/test/ui/generic-associated-types/issue-101020.rs b/src/test/ui/generic-associated-types/issue-101020.rs
new file mode 100644
index 000000000..80d0fa5ad
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-101020.rs
@@ -0,0 +1,35 @@
+pub trait LendingIterator {
+ type Item<'a>
+ where
+ Self: 'a;
+
+ fn consume<F>(self, _f: F)
+ where
+ Self: Sized,
+ for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
+ {
+ }
+}
+
+impl<I: LendingIterator + ?Sized> LendingIterator for &mut I {
+ type Item<'a> = I::Item<'a> where Self: 'a;
+}
+struct EmptyIter;
+impl LendingIterator for EmptyIter {
+ type Item<'a> = &'a mut () where Self:'a;
+}
+pub trait FuncInput<'a, F>
+where
+ F: Foo<Self>,
+ Self: Sized,
+{
+}
+impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo<T> {}
+trait Foo<T> {}
+
+fn map_test() {
+ (&mut EmptyIter).consume(());
+ //~^ ERROR the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-101020.stderr b/src/test/ui/generic-associated-types/issue-101020.stderr
new file mode 100644
index 000000000..b4e94cb83
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-101020.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
+ --> $DIR/issue-101020.rs:31:5
+ |
+LL | (&mut EmptyIter).consume(());
+ | ^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
+ |
+note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>`
+ --> $DIR/issue-101020.rs:27:20
+ |
+LL | impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo<T> {}
+ | ^^^^^^^^^^^^^^^^ ^
+note: required by a bound in `LendingIterator::consume`
+ --> $DIR/issue-101020.rs:9:33
+ |
+LL | fn consume<F>(self, _f: F)
+ | ------- required by a bound in this
+...
+LL | for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `LendingIterator::consume`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generic-associated-types/issue-102333.rs b/src/test/ui/generic-associated-types/issue-102333.rs
new file mode 100644
index 000000000..6c7256332
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102333.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+trait A {
+ type T: B<U<1i32> = ()>;
+}
+
+trait B {
+ type U<const C: i32>;
+}
+
+fn f<T: A>() {
+ let _: <<T as A>::T as B>::U<1i32> = ();
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-102335-gat.rs b/src/test/ui/generic-associated-types/issue-102335-gat.rs
new file mode 100644
index 000000000..a7255fdcb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102335-gat.rs
@@ -0,0 +1,12 @@
+trait T {
+ type A: S<C<(), i32 = ()> = ()>;
+ //~^ ERROR associated type bindings are not allowed here
+}
+
+trait Q {}
+
+trait S {
+ type C<T>: Q;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-102335-gat.stderr b/src/test/ui/generic-associated-types/issue-102335-gat.stderr
new file mode 100644
index 000000000..7a7900a1e
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102335-gat.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-102335-gat.rs:2:21
+ |
+LL | type A: S<C<(), i32 = ()> = ()>;
+ | ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/generic-associated-types/issue-47206-where-clause.rs b/src/test/ui/generic-associated-types/issue-47206-where-clause.rs
index d352c1948..3d1b88ddf 100644
--- a/src/test/ui/generic-associated-types/issue-47206-where-clause.rs
+++ b/src/test/ui/generic-associated-types/issue-47206-where-clause.rs
@@ -1,7 +1,5 @@
// Check that this program doesn't cause the compiler to error without output.
-#![feature(generic_associated_types)]
-
trait Foo {
type Assoc3<T>;
}
diff --git a/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr b/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr
index 31948a878..7006744df 100644
--- a/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr
+++ b/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
- --> $DIR/issue-47206-where-clause.rs:12:38
+ --> $DIR/issue-47206-where-clause.rs:10:38
|
LL | type Assoc3<T>;
| -------------- definition of `Assoc3` from trait
diff --git a/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
index e87a76825..625ccfe89 100644
--- a/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
+++ b/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Cert {
type PublicKey<'a>: From<&'a [u8]>;
}
diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
index d74d6d056..c1140bff8 100644
--- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
+++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// check-pass
trait Iterator {
diff --git a/src/test/ui/generic-associated-types/issue-67424.rs b/src/test/ui/generic-associated-types/issue-67424.rs
index fa35a3e8b..b6c7c70cd 100644
--- a/src/test/ui/generic-associated-types/issue-67424.rs
+++ b/src/test/ui/generic-associated-types/issue-67424.rs
@@ -1,3 +1,4 @@
+// check-pass
// Fixed by #67160
trait Trait1 {
@@ -6,7 +7,6 @@ trait Trait1 {
trait Trait2 {
type Type1<B>: Trait1<A=B>;
- //~^ ERROR: generic associated types are unstable
}
fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-67424.stderr b/src/test/ui/generic-associated-types/issue-67424.stderr
deleted file mode 100644
index bbb7d56f5..000000000
--- a/src/test/ui/generic-associated-types/issue-67424.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: generic associated types are unstable
- --> $DIR/issue-67424.rs:8:5
- |
-LL | type Type1<B>: Trait1<A=B>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
- = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr
index 74a616aaa..4cc68530e 100644
--- a/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr
+++ b/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr
@@ -1,11 +1,11 @@
error[E0038]: the trait `X` cannot be made into an object
- --> $DIR/issue-67510-pass.rs:13:23
+ --> $DIR/issue-67510-pass.rs:12:23
|
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-67510-pass.rs:10:10
+ --> $DIR/issue-67510-pass.rs:9:10
|
LL | trait X {
| - this trait cannot be made into an object...
diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.rs b/src/test/ui/generic-associated-types/issue-67510-pass.rs
index c5b02ff9a..66ce3e807 100644
--- a/src/test/ui/generic-associated-types/issue-67510-pass.rs
+++ b/src/test/ui/generic-associated-types/issue-67510-pass.rs
@@ -2,7 +2,6 @@
//[base] check-fail
//[extended] check-pass
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/issue-67510.rs b/src/test/ui/generic-associated-types/issue-67510.rs
index 5725b660a..ab5c25d74 100644
--- a/src/test/ui/generic-associated-types/issue-67510.rs
+++ b/src/test/ui/generic-associated-types/issue-67510.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
}
diff --git a/src/test/ui/generic-associated-types/issue-67510.stderr b/src/test/ui/generic-associated-types/issue-67510.stderr
index 8aeda22ba..d25c5b0f3 100644
--- a/src/test/ui/generic-associated-types/issue-67510.stderr
+++ b/src/test/ui/generic-associated-types/issue-67510.stderr
@@ -1,5 +1,5 @@
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/issue-67510.rs:7:21
+ --> $DIR/issue-67510.rs:5:21
|
LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
| ^^ undeclared lifetime
@@ -15,7 +15,7 @@ LL | fn f<'a>(x: Box<dyn X<Y<'a> = &'a ()>>) {}
| ++++
error[E0261]: use of undeclared lifetime name `'a`
- --> $DIR/issue-67510.rs:7:28
+ --> $DIR/issue-67510.rs:5:28
|
LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
| ^^ undeclared lifetime
@@ -30,13 +30,13 @@ LL | fn f<'a>(x: Box<dyn X<Y<'a> = &'a ()>>) {}
| ++++
error[E0038]: the trait `X` cannot be made into an object
- --> $DIR/issue-67510.rs:7:13
+ --> $DIR/issue-67510.rs:5:13
|
LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-67510.rs:4:10
+ --> $DIR/issue-67510.rs:2:10
|
LL | trait X {
| - this trait cannot be made into an object...
diff --git a/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
index 617d985dc..f1e779fcb 100644
--- a/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
+++ b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
@@ -1,7 +1,5 @@
// Regression test for #68641
-#![feature(generic_associated_types)]
-
trait UnsafeCopy {
type Item<'a>: Copy;
diff --git a/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr
index 2e21b38cb..6bb7492af 100644
--- a/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr
+++ b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `T: Copy` is not satisfied
- --> $DIR/issue-68641-check-gat-bounds.rs:14:21
+ --> $DIR/issue-68641-check-gat-bounds.rs:12:21
|
LL | type Item<'a> = T;
| ^ the trait `Copy` is not implemented for `T`
|
note: required by a bound in `UnsafeCopy::Item`
- --> $DIR/issue-68641-check-gat-bounds.rs:6:20
+ --> $DIR/issue-68641-check-gat-bounds.rs:4:20
|
LL | type Item<'a>: Copy;
| ^^^^ required by this bound in `UnsafeCopy::Item`
diff --git a/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
index def0ad18f..f5502adee 100644
--- a/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
+++ b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
@@ -1,7 +1,5 @@
// Regression test for #68642
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>: Fn() -> u32;
diff --git a/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr
index 713cc744f..07452137b 100644
--- a/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr
+++ b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr
@@ -1,12 +1,12 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
- --> $DIR/issue-68642-broken-llvm-ir.rs:14:18
+ --> $DIR/issue-68642-broken-llvm-ir.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
- --> $DIR/issue-68642-broken-llvm-ir.rs:6:17
+ --> $DIR/issue-68642-broken-llvm-ir.rs:4:17
|
LL | type F<'a>: Fn() -> u32;
| ^^^^^^^^^^^ required by this bound in `Fun::F`
diff --git a/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs b/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs
index 9af065b5d..6050a8bf5 100644
--- a/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs
+++ b/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs
@@ -1,7 +1,5 @@
// Regression test for #68643
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>: Fn() -> u32;
diff --git a/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr b/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr
index a7b7f64cd..31ded5dab 100644
--- a/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr
+++ b/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr
@@ -1,12 +1,12 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
- --> $DIR/issue-68643-broken-mir.rs:14:18
+ --> $DIR/issue-68643-broken-mir.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
- --> $DIR/issue-68643-broken-mir.rs:6:17
+ --> $DIR/issue-68643-broken-mir.rs:4:17
|
LL | type F<'a>: Fn() -> u32;
| ^^^^^^^^^^^ required by this bound in `Fun::F`
diff --git a/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs
index 1d2636c26..898cfa1e7 100644
--- a/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs
+++ b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs
@@ -1,7 +1,5 @@
// Regression test for #68644
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>: Fn() -> u32;
diff --git a/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr
index 5e921e053..e2f9930cc 100644
--- a/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr
+++ b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr
@@ -1,12 +1,12 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
- --> $DIR/issue-68644-codegen-selection.rs:14:18
+ --> $DIR/issue-68644-codegen-selection.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
- --> $DIR/issue-68644-codegen-selection.rs:6:17
+ --> $DIR/issue-68644-codegen-selection.rs:4:17
|
LL | type F<'a>: Fn() -> u32;
| ^^^^^^^^^^^ required by this bound in `Fun::F`
diff --git a/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
index aa505064f..60b065bfc 100644
--- a/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
+++ b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
@@ -1,7 +1,5 @@
// Regression test for #68645
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>: Fn() -> u32;
diff --git a/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr
index 7edcdce62..0065368ad 100644
--- a/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr
+++ b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr
@@ -1,12 +1,12 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
- --> $DIR/issue-68645-codegen-fulfillment.rs:14:18
+ --> $DIR/issue-68645-codegen-fulfillment.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
- --> $DIR/issue-68645-codegen-fulfillment.rs:6:17
+ --> $DIR/issue-68645-codegen-fulfillment.rs:4:17
|
LL | type F<'a>: Fn() -> u32;
| ^^^^^^^^^^^ required by this bound in `Fun::F`
diff --git a/src/test/ui/generic-associated-types/issue-68648-1.rs b/src/test/ui/generic-associated-types/issue-68648-1.rs
index 17bc034b3..0df41bab3 100644
--- a/src/test/ui/generic-associated-types/issue-68648-1.rs
+++ b/src/test/ui/generic-associated-types/issue-68648-1.rs
@@ -1,8 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
-
trait Fun {
type F<'a>;
diff --git a/src/test/ui/generic-associated-types/issue-68648-2.rs b/src/test/ui/generic-associated-types/issue-68648-2.rs
index 6c9a0d126..0f963d58f 100644
--- a/src/test/ui/generic-associated-types/issue-68648-2.rs
+++ b/src/test/ui/generic-associated-types/issue-68648-2.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>;
diff --git a/src/test/ui/generic-associated-types/issue-68648-2.stderr b/src/test/ui/generic-associated-types/issue-68648-2.stderr
index 06c1efcd8..b2bef19eb 100644
--- a/src/test/ui/generic-associated-types/issue-68648-2.stderr
+++ b/src/test/ui/generic-associated-types/issue-68648-2.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/issue-68648-2.rs:14:17
+ --> $DIR/issue-68648-2.rs:12:17
|
LL | fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
| - this type parameter
@@ -11,7 +11,7 @@ LL | T::identity(())
= note: expected type parameter `T`
found unit type `()`
note: associated function defined here
- --> $DIR/issue-68648-2.rs:6:8
+ --> $DIR/issue-68648-2.rs:4:8
|
LL | fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
| ^^^^^^^^ --------------
diff --git a/src/test/ui/generic-associated-types/issue-68649-pass.rs b/src/test/ui/generic-associated-types/issue-68649-pass.rs
index 33f08faff..772743877 100644
--- a/src/test/ui/generic-associated-types/issue-68649-pass.rs
+++ b/src/test/ui/generic-associated-types/issue-68649-pass.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>;
diff --git a/src/test/ui/generic-associated-types/issue-68653.rs b/src/test/ui/generic-associated-types/issue-68653.rs
index 1e84717e9..170b87cf2 100644
--- a/src/test/ui/generic-associated-types/issue-68653.rs
+++ b/src/test/ui/generic-associated-types/issue-68653.rs
@@ -2,8 +2,6 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a: 'a>;
}
diff --git a/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs b/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs
index c0d933362..607cfed0b 100644
--- a/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs
+++ b/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs
@@ -1,7 +1,5 @@
// Regression test for #68656
-#![feature(generic_associated_types)]
-
trait UnsafeCopy<T: Copy> {
type Item<'a>: std::ops::Deref<Target = T>;
diff --git a/src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr b/src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr
index 8e0f23716..e8770aedf 100644
--- a/src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr
+++ b/src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr
@@ -1,5 +1,5 @@
error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
- --> $DIR/issue-68656-unsized-values.rs:15:21
+ --> $DIR/issue-68656-unsized-values.rs:13:21
|
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<T> for T {
| - this type parameter
@@ -9,7 +9,7 @@ LL | type Item<'a> = T;
= note: expected type parameter `T`
found associated type `<T as Deref>::Target`
note: required by a bound in `UnsafeCopy::Item`
- --> $DIR/issue-68656-unsized-values.rs:6:36
+ --> $DIR/issue-68656-unsized-values.rs:4:36
|
LL | type Item<'a>: std::ops::Deref<Target = T>;
| ^^^^^^^^^^ required by this bound in `UnsafeCopy::Item`
diff --git a/src/test/ui/generic-associated-types/issue-70303.rs b/src/test/ui/generic-associated-types/issue-70303.rs
index 568996e1a..0edff5e4e 100644
--- a/src/test/ui/generic-associated-types/issue-70303.rs
+++ b/src/test/ui/generic-associated-types/issue-70303.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Document {
type Cursor<'a>: DocCursor<'a> where Self: 'a;
diff --git a/src/test/ui/generic-associated-types/issue-70304.rs b/src/test/ui/generic-associated-types/issue-70304.rs
index f778f985c..8898d4c7d 100644
--- a/src/test/ui/generic-associated-types/issue-70304.rs
+++ b/src/test/ui/generic-associated-types/issue-70304.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Document {
type Cursor<'a>: DocCursor<'a>;
//~^ ERROR: missing required bound on `Cursor`
diff --git a/src/test/ui/generic-associated-types/issue-70304.stderr b/src/test/ui/generic-associated-types/issue-70304.stderr
index bba7cab70..99339e968 100644
--- a/src/test/ui/generic-associated-types/issue-70304.stderr
+++ b/src/test/ui/generic-associated-types/issue-70304.stderr
@@ -1,11 +1,11 @@
error[E0637]: `'_` cannot be used here
- --> $DIR/issue-70304.rs:48:41
+ --> $DIR/issue-70304.rs:46:41
|
LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
| ^^ `'_` is a reserved lifetime name
error[E0106]: missing lifetime specifier
- --> $DIR/issue-70304.rs:48:61
+ --> $DIR/issue-70304.rs:46:61
|
LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
| ^^ expected named lifetime parameter
@@ -17,7 +17,7 @@ LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'static>> {
| ~~~~~~~
error: missing required bound on `Cursor`
- --> $DIR/issue-70304.rs:4:5
+ --> $DIR/issue-70304.rs:2:5
|
LL | type Cursor<'a>: DocCursor<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
diff --git a/src/test/ui/generic-associated-types/issue-71176.rs b/src/test/ui/generic-associated-types/issue-71176.rs
index c2f0d59f4..f0e162d82 100644
--- a/src/test/ui/generic-associated-types/issue-71176.rs
+++ b/src/test/ui/generic-associated-types/issue-71176.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Provider {
type A<'a>;
}
diff --git a/src/test/ui/generic-associated-types/issue-71176.stderr b/src/test/ui/generic-associated-types/issue-71176.stderr
index 08c8d4162..386c97161 100644
--- a/src/test/ui/generic-associated-types/issue-71176.stderr
+++ b/src/test/ui/generic-associated-types/issue-71176.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `Provider::A`
- --> $DIR/issue-71176.rs:12:27
+ --> $DIR/issue-71176.rs:10:27
|
LL | inner: Box<dyn Provider<A = B>>,
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-71176.rs:4:10
+ --> $DIR/issue-71176.rs:2:10
|
LL | type A<'a>;
| ^ --
diff --git a/src/test/ui/generic-associated-types/issue-74684-1.rs b/src/test/ui/generic-associated-types/issue-74684-1.rs
index 0e3899a88..e9ec80074 100644
--- a/src/test/ui/generic-associated-types/issue-74684-1.rs
+++ b/src/test/ui/generic-associated-types/issue-74684-1.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>: ?Sized;
diff --git a/src/test/ui/generic-associated-types/issue-74684-1.stderr b/src/test/ui/generic-associated-types/issue-74684-1.stderr
index 2cd050ed8..cacc97307 100644
--- a/src/test/ui/generic-associated-types/issue-74684-1.stderr
+++ b/src/test/ui/generic-associated-types/issue-74684-1.stderr
@@ -1,5 +1,5 @@
error[E0597]: `a` does not live long enough
- --> $DIR/issue-74684-1.rs:15:26
+ --> $DIR/issue-74684-1.rs:13:26
|
LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(_ : Box<T>) -> &'static T::F<'a> {
| -- lifetime `'a` defined here
diff --git a/src/test/ui/generic-associated-types/issue-74684-2.rs b/src/test/ui/generic-associated-types/issue-74684-2.rs
index fca55070b..ff243af2c 100644
--- a/src/test/ui/generic-associated-types/issue-74684-2.rs
+++ b/src/test/ui/generic-associated-types/issue-74684-2.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Fun {
type F<'a>: ?Sized;
diff --git a/src/test/ui/generic-associated-types/issue-74684-2.stderr b/src/test/ui/generic-associated-types/issue-74684-2.stderr
index f0e03e73f..59b85abf5 100644
--- a/src/test/ui/generic-associated-types/issue-74684-2.stderr
+++ b/src/test/ui/generic-associated-types/issue-74684-2.stderr
@@ -1,16 +1,18 @@
error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
- --> $DIR/issue-74684-2.rs:23:5
+ --> $DIR/issue-74684-2.rs:21:9
|
LL | bug(Box::new(x));
- | ^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ | --- ^^^^^^^^^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `[u8]`
- --> $DIR/issue-74684-2.rs:10:18
+ --> $DIR/issue-74684-2.rs:8:18
|
LL | type F<'a> = i32;
| ^^^
note: required by a bound in `bug`
- --> $DIR/issue-74684-2.rs:13:28
+ --> $DIR/issue-74684-2.rs:11:28
|
LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
| ^^^^^^^^^^^^ required by this bound in `bug`
diff --git a/src/test/ui/generic-associated-types/issue-74816.rs b/src/test/ui/generic-associated-types/issue-74816.rs
index c932025d1..344afb87f 100644
--- a/src/test/ui/generic-associated-types/issue-74816.rs
+++ b/src/test/ui/generic-associated-types/issue-74816.rs
@@ -1,5 +1,4 @@
#![feature(associated_type_defaults)]
-#![feature(generic_associated_types)]
trait Trait1 {
fn foo();
diff --git a/src/test/ui/generic-associated-types/issue-74816.stderr b/src/test/ui/generic-associated-types/issue-74816.stderr
index 9eaa74e34..45018e697 100644
--- a/src/test/ui/generic-associated-types/issue-74816.stderr
+++ b/src/test/ui/generic-associated-types/issue-74816.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `Self: Trait1` is not satisfied
- --> $DIR/issue-74816.rs:9:31
+ --> $DIR/issue-74816.rs:8:31
|
LL | type Associated: Trait1 = Self;
| ^^^^ the trait `Trait1` is not implemented for `Self`
|
note: required by a bound in `Trait2::Associated`
- --> $DIR/issue-74816.rs:9:22
+ --> $DIR/issue-74816.rs:8:22
|
LL | type Associated: Trait1 = Self;
| ^^^^^^ required by this bound in `Trait2::Associated`
@@ -15,13 +15,13 @@ LL | trait Trait2: Trait1 {
| ++++++++
error[E0277]: the size for values of type `Self` cannot be known at compilation time
- --> $DIR/issue-74816.rs:9:31
+ --> $DIR/issue-74816.rs:8:31
|
LL | type Associated: Trait1 = Self;
| ^^^^ doesn't have a size known at compile-time
|
note: required by a bound in `Trait2::Associated`
- --> $DIR/issue-74816.rs:9:5
+ --> $DIR/issue-74816.rs:8:5
|
LL | type Associated: Trait1 = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
diff --git a/src/test/ui/generic-associated-types/issue-74824.rs b/src/test/ui/generic-associated-types/issue-74824.rs
index 1bbf7aac5..10c45d133 100644
--- a/src/test/ui/generic-associated-types/issue-74824.rs
+++ b/src/test/ui/generic-associated-types/issue-74824.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
use std::ops::Deref;
diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr
index 8517eb9fa..623adb1c2 100644
--- a/src/test/ui/generic-associated-types/issue-74824.stderr
+++ b/src/test/ui/generic-associated-types/issue-74824.stderr
@@ -1,24 +1,24 @@
error[E0277]: the trait bound `Box<T>: Copy` is not satisfied
- --> $DIR/issue-74824.rs:7:26
+ --> $DIR/issue-74824.rs:6:26
|
LL | type Copy<T>: Copy = Box<T>;
| ^^^^^^ the trait `Copy` is not implemented for `Box<T>`
|
note: required by a bound in `UnsafeCopy::Copy`
- --> $DIR/issue-74824.rs:7:19
+ --> $DIR/issue-74824.rs:6:19
|
LL | type Copy<T>: Copy = Box<T>;
| ^^^^ required by this bound in `UnsafeCopy::Copy`
error[E0277]: the trait bound `T: Clone` is not satisfied
- --> $DIR/issue-74824.rs:7:26
+ --> $DIR/issue-74824.rs:6:26
|
LL | type Copy<T>: Copy = Box<T>;
| ^^^^^^ the trait `Clone` is not implemented for `T`
|
- = note: required because of the requirements on the impl of `Clone` for `Box<T>`
+ = note: required for `Box<T>` to implement `Clone`
note: required by a bound in `UnsafeCopy::Copy`
- --> $DIR/issue-74824.rs:7:19
+ --> $DIR/issue-74824.rs:6:19
|
LL | type Copy<T>: Copy = Box<T>;
| ^^^^ required by this bound in `UnsafeCopy::Copy`
diff --git a/src/test/ui/generic-associated-types/issue-76407.rs b/src/test/ui/generic-associated-types/issue-76407.rs
index a8141829b..9556ec6da 100644
--- a/src/test/ui/generic-associated-types/issue-76407.rs
+++ b/src/test/ui/generic-associated-types/issue-76407.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Marker {}
impl Marker for u32 {}
diff --git a/src/test/ui/generic-associated-types/issue-76535.base.stderr b/src/test/ui/generic-associated-types/issue-76535.base.stderr
index 5decd58bb..088f69b09 100644
--- a/src/test/ui/generic-associated-types/issue-76535.base.stderr
+++ b/src/test/ui/generic-associated-types/issue-76535.base.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `SuperTrait::SubType`
- --> $DIR/issue-76535.rs:40:33
+ --> $DIR/issue-76535.rs:39:33
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-76535.rs:10:10
+ --> $DIR/issue-76535.rs:9:10
|
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ --
@@ -15,13 +15,13 @@ LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperS
| ~~~~~~~~~~~
error[E0038]: the trait `SuperTrait` cannot be made into an object
- --> $DIR/issue-76535.rs:40:14
+ --> $DIR/issue-76535.rs:39:14
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-76535.rs:10:10
+ --> $DIR/issue-76535.rs:9:10
|
LL | pub trait SuperTrait {
| ---------- this trait cannot be made into an object...
@@ -30,20 +30,20 @@ LL | type SubType<'a>: SubTrait where Self: 'a;
= help: consider moving `SubType` to another trait
error[E0038]: the trait `SuperTrait` cannot be made into an object
- --> $DIR/issue-76535.rs:40:57
+ --> $DIR/issue-76535.rs:39:57
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-76535.rs:10:10
+ --> $DIR/issue-76535.rs:9:10
|
LL | pub trait SuperTrait {
| ---------- this trait cannot be made into an object...
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ ...because it contains the generic associated type `SubType`
= help: consider moving `SubType` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
+ = note: required for `Box<SuperStruct>` to implement `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>`
= note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/generic-associated-types/issue-76535.extended.stderr b/src/test/ui/generic-associated-types/issue-76535.extended.stderr
index 067d0489b..e79f0a73f 100644
--- a/src/test/ui/generic-associated-types/issue-76535.extended.stderr
+++ b/src/test/ui/generic-associated-types/issue-76535.extended.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `SuperTrait::SubType`
- --> $DIR/issue-76535.rs:40:33
+ --> $DIR/issue-76535.rs:39:33
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-76535.rs:10:10
+ --> $DIR/issue-76535.rs:9:10
|
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ --
diff --git a/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs
index 46f217ba0..2457a05a0 100644
--- a/src/test/ui/generic-associated-types/issue-76535.rs
+++ b/src/test/ui/generic-associated-types/issue-76535.rs
@@ -1,6 +1,5 @@
// revisions: base extended
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/issue-76826.rs b/src/test/ui/generic-associated-types/issue-76826.rs
index 28eb3b0e7..ead78453e 100644
--- a/src/test/ui/generic-associated-types/issue-76826.rs
+++ b/src/test/ui/generic-associated-types/issue-76826.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(generic_associated_types)]
-
pub trait Iter {
type Item<'a> where Self: 'a;
diff --git a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
index 850d83be6..fd3b967d9 100644
--- a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
+++ b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
@@ -1,9 +1,7 @@
-// Test for diagnostics when we have mismatched lifetime due to implict 'static lifetime in GATs
+// Test for diagnostics when we have mismatched lifetime due to implicit 'static lifetime in GATs
// check-fail
-#![feature(generic_associated_types)]
-
pub trait A {}
impl A for &dyn A {}
impl A for Box<dyn A> {}
diff --git a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
index d487f19ba..86e0f5745 100644
--- a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
+++ b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
@@ -1,22 +1,22 @@
error: incompatible lifetime on type
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:18
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:15:18
|
LL | type T<'a> = Box<dyn A + 'a>;
| ^^^^^^^^^^^^^^^
|
note: because this has an unmet lifetime requirement
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:12:17
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:10:17
|
LL | type T<'a>: A;
| ^ introduces a `'static` lifetime requirement
note: the lifetime `'a` as defined here...
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:12
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:15:12
|
LL | type T<'a> = Box<dyn A + 'a>;
| ^^
= note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
note: this has an implicit `'static` lifetime requirement
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:9:20
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:7:20
|
LL | impl A for Box<dyn A> {}
| ^
@@ -26,51 +26,51 @@ LL | impl A for Box<dyn A + '_> {}
| ++++
error: incompatible lifetime on type
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:18
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:25:18
|
LL | type T<'a> = Box<dyn A + 'a>;
| ^^^^^^^^^^^^^^^
|
note: because this has an unmet lifetime requirement
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:23:17
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:21:17
|
LL | type T<'a>: C;
| ^ introduces a `'static` lifetime requirement
note: the lifetime `'a` as defined here...
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:12
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:25:12
|
LL | type T<'a> = Box<dyn A + 'a>;
| ^^
note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:21:1
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:19:1
|
LL | impl C for Box<dyn A + 'static> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: incompatible lifetime on type
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:18
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:35:18
|
LL | type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: because this has an unmet lifetime requirement
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:33:17
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:17
|
LL | type T<'a>: E;
| ^ introduces a `'static` lifetime requirement
note: the lifetime `'a` as defined here...
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:12
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:35:12
|
LL | type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
| ^^
= note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
note: this has an implicit `'static` lifetime requirement
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:21
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:29:21
|
LL | impl E for (Box<dyn A>, Box<dyn A>) {}
| ^
note: this has an implicit `'static` lifetime requirement
- --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:33
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:29:33
|
LL | impl E for (Box<dyn A>, Box<dyn A>) {}
| ^
diff --git a/src/test/ui/generic-associated-types/issue-78671.base.stderr b/src/test/ui/generic-associated-types/issue-78671.base.stderr
index 6bcd004b1..514f8d45a 100644
--- a/src/test/ui/generic-associated-types/issue-78671.base.stderr
+++ b/src/test/ui/generic-associated-types/issue-78671.base.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `CollectionFamily::Member`
- --> $DIR/issue-78671.rs:11:47
+ --> $DIR/issue-78671.rs:10:47
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
| ^^^^^^ expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `T`
- --> $DIR/issue-78671.rs:8:10
+ --> $DIR/issue-78671.rs:7:10
|
LL | type Member<T>;
| ^^^^^^ -
@@ -15,13 +15,13 @@ LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize>
| ~~~~~~~~~
error[E0038]: the trait `CollectionFamily` cannot be made into an object
- --> $DIR/issue-78671.rs:11:25
+ --> $DIR/issue-78671.rs:10:25
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-78671.rs:8:10
+ --> $DIR/issue-78671.rs:7:10
|
LL | trait CollectionFamily {
| ---------------- this trait cannot be made into an object...
diff --git a/src/test/ui/generic-associated-types/issue-78671.extended.stderr b/src/test/ui/generic-associated-types/issue-78671.extended.stderr
index f1b489335..6fa09a4c7 100644
--- a/src/test/ui/generic-associated-types/issue-78671.extended.stderr
+++ b/src/test/ui/generic-associated-types/issue-78671.extended.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `CollectionFamily::Member`
- --> $DIR/issue-78671.rs:11:47
+ --> $DIR/issue-78671.rs:10:47
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
| ^^^^^^ expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `T`
- --> $DIR/issue-78671.rs:8:10
+ --> $DIR/issue-78671.rs:7:10
|
LL | type Member<T>;
| ^^^^^^ -
diff --git a/src/test/ui/generic-associated-types/issue-78671.rs b/src/test/ui/generic-associated-types/issue-78671.rs
index c09dac28b..327b0c14a 100644
--- a/src/test/ui/generic-associated-types/issue-78671.rs
+++ b/src/test/ui/generic-associated-types/issue-78671.rs
@@ -1,6 +1,5 @@
// revisions: base extended
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/issue-79422.base.stderr b/src/test/ui/generic-associated-types/issue-79422.base.stderr
index 404c975d6..3c1a29d48 100644
--- a/src/test/ui/generic-associated-types/issue-79422.base.stderr
+++ b/src/test/ui/generic-associated-types/issue-79422.base.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `MapLike::VRefCont`
- --> $DIR/issue-79422.rs:48:36
+ --> $DIR/issue-79422.rs:47:36
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-79422.rs:24:10
+ --> $DIR/issue-79422.rs:23:10
|
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
| ^^^^^^^^ --
@@ -15,13 +15,13 @@ LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
| ~~~~~~~~~~~~
error[E0038]: the trait `MapLike` cannot be made into an object
- --> $DIR/issue-79422.rs:48:12
+ --> $DIR/issue-79422.rs:47:12
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-79422.rs:24:10
+ --> $DIR/issue-79422.rs:23:10
|
LL | trait MapLike<K, V> {
| ------- this trait cannot be made into an object...
@@ -30,20 +30,20 @@ LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
= help: consider moving `VRefCont` to another trait
error[E0038]: the trait `MapLike` cannot be made into an object
- --> $DIR/issue-79422.rs:45:13
+ --> $DIR/issue-79422.rs:44:13
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/issue-79422.rs:24:10
+ --> $DIR/issue-79422.rs:23:10
|
LL | trait MapLike<K, V> {
| ------- this trait cannot be made into an object...
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
= help: consider moving `VRefCont` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
+ = note: required for `Box<BTreeMap<u8, u8>>` to implement `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>`
= note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/generic-associated-types/issue-79422.extended.stderr b/src/test/ui/generic-associated-types/issue-79422.extended.stderr
index 9bcbd7471..58c921bf0 100644
--- a/src/test/ui/generic-associated-types/issue-79422.extended.stderr
+++ b/src/test/ui/generic-associated-types/issue-79422.extended.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `MapLike::VRefCont`
- --> $DIR/issue-79422.rs:48:36
+ --> $DIR/issue-79422.rs:47:36
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-79422.rs:24:10
+ --> $DIR/issue-79422.rs:23:10
|
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
| ^^^^^^^^ --
@@ -15,13 +15,13 @@ LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
| ~~~~~~~~~~~~
error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
- --> $DIR/issue-79422.rs:45:13
+ --> $DIR/issue-79422.rs:44:13
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
|
note: expected this to be `(dyn RefCont<'_, u8> + 'static)`
- --> $DIR/issue-79422.rs:29:25
+ --> $DIR/issue-79422.rs:28:25
|
LL | type VRefCont<'a> = &'a V where Self: 'a;
| ^^^^^
diff --git a/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs
index 7749975e6..a52dd792d 100644
--- a/src/test/ui/generic-associated-types/issue-79422.rs
+++ b/src/test/ui/generic-associated-types/issue-79422.rs
@@ -1,6 +1,5 @@
// revisions: base extended
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/issue-79636-1.rs b/src/test/ui/generic-associated-types/issue-79636-1.rs
index 6d73fd68d..a89039b5c 100644
--- a/src/test/ui/generic-associated-types/issue-79636-1.rs
+++ b/src/test/ui/generic-associated-types/issue-79636-1.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Monad {
type Unwrapped;
type Wrapped<B>;
diff --git a/src/test/ui/generic-associated-types/issue-79636-1.stderr b/src/test/ui/generic-associated-types/issue-79636-1.stderr
index 1ecb86282..155477048 100644
--- a/src/test/ui/generic-associated-types/issue-79636-1.stderr
+++ b/src/test/ui/generic-associated-types/issue-79636-1.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `Monad::Wrapped`
- --> $DIR/issue-79636-1.rs:15:34
+ --> $DIR/issue-79636-1.rs:13:34
|
LL | MInner: Monad<Unwrapped = A, Wrapped = MOuter::Wrapped<A>>,
| ^^^^^^^ expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `B`
- --> $DIR/issue-79636-1.rs:5:10
+ --> $DIR/issue-79636-1.rs:3:10
|
LL | type Wrapped<B>;
| ^^^^^^^ -
diff --git a/src/test/ui/generic-associated-types/issue-79636-2.rs b/src/test/ui/generic-associated-types/issue-79636-2.rs
index cdaf2e483..ff5ff38c9 100644
--- a/src/test/ui/generic-associated-types/issue-79636-2.rs
+++ b/src/test/ui/generic-associated-types/issue-79636-2.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait SomeTrait {
type Wrapped<A>: SomeTrait;
diff --git a/src/test/ui/generic-associated-types/issue-79636-2.stderr b/src/test/ui/generic-associated-types/issue-79636-2.stderr
index ae61b7b10..6a36bfc37 100644
--- a/src/test/ui/generic-associated-types/issue-79636-2.stderr
+++ b/src/test/ui/generic-associated-types/issue-79636-2.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `SomeTrait::Wrapped`
- --> $DIR/issue-79636-2.rs:11:18
+ --> $DIR/issue-79636-2.rs:9:18
|
LL | W: SomeTrait<Wrapped = W>,
| ^^^^^^^ expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `A`
- --> $DIR/issue-79636-2.rs:4:10
+ --> $DIR/issue-79636-2.rs:2:10
|
LL | type Wrapped<A>: SomeTrait;
| ^^^^^^^ -
diff --git a/src/test/ui/generic-associated-types/issue-80433-reduced.rs b/src/test/ui/generic-associated-types/issue-80433-reduced.rs
index f15d4d8b1..44831a995 100644
--- a/src/test/ui/generic-associated-types/issue-80433-reduced.rs
+++ b/src/test/ui/generic-associated-types/issue-80433-reduced.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
struct E {}
trait TestMut {
diff --git a/src/test/ui/generic-associated-types/issue-80433.rs b/src/test/ui/generic-associated-types/issue-80433.rs
index 6a1fe7519..05ff82fa7 100644
--- a/src/test/ui/generic-associated-types/issue-80433.rs
+++ b/src/test/ui/generic-associated-types/issue-80433.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
#[derive(Default)]
struct E<T> {
data: T,
diff --git a/src/test/ui/generic-associated-types/issue-80433.stderr b/src/test/ui/generic-associated-types/issue-80433.stderr
index d8c210dcf..20a407dd4 100644
--- a/src/test/ui/generic-associated-types/issue-80433.stderr
+++ b/src/test/ui/generic-associated-types/issue-80433.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `TestMut::Output`
- --> $DIR/issue-80433.rs:23:47
+ --> $DIR/issue-80433.rs:21:47
|
LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
| ^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-80433.rs:9:10
+ --> $DIR/issue-80433.rs:7:10
|
LL | type Output<'a>;
| ^^^^^^ --
diff --git a/src/test/ui/generic-associated-types/issue-81487.rs b/src/test/ui/generic-associated-types/issue-81487.rs
index 7f399c4f9..0d19a75bb 100644
--- a/src/test/ui/generic-associated-types/issue-81487.rs
+++ b/src/test/ui/generic-associated-types/issue-81487.rs
@@ -1,7 +1,5 @@
// build-pass
-#![feature(generic_associated_types)]
-
trait Trait {
type Ref<'a>;
}
diff --git a/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs
index fa2f86242..a7cc9a605 100644
--- a/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs
+++ b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs
@@ -1,7 +1,5 @@
// Regression test for #81712.
-#![feature(generic_associated_types)]
-
trait A {
type BType: B<AType = Self>;
}
diff --git a/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr
index 86c99c32f..c8961e28e 100644
--- a/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr
+++ b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `C::DType`
- --> $DIR/issue-81712-cyclic-traits.rs:16:19
+ --> $DIR/issue-81712-cyclic-traits.rs:14:19
|
LL | type CType: C<DType = Self>;
| ^^^^^ expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `T`
- --> $DIR/issue-81712-cyclic-traits.rs:13:10
+ --> $DIR/issue-81712-cyclic-traits.rs:11:10
|
LL | type DType<T>: D<T, CType = Self>;
| ^^^^^ -
diff --git a/src/test/ui/generic-associated-types/issue-81862.rs b/src/test/ui/generic-associated-types/issue-81862.rs
index e457bca0c..bde828b77 100644
--- a/src/test/ui/generic-associated-types/issue-81862.rs
+++ b/src/test/ui/generic-associated-types/issue-81862.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait StreamingIterator {
type Item<'a>;
fn next(&mut self) -> Option<Self::Item>;
diff --git a/src/test/ui/generic-associated-types/issue-81862.stderr b/src/test/ui/generic-associated-types/issue-81862.stderr
index c664b3ee6..ba7980846 100644
--- a/src/test/ui/generic-associated-types/issue-81862.stderr
+++ b/src/test/ui/generic-associated-types/issue-81862.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `StreamingIterator::Item`
- --> $DIR/issue-81862.rs:5:40
+ --> $DIR/issue-81862.rs:3:40
|
LL | fn next(&mut self) -> Option<Self::Item>;
| ^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-81862.rs:4:10
+ --> $DIR/issue-81862.rs:2:10
|
LL | type Item<'a>;
| ^^^^ --
diff --git a/src/test/ui/generic-associated-types/issue-84931.rs b/src/test/ui/generic-associated-types/issue-84931.rs
index 9e247de16..4123ce9d4 100644
--- a/src/test/ui/generic-associated-types/issue-84931.rs
+++ b/src/test/ui/generic-associated-types/issue-84931.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
// check-fail
trait StreamingIter {
diff --git a/src/test/ui/generic-associated-types/issue-84931.stderr b/src/test/ui/generic-associated-types/issue-84931.stderr
index 11c3dffde..fffea98a4 100644
--- a/src/test/ui/generic-associated-types/issue-84931.stderr
+++ b/src/test/ui/generic-associated-types/issue-84931.stderr
@@ -1,5 +1,5 @@
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/issue-84931.rs:15:21
+ --> $DIR/issue-84931.rs:14:21
|
LL | type Item<'a> = &'a mut T;
| ^^^^^^^^^- help: consider adding a where clause: `where T: 'a`
diff --git a/src/test/ui/generic-associated-types/issue-85921.rs b/src/test/ui/generic-associated-types/issue-85921.rs
index df59f497d..d281ed9ee 100644
--- a/src/test/ui/generic-associated-types/issue-85921.rs
+++ b/src/test/ui/generic-associated-types/issue-85921.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Trait {
type Assoc<'a>;
diff --git a/src/test/ui/generic-associated-types/issue-86483.rs b/src/test/ui/generic-associated-types/issue-86483.rs
index 07dd0bffd..70267637a 100644
--- a/src/test/ui/generic-associated-types/issue-86483.rs
+++ b/src/test/ui/generic-associated-types/issue-86483.rs
@@ -4,8 +4,6 @@
//
// check-pass
-#![feature(generic_associated_types)]
-
pub trait IceIce<T>
where
for<'a> T: 'a,
diff --git a/src/test/ui/generic-associated-types/issue-86787.rs b/src/test/ui/generic-associated-types/issue-86787.rs
index 0f8096c8a..96075ca50 100644
--- a/src/test/ui/generic-associated-types/issue-86787.rs
+++ b/src/test/ui/generic-associated-types/issue-86787.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
// check-fail
enum Either<L, R> {
diff --git a/src/test/ui/generic-associated-types/issue-86787.stderr b/src/test/ui/generic-associated-types/issue-86787.stderr
index d4b2267d3..f34c63cf7 100644
--- a/src/test/ui/generic-associated-types/issue-86787.stderr
+++ b/src/test/ui/generic-associated-types/issue-86787.stderr
@@ -1,5 +1,5 @@
error: missing required bound on `TRef`
- --> $DIR/issue-86787.rs:11:5
+ --> $DIR/issue-86787.rs:10:5
|
LL | type TRef<'a>;
| ^^^^^^^^^^^^^-
diff --git a/src/test/ui/generic-associated-types/issue-87258_a.rs b/src/test/ui/generic-associated-types/issue-87258_a.rs
index c65f3fb2a..9ab683d3d 100644
--- a/src/test/ui/generic-associated-types/issue-87258_a.rs
+++ b/src/test/ui/generic-associated-types/issue-87258_a.rs
@@ -1,5 +1,4 @@
#![feature(type_alias_impl_trait)]
-#![feature(generic_associated_types)]
// See https://github.com/rust-lang/rust/issues/87258#issuecomment-883293367
diff --git a/src/test/ui/generic-associated-types/issue-87258_a.stderr b/src/test/ui/generic-associated-types/issue-87258_a.stderr
index db3a5c819..fa0748a28 100644
--- a/src/test/ui/generic-associated-types/issue-87258_a.stderr
+++ b/src/test/ui/generic-associated-types/issue-87258_a.stderr
@@ -1,5 +1,5 @@
error: unconstrained opaque type
- --> $DIR/issue-87258_a.rs:18:26
+ --> $DIR/issue-87258_a.rs:17:26
|
LL | type FooFuture<'a> = impl Trait1;
| ^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/issue-87258_b.rs b/src/test/ui/generic-associated-types/issue-87258_b.rs
index f59e0d766..7b7610b21 100644
--- a/src/test/ui/generic-associated-types/issue-87258_b.rs
+++ b/src/test/ui/generic-associated-types/issue-87258_b.rs
@@ -1,5 +1,4 @@
#![feature(type_alias_impl_trait)]
-#![feature(generic_associated_types)]
// See https://github.com/rust-lang/rust/issues/87258#issuecomment-883293367
diff --git a/src/test/ui/generic-associated-types/issue-87258_b.stderr b/src/test/ui/generic-associated-types/issue-87258_b.stderr
index 9faccc961..0ee665f38 100644
--- a/src/test/ui/generic-associated-types/issue-87258_b.stderr
+++ b/src/test/ui/generic-associated-types/issue-87258_b.stderr
@@ -1,5 +1,5 @@
error: unconstrained opaque type
- --> $DIR/issue-87258_b.rs:17:49
+ --> $DIR/issue-87258_b.rs:16:49
|
LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
| ^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/issue-87429-2.rs b/src/test/ui/generic-associated-types/issue-87429-2.rs
index d35bb098a..feb43ee5a 100644
--- a/src/test/ui/generic-associated-types/issue-87429-2.rs
+++ b/src/test/ui/generic-associated-types/issue-87429-2.rs
@@ -4,8 +4,6 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Family {
type Member<'a, C: Eq>: for<'b> MyBound<'b, C>;
}
diff --git a/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs
index 9ee07c2f1..2006f9bc7 100644
--- a/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs
+++ b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs
@@ -1,7 +1,6 @@
// check-fail
#![feature(associated_type_defaults)]
-#![feature(generic_associated_types)]
trait Family {
// Fine, i32: PartialEq<i32>
diff --git a/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
index c6fa02cb9..b1abe012b 100644
--- a/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
+++ b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
@@ -1,12 +1,12 @@
error[E0277]: can't compare `Foo` with `Foo`
- --> $DIR/issue-87429-associated-type-default.rs:14:60
+ --> $DIR/issue-87429-associated-type-default.rs:13:60
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
| ^^^ no implementation for `Foo == Foo`
|
= help: the trait `PartialEq` is not implemented for `Foo`
note: required by a bound in `Family2::Member`
- --> $DIR/issue-87429-associated-type-default.rs:14:22
+ --> $DIR/issue-87429-associated-type-default.rs:13:22
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family2::Member`
diff --git a/src/test/ui/generic-associated-types/issue-87429-specialization.rs b/src/test/ui/generic-associated-types/issue-87429-specialization.rs
index b365e07fe..6e31f1b21 100644
--- a/src/test/ui/generic-associated-types/issue-87429-specialization.rs
+++ b/src/test/ui/generic-associated-types/issue-87429-specialization.rs
@@ -2,7 +2,6 @@
#![feature(specialization)]
//~^ WARN incomplete
-#![feature(generic_associated_types)]
trait Family {
type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
diff --git a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
index 015e0c779..d8e889aec 100644
--- a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
+++ b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
@@ -9,14 +9,14 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
error[E0277]: can't compare `Foo` with `Foo`
- --> $DIR/issue-87429-specialization.rs:21:31
+ --> $DIR/issue-87429-specialization.rs:20:31
|
LL | default type Member<'a> = Foo;
| ^^^ no implementation for `Foo == Foo`
|
= help: the trait `PartialEq` is not implemented for `Foo`
note: required by a bound in `Family::Member`
- --> $DIR/issue-87429-specialization.rs:8:22
+ --> $DIR/issue-87429-specialization.rs:7:22
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member`
diff --git a/src/test/ui/generic-associated-types/issue-87429.rs b/src/test/ui/generic-associated-types/issue-87429.rs
index f905348ae..56394823c 100644
--- a/src/test/ui/generic-associated-types/issue-87429.rs
+++ b/src/test/ui/generic-associated-types/issue-87429.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Family {
type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
}
diff --git a/src/test/ui/generic-associated-types/issue-87748.rs b/src/test/ui/generic-associated-types/issue-87748.rs
new file mode 100644
index 000000000..6cbe3d902
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87748.rs
@@ -0,0 +1,21 @@
+// Checks that we properly add implied bounds from unnormalized projections in
+// inputs when typechecking functions.
+
+// check-pass
+
+trait MyTrait {
+ type Assoc<'a, 'b> where 'b: 'a;
+ fn do_sth(arg: Self::Assoc<'_, '_>);
+ fn do_sth2(arg: Self::Assoc<'_, '_>) {}
+}
+
+struct Foo;
+
+impl MyTrait for Foo {
+ type Assoc<'a, 'b> = u32 where 'b: 'a;
+
+ fn do_sth(_: u32) {}
+ fn do_sth2(_: Self::Assoc<'static, 'static>) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-87750.rs b/src/test/ui/generic-associated-types/issue-87750.rs
index 89bd79ac2..0a11a0f3a 100644
--- a/src/test/ui/generic-associated-types/issue-87750.rs
+++ b/src/test/ui/generic-associated-types/issue-87750.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait PointerFamily {
type Pointer<T>;
}
diff --git a/src/test/ui/generic-associated-types/issue-87750.stderr b/src/test/ui/generic-associated-types/issue-87750.stderr
index 854541f3d..b358ca273 100644
--- a/src/test/ui/generic-associated-types/issue-87750.stderr
+++ b/src/test/ui/generic-associated-types/issue-87750.stderr
@@ -1,5 +1,5 @@
error[E0275]: overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
- --> $DIR/issue-87750.rs:20:16
+ --> $DIR/issue-87750.rs:18:16
|
LL | let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/issue-88287.rs b/src/test/ui/generic-associated-types/issue-88287.rs
index 4952a0825..82188493d 100644
--- a/src/test/ui/generic-associated-types/issue-88287.rs
+++ b/src/test/ui/generic-associated-types/issue-88287.rs
@@ -1,6 +1,5 @@
// edition:2018
-#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
use std::future::Future;
diff --git a/src/test/ui/generic-associated-types/issue-88287.stderr b/src/test/ui/generic-associated-types/issue-88287.stderr
index 5241d85a5..1b84cce62 100644
--- a/src/test/ui/generic-associated-types/issue-88287.stderr
+++ b/src/test/ui/generic-associated-types/issue-88287.stderr
@@ -1,5 +1,5 @@
error[E0277]: the size for values of type `A` cannot be known at compilation time
- --> $DIR/issue-88287.rs:35:9
+ --> $DIR/issue-88287.rs:34:9
|
LL | type SearchFutureTy<'f, A, B: 'f>
| - this type parameter needs to be `std::marker::Sized`
@@ -8,7 +8,7 @@ LL | async move { todo!() }
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
note: required by a bound in `<T as SearchableResourceExt<Criteria>>`
- --> $DIR/issue-88287.rs:25:6
+ --> $DIR/issue-88287.rs:24:6
|
LL | impl<T, Criteria> SearchableResourceExt<Criteria> for T
| ^ required by this bound in `<T as SearchableResourceExt<Criteria>>`
diff --git a/src/test/ui/generic-associated-types/issue-88360.rs b/src/test/ui/generic-associated-types/issue-88360.rs
index 8ee98201a..c02690618 100644
--- a/src/test/ui/generic-associated-types/issue-88360.rs
+++ b/src/test/ui/generic-associated-types/issue-88360.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait GatTrait {
type Gat<'a> where Self: 'a;
diff --git a/src/test/ui/generic-associated-types/issue-88360.stderr b/src/test/ui/generic-associated-types/issue-88360.stderr
index 5f769d799..cd3750344 100644
--- a/src/test/ui/generic-associated-types/issue-88360.stderr
+++ b/src/test/ui/generic-associated-types/issue-88360.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/issue-88360.rs:15:9
+ --> $DIR/issue-88360.rs:13:9
|
LL | trait SuperTrait<T>
| - this type parameter
diff --git a/src/test/ui/generic-associated-types/issue-88405.rs b/src/test/ui/generic-associated-types/issue-88405.rs
index 4a405bd36..8dad6a89f 100644
--- a/src/test/ui/generic-associated-types/issue-88405.rs
+++ b/src/test/ui/generic-associated-types/issue-88405.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait SomeTrait {}
trait OtherTrait {
type Item;
diff --git a/src/test/ui/generic-associated-types/issue-88459.rs b/src/test/ui/generic-associated-types/issue-88459.rs
index 3b26a1801..07d7bc06d 100644
--- a/src/test/ui/generic-associated-types/issue-88459.rs
+++ b/src/test/ui/generic-associated-types/issue-88459.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
trait Trait {
type Assoc<'a>;
}
diff --git a/src/test/ui/generic-associated-types/issue-88595.rs b/src/test/ui/generic-associated-types/issue-88595.rs
index e0796dfec..24641ee1f 100644
--- a/src/test/ui/generic-associated-types/issue-88595.rs
+++ b/src/test/ui/generic-associated-types/issue-88595.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-88595.stderr b/src/test/ui/generic-associated-types/issue-88595.stderr
index 79d3479af..bcefc8066 100644
--- a/src/test/ui/generic-associated-types/issue-88595.stderr
+++ b/src/test/ui/generic-associated-types/issue-88595.stderr
@@ -1,11 +1,11 @@
error: non-defining opaque type use in defining scope
- --> $DIR/issue-88595.rs:21:35
+ --> $DIR/issue-88595.rs:20:35
|
LL | fn a(&'a self) -> Self::B<'a> {}
| ^^
|
note: lifetime used multiple times
- --> $DIR/issue-88595.rs:18:6
+ --> $DIR/issue-88595.rs:17:6
|
LL | impl<'a> A<'a> for C {
| ^^
diff --git a/src/test/ui/generic-associated-types/issue-89352.rs b/src/test/ui/generic-associated-types/issue-89352.rs
index d9c656d5f..1896d0c87 100644
--- a/src/test/ui/generic-associated-types/issue-89352.rs
+++ b/src/test/ui/generic-associated-types/issue-89352.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
use std::marker::PhantomData;
pub trait GenAssoc<T> {
diff --git a/src/test/ui/generic-associated-types/issue-90014.rs b/src/test/ui/generic-associated-types/issue-90014.rs
index f110b0693..55db95a6d 100644
--- a/src/test/ui/generic-associated-types/issue-90014.rs
+++ b/src/test/ui/generic-associated-types/issue-90014.rs
@@ -1,6 +1,5 @@
// edition:2018
-#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
use std::future::Future;
diff --git a/src/test/ui/generic-associated-types/issue-90014.stderr b/src/test/ui/generic-associated-types/issue-90014.stderr
index 457c582e8..2d3f4a6af 100644
--- a/src/test/ui/generic-associated-types/issue-90014.stderr
+++ b/src/test/ui/generic-associated-types/issue-90014.stderr
@@ -1,5 +1,5 @@
error[E0477]: the type `&mut ()` does not fulfill the required lifetime
- --> $DIR/issue-90014.rs:14:20
+ --> $DIR/issue-90014.rs:13:20
|
LL | type Fut<'a> where Self: 'a;
| ------------ definition of `Fut` from trait
@@ -8,7 +8,7 @@ LL | type Fut<'a> = impl Future<Output = ()>;
| ^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
|
note: type must outlive the lifetime `'a` as defined here
- --> $DIR/issue-90014.rs:14:14
+ --> $DIR/issue-90014.rs:13:14
|
LL | type Fut<'a> = impl Future<Output = ()>;
| ^^
diff --git a/src/test/ui/generic-associated-types/issue-90729.rs b/src/test/ui/generic-associated-types/issue-90729.rs
index 98295cce8..bcec2e321 100644
--- a/src/test/ui/generic-associated-types/issue-90729.rs
+++ b/src/test/ui/generic-associated-types/issue-90729.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
use std::marker::PhantomData;
pub trait Type {
diff --git a/src/test/ui/generic-associated-types/issue-91139.migrate.stderr b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr
index b424d9a2f..690160577 100644
--- a/src/test/ui/generic-associated-types/issue-91139.migrate.stderr
+++ b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr
@@ -1,13 +1,8 @@
-error[E0311]: the parameter type `T` may not live long enough
- --> $DIR/issue-91139.rs:27:12
+error: expected identifier, found `<<`
+ --> $DIR/issue-91139.rs:1:1
|
-LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
- |
-help: consider adding an explicit lifetime bound...
- |
-LL | fn foo<T: 'a>() {
- | ++++
+LL | <<<<<<< HEAD
+ | ^^ expected identifier
error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs
index 40eef11f0..5fc6071c9 100644
--- a/src/test/ui/generic-associated-types/issue-91139.rs
+++ b/src/test/ui/generic-associated-types/issue-91139.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Foo<T> {
type Type<'a>
where
diff --git a/src/test/ui/generic-associated-types/issue-91139.stderr b/src/test/ui/generic-associated-types/issue-91139.stderr
index b789b3a42..8bbe98fa1 100644
--- a/src/test/ui/generic-associated-types/issue-91139.stderr
+++ b/src/test/ui/generic-associated-types/issue-91139.stderr
@@ -1,41 +1,41 @@
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:12
+ --> $DIR/issue-91139.rs:14:12
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:12
+ --> $DIR/issue-91139.rs:14:12
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:12
+ --> $DIR/issue-91139.rs:14:12
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:12
+ --> $DIR/issue-91139.rs:14:12
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:58
+ --> $DIR/issue-91139.rs:14:58
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:58
+ --> $DIR/issue-91139.rs:14:58
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/issue-91139.rs:16:58
+ --> $DIR/issue-91139.rs:14:58
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
@@ -46,13 +46,13 @@ LL | fn foo<T: 'static>() {
| +++++++++
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:58
+ --> $DIR/issue-91139.rs:14:58
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^
error: `T` does not live long enough
- --> $DIR/issue-91139.rs:16:58
+ --> $DIR/issue-91139.rs:14:58
|
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/issue-91883.rs b/src/test/ui/generic-associated-types/issue-91883.rs
index 3d4585a44..e870e08a3 100644
--- a/src/test/ui/generic-associated-types/issue-91883.rs
+++ b/src/test/ui/generic-associated-types/issue-91883.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
use std::fmt::Debug;
use std::marker::PhantomData;
diff --git a/src/test/ui/generic-associated-types/issue-91883.stderr b/src/test/ui/generic-associated-types/issue-91883.stderr
index baf4889cc..1cfc2aaf1 100644
--- a/src/test/ui/generic-associated-types/issue-91883.stderr
+++ b/src/test/ui/generic-associated-types/issue-91883.stderr
@@ -1,5 +1,5 @@
error[E0478]: lifetime bound not satisfied
- --> $DIR/issue-91883.rs:32:24
+ --> $DIR/issue-91883.rs:30:24
|
LL | type Cursor<'tx>: Cursor<'tx>
| ----------------------------- definition of `Cursor` from trait
@@ -8,12 +8,12 @@ LL | type Cursor<'tx> = CursorImpl<'tx>;
| ^^^^^^^^^^^^^^^- help: try copying these clauses from the trait: `where 'db: 'tx, Self: 'tx`
|
note: lifetime parameter instantiated with the lifetime `'db` as defined here
- --> $DIR/issue-91883.rs:31:6
+ --> $DIR/issue-91883.rs:29:6
|
LL | impl<'db> Transaction<'db> for TransactionImpl<'db> {
| ^^^
note: but lifetime parameter must outlive the lifetime `'tx` as defined here
- --> $DIR/issue-91883.rs:32:17
+ --> $DIR/issue-91883.rs:30:17
|
LL | type Cursor<'tx> = CursorImpl<'tx>;
| ^^^
diff --git a/src/test/ui/generic-associated-types/issue-92033.rs b/src/test/ui/generic-associated-types/issue-92033.rs
index 1d5f7d5c0..d111580b8 100644
--- a/src/test/ui/generic-associated-types/issue-92033.rs
+++ b/src/test/ui/generic-associated-types/issue-92033.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
struct Texture;
trait Surface {
diff --git a/src/test/ui/generic-associated-types/issue-92033.stderr b/src/test/ui/generic-associated-types/issue-92033.stderr
index 6dd901027..cd7eed254 100644
--- a/src/test/ui/generic-associated-types/issue-92033.stderr
+++ b/src/test/ui/generic-associated-types/issue-92033.stderr
@@ -1,5 +1,5 @@
error[E0477]: the type `&'s Texture` does not fulfill the required lifetime
- --> $DIR/issue-92033.rs:22:28
+ --> $DIR/issue-92033.rs:20:28
|
LL | type TextureIter<'a>: Iterator<Item = &'a Texture>
| -------------------------------------------------- definition of `TextureIter` from trait
@@ -8,7 +8,7 @@ LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
|
note: type must outlive the lifetime `'a` as defined here
- --> $DIR/issue-92033.rs:22:22
+ --> $DIR/issue-92033.rs:20:22
|
LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
| ^^
diff --git a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
index c74161cd3..ce1fd6dd9 100644
--- a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
+++ b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
@@ -1,5 +1,5 @@
error[E0311]: the parameter type `C` may not live long enough
- --> $DIR/issue-92096.rs:20:33
+ --> $DIR/issue-92096.rs:19:33
|
LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
| ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
@@ -10,7 +10,7 @@ LL | C: Client + Send + Sync + 'a,
| ++++
error[E0311]: the parameter type `C` may not live long enough
- --> $DIR/issue-92096.rs:20:33
+ --> $DIR/issue-92096.rs:19:33
|
LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
| ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
diff --git a/src/test/ui/generic-associated-types/issue-92096.rs b/src/test/ui/generic-associated-types/issue-92096.rs
index 377b8164a..e285af666 100644
--- a/src/test/ui/generic-associated-types/issue-92096.rs
+++ b/src/test/ui/generic-associated-types/issue-92096.rs
@@ -1,7 +1,5 @@
// edition:2018
-#![feature(generic_associated_types)]
-
use std::future::Future;
trait Client {
diff --git a/src/test/ui/generic-associated-types/issue-92096.stderr b/src/test/ui/generic-associated-types/issue-92096.stderr
index ca61a0f43..91a06d5ac 100644
--- a/src/test/ui/generic-associated-types/issue-92096.stderr
+++ b/src/test/ui/generic-associated-types/issue-92096.stderr
@@ -1,5 +1,5 @@
error: `C` does not live long enough
- --> $DIR/issue-92096.rs:19:5
+ --> $DIR/issue-92096.rs:17:5
|
LL | async move { c.connect().await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/issue-92280.rs b/src/test/ui/generic-associated-types/issue-92280.rs
index 81d000f10..9284beea3 100644
--- a/src/test/ui/generic-associated-types/issue-92280.rs
+++ b/src/test/ui/generic-associated-types/issue-92280.rs
@@ -1,6 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
#![allow(non_camel_case_types)]
trait HasAssoc {
diff --git a/src/test/ui/generic-associated-types/issue-92954.rs b/src/test/ui/generic-associated-types/issue-92954.rs
index 95c090ff4..22ce8f9fe 100644
--- a/src/test/ui/generic-associated-types/issue-92954.rs
+++ b/src/test/ui/generic-associated-types/issue-92954.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
pub trait Foo {
type Assoc<'c>;
fn function() -> for<'x> fn(Self::Assoc<'x>);
diff --git a/src/test/ui/generic-associated-types/issue-93141.rs b/src/test/ui/generic-associated-types/issue-93141.rs
index 39ca77d13..48c78b9c0 100644
--- a/src/test/ui/generic-associated-types/issue-93141.rs
+++ b/src/test/ui/generic-associated-types/issue-93141.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
pub trait Fooey: Sized {
type Context<'c> where Self: 'c;
}
diff --git a/src/test/ui/generic-associated-types/issue-93262.rs b/src/test/ui/generic-associated-types/issue-93262.rs
index adc6aa8fa..a7bcd111d 100644
--- a/src/test/ui/generic-associated-types/issue-93262.rs
+++ b/src/test/ui/generic-associated-types/issue-93262.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
pub trait Trait {
type Assoc<'a> where Self: 'a;
}
diff --git a/src/test/ui/generic-associated-types/issue-93340.rs b/src/test/ui/generic-associated-types/issue-93340.rs
index d065bde88..4662fda53 100644
--- a/src/test/ui/generic-associated-types/issue-93340.rs
+++ b/src/test/ui/generic-associated-types/issue-93340.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
pub trait Scalar: 'static {
type RefType<'a>: ScalarRef<'a>;
}
diff --git a/src/test/ui/generic-associated-types/issue-93341.rs b/src/test/ui/generic-associated-types/issue-93341.rs
index e96a768ec..737b2bbdb 100644
--- a/src/test/ui/generic-associated-types/issue-93341.rs
+++ b/src/test/ui/generic-associated-types/issue-93341.rs
@@ -1,6 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
use std::marker::PhantomData;
pub struct Id<'id>(PhantomData<fn(&'id ()) -> &'id ()>);
diff --git a/src/test/ui/generic-associated-types/issue-93342.rs b/src/test/ui/generic-associated-types/issue-93342.rs
index d8d7adac9..d4422d5d1 100644
--- a/src/test/ui/generic-associated-types/issue-93342.rs
+++ b/src/test/ui/generic-associated-types/issue-93342.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
use std::marker::PhantomData;
pub trait Scalar: 'static {
diff --git a/src/test/ui/generic-associated-types/issue-93874.rs b/src/test/ui/generic-associated-types/issue-93874.rs
index f403d7516..30956655a 100644
--- a/src/test/ui/generic-associated-types/issue-93874.rs
+++ b/src/test/ui/generic-associated-types/issue-93874.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
pub trait Build {
type Output<O>;
fn build<O>(self, input: O) -> Self::Output<O>;
diff --git a/src/test/ui/generic-associated-types/issue-95305.rs b/src/test/ui/generic-associated-types/issue-95305.rs
index e2f1710fa..6c3ec20e7 100644
--- a/src/test/ui/generic-associated-types/issue-95305.rs
+++ b/src/test/ui/generic-associated-types/issue-95305.rs
@@ -2,7 +2,6 @@
// Forbid it for now but proper support might be added
// at some point in the future.
-#![feature(generic_associated_types)]
#![feature(anonymous_lifetime_in_impl_trait)]
trait Foo {
type Item<'a>;
diff --git a/src/test/ui/generic-associated-types/issue-95305.stderr b/src/test/ui/generic-associated-types/issue-95305.stderr
index d8557525f..eb15cbc62 100644
--- a/src/test/ui/generic-associated-types/issue-95305.stderr
+++ b/src/test/ui/generic-associated-types/issue-95305.stderr
@@ -1,5 +1,5 @@
error[E0637]: `'_` cannot be used here
- --> $DIR/issue-95305.rs:11:26
+ --> $DIR/issue-95305.rs:10:26
|
LL | fn foo(x: &impl Foo<Item<'_> = u32>) { }
| ^^ `'_` is a reserved lifetime name
diff --git a/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs
index af0049891..8ad351bd3 100644
--- a/src/test/ui/generic-associated-types/iterable.rs
+++ b/src/test/ui/generic-associated-types/iterable.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// run-pass
trait Iterable {
diff --git a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
index 655abd18d..36974b3df 100644
--- a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
+++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
@@ -1,8 +1,6 @@
// Test that the predicate printed in an unresolved method error prints the
// generics for a generic associated type.
-#![feature(generic_associated_types)]
-
trait X {
type Y<T>;
}
diff --git a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
index d9dc77ac8..baef38f6b 100644
--- a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
+++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
@@ -1,5 +1,5 @@
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
- --> $DIR/method-unsatified-assoc-type-predicate.rs:30:7
+ --> $DIR/method-unsatified-assoc-type-predicate.rs:28:7
|
LL | struct S;
| --------
@@ -12,7 +12,7 @@ LL | a.f();
| ^ method cannot be called on `S` due to unsatisfied trait bounds
|
note: trait bound `<S as X>::Y<i32> = i32` was not satisfied
- --> $DIR/method-unsatified-assoc-type-predicate.rs:14:11
+ --> $DIR/method-unsatified-assoc-type-predicate.rs:12:11
|
LL | impl<T: X<Y<i32> = i32>> M for T {}
| ^^^^^^^^^^^^ - -
diff --git a/src/test/ui/generic-associated-types/missing-bounds.fixed b/src/test/ui/generic-associated-types/missing-bounds.fixed
index 2315810a4..ee758f19e 100644
--- a/src/test/ui/generic-associated-types/missing-bounds.fixed
+++ b/src/test/ui/generic-associated-types/missing-bounds.fixed
@@ -24,7 +24,7 @@ impl<B: Add + Add<Output = B>> Add for C<B> {
struct D<B>(B);
-impl<B: std::ops::Add<Output=B>> Add for D<B> {
+impl<B: std::ops::Add<Output = B>> Add for D<B> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
diff --git a/src/test/ui/generic-associated-types/missing-bounds.stderr b/src/test/ui/generic-associated-types/missing-bounds.stderr
index 138c642dd..c913483a8 100644
--- a/src/test/ui/generic-associated-types/missing-bounds.stderr
+++ b/src/test/ui/generic-associated-types/missing-bounds.stderr
@@ -66,8 +66,8 @@ LL | Self(self.0 + rhs.0)
|
help: consider restricting type parameter `B`
|
-LL | impl<B: std::ops::Add<Output=B>> Add for D<B> {
- | +++++++++++++++++++++++++
+LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
+ | +++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/missing-bounds.rs:42:14
diff --git a/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs
index 8171dc0ae..de9cad308 100644
--- a/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs
+++ b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs
@@ -1,7 +1,5 @@
// check-fail
-#![feature(generic_associated_types)]
-
trait Foo {
type Assoc<'a, 'b>;
}
diff --git a/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr
index edd1f9367..ffdba6676 100644
--- a/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr
+++ b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
- --> $DIR/missing-where-clause-on-trait.rs:9:39
+ --> $DIR/missing-where-clause-on-trait.rs:7:39
|
LL | type Assoc<'a, 'b>;
| ------------------ definition of `Assoc` from trait
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_args.rs b/src/test/ui/generic-associated-types/missing_lifetime_args.rs
index cd918157f..78def8092 100644
--- a/src/test/ui/generic-associated-types/missing_lifetime_args.rs
+++ b/src/test/ui/generic-associated-types/missing_lifetime_args.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a, 'b>;
}
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_args.stderr b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
index 7cf3f4b73..0ad1f1f8c 100644
--- a/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
+++ b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -1,11 +1,11 @@
error[E0107]: missing generics for associated type `X::Y`
- --> $DIR/missing_lifetime_args.rs:13:32
+ --> $DIR/missing_lifetime_args.rs:11:32
|
LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
| ^ expected 2 lifetime arguments
|
note: associated type defined here, with 2 lifetime parameters: `'a`, `'b`
- --> $DIR/missing_lifetime_args.rs:4:10
+ --> $DIR/missing_lifetime_args.rs:2:10
|
LL | type Y<'a, 'b>;
| ^ -- --
@@ -15,7 +15,7 @@ LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'c, 'd> = (&'c u32, &'d u32)>>) {}
| ~~~~~~~~~
error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
- --> $DIR/missing_lifetime_args.rs:16:26
+ --> $DIR/missing_lifetime_args.rs:14:26
|
LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
| ^^^ -- -- supplied 2 lifetime arguments
@@ -23,7 +23,7 @@ LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
| expected 3 lifetime arguments
|
note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
- --> $DIR/missing_lifetime_args.rs:7:8
+ --> $DIR/missing_lifetime_args.rs:5:8
|
LL | struct Foo<'a, 'b, 'c> {
| ^^^ -- -- --
@@ -33,7 +33,7 @@ LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
| ++++
error[E0107]: this struct takes 3 lifetime arguments but 1 lifetime argument was supplied
- --> $DIR/missing_lifetime_args.rs:19:16
+ --> $DIR/missing_lifetime_args.rs:17:16
|
LL | fn f<'a>(_arg: Foo<'a>) {}
| ^^^ -- supplied 1 lifetime argument
@@ -41,7 +41,7 @@ LL | fn f<'a>(_arg: Foo<'a>) {}
| expected 3 lifetime arguments
|
note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
- --> $DIR/missing_lifetime_args.rs:7:8
+ --> $DIR/missing_lifetime_args.rs:5:8
|
LL | struct Foo<'a, 'b, 'c> {
| ^^^ -- -- --
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_const.rs b/src/test/ui/generic-associated-types/missing_lifetime_const.rs
index e3e78dd96..8b174b9e9 100644
--- a/src/test/ui/generic-associated-types/missing_lifetime_const.rs
+++ b/src/test/ui/generic-associated-types/missing_lifetime_const.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Foo {
type Assoc<'a, const N: usize>;
}
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_const.stderr b/src/test/ui/generic-associated-types/missing_lifetime_const.stderr
index 5d50637bd..62d2e9f49 100644
--- a/src/test/ui/generic-associated-types/missing_lifetime_const.stderr
+++ b/src/test/ui/generic-associated-types/missing_lifetime_const.stderr
@@ -1,11 +1,11 @@
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/missing_lifetime_const.rs:8:24
+ --> $DIR/missing_lifetime_const.rs:6:24
|
LL | let _: <T as Foo>::Assoc<3>;
| ^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/missing_lifetime_const.rs:4:10
+ --> $DIR/missing_lifetime_const.rs:2:10
|
LL | type Assoc<'a, const N: usize>;
| ^^^^^ --
diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/generic-associated-types/parameter_number_and_kind.rs
index 0508cc2da..8428e7763 100644
--- a/src/test/ui/generic-associated-types/parameter_number_and_kind.rs
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
trait Foo {
diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
index 53d76fd22..c20b9669e 100644
--- a/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
@@ -1,5 +1,5 @@
error[E0107]: this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
- --> $DIR/parameter_number_and_kind.rs:12:24
+ --> $DIR/parameter_number_and_kind.rs:11:24
|
LL | type FErr1 = Self::E<'static, 'static>;
| ^ ------- help: remove this lifetime argument
@@ -7,19 +7,19 @@ LL | type FErr1 = Self::E<'static, 'static>;
| expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/parameter_number_and_kind.rs:9:10
+ --> $DIR/parameter_number_and_kind.rs:8:10
|
LL | type E<'a, T>;
| ^ --
error[E0107]: this associated type takes 1 generic argument but 0 generic arguments were supplied
- --> $DIR/parameter_number_and_kind.rs:12:24
+ --> $DIR/parameter_number_and_kind.rs:11:24
|
LL | type FErr1 = Self::E<'static, 'static>;
| ^ expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `T`
- --> $DIR/parameter_number_and_kind.rs:9:10
+ --> $DIR/parameter_number_and_kind.rs:8:10
|
LL | type E<'a, T>;
| ^ -
@@ -29,7 +29,7 @@ LL | type FErr1 = Self::E<'static, 'static, T>;
| +++
error[E0107]: this associated type takes 1 generic argument but 2 generic arguments were supplied
- --> $DIR/parameter_number_and_kind.rs:15:27
+ --> $DIR/parameter_number_and_kind.rs:14:27
|
LL | type FErr2<T> = Self::E<'static, T, u32>;
| ^ --- help: remove this generic argument
@@ -37,7 +37,7 @@ LL | type FErr2<T> = Self::E<'static, T, u32>;
| expected 1 generic argument
|
note: associated type defined here, with 1 generic parameter: `T`
- --> $DIR/parameter_number_and_kind.rs:9:10
+ --> $DIR/parameter_number_and_kind.rs:8:10
|
LL | type E<'a, T>;
| ^ -
diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs
index 6ca0bc6dd..c1381025a 100644
--- a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
// FIXME(#44265) add tests for type-generic and const-genertic associated types.
diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
index 1458bf0c4..fdd6d305a 100644
--- a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
@@ -1,5 +1,5 @@
error[E0195]: lifetime parameters or bounds on type `A` do not match the trait declaration
- --> $DIR/parameter_number_and_kind_impl.rs:15:11
+ --> $DIR/parameter_number_and_kind_impl.rs:14:11
|
LL | type A<'a>;
| ---- lifetimes in impl do not match this type in trait
@@ -8,7 +8,7 @@ LL | type A = u32;
| ^ lifetimes do not match type in trait
error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
- --> $DIR/parameter_number_and_kind_impl.rs:17:12
+ --> $DIR/parameter_number_and_kind_impl.rs:16:12
|
LL | type B<'a, 'b>;
| -- --
@@ -21,7 +21,7 @@ LL | type B<'a, T> = Vec<T>;
| found 1 type parameter
error[E0195]: lifetime parameters or bounds on type `C` do not match the trait declaration
- --> $DIR/parameter_number_and_kind_impl.rs:19:11
+ --> $DIR/parameter_number_and_kind_impl.rs:18:11
|
LL | type C;
| - lifetimes in impl do not match this type in trait
@@ -30,7 +30,7 @@ LL | type C<'a> = u32;
| ^^^^ lifetimes do not match type in trait
error[E0049]: type `A` has 1 type parameter but its trait declaration has 0 type parameters
- --> $DIR/parameter_number_and_kind_impl.rs:26:12
+ --> $DIR/parameter_number_and_kind_impl.rs:25:12
|
LL | type A<'a>;
| -- expected 0 type parameters
@@ -39,7 +39,7 @@ LL | type A<T> = u32;
| ^ found 1 type parameter
error[E0195]: lifetime parameters or bounds on type `B` do not match the trait declaration
- --> $DIR/parameter_number_and_kind_impl.rs:28:11
+ --> $DIR/parameter_number_and_kind_impl.rs:27:11
|
LL | type B<'a, 'b>;
| -------- lifetimes in impl do not match this type in trait
@@ -48,7 +48,7 @@ LL | type B<'a> = u32;
| ^^^^ lifetimes do not match type in trait
error[E0049]: type `C` has 1 type parameter but its trait declaration has 0 type parameters
- --> $DIR/parameter_number_and_kind_impl.rs:30:12
+ --> $DIR/parameter_number_and_kind_impl.rs:29:12
|
LL | type C;
| - expected 0 type parameters
diff --git a/src/test/ui/generic-associated-types/parse/in-trait-impl.rs b/src/test/ui/generic-associated-types/parse/in-trait-impl.rs
index 7f4775ddb..767098835 100644
--- a/src/test/ui/generic-associated-types/parse/in-trait-impl.rs
+++ b/src/test/ui/generic-associated-types/parse/in-trait-impl.rs
@@ -1,8 +1,6 @@
// check-pass
// compile-flags: -Z parse-only
-#![feature(generic_associated_types)]
-
impl<T> Baz for T where T: Foo {
type Quux<'a> = <T as Foo>::Bar<'a, 'static>;
}
diff --git a/src/test/ui/generic-associated-types/parse/in-trait.rs b/src/test/ui/generic-associated-types/parse/in-trait.rs
index d438795eb..6628aac37 100644
--- a/src/test/ui/generic-associated-types/parse/in-trait.rs
+++ b/src/test/ui/generic-associated-types/parse/in-trait.rs
@@ -1,8 +1,6 @@
// check-pass
// compile-flags: -Z parse-only
-#![feature(generic_associated_types)]
-
use std::ops::Deref;
use std::fmt::Debug;
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs
index be85598b7..cbb051892 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
}
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr
index 2b265e921..53d5f9de6 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr
@@ -1,5 +1,5 @@
error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
- --> $DIR/trait-path-expected-token.rs:7:33
+ --> $DIR/trait-path-expected-token.rs:5:33
|
LL | fn f1<'a>(arg : Box<dyn X<Y = B = &'a ()>>) {}
| - ^ expected one of 7 possible tokens
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs b/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs
index d57c2813b..9183ec497 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
mod error1 {
trait X {
type Y<'a>;
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr b/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr
index 272afc10b..cf2b1763f 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr
@@ -1,5 +1,5 @@
error: expected expression, found `)`
- --> $DIR/trait-path-expressions.rs:8:39
+ --> $DIR/trait-path-expressions.rs:6:39
|
LL | fn f1<'a>(arg : Box<dyn X< 1 = 32 >>) {}
| - ^ expected expression
@@ -7,7 +7,7 @@ LL | fn f1<'a>(arg : Box<dyn X< 1 = 32 >>) {}
| while parsing a const generic argument starting here
error: expected one of `,`, `:`, or `>`, found `=`
- --> $DIR/trait-path-expressions.rs:18:36
+ --> $DIR/trait-path-expressions.rs:16:36
|
LL | fn f2<'a>(arg : Box<dyn X< { 1 } = 32 >>) {}
| - ^ expected one of `,`, `:`, or `>`
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
index 791486480..ecabf8943 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
+++ b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
}
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr
index 3ace774a0..10ceccedc 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr
@@ -1,5 +1,5 @@
error: expected one of `>`, a const expression, lifetime, or type, found `:`
- --> $DIR/trait-path-missing-gen_arg.rs:8:30
+ --> $DIR/trait-path-missing-gen_arg.rs:6:30
|
LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
| ^ expected one of `>`, a const expression, lifetime, or type
@@ -10,13 +10,13 @@ LL | fn f1<'a>(arg : Box<{ dyn X< : 32 } >>) {}
| + +
error: expected parameter name, found `>`
- --> $DIR/trait-path-missing-gen_arg.rs:8:36
+ --> $DIR/trait-path-missing-gen_arg.rs:6:36
|
LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
| ^ expected parameter name
error: expected one of `!`, `)`, `+`, `,`, or `::`, found `>`
- --> $DIR/trait-path-missing-gen_arg.rs:8:36
+ --> $DIR/trait-path-missing-gen_arg.rs:6:36
|
LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
| ^
@@ -25,7 +25,7 @@ LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
| help: missing `,`
error: expected one of `>`, a const expression, lifetime, or type, found `=`
- --> $DIR/trait-path-missing-gen_arg.rs:16:30
+ --> $DIR/trait-path-missing-gen_arg.rs:14:30
|
LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {}
| - ^ expected one of `>`, a const expression, lifetime, or type
@@ -33,7 +33,7 @@ LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {}
| maybe try to close unmatched angle bracket
error[E0747]: constant provided when a type was expected
- --> $DIR/trait-path-missing-gen_arg.rs:8:23
+ --> $DIR/trait-path-missing-gen_arg.rs:6:23
|
LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
| ^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-segments.rs b/src/test/ui/generic-associated-types/parse/trait-path-segments.rs
index e943f075f..458e203eb 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-segments.rs
+++ b/src/test/ui/generic-associated-types/parse/trait-path-segments.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
const _: () = {
trait X {
type Y<'a>;
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr b/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr
index 7394393c0..8bc737d67 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr
@@ -1,5 +1,5 @@
error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=`
- --> $DIR/trait-path-segments.rs:8:36
+ --> $DIR/trait-path-segments.rs:6:36
|
LL | fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {}
| - ^ expected one of 8 possible tokens
@@ -12,7 +12,7 @@ LL | fn f1<'a>(arg : Box<dyn X<X::Y> = u32>>) {}
| +
error: expected one of `,`, `::`, `:`, or `>`, found `=`
- --> $DIR/trait-path-segments.rs:19:35
+ --> $DIR/trait-path-segments.rs:17:35
|
LL | impl<T : X<<Self as X>::Y<'a> = &'a u32>> Z for T {}
| - ^ expected one of `,`, `::`, `:`, or `>`
@@ -25,7 +25,7 @@ LL | impl<T : X<<Self as X>::Y<'a>> = &'a u32>> Z for T {}
| +
error: expected one of `!`, `+`, `,`, `::`, `:`, or `>`, found `=`
- --> $DIR/trait-path-segments.rs:30:25
+ --> $DIR/trait-path-segments.rs:28:25
|
LL | impl<T : X<X::Y<'a> = &'a u32>> Z for T {}
| - ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>`
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
index 4846af96d..1622b92aa 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
+++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
}
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
index 46ddcb635..e00a414ef 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
@@ -1,11 +1,11 @@
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/trait-path-type-error-once-implemented.rs:8:29
+ --> $DIR/trait-path-type-error-once-implemented.rs:6:29
|
LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/trait-path-type-error-once-implemented.rs:4:10
+ --> $DIR/trait-path-type-error-once-implemented.rs:2:10
|
LL | type Y<'a>;
| ^ --
@@ -15,7 +15,7 @@ LL | fn f2<'a>(arg : Box<dyn X<Y<'a, 1> = &'a ()>>) {}
| +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
- --> $DIR/trait-path-type-error-once-implemented.rs:8:29
+ --> $DIR/trait-path-type-error-once-implemented.rs:6:29
|
LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
| ^--- help: remove these generics
@@ -23,7 +23,7 @@ LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
| expected 0 generic arguments
|
note: associated type defined here, with 0 generic parameters
- --> $DIR/trait-path-type-error-once-implemented.rs:4:10
+ --> $DIR/trait-path-type-error-once-implemented.rs:2:10
|
LL | type Y<'a>;
| ^
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-types.rs b/src/test/ui/generic-associated-types/parse/trait-path-types.rs
index 856253cc7..74a00342f 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-types.rs
+++ b/src/test/ui/generic-associated-types/parse/trait-path-types.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait X {
type Y<'a>;
}
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-types.stderr b/src/test/ui/generic-associated-types/parse/trait-path-types.stderr
index fe9ed579e..8f7a73c95 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-types.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-types.stderr
@@ -1,5 +1,5 @@
error: expected one of `,`, `:`, or `>`, found `=`
- --> $DIR/trait-path-types.rs:8:37
+ --> $DIR/trait-path-types.rs:6:37
|
LL | fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {}
| - ^ expected one of `,`, `:`, or `>`
@@ -12,7 +12,7 @@ LL | fn f<'a>(arg : Box<dyn X< [u8; 1]> = u32>>) {}
| +
error: expected one of `,`, `:`, or `>`, found `=`
- --> $DIR/trait-path-types.rs:13:37
+ --> $DIR/trait-path-types.rs:11:37
|
LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'a ()>>) {}
| - ^ expected one of `,`, `:`, or `>`
@@ -25,7 +25,7 @@ LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>)> = &'a ()>>) {}
| +
error: expected one of `,`, `:`, or `>`, found `=`
- --> $DIR/trait-path-types.rs:18:33
+ --> $DIR/trait-path-types.rs:16:33
|
LL | fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {}
| -- ^ expected one of `,`, `:`, or `>`
diff --git a/src/test/ui/generic-associated-types/pointer_family.rs b/src/test/ui/generic-associated-types/pointer_family.rs
index da86e7f27..80827cd56 100644
--- a/src/test/ui/generic-associated-types/pointer_family.rs
+++ b/src/test/ui/generic-associated-types/pointer_family.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// check-pass
use std::rc::Rc;
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
index 794d677c8..58d57df63 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
@@ -1,8 +1,6 @@
// Like `projection-bound-cycle.rs` but this avoids using
// `feature(trivial_bounds)`.
-#![feature(generic_associated_types)]
-
trait Print {
fn print();
}
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
index 2b57c439f..27c1a8299 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
@@ -1,11 +1,11 @@
error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
- --> $DIR/projection-bound-cycle-generic.rs:44:18
+ --> $DIR/projection-bound-cycle-generic.rs:42:18
|
LL | type Assoc = OnlySized<<T as Foo>::Item>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `OnlySized`
- --> $DIR/projection-bound-cycle-generic.rs:28:18
+ --> $DIR/projection-bound-cycle-generic.rs:26:18
|
LL | struct OnlySized<T> where T: Sized { f: T }
| ^ required by this bound in `OnlySized`
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.rs b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
index 6564a3608..4cad1f613 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle.rs
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
@@ -2,7 +2,6 @@
// Make sure that we make sure that we don't allow arbitrary bounds to be
// proven when a bound and a where clause of an associated type are the same.
-#![feature(generic_associated_types)]
#![feature(trivial_bounds)]
trait Print {
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
index d9d0bf427..a46518c80 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
@@ -1,11 +1,11 @@
error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
- --> $DIR/projection-bound-cycle.rs:46:18
+ --> $DIR/projection-bound-cycle.rs:45:18
|
LL | type Assoc = OnlySized<<T as Foo>::Item>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `OnlySized`
- --> $DIR/projection-bound-cycle.rs:30:18
+ --> $DIR/projection-bound-cycle.rs:29:18
|
LL | struct OnlySized<T> where T: Sized { f: T }
| ^ required by this bound in `OnlySized`
diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
index a40c0c2c4..8e4d5ca5e 100644
--- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
+++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
pub trait X {
type Y<'a> where Self: 'a;
fn m(&self) -> Self::Y<'_>;
diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
index 4620aa34e..753ead48b 100644
--- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
+++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/projection-type-lifetime-mismatch.rs:17:5
+ --> $DIR/projection-type-lifetime-mismatch.rs:15:5
|
LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
| - let's call the lifetime of this reference `'1`
@@ -7,7 +7,7 @@ LL | x.m()
| ^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/projection-type-lifetime-mismatch.rs:22:5
+ --> $DIR/projection-type-lifetime-mismatch.rs:20:5
|
LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
| - let's call the lifetime of this reference `'1`
@@ -15,7 +15,7 @@ LL | x.m()
| ^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/projection-type-lifetime-mismatch.rs:27:5
+ --> $DIR/projection-type-lifetime-mismatch.rs:25:5
|
LL | fn h(x: &()) -> &'static () {
| - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.rs b/src/test/ui/generic-associated-types/self-outlives-lint.rs
index 300907adb..673891fc3 100644
--- a/src/test/ui/generic-associated-types/self-outlives-lint.rs
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
// check-fail
use std::fmt::Debug;
@@ -210,4 +208,17 @@ trait StaticReturnAndTakes<'a> {
fn bar<'b>(&self, arg: Self::Y<'b>);
}
+// We require bounds when the GAT appears in the inputs
+trait Input {
+ type Item<'a>;
+ //~^ missing required
+ fn takes_item<'a>(&'a self, item: Self::Item<'a>);
+}
+
+// We don't require bounds when the GAT appears in the where clauses
+trait WhereClause {
+ type Item<'a>;
+ fn takes_item<'a>(&'a self) where Self::Item<'a>: ;
+}
+
fn main() {}
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.stderr b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
index fdb1f50a7..58172bf06 100644
--- a/src/test/ui/generic-associated-types/self-outlives-lint.stderr
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
@@ -1,5 +1,5 @@
error: missing required bound on `Item`
- --> $DIR/self-outlives-lint.rs:9:5
+ --> $DIR/self-outlives-lint.rs:7:5
|
LL | type Item<'x>;
| ^^^^^^^^^^^^^-
@@ -10,7 +10,7 @@ LL | type Item<'x>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Out`
- --> $DIR/self-outlives-lint.rs:25:5
+ --> $DIR/self-outlives-lint.rs:23:5
|
LL | type Out<'x>;
| ^^^^^^^^^^^^-
@@ -21,7 +21,7 @@ LL | type Out<'x>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Out`
- --> $DIR/self-outlives-lint.rs:39:5
+ --> $DIR/self-outlives-lint.rs:37:5
|
LL | type Out<'x>;
| ^^^^^^^^^^^^-
@@ -32,7 +32,7 @@ LL | type Out<'x>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bounds on `Out`
- --> $DIR/self-outlives-lint.rs:46:5
+ --> $DIR/self-outlives-lint.rs:44:5
|
LL | type Out<'x, 'y>;
| ^^^^^^^^^^^^^^^^-
@@ -43,7 +43,7 @@ LL | type Out<'x, 'y>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Out`
- --> $DIR/self-outlives-lint.rs:61:5
+ --> $DIR/self-outlives-lint.rs:59:5
|
LL | type Out<'x, D>;
| ^^^^^^^^^^^^^^^-
@@ -54,7 +54,7 @@ LL | type Out<'x, D>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Out`
- --> $DIR/self-outlives-lint.rs:77:5
+ --> $DIR/self-outlives-lint.rs:75:5
|
LL | type Out<'x, D>;
| ^^^^^^^^^^^^^^^-
@@ -65,7 +65,7 @@ LL | type Out<'x, D>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Out`
- --> $DIR/self-outlives-lint.rs:92:5
+ --> $DIR/self-outlives-lint.rs:90:5
|
LL | type Out<'x, D>;
| ^^^^^^^^^^^^^^^-
@@ -76,7 +76,7 @@ LL | type Out<'x, D>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bounds on `Bar`
- --> $DIR/self-outlives-lint.rs:114:5
+ --> $DIR/self-outlives-lint.rs:112:5
|
LL | type Bar<'b>;
| ^^^^^^^^^^^^-
@@ -87,7 +87,7 @@ LL | type Bar<'b>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Bar`
- --> $DIR/self-outlives-lint.rs:122:5
+ --> $DIR/self-outlives-lint.rs:120:5
|
LL | type Bar<'b>;
| ^^^^^^^^^^^^-
@@ -98,7 +98,7 @@ LL | type Bar<'b>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Bar`
- --> $DIR/self-outlives-lint.rs:129:5
+ --> $DIR/self-outlives-lint.rs:127:5
|
LL | type Bar<'b>;
| ^^^^^^^^^^^^-
@@ -109,7 +109,7 @@ LL | type Bar<'b>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Item`
- --> $DIR/self-outlives-lint.rs:142:5
+ --> $DIR/self-outlives-lint.rs:140:5
|
LL | type Item<'a>;
| ^^^^^^^^^^^^^-
@@ -120,7 +120,7 @@ LL | type Item<'a>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Iterator`
- --> $DIR/self-outlives-lint.rs:144:5
+ --> $DIR/self-outlives-lint.rs:142:5
|
LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -131,7 +131,7 @@ LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Item`
- --> $DIR/self-outlives-lint.rs:150:5
+ --> $DIR/self-outlives-lint.rs:148:5
|
LL | type Item<'a>;
| ^^^^^^^^^^^^^-
@@ -142,7 +142,7 @@ LL | type Item<'a>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Bar`
- --> $DIR/self-outlives-lint.rs:159:5
+ --> $DIR/self-outlives-lint.rs:157:5
|
LL | type Bar<'a, 'b>;
| ^^^^^^^^^^^^^^^^-
@@ -153,7 +153,7 @@ LL | type Bar<'a, 'b>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Fut`
- --> $DIR/self-outlives-lint.rs:175:5
+ --> $DIR/self-outlives-lint.rs:173:5
|
LL | type Fut<'out>;
| ^^^^^^^^^^^^^^-
@@ -163,5 +163,16 @@ LL | type Fut<'out>;
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
-error: aborting due to 15 previous errors
+error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:213:5
+ |
+LL | type Item<'a>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: aborting due to 16 previous errors
diff --git a/src/test/ui/generic-associated-types/shadowing.rs b/src/test/ui/generic-associated-types/shadowing.rs
index 2a9763457..a05d6e143 100644
--- a/src/test/ui/generic-associated-types/shadowing.rs
+++ b/src/test/ui/generic-associated-types/shadowing.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Shadow<'a> {
type Bar<'a>;
//~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope
diff --git a/src/test/ui/generic-associated-types/shadowing.stderr b/src/test/ui/generic-associated-types/shadowing.stderr
index be7659209..bb32684bc 100644
--- a/src/test/ui/generic-associated-types/shadowing.stderr
+++ b/src/test/ui/generic-associated-types/shadowing.stderr
@@ -1,5 +1,5 @@
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
- --> $DIR/shadowing.rs:4:14
+ --> $DIR/shadowing.rs:2:14
|
LL | trait Shadow<'a> {
| -- first declared here
@@ -7,7 +7,7 @@ LL | type Bar<'a>;
| ^^ lifetime `'a` already in scope
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
- --> $DIR/shadowing.rs:13:14
+ --> $DIR/shadowing.rs:11:14
|
LL | impl<'a> NoShadow<'a> for &'a u32 {
| -- first declared here
@@ -15,7 +15,7 @@ LL | type Bar<'a> = i32;
| ^^ lifetime `'a` already in scope
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
- --> $DIR/shadowing.rs:18:14
+ --> $DIR/shadowing.rs:16:14
|
LL | trait ShadowT<T> {
| - first use of `T`
@@ -23,7 +23,7 @@ LL | type Bar<T>;
| ^ already used
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
- --> $DIR/shadowing.rs:27:14
+ --> $DIR/shadowing.rs:25:14
|
LL | impl<T> NoShadowT<T> for Option<T> {
| - first use of `T`
diff --git a/src/test/ui/generic-associated-types/streaming_iterator.rs b/src/test/ui/generic-associated-types/streaming_iterator.rs
index e71b6805a..408b8dc99 100644
--- a/src/test/ui/generic-associated-types/streaming_iterator.rs
+++ b/src/test/ui/generic-associated-types/streaming_iterator.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(generic_associated_types)]
-
use std::fmt::Display;
trait StreamingIterator {
diff --git a/src/test/ui/generic-associated-types/trait-objects.base.stderr b/src/test/ui/generic-associated-types/trait-objects.base.stderr
index 1df76a21b..556422c27 100644
--- a/src/test/ui/generic-associated-types/trait-objects.base.stderr
+++ b/src/test/ui/generic-associated-types/trait-objects.base.stderr
@@ -1,11 +1,11 @@
error[E0038]: the trait `StreamingIterator` cannot be made into an object
- --> $DIR/trait-objects.rs:14:21
+ --> $DIR/trait-objects.rs:13:21
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/trait-objects.rs:8:10
+ --> $DIR/trait-objects.rs:7:10
|
LL | trait StreamingIterator {
| ----------------- this trait cannot be made into an object...
diff --git a/src/test/ui/generic-associated-types/trait-objects.extended.stderr b/src/test/ui/generic-associated-types/trait-objects.extended.stderr
index 52d48d578..45b64d2b0 100644
--- a/src/test/ui/generic-associated-types/trait-objects.extended.stderr
+++ b/src/test/ui/generic-associated-types/trait-objects.extended.stderr
@@ -1,5 +1,5 @@
error[E0521]: borrowed data escapes outside of function
- --> $DIR/trait-objects.rs:16:5
+ --> $DIR/trait-objects.rs:15:5
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
| - - let's call the lifetime of this reference `'1`
@@ -11,6 +11,8 @@ LL | x.size_hint().0
| |
| `x` escapes the function body here
| argument requires that `'1` must outlive `'static`
+ |
+ = note: due to current limitations in the borrow checker, this implies a `'static` lifetime
error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/trait-objects.rs b/src/test/ui/generic-associated-types/trait-objects.rs
index c1da1e0a3..17fed11ba 100644
--- a/src/test/ui/generic-associated-types/trait-objects.rs
+++ b/src/test/ui/generic-associated-types/trait-objects.rs
@@ -1,6 +1,5 @@
// revisions: base extended
-#![feature(generic_associated_types)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
diff --git a/src/test/ui/generic-associated-types/type-param-defaults.rs b/src/test/ui/generic-associated-types/type-param-defaults.rs
new file mode 100644
index 000000000..f034076b0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/type-param-defaults.rs
@@ -0,0 +1,34 @@
+// Check that we disallow GAT param defaults, even with `invalid_type_param_default` allowed
+
+#![allow(invalid_type_param_default)]
+
+trait Trait {
+ type Assoc<T = u32>;
+ //~^ defaults for type parameters are only allowed
+}
+
+impl Trait for () {
+ type Assoc<T = u32> = u64;
+ //~^ defaults for type parameters are only allowed
+}
+
+impl Trait for u32 {
+ type Assoc<T = u32> = T;
+ //~^ defaults for type parameters are only allowed
+}
+
+trait Other {}
+impl Other for u32 {}
+
+fn foo<T>()
+where
+ T: Trait<Assoc = u32>,
+ T::Assoc: Other {
+ }
+
+fn main() {
+ // errors
+ foo::<()>();
+ // works
+ foo::<u32>();
+}
diff --git a/src/test/ui/generic-associated-types/type-param-defaults.stderr b/src/test/ui/generic-associated-types/type-param-defaults.stderr
new file mode 100644
index 000000000..85ccaba0e
--- /dev/null
+++ b/src/test/ui/generic-associated-types/type-param-defaults.stderr
@@ -0,0 +1,20 @@
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/type-param-defaults.rs:6:16
+ |
+LL | type Assoc<T = u32>;
+ | ^^^^^^^
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/type-param-defaults.rs:11:16
+ |
+LL | type Assoc<T = u32> = u64;
+ | ^^^^^^^
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/type-param-defaults.rs:16:16
+ |
+LL | type Assoc<T = u32> = T;
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
index 8b40dac57..1cc09aa6d 100644
--- a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
+++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
pub trait X {
type Y<'a: 'static>;
//~^ WARNING unnecessary lifetime parameter
diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
index ae52010cc..fbd79879d 100644
--- a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
+++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
@@ -1,5 +1,5 @@
warning: unnecessary lifetime parameter `'a`
- --> $DIR/unsatified-item-lifetime-bound.rs:4:12
+ --> $DIR/unsatified-item-lifetime-bound.rs:2:12
|
LL | type Y<'a: 'static>;
| ^^
@@ -7,39 +7,39 @@ LL | type Y<'a: 'static>;
= help: you can use the `'static` lifetime directly, in place of `'a`
error[E0478]: lifetime bound not satisfied
- --> $DIR/unsatified-item-lifetime-bound.rs:13:8
+ --> $DIR/unsatified-item-lifetime-bound.rs:11:8
|
LL | f: <T as X>::Y<'a>,
| ^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
- --> $DIR/unsatified-item-lifetime-bound.rs:12:10
+ --> $DIR/unsatified-item-lifetime-bound.rs:10:10
|
LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
| ^^
= note: but lifetime parameter must outlive the static lifetime
error[E0478]: lifetime bound not satisfied
- --> $DIR/unsatified-item-lifetime-bound.rs:18:8
+ --> $DIR/unsatified-item-lifetime-bound.rs:16:8
|
LL | f: <T as X>::Y<'a>,
| ^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
- --> $DIR/unsatified-item-lifetime-bound.rs:17:10
+ --> $DIR/unsatified-item-lifetime-bound.rs:15:10
|
LL | struct C<'a, T: X> {
| ^^
= note: but lifetime parameter must outlive the static lifetime
error[E0478]: lifetime bound not satisfied
- --> $DIR/unsatified-item-lifetime-bound.rs:23:8
+ --> $DIR/unsatified-item-lifetime-bound.rs:21:8
|
LL | f: <() as X>::Y<'a>,
| ^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
- --> $DIR/unsatified-item-lifetime-bound.rs:22:10
+ --> $DIR/unsatified-item-lifetime-bound.rs:20:10
|
LL | struct D<'a> {
| ^^
diff --git a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
index 6466bf98d..7137d9237 100644
--- a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
+++ b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait ATy {
type Item<'a>: 'a;
}
diff --git a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
index 7ec9386ca..1c9ac01ec 100644
--- a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
+++ b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
@@ -1,23 +1,23 @@
error[E0477]: the type `&'b ()` does not fulfill the required lifetime
- --> $DIR/unsatisfied-outlives-bound.rs:8:21
+ --> $DIR/unsatisfied-outlives-bound.rs:6:21
|
LL | type Item<'a> = &'b ();
| ^^^^^^
|
note: type must outlive the lifetime `'a` as defined here as required by this binding
- --> $DIR/unsatisfied-outlives-bound.rs:8:15
+ --> $DIR/unsatisfied-outlives-bound.rs:6:15
|
LL | type Item<'a> = &'b ();
| ^^
error[E0477]: the type `&'a ()` does not fulfill the required lifetime
- --> $DIR/unsatisfied-outlives-bound.rs:17:21
+ --> $DIR/unsatisfied-outlives-bound.rs:15:21
|
LL | type Item<'a> = &'a ();
| ^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
- --> $DIR/unsatisfied-outlives-bound.rs:13:20
+ --> $DIR/unsatisfied-outlives-bound.rs:11:20
|
LL | type Item<'a>: 'static;
| ^^^^^^^
diff --git a/src/test/ui/generic-associated-types/variance_constraints.rs b/src/test/ui/generic-associated-types/variance_constraints.rs
index 7d0f7638a..0e9dbb8b1 100644
--- a/src/test/ui/generic-associated-types/variance_constraints.rs
+++ b/src/test/ui/generic-associated-types/variance_constraints.rs
@@ -1,6 +1,5 @@
// check-pass
// issue #69184
-#![feature(generic_associated_types)]
trait A {
type B<'a> where Self: 'a;
diff --git a/src/test/ui/generics/issue-59508-1.rs b/src/test/ui/generics/issue-59508-1.rs
index 7e1dd7707..8e27749e8 100644
--- a/src/test/ui/generics/issue-59508-1.rs
+++ b/src/test/ui/generics/issue-59508-1.rs
@@ -8,7 +8,7 @@ struct A;
impl A {
pub fn do_things<T, 'a, 'b: 'a>() {
- //~^ ERROR lifetime parameters must be declared prior to type parameters
+ //~^ ERROR lifetime parameters must be declared prior to type and const parameters
println!("panic");
}
}
diff --git a/src/test/ui/generics/issue-59508-1.stderr b/src/test/ui/generics/issue-59508-1.stderr
index d162365ea..1c510044f 100644
--- a/src/test/ui/generics/issue-59508-1.stderr
+++ b/src/test/ui/generics/issue-59508-1.stderr
@@ -1,4 +1,4 @@
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/issue-59508-1.rs:10:25
|
LL | pub fn do_things<T, 'a, 'b: 'a>() {
diff --git a/src/test/ui/generics/issue-59508.fixed b/src/test/ui/generics/issue-59508.fixed
index b5c60a162..de8f47d4c 100644
--- a/src/test/ui/generics/issue-59508.fixed
+++ b/src/test/ui/generics/issue-59508.fixed
@@ -8,7 +8,7 @@ struct A;
impl A {
pub fn do_things<'a, 'b: 'a, T>() {
- //~^ ERROR lifetime parameters must be declared prior to type parameters
+ //~^ ERROR lifetime parameters must be declared prior to type and const parameters
println!("panic");
}
}
diff --git a/src/test/ui/generics/issue-59508.rs b/src/test/ui/generics/issue-59508.rs
index 0b39c5d8f..a4c7d4ff2 100644
--- a/src/test/ui/generics/issue-59508.rs
+++ b/src/test/ui/generics/issue-59508.rs
@@ -8,7 +8,7 @@ struct A;
impl A {
pub fn do_things<T, 'a, 'b: 'a>() {
- //~^ ERROR lifetime parameters must be declared prior to type parameters
+ //~^ ERROR lifetime parameters must be declared prior to type and const parameters
println!("panic");
}
}
diff --git a/src/test/ui/generics/issue-59508.stderr b/src/test/ui/generics/issue-59508.stderr
index c52ae4182..fd23b6276 100644
--- a/src/test/ui/generics/issue-59508.stderr
+++ b/src/test/ui/generics/issue-59508.stderr
@@ -1,4 +1,4 @@
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/issue-59508.rs:10:25
|
LL | pub fn do_things<T, 'a, 'b: 'a>() {
diff --git a/src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs
index fe3e4fbc7..0e208818e 100644
--- a/src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs
+++ b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs
@@ -1,4 +1,4 @@
#![crate_type = "lib"]
struct S<T = (), 'a>(&'a T);
-//~^ ERROR lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
diff --git a/src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr
index 119b1a0d2..70793a9c9 100644
--- a/src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr
+++ b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr
@@ -1,4 +1,4 @@
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/issue-80512-param-reordering-with-defaults.rs:3:18
|
LL | struct S<T = (), 'a>(&'a T);
diff --git a/src/test/ui/generics/issue-98432.stderr b/src/test/ui/generics/issue-98432.stderr
index afa67b63b..c7b5c3361 100644
--- a/src/test/ui/generics/issue-98432.stderr
+++ b/src/test/ui/generics/issue-98432.stderr
@@ -5,9 +5,9 @@ LL | impl<T> Struct<T> {
| - type parameter from outer function
LL | const CONST: fn() = || {
LL | struct _Obligation where T:;
- | ^ use of generic parameter from outer function
- |
- = help: try using a local generic parameter instead
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<T>`
error: aborting due to previous error
diff --git a/src/test/ui/generics/lifetime-before-type-params.rs b/src/test/ui/generics/lifetime-before-type-params.rs
index 5a71d6efe..d64b1b0b4 100644
--- a/src/test/ui/generics/lifetime-before-type-params.rs
+++ b/src/test/ui/generics/lifetime-before-type-params.rs
@@ -1,11 +1,11 @@
#![allow(unused)]
fn first<T, 'a, 'b>() {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
fn second<'a, T, 'b>() {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
fn third<T, U, 'a>() {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
fn fourth<'a, T, 'b, U, 'c, V>() {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
fn main() {}
diff --git a/src/test/ui/generics/lifetime-before-type-params.stderr b/src/test/ui/generics/lifetime-before-type-params.stderr
index 62d95e453..84825eb4c 100644
--- a/src/test/ui/generics/lifetime-before-type-params.stderr
+++ b/src/test/ui/generics/lifetime-before-type-params.stderr
@@ -1,22 +1,22 @@
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/lifetime-before-type-params.rs:2:13
|
LL | fn first<T, 'a, 'b>() {}
| ----^^--^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/lifetime-before-type-params.rs:4:18
|
LL | fn second<'a, T, 'b>() {}
| --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/lifetime-before-type-params.rs:6:16
|
LL | fn third<T, U, 'a>() {}
| -------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, U>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/lifetime-before-type-params.rs:8:18
|
LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
diff --git a/src/test/ui/hashmap/hashmap-index-mut.rs b/src/test/ui/hashmap/hashmap-index-mut.rs
new file mode 100644
index 000000000..98448e9d5
--- /dev/null
+++ b/src/test/ui/hashmap/hashmap-index-mut.rs
@@ -0,0 +1,6 @@
+use std::collections::HashMap;
+
+fn main() {
+ let mut map = HashMap::<u32, u32>::new();
+ map[&0] = 1; //~ ERROR cannot assign
+}
diff --git a/src/test/ui/hashmap/hashmap-index-mut.stderr b/src/test/ui/hashmap/hashmap-index-mut.stderr
new file mode 100644
index 000000000..c1948ab62
--- /dev/null
+++ b/src/test/ui/hashmap/hashmap-index-mut.stderr
@@ -0,0 +1,19 @@
+error[E0594]: cannot assign to data in an index of `HashMap<u32, u32>`
+ --> $DIR/hashmap-index-mut.rs:5:5
+ |
+LL | map[&0] = 1;
+ | ^^^^^^^^^^^ cannot assign
+ |
+ = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `HashMap<u32, u32>`
+help: to modify a `HashMap<u32, u32>`, use `.get_mut()`, `.insert()` or the entry API
+ |
+LL | map.insert(&0, 1);
+ | ~~~~~~~~ ~ +
+LL | map.get_mut(&0).map(|val| { *val = 1; });
+ | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ++++
+LL | let val = map.entry(&0).or_insert(1);
+ | +++++++++ ~~~~~~~ ~~~~~~~~~~~~ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/hrtb/complex.rs b/src/test/ui/higher-rank-trait-bounds/complex.rs
index 8cdfe247e..8cdfe247e 100644
--- a/src/test/ui/hrtb/complex.rs
+++ b/src/test/ui/higher-rank-trait-bounds/complex.rs
diff --git a/src/test/ui/hrtb/due-to-where-clause.rs b/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.rs
index 1afd15613..1afd15613 100644
--- a/src/test/ui/hrtb/due-to-where-clause.rs
+++ b/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.rs
diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.stderr
index 520938a63..520938a63 100644
--- a/src/test/ui/hrtb/due-to-where-clause.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/due-to-where-clause.stderr
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs
index a20d03c77..a20d03c77 100644
--- a/src/test/ui/hrtb/hrtb-cache-issue-54302.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr
index f014eab86..f014eab86 100644
--- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs
index e83686404..e83686404 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr
index 46f5308dd..46f5308dd 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr
diff --git a/src/test/ui/hrtb/hrtb-debruijn-in-receiver.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs
index 05d3e1a43..05d3e1a43 100644
--- a/src/test/ui/hrtb/hrtb-debruijn-in-receiver.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs
diff --git a/src/test/ui/hrtb/hrtb-debruijn-in-receiver.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr
index fa391ecba..fa391ecba 100644
--- a/src/test/ui/hrtb/hrtb-debruijn-in-receiver.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs
index 567802376..567802376 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-fn.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr
index 9914783d9..9914783d9 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs
index 921061916..921061916 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr
index 364b613fc..364b613fc 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs
index f95496a6c..f95496a6c 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs
index 9b9e4496a..9b9e4496a 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr
index cb2ce8a41..cb2ce8a41 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs
index f9ae1429e..f9ae1429e 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
index 8cda76b94..8cda76b94 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs
index 48ebe5017..48ebe5017 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
index 88793a152..88793a152 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs
index 89fc4705a..89fc4705a 100644
--- a/src/test/ui/hrtb/hrtb-identity-fn-borrows.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
index 4886a3c8b..4886a3c8b 100644
--- a/src/test/ui/hrtb/hrtb-identity-fn-borrows.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs
index 8fb4218f8..8fb4218f8 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr
index b4312091e..31e11e128 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr
@@ -14,6 +14,12 @@ LL | fn give_some<'a>() {
| -- lifetime `'a` defined here
LL | want_hrtb::<&'a u32>()
| ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/hrtb-just-for-static.rs:9:15
+ |
+LL | where T : for<'a> Foo<&'a isize>
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:30:5
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr
index a94c80eb3..a94c80eb3 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs
index d45fa183c..d45fa183c 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
index 1461e7fd2..5e75a4cc8 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
@@ -46,6 +46,12 @@ LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
...
LL | foo_hrtb_bar_not(&mut t);
| ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/hrtb-perfect-forwarding.rs:37:8
+ |
+LL | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: implementation of `Bar` is not general enough
--> $DIR/hrtb-perfect-forwarding.rs:43:5
diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/higher-rank-trait-bounds/issue-30786.rs
index e5f46f711..e5f46f711 100644
--- a/src/test/ui/hrtb/issue-30786.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-30786.rs
diff --git a/src/test/ui/hrtb/issue-30786.stderr b/src/test/ui/higher-rank-trait-bounds/issue-30786.stderr
index bc7b5e914..ffe3d7b81 100644
--- a/src/test/ui/hrtb/issue-30786.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/issue-30786.stderr
@@ -18,10 +18,6 @@ note: the following trait bounds were not satisfied:
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here
-help: one of the expressions' fields has a method of the same name
- |
-LL | let filter = map.stream.filterx(|x: &_| true);
- | +++++++
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:130:24
@@ -43,10 +39,6 @@ note: the following trait bounds were not satisfied:
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here
-help: one of the expressions' fields has a method of the same name
- |
-LL | let count = filter.stream.countx();
- | +++++++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/hrtb/issue-46989.rs b/src/test/ui/higher-rank-trait-bounds/issue-46989.rs
index 4a09f4be1..4a09f4be1 100644
--- a/src/test/ui/hrtb/issue-46989.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-46989.rs
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/higher-rank-trait-bounds/issue-46989.stderr
index 309e1a676..309e1a676 100644
--- a/src/test/ui/hrtb/issue-46989.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/issue-46989.stderr
diff --git a/src/test/ui/hrtb/issue-57639.rs b/src/test/ui/higher-rank-trait-bounds/issue-57639.rs
index 392e7233b..392e7233b 100644
--- a/src/test/ui/hrtb/issue-57639.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-57639.rs
diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/higher-rank-trait-bounds/issue-58451.rs
index f36d549e4..f36d549e4 100644
--- a/src/test/ui/hrtb/issue-58451.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-58451.rs
diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/higher-rank-trait-bounds/issue-58451.stderr
index 22ba63c3e..09e25f4dc 100644
--- a/src/test/ui/hrtb/issue-58451.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/issue-58451.stderr
@@ -12,7 +12,7 @@ LL | fn f<I>(i: I)
help: provide the argument
|
LL | f(&[f(/* value */)]);
- | ~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.rs b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs
index 80f099ce3..e70f6fc34 100644
--- a/src/test/ui/hrtb/issue-62203-hrtb-ice.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs
@@ -36,11 +36,15 @@ trait Ty<'a> {
fn main() {
let v = Unit2.m(
- //~^ ERROR type mismatch
L {
- //~^ ERROR type mismatch
- f : |x| { drop(x); Unit4 }
- });
+ //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
+ //~| ERROR type mismatch
+ f: |x| {
+ drop(x);
+ Unit4
+ },
+ },
+ );
}
impl<'a> Ty<'a> for Unit2 {
diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
index 79ef56b9f..ab5598e36 100644
--- a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
@@ -1,8 +1,16 @@
-error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
- --> $DIR/issue-62203-hrtb-ice.rs:38:19
+error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
+ --> $DIR/issue-62203-hrtb-ice.rs:39:9
|
-LL | let v = Unit2.m(
- | ^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
+LL | let v = Unit2.m(
+ | - required by a bound introduced by this call
+LL | / L {
+LL | |
+LL | |
+LL | | f: |x| {
+... |
+LL | | },
+LL | | },
+ | |_________^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
|
note: expected this to be `<_ as Ty<'_>>::V`
--> $DIR/issue-62203-hrtb-ice.rs:21:14
@@ -22,19 +30,21 @@ LL | where
LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
-error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20] as FnOnce<((&'r u8,),)>>::Output == Unit3`
- --> $DIR/issue-62203-hrtb-ice.rs:40:9
+error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4`
+ --> $DIR/issue-62203-hrtb-ice.rs:39:9
|
LL | let v = Unit2.m(
| - required by a bound introduced by this call
-LL |
LL | / L {
LL | |
-LL | | f : |x| { drop(x); Unit4 }
-LL | | });
+LL | |
+LL | | f: |x| {
+... |
+LL | | },
+LL | | },
| |_________^ expected struct `Unit3`, found struct `Unit4`
|
-note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20]>`
+note: required for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>` to implement `for<'r> T0<'r, (&'r u8,)>`
--> $DIR/issue-62203-hrtb-ice.rs:17:16
|
LL | impl<'a, A, T> T0<'a, A> for L<T>
diff --git a/src/test/ui/hrtb/issue-88446.rs b/src/test/ui/higher-rank-trait-bounds/issue-88446.rs
index 571b85317..571b85317 100644
--- a/src/test/ui/hrtb/issue-88446.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-88446.rs
diff --git a/src/test/ui/hrtb/issue-90177.rs b/src/test/ui/higher-rank-trait-bounds/issue-90177.rs
index b151a9d3a..b151a9d3a 100644
--- a/src/test/ui/hrtb/issue-90177.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-90177.rs
diff --git a/src/test/ui/hrtb/issue-95034.rs b/src/test/ui/higher-rank-trait-bounds/issue-95034.rs
index d8edbe7e5..d8edbe7e5 100644
--- a/src/test/ui/hrtb/issue-95034.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-95034.rs
diff --git a/src/test/ui/hrtb/issue-95034.stderr b/src/test/ui/higher-rank-trait-bounds/issue-95034.stderr
index 1d8329142..1d8329142 100644
--- a/src/test/ui/hrtb/issue-95034.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/issue-95034.stderr
diff --git a/src/test/ui/hrtb/issue-95230.rs b/src/test/ui/higher-rank-trait-bounds/issue-95230.rs
index 92c506eab..92c506eab 100644
--- a/src/test/ui/hrtb/issue-95230.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-95230.rs
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr
index 066bf431a..b30dd36d2 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr
@@ -1,8 +1,10 @@
error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
- --> $DIR/issue-62529-3.rs:25:9
+ --> $DIR/issue-62529-3.rs:25:14
|
LL | call(f, ());
- | ^^^^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
+ | ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
+ | |
+ | required by a bound introduced by this call
|
= note: expected a closure with arguments `((),)`
found a closure with arguments `(<_ as ATC<'a>>::Type,)`
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs
index 172bf218c..de9348f53 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs
@@ -7,7 +7,6 @@ trait SomeTrait<'a> {
fn give_me_ice<T>() {
callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
//~^ ERROR the trait bound `for<'r> T: SomeTrait<'r>` is not satisfied [E0277]
- //~| ERROR the trait bound `for<'r> T: SomeTrait<'r>` is not satisfied [E0277]
}
fn callee<T: Fn<(&'static (),)>>() {
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr
index ecca4b999..6a948a116 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr
@@ -9,17 +9,6 @@ help: consider restricting type parameter `T`
LL | fn give_me_ice<T: for<'r> SomeTrait<'r>>() {
| +++++++++++++++++++++++
-error[E0277]: the trait bound `for<'r> T: SomeTrait<'r>` is not satisfied
- --> $DIR/issue-85455.rs:8:14
- |
-LL | callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'r> SomeTrait<'r>` is not implemented for `T`
- |
-help: consider restricting type parameter `T`
- |
-LL | fn give_me_ice<T: for<'r> SomeTrait<'r>>() {
- | +++++++++++++++++++++++
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
index a6858154d..14fe1803b 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
LL | C: StackContext,
| ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
-note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
+note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>`
--> $DIR/issue-89118.rs:5:23
|
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
@@ -24,7 +24,7 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
LL | impl<C> EthernetWorker<C> {}
| ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
-note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
+note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>`
--> $DIR/issue-89118.rs:5:23
|
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
@@ -44,7 +44,7 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
LL | type Handler = Ctx<C::Dispatcher>;
| ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
-note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
+note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>`
--> $DIR/issue-89118.rs:5:23
|
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs
index e150ecfe9..effc32945 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(generic_associated_types)]
-
use std::marker::PhantomData;
trait Family: Sized {
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs
index 18b7f3834..628b5cba1 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs
@@ -1,7 +1,5 @@
//check-pass
-#![feature(generic_associated_types)]
-
trait Yokeable<'a>: 'static {
type Output: 'a;
}
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index 634ff1486..b6e283647 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -29,6 +29,11 @@ note: ...which requires building MIR for `cycle1`...
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires building THIR for `cycle1`...
+ --> $DIR/auto-trait-leak.rs:12:1
+ |
+LL | fn cycle1() -> impl Clone {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:14:5
|
@@ -65,6 +70,11 @@ note: ...which requires building MIR for `cycle2`...
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires building THIR for `cycle2`...
+ --> $DIR/auto-trait-leak.rs:19:1
+ |
+LL | fn cycle2() -> impl Clone {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:5
|
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index f14b447b0..d4a349551 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -12,10 +12,15 @@ error[E0308]: mismatched types
--> $DIR/equality.rs:15:5
|
LL | fn two(x: bool) -> impl Foo {
- | -------- expected `_` because of return type
+ | -------- expected `i32` because of return type
...
LL | 0_u32
| ^^^^^ expected `i32`, found `u32`
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 0_i32
+ | ~~~
error[E0277]: cannot add `impl Foo` to `u32`
--> $DIR/equality.rs:24:11
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
index c01c33a89..8f4092273 100644
--- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
+++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
@@ -6,9 +6,8 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
|
help: add `dyn` keyword before this trait
|
-LL - fn ice() -> impl AsRef<Fn(&())> {
-LL + fn ice() -> impl AsRef<dyn Fn(&())> {
- |
+LL | fn ice() -> impl AsRef<dyn Fn(&())> {
+ | +++
error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied
--> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.rs b/src/test/ui/impl-trait/impl-generic-mismatch.rs
index ba678bb03..fb8bde0d0 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.rs
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.rs
@@ -18,6 +18,15 @@ impl Bar for () {
//~^ Error method `bar` has incompatible signature for trait
}
+trait Baz {
+ fn baz<U: Debug, T: Debug>(&self, _: &U, _: &T);
+}
+
+impl Baz for () {
+ fn baz<T: Debug>(&self, _: &impl Debug, _: &T) { }
+ //~^ Error method `baz` has incompatible signature for trait
+}
+
// With non-local trait (#49841):
use std::hash::{Hash, Hasher};
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.stderr b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
index 489afd761..542f02d7e 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
@@ -27,8 +27,22 @@ help: try changing the `impl Trait` argument to a generic parameter
LL | fn bar<U: Debug>(&self, _: &U) { }
| ++++++++++ ~
+error[E0643]: method `baz` has incompatible signature for trait
+ --> $DIR/impl-generic-mismatch.rs:26:33
+ |
+LL | fn baz<U: Debug, T: Debug>(&self, _: &U, _: &T);
+ | - declaration in trait here
+...
+LL | fn baz<T: Debug>(&self, _: &impl Debug, _: &T) { }
+ | ^^^^^^^^^^ expected generic parameter, found `impl Trait`
+ |
+help: try changing the `impl Trait` argument to a generic parameter
+ |
+LL | fn baz<U: Debug, T: Debug>(&self, _: &T, _: &T) { }
+ | ~~~~~~~~~~~~~~~~~~~~ ~
+
error[E0643]: method `hash` has incompatible signature for trait
- --> $DIR/impl-generic-mismatch.rs:28:33
+ --> $DIR/impl-generic-mismatch.rs:37:33
|
LL | fn hash(&self, hasher: &mut impl Hasher) {}
| ^^^^^^^^^^^ expected generic parameter, found `impl Trait`
@@ -38,6 +52,6 @@ LL | fn hash(&self, hasher: &mut impl Hasher) {}
LL | fn hash<H: Hasher>(&self, state: &mut H);
| - declaration in trait here
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0643`.
diff --git a/src/test/ui/impl-trait/in-trait/deep-match-works.rs b/src/test/ui/impl-trait/in-trait/deep-match-works.rs
new file mode 100644
index 000000000..772da845e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/deep-match-works.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+struct Wrapper<T>(T);
+
+trait Foo {
+ fn bar() -> Wrapper<impl Sized>;
+}
+
+impl Foo for () {
+ fn bar() -> Wrapper<i32> { Wrapper(0) }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/deep-match.rs b/src/test/ui/impl-trait/in-trait/deep-match.rs
new file mode 100644
index 000000000..a6385147c
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/deep-match.rs
@@ -0,0 +1,15 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+struct Wrapper<T>(T);
+
+trait Foo {
+ fn bar() -> Wrapper<impl Sized>;
+}
+
+impl Foo for () {
+ fn bar() -> i32 { 0 }
+ //~^ ERROR method `bar` has an incompatible return type for trait
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/deep-match.stderr b/src/test/ui/impl-trait/in-trait/deep-match.stderr
new file mode 100644
index 000000000..034ee5ea4
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/deep-match.stderr
@@ -0,0 +1,15 @@
+error[E0053]: method `bar` has an incompatible return type for trait
+ --> $DIR/deep-match.rs:11:17
+ |
+LL | fn bar() -> i32 { 0 }
+ | ^^^
+ | |
+ | expected struct `Wrapper`, found `i32`
+ | return type in trait
+ |
+ = note: expected struct `Wrapper<_>`
+ found type `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs
new file mode 100644
index 000000000..bb4e0d44f
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs
@@ -0,0 +1,13 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ fn bar() -> impl std::fmt::Display;
+}
+
+impl Foo for () {
+ fn bar() -> () {}
+ //~^ ERROR `()` doesn't implement `std::fmt::Display`
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr
new file mode 100644
index 000000000..aa5492d28
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `()` doesn't implement `std::fmt::Display`
+ --> $DIR/doesnt-satisfy.rs:9:17
+ |
+LL | fn bar() -> () {}
+ | ^^ `()` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `()`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Foo::bar::{opaque#0}`
+ --> $DIR/doesnt-satisfy.rs:5:22
+ |
+LL | fn bar() -> impl std::fmt::Display;
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/in-trait/encode.rs b/src/test/ui/impl-trait/in-trait/encode.rs
new file mode 100644
index 000000000..efb9f6498
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/encode.rs
@@ -0,0 +1,9 @@
+// build-pass
+// compile-flags: --crate-type=lib
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ fn bar() -> impl Sized;
+}
diff --git a/src/test/ui/impl-trait/in-trait/nested-rpitit.rs b/src/test/ui/impl-trait/in-trait/nested-rpitit.rs
new file mode 100644
index 000000000..65285e3a3
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/nested-rpitit.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+use std::ops::Deref;
+
+trait Foo {
+ fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
+}
+
+struct A;
+
+impl Foo for A {
+ fn bar(self) -> &'static str {
+ "Hello, world"
+ }
+}
+
+struct B;
+
+impl Foo for B {
+ fn bar(self) -> Box<i32> {
+ Box::new(42)
+ }
+}
+
+fn main() {
+ println!("Message for you: {:?}", &*A.bar());
+ println!("Another for you: {:?}", &*B.bar());
+}
diff --git a/src/test/ui/impl-trait/in-trait/object-safety.rs b/src/test/ui/impl-trait/in-trait/object-safety.rs
new file mode 100644
index 000000000..dd35b9a2d
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/object-safety.rs
@@ -0,0 +1,22 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {
+ fn baz(&self) -> impl Debug;
+}
+
+impl Foo for u32 {
+ fn baz(&self) -> u32 {
+ 32
+ }
+}
+
+fn main() {
+ let i = Box::new(42_u32) as Box<dyn Foo>;
+ //~^ ERROR the trait `Foo` cannot be made into an object
+ //~| ERROR the trait `Foo` cannot be made into an object
+ let s = i.baz();
+ //~^ ERROR the trait `Foo` cannot be made into an object
+}
diff --git a/src/test/ui/impl-trait/in-trait/object-safety.stderr b/src/test/ui/impl-trait/in-trait/object-safety.stderr
new file mode 100644
index 000000000..9a1554b5e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/object-safety.stderr
@@ -0,0 +1,50 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety.rs:17:33
+ |
+LL | let i = Box::new(42_u32) as Box<dyn Foo>;
+ | ^^^^^^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety.rs:7:8
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn baz(&self) -> impl Debug;
+ | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety.rs:20:13
+ |
+LL | let s = i.baz();
+ | ^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety.rs:7:8
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn baz(&self) -> impl Debug;
+ | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety.rs:17:13
+ |
+LL | let i = Box::new(42_u32) as Box<dyn Foo>;
+ | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety.rs:7:8
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn baz(&self) -> impl Debug;
+ | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ = help: consider moving `baz` to another trait
+ = note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
+ = note: required by cast to type `Box<dyn Foo>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
new file mode 100644
index 000000000..3ac264e8e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
@@ -0,0 +1,19 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+
+trait Foo {
+ fn bar(&self) -> impl Display;
+}
+
+impl Foo for () {
+ fn bar(&self) -> impl Display {
+ "Hello, world"
+ }
+}
+
+fn main() {
+ let x: &str = ().bar();
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr
new file mode 100644
index 000000000..15edda483
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+ --> $DIR/opaque-in-impl-is-opaque.rs:17:19
+ |
+LL | fn bar(&self) -> impl Display {
+ | ------------ the found opaque type
+...
+LL | let x: &str = ().bar();
+ | ---- ^^^^^^^^ expected `&str`, found opaque type
+ | |
+ | expected due to this
+ |
+ = note: expected reference `&str`
+ found opaque type `impl std::fmt::Display`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
new file mode 100644
index 000000000..2e0662969
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
@@ -0,0 +1,48 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {
+ fn foo(&self) -> impl Debug;
+}
+
+impl Foo for () {
+ fn foo(&self) -> impl Debug {
+ "Hello, world"
+ }
+}
+
+impl<T: Default + Debug> Foo for std::marker::PhantomData<T> {
+ fn foo(&self) -> impl Debug {
+ T::default()
+ }
+}
+
+trait Bar {
+ fn bar<T>(&self) -> impl Debug;
+}
+
+impl Bar for () {
+ fn bar<T>(&self) -> impl Debug {
+ format!("Hello with generic {}", std::any::type_name::<T>())
+ }
+}
+
+trait Baz {
+ fn baz(&self) -> impl Debug + '_;
+}
+
+impl Baz for String {
+ fn baz(&self) -> impl Debug + '_ {
+ (self,)
+ }
+}
+
+fn main() {
+ println!("{:?}", ().foo());
+ println!("{:?}", ().bar::<u64>());
+ println!("{:?}", "hi".to_string().baz());
+}
diff --git a/src/test/ui/impl-trait/in-trait/reveal.rs b/src/test/ui/impl-trait/in-trait/reveal.rs
new file mode 100644
index 000000000..d6ede1cc4
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/reveal.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ fn f() -> Box<impl Sized>;
+}
+
+impl Foo for () {
+ fn f() -> Box<String> {
+ Box::new(String::new())
+ }
+}
+
+fn main() {
+ let x: Box<String> = <() as Foo>::f();
+}
diff --git a/src/test/ui/impl-trait/in-trait/success.rs b/src/test/ui/impl-trait/in-trait/success.rs
new file mode 100644
index 000000000..4cbe682b4
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/success.rs
@@ -0,0 +1,40 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+
+trait Foo {
+ fn bar(&self) -> impl Display;
+}
+
+impl Foo for i32 {
+ fn bar(&self) -> i32 {
+ *self
+ }
+}
+
+impl Foo for &'static str {
+ fn bar(&self) -> &'static str {
+ *self
+ }
+}
+
+struct Yay;
+
+impl Foo for Yay {
+ fn bar(&self) -> String {
+ String::from(":^)")
+ }
+}
+
+fn foo_generically<T: Foo>(t: T) {
+ println!("{}", t.bar());
+}
+
+fn main() {
+ println!("{}", "Hello, world.".bar());
+ println!("The answer is {}!", 42.bar());
+ foo_generically(Yay);
+}
diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.rs b/src/test/ui/impl-trait/in-trait/wf-bounds.rs
new file mode 100644
index 000000000..2c71583b3
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/wf-bounds.rs
@@ -0,0 +1,16 @@
+// issue #101663
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Wf<T> {}
+
+trait Uwu {
+ fn nya() -> impl Wf<Vec<[u8]>>;
+ //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+
+ fn nya2() -> impl Wf<[u8]>;
+ //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.stderr b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr
new file mode 100644
index 000000000..92e36841b
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/wf-bounds.rs:9:22
+ |
+LL | fn nya() -> impl Wf<Vec<[u8]>>;
+ | ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `Vec`
+ --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ |
+LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
+ | ^ required by this bound in `Vec`
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/wf-bounds.rs:12:23
+ |
+LL | fn nya2() -> impl Wf<[u8]>;
+ | ^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `Wf`
+ --> $DIR/wf-bounds.rs:6:10
+ |
+LL | trait Wf<T> {}
+ | ^ required by this bound in `Wf`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Wf<T: ?Sized> {}
+ | ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/issue-100075-2.rs b/src/test/ui/impl-trait/issue-100075-2.rs
new file mode 100644
index 000000000..cf059af19
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-100075-2.rs
@@ -0,0 +1,8 @@
+fn opaque<T>(t: T) -> impl Sized {
+ //~^ ERROR cannot resolve opaque type
+ //~| WARNING function cannot return without recursing
+ opaque(Some(t))
+}
+
+#[allow(dead_code)]
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-100075-2.stderr b/src/test/ui/impl-trait/issue-100075-2.stderr
new file mode 100644
index 000000000..5a1f1a97d
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-100075-2.stderr
@@ -0,0 +1,24 @@
+warning: function cannot return without recursing
+ --> $DIR/issue-100075-2.rs:1:1
+ |
+LL | fn opaque<T>(t: T) -> impl Sized {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+...
+LL | opaque(Some(t))
+ | --------------- recursive call site
+ |
+ = note: `#[warn(unconditional_recursion)]` on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+error[E0720]: cannot resolve opaque type
+ --> $DIR/issue-100075-2.rs:1:23
+ |
+LL | fn opaque<T>(t: T) -> impl Sized {
+ | ^^^^^^^^^^ recursive opaque type
+...
+LL | opaque(Some(t))
+ | --------------- returning here with type `impl Sized`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/issue-100075.rs b/src/test/ui/impl-trait/issue-100075.rs
new file mode 100644
index 000000000..ea30abb48
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-100075.rs
@@ -0,0 +1,21 @@
+trait Marker {}
+impl<T> Marker for T {}
+
+fn maybe<T>(
+ _t: T,
+) -> Option<
+ //removing the line below makes it compile
+ &'static T,
+> {
+ None
+}
+
+fn _g<T>(t: &'static T) -> &'static impl Marker {
+ //~^ ERROR cannot resolve opaque type
+ if let Some(t) = maybe(t) {
+ return _g(t);
+ }
+ todo!()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-100075.stderr b/src/test/ui/impl-trait/issue-100075.stderr
new file mode 100644
index 000000000..267ecfdae
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-100075.stderr
@@ -0,0 +1,12 @@
+error[E0720]: cannot resolve opaque type
+ --> $DIR/issue-100075.rs:13:37
+ |
+LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
+ | ^^^^^^^^^^^ recursive opaque type
+...
+LL | return _g(t);
+ | ----- returning here with type `&impl Marker`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/issue-103599.rs b/src/test/ui/impl-trait/issue-103599.rs
new file mode 100644
index 000000000..043ae67f2
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-103599.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+trait T {}
+
+fn wrap(x: impl T) -> impl T {
+ //~^ WARN function cannot return without recursing
+ wrap(wrap(x))
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-103599.stderr b/src/test/ui/impl-trait/issue-103599.stderr
new file mode 100644
index 000000000..79fb355dd
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-103599.stderr
@@ -0,0 +1,14 @@
+warning: function cannot return without recursing
+ --> $DIR/issue-103599.rs:5:1
+ |
+LL | fn wrap(x: impl T) -> impl T {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL |
+LL | wrap(wrap(x))
+ | ------- recursive call site
+ |
+ = note: `#[warn(unconditional_recursion)]` on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/issue-99914.rs b/src/test/ui/impl-trait/issue-99914.rs
new file mode 100644
index 000000000..4324a0229
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-99914.rs
@@ -0,0 +1,13 @@
+// edition:2021
+
+fn main() {}
+
+struct Error;
+struct Okay;
+
+fn foo(t: Result<Okay, Error>) {
+ t.and_then(|t| -> _ { bar(t) });
+ //~^ ERROR mismatched types
+}
+
+async fn bar(t: Okay) {}
diff --git a/src/test/ui/impl-trait/issue-99914.stderr b/src/test/ui/impl-trait/issue-99914.stderr
new file mode 100644
index 000000000..074d5d58d
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-99914.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-99914.rs:9:27
+ |
+LL | t.and_then(|t| -> _ { bar(t) });
+ | ^^^^^^ expected enum `Result`, found opaque type
+ |
+note: while checking the return type of the `async fn`
+ --> $DIR/issue-99914.rs:13:23
+ |
+LL | async fn bar(t: Okay) {}
+ | ^ checked the `Output` of this `async fn`, found opaque type
+ = note: expected enum `Result<_, Error>`
+ found opaque type `impl Future<Output = ()>`
+help: try wrapping the expression in `Ok`
+ |
+LL | t.and_then(|t| -> _ { Ok(bar(t)) });
+ | +++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/issues/issue-78722.rs b/src/test/ui/impl-trait/issues/issue-78722.rs
index 002e4cde4..90d1cd379 100644
--- a/src/test/ui/impl-trait/issues/issue-78722.rs
+++ b/src/test/ui/impl-trait/issues/issue-78722.rs
@@ -7,7 +7,7 @@ type F = impl core::future::Future<Output = u8>;
struct Bug {
V1: [(); {
fn concrete_use() -> F {
- //~^ ERROR type mismatch
+ //~^ ERROR expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
async {}
}
let f: F = async { 1 };
diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr
index 690d6abc7..9a0ffbc89 100644
--- a/src/test/ui/impl-trait/issues/issue-78722.stderr
+++ b/src/test/ui/impl-trait/issues/issue-78722.stderr
@@ -16,7 +16,7 @@ LL | let f: F = async { 1 };
LL | }],
| - value is dropped here
-error[E0271]: type mismatch resolving `<impl Future<Output = ()> as Future>::Output == u8`
+error[E0271]: expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722.rs:9:30
|
LL | fn concrete_use() -> F {
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait2.stderr b/src/test/ui/impl-trait/nested-return-type2-tait2.stderr
index fe1ae4fcb..348c737b0 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait2.stderr
+++ b/src/test/ui/impl-trait/nested-return-type2-tait2.stderr
@@ -5,7 +5,7 @@ LL | || 42
| ^^^^^ the trait `Duh` is not implemented for `Sendable`
|
= help: the trait `Duh` is implemented for `i32`
-note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]`
+note: required for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]` to implement `Trait`
--> $DIR/nested-return-type2-tait2.rs:14:31
|
LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait3.stderr b/src/test/ui/impl-trait/nested-return-type2-tait3.stderr
index c0695d627..6ac671415 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait3.stderr
+++ b/src/test/ui/impl-trait/nested-return-type2-tait3.stderr
@@ -5,7 +5,7 @@ LL | || 42
| ^^^^^ the trait `Duh` is not implemented for `impl Send`
|
= help: the trait `Duh` is implemented for `i32`
-note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]`
+note: required for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]` to implement `Trait`
--> $DIR/nested-return-type2-tait3.rs:14:31
|
LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
diff --git a/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs
new file mode 100644
index 000000000..287a030cf
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+pub struct VecNumber<'s> {
+ pub vec_number: Vec<Number<'s>>,
+ pub auxiliary_object: &'s Vec<usize>,
+}
+
+pub struct Number<'s> {
+ pub number: &'s usize,
+}
+
+impl<'s> VecNumber<'s> {
+ pub fn vec_number_iterable_per_item_in_auxiliary_object(
+ &self,
+ ) -> impl Iterator<Item = (&'s usize, impl Iterator<Item = &Number<'s>>)> {
+ self.auxiliary_object.iter().map(move |n| {
+ let iter_number = self.vec_number.iter();
+ (n, iter_number)
+ })
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr
index bb4ae5e82..3291cad68 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.stderr
+++ b/src/test/ui/impl-trait/nested_impl_trait.stderr
@@ -53,7 +53,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
|
= help: the trait `Into<U>` is implemented for `T`
- = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
+ = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
--> $DIR/nested_impl_trait.rs:18:34
@@ -62,7 +62,7 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
|
= help: the trait `Into<U>` is implemented for `T`
- = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
+ = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
error: aborting due to 8 previous errors
diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
index 365ecd9fc..687dbe65e 100644
--- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
+++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
@@ -21,10 +21,10 @@ LL | fn foo() -> Self where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
- --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13
+ --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:17
|
LL | fn cat() -> Box<dyn NotObjectSafe> {
- | ^^^^^^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8
diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
index 5ca01a593..d6f5a1ac2 100644
--- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
+++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5
|
LL | fn can() -> impl NotObjectSafe {
- | ------------------ expected `_` because of return type
+ | ------------------ expected `A` because of return type
...
LL | B
| ^ expected struct `A`, found struct `B`
@@ -11,7 +11,7 @@ error[E0308]: mismatched types
--> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5
|
LL | fn cat() -> impl ObjectSafe {
- | --------------- expected `_` because of return type
+ | --------------- expected `A` because of return type
...
LL | B
| ^ expected struct `A`, found struct `B`
diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
index 10510c175..3c65fd998 100644
--- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -2,28 +2,43 @@ error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
|
LL | fn foo() -> impl std::fmt::Display {
- | ---------------------- expected `_` because of return type
+ | ---------------------- expected `i32` because of return type
...
LL | 1u32
| ^^^^ expected `i32`, found `u32`
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 1i32
+ | ~~~
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16
|
LL | fn bar() -> impl std::fmt::Display {
- | ---------------------- expected `_` because of return type
+ | ---------------------- expected `i32` because of return type
...
LL | return 1u32;
| ^^^^ expected `i32`, found `u32`
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | return 1i32;
+ | ~~~
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9
|
LL | fn baz() -> impl std::fmt::Display {
- | ---------------------- expected `_` because of return type
+ | ---------------------- expected `i32` because of return type
...
LL | 1u32
| ^^^^ expected `i32`, found `u32`
+ |
+help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
+ |
+LL | }.try_into().unwrap()
+ | ++++++++++++++++++++
error[E0308]: `if` and `else` have incompatible types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9
@@ -36,36 +51,66 @@ LL | | 1u32
| | ^^^^ expected `i32`, found `u32`
LL | | }
| |_____- `if` and `else` have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn qux() -> Box<dyn std::fmt::Display> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ Box::new(0i32)
+LL | } else {
+LL ~ Box::new(1u32)
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 1i32
+ | ~~~
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14
|
LL | fn bat() -> impl std::fmt::Display {
- | ---------------------- expected `_` because of return type
+ | ---------------------- expected `i32` because of return type
...
LL | _ => 1u32,
| ^^^^ expected `i32`, found `u32`
+ |
+help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
+ |
+LL | }.try_into().unwrap()
+ | ++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5
|
LL | fn can() -> impl std::fmt::Display {
- | ---------------------- expected `_` because of return type
+ | ---------------------- expected `i32` because of return type
LL | / match 13 {
LL | | 0 => return 0i32,
LL | | 1 => 1u32,
LL | | _ => 2u32,
LL | | }
| |_____^ expected `i32`, found `u32`
+ |
+help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
+ |
+LL | }.try_into().unwrap()
+ | ++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13
|
LL | fn cat() -> impl std::fmt::Display {
- | ---------------------- expected `_` because of return type
+ | ---------------------- expected `i32` because of return type
...
LL | 1u32
| ^^^^ expected `i32`, found `u32`
+ |
+help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
+ |
+LL | }.try_into().unwrap()
+ | ++++++++++++++++++++
error[E0308]: `match` arms have incompatible types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14
@@ -78,6 +123,20 @@ LL | | 1 => 1u32,
LL | | _ => 2u32,
LL | | }
| |_____- `match` arms have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn dog() -> Box<dyn std::fmt::Display> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ 0 => Box::new(0i32),
+LL ~ 1 => Box::new(1u32),
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 1 => 1i32,
+ | ~~~
error[E0308]: `if` and `else` have incompatible types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:97:9
@@ -90,6 +149,21 @@ LL | | 1u32
| | ^^^^ expected `i32`, found `u32`
LL | | }
| |_____- `if` and `else` have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn apt() -> Box<dyn std::fmt::Display> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ Box::new(0i32)
+LL | } else {
+LL ~ Box::new(1u32)
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 1i32
+ | ~~~
error[E0746]: return type cannot have an unboxed trait object
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13
@@ -125,6 +199,11 @@ LL | | 1 => 1u32,
LL | | _ => 2u32,
LL | | }
| |_____- `match` arms have incompatible types
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 1 => 1i32,
+ | ~~~
error[E0746]: return type cannot have an unboxed trait object
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
@@ -164,6 +243,11 @@ LL | | 1u32
| | ^^^^ expected `i32`, found `u32`
LL | | }
| |_____- `if` and `else` have incompatible types
+ |
+help: change the type of the numeric literal from `u32` to `i32`
+ |
+LL | 1i32
+ | ~~~
error[E0746]: return type cannot have an unboxed trait object
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13
diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
index ade0dfa1b..cf2998bbf 100644
--- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
+++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
@@ -9,7 +9,7 @@ note: expected this to be `u8`
|
LL | type Assoc = u8;
| ^^
-note: required because of the requirements on the impl of `Test` for `()`
+note: required for `()` to implement `Test`
--> $DIR/projection-mismatch-in-impl-where-clause.rs:11:9
|
LL | impl<T> Test for T where T: Super<Assoc = ()> {}
diff --git a/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr b/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr
index 2a328a0e6..c10a856d8 100644
--- a/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr
+++ b/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr
@@ -11,7 +11,7 @@ LL | fn opaque() -> impl Fn() -> i32 {
|
= note: expected type `i32`
found opaque type `impl Fn() -> i32`
-help: use parentheses to call this closure
+help: use parentheses to call this opaque type
|
LL | opaque()()
| ++
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 58a2f79ef..9b346387d 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -162,12 +162,18 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
|
LL | fn in_return() -> impl Debug;
| ^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
--> $DIR/where-allowed.rs:125:34
|
LL | fn in_trait_impl_return() -> impl Debug { () }
| ^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param
--> $DIR/where-allowed.rs:138:33
diff --git a/src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.rs b/src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.rs
new file mode 100644
index 000000000..33b746c5e
--- /dev/null
+++ b/src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.rs
@@ -0,0 +1,27 @@
+// Test for a less than ideal interaction of implied bounds and normalization.
+trait Tr {
+ type Ty;
+}
+
+impl<T: 'static> Tr for T {
+ type Ty = &'static T;
+}
+
+// `<&'a u8 as Tr>::Ty` should cause an error because `&'a u8: Tr` doesn't hold for
+// all possible 'a. However, we consider normalized types for implied bounds.
+//
+// We normalize this projection to `&'static &'a u8` and add a nested `&'a u8: 'static`
+// bound. This bound is then proven using the implied bounds for `&'static &'a u8` which
+// we only get by normalizing in the first place.
+fn test<'a>(x: &'a u8, _wf: <&'a u8 as Tr>::Ty) -> &'static u8 { x }
+
+fn main() {
+ // This works as we have 'static references due to promotion.
+ let _: &'static u8 = test(&3, &&3);
+ // This causes an error because the projection requires 'a to be 'static.
+ // It would be unsound if this compiled.
+ let x: u8 = 3;
+ let _: &'static u8 = test(&x, &&3);
+ //~^ ERROR `x` does not live long enough
+
+}
diff --git a/src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr b/src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
new file mode 100644
index 000000000..d0249e74f
--- /dev/null
+++ b/src/test/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/assoc-ty-wf-used-to-get-assoc-ty.rs:24:31
+ |
+LL | let _: &'static u8 = test(&x, &&3);
+ | -----^^------
+ | | |
+ | | borrowed value does not live long enough
+ | argument requires that `x` is borrowed for `'static`
+...
+LL | }
+ | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/implied-bounds/impl-header-unnormalized-types.rs b/src/test/ui/implied-bounds/impl-header-unnormalized-types.rs
new file mode 100644
index 000000000..d84539f8a
--- /dev/null
+++ b/src/test/ui/implied-bounds/impl-header-unnormalized-types.rs
@@ -0,0 +1,28 @@
+struct Foo<T>(T);
+
+trait GoodBye {
+ type Forget;
+}
+impl<T> GoodBye for T {
+ type Forget = ();
+}
+
+trait NeedsWf<'a, 'b> {
+ type Assoc;
+}
+
+impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
+ type Assoc = &'a &'b ();
+ //~^ ERROR in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+}
+
+fn needs_wf<'a, 'b, T: NeedsWf<'a, 'b>>() {}
+
+fn foo<'a: 'a, 'b: 'b>(_: &'b String) {
+ needs_wf::<'a, 'b, Foo<()>>();
+}
+
+fn main() {
+ let x = String::from("hello");
+ foo::<'static, '_>(&x);
+}
diff --git a/src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr b/src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr
new file mode 100644
index 000000000..88abd5f54
--- /dev/null
+++ b/src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr
@@ -0,0 +1,20 @@
+error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+ --> $DIR/impl-header-unnormalized-types.rs:15:18
+ |
+LL | type Assoc = &'a &'b ();
+ | ^^^^^^^^^^
+ |
+note: the pointer is valid for the lifetime `'a` as defined here
+ --> $DIR/impl-header-unnormalized-types.rs:14:6
+ |
+LL | impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
+ | ^^
+note: but the referenced data is only valid for the lifetime `'b` as defined here
+ --> $DIR/impl-header-unnormalized-types.rs:14:10
+ |
+LL | impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/src/test/ui/implied-bounds/issue-100690.rs b/src/test/ui/implied-bounds/issue-100690.rs
new file mode 100644
index 000000000..5599cd410
--- /dev/null
+++ b/src/test/ui/implied-bounds/issue-100690.rs
@@ -0,0 +1,45 @@
+// This code (probably) _should_ compile, but it currently does not because we
+// are not smart enough about implied bounds.
+
+use std::io;
+
+fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
+//~^ NOTE required by a bound in this
+where
+ F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
+ //~^ NOTE required by this bound in `real_dispatch`
+ //~| NOTE required by a bound in `real_dispatch`
+{
+ todo!()
+}
+
+#[derive(Debug)]
+struct UIView<'a, T: 'a> {
+ _phantom: std::marker::PhantomData<&'a mut T>,
+}
+
+trait Handle<'a, T: 'a, V, R> {
+ fn dispatch<F>(&self, f: F) -> Result<(), io::Error>
+ where
+ F: FnOnce(&mut V) -> R + Send + 'static;
+}
+
+#[derive(Debug, Clone)]
+struct TUIHandle<T> {
+ _phantom: std::marker::PhantomData<T>,
+}
+
+impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle<T> {
+ fn dispatch<F>(&self, f: F) -> Result<(), io::Error>
+ where
+ F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static,
+ {
+ real_dispatch(f)
+ //~^ ERROR expected a `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+ //~| NOTE expected an `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+ //~| NOTE expected a closure with arguments
+ //~| NOTE required by a bound introduced by this call
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/implied-bounds/issue-100690.stderr b/src/test/ui/implied-bounds/issue-100690.stderr
new file mode 100644
index 000000000..3f6af70d8
--- /dev/null
+++ b/src/test/ui/implied-bounds/issue-100690.stderr
@@ -0,0 +1,22 @@
+error[E0277]: expected a `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+ --> $DIR/issue-100690.rs:37:23
+ |
+LL | real_dispatch(f)
+ | ------------- ^ expected an `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected a closure with arguments `(&mut UIView<'a, T>,)`
+ found a closure with arguments `(&mut UIView<'_, T>,)`
+note: required by a bound in `real_dispatch`
+ --> $DIR/issue-100690.rs:9:8
+ |
+LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
+ | ------------- required by a bound in this
+...
+LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/implied-bounds/issue-101951.rs b/src/test/ui/implied-bounds/issue-101951.rs
new file mode 100644
index 000000000..108fef8a1
--- /dev/null
+++ b/src/test/ui/implied-bounds/issue-101951.rs
@@ -0,0 +1,50 @@
+// Taken directly from that issue.
+//
+// This test detected that we didn't correctly resolve
+// inference variables when computing implied bounds.
+//
+// check-pass
+pub trait BuilderFn<'a> {
+ type Output;
+}
+
+impl<'a, F, Out> BuilderFn<'a> for F
+where
+ F: FnOnce(&'a mut ()) -> Out,
+{
+ type Output = Out;
+}
+
+pub trait ConstructionFirm {
+ type Builder: for<'a> BuilderFn<'a>;
+}
+
+pub trait Campus<T>
+where
+ T: ConstructionFirm,
+{
+ fn add_building(
+ &mut self,
+ building: &mut <<T as ConstructionFirm>::Builder as BuilderFn<'_>>::Output,
+ );
+}
+
+struct ArchitectsInc {}
+
+impl ConstructionFirm for ArchitectsInc {
+ type Builder = fn(&mut ()) -> PrettyCondo<'_>;
+}
+
+struct PrettyCondo<'a> {
+ _marker: &'a mut (),
+}
+
+struct CondoEstate {}
+
+impl Campus<ArchitectsInc> for CondoEstate {
+ fn add_building(&mut self, _building: &mut PrettyCondo<'_>) {
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr
index b36f4dab8..e020d0298 100644
--- a/src/test/ui/index-help.stderr
+++ b/src/test/ui/index-help.stderr
@@ -6,7 +6,7 @@ LL | x[0i32];
|
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<i32>` for `Vec<{integer}>`
+ = note: required for `Vec<{integer}>` to implement `Index<i32>`
error: aborting due to previous error
diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr
index fbff20f8d..7a741cfc7 100644
--- a/src/test/ui/indexing-requires-a-uint.stderr
+++ b/src/test/ui/indexing-requires-a-uint.stderr
@@ -6,7 +6,7 @@ LL | [0][0u8];
|
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<u8>` for `[{integer}]`
+ = note: required for `[{integer}]` to implement `Index<u8>`
error[E0308]: mismatched types
--> $DIR/indexing-requires-a-uint.rs:12:18
diff --git a/src/test/ui/inference/issue-71732.stderr b/src/test/ui/inference/issue-71732.stderr
index 04673a375..79bee3328 100644
--- a/src/test/ui/inference/issue-71732.stderr
+++ b/src/test/ui/inference/issue-71732.stderr
@@ -2,7 +2,9 @@ error[E0283]: type annotations needed
--> $DIR/issue-71732.rs:18:10
|
LL | .get(&"key".into())
- | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get`
+ | ^^^ ------------- type must be known at this point
+ | |
+ | cannot infer type of the type parameter `Q` declared on the associated function `get`
|
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
- impl Borrow<str> for String;
@@ -13,7 +15,7 @@ note: required by a bound in `HashMap::<K, V, S>::get`
|
LL | K: Borrow<Q>,
| ^^^^^^^^^ required by this bound in `HashMap::<K, V, S>::get`
-help: consider specifying the type argument in the function call
+help: consider specifying the generic argument
|
LL | .get::<Q>(&"key".into())
| +++++
diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr
index e395e65fa..4f621b82d 100644
--- a/src/test/ui/inference/issue-86162-1.stderr
+++ b/src/test/ui/inference/issue-86162-1.stderr
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
| --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
| |
- | type must be known at this point
+ | required by a bound introduced by this call
|
= note: cannot satisfy `_: Clone`
note: required by a bound in `foo`
diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr
index 30e6e10ea..9aff2cec1 100644
--- a/src/test/ui/inference/issue-86162-2.stderr
+++ b/src/test/ui/inference/issue-86162-2.stderr
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
| -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
| |
- | type must be known at this point
+ | required by a bound introduced by this call
|
= note: cannot satisfy `_: Clone`
note: required by a bound in `Foo::bar`
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
index bcd29bb4e..b0c0d3397 100644
--- a/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Foo {
type Output<T>;
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
index 65a75b68c..cbc2477de 100644
--- a/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
@@ -1,5 +1,5 @@
error[E0282]: type annotations needed
- --> $DIR/expr-struct-type-relative-gat.rs:17:9
+ --> $DIR/expr-struct-type-relative-gat.rs:15:9
|
LL | Self::Output::Simple {};
| ^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated type `Output`
diff --git a/src/test/ui/integral-indexing.stderr b/src/test/ui/integral-indexing.stderr
index 3f9094d12..bbbb2a86a 100644
--- a/src/test/ui/integral-indexing.stderr
+++ b/src/test/ui/integral-indexing.stderr
@@ -6,7 +6,7 @@ LL | v[3u8];
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<u8>` for `Vec<isize>`
+ = note: required for `Vec<isize>` to implement `Index<u8>`
error[E0277]: the type `[isize]` cannot be indexed by `i8`
--> $DIR/integral-indexing.rs:7:7
@@ -16,7 +16,7 @@ LL | v[3i8];
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<i8>` for `Vec<isize>`
+ = note: required for `Vec<isize>` to implement `Index<i8>`
error[E0277]: the type `[isize]` cannot be indexed by `u32`
--> $DIR/integral-indexing.rs:8:7
@@ -26,7 +26,7 @@ LL | v[3u32];
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<u32>` for `Vec<isize>`
+ = note: required for `Vec<isize>` to implement `Index<u32>`
error[E0277]: the type `[isize]` cannot be indexed by `i32`
--> $DIR/integral-indexing.rs:9:7
@@ -36,7 +36,7 @@ LL | v[3i32];
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<i32>` for `Vec<isize>`
+ = note: required for `Vec<isize>` to implement `Index<i32>`
error[E0277]: the type `[u8]` cannot be indexed by `u8`
--> $DIR/integral-indexing.rs:12:18
@@ -46,7 +46,7 @@ LL | s.as_bytes()[3u8];
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<u8>` for `[u8]`
+ = note: required for `[u8]` to implement `Index<u8>`
error[E0277]: the type `[u8]` cannot be indexed by `i8`
--> $DIR/integral-indexing.rs:13:18
@@ -56,7 +56,7 @@ LL | s.as_bytes()[3i8];
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<i8>` for `[u8]`
+ = note: required for `[u8]` to implement `Index<i8>`
error[E0277]: the type `[u8]` cannot be indexed by `u32`
--> $DIR/integral-indexing.rs:14:18
@@ -66,7 +66,7 @@ LL | s.as_bytes()[3u32];
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<u32>` for `[u8]`
+ = note: required for `[u8]` to implement `Index<u32>`
error[E0277]: the type `[u8]` cannot be indexed by `i32`
--> $DIR/integral-indexing.rs:15:18
@@ -76,7 +76,7 @@ LL | s.as_bytes()[3i32];
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<i32>` for `[u8]`
+ = note: required for `[u8]` to implement `Index<i32>`
error: aborting due to 8 previous errors
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index 349fb6daf..94f41c925 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -1,12 +1,14 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/interior-mutability.rs:5:5
+ --> $DIR/interior-mutability.rs:5:18
|
LL | catch_unwind(|| { x.set(23); });
- | ^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | |
+ | required by a bound introduced by this call
|
= help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `Cell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `&Cell<i32>`
+ = note: required for `&Cell<i32>` to implement `UnwindSafe`
note: required because it's used within this closure
--> $DIR/interior-mutability.rs:5:18
|
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
new file mode 100644
index 000000000..29aefe071
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
@@ -0,0 +1,6 @@
+// See issue #100696.
+// run-fail
+// check-run-results
+fn main() {
+ &""[1..];
+}
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
new file mode 100644
index 000000000..e53e60346
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
@@ -0,0 +1,2 @@
+thread 'main' panicked at 'byte index 1 is out of bounds of ``', $DIR/const-eval-select-backtrace-std.rs:5:6
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace.rs b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
new file mode 100644
index 000000000..99f072520
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
@@ -0,0 +1,18 @@
+#![feature(core_intrinsics)]
+// See issue #100696.
+// run-fail
+// check-run-results
+
+#[track_caller]
+fn uhoh() {
+ panic!("Aaah!")
+}
+
+const fn c() {}
+
+fn main() {
+ // safety: this is unsound and just used to test
+ unsafe {
+ std::intrinsics::const_eval_select((), c, uhoh);
+ }
+}
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
new file mode 100644
index 000000000..2fd730ac7
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
@@ -0,0 +1,2 @@
+thread 'main' panicked at 'Aaah!', $DIR/const-eval-select-backtrace.rs:16:9
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.rs b/src/test/ui/intrinsics/const-eval-select-bad.rs
index 52f4e594f..fa14efad7 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.rs
+++ b/src/test/ui/intrinsics/const-eval-select-bad.rs
@@ -5,10 +5,13 @@ use std::intrinsics::const_eval_select;
const fn not_fn_items() {
const_eval_select((), || {}, || {});
- //~^ ERROR the trait bound
+ //~^ ERROR this argument must be a function item
+ //~| ERROR this argument must be a function item
const_eval_select((), 42, 0xDEADBEEF);
- //~^ ERROR the trait bound
+ //~^ ERROR expected a `FnOnce<()>` closure
//~| ERROR expected a `FnOnce<()>` closure
+ //~| ERROR this argument must be a function item
+ //~| ERROR this argument must be a function item
}
const fn foo(n: i32) -> i32 {
@@ -27,7 +30,7 @@ fn baz(n: bool) -> i32 {
const fn return_ty_mismatch() {
const_eval_select((1,), foo, bar);
- //~^ ERROR type mismatch
+ //~^ ERROR expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
}
const fn args_ty_mismatch() {
@@ -35,4 +38,9 @@ const fn args_ty_mismatch() {
//~^ ERROR type mismatch
}
+const fn non_const_fn() {
+ const_eval_select((1,), bar, bar);
+ //~^ ERROR this argument must be a `const fn`
+}
+
fn main() {}
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index 89dba12c8..3720528ad 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -1,42 +1,57 @@
-error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]: FnOnce<()>` is not satisfied
+error: this argument must be a function item
--> $DIR/const-eval-select-bad.rs:7:27
|
LL | const_eval_select((), || {}, || {});
- | ----------------- ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`
- | |
- | required by a bound introduced by this call
+ | ^^^^^
|
- = help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`
-note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`, but that implementation is not `const`
- --> $DIR/const-eval-select-bad.rs:7:27
+ = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]
+ = help: consult the documentation on `const_eval_select` for more information
+
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:7:34
|
LL | const_eval_select((), || {}, || {});
- | ^^^^^
- = note: wrap the `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]` in a closure with no arguments: `|| { /* code */ }`
-note: required by a bound in `const_eval_select`
- --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ | ^^^^^
|
-LL | F: ~const FnOnce<ARG, Output = RET>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+ = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:34: 7:36]
+ = help: consult the documentation on `const_eval_select` for more information
-error[E0277]: the trait bound `{integer}: FnOnce<()>` is not satisfied
- --> $DIR/const-eval-select-bad.rs:9:27
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:10:27
+ |
+LL | const_eval_select((), 42, 0xDEADBEEF);
+ | ^^
+ |
+ = note: expected a function item, found {integer}
+ = help: consult the documentation on `const_eval_select` for more information
+
+error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
+ --> $DIR/const-eval-select-bad.rs:10:27
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}`
| |
| required by a bound introduced by this call
|
- = help: the trait `~const FnOnce<()>` is not implemented for `{integer}`
+ = help: the trait `FnOnce<()>` is not implemented for `{integer}`
= note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
-LL | F: ~const FnOnce<ARG, Output = RET>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | F: FnOnce<ARG, Output = RET>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:10:31
+ |
+LL | const_eval_select((), 42, 0xDEADBEEF);
+ | ^^^^^^^^^^
+ |
+ = note: expected a function item, found {integer}
+ = help: consult the documentation on `const_eval_select` for more information
error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
- --> $DIR/const-eval-select-bad.rs:9:31
+ --> $DIR/const-eval-select-bad.rs:10:31
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
@@ -48,23 +63,25 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
-LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | G: FnOnce<ARG, Output = RET>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
-error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
- --> $DIR/const-eval-select-bad.rs:29:5
+error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
+ --> $DIR/const-eval-select-bad.rs:32:34
|
LL | const_eval_select((1,), foo, bar);
- | ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool`
+ | ----------------- ^^^ expected `i32`, found `bool`
+ | |
+ | required by a bound introduced by this call
|
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
-LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
- | ^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | G: FnOnce<ARG, Output = RET>,
+ | ^^^^^^^^^^^^ required by this bound in `const_eval_select`
error[E0631]: type mismatch in function arguments
- --> $DIR/const-eval-select-bad.rs:34:32
+ --> $DIR/const-eval-select-bad.rs:37:32
|
LL | const fn foo(n: i32) -> i32 {
| --------------------------- found signature defined here
@@ -79,10 +96,18 @@ LL | const_eval_select((true,), foo, baz);
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
-LL | F: ~const FnOnce<ARG, Output = RET>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | F: FnOnce<ARG, Output = RET>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+
+error: this argument must be a `const fn`
+ --> $DIR/const-eval-select-bad.rs:42:29
+ |
+LL | const_eval_select((1,), bar, bar);
+ | ^^^
+ |
+ = help: consult the documentation on `const_eval_select` for more information
-error: aborting due to 5 previous errors
+error: aborting due to 9 previous errors
Some errors have detailed explanations: E0271, E0277, E0631.
For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/issue-94866.stderr b/src/test/ui/issue-94866.stderr
index 5477d83f4..b3c17ce89 100644
--- a/src/test/ui/issue-94866.stderr
+++ b/src/test/ui/issue-94866.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `B` not covered
+error[E0004]: non-exhaustive patterns: `Enum::B` not covered
--> $DIR/issue-94866.rs:10:11
|
LL | match Enum::A {
- | ^^^^^^^ pattern `B` not covered
+ | ^^^^^^^ pattern `Enum::B` not covered
|
note: `Enum` defined here
--> $DIR/issue-94866.rs:7:16
@@ -13,7 +13,7 @@ LL | enum Enum { A, B }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Enum::A => m!(),
-LL + B => todo!()
+LL + Enum::B => todo!()
|
error: aborting due to previous error
diff --git a/src/test/ui/issues/auxiliary/issue-2380.rs b/src/test/ui/issues/auxiliary/issue-2380.rs
index 9a51a73c9..79fd62d16 100644
--- a/src/test/ui/issues/auxiliary/issue-2380.rs
+++ b/src/test/ui/issues/auxiliary/issue-2380.rs
@@ -1,8 +1,6 @@
#![crate_name="a"]
#![crate_type = "lib"]
-#![feature(box_syntax)]
-
pub trait i<T>
{
fn dummy(&self, t: T) -> T { panic!() }
@@ -11,5 +9,5 @@ pub trait i<T>
pub fn f<T>() -> Box<i<T>+'static> {
impl<T> i<T> for () { }
- box () as Box<i<T>+'static>
+ Box::new(()) as Box<i<T>+'static>
}
diff --git a/src/test/ui/issues/issue-100550-normalization-ice-exposed-by-mir-inlining.rs b/src/test/ui/issues/issue-100550-normalization-ice-exposed-by-mir-inlining.rs
deleted file mode 100644
index 2ed50d709..000000000
--- a/src/test/ui/issues/issue-100550-normalization-ice-exposed-by-mir-inlining.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// check-pass
-
-// compile-flags: --emit=mir,link -O
-
-// There is an ICE somewhere in type normalization, and we are hitting it during
-// the MIR inlining pass on this code.
-//
-// Long term, we should fix that ICE and change the compile-flags for this test
-// to explicitly enable MIR inlining.
-//
-// Short term, we are diabling MIR inlining for Rust 1.64-beta, so that we avoid
-// this ICE in this instance.
-
-pub trait Trait {
- type Associated;
-}
-impl<T> Trait for T {
- type Associated = T;
-}
-
-pub struct Struct<T>(<T as Trait>::Associated);
-
-pub fn foo<T>() -> Struct<T>
-where
- T: Trait,
-{
- bar()
-}
-
-#[inline]
-fn bar<T>() -> Struct<T> {
- Struct(baz())
-}
-
-fn baz<T>() -> T {
- unimplemented!()
-}
-
-fn main() { }
diff --git a/src/test/ui/issues/issue-100605.rs b/src/test/ui/issues/issue-100605.rs
new file mode 100644
index 000000000..917a45c15
--- /dev/null
+++ b/src/test/ui/issues/issue-100605.rs
@@ -0,0 +1,9 @@
+fn takes_option(_arg: Option<&String>) {}
+
+fn main() {
+ takes_option(&None); //~ ERROR 4:18: 4:23: mismatched types [E0308]
+
+ let x = String::from("x");
+ let res = Some(x);
+ takes_option(&res); //~ ERROR 8:18: 8:22: mismatched types [E0308]
+}
diff --git a/src/test/ui/issues/issue-100605.stderr b/src/test/ui/issues/issue-100605.stderr
new file mode 100644
index 000000000..886e3cd6b
--- /dev/null
+++ b/src/test/ui/issues/issue-100605.stderr
@@ -0,0 +1,46 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-100605.rs:4:18
+ |
+LL | takes_option(&None);
+ | ------------ ^^^^^ expected enum `Option`, found `&Option<_>`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `Option<&String>`
+ found reference `&Option<_>`
+note: function defined here
+ --> $DIR/issue-100605.rs:1:4
+ |
+LL | fn takes_option(_arg: Option<&String>) {}
+ | ^^^^^^^^^^^^ ---------------------
+help: you can convert from `&Option<T>` to `Option<&T>` using `.as_ref()`
+ |
+LL | takes_option(None.as_ref());
+ | ~~~~~~~~~~~~~
+help: consider removing the borrow
+ |
+LL - takes_option(&None);
+LL + takes_option(None);
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/issue-100605.rs:8:18
+ |
+LL | takes_option(&res);
+ | ------------ ^^^^
+ | | |
+ | | expected enum `Option`, found `&Option<String>`
+ | | help: you can convert from `&Option<T>` to `Option<&T>` using `.as_ref()`: `res.as_ref()`
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `Option<&String>`
+ found reference `&Option<String>`
+note: function defined here
+ --> $DIR/issue-100605.rs:1:4
+ |
+LL | fn takes_option(_arg: Option<&String>) {}
+ | ^^^^^^^^^^^^ ---------------------
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-10682.rs b/src/test/ui/issues/issue-10682.rs
index afaa90f05..72e4559d3 100644
--- a/src/test/ui/issues/issue-10682.rs
+++ b/src/test/ui/issues/issue-10682.rs
@@ -4,12 +4,10 @@
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
fn work(_: Box<isize>) {}
fn foo<F:FnOnce()>(_: F) {}
pub fn main() {
- let a = box 1;
+ let a = Box::new(1);
foo(move|| { foo(move|| { work(a) }) })
}
diff --git a/src/test/ui/issues/issue-10767.rs b/src/test/ui/issues/issue-10767.rs
index f40815fdb..5670cd458 100644
--- a/src/test/ui/issues/issue-10767.rs
+++ b/src/test/ui/issues/issue-10767.rs
@@ -1,10 +1,8 @@
// run-pass
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
pub fn main() {
fn f() {
}
- let _: Box<fn()> = box (f as fn());
+ let _: Box<fn()> = Box::new(f as fn());
}
diff --git a/src/test/ui/issues/issue-10802.rs b/src/test/ui/issues/issue-10802.rs
index f1d6b37a6..99e1a92df 100644
--- a/src/test/ui/issues/issue-10802.rs
+++ b/src/test/ui/issues/issue-10802.rs
@@ -1,6 +1,5 @@
// run-pass
#![allow(dead_code)]
-#![feature(box_syntax)]
struct DroppableStruct;
enum DroppableEnum {
@@ -33,14 +32,14 @@ impl Whatever {
fn main() {
{
- let f: Box<_> = box DroppableStruct;
- let _a = Whatever::new(box f as Box<dyn MyTrait>);
+ let f: Box<_> = Box::new(DroppableStruct);
+ let _a = Whatever::new(Box::new(f) as Box<dyn MyTrait>);
}
assert!(unsafe { DROPPED });
unsafe { DROPPED = false; }
{
- let f: Box<_> = box DroppableEnum::DroppableVariant1;
- let _a = Whatever::new(box f as Box<dyn MyTrait>);
+ let f: Box<_> = Box::new(DroppableEnum::DroppableVariant1);
+ let _a = Whatever::new(Box::new(f) as Box<dyn MyTrait>);
}
assert!(unsafe { DROPPED });
}
diff --git a/src/test/ui/issues/issue-11192.rs b/src/test/ui/issues/issue-11192.rs
index 3bf91675e..1a3d8c9fe 100644
--- a/src/test/ui/issues/issue-11192.rs
+++ b/src/test/ui/issues/issue-11192.rs
@@ -1,20 +1,20 @@
-#![feature(box_syntax)]
-
struct Foo {
x: isize
}
+
impl Drop for Foo {
fn drop(&mut self) {
println!("drop {}", self.x);
}
}
+
fn main() {
- let mut ptr: Box<_> = box Foo { x: 0 };
+ let mut ptr: Box<_> = Box::new(Foo { x: 0 });
let mut test = |foo: &Foo| {
println!("access {}", foo.x);
- ptr = box Foo { x: ptr.x + 1 };
+ ptr = Box::new(Foo { x: ptr.x + 1 });
println!("access {}", foo.x);
};
test(&*ptr);
diff --git a/src/test/ui/issues/issue-11192.stderr b/src/test/ui/issues/issue-11192.stderr
index 2a9d91317..fc1548013 100644
--- a/src/test/ui/issues/issue-11192.stderr
+++ b/src/test/ui/issues/issue-11192.stderr
@@ -4,7 +4,7 @@ error[E0502]: cannot borrow `*ptr` as immutable because it is also borrowed as m
LL | let mut test = |foo: &Foo| {
| ----------- mutable borrow occurs here
LL | println!("access {}", foo.x);
-LL | ptr = box Foo { x: ptr.x + 1 };
+LL | ptr = Box::new(Foo { x: ptr.x + 1 });
| --- first borrow occurs due to use of `ptr` in closure
...
LL | test(&*ptr);
diff --git a/src/test/ui/issues/issue-11374.stderr b/src/test/ui/issues/issue-11374.stderr
index 3a1d43310..15b2bbeb7 100644
--- a/src/test/ui/issues/issue-11374.stderr
+++ b/src/test/ui/issues/issue-11374.stderr
@@ -14,7 +14,7 @@ note: associated function defined here
--> $DIR/issue-11374.rs:13:12
|
LL | pub fn read_to(&mut self, vec: &mut [u8]) {
- | ^^^^^^^ --------- --------------
+ | ^^^^^^^ --------------
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-11515.rs b/src/test/ui/issues/issue-11515.rs
index 2072f9c47..b5c942f96 100644
--- a/src/test/ui/issues/issue-11515.rs
+++ b/src/test/ui/issues/issue-11515.rs
@@ -1,10 +1,10 @@
-#![feature(box_syntax)]
-
struct Test {
func: Box<dyn FnMut() + 'static>,
}
+
+
fn main() {
let closure: Box<dyn Fn() + 'static> = Box::new(|| ());
- let test = box Test { func: closure }; //~ ERROR trait upcasting coercion is experimental [E0658]
+ let test = Box::new(Test { func: closure }); //~ ERROR trait upcasting coercion is experimental [E0658]
}
diff --git a/src/test/ui/issues/issue-11515.stderr b/src/test/ui/issues/issue-11515.stderr
index 17bfae2a4..accd47f0f 100644
--- a/src/test/ui/issues/issue-11515.stderr
+++ b/src/test/ui/issues/issue-11515.stderr
@@ -1,8 +1,8 @@
error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
- --> $DIR/issue-11515.rs:9:33
+ --> $DIR/issue-11515.rs:9:38
|
-LL | let test = box Test { func: closure };
- | ^^^^^^^
+LL | let test = Box::new(Test { func: closure });
+ | ^^^^^^^
|
= note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
= help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
diff --git a/src/test/ui/issues/issue-11552.rs b/src/test/ui/issues/issue-11552.rs
index bae12375d..9fb9f3d2e 100644
--- a/src/test/ui/issues/issue-11552.rs
+++ b/src/test/ui/issues/issue-11552.rs
@@ -1,6 +1,5 @@
// run-pass
#![feature(box_patterns)]
-#![feature(box_syntax)]
#[derive(Clone)]
enum Noun
@@ -18,5 +17,8 @@ fn fas(n: &Noun) -> Noun
}
pub fn main() {
- fas(&Noun::Cell(box Noun::Atom(2), box Noun::Cell(box Noun::Atom(2), box Noun::Atom(3))));
+ fas(
+ &Noun::Cell(Box::new(Noun::Atom(2)),
+ Box::new(Noun::Cell(Box::new(Noun::Atom(2)), Box::new(Noun::Atom(3)))))
+ );
}
diff --git a/src/test/ui/issues/issue-11844.rs b/src/test/ui/issues/issue-11844.rs
index bb06f00d5..f974a4702 100644
--- a/src/test/ui/issues/issue-11844.rs
+++ b/src/test/ui/issues/issue-11844.rs
@@ -1,7 +1,5 @@
-#![feature(box_syntax)]
-
fn main() {
- let a = Some(box 1);
+ let a = Some(Box::new(1));
match a {
Ok(a) => //~ ERROR: mismatched types
println!("{}",a),
diff --git a/src/test/ui/issues/issue-11844.stderr b/src/test/ui/issues/issue-11844.stderr
index 9d7470e7a..81cf918a1 100644
--- a/src/test/ui/issues/issue-11844.stderr
+++ b/src/test/ui/issues/issue-11844.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/issue-11844.rs:6:9
+ --> $DIR/issue-11844.rs:4:9
|
LL | match a {
| - this expression has type `Option<Box<{integer}>>`
diff --git a/src/test/ui/issues/issue-12127.rs b/src/test/ui/issues/issue-12127.rs
index bb2c27345..8b30ddc2d 100644
--- a/src/test/ui/issues/issue-12127.rs
+++ b/src/test/ui/issues/issue-12127.rs
@@ -1,10 +1,10 @@
-#![feature(box_syntax, unboxed_closures)]
+#![feature(unboxed_closures)]
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
fn do_it(x: &isize) { }
fn main() {
- let x: Box<_> = box 22;
+ let x: Box<_> = Box::new(22);
let f = to_fn_once(move|| do_it(&*x));
to_fn_once(move|| {
f();
diff --git a/src/test/ui/issues/issue-13323.rs b/src/test/ui/issues/issue-13323.rs
index 26847ee7a..71e14d4da 100644
--- a/src/test/ui/issues/issue-13323.rs
+++ b/src/test/ui/issues/issue-13323.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
struct StrWrap {
s: String
@@ -48,7 +47,7 @@ impl<T: Eq> Matcher<T> for EqualTo<T> {
}
fn equal_to<T: Eq>(expected: T) -> Box<EqualTo<T>> {
- box EqualTo { expected: expected }
+ Box::new(EqualTo { expected: expected })
}
pub fn main() {
diff --git a/src/test/ui/issues/issue-14399.rs b/src/test/ui/issues/issue-14399.rs
index 6bf8a5899..7b32bf8e4 100644
--- a/src/test/ui/issues/issue-14399.rs
+++ b/src/test/ui/issues/issue-14399.rs
@@ -6,8 +6,6 @@
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
#[derive(Clone)]
struct B1;
@@ -15,6 +13,6 @@ trait A { fn foo(&self) {} }
impl A for B1 {}
fn main() {
- let v: Box<_> = box B1;
+ let v: Box<_> = Box::new(B1);
let _c: Box<dyn A> = v.clone();
}
diff --git a/src/test/ui/issues/issue-14915.rs b/src/test/ui/issues/issue-14915.rs
index 909540355..127b909dd 100644
--- a/src/test/ui/issues/issue-14915.rs
+++ b/src/test/ui/issues/issue-14915.rs
@@ -1,7 +1,5 @@
-#![feature(box_syntax)]
-
fn main() {
- let x: Box<isize> = box 0;
+ let x: Box<isize> = Box::new(0);
println!("{}", x + 1);
//~^ ERROR cannot add `{integer}` to `Box<isize>`
diff --git a/src/test/ui/issues/issue-14915.stderr b/src/test/ui/issues/issue-14915.stderr
index bd0b1d39a..6e6326929 100644
--- a/src/test/ui/issues/issue-14915.stderr
+++ b/src/test/ui/issues/issue-14915.stderr
@@ -1,5 +1,5 @@
error[E0369]: cannot add `{integer}` to `Box<isize>`
- --> $DIR/issue-14915.rs:6:22
+ --> $DIR/issue-14915.rs:4:22
|
LL | println!("{}", x + 1);
| - ^ - {integer}
diff --git a/src/test/ui/issues/issue-15524.rs b/src/test/ui/issues/issue-15524.rs
deleted file mode 100644
index 565db2d0f..000000000
--- a/src/test/ui/issues/issue-15524.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-const N: isize = 1;
-
-enum Foo {
- //~^ ERROR discriminant value `1` assigned more than once
- //~| ERROR discriminant value `1` assigned more than once
- //~| ERROR discriminant value `1` assigned more than once
- A = 1,
- B = 1,
- C = 0,
- D,
-
- E = N,
-
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-15524.stderr b/src/test/ui/issues/issue-15524.stderr
deleted file mode 100644
index 1195e0a34..000000000
--- a/src/test/ui/issues/issue-15524.stderr
+++ /dev/null
@@ -1,40 +0,0 @@
-error[E0081]: discriminant value `1` assigned more than once
- --> $DIR/issue-15524.rs:3:1
- |
-LL | enum Foo {
- | ^^^^^^^^
-...
-LL | A = 1,
- | - first assignment of `1`
-LL | B = 1,
- | - second assignment of `1`
-
-error[E0081]: discriminant value `1` assigned more than once
- --> $DIR/issue-15524.rs:3:1
- |
-LL | enum Foo {
- | ^^^^^^^^
-...
-LL | A = 1,
- | - first assignment of `1`
-LL | B = 1,
-LL | C = 0,
- | ----- assigned discriminant for `D` was incremented from this discriminant
-LL | D,
- | - second assignment of `1`
-
-error[E0081]: discriminant value `1` assigned more than once
- --> $DIR/issue-15524.rs:3:1
- |
-LL | enum Foo {
- | ^^^^^^^^
-...
-LL | A = 1,
- | - first assignment of `1`
-...
-LL | E = N,
- | - second assignment of `1`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0081`.
diff --git a/src/test/ui/issues/issue-15571.rs b/src/test/ui/issues/issue-15571.rs
index 5381d6523..5f228b286 100644
--- a/src/test/ui/issues/issue-15571.rs
+++ b/src/test/ui/issues/issue-15571.rs
@@ -1,8 +1,7 @@
// run-pass
-#![feature(box_syntax)]
fn match_on_local() {
- let mut foo: Option<Box<_>> = Some(box 5);
+ let mut foo: Option<Box<_>> = Some(Box::new(5));
match foo {
None => {},
Some(x) => {
@@ -37,7 +36,7 @@ fn match_on_binding() {
}
fn match_on_upvar() {
- let mut foo: Option<Box<_>> = Some(box 8);
+ let mut foo: Option<Box<_>> = Some(Box::new(8));
let f = move|| {
match foo {
None => {},
@@ -52,7 +51,7 @@ fn match_on_upvar() {
fn main() {
match_on_local();
- match_on_arg(Some(box 6));
+ match_on_arg(Some(Box::new(6)));
match_on_binding();
match_on_upvar();
}
diff --git a/src/test/ui/issues/issue-15763.rs b/src/test/ui/issues/issue-15763.rs
index 9ceffff2e..ae0863615 100644
--- a/src/test/ui/issues/issue-15763.rs
+++ b/src/test/ui/issues/issue-15763.rs
@@ -1,6 +1,5 @@
// run-pass
#![allow(unreachable_code)]
-#![feature(box_syntax)]
#[derive(PartialEq, Debug)]
struct Bar {
@@ -78,12 +77,12 @@ fn main() {
assert_eq!(cc().unwrap(), 3);
assert_eq!(dd().unwrap(), 3);
- let i = box 32isize as Box<dyn A>;
+ let i = Box::new(32isize) as Box<dyn A>;
assert_eq!(i.aaa(), 3);
- let i = box 32isize as Box<dyn A>;
+ let i = Box::new(32isize) as Box<dyn A>;
assert_eq!(i.bbb(), 3);
- let i = box 32isize as Box<dyn A>;
+ let i = Box::new(32isize) as Box<dyn A>;
assert_eq!(i.ccc().unwrap(), 3);
- let i = box 32isize as Box<dyn A>;
+ let i = Box::new(32isize) as Box<dyn A>;
assert_eq!(i.ddd().unwrap(), 3);
}
diff --git a/src/test/ui/issues/issue-16538.mir.stderr b/src/test/ui/issues/issue-16538.mir.stderr
index 7dab7de76..e320df4b7 100644
--- a/src/test/ui/issues/issue-16538.mir.stderr
+++ b/src/test/ui/issues/issue-16538.mir.stderr
@@ -5,6 +5,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:14:30
diff --git a/src/test/ui/issues/issue-16538.thir.stderr b/src/test/ui/issues/issue-16538.thir.stderr
index a18b0197d..4a8628692 100644
--- a/src/test/ui/issues/issue-16538.thir.stderr
+++ b/src/test/ui/issues/issue-16538.thir.stderr
@@ -21,6 +21,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-16739.rs b/src/test/ui/issues/issue-16739.rs
index 94da2ca5c..b21ea4bcd 100644
--- a/src/test/ui/issues/issue-16739.rs
+++ b/src/test/ui/issues/issue-16739.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
#![feature(unboxed_closures, fn_traits)]
// Test that unboxing shim for calling rust-call ABI methods through a
@@ -35,12 +34,12 @@ impl FnOnce<(u32,u32)> for Foo {
}
fn main() {
- let mut f = box Foo { foo: 42 } as Box<dyn FnMut() -> u32>;
+ let mut f = Box::new(Foo { foo: 42 }) as Box<dyn FnMut() -> u32>;
assert_eq!(f.call_mut(()), 42);
- let mut f = box Foo { foo: 40 } as Box<dyn FnMut(u32) -> u32>;
+ let mut f = Box::new(Foo { foo: 40 }) as Box<dyn FnMut(u32) -> u32>;
assert_eq!(f.call_mut((2,)), 42);
- let mut f = box Foo { foo: 40 } as Box<dyn FnMut(u32, u32) -> u32>;
+ let mut f = Box::new(Foo { foo: 40 }) as Box<dyn FnMut(u32, u32) -> u32>;
assert_eq!(f.call_mut((1, 1)), 42);
}
diff --git a/src/test/ui/issues/issue-16774.rs b/src/test/ui/issues/issue-16774.rs
index 9e9b84034..2b308ef76 100644
--- a/src/test/ui/issues/issue-16774.rs
+++ b/src/test/ui/issues/issue-16774.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
#![feature(box_patterns)]
use std::ops::{Deref, DerefMut};
@@ -35,7 +34,7 @@ impl DerefMut for X {
fn main() {
{
- let mut test = X(box 5);
+ let mut test = X(Box::new(5));
{
let mut change = || { *test = 10 };
change();
diff --git a/src/test/ui/issues/issue-16939.stderr b/src/test/ui/issues/issue-16939.stderr
index aaa3c49b3..766456454 100644
--- a/src/test/ui/issues/issue-16939.stderr
+++ b/src/test/ui/issues/issue-16939.stderr
@@ -12,7 +12,7 @@ LL | fn _foo<F: Fn()> (f: F) {
help: remove the extra argument
|
LL | |t| f();
- | ~~~
+ | ~~
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr
index 3a629e1eb..4856418ed 100644
--- a/src/test/ui/issues/issue-17252.stderr
+++ b/src/test/ui/issues/issue-17252.stderr
@@ -2,7 +2,7 @@ error[E0391]: cycle detected when const-evaluating + checking `FOO`
--> $DIR/issue-17252.rs:1:1
|
LL | const FOO: usize = FOO;
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: ...which immediately requires const-evaluating + checking `FOO` again
note: cycle used when const-evaluating + checking `main::{constant#0}`
diff --git a/src/test/ui/issues/issue-17322.rs b/src/test/ui/issues/issue-17322.rs
index 20a8d1361..b4fc40c3f 100644
--- a/src/test/ui/issues/issue-17322.rs
+++ b/src/test/ui/issues/issue-17322.rs
@@ -1,8 +1,6 @@
// run-pass
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
use std::io::{self, Write};
fn f(wr: &mut dyn Write) {
@@ -10,6 +8,6 @@ fn f(wr: &mut dyn Write) {
}
fn main() {
- let mut wr = box io::stdout() as Box<dyn Write>;
+ let mut wr = Box::new(io::stdout()) as Box<dyn Write>;
f(&mut wr);
}
diff --git a/src/test/ui/issues/issue-18611.stderr b/src/test/ui/issues/issue-18611.stderr
index bd18d4622..22c3470b6 100644
--- a/src/test/ui/issues/issue-18611.stderr
+++ b/src/test/ui/issues/issue-18611.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `isize: HasState` is not satisfied
- --> $DIR/issue-18611.rs:1:18
+ --> $DIR/issue-18611.rs:1:1
|
-LL | fn add_state(op: <isize as HasState>::State) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+LL | / fn add_state(op: <isize as HasState>::State) {
+LL | |
+LL | | }
+ | |_^ the trait `HasState` is not implemented for `isize`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-18819.stderr b/src/test/ui/issues/issue-18819.stderr
index 6499dd0d8..767fdd5ca 100644
--- a/src/test/ui/issues/issue-18819.stderr
+++ b/src/test/ui/issues/issue-18819.stderr
@@ -2,11 +2,13 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/issue-18819.rs:16:5
|
LL | print_x(X);
- | ^^^^^^^---
- | ||
- | |expected reference, found struct `X`
- | an argument of type `&str` is missing
+ | ^^^^^^^--- an argument of type `&str` is missing
|
+note: expected reference, found struct `X`
+ --> $DIR/issue-18819.rs:16:13
+ |
+LL | print_x(X);
+ | ^
= note: expected reference `&dyn Foo<Item = bool>`
found struct `X`
note: function defined here
@@ -21,7 +23,7 @@ LL | print_x(&X);
help: provide the argument
|
LL | print_x(/* &dyn Foo<Item = bool> */, /* &str */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-20162.stderr b/src/test/ui/issues/issue-20162.stderr
index d70bf6e1d..3f9b3be98 100644
--- a/src/test/ui/issues/issue-20162.stderr
+++ b/src/test/ui/issues/issue-20162.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `X: Ord` is not satisfied
- --> $DIR/issue-20162.rs:5:7
+ --> $DIR/issue-20162.rs:5:5
|
LL | b.sort();
- | ^^^^ the trait `Ord` is not implemented for `X`
+ | ^ ---- required by a bound introduced by this call
+ | |
+ | the trait `Ord` is not implemented for `X`
|
note: required by a bound in `slice::<impl [T]>::sort`
--> $SRC_DIR/alloc/src/slice.rs:LL:COL
diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr
index ea493c58a..2db60b641 100644
--- a/src/test/ui/issues/issue-20413.stderr
+++ b/src/test/ui/issues/issue-20413.stderr
@@ -14,13 +14,13 @@ LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Foo` for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
--> $DIR/issue-20413.rs:8:9
|
LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^ ^
= note: 127 redundant requirements hidden
- = note: required because of the requirements on the impl of `Foo` for `NoData<T>`
+ = note: required for `NoData<T>` to implement `Foo`
error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
--> $DIR/issue-20413.rs:27:42
@@ -29,18 +29,18 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
--> $DIR/issue-20413.rs:27:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
-note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
--> $DIR/issue-20413.rs:34:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
= note: 126 redundant requirements hidden
- = note: required because of the requirements on the impl of `Baz` for `EvenLessData<T>`
+ = note: required for `EvenLessData<T>` to implement `Baz`
error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
--> $DIR/issue-20413.rs:34:42
@@ -49,18 +49,18 @@ LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
--> $DIR/issue-20413.rs:34:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
-note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
--> $DIR/issue-20413.rs:27:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
= note: 126 redundant requirements hidden
- = note: required because of the requirements on the impl of `Bar` for `AlmostNoData<T>`
+ = note: required for `AlmostNoData<T>` to implement `Bar`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr
index 41eefe3f8..e1858b639 100644
--- a/src/test/ui/issues/issue-20605.stderr
+++ b/src/test/ui/issues/issue-20605.stderr
@@ -2,10 +2,10 @@ error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cann
--> $DIR/issue-20605.rs:2:17
|
LL | for item in *things { *item = 0 }
- | ^^^^^^^ expected an implementor of trait `IntoIterator`
+ | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
- = note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
+ = note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
help: consider mutably borrowing here
|
LL | for item in &mut *things { *item = 0 }
diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr
index 57f9575bd..ef62dece8 100644
--- a/src/test/ui/issues/issue-20831-debruijn.stderr
+++ b/src/test/ui/issues/issue-20831-debruijn.stderr
@@ -1,8 +1,14 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
- --> $DIR/issue-20831-debruijn.rs:28:8
+ --> $DIR/issue-20831-debruijn.rs:28:5
|
-LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
- | ^^^^^^^^^
+LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
+LL | | // Not obvious, but there is an implicit lifetime here -------^
+LL | |
+LL | | //
+... |
+LL | | self.sub = t;
+LL | | }
+ | |_____^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
--> $DIR/issue-20831-debruijn.rs:28:58
@@ -15,10 +21,16 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
| ^^
note: ...so that the types are compatible
- --> $DIR/issue-20831-debruijn.rs:28:8
+ --> $DIR/issue-20831-debruijn.rs:28:5
|
-LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
- | ^^^^^^^^^
+LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
+LL | | // Not obvious, but there is an implicit lifetime here -------^
+LL | |
+LL | | //
+... |
+LL | | self.sub = t;
+LL | | }
+ | |_____^
= note: expected `<MyStruct<'a> as Publisher<'_>>`
found `<MyStruct<'_> as Publisher<'_>>`
diff --git a/src/test/ui/issues/issue-21033.rs b/src/test/ui/issues/issue-21033.rs
index 86cc7707e..91f72eb36 100644
--- a/src/test/ui/issues/issue-21033.rs
+++ b/src/test/ui/issues/issue-21033.rs
@@ -4,7 +4,6 @@
// pretty-expanded FIXME #23616
#![feature(box_patterns)]
-#![feature(box_syntax)]
enum E {
StructVar { boxed: Box<i32> }
@@ -13,7 +12,7 @@ enum E {
fn main() {
// Test matching each shorthand notation for field patterns.
- let mut a = E::StructVar { boxed: box 3 };
+ let mut a = E::StructVar { boxed: Box::new(3) };
match a {
E::StructVar { box boxed } => { }
}
@@ -38,7 +37,7 @@ fn main() {
// Test matching non shorthand notation. Recreate a since last test
// moved `boxed`
- let mut a = E::StructVar { boxed: box 3 };
+ let mut a = E::StructVar { boxed: Box::new(3) };
match a {
E::StructVar { boxed: box ref mut num } => { }
}
diff --git a/src/test/ui/issues/issue-21763.stderr b/src/test/ui/issues/issue-21763.stderr
index b8b38c0a7..72c650297 100644
--- a/src/test/ui/issues/issue-21763.stderr
+++ b/src/test/ui/issues/issue-21763.stderr
@@ -1,12 +1,12 @@
error[E0277]: `Rc<()>` cannot be sent between threads safely
- --> $DIR/issue-21763.rs:9:5
+ --> $DIR/issue-21763.rs:9:11
|
LL | foo::<HashMap<Rc<()>, Rc<()>>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
|
= help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>`
= note: required because it appears within the type `(Rc<()>, Rc<()>)`
- = note: required because of the requirements on the impl of `Send` for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>`
+ = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send`
= note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>`
= note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>`
note: required by a bound in `foo`
diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr
index 4909398bb..731615a6b 100644
--- a/src/test/ui/issues/issue-21950.stderr
+++ b/src/test/ui/issues/issue-21950.stderr
@@ -1,3 +1,12 @@
+error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified
+ --> $DIR/issue-21950.rs:10:25
+ |
+LL | type Output;
+ | ----------- `Output` defined here
+...
+LL | let x = &10 as &dyn Add;
+ | ^^^ help: specify the associated type: `Add<Output = Type>`
+
error[E0393]: the type parameter `Rhs` must be explicitly specified
--> $DIR/issue-21950.rs:10:25
|
@@ -9,15 +18,6 @@ LL | let x = &10 as &dyn Add;
|
= note: because of the default `Self` reference, type parameters must be specified on object types
-error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified
- --> $DIR/issue-21950.rs:10:25
- |
-LL | type Output;
- | ----------- `Output` defined here
-...
-LL | let x = &10 as &dyn Add;
- | ^^^ help: specify the associated type: `Add<Output = Type>`
-
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0393.
diff --git a/src/test/ui/issues/issue-22872.stderr b/src/test/ui/issues/issue-22872.stderr
index a84cb7d8c..7382d40c0 100644
--- a/src/test/ui/issues/issue-22872.stderr
+++ b/src/test/ui/issues/issue-22872.stderr
@@ -5,7 +5,7 @@ LL | let _: Box<dyn for<'b> Wrap<'b>> = Box::new(Wrapper(process));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `<P as Process<'_>>::Item` is not an iterator
|
= help: the trait `Iterator` is not implemented for `<P as Process<'_>>::Item`
-note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper<P>`
+note: required for `Wrapper<P>` to implement `for<'b> Wrap<'b>`
--> $DIR/issue-22872.rs:7:13
|
LL | impl<'b, P> Wrap<'b> for Wrapper<P>
diff --git a/src/test/ui/issues/issue-2288.rs b/src/test/ui/issues/issue-2288.rs
index c74e53fca..6fd690a4d 100644
--- a/src/test/ui/issues/issue-2288.rs
+++ b/src/test/ui/issues/issue-2288.rs
@@ -1,8 +1,6 @@
// run-pass
#![allow(non_camel_case_types)]
-#![feature(box_syntax)]
-
trait clam<A> {
fn chowder(&self, y: A);
}
@@ -30,6 +28,6 @@ fn f<A>(x: Box<dyn clam<A>>, a: A) {
pub fn main() {
let c = foo(42);
- let d: Box<dyn clam<isize>> = box c as Box<dyn clam<isize>>;
+ let d: Box<dyn clam<isize>> = Box::new(c) as Box<dyn clam<isize>>;
f(d, c.x);
}
diff --git a/src/test/ui/issues/issue-23024.rs b/src/test/ui/issues/issue-23024.rs
index e92273bd4..010281ee3 100644
--- a/src/test/ui/issues/issue-23024.rs
+++ b/src/test/ui/issues/issue-23024.rs
@@ -1,11 +1,10 @@
-#![feature(box_syntax)]
use std::any::Any;
fn main()
{
fn h(x:i32) -> i32 {3*x}
let mut vfnfer:Vec<Box<dyn Any>> = vec![];
- vfnfer.push(box h);
+ vfnfer.push(Box::new(h));
println!("{:?}",(vfnfer[0] as dyn Fn)(3));
//~^ ERROR the precise format of `Fn`-family traits'
//~| ERROR missing generics for trait `Fn`
diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr
index 7a4d90b44..73f93c51d 100644
--- a/src/test/ui/issues/issue-23024.stderr
+++ b/src/test/ui/issues/issue-23024.stderr
@@ -1,5 +1,5 @@
error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
- --> $DIR/issue-23024.rs:9:39
+ --> $DIR/issue-23024.rs:8:39
|
LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
| ^^ help: use parenthetical notation instead: `Fn() -> ()`
@@ -8,7 +8,7 @@ LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0107]: missing generics for trait `Fn`
- --> $DIR/issue-23024.rs:9:39
+ --> $DIR/issue-23024.rs:8:39
|
LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
| ^^ expected 1 generic argument
@@ -24,7 +24,7 @@ LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3));
| ~~~~~~~~
error[E0191]: the value of the associated type `Output` (from trait `FnOnce`) must be specified
- --> $DIR/issue-23024.rs:9:39
+ --> $DIR/issue-23024.rs:8:39
|
LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
| ^^ help: specify the associated type: `Fn<Output = Type>`
diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr
index 7519e632d..f6cda3de5 100644
--- a/src/test/ui/issues/issue-23122-2.stderr
+++ b/src/test/ui/issues/issue-23122-2.stderr
@@ -1,15 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
+error[E0275]: overflow evaluating the requirement `<T as Next>::Next`
--> $DIR/issue-23122-2.rs:10:17
|
LL | type Next = <GetNext<T::Next> as Next>::Next;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
-note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
- --> $DIR/issue-23122-2.rs:9:15
- |
-LL | impl<T: Next> Next for GetNext<T> {
- | ^^^^ ^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr
index dcb99605d..074939f68 100644
--- a/src/test/ui/issues/issue-23302-3.stderr
+++ b/src/test/ui/issues/issue-23302-3.stderr
@@ -2,13 +2,13 @@ error[E0391]: cycle detected when const-evaluating + checking `A`
--> $DIR/issue-23302-3.rs:1:1
|
LL | const A: i32 = B;
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `B`...
--> $DIR/issue-23302-3.rs:3:1
|
LL | const B: i32 = A;
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating + checking `A`, completing the cycle
note: cycle used when simplifying constant for the type system `A`
--> $DIR/issue-23302-3.rs:1:1
diff --git a/src/test/ui/issues/issue-23491.rs b/src/test/ui/issues/issue-23491.rs
index 1cb969731..e5f9dd3ef 100644
--- a/src/test/ui/issues/issue-23491.rs
+++ b/src/test/ui/issues/issue-23491.rs
@@ -1,9 +1,8 @@
// run-pass
#![allow(unused_variables)]
-#![feature(box_syntax)]
struct Node<T: ?Sized>(#[allow(unused_tuple_struct_fields)] T);
fn main() {
- let x: Box<Node<[isize]>> = box Node([]);
+ let x: Box<Node<[isize]>> = Box::new(Node([]));
}
diff --git a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs
index 403cf970b..cdb130d60 100644
--- a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs
+++ b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs
@@ -97,7 +97,7 @@ pub fn main() {
// ever hands f_A off to instances of GaspA, and thus one should
// be able to prove the invariant that f_A is *only* invoked from
// from an instance of GaspA (either via the GaspA drop
- // implementation or the E drop implementaton). Yet the old (bad)
+ // implementation or the E drop implementation). Yet the old (bad)
// behavior allowed a call to f_A to leak in while we are tearing
// down a value of type GaspB.
}
diff --git a/src/test/ui/issues/issue-25901.stderr b/src/test/ui/issues/issue-25901.stderr
index e933745c4..c6c80e41c 100644
--- a/src/test/ui/issues/issue-25901.stderr
+++ b/src/test/ui/issues/issue-25901.stderr
@@ -16,6 +16,7 @@ note: impl defined here, but it is not `const`
LL | impl Deref for A {
| ^^^^^^^^^^^^^^^^
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-26217.stderr b/src/test/ui/issues/issue-26217.stderr
index c7601caac..73c772205 100644
--- a/src/test/ui/issues/issue-26217.stderr
+++ b/src/test/ui/issues/issue-26217.stderr
@@ -5,6 +5,12 @@ LL | fn bar<'a>() {
| -- lifetime `'a` defined here
LL | foo::<&'a i32>();
| ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/issue-26217.rs:1:30
+ |
+LL | fn foo<T>() where for<'a> T: 'a {}
+ | ^^
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-2708.rs b/src/test/ui/issues/issue-2708.rs
index abd5e9507..4e53b9d14 100644
--- a/src/test/ui/issues/issue-2708.rs
+++ b/src/test/ui/issues/issue-2708.rs
@@ -4,7 +4,7 @@
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
+
struct Font {
fontbuf: usize,
@@ -26,5 +26,5 @@ fn Font() -> Font {
}
pub fn main() {
- let _f: Box<_> = box Font();
+ let _f: Box<_> = Box::new(Font());
}
diff --git a/src/test/ui/issues/issue-2734.rs b/src/test/ui/issues/issue-2734.rs
index d449f6449..df4f394dc 100644
--- a/src/test/ui/issues/issue-2734.rs
+++ b/src/test/ui/issues/issue-2734.rs
@@ -4,21 +4,19 @@
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
trait hax {
fn dummy(&self) { }
}
impl<A> hax for A { }
fn perform_hax<T: 'static>(x: Box<T>) -> Box<dyn hax+'static> {
- box x as Box<dyn hax+'static>
+ Box::new(x) as Box<dyn hax+'static>
}
fn deadcode() {
- perform_hax(box "deadcode".to_string());
+ perform_hax(Box::new("deadcode".to_string()));
}
pub fn main() {
- let _ = perform_hax(box 42);
+ let _ = perform_hax(Box::new(42));
}
diff --git a/src/test/ui/issues/issue-2735.rs b/src/test/ui/issues/issue-2735.rs
index 794c7d4ed..20d3949a9 100644
--- a/src/test/ui/issues/issue-2735.rs
+++ b/src/test/ui/issues/issue-2735.rs
@@ -4,21 +4,19 @@
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
trait hax {
fn dummy(&self) { }
}
impl<A> hax for A { }
fn perform_hax<T: 'static>(x: Box<T>) -> Box<dyn hax+'static> {
- box x as Box<dyn hax+'static>
+ Box::new(x) as Box<dyn hax+'static>
}
fn deadcode() {
- perform_hax(box "deadcode".to_string());
+ perform_hax(Box::new("deadcode".to_string()));
}
pub fn main() {
- perform_hax(box 42);
+ perform_hax(Box::new(42));
}
diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr
index b1d1c01b2..85a8698af 100644
--- a/src/test/ui/issues/issue-28344.stderr
+++ b/src/test/ui/issues/issue-28344.stderr
@@ -25,7 +25,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
| ^^^^^
| |
| function or associated item not found in `dyn BitXor<_>`
- | help: there is an associated function with a similar name: `bitxor`
+ | help: there is a method with a similar name: `bitxor`
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-28344.rs:10:13
@@ -53,7 +53,7 @@ LL | let g = BitXor::bitor;
| ^^^^^
| |
| function or associated item not found in `dyn BitXor<_>`
- | help: there is an associated function with a similar name: `bitxor`
+ | help: there is a method with a similar name: `bitxor`
error: aborting due to 4 previous errors; 2 warnings emitted
diff --git a/src/test/ui/issues/issue-2935.rs b/src/test/ui/issues/issue-2935.rs
index 11641ca73..37f818199 100644
--- a/src/test/ui/issues/issue-2935.rs
+++ b/src/test/ui/issues/issue-2935.rs
@@ -1,7 +1,6 @@
// run-pass
#![allow(dead_code)]
#![allow(non_camel_case_types)]
-#![feature(box_syntax)]
//type t = { a: isize };
// type t = { a: bool };
@@ -20,7 +19,7 @@ pub fn main() {
// let y = box ({a: 4});
// let z = box ({a: 4} as it);
// let z = box ({a: true} as it);
- let z: Box<_> = box (box true as Box<dyn it>);
+ let z: Box<_> = Box::new(Box::new(true) as Box<dyn it>);
// x.f();
// y.f();
// (*z).f();
diff --git a/src/test/ui/issues/issue-3026.rs b/src/test/ui/issues/issue-3026.rs
index 1dea8134f..4619a3fe7 100644
--- a/src/test/ui/issues/issue-3026.rs
+++ b/src/test/ui/issues/issue-3026.rs
@@ -1,13 +1,11 @@
// run-pass
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
use std::collections::HashMap;
pub fn main() {
let x: Box<_>;
let mut buggy_map: HashMap<usize, &usize> = HashMap::new();
- x = box 1;
+ x = Box::new(1);
buggy_map.insert(42, &*x);
}
diff --git a/src/test/ui/issues/issue-31173.rs b/src/test/ui/issues/issue-31173.rs
index 48061ae54..04efa2718 100644
--- a/src/test/ui/issues/issue-31173.rs
+++ b/src/test/ui/issues/issue-31173.rs
@@ -3,12 +3,13 @@ use std::vec::IntoIter;
pub fn get_tok(it: &mut IntoIter<u8>) {
let mut found_e = false;
- let temp: Vec<u8> = it.take_while(|&x| {
- found_e = true;
- false
- })
+ let temp: Vec<u8> = it
+ //~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
+ .take_while(|&x| {
+ found_e = true;
+ false
+ })
.cloned()
- //~^ ERROR type mismatch resolving
.collect(); //~ ERROR the method
}
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index 68337a715..e3334eef3 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -1,8 +1,16 @@
-error[E0271]: type mismatch resolving `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]> as Iterator>::Item == &_`
- --> $DIR/issue-31173.rs:10:10
- |
-LL | .cloned()
- | ^^^^^^ expected reference, found `u8`
+error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>` to be an iterator that yields `&_`, but it yields `u8`
+ --> $DIR/issue-31173.rs:6:25
+ |
+LL | let temp: Vec<u8> = it
+ | _________________________^
+LL | |
+LL | | .take_while(|&x| {
+LL | | found_e = true;
+LL | | false
+LL | | })
+ | |__________^ expected reference, found `u8`
+LL | .cloned()
+ | ------ required by a bound introduced by this call
|
= note: expected reference `&_`
found type `u8`
@@ -12,27 +20,27 @@ note: required by a bound in `cloned`
LL | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in `cloned`
-error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>`, but its trait bounds were not satisfied
- --> $DIR/issue-31173.rs:12:10
+error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>`, but its trait bounds were not satisfied
+ --> $DIR/issue-31173.rs:13:10
|
LL | .collect();
- | ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>` due to unsatisfied trait bounds
- |
- ::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
- |
-LL | pub struct Cloned<I> {
- | -------------------- doesn't satisfy `_: Iterator`
+ | ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>` due to unsatisfied trait bounds
|
::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
|
LL | pub struct TakeWhile<I, P> {
| -------------------------- doesn't satisfy `<_ as Iterator>::Item = &_`
|
+ ::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
+ |
+LL | pub struct Cloned<I> {
+ | -------------------- doesn't satisfy `_: Iterator`
+ |
= note: the following trait bounds were not satisfied:
- `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]> as Iterator>::Item = &_`
- which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator`
- `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator`
- which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator`
+ `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]> as Iterator>::Item = &_`
+ which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
+ `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
+ which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-3121.rs b/src/test/ui/issues/issue-3121.rs
index f7bbfa9f6..4bf5b9b60 100644
--- a/src/test/ui/issues/issue-3121.rs
+++ b/src/test/ui/issues/issue-3121.rs
@@ -1,7 +1,6 @@
// run-pass
#![allow(dead_code)]
#![allow(non_camel_case_types)]
-#![feature(box_syntax)]
#[derive(Copy, Clone)]
enum side { mayo, catsup, vinegar }
@@ -21,5 +20,5 @@ fn foo(m: Box<meal>, cond: bool) {
}
pub fn main() {
- foo(box meal::for_here(order::hamburger), true)
+ foo(Box::new(meal::for_here(order::hamburger)), true)
}
diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr
index 4d8eb6360..aa0b5ce64 100644
--- a/src/test/ui/issues/issue-3214.stderr
+++ b/src/test/ui/issues/issue-3214.stderr
@@ -2,10 +2,9 @@ error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-3214.rs:3:12
|
LL | fn foo<T>() {
- | --- - type parameter from outer function
- | |
- | try adding a local generic parameter in this method instead
+ | - type parameter from outer function
LL | struct Foo {
+ | - help: try using a local generic parameter instead: `<T>`
LL | x: T,
| ^ use of generic parameter from outer function
diff --git a/src/test/ui/issues/issue-32709.stderr b/src/test/ui/issues/issue-32709.stderr
index 112cb3359..1d595ca56 100644
--- a/src/test/ui/issues/issue-32709.stderr
+++ b/src/test/ui/issues/issue-32709.stderr
@@ -10,7 +10,7 @@ LL | Err(5)?;
= help: the following other types implement trait `FromResidual<R>`:
<Result<T, F> as FromResidual<Result<Infallible, E>>>
<Result<T, F> as FromResidual<Yeet<E>>>
- = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>`
+ = note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-3290.rs b/src/test/ui/issues/issue-3290.rs
index 840c7ff83..7014d517f 100644
--- a/src/test/ui/issues/issue-3290.rs
+++ b/src/test/ui/issues/issue-3290.rs
@@ -1,9 +1,8 @@
// run-pass
-#![feature(box_syntax)]
#![allow(dead_code)]
pub fn main() {
- let mut x: Box<_> = box 3;
+ let mut x: Box<_> = Box::new(3);
x = x;
assert_eq!(*x, 3);
}
diff --git a/src/test/ui/issues/issue-33941.rs b/src/test/ui/issues/issue-33941.rs
index a1213623e..8430e85df 100644
--- a/src/test/ui/issues/issue-33941.rs
+++ b/src/test/ui/issues/issue-33941.rs
@@ -3,7 +3,7 @@
use std::collections::HashMap;
fn main() {
- for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch
- //~^ ERROR type mismatch
- //~| ERROR type mismatch
+ for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+ //~^ ERROR expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+ //~| ERROR expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
}
diff --git a/src/test/ui/issues/issue-33941.stderr b/src/test/ui/issues/issue-33941.stderr
index e1ce6eed9..691b8f88f 100644
--- a/src/test/ui/issues/issue-33941.stderr
+++ b/src/test/ui/issues/issue-33941.stderr
@@ -1,8 +1,10 @@
-error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
- --> $DIR/issue-33941.rs:6:36
+error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+ --> $DIR/issue-33941.rs:6:14
|
LL | for _ in HashMap::new().iter().cloned() {}
- | ^^^^^^ expected reference, found tuple
+ | ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call
+ | |
+ | expected reference, found tuple
|
= note: expected reference `&_`
found tuple `(&_, &_)`
@@ -12,7 +14,7 @@ note: required by a bound in `cloned`
LL | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in `cloned`
-error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
+error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
--> $DIR/issue-33941.rs:6:14
|
LL | for _ in HashMap::new().iter().cloned() {}
@@ -20,10 +22,10 @@ LL | for _ in HashMap::new().iter().cloned() {}
|
= note: expected tuple `(&_, &_)`
found reference `&_`
- = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
- = note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
+ = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
+ = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`
-error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
+error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
--> $DIR/issue-33941.rs:6:14
|
LL | for _ in HashMap::new().iter().cloned() {}
@@ -31,7 +33,7 @@ LL | for _ in HashMap::new().iter().cloned() {}
|
= note: expected tuple `(&_, &_)`
found reference `&_`
- = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
+ = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr
index 48ae2df69..72082f0cd 100644
--- a/src/test/ui/issues/issue-34334.stderr
+++ b/src/test/ui/issues/issue-34334.stderr
@@ -13,10 +13,12 @@ LL | let sr: Vec<(u32, _, _)> = vec![];
| +
error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
- --> $DIR/issue-34334.rs:5:87
+ --> $DIR/issue-34334.rs:5:33
|
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
- | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
|
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
diff --git a/src/test/ui/issues/issue-34349.stderr b/src/test/ui/issues/issue-34349.stderr
index d0b51961b..8e9a16619 100644
--- a/src/test/ui/issues/issue-34349.stderr
+++ b/src/test/ui/issues/issue-34349.stderr
@@ -7,7 +7,15 @@ LL | farewell.push_str("!!!");
| -------- closure is `FnMut` because it mutates the variable `farewell` here
...
LL | apply(diary);
- | ----- the requirement to implement `Fn` derives from here
+ | ----- ----- the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `apply`
+ --> $DIR/issue-34349.rs:11:32
+ |
+LL | fn apply<F>(f: F) where F: Fn() {
+ | ^^^^ required by this bound in `apply`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-3447.rs b/src/test/ui/issues/issue-3447.rs
index 1e329d152..ee5b22778 100644
--- a/src/test/ui/issues/issue-3447.rs
+++ b/src/test/ui/issues/issue-3447.rs
@@ -2,7 +2,6 @@
#![allow(dead_code)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
-#![feature(box_syntax)]
use std::cell::RefCell;
@@ -20,7 +19,7 @@ impl<T:'static> list<T> {
next: None
};
- self.next = Some(box RefCell::new(newList));
+ self.next = Some(Box::new(RefCell::new(newList)));
}
}
diff --git a/src/test/ui/issues/issue-35241.stderr b/src/test/ui/issues/issue-35241.stderr
index a66289a1c..9ee7654a0 100644
--- a/src/test/ui/issues/issue-35241.stderr
+++ b/src/test/ui/issues/issue-35241.stderr
@@ -13,8 +13,8 @@ LL | fn test() -> Foo { Foo }
found fn item `fn(u32) -> Foo {Foo}`
help: use parentheses to instantiate this tuple struct
|
-LL | fn test() -> Foo { Foo(_) }
- | +++
+LL | fn test() -> Foo { Foo(/* u32 */) }
+ | +++++++++++
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-35570.rs b/src/test/ui/issues/issue-35570.rs
index 42cef9a47..a2b0222d4 100644
--- a/src/test/ui/issues/issue-35570.rs
+++ b/src/test/ui/issues/issue-35570.rs
@@ -6,7 +6,8 @@ trait Trait2<'a> {
}
fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
-//~^ the trait bound `for<'a> (): Trait2<'a>` is not satisfied
+ //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
+ //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
let _e: (usize, usize) = unsafe{mem::transmute(param)};
}
diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr
index 2697d46bd..ebc40f678 100644
--- a/src/test/ui/issues/issue-35570.stderr
+++ b/src/test/ui/issues/issue-35570.stderr
@@ -1,9 +1,19 @@
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
+ --> $DIR/issue-35570.rs:8:1
+ |
+LL | / fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
+LL | |
+LL | |
+LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)};
+LL | | }
+ | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
+
+error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
--> $DIR/issue-35570.rs:8:40
|
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
-error: aborting due to previous error
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-3794.rs b/src/test/ui/issues/issue-3794.rs
index 1809e822c..b1f028fbc 100644
--- a/src/test/ui/issues/issue-3794.rs
+++ b/src/test/ui/issues/issue-3794.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
#![allow(dead_code)]
trait T {
@@ -26,7 +25,7 @@ fn print_s(s: &S) {
}
pub fn main() {
- let s: Box<S> = box S { s: 5 };
+ let s: Box<S> = Box::new(S { s: 5 });
print_s(&*s);
let t: Box<dyn T> = s as Box<dyn T>;
print_t(&*t);
diff --git a/src/test/ui/issues/issue-3878.rs b/src/test/ui/issues/issue-3878.rs
index a121f0ba8..6de3405af 100644
--- a/src/test/ui/issues/issue-3878.rs
+++ b/src/test/ui/issues/issue-3878.rs
@@ -2,9 +2,8 @@
// pretty-expanded FIXME #23616
#![allow(path_statements)]
-#![feature(box_syntax)]
pub fn main() {
- let y: Box<_> = box 1;
+ let y: Box<_> = Box::new(1);
y;
}
diff --git a/src/test/ui/issues/issue-38821.stderr b/src/test/ui/issues/issue-38821.stderr
index cdf1f0dfc..9abd2436b 100644
--- a/src/test/ui/issues/issue-38821.stderr
+++ b/src/test/ui/issues/issue-38821.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
LL | #[derive(Debug, Copy, Clone)]
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
|
-note: required because of the requirements on the impl of `IntoNullable` for `<Col as Expression>::SqlType`
+note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
|
LL | impl<T: NotNull> IntoNullable for T {
diff --git a/src/test/ui/issues/issue-39970.stderr b/src/test/ui/issues/issue-39970.stderr
index 1f64a90bc..774575d1d 100644
--- a/src/test/ui/issues/issue-39970.stderr
+++ b/src/test/ui/issues/issue-39970.stderr
@@ -9,7 +9,7 @@ note: expected this to be `()`
|
LL | type Element = &'a ();
| ^^^^^^
-note: required because of the requirements on the impl of `Visit` for `()`
+note: required for `()` to implement `Visit`
--> $DIR/issue-39970.rs:13:6
|
LL | impl Visit for () where
diff --git a/src/test/ui/issues/issue-40510-3.stderr b/src/test/ui/issues/issue-40510-3.stderr
index 22186ba9a..eb077415e 100644
--- a/src/test/ui/issues/issue-40510-3.stderr
+++ b/src/test/ui/issues/issue-40510-3.stderr
@@ -14,6 +14,10 @@ LL | | }
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
+help: consider adding 'move' keyword before the nested closure
+ |
+LL | move || {
+ | ++++
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-40827.stderr b/src/test/ui/issues/issue-40827.stderr
index 11c23e5b6..7f5c578ae 100644
--- a/src/test/ui/issues/issue-40827.stderr
+++ b/src/test/ui/issues/issue-40827.stderr
@@ -12,7 +12,7 @@ note: required because it appears within the type `Bar`
|
LL | enum Bar {
| ^^^
- = note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
+ = note: required for `Arc<Bar>` to implement `Send`
note: required because it appears within the type `Foo`
--> $DIR/issue-40827.rs:4:8
|
@@ -38,7 +38,7 @@ note: required because it appears within the type `Bar`
|
LL | enum Bar {
| ^^^
- = note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
+ = note: required for `Arc<Bar>` to implement `Send`
note: required because it appears within the type `Foo`
--> $DIR/issue-40827.rs:4:8
|
diff --git a/src/test/ui/issues/issue-41139.stderr b/src/test/ui/issues/issue-41139.stderr
index 48b22bca2..97492e6e0 100644
--- a/src/test/ui/issues/issue-41139.stderr
+++ b/src/test/ui/issues/issue-41139.stderr
@@ -5,9 +5,7 @@ LL | fn get_function<'a>() -> &'a dyn Fn() -> dyn Trait {
| -------------------------------------------------- `get_function` defined here returns `&dyn Fn() -> (dyn Trait + 'static)`
...
LL | let t: &dyn Trait = &get_function()();
- | ^^^^^^^^^^^^^^--
- | |
- | call expression requires function
+ | ^^^^^^^^^^^^^^ this trait object returns an unsized value `(dyn Trait + 'static)`, so it cannot be called
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-41726.stderr b/src/test/ui/issues/issue-41726.stderr
index 22631e7c2..b05c1fb14 100644
--- a/src/test/ui/issues/issue-41726.stderr
+++ b/src/test/ui/issues/issue-41726.stderr
@@ -5,6 +5,10 @@ LL | things[src.as_str()].sort();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `HashMap<String, Vec<String>>`
+help: to modify a `HashMap<String, Vec<String>>` use `.get_mut()`
+ |
+LL | things.get_mut(src.as_str()).map(|val| val.sort());
+ | ~~~~~~~~~ ~~~~~~~~~~~~~~~ +
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr
index fcbb40140..e249db9df 100644
--- a/src/test/ui/issues/issue-41974.stderr
+++ b/src/test/ui/issues/issue-41974.stderr
@@ -7,11 +7,11 @@ LL | impl<T> Drop for T where T: A {
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
--> $DIR/issue-41974.rs:7:18
|
LL | impl<T> Drop for T where T: A {
- | ^ must be a struct, enum, or union
+ | ^ must be a struct, enum, or union in the current crate
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-43988.stderr b/src/test/ui/issues/issue-43988.stderr
index 03aa37f52..02c5dd5bf 100644
--- a/src/test/ui/issues/issue-43988.stderr
+++ b/src/test/ui/issues/issue-43988.stderr
@@ -31,12 +31,16 @@ error[E0552]: unrecognized representation hint
|
LL | #[repr(nothing)]
| ^^^^^^^
+ |
+ = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
error[E0552]: unrecognized representation hint
--> $DIR/issue-43988.rs:18:12
|
LL | #[repr(something_not_real)]
| ^^^^^^^^^^^^^^^^^^
+ |
+ = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43988.rs:30:5
diff --git a/src/test/ui/issues/issue-47511.stderr b/src/test/ui/issues/issue-47511.stderr
index 5b84f7ed6..9998ee0e8 100644
--- a/src/test/ui/issues/issue-47511.stderr
+++ b/src/test/ui/issues/issue-47511.stderr
@@ -4,7 +4,8 @@ error[E0581]: return type references an anonymous lifetime, which is not constra
LL | fn f(_: X) -> X {
| ^
|
- = note: lifetimes appearing in an associated type are not considered constrained
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
--> $DIR/issue-47511.rs:12:23
diff --git a/src/test/ui/issues/issue-4759.rs b/src/test/ui/issues/issue-4759.rs
index 53785af09..e5b9e2ed5 100644
--- a/src/test/ui/issues/issue-4759.rs
+++ b/src/test/ui/issues/issue-4759.rs
@@ -2,8 +2,6 @@
// pretty-expanded FIXME #23616
#![allow(non_shorthand_field_patterns)]
-#![feature(box_syntax)]
-
struct T { a: Box<isize> }
trait U {
@@ -15,6 +13,6 @@ impl U for Box<isize> {
}
pub fn main() {
- let T { a: a } = T { a: box 0 };
+ let T { a: a } = T { a: Box::new(0) };
a.f();
}
diff --git a/src/test/ui/issues/issue-4935.stderr b/src/test/ui/issues/issue-4935.stderr
index aab19a699..bb45fa083 100644
--- a/src/test/ui/issues/issue-4935.stderr
+++ b/src/test/ui/issues/issue-4935.stderr
@@ -12,7 +12,7 @@ LL | fn foo(a: usize) {}
help: remove the extra argument
|
LL | fn main() { foo(5) }
- | ~~~~~~
+ | ~~~
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-4972.rs b/src/test/ui/issues/issue-4972.rs
index fab258f13..3f1c6f855 100644
--- a/src/test/ui/issues/issue-4972.rs
+++ b/src/test/ui/issues/issue-4972.rs
@@ -1,5 +1,4 @@
#![feature(box_patterns)]
-#![feature(box_syntax)]
trait MyTrait {
fn dummy(&self) {}
diff --git a/src/test/ui/issues/issue-4972.stderr b/src/test/ui/issues/issue-4972.stderr
index 40db50278..83daded7e 100644
--- a/src/test/ui/issues/issue-4972.stderr
+++ b/src/test/ui/issues/issue-4972.stderr
@@ -1,5 +1,5 @@
error[E0033]: type `Box<(dyn MyTrait + 'static)>` cannot be dereferenced
- --> $DIR/issue-4972.rs:14:25
+ --> $DIR/issue-4972.rs:13:25
|
LL | TraitWrapper::A(box ref map) => map,
| ^^^^^^^^^^^ type `Box<(dyn MyTrait + 'static)>` cannot be dereferenced
diff --git a/src/test/ui/issues/issue-49824.stderr b/src/test/ui/issues/issue-49824.stderr
index 2fec48254..14beadece 100644
--- a/src/test/ui/issues/issue-49824.stderr
+++ b/src/test/ui/issues/issue-49824.stderr
@@ -14,6 +14,10 @@ LL | | }
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
+help: consider adding 'move' keyword before the nested closure
+ |
+LL | move || {
+ | ++++
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-5100.rs b/src/test/ui/issues/issue-5100.rs
index 5e926fabe..69ed4b0e4 100644
--- a/src/test/ui/issues/issue-5100.rs
+++ b/src/test/ui/issues/issue-5100.rs
@@ -1,5 +1,5 @@
#![feature(box_patterns)]
-#![feature(box_syntax)]
+
enum A { B, C }
diff --git a/src/test/ui/issues/issue-5192.rs b/src/test/ui/issues/issue-5192.rs
index 5a83d1c2f..e2f835c19 100644
--- a/src/test/ui/issues/issue-5192.rs
+++ b/src/test/ui/issues/issue-5192.rs
@@ -2,8 +2,6 @@
#![allow(dead_code)]
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
pub trait EventLoop {
fn dummy(&self) { }
}
@@ -37,5 +35,5 @@ impl Scheduler {
}
pub fn main() {
- let _sched = Scheduler::new(box UvEventLoop::new() as Box<dyn EventLoop>);
+ let _sched = Scheduler::new(Box::new(UvEventLoop::new()) as Box<dyn EventLoop>);
}
diff --git a/src/test/ui/issues/issue-5439.rs b/src/test/ui/issues/issue-5439.rs
index cd039506f..852b264dc 100644
--- a/src/test/ui/issues/issue-5439.rs
+++ b/src/test/ui/issues/issue-5439.rs
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
struct Foo {
foo: isize,
}
@@ -10,7 +8,7 @@ struct Bar {
impl Bar {
fn make_foo (&self, i: isize) -> Box<Foo> {
- return box Foo { nonexistent: self, foo: i }; //~ ERROR: no field named
+ return Box::new(Foo { nonexistent: self, foo: i }); //~ ERROR: no field named
}
}
diff --git a/src/test/ui/issues/issue-5439.stderr b/src/test/ui/issues/issue-5439.stderr
index bd0cb670b..dc8f8b878 100644
--- a/src/test/ui/issues/issue-5439.stderr
+++ b/src/test/ui/issues/issue-5439.stderr
@@ -1,8 +1,8 @@
error[E0560]: struct `Foo` has no field named `nonexistent`
- --> $DIR/issue-5439.rs:13:26
+ --> $DIR/issue-5439.rs:11:31
|
-LL | return box Foo { nonexistent: self, foo: i };
- | ^^^^^^^^^^^ `Foo` does not have this field
+LL | return Box::new(Foo { nonexistent: self, foo: i });
+ | ^^^^^^^^^^^ `Foo` does not have this field
|
= note: available fields are: `foo`
diff --git a/src/test/ui/issues/issue-5666.rs b/src/test/ui/issues/issue-5666.rs
index aa5132778..810895b1b 100644
--- a/src/test/ui/issues/issue-5666.rs
+++ b/src/test/ui/issues/issue-5666.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
struct Dog {
name : String
@@ -17,8 +16,8 @@ impl Barks for Dog {
pub fn main() {
- let snoopy = box Dog{name: "snoopy".to_string()};
- let bubbles = box Dog{name: "bubbles".to_string()};
+ let snoopy = Box::new(Dog{name: "snoopy".to_string()});
+ let bubbles = Box::new(Dog{name: "bubbles".to_string()});
let barker = [snoopy as Box<dyn Barks>, bubbles as Box<dyn Barks>];
for pup in &barker {
diff --git a/src/test/ui/issues/issue-5718.rs b/src/test/ui/issues/issue-5718.rs
index 63efec953..f29a1e2a0 100644
--- a/src/test/ui/issues/issue-5718.rs
+++ b/src/test/ui/issues/issue-5718.rs
@@ -1,14 +1,12 @@
// run-pass
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
struct Element;
macro_rules! foo {
($tag: expr, $string: expr) => {
if $tag == $string {
- let element: Box<_> = box Element;
+ let element: Box<_> = Box::new(Element);
unsafe {
return std::mem::transmute::<_, usize>(element);
}
diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr
index 8e19f1400..b10273f14 100644
--- a/src/test/ui/issues/issue-57362-1.stderr
+++ b/src/test/ui/issues/issue-57362-1.stderr
@@ -2,9 +2,7 @@ error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current
--> $DIR/issue-57362-1.rs:20:7
|
LL | a.f();
- | - ^ method not found in `fn(&u8)`
- | |
- | this is a function, perhaps you wish to call it
+ | ^ method not found in `fn(&u8)`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Trait` defines an item `f`, perhaps you need to implement it
diff --git a/src/test/ui/issues/issue-5884.rs b/src/test/ui/issues/issue-5884.rs
index 2f64342a6..991c52321 100644
--- a/src/test/ui/issues/issue-5884.rs
+++ b/src/test/ui/issues/issue-5884.rs
@@ -2,8 +2,6 @@
#![allow(dead_code)]
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
pub struct Foo {
a: isize,
}
@@ -14,7 +12,7 @@ struct Bar<'a> {
}
fn check(a: Box<Foo>) {
- let _ic = Bar{ b: &*a, a: box None };
+ let _ic = Bar{ b: &*a, a: Box::new(None) };
}
pub fn main(){}
diff --git a/src/test/ui/issues/issue-59488.rs b/src/test/ui/issues/issue-59488.rs
index 922b59393..384501e3e 100644
--- a/src/test/ui/issues/issue-59488.rs
+++ b/src/test/ui/issues/issue-59488.rs
@@ -30,4 +30,5 @@ fn main() {
assert_eq!(Foo::Bar, i);
//~^ ERROR binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}` [E0369]
//~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277]
+ //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277]
}
diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr
index 7ce3dedaa..08fe0b35e 100644
--- a/src/test/ui/issues/issue-59488.stderr
+++ b/src/test/ui/issues/issue-59488.stderr
@@ -6,7 +6,7 @@ LL | foo > 12;
| |
| fn() -> i32 {foo}
|
-help: you might have forgotten to call this function
+help: use parentheses to call this function
|
LL | foo() > 12;
| ++
@@ -28,10 +28,10 @@ LL | bar > 13;
| |
| fn(i64) -> i64 {bar}
|
-help: you might have forgotten to call this function
+help: use parentheses to call this function
|
-LL | bar( /* arguments */ ) > 13;
- | +++++++++++++++++++
+LL | bar(/* i64 */) > 13;
+ | +++++++++++
error[E0308]: mismatched types
--> $DIR/issue-59488.rs:18:11
@@ -50,14 +50,10 @@ LL | foo > foo;
| |
| fn() -> i32 {foo}
|
-help: you might have forgotten to call this function
+help: use parentheses to call these
|
-LL | foo() > foo;
- | ++
-help: you might have forgotten to call this function
- |
-LL | foo > foo();
- | ++
+LL | foo() > foo();
+ | ++ ++
error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
--> $DIR/issue-59488.rs:25:9
@@ -93,7 +89,26 @@ error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
LL | assert_eq!(Foo::Bar, i);
| ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = help: the trait `Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}`
+ = help: the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
+ = help: the following other types implement trait `Debug`:
+ extern "C" fn() -> Ret
+ extern "C" fn(A, B) -> Ret
+ extern "C" fn(A, B, ...) -> Ret
+ extern "C" fn(A, B, C) -> Ret
+ extern "C" fn(A, B, C, ...) -> Ret
+ extern "C" fn(A, B, C, D) -> Ret
+ extern "C" fn(A, B, C, D, ...) -> Ret
+ extern "C" fn(A, B, C, D, E) -> Ret
+ and 68 others
+ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
+ --> $DIR/issue-59488.rs:30:5
+ |
+LL | assert_eq!(Foo::Bar, i);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = help: the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
= help: the following other types implement trait `Debug`:
extern "C" fn() -> Ret
extern "C" fn(A, B) -> Ret
@@ -106,7 +121,7 @@ LL | assert_eq!(Foo::Bar, i);
and 68 others
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
Some errors have detailed explanations: E0277, E0308, E0369.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-5997-enum.stderr b/src/test/ui/issues/issue-5997-enum.stderr
index 1c58b9c39..3a79215d3 100644
--- a/src/test/ui/issues/issue-5997-enum.stderr
+++ b/src/test/ui/issues/issue-5997-enum.stderr
@@ -2,11 +2,11 @@ error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-5997-enum.rs:2:16
|
LL | fn f<Z>() -> bool {
- | - - type parameter from outer function
- | |
- | try adding a local generic parameter in this method instead
+ | - type parameter from outer function
LL | enum E { V(Z) }
- | ^ use of generic parameter from outer function
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<Z>`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-5997-struct.stderr b/src/test/ui/issues/issue-5997-struct.stderr
index 5b388d16d..d2e97f767 100644
--- a/src/test/ui/issues/issue-5997-struct.stderr
+++ b/src/test/ui/issues/issue-5997-struct.stderr
@@ -2,11 +2,11 @@ error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-5997-struct.rs:2:14
|
LL | fn f<T>() -> bool {
- | - - type parameter from outer function
- | |
- | try adding a local generic parameter in this method instead
+ | - type parameter from outer function
LL | struct S(T);
- | ^ use of generic parameter from outer function
+ | -^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<T>`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-60218.stderr b/src/test/ui/issues/issue-60218.stderr
index 870b25014..dd72b6515 100644
--- a/src/test/ui/issues/issue-60218.stderr
+++ b/src/test/ui/issues/issue-60218.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `&u32: Foo` is not satisfied
- --> $DIR/issue-60218.rs:18:27
+ --> $DIR/issue-60218.rs:18:19
|
LL | trigger_error(vec![], |x: &u32| x)
- | ------------- ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32`
+ | ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/issues/issue-62480.rs b/src/test/ui/issues/issue-62480.rs
index 5c3be3e64..94a9c2ab8 100644
--- a/src/test/ui/issues/issue-62480.rs
+++ b/src/test/ui/issues/issue-62480.rs
@@ -1,5 +1,3 @@
-#![feature(label_break_value)]
-
fn main() {
// This used to ICE during liveness check because `target_id` passed to
// `propagate_through_expr` would be the closure and not the `loop`, which wouldn't be found in
diff --git a/src/test/ui/issues/issue-62480.stderr b/src/test/ui/issues/issue-62480.stderr
index 17085ef90..db2305370 100644
--- a/src/test/ui/issues/issue-62480.stderr
+++ b/src/test/ui/issues/issue-62480.stderr
@@ -1,5 +1,5 @@
error[E0767]: use of unreachable label `'a`
- --> $DIR/issue-62480.rs:8:18
+ --> $DIR/issue-62480.rs:6:18
|
LL | 'a: {
| -- unreachable label defined here
@@ -9,7 +9,7 @@ LL | || break 'a
= note: labels are unreachable through functions, closures, async blocks and modules
error[E0267]: `break` inside of a closure
- --> $DIR/issue-62480.rs:8:12
+ --> $DIR/issue-62480.rs:6:12
|
LL | || break 'a
| -- ^^^^^^^^ cannot `break` inside of a closure
diff --git a/src/test/ui/issues/issue-6318.rs b/src/test/ui/issues/issue-6318.rs
index d8bd83f0d..e5f245f6f 100644
--- a/src/test/ui/issues/issue-6318.rs
+++ b/src/test/ui/issues/issue-6318.rs
@@ -1,8 +1,6 @@
// run-pass
// pretty-expanded FIXME #23616
-#![feature(box_syntax)]
-
pub enum Thing {
A(Box<dyn Foo+'static>)
}
@@ -16,7 +14,7 @@ pub struct Struct;
impl Foo for Struct {}
pub fn main() {
- match Thing::A(box Struct as Box<dyn Foo + 'static>) {
+ match Thing::A(Box::new(Struct) as Box<dyn Foo + 'static>) {
Thing::A(_a) => 0,
};
}
diff --git a/src/test/ui/issues/issue-6557.rs b/src/test/ui/issues/issue-6557.rs
index e066aa529..757e9608f 100644
--- a/src/test/ui/issues/issue-6557.rs
+++ b/src/test/ui/issues/issue-6557.rs
@@ -3,7 +3,6 @@
// pretty-expanded FIXME #23616
#![feature(box_patterns)]
-#![feature(box_syntax)]
fn foo(box (_x, _y): Box<(isize, isize)>) {}
diff --git a/src/test/ui/issues/issue-66706.rs b/src/test/ui/issues/issue-66706.rs
index 4585bcc8c..835fdfae8 100644
--- a/src/test/ui/issues/issue-66706.rs
+++ b/src/test/ui/issues/issue-66706.rs
@@ -2,7 +2,6 @@ fn a() {
[0; [|_: _ &_| ()].len()]
//~^ ERROR expected `,`, found `&`
//~| ERROR type annotations needed
- //~| ERROR mismatched types
}
fn b() {
@@ -13,13 +12,11 @@ fn b() {
fn c() {
[0; [|&_: _ &_| {}; 0 ].len()]
//~^ ERROR expected `,`, found `&`
- //~| ERROR mismatched types
}
fn d() {
[0; match [|f @ &ref _| () ] {} ]
//~^ ERROR expected identifier, found reserved identifier `_`
- //~| ERROR mismatched types
}
fn main() {}
diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr
index 1c55560cb..8a30c0cad 100644
--- a/src/test/ui/issues/issue-66706.stderr
+++ b/src/test/ui/issues/issue-66706.stderr
@@ -7,13 +7,13 @@ LL | [0; [|_: _ &_| ()].len()]
| help: missing `,`
error: expected identifier, found reserved identifier `_`
- --> $DIR/issue-66706.rs:9:20
+ --> $DIR/issue-66706.rs:8:20
|
LL | [0; [|f @ &ref _| {} ; 0 ].len() ];
| ^ expected identifier, found reserved identifier
error: expected `,`, found `&`
- --> $DIR/issue-66706.rs:14:17
+ --> $DIR/issue-66706.rs:13:17
|
LL | [0; [|&_: _ &_| {}; 0 ].len()]
| -^ expected `,`
@@ -21,7 +21,7 @@ LL | [0; [|&_: _ &_| {}; 0 ].len()]
| help: missing `,`
error: expected identifier, found reserved identifier `_`
- --> $DIR/issue-66706.rs:20:26
+ --> $DIR/issue-66706.rs:18:26
|
LL | [0; match [|f @ &ref _| () ] {} ]
| ^ expected identifier, found reserved identifier
@@ -32,31 +32,6 @@ error[E0282]: type annotations needed
LL | [0; [|_: _ &_| ()].len()]
| ^ cannot infer type
-error[E0308]: mismatched types
- --> $DIR/issue-66706.rs:2:5
- |
-LL | fn a() {
- | - help: try adding a return type: `-> [i32; _]`
-LL | [0; [|_: _ &_| ()].len()]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
-
-error[E0308]: mismatched types
- --> $DIR/issue-66706.rs:14:5
- |
-LL | fn c() {
- | - help: try adding a return type: `-> [i32; _]`
-LL | [0; [|&_: _ &_| {}; 0 ].len()]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
-
-error[E0308]: mismatched types
- --> $DIR/issue-66706.rs:20:5
- |
-LL | fn d() {
- | - help: try adding a return type: `-> [i32; _]`
-LL | [0; match [|f @ &ref _| () ] {} ]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
-
-error: aborting due to 8 previous errors
+error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0282, E0308.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr
index d6e392516..2de150376 100644
--- a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr
+++ b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr
@@ -1,8 +1,10 @@
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
- --> $DIR/issue-66923-show-error-for-correct-call.rs:8:39
+ --> $DIR/issue-66923-show-error-for-correct-call.rs:8:24
|
LL | let x2: Vec<f64> = x1.into_iter().collect();
- | ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
+ | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
@@ -13,10 +15,12 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
- --> $DIR/issue-66923-show-error-for-correct-call.rs:12:29
+ --> $DIR/issue-66923-show-error-for-correct-call.rs:12:14
|
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
- | ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
+ | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
diff --git a/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
index 733456a1a..37e2c3bdd 100644
--- a/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
+++ b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
@@ -6,7 +6,7 @@ LL | let _ = Pin::new(Apple) == Rc::pin(Apple);
|
= note: expected struct `Apple`
found struct `Rc<Apple>`
- = note: required because of the requirements on the impl of `PartialEq<Pin<Rc<Apple>>>` for `Pin<Apple>`
+ = note: required for `Pin<Apple>` to implement `PartialEq<Pin<Rc<Apple>>>`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr
index e5ab65169..f581429a2 100644
--- a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr
+++ b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr
@@ -17,10 +17,10 @@ LL | | }
= note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info)
error: missing type for `const` item
- --> $DIR/issue-69396-const-no-type-in-macro.rs:4:19
+ --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20
|
LL | const A = "A".$fn();
- | ^ help: provide a type for the constant: `A: usize`
+ | ^ help: provide a type for the constant: `: usize`
...
LL | / suite! {
LL | | len;
@@ -31,13 +31,13 @@ LL | | }
= note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
- --> $DIR/issue-69396-const-no-type-in-macro.rs:4:19
+ --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20
|
LL | const A = "A".$fn();
- | ^
- | |
- | not allowed in type signatures
- | help: replace with the correct type: `bool`
+ | ^
+ | |
+ | not allowed in type signatures
+ | help: replace with the correct type: `bool`
...
LL | / suite! {
LL | | len;
diff --git a/src/test/ui/issues/issue-69455.stderr b/src/test/ui/issues/issue-69455.stderr
index b732df764..9d11cf19e 100644
--- a/src/test/ui/issues/issue-69455.stderr
+++ b/src/test/ui/issues/issue-69455.stderr
@@ -16,7 +16,7 @@ error[E0283]: type annotations needed
LL | println!("{}", 23u64.test(xs.iter().sum()));
| ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
| |
- | type must be known at this point
+ | required by a bound introduced by this call
|
note: multiple `impl`s satisfying `u64: Test<_>` found
--> $DIR/issue-69455.rs:11:1
diff --git a/src/test/ui/issues/issue-7013.rs b/src/test/ui/issues/issue-7013.rs
index c1f400b33..1fb01303c 100644
--- a/src/test/ui/issues/issue-7013.rs
+++ b/src/test/ui/issues/issue-7013.rs
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
use std::cell::RefCell;
use std::rc::Rc;
@@ -23,6 +21,6 @@ struct A {
}
fn main() {
- let a = A {v: box B{v: None} as Box<dyn Foo + Send>};
+ let a = A {v: Box::new(B{v: None}) as Box<dyn Foo + Send>};
//~^ ERROR `Rc<RefCell<A>>` cannot be sent between threads safely
}
diff --git a/src/test/ui/issues/issue-7013.stderr b/src/test/ui/issues/issue-7013.stderr
index f6cb1cbdc..4575f4dba 100644
--- a/src/test/ui/issues/issue-7013.stderr
+++ b/src/test/ui/issues/issue-7013.stderr
@@ -1,13 +1,13 @@
error[E0277]: `Rc<RefCell<A>>` cannot be sent between threads safely
- --> $DIR/issue-7013.rs:26:19
+ --> $DIR/issue-7013.rs:24:19
|
-LL | let a = A {v: box B{v: None} as Box<dyn Foo + Send>};
- | ^^^^^^^^^^^^^^ `Rc<RefCell<A>>` cannot be sent between threads safely
+LL | let a = A {v: Box::new(B{v: None}) as Box<dyn Foo + Send>};
+ | ^^^^^^^^^^^^^^^^^^^^ `Rc<RefCell<A>>` cannot be sent between threads safely
|
= help: within `B`, the trait `Send` is not implemented for `Rc<RefCell<A>>`
= note: required because it appears within the type `Option<Rc<RefCell<A>>>`
note: required because it appears within the type `B`
- --> $DIR/issue-7013.rs:10:8
+ --> $DIR/issue-7013.rs:8:8
|
LL | struct B {
| ^
diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
index c6e6ea1e0..7f29709ce 100644
--- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
+++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
@@ -8,11 +8,6 @@ LL | assert_eq!(a, 0);
| {integer}
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you might have forgotten to call this function
- --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
- |
-LL | if !(*left_val() == *right_val) {
- | ++
error[E0308]: mismatched types
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
@@ -21,7 +16,7 @@ LL | assert_eq!(a, 0);
| ^^^^^^^^^^^^^^^^ expected fn item, found integer
|
= note: expected fn item `fn() -> i32 {a}`
- found type `i32`
+ found type `{integer}`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `fn() -> i32 {a}` doesn't implement `Debug`
@@ -33,7 +28,7 @@ LL | fn a() -> i32 {
LL | assert_eq!(a, 0);
| ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = help: the trait `Debug` is not implemented for `fn() -> i32 {a}`
+ = help: the trait `Debug` is not implemented for fn item `fn() -> i32 {a}`
= help: use parentheses to call the function: `a()`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/test/ui/issues/issue-7364.rs b/src/test/ui/issues/issue-7364.rs
index 83c52d286..79642bd41 100644
--- a/src/test/ui/issues/issue-7364.rs
+++ b/src/test/ui/issues/issue-7364.rs
@@ -1,9 +1,7 @@
-#![feature(box_syntax)]
-
use std::cell::RefCell;
// Regression test for issue 7364
-static boxed: Box<RefCell<isize>> = box RefCell::new(0);
+static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
//~^ ERROR `RefCell<isize>` cannot be shared between threads safely [E0277]
fn main() { }
diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr
index f2e80f451..5dc8c2b60 100644
--- a/src/test/ui/issues/issue-7364.stderr
+++ b/src/test/ui/issues/issue-7364.stderr
@@ -1,11 +1,11 @@
error[E0277]: `RefCell<isize>` cannot be shared between threads safely
- --> $DIR/issue-7364.rs:6:15
+ --> $DIR/issue-7364.rs:4:15
|
-LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
+LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
| ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `RefCell<isize>`
- = note: required because of the requirements on the impl of `Sync` for `Unique<RefCell<isize>>`
+ = note: required for `Unique<RefCell<isize>>` to implement `Sync`
= note: required because it appears within the type `Box<RefCell<isize>>`
= note: shared static variables must have a type that implements `Sync`
diff --git a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
index 2961dc79f..c089c3308 100644
--- a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
@@ -8,8 +8,6 @@
*/
-#![feature(box_syntax)]
-
pub fn main() {}
trait A {
@@ -19,4 +17,4 @@ trait A {
impl<T: 'static> A for T {}
fn owned2<T: 'static>(a: Box<T>) { a as Box<dyn A>; }
-fn owned3<T: 'static>(a: Box<T>) { box a as Box<dyn A>; }
+fn owned3<T: 'static>(a: Box<T>) { Box::new(a) as Box<dyn A>; }
diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr
index 399c940ca..b26c1834d 100644
--- a/src/test/ui/issues/issue-86756.stderr
+++ b/src/test/ui/issues/issue-86756.stderr
@@ -25,9 +25,8 @@ LL | eq::<dyn, Foo>
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - eq::<dyn, Foo>
-LL + eq::<dyn, dyn Foo>
- |
+LL | eq::<dyn, dyn Foo>
+ | +++
error[E0107]: missing generics for trait `Foo`
--> $DIR/issue-86756.rs:5:15
diff --git a/src/test/ui/issues/issue-9129.rs b/src/test/ui/issues/issue-9129.rs
index 780a6419c..04110b3ae 100644
--- a/src/test/ui/issues/issue-9129.rs
+++ b/src/test/ui/issues/issue-9129.rs
@@ -4,8 +4,6 @@
#![allow(non_snake_case)]
// ignore-pretty unreported
-#![feature(box_syntax)]
-
pub trait bomb { fn boom(&self, _: Ident); }
pub struct S;
impl bomb for S { fn boom(&self, _: Ident) { } }
@@ -29,6 +27,6 @@ pub fn light_fuse(fld: Box<dyn bomb>) {
}
pub fn main() {
- let b = box S as Box<dyn bomb>;
+ let b = Box::new(S) as Box<dyn bomb>;
light_fuse(b);
}
diff --git a/src/test/ui/issues/issue-9382.rs b/src/test/ui/issues/issue-9382.rs
index dbb0fa524..65718343f 100644
--- a/src/test/ui/issues/issue-9382.rs
+++ b/src/test/ui/issues/issue-9382.rs
@@ -3,7 +3,6 @@
// run-pass
#![allow(dead_code)]
-#![feature(box_syntax)]
// Tests for a previous bug that occurred due to an interaction
// between struct field initialization and the auto-coercion
@@ -24,11 +23,11 @@ struct Thing2<'a> {
pub fn main() {
let _t1_fixed = Thing1 {
baz: &[],
- bar: box 32,
+ bar: Box::new(32),
};
Thing1 {
baz: &Vec::new(),
- bar: box 32,
+ bar: Box::new(32),
};
let _t2_fixed = Thing2 {
baz: &[],
diff --git a/src/test/ui/issues/issue-99875.rs b/src/test/ui/issues/issue-99875.rs
new file mode 100644
index 000000000..cf73fd8d3
--- /dev/null
+++ b/src/test/ui/issues/issue-99875.rs
@@ -0,0 +1,16 @@
+struct Argument;
+struct Return;
+
+fn function(_: Argument) -> Return { todo!() }
+
+trait Trait {}
+impl Trait for fn(Argument) -> Return {}
+
+fn takes(_: impl Trait) {}
+
+fn main() {
+ takes(function);
+ //~^ ERROR the trait bound
+ takes(|_: Argument| -> Return { todo!() });
+ //~^ ERROR the trait bound
+}
diff --git a/src/test/ui/issues/issue-99875.stderr b/src/test/ui/issues/issue-99875.stderr
new file mode 100644
index 000000000..3ff8f12f1
--- /dev/null
+++ b/src/test/ui/issues/issue-99875.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied
+ --> $DIR/issue-99875.rs:12:11
+ |
+LL | takes(function);
+ | ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
+note: required by a bound in `takes`
+ --> $DIR/issue-99875.rs:9:18
+ |
+LL | fn takes(_: impl Trait) {}
+ | ^^^^^ required by this bound in `takes`
+
+error[E0277]: the trait bound `[closure@$DIR/issue-99875.rs:14:11: 14:34]: Trait` is not satisfied
+ --> $DIR/issue-99875.rs:14:11
+ |
+LL | takes(|_: Argument| -> Return { todo!() });
+ | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for closure `[closure@$DIR/issue-99875.rs:14:11: 14:34]`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
+note: required by a bound in `takes`
+ --> $DIR/issue-99875.rs:9:18
+ |
+LL | fn takes(_: impl Trait) {}
+ | ^^^^^ required by this bound in `takes`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs
index a1144c8cb..7d35da825 100644
--- a/src/test/ui/iterators/collect-into-array.rs
+++ b/src/test/ui/iterators/collect-into-array.rs
@@ -4,4 +4,5 @@ fn main() {
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
//~| NOTE required by a bound in `collect`
+ //~| NOTE required by a bound introduced by this call
}
diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr
index 7be53a487..7fe9707e6 100644
--- a/src/test/ui/iterators/collect-into-array.stderr
+++ b/src/test/ui/iterators/collect-into-array.stderr
@@ -1,8 +1,10 @@
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
- --> $DIR/collect-into-array.rs:3:39
+ --> $DIR/collect-into-array.rs:3:31
|
LL | let whatever: [u32; 10] = (0..10).collect();
- | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()`
+ | ^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
= help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]`
note: required by a bound in `collect`
diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs
index aafa6bc8b..5eade0756 100644
--- a/src/test/ui/iterators/collect-into-slice.rs
+++ b/src/test/ui/iterators/collect-into-slice.rs
@@ -1,15 +1,20 @@
fn process_slice(data: &[i32]) {
//~^ NOTE required by a bound in this
+ //~| NOTE required by a bound in this
todo!()
}
fn main() {
let some_generated_vec = (0..10).collect();
//~^ ERROR the size for values of type `[i32]` cannot be known at compilation time
+ //~| ERROR the size for values of type `[i32]` cannot be known at compilation time
//~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size
//~| NOTE try explicitly collecting into a `Vec<{integer}>`
//~| NOTE required by a bound in `collect`
+ //~| NOTE required by a bound in `collect`
//~| NOTE all local variables must have a statically known size
//~| NOTE doesn't have a size known at compile-time
+ //~| NOTE doesn't have a size known at compile-time
+ //~| NOTE required by a bound introduced by this call
process_slice(&some_generated_vec);
}
diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr
index 4842e65fe..bce40118b 100644
--- a/src/test/ui/iterators/collect-into-slice.stderr
+++ b/src/test/ui/iterators/collect-into-slice.stderr
@@ -1,5 +1,5 @@
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
- --> $DIR/collect-into-slice.rs:7:9
+ --> $DIR/collect-into-slice.rs:8:9
|
LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -8,11 +8,26 @@ LL | let some_generated_vec = (0..10).collect();
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/collect-into-slice.rs:8:38
+ |
+LL | let some_generated_vec = (0..10).collect();
+ | ^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
+ | ^ required by this bound in `collect`
+
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
- --> $DIR/collect-into-slice.rs:7:38
+ --> $DIR/collect-into-slice.rs:8:30
|
LL | let some_generated_vec = (0..10).collect();
- | ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
+ | ^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | try explicitly collecting into a `Vec<{integer}>`
|
= help: the trait `FromIterator<{integer}>` is not implemented for `[i32]`
note: required by a bound in `collect`
@@ -21,6 +36,6 @@ note: required by a bound in `collect`
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/integral.stderr b/src/test/ui/iterators/integral.stderr
index 5e2744bab..047a71f98 100644
--- a/src/test/ui/iterators/integral.stderr
+++ b/src/test/ui/iterators/integral.stderr
@@ -6,7 +6,7 @@ LL | for _ in 42 {}
|
= help: the trait `Iterator` is not implemented for `{integer}`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
+ = note: required for `{integer}` to implement `IntoIterator`
error[E0277]: `u8` is not an iterator
--> $DIR/integral.rs:4:14
@@ -16,7 +16,7 @@ LL | for _ in 42 as u8 {}
|
= help: the trait `Iterator` is not implemented for `u8`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `u8`
+ = note: required for `u8` to implement `IntoIterator`
error[E0277]: `i8` is not an iterator
--> $DIR/integral.rs:6:14
@@ -26,7 +26,7 @@ LL | for _ in 42 as i8 {}
|
= help: the trait `Iterator` is not implemented for `i8`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `i8`
+ = note: required for `i8` to implement `IntoIterator`
error[E0277]: `u16` is not an iterator
--> $DIR/integral.rs:8:14
@@ -36,7 +36,7 @@ LL | for _ in 42 as u16 {}
|
= help: the trait `Iterator` is not implemented for `u16`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `u16`
+ = note: required for `u16` to implement `IntoIterator`
error[E0277]: `i16` is not an iterator
--> $DIR/integral.rs:10:14
@@ -46,7 +46,7 @@ LL | for _ in 42 as i16 {}
|
= help: the trait `Iterator` is not implemented for `i16`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `i16`
+ = note: required for `i16` to implement `IntoIterator`
error[E0277]: `u32` is not an iterator
--> $DIR/integral.rs:12:14
@@ -56,7 +56,7 @@ LL | for _ in 42 as u32 {}
|
= help: the trait `Iterator` is not implemented for `u32`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `u32`
+ = note: required for `u32` to implement `IntoIterator`
error[E0277]: `i32` is not an iterator
--> $DIR/integral.rs:14:14
@@ -66,7 +66,7 @@ LL | for _ in 42 as i32 {}
|
= help: the trait `Iterator` is not implemented for `i32`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `i32`
+ = note: required for `i32` to implement `IntoIterator`
error[E0277]: `u64` is not an iterator
--> $DIR/integral.rs:16:14
@@ -76,7 +76,7 @@ LL | for _ in 42 as u64 {}
|
= help: the trait `Iterator` is not implemented for `u64`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `u64`
+ = note: required for `u64` to implement `IntoIterator`
error[E0277]: `i64` is not an iterator
--> $DIR/integral.rs:18:14
@@ -86,7 +86,7 @@ LL | for _ in 42 as i64 {}
|
= help: the trait `Iterator` is not implemented for `i64`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `i64`
+ = note: required for `i64` to implement `IntoIterator`
error[E0277]: `usize` is not an iterator
--> $DIR/integral.rs:20:14
@@ -96,7 +96,7 @@ LL | for _ in 42 as usize {}
|
= help: the trait `Iterator` is not implemented for `usize`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `usize`
+ = note: required for `usize` to implement `IntoIterator`
error[E0277]: `isize` is not an iterator
--> $DIR/integral.rs:22:14
@@ -106,7 +106,7 @@ LL | for _ in 42 as isize {}
|
= help: the trait `Iterator` is not implemented for `isize`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `isize`
+ = note: required for `isize` to implement `IntoIterator`
error[E0277]: `{float}` is not an iterator
--> $DIR/integral.rs:24:14
@@ -115,7 +115,7 @@ LL | for _ in 42.0 {}
| ^^^^ `{float}` is not an iterator
|
= help: the trait `Iterator` is not implemented for `{float}`
- = note: required because of the requirements on the impl of `IntoIterator` for `{float}`
+ = note: required for `{float}` to implement `IntoIterator`
error: aborting due to 12 previous errors
diff --git a/src/test/ui/iterators/issue-28098.rs b/src/test/ui/iterators/issue-28098.rs
index 62a90d90d..80c77edae 100644
--- a/src/test/ui/iterators/issue-28098.rs
+++ b/src/test/ui/iterators/issue-28098.rs
@@ -2,12 +2,14 @@ fn main() {
let _ = Iterator::next(&mut ());
//~^ ERROR `()` is not an iterator
//~| ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
for _ in false {}
//~^ ERROR `bool` is not an iterator
let _ = Iterator::next(&mut ());
//~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
other()
}
@@ -18,9 +20,11 @@ pub fn other() {
let _ = Iterator::next(&mut ());
//~^ ERROR `()` is not an iterator
//~| ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
let _ = Iterator::next(&mut ());
//~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
for _ in false {}
//~^ ERROR `bool` is not an iterator
diff --git a/src/test/ui/iterators/issue-28098.stderr b/src/test/ui/iterators/issue-28098.stderr
index 3beb99292..3256e57d4 100644
--- a/src/test/ui/iterators/issue-28098.stderr
+++ b/src/test/ui/iterators/issue-28098.stderr
@@ -8,17 +8,25 @@ LL | let _ = Iterator::next(&mut ());
|
= help: the trait `Iterator` is not implemented for `()`
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:2:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
error[E0277]: `bool` is not an iterator
- --> $DIR/issue-28098.rs:6:14
+ --> $DIR/issue-28098.rs:7:14
|
LL | for _ in false {}
| ^^^^^ `bool` is not an iterator
|
= help: the trait `Iterator` is not implemented for `bool`
- = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+ = note: required for `bool` to implement `IntoIterator`
error[E0277]: `()` is not an iterator
- --> $DIR/issue-28098.rs:9:28
+ --> $DIR/issue-28098.rs:10:28
|
LL | let _ = Iterator::next(&mut ());
| -------------- ^^^^^^^ `()` is not an iterator
@@ -28,6 +36,14 @@ LL | let _ = Iterator::next(&mut ());
= help: the trait `Iterator` is not implemented for `()`
error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:10:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
--> $DIR/issue-28098.rs:2:13
|
LL | let _ = Iterator::next(&mut ());
@@ -36,7 +52,7 @@ LL | let _ = Iterator::next(&mut ());
= help: the trait `Iterator` is not implemented for `()`
error[E0277]: `()` is not an iterator
- --> $DIR/issue-28098.rs:18:28
+ --> $DIR/issue-28098.rs:20:28
|
LL | let _ = Iterator::next(&mut ());
| -------------- ^^^^^^^ `()` is not an iterator
@@ -46,7 +62,15 @@ LL | let _ = Iterator::next(&mut ());
= help: the trait `Iterator` is not implemented for `()`
error[E0277]: `()` is not an iterator
- --> $DIR/issue-28098.rs:22:28
+ --> $DIR/issue-28098.rs:20:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:25:28
|
LL | let _ = Iterator::next(&mut ());
| -------------- ^^^^^^^ `()` is not an iterator
@@ -55,23 +79,31 @@ LL | let _ = Iterator::next(&mut ());
|
= help: the trait `Iterator` is not implemented for `()`
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:25:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
error[E0277]: `bool` is not an iterator
- --> $DIR/issue-28098.rs:25:14
+ --> $DIR/issue-28098.rs:29:14
|
LL | for _ in false {}
| ^^^^^ `bool` is not an iterator
|
= help: the trait `Iterator` is not implemented for `bool`
- = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+ = note: required for `bool` to implement `IntoIterator`
error[E0277]: `()` is not an iterator
- --> $DIR/issue-28098.rs:18:13
+ --> $DIR/issue-28098.rs:20:13
|
LL | let _ = Iterator::next(&mut ());
| ^^^^^^^^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
-error: aborting due to 8 previous errors
+error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/issue-58952-filter-type-length.rs b/src/test/ui/iterators/issue-58952-filter-type-length.rs
index ffbe89a14..6d12db8d1 100644
--- a/src/test/ui/iterators/issue-58952-filter-type-length.rs
+++ b/src/test/ui/iterators/issue-58952-filter-type-length.rs
@@ -1,6 +1,6 @@
// run-pass
//! This snippet causes the type length to blowup exponentially,
-//! so check that we don't accidentially exceed the type length limit.
+//! so check that we don't accidentally exceed the type length limit.
// FIXME: Once the size of iterator adaptors is further reduced,
// increase the complexity of this test.
use std::collections::VecDeque;
diff --git a/src/test/ui/iterators/ranges.stderr b/src/test/ui/iterators/ranges.stderr
index 440a8960a..b9fbcd530 100644
--- a/src/test/ui/iterators/ranges.stderr
+++ b/src/test/ui/iterators/ranges.stderr
@@ -6,7 +6,7 @@ LL | for _ in ..10 {}
|
= help: the trait `Iterator` is not implemented for `RangeTo<{integer}>`
= note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end`
- = note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
+ = note: required for `RangeTo<{integer}>` to implement `IntoIterator`
error[E0277]: `RangeToInclusive<{integer}>` is not an iterator
--> $DIR/ranges.rs:4:14
@@ -16,7 +16,7 @@ LL | for _ in ..=10 {}
|
= help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>`
= note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end`
- = note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
+ = note: required for `RangeToInclusive<{integer}>` to implement `IntoIterator`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr
index d9c40fe1b..ddfe0169b 100644
--- a/src/test/ui/iterators/string.stderr
+++ b/src/test/ui/iterators/string.stderr
@@ -5,7 +5,7 @@ LL | for _ in "".to_owned() {}
| ^^^^^^^^^^^^^ `String` is not an iterator; try calling `.chars()` or `.bytes()`
|
= help: the trait `Iterator` is not implemented for `String`
- = note: required because of the requirements on the impl of `IntoIterator` for `String`
+ = note: required for `String` to implement `IntoIterator`
error[E0277]: `&str` is not an iterator
--> $DIR/string.rs:4:14
@@ -14,7 +14,7 @@ LL | for _ in "" {}
| ^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
|
= help: the trait `Iterator` is not implemented for `&str`
- = note: required because of the requirements on the impl of `IntoIterator` for `&str`
+ = note: required for `&str` to implement `IntoIterator`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/json-multiple.stderr b/src/test/ui/json-multiple.stderr
deleted file mode 100644
index 7ed345113..000000000
--- a/src/test/ui/json-multiple.stderr
+++ /dev/null
@@ -1 +0,0 @@
-{"artifact":"$TEST_BUILD_DIR/json-multiple/libjson_multiple.rlib","emit":"link"}
diff --git a/src/test/ui/json-options.stderr b/src/test/ui/json-options.stderr
deleted file mode 100644
index 24977731d..000000000
--- a/src/test/ui/json-options.stderr
+++ /dev/null
@@ -1 +0,0 @@
-{"artifact":"$TEST_BUILD_DIR/json-options/libjson_options.rlib","emit":"link"}
diff --git a/src/test/ui/json-and-color.rs b/src/test/ui/json/json-and-color.rs
index 6f8326fe2..6f8326fe2 100644
--- a/src/test/ui/json-and-color.rs
+++ b/src/test/ui/json/json-and-color.rs
diff --git a/src/test/ui/json-and-color.stderr b/src/test/ui/json/json-and-color.stderr
index 1cda6af09..1cda6af09 100644
--- a/src/test/ui/json-and-color.stderr
+++ b/src/test/ui/json/json-and-color.stderr
diff --git a/src/test/ui/json-and-error-format.rs b/src/test/ui/json/json-and-error-format.rs
index 6e2d73c76..6e2d73c76 100644
--- a/src/test/ui/json-and-error-format.rs
+++ b/src/test/ui/json/json-and-error-format.rs
diff --git a/src/test/ui/json-and-error-format.stderr b/src/test/ui/json/json-and-error-format.stderr
index 80e022137..80e022137 100644
--- a/src/test/ui/json-and-error-format.stderr
+++ b/src/test/ui/json/json-and-error-format.stderr
diff --git a/src/test/ui/json-bom-plus-crlf-multifile-aux.rs b/src/test/ui/json/json-bom-plus-crlf-multifile-aux.rs
index 991ea1d85..991ea1d85 100644
--- a/src/test/ui/json-bom-plus-crlf-multifile-aux.rs
+++ b/src/test/ui/json/json-bom-plus-crlf-multifile-aux.rs
diff --git a/src/test/ui/json-bom-plus-crlf-multifile.rs b/src/test/ui/json/json-bom-plus-crlf-multifile.rs
index 9290e0104..9290e0104 100644
--- a/src/test/ui/json-bom-plus-crlf-multifile.rs
+++ b/src/test/ui/json/json-bom-plus-crlf-multifile.rs
diff --git a/src/test/ui/json-bom-plus-crlf-multifile.stderr b/src/test/ui/json/json-bom-plus-crlf-multifile.stderr
index 02f3bc687..02f3bc687 100644
--- a/src/test/ui/json-bom-plus-crlf-multifile.stderr
+++ b/src/test/ui/json/json-bom-plus-crlf-multifile.stderr
diff --git a/src/test/ui/json-bom-plus-crlf.rs b/src/test/ui/json/json-bom-plus-crlf.rs
index be5b7dd2a..be5b7dd2a 100644
--- a/src/test/ui/json-bom-plus-crlf.rs
+++ b/src/test/ui/json/json-bom-plus-crlf.rs
diff --git a/src/test/ui/json-bom-plus-crlf.stderr b/src/test/ui/json/json-bom-plus-crlf.stderr
index df6bd7286..df6bd7286 100644
--- a/src/test/ui/json-bom-plus-crlf.stderr
+++ b/src/test/ui/json/json-bom-plus-crlf.stderr
diff --git a/src/test/ui/json-invalid.rs b/src/test/ui/json/json-invalid.rs
index 54d0dd184..54d0dd184 100644
--- a/src/test/ui/json-invalid.rs
+++ b/src/test/ui/json/json-invalid.rs
diff --git a/src/test/ui/json-invalid.stderr b/src/test/ui/json/json-invalid.stderr
index 18bc76ab7..18bc76ab7 100644
--- a/src/test/ui/json-invalid.stderr
+++ b/src/test/ui/json/json-invalid.stderr
diff --git a/src/test/ui/json-multiple.polonius.stderr b/src/test/ui/json/json-multiple.polonius.stderr
index 0e4d442f2..0e4d442f2 100644
--- a/src/test/ui/json-multiple.polonius.stderr
+++ b/src/test/ui/json/json-multiple.polonius.stderr
diff --git a/src/test/ui/json-multiple.rs b/src/test/ui/json/json-multiple.rs
index fb126339d..fb126339d 100644
--- a/src/test/ui/json-multiple.rs
+++ b/src/test/ui/json/json-multiple.rs
diff --git a/src/test/ui/json/json-multiple.stderr b/src/test/ui/json/json-multiple.stderr
new file mode 100644
index 000000000..55ccfd5fa
--- /dev/null
+++ b/src/test/ui/json/json-multiple.stderr
@@ -0,0 +1 @@
+{"artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"}
diff --git a/src/test/ui/json-options.polonius.stderr b/src/test/ui/json/json-options.polonius.stderr
index e21f6f85d..e21f6f85d 100644
--- a/src/test/ui/json-options.polonius.stderr
+++ b/src/test/ui/json/json-options.polonius.stderr
diff --git a/src/test/ui/json-options.rs b/src/test/ui/json/json-options.rs
index 8b6ba131e..8b6ba131e 100644
--- a/src/test/ui/json-options.rs
+++ b/src/test/ui/json/json-options.rs
diff --git a/src/test/ui/json/json-options.stderr b/src/test/ui/json/json-options.stderr
new file mode 100644
index 000000000..645a26f5a
--- /dev/null
+++ b/src/test/ui/json/json-options.stderr
@@ -0,0 +1 @@
+{"artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"}
diff --git a/src/test/ui/json-short.rs b/src/test/ui/json/json-short.rs
index 7414a5586..7414a5586 100644
--- a/src/test/ui/json-short.rs
+++ b/src/test/ui/json/json-short.rs
diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json/json-short.stderr
index 3bd85b083..3bd85b083 100644
--- a/src/test/ui/json-short.stderr
+++ b/src/test/ui/json/json-short.stderr
diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.rs b/src/test/ui/kindck/kindck-impl-type-params-2.rs
index 8b0771985..8950fc51e 100644
--- a/src/test/ui/kindck/kindck-impl-type-params-2.rs
+++ b/src/test/ui/kindck/kindck-impl-type-params-2.rs
@@ -11,5 +11,5 @@ fn take_param<T:Foo>(foo: &T) { }
fn main() {
let x: Box<_> = Box::new(3);
take_param(&x);
- //~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied
+ //~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied
}
diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
index 89975e968..930d96375 100644
--- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
+error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
--> $DIR/kindck-impl-type-params-2.rs:13:16
|
LL | take_param(&x);
@@ -6,7 +6,7 @@ LL | take_param(&x);
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
+note: required for `Box<{integer}>` to implement `Foo`
--> $DIR/kindck-impl-type-params-2.rs:6:14
|
LL | impl<T:Copy> Foo for T {
diff --git a/src/test/ui/kindck/kindck-impl-type-params.stderr b/src/test/ui/kindck/kindck-impl-type-params.stderr
index 902349135..8dbe0c38c 100644
--- a/src/test/ui/kindck/kindck-impl-type-params.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
LL | let a = &t as &dyn Gettable<T>;
| ^^ `T` cannot be sent between threads safely
|
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
--> $DIR/kindck-impl-type-params.rs:12:32
|
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -21,7 +21,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
LL | let a = &t as &dyn Gettable<T>;
| ^^ the trait `Copy` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
--> $DIR/kindck-impl-type-params.rs:12:32
|
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -38,7 +38,7 @@ error[E0277]: `T` cannot be sent between threads safely
LL | let a: &dyn Gettable<T> = &t;
| ^^ `T` cannot be sent between threads safely
|
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
--> $DIR/kindck-impl-type-params.rs:12:32
|
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -55,7 +55,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
LL | let a: &dyn Gettable<T> = &t;
| ^^ the trait `Copy` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
--> $DIR/kindck-impl-type-params.rs:12:32
|
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -73,7 +73,7 @@ LL | let a = t as Box<dyn Gettable<String>>;
| ^ the trait `Copy` is not implemented for `String`
|
= help: the trait `Gettable<T>` is implemented for `S<T>`
-note: required because of the requirements on the impl of `Gettable<String>` for `S<String>`
+note: required for `S<String>` to implement `Gettable<String>`
--> $DIR/kindck-impl-type-params.rs:12:32
|
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -87,7 +87,7 @@ LL | let a: Box<dyn Gettable<Foo>> = t;
| ^ the trait `Copy` is not implemented for `Foo`
|
= help: the trait `Gettable<T>` is implemented for `S<T>`
-note: required because of the requirements on the impl of `Gettable<Foo>` for `S<Foo>`
+note: required for `S<Foo>` to implement `Gettable<Foo>`
--> $DIR/kindck-impl-type-params.rs:12:32
|
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
index 016cd393c..e81d2441e 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
+error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
--> $DIR/kindck-inherited-copy-bound.rs:21:16
|
LL | take_param(&x);
@@ -6,7 +6,7 @@ LL | take_param(&x);
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
+note: required for `Box<{integer}>` to implement `Foo`
--> $DIR/kindck-inherited-copy-bound.rs:14:14
|
LL | impl<T:Copy> Foo for T {
@@ -44,7 +44,7 @@ LL | trait Foo : Copy {
| --- ^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<{integer}>`
+ = note: required for `&Box<{integer}>` to implement `CoerceUnsized<&dyn Foo>`
= note: required by cast to type `&dyn Foo`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
index eaf34dff4..2380533b9 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
+error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
--> $DIR/kindck-inherited-copy-bound.rs:21:16
|
LL | take_param(&x);
@@ -6,7 +6,7 @@ LL | take_param(&x);
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
+note: required for `Box<{integer}>` to implement `Foo`
--> $DIR/kindck-inherited-copy-bound.rs:14:14
|
LL | impl<T:Copy> Foo for T {
@@ -30,7 +30,7 @@ LL | trait Foo : Copy {
| --- ^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<i32>`
+ = note: required for `&Box<i32>` to implement `CoerceUnsized<&dyn Foo>`
= note: required by cast to type `&dyn Foo`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr
index eab003a11..cc6e1f59c 100644
--- a/src/test/ui/kindck/kindck-nonsendable-1.stderr
+++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr
@@ -1,10 +1,12 @@
error[E0277]: `Rc<usize>` cannot be sent between threads safely
- --> $DIR/kindck-nonsendable-1.rs:9:5
+ --> $DIR/kindck-nonsendable-1.rs:9:9
|
LL | bar(move|| foo(x));
- | ^^^ ------ within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`
- | |
- | `Rc<usize>` cannot be sent between threads safely
+ | --- ------^^^^^^^
+ | | |
+ | | `Rc<usize>` cannot be sent between threads safely
+ | | within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`
+ | required by a bound introduced by this call
|
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc<usize>`
note: required because it's used within this closure
diff --git a/src/test/ui/kindck/kindck-send-object.stderr b/src/test/ui/kindck/kindck-send-object.stderr
index f14983a51..e9bbeeacd 100644
--- a/src/test/ui/kindck/kindck-send-object.stderr
+++ b/src/test/ui/kindck/kindck-send-object.stderr
@@ -1,11 +1,11 @@
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
- --> $DIR/kindck-send-object.rs:12:5
+ --> $DIR/kindck-send-object.rs:12:19
|
LL | assert_send::<&'static (dyn Dummy + 'static)>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
- = note: required because of the requirements on the impl of `Send` for `&'static (dyn Dummy + 'static)`
+ = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object.rs:5:18
|
@@ -13,13 +13,13 @@ LL | fn assert_send<T:Send>() { }
| ^^^^ required by this bound in `assert_send`
error[E0277]: `dyn Dummy` cannot be sent between threads safely
- --> $DIR/kindck-send-object.rs:17:5
+ --> $DIR/kindck-send-object.rs:17:19
|
LL | assert_send::<Box<dyn Dummy>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
+ | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `dyn Dummy`
- = note: required because of the requirements on the impl of `Send` for `Unique<dyn Dummy>`
+ = note: required for `Unique<dyn Dummy>` to implement `Send`
= note: required because it appears within the type `Box<dyn Dummy>`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object.rs:5:18
diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr
index 1f5e21cbf..11f597fee 100644
--- a/src/test/ui/kindck/kindck-send-object1.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.stderr
@@ -1,11 +1,11 @@
error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
- --> $DIR/kindck-send-object1.rs:10:5
+ --> $DIR/kindck-send-object1.rs:10:19
|
LL | assert_send::<&'a dyn Dummy>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
+ | ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`
- = note: required because of the requirements on the impl of `Send` for `&'a (dyn Dummy + 'a)`
+ = note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object1.rs:5:18
|
@@ -13,13 +13,13 @@ LL | fn assert_send<T:Send+'static>() { }
| ^^^^ required by this bound in `assert_send`
error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
- --> $DIR/kindck-send-object1.rs:28:5
+ --> $DIR/kindck-send-object1.rs:28:19
|
LL | assert_send::<Box<dyn Dummy + 'a>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
+ | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `(dyn Dummy + 'a)`
- = note: required because of the requirements on the impl of `Send` for `Unique<(dyn Dummy + 'a)>`
+ = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send`
= note: required because it appears within the type `Box<(dyn Dummy + 'a)>`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object1.rs:5:18
diff --git a/src/test/ui/kindck/kindck-send-object2.stderr b/src/test/ui/kindck/kindck-send-object2.stderr
index 527127e95..b8af33d0d 100644
--- a/src/test/ui/kindck/kindck-send-object2.stderr
+++ b/src/test/ui/kindck/kindck-send-object2.stderr
@@ -1,11 +1,11 @@
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
- --> $DIR/kindck-send-object2.rs:7:5
+ --> $DIR/kindck-send-object2.rs:7:19
|
LL | assert_send::<&'static dyn Dummy>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
+ | ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
- = note: required because of the requirements on the impl of `Send` for `&'static (dyn Dummy + 'static)`
+ = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object2.rs:3:18
|
@@ -13,13 +13,13 @@ LL | fn assert_send<T:Send>() { }
| ^^^^ required by this bound in `assert_send`
error[E0277]: `dyn Dummy` cannot be sent between threads safely
- --> $DIR/kindck-send-object2.rs:12:5
+ --> $DIR/kindck-send-object2.rs:12:19
|
LL | assert_send::<Box<dyn Dummy>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
+ | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `dyn Dummy`
- = note: required because of the requirements on the impl of `Send` for `Unique<dyn Dummy>`
+ = note: required for `Unique<dyn Dummy>` to implement `Send`
= note: required because it appears within the type `Box<dyn Dummy>`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object2.rs:3:18
diff --git a/src/test/ui/kindck/kindck-send-owned.stderr b/src/test/ui/kindck/kindck-send-owned.stderr
index 454291aa9..b03f56465 100644
--- a/src/test/ui/kindck/kindck-send-owned.stderr
+++ b/src/test/ui/kindck/kindck-send-owned.stderr
@@ -1,11 +1,11 @@
error[E0277]: `*mut u8` cannot be sent between threads safely
- --> $DIR/kindck-send-owned.rs:12:5
+ --> $DIR/kindck-send-owned.rs:12:19
|
LL | assert_send::<Box<*mut u8>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
+ | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `*mut u8`
- = note: required because of the requirements on the impl of `Send` for `Unique<*mut u8>`
+ = note: required for `Unique<*mut u8>` to implement `Send`
= note: required because it appears within the type `Box<*mut u8>`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-owned.rs:3:18
diff --git a/src/test/ui/label/label_break_value_continue.rs b/src/test/ui/label/label_break_value_continue.rs
index e0deb30c9..22172f4fd 100644
--- a/src/test/ui/label/label_break_value_continue.rs
+++ b/src/test/ui/label/label_break_value_continue.rs
@@ -1,4 +1,3 @@
-#![feature(label_break_value)]
#![allow(unused_labels)]
// Simple continue pointing to an unlabeled break should yield in an error
diff --git a/src/test/ui/label/label_break_value_continue.stderr b/src/test/ui/label/label_break_value_continue.stderr
index 9b8693dc5..284d213d6 100644
--- a/src/test/ui/label/label_break_value_continue.stderr
+++ b/src/test/ui/label/label_break_value_continue.stderr
@@ -1,11 +1,11 @@
error[E0695]: unlabeled `continue` inside of a labeled block
- --> $DIR/label_break_value_continue.rs:7:9
+ --> $DIR/label_break_value_continue.rs:6:9
|
LL | continue;
| ^^^^^^^^ `continue` statements that would diverge to or through a labeled block need to bear a label
error[E0696]: `continue` pointing to a labeled block
- --> $DIR/label_break_value_continue.rs:14:9
+ --> $DIR/label_break_value_continue.rs:13:9
|
LL | / 'b: {
LL | | continue 'b;
@@ -14,7 +14,7 @@ LL | | }
| |_____- labeled block the `continue` points to
error[E0695]: unlabeled `continue` inside of a labeled block
- --> $DIR/label_break_value_continue.rs:22:13
+ --> $DIR/label_break_value_continue.rs:21:13
|
LL | continue;
| ^^^^^^^^ `continue` statements that would diverge to or through a labeled block need to bear a label
diff --git a/src/test/ui/label/label_break_value_desugared_break.rs b/src/test/ui/label/label_break_value_desugared_break.rs
index de883b611..70227d869 100644
--- a/src/test/ui/label/label_break_value_desugared_break.rs
+++ b/src/test/ui/label/label_break_value_desugared_break.rs
@@ -1,5 +1,5 @@
// compile-flags: --edition 2018
-#![feature(label_break_value, try_blocks)]
+#![feature(try_blocks)]
// run-pass
fn main() {
@@ -9,4 +9,11 @@ fn main() {
break 'foo;
}
};
+
+ 'foo: {
+ let _: Result<(), ()> = try {
+ Err(())?;
+ break 'foo;
+ };
+ }
}
diff --git a/src/test/ui/label/label_break_value_illegal_uses.fixed b/src/test/ui/label/label_break_value_illegal_uses.fixed
index c1d2023a2..fb75276b4 100644
--- a/src/test/ui/label/label_break_value_illegal_uses.fixed
+++ b/src/test/ui/label/label_break_value_illegal_uses.fixed
@@ -1,5 +1,4 @@
// run-rustfix
-#![feature(label_break_value)]
// These are forbidden occurrences of label-break-value
diff --git a/src/test/ui/label/label_break_value_illegal_uses.rs b/src/test/ui/label/label_break_value_illegal_uses.rs
index 5b20c95e5..3cbf41380 100644
--- a/src/test/ui/label/label_break_value_illegal_uses.rs
+++ b/src/test/ui/label/label_break_value_illegal_uses.rs
@@ -1,5 +1,4 @@
// run-rustfix
-#![feature(label_break_value)]
// These are forbidden occurrences of label-break-value
diff --git a/src/test/ui/label/label_break_value_illegal_uses.stderr b/src/test/ui/label/label_break_value_illegal_uses.stderr
index 24b733fec..15016ffd5 100644
--- a/src/test/ui/label/label_break_value_illegal_uses.stderr
+++ b/src/test/ui/label/label_break_value_illegal_uses.stderr
@@ -1,23 +1,23 @@
error: block label not supported here
- --> $DIR/label_break_value_illegal_uses.rs:8:12
+ --> $DIR/label_break_value_illegal_uses.rs:7:12
|
LL | unsafe 'b: {}
| ^^^ not supported here
error: block label not supported here
- --> $DIR/label_break_value_illegal_uses.rs:12:13
+ --> $DIR/label_break_value_illegal_uses.rs:11:13
|
LL | if true 'b: {}
| ^^^ not supported here
error: block label not supported here
- --> $DIR/label_break_value_illegal_uses.rs:16:21
+ --> $DIR/label_break_value_illegal_uses.rs:15:21
|
LL | if true {} else 'b: {}
| ^^^ not supported here
error: block label not supported here
- --> $DIR/label_break_value_illegal_uses.rs:20:17
+ --> $DIR/label_break_value_illegal_uses.rs:19:17
|
LL | match false 'b: {
| ^^^ not supported here
diff --git a/src/test/ui/label/label_break_value_unlabeled_break.rs b/src/test/ui/label/label_break_value_unlabeled_break.rs
index fa0c70edc..2a4f5d574 100644
--- a/src/test/ui/label/label_break_value_unlabeled_break.rs
+++ b/src/test/ui/label/label_break_value_unlabeled_break.rs
@@ -1,4 +1,3 @@
-#![feature(label_break_value)]
#![allow(unused_labels)]
// Simple unlabeled break should yield in an error
diff --git a/src/test/ui/label/label_break_value_unlabeled_break.stderr b/src/test/ui/label/label_break_value_unlabeled_break.stderr
index 0c4f573d2..a2ccd27b8 100644
--- a/src/test/ui/label/label_break_value_unlabeled_break.stderr
+++ b/src/test/ui/label/label_break_value_unlabeled_break.stderr
@@ -1,11 +1,11 @@
error[E0695]: unlabeled `break` inside of a labeled block
- --> $DIR/label_break_value_unlabeled_break.rs:7:9
+ --> $DIR/label_break_value_unlabeled_break.rs:6:9
|
LL | break;
| ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label
error[E0695]: unlabeled `break` inside of a labeled block
- --> $DIR/label_break_value_unlabeled_break.rs:15:13
+ --> $DIR/label_break_value_unlabeled_break.rs:14:13
|
LL | break;
| ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label
diff --git a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
index 6deb1f271..bfabe2d12 100644
--- a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
+++ b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
@@ -411,7 +411,7 @@ error: layout_of(NicheFirst) = Layout {
valid_range: 0..=4,
},
tag_encoding: Niche {
- dataful_variant: 0,
+ untagged_variant: 0,
niche_variants: 1..=2,
niche_start: 3,
},
@@ -555,7 +555,7 @@ error: layout_of(NicheSecond) = Layout {
valid_range: 0..=4,
},
tag_encoding: Niche {
- dataful_variant: 0,
+ untagged_variant: 0,
niche_variants: 1..=2,
niche_start: 3,
},
diff --git a/src/test/ui/layout/zero-sized-array-enum-niche.stderr b/src/test/ui/layout/zero-sized-array-enum-niche.stderr
index 56d3a52bb..a3e82070e 100644
--- a/src/test/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/src/test/ui/layout/zero-sized-array-enum-niche.stderr
@@ -353,7 +353,7 @@ error: layout_of(std::result::Result<[u32; 0], Packed<U16IsZero>>) = Layout {
valid_range: 0..=1,
},
tag_encoding: Niche {
- dataful_variant: 1,
+ untagged_variant: 1,
niche_variants: 0..=0,
niche_start: 1,
},
diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr
index 6b87da0c0..33f82448d 100644
--- a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr
+++ b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr
@@ -1,8 +1,10 @@
error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_`
- --> $DIR/branches.rs:19:28
+ --> $DIR/branches.rs:19:9
|
LL | std::iter::empty().collect()
- | ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
+ | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
|
= help: the trait `FromIterator<_>` is not implemented for `Bar`
note: required by a bound in `collect`
diff --git a/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr b/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr
index 42a1f782d..57978edf2 100644
--- a/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr
+++ b/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr
@@ -1,8 +1,10 @@
error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_`
- --> $DIR/recursion4.rs:10:28
+ --> $DIR/recursion4.rs:10:9
|
LL | x = std::iter::empty().collect();
- | ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
+ | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
|
= help: the trait `FromIterator<_>` is not implemented for `Foo`
note: required by a bound in `collect`
@@ -12,10 +14,12 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_`
- --> $DIR/recursion4.rs:19:28
+ --> $DIR/recursion4.rs:19:9
|
LL | x = std::iter::empty().collect();
- | ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
+ | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
+ | |
+ | value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
|
= help: the trait `FromIterator<_>` is not implemented for `impl Debug`
note: required by a bound in `collect`
diff --git a/src/test/ui/let-else/const-fn.rs b/src/test/ui/let-else/const-fn.rs
new file mode 100644
index 000000000..336b0b4b7
--- /dev/null
+++ b/src/test/ui/let-else/const-fn.rs
@@ -0,0 +1,19 @@
+// run-pass
+// issue #101932
+
+#![cfg_attr(bootstrap, feature(let_else))]
+
+const fn foo(a: Option<i32>) -> i32 {
+ let Some(a) = a else {
+ return 42
+ };
+
+ a + 1
+}
+
+fn main() {
+ const A: i32 = foo(None);
+ const B: i32 = foo(Some(1));
+
+ println!("{} {}", A, B);
+}
diff --git a/src/test/ui/let-else/issue-100103.rs b/src/test/ui/let-else/issue-100103.rs
new file mode 100644
index 000000000..f5f9b2f5f
--- /dev/null
+++ b/src/test/ui/let-else/issue-100103.rs
@@ -0,0 +1,15 @@
+// edition:2021
+// check-pass
+
+#![feature(try_blocks)]
+
+
+fn main() {
+ let _: Result<i32, i32> = try {
+ let Some(x) = Some(0) else {
+ Err(1)?
+ };
+
+ x
+ };
+}
diff --git a/src/test/ui/let-else/issue-102317.rs b/src/test/ui/let-else/issue-102317.rs
new file mode 100644
index 000000000..7369b4938
--- /dev/null
+++ b/src/test/ui/let-else/issue-102317.rs
@@ -0,0 +1,20 @@
+// issue #102317
+// build-pass
+// compile-flags: --edition 2021 -C opt-level=3 -Zvalidate-mir
+
+struct SegmentJob;
+
+impl Drop for SegmentJob {
+ fn drop(&mut self) {}
+}
+
+pub async fn run() -> Result<(), ()> {
+ let jobs = Vec::<SegmentJob>::new();
+ let Some(_job) = jobs.into_iter().next() else {
+ return Ok(())
+ };
+
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/test/ui/let-else/issue-94176.rs b/src/test/ui/let-else/issue-94176.rs
new file mode 100644
index 000000000..f76dfc15b
--- /dev/null
+++ b/src/test/ui/let-else/issue-94176.rs
@@ -0,0 +1,10 @@
+// Issue #94176: wrong span for the error message of a mismatched type error,
+// if the function uses a `let else` construct.
+
+
+pub fn test(a: Option<u32>) -> Option<u32> { //~ ERROR mismatched types
+ let Some(_) = a else { return None; };
+ println!("Foo");
+}
+
+fn main() {}
diff --git a/src/test/ui/let-else/issue-94176.stderr b/src/test/ui/let-else/issue-94176.stderr
new file mode 100644
index 000000000..0cb97acee
--- /dev/null
+++ b/src/test/ui/let-else/issue-94176.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-94176.rs:5:32
+ |
+LL | pub fn test(a: Option<u32>) -> Option<u32> {
+ | ---- ^^^^^^^^^^^ expected enum `Option`, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+ |
+ = note: expected enum `Option<u32>`
+ found unit type `()`
+help: consider returning the local binding `a`
+ |
+LL ~ println!("Foo");
+LL + a
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/let-else/issue-99975.rs b/src/test/ui/let-else/issue-99975.rs
new file mode 100644
index 000000000..5b164f347
--- /dev/null
+++ b/src/test/ui/let-else/issue-99975.rs
@@ -0,0 +1,20 @@
+// run-pass
+// compile-flags: -C opt-level=3 -Zvalidate-mir
+
+
+
+fn return_result() -> Option<String> {
+ Some("ok".to_string())
+}
+
+fn start() -> String {
+ let Some(content) = return_result() else {
+ return "none".to_string()
+ };
+
+ content
+}
+
+fn main() {
+ start();
+}
diff --git a/src/test/ui/let-else/let-else-allow-in-expr.rs b/src/test/ui/let-else/let-else-allow-in-expr.rs
index 39f4c9060..33acb6c6a 100644
--- a/src/test/ui/let-else/let-else-allow-in-expr.rs
+++ b/src/test/ui/let-else/let-else-allow-in-expr.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
#![deny(unused_variables)]
fn main() {
diff --git a/src/test/ui/let-else/let-else-allow-in-expr.stderr b/src/test/ui/let-else/let-else-allow-in-expr.stderr
index e86bcbc85..3b2b9066c 100644
--- a/src/test/ui/let-else/let-else-allow-in-expr.stderr
+++ b/src/test/ui/let-else/let-else-allow-in-expr.stderr
@@ -1,17 +1,17 @@
error: unused variable: `x`
- --> $DIR/let-else-allow-in-expr.rs:7:13
+ --> $DIR/let-else-allow-in-expr.rs:5:13
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
note: the lint level is defined here
- --> $DIR/let-else-allow-in-expr.rs:3:9
+ --> $DIR/let-else-allow-in-expr.rs:1:9
|
LL | #![deny(unused_variables)]
| ^^^^^^^^^^^^^^^^
error: unused variable: `x`
- --> $DIR/let-else-allow-in-expr.rs:29:9
+ --> $DIR/let-else-allow-in-expr.rs:27:9
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
diff --git a/src/test/ui/let-else/let-else-allow-unused.rs b/src/test/ui/let-else/let-else-allow-unused.rs
index 86ebacfa7..bbb1c7bea 100644
--- a/src/test/ui/let-else/let-else-allow-unused.rs
+++ b/src/test/ui/let-else/let-else-allow-unused.rs
@@ -1,6 +1,6 @@
// issue #89807
-#![feature(let_else)]
+
#[deny(unused_variables)]
diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs b/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs
index b65fa13c1..955f33ee1 100644
--- a/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs
+++ b/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs
@@ -1,6 +1,6 @@
// from rfc2005 test suite
-#![feature(let_else)]
+
// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the
// final default binding mode mutable.
diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs b/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs
index 63b35df76..1524d0102 100644
--- a/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs
+++ b/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs
@@ -1,8 +1,8 @@
-#![feature(let_else)]
-
// Slightly different from explicit-mut-annotated -- this won't show an error until borrowck.
// Should it show a type error instead?
+
+
fn main() {
let Some(n): &mut Option<i32> = &mut &Some(5i32) else {
//~^ ERROR cannot borrow data in a `&` reference as mutable
diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs b/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs
index 305be9221..b0a6264a1 100644
--- a/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs
+++ b/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs
@@ -1,6 +1,6 @@
// check-pass
-#![feature(let_else)]
+
fn main() {
let Some(n) = &mut &mut Some(5i32) else { return; };
diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut.rs b/src/test/ui/let-else/let-else-binding-explicit-mut.rs
index dbe4715b1..a153b3af0 100644
--- a/src/test/ui/let-else/let-else-binding-explicit-mut.rs
+++ b/src/test/ui/let-else/let-else-binding-explicit-mut.rs
@@ -1,6 +1,6 @@
// from rfc2005 test suite
-#![feature(let_else)]
+
// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the
// final default binding mode mutable.
diff --git a/src/test/ui/let-else/let-else-binding-immutable.rs b/src/test/ui/let-else/let-else-binding-immutable.rs
index 96de0ffe2..ff2d9f240 100644
--- a/src/test/ui/let-else/let-else-binding-immutable.rs
+++ b/src/test/ui/let-else/let-else-binding-immutable.rs
@@ -1,6 +1,6 @@
// from rfc2005 test suite
-#![feature(let_else)]
+
pub fn main() {
let Some(x) = &Some(3) else {
diff --git a/src/test/ui/let-else/let-else-bindings.rs b/src/test/ui/let-else/let-else-bindings.rs
index d5121e744..7d2cad978 100644
--- a/src/test/ui/let-else/let-else-bindings.rs
+++ b/src/test/ui/let-else/let-else-bindings.rs
@@ -1,6 +1,6 @@
// run-pass
// adapted from src/test/ui/binding/if-let.rs
-#![feature(let_else)]
+
#![allow(dead_code)]
fn none() -> bool {
diff --git a/src/test/ui/let-else/let-else-bool-binop-init.fixed b/src/test/ui/let-else/let-else-bool-binop-init.fixed
index e47f7f23d..20e558ca9 100644
--- a/src/test/ui/let-else/let-else-bool-binop-init.fixed
+++ b/src/test/ui/let-else/let-else-bool-binop-init.fixed
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(let_else)]
+
fn main() {
let true = (true && false) else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else`
diff --git a/src/test/ui/let-else/let-else-bool-binop-init.rs b/src/test/ui/let-else/let-else-bool-binop-init.rs
index e443fb0d6..f88179a94 100644
--- a/src/test/ui/let-else/let-else-bool-binop-init.rs
+++ b/src/test/ui/let-else/let-else-bool-binop-init.rs
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(let_else)]
+
fn main() {
let true = true && false else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else`
diff --git a/src/test/ui/let-else/let-else-brace-before-else.fixed b/src/test/ui/let-else/let-else-brace-before-else.fixed
index fb4fd7779..a75c770dd 100644
--- a/src/test/ui/let-else/let-else-brace-before-else.fixed
+++ b/src/test/ui/let-else/let-else-brace-before-else.fixed
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(let_else)]
+
fn main() {
let Some(1) = ({ Some(1) }) else {
diff --git a/src/test/ui/let-else/let-else-brace-before-else.rs b/src/test/ui/let-else/let-else-brace-before-else.rs
index c4c5a1ca2..5603b946f 100644
--- a/src/test/ui/let-else/let-else-brace-before-else.rs
+++ b/src/test/ui/let-else/let-else-brace-before-else.rs
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(let_else)]
+
fn main() {
let Some(1) = { Some(1) } else {
diff --git a/src/test/ui/let-else/let-else-check.rs b/src/test/ui/let-else/let-else-check.rs
index 9e32cbef7..713fd986e 100644
--- a/src/test/ui/let-else/let-else-check.rs
+++ b/src/test/ui/let-else/let-else-check.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
#![deny(unused_variables)]
fn main() {
diff --git a/src/test/ui/let-else/let-else-check.stderr b/src/test/ui/let-else/let-else-check.stderr
index 3d647a4c0..bdecbf708 100644
--- a/src/test/ui/let-else/let-else-check.stderr
+++ b/src/test/ui/let-else/let-else-check.stderr
@@ -1,17 +1,17 @@
error: unused variable: `x`
- --> $DIR/let-else-check.rs:14:13
+ --> $DIR/let-else-check.rs:12:13
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
note: the lint level is defined here
- --> $DIR/let-else-check.rs:3:9
+ --> $DIR/let-else-check.rs:1:9
|
LL | #![deny(unused_variables)]
| ^^^^^^^^^^^^^^^^
error: unused variable: `x`
- --> $DIR/let-else-check.rs:18:9
+ --> $DIR/let-else-check.rs:16:9
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
diff --git a/src/test/ui/let-else/let-else-deref-coercion-annotated.rs b/src/test/ui/let-else/let-else-deref-coercion-annotated.rs
index 65d88a6d8..60fdf825a 100644
--- a/src/test/ui/let-else/let-else-deref-coercion-annotated.rs
+++ b/src/test/ui/let-else/let-else-deref-coercion-annotated.rs
@@ -6,7 +6,7 @@
// Deref/DerefMut to Bar. You can do this with an irrefutable binding, so it should work with
// let-else too.
-#![feature(let_else)]
+
use std::ops::{Deref, DerefMut};
struct Foo(Bar);
diff --git a/src/test/ui/let-else/let-else-deref-coercion.rs b/src/test/ui/let-else/let-else-deref-coercion.rs
index 87489d84b..052a5a8c7 100644
--- a/src/test/ui/let-else/let-else-deref-coercion.rs
+++ b/src/test/ui/let-else/let-else-deref-coercion.rs
@@ -3,7 +3,7 @@
// We attempt to `let Bar::Present(_) = foo else { ... }` where foo is meant to Deref/DerefMut to
// Bar. This fails, you must add a type annotation like `let _: &mut Bar = _ else { ... }`
-#![feature(let_else)]
+
use std::ops::{Deref, DerefMut};
struct Foo(Bar);
diff --git a/src/test/ui/let-else/let-else-destructuring.rs b/src/test/ui/let-else/let-else-destructuring.rs
index 9a09c414a..d1f1a69bf 100644
--- a/src/test/ui/let-else/let-else-destructuring.rs
+++ b/src/test/ui/let-else/let-else-destructuring.rs
@@ -1,4 +1,3 @@
-#![feature(let_else)]
#[derive(Debug)]
enum Foo {
Done,
diff --git a/src/test/ui/let-else/let-else-destructuring.stderr b/src/test/ui/let-else/let-else-destructuring.stderr
index 95efb7116..7d6cb2386 100644
--- a/src/test/ui/let-else/let-else-destructuring.stderr
+++ b/src/test/ui/let-else/let-else-destructuring.stderr
@@ -1,11 +1,11 @@
error: <assignment> ... else { ... } is not allowed
- --> $DIR/let-else-destructuring.rs:11:9
+ --> $DIR/let-else-destructuring.rs:10:9
|
LL | &Foo::Nested(Some(value)) = value else { break };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0070]: invalid left-hand side of assignment
- --> $DIR/let-else-destructuring.rs:11:35
+ --> $DIR/let-else-destructuring.rs:10:35
|
LL | &Foo::Nested(Some(value)) = value else { break };
| ------------------------- ^
diff --git a/src/test/ui/let-else/let-else-drop-order.rs b/src/test/ui/let-else/let-else-drop-order.rs
new file mode 100644
index 000000000..e91e5de84
--- /dev/null
+++ b/src/test/ui/let-else/let-else-drop-order.rs
@@ -0,0 +1,270 @@
+// run-pass
+// edition:2021
+// check-run-results
+//
+// Drop order tests for let else
+//
+// Mostly this ensures two things:
+// 1. That let and let else temporary drop order is the same.
+// This is a specific design request: https://github.com/rust-lang/rust/pull/93628#issuecomment-1047140316
+// 2. That the else block truly only runs after the
+// temporaries have dropped.
+//
+// We also print some nice tables for an overview by humans.
+// Changes in those tables are considered breakages, but the
+// important properties 1 and 2 are also enforced by the code.
+// This is important as it's easy to update the stdout file
+// with a --bless and miss the impact of that change.
+
+
+#![allow(irrefutable_let_patterns)]
+
+use std::cell::RefCell;
+use std::rc::Rc;
+
+#[derive(Clone)]
+struct DropAccountant(Rc<RefCell<Vec<Vec<String>>>>);
+
+impl DropAccountant {
+ fn new() -> Self {
+ Self(Default::default())
+ }
+ fn build_droppy(&self, v: u32) -> Droppy<u32> {
+ Droppy(self.clone(), v)
+ }
+ fn build_droppy_enum_none(&self, _v: u32) -> ((), DroppyEnum<u32>) {
+ ((), DroppyEnum::None(self.clone()))
+ }
+ fn new_list(&self, s: impl ToString) {
+ self.0.borrow_mut().push(vec![s.to_string()]);
+ }
+ fn push(&self, s: impl ToString) {
+ let s = s.to_string();
+ let mut accounts = self.0.borrow_mut();
+ accounts.last_mut().unwrap().push(s);
+ }
+ fn print_table(&self) {
+ println!();
+
+ let accounts = self.0.borrow();
+ let before_last = &accounts[accounts.len() - 2];
+ let last = &accounts[accounts.len() - 1];
+ let before_last = get_comma_list(before_last);
+ let last = get_comma_list(last);
+ const LINES: &[&str] = &[
+ "vanilla",
+ "&",
+ "&mut",
+ "move",
+ "fn(this)",
+ "tuple",
+ "array",
+ "ref &",
+ "ref mut &mut",
+ ];
+ let max_len = LINES.iter().map(|v| v.len()).max().unwrap();
+ let max_len_before = before_last.iter().map(|v| v.len()).max().unwrap();
+ let max_len_last = last.iter().map(|v| v.len()).max().unwrap();
+
+ println!(
+ "| {: <max_len$} | {: <max_len_before$} | {: <max_len_last$} |",
+ "construct", before_last[0], last[0]
+ );
+ println!("| {:-<max_len$} | {:-<max_len_before$} | {:-<max_len_last$} |", "", "", "");
+
+ for ((l, l_before), l_last) in
+ LINES.iter().zip(before_last[1..].iter()).zip(last[1..].iter())
+ {
+ println!(
+ "| {: <max_len$} | {: <max_len_before$} | {: <max_len_last$} |",
+ l, l_before, l_last,
+ );
+ }
+ }
+ #[track_caller]
+ fn assert_all_equal_to(&self, st: &str) {
+ let accounts = self.0.borrow();
+ let last = &accounts[accounts.len() - 1];
+ let last = get_comma_list(last);
+ for line in last[1..].iter() {
+ assert_eq!(line.trim(), st.trim());
+ }
+ }
+ #[track_caller]
+ fn assert_equality_last_two_lists(&self) {
+ let accounts = self.0.borrow();
+ let last = &accounts[accounts.len() - 1];
+ let before_last = &accounts[accounts.len() - 2];
+ for (l, b) in last[1..].iter().zip(before_last[1..].iter()) {
+ if !(l == b || l == "n/a" || b == "n/a") {
+ panic!("not equal: '{last:?}' != '{before_last:?}'");
+ }
+ }
+ }
+}
+
+fn get_comma_list(sl: &[String]) -> Vec<String> {
+ std::iter::once(sl[0].clone())
+ .chain(sl[1..].chunks(2).map(|c| c.join(",")))
+ .collect::<Vec<String>>()
+}
+
+struct Droppy<T>(DropAccountant, T);
+
+impl<T> Drop for Droppy<T> {
+ fn drop(&mut self) {
+ self.0.push("drop");
+ }
+}
+
+#[allow(dead_code)]
+enum DroppyEnum<T> {
+ Some(DropAccountant, T),
+ None(DropAccountant),
+}
+
+impl<T> Drop for DroppyEnum<T> {
+ fn drop(&mut self) {
+ match self {
+ DroppyEnum::Some(acc, _inner) => acc,
+ DroppyEnum::None(acc) => acc,
+ }
+ .push("drop");
+ }
+}
+
+macro_rules! nestings_with {
+ ($construct:ident, $binding:pat, $exp:expr) => {
+ // vanilla:
+ $construct!($binding, $exp.1);
+
+ // &:
+ $construct!(&$binding, &$exp.1);
+
+ // &mut:
+ $construct!(&mut $binding, &mut ($exp.1));
+
+ {
+ // move:
+ let w = $exp;
+ $construct!(
+ $binding,
+ {
+ let w = w;
+ w
+ }
+ .1
+ );
+ }
+
+ // fn(this):
+ $construct!($binding, std::convert::identity($exp).1);
+ };
+}
+
+macro_rules! nestings {
+ ($construct:ident, $binding:pat, $exp:expr) => {
+ nestings_with!($construct, $binding, $exp);
+
+ // tuple:
+ $construct!(($binding, 77), ($exp.1, 77));
+
+ // array:
+ $construct!([$binding], [$exp.1]);
+ };
+}
+
+macro_rules! let_else {
+ ($acc:expr, $v:expr, $binding:pat, $build:ident) => {
+ let acc = $acc;
+ let v = $v;
+
+ macro_rules! let_else_construct {
+ ($arg:pat, $exp:expr) => {
+ loop {
+ let $arg = $exp else {
+ acc.push("else");
+ break;
+ };
+ acc.push("body");
+ break;
+ }
+ };
+ }
+ nestings!(let_else_construct, $binding, acc.$build(v));
+ // ref &:
+ let_else_construct!($binding, &acc.$build(v).1);
+
+ // ref mut &mut:
+ let_else_construct!($binding, &mut acc.$build(v).1);
+ };
+}
+
+macro_rules! let_ {
+ ($acc:expr, $binding:tt) => {
+ let acc = $acc;
+
+ macro_rules! let_construct {
+ ($arg:pat, $exp:expr) => {{
+ let $arg = $exp;
+ acc.push("body");
+ }};
+ }
+ let v = 0;
+ {
+ nestings_with!(let_construct, $binding, acc.build_droppy(v));
+ }
+ acc.push("n/a");
+ acc.push("n/a");
+ acc.push("n/a");
+ acc.push("n/a");
+
+ // ref &:
+ let_construct!($binding, &acc.build_droppy(v).1);
+
+ // ref mut &mut:
+ let_construct!($binding, &mut acc.build_droppy(v).1);
+ };
+}
+
+fn main() {
+ let acc = DropAccountant::new();
+
+ println!(" --- matching cases ---");
+
+ // Ensure that let and let else have the same behaviour
+ acc.new_list("let _");
+ let_!(&acc, _);
+ acc.new_list("let else _");
+ let_else!(&acc, 0, _, build_droppy);
+ acc.assert_equality_last_two_lists();
+ acc.print_table();
+
+ // Ensure that let and let else have the same behaviour
+ acc.new_list("let _v");
+ let_!(&acc, _v);
+ acc.new_list("let else _v");
+ let_else!(&acc, 0, _v, build_droppy);
+ acc.assert_equality_last_two_lists();
+ acc.print_table();
+
+ println!();
+
+ println!(" --- mismatching cases ---");
+
+ acc.new_list("let else _ mismatch");
+ let_else!(&acc, 1, DroppyEnum::Some(_, _), build_droppy_enum_none);
+ acc.new_list("let else _v mismatch");
+ let_else!(&acc, 1, DroppyEnum::Some(_, _v), build_droppy_enum_none);
+ acc.print_table();
+ // This ensures that we always drop before visiting the else case
+ acc.assert_all_equal_to("drop,else");
+
+ acc.new_list("let else 0 mismatch");
+ let_else!(&acc, 1, 0, build_droppy);
+ acc.new_list("let else 0 mismatch");
+ let_else!(&acc, 1, 0, build_droppy);
+ acc.print_table();
+ // This ensures that we always drop before visiting the else case
+ acc.assert_all_equal_to("drop,else");
+}
diff --git a/src/test/ui/let-else/let-else-drop-order.run.stdout b/src/test/ui/let-else/let-else-drop-order.run.stdout
new file mode 100644
index 000000000..01cf2f73e
--- /dev/null
+++ b/src/test/ui/let-else/let-else-drop-order.run.stdout
@@ -0,0 +1,51 @@
+ --- matching cases ---
+
+| construct | let _ | let else _ |
+| ------------ | --------- | ---------- |
+| vanilla | drop,body | drop,body |
+| & | body,drop | body,drop |
+| &mut | body,drop | body,drop |
+| move | drop,body | drop,body |
+| fn(this) | drop,body | drop,body |
+| tuple | n/a,n/a | drop,body |
+| array | n/a,n/a | drop,body |
+| ref & | body,drop | body,drop |
+| ref mut &mut | body,drop | body,drop |
+
+| construct | let _v | let else _v |
+| ------------ | --------- | ----------- |
+| vanilla | drop,body | drop,body |
+| & | body,drop | body,drop |
+| &mut | body,drop | body,drop |
+| move | drop,body | drop,body |
+| fn(this) | drop,body | drop,body |
+| tuple | n/a,n/a | drop,body |
+| array | n/a,n/a | drop,body |
+| ref & | body,drop | body,drop |
+| ref mut &mut | body,drop | body,drop |
+
+ --- mismatching cases ---
+
+| construct | let else _ mismatch | let else _v mismatch |
+| ------------ | ------------------- | -------------------- |
+| vanilla | drop,else | drop,else |
+| & | drop,else | drop,else |
+| &mut | drop,else | drop,else |
+| move | drop,else | drop,else |
+| fn(this) | drop,else | drop,else |
+| tuple | drop,else | drop,else |
+| array | drop,else | drop,else |
+| ref & | drop,else | drop,else |
+| ref mut &mut | drop,else | drop,else |
+
+| construct | let else 0 mismatch | let else 0 mismatch |
+| ------------ | ------------------- | ------------------- |
+| vanilla | drop,else | drop,else |
+| & | drop,else | drop,else |
+| &mut | drop,else | drop,else |
+| move | drop,else | drop,else |
+| fn(this) | drop,else | drop,else |
+| tuple | drop,else | drop,else |
+| array | drop,else | drop,else |
+| ref & | drop,else | drop,else |
+| ref mut &mut | drop,else | drop,else |
diff --git a/src/test/ui/let-else/let-else-if.rs b/src/test/ui/let-else/let-else-if.rs
index c3a17330d..e8c54ca7a 100644
--- a/src/test/ui/let-else/let-else-if.rs
+++ b/src/test/ui/let-else/let-else-if.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
fn main() {
let Some(_) = Some(()) else if true {
//~^ ERROR conditional `else if` is not supported for `let...else`
diff --git a/src/test/ui/let-else/let-else-if.stderr b/src/test/ui/let-else/let-else-if.stderr
index 746738bbd..c63fd61c5 100644
--- a/src/test/ui/let-else/let-else-if.stderr
+++ b/src/test/ui/let-else/let-else-if.stderr
@@ -1,5 +1,5 @@
error: conditional `else if` is not supported for `let...else`
- --> $DIR/let-else-if.rs:4:33
+ --> $DIR/let-else-if.rs:2:33
|
LL | let Some(_) = Some(()) else if true {
| ^^ expected `{`
diff --git a/src/test/ui/let-else/let-else-irrefutable.rs b/src/test/ui/let-else/let-else-irrefutable.rs
index b1e09a124..1cb68ecb8 100644
--- a/src/test/ui/let-else/let-else-irrefutable.rs
+++ b/src/test/ui/let-else/let-else-irrefutable.rs
@@ -1,6 +1,6 @@
// check-pass
-#![feature(let_else)]
+
fn main() {
let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
diff --git a/src/test/ui/let-else/let-else-missing-semicolon.rs b/src/test/ui/let-else/let-else-missing-semicolon.rs
index ed9d79f1e..d87ac90c1 100644
--- a/src/test/ui/let-else/let-else-missing-semicolon.rs
+++ b/src/test/ui/let-else/let-else-missing-semicolon.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
fn main() {
let Some(x) = Some(1) else {
return;
diff --git a/src/test/ui/let-else/let-else-missing-semicolon.stderr b/src/test/ui/let-else/let-else-missing-semicolon.stderr
index 1818a0b12..99029ff33 100644
--- a/src/test/ui/let-else/let-else-missing-semicolon.stderr
+++ b/src/test/ui/let-else/let-else-missing-semicolon.stderr
@@ -1,5 +1,5 @@
error: expected `;`, found keyword `let`
- --> $DIR/let-else-missing-semicolon.rs:6:6
+ --> $DIR/let-else-missing-semicolon.rs:4:6
|
LL | }
| ^ help: add `;` here
@@ -7,7 +7,7 @@ LL | let _ = "";
| --- unexpected token
error: expected `;`, found `}`
- --> $DIR/let-else-missing-semicolon.rs:10:6
+ --> $DIR/let-else-missing-semicolon.rs:8:6
|
LL | }
| ^ help: add `;` here
diff --git a/src/test/ui/let-else/let-else-no-double-error.rs b/src/test/ui/let-else/let-else-no-double-error.rs
index 35dcdd3f6..91fcc5d7e 100644
--- a/src/test/ui/let-else/let-else-no-double-error.rs
+++ b/src/test/ui/let-else/let-else-no-double-error.rs
@@ -1,6 +1,6 @@
// from rfc2005 test suite
-#![feature(let_else)]
+
// Without caching type lookups in FnCtxt.resolve_ty_and_def_ufcs
// the error below would be reported twice (once when checking
diff --git a/src/test/ui/let-else/let-else-non-copy.rs b/src/test/ui/let-else/let-else-non-copy.rs
index 79ed82dd1..08c07dd1a 100644
--- a/src/test/ui/let-else/let-else-non-copy.rs
+++ b/src/test/ui/let-else/let-else-non-copy.rs
@@ -10,7 +10,7 @@
//
// The move was due to mir::Place being Copy, but mir::VarDebugInfoContents not being Copy.
-#![feature(let_else)]
+
#[derive(Copy, Clone)]
struct Copyable;
diff --git a/src/test/ui/let-else/let-else-non-diverging.rs b/src/test/ui/let-else/let-else-non-diverging.rs
index a1cee335a..b5bd91ceb 100644
--- a/src/test/ui/let-else/let-else-non-diverging.rs
+++ b/src/test/ui/let-else/let-else-non-diverging.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
fn main() {
let Some(x) = Some(1) else { //~ ERROR does not diverge
Some(2)
diff --git a/src/test/ui/let-else/let-else-non-diverging.stderr b/src/test/ui/let-else/let-else-non-diverging.stderr
index 05e45f689..c999a5495 100644
--- a/src/test/ui/let-else/let-else-non-diverging.stderr
+++ b/src/test/ui/let-else/let-else-non-diverging.stderr
@@ -1,5 +1,5 @@
error[E0308]: `else` clause of `let...else` does not diverge
- --> $DIR/let-else-non-diverging.rs:4:32
+ --> $DIR/let-else-non-diverging.rs:2:32
|
LL | let Some(x) = Some(1) else {
| ________________________________^
@@ -13,7 +13,7 @@ LL | | };
= help: ...or use `match` instead of `let...else`
error[E0308]: `else` clause of `let...else` does not diverge
- --> $DIR/let-else-non-diverging.rs:7:32
+ --> $DIR/let-else-non-diverging.rs:5:32
|
LL | let Some(x) = Some(1) else {
| ________________________________^
@@ -29,7 +29,7 @@ LL | | };
= help: ...or use `match` instead of `let...else`
error[E0308]: `else` clause of `let...else` does not diverge
- --> $DIR/let-else-non-diverging.rs:12:32
+ --> $DIR/let-else-non-diverging.rs:10:32
|
LL | let Some(x) = Some(1) else { Some(2) };
| ^^^^^^^^^^^ expected `!`, found enum `Option`
diff --git a/src/test/ui/let-else/let-else-ref-bindings-pass.rs b/src/test/ui/let-else/let-else-ref-bindings-pass.rs
index f4abd6cc2..62fc65731 100644
--- a/src/test/ui/let-else/let-else-ref-bindings-pass.rs
+++ b/src/test/ui/let-else/let-else-ref-bindings-pass.rs
@@ -1,6 +1,6 @@
// check-pass
-#![feature(let_else)]
+
#![allow(unused_variables)]
fn ref_() {
diff --git a/src/test/ui/let-else/let-else-ref-bindings.rs b/src/test/ui/let-else/let-else-ref-bindings.rs
index a4cd8e8c4..687e235d4 100644
--- a/src/test/ui/let-else/let-else-ref-bindings.rs
+++ b/src/test/ui/let-else/let-else-ref-bindings.rs
@@ -1,6 +1,6 @@
-#![feature(let_else)]
#![allow(unused_variables)]
+
fn ref_() {
let bytes: Vec<u8> = b"Hello"[..].to_vec();
let some = Some(bytes);
diff --git a/src/test/ui/let-else/let-else-run-pass.rs b/src/test/ui/let-else/let-else-run-pass.rs
index 5d9662323..a0fb6c683 100644
--- a/src/test/ui/let-else/let-else-run-pass.rs
+++ b/src/test/ui/let-else/let-else-run-pass.rs
@@ -1,6 +1,6 @@
// run-pass
-#![feature(let_else)]
+
fn main() {
#[allow(dead_code)]
diff --git a/src/test/ui/let-else/let-else-scope.rs b/src/test/ui/let-else/let-else-scope.rs
index f17682db4..78a67769e 100644
--- a/src/test/ui/let-else/let-else-scope.rs
+++ b/src/test/ui/let-else/let-else-scope.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
fn main() {
let Some(x) = Some(2) else {
panic!("{}", x); //~ ERROR cannot find value `x` in this scope
diff --git a/src/test/ui/let-else/let-else-scope.stderr b/src/test/ui/let-else/let-else-scope.stderr
index 4b3936eac..3b4f09829 100644
--- a/src/test/ui/let-else/let-else-scope.stderr
+++ b/src/test/ui/let-else/let-else-scope.stderr
@@ -1,5 +1,5 @@
error[E0425]: cannot find value `x` in this scope
- --> $DIR/let-else-scope.rs:5:22
+ --> $DIR/let-else-scope.rs:3:22
|
LL | panic!("{}", x);
| ^ not found in this scope
diff --git a/src/test/ui/let-else/let-else-slicing-error.rs b/src/test/ui/let-else/let-else-slicing-error.rs
index 4022656a8..25770094b 100644
--- a/src/test/ui/let-else/let-else-slicing-error.rs
+++ b/src/test/ui/let-else/let-else-slicing-error.rs
@@ -1,5 +1,5 @@
// issue #92069
-#![feature(let_else)]
+
fn main() {
let nums = vec![5, 4, 3, 2, 1];
diff --git a/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs b/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs
index 2aa17ae8c..ee378abcf 100644
--- a/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs
+++ b/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs
@@ -1,7 +1,7 @@
// run-pass
// issue #89688
-#![feature(let_else)]
+
fn example_let_else(value: Option<String>) {
let Some(inner) = value else {
diff --git a/src/test/ui/let-else/let-else-temp-borrowck.rs b/src/test/ui/let-else/let-else-temp-borrowck.rs
index 3910d35e7..6b4642d2f 100644
--- a/src/test/ui/let-else/let-else-temp-borrowck.rs
+++ b/src/test/ui/let-else/let-else-temp-borrowck.rs
@@ -3,7 +3,7 @@
// from issue #93951, where borrowck complained the temporary that `foo(&x)` was stored in was to
// be dropped sometime after `x` was. It then suggested adding a semicolon that was already there.
-#![feature(let_else)]
+
use std::fmt::Debug;
fn foo<'a>(x: &'a str) -> Result<impl Debug + 'a, ()> {
diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs
index 9c86901b9..c23eaa997 100644
--- a/src/test/ui/let-else/let-else-temporary-lifetime.rs
+++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs
@@ -1,5 +1,5 @@
// run-pass
-#![feature(let_else)]
+// compile-flags: -Zvalidate-mir
use std::fmt::Display;
use std::rc::Rc;
@@ -75,6 +75,17 @@ fn main() {
}
}
{
+ fn must_pass() {
+ let rc = Rc::new(());
+ let &None = &Some(Rc::clone(&rc)) else {
+ Rc::try_unwrap(rc).unwrap();
+ return;
+ };
+ unreachable!();
+ }
+ must_pass();
+ }
+ {
// test let-else drops temps before else block
// NOTE: this test has to be the last block in the `main`
// body.
diff --git a/src/test/ui/let-else/let-else-then-diverge.rs b/src/test/ui/let-else/let-else-then-diverge.rs
new file mode 100644
index 000000000..1c8f7d758
--- /dev/null
+++ b/src/test/ui/let-else/let-else-then-diverge.rs
@@ -0,0 +1,19 @@
+//
+// popped up in in #94012, where an alternative desugaring was
+// causing unreachable code errors
+
+
+#![deny(unused_variables)]
+#![deny(unreachable_code)]
+
+fn let_else_diverge() -> bool {
+ let Some(_) = Some("test") else {
+ let x = 5; //~ ERROR unused variable: `x`
+ return false;
+ };
+ return true;
+}
+
+fn main() {
+ let_else_diverge();
+}
diff --git a/src/test/ui/let-else/let-else-then-diverge.stderr b/src/test/ui/let-else/let-else-then-diverge.stderr
new file mode 100644
index 000000000..ceb61029d
--- /dev/null
+++ b/src/test/ui/let-else/let-else-then-diverge.stderr
@@ -0,0 +1,14 @@
+error: unused variable: `x`
+ --> $DIR/let-else-then-diverge.rs:11:13
+ |
+LL | let x = 5;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+note: the lint level is defined here
+ --> $DIR/let-else-then-diverge.rs:6:9
+ |
+LL | #![deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/let-else/let-else.rs b/src/test/ui/let-else/let-else.rs
new file mode 100644
index 000000000..3505533e6
--- /dev/null
+++ b/src/test/ui/let-else/let-else.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+fn main() {
+ let Some(x) = Some(1) else {
+ return;
+ };
+ assert_eq!(x, 1);
+}
diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr
index 3b2a062c1..08e4be2c0 100644
--- a/src/test/ui/lexical-scopes.stderr
+++ b/src/test/ui/lexical-scopes.stderr
@@ -1,6 +1,8 @@
error[E0574]: expected struct, variant or union type, found type parameter `T`
--> $DIR/lexical-scopes.rs:3:13
|
+LL | fn f<T>() {
+ | - found this type parameter
LL | let t = T { i: 0 };
| ^ not a struct, variant or union type
diff --git a/src/test/ui/lifetimes/fullwidth-ampersand.rs b/src/test/ui/lifetimes/fullwidth-ampersand.rs
new file mode 100644
index 000000000..7d8948bd8
--- /dev/null
+++ b/src/test/ui/lifetimes/fullwidth-ampersand.rs
@@ -0,0 +1,7 @@
+// Verify that we do not ICE when the user uses a multubyte ampersand.
+
+fn f(_: &&()) -> &() { todo!() }
+//~^ ERROR unknown start of token: \u{ff06}
+//~| ERROR missing lifetime specifier [E0106]
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/fullwidth-ampersand.stderr b/src/test/ui/lifetimes/fullwidth-ampersand.stderr
new file mode 100644
index 000000000..4645254f4
--- /dev/null
+++ b/src/test/ui/lifetimes/fullwidth-ampersand.stderr
@@ -0,0 +1,26 @@
+error: unknown start of token: \u{ff06}
+ --> $DIR/fullwidth-ampersand.rs:3:10
+ |
+LL | fn f(_: &&()) -> &() { todo!() }
+ | ^^
+ |
+help: Unicode character '&' (Fullwidth Ampersand) looks like '&' (Ampersand), but it is not
+ |
+LL | fn f(_: &&()) -> &() { todo!() }
+ | ~
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/fullwidth-ampersand.rs:3:18
+ |
+LL | fn f(_: &&()) -> &() { todo!() }
+ | ----- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say which one of argument 1's 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn f<'a>(_: &'a &'a ()) -> &'a () { todo!() }
+ | ++++ ++ ++ ++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/lifetimes/issue-26638.stderr b/src/test/ui/lifetimes/issue-26638.stderr
index f3af5cf5a..98d39d614 100644
--- a/src/test/ui/lifetimes/issue-26638.stderr
+++ b/src/test/ui/lifetimes/issue-26638.stderr
@@ -54,7 +54,7 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
help: provide the argument
|
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) }
- | ~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/issue-26638.rs:5:47
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
index 7a2eba518..d0a8fe795 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
@@ -42,4 +42,10 @@ fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
panic!()
}
+fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
+//~^ ERROR missing lifetime specifier
+
+// This is ok because both `'a` are for the same parameter.
+fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
+
fn main() {}
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index d07754879..5eee953ef 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -70,6 +70,18 @@ help: consider using the `'a` lifetime
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
| ++
-error: aborting due to 6 previous errors
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37
+ |
+LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
+ | ------- ------- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'a` lifetime
+ |
+LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
+ | ++
+
+error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/lifetimes/missing-lifetime-in-alias.rs b/src/test/ui/lifetimes/missing-lifetime-in-alias.rs
index af7b64127..51c564c01 100644
--- a/src/test/ui/lifetimes/missing-lifetime-in-alias.rs
+++ b/src/test/ui/lifetimes/missing-lifetime-in-alias.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
trait Trait<'a> {
type Foo;
diff --git a/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr b/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr
index b8c68a460..428b8f14b 100644
--- a/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr
+++ b/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr
@@ -1,5 +1,5 @@
error[E0106]: missing lifetime specifier
- --> $DIR/missing-lifetime-in-alias.rs:22:24
+ --> $DIR/missing-lifetime-in-alias.rs:20:24
|
LL | type B<'a> = <A<'a> as Trait>::Foo;
| ^^^^^ expected named lifetime parameter
@@ -10,13 +10,13 @@ LL | type B<'a> = <A<'a> as Trait<'a>>::Foo;
| ++++
error[E0106]: missing lifetime specifier
- --> $DIR/missing-lifetime-in-alias.rs:26:28
+ --> $DIR/missing-lifetime-in-alias.rs:24:28
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
| ^^^^^ expected named lifetime parameter
|
note: these named lifetimes are available to use
- --> $DIR/missing-lifetime-in-alias.rs:26:8
+ --> $DIR/missing-lifetime-in-alias.rs:24:8
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
| ^^ ^^
@@ -26,13 +26,13 @@ LL | type C<'a, 'b> = <A<'a> as Trait<'lifetime>>::Bar;
| +++++++++++
error[E0107]: missing generics for associated type `Trait::Bar`
- --> $DIR/missing-lifetime-in-alias.rs:26:36
+ --> $DIR/missing-lifetime-in-alias.rs:24:36
|
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
| ^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'b`
- --> $DIR/missing-lifetime-in-alias.rs:6:10
+ --> $DIR/missing-lifetime-in-alias.rs:4:10
|
LL | type Bar<'b>
| ^^^ --
diff --git a/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
new file mode 100644
index 000000000..645bc7db0
--- /dev/null
+++ b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
@@ -0,0 +1,9 @@
+fn no_restriction<T>(x: &()) -> &() {
+ with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () {
+ x
+}
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
new file mode 100644
index 000000000..a8b0996d8
--- /dev/null
+++ b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
@@ -0,0 +1,23 @@
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
+ |
+LL | with_restriction::<T>(x)
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+ --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:1:25
+ |
+LL | fn no_restriction<T>(x: &()) -> &() {
+ | ^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+ --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
+ |
+LL | with_restriction::<T>(x)
+ | ^^^^^^^^^^^^^^^^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
+ | +++ ++++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/limits/issue-17913.rs b/src/test/ui/limits/issue-17913.rs
index ca13b9bd6..8d4cbe201 100644
--- a/src/test/ui/limits/issue-17913.rs
+++ b/src/test/ui/limits/issue-17913.rs
@@ -6,18 +6,16 @@
// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-#![feature(box_syntax)]
-
#[cfg(target_pointer_width = "64")]
fn main() {
let n = 0_usize;
- let a: Box<_> = box [&n; 0xF000000000000000_usize];
+ let a: Box<_> = Box::new([&n; 0xF000000000000000_usize]);
println!("{}", a[0xFFFFFF_usize]);
}
#[cfg(target_pointer_width = "32")]
fn main() {
let n = 0_usize;
- let a: Box<_> = box [&n; 0xFFFFFFFF_usize];
+ let a: Box<_> = Box::new([&n; 0xFFFFFFFF_usize]);
println!("{}", a[0xFFFFFF_usize]);
}
diff --git a/src/test/ui/linkage-attr/link-attr-validation-early.stderr b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
index d36601ed0..903141e43 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-early.stderr
+++ b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
@@ -1,4 +1,4 @@
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
--> $DIR/link-attr-validation-early.rs:2:1
|
LL | #[link]
@@ -8,7 +8,7 @@ LL | #[link]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
--> $DIR/link-attr-validation-early.rs:4:1
|
LL | #[link = "foo"]
diff --git a/src/test/ui/linkage-attr/link-attr-validation-late.stderr b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
index bb08f9a4c..dd0f1dba2 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-late.stderr
+++ b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
@@ -1,10 +1,10 @@
-error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
--> $DIR/link-attr-validation-late.rs:5:22
|
LL | #[link(name = "...", "literal")]
| ^^^^^^^^^
-error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
--> $DIR/link-attr-validation-late.rs:6:22
|
LL | #[link(name = "...", unknown)]
diff --git a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
index 8d826bd14..94d81c3aa 100644
--- a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
@@ -9,9 +9,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/allowed-group-warn-by-default-lint.rs:10:25
@@ -23,9 +22,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/allowed-group-warn-by-default-lint.rs:10:25
@@ -37,9 +35,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: 3 warnings emitted
diff --git a/src/test/ui/lint/force-warn/cap-lints-allow.stderr b/src/test/ui/lint/force-warn/cap-lints-allow.stderr
index 978270872..7f0fd8530 100644
--- a/src/test/ui/lint/force-warn/cap-lints-allow.stderr
+++ b/src/test/ui/lint/force-warn/cap-lints-allow.stderr
@@ -9,9 +9,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/cap-lints-allow.rs:8:25
@@ -23,9 +22,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/cap-lints-allow.rs:8:25
@@ -37,9 +35,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: 3 warnings emitted
diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
index 6e67ebf27..eb2bca7b8 100644
--- a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
@@ -9,9 +9,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
@@ -23,9 +22,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
@@ -37,9 +35,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: 3 warnings emitted
diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
index c5dea84b8..ed01937a5 100644
--- a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
+++ b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
@@ -9,9 +9,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/lint-group-allowed-lint-group.rs:10:25
@@ -23,9 +22,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/lint-group-allowed-lint-group.rs:10:25
@@ -37,9 +35,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: 3 warnings emitted
diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
index acd0c503d..8db7c1275 100644
--- a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
@@ -9,9 +9,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
@@ -23,9 +22,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
@@ -37,9 +35,8 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub fn function(_x: Box<SomeTrait>) {}
-LL + pub fn function(_x: Box<dyn SomeTrait>) {}
- |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
warning: 3 warnings emitted
diff --git a/src/test/ui/lint/issue-101284.rs b/src/test/ui/lint/issue-101284.rs
new file mode 100644
index 000000000..1381d4f17
--- /dev/null
+++ b/src/test/ui/lint/issue-101284.rs
@@ -0,0 +1,15 @@
+// check-pass
+// edition:2021
+#![deny(rust_2021_compatibility)]
+
+pub struct Warns {
+ // `Arc` has significant drop
+ _significant_drop: std::sync::Arc<()>,
+ field: String,
+}
+
+pub fn test(w: Warns) {
+ _ = || drop(w.field);
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
index c66037e9a..b4fc33174 100644
--- a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
+++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
@@ -5,7 +5,7 @@
// If you turn off deduplicate diagnostics (which rustc turns on by default but
// compiletest turns off when it runs ui tests), then the errors are
// (unfortunately) repeated here because the checking is done as we read in the
-// errors, and curretly that happens two or three different times, depending on
+// errors, and currently that happens two or three different times, depending on
// compiler flags.
//
// I decided avoiding the redundant output was not worth the time in engineering
diff --git a/src/test/ui/lint/let_underscore/let_underscore_drop.rs b/src/test/ui/lint/let_underscore/let_underscore_drop.rs
new file mode 100644
index 000000000..f298871f1
--- /dev/null
+++ b/src/test/ui/lint/let_underscore/let_underscore_drop.rs
@@ -0,0 +1,14 @@
+// check-pass
+#![warn(let_underscore_drop)]
+
+struct NontrivialDrop;
+
+impl Drop for NontrivialDrop {
+ fn drop(&mut self) {
+ println!("Dropping!");
+ }
+}
+
+fn main() {
+ let _ = NontrivialDrop; //~WARNING non-binding let on a type that implements `Drop`
+}
diff --git a/src/test/ui/lint/let_underscore/let_underscore_drop.stderr b/src/test/ui/lint/let_underscore/let_underscore_drop.stderr
new file mode 100644
index 000000000..7b7de202e
--- /dev/null
+++ b/src/test/ui/lint/let_underscore/let_underscore_drop.stderr
@@ -0,0 +1,22 @@
+warning: non-binding let on a type that implements `Drop`
+ --> $DIR/let_underscore_drop.rs:13:5
+ |
+LL | let _ = NontrivialDrop;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/let_underscore_drop.rs:2:9
+ |
+LL | #![warn(let_underscore_drop)]
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider binding to an unused variable to avoid immediately dropping the value
+ |
+LL | let _unused = NontrivialDrop;
+ | ~~~~~~~
+help: consider immediately dropping the value
+ |
+LL | drop(NontrivialDrop);
+ | ~~~~~ +
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/lint/let_underscore/let_underscore_lock.rs b/src/test/ui/lint/let_underscore/let_underscore_lock.rs
new file mode 100644
index 000000000..7423862cd
--- /dev/null
+++ b/src/test/ui/lint/let_underscore/let_underscore_lock.rs
@@ -0,0 +1,7 @@
+// check-fail
+use std::sync::{Arc, Mutex};
+
+fn main() {
+ let data = Arc::new(Mutex::new(0));
+ let _ = data.lock().unwrap(); //~ERROR non-binding let on a synchronization lock
+}
diff --git a/src/test/ui/lint/let_underscore/let_underscore_lock.stderr b/src/test/ui/lint/let_underscore/let_underscore_lock.stderr
new file mode 100644
index 000000000..fb58af0a4
--- /dev/null
+++ b/src/test/ui/lint/let_underscore/let_underscore_lock.stderr
@@ -0,0 +1,20 @@
+error: non-binding let on a synchronization lock
+ --> $DIR/let_underscore_lock.rs:6:9
+ |
+LL | let _ = data.lock().unwrap();
+ | ^ ^^^^^^^^^^^^^^^^^^^^ this binding will immediately drop the value assigned to it
+ | |
+ | this lock is not assigned to a binding and is immediately dropped
+ |
+ = note: `#[deny(let_underscore_lock)]` on by default
+help: consider binding to an unused variable to avoid immediately dropping the value
+ |
+LL | let _unused = data.lock().unwrap();
+ | ~~~~~~~
+help: consider immediately dropping the value
+ |
+LL | drop(data.lock().unwrap());
+ | ~~~~~ +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.rs b/src/test/ui/lint/lint-attr-everywhere-early.rs
new file mode 100644
index 000000000..fd0c4b43e
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-early.rs
@@ -0,0 +1,176 @@
+// Tests that lint levels can be set for early lints.
+#![allow(non_camel_case_types, unsafe_code, while_true, unused_parens)]
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+fn verify_no_warnings() {
+ type non_camel_type = i32; // non_camel_case_types
+ struct NON_CAMEL_IS_ALLOWED; // non_camel_case_types
+ unsafe {} // unsafe_code
+ enum Enum {
+ VARIANT_CAMEL // non_camel_case_types
+ }
+ fn generics<foo>() {} // non_camel_case_types
+ while true {} // while_true
+ type T = (i32); // unused_parens
+}
+
+
+// ################## Types
+
+#[deny(non_camel_case_types)]
+type type_outer = i32; //~ ERROR type `type_outer` should have an upper camel case name
+
+type BareFnPtr = fn(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+// There aren't any early lints that currently apply to the variadic spot.
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(non_camel_case_types)]
+struct ITEM_OUTER; //~ ERROR type `ITEM_OUTER` should have an upper camel case name
+
+mod module_inner {
+ #![deny(unsafe_code)]
+ fn f() {
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ }
+}
+
+struct Associated;
+impl Associated {
+ #![deny(unsafe_code)]
+
+ fn inherent_denied_from_inner() { unsafe {} } //~ usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn inherent_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const INHERENT_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+}
+
+trait trait_inner { //~ ERROR trait `trait_inner` should have an upper camel case name
+ #![deny(non_camel_case_types)]
+}
+
+trait AssociatedTrait {
+ #![deny(unsafe_code)]
+
+ fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+ #[deny(non_camel_case_types)]
+ type assoc_type; //~ ERROR associated type `assoc_type` should have an upper camel case name
+}
+
+impl AssociatedTrait for Associated {
+ #![deny(unsafe_code)]
+
+ fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+ #[deny(unused_parens)]
+ type assoc_type = (i32); //~ ERROR unnecessary parentheses around type
+}
+
+struct StructFields {
+ #[deny(unused_parens)]f1: (i32), //~ ERROR unnecessary parentheses around type
+}
+struct StructTuple(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+
+enum Enum {
+ #[deny(non_camel_case_types)]
+ VARIANT_CAMEL, //~ ERROR variant `VARIANT_CAMEL` should have an upper camel case name
+}
+
+extern "C" {
+ #![deny(unused_parens)]
+
+ fn foreign_denied_from_inner(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+extern "C" {
+ #[deny(unused_parens)]
+ fn foreign_denied_from_outer(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+fn function(#[deny(unused_parens)] param: (i32)) {} //~ ERROR unnecessary parentheses around type
+
+fn generics<#[deny(non_camel_case_types)]foo>() {} //~ ERROR type parameter `foo` should have an upper camel case name
+
+
+// ################## Statements
+fn statements() {
+ #[deny(unused_parens)]
+ let x = (1); //~ ERROR unnecessary parentheses around assigned value
+}
+
+
+// ################## Expressions
+fn expressions() {
+ let closure = |#[deny(unused_parens)] param: (i32)| {}; //~ ERROR unnecessary parentheses around type
+
+ struct Match{f1: i32}
+ // Strangely unused_parens doesn't fire with {f1: (123)}
+ let f = Match{#[deny(unused_parens)]f1: {(123)}}; //~ ERROR unnecessary parentheses around block return value
+
+ match f {
+ #![deny(unsafe_code)]
+
+ #[deny(while_true)]
+ Match{f1} => {
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ while true {} //~ ERROR denote infinite loops with
+ }
+ }
+
+ // Statement Block
+ {
+ #![deny(unsafe_code)]
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ }
+ let block_tail = {
+ #[deny(unsafe_code)]
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ };
+
+ // Before expression as a statement.
+ #[deny(unsafe_code)]
+ unsafe {}; //~ ERROR usage of an `unsafe` block
+
+ [#[deny(unsafe_code)] unsafe {123}]; //~ ERROR usage of an `unsafe` block
+ (#[deny(unsafe_code)] unsafe {123},); //~ ERROR usage of an `unsafe` block
+ fn call(p: i32) {}
+ call(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+ struct TupleStruct(i32);
+ TupleStruct(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+}
+
+
+// ################## Patterns
+fn patterns() {
+ struct PatField{f1: i32, f2: i32};
+ let f = PatField{f1: 1, f2: 2};
+ match f {
+ PatField {
+ #[deny(ellipsis_inclusive_range_patterns)]
+ f1: 0...100,
+ //~^ ERROR range patterns are deprecated
+ //~| WARNING this is accepted in the current edition
+ ..
+ } => {}
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.stderr b/src/test/ui/lint/lint-attr-everywhere-early.stderr
new file mode 100644
index 000000000..1d6e3cda4
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-early.stderr
@@ -0,0 +1,486 @@
+error: type `type_outer` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:22:6
+ |
+LL | type type_outer = i32;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `TypeOuter`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:21:8
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:24:43
+ |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:24:28
+ |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - type BareFnPtr = fn(#[deny(unused_parens)](i32));
+LL + type BareFnPtr = fn(#[deny(unused_parens)]i32);
+ |
+
+error: type `ITEM_OUTER` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:30:8
+ |
+LL | struct ITEM_OUTER;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `ItemOuter`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:29:8
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:35:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:33:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:43:39
+ |
+LL | fn inherent_denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:41:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:46:24
+ |
+LL | fn inherent_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:45:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:49:34
+ |
+LL | const INHERENT_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:48:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: trait `trait_inner` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:52:7
+ |
+LL | trait trait_inner {
+ | ^^^^^^^^^^^ help: convert the identifier to upper camel case: `TraitInner`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:53:13
+ |
+LL | #![deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:59:30
+ |
+LL | fn denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:57:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:62:21
+ |
+LL | fn assoc_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:61:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:65:31
+ |
+LL | const ASSOC_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:64:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: associated type `assoc_type` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:68:10
+ |
+LL | type assoc_type;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `AssocType`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:67:12
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:74:30
+ |
+LL | fn denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:72:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:77:21
+ |
+LL | fn assoc_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:76:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:80:31
+ |
+LL | const ASSOC_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:79:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:83:23
+ |
+LL | type assoc_type = (i32);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:82:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - type assoc_type = (i32);
+LL + type assoc_type = i32;
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:87:31
+ |
+LL | #[deny(unused_parens)]f1: (i32),
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:87:12
+ |
+LL | #[deny(unused_parens)]f1: (i32),
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - #[deny(unused_parens)]f1: (i32),
+LL + #[deny(unused_parens)]f1: i32,
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:89:42
+ |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:89:27
+ |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - struct StructTuple(#[deny(unused_parens)](i32));
+LL + struct StructTuple(#[deny(unused_parens)]i32);
+ |
+
+error: variant `VARIANT_CAMEL` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:93:5
+ |
+LL | VARIANT_CAMEL,
+ | ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `VariantCamel`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:92:12
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:99:37
+ |
+LL | fn foreign_denied_from_inner(x: (i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:97:13
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn foreign_denied_from_inner(x: (i32));
+LL + fn foreign_denied_from_inner(x: i32);
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:104:37
+ |
+LL | fn foreign_denied_from_outer(x: (i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:103:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn foreign_denied_from_outer(x: (i32));
+LL + fn foreign_denied_from_outer(x: i32);
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:107:43
+ |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:107:20
+ |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn function(#[deny(unused_parens)] param: (i32)) {}
+LL + fn function(#[deny(unused_parens)] param: i32) {}
+ |
+
+error: type parameter `foo` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:109:42
+ |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+ | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:109:20
+ |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-attr-everywhere-early.rs:115:13
+ |
+LL | let x = (1);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:114:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let x = (1);
+LL + let x = 1;
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:121:50
+ |
+LL | let closure = |#[deny(unused_parens)] param: (i32)| {};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:121:27
+ |
+LL | let closure = |#[deny(unused_parens)] param: (i32)| {};
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let closure = |#[deny(unused_parens)] param: (i32)| {};
+LL + let closure = |#[deny(unused_parens)] param: i32| {};
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/lint-attr-everywhere-early.rs:125:46
+ |
+LL | let f = Match{#[deny(unused_parens)]f1: {(123)}};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:125:26
+ |
+LL | let f = Match{#[deny(unused_parens)]f1: {(123)}};
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let f = Match{#[deny(unused_parens)]f1: {(123)}};
+LL + let f = Match{#[deny(unused_parens)]f1: {123}};
+ |
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:132:13
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:128:17
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:133:13
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:130:16
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:140:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:139:17
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:144:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:143:16
+ |
+LL | #[deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:149:5
+ |
+LL | unsafe {};
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:148:12
+ |
+LL | #[deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:151:27
+ |
+LL | [#[deny(unsafe_code)] unsafe {123}];
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:151:13
+ |
+LL | [#[deny(unsafe_code)] unsafe {123}];
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:152:27
+ |
+LL | (#[deny(unsafe_code)] unsafe {123},);
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:152:13
+ |
+LL | (#[deny(unsafe_code)] unsafe {123},);
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:154:31
+ |
+LL | call(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:154:17
+ |
+LL | call(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:156:38
+ |
+LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:156:24
+ |
+LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^
+
+error: `...` range patterns are deprecated
+ --> $DIR/lint-attr-everywhere-early.rs:167:18
+ |
+LL | f1: 0...100,
+ | ^^^ help: use `..=` for an inclusive range
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:166:20
+ |
+LL | #[deny(ellipsis_inclusive_range_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: aborting due to 36 previous errors
+
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.rs b/src/test/ui/lint/lint-attr-everywhere-late.rs
new file mode 100644
index 000000000..1055157d6
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-late.rs
@@ -0,0 +1,197 @@
+// Tests that lint levels can be set for late lints.
+#![allow(
+ non_snake_case,
+ overflowing_literals,
+ missing_docs,
+ dyn_drop,
+ enum_intrinsics_non_enums,
+ clashing_extern_declarations
+)]
+
+extern crate core;
+use core::mem::{Discriminant, discriminant};
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+pub fn missing_docs_allowed() {} // missing_docs
+fn dyn_drop_allowed(_x: Box<dyn Drop>) {} // dyn_drop
+fn verify_no_warnings() {
+ discriminant::<i32>(&123); // enum_intrinsics_non_enums
+ let x: u8 = 1000; // overflowing_literals
+ let NON_SNAKE_CASE = 1; // non_snake_case
+}
+mod clashing_extern_allowed {
+ extern "C" {
+ fn extern_allowed();
+ }
+}
+extern "C" {
+ fn extern_allowed(_: i32); // clashing_extern_declarations
+}
+
+// ################## Types
+
+#[deny(missing_docs)]
+pub type MissingDocType = i32; //~ ERROR missing documentation for a type alias
+
+// There aren't any late lints that I can find that can be easily used with types.
+// type BareFnPtr = fn(#[deny()]i32);
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(missing_docs)]
+pub struct ItemOuter; //~ ERROR missing documentation for a struct
+
+pub mod module_inner { //~ ERROR missing documentation for a module
+ #![deny(missing_docs)]
+ pub fn missing_inner() {} //~ ERROR missing documentation for a function
+}
+
+pub struct Associated;
+impl Associated {
+ #![deny(missing_docs)]
+
+ pub fn inherent_denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+impl Associated {
+ #[deny(missing_docs)]
+ pub fn inherent_fn() {} //~ ERROR missing documentation for an associated function
+
+ #[deny(missing_docs)]
+ pub const INHERENT_CONST: i32 = 1; //~ ERROR missing documentation for an associated constant
+}
+
+pub trait TraitInner { //~ ERROR missing documentation for a trait
+ #![deny(missing_docs)]
+}
+
+pub trait AssociatedTraitInner { //~ ERROR missing documentation for a trait
+ #![deny(missing_docs)]
+
+ fn denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+pub trait AssociatedTrait {
+ fn denied_from_inner(_x: Box<dyn Drop>) {} // Used below
+
+ #[deny(missing_docs)]
+ fn assoc_fn() {} //~ ERROR missing documentation for an associated function
+
+ #[deny(missing_docs)]
+ const ASSOC_CONST: u8 = 1; //~ ERROR missing documentation for an associated constant
+
+ #[deny(missing_docs)]
+ type AssocType; //~ ERROR missing documentation for an associated type
+}
+
+struct Foo;
+
+impl AssociatedTrait for Associated {
+ #![deny(dyn_drop)]
+
+ fn denied_from_inner(_x: Box<dyn Drop>) {} //~ ERROR types that do not implement `Drop`
+
+ #[deny(enum_intrinsics_non_enums)]
+ fn assoc_fn() { discriminant::<i32>(&123); } //~ ERROR the return value of
+
+ #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; //~ ERROR literal out of range
+ type AssocType = i32;
+}
+
+
+// There aren't any late lints that can apply to a field that I can find.
+// non_snake_case doesn't work on fields
+// struct StructFields {
+// #[deny()]f1: i32,
+// }
+// struct StructTuple(#[deny()]i32);
+
+pub enum Enum {
+ #[deny(missing_docs)]
+ Variant1, //~ ERROR missing documentation for a variant
+}
+
+mod clashing_extern {
+ extern "C" {
+ fn clashing1();
+ fn clashing2();
+ }
+}
+extern "C" {
+ #![deny(clashing_extern_declarations)]
+ fn clashing1(_: i32); //~ ERROR `clashing1` redeclared with a different signature
+}
+
+extern "C" {
+ #[deny(clashing_extern_declarations)]
+ fn clashing2(_: i32); //~ ERROR `clashing2` redeclared with a different signature
+}
+
+fn function(#[deny(non_snake_case)] PARAM: i32) {} //~ ERROR variable `PARAM` should have a snake case name
+// There aren't any late lints that can apply to generics that I can find.
+// fn generics<#[deny()]T>() {}
+
+
+// ################## Statements
+fn statements() {
+ #[deny(enum_intrinsics_non_enums)]
+ let _ = discriminant::<i32>(&123); //~ ERROR the return value of
+}
+
+
+// ################## Expressions
+fn expressions() {
+ let closure = |#[deny(non_snake_case)] PARAM: i32| {}; //~ ERROR variable `PARAM` should have a snake case name
+
+ struct Match{f1: i32}
+ // I can't find any late lints for patterns.
+ // let f = Match{#[deny()]f1: 123};
+
+ let f = Match{f1: 123};
+ match f {
+ #![deny(enum_intrinsics_non_enums)]
+ Match{f1} => {
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ }
+ match f {
+ #[deny(enum_intrinsics_non_enums)]
+ Match{f1} => {
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ }
+
+ // Statement Block
+ {
+ #![deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ let block_tail = {
+ #[deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ };
+
+ // Before expression as a statement.
+ #[deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+
+ [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; //~ ERROR the return value of
+ (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); //~ ERROR the return value of
+ fn call(p: Discriminant<i32>) {}
+ call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+ struct TupleStruct(Discriminant<i32>);
+ TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+}
+
+
+// ################## Patterns
+fn patterns() {
+ // There aren't any late lints that I can find that apply to pattern fields.
+ //
+ // struct PatField{f1: i32, f2: i32};
+ // let f = PatField{f1: 1, f2: 2};
+ // let PatField{#[deny()]f1, #[deny()]..} = f;
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.stderr b/src/test/ui/lint/lint-attr-everywhere-late.stderr
new file mode 100644
index 000000000..977843997
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-late.stderr
@@ -0,0 +1,428 @@
+error: missing documentation for a type alias
+ --> $DIR/lint-attr-everywhere-late.rs:35:1
+ |
+LL | pub type MissingDocType = i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:34:8
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+ --> $DIR/lint-attr-everywhere-late.rs:43:1
+ |
+LL | pub struct ItemOuter;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:42:8
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a module
+ --> $DIR/lint-attr-everywhere-late.rs:45:1
+ |
+LL | pub mod module_inner {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:46:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-attr-everywhere-late.rs:47:5
+ |
+LL | pub fn missing_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:54:5
+ |
+LL | pub fn inherent_denied_from_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:52:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:59:5
+ |
+LL | pub fn inherent_fn() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:58:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+ --> $DIR/lint-attr-everywhere-late.rs:62:5
+ |
+LL | pub const INHERENT_CONST: i32 = 1;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:61:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-attr-everywhere-late.rs:65:1
+ |
+LL | pub trait TraitInner {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:66:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-attr-everywhere-late.rs:69:1
+ |
+LL | pub trait AssociatedTraitInner {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:70:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:72:5
+ |
+LL | fn denied_from_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:79:5
+ |
+LL | fn assoc_fn() {}
+ | ^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:78:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+ --> $DIR/lint-attr-everywhere-late.rs:82:5
+ |
+LL | const ASSOC_CONST: u8 = 1;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:81:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+ --> $DIR/lint-attr-everywhere-late.rs:85:5
+ |
+LL | type AssocType;
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:84:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a variant
+ --> $DIR/lint-attr-everywhere-late.rs:112:5
+ |
+LL | Variant1,
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:111:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: `clashing1` redeclared with a different signature
+ --> $DIR/lint-attr-everywhere-late.rs:123:5
+ |
+LL | fn clashing1();
+ | --------------- `clashing1` previously declared here
+...
+LL | fn clashing1(_: i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:122:13
+ |
+LL | #![deny(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected `unsafe extern "C" fn()`
+ found `unsafe extern "C" fn(i32)`
+
+error: `clashing2` redeclared with a different signature
+ --> $DIR/lint-attr-everywhere-late.rs:128:5
+ |
+LL | fn clashing2();
+ | --------------- `clashing2` previously declared here
+...
+LL | fn clashing2(_: i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:127:12
+ |
+LL | #[deny(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected `unsafe extern "C" fn()`
+ found `unsafe extern "C" fn(i32)`
+
+error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
+ --> $DIR/lint-attr-everywhere-late.rs:93:38
+ |
+LL | fn denied_from_inner(_x: Box<dyn Drop>) {}
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:91:13
+ |
+LL | #![deny(dyn_drop)]
+ | ^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:96:21
+ |
+LL | fn assoc_fn() { discriminant::<i32>(&123); }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:95:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:96:41
+ |
+LL | fn assoc_fn() { discriminant::<i32>(&123); }
+ | ^^^^
+
+error: literal out of range for `u8`
+ --> $DIR/lint-attr-everywhere-late.rs:98:59
+ |
+LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:98:12
+ |
+LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+ | ^^^^^^^^^^^^^^^^^^^^
+ = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
+
+error: variable `PARAM` should have a snake case name
+ --> $DIR/lint-attr-everywhere-late.rs:131:37
+ |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+ | ^^^^^ help: convert the identifier to snake case: `param`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:131:20
+ |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+ | ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:139:13
+ |
+LL | let _ = discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:138:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:139:33
+ |
+LL | let _ = discriminant::<i32>(&123);
+ | ^^^^
+
+error: variable `PARAM` should have a snake case name
+ --> $DIR/lint-attr-everywhere-late.rs:145:44
+ |
+LL | let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+ | ^^^^^ help: convert the identifier to snake case: `param`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:145:27
+ |
+LL | let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+ | ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:155:13
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:153:17
+ |
+LL | #![deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:155:33
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:161:13
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:159:16
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:161:33
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:168:9
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:167:17
+ |
+LL | #![deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:168:29
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:172:9
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:171:16
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:172:29
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:177:5
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:176:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:177:25
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:179:41
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:179:13
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:179:61
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:180:41
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:180:13
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:180:61
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:182:45
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:182:17
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:182:65
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:184:52
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:184:24
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:184:72
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^
+
+error: aborting due to 31 previous errors
+
diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs
new file mode 100644
index 000000000..1bc4a3812
--- /dev/null
+++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs
@@ -0,0 +1,30 @@
+// edition:2018
+// compile-flags: -Zdrop-tracking
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ i: i64
+}
+
+struct Bar {
+ u: Umm,
+}
+
+async fn other() {}
+
+impl Bar {
+ async fn uhoh(&mut self) {
+ let guard = &mut self.u; //~ ERROR `Umm` held across
+
+ other().await;
+
+ *guard = Umm {
+ i: 2
+ }
+ }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
new file mode 100644
index 000000000..c49d27128
--- /dev/null
+++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
@@ -0,0 +1,27 @@
+error: reference to `Umm` held across a suspend point, but should not be
+ --> $DIR/ref-drop-tracking.rs:19:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+LL |
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: the lint level is defined here
+ --> $DIR/ref-drop-tracking.rs:4:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref-drop-tracking.rs:19:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/ref-drop-tracking.rs:19:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr b/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr
new file mode 100644
index 000000000..0157c8b7f
--- /dev/null
+++ b/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr
@@ -0,0 +1,27 @@
+error: reference to `Umm` held across a suspend point, but should not be
+ --> $DIR/ref.rs:21:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+LL |
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: the lint level is defined here
+ --> $DIR/ref.rs:6:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref.rs:21:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/ref.rs:21:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/ref.stderr b/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
index 5f000014c..438e6489e 100644
--- a/src/test/ui/lint/must_not_suspend/ref.stderr
+++ b/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
@@ -1,5 +1,5 @@
error: `Umm` held across a suspend point, but should not be
- --> $DIR/ref.rs:18:26
+ --> $DIR/ref.rs:21:26
|
LL | let guard = &mut self.u;
| ^^^^^^
@@ -8,17 +8,17 @@ LL | other().await;
| ------ the value is held across this suspend point
|
note: the lint level is defined here
- --> $DIR/ref.rs:3:9
+ --> $DIR/ref.rs:6:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
note: You gotta use Umm's, ya know?
- --> $DIR/ref.rs:18:26
+ --> $DIR/ref.rs:21:26
|
LL | let guard = &mut self.u;
| ^^^^^^
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
- --> $DIR/ref.rs:18:26
+ --> $DIR/ref.rs:21:26
|
LL | let guard = &mut self.u;
| ^^^^^^
diff --git a/src/test/ui/lint/must_not_suspend/ref.rs b/src/test/ui/lint/must_not_suspend/ref.rs
index 738dd9e04..f6b23746f 100644
--- a/src/test/ui/lint/must_not_suspend/ref.rs
+++ b/src/test/ui/lint/must_not_suspend/ref.rs
@@ -1,10 +1,13 @@
// edition:2018
+// revisions: no_drop_tracking drop_tracking
+// [drop_tracking] compile-flags: -Zdrop-tracking=yes
+// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
#![feature(must_not_suspend)]
#![deny(must_not_suspend)]
#[must_not_suspend = "You gotta use Umm's, ya know?"]
struct Umm {
- i: i64
+ i: i64,
}
struct Bar {
@@ -19,11 +22,8 @@ impl Bar {
other().await;
- *guard = Umm {
- i: 2
- }
+ *guard = Umm { i: 2 }
}
}
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs
index 5cd323c01..dae258407 100644
--- a/src/test/ui/lint/uninitialized-zeroed.rs
+++ b/src/test/ui/lint/uninitialized-zeroed.rs
@@ -100,6 +100,18 @@ fn main() {
let _val: [bool; 2] = mem::zeroed();
let _val: [bool; 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+ let _val: i32 = mem::zeroed();
+ let _val: i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: f32 = mem::zeroed();
+ let _val: f32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: *const () = mem::zeroed();
+ let _val: *const () = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: *const [()] = mem::zeroed();
+ let _val: *const [()] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
// Transmute-from-0
let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization
let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
@@ -114,13 +126,12 @@ fn main() {
let _val: Option<&'static i32> = mem::zeroed();
let _val: Option<fn()> = mem::zeroed();
let _val: MaybeUninit<&'static i32> = mem::zeroed();
- let _val: i32 = mem::zeroed();
let _val: bool = MaybeUninit::zeroed().assume_init();
let _val: [bool; 0] = MaybeUninit::uninit().assume_init();
let _val: [!; 0] = MaybeUninit::zeroed().assume_init();
+
// Some things that happen to work due to rustc implementation details,
// but are not guaranteed to keep working.
- let _val: i32 = mem::uninitialized();
let _val: OneFruit = mem::uninitialized();
}
}
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
index 88121a183..b46042e7b 100644
--- a/src/test/ui/lint/uninitialized-zeroed.stderr
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -97,7 +97,7 @@ LL | let _val: (i32, !) = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
- = note: the `!` type has no valid value
+ = note: integers must not be uninitialized
error: the type `Void` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:57:26
@@ -414,8 +414,52 @@ LL | let _val: [bool; 2] = mem::uninitialized();
|
= note: booleans must be either `true` or `false`
+error: the type `i32` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:104:25
+ |
+LL | let _val: i32 = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: integers must not be uninitialized
+
+error: the type `f32` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:107:25
+ |
+LL | let _val: f32 = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: floats must not be uninitialized
+
+error: the type `*const ()` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:110:31
+ |
+LL | let _val: *const () = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: raw pointers must not be uninitialized
+
+error: the type `*const [()]` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:113:33
+ |
+LL | let _val: *const [()] = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: raw pointers must not be uninitialized
+
error: the type `&i32` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:104:34
+ --> $DIR/uninitialized-zeroed.rs:116:34
|
LL | let _val: &'static i32 = mem::transmute(0usize);
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -426,7 +470,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize);
= note: references must be non-null
error: the type `&[i32]` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:105:36
+ --> $DIR/uninitialized-zeroed.rs:117:36
|
LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -437,7 +481,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
= note: references must be non-null
error: the type `NonZeroU32` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:106:32
+ --> $DIR/uninitialized-zeroed.rs:118:32
|
LL | let _val: NonZeroU32 = mem::transmute(0);
| ^^^^^^^^^^^^^^^^^
@@ -448,7 +492,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0);
= note: `std::num::NonZeroU32` must be non-null
error: the type `NonNull<i32>` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:109:34
+ --> $DIR/uninitialized-zeroed.rs:121:34
|
LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -459,7 +503,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
= note: `std::ptr::NonNull<i32>` must be non-null
error: the type `NonNull<i32>` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:110:34
+ --> $DIR/uninitialized-zeroed.rs:122:34
|
LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -470,7 +514,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
= note: `std::ptr::NonNull<i32>` must be non-null
error: the type `bool` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:111:26
+ --> $DIR/uninitialized-zeroed.rs:123:26
|
LL | let _val: bool = MaybeUninit::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -480,5 +524,5 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init();
|
= note: booleans must be either `true` or `false`
-error: aborting due to 39 previous errors
+error: aborting due to 43 previous errors
diff --git a/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr
index c501aa25f..f2e616899 100644
--- a/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr
+++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr
@@ -11,12 +11,6 @@ LL | #![deny(unused)]
| ^^^^^^
= note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
-error: unused variable: `x`
- --> $DIR/issue-54180-unused-ref-field.rs:29:45
- |
-LL | let _: i32 = points.iter().map(|Point { x, y }| y).sum();
- | ^ help: try ignoring the field: `x: _`
-
error: unused variable: `f1`
--> $DIR/issue-54180-unused-ref-field.rs:26:13
|
@@ -29,5 +23,11 @@ error: unused variable: `x`
LL | Point { y, ref mut x } => y,
| ^^^^^^^^^ help: try ignoring the field: `x: _`
+error: unused variable: `x`
+ --> $DIR/issue-54180-unused-ref-field.rs:29:45
+ |
+LL | let _: i32 = points.iter().map(|Point { x, y }| y).sum();
+ | ^ help: try ignoring the field: `x: _`
+
error: aborting due to 4 previous errors
diff --git a/src/test/ui/lint/unused/lint-unused-variables.stderr b/src/test/ui/lint/unused/lint-unused-variables.stderr
index d6e684e83..fd9a5bcbf 100644
--- a/src/test/ui/lint/unused/lint-unused-variables.stderr
+++ b/src/test/ui/lint/unused/lint-unused-variables.stderr
@@ -17,55 +17,55 @@ LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `a`
- --> $DIR/lint-unused-variables.rs:68:9
+ --> $DIR/lint-unused-variables.rs:22:9
|
LL | a: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_a`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:74:9
+ --> $DIR/lint-unused-variables.rs:29:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:42:9
+ --> $DIR/lint-unused-variables.rs:34:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:47:9
+ --> $DIR/lint-unused-variables.rs:42:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
-error: unused variable: `a`
- --> $DIR/lint-unused-variables.rs:22:9
- |
-LL | a: i32,
- | ^ help: if this is intentional, prefix it with an underscore: `_a`
-
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:29:9
+ --> $DIR/lint-unused-variables.rs:47:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:34:9
+ --> $DIR/lint-unused-variables.rs:55:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:55:9
+ --> $DIR/lint-unused-variables.rs:60:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
+error: unused variable: `a`
+ --> $DIR/lint-unused-variables.rs:68:9
+ |
+LL | a: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:60:9
+ --> $DIR/lint-unused-variables.rs:74:9
|
LL | b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.rs b/src/test/ui/lint/unused/unused_attributes-must_use.rs
index 1c4abb949..51f868706 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.rs
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.rs
@@ -122,4 +122,10 @@ fn main() {
Some(res) => res,
None => 0,
};
+
+ struct PatternField {
+ foo: i32,
+ }
+ let s = PatternField { #[must_use] foo: 123 }; //~ ERROR `#[must_use]` has no effect
+ let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
}
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
index 317d81c59..dd112c23e 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
@@ -105,6 +105,18 @@ error: `#[must_use]` has no effect when applied to an match arm
LL | #[must_use]
| ^^^^^^^^^^^
+error: `#[must_use]` has no effect when applied to a struct field
+ --> $DIR/unused_attributes-must_use.rs:129:28
+ |
+LL | let s = PatternField { #[must_use] foo: 123 };
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a pattern field
+ --> $DIR/unused_attributes-must_use.rs:130:24
+ |
+LL | let PatternField { #[must_use] foo } = s;
+ | ^^^^^^^^^^^
+
error: `#[must_use]` has no effect when applied to an associated const
--> $DIR/unused_attributes-must_use.rs:68:5
|
@@ -171,5 +183,5 @@ error: unused return value of `Use::get_four` that must be used
LL | ().get_four();
| ^^^^^^^^^^^^^^
-error: aborting due to 26 previous errors
+error: aborting due to 28 previous errors
diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs
index 8a3568f65..87a5392fd 100644
--- a/src/test/ui/lint/unused_labels.rs
+++ b/src/test/ui/lint/unused_labels.rs
@@ -4,7 +4,6 @@
// check-pass
-#![feature(label_break_value)]
#![warn(unused_labels)]
fn main() {
diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr
index 85adc9ab3..846da792b 100644
--- a/src/test/ui/lint/unused_labels.stderr
+++ b/src/test/ui/lint/unused_labels.stderr
@@ -1,5 +1,5 @@
warning: label name `'many_used_shadowed` shadows a label name that is already in scope
- --> $DIR/unused_labels.rs:62:9
+ --> $DIR/unused_labels.rs:61:9
|
LL | 'many_used_shadowed: for _ in 0..10 {
| ------------------- first declared here
@@ -8,55 +8,55 @@ LL | 'many_used_shadowed: for _ in 0..10 {
| ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope
warning: unused label
- --> $DIR/unused_labels.rs:11:5
+ --> $DIR/unused_labels.rs:10:5
|
LL | 'unused_while_label: while 0 == 0 {
| ^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/unused_labels.rs:8:9
+ --> $DIR/unused_labels.rs:7:9
|
LL | #![warn(unused_labels)]
| ^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:16:5
+ --> $DIR/unused_labels.rs:15:5
|
LL | 'unused_while_let_label: while let Some(_) = opt {
| ^^^^^^^^^^^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:20:5
+ --> $DIR/unused_labels.rs:19:5
|
LL | 'unused_for_label: for _ in 0..10 {
| ^^^^^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:36:9
+ --> $DIR/unused_labels.rs:35:9
|
LL | 'unused_loop_label_inner_2: for _ in 0..10 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:42:5
+ --> $DIR/unused_labels.rs:41:5
|
LL | 'unused_loop_label_outer_3: for _ in 0..10 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:60:5
+ --> $DIR/unused_labels.rs:59:5
|
LL | 'many_used_shadowed: for _ in 0..10 {
| ^^^^^^^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:72:5
+ --> $DIR/unused_labels.rs:71:5
|
LL | 'unused_loop_label: loop {
| ^^^^^^^^^^^^^^^^^^
warning: unused label
- --> $DIR/unused_labels.rs:78:5
+ --> $DIR/unused_labels.rs:77:5
|
LL | 'unused_block_label: {
| ^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/unused_parens_multibyte_recovery.rs b/src/test/ui/lint/unused_parens_multibyte_recovery.rs
new file mode 100644
index 000000000..8fcfae22a
--- /dev/null
+++ b/src/test/ui/lint/unused_parens_multibyte_recovery.rs
@@ -0,0 +1,11 @@
+// ignore-tidy-trailing-newlines
+//
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: format argument must be a string literal
+//
+// Verify that unused parens lint does not try to create a span
+// which points in the middle of a multibyte character.
+
+fn f(){(print!(á \ No newline at end of file
diff --git a/src/test/ui/lint/unused_parens_multibyte_recovery.stderr b/src/test/ui/lint/unused_parens_multibyte_recovery.stderr
new file mode 100644
index 000000000..a0302b17e
--- /dev/null
+++ b/src/test/ui/lint/unused_parens_multibyte_recovery.stderr
@@ -0,0 +1,43 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:17
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:17
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:17
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: format argument must be a string literal
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:16
+ |
+LL | fn f(){(print!(á
+ | ^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | fn f(){(print!("{}", á
+ | +++++
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/liveness/liveness-consts.stderr b/src/test/ui/liveness/liveness-consts.stderr
index adaf54316..16209d16c 100644
--- a/src/test/ui/liveness/liveness-consts.stderr
+++ b/src/test/ui/liveness/liveness-consts.stderr
@@ -39,12 +39,6 @@ warning: unused variable: `z`
LL | pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] {
| ^ help: if this is intentional, prefix it with an underscore: `_z`
-warning: unused variable: `z`
- --> $DIR/liveness-consts.rs:60:13
- |
-LL | let z = 42;
- | ^ help: if this is intentional, prefix it with an underscore: `_z`
-
warning: value assigned to `t` is never read
--> $DIR/liveness-consts.rs:42:9
|
@@ -59,5 +53,11 @@ warning: unused variable: `w`
LL | let w = 10;
| ^ help: if this is intentional, prefix it with an underscore: `_w`
+warning: unused variable: `z`
+ --> $DIR/liveness-consts.rs:60:13
+ |
+LL | let z = 42;
+ | ^ help: if this is intentional, prefix it with an underscore: `_z`
+
warning: 8 warnings emitted
diff --git a/src/test/ui/lowering/issue-96847.rs b/src/test/ui/lowering/issue-96847.rs
new file mode 100644
index 000000000..2aa34c8b3
--- /dev/null
+++ b/src/test/ui/lowering/issue-96847.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+// Test that this doesn't abort during AST lowering. In #96847 it did abort
+// because the attribute was being lowered twice.
+
+#![feature(stmt_expr_attributes)]
+#![feature(lang_items)]
+
+fn main() {
+ for _ in [1,2,3] {
+ #![lang="foo"]
+ println!("foo");
+ }
+}
diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr
deleted file mode 100644
index 217392aa3..000000000
--- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown debugging option: `borrowck`
-
diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr
deleted file mode 100644
index 217392aa3..000000000
--- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown debugging option: `borrowck`
-
diff --git a/src/test/ui/macros/auxiliary/issue-100199.rs b/src/test/ui/macros/auxiliary/issue-100199.rs
new file mode 100644
index 000000000..9e190b542
--- /dev/null
+++ b/src/test/ui/macros/auxiliary/issue-100199.rs
@@ -0,0 +1,18 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro_quote)]
+
+extern crate proc_macro;
+
+use proc_macro::{quote, Ident, Span, TokenStream, TokenTree};
+
+#[proc_macro_attribute]
+pub fn struct_with_bound(_: TokenStream, _: TokenStream) -> TokenStream {
+ let crate_ident = TokenTree::Ident(Ident::new("crate", Span::call_site()));
+ let trait_ident = TokenTree::Ident(Ident::new("MyTrait", Span::call_site()));
+ quote!(
+ struct Foo<T: $crate_ident::$trait_ident> {}
+ )
+}
diff --git a/src/test/ui/macros/issue-100199.rs b/src/test/ui/macros/issue-100199.rs
new file mode 100644
index 000000000..6e50afa07
--- /dev/null
+++ b/src/test/ui/macros/issue-100199.rs
@@ -0,0 +1,16 @@
+#[issue_100199::struct_with_bound] //~ ERROR cannot find trait `MyTrait` in the crate root
+struct Foo {}
+// The above must be on the first line so that it's span points to pos 0.
+// This used to trigger an ICE because the diagnostic emitter would get
+// an unexpected dummy span (lo == 0 == hi) while attempting to print a
+// suggestion.
+
+// aux-build: issue-100199.rs
+
+extern crate issue_100199;
+
+mod traits {
+ pub trait MyTrait {}
+}
+
+fn main() {}
diff --git a/src/test/ui/macros/issue-100199.stderr b/src/test/ui/macros/issue-100199.stderr
new file mode 100644
index 000000000..2cb45dc12
--- /dev/null
+++ b/src/test/ui/macros/issue-100199.stderr
@@ -0,0 +1,15 @@
+error[E0405]: cannot find trait `MyTrait` in the crate root
+ --> $DIR/issue-100199.rs:1:1
+ |
+LL | #[issue_100199::struct_with_bound]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root
+ |
+ = note: this error originates in the attribute macro `issue_100199::struct_with_bound` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this trait
+ |
+LL | use traits::MyTrait;
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs
index f246aa26a..dd159cb5b 100644
--- a/src/test/ui/macros/stringify.rs
+++ b/src/test/ui/macros/stringify.rs
@@ -3,11 +3,17 @@
// compile-flags: --test
#![feature(async_closure)]
+#![feature(box_patterns)]
+#![feature(box_syntax)]
#![feature(const_trait_impl)]
+#![feature(decl_macro)]
#![feature(generators)]
#![feature(half_open_range_patterns)]
#![feature(more_qualified_paths)]
#![feature(raw_ref_op)]
+#![feature(trait_alias)]
+#![feature(try_blocks)]
+#![feature(type_ascription)]
#![deny(unused_macros)]
macro_rules! stringify_block {
@@ -865,8 +871,9 @@ fn test_vis() {
assert_eq!(stringify_vis!(pub(crate)), "pub(crate) ");
assert_eq!(stringify_vis!(pub(self)), "pub(self) ");
assert_eq!(stringify_vis!(pub(super)), "pub(super) ");
- assert_eq!(stringify_vis!(pub(in self)), "pub(self) ");
- assert_eq!(stringify_vis!(pub(in super)), "pub(super) ");
+ assert_eq!(stringify_vis!(pub(in crate)), "pub(in crate) ");
+ assert_eq!(stringify_vis!(pub(in self)), "pub(in self) ");
+ assert_eq!(stringify_vis!(pub(in super)), "pub(in super) ");
assert_eq!(stringify_vis!(pub(in path::to)), "pub(in path::to) ");
assert_eq!(stringify_vis!(pub(in ::path::to)), "pub(in ::path::to) ");
assert_eq!(stringify_vis!(pub(in self::path::to)), "pub(in self::path::to) ");
diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index 13c12ff72..8c2625bdf 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -26,7 +26,7 @@ LL | #[inline = ""]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
--> $DIR/malformed-regressions.rs:7:1
|
LL | #[link]
@@ -35,7 +35,7 @@ LL | #[link]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
--> $DIR/malformed-regressions.rs:9:1
|
LL | #[link = ""]
diff --git a/src/test/ui/match/issue-42679.rs b/src/test/ui/match/issue-42679.rs
index 596309f25..46a0bd35d 100644
--- a/src/test/ui/match/issue-42679.rs
+++ b/src/test/ui/match/issue-42679.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(box_syntax)]
#![feature(box_patterns)]
#[derive(Debug, PartialEq)]
@@ -9,13 +8,13 @@ enum Test {
}
fn main() {
- let a = box Test::Foo(10);
- let b = box Test::Bar(-20);
+ let a = Box::new(Test::Foo(10));
+ let b = Box::new(Test::Bar(-20));
match (a, b) {
(_, box Test::Foo(_)) => unreachable!(),
(box Test::Foo(x), b) => {
assert_eq!(x, 10);
- assert_eq!(b, box Test::Bar(-20));
+ assert_eq!(b, Box::new(Test::Bar(-20)));
},
_ => unreachable!(),
}
diff --git a/src/test/ui/match/match_non_exhaustive.rs b/src/test/ui/match/match_non_exhaustive.rs
index 8219f0eb1..f162dd60f 100644
--- a/src/test/ui/match/match_non_exhaustive.rs
+++ b/src/test/ui/match/match_non_exhaustive.rs
@@ -21,7 +21,7 @@ fn main() {
match l { L::A => (), L::B => () };
// (except if the match is already non-exhaustive)
match l { L::A => () };
- //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
+ //~^ ERROR: non-exhaustive patterns: `L::B` not covered [E0004]
// E1 is not visibly uninhabited from here
let (e1, e2) = bar();
diff --git a/src/test/ui/match/match_non_exhaustive.stderr b/src/test/ui/match/match_non_exhaustive.stderr
index 9d92f8fdb..46ee8d517 100644
--- a/src/test/ui/match/match_non_exhaustive.stderr
+++ b/src/test/ui/match/match_non_exhaustive.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `B` not covered
+error[E0004]: non-exhaustive patterns: `L::B` not covered
--> $DIR/match_non_exhaustive.rs:23:11
|
LL | match l { L::A => () };
- | ^ pattern `B` not covered
+ | ^ pattern `L::B` not covered
|
note: `L` defined here
--> $DIR/match_non_exhaustive.rs:10:13
@@ -12,8 +12,8 @@ LL | enum L { A, B }
= note: the matched value is of type `L`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
-LL | match l { L::A => (), B => todo!() };
- | ++++++++++++++
+LL | match l { L::A => (), L::B => todo!() };
+ | +++++++++++++++++
error[E0004]: non-exhaustive patterns: type `E1` is non-empty
--> $DIR/match_non_exhaustive.rs:28:11
diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr
index 690fe8fa7..a4ffb864d 100644
--- a/src/test/ui/methods/method-call-err-msg.stderr
+++ b/src/test/ui/methods/method-call-err-msg.stderr
@@ -8,11 +8,11 @@ note: associated function defined here
--> $DIR/method-call-err-msg.rs:5:8
|
LL | fn zero(self) -> Foo { self }
- | ^^^^ ----
+ | ^^^^
help: remove the extra argument
|
LL | x.zero()
- | ~~~~~~
+ | ~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/method-call-err-msg.rs:14:7
@@ -24,11 +24,11 @@ note: associated function defined here
--> $DIR/method-call-err-msg.rs:6:8
|
LL | fn one(self, _: isize) -> Foo { self }
- | ^^^ ---- --------
+ | ^^^ --------
help: provide the argument
|
LL | .one(/* isize */)
- | ~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/method-call-err-msg.rs:15:7
@@ -40,11 +40,11 @@ note: associated function defined here
--> $DIR/method-call-err-msg.rs:7:8
|
LL | fn two(self, _: isize, _: isize) -> Foo { self }
- | ^^^ ---- -------- --------
+ | ^^^ -------- --------
help: provide the argument
|
LL | .two(0, /* isize */);
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~
error[E0599]: `Foo` is not an iterator
--> $DIR/method-call-err-msg.rs:19:7
@@ -80,11 +80,11 @@ note: associated function defined here
--> $DIR/method-call-err-msg.rs:8:8
|
LL | fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
- | ^^^^^ ---- ---- ---- ----
+ | ^^^^^ ---- ---- ----
help: provide the arguments
|
LL | y.three::<usize>(/* usize */, /* usize */, /* usize */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 5 previous errors
diff --git a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr
index 0af58bc61..917334116 100644
--- a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr
+++ b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr
@@ -18,7 +18,7 @@ LL | let x = y.neg();
help: you must specify a type for this binding, like `f32`
|
LL | let y: f32 = 2.0;
- | ~~~~~~
+ | +++++
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
--> $DIR/method-on-ambiguous-numeric-type.rs:19:26
@@ -37,7 +37,7 @@ LL | local_bar.pow(2);
help: you must specify a type for this binding, like `i32`
|
LL | ($ident:ident) => { let $ident: i32 = 42; }
- | ~~~~~~~~~~~
+ | +++++
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
--> $DIR/method-on-ambiguous-numeric-type.rs:30:9
@@ -46,10 +46,10 @@ LL | bar.pow(2);
| ^^^
|
help: you must specify a type for this binding, like `i32`
- --> $DIR/auxiliary/macro-in-other-crate.rs:3:29
+ --> $DIR/auxiliary/macro-in-other-crate.rs:3:35
|
LL | ($ident:ident) => { let $ident: i32 = 42; }
- | ~~~~~~~~~~~
+ | +++++
error: aborting due to 5 previous errors
diff --git a/src/test/ui/mir/issue-100476-recursion-check-blewup.rs b/src/test/ui/mir/issue-100476-recursion-check-blewup.rs
deleted file mode 100644
index bc2f32f4c..000000000
--- a/src/test/ui/mir/issue-100476-recursion-check-blewup.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// check-pass
-
-// compile-flags: --emit=mir,link -O
-
-// At one point the MIR inlining, when guarding against infinitely (or even just
-// excessive) recursion, was using `ty::Instance` as the basis for its history
-// check. The problem is that when you have polymorphic recursion, you can have
-// distinct instances of the same code (because you're inlining the same code
-// with differing substitutions), causing the amount of inlining to blow up
-// exponentially.
-//
-// This test illustrates an example of that filed in issue rust#100476.
-
-#![allow(unconditional_recursion)]
-#![feature(decl_macro)]
-
-macro emit($($m:ident)*) {$(
- // Randomize `def_path_hash` by defining them under a module with
- // different names
- pub mod $m {
- pub trait Tr {
- type Next: Tr;
- }
-
- pub fn hoge<const N: usize, T: Tr>() {
- inner::<N, T>();
- }
-
- #[inline(always)]
- fn inner<const N: usize, T: Tr>() {
- inner::<N, T::Next>();
- }
- }
-)*}
-
-// Increase the chance of triggering the bug
-emit!(
- m00 m01 m02 m03 m04 m05 m06 m07 m08 m09
- m10 m11 m12 m13 m14 m15 m16 m17 m18 m19
-);
-
-fn main() { }
diff --git a/src/test/ui/mir/issue-101844.rs b/src/test/ui/mir/issue-101844.rs
new file mode 100644
index 000000000..da8a25f5f
--- /dev/null
+++ b/src/test/ui/mir/issue-101844.rs
@@ -0,0 +1,73 @@
+// check-pass
+
+pub trait FirstTrait {
+ type Item;
+ type Extra: Extra<(), Error = Self::Item>;
+}
+
+trait SecondTrait {
+ type Item2;
+}
+
+trait ThirdTrait: SecondTrait {
+ type Item3;
+}
+
+trait FourthTrait {
+ type Item4;
+}
+
+impl<First> SecondTrait for First
+where
+ First: FirstTrait,
+{
+ type Item2 = First::Extra;
+}
+
+impl<Second, T> ThirdTrait for Second
+where
+ Second: SecondTrait<Item2 = T>,
+{
+ type Item3 = T;
+}
+
+impl<S, Third: ?Sized> FourthTrait for Third
+where
+ Third: ThirdTrait<Item3 = S>,
+{
+ type Item4 = S;
+}
+
+pub trait Extra<Request> {
+ type Error;
+}
+
+struct ImplShoulExist<D, Req> {
+ _gen: (D, Req),
+}
+
+impl<D, Req> ImplShoulExist<D, Req>
+where
+ D: FourthTrait,
+ D::Item4: Extra<Req>,
+ <D::Item4 as Extra<Req>>::Error: Into<()>,
+{
+ fn access_fn(_: D) {
+ todo!()
+ }
+}
+
+impl<D, Req> Extra<Req> for ImplShoulExist<D, Req> {
+ type Error = ();
+}
+
+pub fn broken<MS>(ms: MS)
+where
+ MS: FirstTrait,
+ MS::Item: Into<()>,
+{
+ // Error: Apparently Balance::new doesn't exist during MIR validation
+ let _ = ImplShoulExist::<MS, ()>::access_fn(ms);
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-102389.rs b/src/test/ui/mir/issue-102389.rs
new file mode 100644
index 000000000..8b27d5e55
--- /dev/null
+++ b/src/test/ui/mir/issue-102389.rs
@@ -0,0 +1,8 @@
+enum Enum { A, B, C }
+
+fn func(inbounds: &Enum, array: &[i16; 3]) -> i16 {
+ array[*inbounds as usize]
+ //~^ ERROR [E0507]
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-102389.stderr b/src/test/ui/mir/issue-102389.stderr
new file mode 100644
index 000000000..925dc258a
--- /dev/null
+++ b/src/test/ui/mir/issue-102389.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of `*inbounds` which is behind a shared reference
+ --> $DIR/issue-102389.rs:4:11
+ |
+LL | array[*inbounds as usize]
+ | ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/mir/issue-99852.rs b/src/test/ui/mir/issue-99852.rs
new file mode 100644
index 000000000..1c675788e
--- /dev/null
+++ b/src/test/ui/mir/issue-99852.rs
@@ -0,0 +1,24 @@
+// check-pass
+// compile-flags: -Z validate-mir
+#![feature(let_chains)]
+
+fn lambda<T, U>() -> U
+where
+ T: Default,
+ U: Default,
+{
+ let foo: Result<T, ()> = Ok(T::default());
+ let baz: U = U::default();
+
+ if let Ok(foo) = foo && let Ok(bar) = transform(foo) {
+ bar
+ } else {
+ baz
+ }
+}
+
+fn transform<T, U>(input: T) -> Result<U, ()> {
+ todo!()
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-99866.rs b/src/test/ui/mir/issue-99866.rs
new file mode 100644
index 000000000..d39ae6ebf
--- /dev/null
+++ b/src/test/ui/mir/issue-99866.rs
@@ -0,0 +1,25 @@
+// check-pass
+pub trait Backend {
+ type DescriptorSetLayout;
+}
+
+pub struct Back;
+
+impl Backend for Back {
+ type DescriptorSetLayout = u32;
+}
+
+pub struct HalSetLayouts {
+ vertex_layout: <Back as Backend>::DescriptorSetLayout,
+}
+
+impl HalSetLayouts {
+ pub fn iter<DSL>(self) -> DSL
+ where
+ Back: Backend<DescriptorSetLayout = DSL>,
+ {
+ self.vertex_layout
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-100550-unnormalized-projection.rs b/src/test/ui/mir/mir-inlining/ice-issue-100550-unnormalized-projection.rs
new file mode 100644
index 000000000..f67b07354
--- /dev/null
+++ b/src/test/ui/mir/mir-inlining/ice-issue-100550-unnormalized-projection.rs
@@ -0,0 +1,30 @@
+// This test verifies that we do not ICE due to MIR inlining in case of normalization failure
+// in a projection.
+//
+// compile-flags: --crate-type lib -C opt-level=3
+// build-pass
+
+pub trait Trait {
+ type Associated;
+}
+impl<T> Trait for T {
+ type Associated = T;
+}
+
+pub struct Struct<T>(<T as Trait>::Associated);
+
+pub fn foo<T>() -> Struct<T>
+where
+ T: Trait,
+{
+ bar()
+}
+
+#[inline]
+fn bar<T>() -> Struct<T> {
+ Struct(baz())
+}
+
+fn baz<T>() -> T {
+ unimplemented!()
+}
diff --git a/src/test/ui/mir/mir_codegen_calls_diverging_drops.rs b/src/test/ui/mir/mir_codegen_calls_diverging_drops.rs
index 796d74477..3d2156105 100644
--- a/src/test/ui/mir/mir_codegen_calls_diverging_drops.rs
+++ b/src/test/ui/mir/mir_codegen_calls_diverging_drops.rs
@@ -2,6 +2,7 @@
// error-pattern:diverging_fn called
// error-pattern:0 dropped
// ignore-emscripten no processes
+// needs-unwind this test checks that a destructor is called after panicking
struct Droppable(u8);
impl Drop for Droppable {
diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr
index ef03b67b1..7fec6ecd7 100644
--- a/src/test/ui/mismatched_types/E0409.stderr
+++ b/src/test/ui/mismatched_types/E0409.stderr
@@ -17,6 +17,10 @@ LL | (0, ref y) | (y, 0) => {}
| first introduced with type `&{integer}` here
|
= note: in the same arm, a binding must have the same type in all alternatives
+help: consider adding `ref`
+ |
+LL | (0, ref y) | (ref y, 0) => {}
+ | +++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/mismatched_types/E0631.rs b/src/test/ui/mismatched_types/E0631.rs
index a29394658..83dbdb77a 100644
--- a/src/test/ui/mismatched_types/E0631.rs
+++ b/src/test/ui/mismatched_types/E0631.rs
@@ -1,7 +1,7 @@
#![feature(unboxed_closures)]
fn foo<F: Fn(usize)>(_: F) {}
-fn bar<F: Fn<usize>>(_: F) {}
+fn bar<F: Fn<(usize,)>>(_: F) {}
fn main() {
fn f(_: u64) {}
foo(|_: isize| {}); //~ ERROR type mismatch
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 4d673d455..410ea4b0b 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -27,8 +27,8 @@ LL | bar(|_: isize| {});
note: required by a bound in `bar`
--> $DIR/E0631.rs:4:11
|
-LL | fn bar<F: Fn<usize>>(_: F) {}
- | ^^^^^^^^^ required by this bound in `bar`
+LL | fn bar<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `bar`
error[E0631]: type mismatch in function arguments
--> $DIR/E0631.rs:9:9
@@ -65,8 +65,8 @@ LL | bar(f);
note: required by a bound in `bar`
--> $DIR/E0631.rs:4:11
|
-LL | fn bar<F: Fn<usize>>(_: F) {}
- | ^^^^^^^^^ required by this bound in `bar`
+LL | fn bar<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `bar`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs
index e817631ad..65c8d6a7e 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.rs
+++ b/src/test/ui/mismatched_types/closure-arg-count.rs
@@ -1,6 +1,6 @@
#![feature(unboxed_closures)]
-fn f<F: Fn<usize>>(_: F) {}
+fn f<F: Fn<(usize,)>>(_: F) {}
fn main() {
[1, 2, 3].sort_by(|| panic!());
//~^ ERROR closure is expected to take
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index 3968774e3..a02ec8198 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -56,8 +56,8 @@ LL | f(|| panic!());
note: required by a bound in `f`
--> $DIR/closure-arg-count.rs:3:9
|
-LL | fn f<F: Fn<usize>>(_: F) {}
- | ^^^^^^^^^ required by this bound in `f`
+LL | fn f<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `f`
help: consider changing the closure to take and ignore the expected argument
|
LL | f(|_| panic!());
@@ -74,8 +74,8 @@ LL | f( move || panic!());
note: required by a bound in `f`
--> $DIR/closure-arg-count.rs:3:9
|
-LL | fn f<F: Fn<usize>>(_: F) {}
- | ^^^^^^^^^ required by this bound in `f`
+LL | fn f<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `f`
help: consider changing the closure to take and ignore the expected argument
|
LL | f( move |_| panic!());
diff --git a/src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs b/src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs
new file mode 100644
index 000000000..d302dc99b
--- /dev/null
+++ b/src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs
@@ -0,0 +1,23 @@
+struct S;
+struct Y;
+
+trait Trait {}
+
+impl Trait for Y {}
+
+fn foo() -> impl Trait {
+ if true {
+ S
+ } else {
+ Y //~ ERROR `if` and `else` have incompatible types
+ }
+}
+
+fn bar() -> impl Trait {
+ match true {
+ true => S,
+ false => Y, //~ ERROR `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr b/src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr
new file mode 100644
index 000000000..2f814445b
--- /dev/null
+++ b/src/test/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr
@@ -0,0 +1,26 @@
+error[E0308]: `if` and `else` have incompatible types
+ --> $DIR/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs:12:9
+ |
+LL | / if true {
+LL | | S
+ | | - expected because of this
+LL | | } else {
+LL | | Y
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `if` and `else` have incompatible types
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs:19:18
+ |
+LL | / match true {
+LL | | true => S,
+ | | - this is found to be of type `S`
+LL | | false => Y,
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `match` arms have incompatible types
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/dont-point-return-on-E0308.rs b/src/test/ui/mismatched_types/dont-point-return-on-E0308.rs
new file mode 100644
index 000000000..f2ba610e2
--- /dev/null
+++ b/src/test/ui/mismatched_types/dont-point-return-on-E0308.rs
@@ -0,0 +1,18 @@
+// edition:2021
+
+async fn f(_: &()) {}
+//~^ NOTE function defined here
+//~| NOTE
+// Second note is the span of the underlined argument, I think...
+
+fn main() {
+ (|| async {
+ Err::<(), ()>(())?;
+ f(());
+ //~^ ERROR mismatched types
+ //~| NOTE arguments to this function are incorrect
+ //~| NOTE expected `&()`, found `()`
+ //~| HELP consider borrowing here
+ Ok::<(), ()>(())
+ })();
+}
diff --git a/src/test/ui/mismatched_types/dont-point-return-on-E0308.stderr b/src/test/ui/mismatched_types/dont-point-return-on-E0308.stderr
new file mode 100644
index 000000000..13942682d
--- /dev/null
+++ b/src/test/ui/mismatched_types/dont-point-return-on-E0308.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/dont-point-return-on-E0308.rs:11:11
+ |
+LL | f(());
+ | - ^^
+ | | |
+ | | expected `&()`, found `()`
+ | | help: consider borrowing here: `&()`
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/dont-point-return-on-E0308.rs:3:10
+ |
+LL | async fn f(_: &()) {}
+ | ^ ------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/issue-19109.stderr b/src/test/ui/mismatched_types/issue-19109.stderr
index c25e2687b..5cef64bb1 100644
--- a/src/test/ui/mismatched_types/issue-19109.stderr
+++ b/src/test/ui/mismatched_types/issue-19109.stderr
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
LL | fn function(t: &mut dyn Trait) {
| - help: try adding a return type: `-> *mut dyn Trait`
LL | t as *mut dyn Trait
- | ^^^^^^^^^^^^^^^^^^^ expected `()`, found *-ptr
+ | ^^^^^^^^^^^^^^^^^^^ expected `()`, found `*mut dyn Trait`
|
= note: expected unit type `()`
found raw pointer `*mut dyn Trait`
diff --git a/src/test/ui/mismatched_types/issue-84976.stderr b/src/test/ui/mismatched_types/issue-84976.stderr
index f8f2b1f0f..9157566e3 100644
--- a/src/test/ui/mismatched_types/issue-84976.stderr
+++ b/src/test/ui/mismatched_types/issue-84976.stderr
@@ -3,6 +3,11 @@ error[E0308]: mismatched types
|
LL | length = { foo(&length) };
| ^^^^^^^^^^^^ expected `u32`, found `i32`
+ |
+help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
+ |
+LL | length = { foo(&length).try_into().unwrap() };
+ | ++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/issue-84976.rs:17:14
diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
index c2515c40b..36748fae1 100644
--- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
+++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
@@ -1,8 +1,10 @@
error[E0277]: `Foo` doesn't implement `Debug`
- --> $DIR/method-help-unsatisfied-bound.rs:5:7
+ --> $DIR/method-help-unsatisfied-bound.rs:5:5
|
LL | a.unwrap();
- | ^^^^^^ `Foo` cannot be formatted using `{:?}`
+ | ^ ------ required by a bound introduced by this call
+ | |
+ | `Foo` cannot be formatted using `{:?}`
|
= help: the trait `Debug` is not implemented for `Foo`
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
diff --git a/src/test/ui/mismatched_types/normalize-fn-sig.rs b/src/test/ui/mismatched_types/normalize-fn-sig.rs
new file mode 100644
index 000000000..1a2093c44
--- /dev/null
+++ b/src/test/ui/mismatched_types/normalize-fn-sig.rs
@@ -0,0 +1,16 @@
+trait Foo {
+ type Bar;
+}
+
+impl<T> Foo for T {
+ type Bar = i32;
+}
+
+fn foo<T>(_: <T as Foo>::Bar, _: &'static <T as Foo>::Bar) {}
+
+fn needs_i32_ref_fn(_: fn(&'static i32, i32)) {}
+
+fn main() {
+ needs_i32_ref_fn(foo::<()>);
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/mismatched_types/normalize-fn-sig.stderr b/src/test/ui/mismatched_types/normalize-fn-sig.stderr
new file mode 100644
index 000000000..6c55f29c5
--- /dev/null
+++ b/src/test/ui/mismatched_types/normalize-fn-sig.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/normalize-fn-sig.rs:14:22
+ |
+LL | needs_i32_ref_fn(foo::<()>);
+ | ---------------- ^^^^^^^^^ expected `&i32`, found `i32`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn pointer `fn(&'static i32, i32)`
+ found fn item `fn(i32, &'static i32) {foo::<()>}`
+note: function defined here
+ --> $DIR/normalize-fn-sig.rs:11:4
+ |
+LL | fn needs_i32_ref_fn(_: fn(&'static i32, i32)) {}
+ | ^^^^^^^^^^^^^^^^ ------------------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index 475ea9dfa..fb3597aa8 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -26,7 +26,7 @@ LL | impl FnMut<(isize,)> for S {
help: provide the argument
|
LL | let ans = s(/* isize */);
- | ~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/overloaded-calls-bad.rs:31:15
@@ -44,7 +44,7 @@ LL | impl FnMut<(isize,)> for S {
help: remove the extra argument
|
LL | let ans = s(/* isize */);
- | ~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error: aborting due to 3 previous errors
diff --git a/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed b/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed
new file mode 100644
index 000000000..56f93cfbf
--- /dev/null
+++ b/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed
@@ -0,0 +1,21 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+fn main() {
+ enum Blah {
+ A(isize, isize, usize),
+ B(isize, usize),
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, ref y) | Blah::B(x, ref y) => {}
+ //~^ ERROR mismatched types
+ //~| ERROR variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, y) | Blah::B(x, y) => {}
+ //~^ ERROR mismatched types
+ //~| variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+}
diff --git a/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs b/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs
new file mode 100644
index 000000000..0c33f99a4
--- /dev/null
+++ b/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs
@@ -0,0 +1,21 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+fn main() {
+ enum Blah {
+ A(isize, isize, usize),
+ B(isize, usize),
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, ref y) | Blah::B(x, y) => {}
+ //~^ ERROR mismatched types
+ //~| ERROR variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+ //~^ ERROR mismatched types
+ //~| variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+}
diff --git a/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr b/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr
new file mode 100644
index 000000000..e8357f9a3
--- /dev/null
+++ b/src/test/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr
@@ -0,0 +1,49 @@
+error[E0409]: variable `y` is bound inconsistently across alternatives separated by `|`
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:11:43
+ |
+LL | Blah::A(_, x, ref y) | Blah::B(x, y) => {}
+ | - first binding ^ bound in different ways
+
+error[E0409]: variable `y` is bound inconsistently across alternatives separated by `|`
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:17:43
+ |
+LL | Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+ | - first binding ^ bound in different ways
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:11:43
+ |
+LL | match Blah::A(1, 1, 2) {
+ | ---------------- this expression has type `Blah`
+LL | Blah::A(_, x, ref y) | Blah::B(x, y) => {}
+ | ----- ^ expected `&usize`, found `usize`
+ | |
+ | first introduced with type `&usize` here
+ |
+ = note: in the same arm, a binding must have the same type in all alternatives
+help: consider adding `ref`
+ |
+LL | Blah::A(_, x, ref y) | Blah::B(x, ref y) => {}
+ | +++
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:17:39
+ |
+LL | match Blah::A(1, 1, 2) {
+ | ---------------- this expression has type `Blah`
+LL | Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+ | - ^^^^^ expected `usize`, found `&usize`
+ | |
+ | first introduced with type `usize` here
+ |
+ = note: in the same arm, a binding must have the same type in all alternatives
+help: consider removing `ref`
+ |
+LL - Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+LL + Blah::A(_, x, y) | Blah::B(x, y) => {}
+ |
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0409.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed b/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed
new file mode 100644
index 000000000..f30feaed0
--- /dev/null
+++ b/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+struct S;
+struct Y;
+
+trait Trait {}
+
+impl Trait for S {}
+impl Trait for Y {}
+
+fn foo() -> Box<dyn Trait> {
+ if true {
+ Box::new(S)
+ } else {
+ Box::new(Y) //~ ERROR `if` and `else` have incompatible types
+ }
+}
+
+fn bar() -> Box<dyn Trait> {
+ match true {
+ true => Box::new(S),
+ false => Box::new(Y), //~ ERROR `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs b/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs
new file mode 100644
index 000000000..2bd8146e2
--- /dev/null
+++ b/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+struct S;
+struct Y;
+
+trait Trait {}
+
+impl Trait for S {}
+impl Trait for Y {}
+
+fn foo() -> impl Trait {
+ if true {
+ S
+ } else {
+ Y //~ ERROR `if` and `else` have incompatible types
+ }
+}
+
+fn bar() -> impl Trait {
+ match true {
+ true => S,
+ false => Y, //~ ERROR `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr b/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr
new file mode 100644
index 000000000..f58b9c3ec
--- /dev/null
+++ b/src/test/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr
@@ -0,0 +1,47 @@
+error[E0308]: `if` and `else` have incompatible types
+ --> $DIR/suggest-boxed-trait-objects-instead-of-impl-trait.rs:17:9
+ |
+LL | / if true {
+LL | | S
+ | | - expected because of this
+LL | | } else {
+LL | | Y
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `if` and `else` have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn foo() -> Box<dyn Trait> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ Box::new(S)
+LL | } else {
+LL ~ Box::new(Y)
+ |
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/suggest-boxed-trait-objects-instead-of-impl-trait.rs:24:18
+ |
+LL | / match true {
+LL | | true => S,
+ | | - this is found to be of type `S`
+LL | | false => Y,
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `match` arms have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn bar() -> Box<dyn Trait> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ true => Box::new(S),
+LL ~ false => Box::new(Y),
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/modules/auxiliary/dummy_lib.rs b/src/test/ui/modules/auxiliary/dummy_lib.rs
new file mode 100644
index 000000000..ef805c1f0
--- /dev/null
+++ b/src/test/ui/modules/auxiliary/dummy_lib.rs
@@ -0,0 +1,2 @@
+#[allow(dead_code)]
+pub struct Dummy;
diff --git a/src/test/ui/modules/special_module_name.rs b/src/test/ui/modules/special_module_name.rs
new file mode 100644
index 000000000..15c59b2da
--- /dev/null
+++ b/src/test/ui/modules/special_module_name.rs
@@ -0,0 +1,8 @@
+mod lib;
+//~^ WARN found module declaration for lib.rs
+//~| ERROR file not found for module `lib`
+mod main;
+//~^ WARN found module declaration for main.rs
+//~| ERROR file not found for module `main`
+
+fn main() {}
diff --git a/src/test/ui/modules/special_module_name.stderr b/src/test/ui/modules/special_module_name.stderr
new file mode 100644
index 000000000..8b3da2938
--- /dev/null
+++ b/src/test/ui/modules/special_module_name.stderr
@@ -0,0 +1,37 @@
+error[E0583]: file not found for module `lib`
+ --> $DIR/special_module_name.rs:1:1
+ |
+LL | mod lib;
+ | ^^^^^^^^
+ |
+ = help: to create the module `lib`, create file "$DIR/lib.rs" or "$DIR/lib/mod.rs"
+
+error[E0583]: file not found for module `main`
+ --> $DIR/special_module_name.rs:4:1
+ |
+LL | mod main;
+ | ^^^^^^^^^
+ |
+ = help: to create the module `main`, create file "$DIR/main.rs" or "$DIR/main/mod.rs"
+
+warning: found module declaration for lib.rs
+ --> $DIR/special_module_name.rs:1:1
+ |
+LL | mod lib;
+ | ^^^^^^^^
+ |
+ = note: `#[warn(special_module_name)]` on by default
+ = note: lib.rs is the root of this crate's library target
+ = help: to refer to it from other targets, use the library's name as the path
+
+warning: found module declaration for main.rs
+ --> $DIR/special_module_name.rs:4:1
+ |
+LL | mod main;
+ | ^^^^^^^^^
+ |
+ = note: a binary crate cannot be used as library
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/modules/special_module_name_ignore.rs b/src/test/ui/modules/special_module_name_ignore.rs
new file mode 100644
index 000000000..07cea9b2b
--- /dev/null
+++ b/src/test/ui/modules/special_module_name_ignore.rs
@@ -0,0 +1,9 @@
+// run-pass
+
+#[path = "auxiliary/dummy_lib.rs"]
+mod lib;
+
+#[path = "auxiliary/dummy_lib.rs"]
+mod main;
+
+fn main() {}
diff --git a/src/test/ui/moves/move-out-of-array-ref.stderr b/src/test/ui/moves/move-out-of-array-ref.stderr
index fd682e56a..0caa0b83a 100644
--- a/src/test/ui/moves/move-out-of-array-ref.stderr
+++ b/src/test/ui/moves/move-out-of-array-ref.stderr
@@ -13,7 +13,7 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
--> $DIR/move-out-of-array-ref.rs:13:27
|
LL | let [_, s @ .. , _] = *a;
- | ------ ^^
+ | - ^^
| | |
| | cannot move out of here
| | help: consider borrowing here: `&*a`
@@ -35,7 +35,7 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
--> $DIR/move-out-of-array-ref.rs:23:27
|
LL | let [_, s @ .. , _] = *a;
- | ------ ^^
+ | - ^^
| | |
| | cannot move out of here
| | help: consider borrowing here: `&*a`
diff --git a/src/test/ui/moves/move-out-of-slice-2.stderr b/src/test/ui/moves/move-out-of-slice-2.stderr
index 9a863bf31..93b0dcfc2 100644
--- a/src/test/ui/moves/move-out-of-slice-2.stderr
+++ b/src/test/ui/moves/move-out-of-slice-2.stderr
@@ -14,7 +14,7 @@ LL | match *a {
| ^^ cannot move out of here
LL |
LL | [a @ ..] => {}
- | ------
+ | -
| |
| data moved here
| move occurs because `a` has type `[A]`, which does not implement the `Copy` trait
@@ -26,7 +26,7 @@ LL | match *b {
| ^^ cannot move out of here
LL |
LL | [_, _, b @ .., _] => {}
- | ------
+ | -
| |
| data moved here
| move occurs because `b` has type `[A]`, which does not implement the `Copy` trait
@@ -38,7 +38,7 @@ LL | match *c {
| ^^ cannot move out of here
LL |
LL | [c @ ..] => {}
- | ------
+ | -
| |
| data moved here
| move occurs because `c` has type `[C]`, which does not implement the `Copy` trait
@@ -50,7 +50,7 @@ LL | match *d {
| ^^ cannot move out of here
LL |
LL | [_, _, d @ .., _] => {}
- | ------
+ | -
| |
| data moved here
| move occurs because `d` has type `[C]`, which does not implement the `Copy` trait
diff --git a/src/test/ui/mutexguard-sync.stderr b/src/test/ui/mutexguard-sync.stderr
index b3c77b13e..3fbb2ddf1 100644
--- a/src/test/ui/mutexguard-sync.stderr
+++ b/src/test/ui/mutexguard-sync.stderr
@@ -7,7 +7,7 @@ LL | test_sync(guard);
| required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `Cell<i32>`
- = note: required because of the requirements on the impl of `Sync` for `MutexGuard<'_, Cell<i32>>`
+ = note: required for `MutexGuard<'_, Cell<i32>>` to implement `Sync`
note: required by a bound in `test_sync`
--> $DIR/mutexguard-sync.rs:5:17
|
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index b04ea14d1..c07914df7 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -218,7 +218,7 @@ error[E0277]: the trait bound `fn() -> c::TS {c::TS}: Impossible` is not satisfi
--> $DIR/namespace-mix.rs:56:11
|
LL | check(m3::TS);
- | ----- ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
+ | ----- ^^^^^^ the trait `Impossible` is not implemented for fn item `fn() -> c::TS {c::TS}`
| |
| required by a bound introduced by this call
|
@@ -274,7 +274,7 @@ error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::T
--> $DIR/namespace-mix.rs:62:11
|
LL | check(xm3::TS);
- | ----- ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
+ | ----- ^^^^^^^ the trait `Impossible` is not implemented for fn item `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
| |
| required by a bound introduced by this call
|
@@ -526,7 +526,7 @@ error[E0277]: the trait bound `fn() -> c::E {c::E::TV}: Impossible` is not satis
--> $DIR/namespace-mix.rs:122:11
|
LL | check(m9::TV);
- | ----- ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
+ | ----- ^^^^^^ the trait `Impossible` is not implemented for fn item `fn() -> c::E {c::E::TV}`
| |
| required by a bound introduced by this call
|
@@ -582,7 +582,7 @@ error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::
--> $DIR/namespace-mix.rs:128:11
|
LL | check(xm9::TV);
- | ----- ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
+ | ----- ^^^^^^^ the trait `Impossible` is not implemented for fn item `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/nested-ty-params.stderr b/src/test/ui/nested-ty-params.stderr
index f6741b5e5..8f4746f5e 100644
--- a/src/test/ui/nested-ty-params.stderr
+++ b/src/test/ui/nested-ty-params.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
LL | fn hd<U>(v: Vec<U> ) -> U {
| - type parameter from outer function
LL | fn hd1(w: [U]) -> U { return w[0]; }
- | --- ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `hd1<U>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<U>`
error[E0401]: can't use generic parameters from outer function
--> $DIR/nested-ty-params.rs:3:23
@@ -14,9 +14,9 @@ error[E0401]: can't use generic parameters from outer function
LL | fn hd<U>(v: Vec<U> ) -> U {
| - type parameter from outer function
LL | fn hd1(w: [U]) -> U { return w[0]; }
- | --- ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `hd1<U>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<U>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/never_type/defaulted-never-note.fallback.stderr b/src/test/ui/never_type/defaulted-never-note.fallback.stderr
index 4c8b49224..283aca1b0 100644
--- a/src/test/ui/never_type/defaulted-never-note.fallback.stderr
+++ b/src/test/ui/never_type/defaulted-never-note.fallback.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
- --> $DIR/defaulted-never-note.rs:30:5
+ --> $DIR/defaulted-never-note.rs:30:9
|
LL | foo(_x);
- | ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
+ | --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `ImplementedForUnitButNotNever` is implemented for `()`
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
diff --git a/src/test/ui/never_type/defaulted-never-note.rs b/src/test/ui/never_type/defaulted-never-note.rs
index aefc739a0..d30ffcd38 100644
--- a/src/test/ui/never_type/defaulted-never-note.rs
+++ b/src/test/ui/never_type/defaulted-never-note.rs
@@ -32,6 +32,7 @@ fn smeg() {
//[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
//[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()`
//[fallback]~| NOTE this error might have been caused
+ //[fallback]~| NOTE required by a bound introduced by this call
//[fallback]~| HELP did you intend
}
diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr
index dee2b1d70..3215c4669 100644
--- a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr
+++ b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `!: Test` is not satisfied
- --> $DIR/diverging-fallback-no-leak.rs:17:5
+ --> $DIR/diverging-fallback-no-leak.rs:17:23
|
LL | unconstrained_arg(return);
- | ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!`
+ | ----------------- ^^^^^^ the trait `Test` is not implemented for `!`
+ | |
+ | required by a bound introduced by this call
|
= help: the following other types implement trait `Test`:
()
diff --git a/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr b/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
index 2acf44432..45cf37234 100644
--- a/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
+++ b/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47] as FnOnce<()>>::Output == ()`
+error[E0271]: expected `[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]` to be a closure that returns `()`, but it returns `!`
--> $DIR/fallback-closure-wrap.rs:18:31
|
LL | let error = Closure::wrap(Box::new(move || {
diff --git a/src/test/ui/never_type/fallback-closure-wrap.rs b/src/test/ui/never_type/fallback-closure-wrap.rs
index af0577ac0..f88355bb2 100644
--- a/src/test/ui/never_type/fallback-closure-wrap.rs
+++ b/src/test/ui/never_type/fallback-closure-wrap.rs
@@ -3,7 +3,7 @@
//
// This particular test case currently fails as the inference to `()` rather
// than `!` happens as a result of an `as` cast, which is not currently tracked.
-// Crater did not find many cases of this occuring, but it is included for
+// Crater did not find many cases of this occurring, but it is included for
// awareness.
//
// revisions: nofallback fallback
@@ -16,7 +16,7 @@ use std::marker::PhantomData;
fn main() {
let error = Closure::wrap(Box::new(move || {
- //[fallback]~^ ERROR type mismatch resolving
+ //[fallback]~^ to be a closure that returns `()`, but it returns `!`
panic!("Can't connect to server.");
}) as Box<dyn FnMut()>);
}
diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr
index 54abed383..6dc039fc3 100644
--- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr
+++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr
@@ -1,8 +1,12 @@
error[E0277]: the trait bound `(): T` is not satisfied
- --> $DIR/feature-gate-never_type_fallback.rs:10:5
+ --> $DIR/feature-gate-never_type_fallback.rs:10:9
|
LL | foo(panic!())
- | ^^^ the trait `T` is not implemented for `()`
+ | --- ^^^^^^^^
+ | | |
+ | | the trait `T` is not implemented for `()`
+ | | this tail expression is of type `_`
+ | required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/feature-gate-never_type_fallback.rs:13:16
diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
index e20455913..06e902bca 100644
--- a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
+++ b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `E: From<()>` is not satisfied
- --> $DIR/never-value-fallback-issue-66757.rs:28:5
+ --> $DIR/never-value-fallback-issue-66757.rs:28:26
|
LL | <E as From<_>>::from(never);
- | ^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `E`
+ | -------------------- ^^^^^ the trait `From<()>` is not implemented for `E`
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `From<!>` is implemented for `E`
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index f86a19fff..59b848ea8 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -22,14 +22,8 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
note: no external requirements
--> $DIR/escape-argument-callee.rs:20:1
|
-LL | / fn test() {
-LL | | let x = 44;
-LL | | let mut p = &x;
-LL | |
-... |
-LL | | deref(p);
-LL | | }
- | |_^
+LL | fn test() {
+ | ^^^^^^^^^
|
= note: defining type: test
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index 8cd8b43ca..ff4e8e590 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -13,14 +13,8 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
note: no external requirements
--> $DIR/escape-argument.rs:20:1
|
-LL | / fn test() {
-LL | | let x = 44;
-LL | | let mut p = &x;
-LL | |
-... |
-LL | | deref(p);
-LL | | }
- | |_^
+LL | fn test() {
+ | ^^^^^^^^^
|
= note: defining type: test
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
index abf80e039..4fbd5eb19 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
@@ -29,14 +29,8 @@ LL | let mut closure = || {
note: no external requirements
--> $DIR/escape-upvar-nested.rs:13:1
|
-LL | / fn test() {
-LL | | let x = 44;
-LL | | let mut p = &x;
-LL | |
-... |
-LL | | deref(p);
-LL | | }
- | |_^
+LL | fn test() {
+ | ^^^^^^^^^
|
= note: defining type: test
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
index bc7546421..bc1ceac5b 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
@@ -15,14 +15,8 @@ LL | let mut closure = || p = &y;
note: no external requirements
--> $DIR/escape-upvar-ref.rs:17:1
|
-LL | / fn test() {
-LL | | let x = 44;
-LL | | let mut p = &x;
-LL | |
-... |
-LL | | deref(p);
-LL | | }
- | |_^
+LL | fn test() {
+ | ^^^^^^^^^
|
= note: defining type: test
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index b9b0f3ad2..0d94fca28 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -27,14 +27,8 @@ LL | demand_y(x, y, p)
note: no external requirements
--> $DIR/propagate-approximated-fail-no-postdom.rs:38:1
|
-LL | / fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) {
-LL | | establish_relationships(
-LL | | cell_a,
-LL | | cell_b,
-... |
-LL | | );
-LL | | }
- | |_^
+LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index a2371ee31..435a53533 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -17,14 +17,8 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
note: no external requirements
--> $DIR/propagate-approximated-ref.rs:42:1
|
-LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | | // Only works if 'x: 'y:
-LL | | demand_y(x, y, x.get())
-LL | |
-LL | | });
-LL | | }
- | |_^
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index e53ae167f..6aafbe42c 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -23,14 +23,8 @@ LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
note: no external requirements
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1
|
-LL | / fn case1() {
-LL | | let a = 0;
-LL | | let cell = Cell::new(&a);
-LL | | foo(cell, |cell_a, cell_x| {
-... |
-LL | | })
-LL | | }
- | |_^
+LL | fn case1() {
+ | ^^^^^^^^^^
|
= note: defining type: case1
@@ -51,14 +45,8 @@ LL | foo(cell, |cell_a, cell_x| {
note: no external requirements
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:28:1
|
-LL | / fn case2() {
-LL | | let a = 0;
-LL | | let cell = Cell::new(&a);
-LL | |
-... |
-LL | | })
-LL | | }
- | |_^
+LL | fn case2() {
+ | ^^^^^^^^^^
|
= note: defining type: case2
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index c3c7eb1bd..c95907ea7 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -17,14 +17,8 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
note: no external requirements
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:31:1
|
-LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-LL | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |
-LL | |
-... |
-LL | | });
-LL | | }
- | |_^
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
@@ -46,7 +40,7 @@ LL | | });
| |______`cell_a` escapes the function body here
| argument requires that `'a` must outlive `'static`
|
- = note: requirement occurs because of the type `Cell<&'_#10r u32>`, which makes the generic argument `&'_#10r u32` invariant
+ = note: requirement occurs because of the type `Cell<&'_#9r u32>`, which makes the generic argument `&'_#9r u32` invariant
= note: the struct `Cell<T>` is invariant over the parameter `T`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 846e5aedb..db58d9d6f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -17,14 +17,8 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
note: no external requirements
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:34:1
|
-LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |
-LL | |
-... |
-LL | | });
-LL | | }
- | |_^
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
@@ -46,7 +40,7 @@ LL | | });
| |______`cell_a` escapes the function body here
| argument requires that `'a` must outlive `'static`
|
- = note: requirement occurs because of the type `Cell<&'_#11r u32>`, which makes the generic argument `&'_#11r u32` invariant
+ = note: requirement occurs because of the type `Cell<&'_#10r u32>`, which makes the generic argument `&'_#10r u32` invariant
= note: the struct `Cell<T>` is invariant over the parameter `T`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index a570932ed..be5f1e5ef 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -17,14 +17,8 @@ LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
note: no external requirements
--> $DIR/propagate-approximated-val.rs:35:1
|
-LL | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-LL | | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
-LL | | // Only works if 'x: 'y:
-LL | | demand_y(outlives1, outlives2, x.get())
-LL | |
-LL | | });
-LL | | }
- | |_^
+LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: test
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 407bc6764..d18db97be 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -16,14 +16,8 @@ LL | |_outlives1, _outlives2, x, y| {
note: no external requirements
--> $DIR/propagate-despite-same-free-region.rs:39:1
|
-LL | / fn supply<'a>(cell_a: Cell<&'a u32>) {
-LL | | establish_relationships(
-LL | | cell_a,
-LL | | |_outlives1, _outlives2, x, y| {
-... |
-LL | | );
-LL | | }
- | |_^
+LL | fn supply<'a>(cell_a: Cell<&'a u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index fcb55d37f..e6f88de4e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -26,14 +26,8 @@ LL | demand_y(x, y, x.get())
note: no external requirements
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1
|
-LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-LL | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | | // Only works if 'x: 'y:
-LL | | demand_y(x, y, x.get())
-LL | |
-LL | | });
-LL | | }
- | |_^
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 75beae39e..5f5fce771 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -26,14 +26,8 @@ LL | demand_y(x, y, x.get())
note: no external requirements
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1
|
-LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | | // Only works if 'x: 'y:
-LL | | demand_y(x, y, x.get())
-LL | |
-LL | | });
-LL | | }
- | |_^
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: supply
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
index 58aced2bf..750b08bbe 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -18,11 +18,7 @@ note: no external requirements
LL | / fn supply<'a, T>(value: T)
LL | | where
LL | | T: Trait<'a>,
-LL | | {
-... |
-LL | | });
-LL | | }
- | |_^
+ | |_________________^
|
= note: defining type: supply::<'_#1r, T>
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 1c9d0c835..da89071ea 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -22,11 +22,8 @@ LL | expect_sig(|a, b| b); // ought to return `a`
note: no external requirements
--> $DIR/return-wrong-bound-region.rs:10:1
|
-LL | / fn test() {
-LL | | expect_sig(|a, b| b); // ought to return `a`
-LL | |
-LL | | }
- | |_^
+LL | fn test() {
+ | ^^^^^^^^^
|
= note: defining type: test
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
index 4cd1e406f..ad3eb2483 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.rs
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
@@ -53,7 +53,7 @@ impl<F> R<F> { fn new(f: F) -> Self { R { w: 0, f } } }
// * local/field: Is the structure in a local or a field
// * fully/partial/void: Are we fully initializing it before using any part?
// Is whole type empty due to a void component?
-// * init/reinit: First initialization, or did we previously inititalize and then move out?
+// * init/reinit: First initialization, or did we previously initialize and then move out?
// * struct/tuple: Is this a struct or a (X, Y).
//
// As a shorthand for the cases above, adding a numeric summary to
diff --git a/src/test/ui/nll/issue-51244.stderr b/src/test/ui/nll/issue-51244.stderr
index 19f0223a3..dcb6f9fec 100644
--- a/src/test/ui/nll/issue-51244.stderr
+++ b/src/test/ui/nll/issue-51244.stderr
@@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference
--> $DIR/issue-51244.rs:3:5
|
LL | let ref my_ref @ _ = 0;
- | -------------- help: consider changing this to be a mutable reference: `ref mut my_ref @ _`
+ | ---------- help: consider changing this to be a mutable reference: `ref mut my_ref`
LL | *my_ref = 0;
| ^^^^^^^^^^^ `my_ref` is a `&` reference, so the data it refers to cannot be written
diff --git a/src/test/ui/nll/local-outlives-static-via-hrtb.stderr b/src/test/ui/nll/local-outlives-static-via-hrtb.stderr
index 61009da49..f5c10f3dd 100644
--- a/src/test/ui/nll/local-outlives-static-via-hrtb.stderr
+++ b/src/test/ui/nll/local-outlives-static-via-hrtb.stderr
@@ -9,6 +9,12 @@ LL | assert_static_via_hrtb(&local);
LL | assert_static_via_hrtb_with_assoc_type(&&local);
LL | }
| - `local` dropped here while still borrowed
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/local-outlives-static-via-hrtb.rs:15:53
+ |
+LL | fn assert_static_via_hrtb<G>(_: G) where for<'a> G: Outlives<'a> {}
+ | ^^^^^^^^^^^^
error[E0597]: `local` does not live long enough
--> $DIR/local-outlives-static-via-hrtb.rs:25:45
@@ -20,6 +26,12 @@ LL | assert_static_via_hrtb_with_assoc_type(&&local);
| argument requires that `local` is borrowed for `'static`
LL | }
| - `local` dropped here while still borrowed
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/local-outlives-static-via-hrtb.rs:19:20
+ |
+LL | for<'a> &'a T: Reference<AssociatedType = &'a ()>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr
index 6da3d5d96..6abe53127 100644
--- a/src/test/ui/nll/normalization-bounds-error.stderr
+++ b/src/test/ui/nll/normalization-bounds-error.stderr
@@ -1,8 +1,8 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
- --> $DIR/normalization-bounds-error.rs:12:4
+ --> $DIR/normalization-bounds-error.rs:12:1
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
- | ^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'d` as defined here...
--> $DIR/normalization-bounds-error.rs:12:14
@@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^
note: ...so that the types are compatible
- --> $DIR/normalization-bounds-error.rs:12:4
+ --> $DIR/normalization-bounds-error.rs:12:1
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
- | ^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `Visitor<'d>`
found `Visitor<'_>`
diff --git a/src/test/ui/nll/polonius/assignment-kills-loans.rs b/src/test/ui/nll/polonius/assignment-kills-loans.rs
index c4cf20389..696bf61ce 100644
--- a/src/test/ui/nll/polonius/assignment-kills-loans.rs
+++ b/src/test/ui/nll/polonius/assignment-kills-loans.rs
@@ -1,7 +1,7 @@
#![allow(dead_code)]
// This tests the various kinds of assignments there are. Polonius used to generate `killed`
-// facts only on simple assigments, but not projections, incorrectly causing errors to be emitted
+// facts only on simple assignments, but not projections, incorrectly causing errors to be emitted
// for code accepted by NLL. They are all variations from example code in the NLL RFC.
// check-pass
diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
index c4db6fc97..05e2ea047 100644
--- a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
+++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
@@ -30,4 +30,5 @@ fn main() {
let _x = <fn(&())>::make_f();
//~^ ERROR implementation of `Y` is not general enough
//~| ERROR implementation of `Y` is not general enough
+ //~| ERROR implementation of `Y` is not general enough
}
diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
index 51adfca3e..8c4737988 100644
--- a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
+++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
@@ -16,5 +16,14 @@ LL | let _x = <fn(&())>::make_f();
= note: `Y` would have to be implemented for the type `for<'r> fn(&'r ())`
= note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
-error: aborting due to 2 previous errors
+error: implementation of `Y` is not general enough
+ --> $DIR/impl-fn-ignore-binder-via-bottom.rs:30:14
+ |
+LL | let _x = <fn(&())>::make_f();
+ | ^^^^^^^^^^^^^^^^^^^ implementation of `Y` is not general enough
+ |
+ = note: `Y` would have to be implemented for the type `for<'r> fn(&'r ())`
+ = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
+
+error: aborting due to 3 previous errors
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
index feab24769..ee1f7b64b 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -18,11 +18,7 @@ note: no external requirements
LL | / fn no_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
LL | | where
LL | | T: Iterator,
-LL | | {
-LL | | with_signature(x, |mut y| Box::new(y.next()))
-LL | |
-LL | | }
- | |_^
+ | |________________^
|
= note: defining type: no_region::<'_#1r, T>
@@ -55,10 +51,7 @@ note: no external requirements
LL | / fn correct_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
LL | | where
LL | | T: 'a + Iterator,
-LL | | {
-LL | | with_signature(x, |mut y| Box::new(y.next()))
-LL | | }
- | |_^
+ | |_____________________^
|
= note: defining type: correct_region::<'_#1r, T>
@@ -82,11 +75,7 @@ note: no external requirements
LL | / fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
LL | | where
LL | | T: 'b + Iterator,
-LL | | {
-LL | | with_signature(x, |mut y| Box::new(y.next()))
-LL | |
-LL | | }
- | |_^
+ | |_____________________^
|
= note: defining type: wrong_region::<'_#1r, '_#2r, T>
@@ -120,10 +109,7 @@ LL | / fn outlives_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
LL | | where
LL | | T: 'b + Iterator,
LL | | 'b: 'a,
-LL | | {
-LL | | with_signature(x, |mut y| Box::new(y.next()))
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: outlives_region::<'_#1r, '_#2r, T>
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index 98063bd0a..4e57dfad7 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -20,11 +20,7 @@ note: no external requirements
LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
-LL | | {
-... |
-LL | |
-LL | | }
- | |_^
+ | |____________________^
|
= note: defining type: no_relationships_late::<'_#1r, T>
@@ -74,10 +70,7 @@ LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | 'a: 'a,
-... |
-LL | |
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: no_relationships_early::<'_#1r, '_#2r, T>
@@ -126,10 +119,7 @@ LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | T::AssocType: 'a,
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |_____________________^
|
= note: defining type: projection_outlives::<'_#1r, '_#2r, T>
@@ -155,10 +145,8 @@ LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | T: 'a,
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+LL | | 'b: 'a,
+ | |___________^
|
= note: defining type: elements_outlive::<'_#1r, '_#2r, T>
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
index 45e61bcbd..250c796e2 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
@@ -19,11 +19,7 @@ note: no external requirements
LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | |
-LL | | }
- | |_^
+ | |____________________^
|
= note: defining type: no_relationships_late::<'_#1r, T>
@@ -61,10 +57,7 @@ LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | 'a: 'a,
-... |
-LL | |
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: no_relationships_early::<'_#1r, '_#2r, T>
@@ -102,10 +95,7 @@ LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | T::AssocType: 'a,
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |_____________________^
|
= note: defining type: projection_outlives::<'_#1r, '_#2r, T>
@@ -130,10 +120,7 @@ LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | 'b: 'a,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: elements_outlive::<'_#1r, '_#2r, T>
@@ -157,11 +144,7 @@ note: no external requirements
LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'a>,
-LL | | {
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |____________________^
|
= note: defining type: one_region::<'_#1r, T>
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
index f2549205b..b27186b05 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
@@ -17,10 +17,7 @@ note: no external requirements
LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |____________________^
|
= note: defining type: no_relationships_late::<'_#1r, T>
@@ -43,10 +40,7 @@ LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | 'a: 'a,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: no_relationships_early::<'_#1r, '_#2r, T>
@@ -69,10 +63,7 @@ LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | T::AssocType: 'a,
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |_____________________^
|
= note: defining type: projection_outlives::<'_#1r, '_#2r, T>
@@ -95,10 +86,7 @@ LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b>,
LL | | 'b: 'a,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: elements_outlive::<'_#1r, '_#2r, T>
@@ -120,11 +108,7 @@ note: no external requirements
LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'a>,
-LL | | {
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |____________________^
|
= note: defining type: one_region::<'_#1r, T>
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
index 8e1b6fa2e..0195a693e 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -19,11 +19,7 @@ note: no external requirements
LL | / fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'c>,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | |
-LL | | }
- | |_^
+ | |________________________^
|
= note: defining type: no_relationships_late::<'_#1r, '_#2r, T>
@@ -57,10 +53,7 @@ LL | / fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'c>,
LL | | 'a: 'a,
-... |
-LL | |
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T>
@@ -94,10 +87,7 @@ LL | / fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'c>,
LL | | T::AssocType: 'a,
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |_____________________^
|
= note: defining type: projection_outlives::<'_#1r, '_#2r, '_#3r, T>
@@ -122,10 +112,7 @@ LL | / fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'c>,
LL | | 'b: 'a,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: elements_outlive1::<'_#1r, '_#2r, '_#3r, T>
@@ -150,10 +137,7 @@ LL | / fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'c>,
LL | | 'c: 'a,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: elements_outlive2::<'_#1r, '_#2r, '_#3r, T>
@@ -178,11 +162,7 @@ note: no external requirements
LL | / fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'b>,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | |
-LL | | }
- | |_^
+ | |________________________^
|
= note: defining type: two_regions::<'_#1r, T>
@@ -220,10 +200,7 @@ LL | / fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'b, 'b>,
LL | | 'b: 'a,
-LL | | {
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: two_regions_outlive::<'_#1r, '_#2r, T>
@@ -247,11 +224,7 @@ note: no external requirements
LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
LL | | where
LL | | T: Anything<'a, 'a>,
-LL | | {
-... |
-LL | | with_signature(cell, t, |cell, t| require(cell, t));
-LL | | }
- | |_^
+ | |________________________^
|
= note: defining type: one_region::<'_#1r, T>
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 12c76d198..5d9a044d1 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -15,11 +15,8 @@ LL | twice(cell, value, |a, b| invoke(a, b));
note: no external requirements
--> $DIR/ty-param-closure-approximate-lower-bound.rs:22:1
|
-LL | / fn generic<T>(value: T) {
-LL | | let cell = Cell::new(&());
-LL | | twice(cell, value, |a, b| invoke(a, b));
-LL | | }
- | |_^
+LL | fn generic<T>(value: T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: generic::<T>
@@ -41,11 +38,8 @@ LL | twice(cell, value, |a, b| invoke(a, b));
note: no external requirements
--> $DIR/ty-param-closure-approximate-lower-bound.rs:28:1
|
-LL | / fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) {
-LL | | twice(cell, value, |a, b| invoke(a, b));
-LL | |
-LL | | }
- | |_^
+LL | fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: generic_fail::<T>
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
index 35741859d..50d9e3aab 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -18,11 +18,7 @@ note: no external requirements
LL | / fn no_region<'a, T>(x: Box<T>) -> Box<dyn Debug + 'a>
LL | | where
LL | | T: Debug,
-LL | | {
-... |
-LL | |
-LL | | }
- | |_^
+ | |_____________^
|
= note: defining type: no_region::<'_#1r, T>
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index 0261bc39e..14c55e32a 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -16,14 +16,8 @@ LL | with_signature(a, b, |x, y| {
note: no external requirements
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:26:1
|
-LL | / fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
-LL | | with_signature(a, b, |x, y| {
-LL | |
-LL | | //
-... |
-LL | | })
-LL | | }
- | |_^
+LL | fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: no_region::<T>
@@ -65,11 +59,7 @@ note: no external requirements
LL | / fn correct_region<'a, T>(a: Cell<&'a ()>, b: T)
LL | | where
LL | | T: 'a,
-LL | | {
-... |
-LL | | })
-LL | | }
- | |_^
+ | |__________^
|
= note: defining type: correct_region::<'_#1r, T>
@@ -94,11 +84,7 @@ note: no external requirements
LL | / fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
LL | | where
LL | | T: 'b,
-LL | | {
-... |
-LL | | })
-LL | | }
- | |_^
+ | |__________^
|
= note: defining type: wrong_region::<'_#1r, T>
@@ -139,10 +125,7 @@ LL | / fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
LL | | where
LL | | T: 'b,
LL | | 'b: 'a,
-... |
-LL | | })
-LL | | }
- | |_^
+ | |___________^
|
= note: defining type: outlives_region::<'_#1r, '_#2r, T>
diff --git a/src/test/ui/nll/type-test-universe.stderr b/src/test/ui/nll/type-test-universe.stderr
index 242486c36..31e17d64b 100644
--- a/src/test/ui/nll/type-test-universe.stderr
+++ b/src/test/ui/nll/type-test-universe.stderr
@@ -11,6 +11,12 @@ LL | fn test2<'a>() {
| -- lifetime `'a` defined here
LL | outlives_forall::<Value<'a>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/type-test-universe.rs:6:16
+ |
+LL | for<'u> T: 'u,
+ | ^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
index ee332278c..3326fa521 100644
--- a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
+++ b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
@@ -30,14 +30,15 @@ error[E0597]: `c` does not live long enough
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
-LL | let _closure = || {
- | - `c` dropped here while still borrowed
...
LL | SomeEnum::SomeVariant(Cell::new(&c)),
| ----------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `c` is borrowed for `'a`
+...
+LL | };
+ | - `c` dropped here while still borrowed
error: aborting due to 3 previous errors
diff --git a/src/test/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/src/test/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
index 95bbd62c4..9664fb9f5 100644
--- a/src/test/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
+++ b/src/test/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
@@ -28,28 +28,28 @@ error[E0597]: `c` does not live long enough
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
-LL | let _closure = || {
- | - `c` dropped here while still borrowed
...
LL | f(&c);
| --^^-
| | |
| | borrowed value does not live long enough
| argument requires that `c` is borrowed for `'a`
+LL | };
+ | - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
--> $DIR/adt-tuple-struct-calls.rs:53:11
|
LL | let f = SomeStruct::<&'a u32>;
| - lifetime `'1` appears in the type of `f`
-LL | let _closure = || {
- | - `c` dropped here while still borrowed
-LL | let c = 66;
+...
LL | f(&c);
| --^^-
| | |
| | borrowed value does not live long enough
| argument requires that `c` is borrowed for `'1`
+LL | };
+ | - `c` dropped here while still borrowed
error: aborting due to 4 previous errors
diff --git a/src/test/ui/nll/user-annotations/fns.stderr b/src/test/ui/nll/user-annotations/fns.stderr
index bd4d121d5..e0640da39 100644
--- a/src/test/ui/nll/user-annotations/fns.stderr
+++ b/src/test/ui/nll/user-annotations/fns.stderr
@@ -28,14 +28,14 @@ error[E0597]: `c` does not live long enough
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
-LL | let _closure = || {
- | - `c` dropped here while still borrowed
-LL | let c = 66;
+...
LL | some_fn::<&'a u32>(&c);
| -------------------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `c` is borrowed for `'a`
+LL | };
+ | - `c` dropped here while still borrowed
error: aborting due to 3 previous errors
diff --git a/src/test/ui/nll/user-annotations/method-call.stderr b/src/test/ui/nll/user-annotations/method-call.stderr
index fcaeb465d..10447e45a 100644
--- a/src/test/ui/nll/user-annotations/method-call.stderr
+++ b/src/test/ui/nll/user-annotations/method-call.stderr
@@ -29,14 +29,13 @@ error[E0597]: `c` does not live long enough
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
...
-LL | let _closure = || {
- | - `c` dropped here while still borrowed
-LL | let c = 66;
LL | a.method::<&'a u32>(b, &c);
| ------------------------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `c` is borrowed for `'a`
+LL | };
+ | - `c` dropped here while still borrowed
error: aborting due to 3 previous errors
diff --git a/src/test/ui/nll/user-annotations/method-ufcs-3.stderr b/src/test/ui/nll/user-annotations/method-ufcs-3.stderr
index 328dde980..e7851833e 100644
--- a/src/test/ui/nll/user-annotations/method-ufcs-3.stderr
+++ b/src/test/ui/nll/user-annotations/method-ufcs-3.stderr
@@ -29,14 +29,13 @@ error[E0597]: `c` does not live long enough
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
...
-LL | let _closure = || {
- | - `c` dropped here while still borrowed
-LL | let c = 66;
LL | <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c);
| -------------------------------------------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `c` is borrowed for `'a`
+LL | };
+ | - `c` dropped here while still borrowed
error: aborting due to 3 previous errors
diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr
index 249c2fe2f..c864b93db 100644
--- a/src/test/ui/no-send-res-ports.stderr
+++ b/src/test/ui/no-send-res-ports.stderr
@@ -1,10 +1,17 @@
error[E0277]: `Rc<()>` cannot be sent between threads safely
- --> $DIR/no-send-res-ports.rs:25:5
+ --> $DIR/no-send-res-ports.rs:25:19
|
-LL | thread::spawn(move|| {
- | ^^^^^^^^^^^^^ ------ within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`
- | |
- | `Rc<()>` cannot be sent between threads safely
+LL | thread::spawn(move|| {
+ | ------------- ^-----
+ | | |
+ | _____|_____________within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`
+ | | |
+ | | required by a bound introduced by this call
+LL | |
+LL | | let y = x;
+LL | | println!("{:?}", y);
+LL | | });
+ | |_____^ `Rc<()>` cannot be sent between threads safely
|
= help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>`
note: required because it appears within the type `Port<()>`
diff --git a/src/test/ui/not-clone-closure.stderr b/src/test/ui/not-clone-closure.stderr
index 37d94cf0e..f61ee661b 100644
--- a/src/test/ui/not-clone-closure.stderr
+++ b/src/test/ui/not-clone-closure.stderr
@@ -1,11 +1,13 @@
error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
- --> $DIR/not-clone-closure.rs:11:23
+ --> $DIR/not-clone-closure.rs:11:17
|
LL | let hello = move || {
| ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
...
LL | let hello = hello.clone();
- | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
+ | ^^^^^ ----- required by a bound introduced by this call
+ | |
+ | within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
|
note: required because it's used within this closure
--> $DIR/not-clone-closure.rs:7:17
diff --git a/src/test/ui/not-enough-arguments.stderr b/src/test/ui/not-enough-arguments.stderr
index b1df578ea..8b2dafb4e 100644
--- a/src/test/ui/not-enough-arguments.stderr
+++ b/src/test/ui/not-enough-arguments.stderr
@@ -12,7 +12,7 @@ LL | fn foo(a: isize, b: isize, c: isize, d:isize) {
help: provide the argument
|
LL | foo(1, 2, 3, /* isize */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 6 arguments but 3 arguments were supplied
--> $DIR/not-enough-arguments.rs:29:3
@@ -40,7 +40,7 @@ LL | f: i32,
help: provide the arguments
|
LL | bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/not-panic/not-panic-safe-2.stderr b/src/test/ui/not-panic/not-panic-safe-2.stderr
index 65594702b..3b0f83b3b 100644
--- a/src/test/ui/not-panic/not-panic-safe-2.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-2.stderr
@@ -1,12 +1,12 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-2.rs:10:5
+ --> $DIR/not-panic-safe-2.rs:10:14
|
LL | assert::<Rc<RefCell<i32>>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `Rc<RefCell<i32>>`
+ = note: required for `Rc<RefCell<i32>>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-2.rs:7:14
|
@@ -14,15 +14,15 @@ LL | fn assert<T: UnwindSafe + ?Sized>() {}
| ^^^^^^^^^^ required by this bound in `assert`
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-2.rs:10:5
+ --> $DIR/not-panic-safe-2.rs:10:14
|
LL | assert::<Rc<RefCell<i32>>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
= note: required because it appears within the type `Cell<isize>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `Rc<RefCell<i32>>`
+ = note: required for `Rc<RefCell<i32>>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-2.rs:7:14
|
diff --git a/src/test/ui/not-panic/not-panic-safe-3.stderr b/src/test/ui/not-panic/not-panic-safe-3.stderr
index db3fdb253..9e9a12764 100644
--- a/src/test/ui/not-panic/not-panic-safe-3.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-3.stderr
@@ -1,12 +1,12 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-3.rs:10:5
+ --> $DIR/not-panic-safe-3.rs:10:14
|
LL | assert::<Arc<RefCell<i32>>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `Arc<RefCell<i32>>`
+ = note: required for `Arc<RefCell<i32>>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-3.rs:7:14
|
@@ -14,15 +14,15 @@ LL | fn assert<T: UnwindSafe + ?Sized>() {}
| ^^^^^^^^^^ required by this bound in `assert`
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-3.rs:10:5
+ --> $DIR/not-panic-safe-3.rs:10:14
|
LL | assert::<Arc<RefCell<i32>>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
= note: required because it appears within the type `Cell<isize>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `Arc<RefCell<i32>>`
+ = note: required for `Arc<RefCell<i32>>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-3.rs:7:14
|
diff --git a/src/test/ui/not-panic/not-panic-safe-4.stderr b/src/test/ui/not-panic/not-panic-safe-4.stderr
index 079601b39..fc1c594d0 100644
--- a/src/test/ui/not-panic/not-panic-safe-4.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-4.stderr
@@ -1,12 +1,12 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-4.rs:9:5
+ --> $DIR/not-panic-safe-4.rs:9:14
|
LL | assert::<&RefCell<i32>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `&RefCell<i32>`
+ = note: required for `&RefCell<i32>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-4.rs:6:14
|
@@ -14,15 +14,15 @@ LL | fn assert<T: UnwindSafe + ?Sized>() {}
| ^^^^^^^^^^ required by this bound in `assert`
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-4.rs:9:5
+ --> $DIR/not-panic-safe-4.rs:9:14
|
LL | assert::<&RefCell<i32>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
= note: required because it appears within the type `Cell<isize>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `&RefCell<i32>`
+ = note: required for `&RefCell<i32>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-4.rs:6:14
|
diff --git a/src/test/ui/not-panic/not-panic-safe-5.stderr b/src/test/ui/not-panic/not-panic-safe-5.stderr
index edd0f72dd..cb78370b4 100644
--- a/src/test/ui/not-panic/not-panic-safe-5.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-5.stderr
@@ -1,11 +1,11 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-5.rs:9:5
+ --> $DIR/not-panic-safe-5.rs:9:14
|
LL | assert::<*const UnsafeCell<i32>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `*const UnsafeCell<i32>`
+ = note: required for `*const UnsafeCell<i32>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-5.rs:6:14
|
diff --git a/src/test/ui/not-panic/not-panic-safe-6.stderr b/src/test/ui/not-panic/not-panic-safe-6.stderr
index f3b784a29..7986e341e 100644
--- a/src/test/ui/not-panic/not-panic-safe-6.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-6.stderr
@@ -1,12 +1,12 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-6.rs:9:5
+ --> $DIR/not-panic-safe-6.rs:9:14
|
LL | assert::<*mut RefCell<i32>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `*mut RefCell<i32>`
+ = note: required for `*mut RefCell<i32>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-6.rs:6:14
|
@@ -14,15 +14,15 @@ LL | fn assert<T: UnwindSafe + ?Sized>() {}
| ^^^^^^^^^^ required by this bound in `assert`
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
- --> $DIR/not-panic-safe-6.rs:9:5
+ --> $DIR/not-panic-safe-6.rs:9:14
|
LL | assert::<*mut RefCell<i32>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+ | ^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
= note: required because it appears within the type `Cell<isize>`
= note: required because it appears within the type `RefCell<i32>`
- = note: required because of the requirements on the impl of `UnwindSafe` for `*mut RefCell<i32>`
+ = note: required for `*mut RefCell<i32>` to implement `UnwindSafe`
note: required by a bound in `assert`
--> $DIR/not-panic-safe-6.rs:6:14
|
diff --git a/src/test/ui/object-lifetime/object-lifetime-default.rs b/src/test/ui/object-lifetime/object-lifetime-default.rs
index 60b6629e6..74f5bb7dd 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default.rs
+++ b/src/test/ui/object-lifetime/object-lifetime-default.rs
@@ -1,24 +1,50 @@
#![feature(rustc_attrs)]
#[rustc_object_lifetime_default]
-struct A<T>(T); //~ ERROR BaseDefault
+struct A<
+ T, //~ ERROR BaseDefault
+>(T);
#[rustc_object_lifetime_default]
-struct B<'a,T>(&'a (), T); //~ ERROR BaseDefault
+struct B<
+ 'a,
+ T, //~ ERROR BaseDefault
+>(&'a (), T);
#[rustc_object_lifetime_default]
-struct C<'a,T:'a>(&'a T); //~ ERROR 'a
+struct C<
+ 'a,
+ T: 'a, //~ ERROR 'a
+>(&'a T);
#[rustc_object_lifetime_default]
-struct D<'a,'b,T:'a+'b>(&'a T, &'b T); //~ ERROR Ambiguous
+struct D<
+ 'a,
+ 'b,
+ T: 'a + 'b, //~ ERROR Ambiguous
+>(&'a T, &'b T);
#[rustc_object_lifetime_default]
-struct E<'a,'b:'a,T:'b>(&'a T, &'b T); //~ ERROR 'b
+struct E<
+ 'a,
+ 'b: 'a,
+ T: 'b, //~ ERROR 'b
+>(&'a T, &'b T);
#[rustc_object_lifetime_default]
-struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); //~ ERROR 'a,'b
+struct F<
+ 'a,
+ 'b,
+ T: 'a, //~ ERROR 'a
+ U: 'b, //~ ERROR 'b
+>(&'a T, &'b U);
#[rustc_object_lifetime_default]
-struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); //~ ERROR 'a,Ambiguous
-
-fn main() { }
+struct G<
+ 'a,
+ 'b,
+ T: 'a, //~ ERROR 'a
+ U: 'a + 'b, //~ ERROR Ambiguous
+>(&'a T, &'b U);
+
+fn main() {}
diff --git a/src/test/ui/object-lifetime/object-lifetime-default.stderr b/src/test/ui/object-lifetime/object-lifetime-default.stderr
index 60cb98c8f..a58afad3e 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default.stderr
@@ -1,44 +1,56 @@
error: BaseDefault
- --> $DIR/object-lifetime-default.rs:4:1
+ --> $DIR/object-lifetime-default.rs:5:5
|
-LL | struct A<T>(T);
- | ^^^^^^^^^^^^^^^
+LL | T,
+ | ^
error: BaseDefault
- --> $DIR/object-lifetime-default.rs:7:1
+ --> $DIR/object-lifetime-default.rs:11:5
|
-LL | struct B<'a,T>(&'a (), T);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | T,
+ | ^
error: 'a
- --> $DIR/object-lifetime-default.rs:10:1
+ --> $DIR/object-lifetime-default.rs:17:5
|
-LL | struct C<'a,T:'a>(&'a T);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | T: 'a,
+ | ^
error: Ambiguous
- --> $DIR/object-lifetime-default.rs:13:1
+ --> $DIR/object-lifetime-default.rs:24:5
|
-LL | struct D<'a,'b,T:'a+'b>(&'a T, &'b T);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | T: 'a + 'b,
+ | ^
error: 'b
- --> $DIR/object-lifetime-default.rs:16:1
+ --> $DIR/object-lifetime-default.rs:31:5
|
-LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | T: 'b,
+ | ^
-error: 'a,'b
- --> $DIR/object-lifetime-default.rs:19:1
+error: 'a
+ --> $DIR/object-lifetime-default.rs:38:5
+ |
+LL | T: 'a,
+ | ^
+
+error: 'b
+ --> $DIR/object-lifetime-default.rs:39:5
|
-LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | U: 'b,
+ | ^
-error: 'a,Ambiguous
- --> $DIR/object-lifetime-default.rs:22:1
+error: 'a
+ --> $DIR/object-lifetime-default.rs:46:5
+ |
+LL | T: 'a,
+ | ^
+
+error: Ambiguous
+ --> $DIR/object-lifetime-default.rs:47:5
|
-LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | U: 'a + 'b,
+ | ^
-error: aborting due to 7 previous errors
+error: aborting due to 9 previous errors
diff --git a/src/test/ui/object-safety/issue-19538.stderr b/src/test/ui/object-safety/issue-19538.stderr
index 7b37e1f95..8420637b3 100644
--- a/src/test/ui/object-safety/issue-19538.stderr
+++ b/src/test/ui/object-safety/issue-19538.stderr
@@ -29,7 +29,7 @@ LL | fn foo<T>(&self, val: T);
LL | trait Bar: Foo { }
| --- this trait cannot be made into an object...
= help: consider moving `foo` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
+ = note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>`
= note: required by cast to type `&mut dyn Bar`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
index 9dd144fee..5f94c9284 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/object-safety-associated-consts.rs:12:30
+ --> $DIR/object-safety-associated-consts.rs:12:31
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-associated-consts.rs:9:11
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
index 9ba3b251e..f44de07d5 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
@@ -12,7 +12,7 @@ LL | trait Bar {
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
= note: required by cast to type `&dyn Bar`
error: aborting due to previous error
diff --git a/src/test/ui/object-safety/object-safety-bounds.stderr b/src/test/ui/object-safety/object-safety-bounds.stderr
index 89c4f8ced..29ffb5448 100644
--- a/src/test/ui/object-safety/object-safety-bounds.stderr
+++ b/src/test/ui/object-safety/object-safety-bounds.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `X` cannot be made into an object
- --> $DIR/object-safety-bounds.rs:7:11
+ --> $DIR/object-safety-bounds.rs:7:15
|
LL | fn f() -> Box<dyn X<U = u32>> {
- | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+ | ^^^^^^^^^^^^^^ `X` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-bounds.rs:4:13
diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr
index 345950f1a..458103752 100644
--- a/src/test/ui/object-safety/object-safety-generics.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/object-safety-generics.rs:18:30
+ --> $DIR/object-safety-generics.rs:18:31
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-generics.rs:10:8
@@ -14,10 +14,10 @@ LL | fn bar<T>(&self, t: T);
= help: consider moving `bar` to another trait
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/object-safety-generics.rs:24:39
+ --> $DIR/object-safety-generics.rs:24:40
|
LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-generics.rs:10:8
diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
index 86355627c..9a2d472d5 100644
--- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -12,7 +12,7 @@ LL | trait Bar {
LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
= note: required by cast to type `&dyn Bar`
error[E0038]: the trait `Bar` cannot be made into an object
@@ -29,7 +29,7 @@ LL | trait Bar {
LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
= note: required by cast to type `&dyn Bar`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
index f91c9b985..de430a89b 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/object-safety-mentions-Self.rs:22:30
+ --> $DIR/object-safety-mentions-Self.rs:22:31
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-mentions-Self.rs:11:22
@@ -14,10 +14,10 @@ LL | fn bar(&self, x: &Self);
= help: consider moving `bar` to another trait
error[E0038]: the trait `Baz` cannot be made into an object
- --> $DIR/object-safety-mentions-Self.rs:28:30
+ --> $DIR/object-safety-mentions-Self.rs:28:31
|
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
- | ^^^^^^^^ `Baz` cannot be made into an object
+ | ^^^^^^^ `Baz` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-mentions-Self.rs:15:22
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
index f48628c9d..40a298bd1 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
@@ -12,7 +12,7 @@ LL | trait Bar {
LL | fn bar(&self, x: &Self);
| ^^^^^ ...because method `bar` references the `Self` type in this parameter
= help: consider moving `bar` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
= note: required by cast to type `&dyn Bar`
error[E0038]: the trait `Baz` cannot be made into an object
@@ -29,7 +29,7 @@ LL | trait Baz {
LL | fn baz(&self) -> Self;
| ^^^^ ...because method `baz` references the `Self` type in its return type
= help: consider moving `baz` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Baz>`
= note: required by cast to type `&dyn Baz`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr
index bd8cf4e30..1b025229e 100644
--- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/object-safety-no-static.rs:12:18
+ --> $DIR/object-safety-no-static.rs:12:22
|
LL | fn diverges() -> Box<dyn Foo> {
- | ^^^^^^^^^^^^ `Foo` cannot be made into an object
+ | ^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-no-static.rs:9:8
diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
index ea1c575ff..da87b58c9 100644
--- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
@@ -11,7 +11,7 @@ LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn foo() {}
| ^^^ ...because associated function `foo` has no `self` parameter
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<Bar>`
+ = note: required for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>`
= note: required by cast to type `Box<dyn Foo>`
help: consider turning `foo` into a method by giving it a `&self` argument
|
diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
index 71236c8e3..b01926412 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/object-safety-sized-2.rs:14:30
+ --> $DIR/object-safety-sized-2.rs:14:31
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-sized-2.rs:9:18
diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
index b6e4903b0..6c29c8d5f 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
@@ -11,7 +11,7 @@ LL | trait Bar
| --- this trait cannot be made into an object...
LL | where Self : Sized
| ^^^^^ ...because it requires `Self: Sized`
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
= note: required by cast to type `&dyn Bar`
error: aborting due to previous error
diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr
index 94b06ee93..974813121 100644
--- a/src/test/ui/object-safety/object-safety-sized.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/object-safety-sized.rs:12:30
+ --> $DIR/object-safety-sized.rs:12:31
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-sized.rs:8:13
diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
index 645852c7e..70a44ed61 100644
--- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -11,7 +11,7 @@ LL | trait Bar : Sized {
| --- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
= note: required by cast to type `&dyn Bar`
error: aborting due to previous error
diff --git a/src/test/ui/on-unimplemented/enclosing-scope.rs b/src/test/ui/on-unimplemented/enclosing-scope.rs
deleted file mode 100644
index 881bff63f..000000000
--- a/src/test/ui/on-unimplemented/enclosing-scope.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Test scope annotations from `enclosing_scope` parameter
-
-#![feature(rustc_attrs)]
-
-#[rustc_on_unimplemented(enclosing_scope="in this scope")]
-trait Trait{}
-
-struct Foo;
-
-fn f<T: Trait>(x: T) {}
-
-fn main() {
- let x = || {
- f(Foo{}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
- let y = || {
- f(Foo{}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
- };
- };
-
- {
- {
- f(Foo{}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
- }
- }
-
- f(Foo{}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
-}
diff --git a/src/test/ui/on-unimplemented/enclosing-scope.stderr b/src/test/ui/on-unimplemented/enclosing-scope.stderr
deleted file mode 100644
index 67759d02a..000000000
--- a/src/test/ui/on-unimplemented/enclosing-scope.stderr
+++ /dev/null
@@ -1,86 +0,0 @@
-error[E0277]: the trait bound `Foo: Trait` is not satisfied
- --> $DIR/enclosing-scope.rs:14:11
- |
-LL | let x = || {
- | _____________-
-LL | | f(Foo{});
- | | - ^^^^^ the trait `Trait` is not implemented for `Foo`
- | | |
- | | required by a bound introduced by this call
-LL | | let y = || {
-LL | | f(Foo{});
-LL | | };
-LL | | };
- | |_____- in this scope
- |
-note: required by a bound in `f`
- --> $DIR/enclosing-scope.rs:10:9
- |
-LL | fn f<T: Trait>(x: T) {}
- | ^^^^^ required by this bound in `f`
-
-error[E0277]: the trait bound `Foo: Trait` is not satisfied
- --> $DIR/enclosing-scope.rs:16:15
- |
-LL | let y = || {
- | _________________-
-LL | | f(Foo{});
- | | - ^^^^^ the trait `Trait` is not implemented for `Foo`
- | | |
- | | required by a bound introduced by this call
-LL | | };
- | |_________- in this scope
- |
-note: required by a bound in `f`
- --> $DIR/enclosing-scope.rs:10:9
- |
-LL | fn f<T: Trait>(x: T) {}
- | ^^^^^ required by this bound in `f`
-
-error[E0277]: the trait bound `Foo: Trait` is not satisfied
- --> $DIR/enclosing-scope.rs:22:15
- |
-LL | / fn main() {
-LL | | let x = || {
-LL | | f(Foo{});
-LL | | let y = || {
-... |
-LL | | f(Foo{});
- | | - ^^^^^ the trait `Trait` is not implemented for `Foo`
- | | |
- | | required by a bound introduced by this call
-... |
-LL | | f(Foo{});
-LL | | }
- | |_- in this scope
- |
-note: required by a bound in `f`
- --> $DIR/enclosing-scope.rs:10:9
- |
-LL | fn f<T: Trait>(x: T) {}
- | ^^^^^ required by this bound in `f`
-
-error[E0277]: the trait bound `Foo: Trait` is not satisfied
- --> $DIR/enclosing-scope.rs:26:7
- |
-LL | / fn main() {
-LL | | let x = || {
-LL | | f(Foo{});
-LL | | let y = || {
-... |
-LL | | f(Foo{});
- | | - ^^^^^ the trait `Trait` is not implemented for `Foo`
- | | |
- | | required by a bound introduced by this call
-LL | | }
- | |_- in this scope
- |
-note: required by a bound in `f`
- --> $DIR/enclosing-scope.rs:10:9
- |
-LL | fn f<T: Trait>(x: T) {}
- | ^^^^^ required by this bound in `f`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs
index b74957ebc..a32fd4566 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.rs
+++ b/src/test/ui/on-unimplemented/multiple-impls.rs
@@ -33,10 +33,13 @@ fn main() {
Index::index(&[] as &[i32], 2u32);
//~^ ERROR E0277
//~| ERROR E0277
+ //~| ERROR E0277
Index::index(&[] as &[i32], Foo(2u32));
//~^ ERROR E0277
//~| ERROR E0277
+ //~| ERROR E0277
Index::index(&[] as &[i32], Bar(2u32));
//~^ ERROR E0277
//~| ERROR E0277
+ //~| ERROR E0277
}
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
index 06e1a222a..d628b159a 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.stderr
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
- --> $DIR/multiple-impls.rs:33:18
+ --> $DIR/multiple-impls.rs:33:33
|
LL | Index::index(&[] as &[i32], 2u32);
- | ------------ ^^^^^^^^^^^^^ trait message
+ | ------------ ^^^^ trait message
| |
| required by a bound introduced by this call
|
@@ -11,11 +11,22 @@ LL | Index::index(&[] as &[i32], 2u32);
<[i32] as Index<Bar<usize>>>
<[i32] as Index<Foo<usize>>>
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+ --> $DIR/multiple-impls.rs:33:5
+ |
+LL | Index::index(&[] as &[i32], 2u32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message
+ |
+ = help: the trait `Index<u32>` is not implemented for `[i32]`
+ = help: the following other types implement trait `Index<Idx>`:
+ <[i32] as Index<Bar<usize>>>
+ <[i32] as Index<Foo<usize>>>
+
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
- --> $DIR/multiple-impls.rs:36:18
+ --> $DIR/multiple-impls.rs:37:33
|
LL | Index::index(&[] as &[i32], Foo(2u32));
- | ------------ ^^^^^^^^^^^^^ on impl for Foo
+ | ------------ ^^^^^^^^^ on impl for Foo
| |
| required by a bound introduced by this call
|
@@ -24,11 +35,22 @@ LL | Index::index(&[] as &[i32], Foo(2u32));
<[i32] as Index<Bar<usize>>>
<[i32] as Index<Foo<usize>>>
+error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
+ --> $DIR/multiple-impls.rs:37:5
+ |
+LL | Index::index(&[] as &[i32], Foo(2u32));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
+ |
+ = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+ = help: the following other types implement trait `Index<Idx>`:
+ <[i32] as Index<Bar<usize>>>
+ <[i32] as Index<Foo<usize>>>
+
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
- --> $DIR/multiple-impls.rs:39:18
+ --> $DIR/multiple-impls.rs:41:33
|
LL | Index::index(&[] as &[i32], Bar(2u32));
- | ------------ ^^^^^^^^^^^^^ on impl for Bar
+ | ------------ ^^^^^^^^^ on impl for Bar
| |
| required by a bound introduced by this call
|
@@ -37,6 +59,17 @@ LL | Index::index(&[] as &[i32], Bar(2u32));
<[i32] as Index<Bar<usize>>>
<[i32] as Index<Foo<usize>>>
+error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
+ --> $DIR/multiple-impls.rs:41:5
+ |
+LL | Index::index(&[] as &[i32], Bar(2u32));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
+ |
+ = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+ = help: the following other types implement trait `Index<Idx>`:
+ <[i32] as Index<Bar<usize>>>
+ <[i32] as Index<Foo<usize>>>
+
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
--> $DIR/multiple-impls.rs:33:5
|
@@ -49,7 +82,7 @@ LL | Index::index(&[] as &[i32], 2u32);
<[i32] as Index<Foo<usize>>>
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
- --> $DIR/multiple-impls.rs:36:5
+ --> $DIR/multiple-impls.rs:37:5
|
LL | Index::index(&[] as &[i32], Foo(2u32));
| ^^^^^^^^^^^^ on impl for Foo
@@ -60,7 +93,7 @@ LL | Index::index(&[] as &[i32], Foo(2u32));
<[i32] as Index<Foo<usize>>>
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
- --> $DIR/multiple-impls.rs:39:5
+ --> $DIR/multiple-impls.rs:41:5
|
LL | Index::index(&[] as &[i32], Bar(2u32));
| ^^^^^^^^^^^^ on impl for Bar
@@ -70,6 +103,6 @@ LL | Index::index(&[] as &[i32], Bar(2u32));
<[i32] as Index<Bar<usize>>>
<[i32] as Index<Foo<usize>>>
-error: aborting due to 6 previous errors
+error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs
index ab3e67d01..d0537810c 100644
--- a/src/test/ui/on-unimplemented/on-impl.rs
+++ b/src/test/ui/on-unimplemented/on-impl.rs
@@ -22,4 +22,5 @@ fn main() {
Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
//~^ ERROR E0277
//~| ERROR E0277
+ //~| ERROR E0277
}
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
index 769a3d77a..2253c5992 100644
--- a/src/test/ui/on-unimplemented/on-impl.stderr
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
- --> $DIR/on-impl.rs:22:25
+ --> $DIR/on-impl.rs:22:47
|
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
- | ------------------- ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+ | ------------------- ^^^^ a usize is required to index into a slice
| |
| required by a bound introduced by this call
|
@@ -13,11 +13,20 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
--> $DIR/on-impl.rs:22:5
|
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+ |
+ = help: the trait `Index<u32>` is not implemented for `[i32]`
+ = help: the trait `Index<usize>` is implemented for `[i32]`
+
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+ --> $DIR/on-impl.rs:22:5
+ |
+LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
| ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
|
= help: the trait `Index<u32>` is not implemented for `[i32]`
= help: the trait `Index<usize>` is implemented for `[i32]`
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/on-unimplemented/parent-label.rs b/src/test/ui/on-unimplemented/parent-label.rs
new file mode 100644
index 000000000..b65f64968
--- /dev/null
+++ b/src/test/ui/on-unimplemented/parent-label.rs
@@ -0,0 +1,27 @@
+// Test scope annotations from `parent_label` parameter
+
+#![feature(rustc_attrs)]
+
+#[rustc_on_unimplemented(parent_label = "in this scope")]
+trait Trait {}
+
+struct Foo;
+
+fn f<T: Trait>(x: T) {}
+
+fn main() {
+ let x = || {
+ f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
+ let y = || {
+ f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
+ };
+ };
+
+ {
+ {
+ f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
+ }
+ }
+
+ f(Foo {}); //~ ERROR the trait bound `Foo: Trait` is not satisfied
+}
diff --git a/src/test/ui/on-unimplemented/parent-label.stderr b/src/test/ui/on-unimplemented/parent-label.stderr
new file mode 100644
index 000000000..8cd7412fd
--- /dev/null
+++ b/src/test/ui/on-unimplemented/parent-label.stderr
@@ -0,0 +1,69 @@
+error[E0277]: the trait bound `Foo: Trait` is not satisfied
+ --> $DIR/parent-label.rs:14:11
+ |
+LL | let x = || {
+ | -- in this scope
+LL | f(Foo {});
+ | - ^^^^^^ the trait `Trait` is not implemented for `Foo`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `f`
+ --> $DIR/parent-label.rs:10:9
+ |
+LL | fn f<T: Trait>(x: T) {}
+ | ^^^^^ required by this bound in `f`
+
+error[E0277]: the trait bound `Foo: Trait` is not satisfied
+ --> $DIR/parent-label.rs:16:15
+ |
+LL | let y = || {
+ | -- in this scope
+LL | f(Foo {});
+ | - ^^^^^^ the trait `Trait` is not implemented for `Foo`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `f`
+ --> $DIR/parent-label.rs:10:9
+ |
+LL | fn f<T: Trait>(x: T) {}
+ | ^^^^^ required by this bound in `f`
+
+error[E0277]: the trait bound `Foo: Trait` is not satisfied
+ --> $DIR/parent-label.rs:22:15
+ |
+LL | fn main() {
+ | --------- in this scope
+...
+LL | f(Foo {});
+ | - ^^^^^^ the trait `Trait` is not implemented for `Foo`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `f`
+ --> $DIR/parent-label.rs:10:9
+ |
+LL | fn f<T: Trait>(x: T) {}
+ | ^^^^^ required by this bound in `f`
+
+error[E0277]: the trait bound `Foo: Trait` is not satisfied
+ --> $DIR/parent-label.rs:26:7
+ |
+LL | fn main() {
+ | --------- in this scope
+...
+LL | f(Foo {});
+ | - ^^^^^^ the trait `Trait` is not implemented for `Foo`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `f`
+ --> $DIR/parent-label.rs:10:9
+ |
+LL | fn f<T: Trait>(x: T) {}
+ | ^^^^^ required by this bound in `f`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr
index 72f67a685..a7ec3bda8 100644
--- a/src/test/ui/on-unimplemented/slice-index.stderr
+++ b/src/test/ui/on-unimplemented/slice-index.stderr
@@ -6,7 +6,7 @@ LL | x[1i32];
|
= help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<i32>` for `[i32]`
+ = note: required for `[i32]` to implement `Index<i32>`
error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
--> $DIR/slice-index.rs:9:7
@@ -18,7 +18,7 @@ LL | x[..1i32];
= help: the following other types implement trait `SliceIndex<T>`:
<RangeTo<usize> as SliceIndex<[T]>>
<RangeTo<usize> as SliceIndex<str>>
- = note: required because of the requirements on the impl of `Index<RangeTo<i32>>` for `[i32]`
+ = note: required for `[i32]` to implement `Index<RangeTo<i32>>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/or-patterns/inner-or-pat.or3.stderr b/src/test/ui/or-patterns/inner-or-pat.or3.stderr
new file mode 100644
index 000000000..2236a38c3
--- /dev/null
+++ b/src/test/ui/or-patterns/inner-or-pat.or3.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/inner-or-pat.rs:38:54
+ |
+LL | match x {
+ | - this expression has type `&str`
+LL | x @ ((("h" | "ho" | "yo" | ("dude" | "w")) | () | "nop") | ("hey" | "gg")) |
+ | ^^ expected `str`, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/or-patterns/inner-or-pat.or4.stderr b/src/test/ui/or-patterns/inner-or-pat.or4.stderr
new file mode 100644
index 000000000..058873ff5
--- /dev/null
+++ b/src/test/ui/or-patterns/inner-or-pat.or4.stderr
@@ -0,0 +1,11 @@
+error[E0408]: variable `x` is not bound in all patterns
+ --> $DIR/inner-or-pat.rs:53:37
+ |
+LL | (x @ "red" | (x @ "blue" | "red")) => {
+ | - ^^^^^ pattern doesn't bind `x`
+ | |
+ | variable not in all patterns
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0408`.
diff --git a/src/test/ui/or-patterns/inner-or-pat.rs b/src/test/ui/or-patterns/inner-or-pat.rs
new file mode 100644
index 000000000..f4cf4b0c1
--- /dev/null
+++ b/src/test/ui/or-patterns/inner-or-pat.rs
@@ -0,0 +1,73 @@
+// revisions: or1 or2 or3 or4 or5
+// [or1] run-pass
+// [or2] run-pass
+// [or5] run-pass
+
+#![allow(unreachable_patterns)]
+#![allow(unused_variables)]
+#![allow(unused_parens)]
+#![allow(dead_code)]
+
+
+
+fn foo() {
+ let x = "foo";
+ match x {
+ x @ ((("h" | "ho" | "yo" | ("dude" | "w")) | "no" | "nop") | ("hey" | "gg")) |
+ x @ ("black" | "pink") |
+ x @ ("red" | "blue") => {
+ }
+ _ => (),
+ }
+}
+
+fn bar() {
+ let x = "foo";
+ match x {
+ x @ ("foo" | "bar") |
+ (x @ "red" | (x @ "blue" | x @ "red")) => {
+ }
+ _ => (),
+ }
+}
+
+#[cfg(or3)]
+fn zot() {
+ let x = "foo";
+ match x {
+ x @ ((("h" | "ho" | "yo" | ("dude" | "w")) | () | "nop") | ("hey" | "gg")) |
+ //[or3]~^ ERROR mismatched types
+ x @ ("black" | "pink") |
+ x @ ("red" | "blue") => {
+ }
+ _ => (),
+ }
+}
+
+
+#[cfg(or4)]
+fn hey() {
+ let x = "foo";
+ match x {
+ x @ ("foo" | "bar") |
+ (x @ "red" | (x @ "blue" | "red")) => {
+ //[or4]~^ variable `x` is not bound in all patterns
+ }
+ _ => (),
+ }
+}
+
+fn don() {
+ enum Foo {
+ A,
+ B,
+ C,
+ }
+
+ match Foo::A {
+ | _foo @ (Foo::A | Foo::B) => {}
+ Foo::C => {}
+ };
+}
+
+fn main(){}
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
index 6f9a631b0..dda5c0bb5 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
@@ -7,7 +7,7 @@ fn main() {}
// Test the `pat` macro fragment parser:
macro_rules! accept_pat {
- ($p:pat) => {}
+ ($p:pat) => {};
}
accept_pat!((p | q));
@@ -21,28 +21,28 @@ accept_pat!([p | q]);
#[cfg(FALSE)]
fn or_patterns() {
// Top level of `let`:
- let (| A | B);
+ let (A | B);
let (A | B);
let (A | B): u8;
let (A | B) = 0;
let (A | B): u8 = 0;
// Top level of `for`:
- for | A | B in 0 {}
+ for A | B in 0 {}
for A | B in 0 {}
// Top level of `while`:
- while let | A | B = 0 {}
+ while let A | B = 0 {}
while let A | B = 0 {}
// Top level of `if`:
- if let | A | B = 0 {}
+ if let A | B = 0 {}
if let A | B = 0 {}
// Top level of `match` arms:
match 0 {
- | A | B => {},
- A | B => {},
+ A | B => {}
+ A | B => {}
}
// Functions:
@@ -68,6 +68,8 @@ fn or_patterns() {
// These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
+ //~^ WARN box pattern syntax is experimental
+ //~| WARN unstable syntax
let (&0 | 1);
let (&mut 0 | 1);
let (x @ 0 | 1);
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr
new file mode 100644
index 000000000..c43fe192a
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr
@@ -0,0 +1,13 @@
+warning: box pattern syntax is experimental
+ --> $DIR/or-patterns-syntactic-pass.rs:70:10
+ |
+LL | let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
+ | ^^^^^
+ |
+ = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
+ = help: add `#![feature(box_patterns)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/parser/bad-interpolated-block.rs b/src/test/ui/parser/bad-interpolated-block.rs
index 38d53a14b..c6d7ae383 100644
--- a/src/test/ui/parser/bad-interpolated-block.rs
+++ b/src/test/ui/parser/bad-interpolated-block.rs
@@ -1,5 +1,3 @@
-#![feature(label_break_value)]
-
fn main() {}
macro_rules! m {
diff --git a/src/test/ui/parser/bad-interpolated-block.stderr b/src/test/ui/parser/bad-interpolated-block.stderr
index 77933b1bc..2a0999afd 100644
--- a/src/test/ui/parser/bad-interpolated-block.stderr
+++ b/src/test/ui/parser/bad-interpolated-block.stderr
@@ -1,5 +1,5 @@
error: cannot use a `block` macro fragment here
- --> $DIR/bad-interpolated-block.rs:7:15
+ --> $DIR/bad-interpolated-block.rs:5:15
|
LL | 'lab: $b;
| ------^^
@@ -12,7 +12,7 @@ LL | m!({});
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot use a `block` macro fragment here
- --> $DIR/bad-interpolated-block.rs:8:16
+ --> $DIR/bad-interpolated-block.rs:6:16
|
LL | unsafe $b;
| -------^^
@@ -25,7 +25,7 @@ LL | m!({});
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot use a `block` macro fragment here
- --> $DIR/bad-interpolated-block.rs:9:23
+ --> $DIR/bad-interpolated-block.rs:7:23
|
LL | |x: u8| -> () $b;
| ^^ the `block` fragment is within this context
diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
index afbd13e6f..d8346653c 100644
--- a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
+++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
@@ -3,7 +3,11 @@
#[cfg(FALSE)]
fn syntax() {
foo::<T = u8, T: Ord, String>();
+ //~^ WARN associated type bounds are unstable
+ //~| WARN unstable syntax
foo::<T = u8, 'a, T: Ord>();
+ //~^ WARN associated type bounds are unstable
+ //~| WARN unstable syntax
}
fn main() {}
diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr
new file mode 100644
index 000000000..7e843c7f4
--- /dev/null
+++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr
@@ -0,0 +1,24 @@
+warning: associated type bounds are unstable
+ --> $DIR/constraints-before-generic-args-syntactic-pass.rs:5:19
+ |
+LL | foo::<T = u8, T: Ord, String>();
+ | ^^^^^^
+ |
+ = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
+ = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: associated type bounds are unstable
+ --> $DIR/constraints-before-generic-args-syntactic-pass.rs:8:23
+ |
+LL | foo::<T = u8, 'a, T: Ord>();
+ | ^^^^^^
+ |
+ = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
+ = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-before-array.rs b/src/test/ui/parser/do-not-suggest-semicolon-before-array.rs
new file mode 100644
index 000000000..7ebf3f6b0
--- /dev/null
+++ b/src/test/ui/parser/do-not-suggest-semicolon-before-array.rs
@@ -0,0 +1,8 @@
+fn foo() {}
+
+fn bar() -> [u8; 2] {
+ foo()
+ [1, 3) //~ ERROR expected one of `.`, `?`, `]`, or an operator, found `,`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr b/src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr
new file mode 100644
index 000000000..a9dd52632
--- /dev/null
+++ b/src/test/ui/parser/do-not-suggest-semicolon-before-array.stderr
@@ -0,0 +1,10 @@
+error: expected one of `.`, `?`, `]`, or an operator, found `,`
+ --> $DIR/do-not-suggest-semicolon-before-array.rs:5:5
+ |
+LL | [1, 3)
+ | ^ ^ help: `]` may belong here
+ | |
+ | unclosed delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs b/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs
new file mode 100644
index 000000000..d6f798181
--- /dev/null
+++ b/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let _x = vec[1, 2, 3]; //~ ERROR expected one of `.`, `?`, `]`, or an operator
+}
diff --git a/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr b/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr
new file mode 100644
index 000000000..2fe6a28ee
--- /dev/null
+++ b/src/test/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr
@@ -0,0 +1,8 @@
+error: expected one of `.`, `?`, `]`, or an operator, found `,`
+ --> $DIR/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs:2:19
+ |
+LL | let _x = vec[1, 2, 3];
+ | ^ expected one of `.`, `?`, `]`, or an operator
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-def.rs b/src/test/ui/parser/fn-defined-using-def.rs
new file mode 100644
index 000000000..21da34c47
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-def.rs
@@ -0,0 +1,10 @@
+// Check what happens when `def` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+def foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `def` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-def.stderr b/src/test/ui/parser/fn-defined-using-def.stderr
new file mode 100644
index 000000000..f34329012
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-def.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+ --> $DIR/fn-defined-using-def.rs:6:5
+ |
+LL | def foo() {}
+ | --- ^^^ expected one of `!` or `::`
+ | |
+ | help: write `fn` instead of `def` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-fun.rs b/src/test/ui/parser/fn-defined-using-fun.rs
new file mode 100644
index 000000000..4f7460504
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-fun.rs
@@ -0,0 +1,10 @@
+// Check what happens when `fun` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+fun foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `fun` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-fun.stderr b/src/test/ui/parser/fn-defined-using-fun.stderr
new file mode 100644
index 000000000..2f6cfff35
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-fun.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+ --> $DIR/fn-defined-using-fun.rs:6:5
+ |
+LL | fun foo() {}
+ | --- ^^^ expected one of `!` or `::`
+ | |
+ | help: write `fn` instead of `fun` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-func.rs b/src/test/ui/parser/fn-defined-using-func.rs
new file mode 100644
index 000000000..2dce96fdc
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-func.rs
@@ -0,0 +1,10 @@
+// Check what happens when `func` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+func foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `func` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-func.stderr b/src/test/ui/parser/fn-defined-using-func.stderr
new file mode 100644
index 000000000..355741e89
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-func.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+ --> $DIR/fn-defined-using-func.rs:6:6
+ |
+LL | func foo() {}
+ | ---- ^^^ expected one of `!` or `::`
+ | |
+ | help: write `fn` instead of `func` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-function.rs b/src/test/ui/parser/fn-defined-using-function.rs
new file mode 100644
index 000000000..fd8782728
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-function.rs
@@ -0,0 +1,10 @@
+// Check what happens when `function` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+function foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `function` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-function.stderr b/src/test/ui/parser/fn-defined-using-function.stderr
new file mode 100644
index 000000000..43c33a2cd
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-function.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+ --> $DIR/fn-defined-using-function.rs:6:10
+ |
+LL | function foo() {}
+ | -------- ^^^ expected one of `!` or `::`
+ | |
+ | help: write `fn` instead of `function` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs
index 8ff14fb1f..cf5d3dab4 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.rs
+++ b/src/test/ui/parser/fn-header-semantic-fail.rs
@@ -27,7 +27,6 @@ fn main() {
struct Y;
impl X for Y {
async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
- //~^ ERROR has an incompatible type for trait
unsafe fn ft2() {} // OK.
const fn ft3() {} //~ ERROR functions in traits cannot be declared const
extern "C" fn ft4() {}
@@ -36,7 +35,6 @@ fn main() {
//~| ERROR functions in traits cannot be declared const
//~| ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected
- //~| ERROR has an incompatible type for trait
}
impl Y {
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
index bc51ba8b8..36304779d 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -7,17 +7,6 @@ LL | const async unsafe extern "C" fn ff5() {}
| | `async` because of this
| `const` because of this
-error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:17:9
- |
-LL | async fn ft1();
- | -----^^^^^^^^^^
- | |
- | `async` because of this
- |
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
-
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:19:9
|
@@ -30,17 +19,6 @@ error[E0379]: functions in traits cannot be declared const
LL | const async unsafe extern "C" fn ft5();
| ^^^^^ functions in traits cannot be const
-error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:21:9
- |
-LL | const async unsafe extern "C" fn ft5();
- | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `async` because of this
- |
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
-
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:21:9
|
@@ -50,42 +28,20 @@ LL | const async unsafe extern "C" fn ft5();
| | `async` because of this
| `const` because of this
-error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:29:9
- |
-LL | async fn ft1() {}
- | -----^^^^^^^^^^^^
- | |
- | `async` because of this
- |
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
-
error[E0379]: functions in traits cannot be declared const
- --> $DIR/fn-header-semantic-fail.rs:32:9
+ --> $DIR/fn-header-semantic-fail.rs:31:9
|
LL | const fn ft3() {}
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^ functions in traits cannot be const
-error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:34:9
- |
-LL | const async unsafe extern "C" fn ft5() {}
- | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `async` because of this
- |
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
-
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^-^^^^^------------------------------
@@ -94,7 +50,7 @@ LL | const async unsafe extern "C" fn ft5() {}
| `const` because of this
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:47:9
+ --> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^-^^^^^------------------------------
@@ -103,7 +59,7 @@ LL | const async unsafe extern "C" fn fi5() {}
| `const` because of this
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:53:18
+ --> $DIR/fn-header-semantic-fail.rs:51:18
|
LL | extern "C" {
| ---------- in this `extern` block
@@ -116,7 +72,7 @@ LL | fn fe1();
| ~~
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:54:19
+ --> $DIR/fn-header-semantic-fail.rs:52:19
|
LL | extern "C" {
| ---------- in this `extern` block
@@ -130,7 +86,7 @@ LL | fn fe2();
| ~~
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:55:18
+ --> $DIR/fn-header-semantic-fail.rs:53:18
|
LL | extern "C" {
| ---------- in this `extern` block
@@ -144,7 +100,7 @@ LL | fn fe3();
| ~~
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:56:23
+ --> $DIR/fn-header-semantic-fail.rs:54:23
|
LL | extern "C" {
| ---------- in this `extern` block
@@ -158,7 +114,7 @@ LL | fn fe4();
| ~~
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:57:42
+ --> $DIR/fn-header-semantic-fail.rs:55:42
|
LL | extern "C" {
| ---------- in this `extern` block
@@ -172,7 +128,7 @@ LL | fn fe5();
| ~~
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:57:9
+ --> $DIR/fn-header-semantic-fail.rs:55:9
|
LL | const async unsafe extern "C" fn fe5();
| ^^^^^-^^^^^----------------------------
@@ -180,6 +136,58 @@ LL | const async unsafe extern "C" fn fe5();
| | `async` because of this
| `const` because of this
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:17:9
+ |
+LL | async fn ft1();
+ | -----^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:21:9
+ |
+LL | const async unsafe extern "C" fn ft5();
+ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:29:9
+ |
+LL | async fn ft1() {}
+ | -----^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:33:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:12:44
|
@@ -216,60 +224,24 @@ LL | | }
LL | | }
| |_^
-error[E0053]: method `ft1` has an incompatible type for trait
- --> $DIR/fn-header-semantic-fail.rs:29:24
- |
-LL | async fn ft1() {}
- | ^
- | |
- | checked the `Output` of this `async fn`, found opaque type
- | expected `()`, found opaque type
- |
- = note: while checking the return type of the `async fn`
-note: type in trait
- --> $DIR/fn-header-semantic-fail.rs:17:23
- |
-LL | async fn ft1();
- | ^
- = note: expected fn pointer `fn()`
- found fn pointer `fn() -> impl Future<Output = ()>`
-
-error[E0053]: method `ft5` has an incompatible type for trait
- --> $DIR/fn-header-semantic-fail.rs:34:48
- |
-LL | const async unsafe extern "C" fn ft5() {}
- | ^
- | |
- | checked the `Output` of this `async fn`, found opaque type
- | expected `()`, found opaque type
- |
- = note: while checking the return type of the `async fn`
-note: type in trait
- --> $DIR/fn-header-semantic-fail.rs:21:47
- |
-LL | const async unsafe extern "C" fn ft5();
- | ^
- = note: expected fn pointer `unsafe extern "C" fn()`
- found fn pointer `unsafe extern "C" fn() -> impl Future<Output = ()>`
-
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`
- --> $DIR/fn-header-semantic-fail.rs:34:48
+ --> $DIR/fn-header-semantic-fail.rs:33:48
|
LL | const async unsafe extern "C" fn ft5() {}
| ^
|
note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -288,30 +260,30 @@ LL | | }
LL | | }
| |_^
-error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`
- --> $DIR/fn-header-semantic-fail.rs:47:48
+error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`
+ --> $DIR/fn-header-semantic-fail.rs:45:48
|
LL | const async unsafe extern "C" fn fi5() {}
| ^
|
-note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
- --> $DIR/fn-header-semantic-fail.rs:47:9
+note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+ --> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
- --> $DIR/fn-header-semantic-fail.rs:47:9
+note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+ --> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
- --> $DIR/fn-header-semantic-fail.rs:47:9
+note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+ --> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
- = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`, completing the cycle
+ = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1
|
@@ -324,7 +296,7 @@ LL | | }
LL | | }
| |_^
-error: aborting due to 23 previous errors
+error: aborting due to 21 previous errors
-Some errors have detailed explanations: E0053, E0379, E0391, E0706.
-For more information about an error, try `rustc --explain E0053`.
+Some errors have detailed explanations: E0379, E0391, E0706.
+For more information about an error, try `rustc --explain E0379`.
diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
index 9871cb8fe..1291a021b 100644
--- a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
+++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
fn main() {}
struct X;
diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
index 4b398d791..3856754e0 100644
--- a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
+++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
@@ -1,5 +1,5 @@
error: associated type in `impl` without body
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:8:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:6:5
|
LL | type Y;
| ^^^^^^-
@@ -7,7 +7,7 @@ LL | type Y;
| help: provide a definition for the type: `= <type>;`
error: associated type in `impl` without body
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:9:5
|
LL | type Z: Ord;
| ^^^^^^^^^^^-
@@ -15,13 +15,13 @@ LL | type Z: Ord;
| help: provide a definition for the type: `= <type>;`
error: bounds on `type`s in `impl`s have no effect
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:13
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:9:13
|
LL | type Z: Ord;
| ^^^
error: associated type in `impl` without body
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:5
|
LL | type W: Ord where Self: Eq;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -29,13 +29,13 @@ LL | type W: Ord where Self: Eq;
| help: provide a definition for the type: `= <type>;`
error: bounds on `type`s in `impl`s have no effect
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:13
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:13
|
LL | type W: Ord where Self: Eq;
| ^^^
error: associated type in `impl` without body
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:19:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:17:5
|
LL | type W where Self: Eq;
| ^^^^^^^^^^^^^^^^^^^^^-
@@ -43,7 +43,7 @@ LL | type W where Self: Eq;
| help: provide a definition for the type: `= <type>;`
error[E0658]: inherent associated types are unstable
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:8:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:6:5
|
LL | type Y;
| ^^^^^^^
@@ -52,7 +52,7 @@ LL | type Y;
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
error[E0658]: inherent associated types are unstable
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:9:5
|
LL | type Z: Ord;
| ^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL | type Z: Ord;
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
error[E0658]: inherent associated types are unstable
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:5
|
LL | type W: Ord where Self: Eq;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL | type W: Ord where Self: Eq;
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
error[E0658]: inherent associated types are unstable
- --> $DIR/impl-item-type-no-body-semantic-fail.rs:19:5
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:17:5
|
LL | type W where Self: Eq;
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/parser/increment-notfixed.stderr b/src/test/ui/parser/increment-notfixed.stderr
index 352d98cf8..ae55ae067 100644
--- a/src/test/ui/parser/increment-notfixed.stderr
+++ b/src/test/ui/parser/increment-notfixed.stderr
@@ -8,9 +8,8 @@ help: use `+= 1` instead
|
LL | { let tmp = i; i += 1; tmp };
| +++++++++++ ~~~~~~~~~~~~~~~
-LL - i++;
-LL + i += 1;
- |
+LL | i += 1;
+ | ~~~~
error: Rust has no postfix increment operator
--> $DIR/increment-notfixed.rs:17:12
@@ -24,9 +23,8 @@ help: use `+= 1` instead
|
LL | while { let tmp = i; i += 1; tmp } < 5 {
| +++++++++++ ~~~~~~~~~~~~~~~
-LL - while i++ < 5 {
-LL + while i += 1 < 5 {
- |
+LL | while i += 1 < 5 {
+ | ~~~~
error: Rust has no postfix increment operator
--> $DIR/increment-notfixed.rs:25:8
@@ -38,9 +36,8 @@ help: use `+= 1` instead
|
LL | { let tmp_ = tmp; tmp += 1; tmp_ };
| ++++++++++++ ~~~~~~~~~~~~~~~~~~
-LL - tmp++;
-LL + tmp += 1;
- |
+LL | tmp += 1;
+ | ~~~~
error: Rust has no postfix increment operator
--> $DIR/increment-notfixed.rs:31:14
@@ -54,9 +51,8 @@ help: use `+= 1` instead
|
LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 {
| ++++++++++++ ~~~~~~~~~~~~~~~~~~
-LL - while tmp++ < 5 {
-LL + while tmp += 1 < 5 {
- |
+LL | while tmp += 1 < 5 {
+ | ~~~~
error: Rust has no postfix increment operator
--> $DIR/increment-notfixed.rs:39:16
@@ -68,9 +64,8 @@ help: use `+= 1` instead
|
LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp };
| +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~
-LL - foo.bar.qux++;
-LL + foo.bar.qux += 1;
- |
+LL | foo.bar.qux += 1;
+ | ~~~~
error: Rust has no postfix increment operator
--> $DIR/increment-notfixed.rs:49:10
@@ -82,9 +77,8 @@ help: use `+= 1` instead
|
LL | { let tmp = s.tmp; s.tmp += 1; tmp };
| +++++++++++ ~~~~~~~~~~~~~~~~~~~
-LL - s.tmp++;
-LL + s.tmp += 1;
- |
+LL | s.tmp += 1;
+ | ~~~~
error: Rust has no prefix increment operator
--> $DIR/increment-notfixed.rs:56:5
diff --git a/src/test/ui/parser/issue-100197-mut-let.fixed b/src/test/ui/parser/issue-100197-mut-let.fixed
new file mode 100644
index 000000000..5a8956222
--- /dev/null
+++ b/src/test/ui/parser/issue-100197-mut-let.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+ let mut _x = 123;
+ //~^ ERROR invalid variable declaration
+}
diff --git a/src/test/ui/parser/issue-100197-mut-let.rs b/src/test/ui/parser/issue-100197-mut-let.rs
new file mode 100644
index 000000000..71103813a
--- /dev/null
+++ b/src/test/ui/parser/issue-100197-mut-let.rs
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+ mut let _x = 123;
+ //~^ ERROR invalid variable declaration
+}
diff --git a/src/test/ui/parser/issue-100197-mut-let.stderr b/src/test/ui/parser/issue-100197-mut-let.stderr
new file mode 100644
index 000000000..86658e4f3
--- /dev/null
+++ b/src/test/ui/parser/issue-100197-mut-let.stderr
@@ -0,0 +1,8 @@
+error: invalid variable declaration
+ --> $DIR/issue-100197-mut-let.rs:4:5
+ |
+LL | mut let _x = 123;
+ | ^^^^^^^ help: switch the order of `mut` and `let`: `let mut`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-101477-enum.fixed b/src/test/ui/parser/issue-101477-enum.fixed
new file mode 100644
index 000000000..1dfeae22a
--- /dev/null
+++ b/src/test/ui/parser/issue-101477-enum.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+#[allow(dead_code)]
+enum Demo {
+ A = 1,
+ B = 2 //~ ERROR unexpected `==`
+ //~^ expected item, found `==`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-101477-enum.rs b/src/test/ui/parser/issue-101477-enum.rs
new file mode 100644
index 000000000..ea7051d69
--- /dev/null
+++ b/src/test/ui/parser/issue-101477-enum.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+
+#[allow(dead_code)]
+enum Demo {
+ A = 1,
+ B == 2 //~ ERROR unexpected `==`
+ //~^ expected item, found `==`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-101477-enum.stderr b/src/test/ui/parser/issue-101477-enum.stderr
new file mode 100644
index 000000000..bffc881bd
--- /dev/null
+++ b/src/test/ui/parser/issue-101477-enum.stderr
@@ -0,0 +1,14 @@
+error: unexpected `==`
+ --> $DIR/issue-101477-enum.rs:6:7
+ |
+LL | B == 2
+ | ^^ help: try using `=` instead
+
+error: expected item, found `==`
+ --> $DIR/issue-101477-enum.rs:6:7
+ |
+LL | B == 2
+ | ^^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issue-101477-let.fixed b/src/test/ui/parser/issue-101477-let.fixed
new file mode 100644
index 000000000..9989ad815
--- /dev/null
+++ b/src/test/ui/parser/issue-101477-let.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+ let x = 2; //~ ERROR unexpected `==`
+ println!("x: {}", x)
+}
diff --git a/src/test/ui/parser/issue-101477-let.rs b/src/test/ui/parser/issue-101477-let.rs
new file mode 100644
index 000000000..8b0e8bee1
--- /dev/null
+++ b/src/test/ui/parser/issue-101477-let.rs
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+ let x == 2; //~ ERROR unexpected `==`
+ println!("x: {}", x)
+}
diff --git a/src/test/ui/parser/issue-101477-let.stderr b/src/test/ui/parser/issue-101477-let.stderr
new file mode 100644
index 000000000..1b30d4b17
--- /dev/null
+++ b/src/test/ui/parser/issue-101477-let.stderr
@@ -0,0 +1,8 @@
+error: unexpected `==`
+ --> $DIR/issue-101477-let.rs:4:11
+ |
+LL | let x == 2;
+ | ^^ help: try using `=` instead
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed
new file mode 100644
index 000000000..64ab6f62b
--- /dev/null
+++ b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+ const _FOO: i32 = 123;
+ //~^ ERROR const` and `let` are mutually exclusive
+ const _BAR: i32 = 123;
+ //~^ ERROR `const` and `let` are mutually exclusive
+}
diff --git a/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs
new file mode 100644
index 000000000..50520971f
--- /dev/null
+++ b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+ const let _FOO: i32 = 123;
+ //~^ ERROR const` and `let` are mutually exclusive
+ let const _BAR: i32 = 123;
+ //~^ ERROR `const` and `let` are mutually exclusive
+}
diff --git a/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr
new file mode 100644
index 000000000..72377fc37
--- /dev/null
+++ b/src/test/ui/parser/issue-99910-const-let-mutually-exclusive.stderr
@@ -0,0 +1,14 @@
+error: `const` and `let` are mutually exclusive
+ --> $DIR/issue-99910-const-let-mutually-exclusive.rs:4:5
+ |
+LL | const let _FOO: i32 = 123;
+ | ^^^^^^^^^ help: remove `let`: `const`
+
+error: `const` and `let` are mutually exclusive
+ --> $DIR/issue-99910-const-let-mutually-exclusive.rs:6:5
+ |
+LL | let const _BAR: i32 = 123;
+ | ^^^^^^^^^ help: remove `let`: `const`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-14303-enum.rs b/src/test/ui/parser/issues/issue-14303-enum.rs
deleted file mode 100644
index a61061598..000000000
--- a/src/test/ui/parser/issues/issue-14303-enum.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-enum X<'a, T, 'b> {
-//~^ ERROR lifetime parameters must be declared prior to type parameters
- A(&'a &'b T)
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-enum.stderr b/src/test/ui/parser/issues/issue-14303-enum.stderr
deleted file mode 100644
index 55cef4cab..000000000
--- a/src/test/ui/parser/issues/issue-14303-enum.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
- --> $DIR/issue-14303-enum.rs:1:15
- |
-LL | enum X<'a, T, 'b> {
- | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/issues/issue-14303-fn-def.rs b/src/test/ui/parser/issues/issue-14303-fn-def.rs
deleted file mode 100644
index 221bd311e..000000000
--- a/src/test/ui/parser/issues/issue-14303-fn-def.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-fn foo<'a, T, 'b>(x: &'a T) {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
-
-fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-fn-def.stderr b/src/test/ui/parser/issues/issue-14303-fn-def.stderr
deleted file mode 100644
index bacc92296..000000000
--- a/src/test/ui/parser/issues/issue-14303-fn-def.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
- --> $DIR/issue-14303-fn-def.rs:1:15
- |
-LL | fn foo<'a, T, 'b>(x: &'a T) {}
- | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/issues/issue-14303-impl.rs b/src/test/ui/parser/issues/issue-14303-impl.rs
deleted file mode 100644
index 4dc2c6660..000000000
--- a/src/test/ui/parser/issues/issue-14303-impl.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-struct X<T>(T);
-
-impl<'a, T, 'b> X<T> {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
-
-fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-impl.stderr b/src/test/ui/parser/issues/issue-14303-impl.stderr
deleted file mode 100644
index d6be02f70..000000000
--- a/src/test/ui/parser/issues/issue-14303-impl.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
- --> $DIR/issue-14303-impl.rs:3:13
- |
-LL | impl<'a, T, 'b> X<T> {}
- | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/issues/issue-14303-path.rs b/src/test/ui/parser/issues/issue-14303-path.rs
deleted file mode 100644
index 89ef914ab..000000000
--- a/src/test/ui/parser/issues/issue-14303-path.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-mod foo {
- pub struct X<'a, 'b, 'c, T> {
- a: &'a str,
- b: &'b str,
- c: &'c str,
- t: T,
- }
-}
-
-fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
-//~^ ERROR type provided when a lifetime was expected
-
-fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-path.stderr b/src/test/ui/parser/issues/issue-14303-path.stderr
deleted file mode 100644
index 841e63ecb..000000000
--- a/src/test/ui/parser/issues/issue-14303-path.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0747]: type provided when a lifetime was expected
- --> $DIR/issue-14303-path.rs:10:37
- |
-LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
- | ^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/parser/issues/issue-14303-struct.rs b/src/test/ui/parser/issues/issue-14303-struct.rs
deleted file mode 100644
index 0bd10b4d0..000000000
--- a/src/test/ui/parser/issues/issue-14303-struct.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-struct X<'a, T, 'b> {
-//~^ ERROR lifetime parameters must be declared prior to type parameters
- x: &'a &'b T
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-struct.stderr b/src/test/ui/parser/issues/issue-14303-struct.stderr
deleted file mode 100644
index fa62a39f2..000000000
--- a/src/test/ui/parser/issues/issue-14303-struct.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
- --> $DIR/issue-14303-struct.rs:1:17
- |
-LL | struct X<'a, T, 'b> {
- | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/issues/issue-14303-trait.rs b/src/test/ui/parser/issues/issue-14303-trait.rs
deleted file mode 100644
index f253de92d..000000000
--- a/src/test/ui/parser/issues/issue-14303-trait.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-trait Foo<'a, T, 'b> {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
-
-fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-trait.stderr b/src/test/ui/parser/issues/issue-14303-trait.stderr
deleted file mode 100644
index 75cd67a9d..000000000
--- a/src/test/ui/parser/issues/issue-14303-trait.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
- --> $DIR/issue-14303-trait.rs:1:18
- |
-LL | trait Foo<'a, T, 'b> {}
- | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/issues/issue-14303.rs b/src/test/ui/parser/issues/issue-14303.rs
new file mode 100644
index 000000000..82850d77a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303.rs
@@ -0,0 +1,33 @@
+enum Enum<'a, T, 'b> {
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
+ A(&'a &'b T)
+}
+
+struct Struct<'a, T, 'b> {
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
+ x: &'a &'b T
+}
+
+trait Trait<'a, T, 'b> {}
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
+
+fn foo<'a, T, 'b>(x: &'a T) {}
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
+
+struct Y<T>(T);
+impl<'a, T, 'b> Y<T> {}
+//~^ ERROR lifetime parameters must be declared prior to type and const parameters
+
+mod bar {
+ pub struct X<'a, 'b, 'c, T> {
+ a: &'a str,
+ b: &'b str,
+ c: &'c str,
+ t: T,
+ }
+}
+
+fn bar<'a, 'b, 'c, T>(x: bar::X<'a, T, 'b, 'c>) {}
+//~^ ERROR type provided when a lifetime was expected
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303.stderr b/src/test/ui/parser/issues/issue-14303.stderr
new file mode 100644
index 000000000..f121107c0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303.stderr
@@ -0,0 +1,39 @@
+error: lifetime parameters must be declared prior to type and const parameters
+ --> $DIR/issue-14303.rs:1:18
+ |
+LL | enum Enum<'a, T, 'b> {
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: lifetime parameters must be declared prior to type and const parameters
+ --> $DIR/issue-14303.rs:6:22
+ |
+LL | struct Struct<'a, T, 'b> {
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: lifetime parameters must be declared prior to type and const parameters
+ --> $DIR/issue-14303.rs:11:20
+ |
+LL | trait Trait<'a, T, 'b> {}
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: lifetime parameters must be declared prior to type and const parameters
+ --> $DIR/issue-14303.rs:14:15
+ |
+LL | fn foo<'a, T, 'b>(x: &'a T) {}
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: lifetime parameters must be declared prior to type and const parameters
+ --> $DIR/issue-14303.rs:18:13
+ |
+LL | impl<'a, T, 'b> Y<T> {}
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error[E0747]: type provided when a lifetime was expected
+ --> $DIR/issue-14303.rs:30:37
+ |
+LL | fn bar<'a, 'b, 'c, T>(x: bar::X<'a, T, 'b, 'c>) {}
+ | ^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
index 85c9fe409..a00f37ed6 100644
--- a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
+++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
@@ -107,10 +107,10 @@ LL | V = [Vec::new; { [0].len() ].len() as isize,
| closing delimiter possibly meant for this
error[E0282]: type annotations needed
- --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:26
|
LL | V = [Vec::new; { [].len() ].len() as isize,
- | ^^^ cannot infer type for type parameter `T`
+ | ^^ cannot infer type for type parameter `T`
error[E0282]: type annotations needed
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14
diff --git a/src/test/ui/parser/issues/issue-89574.stderr b/src/test/ui/parser/issues/issue-89574.stderr
index cbee3d351..fb1312c78 100644
--- a/src/test/ui/parser/issues/issue-89574.stderr
+++ b/src/test/ui/parser/issues/issue-89574.stderr
@@ -1,8 +1,8 @@
error: missing type for `const` item
- --> $DIR/issue-89574.rs:2:11
+ --> $DIR/issue-89574.rs:2:22
|
LL | const EMPTY_ARRAY = [];
- | ^^^^^^^^^^^ help: provide a type for the item: `EMPTY_ARRAY: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to previous error
diff --git a/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr b/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr
index c340e958e..5365b0a1f 100644
--- a/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr
+++ b/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr
@@ -15,10 +15,10 @@ LL | const B;
| help: provide a definition for the constant: `= <expr>;`
error: missing type for `const` item
- --> $DIR/item-free-const-no-body-semantic-fail.rs:6:7
+ --> $DIR/item-free-const-no-body-semantic-fail.rs:6:8
|
LL | const B;
- | ^ help: provide a type for the item: `B: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr b/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr
index 4d542b798..1b61e4305 100644
--- a/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr
+++ b/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr
@@ -31,16 +31,16 @@ LL | static mut D;
| help: provide a definition for the static: `= <expr>;`
error: missing type for `static` item
- --> $DIR/item-free-static-no-body-semantic-fail.rs:6:8
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:6:9
|
LL | static B;
- | ^ help: provide a type for the item: `B: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: missing type for `static mut` item
- --> $DIR/item-free-static-no-body-semantic-fail.rs:10:12
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:10:13
|
LL | static mut D;
- | ^ help: provide a type for the item: `D: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to 6 previous errors
diff --git a/src/test/ui/parser/kw-in-trait-bounds.rs b/src/test/ui/parser/kw-in-trait-bounds.rs
new file mode 100644
index 000000000..fa037e593
--- /dev/null
+++ b/src/test/ui/parser/kw-in-trait-bounds.rs
@@ -0,0 +1,47 @@
+// edition:2018
+
+fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+//~^ ERROR expected identifier, found keyword `fn`
+//~| ERROR expected identifier, found keyword `fn`
+//~| ERROR expected identifier, found keyword `fn`
+//~| ERROR cannot find trait `r#fn` in this scope
+//~| ERROR cannot find trait `r#fn` in this scope
+//~| ERROR cannot find trait `r#fn` in this scope
+//~| HELP a trait with a similar name exists
+//~| HELP a trait with a similar name exists
+//~| HELP a trait with a similar name exists
+//~| HELP escape `fn` to use it as an identifier
+//~| HELP escape `fn` to use it as an identifier
+//~| HELP escape `fn` to use it as an identifier
+where
+G: fn(),
+ //~^ ERROR expected identifier, found keyword `fn`
+ //~| ERROR cannot find trait `r#fn` in this scope
+ //~| HELP a trait with a similar name exists
+ //~| HELP escape `fn` to use it as an identifier
+{}
+
+fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+//~^ ERROR expected identifier, found keyword `struct`
+//~| ERROR expected identifier, found keyword `struct`
+//~| ERROR expected identifier, found keyword `struct`
+//~| ERROR cannot find trait `r#struct` in this scope
+//~| ERROR cannot find trait `r#struct` in this scope
+//~| ERROR cannot find trait `r#struct` in this scope
+//~| HELP a trait with a similar name exists
+//~| HELP a trait with a similar name exists
+//~| HELP a trait with a similar name exists
+//~| HELP escape `struct` to use it as an identifier
+//~| HELP escape `struct` to use it as an identifier
+//~| HELP escape `struct` to use it as an identifier
+where
+ B: struct,
+ //~^ ERROR expected identifier, found keyword `struct`
+ //~| ERROR cannot find trait `r#struct` in this scope
+ //~| HELP a trait with a similar name exists
+ //~| HELP escape `struct` to use it as an identifier
+{}
+
+trait Struct {}
+
+fn main() {}
diff --git a/src/test/ui/parser/kw-in-trait-bounds.stderr b/src/test/ui/parser/kw-in-trait-bounds.stderr
new file mode 100644
index 000000000..28196c7ce
--- /dev/null
+++ b/src/test/ui/parser/kw-in-trait-bounds.stderr
@@ -0,0 +1,171 @@
+error: expected identifier, found keyword `fn`
+ --> $DIR/kw-in-trait-bounds.rs:3:10
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+ | ^^ expected identifier, found keyword
+ |
+help: escape `fn` to use it as an identifier
+ |
+LL | fn _f<F: r#fn(), G>(_: impl fn(), _: &dyn fn())
+ | ++
+
+error: expected identifier, found keyword `fn`
+ --> $DIR/kw-in-trait-bounds.rs:3:27
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+ | ^^ expected identifier, found keyword
+ |
+help: escape `fn` to use it as an identifier
+ |
+LL | fn _f<F: fn(), G>(_: impl r#fn(), _: &dyn fn())
+ | ++
+
+error: expected identifier, found keyword `fn`
+ --> $DIR/kw-in-trait-bounds.rs:3:41
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+ | ^^ expected identifier, found keyword
+ |
+help: escape `fn` to use it as an identifier
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn r#fn())
+ | ++
+
+error: expected identifier, found keyword `fn`
+ --> $DIR/kw-in-trait-bounds.rs:17:4
+ |
+LL | G: fn(),
+ | ^^ expected identifier, found keyword
+ |
+help: escape `fn` to use it as an identifier
+ |
+LL | G: r#fn(),
+ | ++
+
+error: expected identifier, found keyword `struct`
+ --> $DIR/kw-in-trait-bounds.rs:24:10
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `struct` to use it as an identifier
+ |
+LL | fn _g<A: r#struct, B>(_: impl struct, _: &dyn struct)
+ | ++
+
+error: expected identifier, found keyword `struct`
+ --> $DIR/kw-in-trait-bounds.rs:24:29
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `struct` to use it as an identifier
+ |
+LL | fn _g<A: struct, B>(_: impl r#struct, _: &dyn struct)
+ | ++
+
+error: expected identifier, found keyword `struct`
+ --> $DIR/kw-in-trait-bounds.rs:24:45
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `struct` to use it as an identifier
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn r#struct)
+ | ++
+
+error: expected identifier, found keyword `struct`
+ --> $DIR/kw-in-trait-bounds.rs:38:8
+ |
+LL | B: struct,
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `struct` to use it as an identifier
+ |
+LL | B: r#struct,
+ | ++
+
+error[E0405]: cannot find trait `r#fn` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:3:10
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+ | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+ |
+ ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args>: FnMut<Args> {
+ | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#fn` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:17:4
+ |
+LL | G: fn(),
+ | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+ |
+ ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args>: FnMut<Args> {
+ | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#fn` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:3:27
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+ | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+ |
+ ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args>: FnMut<Args> {
+ | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#fn` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:3:41
+ |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+ | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+ |
+ ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args>: FnMut<Args> {
+ | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:24:10
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+ | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+ | ------------ similarly named trait `Struct` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:38:8
+ |
+LL | B: struct,
+ | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+ | ------------ similarly named trait `Struct` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:24:29
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+ | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+ | ------------ similarly named trait `Struct` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+ --> $DIR/kw-in-trait-bounds.rs:24:45
+ |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+ | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+ | ------------ similarly named trait `Struct` defined here
+
+error: aborting due to 16 previous errors
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/parser/labeled-no-colon-expr.rs b/src/test/ui/parser/labeled-no-colon-expr.rs
index db9ef52c1..d9ebd7473 100644
--- a/src/test/ui/parser/labeled-no-colon-expr.rs
+++ b/src/test/ui/parser/labeled-no-colon-expr.rs
@@ -1,5 +1,3 @@
-#![feature(label_break_value)]
-
fn main() {
'l0 while false {} //~ ERROR labeled expression must be followed by `:`
'l1 for _ in 0..1 {} //~ ERROR labeled expression must be followed by `:`
diff --git a/src/test/ui/parser/labeled-no-colon-expr.stderr b/src/test/ui/parser/labeled-no-colon-expr.stderr
index a258bd3cc..62288fe15 100644
--- a/src/test/ui/parser/labeled-no-colon-expr.stderr
+++ b/src/test/ui/parser/labeled-no-colon-expr.stderr
@@ -1,5 +1,5 @@
error: labeled expression must be followed by `:`
- --> $DIR/labeled-no-colon-expr.rs:4:5
+ --> $DIR/labeled-no-colon-expr.rs:2:5
|
LL | 'l0 while false {}
| ----^^^^^^^^^^^^^^
@@ -10,7 +10,7 @@ LL | 'l0 while false {}
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
error: labeled expression must be followed by `:`
- --> $DIR/labeled-no-colon-expr.rs:5:5
+ --> $DIR/labeled-no-colon-expr.rs:3:5
|
LL | 'l1 for _ in 0..1 {}
| ----^^^^^^^^^^^^^^^^
@@ -21,7 +21,7 @@ LL | 'l1 for _ in 0..1 {}
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
error: labeled expression must be followed by `:`
- --> $DIR/labeled-no-colon-expr.rs:6:5
+ --> $DIR/labeled-no-colon-expr.rs:4:5
|
LL | 'l2 loop {}
| ----^^^^^^^
@@ -32,7 +32,7 @@ LL | 'l2 loop {}
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
error: labeled expression must be followed by `:`
- --> $DIR/labeled-no-colon-expr.rs:7:5
+ --> $DIR/labeled-no-colon-expr.rs:5:5
|
LL | 'l3 {}
| ----^^
@@ -43,7 +43,7 @@ LL | 'l3 {}
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/labeled-no-colon-expr.rs:8:9
+ --> $DIR/labeled-no-colon-expr.rs:6:9
|
LL | 'l4 0;
| ^ expected `while`, `for`, `loop` or `{` after a label
@@ -55,7 +55,7 @@ LL + 0;
|
error: labeled expression must be followed by `:`
- --> $DIR/labeled-no-colon-expr.rs:8:9
+ --> $DIR/labeled-no-colon-expr.rs:6:9
|
LL | 'l4 0;
| ----^
@@ -66,7 +66,7 @@ LL | 'l4 0;
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
error: cannot use a `block` macro fragment here
- --> $DIR/labeled-no-colon-expr.rs:13:17
+ --> $DIR/labeled-no-colon-expr.rs:11:17
|
LL | 'l5 $b;
| ----^^
@@ -79,7 +79,7 @@ LL | m!({});
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: labeled expression must be followed by `:`
- --> $DIR/labeled-no-colon-expr.rs:16:8
+ --> $DIR/labeled-no-colon-expr.rs:14:8
|
LL | 'l5 $b;
| ---- help: add `:` after the label
diff --git a/src/test/ui/parser/public-instead-of-pub-1.fixed b/src/test/ui/parser/public-instead-of-pub-1.fixed
new file mode 100644
index 000000000..a4fa68ba5
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-1.fixed
@@ -0,0 +1,11 @@
+// Checks what happens when `public` is used instead of the correct, `pub`
+// run-rustfix
+
+pub enum Test {
+ //~^ ERROR expected one of `!` or `::`, found keyword `enum`
+ //~^^ HELP write `pub` instead of `public` to make the item public
+ A,
+ B,
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/public-instead-of-pub-1.rs b/src/test/ui/parser/public-instead-of-pub-1.rs
new file mode 100644
index 000000000..43565c9b1
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-1.rs
@@ -0,0 +1,11 @@
+// Checks what happens when `public` is used instead of the correct, `pub`
+// run-rustfix
+
+public enum Test {
+ //~^ ERROR expected one of `!` or `::`, found keyword `enum`
+ //~^^ HELP write `pub` instead of `public` to make the item public
+ A,
+ B,
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/public-instead-of-pub-1.stderr b/src/test/ui/parser/public-instead-of-pub-1.stderr
new file mode 100644
index 000000000..795a5bcf5
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-1.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found keyword `enum`
+ --> $DIR/public-instead-of-pub-1.rs:4:8
+ |
+LL | public enum Test {
+ | ^^^^ expected one of `!` or `::`
+ |
+help: write `pub` instead of `public` to make the item public
+ |
+LL | pub enum Test {
+ | ~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/public-instead-of-pub-2.rs b/src/test/ui/parser/public-instead-of-pub-2.rs
new file mode 100644
index 000000000..8a43c361e
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-2.rs
@@ -0,0 +1,7 @@
+// Checks what happens when `public` is used instead of the correct, `pub`
+// Won't give help message for this case
+
+public let x = 1;
+//~^ ERROR expected one of `!` or `::`, found keyword `let`
+
+fn main() { }
diff --git a/src/test/ui/parser/public-instead-of-pub-2.stderr b/src/test/ui/parser/public-instead-of-pub-2.stderr
new file mode 100644
index 000000000..efe225656
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-2.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found keyword `let`
+ --> $DIR/public-instead-of-pub-2.rs:4:8
+ |
+LL | public let x = 1;
+ | ^^^ expected one of `!` or `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/public-instead-of-pub-3.fixed b/src/test/ui/parser/public-instead-of-pub-3.fixed
new file mode 100644
index 000000000..14f620f41
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-3.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+mod test {
+ pub const X: i32 = 123;
+ //~^ ERROR expected one of `!` or `::`, found keyword `const`
+}
+
+fn main() {
+ println!("{}", test::X);
+}
diff --git a/src/test/ui/parser/public-instead-of-pub-3.rs b/src/test/ui/parser/public-instead-of-pub-3.rs
new file mode 100644
index 000000000..ee27cb1a1
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-3.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+mod test {
+ public const X: i32 = 123;
+ //~^ ERROR expected one of `!` or `::`, found keyword `const`
+}
+
+fn main() {
+ println!("{}", test::X);
+}
diff --git a/src/test/ui/parser/public-instead-of-pub-3.stderr b/src/test/ui/parser/public-instead-of-pub-3.stderr
new file mode 100644
index 000000000..72efae08d
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub-3.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found keyword `const`
+ --> $DIR/public-instead-of-pub-3.rs:3:12
+ |
+LL | public const X: i32 = 123;
+ | ^^^^^ expected one of `!` or `::`
+ |
+help: write `pub` instead of `public` to make the item public
+ |
+LL | pub const X: i32 = 123;
+ | ~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-field-semi.rs b/src/test/ui/parser/recover-field-semi.rs
new file mode 100644
index 000000000..b70357886
--- /dev/null
+++ b/src/test/ui/parser/recover-field-semi.rs
@@ -0,0 +1,16 @@
+struct Foo {
+ foo: i32;
+ //~^ ERROR struct fields are separated by `,`
+}
+
+union Bar { //~ ERROR
+ foo: i32;
+ //~^ ERROR union fields are separated by `,`
+}
+
+enum Baz {
+ Qux { foo: i32; }
+ //~^ ERROR struct fields are separated by `,`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-field-semi.stderr b/src/test/ui/parser/recover-field-semi.stderr
new file mode 100644
index 000000000..657366db9
--- /dev/null
+++ b/src/test/ui/parser/recover-field-semi.stderr
@@ -0,0 +1,29 @@
+error: struct fields are separated by `,`
+ --> $DIR/recover-field-semi.rs:2:13
+ |
+LL | foo: i32;
+ | ^ help: replace `;` with `,`
+
+error: union fields are separated by `,`
+ --> $DIR/recover-field-semi.rs:7:13
+ |
+LL | foo: i32;
+ | ^ help: replace `;` with `,`
+
+error: struct fields are separated by `,`
+ --> $DIR/recover-field-semi.rs:12:19
+ |
+LL | Qux { foo: i32; }
+ | ^ help: replace `;` with `,`
+
+error: unions cannot have zero fields
+ --> $DIR/recover-field-semi.rs:6:1
+ |
+LL | / union Bar {
+LL | | foo: i32;
+LL | |
+LL | | }
+ | |_^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.fixed b/src/test/ui/parser/recover-labeled-non-block-expr.fixed
index fe546a719..c2e76444d 100644
--- a/src/test/ui/parser/recover-labeled-non-block-expr.fixed
+++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed
@@ -1,5 +1,4 @@
// run-rustfix
-#![feature(label_break_value)]
fn main() {
let _ = 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.rs b/src/test/ui/parser/recover-labeled-non-block-expr.rs
index 35862e2ee..fc11c646a 100644
--- a/src/test/ui/parser/recover-labeled-non-block-expr.rs
+++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs
@@ -1,5 +1,4 @@
// run-rustfix
-#![feature(label_break_value)]
fn main() {
let _ = 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.stderr b/src/test/ui/parser/recover-labeled-non-block-expr.stderr
index 04fc1203e..d66ce6950 100644
--- a/src/test/ui/parser/recover-labeled-non-block-expr.stderr
+++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr
@@ -1,5 +1,5 @@
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/recover-labeled-non-block-expr.rs:4:21
+ --> $DIR/recover-labeled-non-block-expr.rs:3:21
|
LL | let _ = 'label: 1 + 1;
| ^ expected `while`, `for`, `loop` or `{` after a label
@@ -11,7 +11,7 @@ LL + let _ = 1 + 1;
|
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/recover-labeled-non-block-expr.rs:6:13
+ --> $DIR/recover-labeled-non-block-expr.rs:5:13
|
LL | 'label: match () { () => {}, };
| ^^^^^ expected `while`, `for`, `loop` or `{` after a label
@@ -23,7 +23,7 @@ LL + match () { () => {}, };
|
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/recover-labeled-non-block-expr.rs:7:13
+ --> $DIR/recover-labeled-non-block-expr.rs:6:13
|
LL | 'label: match () { () => break 'label, };
| ^^^^^ expected `while`, `for`, `loop` or `{` after a label
@@ -34,7 +34,7 @@ LL | 'label: { match () { () => break 'label, } };
| + +
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/recover-labeled-non-block-expr.rs:9:13
+ --> $DIR/recover-labeled-non-block-expr.rs:8:13
|
LL | 'label: match () { () => 'lp: loop { break 'lp 0 }, };
| ^^^^^ expected `while`, `for`, `loop` or `{` after a label
@@ -45,7 +45,7 @@ LL | 'label: { match () { () => 'lp: loop { break 'lp 0 }, } };
| + +
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/recover-labeled-non-block-expr.rs:12:22
+ --> $DIR/recover-labeled-non-block-expr.rs:11:22
|
LL | let _i = 'label: match x {
| ^^^^^ expected `while`, `for`, `loop` or `{` after a label
@@ -60,7 +60,7 @@ LL ~ } };
|
error: expected `while`, `for`, `loop` or `{` after a label
- --> $DIR/recover-labeled-non-block-expr.rs:26:24
+ --> $DIR/recover-labeled-non-block-expr.rs:25:24
|
LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other });
| ^ expected `while`, `for`, `loop` or `{` after a label
diff --git a/src/test/ui/parser/recover-missing-semi-before-item.fixed b/src/test/ui/parser/recover-missing-semi-before-item.fixed
new file mode 100644
index 000000000..0be17e69e
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi-before-item.fixed
@@ -0,0 +1,61 @@
+// run-rustfix
+
+#![allow(unused_variables, dead_code)]
+
+fn for_struct() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `struct`
+ struct Foo;
+}
+
+fn for_union() {
+ let foo = 3; //~ ERROR expected `;`, found `union`
+ union Foo {
+ foo: usize,
+ }
+}
+
+fn for_enum() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `enum`
+ enum Foo {
+ Bar,
+ }
+}
+
+fn for_fn() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `fn`
+ fn foo() {}
+}
+
+fn for_extern() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `extern`
+ extern fn foo() {}
+}
+
+fn for_impl() {
+ struct Foo;
+ let foo = 3; //~ ERROR expected `;`, found keyword `impl`
+ impl Foo {}
+}
+
+fn for_use() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `pub`
+ pub use bar::Bar;
+}
+
+fn for_mod() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `mod`
+ mod foo {}
+}
+
+fn for_type() {
+ let foo = 3; //~ ERROR expected `;`, found keyword `type`
+ type Foo = usize;
+}
+
+mod bar {
+ pub struct Bar;
+}
+
+const X: i32 = 123; //~ ERROR expected `;`, found keyword `fn`
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-missing-semi-before-item.rs b/src/test/ui/parser/recover-missing-semi-before-item.rs
new file mode 100644
index 000000000..867b7b749
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi-before-item.rs
@@ -0,0 +1,61 @@
+// run-rustfix
+
+#![allow(unused_variables, dead_code)]
+
+fn for_struct() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `struct`
+ struct Foo;
+}
+
+fn for_union() {
+ let foo = 3 //~ ERROR expected `;`, found `union`
+ union Foo {
+ foo: usize,
+ }
+}
+
+fn for_enum() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `enum`
+ enum Foo {
+ Bar,
+ }
+}
+
+fn for_fn() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `fn`
+ fn foo() {}
+}
+
+fn for_extern() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `extern`
+ extern fn foo() {}
+}
+
+fn for_impl() {
+ struct Foo;
+ let foo = 3 //~ ERROR expected `;`, found keyword `impl`
+ impl Foo {}
+}
+
+fn for_use() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `pub`
+ pub use bar::Bar;
+}
+
+fn for_mod() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `mod`
+ mod foo {}
+}
+
+fn for_type() {
+ let foo = 3 //~ ERROR expected `;`, found keyword `type`
+ type Foo = usize;
+}
+
+mod bar {
+ pub struct Bar;
+}
+
+const X: i32 = 123 //~ ERROR expected `;`, found keyword `fn`
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-missing-semi-before-item.stderr b/src/test/ui/parser/recover-missing-semi-before-item.stderr
new file mode 100644
index 000000000..61c43f2f1
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi-before-item.stderr
@@ -0,0 +1,83 @@
+error: expected `;`, found keyword `struct`
+ --> $DIR/recover-missing-semi-before-item.rs:6:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | struct Foo;
+ | ------ unexpected token
+
+error: expected `;`, found `union`
+ --> $DIR/recover-missing-semi-before-item.rs:11:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | union Foo {
+ | ----- unexpected token
+
+error: expected `;`, found keyword `enum`
+ --> $DIR/recover-missing-semi-before-item.rs:18:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | enum Foo {
+ | ---- unexpected token
+
+error: expected `;`, found keyword `fn`
+ --> $DIR/recover-missing-semi-before-item.rs:25:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | fn foo() {}
+ | -- unexpected token
+
+error: expected `;`, found keyword `extern`
+ --> $DIR/recover-missing-semi-before-item.rs:30:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | extern fn foo() {}
+ | ------ unexpected token
+
+error: expected `;`, found keyword `impl`
+ --> $DIR/recover-missing-semi-before-item.rs:36:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | impl Foo {}
+ | ---- unexpected token
+
+error: expected `;`, found keyword `pub`
+ --> $DIR/recover-missing-semi-before-item.rs:41:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | pub use bar::Bar;
+ | --- unexpected token
+
+error: expected `;`, found keyword `mod`
+ --> $DIR/recover-missing-semi-before-item.rs:46:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | mod foo {}
+ | --- unexpected token
+
+error: expected `;`, found keyword `type`
+ --> $DIR/recover-missing-semi-before-item.rs:51:16
+ |
+LL | let foo = 3
+ | ^ help: add `;` here
+LL | type Foo = usize;
+ | ---- unexpected token
+
+error: expected `;`, found keyword `fn`
+ --> $DIR/recover-missing-semi-before-item.rs:59:19
+ |
+LL | const X: i32 = 123
+ | ^ help: add `;` here
+LL |
+LL | fn main() {}
+ | -- unexpected token
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.rs b/src/test/ui/parser/removed-syntax-field-semicolon.rs
index ac28e21ae..808f2a5cc 100644
--- a/src/test/ui/parser/removed-syntax-field-semicolon.rs
+++ b/src/test/ui/parser/removed-syntax-field-semicolon.rs
@@ -1,6 +1,6 @@
struct S {
bar: ();
- //~^ ERROR expected `,`, or `}`, found `;`
+ //~^ ERROR struct fields are separated by `,`
}
fn main() {}
diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.stderr b/src/test/ui/parser/removed-syntax-field-semicolon.stderr
index fbefeb26a..e4f75f672 100644
--- a/src/test/ui/parser/removed-syntax-field-semicolon.stderr
+++ b/src/test/ui/parser/removed-syntax-field-semicolon.stderr
@@ -1,8 +1,8 @@
-error: expected `,`, or `}`, found `;`
+error: struct fields are separated by `,`
--> $DIR/removed-syntax-field-semicolon.rs:2:12
|
LL | bar: ();
- | ^
+ | ^ help: replace `;` with `,`
error: aborting due to previous error
diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr
index 04e34dc16..52e065894 100644
--- a/src/test/ui/parser/removed-syntax-static-fn.stderr
+++ b/src/test/ui/parser/removed-syntax-static-fn.stderr
@@ -16,10 +16,10 @@ LL | }
| - the item list ends here
error: missing type for `static` item
- --> $DIR/removed-syntax-static-fn.rs:4:12
+ --> $DIR/removed-syntax-static-fn.rs:4:14
|
LL | static fn f() {}
- | ^^ help: provide a type for the item: `r#fn: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/parser/struct-filed-with-attr.fixed b/src/test/ui/parser/struct-filed-with-attr.fixed
new file mode 100644
index 000000000..a799ec8ca
--- /dev/null
+++ b/src/test/ui/parser/struct-filed-with-attr.fixed
@@ -0,0 +1,18 @@
+// Issue: 100461, Try to give a helpful diagnostic even when the next struct field has an attribute.
+// run-rustfix
+
+struct Feelings {
+ owo: bool,
+ //~^ ERROR expected `,`, or `}`, found `#`
+ #[allow(unused)]
+ uwu: bool,
+}
+
+impl Feelings {
+ #[allow(unused)]
+ fn hmm(&self) -> bool {
+ self.owo
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/struct-filed-with-attr.rs b/src/test/ui/parser/struct-filed-with-attr.rs
new file mode 100644
index 000000000..bfc78e15b
--- /dev/null
+++ b/src/test/ui/parser/struct-filed-with-attr.rs
@@ -0,0 +1,18 @@
+// Issue: 100461, Try to give a helpful diagnostic even when the next struct field has an attribute.
+// run-rustfix
+
+struct Feelings {
+ owo: bool
+ //~^ ERROR expected `,`, or `}`, found `#`
+ #[allow(unused)]
+ uwu: bool,
+}
+
+impl Feelings {
+ #[allow(unused)]
+ fn hmm(&self) -> bool {
+ self.owo
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/struct-filed-with-attr.stderr b/src/test/ui/parser/struct-filed-with-attr.stderr
new file mode 100644
index 000000000..c2cd7e82e
--- /dev/null
+++ b/src/test/ui/parser/struct-filed-with-attr.stderr
@@ -0,0 +1,8 @@
+error: expected `,`, or `}`, found `#`
+ --> $DIR/struct-filed-with-attr.rs:5:14
+ |
+LL | owo: bool
+ | ^ help: try adding a comma: `,`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr
index 4b191710c..1c91eba68 100644
--- a/src/test/ui/parser/struct-literal-in-for.stderr
+++ b/src/test/ui/parser/struct-literal-in-for.stderr
@@ -24,7 +24,7 @@ LL | | }.hi() {
| |__________^ `bool` is not an iterator
|
= help: the trait `Iterator` is not implemented for `bool`
- = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+ = note: required for `bool` to implement `IntoIterator`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/parser/suggest-assoc-const.fixed b/src/test/ui/parser/suggest-assoc-const.fixed
new file mode 100644
index 000000000..259f37b23
--- /dev/null
+++ b/src/test/ui/parser/suggest-assoc-const.fixed
@@ -0,0 +1,10 @@
+// Issue: 101797, Suggest associated const for incorrect use of let in traits
+// run-rustfix
+trait Trait {
+ const _X: i32;
+ //~^ ERROR non-item in item list
+}
+
+fn main() {
+
+}
diff --git a/src/test/ui/parser/suggest-assoc-const.rs b/src/test/ui/parser/suggest-assoc-const.rs
new file mode 100644
index 000000000..c7be712ec
--- /dev/null
+++ b/src/test/ui/parser/suggest-assoc-const.rs
@@ -0,0 +1,10 @@
+// Issue: 101797, Suggest associated const for incorrect use of let in traits
+// run-rustfix
+trait Trait {
+ let _X: i32;
+ //~^ ERROR non-item in item list
+}
+
+fn main() {
+
+}
diff --git a/src/test/ui/parser/suggest-assoc-const.stderr b/src/test/ui/parser/suggest-assoc-const.stderr
new file mode 100644
index 000000000..2ddfa07c5
--- /dev/null
+++ b/src/test/ui/parser/suggest-assoc-const.stderr
@@ -0,0 +1,8 @@
+error: non-item in item list
+ --> $DIR/suggest-assoc-const.rs:4:5
+ |
+LL | let _X: i32;
+ | ^^^ help: consider using `const` instead of `let` for associated const: `const`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/suggest-const-for-global-var.rs b/src/test/ui/parser/suggest-const-for-global-var.rs
new file mode 100644
index 000000000..d6216cb7a
--- /dev/null
+++ b/src/test/ui/parser/suggest-const-for-global-var.rs
@@ -0,0 +1,6 @@
+let X: i32 = 12;
+//~^ ERROR expected item, found keyword `let`
+
+fn main() {
+ println!("{}", X);
+}
diff --git a/src/test/ui/parser/suggest-const-for-global-var.stderr b/src/test/ui/parser/suggest-const-for-global-var.stderr
new file mode 100644
index 000000000..94e44ec7f
--- /dev/null
+++ b/src/test/ui/parser/suggest-const-for-global-var.stderr
@@ -0,0 +1,8 @@
+error: expected item, found keyword `let`
+ --> $DIR/suggest-const-for-global-var.rs:1:1
+ |
+LL | let X: i32 = 12;
+ | ^^^ consider using `const` or `static` instead of `let` for global variables
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed
new file mode 100644
index 000000000..637047354
--- /dev/null
+++ b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+
+trait Foo {
+ fn bar() {} //~ ERROR non-item in item list
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs
new file mode 100644
index 000000000..4650b05e2
--- /dev/null
+++ b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs
@@ -0,0 +1,7 @@
+// run-rustfix
+
+trait Foo {
+ fn bar() {}; //~ ERROR non-item in item list
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr
new file mode 100644
index 000000000..396e0c130
--- /dev/null
+++ b/src/test/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr
@@ -0,0 +1,15 @@
+error: non-item in item list
+ --> $DIR/suggest-removing-semicolon-after-impl-trait-items.rs:4:16
+ |
+LL | trait Foo {
+ | - item list starts here
+LL | fn bar() {};
+ | ^
+ | |
+ | non-item starts here
+ | help: consider removing this semicolon
+LL | }
+ | - item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/suggest-semicolon-before-array.fixed b/src/test/ui/parser/suggest-semicolon-before-array.fixed
new file mode 100644
index 000000000..a06b58b27
--- /dev/null
+++ b/src/test/ui/parser/suggest-semicolon-before-array.fixed
@@ -0,0 +1,11 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn foo() {}
+
+fn bar() -> [u8; 2] {
+ foo();
+ [1, 3] //~ ERROR expected `;`, found `[`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-semicolon-before-array.rs b/src/test/ui/parser/suggest-semicolon-before-array.rs
new file mode 100644
index 000000000..f601ca2ae
--- /dev/null
+++ b/src/test/ui/parser/suggest-semicolon-before-array.rs
@@ -0,0 +1,11 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn foo() {}
+
+fn bar() -> [u8; 2] {
+ foo()
+ [1, 3] //~ ERROR expected `;`, found `[`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/suggest-semicolon-before-array.stderr b/src/test/ui/parser/suggest-semicolon-before-array.stderr
new file mode 100644
index 000000000..8a33321fb
--- /dev/null
+++ b/src/test/ui/parser/suggest-semicolon-before-array.stderr
@@ -0,0 +1,13 @@
+error: expected `;`, found `[`
+ --> $DIR/suggest-semicolon-before-array.rs:8:5
+ |
+LL | [1, 3]
+ | ^
+ |
+help: consider adding `;` here
+ |
+LL | foo();
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/trait-object-delimiters.rs b/src/test/ui/parser/trait-object-delimiters.rs
index b5258eebb..cc04ac052 100644
--- a/src/test/ui/parser/trait-object-delimiters.rs
+++ b/src/test/ui/parser/trait-object-delimiters.rs
@@ -6,7 +6,7 @@ fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
-//~^ ERROR expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
//~| ERROR at least one trait is required for an object type
fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<`
diff --git a/src/test/ui/parser/trait-object-delimiters.stderr b/src/test/ui/parser/trait-object-delimiters.stderr
index 6eb9c7238..99c451545 100644
--- a/src/test/ui/parser/trait-object-delimiters.stderr
+++ b/src/test/ui/parser/trait-object-delimiters.stderr
@@ -22,11 +22,11 @@ error: expected parameter name, found `{`
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
| ^ expected parameter name
-error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
--> $DIR/trait-object-delimiters.rs:8:17
|
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
- | -^ expected one of 9 possible tokens
+ | -^ expected one of 10 possible tokens
| |
| help: missing `,`
diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr
index 7ee965bd2..823f75bfa 100644
--- a/src/test/ui/parser/trait-object-trait-parens.stderr
+++ b/src/test/ui/parser/trait-object-trait-parens.stderr
@@ -27,9 +27,8 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
-LL + let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
- |
+LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+ | +++
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-trait-parens.rs:8:35
@@ -52,9 +51,8 @@ LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
-LL + let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
- |
+LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
+ | +++
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-trait-parens.rs:13:47
@@ -77,9 +75,8 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
-LL + let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
- |
+LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
+ | +++
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-trait-parens.rs:18:36
diff --git a/src/test/ui/parser/type-alias-where-fixable.fixed b/src/test/ui/parser/type-alias-where-fixable.fixed
index 41dd10676..2f47c0d91 100644
--- a/src/test/ui/parser/type-alias-where-fixable.fixed
+++ b/src/test/ui/parser/type-alias-where-fixable.fixed
@@ -1,8 +1,6 @@
// check-pass
// run-rustfix
-#![feature(generic_associated_types)]
-
trait Trait {
// Fine.
type Assoc where u32: Copy;
diff --git a/src/test/ui/parser/type-alias-where-fixable.rs b/src/test/ui/parser/type-alias-where-fixable.rs
index 562a530a7..b20aa9398 100644
--- a/src/test/ui/parser/type-alias-where-fixable.rs
+++ b/src/test/ui/parser/type-alias-where-fixable.rs
@@ -1,8 +1,6 @@
// check-pass
// run-rustfix
-#![feature(generic_associated_types)]
-
trait Trait {
// Fine.
type Assoc where u32: Copy;
diff --git a/src/test/ui/parser/type-alias-where-fixable.stderr b/src/test/ui/parser/type-alias-where-fixable.stderr
index abfeb62fc..2e516d5c4 100644
--- a/src/test/ui/parser/type-alias-where-fixable.stderr
+++ b/src/test/ui/parser/type-alias-where-fixable.stderr
@@ -1,5 +1,5 @@
warning: where clause not allowed here
- --> $DIR/type-alias-where-fixable.rs:15:16
+ --> $DIR/type-alias-where-fixable.rs:13:16
|
LL | type Assoc where u32: Copy = ();
| ^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL + type Assoc = () where u32: Copy;
|
warning: where clause not allowed here
- --> $DIR/type-alias-where-fixable.rs:18:17
+ --> $DIR/type-alias-where-fixable.rs:16:17
|
LL | type Assoc2 where u32: Copy = () where i32: Copy;
| ^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL + type Assoc2 = () where i32: Copy, u32: Copy;
|
warning: where clause not allowed here
- --> $DIR/type-alias-where-fixable.rs:26:17
+ --> $DIR/type-alias-where-fixable.rs:24:17
|
LL | type Assoc2 where u32: Copy, i32: Copy = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/parser/type-alias-where.rs b/src/test/ui/parser/type-alias-where.rs
index f6e7dfb7b..62e301cb4 100644
--- a/src/test/ui/parser/type-alias-where.rs
+++ b/src/test/ui/parser/type-alias-where.rs
@@ -1,7 +1,5 @@
// check-fail
-#![feature(generic_associated_types)]
-
// Fine, but lints as unused
type Foo where u32: Copy = ();
// Not fine.
diff --git a/src/test/ui/parser/type-alias-where.stderr b/src/test/ui/parser/type-alias-where.stderr
index 8789d2665..fb8381792 100644
--- a/src/test/ui/parser/type-alias-where.stderr
+++ b/src/test/ui/parser/type-alias-where.stderr
@@ -1,5 +1,5 @@
error: where clauses are not allowed after the type for type aliases
- --> $DIR/type-alias-where.rs:8:15
+ --> $DIR/type-alias-where.rs:6:15
|
LL | type Bar = () where u32: Copy;
| ^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | type Bar = () where u32: Copy;
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
error: where clauses are not allowed after the type for type aliases
- --> $DIR/type-alias-where.rs:10:15
+ --> $DIR/type-alias-where.rs:8:15
|
LL | type Baz = () where;
| ^^^^^
diff --git a/src/test/ui/parser/unnecessary-let.rs b/src/test/ui/parser/unnecessary-let.rs
new file mode 100644
index 000000000..627910962
--- /dev/null
+++ b/src/test/ui/parser/unnecessary-let.rs
@@ -0,0 +1,11 @@
+fn main() {
+ for let x of [1, 2, 3] {}
+ //~^ ERROR expected pattern, found `let`
+ //~| ERROR missing `in` in `for` loop
+
+ match 1 {
+ let 1 => {}
+ //~^ ERROR expected pattern, found `let`
+ _ => {}
+ }
+}
diff --git a/src/test/ui/parser/unnecessary-let.stderr b/src/test/ui/parser/unnecessary-let.stderr
new file mode 100644
index 000000000..952119cae
--- /dev/null
+++ b/src/test/ui/parser/unnecessary-let.stderr
@@ -0,0 +1,20 @@
+error: expected pattern, found `let`
+ --> $DIR/unnecessary-let.rs:2:9
+ |
+LL | for let x of [1, 2, 3] {}
+ | ^^^ help: remove the unnecessary `let` keyword
+
+error: missing `in` in `for` loop
+ --> $DIR/unnecessary-let.rs:2:15
+ |
+LL | for let x of [1, 2, 3] {}
+ | ^^ help: try using `in` here instead
+
+error: expected pattern, found `let`
+ --> $DIR/unnecessary-let.rs:7:9
+ |
+LL | let 1 => {}
+ | ^^^ help: remove the unnecessary `let` keyword
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
index 4249a74b3..fad84dda0 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
@@ -40,9 +40,8 @@ error[E0382]: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:14
|
LL | Some(ref _y @ _z) => {}
- | ^^^^^^^^^--
- | | |
- | | value moved here
+ | ^^^^^^ -- value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `X`, which does not implement the `Copy` trait
@@ -55,9 +54,8 @@ error[E0382]: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:26:14
|
LL | Some(ref mut _y @ _z) => {}
- | ^^^^^^^^^^^^^--
- | | |
- | | value moved here
+ | ^^^^^^^^^^ -- value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `X`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
index ee0885a01..a481ca468 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
@@ -2,9 +2,8 @@ error[E0382]: use of partially moved value
--> $DIR/bind-by-move-no-subbindings-fun-param.rs:7:6
|
LL | fn f(a @ A(u): A) -> Box<u8> {
- | ^^^^^^-^
- | | |
- | | value partially moved here
+ | ^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `Box<u8>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
index 8e00bf5c3..a227cc583 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
@@ -2,7 +2,7 @@ error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:11:9
|
LL | let a @ b = U;
- | ^^^^- - move occurs because value has type `U`, which does not implement the `Copy` trait
+ | ^ - - move occurs because value has type `U`, which does not implement the `Copy` trait
| | |
| | value moved here
| value used here after move
@@ -11,9 +11,8 @@ error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:13:9
|
LL | let a @ (b, c) = (U, U);
- | ^^^^^^^^-^
- | | |
- | | value partially moved here
+ | ^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -22,9 +21,8 @@ error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:15:9
|
LL | let a @ (b, c) = (u(), u());
- | ^^^^^^^^-^
- | | |
- | | value partially moved here
+ | ^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -35,9 +33,8 @@ error[E0382]: use of moved value
LL | match Ok(U) {
| ----- move occurs because value has type `Result<U, U>`, which does not implement the `Copy` trait
LL | a @ Ok(b) | a @ Err(b) => {}
- | -------^-
- | | |
- | | value used here after move
+ | - ^ value used here after move
+ | |
| value moved here
error[E0382]: use of moved value
@@ -46,18 +43,16 @@ error[E0382]: use of moved value
LL | match Ok(U) {
| ----- move occurs because value has type `Result<U, U>`, which does not implement the `Copy` trait
LL | a @ Ok(b) | a @ Err(b) => {}
- | --------^-
- | | |
- | | value used here after move
+ | - ^ value used here after move
+ | |
| value moved here
error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:25:9
|
LL | xs @ [a, .., b] => {}
- | ^^^^^^^^^^^^^-^
- | | |
- | | value partially moved here
+ | ^^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -66,9 +61,8 @@ error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:29:9
|
LL | xs @ [_, ys @ .., _] => {}
- | ^^^^^^^^^-------^^^^
- | | |
- | | value partially moved here
+ | ^^ -- value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -77,9 +71,8 @@ error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:22:12
|
LL | fn fun(a @ b: U) {}
- | ^^^^-
- | | |
- | | value moved here
+ | ^ - value moved here
+ | |
| value used here after move
| move occurs because value has type `U`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
index 4b2048855..002c7609f 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
@@ -74,9 +74,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-at-and-box.rs:31:9
|
LL | let ref a @ box b = Box::new(NC);
- | ^^^^^^^^^^^^-
- | | |
- | | value moved here
+ | ^^^^^ - value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `NC`, which does not implement the `Copy` trait
@@ -85,9 +84,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-at-and-box.rs:38:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
- | ^^^^^^^^^^^^---------
- | | |
- | | mutable borrow occurs here
+ | ^^^^^ --------- mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | *b = NC;
@@ -97,9 +95,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-at-and-box.rs:42:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
- | ^^^^^^^^^^^^---------
- | | |
- | | mutable borrow occurs here
+ | ^^^^^ --------- mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | *b = NC;
@@ -109,9 +106,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu
--> $DIR/borrowck-pat-at-and-box.rs:48:9
|
LL | let ref mut a @ box ref b = Box::new(NC);
- | ^^^^^^^^^^^^^^^^-----
- | | |
- | | immutable borrow occurs here
+ | ^^^^^^^^^ ----- immutable borrow occurs here
+ | |
| mutable borrow occurs here
...
LL | drop(b);
@@ -121,9 +117,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu
--> $DIR/borrowck-pat-at-and-box.rs:62:9
|
LL | ref mut a @ box ref b => {
- | ^^^^^^^^^^^^^^^^-----
- | | |
- | | immutable borrow occurs here
+ | ^^^^^^^^^ ----- immutable borrow occurs here
+ | |
| mutable borrow occurs here
...
LL | drop(b);
@@ -133,9 +128,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu
--> $DIR/borrowck-pat-at-and-box.rs:54:11
|
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
- | ^^^^^^^^^^^^^^^^-----
- | | |
- | | immutable borrow occurs here
+ | ^^^^^^^^^ ----- immutable borrow occurs here
+ | |
| mutable borrow occurs here
...
LL | drop(b);
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
index bc2c1625f..a9e66de08 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
@@ -262,9 +262,8 @@ error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
- | ^^^^^^^^^^^^^^^^^^^^^^^^---------^
- | | |
- | | value partially moved here
+ | ^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -273,9 +272,8 @@ error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9
|
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
- | ^^^^^^^^^^^^^^^^^^^^^^^^---------^
- | | |
- | | value partially moved here
+ | ^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -286,10 +284,7 @@ error[E0382]: use of moved value
LL | match Some((U, U)) {
| ------------ move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
- | -----------------------------^^^^^^^^^--
- | | |
- | | value used here after move
- | value moved here
+ | - value moved here ^ value used here after move
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:30
@@ -297,9 +292,8 @@ error[E0382]: borrow of moved value
LL | match Some([U, U]) {
| ------------ move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
LL | mut a @ Some([ref b, ref mut c]) => {}
- | ---------------------^^^^^^^^^--
- | | |
- | | value borrowed here after move
+ | ----- ^^^^^^^^^ value borrowed here after move
+ | |
| value moved here
error[E0382]: borrow of moved value
@@ -308,9 +302,8 @@ error[E0382]: borrow of moved value
LL | match Some(u()) {
| --------- move occurs because value has type `Option<U>`, which does not implement the `Copy` trait
LL | a @ Some(ref b) => {}
- | ---------^^^^^-
- | | |
- | | value borrowed here after move
+ | - ^^^^^ value borrowed here after move
+ | |
| value moved here
error[E0382]: use of moved value
@@ -319,10 +312,7 @@ error[E0382]: use of moved value
LL | match Some((u(), u())) {
| ---------------- move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
- | -----------------------------^^^^^^^^^--
- | | |
- | | value used here after move
- | value moved here
+ | - value moved here ^ value used here after move
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:30
@@ -330,18 +320,16 @@ error[E0382]: borrow of moved value
LL | match Some([u(), u()]) {
| ---------------- move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
LL | mut a @ Some([ref b, ref mut c]) => {}
- | ---------------------^^^^^^^^^--
- | | |
- | | value borrowed here after move
+ | ----- ^^^^^^^^^ value borrowed here after move
+ | |
| value moved here
error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11
|
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
- | ^^^^^^^^^^^^^^^^^^^^-------------^
- | | |
- | | value partially moved here
+ | ^^^^^ ----- value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
index c019aae3d..b2f22fe86 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
@@ -237,9 +237,8 @@ error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:30:9
|
LL | let ref mut a @ [b, mut c] = [U, U];
- | ^^^^^^^^^^^^^^^^-----^
- | | |
- | | value partially moved here
+ | ^^^^^^^^^ ----- value partially moved here
+ | |
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -248,7 +247,7 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:9
|
LL | let ref a @ b = u();
- | ^^^^^^^^- --- move occurs because value has type `U`, which does not implement the `Copy` trait
+ | ^^^^^ - --- move occurs because value has type `U`, which does not implement the `Copy` trait
| | |
| | value moved here
| value borrowed here after move
@@ -257,9 +256,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:18
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
- | ^^^^^^^^-----
- | | |
- | | value moved here
+ | ^^^^^ ----- value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -268,9 +266,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:33
|
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
- | ^^^^^^^^-
- | | |
- | | value moved here
+ | ^^^^^ - value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -279,9 +276,8 @@ error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:42:9
|
LL | let ref mut a @ [b, mut c] = [u(), u()];
- | ^^^^^^^^^^^^^^^^-----^
- | | |
- | | value partially moved here
+ | ^^^^^^^^^ ----- value partially moved here
+ | |
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -290,9 +286,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:23
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
- | ^^^^^^^^-----
- | | |
- | | value moved here
+ | ^^^^^ ----- value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -305,9 +300,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:38
|
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
- | ^^^^^^^^-
- | | |
- | | value moved here
+ | ^^^^^ - value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -320,9 +314,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:11:11
|
LL | fn f1(ref a @ b: U) {}
- | ^^^^^^^^-
- | | |
- | | value moved here
+ | ^^^^^ - value moved here
+ | |
| value borrowed here after move
| move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -330,9 +323,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:20
|
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
- | ^^^^^^^^-----
- | | |
- | | value moved here
+ | ^^^^^ ----- value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -341,9 +333,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:35
|
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
- | ^^^^^^^^-
- | | |
- | | value moved here
+ | ^^^^^ - value moved here
+ | |
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
@@ -352,9 +343,8 @@ error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:20:11
|
LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
- | ^^^^^^^^^^^^^^^^-----^
- | | |
- | | value partially moved here
+ | ^^^^^^^^^ ----- value partially moved here
+ | |
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
index 2ae78d108..8546b4bb4 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
@@ -298,9 +298,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31
|
LL | ref mut z @ &mut Some(ref a) => {
- | ----------------------^^^^^-
- | | |
- | | immutable borrow occurs here
+ | --------- ^^^^^ immutable borrow occurs here
+ | |
| mutable borrow occurs here
...
LL | **z = None;
@@ -310,9 +309,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9
|
LL | let ref mut a @ ref b = u();
- | ^^^^^^^^^^^^-----
- | | |
- | | immutable borrow occurs here
+ | ^^^^^^^^^ ----- immutable borrow occurs here
+ | |
| mutable borrow occurs here
...
LL | drop(b);
@@ -322,9 +320,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:51:9
|
LL | let ref a @ ref mut b = u();
- | ^^^^^^^^---------
- | | |
- | | mutable borrow occurs here
+ | ^^^^^ --------- mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | *b = u();
@@ -334,9 +331,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:20
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
- | -----------^^^^^^^^^-
- | | |
- | | mutable borrow occurs here
+ | ----- ^^^^^^^^^ mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | drop(a);
@@ -346,9 +342,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:45
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
- | ------------^^^^^^^^^-
- | | |
- | | mutable borrow occurs here
+ | ----- ^^^^^^^^^ mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | drop(a);
@@ -406,9 +401,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
- | ^^^^^^^^^---------^^^^^^^^^^^^
- | | |
- | | mutable borrow occurs here
+ | ^^^^^ --------- mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | *b = U;
@@ -418,9 +412,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
- | ^^^^^^^^^---------^^^^^^^^^^^^
- | | |
- | | mutable borrow occurs here
+ | ^^^^^ --------- mutable borrow occurs here
+ | |
| immutable borrow occurs here
...
LL | *b = U;
@@ -430,9 +423,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
- | ^^^^^^^^^---------^^^^^^^^^^^^
- | | |
- | | mutable borrow occurs here
+ | ^^^^^ --------- mutable borrow occurs here
+ | |
| immutable borrow occurs here
LL |
LL | *b = U;
@@ -442,9 +434,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30
|
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
- | --------^^^^^^^^^^^^-
- | | | |
- | | | value moved here
+ | ----- ^^^^^^^^^ - value moved here
+ | | |
| | value borrowed here after move
| move occurs because value has type `U`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
index aa0223041..384a57b2e 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
@@ -262,9 +262,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:29:9
|
LL | let ref mut a @ ref mut b = U;
- | ^^^^^^^^^^^^---------
- | | |
- | | first mutable borrow occurs here
+ | ^^^^^^^^^ --------- first mutable borrow occurs here
+ | |
| second mutable borrow occurs here
...
LL | drop(b);
@@ -274,9 +273,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:39:9
|
LL | let ref mut a @ ref mut b = U;
- | ^^^^^^^^^^^^---------
- | | |
- | | first mutable borrow occurs here
+ | ^^^^^^^^^ --------- first mutable borrow occurs here
+ | |
| second mutable borrow occurs here
...
LL | *b = U;
@@ -286,9 +284,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
- | ---------------^^^^^^^^^-
- | | |
- | | second mutable borrow occurs here
+ | --------- ^^^^^^^^^ second mutable borrow occurs here
+ | |
| first mutable borrow occurs here
...
LL | *a = Err(U);
@@ -298,9 +295,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
- | ----------------^^^^^^^^^-
- | | |
- | | second mutable borrow occurs here
+ | --------- ^^^^^^^^^ second mutable borrow occurs here
+ | |
| first mutable borrow occurs here
...
LL | *a = Err(U);
@@ -310,9 +306,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
- | ---------------^^^^^^^^^-
- | | |
- | | second mutable borrow occurs here
+ | --------- ^^^^^^^^^ second mutable borrow occurs here
+ | |
| first mutable borrow occurs here
...
LL | drop(a);
@@ -322,9 +317,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
- | ----------------^^^^^^^^^-
- | | |
- | | second mutable borrow occurs here
+ | --------- ^^^^^^^^^ second mutable borrow occurs here
+ | |
| first mutable borrow occurs here
...
LL | drop(a);
@@ -334,9 +328,8 @@ error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:21:34
|
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
- | ------------^^^^^^^^^^^^-
- | | | |
- | | | value moved here
+ | --------- ^^^^^^^^^ - value moved here
+ | | |
| | value borrowed here after move
| move occurs because value has type `U`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
index d290144b6..cd3234952 100644
--- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
+++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
@@ -2,9 +2,8 @@ error[E0382]: use of partially moved value
--> $DIR/copy-and-move-mixed.rs:12:9
|
LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
- | ^^^^^^^^^^------------^
- | | |
- | | value partially moved here
+ | ^ - value partially moved here
+ | |
| value used here after partial move
|
= note: partial move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
index d78faa682..840a513d6 100644
--- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
+++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
@@ -48,7 +48,7 @@ error[E0382]: borrow of moved value
--> $DIR/default-binding-modes-both-sides-independent.rs:29:9
|
LL | let ref mut a @ b = NotCopy;
- | ^^^^^^^^^^^^- ------- move occurs because value has type `NotCopy`, which does not implement the `Copy` trait
+ | ^^^^^^^^^ - ------- move occurs because value has type `NotCopy`, which does not implement the `Copy` trait
| | |
| | value moved here
| value borrowed here after move
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
index 3180bd0af..70beb5d42 100644
--- a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
@@ -11,7 +11,7 @@ error[E0596]: cannot borrow `not_mut` as mutable, as it is not declared as mutab
--> $DIR/nested-binding-modes-mut.rs:9:5
|
LL | let not_mut @ mut is_mut = 42;
- | -------------------- help: consider changing this to be mutable: `mut not_mut`
+ | ------- help: consider changing this to be mutable: `mut not_mut`
LL | &mut is_mut;
LL | &mut not_mut;
| ^^^^^^^^^^^^ cannot borrow as mutable
diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
index 5beca04d2..bac2db6ce 100644
--- a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
+++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
@@ -35,7 +35,7 @@ error[E0502]: cannot borrow `arr[..]` as mutable because it is also borrowed as
--> $DIR/borrowck-move-ref-pattern.rs:13:16
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
- | ---------------- immutable borrow occurs here
+ | ----------- immutable borrow occurs here
...
LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr;
| ^^^^^^^^^^^ mutable borrow occurs here
@@ -47,7 +47,7 @@ error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:13:29
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
- | ---------------- borrow of `arr[..]` occurs here
+ | ----------- borrow of `arr[..]` occurs here
...
LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr;
| ^^^ move out of `arr[..]` occurs here
@@ -59,7 +59,7 @@ error[E0505]: cannot move out of `arr[..]` because it is borrowed
--> $DIR/borrowck-move-ref-pattern.rs:13:34
|
LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
- | ---------------- borrow of `arr[..]` occurs here
+ | ----------- borrow of `arr[..]` occurs here
...
LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr;
| ^^^^^^^ move out of `arr[..]` occurs here
diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr
index d96e86393..eba65a618 100644
--- a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr
+++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr
@@ -8,7 +8,15 @@ LL | drop::<U>(_x1);
| --- closure is `FnOnce` because it moves the variable `_x1` out of its environment
...
LL | accept_fn_mut(&c1);
- | ------------- the requirement to implement `FnMut` derives from here
+ | ------------- --- the requirement to implement `FnMut` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `accept_fn_mut`
+ --> $DIR/move-ref-patterns-closure-captures.rs:4:31
+ |
+LL | fn accept_fn_mut(_: &impl FnMut()) {}
+ | ^^^^^^^ required by this bound in `accept_fn_mut`
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
--> $DIR/move-ref-patterns-closure-captures.rs:9:14
@@ -20,7 +28,15 @@ LL | drop::<U>(_x1);
| --- closure is `FnOnce` because it moves the variable `_x1` out of its environment
...
LL | accept_fn(&c1);
- | --------- the requirement to implement `Fn` derives from here
+ | --------- --- the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `accept_fn`
+ --> $DIR/move-ref-patterns-closure-captures.rs:5:27
+ |
+LL | fn accept_fn(_: &impl Fn()) {}
+ | ^^^^ required by this bound in `accept_fn`
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
--> $DIR/move-ref-patterns-closure-captures.rs:20:14
@@ -32,7 +48,15 @@ LL | drop::<&mut U>(_x2);
| --- closure is `FnMut` because it mutates the variable `_x2` here
...
LL | accept_fn(&c2);
- | --------- the requirement to implement `Fn` derives from here
+ | --------- --- the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `accept_fn`
+ --> $DIR/move-ref-patterns-closure-captures.rs:5:27
+ |
+LL | fn accept_fn(_: &impl Fn()) {}
+ | ^^^^ required by this bound in `accept_fn`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs
index 84552f2e7..156285e0f 100644
--- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs
+++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs
@@ -1,5 +1,5 @@
// Here we test that rest patterns, i.e. `..`, are not allowed
-// outside of slice (+ ident patterns witin those), tuple,
+// outside of slice (+ ident patterns within those), tuple,
// and tuple struct patterns and that duplicates are caught in these contexts.
#![feature(box_patterns)]
diff --git a/src/test/ui/pattern/rest-pat-syntactic.rs b/src/test/ui/pattern/rest-pat-syntactic.rs
index 9656a0b5d..4da5a2db7 100644
--- a/src/test/ui/pattern/rest-pat-syntactic.rs
+++ b/src/test/ui/pattern/rest-pat-syntactic.rs
@@ -19,6 +19,8 @@ fn rest_patterns() {
// Box patterns:
let box ..;
+ //~^ WARN box pattern syntax is experimental
+ //~| WARN unstable syntax
// In or-patterns:
match x {
@@ -57,7 +59,7 @@ fn rest_patterns() {
.. |
[
(
- box ..,
+ box .., //~ WARN box pattern syntax is experimental
&(..),
&mut ..,
x @ ..
@@ -67,4 +69,5 @@ fn rest_patterns() {
ref mut x @ ..
=> {}
}
+ //~| WARN unstable syntax
}
diff --git a/src/test/ui/pattern/rest-pat-syntactic.stderr b/src/test/ui/pattern/rest-pat-syntactic.stderr
new file mode 100644
index 000000000..37019b7d5
--- /dev/null
+++ b/src/test/ui/pattern/rest-pat-syntactic.stderr
@@ -0,0 +1,24 @@
+warning: box pattern syntax is experimental
+ --> $DIR/rest-pat-syntactic.rs:21:9
+ |
+LL | let box ..;
+ | ^^^^^^
+ |
+ = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
+ = help: add `#![feature(box_patterns)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: box pattern syntax is experimental
+ --> $DIR/rest-pat-syntactic.rs:62:17
+ |
+LL | box ..,
+ | ^^^^^^
+ |
+ = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
+ = help: add `#![feature(box_patterns)]` to the crate attributes to enable
+ = warning: unstable syntax can change at any point in the future, causing a hard error!
+ = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.fixed b/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.fixed
new file mode 100644
index 000000000..b28dce881
--- /dev/null
+++ b/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+ match Some(1) { //~ ERROR non-exhaustive patterns: `None` not covered
+ Some(1) => {}
+ // hello
+ Some(_) => {}
+ None => todo!()
+ }
+}
diff --git a/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.rs b/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.rs
new file mode 100644
index 000000000..42493a632
--- /dev/null
+++ b/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+ match Some(1) { //~ ERROR non-exhaustive patterns: `None` not covered
+ Some(1) => {}
+ // hello
+ Some(_) => {}
+ }
+}
diff --git a/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.stderr b/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.stderr
new file mode 100644
index 000000000..f3dca9bcb
--- /dev/null
+++ b/src/test/ui/pattern/suggest-adding-appropriate-missing-pattern-excluding-comments.stderr
@@ -0,0 +1,24 @@
+error[E0004]: non-exhaustive patterns: `None` not covered
+ --> $DIR/suggest-adding-appropriate-missing-pattern-excluding-comments.rs:4:11
+ |
+LL | match Some(1) {
+ | ^^^^^^^ pattern `None` not covered
+ |
+note: `Option<i32>` defined here
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+ |
+LL | pub enum Option<T> {
+ | ------------------
+...
+LL | None,
+ | ^^^^ not covered
+ = note: the matched value is of type `Option<i32>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL ~ Some(_) => {}
+LL + None => todo!()
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs
index d968c48fb..5d4181a30 100644
--- a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs
+++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs
@@ -22,22 +22,22 @@ fn main() {
HiddenEnum::A => {}
HiddenEnum::C => {}
}
- //~^^^^ non-exhaustive patterns: `B` not covered
+ //~^^^^ non-exhaustive patterns: `HiddenEnum::B` not covered
match HiddenEnum::A {
HiddenEnum::A => {}
}
- //~^^^ non-exhaustive patterns: `B` and `_` not covered
+ //~^^^ non-exhaustive patterns: `HiddenEnum::B` and `_` not covered
match None {
None => {}
Some(HiddenEnum::A) => {}
}
- //~^^^^ non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
+ //~^^^^ non-exhaustive patterns: `Some(HiddenEnum::B)` and `Some(_)` not covered
match InCrate::A {
InCrate::A => {}
InCrate::B => {}
}
- //~^^^^ non-exhaustive patterns: `C` not covered
+ //~^^^^ non-exhaustive patterns: `InCrate::C` not covered
}
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
index 643e734f9..b450a9aed 100644
--- a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
@@ -16,11 +16,11 @@ LL ~ HiddenEnum::B => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `B` not covered
+error[E0004]: non-exhaustive patterns: `HiddenEnum::B` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:21:11
|
LL | match HiddenEnum::A {
- | ^^^^^^^^^^^^^ pattern `B` not covered
+ | ^^^^^^^^^^^^^ pattern `HiddenEnum::B` not covered
|
note: `HiddenEnum` defined here
--> $DIR/auxiliary/hidden.rs:3:5
@@ -34,14 +34,14 @@ LL | B,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ HiddenEnum::C => {}
-LL + B => todo!()
+LL + HiddenEnum::B => todo!()
|
-error[E0004]: non-exhaustive patterns: `B` and `_` not covered
+error[E0004]: non-exhaustive patterns: `HiddenEnum::B` and `_` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:27:11
|
LL | match HiddenEnum::A {
- | ^^^^^^^^^^^^^ patterns `B` and `_` not covered
+ | ^^^^^^^^^^^^^ patterns `HiddenEnum::B` and `_` not covered
|
note: `HiddenEnum` defined here
--> $DIR/auxiliary/hidden.rs:3:5
@@ -55,14 +55,14 @@ LL | B,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ HiddenEnum::A => {}
-LL + B | _ => todo!()
+LL + HiddenEnum::B | _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
+error[E0004]: non-exhaustive patterns: `Some(HiddenEnum::B)` and `Some(_)` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:32:11
|
LL | match None {
- | ^^^^ patterns `Some(B)` and `Some(_)` not covered
+ | ^^^^ patterns `Some(HiddenEnum::B)` and `Some(_)` not covered
|
note: `Option<HiddenEnum>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
@@ -76,14 +76,14 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ Some(HiddenEnum::A) => {}
-LL + Some(B) | Some(_) => todo!()
+LL + Some(HiddenEnum::B) | Some(_) => todo!()
|
-error[E0004]: non-exhaustive patterns: `C` not covered
+error[E0004]: non-exhaustive patterns: `InCrate::C` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:38:11
|
LL | match InCrate::A {
- | ^^^^^^^^^^ pattern `C` not covered
+ | ^^^^^^^^^^ pattern `InCrate::C` not covered
|
note: `InCrate` defined here
--> $DIR/doc-hidden-non-exhaustive.rs:11:5
@@ -97,7 +97,7 @@ LL | C,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ InCrate::B => {}
-LL + C => todo!()
+LL + InCrate::C => todo!()
|
error: aborting due to 5 previous errors
diff --git a/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
index d31ee0dbd..5e12bc1d2 100644
--- a/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
+++ b/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
@@ -105,11 +105,11 @@ LL | union NonEmptyUnion2 {
= note: the matched value is of type `NonEmptyUnion2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
-error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:83:20
|
LL | match_no_arms!(NonEmptyEnum1::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:24:5
@@ -121,11 +121,11 @@ LL | Foo(bool),
= note: the matched value is of type `NonEmptyEnum1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
-error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:84:20
|
LL | match_no_arms!(NonEmptyEnum2::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:27:5
@@ -139,11 +139,11 @@ LL | Bar,
= note: the matched value is of type `NonEmptyEnum2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
-error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:85:20
|
LL | match_no_arms!(NonEmptyEnum5::V1);
- | ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+ | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:30:6
@@ -238,11 +238,11 @@ LL ~ _ if false => {}
LL + NonEmptyUnion2 { .. } => todo!()
|
-error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:92:24
|
LL | match_guarded_arm!(NonEmptyEnum1::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:24:5
@@ -255,14 +255,14 @@ LL | Foo(bool),
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ _ if false => {}
-LL + Foo(_) => todo!()
+LL + NonEmptyEnum1::Foo(_) => todo!()
|
-error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:93:24
|
LL | match_guarded_arm!(NonEmptyEnum2::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:27:5
@@ -277,14 +277,14 @@ LL | Bar,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ _ if false => {}
-LL + Foo(_) | Bar => todo!()
+LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
|
-error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:94:24
|
LL | match_guarded_arm!(NonEmptyEnum5::V1);
- | ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+ | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:30:6
diff --git a/src/test/ui/pattern/usefulness/empty-match.normal.stderr b/src/test/ui/pattern/usefulness/empty-match.normal.stderr
index d31ee0dbd..5e12bc1d2 100644
--- a/src/test/ui/pattern/usefulness/empty-match.normal.stderr
+++ b/src/test/ui/pattern/usefulness/empty-match.normal.stderr
@@ -105,11 +105,11 @@ LL | union NonEmptyUnion2 {
= note: the matched value is of type `NonEmptyUnion2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
-error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:83:20
|
LL | match_no_arms!(NonEmptyEnum1::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:24:5
@@ -121,11 +121,11 @@ LL | Foo(bool),
= note: the matched value is of type `NonEmptyEnum1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
-error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:84:20
|
LL | match_no_arms!(NonEmptyEnum2::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:27:5
@@ -139,11 +139,11 @@ LL | Bar,
= note: the matched value is of type `NonEmptyEnum2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
-error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:85:20
|
LL | match_no_arms!(NonEmptyEnum5::V1);
- | ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+ | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:30:6
@@ -238,11 +238,11 @@ LL ~ _ if false => {}
LL + NonEmptyUnion2 { .. } => todo!()
|
-error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:92:24
|
LL | match_guarded_arm!(NonEmptyEnum1::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:24:5
@@ -255,14 +255,14 @@ LL | Foo(bool),
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ _ if false => {}
-LL + Foo(_) => todo!()
+LL + NonEmptyEnum1::Foo(_) => todo!()
|
-error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:93:24
|
LL | match_guarded_arm!(NonEmptyEnum2::Foo(true));
- | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:27:5
@@ -277,14 +277,14 @@ LL | Bar,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ _ if false => {}
-LL + Foo(_) | Bar => todo!()
+LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
|
-error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:94:24
|
LL | match_guarded_arm!(NonEmptyEnum5::V1);
- | ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
+ | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:30:6
diff --git a/src/test/ui/pattern/usefulness/empty-match.rs b/src/test/ui/pattern/usefulness/empty-match.rs
index 8110ec013..9cdc0413b 100644
--- a/src/test/ui/pattern/usefulness/empty-match.rs
+++ b/src/test/ui/pattern/usefulness/empty-match.rs
@@ -80,16 +80,16 @@ fn main() {
match_no_arms!(NonEmptyStruct2(true)); //~ ERROR type `NonEmptyStruct2` is non-empty
match_no_arms!((NonEmptyUnion1 { foo: () })); //~ ERROR type `NonEmptyUnion1` is non-empty
match_no_arms!((NonEmptyUnion2 { foo: () })); //~ ERROR type `NonEmptyUnion2` is non-empty
- match_no_arms!(NonEmptyEnum1::Foo(true)); //~ ERROR `Foo(_)` not covered
- match_no_arms!(NonEmptyEnum2::Foo(true)); //~ ERROR `Foo(_)` and `Bar` not covered
- match_no_arms!(NonEmptyEnum5::V1); //~ ERROR `V1`, `V2`, `V3` and 2 more not covered
+ match_no_arms!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
+ match_no_arms!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
+ match_no_arms!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
match_guarded_arm!(0u8); //~ ERROR `_` not covered
match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered
match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered
match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered
match_guarded_arm!((NonEmptyUnion2 { foo: () })); //~ ERROR `NonEmptyUnion2 { .. }` not covered
- match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `Foo(_)` not covered
- match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `Foo(_)` and `Bar` not covered
- match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `V1`, `V2`, `V3` and 2 more not covered
+ match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
+ match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
+ match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
}
diff --git a/src/test/ui/pattern/usefulness/issue-15129.rs b/src/test/ui/pattern/usefulness/issue-15129.rs
index d2b72a86b..f02e5c0c6 100644
--- a/src/test/ui/pattern/usefulness/issue-15129.rs
+++ b/src/test/ui/pattern/usefulness/issue-15129.rs
@@ -10,7 +10,7 @@ pub enum V {
fn main() {
match (T::T1(()), V::V2(true)) {
- //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
+ //~^ ERROR non-exhaustive patterns: `(T::T1(()), V::V2(_))` and `(T::T2(()), V::V1(_))` not covered
(T::T1(()), V::V1(i)) => (),
(T::T2(()), V::V2(b)) => (),
}
diff --git a/src/test/ui/pattern/usefulness/issue-15129.stderr b/src/test/ui/pattern/usefulness/issue-15129.stderr
index af60f3ff5..ee8410b76 100644
--- a/src/test/ui/pattern/usefulness/issue-15129.stderr
+++ b/src/test/ui/pattern/usefulness/issue-15129.stderr
@@ -1,14 +1,14 @@
-error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
+error[E0004]: non-exhaustive patterns: `(T::T1(()), V::V2(_))` and `(T::T2(()), V::V1(_))` not covered
--> $DIR/issue-15129.rs:12:11
|
LL | match (T::T1(()), V::V2(true)) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `(T::T1(()), V::V2(_))` and `(T::T2(()), V::V1(_))` not covered
|
= note: the matched value is of type `(T, V)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ (T::T2(()), V::V2(b)) => (),
-LL ~ (T1(()), V2(_)) | (T2(()), V1(_)) => todo!(),
+LL ~ (T::T1(()), V::V2(_)) | (T::T2(()), V::V1(_)) => todo!(),
|
error: aborting due to previous error
diff --git a/src/test/ui/pattern/usefulness/issue-31561.rs b/src/test/ui/pattern/usefulness/issue-31561.rs
index 813b2409c..5b878851a 100644
--- a/src/test/ui/pattern/usefulness/issue-31561.rs
+++ b/src/test/ui/pattern/usefulness/issue-31561.rs
@@ -6,5 +6,5 @@ enum Thing {
fn main() {
let Thing::Foo(y) = Thing::Foo(1);
- //~^ ERROR refutable pattern in local binding: `Bar` and `Baz` not covered
+ //~^ ERROR refutable pattern in local binding: `Thing::Bar` and `Thing::Baz` not covered
}
diff --git a/src/test/ui/pattern/usefulness/issue-31561.stderr b/src/test/ui/pattern/usefulness/issue-31561.stderr
index 9da6b5eee..20f2f0950 100644
--- a/src/test/ui/pattern/usefulness/issue-31561.stderr
+++ b/src/test/ui/pattern/usefulness/issue-31561.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered
+error[E0005]: refutable pattern in local binding: `Thing::Bar` and `Thing::Baz` not covered
--> $DIR/issue-31561.rs:8:9
|
LL | let Thing::Foo(y) = Thing::Foo(1);
- | ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
+ | ^^^^^^^^^^^^^ patterns `Thing::Bar` and `Thing::Baz` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -21,7 +21,7 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
LL | let y = if let Thing::Foo(y) = Thing::Foo(1) { y } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+help: alternatively, you might want to use let else to handle the variants that aren't matched
|
LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/pattern/usefulness/issue-35609.stderr b/src/test/ui/pattern/usefulness/issue-35609.stderr
index 2247b818d..c9781d52e 100644
--- a/src/test/ui/pattern/usefulness/issue-35609.stderr
+++ b/src/test/ui/pattern/usefulness/issue-35609.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `(Enum::B, _)`, `(Enum::C, _)`, `(Enum::D, _)` and 2 more not covered
--> $DIR/issue-35609.rs:10:11
|
LL | match (A, ()) {
- | ^^^^^^^ patterns `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered
+ | ^^^^^^^ patterns `(Enum::B, _)`, `(Enum::C, _)`, `(Enum::D, _)` and 2 more not covered
|
= note: the matched value is of type `(Enum, ())`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
@@ -11,11 +11,11 @@ LL ~ (A, _) => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `(_, Enum::B)`, `(_, Enum::C)`, `(_, Enum::D)` and 2 more not covered
--> $DIR/issue-35609.rs:14:11
|
LL | match (A, A) {
- | ^^^^^^ patterns `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered
+ | ^^^^^^ patterns `(_, Enum::B)`, `(_, Enum::C)`, `(_, Enum::D)` and 2 more not covered
|
= note: the matched value is of type `(Enum, Enum)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
@@ -24,11 +24,11 @@ LL ~ (_, A) => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `((Enum::B, _), _)`, `((Enum::C, _), _)`, `((Enum::D, _), _)` and 2 more not covered
--> $DIR/issue-35609.rs:18:11
|
LL | match ((A, ()), ()) {
- | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+ | ^^^^^^^^^^^^^ patterns `((Enum::B, _), _)`, `((Enum::C, _), _)`, `((Enum::D, _), _)` and 2 more not covered
|
= note: the matched value is of type `((Enum, ()), ())`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
@@ -37,11 +37,11 @@ LL ~ ((A, ()), _) => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `((Enum::B, _), _)`, `((Enum::C, _), _)`, `((Enum::D, _), _)` and 2 more not covered
--> $DIR/issue-35609.rs:22:11
|
LL | match ((A, ()), A) {
- | ^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+ | ^^^^^^^^^^^^ patterns `((Enum::B, _), _)`, `((Enum::C, _), _)`, `((Enum::D, _), _)` and 2 more not covered
|
= note: the matched value is of type `((Enum, ()), Enum)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
@@ -50,11 +50,11 @@ LL ~ ((A, ()), _) => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `((Enum::B, _), _)`, `((Enum::C, _), _)`, `((Enum::D, _), _)` and 2 more not covered
--> $DIR/issue-35609.rs:26:11
|
LL | match ((A, ()), ()) {
- | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+ | ^^^^^^^^^^^^^ patterns `((Enum::B, _), _)`, `((Enum::C, _), _)`, `((Enum::D, _), _)` and 2 more not covered
|
= note: the matched value is of type `((Enum, ()), ())`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
@@ -63,11 +63,11 @@ LL ~ ((A, _), _) => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `S(Enum::B, _)`, `S(Enum::C, _)`, `S(Enum::D, _)` and 2 more not covered
--> $DIR/issue-35609.rs:31:11
|
LL | match S(A, ()) {
- | ^^^^^^^^ patterns `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered
+ | ^^^^^^^^ patterns `S(Enum::B, _)`, `S(Enum::C, _)`, `S(Enum::D, _)` and 2 more not covered
|
note: `S` defined here
--> $DIR/issue-35609.rs:6:8
@@ -81,11 +81,11 @@ LL ~ S(A, _) => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `Sd { x: Enum::B, .. }`, `Sd { x: Enum::C, .. }`, `Sd { x: Enum::D, .. }` and 2 more not covered
--> $DIR/issue-35609.rs:35:11
|
LL | match (Sd { x: A, y: () }) {
- | ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered
+ | ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: Enum::B, .. }`, `Sd { x: Enum::C, .. }`, `Sd { x: Enum::D, .. }` and 2 more not covered
|
note: `Sd` defined here
--> $DIR/issue-35609.rs:7:8
@@ -99,11 +99,11 @@ LL ~ Sd { x: A, y: _ } => {}
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `Some(Enum::B)`, `Some(Enum::C)`, `Some(Enum::D)` and 2 more not covered
--> $DIR/issue-35609.rs:39:11
|
LL | match Some(A) {
- | ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
+ | ^^^^^^^ patterns `Some(Enum::B)`, `Some(Enum::C)`, `Some(Enum::D)` and 2 more not covered
|
note: `Option<Enum>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
diff --git a/src/test/ui/pattern/usefulness/issue-39362.stderr b/src/test/ui/pattern/usefulness/issue-39362.stderr
index ca37af6fb..b8b17918a 100644
--- a/src/test/ui/pattern/usefulness/issue-39362.stderr
+++ b/src/test/ui/pattern/usefulness/issue-39362.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+error[E0004]: non-exhaustive patterns: `Foo::Bar { bar: Bar::C, .. }`, `Foo::Bar { bar: Bar::D, .. }`, `Foo::Bar { bar: Bar::E, .. }` and 1 more not covered
--> $DIR/issue-39362.rs:10:11
|
LL | match f {
- | ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+ | ^ patterns `Foo::Bar { bar: Bar::C, .. }`, `Foo::Bar { bar: Bar::D, .. }`, `Foo::Bar { bar: Bar::E, .. }` and 1 more not covered
|
note: `Foo` defined here
--> $DIR/issue-39362.rs:2:5
diff --git a/src/test/ui/pattern/usefulness/issue-40221.stderr b/src/test/ui/pattern/usefulness/issue-40221.stderr
index c477e4353..4973e42b0 100644
--- a/src/test/ui/pattern/usefulness/issue-40221.stderr
+++ b/src/test/ui/pattern/usefulness/issue-40221.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `C(QA)` not covered
+error[E0004]: non-exhaustive patterns: `P::C(PC::QA)` not covered
--> $DIR/issue-40221.rs:11:11
|
LL | match proto {
- | ^^^^^ pattern `C(QA)` not covered
+ | ^^^^^ pattern `P::C(PC::QA)` not covered
|
note: `P` defined here
--> $DIR/issue-40221.rs:2:5
@@ -15,7 +15,7 @@ LL | C(PC),
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ P::C(PC::Q) => (),
-LL ~ C(QA) => todo!(),
+LL ~ P::C(PC::QA) => todo!(),
|
error: aborting due to previous error
diff --git a/src/test/ui/pattern/usefulness/issue-50900.rs b/src/test/ui/pattern/usefulness/issue-50900.rs
index 27135af95..9cc760e9a 100644
--- a/src/test/ui/pattern/usefulness/issue-50900.rs
+++ b/src/test/ui/pattern/usefulness/issue-50900.rs
@@ -13,7 +13,7 @@ impl Tag {
fn main() {
match Tag::ExifIFDPointer {
- //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered
+ //~^ ERROR: non-exhaustive patterns: `Tag(Context::Exif, _)` not covered
Tag::ExifIFDPointer => {}
}
}
diff --git a/src/test/ui/pattern/usefulness/issue-50900.stderr b/src/test/ui/pattern/usefulness/issue-50900.stderr
index 2bdbecabb..348246d28 100644
--- a/src/test/ui/pattern/usefulness/issue-50900.stderr
+++ b/src/test/ui/pattern/usefulness/issue-50900.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered
+error[E0004]: non-exhaustive patterns: `Tag(Context::Exif, _)` not covered
--> $DIR/issue-50900.rs:15:11
|
LL | match Tag::ExifIFDPointer {
- | ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered
+ | ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Context::Exif, _)` not covered
|
note: `Tag` defined here
--> $DIR/issue-50900.rs:2:12
@@ -13,7 +13,7 @@ LL | pub struct Tag(pub Context, pub u16);
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Tag::ExifIFDPointer => {}
-LL + Tag(Exif, _) => todo!()
+LL + Tag(Context::Exif, _) => todo!()
|
error: aborting due to previous error
diff --git a/src/test/ui/pattern/usefulness/issue-56379.rs b/src/test/ui/pattern/usefulness/issue-56379.rs
index 9bccccca9..097cf98d0 100644
--- a/src/test/ui/pattern/usefulness/issue-56379.rs
+++ b/src/test/ui/pattern/usefulness/issue-56379.rs
@@ -6,7 +6,7 @@ enum Foo {
fn main() {
match Foo::A(true) {
- //~^ ERROR non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered
+ //~^ ERROR non-exhaustive patterns: `Foo::A(false)`, `Foo::B(false)` and `Foo::C(false)` not covered
Foo::A(true) => {}
Foo::B(true) => {}
Foo::C(true) => {}
diff --git a/src/test/ui/pattern/usefulness/issue-56379.stderr b/src/test/ui/pattern/usefulness/issue-56379.stderr
index f6261001c..6eed6bfae 100644
--- a/src/test/ui/pattern/usefulness/issue-56379.stderr
+++ b/src/test/ui/pattern/usefulness/issue-56379.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered
+error[E0004]: non-exhaustive patterns: `Foo::A(false)`, `Foo::B(false)` and `Foo::C(false)` not covered
--> $DIR/issue-56379.rs:8:11
|
LL | match Foo::A(true) {
- | ^^^^^^^^^^^^ patterns `A(false)`, `B(false)` and `C(false)` not covered
+ | ^^^^^^^^^^^^ patterns `Foo::A(false)`, `Foo::B(false)` and `Foo::C(false)` not covered
|
note: `Foo` defined here
--> $DIR/issue-56379.rs:2:5
@@ -19,7 +19,7 @@ LL | C(bool),
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ Foo::C(true) => {}
-LL + A(false) | B(false) | C(false) => todo!()
+LL + Foo::A(false) | Foo::B(false) | Foo::C(false) => todo!()
|
error: aborting due to previous error
diff --git a/src/test/ui/pattern/usefulness/issue-72377.rs b/src/test/ui/pattern/usefulness/issue-72377.rs
index b0d8a53ed..b5ad3075c 100644
--- a/src/test/ui/pattern/usefulness/issue-72377.rs
+++ b/src/test/ui/pattern/usefulness/issue-72377.rs
@@ -6,7 +6,7 @@ fn main() {
let y = Some(X::A);
match (x, y) {
- //~^ ERROR non-exhaustive patterns: `(A, Some(A))`, `(A, Some(B))`, `(B, Some(B))` and 2
+ //~^ ERROR non-exhaustive patterns: `(X::A, Some(X::A))`, `(X::A, Some(X::B))`, `(X::B, Some(X::B))` and 2
//~| more not covered
(_, None) => false,
(v, Some(w)) if v == w => true,
diff --git a/src/test/ui/pattern/usefulness/issue-72377.stderr b/src/test/ui/pattern/usefulness/issue-72377.stderr
index 20f002dd3..123dd051d 100644
--- a/src/test/ui/pattern/usefulness/issue-72377.stderr
+++ b/src/test/ui/pattern/usefulness/issue-72377.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `(A, Some(A))`, `(A, Some(B))`, `(B, Some(B))` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `(X::A, Some(X::A))`, `(X::A, Some(X::B))`, `(X::B, Some(X::B))` and 2 more not covered
--> $DIR/issue-72377.rs:8:11
|
LL | match (x, y) {
- | ^^^^^^ patterns `(A, Some(A))`, `(A, Some(B))`, `(B, Some(B))` and 2 more not covered
+ | ^^^^^^ patterns `(X::A, Some(X::A))`, `(X::A, Some(X::B))`, `(X::B, Some(X::B))` and 2 more not covered
|
= note: the matched value is of type `(X, Option<X>)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
index 4c5f2d356..3c9c16561 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
@@ -27,7 +27,7 @@ const EAST: Direction = East;
fn nonexhaustive_2() {
match Some(Some(North)) {
- //~^ ERROR non-exhaustive patterns: `Some(Some(West))` not covered
+ //~^ ERROR non-exhaustive patterns: `Some(Some(Direction::West))` not covered
Some(NONE) => (),
Some(Some(North)) => (),
Some(Some(EAST)) => (),
@@ -46,7 +46,7 @@ const STATIC_FOO: Foo = Foo { bar: None, baz: NEW_FALSE };
fn nonexhaustive_3() {
match (Foo { bar: Some(North), baz: NewBool(true) }) {
- //~^ ERROR non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }`
+ //~^ ERROR non-exhaustive patterns: `Foo { bar: Some(Direction::North), baz: NewBool(true) }`
Foo { bar: None, baz: NewBool(true) } => (),
Foo { bar: _, baz: NEW_FALSE } => (),
Foo { bar: Some(West), baz: NewBool(true) } => (),
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
index a2b66f5ed..b0d7fe5eb 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
@@ -11,11 +11,11 @@ LL ~ (false, true) => (),
LL + (true, false) => todo!()
|
-error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
+error[E0004]: non-exhaustive patterns: `Some(Some(Direction::West))` not covered
--> $DIR/match-arm-statics-2.rs:29:11
|
LL | match Some(Some(North)) {
- | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
+ | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(Direction::West))` not covered
|
note: `Option<Option<Direction>>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
@@ -32,14 +32,14 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ None => (),
-LL + Some(Some(West)) => todo!()
+LL + Some(Some(Direction::West)) => todo!()
|
-error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
+error[E0004]: non-exhaustive patterns: `Foo { bar: Some(Direction::North), baz: NewBool(true) }` not covered
--> $DIR/match-arm-statics-2.rs:48:11
|
LL | match (Foo { bar: Some(North), baz: NewBool(true) }) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(Direction::North), baz: NewBool(true) }` not covered
|
note: `Foo` defined here
--> $DIR/match-arm-statics-2.rs:40:8
@@ -50,7 +50,7 @@ LL | struct Foo {
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Foo { bar: Some(EAST), .. } => (),
-LL + Foo { bar: Some(North), baz: NewBool(true) } => todo!()
+LL + Foo { bar: Some(Direction::North), baz: NewBool(true) } => todo!()
|
error: aborting due to 3 previous errors
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs
index 2e15bc2d2..af42fc1ae 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs
@@ -35,43 +35,43 @@ enum E {
fn by_val(e: E) {
let e1 = e.clone();
- match e1 { //~ ERROR non-exhaustive patterns: `B` and `C` not covered
- //~^ NOTE patterns `B` and `C` not covered
+ match e1 { //~ ERROR non-exhaustive patterns: `E::B` and `E::C` not covered
+ //~^ NOTE patterns `E::B` and `E::C` not covered
//~| NOTE the matched value is of type `E`
E::A => {}
}
- let E::A = e; //~ ERROR refutable pattern in local binding: `B` and `C` not covered
- //~^ NOTE patterns `B` and `C` not covered
+ let E::A = e; //~ ERROR refutable pattern in local binding: `E::B` and `E::C` not covered
+ //~^ NOTE patterns `E::B` and `E::C` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
//~| NOTE the matched value is of type `E`
}
fn by_ref_once(e: &E) {
- match e { //~ ERROR non-exhaustive patterns: `&B` and `&C` not covered
- //~^ NOTE patterns `&B` and `&C` not covered
+ match e { //~ ERROR non-exhaustive patterns: `&E::B` and `&E::C` not covered
+ //~^ NOTE patterns `&E::B` and `&E::C` not covered
//~| NOTE the matched value is of type `&E`
E::A => {}
}
- let E::A = e; //~ ERROR refutable pattern in local binding: `&B` and `&C` not covered
- //~^ NOTE patterns `&B` and `&C` not covered
+ let E::A = e; //~ ERROR refutable pattern in local binding: `&E::B` and `&E::C` not covered
+ //~^ NOTE patterns `&E::B` and `&E::C` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
//~| NOTE the matched value is of type `&E`
}
fn by_ref_thrice(e: & &mut &E) {
- match e { //~ ERROR non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
- //~^ NOTE patterns `&&mut &B` and `&&mut &C` not covered
+ match e { //~ ERROR non-exhaustive patterns: `&&mut &E::B` and `&&mut &E::C` not covered
+ //~^ NOTE patterns `&&mut &E::B` and `&&mut &E::C` not covered
//~| NOTE the matched value is of type `&&mut &E`
E::A => {}
}
let E::A = e;
- //~^ ERROR refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered
- //~| NOTE patterns `&&mut &B` and `&&mut &C` not covered
+ //~^ ERROR refutable pattern in local binding: `&&mut &E::B` and `&&mut &E::C` not covered
+ //~| NOTE patterns `&&mut &E::B` and `&&mut &E::C` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
//~| NOTE the matched value is of type `&&mut &E`
@@ -89,15 +89,15 @@ enum Opt {
}
fn ref_pat(e: Opt) {
- match e {//~ ERROR non-exhaustive patterns: `None` not covered
- //~^ NOTE pattern `None` not covered
+ match e {//~ ERROR non-exhaustive patterns: `Opt::None` not covered
+ //~^ NOTE pattern `Opt::None` not covered
//~| NOTE the matched value is of type `Opt`
Opt::Some(ref _x) => {}
}
- let Opt::Some(ref _x) = e; //~ ERROR refutable pattern in local binding: `None` not covered
+ let Opt::Some(ref _x) = e; //~ ERROR refutable pattern in local binding: `Opt::None` not covered
//~^ NOTE the matched value is of type `Opt`
- //~| NOTE pattern `None` not covered
+ //~| NOTE pattern `Opt::None` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
}
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
index 0f06c31c4..678c9b2ab 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `B` and `C` not covered
+error[E0004]: non-exhaustive patterns: `E::B` and `E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:38:11
|
LL | match e1 {
- | ^^ patterns `B` and `C` not covered
+ | ^^ patterns `E::B` and `E::C` not covered
|
note: `E` defined here
--> $DIR/non-exhaustive-defined-here.rs:14:5
@@ -19,14 +19,14 @@ LL | C
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ E::A => {}
-LL + B | C => todo!()
+LL + E::B | E::C => todo!()
|
-error[E0005]: refutable pattern in local binding: `B` and `C` not covered
+error[E0005]: refutable pattern in local binding: `E::B` and `E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:44:9
|
LL | let E::A = e;
- | ^^^^ patterns `B` and `C` not covered
+ | ^^^^ patterns `E::B` and `E::C` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -47,11 +47,11 @@ help: you might want to use `if let` to ignore the variants that aren't matched
LL | if let E::A = e { todo!() }
| ++ ~~~~~~~~~~~
-error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered
+error[E0004]: non-exhaustive patterns: `&E::B` and `&E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:52:11
|
LL | match e {
- | ^ patterns `&B` and `&C` not covered
+ | ^ patterns `&E::B` and `&E::C` not covered
|
note: `E` defined here
--> $DIR/non-exhaustive-defined-here.rs:14:5
@@ -68,14 +68,14 @@ LL | C
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ E::A => {}
-LL + &B | &C => todo!()
+LL + &E::B | &E::C => todo!()
|
-error[E0005]: refutable pattern in local binding: `&B` and `&C` not covered
+error[E0005]: refutable pattern in local binding: `&E::B` and `&E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:58:9
|
LL | let E::A = e;
- | ^^^^ patterns `&B` and `&C` not covered
+ | ^^^^ patterns `&E::B` and `&E::C` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -96,11 +96,11 @@ help: you might want to use `if let` to ignore the variants that aren't matched
LL | if let E::A = e { todo!() }
| ++ ~~~~~~~~~~~
-error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
+error[E0004]: non-exhaustive patterns: `&&mut &E::B` and `&&mut &E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:66:11
|
LL | match e {
- | ^ patterns `&&mut &B` and `&&mut &C` not covered
+ | ^ patterns `&&mut &E::B` and `&&mut &E::C` not covered
|
note: `E` defined here
--> $DIR/non-exhaustive-defined-here.rs:14:5
@@ -117,14 +117,14 @@ LL | C
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ E::A => {}
-LL + &&mut &B | &&mut &C => todo!()
+LL + &&mut &E::B | &&mut &E::C => todo!()
|
-error[E0005]: refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered
+error[E0005]: refutable pattern in local binding: `&&mut &E::B` and `&&mut &E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:72:9
|
LL | let E::A = e;
- | ^^^^ patterns `&&mut &B` and `&&mut &C` not covered
+ | ^^^^ patterns `&&mut &E::B` and `&&mut &E::C` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -145,11 +145,11 @@ help: you might want to use `if let` to ignore the variants that aren't matched
LL | if let E::A = e { todo!() }
| ++ ~~~~~~~~~~~
-error[E0004]: non-exhaustive patterns: `None` not covered
+error[E0004]: non-exhaustive patterns: `Opt::None` not covered
--> $DIR/non-exhaustive-defined-here.rs:92:11
|
LL | match e {
- | ^ pattern `None` not covered
+ | ^ pattern `Opt::None` not covered
|
note: `Opt` defined here
--> $DIR/non-exhaustive-defined-here.rs:84:5
@@ -163,14 +163,14 @@ LL | None,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Opt::Some(ref _x) => {}
-LL + None => todo!()
+LL + Opt::None => todo!()
|
-error[E0005]: refutable pattern in local binding: `None` not covered
+error[E0005]: refutable pattern in local binding: `Opt::None` not covered
--> $DIR/non-exhaustive-defined-here.rs:98:9
|
LL | let Opt::Some(ref _x) = e;
- | ^^^^^^^^^^^^^^^^^ pattern `None` not covered
+ | ^^^^^^^^^^^^^^^^^ pattern `Opt::None` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -187,7 +187,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let _x = if let Opt::Some(ref _x) = e { _x } else { todo!() };
| +++++++++++ +++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Opt::Some(ref _x) = e else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs
index d19814479..69c3c7658 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs
@@ -12,7 +12,7 @@ fn match_nested_vecs<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -> &'s
fn main() {
let x = T::A(U::C);
- match x { //~ ERROR non-exhaustive patterns: `A(C)` not covered
+ match x { //~ ERROR non-exhaustive patterns: `T::A(U::C)` not covered
T::A(U::D) => { panic!("hello"); }
T::B => { panic!("goodbye"); }
}
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
index cbbd544f9..44f327421 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
@@ -11,11 +11,11 @@ LL ~ (None, Ok(&[_, _, ..])) => "None, Ok(at least two elements)",
LL + (Some(&[]), Err(_)) => todo!()
|
-error[E0004]: non-exhaustive patterns: `A(C)` not covered
+error[E0004]: non-exhaustive patterns: `T::A(U::C)` not covered
--> $DIR/non-exhaustive-match-nested.rs:15:11
|
LL | match x {
- | ^ pattern `A(C)` not covered
+ | ^ pattern `T::A(U::C)` not covered
|
note: `T` defined here
--> $DIR/non-exhaustive-match-nested.rs:1:10
@@ -26,7 +26,7 @@ LL | enum T { A(U), B }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ T::B => { panic!("goodbye"); }
-LL + A(C) => todo!()
+LL + T::A(U::C) => todo!()
|
error: aborting due to 2 previous errors
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
index 4ff12aa2f..1cb58b8ce 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
@@ -4,7 +4,7 @@ enum T { A, B }
fn main() {
let x = T::A;
- match x { T::B => { } } //~ ERROR non-exhaustive patterns: `A` not covered
+ match x { T::B => { } } //~ ERROR non-exhaustive patterns: `T::A` not covered
match true { //~ ERROR non-exhaustive patterns: `false` not covered
true => {}
}
@@ -15,11 +15,11 @@ fn main() {
// and `(_, _, 5_i32..=i32::MAX)` not covered
(_, _, 4) => {}
}
- match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` and `(B, B)` not covered
+ match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(T::A, T::A)` and `(T::B, T::B)` not covered
(T::A, T::B) => {}
(T::B, T::A) => {}
}
- match T::A { //~ ERROR non-exhaustive patterns: `B` not covered
+ match T::A { //~ ERROR non-exhaustive patterns: `T::B` not covered
T::A => {}
}
// This is exhaustive, though the algorithm got it wrong at one point
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index f2362c316..4234600d0 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `A` not covered
+error[E0004]: non-exhaustive patterns: `T::A` not covered
--> $DIR/non-exhaustive-match.rs:7:11
|
LL | match x { T::B => { } }
- | ^ pattern `A` not covered
+ | ^ pattern `T::A` not covered
|
note: `T` defined here
--> $DIR/non-exhaustive-match.rs:3:10
@@ -12,8 +12,8 @@ LL | enum T { A, B }
= note: the matched value is of type `T`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
-LL | match x { T::B => { }, A => todo!() }
- | ++++++++++++++
+LL | match x { T::B => { }, T::A => todo!() }
+ | +++++++++++++++++
error[E0004]: non-exhaustive patterns: `false` not covered
--> $DIR/non-exhaustive-match.rs:8:11
@@ -62,24 +62,24 @@ LL ~ (_, _, 4) => {}
LL + (_, _, i32::MIN..=3_i32) | (_, _, 5_i32..=i32::MAX) => todo!()
|
-error[E0004]: non-exhaustive patterns: `(A, A)` and `(B, B)` not covered
+error[E0004]: non-exhaustive patterns: `(T::A, T::A)` and `(T::B, T::B)` not covered
--> $DIR/non-exhaustive-match.rs:18:11
|
LL | match (T::A, T::A) {
- | ^^^^^^^^^^^^ patterns `(A, A)` and `(B, B)` not covered
+ | ^^^^^^^^^^^^ patterns `(T::A, T::A)` and `(T::B, T::B)` not covered
|
= note: the matched value is of type `(T, T)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ (T::B, T::A) => {}
-LL + (A, A) | (B, B) => todo!()
+LL + (T::A, T::A) | (T::B, T::B) => todo!()
|
-error[E0004]: non-exhaustive patterns: `B` not covered
+error[E0004]: non-exhaustive patterns: `T::B` not covered
--> $DIR/non-exhaustive-match.rs:22:11
|
LL | match T::A {
- | ^^^^ pattern `B` not covered
+ | ^^^^ pattern `T::B` not covered
|
note: `T` defined here
--> $DIR/non-exhaustive-match.rs:3:13
@@ -90,7 +90,7 @@ LL | enum T { A, B }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ T::A => {}
-LL + B => todo!()
+LL + T::B => todo!()
|
error[E0004]: non-exhaustive patterns: `[]` not covered
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs
index abb4ea8da..4bd344219 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs
@@ -21,7 +21,7 @@ enum Color {
fn enum_with_single_missing_variant() {
match Color::Red {
- //~^ ERROR non-exhaustive patterns: `Red` not covered
+ //~^ ERROR non-exhaustive patterns: `Color::Red` not covered
Color::CustomRGBA { .. } => (),
Color::Green => ()
}
@@ -33,7 +33,7 @@ enum Direction {
fn enum_with_multiple_missing_variants() {
match Direction::North {
- //~^ ERROR non-exhaustive patterns: `East`, `South` and `West` not covered
+ //~^ ERROR non-exhaustive patterns: `Direction::East`, `Direction::South` and `Direction::West` not covered
Direction::North => ()
}
}
@@ -44,7 +44,7 @@ enum ExcessiveEnum {
fn enum_with_excessive_missing_variants() {
match ExcessiveEnum::First {
- //~^ ERROR `Second`, `Third`, `Fourth` and 8 more not covered
+ //~^ ERROR `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered
ExcessiveEnum::First => ()
}
@@ -52,7 +52,7 @@ fn enum_with_excessive_missing_variants() {
fn enum_struct_variant() {
match Color::Red {
- //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
+ //~^ ERROR non-exhaustive patterns: `Color::CustomRGBA { a: true, .. }` not covered
Color::Red => (),
Color::Green => (),
Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
@@ -68,7 +68,7 @@ enum Enum {
fn vectors_with_nested_enums() {
let x: &'static [Enum] = &[Enum::First, Enum::Second(false)];
match *x {
- //~^ ERROR non-exhaustive patterns: `[Second(true), Second(false)]` not covered
+ //~^ ERROR non-exhaustive patterns: `[Enum::Second(true), Enum::Second(false)]` not covered
[] => (),
[_] => (),
[Enum::First, _] => (),
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
index b0cfd631f..b8af566de 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
@@ -16,11 +16,11 @@ LL ~ Foo { first: false, second: Some([1, 2, 3, 4]) } => (),
LL + Foo { first: false, second: Some([_, _, _, _]) } => todo!()
|
-error[E0004]: non-exhaustive patterns: `Red` not covered
+error[E0004]: non-exhaustive patterns: `Color::Red` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:23:11
|
LL | match Color::Red {
- | ^^^^^^^^^^ pattern `Red` not covered
+ | ^^^^^^^^^^ pattern `Color::Red` not covered
|
note: `Color` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:17:5
@@ -33,14 +33,14 @@ LL | Red,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Color::Green => (),
-LL + Red => todo!()
+LL + Color::Red => todo!()
|
-error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered
+error[E0004]: non-exhaustive patterns: `Direction::East`, `Direction::South` and `Direction::West` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:35:11
|
LL | match Direction::North {
- | ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered
+ | ^^^^^^^^^^^^^^^^ patterns `Direction::East`, `Direction::South` and `Direction::West` not covered
|
note: `Direction` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:31:12
@@ -56,14 +56,14 @@ LL | North, East, South, West
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ Direction::North => (),
-LL + East | South | West => todo!()
+LL + Direction::East | Direction::South | Direction::West => todo!()
|
-error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered
+error[E0004]: non-exhaustive patterns: `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered
--> $DIR/non-exhaustive-pattern-witness.rs:46:11
|
LL | match ExcessiveEnum::First {
- | ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered
+ | ^^^^^^^^^^^^^^^^^^^^ patterns `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered
|
note: `ExcessiveEnum` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:41:6
@@ -77,11 +77,11 @@ LL ~ ExcessiveEnum::First => (),
LL + _ => todo!()
|
-error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
+error[E0004]: non-exhaustive patterns: `Color::CustomRGBA { a: true, .. }` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:54:11
|
LL | match Color::Red {
- | ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered
+ | ^^^^^^^^^^ pattern `Color::CustomRGBA { a: true, .. }` not covered
|
note: `Color` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:19:5
@@ -95,20 +95,20 @@ LL | CustomRGBA { a: bool, r: u8, g: u8, b: u8 }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ Color::CustomRGBA { a: false, r: _, g: _, b: _ } => (),
-LL + CustomRGBA { a: true, .. } => todo!()
+LL + Color::CustomRGBA { a: true, .. } => todo!()
|
-error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered
+error[E0004]: non-exhaustive patterns: `[Enum::Second(true), Enum::Second(false)]` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:70:11
|
LL | match *x {
- | ^^ pattern `[Second(true), Second(false)]` not covered
+ | ^^ pattern `[Enum::Second(true), Enum::Second(false)]` not covered
|
= note: the matched value is of type `[Enum]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ [_, _, ref tail @ .., _] => (),
-LL + [Second(true), Second(false)] => todo!()
+LL + [Enum::Second(true), Enum::Second(false)] => todo!()
|
error[E0004]: non-exhaustive patterns: `((), false)` not covered
diff --git a/src/test/ui/pattern/usefulness/stable-gated-patterns.rs b/src/test/ui/pattern/usefulness/stable-gated-patterns.rs
index ff1c472e2..03db01160 100644
--- a/src/test/ui/pattern/usefulness/stable-gated-patterns.rs
+++ b/src/test/ui/pattern/usefulness/stable-gated-patterns.rs
@@ -8,7 +8,7 @@ fn main() {
match UnstableEnum::Stable {
UnstableEnum::Stable => {}
}
- //~^^^ non-exhaustive patterns: `Stable2` and `_` not covered
+ //~^^^ non-exhaustive patterns: `UnstableEnum::Stable2` and `_` not covered
match UnstableEnum::Stable {
UnstableEnum::Stable => {}
diff --git a/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr b/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
index 98c75953a..7b8588a3c 100644
--- a/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `Stable2` and `_` not covered
+error[E0004]: non-exhaustive patterns: `UnstableEnum::Stable2` and `_` not covered
--> $DIR/stable-gated-patterns.rs:8:11
|
LL | match UnstableEnum::Stable {
- | ^^^^^^^^^^^^^^^^^^^^ patterns `Stable2` and `_` not covered
+ | ^^^^^^^^^^^^^^^^^^^^ patterns `UnstableEnum::Stable2` and `_` not covered
|
note: `UnstableEnum` defined here
--> $DIR/auxiliary/unstable.rs:9:5
@@ -16,7 +16,7 @@ LL | Stable2,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ UnstableEnum::Stable => {}
-LL + Stable2 | _ => todo!()
+LL + UnstableEnum::Stable2 | _ => todo!()
|
error[E0004]: non-exhaustive patterns: `_` not covered
diff --git a/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr
index 6127fad3f..85c97be29 100644
--- a/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `B { x: Some(_) }` not covered
+error[E0004]: non-exhaustive patterns: `A::B { x: Some(_) }` not covered
--> $DIR/struct-like-enum-nonexhaustive.rs:8:11
|
LL | match x {
- | ^ pattern `B { x: Some(_) }` not covered
+ | ^ pattern `A::B { x: Some(_) }` not covered
|
note: `A` defined here
--> $DIR/struct-like-enum-nonexhaustive.rs:2:5
@@ -15,7 +15,7 @@ LL | B { x: Option<isize> },
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ A::B { x: None } => {}
-LL + B { x: Some(_) } => todo!()
+LL + A::B { x: Some(_) } => todo!()
|
error: aborting due to previous error
diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.rs b/src/test/ui/pattern/usefulness/top-level-alternation.rs
index 076de8461..e8cd12ea4 100644
--- a/src/test/ui/pattern/usefulness/top-level-alternation.rs
+++ b/src/test/ui/pattern/usefulness/top-level-alternation.rs
@@ -1,5 +1,3 @@
-#![feature(let_else)]
-
#![deny(unreachable_patterns)]
fn main() {
diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.stderr b/src/test/ui/pattern/usefulness/top-level-alternation.stderr
index dd5936fdc..17fa951c5 100644
--- a/src/test/ui/pattern/usefulness/top-level-alternation.stderr
+++ b/src/test/ui/pattern/usefulness/top-level-alternation.stderr
@@ -1,71 +1,71 @@
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:6:23
+ --> $DIR/top-level-alternation.rs:4:23
|
LL | while let 0..=2 | 1 = 0 {}
| ^
|
note: the lint level is defined here
- --> $DIR/top-level-alternation.rs:3:9
+ --> $DIR/top-level-alternation.rs:1:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:7:20
+ --> $DIR/top-level-alternation.rs:5:20
|
LL | if let 0..=2 | 1 = 0 {}
| ^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:11:15
+ --> $DIR/top-level-alternation.rs:9:15
|
LL | | 0 => {}
| ^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:16:15
+ --> $DIR/top-level-alternation.rs:14:15
|
LL | | Some(0) => {}
| ^^^^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:21:9
+ --> $DIR/top-level-alternation.rs:19:9
|
LL | (0, 0) => {}
| ^^^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:41:9
+ --> $DIR/top-level-alternation.rs:39:9
|
LL | _ => {}
| ^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:45:9
+ --> $DIR/top-level-alternation.rs:43:9
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:46:9
+ --> $DIR/top-level-alternation.rs:44:9
|
LL | None => {}
| ^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:51:9
+ --> $DIR/top-level-alternation.rs:49:9
|
LL | None | Some(_) => {}
| ^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:55:9
+ --> $DIR/top-level-alternation.rs:53:9
|
LL | 1..=2 => {},
| ^^^^^
error: unreachable pattern
- --> $DIR/top-level-alternation.rs:58:14
+ --> $DIR/top-level-alternation.rs:56:14
|
LL | let (0 | 0) = 0 else { return };
| ^
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs b/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs
index bdab327fd..7046555e0 100644
--- a/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs
+++ b/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs
@@ -11,7 +11,7 @@ fn main() {
UnstableEnum::Stable => {}
UnstableEnum::Stable2 => {}
}
- //~^^^^ non-exhaustive patterns: `Unstable` not covered
+ //~^^^^ non-exhaustive patterns: `UnstableEnum::Unstable` not covered
// Ok: all variants are explicitly matched
match UnstableEnum::Stable {
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr b/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
index f07a25ca8..6dc9a4058 100644
--- a/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `Unstable` not covered
+error[E0004]: non-exhaustive patterns: `UnstableEnum::Unstable` not covered
--> $DIR/unstable-gated-patterns.rs:10:11
|
LL | match UnstableEnum::Stable {
- | ^^^^^^^^^^^^^^^^^^^^ pattern `Unstable` not covered
+ | ^^^^^^^^^^^^^^^^^^^^ pattern `UnstableEnum::Unstable` not covered
|
note: `UnstableEnum` defined here
--> $DIR/auxiliary/unstable.rs:11:5
@@ -16,7 +16,7 @@ LL | Unstable,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
LL ~ UnstableEnum::Stable2 => {}
-LL + Unstable => todo!()
+LL + UnstableEnum::Unstable => todo!()
|
error: aborting due to previous error
diff --git a/src/test/ui/phantom-auto-trait.stderr b/src/test/ui/phantom-auto-trait.stderr
index 1cc653c51..015c8fa4c 100644
--- a/src/test/ui/phantom-auto-trait.stderr
+++ b/src/test/ui/phantom-auto-trait.stderr
@@ -6,7 +6,7 @@ LL | is_zen(x)
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Zen` for `&T`
+note: required for `&T` to implement `Zen`
--> $DIR/phantom-auto-trait.rs:10:24
|
LL | unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
@@ -35,7 +35,7 @@ LL | is_zen(x)
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Zen` for `&T`
+note: required for `&T` to implement `Zen`
--> $DIR/phantom-auto-trait.rs:10:24
|
LL | unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
diff --git a/src/test/ui/privacy/access_levels.rs b/src/test/ui/privacy/access_levels.rs
new file mode 100644
index 000000000..d51d2b572
--- /dev/null
+++ b/src/test/ui/privacy/access_levels.rs
@@ -0,0 +1,49 @@
+#![feature(rustc_attrs)]
+
+#[rustc_access_level] mod outer { //~ ERROR None
+ #[rustc_access_level] pub mod inner { //~ ERROR Some(Exported)
+ #[rustc_access_level]
+ extern "C" { //~ ERROR Some(Exported)
+ #[rustc_access_level] static a: u8; //~ ERROR None
+ #[rustc_access_level] pub fn b(); //~ ERROR Some(Exported)
+ }
+ #[rustc_access_level]
+ pub trait Trait { //~ ERROR Some(Exported)
+ #[rustc_access_level] const A: i32; //~ ERROR Some(Exported)
+ #[rustc_access_level] type B; //~ ERROR Some(Exported)
+ }
+
+ #[rustc_access_level]
+ pub struct Struct { //~ ERROR Some(Exported)
+ #[rustc_access_level] a: u8, //~ ERROR None
+ #[rustc_access_level] pub b: u8, //~ ERROR Some(Exported)
+ }
+
+ #[rustc_access_level]
+ pub union Union { //~ ERROR Some(Exported)
+ #[rustc_access_level] a: u8, //~ ERROR None
+ #[rustc_access_level] pub b: u8, //~ ERROR Some(Exported)
+ }
+
+ #[rustc_access_level]
+ pub enum Enum { //~ ERROR Some(Exported)
+ #[rustc_access_level] A( //~ ERROR Some(Exported)
+ #[rustc_access_level] Struct, //~ ERROR Some(Exported)
+ #[rustc_access_level] Union, //~ ERROR Some(Exported)
+ ),
+ }
+ }
+
+ #[rustc_access_level] macro_rules! none_macro { //~ ERROR None
+ () => {};
+ }
+
+ #[macro_export]
+ #[rustc_access_level] macro_rules! public_macro { //~ ERROR Some(Public)
+ () => {};
+ }
+}
+
+pub use outer::inner;
+
+fn main() {}
diff --git a/src/test/ui/privacy/access_levels.stderr b/src/test/ui/privacy/access_levels.stderr
new file mode 100644
index 000000000..f326293c3
--- /dev/null
+++ b/src/test/ui/privacy/access_levels.stderr
@@ -0,0 +1,125 @@
+error: None
+ --> $DIR/access_levels.rs:3:23
+ |
+LL | #[rustc_access_level] mod outer {
+ | ^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:4:27
+ |
+LL | #[rustc_access_level] pub mod inner {
+ | ^^^^^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:6:9
+ |
+LL | / extern "C" {
+LL | | #[rustc_access_level] static a: u8;
+LL | | #[rustc_access_level] pub fn b();
+LL | | }
+ | |_________^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:11:9
+ |
+LL | pub trait Trait {
+ | ^^^^^^^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:17:9
+ |
+LL | pub struct Struct {
+ | ^^^^^^^^^^^^^^^^^
+
+error: None
+ --> $DIR/access_levels.rs:18:35
+ |
+LL | #[rustc_access_level] a: u8,
+ | ^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:19:35
+ |
+LL | #[rustc_access_level] pub b: u8,
+ | ^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:23:9
+ |
+LL | pub union Union {
+ | ^^^^^^^^^^^^^^^
+
+error: None
+ --> $DIR/access_levels.rs:24:35
+ |
+LL | #[rustc_access_level] a: u8,
+ | ^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:25:35
+ |
+LL | #[rustc_access_level] pub b: u8,
+ | ^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:29:9
+ |
+LL | pub enum Enum {
+ | ^^^^^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:30:35
+ |
+LL | #[rustc_access_level] A(
+ | ^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:31:39
+ |
+LL | #[rustc_access_level] Struct,
+ | ^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:32:39
+ |
+LL | #[rustc_access_level] Union,
+ | ^^^^^
+
+error: None
+ --> $DIR/access_levels.rs:37:27
+ |
+LL | #[rustc_access_level] macro_rules! none_macro {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Some(Public)
+ --> $DIR/access_levels.rs:42:27
+ |
+LL | #[rustc_access_level] macro_rules! public_macro {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:12:35
+ |
+LL | #[rustc_access_level] const A: i32;
+ | ^^^^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:13:35
+ |
+LL | #[rustc_access_level] type B;
+ | ^^^^^^
+
+error: None
+ --> $DIR/access_levels.rs:7:35
+ |
+LL | #[rustc_access_level] static a: u8;
+ | ^^^^^^^^^^^^
+
+error: Some(Exported)
+ --> $DIR/access_levels.rs:8:35
+ |
+LL | #[rustc_access_level] pub fn b();
+ | ^^^^^^^^^^
+
+error: aborting due to 20 previous errors
+
diff --git a/src/test/ui/proc-macro/auxiliary/expand-expr.rs b/src/test/ui/proc-macro/auxiliary/expand-expr.rs
index 5463e79d7..1d6ef8a13 100644
--- a/src/test/ui/proc-macro/auxiliary/expand-expr.rs
+++ b/src/test/ui/proc-macro/auxiliary/expand-expr.rs
@@ -80,13 +80,21 @@ fn assert_ts_eq(lhs: &TokenStream, rhs: &TokenStream) {
pub fn expand_expr_is(input: TokenStream) -> TokenStream {
let mut iter = input.into_iter();
let mut expected_tts = Vec::new();
- loop {
+ let comma = loop {
match iter.next() {
- Some(TokenTree::Punct(ref p)) if p.as_char() == ',' => break,
+ Some(TokenTree::Punct(p)) if p.as_char() == ',' => break p,
Some(tt) => expected_tts.push(tt),
None => panic!("expected comma"),
}
- }
+ };
+
+ // Make sure that `Ident` and `Literal` objects from this proc-macro's
+ // environment are not invalidated when `expand_expr` recursively invokes
+ // another macro by taking a local copy, and checking it after the fact.
+ let pre_expand_span = comma.span();
+ let pre_expand_ident = Ident::new("ident", comma.span());
+ let pre_expand_literal = Literal::string("literal");
+ let pre_expand_call_site = Span::call_site();
let expected = expected_tts.into_iter().collect::<TokenStream>();
let expanded = iter.collect::<TokenStream>().expand_expr().expect("expand_expr failed");
@@ -100,6 +108,15 @@ pub fn expand_expr_is(input: TokenStream) -> TokenStream {
// Also compare the raw tts to make sure they line up.
assert_ts_eq(&expected, &expanded);
+ assert!(comma.span().eq(&pre_expand_span), "pre-expansion span is still equal");
+ assert_eq!(pre_expand_ident.to_string(), "ident", "pre-expansion identifier is still valid");
+ assert_eq!(
+ pre_expand_literal.to_string(),
+ "\"literal\"",
+ "pre-expansion literal is still valid"
+ );
+ assert!(Span::call_site().eq(&pre_expand_call_site), "pre-expansion call-site is still equal");
+
TokenStream::new()
}
diff --git a/src/test/ui/proc-macro/auxiliary/re-export.rs b/src/test/ui/proc-macro/auxiliary/re-export.rs
new file mode 100644
index 000000000..e8e9c9d3e
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/re-export.rs
@@ -0,0 +1,19 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn cause_ice(_: TokenStream) -> TokenStream {
+ "
+ enum IceCause {
+ Variant,
+ }
+
+ pub use IceCause::Variant;
+ ".parse().unwrap()
+}
diff --git a/src/test/ui/proc-macro/crt-static.rs b/src/test/ui/proc-macro/crt-static.rs
index 8c1a9dc80..6103acb7b 100644
--- a/src/test/ui/proc-macro/crt-static.rs
+++ b/src/test/ui/proc-macro/crt-static.rs
@@ -9,7 +9,7 @@
// FIXME: This don't work when crate-type is specified by attribute
// `#![crate_type = "proc-macro"]`, not by `--crate-type=proc-macro`
-// command line flag. This is beacuse the list of `cfg` symbols is generated
+// command line flag. This is because the list of `cfg` symbols is generated
// before attributes are parsed. See rustc_interface::util::add_configuration
#[cfg(target_feature = "crt-static")]
compile_error!("crt-static is enabled");
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-101211.rs b/src/test/ui/proc-macro/dollar-crate-issue-101211.rs
new file mode 100644
index 000000000..fc1acfd32
--- /dev/null
+++ b/src/test/ui/proc-macro/dollar-crate-issue-101211.rs
@@ -0,0 +1,29 @@
+// check-pass
+// edition:2021
+// aux-build:test-macros.rs
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+
+#[macro_use]
+extern crate test_macros;
+
+macro_rules! foo {
+ ($($path:ident)::*) => (
+ test_macros::recollect!(
+ $($path)::*
+ )
+ )
+}
+
+macro_rules! baz {
+ () => (
+ foo!($crate::BAR)
+ )
+}
+
+pub const BAR: u32 = 19;
+
+fn main(){
+ std::println!("{}", baz!());
+}
diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.rs b/src/test/ui/proc-macro/expand-to-unstable-2.rs
deleted file mode 100644
index 4160e5418..000000000
--- a/src/test/ui/proc-macro/expand-to-unstable-2.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// aux-build:derive-unstable-2.rs
-
-#![feature(register_attr)]
-
-#![register_attr(rustc_foo)]
-
-#[macro_use]
-extern crate derive_unstable_2;
-
-#[derive(Unstable)]
-//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
-
-struct A;
-
-fn main() {
- foo();
-}
diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr
deleted file mode 100644
index 8b16ffb76..000000000
--- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: attributes starting with `rustc` are reserved for use by the `rustc` compiler
- --> $DIR/expand-to-unstable-2.rs:10:10
- |
-LL | #[derive(Unstable)]
- | ^^^^^^^^
- |
- = note: this error originates in the derive macro `Unstable` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/proc-macro/inner-attrs.rs b/src/test/ui/proc-macro/inner-attrs.rs
index 2e3c704da..1000c9c75 100644
--- a/src/test/ui/proc-macro/inner-attrs.rs
+++ b/src/test/ui/proc-macro/inner-attrs.rs
@@ -1,3 +1,4 @@
+// gate-test-custom_inner_attributes
// compile-flags: -Z span-debug --error-format human
// aux-build:test-macros.rs
// edition:2018
diff --git a/src/test/ui/proc-macro/inner-attrs.stderr b/src/test/ui/proc-macro/inner-attrs.stderr
index 4da8751ef..a332e143a 100644
--- a/src/test/ui/proc-macro/inner-attrs.stderr
+++ b/src/test/ui/proc-macro/inner-attrs.stderr
@@ -1,23 +1,23 @@
error: expected non-macro inner attribute, found attribute macro `print_attr`
- --> $DIR/inner-attrs.rs:63:12
+ --> $DIR/inner-attrs.rs:64:12
|
LL | #![print_attr]
| ^^^^^^^^^^ not a non-macro inner attribute
error: expected non-macro inner attribute, found attribute macro `print_attr`
- --> $DIR/inner-attrs.rs:67:12
+ --> $DIR/inner-attrs.rs:68:12
|
LL | #![print_attr]
| ^^^^^^^^^^ not a non-macro inner attribute
error: expected non-macro inner attribute, found attribute macro `print_attr`
- --> $DIR/inner-attrs.rs:71:12
+ --> $DIR/inner-attrs.rs:72:12
|
LL | #![print_attr]
| ^^^^^^^^^^ not a non-macro inner attribute
error: expected non-macro inner attribute, found attribute macro `print_attr`
- --> $DIR/inner-attrs.rs:75:12
+ --> $DIR/inner-attrs.rs:76:12
|
LL | #![print_attr]
| ^^^^^^^^^^ not a non-macro inner attribute
diff --git a/src/test/ui/proc-macro/inner-attrs.stdout b/src/test/ui/proc-macro/inner-attrs.stdout
index eaa8882d6..490fc02f5 100644
--- a/src/test/ui/proc-macro/inner-attrs.stdout
+++ b/src/test/ui/proc-macro/inner-attrs.stdout
@@ -2,7 +2,7 @@ PRINT-ATTR_ARGS INPUT (DISPLAY): first
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "first",
- span: $DIR/inner-attrs.rs:16:25: 16:30 (#0),
+ span: $DIR/inner-attrs.rs:17:25: 17:30 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second)] fn foo()
@@ -11,40 +11,40 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Alone,
- span: $DIR/inner-attrs.rs:17:1: 17:2 (#0),
+ span: $DIR/inner-attrs.rs:18:1: 18:2 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:17:3: 17:24 (#0),
+ span: $DIR/inner-attrs.rs:18:3: 18:24 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "second",
- span: $DIR/inner-attrs.rs:17:25: 17:31 (#0),
+ span: $DIR/inner-attrs.rs:18:25: 18:31 (#0),
},
],
- span: $DIR/inner-attrs.rs:17:24: 17:32 (#0),
+ span: $DIR/inner-attrs.rs:18:24: 18:32 (#0),
},
],
- span: $DIR/inner-attrs.rs:17:2: 17:33 (#0),
+ span: $DIR/inner-attrs.rs:18:2: 18:33 (#0),
},
Ident {
ident: "fn",
- span: $DIR/inner-attrs.rs:18:1: 18:3 (#0),
+ span: $DIR/inner-attrs.rs:19:1: 19:3 (#0),
},
Ident {
ident: "foo",
- span: $DIR/inner-attrs.rs:18:4: 18:7 (#0),
+ span: $DIR/inner-attrs.rs:19:4: 19:7 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:18:7: 18:9 (#0),
+ span: $DIR/inner-attrs.rs:19:7: 19:9 (#0),
},
Group {
delimiter: Brace,
@@ -52,72 +52,72 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:19:5: 19:6 (#0),
+ span: $DIR/inner-attrs.rs:20:5: 20:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:19:6: 19:7 (#0),
+ span: $DIR/inner-attrs.rs:20:6: 20:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:19:8: 19:29 (#0),
+ span: $DIR/inner-attrs.rs:20:8: 20:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "third",
- span: $DIR/inner-attrs.rs:19:30: 19:35 (#0),
+ span: $DIR/inner-attrs.rs:20:30: 20:35 (#0),
},
],
- span: $DIR/inner-attrs.rs:19:29: 19:36 (#0),
+ span: $DIR/inner-attrs.rs:20:29: 20:36 (#0),
},
],
- span: $DIR/inner-attrs.rs:19:7: 19:37 (#0),
+ span: $DIR/inner-attrs.rs:20:7: 20:37 (#0),
},
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:20:5: 20:6 (#0),
+ span: $DIR/inner-attrs.rs:21:5: 21:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:20:6: 20:7 (#0),
+ span: $DIR/inner-attrs.rs:21:6: 21:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:20:8: 20:29 (#0),
+ span: $DIR/inner-attrs.rs:21:8: 21:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "fourth",
- span: $DIR/inner-attrs.rs:20:30: 20:36 (#0),
+ span: $DIR/inner-attrs.rs:21:30: 21:36 (#0),
},
],
- span: $DIR/inner-attrs.rs:20:29: 20:37 (#0),
+ span: $DIR/inner-attrs.rs:21:29: 21:37 (#0),
},
],
- span: $DIR/inner-attrs.rs:20:7: 20:38 (#0),
+ span: $DIR/inner-attrs.rs:21:7: 21:38 (#0),
},
],
- span: $DIR/inner-attrs.rs:18:10: 21:2 (#0),
+ span: $DIR/inner-attrs.rs:19:10: 22:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): second
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "second",
- span: $DIR/inner-attrs.rs:17:25: 17:31 (#0),
+ span: $DIR/inner-attrs.rs:18:25: 18:31 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): fn foo()
@@ -125,16 +125,16 @@ PRINT-ATTR INPUT (DISPLAY): fn foo()
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "fn",
- span: $DIR/inner-attrs.rs:18:1: 18:3 (#0),
+ span: $DIR/inner-attrs.rs:19:1: 19:3 (#0),
},
Ident {
ident: "foo",
- span: $DIR/inner-attrs.rs:18:4: 18:7 (#0),
+ span: $DIR/inner-attrs.rs:19:4: 19:7 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:18:7: 18:9 (#0),
+ span: $DIR/inner-attrs.rs:19:7: 19:9 (#0),
},
Group {
delimiter: Brace,
@@ -142,88 +142,88 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:19:5: 19:6 (#0),
+ span: $DIR/inner-attrs.rs:20:5: 20:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:19:6: 19:7 (#0),
+ span: $DIR/inner-attrs.rs:20:6: 20:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:19:8: 19:29 (#0),
+ span: $DIR/inner-attrs.rs:20:8: 20:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "third",
- span: $DIR/inner-attrs.rs:19:30: 19:35 (#0),
+ span: $DIR/inner-attrs.rs:20:30: 20:35 (#0),
},
],
- span: $DIR/inner-attrs.rs:19:29: 19:36 (#0),
+ span: $DIR/inner-attrs.rs:20:29: 20:36 (#0),
},
],
- span: $DIR/inner-attrs.rs:19:7: 19:37 (#0),
+ span: $DIR/inner-attrs.rs:20:7: 20:37 (#0),
},
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:20:5: 20:6 (#0),
+ span: $DIR/inner-attrs.rs:21:5: 21:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:20:6: 20:7 (#0),
+ span: $DIR/inner-attrs.rs:21:6: 21:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:20:8: 20:29 (#0),
+ span: $DIR/inner-attrs.rs:21:8: 21:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "fourth",
- span: $DIR/inner-attrs.rs:20:30: 20:36 (#0),
+ span: $DIR/inner-attrs.rs:21:30: 21:36 (#0),
},
],
- span: $DIR/inner-attrs.rs:20:29: 20:37 (#0),
+ span: $DIR/inner-attrs.rs:21:29: 21:37 (#0),
},
],
- span: $DIR/inner-attrs.rs:20:7: 20:38 (#0),
+ span: $DIR/inner-attrs.rs:21:7: 21:38 (#0),
},
],
- span: $DIR/inner-attrs.rs:18:10: 21:2 (#0),
+ span: $DIR/inner-attrs.rs:19:10: 22:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): third
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "third",
- span: $DIR/inner-attrs.rs:19:30: 19:35 (#0),
+ span: $DIR/inner-attrs.rs:20:30: 20:35 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): fn foo() { #! [print_target_and_args(fourth)] }
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "fn",
- span: $DIR/inner-attrs.rs:18:1: 18:3 (#0),
+ span: $DIR/inner-attrs.rs:19:1: 19:3 (#0),
},
Ident {
ident: "foo",
- span: $DIR/inner-attrs.rs:18:4: 18:7 (#0),
+ span: $DIR/inner-attrs.rs:19:4: 19:7 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:18:7: 18:9 (#0),
+ span: $DIR/inner-attrs.rs:19:7: 19:9 (#0),
},
Group {
delimiter: Brace,
@@ -231,70 +231,70 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:20:5: 20:6 (#0),
+ span: $DIR/inner-attrs.rs:21:5: 21:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:20:6: 20:7 (#0),
+ span: $DIR/inner-attrs.rs:21:6: 21:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:20:8: 20:29 (#0),
+ span: $DIR/inner-attrs.rs:21:8: 21:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "fourth",
- span: $DIR/inner-attrs.rs:20:30: 20:36 (#0),
+ span: $DIR/inner-attrs.rs:21:30: 21:36 (#0),
},
],
- span: $DIR/inner-attrs.rs:20:29: 20:37 (#0),
+ span: $DIR/inner-attrs.rs:21:29: 21:37 (#0),
},
],
- span: $DIR/inner-attrs.rs:20:7: 20:38 (#0),
+ span: $DIR/inner-attrs.rs:21:7: 21:38 (#0),
},
],
- span: $DIR/inner-attrs.rs:18:10: 21:2 (#0),
+ span: $DIR/inner-attrs.rs:19:10: 22:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): fourth
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "fourth",
- span: $DIR/inner-attrs.rs:20:30: 20:36 (#0),
+ span: $DIR/inner-attrs.rs:21:30: 21:36 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): fn foo() {}
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "fn",
- span: $DIR/inner-attrs.rs:18:1: 18:3 (#0),
+ span: $DIR/inner-attrs.rs:19:1: 19:3 (#0),
},
Ident {
ident: "foo",
- span: $DIR/inner-attrs.rs:18:4: 18:7 (#0),
+ span: $DIR/inner-attrs.rs:19:4: 19:7 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:18:7: 18:9 (#0),
+ span: $DIR/inner-attrs.rs:19:7: 19:9 (#0),
},
Group {
delimiter: Brace,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:18:10: 21:2 (#0),
+ span: $DIR/inner-attrs.rs:19:10: 22:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): mod_first
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "mod_first",
- span: $DIR/inner-attrs.rs:23:25: 23:34 (#0),
+ span: $DIR/inner-attrs.rs:24:25: 24:34 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(mod_second)] mod inline_mod
@@ -306,35 +306,35 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Alone,
- span: $DIR/inner-attrs.rs:24:1: 24:2 (#0),
+ span: $DIR/inner-attrs.rs:25:1: 25:2 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:24:3: 24:24 (#0),
+ span: $DIR/inner-attrs.rs:25:3: 25:24 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "mod_second",
- span: $DIR/inner-attrs.rs:24:25: 24:35 (#0),
+ span: $DIR/inner-attrs.rs:25:25: 25:35 (#0),
},
],
- span: $DIR/inner-attrs.rs:24:24: 24:36 (#0),
+ span: $DIR/inner-attrs.rs:25:24: 25:36 (#0),
},
],
- span: $DIR/inner-attrs.rs:24:2: 24:37 (#0),
+ span: $DIR/inner-attrs.rs:25:2: 25:37 (#0),
},
Ident {
ident: "mod",
- span: $DIR/inner-attrs.rs:25:1: 25:4 (#0),
+ span: $DIR/inner-attrs.rs:26:1: 26:4 (#0),
},
Ident {
ident: "inline_mod",
- span: $DIR/inner-attrs.rs:25:5: 25:15 (#0),
+ span: $DIR/inner-attrs.rs:26:5: 26:15 (#0),
},
Group {
delimiter: Brace,
@@ -342,72 +342,72 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:26:5: 26:6 (#0),
+ span: $DIR/inner-attrs.rs:27:5: 27:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:26:6: 26:7 (#0),
+ span: $DIR/inner-attrs.rs:27:6: 27:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:26:8: 26:29 (#0),
+ span: $DIR/inner-attrs.rs:27:8: 27:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "mod_third",
- span: $DIR/inner-attrs.rs:26:30: 26:39 (#0),
+ span: $DIR/inner-attrs.rs:27:30: 27:39 (#0),
},
],
- span: $DIR/inner-attrs.rs:26:29: 26:40 (#0),
+ span: $DIR/inner-attrs.rs:27:29: 27:40 (#0),
},
],
- span: $DIR/inner-attrs.rs:26:7: 26:41 (#0),
+ span: $DIR/inner-attrs.rs:27:7: 27:41 (#0),
},
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:27:5: 27:6 (#0),
+ span: $DIR/inner-attrs.rs:28:5: 28:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:27:6: 27:7 (#0),
+ span: $DIR/inner-attrs.rs:28:6: 28:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:27:8: 27:29 (#0),
+ span: $DIR/inner-attrs.rs:28:8: 28:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "mod_fourth",
- span: $DIR/inner-attrs.rs:27:30: 27:40 (#0),
+ span: $DIR/inner-attrs.rs:28:30: 28:40 (#0),
},
],
- span: $DIR/inner-attrs.rs:27:29: 27:41 (#0),
+ span: $DIR/inner-attrs.rs:28:29: 28:41 (#0),
},
],
- span: $DIR/inner-attrs.rs:27:7: 27:42 (#0),
+ span: $DIR/inner-attrs.rs:28:7: 28:42 (#0),
},
],
- span: $DIR/inner-attrs.rs:25:16: 28:2 (#0),
+ span: $DIR/inner-attrs.rs:26:16: 29:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): mod_second
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "mod_second",
- span: $DIR/inner-attrs.rs:24:25: 24:35 (#0),
+ span: $DIR/inner-attrs.rs:25:25: 25:35 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): mod inline_mod
@@ -418,11 +418,11 @@ PRINT-ATTR INPUT (DISPLAY): mod inline_mod
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "mod",
- span: $DIR/inner-attrs.rs:25:1: 25:4 (#0),
+ span: $DIR/inner-attrs.rs:26:1: 26:4 (#0),
},
Ident {
ident: "inline_mod",
- span: $DIR/inner-attrs.rs:25:5: 25:15 (#0),
+ span: $DIR/inner-attrs.rs:26:5: 26:15 (#0),
},
Group {
delimiter: Brace,
@@ -430,83 +430,83 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:26:5: 26:6 (#0),
+ span: $DIR/inner-attrs.rs:27:5: 27:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:26:6: 26:7 (#0),
+ span: $DIR/inner-attrs.rs:27:6: 27:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:26:8: 26:29 (#0),
+ span: $DIR/inner-attrs.rs:27:8: 27:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "mod_third",
- span: $DIR/inner-attrs.rs:26:30: 26:39 (#0),
+ span: $DIR/inner-attrs.rs:27:30: 27:39 (#0),
},
],
- span: $DIR/inner-attrs.rs:26:29: 26:40 (#0),
+ span: $DIR/inner-attrs.rs:27:29: 27:40 (#0),
},
],
- span: $DIR/inner-attrs.rs:26:7: 26:41 (#0),
+ span: $DIR/inner-attrs.rs:27:7: 27:41 (#0),
},
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:27:5: 27:6 (#0),
+ span: $DIR/inner-attrs.rs:28:5: 28:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:27:6: 27:7 (#0),
+ span: $DIR/inner-attrs.rs:28:6: 28:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:27:8: 27:29 (#0),
+ span: $DIR/inner-attrs.rs:28:8: 28:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "mod_fourth",
- span: $DIR/inner-attrs.rs:27:30: 27:40 (#0),
+ span: $DIR/inner-attrs.rs:28:30: 28:40 (#0),
},
],
- span: $DIR/inner-attrs.rs:27:29: 27:41 (#0),
+ span: $DIR/inner-attrs.rs:28:29: 28:41 (#0),
},
],
- span: $DIR/inner-attrs.rs:27:7: 27:42 (#0),
+ span: $DIR/inner-attrs.rs:28:7: 28:42 (#0),
},
],
- span: $DIR/inner-attrs.rs:25:16: 28:2 (#0),
+ span: $DIR/inner-attrs.rs:26:16: 29:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): mod_third
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "mod_third",
- span: $DIR/inner-attrs.rs:26:30: 26:39 (#0),
+ span: $DIR/inner-attrs.rs:27:30: 27:39 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): mod inline_mod { #! [print_target_and_args(mod_fourth)] }
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "mod",
- span: $DIR/inner-attrs.rs:25:1: 25:4 (#0),
+ span: $DIR/inner-attrs.rs:26:1: 26:4 (#0),
},
Ident {
ident: "inline_mod",
- span: $DIR/inner-attrs.rs:25:5: 25:15 (#0),
+ span: $DIR/inner-attrs.rs:26:5: 26:15 (#0),
},
Group {
delimiter: Brace,
@@ -514,58 +514,58 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:27:5: 27:6 (#0),
+ span: $DIR/inner-attrs.rs:28:5: 28:6 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:27:6: 27:7 (#0),
+ span: $DIR/inner-attrs.rs:28:6: 28:7 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "print_target_and_args",
- span: $DIR/inner-attrs.rs:27:8: 27:29 (#0),
+ span: $DIR/inner-attrs.rs:28:8: 28:29 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "mod_fourth",
- span: $DIR/inner-attrs.rs:27:30: 27:40 (#0),
+ span: $DIR/inner-attrs.rs:28:30: 28:40 (#0),
},
],
- span: $DIR/inner-attrs.rs:27:29: 27:41 (#0),
+ span: $DIR/inner-attrs.rs:28:29: 28:41 (#0),
},
],
- span: $DIR/inner-attrs.rs:27:7: 27:42 (#0),
+ span: $DIR/inner-attrs.rs:28:7: 28:42 (#0),
},
],
- span: $DIR/inner-attrs.rs:25:16: 28:2 (#0),
+ span: $DIR/inner-attrs.rs:26:16: 29:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): mod_fourth
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "mod_fourth",
- span: $DIR/inner-attrs.rs:27:30: 27:40 (#0),
+ span: $DIR/inner-attrs.rs:28:30: 28:40 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): mod inline_mod {}
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "mod",
- span: $DIR/inner-attrs.rs:25:1: 25:4 (#0),
+ span: $DIR/inner-attrs.rs:26:1: 26:4 (#0),
},
Ident {
ident: "inline_mod",
- span: $DIR/inner-attrs.rs:25:5: 25:15 (#0),
+ span: $DIR/inner-attrs.rs:26:5: 26:15 (#0),
},
Group {
delimiter: Brace,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:25:16: 28:2 (#0),
+ span: $DIR/inner-attrs.rs:26:16: 29:2 (#0),
},
]
PRINT-DERIVE INPUT (DISPLAY): struct MyDerivePrint
@@ -576,63 +576,63 @@ PRINT-DERIVE INPUT (DISPLAY): struct MyDerivePrint
PRINT-DERIVE INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
- span: $DIR/inner-attrs.rs:35:1: 35:7 (#0),
+ span: $DIR/inner-attrs.rs:36:1: 36:7 (#0),
},
Ident {
ident: "MyDerivePrint",
- span: $DIR/inner-attrs.rs:35:8: 35:21 (#0),
+ span: $DIR/inner-attrs.rs:36:8: 36:21 (#0),
},
Group {
delimiter: Brace,
stream: TokenStream [
Ident {
ident: "field",
- span: $DIR/inner-attrs.rs:36:5: 36:10 (#0),
+ span: $DIR/inner-attrs.rs:37:5: 37:10 (#0),
},
Punct {
ch: ':',
spacing: Alone,
- span: $DIR/inner-attrs.rs:36:10: 36:11 (#0),
+ span: $DIR/inner-attrs.rs:37:10: 37:11 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "u8",
- span: $DIR/inner-attrs.rs:36:13: 36:15 (#0),
+ span: $DIR/inner-attrs.rs:37:13: 37:15 (#0),
},
Punct {
ch: ';',
spacing: Alone,
- span: $DIR/inner-attrs.rs:36:15: 36:16 (#0),
+ span: $DIR/inner-attrs.rs:37:15: 37:16 (#0),
},
Group {
delimiter: Brace,
stream: TokenStream [
Ident {
ident: "match",
- span: $DIR/inner-attrs.rs:37:9: 37:14 (#0),
+ span: $DIR/inner-attrs.rs:38:9: 38:14 (#0),
},
Ident {
ident: "true",
- span: $DIR/inner-attrs.rs:37:15: 37:19 (#0),
+ span: $DIR/inner-attrs.rs:38:15: 38:19 (#0),
},
Group {
delimiter: Brace,
stream: TokenStream [
Ident {
ident: "_",
- span: $DIR/inner-attrs.rs:38:13: 38:14 (#0),
+ span: $DIR/inner-attrs.rs:39:13: 39:14 (#0),
},
Punct {
ch: '=',
spacing: Joint,
- span: $DIR/inner-attrs.rs:38:15: 38:17 (#0),
+ span: $DIR/inner-attrs.rs:39:15: 39:17 (#0),
},
Punct {
ch: '>',
spacing: Alone,
- span: $DIR/inner-attrs.rs:38:15: 38:17 (#0),
+ span: $DIR/inner-attrs.rs:39:15: 39:17 (#0),
},
Group {
delimiter: Brace,
@@ -640,69 +640,69 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Alone,
- span: $DIR/inner-attrs.rs:39:17: 39:18 (#0),
+ span: $DIR/inner-attrs.rs:40:17: 40:18 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:39:18: 39:19 (#0),
+ span: $DIR/inner-attrs.rs:40:18: 40:19 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "rustc_dummy",
- span: $DIR/inner-attrs.rs:39:41: 39:52 (#0),
+ span: $DIR/inner-attrs.rs:40:41: 40:52 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "third",
- span: $DIR/inner-attrs.rs:39:53: 39:58 (#0),
+ span: $DIR/inner-attrs.rs:40:53: 40:58 (#0),
},
],
- span: $DIR/inner-attrs.rs:39:52: 39:59 (#0),
+ span: $DIR/inner-attrs.rs:40:52: 40:59 (#0),
},
],
- span: $DIR/inner-attrs.rs:39:17: 39:18 (#0),
+ span: $DIR/inner-attrs.rs:40:17: 40:18 (#0),
},
Ident {
ident: "true",
- span: $DIR/inner-attrs.rs:40:17: 40:21 (#0),
+ span: $DIR/inner-attrs.rs:41:17: 41:21 (#0),
},
],
- span: $DIR/inner-attrs.rs:38:18: 41:14 (#0),
+ span: $DIR/inner-attrs.rs:39:18: 42:14 (#0),
},
],
- span: $DIR/inner-attrs.rs:37:20: 42:10 (#0),
+ span: $DIR/inner-attrs.rs:38:20: 43:10 (#0),
},
Punct {
ch: ';',
spacing: Alone,
- span: $DIR/inner-attrs.rs:42:10: 42:11 (#0),
+ span: $DIR/inner-attrs.rs:43:10: 43:11 (#0),
},
Literal {
kind: Integer,
symbol: "0",
suffix: None,
- span: $DIR/inner-attrs.rs:43:9: 43:10 (#0),
+ span: $DIR/inner-attrs.rs:44:9: 44:10 (#0),
},
],
- span: $DIR/inner-attrs.rs:36:17: 44:6 (#0),
+ span: $DIR/inner-attrs.rs:37:17: 45:6 (#0),
},
],
- span: $DIR/inner-attrs.rs:36:12: 44:7 (#0),
+ span: $DIR/inner-attrs.rs:37:12: 45:7 (#0),
},
],
- span: $DIR/inner-attrs.rs:35:22: 45:2 (#0),
+ span: $DIR/inner-attrs.rs:36:22: 46:2 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): tuple_attrs
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "tuple_attrs",
- span: $DIR/inner-attrs.rs:48:29: 48:40 (#0),
+ span: $DIR/inner-attrs.rs:49:29: 49:40 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
@@ -714,23 +714,23 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
kind: Integer,
symbol: "3",
suffix: None,
- span: $DIR/inner-attrs.rs:49:9: 49:10 (#0),
+ span: $DIR/inner-attrs.rs:50:9: 50:10 (#0),
},
Punct {
ch: ',',
spacing: Alone,
- span: $DIR/inner-attrs.rs:49:10: 49:11 (#0),
+ span: $DIR/inner-attrs.rs:50:10: 50:11 (#0),
},
Literal {
kind: Integer,
symbol: "4",
suffix: None,
- span: $DIR/inner-attrs.rs:49:12: 49:13 (#0),
+ span: $DIR/inner-attrs.rs:50:12: 50:13 (#0),
},
Punct {
ch: ',',
spacing: Alone,
- span: $DIR/inner-attrs.rs:49:13: 49:14 (#0),
+ span: $DIR/inner-attrs.rs:50:13: 50:14 (#0),
},
Group {
delimiter: Brace,
@@ -738,85 +738,85 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:50:13: 50:14 (#0),
+ span: $DIR/inner-attrs.rs:51:13: 51:14 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:50:14: 50:15 (#0),
+ span: $DIR/inner-attrs.rs:51:14: 51:15 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "cfg_attr",
- span: $DIR/inner-attrs.rs:50:16: 50:24 (#0),
+ span: $DIR/inner-attrs.rs:51:16: 51:24 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "not",
- span: $DIR/inner-attrs.rs:50:25: 50:28 (#0),
+ span: $DIR/inner-attrs.rs:51:25: 51:28 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "FALSE",
- span: $DIR/inner-attrs.rs:50:29: 50:34 (#0),
+ span: $DIR/inner-attrs.rs:51:29: 51:34 (#0),
},
],
- span: $DIR/inner-attrs.rs:50:28: 50:35 (#0),
+ span: $DIR/inner-attrs.rs:51:28: 51:35 (#0),
},
Punct {
ch: ',',
spacing: Alone,
- span: $DIR/inner-attrs.rs:50:35: 50:36 (#0),
+ span: $DIR/inner-attrs.rs:51:35: 51:36 (#0),
},
Ident {
ident: "rustc_dummy",
- span: $DIR/inner-attrs.rs:50:37: 50:48 (#0),
+ span: $DIR/inner-attrs.rs:51:37: 51:48 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "innermost",
- span: $DIR/inner-attrs.rs:50:49: 50:58 (#0),
+ span: $DIR/inner-attrs.rs:51:49: 51:58 (#0),
},
],
- span: $DIR/inner-attrs.rs:50:48: 50:59 (#0),
+ span: $DIR/inner-attrs.rs:51:48: 51:59 (#0),
},
],
- span: $DIR/inner-attrs.rs:50:24: 50:60 (#0),
+ span: $DIR/inner-attrs.rs:51:24: 51:60 (#0),
},
],
- span: $DIR/inner-attrs.rs:50:15: 50:61 (#0),
+ span: $DIR/inner-attrs.rs:51:15: 51:61 (#0),
},
Literal {
kind: Integer,
symbol: "5",
suffix: None,
- span: $DIR/inner-attrs.rs:51:13: 51:14 (#0),
+ span: $DIR/inner-attrs.rs:52:13: 52:14 (#0),
},
],
- span: $DIR/inner-attrs.rs:49:15: 52:10 (#0),
+ span: $DIR/inner-attrs.rs:50:15: 53:10 (#0),
},
],
- span: $DIR/inner-attrs.rs:48:43: 53:6 (#0),
+ span: $DIR/inner-attrs.rs:49:43: 54:6 (#0),
},
Punct {
ch: ';',
spacing: Alone,
- span: $DIR/inner-attrs.rs:53:6: 53:7 (#0),
+ span: $DIR/inner-attrs.rs:54:6: 54:7 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): tuple_attrs
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "tuple_attrs",
- span: $DIR/inner-attrs.rs:55:29: 55:40 (#0),
+ span: $DIR/inner-attrs.rs:56:29: 56:40 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
@@ -828,23 +828,23 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
kind: Integer,
symbol: "3",
suffix: None,
- span: $DIR/inner-attrs.rs:56:9: 56:10 (#0),
+ span: $DIR/inner-attrs.rs:57:9: 57:10 (#0),
},
Punct {
ch: ',',
spacing: Alone,
- span: $DIR/inner-attrs.rs:56:10: 56:11 (#0),
+ span: $DIR/inner-attrs.rs:57:10: 57:11 (#0),
},
Literal {
kind: Integer,
symbol: "4",
suffix: None,
- span: $DIR/inner-attrs.rs:56:12: 56:13 (#0),
+ span: $DIR/inner-attrs.rs:57:12: 57:13 (#0),
},
Punct {
ch: ',',
spacing: Alone,
- span: $DIR/inner-attrs.rs:56:13: 56:14 (#0),
+ span: $DIR/inner-attrs.rs:57:13: 57:14 (#0),
},
Group {
delimiter: Brace,
@@ -852,105 +852,105 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct {
ch: '#',
spacing: Joint,
- span: $DIR/inner-attrs.rs:57:13: 57:14 (#0),
+ span: $DIR/inner-attrs.rs:58:13: 58:14 (#0),
},
Punct {
ch: '!',
spacing: Alone,
- span: $DIR/inner-attrs.rs:57:14: 57:15 (#0),
+ span: $DIR/inner-attrs.rs:58:14: 58:15 (#0),
},
Group {
delimiter: Bracket,
stream: TokenStream [
Ident {
ident: "cfg_attr",
- span: $DIR/inner-attrs.rs:57:16: 57:24 (#0),
+ span: $DIR/inner-attrs.rs:58:16: 58:24 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "not",
- span: $DIR/inner-attrs.rs:57:25: 57:28 (#0),
+ span: $DIR/inner-attrs.rs:58:25: 58:28 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "FALSE",
- span: $DIR/inner-attrs.rs:57:29: 57:34 (#0),
+ span: $DIR/inner-attrs.rs:58:29: 58:34 (#0),
},
],
- span: $DIR/inner-attrs.rs:57:28: 57:35 (#0),
+ span: $DIR/inner-attrs.rs:58:28: 58:35 (#0),
},
Punct {
ch: ',',
spacing: Alone,
- span: $DIR/inner-attrs.rs:57:35: 57:36 (#0),
+ span: $DIR/inner-attrs.rs:58:35: 58:36 (#0),
},
Ident {
ident: "rustc_dummy",
- span: $DIR/inner-attrs.rs:57:37: 57:48 (#0),
+ span: $DIR/inner-attrs.rs:58:37: 58:48 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "innermost",
- span: $DIR/inner-attrs.rs:57:49: 57:58 (#0),
+ span: $DIR/inner-attrs.rs:58:49: 58:58 (#0),
},
],
- span: $DIR/inner-attrs.rs:57:48: 57:59 (#0),
+ span: $DIR/inner-attrs.rs:58:48: 58:59 (#0),
},
],
- span: $DIR/inner-attrs.rs:57:24: 57:60 (#0),
+ span: $DIR/inner-attrs.rs:58:24: 58:60 (#0),
},
],
- span: $DIR/inner-attrs.rs:57:15: 57:61 (#0),
+ span: $DIR/inner-attrs.rs:58:15: 58:61 (#0),
},
Literal {
kind: Integer,
symbol: "5",
suffix: None,
- span: $DIR/inner-attrs.rs:58:13: 58:14 (#0),
+ span: $DIR/inner-attrs.rs:59:13: 59:14 (#0),
},
],
- span: $DIR/inner-attrs.rs:56:15: 59:10 (#0),
+ span: $DIR/inner-attrs.rs:57:15: 60:10 (#0),
},
],
- span: $DIR/inner-attrs.rs:55:43: 60:6 (#0),
+ span: $DIR/inner-attrs.rs:56:43: 61:6 (#0),
},
Punct {
ch: ';',
spacing: Alone,
- span: $DIR/inner-attrs.rs:60:6: 60:7 (#0),
+ span: $DIR/inner-attrs.rs:61:6: 61:7 (#0),
},
]
PRINT-ATTR_ARGS INPUT (DISPLAY): tenth
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
Ident {
ident: "tenth",
- span: $DIR/inner-attrs.rs:82:42: 82:47 (#0),
+ span: $DIR/inner-attrs.rs:83:42: 83:47 (#0),
},
]
PRINT-ATTR INPUT (DISPLAY): fn weird_extern() {}
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "fn",
- span: $DIR/inner-attrs.rs:81:5: 81:7 (#0),
+ span: $DIR/inner-attrs.rs:82:5: 82:7 (#0),
},
Ident {
ident: "weird_extern",
- span: $DIR/inner-attrs.rs:81:8: 81:20 (#0),
+ span: $DIR/inner-attrs.rs:82:8: 82:20 (#0),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:81:20: 81:22 (#0),
+ span: $DIR/inner-attrs.rs:82:20: 82:22 (#0),
},
Group {
delimiter: Brace,
stream: TokenStream [],
- span: $DIR/inner-attrs.rs:81:23: 83:6 (#0),
+ span: $DIR/inner-attrs.rs:82:23: 84:6 (#0),
},
]
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
index 814cd77cf..9a1802737 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
@@ -1,4 +1,5 @@
// aux-build:invalid-punct-ident.rs
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
index 7babe685b..78aa84401 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
@@ -1,5 +1,5 @@
error: proc macro panicked
- --> $DIR/invalid-punct-ident-1.rs:6:1
+ --> $DIR/invalid-punct-ident-1.rs:7:1
|
LL | invalid_punct!();
| ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
index a04dec707..afb6985e4 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
@@ -1,4 +1,5 @@
// aux-build:invalid-punct-ident.rs
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.stderr b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
index 01b80768c..66979e756 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
@@ -1,5 +1,5 @@
error: proc macro panicked
- --> $DIR/invalid-punct-ident-2.rs:6:1
+ --> $DIR/invalid-punct-ident-2.rs:7:1
|
LL | invalid_ident!();
| ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
index f0e953608..ff83695c5 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
@@ -1,4 +1,5 @@
// aux-build:invalid-punct-ident.rs
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
index 899c38158..c096bc8c0 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
@@ -1,5 +1,5 @@
error: proc macro panicked
- --> $DIR/invalid-punct-ident-3.rs:6:1
+ --> $DIR/invalid-punct-ident-3.rs:7:1
|
LL | invalid_raw_ident!();
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.rs b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
index 59b347dac..2d2774bd1 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
@@ -1,4 +1,5 @@
// aux-build:invalid-punct-ident.rs
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
index deb93b893..ab4116141 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
@@ -1,5 +1,5 @@
error: unexpected closing delimiter: `)`
- --> $DIR/invalid-punct-ident-4.rs:6:1
+ --> $DIR/invalid-punct-ident-4.rs:7:1
|
LL | lexer_failure!();
| ^^^^^^^^^^^^^^^^ unexpected closing delimiter
@@ -7,13 +7,13 @@ LL | lexer_failure!();
= note: this error originates in the macro `lexer_failure` (in Nightly builds, run with -Z macro-backtrace for more info)
error: proc macro panicked
- --> $DIR/invalid-punct-ident-4.rs:6:1
+ --> $DIR/invalid-punct-ident-4.rs:7:1
|
LL | lexer_failure!();
| ^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
- --> $DIR/invalid-punct-ident-4.rs:11:33
+ --> $DIR/invalid-punct-ident-4.rs:12:33
|
LL | let _recovery_witness: () = 0;
| -- ^ expected `()`, found integer
diff --git a/src/test/ui/proc-macro/issue-36935.rs b/src/test/ui/proc-macro/issue-36935.rs
index 5c43a564c..03cdfa05e 100644
--- a/src/test/ui/proc-macro/issue-36935.rs
+++ b/src/test/ui/proc-macro/issue-36935.rs
@@ -1,4 +1,5 @@
// aux-build:test-macros.rs
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate test_macros;
diff --git a/src/test/ui/proc-macro/issue-36935.stderr b/src/test/ui/proc-macro/issue-36935.stderr
index 079e134c6..122903798 100644
--- a/src/test/ui/proc-macro/issue-36935.stderr
+++ b/src/test/ui/proc-macro/issue-36935.stderr
@@ -1,5 +1,5 @@
error[E0428]: the name `Baz` is defined multiple times
- --> $DIR/issue-36935.rs:7:1
+ --> $DIR/issue-36935.rs:8:1
|
LL | struct Baz {
| ^^^^^^^^^^
@@ -10,7 +10,7 @@ LL | struct Baz {
= note: `Baz` must be defined only once in the type namespace of this module
error: proc-macro derive panicked
- --> $DIR/issue-36935.rs:6:20
+ --> $DIR/issue-36935.rs:7:20
|
LL | #[derive(Identity, Panic)]
| ^^^^^
diff --git a/src/test/ui/proc-macro/issue-41211.rs b/src/test/ui/proc-macro/issue-41211.rs
deleted file mode 100644
index 072a63baf..000000000
--- a/src/test/ui/proc-macro/issue-41211.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// aux-build:test-macros.rs
-
-// FIXME: https://github.com/rust-lang/rust/issues/41430
-// This is a temporary regression test for the ICE reported in #41211
-
-#![feature(custom_inner_attributes)]
-#![feature(register_attr)]
-
-#![register_attr(identity_attr)]
-
-#![identity_attr]
-//~^ ERROR `identity_attr` is ambiguous
-extern crate test_macros;
-use test_macros::identity_attr;
-
-fn main() {}
diff --git a/src/test/ui/proc-macro/issue-41211.stderr b/src/test/ui/proc-macro/issue-41211.stderr
deleted file mode 100644
index 60cd36a9c..000000000
--- a/src/test/ui/proc-macro/issue-41211.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0659]: `identity_attr` is ambiguous
- --> $DIR/issue-41211.rs:11:4
- |
-LL | #![identity_attr]
- | ^^^^^^^^^^^^^ ambiguous name
- |
- = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
-note: `identity_attr` could refer to the attribute macro imported here
- --> $DIR/issue-41211.rs:14:5
- |
-LL | use test_macros::identity_attr;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: use `crate::identity_attr` to refer to this attribute macro unambiguously
-note: `identity_attr` could also refer to the explicitly registered attribute defined here
- --> $DIR/issue-41211.rs:9:18
- |
-LL | #![register_attr(identity_attr)]
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs b/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs
index 98fa06b6e..5aefec3ec 100644
--- a/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs
+++ b/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.rs
@@ -1,5 +1,6 @@
// aux-build:proc-macro-panic.rs
// edition:2018
+// needs-unwind proc macro panics to report errors
// Regression test for issue #76270
// Tests that we don't print an ICE message when a panic
diff --git a/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.stderr b/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.stderr
index 1dc0f16bf..d69de23a4 100644
--- a/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.stderr
+++ b/src/test/ui/proc-macro/issue-76270-panic-in-libproc-macro.stderr
@@ -1,5 +1,5 @@
error: proc macro panicked
- --> $DIR/issue-76270-panic-in-libproc-macro.rs:10:1
+ --> $DIR/issue-76270-panic-in-libproc-macro.rs:11:1
|
LL | proc_macro_panic::panic_in_libproc_macro!();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/issue-79148.rs b/src/test/ui/proc-macro/issue-79148.rs
new file mode 100644
index 000000000..3f01187a8
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-79148.rs
@@ -0,0 +1,10 @@
+// aux-build:re-export.rs
+// edition:2018
+
+extern crate re_export;
+
+use re_export::cause_ice;
+
+cause_ice!(); //~ ERROR `Variant` is only public within the crate, and cannot be re-exported outside
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/issue-79148.stderr b/src/test/ui/proc-macro/issue-79148.stderr
new file mode 100644
index 000000000..a3b2de01d
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-79148.stderr
@@ -0,0 +1,16 @@
+error[E0364]: `Variant` is only public within the crate, and cannot be re-exported outside
+ --> $DIR/issue-79148.rs:8:1
+ |
+LL | cause_ice!();
+ | ^^^^^^^^^^^^
+ |
+note: consider marking `Variant` as `pub` in the imported module
+ --> $DIR/issue-79148.rs:8:1
+ |
+LL | cause_ice!();
+ | ^^^^^^^^^^^^
+ = note: this error originates in the macro `cause_ice` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0364`.
diff --git a/src/test/ui/proc-macro/load-panic-backtrace.rs b/src/test/ui/proc-macro/load-panic-backtrace.rs
index cd6f70a55..bcdcb704a 100644
--- a/src/test/ui/proc-macro/load-panic-backtrace.rs
+++ b/src/test/ui/proc-macro/load-panic-backtrace.rs
@@ -3,6 +3,7 @@
// rustc-env:RUST_BACKTRACE=0
// normalize-stderr-test "thread '.*' panicked " -> ""
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate test_macros;
diff --git a/src/test/ui/proc-macro/load-panic-backtrace.stderr b/src/test/ui/proc-macro/load-panic-backtrace.stderr
index cef5786d1..45d4fd1c9 100644
--- a/src/test/ui/proc-macro/load-panic-backtrace.stderr
+++ b/src/test/ui/proc-macro/load-panic-backtrace.stderr
@@ -1,6 +1,6 @@
at 'panic-derive', $DIR/auxiliary/test-macros.rs:43:5
error: proc-macro derive panicked
- --> $DIR/load-panic-backtrace.rs:10:10
+ --> $DIR/load-panic-backtrace.rs:11:10
|
LL | #[derive(Panic)]
| ^^^^^
diff --git a/src/test/ui/proc-macro/load-panic.rs b/src/test/ui/proc-macro/load-panic.rs
index 2e9a311d8..6ce88c400 100644
--- a/src/test/ui/proc-macro/load-panic.rs
+++ b/src/test/ui/proc-macro/load-panic.rs
@@ -1,4 +1,5 @@
// aux-build:test-macros.rs
+// needs-unwind proc macro panics to report errors
#[macro_use]
extern crate test_macros;
diff --git a/src/test/ui/proc-macro/load-panic.stderr b/src/test/ui/proc-macro/load-panic.stderr
index 40cc4ee0e..f0d62f690 100644
--- a/src/test/ui/proc-macro/load-panic.stderr
+++ b/src/test/ui/proc-macro/load-panic.stderr
@@ -1,5 +1,5 @@
error: proc-macro derive panicked
- --> $DIR/load-panic.rs:6:10
+ --> $DIR/load-panic.rs:7:10
|
LL | #[derive(Panic)]
| ^^^^^
diff --git a/src/test/ui/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr
index a6bd98ddb..59b3e44c7 100644
--- a/src/test/ui/proc-macro/signature.stderr
+++ b/src/test/ui/proc-macro/signature.stderr
@@ -5,9 +5,12 @@ LL | / pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 {
LL | |
LL | | loop {}
LL | | }
- | |_^ call the function in a closure: `|| unsafe { /* code */ }`
+ | | ^
+ | | |
+ | |_call the function in a closure: `|| unsafe { /* code */ }`
+ | required by a bound introduced by this call
|
- = help: the trait `Fn<(proc_macro::TokenStream,)>` is not implemented for `unsafe extern "C" fn(i32, u32) -> u32 {foo}`
+ = help: the trait `Fn<(proc_macro::TokenStream,)>` is not implemented for fn item `unsafe extern "C" fn(i32, u32) -> u32 {foo}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `ProcMacro::custom_derive`
--> $SRC_DIR/proc_macro/src/bridge/client.rs:LL:COL
diff --git a/src/test/ui/process/core-run-destroy.rs b/src/test/ui/process/core-run-destroy.rs
index 5fd418e6c..d0e97bf01 100644
--- a/src/test/ui/process/core-run-destroy.rs
+++ b/src/test/ui/process/core-run-destroy.rs
@@ -8,6 +8,7 @@
// ignore-emscripten no processes
// ignore-sgx no processes
// ignore-vxworks no 'cat' and 'sleep'
+// ignore-fuchsia no 'cat'
// N.B., these tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
diff --git a/src/test/ui/process/process-envs.rs b/src/test/ui/process/process-envs.rs
index 8fc99b23f..f3a469791 100644
--- a/src/test/ui/process/process-envs.rs
+++ b/src/test/ui/process/process-envs.rs
@@ -2,6 +2,7 @@
// ignore-emscripten no processes
// ignore-sgx no processes
// ignore-vxworks no 'env'
+// ignore-fuchsia no 'env'
use std::process::Command;
use std::env;
diff --git a/src/test/ui/process/process-remove-from-env.rs b/src/test/ui/process/process-remove-from-env.rs
index af4e49dfd..ad027d685 100644
--- a/src/test/ui/process/process-remove-from-env.rs
+++ b/src/test/ui/process/process-remove-from-env.rs
@@ -2,6 +2,7 @@
// ignore-emscripten no processes
// ignore-sgx no processes
// ignore-vxworks no 'env'
+// ignore-fuchsia no 'env'
use std::process::Command;
use std::env;
diff --git a/src/test/ui/process/process-sigpipe.rs b/src/test/ui/process/process-sigpipe.rs
index ecf5e93c9..107eba45d 100644
--- a/src/test/ui/process/process-sigpipe.rs
+++ b/src/test/ui/process/process-sigpipe.rs
@@ -14,6 +14,7 @@
// ignore-emscripten no threads support
// ignore-vxworks no 'sh'
+// ignore-fuchsia no 'sh'
use std::process;
use std::thread;
diff --git a/src/test/ui/ptr_ops/issue-80309-safe.rs b/src/test/ui/ptr_ops/issue-80309-safe.rs
index f7513b6b8..8a4ff1669 100644
--- a/src/test/ui/ptr_ops/issue-80309-safe.rs
+++ b/src/test/ui/ptr_ops/issue-80309-safe.rs
@@ -1,5 +1,4 @@
// run-pass
-// min-llvm-version: 13.0
// compile-flags: -O
// Regression test for issue #80309
diff --git a/src/test/ui/ptr_ops/issue-80309.rs b/src/test/ui/ptr_ops/issue-80309.rs
index 5c0f4b76c..c13ce3c9c 100644
--- a/src/test/ui/ptr_ops/issue-80309.rs
+++ b/src/test/ui/ptr_ops/issue-80309.rs
@@ -1,5 +1,4 @@
// run-pass
-// min-llvm-version: 13.0
// compile-flags: -O
// Regression test for issue #80309
diff --git a/src/test/ui/range/range-1.stderr b/src/test/ui/range/range-1.stderr
index 0bbed8704..aaea91ce0 100644
--- a/src/test/ui/range/range-1.stderr
+++ b/src/test/ui/range/range-1.stderr
@@ -20,14 +20,14 @@ LL | for i in false..true {}
isize
u128
and 5 others
- = note: required because of the requirements on the impl of `Iterator` for `std::ops::Range<bool>`
- = note: required because of the requirements on the impl of `IntoIterator` for `std::ops::Range<bool>`
+ = note: required for `std::ops::Range<bool>` to implement `Iterator`
+ = note: required for `std::ops::Range<bool>` to implement `IntoIterator`
error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
--> $DIR/range-1.rs:14:17
|
LL | let range = *arr..;
- | ^^^^^^ doesn't have a size known at compile-time
+ | ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[{integer}]`
note: required by a bound in `RangeFrom`
diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr
index 89a832984..32f25faf3 100644
--- a/src/test/ui/recursion/issue-83150.stderr
+++ b/src/test/ui/recursion/issue-83150.stderr
@@ -9,10 +9,12 @@ LL | func(&mut iter.map(|x| x + 1))
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose
-error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>: Iterator`
+error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
- = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>`
+ = note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+ = note: 64 redundant requirements hidden
+ = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/recursion/issue-95134.rs b/src/test/ui/recursion/issue-95134.rs
new file mode 100644
index 000000000..adc9c6ee2
--- /dev/null
+++ b/src/test/ui/recursion/issue-95134.rs
@@ -0,0 +1,28 @@
+// build-fail
+// compile-flags: -Copt-level=0
+//~^^ ERROR overflow evaluating the requirement
+
+pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
+ if n > 15 {
+ encode_num(n / 16, &mut writer)?;
+ }
+ Ok(())
+}
+
+pub trait ExampleWriter {
+ type Error;
+}
+
+impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T {
+ type Error = T::Error;
+}
+
+struct EmptyWriter;
+
+impl ExampleWriter for EmptyWriter {
+ type Error = ();
+}
+
+fn main() {
+ encode_num(69, &mut EmptyWriter).unwrap();
+}
diff --git a/src/test/ui/recursion/issue-95134.stderr b/src/test/ui/recursion/issue-95134.stderr
new file mode 100644
index 000000000..57a498694
--- /dev/null
+++ b/src/test/ui/recursion/issue-95134.stderr
@@ -0,0 +1,7 @@
+error[E0275]: overflow evaluating the requirement `<EmptyWriter as ExampleWriter>::Error`
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95134`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index acbd0d059..321ee0a36 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -19,7 +19,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let x = if let Ok(x) = res { x } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Ok(x) = res else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.rs b/src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.rs
new file mode 100644
index 000000000..a1e801e39
--- /dev/null
+++ b/src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.rs
@@ -0,0 +1,12 @@
+pub trait T {}
+
+struct S<'a>(&'a ());
+
+impl<'a> T for S<'a> {}
+
+fn foo() -> impl T {
+ let x = ();
+ S(&x) //~ ERROR `x` does not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr b/src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr
new file mode 100644
index 000000000..6ea238f30
--- /dev/null
+++ b/src/test/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/do-not-suggest-adding-bound-to-opaque-type.rs:9:7
+ |
+LL | S(&x)
+ | --^^-
+ | | |
+ | | borrowed value does not live long enough
+ | opaque type requires that `x` is borrowed for `'static`
+LL | }
+ | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
index bdd1ae91f..a8f7a41c4 100644
--- a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
+++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
@@ -5,7 +5,7 @@
// by the function.
//
// This works today, which precludes changing things so that closures
-// follow the same lifetime-elision rules used elsehwere. See
+// follow the same lifetime-elision rules used elsewhere. See
// rust-lang/rust#56537
// check-pass
diff --git a/src/test/ui/regions/outlives-with-missing.rs b/src/test/ui/regions/outlives-with-missing.rs
new file mode 100644
index 000000000..29d89718b
--- /dev/null
+++ b/src/test/ui/regions/outlives-with-missing.rs
@@ -0,0 +1,16 @@
+trait HandlerFamily {
+ type Target;
+}
+
+struct HandlerWrapper<H: HandlerFamily>(H);
+
+impl<H: HandlerFamily> HandlerWrapper<H> {
+ pub fn set_handler(&self, handler: &H::Target)
+ where
+ T: Send + Sync + 'static,
+ //~^ ERROR cannot find type `T` in this scope
+ {
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/outlives-with-missing.stderr b/src/test/ui/regions/outlives-with-missing.stderr
new file mode 100644
index 000000000..e204c9187
--- /dev/null
+++ b/src/test/ui/regions/outlives-with-missing.stderr
@@ -0,0 +1,12 @@
+error[E0412]: cannot find type `T` in this scope
+ --> $DIR/outlives-with-missing.rs:10:9
+ |
+LL | impl<H: HandlerFamily> HandlerWrapper<H> {
+ | - similarly named type parameter `H` defined here
+...
+LL | T: Send + Sync + 'static,
+ | ^ help: a type parameter with a similar name exists: `H`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
index c1dab6086..110635203 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
@@ -19,7 +19,8 @@ trait Trait2<'a, 'b> {
// since for it to be WF, we would need to know that `'y: 'x`, but we
// do not infer that.
fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
- //~^ the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
+ //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
+ //~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
{
}
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
index 6844e8665..66f592c34 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
@@ -1,4 +1,19 @@
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
+ --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
+ |
+LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
+LL | |
+LL | |
+LL | | {
+LL | | }
+ | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
+ | ++++++++++++++++++++++++
+
+error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
@@ -9,6 +24,6 @@ help: consider restricting type parameter `T`
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ++++++++++++++++++++++++
-error: aborting due to previous error
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr
index 360557fb5..f78f1d822 100644
--- a/src/test/ui/reify-intrinsic.stderr
+++ b/src/test/ui/reify-intrinsic.stderr
@@ -23,6 +23,9 @@ LL | std::intrinsics::unlikely,
|
= note: expected fn item `extern "rust-intrinsic" fn(_) -> _ {likely}`
found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
+ = note: different `fn` items always have unique types, even if their signatures are the same
+ = help: change the expected type to be function pointer `extern "rust-intrinsic" fn(bool) -> bool`
+ = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `likely as extern "rust-intrinsic" fn(bool) -> bool`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/repr/invalid_repr_list_help.rs b/src/test/ui/repr/invalid_repr_list_help.rs
new file mode 100644
index 000000000..c32098453
--- /dev/null
+++ b/src/test/ui/repr/invalid_repr_list_help.rs
@@ -0,0 +1,17 @@
+#![crate_type = "lib"]
+
+#[repr(uwu)] //~ERROR: unrecognized representation hint
+pub struct OwO;
+
+#[repr(uwu = "a")] //~ERROR: unrecognized representation hint
+pub struct OwO2(i32);
+
+#[repr(uwu(4))] //~ERROR: unrecognized representation hint
+pub struct OwO3 {
+ x: i32,
+}
+
+#[repr(uwu, u8)] //~ERROR: unrecognized representation hint
+pub enum OwO4 {
+ UwU = 1,
+}
diff --git a/src/test/ui/repr/invalid_repr_list_help.stderr b/src/test/ui/repr/invalid_repr_list_help.stderr
new file mode 100644
index 000000000..2acd56d9a
--- /dev/null
+++ b/src/test/ui/repr/invalid_repr_list_help.stderr
@@ -0,0 +1,35 @@
+error[E0552]: unrecognized representation hint
+ --> $DIR/invalid_repr_list_help.rs:3:8
+ |
+LL | #[repr(uwu)]
+ | ^^^
+ |
+ = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error[E0552]: unrecognized representation hint
+ --> $DIR/invalid_repr_list_help.rs:6:8
+ |
+LL | #[repr(uwu = "a")]
+ | ^^^^^^^^^
+ |
+ = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error[E0552]: unrecognized representation hint
+ --> $DIR/invalid_repr_list_help.rs:9:8
+ |
+LL | #[repr(uwu(4))]
+ | ^^^^^^
+ |
+ = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error[E0552]: unrecognized representation hint
+ --> $DIR/invalid_repr_list_help.rs:14:8
+ |
+LL | #[repr(uwu, u8)]
+ | ^^^
+ |
+ = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0552`.
diff --git a/src/test/ui/resolve/bad-type-env-capture.stderr b/src/test/ui/resolve/bad-type-env-capture.stderr
index 6f24c0d86..b6282c2d0 100644
--- a/src/test/ui/resolve/bad-type-env-capture.stderr
+++ b/src/test/ui/resolve/bad-type-env-capture.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
LL | fn foo<T>() {
| - type parameter from outer function
LL | fn bar(b: T) { }
- | --- ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `bar<T>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<T>`
error: aborting due to previous error
diff --git a/src/test/ui/resolve/issue-100365.rs b/src/test/ui/resolve/issue-100365.rs
new file mode 100644
index 000000000..1d8835036
--- /dev/null
+++ b/src/test/ui/resolve/issue-100365.rs
@@ -0,0 +1,50 @@
+fn main() {
+ let addr = Into::<std::net::IpAddr>.into([127, 0, 0, 1]);
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+
+ let _ = Into.into(());
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+
+ let _ = Into::<()>.into;
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+}
+
+macro_rules! Trait {
+ () => {
+ ::std::iter::Iterator
+ //~^ ERROR expected value, found trait `std::iter::Iterator`
+ //~| ERROR expected value, found trait `std::iter::Iterator`
+ };
+}
+
+macro_rules! create {
+ () => {
+ Into::<String>.into("")
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+ };
+}
+
+fn interaction_with_macros() {
+ //
+ // Note that if the receiver is a macro call, we do not want to suggest to replace
+ // `.` with `::` as that would be a syntax error.
+ // Since the receiver is a trait and not a type, we cannot suggest to surround
+ // it with angle brackets. It would be interpreted as a trait object type void of
+ // `dyn` which is most likely not what the user intended to write.
+ // `<_ as Trait!()>::` is also not an option as it's equally syntactically invalid.
+ //
+
+ Trait!().map(std::convert::identity); // no `help` here!
+
+ Trait!().map; // no `help` here!
+
+ //
+ // Ensure that the suggestion is shown for expressions inside of macro definitions.
+ //
+
+ let _ = create!();
+}
diff --git a/src/test/ui/resolve/issue-100365.stderr b/src/test/ui/resolve/issue-100365.stderr
new file mode 100644
index 000000000..372d77266
--- /dev/null
+++ b/src/test/ui/resolve/issue-100365.stderr
@@ -0,0 +1,54 @@
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:2:16
+ |
+LL | let addr = Into::<std::net::IpAddr>.into([127, 0, 0, 1]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:6:13
+ |
+LL | let _ = Into.into(());
+ | ^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:10:13
+ |
+LL | let _ = Into::<()>.into;
+ | ^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `std::iter::Iterator`
+ --> $DIR/issue-100365.rs:17:9
+ |
+LL | ::std::iter::Iterator
+ | ^^^^^^^^^^^^^^^^^^^^^ not a value
+...
+LL | Trait!().map(std::convert::identity); // no `help` here!
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `Trait` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `std::iter::Iterator`
+ --> $DIR/issue-100365.rs:17:9
+ |
+LL | ::std::iter::Iterator
+ | ^^^^^^^^^^^^^^^^^^^^^ not a value
+...
+LL | Trait!().map; // no `help` here!
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `Trait` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:25:9
+ |
+LL | Into::<String>.into("")
+ | ^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!();
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/resolve/issue-22692.rs b/src/test/ui/resolve/issue-22692.rs
index 1d8f44222..31a762614 100644
--- a/src/test/ui/resolve/issue-22692.rs
+++ b/src/test/ui/resolve/issue-22692.rs
@@ -1,3 +1,60 @@
fn main() {
- let _ = String.new(); //~ ERROR expected value, found struct `String`
+ let _ = String.new();
+ //~^ ERROR expected value, found struct `String`
+ //~| HELP use the path separator
+
+ let _ = String.default;
+ //~^ ERROR expected value, found struct `String`
+ //~| HELP use the path separator
+
+ let _ = Vec::<()>.with_capacity(1);
+ //~^ ERROR expected value, found struct `Vec`
+ //~| HELP use the path separator
+}
+
+macro_rules! Type {
+ () => {
+ ::std::cell::Cell
+ //~^ ERROR expected value, found struct `std::cell::Cell`
+ //~| ERROR expected value, found struct `std::cell::Cell`
+ //~| ERROR expected value, found struct `std::cell::Cell`
+ };
+}
+
+macro_rules! create {
+ (type method) => {
+ Vec.new()
+ //~^ ERROR expected value, found struct `Vec`
+ //~| HELP use the path separator
+ };
+ (type field) => {
+ Vec.new
+ //~^ ERROR expected value, found struct `Vec`
+ //~| HELP use the path separator
+ };
+ (macro method) => {
+ Type!().new(0)
+ //~^ HELP use the path separator
+ };
+}
+
+fn interaction_with_macros() {
+ //
+ // Verify that we do not only suggest to replace `.` with `::` if the receiver is a
+ // macro call but that we also correctly suggest to surround it with angle brackets.
+ //
+
+ Type!().get();
+ //~^ HELP use the path separator
+
+ Type! {}.get;
+ //~^ HELP use the path separator
+
+ //
+ // Ensure that the suggestion is shown for expressions inside of macro definitions.
+ //
+
+ let _ = create!(type method);
+ let _ = create!(type field);
+ let _ = create!(macro method);
}
diff --git a/src/test/ui/resolve/issue-22692.stderr b/src/test/ui/resolve/issue-22692.stderr
index e076419f6..6962aa161 100644
--- a/src/test/ui/resolve/issue-22692.stderr
+++ b/src/test/ui/resolve/issue-22692.stderr
@@ -2,10 +2,87 @@ error[E0423]: expected value, found struct `String`
--> $DIR/issue-22692.rs:2:13
|
LL | let _ = String.new();
- | ^^^^^^----
- | |
- | help: use the path separator to refer to an item: `String::new`
+ | ^^^^^^- help: use the path separator to refer to an item: `::`
-error: aborting due to previous error
+error[E0423]: expected value, found struct `String`
+ --> $DIR/issue-22692.rs:6:13
+ |
+LL | let _ = String.default;
+ | ^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found struct `Vec`
+ --> $DIR/issue-22692.rs:10:13
+ |
+LL | let _ = Vec::<()>.with_capacity(1);
+ | ^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+ --> $DIR/issue-22692.rs:17:9
+ |
+LL | ::std::cell::Cell
+ | ^^^^^^^^^^^^^^^^^
+...
+LL | Type!().get();
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+ |
+LL | <Type!()>::get();
+ | ~~~~~~~~~~~
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+ --> $DIR/issue-22692.rs:17:9
+ |
+LL | ::std::cell::Cell
+ | ^^^^^^^^^^^^^^^^^
+...
+LL | Type! {}.get;
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+ |
+LL | <Type! {}>::get;
+ | ~~~~~~~~~~~~
+
+error[E0423]: expected value, found struct `Vec`
+ --> $DIR/issue-22692.rs:26:9
+ |
+LL | Vec.new()
+ | ^^^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(type method);
+ | -------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `Vec`
+ --> $DIR/issue-22692.rs:31:9
+ |
+LL | Vec.new
+ | ^^^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(type field);
+ | ------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+ --> $DIR/issue-22692.rs:17:9
+ |
+LL | ::std::cell::Cell
+ | ^^^^^^^^^^^^^^^^^
+...
+LL | let _ = create!(macro method);
+ | --------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+ |
+LL | <Type!()>::new(0)
+ | ~~~~~~~~~~~
+
+error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/resolve/issue-3021-c.stderr b/src/test/ui/resolve/issue-3021-c.stderr
index 8764ac8a8..5176efc3a 100644
--- a/src/test/ui/resolve/issue-3021-c.stderr
+++ b/src/test/ui/resolve/issue-3021-c.stderr
@@ -3,22 +3,22 @@ error[E0401]: can't use generic parameters from outer function
|
LL | fn siphash<T>() {
| - type parameter from outer function
-...
+LL |
+LL | trait U {
+ | - help: try using a local generic parameter instead: `<T>`
LL | fn g(&self, x: T) -> T;
- | - ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `g<T>`
+ | ^ use of generic parameter from outer function
error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-3021-c.rs:4:30
|
LL | fn siphash<T>() {
| - type parameter from outer function
-...
+LL |
+LL | trait U {
+ | - help: try using a local generic parameter instead: `<T>`
LL | fn g(&self, x: T) -> T;
- | - ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `g<T>`
+ | ^ use of generic parameter from outer function
error: aborting due to 2 previous errors
diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
index aaf0f7eae..49462f52f 100644
--- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
+++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
@@ -14,7 +14,6 @@ trait B {
impl B for A {
async fn associated(); //~ ERROR without body
//~^ ERROR cannot be declared `async`
- //~| ERROR has an incompatible type for trait
}
fn main() {}
diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr
index d3214458e..55c3b66f1 100644
--- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr
+++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr
@@ -14,17 +14,6 @@ LL | async fn inherent();
| |
| help: provide a definition for the function: `{ <body> }`
-error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:5
- |
-LL | async fn associated();
- | -----^^^^^^^^^^^^^^^^^
- | |
- | `async` because of this
- |
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
-
error: associated function in `impl` without body
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
|
@@ -34,7 +23,7 @@ LL | async fn associated();
| help: provide a definition for the function: `{ <body> }`
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
+ --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:5
|
LL | async fn associated();
| -----^^^^^^^^^^^^^^^^^
@@ -43,26 +32,22 @@ LL | async fn associated();
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
-error[E0053]: method `associated` has an incompatible type for trait
- --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:26
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
|
LL | async fn associated();
- | ^
- | |
- | checked the `Output` of this `async fn`, found opaque type
- | expected `()`, found opaque type
- |
- = note: while checking the return type of the `async fn`
-note: type in trait
- --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:26
+ | -----^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
|
-LL | async fn associated();
- | ^
- = note: expected fn pointer `fn()`
- found fn pointer `fn() -> impl Future<Output = ()>`
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0053, E0706.
-For more information about an error, try `rustc --explain E0053`.
+For more information about this error, try `rustc --explain E0706`.
diff --git a/src/test/ui/resolve/issue-73427.rs b/src/test/ui/resolve/issue-73427.rs
index 3c62782a8..5c2459a59 100644
--- a/src/test/ui/resolve/issue-73427.rs
+++ b/src/test/ui/resolve/issue-73427.rs
@@ -22,6 +22,10 @@ enum D {
Unit,
}
+enum E {
+ TupleWithFields(()),
+}
+
fn main() {
// Only variants without fields are suggested (and others mentioned in a note) where an enum
// is used rather than a variant.
@@ -34,6 +38,8 @@ fn main() {
//~^ ERROR expected value, found enum `C`
D.foo();
//~^ ERROR expected value, found enum `D`
+ E.foo();
+ //~^ ERROR expected value, found enum `E`
// Only tuple variants are suggested in calls or tuple struct pattern matching.
diff --git a/src/test/ui/resolve/issue-73427.stderr b/src/test/ui/resolve/issue-73427.stderr
index 59bb98a34..a2ca46f0c 100644
--- a/src/test/ui/resolve/issue-73427.stderr
+++ b/src/test/ui/resolve/issue-73427.stderr
@@ -1,5 +1,5 @@
error[E0423]: expected value, found enum `A`
- --> $DIR/issue-73427.rs:29:5
+ --> $DIR/issue-73427.rs:33:5
|
LL | A.foo();
| ^
@@ -23,7 +23,7 @@ LL | (A::Tuple()).foo();
| ~~~~~~~~~~~~
LL | A::Unit.foo();
| ~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | (A::StructWithFields { /* fields */ }).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -31,7 +31,7 @@ LL | (A::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `B`
- --> $DIR/issue-73427.rs:31:5
+ --> $DIR/issue-73427.rs:35:5
|
LL | B.foo();
| ^
@@ -52,7 +52,7 @@ LL | (B::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `C`
- --> $DIR/issue-73427.rs:33:5
+ --> $DIR/issue-73427.rs:37:5
|
LL | C.foo();
| ^
@@ -70,7 +70,7 @@ help: you might have meant to use the following enum variant
|
LL | C::Unit.foo();
| ~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | (C::StructWithFields { /* fields */ }).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -78,7 +78,7 @@ LL | (C::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `D`
- --> $DIR/issue-73427.rs:35:5
+ --> $DIR/issue-73427.rs:39:5
|
LL | D.foo();
| ^
@@ -95,13 +95,37 @@ help: you might have meant to use the following enum variant
|
LL | D::Unit.foo();
| ~~~~~~~
-help: the following enum variant is available
+help: alternatively, the following enum variant is available
|
LL | (D::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+error[E0423]: expected value, found enum `E`
+ --> $DIR/issue-73427.rs:41:5
+ |
+LL | E.foo();
+ | ^
+ |
+note: the enum is defined here
+ --> $DIR/issue-73427.rs:25:1
+ |
+LL | / enum E {
+LL | | TupleWithFields(()),
+LL | | }
+ | |_^
+help: the following enum variant is available
+ |
+LL | (E::TupleWithFields(/* fields */)).foo();
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+help: consider importing one of these items instead
+ |
+LL | use std::f32::consts::E;
+ |
+LL | use std::f64::consts::E;
+ |
+
error[E0423]: expected function, tuple struct or tuple variant, found enum `A`
- --> $DIR/issue-73427.rs:40:13
+ --> $DIR/issue-73427.rs:46:13
|
LL | let x = A(3);
| ^
@@ -126,7 +150,7 @@ LL | let x = A::TupleWithFields(3);
| ~~~~~~~~~~~~~~~~~~
error[E0532]: expected tuple struct or tuple variant, found enum `A`
- --> $DIR/issue-73427.rs:42:12
+ --> $DIR/issue-73427.rs:48:12
|
LL | if let A(3) = x { }
| ^
@@ -150,7 +174,7 @@ LL | if let A::Tuple(3) = x { }
LL | if let A::TupleWithFields(3) = x { }
| ~~~~~~~~~~~~~~~~~~
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
Some errors have detailed explanations: E0423, E0532.
For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs
new file mode 100644
index 000000000..bd496875e
--- /dev/null
+++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs
@@ -0,0 +1,21 @@
+trait Foo<T> {
+ fn foo(&self, name: T) -> usize;
+}
+
+struct Bar {
+ baz: Baz,
+}
+
+struct Baz {
+ num: usize,
+}
+
+impl<Baz> Foo<Baz> for Bar {
+ fn foo(&self, _name: Baz) -> usize {
+ match self.baz {
+ Baz { num } => num, //~ ERROR expected struct, variant or union type, found type parameter `Baz`
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
new file mode 100644
index 000000000..af9f4612a
--- /dev/null
+++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
@@ -0,0 +1,12 @@
+error[E0574]: expected struct, variant or union type, found type parameter `Baz`
+ --> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
+ |
+LL | impl<Baz> Foo<Baz> for Bar {
+ | --- found this type parameter
+...
+LL | Baz { num } => num,
+ | ^^^ not a struct, variant or union type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index f885ac215..a369dc6db 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -19,7 +19,7 @@ help: you might have meant to use the following enum variant
|
LL | m::Z::Unit;
| ~~~~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -47,7 +47,7 @@ help: you might have meant to use the following enum variant
|
LL | m::Z::Unit;
| ~~~~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -89,7 +89,7 @@ help: you might have meant to use the following enum variant
|
LL | let _: E = E::Unit;
| ~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | let _: E = (E::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~
@@ -143,7 +143,7 @@ help: you might have meant to use the following enum variant
|
LL | let _: E = E::Unit;
| ~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | let _: E = (E::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~
@@ -203,7 +203,7 @@ help: you might have meant to use the following enum variant
|
LL | let _: Z = m::Z::Unit;
| ~~~~~~~~~~
-help: the following enum variants are available
+help: alternatively, the following enum variants are also available
|
LL | let _: Z = (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -329,8 +329,8 @@ LL | let _: Z = Z::Fn;
found fn item `fn(u8) -> Z {Z::Fn}`
help: use parentheses to instantiate this tuple variant
|
-LL | let _: Z = Z::Fn(_);
- | +++
+LL | let _: Z = Z::Fn(/* u8 */);
+ | ++++++++++
error[E0618]: expected function, found enum variant `Z::Unit`
--> $DIR/privacy-enum-ctor.rs:31:17
@@ -364,8 +364,8 @@ LL | let _: E = m::E::Fn;
found fn item `fn(u8) -> E {E::Fn}`
help: use parentheses to instantiate this tuple variant
|
-LL | let _: E = m::E::Fn(_);
- | +++
+LL | let _: E = m::E::Fn(/* u8 */);
+ | ++++++++++
error[E0618]: expected function, found enum variant `m::E::Unit`
--> $DIR/privacy-enum-ctor.rs:47:16
@@ -399,8 +399,8 @@ LL | let _: E = E::Fn;
found fn item `fn(u8) -> E {E::Fn}`
help: use parentheses to instantiate this tuple variant
|
-LL | let _: E = E::Fn(_);
- | +++
+LL | let _: E = E::Fn(/* u8 */);
+ | ++++++++++
error[E0618]: expected function, found enum variant `E::Unit`
--> $DIR/privacy-enum-ctor.rs:55:16
diff --git a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr
index 96c1869b4..c805c9eb1 100644
--- a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr
+++ b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr
@@ -31,6 +31,10 @@ LL | Opts::A(ref i) | Opts::B(i) => {}
| first introduced with type `&isize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
+help: consider adding `ref`
+ |
+LL | Opts::A(ref i) | Opts::B(ref i) => {}
+ | +++
error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:18:34
@@ -43,6 +47,10 @@ LL | Opts::A(ref i) | Opts::B(i) => {}
| first introduced with type `&isize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
+help: consider adding `ref`
+ |
+LL | Opts::A(ref i) | Opts::B(ref i) => {}
+ | +++
error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:27:38
diff --git a/src/test/ui/resolve/resolve-inconsistent-names.rs b/src/test/ui/resolve/resolve-inconsistent-names.rs
index 989d2d452..9a40b2034 100644
--- a/src/test/ui/resolve/resolve-inconsistent-names.rs
+++ b/src/test/ui/resolve/resolve-inconsistent-names.rs
@@ -23,6 +23,7 @@ fn main() {
//~| ERROR mismatched types
//~| ERROR variable `c` is not bound in all patterns
//~| HELP if you meant to match on unit variant `E::A`, use the full path in the pattern
+ //~| HELP consider removing `ref`
}
let z = (10, 20);
diff --git a/src/test/ui/resolve/resolve-inconsistent-names.stderr b/src/test/ui/resolve/resolve-inconsistent-names.stderr
index 9de191f7d..773c9f6cd 100644
--- a/src/test/ui/resolve/resolve-inconsistent-names.stderr
+++ b/src/test/ui/resolve/resolve-inconsistent-names.stderr
@@ -55,7 +55,7 @@ LL | (A, B) | (ref B, c) | (c, A) => ()
| first binding
error[E0408]: variable `CONST1` is not bound in all patterns
- --> $DIR/resolve-inconsistent-names.rs:30:23
+ --> $DIR/resolve-inconsistent-names.rs:31:23
|
LL | (CONST1, _) | (_, Const2) => ()
| ------ ^^^^^^^^^^^ pattern doesn't bind `CONST1`
@@ -69,7 +69,7 @@ LL | const CONST1: usize = 10;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible
error[E0408]: variable `Const2` is not bound in all patterns
- --> $DIR/resolve-inconsistent-names.rs:30:9
+ --> $DIR/resolve-inconsistent-names.rs:31:9
|
LL | (CONST1, _) | (_, Const2) => ()
| ^^^^^^^^^^^ ------ variable not in all patterns
@@ -92,6 +92,11 @@ LL | (A, B) | (ref B, c) | (c, A) => ()
| first introduced with type `E` here
|
= note: in the same arm, a binding must have the same type in all alternatives
+help: consider removing `ref`
+ |
+LL - (A, B) | (ref B, c) | (c, A) => ()
+LL + (A, B) | (B, c) | (c, A) => ()
+ |
error: aborting due to 9 previous errors
diff --git a/src/test/ui/resolve/resolve-primitive-fallback.stderr b/src/test/ui/resolve/resolve-primitive-fallback.stderr
index f0eb1a4f4..6d5d5bad9 100644
--- a/src/test/ui/resolve/resolve-primitive-fallback.stderr
+++ b/src/test/ui/resolve/resolve-primitive-fallback.stderr
@@ -34,7 +34,7 @@ LL | pub const fn size_of<T>() -> usize {
help: remove the extra argument
|
LL | std::mem::size_of();
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~
error: aborting due to 3 previous errors
diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr
index 10a703ee0..0a6d1cc3b 100644
--- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr
+++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr
@@ -4,8 +4,8 @@ error[E0401]: can't use generic parameters from outer function
LL | trait TraitA<A> {
| - type parameter from outer function
LL | fn outer(&self) {
- | ----- try adding a local generic parameter in this method instead
LL | enum Foo<B> {
+ | - help: try using a local generic parameter instead: `A,`
LL | Variance(A)
| ^ use of generic parameter from outer function
@@ -15,9 +15,10 @@ error[E0401]: can't use generic parameters from outer function
LL | trait TraitB<A> {
| - type parameter from outer function
LL | fn outer(&self) {
- | ----- try adding a local generic parameter in this method instead
LL | struct Foo<B>(A);
- | ^ use of generic parameter from outer function
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `A,`
error[E0401]: can't use generic parameters from outer function
--> $DIR/resolve-type-param-in-item-in-trait.rs:23:28
@@ -25,9 +26,10 @@ error[E0401]: can't use generic parameters from outer function
LL | trait TraitC<A> {
| - type parameter from outer function
LL | fn outer(&self) {
- | ----- try adding a local generic parameter in this method instead
LL | struct Foo<B> { a: A }
- | ^ use of generic parameter from outer function
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `A,`
error[E0401]: can't use generic parameters from outer function
--> $DIR/resolve-type-param-in-item-in-trait.rs:30:22
@@ -36,9 +38,9 @@ LL | trait TraitD<A> {
| - type parameter from outer function
LL | fn outer(&self) {
LL | fn foo<B>(a: A) { }
- | ------ ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `foo<B, A>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `A,`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/resolve/suggest-path-for-tuple-struct.stderr b/src/test/ui/resolve/suggest-path-for-tuple-struct.stderr
index 957045ca7..4764cf2db 100644
--- a/src/test/ui/resolve/suggest-path-for-tuple-struct.stderr
+++ b/src/test/ui/resolve/suggest-path-for-tuple-struct.stderr
@@ -2,17 +2,13 @@ error[E0423]: expected value, found struct `SomeTupleStruct`
--> $DIR/suggest-path-for-tuple-struct.rs:22:13
|
LL | let _ = SomeTupleStruct.new();
- | ^^^^^^^^^^^^^^^----
- | |
- | help: use the path separator to refer to an item: `SomeTupleStruct::new`
+ | ^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found struct `SomeRegularStruct`
--> $DIR/suggest-path-for-tuple-struct.rs:24:13
|
LL | let _ = SomeRegularStruct.new();
- | ^^^^^^^^^^^^^^^^^----
- | |
- | help: use the path separator to refer to an item: `SomeRegularStruct::new`
+ | ^^^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs
index 204a27240..d5d6b13d6 100644
--- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs
+++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs
@@ -16,44 +16,96 @@ pub mod a {
fn h1() -> i32 {
a.I
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
}
fn h2() -> i32 {
a.g()
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
}
fn h3() -> i32 {
a.b.J
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
}
fn h4() -> i32 {
a::b.J
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
+ //~| HELP use the path separator
}
fn h5() {
a.b.f();
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
let v = Vec::new();
v.push(a::b);
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
}
fn h6() -> i32 {
a::b.f()
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
+ //~| HELP use the path separator
}
fn h7() {
a::b
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
}
fn h8() -> i32 {
a::b()
//~^ ERROR expected function, found module `a::b`
+ //~| HELP a constant with a similar name exists
+}
+
+macro_rules! module {
+ () => {
+ a
+ //~^ ERROR expected value, found module `a`
+ //~| ERROR expected value, found module `a`
+ };
+}
+
+macro_rules! create {
+ (method) => {
+ a.f()
+ //~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
+ };
+ (field) => {
+ a.f
+ //~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
+ };
+}
+
+fn h9() {
+ //
+ // Note that if the receiver is a macro call, we do not want to suggest to replace
+ // `.` with `::` as that would be a syntax error.
+ // Since the receiver is a module and not a type, we cannot suggest to surround
+ // it with angle brackets.
+ //
+
+ module!().g::<()>(); // no `help` here!
+
+ module!().g; // no `help` here!
+
+ //
+ // Ensure that the suggestion is shown for expressions inside of macro definitions.
+ //
+
+ let _ = create!(method);
+ let _ = create!(field);
}
fn main() {}
diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
index 54b242123..a4ce0deeb 100644
--- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
+++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
@@ -2,28 +2,22 @@ error[E0423]: expected value, found module `a`
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:17:5
|
LL | a.I
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::I`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:22:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:23:5
|
LL | a.g()
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::g`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:29:5
|
LL | a.b.J
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::b`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:32:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:35:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
@@ -34,22 +28,20 @@ LL | a::b.J
help: use the path separator to refer to an item
|
LL | a::b::J
- |
+ | ~~
help: a constant with a similar name exists
|
LL | a::I.J
| ~
error[E0423]: expected value, found module `a`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:42:5
|
LL | a.b.f();
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::b`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:40:12
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:46:12
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
@@ -60,7 +52,7 @@ LL | v.push(a::b);
| help: a constant with a similar name exists: `I`
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
@@ -71,14 +63,14 @@ LL | a::b.f()
help: use the path separator to refer to an item
|
LL | a::b::f()
- | ~~~~~~~
+ | ~~
help: a constant with a similar name exists
|
LL | a::I.f()
| ~
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:59:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
@@ -89,7 +81,7 @@ LL | a::b
| help: a constant with a similar name exists: `I`
error[E0423]: expected function, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
@@ -99,6 +91,50 @@ LL | a::b()
| |
| help: a constant with a similar name exists: `I`
-error: aborting due to 9 previous errors
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9
+ |
+LL | a
+ | ^ not a value
+...
+LL | module!().g::<()>(); // no `help` here!
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9
+ |
+LL | a
+ | ^ not a value
+...
+LL | module!().g; // no `help` here!
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:80:9
+ |
+LL | a.f()
+ | ^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(method);
+ | --------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:85:9
+ |
+LL | a.f
+ | ^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(field);
+ | -------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 6086723b5..7d81de438 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -9,7 +9,7 @@ LL | | }
| |_^ `main` can only return types that implement `Termination`
|
= help: the trait `Termination` is not implemented for `f32`
- = note: required because of the requirements on the impl of `Termination` for `Result<f32, ParseFloatError>`
+ = note: required for `Result<f32, ParseFloatError>` to implement `Termination`
note: required by a bound in `assert_test_result`
--> $SRC_DIR/test/src/lib.rs:LL:COL
|
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs
index d9657bac7..5dce8180f 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.rs
@@ -1,5 +1,4 @@
// aux-build:enums.rs
-// run-pass
extern crate enums;
@@ -7,11 +6,6 @@ use enums::FieldLessWithNonExhaustiveVariant;
fn main() {
let e = FieldLessWithNonExhaustiveVariant::default();
- // FIXME: https://github.com/rust-lang/rust/issues/91161
- // This `as` cast *should* be an error, since it would fail
- // if the non-exhaustive variant got fields. But today it
- // doesn't. The fix for that will update this test to
- // show an error (and not be run-pass any more).
- let d = e as u8;
+ let d = e as u8; //~ ERROR casting `FieldLessWithNonExhaustiveVariant` as `u8` is invalid [E0606]
assert_eq!(d, 0);
}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr
new file mode 100644
index 000000000..a61dcf839
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum-as-cast.stderr
@@ -0,0 +1,11 @@
+error[E0606]: casting `FieldLessWithNonExhaustiveVariant` as `u8` is invalid
+ --> $DIR/enum-as-cast.rs:9:13
+ |
+LL | let d = e as u8;
+ | ^^^^^^^
+ |
+ = note: cannot cast an enum with a non-exhaustive variant when it's defined in another crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs
index 70253a4fc..69a283c31 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs
@@ -31,7 +31,7 @@ fn empty_non_exhaustive(x: EmptyNonExhaustiveEnum) {
fn main() {
match NonExhaustiveEnum::Unit {}
- //~^ ERROR `Unit`, `Tuple(_)` and `Struct { .. }` not covered [E0004]
+ //~^ ERROR `NonExhaustiveEnum::Unit`, `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered [E0004]
match NormalEnum::Unit {}
- //~^ ERROR `Unit`, `Tuple(_)` and `Struct { .. }` not covered [E0004]
+ //~^ ERROR `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered [E0004]
}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
index 1f2090448..de1bf8be8 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
@@ -10,11 +10,11 @@ note: the lint level is defined here
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
-error[E0004]: non-exhaustive patterns: `Unit`, `Tuple(_)` and `Struct { .. }` not covered
+error[E0004]: non-exhaustive patterns: `NonExhaustiveEnum::Unit`, `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered
--> $DIR/enum_same_crate_empty_match.rs:33:11
|
LL | match NonExhaustiveEnum::Unit {}
- | ^^^^^^^^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
+ | ^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonExhaustiveEnum::Unit`, `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered
|
note: `NonExhaustiveEnum` defined here
--> $DIR/enum_same_crate_empty_match.rs:5:5
@@ -33,15 +33,15 @@ LL | Struct { field: u32 }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ match NonExhaustiveEnum::Unit {
-LL + Unit | Tuple(_) | Struct { .. } => todo!(),
+LL + NonExhaustiveEnum::Unit | NonExhaustiveEnum::Tuple(_) | NonExhaustiveEnum::Struct { .. } => todo!(),
LL + }
|
-error[E0004]: non-exhaustive patterns: `Unit`, `Tuple(_)` and `Struct { .. }` not covered
+error[E0004]: non-exhaustive patterns: `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered
--> $DIR/enum_same_crate_empty_match.rs:35:11
|
LL | match NormalEnum::Unit {}
- | ^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
+ | ^^^^^^^^^^^^^^^^ patterns `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered
|
note: `NormalEnum` defined here
--> $DIR/enum_same_crate_empty_match.rs:14:5
@@ -60,7 +60,7 @@ LL | Struct { field: u32 }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ match NormalEnum::Unit {
-LL + Unit | Tuple(_) | Struct { .. } => todo!(),
+LL + NormalEnum::Unit | NormalEnum::Tuple(_) | NormalEnum::Struct { .. } => todo!(),
LL + }
|
diff --git a/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
index a9885449f..4b9f8564d 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
@@ -81,7 +81,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:58:9
|
LL | _ => {}
- | ^ pattern `Struct { .. }` not covered
+ | ^ pattern `NonExhaustiveEnum::Struct { .. }` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:57:16
@@ -95,7 +95,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:65:9
|
LL | _ => {}
- | ^ pattern `Tuple(_)` not covered
+ | ^ pattern `NonExhaustiveEnum::Tuple(_)` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:64:16
@@ -109,7 +109,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:75:9
|
LL | _ => {}
- | ^ pattern `Unit` not covered
+ | ^ pattern `NonExhaustiveEnum::Unit` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:74:16
@@ -123,7 +123,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:92:32
|
LL | NestedNonExhaustive::A(_) => {}
- | ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+ | ^ patterns `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:89:12
@@ -137,7 +137,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:94:9
|
LL | _ => {}
- | ^ pattern `C` not covered
+ | ^ pattern `NestedNonExhaustive::C` not covered
|
= help: ensure that all variants are matched explicitly by adding the suggested match arms
= note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
@@ -146,7 +146,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:132:9
|
LL | _ => {}
- | ^ pattern `A(_)` not covered
+ | ^ pattern `NonExhaustiveSingleVariant::A(_)` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:130:12
@@ -160,7 +160,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:144:9
|
LL | _ => {}
- | ^ pattern `Unstable` not covered
+ | ^ pattern `UnstableEnum::Unstable` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:143:16
@@ -174,7 +174,7 @@ error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:168:9
|
LL | _ => {}
- | ^ pattern `Unstable2` not covered
+ | ^ pattern `OnlyUnstableEnum::Unstable2` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:165:12
diff --git a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
index 7cce17898..533e8abf2 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
@@ -16,7 +16,7 @@ error: some variants are not matched explicitly
--> $DIR/stable-omitted-patterns.rs:23:9
|
LL | _ => {}
- | ^ pattern `Stable2` not covered
+ | ^ pattern `UnstableEnum::Stable2` not covered
|
note: the lint level is defined here
--> $DIR/stable-omitted-patterns.rs:22:16
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
index 32a5c07f1..a9c54af04 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
@@ -55,11 +55,11 @@ LL + _ => todo!(),
LL ~ }
|
-error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
--> $DIR/match.rs:31:11
|
LL | match x {}
- | ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+ | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
|
note: `UninhabitedVariants` defined here
--> $DIR/auxiliary/uninhabited.rs:17:23
@@ -74,7 +74,7 @@ LL | #[non_exhaustive] Struct { x: ! }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ match x {
-LL + Tuple(_) | Struct { .. } => todo!(),
+LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
LL ~ }
|
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
index c89c70ae6..ec2a2f6f0 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
@@ -36,11 +36,11 @@ LL + _ => todo!(),
LL ~ }
|
-error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
--> $DIR/match_same_crate.rs:38:11
|
LL | match x {}
- | ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+ | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
|
note: `UninhabitedVariants` defined here
--> $DIR/match_same_crate.rs:16:23
@@ -55,7 +55,7 @@ LL | #[non_exhaustive] Struct { x: ! }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ match x {
-LL + Tuple(_) | Struct { .. } => todo!(),
+LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
LL ~ }
|
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
index d854ea28f..b6b777ec5 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
@@ -55,11 +55,11 @@ LL + _ => todo!(),
LL ~ }
|
-error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
--> $DIR/match_with_exhaustive_patterns.rs:34:11
|
LL | match x {}
- | ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+ | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
|
note: `UninhabitedVariants` defined here
--> $DIR/auxiliary/uninhabited.rs:17:23
@@ -74,7 +74,7 @@ LL | #[non_exhaustive] Struct { x: ! }
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ match x {
-LL + Tuple(_) | Struct { .. } => todo!(),
+LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
LL ~ }
|
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index fce0cdfe0..bc06fde49 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -1493,17 +1493,11 @@ LL | if (let 0 = 0)? {}
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/disallowed-positions.rs:132:19
|
-LL | / fn nested_within_if_expr() {
-LL | | if &let 0 = 0 {}
-LL | |
-LL | |
-... |
-LL | | if (let 0 = 0)? {}
- | | ^ cannot use the `?` operator in a function that returns `()`
-... |
-LL | |
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn nested_within_if_expr() {
+ | -------------------------- this function should return `Result` or `Option` to accept `?`
+...
+LL | if (let 0 = 0)? {}
+ | ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
@@ -1693,17 +1687,11 @@ LL | while (let 0 = 0)? {}
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/disallowed-positions.rs:224:22
|
-LL | / fn nested_within_while_expr() {
-LL | | while &let 0 = 0 {}
-LL | |
-LL | |
-... |
-LL | | while (let 0 = 0)? {}
- | | ^ cannot use the `?` operator in a function that returns `()`
-... |
-LL | |
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn nested_within_while_expr() {
+ | ----------------------------- this function should return `Result` or `Option` to accept `?`
+...
+LL | while (let 0 = 0)? {}
+ | ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
@@ -1881,17 +1869,11 @@ LL | (let 0 = 0)?;
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/disallowed-positions.rs:325:16
|
-LL | / fn outside_if_and_while_expr() {
-LL | | &let 0 = 0;
-LL | |
-LL | |
-... |
-LL | | (let 0 = 0)?;
- | | ^ cannot use the `?` operator in a function that returns `()`
-... |
-LL | |
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn outside_if_and_while_expr() {
+ | ------------------------------ this function should return `Result` or `Option` to accept `?`
+...
+LL | (let 0 = 0)?;
+ | ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
index 12befc637..2a6c14435 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
@@ -1,4 +1,4 @@
-#![feature(let_chains, let_else)]
+#![feature(let_chains)]
fn main() {
let opt = Some(1i32);
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
index 1ced8d8a1..6d18d295c 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
@@ -23,97 +23,97 @@ LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
error: unused variable: `a`
- --> $DIR/param-attrs-cfg.rs:107:27
+ --> $DIR/param-attrs-cfg.rs:41:27
|
LL | #[cfg(something)] a: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_a`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:113:27
+ --> $DIR/param-attrs-cfg.rs:48:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:115:44
+ --> $DIR/param-attrs-cfg.rs:50:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:67:27
+ --> $DIR/param-attrs-cfg.rs:56:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:69:44
+ --> $DIR/param-attrs-cfg.rs:58:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:75:27
+ --> $DIR/param-attrs-cfg.rs:67:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:77:44
+ --> $DIR/param-attrs-cfg.rs:69:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
-error: unused variable: `a`
- --> $DIR/param-attrs-cfg.rs:41:27
- |
-LL | #[cfg(something)] a: i32,
- | ^ help: if this is intentional, prefix it with an underscore: `_a`
-
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:48:27
+ --> $DIR/param-attrs-cfg.rs:75:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:50:44
+ --> $DIR/param-attrs-cfg.rs:77:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:56:27
+ --> $DIR/param-attrs-cfg.rs:86:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:58:44
+ --> $DIR/param-attrs-cfg.rs:88:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:86:27
+ --> $DIR/param-attrs-cfg.rs:94:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:88:44
+ --> $DIR/param-attrs-cfg.rs:96:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
+error: unused variable: `a`
+ --> $DIR/param-attrs-cfg.rs:107:27
+ |
+LL | #[cfg(something)] a: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:94:27
+ --> $DIR/param-attrs-cfg.rs:113:27
|
LL | #[cfg(something)] b: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:96:44
+ --> $DIR/param-attrs-cfg.rs:115:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: if this is intentional, prefix it with an underscore: `_c`
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs
new file mode 100644
index 000000000..22d57f8be
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs
@@ -0,0 +1,9 @@
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+
+#[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+//~^ ERROR import name type must be of the form `import_name_type = "string"`
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr
new file mode 100644
index 000000000..0e95fec29
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr
@@ -0,0 +1,8 @@
+error: import name type must be of the form `import_name_type = "string"`
+ --> $DIR/import-name-type-invalid-format.rs:5:42
+ |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs
new file mode 100644
index 000000000..7ccb0082f
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs
@@ -0,0 +1,10 @@
+// ignore-tidy-linelength
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+//~^ ERROR multiple `import_name_type` arguments in a single `#[link]` attribute
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr
new file mode 100644
index 000000000..7c0e0be91
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr
@@ -0,0 +1,8 @@
+error: multiple `import_name_type` arguments in a single `#[link]` attribute
+ --> $DIR/import-name-type-multiple.rs:6:74
+ |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs
new file mode 100644
index 000000000..f728a578d
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs
@@ -0,0 +1,9 @@
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+//~^ ERROR unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr
new file mode 100644
index 000000000..2b299f2fe
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr
@@ -0,0 +1,8 @@
+error: unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated
+ --> $DIR/import-name-type-unknown-value.rs:5:42
+ |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs
new file mode 100644
index 000000000..ae9207864
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs
@@ -0,0 +1,17 @@
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+
+#[link(name = "foo", import_name_type = "decorated")]
+//~^ ERROR import name type can only be used with link kind `raw-dylib`
+extern "C" { }
+
+#[link(name = "bar", kind = "static", import_name_type = "decorated")]
+//~^ ERROR import name type can only be used with link kind `raw-dylib`
+extern "C" { }
+
+// Specifying `import_name_type` before `kind` shouldn't raise an error.
+#[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")]
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr
new file mode 100644
index 000000000..5898cd875
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr
@@ -0,0 +1,14 @@
+error: import name type can only be used with link kind `raw-dylib`
+ --> $DIR/import-name-type-unsupported-link-kind.rs:5:22
+ |
+LL | #[link(name = "foo", import_name_type = "decorated")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: import name type can only be used with link kind `raw-dylib`
+ --> $DIR/import-name-type-unsupported-link-kind.rs:9:39
+ |
+LL | #[link(name = "bar", kind = "static", import_name_type = "decorated")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs
new file mode 100644
index 000000000..346ea18a8
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs
@@ -0,0 +1,7 @@
+// only-windows
+// ignore-x86
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+//~^ ERROR import name type is only supported on x86
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr
new file mode 100644
index 000000000..b56449299
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr
@@ -0,0 +1,8 @@
+error: import name type is only supported on x86
+ --> $DIR/import-name-type-x86-only.rs:3:42
+ |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs
index 42685cad9..1a128c87a 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs
@@ -1,5 +1,4 @@
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name="foo")]
extern "C" {
@@ -7,6 +6,10 @@ extern "C" {
#[link_ordinal(42)]
//~^ ERROR cannot use `#[link_name]` with `#[link_ordinal]`
fn foo();
+ #[link_name="foo"]
+ #[link_ordinal(5)]
+ //~^ ERROR cannot use `#[link_name]` with `#[link_ordinal]`
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr
index 5d8545b50..481a06d27 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr
@@ -1,17 +1,14 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/link-ordinal-and-name.rs:1:12
- |
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
-
error: cannot use `#[link_name]` with `#[link_ordinal]`
- --> $DIR/link-ordinal-and-name.rs:7:5
+ --> $DIR/link-ordinal-and-name.rs:6:5
|
LL | #[link_ordinal(42)]
| ^^^^^^^^^^^^^^^^^^^
-error: aborting due to previous error; 1 warning emitted
+error: cannot use `#[link_name]` with `#[link_ordinal]`
+ --> $DIR/link-ordinal-and-name.rs:10:5
+ |
+LL | #[link_ordinal(5)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs
index 135f5909e..7c8da050c 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs
@@ -1,11 +1,13 @@
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "foo")]
extern "C" {
#[link_ordinal("JustMonika")]
//~^ ERROR illegal ordinal format in `link_ordinal`
fn foo();
+ #[link_ordinal("JustMonika")]
+ //~^ ERROR illegal ordinal format in `link_ordinal`
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr
index 8453a3966..55cdcad75 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr
@@ -1,19 +1,18 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/link-ordinal-invalid-format.rs:1:12
+error: illegal ordinal format in `link_ordinal`
+ --> $DIR/link-ordinal-invalid-format.rs:5:5
|
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
+LL | #[link_ordinal("JustMonika")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = note: an unsuffixed integer value, e.g., `1`, is expected
error: illegal ordinal format in `link_ordinal`
- --> $DIR/link-ordinal-invalid-format.rs:6:5
+ --> $DIR/link-ordinal-invalid-format.rs:8:5
|
LL | #[link_ordinal("JustMonika")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an unsuffixed integer value, e.g., `1`, is expected
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs
index c391ccd1c..9feed3941 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs
@@ -1,11 +1,13 @@
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "foo")]
extern "C" {
#[link_ordinal()]
//~^ ERROR incorrect number of arguments to `#[link_ordinal]`
fn foo();
+ #[link_ordinal()]
+ //~^ ERROR incorrect number of arguments to `#[link_ordinal]`
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr
index 8e9edfb9d..853cdad8c 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr
@@ -1,19 +1,18 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/link-ordinal-missing-argument.rs:1:12
+error: incorrect number of arguments to `#[link_ordinal]`
+ --> $DIR/link-ordinal-missing-argument.rs:5:5
|
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
+LL | #[link_ordinal()]
+ | ^^^^^^^^^^^^^^^^^
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = note: the attribute requires exactly one argument
error: incorrect number of arguments to `#[link_ordinal]`
- --> $DIR/link-ordinal-missing-argument.rs:6:5
+ --> $DIR/link-ordinal-missing-argument.rs:8:5
|
LL | #[link_ordinal()]
| ^^^^^^^^^^^^^^^^^
|
= note: the attribute requires exactly one argument
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs
index 2a15b1d79..631c363d4 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs
@@ -1,12 +1,14 @@
// only-windows
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "foo", kind = "raw-dylib")]
extern "C" {
#[link_ordinal(1)] //~ ERROR multiple `link_ordinal` attributes
#[link_ordinal(2)]
fn foo();
+ #[link_ordinal(1)] //~ ERROR multiple `link_ordinal` attributes
+ #[link_ordinal(2)]
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr
index 4772533ab..c0453d2bf 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr
@@ -1,23 +1,26 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/link-ordinal-multiple.rs:2:12
+error: multiple `link_ordinal` attributes
+ --> $DIR/link-ordinal-multiple.rs:6:5
|
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
+LL | #[link_ordinal(1)]
+ | ^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+note: attribute also specified here
+ --> $DIR/link-ordinal-multiple.rs:7:5
+ |
+LL | #[link_ordinal(2)]
+ | ^^^^^^^^^^^^^^^^^^
error: multiple `link_ordinal` attributes
- --> $DIR/link-ordinal-multiple.rs:7:5
+ --> $DIR/link-ordinal-multiple.rs:9:5
|
LL | #[link_ordinal(1)]
| ^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
- --> $DIR/link-ordinal-multiple.rs:8:5
+ --> $DIR/link-ordinal-multiple.rs:10:5
|
LL | #[link_ordinal(2)]
| ^^^^^^^^^^^^^^^^^^
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs
new file mode 100644
index 000000000..54e614164
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs
@@ -0,0 +1,24 @@
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
+
+#[link_ordinal(123)]
+//~^ ERROR attribute should be applied to a foreign function or static
+struct Foo {}
+
+#[link_ordinal(123)]
+//~^ ERROR attribute should be applied to a foreign function or static
+fn test() {}
+
+#[link_ordinal(42)]
+//~^ ERROR attribute should be applied to a foreign function or static
+static mut imported_val: i32 = 123;
+
+#[link(name = "exporter", kind = "raw-dylib")]
+extern {
+ #[link_ordinal(13)]
+ fn imported_function();
+
+ #[link_ordinal(42)]
+ static mut imported_variable: i32;
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr
new file mode 100644
index 000000000..ec4104fbe
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr
@@ -0,0 +1,20 @@
+error: attribute should be applied to a foreign function or static
+ --> $DIR/link-ordinal-not-foreign-fn.rs:3:1
+ |
+LL | #[link_ordinal(123)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: attribute should be applied to a foreign function or static
+ --> $DIR/link-ordinal-not-foreign-fn.rs:7:1
+ |
+LL | #[link_ordinal(123)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: attribute should be applied to a foreign function or static
+ --> $DIR/link-ordinal-not-foreign-fn.rs:11:1
+ |
+LL | #[link_ordinal(42)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs
index b6089d27e..46731581e 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs
@@ -1,11 +1,13 @@
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "foo")]
extern "C" {
#[link_ordinal(72436)]
//~^ ERROR ordinal value in `link_ordinal` is too large: `72436`
fn foo();
+ #[link_ordinal(72436)]
+ //~^ ERROR ordinal value in `link_ordinal` is too large: `72436`
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr
index bbe985fa1..fef6de6ae 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr
@@ -1,19 +1,18 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/link-ordinal-too-large.rs:1:12
+error: ordinal value in `link_ordinal` is too large: `72436`
+ --> $DIR/link-ordinal-too-large.rs:5:5
|
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
+LL | #[link_ordinal(72436)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = note: the value may not exceed `u16::MAX`
error: ordinal value in `link_ordinal` is too large: `72436`
- --> $DIR/link-ordinal-too-large.rs:6:5
+ --> $DIR/link-ordinal-too-large.rs:8:5
|
LL | #[link_ordinal(72436)]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: the value may not exceed `u16::MAX`
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs
index 93286c616..71e0ac9f3 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs
@@ -1,11 +1,13 @@
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "foo")]
extern "C" {
#[link_ordinal(3, 4)]
//~^ ERROR incorrect number of arguments to `#[link_ordinal]`
fn foo();
+ #[link_ordinal(3, 4)]
+ //~^ ERROR incorrect number of arguments to `#[link_ordinal]`
+ static mut imported_variable: i32;
}
fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr
index 484c85a0f..7e0fcd845 100644
--- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr
@@ -1,19 +1,18 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/link-ordinal-too-many-arguments.rs:1:12
+error: incorrect number of arguments to `#[link_ordinal]`
+ --> $DIR/link-ordinal-too-many-arguments.rs:5:5
|
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
+LL | #[link_ordinal(3, 4)]
+ | ^^^^^^^^^^^^^^^^^^^^^
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+ = note: the attribute requires exactly one argument
error: incorrect number of arguments to `#[link_ordinal]`
- --> $DIR/link-ordinal-too-many-arguments.rs:6:5
+ --> $DIR/link-ordinal-too-many-arguments.rs:8:5
|
LL | #[link_ordinal(3, 4)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the attribute requires exactly one argument
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs
new file mode 100644
index 000000000..329c93fc1
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs
@@ -0,0 +1,17 @@
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
+
+#[link(name = "foo")]
+extern "C" {
+ #[link_ordinal(3)]
+ //~^ ERROR `#[link_ordinal]` is only supported if link kind is `raw-dylib`
+ fn foo();
+}
+
+#[link(name = "bar", kind = "static")]
+extern "C" {
+ #[link_ordinal(3)]
+ //~^ ERROR `#[link_ordinal]` is only supported if link kind is `raw-dylib`
+ fn bar();
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr
new file mode 100644
index 000000000..5fbffbda5
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr
@@ -0,0 +1,14 @@
+error: `#[link_ordinal]` is only supported if link kind is `raw-dylib`
+ --> $DIR/link-ordinal-unsupported-link-kind.rs:5:5
+ |
+LL | #[link_ordinal(3)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: `#[link_ordinal]` is only supported if link kind is `raw-dylib`
+ --> $DIR/link-ordinal-unsupported-link-kind.rs:12:5
+ |
+LL | #[link_ordinal(3)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs b/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs
index 13c9aa01e..6542faad2 100644
--- a/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs
@@ -3,7 +3,6 @@
// compile-flags: --crate-type lib --emit link
#![allow(clashing_extern_declarations)]
#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
#[link(name = "foo", kind = "raw-dylib")]
extern "C" {
fn f(x: i32);
diff --git a/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr b/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr
index 93ca8f4d8..c6808bec7 100644
--- a/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr
@@ -1,17 +1,8 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/multiple-declarations.rs:5:12
- |
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
-
error: multiple declarations of external function `f` from library `foo.dll` have different calling conventions
- --> $DIR/multiple-declarations.rs:15:9
+ --> $DIR/multiple-declarations.rs:14:9
|
LL | fn f(x: i32);
| ^^^^^^^^^^^^^
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
diff --git a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs
index 5856b18aa..4efffbd53 100644
--- a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs
@@ -1,7 +1,6 @@
// ignore-windows
// compile-flags: --crate-type lib
-#![feature(raw_dylib)]
-//~^ WARNING: the feature `raw_dylib` is incomplete
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
#[link(name = "foo", kind = "raw-dylib")]
//~^ ERROR: link kind `raw-dylib` is only supported on Windows targets
extern "C" {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr
index 600aac81a..14e791f1f 100644
--- a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr
@@ -1,18 +1,9 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/raw-dylib-windows-only.rs:3:12
- |
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
-
error[E0455]: link kind `raw-dylib` is only supported on Windows targets
- --> $DIR/raw-dylib-windows-only.rs:5:29
+ --> $DIR/raw-dylib-windows-only.rs:4:29
|
LL | #[link(name = "foo", kind = "raw-dylib")]
| ^^^^^^^^^^^
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0455`.
diff --git a/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs
index dc647fd63..2f5a23e47 100644
--- a/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs
+++ b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs
@@ -1,8 +1,6 @@
// only-x86_64
// only-windows
// compile-flags: --crate-type lib --emit link
-#![allow(incomplete_features)]
-#![feature(raw_dylib)]
#[link(name = "foo", kind = "raw-dylib")]
extern "stdcall" {
fn f(x: i32);
diff --git a/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr
index d8a2a6af9..f8265ae69 100644
--- a/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr
+++ b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr
@@ -1,5 +1,5 @@
error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
- --> $DIR/unsupported-abi.rs:8:5
+ --> $DIR/unsupported-abi.rs:6:5
|
LL | fn f(x: i32);
| ^^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
index ec724cc96..fddc8d37f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
@@ -1,14 +1,16 @@
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
- --> $DIR/const-default-method-bodies.rs:24:18
+ --> $DIR/const-default-method-bodies.rs:24:5
|
LL | NonConstImpl.a();
- | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
+ | ^^^^^^^^^^^^ - required by a bound introduced by this call
+ | |
+ | the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
- --> $DIR/const-default-method-bodies.rs:24:18
+ --> $DIR/const-default-method-bodies.rs:24:5
|
LL | NonConstImpl.a();
- | ^
+ | ^^^^^^^^^^^^
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | const fn test() where NonConstImpl: ~const ConstDefaultFn {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index 9dbaffd4c..2295a822f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -5,7 +5,7 @@ LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
...
LL | NonTrivialDrop,
- | ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
+ | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
= note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
note: required by a bound in `check`
@@ -52,15 +52,15 @@ LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
...
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
|
-note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
--> $DIR/const-drop-fail.rs:28:25
|
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+ = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:34:19
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index 9dbaffd4c..2295a822f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -5,7 +5,7 @@ LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
...
LL | NonTrivialDrop,
- | ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
+ | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
= note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
note: required by a bound in `check`
@@ -52,15 +52,15 @@ LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
...
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
|
-note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
--> $DIR/const-drop-fail.rs:28:25
|
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+ = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:34:19
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
index 174c62912..d4fa44b4b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
@@ -1,14 +1,16 @@
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
- --> $DIR/cross-crate.rs:17:14
+ --> $DIR/cross-crate.rs:17:5
|
LL | NonConst.func();
- | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
+ | ^^^^^^^^ ---- required by a bound introduced by this call
+ | |
+ | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
- --> $DIR/cross-crate.rs:17:14
+ --> $DIR/cross-crate.rs:17:5
|
LL | NonConst.func();
- | ^^^^
+ | ^^^^^^^^
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr
index 4619dd113..71ecd9b06 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr
@@ -1,14 +1,16 @@
error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied
- --> $DIR/cross-crate.rs:17:14
+ --> $DIR/cross-crate.rs:17:5
|
LL | NonConst.func();
- | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
+ | ^^^^^^^^ ---- required by a bound introduced by this call
+ | |
+ | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
- --> $DIR/cross-crate.rs:17:14
+ --> $DIR/cross-crate.rs:17:5
|
LL | NonConst.func();
- | ^^^^
+ | ^^^^^^^^
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
index b229053eb..85285ba84 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
@@ -1,14 +1,16 @@
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
- --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
+ --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
|
LL | ().a()
- | ^ the trait `~const Tr` is not implemented for `()`
+ | ^^ - required by a bound introduced by this call
+ | |
+ | the trait `~const Tr` is not implemented for `()`
|
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
- --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
+ --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
|
LL | ().a()
- | ^
+ | ^^
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub trait Tr where (): ~const Tr {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs
new file mode 100644
index 000000000..1004bb28c
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs
@@ -0,0 +1,29 @@
+// revisions: nn ny yn yy
+// check-pass
+#![feature(const_trait_impl, associated_type_defaults, const_mut_refs)]
+
+#[cfg_attr(any(yn, yy), const_trait)]
+pub trait Index {
+ type Output;
+}
+
+#[cfg_attr(any(ny, yy), const_trait)]
+pub trait IndexMut where Self: Index {
+ const C: <Self as Index>::Output;
+ type Assoc = <Self as Index>::Output;
+ fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output;
+}
+
+impl Index for () { type Output = (); }
+
+impl const IndexMut for <() as Index>::Output {
+ const C: <Self as Index>::Output = ();
+ type Assoc = <Self as Index>::Output;
+ fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
+ where <Self as Index>::Output:,
+ {}
+}
+
+const C: <() as Index>::Output = ();
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index d5b2d2697..fd5fe25dd 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -20,16 +20,16 @@ LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
| ++++++++++++
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
- --> $DIR/trait-where-clause.rs:15:5
+ --> $DIR/trait-where-clause.rs:15:12
|
LL | T::c::<T>();
- | ^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
+ | ^ the trait `~const Bar` is not implemented for `T`
|
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
- --> $DIR/trait-where-clause.rs:15:5
+ --> $DIR/trait-where-clause.rs:15:12
|
LL | T::c::<T>();
- | ^^^^^^^^^
+ | ^
note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause.rs:8:13
|
@@ -57,10 +57,10 @@ LL | fn test3<T: Foo + Bar>() {
| +++++
error[E0277]: the trait bound `T: Bar` is not satisfied
- --> $DIR/trait-where-clause.rs:29:5
+ --> $DIR/trait-where-clause.rs:29:12
|
LL | T::c::<T>();
- | ^^^^^^^^^ the trait `Bar` is not implemented for `T`
+ | ^ the trait `Bar` is not implemented for `T`
|
note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause.rs:8:13
diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
index e8b261545..d63381b5f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
@@ -3,4 +3,4 @@
#![feature(const_trait_impl)]
struct S<T: const Tr>;
-//~^ ERROR expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path
+//~^ ERROR const bounds must start with `~`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
index b6b77ac4a..31300354a 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
@@ -1,8 +1,10 @@
-error: expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path, found keyword `const`
+error: const bounds must start with `~`
--> $DIR/without-tilde.rs:5:13
|
LL | struct S<T: const Tr>;
- | ^^^^^ expected one of 10 possible tokens
+ | -^^^^
+ | |
+ | help: add `~`: `~`
error: aborting due to previous error
diff --git a/src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr b/src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
index 94a90a568..fc7bf2277 100644
--- a/src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
+++ b/src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
@@ -6,7 +6,7 @@ LL | call(foo);
| |
| required by a bound introduced by this call
|
- = help: the trait `Fn<()>` is not implemented for `fn() {foo}`
+ = help: the trait `Fn<()>` is not implemented for fn item `fn() {foo}`
= note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
note: required by a bound in `call`
@@ -23,7 +23,7 @@ LL | call_mut(foo);
| |
| required by a bound introduced by this call
|
- = help: the trait `FnMut<()>` is not implemented for `fn() {foo}`
+ = help: the trait `FnMut<()>` is not implemented for fn item `fn() {foo}`
= note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
note: required by a bound in `call_mut`
@@ -40,7 +40,7 @@ LL | call_once(foo);
| |
| required by a bound introduced by this call
|
- = help: the trait `FnOnce<()>` is not implemented for `fn() {foo}`
+ = help: the trait `FnOnce<()>` is not implemented for fn item `fn() {foo}`
= note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
note: required by a bound in `call_once`
@@ -57,7 +57,7 @@ LL | call(foo_unsafe);
| |
| required by a bound introduced by this call
|
- = help: the trait `Fn<()>` is not implemented for `unsafe fn() {foo_unsafe}`
+ = help: the trait `Fn<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
note: required by a bound in `call`
@@ -74,7 +74,7 @@ LL | call_mut(foo_unsafe);
| |
| required by a bound introduced by this call
|
- = help: the trait `FnMut<()>` is not implemented for `unsafe fn() {foo_unsafe}`
+ = help: the trait `FnMut<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
note: required by a bound in `call_mut`
@@ -91,7 +91,7 @@ LL | call_once(foo_unsafe);
| |
| required by a bound introduced by this call
|
- = help: the trait `FnOnce<()>` is not implemented for `unsafe fn() {foo_unsafe}`
+ = help: the trait `FnOnce<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
note: required by a bound in `call_once`
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
index 647a9f393..c6bc082cf 100644
--- a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
@@ -13,9 +13,8 @@ LL | #![warn(rust_2021_prefixes_incompatible_syntax)]
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
-LL - m2!(z"hey");
-LL + m2!(z "hey");
- |
+LL | m2!(z "hey");
+ | +
warning: prefix `prefix` is unknown
--> $DIR/reserved-prefixes-migration.rs:19:9
@@ -27,9 +26,8 @@ LL | m2!(prefix"hey");
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
-LL - m2!(prefix"hey");
-LL + m2!(prefix "hey");
- |
+LL | m2!(prefix "hey");
+ | +
warning: prefix `hey` is unknown
--> $DIR/reserved-prefixes-migration.rs:22:9
@@ -41,9 +39,8 @@ LL | m3!(hey#123);
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
-LL - m3!(hey#123);
-LL + m3!(hey #123);
- |
+LL | m3!(hey #123);
+ | +
warning: prefix `hey` is unknown
--> $DIR/reserved-prefixes-migration.rs:25:9
@@ -55,9 +52,8 @@ LL | m3!(hey#hey);
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
-LL - m3!(hey#hey);
-LL + m3!(hey #hey);
- |
+LL | m3!(hey #hey);
+ | +
warning: prefix `kind` is unknown
--> $DIR/reserved-prefixes-migration.rs:35:14
@@ -69,9 +65,8 @@ LL | #name = #kind#value
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
-LL - #name = #kind#value
-LL + #name = #kind #value
- |
+LL | #name = #kind #value
+ | +
warning: 5 warnings emitted
diff --git a/src/test/ui/rust-2021/reserved-prefixes.stderr b/src/test/ui/rust-2021/reserved-prefixes.stderr
index df31aee66..807d6d98b 100644
--- a/src/test/ui/rust-2021/reserved-prefixes.stderr
+++ b/src/test/ui/rust-2021/reserved-prefixes.stderr
@@ -7,9 +7,8 @@ LL | demo3!(foo#bar);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo3!(foo#bar);
-LL + demo3!(foo #bar);
- |
+LL | demo3!(foo #bar);
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:17:12
@@ -20,9 +19,8 @@ LL | demo2!(foo"bar");
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo2!(foo"bar");
-LL + demo2!(foo "bar");
- |
+LL | demo2!(foo "bar");
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:18:12
@@ -33,9 +31,8 @@ LL | demo2!(foo'b');
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo2!(foo'b');
-LL + demo2!(foo 'b');
- |
+LL | demo2!(foo 'b');
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:20:12
@@ -46,9 +43,8 @@ LL | demo2!(foo'b);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo2!(foo'b);
-LL + demo2!(foo 'b);
- |
+LL | demo2!(foo 'b);
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:21:12
@@ -59,9 +55,8 @@ LL | demo3!(foo# bar);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo3!(foo# bar);
-LL + demo3!(foo # bar);
- |
+LL | demo3!(foo # bar);
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:22:12
@@ -72,9 +67,8 @@ LL | demo4!(foo#! bar);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo4!(foo#! bar);
-LL + demo4!(foo #! bar);
- |
+LL | demo4!(foo #! bar);
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:23:12
@@ -85,9 +79,8 @@ LL | demo4!(foo## bar);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo4!(foo## bar);
-LL + demo4!(foo ## bar);
- |
+LL | demo4!(foo ## bar);
+ | +
error: prefix `foo` is unknown
--> $DIR/reserved-prefixes.rs:25:12
@@ -98,9 +91,8 @@ LL | demo4!(foo#bar#);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo4!(foo#bar#);
-LL + demo4!(foo #bar#);
- |
+LL | demo4!(foo #bar#);
+ | +
error: prefix `bar` is unknown
--> $DIR/reserved-prefixes.rs:25:16
@@ -111,9 +103,8 @@ LL | demo4!(foo#bar#);
= note: prefixed identifiers and literals are reserved since Rust 2021
help: consider inserting whitespace here
|
-LL - demo4!(foo#bar#);
-LL + demo4!(foo#bar #);
- |
+LL | demo4!(foo#bar #);
+ | +
error: aborting due to 9 previous errors
diff --git a/src/test/ui/sanitize/memory-eager.rs b/src/test/ui/sanitize/memory-eager.rs
new file mode 100644
index 000000000..cc0593ec0
--- /dev/null
+++ b/src/test/ui/sanitize/memory-eager.rs
@@ -0,0 +1,38 @@
+// needs-sanitizer-support
+// needs-sanitizer-memory
+// min-llvm-version: 14.0.0
+//
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
+//
+// run-fail
+// error-pattern: MemorySanitizer: use-of-uninitialized-value
+// error-pattern: Uninitialized value was created by an allocation
+// error-pattern: in the stack frame
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+#![feature(bench_black_box)]
+
+use std::hint::black_box;
+use std::mem::MaybeUninit;
+
+#[inline(never)]
+#[no_mangle]
+#[allow(invalid_value)]
+fn random() -> char {
+ let r = unsafe { MaybeUninit::uninit().assume_init() };
+ // Avoid optimizing everything out.
+ black_box(r)
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+ random();
+ 0
+}
diff --git a/src/test/ui/sanitize/memory.rs b/src/test/ui/sanitize/memory.rs
index b53f19a5b..14d4de65d 100644
--- a/src/test/ui/sanitize/memory.rs
+++ b/src/test/ui/sanitize/memory.rs
@@ -1,12 +1,15 @@
// needs-sanitizer-support
// needs-sanitizer-memory
//
-// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
//
// run-fail
// error-pattern: MemorySanitizer: use-of-uninitialized-value
// error-pattern: Uninitialized value was created by an allocation
-// error-pattern: in the stack frame of function 'main'
+// error-pattern: in the stack frame
//
// This test case intentionally limits the usage of the std,
// since it will be linked with an uninstrumented version of it.
@@ -14,6 +17,7 @@
#![feature(core_intrinsics)]
#![feature(start)]
#![feature(bench_black_box)]
+#![allow(invalid_value)]
use std::hint::black_box;
use std::mem::MaybeUninit;
@@ -21,9 +25,9 @@ use std::mem::MaybeUninit;
#[inline(never)]
#[no_mangle]
fn random() -> [isize; 32] {
- let r = unsafe { MaybeUninit::uninit().assume_init() };
+ let r = MaybeUninit::uninit();
// Avoid optimizing everything out.
- black_box(r)
+ unsafe { std::intrinsics::volatile_load(r.as_ptr()) }
}
#[inline(never)]
@@ -38,6 +42,6 @@ fn xor(a: &[isize]) -> isize {
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
- let r = random();
+ let r = black_box(random as fn() -> [isize; 32])();
xor(&r)
}
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
index 35a65facb..0ec0d4be5 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
@@ -31,7 +31,7 @@ LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn foo(self: &Rc<Self>) -> usize;
| ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
- = note: required because of the requirements on the impl of `CoerceUnsized<Rc<dyn Foo>>` for `Rc<usize>`
+ = note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
= note: required by cast to type `Rc<dyn Foo>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
index a74752cf8..b494b448e 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
@@ -14,7 +14,7 @@ LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn foo(self: &Rc<Self>) -> usize;
| ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
- = note: required because of the requirements on the impl of `CoerceUnsized<Rc<dyn Foo>>` for `Rc<usize>`
+ = note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
= note: required by cast to type `Rc<dyn Foo>`
error: aborting due to previous error
diff --git a/src/test/ui/simd/intrinsic/ptr-cast.rs b/src/test/ui/simd/intrinsic/ptr-cast.rs
new file mode 100644
index 000000000..1d13720bc
--- /dev/null
+++ b/src/test/ui/simd/intrinsic/ptr-cast.rs
@@ -0,0 +1,33 @@
+// run-pass
+
+#![feature(repr_simd, platform_intrinsics)]
+
+extern "platform-intrinsic" {
+ fn simd_cast_ptr<T, U>(x: T) -> U;
+ fn simd_expose_addr<T, U>(x: T) -> U;
+ fn simd_from_exposed_addr<T, U>(x: T) -> U;
+}
+
+#[derive(Copy, Clone)]
+#[repr(simd)]
+struct V<T>([T; 2]);
+
+fn main() {
+ unsafe {
+ let mut foo = 4i8;
+ let ptr = &mut foo as *mut i8;
+
+ let ptrs = V::<*mut i8>([ptr, core::ptr::null_mut()]);
+
+ // change constness and type
+ let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs);
+
+ let exposed_addr: V<usize> = simd_expose_addr(const_ptrs);
+
+ let from_exposed_addr: V<*mut i8> = simd_from_exposed_addr(exposed_addr);
+
+ assert!(const_ptrs.0 == [ptr as *const u8, core::ptr::null()]);
+ assert!(exposed_addr.0 == [ptr as usize, 0]);
+ assert!(from_exposed_addr.0 == ptrs.0);
+ }
+}
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
index b280c8ab6..94f578af2 100644
--- a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
@@ -12,7 +12,8 @@ impl A {
trait C{async fn new(val: T) {} //~ ERROR `async fn` is not permitted in Rust 2015
//~^ ERROR functions in traits cannot be declared `async`
-//~^^ ERROR cannot find type `T` in this scope
-//~^^^ WARN changes to closure capture in Rust 2021 will affect drop order [rust_2021_incompatible_closure_captures]
+//~| ERROR mismatched types
+//~| ERROR cannot find type `T` in this scope
+//~| WARN changes to closure capture in Rust 2021 will affect drop order [rust_2021_incompatible_closure_captures]
//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
index 50de23229..3814c568e 100644
--- a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
@@ -1,5 +1,5 @@
error: this file contains an unclosed delimiter
- --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:18:53
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:19:53
|
LL | trait C{async fn new(val: T) {}
| - unclosed delimiter
@@ -25,17 +25,6 @@ LL | trait C{async fn new(val: T) {}
= help: pass `--edition 2021` to `rustc`
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
-error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:9
- |
-LL | trait C{async fn new(val: T) {}
- | -----^^^^^^^^^^^^^^^^^^
- | |
- | `async` because of this
- |
- = note: `async` trait functions are not currently supported
- = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
-
error[E0423]: expected function, found module `crate`
--> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:9:5
|
@@ -51,6 +40,19 @@ LL | pub struct A {}
LL | trait C{async fn new(val: T) {}
| ^ help: a struct with a similar name exists: `A`
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:9
+ |
+LL | trait C{async fn new(val: T) {}
+ | -----^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
warning: changes to closure capture in Rust 2021 will affect drop order
--> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:6:57
|
@@ -72,6 +74,20 @@ help: add a dummy let to cause `path` to be fully captured
LL | async fn create(path: impl AsRef<std::path::Path>) { let _ = &path;
| ++++++++++++++
+error[E0308]: mismatched types
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30
+ |
+LL | trait C{async fn new(val: T) {}
+ | ^^ expected associated type, found opaque type
+ |
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+ |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
+ |
+ = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30>)
+ found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
warning: changes to closure capture in Rust 2021 will affect drop order
--> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30
|
@@ -87,7 +103,7 @@ help: add a dummy let to cause `val` to be fully captured
LL | trait C{async fn new(val: T) { let _ = &val;}
| +++++++++++++
-error: aborting due to 6 previous errors; 2 warnings emitted
+error: aborting due to 7 previous errors; 2 warnings emitted
-Some errors have detailed explanations: E0412, E0423, E0670, E0706.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0308, E0412, E0423, E0670, E0706.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index e676d7372..15179954a 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -64,7 +64,7 @@ LL | fn foo(Option<i32>, String) {}
help: remove the extra argument
|
LL | foo(Some(42), 2);
- | ~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/issue-34264.rs:8:13
@@ -78,7 +78,7 @@ note: function defined here
--> $DIR/issue-34264.rs:3:4
|
LL | fn bar(x, y: usize) {}
- | ^^^ - --------
+ | ^^^ --------
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/issue-34264.rs:10:5
@@ -94,7 +94,7 @@ LL | fn bar(x, y: usize) {}
help: remove the extra argument
|
LL | bar(1, 2);
- | ~~~~~~~~~
+ | ~~~~~~
error: aborting due to 6 previous errors
diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr
index 2bc3ff4c3..d8fddc800 100644
--- a/src/test/ui/span/issue-35987.stderr
+++ b/src/test/ui/span/issue-35987.stderr
@@ -2,7 +2,9 @@ error[E0404]: expected trait, found type parameter `Add`
--> $DIR/issue-35987.rs:5:21
|
LL | impl<T: Clone, Add> Add for Foo<T> {
- | ^^^ not a trait
+ | --- ^^^ not a trait
+ | |
+ | found this type parameter
|
help: consider importing this trait instead
|
diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs
deleted file mode 100644
index 70e04bf7e..000000000
--- a/src/test/ui/span/issue-36530.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// gate-test-custom_inner_attributes
-
-#![feature(register_attr)]
-
-#![register_attr(foo)]
-
-#[foo]
-mod foo {
- #![foo] //~ ERROR custom inner attributes are unstable
-}
-
-fn main() {}
diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr
deleted file mode 100644
index a998d7217..000000000
--- a/src/test/ui/span/issue-36530.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: custom inner attributes are unstable
- --> $DIR/issue-36530.rs:9:8
- |
-LL | #![foo]
- | ^^^
- |
- = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
- = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.rs b/src/test/ui/span/lint-unused-unsafe-thir.rs
index 95a537ed2..adb72c26b 100644
--- a/src/test/ui/span/lint-unused-unsafe-thir.rs
+++ b/src/test/ui/span/lint-unused-unsafe-thir.rs
@@ -22,7 +22,7 @@ fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block
unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block
-unsafe fn bad5() { unsafe { unsf() } } //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } }
fn bad6() {
unsafe { // don't put the warning here
unsafe { //~ ERROR: unnecessary `unsafe` block
@@ -31,7 +31,7 @@ fn bad6() {
}
}
unsafe fn bad7() {
- unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsf()
}
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.stderr b/src/test/ui/span/lint-unused-unsafe-thir.stderr
index 6654910c5..3bcbb7597 100644
--- a/src/test/ui/span/lint-unused-unsafe-thir.stderr
+++ b/src/test/ui/span/lint-unused-unsafe-thir.stderr
@@ -31,14 +31,6 @@ LL | fn bad4() { unsafe { callback(||{}) } }
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe-thir.rs:25:20
- |
-LL | unsafe fn bad5() { unsafe { unsf() } }
- | ---------------- ^^^^^^ unnecessary `unsafe` block
- | |
- | because it's nested under this `unsafe` fn
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe-thir.rs:28:9
|
LL | unsafe { // don't put the warning here
@@ -54,13 +46,5 @@ LL | unsafe {
LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe-thir.rs:34:5
- |
-LL | unsafe fn bad7() {
- | ---------------- because it's nested under this `unsafe` fn
-LL | unsafe {
- | ^^^^^^ unnecessary `unsafe` block
-
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/test/ui/span/lint-unused-unsafe.mir.stderr b/src/test/ui/span/lint-unused-unsafe.mir.stderr
index 850550a1d..d8412908c 100644
--- a/src/test/ui/span/lint-unused-unsafe.mir.stderr
+++ b/src/test/ui/span/lint-unused-unsafe.mir.stderr
@@ -29,17 +29,6 @@ LL | fn bad4() { unsafe { callback(||{}) } }
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:30:20
- |
-LL | unsafe fn bad5() { unsafe { unsf() } }
- | ---------------- ^^^^^^ unnecessary `unsafe` block
- | |
- | because it's nested under this `unsafe` fn
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
- = note: `#[allow(unsafe_op_in_unsafe_fn)]` on by default
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:32:5
|
LL | unsafe {
@@ -52,17 +41,6 @@ LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:40:9
- |
-LL | unsafe fn bad7() {
- | ---------------- because it's nested under this `unsafe` fn
-LL | unsafe {
-LL | unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:74:9
|
LL | unsafe {
@@ -273,90 +251,31 @@ LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:197:13
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-LL | unsafe {
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:194:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:198:13
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:199:13
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:205:9
- |
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-LL | unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:203:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:207:13
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-...
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
LL | unsafe { unsf() }
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:208:13
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | unsafe { unsf() }
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:209:13
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | unsafe { unsf() }
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:220:17
@@ -398,19 +317,12 @@ LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:254:9
+ --> $DIR/lint-unused-unsafe.rs:255:13
|
-LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- | ----------------------------------------------- because it's nested under this `unsafe` fn
LL | unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:252:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ------ because it's nested under this `unsafe` block
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:268:13
@@ -631,90 +543,31 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:409:24
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:406:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:410:24
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:411:24
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:417:20
- |
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:415:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:419:24
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-...
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:420:24
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:421:24
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:432:28
@@ -756,19 +609,12 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:466:20
+ --> $DIR/lint-unused-unsafe.rs:467:24
|
-LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- | ----------------------------------------------- because it's nested under this `unsafe` fn
LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:464:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:480:24
@@ -989,90 +835,31 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:622:24
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
-LL | let _ = || unsafe { let _ = || unsf(); };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:619:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:623:24
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { let _ = || unsf(); };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:624:24
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { let _ = || unsf(); };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:630:20
- |
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:628:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:632:24
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-...
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsf();
LL | let _ = || unsafe { let _ = || unsf(); };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:633:24
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { let _ = || unsf(); };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:634:24
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { let _ = || unsf(); };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:645:28
@@ -1114,19 +901,12 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:679:20
+ --> $DIR/lint-unused-unsafe.rs:680:24
|
-LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- | ----------------------------------------------- because it's nested under this `unsafe` fn
LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:677:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:693:24
@@ -1257,90 +1037,31 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:784:28
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:781:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:785:28
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:786:28
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:792:24
- |
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:790:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:794:28
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-...
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:795:28
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:796:28
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:807:32
@@ -1382,19 +1103,12 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:841:24
+ --> $DIR/lint-unused-unsafe.rs:842:28
|
-LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- | ----------------------------------------------- because it's nested under this `unsafe` fn
LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:839:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:855:28
@@ -1525,90 +1239,31 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:942:28
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:939:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:943:28
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:944:28
- |
-LL | unsafe fn granularity_2() {
- | ------------------------- because it's nested under this `unsafe` fn
-...
-LL | let _ = || unsafe { unsf() };
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:950:24
- |
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:948:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:952:28
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
-...
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:953:28
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:954:28
|
-LL | unsafe fn top_level_used_2() {
- | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = || unsafe { unsf() };
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:965:32
@@ -1650,19 +1305,12 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:999:24
+ --> $DIR/lint-unused-unsafe.rs:1000:28
|
-LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- | ----------------------------------------------- because it's nested under this `unsafe` fn
LL | let _ = || unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:997:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:1013:28
@@ -1673,21 +1321,6 @@ LL | let _ = || unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:1044:9
- |
-LL | unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
- | -------------------------------------------------- because it's nested under this `unsafe` fn
-LL | unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:1045:21
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:1059:29
|
LL | let _ = async { unsafe {
@@ -1727,86 +1360,31 @@ LL | let _ = async { unsafe {
| ^^^^^^ unnecessary `unsafe` block
error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:1074:33
- |
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL | let _ = async { unsafe { let _ = async { unsf() }; }};
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/lint-unused-unsafe.rs:1071:17
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:1075:33
- |
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL | let _ = async { unsafe { let _ = async { unsf() }; }};
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:1076:33
- |
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL | let _ = async { unsafe { let _ = async { unsf() }; }};
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
- --> $DIR/lint-unused-unsafe.rs:1078:29
- |
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL | let _ = async { unsafe {
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:1080:33
|
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
+LL | let _ = async { unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = async { unsf() };
LL | let _ = async { unsafe { let _ = async { unsf() }; }};
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:1081:33
|
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
+LL | let _ = async { unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = async { unsafe { let _ = async { unsf() }; }};
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:1082:33
|
-LL | async unsafe fn async_blocks() {
- | ------------------------------ because it's nested under this `unsafe` fn
+LL | let _ = async { unsafe {
+ | ------ because it's nested under this `unsafe` block
...
LL | let _ = async { unsafe { let _ = async { unsf() }; }};
| ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
error: unnecessary `unsafe` block
--> $DIR/lint-unused-unsafe.rs:1092:22
@@ -1820,5 +1398,5 @@ error: unnecessary `unsafe` block
LL | let _x: [(); unsafe { unsafe { size() } }] = [];
| ^^^^^^ unnecessary `unsafe` block
-error: aborting due to 201 previous errors
+error: aborting due to 174 previous errors
diff --git a/src/test/ui/span/lint-unused-unsafe.rs b/src/test/ui/span/lint-unused-unsafe.rs
index f8d1dff35..5d042768b 100644
--- a/src/test/ui/span/lint-unused-unsafe.rs
+++ b/src/test/ui/span/lint-unused-unsafe.rs
@@ -27,7 +27,7 @@ fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block
unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block
-unsafe fn bad5() { unsafe { unsf() } } //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } }
fn bad6() {
unsafe { //~ ERROR: unnecessary `unsafe` block
unsafe { // don't put the warning here
@@ -37,7 +37,7 @@ fn bad6() {
}
unsafe fn bad7() {
unsafe { //~ ERROR: unnecessary `unsafe` block
- unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {
unsf()
}
}
@@ -194,15 +194,15 @@ mod additional_tests {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
unsafe { //~ ERROR: unnecessary `unsafe` block
- unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
- unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
- unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() }
+ unsafe { unsf() }
+ unsafe { unsf() }
}
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
- unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {
unsf();
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
@@ -251,8 +251,8 @@ mod additional_tests {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- unsafe { //~ ERROR: unnecessary `unsafe` block
- unsafe {
+ unsafe {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
@@ -406,15 +406,15 @@ mod additional_tests_closures {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
@@ -463,8 +463,8 @@ mod additional_tests_closures {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
@@ -619,15 +619,15 @@ mod additional_tests_even_more_closures {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); };
+ let _ = || unsafe { let _ = || unsf(); };
+ let _ = || unsafe { let _ = || unsf(); };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
let _ = || unsf();
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
@@ -676,8 +676,8 @@ mod additional_tests_even_more_closures {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
let _ = || unsf();
@@ -781,15 +781,15 @@ mod item_likes {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
@@ -838,8 +838,8 @@ mod item_likes {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
@@ -939,15 +939,15 @@ mod item_likes {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granularity_2() {
let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
};
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn top_level_used_2() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
unsf();
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
@@ -996,8 +996,8 @@ mod item_likes {
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn granular_disallow_op_in_unsafe_fn_3() {
- let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = || unsafe {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
#[deny(unsafe_op_in_unsafe_fn)]
{
unsf();
@@ -1041,7 +1041,7 @@ mod additional_tests_extra {
#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
- unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {
#[allow(unsafe_op_in_unsafe_fn)]
{
unsf();
@@ -1071,11 +1071,11 @@ mod additional_tests_extra {
#[allow(unsafe_op_in_unsafe_fn)]
{
let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
- let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
- let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
- let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }};
+ let _ = async { unsafe { let _ = async { unsf() }; }};
+ let _ = async { unsafe { let _ = async { unsf() }; }};
}};
- let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe {
let _ = async { unsf() };
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr
index e68260e4a..b76a3ab30 100644
--- a/src/test/ui/span/missing-unit-argument.stderr
+++ b/src/test/ui/span/missing-unit-argument.stderr
@@ -12,7 +12,7 @@ LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
help: provide the argument
|
LL | let _: Result<(), String> = Ok(());
- | ~~~~~~
+ | ~~~~
error[E0061]: this function takes 2 arguments but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:12:5
@@ -28,7 +28,7 @@ LL | fn foo(():(), ():()) {}
help: provide the arguments
|
LL | foo((), ());
- | ~~~~~~~~~~~
+ | ~~~~~~~~
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/missing-unit-argument.rs:13:5
@@ -44,7 +44,7 @@ LL | fn foo(():(), ():()) {}
help: provide the argument
|
LL | foo((), ());
- | ~~~~~~~~~~~
+ | ~~~~~~~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:14:5
@@ -60,7 +60,7 @@ LL | fn bar(():()) {}
help: provide the argument
|
LL | bar(());
- | ~~~~~~~
+ | ~~~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:15:7
@@ -72,11 +72,11 @@ note: associated function defined here
--> $DIR/missing-unit-argument.rs:6:8
|
LL | fn baz(self, (): ()) { }
- | ^^^ ---- ------
+ | ^^^ ------
help: provide the argument
|
LL | S.baz(());
- | ~~~~~~~
+ | ~~~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:16:7
@@ -88,11 +88,11 @@ note: associated function defined here
--> $DIR/missing-unit-argument.rs:7:8
|
LL | fn generic<T>(self, _: T) { }
- | ^^^^^^^ ---- ----
+ | ^^^^^^^ ----
help: provide the argument
|
LL | S.generic::<()>(());
- | ~~~~~~~~~~~~~~~~~
+ | ~~~~
error: aborting due to 6 previous errors
diff --git a/src/test/ui/specialization/default-generic-associated-type-bound.rs b/src/test/ui/specialization/default-generic-associated-type-bound.rs
index 0f5714e99..31a0685d0 100644
--- a/src/test/ui/specialization/default-generic-associated-type-bound.rs
+++ b/src/test/ui/specialization/default-generic-associated-type-bound.rs
@@ -1,8 +1,7 @@
// Check that default generics associated types are validated.
#![feature(specialization)]
-#![feature(generic_associated_types)]
-//~^^ WARNING `specialization` is incomplete
+//~^ WARNING `specialization` is incomplete
trait X {
type U<'a>: PartialEq<&'a Self> where Self: 'a;
diff --git a/src/test/ui/specialization/default-generic-associated-type-bound.stderr b/src/test/ui/specialization/default-generic-associated-type-bound.stderr
index 58c6667c8..44c24c1e5 100644
--- a/src/test/ui/specialization/default-generic-associated-type-bound.stderr
+++ b/src/test/ui/specialization/default-generic-associated-type-bound.stderr
@@ -9,14 +9,14 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
error[E0277]: can't compare `T` with `T`
- --> $DIR/default-generic-associated-type-bound.rs:18:26
+ --> $DIR/default-generic-associated-type-bound.rs:17:26
|
LL | default type U<'a> = &'a T;
| ^^^^^ no implementation for `T == T`
|
- = note: required because of the requirements on the impl of `PartialEq` for `&'a T`
+ = note: required for `&'a T` to implement `PartialEq`
note: required by a bound in `X::U`
- --> $DIR/default-generic-associated-type-bound.rs:8:17
+ --> $DIR/default-generic-associated-type-bound.rs:7:17
|
LL | type U<'a>: PartialEq<&'a Self> where Self: 'a;
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `X::U`
diff --git a/src/test/ui/specialization/issue-33017.rs b/src/test/ui/specialization/issue-33017.rs
index 4d19230df..8dbadf58d 100644
--- a/src/test/ui/specialization/issue-33017.rs
+++ b/src/test/ui/specialization/issue-33017.rs
@@ -1,4 +1,4 @@
-// Test to ensure that trait bounds are propertly
+// Test to ensure that trait bounds are properly
// checked on specializable associated types
#![allow(incomplete_features)]
diff --git a/src/test/ui/specialization/issue-38091-2.stderr b/src/test/ui/specialization/issue-38091-2.stderr
index a93f27ff0..146a56358 100644
--- a/src/test/ui/specialization/issue-38091-2.stderr
+++ b/src/test/ui/specialization/issue-38091-2.stderr
@@ -10,7 +10,7 @@ LL | #![feature(specialization)]
error[E0275]: overflow evaluating the requirement `i32: Check`
|
-note: required because of the requirements on the impl of `Iterate` for `i32`
+note: required for `i32` to implement `Iterate`
--> $DIR/issue-38091-2.rs:11:13
|
LL | impl<'a, T> Iterate<'a> for T
diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr
index c4fc44c73..9b74f684b 100644
--- a/src/test/ui/specialization/issue-39448.stderr
+++ b/src/test/ui/specialization/issue-39448.stderr
@@ -14,12 +14,12 @@ error[E0275]: overflow evaluating the requirement `T: FromA<U>`
LL | x.foo(y.to()).to()
| ^^
|
-note: required because of the requirements on the impl of `FromA<U>` for `T`
+note: required for `T` to implement `FromA<U>`
--> $DIR/issue-39448.rs:24:29
|
LL | impl<T: A, U: A + FromA<T>> FromA<T> for U {
| ^^^^^^^^ ^
-note: required because of the requirements on the impl of `ToA<T>` for `U`
+note: required for `U` to implement `ToA<T>`
--> $DIR/issue-39448.rs:34:12
|
LL | impl<T, U> ToA<U> for T
diff --git a/src/test/ui/specialization/issue-45814.stderr b/src/test/ui/specialization/issue-45814.stderr
index ab6adf477..419345add 100644
--- a/src/test/ui/specialization/issue-45814.stderr
+++ b/src/test/ui/specialization/issue-45814.stderr
@@ -1,13 +1,13 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
-note: required because of the requirements on the impl of `Trait<_>` for `T`
+note: required for `T` to implement `Trait<_>`
--> $DIR/issue-45814.rs:8:20
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
= note: 128 redundant requirements hidden
- = note: required because of the requirements on the impl of `Trait<_>` for `T`
+ = note: required for `T` to implement `Trait<_>`
error: aborting due to previous error
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr
index cfb9007c7..fd34a59d2 100644
--- a/src/test/ui/specialization/min_specialization/issue-79224.stderr
+++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr
@@ -1,22 +1,28 @@
error[E0277]: the trait bound `B: Clone` is not satisfied
- --> $DIR/issue-79224.rs:18:17
+ --> $DIR/issue-79224.rs:18:1
|
-LL | impl<B: ?Sized> Display for Cow<'_, B> {
- | ^^^^^^^ the trait `Clone` is not implemented for `B`
+LL | / impl<B: ?Sized> Display for Cow<'_, B> {
+LL | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+LL | | write!(f, "foo")
+LL | | }
+LL | | }
+ | |_^ the trait `Clone` is not implemented for `B`
|
- = note: required because of the requirements on the impl of `ToOwned` for `B`
+ = note: required for `B` to implement `ToOwned`
help: consider further restricting this bound
|
LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
| +++++++++++++++++++
error[E0277]: the trait bound `B: Clone` is not satisfied
- --> $DIR/issue-79224.rs:19:12
+ --> $DIR/issue-79224.rs:19:5
|
-LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- | ^^^^^ the trait `Clone` is not implemented for `B`
+LL | / fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+LL | | write!(f, "foo")
+LL | | }
+ | |_____^ the trait `Clone` is not implemented for `B`
|
- = note: required because of the requirements on the impl of `ToOwned` for `B`
+ = note: required for `B` to implement `ToOwned`
help: consider further restricting this bound
|
LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
diff --git a/src/test/ui/stability-attribute/auxiliary/ctor-stability.rs b/src/test/ui/stability-attribute/auxiliary/ctor-stability.rs
new file mode 100644
index 000000000..74c6023d7
--- /dev/null
+++ b/src/test/ui/stability-attribute/auxiliary/ctor-stability.rs
@@ -0,0 +1,8 @@
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "none", since = "1.0")]
+
+#[stable(feature = "none", since = "1.0")]
+pub enum Foo {
+ A,
+}
diff --git a/src/test/ui/stability-attribute/auxiliary/default_body.rs b/src/test/ui/stability-attribute/auxiliary/default_body.rs
new file mode 100644
index 000000000..3a177419d
--- /dev/null
+++ b/src/test/ui/stability-attribute/auxiliary/default_body.rs
@@ -0,0 +1,29 @@
+#![crate_type = "lib"]
+#![feature(staged_api, rustc_attrs)]
+#![stable(feature = "stable_feature", since = "1.0.0")]
+
+#[stable(feature = "stable_feature", since = "1.0.0")]
+pub trait JustTrait {
+ #[stable(feature = "stable_feature", since = "1.0.0")]
+ #[rustc_default_body_unstable(feature = "constant_default_body", issue = "none")]
+ const CONSTANT: usize = 0;
+
+ #[rustc_default_body_unstable(feature = "fun_default_body", issue = "none")]
+ #[stable(feature = "stable_feature", since = "1.0.0")]
+ fn fun() {}
+}
+
+#[rustc_must_implement_one_of(eq, neq)]
+#[stable(feature = "stable_feature", since = "1.0.0")]
+pub trait Equal {
+ #[rustc_default_body_unstable(feature = "eq_default_body", issue = "none")]
+ #[stable(feature = "stable_feature", since = "1.0.0")]
+ fn eq(&self, other: &Self) -> bool {
+ !self.neq(other)
+ }
+
+ #[stable(feature = "stable_feature", since = "1.0.0")]
+ fn neq(&self, other: &Self) -> bool {
+ !self.eq(other)
+ }
+}
diff --git a/src/test/ui/stability-attribute/ctor-stability.rs b/src/test/ui/stability-attribute/ctor-stability.rs
new file mode 100644
index 000000000..fcab0cb10
--- /dev/null
+++ b/src/test/ui/stability-attribute/ctor-stability.rs
@@ -0,0 +1,8 @@
+// aux-build:ctor-stability.rs
+// check-pass
+
+extern crate ctor_stability;
+
+fn main() {
+ let _ = ctor_stability::Foo::A;
+}
diff --git a/src/test/ui/stability-attribute/default-body-stability-err.rs b/src/test/ui/stability-attribute/default-body-stability-err.rs
new file mode 100644
index 000000000..ecb281bcc
--- /dev/null
+++ b/src/test/ui/stability-attribute/default-body-stability-err.rs
@@ -0,0 +1,19 @@
+// aux-build:default_body.rs
+#![crate_type = "lib"]
+
+extern crate default_body;
+
+use default_body::{Equal, JustTrait};
+
+struct Type;
+
+impl JustTrait for Type {}
+//~^ ERROR not all trait items implemented, missing: `CONSTANT` [E0046]
+//~| ERROR not all trait items implemented, missing: `fun` [E0046]
+
+impl Equal for Type {
+ //~^ ERROR not all trait items implemented, missing: `eq` [E0046]
+ fn neq(&self, other: &Self) -> bool {
+ false
+ }
+}
diff --git a/src/test/ui/stability-attribute/default-body-stability-err.stderr b/src/test/ui/stability-attribute/default-body-stability-err.stderr
new file mode 100644
index 000000000..ef666f30f
--- /dev/null
+++ b/src/test/ui/stability-attribute/default-body-stability-err.stderr
@@ -0,0 +1,38 @@
+error[E0046]: not all trait items implemented, missing: `CONSTANT`
+ --> $DIR/default-body-stability-err.rs:10:1
+ |
+LL | impl JustTrait for Type {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: default implementation of `CONSTANT` is unstable
+ = note: use of unstable library feature 'constant_default_body'
+ = help: add `#![feature(constant_default_body)]` to the crate attributes to enable
+
+error[E0046]: not all trait items implemented, missing: `fun`
+ --> $DIR/default-body-stability-err.rs:10:1
+ |
+LL | impl JustTrait for Type {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: default implementation of `fun` is unstable
+ = note: use of unstable library feature 'fun_default_body'
+ = help: add `#![feature(fun_default_body)]` to the crate attributes to enable
+
+error[E0046]: not all trait items implemented, missing: `eq`
+ --> $DIR/default-body-stability-err.rs:14:1
+ |
+LL | / impl Equal for Type {
+LL | |
+LL | | fn neq(&self, other: &Self) -> bool {
+LL | | false
+LL | | }
+LL | | }
+ | |_^
+ |
+ = note: default implementation of `eq` is unstable
+ = note: use of unstable library feature 'eq_default_body'
+ = help: add `#![feature(eq_default_body)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/stability-attribute/default-body-stability-ok-enables.rs b/src/test/ui/stability-attribute/default-body-stability-ok-enables.rs
new file mode 100644
index 000000000..bdc7522f4
--- /dev/null
+++ b/src/test/ui/stability-attribute/default-body-stability-ok-enables.rs
@@ -0,0 +1,18 @@
+// check-pass
+// aux-build:default_body.rs
+#![crate_type = "lib"]
+#![feature(fun_default_body, eq_default_body, constant_default_body)]
+
+extern crate default_body;
+
+use default_body::{Equal, JustTrait};
+
+struct Type;
+
+impl JustTrait for Type {}
+
+impl Equal for Type {
+ fn neq(&self, other: &Self) -> bool {
+ false
+ }
+}
diff --git a/src/test/ui/stability-attribute/default-body-stability-ok-impls.rs b/src/test/ui/stability-attribute/default-body-stability-ok-impls.rs
new file mode 100644
index 000000000..e1f5c0170
--- /dev/null
+++ b/src/test/ui/stability-attribute/default-body-stability-ok-impls.rs
@@ -0,0 +1,21 @@
+// check-pass
+// aux-build:default_body.rs
+#![crate_type = "lib"]
+
+extern crate default_body;
+
+use default_body::{Equal, JustTrait};
+
+struct Type;
+
+impl JustTrait for Type {
+ const CONSTANT: usize = 1;
+
+ fn fun() {}
+}
+
+impl Equal for Type {
+ fn eq(&self, other: &Self) -> bool {
+ false
+ }
+}
diff --git a/src/test/ui/static/static-vec-repeat-not-constant.stderr b/src/test/ui/static/static-vec-repeat-not-constant.stderr
index 84fc638a9..dec012318 100644
--- a/src/test/ui/static/static-vec-repeat-not-constant.stderr
+++ b/src/test/ui/static/static-vec-repeat-not-constant.stderr
@@ -5,6 +5,7 @@ LL | static a: [isize; 2] = [foo(); 2];
| ^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
+ = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
error: aborting due to previous error
diff --git a/src/test/ui/stats/hir-stats.rs b/src/test/ui/stats/hir-stats.rs
new file mode 100644
index 000000000..5102574d4
--- /dev/null
+++ b/src/test/ui/stats/hir-stats.rs
@@ -0,0 +1,42 @@
+// check-pass
+// compile-flags: -Zhir-stats
+// only-x86_64
+// ignore-stage1
+
+// The aim here is to include at least one of every different type of top-level
+// AST/HIR node reported by `-Zhir-stats`.
+
+#![allow(dead_code)]
+
+use std::arch::asm;
+use std::fmt::Debug;
+use std::ffi::c_void;
+
+extern "C" { fn f(p: *mut c_void); }
+
+/// An enum.
+enum E<'a, T: Copy> { A { t: T }, B(&'a u32) }
+
+trait Go {
+ type G: Debug;
+ fn go(self) -> u32;
+}
+
+impl<'a, T: Copy> Go for E<'a, T> {
+ type G = bool;
+ fn go(self) -> u32 {
+ 99
+ }
+}
+
+fn f2<T>(t: T) where T: Debug {}
+
+fn main() {
+ let x = E::A { t: 3 };
+ match x {
+ E::A { .. } => {}
+ _ => {}
+ }
+
+ unsafe { asm!("mov rdi, 1"); }
+}
diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr
new file mode 100644
index 000000000..8d9776065
--- /dev/null
+++ b/src/test/ui/stats/hir-stats.stderr
@@ -0,0 +1,178 @@
+ast-stats-1 PRE EXPANSION AST STATS
+ast-stats-1 Name Accumulated Size Count Item Size
+ast-stats-1 ----------------------------------------------------------------
+ast-stats-1 ExprField 48 ( 0.6%) 1 48
+ast-stats-1 Crate 56 ( 0.7%) 1 56
+ast-stats-1 Attribute 64 ( 0.8%) 2 32
+ast-stats-1 - Normal 32 ( 0.4%) 1
+ast-stats-1 - DocComment 32 ( 0.4%) 1
+ast-stats-1 GenericArgs 64 ( 0.8%) 1 64
+ast-stats-1 - AngleBracketed 64 ( 0.8%) 1
+ast-stats-1 Local 72 ( 0.9%) 1 72
+ast-stats-1 WherePredicate 72 ( 0.9%) 1 72
+ast-stats-1 - BoundPredicate 72 ( 0.9%) 1
+ast-stats-1 Arm 96 ( 1.1%) 2 48
+ast-stats-1 ForeignItem 96 ( 1.1%) 1 96
+ast-stats-1 - Fn 96 ( 1.1%) 1
+ast-stats-1 FieldDef 160 ( 1.9%) 2 80
+ast-stats-1 Stmt 160 ( 1.9%) 5 32
+ast-stats-1 - Local 32 ( 0.4%) 1
+ast-stats-1 - MacCall 32 ( 0.4%) 1
+ast-stats-1 - Expr 96 ( 1.1%) 3
+ast-stats-1 Param 160 ( 1.9%) 4 40
+ast-stats-1 FnDecl 200 ( 2.4%) 5 40
+ast-stats-1 Variant 240 ( 2.9%) 2 120
+ast-stats-1 Block 288 ( 3.4%) 6 48
+ast-stats-1 GenericBound 352 ( 4.2%) 4 88
+ast-stats-1 - Trait 352 ( 4.2%) 4
+ast-stats-1 AssocItem 416 ( 4.9%) 4 104
+ast-stats-1 - TyAlias 208 ( 2.5%) 2
+ast-stats-1 - Fn 208 ( 2.5%) 2
+ast-stats-1 GenericParam 480 ( 5.7%) 5 96
+ast-stats-1 PathSegment 720 ( 8.6%) 30 24
+ast-stats-1 Expr 832 ( 9.9%) 8 104
+ast-stats-1 - Path 104 ( 1.2%) 1
+ast-stats-1 - Match 104 ( 1.2%) 1
+ast-stats-1 - Struct 104 ( 1.2%) 1
+ast-stats-1 - Lit 208 ( 2.5%) 2
+ast-stats-1 - Block 312 ( 3.7%) 3
+ast-stats-1 Pat 840 (10.0%) 7 120
+ast-stats-1 - Struct 120 ( 1.4%) 1
+ast-stats-1 - Wild 120 ( 1.4%) 1
+ast-stats-1 - Ident 600 ( 7.1%) 5
+ast-stats-1 Ty 1_344 (16.0%) 14 96
+ast-stats-1 - Rptr 96 ( 1.1%) 1
+ast-stats-1 - Ptr 96 ( 1.1%) 1
+ast-stats-1 - ImplicitSelf 192 ( 2.3%) 2
+ast-stats-1 - Path 960 (11.4%) 10
+ast-stats-1 Item 1_656 (19.7%) 9 184
+ast-stats-1 - Trait 184 ( 2.2%) 1
+ast-stats-1 - Enum 184 ( 2.2%) 1
+ast-stats-1 - ForeignMod 184 ( 2.2%) 1
+ast-stats-1 - Impl 184 ( 2.2%) 1
+ast-stats-1 - Fn 368 ( 4.4%) 2
+ast-stats-1 - Use 552 ( 6.6%) 3
+ast-stats-1 ----------------------------------------------------------------
+ast-stats-1 Total 8_416
+ast-stats-1
+ast-stats-2 POST EXPANSION AST STATS
+ast-stats-2 Name Accumulated Size Count Item Size
+ast-stats-2 ----------------------------------------------------------------
+ast-stats-2 ExprField 48 ( 0.5%) 1 48
+ast-stats-2 Crate 56 ( 0.6%) 1 56
+ast-stats-2 GenericArgs 64 ( 0.7%) 1 64
+ast-stats-2 - AngleBracketed 64 ( 0.7%) 1
+ast-stats-2 Local 72 ( 0.8%) 1 72
+ast-stats-2 WherePredicate 72 ( 0.8%) 1 72
+ast-stats-2 - BoundPredicate 72 ( 0.8%) 1
+ast-stats-2 Arm 96 ( 1.0%) 2 48
+ast-stats-2 ForeignItem 96 ( 1.0%) 1 96
+ast-stats-2 - Fn 96 ( 1.0%) 1
+ast-stats-2 InlineAsm 120 ( 1.3%) 1 120
+ast-stats-2 Attribute 128 ( 1.4%) 4 32
+ast-stats-2 - DocComment 32 ( 0.3%) 1
+ast-stats-2 - Normal 96 ( 1.0%) 3
+ast-stats-2 FieldDef 160 ( 1.7%) 2 80
+ast-stats-2 Stmt 160 ( 1.7%) 5 32
+ast-stats-2 - Local 32 ( 0.3%) 1
+ast-stats-2 - Semi 32 ( 0.3%) 1
+ast-stats-2 - Expr 96 ( 1.0%) 3
+ast-stats-2 Param 160 ( 1.7%) 4 40
+ast-stats-2 FnDecl 200 ( 2.2%) 5 40
+ast-stats-2 Variant 240 ( 2.6%) 2 120
+ast-stats-2 Block 288 ( 3.1%) 6 48
+ast-stats-2 GenericBound 352 ( 3.8%) 4 88
+ast-stats-2 - Trait 352 ( 3.8%) 4
+ast-stats-2 AssocItem 416 ( 4.5%) 4 104
+ast-stats-2 - TyAlias 208 ( 2.3%) 2
+ast-stats-2 - Fn 208 ( 2.3%) 2
+ast-stats-2 GenericParam 480 ( 5.2%) 5 96
+ast-stats-2 PathSegment 792 ( 8.7%) 33 24
+ast-stats-2 Pat 840 ( 9.2%) 7 120
+ast-stats-2 - Struct 120 ( 1.3%) 1
+ast-stats-2 - Wild 120 ( 1.3%) 1
+ast-stats-2 - Ident 600 ( 6.6%) 5
+ast-stats-2 Expr 936 (10.2%) 9 104
+ast-stats-2 - Path 104 ( 1.1%) 1
+ast-stats-2 - Match 104 ( 1.1%) 1
+ast-stats-2 - Struct 104 ( 1.1%) 1
+ast-stats-2 - InlineAsm 104 ( 1.1%) 1
+ast-stats-2 - Lit 208 ( 2.3%) 2
+ast-stats-2 - Block 312 ( 3.4%) 3
+ast-stats-2 Ty 1_344 (14.7%) 14 96
+ast-stats-2 - Rptr 96 ( 1.0%) 1
+ast-stats-2 - Ptr 96 ( 1.0%) 1
+ast-stats-2 - ImplicitSelf 192 ( 2.1%) 2
+ast-stats-2 - Path 960 (10.5%) 10
+ast-stats-2 Item 2_024 (22.1%) 11 184
+ast-stats-2 - Trait 184 ( 2.0%) 1
+ast-stats-2 - Enum 184 ( 2.0%) 1
+ast-stats-2 - ExternCrate 184 ( 2.0%) 1
+ast-stats-2 - ForeignMod 184 ( 2.0%) 1
+ast-stats-2 - Impl 184 ( 2.0%) 1
+ast-stats-2 - Fn 368 ( 4.0%) 2
+ast-stats-2 - Use 736 ( 8.0%) 4
+ast-stats-2 ----------------------------------------------------------------
+ast-stats-2 Total 9_144
+ast-stats-2
+hir-stats HIR STATS
+hir-stats Name Accumulated Size Count Item Size
+hir-stats ----------------------------------------------------------------
+hir-stats ForeignItemRef 24 ( 0.2%) 1 24
+hir-stats Lifetime 32 ( 0.3%) 1 32
+hir-stats Mod 32 ( 0.3%) 1 32
+hir-stats ExprField 40 ( 0.4%) 1 40
+hir-stats TraitItemRef 56 ( 0.6%) 2 28
+hir-stats Local 64 ( 0.7%) 1 64
+hir-stats Param 64 ( 0.7%) 2 32
+hir-stats InlineAsm 72 ( 0.7%) 1 72
+hir-stats ImplItemRef 72 ( 0.7%) 2 36
+hir-stats Body 96 ( 1.0%) 3 32
+hir-stats GenericArg 96 ( 1.0%) 4 24
+hir-stats - Type 24 ( 0.2%) 1
+hir-stats - Lifetime 72 ( 0.7%) 3
+hir-stats FieldDef 96 ( 1.0%) 2 48
+hir-stats Arm 96 ( 1.0%) 2 48
+hir-stats Stmt 96 ( 1.0%) 3 32
+hir-stats - Local 32 ( 0.3%) 1
+hir-stats - Semi 32 ( 0.3%) 1
+hir-stats - Expr 32 ( 0.3%) 1
+hir-stats FnDecl 120 ( 1.2%) 3 40
+hir-stats Attribute 128 ( 1.3%) 4 32
+hir-stats GenericArgs 144 ( 1.5%) 3 48
+hir-stats Variant 160 ( 1.7%) 2 80
+hir-stats WherePredicate 168 ( 1.7%) 3 56
+hir-stats - BoundPredicate 168 ( 1.7%) 3
+hir-stats GenericBound 192 ( 2.0%) 4 48
+hir-stats - Trait 192 ( 2.0%) 4
+hir-stats Block 288 ( 3.0%) 6 48
+hir-stats Pat 360 ( 3.7%) 5 72
+hir-stats - Wild 72 ( 0.7%) 1
+hir-stats - Struct 72 ( 0.7%) 1
+hir-stats - Binding 216 ( 2.2%) 3
+hir-stats GenericParam 400 ( 4.1%) 5 80
+hir-stats Generics 560 ( 5.8%) 10 56
+hir-stats Ty 720 ( 7.4%) 15 48
+hir-stats - Ptr 48 ( 0.5%) 1
+hir-stats - Rptr 48 ( 0.5%) 1
+hir-stats - Path 624 ( 6.4%) 13
+hir-stats Expr 768 ( 7.9%) 12 64
+hir-stats - Path 64 ( 0.7%) 1
+hir-stats - Struct 64 ( 0.7%) 1
+hir-stats - Match 64 ( 0.7%) 1
+hir-stats - InlineAsm 64 ( 0.7%) 1
+hir-stats - Lit 128 ( 1.3%) 2
+hir-stats - Block 384 ( 4.0%) 6
+hir-stats Item 960 ( 9.9%) 12 80
+hir-stats - Trait 80 ( 0.8%) 1
+hir-stats - Enum 80 ( 0.8%) 1
+hir-stats - ExternCrate 80 ( 0.8%) 1
+hir-stats - ForeignMod 80 ( 0.8%) 1
+hir-stats - Impl 80 ( 0.8%) 1
+hir-stats - Fn 160 ( 1.7%) 2
+hir-stats - Use 400 ( 4.1%) 5
+hir-stats Path 1_536 (15.9%) 32 48
+hir-stats PathSegment 2_240 (23.1%) 40 56
+hir-stats ----------------------------------------------------------------
+hir-stats Total 9_680
+hir-stats
diff --git a/src/test/ui/std-backtrace.rs b/src/test/ui/std-backtrace.rs
index 07de066b5..3f8306baf 100644
--- a/src/test/ui/std-backtrace.rs
+++ b/src/test/ui/std-backtrace.rs
@@ -7,8 +7,6 @@
// compile-flags:-g
// compile-flags:-Cstrip=none
-#![feature(backtrace)]
-
use std::env;
use std::process::Command;
use std::str;
diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr
index 9079a18d6..019305def 100644
--- a/src/test/ui/str/str-idx.stderr
+++ b/src/test/ui/str/str-idx.stderr
@@ -8,7 +8,7 @@ LL | let _: u8 = s[4];
= note: you can use `.chars().nth()` or `.bytes().nth()`
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<{integer}>` for `str`
+ = note: required for `str` to implement `Index<{integer}>`
error[E0277]: the type `str` cannot be indexed by `{integer}`
--> $DIR/str-idx.rs:4:19
@@ -53,7 +53,7 @@ LL | let _: u8 = s['c'];
| ^^^ string indices are ranges of `usize`
|
= help: the trait `SliceIndex<str>` is not implemented for `char`
- = note: required because of the requirements on the impl of `Index<char>` for `str`
+ = note: required for `str` to implement `Index<char>`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index 2d062e56a..b165c4825 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -32,7 +32,7 @@ LL | s[1usize] = bot();
|
= help: the trait `SliceIndex<str>` is not implemented for `usize`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<usize>` for `str`
+ = note: required for `str` to implement `Index<usize>`
error[E0277]: the type `str` cannot be indexed by `{integer}`
--> $DIR/str-mut-idx.rs:9:15
@@ -77,7 +77,7 @@ LL | s['c'];
| ^^^ string indices are ranges of `usize`
|
= help: the trait `SliceIndex<str>` is not implemented for `char`
- = note: required because of the requirements on the impl of `Index<char>` for `str`
+ = note: required for `str` to implement `Index<char>`
error: aborting due to 6 previous errors
diff --git a/src/test/ui/structs-enums/align-struct.rs b/src/test/ui/structs-enums/align-struct.rs
index 27ef990aa..f5418e754 100644
--- a/src/test/ui/structs-enums/align-struct.rs
+++ b/src/test/ui/structs-enums/align-struct.rs
@@ -1,6 +1,5 @@
// run-pass
#![allow(dead_code)]
-#![feature(box_syntax)]
use std::mem;
@@ -232,9 +231,9 @@ pub fn main() {
assert_eq!(mem::size_of_val(&a), 32);
assert!(is_aligned_to(&a, 16));
- let mut large = box AlignLarge {
+ let mut large = Box::new(AlignLarge {
stuff: [0; 0x10000],
- };
+ });
large.stuff[0] = 132;
*large.stuff.last_mut().unwrap() = 102;
assert_eq!(large.stuff[0], 132);
diff --git a/src/test/ui/structs-enums/type-sizes.rs b/src/test/ui/structs-enums/type-sizes.rs
index 73a11a5e7..7a23f1363 100644
--- a/src/test/ui/structs-enums/type-sizes.rs
+++ b/src/test/ui/structs-enums/type-sizes.rs
@@ -120,6 +120,54 @@ pub enum AlwaysTaggedBecauseItHasNoNiche {
B
}
+pub enum NicheFilledMultipleFields {
+ A(bool, u8),
+ B(u8),
+ C(u8),
+ D(bool),
+ E,
+ F,
+ G,
+}
+
+struct BoolInTheMiddle(std::num::NonZeroU16, bool, u8);
+
+enum NicheWithData {
+ A,
+ B([u16; 5]),
+ Largest { a1: u32, a2: BoolInTheMiddle, a3: u32 },
+ C,
+ D(u32, u32),
+}
+
+// A type with almost 2^16 invalid values.
+#[repr(u16)]
+pub enum NicheU16 {
+ _0,
+}
+
+pub enum EnumManyVariant<X> {
+ Dataful(u8, X),
+
+ // 0x100 niche variants.
+ _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F,
+ _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F,
+ _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F,
+ _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F,
+ _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F,
+ _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F,
+ _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F,
+ _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F,
+ _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F,
+ _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F,
+ _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF,
+ _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF,
+ _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF,
+ _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF,
+ _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF,
+ _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
+}
+
pub fn main() {
assert_eq!(size_of::<u8>(), 1 as usize);
assert_eq!(size_of::<u32>(), 4 as usize);
@@ -170,4 +218,35 @@ pub fn main() {
assert_eq!(size_of::<AlwaysTaggedBecauseItHasNoNiche>(), 8);
assert_eq!(size_of::<Option<AlwaysTaggedBecauseItHasNoNiche>>(), 8);
assert_eq!(size_of::<Option<Option<AlwaysTaggedBecauseItHasNoNiche>>>(), 8);
+
+ assert_eq!(size_of::<NicheFilledMultipleFields>(), 2);
+ assert_eq!(size_of::<Option<NicheFilledMultipleFields>>(), 2);
+ assert_eq!(size_of::<Option<Option<NicheFilledMultipleFields>>>(), 2);
+
+ struct S1{ a: u16, b: std::num::NonZeroU16, c: u16, d: u8, e: u32, f: u64, g:[u8;2] }
+ assert_eq!(size_of::<S1>(), 24);
+ assert_eq!(size_of::<Option<S1>>(), 24);
+
+ assert_eq!(size_of::<NicheWithData>(), 12);
+ assert_eq!(size_of::<Option<NicheWithData>>(), 12);
+ assert_eq!(size_of::<Option<Option<NicheWithData>>>(), 12);
+ assert_eq!(
+ size_of::<Option<Option2<&(), Option<NicheWithData>>>>(),
+ size_of::<(&(), NicheWithData)>()
+ );
+
+ pub enum FillPadding { A(std::num::NonZeroU8, u32), B }
+ assert_eq!(size_of::<FillPadding>(), 8);
+ assert_eq!(size_of::<Option<FillPadding>>(), 8);
+ assert_eq!(size_of::<Option<Option<FillPadding>>>(), 8);
+
+ assert_eq!(size_of::<Result<(std::num::NonZeroU8, u8, u8), u16>>(), 4);
+ assert_eq!(size_of::<Option<Result<(std::num::NonZeroU8, u8, u8), u16>>>(), 4);
+ assert_eq!(size_of::<Result<(std::num::NonZeroU8, u8, u8, u8), u16>>(), 4);
+
+ assert_eq!(size_of::<EnumManyVariant<u16>>(), 6);
+ assert_eq!(size_of::<EnumManyVariant<NicheU16>>(), 4);
+ assert_eq!(size_of::<EnumManyVariant<Option<NicheU16>>>(), 4);
+ assert_eq!(size_of::<EnumManyVariant<Option2<NicheU16,u8>>>(), 6);
+ assert_eq!(size_of::<EnumManyVariant<Option<(NicheU16,u8)>>>(), 6);
}
diff --git a/src/test/ui/structs/struct-record-suggestion.fixed b/src/test/ui/structs/struct-record-suggestion.fixed
index 48144cd1c..49e38b196 100644
--- a/src/test/ui/structs/struct-record-suggestion.fixed
+++ b/src/test/ui/structs/struct-record-suggestion.fixed
@@ -6,11 +6,29 @@ struct A {
d: usize,
}
-fn main() {
- let q = A { c: 5, .. Default::default() };
+fn a() {
+ let q = A { c: 5,..Default::default() };
//~^ ERROR mismatched types
//~| ERROR missing fields
//~| HELP separate the last named field with a comma
- let r = A { c: 5, .. Default::default() };
+ let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
}
+
+#[derive(Debug, Default, Eq, PartialEq)]
+struct B {
+ b: u32,
+}
+
+fn b() {
+ let q = B { b: 1,..Default::default() };
+ //~^ ERROR mismatched types
+ //~| HELP separate the last named field with a comma
+ let r = B { b: 1 };
+ assert_eq!(q, r);
+}
+
+fn main() {
+ a();
+ b();
+}
diff --git a/src/test/ui/structs/struct-record-suggestion.rs b/src/test/ui/structs/struct-record-suggestion.rs
index 6d169d5c6..901f310c8 100644
--- a/src/test/ui/structs/struct-record-suggestion.rs
+++ b/src/test/ui/structs/struct-record-suggestion.rs
@@ -6,11 +6,29 @@ struct A {
d: usize,
}
-fn main() {
- let q = A { c: 5 .. Default::default() };
+fn a() {
+ let q = A { c: 5..Default::default() };
//~^ ERROR mismatched types
//~| ERROR missing fields
//~| HELP separate the last named field with a comma
- let r = A { c: 5, .. Default::default() };
+ let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
}
+
+#[derive(Debug, Default, Eq, PartialEq)]
+struct B {
+ b: u32,
+}
+
+fn b() {
+ let q = B { b: 1..Default::default() };
+ //~^ ERROR mismatched types
+ //~| HELP separate the last named field with a comma
+ let r = B { b: 1 };
+ assert_eq!(q, r);
+}
+
+fn main() {
+ a();
+ b();
+}
diff --git a/src/test/ui/structs/struct-record-suggestion.stderr b/src/test/ui/structs/struct-record-suggestion.stderr
index e5bd03117..66e9f021e 100644
--- a/src/test/ui/structs/struct-record-suggestion.stderr
+++ b/src/test/ui/structs/struct-record-suggestion.stderr
@@ -1,8 +1,8 @@
error[E0308]: mismatched types
--> $DIR/struct-record-suggestion.rs:10:20
|
-LL | let q = A { c: 5 .. Default::default() };
- | ^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::ops::Range`
+LL | let q = A { c: 5..Default::default() };
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::ops::Range`
|
= note: expected type `u64`
found struct `std::ops::Range<{integer}>`
@@ -10,15 +10,28 @@ LL | let q = A { c: 5 .. Default::default() };
error[E0063]: missing fields `b` and `d` in initializer of `A`
--> $DIR/struct-record-suggestion.rs:10:13
|
-LL | let q = A { c: 5 .. Default::default() };
+LL | let q = A { c: 5..Default::default() };
| ^ missing `b` and `d`
|
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
-LL | let q = A { c: 5, .. Default::default() };
+LL | let q = A { c: 5,..Default::default() };
| +
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+ --> $DIR/struct-record-suggestion.rs:24:20
+ |
+LL | let q = B { b: 1..Default::default() };
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found struct `std::ops::Range`
+ |
+ = note: expected type `u32`
+ found struct `std::ops::Range<{integer}>`
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+ |
+LL | let q = B { b: 1,..Default::default() };
+ | +
+
+error: aborting due to 3 previous errors
Some errors have detailed explanations: E0063, E0308.
For more information about an error, try `rustc --explain E0063`.
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
index 805c75f46..0a91c442d 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -2,10 +2,13 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple-errors.rs:6:34
|
LL | let _: Option<(i32, bool)> = Some(1, 2);
- | ^^^^ - - argument of type `{integer}` unexpected
- | |
- | expected tuple, found integer
+ | ^^^^ - argument of type `{integer}` unexpected
|
+note: expected tuple, found integer
+ --> $DIR/args-instead-of-tuple-errors.rs:6:39
+ |
+LL | let _: Option<(i32, bool)> = Some(1, 2);
+ | ^
= note: expected tuple `(i32, bool)`
found type `{integer}`
note: tuple variant defined here
@@ -16,16 +19,19 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
help: remove the extra argument
|
LL | let _: Option<(i32, bool)> = Some(/* (i32, bool) */);
- | ~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple-errors.rs:8:5
|
LL | int_bool(1, 2);
- | ^^^^^^^^ - - argument of type `{integer}` unexpected
- | |
- | expected tuple, found integer
+ | ^^^^^^^^ - argument of type `{integer}` unexpected
|
+note: expected tuple, found integer
+ --> $DIR/args-instead-of-tuple-errors.rs:8:14
+ |
+LL | int_bool(1, 2);
+ | ^
= note: expected tuple `(i32, bool)`
found type `{integer}`
note: function defined here
@@ -36,7 +42,7 @@ LL | fn int_bool(_: (i32, bool)) {
help: remove the extra argument
|
LL | int_bool(/* (i32, bool) */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~
error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
--> $DIR/args-instead-of-tuple-errors.rs:11:28
@@ -52,7 +58,7 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
help: provide the argument
|
LL | let _: Option<(i8,)> = Some(/* (i8,) */);
- | ~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/args-instead-of-tuple-errors.rs:14:34
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.stderr b/src/test/ui/suggestions/args-instead-of-tuple.stderr
index 2448a5149..20f9e5259 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple.stderr
@@ -44,7 +44,7 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
help: provide the argument
|
LL | let _: Option<()> = Some(());
- | ~~~~~~~~
+ | ~~~~
error[E0308]: mismatched types
--> $DIR/args-instead-of-tuple.rs:14:34
diff --git a/src/test/ui/suggestions/as-ref-2.fixed b/src/test/ui/suggestions/as-ref-2.fixed
deleted file mode 100644
index 13bbb233f..000000000
--- a/src/test/ui/suggestions/as-ref-2.fixed
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-rustfix
-
-struct Struct;
-
-fn bar(_: &Struct) -> Struct {
- Struct
-}
-
-fn main() {
- let foo = Some(Struct);
- let _x: Option<Struct> = foo.as_ref().map(|s| bar(&s));
- let _y = foo; //~ERROR use of moved value: `foo`
-}
diff --git a/src/test/ui/suggestions/as-ref-2.rs b/src/test/ui/suggestions/as-ref-2.rs
index 74d61cdd9..b22f409b4 100644
--- a/src/test/ui/suggestions/as-ref-2.rs
+++ b/src/test/ui/suggestions/as-ref-2.rs
@@ -1,5 +1,3 @@
-// run-rustfix
-
struct Struct;
fn bar(_: &Struct) -> Struct {
diff --git a/src/test/ui/suggestions/as-ref-2.stderr b/src/test/ui/suggestions/as-ref-2.stderr
index 3c9d0f72a..e15e45d86 100644
--- a/src/test/ui/suggestions/as-ref-2.stderr
+++ b/src/test/ui/suggestions/as-ref-2.stderr
@@ -1,10 +1,12 @@
error[E0382]: use of moved value: `foo`
- --> $DIR/as-ref-2.rs:12:14
+ --> $DIR/as-ref-2.rs:10:14
|
LL | let foo = Some(Struct);
| --- move occurs because `foo` has type `Option<Struct>`, which does not implement the `Copy` trait
LL | let _x: Option<Struct> = foo.map(|s| bar(&s));
- | ---------------- `foo` moved due to this method call
+ | --- ---------------- `foo` moved due to this method call
+ | |
+ | help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
LL | let _y = foo;
| ^^^ value used here after move
|
@@ -13,10 +15,6 @@ note: this function takes ownership of the receiver `self`, which moves `foo`
|
LL | pub const fn map<U, F>(self, f: F) -> Option<U>
| ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
- |
-LL | let _x: Option<Struct> = foo.as_ref().map(|s| bar(&s));
- | +++++++++
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/as-ref.rs b/src/test/ui/suggestions/as-ref.rs
index 46d946153..a05353441 100644
--- a/src/test/ui/suggestions/as-ref.rs
+++ b/src/test/ui/suggestions/as-ref.rs
@@ -17,4 +17,11 @@ fn main() {
// note: do not suggest because of `E: usize`
let x: &Result<usize, usize> = &Ok(3);
let y: Result<&usize, usize> = x; //~ ERROR mismatched types [E0308]
+
+ let multiple_ref_opt = &&Some(Foo);
+ multiple_ref_opt.map(|arg| takes_ref(arg)); //~ ERROR mismatched types [E0308]
+ multiple_ref_opt.and_then(|arg| Some(takes_ref(arg))); //~ ERROR mismatched types [E0308]
+ let multiple_ref_result = &&Ok(Foo);
+ multiple_ref_result.map(|arg| takes_ref(arg)); //~ ERROR mismatched types [E0308]
+ multiple_ref_result.and_then(|arg| Ok(takes_ref(arg))); //~ ERROR mismatched types [E0308]
}
diff --git a/src/test/ui/suggestions/as-ref.stderr b/src/test/ui/suggestions/as-ref.stderr
index 1efd1b317..deafa9f48 100644
--- a/src/test/ui/suggestions/as-ref.stderr
+++ b/src/test/ui/suggestions/as-ref.stderr
@@ -97,6 +97,66 @@ LL | let y: Result<&usize, usize> = x;
= note: expected enum `Result<&usize, usize>`
found reference `&Result<usize, usize>`
-error: aborting due to 7 previous errors
+error[E0308]: mismatched types
+ --> $DIR/as-ref.rs:22:42
+ |
+LL | multiple_ref_opt.map(|arg| takes_ref(arg));
+ | --- --------- ^^^ expected `&Foo`, found struct `Foo`
+ | | |
+ | | arguments to this function are incorrect
+ | help: consider using `as_ref` instead: `as_ref().map`
+ |
+note: function defined here
+ --> $DIR/as-ref.rs:3:4
+ |
+LL | fn takes_ref(_: &Foo) {}
+ | ^^^^^^^^^ -------
+
+error[E0308]: mismatched types
+ --> $DIR/as-ref.rs:23:52
+ |
+LL | multiple_ref_opt.and_then(|arg| Some(takes_ref(arg)));
+ | -------- --------- ^^^ expected `&Foo`, found struct `Foo`
+ | | |
+ | | arguments to this function are incorrect
+ | help: consider using `as_ref` instead: `as_ref().and_then`
+ |
+note: function defined here
+ --> $DIR/as-ref.rs:3:4
+ |
+LL | fn takes_ref(_: &Foo) {}
+ | ^^^^^^^^^ -------
+
+error[E0308]: mismatched types
+ --> $DIR/as-ref.rs:25:45
+ |
+LL | multiple_ref_result.map(|arg| takes_ref(arg));
+ | --- --------- ^^^ expected `&Foo`, found struct `Foo`
+ | | |
+ | | arguments to this function are incorrect
+ | help: consider using `as_ref` instead: `as_ref().map`
+ |
+note: function defined here
+ --> $DIR/as-ref.rs:3:4
+ |
+LL | fn takes_ref(_: &Foo) {}
+ | ^^^^^^^^^ -------
+
+error[E0308]: mismatched types
+ --> $DIR/as-ref.rs:26:53
+ |
+LL | multiple_ref_result.and_then(|arg| Ok(takes_ref(arg)));
+ | -------- --------- ^^^ expected `&Foo`, found struct `Foo`
+ | | |
+ | | arguments to this function are incorrect
+ | help: consider using `as_ref` instead: `as_ref().and_then`
+ |
+note: function defined here
+ --> $DIR/as-ref.rs:3:4
+ |
+LL | fn takes_ref(_: &Foo) {}
+ | ^^^^^^^^^ -------
+
+error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/assoc-const-as-field.stderr b/src/test/ui/suggestions/assoc-const-as-field.stderr
index 5e746ecb2..78e5634b2 100644
--- a/src/test/ui/suggestions/assoc-const-as-field.stderr
+++ b/src/test/ui/suggestions/assoc-const-as-field.stderr
@@ -2,9 +2,7 @@ error[E0423]: expected value, found struct `Mod::Foo`
--> $DIR/assoc-const-as-field.rs:11:9
|
LL | foo(Mod::Foo.Bar);
- | ^^^^^^^^----
- | |
- | help: use the path separator to refer to an item: `Mod::Foo::Bar`
+ | ^^^^^^^^- help: use the path separator to refer to an item: `::`
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index c7d420e0a..bfd506c9f 100644
--- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -9,7 +9,7 @@ LL | bar(foo);
| |
| required by a bound introduced by this call
|
- = help: the trait `Future` is not implemented for `fn() -> impl Future<Output = ()> {foo}`
+ = help: the trait `Future` is not implemented for fn item `fn() -> impl Future<Output = ()> {foo}`
= note: fn() -> impl Future<Output = ()> {foo} must be a future or must implement `IntoFuture` to be awaited
note: required by a bound in `bar`
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16
@@ -31,7 +31,7 @@ LL | bar(async_closure);
| |
| required by a bound introduced by this call
|
- = help: the trait `Future` is not implemented for `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]`
+ = help: the trait `Future` is not implemented for closure `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]`
= note: [closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33] must be a future or must implement `IntoFuture` to be awaited
note: required by a bound in `bar`
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16
diff --git a/src/test/ui/suggestions/bool_typo_err_suggest.rs b/src/test/ui/suggestions/bool_typo_err_suggest.rs
new file mode 100644
index 000000000..deab0fb05
--- /dev/null
+++ b/src/test/ui/suggestions/bool_typo_err_suggest.rs
@@ -0,0 +1,12 @@
+// Suggest the boolean value instead of emit a generic error that the value
+// True is not in the scope.
+
+fn main() {
+ let x = True;
+ //~^ ERROR cannot find value `True` in this scope
+ //~| HELP you may want to use a bool value instead
+
+ let y = False;
+ //~^ ERROR cannot find value `False` in this scope
+ //~| HELP you may want to use a bool value instead
+}
diff --git a/src/test/ui/suggestions/bool_typo_err_suggest.stderr b/src/test/ui/suggestions/bool_typo_err_suggest.stderr
new file mode 100644
index 000000000..52bde07ca
--- /dev/null
+++ b/src/test/ui/suggestions/bool_typo_err_suggest.stderr
@@ -0,0 +1,25 @@
+error[E0425]: cannot find value `True` in this scope
+ --> $DIR/bool_typo_err_suggest.rs:5:13
+ |
+LL | let x = True;
+ | ^^^^ not found in this scope
+ |
+help: you may want to use a bool value instead
+ |
+LL | let x = true;
+ | ~~~~
+
+error[E0425]: cannot find value `False` in this scope
+ --> $DIR/bool_typo_err_suggest.rs:9:13
+ |
+LL | let y = False;
+ | ^^^^^ not found in this scope
+ |
+help: you may want to use a bool value instead
+ |
+LL | let y = false;
+ | ~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/suggestions/call-boxed.rs b/src/test/ui/suggestions/call-boxed.rs
new file mode 100644
index 000000000..d19e4596a
--- /dev/null
+++ b/src/test/ui/suggestions/call-boxed.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let mut x = 1i32;
+ let y = Box::new(|| 1);
+ x = y;
+ //~^ ERROR mismatched types
+ //~| HELP use parentheses to call this closure
+}
diff --git a/src/test/ui/suggestions/call-boxed.stderr b/src/test/ui/suggestions/call-boxed.stderr
new file mode 100644
index 000000000..9b619ac9a
--- /dev/null
+++ b/src/test/ui/suggestions/call-boxed.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/call-boxed.rs:4:9
+ |
+LL | let mut x = 1i32;
+ | ---- expected due to this value
+LL | let y = Box::new(|| 1);
+ | -- the found closure
+LL | x = y;
+ | ^ expected `i32`, found struct `Box`
+ |
+ = note: expected type `i32`
+ found struct `Box<[closure@$DIR/call-boxed.rs:3:22: 3:24]>`
+help: use parentheses to call this closure
+ |
+LL | x = y();
+ | ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/call-on-missing.rs b/src/test/ui/suggestions/call-on-missing.rs
new file mode 100644
index 000000000..25ced84dd
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-missing.rs
@@ -0,0 +1,39 @@
+struct Foo { i: i32 }
+
+impl Foo {
+ fn bar(&self) {}
+}
+
+fn foo() -> Foo {
+ Foo { i: 1 }
+}
+
+fn main() {
+ foo.bar();
+ //~^ ERROR no method named `bar`
+ //~| HELP use parentheses to call this function
+
+ foo.i;
+ //~^ ERROR no field `i`
+ //~| HELP use parentheses to call this function
+
+ let callable = Box::new(|| Foo { i: 1 }) as Box<dyn Fn() -> Foo>;
+
+ callable.bar();
+ //~^ ERROR no method named `bar`
+ //~| HELP use parentheses to call this trait object
+
+ callable.i;
+ //~^ ERROR no field `i`
+ //~| HELP use parentheses to call this trait object
+}
+
+fn type_param<T: Fn() -> Foo>(t: T) {
+ t.bar();
+ //~^ ERROR no method named `bar`
+ //~| HELP use parentheses to call this type parameter
+
+ t.i;
+ //~^ ERROR no field `i`
+ //~| HELP use parentheses to call this type parameter
+}
diff --git a/src/test/ui/suggestions/call-on-missing.stderr b/src/test/ui/suggestions/call-on-missing.stderr
new file mode 100644
index 000000000..ca9abc7e9
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-missing.stderr
@@ -0,0 +1,75 @@
+error[E0599]: no method named `bar` found for fn item `fn() -> Foo {foo}` in the current scope
+ --> $DIR/call-on-missing.rs:12:9
+ |
+LL | foo.bar();
+ | ^^^ method not found in `fn() -> Foo {foo}`
+ |
+help: use parentheses to call this function
+ |
+LL | foo().bar();
+ | ++
+
+error[E0609]: no field `i` on type `fn() -> Foo {foo}`
+ --> $DIR/call-on-missing.rs:16:9
+ |
+LL | foo.i;
+ | ^
+ |
+help: use parentheses to call this function
+ |
+LL | foo().i;
+ | ++
+
+error[E0599]: no method named `bar` found for struct `Box<dyn Fn() -> Foo>` in the current scope
+ --> $DIR/call-on-missing.rs:22:14
+ |
+LL | callable.bar();
+ | ^^^ method not found in `Box<dyn Fn() -> Foo>`
+ |
+help: use parentheses to call this trait object
+ |
+LL | callable().bar();
+ | ++
+
+error[E0609]: no field `i` on type `Box<dyn Fn() -> Foo>`
+ --> $DIR/call-on-missing.rs:26:14
+ |
+LL | callable.i;
+ | ^ unknown field
+ |
+help: use parentheses to call this trait object
+ |
+LL | callable().i;
+ | ++
+
+error[E0599]: no method named `bar` found for type parameter `T` in the current scope
+ --> $DIR/call-on-missing.rs:32:7
+ |
+LL | fn type_param<T: Fn() -> Foo>(t: T) {
+ | - method `bar` not found for this type parameter
+LL | t.bar();
+ | ^^^ method not found in `T`
+ |
+help: use parentheses to call this type parameter
+ |
+LL | t().bar();
+ | ++
+
+error[E0609]: no field `i` on type `T`
+ --> $DIR/call-on-missing.rs:36:7
+ |
+LL | fn type_param<T: Fn() -> Foo>(t: T) {
+ | - type parameter 'T' declared here
+...
+LL | t.i;
+ | ^
+ |
+help: use parentheses to call this type parameter
+ |
+LL | t().i;
+ | ++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0599, E0609.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/const-no-type.rs b/src/test/ui/suggestions/const-no-type.rs
index 6f46cfdf0..c6fdcdadb 100644
--- a/src/test/ui/suggestions/const-no-type.rs
+++ b/src/test/ui/suggestions/const-no-type.rs
@@ -14,38 +14,38 @@ fn main() {}
const C2 = 42;
//~^ ERROR missing type for `const` item
//~| HELP provide a type for the item
-//~| SUGGESTION C2: <type>
+//~| SUGGESTION : <type>
#[cfg(FALSE)]
static S2 = "abc";
//~^ ERROR missing type for `static` item
//~| HELP provide a type for the item
-//~| SUGGESTION S2: <type>
+//~| SUGGESTION : <type>
#[cfg(FALSE)]
static mut SM2 = "abc";
//~^ ERROR missing type for `static mut` item
//~| HELP provide a type for the item
-//~| SUGGESTION SM2: <type>
+//~| SUGGESTION : <type>
// These will, so the diagnostics should be stolen by typeck:
const C = 42;
//~^ ERROR missing type for `const` item
//~| HELP provide a type for the constant
-//~| SUGGESTION C: i32
+//~| SUGGESTION : i32
const D = &&42;
//~^ ERROR missing type for `const` item
//~| HELP provide a type for the constant
-//~| SUGGESTION D: &&i32
+//~| SUGGESTION : &&i32
static S = Vec::<String>::new();
//~^ ERROR missing type for `static` item
//~| HELP provide a type for the static variable
-//~| SUGGESTION S: Vec<String>
+//~| SUGGESTION : Vec<String>
static mut SM = "abc";
//~^ ERROR missing type for `static mut` item
//~| HELP provide a type for the static variable
-//~| SUGGESTION &str
+//~| SUGGESTION : &str
diff --git a/src/test/ui/suggestions/const-no-type.stderr b/src/test/ui/suggestions/const-no-type.stderr
index 3b0fd6337..bd703992f 100644
--- a/src/test/ui/suggestions/const-no-type.stderr
+++ b/src/test/ui/suggestions/const-no-type.stderr
@@ -1,44 +1,44 @@
error: missing type for `const` item
- --> $DIR/const-no-type.rs:33:7
+ --> $DIR/const-no-type.rs:33:8
|
LL | const C = 42;
- | ^ help: provide a type for the constant: `C: i32`
+ | ^ help: provide a type for the constant: `: i32`
error: missing type for `const` item
- --> $DIR/const-no-type.rs:38:7
+ --> $DIR/const-no-type.rs:38:8
|
LL | const D = &&42;
- | ^ help: provide a type for the constant: `D: &&i32`
+ | ^ help: provide a type for the constant: `: &&i32`
error: missing type for `static` item
- --> $DIR/const-no-type.rs:43:8
+ --> $DIR/const-no-type.rs:43:9
|
LL | static S = Vec::<String>::new();
- | ^ help: provide a type for the static variable: `S: Vec<String>`
+ | ^ help: provide a type for the static variable: `: Vec<String>`
error: missing type for `static mut` item
- --> $DIR/const-no-type.rs:48:12
+ --> $DIR/const-no-type.rs:48:14
|
LL | static mut SM = "abc";
- | ^^ help: provide a type for the static variable: `SM: &str`
+ | ^ help: provide a type for the static variable: `: &str`
error: missing type for `const` item
- --> $DIR/const-no-type.rs:14:7
+ --> $DIR/const-no-type.rs:14:9
|
LL | const C2 = 42;
- | ^^ help: provide a type for the item: `C2: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: missing type for `static` item
- --> $DIR/const-no-type.rs:20:8
+ --> $DIR/const-no-type.rs:20:10
|
LL | static S2 = "abc";
- | ^^ help: provide a type for the item: `S2: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: missing type for `static mut` item
- --> $DIR/const-no-type.rs:26:12
+ --> $DIR/const-no-type.rs:26:15
|
LL | static mut SM2 = "abc";
- | ^^^ help: provide a type for the item: `SM2: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to 7 previous errors
diff --git a/src/test/ui/suggestions/copied-and-cloned.fixed b/src/test/ui/suggestions/copied-and-cloned.fixed
new file mode 100644
index 000000000..f801403fe
--- /dev/null
+++ b/src/test/ui/suggestions/copied-and-cloned.fixed
@@ -0,0 +1,23 @@
+// run-rustfix
+
+fn expect<T>(_: T) {}
+
+fn main() {
+ let x = Some(&());
+ expect::<Option<()>>(x.copied());
+ //~^ ERROR mismatched types
+ //~| HELP use `Option::copied` to copy the value inside the `Option`
+ let x = Ok(&());
+ expect::<Result<(), ()>>(x.copied());
+ //~^ ERROR mismatched types
+ //~| HELP use `Result::copied` to copy the value inside the `Result`
+ let s = String::new();
+ let x = Some(&s);
+ expect::<Option<String>>(x.cloned());
+ //~^ ERROR mismatched types
+ //~| HELP use `Option::cloned` to clone the value inside the `Option`
+ let x = Ok(&s);
+ expect::<Result<String, ()>>(x.cloned());
+ //~^ ERROR mismatched types
+ //~| HELP use `Result::cloned` to clone the value inside the `Result`
+}
diff --git a/src/test/ui/suggestions/copied-and-cloned.rs b/src/test/ui/suggestions/copied-and-cloned.rs
new file mode 100644
index 000000000..640450b76
--- /dev/null
+++ b/src/test/ui/suggestions/copied-and-cloned.rs
@@ -0,0 +1,23 @@
+// run-rustfix
+
+fn expect<T>(_: T) {}
+
+fn main() {
+ let x = Some(&());
+ expect::<Option<()>>(x);
+ //~^ ERROR mismatched types
+ //~| HELP use `Option::copied` to copy the value inside the `Option`
+ let x = Ok(&());
+ expect::<Result<(), ()>>(x);
+ //~^ ERROR mismatched types
+ //~| HELP use `Result::copied` to copy the value inside the `Result`
+ let s = String::new();
+ let x = Some(&s);
+ expect::<Option<String>>(x);
+ //~^ ERROR mismatched types
+ //~| HELP use `Option::cloned` to clone the value inside the `Option`
+ let x = Ok(&s);
+ expect::<Result<String, ()>>(x);
+ //~^ ERROR mismatched types
+ //~| HELP use `Result::cloned` to clone the value inside the `Result`
+}
diff --git a/src/test/ui/suggestions/copied-and-cloned.stderr b/src/test/ui/suggestions/copied-and-cloned.stderr
new file mode 100644
index 000000000..a6336281b
--- /dev/null
+++ b/src/test/ui/suggestions/copied-and-cloned.stderr
@@ -0,0 +1,83 @@
+error[E0308]: mismatched types
+ --> $DIR/copied-and-cloned.rs:7:26
+ |
+LL | expect::<Option<()>>(x);
+ | -------------------- ^ expected `()`, found `&()`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `Option<()>`
+ found enum `Option<&()>`
+note: function defined here
+ --> $DIR/copied-and-cloned.rs:3:4
+ |
+LL | fn expect<T>(_: T) {}
+ | ^^^^^^ ----
+help: use `Option::copied` to copy the value inside the `Option`
+ |
+LL | expect::<Option<()>>(x.copied());
+ | +++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/copied-and-cloned.rs:11:30
+ |
+LL | expect::<Result<(), ()>>(x);
+ | ------------------------ ^ expected `()`, found `&()`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `Result<(), ()>`
+ found enum `Result<&(), _>`
+note: function defined here
+ --> $DIR/copied-and-cloned.rs:3:4
+ |
+LL | fn expect<T>(_: T) {}
+ | ^^^^^^ ----
+help: use `Result::copied` to copy the value inside the `Result`
+ |
+LL | expect::<Result<(), ()>>(x.copied());
+ | +++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/copied-and-cloned.rs:16:30
+ |
+LL | expect::<Option<String>>(x);
+ | ------------------------ ^ expected struct `String`, found `&String`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `Option<String>`
+ found enum `Option<&String>`
+note: function defined here
+ --> $DIR/copied-and-cloned.rs:3:4
+ |
+LL | fn expect<T>(_: T) {}
+ | ^^^^^^ ----
+help: use `Option::cloned` to clone the value inside the `Option`
+ |
+LL | expect::<Option<String>>(x.cloned());
+ | +++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/copied-and-cloned.rs:20:34
+ |
+LL | expect::<Result<String, ()>>(x);
+ | ---------------------------- ^ expected struct `String`, found `&String`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `Result<String, ()>`
+ found enum `Result<&String, _>`
+note: function defined here
+ --> $DIR/copied-and-cloned.rs:3:4
+ |
+LL | fn expect<T>(_: T) {}
+ | ^^^^^^ ----
+help: use `Result::cloned` to clone the value inside the `Result`
+ |
+LL | expect::<Result<String, ()>>(x.cloned());
+ | +++++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/deref-path-method.rs b/src/test/ui/suggestions/deref-path-method.rs
new file mode 100644
index 000000000..0281cdb6b
--- /dev/null
+++ b/src/test/ui/suggestions/deref-path-method.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let vec = Vec::new();
+ Vec::contains(&vec, &0);
+ //~^ ERROR no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope
+ //~| HELP the function `contains` is implemented on `[_]`
+}
diff --git a/src/test/ui/suggestions/deref-path-method.stderr b/src/test/ui/suggestions/deref-path-method.stderr
new file mode 100644
index 000000000..1cc37d611
--- /dev/null
+++ b/src/test/ui/suggestions/deref-path-method.stderr
@@ -0,0 +1,14 @@
+error[E0599]: no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope
+ --> $DIR/deref-path-method.rs:3:10
+ |
+LL | Vec::contains(&vec, &0);
+ | ^^^^^^^^ function or associated item not found in `Vec<_, _>`
+ |
+help: the function `contains` is implemented on `[_]`
+ |
+LL | <[_]>::contains(&vec, &0);
+ | ~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/derive-clone-for-eq.stderr b/src/test/ui/suggestions/derive-clone-for-eq.stderr
index 55a23c031..0645f0cdd 100644
--- a/src/test/ui/suggestions/derive-clone-for-eq.stderr
+++ b/src/test/ui/suggestions/derive-clone-for-eq.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
LL | #[derive(Clone, Eq)]
| ^^ the trait `Clone` is not implemented for `T`
|
-note: required because of the requirements on the impl of `PartialEq` for `Struct<T>`
+note: required for `Struct<T>` to implement `PartialEq`
--> $DIR/derive-clone-for-eq.rs:9:19
|
LL | impl<T: Clone, U> PartialEq<U> for Struct<T>
diff --git a/src/test/ui/suggestions/derive-macro-missing-bounds.stderr b/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
index 4186dc7cb..b9f773965 100644
--- a/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
+++ b/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
@@ -26,13 +26,13 @@ LL | #[derive(Debug)]
LL | struct Outer<T>(Inner<T>);
| ^^^^^^^^ the trait `c::Trait` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Debug` for `c::Inner<T>`
+note: required for `c::Inner<T>` to implement `Debug`
--> $DIR/derive-macro-missing-bounds.rs:34:28
|
LL | impl<T: Debug + Trait> Debug for Inner<T> {
| ^^^^^ ^^^^^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Debug` for `&c::Inner<T>`
+ = note: required for `&c::Inner<T>` to implement `Debug`
= note: required for the cast from `&c::Inner<T>` to the object type `dyn Debug`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
@@ -48,13 +48,13 @@ LL | #[derive(Debug)]
LL | struct Outer<T>(Inner<T>);
| ^^^^^^^^ the trait `d::Trait` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Debug` for `d::Inner<T>`
+note: required for `d::Inner<T>` to implement `Debug`
--> $DIR/derive-macro-missing-bounds.rs:49:13
|
LL | impl<T> Debug for Inner<T> where T: Debug, T: Trait {
| ^^^^^ ^^^^^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Debug` for `&d::Inner<T>`
+ = note: required for `&d::Inner<T>` to implement `Debug`
= note: required for the cast from `&d::Inner<T>` to the object type `dyn Debug`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
@@ -70,13 +70,13 @@ LL | #[derive(Debug)]
LL | struct Outer<T>(Inner<T>);
| ^^^^^^^^ the trait `e::Trait` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Debug` for `e::Inner<T>`
+note: required for `e::Inner<T>` to implement `Debug`
--> $DIR/derive-macro-missing-bounds.rs:64:13
|
LL | impl<T> Debug for Inner<T> where T: Debug + Trait {
| ^^^^^ ^^^^^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Debug` for `&e::Inner<T>`
+ = note: required for `&e::Inner<T>` to implement `Debug`
= note: required for the cast from `&e::Inner<T>` to the object type `dyn Debug`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
@@ -92,13 +92,13 @@ LL | #[derive(Debug)]
LL | struct Outer<T>(Inner<T>);
| ^^^^^^^^ the trait `f::Trait` is not implemented for `T`
|
-note: required because of the requirements on the impl of `Debug` for `f::Inner<T>`
+note: required for `f::Inner<T>` to implement `Debug`
--> $DIR/derive-macro-missing-bounds.rs:79:20
|
LL | impl<T: Debug> Debug for Inner<T> where T: Trait {
| ^^^^^ ^^^^^^^^
= note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Debug` for `&f::Inner<T>`
+ = note: required for `&f::Inner<T>` to implement `Debug`
= note: required for the cast from `&f::Inner<T>` to the object type `dyn Debug`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
diff --git a/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr b/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr
index 677aa031b..c66da3ea6 100644
--- a/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr
+++ b/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `set` found for array `[u8; 1]` in the current sco
--> $DIR/dont-suggest-pin-array-dot-set.rs:14:7
|
LL | a.set(0, 3);
- | ^^^ help: there is an associated function with a similar name: `get`
+ | ^^^ help: there is a method with a similar name: `get`
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.rs b/src/test/ui/suggestions/dont-try-removing-the-field.rs
new file mode 100644
index 000000000..948aa2b94
--- /dev/null
+++ b/src/test/ui/suggestions/dont-try-removing-the-field.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+ foo: i32,
+ bar: i32,
+ baz: (),
+}
+
+fn use_foo(x: Foo) -> (i32, i32) {
+ let Foo { foo, bar, baz } = x; //~ WARNING unused variable: `baz`
+ //~| help: try ignoring the field
+ return (foo, bar);
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.stderr b/src/test/ui/suggestions/dont-try-removing-the-field.stderr
new file mode 100644
index 000000000..263171a4a
--- /dev/null
+++ b/src/test/ui/suggestions/dont-try-removing-the-field.stderr
@@ -0,0 +1,10 @@
+warning: unused variable: `baz`
+ --> $DIR/dont-try-removing-the-field.rs:12:25
+ |
+LL | let Foo { foo, bar, baz } = x;
+ | ^^^ help: try ignoring the field: `baz: _`
+ |
+ = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 71facf57e..77cef485f 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -46,10 +46,12 @@ LL | pub const fn new(pointer: P) -> Pin<P> {
| ^^^
error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
- --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5
+ --> $DIR/expected-boxed-future-isnt-pinned.rs:19:14
|
LL | Pin::new(x)
- | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
+ | -------- ^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
+ | |
+ | required by a bound introduced by this call
|
= note: consider using `Box::pin`
note: required by a bound in `Pin::<P>::new`
@@ -59,10 +61,12 @@ LL | impl<P: Deref<Target: Unpin>> Pin<P> {
| ^^^^^ required by this bound in `Pin::<P>::new`
error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
- --> $DIR/expected-boxed-future-isnt-pinned.rs:24:5
+ --> $DIR/expected-boxed-future-isnt-pinned.rs:24:14
|
LL | Pin::new(Box::new(x))
- | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
+ | -------- ^^^^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
+ | |
+ | required by a bound introduced by this call
|
= note: consider using `Box::pin`
note: required by a bound in `Pin::<P>::new`
@@ -87,7 +91,7 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type
|
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
- found opaque type `impl Future`
+ found opaque type `impl Future<Output = {integer}>`
help: you need to pin and box this expression
|
LL ~ Box::pin(async {
diff --git a/src/test/ui/suggestions/field-access-considering-privacy.rs b/src/test/ui/suggestions/field-access-considering-privacy.rs
new file mode 100644
index 000000000..3de06b214
--- /dev/null
+++ b/src/test/ui/suggestions/field-access-considering-privacy.rs
@@ -0,0 +1,35 @@
+use a::TyCtxt;
+
+mod a {
+ use std::ops::Deref;
+ pub struct TyCtxt<'tcx> {
+ gcx: &'tcx GlobalCtxt<'tcx>,
+ }
+
+ impl<'tcx> Deref for TyCtxt<'tcx> {
+ type Target = &'tcx GlobalCtxt<'tcx>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.gcx
+ }
+ }
+
+ pub struct GlobalCtxt<'tcx> {
+ pub sess: &'tcx Session,
+ _t: &'tcx (),
+ }
+
+ pub struct Session {
+ pub opts: (),
+ }
+}
+
+mod b {
+ fn foo<'tcx>(tcx: crate::TyCtxt<'tcx>) {
+ tcx.opts;
+ //~^ ERROR no field `opts` on type `TyCtxt<'tcx>`
+ //~| HELP one of the expressions' fields has a field of the same name
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/field-access-considering-privacy.stderr b/src/test/ui/suggestions/field-access-considering-privacy.stderr
new file mode 100644
index 000000000..cbf6f3d10
--- /dev/null
+++ b/src/test/ui/suggestions/field-access-considering-privacy.stderr
@@ -0,0 +1,14 @@
+error[E0609]: no field `opts` on type `TyCtxt<'tcx>`
+ --> $DIR/field-access-considering-privacy.rs:29:13
+ |
+LL | tcx.opts;
+ | ^^^^ unknown field
+ |
+help: one of the expressions' fields has a field of the same name
+ |
+LL | tcx.sess.opts;
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index fb0a6f70b..fe603b675 100644
--- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -5,7 +5,7 @@ LL | fn foo() -> impl T<O=()> { S }
| --- consider calling this function
...
LL | bar(foo);
- | --- ^^^ the trait `T` is not implemented for `fn() -> impl T<O = ()> {foo}`
+ | --- ^^^ the trait `T` is not implemented for fn item `fn() -> impl T<O = ()> {foo}`
| |
| required by a bound introduced by this call
|
@@ -25,7 +25,7 @@ error[E0277]: the trait bound `[closure@$DIR/fn-ctor-passed-as-arg-where-it-shou
LL | let closure = || S;
| -- consider calling this closure
LL | bar(closure);
- | --- ^^^^^^^ the trait `T` is not implemented for `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]`
+ | --- ^^^^^^^ the trait `T` is not implemented for closure `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index e75ce0da8..3c7b895e3 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -33,8 +33,8 @@ LL | let _: usize = foo;
found fn item `fn(usize, usize) -> usize {foo}`
help: use parentheses to call this function
|
-LL | let _: usize = foo(_, _);
- | ++++++
+LL | let _: usize = foo(/* usize */, /* usize */);
+ | ++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:30:16
@@ -51,8 +51,8 @@ LL | let _: S = S;
found fn item `fn(usize, usize) -> S {S}`
help: use parentheses to instantiate this tuple struct
|
-LL | let _: S = S(_, _);
- | ++++++
+LL | let _: S = S(/* usize */, /* usize */);
+ | ++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:31:20
@@ -103,10 +103,10 @@ LL | let _: usize = T::baz;
|
= note: expected type `usize`
found fn item `fn(usize, usize) -> usize {<_ as T>::baz}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = T::baz(_, _);
- | ++++++
+LL | let _: usize = T::baz(/* usize */, /* usize */);
+ | ++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:34:20
@@ -121,10 +121,10 @@ LL | let _: usize = T::bat;
|
= note: expected type `usize`
found fn item `fn(usize) -> usize {<_ as T>::bat}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = T::bat(_);
- | +++
+LL | let _: usize = T::bat(/* usize */);
+ | +++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:35:16
@@ -141,8 +141,8 @@ LL | let _: E = E::A;
found fn item `fn(usize) -> E {E::A}`
help: use parentheses to instantiate this tuple variant
|
-LL | let _: E = E::A(_);
- | +++
+LL | let _: E = E::A(/* usize */);
+ | +++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:37:20
@@ -157,10 +157,10 @@ LL | let _: usize = X::baz;
|
= note: expected type `usize`
found fn item `fn(usize, usize) -> usize {<X as T>::baz}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = X::baz(_, _);
- | ++++++
+LL | let _: usize = X::baz(/* usize */, /* usize */);
+ | ++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:38:20
@@ -175,10 +175,10 @@ LL | let _: usize = X::bat;
|
= note: expected type `usize`
found fn item `fn(usize) -> usize {<X as T>::bat}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = X::bat(_);
- | +++
+LL | let _: usize = X::bat(/* usize */);
+ | +++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:39:20
@@ -193,10 +193,10 @@ LL | let _: usize = X::bax;
|
= note: expected type `usize`
found fn item `fn(usize) -> usize {<X as T>::bax}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = X::bax(_);
- | +++
+LL | let _: usize = X::bax(/* usize */);
+ | +++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:40:20
@@ -211,10 +211,10 @@ LL | let _: usize = X::bach;
|
= note: expected type `usize`
found fn item `fn(usize) -> usize {<X as T>::bach}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = X::bach(_);
- | +++
+LL | let _: usize = X::bach(/* usize */);
+ | +++++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:41:20
@@ -229,10 +229,10 @@ LL | let _: usize = X::ban;
|
= note: expected type `usize`
found fn item `for<'r> fn(&'r X) -> usize {<X as T>::ban}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = X::ban(_);
- | +++
+LL | let _: usize = X::ban(/* &X */);
+ | ++++++++++
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:42:20
@@ -247,10 +247,10 @@ LL | let _: usize = X::bal;
|
= note: expected type `usize`
found fn item `for<'r> fn(&'r X) -> usize {<X as T>::bal}`
-help: use parentheses to call this function
+help: use parentheses to call this associated function
|
-LL | let _: usize = X::bal(_);
- | +++
+LL | let _: usize = X::bal(/* &X */);
+ | ++++++++++
error[E0615]: attempted to take value of method `ban` on type `X`
--> $DIR/fn-or-tuple-struct-without-args.rs:43:22
diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr
index ba6af8f15..864ab0535 100644
--- a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr
+++ b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `for<'b> &'b S: Trait` is not satisfied
- --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:5
+ --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:14
|
LL | foo::<S>(s);
- | ^^^^^^^^ the trait `for<'b> Trait` is not implemented for `&'b S`
+ | -------- ^ the trait `for<'b> Trait` is not implemented for `&'b S`
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Trait` is implemented for `&'a mut S`
= note: `for<'b> Trait` is implemented for `&'b mut S`, but not for `&'b S`
diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr
index 5f3f62a7b..e01102e38 100644
--- a/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr
+++ b/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr
@@ -21,7 +21,7 @@ error[E0277]: the trait bound `S: Trait` is not satisfied
--> $DIR/imm-ref-trait-object-literal.rs:13:7
|
LL | foo(s);
- | --- ^ expected an implementor of trait `Trait`
+ | --- ^ the trait `Trait` is not implemented for `S`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr
index 8ae5c8479..a56a2a188 100644
--- a/src/test/ui/suggestions/into-str.stderr
+++ b/src/test/ui/suggestions/into-str.stderr
@@ -14,7 +14,7 @@ LL | foo(String::new());
<String as From<Box<str>>>
<String as From<Cow<'a, str>>>
<String as From<char>>
- = note: required because of the requirements on the impl of `Into<&str>` for `String`
+ = note: required for `String` to implement `Into<&str>`
note: required by a bound in `foo`
--> $DIR/into-str.rs:1:31
|
diff --git a/src/test/ui/suggestions/issue-101421.rs b/src/test/ui/suggestions/issue-101421.rs
new file mode 100644
index 000000000..b615997d1
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101421.rs
@@ -0,0 +1,12 @@
+pub trait Ice {
+ fn f(&self, _: ());
+}
+
+impl Ice for () {
+ fn f(&self, _: ()) {}
+}
+
+fn main() {
+ ().f::<()>(());
+ //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+}
diff --git a/src/test/ui/suggestions/issue-101421.stderr b/src/test/ui/suggestions/issue-101421.stderr
new file mode 100644
index 000000000..f8e1efb88
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101421.stderr
@@ -0,0 +1,17 @@
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-101421.rs:10:8
+ |
+LL | ().f::<()>(());
+ | ^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $DIR/issue-101421.rs:2:8
+ |
+LL | fn f(&self, _: ());
+ | ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/suggestions/issue-101465.rs b/src/test/ui/suggestions/issue-101465.rs
new file mode 100644
index 000000000..8e42e2c22
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101465.rs
@@ -0,0 +1,25 @@
+#![feature(trait_alias)]
+
+struct B;
+struct C;
+
+trait Tr {}
+
+impl Tr for B {}
+impl Tr for C {}
+
+trait Tr2<S> = Into<S>;
+
+fn foo2<T: Tr2<()>>() {}
+
+fn foo() -> impl Tr {
+ let x = foo2::<_>();
+
+ match true {
+ true => B,
+ false => C,
+ //~^ `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-101465.stderr b/src/test/ui/suggestions/issue-101465.stderr
new file mode 100644
index 000000000..e2ca77712
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101465.stderr
@@ -0,0 +1,25 @@
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/issue-101465.rs:20:18
+ |
+LL | / match true {
+LL | | true => B,
+ | | - this is found to be of type `B`
+LL | | false => C,
+ | | ^ expected struct `B`, found struct `C`
+LL | |
+LL | | }
+ | |_____- `match` arms have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn foo() -> Box<dyn Tr> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ true => Box::new(B),
+LL ~ false => Box::new(C),
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/issue-101984.rs b/src/test/ui/suggestions/issue-101984.rs
new file mode 100644
index 000000000..5f7ecb77e
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101984.rs
@@ -0,0 +1,27 @@
+use std::marker::PhantomData;
+
+type Component = fn(&());
+
+struct Wrapper {
+ router: Router<(Component, Box<Self>)>,
+}
+
+struct Match<C>(PhantomData<C>);
+
+struct Router<T>(PhantomData<T>);
+
+impl<T> Router<T> {
+ pub fn at(&self) -> Result<Match<&T>, ()> {
+ todo!()
+ }
+}
+
+impl Wrapper {
+ fn at(&self, path: &str) -> Result<(Component, Box<Self>), ()> {
+ let (cmp, router) = self.router.at()?;
+ //~^ ERROR mismatched types
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-101984.stderr b/src/test/ui/suggestions/issue-101984.stderr
new file mode 100644
index 000000000..c744c62d1
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101984.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-101984.rs:21:13
+ |
+LL | let (cmp, router) = self.router.at()?;
+ | ^^^^^^^^^^^^^ ----------------- this expression has type `Match<&(for<'r> fn(&'r ()), Box<Wrapper>)>`
+ | |
+ | expected struct `Match`, found tuple
+ |
+ = note: expected struct `Match<&(for<'r> fn(&'r ()), Box<Wrapper>)>`
+ found tuple `(_, _)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr
index c0d776e59..a788cab6e 100644
--- a/src/test/ui/suggestions/issue-61963.stderr
+++ b/src/test/ui/suggestions/issue-61963.stderr
@@ -13,9 +13,8 @@ LL | #![deny(bare_trait_objects)]
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - bar: Box<Bar>,
-LL + bar: Box<dyn Bar>,
- |
+LL | bar: Box<dyn Bar>,
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-61963.rs:18:1
@@ -27,9 +26,8 @@ LL | pub struct Foo {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub struct Foo {
-LL + dyn pub struct Foo {
- |
+LL | dyn pub struct Foo {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-61963.rs:28:14
@@ -41,9 +39,8 @@ LL | bar: Box<Bar>,
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - bar: Box<Bar>,
-LL + bar: Box<dyn Bar>,
- |
+LL | bar: Box<dyn Bar>,
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-61963.rs:28:14
@@ -55,9 +52,8 @@ LL | bar: Box<Bar>,
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - bar: Box<Bar>,
-LL + bar: Box<dyn Bar>,
- |
+LL | bar: Box<dyn Bar>,
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-61963.rs:18:1
@@ -69,9 +65,8 @@ LL | pub struct Foo {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub struct Foo {
-LL + dyn pub struct Foo {
- |
+LL | dyn pub struct Foo {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-61963.rs:18:1
@@ -83,9 +78,8 @@ LL | pub struct Foo {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub struct Foo {
-LL + dyn pub struct Foo {
- |
+LL | dyn pub struct Foo {
+ | +++
error: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-61963.rs:18:1
@@ -97,9 +91,8 @@ LL | pub struct Foo {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - pub struct Foo {
-LL + dyn pub struct Foo {
- |
+LL | dyn pub struct Foo {
+ | +++
error: aborting due to 7 previous errors
diff --git a/src/test/ui/suggestions/issue-62843.stderr b/src/test/ui/suggestions/issue-62843.stderr
index bc1c69406..62f0943d4 100644
--- a/src/test/ui/suggestions/issue-62843.stderr
+++ b/src/test/ui/suggestions/issue-62843.stderr
@@ -2,12 +2,12 @@ error[E0277]: expected a `FnMut<(char,)>` closure, found `String`
--> $DIR/issue-62843.rs:4:32
|
LL | println!("{:?}", line.find(pattern));
- | ---- ^^^^^^^ expected an implementor of trait `Pattern<'_>`
+ | ---- ^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
| |
| required by a bound introduced by this call
|
= note: the trait bound `String: Pattern<'_>` is not satisfied
- = note: required because of the requirements on the impl of `Pattern<'_>` for `String`
+ = note: required for `String` to implement `Pattern<'_>`
note: required by a bound in `core::str::<impl str>::find`
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
diff --git a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr
index 383f40d47..684db23e1 100644
--- a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr
+++ b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr
@@ -1,13 +1,15 @@
error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied
- --> $DIR/issue-71394-no-from-impl.rs:3:25
+ --> $DIR/issue-71394-no-from-impl.rs:3:20
|
LL | let _: &[i8] = data.into();
- | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`
+ | ^^^^ ---- required by a bound introduced by this call
+ | |
+ | the trait `From<&[u8]>` is not implemented for `&[i8]`
|
= help: the following other types implement trait `From<T>`:
<[T; LANES] as From<Simd<T, LANES>>>
<[bool; LANES] as From<Mask<T, LANES>>>
- = note: required because of the requirements on the impl of `Into<&[i8]>` for `&[u8]`
+ = note: required for `&[u8]` to implement `Into<&[i8]>`
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/issue-84973-2.stderr b/src/test/ui/suggestions/issue-84973-2.stderr
index 2c54ea672..513bf28fb 100644
--- a/src/test/ui/suggestions/issue-84973-2.stderr
+++ b/src/test/ui/suggestions/issue-84973-2.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied
--> $DIR/issue-84973-2.rs:11:9
|
LL | foo(a);
- | --- ^ expected an implementor of trait `Tr`
+ | --- ^ the trait `Tr` is not implemented for `i32`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/suggestions/issue-84973-blacklist.stderr b/src/test/ui/suggestions/issue-84973-blacklist.stderr
index ae0d3efca..c20cc8164 100644
--- a/src/test/ui/suggestions/issue-84973-blacklist.stderr
+++ b/src/test/ui/suggestions/issue-84973-blacklist.stderr
@@ -31,10 +31,12 @@ LL | #[derive(Clone)]
|
error[E0277]: `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` cannot be unpinned
- --> $DIR/issue-84973-blacklist.rs:17:5
+ --> $DIR/issue-84973-blacklist.rs:17:13
|
LL | f_unpin(static || { yield; });
- | ^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]`
+ | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]`
+ | |
+ | required by a bound introduced by this call
|
= note: consider using `Box::pin`
note: required by a bound in `f_unpin`
diff --git a/src/test/ui/suggestions/issue-84973-negative.stderr b/src/test/ui/suggestions/issue-84973-negative.stderr
index 15559d4ae..ce838bce0 100644
--- a/src/test/ui/suggestions/issue-84973-negative.stderr
+++ b/src/test/ui/suggestions/issue-84973-negative.stderr
@@ -17,7 +17,7 @@ error[E0277]: the trait bound `f32: Tr` is not satisfied
--> $DIR/issue-84973-negative.rs:11:9
|
LL | bar(b);
- | --- ^ expected an implementor of trait `Tr`
+ | --- ^ the trait `Tr` is not implemented for `f32`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/suggestions/issue-84973.stderr b/src/test/ui/suggestions/issue-84973.stderr
index 24c989ec3..ae2bf5aac 100644
--- a/src/test/ui/suggestions/issue-84973.stderr
+++ b/src/test/ui/suggestions/issue-84973.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied
--> $DIR/issue-84973.rs:6:24
|
LL | let o = Other::new(f);
- | ---------- ^ expected an implementor of trait `SomeTrait`
+ | ---------- ^ the trait `SomeTrait` is not implemented for `Fancy`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/suggestions/issue-85347.rs b/src/test/ui/suggestions/issue-85347.rs
index f08e38689..02b5fb618 100644
--- a/src/test/ui/suggestions/issue-85347.rs
+++ b/src/test/ui/suggestions/issue-85347.rs
@@ -1,9 +1,8 @@
-#![allow(incomplete_features)]
-#![feature(generic_associated_types)]
use std::ops::Deref;
trait Foo {
type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
//~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ //~| ERROR associated type bindings are not allowed here
//~| HELP add missing
}
diff --git a/src/test/ui/suggestions/issue-85347.stderr b/src/test/ui/suggestions/issue-85347.stderr
index fccd2ef8d..17c1b7dc4 100644
--- a/src/test/ui/suggestions/issue-85347.stderr
+++ b/src/test/ui/suggestions/issue-85347.stderr
@@ -1,11 +1,11 @@
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/issue-85347.rs:5:42
+ --> $DIR/issue-85347.rs:3:42
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
| ^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
- --> $DIR/issue-85347.rs:5:10
+ --> $DIR/issue-85347.rs:3:10
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
| ^^^ --
@@ -14,6 +14,13 @@ help: add missing lifetime argument
LL | type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
| +++
-error: aborting due to previous error
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-85347.rs:3:46
+ |
+LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
+ | ^^^^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0229.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/suggestions/issue-89064.rs b/src/test/ui/suggestions/issue-89064.rs
new file mode 100644
index 000000000..fa5fc899d
--- /dev/null
+++ b/src/test/ui/suggestions/issue-89064.rs
@@ -0,0 +1,35 @@
+use std::convert::TryInto;
+
+trait A<T> {
+ fn foo() {}
+}
+
+trait B<T, U> {
+ fn bar() {}
+}
+
+struct S;
+
+impl<T> A<T> for S {}
+impl<T, U> B<T, U> for S {}
+
+fn main() {
+ let _ = A::foo::<S>();
+ //~^ ERROR
+ //~| HELP remove these generics
+ //~| HELP consider moving this generic argument
+
+ let _ = B::bar::<S, S>();
+ //~^ ERROR
+ //~| HELP remove these generics
+ //~| HELP consider moving these generic arguments
+
+ let _ = A::<S>::foo::<S>();
+ //~^ ERROR
+ //~| HELP remove these generics
+
+ let _ = 42.into::<Option<_>>();
+ //~^ ERROR
+ //~| HELP remove these generics
+ //~| HELP consider moving this generic argument
+}
diff --git a/src/test/ui/suggestions/issue-89064.stderr b/src/test/ui/suggestions/issue-89064.stderr
new file mode 100644
index 000000000..8b2a38816
--- /dev/null
+++ b/src/test/ui/suggestions/issue-89064.stderr
@@ -0,0 +1,82 @@
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-89064.rs:17:16
+ |
+LL | let _ = A::foo::<S>();
+ | ^^^ expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $DIR/issue-89064.rs:4:8
+ |
+LL | fn foo() {}
+ | ^^^
+help: consider moving this generic argument to the `A` trait, which takes up to 1 argument
+ |
+LL - let _ = A::foo::<S>();
+LL + let _ = A::<S>::foo();
+ |
+help: remove these generics
+ |
+LL - let _ = A::foo::<S>();
+LL + let _ = A::foo();
+ |
+
+error[E0107]: this associated function takes 0 generic arguments but 2 generic arguments were supplied
+ --> $DIR/issue-89064.rs:22:16
+ |
+LL | let _ = B::bar::<S, S>();
+ | ^^^ expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $DIR/issue-89064.rs:8:8
+ |
+LL | fn bar() {}
+ | ^^^
+help: consider moving these generic arguments to the `B` trait, which takes up to 2 arguments
+ |
+LL - let _ = B::bar::<S, S>();
+LL + let _ = B::<S, S>::bar();
+ |
+help: remove these generics
+ |
+LL - let _ = B::bar::<S, S>();
+LL + let _ = B::bar();
+ |
+
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-89064.rs:27:21
+ |
+LL | let _ = A::<S>::foo::<S>();
+ | ^^^----- help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $DIR/issue-89064.rs:4:8
+ |
+LL | fn foo() {}
+ | ^^^
+
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-89064.rs:31:16
+ |
+LL | let _ = 42.into::<Option<_>>();
+ | ^^^^ expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn into(self) -> T;
+ | ^^^^
+help: consider moving this generic argument to the `Into` trait, which takes up to 1 argument
+ |
+LL | let _ = Into::<Option<_>>::into(42);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+help: remove these generics
+ |
+LL - let _ = 42.into::<Option<_>>();
+LL + let _ = 42.into();
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/suggestions/issue-96223.stderr b/src/test/ui/suggestions/issue-96223.stderr
index 513725d99..72a9a739a 100644
--- a/src/test/ui/suggestions/issue-96223.stderr
+++ b/src/test/ui/suggestions/issue-96223.stderr
@@ -7,12 +7,12 @@ LL | icey_bounds(&p);
| required by a bound introduced by this call
|
= help: the trait `Foo<'de>` is implemented for `Baz<T>`
-note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz<EmptyBis<'de>>`
+note: required for `Baz<EmptyBis<'de>>` to implement `for<'de> Foo<'de>`
--> $DIR/issue-96223.rs:16:14
|
LL | impl<'de, T> Foo<'de> for Baz<T> where T: Foo<'de> {}
| ^^^^^^^^ ^^^^^^
-note: required because of the requirements on the impl of `Dummy<EmptyMarker>` for `Empty`
+note: required for `Empty` to implement `Dummy<EmptyMarker>`
--> $DIR/issue-96223.rs:20:9
|
LL | impl<M> Dummy<M> for Empty
diff --git a/src/test/ui/suggestions/issue-96555.stderr b/src/test/ui/suggestions/issue-96555.stderr
index a1a603cf2..9a8a183dc 100644
--- a/src/test/ui/suggestions/issue-96555.stderr
+++ b/src/test/ui/suggestions/issue-96555.stderr
@@ -8,7 +8,7 @@ LL | m::f1().await;
|
= help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited
- = note: required because of the requirements on the impl of `IntoFuture` for `()`
+ = note: required for `()` to implement `IntoFuture`
help: remove the `.await`
|
LL - m::f1().await;
@@ -29,7 +29,7 @@ LL | m::f2().await;
|
= help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited
- = note: required because of the requirements on the impl of `IntoFuture` for `()`
+ = note: required for `()` to implement `IntoFuture`
help: remove the `.await`
|
LL - m::f2().await;
@@ -50,7 +50,7 @@ LL | m::f3().await;
|
= help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited
- = note: required because of the requirements on the impl of `IntoFuture` for `()`
+ = note: required for `()` to implement `IntoFuture`
help: remove the `.await`
|
LL - m::f3().await;
diff --git a/src/test/ui/suggestions/issue-97677.fixed b/src/test/ui/suggestions/issue-97677.fixed
index 73ca9f97b..1e7569fa4 100644
--- a/src/test/ui/suggestions/issue-97677.fixed
+++ b/src/test/ui/suggestions/issue-97677.fixed
@@ -1,6 +1,6 @@
// run-rustfix
-fn add_ten<N: std::ops::Add<i32, Output=N>>(n: N) -> N {
+fn add_ten<N: std::ops::Add<i32, Output = N>>(n: N) -> N {
n + 10
//~^ ERROR cannot add `{integer}` to `N`
}
diff --git a/src/test/ui/suggestions/issue-97677.stderr b/src/test/ui/suggestions/issue-97677.stderr
index 069b184ac..575d79267 100644
--- a/src/test/ui/suggestions/issue-97677.stderr
+++ b/src/test/ui/suggestions/issue-97677.stderr
@@ -8,8 +8,8 @@ LL | n + 10
|
help: consider restricting type parameter `N`
|
-LL | fn add_ten<N: std::ops::Add<i32, Output=N>>(n: N) -> N {
- | ++++++++++++++++++++++++++++++
+LL | fn add_ten<N: std::ops::Add<i32, Output = N>>(n: N) -> N {
+ | ++++++++++++++++++++++++++++++++
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
index 0212c2d71..e5d2ead6a 100644
--- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
@@ -22,8 +22,8 @@ LL | | });
| |______^
help: consider adding an explicit lifetime bound...
|
-LL | fn func<T: Test + 'a>(foo: &Foo, t: T) {
- | ++++
+LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) {
+ | +++ ++++
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index 0d749f04b..ed1b91676 100644
--- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -47,8 +47,10 @@ LL | | }
| |_____^
help: consider adding an explicit lifetime bound...
|
-LL | G: Get<T> + 'a,
- | ++++
+LL ~ fn bar<'a, G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL | where
+LL ~ G: Get<T> + 'a,
+ |
error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:52:5
@@ -74,8 +76,8 @@ LL | | }
| |_____^
help: consider adding an explicit lifetime bound...
|
-LL | fn qux<'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
- | ++++
+LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+ | +++ ++++
error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:61:9
@@ -101,8 +103,8 @@ LL | | }
| |_________^
help: consider adding an explicit lifetime bound...
|
-LL | fn qux<'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
- | ++++
+LL | fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+ | +++ ++++
error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:73:5
@@ -130,8 +132,8 @@ LL | | }
| |_____^
help: consider adding an explicit lifetime bound...
|
-LL | fn bat<'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
- | ++++
+LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+ | +++ ++++
error[E0621]: explicit lifetime required in the type of `dest`
--> $DIR/missing-lifetimes-in-signature.rs:73:5
diff --git a/src/test/ui/suggestions/many-type-ascription.rs b/src/test/ui/suggestions/many-type-ascription.rs
new file mode 100644
index 000000000..31ac556b9
--- /dev/null
+++ b/src/test/ui/suggestions/many-type-ascription.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let _ = 0: i32; //~ ERROR: type ascription is experimental
+ let _ = 0: i32; // (error only emitted once)
+}
diff --git a/src/test/ui/suggestions/many-type-ascription.stderr b/src/test/ui/suggestions/many-type-ascription.stderr
new file mode 100644
index 000000000..3706bbae9
--- /dev/null
+++ b/src/test/ui/suggestions/many-type-ascription.stderr
@@ -0,0 +1,12 @@
+error[E0658]: type ascription is experimental
+ --> $DIR/many-type-ascription.rs:2:13
+ |
+LL | let _ = 0: i32;
+ | ^^^^^^
+ |
+ = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+ = help: add `#![feature(type_ascription)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.rs b/src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
new file mode 100644
index 000000000..2f540060a
--- /dev/null
+++ b/src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
@@ -0,0 +1,18 @@
+// Generalizes the suggestion introduced in #100838
+
+trait Foo<T> {
+ fn bar(&self, _: T);
+}
+
+impl Foo<i32> for i32 {
+ fn bar(&self, x: i32) {
+ println!("{}", self + x);
+ }
+}
+
+fn main() {
+ 1.bar::<i32>(0);
+ //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+ //~| HELP consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
+ //~| HELP remove these generics
+}
diff --git a/src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr b/src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
new file mode 100644
index 000000000..9557220f6
--- /dev/null
+++ b/src/test/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
@@ -0,0 +1,24 @@
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/move-generic-to-trait-in-method-with-params.rs:14:7
+ |
+LL | 1.bar::<i32>(0);
+ | ^^^ expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $DIR/move-generic-to-trait-in-method-with-params.rs:4:8
+ |
+LL | fn bar(&self, _: T);
+ | ^^^
+help: consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
+ |
+LL | Foo::<i32>::bar(1, 0);
+ | ~~~~~~~~~~~~~~~~~~~~~
+help: remove these generics
+ |
+LL - 1.bar::<i32>(0);
+LL + 1.bar(0);
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/suggestions/option-content-move.fixed b/src/test/ui/suggestions/option-content-move.fixed
deleted file mode 100644
index ba16bcc8a..000000000
--- a/src/test/ui/suggestions/option-content-move.fixed
+++ /dev/null
@@ -1,39 +0,0 @@
-//run-rustfix
-
-pub struct LipogramCorpora {
- selections: Vec<(char, Option<String>)>,
-}
-
-impl LipogramCorpora {
- pub fn validate_all(&mut self) -> Result<(), char> {
- for selection in &self.selections {
- if selection.1.is_some() {
- if selection.1.as_ref().unwrap().contains(selection.0) {
- //~^ ERROR cannot move out of `selection.1`
- return Err(selection.0);
- }
- }
- }
- Ok(())
- }
-}
-
-pub struct LipogramCorpora2 {
- selections: Vec<(char, Result<String, String>)>,
-}
-
-impl LipogramCorpora2 {
- pub fn validate_all(&mut self) -> Result<(), char> {
- for selection in &self.selections {
- if selection.1.is_ok() {
- if selection.1.as_ref().unwrap().contains(selection.0) {
- //~^ ERROR cannot move out of `selection.1`
- return Err(selection.0);
- }
- }
- }
- Ok(())
- }
-}
-
-fn main() {}
diff --git a/src/test/ui/suggestions/option-content-move.rs b/src/test/ui/suggestions/option-content-move.rs
index ef38f114e..46c895b95 100644
--- a/src/test/ui/suggestions/option-content-move.rs
+++ b/src/test/ui/suggestions/option-content-move.rs
@@ -1,5 +1,3 @@
-//run-rustfix
-
pub struct LipogramCorpora {
selections: Vec<(char, Option<String>)>,
}
diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr
index fccfbe1d7..a6f1ebc97 100644
--- a/src/test/ui/suggestions/option-content-move.stderr
+++ b/src/test/ui/suggestions/option-content-move.stderr
@@ -1,9 +1,10 @@
error[E0507]: cannot move out of `selection.1` which is behind a shared reference
- --> $DIR/option-content-move.rs:11:20
+ --> $DIR/option-content-move.rs:9:20
|
LL | if selection.1.unwrap().contains(selection.0) {
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
| |
+ | help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
|
note: this function takes ownership of the receiver `self`, which moves `selection.1`
@@ -11,17 +12,14 @@ note: this function takes ownership of the receiver `self`, which moves `selecti
|
LL | pub const fn unwrap(self) -> T {
| ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
- |
-LL | if selection.1.as_ref().unwrap().contains(selection.0) {
- | +++++++++
error[E0507]: cannot move out of `selection.1` which is behind a shared reference
- --> $DIR/option-content-move.rs:29:20
+ --> $DIR/option-content-move.rs:27:20
|
LL | if selection.1.unwrap().contains(selection.0) {
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
| |
+ | help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
|
note: this function takes ownership of the receiver `self`, which moves `selection.1`
@@ -29,10 +27,6 @@ note: this function takes ownership of the receiver `self`, which moves `selecti
|
LL | pub fn unwrap(self) -> T
| ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
- |
-LL | if selection.1.as_ref().unwrap().contains(selection.0) {
- | +++++++++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/suggestions/restrict-type-not-param.rs b/src/test/ui/suggestions/restrict-type-not-param.rs
new file mode 100644
index 000000000..60f5ba45c
--- /dev/null
+++ b/src/test/ui/suggestions/restrict-type-not-param.rs
@@ -0,0 +1,12 @@
+use std::ops::Add;
+
+struct Wrapper<T>(T);
+
+trait Foo {}
+
+fn qux<T>(a: Wrapper<T>, b: T) -> T {
+ a + b
+ //~^ ERROR cannot add `T` to `Wrapper<T>`
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/restrict-type-not-param.stderr b/src/test/ui/suggestions/restrict-type-not-param.stderr
new file mode 100644
index 000000000..e7d9c5ecb
--- /dev/null
+++ b/src/test/ui/suggestions/restrict-type-not-param.stderr
@@ -0,0 +1,26 @@
+error[E0369]: cannot add `T` to `Wrapper<T>`
+ --> $DIR/restrict-type-not-param.rs:8:7
+ |
+LL | a + b
+ | - ^ - T
+ | |
+ | Wrapper<T>
+ |
+note: an implementation of `Add<_>` might be missing for `Wrapper<T>`
+ --> $DIR/restrict-type-not-param.rs:3:1
+ |
+LL | struct Wrapper<T>(T);
+ | ^^^^^^^^^^^^^^^^^ must implement `Add<_>`
+note: the following trait must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ |
+LL | pub trait Add<Rhs = Self> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+ |
+LL | fn qux<T>(a: Wrapper<T>, b: T) -> T where Wrapper<T>: Add<T, Output = T> {
+ | ++++++++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/suggestions/return-closures.rs b/src/test/ui/suggestions/return-closures.rs
new file mode 100644
index 000000000..86c7c1537
--- /dev/null
+++ b/src/test/ui/suggestions/return-closures.rs
@@ -0,0 +1,13 @@
+fn foo() {
+ //~^ HELP try adding a return type
+ |x: &i32| 1i32
+ //~^ ERROR mismatched types
+}
+
+fn bar(i: impl Sized) {
+ //~^ HELP a return type might be missing here
+ || i
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-closures.stderr b/src/test/ui/suggestions/return-closures.stderr
new file mode 100644
index 000000000..e273793ea
--- /dev/null
+++ b/src/test/ui/suggestions/return-closures.stderr
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+ --> $DIR/return-closures.rs:3:5
+ |
+LL | fn foo() {
+ | - help: try adding a return type: `-> impl for<'r> Fn(&'r i32) -> i32`
+LL |
+LL | |x: &i32| 1i32
+ | ^^^^^^^^^^^^^^ expected `()`, found closure
+ |
+ = note: expected unit type `()`
+ found closure `[closure@$DIR/return-closures.rs:3:5: 3:14]`
+
+error[E0308]: mismatched types
+ --> $DIR/return-closures.rs:9:5
+ |
+LL | fn bar(i: impl Sized) {
+ | - help: a return type might be missing here: `-> _`
+LL |
+LL | || i
+ | ^^^^ expected `()`, found closure
+ |
+ = note: expected unit type `()`
+ found closure `[closure@$DIR/return-closures.rs:9:5: 9:7]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/return-cycle-2.rs b/src/test/ui/suggestions/return-cycle-2.rs
new file mode 100644
index 000000000..d6d24be1b
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle-2.rs
@@ -0,0 +1,14 @@
+use std::marker::PhantomData;
+
+struct Token<T>(PhantomData<T>);
+
+impl<T> Token<T> {
+ fn as_ref(_: i32, _: i32) -> _ {
+ //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+ //~| NOTE not allowed in type signatures
+ //~| HELP replace with the correct return type
+ Token(PhantomData::<&T>)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-cycle-2.stderr b/src/test/ui/suggestions/return-cycle-2.stderr
new file mode 100644
index 000000000..3a1a0f7f4
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle-2.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+ --> $DIR/return-cycle-2.rs:6:34
+ |
+LL | fn as_ref(_: i32, _: i32) -> _ {
+ | ^
+ | |
+ | not allowed in type signatures
+ | help: replace with the correct return type: `Token<&'static T>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/suggestions/return-cycle.rs b/src/test/ui/suggestions/return-cycle.rs
new file mode 100644
index 000000000..60b80e35a
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle.rs
@@ -0,0 +1,14 @@
+use std::marker::PhantomData;
+
+struct Token<T>(PhantomData<T>);
+
+impl<T> Token<T> {
+ fn new() -> _ {
+ //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+ //~| NOTE not allowed in type signatures
+ //~| HELP replace with the correct return type
+ Token(PhantomData::<()>)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-cycle.stderr b/src/test/ui/suggestions/return-cycle.stderr
new file mode 100644
index 000000000..63fa9e040
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+ --> $DIR/return-cycle.rs:6:17
+ |
+LL | fn new() -> _ {
+ | ^
+ | |
+ | not allowed in type signatures
+ | help: replace with the correct return type: `Token<()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr
index fd2a44f9a..84ecd749b 100644
--- a/src/test/ui/suggestions/slice-issue-87994.stderr
+++ b/src/test/ui/suggestions/slice-issue-87994.stderr
@@ -2,10 +2,10 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation
--> $DIR/slice-issue-87994.rs:3:12
|
LL | for _ in v[1..] {
- | ^^^^^^ expected an implementor of trait `IntoIterator`
+ | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]`
|
= note: the trait bound `[i32]: IntoIterator` is not satisfied
- = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+ = note: required for `[i32]` to implement `IntoIterator`
help: consider borrowing here
|
LL | for _ in &v[1..] {
@@ -17,10 +17,10 @@ error[E0277]: `[i32]` is not an iterator
--> $DIR/slice-issue-87994.rs:3:12
|
LL | for _ in v[1..] {
- | ^^^^^^ expected an implementor of trait `IntoIterator`
+ | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]`
|
= note: the trait bound `[i32]: IntoIterator` is not satisfied
- = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+ = note: required for `[i32]` to implement `IntoIterator`
help: consider borrowing here
|
LL | for _ in &v[1..] {
@@ -32,10 +32,10 @@ error[E0277]: the size for values of type `[K]` cannot be known at compilation t
--> $DIR/slice-issue-87994.rs:11:13
|
LL | for i2 in v2[1..] {
- | ^^^^^^^ expected an implementor of trait `IntoIterator`
+ | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]`
|
= note: the trait bound `[K]: IntoIterator` is not satisfied
- = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+ = note: required for `[K]` to implement `IntoIterator`
help: consider borrowing here
|
LL | for i2 in &v2[1..] {
@@ -47,10 +47,10 @@ error[E0277]: `[K]` is not an iterator
--> $DIR/slice-issue-87994.rs:11:13
|
LL | for i2 in v2[1..] {
- | ^^^^^^^ expected an implementor of trait `IntoIterator`
+ | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]`
|
= note: the trait bound `[K]: IntoIterator` is not satisfied
- = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+ = note: required for `[K]` to implement `IntoIterator`
help: consider borrowing here
|
LL | for i2 in &v2[1..] {
diff --git a/src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.rs b/src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.rs
new file mode 100644
index 000000000..21ab6830b
--- /dev/null
+++ b/src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.rs
@@ -0,0 +1,10 @@
+// When build the suggesttion take in consideration the `:?`
+// https://github.com/rust-lang/rust/issues/100648
+#![deny(warnings)]
+
+fn main () {
+ println!("hello {:?}", world = "world");
+ //~^ ERROR named argument `world` is not used by name
+ //~| HELP use the named argument by name to avoid ambiguity
+ //~| SUGGESTION world
+}
diff --git a/src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.stderr b/src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.stderr
new file mode 100644
index 000000000..850f69f2d
--- /dev/null
+++ b/src/test/ui/suggestions/sugg_with_positional_args_and_debug_fmt.stderr
@@ -0,0 +1,21 @@
+error: named argument `world` is not used by name
+ --> $DIR/sugg_with_positional_args_and_debug_fmt.rs:6:28
+ |
+LL | println!("hello {:?}", world = "world");
+ | ---- ^^^^^ this named argument is referred to by position in formatting string
+ | |
+ | this formatting argument uses named argument `world` by position
+ |
+note: the lint level is defined here
+ --> $DIR/sugg_with_positional_args_and_debug_fmt.rs:3:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(named_arguments_used_positionally)]` implied by `#[deny(warnings)]`
+help: use the named argument by name to avoid ambiguity
+ |
+LL | println!("hello {world:?}", world = "world");
+ | +++++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed
new file mode 100644
index 000000000..e9b8a9caa
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused_variables)]
+
+fn foo(foo: &mut usize) {
+ todo!()
+}
+
+fn bar(bar: &usize) {
+ todo!()
+}
+
+fn main() {
+ foo(&mut Default::default()); //~ the trait bound `&mut usize: Default` is not satisfied
+ bar(&Default::default()); //~ the trait bound `&usize: Default` is not satisfied
+}
diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs
new file mode 100644
index 000000000..5fae21ccc
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused_variables)]
+
+fn foo(foo: &mut usize) {
+ todo!()
+}
+
+fn bar(bar: &usize) {
+ todo!()
+}
+
+fn main() {
+ foo(Default::default()); //~ the trait bound `&mut usize: Default` is not satisfied
+ bar(Default::default()); //~ the trait bound `&usize: Default` is not satisfied
+}
diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
new file mode 100644
index 000000000..125a8b44f
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `&mut usize: Default` is not satisfied
+ --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9
+ |
+LL | foo(Default::default());
+ | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize`
+ |
+help: consider mutably borrowing here
+ |
+LL | foo(&mut Default::default());
+ | ++++
+
+error[E0277]: the trait bound `&usize: Default` is not satisfied
+ --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9
+ |
+LL | bar(Default::default());
+ | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize`
+ |
+help: consider borrowing here
+ |
+LL | bar(&Default::default());
+ | +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/suggest-blanket-impl-local-trait.rs b/src/test/ui/suggestions/suggest-blanket-impl-local-trait.rs
index 7cf536f79..14fef1b52 100644
--- a/src/test/ui/suggestions/suggest-blanket-impl-local-trait.rs
+++ b/src/test/ui/suggestions/suggest-blanket-impl-local-trait.rs
@@ -1,5 +1,5 @@
// Ensure that the compiler include the blanklet implementation suggestion
-// when inside a `impl` statment are used two local traits.
+// when inside a `impl` statement are used two local traits.
//
// edition:2021
use std::fmt;
diff --git a/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr b/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr
index d739a8272..398caa98b 100644
--- a/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr
+++ b/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr
@@ -6,9 +6,8 @@ LL | impl LocalTraitTwo for LocalTraitOne {}
|
help: add `dyn` keyword before this trait
|
-LL - impl LocalTraitTwo for LocalTraitOne {}
-LL + impl LocalTraitTwo for dyn LocalTraitOne {}
- |
+LL | impl LocalTraitTwo for dyn LocalTraitOne {}
+ | +++
help: alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne`
|
LL | impl<T: LocalTraitOne> LocalTraitTwo for T {}
@@ -22,9 +21,8 @@ LL | impl fmt::Display for LocalTraitOne {
|
help: add `dyn` keyword before this trait
|
-LL - impl fmt::Display for LocalTraitOne {
-LL + impl fmt::Display for dyn LocalTraitOne {
- |
+LL | impl fmt::Display for dyn LocalTraitOne {
+ | +++
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/suggest-blanket-impl-local-trait.rs:26:23
@@ -34,9 +32,8 @@ LL | impl fmt::Display for LocalTraitTwo + Send {
|
help: add `dyn` keyword before this trait
|
-LL - impl fmt::Display for LocalTraitTwo + Send {
-LL + impl fmt::Display for dyn LocalTraitTwo + Send {
- |
+LL | impl fmt::Display for dyn LocalTraitTwo + Send {
+ | +++
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/suggest-blanket-impl-local-trait.rs:34:24
@@ -46,9 +43,8 @@ LL | impl LocalTraitOne for fmt::Display {}
|
help: add `dyn` keyword before this trait
|
-LL - impl LocalTraitOne for fmt::Display {}
-LL + impl LocalTraitOne for dyn fmt::Display {}
- |
+LL | impl LocalTraitOne for dyn fmt::Display {}
+ | +++
help: alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display`
|
LL | impl<T: fmt::Display> LocalTraitOne for T {}
@@ -62,9 +58,8 @@ LL | impl LocalTraitOne for fmt::Display + Send {}
|
help: add `dyn` keyword before this trait
|
-LL - impl LocalTraitOne for fmt::Display + Send {}
-LL + impl LocalTraitOne for dyn fmt::Display + Send {}
- |
+LL | impl LocalTraitOne for dyn fmt::Display + Send {}
+ | +++
help: alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display + Send`
|
LL | impl<T: fmt::Display + Send> LocalTraitOne for T {}
@@ -78,9 +73,8 @@ LL | impl<E> GenericTrait<E> for LocalTraitOne {}
|
help: add `dyn` keyword before this trait
|
-LL - impl<E> GenericTrait<E> for LocalTraitOne {}
-LL + impl<E> GenericTrait<E> for dyn LocalTraitOne {}
- |
+LL | impl<E> GenericTrait<E> for dyn LocalTraitOne {}
+ | +++
help: alternatively use a blanket implementation to implement `GenericTrait<E>` for all types that also implement `LocalTraitOne`
|
LL | impl<E, T: LocalTraitOne> GenericTrait<E> for T {}
@@ -94,9 +88,8 @@ LL | impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {}
|
help: add `dyn` keyword before this trait
|
-LL - impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {}
-LL + impl<T, E> GenericTraitTwo<E> for dyn GenericTrait<T> {}
- |
+LL | impl<T, E> GenericTraitTwo<E> for dyn GenericTrait<T> {}
+ | +++
help: alternatively use a blanket implementation to implement `GenericTraitTwo<E>` for all types that also implement `GenericTrait<T>`
|
LL | impl<T, E, U: GenericTrait<T>> GenericTraitTwo<E> for U {}
diff --git a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr
index 6b6e40613..6ce9bfd9d 100644
--- a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr
+++ b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr
@@ -2,9 +2,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
--> $DIR/suggest-borrow-to-dyn-object.rs:12:11
|
LL | check(s);
- | ----- ^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^ doesn't have a size known at compile-time
|
= help: within `OsStr`, the trait `Sized` is not implemented for `[u8]`
= note: required because it appears within the type `OsStr`
diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.stderr b/src/test/ui/suggestions/suggest-dereferencing-index.stderr
index c8b87af7b..147dc9234 100644
--- a/src/test/ui/suggestions/suggest-dereferencing-index.stderr
+++ b/src/test/ui/suggestions/suggest-dereferencing-index.stderr
@@ -6,7 +6,7 @@ LL | let one_item_please: i32 = [1, 2, 3][i];
|
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
- = note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]`
+ = note: required for `[{integer}]` to implement `Index<&usize>`
help: dereference this index
|
LL | let one_item_please: i32 = [1, 2, 3][*i];
diff --git a/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr b/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr
index 6583cabe1..f2eb651ea 100644
--- a/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr
+++ b/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `A: Trait` is not satisfied
--> $DIR/suggest-imm-mut-trait-implementations.rs:20:9
|
LL | foo(a);
- | --- ^ expected an implementor of trait `Trait`
+ | --- ^ the trait `Trait` is not implemented for `A`
| |
| required by a bound introduced by this call
|
@@ -22,7 +22,7 @@ error[E0277]: the trait bound `B: Trait` is not satisfied
--> $DIR/suggest-imm-mut-trait-implementations.rs:21:9
|
LL | foo(b);
- | --- ^ expected an implementor of trait `Trait`
+ | --- ^ the trait `Trait` is not implemented for `B`
| |
| required by a bound introduced by this call
|
@@ -40,7 +40,7 @@ error[E0277]: the trait bound `C: Trait` is not satisfied
--> $DIR/suggest-imm-mut-trait-implementations.rs:22:9
|
LL | foo(c);
- | --- ^ expected an implementor of trait `Trait`
+ | --- ^ the trait `Trait` is not implemented for `C`
| |
| required by a bound introduced by this call
|
diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr
index 97d7e6696..03cb9c779 100644
--- a/src/test/ui/suggestions/suggest-methods.stderr
+++ b/src/test/ui/suggestions/suggest-methods.stderr
@@ -5,25 +5,25 @@ LL | struct Foo;
| ---------- method `bat` not found for this struct
...
LL | f.bat(1.0);
- | ^^^ help: there is an associated function with a similar name: `bar`
+ | ^^^ help: there is a method with a similar name: `bar`
error[E0599]: no method named `is_emtpy` found for struct `String` in the current scope
--> $DIR/suggest-methods.rs:21:15
|
LL | let _ = s.is_emtpy();
- | ^^^^^^^^ help: there is an associated function with a similar name: `is_empty`
+ | ^^^^^^^^ help: there is a method with a similar name: `is_empty`
error[E0599]: no method named `count_eos` found for type `u32` in the current scope
--> $DIR/suggest-methods.rs:25:19
|
LL | let _ = 63u32.count_eos();
- | ^^^^^^^^^ help: there is an associated function with a similar name: `count_zeros`
+ | ^^^^^^^^^ help: there is a method with a similar name: `count_zeros`
error[E0599]: no method named `count_o` found for type `u32` in the current scope
--> $DIR/suggest-methods.rs:28:19
|
LL | let _ = 63u32.count_o();
- | ^^^^^^^ help: there is an associated function with a similar name: `count_ones`
+ | ^^^^^^^ help: there is a method with a similar name: `count_ones`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
index f52631cae..b1a49447d 100644
--- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
@@ -1,22 +1,22 @@
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/suggest-move-lifetimes.rs:1:13
|
LL | struct A<T, 'a> {
| ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/suggest-move-lifetimes.rs:5:13
|
LL | struct B<T, 'a, U> {
| ----^^---- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, U>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/suggest-move-lifetimes.rs:10:16
|
LL | struct C<T, U, 'a> {
| -------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, U>`
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime parameters must be declared prior to type and const parameters
--> $DIR/suggest-move-lifetimes.rs:15:16
|
LL | struct D<T, U, 'a, 'b, V, 'c> {
diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr
index 1a6032db0..b222e8142 100644
--- a/src/test/ui/suggestions/suggest-move-types.stderr
+++ b/src/test/ui/suggestions/suggest-move-types.stderr
@@ -121,7 +121,7 @@ LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=()
| ^^
|
= note: lifetime arguments must be provided before type arguments
- = help: reorder the arguments: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
+ = help: reorder the arguments: lifetimes, then type and consts: `<'a, 'b, 'c, T, U, V>`
error[E0747]: lifetime provided when a type was expected
--> $DIR/suggest-move-types.rs:82:56
@@ -130,7 +130,7 @@ LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, '
| ^^
|
= note: lifetime arguments must be provided before type arguments
- = help: reorder the arguments: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
+ = help: reorder the arguments: lifetimes, then type and consts: `<'a, 'b, 'c, T, U, V>`
error: aborting due to 12 previous errors
diff --git a/src/test/ui/suggestions/suggest-ref-macro.stderr b/src/test/ui/suggestions/suggest-ref-macro.stderr
index 84cbc9357..17de49fbd 100644
--- a/src/test/ui/suggestions/suggest-ref-macro.stderr
+++ b/src/test/ui/suggestions/suggest-ref-macro.stderr
@@ -10,14 +10,8 @@ LL | #[hello]
note: function defined here
--> $DIR/suggest-ref-macro.rs:8:1
|
-LL | #[hello]
- | _-^^^^^^^
-LL | | fn abc() {}
-LL | |
-LL | | fn x(_: &mut i32) {}
-LL | |
-LL | | macro_rules! bla {
- | |_____________-
+LL | #[hello]
+ | ^^^^^^^^
= note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.stderr b/src/test/ui/suggestions/suggest-remove-refs-1.stderr
index 1083b2f97..1a843f3f5 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-1.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-1.stderr
@@ -8,7 +8,7 @@ LL | for (i, _) in &v.iter().enumerate() {
| help: consider removing the leading `&`-reference
|
= help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
- = note: required because of the requirements on the impl of `IntoIterator` for `&Enumerate<std::slice::Iter<'_, {integer}>>`
+ = note: required for `&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.stderr b/src/test/ui/suggestions/suggest-remove-refs-2.stderr
index 197b19a1b..f39361d52 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-2.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-2.stderr
@@ -8,7 +8,7 @@ LL | for (i, _) in & & & & &v.iter().enumerate() {
| help: consider removing 5 leading `&`-references
|
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
- = note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
+ = note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.stderr b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
index bb0cceac1..4d0732427 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-3.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
@@ -12,7 +12,7 @@ LL | | .enumerate() {
| |_____________________^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
- = note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
+ = note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
index fc880d6b8..87e716436 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
@@ -39,9 +39,8 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
help: add `dyn` keyword before this trait
|
-LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
-LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
- |
+LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
+ | +++
error: aborting due to 4 previous errors
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index f5143762d..f716e6c17 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -42,9 +42,8 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
-LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
- |
+LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
+ | +++
error: aborting due to 3 previous errors; 1 warning emitted
diff --git a/src/test/ui/suggestions/too-many-field-suggestions.rs b/src/test/ui/suggestions/too-many-field-suggestions.rs
new file mode 100644
index 000000000..905f9502c
--- /dev/null
+++ b/src/test/ui/suggestions/too-many-field-suggestions.rs
@@ -0,0 +1,29 @@
+struct Thing {
+ a0: Foo,
+ a1: Foo,
+ a2: Foo,
+ a3: Foo,
+ a4: Foo,
+ a5: Foo,
+ a6: Foo,
+ a7: Foo,
+ a8: Foo,
+ a9: Foo,
+}
+
+struct Foo {
+ field: Field,
+}
+
+struct Field;
+
+impl Foo {
+ fn bar(&self) {}
+}
+
+fn bar(t: Thing) {
+ t.bar(); //~ ERROR no method named `bar` found for struct `Thing`
+ t.field; //~ ERROR no field `field` on type `Thing`
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/too-many-field-suggestions.stderr b/src/test/ui/suggestions/too-many-field-suggestions.stderr
new file mode 100644
index 000000000..63ad6fdb1
--- /dev/null
+++ b/src/test/ui/suggestions/too-many-field-suggestions.stderr
@@ -0,0 +1,44 @@
+error[E0599]: no method named `bar` found for struct `Thing` in the current scope
+ --> $DIR/too-many-field-suggestions.rs:25:7
+ |
+LL | struct Thing {
+ | ------------ method `bar` not found for this struct
+...
+LL | t.bar();
+ | ^^^ method not found in `Thing`
+ |
+help: some of the expressions' fields have a method of the same name
+ |
+LL | t.a0.bar();
+ | +++
+LL | t.a1.bar();
+ | +++
+LL | t.a2.bar();
+ | +++
+LL | t.a3.bar();
+ | +++
+ and 6 other candidates
+
+error[E0609]: no field `field` on type `Thing`
+ --> $DIR/too-many-field-suggestions.rs:26:7
+ |
+LL | t.field;
+ | ^^^^^ unknown field
+ |
+ = note: available fields are: `a0`, `a1`, `a2`, `a3`, `a4` ... and 5 others
+help: some of the expressions' fields have a field of the same name
+ |
+LL | t.a0.field;
+ | +++
+LL | t.a1.field;
+ | +++
+LL | t.a2.field;
+ | +++
+LL | t.a3.field;
+ | +++
+ and 6 other candidates
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0599, E0609.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/try-removing-the-field.rs b/src/test/ui/suggestions/try-removing-the-field.rs
new file mode 100644
index 000000000..9d0573ca2
--- /dev/null
+++ b/src/test/ui/suggestions/try-removing-the-field.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+ foo: i32,
+ bar: (),
+ baz: (),
+}
+
+fn use_foo(x: Foo) -> i32 {
+ let Foo { foo, bar, .. } = x; //~ WARNING unused variable: `bar`
+ //~| help: try removing the field
+ return foo;
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/try-removing-the-field.stderr b/src/test/ui/suggestions/try-removing-the-field.stderr
new file mode 100644
index 000000000..448a2c3d2
--- /dev/null
+++ b/src/test/ui/suggestions/try-removing-the-field.stderr
@@ -0,0 +1,12 @@
+warning: unused variable: `bar`
+ --> $DIR/try-removing-the-field.rs:12:20
+ |
+LL | let Foo { foo, bar, .. } = x;
+ | ^^^-
+ | |
+ | help: try removing the field
+ |
+ = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/suggestions/type-ascription-and-other-error.rs b/src/test/ui/suggestions/type-ascription-and-other-error.rs
new file mode 100644
index 000000000..99ab2f3c8
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-and-other-error.rs
@@ -0,0 +1,6 @@
+fn main() {
+ not rust; //~ ERROR
+ let _ = 0: i32; // (error hidden by existing error)
+ #[cfg(FALSE)]
+ let _ = 0: i32; // (warning hidden by existing error)
+}
diff --git a/src/test/ui/suggestions/type-ascription-and-other-error.stderr b/src/test/ui/suggestions/type-ascription-and-other-error.stderr
new file mode 100644
index 000000000..eadf634bb
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-and-other-error.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `rust`
+ --> $DIR/type-ascription-and-other-error.rs:2:9
+ |
+LL | not rust;
+ | ^^^^ expected one of 8 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/unnamable-types.stderr b/src/test/ui/suggestions/unnamable-types.stderr
index de64269d1..ede3ebfa7 100644
--- a/src/test/ui/suggestions/unnamable-types.stderr
+++ b/src/test/ui/suggestions/unnamable-types.stderr
@@ -1,8 +1,8 @@
error: missing type for `const` item
- --> $DIR/unnamable-types.rs:6:7
+ --> $DIR/unnamable-types.rs:6:8
|
LL | const A = 5;
- | ^ help: provide a type for the constant: `A: i32`
+ | ^ help: provide a type for the constant: `: i32`
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/unnamable-types.rs:10:11
@@ -26,10 +26,10 @@ LL | const C: _ = || 42;
| ^^^^^
error: missing type for `const` item
- --> $DIR/unnamable-types.rs:23:7
+ --> $DIR/unnamable-types.rs:23:8
|
LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
- | ^
+ | ^
|
note: however, the inferred type `S<[closure@$DIR/unnamable-types.rs:23:31: 23:45]>` cannot be named
--> $DIR/unnamable-types.rs:23:11
@@ -38,22 +38,22 @@ LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing type for `const` item
- --> $DIR/unnamable-types.rs:29:7
+ --> $DIR/unnamable-types.rs:29:8
|
LL | const E = foo;
- | ^ help: provide a type for the constant: `E: fn() -> i32`
+ | ^ help: provide a type for the constant: `: fn() -> i32`
error: missing type for `const` item
- --> $DIR/unnamable-types.rs:32:7
+ --> $DIR/unnamable-types.rs:32:8
|
LL | const F = S { t: foo };
- | ^ help: provide a type for the constant: `F: S<fn() -> i32>`
+ | ^ help: provide a type for the constant: `: S<fn() -> i32>`
error: missing type for `const` item
- --> $DIR/unnamable-types.rs:37:7
+ --> $DIR/unnamable-types.rs:37:8
|
LL | const G = || -> i32 { yield 0; return 1; };
- | ^
+ | ^
|
note: however, the inferred type `[generator@$DIR/unnamable-types.rs:37:11: 37:20]` cannot be named
--> $DIR/unnamable-types.rs:37:11
diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
index 7038a572b..75b919232 100644
--- a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
+++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
@@ -12,7 +12,7 @@ LL | pub trait T<X, Y> {
help: replace the generic bounds with the associated types
|
LL | i: Box<dyn T<usize, usize, A = usize, C = usize, B=usize>>,
- | ~~~~~~~~~ ~~~~~~~~~
+ | +++ +++
error[E0191]: the value of the associated types `A` (from trait `T`), `C` (from trait `T`) must be specified
--> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
diff --git a/src/test/ui/tag-variant-disr-dup.rs b/src/test/ui/tag-variant-disr-dup.rs
deleted file mode 100644
index e497f993d..000000000
--- a/src/test/ui/tag-variant-disr-dup.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Black and White have the same discriminator value ...
-
-enum Color {
- //~^ ERROR discriminant value `0` assigned more than once
- Red = 0xff0000,
- Green = 0x00ff00,
- Blue = 0x0000ff,
- Black = 0x000000,
- White = 0x000000,
-}
-
-fn main() { }
diff --git a/src/test/ui/tag-variant-disr-dup.stderr b/src/test/ui/tag-variant-disr-dup.stderr
deleted file mode 100644
index 6b1ba43d2..000000000
--- a/src/test/ui/tag-variant-disr-dup.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0081]: discriminant value `0` assigned more than once
- --> $DIR/tag-variant-disr-dup.rs:3:1
- |
-LL | enum Color {
- | ^^^^^^^^^^
-...
-LL | Black = 0x000000,
- | -------- first assignment of `0`
-LL | White = 0x000000,
- | -------- second assignment of `0`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0081`.
diff --git a/src/test/ui/thir-tree.stdout b/src/test/ui/thir-tree.stdout
index 3c84be8e8..5fcdfca18 100644
--- a/src/test/ui/thir-tree.stdout
+++ b/src/test/ui/thir-tree.stdout
@@ -1,6 +1,17 @@
DefId(0:3 ~ thir_tree[8f1d]::main):
Thir {
arms: [],
+ blocks: [
+ Block {
+ targeted_by_break: false,
+ region_scope: Node(1),
+ opt_destruction_scope: None,
+ span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+ stmts: [],
+ expr: None,
+ safety_mode: Safe,
+ },
+ ],
exprs: [
Expr {
ty: (),
@@ -9,15 +20,7 @@ Thir {
),
span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
kind: Block {
- body: Block {
- targeted_by_break: false,
- region_scope: Node(1),
- opt_destruction_scope: None,
- span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
- stmts: [],
- expr: None,
- safety_mode: Safe,
- },
+ block: b0,
},
},
Expr {
@@ -51,5 +54,6 @@ Thir {
},
],
stmts: [],
+ params: [],
}
diff --git a/src/test/ui/traits/alias/cross-crate.stderr b/src/test/ui/traits/alias/cross-crate.stderr
index d0d00c97e..ae9d7d0a9 100644
--- a/src/test/ui/traits/alias/cross-crate.stderr
+++ b/src/test/ui/traits/alias/cross-crate.stderr
@@ -5,7 +5,7 @@ LL | use_alias::<Rc<u32>>();
| ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `Rc<u32>`
- = note: required because of the requirements on the impl of `SendSync` for `Rc<u32>`
+ = note: required for `Rc<u32>` to implement `SendSync`
note: required by a bound in `use_alias`
--> $DIR/cross-crate.rs:10:17
|
@@ -19,7 +19,7 @@ LL | use_alias::<Rc<u32>>();
| ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Rc<u32>`
- = note: required because of the requirements on the impl of `SendSync` for `Rc<u32>`
+ = note: required for `Rc<u32>` to implement `SendSync`
note: required by a bound in `use_alias`
--> $DIR/cross-crate.rs:10:17
|
diff --git a/src/test/ui/traits/alias/generic-default-in-dyn.rs b/src/test/ui/traits/alias/generic-default-in-dyn.rs
new file mode 100644
index 000000000..d44e1c2a9
--- /dev/null
+++ b/src/test/ui/traits/alias/generic-default-in-dyn.rs
@@ -0,0 +1,10 @@
+trait SendEqAlias<T> = PartialEq;
+//~^ ERROR trait aliases are experimental
+
+struct Foo<T>(dyn SendEqAlias<T>);
+//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+
+struct Bar<T>(dyn SendEqAlias<T>, T);
+//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/generic-default-in-dyn.stderr b/src/test/ui/traits/alias/generic-default-in-dyn.stderr
new file mode 100644
index 000000000..76a068e86
--- /dev/null
+++ b/src/test/ui/traits/alias/generic-default-in-dyn.stderr
@@ -0,0 +1,39 @@
+error[E0658]: trait aliases are experimental
+ --> $DIR/generic-default-in-dyn.rs:1:1
+ |
+LL | trait SendEqAlias<T> = PartialEq;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #41517 <https://github.com/rust-lang/rust/issues/41517> for more information
+ = help: add `#![feature(trait_alias)]` to the crate attributes to enable
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/generic-default-in-dyn.rs:4:19
+ |
+LL | struct Foo<T>(dyn SendEqAlias<T>);
+ | ^^^^^^^^^^^^^^ missing reference to `Rhs`
+ |
+ ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait PartialEq<Rhs: ?Sized = Self> {
+ | --------------------------------------- type parameter `Rhs` must be specified for this
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/generic-default-in-dyn.rs:7:19
+ |
+LL | struct Bar<T>(dyn SendEqAlias<T>, T);
+ | ^^^^^^^^^^^^^^ missing reference to `Rhs`
+ |
+ ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait PartialEq<Rhs: ?Sized = Self> {
+ | --------------------------------------- type parameter `Rhs` must be specified for this
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0393, E0658.
+For more information about an error, try `rustc --explain E0393`.
diff --git a/src/test/ui/traits/alias/self-in-const-generics.rs b/src/test/ui/traits/alias/self-in-const-generics.rs
new file mode 100644
index 000000000..b0de8ccd6
--- /dev/null
+++ b/src/test/ui/traits/alias/self-in-const-generics.rs
@@ -0,0 +1,12 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+#![feature(trait_alias)]
+
+trait Bar<const N: usize> {}
+
+trait BB = Bar<{ 2 + 1 }>;
+
+fn foo(x: &dyn BB) {}
+//~^ ERROR the trait alias `BB` cannot be made into an object [E0038]
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/self-in-const-generics.stderr b/src/test/ui/traits/alias/self-in-const-generics.stderr
new file mode 100644
index 000000000..61cc217cf
--- /dev/null
+++ b/src/test/ui/traits/alias/self-in-const-generics.stderr
@@ -0,0 +1,11 @@
+error[E0038]: the trait alias `BB` cannot be made into an object
+ --> $DIR/self-in-const-generics.rs:9:16
+ |
+LL | fn foo(x: &dyn BB) {}
+ | ^^
+ |
+ = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/traits/alias/self-in-generics.rs b/src/test/ui/traits/alias/self-in-generics.rs
new file mode 100644
index 000000000..0bb6335f9
--- /dev/null
+++ b/src/test/ui/traits/alias/self-in-generics.rs
@@ -0,0 +1,15 @@
+// astconv uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
+// This `FreshTy(0)` can leak into substs, causing ICEs in several places.
+// Using `save-analysis` triggers type-checking `f` that would be normally skipped
+// as `type_of` emitted an error.
+//
+// compile-flags: -Zsave-analysis
+
+#![feature(trait_alias)]
+
+pub trait SelfInput = Fn(&mut Self);
+
+pub fn f(_f: &dyn SelfInput) {}
+//~^ ERROR the trait alias `SelfInput` cannot be made into an object [E0038]
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/self-in-generics.stderr b/src/test/ui/traits/alias/self-in-generics.stderr
new file mode 100644
index 000000000..110d60e6e
--- /dev/null
+++ b/src/test/ui/traits/alias/self-in-generics.stderr
@@ -0,0 +1,11 @@
+error[E0038]: the trait alias `SelfInput` cannot be made into an object
+ --> $DIR/self-in-generics.rs:12:19
+ |
+LL | pub fn f(_f: &dyn SelfInput) {}
+ | ^^^^^^^^^
+ |
+ = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/traits/assoc-type-in-superbad.rs b/src/test/ui/traits/assoc-type-in-superbad.rs
index 579ce7cf7..d7d6241ef 100644
--- a/src/test/ui/traits/assoc-type-in-superbad.rs
+++ b/src/test/ui/traits/assoc-type-in-superbad.rs
@@ -4,13 +4,13 @@
use std::vec::IntoIter;
-pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
+pub trait Foo: Iterator<Item = <Self as Foo>::Key> {
type Key;
}
impl Foo for IntoIter<i32> {
- type Key = u32; //~ ERROR type mismatch
+ type Key = u32;
+ //~^ ERROR expected `std::vec::IntoIter<i32>` to be an iterator that yields `u32`, but it yields `i32`
}
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/traits/assoc-type-in-superbad.stderr b/src/test/ui/traits/assoc-type-in-superbad.stderr
index f36947914..3e2d9d903 100644
--- a/src/test/ui/traits/assoc-type-in-superbad.stderr
+++ b/src/test/ui/traits/assoc-type-in-superbad.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<std::vec::IntoIter<i32> as Iterator>::Item == u32`
+error[E0271]: expected `std::vec::IntoIter<i32>` to be an iterator that yields `u32`, but it yields `i32`
--> $DIR/assoc-type-in-superbad.rs:12:16
|
LL | type Key = u32;
@@ -7,8 +7,8 @@ LL | type Key = u32;
note: required by a bound in `Foo`
--> $DIR/assoc-type-in-superbad.rs:7:25
|
-LL | pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
- | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo`
+LL | pub trait Foo: Iterator<Item = <Self as Foo>::Key> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo`
error: aborting due to previous error
diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr
index bfbbe7fd2..fa7a8a2a0 100644
--- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr
+++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `str: Clone` is not satisfied
- --> $DIR/check-trait-object-bounds-1.rs:12:5
+ --> $DIR/check-trait-object-bounds-1.rs:12:9
|
LL | f::<dyn X<Y = str>>();
- | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+ | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `f`
diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr
index 46e8ce788..4084f69a6 100644
--- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr
+++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr
@@ -1,8 +1,8 @@
error[E0277]: expected a `FnOnce<(&i32,)>` closure, found `i32`
- --> $DIR/check-trait-object-bounds-2.rs:13:5
+ --> $DIR/check-trait-object-bounds-2.rs:13:9
|
LL | f::<dyn for<'x> X<'x, F = i32>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32`
|
= help: the trait `for<'r> FnOnce<(&'r i32,)>` is not implemented for `i32`
note: required by a bound in `f`
diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr
index 3ca36d5d2..4891ee9c2 100644
--- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr
+++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `str: Clone` is not satisfied
- --> $DIR/check-trait-object-bounds-4.rs:15:5
+ --> $DIR/check-trait-object-bounds-4.rs:15:9
|
LL | f::<dyn X<Y = str>>();
- | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+ | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `f`
diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr
index 4251c1a1e..00fdb3753 100644
--- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr
+++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr
@@ -1,8 +1,10 @@
error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
- --> $DIR/check-trait-object-bounds-5.rs:23:5
+ --> $DIR/check-trait-object-bounds-5.rs:23:12
|
LL | is_obj(x)
- | ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64`
+ | ------ ^ type mismatch resolving `<i32 as Is>::T == i64`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `i64`
--> $DIR/check-trait-object-bounds-5.rs:9:14
diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr
index 5b23a513e..9b0975e5e 100644
--- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr
+++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr
@@ -1,8 +1,10 @@
error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
- --> $DIR/check-trait-object-bounds-6.rs:20:5
+ --> $DIR/check-trait-object-bounds-6.rs:20:12
|
LL | is_obj(x)
- | ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64`
+ | ------ ^ type mismatch resolving `<i32 as Is>::T == i64`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `i64`
--> $DIR/check-trait-object-bounds-6.rs:9:14
diff --git a/src/test/ui/traits/bad-method-typaram-kind.stderr b/src/test/ui/traits/bad-method-typaram-kind.stderr
index 8befa4c5f..56acfbe80 100644
--- a/src/test/ui/traits/bad-method-typaram-kind.stderr
+++ b/src/test/ui/traits/bad-method-typaram-kind.stderr
@@ -1,8 +1,8 @@
error[E0277]: `T` cannot be sent between threads safely
- --> $DIR/bad-method-typaram-kind.rs:2:7
+ --> $DIR/bad-method-typaram-kind.rs:2:13
|
LL | 1.bar::<T>();
- | ^^^ `T` cannot be sent between threads safely
+ | ^ `T` cannot be sent between threads safely
|
note: required by a bound in `Bar::bar`
--> $DIR/bad-method-typaram-kind.rs:6:14
diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
index 1d2345180..f9a934764 100644
--- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
+++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
@@ -2,10 +2,9 @@ fn strip_lf(s: &str) -> &str {
s.strip_suffix(b'\n').unwrap_or(s)
//~^ ERROR expected a `FnMut<(char,)>` closure, found `u8`
//~| NOTE expected an `FnMut<(char,)>` closure, found `u8`
- //~| NOTE required by a bound introduced by this call
//~| HELP the trait `FnMut<(char,)>` is not implemented for `u8`
//~| HELP the following other types implement trait `Pattern<'a>`:
- //~| NOTE required because of the requirements on the impl of `Pattern<'_>` for `u8`
+ //~| NOTE required for `u8` to implement `Pattern<'_>`
}
diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
index 6ce57b626..ce9ab2d81 100644
--- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
+++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
@@ -1,10 +1,8 @@
error[E0277]: expected a `FnMut<(char,)>` closure, found `u8`
- --> $DIR/assoc-fn-bound-root-obligation.rs:2:20
+ --> $DIR/assoc-fn-bound-root-obligation.rs:2:7
|
LL | s.strip_suffix(b'\n').unwrap_or(s)
- | ------------ ^^^^^ expected an `FnMut<(char,)>` closure, found `u8`
- | |
- | required by a bound introduced by this call
+ | ^^^^^^^^^^^^ expected an `FnMut<(char,)>` closure, found `u8`
|
= help: the trait `FnMut<(char,)>` is not implemented for `u8`
= help: the following other types implement trait `Pattern<'a>`:
@@ -15,7 +13,7 @@ LL | s.strip_suffix(b'\n').unwrap_or(s)
&'c &'b str
[char; N]
char
- = note: required because of the requirements on the impl of `Pattern<'_>` for `u8`
+ = note: required for `u8` to implement `Pattern<'_>`
error: aborting due to previous error
diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr
index 8a92dd118..1c52629da 100644
--- a/src/test/ui/traits/bound/not-on-bare-trait.stderr
+++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr
@@ -9,9 +9,8 @@ LL | fn foo(_x: Foo + Send) {
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
-LL - fn foo(_x: Foo + Send) {
-LL + fn foo(_x: dyn Foo + Send) {
- |
+LL | fn foo(_x: dyn Foo + Send) {
+ | +++
error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
--> $DIR/not-on-bare-trait.rs:7:8
diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.rs b/src/test/ui/traits/bound/on-structs-and-enums-locals.rs
index 21c0ce80f..60ba343bb 100644
--- a/src/test/ui/traits/bound/on-structs-and-enums-locals.rs
+++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.rs
@@ -8,8 +8,8 @@ struct Foo<T:Trait> {
fn main() {
let foo = Foo {
- //~^ ERROR E0277
x: 3
+ //~^ ERROR E0277
};
let baz: Foo<usize> = loop { };
diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr
index c9068a270..20bbe69c0 100644
--- a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr
+++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr
@@ -11,10 +11,10 @@ LL | struct Foo<T:Trait> {
| ^^^^^ required by this bound in `Foo`
error[E0277]: the trait bound `{integer}: Trait` is not satisfied
- --> $DIR/on-structs-and-enums-locals.rs:10:15
+ --> $DIR/on-structs-and-enums-locals.rs:11:12
|
-LL | let foo = Foo {
- | ^^^ the trait `Trait` is not implemented for `{integer}`
+LL | x: 3
+ | ^ the trait `Trait` is not implemented for `{integer}`
|
note: required by a bound in `Foo`
--> $DIR/on-structs-and-enums-locals.rs:5:14
diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs b/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs
index 8156868e0..5ef35b513 100644
--- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs
+++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs
@@ -6,8 +6,8 @@ use on_structs_and_enums_xc::{Bar, Foo, Trait};
fn main() {
let foo = Foo {
- //~^ ERROR E0277
x: 3
+ //~^ ERROR E0277
};
let bar: Bar<f64> = return;
//~^ ERROR E0277
diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr
index f4cc64af9..3fb5decb7 100644
--- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr
+++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr
@@ -11,10 +11,10 @@ LL | pub enum Bar<T:Trait> {
| ^^^^^ required by this bound in `Bar`
error[E0277]: the trait bound `{integer}: Trait` is not satisfied
- --> $DIR/on-structs-and-enums-xc1.rs:8:15
+ --> $DIR/on-structs-and-enums-xc1.rs:9:12
|
-LL | let foo = Foo {
- | ^^^ the trait `Trait` is not implemented for `{integer}`
+LL | x: 3
+ | ^ the trait `Trait` is not implemented for `{integer}`
|
note: required by a bound in `Foo`
--> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18
diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr
index 859403f20..2478eb354 100644
--- a/src/test/ui/traits/cycle-cache-err-60010.stderr
+++ b/src/test/ui/traits/cycle-cache-err-60010.stderr
@@ -17,12 +17,12 @@ note: required because it appears within the type `RootDatabase`
|
LL | struct RootDatabase {
| ^^^^^^^^^^^^
-note: required because of the requirements on the impl of `SourceDatabase` for `RootDatabase`
+note: required for `RootDatabase` to implement `SourceDatabase`
--> $DIR/cycle-cache-err-60010.rs:44:9
|
LL | impl<T> SourceDatabase for T
| ^^^^^^^^^^^^^^ ^
-note: required because of the requirements on the impl of `Query<RootDatabase>` for `ParseQuery`
+note: required for `ParseQuery` to implement `Query<RootDatabase>`
--> $DIR/cycle-cache-err-60010.rs:37:10
|
LL | impl<DB> Query<DB> for ParseQuery
diff --git a/src/test/ui/traits/inductive-overflow/lifetime.rs b/src/test/ui/traits/inductive-overflow/lifetime.rs
index c36c17d3d..004e47737 100644
--- a/src/test/ui/traits/inductive-overflow/lifetime.rs
+++ b/src/test/ui/traits/inductive-overflow/lifetime.rs
@@ -28,5 +28,5 @@ fn main() {
is_send::<X<C<'static>>>();
//~^ ERROR overflow evaluating
//~| 3 redundant requirements hidden
- //~| required because of
+ //~| required for
}
diff --git a/src/test/ui/traits/inductive-overflow/lifetime.stderr b/src/test/ui/traits/inductive-overflow/lifetime.stderr
index 9ca615aac..b72d53bdd 100644
--- a/src/test/ui/traits/inductive-overflow/lifetime.stderr
+++ b/src/test/ui/traits/inductive-overflow/lifetime.stderr
@@ -4,13 +4,13 @@ error[E0275]: overflow evaluating the requirement `X<C<'_>>: NotAuto`
LL | is_send::<X<C<'static>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: required because of the requirements on the impl of `NotAuto` for `Box<X<C<'_>>>`
+note: required for `Box<X<C<'_>>>` to implement `NotAuto`
--> $DIR/lifetime.rs:18:18
|
LL | impl<T: NotAuto> NotAuto for Box<T> {}
| ^^^^^^^ ^^^^^^
= note: 3 redundant requirements hidden
- = note: required because of the requirements on the impl of `NotAuto` for `X<C<'static>>`
+ = note: required for `X<C<'static>>` to implement `NotAuto`
note: required by a bound in `is_send`
--> $DIR/lifetime.rs:22:15
|
diff --git a/src/test/ui/traits/inductive-overflow/simultaneous.stderr b/src/test/ui/traits/inductive-overflow/simultaneous.stderr
index 230c2638c..09930e60e 100644
--- a/src/test/ui/traits/inductive-overflow/simultaneous.stderr
+++ b/src/test/ui/traits/inductive-overflow/simultaneous.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `{integer}: Tweedledum`
LL | is_ee(4);
| ^^^^^
|
-note: required because of the requirements on the impl of `Combo` for `{integer}`
+note: required for `{integer}` to implement `Combo`
--> $DIR/simultaneous.rs:11:34
|
LL | impl<T: Tweedledee + Tweedledum> Combo for T {}
diff --git a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
index d7697dcc6..3ec288d13 100644
--- a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
+++ b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
@@ -14,7 +14,7 @@ LL | let (a, b) = copy(NoClone);
| |
| required by a bound introduced by this call
|
-note: required because of the requirements on the impl of `Magic` for `NoClone`
+note: required for `NoClone` to implement `Magic`
--> $DIR/supertrait-auto-trait.rs:8:12
|
LL | auto trait Magic: Copy {}
diff --git a/src/test/ui/traits/inductive-overflow/supertrait.stderr b/src/test/ui/traits/inductive-overflow/supertrait.stderr
index 95325a534..4b862cf79 100644
--- a/src/test/ui/traits/inductive-overflow/supertrait.stderr
+++ b/src/test/ui/traits/inductive-overflow/supertrait.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `NoClone: Magic`
LL | let (a, b) = copy(NoClone);
| ^^^^
|
-note: required because of the requirements on the impl of `Magic` for `NoClone`
+note: required for `NoClone` to implement `Magic`
--> $DIR/supertrait.rs:5:16
|
LL | impl<T: Magic> Magic for T {}
diff --git a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr
index cab0ccdf7..656e0d0bf 100644
--- a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr
+++ b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr
@@ -1,18 +1,22 @@
error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
- --> $DIR/repeated-supertrait-ambig.rs:26:7
+ --> $DIR/repeated-supertrait-ambig.rs:26:15
|
LL | c.same_as(22)
- | ^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ | ------- ^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ | |
+ | required by a bound introduced by this call
|
= help: the following other types implement trait `CompareTo<T>`:
<i64 as CompareTo<i64>>
<i64 as CompareTo<u64>>
error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
- --> $DIR/repeated-supertrait-ambig.rs:30:7
+ --> $DIR/repeated-supertrait-ambig.rs:30:15
|
LL | c.same_as(22)
- | ^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
+ | ------- ^^ the trait `CompareTo<i32>` is not implemented for `C`
+ | |
+ | required by a bound introduced by this call
|
help: consider further restricting this bound
|
@@ -20,20 +24,24 @@ LL | fn with_trait<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
| ++++++++++++++++
error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
- --> $DIR/repeated-supertrait-ambig.rs:34:5
+ --> $DIR/repeated-supertrait-ambig.rs:34:37
|
LL | <dyn CompareToInts>::same_as(c, 22)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ | ---------------------------- ^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ | |
+ | required by a bound introduced by this call
|
= help: the following other types implement trait `CompareTo<T>`:
<i64 as CompareTo<i64>>
<i64 as CompareTo<u64>>
error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
- --> $DIR/repeated-supertrait-ambig.rs:38:5
+ --> $DIR/repeated-supertrait-ambig.rs:38:27
|
LL | CompareTo::same_as(c, 22)
- | ^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
+ | ------------------ ^^ the trait `CompareTo<i32>` is not implemented for `C`
+ | |
+ | required by a bound introduced by this call
|
help: consider further restricting this bound
|
@@ -41,10 +49,12 @@ LL | fn with_ufcs2<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
| ++++++++++++++++
error[E0277]: the trait bound `i64: CompareTo<i32>` is not satisfied
- --> $DIR/repeated-supertrait-ambig.rs:42:23
+ --> $DIR/repeated-supertrait-ambig.rs:42:31
|
LL | assert_eq!(22_i64.same_as(22), true);
- | ^^^^^^^ the trait `CompareTo<i32>` is not implemented for `i64`
+ | ------- ^^ the trait `CompareTo<i32>` is not implemented for `i64`
+ | |
+ | required by a bound introduced by this call
|
= help: the following other types implement trait `CompareTo<T>`:
<i64 as CompareTo<i64>>
diff --git a/src/test/ui/traits/issue-18400.stderr b/src/test/ui/traits/issue-18400.stderr
index 92e0f6007..4394e6f7e 100644
--- a/src/test/ui/traits/issue-18400.stderr
+++ b/src/test/ui/traits/issue-18400.stderr
@@ -5,13 +5,13 @@ LL | 0.contains(bits);
| ^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_18400`)
-note: required because of the requirements on the impl of `Set<&[_]>` for `{integer}`
+note: required for `{integer}` to implement `Set<&[_]>`
--> $DIR/issue-18400.rs:6:16
|
LL | impl<'a, T, S> Set<&'a [T]> for S where
| ^^^^^^^^^^^^ ^
= note: 128 redundant requirements hidden
- = note: required because of the requirements on the impl of `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>` for `{integer}`
+ = note: required for `{integer}` to implement `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>`
error: aborting due to previous error
diff --git a/src/test/ui/traits/issue-20692.stderr b/src/test/ui/traits/issue-20692.stderr
index 1d7f252e5..2028994cd 100644
--- a/src/test/ui/traits/issue-20692.stderr
+++ b/src/test/ui/traits/issue-20692.stderr
@@ -27,7 +27,7 @@ LL | trait Array: Sized + Copy {}
| | |
| | ...because it requires `Self: Sized`
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Array>` for `&T`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Array>`
= note: required by cast to type `&dyn Array`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/issue-38604.stderr b/src/test/ui/traits/issue-38604.stderr
index d41488c15..50d6fb054 100644
--- a/src/test/ui/traits/issue-38604.stderr
+++ b/src/test/ui/traits/issue-38604.stderr
@@ -25,7 +25,7 @@ LL | trait Foo where u32: Q<Self> {
| --- ^^^^^^^ ...because it uses `Self` as a type parameter
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<()>`
+ = note: required for `Box<()>` to implement `CoerceUnsized<Box<dyn Foo>>`
= note: required by cast to type `Box<dyn Foo>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/issue-71036.rs b/src/test/ui/traits/issue-71036.rs
index 3d2df6fe9..69eed0c04 100644
--- a/src/test/ui/traits/issue-71036.rs
+++ b/src/test/ui/traits/issue-71036.rs
@@ -12,6 +12,6 @@ impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'
//~^ ERROR the trait bound `&'a T: Unsize<&'a U>` is not satisfied
//~| NOTE the trait `Unsize<&'a U>` is not implemented for `&'a T`
//~| NOTE all implementations of `Unsize` are provided automatically by the compiler
-//~| NOTE required because of the requirements on the impl
+//~| NOTE required for
fn main() {}
diff --git a/src/test/ui/traits/issue-71036.stderr b/src/test/ui/traits/issue-71036.stderr
index 3ee6db40e..79eb7a2ae 100644
--- a/src/test/ui/traits/issue-71036.stderr
+++ b/src/test/ui/traits/issue-71036.stderr
@@ -5,7 +5,7 @@ LL | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize<&'a U>` is not implemented for `&'a T`
|
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
- = note: required because of the requirements on the impl of `DispatchFromDyn<&'a &'a U>` for `&'a &'a T`
+ = note: required for `&'a &'a T` to implement `DispatchFromDyn<&'a &'a U>`
error: aborting due to previous error
diff --git a/src/test/ui/traits/issue-71136.stderr b/src/test/ui/traits/issue-71136.stderr
index 62a2a64ed..f54173392 100644
--- a/src/test/ui/traits/issue-71136.stderr
+++ b/src/test/ui/traits/issue-71136.stderr
@@ -7,7 +7,7 @@ LL | struct FooHolster {
LL | the_foos: Vec<Foo>,
| ^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Foo`
|
- = note: required because of the requirements on the impl of `Clone` for `Vec<Foo>`
+ = note: required for `Vec<Foo>` to implement `Clone`
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Foo` with `#[derive(Clone)]`
|
diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr
index 2b832e27c..e210f11b3 100644
--- a/src/test/ui/traits/issue-77982.stderr
+++ b/src/test/ui/traits/issue-77982.stderr
@@ -2,7 +2,9 @@ error[E0283]: type annotations needed
--> $DIR/issue-77982.rs:8:10
|
LL | opts.get(opt.as_ref());
- | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get`
+ | ^^^ ------------ type must be known at this point
+ | |
+ | cannot infer type of the type parameter `Q` declared on the associated function `get`
|
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
- impl Borrow<str> for String;
@@ -13,7 +15,7 @@ note: required by a bound in `HashMap::<K, V, S>::get`
|
LL | K: Borrow<Q>,
| ^^^^^^^^^ required by this bound in `HashMap::<K, V, S>::get`
-help: consider specifying the type argument in the function call
+help: consider specifying the generic argument
|
LL | opts.get::<Q>(opt.as_ref());
| +++++
@@ -42,7 +44,7 @@ error[E0283]: type annotations needed
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
| --------- ^^^^
| |
- | type must be known at this point
+ | required by a bound introduced by this call
|
= note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`:
- impl From<Ipv4Addr> for u32;
diff --git a/src/test/ui/traits/issue-82830.stderr b/src/test/ui/traits/issue-82830.stderr
index f863143c7..6a597a402 100644
--- a/src/test/ui/traits/issue-82830.stderr
+++ b/src/test/ui/traits/issue-82830.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `P: Sized`
LL | t: MaybeBox<P>,
| ^^^^^^^^^^^
|
-note: required because of the requirements on the impl of `A<P, Box<P>>` for `P`
+note: required for `P` to implement `A<P, Box<P>>`
--> $DIR/issue-82830.rs:10:12
|
LL | impl<Y, N> A<Y, N> for P {
diff --git a/src/test/ui/traits/issue-91594.stderr b/src/test/ui/traits/issue-91594.stderr
index f2b3de13b..5fcd090a8 100644
--- a/src/test/ui/traits/issue-91594.stderr
+++ b/src/test/ui/traits/issue-91594.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
- --> $DIR/issue-91594.rs:10:6
+ --> $DIR/issue-91594.rs:10:1
|
LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
|
= help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
-note: required because of the requirements on the impl of `Component<Foo>` for `Foo`
+note: required for `Foo` to implement `Component<Foo>`
--> $DIR/issue-91594.rs:13:27
|
LL | impl<M: HasComponent<()>> Component<M> for Foo {
diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
index f5d6d72af..6acf2fe65 100644
--- a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
+++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
@@ -15,9 +15,9 @@ LL | recurse(IteratorOfWrapped(elements).map(|t| t.0))
error[E0275]: overflow evaluating the requirement `(): Sized`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
- = note: required because of the requirements on the impl of `Iterator` for `std::iter::Empty<()>`
+ = note: required for `std::iter::Empty<()>` to implement `Iterator`
= note: 171 redundant requirements hidden
- = note: required because of the requirements on the impl of `Iterator` for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>`
+ = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>` to implement `Iterator`
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/traits/issue-97576.stderr b/src/test/ui/traits/issue-97576.stderr
index bdee073d6..146d38d07 100644
--- a/src/test/ui/traits/issue-97576.stderr
+++ b/src/test/ui/traits/issue-97576.stderr
@@ -1,10 +1,12 @@
error[E0277]: the trait bound `String: From<impl ToString>` is not satisfied
- --> $DIR/issue-97576.rs:8:22
+ --> $DIR/issue-97576.rs:8:18
|
LL | bar: bar.into(),
- | ^^^^ the trait `From<impl ToString>` is not implemented for `String`
+ | ^^^ ---- required by a bound introduced by this call
+ | |
+ | the trait `From<impl ToString>` is not implemented for `String`
|
- = note: required because of the requirements on the impl of `Into<String>` for `impl ToString`
+ = note: required for `impl ToString` to implement `Into<String>`
error: aborting due to previous error
diff --git a/src/test/ui/traits/multidispatch-bad.stderr b/src/test/ui/traits/multidispatch-bad.stderr
index 8b6e61006..d58f1e2d9 100644
--- a/src/test/ui/traits/multidispatch-bad.stderr
+++ b/src/test/ui/traits/multidispatch-bad.stderr
@@ -10,7 +10,7 @@ note: function defined here
--> $DIR/multidispatch-bad.rs:13:4
|
LL | fn test<T,U>(_: T, _: U)
- | ^^^^ ---- ----
+ | ^^^^ ----
help: change the type of the numeric literal from `i32` to `u32`
|
LL | test(22i32, 44u32);
diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr
index cbec35934..6e6172eea 100644
--- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr
+++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr
@@ -13,7 +13,9 @@ error[E0283]: type annotations needed
--> $DIR/multidispatch-convert-ambig-dest.rs:26:5
|
LL | test(22, std::default::Default::default());
- | ^^^^ cannot infer type of the type parameter `U` declared on the function `test`
+ | ^^^^ -------------------------------- type must be known at this point
+ | |
+ | cannot infer type of the type parameter `U` declared on the function `test`
|
note: multiple `impl`s satisfying `i32: Convert<_>` found
--> $DIR/multidispatch-convert-ambig-dest.rs:8:1
@@ -30,10 +32,10 @@ LL | fn test<T,U>(_: T, _: U)
| ---- required by a bound in this
LL | where T : Convert<U>
| ^^^^^^^^^^ required by this bound in `test`
-help: consider specifying the type arguments in the function call
+help: consider specifying the generic arguments
|
-LL | test::<T, U>(22, std::default::Default::default());
- | ++++++++
+LL | test::<i32, U>(22, std::default::Default::default());
+ | ++++++++++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs
index 1314f9cb0..17ddaa312 100644
--- a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs
+++ b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs
@@ -1,5 +1,5 @@
// This tests issue #79683: note in the error message that the trait is
-// explicitely unimplemented instead of suggesting to implement it.
+// explicitly unimplemented instead of suggesting to implement it.
#![feature(negative_impls)]
diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
index c5d4ccc2f..41fc3600f 100644
--- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
+++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
@@ -61,12 +61,12 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely
--> $DIR/negated-auto-traits-error.rs:48:13
|
LL | is_send(Box::new(TestType));
- | ------- ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Send`
+ | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique<dummy2::TestType>`
| |
| required by a bound introduced by this call
|
= note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied
- = note: required because of the requirements on the impl of `Send` for `Unique<dummy2::TestType>`
+ = note: required for `Unique<dummy2::TestType>` to implement `Send`
= note: required because it appears within the type `Box<dummy2::TestType>`
note: required by a bound in `is_send`
--> $DIR/negated-auto-traits-error.rs:16:15
@@ -92,7 +92,7 @@ note: required because it appears within the type `Outer2<dummy3::TestType>`
|
LL | struct Outer2<T>(T);
| ^^^^^^
- = note: required because of the requirements on the impl of `Send` for `Unique<Outer2<dummy3::TestType>>`
+ = note: required for `Unique<Outer2<dummy3::TestType>>` to implement `Send`
= note: required because it appears within the type `Box<Outer2<dummy3::TestType>>`
note: required by a bound in `is_send`
--> $DIR/negated-auto-traits-error.rs:16:15
@@ -109,7 +109,7 @@ LL | is_sync(Outer2(TestType));
| required by a bound introduced by this call
|
= help: the trait `Send` is not implemented for `main::TestType`
-note: required because of the requirements on the impl of `Sync` for `Outer2<main::TestType>`
+note: required for `Outer2<main::TestType>` to implement `Sync`
--> $DIR/negated-auto-traits-error.rs:14:22
|
LL | unsafe impl<T: Send> Sync for Outer2<T> {}
diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr
index 75d45d905..53178328c 100644
--- a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr
+++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr
@@ -22,7 +22,7 @@ LL | impl I<i32> for B {}
| ^^^^^^^^^^^^^^^^^
LL | impl I<u32> for B {}
| ^^^^^^^^^^^^^^^^^
-note: required because of the requirements on the impl of `V<_>` for `A<B>`
+note: required for `A<B>` to implement `V<_>`
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:12
|
LL | impl<T, U> V<U> for A<T>
diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr
index eab42ca56..cbf093866 100644
--- a/src/test/ui/traits/object/enforce-supertrait-projection.stderr
+++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr
@@ -1,12 +1,12 @@
error[E0271]: type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
- --> $DIR/enforce-supertrait-projection.rs:9:5
+ --> $DIR/enforce-supertrait-projection.rs:9:17
|
LL | fn transmute<A, B>(x: A) -> B {
| - - expected type parameter
| |
| found type parameter
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
|
= note: expected type parameter `B`
found type parameter `A`
diff --git a/src/test/ui/traits/object/safety.stderr b/src/test/ui/traits/object/safety.stderr
index cf534d984..dc18adeaf 100644
--- a/src/test/ui/traits/object/safety.stderr
+++ b/src/test/ui/traits/object/safety.stderr
@@ -11,7 +11,7 @@ LL | trait Tr {
| -- this trait cannot be made into an object...
LL | fn foo();
| ^^^ ...because associated function `foo` has no `self` parameter
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Tr>` for `&St`
+ = note: required for `&St` to implement `CoerceUnsized<&dyn Tr>`
= note: required by cast to type `&dyn Tr`
help: consider turning `foo` into a method by giving it a `&self` argument
|
diff --git a/src/test/ui/traits/pointee-tail-is-generic-errors.stderr b/src/test/ui/traits/pointee-tail-is-generic-errors.stderr
index 8456f8456..0c3d7060d 100644
--- a/src/test/ui/traits/pointee-tail-is-generic-errors.stderr
+++ b/src/test/ui/traits/pointee-tail-is-generic-errors.stderr
@@ -1,8 +1,8 @@
error[E0271]: type mismatch resolving `<T as Pointee>::Metadata == ()`
- --> $DIR/pointee-tail-is-generic-errors.rs:13:5
+ --> $DIR/pointee-tail-is-generic-errors.rs:13:15
|
LL | is_thin::<T>();
- | ^^^^^^^^^^^^ expected `()`, found associated type
+ | ^ expected `()`, found associated type
|
= note: expected unit type `()`
found associated type `<T as Pointee>::Metadata`
@@ -15,13 +15,13 @@ LL | fn is_thin<T: std::ptr::Pointee<Metadata = ()> + ?Sized>() {}
| ^^^^^^^^^^^^^ required by this bound in `is_thin`
error[E0271]: type mismatch resolving `<Opaque as Pointee>::Metadata == ()`
- --> $DIR/pointee-tail-is-generic-errors.rs:16:5
+ --> $DIR/pointee-tail-is-generic-errors.rs:16:15
|
LL | type Opaque = impl std::fmt::Debug + ?Sized;
| ----------------------------- the found opaque type
...
LL | is_thin::<Opaque>();
- | ^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | ^^^^^^ expected `()`, found associated type
|
= note: expected unit type `()`
found associated type `<Opaque as Pointee>::Metadata`
diff --git a/src/test/ui/traits/resolution-in-overloaded-op.stderr b/src/test/ui/traits/resolution-in-overloaded-op.stderr
index 34fae64e4..fe5e1d6d2 100644
--- a/src/test/ui/traits/resolution-in-overloaded-op.stderr
+++ b/src/test/ui/traits/resolution-in-overloaded-op.stderr
@@ -8,8 +8,8 @@ LL | a * b
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
-LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64> {
- | ++++++++++++++++++
+LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64, Output = f64> {
+ | ++++++++++++++++++++++++++++++++
error: aborting due to previous error
diff --git a/src/test/ui/traits/suggest-deferences/issue-39029.stderr b/src/test/ui/traits/suggest-deferences/issue-39029.stderr
index 5c324cd38..eb2b88059 100644
--- a/src/test/ui/traits/suggest-deferences/issue-39029.stderr
+++ b/src/test/ui/traits/suggest-deferences/issue-39029.stderr
@@ -2,18 +2,20 @@ error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied
--> $DIR/issue-39029.rs:16:37
|
LL | let _errors = TcpListener::bind(&bad);
- | ----------------- ^^^^
- | | |
- | | the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
- | | help: consider dereferencing here: `&*bad`
+ | ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
+ | |
| required by a bound introduced by this call
|
- = note: required because of the requirements on the impl of `ToSocketAddrs` for `&NoToSocketAddrs`
+ = note: required for `&NoToSocketAddrs` to implement `ToSocketAddrs`
note: required by a bound in `TcpListener::bind`
--> $SRC_DIR/std/src/net/tcp.rs:LL:COL
|
LL | pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
| ^^^^^^^^^^^^^ required by this bound in `TcpListener::bind`
+help: consider dereferencing here
+ |
+LL | let _errors = TcpListener::bind(&*bad);
+ | +
error: aborting due to previous error
diff --git a/src/test/ui/traits/suggest-deferences/issue-62530.stderr b/src/test/ui/traits/suggest-deferences/issue-62530.stderr
index d129328da..e47ae0b65 100644
--- a/src/test/ui/traits/suggest-deferences/issue-62530.stderr
+++ b/src/test/ui/traits/suggest-deferences/issue-62530.stderr
@@ -2,10 +2,8 @@ error[E0277]: the trait bound `&String: SomeTrait` is not satisfied
--> $DIR/issue-62530.rs:13:26
|
LL | takes_type_parameter(&string); // Error
- | -------------------- ^^^^^^^
- | | |
- | | the trait `SomeTrait` is not implemented for `&String`
- | | help: consider dereferencing here: `&*string`
+ | -------------------- ^^^^^^^ the trait `SomeTrait` is not implemented for `&String`
+ | |
| required by a bound introduced by this call
|
note: required by a bound in `takes_type_parameter`
@@ -13,6 +11,10 @@ note: required by a bound in `takes_type_parameter`
|
LL | fn takes_type_parameter<T>(_x: T) where T: SomeTrait {}
| ^^^^^^^^^ required by this bound in `takes_type_parameter`
+help: consider dereferencing here
+ |
+LL | takes_type_parameter(&*string); // Error
+ | +
error: aborting due to previous error
diff --git a/src/test/ui/traits/suggest-deferences/multiple-0.stderr b/src/test/ui/traits/suggest-deferences/multiple-0.stderr
index efb3c7d12..6a4d4b8d5 100644
--- a/src/test/ui/traits/suggest-deferences/multiple-0.stderr
+++ b/src/test/ui/traits/suggest-deferences/multiple-0.stderr
@@ -2,10 +2,8 @@ error[E0277]: the trait bound `&Baz: Happy` is not satisfied
--> $DIR/multiple-0.rs:34:9
|
LL | foo(&baz);
- | --- ^^^^
- | | |
- | | the trait `Happy` is not implemented for `&Baz`
- | | help: consider dereferencing here: `&***baz`
+ | --- ^^^^ the trait `Happy` is not implemented for `&Baz`
+ | |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
@@ -13,6 +11,10 @@ note: required by a bound in `foo`
|
LL | fn foo<T>(_: T) where T: Happy {}
| ^^^^^ required by this bound in `foo`
+help: consider dereferencing here
+ |
+LL | foo(&***baz);
+ | +++
error: aborting due to previous error
diff --git a/src/test/ui/traits/suggest-deferences/root-obligation.stderr b/src/test/ui/traits/suggest-deferences/root-obligation.stderr
index 16e03e79c..76663ace7 100644
--- a/src/test/ui/traits/suggest-deferences/root-obligation.stderr
+++ b/src/test/ui/traits/suggest-deferences/root-obligation.stderr
@@ -7,8 +7,8 @@ LL | .filter(|c| "aeiou".contains(c))
| required by a bound introduced by this call
|
= help: the trait `Fn<(char,)>` is not implemented for `char`
- = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&char`
- = note: required because of the requirements on the impl of `Pattern<'_>` for `&char`
+ = note: required for `&char` to implement `FnOnce<(char,)>`
+ = note: required for `&char` to implement `Pattern<'_>`
note: required by a bound in `core::str::<impl str>::contains`
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
diff --git a/src/test/ui/traits/suggest-where-clause.stderr b/src/test/ui/traits/suggest-where-clause.stderr
index d4d9b4967..747e2477b 100644
--- a/src/test/ui/traits/suggest-where-clause.stderr
+++ b/src/test/ui/traits/suggest-where-clause.stderr
@@ -19,13 +19,13 @@ LL + fn check<T: Iterator, U>() {
|
error[E0277]: the size for values of type `U` cannot be known at compilation time
- --> $DIR/suggest-where-clause.rs:10:5
+ --> $DIR/suggest-where-clause.rs:10:20
|
LL | fn check<T: Iterator, U: ?Sized>() {
| - this type parameter needs to be `std::marker::Sized`
...
LL | mem::size_of::<Misc<U>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | ^^^^^^^ doesn't have a size known at compile-time
|
note: required because it appears within the type `Misc<U>`
--> $DIR/suggest-where-clause.rs:3:8
diff --git a/src/test/ui/traits/test-2.stderr b/src/test/ui/traits/test-2.stderr
index 77ea4e4e9..eaa20b0b4 100644
--- a/src/test/ui/traits/test-2.stderr
+++ b/src/test/ui/traits/test-2.stderr
@@ -76,7 +76,7 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
| this trait cannot be made into an object...
= help: consider moving `dup` to another trait
= help: consider moving `blah` to another trait
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn bar>>` for `Box<{integer}>`
+ = note: required for `Box<{integer}>` to implement `CoerceUnsized<Box<dyn bar>>`
= note: required by cast to type `Box<dyn bar>`
error: aborting due to 5 previous errors
diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
index 8c6901180..af7a410f6 100644
--- a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
+++ b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `c` found for reference `&dyn Bar` in the current
--> $DIR/subtrait-method.rs:56:9
|
LL | bar.c();
- | ^ help: there is an associated function with a similar name: `a`
+ | ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
@@ -15,7 +15,7 @@ error[E0599]: no method named `b` found for reference `&dyn Foo` in the current
--> $DIR/subtrait-method.rs:60:9
|
LL | foo.b();
- | ^ help: there is an associated function with a similar name: `a`
+ | ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it
@@ -28,7 +28,7 @@ error[E0599]: no method named `c` found for reference `&dyn Foo` in the current
--> $DIR/subtrait-method.rs:62:9
|
LL | foo.c();
- | ^ help: there is an associated function with a similar name: `a`
+ | ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
@@ -41,7 +41,7 @@ error[E0599]: no method named `b` found for reference `&dyn Foo` in the current
--> $DIR/subtrait-method.rs:66:9
|
LL | foo.b();
- | ^ help: there is an associated function with a similar name: `a`
+ | ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it
@@ -54,7 +54,7 @@ error[E0599]: no method named `c` found for reference `&dyn Foo` in the current
--> $DIR/subtrait-method.rs:68:9
|
LL | foo.c();
- | ^ help: there is an associated function with a similar name: `a`
+ | ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
diff --git a/src/test/ui/unspecified-self-in-trait-ref.rs b/src/test/ui/traits/unspecified-self-in-trait-ref.rs
index 158b5a985..158b5a985 100644
--- a/src/test/ui/unspecified-self-in-trait-ref.rs
+++ b/src/test/ui/traits/unspecified-self-in-trait-ref.rs
diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr
index 7869176bb..7869176bb 100644
--- a/src/test/ui/unspecified-self-in-trait-ref.stderr
+++ b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr
diff --git a/src/test/ui/transmutability/abstraction/abstracted_assume.rs b/src/test/ui/transmutability/abstraction/abstracted_assume.rs
index 2abbbf3c1..0225c4230 100644
--- a/src/test/ui/transmutability/abstraction/abstracted_assume.rs
+++ b/src/test/ui/transmutability/abstraction/abstracted_assume.rs
@@ -3,6 +3,7 @@
//! provided indirectly through an abstraction.
#![crate_type = "lib"]
+#![feature(adt_const_params)]
#![feature(transmutability)]
#![allow(dead_code, incomplete_features, non_camel_case_types)]
@@ -13,19 +14,13 @@ mod assert {
Src,
Dst,
Context,
- const ASSUME_ALIGNMENT: bool,
- const ASSUME_LIFETIMES: bool,
- const ASSUME_VALIDITY: bool,
- const ASSUME_VISIBILITY: bool,
+ const ASSUME: std::mem::Assume,
>()
where
Dst: BikeshedIntrinsicFrom<
Src,
Context,
- ASSUME_ALIGNMENT,
- ASSUME_LIFETIMES,
- ASSUME_VALIDITY,
- ASSUME_VISIBILITY,
+ ASSUME,
>,
{}
}
@@ -35,7 +30,7 @@ fn direct() {
#[repr(C)] struct Src;
#[repr(C)] struct Dst;
- assert::is_transmutable::<Src, Dst, Context, false, false, false, false>();
+ assert::is_transmutable::<Src, Dst, Context, { std::mem::Assume::NOTHING }>();
}
fn via_const() {
@@ -45,7 +40,7 @@ fn via_const() {
const FALSE: bool = false;
- assert::is_transmutable::<Src, Dst, Context, FALSE, FALSE, FALSE, FALSE>();
+ assert::is_transmutable::<Src, Dst, Context, { std::mem::Assume::NOTHING }>();
}
fn via_associated_const() {
@@ -65,9 +60,13 @@ fn via_associated_const() {
Src,
Dst,
Context,
- {Ty::FALSE},
- {Ty::FALSE},
- {Ty::FALSE},
- {Ty::FALSE}
+ {
+ std::mem::Assume {
+ alignment: {Ty::FALSE},
+ lifetimes: {Ty::FALSE},
+ safety: {Ty::FALSE},
+ validity: {Ty::FALSE},
+ }
+ }
>();
}
diff --git a/src/test/ui/transmutability/abstraction/const_generic_fn.rs b/src/test/ui/transmutability/abstraction/const_generic_fn.rs
index 94c38bb28..e693a0957 100644
--- a/src/test/ui/transmutability/abstraction/const_generic_fn.rs
+++ b/src/test/ui/transmutability/abstraction/const_generic_fn.rs
@@ -6,13 +6,13 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn array_like<T, E, const N: usize>()
where
- T: BikeshedIntrinsicFrom<[E; N], Context, false, false, false, true>,
- [E; N]: BikeshedIntrinsicFrom<T, Context, false, false, false, true>
+ T: BikeshedIntrinsicFrom<[E; N], Context, { Assume::SAFETY }>,
+ [E; N]: BikeshedIntrinsicFrom<T, Context, { Assume::SAFETY }>
{}
}
diff --git a/src/test/ui/transmutability/arrays/should_have_correct_length.rs b/src/test/ui/transmutability/arrays/should_have_correct_length.rs
index bfe6d830a..353797d0c 100644
--- a/src/test/ui/transmutability/arrays/should_have_correct_length.rs
+++ b/src/test/ui/transmutability/arrays/should_have_correct_length.rs
@@ -6,12 +6,12 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
{}
}
diff --git a/src/test/ui/transmutability/arrays/should_inherit_alignment.rs b/src/test/ui/transmutability/arrays/should_inherit_alignment.rs
index fcb1765ea..b00e5c7e4 100644
--- a/src/test/ui/transmutability/arrays/should_inherit_alignment.rs
+++ b/src/test/ui/transmutability/arrays/should_inherit_alignment.rs
@@ -6,12 +6,17 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs
index 8e69527c1..853bd9cbc 100644
--- a/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs
+++ b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs
@@ -5,12 +5,17 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr
index eae0c947d..96a2fdc54 100644
--- a/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr
+++ b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr
@@ -1,98 +1,134 @@
error[E0277]: `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:21:52
+ --> $DIR/should_require_well_defined_layout.rs:26:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<[String; 0], assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<[String; 0], assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `[String; 0]` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:22:47
+ --> $DIR/should_require_well_defined_layout.rs:27:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 0]` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `[String; 0]`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `[String; 0]`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:27:52
+ --> $DIR/should_require_well_defined_layout.rs:32:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<[String; 1], assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<[String; 1], assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `[String; 1]` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:28:47
+ --> $DIR/should_require_well_defined_layout.rs:33:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 1]` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `[String; 1]`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `[String; 1]`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:33:52
+ --> $DIR/should_require_well_defined_layout.rs:38:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<[String; 2], assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<[String; 2], assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `[String; 2]` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:34:47
+ --> $DIR/should_require_well_defined_layout.rs:39:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 2]` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `[String; 2]`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `[String; 2]`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error: aborting due to 6 previous errors
diff --git a/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
index 18e02b0d2..940f070e7 100644
--- a/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
+++ b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
@@ -5,11 +5,18 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
index fa2e3b89b..4da5fcea3 100644
--- a/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
+++ b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
@@ -1,322 +1,462 @@
error[E0277]: `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:41:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:48:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Zst, n8::Context, true, true, true, true>` is not implemented for `V0i8`
+ = help: the trait `BikeshedIntrinsicFrom<Zst, n8::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0i8`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:43:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:50:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0i8, n8::Context, true, true, true, true>` is not implemented for `u16`
+ = help: the trait `BikeshedIntrinsicFrom<V0i8, n8::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u16`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:49:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:56:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Zst, n8::Context, true, true, true, true>` is not implemented for `V0u8`
+ = help: the trait `BikeshedIntrinsicFrom<Zst, n8::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0u8`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:51:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:58:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0u8, n8::Context, true, true, true, true>` is not implemented for `u16`
+ = help: the trait `BikeshedIntrinsicFrom<V0u8, n8::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u16`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:65:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:72:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, n16::Context, true, true, true, true>` is not implemented for `V0i16`
+ = help: the trait `BikeshedIntrinsicFrom<u8, n16::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0i16`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:67:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:74:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0i16, n16::Context, true, true, true, true>` is not implemented for `u32`
+ = help: the trait `BikeshedIntrinsicFrom<V0i16, n16::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u32`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:73:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:80:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, n16::Context, true, true, true, true>` is not implemented for `V0u16`
+ = help: the trait `BikeshedIntrinsicFrom<u8, n16::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0u16`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:75:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:82:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0u16, n16::Context, true, true, true, true>` is not implemented for `u32`
+ = help: the trait `BikeshedIntrinsicFrom<V0u16, n16::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u32`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:89:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:96:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, n32::Context, true, true, true, true>` is not implemented for `V0i32`
+ = help: the trait `BikeshedIntrinsicFrom<u16, n32::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0i32`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:91:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:98:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0i32, n32::Context, true, true, true, true>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<V0i32, n32::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:97:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:104:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, n32::Context, true, true, true, true>` is not implemented for `V0u32`
+ = help: the trait `BikeshedIntrinsicFrom<u16, n32::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0u32`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:99:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:106:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0u32, n32::Context, true, true, true, true>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<V0u32, n32::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:113:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, n64::Context, true, true, true, true>` is not implemented for `V0i64`
+ = help: the trait `BikeshedIntrinsicFrom<u32, n64::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0i64`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:115:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:122:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0i64, n64::Context, true, true, true, true>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<V0i64, n64::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:121:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:128:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, n64::Context, true, true, true, true>` is not implemented for `V0u64`
+ = help: the trait `BikeshedIntrinsicFrom<u32, n64::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0u64`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:123:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:130:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0u64, n64::Context, true, true, true, true>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<V0u64, n64::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:137:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, nsize::Context, true, true, true, true>` is not implemented for `V0isize`
+ = help: the trait `BikeshedIntrinsicFrom<u8, nsize::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0isize`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:139:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:146:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0isize, nsize::Context, true, true, true, true>` is not implemented for `[usize; 2]`
+ = help: the trait `BikeshedIntrinsicFrom<V0isize, nsize::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `[usize; 2]`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:145:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:152:44
|
LL | assert::is_transmutable::<Smaller, Current, Context>();
| ^^^^^^^ `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, nsize::Context, true, true, true, true>` is not implemented for `V0usize`
+ = help: the trait `BikeshedIntrinsicFrom<u8, nsize::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `V0usize`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`.
- --> $DIR/primitive_reprs_should_have_correct_length.rs:147:44
+ --> $DIR/primitive_reprs_should_have_correct_length.rs:154:44
|
LL | assert::is_transmutable::<Current, Larger, Context>();
| ^^^^^^ `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<V0usize, nsize::Context, true, true, true, true>` is not implemented for `[usize; 2]`
+ = help: the trait `BikeshedIntrinsicFrom<V0usize, nsize::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `[usize; 2]`
note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error: aborting due to 20 previous errors
diff --git a/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs
index 978a12648..102111ae2 100644
--- a/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs
+++ b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs
@@ -6,12 +6,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
index 3273e87c8..510b8c56e 100644
--- a/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
+++ b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
@@ -1,98 +1,140 @@
error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:21:52
+ --> $DIR/should_require_well_defined_layout.rs:28:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<void::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<void::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:22:47
+ --> $DIR/should_require_well_defined_layout.rs:29:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `void::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `void::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `void::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:27:52
+ --> $DIR/should_require_well_defined_layout.rs:34:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `singleton::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<singleton::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<singleton::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:28:47
+ --> $DIR/should_require_well_defined_layout.rs:35:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `singleton::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `singleton::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `singleton::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:33:52
+ --> $DIR/should_require_well_defined_layout.rs:40:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `duplex::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<duplex::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<duplex::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:34:47
+ --> $DIR/should_require_well_defined_layout.rs:41:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `duplex::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `duplex::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `duplex::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error: aborting due to 6 previous errors
diff --git a/src/test/ui/transmutability/enums/should_order_correctly.rs b/src/test/ui/transmutability/enums/should_order_correctly.rs
index 6558d2658..b753cf0e6 100644
--- a/src/test/ui/transmutability/enums/should_order_correctly.rs
+++ b/src/test/ui/transmutability/enums/should_order_correctly.rs
@@ -7,12 +7,17 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/enums/should_pad_variants.rs b/src/test/ui/transmutability/enums/should_pad_variants.rs
index 466b6c8a1..c077c52a3 100644
--- a/src/test/ui/transmutability/enums/should_pad_variants.rs
+++ b/src/test/ui/transmutability/enums/should_pad_variants.rs
@@ -6,11 +6,16 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/enums/should_pad_variants.stderr b/src/test/ui/transmutability/enums/should_pad_variants.stderr
index 429f7211d..a823503d5 100644
--- a/src/test/ui/transmutability/enums/should_pad_variants.stderr
+++ b/src/test/ui/transmutability/enums/should_pad_variants.stderr
@@ -1,18 +1,24 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`.
- --> $DIR/should_pad_variants.rs:39:36
+ --> $DIR/should_pad_variants.rs:44:36
|
LL | assert::is_transmutable::<Src, Dst, Context>();
| ^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, should_pad_variants::Context, true, true, true, true>` is not implemented for `Dst`
+ = help: the trait `BikeshedIntrinsicFrom<Src, should_pad_variants::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `Dst`
note: required by a bound in `is_transmutable`
--> $DIR/should_pad_variants.rs:13:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/enums/should_respect_endianness.rs b/src/test/ui/transmutability/enums/should_respect_endianness.rs
index 67a3c4e94..19ff69005 100644
--- a/src/test/ui/transmutability/enums/should_respect_endianness.rs
+++ b/src/test/ui/transmutability/enums/should_respect_endianness.rs
@@ -7,12 +7,17 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/enums/should_respect_endianness.stderr b/src/test/ui/transmutability/enums/should_respect_endianness.stderr
index 78023cb37..fcb70813b 100644
--- a/src/test/ui/transmutability/enums/should_respect_endianness.stderr
+++ b/src/test/ui/transmutability/enums/should_respect_endianness.stderr
@@ -1,18 +1,24 @@
error[E0277]: `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context`.
- --> $DIR/should_respect_endianness.rs:32:36
+ --> $DIR/should_respect_endianness.rs:37:36
|
LL | assert::is_transmutable::<Src, Unexpected>();
| ^^^^^^^^^^ `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, assert::Context, true, true, true, true>` is not implemented for `Unexpected`
+ = help: the trait `BikeshedIntrinsicFrom<Src, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `Unexpected`
note: required by a bound in `is_transmutable`
--> $DIR/should_respect_endianness.rs:15:14
|
-LL | pub fn is_transmutable<Src, Dst>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs
index e13462d39..b3a1e13b8 100644
--- a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs
+++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs
@@ -10,7 +10,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
+ Dst: BikeshedIntrinsicFrom<Src, Context>
{}
}
diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs
index dc51e2a8f..092b205b7 100644
--- a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs
+++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs
@@ -10,7 +10,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
+ Dst: BikeshedIntrinsicFrom<Src, Context>
{}
}
diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
index 86fc8bd6b..ebe34e134 100644
--- a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
+++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
@@ -10,7 +10,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
+ Dst: BikeshedIntrinsicFrom<Src, Context>
{}
}
diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs
index bd36748e7..354abf99d 100644
--- a/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs
+++ b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs
@@ -2,11 +2,13 @@
//! provided.
#![crate_type = "lib"]
+#![feature(adt_const_params)]
+#![feature(generic_const_exprs)]
#![feature(transmutability)]
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<
Src,
@@ -14,19 +16,34 @@ mod assert {
Context,
const ASSUME_ALIGNMENT: bool,
const ASSUME_LIFETIMES: bool,
+ const ASSUME_SAFETY: bool,
const ASSUME_VALIDITY: bool,
- const ASSUME_VISIBILITY: bool,
>()
where
Dst: BikeshedIntrinsicFrom<
Src,
Context,
- ASSUME_ALIGNMENT,
- ASSUME_LIFETIMES,
- ASSUME_VALIDITY,
- ASSUME_VISIBILITY,
+ { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
+ //~^ ERROR E0080
+ //~| ERROR E0080
+ //~| ERROR E0080
+ //~| ERROR E0080
>,
{}
+
+ const fn from_options(
+ alignment: bool,
+ lifetimes: bool,
+ safety: bool,
+ validity: bool,
+ ) -> Assume {
+ Assume {
+ alignment,
+ lifetimes,
+ safety,
+ validity,
+ }
+ }
}
fn test() {
diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr
index e1464e023..a258f2ece 100644
--- a/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr
+++ b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr
@@ -1,27 +1,52 @@
error[E0308]: mismatched types
- --> $DIR/wrong-type-assume.rs:36:51
+ --> $DIR/wrong-type-assume.rs:53:51
|
LL | assert::is_transmutable::<Src, Dst, Context, {0u8}, false, false, false>();
| ^^^ expected `bool`, found `u8`
+error[E0080]: evaluation of `assert::is_transmutable::<test::Src, test::Dst, test::Context, {0u8}, false, false, false>::{constant#0}` failed
+ --> $DIR/wrong-type-assume.rs:26:15
+ |
+LL | { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
error[E0308]: mismatched types
- --> $DIR/wrong-type-assume.rs:37:58
+ --> $DIR/wrong-type-assume.rs:54:58
|
LL | assert::is_transmutable::<Src, Dst, Context, false, {0u8}, false, false>();
| ^^^ expected `bool`, found `u8`
+error[E0080]: evaluation of `assert::is_transmutable::<test::Src, test::Dst, test::Context, false, {0u8}, false, false>::{constant#0}` failed
+ --> $DIR/wrong-type-assume.rs:26:15
+ |
+LL | { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
error[E0308]: mismatched types
- --> $DIR/wrong-type-assume.rs:38:65
+ --> $DIR/wrong-type-assume.rs:55:65
|
LL | assert::is_transmutable::<Src, Dst, Context, false, false, {0u8}, false>();
| ^^^ expected `bool`, found `u8`
+error[E0080]: evaluation of `assert::is_transmutable::<test::Src, test::Dst, test::Context, false, false, {0u8}, false>::{constant#0}` failed
+ --> $DIR/wrong-type-assume.rs:26:15
+ |
+LL | { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
error[E0308]: mismatched types
- --> $DIR/wrong-type-assume.rs:39:72
+ --> $DIR/wrong-type-assume.rs:56:72
|
LL | assert::is_transmutable::<Src, Dst, Context, false, false, false, {0u8}>();
| ^^^ expected `bool`, found `u8`
-error: aborting due to 4 previous errors
+error[E0080]: evaluation of `assert::is_transmutable::<test::Src, test::Dst, test::Context, false, false, false, {0u8}>::{constant#0}` failed
+ --> $DIR/wrong-type-assume.rs:26:15
+ |
+LL | { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
+error: aborting due to 8 previous errors
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0080, E0308.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/transmutability/primitives/bool.rs b/src/test/ui/transmutability/primitives/bool.rs
index 4f79bc253..eebb74fff 100644
--- a/src/test/ui/transmutability/primitives/bool.rs
+++ b/src/test/ui/transmutability/primitives/bool.rs
@@ -4,17 +4,17 @@
#![allow(incomplete_features)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
{}
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
{}
}
diff --git a/src/test/ui/transmutability/primitives/bool.stderr b/src/test/ui/transmutability/primitives/bool.stderr
index dc740251c..214b5e150 100644
--- a/src/test/ui/transmutability/primitives/bool.stderr
+++ b/src/test/ui/transmutability/primitives/bool.stderr
@@ -4,15 +4,15 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope
LL | assert::is_transmutable::<u8, bool>();
| ^^^^ `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, true>` is not implemented for `bool`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `bool`
note: required by a bound in `is_transmutable`
--> $DIR/bool.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/primitives/numbers.rs b/src/test/ui/transmutability/primitives/numbers.rs
index a5f79065d..0df43d204 100644
--- a/src/test/ui/transmutability/primitives/numbers.rs
+++ b/src/test/ui/transmutability/primitives/numbers.rs
@@ -9,7 +9,7 @@ mod assert {
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
+ Dst: BikeshedIntrinsicFrom<Src, Context>
{}
}
diff --git a/src/test/ui/transmutability/primitives/numbers.stderr b/src/test/ui/transmutability/primitives/numbers.stderr
index 9b802a444..7cb7ca8e6 100644
--- a/src/test/ui/transmutability/primitives/numbers.stderr
+++ b/src/test/ui/transmutability/primitives/numbers.stderr
@@ -4,15 +4,15 @@ error[E0277]: `i8` cannot be safely transmuted into `i16` in the defining scope
LL | assert::is_transmutable::< i8, i16>();
| ^^^ `i8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i16`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i16`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:63:40
@@ -20,15 +20,15 @@ error[E0277]: `i8` cannot be safely transmuted into `u16` in the defining scope
LL | assert::is_transmutable::< i8, u16>();
| ^^^ `i8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u16`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u16`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:64:40
@@ -36,15 +36,15 @@ error[E0277]: `i8` cannot be safely transmuted into `i32` in the defining scope
LL | assert::is_transmutable::< i8, i32>();
| ^^^ `i8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i32`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:65:40
@@ -52,15 +52,15 @@ error[E0277]: `i8` cannot be safely transmuted into `f32` in the defining scope
LL | assert::is_transmutable::< i8, f32>();
| ^^^ `i8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `f32`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:66:40
@@ -68,15 +68,15 @@ error[E0277]: `i8` cannot be safely transmuted into `u32` in the defining scope
LL | assert::is_transmutable::< i8, u32>();
| ^^^ `i8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u32`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:67:40
@@ -84,15 +84,15 @@ error[E0277]: `i8` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< i8, u64>();
| ^^^ `i8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:68:40
@@ -100,15 +100,15 @@ error[E0277]: `i8` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< i8, i64>();
| ^^^ `i8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:69:40
@@ -116,15 +116,15 @@ error[E0277]: `i8` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< i8, f64>();
| ^^^ `i8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:70:39
@@ -132,15 +132,15 @@ error[E0277]: `i8` cannot be safely transmuted into `u128` in the defining scope
LL | assert::is_transmutable::< i8, u128>();
| ^^^^ `i8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:71:39
@@ -148,15 +148,15 @@ error[E0277]: `i8` cannot be safely transmuted into `i128` in the defining scope
LL | assert::is_transmutable::< i8, i128>();
| ^^^^ `i8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:73:40
@@ -164,15 +164,15 @@ error[E0277]: `u8` cannot be safely transmuted into `i16` in the defining scope
LL | assert::is_transmutable::< u8, i16>();
| ^^^ `u8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i16`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i16`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:74:40
@@ -180,15 +180,15 @@ error[E0277]: `u8` cannot be safely transmuted into `u16` in the defining scope
LL | assert::is_transmutable::< u8, u16>();
| ^^^ `u8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u16`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u16`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:75:40
@@ -196,15 +196,15 @@ error[E0277]: `u8` cannot be safely transmuted into `i32` in the defining scope
LL | assert::is_transmutable::< u8, i32>();
| ^^^ `u8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i32`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:76:40
@@ -212,15 +212,15 @@ error[E0277]: `u8` cannot be safely transmuted into `f32` in the defining scope
LL | assert::is_transmutable::< u8, f32>();
| ^^^ `u8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `f32`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:77:40
@@ -228,15 +228,15 @@ error[E0277]: `u8` cannot be safely transmuted into `u32` in the defining scope
LL | assert::is_transmutable::< u8, u32>();
| ^^^ `u8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u32`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:78:40
@@ -244,15 +244,15 @@ error[E0277]: `u8` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< u8, u64>();
| ^^^ `u8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:79:40
@@ -260,15 +260,15 @@ error[E0277]: `u8` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< u8, i64>();
| ^^^ `u8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:80:40
@@ -276,15 +276,15 @@ error[E0277]: `u8` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< u8, f64>();
| ^^^ `u8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:81:39
@@ -292,15 +292,15 @@ error[E0277]: `u8` cannot be safely transmuted into `u128` in the defining scope
LL | assert::is_transmutable::< u8, u128>();
| ^^^^ `u8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:82:39
@@ -308,15 +308,15 @@ error[E0277]: `u8` cannot be safely transmuted into `i128` in the defining scope
LL | assert::is_transmutable::< u8, i128>();
| ^^^^ `u8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:84:40
@@ -324,15 +324,15 @@ error[E0277]: `i16` cannot be safely transmuted into `i32` in the defining scope
LL | assert::is_transmutable::< i16, i32>();
| ^^^ `i16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `i32`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:85:40
@@ -340,15 +340,15 @@ error[E0277]: `i16` cannot be safely transmuted into `f32` in the defining scope
LL | assert::is_transmutable::< i16, f32>();
| ^^^ `i16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `f32`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:86:40
@@ -356,15 +356,15 @@ error[E0277]: `i16` cannot be safely transmuted into `u32` in the defining scope
LL | assert::is_transmutable::< i16, u32>();
| ^^^ `i16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `u32`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:87:40
@@ -372,15 +372,15 @@ error[E0277]: `i16` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< i16, u64>();
| ^^^ `i16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:88:40
@@ -388,15 +388,15 @@ error[E0277]: `i16` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< i16, i64>();
| ^^^ `i16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:89:40
@@ -404,15 +404,15 @@ error[E0277]: `i16` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< i16, f64>();
| ^^^ `i16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:90:39
@@ -420,15 +420,15 @@ error[E0277]: `i16` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< i16, u128>();
| ^^^^ `i16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:91:39
@@ -436,15 +436,15 @@ error[E0277]: `i16` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< i16, i128>();
| ^^^^ `i16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:93:40
@@ -452,15 +452,15 @@ error[E0277]: `u16` cannot be safely transmuted into `i32` in the defining scope
LL | assert::is_transmutable::< u16, i32>();
| ^^^ `u16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `i32`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:94:40
@@ -468,15 +468,15 @@ error[E0277]: `u16` cannot be safely transmuted into `f32` in the defining scope
LL | assert::is_transmutable::< u16, f32>();
| ^^^ `u16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `f32`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:95:40
@@ -484,15 +484,15 @@ error[E0277]: `u16` cannot be safely transmuted into `u32` in the defining scope
LL | assert::is_transmutable::< u16, u32>();
| ^^^ `u16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `u32`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u32`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:96:40
@@ -500,15 +500,15 @@ error[E0277]: `u16` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< u16, u64>();
| ^^^ `u16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:97:40
@@ -516,15 +516,15 @@ error[E0277]: `u16` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< u16, i64>();
| ^^^ `u16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:98:40
@@ -532,15 +532,15 @@ error[E0277]: `u16` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< u16, f64>();
| ^^^ `u16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:99:39
@@ -548,15 +548,15 @@ error[E0277]: `u16` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< u16, u128>();
| ^^^^ `u16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:100:39
@@ -564,15 +564,15 @@ error[E0277]: `u16` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< u16, i128>();
| ^^^^ `u16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:102:40
@@ -580,15 +580,15 @@ error[E0277]: `i32` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< i32, u64>();
| ^^^ `i32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:103:40
@@ -596,15 +596,15 @@ error[E0277]: `i32` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< i32, i64>();
| ^^^ `i32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:104:40
@@ -612,15 +612,15 @@ error[E0277]: `i32` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< i32, f64>();
| ^^^ `i32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:105:39
@@ -628,15 +628,15 @@ error[E0277]: `i32` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< i32, u128>();
| ^^^^ `i32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:106:39
@@ -644,15 +644,15 @@ error[E0277]: `i32` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< i32, i128>();
| ^^^^ `i32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:108:40
@@ -660,15 +660,15 @@ error[E0277]: `f32` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< f32, u64>();
| ^^^ `f32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:109:40
@@ -676,15 +676,15 @@ error[E0277]: `f32` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< f32, i64>();
| ^^^ `f32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:110:40
@@ -692,15 +692,15 @@ error[E0277]: `f32` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< f32, f64>();
| ^^^ `f32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:111:39
@@ -708,15 +708,15 @@ error[E0277]: `f32` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< f32, u128>();
| ^^^^ `f32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:112:39
@@ -724,15 +724,15 @@ error[E0277]: `f32` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< f32, i128>();
| ^^^^ `f32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:114:40
@@ -740,15 +740,15 @@ error[E0277]: `u32` cannot be safely transmuted into `u64` in the defining scope
LL | assert::is_transmutable::< u32, u64>();
| ^^^ `u32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `u64`
+ = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:115:40
@@ -756,15 +756,15 @@ error[E0277]: `u32` cannot be safely transmuted into `i64` in the defining scope
LL | assert::is_transmutable::< u32, i64>();
| ^^^ `u32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `i64`
+ = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:116:40
@@ -772,15 +772,15 @@ error[E0277]: `u32` cannot be safely transmuted into `f64` in the defining scope
LL | assert::is_transmutable::< u32, f64>();
| ^^^ `u32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `f64`
+ = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `f64`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:117:39
@@ -788,15 +788,15 @@ error[E0277]: `u32` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< u32, u128>();
| ^^^^ `u32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:118:39
@@ -804,15 +804,15 @@ error[E0277]: `u32` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< u32, i128>();
| ^^^^ `u32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:120:39
@@ -820,15 +820,15 @@ error[E0277]: `u64` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< u64, u128>();
| ^^^^ `u64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u64, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<u64, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `u64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:121:39
@@ -836,15 +836,15 @@ error[E0277]: `u64` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< u64, i128>();
| ^^^^ `u64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u64, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<u64, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:123:39
@@ -852,15 +852,15 @@ error[E0277]: `i64` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< i64, u128>();
| ^^^^ `i64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i64, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<i64, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `i64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:124:39
@@ -868,15 +868,15 @@ error[E0277]: `i64` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< i64, i128>();
| ^^^^ `i64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<i64, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<i64, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:126:39
@@ -884,15 +884,15 @@ error[E0277]: `f64` cannot be safely transmuted into `u128` in the defining scop
LL | assert::is_transmutable::< f64, u128>();
| ^^^^ `f64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f64, assert::Context, false, false, false, false>` is not implemented for `u128`
+ = help: the trait `BikeshedIntrinsicFrom<f64, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `u128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `f64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
--> $DIR/numbers.rs:127:39
@@ -900,15 +900,15 @@ error[E0277]: `f64` cannot be safely transmuted into `i128` in the defining scop
LL | assert::is_transmutable::< f64, i128>();
| ^^^^ `f64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<f64, assert::Context, false, false, false, false>` is not implemented for `i128`
+ = help: the trait `BikeshedIntrinsicFrom<f64, assert::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `i128`
note: required by a bound in `is_transmutable`
--> $DIR/numbers.rs:12:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 57 previous errors
diff --git a/src/test/ui/transmutability/primitives/unit.rs b/src/test/ui/transmutability/primitives/unit.rs
index 86d474030..1975a61de 100644
--- a/src/test/ui/transmutability/primitives/unit.rs
+++ b/src/test/ui/transmutability/primitives/unit.rs
@@ -5,11 +5,16 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/primitives/unit.stderr b/src/test/ui/transmutability/primitives/unit.stderr
index cf27c0d17..8cabe44a0 100644
--- a/src/test/ui/transmutability/primitives/unit.stderr
+++ b/src/test/ui/transmutability/primitives/unit.stderr
@@ -1,18 +1,24 @@
error[E0277]: `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context`.
- --> $DIR/unit.rs:23:35
+ --> $DIR/unit.rs:28:35
|
LL | assert::is_transmutable::<(), u8, Context>();
| ^^ `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<(), should_have_correct_size::Context, true, true, true, true>` is not implemented for `u8`
+ = help: the trait `BikeshedIntrinsicFrom<(), should_have_correct_size::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u8`
note: required by a bound in `is_transmutable`
--> $DIR/unit.rs:12:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/references.rs b/src/test/ui/transmutability/references.rs
index c6fd4c43e..af3ff0ec1 100644
--- a/src/test/ui/transmutability/references.rs
+++ b/src/test/ui/transmutability/references.rs
@@ -5,12 +5,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/references.stderr b/src/test/ui/transmutability/references.stderr
index b1359ea58..e9c7b144a 100644
--- a/src/test/ui/transmutability/references.stderr
+++ b/src/test/ui/transmutability/references.stderr
@@ -1,18 +1,25 @@
error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`.
- --> $DIR/references.rs:19:37
+ --> $DIR/references.rs:26:52
|
LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>();
- | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`.
+ | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<&'static Unit, assert::Context, true, true, true, true>` is not implemented for `&'static Unit`
+ = help: the trait `BikeshedIntrinsicFrom<&'static Unit, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `&'static Unit`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/references.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/structs/repr/should_handle_align.rs b/src/test/ui/transmutability/structs/repr/should_handle_align.rs
index 71720165a..ea9bf2a23 100644
--- a/src/test/ui/transmutability/structs/repr/should_handle_align.rs
+++ b/src/test/ui/transmutability/structs/repr/should_handle_align.rs
@@ -6,12 +6,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/structs/repr/should_handle_packed.rs b/src/test/ui/transmutability/structs/repr/should_handle_packed.rs
index ae8acf504..17dc995fc 100644
--- a/src/test/ui/transmutability/structs/repr/should_handle_packed.rs
+++ b/src/test/ui/transmutability/structs/repr/should_handle_packed.rs
@@ -6,12 +6,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs
index 556be989d..9a65b4d70 100644
--- a/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs
+++ b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs
@@ -5,12 +5,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
index 07355f7c2..621dbee84 100644
--- a/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
+++ b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
@@ -1,194 +1,278 @@
error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:21:52
+ --> $DIR/should_require_well_defined_layout.rs:28:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::unit::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::unit::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:22:47
+ --> $DIR/should_require_well_defined_layout.rs:29:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::unit::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `should_reject_repr_rust::unit::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:27:52
+ --> $DIR/should_require_well_defined_layout.rs:34:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::tuple::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::tuple::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:28:47
+ --> $DIR/should_require_well_defined_layout.rs:35:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::tuple::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `should_reject_repr_rust::tuple::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:33:52
+ --> $DIR/should_require_well_defined_layout.rs:40:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::braces::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::braces::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:34:47
+ --> $DIR/should_require_well_defined_layout.rs:41:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::braces::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `should_reject_repr_rust::braces::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:39:52
+ --> $DIR/should_require_well_defined_layout.rs:46:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `aligned::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<aligned::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<aligned::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:40:47
+ --> $DIR/should_require_well_defined_layout.rs:47:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `aligned::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `aligned::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `aligned::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:45:52
+ --> $DIR/should_require_well_defined_layout.rs:52:52
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `packed::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<packed::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<packed::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:46:47
+ --> $DIR/should_require_well_defined_layout.rs:53:47
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `packed::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `packed::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `packed::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `nested::repr_c` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:52:49
+ --> $DIR/should_require_well_defined_layout.rs:59:49
|
LL | assert::is_maybe_transmutable::<repr_c, ()>();
| ^^ `nested::repr_c` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<nested::repr_c, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<nested::repr_c, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:53:47
+ --> $DIR/should_require_well_defined_layout.rs:60:47
|
LL | assert::is_maybe_transmutable::<u128, repr_c>();
| ^^^^^^ `u128` cannot be safely transmuted into `nested::repr_c` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `nested::repr_c`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `nested::repr_c`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error: aborting due to 12 previous errors
diff --git a/src/test/ui/transmutability/structs/should_order_fields_correctly.rs b/src/test/ui/transmutability/structs/should_order_fields_correctly.rs
index db49b914f..28724562b 100644
--- a/src/test/ui/transmutability/structs/should_order_fields_correctly.rs
+++ b/src/test/ui/transmutability/structs/should_order_fields_correctly.rs
@@ -6,12 +6,17 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/unions/boolish.rs b/src/test/ui/transmutability/unions/boolish.rs
index 975118b99..e469c4973 100644
--- a/src/test/ui/transmutability/unions/boolish.rs
+++ b/src/test/ui/transmutability/unions/boolish.rs
@@ -7,12 +7,12 @@
#![allow(incomplete_features)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
{}
}
diff --git a/src/test/ui/transmutability/unions/repr/should_handle_align.rs b/src/test/ui/transmutability/unions/repr/should_handle_align.rs
index e215799a2..09c13cc4d 100644
--- a/src/test/ui/transmutability/unions/repr/should_handle_align.rs
+++ b/src/test/ui/transmutability/unions/repr/should_handle_align.rs
@@ -6,12 +6,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/unions/repr/should_handle_packed.rs b/src/test/ui/transmutability/unions/repr/should_handle_packed.rs
index 34a53c7a8..24c2abd69 100644
--- a/src/test/ui/transmutability/unions/repr/should_handle_packed.rs
+++ b/src/test/ui/transmutability/unions/repr/should_handle_packed.rs
@@ -6,12 +6,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs
index cec8e389f..b1d5f71dc 100644
--- a/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs
+++ b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs
@@ -5,12 +5,19 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ }
+ }>
{}
}
diff --git a/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
index 2ed01b159..523bde85a 100644
--- a/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
+++ b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
@@ -1,34 +1,48 @@
error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:23:48
+ --> $DIR/should_require_well_defined_layout.rs:30:48
|
LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()`
+ = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::repr_rust, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` in the defining scope of `assert::Context`.
- --> $DIR/should_require_well_defined_layout.rs:24:43
+ --> $DIR/should_require_well_defined_layout.rs:31:43
|
LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::repr_rust`
+ = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `should_reject_repr_rust::repr_rust`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14
|
-LL | pub fn is_maybe_transmutable<Src, Dst>()
- | --------------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume {
+LL | | alignment: true,
+LL | | lifetimes: true,
+... |
+LL | | }
+LL | | }>
+ | |__________^ required by this bound in `is_maybe_transmutable`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/transmutability/unions/should_pad_variants.rs b/src/test/ui/transmutability/unions/should_pad_variants.rs
index c4757900f..cabe54467 100644
--- a/src/test/ui/transmutability/unions/should_pad_variants.rs
+++ b/src/test/ui/transmutability/unions/should_pad_variants.rs
@@ -6,11 +6,16 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, {
+ Assume::ALIGNMENT
+ .and(Assume::LIFETIMES)
+ .and(Assume::SAFETY)
+ .and(Assume::VALIDITY)
+ }>
{}
}
diff --git a/src/test/ui/transmutability/unions/should_pad_variants.stderr b/src/test/ui/transmutability/unions/should_pad_variants.stderr
index 429f7211d..a823503d5 100644
--- a/src/test/ui/transmutability/unions/should_pad_variants.stderr
+++ b/src/test/ui/transmutability/unions/should_pad_variants.stderr
@@ -1,18 +1,24 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`.
- --> $DIR/should_pad_variants.rs:39:36
+ --> $DIR/should_pad_variants.rs:44:36
|
LL | assert::is_transmutable::<Src, Dst, Context>();
| ^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, should_pad_variants::Context, true, true, true, true>` is not implemented for `Dst`
+ = help: the trait `BikeshedIntrinsicFrom<Src, should_pad_variants::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `Dst`
note: required by a bound in `is_transmutable`
--> $DIR/should_pad_variants.rs:13:14
|
-LL | pub fn is_transmutable<Src, Dst, Context>()
- | --------------- required by a bound in this
-LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | pub fn is_transmutable<Src, Dst, Context>()
+ | --------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, {
+ | ______________^
+LL | | Assume::ALIGNMENT
+LL | | .and(Assume::LIFETIMES)
+LL | | .and(Assume::SAFETY)
+LL | | .and(Assume::VALIDITY)
+LL | | }>
+ | |__________^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs b/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs
index 2493d7155..1007fdd79 100644
--- a/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs
+++ b/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs
@@ -7,13 +7,12 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true>
- // validity IS assumed --------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
{}
}
diff --git a/src/test/ui/transmutability/unions/should_reject_contraction.rs b/src/test/ui/transmutability/unions/should_reject_contraction.rs
index e8138d0e0..a24dfccd3 100644
--- a/src/test/ui/transmutability/unions/should_reject_contraction.rs
+++ b/src/test/ui/transmutability/unions/should_reject_contraction.rs
@@ -5,12 +5,12 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
{}
}
diff --git a/src/test/ui/transmutability/unions/should_reject_contraction.stderr b/src/test/ui/transmutability/unions/should_reject_contraction.stderr
index 99f589008..41f0cedc3 100644
--- a/src/test/ui/transmutability/unions/should_reject_contraction.stderr
+++ b/src/test/ui/transmutability/unions/should_reject_contraction.stderr
@@ -4,15 +4,15 @@ error[E0277]: `Superset` cannot be safely transmuted into `Subset` in the defini
LL | assert::is_transmutable::<Superset, Subset>();
| ^^^^^^ `Superset` cannot be safely transmuted into `Subset` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Superset, assert::Context, false, false, false, true>` is not implemented for `Subset`
+ = help: the trait `BikeshedIntrinsicFrom<Superset, assert::Context, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `Subset`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_contraction.rs:13:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/unions/should_reject_disjoint.rs b/src/test/ui/transmutability/unions/should_reject_disjoint.rs
index 16160e29a..43aaa6905 100644
--- a/src/test/ui/transmutability/unions/should_reject_disjoint.rs
+++ b/src/test/ui/transmutability/unions/should_reject_disjoint.rs
@@ -5,13 +5,12 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true>
- // validity IS assumed --------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
{}
}
diff --git a/src/test/ui/transmutability/unions/should_reject_disjoint.stderr b/src/test/ui/transmutability/unions/should_reject_disjoint.stderr
index 5714e2bf3..4323f9740 100644
--- a/src/test/ui/transmutability/unions/should_reject_disjoint.stderr
+++ b/src/test/ui/transmutability/unions/should_reject_disjoint.stderr
@@ -1,34 +1,34 @@
error[E0277]: `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`.
- --> $DIR/should_reject_disjoint.rs:34:40
+ --> $DIR/should_reject_disjoint.rs:33:40
|
LL | assert::is_maybe_transmutable::<A, B>();
| ^ `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<A, assert::Context, false, false, true, true>` is not implemented for `B`
+ = help: the trait `BikeshedIntrinsicFrom<A, assert::Context, Assume { alignment: false, lifetimes: false, safety: true, validity: true }>` is not implemented for `B`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_reject_disjoint.rs:13:14
|
LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
- --> $DIR/should_reject_disjoint.rs:35:40
+ --> $DIR/should_reject_disjoint.rs:34:40
|
LL | assert::is_maybe_transmutable::<B, A>();
| ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, false, false, true, true>` is not implemented for `A`
+ = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: false, lifetimes: false, safety: true, validity: true }>` is not implemented for `A`
note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_reject_disjoint.rs:13:14
|
LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/transmutability/unions/should_reject_intersecting.rs b/src/test/ui/transmutability/unions/should_reject_intersecting.rs
index 58e399fb9..9cd4233ee 100644
--- a/src/test/ui/transmutability/unions/should_reject_intersecting.rs
+++ b/src/test/ui/transmutability/unions/should_reject_intersecting.rs
@@ -6,13 +6,13 @@
#![allow(dead_code, incomplete_features, non_camel_case_types)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- // validity is NOT assumed ----------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ // validity is NOT assumed --------------^^^^^^^^^^^^^^^^^^
{}
}
diff --git a/src/test/ui/transmutability/unions/should_reject_intersecting.stderr b/src/test/ui/transmutability/unions/should_reject_intersecting.stderr
index 92689a5f8..e009888ae 100644
--- a/src/test/ui/transmutability/unions/should_reject_intersecting.stderr
+++ b/src/test/ui/transmutability/unions/should_reject_intersecting.stderr
@@ -4,15 +4,15 @@ error[E0277]: `A` cannot be safely transmuted into `B` in the defining scope of
LL | assert::is_transmutable::<A, B>();
| ^ `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<A, assert::Context, false, false, false, true>` is not implemented for `B`
+ = help: the trait `BikeshedIntrinsicFrom<A, assert::Context, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `B`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_intersecting.rs:14:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
--> $DIR/should_reject_intersecting.rs:37:34
@@ -20,15 +20,15 @@ error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of
LL | assert::is_transmutable::<B, A>();
| ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, false, false, false, true>` is not implemented for `A`
+ = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `A`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_intersecting.rs:14:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs
index 5a8c81049..8a41669c6 100644
--- a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs
+++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs
@@ -7,12 +7,12 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- // visibility IS assumed -------------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^
{}
}
diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs
index 77ab4fa6b..dd57b877d 100644
--- a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs
+++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs
@@ -7,12 +7,12 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- // visibility IS assumed -------------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^
{}
}
diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs
index 2421b24cb..ebce8ce87 100644
--- a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs
+++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs
@@ -13,12 +13,12 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- // visibility IS assumed -------------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^
{}
}
diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs
index 80b454fda..546fcbaa3 100644
--- a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs
+++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs
@@ -8,12 +8,12 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- // visibility IS assumed -------------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^
{}
}
diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs
index 7c53c91e4..b9b74d183 100644
--- a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs
+++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs
@@ -8,12 +8,12 @@
#![allow(dead_code)]
mod assert {
- use std::mem::BikeshedIntrinsicFrom;
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true>
- // visibility IS assumed -------------------------------------^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+ // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs
index c3f298f01..5a0df09d4 100644
--- a/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs
+++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs
@@ -11,8 +11,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs
index 73f6aece5..0f69630cc 100644
--- a/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs
+++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs
@@ -11,8 +11,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs
index 6d602601e..9c8345a8e 100644
--- a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs
+++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs
@@ -11,8 +11,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr
index 3f7d08d0a..39b73302e 100644
--- a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr
+++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr
@@ -1,5 +1,5 @@
error[E0446]: private type `src::Zst` in public interface
- --> $DIR/should_accept_if_src_has_unreachable_field.rs:23:9
+ --> $DIR/should_accept_if_src_has_unreachable_field.rs:22:9
|
LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type
| -------------------- `src::Zst` declared as private
diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs
index 1943fb871..acf9f2302 100644
--- a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs
+++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs
@@ -11,8 +11,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr
index e961984e1..76dc7f340 100644
--- a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr
+++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr
@@ -1,11 +1,11 @@
error[E0603]: struct `Src` is private
- --> $DIR/should_accept_if_src_has_unreachable_ty.rs:38:36
+ --> $DIR/should_accept_if_src_has_unreachable_ty.rs:37:36
|
LL | assert::is_transmutable::<src::Src, dst::Dst, Context>();
| ^^^ private struct
|
note: the struct `Src` is defined here
- --> $DIR/should_accept_if_src_has_unreachable_ty.rs:23:16
+ --> $DIR/should_accept_if_src_has_unreachable_ty.rs:22:16
|
LL | #[repr(C)] pub(self) struct Src {
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs
index fcf3f3a52..e8c3fbc9a 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs
@@ -10,8 +10,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr
index 85124019e..d5d6d431b 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr
@@ -1,18 +1,18 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
- --> $DIR/should_reject_if_dst_has_private_field.rs:36:41
+ --> $DIR/should_reject_if_dst_has_private_field.rs:35:41
|
LL | assert::is_transmutable::<src::Src, dst::Dst, Context>();
| ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst`
+ = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `Dst`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_if_dst_has_private_field.rs:13:14
|
LL | pub fn is_transmutable<Src, Dst, Context>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs
index 566b56467..47bca27ab 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs
@@ -10,8 +10,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr
index 0be564d93..a1ca2ced5 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr
@@ -1,18 +1,18 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
- --> $DIR/should_reject_if_dst_has_private_variant.rs:37:41
+ --> $DIR/should_reject_if_dst_has_private_variant.rs:36:41
|
LL | assert::is_transmutable::<src::Src, dst::Dst, Context>();
| ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst`
+ = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `Dst`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_if_dst_has_private_variant.rs:13:14
|
LL | pub fn is_transmutable<Src, Dst, Context>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs
index 35fff5966..662c32af1 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs
@@ -23,8 +23,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs
index 42799d803..d7e21676f 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs
@@ -12,8 +12,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr
index 95c68d452..4e648664d 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr
@@ -1,18 +1,18 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
- --> $DIR/should_reject_if_dst_has_unreachable_field.rs:38:41
+ --> $DIR/should_reject_if_dst_has_unreachable_field.rs:37:41
|
LL | assert::is_transmutable::<src::Src, dst::Dst, Context>();
| ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst`
+ = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `Dst`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_if_dst_has_unreachable_field.rs:15:14
|
LL | pub fn is_transmutable<Src, Dst, Context>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to previous error
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs
index e13b32b30..c7b59f15b 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs
@@ -12,8 +12,7 @@ mod assert {
pub fn is_transmutable<Src, Dst, Context>()
where
- Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- // visibility is NOT assumed ---------------------------------^^^^^
+ Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
{}
}
diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr
index 3391839e3..bd72d64cc 100644
--- a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr
+++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr
@@ -1,30 +1,30 @@
error[E0603]: struct `Dst` is private
- --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:39:46
+ --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:38:46
|
LL | assert::is_transmutable::<src::Src, dst::Dst, Context>();
| ^^^ private struct
|
note: the struct `Dst` is defined here
- --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:32:16
+ --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:31:16
|
LL | #[repr(C)] pub(self) struct Dst {
| ^^^^^^^^^^^^^^^^^^^^
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
- --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:39:41
+ --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:38:41
|
LL | assert::is_transmutable::<src::Src, dst::Dst, Context>();
| ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`.
|
- = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst`
+ = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `Dst`
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_if_dst_has_unreachable_ty.rs:15:14
|
LL | pub fn is_transmutable<Src, Dst, Context>()
| --------------- required by a bound in this
LL | where
-LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false>
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr
index f9906713f..e11c3f810 100644
--- a/src/test/ui/try-block/try-block-bad-type.stderr
+++ b/src/test/ui/try-block/try-block-bad-type.stderr
@@ -6,7 +6,7 @@ LL | Err("")?;
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the trait `From<Infallible>` is implemented for `TryFromSliceError`
- = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<u32, TryFromSliceError>`
+ = note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
--> $DIR/try-block-bad-type.rs:12:9
diff --git a/src/test/ui/try-trait/bad-interconversion.stderr b/src/test/ui/try-trait/bad-interconversion.stderr
index 1dbf3ebdf..27e6a603a 100644
--- a/src/test/ui/try-trait/bad-interconversion.stderr
+++ b/src/test/ui/try-trait/bad-interconversion.stderr
@@ -17,18 +17,15 @@ LL | Ok(Err(123_i32)?)
<f64 as From<i32>>
<f64 as From<i8>>
and 67 others
- = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, i32>>` for `Result<u64, u8>`
+ = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
--> $DIR/bad-interconversion.rs:11:12
|
-LL | / fn option_to_result() -> Result<u64, String> {
-LL | | Some(3)?;
- | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u64, String>`
-LL | |
-LL | | Ok(10)
-LL | | }
- | |_- this function returns a `Result`
+LL | fn option_to_result() -> Result<u64, String> {
+ | -------------------------------------------- this function returns a `Result`
+LL | Some(3)?;
+ | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u64, String>`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>`
= help: the following other types implement trait `FromResidual<R>`:
@@ -38,12 +35,10 @@ LL | | }
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
--> $DIR/bad-interconversion.rs:17:31
|
-LL | / fn control_flow_to_result() -> Result<u64, String> {
-LL | | Ok(ControlFlow::Break(123)?)
- | | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result<u64, String>`
-LL | |
-LL | | }
- | |_- this function returns a `Result`
+LL | fn control_flow_to_result() -> Result<u64, String> {
+ | -------------------------------------------------- this function returns a `Result`
+LL | Ok(ControlFlow::Break(123)?)
+ | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result<u64, String>`
|
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
= help: the following other types implement trait `FromResidual<R>`:
@@ -53,12 +48,10 @@ LL | | }
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
--> $DIR/bad-interconversion.rs:22:22
|
-LL | / fn result_to_option() -> Option<u16> {
-LL | | Some(Err("hello")?)
- | | ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
-LL | |
-LL | | }
- | |_- this function returns an `Option`
+LL | fn result_to_option() -> Option<u16> {
+ | ------------------------------------ this function returns an `Option`
+LL | Some(Err("hello")?)
+ | ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
|
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>`
= help: the following other types implement trait `FromResidual<R>`:
@@ -68,12 +61,10 @@ LL | | }
error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
--> $DIR/bad-interconversion.rs:27:33
|
-LL | / fn control_flow_to_option() -> Option<u64> {
-LL | | Some(ControlFlow::Break(123)?)
- | | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>`
-LL | |
-LL | | }
- | |_- this function returns an `Option`
+LL | fn control_flow_to_option() -> Option<u64> {
+ | ------------------------------------------ this function returns an `Option`
+LL | Some(ControlFlow::Break(123)?)
+ | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>`
|
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
= help: the following other types implement trait `FromResidual<R>`:
@@ -83,12 +74,10 @@ LL | | }
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
--> $DIR/bad-interconversion.rs:32:39
|
-LL | / fn result_to_control_flow() -> ControlFlow<String> {
-LL | | ControlFlow::Continue(Err("hello")?)
- | | ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `ControlFlow<String>`
-LL | |
-LL | | }
- | |_- this function returns a `ControlFlow`
+LL | fn result_to_control_flow() -> ControlFlow<String> {
+ | -------------------------------------------------- this function returns a `ControlFlow`
+LL | ControlFlow::Continue(Err("hello")?)
+ | ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `ControlFlow<String>`
|
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
= help: the trait `FromResidual` is implemented for `ControlFlow<B, C>`
@@ -96,13 +85,10 @@ LL | | }
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
--> $DIR/bad-interconversion.rs:37:12
|
-LL | / fn option_to_control_flow() -> ControlFlow<u64> {
-LL | | Some(3)?;
- | | ^ this `?` produces `Option<Infallible>`, which is incompatible with `ControlFlow<u64>`
-LL | |
-LL | | ControlFlow::Break(10)
-LL | | }
- | |_- this function returns a `ControlFlow`
+LL | fn option_to_control_flow() -> ControlFlow<u64> {
+ | ----------------------------------------------- this function returns a `ControlFlow`
+LL | Some(3)?;
+ | ^ this `?` produces `Option<Infallible>`, which is incompatible with `ControlFlow<u64>`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
= help: the trait `FromResidual` is implemented for `ControlFlow<B, C>`
@@ -110,13 +96,10 @@ LL | | }
error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
--> $DIR/bad-interconversion.rs:43:29
|
-LL | / fn control_flow_to_control_flow() -> ControlFlow<i64> {
-LL | | ControlFlow::Break(4_u8)?;
- | | ^ this `?` produces `ControlFlow<u8, Infallible>`, which is incompatible with `ControlFlow<i64>`
-LL | |
-LL | | ControlFlow::Continue(())
-LL | | }
- | |_- this function returns a `ControlFlow`
+LL | fn control_flow_to_control_flow() -> ControlFlow<i64> {
+ | ----------------------------------------------------- this function returns a `ControlFlow`
+LL | ControlFlow::Break(4_u8)?;
+ | ^ this `?` produces `ControlFlow<u8, Infallible>`, which is incompatible with `ControlFlow<i64>`
|
= help: the trait `FromResidual<ControlFlow<u8, Infallible>>` is not implemented for `ControlFlow<i64>`
= note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
diff --git a/src/test/ui/try-trait/option-to-result.stderr b/src/test/ui/try-trait/option-to-result.stderr
index ae5c3ad62..fabc1ff2c 100644
--- a/src/test/ui/try-trait/option-to-result.stderr
+++ b/src/test/ui/try-trait/option-to-result.stderr
@@ -1,13 +1,11 @@
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
--> $DIR/option-to-result.rs:5:6
|
-LL | / fn test_result() -> Result<(),()> {
-LL | | let a:Option<()> = Some(());
-LL | | a?;
- | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>`
-LL | | Ok(())
-LL | | }
- | |_- this function returns a `Result`
+LL | fn test_result() -> Result<(),()> {
+ | --------------------------------- this function returns a `Result`
+LL | let a:Option<()> = Some(());
+LL | a?;
+ | ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
= help: the following other types implement trait `FromResidual<R>`:
@@ -17,13 +15,11 @@ LL | | }
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
--> $DIR/option-to-result.rs:11:6
|
-LL | / fn test_option() -> Option<i32>{
-LL | | let a:Result<i32, i32> = Ok(5);
-LL | | a?;
- | | ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
-LL | | Some(5)
-LL | | }
- | |_- this function returns an `Option`
+LL | fn test_option() -> Option<i32>{
+ | ------------------------------- this function returns an `Option`
+LL | let a:Result<i32, i32> = Ok(5);
+LL | a?;
+ | ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
|
= help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>`
= help: the following other types implement trait `FromResidual<R>`:
diff --git a/src/test/ui/try-trait/try-on-option-diagnostics.stderr b/src/test/ui/try-trait/try-on-option-diagnostics.stderr
index a6badd190..9ee540c79 100644
--- a/src/test/ui/try-trait/try-on-option-diagnostics.stderr
+++ b/src/test/ui/try-trait/try-on-option-diagnostics.stderr
@@ -1,51 +1,44 @@
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:7:6
|
-LL | / fn a_function() -> u32 {
-LL | | let x: Option<u32> = None;
-LL | | x?;
- | | ^ cannot use the `?` operator in a function that returns `u32`
-LL | | 22
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn a_function() -> u32 {
+ | ---------------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a function that returns `u32`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:14:10
|
-LL | let a_closure = || {
- | _____________________-
-LL | | let x: Option<u32> = None;
-LL | | x?;
- | | ^ cannot use the `?` operator in a closure that returns `{integer}`
-LL | | 22
-LL | | };
- | |_____- this function should return `Result` or `Option` to accept `?`
+LL | let a_closure = || {
+ | -- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a closure that returns `{integer}`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:26:14
|
-LL | / fn a_method() {
-LL | | let x: Option<u32> = None;
-LL | | x?;
- | | ^ cannot use the `?` operator in a method that returns `()`
-LL | | }
- | |_________- this function should return `Result` or `Option` to accept `?`
+LL | fn a_method() {
+ | ------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a method that returns `()`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:39:14
|
-LL | / fn a_trait_method() {
-LL | | let x: Option<u32> = None;
-LL | | x?;
- | | ^ cannot use the `?` operator in a trait method that returns `()`
-LL | | }
- | |_________- this function should return `Result` or `Option` to accept `?`
+LL | fn a_trait_method() {
+ | ------------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a trait method that returns `()`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
diff --git a/src/test/ui/try-trait/try-on-option.stderr b/src/test/ui/try-trait/try-on-option.stderr
index ba85a7cad..fad6a1fe8 100644
--- a/src/test/ui/try-trait/try-on-option.stderr
+++ b/src/test/ui/try-trait/try-on-option.stderr
@@ -1,13 +1,11 @@
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
--> $DIR/try-on-option.rs:5:6
|
-LL | / fn foo() -> Result<u32, ()> {
-LL | | let x: Option<u32> = None;
-LL | | x?;
- | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u32, ()>`
-LL | | Ok(22)
-LL | | }
- | |_- this function returns a `Result`
+LL | fn foo() -> Result<u32, ()> {
+ | --------------------------- this function returns a `Result`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u32, ()>`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>`
= help: the following other types implement trait `FromResidual<R>`:
@@ -17,13 +15,11 @@ LL | | }
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option.rs:11:6
|
-LL | / fn bar() -> u32 {
-LL | | let x: Option<u32> = None;
-LL | | x?;
- | | ^ cannot use the `?` operator in a function that returns `u32`
-LL | | 22
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn bar() -> u32 {
+ | --------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a function that returns `u32`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
diff --git a/src/test/ui/try-trait/try-operator-on-main.stderr b/src/test/ui/try-trait/try-operator-on-main.stderr
index ad55f40b5..7cd38e0cf 100644
--- a/src/test/ui/try-trait/try-operator-on-main.stderr
+++ b/src/test/ui/try-trait/try-operator-on-main.stderr
@@ -1,15 +1,11 @@
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-operator-on-main.rs:7:31
|
-LL | / fn main() {
-LL | | // error for a `Try` type on a non-`Try` fn
-LL | | std::fs::File::open("foo")?;
- | | ^ cannot use the `?` operator in a function that returns `()`
-LL | |
-... |
-LL | | try_trait_generic::<()>();
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn main() {
+ | --------- this function should return `Result` or `Option` to accept `?`
+LL | // error for a `Try` type on a non-`Try` fn
+LL | std::fs::File::open("foo")?;
+ | ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
@@ -24,17 +20,11 @@ LL | ()?;
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-operator-on-main.rs:10:7
|
-LL | / fn main() {
-LL | | // error for a `Try` type on a non-`Try` fn
-LL | | std::fs::File::open("foo")?;
-LL | |
-LL | | // a non-`Try` type on a non-`Try` fn
-LL | | ()?;
- | | ^ cannot use the `?` operator in a function that returns `()`
-... |
-LL | | try_trait_generic::<()>();
-LL | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+LL | fn main() {
+ | --------- this function should return `Result` or `Option` to accept `?`
+...
+LL | ()?;
+ | ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
diff --git a/src/test/ui/tuple/add-tuple-within-arguments.stderr b/src/test/ui/tuple/add-tuple-within-arguments.stderr
index 95df96ca0..7029d298d 100644
--- a/src/test/ui/tuple/add-tuple-within-arguments.stderr
+++ b/src/test/ui/tuple/add-tuple-within-arguments.stderr
@@ -8,7 +8,7 @@ note: function defined here
--> $DIR/add-tuple-within-arguments.rs:1:4
|
LL | fn foo(s: &str, a: (i32, i32), s2: &str) {}
- | ^^^ ------- ------------- --------
+ | ^^^ -------------
help: wrap these arguments in parentheses to construct a tuple
|
LL | foo("hi", (1, 2), "hi");
@@ -28,7 +28,7 @@ note: function defined here
--> $DIR/add-tuple-within-arguments.rs:3:4
|
LL | fn bar(s: &str, a: (&str,), s2: &str) {}
- | ^^^ ------- ---------- --------
+ | ^^^ ----------
help: use a trailing comma to create a tuple with one element
|
LL | bar("hi", ("hi",), "hi");
diff --git a/src/test/ui/tuple/builtin-fail.rs b/src/test/ui/tuple/builtin-fail.rs
new file mode 100644
index 000000000..312080961
--- /dev/null
+++ b/src/test/ui/tuple/builtin-fail.rs
@@ -0,0 +1,19 @@
+#![feature(tuple_trait)]
+
+fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
+
+struct TupleStruct(i32, i32);
+
+fn from_param_env<T>() {
+ assert_is_tuple::<T>();
+ //~^ ERROR `T` is not a tuple
+}
+
+fn main() {
+ assert_is_tuple::<i32>();
+ //~^ ERROR `i32` is not a tuple
+ assert_is_tuple::<(i32)>();
+ //~^ ERROR `i32` is not a tuple
+ assert_is_tuple::<TupleStruct>();
+ //~^ ERROR `TupleStruct` is not a tuple
+}
diff --git a/src/test/ui/tuple/builtin-fail.stderr b/src/test/ui/tuple/builtin-fail.stderr
new file mode 100644
index 000000000..e3e29a73f
--- /dev/null
+++ b/src/test/ui/tuple/builtin-fail.stderr
@@ -0,0 +1,55 @@
+error[E0277]: `T` is not a tuple
+ --> $DIR/builtin-fail.rs:8:23
+ |
+LL | assert_is_tuple::<T>();
+ | ^ the trait `Tuple` is not implemented for `T`
+ |
+note: required by a bound in `assert_is_tuple`
+ --> $DIR/builtin-fail.rs:3:23
+ |
+LL | fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
+ | ^^^^^^^^^^^^^^^^^^ required by this bound in `assert_is_tuple`
+help: consider restricting type parameter `T`
+ |
+LL | fn from_param_env<T: std::marker::Tuple>() {
+ | ++++++++++++++++++++
+
+error[E0277]: `i32` is not a tuple
+ --> $DIR/builtin-fail.rs:13:23
+ |
+LL | assert_is_tuple::<i32>();
+ | ^^^ the trait `Tuple` is not implemented for `i32`
+ |
+note: required by a bound in `assert_is_tuple`
+ --> $DIR/builtin-fail.rs:3:23
+ |
+LL | fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
+ | ^^^^^^^^^^^^^^^^^^ required by this bound in `assert_is_tuple`
+
+error[E0277]: `i32` is not a tuple
+ --> $DIR/builtin-fail.rs:15:24
+ |
+LL | assert_is_tuple::<(i32)>();
+ | ^^^ the trait `Tuple` is not implemented for `i32`
+ |
+note: required by a bound in `assert_is_tuple`
+ --> $DIR/builtin-fail.rs:3:23
+ |
+LL | fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
+ | ^^^^^^^^^^^^^^^^^^ required by this bound in `assert_is_tuple`
+
+error[E0277]: `TupleStruct` is not a tuple
+ --> $DIR/builtin-fail.rs:17:23
+ |
+LL | assert_is_tuple::<TupleStruct>();
+ | ^^^^^^^^^^^ the trait `Tuple` is not implemented for `TupleStruct`
+ |
+note: required by a bound in `assert_is_tuple`
+ --> $DIR/builtin-fail.rs:3:23
+ |
+LL | fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
+ | ^^^^^^^^^^^^^^^^^^ required by this bound in `assert_is_tuple`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/tuple/builtin.rs b/src/test/ui/tuple/builtin.rs
new file mode 100644
index 000000000..d87ce5263
--- /dev/null
+++ b/src/test/ui/tuple/builtin.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+#![feature(tuple_trait)]
+
+fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
+
+struct Unsized([u8]);
+
+fn from_param_env<T: std::marker::Tuple + ?Sized>() {
+ assert_is_tuple::<T>();
+}
+
+fn main() {
+ assert_is_tuple::<()>();
+ assert_is_tuple::<(i32,)>();
+ assert_is_tuple::<(Unsized,)>();
+ from_param_env::<()>();
+ from_param_env::<(i32,)>();
+ from_param_env::<(Unsized,)>();
+}
diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr
index 2733fb314..f3a547fa2 100644
--- a/src/test/ui/tuple/wrong_argument_ice-3.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr
@@ -2,10 +2,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/wrong_argument_ice-3.rs:9:16
|
LL | groups.push(new_group, vec![process]);
- | ^^^^ --------- ------------- argument of type `Vec<&Process>` unexpected
- | |
- | expected tuple, found struct `Vec`
+ | ^^^^ ------------- argument of type `Vec<&Process>` unexpected
|
+note: expected tuple, found struct `Vec`
+ --> $DIR/wrong_argument_ice-3.rs:9:21
+ |
+LL | groups.push(new_group, vec![process]);
+ | ^^^^^^^^^
= note: expected tuple `(Vec<String>, Vec<Process>)`
found struct `Vec<String>`
note: associated function defined here
@@ -16,7 +19,7 @@ LL | pub fn push(&mut self, value: T) {
help: remove the extra argument
|
LL | groups.push(/* (Vec<String>, Vec<Process>) */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/tuple/wrong_argument_ice-4.stderr b/src/test/ui/tuple/wrong_argument_ice-4.stderr
index 828ae21b4..a2686ab94 100644
--- a/src/test/ui/tuple/wrong_argument_ice-4.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-4.stderr
@@ -16,7 +16,7 @@ LL | (|| {})(|| {
help: remove the extra argument
|
LL | (|| {})();
- | ~~~~~~~~~
+ | ~~
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
index 006253f84..eb58ee73c 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -12,7 +12,7 @@ LL | V(u8)
help: provide the argument
|
LL | <E>::V(/* u8 */);
- | ~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
diff --git a/src/test/ui/type-alias-impl-trait/closure_args.rs b/src/test/ui/type-alias-impl-trait/closure_args.rs
new file mode 100644
index 000000000..c5e7af81d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_args.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+// regression test for https://github.com/rust-lang/rust/issues/100800
+
+#![feature(type_alias_impl_trait)]
+
+trait Anything {}
+impl<T> Anything for T {}
+type Input = impl Anything;
+fn run<F: FnOnce(Input) -> ()>(f: F, i: Input) {
+ f(i);
+}
+
+fn main() {
+ run(|x: u32| {println!("{x}");}, 0);
+}
diff --git a/src/test/ui/type-alias-impl-trait/closure_args2.rs b/src/test/ui/type-alias-impl-trait/closure_args2.rs
new file mode 100644
index 000000000..82386c280
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_args2.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait Foo {
+ // This was reachable in https://github.com/rust-lang/rust/issues/100800
+ fn foo(&self) { unreachable!() }
+}
+impl<T> Foo for T {}
+
+struct B;
+impl B {
+ fn foo(&self) {}
+}
+
+type Input = impl Foo;
+fn run1<F: FnOnce(Input)>(f: F, i: Input) {f(i)}
+fn run2<F: FnOnce(B)>(f: F, i: B) {f(i)}
+
+fn main() {
+ run1(|x: B| {x.foo()}, B);
+ run2(|x: B| {x.foo()}, B);
+}
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs.rs b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
index c32174288..03fb64b7b 100644
--- a/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
@@ -1,17 +1,33 @@
-// check-pass
-
#![feature(type_alias_impl_trait)]
-mod foo {
+mod lifetime_params {
type Ty<'a> = impl Sized;
fn defining(s: &str) -> Ty<'_> { s }
fn execute(ty: Ty<'_>) -> &str { todo!() }
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+
+ type BadFnSig = fn(Ty<'_>) -> &str;
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+ type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
+ //~^ ERROR binding for associated type `Output` references an anonymous lifetime
}
-mod bar {
+mod lifetime_params_2 {
type Ty<'a> = impl FnOnce() -> &'a str;
fn defining(s: &str) -> Ty<'_> { move || s }
fn execute(ty: Ty<'_>) -> &str { ty() }
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+}
+
+// regression test for https://github.com/rust-lang/rust/issues/97104
+mod type_params {
+ type Ty<T> = impl Sized;
+ fn define<T>(s: T) -> Ty<T> { s }
+
+ type BadFnSig = fn(Ty<&str>) -> &str;
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+ type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
+ //~^ ERROR binding for associated type `Output` references an anonymous lifetime
}
fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs.stderr b/src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
new file mode 100644
index 000000000..93953fd06
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
@@ -0,0 +1,58 @@
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:6:31
+ |
+LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:9:35
+ |
+LL | type BadFnSig = fn(Ty<'_>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+ --> $DIR/constrain_inputs.rs:11:42
+ |
+LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:18:31
+ |
+LL | fn execute(ty: Ty<'_>) -> &str { ty() }
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:27:37
+ |
+LL | type BadFnSig = fn(Ty<&str>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+ --> $DIR/constrain_inputs.rs:29:44
+ |
+LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0581, E0582.
+For more information about an error, try `rustc --explain E0581`.
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
new file mode 100644
index 000000000..3bae0f173
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
@@ -0,0 +1,31 @@
+#![feature(type_alias_impl_trait)]
+
+trait Static: 'static {}
+impl Static for () {}
+
+type Gal<T> = impl Static;
+fn _defining<T>() -> Gal<T> {}
+
+trait Callable<Arg> { type Output; }
+
+/// We can infer `<C as Callable<Arg>>::Output: 'static`,
+/// because we know `C: 'static` and `Arg: 'static`,
+fn box_str<C, Arg>(s: C::Output) -> Box<dyn AsRef<str> + 'static>
+where
+ Arg: Static,
+ C: ?Sized + Callable<Arg> + 'static,
+ C::Output: AsRef<str>,
+{
+ Box::new(s)
+}
+
+fn extend_lifetime(s: &str) -> Box<dyn AsRef<str> + 'static> {
+ type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
+ //~^ ERROR binding for associated type `Output` references lifetime `'a`
+ box_str::<MalformedTy, _>(s)
+}
+
+fn main() {
+ let extended = extend_lifetime(&String::from("hello"));
+ println!("{}", extended.as_ref().as_ref());
+}
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
new file mode 100644
index 000000000..d5fc46cb1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
@@ -0,0 +1,9 @@
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/constrain_inputs_unsound.rs:23:58
+ |
+LL | type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
index 2768f0c3a..586ea8234 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (t, u)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(T, U)`
+ = note: required for `(T, U)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -16,7 +16,7 @@ error[E0277]: `U` doesn't implement `Debug`
LL | (t, u)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(T, U)`
+ = note: required for `(T, U)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
@@ -28,7 +28,7 @@ error[E0277]: `U` doesn't implement `Debug`
LL | (u, t)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+ = note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
@@ -40,7 +40,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (u, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+ = note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
index c1712ca2e..cb162d382 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (t, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(T, T)`
+ = note: required for `(T, T)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -16,7 +16,7 @@ error[E0277]: `U` doesn't implement `Debug`
LL | (u, t)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+ = note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
@@ -28,7 +28,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (u, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+ = note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
index b83105c45..14cbfb380 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (t, 4u32)
| ^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(T, u32)`
+ = note: required for `(T, u32)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -16,7 +16,7 @@ error[E0277]: `U` doesn't implement `Debug`
LL | (u, 4u32)
| ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(U, u32)`
+ = note: required for `(U, u32)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
index 50cf98273..722693e42 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
@@ -15,7 +15,7 @@ error[E0277]: `A` doesn't implement `Debug`
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
+ = note: required for `(A, B, _)` to implement `Debug`
help: consider restricting type parameter `A`
|
LL | type Two<A: std::fmt::Debug, B> = impl Debug;
@@ -27,7 +27,7 @@ error[E0277]: `B` doesn't implement `Debug`
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
+ = note: required for `(A, B, _)` to implement `Debug`
help: consider restricting type parameter `B`
|
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
@@ -39,7 +39,7 @@ error[E0277]: `A` doesn't implement `Debug`
LL | (t, u, 42)
| ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
+ = note: required for `(A, B, i32)` to implement `Debug`
help: consider restricting type parameter `A`
|
LL | type Two<A: std::fmt::Debug, B> = impl Debug;
@@ -51,7 +51,7 @@ error[E0277]: `B` doesn't implement `Debug`
LL | (t, u, 42)
| ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
+ = note: required for `(A, B, i32)` to implement `Debug`
help: consider restricting type parameter `B`
|
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.rs b/src/test/ui/type-alias-impl-trait/issue-57961.rs
index 472886c9c..24b3a0458 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57961.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57961.rs
@@ -8,7 +8,7 @@ trait Foo {
impl Foo for () {
type Bar = std::vec::IntoIter<u32>;
- //~^ ERROR type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X
+ //~^ ERROR expected `std::vec::IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
}
fn incoherent() {
diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.stderr b/src/test/ui/type-alias-impl-trait/issue-57961.stderr
index ed4caf6ce..fb40895c4 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57961.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57961.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X`
+error[E0271]: expected `std::vec::IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
--> $DIR/issue-57961.rs:10:16
|
LL | type X = impl Sized;
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
index 082b0f0c3..d0c04371b 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
@@ -11,7 +11,7 @@ error[E0277]: the trait bound `(): Bug` is not satisfied
--> $DIR/issue-60371.rs:10:40
|
LL | const FUN: fn() -> Self::Item = || ();
- | ^ the trait `Bug` is not implemented for `()`
+ | ^^ the trait `Bug` is not implemented for `()`
|
= help: the trait `Bug` is implemented for `&()`
diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
index 5ed29e0ac..66886db6e 100644
--- a/src/test/ui/type-alias-impl-trait/issue-74280.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-74280.rs:9:5
|
LL | fn test() -> Test {
- | ---- expected `_` because of return type
+ | ---- expected `()` because of return type
LL | let y = || -> Test { () };
LL | 7
| ^ expected `()`, found integer
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-1.rs b/src/test/ui/type-alias-impl-trait/issue-90400-1.rs
index 8550a3e86..15aead2f6 100644
--- a/src/test/ui/type-alias-impl-trait/issue-90400-1.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-1.rs
@@ -1,7 +1,6 @@
// Regression test for #90400,
// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836
-#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
trait Bar {
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr
index 428a10740..ead28769f 100644
--- a/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `B: Bar` is not satisfied
- --> $DIR/issue-90400-1.rs:23:9
+ --> $DIR/issue-90400-1.rs:22:9
|
LL | move || bar.bar()
| ^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
|
note: required by a bound in `<MyFoo as Foo>::foo`
- --> $DIR/issue-90400-1.rs:22:15
+ --> $DIR/issue-90400-1.rs:21:15
|
LL | fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> {
| ^^^ required by this bound in `<MyFoo as Foo>::foo`
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.rs b/src/test/ui/type-alias-impl-trait/issue-90400-2.rs
index 2b369bb8a..4c6e893c1 100644
--- a/src/test/ui/type-alias-impl-trait/issue-90400-2.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.rs
@@ -1,7 +1,6 @@
// Regression test for #90400,
// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836
-#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
trait Bar {
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
index 5da05a439..50b2dc049 100644
--- a/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `B: Bar` is not satisfied
- --> $DIR/issue-90400-2.rs:26:9
+ --> $DIR/issue-90400-2.rs:25:9
|
LL | MyBaz(bar)
| ^^^^^^^^^^ the trait `Bar` is not implemented for `B`
|
-note: required because of the requirements on the impl of `Baz` for `MyBaz<B>`
- --> $DIR/issue-90400-2.rs:31:14
+note: required for `MyBaz<B>` to implement `Baz`
+ --> $DIR/issue-90400-2.rs:30:14
|
LL | impl<B: Bar> Baz for MyBaz<B> {
| ^^^ ^^^^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/issue-98604.rs b/src/test/ui/type-alias-impl-trait/issue-98604.rs
index a4fd8a82a..32c2f9ed5 100644
--- a/src/test/ui/type-alias-impl-trait/issue-98604.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-98604.rs
@@ -1,13 +1,11 @@
// edition:2018
-type AsyncFnPtr = Box<
- dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>,
->;
+type AsyncFnPtr = Box<dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>>;
async fn test() {}
#[allow(unused_must_use)]
fn main() {
Box::new(test) as AsyncFnPtr;
- //~^ ERROR type mismatch
+ //~^ ERROR expected `fn() -> impl Future<Output = ()> {test}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
}
diff --git a/src/test/ui/type-alias-impl-trait/issue-98604.stderr b/src/test/ui/type-alias-impl-trait/issue-98604.stderr
index f04d1b4d7..92d01eb0d 100644
--- a/src/test/ui/type-alias-impl-trait/issue-98604.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-98604.stderr
@@ -1,11 +1,11 @@
-error[E0271]: type mismatch resolving `<fn() -> impl Future<Output = ()> {test} as FnOnce<()>>::Output == Pin<Box<(dyn Future<Output = ()> + 'static)>>`
- --> $DIR/issue-98604.rs:11:5
+error[E0271]: expected `fn() -> impl Future<Output = ()> {test}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+ --> $DIR/issue-98604.rs:9:5
|
LL | Box::new(test) as AsyncFnPtr;
| ^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
|
note: while checking the return type of the `async fn`
- --> $DIR/issue-98604.rs:7:17
+ --> $DIR/issue-98604.rs:5:17
|
LL | async fn test() {}
| ^ checked the `Output` of this `async fn`, found opaque type
diff --git a/src/test/ui/type-alias-impl-trait/issue-98608.rs b/src/test/ui/type-alias-impl-trait/issue-98608.rs
index d75762a8b..1f89af045 100644
--- a/src/test/ui/type-alias-impl-trait/issue-98608.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-98608.rs
@@ -1,8 +1,10 @@
-fn hi() -> impl Sized { std::ptr::null::<u8>() }
+fn hi() -> impl Sized {
+ std::ptr::null::<u8>()
+}
fn main() {
let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
- //~^ ERROR type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
+ //~^ ERROR expected `fn() -> impl Sized {hi}` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
let boxed = b();
let null = *boxed;
println!("{null:?}");
diff --git a/src/test/ui/type-alias-impl-trait/issue-98608.stderr b/src/test/ui/type-alias-impl-trait/issue-98608.stderr
index 8f3ec7d9d..916a58451 100644
--- a/src/test/ui/type-alias-impl-trait/issue-98608.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-98608.stderr
@@ -1,7 +1,7 @@
-error[E0271]: type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
- --> $DIR/issue-98608.rs:4:39
+error[E0271]: expected `fn() -> impl Sized {hi}` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
+ --> $DIR/issue-98608.rs:6:39
|
-LL | fn hi() -> impl Sized { std::ptr::null::<u8>() }
+LL | fn hi() -> impl Sized {
| ---------- the found opaque type
...
LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
index cdaae99e2..66a6b0bbf 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied
LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
| ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B`
|
- = note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
+ = note: required for `&A` to implement `Into<&'static B>`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
index a5ac38c38..b11198c58 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (t, 5i8)
| ^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(T, i8)`
+ = note: required for `(T, i8)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -27,7 +27,7 @@ error[E0277]: `T` doesn't implement `Debug`
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
- = note: required because of the requirements on the impl of `Debug` for `(T, _)`
+ = note: required for `(T, _)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
index e70916573..95fb6f6a5 100644
--- a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `T: Trait` is not satisfied
LL | ()
| ^^ the trait `Trait` is not implemented for `T`
|
-note: required because of the requirements on the impl of `ProofForConversion<T>` for `()`
+note: required for `()` to implement `ProofForConversion<T>`
--> $DIR/underconstrained_generic.rs:13:16
|
LL | impl<X: Trait> ProofForConversion<X> for () {
diff --git a/src/test/ui/type/issue-100584.rs b/src/test/ui/type/issue-100584.rs
new file mode 100644
index 000000000..102846563
--- /dev/null
+++ b/src/test/ui/type/issue-100584.rs
@@ -0,0 +1,15 @@
+#![deny(unused)]
+fn foo(xyza: &str) {
+//~^ ERROR unused variable: `xyza`
+ let _ = "{xyza}";
+}
+
+fn foo3(xyza: &str) {
+//~^ ERROR unused variable: `xyza`
+ let _ = "aaa{xyza}bbb";
+}
+
+fn main() {
+ foo("x");
+ foo3("xx");
+}
diff --git a/src/test/ui/type/issue-100584.stderr b/src/test/ui/type/issue-100584.stderr
new file mode 100644
index 000000000..e1db14d1f
--- /dev/null
+++ b/src/test/ui/type/issue-100584.stderr
@@ -0,0 +1,44 @@
+error: unused variable: `xyza`
+ --> $DIR/issue-100584.rs:2:8
+ |
+LL | fn foo(xyza: &str) {
+ | ^^^^ unused variable
+LL |
+LL | let _ = "{xyza}";
+ | -------- you might have meant to use string interpolation in this string literal
+ |
+note: the lint level is defined here
+ --> $DIR/issue-100584.rs:1:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+help: string interpolation only works in `format!` invocations
+ |
+LL | let _ = format!("{xyza}");
+ | ++++++++ +
+help: if this is intentional, prefix it with an underscore
+ |
+LL | fn foo(_xyza: &str) {
+ | ~~~~~
+
+error: unused variable: `xyza`
+ --> $DIR/issue-100584.rs:7:9
+ |
+LL | fn foo3(xyza: &str) {
+ | ^^^^ unused variable
+LL |
+LL | let _ = "aaa{xyza}bbb";
+ | -------------- you might have meant to use string interpolation in this string literal
+ |
+help: string interpolation only works in `format!` invocations
+ |
+LL | let _ = format!("aaa{xyza}bbb");
+ | ++++++++ +
+help: if this is intentional, prefix it with an underscore
+ |
+LL | fn foo3(_xyza: &str) {
+ | ~~~~~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs
index 65b79650d..e49731725 100644
--- a/src/test/ui/type/type-alias-bounds.rs
+++ b/src/test/ui/type/type-alias-bounds.rs
@@ -52,7 +52,7 @@ type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases
// Do this instead:
type T4<U> = <U as Bound>::Assoc;
-// Make sure the help about associatd types is not shown incorrectly
+// Make sure the help about associated types is not shown incorrectly
type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN not enforced in type aliases
type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN not enforced in type aliases
diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr
index 0b6283fbc..7f18b4510 100644
--- a/src/test/ui/type/type-arg-out-of-scope.stderr
+++ b/src/test/ui/type/type-arg-out-of-scope.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
LL | fn foo<T>(x: T) {
| - type parameter from outer function
LL | fn bar(f: Box<dyn FnMut(T) -> T>) { }
- | --- ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `bar<T>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<T>`
error[E0401]: can't use generic parameters from outer function
--> $DIR/type-arg-out-of-scope.rs:3:35
@@ -14,9 +14,9 @@ error[E0401]: can't use generic parameters from outer function
LL | fn foo<T>(x: T) {
| - type parameter from outer function
LL | fn bar(f: Box<dyn FnMut(T) -> T>) { }
- | --- ^ use of generic parameter from outer function
- | |
- | help: try using a local generic parameter instead: `bar<T>`
+ | - ^ use of generic parameter from outer function
+ | |
+ | help: try using a local generic parameter instead: `<T>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
index fcac6c495..de578ca93 100644
--- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
@@ -21,7 +21,7 @@ LL | pub fn with_capacity(capacity: usize) -> Self {
help: remove the extra argument
|
LL | let x: Vec::with_capacity(10);
- | ~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr
index 56a9b5317..cf77c057d 100644
--- a/src/test/ui/type/type-check-defaults.stderr
+++ b/src/test/ui/type/type-check-defaults.stderr
@@ -1,8 +1,8 @@
error[E0277]: a value of type `i32` cannot be built from an iterator over elements of type `i32`
- --> $DIR/type-check-defaults.rs:6:19
+ --> $DIR/type-check-defaults.rs:6:23
|
LL | struct WellFormed<Z = Foo<i32, i32>>(Z);
- | ^^^^^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
+ | ^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
|
= help: the trait `FromIterator<i32>` is not implemented for `i32`
note: required by a bound in `Foo`
@@ -12,10 +12,10 @@ LL | struct Foo<T, U: FromIterator<T>>(T, U);
| ^^^^^^^^^^^^^^^ required by this bound in `Foo`
error[E0277]: a value of type `i32` cannot be built from an iterator over elements of type `i32`
- --> $DIR/type-check-defaults.rs:8:27
+ --> $DIR/type-check-defaults.rs:8:38
|
LL | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
- | ^^^^^^^^^^^^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
+ | ^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
|
= help: the trait `FromIterator<i32>` is not implemented for `i32`
note: required by a bound in `Foo`
diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
index 615fd2ccb..847bc517e 100644
--- a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
+++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
@@ -1,13 +1,13 @@
error: function can not have more than 65535 arguments
- --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24
+ --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:22
|
-LL | fn _f($($t: ()),*) {}
- | ________________________^
-LL | | }
-LL | | }
-LL | |
-LL | | many_args!{[_]########## ######}
- | |____________^
+LL | fn _f($($t: ()),*) {}
+ | ^
+...
+LL | many_args!{[_]########## ######}
+ | -------------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `many_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr
index 53610985f..220b3929c 100644
--- a/src/test/ui/type/type-params-in-different-spaces-2.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
- --> $DIR/type-params-in-different-spaces-2.rs:10:9
+ --> $DIR/type-params-in-different-spaces-2.rs:10:16
|
LL | Tr::op(u)
- | ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
+ | ------ ^ the trait `Tr<U>` is not implemented for `Self`
+ | |
+ | required by a bound introduced by this call
|
help: consider further restricting `Self`
|
@@ -10,10 +12,12 @@ LL | fn test<U>(u: U) -> Self where Self: Tr<U> {
| +++++++++++++++++
error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
- --> $DIR/type-params-in-different-spaces-2.rs:16:9
+ --> $DIR/type-params-in-different-spaces-2.rs:16:16
|
LL | Tr::op(u)
- | ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
+ | ------ ^ the trait `Tr<U>` is not implemented for `Self`
+ | |
+ | required by a bound introduced by this call
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr
index 1508b84c1..84ac48b1e 100644
--- a/src/test/ui/type_length_limit.stderr
+++ b/src/test/ui/type_length_limit.stderr
@@ -4,8 +4,8 @@ error: reached the type-length limit while instantiating `std::mem::drop::<Optio
LL | pub fn drop<T>(_x: T) {}
| ^^^^^^^^^^^^^^^^^^^^^
|
- = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
= help: consider adding a `#![type_length_limit="8"]` attribute to your crate
+ = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
@@ -13,8 +13,8 @@ error: reached the type-length limit while instantiating `<[closure@std::rt::lan
LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
= help: consider adding a `#![type_length_limit="8"]` attribute to your crate
+ = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
error: aborting due to 2 previous errors
diff --git a/src/test/ui/typeck/assign-non-lval-derefmut.stderr b/src/test/ui/typeck/assign-non-lval-derefmut.stderr
index a6fcdfe21..e394cf820 100644
--- a/src/test/ui/typeck/assign-non-lval-derefmut.stderr
+++ b/src/test/ui/typeck/assign-non-lval-derefmut.stderr
@@ -19,7 +19,7 @@ LL | x.lock().unwrap() += 1;
| |
| cannot use `+=` on type `MutexGuard<'_, usize>`
|
-help: `+=` can be used on `usize`, you can dereference `x.lock().unwrap()`
+help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *x.lock().unwrap() += 1;
| +
@@ -47,7 +47,7 @@ LL | y += 1;
| |
| cannot use `+=` on type `MutexGuard<'_, usize>`
|
-help: `+=` can be used on `usize`, you can dereference `y`
+help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *y += 1;
| +
diff --git a/src/test/ui/typeck/assign-non-lval-mut-ref.stderr b/src/test/ui/typeck/assign-non-lval-mut-ref.stderr
index be2e9fe95..cbdc960ba 100644
--- a/src/test/ui/typeck/assign-non-lval-mut-ref.stderr
+++ b/src/test/ui/typeck/assign-non-lval-mut-ref.stderr
@@ -19,7 +19,7 @@ LL | x.last_mut().unwrap() += 1;
| |
| cannot use `+=` on type `&mut usize`
|
-help: `+=` can be used on `usize`, you can dereference `x.last_mut().unwrap()`
+help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *x.last_mut().unwrap() += 1;
| +
@@ -45,7 +45,7 @@ LL | y += 1;
| |
| cannot use `+=` on type `&mut usize`
|
-help: `+=` can be used on `usize`, you can dereference `y`
+help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *y += 1;
| +
diff --git a/src/test/ui/typeck/assign-non-lval-needs-deref.rs b/src/test/ui/typeck/assign-non-lval-needs-deref.rs
new file mode 100644
index 000000000..c979d76b4
--- /dev/null
+++ b/src/test/ui/typeck/assign-non-lval-needs-deref.rs
@@ -0,0 +1,19 @@
+// issue #101376
+
+use std::ops::AddAssign;
+struct Foo;
+
+impl AddAssign<()> for Foo {
+ fn add_assign(&mut self, _: ()) {}
+}
+
+impl AddAssign<()> for &mut Foo {
+ fn add_assign(&mut self, _: ()) {}
+}
+
+fn main() {
+ (&mut Foo) += ();
+ //~^ ERROR invalid left-hand side of assignment
+ //~| NOTE cannot assign to this expression
+ //~| HELP consider dereferencing the left-hand side of this operation
+}
diff --git a/src/test/ui/typeck/assign-non-lval-needs-deref.stderr b/src/test/ui/typeck/assign-non-lval-needs-deref.stderr
new file mode 100644
index 000000000..ee83b1453
--- /dev/null
+++ b/src/test/ui/typeck/assign-non-lval-needs-deref.stderr
@@ -0,0 +1,16 @@
+error[E0067]: invalid left-hand side of assignment
+ --> $DIR/assign-non-lval-needs-deref.rs:15:16
+ |
+LL | (&mut Foo) += ();
+ | ---------- ^^
+ | |
+ | cannot assign to this expression
+ |
+help: consider dereferencing the left-hand side of this operation
+ |
+LL | *(&mut Foo) += ();
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0067`.
diff --git a/src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs b/src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs
new file mode 100644
index 000000000..97e0b213f
--- /dev/null
+++ b/src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.rs
@@ -0,0 +1,8 @@
+trait Foo {
+ const A; //~ ERROR missing type for `const` item
+ static B;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR missing type for `static` item
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr b/src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr
new file mode 100644
index 000000000..8982d6285
--- /dev/null
+++ b/src/test/ui/typeck/do-not-suggest-placeholder-to-const-static-without-type.stderr
@@ -0,0 +1,20 @@
+error: associated `static` items are not allowed
+ --> $DIR/do-not-suggest-placeholder-to-const-static-without-type.rs:3:5
+ |
+LL | static B;
+ | ^^^^^^^^^
+
+error: missing type for `const` item
+ --> $DIR/do-not-suggest-placeholder-to-const-static-without-type.rs:2:12
+ |
+LL | const A;
+ | ^ help: provide a type for the item: `: <type>`
+
+error: missing type for `static` item
+ --> $DIR/do-not-suggest-placeholder-to-const-static-without-type.rs:3:13
+ |
+LL | static B;
+ | ^ help: provide a type for the item: `: <type>`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/typeck/issue-100164.fixed b/src/test/ui/typeck/issue-100164.fixed
new file mode 100644
index 000000000..a5f68beb1
--- /dev/null
+++ b/src/test/ui/typeck/issue-100164.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+const _A: i32 = 123;
+//~^ ERROR: missing type for `const` item
+
+fn main() {
+ const _B: i32 = 123;
+ //~^ ERROR: missing type for `const` item
+}
diff --git a/src/test/ui/typeck/issue-100164.rs b/src/test/ui/typeck/issue-100164.rs
new file mode 100644
index 000000000..7efb9ac62
--- /dev/null
+++ b/src/test/ui/typeck/issue-100164.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+const _A: = 123;
+//~^ ERROR: missing type for `const` item
+
+fn main() {
+ const _B: = 123;
+ //~^ ERROR: missing type for `const` item
+}
diff --git a/src/test/ui/typeck/issue-100164.stderr b/src/test/ui/typeck/issue-100164.stderr
new file mode 100644
index 000000000..06a132d65
--- /dev/null
+++ b/src/test/ui/typeck/issue-100164.stderr
@@ -0,0 +1,14 @@
+error: missing type for `const` item
+ --> $DIR/issue-100164.rs:3:10
+ |
+LL | const _A: = 123;
+ | ^ help: provide a type for the constant: `i32`
+
+error: missing type for `const` item
+ --> $DIR/issue-100164.rs:7:14
+ |
+LL | const _B: = 123;
+ | ^ help: provide a type for the constant: `i32`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/typeck/issue-100246.rs b/src/test/ui/typeck/issue-100246.rs
new file mode 100644
index 000000000..8f0b34bab
--- /dev/null
+++ b/src/test/ui/typeck/issue-100246.rs
@@ -0,0 +1,30 @@
+#![recursion_limit = "5"] // To reduce noise
+
+//expect incompatible type error when ambiguous traits are in scope
+//and not an overflow error on the span in the main function.
+
+struct Ratio<T>(T);
+
+pub trait Pow {
+ fn pow(self) -> Self;
+}
+
+impl<'a, T> Pow for &'a Ratio<T>
+where
+ &'a T: Pow,
+{
+ fn pow(self) -> Self {
+ self
+ }
+}
+
+fn downcast<'a, W: ?Sized>() -> std::io::Result<&'a W> {
+ todo!()
+}
+
+struct Other;
+
+fn main() -> std::io::Result<()> {
+ let other: Other = downcast()?;//~ERROR 28:24: 28:35: `?` operator has incompatible types
+ Ok(())
+}
diff --git a/src/test/ui/typeck/issue-100246.stderr b/src/test/ui/typeck/issue-100246.stderr
new file mode 100644
index 000000000..8b77de94e
--- /dev/null
+++ b/src/test/ui/typeck/issue-100246.stderr
@@ -0,0 +1,13 @@
+error[E0308]: `?` operator has incompatible types
+ --> $DIR/issue-100246.rs:28:24
+ |
+LL | let other: Other = downcast()?;
+ | ^^^^^^^^^^^ expected struct `Other`, found reference
+ |
+ = note: `?` operator cannot convert from `&_` to `Other`
+ = note: expected struct `Other`
+ found reference `&_`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/issue-100285.rs b/src/test/ui/typeck/issue-100285.rs
new file mode 100644
index 000000000..e206469b8
--- /dev/null
+++ b/src/test/ui/typeck/issue-100285.rs
@@ -0,0 +1,22 @@
+fn foo(n: i32) -> i32 {
+ for i in 0..0 {
+ //~^ ERROR: mismatched types [E0308]
+ if n < 0 {
+ return i;
+ } else if n < 10 {
+ return 1;
+ } else if n < 20 {
+ return 2;
+ } else if n < 30 {
+ return 3;
+ } else if n < 40 {
+ return 4;
+ } else {
+ return 5;
+ }
+
+ }
+ //~| help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-100285.stderr b/src/test/ui/typeck/issue-100285.stderr
new file mode 100644
index 000000000..42c64b039
--- /dev/null
+++ b/src/test/ui/typeck/issue-100285.stderr
@@ -0,0 +1,34 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-100285.rs:2:5
+ |
+LL | fn foo(n: i32) -> i32 {
+ | --- expected `i32` because of return type
+LL | / for i in 0..0 {
+LL | |
+LL | | if n < 0 {
+LL | | return i;
+... |
+LL | |
+LL | | }
+ | |_____^ expected `i32`, found `()`
+ |
+note: the function expects a value to always be returned, but loops might run zero times
+ --> $DIR/issue-100285.rs:2:5
+ |
+LL | for i in 0..0 {
+ | ^^^^^^^^^^^^^ this might have zero elements to iterate on
+...
+LL | return i;
+ | -------- if the loop doesn't execute, this value would never get returned
+LL | } else if n < 10 {
+LL | return 1;
+ | -------- if the loop doesn't execute, this value would never get returned
+LL | } else if n < 20 {
+LL | return 2;
+ | -------- if the loop doesn't execute, this value would never get returned
+ = note: if the loop doesn't execute, 3 other values would never get returned
+ = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/issue-29124.stderr b/src/test/ui/typeck/issue-29124.stderr
index c5d2ec084..a837a7d2d 100644
--- a/src/test/ui/typeck/issue-29124.stderr
+++ b/src/test/ui/typeck/issue-29124.stderr
@@ -2,17 +2,13 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in
--> $DIR/issue-29124.rs:15:15
|
LL | Obj::func.x();
- | --------- ^ method not found in `fn() -> Ret {Obj::func}`
- | |
- | this is a function, perhaps you wish to call it
+ | ^ method not found in `fn() -> Ret {Obj::func}`
error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope
--> $DIR/issue-29124.rs:17:10
|
LL | func.x();
- | ---- ^ method not found in `fn() -> Ret {func}`
- | |
- | this is a function, perhaps you wish to call it
+ | ^ method not found in `fn() -> Ret {func}`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/typeck/issue-79040.stderr b/src/test/ui/typeck/issue-79040.stderr
index aec2e1ec9..c820d1e08 100644
--- a/src/test/ui/typeck/issue-79040.stderr
+++ b/src/test/ui/typeck/issue-79040.stderr
@@ -7,10 +7,10 @@ LL | const FOO = "hello" + 1;
| &str
error: missing type for `const` item
- --> $DIR/issue-79040.rs:2:11
+ --> $DIR/issue-79040.rs:2:14
|
LL | const FOO = "hello" + 1;
- | ^^^ help: provide a type for the item: `FOO: <type>`
+ | ^ help: provide a type for the item: `: <type>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.rs b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs
index 1875d8280..be68ad32a 100644
--- a/src/test/ui/typeck/issue-87181/empty-tuple-method.rs
+++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs
@@ -4,7 +4,7 @@ struct Bar<T> {
struct Foo();
impl Foo {
- fn foo() { }
+ fn foo(&self) { }
}
fn main() {
diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
index 6ed70b301..a18c54a29 100644
--- a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
+++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
@@ -2,11 +2,9 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the
--> $DIR/empty-tuple-method.rs:12:15
|
LL | thing.bar.foo();
- | --------- ^^^ method not found in `fn() -> Foo {Foo}`
- | |
- | this is the constructor of a struct
+ | ^^^ method not found in `fn() -> Foo {Foo}`
|
-help: call the constructor
+help: use parentheses to instantiate this tuple struct
|
LL | (thing.bar)().foo();
| + +++
diff --git a/src/test/ui/typeck/issue-87181/enum-variant.rs b/src/test/ui/typeck/issue-87181/enum-variant.rs
index 3b926b90f..d87f99c3c 100644
--- a/src/test/ui/typeck/issue-87181/enum-variant.rs
+++ b/src/test/ui/typeck/issue-87181/enum-variant.rs
@@ -6,7 +6,7 @@ enum Foo{
Tup()
}
impl Foo {
- fn foo() { }
+ fn foo(&self) { }
}
fn main() {
diff --git a/src/test/ui/typeck/issue-87181/enum-variant.stderr b/src/test/ui/typeck/issue-87181/enum-variant.stderr
index a3a818696..90641410d 100644
--- a/src/test/ui/typeck/issue-87181/enum-variant.stderr
+++ b/src/test/ui/typeck/issue-87181/enum-variant.stderr
@@ -2,11 +2,9 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` i
--> $DIR/enum-variant.rs:14:15
|
LL | thing.bar.foo();
- | --------- ^^^ method not found in `fn() -> Foo {Foo::Tup}`
- | |
- | this is the constructor of an enum variant
+ | ^^^ method not found in `fn() -> Foo {Foo::Tup}`
|
-help: call the constructor
+help: use parentheses to instantiate this tuple variant
|
LL | (thing.bar)().foo();
| + +++
diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr
index 4d22ada02..c1ca26ee9 100644
--- a/src/test/ui/typeck/issue-87181/tuple-field.stderr
+++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr
@@ -2,14 +2,12 @@ error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}`
--> $DIR/tuple-field.rs:12:15
|
LL | thing.bar.0;
- | --------- ^
- | |
- | this is the constructor of a struct
+ | ^
|
-help: call the constructor
+help: use parentheses to instantiate this tuple struct
|
-LL | (thing.bar)(_, _).0;
- | + +++++++
+LL | (thing.bar)(/* char */, /* u16 */).0;
+ | + ++++++++++++++++++++++++
error: aborting due to previous error
diff --git a/src/test/ui/typeck/issue-87181/tuple-method.stderr b/src/test/ui/typeck/issue-87181/tuple-method.stderr
index 1e392e179..e27c41858 100644
--- a/src/test/ui/typeck/issue-87181/tuple-method.stderr
+++ b/src/test/ui/typeck/issue-87181/tuple-method.stderr
@@ -2,14 +2,7 @@ error[E0599]: no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}`
--> $DIR/tuple-method.rs:12:15
|
LL | thing.bar.foo();
- | --------- ^^^ method not found in `fn(u8, i32) -> Foo {Foo}`
- | |
- | this is the constructor of a struct
- |
-help: call the constructor
- |
-LL | (thing.bar)(_, _).foo();
- | + +++++++
+ | ^^^ method not found in `fn(u8, i32) -> Foo {Foo}`
error: aborting due to previous error
diff --git a/src/test/ui/typeck/issue-90101.stderr b/src/test/ui/typeck/issue-90101.stderr
index ab9a72edf..d2729d853 100644
--- a/src/test/ui/typeck/issue-90101.stderr
+++ b/src/test/ui/typeck/issue-90101.stderr
@@ -12,7 +12,7 @@ LL | func(Path::new("hello").to_path_buf().to_string_lossy(), "world")
<PathBuf as From<Cow<'a, Path>>>
<PathBuf as From<OsString>>
<PathBuf as From<String>>
- = note: required because of the requirements on the impl of `Into<PathBuf>` for `Cow<'_, str>`
+ = note: required for `Cow<'_, str>` to implement `Into<PathBuf>`
note: required by a bound in `func`
--> $DIR/issue-90101.rs:3:20
|
diff --git a/src/test/ui/typeck/issue-91210-ptr-method.stderr b/src/test/ui/typeck/issue-91210-ptr-method.stderr
index 503a32373..7a0cfb2cf 100644
--- a/src/test/ui/typeck/issue-91210-ptr-method.stderr
+++ b/src/test/ui/typeck/issue-91210-ptr-method.stderr
@@ -2,9 +2,12 @@ error[E0615]: attempted to take value of method `read` on type `*mut Foo`
--> $DIR/issue-91210-ptr-method.rs:10:7
|
LL | x.read = 4;
- | - ^^^^ method, not a field
- | |
- | help: to access the field, dereference first: `(*x)`
+ | ^^^^ method, not a field
+ |
+help: to access the field, dereference first
+ |
+LL | (*x).read = 4;
+ | ++ +
error: aborting due to previous error
diff --git a/src/test/ui/typeck/issue-91633.rs b/src/test/ui/typeck/issue-91633.rs
new file mode 100644
index 000000000..331a798dd
--- /dev/null
+++ b/src/test/ui/typeck/issue-91633.rs
@@ -0,0 +1,8 @@
+// check-pass
+fn f<T> (it: &[T])
+where
+ [T] : std::ops::Index<usize>,
+{
+ let _ = &it[0];
+}
+fn main(){}
diff --git a/src/test/ui/typeck/issue-96738.stderr b/src/test/ui/typeck/issue-96738.stderr
index 32f538498..0d4d87ef4 100644
--- a/src/test/ui/typeck/issue-96738.stderr
+++ b/src/test/ui/typeck/issue-96738.stderr
@@ -2,27 +2,13 @@ error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> O
--> $DIR/issue-96738.rs:2:10
|
LL | Some.nonexistent_method();
- | ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
- | |
- | this is the constructor of an enum variant
- |
-help: call the constructor
- |
-LL | (Some)(_).nonexistent_method();
- | + ++++
+ | ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}`
error[E0609]: no field `nonexistent_field` on type `fn(_) -> Option<_> {Option::<_>::Some}`
--> $DIR/issue-96738.rs:3:10
|
LL | Some.nonexistent_field;
- | ---- ^^^^^^^^^^^^^^^^^
- | |
- | this is the constructor of an enum variant
- |
-help: call the constructor
- |
-LL | (Some)(_).nonexistent_field;
- | + ++++
+ | ^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/typeck/issue-98982.rs b/src/test/ui/typeck/issue-98982.rs
new file mode 100644
index 000000000..2553824bb
--- /dev/null
+++ b/src/test/ui/typeck/issue-98982.rs
@@ -0,0 +1,9 @@
+fn foo() -> i32 {
+ for i in 0..0 {
+ //~^ ERROR: mismatched types [E0308]
+ return i;
+ }
+ //~| help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-98982.stderr b/src/test/ui/typeck/issue-98982.stderr
new file mode 100644
index 000000000..3c9806ac9
--- /dev/null
+++ b/src/test/ui/typeck/issue-98982.stderr
@@ -0,0 +1,24 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-98982.rs:2:5
+ |
+LL | fn foo() -> i32 {
+ | --- expected `i32` because of return type
+LL | / for i in 0..0 {
+LL | |
+LL | | return i;
+LL | | }
+ | |_____^ expected `i32`, found `()`
+ |
+note: the function expects a value to always be returned, but loops might run zero times
+ --> $DIR/issue-98982.rs:2:5
+ |
+LL | for i in 0..0 {
+ | ^^^^^^^^^^^^^ this might have zero elements to iterate on
+LL |
+LL | return i;
+ | -------- if the loop doesn't execute, this value would never get returned
+ = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/point-at-type-param-in-path-expr.rs b/src/test/ui/typeck/point-at-type-param-in-path-expr.rs
new file mode 100644
index 000000000..9a21536f9
--- /dev/null
+++ b/src/test/ui/typeck/point-at-type-param-in-path-expr.rs
@@ -0,0 +1,6 @@
+fn foo<T: std::fmt::Display>() {}
+
+fn main() {
+ let x = foo::<()>;
+ //~^ ERROR `()` doesn't implement `std::fmt::Display`
+}
diff --git a/src/test/ui/typeck/point-at-type-param-in-path-expr.stderr b/src/test/ui/typeck/point-at-type-param-in-path-expr.stderr
new file mode 100644
index 000000000..1feaa0508
--- /dev/null
+++ b/src/test/ui/typeck/point-at-type-param-in-path-expr.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `()` doesn't implement `std::fmt::Display`
+ --> $DIR/point-at-type-param-in-path-expr.rs:4:19
+ |
+LL | let x = foo::<()>;
+ | ^^ `()` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `()`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `foo`
+ --> $DIR/point-at-type-param-in-path-expr.rs:1:11
+ |
+LL | fn foo<T: std::fmt::Display>() {}
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/typeck/remove-extra-argument.stderr b/src/test/ui/typeck/remove-extra-argument.stderr
index 703032a83..b734bcd4e 100644
--- a/src/test/ui/typeck/remove-extra-argument.stderr
+++ b/src/test/ui/typeck/remove-extra-argument.stderr
@@ -12,7 +12,7 @@ LL | fn l(_a: Vec<u8>) {}
help: remove the extra argument
|
LL | l(vec![])
- |
+ | ~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr
index f72082d53..ea94bcbc2 100644
--- a/src/test/ui/typeck/struct-enum-wrong-args.stderr
+++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr
@@ -12,7 +12,7 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
help: remove the extra argument
|
LL | let _ = Some(3);
- | ~~~~~~~
+ | ~~~
error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:7:13
@@ -30,7 +30,7 @@ LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
help: remove the extra arguments
|
LL | let _ = Ok(3);
- | ~~~~~
+ | ~~~
error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:8:13
@@ -46,7 +46,7 @@ LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
help: provide the argument
|
LL | let _ = Ok(/* value */);
- | ~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~
error[E0061]: this struct takes 1 argument but 0 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:9:13
@@ -62,7 +62,7 @@ LL | struct Wrapper(i32);
help: provide the argument
|
LL | let _ = Wrapper(/* i32 */);
- | ~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~
error[E0061]: this struct takes 1 argument but 2 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:10:13
@@ -78,7 +78,7 @@ LL | struct Wrapper(i32);
help: remove the extra argument
|
LL | let _ = Wrapper(5);
- | ~~~~~~~~~~
+ | ~~~
error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:11:13
@@ -94,7 +94,7 @@ LL | struct DoubleWrapper(i32, i32);
help: provide the arguments
|
LL | let _ = DoubleWrapper(/* i32 */, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~~~~~~~~~
error[E0061]: this struct takes 2 arguments but 1 argument was supplied
--> $DIR/struct-enum-wrong-args.rs:12:13
@@ -110,7 +110,7 @@ LL | struct DoubleWrapper(i32, i32);
help: provide the argument
|
LL | let _ = DoubleWrapper(5, /* i32 */);
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~~~~~~~~~
error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:13:13
@@ -126,7 +126,7 @@ LL | struct DoubleWrapper(i32, i32);
help: remove the extra argument
|
LL | let _ = DoubleWrapper(5, 2);
- | ~~~~~~~~~~~~~~~~~~~
+ | ~~~~~~
error: aborting due to 8 previous errors
diff --git a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr
index e8e069708..503015f3b 100644
--- a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr
+++ b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr
@@ -4,7 +4,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.e1;
| ^^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0e1;
| +
@@ -15,7 +15,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.E1;
| ^^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0E1;
| +
@@ -26,7 +26,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.f32;
| ^^^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0f32;
| +
@@ -37,7 +37,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.f64;
| ^^^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0f64;
| +
@@ -48,7 +48,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.e+12;
| ^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0e+12;
| +
@@ -59,7 +59,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.e-12;
| ^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0e-12;
| +
@@ -70,7 +70,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 2.e1f32;
| ^^^^^
|
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
|
LL | 2.0e1f32;
| +
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
index 6bb5e1f54..b9fca1a1b 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
@@ -12,10 +12,10 @@ LL | fn is_sync<T: Sync>() {}
| ^^^^ required by this bound in `is_sync`
error[E0277]: `UnsafeCell<u8>` cannot be shared between threads safely
- --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:5
+ --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:15
|
LL | is_sync::<MyTypeWUnsafe>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<u8>` cannot be shared between threads safely
+ | ^^^^^^^^^^^^^ `UnsafeCell<u8>` cannot be shared between threads safely
|
= help: within `MyTypeWUnsafe`, the trait `Sync` is not implemented for `UnsafeCell<u8>`
note: required because it appears within the type `MyTypeWUnsafe`
@@ -30,10 +30,10 @@ LL | fn is_sync<T: Sync>() {}
| ^^^^ required by this bound in `is_sync`
error[E0277]: `Managed` cannot be shared between threads safely
- --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:5
+ --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:15
|
LL | is_sync::<MyTypeManaged>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely
+ | ^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely
|
= help: within `MyTypeManaged`, the trait `Sync` is not implemented for `Managed`
note: required because it appears within the type `MyTypeManaged`
diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr
index 3ea317dfb..c57f71b80 100644
--- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr
@@ -189,10 +189,10 @@ LL ~ b: (T, T),
|
error: missing type for `static` item
- --> $DIR/typeck_type_placeholder_item.rs:73:12
+ --> $DIR/typeck_type_placeholder_item.rs:73:13
|
LL | static A = 42;
- | ^ help: provide a type for the static variable: `A: i32`
+ | ^ help: provide a type for the static variable: `: i32`
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/typeck_type_placeholder_item.rs:75:15
diff --git a/src/test/ui/typeof/issue-100183.rs b/src/test/ui/typeof/issue-100183.rs
new file mode 100644
index 000000000..13e9493ea
--- /dev/null
+++ b/src/test/ui/typeof/issue-100183.rs
@@ -0,0 +1,6 @@
+struct Struct {
+ y: (typeof("hey"),),
+ //~^ ERROR `typeof` is a reserved keyword but unimplemented
+}
+
+fn main() {}
diff --git a/src/test/ui/typeof/issue-100183.stderr b/src/test/ui/typeof/issue-100183.stderr
new file mode 100644
index 000000000..01d3079b2
--- /dev/null
+++ b/src/test/ui/typeof/issue-100183.stderr
@@ -0,0 +1,14 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+ --> $DIR/issue-100183.rs:2:9
+ |
+LL | y: (typeof("hey"),),
+ | ^^^^^^^^^^^^^ reserved keyword
+ |
+help: consider replacing `typeof(...)` with an actual type
+ |
+LL | y: (&'static str,),
+ | ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0516`.
diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.rs b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.rs
index 939b3c522..ec86213f8 100644
--- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.rs
+++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.rs
@@ -3,6 +3,7 @@ use std::ops::Add;
fn main() {
<i32 as Add<u32>>::add(1, 2);
//~^ ERROR cannot add `u32` to `i32`
+ //~| ERROR cannot add `u32` to `i32`
<i32 as Add<i32>>::add(1u32, 2);
//~^ ERROR mismatched types
<i32 as Add<i32>>::add(1, 2u32);
diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index c6f9b3661..eaab6ff3d 100644
--- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -1,8 +1,10 @@
error[E0277]: cannot add `u32` to `i32`
- --> $DIR/ufcs-qpath-self-mismatch.rs:4:5
+ --> $DIR/ufcs-qpath-self-mismatch.rs:4:31
|
LL | <i32 as Add<u32>>::add(1, 2);
- | ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32`
+ | ---------------------- ^ no implementation for `i32 + u32`
+ | |
+ | required by a bound introduced by this call
|
= help: the trait `Add<u32>` is not implemented for `i32`
= help: the following other types implement trait `Add<Rhs>`:
@@ -17,7 +19,7 @@ LL | <i32 as Add<u32>>::add(1, 2);
and 48 others
error[E0308]: mismatched types
- --> $DIR/ufcs-qpath-self-mismatch.rs:6:28
+ --> $DIR/ufcs-qpath-self-mismatch.rs:7:28
|
LL | <i32 as Add<i32>>::add(1u32, 2);
| ---------------------- ^^^^ expected `i32`, found `u32`
@@ -35,7 +37,7 @@ LL | <i32 as Add<i32>>::add(1i32, 2);
| ~~~
error[E0308]: mismatched types
- --> $DIR/ufcs-qpath-self-mismatch.rs:8:31
+ --> $DIR/ufcs-qpath-self-mismatch.rs:9:31
|
LL | <i32 as Add<i32>>::add(1, 2u32);
| ---------------------- ^^^^ expected `i32`, found `u32`
@@ -52,7 +54,25 @@ help: change the type of the numeric literal from `u32` to `i32`
LL | <i32 as Add<i32>>::add(1, 2i32);
| ~~~
-error: aborting due to 3 previous errors
+error[E0277]: cannot add `u32` to `i32`
+ --> $DIR/ufcs-qpath-self-mismatch.rs:4:5
+ |
+LL | <i32 as Add<u32>>::add(1, 2);
+ | ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32`
+ |
+ = help: the trait `Add<u32>` is not implemented for `i32`
+ = help: the following other types implement trait `Add<Rhs>`:
+ <&'a f32 as Add<f32>>
+ <&'a f64 as Add<f64>>
+ <&'a i128 as Add<i128>>
+ <&'a i16 as Add<i16>>
+ <&'a i32 as Add<i32>>
+ <&'a i64 as Add<i64>>
+ <&'a i8 as Add<i8>>
+ <&'a isize as Add<isize>>
+ and 48 others
+
+error: aborting due to 4 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
new file mode 100644
index 000000000..925463d6d
--- /dev/null
+++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
@@ -0,0 +1,8 @@
+#![feature(unboxed_closures)]
+
+fn a<F: Fn<usize>>(f: F) {}
+
+fn main() {
+ a(|_: usize| {});
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
new file mode 100644
index 000000000..9a24fb8c2
--- /dev/null
+++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+ --> $DIR/non-tupled-arg-mismatch.rs:6:5
+ |
+LL | a(|_: usize| {});
+ | ^ types differ
+ |
+ = note: expected trait `Fn<usize>`
+ found trait `Fn<(usize,)>`
+note: required by a bound in `a`
+ --> $DIR/non-tupled-arg-mismatch.rs:3:9
+ |
+LL | fn a<F: Fn<usize>>(f: F) {}
+ | ^^^^^^^^^ required by this bound in `a`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
index 85ff49d61..635ebbb71 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
@@ -6,7 +6,17 @@ LL | let c = || drop(y.0);
| |
| this closure implements `FnOnce`, not `Fn`
LL | foo(c);
- | --- the requirement to implement `Fn` derives from here
+ | --- - the requirement to implement `Fn` derives from here
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `foo`
+ --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:4:14
+ |
+LL | fn foo<F>(f: F)
+ | --- required by a bound in this
+LL | where F: Fn()
+ | ^^^^ required by this bound in `foo`
error: aborting due to previous error
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
index 4f89afa32..e5ca0edd7 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
@@ -2,9 +2,7 @@ error[E0599]: no method named `call` found for closure `[closure@$DIR/unboxed-cl
--> $DIR/unboxed-closures-static-call-wrong-trait.rs:7:10
|
LL | mut_.call((0, ));
- | ---- ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:29]`
- | |
- | this is a function, perhaps you wish to call it
+ | ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:29]`
error: aborting due to previous error
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
index 3241c9f85..455f83f57 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
@@ -6,11 +6,11 @@ LL | let z = f(1_usize, 2);
| |
| arguments to this function are incorrect
|
-note: closure defined here
- --> $DIR/unboxed-closures-type-mismatch.rs:4:17
+note: closure parameter defined here
+ --> $DIR/unboxed-closures-type-mismatch.rs:4:18
|
LL | let mut f = |x: isize, y: isize| -> isize { x + y };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^
help: change the type of the numeric literal from `usize` to `isize`
|
LL | let z = f(1_isize, 2);
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
index 18e133957..9833304c6 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
@@ -6,7 +6,7 @@ LL | let x = call_it(&square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
+ = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for fn item `for<'r> unsafe fn(&'r isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it`
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:15
@@ -22,7 +22,7 @@ LL | let y = call_it_mut(&mut square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
+ = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for fn item `for<'r> unsafe fn(&'r isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_mut`
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:19
@@ -38,7 +38,7 @@ LL | let z = call_it_once(square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
+ = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for fn item `for<'r> unsafe fn(&'r isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_once`
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:15:20
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
index 77c176de6..54c92e0cd 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
@@ -6,7 +6,7 @@ LL | let x = call_it(&square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+ = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for fn item `for<'r> extern "C" fn(&'r isize) -> isize {square}`
note: required by a bound in `call_it`
--> $DIR/unboxed-closures-wrong-abi.rs:9:15
|
@@ -21,7 +21,7 @@ LL | let y = call_it_mut(&mut square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+ = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for fn item `for<'r> extern "C" fn(&'r isize) -> isize {square}`
note: required by a bound in `call_it_mut`
--> $DIR/unboxed-closures-wrong-abi.rs:12:19
|
@@ -36,7 +36,7 @@ LL | let z = call_it_once(square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+ = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for fn item `for<'r> extern "C" fn(&'r isize) -> isize {square}`
note: required by a bound in `call_it_once`
--> $DIR/unboxed-closures-wrong-abi.rs:15:20
|
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
index c826af3c4..2fedb5b92 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
@@ -6,7 +6,7 @@ LL | let x = call_it(&square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
+ = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for fn item `unsafe fn(isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it`
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:15
@@ -22,7 +22,7 @@ LL | let y = call_it_mut(&mut square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
+ = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for fn item `unsafe fn(isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_mut`
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:19
@@ -38,7 +38,7 @@ LL | let z = call_it_once(square, 22);
| |
| required by a bound introduced by this call
|
- = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
+ = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for fn item `unsafe fn(isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_once`
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:16:20
diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.rs b/src/test/ui/uninhabited/uninhabited-irrefutable.rs
index 661b5486a..1a0f3c5e5 100644
--- a/src/test/ui/uninhabited/uninhabited-irrefutable.rs
+++ b/src/test/ui/uninhabited/uninhabited-irrefutable.rs
@@ -24,5 +24,5 @@ enum Foo {
fn main() {
let x: Foo = Foo::D(123, 456);
- let Foo::D(_y, _z) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered
+ let Foo::D(_y, _z) = x; //~ ERROR refutable pattern in local binding: `Foo::A(_)` not covered
}
diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
index c571e17a7..32f287a18 100644
--- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
+++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `A(_)` not covered
+error[E0005]: refutable pattern in local binding: `Foo::A(_)` not covered
--> $DIR/uninhabited-irrefutable.rs:27:9
|
LL | let Foo::D(_y, _z) = x;
- | ^^^^^^^^^^^^^^ pattern `A(_)` not covered
+ | ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -18,7 +18,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let (_y, _z) = if let Foo::D(_y, _z) = x { (_y, _z) } else { todo!() };
| +++++++++++++++++ +++++++++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Foo::D(_y, _z) = x else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index 2c107b1f7..c78829634 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -122,7 +122,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let x = if let Ok(x) = x { x } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
-help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+help: alternatively, you might want to use let else to handle the variant that isn't matched
|
LL | let Ok(x) = x else { todo!() };
| ++++++++++++++++
diff --git a/src/test/ui/union/union-generic.mirunsafeck.stderr b/src/test/ui/union/union-generic.mirunsafeck.stderr
index a4f0c400d..037022a91 100644
--- a/src/test/ui/union/union-generic.mirunsafeck.stderr
+++ b/src/test/ui/union/union-generic.mirunsafeck.stderr
@@ -11,10 +11,10 @@ LL | union U<T: Copy> {
| ^^^^ required by this bound in `U`
error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
- --> $DIR/union-generic.rs:13:13
+ --> $DIR/union-generic.rs:13:17
|
LL | let u = U::<Rc<u32>> { a: Default::default() };
- | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
+ | ^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
|
note: required by a bound in `U`
--> $DIR/union-generic.rs:6:12
diff --git a/src/test/ui/union/union-generic.thirunsafeck.stderr b/src/test/ui/union/union-generic.thirunsafeck.stderr
index a4f0c400d..037022a91 100644
--- a/src/test/ui/union/union-generic.thirunsafeck.stderr
+++ b/src/test/ui/union/union-generic.thirunsafeck.stderr
@@ -11,10 +11,10 @@ LL | union U<T: Copy> {
| ^^^^ required by this bound in `U`
error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
- --> $DIR/union-generic.rs:13:13
+ --> $DIR/union-generic.rs:13:17
|
LL | let u = U::<Rc<u32>> { a: Default::default() };
- | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
+ | ^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
|
note: required by a bound in `U`
--> $DIR/union-generic.rs:6:12
diff --git a/src/test/ui/unpretty/avoid-crash.rs b/src/test/ui/unpretty/avoid-crash.rs
new file mode 100644
index 000000000..fd84b70d9
--- /dev/null
+++ b/src/test/ui/unpretty/avoid-crash.rs
@@ -0,0 +1,4 @@
+// normalize-stderr-test "error `.*`" -> "$$ERROR_MESSAGE"
+// compile-flags: -o/tmp/ -Zunpretty=ast-tree
+
+fn main() {}
diff --git a/src/test/ui/unpretty/avoid-crash.stderr b/src/test/ui/unpretty/avoid-crash.stderr
new file mode 100644
index 000000000..11cd3866f
--- /dev/null
+++ b/src/test/ui/unpretty/avoid-crash.stderr
@@ -0,0 +1,4 @@
+error: pretty-print failed to write `/tmp/` due to $ERROR_MESSAGE
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/unpretty/bad-literal.rs b/src/test/ui/unpretty/bad-literal.rs
new file mode 100644
index 000000000..6dcc0da30
--- /dev/null
+++ b/src/test/ui/unpretty/bad-literal.rs
@@ -0,0 +1,8 @@
+// compile-flags: -Zunpretty=hir
+// check-fail
+
+// In #100948 this caused an ICE with -Zunpretty=hir.
+fn main() {
+ 1u;
+ //~^ ERROR invalid suffix `u` for number literal
+}
diff --git a/src/test/ui/unpretty/bad-literal.stderr b/src/test/ui/unpretty/bad-literal.stderr
new file mode 100644
index 000000000..f3fcb4a4e
--- /dev/null
+++ b/src/test/ui/unpretty/bad-literal.stderr
@@ -0,0 +1,10 @@
+error: invalid suffix `u` for number literal
+ --> $DIR/bad-literal.rs:6:5
+ |
+LL | 1u;
+ | ^^ invalid suffix `u`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/unpretty/bad-literal.stdout b/src/test/ui/unpretty/bad-literal.stdout
new file mode 100644
index 000000000..8df933270
--- /dev/null
+++ b/src/test/ui/unpretty/bad-literal.stdout
@@ -0,0 +1,11 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+// compile-flags: -Zunpretty=hir
+// check-fail
+
+// In #100948 this caused an ICE with -Zunpretty=hir.
+fn main() {
+ <bad-literal>;
+ }
diff --git a/src/test/ui/unpretty/pretty-let-else.rs b/src/test/ui/unpretty/pretty-let-else.rs
new file mode 100644
index 000000000..b5ae52969
--- /dev/null
+++ b/src/test/ui/unpretty/pretty-let-else.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zunpretty=hir
+// check-pass
+
+
+
+fn foo(x: Option<u32>) {
+ let Some(_) = x else { panic!() };
+}
+
+fn main() {}
diff --git a/src/test/ui/unpretty/pretty-let-else.stdout b/src/test/ui/unpretty/pretty-let-else.stdout
new file mode 100644
index 000000000..35ad1cd1b
--- /dev/null
+++ b/src/test/ui/unpretty/pretty-let-else.stdout
@@ -0,0 +1,18 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+// compile-flags: -Zunpretty=hir
+// check-pass
+
+
+
+fn foo(x:
+ Option<u32>) {
+ let Some(_) = x else
+ {
+
+ { ::std::rt::begin_panic("explicit panic") }
+ };
+ }
+fn main() { }
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
index fd58e1b1e..b968174dd 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
@@ -81,40 +81,8 @@ error: unnecessary `unsafe` block
LL | unsafe { unsafe { unsf() } }
| ^^^^^^ unnecessary `unsafe` block
-error: unnecessary `unsafe` block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5
- |
-LL | unsafe fn allow_level() {
- | ----------------------- because it's nested under this `unsafe` fn
-...
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:53:9
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9
- |
-LL | unsafe fn nested_allow_level() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
- |
- = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:65:13
- |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
- | ^^^^^^^^^^^^^^^^^^^^^^
-
error[E0133]: call to unsafe function is unsafe and requires unsafe block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5
+ --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
LL | unsf();
| ^^^^^^ call to unsafe function
@@ -122,13 +90,13 @@ LL | unsf();
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9
+ --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:81:9
|
LL | unsf();
| ^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error: aborting due to 13 previous errors
+error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
index 30b072340..db1e916a3 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
@@ -58,7 +58,6 @@ unsafe fn allow_level() {
VOID = ();
unsafe { unsf() }
- //~^ ERROR unnecessary `unsafe` block
}
unsafe fn nested_allow_level() {
@@ -70,7 +69,6 @@ unsafe fn nested_allow_level() {
VOID = ();
unsafe { unsf() }
- //~^ ERROR unnecessary `unsafe` block
}
}
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
index 2ba6a7293..e36529365 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
@@ -83,26 +83,8 @@ LL | unsafe { unsafe { unsf() } }
| |
| because it's nested under this `unsafe` block
-error: unnecessary `unsafe` block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5
- |
-LL | unsafe fn allow_level() {
- | ----------------------- because it's nested under this `unsafe` fn
-...
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
-
-error: unnecessary `unsafe` block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9
- |
-LL | unsafe fn nested_allow_level() {
- | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL | unsafe { unsf() }
- | ^^^^^^ unnecessary `unsafe` block
-
error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5
+ --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
LL | unsf();
| ^^^^^^ call to unsafe function
@@ -110,13 +92,13 @@ LL | unsf();
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block
- --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9
+ --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:81:9
|
LL | unsf();
| ^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error: aborting due to 13 previous errors
+error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsized-locals/unsized-exprs.stderr b/src/test/ui/unsized-locals/unsized-exprs.stderr
index 6960255d9..a7f57e3fd 100644
--- a/src/test/ui/unsized-locals/unsized-exprs.stderr
+++ b/src/test/ui/unsized-locals/unsized-exprs.stderr
@@ -12,9 +12,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
--> $DIR/unsized-exprs.rs:24:22
|
LL | udrop::<A<[u8]>>(A { 0: *foo() });
- | ---------------- ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `A<[u8]>`
diff --git a/src/test/ui/unsized/issue-71659.stderr b/src/test/ui/unsized/issue-71659.stderr
index d7b95f557..50060e53a 100644
--- a/src/test/ui/unsized/issue-71659.stderr
+++ b/src/test/ui/unsized/issue-71659.stderr
@@ -1,8 +1,10 @@
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
- --> $DIR/issue-71659.rs:30:15
+ --> $DIR/issue-71659.rs:30:13
|
LL | let x = x.cast::<[i32]>();
- | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
+ | ^ ---- required by a bound introduced by this call
+ | |
+ | the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
note: required by a bound in `Cast::cast`
--> $DIR/issue-71659.rs:19:15
diff --git a/src/test/ui/unsized/issue-75707.stderr b/src/test/ui/unsized/issue-75707.stderr
index 7d0a2cb85..97618ed05 100644
--- a/src/test/ui/unsized/issue-75707.stderr
+++ b/src/test/ui/unsized/issue-75707.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `MyCall: Callback` is not satisfied
- --> $DIR/issue-75707.rs:15:5
+ --> $DIR/issue-75707.rs:15:9
|
LL | f::<dyn Processing<Call = MyCall>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall`
|
note: required by a bound in `f`
--> $DIR/issue-75707.rs:9:9
diff --git a/src/test/ui/unsized/issue-75899-but-gats.rs b/src/test/ui/unsized/issue-75899-but-gats.rs
new file mode 100644
index 000000000..5716817f4
--- /dev/null
+++ b/src/test/ui/unsized/issue-75899-but-gats.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+use std::fmt::Debug;
+use std::marker::PhantomData;
+
+trait Foo {
+ type Gat<'a>: ?Sized where Self: 'a;
+}
+
+struct Bar<'a, T: Foo + 'a>(T::Gat<'a>);
+
+struct Baz<T: ?Sized>(PhantomData<T>);
+
+impl<T: ?Sized> Foo for Baz<T> {
+ type Gat<'a> = T where Self: 'a;
+}
+
+fn main() {
+ let x = Bar::<'_, Baz<()>>(());
+ let y: &Bar<'_, Baz<dyn Debug>> = &x;
+}
diff --git a/src/test/ui/unsized/issue-75899.rs b/src/test/ui/unsized/issue-75899.rs
new file mode 100644
index 000000000..abff17e11
--- /dev/null
+++ b/src/test/ui/unsized/issue-75899.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+trait Trait {}
+impl<T> Trait for T {}
+
+trait Noop {
+ type Assoc: ?Sized;
+}
+impl<T: ?Sized> Noop for T {
+ type Assoc = T;
+}
+
+struct NoopNewtype<T: ?Sized + Noop>(T::Assoc);
+fn coerce_newtype<T: Trait>(x: &NoopNewtype<T>) -> &NoopNewtype<dyn Trait + '_> {
+ x
+}
+
+fn main() {}
diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr
index 0221ef16b..b47726054 100644
--- a/src/test/ui/unsized/unsized-fn-param.stderr
+++ b/src/test/ui/unsized/unsized-fn-param.stderr
@@ -2,9 +2,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
--> $DIR/unsized-fn-param.rs:11:11
|
LL | foo11("bar", &"baz");
- | ----- ^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: required for the cast from `str` to the object type `dyn AsRef<Path>`
@@ -17,9 +15,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
--> $DIR/unsized-fn-param.rs:13:19
|
LL | foo12(&"bar", "baz");
- | ----- ^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: required for the cast from `str` to the object type `dyn AsRef<Path>`
@@ -32,9 +28,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
--> $DIR/unsized-fn-param.rs:16:11
|
LL | foo21("bar", &"baz");
- | ----- ^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: required for the cast from `str` to the object type `dyn AsRef<str>`
@@ -47,9 +41,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
--> $DIR/unsized-fn-param.rs:18:19
|
LL | foo22(&"bar", "baz");
- | ----- ^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: required for the cast from `str` to the object type `dyn AsRef<str>`
diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr
index c9510e92f..dff1b0a51 100644
--- a/src/test/ui/unsized/unsized-struct.stderr
+++ b/src/test/ui/unsized/unsized-struct.stderr
@@ -25,10 +25,10 @@ LL + fn foo2<T>() { not_sized::<Foo<T>>() }
|
error[E0277]: the size for values of type `T` cannot be known at compilation time
- --> $DIR/unsized-struct.rs:13:24
+ --> $DIR/unsized-struct.rs:13:35
|
LL | fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
- | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `std::marker::Sized`
|
diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr
index d64091b15..9ad1ac6b4 100644
--- a/src/test/ui/unsized/unsized3.stderr
+++ b/src/test/ui/unsized/unsized3.stderr
@@ -79,14 +79,12 @@ LL | fn f5<Y: ?Sized>(x: &Y) {}
| ++++++++
error[E0277]: the size for values of type `X` cannot be known at compilation time
- --> $DIR/unsized3.rs:40:8
+ --> $DIR/unsized3.rs:40:5
|
LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
| - this type parameter needs to be `std::marker::Sized`
LL | f5(&(*x1, 34));
- | -- ^^^^^^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^ doesn't have a size known at compile-time
|
note: required because it appears within the type `S<X>`
--> $DIR/unsized3.rs:28:8
@@ -106,9 +104,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
| - this type parameter needs to be `std::marker::Sized`
LL | f5(&(32, *x1));
- | -- ^^^^^^^^^ doesn't have a size known at compile-time
- | |
- | required by a bound introduced by this call
+ | ^^^^^^^^^ doesn't have a size known at compile-time
|
note: required because it appears within the type `S<X>`
--> $DIR/unsized3.rs:28:8
diff --git a/src/test/ui/variance/variance-use-contravariant-struct-1.rs b/src/test/ui/variance/variance-use-contravariant-struct-1.rs
index 7f5906748..40781fbf0 100644
--- a/src/test/ui/variance/variance-use-contravariant-struct-1.rs
+++ b/src/test/ui/variance/variance-use-contravariant-struct-1.rs
@@ -1,4 +1,4 @@
-// Test various uses of structs with distint variances to make sure
+// Test various uses of structs with distinct variances to make sure
// they permit lifetimes to be approximated as expected.
struct SomeStruct<T>(fn(T));
diff --git a/src/test/ui/variance/variance-use-contravariant-struct-2.rs b/src/test/ui/variance/variance-use-contravariant-struct-2.rs
index 2113eb2ad..d4b2d0834 100644
--- a/src/test/ui/variance/variance-use-contravariant-struct-2.rs
+++ b/src/test/ui/variance/variance-use-contravariant-struct-2.rs
@@ -1,4 +1,4 @@
-// Test various uses of structs with distint variances to make sure
+// Test various uses of structs with distinct variances to make sure
// they permit lifetimes to be approximated as expected.
#![allow(dead_code)]
diff --git a/src/test/ui/variance/variance-use-invariant-struct-1.rs b/src/test/ui/variance/variance-use-invariant-struct-1.rs
index d40dbceb5..72f50f345 100644
--- a/src/test/ui/variance/variance-use-invariant-struct-1.rs
+++ b/src/test/ui/variance/variance-use-invariant-struct-1.rs
@@ -1,4 +1,4 @@
-// Test various uses of structs with distint variances to make sure
+// Test various uses of structs with distinct variances to make sure
// they permit lifetimes to be approximated as expected.
struct SomeStruct<T>(*mut T);
diff --git a/src/test/ui/wait-forked-but-failed-child.rs b/src/test/ui/wait-forked-but-failed-child.rs
index 0eb0fe071..674c26a43 100644
--- a/src/test/ui/wait-forked-but-failed-child.rs
+++ b/src/test/ui/wait-forked-but-failed-child.rs
@@ -2,6 +2,7 @@
// ignore-emscripten no processes
// ignore-sgx no processes
// ignore-vxworks no 'ps'
+// ignore-fuchsia no 'ps'
#![feature(rustc_private)]
diff --git a/src/test/ui/wf/hir-wf-check-erase-regions.stderr b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
index 037f8b9f3..b04588c57 100644
--- a/src/test/ui/wf/hir-wf-check-erase-regions.stderr
+++ b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
@@ -6,7 +6,7 @@ LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
|
= help: the trait `Iterator` is not implemented for `&T`
= help: the trait `Iterator` is implemented for `&mut I`
- = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+ = note: required for `&T` to implement `IntoIterator`
note: required by a bound in `Flatten`
--> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
|
@@ -21,7 +21,7 @@ LL | fn into_iter(self) -> Self::IntoIter {
|
= help: the trait `Iterator` is not implemented for `&T`
= help: the trait `Iterator` is implemented for `&mut I`
- = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+ = note: required for `&T` to implement `IntoIterator`
note: required by a bound in `Flatten`
--> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
|
diff --git a/src/test/ui/wf/wf-const-type.stderr b/src/test/ui/wf/wf-const-type.stderr
index e47920d3d..85938364e 100644
--- a/src/test/ui/wf/wf-const-type.stderr
+++ b/src/test/ui/wf/wf-const-type.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<NotCopy>`
+ = note: required for `Option<NotCopy>` to implement `Copy`
note: required by a bound in `IsCopy`
--> $DIR/wf-const-type.rs:7:17
|
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
index 29dfb585a..6cf4f33f9 100644
--- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
@@ -11,7 +11,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+ = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
= note: required by cast to type `Box<dyn Trait>`
error[E0038]: the trait `Trait` cannot be made into an object
@@ -27,7 +27,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+ = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
= note: required by cast to type `Box<(dyn Trait + 'static)>`
error[E0038]: the trait `Trait` cannot be made into an object
@@ -43,7 +43,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+ = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
= note: required by cast to type `Box<dyn Trait>`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
index 02169f26f..c9bd4549a 100644
--- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
@@ -11,7 +11,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
= note: required by cast to type `&dyn Trait`
error[E0038]: the trait `Trait` cannot be made into an object
@@ -27,7 +27,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
= note: required by cast to type `&dyn Trait`
error[E0038]: the trait `Trait` cannot be made into an object
@@ -43,7 +43,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
= note: required by cast to type `&dyn Trait`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
index b03023b5f..78312a091 100644
--- a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `(): Foo` is not satisfied
- --> $DIR/wf-foreign-fn-decl-ret.rs:11:25
+ --> $DIR/wf-foreign-fn-decl-ret.rs:11:5
|
LL | pub fn lint_me() -> <() as Foo>::Assoc;
- | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
--> $DIR/wf-foreign-fn-decl-ret.rs:14:32
diff --git a/src/test/ui/wf/wf-static-type.stderr b/src/test/ui/wf/wf-static-type.stderr
index 4ae69cf2e..16c6124b6 100644
--- a/src/test/ui/wf/wf-static-type.stderr
+++ b/src/test/ui/wf/wf-static-type.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
|
- = note: required because of the requirements on the impl of `Copy` for `Option<NotCopy>`
+ = note: required for `Option<NotCopy>` to implement `Copy`
note: required by a bound in `IsCopy`
--> $DIR/wf-static-type.rs:7:17
|
diff --git a/src/test/ui/wf/wf-trait-fn-ret.stderr b/src/test/ui/wf/wf-trait-fn-ret.stderr
index a59ba3400..9bd3cc771 100644
--- a/src/test/ui/wf/wf-trait-fn-ret.stderr
+++ b/src/test/ui/wf/wf-trait-fn-ret.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Eq` is not satisfied
- --> $DIR/wf-trait-fn-ret.rs:10:22
+ --> $DIR/wf-trait-fn-ret.rs:10:23
|
LL | fn bar(&self) -> &Bar<Self>;
- | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
note: required by a bound in `Bar`
--> $DIR/wf-trait-fn-ret.rs:7:14
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
index 6d141a58e..96fc1d36b 100644
--- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -25,7 +25,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
= note: required by cast to type `&dyn Trait`
error[E0038]: the trait `Trait` cannot be made into an object
@@ -45,7 +45,7 @@ LL | trait Trait: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
- = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&R`
+ = note: required for `&R` to implement `CoerceUnsized<&dyn Trait>`
= note: required by cast to type `&dyn Trait`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/where-clauses/where-clause-method-substituion.stderr b/src/test/ui/where-clauses/where-clause-method-substituion.stderr
index f431deee7..8c47ed6d4 100644
--- a/src/test/ui/where-clauses/where-clause-method-substituion.stderr
+++ b/src/test/ui/where-clauses/where-clause-method-substituion.stderr
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `X: Foo<X>` is not satisfied
- --> $DIR/where-clause-method-substituion.rs:20:7
+ --> $DIR/where-clause-method-substituion.rs:20:16
|
LL | 1.method::<X>();
- | ^^^^^^ the trait `Foo<X>` is not implemented for `X`
+ | ^ the trait `Foo<X>` is not implemented for `X`
|
note: required by a bound in `Bar::method`
--> $DIR/where-clause-method-substituion.rs:6:34
diff --git a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
index c13552bc2..e90502977 100644
--- a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
+++ b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
@@ -1,10 +1,8 @@
error[E0277]: the trait bound `Bar: Eq` is not satisfied
- --> $DIR/where-clauses-method-unsatisfied.rs:18:14
+ --> $DIR/where-clauses-method-unsatisfied.rs:18:7
|
LL | x.equals(&x);
- | ------ ^^ the trait `Eq` is not implemented for `Bar`
- | |
- | required by a bound introduced by this call
+ | ^^^^^^ the trait `Eq` is not implemented for `Bar`
|
note: required by a bound in `Foo::<T>::equals`
--> $DIR/where-clauses-method-unsatisfied.rs:11:52
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index c022d3aa0..c437bde5a 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -13,4 +13,3 @@ tar = "0.4.29"
sha2 = "0.10.1"
rayon = "1.5.1"
hex = "0.4.2"
-num_cpus = "1.13.0"
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index efe3f2b61..1a6760d8c 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -210,7 +210,7 @@ fn main() {
let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") {
num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS")
} else {
- num_cpus::get()
+ std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get)
};
rayon::ThreadPoolBuilder::new()
.num_threads(num_threads)
diff --git a/src/tools/clippy/.github/workflows/clippy.yml b/src/tools/clippy/.github/workflows/clippy.yml
index 0e27cc927..fac2c9971 100644
--- a/src/tools/clippy/.github/workflows/clippy.yml
+++ b/src/tools/clippy/.github/workflows/clippy.yml
@@ -24,6 +24,7 @@ env:
RUST_BACKTRACE: 1
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
NO_FMT_TEST: 1
+ CARGO_INCREMENTAL: 0
jobs:
base:
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 97453303c..30607af49 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -10,6 +10,7 @@ env:
RUST_BACKTRACE: 1
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
NO_FMT_TEST: 1
+ CARGO_INCREMENTAL: 0
defaults:
run:
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 2278a8dc1..d847e4c74 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,157 @@ document.
## Unreleased / In Rust Nightly
-[7c21f91b...master](https://github.com/rust-lang/rust-clippy/compare/7c21f91b...master)
+[d7b5cbf0...master](https://github.com/rust-lang/rust-clippy/compare/d7b5cbf0...master)
+
+## Rust 1.63
+
+Current stable, released 2022-08-11
+
+[7c21f91b...d7b5cbf0](https://github.com/rust-lang/rust-clippy/compare/7c21f91b...d7b5cbf0)
+
+### New Lints
+
+* [`borrow_deref_ref`]
+ [#7930](https://github.com/rust-lang/rust-clippy/pull/7930)
+* [`doc_link_with_quotes`]
+ [#8385](https://github.com/rust-lang/rust-clippy/pull/8385)
+* [`no_effect_replace`]
+ [#8754](https://github.com/rust-lang/rust-clippy/pull/8754)
+* [`rc_clone_in_vec_init`]
+ [#8769](https://github.com/rust-lang/rust-clippy/pull/8769)
+* [`derive_partial_eq_without_eq`]
+ [#8796](https://github.com/rust-lang/rust-clippy/pull/8796)
+* [`mismatching_type_param_order`]
+ [#8831](https://github.com/rust-lang/rust-clippy/pull/8831)
+* [`duplicate_mod`] [#8832](https://github.com/rust-lang/rust-clippy/pull/8832)
+* [`unused_rounding`]
+ [#8866](https://github.com/rust-lang/rust-clippy/pull/8866)
+* [`get_first`] [#8882](https://github.com/rust-lang/rust-clippy/pull/8882)
+* [`swap_ptr_to_ref`]
+ [#8916](https://github.com/rust-lang/rust-clippy/pull/8916)
+* [`almost_complete_letter_range`]
+ [#8918](https://github.com/rust-lang/rust-clippy/pull/8918)
+* [`needless_parens_on_range_literals`]
+ [#8933](https://github.com/rust-lang/rust-clippy/pull/8933)
+* [`as_underscore`] [#8934](https://github.com/rust-lang/rust-clippy/pull/8934)
+
+### Moves and Deprecations
+
+* Rename `eval_order_dependence` to [`mixed_read_write_in_expression`], move to
+ `nursery` [#8621](https://github.com/rust-lang/rust-clippy/pull/8621)
+
+### Enhancements
+
+* [`undocumented_unsafe_blocks`]: Now also lints on unsafe trait implementations
+ [#8761](https://github.com/rust-lang/rust-clippy/pull/8761)
+* [`empty_line_after_outer_attr`]: Now also lints on argumentless macros
+ [#8790](https://github.com/rust-lang/rust-clippy/pull/8790)
+* [`expect_used`]: Now can be disabled in tests with the `allow-expect-in-tests`
+ option [#8802](https://github.com/rust-lang/rust-clippy/pull/8802)
+* [`unwrap_used`]: Now can be disabled in tests with the `allow-unwrap-in-tests`
+ option [#8802](https://github.com/rust-lang/rust-clippy/pull/8802)
+* [`disallowed_methods`]: Now also lints indirect usages
+ [#8852](https://github.com/rust-lang/rust-clippy/pull/8852)
+* [`get_last_with_len`]: Now also lints `VecDeque` and any deref to slice
+ [#8862](https://github.com/rust-lang/rust-clippy/pull/8862)
+* [`manual_range_contains`]: Now also lints on chains of `&&` and `||`
+ [#8884](https://github.com/rust-lang/rust-clippy/pull/8884)
+* [`rc_clone_in_vec_init`]: Now also lints on `Weak`
+ [#8885](https://github.com/rust-lang/rust-clippy/pull/8885)
+* [`dbg_macro`]: Introduce `allow-dbg-in-tests` config option
+ [#8897](https://github.com/rust-lang/rust-clippy/pull/8897)
+* [`use_self`]: Now also lints on `TupleStruct` and `Struct` patterns
+ [#8899](https://github.com/rust-lang/rust-clippy/pull/8899)
+* [`manual_find_map`] and [`manual_filter_map`]: Now also lints on more complex
+ method chains inside `map`
+ [#8930](https://github.com/rust-lang/rust-clippy/pull/8930)
+* [`needless_return`]: Now also lints on macro expressions in return statements
+ [#8932](https://github.com/rust-lang/rust-clippy/pull/8932)
+* [`doc_markdown`]: Users can now indicate, that the `doc-valid-idents` config
+ should extend the default and not replace it
+ [#8944](https://github.com/rust-lang/rust-clippy/pull/8944)
+* [`disallowed_names`]: Users can now indicate, that the `disallowed-names`
+ config should extend the default and not replace it
+ [#8944](https://github.com/rust-lang/rust-clippy/pull/8944)
+* [`never_loop`]: Now checks for `continue` in struct expression
+ [#9002](https://github.com/rust-lang/rust-clippy/pull/9002)
+
+### False Positive Fixes
+
+* [`useless_transmute`]: No longer lints on types with erased regions
+ [#8564](https://github.com/rust-lang/rust-clippy/pull/8564)
+* [`vec_init_then_push`]: No longer lints when further extended
+ [#8699](https://github.com/rust-lang/rust-clippy/pull/8699)
+* [`cmp_owned`]: No longer lints on `From::from` for `Copy` types
+ [#8807](https://github.com/rust-lang/rust-clippy/pull/8807)
+* [`redundant_allocation`]: No longer lints on fat pointers that would become
+ thin pointers [#8813](https://github.com/rust-lang/rust-clippy/pull/8813)
+* [`derive_partial_eq_without_eq`]:
+ * Handle differing predicates applied by `#[derive(PartialEq)]` and
+ `#[derive(Eq)]`
+ [#8869](https://github.com/rust-lang/rust-clippy/pull/8869)
+ * No longer lints on non-public types and better handles generics
+ [#8950](https://github.com/rust-lang/rust-clippy/pull/8950)
+* [`empty_line_after_outer_attr`]: No longer lints empty lines in inner
+ string values [#8892](https://github.com/rust-lang/rust-clippy/pull/8892)
+* [`branches_sharing_code`]: No longer lints when using different binding names
+ [#8901](https://github.com/rust-lang/rust-clippy/pull/8901)
+* [`significant_drop_in_scrutinee`]: No longer lints on Try `?` and `await`
+ desugared expressions [#8902](https://github.com/rust-lang/rust-clippy/pull/8902)
+* [`checked_conversions`]: No longer lints in `const` contexts
+ [#8907](https://github.com/rust-lang/rust-clippy/pull/8907)
+* [`iter_overeager_cloned`]: No longer lints on `.cloned().flatten()` when
+ `T::Item` doesn't implement `IntoIterator`
+ [#8960](https://github.com/rust-lang/rust-clippy/pull/8960)
+
+### Suggestion Fixes/Improvements
+
+* [`vec_init_then_push`]: Suggest to remove `mut` binding when possible
+ [#8699](https://github.com/rust-lang/rust-clippy/pull/8699)
+* [`manual_range_contains`]: Fix suggestion for integers with different signs
+ [#8763](https://github.com/rust-lang/rust-clippy/pull/8763)
+* [`identity_op`]: Add parenthesis to suggestions where required
+ [#8786](https://github.com/rust-lang/rust-clippy/pull/8786)
+* [`cast_lossless`]: No longer gives wrong suggestion on `usize`/`isize`->`f64`
+ [#8778](https://github.com/rust-lang/rust-clippy/pull/8778)
+* [`rc_clone_in_vec_init`]: Add suggestion
+ [#8814](https://github.com/rust-lang/rust-clippy/pull/8814)
+* The "unknown field" error messages for config files now wraps the field names
+ [#8823](https://github.com/rust-lang/rust-clippy/pull/8823)
+* [`cast_abs_to_unsigned`]: Do not remove cast if it's required
+ [#8876](https://github.com/rust-lang/rust-clippy/pull/8876)
+* [`significant_drop_in_scrutinee`]: Improve lint message for types that are not
+ references and not trivially clone-able
+ [#8902](https://github.com/rust-lang/rust-clippy/pull/8902)
+* [`for_loops_over_fallibles`]: Now suggests the correct variant of `iter()`,
+ `iter_mut()` or `into_iter()`
+ [#8941](https://github.com/rust-lang/rust-clippy/pull/8941)
+
+### ICE Fixes
+
+* Fix ICE in [`let_unit_value`] when calling a `static`/`const` callable type
+ [#8835](https://github.com/rust-lang/rust-clippy/pull/8835)
+* Fix ICEs on callable `static`/`const`s
+ [#8896](https://github.com/rust-lang/rust-clippy/pull/8896)
+* [`needless_late_init`]
+ [#8912](https://github.com/rust-lang/rust-clippy/pull/8912)
+* Fix ICE in shadow lints
+ [#8913](https://github.com/rust-lang/rust-clippy/pull/8913)
+
+### Documentation Improvements
+
+* Clippy has a [Book](https://doc.rust-lang.org/nightly/clippy/) now!
+ [#7359](https://github.com/rust-lang/rust-clippy/pull/7359)
+* Add a *copy lint name*-button to Clippy's lint list
+ [#8839](https://github.com/rust-lang/rust-clippy/pull/8839)
+* Display past names of renamed lints on Clippy's lint list
+ [#8843](https://github.com/rust-lang/rust-clippy/pull/8843)
+* Add the ability to show the lint output in the lint list
+ [#8947](https://github.com/rust-lang/rust-clippy/pull/8947)
## Rust 1.62
-Current stable, released 2022-06-30
+Released 2022-06-30
[d0cf3481...7c21f91b](https://github.com/rust-lang/rust-clippy/compare/d0cf3481...7c21f91b)
@@ -965,7 +1111,7 @@ Released 2021-09-09
[#7407](https://github.com/rust-lang/rust-clippy/pull/7407)
* [`redundant_allocation`]: Now additionally supports the `Arc<>` type
[#7308](https://github.com/rust-lang/rust-clippy/pull/7308)
-* [`blacklisted_name`]: Now allows blacklisted names in test code
+* [`disallowed_names`]: Now allows disallowed names in test code
[#7379](https://github.com/rust-lang/rust-clippy/pull/7379)
* [`redundant_closure`]: Suggests `&mut` for `FnMut`
[#7437](https://github.com/rust-lang/rust-clippy/pull/7437)
@@ -2066,7 +2212,7 @@ Released 2020-08-27
[#5692](https://github.com/rust-lang/rust-clippy/pull/5692)
* [`if_same_then_else`]: Don't assume multiplication is always commutative
[#5702](https://github.com/rust-lang/rust-clippy/pull/5702)
-* [`blacklisted_name`]: Remove `bar` from the default configuration
+* [`disallowed_names`]: Remove `bar` from the default configuration
[#5712](https://github.com/rust-lang/rust-clippy/pull/5712)
* [`redundant_pattern_matching`]: Avoid suggesting non-`const fn` calls in const contexts
[#5724](https://github.com/rust-lang/rust-clippy/pull/5724)
@@ -3437,7 +3583,7 @@ Released 2018-09-13
[`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_letter_range
[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
-[`arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic
+[`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
@@ -3457,6 +3603,7 @@ Released 2018-09-13
[`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions
[`bool_assert_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_assert_comparison
[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
+[`bool_to_int_with_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_to_int_with_if
[`borrow_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr
[`borrow_deref_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_deref_ref
[`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
@@ -3481,6 +3628,7 @@ Released 2018-09-13
[`cast_ref_to_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ref_to_mut
[`cast_sign_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_sign_loss
[`cast_slice_different_sizes`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_different_sizes
+[`cast_slice_from_raw_parts`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_from_raw_parts
[`char_lit_as_u8`]: https://rust-lang.github.io/rust-clippy/master/index.html#char_lit_as_u8
[`chars_last_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_last_cmp
[`chars_next_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_next_cmp
@@ -3496,6 +3644,7 @@ Released 2018-09-13
[`collapsible_else_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if
[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
[`collapsible_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match
+[`collapsible_str_replace`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace
[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
[`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty
[`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_static_lifetime
@@ -3522,6 +3671,7 @@ Released 2018-09-13
[`derive_partial_eq_without_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
[`disallowed_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods
+[`disallowed_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names
[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents
[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type
[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types
@@ -3655,6 +3805,8 @@ Released 2018-09-13
[`iter_not_returning_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_not_returning_iterator
[`iter_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth
[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero
+[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections
+[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items
[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned
[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
[`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_with_drain
@@ -3685,6 +3837,7 @@ Released 2018-09-13
[`manual_find`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find
[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map
[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten
+[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed
[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
@@ -3695,6 +3848,7 @@ Released 2018-09-13
[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic
[`manual_split_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once
[`manual_str_repeat`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat
+[`manual_string_new`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new
[`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip
[`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap
[`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or
@@ -3745,6 +3899,7 @@ Released 2018-09-13
[`module_name_repetitions`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions
[`modulo_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic
[`modulo_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_one
+[`multi_assignments`]: https://rust-lang.github.io/rust-clippy/master/index.html#multi_assignments
[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions
[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl
[`must_use_candidate`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_candidate
@@ -3816,13 +3971,16 @@ Released 2018-09-13
[`or_then_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_then_unwrap
[`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
[`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/master/index.html#overflow_check_conditional
+[`overly_complex_bool_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#overly_complex_bool_expr
[`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic
[`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn
[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
+[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
+[`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters
[`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma
[`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence
[`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_in_format_impl
@@ -3868,6 +4026,7 @@ Released 2018-09-13
[`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts
[`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs
[`result_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_expect_used
+[`result_large_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err
[`result_map_or_into_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_or_into_option
[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unit_fn
[`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else
@@ -3926,6 +4085,7 @@ Released 2018-09-13
[`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl
[`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings
[`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn
+[`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned
[`suspicious_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_unary_op_formatting
[`swap_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#swap_ptr_to_ref
[`tabs_in_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#tabs_in_doc_comments
@@ -3998,6 +4158,7 @@ Released 2018-09-13
[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect
[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount
[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
+[`unused_peekable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_peekable
[`unused_rounding`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_rounding
[`unused_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
[`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index 6e15133d2..28b4cfd5f 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -30,10 +30,10 @@ All contributors are expected to follow the [Rust Code of Conduct].
## The Clippy book
If you're new to Clippy and don't know where to start the [Clippy book] includes
-a developer guide and is a good place to start your journey.
+a [developer guide] and is a good place to start your journey.
-<!-- FIXME: Link to the deployed book, once it is deployed through CI -->
-[Clippy book]: book/src
+[Clippy book]: https://doc.rust-lang.org/nightly/clippy/index.html
+[developer guide]: https://doc.rust-lang.org/nightly/clippy/development/index.html
## High level approach
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 1c875c3ad..b7e136ce9 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy"
-version = "0.1.64"
+version = "0.1.65"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index 2c3defeaa..1193771ff 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -144,7 +144,7 @@ value` mapping e.g.
```toml
avoid-breaking-exported-api = false
-blacklisted-names = ["toto", "tata", "titi"]
+disallowed-names = ["toto", "tata", "titi"]
cognitive-complexity-threshold = 30
```
diff --git a/src/tools/clippy/book/src/configuration.md b/src/tools/clippy/book/src/configuration.md
index 6e295ac31..77f1d2e87 100644
--- a/src/tools/clippy/book/src/configuration.md
+++ b/src/tools/clippy/book/src/configuration.md
@@ -7,7 +7,7 @@ basic `variable = value` mapping eg.
```toml
avoid-breaking-exported-api = false
-blacklisted-names = ["toto", "tata", "titi"]
+disallowed-names = ["toto", "tata", "titi"]
cognitive-complexity-threshold = 30
```
diff --git a/src/tools/clippy/book/src/development/common_tools_writing_lints.md b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
index 15e00c7d7..2bc275cef 100644
--- a/src/tools/clippy/book/src/development/common_tools_writing_lints.md
+++ b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
@@ -66,7 +66,7 @@ Starting with an `expr`, you can check whether it is calling a specific method
impl<'tcx> LateLintPass<'tcx> for MyStructLint {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
// Check our expr is calling a method
- if let hir::ExprKind::MethodCall(path, _, [_self_arg, ..]) = &expr.kind
+ if let hir::ExprKind::MethodCall(path, _, _self_arg, ..) = &expr.kind
// Check the name of this method is `some_method`
&& path.ident.name == sym!(some_method)
// Optionally, check the type of the self argument.
diff --git a/src/tools/clippy/clippy_dev/src/bless.rs b/src/tools/clippy/clippy_dev/src/bless.rs
index f5c51b947..92b2771f3 100644
--- a/src/tools/clippy/clippy_dev/src/bless.rs
+++ b/src/tools/clippy/clippy_dev/src/bless.rs
@@ -37,7 +37,7 @@ fn update_reference_file(test_output_entry: &DirEntry, ignore_timestamp: bool) {
return;
}
- let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
+ let test_output_file = fs::read(test_output_path).expect("Unable to read test output file");
let reference_file = fs::read(&reference_file_path).unwrap_or_default();
if test_output_file != reference_file {
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index 3b27f061e..357cf6fc4 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -46,7 +46,7 @@ pub fn run(check: bool, verbose: bool) {
// dependency
if fs::read_to_string(project_root.join("Cargo.toml"))
.expect("Failed to read clippy Cargo.toml")
- .contains(&"[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
+ .contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
{
return Err(CliError::IntellijSetupActive);
}
@@ -193,10 +193,10 @@ fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
let args = &["--version"];
if context.verbose {
- println!("{}", format_command(&program, &dir, args));
+ println!("{}", format_command(program, &dir, args));
}
- let output = Command::new(&program).current_dir(&dir).args(args.iter()).output()?;
+ let output = Command::new(program).current_dir(&dir).args(args.iter()).output()?;
if output.status.success() {
Ok(())
@@ -207,7 +207,7 @@ fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
Err(CliError::RustfmtNotInstalled)
} else {
Err(CliError::CommandFailed(
- format_command(&program, &dir, args),
+ format_command(program, &dir, args),
std::str::from_utf8(&output.stderr).unwrap_or("").to_string(),
))
}
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 82574a8e6..54c7456a2 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -1,5 +1,5 @@
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![feature(rustc_private)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index 03d2ef3d1..331b76484 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -120,15 +120,17 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
let new_lint = if enable_msrv {
format!(
- "store.register_{lint_pass}_pass(move || Box::new({module_name}::{camel_name}::new(msrv)));\n ",
+ "store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv)));\n ",
lint_pass = lint.pass,
+ ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
camel_name = to_camel_case(lint.name),
)
} else {
format!(
- "store.register_{lint_pass}_pass(|| Box::new({module_name}::{camel_name}));\n ",
+ "store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ",
lint_pass = lint.pass,
+ ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
camel_name = to_camel_case(lint.name),
)
@@ -155,7 +157,7 @@ fn to_camel_case(name: &str) -> String {
name.split('_')
.map(|s| {
if s.is_empty() {
- String::from("")
+ String::new()
} else {
[&s[0..1].to_uppercase(), &s[1..]].concat()
}
@@ -438,7 +440,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
let mut lint_context = None;
let mut iter = rustc_lexer::tokenize(&file_contents).map(|t| {
- let range = offset..offset + t.len;
+ let range = offset..offset + t.len as usize;
offset = range.end;
LintDeclSearchResult {
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index aed38bc28..b95061bf8 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -3,7 +3,7 @@ use aho_corasick::AhoCorasickBuilder;
use indoc::writedoc;
use itertools::Itertools;
use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
-use std::collections::{HashMap, HashSet};
+use std::collections::{BTreeSet, HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt::Write;
use std::fs::{self, OpenOptions};
@@ -124,6 +124,8 @@ fn generate_lint_files(
let content = gen_lint_group_list("all", all_group_lints);
process_file("clippy_lints/src/lib.register_all.rs", update_mode, &content);
+ update_docs(update_mode, &usable_lints);
+
for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
let content = gen_lint_group_list(&lint_group, lints.iter());
process_file(
@@ -140,6 +142,62 @@ fn generate_lint_files(
process_file("tests/ui/rename.rs", update_mode, &content);
}
+fn update_docs(update_mode: UpdateMode, usable_lints: &[Lint]) {
+ replace_region_in_file(update_mode, Path::new("src/docs.rs"), "docs! {\n", "\n}\n", |res| {
+ for name in usable_lints.iter().map(|lint| lint.name.clone()).sorted() {
+ writeln!(res, r#" "{name}","#).unwrap();
+ }
+ });
+
+ if update_mode == UpdateMode::Check {
+ let mut extra = BTreeSet::new();
+ let mut lint_names = usable_lints
+ .iter()
+ .map(|lint| lint.name.clone())
+ .collect::<BTreeSet<_>>();
+ for file in std::fs::read_dir("src/docs").unwrap() {
+ let filename = file.unwrap().file_name().into_string().unwrap();
+ if let Some(name) = filename.strip_suffix(".txt") {
+ if !lint_names.remove(name) {
+ extra.insert(name.to_string());
+ }
+ }
+ }
+
+ let failed = print_lint_names("extra lint docs:", &extra) | print_lint_names("missing lint docs:", &lint_names);
+
+ if failed {
+ exit_with_failure();
+ }
+ } else {
+ if std::fs::remove_dir_all("src/docs").is_err() {
+ eprintln!("could not remove src/docs directory");
+ }
+ if std::fs::create_dir("src/docs").is_err() {
+ eprintln!("could not recreate src/docs directory");
+ }
+ }
+ for lint in usable_lints {
+ process_file(
+ Path::new("src/docs").join(lint.name.clone() + ".txt"),
+ update_mode,
+ &lint.documentation,
+ );
+ }
+}
+
+fn print_lint_names(header: &str, lints: &BTreeSet<String>) -> bool {
+ if lints.is_empty() {
+ return false;
+ }
+ println!("{}", header);
+ for lint in lints.iter().sorted() {
+ println!(" {}", lint);
+ }
+ println!();
+ true
+}
+
pub fn print_lints() {
let (lint_list, _, _) = gather_all();
let usable_lints = Lint::usable_lints(&lint_list);
@@ -418,7 +476,7 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io
.expect("failed to find `impl_lint_pass` terminator");
impl_lint_pass_end += impl_lint_pass_start;
- if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(&lint_name_upper) {
+ if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(lint_name_upper) {
let mut lint_name_end = impl_lint_pass_start + (lint_name_pos + lint_name_upper.len());
for c in content[lint_name_end..impl_lint_pass_end].chars() {
// Remove trailing whitespace
@@ -451,7 +509,7 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io
}
let mut content =
- fs::read_to_string(&path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
+ fs::read_to_string(path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
eprintln!(
"warn: you will have to manually remove any code related to `{}` from `{}`",
@@ -589,17 +647,26 @@ struct Lint {
desc: String,
module: String,
declaration_range: Range<usize>,
+ documentation: String,
}
impl Lint {
#[must_use]
- fn new(name: &str, group: &str, desc: &str, module: &str, declaration_range: Range<usize>) -> Self {
+ fn new(
+ name: &str,
+ group: &str,
+ desc: &str,
+ module: &str,
+ declaration_range: Range<usize>,
+ documentation: String,
+ ) -> Self {
Self {
name: name.to_lowercase(),
group: group.into(),
desc: remove_line_splices(desc),
module: module.into(),
declaration_range,
+ documentation,
}
}
@@ -836,7 +903,7 @@ pub(crate) struct LintDeclSearchResult<'a> {
fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
let mut offset = 0usize;
let mut iter = tokenize(contents).map(|t| {
- let range = offset..offset + t.len;
+ let range = offset..offset + t.len as usize;
offset = range.end;
LintDeclSearchResult {
@@ -852,27 +919,35 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
}| token_kind == &TokenKind::Ident && *content == "declare_clippy_lint",
) {
let start = range.start;
-
- let mut iter = iter
- .by_ref()
- .filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
+ let mut docs = String::with_capacity(128);
+ let mut iter = iter.by_ref().filter(|t| !matches!(t.token_kind, TokenKind::Whitespace));
// matches `!{`
match_tokens!(iter, Bang OpenBrace);
- match iter.next() {
- // #[clippy::version = "version"] pub
- Some(LintDeclSearchResult {
- token_kind: TokenKind::Pound,
- ..
- }) => {
- match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
- },
- // pub
- Some(LintDeclSearchResult {
- token_kind: TokenKind::Ident,
- ..
- }) => (),
- _ => continue,
+ let mut in_code = false;
+ while let Some(t) = iter.next() {
+ match t.token_kind {
+ TokenKind::LineComment { .. } => {
+ if let Some(line) = t.content.strip_prefix("/// ").or_else(|| t.content.strip_prefix("///")) {
+ if line.starts_with("```") {
+ docs += "```\n";
+ in_code = !in_code;
+ } else if !(in_code && line.starts_with("# ")) {
+ docs += line;
+ docs.push('\n');
+ }
+ }
+ },
+ TokenKind::Pound => {
+ match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
+ break;
+ },
+ TokenKind::Ident => {
+ break;
+ },
+ _ => {},
+ }
}
+ docs.pop(); // remove final newline
let (name, group, desc) = match_tokens!(
iter,
@@ -890,7 +965,7 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
..
}) = iter.next()
{
- lints.push(Lint::new(name, group, desc, module, start..range.end));
+ lints.push(Lint::new(name, group, desc, module, start..range.end, docs));
}
}
}
@@ -899,7 +974,7 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
fn parse_deprecated_contents(contents: &str, lints: &mut Vec<DeprecatedLint>) {
let mut offset = 0usize;
let mut iter = tokenize(contents).map(|t| {
- let range = offset..offset + t.len;
+ let range = offset..offset + t.len as usize;
offset = range.end;
LintDeclSearchResult {
@@ -946,7 +1021,7 @@ fn parse_renamed_contents(contents: &str, lints: &mut Vec<RenamedLint>) {
for line in contents.lines() {
let mut offset = 0usize;
let mut iter = tokenize(line).map(|t| {
- let range = offset..offset + t.len;
+ let range = offset..offset + t.len as usize;
offset = range.end;
LintDeclSearchResult {
@@ -977,7 +1052,11 @@ fn remove_line_splices(s: &str) -> String {
.and_then(|s| s.strip_suffix('"'))
.unwrap_or_else(|| panic!("expected quoted string, found `{}`", s));
let mut res = String::with_capacity(s.len());
- unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, _| res.push_str(&s[range]));
+ unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, ch| {
+ if ch.is_ok() {
+ res.push_str(&s[range]);
+ }
+ });
res
}
@@ -1116,6 +1195,7 @@ mod tests {
"\"really long text\"",
"module_name",
Range::default(),
+ String::new(),
),
Lint::new(
"doc_markdown",
@@ -1123,6 +1203,7 @@ mod tests {
"\"single line\"",
"module_name",
Range::default(),
+ String::new(),
),
];
assert_eq!(expected, result);
@@ -1162,6 +1243,7 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
+ String::new(),
),
Lint::new(
"should_assert_eq2",
@@ -1169,6 +1251,7 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
+ String::new(),
),
Lint::new(
"should_assert_eq2",
@@ -1176,6 +1259,7 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
+ String::new(),
),
];
let expected = vec![Lint::new(
@@ -1184,6 +1268,7 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
+ String::new(),
)];
assert_eq!(expected, Lint::usable_lints(&lints));
}
@@ -1191,22 +1276,51 @@ mod tests {
#[test]
fn test_by_lint_group() {
let lints = vec![
- Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
+ Lint::new(
+ "should_assert_eq",
+ "group1",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
+ ),
Lint::new(
"should_assert_eq2",
"group2",
"\"abc\"",
"module_name",
Range::default(),
+ String::new(),
+ ),
+ Lint::new(
+ "incorrect_match",
+ "group1",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
),
- Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
];
let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
expected.insert(
"group1".to_string(),
vec![
- Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
- Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
+ Lint::new(
+ "should_assert_eq",
+ "group1",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
+ ),
+ Lint::new(
+ "incorrect_match",
+ "group1",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
+ ),
],
);
expected.insert(
@@ -1217,6 +1331,7 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
+ String::new(),
)],
);
assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
@@ -1255,9 +1370,30 @@ mod tests {
#[test]
fn test_gen_lint_group_list() {
let lints = vec![
- Lint::new("abc", "group1", "\"abc\"", "module_name", Range::default()),
- Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
- Lint::new("internal", "internal_style", "\"abc\"", "module_name", Range::default()),
+ Lint::new(
+ "abc",
+ "group1",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
+ ),
+ Lint::new(
+ "should_assert_eq",
+ "group1",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
+ ),
+ Lint::new(
+ "internal",
+ "internal_style",
+ "\"abc\"",
+ "module_name",
+ Range::default(),
+ String::new(),
+ ),
];
let expected = GENERATED_FILE_COMMENT.to_string()
+ &[
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 79a56dc40..738562ef8 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy_lints"
-version = "0.1.64"
+version = "0.1.65"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/as_underscore.rs b/src/tools/clippy/clippy_lints/src/as_underscore.rs
deleted file mode 100644
index 0bdef9d0a..000000000
--- a/src/tools/clippy/clippy_lints/src/as_underscore.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, TyKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-
-declare_clippy_lint! {
- /// ### What it does
- /// Check for the usage of `as _` conversion using inferred type.
- ///
- /// ### Why is this bad?
- /// The conversion might include lossy conversion and dangerous cast that might go
- /// undetected du to the type being inferred.
- ///
- /// The lint is allowed by default as using `_` is less wordy than always specifying the type.
- ///
- /// ### Example
- /// ```rust
- /// fn foo(n: usize) {}
- /// let n: u16 = 256;
- /// foo(n as _);
- /// ```
- /// Use instead:
- /// ```rust
- /// fn foo(n: usize) {}
- /// let n: u16 = 256;
- /// foo(n as usize);
- /// ```
- #[clippy::version = "1.63.0"]
- pub AS_UNDERSCORE,
- restriction,
- "detects `as _` conversion"
-}
-declare_lint_pass!(AsUnderscore => [AS_UNDERSCORE]);
-
-impl<'tcx> LateLintPass<'tcx> for AsUnderscore {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
- if in_external_macro(cx.sess(), expr.span) {
- return;
- }
-
- if let ExprKind::Cast(_, ty) = expr.kind && let TyKind::Infer = ty.kind {
-
- let ty_resolved = cx.typeck_results().expr_ty(expr);
- if let ty::Error(_) = ty_resolved.kind() {
- span_lint_and_help(
- cx,
- AS_UNDERSCORE,
- expr.span,
- "using `as _` conversion",
- None,
- "consider giving the type explicitly",
- );
- } else {
- span_lint_and_then(
- cx,
- AS_UNDERSCORE,
- expr.span,
- "using `as _` conversion",
- |diag| {
- diag.span_suggestion(
- ty.span,
- "consider giving the type explicitly",
- ty_resolved,
- Applicability::MachineApplicable,
- );
- }
- );
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
index 4caab6230..7cd198ace 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
@@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
&& matches!(cx.tcx.get_diagnostic_name(macro_call.def_id), Some(sym::assert_macro))
&& let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn)
&& matches!(panic_expn, PanicExpn::Empty)
- && let ExprKind::MethodCall(method_segment, [recv], _) = condition.kind
+ && let ExprKind::MethodCall(method_segment, recv, [], _) = condition.kind
&& let result_type_with_refs = cx.typeck_results().expr_ty(recv)
&& let result_type = result_type_with_refs.peel_refs()
&& is_type_diagnostic_item(cx, result_type, sym::Result)
@@ -53,13 +53,14 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
if result_type_with_refs != result_type {
return;
} else if let Res::Local(binding_id) = path_res(cx, recv)
- && local_used_after_expr(cx, binding_id, recv) {
+ && local_used_after_expr(cx, binding_id, recv)
+ {
return;
}
}
let mut app = Applicability::MachineApplicable;
match method_segment.ident.as_str() {
- "is_ok" if has_debug_impl(cx, substs.type_at(1)) => {
+ "is_ok" if type_suitable_to_unwrap(cx, substs.type_at(1)) => {
span_lint_and_sugg(
cx,
ASSERTIONS_ON_RESULT_STATES,
@@ -73,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
app,
);
}
- "is_err" if has_debug_impl(cx, substs.type_at(0)) => {
+ "is_err" if type_suitable_to_unwrap(cx, substs.type_at(0)) => {
span_lint_and_sugg(
cx,
ASSERTIONS_ON_RESULT_STATES,
@@ -99,3 +100,7 @@ fn has_debug_impl<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
.get_diagnostic_item(sym::Debug)
.map_or(false, |debug| implements_trait(cx, ty, debug, &[]))
}
+
+fn type_suitable_to_unwrap<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
+ has_debug_impl(cx, ty) && !ty.is_unit() && !ty.is_never()
+}
diff --git a/src/tools/clippy/clippy_lints/src/async_yields_async.rs b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
index 27c2896e1..9464694a3 100644
--- a/src/tools/clippy/clippy_lints/src/async_yields_async.rs
+++ b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
@@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
hir_id: body.value.hir_id,
};
let typeck_results = cx.tcx.typeck_body(body_id);
- let expr_ty = typeck_results.expr_ty(&body.value);
+ let expr_ty = typeck_results.expr_ty(body.value);
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
let return_expr_span = match &body.value.kind {
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index 4bcbeacf9..732dc2b43 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -475,7 +475,7 @@ fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem
fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
if let ItemKind::Fn(_, _, eid) = item.kind {
- is_relevant_expr(cx, cx.tcx.typeck_body(eid), &cx.tcx.hir().body(eid).value)
+ is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
} else {
true
}
@@ -483,7 +483,7 @@ fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool {
match item.kind {
- ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), &cx.tcx.hir().body(eid).value),
+ ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value),
_ => false,
}
}
@@ -492,7 +492,7 @@ fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool {
match item.kind {
TraitItemKind::Fn(_, TraitFn::Required(_)) => true,
TraitItemKind::Fn(_, TraitFn::Provided(eid)) => {
- is_relevant_expr(cx, cx.tcx.typeck_body(eid), &cx.tcx.hir().body(eid).value)
+ is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
},
_ => false,
}
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs
index ad206b5fb..d9e2c9c85 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
// do not lint if the closure is called using an iterator (see #1141)
if_chain! {
if let Some(parent) = get_parent_expr(self.cx, expr);
- if let ExprKind::MethodCall(_, [self_arg, ..], _) = &parent.kind;
+ if let ExprKind::MethodCall(_, self_arg, ..) = &parent.kind;
let caller = self.cx.typeck_results().expr_ty(self_arg);
if let Some(iter_id) = self.cx.tcx.get_diagnostic_item(sym::Iterator);
if implements_trait(self.cx, caller, iter_id, &[]);
@@ -117,7 +117,8 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInIfConditions {
);
}
} else {
- let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
+ let span =
+ block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
if span.from_expansion() || expr.span.from_expansion() {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs b/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs
new file mode 100644
index 000000000..a4b8cbb0d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs
@@ -0,0 +1,125 @@
+use rustc_ast::{ExprPrecedence, LitKind};
+use rustc_hir::{Block, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, source::snippet_block_with_applicability};
+use rustc_errors::Applicability;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Instead of using an if statement to convert a bool to an int,
+ /// this lint suggests using a `from()` function or an `as` coercion.
+ ///
+ /// ### Why is this bad?
+ /// Coercion or `from()` is idiomatic way to convert bool to a number.
+ /// Both methods are guaranteed to return 1 for true, and 0 for false.
+ ///
+ /// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
+ ///
+ /// ### Example
+ /// ```rust
+ /// # let condition = false;
+ /// if condition {
+ /// 1_i64
+ /// } else {
+ /// 0
+ /// };
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # let condition = false;
+ /// i64::from(condition);
+ /// ```
+ /// or
+ /// ```rust
+ /// # let condition = false;
+ /// condition as i64;
+ /// ```
+ #[clippy::version = "1.65.0"]
+ pub BOOL_TO_INT_WITH_IF,
+ style,
+ "using if to convert bool to int"
+}
+declare_lint_pass!(BoolToIntWithIf => [BOOL_TO_INT_WITH_IF]);
+
+impl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf {
+ fn check_expr(&mut self, ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+ if !expr.span.from_expansion() {
+ check_if_else(ctx, expr);
+ }
+ }
+}
+
+fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+ if let ExprKind::If(check, then, Some(else_)) = expr.kind
+ && let Some(then_lit) = int_literal(then)
+ && let Some(else_lit) = int_literal(else_)
+ && check_int_literal_equals_val(then_lit, 1)
+ && check_int_literal_equals_val(else_lit, 0)
+ {
+ let mut applicability = Applicability::MachineApplicable;
+ let snippet = snippet_block_with_applicability(ctx, check.span, "..", None, &mut applicability);
+ let snippet_with_braces = {
+ let need_parens = should_have_parentheses(check);
+ let (left_paren, right_paren) = if need_parens {("(", ")")} else {("", "")};
+ format!("{left_paren}{snippet}{right_paren}")
+ };
+
+ let ty = ctx.typeck_results().expr_ty(then_lit); // then and else must be of same type
+
+ let suggestion = {
+ let wrap_in_curly = is_else_clause(ctx.tcx, expr);
+ let (left_curly, right_curly) = if wrap_in_curly {("{", "}")} else {("", "")};
+ format!(
+ "{left_curly}{ty}::from({snippet}){right_curly}"
+ )
+ }; // when used in else clause if statement should be wrapped in curly braces
+
+ span_lint_and_then(ctx,
+ BOOL_TO_INT_WITH_IF,
+ expr.span,
+ "boolean to int conversion using if",
+ |diag| {
+ diag.span_suggestion(
+ expr.span,
+ "replace with from",
+ suggestion,
+ applicability,
+ );
+ diag.note(format!("`{snippet_with_braces} as {ty}` or `{snippet_with_braces}.into()` can also be valid options"));
+ });
+ };
+}
+
+// If block contains only a int literal expression, return literal expression
+fn int_literal<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>) -> Option<&'tcx rustc_hir::Expr<'tcx>> {
+ if let ExprKind::Block(block, _) = expr.kind
+ && let Block {
+ stmts: [], // Shouldn't lint if statements with side effects
+ expr: Some(expr),
+ ..
+ } = block
+ && let ExprKind::Lit(lit) = &expr.kind
+ && let LitKind::Int(_, _) = lit.node
+ {
+ Some(expr)
+ } else {
+ None
+ }
+}
+
+fn check_int_literal_equals_val<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>, expected_value: u128) -> bool {
+ if let ExprKind::Lit(lit) = &expr.kind
+ && let LitKind::Int(val, _) = lit.node
+ && val == expected_value
+ {
+ true
+ } else {
+ false
+ }
+}
+
+fn should_have_parentheses<'tcx>(check: &'tcx rustc_hir::Expr<'tcx>) -> bool {
+ check.precedence().order() < ExprPrecedence::Cast.order()
+}
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 526ee2f89..656d639f0 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -64,7 +64,7 @@ declare_clippy_lint! {
/// if a {}
/// ```
#[clippy::version = "pre 1.29.0"]
- pub LOGIC_BUG,
+ pub OVERLY_COMPLEX_BOOL_EXPR,
correctness,
"boolean expressions that contain terminals which can be eliminated"
}
@@ -72,7 +72,7 @@ declare_clippy_lint! {
// For each pairs, both orders are considered.
const METHODS_WITH_NEGATION: [(&str, &str); 2] = [("is_some", "is_none"), ("is_err", "is_ok")];
-declare_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, LOGIC_BUG]);
+declare_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, OVERLY_COMPLEX_BOOL_EXPR]);
impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
fn check_fn(
@@ -270,8 +270,8 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
))
})
},
- ExprKind::MethodCall(path, args, _) if args.len() == 1 => {
- let type_of_receiver = cx.typeck_results().expr_ty(&args[0]);
+ ExprKind::MethodCall(path, receiver, [], _) => {
+ let type_of_receiver = cx.typeck_results().expr_ty(receiver);
if !is_type_diagnostic_item(cx, type_of_receiver, sym::Option)
&& !is_type_diagnostic_item(cx, type_of_receiver, sym::Result)
{
@@ -285,7 +285,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
let path: &str = path.ident.name.as_str();
a == path
})
- .and_then(|(_, neg_method)| Some(format!("{}.{}()", snippet_opt(cx, args[0].span)?, neg_method)))
+ .and_then(|(_, neg_method)| Some(format!("{}.{}()", snippet_opt(cx, receiver.span)?, neg_method)))
},
_ => None,
}
@@ -396,7 +396,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 {
span_lint_hir_and_then(
self.cx,
- LOGIC_BUG,
+ OVERLY_COMPLEX_BOOL_EXPR,
e.hir_id,
e.span,
"this boolean expression contains a logic bug",
diff --git a/src/tools/clippy/clippy_lints/src/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/borrow_as_ptr.rs
deleted file mode 100644
index 0993adbae..000000000
--- a/src/tools/clippy/clippy_lints/src/borrow_as_ptr.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_no_std_crate;
-use clippy_utils::source::snippet_opt;
-use clippy_utils::{meets_msrv, msrvs};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, TyKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
-use rustc_session::{declare_tool_lint, impl_lint_pass};
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for the usage of `&expr as *const T` or
- /// `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
- /// `ptr::addr_of_mut` instead.
- ///
- /// ### Why is this bad?
- /// This would improve readability and avoid creating a reference
- /// that points to an uninitialized value or unaligned place.
- /// Read the `ptr::addr_of` docs for more information.
- ///
- /// ### Example
- /// ```rust
- /// let val = 1;
- /// let p = &val as *const i32;
- ///
- /// let mut val_mut = 1;
- /// let p_mut = &mut val_mut as *mut i32;
- /// ```
- /// Use instead:
- /// ```rust
- /// let val = 1;
- /// let p = std::ptr::addr_of!(val);
- ///
- /// let mut val_mut = 1;
- /// let p_mut = std::ptr::addr_of_mut!(val_mut);
- /// ```
- #[clippy::version = "1.60.0"]
- pub BORROW_AS_PTR,
- pedantic,
- "borrowing just to cast to a raw pointer"
-}
-
-impl_lint_pass!(BorrowAsPtr => [BORROW_AS_PTR]);
-
-pub struct BorrowAsPtr {
- msrv: Option<RustcVersion>,
-}
-
-impl BorrowAsPtr {
- #[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
- Self { msrv }
- }
-}
-
-impl<'tcx> LateLintPass<'tcx> for BorrowAsPtr {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if !meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
- return;
- }
-
- if expr.span.from_expansion() {
- return;
- }
-
- if_chain! {
- if let ExprKind::Cast(left_expr, ty) = &expr.kind;
- if let TyKind::Ptr(_) = ty.kind;
- if let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = &left_expr.kind;
-
- then {
- let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
- let macro_name = match mutability {
- Mutability::Not => "addr_of",
- Mutability::Mut => "addr_of_mut",
- };
-
- span_lint_and_sugg(
- cx,
- BORROW_AS_PTR,
- expr.span,
- "borrow as raw pointer",
- "try",
- format!(
- "{}::ptr::{}!({})",
- core_or_std,
- macro_name,
- snippet_opt(cx, e.span).unwrap()
- ),
- Applicability::MachineApplicable,
- );
- }
- }
- }
-
- extract_msrv_attr!(LateContext);
-}
diff --git a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
index 937765b66..c4520d003 100644
--- a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
@@ -29,22 +29,17 @@ declare_clippy_lint! {
///
/// ### Example
/// ```rust
- /// fn foo(_x: &str) {}
- ///
/// let s = &String::new();
///
/// let a: &String = &* s;
- /// foo(&*s);
/// ```
///
/// Use instead:
/// ```rust
- /// # fn foo(_x: &str) {}
/// # let s = &String::new();
/// let a: &String = s;
- /// foo(&**s);
/// ```
- #[clippy::version = "1.59.0"]
+ #[clippy::version = "1.63.0"]
pub BORROW_DEREF_REF,
complexity,
"deref on an immutable reference returns the same type as itself"
diff --git a/src/tools/clippy/clippy_lints/src/bytecount.rs b/src/tools/clippy/clippy_lints/src/bytecount.rs
deleted file mode 100644
index 326ce3408..000000000
--- a/src/tools/clippy/clippy_lints/src/bytecount.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::match_type;
-use clippy_utils::visitors::is_local_used;
-use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{self, UintTy};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for naive byte counts
- ///
- /// ### Why is this bad?
- /// The [`bytecount`](https://crates.io/crates/bytecount)
- /// crate has methods to count your bytes faster, especially for large slices.
- ///
- /// ### Known problems
- /// If you have predominantly small slices, the
- /// `bytecount::count(..)` method may actually be slower. However, if you can
- /// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
- /// faster in those cases.
- ///
- /// ### Example
- /// ```rust
- /// # let vec = vec![1_u8];
- /// let count = vec.iter().filter(|x| **x == 0u8).count();
- /// ```
- ///
- /// Use instead:
- /// ```rust,ignore
- /// # let vec = vec![1_u8];
- /// let count = bytecount::count(&vec, 0u8);
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub NAIVE_BYTECOUNT,
- pedantic,
- "use of naive `<slice>.filter(|&x| x == y).count()` to count byte values"
-}
-
-declare_lint_pass!(ByteCount => [NAIVE_BYTECOUNT]);
-
-impl<'tcx> LateLintPass<'tcx> for ByteCount {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
- if_chain! {
- if let ExprKind::MethodCall(count, [count_recv], _) = expr.kind;
- if count.ident.name == sym::count;
- if let ExprKind::MethodCall(filter, [filter_recv, filter_arg], _) = count_recv.kind;
- if filter.ident.name == sym!(filter);
- if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind;
- let body = cx.tcx.hir().body(body);
- if let [param] = body.params;
- if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;
- if let ExprKind::Binary(ref op, l, r) = body.value.kind;
- if op.node == BinOpKind::Eq;
- if match_type(cx,
- cx.typeck_results().expr_ty(filter_recv).peel_refs(),
- &paths::SLICE_ITER);
- let operand_is_arg = |expr| {
- let expr = peel_ref_operators(cx, peel_blocks(expr));
- path_to_local_id(expr, arg_id)
- };
- let needle = if operand_is_arg(l) {
- r
- } else if operand_is_arg(r) {
- l
- } else {
- return;
- };
- if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(needle).peel_refs().kind();
- if !is_local_used(cx, needle, arg_id);
- then {
- let haystack = if let ExprKind::MethodCall(path, args, _) =
- filter_recv.kind {
- let p = path.ident.name;
- if (p == sym::iter || p == sym!(iter_mut)) && args.len() == 1 {
- &args[0]
- } else {
- filter_recv
- }
- } else {
- filter_recv
- };
- let mut applicability = Applicability::MaybeIncorrect;
- span_lint_and_sugg(
- cx,
- NAIVE_BYTECOUNT,
- expr.span,
- "you appear to be counting bytes the naive way",
- "consider using the bytecount crate",
- format!("bytecount::count({}, {})",
- snippet_with_applicability(cx, haystack.span, "..", &mut applicability),
- snippet_with_applicability(cx, needle.span, "..", &mut applicability)),
- applicability,
- );
- }
- };
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/bytes_count_to_len.rs
deleted file mode 100644
index d70dbf5b2..000000000
--- a/src/tools/clippy/clippy_lints/src/bytes_count_to_len.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{match_def_path, paths};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir as hir;
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- /// It checks for `str::bytes().count()` and suggests replacing it with
- /// `str::len()`.
- ///
- /// ### Why is this bad?
- /// `str::bytes().count()` is longer and may not be as performant as using
- /// `str::len()`.
- ///
- /// ### Example
- /// ```rust
- /// "hello".bytes().count();
- /// String::from("hello").bytes().count();
- /// ```
- /// Use instead:
- /// ```rust
- /// "hello".len();
- /// String::from("hello").len();
- /// ```
- #[clippy::version = "1.62.0"]
- pub BYTES_COUNT_TO_LEN,
- complexity,
- "Using `bytes().count()` when `len()` performs the same functionality"
-}
-
-declare_lint_pass!(BytesCountToLen => [BYTES_COUNT_TO_LEN]);
-
-impl<'tcx> LateLintPass<'tcx> for BytesCountToLen {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if_chain! {
- if let hir::ExprKind::MethodCall(_, expr_args, _) = &expr.kind;
- if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
- if match_def_path(cx, expr_def_id, &paths::ITER_COUNT);
-
- if let [bytes_expr] = &**expr_args;
- if let hir::ExprKind::MethodCall(_, bytes_args, _) = &bytes_expr.kind;
- if let Some(bytes_def_id) = cx.typeck_results().type_dependent_def_id(bytes_expr.hir_id);
- if match_def_path(cx, bytes_def_id, &paths::STR_BYTES);
-
- if let [str_expr] = &**bytes_args;
- let ty = cx.typeck_results().expr_ty(str_expr).peel_refs();
-
- if is_type_diagnostic_item(cx, ty, sym::String) || ty.kind() == &ty::Str;
- then {
- let mut applicability = Applicability::MachineApplicable;
- span_lint_and_sugg(
- cx,
- BYTES_COUNT_TO_LEN,
- expr.span,
- "using long and hard to read `.bytes().count()`",
- "consider calling `.len()` instead",
- format!("{}.len()", snippet_with_applicability(cx, str_expr.span, "..", &mut applicability)),
- applicability
- );
- }
- };
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
deleted file mode 100644
index 7eff71d50..000000000
--- a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_help;
-use if_chain::if_chain;
-use rustc_ast::ast::LitKind;
-use rustc_hir::{Expr, ExprKind, PathSegment};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{source_map::Spanned, symbol::sym, Span};
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for calls to `ends_with` with possible file extensions
- /// and suggests to use a case-insensitive approach instead.
- ///
- /// ### Why is this bad?
- /// `ends_with` is case-sensitive and may not detect files with a valid extension.
- ///
- /// ### Example
- /// ```rust
- /// fn is_rust_file(filename: &str) -> bool {
- /// filename.ends_with(".rs")
- /// }
- /// ```
- /// Use instead:
- /// ```rust
- /// fn is_rust_file(filename: &str) -> bool {
- /// let filename = std::path::Path::new(filename);
- /// filename.extension()
- /// .map(|ext| ext.eq_ignore_ascii_case("rs"))
- /// .unwrap_or(false)
- /// }
- /// ```
- #[clippy::version = "1.51.0"]
- pub CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
- pedantic,
- "Checks for calls to ends_with with case-sensitive file extensions"
-}
-
-declare_lint_pass!(CaseSensitiveFileExtensionComparisons => [CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS]);
-
-fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Span> {
- if_chain! {
- if let ExprKind::MethodCall(PathSegment { ident, .. }, [obj, extension, ..], span) = expr.kind;
- if ident.as_str() == "ends_with";
- if let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), ..}) = extension.kind;
- if (2..=6).contains(&ext_literal.as_str().len());
- if ext_literal.as_str().starts_with('.');
- if ext_literal.as_str().chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
- || ext_literal.as_str().chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
- then {
- let mut ty = ctx.typeck_results().expr_ty(obj);
- ty = match ty.kind() {
- ty::Ref(_, ty, ..) => *ty,
- _ => ty
- };
-
- match ty.kind() {
- ty::Str => {
- return Some(span);
- },
- ty::Adt(def, _) => {
- if ctx.tcx.is_diagnostic_item(sym::String, def.did()) {
- return Some(span);
- }
- },
- _ => { return None; }
- }
- }
- }
- None
-}
-
-impl<'tcx> LateLintPass<'tcx> for CaseSensitiveFileExtensionComparisons {
- fn check_expr(&mut self, ctx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if let Some(span) = check_case_sensitive_file_extension_comparison(ctx, expr) {
- span_lint_and_help(
- ctx,
- CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
- span,
- "case-sensitive file extension comparison",
- None,
- "consider using a case-insensitive comparison instead",
- );
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs b/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs
new file mode 100644
index 000000000..56e894c62
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs
@@ -0,0 +1,25 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, Ty, TyKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty;
+
+use super::AS_UNDERSCORE;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ty: &'tcx Ty<'_>) {
+ if matches!(ty.kind, TyKind::Infer) {
+ span_lint_and_then(cx, AS_UNDERSCORE, expr.span, "using `as _` conversion", |diag| {
+ let ty_resolved = cx.typeck_results().expr_ty(expr);
+ if let ty::Error(_) = ty_resolved.kind() {
+ diag.help("consider giving the type explicitly");
+ } else {
+ diag.span_suggestion(
+ ty.span,
+ "consider giving the type explicitly",
+ ty_resolved,
+ Applicability::MachineApplicable,
+ );
+ }
+ });
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
new file mode 100644
index 000000000..6e1f8cd64
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -0,0 +1,37 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_no_std_crate;
+use clippy_utils::source::snippet_with_context;
+use rustc_errors::Applicability;
+use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
+use rustc_lint::LateContext;
+
+use super::BORROW_AS_PTR;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ cast_expr: &'tcx Expr<'_>,
+ cast_to: &'tcx Ty<'_>,
+) {
+ if matches!(cast_to.kind, TyKind::Ptr(_))
+ && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
+ {
+ let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
+ let macro_name = match mutability {
+ Mutability::Not => "addr_of",
+ Mutability::Mut => "addr_of_mut",
+ };
+ let mut app = Applicability::MachineApplicable;
+ let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
+
+ span_lint_and_sugg(
+ cx,
+ BORROW_AS_PTR,
+ expr.span,
+ "borrow as raw pointer",
+ "try",
+ format!("{}::ptr::{}!({})", core_or_std, macro_name, snip),
+ Applicability::MachineApplicable,
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
index 64ea326b7..3f1edabe6 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -20,7 +20,7 @@ pub(super) fn check(
if meets_msrv(msrv, msrvs::UNSIGNED_ABS)
&& let ty::Int(from) = cast_from.kind()
&& let ty::Uint(to) = cast_to.kind()
- && let ExprKind::MethodCall(method_path, args, _) = cast_expr.kind
+ && let ExprKind::MethodCall(method_path, receiver, ..) = cast_expr.kind
&& method_path.ident.name.as_str() == "abs"
{
let span = if from.bit_width() == to.bit_width() {
@@ -37,7 +37,7 @@ pub(super) fn check(
span,
&format!("casting the result of `{cast_from}::abs()` to {cast_to}"),
"replace with",
- format!("{}.unsigned_abs()", Sugg::hir(cx, &args[0], "..")),
+ format!("{}.unsigned_abs()", Sugg::hir(cx, receiver, "..").maybe_par()),
Applicability::MachineApplicable,
);
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 64f87c80f..406547a44 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -44,7 +44,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
.saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
_ => nbits,
},
- ExprKind::MethodCall(method, [left, right], _) => {
+ ExprKind::MethodCall(method, left, [right], _) => {
if signed {
return nbits;
}
@@ -55,7 +55,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
};
apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::max_value()))
},
- ExprKind::MethodCall(method, [_, lo, hi], _) => {
+ ExprKind::MethodCall(method, _, [lo, hi], _) => {
if method.ident.as_str() == "clamp" {
//FIXME: make this a diagnostic item
if let (Some(lo_bits), Some(hi_bits)) = (get_constant_bits(cx, lo), get_constant_bits(cx, hi)) {
@@ -64,7 +64,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
}
nbits
},
- ExprKind::MethodCall(method, [_value], _) => {
+ ExprKind::MethodCall(method, _value, [], _) => {
if method.ident.name.as_str() == "signum" {
0 // do not lint if cast comes from a `signum` function
} else {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index d476a1a76..da7b12f67 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -18,7 +18,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
cx.typeck_results().expr_ty(expr),
);
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
- } else if let ExprKind::MethodCall(method_path, [self_arg, ..], _) = &expr.kind {
+ } else if let ExprKind::MethodCall(method_path, self_arg, ..) = &expr.kind {
if method_path.ident.name == sym!(cast)
&& let Some(generic_args) = method_path.args
&& let [GenericArg::Type(cast_to)] = generic_args.args
@@ -64,7 +64,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
return false;
};
match parent.kind {
- ExprKind::MethodCall(name, [self_arg, ..], _) if self_arg.hir_id == e.hir_id => {
+ ExprKind::MethodCall(name, self_arg, ..) if self_arg.hir_id == e.hir_id => {
if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned")
&& let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
&& let Some(def_id) = cx.tcx.impl_of_method(def_id)
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs b/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
index 75f70b77e..5b59350be 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
@@ -41,14 +41,14 @@ fn should_lint(cx: &LateContext<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast
}
// Don't lint for the result of methods that always return non-negative values.
- if let ExprKind::MethodCall(path, _, _) = cast_op.kind {
+ if let ExprKind::MethodCall(path, ..) = cast_op.kind {
let mut method_name = path.ident.name.as_str();
let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"];
if_chain! {
if method_name == "unwrap";
if let Some(arglist) = method_chain_args(cast_op, &["unwrap"]);
- if let ExprKind::MethodCall(inner_path, _, _) = &arglist[0][0].kind;
+ if let ExprKind::MethodCall(inner_path, ..) = &arglist[0].0.kind;
then {
method_name = inner_path.ident.name.as_str();
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
new file mode 100644
index 000000000..284ef1659
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
@@ -0,0 +1,63 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::{match_def_path, meets_msrv, msrvs, paths};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{def_id::DefId, Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, Ty};
+use rustc_semver::RustcVersion;
+
+use super::CAST_SLICE_FROM_RAW_PARTS;
+
+enum RawPartsKind {
+ Immutable,
+ Mutable,
+}
+
+fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {
+ if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS) {
+ Some(RawPartsKind::Immutable)
+ } else if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS_MUT) {
+ Some(RawPartsKind::Mutable)
+ } else {
+ None
+ }
+}
+
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ expr: &Expr<'_>,
+ cast_expr: &Expr<'_>,
+ cast_to: Ty<'_>,
+ msrv: Option<RustcVersion>,
+) {
+ if_chain! {
+ if meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS);
+ if let ty::RawPtr(ptrty) = cast_to.kind();
+ if let ty::Slice(_) = ptrty.ty.kind();
+ if let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind;
+ if let ExprKind::Path(ref qpath) = fun.kind;
+ if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
+ if let Some(rpk) = raw_parts_kind(cx, fun_def_id);
+ then {
+ let func = match rpk {
+ RawPartsKind::Immutable => "from_raw_parts",
+ RawPartsKind::Mutable => "from_raw_parts_mut"
+ };
+ let span = expr.span;
+ let mut applicability = Applicability::MachineApplicable;
+ let ptr = snippet_with_applicability(cx, ptr_arg.span, "ptr", &mut applicability);
+ let len = snippet_with_applicability(cx, len_arg.span, "len", &mut applicability);
+ span_lint_and_sugg(
+ cx,
+ CAST_SLICE_FROM_RAW_PARTS,
+ span,
+ &format!("casting the result of `{func}` to {cast_to}"),
+ "replace with",
+ format!("core::ptr::slice_{func}({ptr}, {len})"),
+ applicability
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index af3798a0c..cc5d346b9 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -1,3 +1,5 @@
+mod as_underscore;
+mod borrow_as_ptr;
mod cast_abs_to_unsigned;
mod cast_enum_constructor;
mod cast_lossless;
@@ -8,6 +10,7 @@ mod cast_ptr_alignment;
mod cast_ref_to_mut;
mod cast_sign_loss;
mod cast_slice_different_sizes;
+mod cast_slice_from_raw_parts;
mod char_lit_as_u8;
mod fn_to_numeric_cast;
mod fn_to_numeric_cast_any;
@@ -16,7 +19,7 @@ mod ptr_as_ptr;
mod unnecessary_cast;
mod utils;
-use clippy_utils::is_hir_ty_cfg_dependant;
+use clippy_utils::{is_hir_ty_cfg_dependant, meets_msrv, msrvs};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
@@ -506,6 +509,93 @@ declare_clippy_lint! {
"casting the result of `abs()` to an unsigned integer can panic"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Check for the usage of `as _` conversion using inferred type.
+ ///
+ /// ### Why is this bad?
+ /// The conversion might include lossy conversion and dangerous cast that might go
+ /// undetected due to the type being inferred.
+ ///
+ /// The lint is allowed by default as using `_` is less wordy than always specifying the type.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn foo(n: usize) {}
+ /// let n: u16 = 256;
+ /// foo(n as _);
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// fn foo(n: usize) {}
+ /// let n: u16 = 256;
+ /// foo(n as usize);
+ /// ```
+ #[clippy::version = "1.63.0"]
+ pub AS_UNDERSCORE,
+ restriction,
+ "detects `as _` conversion"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for the usage of `&expr as *const T` or
+ /// `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
+ /// `ptr::addr_of_mut` instead.
+ ///
+ /// ### Why is this bad?
+ /// This would improve readability and avoid creating a reference
+ /// that points to an uninitialized value or unaligned place.
+ /// Read the `ptr::addr_of` docs for more information.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let val = 1;
+ /// let p = &val as *const i32;
+ ///
+ /// let mut val_mut = 1;
+ /// let p_mut = &mut val_mut as *mut i32;
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let val = 1;
+ /// let p = std::ptr::addr_of!(val);
+ ///
+ /// let mut val_mut = 1;
+ /// let p_mut = std::ptr::addr_of_mut!(val_mut);
+ /// ```
+ #[clippy::version = "1.60.0"]
+ pub BORROW_AS_PTR,
+ pedantic,
+ "borrowing just to cast to a raw pointer"
+}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for a raw slice being cast to a slice pointer
+ ///
+ /// ### Why is this bad?
+ /// This can result in multiple `&mut` references to the same location when only a pointer is
+ /// required.
+ /// `ptr::slice_from_raw_parts` is a safe alternative that doesn't require
+ /// the same [safety requirements] to be upheld.
+ ///
+ /// ### Example
+ /// ```rust,ignore
+ /// let _: *const [u8] = std::slice::from_raw_parts(ptr, len) as *const _;
+ /// let _: *mut [u8] = std::slice::from_raw_parts_mut(ptr, len) as *mut _;
+ /// ```
+ /// Use instead:
+ /// ```rust,ignore
+ /// let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, len);
+ /// let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);
+ /// ```
+ /// [safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety
+ #[clippy::version = "1.64.0"]
+ pub CAST_SLICE_FROM_RAW_PARTS,
+ suspicious,
+ "casting a slice created from a pointer and length to a slice pointer"
+}
+
pub struct Casts {
msrv: Option<RustcVersion>,
}
@@ -534,7 +624,10 @@ impl_lint_pass!(Casts => [
PTR_AS_PTR,
CAST_ENUM_TRUNCATION,
CAST_ENUM_CONSTRUCTOR,
- CAST_ABS_TO_UNSIGNED
+ CAST_ABS_TO_UNSIGNED,
+ AS_UNDERSCORE,
+ BORROW_AS_PTR,
+ CAST_SLICE_FROM_RAW_PARTS
]);
impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -547,8 +640,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
return;
}
- if let ExprKind::Cast(cast_expr, cast_to) = expr.kind {
- if is_hir_ty_cfg_dependant(cx, cast_to) {
+ if let ExprKind::Cast(cast_expr, cast_to_hir) = expr.kind {
+ if is_hir_ty_cfg_dependant(cx, cast_to_hir) {
return;
}
let (cast_from, cast_to) = (
@@ -559,7 +652,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) {
return;
}
-
+ cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, self.msrv);
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
@@ -575,6 +668,12 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
cast_enum_constructor::check(cx, expr, cast_expr, cast_from);
}
+
+ as_underscore::check(cx, expr, cast_to_hir);
+
+ if meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
+ borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
+ }
}
cast_ref_to_mut::check(cx, expr);
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index fff7da8e3..19d2e6e1d 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -90,13 +90,20 @@ pub(super) fn check<'tcx>(
fn lint_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) {
let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" };
+ let replaced_literal;
+ let matchless = if literal_str.contains(['(', ')']) {
+ replaced_literal = literal_str.replace(['(', ')'], "");
+ &replaced_literal
+ } else {
+ literal_str
+ };
span_lint_and_sugg(
cx,
UNNECESSARY_CAST,
expr.span,
&format!("casting {} literal to `{}` is unnecessary", literal_kind_name, cast_to),
"try",
- format!("{}_{}", literal_str.trim_end_matches('.'), cast_to),
+ format!("{}_{}", matchless.trim_end_matches('.'), cast_to),
Applicability::MachineApplicable,
);
}
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 17fc81951..37b2fdcff 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -270,10 +270,7 @@ fn get_types_from_cast<'a>(
let limit_from: Option<(&Expr<'_>, &str)> = call_from_cast.or_else(|| {
if_chain! {
// `from_type::from, to_type::max_value()`
- if let ExprKind::Call(from_func, args) = &expr.kind;
- // `to_type::max_value()`
- if args.len() == 1;
- if let limit = &args[0];
+ if let ExprKind::Call(from_func, [limit]) = &expr.kind;
// `from_type::from`
if let ExprKind::Path(ref path) = &from_func.kind;
if let Some(from_sym) = get_implementing_type(path, INTS, "from");
diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
index 454ec2338..20cc330e0 100644
--- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
+++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
@@ -74,8 +74,8 @@ impl EarlyLintPass for CrateInMacroDef {
fn is_macro_export(attr: &Attribute) -> bool {
if_chain! {
- if let AttrKind::Normal(attr_item, _) = &attr.kind;
- if let [segment] = attr_item.path.segments.as_slice();
+ if let AttrKind::Normal(normal) = &attr.kind;
+ if let [segment] = normal.item.path.segments.as_slice();
then {
segment.ident.name == sym::macro_export
} else {
diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs
index 18d34370a..878248a6b 100644
--- a/src/tools/clippy/clippy_lints/src/create_dir.rs
+++ b/src/tools/clippy/clippy_lints/src/create_dir.rs
@@ -34,7 +34,7 @@ declare_lint_pass!(CreateDir => [CREATE_DIR]);
impl LateLintPass<'_> for CreateDir {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
- if let ExprKind::Call(func, args) = expr.kind;
+ if let ExprKind::Call(func, [arg, ..]) = expr.kind;
if let ExprKind::Path(ref path) = func.kind;
if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
@@ -45,7 +45,7 @@ impl LateLintPass<'_> for CreateDir {
expr.span,
"calling `std::fs::create_dir` where there may be a better way",
"consider calling `std::fs::create_dir_all` instead",
- format!("create_dir_all({})", snippet(cx, args[0].span, "..")),
+ format!("create_dir_all({})", snippet(cx, arg.span, "..")),
Applicability::MaybeIncorrect,
)
}
diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs
index d99a1aa29..4e68d6810 100644
--- a/src/tools/clippy/clippy_lints/src/default.rs
+++ b/src/tools/clippy/clippy_lints/src/default.rs
@@ -1,7 +1,9 @@
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::ty::{has_drop, is_copy};
-use clippy_utils::{any_parent_is_automatically_derived, contains_name, get_parent_expr, match_def_path, paths};
+use clippy_utils::{
+ any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths,
+};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
@@ -94,6 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
if let QPath::Resolved(None, _path) = qpath;
let expr_ty = cx.typeck_results().expr_ty(expr);
if let ty::Adt(def, ..) = expr_ty.kind();
+ if !is_from_proc_macro(cx, expr);
then {
// TODO: Work out a way to put "whatever the imported way of referencing
// this type in this file" rather than a fully-qualified type.
@@ -139,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
if adt.is_struct();
let variant = adt.non_enum_variant();
if adt.did().is_local() || !variant.is_field_list_non_exhaustive();
- let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id();
+ let module_did = cx.tcx.parent_module(stmt.hir_id);
if variant
.fields
.iter()
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index fb418a325..be02f328e 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -131,10 +131,10 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
}
},
- ExprKind::MethodCall(_, args, _) => {
+ ExprKind::MethodCall(_, receiver, args, _) => {
if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {
let fn_sig = self.cx.tcx.fn_sig(def_id).skip_binder();
- for (expr, bound) in iter::zip(*args, fn_sig.inputs()) {
+ for (expr, bound) in iter::zip(std::iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) {
self.ty_bounds.push(TyBound::Ty(*bound));
self.visit_expr(expr);
self.ty_bounds.pop();
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 514661589..88e28018e 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1,24 +1,34 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, variant_of_res};
-use clippy_utils::{get_parent_expr, is_lint_allowed, path_to_local, walk_to_expr_usage};
+use clippy_utils::ty::{expr_sig, is_copy, peel_mid_ty_refs, ty_sig, variant_of_res};
+use clippy_utils::{
+ fn_def_id, get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, meets_msrv, msrvs, path_to_local,
+ walk_to_expr_usage,
+};
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{
- self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy, GenericArg, HirId,
- ImplItem, ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
- TraitItemKind, TyKind, UnOp,
+ self as hir, def_id::DefId, BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy,
+ GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind,
+ Path, QPath, TraitItem, TraitItemKind, TyKind, UnOp,
};
+use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
+use rustc_middle::ty::{
+ self, subst::Subst, Binder, BoundVariableKind, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind,
+ ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults,
+};
+use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{symbol::sym, Span, Symbol};
-use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
+use rustc_trait_selection::infer::InferCtxtExt as _;
+use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
+use std::collections::VecDeque;
declare_clippy_lint! {
/// ### What it does
@@ -127,7 +137,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.60.0"]
pub EXPLICIT_AUTO_DEREF,
- nursery,
+ complexity,
"dereferencing when the compiler would automatically dereference"
}
@@ -151,6 +161,7 @@ pub struct Dereferencing {
/// been finished. Note we can't lint at the end of every body as they can be nested within each
/// other.
current_body: Option<BodyId>,
+
/// The list of locals currently being checked by the lint.
/// If the value is `None`, then the binding has been seen as a ref pattern, but is not linted.
/// This is needed for or patterns where one of the branches can be linted, but another can not
@@ -158,6 +169,19 @@ pub struct Dereferencing {
///
/// e.g. `m!(x) | Foo::Bar(ref x)`
ref_locals: FxIndexMap<HirId, Option<RefPat>>,
+
+ // `IntoIterator` for arrays requires Rust 1.53.
+ msrv: Option<RustcVersion>,
+}
+
+impl Dereferencing {
+ #[must_use]
+ pub fn new(msrv: Option<RustcVersion>) -> Self {
+ Self {
+ msrv,
+ ..Dereferencing::default()
+ }
+ }
}
struct StateData {
@@ -170,6 +194,7 @@ struct StateData {
struct DerefedBorrow {
count: usize,
msg: &'static str,
+ snip_expr: Option<HirId>,
}
enum State {
@@ -183,24 +208,24 @@ enum State {
},
DerefedBorrow(DerefedBorrow),
ExplicitDeref {
- // Span and id of the top-level deref expression if the parent expression is a borrow.
- deref_span_id: Option<(Span, HirId)>,
+ mutability: Option<Mutability>,
},
ExplicitDerefField {
name: Symbol,
},
Reborrow {
- deref_span: Span,
- deref_hir_id: HirId,
+ mutability: Mutability,
+ },
+ Borrow {
+ mutability: Mutability,
},
- Borrow,
}
// A reference operation considered by this lint pass
enum RefOp {
Method(Mutability),
Deref,
- AddrOf,
+ AddrOf(Mutability),
}
struct RefPat {
@@ -250,7 +275,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
match (self.state.take(), kind) {
(None, kind) => {
let expr_ty = typeck.expr_ty(expr);
- let (position, adjustments) = walk_parents(cx, expr);
+ let (position, adjustments) = walk_parents(cx, expr, self.msrv);
match kind {
RefOp::Deref => {
@@ -263,7 +288,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
));
} else if position.is_deref_stable() {
self.state = Some((
- State::ExplicitDeref { deref_span_id: None },
+ State::ExplicitDeref { mutability: None },
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
}
@@ -289,7 +314,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
},
));
},
- RefOp::AddrOf => {
+ RefOp::AddrOf(mutability) => {
// Find the number of times the borrow is auto-derefed.
let mut iter = adjustments.iter();
let mut deref_count = 0usize;
@@ -331,20 +356,23 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
let deref_msg =
"this expression creates a reference which is immediately dereferenced by the compiler";
let borrow_msg = "this expression borrows a value the compiler would automatically borrow";
+ let impl_msg = "the borrowed expression implements the required traits";
- let (required_refs, msg) = if position.can_auto_borrow() {
- (1, if deref_count == 1 { borrow_msg } else { deref_msg })
+ let (required_refs, msg, snip_expr) = if position.can_auto_borrow() {
+ (1, if deref_count == 1 { borrow_msg } else { deref_msg }, None)
+ } else if let Position::ImplArg(hir_id) = position {
+ (0, impl_msg, Some(hir_id))
} else if let Some(&Adjust::Borrow(AutoBorrow::Ref(_, mutability))) =
next_adjust.map(|a| &a.kind)
{
if matches!(mutability, AutoBorrowMutability::Mut { .. }) && !position.is_reborrow_stable()
{
- (3, deref_msg)
+ (3, deref_msg, None)
} else {
- (2, deref_msg)
+ (2, deref_msg, None)
}
} else {
- (2, deref_msg)
+ (2, deref_msg, None)
};
if deref_count >= required_refs {
@@ -354,12 +382,17 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
// can't be removed without breaking the code. See earlier comment.
count: deref_count - required_refs,
msg,
+ snip_expr,
}),
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
- } else if position.is_deref_stable() {
+ } else if position.is_deref_stable()
+ // Auto-deref doesn't combine with other adjustments
+ && next_adjust.map_or(true, |a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
+ && iter.all(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
+ {
self.state = Some((
- State::Borrow,
+ State::Borrow { mutability },
StateData {
span: expr.span,
hir_id: expr.hir_id,
@@ -395,7 +428,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
data,
));
},
- (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf) if state.count != 0 => {
+ (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(_)) if state.count != 0 => {
self.state = Some((
State::DerefedBorrow(DerefedBorrow {
count: state.count - 1,
@@ -404,12 +437,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
data,
));
},
- (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf) => {
+ (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(mutability)) => {
let position = data.position;
report(cx, expr, State::DerefedBorrow(state), data);
if position.is_deref_stable() {
self.state = Some((
- State::Borrow,
+ State::Borrow { mutability },
StateData {
span: expr.span,
hir_id: expr.hir_id,
@@ -430,43 +463,28 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
));
} else if position.is_deref_stable() {
self.state = Some((
- State::ExplicitDeref { deref_span_id: None },
+ State::ExplicitDeref { mutability: None },
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
}
},
- (Some((State::Borrow, data)), RefOp::Deref) => {
+ (Some((State::Borrow { mutability }, data)), RefOp::Deref) => {
if typeck.expr_ty(sub_expr).is_ref() {
- self.state = Some((
- State::Reborrow {
- deref_span: expr.span,
- deref_hir_id: expr.hir_id,
- },
- data,
- ));
+ self.state = Some((State::Reborrow { mutability }, data));
} else {
self.state = Some((
State::ExplicitDeref {
- deref_span_id: Some((expr.span, expr.hir_id)),
+ mutability: Some(mutability),
},
data,
));
}
},
- (
- Some((
- State::Reborrow {
- deref_span,
- deref_hir_id,
- },
- data,
- )),
- RefOp::Deref,
- ) => {
+ (Some((State::Reborrow { mutability }, data)), RefOp::Deref) => {
self.state = Some((
State::ExplicitDeref {
- deref_span_id: Some((deref_span, deref_hir_id)),
+ mutability: Some(mutability),
},
data,
));
@@ -485,7 +503,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
}
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
- if let PatKind::Binding(BindingAnnotation::Ref, id, name, _) = pat.kind {
+ if let PatKind::Binding(BindingAnnotation::REF, id, name, _) = pat.kind {
if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) {
// This binding id has been seen before. Add this pattern to the list of changes.
if let Some(prev_pat) = opt_prev_pat {
@@ -521,7 +539,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
spans: vec![pat.span],
app,
replacements: vec![(pat.span, snip.into())],
- hir_id: pat.hir_id
+ hir_id: pat.hir_id,
}),
);
}
@@ -553,6 +571,8 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
self.current_body = None;
}
}
+
+ extract_msrv_attr!(LateContext);
}
fn try_parse_ref_op<'tcx>(
@@ -561,7 +581,7 @@ fn try_parse_ref_op<'tcx>(
expr: &'tcx Expr<'_>,
) -> Option<(RefOp, &'tcx Expr<'tcx>)> {
let (def_id, arg) = match expr.kind {
- ExprKind::MethodCall(_, [arg], _) => (typeck.type_dependent_def_id(expr.hir_id)?, arg),
+ ExprKind::MethodCall(_, arg, [], _) => (typeck.type_dependent_def_id(expr.hir_id)?, arg),
ExprKind::Call(
Expr {
kind: ExprKind::Path(path),
@@ -573,7 +593,7 @@ fn try_parse_ref_op<'tcx>(
ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_unsafe_ptr() => {
return Some((RefOp::Deref, sub_expr));
},
- ExprKind::AddrOf(BorrowKind::Ref, _, sub_expr) => return Some((RefOp::AddrOf, sub_expr)),
+ ExprKind::AddrOf(BorrowKind::Ref, mutability, sub_expr) => return Some((RefOp::AddrOf(mutability), sub_expr)),
_ => return None,
};
if tcx.is_diagnostic_item(sym::deref_method, def_id) {
@@ -605,22 +625,26 @@ enum Position {
/// The method is defined on a reference type. e.g. `impl Foo for &T`
MethodReceiverRefImpl,
Callee,
+ ImplArg(HirId),
FieldAccess(Symbol),
Postfix,
Deref,
/// Any other location which will trigger auto-deref to a specific time.
- DerefStable(i8),
+ /// Contains the precedence of the parent expression and whether the target type is sized.
+ DerefStable(i8, bool),
/// Any other location which will trigger auto-reborrowing.
+ /// Contains the precedence of the parent expression.
ReborrowStable(i8),
+ /// Contains the precedence of the parent expression.
Other(i8),
}
impl Position {
fn is_deref_stable(self) -> bool {
- matches!(self, Self::DerefStable(_))
+ matches!(self, Self::DerefStable(..))
}
fn is_reborrow_stable(self) -> bool {
- matches!(self, Self::DerefStable(_) | Self::ReborrowStable(_))
+ matches!(self, Self::DerefStable(..) | Self::ReborrowStable(_))
}
fn can_auto_borrow(self) -> bool {
@@ -628,7 +652,7 @@ impl Position {
}
fn lint_explicit_deref(self) -> bool {
- matches!(self, Self::Other(_) | Self::DerefStable(_) | Self::ReborrowStable(_))
+ matches!(self, Self::Other(_) | Self::DerefStable(..) | Self::ReborrowStable(_))
}
fn precedence(self) -> i8 {
@@ -638,8 +662,8 @@ impl Position {
| Self::Callee
| Self::FieldAccess(_)
| Self::Postfix => PREC_POSTFIX,
- Self::Deref => PREC_PREFIX,
- Self::DerefStable(p) | Self::ReborrowStable(p) | Self::Other(p) => p,
+ Self::ImplArg(_) | Self::Deref => PREC_PREFIX,
+ Self::DerefStable(p, _) | Self::ReborrowStable(p) | Self::Other(p) => p,
}
}
}
@@ -647,8 +671,12 @@ impl Position {
/// Walks up the parent expressions attempting to determine both how stable the auto-deref result
/// is, and which adjustments will be applied to it. Note this will not consider auto-borrow
/// locations as those follow different rules.
-#[allow(clippy::too_many_lines)]
-fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &'tcx [Adjustment<'tcx>]) {
+#[expect(clippy::too_many_lines)]
+fn walk_parents<'tcx>(
+ cx: &LateContext<'tcx>,
+ e: &'tcx Expr<'_>,
+ msrv: Option<RustcVersion>,
+) -> (Position, &'tcx [Adjustment<'tcx>]) {
let mut adjustments = [].as_slice();
let mut precedence = 0i8;
let ctxt = e.span.ctxt();
@@ -659,7 +687,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
}
match parent {
Node::Local(Local { ty: Some(ty), span, .. }) if span.ctxt() == ctxt => {
- Some(binding_ty_auto_deref_stability(ty, precedence))
+ Some(binding_ty_auto_deref_stability(cx, ty, precedence, List::empty()))
},
Node::Item(&Item {
kind: ItemKind::Static(..) | ItemKind::Const(..),
@@ -680,11 +708,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
..
}) if span.ctxt() == ctxt => {
let ty = cx.tcx.type_of(def_id);
- Some(if ty.is_ref() {
- Position::DerefStable(precedence)
- } else {
- Position::Other(precedence)
- })
+ Some(ty_auto_deref_stability(cx, ty, precedence).position_for_result(cx))
},
Node::Item(&Item {
@@ -705,45 +729,51 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
span,
..
}) if span.ctxt() == ctxt => {
- let output = cx.tcx.fn_sig(def_id.to_def_id()).skip_binder().output();
- Some(if !output.is_ref() {
- Position::Other(precedence)
- } else if output.has_placeholders() || output.has_opaque_types() {
- Position::ReborrowStable(precedence)
- } else {
- Position::DerefStable(precedence)
- })
+ let output = cx
+ .tcx
+ .erase_late_bound_regions(cx.tcx.fn_sig(def_id.to_def_id()).output());
+ Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
+ },
+
+ Node::ExprField(field) if field.span.ctxt() == ctxt => match get_parent_expr_for_hir(cx, field.hir_id) {
+ Some(Expr {
+ hir_id,
+ kind: ExprKind::Struct(path, ..),
+ ..
+ }) => variant_of_res(cx, cx.qpath_res(path, *hir_id))
+ .and_then(|variant| variant.fields.iter().find(|f| f.name == field.ident.name))
+ .map(|field_def| {
+ ty_auto_deref_stability(cx, cx.tcx.type_of(field_def.did), precedence).position_for_arg()
+ }),
+ _ => None,
},
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
ExprKind::Ret(_) => {
let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
Some(
- if let Node::Expr(Expr {
- kind: ExprKind::Closure(&Closure { fn_decl, .. }),
- ..
- }) = cx.tcx.hir().get(owner_id)
+ if let Node::Expr(
+ closure_expr @ Expr {
+ kind: ExprKind::Closure(closure),
+ ..
+ },
+ ) = cx.tcx.hir().get(owner_id)
{
- match fn_decl.output {
- FnRetTy::Return(ty) => binding_ty_auto_deref_stability(ty, precedence),
- FnRetTy::DefaultReturn(_) => Position::Other(precedence),
- }
+ closure_result_position(cx, closure, cx.typeck_results().expr_ty(closure_expr), precedence)
} else {
let output = cx
.tcx
- .fn_sig(cx.tcx.hir().local_def_id(owner_id))
- .skip_binder()
- .output();
- if !output.is_ref() {
- Position::Other(precedence)
- } else if output.has_placeholders() || output.has_opaque_types() {
- Position::ReborrowStable(precedence)
- } else {
- Position::DerefStable(precedence)
- }
+ .erase_late_bound_regions(cx.tcx.fn_sig(cx.tcx.hir().local_def_id(owner_id)).output());
+ ty_auto_deref_stability(cx, output, precedence).position_for_result(cx)
},
)
},
+ ExprKind::Closure(closure) => Some(closure_result_position(
+ cx,
+ closure,
+ cx.typeck_results().expr_ty(parent),
+ precedence,
+ )),
ExprKind::Call(func, _) if func.hir_id == child_id => {
(child_id == e.hir_id).then_some(Position::Callee)
},
@@ -751,65 +781,72 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
.iter()
.position(|arg| arg.hir_id == child_id)
.zip(expr_sig(cx, func))
- .and_then(|(i, sig)| sig.input_with_hir(i))
- .map(|(hir_ty, ty)| match hir_ty {
- // Type inference for closures can depend on how they're called. Only go by the explicit
- // types here.
- Some(ty) => binding_ty_auto_deref_stability(ty, precedence),
- None => param_auto_deref_stability(ty.skip_binder(), precedence),
+ .and_then(|(i, sig)| {
+ sig.input_with_hir(i).map(|(hir_ty, ty)| match hir_ty {
+ // Type inference for closures can depend on how they're called. Only go by the explicit
+ // types here.
+ Some(hir_ty) => binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars()),
+ None => {
+ if let ty::Param(param_ty) = ty.skip_binder().kind() {
+ needless_borrow_impl_arg_position(cx, parent, i, *param_ty, e, precedence, msrv)
+ } else {
+ ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
+ .position_for_arg()
+ }
+ },
+ })
}),
- ExprKind::MethodCall(_, args, _) => {
+ ExprKind::MethodCall(_, receiver, args, _) => {
let id = cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap();
- args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
- if i == 0 {
- // Check for calls to trait methods where the trait is implemented on a reference.
- // Two cases need to be handled:
- // * `self` methods on `&T` will never have auto-borrow
- // * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take
- // priority.
- if e.hir_id != child_id {
- Position::ReborrowStable(precedence)
- } else if let Some(trait_id) = cx.tcx.trait_of_item(id)
- && let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
- && let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
- && let subs = match cx
- .typeck_results()
- .node_substs_opt(parent.hir_id)
- .and_then(|subs| subs.get(1..))
- {
- Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
- None => cx.tcx.mk_substs([].iter()),
- } && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
- // Trait methods taking `&self`
- sub_ty
- } else {
- // Trait methods taking `self`
- arg_ty
- } && impl_ty.is_ref()
- && cx.tcx.infer_ctxt().enter(|infcx|
- infcx
- .type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
- .must_apply_modulo_regions()
- )
+ if receiver.hir_id == child_id {
+ // Check for calls to trait methods where the trait is implemented on a reference.
+ // Two cases need to be handled:
+ // * `self` methods on `&T` will never have auto-borrow
+ // * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take
+ // priority.
+ if e.hir_id != child_id {
+ return Some(Position::ReborrowStable(precedence))
+ } else if let Some(trait_id) = cx.tcx.trait_of_item(id)
+ && let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
+ && let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
+ && let subs = match cx
+ .typeck_results()
+ .node_substs_opt(parent.hir_id)
+ .and_then(|subs| subs.get(1..))
{
- Position::MethodReceiverRefImpl
+ Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
+ None => cx.tcx.mk_substs(std::iter::empty::<ty::subst::GenericArg<'_>>()),
+ } && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
+ // Trait methods taking `&self`
+ sub_ty
} else {
- Position::MethodReceiver
- }
+ // Trait methods taking `self`
+ arg_ty
+ } && impl_ty.is_ref()
+ && cx.tcx.infer_ctxt().enter(|infcx|
+ infcx
+ .type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
+ .must_apply_modulo_regions()
+ )
+ {
+ return Some(Position::MethodReceiverRefImpl)
+ }
+ return Some(Position::MethodReceiver);
+ }
+ args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
+ let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i + 1];
+ if let ty::Param(param_ty) = ty.kind() {
+ needless_borrow_impl_arg_position(cx, parent, i + 1, *param_ty, e, precedence, msrv)
} else {
- param_auto_deref_stability(cx.tcx.fn_sig(id).skip_binder().inputs()[i], precedence)
+ ty_auto_deref_stability(
+ cx,
+ cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i + 1)),
+ precedence,
+ )
+ .position_for_arg()
}
})
},
- ExprKind::Struct(path, fields, _) => {
- let variant = variant_of_res(cx, cx.qpath_res(path, parent.hir_id));
- fields
- .iter()
- .find(|f| f.expr.hir_id == child_id)
- .zip(variant)
- .and_then(|(field, variant)| variant.fields.iter().find(|f| f.name == field.ident.name))
- .map(|field| param_auto_deref_stability(cx.tcx.type_of(field.did), precedence))
- },
ExprKind::Field(child, name) if child.hir_id == e.hir_id => Some(Position::FieldAccess(name.name)),
ExprKind::Unary(UnOp::Deref, child) if child.hir_id == e.hir_id => Some(Position::Deref),
ExprKind::Match(child, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
@@ -831,6 +868,26 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
(position, adjustments)
}
+fn closure_result_position<'tcx>(
+ cx: &LateContext<'tcx>,
+ closure: &'tcx Closure<'_>,
+ ty: Ty<'tcx>,
+ precedence: i8,
+) -> Position {
+ match closure.fn_decl.output {
+ FnRetTy::Return(hir_ty) => {
+ if let Some(sig) = ty_sig(cx, ty)
+ && let Some(output) = sig.output()
+ {
+ binding_ty_auto_deref_stability(cx, hir_ty, precedence, output.bound_vars())
+ } else {
+ Position::Other(precedence)
+ }
+ },
+ FnRetTy::DefaultReturn(_) => Position::Other(precedence),
+ }
+}
+
// Checks the stability of auto-deref when assigned to a binding with the given explicit type.
//
// e.g.
@@ -840,7 +897,12 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
//
// Here `y1` and `y2` would resolve to different types, so the type `&Box<_>` is not stable when
// switching to auto-dereferencing.
-fn binding_ty_auto_deref_stability(ty: &hir::Ty<'_>, precedence: i8) -> Position {
+fn binding_ty_auto_deref_stability<'tcx>(
+ cx: &LateContext<'tcx>,
+ ty: &'tcx hir::Ty<'_>,
+ precedence: i8,
+ binder_args: &'tcx List<BoundVariableKind>,
+) -> Position {
let TyKind::Rptr(_, ty) = &ty.kind else {
return Position::Other(precedence);
};
@@ -870,21 +932,33 @@ fn binding_ty_auto_deref_stability(ty: &hir::Ty<'_>, precedence: i8) -> Position
{
Position::ReborrowStable(precedence)
} else {
- Position::DerefStable(precedence)
+ Position::DerefStable(
+ precedence,
+ cx.tcx
+ .erase_late_bound_regions(Binder::bind_with_vars(
+ cx.typeck_results().node_type(ty.ty.hir_id),
+ binder_args,
+ ))
+ .is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
+ )
}
},
- TyKind::Slice(_)
- | TyKind::Array(..)
- | TyKind::BareFn(_)
- | TyKind::Never
+ TyKind::Slice(_) => Position::DerefStable(precedence, false),
+ TyKind::Array(..) | TyKind::Ptr(_) | TyKind::BareFn(_) => Position::DerefStable(precedence, true),
+ TyKind::Never
| TyKind::Tup(_)
- | TyKind::Ptr(_)
- | TyKind::TraitObject(..)
- | TyKind::Path(_) => Position::DerefStable(precedence),
- TyKind::OpaqueDef(..)
- | TyKind::Infer
- | TyKind::Typeof(..)
- | TyKind::Err => Position::ReborrowStable(precedence),
+ | TyKind::Path(_) => Position::DerefStable(
+ precedence,
+ cx.tcx
+ .erase_late_bound_regions(Binder::bind_with_vars(
+ cx.typeck_results().node_type(ty.ty.hir_id),
+ binder_args,
+ ))
+ .is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
+ ),
+ TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => {
+ Position::ReborrowStable(precedence)
+ },
};
}
}
@@ -920,10 +994,238 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
v.0
}
+// Checks whether:
+// * child is an expression of the form `&e` in an argument position requiring an `impl Trait`
+// * `e`'s type implements `Trait` and is copyable
+// If the conditions are met, returns `Some(Position::ImplArg(..))`; otherwise, returns `None`.
+// The "is copyable" condition is to avoid the case where removing the `&` means `e` would have to
+// be moved, but it cannot be.
+fn needless_borrow_impl_arg_position<'tcx>(
+ cx: &LateContext<'tcx>,
+ parent: &Expr<'tcx>,
+ arg_index: usize,
+ param_ty: ParamTy,
+ mut expr: &Expr<'tcx>,
+ precedence: i8,
+ msrv: Option<RustcVersion>,
+) -> Position {
+ let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
+ let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
+
+ let Some(callee_def_id) = fn_def_id(cx, parent) else { return Position::Other(precedence) };
+ let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
+ let substs_with_expr_ty = cx
+ .typeck_results()
+ .node_substs(if let ExprKind::Call(callee, _) = parent.kind {
+ callee.hir_id
+ } else {
+ parent.hir_id
+ });
+
+ let predicates = cx.tcx.param_env(callee_def_id).caller_bounds();
+ let projection_predicates = predicates
+ .iter()
+ .filter_map(|predicate| {
+ if let PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
+ Some(projection_predicate)
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>();
+
+ let mut trait_with_ref_mut_self_method = false;
+
+ // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
+ if predicates
+ .iter()
+ .filter_map(|predicate| {
+ if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
+ {
+ Some(trait_predicate.trait_ref.def_id)
+ } else {
+ None
+ }
+ })
+ .inspect(|trait_def_id| {
+ trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
+ })
+ .all(|trait_def_id| {
+ Some(trait_def_id) == destruct_trait_def_id
+ || Some(trait_def_id) == sized_trait_def_id
+ || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
+ })
+ {
+ return Position::Other(precedence);
+ }
+
+ // `substs_with_referent_ty` can be constructed outside of `check_referent` because the same
+ // elements are modified each time `check_referent` is called.
+ let mut substs_with_referent_ty = substs_with_expr_ty.to_vec();
+
+ let mut check_referent = |referent| {
+ let referent_ty = cx.typeck_results().expr_ty(referent);
+
+ if !is_copy(cx, referent_ty) {
+ return false;
+ }
+
+ // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+ if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
+ return false;
+ }
+
+ if !replace_types(
+ cx,
+ param_ty,
+ referent_ty,
+ fn_sig,
+ arg_index,
+ &projection_predicates,
+ &mut substs_with_referent_ty,
+ ) {
+ return false;
+ }
+
+ predicates.iter().all(|predicate| {
+ if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
+ && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
+ && let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack()
+ && ty.is_array()
+ && !meets_msrv(msrv, msrvs::ARRAY_INTO_ITERATOR)
+ {
+ return false;
+ }
+
+ let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
+ let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
+ cx.tcx
+ .infer_ctxt()
+ .enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
+ })
+ };
+
+ let mut needless_borrow = false;
+ while let ExprKind::AddrOf(_, _, referent) = expr.kind {
+ if !check_referent(referent) {
+ break;
+ }
+ expr = referent;
+ needless_borrow = true;
+ }
+
+ if needless_borrow {
+ Position::ImplArg(expr.hir_id)
+ } else {
+ Position::Other(precedence)
+ }
+}
+
+fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
+ cx.tcx
+ .associated_items(trait_def_id)
+ .in_definition_order()
+ .any(|assoc_item| {
+ if assoc_item.fn_has_self_parameter {
+ let self_ty = cx.tcx.fn_sig(assoc_item.def_id).skip_binder().inputs()[0];
+ matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
+ } else {
+ false
+ }
+ })
+}
+
+// Iteratively replaces `param_ty` with `new_ty` in `substs`, and similarly for each resulting
+// projected type that is a type parameter. Returns `false` if replacing the types would have an
+// effect on the function signature beyond substituting `new_ty` for `param_ty`.
+// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
+fn replace_types<'tcx>(
+ cx: &LateContext<'tcx>,
+ param_ty: ParamTy,
+ new_ty: Ty<'tcx>,
+ fn_sig: FnSig<'tcx>,
+ arg_index: usize,
+ projection_predicates: &[ProjectionPredicate<'tcx>],
+ substs: &mut [ty::GenericArg<'tcx>],
+) -> bool {
+ let mut replaced = BitSet::new_empty(substs.len());
+
+ let mut deque = VecDeque::with_capacity(substs.len());
+ deque.push_back((param_ty, new_ty));
+
+ while let Some((param_ty, new_ty)) = deque.pop_front() {
+ // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
+ if !fn_sig
+ .inputs_and_output
+ .iter()
+ .enumerate()
+ .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
+ {
+ return false;
+ }
+
+ substs[param_ty.index as usize] = ty::GenericArg::from(new_ty);
+
+ // The `replaced.insert(...)` check provides some protection against infinite loops.
+ if replaced.insert(param_ty.index) {
+ for projection_predicate in projection_predicates {
+ if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
+ && let Some(term_ty) = projection_predicate.term.ty()
+ && let ty::Param(term_param_ty) = term_ty.kind()
+ {
+ let item_def_id = projection_predicate.projection_ty.item_def_id;
+ let assoc_item = cx.tcx.associated_item(item_def_id);
+ let projection = cx.tcx
+ .mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, &[]));
+
+ if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
+ && substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
+ {
+ deque.push_back((*term_param_ty, projected_ty));
+ }
+ }
+ }
+ }
+ }
+
+ true
+}
+
+struct TyPosition<'tcx> {
+ position: Position,
+ ty: Option<Ty<'tcx>>,
+}
+impl From<Position> for TyPosition<'_> {
+ fn from(position: Position) -> Self {
+ Self { position, ty: None }
+ }
+}
+impl<'tcx> TyPosition<'tcx> {
+ fn new_deref_stable_for_result(precedence: i8, ty: Ty<'tcx>) -> Self {
+ Self {
+ position: Position::ReborrowStable(precedence),
+ ty: Some(ty),
+ }
+ }
+ fn position_for_result(self, cx: &LateContext<'tcx>) -> Position {
+ match (self.position, self.ty) {
+ (Position::ReborrowStable(precedence), Some(ty)) => {
+ Position::DerefStable(precedence, ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env))
+ },
+ (position, _) => position,
+ }
+ }
+ fn position_for_arg(self) -> Position {
+ self.position
+ }
+}
+
// Checks whether a type is stable when switching to auto dereferencing,
-fn param_auto_deref_stability(ty: Ty<'_>, precedence: i8) -> Position {
+fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedence: i8) -> TyPosition<'tcx> {
let ty::Ref(_, mut ty, _) = *ty.kind() else {
- return Position::Other(precedence);
+ return Position::Other(precedence).into();
};
loop {
@@ -932,35 +1234,38 @@ fn param_auto_deref_stability(ty: Ty<'_>, precedence: i8) -> Position {
ty = ref_ty;
continue;
},
- ty::Infer(_)
- | ty::Error(_)
- | ty::Param(_)
- | ty::Bound(..)
- | ty::Opaque(..)
- | ty::Placeholder(_)
- | ty::Dynamic(..) => Position::ReborrowStable(precedence),
- ty::Adt(..) if ty.has_placeholders() || ty.has_param_types_or_consts() => {
- Position::ReborrowStable(precedence)
+ ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty),
+ ty::Infer(_) | ty::Error(_) | ty::Bound(..) | ty::Opaque(..) | ty::Placeholder(_) | ty::Dynamic(..) => {
+ Position::ReborrowStable(precedence).into()
},
- ty::Adt(..)
- | ty::Bool
+ ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => {
+ Position::ReborrowStable(precedence).into()
+ },
+ ty::Adt(_, substs) if substs.has_param_types_or_consts() => {
+ TyPosition::new_deref_stable_for_result(precedence, ty)
+ },
+ ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
- | ty::Float(_)
- | ty::Foreign(_)
- | ty::Str
| ty::Array(..)
- | ty::Slice(..)
+ | ty::Float(_)
| ty::RawPtr(..)
+ | ty::FnPtr(_) => Position::DerefStable(precedence, true).into(),
+ ty::Str | ty::Slice(..) => Position::DerefStable(precedence, false).into(),
+ ty::Adt(..)
+ | ty::Foreign(_)
| ty::FnDef(..)
- | ty::FnPtr(_)
- | ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
+ | ty::Closure(..)
| ty::Never
| ty::Tuple(_)
- | ty::Projection(_) => Position::DerefStable(precedence),
+ | ty::Projection(_) => Position::DerefStable(
+ precedence,
+ ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
+ )
+ .into(),
};
}
}
@@ -1026,7 +1331,8 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
},
State::DerefedBorrow(state) => {
let mut app = Applicability::MachineApplicable;
- let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app);
+ let snip_expr = state.snip_expr.map_or(expr, |hir_id| cx.tcx.hir().expect_expr(hir_id));
+ let (snip, snip_is_macro) = snippet_with_context(cx, snip_expr.span, data.span.ctxt(), "..", &mut app);
span_lint_hir_and_then(cx, NEEDLESS_BORROW, data.hir_id, data.span, state.msg, |diag| {
let calls_field = matches!(expr.kind, ExprKind::Field(..)) && matches!(data.position, Position::Callee);
let sugg = if !snip_is_macro
@@ -1040,34 +1346,64 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
diag.span_suggestion(data.span, "change this to", sugg, app);
});
},
- State::ExplicitDeref { deref_span_id } => {
- let (span, hir_id, precedence) = if let Some((span, hir_id)) = deref_span_id
+ State::ExplicitDeref { mutability } => {
+ if matches!(
+ expr.kind,
+ ExprKind::Block(..)
+ | ExprKind::ConstBlock(_)
+ | ExprKind::If(..)
+ | ExprKind::Loop(..)
+ | ExprKind::Match(..)
+ ) && matches!(data.position, Position::DerefStable(_, true))
+ {
+ // Rustc bug: auto deref doesn't work on block expression when targeting sized types.
+ return;
+ }
+
+ let (prefix, precedence) = if let Some(mutability) = mutability
&& !cx.typeck_results().expr_ty(expr).is_ref()
{
- (span, hir_id, PREC_PREFIX)
+ let prefix = match mutability {
+ Mutability::Not => "&",
+ Mutability::Mut => "&mut ",
+ };
+ (prefix, 0)
} else {
- (data.span, data.hir_id, data.position.precedence())
+ ("", data.position.precedence())
};
span_lint_hir_and_then(
cx,
EXPLICIT_AUTO_DEREF,
- hir_id,
- span,
+ data.hir_id,
+ data.span,
"deref which would be done by auto-deref",
|diag| {
let mut app = Applicability::MachineApplicable;
- let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, span.ctxt(), "..", &mut app);
+ let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app);
let sugg =
if !snip_is_macro && expr.precedence().order() < precedence && !has_enclosing_paren(&snip) {
- format!("({})", snip)
+ format!("{}({})", prefix, snip)
} else {
- snip.into()
+ format!("{}{}", prefix, snip)
};
- diag.span_suggestion(span, "try this", sugg, app);
+ diag.span_suggestion(data.span, "try this", sugg, app);
},
);
},
State::ExplicitDerefField { .. } => {
+ if matches!(
+ expr.kind,
+ ExprKind::Block(..)
+ | ExprKind::ConstBlock(_)
+ | ExprKind::If(..)
+ | ExprKind::Loop(..)
+ | ExprKind::Match(..)
+ ) && matches!(data.position, Position::DerefStable(_, true))
+ {
+ // Rustc bug: auto deref doesn't work on block expression when targeting sized types.
+ return;
+ }
+
span_lint_hir_and_then(
cx,
EXPLICIT_AUTO_DEREF,
@@ -1081,7 +1417,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
},
);
},
- State::Borrow | State::Reborrow { .. } => (),
+ State::Borrow { .. } | State::Reborrow { .. } => (),
}
}
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 4d7f4076d..ef9eeecc6 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -40,7 +40,7 @@ declare_clippy_lint! {
///
/// ### Known problems
/// Derive macros [sometimes use incorrect bounds](https://github.com/rust-lang/rust/issues/26925)
- /// in generic types and the user defined `impl` maybe is more generalized or
+ /// in generic types and the user defined `impl` may be more generalized or
/// specialized than what derive will produce. This lint can't detect the manual `impl`
/// has exactly equal bounds, and therefore this lint is disabled for types with
/// generic parameters.
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index a982990e4..751ca24d5 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -15,7 +15,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::traits::Reveal;
use rustc_middle::ty::{
self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef,
- Ty, TyCtxt, Visibility,
+ Ty, TyCtxt,
};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
@@ -425,7 +425,7 @@ struct UnsafeVisitor<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
type NestedFilter = nested_filter::All;
- fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, span: Span, id: HirId) {
+ fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, _: Span, id: HirId) {
if self.has_unsafe {
return;
}
@@ -438,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
}
}
- walk_fn(self, kind, decl, body_id, span, id);
+ walk_fn(self, kind, decl, body_id, id);
}
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
@@ -464,7 +464,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) {
if_chain! {
if let ty::Adt(adt, substs) = ty.kind();
- if cx.tcx.visibility(adt.did()) == Visibility::Public;
+ if cx.tcx.visibility(adt.did()).is_public();
if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq);
if let Some(def_id) = trait_ref.trait_def_id();
if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id);
@@ -516,7 +516,10 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain(
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
tcx.mk_predicate(Binder::dummy(PredicateKind::Trait(TraitPredicate {
- trait_ref: TraitRef::new(eq_trait_id, tcx.mk_substs([tcx.mk_param_from_def(param)].into_iter())),
+ trait_ref: TraitRef::new(
+ eq_trait_id,
+ tcx.mk_substs(std::iter::once(tcx.mk_param_from_def(param))),
+ ),
constness: BoundConstness::NotConst,
polarity: ImplPolarity::Positive,
})))
diff --git a/src/tools/clippy/clippy_lints/src/blacklisted_name.rs b/src/tools/clippy/clippy_lints/src/disallowed_names.rs
index 1600fb25d..6e6615f08 100644
--- a/src/tools/clippy/clippy_lints/src/blacklisted_name.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_names.rs
@@ -6,7 +6,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
/// ### What it does
- /// Checks for usage of blacklisted names for variables, such
+ /// Checks for usage of disallowed names for variables, such
/// as `foo`.
///
/// ### Why is this bad?
@@ -18,21 +18,21 @@ declare_clippy_lint! {
/// let foo = 3.14;
/// ```
#[clippy::version = "pre 1.29.0"]
- pub BLACKLISTED_NAME,
+ pub DISALLOWED_NAMES,
style,
- "usage of a blacklisted/placeholder name"
+ "usage of a disallowed/placeholder name"
}
#[derive(Clone, Debug)]
-pub struct BlacklistedName {
- blacklist: FxHashSet<String>,
+pub struct DisallowedNames {
+ disallow: FxHashSet<String>,
test_modules_deep: u32,
}
-impl BlacklistedName {
- pub fn new(blacklist: FxHashSet<String>) -> Self {
+impl DisallowedNames {
+ pub fn new(disallow: FxHashSet<String>) -> Self {
Self {
- blacklist,
+ disallow,
test_modules_deep: 0,
}
}
@@ -42,9 +42,9 @@ impl BlacklistedName {
}
}
-impl_lint_pass!(BlacklistedName => [BLACKLISTED_NAME]);
+impl_lint_pass!(DisallowedNames => [DISALLOWED_NAMES]);
-impl<'tcx> LateLintPass<'tcx> for BlacklistedName {
+impl<'tcx> LateLintPass<'tcx> for DisallowedNames {
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
if is_test_module_or_function(cx.tcx, item) {
self.test_modules_deep = self.test_modules_deep.saturating_add(1);
@@ -58,12 +58,12 @@ impl<'tcx> LateLintPass<'tcx> for BlacklistedName {
}
if let PatKind::Binding(.., ident, _) = pat.kind {
- if self.blacklist.contains(&ident.name.to_string()) {
+ if self.disallow.contains(&ident.name.to_string()) {
span_lint(
cx,
- BLACKLISTED_NAME,
+ DISALLOWED_NAMES,
ident.span,
- &format!("use of a blacklisted/placeholder name `{}`", ident.name),
+ &format!("use of a disallowed/placeholder name `{}`", ident.name),
);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_types.rs b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
index 14f89edce..28dbfbab2 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_types.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{
- def::Res, def_id::DefId, Item, ItemKind, PolyTraitRef, PrimTy, TraitBoundModifier, Ty, TyKind, UseKind,
+ def::Res, def_id::DefId, Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -120,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
}
}
- fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) {
+ fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>) {
self.check_res_emit(cx, &poly.trait_ref.path.res, poly.trait_ref.path.span);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index da111e737..eb158d850 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -236,7 +236,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
typeck_results: cx.tcx.typeck(item.def_id),
panic_span: None,
};
- fpu.visit_expr(&body.value);
+ fpu.visit_expr(body.value);
lint_for_missing_headers(cx, item.def_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
}
},
@@ -286,7 +286,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
typeck_results: cx.tcx.typeck(item.def_id),
panic_span: None,
};
- fpu.visit_expr(&body.value);
+ fpu.visit_expr(body.value);
lint_for_missing_headers(cx, item.def_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
}
}
@@ -348,7 +348,7 @@ fn lint_for_missing_headers<'tcx>(
if let Some(future) = cx.tcx.lang_items().future_trait();
let typeck = cx.tcx.typeck_body(body_id);
let body = cx.tcx.hir().body(body_id);
- let ret_ty = typeck.expr_ty(&body.value);
+ let ret_ty = typeck.expr_ty(body.value);
if implements_trait(cx, ret_ty, future, &[]);
if let ty::Opaque(_, subs) = ret_ty.kind();
if let Some(gen) = subs.types().next();
@@ -828,7 +828,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
// check for `unwrap`
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
- let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
+ let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();
if is_type_diagnostic_item(self.cx, receiver_ty, sym::Option)
|| is_type_diagnostic_item(self.cx, receiver_ty, sym::Result)
{
diff --git a/src/tools/clippy/clippy_lints/src/doc_link_with_quotes.rs b/src/tools/clippy/clippy_lints/src/doc_link_with_quotes.rs
index cb07f57e8..0ff1d2755 100644
--- a/src/tools/clippy/clippy_lints/src/doc_link_with_quotes.rs
+++ b/src/tools/clippy/clippy_lints/src/doc_link_with_quotes.rs
@@ -21,7 +21,7 @@ declare_clippy_lint! {
/// /// See also: [`foo`]
/// fn bar() {}
/// ```
- #[clippy::version = "1.60.0"]
+ #[clippy::version = "1.63.0"]
pub DOC_LINK_WITH_QUOTES,
pedantic,
"possible typo for an intra-doc link"
diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
index e1eb3b632..7ff7068f0 100644
--- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
+++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
@@ -39,7 +39,7 @@ declare_clippy_lint! {
/// // a.rs
/// use crate::b;
/// ```
- #[clippy::version = "1.62.0"]
+ #[clippy::version = "1.63.0"]
pub DUPLICATE_MOD,
suspicious,
"file loaded as module multiple times"
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index 4e3ae4c96..e70df3f53 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -245,8 +245,8 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
match expr.kind {
ExprKind::MethodCall(
_,
+ map,
[
- map,
Expr {
kind: ExprKind::AddrOf(_, _, key),
span: key_span,
@@ -280,7 +280,7 @@ struct InsertExpr<'tcx> {
value: &'tcx Expr<'tcx>,
}
fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
- if let ExprKind::MethodCall(_, [map, key, value], _) = expr.kind {
+ if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
if match_def_path(cx, id, &paths::BTREEMAP_INSERT) || match_def_path(cx, id, &paths::HASHMAP_INSERT) {
Some(InsertExpr { map, key, value })
diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
index fdfb821ac..bce49165e 100644
--- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
+++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
@@ -51,7 +51,9 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
false
},
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
- PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => !etc.is_some() && array_rec(a),
+ PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => {
+ !etc.as_opt_usize().is_some() && array_rec(a)
+ }
PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),
PatKind::Path(_) | PatKind::Lit(_) => true,
}
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 1ac7bfba0..327865e4c 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -1,5 +1,4 @@
use clippy_utils::diagnostics::span_lint_hir;
-use clippy_utils::ty::contains_ty;
use rustc_hir::intravisit;
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
use rustc_infer::infer::TyCtxtInferExt;
@@ -30,18 +29,12 @@ declare_clippy_lint! {
///
/// ### Example
/// ```rust
- /// # fn foo(bar: usize) {}
- /// let x = Box::new(1);
- /// foo(*x);
- /// println!("{}", *x);
+ /// fn foo(x: Box<u32>) {}
/// ```
///
/// Use instead:
/// ```rust
- /// # fn foo(bar: usize) {}
- /// let x = 1;
- /// foo(x);
- /// println!("{}", x);
+ /// fn foo(x: u32) {}
/// ```
#[clippy::version = "pre 1.29.0"]
pub BOXED_LOCAL,
@@ -172,7 +165,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
// skip if there is a `self` parameter binding to a type
// that contains `Self` (i.e.: `self: Box<Self>`), see #4804
if let Some(trait_self_ty) = self.trait_self_ty {
- if map.name(cmt.hir_id) == kw::SelfLower && contains_ty(cmt.place.ty(), trait_self_ty) {
+ if map.name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) {
return;
}
}
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 4f9ff97f1..53bc617a4 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
};
if body.value.span.from_expansion() {
if body.params.is_empty() {
- if let Some(VecArgs::Vec(&[])) = higher::VecArgs::hir(cx, &body.value) {
+ if let Some(VecArgs::Vec(&[])) = higher::VecArgs::hir(cx, body.value) {
// replace `|| vec![]` with `Vec::new`
span_lint_and_sugg(
cx,
@@ -103,10 +103,10 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
let closure_ty = cx.typeck_results().expr_ty(expr);
if_chain!(
- if !is_adjusted(cx, &body.value);
+ if !is_adjusted(cx, body.value);
if let ExprKind::Call(callee, args) = body.value.kind;
if let ExprKind::Path(_) = callee.kind;
- if check_inputs(cx, body.params, args);
+ if check_inputs(cx, body.params, None, args);
let callee_ty = cx.typeck_results().expr_ty_adjusted(callee);
let call_ty = cx.typeck_results().type_dependent_def_id(body.value.hir_id)
.map_or(callee_ty, |id| cx.tcx.type_of(id));
@@ -145,9 +145,9 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
);
if_chain!(
- if !is_adjusted(cx, &body.value);
- if let ExprKind::MethodCall(path, args, _) = body.value.kind;
- if check_inputs(cx, body.params, args);
+ if !is_adjusted(cx, body.value);
+ if let ExprKind::MethodCall(path, receiver, args, _) = body.value.kind;
+ if check_inputs(cx, body.params, Some(receiver), args);
let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap();
let substs = cx.typeck_results().node_substs(body.value.hir_id);
let call_ty = cx.tcx.bound_type_of(method_def_id).subst(cx.tcx, substs);
@@ -167,12 +167,17 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
}
}
-fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_>]) -> bool {
- if params.len() != call_args.len() {
+fn check_inputs(
+ cx: &LateContext<'_>,
+ params: &[Param<'_>],
+ receiver: Option<&Expr<'_>>,
+ call_args: &[Expr<'_>],
+) -> bool {
+ if receiver.map_or(params.len() != call_args.len(), |_| params.len() != call_args.len() + 1) {
return false;
}
let binding_modes = cx.typeck_results().pat_binding_modes();
- std::iter::zip(params, call_args).all(|(param, arg)| {
+ let check_inputs = |param: &Param<'_>, arg| {
match param.pat.kind {
PatKind::Binding(_, id, ..) if path_to_local_id(arg, id) => {},
_ => return false,
@@ -200,7 +205,8 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_
},
_ => false,
}
- })
+ };
+ std::iter::zip(params, receiver.into_iter().chain(call_args.iter())).all(|(param, arg)| check_inputs(param, arg))
}
fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure_ty: Ty<'tcx>, call_ty: Ty<'tcx>) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 5bf4313b4..b9ed4af02 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -45,10 +45,10 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
// match call to unwrap
- if let ExprKind::MethodCall(unwrap_fun, [write_call], _) = expr.kind;
+ if let ExprKind::MethodCall(unwrap_fun, write_call, [], _) = expr.kind;
if unwrap_fun.ident.name == sym::unwrap;
// match call to write_fmt
- if let ExprKind::MethodCall(write_fun, [write_recv, write_arg], _) = look_in_block(cx, &write_call.kind);
+ if let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = look_in_block(cx, &write_call.kind);
if write_fun.ident.name == sym!(write_fmt);
// match calls to std::io::stdout() / std::io::stderr ()
if let Some(dest_name) = if match_function_call(cx, write_recv, &paths::STDOUT).is_some() {
@@ -128,7 +128,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
if let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res);
// Find id of the local we found in the block
- if let PatKind::Binding(BindingAnnotation::Unannotated, local_hir_id, _ident, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind;
// If those two are the same hir id
if res_pat.hir_id == local_hir_id;
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index b88e53aec..1f69f34a2 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -84,7 +84,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h
// check for `unwrap`
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
- let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
+ let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();
if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option)
|| is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result)
{
@@ -110,7 +110,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h
typeck_results: cx.tcx.typeck(impl_item.id.def_id),
result: Vec::new(),
};
- fpu.visit_expr(&body.value);
+ fpu.visit_expr(body.value);
// if we've found one, lint
if !fpu.result.is_empty() {
diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
index df9b41d2c..ba53a9678 100644
--- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
@@ -164,15 +164,15 @@ fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>) -> Su
suggestion.maybe_par()
}
-fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
- if let Some(method) = get_specialized_log_method(cx, &args[1]) {
+fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {
+ if let Some(method) = get_specialized_log_method(cx, &args[0]) {
span_lint_and_sugg(
cx,
SUBOPTIMAL_FLOPS,
expr.span,
"logarithm for bases 2, 10 and e can be computed more accurately",
"consider using",
- format!("{}.{}()", Sugg::hir(cx, &args[0], ".."), method),
+ format!("{}.{}()", Sugg::hir(cx, receiver, "..").maybe_par(), method),
Applicability::MachineApplicable,
);
}
@@ -180,14 +180,14 @@ fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and
// suggest usage of `(x + (y - 1)).ln_1p()` instead
-fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
+fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {
if let ExprKind::Binary(
Spanned {
node: BinOpKind::Add, ..
},
lhs,
rhs,
- ) = &args[0].kind
+ ) = receiver.kind
{
let recv = match (
constant(cx, cx.typeck_results(), lhs),
@@ -235,41 +235,41 @@ fn get_integer_from_float_constant(value: &Constant) -> Option<i32> {
}
}
-fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
+fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {
// Check receiver
- if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[0]) {
- let method = if F32(f32_consts::E) == value || F64(f64_consts::E) == value {
- "exp"
+ if let Some((value, _)) = constant(cx, cx.typeck_results(), receiver) {
+ if let Some(method) = if F32(f32_consts::E) == value || F64(f64_consts::E) == value {
+ Some("exp")
} else if F32(2.0) == value || F64(2.0) == value {
- "exp2"
+ Some("exp2")
} else {
- return;
- };
-
- span_lint_and_sugg(
- cx,
- SUBOPTIMAL_FLOPS,
- expr.span,
- "exponent for bases 2 and e can be computed more accurately",
- "consider using",
- format!("{}.{}()", prepare_receiver_sugg(cx, &args[1]), method),
- Applicability::MachineApplicable,
- );
+ None
+ } {
+ span_lint_and_sugg(
+ cx,
+ SUBOPTIMAL_FLOPS,
+ expr.span,
+ "exponent for bases 2 and e can be computed more accurately",
+ "consider using",
+ format!("{}.{}()", prepare_receiver_sugg(cx, &args[0]), method),
+ Applicability::MachineApplicable,
+ );
+ }
}
// Check argument
- if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[1]) {
+ if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[0]) {
let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value {
(
SUBOPTIMAL_FLOPS,
"square-root of a number can be computed more efficiently and accurately",
- format!("{}.sqrt()", Sugg::hir(cx, &args[0], "..")),
+ format!("{}.sqrt()", Sugg::hir(cx, receiver, "..").maybe_par()),
)
} else if F32(1.0 / 3.0) == value || F64(1.0 / 3.0) == value {
(
IMPRECISE_FLOPS,
"cube-root of a number can be computed more accurately",
- format!("{}.cbrt()", Sugg::hir(cx, &args[0], "..")),
+ format!("{}.cbrt()", Sugg::hir(cx, receiver, "..").maybe_par()),
)
} else if let Some(exponent) = get_integer_from_float_constant(&value) {
(
@@ -277,7 +277,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
"exponentiation with integer powers can be computed more efficiently",
format!(
"{}.powi({})",
- Sugg::hir(cx, &args[0], ".."),
+ Sugg::hir(cx, receiver, "..").maybe_par(),
numeric_literal::format(&exponent.to_string(), None, false)
),
)
@@ -297,13 +297,14 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
}
}
-fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
- if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[1]) {
+fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {
+ if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[0]) {
if value == Int(2) {
if let Some(parent) = get_parent_expr(cx, expr) {
if let Some(grandparent) = get_parent_expr(cx, parent) {
- if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, args, _) = grandparent.kind {
- if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() {
+ if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, receiver, ..) = grandparent.kind
+ {
+ if method_name.as_str() == "sqrt" && detect_hypot(cx, receiver).is_some() {
return;
}
}
@@ -327,8 +328,8 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
"consider using",
format!(
"{}.mul_add({}, {})",
- Sugg::hir(cx, &args[0], ".."),
- Sugg::hir(cx, &args[0], ".."),
+ Sugg::hir(cx, receiver, "..").maybe_par(),
+ Sugg::hir(cx, receiver, ".."),
Sugg::hir(cx, other_addend, ".."),
),
Applicability::MachineApplicable,
@@ -339,14 +340,14 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
}
}
-fn detect_hypot(cx: &LateContext<'_>, args: &[Expr<'_>]) -> Option<String> {
+fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option<String> {
if let ExprKind::Binary(
Spanned {
node: BinOpKind::Add, ..
},
add_lhs,
add_rhs,
- ) = args[0].kind
+ ) = receiver.kind
{
// check if expression of the form x * x + y * y
if_chain! {
@@ -363,12 +364,12 @@ fn detect_hypot(cx: &LateContext<'_>, args: &[Expr<'_>]) -> Option<String> {
if_chain! {
if let ExprKind::MethodCall(
PathSegment { ident: lmethod_name, .. },
- [largs_0, largs_1, ..],
+ largs_0, [largs_1, ..],
_
) = &add_lhs.kind;
if let ExprKind::MethodCall(
PathSegment { ident: rmethod_name, .. },
- [rargs_0, rargs_1, ..],
+ rargs_0, [rargs_1, ..],
_
) = &add_rhs.kind;
if lmethod_name.as_str() == "powi" && rmethod_name.as_str() == "powi";
@@ -384,8 +385,8 @@ fn detect_hypot(cx: &LateContext<'_>, args: &[Expr<'_>]) -> Option<String> {
None
}
-fn check_hypot(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
- if let Some(message) = detect_hypot(cx, args) {
+fn check_hypot(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {
+ if let Some(message) = detect_hypot(cx, receiver) {
span_lint_and_sugg(
cx,
IMPRECISE_FLOPS,
@@ -406,7 +407,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) {
if cx.typeck_results().expr_ty(lhs).is_floating_point();
if let Some((value, _)) = constant(cx, cx.typeck_results(), rhs);
if F32(1.0) == value || F64(1.0) == value;
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &lhs.kind;
+ if let ExprKind::MethodCall(path, self_arg, ..) = &lhs.kind;
if cx.typeck_results().expr_ty(self_arg).is_floating_point();
if path.ident.name.as_str() == "exp";
then {
@@ -418,7 +419,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) {
"consider using",
format!(
"{}.exp_m1()",
- Sugg::hir(cx, self_arg, "..")
+ Sugg::hir(cx, self_arg, "..").maybe_par()
),
Applicability::MachineApplicable,
);
@@ -450,8 +451,8 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
) = &expr.kind
{
if let Some(parent) = get_parent_expr(cx, expr) {
- if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, args, _) = parent.kind {
- if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() {
+ if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, receiver, ..) = parent.kind {
+ if method_name.as_str() == "sqrt" && detect_hypot(cx, receiver).is_some() {
return;
}
}
@@ -550,11 +551,11 @@ fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) {
then {
let positive_abs_sugg = (
"manual implementation of `abs` method",
- format!("{}.abs()", Sugg::hir(cx, body, "..")),
+ format!("{}.abs()", Sugg::hir(cx, body, "..").maybe_par()),
);
let negative_abs_sugg = (
"manual implementation of negation of `abs` method",
- format!("-{}.abs()", Sugg::hir(cx, body, "..")),
+ format!("-{}.abs()", Sugg::hir(cx, body, "..").maybe_par()),
);
let sugg = if is_testing_positive(cx, cond, body) {
if if_expr_positive {
@@ -586,14 +587,14 @@ fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) {
fn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {
if_chain! {
- if let ExprKind::MethodCall(PathSegment { ident: method_name_a, .. }, args_a, _) = expr_a.kind;
- if let ExprKind::MethodCall(PathSegment { ident: method_name_b, .. }, args_b, _) = expr_b.kind;
+ if let ExprKind::MethodCall(PathSegment { ident: method_name_a, .. }, _, args_a, _) = expr_a.kind;
+ if let ExprKind::MethodCall(PathSegment { ident: method_name_b, .. }, _, args_b, _) = expr_b.kind;
then {
return method_name_a.as_str() == method_name_b.as_str() &&
args_a.len() == args_b.len() &&
(
["ln", "log2", "log10"].contains(&method_name_a.as_str()) ||
- method_name_a.as_str() == "log" && args_a.len() == 2 && eq_expr_value(cx, &args_a[1], &args_b[1])
+ method_name_a.as_str() == "log" && args_a.len() == 1 && eq_expr_value(cx, &args_a[0], &args_b[0])
);
}
}
@@ -612,8 +613,8 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) {
rhs,
) = &expr.kind;
if are_same_base_logs(cx, lhs, rhs);
- if let ExprKind::MethodCall(_, [largs_self, ..], _) = &lhs.kind;
- if let ExprKind::MethodCall(_, [rargs_self, ..], _) = &rhs.kind;
+ if let ExprKind::MethodCall(_, largs_self, ..) = &lhs.kind;
+ if let ExprKind::MethodCall(_, rargs_self, ..) = &rhs.kind;
then {
span_lint_and_sugg(
cx,
@@ -621,7 +622,7 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) {
expr.span,
"log base can be expressed more clearly",
"consider using",
- format!("{}.log({})", Sugg::hir(cx, largs_self, ".."), Sugg::hir(cx, rargs_self, ".."),),
+ format!("{}.log({})", Sugg::hir(cx, largs_self, "..").maybe_par(), Sugg::hir(cx, rargs_self, ".."),),
Applicability::MachineApplicable,
);
}
@@ -651,7 +652,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) &&
(F32(180_f32) == lvalue || F64(180_f64) == lvalue)
{
- let mut proposal = format!("{}.to_degrees()", Sugg::hir(cx, mul_lhs, ".."));
+ let mut proposal = format!("{}.to_degrees()", Sugg::hir(cx, mul_lhs, "..").maybe_par());
if_chain! {
if let ExprKind::Lit(ref literal) = mul_lhs.kind;
if let ast::LitKind::Float(ref value, float_type) = literal.node;
@@ -677,7 +678,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
(F32(180_f32) == rvalue || F64(180_f64) == rvalue) &&
(F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue)
{
- let mut proposal = format!("{}.to_radians()", Sugg::hir(cx, mul_lhs, ".."));
+ let mut proposal = format!("{}.to_radians()", Sugg::hir(cx, mul_lhs, "..").maybe_par());
if_chain! {
if let ExprKind::Lit(ref literal) = mul_lhs.kind;
if let ast::LitKind::Float(ref value, float_type) = literal.node;
@@ -711,16 +712,16 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
return;
}
- if let ExprKind::MethodCall(path, args, _) = &expr.kind {
- let recv_ty = cx.typeck_results().expr_ty(&args[0]);
+ if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind {
+ let recv_ty = cx.typeck_results().expr_ty(receiver);
if recv_ty.is_floating_point() {
match path.ident.name.as_str() {
- "ln" => check_ln1p(cx, expr, args),
- "log" => check_log_base(cx, expr, args),
- "powf" => check_powf(cx, expr, args),
- "powi" => check_powi(cx, expr, args),
- "sqrt" => check_hypot(cx, expr, args),
+ "ln" => check_ln1p(cx, expr, receiver),
+ "log" => check_log_base(cx, expr, receiver, args),
+ "powf" => check_powf(cx, expr, receiver, args),
+ "powi" => check_powi(cx, expr, receiver, args),
+ "sqrt" => check_hypot(cx, expr, receiver),
_ => {},
}
}
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index 925a8cb8d..0c5851cdb 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
-use clippy_utils::source::{snippet_opt, snippet_with_applicability};
+use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -56,29 +56,27 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
};
let mut applicability = Applicability::MachineApplicable;
- if format_args.value_args.is_empty() {
- match *format_args.format_string_parts {
+ if format_args.args.is_empty() {
+ match *format_args.format_string.parts {
[] => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability),
[_] => {
- if let Some(s_src) = snippet_opt(cx, format_args.format_string_span) {
- // Simulate macro expansion, converting {{ and }} to { and }.
- let s_expand = s_src.replace("{{", "{").replace("}}", "}");
- let sugg = format!("{}.to_string()", s_expand);
- span_useless_format(cx, call_site, sugg, applicability);
- }
+ // Simulate macro expansion, converting {{ and }} to { and }.
+ let s_expand = format_args.format_string.snippet.replace("{{", "{").replace("}}", "}");
+ let sugg = format!("{}.to_string()", s_expand);
+ span_useless_format(cx, call_site, sugg, applicability);
},
[..] => {},
}
- } else if let [value] = *format_args.value_args {
+ } else if let [arg] = &*format_args.args {
+ let value = arg.param.value;
if_chain! {
- if format_args.format_string_parts == [kw::Empty];
+ if format_args.format_string.parts == [kw::Empty];
if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
ty::Str => true,
_ => false,
};
- if let Some(args) = format_args.args();
- if args.iter().all(|arg| arg.format_trait == sym::Display && !arg.has_string_formatting());
+ if !arg.format.has_string_formatting();
then {
let is_new_string = match value.kind {
ExprKind::Binary(..) => true,
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 1e6feaac2..2a55c48cf 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -1,11 +1,12 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::is_diag_trait_item;
-use clippy_utils::macros::{is_format_macro, FormatArgsArg, FormatArgsExpn};
+use clippy_utils::macros::{is_format_macro, FormatArgsExpn};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
use if_chain::if_chain;
+use itertools::Itertools;
use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, HirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
use rustc_middle::ty::Ty;
@@ -74,20 +75,16 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
if let Some(macro_def_id) = outermost_expn_data.macro_def_id;
if is_format_macro(cx, macro_def_id);
if let ExpnKind::Macro(_, name) = outermost_expn_data.kind;
- if let Some(args) = format_args.args();
then {
- for (i, arg) in args.iter().enumerate() {
- if arg.format_trait != sym::Display {
+ for arg in &format_args.args {
+ if arg.format.has_string_formatting() {
continue;
}
- if arg.has_string_formatting() {
+ if is_aliased(&format_args, arg.param.value.hir_id) {
continue;
}
- if is_aliased(&args, i) {
- continue;
- }
- check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.value);
- check_to_string_in_format_args(cx, name, arg.value);
+ check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value);
+ check_to_string_in_format_args(cx, name, arg.param.value);
}
}
}
@@ -102,7 +99,12 @@ fn outermost_expn_data(expn_data: ExpnData) -> ExpnData {
}
}
-fn check_format_in_format_args(cx: &LateContext<'_>, call_site: Span, name: Symbol, arg: &Expr<'_>) {
+fn check_format_in_format_args(
+ cx: &LateContext<'_>,
+ call_site: Span,
+ name: Symbol,
+ arg: &Expr<'_>,
+) {
let expn_data = arg.span.ctxt().outer_expn_data();
if expn_data.call_site.from_expansion() {
return;
@@ -129,50 +131,58 @@ fn check_format_in_format_args(cx: &LateContext<'_>, call_site: Span, name: Symb
fn check_to_string_in_format_args(cx: &LateContext<'_>, name: Symbol, value: &Expr<'_>) {
if_chain! {
if !value.span.from_expansion();
- if let ExprKind::MethodCall(_, [receiver], _) = value.kind;
+ if let ExprKind::MethodCall(_, receiver, [], _) = value.kind;
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id);
if is_diag_trait_item(cx, method_def_id, sym::ToString);
let receiver_ty = cx.typeck_results().expr_ty(receiver);
if let Some(display_trait_id) = cx.tcx.get_diagnostic_item(sym::Display);
+ let (n_needed_derefs, target) =
+ count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter());
+ if implements_trait(cx, target, display_trait_id, &[]);
+ if let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait();
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
then {
- let (n_needed_derefs, target) = count_needed_derefs(
- receiver_ty,
- cx.typeck_results().expr_adjustments(receiver).iter(),
- );
- if implements_trait(cx, target, display_trait_id, &[]) {
- if n_needed_derefs == 0 {
- span_lint_and_sugg(
- cx,
- TO_STRING_IN_FORMAT_ARGS,
- value.span.with_lo(receiver.span.hi()),
- &format!("`to_string` applied to a type that implements `Display` in `{}!` args", name),
- "remove this",
- String::new(),
- Applicability::MachineApplicable,
- );
- } else {
- span_lint_and_sugg(
- cx,
- TO_STRING_IN_FORMAT_ARGS,
- value.span,
- &format!("`to_string` applied to a type that implements `Display` in `{}!` args", name),
- "use this",
- format!("{:*>width$}{}", "", receiver_snippet, width = n_needed_derefs),
- Applicability::MachineApplicable,
- );
- }
+ let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]);
+ if n_needed_derefs == 0 && !needs_ref {
+ span_lint_and_sugg(
+ cx,
+ TO_STRING_IN_FORMAT_ARGS,
+ value.span.with_lo(receiver.span.hi()),
+ &format!(
+ "`to_string` applied to a type that implements `Display` in `{}!` args",
+ name
+ ),
+ "remove this",
+ String::new(),
+ Applicability::MachineApplicable,
+ );
+ } else {
+ span_lint_and_sugg(
+ cx,
+ TO_STRING_IN_FORMAT_ARGS,
+ value.span,
+ &format!(
+ "`to_string` applied to a type that implements `Display` in `{}!` args",
+ name
+ ),
+ "use this",
+ format!(
+ "{}{:*>width$}{}",
+ if needs_ref { "&" } else { "" },
+ "",
+ receiver_snippet,
+ width = n_needed_derefs
+ ),
+ Applicability::MachineApplicable,
+ );
}
}
}
}
-// Returns true if `args[i]` "refers to" or "is referred to by" another argument.
-fn is_aliased(args: &[FormatArgsArg<'_>], i: usize) -> bool {
- let value = args[i].value;
- args.iter()
- .enumerate()
- .any(|(j, arg)| i != j && std::ptr::eq(value, arg.value))
+// Returns true if `hir_id` is referred to by multiple format params
+fn is_aliased(args: &FormatArgsExpn<'_>, hir_id: HirId) -> bool {
+ args.params().filter(|param| param.value.hir_id == hir_id).at_most_one().is_err()
}
fn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>)
@@ -182,11 +192,7 @@ where
let mut n_total = 0;
let mut n_needed = 0;
loop {
- if let Some(Adjustment {
- kind: Adjust::Deref(overloaded_deref),
- target,
- }) = iter.next()
- {
+ if let Some(Adjustment { kind: Adjust::Deref(overloaded_deref), target }) = iter.next() {
n_total += 1;
if overloaded_deref.is_some() {
n_needed = n_total;
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index 04b5be6c8..b628fd9f7 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
-use clippy_utils::macros::{is_format_macro, root_macro_call_first_node, FormatArgsArg, FormatArgsExpn};
+use clippy_utils::macros::{is_format_macro, root_macro_call_first_node, FormatArg, FormatArgsExpn};
use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators};
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -139,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatImpl {
fn check_to_string_in_display(cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
// Get the hir_id of the object we are calling the method on
- if let ExprKind::MethodCall(path, [ref self_arg, ..], _) = expr.kind;
+ if let ExprKind::MethodCall(path, self_arg, ..) = expr.kind;
// Is the method to_string() ?
if path.ident.name == sym::to_string;
// Is the method a part of the ToString trait? (i.e. not to_string() implemented
@@ -168,10 +168,9 @@ fn check_self_in_format_args<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>,
if let macro_def_id = outer_macro.def_id;
if let Some(format_args) = FormatArgsExpn::find_nested(cx, expr, outer_macro.expn);
if is_format_macro(cx, macro_def_id);
- if let Some(args) = format_args.args();
then {
- for arg in args {
- if arg.format_trait != impl_trait.name {
+ for arg in format_args.args {
+ if arg.format.r#trait != impl_trait.name {
continue;
}
check_format_arg_self(cx, expr, &arg, impl_trait);
@@ -180,11 +179,11 @@ fn check_self_in_format_args<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>,
}
}
-fn check_format_arg_self(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &FormatArgsArg<'_>, impl_trait: FormatTrait) {
+fn check_format_arg_self(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &FormatArg<'_>, impl_trait: FormatTrait) {
// Handle multiple dereferencing of references e.g. &&self
// Handle dereference of &self -> self that is equivalent (i.e. via *self in fmt() impl)
// Since the argument to fmt is itself a reference: &self
- let reference = peel_ref_operators(cx, arg.value);
+ let reference = peel_ref_operators(cx, arg.param.value);
let map = cx.tcx.hir();
// Is the reference self?
if path_to_local(reference).map(|x| map.name(x)) == Some(kw::SelfLower) {
diff --git a/src/tools/clippy/clippy_lints/src/format_push_string.rs b/src/tools/clippy/clippy_lints/src/format_push_string.rs
index ebf5ab086..9b9f1872b 100644
--- a/src/tools/clippy/clippy_lints/src/format_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs
@@ -54,7 +54,7 @@ fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
impl<'tcx> LateLintPass<'tcx> for FormatPushString {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let arg = match expr.kind {
- ExprKind::MethodCall(_, [_, arg], _) => {
+ ExprKind::MethodCall(_, _, [arg], _) => {
if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) &&
match_def_path(cx, fn_def_id, &paths::PUSH_STR) {
arg
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index db0166da5..01cefe4af 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -1,4 +1,5 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
+use clippy_utils::is_span_if;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
@@ -297,12 +298,11 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) {
fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
if_chain! {
if !first.span.from_expansion() && !second.span.from_expansion();
- if let ExprKind::If(cond_expr, ..) = &first.kind;
+ if matches!(first.kind, ExprKind::If(..));
if is_block(second) || is_if(second);
// Proc-macros can give weird spans. Make sure this is actually an `if`.
- if let Some(if_snip) = snippet_opt(cx, first.span.until(cond_expr.span));
- if if_snip.starts_with("if");
+ if is_span_if(cx, first.span);
// If there is a line break between the two expressions, don't lint.
// If there is a non-whitespace character, this span came from a proc-macro.
diff --git a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
index 57b075132..74941d817 100644
--- a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
+++ b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
@@ -46,7 +46,7 @@ declare_lint_pass!(FromStrRadix10 => [FROM_STR_RADIX_10]);
impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
fn check_expr(&mut self, cx: &LateContext<'tcx>, exp: &Expr<'tcx>) {
if_chain! {
- if let ExprKind::Call(maybe_path, arguments) = &exp.kind;
+ if let ExprKind::Call(maybe_path, [src, radix]) = &exp.kind;
if let ExprKind::Path(QPath::TypeRelative(ty, pathseg)) = &maybe_path.kind;
// check if the first part of the path is some integer primitive
@@ -60,20 +60,19 @@ impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
if pathseg.ident.name.as_str() == "from_str_radix";
// check if the second argument is a primitive `10`
- if arguments.len() == 2;
- if let ExprKind::Lit(lit) = &arguments[1].kind;
+ if let ExprKind::Lit(lit) = &radix.kind;
if let rustc_ast::ast::LitKind::Int(10, _) = lit.node;
then {
- let expr = if let ExprKind::AddrOf(_, _, expr) = &arguments[0].kind {
+ let expr = if let ExprKind::AddrOf(_, _, expr) = &src.kind {
let ty = cx.typeck_results().expr_ty(expr);
if is_ty_stringish(cx, ty) {
expr
} else {
- &arguments[0]
+ &src
}
} else {
- &arguments[0]
+ &src
};
let sugg = Sugg::hir_with_applicability(
diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs
index 73261fb8a..90911e0bf 100644
--- a/src/tools/clippy/clippy_lints/src/functions/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs
@@ -1,6 +1,6 @@
mod must_use;
mod not_unsafe_ptr_arg_deref;
-mod result_unit_err;
+mod result;
mod too_many_arguments;
mod too_many_lines;
@@ -217,17 +217,62 @@ declare_clippy_lint! {
"public function returning `Result` with an `Err` type of `()`"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for functions that return `Result` with an unusually large
+ /// `Err`-variant.
+ ///
+ /// ### Why is this bad?
+ /// A `Result` is at least as large as the `Err`-variant. While we
+ /// expect that variant to be seldomly used, the compiler needs to reserve
+ /// and move that much memory every single time.
+ ///
+ /// ### Known problems
+ /// The size determined by Clippy is platform-dependent.
+ ///
+ /// ### Examples
+ /// ```rust
+ /// pub enum ParseError {
+ /// UnparsedBytes([u8; 512]),
+ /// UnexpectedEof,
+ /// }
+ ///
+ /// // The `Result` has at least 512 bytes, even in the `Ok`-case
+ /// pub fn parse() -> Result<(), ParseError> {
+ /// Ok(())
+ /// }
+ /// ```
+ /// should be
+ /// ```
+ /// pub enum ParseError {
+ /// UnparsedBytes(Box<[u8; 512]>),
+ /// UnexpectedEof,
+ /// }
+ ///
+ /// // The `Result` is slightly larger than a pointer
+ /// pub fn parse() -> Result<(), ParseError> {
+ /// Ok(())
+ /// }
+ /// ```
+ #[clippy::version = "1.64.0"]
+ pub RESULT_LARGE_ERR,
+ perf,
+ "function returning `Result` with large `Err` type"
+}
+
#[derive(Copy, Clone)]
pub struct Functions {
too_many_arguments_threshold: u64,
too_many_lines_threshold: u64,
+ large_error_threshold: u64,
}
impl Functions {
- pub fn new(too_many_arguments_threshold: u64, too_many_lines_threshold: u64) -> Self {
+ pub fn new(too_many_arguments_threshold: u64, too_many_lines_threshold: u64, large_error_threshold: u64) -> Self {
Self {
too_many_arguments_threshold,
too_many_lines_threshold,
+ large_error_threshold,
}
}
}
@@ -240,6 +285,7 @@ impl_lint_pass!(Functions => [
DOUBLE_MUST_USE,
MUST_USE_CANDIDATE,
RESULT_UNIT_ERR,
+ RESULT_LARGE_ERR,
]);
impl<'tcx> LateLintPass<'tcx> for Functions {
@@ -259,18 +305,18 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
must_use::check_item(cx, item);
- result_unit_err::check_item(cx, item);
+ result::check_item(cx, item, self.large_error_threshold);
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
must_use::check_impl_item(cx, item);
- result_unit_err::check_impl_item(cx, item);
+ result::check_impl_item(cx, item, self.large_error_threshold);
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold);
not_unsafe_ptr_arg_deref::check_trait_item(cx, item);
must_use::check_trait_item(cx, item);
- result_unit_err::check_trait_item(cx, item);
+ result::check_trait_item(cx, item, self.large_error_threshold);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 6672a6cb0..00a493776 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -212,7 +212,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> {
return;
}
match expr.kind {
- Call(_, args) | MethodCall(_, args, _) => {
+ Call(_, args) => {
let mut tys = DefIdSet::default();
for arg in args {
if self.cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
@@ -230,6 +230,24 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> {
tys.clear();
}
},
+ MethodCall(_, receiver, args, _) => {
+ let mut tys = DefIdSet::default();
+ for arg in std::iter::once(receiver).chain(args.iter()) {
+ if self.cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
+ && is_mutable_ty(
+ self.cx,
+ self.cx.tcx.typeck(arg.hir_id.owner).expr_ty(arg),
+ arg.span,
+ &mut tys,
+ )
+ && is_mutated_static(arg)
+ {
+ self.mutates_static = true;
+ return;
+ }
+ tys.clear();
+ }
+ },
Assign(target, ..) | AssignOp(_, target, _) | AddrOf(_, hir::Mutability::Mut, target) => {
self.mutates_static |= is_mutated_static(target);
},
@@ -254,6 +272,6 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
cx,
mutates_static: false,
};
- intravisit::walk_expr(&mut v, &body.value);
+ intravisit::walk_expr(&mut v, body.value);
v.mutates_static
}
diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index 565a1c871..3bbfa52e8 100644
--- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -88,11 +88,12 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
}
}
},
- hir::ExprKind::MethodCall(_, args, _) => {
+ hir::ExprKind::MethodCall(_, receiver, args, _) => {
let def_id = self.typeck_results.type_dependent_def_id(expr.hir_id).unwrap();
let base_type = self.cx.tcx.type_of(def_id);
if type_is_unsafe_function(self.cx, base_type) {
+ self.check_arg(receiver);
for arg in args {
self.check_arg(arg);
}
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
new file mode 100644
index 000000000..9591405cb
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -0,0 +1,100 @@
+use rustc_errors::Diagnostic;
+use rustc_hir as hir;
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::{self, Ty};
+use rustc_span::{sym, Span};
+
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
+use clippy_utils::trait_ref_of_method;
+use clippy_utils::ty::{approx_ty_size, is_type_diagnostic_item};
+
+use super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};
+
+/// The type of the `Err`-variant in a `std::result::Result` returned by the
+/// given `FnDecl`
+fn result_err_ty<'tcx>(
+ cx: &LateContext<'tcx>,
+ decl: &hir::FnDecl<'tcx>,
+ id: hir::def_id::LocalDefId,
+ item_span: Span,
+) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
+ if !in_external_macro(cx.sess(), item_span)
+ && let hir::FnRetTy::Return(hir_ty) = decl.output
+ && let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).output())
+ && is_type_diagnostic_item(cx, ty, sym::Result)
+ && let ty::Adt(_, substs) = ty.kind()
+ {
+ let err_ty = substs.type_at(1);
+ Some((hir_ty, err_ty))
+ } else {
+ None
+ }
+}
+
+pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64) {
+ if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind
+ && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id, item.span)
+ {
+ if cx.access_levels.is_exported(item.def_id) {
+ let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
+ check_result_unit_err(cx, err_ty, fn_header_span);
+ }
+ check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
+ }
+}
+
+pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem<'tcx>, large_err_threshold: u64) {
+ // Don't lint if method is a trait's implementation, we can't do anything about those
+ if let hir::ImplItemKind::Fn(ref sig, _) = item.kind
+ && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id, item.span)
+ && trait_ref_of_method(cx, item.def_id).is_none()
+ {
+ if cx.access_levels.is_exported(item.def_id) {
+ let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
+ check_result_unit_err(cx, err_ty, fn_header_span);
+ }
+ check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
+ }
+}
+
+pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::TraitItem<'tcx>, large_err_threshold: u64) {
+ if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
+ let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
+ if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id, item.span) {
+ if cx.access_levels.is_exported(item.def_id) {
+ check_result_unit_err(cx, err_ty, fn_header_span);
+ }
+ check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
+ }
+ }
+}
+
+fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: Span) {
+ if err_ty.is_unit() {
+ span_lint_and_help(
+ cx,
+ RESULT_UNIT_ERR,
+ fn_header_span,
+ "this returns a `Result<_, ()>`",
+ None,
+ "use a custom `Error` type instead",
+ );
+ }
+}
+
+fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) {
+ let ty_size = approx_ty_size(cx, err_ty);
+ if ty_size >= large_err_threshold {
+ span_lint_and_then(
+ cx,
+ RESULT_LARGE_ERR,
+ hir_ty_span,
+ "the `Err`-variant returned from this function is very large",
+ |diag: &mut Diagnostic| {
+ diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
+ diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+ },
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/functions/result_unit_err.rs b/src/tools/clippy/clippy_lints/src/functions/result_unit_err.rs
deleted file mode 100644
index 2e63a1f92..000000000
--- a/src/tools/clippy/clippy_lints/src/functions/result_unit_err.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-use rustc_hir as hir;
-use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty;
-use rustc_span::{sym, Span};
-use rustc_typeck::hir_ty_to_ty;
-
-use if_chain::if_chain;
-
-use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::trait_ref_of_method;
-use clippy_utils::ty::is_type_diagnostic_item;
-
-use super::RESULT_UNIT_ERR;
-
-pub(super) fn check_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
- if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind {
- let is_public = cx.access_levels.is_exported(item.def_id);
- let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
- if is_public {
- check_result_unit_err(cx, sig.decl, item.span, fn_header_span);
- }
- }
-}
-
-pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &hir::ImplItem<'_>) {
- if let hir::ImplItemKind::Fn(ref sig, _) = item.kind {
- let is_public = cx.access_levels.is_exported(item.def_id);
- let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
- if is_public && trait_ref_of_method(cx, item.def_id).is_none() {
- check_result_unit_err(cx, sig.decl, item.span, fn_header_span);
- }
- }
-}
-
-pub(super) fn check_trait_item(cx: &LateContext<'_>, item: &hir::TraitItem<'_>) {
- if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
- let is_public = cx.access_levels.is_exported(item.def_id);
- let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
- if is_public {
- check_result_unit_err(cx, sig.decl, item.span, fn_header_span);
- }
- }
-}
-
-fn check_result_unit_err(cx: &LateContext<'_>, decl: &hir::FnDecl<'_>, item_span: Span, fn_header_span: Span) {
- if_chain! {
- if !in_external_macro(cx.sess(), item_span);
- if let hir::FnRetTy::Return(ty) = decl.output;
- let ty = hir_ty_to_ty(cx.tcx, ty);
- if is_type_diagnostic_item(cx, ty, sym::Result);
- if let ty::Adt(_, substs) = ty.kind();
- let err_ty = substs.type_at(1);
- if err_ty.is_unit();
- then {
- span_lint_and_help(
- cx,
- RESULT_UNIT_ERR,
- fn_header_span,
- "this returns a `Result<_, ()>`",
- None,
- "use a custom `Error` type instead",
- );
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs
index 5c46d6c7d..ef7d75aa8 100644
--- a/src/tools/clippy/clippy_lints/src/future_not_send.rs
+++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::{EarlyBinder, Opaque, PredicateKind::Trait};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span};
use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
-use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine};
+use rustc_trait_selection::traits::{self, FulfillmentError};
declare_clippy_lint! {
/// ### What it does
@@ -80,9 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
let span = decl.output.span();
let send_errors = cx.tcx.infer_ctxt().enter(|infcx| {
let cause = traits::ObligationCause::misc(span, hir_id);
- let mut fulfillment_cx = traits::FulfillmentContext::new();
- fulfillment_cx.register_bound(&infcx, cx.param_env, ret_ty, send_trait, cause);
- fulfillment_cx.select_all_or_error(&infcx)
+ traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait)
});
if !send_errors.is_empty() {
span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/get_first.rs b/src/tools/clippy/clippy_lints/src/get_first.rs
deleted file mode 100644
index 529f7baba..000000000
--- a/src/tools/clippy/clippy_lints/src/get_first.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_slice_of_primitives, match_def_path, paths};
-use if_chain::if_chain;
-use rustc_ast::LitKind;
-use rustc_errors::Applicability;
-use rustc_hir as hir;
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Spanned;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for using `x.get(0)` instead of
- /// `x.first()`.
- ///
- /// ### Why is this bad?
- /// Using `x.first()` is easier to read and has the same
- /// result.
- ///
- /// ### Example
- /// ```rust
- /// let x = vec![2, 3, 5];
- /// let first_element = x.get(0);
- /// ```
- ///
- /// Use instead:
- /// ```rust
- /// let x = vec![2, 3, 5];
- /// let first_element = x.first();
- /// ```
- #[clippy::version = "1.63.0"]
- pub GET_FIRST,
- style,
- "Using `x.get(0)` when `x.first()` is simpler"
-}
-declare_lint_pass!(GetFirst => [GET_FIRST]);
-
-impl<'tcx> LateLintPass<'tcx> for GetFirst {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if_chain! {
- if let hir::ExprKind::MethodCall(_, [struct_calling_on, method_arg], _) = &expr.kind;
- if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
- if match_def_path(cx, expr_def_id, &paths::SLICE_GET);
-
- if let Some(_) = is_slice_of_primitives(cx, struct_calling_on);
- if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = method_arg.kind;
-
- then {
- let mut applicability = Applicability::MachineApplicable;
- let slice_name = snippet_with_applicability(
- cx,
- struct_calling_on.span, "..",
- &mut applicability,
- );
- span_lint_and_sugg(
- cx,
- GET_FIRST,
- expr.span,
- &format!("accessing first element with `{0}.get(0)`", slice_name),
- "try",
- format!("{}.first()", slice_name),
- applicability,
- );
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
index e95017007..9ea8c494c 100644
--- a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
+++ b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
@@ -1,8 +1,9 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::SpanlessEq;
use if_chain::if_chain;
+use rustc_errors::Diagnostic;
use rustc_hir::intravisit::{self as visit, Visitor};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
@@ -45,16 +46,8 @@ declare_lint_pass!(IfLetMutex => [IF_LET_MUTEX]);
impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- let mut arm_visit = ArmVisitor {
- mutex_lock_called: false,
- found_mutex: None,
- cx,
- };
- let mut op_visit = OppVisitor {
- mutex_lock_called: false,
- found_mutex: None,
- cx,
- };
+ let mut arm_visit = ArmVisitor { found_mutex: None, cx };
+ let mut op_visit = OppVisitor { found_mutex: None, cx };
if let Some(higher::IfLet {
let_expr,
if_then,
@@ -63,18 +56,28 @@ impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
}) = higher::IfLet::hir(cx, expr)
{
op_visit.visit_expr(let_expr);
- if op_visit.mutex_lock_called {
+ if let Some(op_mutex) = op_visit.found_mutex {
arm_visit.visit_expr(if_then);
arm_visit.visit_expr(if_else);
- if arm_visit.mutex_lock_called && arm_visit.same_mutex(cx, op_visit.found_mutex.unwrap()) {
- span_lint_and_help(
+ if let Some(arm_mutex) = arm_visit.found_mutex_if_same_as(op_mutex) {
+ let diag = |diag: &mut Diagnostic| {
+ diag.span_label(
+ op_mutex.span,
+ "this Mutex will remain locked for the entire `if let`-block...",
+ );
+ diag.span_label(
+ arm_mutex.span,
+ "... and is tried to lock again here, which will always deadlock.",
+ );
+ diag.help("move the lock call outside of the `if let ...` expression");
+ };
+ span_lint_and_then(
cx,
IF_LET_MUTEX,
expr.span,
"calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock",
- None,
- "move the lock call outside of the `if let ...` expression",
+ diag,
);
}
}
@@ -84,7 +87,6 @@ impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
/// Checks if `Mutex::lock` is called in the `if let` expr.
pub struct OppVisitor<'a, 'tcx> {
- mutex_lock_called: bool,
found_mutex: Option<&'tcx Expr<'tcx>>,
cx: &'a LateContext<'tcx>,
}
@@ -93,7 +95,6 @@ impl<'tcx> Visitor<'tcx> for OppVisitor<'_, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
if let Some(mutex) = is_mutex_lock_call(self.cx, expr) {
self.found_mutex = Some(mutex);
- self.mutex_lock_called = true;
return;
}
visit::walk_expr(self, expr);
@@ -102,7 +103,6 @@ impl<'tcx> Visitor<'tcx> for OppVisitor<'_, 'tcx> {
/// Checks if `Mutex::lock` is called in any of the branches.
pub struct ArmVisitor<'a, 'tcx> {
- mutex_lock_called: bool,
found_mutex: Option<&'tcx Expr<'tcx>>,
cx: &'a LateContext<'tcx>,
}
@@ -111,7 +111,6 @@ impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if let Some(mutex) = is_mutex_lock_call(self.cx, expr) {
self.found_mutex = Some(mutex);
- self.mutex_lock_called = true;
return;
}
visit::walk_expr(self, expr);
@@ -119,17 +118,20 @@ impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> {
}
impl<'tcx, 'l> ArmVisitor<'tcx, 'l> {
- fn same_mutex(&self, cx: &LateContext<'_>, op_mutex: &Expr<'_>) -> bool {
- self.found_mutex
- .map_or(false, |arm_mutex| SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex))
+ fn found_mutex_if_same_as(&self, op_mutex: &Expr<'_>) -> Option<&Expr<'_>> {
+ self.found_mutex.and_then(|arm_mutex| {
+ SpanlessEq::new(self.cx)
+ .eq_expr(op_mutex, arm_mutex)
+ .then_some(arm_mutex)
+ })
}
}
fn is_mutex_lock_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
if_chain! {
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &expr.kind;
+ if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
if path.ident.as_str() == "lock";
- let ty = cx.typeck_results().expr_ty(self_arg);
+ let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
if is_type_diagnostic_item(cx, ty, sym::Mutex);
then {
Some(self_arg)
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index b8d227855..11c432478 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::eager_or_lazy::switch_to_eager_eval;
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::{contains_return, higher, is_else_clause, is_lang_ctor, meets_msrv, msrvs, peel_blocks};
-use if_chain::if_chain;
use rustc_hir::LangItem::{OptionNone, OptionSome};
use rustc_hir::{Expr, ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -11,10 +11,12 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
/// ### What it does
- /// Checks for if-else that could be written to `bool::then`.
+ /// Checks for if-else that could be written using either `bool::then` or `bool::then_some`.
///
/// ### Why is this bad?
- /// Looks a little redundant. Using `bool::then` helps it have less lines of code.
+ /// Looks a little redundant. Using `bool::then` is more concise and incurs no loss of clarity.
+ /// For simple calculations and known values, use `bool::then_some`, which is eagerly evaluated
+ /// in comparison to `bool::then`.
///
/// ### Example
/// ```rust
@@ -39,7 +41,7 @@ declare_clippy_lint! {
#[clippy::version = "1.53.0"]
pub IF_THEN_SOME_ELSE_NONE,
restriction,
- "Finds if-else that could be written using `bool::then`"
+ "Finds if-else that could be written using either `bool::then` or `bool::then_some`"
}
pub struct IfThenSomeElseNone {
@@ -56,7 +58,7 @@ impl IfThenSomeElseNone {
impl_lint_pass!(IfThenSomeElseNone => [IF_THEN_SOME_ELSE_NONE]);
impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if !meets_msrv(self.msrv, msrvs::BOOL_THEN) {
return;
}
@@ -70,43 +72,47 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
return;
}
- if_chain! {
- if let Some(higher::If { cond, then, r#else: Some(els) }) = higher::If::hir(expr);
- if let ExprKind::Block(then_block, _) = then.kind;
- if let Some(then_expr) = then_block.expr;
- if let ExprKind::Call(then_call, [then_arg]) = then_expr.kind;
- if let ExprKind::Path(ref then_call_qpath) = then_call.kind;
- if is_lang_ctor(cx, then_call_qpath, OptionSome);
- if let ExprKind::Path(ref qpath) = peel_blocks(els).kind;
- if is_lang_ctor(cx, qpath, OptionNone);
- if !stmts_contains_early_return(then_block.stmts);
- then {
- let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]");
- let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) {
- format!("({})", cond_snip)
- } else {
- cond_snip.into_owned()
- };
- let arg_snip = snippet_with_macro_callsite(cx, then_arg.span, "");
- let closure_body = if then_block.stmts.is_empty() {
- arg_snip.into_owned()
- } else {
- format!("{{ /* snippet */ {} }}", arg_snip)
- };
- let help = format!(
- "consider using `bool::then` like: `{}.then(|| {})`",
- cond_snip,
- closure_body,
- );
- span_lint_and_help(
- cx,
- IF_THEN_SOME_ELSE_NONE,
- expr.span,
- "this could be simplified with `bool::then`",
- None,
- &help,
- );
- }
+ if let Some(higher::If { cond, then, r#else: Some(els) }) = higher::If::hir(expr)
+ && let ExprKind::Block(then_block, _) = then.kind
+ && let Some(then_expr) = then_block.expr
+ && let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
+ && let ExprKind::Path(ref then_call_qpath) = then_call.kind
+ && is_lang_ctor(cx, then_call_qpath, OptionSome)
+ && let ExprKind::Path(ref qpath) = peel_blocks(els).kind
+ && is_lang_ctor(cx, qpath, OptionNone)
+ && !stmts_contains_early_return(then_block.stmts)
+ {
+ let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]");
+ let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) {
+ format!("({})", cond_snip)
+ } else {
+ cond_snip.into_owned()
+ };
+ let arg_snip = snippet_with_macro_callsite(cx, then_arg.span, "");
+ let mut method_body = if then_block.stmts.is_empty() {
+ arg_snip.into_owned()
+ } else {
+ format!("{{ /* snippet */ {} }}", arg_snip)
+ };
+ let method_name = if switch_to_eager_eval(cx, expr) && meets_msrv(self.msrv, msrvs::BOOL_THEN_SOME) {
+ "then_some"
+ } else {
+ method_body.insert_str(0, "|| ");
+ "then"
+ };
+
+ let help = format!(
+ "consider using `bool::{}` like: `{}.{}({})`",
+ method_name, cond_snip, method_name, method_body,
+ );
+ span_lint_and_help(
+ cx,
+ IF_THEN_SOME_ELSE_NONE,
+ expr.span,
+ &format!("this could be simplified with `bool::{}`", method_name),
+ None,
+ &help,
+ );
}
}
diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs
index a6610ade3..feec8ec2e 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_return.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs
@@ -232,7 +232,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
return;
}
- let res_ty = cx.typeck_results().expr_ty(&body.value);
+ let res_ty = cx.typeck_results().expr_ty(body.value);
if res_ty.is_unit() || res_ty.is_never() {
return;
}
@@ -243,7 +243,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
None => return,
}
} else {
- &body.value
+ body.value
};
lint_implicit_returns(cx, expr, expr.span.ctxt(), None);
}
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index d0c6495e3..0dd7f5bf0 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -95,12 +95,14 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
let mut removed_pat: FxHashSet<hir::HirId> = FxHashSet::default();
let mut slices: FxIndexMap<hir::HirId, SliceLintInformation> = FxIndexMap::default();
pat.walk_always(|pat| {
- if let hir::PatKind::Binding(binding, value_hir_id, ident, sub_pat) = pat.kind {
- // We'll just ignore mut and ref mut for simplicity sake right now
- if let hir::BindingAnnotation::Mutable | hir::BindingAnnotation::RefMut = binding {
- return;
- }
-
+ // We'll just ignore mut and ref mut for simplicity sake right now
+ if let hir::PatKind::Binding(
+ hir::BindingAnnotation(by_ref, hir::Mutability::Not),
+ value_hir_id,
+ ident,
+ sub_pat,
+ ) = pat.kind
+ {
// This block catches bindings with sub patterns. It would be hard to build a correct suggestion
// for them and it's likely that the user knows what they are doing in such a case.
if removed_pat.contains(&value_hir_id) {
@@ -116,7 +118,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
if let ty::Slice(inner_ty) | ty::Array(inner_ty, _) = bound_ty.peel_refs().kind() {
// The values need to use the `ref` keyword if they can't be copied.
// This will need to be adjusted if the lint want to support mutable access in the future
- let src_is_ref = bound_ty.is_ref() && binding != hir::BindingAnnotation::Ref;
+ let src_is_ref = bound_ty.is_ref() && by_ref != hir::ByRef::Yes;
let needs_ref = !(src_is_ref || is_copy(cx, *inner_ty));
let slice_info = slices
diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
index 01c7eef4e..8c2c96fa1 100644
--- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
@@ -123,45 +123,45 @@ use self::Heuristic::{All, Always, Any, First};
/// is an upper bound, e.g., some methods can return a possibly
/// infinite iterator at worst, e.g., `take_while`.
const HEURISTICS: [(&str, usize, Heuristic, Finiteness); 19] = [
- ("zip", 2, All, Infinite),
- ("chain", 2, Any, Infinite),
- ("cycle", 1, Always, Infinite),
- ("map", 2, First, Infinite),
- ("by_ref", 1, First, Infinite),
- ("cloned", 1, First, Infinite),
- ("rev", 1, First, Infinite),
- ("inspect", 1, First, Infinite),
- ("enumerate", 1, First, Infinite),
- ("peekable", 2, First, Infinite),
- ("fuse", 1, First, Infinite),
- ("skip", 2, First, Infinite),
- ("skip_while", 1, First, Infinite),
- ("filter", 2, First, Infinite),
- ("filter_map", 2, First, Infinite),
- ("flat_map", 2, First, Infinite),
- ("unzip", 1, First, Infinite),
- ("take_while", 2, First, MaybeInfinite),
- ("scan", 3, First, MaybeInfinite),
+ ("zip", 1, All, Infinite),
+ ("chain", 1, Any, Infinite),
+ ("cycle", 0, Always, Infinite),
+ ("map", 1, First, Infinite),
+ ("by_ref", 0, First, Infinite),
+ ("cloned", 0, First, Infinite),
+ ("rev", 0, First, Infinite),
+ ("inspect", 0, First, Infinite),
+ ("enumerate", 0, First, Infinite),
+ ("peekable", 1, First, Infinite),
+ ("fuse", 0, First, Infinite),
+ ("skip", 1, First, Infinite),
+ ("skip_while", 0, First, Infinite),
+ ("filter", 1, First, Infinite),
+ ("filter_map", 1, First, Infinite),
+ ("flat_map", 1, First, Infinite),
+ ("unzip", 0, First, Infinite),
+ ("take_while", 1, First, MaybeInfinite),
+ ("scan", 2, First, MaybeInfinite),
];
fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
match expr.kind {
- ExprKind::MethodCall(method, args, _) => {
+ ExprKind::MethodCall(method, receiver, args, _) => {
for &(name, len, heuristic, cap) in &HEURISTICS {
if method.ident.name.as_str() == name && args.len() == len {
return (match heuristic {
Always => Infinite,
- First => is_infinite(cx, &args[0]),
- Any => is_infinite(cx, &args[0]).or(is_infinite(cx, &args[1])),
- All => is_infinite(cx, &args[0]).and(is_infinite(cx, &args[1])),
+ First => is_infinite(cx, receiver),
+ Any => is_infinite(cx, receiver).or(is_infinite(cx, &args[0])),
+ All => is_infinite(cx, receiver).and(is_infinite(cx, &args[0])),
})
.and(cap);
}
}
- if method.ident.name == sym!(flat_map) && args.len() == 2 {
- if let ExprKind::Closure(&Closure { body, .. }) = args[1].kind {
+ if method.ident.name == sym!(flat_map) && args.len() == 1 {
+ if let ExprKind::Closure(&Closure { body, .. }) = args[0].kind {
let body = cx.tcx.hir().body(body);
- return is_infinite(cx, &body.value);
+ return is_infinite(cx, body.value);
}
}
Finite
@@ -179,29 +179,29 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
/// the names and argument lengths of methods that *may* exhaust their
/// iterators
const POSSIBLY_COMPLETING_METHODS: [(&str, usize); 6] = [
- ("find", 2),
- ("rfind", 2),
- ("position", 2),
- ("rposition", 2),
- ("any", 2),
- ("all", 2),
+ ("find", 1),
+ ("rfind", 1),
+ ("position", 1),
+ ("rposition", 1),
+ ("any", 1),
+ ("all", 1),
];
/// the names and argument lengths of methods that *always* exhaust
/// their iterators
const COMPLETING_METHODS: [(&str, usize); 12] = [
- ("count", 1),
- ("fold", 3),
- ("for_each", 2),
- ("partition", 2),
- ("max", 1),
- ("max_by", 2),
- ("max_by_key", 2),
- ("min", 1),
- ("min_by", 2),
- ("min_by_key", 2),
- ("sum", 1),
- ("product", 1),
+ ("count", 0),
+ ("fold", 2),
+ ("for_each", 1),
+ ("partition", 1),
+ ("max", 0),
+ ("max_by", 1),
+ ("max_by_key", 1),
+ ("min", 0),
+ ("min_by", 1),
+ ("min_by_key", 1),
+ ("sum", 0),
+ ("product", 0),
];
/// the paths of types that are known to be infinitely allocating
@@ -218,26 +218,26 @@ const INFINITE_COLLECTORS: &[Symbol] = &[
fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
match expr.kind {
- ExprKind::MethodCall(method, args, _) => {
+ ExprKind::MethodCall(method, receiver, args, _) => {
for &(name, len) in &COMPLETING_METHODS {
if method.ident.name.as_str() == name && args.len() == len {
- return is_infinite(cx, &args[0]);
+ return is_infinite(cx, receiver);
}
}
for &(name, len) in &POSSIBLY_COMPLETING_METHODS {
if method.ident.name.as_str() == name && args.len() == len {
- return MaybeInfinite.and(is_infinite(cx, &args[0]));
+ return MaybeInfinite.and(is_infinite(cx, receiver));
}
}
- if method.ident.name == sym!(last) && args.len() == 1 {
+ if method.ident.name == sym!(last) && args.is_empty() {
let not_double_ended = cx
.tcx
.get_diagnostic_item(sym::DoubleEndedIterator)
.map_or(false, |id| {
- !implements_trait(cx, cx.typeck_results().expr_ty(&args[0]), id, &[])
+ !implements_trait(cx, cx.typeck_results().expr_ty(receiver), id, &[])
});
if not_double_ended {
- return is_infinite(cx, &args[0]);
+ return is_infinite(cx, receiver);
}
} else if method.ident.name == sym!(collect) {
let ty = cx.typeck_results().expr_ty(expr);
@@ -245,7 +245,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
.iter()
.any(|diag_item| is_type_diagnostic_item(cx, ty, *diag_item))
{
- return is_infinite(cx, &args[0]);
+ return is_infinite(cx, receiver);
}
}
},
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index c58df126d..eb13d0869 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -1,13 +1,12 @@
//! lint when there is a large size difference between variants on an enum
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{diagnostics::span_lint_and_then, ty::is_copy};
+use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size, ty::is_copy};
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{Adt, Ty};
+use rustc_middle::ty::{Adt, AdtDef, GenericArg, List, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
@@ -17,7 +16,7 @@ declare_clippy_lint! {
/// `enum`s.
///
/// ### Why is this bad?
- /// Enum size is bounded by the largest variant. Having a
+ /// Enum size is bounded by the largest variant. Having one
/// large variant can penalize the memory layout of that enum.
///
/// ### Known problems
@@ -33,8 +32,9 @@ declare_clippy_lint! {
/// use case it may be possible to store the large data in an auxiliary
/// structure (e.g. Arena or ECS).
///
- /// The lint will ignore generic types if the layout depends on the
- /// generics, even if the size difference will be large anyway.
+ /// The lint will ignore the impact of generic types to the type layout by
+ /// assuming every type parameter is zero-sized. Depending on your use case,
+ /// this may lead to a false positive.
///
/// ### Example
/// ```rust
@@ -83,6 +83,38 @@ struct VariantInfo {
fields_size: Vec<FieldInfo>,
}
+fn variants_size<'tcx>(
+ cx: &LateContext<'tcx>,
+ adt: AdtDef<'tcx>,
+ subst: &'tcx List<GenericArg<'tcx>>,
+) -> Vec<VariantInfo> {
+ let mut variants_size = adt
+ .variants()
+ .iter()
+ .enumerate()
+ .map(|(i, variant)| {
+ let mut fields_size = variant
+ .fields
+ .iter()
+ .enumerate()
+ .map(|(i, f)| FieldInfo {
+ ind: i,
+ size: approx_ty_size(cx, f.ty(cx.tcx, subst)),
+ })
+ .collect::<Vec<_>>();
+ fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
+
+ VariantInfo {
+ ind: i,
+ size: fields_size.iter().map(|info| info.size).sum(),
+ fields_size,
+ }
+ })
+ .collect::<Vec<_>>();
+ variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
+ variants_size
+}
+
impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
@@ -92,36 +124,14 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
}
if let ItemKind::Enum(ref def, _) = item.kind {
let ty = cx.tcx.type_of(item.def_id);
- let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
+ let (adt, subst) = match ty.kind() {
+ Adt(adt, subst) => (adt, subst),
+ _ => panic!("already checked whether this is an enum"),
+ };
if adt.variants().len() <= 1 {
return;
}
- let mut variants_size: Vec<VariantInfo> = Vec::new();
- for (i, variant) in adt.variants().iter().enumerate() {
- let mut fields_size = Vec::new();
- for (i, f) in variant.fields.iter().enumerate() {
- let ty = cx.tcx.type_of(f.did);
- // don't lint variants which have a field of generic type.
- match cx.layout_of(ty) {
- Ok(l) => {
- let fsize = l.size.bytes();
- fields_size.push(FieldInfo { ind: i, size: fsize });
- },
- Err(_) => {
- return;
- },
- }
- }
- let size: u64 = fields_size.iter().map(|info| info.size).sum();
-
- variants_size.push(VariantInfo {
- ind: i,
- size,
- fields_size,
- });
- }
-
- variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
+ let variants_size = variants_size(cx, *adt, subst);
let mut difference = variants_size[0].size - variants_size[1].size;
if difference > self.maximum_size_difference_allowed {
@@ -129,20 +139,30 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
span_lint_and_then(
cx,
LARGE_ENUM_VARIANT,
- def.variants[variants_size[0].ind].span,
+ item.span,
"large size difference between variants",
|diag| {
diag.span_label(
+ item.span,
+ format!("the entire enum is at least {} bytes", approx_ty_size(cx, ty)),
+ );
+ diag.span_label(
def.variants[variants_size[0].ind].span,
- &format!("this variant is {} bytes", variants_size[0].size),
+ format!("the largest variant contains at least {} bytes", variants_size[0].size),
);
- diag.span_note(
+ diag.span_label(
def.variants[variants_size[1].ind].span,
- &format!("and the second-largest variant is {} bytes:", variants_size[1].size),
+ &if variants_size[1].fields_size.is_empty() {
+ "the second-largest variant carries no data at all".to_owned()
+ } else {
+ format!(
+ "the second-largest variant contains at least {} bytes",
+ variants_size[1].size
+ )
+ },
);
let fields = def.variants[variants_size[0].ind].data.fields();
- variants_size[0].fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
let mut applicability = Applicability::MaybeIncorrect;
if is_copy(cx, ty) || maybe_copy(cx, ty) {
diag.span_note(
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 246f5aad8..7ae8ef830 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -370,7 +370,8 @@ fn check_for_is_empty<'tcx>(
}
fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
- if let (&ExprKind::MethodCall(method_path, args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) {
+ if let (&ExprKind::MethodCall(method_path, receiver, args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind)
+ {
// check if we are in an is_empty() method
if let Some(name) = get_item_name(cx, method) {
if name.as_str() == "is_empty" {
@@ -378,16 +379,28 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>
}
}
- check_len(cx, span, method_path.ident.name, args, &lit.node, op, compare_to);
+ check_len(
+ cx,
+ span,
+ method_path.ident.name,
+ receiver,
+ args,
+ &lit.node,
+ op,
+ compare_to,
+ );
} else {
check_empty_expr(cx, span, method, lit, op);
}
}
+// FIXME(flip1995): Figure out how to reduce the number of arguments
+#[allow(clippy::too_many_arguments)]
fn check_len(
cx: &LateContext<'_>,
span: Span,
method_name: Symbol,
+ receiver: &Expr<'_>,
args: &[Expr<'_>],
lit: &LitKind,
op: &str,
@@ -399,7 +412,7 @@ fn check_len(
return;
}
- if method_name == sym::len && args.len() == 1 && has_is_empty(cx, &args[0]) {
+ if method_name == sym::len && args.is_empty() && has_is_empty(cx, receiver) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
@@ -410,7 +423,7 @@ fn check_len(
format!(
"{}{}.is_empty()",
op,
- snippet_with_applicability(cx, args[0].span, "_", &mut applicability)
+ snippet_with_applicability(cx, receiver.span, "_", &mut applicability)
),
applicability,
);
diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
index 56bbbbbc8..10fc0f401 100644
--- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs
+++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
@@ -4,7 +4,7 @@ use clippy_utils::{path_to_local_id, visitors::is_local_used};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir::BindingAnnotation;
+use rustc_hir::{BindingAnnotation, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
};
let mutability = match mode {
- BindingAnnotation::RefMut | BindingAnnotation::Mutable => "<mut> ",
+ BindingAnnotation(_, Mutability::Mut) => "<mut> ",
_ => "",
};
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_all.rs b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
index 763dd2a40..751409602 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
@@ -15,18 +15,18 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE),
LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
- LintId::of(blacklisted_name::BLACKLISTED_NAME),
LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
- LintId::of(booleans::LOGIC_BUG),
+ LintId::of(bool_to_int_with_if::BOOL_TO_INT_WITH_IF),
LintId::of(booleans::NONMINIMAL_BOOL),
+ LintId::of(booleans::OVERLY_COMPLEX_BOOL_EXPR),
LintId::of(borrow_deref_ref::BORROW_DEREF_REF),
- LintId::of(bytes_count_to_len::BYTES_COUNT_TO_LEN),
LintId::of(casts::CAST_ABS_TO_UNSIGNED),
LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
LintId::of(casts::CAST_ENUM_TRUNCATION),
LintId::of(casts::CAST_REF_TO_MUT),
LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),
+ LintId::of(casts::CAST_SLICE_FROM_RAW_PARTS),
LintId::of(casts::CHAR_LIT_AS_U8),
LintId::of(casts::FN_TO_NUMERIC_CAST),
LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
@@ -39,12 +39,14 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
LintId::of(default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY),
+ LintId::of(dereference::EXPLICIT_AUTO_DEREF),
LintId::of(dereference::NEEDLESS_BORROW),
LintId::of(derivable_impls::DERIVABLE_IMPLS),
LintId::of(derive::DERIVE_HASH_XOR_EQ),
LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
LintId::of(derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ),
LintId::of(disallowed_methods::DISALLOWED_METHODS),
+ LintId::of(disallowed_names::DISALLOWED_NAMES),
LintId::of(disallowed_types::DISALLOWED_TYPES),
LintId::of(doc::MISSING_SAFETY_DOC),
LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
@@ -79,9 +81,9 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(functions::DOUBLE_MUST_USE),
LintId::of(functions::MUST_USE_UNIT),
LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
+ LintId::of(functions::RESULT_LARGE_ERR),
LintId::of(functions::RESULT_UNIT_ERR),
LintId::of(functions::TOO_MANY_ARGUMENTS),
- LintId::of(get_first::GET_FIRST),
LintId::of(if_let_mutex::IF_LET_MUTEX),
LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
LintId::of(infinite_iter::INFINITE_ITER),
@@ -127,7 +129,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(manual_rem_euclid::MANUAL_REM_EUCLID),
LintId::of(manual_retain::MANUAL_RETAIN),
LintId::of(manual_strip::MANUAL_STRIP),
- LintId::of(map_clone::MAP_CLONE),
LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
LintId::of(match_result_ok::MATCH_RESULT_OK),
@@ -149,17 +150,20 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
LintId::of(methods::BIND_INSTEAD_OF_MAP),
+ LintId::of(methods::BYTES_COUNT_TO_LEN),
LintId::of(methods::BYTES_NTH),
LintId::of(methods::CHARS_LAST_CMP),
LintId::of(methods::CHARS_NEXT_CMP),
LintId::of(methods::CLONE_DOUBLE_REF),
LintId::of(methods::CLONE_ON_COPY),
+ LintId::of(methods::COLLAPSIBLE_STR_REPLACE),
LintId::of(methods::ERR_EXPECT),
LintId::of(methods::EXPECT_FUN_CALL),
LintId::of(methods::EXTEND_WITH_DRAIN),
LintId::of(methods::FILTER_MAP_IDENTITY),
LintId::of(methods::FILTER_NEXT),
LintId::of(methods::FLAT_MAP_IDENTITY),
+ LintId::of(methods::GET_FIRST),
LintId::of(methods::GET_LAST_WITH_LEN),
LintId::of(methods::INSPECT_FOR_EACH),
LintId::of(methods::INTO_ITER_ON_REF),
@@ -177,13 +181,16 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
LintId::of(methods::MANUAL_SPLIT_ONCE),
LintId::of(methods::MANUAL_STR_REPEAT),
+ LintId::of(methods::MAP_CLONE),
LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
LintId::of(methods::MAP_FLATTEN),
LintId::of(methods::MAP_IDENTITY),
+ LintId::of(methods::MUT_MUTEX_LOCK),
LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
LintId::of(methods::NEEDLESS_OPTION_TAKE),
LintId::of(methods::NEEDLESS_SPLITN),
LintId::of(methods::NEW_RET_NO_SELF),
+ LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
LintId::of(methods::NO_EFFECT_REPLACE),
LintId::of(methods::OBFUSCATED_IF_ELSE),
LintId::of(methods::OK_EXPECT),
@@ -192,6 +199,8 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(methods::OPTION_MAP_OR_NONE),
LintId::of(methods::OR_FUN_CALL),
LintId::of(methods::OR_THEN_UNWRAP),
+ LintId::of(methods::RANGE_ZIP_WITH_LEN),
+ LintId::of(methods::REPEAT_ONCE),
LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
LintId::of(methods::SEARCH_IS_SOME),
LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
@@ -201,14 +210,18 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(methods::STRING_EXTEND_CHARS),
LintId::of(methods::SUSPICIOUS_MAP),
LintId::of(methods::SUSPICIOUS_SPLITN),
+ LintId::of(methods::SUSPICIOUS_TO_OWNED),
LintId::of(methods::UNINIT_ASSUMED_INIT),
+ LintId::of(methods::UNIT_HASH),
LintId::of(methods::UNNECESSARY_FILTER_MAP),
LintId::of(methods::UNNECESSARY_FIND_MAP),
LintId::of(methods::UNNECESSARY_FOLD),
LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
+ LintId::of(methods::UNNECESSARY_SORT_BY),
LintId::of(methods::UNNECESSARY_TO_OWNED),
LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
LintId::of(methods::USELESS_ASREF),
+ LintId::of(methods::VEC_RESIZE_TO_ZERO),
LintId::of(methods::WRONG_SELF_CONVENTION),
LintId::of(methods::ZST_OFFSET),
LintId::of(minmax::MIN_MAX),
@@ -223,8 +236,8 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
LintId::of(mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION),
+ LintId::of(multi_assignments::MULTI_ASSIGNMENTS),
LintId::of(mut_key::MUTABLE_KEY_TYPE),
- LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
LintId::of(needless_bool::BOOL_COMPARISON),
@@ -244,7 +257,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
LintId::of(octal_escapes::OCTAL_ESCAPES),
- LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
+ LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
LintId::of(operators::ASSIGN_OP_PATTERN),
LintId::of(operators::BAD_BIT_MASK),
@@ -265,6 +278,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
+ LintId::of(partialeq_to_none::PARTIALEQ_TO_NONE),
LintId::of(precedence::PRECEDENCE),
LintId::of(ptr::CMP_NULL),
LintId::of(ptr::INVALID_NULL_PTR_USAGE),
@@ -273,10 +287,8 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
LintId::of(question_mark::QUESTION_MARK),
LintId::of(ranges::MANUAL_RANGE_CONTAINS),
- LintId::of(ranges::RANGE_ZIP_WITH_LEN),
LintId::of(ranges::REVERSED_EMPTY_RANGES),
LintId::of(rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT),
- LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
LintId::of(redundant_clone::REDUNDANT_CLONE),
LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
@@ -284,7 +296,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
LintId::of(reference::DEREF_ADDROF),
LintId::of(regex::INVALID_REGEX),
- LintId::of(repeat_once::REPEAT_ONCE),
LintId::of(returns::LET_AND_RETURN),
LintId::of(returns::NEEDLESS_RETURN),
LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
@@ -312,10 +323,10 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
+ LintId::of(transmute::TRANSMUTING_NULL),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::USELESS_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
- LintId::of(transmuting_null::TRANSMUTING_NULL),
LintId::of(types::BORROWED_BOX),
LintId::of(types::BOX_COLLECTION),
LintId::of(types::REDUNDANT_ALLOCATION),
@@ -323,7 +334,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(types::VEC_BOX),
LintId::of(unicode::INVISIBLE_CHARACTERS),
LintId::of(uninit_vec::UNINIT_VEC),
- LintId::of(unit_hash::UNIT_HASH),
LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
LintId::of(unit_types::LET_UNIT_VALUE),
LintId::of(unit_types::UNIT_ARG),
@@ -331,7 +341,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
LintId::of(unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS),
- LintId::of(unnecessary_sort_by::UNNECESSARY_SORT_BY),
LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
LintId::of(unused_unit::UNUSED_UNIT),
@@ -341,7 +350,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(useless_conversion::USELESS_CONVERSION),
LintId::of(vec::USELESS_VEC),
LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
- LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
+ LintId::of(write::POSITIONAL_NAMED_FORMAT_PARAMETERS),
LintId::of(write::PRINTLN_EMPTY_STRING),
LintId::of(write::PRINT_LITERAL),
LintId::of(write::PRINT_WITH_NEWLINE),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs b/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
index ed5446f58..aa247352f 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
@@ -6,9 +6,9 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
LintId::of(attrs::DEPRECATED_CFG_ATTR),
LintId::of(booleans::NONMINIMAL_BOOL),
LintId::of(borrow_deref_ref::BORROW_DEREF_REF),
- LintId::of(bytes_count_to_len::BYTES_COUNT_TO_LEN),
LintId::of(casts::CHAR_LIT_AS_U8),
LintId::of(casts::UNNECESSARY_CAST),
+ LintId::of(dereference::EXPLICIT_AUTO_DEREF),
LintId::of(derivable_impls::DERIVABLE_IMPLS),
LintId::of(double_parens::DOUBLE_PARENS),
LintId::of(explicit_write::EXPLICIT_WRITE),
@@ -32,6 +32,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
LintId::of(matches::NEEDLESS_MATCH),
LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
LintId::of(methods::BIND_INSTEAD_OF_MAP),
+ LintId::of(methods::BYTES_COUNT_TO_LEN),
LintId::of(methods::CLONE_ON_COPY),
LintId::of(methods::FILTER_MAP_IDENTITY),
LintId::of(methods::FILTER_NEXT),
@@ -50,10 +51,13 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
LintId::of(methods::OPTION_AS_REF_DEREF),
LintId::of(methods::OPTION_FILTER_MAP),
LintId::of(methods::OR_THEN_UNWRAP),
+ LintId::of(methods::RANGE_ZIP_WITH_LEN),
+ LintId::of(methods::REPEAT_ONCE),
LintId::of(methods::SEARCH_IS_SOME),
LintId::of(methods::SKIP_WHILE_NEXT),
LintId::of(methods::UNNECESSARY_FILTER_MAP),
LintId::of(methods::UNNECESSARY_FIND_MAP),
+ LintId::of(methods::UNNECESSARY_SORT_BY),
LintId::of(methods::USELESS_ASREF),
LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
@@ -68,6 +72,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
LintId::of(no_effect::NO_EFFECT),
LintId::of(no_effect::UNNECESSARY_OPERATION),
+ LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
LintId::of(operators::DOUBLE_COMPARISONS),
LintId::of(operators::DURATION_SUBSEC),
LintId::of(operators::IDENTITY_OP),
@@ -75,11 +80,9 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
LintId::of(precedence::PRECEDENCE),
LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
- LintId::of(ranges::RANGE_ZIP_WITH_LEN),
LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
LintId::of(redundant_slicing::REDUNDANT_SLICING),
LintId::of(reference::DEREF_ADDROF),
- LintId::of(repeat_once::REPEAT_ONCE),
LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
LintId::of(swap::MANUAL_SWAP),
@@ -98,7 +101,6 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
LintId::of(types::TYPE_COMPLEXITY),
LintId::of(types::VEC_BOX),
LintId::of(unit_types::UNIT_ARG),
- LintId::of(unnecessary_sort_by::UNNECESSARY_SORT_BY),
LintId::of(unwrap::UNNECESSARY_UNWRAP),
LintId::of(useless_conversion::USELESS_CONVERSION),
LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs b/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
index 9975859c5..ecec5cf57 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
@@ -8,7 +8,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
LintId::of(attrs::DEPRECATED_SEMVER),
LintId::of(attrs::MISMATCHED_TARGET_OS),
LintId::of(attrs::USELESS_ATTRIBUTE),
- LintId::of(booleans::LOGIC_BUG),
+ LintId::of(booleans::OVERLY_COMPLEX_BOOL_EXPR),
LintId::of(casts::CAST_REF_TO_MUT),
LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),
LintId::of(copies::IFS_SAME_COND),
@@ -39,12 +39,14 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
LintId::of(methods::CLONE_DOUBLE_REF),
LintId::of(methods::ITERATOR_STEP_BY_ZERO),
+ LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
LintId::of(methods::SUSPICIOUS_SPLITN),
LintId::of(methods::UNINIT_ASSUMED_INIT),
+ LintId::of(methods::UNIT_HASH),
+ LintId::of(methods::VEC_RESIZE_TO_ZERO),
LintId::of(methods::ZST_OFFSET),
LintId::of(minmax::MIN_MAX),
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
- LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
LintId::of(operators::BAD_BIT_MASK),
LintId::of(operators::CMP_NAN),
@@ -57,22 +59,19 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
LintId::of(ptr::INVALID_NULL_PTR_USAGE),
LintId::of(ptr::MUT_FROM_REF),
LintId::of(ranges::REVERSED_EMPTY_RANGES),
- LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
LintId::of(regex::INVALID_REGEX),
LintId::of(serde_api::SERDE_API_MISUSE),
LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
LintId::of(swap::ALMOST_SWAPPED),
+ LintId::of(transmute::TRANSMUTING_NULL),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
- LintId::of(transmuting_null::TRANSMUTING_NULL),
LintId::of(unicode::INVISIBLE_CHARACTERS),
LintId::of(uninit_vec::UNINIT_VEC),
- LintId::of(unit_hash::UNIT_HASH),
LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
LintId::of(unit_types::UNIT_CMP),
LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
LintId::of(unwrap::PANICKING_UNWRAP),
- LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs b/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
index 99bde35cf..962e67220 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
@@ -38,7 +38,6 @@ store.register_lints(&[
almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
approx_const::APPROX_CONSTANT,
as_conversions::AS_CONVERSIONS,
- as_underscore::AS_UNDERSCORE,
asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
@@ -55,21 +54,19 @@ store.register_lints(&[
await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE,
await_holding_invalid::AWAIT_HOLDING_LOCK,
await_holding_invalid::AWAIT_HOLDING_REFCELL_REF,
- blacklisted_name::BLACKLISTED_NAME,
blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS,
bool_assert_comparison::BOOL_ASSERT_COMPARISON,
- booleans::LOGIC_BUG,
+ bool_to_int_with_if::BOOL_TO_INT_WITH_IF,
booleans::NONMINIMAL_BOOL,
- borrow_as_ptr::BORROW_AS_PTR,
+ booleans::OVERLY_COMPLEX_BOOL_EXPR,
borrow_deref_ref::BORROW_DEREF_REF,
- bytecount::NAIVE_BYTECOUNT,
- bytes_count_to_len::BYTES_COUNT_TO_LEN,
cargo::CARGO_COMMON_METADATA,
cargo::MULTIPLE_CRATE_VERSIONS,
cargo::NEGATIVE_FEATURE_NAMES,
cargo::REDUNDANT_FEATURE_NAMES,
cargo::WILDCARD_DEPENDENCIES,
- case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
+ casts::AS_UNDERSCORE,
+ casts::BORROW_AS_PTR,
casts::CAST_ABS_TO_UNSIGNED,
casts::CAST_ENUM_CONSTRUCTOR,
casts::CAST_ENUM_TRUNCATION,
@@ -81,6 +78,7 @@ store.register_lints(&[
casts::CAST_REF_TO_MUT,
casts::CAST_SIGN_LOSS,
casts::CAST_SLICE_DIFFERENT_SIZES,
+ casts::CAST_SLICE_FROM_RAW_PARTS,
casts::CHAR_LIT_AS_U8,
casts::FN_TO_NUMERIC_CAST,
casts::FN_TO_NUMERIC_CAST_ANY,
@@ -116,6 +114,7 @@ store.register_lints(&[
derive::EXPL_IMPL_CLONE_ON_COPY,
derive::UNSAFE_DERIVE_DESERIALIZE,
disallowed_methods::DISALLOWED_METHODS,
+ disallowed_names::DISALLOWED_NAMES,
disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
disallowed_types::DISALLOWED_TYPES,
doc::DOC_MARKDOWN,
@@ -173,11 +172,11 @@ store.register_lints(&[
functions::MUST_USE_CANDIDATE,
functions::MUST_USE_UNIT,
functions::NOT_UNSAFE_PTR_ARG_DEREF,
+ functions::RESULT_LARGE_ERR,
functions::RESULT_UNIT_ERR,
functions::TOO_MANY_ARGUMENTS,
functions::TOO_MANY_LINES,
future_not_send::FUTURE_NOT_SEND,
- get_first::GET_FIRST,
if_let_mutex::IF_LET_MUTEX,
if_not_else::IF_NOT_ELSE,
if_then_some_else_none::IF_THEN_SOME_ELSE_NONE,
@@ -244,13 +243,12 @@ store.register_lints(&[
manual_assert::MANUAL_ASSERT,
manual_async_fn::MANUAL_ASYNC_FN,
manual_bits::MANUAL_BITS,
+ manual_instant_elapsed::MANUAL_INSTANT_ELAPSED,
manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
- manual_ok_or::MANUAL_OK_OR,
manual_rem_euclid::MANUAL_REM_EUCLID,
manual_retain::MANUAL_RETAIN,
+ manual_string_new::MANUAL_STRING_NEW,
manual_strip::MANUAL_STRIP,
- map_clone::MAP_CLONE,
- map_err_ignore::MAP_ERR_IGNORE,
map_unit_fn::OPTION_MAP_UNIT_FN,
map_unit_fn::RESULT_MAP_UNIT_FN,
match_result_ok::MATCH_RESULT_OK,
@@ -283,13 +281,16 @@ store.register_lints(&[
mem_replace::MEM_REPLACE_WITH_DEFAULT,
mem_replace::MEM_REPLACE_WITH_UNINIT,
methods::BIND_INSTEAD_OF_MAP,
+ methods::BYTES_COUNT_TO_LEN,
methods::BYTES_NTH,
+ methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
methods::CHARS_LAST_CMP,
methods::CHARS_NEXT_CMP,
methods::CLONED_INSTEAD_OF_COPIED,
methods::CLONE_DOUBLE_REF,
methods::CLONE_ON_COPY,
methods::CLONE_ON_REF_PTR,
+ methods::COLLAPSIBLE_STR_REPLACE,
methods::ERR_EXPECT,
methods::EXPECT_FUN_CALL,
methods::EXPECT_USED,
@@ -301,6 +302,7 @@ store.register_lints(&[
methods::FLAT_MAP_IDENTITY,
methods::FLAT_MAP_OPTION,
methods::FROM_ITER_INSTEAD_OF_COLLECT,
+ methods::GET_FIRST,
methods::GET_LAST_WITH_LEN,
methods::GET_UNWRAP,
methods::IMPLICIT_CLONE,
@@ -314,22 +316,30 @@ store.register_lints(&[
methods::ITER_NEXT_SLICE,
methods::ITER_NTH,
methods::ITER_NTH_ZERO,
+ methods::ITER_ON_EMPTY_COLLECTIONS,
+ methods::ITER_ON_SINGLE_ITEMS,
methods::ITER_OVEREAGER_CLONED,
methods::ITER_SKIP_NEXT,
methods::ITER_WITH_DRAIN,
methods::MANUAL_FILTER_MAP,
methods::MANUAL_FIND_MAP,
+ methods::MANUAL_OK_OR,
methods::MANUAL_SATURATING_ARITHMETIC,
methods::MANUAL_SPLIT_ONCE,
methods::MANUAL_STR_REPEAT,
+ methods::MAP_CLONE,
methods::MAP_COLLECT_RESULT_UNIT,
+ methods::MAP_ERR_IGNORE,
methods::MAP_FLATTEN,
methods::MAP_IDENTITY,
methods::MAP_UNWRAP_OR,
+ methods::MUT_MUTEX_LOCK,
+ methods::NAIVE_BYTECOUNT,
methods::NEEDLESS_OPTION_AS_DEREF,
methods::NEEDLESS_OPTION_TAKE,
methods::NEEDLESS_SPLITN,
methods::NEW_RET_NO_SELF,
+ methods::NONSENSICAL_OPEN_OPTIONS,
methods::NO_EFFECT_REPLACE,
methods::OBFUSCATED_IF_ELSE,
methods::OK_EXPECT,
@@ -338,25 +348,34 @@ store.register_lints(&[
methods::OPTION_MAP_OR_NONE,
methods::OR_FUN_CALL,
methods::OR_THEN_UNWRAP,
+ methods::PATH_BUF_PUSH_OVERWRITE,
+ methods::RANGE_ZIP_WITH_LEN,
+ methods::REPEAT_ONCE,
methods::RESULT_MAP_OR_INTO_OPTION,
methods::SEARCH_IS_SOME,
methods::SHOULD_IMPLEMENT_TRAIT,
methods::SINGLE_CHAR_ADD_STR,
methods::SINGLE_CHAR_PATTERN,
methods::SKIP_WHILE_NEXT,
+ methods::STABLE_SORT_PRIMITIVE,
methods::STRING_EXTEND_CHARS,
methods::SUSPICIOUS_MAP,
methods::SUSPICIOUS_SPLITN,
+ methods::SUSPICIOUS_TO_OWNED,
methods::UNINIT_ASSUMED_INIT,
+ methods::UNIT_HASH,
methods::UNNECESSARY_FILTER_MAP,
methods::UNNECESSARY_FIND_MAP,
methods::UNNECESSARY_FOLD,
methods::UNNECESSARY_JOIN,
methods::UNNECESSARY_LAZY_EVALUATIONS,
+ methods::UNNECESSARY_SORT_BY,
methods::UNNECESSARY_TO_OWNED,
methods::UNWRAP_OR_ELSE_DEFAULT,
methods::UNWRAP_USED,
methods::USELESS_ASREF,
+ methods::VEC_RESIZE_TO_ZERO,
+ methods::VERBOSE_FILE_READS,
methods::WRONG_SELF_CONVENTION,
methods::ZST_OFFSET,
minmax::MIN_MAX,
@@ -383,9 +402,9 @@ store.register_lints(&[
mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION,
module_style::MOD_MODULE_FILES,
module_style::SELF_NAMED_MODULE_FILES,
+ multi_assignments::MULTI_ASSIGNMENTS,
mut_key::MUTABLE_KEY_TYPE,
mut_mut::MUT_MUT,
- mut_mutex_lock::MUT_MUTEX_LOCK,
mut_reference::UNNECESSARY_MUT_PASSED,
mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
mutex_atomic::MUTEX_ATOMIC,
@@ -417,9 +436,8 @@ store.register_lints(&[
nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES,
octal_escapes::OCTAL_ESCAPES,
only_used_in_recursion::ONLY_USED_IN_RECURSION,
- open_options::NONSENSICAL_OPEN_OPTIONS,
operators::ABSURD_EXTREME_COMPARISONS,
- operators::ARITHMETIC,
+ operators::ARITHMETIC_SIDE_EFFECTS,
operators::ASSIGN_OP_PATTERN,
operators::BAD_BIT_MASK,
operators::CMP_NAN,
@@ -453,9 +471,9 @@ store.register_lints(&[
panic_unimplemented::UNIMPLEMENTED,
panic_unimplemented::UNREACHABLE,
partialeq_ne_impl::PARTIALEQ_NE_IMPL,
+ partialeq_to_none::PARTIALEQ_TO_NONE,
pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE,
pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF,
- path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE,
pattern_type_mismatch::PATTERN_TYPE_MISMATCH,
precedence::PRECEDENCE,
ptr::CMP_NULL,
@@ -468,7 +486,6 @@ store.register_lints(&[
ranges::MANUAL_RANGE_CONTAINS,
ranges::RANGE_MINUS_ONE,
ranges::RANGE_PLUS_ONE,
- ranges::RANGE_ZIP_WITH_LEN,
ranges::REVERSED_EMPTY_RANGES,
rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT,
read_zero_byte_vec::READ_ZERO_BYTE_VEC,
@@ -484,7 +501,6 @@ store.register_lints(&[
reference::DEREF_ADDROF,
regex::INVALID_REGEX,
regex::TRIVIAL_REGEX,
- repeat_once::REPEAT_ONCE,
return_self_not_must_use::RETURN_SELF_NOT_MUST_USE,
returns::LET_AND_RETURN,
returns::NEEDLESS_RETURN,
@@ -499,7 +515,6 @@ store.register_lints(&[
single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
- stable_sort_primitive::STABLE_SORT_PRIMITIVE,
std_instead_of_core::ALLOC_INSTEAD_OF_CORE,
std_instead_of_core::STD_INSTEAD_OF_ALLOC,
std_instead_of_core::STD_INSTEAD_OF_CORE,
@@ -535,10 +550,10 @@ store.register_lints(&[
transmute::TRANSMUTE_PTR_TO_PTR,
transmute::TRANSMUTE_PTR_TO_REF,
transmute::TRANSMUTE_UNDEFINED_REPR,
+ transmute::TRANSMUTING_NULL,
transmute::UNSOUND_COLLECTION_TRANSMUTE,
transmute::USELESS_TRANSMUTE,
transmute::WRONG_TRANSMUTE,
- transmuting_null::TRANSMUTING_NULL,
types::BORROWED_BOX,
types::BOX_COLLECTION,
types::LINKEDLIST,
@@ -553,7 +568,6 @@ store.register_lints(&[
unicode::NON_ASCII_LITERAL,
unicode::UNICODE_NOT_NFC,
uninit_vec::UNINIT_VEC,
- unit_hash::UNIT_HASH,
unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
unit_types::LET_UNIT_VALUE,
unit_types::UNIT_ARG,
@@ -562,12 +576,12 @@ store.register_lints(&[
unnamed_address::VTABLE_ADDRESS_COMPARISONS,
unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS,
unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS,
- unnecessary_sort_by::UNNECESSARY_SORT_BY,
unnecessary_wraps::UNNECESSARY_WRAPS,
unnested_or_patterns::UNNESTED_OR_PATTERNS,
unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
unused_async::UNUSED_ASYNC,
unused_io_amount::UNUSED_IO_AMOUNT,
+ unused_peekable::UNUSED_PEEKABLE,
unused_rounding::UNUSED_ROUNDING,
unused_self::UNUSED_SELF,
unused_unit::UNUSED_UNIT,
@@ -579,10 +593,9 @@ store.register_lints(&[
useless_conversion::USELESS_CONVERSION,
vec::USELESS_VEC,
vec_init_then_push::VEC_INIT_THEN_PUSH,
- vec_resize_to_zero::VEC_RESIZE_TO_ZERO,
- verbose_file_reads::VERBOSE_FILE_READS,
wildcard_imports::ENUM_GLOB_USE,
wildcard_imports::WILDCARD_IMPORTS,
+ write::POSITIONAL_NAMED_FORMAT_PARAMETERS,
write::PRINTLN_EMPTY_STRING,
write::PRINT_LITERAL,
write::PRINT_STDERR,
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs b/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs
index 973191eb1..0876b2c3b 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs
@@ -6,7 +6,6 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
LintId::of(attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
LintId::of(cognitive_complexity::COGNITIVE_COMPLEXITY),
LintId::of(copies::BRANCHES_SHARING_CODE),
- LintId::of(dereference::EXPLICIT_AUTO_DEREF),
LintId::of(equatable_if_let::EQUATABLE_IF_LET),
LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
@@ -15,22 +14,27 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
LintId::of(index_refutable_slice::INDEX_REFUTABLE_SLICE),
LintId::of(let_if_seq::USELESS_LET_IF_SEQ),
LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE),
+ LintId::of(methods::ITER_ON_EMPTY_COLLECTIONS),
+ LintId::of(methods::ITER_ON_SINGLE_ITEMS),
LintId::of(methods::ITER_WITH_DRAIN),
+ LintId::of(methods::PATH_BUF_PUSH_OVERWRITE),
LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN),
LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
LintId::of(mutex_atomic::MUTEX_ATOMIC),
LintId::of(mutex_atomic::MUTEX_INTEGER),
LintId::of(non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY),
LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
- LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
LintId::of(option_if_let_else::OPTION_IF_LET_ELSE),
- LintId::of(path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
+ LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
LintId::of(redundant_pub_crate::REDUNDANT_PUB_CRATE),
LintId::of(regex::TRIVIAL_REGEX),
LintId::of(strings::STRING_LIT_AS_BYTES),
LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY),
+ LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
+ LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
+ LintId::of(unused_peekable::UNUSED_PEEKABLE),
LintId::of(unused_rounding::UNUSED_ROUNDING),
LintId::of(use_self::USE_SELF),
])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs b/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
index a1b546658..03c3c202e 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
@@ -4,9 +4,7 @@
store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
LintId::of(attrs::INLINE_ALWAYS),
- LintId::of(borrow_as_ptr::BORROW_AS_PTR),
- LintId::of(bytecount::NAIVE_BYTECOUNT),
- LintId::of(case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
+ LintId::of(casts::BORROW_AS_PTR),
LintId::of(casts::CAST_LOSSLESS),
LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
LintId::of(casts::CAST_POSSIBLE_WRAP),
@@ -49,20 +47,25 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
LintId::of(loops::EXPLICIT_ITER_LOOP),
LintId::of(macro_use::MACRO_USE_IMPORTS),
LintId::of(manual_assert::MANUAL_ASSERT),
- LintId::of(manual_ok_or::MANUAL_OK_OR),
+ LintId::of(manual_instant_elapsed::MANUAL_INSTANT_ELAPSED),
+ LintId::of(manual_string_new::MANUAL_STRING_NEW),
LintId::of(matches::MATCH_BOOL),
LintId::of(matches::MATCH_ON_VEC_ITEMS),
LintId::of(matches::MATCH_SAME_ARMS),
LintId::of(matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
LintId::of(matches::MATCH_WILD_ERR_ARM),
LintId::of(matches::SINGLE_MATCH_ELSE),
+ LintId::of(methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
LintId::of(methods::FILTER_MAP_NEXT),
LintId::of(methods::FLAT_MAP_OPTION),
LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
LintId::of(methods::IMPLICIT_CLONE),
LintId::of(methods::INEFFICIENT_TO_STRING),
+ LintId::of(methods::MANUAL_OK_OR),
LintId::of(methods::MAP_UNWRAP_OR),
+ LintId::of(methods::NAIVE_BYTECOUNT),
+ LintId::of(methods::STABLE_SORT_PRIMITIVE),
LintId::of(methods::UNNECESSARY_JOIN),
LintId::of(misc::USED_UNDERSCORE_BINDING),
LintId::of(mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER),
@@ -84,10 +87,7 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
LintId::of(ref_option_ref::REF_OPTION_REF),
LintId::of(return_self_not_must_use::RETURN_SELF_NOT_MUST_USE),
LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
- LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
LintId::of(strings::STRING_ADD_ASSIGN),
- LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
- LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
LintId::of(types::LINKEDLIST),
LintId::of(types::OPTION_OPTION),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_perf.rs b/src/tools/clippy/clippy_lints/src/lib.register_perf.rs
index e1b90acb9..195ce41e3 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_perf.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_perf.rs
@@ -7,12 +7,14 @@ store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
LintId::of(escape::BOXED_LOCAL),
LintId::of(format_args::FORMAT_IN_FORMAT_ARGS),
LintId::of(format_args::TO_STRING_IN_FORMAT_ARGS),
+ LintId::of(functions::RESULT_LARGE_ERR),
LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
LintId::of(loops::MANUAL_MEMCPY),
LintId::of(loops::MISSING_SPIN_LOOP),
LintId::of(loops::NEEDLESS_COLLECT),
LintId::of(manual_retain::MANUAL_RETAIN),
+ LintId::of(methods::COLLAPSIBLE_STR_REPLACE),
LintId::of(methods::EXPECT_FUN_CALL),
LintId::of(methods::EXTEND_WITH_DRAIN),
LintId::of(methods::ITER_NTH),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
index a7339ef27..6eb9b3d3b 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
@@ -4,11 +4,11 @@
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
LintId::of(as_conversions::AS_CONVERSIONS),
- LintId::of(as_underscore::AS_UNDERSCORE),
LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
+ LintId::of(casts::AS_UNDERSCORE),
LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
LintId::of(create_dir::CREATE_DIR),
LintId::of(dbg_macro::DBG_MACRO),
@@ -30,7 +30,6 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
LintId::of(large_include_file::LARGE_INCLUDE_FILE),
LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
- LintId::of(map_err_ignore::MAP_ERR_IGNORE),
LintId::of(matches::REST_PAT_IN_FULLY_BOUND_STRUCTS),
LintId::of(matches::TRY_ERR),
LintId::of(matches::WILDCARD_ENUM_MATCH_ARM),
@@ -39,7 +38,9 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
LintId::of(methods::EXPECT_USED),
LintId::of(methods::FILETYPE_IS_FILE),
LintId::of(methods::GET_UNWRAP),
+ LintId::of(methods::MAP_ERR_IGNORE),
LintId::of(methods::UNWRAP_USED),
+ LintId::of(methods::VERBOSE_FILE_READS),
LintId::of(misc_early::SEPARATED_LITERAL_SUFFIX),
LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
@@ -49,7 +50,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
LintId::of(mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION),
LintId::of(module_style::MOD_MODULE_FILES),
LintId::of(module_style::SELF_NAMED_MODULE_FILES),
- LintId::of(operators::ARITHMETIC),
+ LintId::of(operators::ARITHMETIC_SIDE_EFFECTS),
LintId::of(operators::FLOAT_ARITHMETIC),
LintId::of(operators::FLOAT_CMP_CONST),
LintId::of(operators::INTEGER_ARITHMETIC),
@@ -81,7 +82,6 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
LintId::of(unicode::NON_ASCII_LITERAL),
LintId::of(unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS),
LintId::of(unwrap_in_result::UNWRAP_IN_RESULT),
- LintId::of(verbose_file_reads::VERBOSE_FILE_READS),
LintId::of(write::PRINT_STDERR),
LintId::of(write::PRINT_STDOUT),
LintId::of(write::USE_DEBUG),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_style.rs b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
index e95bab1d0..05d2ec2e9 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_style.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
@@ -4,9 +4,9 @@
store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
- LintId::of(blacklisted_name::BLACKLISTED_NAME),
LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
+ LintId::of(bool_to_int_with_if::BOOL_TO_INT_WITH_IF),
LintId::of(casts::FN_TO_NUMERIC_CAST),
LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
@@ -17,6 +17,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(dereference::NEEDLESS_BORROW),
LintId::of(derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ),
LintId::of(disallowed_methods::DISALLOWED_METHODS),
+ LintId::of(disallowed_names::DISALLOWED_NAMES),
LintId::of(disallowed_types::DISALLOWED_TYPES),
LintId::of(doc::MISSING_SAFETY_DOC),
LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
@@ -29,7 +30,6 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(functions::DOUBLE_MUST_USE),
LintId::of(functions::MUST_USE_UNIT),
LintId::of(functions::RESULT_UNIT_ERR),
- LintId::of(get_first::GET_FIRST),
LintId::of(inherent_to_string::INHERENT_TO_STRING),
LintId::of(init_numbered_fields::INIT_NUMBERED_FIELDS),
LintId::of(len_zero::COMPARISON_TO_EMPTY),
@@ -45,7 +45,6 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
LintId::of(manual_bits::MANUAL_BITS),
LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
- LintId::of(map_clone::MAP_CLONE),
LintId::of(match_result_ok::MATCH_RESULT_OK),
LintId::of(matches::COLLAPSIBLE_MATCH),
LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
@@ -61,6 +60,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(methods::CHARS_LAST_CMP),
LintId::of(methods::CHARS_NEXT_CMP),
LintId::of(methods::ERR_EXPECT),
+ LintId::of(methods::GET_FIRST),
LintId::of(methods::INTO_ITER_ON_REF),
LintId::of(methods::IS_DIGIT_ASCII_RADIX),
LintId::of(methods::ITER_CLONED_COLLECT),
@@ -68,7 +68,9 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(methods::ITER_NTH_ZERO),
LintId::of(methods::ITER_SKIP_NEXT),
LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
+ LintId::of(methods::MAP_CLONE),
LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
+ LintId::of(methods::MUT_MUTEX_LOCK),
LintId::of(methods::NEW_RET_NO_SELF),
LintId::of(methods::OBFUSCATED_IF_ELSE),
LintId::of(methods::OK_EXPECT),
@@ -88,7 +90,6 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
LintId::of(misc_early::REDUNDANT_PATTERN),
- LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
LintId::of(needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS),
@@ -100,6 +101,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
LintId::of(operators::ASSIGN_OP_PATTERN),
LintId::of(operators::OP_REF),
LintId::of(operators::PTR_EQ),
+ LintId::of(partialeq_to_none::PARTIALEQ_TO_NONE),
LintId::of(ptr::CMP_NULL),
LintId::of(ptr::PTR_ARG),
LintId::of(question_mark::QUESTION_MARK),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
index 964992bd9..bede91f18 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
@@ -11,6 +11,7 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
LintId::of(casts::CAST_ABS_TO_UNSIGNED),
LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
LintId::of(casts::CAST_ENUM_TRUNCATION),
+ LintId::of(casts::CAST_SLICE_FROM_RAW_PARTS),
LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
LintId::of(drop_forget_ref::DROP_NON_DROP),
LintId::of(drop_forget_ref::FORGET_NON_DROP),
@@ -24,6 +25,8 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
LintId::of(loops::MUT_RANGE_BOUND),
LintId::of(methods::NO_EFFECT_REPLACE),
LintId::of(methods::SUSPICIOUS_MAP),
+ LintId::of(methods::SUSPICIOUS_TO_OWNED),
+ LintId::of(multi_assignments::MULTI_ASSIGNMENTS),
LintId::of(mut_key::MUTABLE_KEY_TYPE),
LintId::of(octal_escapes::OCTAL_ESCAPES),
LintId::of(operators::FLOAT_EQUALITY_WITHOUT_ABS),
@@ -32,4 +35,5 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
LintId::of(swap_ptr_to_ref::SWAP_PTR_TO_REF),
+ LintId::of(write::POSITIONAL_NAMED_FORMAT_PARAMETERS),
])
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 5a3111632..ceaaf5c6d 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -5,7 +5,7 @@
#![feature(drain_filter)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(lint_reasons)]
#![feature(never_type)]
#![feature(once_cell)]
@@ -171,23 +171,18 @@ mod renamed_lints;
mod almost_complete_letter_range;
mod approx_const;
mod as_conversions;
-mod as_underscore;
mod asm_syntax;
mod assertions_on_constants;
mod assertions_on_result_states;
mod async_yields_async;
mod attrs;
mod await_holding_invalid;
-mod blacklisted_name;
mod blocks_in_if_conditions;
mod bool_assert_comparison;
+mod bool_to_int_with_if;
mod booleans;
-mod borrow_as_ptr;
mod borrow_deref_ref;
-mod bytecount;
-mod bytes_count_to_len;
mod cargo;
-mod case_sensitive_file_extension_comparisons;
mod casts;
mod checked_conversions;
mod cognitive_complexity;
@@ -206,6 +201,7 @@ mod dereference;
mod derivable_impls;
mod derive;
mod disallowed_methods;
+mod disallowed_names;
mod disallowed_script_idents;
mod disallowed_types;
mod doc;
@@ -239,7 +235,6 @@ mod from_over_into;
mod from_str_radix_10;
mod functions;
mod future_not_send;
-mod get_first;
mod if_let_mutex;
mod if_not_else;
mod if_then_some_else_none;
@@ -274,13 +269,12 @@ mod main_recursion;
mod manual_assert;
mod manual_async_fn;
mod manual_bits;
+mod manual_instant_elapsed;
mod manual_non_exhaustive;
-mod manual_ok_or;
mod manual_rem_euclid;
mod manual_retain;
+mod manual_string_new;
mod manual_strip;
-mod map_clone;
-mod map_err_ignore;
mod map_unit_fn;
mod match_result_ok;
mod matches;
@@ -297,9 +291,9 @@ mod missing_enforced_import_rename;
mod missing_inline;
mod mixed_read_write_in_expression;
mod module_style;
+mod multi_assignments;
mod mut_key;
mod mut_mut;
-mod mut_mutex_lock;
mod mut_reference;
mod mutable_debug_assertion;
mod mutex_atomic;
@@ -324,7 +318,6 @@ mod non_send_fields_in_send_ty;
mod nonstandard_macro_braces;
mod octal_escapes;
mod only_used_in_recursion;
-mod open_options;
mod operators;
mod option_env_unwrap;
mod option_if_let_else;
@@ -332,8 +325,8 @@ mod overflow_check_conditional;
mod panic_in_result_fn;
mod panic_unimplemented;
mod partialeq_ne_impl;
+mod partialeq_to_none;
mod pass_by_ref_or_value;
-mod path_buf_push_overwrite;
mod pattern_type_mismatch;
mod precedence;
mod ptr;
@@ -353,7 +346,6 @@ mod redundant_static_lifetimes;
mod ref_option_ref;
mod reference;
mod regex;
-mod repeat_once;
mod return_self_not_must_use;
mod returns;
mod same_name_method;
@@ -365,7 +357,6 @@ mod single_char_lifetime_names;
mod single_component_path_imports;
mod size_of_in_element_count;
mod slow_vector_initialization;
-mod stable_sort_primitive;
mod std_instead_of_core;
mod strings;
mod strlen_on_c_strings;
@@ -379,23 +370,21 @@ mod to_digit_is_some;
mod trailing_empty_array;
mod trait_bounds;
mod transmute;
-mod transmuting_null;
mod types;
mod undocumented_unsafe_blocks;
mod unicode;
mod uninit_vec;
-mod unit_hash;
mod unit_return_expecting_ord;
mod unit_types;
mod unnamed_address;
mod unnecessary_owned_empty_strings;
mod unnecessary_self_imports;
-mod unnecessary_sort_by;
mod unnecessary_wraps;
mod unnested_or_patterns;
mod unsafe_removed_from_name;
mod unused_async;
mod unused_io_amount;
+mod unused_peekable;
mod unused_rounding;
mod unused_self;
mod unused_unit;
@@ -406,8 +395,6 @@ mod use_self;
mod useless_conversion;
mod vec;
mod vec_init_then_push;
-mod vec_resize_to_zero;
-mod verbose_file_reads;
mod wildcard_imports;
mod write;
mod zero_div_zero;
@@ -487,7 +474,7 @@ pub fn read_conf(sess: &Session) -> Conf {
},
};
- let TryConf { conf, errors } = utils::conf::read(&file_name);
+ let TryConf { conf, errors, warnings } = utils::conf::read(&file_name);
// all conf errors are non-fatal, we just use the default conf in case of error
for error in errors {
sess.err(&format!(
@@ -497,6 +484,15 @@ pub fn read_conf(sess: &Session) -> Conf {
));
}
+ for warning in warnings {
+ sess.struct_warn(&format!(
+ "error reading Clippy's configuration file `{}`: {}",
+ file_name.display(),
+ format_error(warning)
+ ))
+ .emit();
+ }
+
conf
}
@@ -538,70 +534,73 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
{
store.register_early_pass(|| Box::new(utils::internal_lints::ClippyLintsInternal));
store.register_early_pass(|| Box::new(utils::internal_lints::ProduceIce));
- store.register_late_pass(|| Box::new(utils::internal_lints::CollapsibleCalls));
- store.register_late_pass(|| Box::new(utils::internal_lints::CompilerLintFunctions::new()));
- store.register_late_pass(|| Box::new(utils::internal_lints::IfChainStyle));
- store.register_late_pass(|| Box::new(utils::internal_lints::InvalidPaths));
- store.register_late_pass(|| Box::new(utils::internal_lints::InterningDefinedSymbol::default()));
- store.register_late_pass(|| Box::new(utils::internal_lints::LintWithoutLintPass::default()));
- store.register_late_pass(|| Box::new(utils::internal_lints::MatchTypeOnDiagItem));
- store.register_late_pass(|| Box::new(utils::internal_lints::OuterExpnDataPass));
- store.register_late_pass(|| Box::new(utils::internal_lints::MsrvAttrImpl));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::CollapsibleCalls));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::CompilerLintFunctions::new()));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::IfChainStyle));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::InvalidPaths));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::InterningDefinedSymbol::default()));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::LintWithoutLintPass::default()));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::MatchTypeOnDiagItem));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::OuterExpnDataPass));
+ store.register_late_pass(|_| Box::new(utils::internal_lints::MsrvAttrImpl));
}
- let arithmetic_allowed = conf.arithmetic_allowed.clone();
- store.register_late_pass(move || Box::new(operators::arithmetic::Arithmetic::new(arithmetic_allowed.clone())));
- store.register_late_pass(|| Box::new(utils::dump_hir::DumpHir));
- store.register_late_pass(|| Box::new(utils::author::Author));
+ let arithmetic_side_effects_allowed = conf.arithmetic_side_effects_allowed.clone();
+ store.register_late_pass(move |_| {
+ Box::new(operators::arithmetic_side_effects::ArithmeticSideEffects::new(
+ arithmetic_side_effects_allowed.clone(),
+ ))
+ });
+ store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
+ store.register_late_pass(|_| Box::new(utils::author::Author));
let await_holding_invalid_types = conf.await_holding_invalid_types.clone();
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(await_holding_invalid::AwaitHolding::new(
await_holding_invalid_types.clone(),
))
});
- store.register_late_pass(|| Box::new(serde_api::SerdeApi));
+ store.register_late_pass(|_| Box::new(serde_api::SerdeApi));
let vec_box_size_threshold = conf.vec_box_size_threshold;
let type_complexity_threshold = conf.type_complexity_threshold;
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(types::Types::new(
vec_box_size_threshold,
type_complexity_threshold,
avoid_breaking_exported_api,
))
});
- store.register_late_pass(|| Box::new(booleans::NonminimalBool));
- store.register_late_pass(|| Box::new(enum_clike::UnportableVariant));
- store.register_late_pass(|| Box::new(float_literal::FloatLiteral));
- store.register_late_pass(|| Box::new(ptr::Ptr));
- store.register_late_pass(|| Box::new(needless_bool::NeedlessBool));
- store.register_late_pass(|| Box::new(needless_bool::BoolComparison));
- store.register_late_pass(|| Box::new(needless_for_each::NeedlessForEach));
- store.register_late_pass(|| Box::new(misc::MiscLints));
- store.register_late_pass(|| Box::new(eta_reduction::EtaReduction));
- store.register_late_pass(|| Box::new(mut_mut::MutMut));
- store.register_late_pass(|| Box::new(mut_reference::UnnecessaryMutPassed));
- store.register_late_pass(|| Box::new(len_zero::LenZero));
- store.register_late_pass(|| Box::new(attrs::Attributes));
- store.register_late_pass(|| Box::new(blocks_in_if_conditions::BlocksInIfConditions));
- store.register_late_pass(|| Box::new(unicode::Unicode));
- store.register_late_pass(|| Box::new(uninit_vec::UninitVec));
- store.register_late_pass(|| Box::new(unit_hash::UnitHash));
- store.register_late_pass(|| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
- store.register_late_pass(|| Box::new(strings::StringAdd));
- store.register_late_pass(|| Box::new(implicit_return::ImplicitReturn));
- store.register_late_pass(|| Box::new(implicit_saturating_sub::ImplicitSaturatingSub));
- store.register_late_pass(|| Box::new(default_numeric_fallback::DefaultNumericFallback));
- store.register_late_pass(|| Box::new(inconsistent_struct_constructor::InconsistentStructConstructor));
- store.register_late_pass(|| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
+ store.register_late_pass(|_| Box::new(booleans::NonminimalBool));
+ store.register_late_pass(|_| Box::new(enum_clike::UnportableVariant));
+ store.register_late_pass(|_| Box::new(float_literal::FloatLiteral));
+ store.register_late_pass(|_| Box::new(ptr::Ptr));
+ store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
+ store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
+ store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
+ store.register_late_pass(|_| Box::new(misc::MiscLints));
+ store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
+ store.register_late_pass(|_| Box::new(mut_mut::MutMut));
+ store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
+ store.register_late_pass(|_| Box::new(len_zero::LenZero));
+ store.register_late_pass(|_| Box::new(attrs::Attributes));
+ store.register_late_pass(|_| Box::new(blocks_in_if_conditions::BlocksInIfConditions));
+ store.register_late_pass(|_| Box::new(unicode::Unicode));
+ store.register_late_pass(|_| Box::new(uninit_vec::UninitVec));
+ store.register_late_pass(|_| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
+ store.register_late_pass(|_| Box::new(strings::StringAdd));
+ store.register_late_pass(|_| Box::new(implicit_return::ImplicitReturn));
+ store.register_late_pass(|_| Box::new(implicit_saturating_sub::ImplicitSaturatingSub));
+ store.register_late_pass(|_| Box::new(default_numeric_fallback::DefaultNumericFallback));
+ store.register_late_pass(|_| Box::new(inconsistent_struct_constructor::InconsistentStructConstructor));
+ store.register_late_pass(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
let msrv = read_msrv(conf, sess);
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
let allow_expect_in_tests = conf.allow_expect_in_tests;
let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
- store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv)));
+ store.register_late_pass(move |_| {
Box::new(methods::Methods::new(
avoid_breaking_exported_api,
msrv,
@@ -609,154 +608,148 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
allow_unwrap_in_tests,
))
});
- store.register_late_pass(move || Box::new(matches::Matches::new(msrv)));
+ store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv)));
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
- store.register_late_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
- store.register_late_pass(move || Box::new(manual_strip::ManualStrip::new(msrv)));
+ store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
+ store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv)));
store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv)));
store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(msrv)));
- store.register_late_pass(move || Box::new(checked_conversions::CheckedConversions::new(msrv)));
- store.register_late_pass(move || Box::new(mem_replace::MemReplace::new(msrv)));
- store.register_late_pass(move || Box::new(ranges::Ranges::new(msrv)));
- store.register_late_pass(move || Box::new(from_over_into::FromOverInto::new(msrv)));
- store.register_late_pass(move || Box::new(use_self::UseSelf::new(msrv)));
- store.register_late_pass(move || Box::new(missing_const_for_fn::MissingConstForFn::new(msrv)));
- store.register_late_pass(move || Box::new(needless_question_mark::NeedlessQuestionMark));
- store.register_late_pass(move || Box::new(casts::Casts::new(msrv)));
+ store.register_late_pass(move |_| Box::new(checked_conversions::CheckedConversions::new(msrv)));
+ store.register_late_pass(move |_| Box::new(mem_replace::MemReplace::new(msrv)));
+ store.register_late_pass(move |_| Box::new(ranges::Ranges::new(msrv)));
+ store.register_late_pass(move |_| Box::new(from_over_into::FromOverInto::new(msrv)));
+ store.register_late_pass(move |_| Box::new(use_self::UseSelf::new(msrv)));
+ store.register_late_pass(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(msrv)));
+ store.register_late_pass(move |_| Box::new(needless_question_mark::NeedlessQuestionMark));
+ store.register_late_pass(move |_| Box::new(casts::Casts::new(msrv)));
store.register_early_pass(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(msrv)));
- store.register_late_pass(move || Box::new(map_clone::MapClone::new(msrv)));
-
- store.register_late_pass(|| Box::new(size_of_in_element_count::SizeOfInElementCount));
- store.register_late_pass(|| Box::new(same_name_method::SameNameMethod));
+ store.register_late_pass(|_| Box::new(size_of_in_element_count::SizeOfInElementCount));
+ store.register_late_pass(|_| Box::new(same_name_method::SameNameMethod));
let max_suggested_slice_pattern_length = conf.max_suggested_slice_pattern_length;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(index_refutable_slice::IndexRefutableSlice::new(
max_suggested_slice_pattern_length,
msrv,
))
});
- store.register_late_pass(|| Box::new(map_err_ignore::MapErrIgnore));
- store.register_late_pass(|| Box::new(shadow::Shadow::default()));
- store.register_late_pass(|| Box::new(unit_types::UnitTypes));
- store.register_late_pass(|| Box::new(loops::Loops));
- store.register_late_pass(|| Box::new(main_recursion::MainRecursion::default()));
- store.register_late_pass(|| Box::new(lifetimes::Lifetimes));
- store.register_late_pass(|| Box::new(entry::HashMapPass));
- store.register_late_pass(|| Box::new(minmax::MinMaxPass));
- store.register_late_pass(|| Box::new(open_options::OpenOptions));
- store.register_late_pass(|| Box::new(zero_div_zero::ZeroDiv));
- store.register_late_pass(|| Box::new(mutex_atomic::Mutex));
- store.register_late_pass(|| Box::new(needless_update::NeedlessUpdate));
- store.register_late_pass(|| Box::new(needless_borrowed_ref::NeedlessBorrowedRef));
- store.register_late_pass(|| Box::new(borrow_deref_ref::BorrowDerefRef));
- store.register_late_pass(|| Box::new(no_effect::NoEffect));
- store.register_late_pass(|| Box::new(temporary_assignment::TemporaryAssignment));
- store.register_late_pass(move || Box::new(transmute::Transmute::new(msrv)));
+ store.register_late_pass(|_| Box::new(shadow::Shadow::default()));
+ store.register_late_pass(|_| Box::new(unit_types::UnitTypes));
+ store.register_late_pass(|_| Box::new(loops::Loops));
+ store.register_late_pass(|_| Box::new(main_recursion::MainRecursion::default()));
+ store.register_late_pass(|_| Box::new(lifetimes::Lifetimes));
+ store.register_late_pass(|_| Box::new(entry::HashMapPass));
+ store.register_late_pass(|_| Box::new(minmax::MinMaxPass));
+ store.register_late_pass(|_| Box::new(zero_div_zero::ZeroDiv));
+ store.register_late_pass(|_| Box::new(mutex_atomic::Mutex));
+ store.register_late_pass(|_| Box::new(needless_update::NeedlessUpdate));
+ store.register_late_pass(|_| Box::new(needless_borrowed_ref::NeedlessBorrowedRef));
+ store.register_late_pass(|_| Box::new(borrow_deref_ref::BorrowDerefRef));
+ store.register_late_pass(|_| Box::new(no_effect::NoEffect));
+ store.register_late_pass(|_| Box::new(temporary_assignment::TemporaryAssignment));
+ store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv)));
let cognitive_complexity_threshold = conf.cognitive_complexity_threshold;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(cognitive_complexity::CognitiveComplexity::new(
cognitive_complexity_threshold,
))
});
let too_large_for_stack = conf.too_large_for_stack;
- store.register_late_pass(move || Box::new(escape::BoxedLocal { too_large_for_stack }));
- store.register_late_pass(move || Box::new(vec::UselessVec { too_large_for_stack }));
- store.register_late_pass(|| Box::new(panic_unimplemented::PanicUnimplemented));
- store.register_late_pass(|| Box::new(strings::StringLitAsBytes));
- store.register_late_pass(|| Box::new(derive::Derive));
- store.register_late_pass(|| Box::new(derivable_impls::DerivableImpls));
- store.register_late_pass(|| Box::new(drop_forget_ref::DropForgetRef));
- store.register_late_pass(|| Box::new(empty_enum::EmptyEnum));
- store.register_late_pass(|| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
- store.register_late_pass(|| Box::new(regex::Regex));
- store.register_late_pass(|| Box::new(copies::CopyAndPaste));
- store.register_late_pass(|| Box::new(copy_iterator::CopyIterator));
- store.register_late_pass(|| Box::new(format::UselessFormat));
- store.register_late_pass(|| Box::new(swap::Swap));
- store.register_late_pass(|| Box::new(overflow_check_conditional::OverflowCheckConditional));
- store.register_late_pass(|| Box::new(new_without_default::NewWithoutDefault::default()));
- let blacklisted_names = conf.blacklisted_names.iter().cloned().collect::<FxHashSet<_>>();
- store.register_late_pass(move || Box::new(blacklisted_name::BlacklistedName::new(blacklisted_names.clone())));
+ store.register_late_pass(move |_| Box::new(escape::BoxedLocal { too_large_for_stack }));
+ store.register_late_pass(move |_| Box::new(vec::UselessVec { too_large_for_stack }));
+ store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
+ store.register_late_pass(|_| Box::new(strings::StringLitAsBytes));
+ store.register_late_pass(|_| Box::new(derive::Derive));
+ store.register_late_pass(|_| Box::new(derivable_impls::DerivableImpls));
+ store.register_late_pass(|_| Box::new(drop_forget_ref::DropForgetRef));
+ store.register_late_pass(|_| Box::new(empty_enum::EmptyEnum));
+ store.register_late_pass(|_| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
+ store.register_late_pass(|_| Box::new(regex::Regex));
+ store.register_late_pass(|_| Box::new(copies::CopyAndPaste));
+ store.register_late_pass(|_| Box::new(copy_iterator::CopyIterator));
+ store.register_late_pass(|_| Box::new(format::UselessFormat));
+ store.register_late_pass(|_| Box::new(swap::Swap));
+ store.register_late_pass(|_| Box::new(overflow_check_conditional::OverflowCheckConditional));
+ store.register_late_pass(|_| Box::new(new_without_default::NewWithoutDefault::default()));
+ let disallowed_names = conf.disallowed_names.iter().cloned().collect::<FxHashSet<_>>();
+ store.register_late_pass(move |_| Box::new(disallowed_names::DisallowedNames::new(disallowed_names.clone())));
let too_many_arguments_threshold = conf.too_many_arguments_threshold;
let too_many_lines_threshold = conf.too_many_lines_threshold;
- store.register_late_pass(move || {
+ let large_error_threshold = conf.large_error_threshold;
+ store.register_late_pass(move |_| {
Box::new(functions::Functions::new(
too_many_arguments_threshold,
too_many_lines_threshold,
+ large_error_threshold,
))
});
let doc_valid_idents = conf.doc_valid_idents.iter().cloned().collect::<FxHashSet<_>>();
- store.register_late_pass(move || Box::new(doc::DocMarkdown::new(doc_valid_idents.clone())));
- store.register_late_pass(|| Box::new(neg_multiply::NegMultiply));
- store.register_late_pass(|| Box::new(mem_forget::MemForget));
- store.register_late_pass(|| Box::new(let_if_seq::LetIfSeq));
- store.register_late_pass(|| Box::new(mixed_read_write_in_expression::EvalOrderDependence));
- store.register_late_pass(|| Box::new(missing_doc::MissingDoc::new()));
- store.register_late_pass(|| Box::new(missing_inline::MissingInline));
- store.register_late_pass(move || Box::new(exhaustive_items::ExhaustiveItems));
- store.register_late_pass(|| Box::new(match_result_ok::MatchResultOk));
- store.register_late_pass(|| Box::new(partialeq_ne_impl::PartialEqNeImpl));
- store.register_late_pass(|| Box::new(unused_io_amount::UnusedIoAmount));
+ store.register_late_pass(move |_| Box::new(doc::DocMarkdown::new(doc_valid_idents.clone())));
+ store.register_late_pass(|_| Box::new(neg_multiply::NegMultiply));
+ store.register_late_pass(|_| Box::new(mem_forget::MemForget));
+ store.register_late_pass(|_| Box::new(let_if_seq::LetIfSeq));
+ store.register_late_pass(|_| Box::new(mixed_read_write_in_expression::EvalOrderDependence));
+ store.register_late_pass(|_| Box::new(missing_doc::MissingDoc::new()));
+ store.register_late_pass(|_| Box::new(missing_inline::MissingInline));
+ store.register_late_pass(move |_| Box::new(exhaustive_items::ExhaustiveItems));
+ store.register_late_pass(|_| Box::new(match_result_ok::MatchResultOk));
+ store.register_late_pass(|_| Box::new(partialeq_ne_impl::PartialEqNeImpl));
+ store.register_late_pass(|_| Box::new(unused_io_amount::UnusedIoAmount));
let enum_variant_size_threshold = conf.enum_variant_size_threshold;
- store.register_late_pass(move || Box::new(large_enum_variant::LargeEnumVariant::new(enum_variant_size_threshold)));
- store.register_late_pass(|| Box::new(explicit_write::ExplicitWrite));
- store.register_late_pass(|| Box::new(needless_pass_by_value::NeedlessPassByValue));
+ store.register_late_pass(move |_| Box::new(large_enum_variant::LargeEnumVariant::new(enum_variant_size_threshold)));
+ store.register_late_pass(|_| Box::new(explicit_write::ExplicitWrite));
+ store.register_late_pass(|_| Box::new(needless_pass_by_value::NeedlessPassByValue));
let pass_by_ref_or_value = pass_by_ref_or_value::PassByRefOrValue::new(
conf.trivial_copy_size_limit,
conf.pass_by_value_size_limit,
conf.avoid_breaking_exported_api,
&sess.target,
);
- store.register_late_pass(move || Box::new(pass_by_ref_or_value));
- store.register_late_pass(|| Box::new(ref_option_ref::RefOptionRef));
- store.register_late_pass(|| Box::new(bytecount::ByteCount));
- store.register_late_pass(|| Box::new(infinite_iter::InfiniteIter));
- store.register_late_pass(|| Box::new(inline_fn_without_body::InlineFnWithoutBody));
- store.register_late_pass(|| Box::new(useless_conversion::UselessConversion::default()));
- store.register_late_pass(|| Box::new(implicit_hasher::ImplicitHasher));
- store.register_late_pass(|| Box::new(fallible_impl_from::FallibleImplFrom));
- store.register_late_pass(|| Box::new(question_mark::QuestionMark));
+ store.register_late_pass(move |_| Box::new(pass_by_ref_or_value));
+ store.register_late_pass(|_| Box::new(ref_option_ref::RefOptionRef));
+ store.register_late_pass(|_| Box::new(infinite_iter::InfiniteIter));
+ store.register_late_pass(|_| Box::new(inline_fn_without_body::InlineFnWithoutBody));
+ store.register_late_pass(|_| Box::new(useless_conversion::UselessConversion::default()));
+ store.register_late_pass(|_| Box::new(implicit_hasher::ImplicitHasher));
+ store.register_late_pass(|_| Box::new(fallible_impl_from::FallibleImplFrom));
+ store.register_late_pass(|_| Box::new(question_mark::QuestionMark));
store.register_early_pass(|| Box::new(suspicious_operation_groupings::SuspiciousOperationGroupings));
- store.register_late_pass(|| Box::new(suspicious_trait_impl::SuspiciousImpl));
- store.register_late_pass(|| Box::new(map_unit_fn::MapUnit));
- store.register_late_pass(|| Box::new(inherent_impl::MultipleInherentImpl));
- store.register_late_pass(|| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd));
- store.register_late_pass(|| Box::new(unwrap::Unwrap));
- store.register_late_pass(|| Box::new(indexing_slicing::IndexingSlicing));
- store.register_late_pass(|| Box::new(non_copy_const::NonCopyConst));
- store.register_late_pass(|| Box::new(ptr_offset_with_cast::PtrOffsetWithCast));
- store.register_late_pass(|| Box::new(redundant_clone::RedundantClone));
- store.register_late_pass(|| Box::new(slow_vector_initialization::SlowVectorInit));
- store.register_late_pass(|| Box::new(unnecessary_sort_by::UnnecessarySortBy));
- store.register_late_pass(move || Box::new(unnecessary_wraps::UnnecessaryWraps::new(avoid_breaking_exported_api)));
- store.register_late_pass(|| Box::new(assertions_on_constants::AssertionsOnConstants));
- store.register_late_pass(|| Box::new(assertions_on_result_states::AssertionsOnResultStates));
- store.register_late_pass(|| Box::new(transmuting_null::TransmutingNull));
- store.register_late_pass(|| Box::new(path_buf_push_overwrite::PathBufPushOverwrite));
- store.register_late_pass(|| Box::new(inherent_to_string::InherentToString));
+ store.register_late_pass(|_| Box::new(suspicious_trait_impl::SuspiciousImpl));
+ store.register_late_pass(|_| Box::new(map_unit_fn::MapUnit));
+ store.register_late_pass(|_| Box::new(inherent_impl::MultipleInherentImpl));
+ store.register_late_pass(|_| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd));
+ store.register_late_pass(|_| Box::new(unwrap::Unwrap));
+ store.register_late_pass(|_| Box::new(indexing_slicing::IndexingSlicing));
+ store.register_late_pass(|_| Box::new(non_copy_const::NonCopyConst));
+ store.register_late_pass(|_| Box::new(ptr_offset_with_cast::PtrOffsetWithCast));
+ store.register_late_pass(|_| Box::new(redundant_clone::RedundantClone));
+ store.register_late_pass(|_| Box::new(slow_vector_initialization::SlowVectorInit));
+ store.register_late_pass(move |_| Box::new(unnecessary_wraps::UnnecessaryWraps::new(avoid_breaking_exported_api)));
+ store.register_late_pass(|_| Box::new(assertions_on_constants::AssertionsOnConstants));
+ store.register_late_pass(|_| Box::new(assertions_on_result_states::AssertionsOnResultStates));
+ store.register_late_pass(|_| Box::new(inherent_to_string::InherentToString));
let max_trait_bounds = conf.max_trait_bounds;
- store.register_late_pass(move || Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
- store.register_late_pass(|| Box::new(comparison_chain::ComparisonChain));
- store.register_late_pass(|| Box::new(mut_key::MutableKeyType));
+ store.register_late_pass(move |_| Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
+ store.register_late_pass(|_| Box::new(comparison_chain::ComparisonChain));
+ store.register_late_pass(|_| Box::new(mut_key::MutableKeyType));
store.register_early_pass(|| Box::new(reference::DerefAddrOf));
store.register_early_pass(|| Box::new(double_parens::DoubleParens));
- store.register_late_pass(|| Box::new(format_impl::FormatImpl::new()));
+ store.register_late_pass(|_| Box::new(format_impl::FormatImpl::new()));
store.register_early_pass(|| Box::new(unsafe_removed_from_name::UnsafeNameRemoval));
store.register_early_pass(|| Box::new(else_if_without_else::ElseIfWithoutElse));
store.register_early_pass(|| Box::new(int_plus_one::IntPlusOne));
store.register_early_pass(|| Box::new(formatting::Formatting));
store.register_early_pass(|| Box::new(misc_early::MiscEarlyLints));
store.register_early_pass(|| Box::new(redundant_closure_call::RedundantClosureCall));
- store.register_late_pass(|| Box::new(redundant_closure_call::RedundantClosureCall));
+ store.register_late_pass(|_| Box::new(redundant_closure_call::RedundantClosureCall));
store.register_early_pass(|| Box::new(unused_unit::UnusedUnit));
- store.register_late_pass(|| Box::new(returns::Return));
+ store.register_late_pass(|_| Box::new(returns::Return));
store.register_early_pass(|| Box::new(collapsible_if::CollapsibleIf));
store.register_early_pass(|| Box::new(items_after_statements::ItemsAfterStatements));
store.register_early_pass(|| Box::new(precedence::Precedence));
- store.register_late_pass(|| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));
+ store.register_late_pass(|_| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));
store.register_early_pass(|| Box::new(needless_continue::NeedlessContinue));
store.register_early_pass(|| Box::new(redundant_else::RedundantElse));
- store.register_late_pass(|| Box::new(create_dir::CreateDir));
+ store.register_late_pass(|_| Box::new(create_dir::CreateDir));
store.register_early_pass(|| Box::new(needless_arbitrary_self_type::NeedlessArbitrarySelfType));
let literal_representation_lint_fraction_readability = conf.unreadable_literal_lint_fractions;
store.register_early_pass(move || {
@@ -771,7 +764,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
))
});
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(enum_variants::EnumVariantNames::new(
enum_variant_name_threshold,
avoid_breaking_exported_api,
@@ -779,23 +772,23 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments));
let upper_case_acronyms_aggressive = conf.upper_case_acronyms_aggressive;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(upper_case_acronyms::UpperCaseAcronyms::new(
avoid_breaking_exported_api,
upper_case_acronyms_aggressive,
))
});
- store.register_late_pass(|| Box::new(default::Default::default()));
- store.register_late_pass(move || Box::new(unused_self::UnusedSelf::new(avoid_breaking_exported_api)));
- store.register_late_pass(|| Box::new(mutable_debug_assertion::DebugAssertWithMutCall));
- store.register_late_pass(|| Box::new(exit::Exit));
- store.register_late_pass(|| Box::new(to_digit_is_some::ToDigitIsSome));
+ store.register_late_pass(|_| Box::new(default::Default::default()));
+ store.register_late_pass(move |_| Box::new(unused_self::UnusedSelf::new(avoid_breaking_exported_api)));
+ store.register_late_pass(|_| Box::new(mutable_debug_assertion::DebugAssertWithMutCall));
+ store.register_late_pass(|_| Box::new(exit::Exit));
+ store.register_late_pass(|_| Box::new(to_digit_is_some::ToDigitIsSome));
let array_size_threshold = conf.array_size_threshold;
- store.register_late_pass(move || Box::new(large_stack_arrays::LargeStackArrays::new(array_size_threshold)));
- store.register_late_pass(move || Box::new(large_const_arrays::LargeConstArrays::new(array_size_threshold)));
- store.register_late_pass(|| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
+ store.register_late_pass(move |_| Box::new(large_stack_arrays::LargeStackArrays::new(array_size_threshold)));
+ store.register_late_pass(move |_| Box::new(large_const_arrays::LargeConstArrays::new(array_size_threshold)));
+ store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
store.register_early_pass(|| Box::new(as_conversions::AsConversions));
- store.register_late_pass(|| Box::new(let_underscore::LetUnderscore));
+ store.register_late_pass(|_| Box::new(let_underscore::LetUnderscore));
store.register_early_pass(|| Box::new(single_component_path_imports::SingleComponentPathImports));
let max_fn_params_bools = conf.max_fn_params_bools;
let max_struct_bools = conf.max_struct_bools;
@@ -807,20 +800,17 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
let warn_on_all_wildcard_imports = conf.warn_on_all_wildcard_imports;
- store.register_late_pass(move || Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
- store.register_late_pass(|| Box::new(verbose_file_reads::VerboseFileReads));
- store.register_late_pass(|| Box::new(redundant_pub_crate::RedundantPubCrate::default()));
- store.register_late_pass(|| Box::new(unnamed_address::UnnamedAddress));
- store.register_late_pass(|| Box::new(dereference::Dereferencing::default()));
- store.register_late_pass(|| Box::new(option_if_let_else::OptionIfLetElse));
- store.register_late_pass(|| Box::new(future_not_send::FutureNotSend));
- store.register_late_pass(|| Box::new(if_let_mutex::IfLetMutex));
- store.register_late_pass(|| Box::new(if_not_else::IfNotElse));
- store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
- store.register_late_pass(|| Box::new(mut_mutex_lock::MutMutexLock));
- store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn));
- store.register_late_pass(|| Box::new(vec_resize_to_zero::VecResizeToZero));
- store.register_late_pass(|| Box::new(panic_in_result_fn::PanicInResultFn));
+ store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
+ store.register_late_pass(|_| Box::new(redundant_pub_crate::RedundantPubCrate::default()));
+ store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
+ store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv)));
+ store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
+ store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
+ store.register_late_pass(|_| Box::new(if_let_mutex::IfLetMutex));
+ store.register_late_pass(|_| Box::new(if_not_else::IfNotElse));
+ store.register_late_pass(|_| Box::new(equatable_if_let::PatternEquality));
+ store.register_late_pass(|_| Box::new(manual_async_fn::ManualAsyncFn));
+ store.register_late_pass(|_| Box::new(panic_in_result_fn::PanicInResultFn));
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
store.register_early_pass(move || {
Box::new(non_expressive_names::NonExpressiveNames {
@@ -829,98 +819,94 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
let macro_matcher = conf.standard_macro_braces.iter().cloned().collect::<FxHashSet<_>>();
store.register_early_pass(move || Box::new(nonstandard_macro_braces::MacroBraces::new(&macro_matcher)));
- store.register_late_pass(|| Box::new(macro_use::MacroUseImports::default()));
- store.register_late_pass(|| Box::new(pattern_type_mismatch::PatternTypeMismatch));
- store.register_late_pass(|| Box::new(stable_sort_primitive::StableSortPrimitive));
- store.register_late_pass(|| Box::new(repeat_once::RepeatOnce));
- store.register_late_pass(|| Box::new(unwrap_in_result::UnwrapInResult));
- store.register_late_pass(|| Box::new(manual_ok_or::ManualOkOr));
- store.register_late_pass(|| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
- store.register_late_pass(|| Box::new(async_yields_async::AsyncYieldsAsync));
+ store.register_late_pass(|_| Box::new(macro_use::MacroUseImports::default()));
+ store.register_late_pass(|_| Box::new(pattern_type_mismatch::PatternTypeMismatch));
+ store.register_late_pass(|_| Box::new(unwrap_in_result::UnwrapInResult));
+ store.register_late_pass(|_| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
+ store.register_late_pass(|_| Box::new(async_yields_async::AsyncYieldsAsync));
let disallowed_methods = conf.disallowed_methods.clone();
- store.register_late_pass(move || Box::new(disallowed_methods::DisallowedMethods::new(disallowed_methods.clone())));
+ store.register_late_pass(move |_| Box::new(disallowed_methods::DisallowedMethods::new(disallowed_methods.clone())));
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86AttSyntax));
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
- store.register_late_pass(|| Box::new(empty_drop::EmptyDrop));
- store.register_late_pass(|| Box::new(strings::StrToString));
- store.register_late_pass(|| Box::new(strings::StringToString));
- store.register_late_pass(|| Box::new(zero_sized_map_values::ZeroSizedMapValues));
- store.register_late_pass(|| Box::new(vec_init_then_push::VecInitThenPush::default()));
- store.register_late_pass(|| {
- Box::new(case_sensitive_file_extension_comparisons::CaseSensitiveFileExtensionComparisons)
- });
- store.register_late_pass(|| Box::new(redundant_slicing::RedundantSlicing));
- store.register_late_pass(|| Box::new(from_str_radix_10::FromStrRadix10));
- store.register_late_pass(move || Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv)));
- store.register_late_pass(|| Box::new(bool_assert_comparison::BoolAssertComparison));
+ store.register_late_pass(|_| Box::new(empty_drop::EmptyDrop));
+ store.register_late_pass(|_| Box::new(strings::StrToString));
+ store.register_late_pass(|_| Box::new(strings::StringToString));
+ store.register_late_pass(|_| Box::new(zero_sized_map_values::ZeroSizedMapValues));
+ store.register_late_pass(|_| Box::new(vec_init_then_push::VecInitThenPush::default()));
+ store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));
+ store.register_late_pass(|_| Box::new(from_str_radix_10::FromStrRadix10));
+ store.register_late_pass(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv)));
+ store.register_late_pass(|_| Box::new(bool_assert_comparison::BoolAssertComparison));
store.register_early_pass(move || Box::new(module_style::ModStyle));
- store.register_late_pass(|| Box::new(unused_async::UnusedAsync));
+ store.register_late_pass(|_| Box::new(unused_async::UnusedAsync));
let disallowed_types = conf.disallowed_types.clone();
- store.register_late_pass(move || Box::new(disallowed_types::DisallowedTypes::new(disallowed_types.clone())));
+ store.register_late_pass(move |_| Box::new(disallowed_types::DisallowedTypes::new(disallowed_types.clone())));
let import_renames = conf.enforced_import_renames.clone();
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(missing_enforced_import_rename::ImportRename::new(
import_renames.clone(),
))
});
let scripts = conf.allowed_scripts.clone();
store.register_early_pass(move || Box::new(disallowed_script_idents::DisallowedScriptIdents::new(&scripts)));
- store.register_late_pass(|| Box::new(strlen_on_c_strings::StrlenOnCStrings));
- store.register_late_pass(move || Box::new(self_named_constructors::SelfNamedConstructors));
- store.register_late_pass(move || Box::new(iter_not_returning_iterator::IterNotReturningIterator));
- store.register_late_pass(move || Box::new(manual_assert::ManualAssert));
+ store.register_late_pass(|_| Box::new(strlen_on_c_strings::StrlenOnCStrings));
+ store.register_late_pass(move |_| Box::new(self_named_constructors::SelfNamedConstructors));
+ store.register_late_pass(move |_| Box::new(iter_not_returning_iterator::IterNotReturningIterator));
+ store.register_late_pass(move |_| Box::new(manual_assert::ManualAssert));
let enable_raw_pointer_heuristic_for_send = conf.enable_raw_pointer_heuristic_for_send;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(non_send_fields_in_send_ty::NonSendFieldInSendTy::new(
enable_raw_pointer_heuristic_for_send,
))
});
- store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
- store.register_late_pass(move || Box::new(format_args::FormatArgs));
- store.register_late_pass(|| Box::new(trailing_empty_array::TrailingEmptyArray));
+ store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
+ store.register_late_pass(move |_| Box::new(format_args::FormatArgs));
+ store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
- store.register_late_pass(|| Box::new(needless_late_init::NeedlessLateInit));
- store.register_late_pass(|| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
- store.register_late_pass(|| Box::new(init_numbered_fields::NumberedFields));
+ store.register_late_pass(|_| Box::new(needless_late_init::NeedlessLateInit));
+ store.register_late_pass(|_| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
+ store.register_late_pass(|_| Box::new(init_numbered_fields::NumberedFields));
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
- store.register_late_pass(move || Box::new(borrow_as_ptr::BorrowAsPtr::new(msrv)));
- store.register_late_pass(move || Box::new(manual_bits::ManualBits::new(msrv)));
- store.register_late_pass(|| Box::new(default_union_representation::DefaultUnionRepresentation));
+ store.register_late_pass(move |_| Box::new(manual_bits::ManualBits::new(msrv)));
+ store.register_late_pass(|_| Box::new(default_union_representation::DefaultUnionRepresentation));
store.register_early_pass(|| Box::new(doc_link_with_quotes::DocLinkWithQuotes));
- store.register_late_pass(|| Box::new(only_used_in_recursion::OnlyUsedInRecursion));
+ store.register_late_pass(|_| Box::new(only_used_in_recursion::OnlyUsedInRecursion::default()));
let allow_dbg_in_tests = conf.allow_dbg_in_tests;
- store.register_late_pass(move || Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
+ store.register_late_pass(move |_| Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
let cargo_ignore_publish = conf.cargo_ignore_publish;
- store.register_late_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(cargo::Cargo {
ignore_publish: cargo_ignore_publish,
})
});
store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets));
- store.register_late_pass(|| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings));
+ store.register_late_pass(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings));
store.register_early_pass(|| Box::new(pub_use::PubUse));
- store.register_late_pass(|| Box::new(format_push_string::FormatPushString));
- store.register_late_pass(|| Box::new(bytes_count_to_len::BytesCountToLen));
+ store.register_late_pass(|_| Box::new(format_push_string::FormatPushString));
let max_include_file_size = conf.max_include_file_size;
- store.register_late_pass(move || Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
- store.register_late_pass(|| Box::new(strings::TrimSplitWhitespace));
- store.register_late_pass(|| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
+ store.register_late_pass(move |_| Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
+ store.register_late_pass(|_| Box::new(strings::TrimSplitWhitespace));
+ store.register_late_pass(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
store.register_early_pass(|| Box::new(duplicate_mod::DuplicateMod::default()));
- store.register_late_pass(|| Box::new(get_first::GetFirst));
store.register_early_pass(|| Box::new(unused_rounding::UnusedRounding));
store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv)));
- store.register_late_pass(|| Box::new(swap_ptr_to_ref::SwapPtrToRef));
- store.register_late_pass(|| Box::new(mismatching_type_param_order::TypeParamMismatch));
- store.register_late_pass(|| Box::new(as_underscore::AsUnderscore));
- store.register_late_pass(|| Box::new(read_zero_byte_vec::ReadZeroByteVec));
- store.register_late_pass(|| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
- store.register_late_pass(move || Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
- store.register_late_pass(move || Box::new(manual_retain::ManualRetain::new(msrv)));
+ store.register_late_pass(|_| Box::new(swap_ptr_to_ref::SwapPtrToRef));
+ store.register_late_pass(|_| Box::new(mismatching_type_param_order::TypeParamMismatch));
+ store.register_late_pass(|_| Box::new(read_zero_byte_vec::ReadZeroByteVec));
+ store.register_late_pass(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
+ store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
+ store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv)));
let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold;
- store.register_late_pass(move || Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
- store.register_late_pass(|| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
- store.register_late_pass(|| Box::new(std_instead_of_core::StdReexports::default()));
+ store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
+ store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
+ store.register_late_pass(|_| Box::new(std_instead_of_core::StdReexports::default()));
+ store.register_late_pass(|_| Box::new(manual_instant_elapsed::ManualInstantElapsed));
+ store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
+ store.register_late_pass(|_| Box::new(manual_string_new::ManualStringNew));
+ store.register_late_pass(|_| Box::new(unused_peekable::UnusedPeekable));
+ store.register_early_pass(|| Box::new(multi_assignments::MultiAssignments));
+ store.register_late_pass(|_| Box::new(bool_to_int_with_if::BoolToIntWithIf));
// add lints here, do not remove this comment, it's used in `new_lint`
}
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 573a7c016..643a7cfd5 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -10,7 +10,7 @@ use rustc_hir::FnRetTy::Return;
use rustc_hir::{
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin,
- TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
+ TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter as middle_nested_filter;
@@ -276,7 +276,7 @@ fn could_use_elision<'tcx>(
let mut checker = BodyLifetimeChecker {
lifetimes_used_in_body: false,
};
- checker.visit_expr(&body.value);
+ checker.visit_expr(body.value);
if checker.lifetimes_used_in_body {
return false;
}
@@ -422,7 +422,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
self.record(&Some(*lifetime));
}
- fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>, tbm: TraitBoundModifier) {
+ fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) {
let trait_ref = &poly_tref.trait_ref;
if CLOSURE_TRAIT_BOUNDS.iter().any(|&item| {
self.cx
@@ -435,13 +435,13 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
sub_visitor.visit_trait_ref(trait_ref);
self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
} else {
- walk_poly_trait_ref(self, poly_tref, tbm);
+ walk_poly_trait_ref(self, poly_tref);
}
}
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
match ty.kind {
- TyKind::OpaqueDef(item, bounds) => {
+ TyKind::OpaqueDef(item, bounds, _) => {
let map = self.cx.tcx.hir();
let item = map.item(item);
let len = self.lts.len();
@@ -466,7 +466,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
self.unelided_trait_object_lifetime = true;
}
for bound in bounds {
- self.visit_poly_trait_ref(bound, TraitBoundModifier::None);
+ self.visit_poly_trait_ref(bound);
}
},
_ => walk_ty(self, ty),
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
index 215c83a7e..09b2376d5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
@@ -106,7 +106,7 @@ fn get_binding(pat: &Pat<'_>) -> Option<HirId> {
hir_id = None;
return;
}
- if let BindingAnnotation::Unannotated = annotation {
+ if let BindingAnnotation::NONE = annotation {
hir_id = Some(id);
}
});
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index b31015d19..3fc569af8 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -119,11 +119,9 @@ fn build_manual_memcpy_suggestion<'tcx>(
let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| {
if_chain! {
- if let ExprKind::MethodCall(method, len_args, _) = end.kind;
+ if let ExprKind::MethodCall(method, recv, [], _) = end.kind;
if method.ident.name == sym::len;
- if len_args.len() == 1;
- if let Some(arg) = len_args.get(0);
- if path_to_local(arg) == path_to_local(base);
+ if path_to_local(recv) == path_to_local(base);
then {
if sugg.to_string() == end_str {
sugg::EMPTY.into()
@@ -343,10 +341,8 @@ fn get_slice_like_element_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Opti
fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
if_chain! {
- if let ExprKind::MethodCall(method, args, _) = expr.kind;
+ if let ExprKind::MethodCall(method, arg, [], _) = expr.kind;
if method.ident.name == sym::clone;
- if args.len() == 1;
- if let Some(arg) = args.get(0);
then { arg } else { expr }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
index 0696afa39..8412875b1 100644
--- a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
@@ -33,7 +33,7 @@ fn unpack_cond<'tcx>(cond: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>) {
if_chain! {
if let ExprKind::Block(Block { stmts: [], expr: None, ..}, _) = body.kind;
- if let ExprKind::MethodCall(method, [callee, ..], _) = unpack_cond(cond).kind;
+ if let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind;
if [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name);
if let ty::Adt(def, _substs) = cx.typeck_results().expr_ty(callee).kind();
if cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did());
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index ed270bd49..74f3bda9f 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -742,7 +742,7 @@ fn check_for_loop<'tcx>(
fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) {
let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used
- if let ExprKind::MethodCall(method, [self_arg], _) = arg.kind {
+ if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind {
let method_name = method.ident.as_str();
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
match method_name {
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index aedf3810b..fce2d5463 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -44,7 +44,7 @@ fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId>
if_chain! {
if let Some(hir_id) = path_to_local(bound);
if let Node::Pat(pat) = cx.tcx.hir().get(hir_id);
- if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind;
+ if let PatKind::Binding(BindingAnnotation::MUT, ..) = pat.kind;
then {
return Some(hir_id);
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs b/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
index ddaffc751..6e6faa79a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
@@ -1,5 +1,6 @@
use super::NEEDLESS_COLLECT;
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
+use clippy_utils::higher;
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
@@ -24,11 +25,11 @@ pub(super) fn check<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
}
fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
if_chain! {
- if let ExprKind::MethodCall(method, args, _) = expr.kind;
- if let ExprKind::MethodCall(chain_method, _, _) = args[0].kind;
- if chain_method.ident.name == sym!(collect) && is_trait_method(cx, &args[0], sym::Iterator);
+ if let ExprKind::MethodCall(method, receiver, args, _) = expr.kind;
+ if let ExprKind::MethodCall(chain_method, ..) = receiver.kind;
+ if chain_method.ident.name == sym!(collect) && is_trait_method(cx, receiver, sym::Iterator);
then {
- let ty = cx.typeck_results().expr_ty(&args[0]);
+ let ty = cx.typeck_results().expr_ty(receiver);
let mut applicability = Applicability::MaybeIncorrect;
let is_empty_sugg = "next().is_none()".to_string();
let method_name = method.ident.name.as_str();
@@ -40,7 +41,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
"len" => "count()".to_string(),
"is_empty" => is_empty_sugg,
"contains" => {
- let contains_arg = snippet_with_applicability(cx, args[1].span, "??", &mut applicability);
+ let contains_arg = snippet_with_applicability(cx, args[0].span, "??", &mut applicability);
let (arg, pred) = contains_arg
.strip_prefix('&')
.map_or(("&x", &*contains_arg), |s| ("x", s));
@@ -79,7 +80,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
if let StmtKind::Local(local) = stmt.kind;
if let PatKind::Binding(_, id, ..) = local.pat.kind;
if let Some(init_expr) = local.init;
- if let ExprKind::MethodCall(method_name, &[ref iter_source], ..) = init_expr.kind;
+ if let ExprKind::MethodCall(method_name, iter_source, [], ..) = init_expr.kind;
if method_name.ident.name == sym!(collect) && is_trait_method(cx, init_expr, sym::Iterator);
let ty = cx.typeck_results().expr_ty(init_expr);
if is_type_diagnostic_item(cx, ty, sym::Vec) ||
@@ -184,16 +185,25 @@ struct IterFunctionVisitor<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
fn visit_block(&mut self, block: &'tcx Block<'tcx>) {
for (expr, hir_id) in block.stmts.iter().filter_map(get_expr_and_hir_id_from_stmt) {
+ if check_loop_kind(expr).is_some() {
+ continue;
+ }
self.visit_block_expr(expr, hir_id);
}
if let Some(expr) = block.expr {
- self.visit_block_expr(expr, None);
+ if let Some(loop_kind) = check_loop_kind(expr) {
+ if let LoopKind::Conditional(block_expr) = loop_kind {
+ self.visit_block_expr(block_expr, None);
+ }
+ } else {
+ self.visit_block_expr(expr, None);
+ }
}
}
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
// Check function calls on our collection
- if let ExprKind::MethodCall(method_name, [recv, args @ ..], _) = &expr.kind {
+ if let ExprKind::MethodCall(method_name, recv, [args @ ..], _) = &expr.kind {
if method_name.ident.name == sym!(collect) && is_trait_method(self.cx, expr, sym::Iterator) {
self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv));
self.visit_expr(recv);
@@ -264,6 +274,28 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
}
}
+enum LoopKind<'tcx> {
+ Conditional(&'tcx Expr<'tcx>),
+ Loop,
+}
+
+fn check_loop_kind<'tcx>(expr: &Expr<'tcx>) -> Option<LoopKind<'tcx>> {
+ if let Some(higher::WhileLet { let_expr, .. }) = higher::WhileLet::hir(expr) {
+ return Some(LoopKind::Conditional(let_expr));
+ }
+ if let Some(higher::While { condition, .. }) = higher::While::hir(expr) {
+ return Some(LoopKind::Conditional(condition));
+ }
+ if let Some(higher::ForLoop { arg, .. }) = higher::ForLoop::hir(expr) {
+ return Some(LoopKind::Conditional(arg));
+ }
+ if let ExprKind::Loop { .. } = expr.kind {
+ return Some(LoopKind::Loop);
+ }
+
+ None
+}
+
impl<'tcx> IterFunctionVisitor<'_, 'tcx> {
fn visit_block_expr(&mut self, expr: &'tcx Expr<'tcx>, hir_id: Option<HirId>) {
self.current_statement_hir_id = hir_id;
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index a7ef562b2..8ab640051 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -188,10 +188,9 @@ pub(super) fn check<'tcx>(
fn is_len_call(expr: &Expr<'_>, var: Symbol) -> bool {
if_chain! {
- if let ExprKind::MethodCall(method, len_args, _) = expr.kind;
- if len_args.len() == 1;
+ if let ExprKind::MethodCall(method, recv, [], _) = expr.kind;
if method.ident.name == sym::len;
- if let ExprKind::Path(QPath::Resolved(_, path)) = len_args[0].kind;
+ if let ExprKind::Path(QPath::Resolved(_, path)) = recv.kind;
if path.segments.len() == 1;
if path.segments[0].ident.name == var;
then {
@@ -302,7 +301,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
if_chain! {
// a range index op
- if let ExprKind::MethodCall(meth, [args_0, args_1, ..], _) = &expr.kind;
+ if let ExprKind::MethodCall(meth, args_0, [args_1, ..], _) = &expr.kind;
if (meth.ident.name == sym::index && match_trait_method(self.cx, expr, &paths::INDEX))
|| (meth.ident.name == sym::index_mut && match_trait_method(self.cx, expr, &paths::INDEX_MUT));
if !self.check(args_1, args_0, expr);
@@ -357,9 +356,12 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
self.visit_expr(expr);
}
},
- ExprKind::MethodCall(_, args, _) => {
+ ExprKind::MethodCall(_, receiver, args, _) => {
let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
- for (ty, expr) in iter::zip(self.cx.tcx.fn_sig(def_id).inputs().skip_binder(), args) {
+ for (ty, expr) in iter::zip(
+ self.cx.tcx.fn_sig(def_id).inputs().skip_binder(),
+ std::iter::once(receiver).chain(args.iter()),
+ ) {
self.prefer_mutable = false;
if let ty::Ref(_, _, mutbl) = *ty.kind() {
if mutbl == Mutability::Mut {
@@ -371,7 +373,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
},
ExprKind::Closure(&Closure { body, .. }) => {
let body = self.cx.tcx.hir().body(body);
- self.visit_expr(&body.value);
+ self.visit_expr(body.value);
},
_ => walk_expr(self, expr),
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 32de20f65..116e589ca 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -120,8 +120,9 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
| ExprKind::Repeat(e, _)
| ExprKind::DropTemps(e) => never_loop_expr(e, main_loop_id),
ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, main_loop_id),
- ExprKind::Array(es) | ExprKind::MethodCall(_, es, _) | ExprKind::Tup(es) => {
- never_loop_expr_all(&mut es.iter(), main_loop_id)
+ ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(&mut es.iter(), main_loop_id),
+ ExprKind::MethodCall(_, receiver, es, _) => {
+ never_loop_expr_all(&mut std::iter::once(receiver).chain(es.iter()), main_loop_id)
},
ExprKind::Struct(_, fields, base) => {
let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), main_loop_id);
@@ -178,9 +179,9 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
never_loop_expr(expr, main_loop_id)
},
- InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id),
+ InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter().copied(), main_loop_id),
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
- never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id)
+ never_loop_expr_all(&mut once(*in_expr).chain(out_expr.iter().copied()), main_loop_id)
},
InlineAsmOperand::Const { .. }
| InlineAsmOperand::SymFn { .. }
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index 1439f1f4c..aeefe6e33 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -7,7 +7,7 @@ use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind};
+use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind};
use rustc_lint::LateContext;
use rustc_span::symbol::sym;
use std::iter::Iterator;
@@ -65,7 +65,7 @@ pub(super) fn check<'tcx>(
if_chain! {
if let Node::Pat(pat) = node;
if let PatKind::Binding(bind_ann, ..) = pat.kind;
- if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable);
+ if !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut));
let parent_node = cx.tcx.hir().get_parent_node(hir_id);
if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node);
if let Some(init) = parent_let_expr.init;
@@ -180,10 +180,9 @@ fn get_vec_push<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) -> Option<(&
if_chain! {
// Extract method being called
if let StmtKind::Semi(semi_stmt) = &stmt.kind;
- if let ExprKind::MethodCall(path, args, _) = &semi_stmt.kind;
+ if let ExprKind::MethodCall(path, self_expr, args, _) = &semi_stmt.kind;
// Figure out the parameters for the method call
- if let Some(self_expr) = args.get(0);
- if let Some(pushed_item) = args.get(1);
+ if let Some(pushed_item) = args.get(0);
// Check that the method being called is push() on a Vec
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec);
if path.ident.name.as_str() == "push";
diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
index a0bd7ad0a..f4b47808d 100644
--- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
@@ -35,32 +35,29 @@ pub(super) fn check<'tcx>(
) => (arg, "&mut "),
ExprKind::MethodCall(
method,
- [
- Expr {
- kind: ExprKind::Array([arg]),
- ..
- },
- ],
+ Expr {
+ kind: ExprKind::Array([arg]),
+ ..
+ },
+ [],
_,
) if method.ident.name == rustc_span::sym::iter => (arg, "&"),
ExprKind::MethodCall(
method,
- [
- Expr {
- kind: ExprKind::Array([arg]),
- ..
- },
- ],
+ Expr {
+ kind: ExprKind::Array([arg]),
+ ..
+ },
+ [],
_,
) if method.ident.name.as_str() == "iter_mut" => (arg, "&mut "),
ExprKind::MethodCall(
method,
- [
- Expr {
- kind: ExprKind::Array([arg]),
- ..
- },
- ],
+ Expr {
+ kind: ExprKind::Array([arg]),
+ ..
+ },
+ [],
_,
) if method.ident.name == rustc_span::sym::into_iter => (arg, ""),
// Only check for arrays edition 2021 or later, as this case will trigger a compiler error otherwise.
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs
index ca617859d..735d704a4 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs
@@ -11,7 +11,14 @@ use rustc_lint::LateContext;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {
let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) {
([stmt, stmts @ ..], expr) => {
- if let StmtKind::Local(&Local { init: Some(e), els: None, .. }) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
+ if let StmtKind::Local(&Local {
+ init: Some(e),
+ els: None,
+ ..
+ })
+ | StmtKind::Semi(e)
+ | StmtKind::Expr(e) = stmt.kind
+ {
(e, !stmts.is_empty() || expr.is_some())
} else {
return;
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
index e9e215e66..deb21894f 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Res::Def(_, pat_did) = pat_path.res;
if match_def_path(cx, pat_did, &paths::OPTION_SOME);
// check for call to `Iterator::next`
- if let ExprKind::MethodCall(method_name, [iter_expr], _) = let_expr.kind;
+ if let ExprKind::MethodCall(method_name, iter_expr, [], _) = let_expr.kind;
if method_name.ident.name == sym::next;
if is_trait_method(cx, let_expr, sym::Iterator);
if let Some(iter_expr_struct) = try_parse_iter_expr(cx, iter_expr);
@@ -356,7 +356,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
after_loop: false,
used_iter: false,
};
- v.visit_expr(&cx.tcx.hir().body(cx.enclosing_body.unwrap()).value);
+ v.visit_expr(cx.tcx.hir().body(cx.enclosing_body.unwrap()).value);
v.used_iter
}
}
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index a0ca7e6ff..754b0e78a 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -103,7 +103,7 @@ fn future_trait_ref<'tcx>(
ty: &'tcx Ty<'tcx>,
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
if_chain! {
- if let TyKind::OpaqueDef(item_id, bounds) = ty.kind;
+ if let TyKind::OpaqueDef(item_id, bounds, false) = ty.kind;
let item = cx.tcx.hir().item(item_id);
if let ItemKind::OpaqueTy(opaque) = &item.kind;
if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
@@ -192,7 +192,7 @@ fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str,
match output.kind {
TyKind::Tup(tys) if tys.is_empty() => {
let sugg = "remove the return type";
- Some((sugg, "".into()))
+ Some((sugg, String::new()))
},
_ => {
let sugg = "return the output of the future directly";
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index 60bbcde4f..6655c92b1 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -105,7 +105,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id);
then {
- cx.typeck_results().node_substs(count_func.hir_id).types().next().map(|resolved_ty| (real_ty, resolved_ty))
+ cx.typeck_results().node_substs(count_func.hir_id).types().next().map(|resolved_ty| (*real_ty, resolved_ty))
} else {
None
}
@@ -134,7 +134,7 @@ fn create_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, base_sugg: String) -> Stri
fn is_ty_conversion(expr: &Expr<'_>) -> bool {
if let ExprKind::Cast(..) = expr.kind {
true
- } else if let ExprKind::MethodCall(path, [_], _) = expr.kind
+ } else if let ExprKind::MethodCall(path, _, [], _) = expr.kind
&& path.ident.name == rustc_span::sym::try_into
{
// This is only called for `usize` which implements `TryInto`. Therefore,
diff --git a/src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs b/src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs
new file mode 100644
index 000000000..331cda1db
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs
@@ -0,0 +1,69 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::source_map::Spanned;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Lints subtraction between `Instant::now()` and another `Instant`.
+ ///
+ /// ### Why is this bad?
+ /// It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
+ /// as `Instant` subtraction saturates.
+ ///
+ /// `prev_instant.elapsed()` also more clearly signals intention.
+ ///
+ /// ### Example
+ /// ```rust
+ /// use std::time::Instant;
+ /// let prev_instant = Instant::now();
+ /// let duration = Instant::now() - prev_instant;
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// use std::time::Instant;
+ /// let prev_instant = Instant::now();
+ /// let duration = prev_instant.elapsed();
+ /// ```
+ #[clippy::version = "1.64.0"]
+ pub MANUAL_INSTANT_ELAPSED,
+ pedantic,
+ "subtraction between `Instant::now()` and previous `Instant`"
+}
+
+declare_lint_pass!(ManualInstantElapsed => [MANUAL_INSTANT_ELAPSED]);
+
+impl LateLintPass<'_> for ManualInstantElapsed {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
+ if let ExprKind::Binary(Spanned {node: BinOpKind::Sub, ..}, lhs, rhs) = expr.kind
+ && check_instant_now_call(cx, lhs)
+ && let ty_resolved = cx.typeck_results().expr_ty(rhs)
+ && let rustc_middle::ty::Adt(def, _) = ty_resolved.kind()
+ && clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT)
+ && let Some(sugg) = clippy_utils::sugg::Sugg::hir_opt(cx, rhs)
+ {
+ span_lint_and_sugg(
+ cx,
+ MANUAL_INSTANT_ELAPSED,
+ expr.span,
+ "manual implementation of `Instant::elapsed`",
+ "try",
+ format!("{}.elapsed()", sugg.maybe_par()),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+}
+
+fn check_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
+ if let ExprKind::Call(fn_expr, []) = expr_block.kind
+ && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
+ && clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
+ {
+ true
+ } else {
+ false
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/manual_ok_or.rs
deleted file mode 100644
index 9abf2507b..000000000
--- a/src/tools/clippy/clippy_lints/src/manual_ok_or.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_lang_ctor, path_to_local_id};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::LangItem::{ResultErr, ResultOk};
-use rustc_hir::{Closure, Expr, ExprKind, PatKind};
-use rustc_lint::LintContext;
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- ///
- /// Finds patterns that reimplement `Option::ok_or`.
- ///
- /// ### Why is this bad?
- ///
- /// Concise code helps focusing on behavior instead of boilerplate.
- ///
- /// ### Examples
- /// ```rust
- /// let foo: Option<i32> = None;
- /// foo.map_or(Err("error"), |v| Ok(v));
- /// ```
- ///
- /// Use instead:
- /// ```rust
- /// let foo: Option<i32> = None;
- /// foo.ok_or("error");
- /// ```
- #[clippy::version = "1.49.0"]
- pub MANUAL_OK_OR,
- pedantic,
- "finds patterns that can be encoded more concisely with `Option::ok_or`"
-}
-
-declare_lint_pass!(ManualOkOr => [MANUAL_OK_OR]);
-
-impl<'tcx> LateLintPass<'tcx> for ManualOkOr {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'tcx>) {
- if in_external_macro(cx.sess(), scrutinee.span) {
- return;
- }
-
- if_chain! {
- if let ExprKind::MethodCall(method_segment, args, _) = scrutinee.kind;
- if method_segment.ident.name == sym!(map_or);
- if args.len() == 3;
- let method_receiver = &args[0];
- let ty = cx.typeck_results().expr_ty(method_receiver);
- if is_type_diagnostic_item(cx, ty, sym::Option);
- let or_expr = &args[1];
- if is_ok_wrapping(cx, &args[2]);
- if let ExprKind::Call(Expr { kind: ExprKind::Path(err_path), .. }, &[ref err_arg]) = or_expr.kind;
- if is_lang_ctor(cx, err_path, ResultErr);
- if let Some(method_receiver_snippet) = snippet_opt(cx, method_receiver.span);
- if let Some(err_arg_snippet) = snippet_opt(cx, err_arg.span);
- if let Some(indent) = indent_of(cx, scrutinee.span);
- then {
- let reindented_err_arg_snippet =
- reindent_multiline(err_arg_snippet.into(), true, Some(indent + 4));
- span_lint_and_sugg(
- cx,
- MANUAL_OK_OR,
- scrutinee.span,
- "this pattern reimplements `Option::ok_or`",
- "replace with",
- format!(
- "{}.ok_or({})",
- method_receiver_snippet,
- reindented_err_arg_snippet
- ),
- Applicability::MachineApplicable,
- );
- }
- }
- }
-}
-
-fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {
- if let ExprKind::Path(ref qpath) = map_expr.kind {
- if is_lang_ctor(cx, qpath, ResultOk) {
- return true;
- }
- }
- if_chain! {
- if let ExprKind::Closure(&Closure { body, .. }) = map_expr.kind;
- let body = cx.tcx.hir().body(body);
- if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind;
- if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind;
- if is_lang_ctor(cx, ok_path, ResultOk);
- then { path_to_local_id(ok_arg, param_id) } else { false }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 42d2577cc..f28c37d3d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -66,9 +66,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if let Some(parent_expr) = get_parent_expr(cx, expr)
&& let Assign(left_expr, collect_expr, _) = &parent_expr.kind
- && let hir::ExprKind::MethodCall(seg, _, _) = &collect_expr.kind
+ && let hir::ExprKind::MethodCall(seg, ..) = &collect_expr.kind
&& seg.args.is_none()
- && let hir::ExprKind::MethodCall(_, [target_expr], _) = &collect_expr.kind
+ && let hir::ExprKind::MethodCall(_, target_expr, [], _) = &collect_expr.kind
&& let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
&& match_def_path(cx, collect_def_id, &paths::CORE_ITER_COLLECT) {
check_into_iter(cx, parent_expr, left_expr, target_expr, self.msrv);
@@ -87,10 +87,10 @@ fn check_into_iter(
target_expr: &hir::Expr<'_>,
msrv: Option<RustcVersion>,
) {
- if let hir::ExprKind::MethodCall(_, [into_iter_expr, _], _) = &target_expr.kind
+ if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
&& let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
- && let hir::ExprKind::MethodCall(_, [struct_expr], _) = &into_iter_expr.kind
+ && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
&& let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
&& match_def_path(cx, into_iter_def_id, &paths::CORE_ITER_INTO_ITER)
&& match_acceptable_type(cx, left_expr, msrv)
@@ -106,14 +106,14 @@ fn check_iter(
target_expr: &hir::Expr<'_>,
msrv: Option<RustcVersion>,
) {
- if let hir::ExprKind::MethodCall(_, [filter_expr], _) = &target_expr.kind
+ if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
&& let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
&& (match_def_path(cx, copied_def_id, &paths::CORE_ITER_COPIED)
|| match_def_path(cx, copied_def_id, &paths::CORE_ITER_CLONED))
- && let hir::ExprKind::MethodCall(_, [iter_expr, _], _) = &filter_expr.kind
+ && let hir::ExprKind::MethodCall(_, iter_expr, [_], _) = &filter_expr.kind
&& let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
- && let hir::ExprKind::MethodCall(_, [struct_expr], _) = &iter_expr.kind
+ && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &iter_expr.kind
&& let Some(iter_expr_def_id) = cx.typeck_results().type_dependent_def_id(iter_expr.hir_id)
&& match_acceptable_def_path(cx, iter_expr_def_id)
&& match_acceptable_type(cx, left_expr, msrv)
@@ -130,13 +130,13 @@ fn check_to_owned(
msrv: Option<RustcVersion>,
) {
if meets_msrv(msrv, msrvs::STRING_RETAIN)
- && let hir::ExprKind::MethodCall(_, [filter_expr], _) = &target_expr.kind
+ && let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
&& let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
&& match_def_path(cx, to_owned_def_id, &paths::TO_OWNED_METHOD)
- && let hir::ExprKind::MethodCall(_, [chars_expr, _], _) = &filter_expr.kind
+ && let hir::ExprKind::MethodCall(_, chars_expr, [_], _) = &filter_expr.kind
&& let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
- && let hir::ExprKind::MethodCall(_, [str_expr], _) = &chars_expr.kind
+ && let hir::ExprKind::MethodCall(_, str_expr, [], _) = &chars_expr.kind
&& let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
&& match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
@@ -147,7 +147,7 @@ fn check_to_owned(
}
fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) {
- if let hir::ExprKind::MethodCall(_, [_, closure], _) = filter_expr.kind
+ if let hir::ExprKind::MethodCall(_, _, [closure], _) = filter_expr.kind
&& let hir::ExprKind::Closure(&hir::Closure { body, ..}) = closure.kind
&& let filter_body = cx.tcx.hir().body(body)
&& let [filter_params] = filter_body.params
diff --git a/src/tools/clippy/clippy_lints/src/manual_string_new.rs b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
new file mode 100644
index 000000000..6acfb2ae3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
@@ -0,0 +1,135 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::LitKind;
+use rustc_errors::Applicability::MachineApplicable;
+use rustc_hir::{Expr, ExprKind, PathSegment, QPath, TyKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{sym, symbol, Span};
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks for usage of `""` to create a `String`, such as `"".to_string()`, `"".to_owned()`,
+ /// `String::from("")` and others.
+ ///
+ /// ### Why is this bad?
+ ///
+ /// Different ways of creating an empty string makes your code less standardized, which can
+ /// be confusing.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let a = "".to_string();
+ /// let b: String = "".into();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let a = String::new();
+ /// let b = String::new();
+ /// ```
+ #[clippy::version = "1.65.0"]
+ pub MANUAL_STRING_NEW,
+ pedantic,
+ "empty String is being created manually"
+}
+declare_lint_pass!(ManualStringNew => [MANUAL_STRING_NEW]);
+
+impl LateLintPass<'_> for ManualStringNew {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ if expr.span.from_expansion() {
+ return;
+ }
+
+ let ty = cx.typeck_results().expr_ty(expr);
+ match ty.kind() {
+ ty::Adt(adt_def, _) if adt_def.is_struct() => {
+ if !cx.tcx.is_diagnostic_item(sym::String, adt_def.did()) {
+ return;
+ }
+ },
+ _ => return,
+ }
+
+ match expr.kind {
+ ExprKind::Call(func, args) => {
+ parse_call(cx, expr.span, func, args);
+ },
+ ExprKind::MethodCall(path_segment, receiver, ..) => {
+ parse_method_call(cx, expr.span, path_segment, receiver);
+ },
+ _ => (),
+ }
+ }
+}
+
+/// Checks if an expression's kind corresponds to an empty &str.
+fn is_expr_kind_empty_str(expr_kind: &ExprKind<'_>) -> bool {
+ if let ExprKind::Lit(lit) = expr_kind &&
+ let LitKind::Str(value, _) = lit.node &&
+ value == symbol::kw::Empty
+ {
+ return true;
+ }
+
+ false
+}
+
+fn warn_then_suggest(cx: &LateContext<'_>, span: Span) {
+ span_lint_and_sugg(
+ cx,
+ MANUAL_STRING_NEW,
+ span,
+ "empty String is being created manually",
+ "consider using",
+ "String::new()".into(),
+ MachineApplicable,
+ );
+}
+
+/// Tries to parse an expression as a method call, emitting the warning if necessary.
+fn parse_method_call(cx: &LateContext<'_>, span: Span, path_segment: &PathSegment<'_>, receiver: &Expr<'_>) {
+ let ident = path_segment.ident.as_str();
+ let method_arg_kind = &receiver.kind;
+ if ["to_string", "to_owned", "into"].contains(&ident) && is_expr_kind_empty_str(method_arg_kind) {
+ warn_then_suggest(cx, span);
+ } else if let ExprKind::Call(func, args) = method_arg_kind {
+ // If our first argument is a function call itself, it could be an `unwrap`-like function.
+ // E.g. String::try_from("hello").unwrap(), TryFrom::try_from("").expect("hello"), etc.
+ parse_call(cx, span, func, args);
+ }
+}
+
+/// Tries to parse an expression as a function call, emitting the warning if necessary.
+fn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, args: &[Expr<'_>]) {
+ if args.len() != 1 {
+ return;
+ }
+
+ let arg_kind = &args[0].kind;
+ if let ExprKind::Path(qpath) = &func.kind {
+ if let QPath::TypeRelative(_, _) = qpath {
+ // String::from(...) or String::try_from(...)
+ if let QPath::TypeRelative(ty, path_seg) = qpath &&
+ [sym::from, sym::try_from].contains(&path_seg.ident.name) &&
+ let TyKind::Path(qpath) = &ty.kind &&
+ let QPath::Resolved(_, path) = qpath &&
+ let [path_seg] = path.segments &&
+ path_seg.ident.name == sym::String &&
+ is_expr_kind_empty_str(arg_kind)
+ {
+ warn_then_suggest(cx, span);
+ }
+ } else if let QPath::Resolved(_, path) = qpath {
+ // From::from(...) or TryFrom::try_from(...)
+ if let [path_seg1, path_seg2] = path.segments &&
+ is_expr_kind_empty_str(arg_kind) && (
+ (path_seg1.ident.name == sym::From && path_seg2.ident.name == sym::from) ||
+ (path_seg1.ident.name == sym::TryFrom && path_seg2.ident.name == sym::try_from)
+ )
+ {
+ warn_then_suggest(cx, span);
+ }
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index dfb3efc4e..7941c8c9c 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
if_chain! {
if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr);
- if let ExprKind::MethodCall(_, [target_arg, pattern], _) = cond.kind;
+ if let ExprKind::MethodCall(_, target_arg, [pattern], _) = cond.kind;
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(cond.hir_id);
if let ExprKind::Path(target_path) = &target_arg.kind;
then {
@@ -132,7 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
// Returns `Some(arg)` if `expr` matches `arg.len()` and `None` otherwise.
fn len_arg<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
if_chain! {
- if let ExprKind::MethodCall(_, [arg], _) = expr.kind;
+ if let ExprKind::MethodCall(_, arg, [], _) = expr.kind;
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if match_def_path(cx, method_def_id, &paths::STR_LEN);
then {
diff --git a/src/tools/clippy/clippy_lints/src/map_clone.rs b/src/tools/clippy/clippy_lints/src/map_clone.rs
deleted file mode 100644
index 95c312f1f..000000000
--- a/src/tools/clippy/clippy_lints/src/map_clone.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
-use clippy_utils::{is_trait_method, meets_msrv, msrvs, peel_blocks};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir as hir;
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::Mutability;
-use rustc_middle::ty;
-use rustc_middle::ty::adjustment::Adjust;
-use rustc_semver::RustcVersion;
-use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span};
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for usage of `map(|x| x.clone())` or
- /// dereferencing closures for `Copy` types, on `Iterator` or `Option`,
- /// and suggests `cloned()` or `copied()` instead
- ///
- /// ### Why is this bad?
- /// Readability, this can be written more concisely
- ///
- /// ### Example
- /// ```rust
- /// let x = vec![42, 43];
- /// let y = x.iter();
- /// let z = y.map(|i| *i);
- /// ```
- ///
- /// The correct use would be:
- ///
- /// ```rust
- /// let x = vec![42, 43];
- /// let y = x.iter();
- /// let z = y.cloned();
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub MAP_CLONE,
- style,
- "using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types"
-}
-
-pub struct MapClone {
- msrv: Option<RustcVersion>,
-}
-
-impl_lint_pass!(MapClone => [MAP_CLONE]);
-
-impl MapClone {
- pub fn new(msrv: Option<RustcVersion>) -> Self {
- Self { msrv }
- }
-}
-
-impl<'tcx> LateLintPass<'tcx> for MapClone {
- fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) {
- if e.span.from_expansion() {
- return;
- }
-
- if_chain! {
- if let hir::ExprKind::MethodCall(method, args, _) = e.kind;
- if args.len() == 2;
- if method.ident.name == sym::map;
- let ty = cx.typeck_results().expr_ty(&args[0]);
- if is_type_diagnostic_item(cx, ty, sym::Option) || is_trait_method(cx, e, sym::Iterator);
- if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = args[1].kind;
- then {
- let closure_body = cx.tcx.hir().body(body);
- let closure_expr = peel_blocks(&closure_body.value);
- match closure_body.params[0].pat.kind {
- hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding(
- hir::BindingAnnotation::Unannotated, .., name, None
- ) = inner.kind {
- if ident_eq(name, closure_expr) {
- self.lint_explicit_closure(cx, e.span, args[0].span, true);
- }
- },
- hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, .., name, None) => {
- match closure_expr.kind {
- hir::ExprKind::Unary(hir::UnOp::Deref, inner) => {
- if ident_eq(name, inner) {
- if let ty::Ref(.., Mutability::Not) = cx.typeck_results().expr_ty(inner).kind() {
- self.lint_explicit_closure(cx, e.span, args[0].span, true);
- }
- }
- },
- hir::ExprKind::MethodCall(method, [obj], _) => if_chain! {
- if ident_eq(name, obj) && method.ident.name == sym::clone;
- if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id);
- if let Some(trait_id) = cx.tcx.trait_of_item(fn_id);
- if cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id);
- // no autoderefs
- if !cx.typeck_results().expr_adjustments(obj).iter()
- .any(|a| matches!(a.kind, Adjust::Deref(Some(..))));
- then {
- let obj_ty = cx.typeck_results().expr_ty(obj);
- if let ty::Ref(_, ty, mutability) = obj_ty.kind() {
- if matches!(mutability, Mutability::Not) {
- let copy = is_copy(cx, *ty);
- self.lint_explicit_closure(cx, e.span, args[0].span, copy);
- }
- } else {
- lint_needless_cloning(cx, e.span, args[0].span);
- }
- }
- },
- _ => {},
- }
- },
- _ => {},
- }
- }
- }
- }
-
- extract_msrv_attr!(LateContext);
-}
-
-fn ident_eq(name: Ident, path: &hir::Expr<'_>) -> bool {
- if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = path.kind {
- path.segments.len() == 1 && path.segments[0].ident == name
- } else {
- false
- }
-}
-
-fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
- span_lint_and_sugg(
- cx,
- MAP_CLONE,
- root.trim_start(receiver).unwrap(),
- "you are needlessly cloning iterator elements",
- "remove the `map` call",
- String::new(),
- Applicability::MachineApplicable,
- );
-}
-
-impl MapClone {
- fn lint_explicit_closure(&self, cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {
- let mut applicability = Applicability::MachineApplicable;
-
- let (message, sugg_method) = if is_copy && meets_msrv(self.msrv, msrvs::ITERATOR_COPIED) {
- ("you are using an explicit closure for copying elements", "copied")
- } else {
- ("you are using an explicit closure for cloning elements", "cloned")
- };
-
- span_lint_and_sugg(
- cx,
- MAP_CLONE,
- replace,
- message,
- &format!("consider calling the dedicated `{}` method", sugg_method),
- format!(
- "{}.{}()",
- snippet_with_applicability(cx, root, "..", &mut applicability),
- sugg_method,
- ),
- applicability,
- );
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/map_err_ignore.rs
deleted file mode 100644
index 21d0e19eb..000000000
--- a/src/tools/clippy/clippy_lints/src/map_err_ignore.rs
+++ /dev/null
@@ -1,154 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{CaptureBy, Closure, Expr, ExprKind, PatKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for instances of `map_err(|_| Some::Enum)`
- ///
- /// ### Why is this bad?
- /// This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error
- ///
- /// ### Example
- /// Before:
- /// ```rust
- /// use std::fmt;
- ///
- /// #[derive(Debug)]
- /// enum Error {
- /// Indivisible,
- /// Remainder(u8),
- /// }
- ///
- /// impl fmt::Display for Error {
- /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- /// match self {
- /// Error::Indivisible => write!(f, "could not divide input by three"),
- /// Error::Remainder(remainder) => write!(
- /// f,
- /// "input is not divisible by three, remainder = {}",
- /// remainder
- /// ),
- /// }
- /// }
- /// }
- ///
- /// impl std::error::Error for Error {}
- ///
- /// fn divisible_by_3(input: &str) -> Result<(), Error> {
- /// input
- /// .parse::<i32>()
- /// .map_err(|_| Error::Indivisible)
- /// .map(|v| v % 3)
- /// .and_then(|remainder| {
- /// if remainder == 0 {
- /// Ok(())
- /// } else {
- /// Err(Error::Remainder(remainder as u8))
- /// }
- /// })
- /// }
- /// ```
- ///
- /// After:
- /// ```rust
- /// use std::{fmt, num::ParseIntError};
- ///
- /// #[derive(Debug)]
- /// enum Error {
- /// Indivisible(ParseIntError),
- /// Remainder(u8),
- /// }
- ///
- /// impl fmt::Display for Error {
- /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- /// match self {
- /// Error::Indivisible(_) => write!(f, "could not divide input by three"),
- /// Error::Remainder(remainder) => write!(
- /// f,
- /// "input is not divisible by three, remainder = {}",
- /// remainder
- /// ),
- /// }
- /// }
- /// }
- ///
- /// impl std::error::Error for Error {
- /// fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- /// match self {
- /// Error::Indivisible(source) => Some(source),
- /// _ => None,
- /// }
- /// }
- /// }
- ///
- /// fn divisible_by_3(input: &str) -> Result<(), Error> {
- /// input
- /// .parse::<i32>()
- /// .map_err(Error::Indivisible)
- /// .map(|v| v % 3)
- /// .and_then(|remainder| {
- /// if remainder == 0 {
- /// Ok(())
- /// } else {
- /// Err(Error::Remainder(remainder as u8))
- /// }
- /// })
- /// }
- /// ```
- #[clippy::version = "1.48.0"]
- pub MAP_ERR_IGNORE,
- restriction,
- "`map_err` should not ignore the original error"
-}
-
-declare_lint_pass!(MapErrIgnore => [MAP_ERR_IGNORE]);
-
-impl<'tcx> LateLintPass<'tcx> for MapErrIgnore {
- // do not try to lint if this is from a macro or desugaring
- fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
- if e.span.from_expansion() {
- return;
- }
-
- // check if this is a method call (e.g. x.foo())
- if let ExprKind::MethodCall(method, args, _) = e.kind {
- // only work if the method name is `map_err` and there are only 2 arguments (e.g. x.map_err(|_|[1]
- // Enum::Variant[2]))
- if method.ident.as_str() == "map_err" && args.len() == 2 {
- // make sure the first argument is a closure, and grab the CaptureRef, BodyId, and fn_decl_span
- // fields
- if let ExprKind::Closure(&Closure {
- capture_clause,
- body,
- fn_decl_span,
- ..
- }) = args[1].kind
- {
- // check if this is by Reference (meaning there's no move statement)
- if capture_clause == CaptureBy::Ref {
- // Get the closure body to check the parameters and values
- let closure_body = cx.tcx.hir().body(body);
- // make sure there's only one parameter (`|_|`)
- if closure_body.params.len() == 1 {
- // make sure that parameter is the wild token (`_`)
- if let PatKind::Wild = closure_body.params[0].pat.kind {
- // span the area of the closure capture and warn that the
- // original error will be thrown away
- span_lint_and_help(
- cx,
- MAP_ERR_IGNORE,
- fn_decl_span,
- "`map_err(|_|...` wildcard pattern discards the original error",
- None,
- "consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)",
- );
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index af9d948af..33d744815 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -97,11 +97,7 @@ declare_clippy_lint! {
declare_lint_pass!(MapUnit => [OPTION_MAP_UNIT_FN, RESULT_MAP_UNIT_FN]);
fn is_unit_type(ty: Ty<'_>) -> bool {
- match ty.kind() {
- ty::Tuple(slice) => slice.is_empty(),
- ty::Never => true,
- _ => false,
- }
+ ty.is_unit() || ty.is_never()
}
fn is_unit_function(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
@@ -204,8 +200,13 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String {
)
}
-fn lint_map_unit_fn(cx: &LateContext<'_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) {
- let var_arg = &map_args[0];
+fn lint_map_unit_fn(
+ cx: &LateContext<'_>,
+ stmt: &hir::Stmt<'_>,
+ expr: &hir::Expr<'_>,
+ map_args: (&hir::Expr<'_>, &[hir::Expr<'_>]),
+) {
+ let var_arg = &map_args.0;
let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Option) {
("Option", "Some", OPTION_MAP_UNIT_FN)
@@ -214,7 +215,7 @@ fn lint_map_unit_fn(cx: &LateContext<'_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr
} else {
return;
};
- let fn_arg = &map_args[1];
+ let fn_arg = &map_args.1[0];
if is_unit_function(cx, fn_arg) {
let mut applicability = Applicability::MachineApplicable;
diff --git a/src/tools/clippy/clippy_lints/src/match_result_ok.rs b/src/tools/clippy/clippy_lints/src/match_result_ok.rs
index 3349b85f1..8588ab1ed 100644
--- a/src/tools/clippy/clippy_lints/src/match_result_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/match_result_ok.rs
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchResultOk {
};
if_chain! {
- if let ExprKind::MethodCall(ok_path, [ref result_types_0, ..], _) = let_expr.kind; //check is expr.ok() has type Result<T,E>.ok(, _)
+ if let ExprKind::MethodCall(ok_path, result_types_0, ..) = let_expr.kind; //check is expr.ok() has type Result<T,E>.ok(, _)
if let PatKind::TupleStruct(QPath::Resolved(_, x), y, _) = let_pat.kind; //get operation
if method_chain_args(let_expr, &["ok"]).is_some(); //test to see if using ok() method use std::marker::Sized;
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(result_types_0), sym::Result);
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_map.rs b/src/tools/clippy/clippy_lints/src/matches/manual_map.rs
index 8f98b43b9..b0198e856 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_map.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_map.rs
@@ -165,7 +165,7 @@ fn check<'tcx>(
}
// `ref` and `ref mut` annotations were handled earlier.
- let annotation = if matches!(annotation, BindingAnnotation::Mutable) {
+ let annotation = if matches!(annotation, BindingAnnotation::MUT) {
"mut "
} else {
""
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
index d914eba01..91d17f481 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_lang_ctor, peel_blocks};
use rustc_errors::Applicability;
-use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, LangItem, PatKind, QPath};
+use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath};
use rustc_lint::LateContext;
use rustc_middle::ty;
@@ -10,18 +10,17 @@ use super::MATCH_AS_REF;
pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
- let arm_ref: Option<BindingAnnotation> = if is_none_arm(cx, &arms[0]) {
+ let arm_ref_mut = if is_none_arm(cx, &arms[0]) {
is_ref_some_arm(cx, &arms[1])
} else if is_none_arm(cx, &arms[1]) {
is_ref_some_arm(cx, &arms[0])
} else {
None
};
- if let Some(rb) = arm_ref {
- let suggestion = if rb == BindingAnnotation::Ref {
- "as_ref"
- } else {
- "as_mut"
+ if let Some(rb) = arm_ref_mut {
+ let suggestion = match rb {
+ Mutability::Not => "as_ref",
+ Mutability::Mut => "as_mut",
};
let output_ty = cx.typeck_results().expr_ty(expr);
@@ -66,19 +65,18 @@ fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
}
// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
-fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<BindingAnnotation> {
+fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
if_chain! {
if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind;
if is_lang_ctor(cx, qpath, LangItem::OptionSome);
- if let PatKind::Binding(rb, .., ident, _) = first_pat.kind;
- if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
- if let ExprKind::Call(e, args) = peel_blocks(arm.body).kind;
+ if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., ident, _) = first_pat.kind;
+ if let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind;
if let ExprKind::Path(ref some_path) = e.kind;
- if is_lang_ctor(cx, some_path, LangItem::OptionSome) && args.len() == 1;
- if let ExprKind::Path(QPath::Resolved(_, path2)) = args[0].kind;
+ if is_lang_ctor(cx, some_path, LangItem::OptionSome);
+ if let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind;
if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
then {
- return Some(rb)
+ return Some(mutabl)
}
}
None
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index 0da4833f1..34cc08268 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -1,10 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_wild;
use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::span_contains_comment;
use rustc_ast::{Attribute, LitKind};
use rustc_errors::Applicability;
use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Guard, Pat};
-use rustc_lint::LateContext;
+use rustc_lint::{LateContext, LintContext};
use rustc_middle::ty;
use rustc_span::source_map::Spanned;
@@ -76,6 +77,7 @@ where
>,
{
if_chain! {
+ if !span_contains_comment(cx.sess().source_map(), expr.span);
if iter.len() >= 2;
if cx.typeck_results().expr_ty(expr).is_bool();
if let Some((_, last_pat_opt, last_expr, _)) = iter.next_back();
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index 582782f24..d37f44d4a 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -8,11 +8,10 @@ use rustc_arena::DroplessArena;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
-use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdSet, Pat, PatKind, RangeEnd};
+use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatKind, RangeEnd};
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::Symbol;
-use std::collections::hash_map::Entry;
use super::MATCH_SAME_ARMS;
@@ -71,9 +70,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
if let Some(a_id) = path_to_local(a);
if let Some(b_id) = path_to_local(b);
let entry = match local_map.entry(a_id) {
- Entry::Vacant(entry) => entry,
+ HirIdMapEntry::Vacant(entry) => entry,
// check if using the same bindings as before
- Entry::Occupied(entry) => return *entry.get() == b_id,
+ HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id,
};
// the names technically don't have to match; this makes the lint more conservative
if cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id);
@@ -248,7 +247,7 @@ impl<'a> NormalizedPat<'a> {
} else {
(None, adt.non_enum_variant())
};
- let (front, back) = match wild_idx {
+ let (front, back) = match wild_idx.as_opt_usize() {
Some(i) => pats.split_at(i),
None => (pats, [].as_slice()),
};
@@ -268,7 +267,7 @@ impl<'a> NormalizedPat<'a> {
ty::Tuple(subs) => subs.len(),
_ => return Self::Wild,
};
- let (front, back) = match wild_idx {
+ let (front, back) = match wild_idx.as_opt_usize() {
Some(i) => pats.split_at(i),
None => (pats, [].as_slice()),
};
@@ -290,7 +289,7 @@ impl<'a> NormalizedPat<'a> {
LitKind::Char(val) => Self::LitInt(val.into()),
LitKind::Int(val, _) => Self::LitInt(val),
LitKind::Bool(val) => Self::LitBool(val),
- LitKind::Float(..) | LitKind::Err(_) => Self::Wild,
+ LitKind::Float(..) | LitKind::Err => Self::Wild,
},
_ => Self::Wild,
},
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
index fa3b8d1fc..1e80b6cf2 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
@@ -48,7 +48,7 @@ struct MatchExprVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for MatchExprVisitor<'a, 'tcx> {
fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
match ex.kind {
- ExprKind::MethodCall(segment, [receiver], _) if self.case_altered(segment.ident.as_str(), receiver) => {},
+ ExprKind::MethodCall(segment, receiver, [], _) if self.case_altered(segment.ident.as_str(), receiver) => {},
_ => walk_expr(self, ex),
}
}
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs
index bc16f17b6..a3aa2e4b3 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs
@@ -40,7 +40,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<'
arm.pat.span,
&format!("`Err({})` matches all errors", ident_bind_name),
None,
- "match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable",
+ "match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable",
);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index eba230e5a..e6b183fc0 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -21,8 +21,8 @@ mod single_match;
mod try_err;
mod wild_in_or_pats;
-use clippy_utils::source::{snippet_opt, span_starts_with, walk_span_to_context};
-use clippy_utils::{higher, in_constant, meets_msrv, msrvs};
+use clippy_utils::source::{snippet_opt, walk_span_to_context};
+use clippy_utils::{higher, in_constant, is_span_match, meets_msrv, msrvs};
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -949,7 +949,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
let from_expansion = expr.span.from_expansion();
if let ExprKind::Match(ex, arms, source) = expr.kind {
- if source == MatchSource::Normal && !span_starts_with(cx, expr.span, "match") {
+ if source == MatchSource::Normal && !is_span_match(cx, expr.span) {
return;
}
if matches!(source, MatchSource::Normal | MatchSource::ForLoopDesugar) {
diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
index fa19cddd3..634eef82e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
@@ -8,7 +8,7 @@ use clippy_utils::{
};
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, FnRetTy, Node, Pat, PatKind, Path, QPath};
+use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
use rustc_lint::LateContext;
use rustc_span::sym;
use rustc_typeck::hir_ty_to_ty;
@@ -65,8 +65,26 @@ pub(crate) fn check_if_let<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'_>, if_let:
fn check_all_arms(cx: &LateContext<'_>, match_expr: &Expr<'_>, arms: &[Arm<'_>]) -> bool {
for arm in arms {
let arm_expr = peel_blocks_with_stmt(arm.body);
+
+ if let Some(guard_expr) = &arm.guard {
+ match guard_expr {
+ // gives up if `pat if expr` can have side effects
+ Guard::If(if_cond) => {
+ if if_cond.can_have_side_effects() {
+ return false;
+ }
+ },
+ // gives up `pat if let ...` arm
+ Guard::IfLet(_) => {
+ return false;
+ },
+ };
+ }
+
if let PatKind::Wild = arm.pat.kind {
- return eq_expr_value(cx, match_expr, strip_return(arm_expr));
+ if !eq_expr_value(cx, match_expr, strip_return(arm_expr)) {
+ return false;
+ }
} else if !pat_same_as_expr(arm.pat, arm_expr) {
return false;
}
@@ -171,8 +189,7 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
},
)),
) => {
- return !matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut)
- && pat_ident.name == first_seg.ident.name;
+ return !matches!(annot, BindingAnnotation(ByRef::Yes, _)) && pat_ident.name == first_seg.ident.name;
},
// Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
(PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => {
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
index 8499e050a..c89784065 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -2,17 +2,17 @@ use super::REDUNDANT_PATTERN_MATCHING;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::needs_ordered_drop;
+use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop};
use clippy_utils::visitors::any_temporaries_need_ordered_drop;
-use clippy_utils::{higher, is_lang_ctor, is_trait_method, match_def_path, paths};
+use clippy_utils::{higher, is_lang_ctor, is_trait_method};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
-use rustc_hir::LangItem::{OptionNone, PollPending};
+use rustc_hir::LangItem::{self, OptionSome, OptionNone, PollPending, PollReady, ResultOk, ResultErr};
use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, subst::GenericArgKind, DefIdTree, Ty};
-use rustc_span::sym;
+use rustc_span::{sym, Symbol};
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Some(higher::WhileLet { let_pat, let_expr, .. }) = higher::WhileLet::hir(expr) {
@@ -75,9 +75,9 @@ fn find_sugg_for_if_let<'tcx>(
("is_some()", op_ty)
} else if Some(id) == lang_items.poll_ready_variant() {
("is_ready()", op_ty)
- } else if match_def_path(cx, id, &paths::IPADDR_V4) {
+ } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V4))) {
("is_ipv4()", op_ty)
- } else if match_def_path(cx, id, &paths::IPADDR_V6) {
+ } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V6))) {
("is_ipv6()", op_ty)
} else {
return;
@@ -120,7 +120,7 @@ fn find_sugg_for_if_let<'tcx>(
// check that `while_let_on_iterator` lint does not trigger
if_chain! {
if keyword == "while";
- if let ExprKind::MethodCall(method_path, _, _) = let_expr.kind;
+ if let ExprKind::MethodCall(method_path, ..) = let_expr.kind;
if method_path.ident.name == sym::next;
if is_trait_method(cx, let_expr, sym::Iterator);
then {
@@ -187,8 +187,8 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
arms,
path_left,
path_right,
- &paths::RESULT_OK,
- &paths::RESULT_ERR,
+ Item::Lang(ResultOk),
+ Item::Lang(ResultErr),
"is_ok()",
"is_err()",
)
@@ -198,8 +198,8 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
arms,
path_left,
path_right,
- &paths::IPADDR_V4,
- &paths::IPADDR_V6,
+ Item::Diag(sym::IpAddr, sym!(V4)),
+ Item::Diag(sym::IpAddr, sym!(V6)),
"is_ipv4()",
"is_ipv6()",
)
@@ -213,13 +213,14 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
if patterns.len() == 1 =>
{
if let PatKind::Wild = patterns[0].kind {
+
find_good_method_for_match(
cx,
arms,
path_left,
path_right,
- &paths::OPTION_SOME,
- &paths::OPTION_NONE,
+ Item::Lang(OptionSome),
+ Item::Lang(OptionNone),
"is_some()",
"is_none()",
)
@@ -229,8 +230,8 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
arms,
path_left,
path_right,
- &paths::POLL_READY,
- &paths::POLL_PENDING,
+ Item::Lang(PollReady),
+ Item::Lang(PollPending),
"is_ready()",
"is_pending()",
)
@@ -266,28 +267,61 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
}
}
+#[derive(Clone, Copy)]
+enum Item {
+ Lang(LangItem),
+ Diag(Symbol, Symbol),
+}
+
+fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expected_item: Item) -> bool {
+ let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else { return false };
+
+ match expected_item {
+ Item::Lang(expected_lang_item) => {
+ let expected_id = cx.tcx.lang_items().require(expected_lang_item).unwrap();
+ cx.tcx.parent(id) == expected_id
+ },
+ Item::Diag(expected_ty, expected_variant) => {
+ let ty = cx.typeck_results().pat_ty(pat);
+
+ if is_type_diagnostic_item(cx, ty, expected_ty) {
+ let variant = ty.ty_adt_def()
+ .expect("struct pattern type is not an ADT")
+ .variant_of_res(cx.qpath_res(path, pat.hir_id));
+
+ return variant.name == expected_variant
+ }
+
+ false
+ }
+ }
+}
+
#[expect(clippy::too_many_arguments)]
fn find_good_method_for_match<'a>(
cx: &LateContext<'_>,
arms: &[Arm<'_>],
path_left: &QPath<'_>,
path_right: &QPath<'_>,
- expected_left: &[&str],
- expected_right: &[&str],
+ expected_item_left: Item,
+ expected_item_right: Item,
should_be_left: &'a str,
should_be_right: &'a str,
) -> Option<&'a str> {
- let left_id = cx
- .typeck_results()
- .qpath_res(path_left, arms[0].pat.hir_id)
- .opt_def_id()?;
- let right_id = cx
- .typeck_results()
- .qpath_res(path_right, arms[1].pat.hir_id)
- .opt_def_id()?;
- let body_node_pair = if match_def_path(cx, left_id, expected_left) && match_def_path(cx, right_id, expected_right) {
+ let pat_left = arms[0].pat;
+ let pat_right = arms[1].pat;
+
+ let body_node_pair = if (
+ is_pat_variant(cx, pat_left, path_left, expected_item_left)
+ ) && (
+ is_pat_variant(cx, pat_right, path_right, expected_item_right)
+ ) {
(&arms[0].body.kind, &arms[1].body.kind)
- } else if match_def_path(cx, right_id, expected_left) && match_def_path(cx, right_id, expected_right) {
+ } else if (
+ is_pat_variant(cx, pat_left, path_left, expected_item_right)
+ ) && (
+ is_pat_variant(cx, pat_right, path_right, expected_item_left)
+ ) {
(&arms[1].body.kind, &arms[0].body.kind)
} else {
return None;
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index b0b15b3f5..86a9df034 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -291,7 +291,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
self.is_chain_end = false;
match ex.kind {
- ExprKind::MethodCall(_, [ref expr, ..], _) => {
+ ExprKind::MethodCall(_, expr, ..) => {
self.visit_expr(expr);
}
ExprKind::Binary(_, left, right) => {
@@ -331,8 +331,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
ExprKind::Index(..) |
ExprKind::Ret(..) |
ExprKind::Repeat(..) |
- ExprKind::Yield(..) |
- ExprKind::MethodCall(..) => walk_expr(self, ex),
+ ExprKind::Yield(..) => walk_expr(self, ex),
ExprKind::AddrOf(_, _, _) |
ExprKind::Block(_, _) |
ExprKind::Break(_, _) |
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 92091a0c3..56bcdc01f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -175,7 +175,7 @@ fn collect_pat_paths<'a>(acc: &mut Vec<Ty<'a>>, cx: &LateContext<'a>, pat: &Pat<
let p_ty = cx.typeck_results().pat_ty(p);
collect_pat_paths(acc, cx, p, p_ty);
}),
- PatKind::TupleStruct(..) | PatKind::Binding(BindingAnnotation::Unannotated, .., None) | PatKind::Path(_) => {
+ PatKind::TupleStruct(..) | PatKind::Binding(BindingAnnotation::NONE, .., None) | PatKind::Path(_) => {
acc.push(ty);
},
_ => {},
@@ -200,13 +200,11 @@ fn form_exhaustive_matches<'a>(cx: &LateContext<'a>, ty: Ty<'a>, left: &Pat<'_>,
// We don't actually know the position and the presence of the `..` (dotdot) operator
// in the arms, so we need to evaluate the correct offsets here in order to iterate in
// both arms at the same time.
+ let left_pos = left_pos.as_opt_usize();
+ let right_pos = right_pos.as_opt_usize();
let len = max(
- left_in.len() + {
- if left_pos.is_some() { 1 } else { 0 }
- },
- right_in.len() + {
- if right_pos.is_some() { 1 } else { 0 }
- },
+ left_in.len() + usize::from(left_pos.is_some()),
+ right_in.len() + usize::from(right_pos.is_some()),
);
let mut left_pos = left_pos.unwrap_or(usize::MAX);
let mut right_pos = right_pos.unwrap_or(usize::MAX);
diff --git a/src/tools/clippy/clippy_lints/src/matches/try_err.rs b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
index 0491a0679..663277d11 100644
--- a/src/tools/clippy/clippy_lints/src/matches/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
@@ -23,12 +23,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
// val,
// };
if_chain! {
- if let ExprKind::Call(match_fun, try_args) = scrutinee.kind;
+ if let ExprKind::Call(match_fun, [try_arg, ..]) = scrutinee.kind;
if let ExprKind::Path(ref match_fun_path) = match_fun.kind;
if matches!(match_fun_path, QPath::LangItem(LangItem::TryTraitBranch, ..));
- if let Some(try_arg) = try_args.get(0);
- if let ExprKind::Call(err_fun, err_args) = try_arg.kind;
- if let Some(err_arg) = err_args.get(0);
+ if let ExprKind::Call(err_fun, [err_arg, ..]) = try_arg.kind;
if let ExprKind::Path(ref err_fun_path) = err_fun.kind;
if is_lang_ctor(cx, err_fun_path, ResultErr);
if let Some(return_ty) = find_return_type(cx, &expr.kind);
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 41073d40f..cad3ea2a1 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -163,8 +163,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
}
if_chain! {
- if let ExprKind::Call(repl_func, repl_args) = src.kind;
- if repl_args.is_empty();
+ if let ExprKind::Call(repl_func, []) = src.kind;
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
then {
@@ -246,11 +245,10 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
// Check that `expr` is a call to `mem::replace()`
- if let ExprKind::Call(func, func_args) = expr.kind;
+ if let ExprKind::Call(func, [dest, src]) = expr.kind;
if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id();
if cx.tcx.is_diagnostic_item(sym::mem_replace, def_id);
- if let [dest, src] = func_args;
then {
check_replace_option_with_none(cx, src, dest, expr.span);
check_replace_with_uninit(cx, src, dest, expr.span);
diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
index 2f117e4dc..22f5635a5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -152,7 +152,7 @@ pub(crate) trait BindInsteadOfMap {
match arg.kind {
hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) => {
let closure_body = cx.tcx.hir().body(body);
- let closure_expr = peel_blocks(&closure_body.value);
+ let closure_expr = peel_blocks(closure_body.value);
if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, fn_decl_span) {
true
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs
new file mode 100644
index 000000000..fef90f6eb
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs
@@ -0,0 +1,70 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::match_type;
+use clippy_utils::visitors::is_local_used;
+use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, UintTy};
+use rustc_span::sym;
+
+use super::NAIVE_BYTECOUNT;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ filter_recv: &'tcx Expr<'_>,
+ filter_arg: &'tcx Expr<'_>,
+) {
+ if_chain! {
+ if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind;
+ let body = cx.tcx.hir().body(body);
+ if let [param] = body.params;
+ if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;
+ if let ExprKind::Binary(ref op, l, r) = body.value.kind;
+ if op.node == BinOpKind::Eq;
+ if match_type(cx,
+ cx.typeck_results().expr_ty(filter_recv).peel_refs(),
+ &paths::SLICE_ITER);
+ let operand_is_arg = |expr| {
+ let expr = peel_ref_operators(cx, peel_blocks(expr));
+ path_to_local_id(expr, arg_id)
+ };
+ let needle = if operand_is_arg(l) {
+ r
+ } else if operand_is_arg(r) {
+ l
+ } else {
+ return;
+ };
+ if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(needle).peel_refs().kind();
+ if !is_local_used(cx, needle, arg_id);
+ then {
+ let haystack = if let ExprKind::MethodCall(path, receiver, [], _) =
+ filter_recv.kind {
+ let p = path.ident.name;
+ if p == sym::iter || p == sym!(iter_mut) {
+ receiver
+ } else {
+ filter_recv
+ }
+ } else {
+ filter_recv
+ };
+ let mut applicability = Applicability::MaybeIncorrect;
+ span_lint_and_sugg(
+ cx,
+ NAIVE_BYTECOUNT,
+ expr.span,
+ "you appear to be counting bytes the naive way",
+ "consider using the bytecount crate",
+ format!("bytecount::count({}, {})",
+ snippet_with_applicability(cx, haystack.span, "..", &mut applicability),
+ snippet_with_applicability(cx, needle.span, "..", &mut applicability)),
+ applicability,
+ );
+ }
+ };
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
new file mode 100644
index 000000000..fcfc25b52
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
@@ -0,0 +1,37 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::is_type_diagnostic_item;
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::BYTES_COUNT_TO_LEN;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx hir::Expr<'_>,
+ count_recv: &'tcx hir::Expr<'_>,
+ bytes_recv: &'tcx hir::Expr<'_>,
+) {
+ if_chain! {
+ if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
+ if cx.tcx.type_of(impl_id).is_str();
+ let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
+ if ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String);
+ then {
+ let mut applicability = Applicability::MachineApplicable;
+ span_lint_and_sugg(
+ cx,
+ BYTES_COUNT_TO_LEN,
+ expr.span,
+ "using long and hard to read `.bytes().count()`",
+ "consider calling `.len()` instead",
+ format!("{}.len()", snippet_with_applicability(cx, bytes_recv.span, "..", &mut applicability)),
+ applicability
+ );
+ }
+ };
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
new file mode 100644
index 000000000..b3c2c7c9a
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
@@ -0,0 +1,41 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::ty::is_type_diagnostic_item;
+use if_chain::if_chain;
+use rustc_ast::ast::LitKind;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::{source_map::Spanned, symbol::sym, Span};
+
+use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ call_span: Span,
+ recv: &'tcx Expr<'_>,
+ arg: &'tcx Expr<'_>,
+) {
+ if_chain! {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if cx.tcx.type_of(impl_id).is_str();
+ if let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), ..}) = arg.kind;
+ if (2..=6).contains(&ext_literal.as_str().len());
+ let ext_str = ext_literal.as_str();
+ if ext_str.starts_with('.');
+ if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
+ || ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
+ let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
+ if recv_ty.is_str() || is_type_diagnostic_item(cx, recv_ty, sym::String);
+ then {
+ span_lint_and_help(
+ cx,
+ CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
+ call_span,
+ "case-sensitive file extension comparison",
+ None,
+ "consider using a case-insensitive comparison instead",
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs
index f7b79f083..b2bc1ad5c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs
@@ -23,7 +23,7 @@ pub(super) fn check(
if Some(id) == cx.tcx.lang_items().option_some_variant();
then {
let mut applicability = Applicability::MachineApplicable;
- let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0][0]).peel_refs();
+ let self_ty = cx.typeck_results().expr_ty_adjusted(args[0].0).peel_refs();
if *self_ty.kind() != ty::Str {
return false;
@@ -37,7 +37,7 @@ pub(super) fn check(
"like this",
format!("{}{}.{}({})",
if info.eq { "" } else { "!" },
- snippet_with_applicability(cx, args[0][0].span, "..", &mut applicability),
+ snippet_with_applicability(cx, args[0].0.span, "..", &mut applicability),
suggest,
snippet_with_applicability(cx, arg_char.span, "..", &mut applicability)),
applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
index a7c0e4392..b85bfec2b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
@@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(
"like this",
format!("{}{}.{}('{}')",
if info.eq { "" } else { "!" },
- snippet_with_applicability(cx, args[0][0].span, "..", &mut applicability),
+ snippet_with_applicability(cx, args[0].0.span, "..", &mut applicability),
suggest,
c.escape_default()),
applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
index 0b38a0720..7ab6b84c2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg;
use clippy_utils::ty::is_copy;
use rustc_errors::Applicability;
-use rustc_hir::{BindingAnnotation, Expr, ExprKind, MatchSource, Node, PatKind};
+use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, adjustment::Adjust};
use rustc_span::symbol::{sym, Symbol};
@@ -14,10 +14,17 @@ use super::CLONE_ON_COPY;
/// Checks for the `CLONE_ON_COPY` lint.
#[allow(clippy::too_many_lines)]
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol, args: &[Expr<'_>]) {
- let arg = match args {
- [arg] if method_name == sym::clone => arg,
- _ => return,
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ expr: &Expr<'_>,
+ method_name: Symbol,
+ receiver: &Expr<'_>,
+ args: &[Expr<'_>],
+) {
+ let arg = if method_name == sym::clone && args.is_empty() {
+ receiver
+ } else {
+ return;
};
if cx
.typeck_results()
@@ -81,24 +88,24 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol,
// &*x is a nop, &x.clone() is not
ExprKind::AddrOf(..) => return,
// (*x).func() is useless, x.clone().func() can work in case func borrows self
- ExprKind::MethodCall(_, [self_arg, ..], _)
+ ExprKind::MethodCall(_, self_arg, ..)
if expr.hir_id == self_arg.hir_id && ty != cx.typeck_results().expr_ty_adjusted(expr) =>
{
return;
},
- ExprKind::MethodCall(_, [self_arg, ..], _) if expr.hir_id == self_arg.hir_id => true,
+ // ? is a Call, makes sure not to rec *x?, but rather (*x)?
+ ExprKind::Call(hir_callee, _) => matches!(
+ hir_callee.kind,
+ ExprKind::Path(QPath::LangItem(rustc_hir::LangItem::TryTraitBranch, _, _))
+ ),
+ ExprKind::MethodCall(_, self_arg, ..) if expr.hir_id == self_arg.hir_id => true,
ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
| ExprKind::Field(..)
| ExprKind::Index(..) => true,
_ => false,
},
// local binding capturing a reference
- Some(Node::Local(l))
- if matches!(
- l.pat.kind,
- PatKind::Binding(BindingAnnotation::Ref | BindingAnnotation::RefMut, ..)
- ) =>
- {
+ Some(Node::Local(l)) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..)) => {
return;
},
_ => false,
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
index 6417bc813..f82ca8912 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
@@ -10,12 +10,17 @@ use rustc_span::symbol::{sym, Symbol};
use super::CLONE_ON_REF_PTR;
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol, args: &[hir::Expr<'_>]) {
- if !(args.len() == 1 && method_name == sym::clone) {
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ expr: &hir::Expr<'_>,
+ method_name: Symbol,
+ receiver: &hir::Expr<'_>,
+ args: &[hir::Expr<'_>],
+) {
+ if !(args.is_empty() && method_name == sym::clone) {
return;
}
- let arg = &args[0];
- let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
+ let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
if let ty::Adt(_, subst) = obj_ty.kind() {
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
@@ -28,7 +33,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Sym
return;
};
- let snippet = snippet_with_macro_callsite(cx, arg.span, "..");
+ let snippet = snippet_with_macro_callsite(cx, receiver.span, "..");
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs b/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
new file mode 100644
index 000000000..501646863
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
@@ -0,0 +1,96 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet;
+use clippy_utils::visitors::for_each_expr;
+use clippy_utils::{eq_expr_value, get_parent_expr};
+use core::ops::ControlFlow;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use std::collections::VecDeque;
+
+use super::method_call;
+use super::COLLAPSIBLE_STR_REPLACE;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
+ from: &'tcx hir::Expr<'tcx>,
+ to: &'tcx hir::Expr<'tcx>,
+) {
+ let replace_methods = collect_replace_calls(cx, expr, to);
+ if replace_methods.methods.len() > 1 {
+ let from_kind = cx.typeck_results().expr_ty(from).peel_refs().kind();
+ // If the parent node's `to` argument is the same as the `to` argument
+ // of the last replace call in the current chain, don't lint as it was already linted
+ if let Some(parent) = get_parent_expr(cx, expr)
+ && let Some(("replace", _, [current_from, current_to], _)) = method_call(parent)
+ && eq_expr_value(cx, to, current_to)
+ && from_kind == cx.typeck_results().expr_ty(current_from).peel_refs().kind()
+ {
+ return;
+ }
+
+ check_consecutive_replace_calls(cx, expr, &replace_methods, to);
+ }
+}
+
+struct ReplaceMethods<'tcx> {
+ methods: VecDeque<&'tcx hir::Expr<'tcx>>,
+ from_args: VecDeque<&'tcx hir::Expr<'tcx>>,
+}
+
+fn collect_replace_calls<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
+ to_arg: &'tcx hir::Expr<'tcx>,
+) -> ReplaceMethods<'tcx> {
+ let mut methods = VecDeque::new();
+ let mut from_args = VecDeque::new();
+
+ let _: Option<()> = for_each_expr(expr, |e| {
+ if let Some(("replace", _, [from, to], _)) = method_call(e) {
+ if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() {
+ methods.push_front(e);
+ from_args.push_front(from);
+ ControlFlow::Continue(())
+ } else {
+ ControlFlow::BREAK
+ }
+ } else {
+ ControlFlow::Continue(())
+ }
+ });
+
+ ReplaceMethods { methods, from_args }
+}
+
+/// Check a chain of `str::replace` calls for `collapsible_str_replace` lint.
+fn check_consecutive_replace_calls<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
+ replace_methods: &ReplaceMethods<'tcx>,
+ to_arg: &'tcx hir::Expr<'tcx>,
+) {
+ let from_args = &replace_methods.from_args;
+ let from_arg_reprs: Vec<String> = from_args
+ .iter()
+ .map(|from_arg| snippet(cx, from_arg.span, "..").to_string())
+ .collect();
+ let app = Applicability::MachineApplicable;
+ let earliest_replace_call = replace_methods.methods.front().unwrap();
+ if let Some((_, _, [..], span_lo)) = method_call(earliest_replace_call) {
+ span_lint_and_sugg(
+ cx,
+ COLLAPSIBLE_STR_REPLACE,
+ expr.span.with_lo(span_lo.lo()),
+ "used consecutive `str::replace` call",
+ "replace with",
+ format!(
+ "replace([{}], {})",
+ from_arg_reprs.join(", "),
+ snippet(cx, to_arg.span, ".."),
+ ),
+ app,
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index 6f2307d8f..bd846d71d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -19,6 +19,7 @@ pub(super) fn check<'tcx>(
expr: &hir::Expr<'_>,
method_span: Span,
name: &str,
+ receiver: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
) {
// Strip `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or
@@ -28,16 +29,13 @@ pub(super) fn check<'tcx>(
loop {
arg_root = match &arg_root.kind {
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr,
- hir::ExprKind::MethodCall(method_name, call_args, _) => {
- if call_args.len() == 1
- && (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref)
- && {
- let arg_type = cx.typeck_results().expr_ty(&call_args[0]);
- let base_type = arg_type.peel_refs();
- *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String)
- }
- {
- &call_args[0]
+ hir::ExprKind::MethodCall(method_name, receiver, [], ..) => {
+ if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {
+ let arg_type = cx.typeck_results().expr_ty(receiver);
+ let base_type = arg_type.peel_refs();
+ *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String)
+ } {
+ receiver
} else {
break;
}
@@ -114,11 +112,11 @@ pub(super) fn check<'tcx>(
}
}
- if args.len() != 2 || name != "expect" || !is_call(&args[1].kind) {
+ if args.len() != 1 || name != "expect" || !is_call(&args[0].kind) {
return;
}
- let receiver_type = cx.typeck_results().expr_ty_adjusted(&args[0]);
+ let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);
let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym::Option) {
"||"
} else if is_type_diagnostic_item(cx, receiver_type, sym::Result) {
@@ -127,7 +125,7 @@ pub(super) fn check<'tcx>(
return;
};
- let arg_root = get_arg_root(cx, &args[1]);
+ let arg_root = get_arg_root(cx, &args[0]);
let span_replace_word = method_span.with_hi(expr.span.hi());
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_used.rs b/src/tools/clippy/clippy_lints/src/methods/expect_used.rs
index fbc3348f1..d59fefa1d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_used.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_used.rs
@@ -7,30 +7,38 @@ use rustc_span::sym;
use super::EXPECT_USED;
-/// lint use of `expect()` for `Option`s and `Result`s
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, allow_expect_in_tests: bool) {
+/// lint use of `expect()` or `expect_err` for `Result` and `expect()` for `Option`.
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ expr: &hir::Expr<'_>,
+ recv: &hir::Expr<'_>,
+ is_err: bool,
+ allow_expect_in_tests: bool,
+) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
- let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
- Some((EXPECT_USED, "an Option", "None"))
+ let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
+ Some((EXPECT_USED, "an Option", "None", ""))
} else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
- Some((EXPECT_USED, "a Result", "Err"))
+ Some((EXPECT_USED, "a Result", if is_err { "Ok" } else { "Err" }, "an "))
} else {
None
};
+ let method = if is_err { "expect_err" } else { "expect" };
+
if allow_expect_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
return;
}
- if let Some((lint, kind, none_value)) = mess {
+ if let Some((lint, kind, none_value, none_prefix)) = mess {
span_lint_and_help(
cx,
lint,
expr.span,
- &format!("used `expect()` on `{}` value", kind,),
+ &format!("used `{method}()` on `{kind}` value"),
None,
- &format!("if this value is an `{}`, it will panic", none_value,),
+ &format!("if this value is {none_prefix}`{none_value}`, it will panic"),
);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs b/src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs
index a15fe6094..37b284635 100644
--- a/src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs
@@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
if_chain! {
if is_type_diagnostic_item(cx, ty, sym::Vec);
//check source object
- if let ExprKind::MethodCall(src_method, [drain_vec, drain_arg], _) = &arg.kind;
+ if let ExprKind::MethodCall(src_method, drain_vec, [drain_arg], _) = &arg.kind;
if src_method.ident.as_str() == "drain";
let src_ty = cx.typeck_results().expr_ty(drain_vec);
//check if actual src type is mutable for code suggestion
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 692e22a7c..9719b2f1c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -25,14 +25,14 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
},
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let body = cx.tcx.hir().body(body);
- let closure_expr = peel_blocks(&body.value);
+ let closure_expr = peel_blocks(body.value);
let arg_id = body.params[0].pat.hir_id;
match closure_expr.kind {
- hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, args, _) => {
+ hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, receiver, ..) => {
if_chain! {
if ident.name == method_name;
- if let hir::ExprKind::Path(path) = &args[0].kind;
- if let Res::Local(ref local) = cx.qpath_res(path, args[0].hir_id);
+ if let hir::ExprKind::Path(path) = &receiver.kind;
+ if let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id);
then {
return arg_id == *local
}
@@ -106,7 +106,7 @@ pub(super) fn check<'tcx>(
};
// closure ends with is_some() or is_ok()
if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind;
- if let ExprKind::MethodCall(path, [filter_arg], _) = filter_body.value.kind;
+ if let ExprKind::MethodCall(path, filter_arg, [], _) = filter_body.value.kind;
if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).peel_refs().ty_adt_def();
if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did()) {
Some(false)
@@ -123,13 +123,13 @@ pub(super) fn check<'tcx>(
if let [map_param] = map_body.params;
if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind;
// closure ends with expect() or unwrap()
- if let ExprKind::MethodCall(seg, [map_arg, ..], _) = map_body.value.kind;
+ if let ExprKind::MethodCall(seg, map_arg, ..) = map_body.value.kind;
if matches!(seg.ident.name, sym::expect | sym::unwrap | sym::unwrap_or);
// .filter(..).map(|y| f(y).copied().unwrap())
// ~~~~
let map_arg_peeled = match map_arg.kind {
- ExprKind::MethodCall(method, [original_arg], _) if acceptable_methods(method) => {
+ ExprKind::MethodCall(method, original_arg, [], _) if acceptable_methods(method) => {
original_arg
},
_ => map_arg,
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_first.rs b/src/tools/clippy/clippy_lints/src/methods/get_first.rs
new file mode 100644
index 000000000..4de77de74
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/get_first.rs
@@ -0,0 +1,39 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_slice_of_primitives;
+use clippy_utils::source::snippet_with_applicability;
+use if_chain::if_chain;
+use rustc_ast::LitKind;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_span::source_map::Spanned;
+
+use super::GET_FIRST;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx hir::Expr<'_>,
+ recv: &'tcx hir::Expr<'_>,
+ arg: &'tcx hir::Expr<'_>,
+) {
+ if_chain! {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if cx.tcx.type_of(impl_id).is_slice();
+ if let Some(_) = is_slice_of_primitives(cx, recv);
+ if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind;
+ then {
+ let mut app = Applicability::MachineApplicable;
+ let slice_name = snippet_with_applicability(cx, recv.span, "..", &mut app);
+ span_lint_and_sugg(
+ cx,
+ GET_FIRST,
+ expr.span,
+ &format!("accessing first element with `{0}.get(0)`", slice_name),
+ "try",
+ format!("{}.first()", slice_name),
+ app,
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs b/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
index 23368238e..02aada872 100644
--- a/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
@@ -22,7 +22,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
) = arg.kind
// LHS of subtraction is "x.len()"
- && let ExprKind::MethodCall(lhs_path, [lhs_recv], _) = &lhs.kind
+ && let ExprKind::MethodCall(lhs_path, lhs_recv, [], _) = &lhs.kind
&& lhs_path.ident.name == sym::len
// RHS of subtraction is 1
diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
index f52170df6..e1c9b5248 100644
--- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
@@ -12,13 +12,19 @@ use rustc_span::symbol::{sym, Symbol};
use super::INEFFICIENT_TO_STRING;
/// Checks for the `INEFFICIENT_TO_STRING` lint
-pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Symbol, args: &[hir::Expr<'_>]) {
+pub fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &hir::Expr<'_>,
+ method_name: Symbol,
+ receiver: &hir::Expr<'_>,
+ args: &[hir::Expr<'_>],
+) {
if_chain! {
- if args.len() == 1 && method_name == sym::to_string;
+ if args.is_empty() && method_name == sym::to_string;
if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD);
if let Some(substs) = cx.typeck_results().node_substs_opt(expr.hir_id);
- let arg_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
+ let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver);
let self_ty = substs.type_at(0);
let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty);
if deref_count >= 1;
@@ -35,7 +41,7 @@ pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
self_ty, deref_self_ty
));
let mut applicability = Applicability::MachineApplicable;
- let arg_snippet = snippet_with_applicability(cx, args[0].span, "..", &mut applicability);
+ let arg_snippet = snippet_with_applicability(cx, receiver.span, "..", &mut applicability);
diag.span_suggestion(
expr.span,
"try dereferencing the receiver",
diff --git a/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs b/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
index da13b4ba3..11e76841e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
@@ -16,9 +16,9 @@ pub(super) fn check(
expr: &hir::Expr<'_>,
method_span: Span,
method_name: Symbol,
- args: &[hir::Expr<'_>],
+ receiver: &hir::Expr<'_>,
) {
- let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
+ let self_ty = cx.typeck_results().expr_ty_adjusted(receiver);
if_chain! {
if let ty::Ref(..) = self_ty.kind();
if method_name == sym::into_iter;
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
new file mode 100644
index 000000000..cea7b0d82
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -0,0 +1,107 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet;
+use clippy_utils::{get_expr_use_or_unification_node, is_lang_ctor, is_no_std_crate};
+
+use rustc_errors::Applicability;
+use rustc_hir::LangItem::{OptionNone, OptionSome};
+use rustc_hir::{Expr, ExprKind, Node};
+use rustc_lint::LateContext;
+
+use super::{ITER_ON_EMPTY_COLLECTIONS, ITER_ON_SINGLE_ITEMS};
+
+enum IterType {
+ Iter,
+ IterMut,
+ IntoIter,
+}
+
+impl IterType {
+ fn ref_prefix(&self) -> &'static str {
+ match self {
+ Self::Iter => "&",
+ Self::IterMut => "&mut ",
+ Self::IntoIter => "",
+ }
+ }
+}
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
+ let item = match &recv.kind {
+ ExprKind::Array(v) if v.len() <= 1 => v.first(),
+ ExprKind::Path(p) => {
+ if is_lang_ctor(cx, p, OptionNone) {
+ None
+ } else {
+ return;
+ }
+ },
+ ExprKind::Call(f, some_args) if some_args.len() == 1 => {
+ if let ExprKind::Path(p) = &f.kind {
+ if is_lang_ctor(cx, p, OptionSome) {
+ Some(&some_args[0])
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ },
+ _ => return,
+ };
+ let iter_type = match method_name {
+ "iter" => IterType::Iter,
+ "iter_mut" => IterType::IterMut,
+ "into_iter" => IterType::IntoIter,
+ _ => return,
+ };
+
+ let is_unified = match get_expr_use_or_unification_node(cx.tcx, expr) {
+ Some((Node::Expr(parent), child_id)) => match parent.kind {
+ ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id == child_id => false,
+ ExprKind::If(_, _, _)
+ | ExprKind::Match(_, _, _)
+ | ExprKind::Closure(_)
+ | ExprKind::Ret(_)
+ | ExprKind::Break(_, _) => true,
+ _ => false,
+ },
+ Some((Node::Stmt(_) | Node::Local(_), _)) => false,
+ _ => true,
+ };
+
+ if is_unified {
+ return;
+ }
+
+ if let Some(i) = item {
+ let sugg = format!(
+ "{}::iter::once({}{})",
+ if is_no_std_crate(cx) { "core" } else { "std" },
+ iter_type.ref_prefix(),
+ snippet(cx, i.span, "...")
+ );
+ span_lint_and_sugg(
+ cx,
+ ITER_ON_SINGLE_ITEMS,
+ expr.span,
+ &format!("`{method_name}` call on a collection with only one item"),
+ "try",
+ sugg,
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ span_lint_and_sugg(
+ cx,
+ ITER_ON_EMPTY_COLLECTIONS,
+ expr.span,
+ &format!("`{method_name}` call on an empty collection"),
+ "try",
+ if is_no_std_crate(cx) {
+ "core::iter::empty()".to_string()
+ } else {
+ "std::iter::empty()".to_string()
+ },
+ Applicability::MaybeIncorrect,
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs
index 43e9451f7..beb772100 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs
@@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
if let Some(id) = path_to_local(recv);
if let Node::Pat(pat) = cx.tcx.hir().get(id);
if let PatKind::Binding(ann, _, _, _) = pat.kind;
- if ann != BindingAnnotation::Mutable;
+ if ann != BindingAnnotation::MUT;
then {
application = Applicability::Unspecified;
diag.span_help(
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs b/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
index 152072e09..a669cbbbc 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
@@ -35,7 +35,7 @@ fn is_full_range(cx: &LateContext<'_>, container: &Expr<'_>, range: Range<'_>) -
&& range.end.map_or(true, |e| {
if range.limits == RangeLimits::HalfOpen
&& let ExprKind::Path(QPath::Resolved(None, container_path)) = container.kind
- && let ExprKind::MethodCall(name, [self_arg], _) = e.kind
+ && let ExprKind::MethodCall(name, self_arg, [], _) = e.kind
&& name.ident.name == sym::len
&& let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind
{
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
new file mode 100644
index 000000000..ffd2f4a38
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
@@ -0,0 +1,64 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{is_lang_ctor, path_to_local_id};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::LangItem::{ResultErr, ResultOk};
+use rustc_hir::{Closure, Expr, ExprKind, PatKind};
+use rustc_lint::LateContext;
+use rustc_span::symbol::sym;
+
+use super::MANUAL_OK_OR;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'tcx>,
+ recv: &'tcx Expr<'_>,
+ or_expr: &'tcx Expr<'_>,
+ map_expr: &'tcx Expr<'_>,
+) {
+ if_chain! {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Option);
+ if let ExprKind::Call(Expr { kind: ExprKind::Path(err_path), .. }, [err_arg]) = or_expr.kind;
+ if is_lang_ctor(cx, err_path, ResultErr);
+ if is_ok_wrapping(cx, map_expr);
+ if let Some(recv_snippet) = snippet_opt(cx, recv.span);
+ if let Some(err_arg_snippet) = snippet_opt(cx, err_arg.span);
+ if let Some(indent) = indent_of(cx, expr.span);
+ then {
+ let reindented_err_arg_snippet = reindent_multiline(err_arg_snippet.into(), true, Some(indent + 4));
+ span_lint_and_sugg(
+ cx,
+ MANUAL_OK_OR,
+ expr.span,
+ "this pattern reimplements `Option::ok_or`",
+ "replace with",
+ format!(
+ "{}.ok_or({})",
+ recv_snippet,
+ reindented_err_arg_snippet
+ ),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+}
+
+fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {
+ if let ExprKind::Path(ref qpath) = map_expr.kind {
+ if is_lang_ctor(cx, qpath, ResultOk) {
+ return true;
+ }
+ }
+ if_chain! {
+ if let ExprKind::Closure(&Closure { body, .. }) = map_expr.kind;
+ let body = cx.tcx.hir().body(body);
+ if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind;
+ if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind;
+ if is_lang_ctor(cx, ok_path, ResultOk);
+ then { path_to_local_id(ok_arg, param_id) } else { false }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
new file mode 100644
index 000000000..8261ef5e1
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -0,0 +1,122 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
+use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs, peel_blocks};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_middle::mir::Mutability;
+use rustc_middle::ty;
+use rustc_middle::ty::adjustment::Adjust;
+use rustc_semver::RustcVersion;
+use rustc_span::symbol::Ident;
+use rustc_span::{sym, Span};
+
+use super::MAP_CLONE;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'_>,
+ e: &hir::Expr<'_>,
+ recv: &hir::Expr<'_>,
+ arg: &'tcx hir::Expr<'_>,
+ msrv: Option<RustcVersion>,
+) {
+ if_chain! {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id);
+ if cx.tcx.impl_of_method(method_id)
+ .map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id), sym::Option))
+ || is_diag_trait_item(cx, method_id, sym::Iterator);
+ if let hir::ExprKind::Closure(&hir::Closure{ body, .. }) = arg.kind;
+ then {
+ let closure_body = cx.tcx.hir().body(body);
+ let closure_expr = peel_blocks(closure_body.value);
+ match closure_body.params[0].pat.kind {
+ hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding(
+ hir::BindingAnnotation::NONE, .., name, None
+ ) = inner.kind {
+ if ident_eq(name, closure_expr) {
+ lint_explicit_closure(cx, e.span, recv.span, true, msrv);
+ }
+ },
+ hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) => {
+ match closure_expr.kind {
+ hir::ExprKind::Unary(hir::UnOp::Deref, inner) => {
+ if ident_eq(name, inner) {
+ if let ty::Ref(.., Mutability::Not) = cx.typeck_results().expr_ty(inner).kind() {
+ lint_explicit_closure(cx, e.span, recv.span, true, msrv);
+ }
+ }
+ },
+ hir::ExprKind::MethodCall(method, obj, [], _) => if_chain! {
+ if ident_eq(name, obj) && method.ident.name == sym::clone;
+ if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id);
+ if let Some(trait_id) = cx.tcx.trait_of_item(fn_id);
+ if cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id);
+ // no autoderefs
+ if !cx.typeck_results().expr_adjustments(obj).iter()
+ .any(|a| matches!(a.kind, Adjust::Deref(Some(..))));
+ then {
+ let obj_ty = cx.typeck_results().expr_ty(obj);
+ if let ty::Ref(_, ty, mutability) = obj_ty.kind() {
+ if matches!(mutability, Mutability::Not) {
+ let copy = is_copy(cx, *ty);
+ lint_explicit_closure(cx, e.span, recv.span, copy, msrv);
+ }
+ } else {
+ lint_needless_cloning(cx, e.span, recv.span);
+ }
+ }
+ },
+ _ => {},
+ }
+ },
+ _ => {},
+ }
+ }
+ }
+}
+
+fn ident_eq(name: Ident, path: &hir::Expr<'_>) -> bool {
+ if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = path.kind {
+ path.segments.len() == 1 && path.segments[0].ident == name
+ } else {
+ false
+ }
+}
+
+fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
+ span_lint_and_sugg(
+ cx,
+ MAP_CLONE,
+ root.trim_start(receiver).unwrap(),
+ "you are needlessly cloning iterator elements",
+ "remove the `map` call",
+ String::new(),
+ Applicability::MachineApplicable,
+ );
+}
+
+fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: Option<RustcVersion>) {
+ let mut applicability = Applicability::MachineApplicable;
+
+ let (message, sugg_method) = if is_copy && meets_msrv(msrv, msrvs::ITERATOR_COPIED) {
+ ("you are using an explicit closure for copying elements", "copied")
+ } else {
+ ("you are using an explicit closure for cloning elements", "cloned")
+ };
+
+ span_lint_and_sugg(
+ cx,
+ MAP_CLONE,
+ replace,
+ message,
+ &format!("consider calling the dedicated `{}` method", sugg_method),
+ format!(
+ "{}.{}()",
+ snippet_with_applicability(cx, root, "..", &mut applicability),
+ sugg_method,
+ ),
+ applicability,
+ );
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs
new file mode 100644
index 000000000..1fb661714
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs
@@ -0,0 +1,34 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_hir::{CaptureBy, Closure, Expr, ExprKind, PatKind};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::MAP_ERR_IGNORE;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'_>, e: &Expr<'_>, arg: &'tcx Expr<'_>) {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+ && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
+ && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Result)
+ && let ExprKind::Closure(&Closure {
+ capture_clause: CaptureBy::Ref,
+ body,
+ fn_decl_span,
+ ..
+ }) = arg.kind
+ && let closure_body = cx.tcx.hir().body(body)
+ && let [param] = closure_body.params
+ && let PatKind::Wild = param.pat.kind
+ {
+ // span the area of the closure capture and warn that the
+ // original error will be thrown away
+ span_lint_and_help(
+ cx,
+ MAP_ERR_IGNORE,
+ fn_decl_span,
+ "`map_err(|_|...` wildcard pattern discards the original error",
+ None,
+ "consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)",
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 202fbc1f7..41942b20e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -1,5 +1,8 @@
mod bind_instead_of_map;
+mod bytecount;
+mod bytes_count_to_len;
mod bytes_nth;
+mod case_sensitive_file_extension_comparisons;
mod chars_cmp;
mod chars_cmp_with_unwrap;
mod chars_last_cmp;
@@ -9,6 +12,7 @@ mod chars_next_cmp_with_unwrap;
mod clone_on_copy;
mod clone_on_ref_ptr;
mod cloned_instead_of_copied;
+mod collapsible_str_replace;
mod err_expect;
mod expect_fun_call;
mod expect_used;
@@ -21,6 +25,7 @@ mod filter_next;
mod flat_map_identity;
mod flat_map_option;
mod from_iter_instead_of_collect;
+mod get_first;
mod get_last_with_len;
mod get_unwrap;
mod implicit_clone;
@@ -33,55 +38,72 @@ mod iter_count;
mod iter_next_slice;
mod iter_nth;
mod iter_nth_zero;
+mod iter_on_single_or_empty_collections;
mod iter_overeager_cloned;
mod iter_skip_next;
mod iter_with_drain;
mod iterator_step_by_zero;
+mod manual_ok_or;
mod manual_saturating_arithmetic;
mod manual_str_repeat;
+mod map_clone;
mod map_collect_result_unit;
+mod map_err_ignore;
mod map_flatten;
mod map_identity;
mod map_unwrap_or;
+mod mut_mutex_lock;
mod needless_option_as_deref;
mod needless_option_take;
mod no_effect_replace;
mod obfuscated_if_else;
mod ok_expect;
+mod open_options;
mod option_as_ref_deref;
mod option_map_or_none;
mod option_map_unwrap_or;
mod or_fun_call;
mod or_then_unwrap;
+mod path_buf_push_overwrite;
+mod range_zip_with_len;
+mod repeat_once;
mod search_is_some;
mod single_char_add_str;
mod single_char_insert_string;
mod single_char_pattern;
mod single_char_push_string;
mod skip_while_next;
+mod stable_sort_primitive;
mod str_splitn;
mod string_extend_chars;
mod suspicious_map;
mod suspicious_splitn;
+mod suspicious_to_owned;
mod uninit_assumed_init;
+mod unit_hash;
mod unnecessary_filter_map;
mod unnecessary_fold;
mod unnecessary_iter_cloned;
mod unnecessary_join;
mod unnecessary_lazy_eval;
+mod unnecessary_sort_by;
mod unnecessary_to_owned;
mod unwrap_or_else_default;
mod unwrap_used;
mod useless_asref;
mod utils;
+mod vec_resize_to_zero;
+mod verbose_file_reads;
mod wrong_self_convention;
mod zst_offset;
use bind_instead_of_map::BindInsteadOfMap;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::ty::{contains_adt_constructor, contains_ty, implements_trait, is_copy, is_type_diagnostic_item};
-use clippy_utils::{contains_return, get_trait_def_id, iter_input_pats, meets_msrv, msrvs, paths, return_ty};
+use clippy_utils::ty::{contains_adt_constructor, implements_trait, is_copy, is_type_diagnostic_item};
+use clippy_utils::{
+ contains_return, get_trait_def_id, is_trait_method, iter_input_pats, meets_msrv, msrvs, paths, return_ty,
+};
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_hir::def::Res;
@@ -119,6 +141,32 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
+ /// Checks for consecutive calls to `str::replace` (2 or more)
+ /// that can be collapsed into a single call.
+ ///
+ /// ### Why is this bad?
+ /// Consecutive `str::replace` calls scan the string multiple times
+ /// with repetitive code.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let hello = "hesuo worpd"
+ /// .replace('s', "l")
+ /// .replace("u", "l")
+ /// .replace('p', "l");
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let hello = "hesuo worpd".replace(&['s', 'u', 'p'], "l");
+ /// ```
+ #[clippy::version = "1.64.0"]
+ pub COLLAPSIBLE_STR_REPLACE,
+ perf,
+ "collapse consecutive calls to str::replace (2 or more) into a single call"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
/// Checks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed.
///
/// ### Why is this bad?
@@ -173,7 +221,7 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
- /// Checks for `.unwrap()` calls on `Option`s and on `Result`s.
+ /// Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s.
///
/// ### Why is this bad?
/// It is better to handle the `None` or `Err` case,
@@ -204,6 +252,17 @@ declare_clippy_lint! {
/// option.expect("more helpful message");
/// result.expect("more helpful message");
/// ```
+ ///
+ /// If [expect_used](#expect_used) is enabled, instead:
+ /// ```rust,ignore
+ /// # let option = Some(1);
+ /// # let result: Result<usize, ()> = Ok(1);
+ /// option?;
+ ///
+ /// // or
+ ///
+ /// result?;
+ /// ```
#[clippy::version = "1.45.0"]
pub UNWRAP_USED,
restriction,
@@ -212,7 +271,7 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
- /// Checks for `.expect()` calls on `Option`s and `Result`s.
+ /// Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s.
///
/// ### Why is this bad?
/// Usually it is better to handle the `None` or `Err` case.
@@ -766,8 +825,9 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
/// Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,
- /// etc., and suggests to use `or_else`, `unwrap_or_else`, etc., or
- /// `unwrap_or_default` instead.
+ /// `.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`,
+ /// `.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()`
+ /// etc. instead.
///
/// ### Why is this bad?
/// The function will always be called and potentially
@@ -1997,6 +2057,55 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
+ /// Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`.
+ ///
+ /// ### Why is this bad?
+ /// Calling `to_owned()` on a `Cow` creates a clone of the `Cow`
+ /// itself, without taking ownership of the `Cow` contents (i.e.
+ /// it's equivalent to calling `Cow::clone`).
+ /// The similarly named `into_owned` method, on the other hand,
+ /// clones the `Cow` contents, effectively turning any `Cow::Borrowed`
+ /// into a `Cow::Owned`.
+ ///
+ /// Given the potential ambiguity, consider replacing `to_owned`
+ /// with `clone` for better readability or, if getting a `Cow::Owned`
+ /// was the original intent, using `into_owned` instead.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::borrow::Cow;
+ /// let s = "Hello world!";
+ /// let cow = Cow::Borrowed(s);
+ ///
+ /// let data = cow.to_owned();
+ /// assert!(matches!(data, Cow::Borrowed(_)))
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # use std::borrow::Cow;
+ /// let s = "Hello world!";
+ /// let cow = Cow::Borrowed(s);
+ ///
+ /// let data = cow.clone();
+ /// assert!(matches!(data, Cow::Borrowed(_)))
+ /// ```
+ /// or
+ /// ```rust
+ /// # use std::borrow::Cow;
+ /// let s = "Hello world!";
+ /// let cow = Cow::Borrowed(s);
+ ///
+ /// let data = cow.into_owned();
+ /// assert!(matches!(data, String))
+ /// ```
+ #[clippy::version = "1.65.0"]
+ pub SUSPICIOUS_TO_OWNED,
+ suspicious,
+ "calls to `to_owned` on a `Cow<'_, _>` might not do what they are expected"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
/// Checks for calls to [`splitn`]
/// (https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and
/// related functions with either zero or one splits.
@@ -2258,7 +2367,7 @@ declare_clippy_lint! {
/// "1234".replace("12", "12");
/// "1234".replacen("12", "12", 1);
/// ```
- #[clippy::version = "1.62.0"]
+ #[clippy::version = "1.63.0"]
pub NO_EFFECT_REPLACE,
suspicious,
"replace with no effect"
@@ -2293,6 +2402,640 @@ declare_clippy_lint! {
more clearly with `if .. else ..`"
}
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item
+ ///
+ /// ### Why is this bad?
+ ///
+ /// It is simpler to use the once function from the standard library:
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// let a = [123].iter();
+ /// let b = Some(123).into_iter();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// use std::iter;
+ /// let a = iter::once(&123);
+ /// let b = iter::once(123);
+ /// ```
+ ///
+ /// ### Known problems
+ ///
+ /// The type of the resulting iterator might become incompatible with its usage
+ #[clippy::version = "1.64.0"]
+ pub ITER_ON_SINGLE_ITEMS,
+ nursery,
+ "Iterator for array of length 1"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections
+ ///
+ /// ### Why is this bad?
+ ///
+ /// It is simpler to use the empty function from the standard library:
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// use std::{slice, option};
+ /// let a: slice::Iter<i32> = [].iter();
+ /// let f: option::IntoIter<i32> = None.into_iter();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// use std::iter;
+ /// let a: iter::Empty<i32> = iter::empty();
+ /// let b: iter::Empty<i32> = iter::empty();
+ /// ```
+ ///
+ /// ### Known problems
+ ///
+ /// The type of the resulting iterator might become incompatible with its usage
+ #[clippy::version = "1.64.0"]
+ pub ITER_ON_EMPTY_COLLECTIONS,
+ nursery,
+ "Iterator for empty array"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for naive byte counts
+ ///
+ /// ### Why is this bad?
+ /// The [`bytecount`](https://crates.io/crates/bytecount)
+ /// crate has methods to count your bytes faster, especially for large slices.
+ ///
+ /// ### Known problems
+ /// If you have predominantly small slices, the
+ /// `bytecount::count(..)` method may actually be slower. However, if you can
+ /// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
+ /// faster in those cases.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # let vec = vec![1_u8];
+ /// let count = vec.iter().filter(|x| **x == 0u8).count();
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust,ignore
+ /// # let vec = vec![1_u8];
+ /// let count = bytecount::count(&vec, 0u8);
+ /// ```
+ #[clippy::version = "pre 1.29.0"]
+ pub NAIVE_BYTECOUNT,
+ pedantic,
+ "use of naive `<slice>.filter(|&x| x == y).count()` to count byte values"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// It checks for `str::bytes().count()` and suggests replacing it with
+ /// `str::len()`.
+ ///
+ /// ### Why is this bad?
+ /// `str::bytes().count()` is longer and may not be as performant as using
+ /// `str::len()`.
+ ///
+ /// ### Example
+ /// ```rust
+ /// "hello".bytes().count();
+ /// String::from("hello").bytes().count();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// "hello".len();
+ /// String::from("hello").len();
+ /// ```
+ #[clippy::version = "1.62.0"]
+ pub BYTES_COUNT_TO_LEN,
+ complexity,
+ "Using `bytes().count()` when `len()` performs the same functionality"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for calls to `ends_with` with possible file extensions
+ /// and suggests to use a case-insensitive approach instead.
+ ///
+ /// ### Why is this bad?
+ /// `ends_with` is case-sensitive and may not detect files with a valid extension.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn is_rust_file(filename: &str) -> bool {
+ /// filename.ends_with(".rs")
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// fn is_rust_file(filename: &str) -> bool {
+ /// let filename = std::path::Path::new(filename);
+ /// filename.extension()
+ /// .map_or(false, |ext| ext.eq_ignore_ascii_case("rs"))
+ /// }
+ /// ```
+ #[clippy::version = "1.51.0"]
+ pub CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
+ pedantic,
+ "Checks for calls to ends_with with case-sensitive file extensions"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for using `x.get(0)` instead of
+ /// `x.first()`.
+ ///
+ /// ### Why is this bad?
+ /// Using `x.first()` is easier to read and has the same
+ /// result.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let x = vec![2, 3, 5];
+ /// let first_element = x.get(0);
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// let x = vec![2, 3, 5];
+ /// let first_element = x.first();
+ /// ```
+ #[clippy::version = "1.63.0"]
+ pub GET_FIRST,
+ style,
+ "Using `x.get(0)` when `x.first()` is simpler"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Finds patterns that reimplement `Option::ok_or`.
+ ///
+ /// ### Why is this bad?
+ ///
+ /// Concise code helps focusing on behavior instead of boilerplate.
+ ///
+ /// ### Examples
+ /// ```rust
+ /// let foo: Option<i32> = None;
+ /// foo.map_or(Err("error"), |v| Ok(v));
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// let foo: Option<i32> = None;
+ /// foo.ok_or("error");
+ /// ```
+ #[clippy::version = "1.49.0"]
+ pub MANUAL_OK_OR,
+ pedantic,
+ "finds patterns that can be encoded more concisely with `Option::ok_or`"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for usage of `map(|x| x.clone())` or
+ /// dereferencing closures for `Copy` types, on `Iterator` or `Option`,
+ /// and suggests `cloned()` or `copied()` instead
+ ///
+ /// ### Why is this bad?
+ /// Readability, this can be written more concisely
+ ///
+ /// ### Example
+ /// ```rust
+ /// let x = vec![42, 43];
+ /// let y = x.iter();
+ /// let z = y.map(|i| *i);
+ /// ```
+ ///
+ /// The correct use would be:
+ ///
+ /// ```rust
+ /// let x = vec![42, 43];
+ /// let y = x.iter();
+ /// let z = y.cloned();
+ /// ```
+ #[clippy::version = "pre 1.29.0"]
+ pub MAP_CLONE,
+ style,
+ "using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for instances of `map_err(|_| Some::Enum)`
+ ///
+ /// ### Why is this bad?
+ /// This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error
+ ///
+ /// ### Example
+ /// Before:
+ /// ```rust
+ /// use std::fmt;
+ ///
+ /// #[derive(Debug)]
+ /// enum Error {
+ /// Indivisible,
+ /// Remainder(u8),
+ /// }
+ ///
+ /// impl fmt::Display for Error {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// match self {
+ /// Error::Indivisible => write!(f, "could not divide input by three"),
+ /// Error::Remainder(remainder) => write!(
+ /// f,
+ /// "input is not divisible by three, remainder = {}",
+ /// remainder
+ /// ),
+ /// }
+ /// }
+ /// }
+ ///
+ /// impl std::error::Error for Error {}
+ ///
+ /// fn divisible_by_3(input: &str) -> Result<(), Error> {
+ /// input
+ /// .parse::<i32>()
+ /// .map_err(|_| Error::Indivisible)
+ /// .map(|v| v % 3)
+ /// .and_then(|remainder| {
+ /// if remainder == 0 {
+ /// Ok(())
+ /// } else {
+ /// Err(Error::Remainder(remainder as u8))
+ /// }
+ /// })
+ /// }
+ /// ```
+ ///
+ /// After:
+ /// ```rust
+ /// use std::{fmt, num::ParseIntError};
+ ///
+ /// #[derive(Debug)]
+ /// enum Error {
+ /// Indivisible(ParseIntError),
+ /// Remainder(u8),
+ /// }
+ ///
+ /// impl fmt::Display for Error {
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// match self {
+ /// Error::Indivisible(_) => write!(f, "could not divide input by three"),
+ /// Error::Remainder(remainder) => write!(
+ /// f,
+ /// "input is not divisible by three, remainder = {}",
+ /// remainder
+ /// ),
+ /// }
+ /// }
+ /// }
+ ///
+ /// impl std::error::Error for Error {
+ /// fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ /// match self {
+ /// Error::Indivisible(source) => Some(source),
+ /// _ => None,
+ /// }
+ /// }
+ /// }
+ ///
+ /// fn divisible_by_3(input: &str) -> Result<(), Error> {
+ /// input
+ /// .parse::<i32>()
+ /// .map_err(Error::Indivisible)
+ /// .map(|v| v % 3)
+ /// .and_then(|remainder| {
+ /// if remainder == 0 {
+ /// Ok(())
+ /// } else {
+ /// Err(Error::Remainder(remainder as u8))
+ /// }
+ /// })
+ /// }
+ /// ```
+ #[clippy::version = "1.48.0"]
+ pub MAP_ERR_IGNORE,
+ restriction,
+ "`map_err` should not ignore the original error"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for `&mut Mutex::lock` calls
+ ///
+ /// ### Why is this bad?
+ /// `Mutex::lock` is less efficient than
+ /// calling `Mutex::get_mut`. In addition you also have a statically
+ /// guarantee that the mutex isn't locked, instead of just a runtime
+ /// guarantee.
+ ///
+ /// ### Example
+ /// ```rust
+ /// use std::sync::{Arc, Mutex};
+ ///
+ /// let mut value_rc = Arc::new(Mutex::new(42_u8));
+ /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
+ ///
+ /// let mut value = value_mutex.lock().unwrap();
+ /// *value += 1;
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// use std::sync::{Arc, Mutex};
+ ///
+ /// let mut value_rc = Arc::new(Mutex::new(42_u8));
+ /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
+ ///
+ /// let value = value_mutex.get_mut().unwrap();
+ /// *value += 1;
+ /// ```
+ #[clippy::version = "1.49.0"]
+ pub MUT_MUTEX_LOCK,
+ style,
+ "`&mut Mutex::lock` does unnecessary locking"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for duplicate open options as well as combinations
+ /// that make no sense.
+ ///
+ /// ### Why is this bad?
+ /// In the best case, the code will be harder to read than
+ /// necessary. I don't know the worst case.
+ ///
+ /// ### Example
+ /// ```rust
+ /// use std::fs::OpenOptions;
+ ///
+ /// OpenOptions::new().read(true).truncate(true);
+ /// ```
+ #[clippy::version = "pre 1.29.0"]
+ pub NONSENSICAL_OPEN_OPTIONS,
+ correctness,
+ "nonsensical combination of options for opening a file"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
+ /// calls on `PathBuf` that can cause overwrites.
+ ///
+ /// ### Why is this bad?
+ /// Calling `push` with a root path at the start can overwrite the
+ /// previous defined path.
+ ///
+ /// ### Example
+ /// ```rust
+ /// use std::path::PathBuf;
+ ///
+ /// let mut x = PathBuf::from("/foo");
+ /// x.push("/bar");
+ /// assert_eq!(x, PathBuf::from("/bar"));
+ /// ```
+ /// Could be written:
+ ///
+ /// ```rust
+ /// use std::path::PathBuf;
+ ///
+ /// let mut x = PathBuf::from("/foo");
+ /// x.push("bar");
+ /// assert_eq!(x, PathBuf::from("/foo/bar"));
+ /// ```
+ #[clippy::version = "1.36.0"]
+ pub PATH_BUF_PUSH_OVERWRITE,
+ nursery,
+ "calling `push` with file system root on `PathBuf` can overwrite it"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for zipping a collection with the range of
+ /// `0.._.len()`.
+ ///
+ /// ### Why is this bad?
+ /// The code is better expressed with `.enumerate()`.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # let x = vec![1];
+ /// let _ = x.iter().zip(0..x.len());
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// # let x = vec![1];
+ /// let _ = x.iter().enumerate();
+ /// ```
+ #[clippy::version = "pre 1.29.0"]
+ pub RANGE_ZIP_WITH_LEN,
+ complexity,
+ "zipping iterator with a range when `enumerate()` would do"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for usage of `.repeat(1)` and suggest the following method for each types.
+ /// - `.to_string()` for `str`
+ /// - `.clone()` for `String`
+ /// - `.to_vec()` for `slice`
+ ///
+ /// The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if
+ /// they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))
+ ///
+ /// ### Why is this bad?
+ /// For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning
+ /// the string is the intention behind this, `clone()` should be used.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn main() {
+ /// let x = String::from("hello world").repeat(1);
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// fn main() {
+ /// let x = String::from("hello world").clone();
+ /// }
+ /// ```
+ #[clippy::version = "1.47.0"]
+ pub REPEAT_ONCE,
+ complexity,
+ "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` "
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// When sorting primitive values (integers, bools, chars, as well
+ /// as arrays, slices, and tuples of such items), it is typically better to
+ /// use an unstable sort than a stable sort.
+ ///
+ /// ### Why is this bad?
+ /// Typically, using a stable sort consumes more memory and cpu cycles.
+ /// Because values which compare equal are identical, preserving their
+ /// relative order (the guarantee that a stable sort provides) means
+ /// nothing, while the extra costs still apply.
+ ///
+ /// ### Known problems
+ ///
+ /// As pointed out in
+ /// [issue #8241](https://github.com/rust-lang/rust-clippy/issues/8241),
+ /// a stable sort can instead be significantly faster for certain scenarios
+ /// (eg. when a sorted vector is extended with new data and resorted).
+ ///
+ /// For more information and benchmarking results, please refer to the
+ /// issue linked above.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let mut vec = vec![2, 1, 3];
+ /// vec.sort();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let mut vec = vec![2, 1, 3];
+ /// vec.sort_unstable();
+ /// ```
+ #[clippy::version = "1.47.0"]
+ pub STABLE_SORT_PRIMITIVE,
+ pedantic,
+ "use of sort() when sort_unstable() is equivalent"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Detects `().hash(_)`.
+ ///
+ /// ### Why is this bad?
+ /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::hash::Hash;
+ /// # use std::collections::hash_map::DefaultHasher;
+ /// # enum Foo { Empty, WithValue(u8) }
+ /// # use Foo::*;
+ /// # let mut state = DefaultHasher::new();
+ /// # let my_enum = Foo::Empty;
+ /// match my_enum {
+ /// Empty => ().hash(&mut state),
+ /// WithValue(x) => x.hash(&mut state),
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # use std::hash::Hash;
+ /// # use std::collections::hash_map::DefaultHasher;
+ /// # enum Foo { Empty, WithValue(u8) }
+ /// # use Foo::*;
+ /// # let mut state = DefaultHasher::new();
+ /// # let my_enum = Foo::Empty;
+ /// match my_enum {
+ /// Empty => 0_u8.hash(&mut state),
+ /// WithValue(x) => x.hash(&mut state),
+ /// }
+ /// ```
+ #[clippy::version = "1.58.0"]
+ pub UNIT_HASH,
+ correctness,
+ "hashing a unit value, which does nothing"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Detects uses of `Vec::sort_by` passing in a closure
+ /// which compares the two arguments, either directly or indirectly.
+ ///
+ /// ### Why is this bad?
+ /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if
+ /// possible) than to use `Vec::sort_by` and a more complicated
+ /// closure.
+ ///
+ /// ### Known problems
+ /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already
+ /// imported by a use statement, then it will need to be added manually.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # struct A;
+ /// # impl A { fn foo(&self) {} }
+ /// # let mut vec: Vec<A> = Vec::new();
+ /// vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # struct A;
+ /// # impl A { fn foo(&self) {} }
+ /// # let mut vec: Vec<A> = Vec::new();
+ /// vec.sort_by_key(|a| a.foo());
+ /// ```
+ #[clippy::version = "1.46.0"]
+ pub UNNECESSARY_SORT_BY,
+ complexity,
+ "Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Finds occurrences of `Vec::resize(0, an_int)`
+ ///
+ /// ### Why is this bad?
+ /// This is probably an argument inversion mistake.
+ ///
+ /// ### Example
+ /// ```rust
+ /// vec!(1, 2, 3, 4, 5).resize(0, 5)
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// vec!(1, 2, 3, 4, 5).clear()
+ /// ```
+ #[clippy::version = "1.46.0"]
+ pub VEC_RESIZE_TO_ZERO,
+ correctness,
+ "emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for use of File::read_to_end and File::read_to_string.
+ ///
+ /// ### Why is this bad?
+ /// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.
+ /// See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)
+ ///
+ /// ### Example
+ /// ```rust,no_run
+ /// # use std::io::Read;
+ /// # use std::fs::File;
+ /// let mut f = File::open("foo.txt").unwrap();
+ /// let mut bytes = Vec::new();
+ /// f.read_to_end(&mut bytes).unwrap();
+ /// ```
+ /// Can be written more concisely as
+ /// ```rust,no_run
+ /// # use std::fs;
+ /// let mut bytes = fs::read("foo.txt").unwrap();
+ /// ```
+ #[clippy::version = "1.44.0"]
+ pub VERBOSE_FILE_READS,
+ restriction,
+ "use of `File::read_to_end` or `File::read_to_string`"
+}
+
pub struct Methods {
avoid_breaking_exported_api: bool,
msrv: Option<RustcVersion>,
@@ -2336,6 +3079,7 @@ impl_lint_pass!(Methods => [
CLONE_ON_COPY,
CLONE_ON_REF_PTR,
CLONE_DOUBLE_REF,
+ COLLAPSIBLE_STR_REPLACE,
ITER_OVEREAGER_CLONED,
CLONED_INSTEAD_OF_COPIED,
FLAT_MAP_OPTION,
@@ -2382,6 +3126,7 @@ impl_lint_pass!(Methods => [
FROM_ITER_INSTEAD_OF_COLLECT,
INSPECT_FOR_EACH,
IMPLICIT_CLONE,
+ SUSPICIOUS_TO_OWNED,
SUSPICIOUS_SPLITN,
MANUAL_STR_REPEAT,
EXTEND_WITH_DRAIN,
@@ -2395,14 +3140,35 @@ impl_lint_pass!(Methods => [
NEEDLESS_OPTION_TAKE,
NO_EFFECT_REPLACE,
OBFUSCATED_IF_ELSE,
+ ITER_ON_SINGLE_ITEMS,
+ ITER_ON_EMPTY_COLLECTIONS,
+ NAIVE_BYTECOUNT,
+ BYTES_COUNT_TO_LEN,
+ CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
+ GET_FIRST,
+ MANUAL_OK_OR,
+ MAP_CLONE,
+ MAP_ERR_IGNORE,
+ MUT_MUTEX_LOCK,
+ NONSENSICAL_OPEN_OPTIONS,
+ PATH_BUF_PUSH_OVERWRITE,
+ RANGE_ZIP_WITH_LEN,
+ REPEAT_ONCE,
+ STABLE_SORT_PRIMITIVE,
+ UNIT_HASH,
+ UNNECESSARY_SORT_BY,
+ VEC_RESIZE_TO_ZERO,
+ VERBOSE_FILE_READS,
]);
/// Extracts a method call name, args, and `Span` of the method name.
-fn method_call<'tcx>(recv: &'tcx hir::Expr<'tcx>) -> Option<(&'tcx str, &'tcx [hir::Expr<'tcx>], Span)> {
- if let ExprKind::MethodCall(path, args, _) = recv.kind {
- if !args.iter().any(|e| e.span.from_expansion()) {
+fn method_call<'tcx>(
+ recv: &'tcx hir::Expr<'tcx>,
+) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span)> {
+ if let ExprKind::MethodCall(path, receiver, args, _) = recv.kind {
+ if !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() {
let name = path.ident.name.as_str();
- return Some((name, args, path.ident.span));
+ return Some((name, receiver, args, path.ident.span));
}
}
None
@@ -2420,17 +3186,17 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
hir::ExprKind::Call(func, args) => {
from_iter_instead_of_collect::check(cx, expr, args, func);
},
- hir::ExprKind::MethodCall(method_call, args, _) => {
+ hir::ExprKind::MethodCall(method_call, receiver, args, _) => {
let method_span = method_call.ident.span;
- or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), args);
- expect_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), args);
- clone_on_copy::check(cx, expr, method_call.ident.name, args);
- clone_on_ref_ptr::check(cx, expr, method_call.ident.name, args);
- inefficient_to_string::check(cx, expr, method_call.ident.name, args);
- single_char_add_str::check(cx, expr, args);
- into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, args);
- single_char_pattern::check(cx, expr, method_call.ident.name, args);
- unnecessary_to_owned::check(cx, expr, method_call.ident.name, args, self.msrv);
+ or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
+ expect_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
+ clone_on_copy::check(cx, expr, method_call.ident.name, receiver, args);
+ clone_on_ref_ptr::check(cx, expr, method_call.ident.name, receiver, args);
+ inefficient_to_string::check(cx, expr, method_call.ident.name, receiver, args);
+ single_char_add_str::check(cx, expr, receiver, args);
+ into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, receiver);
+ single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args);
+ unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, self.msrv);
},
hir::ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
let mut info = BinaryExprInfo {
@@ -2530,7 +3296,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if contains_adt_constructor(ret_ty, self_adt) {
return;
}
- } else if contains_ty(ret_ty, self_ty) {
+ } else if ret_ty.contains(self_ty) {
return;
}
@@ -2539,16 +3305,16 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
// one of the associated types must be Self
for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) {
if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
- let assoc_ty = match projection_predicate.term {
- ty::Term::Ty(ty) => ty,
- ty::Term::Const(_c) => continue,
+ let assoc_ty = match projection_predicate.term.unpack() {
+ ty::TermKind::Ty(ty) => ty,
+ ty::TermKind::Const(_c) => continue,
};
// walk the associated type and check for Self
if let Some(self_adt) = self_ty.ty_adt_def() {
if contains_adt_constructor(assoc_ty, self_adt) {
return;
}
- } else if contains_ty(assoc_ty, self_ty) {
+ } else if assoc_ty.contains(self_ty) {
return;
}
}
@@ -2597,7 +3363,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if let TraitItemKind::Fn(_, _) = item.kind;
let ret_ty = return_ty(cx, item.hir_id());
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
- if !contains_ty(ret_ty, self_ty);
+ if !ret_ty.contains(self_ty);
then {
span_lint(
@@ -2616,7 +3382,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
impl Methods {
#[allow(clippy::too_many_lines)]
fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if let Some((name, [recv, args @ ..], span)) = method_call(expr) {
+ if let Some((name, recv, args, span)) = method_call(expr) {
match (name, args) {
("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
zst_offset::check(cx, expr, recv);
@@ -2636,35 +3402,43 @@ impl Methods {
("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv),
("collect", []) => match method_call(recv) {
- Some((name @ ("cloned" | "copied"), [recv2], _)) => {
+ Some((name @ ("cloned" | "copied"), recv2, [], _)) => {
iter_cloned_collect::check(cx, name, expr, recv2);
},
- Some(("map", [m_recv, m_arg], _)) => {
+ Some(("map", m_recv, [m_arg], _)) => {
map_collect_result_unit::check(cx, expr, m_recv, m_arg, recv);
},
- Some(("take", [take_self_arg, take_arg], _)) => {
+ Some(("take", take_self_arg, [take_arg], _)) => {
if meets_msrv(self.msrv, msrvs::STR_REPEAT) {
manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
}
},
_ => {},
},
- ("count", []) => match method_call(recv) {
- Some(("cloned", [recv2], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, true, false),
- Some((name2 @ ("into_iter" | "iter" | "iter_mut"), [recv2], _)) => {
+ ("count", []) if is_trait_method(cx, expr, sym::Iterator) => match method_call(recv) {
+ Some(("cloned", recv2, [], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, true, false),
+ Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _)) => {
iter_count::check(cx, expr, recv2, name2);
},
- Some(("map", [_, arg], _)) => suspicious_map::check(cx, expr, recv, arg),
+ Some(("map", _, [arg], _)) => suspicious_map::check(cx, expr, recv, arg),
+ Some(("filter", recv2, [arg], _)) => bytecount::check(cx, expr, recv2, arg),
+ Some(("bytes", recv2, [], _)) => bytes_count_to_len::check(cx, expr, recv, recv2),
_ => {},
},
("drain", [arg]) => {
iter_with_drain::check(cx, expr, recv, span, arg);
},
+ ("ends_with", [arg]) => {
+ if let ExprKind::MethodCall(.., span) = expr.kind {
+ case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg);
+ }
+ },
("expect", [_]) => match method_call(recv) {
- Some(("ok", [recv], _)) => ok_expect::check(cx, expr, recv),
- Some(("err", [recv], err_span)) => err_expect::check(cx, expr, recv, self.msrv, span, err_span),
- _ => expect_used::check(cx, expr, recv, self.allow_expect_in_tests),
+ Some(("ok", recv, [], _)) => ok_expect::check(cx, expr, recv),
+ Some(("err", recv, [], err_span)) => err_expect::check(cx, expr, recv, self.msrv, span, err_span),
+ _ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests),
},
+ ("expect_err", [_]) => expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests),
("extend", [arg]) => {
string_extend_chars::check(cx, expr, recv, arg);
extend_with_drain::check(cx, expr, recv, arg);
@@ -2681,36 +3455,53 @@ impl Methods {
flat_map_option::check(cx, expr, arg, span);
},
("flatten", []) => match method_call(recv) {
- Some(("map", [recv, map_arg], map_span)) => map_flatten::check(cx, expr, recv, map_arg, map_span),
- Some(("cloned", [recv2], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, true),
+ Some(("map", recv, [map_arg], map_span)) => map_flatten::check(cx, expr, recv, map_arg, map_span),
+ Some(("cloned", recv2, [], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, true),
_ => {},
},
("fold", [init, acc]) => unnecessary_fold::check(cx, expr, init, acc, span),
("for_each", [_]) => {
- if let Some(("inspect", [_, _], span2)) = method_call(recv) {
+ if let Some(("inspect", _, [_], span2)) = method_call(recv) {
inspect_for_each::check(cx, expr, span2);
}
},
- ("get", [arg]) => get_last_with_len::check(cx, expr, recv, arg),
+ ("get", [arg]) => {
+ get_first::check(cx, expr, recv, arg);
+ get_last_with_len::check(cx, expr, recv, arg);
+ },
("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
+ ("hash", [arg]) => {
+ unit_hash::check(cx, expr, recv, arg);
+ },
("is_file", []) => filetype_is_file::check(cx, expr, recv),
("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),
("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
+ ("iter" | "iter_mut" | "into_iter", []) => {
+ iter_on_single_or_empty_collections::check(cx, expr, name, recv);
+ },
("join", [join_arg]) => {
- if let Some(("collect", _, span)) = method_call(recv) {
+ if let Some(("collect", _, _, span)) = method_call(recv) {
unnecessary_join::check(cx, expr, recv, join_arg, span);
}
},
("last", []) | ("skip", [_]) => {
- if let Some((name2, [recv2, args2 @ ..], _span2)) = method_call(recv) {
+ if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
if let ("cloned", []) = (name2, args2) {
iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
}
}
},
+ ("lock", []) => {
+ mut_mutex_lock::check(cx, expr, recv, span);
+ },
(name @ ("map" | "map_err"), [m_arg]) => {
- if let Some((name, [recv2, args @ ..], span2)) = method_call(recv) {
+ if name == "map" {
+ map_clone::check(cx, expr, recv, m_arg, self.msrv);
+ } else {
+ map_err_ignore::check(cx, expr, m_arg);
+ }
+ if let Some((name, recv2, args, span2)) = method_call(recv) {
match (name, args) {
("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv),
("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv),
@@ -2725,9 +3516,12 @@ impl Methods {
}
map_identity::check(cx, expr, recv, m_arg, name, span);
},
- ("map_or", [def, map]) => option_map_or_none::check(cx, expr, recv, def, map),
+ ("map_or", [def, map]) => {
+ option_map_or_none::check(cx, expr, recv, def, map);
+ manual_ok_or::check(cx, expr, recv, def, map);
+ },
("next", []) => {
- if let Some((name2, [recv2, args2 @ ..], _)) = method_call(recv) {
+ if let Some((name2, recv2, args2, _)) = method_call(recv) {
match (name2, args2) {
("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
@@ -2740,18 +3534,53 @@ impl Methods {
}
},
("nth", [n_arg]) => match method_call(recv) {
- Some(("bytes", [recv2], _)) => bytes_nth::check(cx, expr, recv2, n_arg),
- Some(("cloned", [recv2], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
- Some(("iter", [recv2], _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false),
- Some(("iter_mut", [recv2], _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true),
+ Some(("bytes", recv2, [], _)) => bytes_nth::check(cx, expr, recv2, n_arg),
+ Some(("cloned", recv2, [], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
+ Some(("iter", recv2, [], _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false),
+ Some(("iter_mut", recv2, [], _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true),
_ => iter_nth_zero::check(cx, expr, recv, n_arg),
},
("ok_or_else", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"),
+ ("open", [_]) => {
+ open_options::check(cx, expr, recv);
+ },
("or_else", [arg]) => {
if !bind_instead_of_map::ResultOrElseErrInfo::check(cx, expr, recv, arg) {
unnecessary_lazy_eval::check(cx, expr, recv, arg, "or");
}
},
+ ("push", [arg]) => {
+ path_buf_push_overwrite::check(cx, expr, arg);
+ },
+ ("read_to_end", [_]) => {
+ verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_END_MSG);
+ },
+ ("read_to_string", [_]) => {
+ verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_STRING_MSG);
+ },
+ ("repeat", [arg]) => {
+ repeat_once::check(cx, expr, recv, arg);
+ },
+ (name @ ("replace" | "replacen"), [arg1, arg2] | [arg1, arg2, _]) => {
+ no_effect_replace::check(cx, expr, arg1, arg2);
+
+ // Check for repeated `str::replace` calls to perform `collapsible_str_replace` lint
+ if name == "replace" && let Some(("replace", ..)) = method_call(recv) {
+ collapsible_str_replace::check(cx, expr, arg1, arg2);
+ }
+ },
+ ("resize", [count_arg, default_arg]) => {
+ vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span);
+ },
+ ("sort", []) => {
+ stable_sort_primitive::check(cx, expr, recv);
+ },
+ ("sort_by", [arg]) => {
+ unnecessary_sort_by::check(cx, expr, recv, arg, false);
+ },
+ ("sort_unstable_by", [arg]) => {
+ unnecessary_sort_by::check(cx, expr, recv, arg, true);
+ },
("splitn" | "rsplitn", [count_arg, pat_arg]) => {
if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
suspicious_splitn::check(cx, name, expr, recv, count);
@@ -2765,7 +3594,7 @@ impl Methods {
},
("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
("take", [_arg]) => {
- if let Some((name2, [recv2, args2 @ ..], _span2)) = method_call(recv) {
+ if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
if let ("cloned", []) = (name2, args2) {
iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
}
@@ -2778,46 +3607,56 @@ impl Methods {
}
unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some");
},
- ("to_os_string" | "to_owned" | "to_path_buf" | "to_vec", []) => {
+ ("to_owned", []) => {
+ if !suspicious_to_owned::check(cx, expr, recv) {
+ implicit_clone::check(cx, name, expr, recv);
+ }
+ },
+ ("to_os_string" | "to_path_buf" | "to_vec", []) => {
implicit_clone::check(cx, name, expr, recv);
},
("unwrap", []) => {
match method_call(recv) {
- Some(("get", [recv, get_arg], _)) => {
+ Some(("get", recv, [get_arg], _)) => {
get_unwrap::check(cx, expr, recv, get_arg, false);
},
- Some(("get_mut", [recv, get_arg], _)) => {
+ Some(("get_mut", recv, [get_arg], _)) => {
get_unwrap::check(cx, expr, recv, get_arg, true);
},
- Some(("or", [recv, or_arg], or_span)) => {
+ Some(("or", recv, [or_arg], or_span)) => {
or_then_unwrap::check(cx, expr, recv, or_arg, or_span);
},
_ => {},
}
- unwrap_used::check(cx, expr, recv, self.allow_unwrap_in_tests);
+ unwrap_used::check(cx, expr, recv, false, self.allow_unwrap_in_tests);
},
+ ("unwrap_err", []) => unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests),
("unwrap_or", [u_arg]) => match method_call(recv) {
- Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), [lhs, rhs], _)) => {
+ Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _)) => {
manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]);
},
- Some(("map", [m_recv, m_arg], span)) => {
+ Some(("map", m_recv, [m_arg], span)) => {
option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span);
},
- Some(("then_some", [t_recv, t_arg], _)) => {
+ Some(("then_some", t_recv, [t_arg], _)) => {
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg);
},
_ => {},
},
("unwrap_or_else", [u_arg]) => match method_call(recv) {
- Some(("map", [recv, map_arg], _))
+ Some(("map", recv, [map_arg], _))
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {},
_ => {
unwrap_or_else_default::check(cx, expr, recv, u_arg);
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
},
},
- ("replace" | "replacen", [arg1, arg2] | [arg1, arg2, _]) => {
- no_effect_replace::check(cx, expr, arg1, arg2);
+ ("zip", [arg]) => {
+ if let ExprKind::MethodCall(name, iter_recv, [], _) = recv.kind
+ && name.ident.name == sym::iter
+ {
+ range_zip_with_len::check(cx, expr, iter_recv, arg);
+ }
},
_ => {},
}
@@ -2826,7 +3665,7 @@ impl Methods {
}
fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, is_some: bool) {
- if let Some((name @ ("find" | "position" | "rposition"), [f_recv, arg], span)) = method_call(recv) {
+ if let Some((name @ ("find" | "position" | "rposition"), f_recv, [arg], span)) = method_call(recv) {
search_is_some::check(cx, expr, name, is_some, f_recv, arg, recv, span);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
new file mode 100644
index 000000000..b9593b368
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
@@ -0,0 +1,31 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::{expr_custom_deref_adjustment, ty::is_type_diagnostic_item};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, Mutability};
+use rustc_lint::LateContext;
+use rustc_middle::ty;
+use rustc_span::{sym, Span};
+
+use super::MUT_MUTEX_LOCK;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &'tcx Expr<'tcx>, name_span: Span) {
+ if_chain! {
+ if matches!(expr_custom_deref_adjustment(cx, recv), None | Some(Mutability::Mut));
+ if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind();
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Mutex);
+ then {
+ span_lint_and_sugg(
+ cx,
+ MUT_MUTEX_LOCK,
+ name_span,
+ "calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference",
+ "change this to",
+ "get_mut".to_owned(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
index 5a0b50420..597af853d 100644
--- a/src/tools/clippy/clippy_lints/src/open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
@@ -3,43 +3,19 @@ use clippy_utils::paths;
use clippy_utils::ty::match_type;
use rustc_ast::ast::LitKind;
use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_lint::LateContext;
use rustc_span::source_map::{Span, Spanned};
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for duplicate open options as well as combinations
- /// that make no sense.
- ///
- /// ### Why is this bad?
- /// In the best case, the code will be harder to read than
- /// necessary. I don't know the worst case.
- ///
- /// ### Example
- /// ```rust
- /// use std::fs::OpenOptions;
- ///
- /// OpenOptions::new().read(true).truncate(true);
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub NONSENSICAL_OPEN_OPTIONS,
- correctness,
- "nonsensical combination of options for opening a file"
-}
-
-declare_lint_pass!(OpenOptions => [NONSENSICAL_OPEN_OPTIONS]);
+use super::NONSENSICAL_OPEN_OPTIONS;
-impl<'tcx> LateLintPass<'tcx> for OpenOptions {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &e.kind {
- let obj_ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
- if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
- let mut options = Vec::new();
- get_open_options(cx, self_arg, &mut options);
- check_open_options(cx, &options, e.span);
- }
- }
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+ && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
+ && match_type(cx, cx.tcx.type_of(impl_id), &paths::OPEN_OPTIONS)
+ {
+ let mut options = Vec::new();
+ get_open_options(cx, recv, &mut options);
+ check_open_options(cx, &options, e.span);
}
}
@@ -60,12 +36,12 @@ enum OpenOption {
}
fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) {
- if let ExprKind::MethodCall(path, arguments, _) = argument.kind {
- let obj_ty = cx.typeck_results().expr_ty(&arguments[0]).peel_refs();
+ if let ExprKind::MethodCall(path, receiver, arguments, _) = argument.kind {
+ let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
// Only proceed if this is a call on some object of type std::fs::OpenOptions
- if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 {
- let argument_option = match arguments[1].kind {
+ if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && !arguments.is_empty() {
+ let argument_option = match arguments[0].kind {
ExprKind::Lit(ref span) => {
if let Spanned {
node: LitKind::Bool(lit),
@@ -101,7 +77,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
_ => (),
}
- get_open_options(cx, &arguments[0], options);
+ get_open_options(cx, receiver, options);
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 20cad0f18..c409268de 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -53,16 +53,15 @@ pub(super) fn check<'tcx>(
}),
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let closure_body = cx.tcx.hir().body(body);
- let closure_expr = peel_blocks(&closure_body.value);
+ let closure_expr = peel_blocks(closure_body.value);
match &closure_expr.kind {
- hir::ExprKind::MethodCall(_, args, _) => {
+ hir::ExprKind::MethodCall(_, receiver, [], _) => {
if_chain! {
- if args.len() == 1;
- if path_to_local_id(&args[0], closure_body.params[0].pat.hir_id);
+ if path_to_local_id(receiver, closure_body.params[0].pat.hir_id);
let adj = cx
.typeck_results()
- .expr_adjustments(&args[0])
+ .expr_adjustments(receiver)
.iter()
.map(|x| &x.kind)
.collect::<Box<[_]>>();
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs
index 5a39b82b0..6657cdccd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs
@@ -74,7 +74,7 @@ pub(super) fn check<'tcx>(
if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind;
let arg_snippet = snippet(cx, fn_decl_span, "..");
let body = cx.tcx.hir().body(body);
- if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);
+ if let Some((func, [arg_char])) = reduce_unit_expression(body.value);
if let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id));
if Some(id) == cx.tcx.lang_items().option_some_variant();
then {
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index 6c641af59..3c4002a3a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -78,7 +78,7 @@ pub(super) fn check<'tcx>(
map_span,
String::from(if unwrap_snippet_none { "and_then" } else { "map_or" }),
),
- (expr.span.with_lo(unwrap_recv.span.hi()), String::from("")),
+ (expr.span.with_lo(unwrap_recv.span.hi()), String::new()),
];
if !unwrap_snippet_none {
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 6af134019..b43b9258c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -20,9 +20,11 @@ pub(super) fn check<'tcx>(
expr: &hir::Expr<'_>,
method_span: Span,
name: &str,
+ receiver: &'tcx hir::Expr<'_>,
args: &'tcx [hir::Expr<'_>],
) {
- /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
+ /// Checks for `unwrap_or(T::new())`, `unwrap_or(T::default())`,
+ /// `or_insert(T::new())` or `or_insert(T::default())`.
#[allow(clippy::too_many_arguments)]
fn check_unwrap_or_default(
cx: &LateContext<'_>,
@@ -42,7 +44,11 @@ pub(super) fn check<'tcx>(
if_chain! {
if !or_has_args;
- if name == "unwrap_or";
+ if let Some(sugg) = match name {
+ "unwrap_or" => Some("unwrap_or_default"),
+ "or_insert" => Some("or_default"),
+ _ => None,
+ };
if let hir::ExprKind::Path(ref qpath) = fun.kind;
if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default);
let path = last_path_segment(qpath).ident.name;
@@ -58,7 +64,7 @@ pub(super) fn check<'tcx>(
method_span.with_hi(span.hi()),
&format!("use of `{}` followed by a call to `{}`", name, path),
"try this",
- "unwrap_or_default()".to_string(),
+ format!("{}()", sugg),
Applicability::MachineApplicable,
);
@@ -82,7 +88,7 @@ pub(super) fn check<'tcx>(
fun_span: Option<Span>,
) {
// (path, fn_has_argument, methods, suffix)
- static KNOW_TYPES: [(&[&str], bool, &[&str], &str); 4] = [
+ const KNOW_TYPES: [(&[&str], bool, &[&str], &str); 4] = [
(&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"),
(&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"),
(&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"),
@@ -144,7 +150,7 @@ pub(super) fn check<'tcx>(
}
}
- if let [self_arg, arg] = args {
+ if let [arg] = args {
let inner_arg = if let hir::ExprKind::Block(
hir::Block {
stmts: [],
@@ -163,11 +169,11 @@ pub(super) fn check<'tcx>(
let or_has_args = !or_args.is_empty();
if !check_unwrap_or_default(cx, name, fun, arg, or_has_args, expr.span, method_span) {
let fun_span = if or_has_args { None } else { Some(fun.span) };
- check_general_case(cx, name, method_span, self_arg, arg, expr.span, fun_span);
+ check_general_case(cx, name, method_span, receiver, arg, expr.span, fun_span);
}
},
hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
- check_general_case(cx, name, method_span, self_arg, arg, expr.span, None);
+ check_general_case(cx, name, method_span, receiver, arg, expr.span, None);
},
_ => (),
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs
new file mode 100644
index 000000000..0cc28c0dc
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs
@@ -0,0 +1,37 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::ty::is_type_diagnostic_item;
+use if_chain::if_chain;
+use rustc_ast::ast::LitKind;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::symbol::sym;
+use std::path::{Component, Path};
+
+use super::PATH_BUF_PUSH_OVERWRITE;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
+ if_chain! {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::PathBuf);
+ if let ExprKind::Lit(ref lit) = arg.kind;
+ if let LitKind::Str(ref path_lit, _) = lit.node;
+ if let pushed_path = Path::new(path_lit.as_str());
+ if let Some(pushed_path_lit) = pushed_path.to_str();
+ if pushed_path.has_root();
+ if let Some(root) = pushed_path.components().next();
+ if root == Component::RootDir;
+ then {
+ span_lint_and_sugg(
+ cx,
+ PATH_BUF_PUSH_OVERWRITE,
+ lit.span,
+ "calling `push` with '/' or '\\' (file system root) will overwrite the previous path definition",
+ "try",
+ format!("\"{}\"", pushed_path_lit.trim_start_matches(|c| c == '/' || c == '\\')),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs b/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
new file mode 100644
index 000000000..867a3b402
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
@@ -0,0 +1,34 @@
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::source::snippet;
+use clippy_utils::{higher, SpanlessEq};
+use clippy_utils::{is_integer_const, is_trait_method};
+use if_chain::if_chain;
+use rustc_hir::{Expr, ExprKind, QPath};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::RANGE_ZIP_WITH_LEN;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, zip_arg: &'tcx Expr<'_>) {
+ if_chain! {
+ if is_trait_method(cx, expr, sym::Iterator);
+ // range expression in `.zip()` call: `0..x.len()`
+ if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::Range::hir(zip_arg);
+ if is_integer_const(cx, start, 0);
+ // `.len()` call
+ if let ExprKind::MethodCall(len_path, len_recv, [], _) = end.kind;
+ if len_path.ident.name == sym::len;
+ // `.iter()` and `.len()` called on same `Path`
+ if let ExprKind::Path(QPath::Resolved(_, iter_path)) = recv.kind;
+ if let ExprKind::Path(QPath::Resolved(_, len_path)) = len_recv.kind;
+ if SpanlessEq::new(cx).eq_path_segments(iter_path.segments, len_path.segments);
+ then {
+ span_lint(cx,
+ RANGE_ZIP_WITH_LEN,
+ expr.span,
+ &format!("it is more idiomatic to use `{}.iter().enumerate()`",
+ snippet(cx, recv.span, "_"))
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs b/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs
new file mode 100644
index 000000000..0a14f9216
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs
@@ -0,0 +1,52 @@
+use clippy_utils::consts::{constant_context, Constant};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::REPEAT_ONCE;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ recv: &'tcx Expr<'_>,
+ repeat_arg: &'tcx Expr<'_>,
+) {
+ if constant_context(cx, cx.typeck_results()).expr(repeat_arg) == Some(Constant::Int(1)) {
+ let ty = cx.typeck_results().expr_ty(recv).peel_refs();
+ if ty.is_str() {
+ span_lint_and_sugg(
+ cx,
+ REPEAT_ONCE,
+ expr.span,
+ "calling `repeat(1)` on str",
+ "consider using `.to_string()` instead",
+ format!("{}.to_string()", snippet(cx, recv.span, r#""...""#)),
+ Applicability::MachineApplicable,
+ );
+ } else if ty.builtin_index().is_some() {
+ span_lint_and_sugg(
+ cx,
+ REPEAT_ONCE,
+ expr.span,
+ "calling `repeat(1)` on slice",
+ "consider using `.to_vec()` instead",
+ format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)),
+ Applicability::MachineApplicable,
+ );
+ } else if is_type_diagnostic_item(cx, ty, sym::String) {
+ span_lint_and_sugg(
+ cx,
+ REPEAT_ONCE,
+ expr.span,
+ "calling `repeat(1)` on a string literal",
+ "consider using `.clone()` instead",
+ format!("{}.clone()", snippet(cx, recv.span, r#""...""#)),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
index 9a5fabcf7..81450fd8c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
@@ -3,12 +3,12 @@ use clippy_utils::{match_def_path, paths};
use rustc_hir as hir;
use rustc_lint::LateContext;
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
if match_def_path(cx, fn_def_id, &paths::PUSH_STR) {
- single_char_push_string::check(cx, expr, args);
+ single_char_push_string::check(cx, expr, receiver, args);
} else if match_def_path(cx, fn_def_id, &paths::INSERT_STR) {
- single_char_insert_string::check(cx, expr, args);
+ single_char_insert_string::check(cx, expr, receiver, args);
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs
index 6cdc954c0..18b6b5be1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs
@@ -8,12 +8,12 @@ use rustc_lint::LateContext;
use super::SINGLE_CHAR_ADD_STR;
/// lint for length-1 `str`s as argument for `insert_str`
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let mut applicability = Applicability::MachineApplicable;
- if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[2], &mut applicability) {
+ if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability) {
let base_string_snippet =
- snippet_with_applicability(cx, args[0].span.source_callsite(), "_", &mut applicability);
- let pos_arg = snippet_with_applicability(cx, args[1].span, "..", &mut applicability);
+ snippet_with_applicability(cx, receiver.span.source_callsite(), "_", &mut applicability);
+ let pos_arg = snippet_with_applicability(cx, args[0].span, "..", &mut applicability);
let sugg = format!("{}.insert({}, {})", base_string_snippet, pos_arg, extension_string);
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
index bf9006c69..4221c52d5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
@@ -10,37 +10,43 @@ use rustc_span::symbol::Symbol;
use super::SINGLE_CHAR_PATTERN;
const PATTERN_METHODS: [(&str, usize); 24] = [
- ("contains", 1),
- ("starts_with", 1),
- ("ends_with", 1),
- ("find", 1),
- ("rfind", 1),
- ("split", 1),
- ("split_inclusive", 1),
- ("rsplit", 1),
- ("split_terminator", 1),
- ("rsplit_terminator", 1),
- ("splitn", 2),
- ("rsplitn", 2),
- ("split_once", 1),
- ("rsplit_once", 1),
- ("matches", 1),
- ("rmatches", 1),
- ("match_indices", 1),
- ("rmatch_indices", 1),
- ("strip_prefix", 1),
- ("strip_suffix", 1),
- ("trim_start_matches", 1),
- ("trim_end_matches", 1),
- ("replace", 1),
- ("replacen", 1),
+ ("contains", 0),
+ ("starts_with", 0),
+ ("ends_with", 0),
+ ("find", 0),
+ ("rfind", 0),
+ ("split", 0),
+ ("split_inclusive", 0),
+ ("rsplit", 0),
+ ("split_terminator", 0),
+ ("rsplit_terminator", 0),
+ ("splitn", 1),
+ ("rsplitn", 1),
+ ("split_once", 0),
+ ("rsplit_once", 0),
+ ("matches", 0),
+ ("rmatches", 0),
+ ("match_indices", 0),
+ ("rmatch_indices", 0),
+ ("strip_prefix", 0),
+ ("strip_suffix", 0),
+ ("trim_start_matches", 0),
+ ("trim_end_matches", 0),
+ ("replace", 0),
+ ("replacen", 0),
];
/// lint for length-1 `str`s for methods in `PATTERN_METHODS`
-pub(super) fn check(cx: &LateContext<'_>, _expr: &hir::Expr<'_>, method_name: Symbol, args: &[hir::Expr<'_>]) {
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ _expr: &hir::Expr<'_>,
+ method_name: Symbol,
+ receiver: &hir::Expr<'_>,
+ args: &[hir::Expr<'_>],
+) {
for &(method, pos) in &PATTERN_METHODS {
if_chain! {
- if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(&args[0]).kind();
+ if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind();
if *ty.kind() == ty::Str;
if method_name.as_str() == method && args.len() > pos;
let arg = &args[pos];
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs
index 0237d39cb..9ea675195 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs
@@ -8,11 +8,11 @@ use rustc_lint::LateContext;
use super::SINGLE_CHAR_ADD_STR;
/// lint for length-1 `str`s as argument for `push_str`
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let mut applicability = Applicability::MachineApplicable;
- if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability) {
+ if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability) {
let base_string_snippet =
- snippet_with_applicability(cx, args[0].span.source_callsite(), "..", &mut applicability);
+ snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability);
let sugg = format!("{}.push({})", base_string_snippet, extension_string);
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs
new file mode 100644
index 000000000..91951c65b
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs
@@ -0,0 +1,31 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_slice_of_primitives;
+use clippy_utils::source::snippet_with_context;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+
+use super::STABLE_SORT_PRIMITIVE;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+ && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
+ && cx.tcx.type_of(impl_id).is_slice()
+ && let Some(slice_type) = is_slice_of_primitives(cx, recv)
+ {
+ span_lint_and_then(
+ cx,
+ STABLE_SORT_PRIMITIVE,
+ e.span,
+ &format!("used `sort` on primitive type `{}`", slice_type),
+ |diag| {
+ let mut app = Applicability::MachineApplicable;
+ let recv_snip = snippet_with_context(cx, recv.span, e.span.ctxt(), "..", &mut app).0;
+ diag.span_suggestion(e.span, "try", format!("{}.sort_unstable()", recv_snip), app);
+ diag.note(
+ "an unstable sort typically performs faster without any observable difference for this data type",
+ );
+ },
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 4ac738272..9ca4d6555 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -130,7 +130,7 @@ fn check_manual_split_once_indirect(
let ctxt = expr.span.ctxt();
let mut parents = cx.tcx.hir().parent_iter(expr.hir_id);
if let (_, Node::Local(local)) = parents.next()?
- && let PatKind::Binding(BindingAnnotation::Mutable, iter_binding_id, iter_ident, None) = local.pat.kind
+ && let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind
&& let (iter_stmt_id, Node::Stmt(_)) = parents.next()?
&& let (_, Node::Block(enclosing_block)) = parents.next()?
@@ -212,11 +212,10 @@ fn indirect_usage<'tcx>(
ctxt: SyntaxContext,
) -> Option<IndirectUsage<'tcx>> {
if let StmtKind::Local(Local {
- pat:
- Pat {
- kind: PatKind::Binding(BindingAnnotation::Unannotated, _, ident, None),
- ..
- },
+ pat: Pat {
+ kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None),
+ ..
+ },
init: Some(init_expr),
hir_id: local_hir_id,
..
@@ -292,7 +291,7 @@ fn parse_iter_usage<'tcx>(
) -> Option<IterUsage> {
let (kind, span) = match iter.next() {
Some((_, Node::Expr(e))) if e.span.ctxt() == ctxt => {
- let (name, args) = if let ExprKind::MethodCall(name, [_, args @ ..], _) = e.kind {
+ let (name, args) = if let ExprKind::MethodCall(name, _, [args @ ..], _) = e.kind {
(name, args)
} else {
return None;
@@ -327,7 +326,7 @@ fn parse_iter_usage<'tcx>(
} else {
if_chain! {
if let Some((_, Node::Expr(next_expr))) = iter.next();
- if let ExprKind::MethodCall(next_name, [_], _) = next_expr.kind;
+ if let ExprKind::MethodCall(next_name, _, [], _) = next_expr.kind;
if next_name.ident.name == sym::next;
if next_expr.span.ctxt() == ctxt;
if let Some(next_id) = cx.typeck_results().type_dependent_def_id(next_expr.hir_id);
@@ -367,7 +366,7 @@ fn parse_iter_usage<'tcx>(
}
},
_ if e.span.ctxt() != ctxt => (None, span),
- ExprKind::MethodCall(name, [_], _)
+ ExprKind::MethodCall(name, _, [], _)
if name.ident.name == sym::unwrap
&& cx
.typeck_results()
diff --git a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
index d06658f2a..143dcee35 100644
--- a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
@@ -16,7 +16,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
return;
}
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
- let target = &arglists[0][0];
+ let target = &arglists[0].0;
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
let ref_str = if *self_ty.kind() == ty::Str {
""
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs
index 9c3375bf3..851cdf544 100644
--- a/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs
@@ -15,9 +15,9 @@ pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, count_recv: &hi
if let Some(def_id) = cx.tcx.hir().opt_local_def_id(closure.hir_id);
if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id);
let closure_body = cx.tcx.hir().body(body_id);
- if !cx.typeck_results().expr_ty(&closure_body.value).is_unit();
+ if !cx.typeck_results().expr_ty(closure_body.value).is_unit();
then {
- if let Some(map_mutated_vars) = mutated_variables(&closure_body.value, cx) {
+ if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx) {
// A variable is used mutably inside of the closure. Suppress the lint.
if !map_mutated_vars.is_empty() {
return;
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
new file mode 100644
index 000000000..6b306fbf0
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
@@ -0,0 +1,36 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_diag_trait_item;
+use clippy_utils::source::snippet_with_context;
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_middle::ty;
+use rustc_span::sym;
+
+use super::SUSPICIOUS_TO_OWNED;
+
+pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) -> bool {
+ if_chain! {
+ if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if is_diag_trait_item(cx, method_def_id, sym::ToOwned);
+ let input_type = cx.typeck_results().expr_ty(expr);
+ if let ty::Adt(adt, _) = cx.typeck_results().expr_ty(expr).kind();
+ if cx.tcx.is_diagnostic_item(sym::Cow, adt.did());
+ then {
+ let mut app = Applicability::MaybeIncorrect;
+ let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), "..", &mut app).0;
+ span_lint_and_sugg(
+ cx,
+ SUSPICIOUS_TO_OWNED,
+ expr.span,
+ &format!("this `to_owned` call clones the {0} itself and does not cause the {0} contents to become owned", input_type),
+ "consider using, depending on intent",
+ format!("{0}.clone()` or `{0}.into_owned()", recv_snip),
+ app,
+ );
+ return true;
+ }
+ }
+ false
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs b/src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs
index 77d21f1d3..a1c629473 100644
--- a/src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{is_expr_diagnostic_item, ty::is_uninit_value_valid_for_ty};
+use clippy_utils::{is_path_diagnostic_item, ty::is_uninit_value_valid_for_ty};
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_lint::LateContext;
@@ -12,7 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
if_chain! {
if let hir::ExprKind::Call(callee, args) = recv.kind;
if args.is_empty();
- if is_expr_diagnostic_item(cx, callee, sym::maybe_uninit_uninit);
+ if is_path_diagnostic_item(cx, callee, sym::maybe_uninit_uninit);
if !is_uninit_value_valid_for_ty(cx, cx.typeck_results().expr_ty_adjusted(expr));
then {
span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/methods/unit_hash.rs b/src/tools/clippy/clippy_lints/src/methods/unit_hash.rs
new file mode 100644
index 000000000..3c7955bc4
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/unit_hash.rs
@@ -0,0 +1,29 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_trait_method;
+use clippy_utils::source::snippet;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::UNIT_HASH;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
+ if is_trait_method(cx, expr, sym::Hash) && cx.typeck_results().expr_ty(recv).is_unit() {
+ span_lint_and_then(
+ cx,
+ UNIT_HASH,
+ expr.span,
+ "this call to `hash` on the unit type will do nothing",
+ |diag| {
+ diag.span_suggestion(
+ expr.span,
+ "remove the call to `hash` or consider using",
+ format!("0_u8.hash({})", snippet(cx, arg.span, ".."),),
+ Applicability::MaybeIncorrect,
+ );
+ diag.note("the implementation of `Hash` for `()` is a no-op");
+ },
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index bafa6fc58..4e8c201f4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -21,14 +21,13 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {
let body = cx.tcx.hir().body(body);
let arg_id = body.params[0].pat.hir_id;
- let mutates_arg =
- mutated_variables(&body.value, cx).map_or(true, |used_mutably| used_mutably.contains(&arg_id));
- let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, &body.value);
+ let mutates_arg = mutated_variables(body.value, cx).map_or(true, |used_mutably| used_mutably.contains(&arg_id));
+ let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, body.value);
- let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, &body.value);
+ let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, body.value);
let mut return_visitor = ReturnVisitor::new(cx, arg_id);
- return_visitor.visit_expr(&body.value);
+ return_visitor.visit_expr(body.value);
found_mapping |= return_visitor.found_mapping;
found_filtering |= return_visitor.found_filtering;
@@ -36,7 +35,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
let sugg = if !found_filtering {
if name == "filter_map" { "map" } else { "map(..).next()" }
} else if !found_mapping && !mutates_arg && (!clone_or_copy_needed || is_copy(cx, in_ty)) {
- match cx.typeck_results().expr_ty(&body.value).kind() {
+ match cx.typeck_results().expr_ty(body.value).kind() {
ty::Adt(adt, subst)
if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && in_ty == subst.type_at(0) =>
{
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
index c3531d4d0..c17ef6809 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
@@ -31,7 +31,7 @@ pub(super) fn check(
// Extract the body of the closure passed to fold
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind;
let closure_body = cx.tcx.hir().body(body);
- let closure_expr = peel_blocks(&closure_body.value);
+ let closure_expr = peel_blocks(closure_body.value);
// Check if the closure body is of the form `acc <op> some_expr(x)`
if let hir::ExprKind::Binary(ref bin_op, left_expr, right_expr) = closure_expr.kind;
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 19037093e..95138c0e2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -43,7 +43,7 @@ pub fn check_for_loop_iter(
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
then {
let snippet = if_chain! {
- if let ExprKind::MethodCall(maybe_iter_method_name, [collection], _) = receiver.kind;
+ if let ExprKind::MethodCall(maybe_iter_method_name, collection, [], _) = receiver.kind;
if maybe_iter_method_name.ident.name == sym::iter;
if let Some(iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
index 1876c7fb9..a187a8d60 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
@@ -54,7 +54,7 @@ pub(super) fn check<'tcx>(
// This is a duplicate of what's happening in clippy_lints::methods::method_call,
// which isn't ideal, We want to get the method call span,
// but prefer to avoid changing the signature of the function itself.
- if let hir::ExprKind::MethodCall(_, _, span) = expr.kind {
+ if let hir::ExprKind::MethodCall(.., span) = expr.kind {
span_lint_and_then(cx, UNNECESSARY_LAZY_EVALUATIONS, expr.span, msg, |diag| {
diag.span_suggestion(
span,
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
index ea5aadbbc..ed5a75b0f 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -1,51 +1,17 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_trait_method;
use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::ty::implements_trait;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::LateContext;
use rustc_middle::ty::{self, subst::GenericArgKind};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
use rustc_span::symbol::Ident;
use std::iter;
-declare_clippy_lint! {
- /// ### What it does
- /// Detects uses of `Vec::sort_by` passing in a closure
- /// which compares the two arguments, either directly or indirectly.
- ///
- /// ### Why is this bad?
- /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if
- /// possible) than to use `Vec::sort_by` and a more complicated
- /// closure.
- ///
- /// ### Known problems
- /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already
- /// imported by a use statement, then it will need to be added manually.
- ///
- /// ### Example
- /// ```rust
- /// # struct A;
- /// # impl A { fn foo(&self) {} }
- /// # let mut vec: Vec<A> = Vec::new();
- /// vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
- /// ```
- /// Use instead:
- /// ```rust
- /// # struct A;
- /// # impl A { fn foo(&self) {} }
- /// # let mut vec: Vec<A> = Vec::new();
- /// vec.sort_by_key(|a| a.foo());
- /// ```
- #[clippy::version = "1.46.0"]
- pub UNNECESSARY_SORT_BY,
- complexity,
- "Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer"
-}
-
-declare_lint_pass!(UnnecessarySortBy => [UNNECESSARY_SORT_BY]);
+use super::UNNECESSARY_SORT_BY;
enum LintTrigger {
Sort(SortDetection),
@@ -54,7 +20,6 @@ enum LintTrigger {
struct SortDetection {
vec_name: String,
- unstable: bool,
}
struct SortByKeyDetection {
@@ -62,7 +27,6 @@ struct SortByKeyDetection {
closure_arg: String,
closure_body: String,
reverse: bool,
- unstable: bool,
}
/// Detect if the two expressions are mirrored (identical, except one
@@ -86,9 +50,13 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident
// The two exprs are method calls.
// Check to see that the function is the same and the arguments are mirrored
// This is enough because the receiver of the method is listed in the arguments
- (ExprKind::MethodCall(left_segment, left_args, _), ExprKind::MethodCall(right_segment, right_args, _)) => {
+ (
+ ExprKind::MethodCall(left_segment, left_receiver, left_args, _),
+ ExprKind::MethodCall(right_segment, right_receiver, right_args, _),
+ ) => {
left_segment.ident == right_segment.ident
&& iter::zip(*left_args, *right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident))
+ && mirrored_exprs(left_receiver, a_ident, right_receiver, b_ident)
},
// Two tuples with mirrored contents
(ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => {
@@ -150,20 +118,20 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident
}
}
-fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
+fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) -> Option<LintTrigger> {
if_chain! {
- if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind;
- if let name = name_ident.ident.name.to_ident_string();
- if name == "sort_by" || name == "sort_unstable_by";
- if let [vec, Expr { kind: ExprKind::Closure(Closure { body: closure_body_id, .. }), .. }] = args;
- if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::Vec);
- if let closure_body = cx.tcx.hir().body(*closure_body_id);
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if cx.tcx.type_of(impl_id).is_slice();
+ if let ExprKind::Closure(&Closure { body, .. }) = arg.kind;
+ if let closure_body = cx.tcx.hir().body(body);
if let &[
Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..},
Param { pat: Pat { kind: PatKind::Binding(_, _, right_ident, _), .. }, .. }
] = &closure_body.params;
- if let ExprKind::MethodCall(method_path, [ref left_expr, ref right_expr], _) = &closure_body.value.kind;
+ if let ExprKind::MethodCall(method_path, left_expr, [right_expr], _) = closure_body.value.kind;
if method_path.ident.name == sym::cmp;
+ if is_trait_method(cx, closure_body.value, sym::Ord);
then {
let (closure_body, closure_arg, reverse) = if mirrored_exprs(
left_expr,
@@ -177,19 +145,18 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
} else {
return None;
};
- let vec_name = Sugg::hir(cx, &args[0], "..").to_string();
- let unstable = name == "sort_unstable_by";
+ let vec_name = Sugg::hir(cx, recv, "..").to_string();
if_chain! {
- if let ExprKind::Path(QPath::Resolved(_, Path {
- segments: [PathSegment { ident: left_name, .. }], ..
- })) = &left_expr.kind;
- if left_name == left_ident;
- if cx.tcx.get_diagnostic_item(sym::Ord).map_or(false, |id| {
- implements_trait(cx, cx.typeck_results().expr_ty(left_expr), id, &[])
- });
+ if let ExprKind::Path(QPath::Resolved(_, Path {
+ segments: [PathSegment { ident: left_name, .. }], ..
+ })) = &left_expr.kind;
+ if left_name == left_ident;
+ if cx.tcx.get_diagnostic_item(sym::Ord).map_or(false, |id| {
+ implements_trait(cx, cx.typeck_results().expr_ty(left_expr), id, &[])
+ });
then {
- return Some(LintTrigger::Sort(SortDetection { vec_name, unstable }));
+ return Some(LintTrigger::Sort(SortDetection { vec_name }));
}
}
@@ -199,7 +166,6 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
closure_arg,
closure_body,
reverse,
- unstable,
}));
}
}
@@ -213,46 +179,50 @@ fn expr_borrows(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_)))
}
-impl LateLintPass<'_> for UnnecessarySortBy {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
- match detect_lint(cx, expr) {
- Some(LintTrigger::SortByKey(trigger)) => span_lint_and_sugg(
- cx,
- UNNECESSARY_SORT_BY,
- expr.span,
- "use Vec::sort_by_key here instead",
- "try",
- format!(
- "{}.sort{}_by_key(|{}| {})",
- trigger.vec_name,
- if trigger.unstable { "_unstable" } else { "" },
- trigger.closure_arg,
- if trigger.reverse {
- format!("std::cmp::Reverse({})", trigger.closure_body)
- } else {
- trigger.closure_body.to_string()
- },
- ),
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ recv: &'tcx Expr<'_>,
+ arg: &'tcx Expr<'_>,
+ is_unstable: bool,
+) {
+ match detect_lint(cx, expr, recv, arg) {
+ Some(LintTrigger::SortByKey(trigger)) => span_lint_and_sugg(
+ cx,
+ UNNECESSARY_SORT_BY,
+ expr.span,
+ "use Vec::sort_by_key here instead",
+ "try",
+ format!(
+ "{}.sort{}_by_key(|{}| {})",
+ trigger.vec_name,
+ if is_unstable { "_unstable" } else { "" },
+ trigger.closure_arg,
if trigger.reverse {
- Applicability::MaybeIncorrect
+ format!("std::cmp::Reverse({})", trigger.closure_body)
} else {
- Applicability::MachineApplicable
+ trigger.closure_body.to_string()
},
),
- Some(LintTrigger::Sort(trigger)) => span_lint_and_sugg(
- cx,
- UNNECESSARY_SORT_BY,
- expr.span,
- "use Vec::sort here instead",
- "try",
- format!(
- "{}.sort{}()",
- trigger.vec_name,
- if trigger.unstable { "_unstable" } else { "" },
- ),
- Applicability::MachineApplicable,
+ if trigger.reverse {
+ Applicability::MaybeIncorrect
+ } else {
+ Applicability::MachineApplicable
+ },
+ ),
+ Some(LintTrigger::Sort(trigger)) => span_lint_and_sugg(
+ cx,
+ UNNECESSARY_SORT_BY,
+ expr.span,
+ "use Vec::sort here instead",
+ "try",
+ format!(
+ "{}.sort{}()",
+ trigger.vec_name,
+ if is_unstable { "_unstable" } else { "" },
),
- None => {},
- }
+ Applicability::MachineApplicable,
+ ),
+ None => {},
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index b3276f139..763bfafec 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -1,22 +1,25 @@
use super::implicit_clone::is_clone_like;
use super::unnecessary_iter_cloned::{self, is_into_iter};
+use crate::rustc_middle::ty::Subst;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{
- contains_ty, get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs,
-};
+use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
+use clippy_utils::visitors::find_all_ret_expressions;
+use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
use clippy_utils::{meets_msrv, msrvs};
-
-use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item};
use rustc_errors::Applicability;
-use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind};
+use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
+use rustc_middle::ty::EarlyBinder;
+use rustc_middle::ty::{self, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
use rustc_semver::RustcVersion;
use rustc_span::{sym, Symbol};
+use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
+use rustc_typeck::check::{FnCtxt, Inherited};
use std::cmp::max;
use super::UNNECESSARY_TO_OWNED;
@@ -25,16 +28,17 @@ pub fn check<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'tcx>,
method_name: Symbol,
- args: &'tcx [Expr<'tcx>],
+ receiver: &'tcx Expr<'_>,
+ args: &'tcx [Expr<'_>],
msrv: Option<RustcVersion>,
) {
if_chain! {
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
- if let [receiver] = args;
+ if args.is_empty();
then {
if is_cloned_or_copied(cx, method_name, method_def_id) {
unnecessary_iter_cloned::check(cx, expr, method_name, receiver);
- } else if is_to_owned_like(cx, method_name, method_def_id) {
+ } else if is_to_owned_like(cx, expr, method_name, method_def_id) {
// At this point, we know the call is of a `to_owned`-like function. The functions
// `check_addr_of_expr` and `check_call_arg` determine whether the call is unnecessary
// based on its context, that is, whether it is a referent in an `AddrOf` expression, an
@@ -246,12 +250,12 @@ fn check_other_call_arg<'tcx>(
) -> bool {
if_chain! {
if let Some((maybe_call, maybe_arg)) = skip_addr_of_ancestors(cx, expr);
- if let Some((callee_def_id, call_substs, call_args)) = get_callee_substs_and_args(cx, maybe_call);
+ if let Some((callee_def_id, _, recv, call_args)) = get_callee_substs_and_args(cx, maybe_call);
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
- if let Some(i) = call_args.iter().position(|arg| arg.hir_id == maybe_arg.hir_id);
+ if let Some(i) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == maybe_arg.hir_id);
if let Some(input) = fn_sig.inputs().get(i);
let (input, n_refs) = peel_mid_ty_refs(*input);
- if let (trait_predicates, projection_predicates) = get_input_traits_and_projections(cx, callee_def_id, input);
+ if let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input);
if let Some(sized_def_id) = cx.tcx.lang_items().sized_trait();
if let [trait_predicate] = trait_predicates
.iter()
@@ -259,40 +263,13 @@ fn check_other_call_arg<'tcx>(
.collect::<Vec<_>>()[..];
if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref);
if let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef);
+ if trait_predicate.def_id() == deref_trait_id || trait_predicate.def_id() == as_ref_trait_id;
let receiver_ty = cx.typeck_results().expr_ty(receiver);
- // If the callee has type parameters, they could appear in `projection_predicate.ty` or the
- // types of `trait_predicate.trait_ref.substs`.
- if if trait_predicate.def_id() == deref_trait_id {
- if let [projection_predicate] = projection_predicates[..] {
- let normalized_ty =
- cx.tcx
- .subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.term);
- implements_trait(cx, receiver_ty, deref_trait_id, &[])
- && get_associated_type(cx, receiver_ty, deref_trait_id, "Target")
- .map_or(false, |ty| ty::Term::Ty(ty) == normalized_ty)
- } else {
- false
- }
- } else if trait_predicate.def_id() == as_ref_trait_id {
- let composed_substs = compose_substs(
- cx,
- &trait_predicate.trait_ref.substs.iter().skip(1).collect::<Vec<_>>()[..],
- call_substs,
- );
- implements_trait(cx, receiver_ty, as_ref_trait_id, &composed_substs)
- } else {
- false
- };
+ if can_change_type(cx, maybe_arg, receiver_ty);
// We can't add an `&` when the trait is `Deref` because `Target = &T` won't match
// `Target = T`.
if n_refs > 0 || is_copy(cx, receiver_ty) || trait_predicate.def_id() != deref_trait_id;
let n_refs = max(n_refs, if is_copy(cx, receiver_ty) { 0 } else { 1 });
- // If the trait is `AsRef` and the input type variable `T` occurs in the output type, then
- // `T` must not be instantiated with a reference
- // (https://github.com/rust-lang/rust-clippy/issues/8507).
- if (n_refs == 0 && !receiver_ty.is_ref())
- || trait_predicate.def_id() != as_ref_trait_id
- || !contains_ty(fn_sig.output(), input);
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
then {
span_lint_and_sugg(
@@ -331,22 +308,22 @@ fn skip_addr_of_ancestors<'tcx>(
fn get_callee_substs_and_args<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'tcx>,
-) -> Option<(DefId, SubstsRef<'tcx>, &'tcx [Expr<'tcx>])> {
+) -> Option<(DefId, SubstsRef<'tcx>, Option<&'tcx Expr<'tcx>>, &'tcx [Expr<'tcx>])> {
if_chain! {
if let ExprKind::Call(callee, args) = expr.kind;
let callee_ty = cx.typeck_results().expr_ty(callee);
if let ty::FnDef(callee_def_id, _) = callee_ty.kind();
then {
let substs = cx.typeck_results().node_substs(callee.hir_id);
- return Some((*callee_def_id, substs, args));
+ return Some((*callee_def_id, substs, None, args));
}
}
if_chain! {
- if let ExprKind::MethodCall(_, args, _) = expr.kind;
+ if let ExprKind::MethodCall(_, recv, args, _) = expr.kind;
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
then {
let substs = cx.typeck_results().node_substs(expr.hir_id);
- return Some((method_def_id, substs, args));
+ return Some((method_def_id, substs, Some(recv), args));
}
}
None
@@ -360,25 +337,15 @@ fn get_input_traits_and_projections<'tcx>(
) -> (Vec<TraitPredicate<'tcx>>, Vec<ProjectionPredicate<'tcx>>) {
let mut trait_predicates = Vec::new();
let mut projection_predicates = Vec::new();
- for (predicate, _) in cx.tcx.predicates_of(callee_def_id).predicates.iter() {
- // `substs` should have 1 + n elements. The first is the type on the left hand side of an
- // `as`. The remaining n are trait parameters.
- let is_input_substs = |substs: SubstsRef<'tcx>| {
- if_chain! {
- if let Some(arg) = substs.iter().next();
- if let GenericArgKind::Type(arg_ty) = arg.unpack();
- if arg_ty == input;
- then { true } else { false }
- }
- };
+ for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() {
match predicate.kind().skip_binder() {
PredicateKind::Trait(trait_predicate) => {
- if is_input_substs(trait_predicate.trait_ref.substs) {
+ if trait_predicate.trait_ref.self_ty() == input {
trait_predicates.push(trait_predicate);
}
},
PredicateKind::Projection(projection_predicate) => {
- if is_input_substs(projection_predicate.projection_ty.substs) {
+ if projection_predicate.projection_ty.self_ty() == input {
projection_predicates.push(projection_predicate);
}
},
@@ -388,22 +355,103 @@ fn get_input_traits_and_projections<'tcx>(
(trait_predicates, projection_predicates)
}
-/// Composes two substitutions by applying the latter to the types of the former.
-fn compose_substs<'tcx>(
- cx: &LateContext<'tcx>,
- left: &[GenericArg<'tcx>],
- right: SubstsRef<'tcx>,
-) -> Vec<GenericArg<'tcx>> {
- left.iter()
- .map(|arg| {
- if let GenericArgKind::Type(arg_ty) = arg.unpack() {
- let normalized_ty = cx.tcx.subst_and_normalize_erasing_regions(right, cx.param_env, arg_ty);
- GenericArg::from(normalized_ty)
- } else {
- *arg
+fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<'a>) -> bool {
+ for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) {
+ match node {
+ Node::Stmt(_) => return true,
+ Node::Block(..) => continue,
+ Node::Item(item) => {
+ if let ItemKind::Fn(_, _, body_id) = &item.kind
+ && let output_ty = return_ty(cx, item.hir_id())
+ && let local_def_id = cx.tcx.hir().local_def_id(item.hir_id())
+ && Inherited::build(cx.tcx, local_def_id).enter(|inherited| {
+ let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.hir_id());
+ fn_ctxt.can_coerce(ty, output_ty)
+ }) {
+ if has_lifetime(output_ty) && has_lifetime(ty) {
+ return false;
+ }
+ let body = cx.tcx.hir().body(*body_id);
+ let body_expr = &body.value;
+ let mut count = 0;
+ return find_all_ret_expressions(cx, body_expr, |_| { count += 1; count <= 1 });
+ }
}
- })
- .collect()
+ Node::Expr(parent_expr) => {
+ if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
+ {
+ let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
+ if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
+ && let Some(param_ty) = fn_sig.inputs().get(arg_index)
+ && let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind()
+ {
+ if fn_sig
+ .inputs()
+ .iter()
+ .enumerate()
+ .filter(|(i, _)| *i != arg_index)
+ .any(|(_, ty)| ty.contains(*param_ty))
+ {
+ return false;
+ }
+
+ let mut trait_predicates = cx.tcx.param_env(callee_def_id)
+ .caller_bounds().iter().filter(|predicate| {
+ if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ && trait_predicate.trait_ref.self_ty() == *param_ty {
+ true
+ } else {
+ false
+ }
+ });
+
+ let new_subst = cx.tcx.mk_substs(
+ call_substs.iter()
+ .enumerate()
+ .map(|(i, t)|
+ if i == (*param_index as usize) {
+ GenericArg::from(ty)
+ } else {
+ t
+ }));
+
+ if trait_predicates.any(|predicate| {
+ let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
+ let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
+ !cx.tcx
+ .infer_ctxt()
+ .enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
+ }) {
+ return false;
+ }
+
+ let output_ty = fn_sig.output();
+ if output_ty.contains(*param_ty) {
+ if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions(
+ new_subst, cx.param_env, output_ty) {
+ expr = parent_expr;
+ ty = new_ty;
+ continue;
+ }
+ return false;
+ }
+
+ return true;
+ }
+ } else if let ExprKind::Block(..) = parent_expr.kind {
+ continue;
+ }
+ return false;
+ },
+ _ => return false,
+ }
+ }
+
+ false
+}
+
+fn has_lifetime(ty: Ty<'_>) -> bool {
+ ty.walk().any(|t| matches!(t.unpack(), GenericArgKind::Lifetime(_)))
}
/// Returns true if the named method is `Iterator::cloned` or `Iterator::copied`.
@@ -414,10 +462,10 @@ fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id:
/// Returns true if the named method can be used to convert the receiver to its "owned"
/// representation.
-fn is_to_owned_like(cx: &LateContext<'_>, method_name: Symbol, method_def_id: DefId) -> bool {
+fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name: Symbol, method_def_id: DefId) -> bool {
is_clone_like(cx, method_name.as_str(), method_def_id)
|| is_cow_into_owned(cx, method_name, method_def_id)
- || is_to_string(cx, method_name, method_def_id)
+ || is_to_string_on_string_like(cx, call_expr, method_name, method_def_id)
}
/// Returns true if the named method is `Cow::into_owned`.
@@ -425,7 +473,27 @@ fn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_def_id: D
method_name.as_str() == "into_owned" && is_diag_item_method(cx, method_def_id, sym::Cow)
}
-/// Returns true if the named method is `ToString::to_string`.
-fn is_to_string(cx: &LateContext<'_>, method_name: Symbol, method_def_id: DefId) -> bool {
- method_name == sym::to_string && is_diag_trait_item(cx, method_def_id, sym::ToString)
+/// Returns true if the named method is `ToString::to_string` and it's called on a type that
+/// is string-like i.e. implements `AsRef<str>` or `Deref<str>`.
+fn is_to_string_on_string_like<'a>(
+ cx: &LateContext<'_>,
+ call_expr: &'a Expr<'a>,
+ method_name: Symbol,
+ method_def_id: DefId,
+) -> bool {
+ if method_name != sym::to_string || !is_diag_trait_item(cx, method_def_id, sym::ToString) {
+ return false;
+ }
+
+ if let Some(substs) = cx.typeck_results().node_substs_opt(call_expr.hir_id)
+ && let [generic_arg] = substs.as_slice()
+ && let GenericArgKind::Type(ty) = generic_arg.unpack()
+ && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
+ && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
+ && (implements_trait(cx, ty, deref_trait_id, &[cx.tcx.types.str_.into()]) ||
+ implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) {
+ true
+ } else {
+ false
+ }
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unwrap_or_else_default.rs b/src/tools/clippy/clippy_lints/src/methods/unwrap_or_else_default.rs
index f3af281d6..045f739e6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unwrap_or_else_default.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unwrap_or_else_default.rs
@@ -5,10 +5,11 @@ use clippy_utils::{
diagnostics::span_lint_and_sugg, is_default_equivalent_call, source::snippet_with_applicability,
ty::is_type_diagnostic_item,
};
+use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_span::sym;
+use rustc_span::{sym, symbol};
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
@@ -25,7 +26,7 @@ pub(super) fn check<'tcx>(
if_chain! {
if is_option || is_result;
- if is_default_equivalent_call(cx, u_arg);
+ if closure_body_returns_empty_to_string(cx, u_arg) || is_default_equivalent_call(cx, u_arg);
then {
let mut applicability = Applicability::MachineApplicable;
@@ -44,3 +45,22 @@ pub(super) fn check<'tcx>(
}
}
}
+
+fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {
+ if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind {
+ let body = cx.tcx.hir().body(body);
+
+ if body.params.is_empty()
+ && let hir::Expr{ kind, .. } = &body.value
+ && let hir::ExprKind::MethodCall(hir::PathSegment {ident, ..}, self_arg, _, _) = kind
+ && ident == &symbol::Ident::from_str("to_string")
+ && let hir::Expr{ kind, .. } = self_arg
+ && let hir::ExprKind::Lit(lit) = kind
+ && let LitKind::Str(symbol::kw::Empty, _) = lit.node
+ {
+ return true;
+ }
+ }
+
+ false
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs b/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs
index 5c7610149..ee17f2d78 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs
@@ -1,40 +1,53 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_in_test_function;
use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{is_in_test_function, is_lint_allowed};
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;
-use super::UNWRAP_USED;
+use super::{EXPECT_USED, UNWRAP_USED};
-/// lint use of `unwrap()` for `Option`s and `Result`s
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, allow_unwrap_in_tests: bool) {
+/// lint use of `unwrap()` or `unwrap_err` for `Result` and `unwrap()` for `Option`.
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ expr: &hir::Expr<'_>,
+ recv: &hir::Expr<'_>,
+ is_err: bool,
+ allow_unwrap_in_tests: bool,
+) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
- let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
- Some((UNWRAP_USED, "an Option", "None"))
+ let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
+ Some((UNWRAP_USED, "an Option", "None", ""))
} else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
- Some((UNWRAP_USED, "a Result", "Err"))
+ Some((UNWRAP_USED, "a Result", if is_err { "Ok" } else { "Err" }, "an "))
} else {
None
};
+ let method_suffix = if is_err { "_err" } else { "" };
+
if allow_unwrap_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
return;
}
- if let Some((lint, kind, none_value)) = mess {
+ if let Some((lint, kind, none_value, none_prefix)) = mess {
+ let help = if is_lint_allowed(cx, EXPECT_USED, expr.hir_id) {
+ format!(
+ "if you don't want to handle the `{none_value}` case gracefully, consider \
+ using `expect{method_suffix}()` to provide a better panic message"
+ )
+ } else {
+ format!("if this value is {none_prefix}`{none_value}`, it will panic")
+ };
+
span_lint_and_help(
cx,
lint,
expr.span,
- &format!("used `unwrap()` on `{}` value", kind,),
+ &format!("used `unwrap{method_suffix}()` on `{kind}` value"),
None,
- &format!(
- "if you don't want to handle the `{}` case gracefully, consider \
- using `expect()` to provide a better panic message",
- none_value,
- ),
+ &help,
);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index 3015531e8..ae6b165fd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -28,7 +28,7 @@ pub(super) fn derefs_to_slice<'tcx>(
}
}
- if let hir::ExprKind::MethodCall(path, [self_arg, ..], _) = &expr.kind {
+ if let hir::ExprKind::MethodCall(path, self_arg, ..) = &expr.kind {
if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(self_arg)) {
Some(self_arg)
} else {
@@ -139,9 +139,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> {
self.addr_of_exprs.push(parent);
return;
},
- ExprKind::MethodCall(_, args, _) => {
+ ExprKind::MethodCall(.., args, _) => {
if_chain! {
- if args.iter().skip(1).all(|arg| !self.is_binding(arg));
+ if args.iter().all(|arg| !self.is_binding(arg));
if let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id);
let method_ty = self.cx.tcx.type_of(method_def_id);
let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder();
diff --git a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs
new file mode 100644
index 000000000..02d8364cb
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs
@@ -0,0 +1,45 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::ty::is_type_diagnostic_item;
+use if_chain::if_chain;
+use rustc_ast::LitKind;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::source_map::Spanned;
+use rustc_span::{sym, Span};
+
+use super::VEC_RESIZE_TO_ZERO;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ count_arg: &'tcx Expr<'_>,
+ default_arg: &'tcx Expr<'_>,
+ name_span: Span,
+) {
+ if_chain! {
+ if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
+ if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
+ if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Vec);
+ if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = count_arg.kind;
+ if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = default_arg.kind;
+ then {
+ let method_call_span = expr.span.with_lo(name_span.lo());
+ span_lint_and_then(
+ cx,
+ VEC_RESIZE_TO_ZERO,
+ expr.span,
+ "emptying a vector with `resize`",
+ |db| {
+ db.help("the arguments may be inverted...");
+ db.span_suggestion(
+ method_call_span,
+ "...or you can empty the vector with",
+ "clear()".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ },
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs b/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs
new file mode 100644
index 000000000..2fe5ae9a9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs
@@ -0,0 +1,28 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::is_trait_method;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_hir::{Expr, ExprKind, QPath};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::VERBOSE_FILE_READS;
+
+pub(super) const READ_TO_END_MSG: (&str, &str) = ("use of `File::read_to_end`", "consider using `fs::read` instead");
+pub(super) const READ_TO_STRING_MSG: (&str, &str) = (
+ "use of `File::read_to_string`",
+ "consider using `fs::read_to_string` instead",
+);
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ recv: &'tcx Expr<'_>,
+ (msg, help): (&str, &str),
+) {
+ if is_trait_method(cx, expr, sym::IoRead)
+ && matches!(recv.kind, ExprKind::Path(QPath::Resolved(None, _)))
+ && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(recv).peel_refs(), sym::File)
+ {
+ span_lint_and_help(cx, VERBOSE_FILE_READS, expr.span, msg, None, help);
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/minmax.rs b/src/tools/clippy/clippy_lints/src/minmax.rs
index a081cde85..4d8579135 100644
--- a/src/tools/clippy/clippy_lints/src/minmax.rs
+++ b/src/tools/clippy/clippy_lints/src/minmax.rs
@@ -1,7 +1,6 @@
use clippy_utils::consts::{constant_simple, Constant};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::{match_trait_method, paths};
-use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -75,45 +74,49 @@ fn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Cons
.qpath_res(qpath, path.hir_id)
.opt_def_id()
.and_then(|def_id| match cx.tcx.get_diagnostic_name(def_id) {
- Some(sym::cmp_min) => fetch_const(cx, args, MinMax::Min),
- Some(sym::cmp_max) => fetch_const(cx, args, MinMax::Max),
+ Some(sym::cmp_min) => fetch_const(cx, None, args, MinMax::Min),
+ Some(sym::cmp_max) => fetch_const(cx, None, args, MinMax::Max),
_ => None,
})
} else {
None
}
},
- ExprKind::MethodCall(path, args, _) => {
- if_chain! {
- if let [obj, _] = args;
- if cx.typeck_results().expr_ty(obj).is_floating_point() || match_trait_method(cx, expr, &paths::ORD);
- then {
- if path.ident.name == sym!(max) {
- fetch_const(cx, args, MinMax::Max)
- } else if path.ident.name == sym!(min) {
- fetch_const(cx, args, MinMax::Min)
- } else {
- None
- }
+ ExprKind::MethodCall(path, receiver, args @ [_], _) => {
+ if cx.typeck_results().expr_ty(receiver).is_floating_point() || match_trait_method(cx, expr, &paths::ORD) {
+ if path.ident.name == sym!(max) {
+ fetch_const(cx, Some(receiver), args, MinMax::Max)
+ } else if path.ident.name == sym!(min) {
+ fetch_const(cx, Some(receiver), args, MinMax::Min)
} else {
None
}
+ } else {
+ None
}
},
_ => None,
}
}
-fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Option<(MinMax, Constant, &'a Expr<'a>)> {
- if args.len() != 2 {
+fn fetch_const<'a>(
+ cx: &LateContext<'_>,
+ receiver: Option<&'a Expr<'a>>,
+ args: &'a [Expr<'a>],
+ m: MinMax,
+) -> Option<(MinMax, Constant, &'a Expr<'a>)> {
+ let mut args = receiver.into_iter().chain(args);
+ let first_arg = args.next()?;
+ let second_arg = args.next()?;
+ if args.next().is_some() {
return None;
}
- constant_simple(cx, cx.typeck_results(), &args[0]).map_or_else(
- || constant_simple(cx, cx.typeck_results(), &args[1]).map(|c| (m, c, &args[0])),
+ constant_simple(cx, cx.typeck_results(), first_arg).map_or_else(
+ || constant_simple(cx, cx.typeck_results(), second_arg).map(|c| (m, c, first_arg)),
|c| {
- if constant_simple(cx, cx.typeck_results(), &args[1]).is_none() {
+ if constant_simple(cx, cx.typeck_results(), second_arg).is_none() {
// otherwise ignore
- Some((m, c, &args[1]))
+ Some((m, c, second_arg))
} else {
None
}
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 8224e80c9..ea245edd7 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -5,8 +5,8 @@ use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
- self as hir, def, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind, Stmt,
- StmtKind, TyKind,
+ self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind,
+ Stmt, StmtKind, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
@@ -146,7 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
return;
}
for arg in iter_input_pats(decl, body) {
- if let PatKind::Binding(BindingAnnotation::Ref | BindingAnnotation::RefMut, ..) = arg.pat.kind {
+ if let PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..) = arg.pat.kind {
span_lint(
cx,
TOPLEVEL_REF_ARG,
@@ -162,9 +162,8 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
if_chain! {
if !in_external_macro(cx.tcx.sess, stmt.span);
if let StmtKind::Local(local) = stmt.kind;
- if let PatKind::Binding(an, .., name, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., name, None) = local.pat.kind;
if let Some(init) = local.init;
- if an == BindingAnnotation::Ref || an == BindingAnnotation::RefMut;
then {
// use the macro callsite when the init span (but not the whole local span)
// comes from an expansion like `vec![1, 2, 3]` in `let ref _ = vec![1, 2, 3];`
@@ -173,7 +172,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
} else {
Sugg::hir(cx, init, "..")
};
- let (mutopt, initref) = if an == BindingAnnotation::RefMut {
+ let (mutopt, initref) = if mutabl == Mutability::Mut {
("mut ", sugg_init.mut_addr())
} else {
("", sugg_init.addr())
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs
index 525dbf775..d7bb0616a 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs
@@ -1,18 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::{BindingMode, Mutability, Pat, PatKind};
+use rustc_ast::ast::{Pat, PatKind};
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
use super::REDUNDANT_PATTERN;
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
- if let PatKind::Ident(left, ident, Some(ref right)) = pat.kind {
- let left_binding = match left {
- BindingMode::ByRef(Mutability::Mut) => "ref mut ",
- BindingMode::ByRef(Mutability::Not) => "ref ",
- BindingMode::ByValue(..) => "",
- };
-
+ if let PatKind::Ident(ann, ident, Some(ref right)) = pat.kind {
if let PatKind::Wild = right.kind {
span_lint_and_sugg(
cx,
@@ -23,7 +17,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
ident.name, ident.name,
),
"try",
- format!("{}{}", left_binding, ident.name),
+ format!("{}{}", ann.prefix_str(), ident.name),
Applicability::MachineApplicable,
);
}
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
index df044538f..7c4ae746e 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
@@ -46,7 +46,7 @@ fn span_lint(cx: &EarlyContext<'_>, span: Span, only_one: bool) {
"these patterns are unneeded as the `..` pattern can match those elements"
},
if only_one { "remove it" } else { "remove them" },
- "".to_string(),
+ String::new(),
Applicability::MachineApplicable,
);
}
diff --git a/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs b/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
index f763e0d24..020efeaeb 100644
--- a/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
+++ b/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
@@ -40,7 +40,7 @@ declare_clippy_lint! {
/// }
/// impl<A, B> Foo<A, B> {}
/// ```
- #[clippy::version = "1.62.0"]
+ #[clippy::version = "1.63.0"]
pub MISMATCHING_TYPE_PARAM_ORDER,
pedantic,
"type parameter positioned inconsistently between type def and impl block"
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 16d65966c..bc304c081 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -1,7 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::qualify_min_const_fn::is_min_const_fn;
use clippy_utils::ty::has_drop;
-use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, meets_msrv, msrvs, trait_ref_of_method};
+use clippy_utils::{
+ fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, meets_msrv, msrvs, trait_ref_of_method,
+};
use rustc_hir as hir;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::intravisit::FnKind;
@@ -86,10 +88,10 @@ impl MissingConstForFn {
impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
fn check_fn(
&mut self,
- cx: &LateContext<'_>,
- kind: FnKind<'_>,
+ cx: &LateContext<'tcx>,
+ kind: FnKind<'tcx>,
_: &FnDecl<'_>,
- _: &Body<'_>,
+ body: &Body<'tcx>,
span: Span,
hir_id: HirId,
) {
@@ -124,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
FnKind::Method(_, sig, ..) => {
if trait_ref_of_method(cx, def_id).is_some()
|| already_const(sig.header)
- || method_accepts_dropable(cx, sig.decl.inputs)
+ || method_accepts_droppable(cx, sig.decl.inputs)
{
return;
}
@@ -144,6 +146,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
}
}
+ if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) {
+ return;
+ }
+
let mir = cx.tcx.optimized_mir(def_id);
if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv) {
@@ -159,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
/// Returns true if any of the method parameters is a type that implements `Drop`. The method
/// can't be made const then, because `drop` can't be const-evaluated.
-fn method_accepts_dropable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
+fn method_accepts_droppable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
// If any of the params are droppable, return true
param_tys.iter().any(|hir_ty| {
let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty);
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 88ba00292..3701fdb4a 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -7,7 +7,8 @@
use clippy_utils::attrs::is_doc_hidden;
use clippy_utils::diagnostics::span_lint;
-use rustc_ast::ast;
+use clippy_utils::is_from_proc_macro;
+use rustc_ast::ast::{self, MetaItem, MetaItemKind};
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::DefIdTree;
@@ -57,6 +58,20 @@ impl MissingDoc {
*self.doc_hidden_stack.last().expect("empty doc_hidden_stack")
}
+ fn has_include(meta: Option<MetaItem>) -> bool {
+ if_chain! {
+ if let Some(meta) = meta;
+ if let MetaItemKind::List(list) = meta.kind;
+ if let Some(meta) = list.get(0);
+ if let Some(name) = meta.ident();
+ then {
+ name.name == sym::include
+ } else {
+ false
+ }
+ }
+ }
+
fn check_missing_docs_attrs(
&self,
cx: &LateContext<'_>,
@@ -80,7 +95,9 @@ impl MissingDoc {
return;
}
- let has_doc = attrs.iter().any(|a| a.doc_str().is_some());
+ let has_doc = attrs
+ .iter()
+ .any(|a| a.doc_str().is_some() || Self::has_include(a.meta()));
if !has_doc {
span_lint(
cx,
@@ -141,14 +158,18 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
let attrs = cx.tcx.hir().attrs(it.hir_id());
- self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
+ if !is_from_proc_macro(cx, it) {
+ self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
+ }
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
- self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
+ if !is_from_proc_macro(cx, trait_item) {
+ self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
+ }
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
@@ -163,18 +184,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
- self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
+ if !is_from_proc_macro(cx, impl_item) {
+ self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
+ }
}
fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) {
if !sf.is_positional() {
let attrs = cx.tcx.hir().attrs(sf.hir_id);
- self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
+ if !is_from_proc_macro(cx, sf) {
+ self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
+ }
}
}
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
let attrs = cx.tcx.hir().attrs(v.id);
- self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
+ if !is_from_proc_macro(cx, v) {
+ self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/multi_assignments.rs b/src/tools/clippy/clippy_lints/src/multi_assignments.rs
new file mode 100644
index 000000000..81eb1a085
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/multi_assignments.rs
@@ -0,0 +1,65 @@
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::ast::{Expr, ExprKind, Stmt, StmtKind};
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for nested assignments.
+ ///
+ /// ### Why is this bad?
+ /// While this is in most cases already a type mismatch,
+ /// the result of an assignment being `()` can throw off people coming from languages like python or C,
+ /// where such assignments return a copy of the assigned value.
+ ///
+ /// ### Example
+ /// ```rust
+ ///# let (a, b);
+ /// a = b = 42;
+ /// ```
+ /// Use instead:
+ /// ```rust
+ ///# let (a, b);
+ /// b = 42;
+ /// a = b;
+ /// ```
+ #[clippy::version = "1.65.0"]
+ pub MULTI_ASSIGNMENTS,
+ suspicious,
+ "instead of using `a = b = c;` use `a = c; b = c;`"
+}
+
+declare_lint_pass!(MultiAssignments => [MULTI_ASSIGNMENTS]);
+
+fn strip_paren_blocks(expr: &Expr) -> &Expr {
+ match &expr.kind {
+ ExprKind::Paren(e) => strip_paren_blocks(e),
+ ExprKind::Block(b, _) => {
+ if let [
+ Stmt {
+ kind: StmtKind::Expr(e),
+ ..
+ },
+ ] = &b.stmts[..]
+ {
+ strip_paren_blocks(e)
+ } else {
+ expr
+ }
+ },
+ _ => expr,
+ }
+}
+
+impl EarlyLintPass for MultiAssignments {
+ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+ if let ExprKind::Assign(target, source, _) = &expr.kind {
+ if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(target).kind {
+ span_lint(cx, MULTI_ASSIGNMENTS, expr.span, "assignments don't nest intuitively");
+ };
+ if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(source).kind {
+ span_lint(cx, MULTI_ASSIGNMENTS, expr.span, "assignments don't nest intuitively");
+ }
+ };
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs
deleted file mode 100644
index b7f981faa..000000000
--- a/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Mutability};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for `&mut Mutex::lock` calls
- ///
- /// ### Why is this bad?
- /// `Mutex::lock` is less efficient than
- /// calling `Mutex::get_mut`. In addition you also have a statically
- /// guarantee that the mutex isn't locked, instead of just a runtime
- /// guarantee.
- ///
- /// ### Example
- /// ```rust
- /// use std::sync::{Arc, Mutex};
- ///
- /// let mut value_rc = Arc::new(Mutex::new(42_u8));
- /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
- ///
- /// let mut value = value_mutex.lock().unwrap();
- /// *value += 1;
- /// ```
- /// Use instead:
- /// ```rust
- /// use std::sync::{Arc, Mutex};
- ///
- /// let mut value_rc = Arc::new(Mutex::new(42_u8));
- /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
- ///
- /// let value = value_mutex.get_mut().unwrap();
- /// *value += 1;
- /// ```
- #[clippy::version = "1.49.0"]
- pub MUT_MUTEX_LOCK,
- style,
- "`&mut Mutex::lock` does unnecessary locking"
-}
-
-declare_lint_pass!(MutMutexLock => [MUT_MUTEX_LOCK]);
-
-impl<'tcx> LateLintPass<'tcx> for MutMutexLock {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>) {
- if_chain! {
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &ex.kind;
- if path.ident.name == sym!(lock);
- let ty = cx.typeck_results().expr_ty(self_arg);
- if let ty::Ref(_, inner_ty, Mutability::Mut) = ty.kind();
- if is_type_diagnostic_item(cx, *inner_ty, sym::Mutex);
- then {
- span_lint_and_sugg(
- cx,
- MUT_MUTEX_LOCK,
- path.ident.span,
- "calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference",
- "change this to",
- "get_mut".to_owned(),
- Applicability::MaybeIncorrect,
- );
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs
index f434a655f..82dc03ef5 100644
--- a/src/tools/clippy/clippy_lints/src/mut_reference.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs
@@ -43,18 +43,24 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
if let ExprKind::Path(ref path) = fn_expr.kind {
check_arguments(
cx,
- arguments,
+ arguments.iter().collect(),
cx.typeck_results().expr_ty(fn_expr),
&rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false)),
"function",
);
}
},
- ExprKind::MethodCall(path, arguments, _) => {
+ ExprKind::MethodCall(path, receiver, arguments, _) => {
let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap();
let substs = cx.typeck_results().node_substs(e.hir_id);
let method_type = cx.tcx.bound_type_of(def_id).subst(cx.tcx, substs);
- check_arguments(cx, arguments, method_type, path.ident.as_str(), "method");
+ check_arguments(
+ cx,
+ std::iter::once(receiver).chain(arguments.iter()).collect(),
+ method_type,
+ path.ident.as_str(),
+ "method",
+ );
},
_ => (),
}
@@ -63,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
fn check_arguments<'tcx>(
cx: &LateContext<'tcx>,
- arguments: &[Expr<'_>],
+ arguments: Vec<&Expr<'_>>,
type_definition: Ty<'tcx>,
name: &str,
fn_kind: &str,
diff --git a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs
index 9838d3cad..f2ffac85b 100644
--- a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use if_chain::if_chain;
-use rustc_ast::ast::{BindingMode, Lifetime, Mutability, Param, PatKind, Path, TyKind};
+use rustc_ast::ast::{BindingAnnotation, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -120,14 +120,14 @@ impl EarlyLintPass for NeedlessArbitrarySelfType {
match &p.ty.kind {
TyKind::Path(None, path) => {
- if let PatKind::Ident(BindingMode::ByValue(mutbl), _, _) = p.pat.kind {
+ if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), _, _) = p.pat.kind {
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl);
}
},
TyKind::Rptr(lifetime, mut_ty) => {
if_chain! {
if let TyKind::Path(None, path) = &mut_ty.ty.kind;
- if let PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, _) = p.pat.kind;
+ if let PatKind::Ident(BindingAnnotation::NONE, _, _) = p.pat.kind;
then {
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl);
}
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
index 05c012b92..b8855e5ad 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
@@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
if let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind;
// Check sub_pat got a `ref` keyword (excluding `ref mut`).
- if let PatKind::Binding(BindingAnnotation::Ref, .., spanned_name, _) = sub_pat.kind;
+ if let PatKind::Binding(BindingAnnotation::REF, .., spanned_name, _) = sub_pat.kind;
let parent_id = cx.tcx.hir().get_parent_node(pat.hir_id);
if let Some(parent_node) = cx.tcx.hir().find(parent_id);
then {
diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
index 10e188ecb..3233d87c0 100644
--- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
@@ -56,12 +56,12 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
if_chain! {
// Check the method name is `for_each`.
- if let ExprKind::MethodCall(method_name, [for_each_recv, for_each_arg], _) = expr.kind;
+ if let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind;
if method_name.ident.name == Symbol::intern("for_each");
// Check `for_each` is an associated function of `Iterator`.
if is_trait_method(cx, expr, sym::Iterator);
// Checks the receiver of `for_each` is also a method call.
- if let ExprKind::MethodCall(_, [iter_recv], _) = for_each_recv.kind;
+ if let ExprKind::MethodCall(_, iter_recv, [], _) = for_each_recv.kind;
// Skip the lint if the call chain is too long. e.g. `v.field.iter().for_each()` or
// `v.foo().iter().for_each()` must be skipped.
if matches!(
@@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
if let ExprKind::Block(..) = body.value.kind;
then {
let mut ret_collector = RetCollector::default();
- ret_collector.visit_expr(&body.value);
+ ret_collector.visit_expr(body.value);
// Skip the lint if `return` is used in `Loop` in order not to suggest using `'label`.
if ret_collector.ret_in_loop {
diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
index ff2999b1f..de99f1d70 100644
--- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
@@ -373,7 +373,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
if let Local {
init: None,
pat: &Pat {
- kind: PatKind::Binding(BindingAnnotation::Unannotated, binding_id, _, None),
+ kind: PatKind::Binding(BindingAnnotation::NONE, binding_id, _, None),
..
},
source: LocalSource::Normal,
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 0cbef1c95..060037ed4 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -8,7 +8,9 @@ use rustc_ast::ast::Attribute;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::intravisit::FnKind;
-use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Node, PatKind, QPath, TyKind};
+use rustc_hir::{
+ BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
+};
use rustc_hir::{HirIdMap, HirIdSet};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
@@ -171,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
(
preds.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())),
!preds.is_empty() && {
- let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty);
+ let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_erased, ty);
preds.iter().all(|t| {
let ty_params = t.trait_ref.substs.iter().skip(1).collect::<Vec<_>>();
implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)
@@ -188,13 +190,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
if !implements_borrow_trait;
if !all_borrowable_trait;
- if let PatKind::Binding(mode, canonical_id, ..) = arg.pat.kind;
+ if let PatKind::Binding(BindingAnnotation(_, Mutability::Not), canonical_id, ..) = arg.pat.kind;
if !moved_vars.contains(&canonical_id);
then {
- if mode == BindingAnnotation::Mutable || mode == BindingAnnotation::RefMut {
- continue;
- }
-
// Dereference suggestion
let sugg = |diag: &mut Diagnostic| {
if let ty::Adt(def, ..) = ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
index ed022b9d5..25fb4f0f4 100644
--- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
+++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
@@ -43,7 +43,7 @@ declare_lint_pass!(NonOctalUnixPermissions => [NON_OCTAL_UNIX_PERMISSIONS]);
impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
match &expr.kind {
- ExprKind::MethodCall(path, [func, param], _) => {
+ ExprKind::MethodCall(path, func, [param], _) => {
let obj_ty = cx.typeck_results().expr_ty(func).peel_refs();
if_chain! {
diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
index 6ad6837f0..bffbf20b4 100644
--- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs
+++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
@@ -57,10 +57,10 @@ impl EarlyLintPass for OctalEscapes {
}
if let ExprKind::Lit(lit) = &expr.kind {
- if matches!(lit.token.kind, LitKind::Str) {
- check_lit(cx, &lit.token, lit.span, true);
- } else if matches!(lit.token.kind, LitKind::ByteStr) {
- check_lit(cx, &lit.token, lit.span, false);
+ if matches!(lit.token_lit.kind, LitKind::Str) {
+ check_lit(cx, &lit.token_lit, lit.span, true);
+ } else if matches!(lit.token_lit.kind, LitKind::ByteStr) {
+ check_lit(cx, &lit.token_lit, lit.span, false);
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
index 413a740be..6217110a1 100644
--- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -1,26 +1,18 @@
-use std::collections::VecDeque;
-
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_lint_allowed;
-use itertools::{izip, Itertools};
-use rustc_ast::{walk_list, Label, Mutability};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::{get_expr_use_or_unification_node, get_parent_node, path_def_id, path_to_local, path_to_local_id};
+use core::cell::Cell;
+use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
-use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
-use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
-use rustc_hir::intravisit::{walk_expr, walk_stmt, FnKind, Visitor};
-use rustc_hir::{
- Arm, Block, Body, Closure, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path,
- PathSegment, QPath, Stmt, StmtKind, TyKind, UnOp,
-};
+use rustc_hir::hir_id::HirIdMap;
+use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
-use rustc_middle::ty::{Ty, TyCtxt, TypeckResults};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::kw;
-use rustc_span::symbol::Ident;
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::{self, ConstKind};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::symbol::{kw, Ident};
use rustc_span::Span;
+use std::iter;
declare_clippy_lint! {
/// ### What it does
@@ -89,572 +81,315 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.61.0"]
pub ONLY_USED_IN_RECURSION,
- nursery,
+ complexity,
"arguments that is only used in recursion can be removed"
}
-declare_lint_pass!(OnlyUsedInRecursion => [ONLY_USED_IN_RECURSION]);
-
-impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
- fn check_fn(
- &mut self,
- cx: &LateContext<'tcx>,
- kind: FnKind<'tcx>,
- decl: &'tcx rustc_hir::FnDecl<'tcx>,
- body: &'tcx Body<'tcx>,
- _: Span,
- id: HirId,
- ) {
- if is_lint_allowed(cx, ONLY_USED_IN_RECURSION, id) {
- return;
- }
- if let FnKind::ItemFn(ident, ..) | FnKind::Method(ident, ..) = kind {
- let def_id = id.owner.to_def_id();
- let data = cx.tcx.def_path(def_id).data;
-
- if data.len() > 1 {
- match data.get(data.len() - 2) {
- Some(DisambiguatedDefPathData {
- data: DefPathData::Impl,
- disambiguator,
- }) if *disambiguator != 0 => return,
- _ => {},
- }
- }
-
- let has_self = !matches!(decl.implicit_self, ImplicitSelfKind::None);
-
- let ty_res = cx.typeck_results();
- let param_span = body
- .params
- .iter()
- .flat_map(|param| {
- let mut v = Vec::new();
- param.pat.each_binding(|_, hir_id, span, ident| {
- v.push((hir_id, span, ident));
- });
- v
- })
- .skip(if has_self { 1 } else { 0 })
- .filter(|(_, _, ident)| !ident.name.as_str().starts_with('_'))
- .collect_vec();
-
- let params = body.params.iter().map(|param| param.pat).collect();
-
- let mut visitor = SideEffectVisit {
- graph: FxHashMap::default(),
- has_side_effect: FxHashSet::default(),
- ret_vars: Vec::new(),
- contains_side_effect: false,
- break_vars: FxHashMap::default(),
- params,
- fn_ident: ident,
- fn_def_id: def_id,
- is_method: matches!(kind, FnKind::Method(..)),
- has_self,
- ty_res,
- tcx: cx.tcx,
- visited_exprs: FxHashSet::default(),
- };
-
- visitor.visit_expr(&body.value);
- let vars = std::mem::take(&mut visitor.ret_vars);
- // this would set the return variables to side effect
- visitor.add_side_effect(vars);
-
- let mut queue = visitor.has_side_effect.iter().copied().collect::<VecDeque<_>>();
-
- // a simple BFS to check all the variables that have side effect
- while let Some(id) = queue.pop_front() {
- if let Some(next) = visitor.graph.get(&id) {
- for i in next {
- if !visitor.has_side_effect.contains(i) {
- visitor.has_side_effect.insert(*i);
- queue.push_back(*i);
- }
- }
- }
- }
-
- for (id, span, ident) in param_span {
- // if the variable is not used in recursion, it would be marked as unused
- if !visitor.has_side_effect.contains(&id) {
- let mut queue = VecDeque::new();
- let mut visited = FxHashSet::default();
-
- queue.push_back(id);
-
- // a simple BFS to check the graph can reach to itself
- // if it can't, it means the variable is never used in recursion
- while let Some(id) = queue.pop_front() {
- if let Some(next) = visitor.graph.get(&id) {
- for i in next {
- if !visited.contains(i) {
- visited.insert(id);
- queue.push_back(*i);
- }
- }
- }
- }
+impl_lint_pass!(OnlyUsedInRecursion => [ONLY_USED_IN_RECURSION]);
+
+#[derive(Clone, Copy)]
+enum FnKind {
+ Fn,
+ TraitFn,
+ // This is a hack. Ideally we would store a `SubstsRef<'tcx>` type here, but a lint pass must be `'static`.
+ // Substitutions are, however, interned. This allows us to store the pointer as a `usize` when comparing for
+ // equality.
+ ImplTraitFn(usize),
+}
- if visited.contains(&id) {
- span_lint_and_sugg(
- cx,
- ONLY_USED_IN_RECURSION,
- span,
- "parameter is only used in recursion",
- "if this is intentional, prefix with an underscore",
- format!("_{}", ident.name.as_str()),
- Applicability::MaybeIncorrect,
- );
- }
- }
- }
+struct Param {
+ /// The function this is a parameter for.
+ fn_id: DefId,
+ fn_kind: FnKind,
+ /// The index of this parameter.
+ idx: usize,
+ ident: Ident,
+ /// Whether this parameter should be linted. Set by `Params::flag_for_linting`.
+ apply_lint: Cell<bool>,
+ /// All the uses of this parameter.
+ uses: Vec<Usage>,
+}
+impl Param {
+ fn new(fn_id: DefId, fn_kind: FnKind, idx: usize, ident: Ident) -> Self {
+ Self {
+ fn_id,
+ fn_kind,
+ idx,
+ ident,
+ apply_lint: Cell::new(true),
+ uses: Vec::new(),
}
}
}
-pub fn is_primitive(ty: Ty<'_>) -> bool {
- let ty = ty.peel_refs();
- ty.is_primitive() || ty.is_str()
+#[derive(Debug)]
+struct Usage {
+ span: Span,
+ idx: usize,
}
-
-pub fn is_array(ty: Ty<'_>) -> bool {
- let ty = ty.peel_refs();
- ty.is_array() || ty.is_array_slice()
+impl Usage {
+ fn new(span: Span, idx: usize) -> Self {
+ Self { span, idx }
+ }
}
-/// This builds the graph of side effect.
-/// The edge `a -> b` means if `a` has side effect, `b` will have side effect.
-///
-/// There are some example in following code:
-/// ```rust, ignore
-/// let b = 1;
-/// let a = b; // a -> b
-/// let (c, d) = (a, b); // c -> b, d -> b
-///
-/// let e = if a == 0 { // e -> a
-/// c // e -> c
-/// } else {
-/// d // e -> d
-/// };
-/// ```
-pub struct SideEffectVisit<'tcx> {
- graph: FxHashMap<HirId, FxHashSet<HirId>>,
- has_side_effect: FxHashSet<HirId>,
- // bool for if the variable was dereferenced from mutable reference
- ret_vars: Vec<(HirId, bool)>,
- contains_side_effect: bool,
- // break label
- break_vars: FxHashMap<Ident, Vec<(HirId, bool)>>,
- params: Vec<&'tcx Pat<'tcx>>,
- fn_ident: Ident,
- fn_def_id: DefId,
- is_method: bool,
- has_self: bool,
- ty_res: &'tcx TypeckResults<'tcx>,
- tcx: TyCtxt<'tcx>,
- visited_exprs: FxHashSet<HirId>,
+/// The parameters being checked by the lint, indexed by both the parameter's `HirId` and the
+/// `DefId` of the function paired with the parameter's index.
+#[derive(Default)]
+struct Params {
+ params: Vec<Param>,
+ by_id: HirIdMap<usize>,
+ by_fn: FxHashMap<(DefId, usize), usize>,
}
-
-impl<'tcx> Visitor<'tcx> for SideEffectVisit<'tcx> {
- fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {
- match s.kind {
- StmtKind::Local(Local {
- pat, init: Some(init), ..
- }) => {
- self.visit_pat_expr(pat, init, false);
- },
- StmtKind::Item(_) | StmtKind::Expr(_) | StmtKind::Semi(_) => {
- walk_stmt(self, s);
- },
- StmtKind::Local(_) => {},
- }
- self.ret_vars.clear();
+impl Params {
+ fn insert(&mut self, param: Param, id: HirId) {
+ let idx = self.params.len();
+ self.by_id.insert(id, idx);
+ self.by_fn.insert((param.fn_id, param.idx), idx);
+ self.params.push(param);
}
- fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
- if !self.visited_exprs.insert(ex.hir_id) {
- return;
- }
- match ex.kind {
- ExprKind::Array(exprs) | ExprKind::Tup(exprs) => {
- self.ret_vars = exprs
- .iter()
- .flat_map(|expr| {
- self.visit_expr(expr);
- std::mem::take(&mut self.ret_vars)
- })
- .collect();
- },
- ExprKind::Call(callee, args) => self.visit_fn(callee, args),
- ExprKind::MethodCall(path, args, _) => self.visit_method_call(path, args),
- ExprKind::Binary(_, lhs, rhs) => {
- self.visit_bin_op(lhs, rhs);
- },
- ExprKind::Unary(op, expr) => self.visit_un_op(op, expr),
- ExprKind::Let(Let { pat, init, .. }) => self.visit_pat_expr(pat, init, false),
- ExprKind::If(bind, then_expr, else_expr) => {
- self.visit_if(bind, then_expr, else_expr);
- },
- ExprKind::Match(expr, arms, _) => self.visit_match(expr, arms),
- // since analysing the closure is not easy, just set all variables in it to side-effect
- ExprKind::Closure(&Closure { body, .. }) => {
- let body = self.tcx.hir().body(body);
- self.visit_body(body);
- let vars = std::mem::take(&mut self.ret_vars);
- self.add_side_effect(vars);
- },
- ExprKind::Loop(block, label, _, _) | ExprKind::Block(block, label) => {
- self.visit_block_label(block, label);
- },
- ExprKind::Assign(bind, expr, _) => {
- self.visit_assign(bind, expr);
- },
- ExprKind::AssignOp(_, bind, expr) => {
- self.visit_assign(bind, expr);
- self.visit_bin_op(bind, expr);
- },
- ExprKind::Field(expr, _) => {
- self.visit_expr(expr);
- if matches!(self.ty_res.expr_ty(expr).kind(), ty::Ref(_, _, Mutability::Mut)) {
- self.ret_vars.iter_mut().for_each(|(_, b)| *b = true);
- }
- },
- ExprKind::Index(expr, index) => {
- self.visit_expr(expr);
- let mut vars = std::mem::take(&mut self.ret_vars);
- self.visit_expr(index);
- self.ret_vars.append(&mut vars);
-
- if !is_array(self.ty_res.expr_ty(expr)) {
- self.add_side_effect(self.ret_vars.clone());
- } else if matches!(self.ty_res.expr_ty(expr).kind(), ty::Ref(_, _, Mutability::Mut)) {
- self.ret_vars.iter_mut().for_each(|(_, b)| *b = true);
- }
- },
- ExprKind::Break(dest, Some(expr)) => {
- self.visit_expr(expr);
- if let Some(label) = dest.label {
- self.break_vars
- .entry(label.ident)
- .or_insert(Vec::new())
- .append(&mut self.ret_vars);
- }
- self.contains_side_effect = true;
- },
- ExprKind::Ret(Some(expr)) => {
- self.visit_expr(expr);
- let vars = std::mem::take(&mut self.ret_vars);
- self.add_side_effect(vars);
- self.contains_side_effect = true;
- },
- ExprKind::Break(_, None) | ExprKind::Continue(_) | ExprKind::Ret(None) => {
- self.contains_side_effect = true;
- },
- ExprKind::Struct(_, exprs, expr) => {
- let mut ret_vars = exprs
- .iter()
- .flat_map(|field| {
- self.visit_expr(field.expr);
- std::mem::take(&mut self.ret_vars)
- })
- .collect();
-
- walk_list!(self, visit_expr, expr);
- self.ret_vars.append(&mut ret_vars);
- },
- _ => walk_expr(self, ex),
+ fn remove_by_id(&mut self, id: HirId) {
+ if let Some(param) = self.get_by_id_mut(id) {
+ param.uses = Vec::new();
+ let key = (param.fn_id, param.idx);
+ self.by_fn.remove(&key);
+ self.by_id.remove(&id);
}
}
- fn visit_path(&mut self, path: &'tcx Path<'tcx>, _id: HirId) {
- if let Res::Local(id) = path.res {
- self.ret_vars.push((id, false));
- }
+ fn get_by_id_mut(&mut self, id: HirId) -> Option<&mut Param> {
+ self.params.get_mut(*self.by_id.get(&id)?)
}
-}
-impl<'tcx> SideEffectVisit<'tcx> {
- fn visit_assign(&mut self, lhs: &'tcx Expr<'tcx>, rhs: &'tcx Expr<'tcx>) {
- // Just support array and tuple unwrapping for now.
- //
- // ex) `(a, b) = (c, d);`
- // The graph would look like this:
- // a -> c
- // b -> d
- //
- // This would minimize the connection of the side-effect graph.
- match (&lhs.kind, &rhs.kind) {
- (ExprKind::Array(lhs), ExprKind::Array(rhs)) | (ExprKind::Tup(lhs), ExprKind::Tup(rhs)) => {
- // if not, it is a compile error
- debug_assert!(lhs.len() == rhs.len());
- izip!(*lhs, *rhs).for_each(|(lhs, rhs)| self.visit_assign(lhs, rhs));
- },
- // in other assigns, we have to connect all each other
- // because they can be connected somehow
- _ => {
- self.visit_expr(lhs);
- let lhs_vars = std::mem::take(&mut self.ret_vars);
- self.visit_expr(rhs);
- let rhs_vars = std::mem::take(&mut self.ret_vars);
- self.connect_assign(&lhs_vars, &rhs_vars, false);
- },
- }
+ fn get_by_fn(&self, id: DefId, idx: usize) -> Option<&Param> {
+ self.params.get(*self.by_fn.get(&(id, idx))?)
}
- fn visit_block_label(&mut self, block: &'tcx Block<'tcx>, label: Option<Label>) {
- self.visit_block(block);
- let _ = label.and_then(|label| {
- self.break_vars
- .remove(&label.ident)
- .map(|mut break_vars| self.ret_vars.append(&mut break_vars))
- });
- }
-
- fn visit_bin_op(&mut self, lhs: &'tcx Expr<'tcx>, rhs: &'tcx Expr<'tcx>) {
- self.visit_expr(lhs);
- let mut ret_vars = std::mem::take(&mut self.ret_vars);
- self.visit_expr(rhs);
- self.ret_vars.append(&mut ret_vars);
-
- // the binary operation between non primitive values are overloaded operators
- // so they can have side-effects
- if !is_primitive(self.ty_res.expr_ty(lhs)) || !is_primitive(self.ty_res.expr_ty(rhs)) {
- self.ret_vars.iter().for_each(|id| {
- self.has_side_effect.insert(id.0);
- });
- self.contains_side_effect = true;
- }
+ fn clear(&mut self) {
+ self.params.clear();
+ self.by_id.clear();
+ self.by_fn.clear();
}
- fn visit_un_op(&mut self, op: UnOp, expr: &'tcx Expr<'tcx>) {
- self.visit_expr(expr);
- let ty = self.ty_res.expr_ty(expr);
- // dereferencing a reference has no side-effect
- if !is_primitive(ty) && !matches!((op, ty.kind()), (UnOp::Deref, ty::Ref(..))) {
- self.add_side_effect(self.ret_vars.clone());
- }
-
- if matches!((op, ty.kind()), (UnOp::Deref, ty::Ref(_, _, Mutability::Mut))) {
- self.ret_vars.iter_mut().for_each(|(_, b)| *b = true);
+ /// Sets the `apply_lint` flag on each parameter.
+ fn flag_for_linting(&mut self) {
+ // Stores the list of parameters currently being resolved. Needed to avoid cycles.
+ let mut eval_stack = Vec::new();
+ for param in &self.params {
+ self.try_disable_lint_for_param(param, &mut eval_stack);
}
}
- fn visit_pat_expr(&mut self, pat: &'tcx Pat<'tcx>, expr: &'tcx Expr<'tcx>, connect_self: bool) {
- match (&pat.kind, &expr.kind) {
- (PatKind::Tuple(pats, _), ExprKind::Tup(exprs)) => {
- self.ret_vars = izip!(*pats, *exprs)
- .flat_map(|(pat, expr)| {
- self.visit_pat_expr(pat, expr, connect_self);
- std::mem::take(&mut self.ret_vars)
- })
- .collect();
- },
- (PatKind::Slice(front_exprs, _, back_exprs), ExprKind::Array(exprs)) => {
- let mut vars = izip!(*front_exprs, *exprs)
- .flat_map(|(pat, expr)| {
- self.visit_pat_expr(pat, expr, connect_self);
- std::mem::take(&mut self.ret_vars)
- })
- .collect();
- self.ret_vars = izip!(back_exprs.iter().rev(), exprs.iter().rev())
- .flat_map(|(pat, expr)| {
- self.visit_pat_expr(pat, expr, connect_self);
- std::mem::take(&mut self.ret_vars)
- })
- .collect();
- self.ret_vars.append(&mut vars);
- },
- _ => {
- let mut lhs_vars = Vec::new();
- pat.each_binding(|_, id, _, _| lhs_vars.push((id, false)));
- self.visit_expr(expr);
- let rhs_vars = std::mem::take(&mut self.ret_vars);
- self.connect_assign(&lhs_vars, &rhs_vars, connect_self);
- self.ret_vars = rhs_vars;
- },
+ // Use by calling `flag_for_linting`.
+ fn try_disable_lint_for_param(&self, param: &Param, eval_stack: &mut Vec<usize>) -> bool {
+ if !param.apply_lint.get() {
+ true
+ } else if param.uses.is_empty() {
+ // Don't lint on unused parameters.
+ param.apply_lint.set(false);
+ true
+ } else if eval_stack.contains(&param.idx) {
+ // Already on the evaluation stack. Returning false will continue to evaluate other dependencies.
+ false
+ } else {
+ eval_stack.push(param.idx);
+ // Check all cases when used at a different parameter index.
+ // Needed to catch cases like: `fn f(x: u32, y: u32) { f(y, x) }`
+ for usage in param.uses.iter().filter(|u| u.idx != param.idx) {
+ if self
+ .get_by_fn(param.fn_id, usage.idx)
+ // If the parameter can't be found, then it's used for more than just recursion.
+ .map_or(true, |p| self.try_disable_lint_for_param(p, eval_stack))
+ {
+ param.apply_lint.set(false);
+ eval_stack.pop();
+ return true;
+ }
+ }
+ eval_stack.pop();
+ false
}
}
+}
- fn visit_fn(&mut self, callee: &'tcx Expr<'tcx>, args: &'tcx [Expr<'tcx>]) {
- self.visit_expr(callee);
- let mut ret_vars = std::mem::take(&mut self.ret_vars);
- self.add_side_effect(ret_vars.clone());
-
- let mut is_recursive = false;
-
- if_chain! {
- if !self.has_self;
- if let ExprKind::Path(QPath::Resolved(_, path)) = callee.kind;
- if let Res::Def(DefKind::Fn, def_id) = path.res;
- if self.fn_def_id == def_id;
- then {
- is_recursive = true;
- }
- }
+#[derive(Default)]
+pub struct OnlyUsedInRecursion {
+ /// Track the top-level body entered. Needed to delay reporting when entering nested bodies.
+ entered_body: Option<HirId>,
+ params: Params,
+}
- if_chain! {
- if !self.has_self && self.is_method;
- if let ExprKind::Path(QPath::TypeRelative(ty, segment)) = callee.kind;
- if segment.ident == self.fn_ident;
- if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
- if let Res::SelfTy{ .. } = path.res;
- then {
- is_recursive = true;
- }
+impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
+ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) {
+ if body.value.span.from_expansion() {
+ return;
}
-
- if is_recursive {
- izip!(self.params.clone(), args).for_each(|(pat, expr)| {
- self.visit_pat_expr(pat, expr, true);
- self.ret_vars.clear();
- });
- } else {
- // This would set arguments used in closure that does not have side-effect.
- // Closure itself can be detected whether there is a side-effect, but the
- // value of variable that is holding closure can change.
- // So, we just check the variables.
- self.ret_vars = args
- .iter()
- .flat_map(|expr| {
- self.visit_expr(expr);
- std::mem::take(&mut self.ret_vars)
- })
- .collect_vec()
- .into_iter()
- .map(|id| {
- self.has_side_effect.insert(id.0);
- id
- })
- .collect();
- self.contains_side_effect = true;
+ // `skip_params` is either `0` or `1` to skip the `self` parameter in trait functions.
+ // It can't be renamed, and it can't be removed without removing it from multiple functions.
+ let (fn_id, fn_kind, skip_params) = match get_parent_node(cx.tcx, body.value.hir_id) {
+ Some(Node::Item(i)) => (i.def_id.to_def_id(), FnKind::Fn, 0),
+ Some(Node::TraitItem(&TraitItem {
+ kind: TraitItemKind::Fn(ref sig, _),
+ def_id,
+ ..
+ })) => (
+ def_id.to_def_id(),
+ FnKind::TraitFn,
+ usize::from(sig.decl.implicit_self.has_implicit_self()),
+ ),
+ Some(Node::ImplItem(&ImplItem {
+ kind: ImplItemKind::Fn(ref sig, _),
+ def_id,
+ ..
+ })) => {
+ #[allow(trivial_casts)]
+ if let Some(Node::Item(item)) = get_parent_node(cx.tcx, cx.tcx.hir().local_def_id_to_hir_id(def_id))
+ && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.def_id)
+ && let Some(trait_item_id) = cx.tcx.associated_item(def_id).trait_item_def_id
+ {
+ (
+ trait_item_id,
+ FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.substs) as *const _ as usize),
+ usize::from(sig.decl.implicit_self.has_implicit_self()),
+ )
+ } else {
+ (def_id.to_def_id(), FnKind::Fn, 0)
+ }
+ },
+ _ => return,
+ };
+ body.params
+ .iter()
+ .enumerate()
+ .skip(skip_params)
+ .filter_map(|(idx, p)| match p.pat.kind {
+ PatKind::Binding(_, id, ident, None) if !ident.as_str().starts_with('_') => {
+ Some((id, Param::new(fn_id, fn_kind, idx, ident)))
+ },
+ _ => None,
+ })
+ .for_each(|(id, param)| self.params.insert(param, id));
+ if self.entered_body.is_none() {
+ self.entered_body = Some(body.value.hir_id);
}
-
- self.ret_vars.append(&mut ret_vars);
}
- fn visit_method_call(&mut self, path: &'tcx PathSegment<'tcx>, args: &'tcx [Expr<'tcx>]) {
- if_chain! {
- if self.is_method;
- if path.ident == self.fn_ident;
- if let ExprKind::Path(QPath::Resolved(_, path)) = args.first().unwrap().kind;
- if let Res::Local(..) = path.res;
- let ident = path.segments.last().unwrap().ident;
- if ident.name == kw::SelfLower;
- then {
- izip!(self.params.clone(), args.iter())
- .for_each(|(pat, expr)| {
- self.visit_pat_expr(pat, expr, true);
- self.ret_vars.clear();
- });
- } else {
- self.ret_vars = args
- .iter()
- .flat_map(|expr| {
- self.visit_expr(expr);
- std::mem::take(&mut self.ret_vars)
- })
- .collect_vec()
- .into_iter()
- .map(|a| {
- self.has_side_effect.insert(a.0);
- a
- })
- .collect();
- self.contains_side_effect = true;
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) {
+ if let Some(id) = path_to_local(e)
+ && let Some(param) = self.params.get_by_id_mut(id)
+ {
+ let typeck = cx.typeck_results();
+ let span = e.span;
+ let mut e = e;
+ loop {
+ match get_expr_use_or_unification_node(cx.tcx, e) {
+ None | Some((Node::Stmt(_), _)) => return,
+ Some((Node::Expr(parent), child_id)) => match parent.kind {
+ // Recursive call. Track which index the parameter is used in.
+ ExprKind::Call(callee, args)
+ if path_def_id(cx, callee).map_or(false, |id| {
+ id == param.fn_id
+ && has_matching_substs(param.fn_kind, typeck.node_substs(callee.hir_id))
+ }) =>
+ {
+ if let Some(idx) = args.iter().position(|arg| arg.hir_id == child_id) {
+ param.uses.push(Usage::new(span, idx));
+ }
+ return;
+ },
+ ExprKind::MethodCall(_, receiver, args, _)
+ if typeck.type_dependent_def_id(parent.hir_id).map_or(false, |id| {
+ id == param.fn_id
+ && has_matching_substs(param.fn_kind, typeck.node_substs(parent.hir_id))
+ }) =>
+ {
+ if let Some(idx) = iter::once(receiver).chain(args).position(|arg| arg.hir_id == child_id) {
+ param.uses.push(Usage::new(span, idx));
+ }
+ return;
+ },
+ // Assignment to a parameter is fine.
+ ExprKind::Assign(lhs, _, _) | ExprKind::AssignOp(_, lhs, _) if lhs.hir_id == child_id => {
+ return;
+ },
+ // Parameter update e.g. `x = x + 1`
+ ExprKind::Assign(lhs, rhs, _) | ExprKind::AssignOp(_, lhs, rhs)
+ if rhs.hir_id == child_id && path_to_local_id(lhs, id) =>
+ {
+ return;
+ },
+ // Side-effect free expressions. Walk to the parent expression.
+ ExprKind::Binary(_, lhs, rhs)
+ if typeck.expr_ty(lhs).is_primitive() && typeck.expr_ty(rhs).is_primitive() =>
+ {
+ e = parent;
+ continue;
+ },
+ ExprKind::Unary(_, arg) if typeck.expr_ty(arg).is_primitive() => {
+ e = parent;
+ continue;
+ },
+ ExprKind::AddrOf(..) | ExprKind::Cast(..) => {
+ e = parent;
+ continue;
+ },
+ // Only allow field accesses without auto-deref
+ ExprKind::Field(..) if typeck.adjustments().get(child_id).is_none() => {
+ e = parent;
+ continue
+ }
+ _ => (),
+ },
+ _ => (),
+ }
+ self.params.remove_by_id(id);
+ return;
}
}
}
- fn visit_if(&mut self, bind: &'tcx Expr<'tcx>, then_expr: &'tcx Expr<'tcx>, else_expr: Option<&'tcx Expr<'tcx>>) {
- let contains_side_effect = self.contains_side_effect;
- self.contains_side_effect = false;
- self.visit_expr(bind);
- let mut vars = std::mem::take(&mut self.ret_vars);
- self.visit_expr(then_expr);
- let mut then_vars = std::mem::take(&mut self.ret_vars);
- walk_list!(self, visit_expr, else_expr);
- if self.contains_side_effect {
- self.add_side_effect(vars.clone());
- }
- self.contains_side_effect |= contains_side_effect;
- self.ret_vars.append(&mut vars);
- self.ret_vars.append(&mut then_vars);
- }
-
- fn visit_match(&mut self, expr: &'tcx Expr<'tcx>, arms: &'tcx [Arm<'tcx>]) {
- self.visit_expr(expr);
- let mut expr_vars = std::mem::take(&mut self.ret_vars);
- self.ret_vars = arms
- .iter()
- .flat_map(|arm| {
- let contains_side_effect = self.contains_side_effect;
- self.contains_side_effect = false;
- // this would visit `expr` multiple times
- // but couldn't think of a better way
- self.visit_pat_expr(arm.pat, expr, false);
- let mut vars = std::mem::take(&mut self.ret_vars);
- let _ = arm.guard.as_ref().map(|guard| {
- self.visit_expr(match guard {
- Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => expr,
- });
- vars.append(&mut self.ret_vars);
- });
- self.visit_expr(arm.body);
- if self.contains_side_effect {
- self.add_side_effect(vars.clone());
- self.add_side_effect(expr_vars.clone());
+ fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) {
+ if self.entered_body == Some(body.value.hir_id) {
+ self.entered_body = None;
+ self.params.flag_for_linting();
+ for param in &self.params.params {
+ if param.apply_lint.get() {
+ span_lint_and_then(
+ cx,
+ ONLY_USED_IN_RECURSION,
+ param.ident.span,
+ "parameter is only used in recursion",
+ |diag| {
+ if param.ident.name != kw::SelfLower {
+ diag.span_suggestion(
+ param.ident.span,
+ "if this is intentional, prefix it with an underscore",
+ format!("_{}", param.ident.name),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ diag.span_note(
+ param.uses.iter().map(|x| x.span).collect::<Vec<_>>(),
+ "parameter used here",
+ );
+ },
+ );
}
- self.contains_side_effect |= contains_side_effect;
- vars.append(&mut self.ret_vars);
- vars
- })
- .collect();
- self.ret_vars.append(&mut expr_vars);
- }
-
- fn connect_assign(&mut self, lhs: &[(HirId, bool)], rhs: &[(HirId, bool)], connect_self: bool) {
- // if mutable dereference is on assignment it can have side-effect
- // (this can lead to parameter mutable dereference and change the original value)
- // too hard to detect whether this value is from parameter, so this would all
- // check mutable dereference assignment to side effect
- lhs.iter().filter(|(_, b)| *b).for_each(|(id, _)| {
- self.has_side_effect.insert(*id);
- self.contains_side_effect = true;
- });
-
- // there is no connection
- if lhs.is_empty() || rhs.is_empty() {
- return;
- }
-
- // by connected rhs in cycle, the connections would decrease
- // from `n * m` to `n + m`
- // where `n` and `m` are length of `lhs` and `rhs`.
-
- // unwrap is possible since rhs is not empty
- let rhs_first = rhs.first().unwrap();
- for (id, _) in lhs.iter() {
- if connect_self || *id != rhs_first.0 {
- self.graph
- .entry(*id)
- .or_insert_with(FxHashSet::default)
- .insert(rhs_first.0);
}
+ self.params.clear();
}
-
- let rhs = rhs.iter();
- izip!(rhs.clone().cycle().skip(1), rhs).for_each(|(from, to)| {
- if connect_self || from.0 != to.0 {
- self.graph.entry(from.0).or_insert_with(FxHashSet::default).insert(to.0);
- }
- });
}
+}
- fn add_side_effect(&mut self, v: Vec<(HirId, bool)>) {
- for (id, _) in v {
- self.has_side_effect.insert(id);
- self.contains_side_effect = true;
- }
+fn has_matching_substs(kind: FnKind, substs: SubstsRef<'_>) -> bool {
+ match kind {
+ FnKind::Fn => true,
+ FnKind::TraitFn => substs.iter().enumerate().all(|(idx, subst)| match subst.unpack() {
+ GenericArgKind::Lifetime(_) => true,
+ GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx),
+ GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx),
+ }),
+ #[allow(trivial_casts)]
+ FnKind::ImplTraitFn(expected_substs) => substs as *const _ as usize == expected_substs,
}
}
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic.rs
deleted file mode 100644
index 800cf249f..000000000
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-#![allow(
- // False positive
- clippy::match_same_arms
-)]
-
-use super::ARITHMETIC;
-use clippy_utils::{consts::constant_simple, diagnostics::span_lint};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir as hir;
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::impl_lint_pass;
-use rustc_span::source_map::Span;
-
-const HARD_CODED_ALLOWED: &[&str] = &["std::num::Saturating", "std::string::String", "std::num::Wrapping"];
-
-#[derive(Debug)]
-pub struct Arithmetic {
- allowed: FxHashSet<String>,
- // Used to check whether expressions are constants, such as in enum discriminants and consts
- const_span: Option<Span>,
- expr_span: Option<Span>,
-}
-
-impl_lint_pass!(Arithmetic => [ARITHMETIC]);
-
-impl Arithmetic {
- #[must_use]
- pub fn new(mut allowed: FxHashSet<String>) -> Self {
- allowed.extend(HARD_CODED_ALLOWED.iter().copied().map(String::from));
- Self {
- allowed,
- const_span: None,
- expr_span: None,
- }
- }
-
- /// Checks if the given `expr` has any of the inner `allowed` elements.
- fn is_allowed_ty(&self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
- self.allowed.contains(
- cx.typeck_results()
- .expr_ty(expr)
- .to_string()
- .split('<')
- .next()
- .unwrap_or_default(),
- )
- }
-
- fn issue_lint(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
- span_lint(cx, ARITHMETIC, expr.span, "arithmetic detected");
- self.expr_span = Some(expr.span);
- }
-}
-
-impl<'tcx> LateLintPass<'tcx> for Arithmetic {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if self.expr_span.is_some() {
- return;
- }
- if let Some(span) = self.const_span && span.contains(expr.span) {
- return;
- }
- match &expr.kind {
- hir::ExprKind::Binary(op, lhs, rhs) | hir::ExprKind::AssignOp(op, lhs, rhs) => {
- let (
- hir::BinOpKind::Add
- | hir::BinOpKind::Sub
- | hir::BinOpKind::Mul
- | hir::BinOpKind::Div
- | hir::BinOpKind::Rem
- | hir::BinOpKind::Shl
- | hir::BinOpKind::Shr
- ) = op.node else {
- return;
- };
- if self.is_allowed_ty(cx, lhs) || self.is_allowed_ty(cx, rhs) {
- return;
- }
- self.issue_lint(cx, expr);
- },
- hir::ExprKind::Unary(hir::UnOp::Neg, _) => {
- // CTFE already takes care of things like `-1` that do not overflow.
- if constant_simple(cx, cx.typeck_results(), expr).is_none() {
- self.issue_lint(cx, expr);
- }
- },
- _ => {},
- }
- }
-
- fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
- let body_owner = cx.tcx.hir().body_owner_def_id(body.id());
- match cx.tcx.hir().body_owner_kind(body_owner) {
- hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => {
- let body_span = cx.tcx.def_span(body_owner);
- if let Some(span) = self.const_span && span.contains(body_span) {
- return;
- }
- self.const_span = Some(body_span);
- },
- hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => {},
- }
- }
-
- fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
- let body_owner = cx.tcx.hir().body_owner(body.id());
- let body_span = cx.tcx.hir().span(body_owner);
- if let Some(span) = self.const_span && span.contains(body_span) {
- return;
- }
- self.const_span = None;
- }
-
- fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if Some(expr.span) == self.expr_span {
- self.expr_span = None;
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
new file mode 100644
index 000000000..83b69fbb3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -0,0 +1,173 @@
+#![allow(
+ // False positive
+ clippy::match_same_arms
+)]
+
+use super::ARITHMETIC_SIDE_EFFECTS;
+use clippy_utils::{consts::constant_simple, diagnostics::span_lint};
+use rustc_ast as ast;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_hir as hir;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::Ty;
+use rustc_session::impl_lint_pass;
+use rustc_span::source_map::{Span, Spanned};
+
+const HARD_CODED_ALLOWED: &[&str] = &[
+ "f32",
+ "f64",
+ "std::num::Saturating",
+ "std::string::String",
+ "std::num::Wrapping",
+];
+
+#[derive(Debug)]
+pub struct ArithmeticSideEffects {
+ allowed: FxHashSet<String>,
+ // Used to check whether expressions are constants, such as in enum discriminants and consts
+ const_span: Option<Span>,
+ expr_span: Option<Span>,
+}
+
+impl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]);
+
+impl ArithmeticSideEffects {
+ #[must_use]
+ pub fn new(mut allowed: FxHashSet<String>) -> Self {
+ allowed.extend(HARD_CODED_ALLOWED.iter().copied().map(String::from));
+ Self {
+ allowed,
+ const_span: None,
+ expr_span: None,
+ }
+ }
+
+ /// Checks assign operators (+=, -=, *=, /=) of integers in a non-constant environment that
+ /// won't overflow.
+ fn has_valid_assign_op(op: &Spanned<hir::BinOpKind>, rhs: &hir::Expr<'_>, rhs_refs: Ty<'_>) -> bool {
+ if !Self::is_literal_integer(rhs, rhs_refs) {
+ return false;
+ }
+ if let hir::BinOpKind::Div | hir::BinOpKind::Mul = op.node
+ && let hir::ExprKind::Lit(ref lit) = rhs.kind
+ && let ast::LitKind::Int(1, _) = lit.node
+ {
+ return true;
+ }
+ false
+ }
+
+ /// Checks "raw" binary operators (+, -, *, /) of integers in a non-constant environment
+ /// already handled by the CTFE.
+ fn has_valid_bin_op(lhs: &hir::Expr<'_>, lhs_refs: Ty<'_>, rhs: &hir::Expr<'_>, rhs_refs: Ty<'_>) -> bool {
+ Self::is_literal_integer(lhs, lhs_refs) && Self::is_literal_integer(rhs, rhs_refs)
+ }
+
+ /// Checks if the given `expr` has any of the inner `allowed` elements.
+ fn is_allowed_ty(&self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
+ self.allowed.contains(
+ cx.typeck_results()
+ .expr_ty(expr)
+ .to_string()
+ .split('<')
+ .next()
+ .unwrap_or_default(),
+ )
+ }
+
+ /// Explicit integers like `1` or `i32::MAX`. Does not take into consideration references.
+ fn is_literal_integer(expr: &hir::Expr<'_>, expr_refs: Ty<'_>) -> bool {
+ let is_integral = expr_refs.is_integral();
+ let is_literal = matches!(expr.kind, hir::ExprKind::Lit(_));
+ is_integral && is_literal
+ }
+
+ fn issue_lint(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
+ span_lint(cx, ARITHMETIC_SIDE_EFFECTS, expr.span, "arithmetic detected");
+ self.expr_span = Some(expr.span);
+ }
+
+ /// Manages when the lint should be triggered. Operations in constant environments, hard coded
+ /// types, custom allowed types and non-constant operations that won't overflow are ignored.
+ fn manage_bin_ops(
+ &mut self,
+ cx: &LateContext<'_>,
+ expr: &hir::Expr<'_>,
+ op: &Spanned<hir::BinOpKind>,
+ lhs: &hir::Expr<'_>,
+ rhs: &hir::Expr<'_>,
+ ) {
+ if constant_simple(cx, cx.typeck_results(), expr).is_some() {
+ return;
+ }
+ if !matches!(
+ op.node,
+ hir::BinOpKind::Add
+ | hir::BinOpKind::Sub
+ | hir::BinOpKind::Mul
+ | hir::BinOpKind::Div
+ | hir::BinOpKind::Rem
+ | hir::BinOpKind::Shl
+ | hir::BinOpKind::Shr
+ ) {
+ return;
+ };
+ if self.is_allowed_ty(cx, lhs) || self.is_allowed_ty(cx, rhs) {
+ return;
+ }
+ let lhs_refs = cx.typeck_results().expr_ty(lhs).peel_refs();
+ let rhs_refs = cx.typeck_results().expr_ty(rhs).peel_refs();
+ let has_valid_assign_op = Self::has_valid_assign_op(op, rhs, rhs_refs);
+ if has_valid_assign_op || Self::has_valid_bin_op(lhs, lhs_refs, rhs, rhs_refs) {
+ return;
+ }
+ self.issue_lint(cx, expr);
+ }
+}
+
+impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+ if self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span)) {
+ return;
+ }
+ match &expr.kind {
+ hir::ExprKind::Binary(op, lhs, rhs) | hir::ExprKind::AssignOp(op, lhs, rhs) => {
+ self.manage_bin_ops(cx, expr, op, lhs, rhs);
+ },
+ hir::ExprKind::Unary(hir::UnOp::Neg, _) => {
+ if constant_simple(cx, cx.typeck_results(), expr).is_none() {
+ self.issue_lint(cx, expr);
+ }
+ },
+ _ => {},
+ }
+ }
+
+ fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
+ let body_owner = cx.tcx.hir().body_owner(body.id());
+ let body_owner_def_id = cx.tcx.hir().local_def_id(body_owner);
+ let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id);
+ if let hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) = body_owner_kind {
+ let body_span = cx.tcx.hir().span_with_body(body_owner);
+ if let Some(span) = self.const_span && span.contains(body_span) {
+ return;
+ }
+ self.const_span = Some(body_span);
+ }
+ }
+
+ fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
+ let body_owner = cx.tcx.hir().body_owner(body.id());
+ let body_span = cx.tcx.hir().span(body_owner);
+ if let Some(span) = self.const_span && span.contains(body_span) {
+ return;
+ }
+ self.const_span = None;
+ }
+
+ fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+ if Some(expr.span) == self.expr_span {
+ self.expr_span = None;
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
index e1f9b5906..638a514ff 100644
--- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
@@ -38,7 +38,7 @@ fn symmetric_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'t
fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) {
let typeck = cx.typeck_results();
let (arg, arg_span) = match expr.kind {
- ExprKind::MethodCall(.., [arg], _)
+ ExprKind::MethodCall(_, arg, [], _)
if typeck
.type_dependent_def_id(expr.hir_id)
.and_then(|id| cx.tcx.trait_of_item(id))
diff --git a/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs b/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs
index 0d067d1e1..827a2b267 100644
--- a/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs
@@ -17,7 +17,7 @@ pub(crate) fn check<'tcx>(
right: &'tcx Expr<'_>,
) {
if op == BinOpKind::Div
- && let ExprKind::MethodCall(method_path, [self_arg], _) = left.kind
+ && let ExprKind::MethodCall(method_path, self_arg, [], _) = left.kind
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_arg).peel_refs(), sym::Duration)
&& let Some((Constant::Int(divisor), _)) = constant(cx, cx.typeck_results(), right)
{
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
index 0ef793443..97ddcdb24 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
@@ -113,7 +113,7 @@ fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
}
if_chain! {
- if let ExprKind::MethodCall(method_name, [ref self_arg, ..], _) = expr.kind;
+ if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind;
if sym!(signum) == method_name.ident.name;
// Check that the receiver of the signum() is a float (expressions[0] is the receiver of
// the method call)
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index bb6d99406..c32b4df4f 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -21,7 +21,7 @@ mod ptr_eq;
mod self_assignment;
mod verbose_bit_mask;
-pub(crate) mod arithmetic;
+pub(crate) mod arithmetic_side_effects;
use rustc_hir::{Body, Expr, ExprKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
@@ -61,25 +61,29 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
- /// Checks for any kind of arithmetic operation of any type.
+ /// Checks any kind of arithmetic operation of any type.
///
/// Operators like `+`, `-`, `*` or `<<` are usually capable of overflowing according to the [Rust
/// Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
- /// or can panic (`/`, `%`). Known safe built-in types like `Wrapping` or `Saturing` are filtered
- /// away.
+ /// or can panic (`/`, `%`).
+ ///
+ /// Known safe built-in types like `Wrapping` or `Saturing`, floats, operations in constant
+ /// environments, allowed types and non-constant operations that won't overflow are ignored.
///
/// ### Why is this bad?
- /// Integer overflow will trigger a panic in debug builds or will wrap in
- /// release mode. Division by zero will cause a panic in either mode. In some applications one
- /// wants explicitly checked, wrapping or saturating arithmetic.
+ /// For integers, overflow will trigger a panic in debug builds or wrap the result in
+ /// release mode; division by zero will cause a panic in either mode. As a result, it is
+ /// desirable to explicitly call checked, wrapping or saturating arithmetic methods.
///
/// #### Example
/// ```rust
- /// # let a = 0;
- /// a + 1;
+ /// // `n` can be any number, including `i32::MAX`.
+ /// fn foo(n: i32) -> i32 {
+ /// n + 1
+ /// }
/// ```
///
- /// Third-party types also tend to overflow.
+ /// Third-party types can also overflow or present unwanted side-effects.
///
/// #### Example
/// ```ignore,rust
@@ -88,11 +92,11 @@ declare_clippy_lint! {
/// ```
///
/// ### Allowed types
- /// Custom allowed types can be specified through the "arithmetic-allowed" filter.
+ /// Custom allowed types can be specified through the "arithmetic-side-effects-allowed" filter.
#[clippy::version = "1.64.0"]
- pub ARITHMETIC,
+ pub ARITHMETIC_SIDE_EFFECTS,
restriction,
- "any arithmetic expression that could overflow or panic"
+ "any arithmetic expression that can cause side effects like overflows or panics"
}
declare_clippy_lint! {
@@ -785,7 +789,7 @@ pub struct Operators {
}
impl_lint_pass!(Operators => [
ABSURD_EXTREME_COMPARISONS,
- ARITHMETIC,
+ ARITHMETIC_SIDE_EFFECTS,
INTEGER_ARITHMETIC,
FLOAT_ARITHMETIC,
ASSIGN_OP_PATTERN,
diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
index 1805672e3..1085e6089 100644
--- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
@@ -185,7 +185,7 @@ fn in_impl<'tcx>(
if let ItemKind::Impl(item) = &item.kind;
if let Some(of_trait) = &item.of_trait;
if let Some(seg) = of_trait.path.segments.last();
- if let Some(Res::Def(_, trait_id)) = seg.res;
+ if let Res::Def(_, trait_id) = seg.res;
if trait_id == bin_op;
if let Some(generic_args) = seg.args;
if let Some(GenericArg::Type(other_ty)) = generic_args.args.last();
diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
index 44f153cff..0315678bf 100644
--- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
@@ -1,21 +1,22 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{
can_move_expr_to_closure, eager_or_lazy, higher, in_constant, is_else_clause, is_lang_ctor, peel_blocks,
peel_hir_expr_while, CaptureKind,
};
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::LangItem::OptionSome;
-use rustc_hir::{def::Res, BindingAnnotation, Expr, ExprKind, Mutability, PatKind, Path, QPath, UnOp};
+use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
+use rustc_hir::{
+ def::Res, Arm, BindingAnnotation, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp,
+};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
- /// Lints usage of `if let Some(v) = ... { y } else { x }` which is more
+ /// Lints usage of `if let Some(v) = ... { y } else { x }` and
+ /// `match .. { Some(v) => y, None/_ => x }` which are more
/// idiomatically done with `Option::map_or` (if the else bit is a pure
/// expression) or `Option::map_or_else` (if the else bit is an impure
/// expression).
@@ -39,6 +40,10 @@ declare_clippy_lint! {
/// } else {
/// 5
/// };
+ /// let _ = match optional {
+ /// Some(val) => val + 1,
+ /// None => 5
+ /// };
/// let _ = if let Some(foo) = optional {
/// foo
/// } else {
@@ -53,11 +58,14 @@ declare_clippy_lint! {
/// # let optional: Option<u32> = Some(0);
/// # fn do_complicated_function() -> u32 { 5 };
/// let _ = optional.map_or(5, |foo| foo);
+ /// let _ = optional.map_or(5, |val| val + 1);
/// let _ = optional.map_or_else(||{
/// let y = do_complicated_function();
/// y*y
/// }, |foo| foo);
/// ```
+ // FIXME: Before moving this lint out of nursery, the lint name needs to be updated. It now also
+ // covers matches and `Result`.
#[clippy::version = "1.47.0"]
pub OPTION_IF_LET_ELSE,
nursery,
@@ -66,19 +74,21 @@ declare_clippy_lint! {
declare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]);
-/// Returns true iff the given expression is the result of calling `Result::ok`
-fn is_result_ok(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
- if let ExprKind::MethodCall(path, &[ref receiver], _) = &expr.kind {
- path.ident.name.as_str() == "ok"
- && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver), sym::Result)
- } else {
- false
- }
-}
-
-/// A struct containing information about occurrences of the
-/// `if let Some(..) = .. else` construct that this lint detects.
-struct OptionIfLetElseOccurrence {
+/// A struct containing information about occurrences of construct that this lint detects
+///
+/// Such as:
+///
+/// ```ignore
+/// if let Some(..) = {..} else {..}
+/// ```
+/// or
+/// ```ignore
+/// match x {
+/// Some(..) => {..},
+/// None/_ => {..}
+/// }
+/// ```
+struct OptionOccurence {
option: String,
method_sugg: String,
some_expr: String,
@@ -99,43 +109,38 @@ fn format_option_in_sugg(cx: &LateContext<'_>, cond_expr: &Expr<'_>, as_ref: boo
)
}
-/// If this expression is the option if let/else construct we're detecting, then
-/// this function returns an `OptionIfLetElseOccurrence` struct with details if
-/// this construct is found, or None if this construct is not found.
-fn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<OptionIfLetElseOccurrence> {
+fn try_get_option_occurence<'tcx>(
+ cx: &LateContext<'tcx>,
+ pat: &Pat<'tcx>,
+ expr: &Expr<'_>,
+ if_then: &'tcx Expr<'_>,
+ if_else: &'tcx Expr<'_>,
+) -> Option<OptionOccurence> {
+ let cond_expr = match expr.kind {
+ ExprKind::Unary(UnOp::Deref, inner_expr) | ExprKind::AddrOf(_, _, inner_expr) => inner_expr,
+ _ => expr,
+ };
+ let inner_pat = try_get_inner_pat(cx, pat)?;
if_chain! {
- if !expr.span.from_expansion(); // Don't lint macros, because it behaves weirdly
- if !in_constant(cx, expr.hir_id);
- if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: Some(if_else) })
- = higher::IfLet::hir(cx, expr);
- if !is_else_clause(cx.tcx, expr);
- if !is_result_ok(cx, let_expr); // Don't lint on Result::ok because a different lint does it already
- if let PatKind::TupleStruct(struct_qpath, [inner_pat], _) = &let_pat.kind;
- if is_lang_ctor(cx, struct_qpath, OptionSome);
- if let PatKind::Binding(bind_annotation, _, id, None) = &inner_pat.kind;
+ if let PatKind::Binding(bind_annotation, _, id, None) = inner_pat.kind;
if let Some(some_captures) = can_move_expr_to_closure(cx, if_then);
if let Some(none_captures) = can_move_expr_to_closure(cx, if_else);
if some_captures
.iter()
.filter_map(|(id, &c)| none_captures.get(id).map(|&c2| (c, c2)))
.all(|(x, y)| x.is_imm_ref() && y.is_imm_ref());
-
then {
- let capture_mut = if bind_annotation == &BindingAnnotation::Mutable { "mut " } else { "" };
+ let capture_mut = if bind_annotation == BindingAnnotation::MUT { "mut " } else { "" };
let some_body = peel_blocks(if_then);
let none_body = peel_blocks(if_else);
let method_sugg = if eager_or_lazy::switch_to_eager_eval(cx, none_body) { "map_or" } else { "map_or_else" };
let capture_name = id.name.to_ident_string();
- let (as_ref, as_mut) = match &let_expr.kind {
+ let (as_ref, as_mut) = match &expr.kind {
ExprKind::AddrOf(_, Mutability::Not, _) => (true, false),
ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true),
- _ => (bind_annotation == &BindingAnnotation::Ref, bind_annotation == &BindingAnnotation::RefMut),
- };
- let cond_expr = match let_expr.kind {
- // Pointer dereferencing happens automatically, so we can omit it in the suggestion
- ExprKind::Unary(UnOp::Deref, expr) | ExprKind::AddrOf(_, _, expr) => expr,
- _ => let_expr,
+ _ => (bind_annotation == BindingAnnotation::REF, bind_annotation == BindingAnnotation::REF_MUT),
};
+
// Check if captures the closure will need conflict with borrows made in the scrutinee.
// TODO: check all the references made in the scrutinee expression. This will require interacting
// with the borrow checker. Currently only `<local>[.<field>]*` is checked for.
@@ -154,30 +159,100 @@ fn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) ->
}
}
}
- Some(OptionIfLetElseOccurrence {
+
+ return Some(OptionOccurence {
option: format_option_in_sugg(cx, cond_expr, as_ref, as_mut),
method_sugg: method_sugg.to_string(),
some_expr: format!("|{}{}| {}", capture_mut, capture_name, Sugg::hir_with_macro_callsite(cx, some_body, "..")),
none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir_with_macro_callsite(cx, none_body, "..")),
- })
+ });
+ }
+ }
+
+ None
+}
+
+fn try_get_inner_pat<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<&'tcx Pat<'tcx>> {
+ if let PatKind::TupleStruct(ref qpath, [inner_pat], ..) = pat.kind {
+ if is_lang_ctor(cx, qpath, OptionSome) || is_lang_ctor(cx, qpath, ResultOk) {
+ return Some(inner_pat);
+ }
+ }
+ None
+}
+
+/// If this expression is the option if let/else construct we're detecting, then
+/// this function returns an `OptionOccurence` struct with details if
+/// this construct is found, or None if this construct is not found.
+fn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<OptionOccurence> {
+ if let Some(higher::IfLet {
+ let_pat,
+ let_expr,
+ if_then,
+ if_else: Some(if_else),
+ }) = higher::IfLet::hir(cx, expr)
+ {
+ if !is_else_clause(cx.tcx, expr) {
+ return try_get_option_occurence(cx, let_pat, let_expr, if_then, if_else);
+ }
+ }
+ None
+}
+
+fn detect_option_match<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<OptionOccurence> {
+ if let ExprKind::Match(ex, arms, MatchSource::Normal) = expr.kind {
+ if let Some((let_pat, if_then, if_else)) = try_convert_match(cx, arms) {
+ return try_get_option_occurence(cx, let_pat, ex, if_then, if_else);
+ }
+ }
+ None
+}
+
+fn try_convert_match<'tcx>(
+ cx: &LateContext<'tcx>,
+ arms: &[Arm<'tcx>],
+) -> Option<(&'tcx Pat<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {
+ if arms.len() == 2 {
+ return if is_none_or_err_arm(cx, &arms[1]) {
+ Some((arms[0].pat, arms[0].body, arms[1].body))
+ } else if is_none_or_err_arm(cx, &arms[0]) {
+ Some((arms[1].pat, arms[1].body, arms[0].body))
} else {
None
- }
+ };
+ }
+ None
+}
+
+fn is_none_or_err_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
+ match arm.pat.kind {
+ PatKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
+ PatKind::TupleStruct(ref qpath, [first_pat], _) => {
+ is_lang_ctor(cx, qpath, ResultErr) && matches!(first_pat.kind, PatKind::Wild)
+ },
+ PatKind::Wild => true,
+ _ => false,
}
}
impl<'tcx> LateLintPass<'tcx> for OptionIfLetElse {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
- if let Some(detection) = detect_option_if_let_else(cx, expr) {
+ // Don't lint macros and constants
+ if expr.span.from_expansion() || in_constant(cx, expr.hir_id) {
+ return;
+ }
+
+ let detection = detect_option_if_let_else(cx, expr).or_else(|| detect_option_match(cx, expr));
+ if let Some(det) = detection {
span_lint_and_sugg(
cx,
OPTION_IF_LET_ELSE,
expr.span,
- format!("use Option::{} instead of an if let/else", detection.method_sugg).as_str(),
+ format!("use Option::{} instead of an if let/else", det.method_sugg).as_str(),
"try",
format!(
"{}.{}({}, {})",
- detection.option, detection.method_sugg, detection.none_expr, detection.some_expr,
+ det.option, det.method_sugg, det.none_expr, det.some_expr
),
Applicability::MaybeIncorrect,
);
diff --git a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
index 21acf003d..4aa0d9227 100644
--- a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
@@ -69,7 +69,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir
}
true
})
- .visit_expr(&body.value);
+ .visit_expr(body.value);
if !panics.is_empty() {
span_lint_and_then(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs b/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs
new file mode 100644
index 000000000..000b0ba7a
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs
@@ -0,0 +1,105 @@
+use clippy_utils::{
+ diagnostics::span_lint_and_sugg, is_lang_ctor, peel_hir_expr_refs, peel_ref_operators, sugg,
+ ty::is_type_diagnostic_item,
+};
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks for binary comparisons to a literal `Option::None`.
+ ///
+ /// ### Why is this bad?
+ ///
+ /// A programmer checking if some `foo` is `None` via a comparison `foo == None`
+ /// is usually inspired from other programming languages (e.g. `foo is None`
+ /// in Python).
+ /// Checking if a value of type `Option<T>` is (not) equal to `None` in that
+ /// way relies on `T: PartialEq` to do the comparison, which is unneeded.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn foo(f: Option<u32>) -> &'static str {
+ /// if f != None { "yay" } else { "nay" }
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// fn foo(f: Option<u32>) -> &'static str {
+ /// if f.is_some() { "yay" } else { "nay" }
+ /// }
+ /// ```
+ #[clippy::version = "1.64.0"]
+ pub PARTIALEQ_TO_NONE,
+ style,
+ "Binary comparison to `Option<T>::None` relies on `T: PartialEq`, which is unneeded"
+}
+declare_lint_pass!(PartialeqToNone => [PARTIALEQ_TO_NONE]);
+
+impl<'tcx> LateLintPass<'tcx> for PartialeqToNone {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
+ // Skip expanded code, as we have no control over it anyway...
+ if e.span.from_expansion() {
+ return;
+ }
+
+ // If the expression is of type `Option`
+ let is_ty_option =
+ |expr: &Expr<'_>| is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr).peel_refs(), sym::Option);
+
+ // If the expression is a literal `Option::None`
+ let is_none_ctor = |expr: &Expr<'_>| {
+ !expr.span.from_expansion()
+ && matches!(&peel_hir_expr_refs(expr).0.kind,
+ ExprKind::Path(p) if is_lang_ctor(cx, p, LangItem::OptionNone))
+ };
+
+ let mut applicability = Applicability::MachineApplicable;
+
+ if let ExprKind::Binary(op, left_side, right_side) = e.kind {
+ // All other comparisons (e.g. `>= None`) have special meaning wrt T
+ let is_eq = match op.node {
+ BinOpKind::Eq => true,
+ BinOpKind::Ne => false,
+ _ => return,
+ };
+
+ // We are only interested in comparisons between `Option` and a literal `Option::None`
+ let scrutinee = match (
+ is_none_ctor(left_side) && is_ty_option(right_side),
+ is_none_ctor(right_side) && is_ty_option(left_side),
+ ) {
+ (true, false) => right_side,
+ (false, true) => left_side,
+ _ => return,
+ };
+
+ // Peel away refs/derefs (as long as we don't cross manual deref impls), as
+ // autoref/autoderef will take care of those
+ let sugg = format!(
+ "{}.{}",
+ sugg::Sugg::hir_with_applicability(cx, peel_ref_operators(cx, scrutinee), "..", &mut applicability)
+ .maybe_par(),
+ if is_eq { "is_none()" } else { "is_some()" }
+ );
+
+ span_lint_and_sugg(
+ cx,
+ PARTIALEQ_TO_NONE,
+ e.span,
+ "binary comparison to literal `Option::None`",
+ if is_eq {
+ "use `Option::is_none()` instead"
+ } else {
+ "use `Option::is_some()` instead"
+ },
+ sugg,
+ applicability,
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 5fa4fd748..0960b050c 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -221,7 +221,7 @@ impl<'tcx> PassByRefOrValue {
// if function has a body and parameter is annotated with mut, ignore
if let Some(param) = fn_body.and_then(|body| body.params.get(index)) {
match param.pat.kind {
- PatKind::Binding(BindingAnnotation::Unannotated, _, _, _) => {},
+ PatKind::Binding(BindingAnnotation::NONE, _, _, _) => {},
_ => continue,
}
}
diff --git a/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs
deleted file mode 100644
index 3f940ce61..000000000
--- a/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use if_chain::if_chain;
-use rustc_ast::ast::LitKind;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::sym;
-use std::path::{Component, Path};
-
-declare_clippy_lint! {
- /// ### What it does
- ///* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
- /// calls on `PathBuf` that can cause overwrites.
- ///
- /// ### Why is this bad?
- /// Calling `push` with a root path at the start can overwrite the
- /// previous defined path.
- ///
- /// ### Example
- /// ```rust
- /// use std::path::PathBuf;
- ///
- /// let mut x = PathBuf::from("/foo");
- /// x.push("/bar");
- /// assert_eq!(x, PathBuf::from("/bar"));
- /// ```
- /// Could be written:
- ///
- /// ```rust
- /// use std::path::PathBuf;
- ///
- /// let mut x = PathBuf::from("/foo");
- /// x.push("bar");
- /// assert_eq!(x, PathBuf::from("/foo/bar"));
- /// ```
- #[clippy::version = "1.36.0"]
- pub PATH_BUF_PUSH_OVERWRITE,
- nursery,
- "calling `push` with file system root on `PathBuf` can overwrite it"
-}
-
-declare_lint_pass!(PathBufPushOverwrite => [PATH_BUF_PUSH_OVERWRITE]);
-
-impl<'tcx> LateLintPass<'tcx> for PathBufPushOverwrite {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if_chain! {
- if let ExprKind::MethodCall(path, args, _) = expr.kind;
- if path.ident.name == sym!(push);
- if args.len() == 2;
- if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&args[0]).peel_refs(), sym::PathBuf);
- if let Some(get_index_arg) = args.get(1);
- if let ExprKind::Lit(ref lit) = get_index_arg.kind;
- if let LitKind::Str(ref path_lit, _) = lit.node;
- if let pushed_path = Path::new(path_lit.as_str());
- if let Some(pushed_path_lit) = pushed_path.to_str();
- if pushed_path.has_root();
- if let Some(root) = pushed_path.components().next();
- if root == Component::RootDir;
- then {
- span_lint_and_sugg(
- cx,
- PATH_BUF_PUSH_OVERWRITE,
- lit.span,
- "calling `push` with '/' or '\\' (file system root) will overwrite the previous path definition",
- "try",
- format!("\"{}\"", pushed_path_lit.trim_start_matches(|c| c == '/' || c == '\\')),
- Applicability::MachineApplicable,
- );
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 3c5ea2d94..41d1baba6 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -507,7 +507,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
if let Some(args) = args
&& !args.is_empty()
&& body.map_or(true, |body| {
- sig.header.unsafety == Unsafety::Unsafe || contains_unsafe_block(cx, &body.value)
+ sig.header.unsafety == Unsafety::Unsafe || contains_unsafe_block(cx, body.value)
})
{
span_lint_and_then(
@@ -571,7 +571,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
Some((Node::Stmt(_), _)) => (),
Some((Node::Local(l), _)) => {
// Only trace simple bindings. e.g `let x = y;`
- if let PatKind::Binding(BindingAnnotation::Unannotated, id, _, None) = l.pat.kind {
+ if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind {
self.bindings.insert(id, args_idx);
} else {
set_skip_flag();
@@ -591,8 +591,11 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
set_skip_flag();
}
},
- ExprKind::MethodCall(name, expr_args @ [self_arg, ..], _) => {
- let i = expr_args.iter().position(|arg| arg.hir_id == child_id).unwrap_or(0);
+ ExprKind::MethodCall(name, self_arg, expr_args, _) => {
+ let i = std::iter::once(self_arg)
+ .chain(expr_args.iter())
+ .position(|arg| arg.hir_id == child_id)
+ .unwrap_or(0);
if i == 0 {
// Check if the method can be renamed.
let name = name.ident.as_str();
@@ -644,7 +647,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
.filter_map(|(i, arg)| {
let param = &body.params[arg.idx];
match param.pat.kind {
- PatKind::Binding(BindingAnnotation::Unannotated, id, _, None)
+ PatKind::Binding(BindingAnnotation::NONE, id, _, None)
if !is_lint_allowed(cx, PTR_ARG, param.hir_id) =>
{
Some((id, i))
@@ -661,7 +664,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
results,
skip_count,
};
- v.visit_expr(&body.value);
+ v.visit_expr(body.value);
v.results
}
diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
index b907f38af..4dc65da3e 100644
--- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
@@ -93,7 +93,7 @@ fn expr_as_ptr_offset_call<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, Method)> {
- if let ExprKind::MethodCall(path_segment, [arg_0, arg_1, ..], _) = &expr.kind {
+ if let ExprKind::MethodCall(path_segment, arg_0, [arg_1, ..], _) = &expr.kind {
if is_expr_ty_raw_ptr(cx, arg_0) {
if path_segment.ident.name == sym::offset {
return Some((arg_0, arg_1, Method::Offset));
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index fd0a53839..569870ab2 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -9,7 +9,7 @@ use clippy_utils::{
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
-use rustc_hir::{BindingAnnotation, Expr, ExprKind, Node, PatKind, PathSegment, QPath};
+use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, Node, PatKind, PathSegment, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -86,8 +86,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
if_chain! {
if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr);
if !is_else_clause(cx.tcx, expr);
- if let ExprKind::MethodCall(segment, args, _) = &cond.kind;
- if let Some(caller) = args.get(0);
+ if let ExprKind::MethodCall(segment, caller, ..) = &cond.kind;
let caller_ty = cx.typeck_results().expr_ty(caller);
let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then, r#else);
if is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block);
@@ -123,8 +122,9 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
if_chain! {
if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr);
if !is_else_clause(cx.tcx, expr);
- if let PatKind::TupleStruct(ref path1, [field], None) = let_pat.kind;
- if let PatKind::Binding(annot, bind_id, ident, _) = field.kind;
+ if let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind;
+ if ddpos.as_opt_usize().is_none();
+ if let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind;
let caller_ty = cx.typeck_results().expr_ty(let_expr);
let if_block = IfBlockType::IfLet(path1, caller_ty, ident.name, let_expr, if_then, if_else);
if (is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id))
@@ -133,12 +133,11 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
then {
let mut applicability = Applicability::MachineApplicable;
let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
- let by_ref = matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
let requires_semi = matches!(get_parent_node(cx.tcx, expr.hir_id), Some(Node::Stmt(_)));
let sugg = format!(
"{}{}?{}",
receiver_str,
- if by_ref { ".as_ref()" } else { "" },
+ if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
if requires_semi { ";" } else { "" }
);
span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index 547d4da81..918d624ee 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -1,48 +1,22 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::higher;
use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use clippy_utils::{get_parent_expr, in_constant, is_integer_const, meets_msrv, msrvs, path_to_local};
-use clippy_utils::{higher, SpanlessEq};
use if_chain::if_chain;
use rustc_ast::ast::RangeLimits;
use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind, HirId, PathSegment, QPath};
+use rustc_hir::{BinOpKind, Expr, ExprKind, HirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::{Span, Spanned};
-use rustc_span::sym;
use std::cmp::Ordering;
declare_clippy_lint! {
/// ### What it does
- /// Checks for zipping a collection with the range of
- /// `0.._.len()`.
- ///
- /// ### Why is this bad?
- /// The code is better expressed with `.enumerate()`.
- ///
- /// ### Example
- /// ```rust
- /// # let x = vec![1];
- /// let _ = x.iter().zip(0..x.len());
- /// ```
- ///
- /// Use instead:
- /// ```rust
- /// # let x = vec![1];
- /// let _ = x.iter().enumerate();
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub RANGE_ZIP_WITH_LEN,
- complexity,
- "zipping iterator with a range when `enumerate()` would do"
-}
-
-declare_clippy_lint! {
- /// ### What it does
/// Checks for exclusive ranges where 1 is added to the
/// upper bound, e.g., `x..(y+1)`.
///
@@ -198,7 +172,6 @@ impl Ranges {
}
impl_lint_pass!(Ranges => [
- RANGE_ZIP_WITH_LEN,
RANGE_PLUS_ONE,
RANGE_MINUS_ONE,
REVERSED_EMPTY_RANGES,
@@ -207,16 +180,10 @@ impl_lint_pass!(Ranges => [
impl<'tcx> LateLintPass<'tcx> for Ranges {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- match expr.kind {
- ExprKind::MethodCall(path, args, _) => {
- check_range_zip_with_len(cx, path, args, expr.span);
- },
- ExprKind::Binary(ref op, l, r) => {
- if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
- check_possible_range_contains(cx, op.node, l, r, expr, expr.span);
- }
- },
- _ => {},
+ if let ExprKind::Binary(ref op, l, r) = expr.kind {
+ if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
+ check_possible_range_contains(cx, op.node, l, r, expr, expr.span);
+ }
}
check_exclusive_range_plus_one(cx, expr);
@@ -380,37 +347,10 @@ fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option<R
None
}
-fn check_range_zip_with_len(cx: &LateContext<'_>, path: &PathSegment<'_>, args: &[Expr<'_>], span: Span) {
- if_chain! {
- if path.ident.as_str() == "zip";
- if let [iter, zip_arg] = args;
- // `.iter()` call
- if let ExprKind::MethodCall(iter_path, iter_args, _) = iter.kind;
- if iter_path.ident.name == sym::iter;
- // range expression in `.zip()` call: `0..x.len()`
- if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::Range::hir(zip_arg);
- if is_integer_const(cx, start, 0);
- // `.len()` call
- if let ExprKind::MethodCall(len_path, len_args, _) = end.kind;
- if len_path.ident.name == sym::len && len_args.len() == 1;
- // `.iter()` and `.len()` called on same `Path`
- if let ExprKind::Path(QPath::Resolved(_, iter_path)) = iter_args[0].kind;
- if let ExprKind::Path(QPath::Resolved(_, len_path)) = len_args[0].kind;
- if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments);
- then {
- span_lint(cx,
- RANGE_ZIP_WITH_LEN,
- span,
- &format!("it is more idiomatic to use `{}.iter().enumerate()`",
- snippet(cx, iter_args[0].span, "_"))
- );
- }
- }
-}
-
// exclusive range plus one: `x..(y+1)`
fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
+ if expr.span.can_be_used_for_suggestions();
if let Some(higher::Range {
start,
end: Some(end),
@@ -418,14 +358,7 @@ fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
}) = higher::Range::hir(expr);
if let Some(y) = y_plus_one(cx, end);
then {
- let span = if expr.span.from_expansion() {
- expr.span
- .ctxt()
- .outer_expn_data()
- .call_site
- } else {
- expr.span
- };
+ let span = expr.span;
span_lint_and_then(
cx,
RANGE_PLUS_ONE,
@@ -460,6 +393,7 @@ fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
// inclusive range minus one: `x..=(y-1)`
fn check_inclusive_range_minus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
+ if expr.span.can_be_used_for_suggestions();
if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::Range::hir(expr);
if let Some(y) = y_minus_one(cx, end);
then {
diff --git a/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs b/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs
index 8db8c4e9b..e82aa3a7b 100644
--- a/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs
+++ b/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs
@@ -41,7 +41,7 @@ declare_clippy_lint! {
/// let data = std::rc::Rc::new("some data".to_string());
/// let v = vec![data; 100];
/// ```
- #[clippy::version = "1.62.0"]
+ #[clippy::version = "1.63.0"]
pub RC_CLONE_IN_VEC_INIT,
suspicious,
"initializing reference-counted pointer in `vec![elem; len]`"
diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
index 9538a8104..2882ba033 100644
--- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
@@ -43,7 +43,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.63.0"]
pub READ_ZERO_BYTE_VEC,
- correctness,
+ nursery,
"checks for reads into a zero-length `Vec`"
}
declare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]);
@@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
// finds use of `_.read(&mut v)`
let mut read_found = false;
let mut visitor = expr_visitor_no_bodies(|expr| {
- if let ExprKind::MethodCall(path, [_self, arg], _) = expr.kind
+ if let ExprKind::MethodCall(path, _self, [arg], _) = expr.kind
&& let PathSegment { ident: read_or_read_exact, .. } = *path
&& matches!(read_or_read_exact.as_str(), "read" | "read_exact")
&& let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index eddca6045..9fd86331e 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
vis.into_map(cx, maybe_storage_live_result)
};
- for (bb, bbdata) in mir.basic_blocks().iter_enumerated() {
+ for (bb, bbdata) in mir.basic_blocks.iter_enumerated() {
let terminator = bbdata.terminator();
if terminator.source_info.span.from_expansion() {
@@ -186,7 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
unwrap_or_continue!(find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0]));
let loc = mir::Location {
block: bb,
- statement_index: mir.basic_blocks()[bb].statements.len(),
+ statement_index: mir.basic_blocks[bb].statements.len(),
};
// This can be turned into `res = move local` if `arg` and `cloned` are not borrowed
@@ -310,7 +310,7 @@ fn find_stmt_assigns_to<'tcx>(
by_ref: bool,
bb: mir::BasicBlock,
) -> Option<(mir::Local, CannotMoveOut)> {
- let rvalue = mir.basic_blocks()[bb].statements.iter().rev().find_map(|stmt| {
+ let rvalue = mir.basic_blocks[bb].statements.iter().rev().find_map(|stmt| {
if let mir::StatementKind::Assign(box (mir::Place { local, .. }, v)) = &stmt.kind {
return if *local == to_local { Some(v) } else { None };
}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index f5a93ceba..74eea6de4 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
-use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_ast::visit as ast_visit;
@@ -69,7 +69,7 @@ impl EarlyLintPass for RedundantClosureCall {
if_chain! {
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
if let ast::ExprKind::Paren(ref closure) = paren.kind;
- if let ast::ExprKind::Closure(_, _, _, _, ref decl, ref block, _) = closure.kind;
+ if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
then {
let mut visitor = ReturnVisitor::new();
visitor.visit_expr(block);
@@ -81,10 +81,19 @@ impl EarlyLintPass for RedundantClosureCall {
"try not to call a closure in the expression where it is declared",
|diag| {
if decl.inputs.is_empty() {
- let mut app = Applicability::MachineApplicable;
- let hint =
- snippet_with_applicability(cx, block.span, "..", &mut app).into_owned();
- diag.span_suggestion(expr.span, "try doing something like", hint, app);
+ let app = Applicability::MachineApplicable;
+ let mut hint = Sugg::ast(cx, block, "..");
+
+ if r#async.is_async() {
+ // `async x` is a syntax error, so it becomes `async { x }`
+ if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
+ hint = hint.blockify();
+ }
+
+ hint = hint.asyncify();
+ }
+
+ diag.span_suggestion(expr.span, "try doing something like", hint.to_string(), app);
}
},
);
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index db6c97f37..8693ca9af 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -11,6 +11,8 @@ use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::subst::GenericArg;
use rustc_session::{declare_lint_pass, declare_tool_lint};
+use std::iter;
+
declare_clippy_lint! {
/// ### What it does
/// Checks for redundant slicing expressions which use the full range, and
@@ -134,7 +136,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
} else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env,
- cx.tcx.mk_projection(target_id, cx.tcx.mk_substs([GenericArg::from(indexed_ty)].into_iter())),
+ cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(iter::once(GenericArg::from(indexed_ty)))),
) {
if deref_ty == expr_ty {
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index f8801f769..2d751c274 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -48,15 +48,15 @@ impl_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);
impl RedundantStaticLifetimes {
// Recursively visit types
- fn visit_type(&mut self, ty: &Ty, cx: &EarlyContext<'_>, reason: &str) {
+ fn visit_type(ty: &Ty, cx: &EarlyContext<'_>, reason: &str) {
match ty.kind {
// Be careful of nested structures (arrays and tuples)
TyKind::Array(ref ty, _) | TyKind::Slice(ref ty) => {
- self.visit_type(ty, cx, reason);
+ Self::visit_type(ty, cx, reason);
},
TyKind::Tup(ref tup) => {
for tup_ty in tup {
- self.visit_type(tup_ty, cx, reason);
+ Self::visit_type(tup_ty, cx, reason);
}
},
// This is what we are looking for !
@@ -87,7 +87,7 @@ impl RedundantStaticLifetimes {
_ => {},
}
}
- self.visit_type(&borrow_type.ty, cx, reason);
+ Self::visit_type(&borrow_type.ty, cx, reason);
},
_ => {},
}
@@ -102,13 +102,13 @@ impl EarlyLintPass for RedundantStaticLifetimes {
if !item.span.from_expansion() {
if let ItemKind::Const(_, ref var_type, _) = item.kind {
- self.visit_type(var_type, cx, "constants have by default a `'static` lifetime");
+ Self::visit_type(var_type, cx, "constants have by default a `'static` lifetime");
// Don't check associated consts because `'static` cannot be elided on those (issue
// #2438)
}
if let ItemKind::Static(ref var_type, _, _) = item.kind {
- self.visit_type(var_type, cx, "statics have by default a `'static` lifetime");
+ Self::visit_type(var_type, cx, "statics have by default a `'static` lifetime");
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
index 909d6971a..42514f861 100644
--- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
@@ -43,8 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
if mut_ty.mutbl == Mutability::Not;
if let TyKind::Path(ref qpath) = &mut_ty.ty.kind;
let last = last_path_segment(qpath);
- if let Some(res) = last.res;
- if let Some(def_id) = res.opt_def_id();
+ if let Some(def_id) = last.res.opt_def_id();
if cx.tcx.is_diagnostic_item(sym::Option, def_id);
if let Some(params) = last_path_segment(qpath).args ;
diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs
index f9a9b0691..6bcae0da8 100644
--- a/src/tools/clippy/clippy_lints/src/regex.rs
+++ b/src/tools/clippy/clippy_lints/src/regex.rs
@@ -57,21 +57,20 @@ declare_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]);
impl<'tcx> LateLintPass<'tcx> for Regex {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
- if let ExprKind::Call(fun, args) = expr.kind;
+ if let ExprKind::Call(fun, [arg]) = expr.kind;
if let ExprKind::Path(ref qpath) = fun.kind;
- if args.len() == 1;
if let Some(def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
then {
if match_def_path(cx, def_id, &paths::REGEX_NEW) ||
match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) {
- check_regex(cx, &args[0], true);
+ check_regex(cx, arg, true);
} else if match_def_path(cx, def_id, &paths::REGEX_BYTES_NEW) ||
match_def_path(cx, def_id, &paths::REGEX_BYTES_BUILDER_NEW) {
- check_regex(cx, &args[0], false);
+ check_regex(cx, arg, false);
} else if match_def_path(cx, def_id, &paths::REGEX_SET_NEW) {
- check_set(cx, &args[0], true);
+ check_set(cx, arg, true);
} else if match_def_path(cx, def_id, &paths::REGEX_BYTES_SET_NEW) {
- check_set(cx, &args[0], false);
+ check_set(cx, arg, false);
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index ba03ef937..6bea6dc07 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -2,6 +2,7 @@
#[rustfmt::skip]
pub static RENAMED_LINTS: &[(&str, &str)] = &[
+ ("clippy::blacklisted_name", "clippy::disallowed_names"),
("clippy::block_in_if_condition_expr", "clippy::blocks_in_if_conditions"),
("clippy::block_in_if_condition_stmt", "clippy::blocks_in_if_conditions"),
("clippy::box_vec", "clippy::box_collection"),
@@ -14,6 +15,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::for_loop_over_result", "clippy::for_loops_over_fallibles"),
("clippy::identity_conversion", "clippy::useless_conversion"),
("clippy::if_let_some_result", "clippy::match_result_ok"),
+ ("clippy::logic_bug", "clippy::overly_complex_bool_expr"),
("clippy::new_without_default_derive", "clippy::new_without_default"),
("clippy::option_and_then_some", "clippy::bind_instead_of_map"),
("clippy::option_expect_used", "clippy::expect_used"),
diff --git a/src/tools/clippy/clippy_lints/src/repeat_once.rs b/src/tools/clippy/clippy_lints/src/repeat_once.rs
deleted file mode 100644
index 898c70ace..000000000
--- a/src/tools/clippy/clippy_lints/src/repeat_once.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-use clippy_utils::consts::{constant_context, Constant};
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for usage of `.repeat(1)` and suggest the following method for each types.
- /// - `.to_string()` for `str`
- /// - `.clone()` for `String`
- /// - `.to_vec()` for `slice`
- ///
- /// The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if
- /// they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))
- ///
- /// ### Why is this bad?
- /// For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning
- /// the string is the intention behind this, `clone()` should be used.
- ///
- /// ### Example
- /// ```rust
- /// fn main() {
- /// let x = String::from("hello world").repeat(1);
- /// }
- /// ```
- /// Use instead:
- /// ```rust
- /// fn main() {
- /// let x = String::from("hello world").clone();
- /// }
- /// ```
- #[clippy::version = "1.47.0"]
- pub REPEAT_ONCE,
- complexity,
- "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` "
-}
-
-declare_lint_pass!(RepeatOnce => [REPEAT_ONCE]);
-
-impl<'tcx> LateLintPass<'tcx> for RepeatOnce {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) {
- if_chain! {
- if let ExprKind::MethodCall(path, [receiver, count], _) = &expr.kind;
- if path.ident.name == sym!(repeat);
- if constant_context(cx, cx.typeck_results()).expr(count) == Some(Constant::Int(1));
- if !receiver.span.from_expansion();
- then {
- let ty = cx.typeck_results().expr_ty(receiver).peel_refs();
- if ty.is_str() {
- span_lint_and_sugg(
- cx,
- REPEAT_ONCE,
- expr.span,
- "calling `repeat(1)` on str",
- "consider using `.to_string()` instead",
- format!("{}.to_string()", snippet(cx, receiver.span, r#""...""#)),
- Applicability::MachineApplicable,
- );
- } else if ty.builtin_index().is_some() {
- span_lint_and_sugg(
- cx,
- REPEAT_ONCE,
- expr.span,
- "calling `repeat(1)` on slice",
- "consider using `.to_vec()` instead",
- format!("{}.to_vec()", snippet(cx, receiver.span, r#""...""#)),
- Applicability::MachineApplicable,
- );
- } else if is_type_diagnostic_item(cx, ty, sym::String) {
- span_lint_and_sugg(
- cx,
- REPEAT_ONCE,
- expr.span,
- "calling `repeat(1)` on a string literal",
- "consider using `.clone()` instead",
- format!("{}.clone()", snippet(cx, receiver.span, r#""...""#)),
- Applicability::MachineApplicable,
- );
- }
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 1d9a2abf7..91553240e 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::{snippet_opt, snippet_with_context};
use clippy_utils::{fn_def_id, path_to_local_id};
use if_chain::if_chain;
-use rustc_ast::ast::Attribute;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, HirId, MatchSource, PatKind, StmtKind};
@@ -11,7 +10,6 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
-use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@@ -141,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
} else {
RetReplacement::Empty
};
- check_final_expr(cx, &body.value, Some(body.value.span), replacement);
+ check_final_expr(cx, body.value, Some(body.value.span), replacement);
},
FnKind::ItemFn(..) | FnKind::Method(..) => {
if let ExprKind::Block(block, _) = body.value.kind {
@@ -152,10 +150,6 @@ impl<'tcx> LateLintPass<'tcx> for Return {
}
}
-fn attr_is_cfg(attr: &Attribute) -> bool {
- attr.meta_item_list().is_some() && attr.has_name(sym::cfg)
-}
-
fn check_block_return<'tcx>(cx: &LateContext<'tcx>, block: &Block<'tcx>) {
if let Some(expr) = block.expr {
check_final_expr(cx, expr, Some(expr.span), RetReplacement::Empty);
@@ -178,9 +172,7 @@ fn check_final_expr<'tcx>(
match expr.kind {
// simple return is always "bad"
ExprKind::Ret(ref inner) => {
- // allow `#[cfg(a)] return a; #[cfg(b)] return b;`
- let attrs = cx.tcx.hir().attrs(expr.hir_id);
- if !attrs.iter().any(attr_is_cfg) {
+ if cx.tcx.hir().attrs(expr.hir_id).is_empty() {
let borrows = inner.map_or(false, |inner| last_statement_borrows(cx, inner));
if !borrows {
emit_return_lint(
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
index d07c26d7c..9cea4d880 100644
--- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
+++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::return_ty;
-use clippy_utils::ty::{contains_adt_constructor, contains_ty};
+use clippy_utils::ty::contains_adt_constructor;
use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
if !contains_adt_constructor(ret_ty, self_adt) {
return;
}
- } else if !contains_ty(ret_ty, self_ty) {
+ } else if !ret_ty.contains(self_ty) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
index bfb9f0d01..ac4e29e9d 100644
--- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
+++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
@@ -108,7 +108,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
};
if_chain! {
// Find calls to copy_{from,to}{,_nonoverlapping} and write_bytes methods
- if let ExprKind::MethodCall(method_path, [ptr_self, .., count], _) = expr.kind;
+ if let ExprKind::MethodCall(method_path, ptr_self, [.., count], _) = expr.kind;
let method_ident = method_path.ident.as_str();
if METHODS.iter().any(|m| *m == method_ident);
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index 2c8aa17e8..c07aa00a1 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -99,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
// Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)`
if_chain! {
if let StmtKind::Local(local) = stmt.kind;
- if let PatKind::Binding(BindingAnnotation::Mutable, local_id, _, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::MUT, local_id, _, None) = local.pat.kind;
if let Some(init) = local.init;
if let Some(len_arg) = Self::is_vec_with_capacity(cx, init);
@@ -201,7 +201,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) {
if_chain! {
if self.initialization_found;
- if let ExprKind::MethodCall(path, [self_arg, extend_arg], _) = expr.kind;
+ if let ExprKind::MethodCall(path, self_arg, [extend_arg], _) = expr.kind;
if path_to_local_id(self_arg, self.vec_alloc.local_id);
if path.ident.name == sym!(extend);
if self.is_repeat_take(extend_arg);
@@ -215,7 +215,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
/// Checks if the given expression is resizing a vector with 0
fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'_>) {
if self.initialization_found
- && let ExprKind::MethodCall(path, [self_arg, len_arg, fill_arg], _) = expr.kind
+ && let ExprKind::MethodCall(path, self_arg, [len_arg, fill_arg], _) = expr.kind
&& path_to_local_id(self_arg, self.vec_alloc.local_id)
&& path.ident.name == sym!(resize)
// Check that is filled with 0
@@ -224,7 +224,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
// Check that len expression is equals to `with_capacity` expression
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr) {
self.slow_expression = Some(InitializationType::Resize(expr));
- } else if let ExprKind::MethodCall(path, _, _) = len_arg.kind && path.ident.as_str() == "capacity" {
+ } else if let ExprKind::MethodCall(path, ..) = len_arg.kind && path.ident.as_str() == "capacity" {
self.slow_expression = Some(InitializationType::Resize(expr));
}
}
@@ -233,20 +233,15 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
/// Returns `true` if give expression is `repeat(0).take(...)`
fn is_repeat_take(&self, expr: &Expr<'_>) -> bool {
if_chain! {
- if let ExprKind::MethodCall(take_path, take_args, _) = expr.kind;
+ if let ExprKind::MethodCall(take_path, recv, [len_arg, ..], _) = expr.kind;
if take_path.ident.name == sym!(take);
-
// Check that take is applied to `repeat(0)`
- if let Some(repeat_expr) = take_args.get(0);
- if self.is_repeat_zero(repeat_expr);
-
- if let Some(len_arg) = take_args.get(1);
-
+ if self.is_repeat_zero(recv);
then {
// Check that len expression is equals to `with_capacity` expression
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr) {
return true;
- } else if let ExprKind::MethodCall(path, _, _) = len_arg.kind && path.ident.as_str() == "capacity" {
+ } else if let ExprKind::MethodCall(path, ..) = len_arg.kind && path.ident.as_str() == "capacity" {
return true;
}
}
diff --git a/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs
deleted file mode 100644
index a6c685df7..000000000
--- a/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{is_slice_of_primitives, sugg::Sugg};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-
-declare_clippy_lint! {
- /// ### What it does
- /// When sorting primitive values (integers, bools, chars, as well
- /// as arrays, slices, and tuples of such items), it is typically better to
- /// use an unstable sort than a stable sort.
- ///
- /// ### Why is this bad?
- /// Typically, using a stable sort consumes more memory and cpu cycles.
- /// Because values which compare equal are identical, preserving their
- /// relative order (the guarantee that a stable sort provides) means
- /// nothing, while the extra costs still apply.
- ///
- /// ### Known problems
- ///
- /// As pointed out in
- /// [issue #8241](https://github.com/rust-lang/rust-clippy/issues/8241),
- /// a stable sort can instead be significantly faster for certain scenarios
- /// (eg. when a sorted vector is extended with new data and resorted).
- ///
- /// For more information and benchmarking results, please refer to the
- /// issue linked above.
- ///
- /// ### Example
- /// ```rust
- /// let mut vec = vec![2, 1, 3];
- /// vec.sort();
- /// ```
- /// Use instead:
- /// ```rust
- /// let mut vec = vec![2, 1, 3];
- /// vec.sort_unstable();
- /// ```
- #[clippy::version = "1.47.0"]
- pub STABLE_SORT_PRIMITIVE,
- pedantic,
- "use of sort() when sort_unstable() is equivalent"
-}
-
-declare_lint_pass!(StableSortPrimitive => [STABLE_SORT_PRIMITIVE]);
-
-/// The three "kinds" of sorts
-enum SortingKind {
- Vanilla,
- /* The other kinds of lint are currently commented out because they
- * can map distinct values to equal ones. If the key function is
- * provably one-to-one, or if the Cmp function conserves equality,
- * then they could be linted on, but I don't know if we can check
- * for that. */
-
- /* ByKey,
- * ByCmp, */
-}
-impl SortingKind {
- /// The name of the stable version of this kind of sort
- fn stable_name(&self) -> &str {
- match self {
- SortingKind::Vanilla => "sort",
- /* SortingKind::ByKey => "sort_by_key",
- * SortingKind::ByCmp => "sort_by", */
- }
- }
- /// The name of the unstable version of this kind of sort
- fn unstable_name(&self) -> &str {
- match self {
- SortingKind::Vanilla => "sort_unstable",
- /* SortingKind::ByKey => "sort_unstable_by_key",
- * SortingKind::ByCmp => "sort_unstable_by", */
- }
- }
- /// Takes the name of a function call and returns the kind of sort
- /// that corresponds to that function name (or None if it isn't)
- fn from_stable_name(name: &str) -> Option<SortingKind> {
- match name {
- "sort" => Some(SortingKind::Vanilla),
- // "sort_by" => Some(SortingKind::ByCmp),
- // "sort_by_key" => Some(SortingKind::ByKey),
- _ => None,
- }
- }
-}
-
-/// A detected instance of this lint
-struct LintDetection {
- slice_name: String,
- method: SortingKind,
- method_args: String,
- slice_type: String,
-}
-
-fn detect_stable_sort_primitive(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintDetection> {
- if_chain! {
- if let ExprKind::MethodCall(method_name, args, _) = &expr.kind;
- if let Some(slice) = &args.get(0);
- if let Some(method) = SortingKind::from_stable_name(method_name.ident.name.as_str());
- if let Some(slice_type) = is_slice_of_primitives(cx, slice);
- then {
- let args_str = args.iter().skip(1).map(|arg| Sugg::hir(cx, arg, "..").to_string()).collect::<Vec<String>>().join(", ");
- Some(LintDetection { slice_name: Sugg::hir(cx, slice, "..").to_string(), method, method_args: args_str, slice_type })
- } else {
- None
- }
- }
-}
-
-impl LateLintPass<'_> for StableSortPrimitive {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
- if let Some(detection) = detect_stable_sort_primitive(cx, expr) {
- span_lint_and_then(
- cx,
- STABLE_SORT_PRIMITIVE,
- expr.span,
- format!(
- "used `{}` on primitive type `{}`",
- detection.method.stable_name(),
- detection.slice_type,
- )
- .as_str(),
- |diag| {
- diag.span_suggestion(
- expr.span,
- "try",
- format!(
- "{}.{}({})",
- detection.slice_name,
- detection.method.unstable_name(),
- detection.method_args,
- ),
- Applicability::MachineApplicable,
- );
- diag.note(
- "an unstable sort typically performs faster without any observable difference for this data type",
- );
- },
- );
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 22eb06b36..662d399ca 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
let (method_names, expressions, _) = method_calls(left, 1);
if method_names.len() == 1;
if expressions.len() == 1;
- if expressions[0].len() == 1;
+ if expressions[0].1.is_empty();
if method_names[0] == sym!(as_bytes);
// Check for slicer
@@ -270,7 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
then {
let mut applicability = Applicability::MachineApplicable;
- let string_expression = &expressions[0][0];
+ let string_expression = &expressions[0].0;
let snippet_app = snippet_with_applicability(
cx,
@@ -291,12 +291,12 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
}
if_chain! {
- if let ExprKind::MethodCall(path, args, _) = &e.kind;
+ if let ExprKind::MethodCall(path, receiver, ..) = &e.kind;
if path.ident.name == sym!(as_bytes);
- if let ExprKind::Lit(lit) = &args[0].kind;
+ if let ExprKind::Lit(lit) = &receiver.kind;
if let LitKind::Str(lit_content, _) = &lit.node;
then {
- let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
+ let callsite = snippet(cx, receiver.span.source_callsite(), r#""foo""#);
let mut applicability = Applicability::MachineApplicable;
if callsite.starts_with("include_str!") {
span_lint_and_sugg(
@@ -305,7 +305,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
e.span,
"calling `as_bytes()` on `include_str!(..)`",
"consider using `include_bytes!(..)` instead",
- snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability).replacen(
+ snippet_with_applicability(cx, receiver.span, r#""foo""#, &mut applicability).replacen(
"include_str",
"include_bytes",
1,
@@ -314,7 +314,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
);
} else if lit_content.as_str().is_ascii()
&& lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT
- && !args[0].span.from_expansion()
+ && !receiver.span.from_expansion()
{
span_lint_and_sugg(
cx,
@@ -324,7 +324,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
"consider using a byte string literal instead",
format!(
"b{}",
- snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability)
+ snippet_with_applicability(cx, receiver.span, r#""foo""#, &mut applicability)
),
applicability,
);
@@ -333,9 +333,9 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
}
if_chain! {
- if let ExprKind::MethodCall(path, [recv], _) = &e.kind;
+ if let ExprKind::MethodCall(path, recv, [], _) = &e.kind;
if path.ident.name == sym!(into_bytes);
- if let ExprKind::MethodCall(path, [recv], _) = &recv.kind;
+ if let ExprKind::MethodCall(path, recv, [], _) = &recv.kind;
if matches!(path.ident.name.as_str(), "to_owned" | "to_string");
if let ExprKind::Lit(lit) = &recv.kind;
if let LitKind::Str(lit_content, _) = &lit.node;
@@ -393,7 +393,7 @@ declare_lint_pass!(StrToString => [STR_TO_STRING]);
impl<'tcx> LateLintPass<'tcx> for StrToString {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
if_chain! {
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &expr.kind;
+ if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
if path.ident.name == sym::to_string;
let ty = cx.typeck_results().expr_ty(self_arg);
if let ty::Ref(_, ty, ..) = ty.kind();
@@ -443,7 +443,7 @@ declare_lint_pass!(StringToString => [STRING_TO_STRING]);
impl<'tcx> LateLintPass<'tcx> for StringToString {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
if_chain! {
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &expr.kind;
+ if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
if path.ident.name == sym::to_string;
let ty = cx.typeck_results().expr_ty(self_arg);
if is_type_diagnostic_item(cx, ty, sym::String);
@@ -487,11 +487,11 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
let tyckres = cx.typeck_results();
if_chain! {
- if let ExprKind::MethodCall(path, [split_recv], split_ws_span) = expr.kind;
+ if let ExprKind::MethodCall(path, split_recv, [], split_ws_span) = expr.kind;
if path.ident.name == sym!(split_whitespace);
if let Some(split_ws_def_id) = tyckres.type_dependent_def_id(expr.hir_id);
if cx.tcx.is_diagnostic_item(sym::str_split_whitespace, split_ws_def_id);
- if let ExprKind::MethodCall(path, [_trim_recv], trim_span) = split_recv.kind;
+ if let ExprKind::MethodCall(path, _trim_recv, [], trim_span) = split_recv.kind;
if let trim_fn_name @ ("trim" | "trim_start" | "trim_end") = path.ident.name.as_str();
if let Some(trim_def_id) = tyckres.type_dependent_def_id(split_recv.hir_id);
if is_one_of_trim_diagnostic_items(cx, trim_def_id);
diff --git a/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs b/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs
index 7bc9cf742..78403d9fd 100644
--- a/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs
@@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
if let ExprKind::Path(path) = &func.kind;
if let Some(did) = cx.qpath_res(path, func.hir_id).opt_def_id();
if match_libc_symbol(cx, did, "strlen");
- if let ExprKind::MethodCall(path, [self_arg], _) = recv.kind;
+ if let ExprKind::MethodCall(path, self_arg, [], _) = recv.kind;
if !recv.span.from_expansion();
if path.ident.name == sym::as_ptr;
then {
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index 4294464db..6add20c1f 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
]
.iter()
.find(|&(ts, _)| ts.iter().any(|&t| Ok(trait_id) == cx.tcx.lang_items().require(t)));
- if count_binops(&body.value) == 1;
+ if count_binops(body.value) == 1;
then {
span_lint(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
index aa6c01b3a..651201f34 100644
--- a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
+++ b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
@@ -39,19 +39,17 @@ declare_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]);
impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if_chain! {
- if let hir::ExprKind::MethodCall(is_some_path, is_some_args, _) = &expr.kind;
+ if let hir::ExprKind::MethodCall(is_some_path, to_digit_expr, [], _) = &expr.kind;
if is_some_path.ident.name.as_str() == "is_some";
- if let [to_digit_expr] = &**is_some_args;
then {
let match_result = match &to_digit_expr.kind {
- hir::ExprKind::MethodCall(to_digits_path, to_digit_args, _) => {
+ hir::ExprKind::MethodCall(to_digits_path, char_arg, [radix_arg], _) => {
if_chain! {
- if let [char_arg, radix_arg] = &**to_digit_args;
if to_digits_path.ident.name.as_str() == "to_digit";
let char_arg_ty = cx.typeck_results().expr_ty_adjusted(char_arg);
if *char_arg_ty.kind() == ty::Char;
then {
- Some((true, char_arg, radix_arg))
+ Some((true, *char_arg, radix_arg))
} else {
None
}
@@ -59,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
}
hir::ExprKind::Call(to_digits_call, to_digit_args) => {
if_chain! {
- if let [char_arg, radix_arg] = &**to_digit_args;
+ if let [char_arg, radix_arg] = *to_digit_args;
if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind;
if let to_digits_call_res = cx.qpath_res(to_digits_path, to_digits_call.hir_id);
if let Some(to_digits_def_id) = to_digits_call_res.opt_def_id();
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 0a42a31fb..a25be93b8 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -4,7 +4,7 @@ use clippy_utils::{SpanlessEq, SpanlessHash};
use core::hash::{Hash, Hasher};
use if_chain::if_chain;
use itertools::Itertools;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::unhash::UnhashMap;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
@@ -15,6 +15,7 @@ use rustc_hir::{
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{BytePos, Span};
+use std::collections::hash_map::Entry;
declare_clippy_lint! {
/// ### What it does
@@ -103,7 +104,6 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
fn check_generics(&mut self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
self.check_type_repetition(cx, gen);
check_trait_bound_duplication(cx, gen);
- check_bounds_or_where_duplication(cx, gen);
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
@@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
if !bound_predicate.span.from_expansion();
if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
if let Some(PathSegment {
- res: Some(Res::SelfTy{ trait_: Some(def_id), alias_to: _ }), ..
+ res: Res::SelfTy{ trait_: Some(def_id), alias_to: _ }, ..
}) = segments.first();
if let Some(
Node::Item(
@@ -234,35 +234,61 @@ impl TraitBounds {
}
fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
- if gen.span.from_expansion() || gen.params.is_empty() || gen.predicates.is_empty() {
+ if gen.span.from_expansion() {
return;
}
- let mut map = FxHashMap::<_, Vec<_>>::default();
- for predicate in gen.predicates {
+ // Explanation:
+ // fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
+ // where T: Clone + Default, { unimplemented!(); }
+ // ^^^^^^^^^^^^^^^^^^
+ // |
+ // collects each of these where clauses into a set keyed by generic name and comparable trait
+ // eg. (T, Clone)
+ let where_predicates = gen
+ .predicates
+ .iter()
+ .filter_map(|pred| {
+ if_chain! {
+ if pred.in_where_clause();
+ if let WherePredicate::BoundPredicate(bound_predicate) = pred;
+ if let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind;
+ then {
+ return Some(
+ rollup_traits(cx, bound_predicate.bounds, "these where clauses contain repeated elements")
+ .into_iter().map(|(trait_ref, _)| (path.res, trait_ref)))
+ }
+ }
+ None
+ })
+ .flatten()
+ .collect::<FxHashSet<_>>();
+
+ // Explanation:
+ // fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) ...
+ // ^^^^^^^^^^^^^^^^^^ ^^^^^^^
+ // |
+ // compare trait bounds keyed by generic name and comparable trait to collected where
+ // predicates eg. (T, Clone)
+ for predicate in gen.predicates.iter().filter(|pred| !pred.in_where_clause()) {
if_chain! {
- if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
+ if let WherePredicate::BoundPredicate(bound_predicate) = predicate;
if bound_predicate.origin != PredicateOrigin::ImplTrait;
if !bound_predicate.span.from_expansion();
- if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
- if let Some(segment) = segments.first();
+ if let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind;
then {
- for (res_where, _, span_where) in bound_predicate.bounds.iter().filter_map(get_trait_info_from_bound) {
- let trait_resolutions_direct = map.entry(segment.ident).or_default();
- if let Some((_, span_direct)) = trait_resolutions_direct
- .iter()
- .find(|(res_direct, _)| *res_direct == res_where) {
+ let traits = rollup_traits(cx, bound_predicate.bounds, "these bounds contain repeated elements");
+ for (trait_ref, span) in traits {
+ let key = (path.res, trait_ref);
+ if where_predicates.contains(&key) {
span_lint_and_help(
cx,
TRAIT_DUPLICATION_IN_BOUNDS,
- *span_direct,
+ span,
"this trait bound is already specified in the where clause",
None,
"consider removing this trait bound",
- );
- }
- else {
- trait_resolutions_direct.push((res_where, span_where));
+ );
}
}
}
@@ -270,23 +296,11 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
}
}
-#[derive(PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
struct ComparableTraitRef(Res, Vec<Res>);
-
-fn check_bounds_or_where_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
- if gen.span.from_expansion() {
- return;
- }
-
- for predicate in gen.predicates {
- if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate {
- let msg = if predicate.in_where_clause() {
- "these where clauses contain repeated elements"
- } else {
- "these bounds contain repeated elements"
- };
- rollup_traits(cx, bound_predicate.bounds, msg);
- }
+impl Default for ComparableTraitRef {
+ fn default() -> Self {
+ Self(Res::Err, Vec::new())
}
}
@@ -331,7 +345,7 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
)
}
-fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
+fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) -> Vec<(ComparableTraitRef, Span)> {
let mut map = FxHashMap::default();
let mut repeated_res = false;
@@ -343,23 +357,33 @@ fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
}
};
+ let mut i = 0usize;
for bound in bounds.iter().filter_map(only_comparable_trait_refs) {
let (comparable_bound, span_direct) = bound;
- if map.insert(comparable_bound, span_direct).is_some() {
- repeated_res = true;
+ match map.entry(comparable_bound) {
+ Entry::Occupied(_) => repeated_res = true,
+ Entry::Vacant(e) => {
+ e.insert((span_direct, i));
+ i += 1;
+ },
}
}
+ // Put bounds in source order
+ let mut comparable_bounds = vec![Default::default(); map.len()];
+ for (k, (v, i)) in map {
+ comparable_bounds[i] = (k, v);
+ }
+
if_chain! {
if repeated_res;
if let [first_trait, .., last_trait] = bounds;
then {
let all_trait_span = first_trait.span().to(last_trait.span());
- let mut traits = map.values()
- .filter_map(|span| snippet_opt(cx, *span))
+ let traits = comparable_bounds.iter()
+ .filter_map(|&(_, span)| snippet_opt(cx, span))
.collect::<Vec<_>>();
- traits.sort_unstable();
let traits = traits.join(" + ");
span_lint_and_sugg(
@@ -373,4 +397,6 @@ fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
);
}
}
+
+ comparable_bounds
}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 5f3e98144..424a6e926 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -9,6 +9,7 @@ mod transmute_ptr_to_ref;
mod transmute_ref_to_ref;
mod transmute_undefined_repr;
mod transmutes_expressible_as_ptr_casts;
+mod transmuting_null;
mod unsound_collection_transmute;
mod useless_transmute;
mod utils;
@@ -386,6 +387,28 @@ declare_clippy_lint! {
"transmute to or from a type with an undefined representation"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for transmute calls which would receive a null pointer.
+ ///
+ /// ### Why is this bad?
+ /// Transmuting a null pointer is undefined behavior.
+ ///
+ /// ### Known problems
+ /// Not all cases can be detected at the moment of this writing.
+ /// For example, variables which hold a null pointer and are then fed to a `transmute`
+ /// call, aren't detectable yet.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };
+ /// ```
+ #[clippy::version = "1.35.0"]
+ pub TRANSMUTING_NULL,
+ correctness,
+ "transmutes from a null pointer to a reference, which is undefined behavior"
+}
+
pub struct Transmute {
msrv: Option<RustcVersion>,
}
@@ -404,6 +427,7 @@ impl_lint_pass!(Transmute => [
UNSOUND_COLLECTION_TRANSMUTE,
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
TRANSMUTE_UNDEFINED_REPR,
+ TRANSMUTING_NULL,
]);
impl Transmute {
#[must_use]
@@ -436,6 +460,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
let linted = wrong_transmute::check(cx, e, from_ty, to_ty)
| crosspointer_transmute::check(cx, e, from_ty, to_ty)
+ | transmuting_null::check(cx, e, arg, to_ty)
| transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv)
| transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 20b348fc1..b6d7d9f5b 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -5,9 +5,9 @@ use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::subst::{Subst, SubstsRef};
use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy};
-use rustc_span::Span;
+use rustc_span::DUMMY_SP;
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
e: &'tcx Expr<'_>,
@@ -18,116 +18,89 @@ pub(super) fn check<'tcx>(
let mut to_ty = cx.tcx.erase_regions(to_ty_orig);
while from_ty != to_ty {
- match reduce_refs(cx, e.span, from_ty, to_ty) {
- ReducedTys::FromFatPtr {
- unsized_ty,
- to_ty: to_sub_ty,
- } => match reduce_ty(cx, to_sub_ty) {
- ReducedTy::TypeErasure => break,
- ReducedTy::UnorderedFields(ty) if is_size_pair(ty) => break,
- ReducedTy::Ref(to_sub_ty) => {
- from_ty = unsized_ty;
- to_ty = to_sub_ty;
- continue;
- },
- _ => {
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!("transmute from `{}` which has an undefined layout", from_ty_orig),
- |diag| {
- if from_ty_orig.peel_refs() != unsized_ty {
- diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
- }
- },
- );
- return true;
- },
+ let reduced_tys = reduce_refs(cx, from_ty, to_ty);
+ match (reduce_ty(cx, reduced_tys.from_ty), reduce_ty(cx, reduced_tys.to_ty)) {
+ // Various forms of type erasure.
+ (ReducedTy::TypeErasure { raw_ptr_only: false }, _)
+ | (_, ReducedTy::TypeErasure { raw_ptr_only: false }) => return false,
+ (ReducedTy::TypeErasure { .. }, _) if reduced_tys.from_raw_ptr => return false,
+ (_, ReducedTy::TypeErasure { .. }) if reduced_tys.to_raw_ptr => return false,
+
+ // `Repr(C)` <-> unordered type.
+ // If the first field of the `Repr(C)` type matches then the transmute is ok
+ (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
+ | (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty))) => {
+ from_ty = from_sub_ty;
+ to_ty = to_sub_ty;
+ continue;
},
- ReducedTys::ToFatPtr {
- unsized_ty,
- from_ty: from_sub_ty,
- } => match reduce_ty(cx, from_sub_ty) {
- ReducedTy::TypeErasure => break,
- ReducedTy::UnorderedFields(ty) if is_size_pair(ty) => break,
- ReducedTy::Ref(from_sub_ty) => {
- from_ty = from_sub_ty;
- to_ty = unsized_ty;
- continue;
- },
- _ => {
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!("transmute to `{}` which has an undefined layout", to_ty_orig),
- |diag| {
- if to_ty_orig.peel_refs() != unsized_ty {
- diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
- }
- },
- );
- return true;
- },
+ (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
+ from_ty = from_sub_ty;
+ to_ty = to_sub_ty;
+ continue;
},
- ReducedTys::ToPtr {
- from_ty: from_sub_ty,
- to_ty: to_sub_ty,
- } => match reduce_ty(cx, from_sub_ty) {
- ReducedTy::UnorderedFields(from_ty) => {
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!("transmute from `{}` which has an undefined layout", from_ty_orig),
- |diag| {
- if from_ty_orig.peel_refs() != from_ty {
- diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
- }
- },
- );
- return true;
- },
- ReducedTy::Ref(from_sub_ty) => {
- from_ty = from_sub_ty;
- to_ty = to_sub_ty;
- continue;
- },
- _ => break,
+ (ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty)))
+ if reduced_tys.from_fat_ptr =>
+ {
+ from_ty = from_sub_ty;
+ to_ty = to_sub_ty;
+ continue;
},
- ReducedTys::FromPtr {
- from_ty: from_sub_ty,
- to_ty: to_sub_ty,
- } => match reduce_ty(cx, to_sub_ty) {
- ReducedTy::UnorderedFields(to_ty) => {
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!("transmute to `{}` which has an undefined layout", to_ty_orig),
- |diag| {
- if to_ty_orig.peel_refs() != to_ty {
- diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
- }
- },
- );
- return true;
- },
- ReducedTy::Ref(to_sub_ty) => {
- from_ty = from_sub_ty;
- to_ty = to_sub_ty;
- continue;
- },
- _ => break,
+
+ // ptr <-> ptr
+ (ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))
+ if matches!(from_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_))
+ && matches!(to_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_)) =>
+ {
+ from_ty = from_sub_ty;
+ to_ty = to_sub_ty;
+ continue;
},
- ReducedTys::Other {
- from_ty: from_sub_ty,
- to_ty: to_sub_ty,
- } => match (reduce_ty(cx, from_sub_ty), reduce_ty(cx, to_sub_ty)) {
- (ReducedTy::TypeErasure, _) | (_, ReducedTy::TypeErasure) => return false,
- (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
- let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs))
+
+ // fat ptr <-> (*size, *size)
+ (ReducedTy::Other(_), ReducedTy::UnorderedFields(to_ty))
+ if reduced_tys.from_fat_ptr && is_size_pair(to_ty) =>
+ {
+ return false;
+ },
+ (ReducedTy::UnorderedFields(from_ty), ReducedTy::Other(_))
+ if reduced_tys.to_fat_ptr && is_size_pair(from_ty) =>
+ {
+ return false;
+ },
+
+ // fat ptr -> some struct | some struct -> fat ptr
+ (ReducedTy::Other(_), _) if reduced_tys.from_fat_ptr => {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_UNDEFINED_REPR,
+ e.span,
+ &format!("transmute from `{}` which has an undefined layout", from_ty_orig),
+ |diag| {
+ if from_ty_orig.peel_refs() != from_ty.peel_refs() {
+ diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
+ }
+ },
+ );
+ return true;
+ },
+ (_, ReducedTy::Other(_)) if reduced_tys.to_fat_ptr => {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_UNDEFINED_REPR,
+ e.span,
+ &format!("transmute to `{}` which has an undefined layout", to_ty_orig),
+ |diag| {
+ if to_ty_orig.peel_refs() != to_ty.peel_refs() {
+ diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
+ }
+ },
+ );
+ return true;
+ },
+
+ (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
+ let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs))
= (from_ty.kind(), to_ty.kind())
&& from_def == to_def
{
@@ -138,79 +111,72 @@ pub(super) fn check<'tcx>(
} else {
None
};
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!(
- "transmute from `{}` to `{}`, both of which have an undefined layout",
- from_ty_orig, to_ty_orig
- ),
- |diag| {
- if let Some(same_adt_did) = same_adt_did {
- diag.note(&format!(
- "two instances of the same generic type (`{}`) may have different layouts",
- cx.tcx.item_name(same_adt_did)
- ));
- } else {
- if from_ty_orig.peel_refs() != from_ty {
- diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
- }
- if to_ty_orig.peel_refs() != to_ty {
- diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
- }
- }
- },
- );
- return true;
- },
- (
- ReducedTy::UnorderedFields(from_ty),
- ReducedTy::Other(_) | ReducedTy::OrderedFields(_) | ReducedTy::Ref(_),
- ) => {
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!("transmute from `{}` which has an undefined layout", from_ty_orig),
- |diag| {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_UNDEFINED_REPR,
+ e.span,
+ &format!(
+ "transmute from `{}` to `{}`, both of which have an undefined layout",
+ from_ty_orig, to_ty_orig
+ ),
+ |diag| {
+ if let Some(same_adt_did) = same_adt_did {
+ diag.note(&format!(
+ "two instances of the same generic type (`{}`) may have different layouts",
+ cx.tcx.item_name(same_adt_did)
+ ));
+ } else {
if from_ty_orig.peel_refs() != from_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
}
- },
- );
- return true;
- },
- (
- ReducedTy::Other(_) | ReducedTy::OrderedFields(_) | ReducedTy::Ref(_),
- ReducedTy::UnorderedFields(to_ty),
- ) => {
- span_lint_and_then(
- cx,
- TRANSMUTE_UNDEFINED_REPR,
- e.span,
- &format!("transmute into `{}` which has an undefined layout", to_ty_orig),
- |diag| {
if to_ty_orig.peel_refs() != to_ty {
diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
}
- },
- );
- return true;
- },
- (ReducedTy::Ref(from_sub_ty), ReducedTy::Ref(to_sub_ty)) => {
- from_ty = from_sub_ty;
- to_ty = to_sub_ty;
- continue;
- },
- (
- ReducedTy::OrderedFields(_) | ReducedTy::Ref(_) | ReducedTy::Other(_) | ReducedTy::Param,
- ReducedTy::OrderedFields(_) | ReducedTy::Ref(_) | ReducedTy::Other(_) | ReducedTy::Param,
- )
- | (
- ReducedTy::UnorderedFields(_) | ReducedTy::Param,
- ReducedTy::UnorderedFields(_) | ReducedTy::Param,
- ) => break,
+ }
+ },
+ );
+ return true;
+ },
+ (
+ ReducedTy::UnorderedFields(from_ty),
+ ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ) => {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_UNDEFINED_REPR,
+ e.span,
+ &format!("transmute from `{}` which has an undefined layout", from_ty_orig),
+ |diag| {
+ if from_ty_orig.peel_refs() != from_ty {
+ diag.note(&format!("the contained type `{}` has an undefined layout", from_ty));
+ }
+ },
+ );
+ return true;
+ },
+ (
+ ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::UnorderedFields(to_ty),
+ ) => {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_UNDEFINED_REPR,
+ e.span,
+ &format!("transmute into `{}` which has an undefined layout", to_ty_orig),
+ |diag| {
+ if to_ty_orig.peel_refs() != to_ty {
+ diag.note(&format!("the contained type `{}` has an undefined layout", to_ty));
+ }
+ },
+ );
+ return true;
+ },
+ (
+ ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
+ )
+ | (ReducedTy::UnorderedFields(_), ReducedTy::UnorderedFields(_)) => {
+ break;
},
}
}
@@ -218,64 +184,64 @@ pub(super) fn check<'tcx>(
false
}
-enum ReducedTys<'tcx> {
- FromFatPtr { unsized_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
- ToFatPtr { unsized_ty: Ty<'tcx>, from_ty: Ty<'tcx> },
- ToPtr { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
- FromPtr { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
- Other { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
+#[expect(clippy::struct_excessive_bools)]
+struct ReducedTys<'tcx> {
+ from_ty: Ty<'tcx>,
+ to_ty: Ty<'tcx>,
+ from_raw_ptr: bool,
+ to_raw_ptr: bool,
+ from_fat_ptr: bool,
+ to_fat_ptr: bool,
}
/// Remove references so long as both types are references.
-fn reduce_refs<'tcx>(
- cx: &LateContext<'tcx>,
- span: Span,
- mut from_ty: Ty<'tcx>,
- mut to_ty: Ty<'tcx>,
-) -> ReducedTys<'tcx> {
- loop {
- return match (from_ty.kind(), to_ty.kind()) {
+fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: Ty<'tcx>) -> ReducedTys<'tcx> {
+ let mut from_raw_ptr = false;
+ let mut to_raw_ptr = false;
+ let (from_fat_ptr, to_fat_ptr) = loop {
+ break match (from_ty.kind(), to_ty.kind()) {
(
&(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
&(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
) => {
+ from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
from_ty = from_sub_ty;
+ to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
to_ty = to_sub_ty;
continue;
},
(&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
- if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
+ if !unsized_ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env) =>
{
- ReducedTys::FromFatPtr { unsized_ty, to_ty }
+ (true, false)
},
(_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
- if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
+ if !unsized_ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env) =>
{
- ReducedTys::ToFatPtr { unsized_ty, from_ty }
+ (false, true)
},
- (&(ty::Ref(_, from_ty, _) | ty::RawPtr(TypeAndMut { ty: from_ty, .. })), _) => {
- ReducedTys::FromPtr { from_ty, to_ty }
- },
- (_, &(ty::Ref(_, to_ty, _) | ty::RawPtr(TypeAndMut { ty: to_ty, .. }))) => {
- ReducedTys::ToPtr { from_ty, to_ty }
- },
- _ => ReducedTys::Other { from_ty, to_ty },
+ _ => (false, false),
};
+ };
+ ReducedTys {
+ from_ty,
+ to_ty,
+ from_raw_ptr,
+ to_raw_ptr,
+ from_fat_ptr,
+ to_fat_ptr,
}
}
enum ReducedTy<'tcx> {
/// The type can be used for type erasure.
- TypeErasure,
+ TypeErasure { raw_ptr_only: bool },
/// The type is a struct containing either zero non-zero sized fields, or multiple non-zero
/// sized fields with a defined order.
- OrderedFields(Ty<'tcx>),
+ /// The second value is the first non-zero sized type.
+ OrderedFields(Ty<'tcx>, Option<Ty<'tcx>>),
/// The type is a struct containing multiple non-zero sized fields with no defined order.
UnorderedFields(Ty<'tcx>),
- /// The type is a reference to the contained type.
- Ref(Ty<'tcx>),
- /// The type is a generic parameter.
- Param,
/// Any other type.
Other(Ty<'tcx>),
}
@@ -285,16 +251,18 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
loop {
ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty);
return match *ty.kind() {
- ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => ReducedTy::TypeErasure,
+ ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
+ ReducedTy::TypeErasure { raw_ptr_only: false }
+ },
ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {
ty = sub_ty;
continue;
},
- ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure,
+ ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure { raw_ptr_only: false },
ty::Tuple(args) => {
let mut iter = args.iter();
let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {
- return ReducedTy::OrderedFields(ty);
+ return ReducedTy::OrderedFields(ty, None);
};
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
ty = sized_ty;
@@ -309,27 +277,25 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
.iter()
.map(|f| cx.tcx.bound_type_of(f.did).subst(cx.tcx, substs));
let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {
- return ReducedTy::TypeErasure;
+ return ReducedTy::TypeErasure { raw_ptr_only: false };
};
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
ty = sized_ty;
continue;
}
if def.repr().inhibit_struct_field_reordering_opt() {
- ReducedTy::OrderedFields(ty)
+ ReducedTy::OrderedFields(ty, Some(sized_ty))
} else {
ReducedTy::UnorderedFields(ty)
}
},
ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
- ReducedTy::TypeErasure
+ ReducedTy::TypeErasure { raw_ptr_only: false }
},
// TODO: Check if the conversion to or from at least one of a union's fields is valid.
- ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure,
- ty::Foreign(_) => ReducedTy::TypeErasure,
- ty::Ref(_, ty, _) => ReducedTy::Ref(ty),
- ty::RawPtr(ty) => ReducedTy::Ref(ty.ty),
- ty::Param(_) => ReducedTy::Param,
+ ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure { raw_ptr_only: false },
+ ty::Foreign(_) | ty::Param(_) => ReducedTy::TypeErasure { raw_ptr_only: false },
+ ty::Int(_) | ty::Uint(_) => ReducedTy::TypeErasure { raw_ptr_only: true },
_ => ReducedTy::Other(ty),
};
}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmuting_null.rs b/src/tools/clippy/clippy_lints/src/transmute/transmuting_null.rs
new file mode 100644
index 000000000..d8e349af7
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmuting_null.rs
@@ -0,0 +1,61 @@
+use clippy_utils::consts::{constant_context, Constant};
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::is_path_diagnostic_item;
+use if_chain::if_chain;
+use rustc_ast::LitKind;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
+use rustc_span::symbol::sym;
+
+use super::TRANSMUTING_NULL;
+
+const LINT_MSG: &str = "transmuting a known null pointer into a reference";
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, to_ty: Ty<'tcx>) -> bool {
+ if !to_ty.is_ref() {
+ return false;
+ }
+
+ // Catching transmute over constants that resolve to `null`.
+ let mut const_eval_context = constant_context(cx, cx.typeck_results());
+ if_chain! {
+ if let ExprKind::Path(ref _qpath) = arg.kind;
+ if let Some(Constant::RawPtr(x)) = const_eval_context.expr(arg);
+ if x == 0;
+ then {
+ span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
+ return true;
+ }
+ }
+
+ // Catching:
+ // `std::mem::transmute(0 as *const i32)`
+ if_chain! {
+ if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind;
+ if let ExprKind::Lit(ref lit) = inner_expr.kind;
+ if let LitKind::Int(0, _) = lit.node;
+ then {
+ span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
+ return true;
+ }
+ }
+
+ // Catching:
+ // `std::mem::transmute(std::ptr::null::<i32>())`
+ if_chain! {
+ if let ExprKind::Call(func1, []) = arg.kind;
+ if is_path_diagnostic_item(cx, func1, sym::ptr_null);
+ then {
+ span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
+ return true;
+ }
+ }
+
+ // FIXME:
+ // Also catch transmutations of variables which are known nulls.
+ // To do this, MIR const propagation seems to be the better tool.
+ // Whenever MIR const prop routines are more developed, this will
+ // become available. As of this writing (25/03/19) it is not yet.
+ false
+}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
index 74927570b..8bdadf244 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
@@ -2,7 +2,7 @@ use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::{cast::CastKind, Ty};
use rustc_span::DUMMY_SP;
-use rustc_typeck::check::{cast::CastCheck, FnCtxt, Inherited};
+use rustc_typeck::check::{cast::{self, CastCheckResult}, FnCtxt, Inherited};
// check if the component types of the transmuted collection and the result have different ABI,
// size or alignment
@@ -53,7 +53,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
"Newly created FnCtxt contained errors"
);
- if let Ok(check) = CastCheck::new(
+ if let CastCheckResult::Deferred(check) = cast::check_cast(
&fn_ctxt, e, from_ty, to_ty,
// We won't show any error to the user, so we don't care what the span is here.
DUMMY_SP, DUMMY_SP,
diff --git a/src/tools/clippy/clippy_lints/src/transmuting_null.rs b/src/tools/clippy/clippy_lints/src/transmuting_null.rs
deleted file mode 100644
index 7939dfedc..000000000
--- a/src/tools/clippy/clippy_lints/src/transmuting_null.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-use clippy_utils::consts::{constant_context, Constant};
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_expr_diagnostic_item;
-use if_chain::if_chain;
-use rustc_ast::LitKind;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for transmute calls which would receive a null pointer.
- ///
- /// ### Why is this bad?
- /// Transmuting a null pointer is undefined behavior.
- ///
- /// ### Known problems
- /// Not all cases can be detected at the moment of this writing.
- /// For example, variables which hold a null pointer and are then fed to a `transmute`
- /// call, aren't detectable yet.
- ///
- /// ### Example
- /// ```rust
- /// let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };
- /// ```
- #[clippy::version = "1.35.0"]
- pub TRANSMUTING_NULL,
- correctness,
- "transmutes from a null pointer to a reference, which is undefined behavior"
-}
-
-declare_lint_pass!(TransmutingNull => [TRANSMUTING_NULL]);
-
-const LINT_MSG: &str = "transmuting a known null pointer into a reference";
-
-impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if in_external_macro(cx.sess(), expr.span) {
- return;
- }
-
- if_chain! {
- if let ExprKind::Call(func, [arg]) = expr.kind;
- if is_expr_diagnostic_item(cx, func, sym::transmute);
-
- then {
- // Catching transmute over constants that resolve to `null`.
- let mut const_eval_context = constant_context(cx, cx.typeck_results());
- if_chain! {
- if let ExprKind::Path(ref _qpath) = arg.kind;
- if let Some(Constant::RawPtr(x)) = const_eval_context.expr(arg);
- if x == 0;
- then {
- span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
- }
- }
-
- // Catching:
- // `std::mem::transmute(0 as *const i32)`
- if_chain! {
- if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind;
- if let ExprKind::Lit(ref lit) = inner_expr.kind;
- if let LitKind::Int(0, _) = lit.node;
- then {
- span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
- }
- }
-
- // Catching:
- // `std::mem::transmute(std::ptr::null::<i32>())`
- if_chain! {
- if let ExprKind::Call(func1, []) = arg.kind;
- if is_expr_diagnostic_item(cx, func1, sym::ptr_null);
- then {
- span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
- }
- }
-
- // FIXME:
- // Also catch transmutations of variables which are known nulls.
- // To do this, MIR const propagation seems to be the better tool.
- // Whenever MIR const prop routines are more developed, this will
- // become available. As of this writing (25/03/19) it is not yet.
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/unicode.rs b/src/tools/clippy/clippy_lints/src/unicode.rs
index cc64d17be..8980283e5 100644
--- a/src/tools/clippy/clippy_lints/src/unicode.rs
+++ b/src/tools/clippy/clippy_lints/src/unicode.rs
@@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_lint_allowed;
+use clippy_utils::macros::span_is_local;
use clippy_utils::source::snippet;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
@@ -98,6 +99,10 @@ fn escape<T: Iterator<Item = char>>(s: T) -> String {
}
fn check_str(cx: &LateContext<'_>, span: Span, id: HirId) {
+ if !span_is_local(span) {
+ return;
+ }
+
let string = snippet(cx, span, "");
if string.chars().any(|c| ['\u{200B}', '\u{ad}', '\u{2060}'].contains(&c)) {
span_lint_and_sugg(
@@ -113,6 +118,7 @@ fn check_str(cx: &LateContext<'_>, span: Span, id: HirId) {
Applicability::MachineApplicable,
);
}
+
if string.chars().any(|c| c as u32 > 0x7F) {
span_lint_and_sugg(
cx,
@@ -128,6 +134,7 @@ fn check_str(cx: &LateContext<'_>, span: Span, id: HirId) {
Applicability::MachineApplicable,
);
}
+
if is_lint_allowed(cx, NON_ASCII_LITERAL, id) && string.chars().zip(string.nfc()).any(|(a, b)| a != b) {
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/uninit_vec.rs b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
index 9f4c5555f..3f99bd3f3 100644
--- a/src/tools/clippy/clippy_lints/src/uninit_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
@@ -45,7 +45,7 @@ declare_clippy_lint! {
/// let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);
/// vec.set_len(1000); // `MaybeUninit` can be uninitialized
/// ```
- /// 3. If you are on nightly, `Vec::spare_capacity_mut()` is available:
+ /// 3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available:
/// ```rust,ignore
/// let mut vec: Vec<u8> = Vec::with_capacity(1000);
/// let remaining = vec.spare_capacity_mut(); // `&mut [MaybeUninit<u8>]`
@@ -177,7 +177,7 @@ fn extract_init_or_reserve_target<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt
});
}
},
- ExprKind::MethodCall(path, [self_expr, _], _) if is_reserve(cx, path, self_expr) => {
+ ExprKind::MethodCall(path, self_expr, [_], _) if is_reserve(cx, path, self_expr) => {
return Some(TargetVec {
location: VecLocation::Expr(self_expr),
init_kind: None,
@@ -211,7 +211,7 @@ fn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Opt
}
});
match expr.kind {
- ExprKind::MethodCall(path, [self_expr, _], _) => {
+ ExprKind::MethodCall(path, self_expr, [_], _) => {
let self_type = cx.typeck_results().expr_ty(self_expr).peel_refs();
if is_type_diagnostic_item(cx, self_type, sym::Vec) && path.ident.name.as_str() == "set_len" {
Some((self_expr, expr.span))
diff --git a/src/tools/clippy/clippy_lints/src/unit_hash.rs b/src/tools/clippy/clippy_lints/src/unit_hash.rs
deleted file mode 100644
index 88ca0cb20..000000000
--- a/src/tools/clippy/clippy_lints/src/unit_hash.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Detects `().hash(_)`.
- ///
- /// ### Why is this bad?
- /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
- ///
- /// ### Example
- /// ```rust
- /// # use std::hash::Hash;
- /// # use std::collections::hash_map::DefaultHasher;
- /// # enum Foo { Empty, WithValue(u8) }
- /// # use Foo::*;
- /// # let mut state = DefaultHasher::new();
- /// # let my_enum = Foo::Empty;
- /// match my_enum {
- /// Empty => ().hash(&mut state),
- /// WithValue(x) => x.hash(&mut state),
- /// }
- /// ```
- /// Use instead:
- /// ```rust
- /// # use std::hash::Hash;
- /// # use std::collections::hash_map::DefaultHasher;
- /// # enum Foo { Empty, WithValue(u8) }
- /// # use Foo::*;
- /// # let mut state = DefaultHasher::new();
- /// # let my_enum = Foo::Empty;
- /// match my_enum {
- /// Empty => 0_u8.hash(&mut state),
- /// WithValue(x) => x.hash(&mut state),
- /// }
- /// ```
- #[clippy::version = "1.58.0"]
- pub UNIT_HASH,
- correctness,
- "hashing a unit value, which does nothing"
-}
-declare_lint_pass!(UnitHash => [UNIT_HASH]);
-
-impl<'tcx> LateLintPass<'tcx> for UnitHash {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if_chain! {
- if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind;
- if name_ident.ident.name == sym::hash;
- if let [recv, state_param] = args;
- if cx.typeck_results().expr_ty(recv).is_unit();
- then {
- span_lint_and_then(
- cx,
- UNIT_HASH,
- expr.span,
- "this call to `hash` on the unit type will do nothing",
- |diag| {
- diag.span_suggestion(
- expr.span,
- "remove the call to `hash` or consider using",
- format!(
- "0_u8.hash({})",
- snippet(cx, state_param.span, ".."),
- ),
- Applicability::MaybeIncorrect,
- );
- diag.note("the implementation of `Hash` for `()` is a no-op");
- }
- );
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
index b0fce91ab..c0a4f3fba 100644
--- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
@@ -144,11 +144,12 @@ fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Spa
impl<'tcx> LateLintPass<'tcx> for UnitReturnExpectingOrd {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if let ExprKind::MethodCall(_, args, _) = expr.kind {
+ if let ExprKind::MethodCall(_, receiver, args, _) = expr.kind {
let arg_indices = get_args_to_check(cx, expr);
+ let args = std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>();
for (i, trait_name) in arg_indices {
if i < args.len() {
- match check_arg(cx, &args[i]) {
+ match check_arg(cx, args[i]) {
Some((span, None)) => {
span_lint(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index aec028d5c..ce9ebad8c 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -19,10 +19,12 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
&& cx.typeck_results().pat_ty(local.pat).is_unit()
{
if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer))
- || matches!(local.pat.kind, PatKind::Tuple([], None)))
+ || matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()))
&& expr_needs_inferred_result(cx, init)
{
- if !matches!(local.pat.kind, PatKind::Wild | PatKind::Tuple([], None)) {
+ if !matches!(local.pat.kind, PatKind::Wild)
+ && !matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none())
+ {
span_lint_and_then(
cx,
LET_UNIT_VALUE,
@@ -128,7 +130,7 @@ fn needs_inferred_result_ty(
locals_to_check: &mut Vec<HirId>,
seen_locals: &mut HirIdSet,
) -> bool {
- let (id, args) = match e.kind {
+ let (id, receiver, args) = match e.kind {
ExprKind::Call(
Expr {
kind: ExprKind::Path(ref path),
@@ -137,11 +139,11 @@ fn needs_inferred_result_ty(
},
args,
) => match cx.qpath_res(path, *hir_id) {
- Res::Def(DefKind::AssocFn | DefKind::Fn, id) => (id, args),
+ Res::Def(DefKind::AssocFn | DefKind::Fn, id) => (id, None, args),
_ => return false,
},
- ExprKind::MethodCall(_, args, _) => match cx.typeck_results().type_dependent_def_id(e.hir_id) {
- Some(id) => (id, args),
+ ExprKind::MethodCall(_, receiver, args, _) => match cx.typeck_results().type_dependent_def_id(e.hir_id) {
+ Some(id) => (id, Some(receiver), args),
None => return false,
},
ExprKind::Path(QPath::Resolved(None, path)) => {
@@ -156,6 +158,11 @@ fn needs_inferred_result_ty(
};
let sig = cx.tcx.fn_sig(id).skip_binder();
if let ty::Param(output_ty) = *sig.output().kind() {
+ let args: Vec<&Expr<'_>> = if let Some(receiver) = receiver {
+ std::iter::once(receiver).chain(args.iter()).collect()
+ } else {
+ args.iter().collect()
+ };
sig.inputs().iter().zip(args).all(|(&ty, arg)| {
!ty.is_param(output_ty.index) || each_value_source_needs_inference(cx, arg, locals_to_check, seen_locals)
})
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/mod.rs b/src/tools/clippy/clippy_lints/src/unit_types/mod.rs
index 6aa86a57c..546242ebd 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/mod.rs
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitTypes {
let_unit_value::check(cx, local);
}
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
unit_cmp::check(cx, expr);
unit_arg::check(cx, expr);
}
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
index 97d92f10e..a6f777abc 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
@@ -1,4 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_from_proc_macro;
use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -7,7 +8,7 @@ use rustc_lint::LateContext;
use super::{utils, UNIT_ARG};
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if expr.span.from_expansion() {
return;
}
@@ -29,26 +30,27 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
}
}
- match expr.kind {
- ExprKind::Call(_, args) | ExprKind::MethodCall(_, args, _) => {
- let args_to_recover = args
- .iter()
- .filter(|arg| {
- if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) {
- !matches!(
- &arg.kind,
- ExprKind::Match(.., MatchSource::TryDesugar) | ExprKind::Path(..)
- )
- } else {
- false
- }
- })
- .collect::<Vec<_>>();
- if !args_to_recover.is_empty() {
- lint_unit_args(cx, expr, &args_to_recover);
+ let args: Vec<_> = match expr.kind {
+ ExprKind::Call(_, args) => args.iter().collect(),
+ ExprKind::MethodCall(_, receiver, args, _) => std::iter::once(receiver).chain(args.iter()).collect(),
+ _ => return,
+ };
+
+ let args_to_recover = args
+ .into_iter()
+ .filter(|arg| {
+ if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) {
+ !matches!(
+ &arg.kind,
+ ExprKind::Match(.., MatchSource::TryDesugar) | ExprKind::Path(..)
+ )
+ } else {
+ false
}
- },
- _ => (),
+ })
+ .collect::<Vec<_>>();
+ if !args_to_recover.is_empty() && !is_from_proc_macro(cx, expr) {
+ lint_unit_args(cx, expr, args_to_recover.as_slice());
}
}
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index f4f5a4336..2c40827db 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -115,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
// Check if all return expression respect the following condition and collect them.
let mut suggs = Vec::new();
- let can_sugg = find_all_ret_expressions(cx, &body.value, |ret_expr| {
+ let can_sugg = find_all_ret_expressions(cx, body.value, |ret_expr| {
if_chain! {
if !ret_expr.span.from_expansion();
// Check if a function call.
@@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
(
ret_expr.span,
if inner_type.is_unit() {
- "".to_string()
+ String::new()
} else {
snippet(cx, arg.span.source_callsite(), "..").to_string()
}
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 04e2f301b..fb73c3866 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -137,12 +137,12 @@ fn insert_necessary_parens(pat: &mut P<Pat>) {
struct Visitor;
impl MutVisitor for Visitor {
fn visit_pat(&mut self, pat: &mut P<Pat>) {
- use ast::{BindingMode::*, Mutability::*};
+ use ast::BindingAnnotation;
noop_visit_pat(pat, self);
let target = match &mut pat.kind {
// `i @ a | b`, `box a | b`, and `& mut? a | b`.
Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p,
- Ref(p, Not) if matches!(p.kind, Ident(ByValue(Mut), ..)) => p, // `&(mut x)`
+ Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingAnnotation::MUT, ..)) => p, // `&(mut x)`
_ => return,
};
target.kind = Paren(P(take_pat(target)));
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index a832dfccc..bf487c7ca 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
) {
if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
let mut visitor = AsyncFnVisitor { cx, found_await: false };
- walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id);
+ walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
if !visitor.found_await {
span_lint_and_help(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
index 323cf83ff..b38d71784 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
check_map_error(cx, res, expr);
}
},
- hir::ExprKind::MethodCall(path, [ref arg_0, ..], _) => match path.ident.as_str() {
+ hir::ExprKind::MethodCall(path, arg_0, ..) => match path.ident.as_str() {
"expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => {
check_map_error(cx, arg_0, expr);
},
@@ -94,9 +94,9 @@ fn try_remove_await<'a>(expr: &'a hir::Expr<'a>) -> Option<&hir::Expr<'a>> {
fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
let mut call = call;
- while let hir::ExprKind::MethodCall(path, args, _) = call.kind {
+ while let hir::ExprKind::MethodCall(path, receiver, ..) = call.kind {
if matches!(path.ident.as_str(), "or" | "or_else" | "ok") {
- call = &args[0];
+ call = receiver;
} else {
break;
}
@@ -110,7 +110,7 @@ fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<
}
fn check_method_call(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>, is_await: bool) {
- if let hir::ExprKind::MethodCall(path, _, _) = call.kind {
+ if let hir::ExprKind::MethodCall(path, ..) = call.kind {
let symbol = path.ident.as_str();
let read_trait = if is_await {
match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCREADEXT)
diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
new file mode 100644
index 000000000..cc8656435
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
@@ -0,0 +1,226 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::ty::{match_type, peel_mid_ty_refs_is_mutable};
+use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, paths, peel_ref_operators};
+use rustc_ast::Mutability;
+use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::lang_items::LangItem;
+use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for the creation of a `peekable` iterator that is never `.peek()`ed
+ ///
+ /// ### Why is this bad?
+ /// Creating a peekable iterator without using any of its methods is likely a mistake,
+ /// or just a leftover after a refactor.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let collection = vec![1, 2, 3];
+ /// let iter = collection.iter().peekable();
+ ///
+ /// for item in iter {
+ /// // ...
+ /// }
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// let collection = vec![1, 2, 3];
+ /// let iter = collection.iter();
+ ///
+ /// for item in iter {
+ /// // ...
+ /// }
+ /// ```
+ #[clippy::version = "1.64.0"]
+ pub UNUSED_PEEKABLE,
+ nursery,
+ "creating a peekable iterator without using any of its methods"
+}
+
+declare_lint_pass!(UnusedPeekable => [UNUSED_PEEKABLE]);
+
+impl<'tcx> LateLintPass<'tcx> for UnusedPeekable {
+ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
+ // Don't lint `Peekable`s returned from a block
+ if let Some(expr) = block.expr
+ && let Some(ty) = cx.typeck_results().expr_ty_opt(peel_ref_operators(cx, expr))
+ && match_type(cx, ty, &paths::PEEKABLE)
+ {
+ return;
+ }
+
+ for (idx, stmt) in block.stmts.iter().enumerate() {
+ if !stmt.span.from_expansion()
+ && let StmtKind::Local(local) = stmt.kind
+ && let PatKind::Binding(_, binding, ident, _) = local.pat.kind
+ && let Some(init) = local.init
+ && !init.span.from_expansion()
+ && let Some(ty) = cx.typeck_results().expr_ty_opt(init)
+ && let (ty, _, Mutability::Mut) = peel_mid_ty_refs_is_mutable(ty)
+ && match_type(cx, ty, &paths::PEEKABLE)
+ {
+ let mut vis = PeekableVisitor::new(cx, binding);
+
+ if idx + 1 == block.stmts.len() && block.expr.is_none() {
+ return;
+ }
+
+ for stmt in &block.stmts[idx..] {
+ vis.visit_stmt(stmt);
+ }
+
+ if let Some(expr) = block.expr {
+ vis.visit_expr(expr);
+ }
+
+ if !vis.found_peek_call {
+ span_lint_and_help(
+ cx,
+ UNUSED_PEEKABLE,
+ ident.span,
+ "`peek` never called on `Peekable` iterator",
+ None,
+ "consider removing the call to `peekable`"
+ );
+ }
+ }
+ }
+ }
+}
+
+struct PeekableVisitor<'a, 'tcx> {
+ cx: &'a LateContext<'tcx>,
+ expected_hir_id: HirId,
+ found_peek_call: bool,
+}
+
+impl<'a, 'tcx> PeekableVisitor<'a, 'tcx> {
+ fn new(cx: &'a LateContext<'tcx>, expected_hir_id: HirId) -> Self {
+ Self {
+ cx,
+ expected_hir_id,
+ found_peek_call: false,
+ }
+ }
+}
+
+impl<'tcx> Visitor<'_> for PeekableVisitor<'_, 'tcx> {
+ fn visit_expr(&mut self, ex: &'_ Expr<'_>) {
+ if self.found_peek_call {
+ return;
+ }
+
+ if path_to_local_id(ex, self.expected_hir_id) {
+ for (_, node) in self.cx.tcx.hir().parent_iter(ex.hir_id) {
+ match node {
+ Node::Expr(expr) => {
+ match expr.kind {
+ // some_function(peekable)
+ //
+ // If the Peekable is passed to a function, stop
+ ExprKind::Call(_, args) => {
+ if let Some(func_did) = fn_def_id(self.cx, expr)
+ && let Ok(into_iter_did) = self
+ .cx
+ .tcx
+ .lang_items()
+ .require(LangItem::IntoIterIntoIter)
+ && func_did == into_iter_did
+ {
+ // Probably a for loop desugar, stop searching
+ return;
+ }
+
+ if args.iter().any(|arg| {
+ matches!(arg.kind, ExprKind::Path(_)) && arg_is_mut_peekable(self.cx, arg)
+ }) {
+ self.found_peek_call = true;
+ return;
+ }
+ },
+ // Catch anything taking a Peekable mutably
+ ExprKind::MethodCall(
+ PathSegment {
+ ident: method_name_ident,
+ ..
+ },
+ self_arg,
+ remaining_args,
+ _,
+ ) => {
+ let method_name = method_name_ident.name.as_str();
+
+ // `Peekable` methods
+ if matches!(method_name, "peek" | "peek_mut" | "next_if" | "next_if_eq")
+ && arg_is_mut_peekable(self.cx, self_arg)
+ {
+ self.found_peek_call = true;
+ return;
+ }
+
+ // foo.some_method() excluding Iterator methods
+ if remaining_args.iter().any(|arg| arg_is_mut_peekable(self.cx, arg))
+ && !is_trait_method(self.cx, expr, sym::Iterator)
+ {
+ self.found_peek_call = true;
+ return;
+ }
+
+ // foo.by_ref(), keep checking for `peek`
+ if method_name == "by_ref" {
+ continue;
+ }
+
+ return;
+ },
+ ExprKind::AddrOf(_, Mutability::Mut, _) | ExprKind::Unary(..) | ExprKind::DropTemps(_) => {
+ },
+ ExprKind::AddrOf(_, Mutability::Not, _) => return,
+ _ => {
+ self.found_peek_call = true;
+ return;
+ },
+ }
+ },
+ Node::Local(Local { init: Some(init), .. }) => {
+ if arg_is_mut_peekable(self.cx, init) {
+ self.found_peek_call = true;
+ return;
+ }
+
+ break;
+ },
+ Node::Stmt(stmt) => match stmt.kind {
+ StmtKind::Expr(_) | StmtKind::Semi(_) => {},
+ _ => {
+ self.found_peek_call = true;
+ return;
+ },
+ },
+ Node::Block(_) | Node::ExprField(_) => {},
+ _ => {
+ break;
+ },
+ }
+ }
+ }
+
+ walk_expr(self, ex);
+ }
+}
+
+fn arg_is_mut_peekable(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {
+ if let Some(ty) = cx.typeck_results().expr_ty_opt(arg)
+ && let (ty, _, Mutability::Mut) = peel_mid_ty_refs_is_mutable(ty)
+ && match_type(cx, ty, &paths::PEEKABLE)
+ {
+ true
+ } else {
+ false
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/unused_rounding.rs b/src/tools/clippy/clippy_lints/src/unused_rounding.rs
index 306afe441..72d8a4431 100644
--- a/src/tools/clippy/clippy_lints/src/unused_rounding.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_rounding.rs
@@ -22,7 +22,7 @@ declare_clippy_lint! {
/// ```rust
/// let x = 1f32;
/// ```
- #[clippy::version = "1.62.0"]
+ #[clippy::version = "1.63.0"]
pub UNUSED_ROUNDING,
nursery,
"Uselessly rounding a whole number floating-point literal"
diff --git a/src/tools/clippy/clippy_lints/src/unused_unit.rs b/src/tools/clippy/clippy_lints/src/unused_unit.rs
index 52585e595..cd1d90e86 100644
--- a/src/tools/clippy/clippy_lints/src/unused_unit.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_unit.rs
@@ -89,7 +89,7 @@ impl EarlyLintPass for UnusedUnit {
}
}
- fn check_poly_trait_ref(&mut self, cx: &EarlyContext<'_>, poly: &ast::PolyTraitRef, _: &ast::TraitBoundModifier) {
+ fn check_poly_trait_ref(&mut self, cx: &EarlyContext<'_>, poly: &ast::PolyTraitRef) {
let segments = &poly.trait_ref.path.segments;
if_chain! {
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index d3f9e5abf..3ef265580 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -154,13 +154,13 @@ fn collect_unwrap_info<'tcx>(
return collect_unwrap_info(cx, if_expr, expr, branch, !invert, false);
} else {
if_chain! {
- if let ExprKind::MethodCall(method_name, args, _) = &expr.kind;
- if let Some(local_id) = path_to_local(&args[0]);
- let ty = cx.typeck_results().expr_ty(&args[0]);
+ if let ExprKind::MethodCall(method_name, receiver, args, _) = &expr.kind;
+ if let Some(local_id) = path_to_local(receiver);
+ let ty = cx.typeck_results().expr_ty(receiver);
let name = method_name.ident.as_str();
if is_relevant_option_call(cx, ty, name) || is_relevant_result_call(cx, ty, name);
then {
- assert!(args.len() == 1);
+ assert!(args.is_empty());
let unwrappable = match name {
"is_some" | "is_ok" => true,
"is_err" | "is_none" => false,
@@ -231,7 +231,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
} else {
// find `unwrap[_err]()` calls:
if_chain! {
- if let ExprKind::MethodCall(method_name, [self_arg, ..], _) = expr.kind;
+ if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind;
if let Some(id) = path_to_local(self_arg);
if [sym::unwrap, sym::expect, sym!(unwrap_err)].contains(&method_name.ident.name);
let call_to_unwrap = [sym::unwrap, sym::expect].contains(&method_name.ident.name);
@@ -326,6 +326,6 @@ impl<'tcx> LateLintPass<'tcx> for Unwrap {
unwrappables: Vec::new(),
};
- walk_fn(&mut v, kind, decl, body.id(), span, fn_id);
+ walk_fn(&mut v, kind, decl, body.id(), fn_id);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
index b32be238c..46020adca 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
@@ -83,7 +83,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindExpectUnwrap<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
// check for `expect`
if let Some(arglists) = method_chain_args(expr, &["expect"]) {
- let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
+ let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();
if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option)
|| is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result)
{
@@ -93,7 +93,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindExpectUnwrap<'a, 'tcx> {
// check for `unwrap`
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
- let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
+ let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();
if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option)
|| is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result)
{
@@ -114,7 +114,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tc
typeck_results: cx.tcx.typeck(impl_item.def_id),
result: Vec::new(),
};
- fpu.visit_expr(&body.value);
+ fpu.visit_expr(body.value);
// if we've found one, lint
if !fpu.result.is_empty() {
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index fe29bf29d..f1b6463ad 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -59,17 +59,17 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
ExprKind::Ret(Some(e)) | ExprKind::Break(_, Some(e)) => e,
_ => return,
};
- if let ExprKind::Call(_, args) = e.kind {
- self.try_desugar_arm.push(args[0].hir_id);
+ if let ExprKind::Call(_, [arg, ..]) = e.kind {
+ self.try_desugar_arm.push(arg.hir_id);
}
},
- ExprKind::MethodCall(name, .., args, _) => {
+ ExprKind::MethodCall(name, recv, ..) => {
if is_trait_method(cx, e, sym::Into) && name.ident.as_str() == "into" {
let a = cx.typeck_results().expr_ty(e);
- let b = cx.typeck_results().expr_ty(&args[0]);
+ let b = cx.typeck_results().expr_ty(recv);
if same_type_and_consts(a, b) {
- let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string();
+ let sugg = snippet_with_macro_callsite(cx, recv.span, "<expr>").to_string();
span_lint_and_sugg(
cx,
USELESS_CONVERSION,
@@ -90,9 +90,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
}
}
let a = cx.typeck_results().expr_ty(e);
- let b = cx.typeck_results().expr_ty(&args[0]);
+ let b = cx.typeck_results().expr_ty(recv);
if same_type_and_consts(a, b) {
- let sugg = snippet(cx, args[0].span, "<expr>").into_owned();
+ let sugg = snippet(cx, recv.span, "<expr>").into_owned();
span_lint_and_sugg(
cx,
USELESS_CONVERSION,
@@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
if_chain! {
if is_trait_method(cx, e, sym::TryInto) && name.ident.name == sym::try_into;
let a = cx.typeck_results().expr_ty(e);
- let b = cx.typeck_results().expr_ty(&args[0]);
+ let b = cx.typeck_results().expr_ty(recv);
if is_type_diagnostic_item(cx, a, sym::Result);
if let ty::Adt(_, substs) = a.kind();
if let Some(a_type) = substs.types().next();
@@ -126,14 +126,13 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
}
},
- ExprKind::Call(path, args) => {
+ ExprKind::Call(path, [arg]) => {
if_chain! {
- if args.len() == 1;
if let ExprKind::Path(ref qpath) = path.kind;
if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
then {
let a = cx.typeck_results().expr_ty(e);
- let b = cx.typeck_results().expr_ty(&args[0]);
+ let b = cx.typeck_results().expr_ty(arg);
if_chain! {
if match_def_path(cx, def_id, &paths::TRY_FROM);
if is_type_diagnostic_item(cx, a, sym::Result);
@@ -159,7 +158,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
if same_type_and_consts(a, b);
then {
- let sugg = Sugg::hir_with_macro_callsite(cx, &args[0], "<expr>").maybe_par();
+ let sugg = Sugg::hir_with_macro_callsite(cx, arg, "<expr>").maybe_par();
let sugg_msg =
format!("consider removing `{}()`", snippet(cx, path.span, "From::from"));
span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index c0726868f..4003fff27 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -6,7 +6,9 @@ use rustc_ast::ast::{LitFloatType, LitKind};
use rustc_ast::LitIntType;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
-use rustc_hir::{ArrayLen, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
+use rustc_hir::{
+ ArrayLen, BindingAnnotation, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
+};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::{Ident, Symbol};
@@ -140,7 +142,7 @@ fn check_item(cx: &LateContext<'_>, hir_id: HirId) {
let hir = cx.tcx.hir();
if let Some(body_id) = hir.maybe_body_owned_by(hir_id.expect_owner()) {
check_node(cx, hir_id, |v| {
- v.expr(&v.bind("expr", &hir.body(body_id).value));
+ v.expr(&v.bind("expr", hir.body(body_id).value));
});
}
}
@@ -276,7 +278,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
match lit.value.node {
LitKind::Bool(val) => kind!("Bool({val:?})"),
LitKind::Char(c) => kind!("Char({c:?})"),
- LitKind::Err(val) => kind!("Err({val})"),
+ LitKind::Err => kind!("Err"),
LitKind::Byte(b) => kind!("Byte({b})"),
LitKind::Int(i, suffix) => {
let int_ty = match suffix {
@@ -402,10 +404,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
self.expr(func);
self.slice(args, |e| self.expr(e));
},
- ExprKind::MethodCall(method_name, args, _) => {
- bind!(self, method_name, args);
- kind!("MethodCall({method_name}, {args}, _)");
+ ExprKind::MethodCall(method_name, receiver, args, _) => {
+ bind!(self, method_name, receiver, args);
+ kind!("MethodCall({method_name}, {receiver}, {args}, _)");
self.ident(field!(method_name.ident));
+ self.expr(receiver);
self.slice(args, |e| self.expr(e));
},
ExprKind::Tup(elements) => {
@@ -595,7 +598,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
}
fn body(&self, body_id: &Binding<hir::BodyId>) {
- let expr = &self.cx.tcx.hir().body(body_id.value).value;
+ let expr = self.cx.tcx.hir().body(body_id.value).value;
bind!(self, expr);
out!("let {expr} = &cx.tcx.hir().body({body_id}).value;");
self.expr(expr);
@@ -609,10 +612,16 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
match pat.value.kind {
PatKind::Wild => kind!("Wild"),
- PatKind::Binding(anno, .., name, sub) => {
+ PatKind::Binding(ann, _, name, sub) => {
bind!(self, name);
opt_bind!(self, sub);
- kind!("Binding(BindingAnnotation::{anno:?}, _, {name}, {sub})");
+ let ann = match ann {
+ BindingAnnotation::NONE => "NONE",
+ BindingAnnotation::REF => "REF",
+ BindingAnnotation::MUT => "MUT",
+ BindingAnnotation::REF_MUT => "REF_MUT",
+ };
+ kind!("Binding(BindingAnnotation::{ann}, _, {name}, {sub})");
self.ident(name);
sub.if_some(|p| self.pat(p));
},
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 6e033b3be..a8500beb2 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -30,7 +30,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
"MinGW",
"CamelCase",
];
-const DEFAULT_BLACKLISTED_NAMES: &[&str] = &["foo", "baz", "quux"];
+const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"];
/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
#[derive(Clone, Debug, Deserialize)]
@@ -68,6 +68,7 @@ pub enum DisallowedType {
pub struct TryConf {
pub conf: Conf,
pub errors: Vec<Box<dyn Error>>,
+ pub warnings: Vec<Box<dyn Error>>,
}
impl TryConf {
@@ -75,6 +76,7 @@ impl TryConf {
Self {
conf: Conf::default(),
errors: vec![Box::new(error)],
+ warnings: vec![],
}
}
}
@@ -90,14 +92,14 @@ impl fmt::Display for ConfError {
impl Error for ConfError {}
-fn conf_error(s: String) -> Box<dyn Error> {
- Box::new(ConfError(s))
+fn conf_error(s: impl Into<String>) -> Box<dyn Error> {
+ Box::new(ConfError(s.into()))
}
macro_rules! define_Conf {
($(
$(#[doc = $doc:literal])+
- $(#[conf_deprecated($dep:literal)])?
+ $(#[conf_deprecated($dep:literal, $new_conf:ident)])?
($name:ident: $ty:ty = $default:expr),
)*) => {
/// Clippy lint configuration
@@ -137,17 +139,29 @@ macro_rules! define_Conf {
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapAccess<'de> {
let mut errors = Vec::new();
+ let mut warnings = Vec::new();
$(let mut $name = None;)*
// could get `Field` here directly, but get `str` first for diagnostics
while let Some(name) = map.next_key::<&str>()? {
match Field::deserialize(name.into_deserializer())? {
$(Field::$name => {
- $(errors.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)?
+ $(warnings.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)?
match map.next_value() {
Err(e) => errors.push(conf_error(e.to_string())),
Ok(value) => match $name {
Some(_) => errors.push(conf_error(format!("duplicate field `{}`", name))),
- None => $name = Some(value),
+ None => {
+ $name = Some(value);
+ // $new_conf is the same as one of the defined `$name`s, so
+ // this variable is defined in line 2 of this function.
+ $(match $new_conf {
+ Some(_) => errors.push(conf_error(concat!(
+ "duplicate field `", stringify!($new_conf),
+ "` (provided as `", stringify!($name), "`)"
+ ))),
+ None => $new_conf = $name.clone(),
+ })?
+ },
}
}
})*
@@ -156,7 +170,7 @@ macro_rules! define_Conf {
}
}
let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };
- Ok(TryConf { conf, errors })
+ Ok(TryConf { conf, errors, warnings })
}
}
@@ -194,7 +208,7 @@ define_Conf! {
/// Lint: Arithmetic.
///
/// Suppress checking of the passed type names.
- (arithmetic_allowed: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
+ (arithmetic_side_effects_allowed: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX.
///
/// Suppress lints whenever the suggested change would cause breakage for other crates.
@@ -203,12 +217,11 @@ define_Conf! {
///
/// The minimum rust version that the project supports
(msrv: Option<String> = None),
- /// Lint: BLACKLISTED_NAME.
+ /// DEPRECATED LINT: BLACKLISTED_NAME.
///
- /// The list of blacklisted names to lint about. NB: `bar` is not here since it has legitimate uses. The value
- /// `".."` can be used as part of the list to indicate, that the configured values should be appended to the
- /// default configuration of Clippy. By default any configuraction will replace the default value.
- (blacklisted_names: Vec<String> = super::DEFAULT_BLACKLISTED_NAMES.iter().map(ToString::to_string).collect()),
+ /// Use the Disallowed Names lint instead
+ #[conf_deprecated("Please use `disallowed-names` instead", disallowed_names)]
+ (blacklisted_names: Vec<String> = Vec::new()),
/// Lint: COGNITIVE_COMPLEXITY.
///
/// The maximum cognitive complexity a function can have
@@ -216,8 +229,14 @@ define_Conf! {
/// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY.
///
/// Use the Cognitive Complexity lint instead.
- #[conf_deprecated("Please use `cognitive-complexity-threshold` instead")]
- (cyclomatic_complexity_threshold: Option<u64> = None),
+ #[conf_deprecated("Please use `cognitive-complexity-threshold` instead", cognitive_complexity_threshold)]
+ (cyclomatic_complexity_threshold: u64 = 25),
+ /// Lint: DISALLOWED_NAMES.
+ ///
+ /// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
+ /// `".."` can be used as part of the list to indicate, that the configured values should be appended to the
+ /// default configuration of Clippy. By default any configuration will replace the default value.
+ (disallowed_names: Vec<String> = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()),
/// Lint: DOC_MARKDOWN.
///
/// The list of words this lint should not consider as identifiers needing ticks. The value
@@ -331,7 +350,7 @@ define_Conf! {
/// Lint: DISALLOWED_SCRIPT_IDENTS.
///
/// The list of unicode scripts allowed to be used in the scope.
- (allowed_scripts: Vec<String> = ["Latin"].iter().map(ToString::to_string).collect()),
+ (allowed_scripts: Vec<String> = vec!["Latin".to_string()]),
/// Lint: NON_SEND_FIELDS_IN_SEND_TY.
///
/// Whether to apply the raw pointer heuristic to determine if a type is `Send`.
@@ -360,6 +379,10 @@ define_Conf! {
///
/// Whether `dbg!` should be allowed in test functions
(allow_dbg_in_tests: bool = false),
+ /// Lint: RESULT_LARGE_ERR
+ ///
+ /// The maximum size of the `Err`-variant in a `Result` returned from a function
+ (large_error_threshold: u64 = 128),
}
/// Search for the configuration file.
@@ -420,7 +443,7 @@ pub fn read(path: &Path) -> TryConf {
match toml::from_str::<TryConf>(&content) {
Ok(mut conf) => {
extend_vec_if_indicator_present(&mut conf.conf.doc_valid_idents, DEFAULT_DOC_VALID_IDENTS);
- extend_vec_if_indicator_present(&mut conf.conf.blacklisted_names, DEFAULT_BLACKLISTED_NAMES);
+ extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES);
conf
},
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
index b30965329..17d9a0418 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
@@ -496,14 +496,16 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
cx,
};
let body_id = cx.tcx.hir().body_owned_by(
- impl_item_refs
- .iter()
- .find(|iiref| iiref.ident.as_str() == "get_lints")
- .expect("LintPass needs to implement get_lints")
- .id
- .hir_id(),
+ cx.tcx.hir().local_def_id(
+ impl_item_refs
+ .iter()
+ .find(|iiref| iiref.ident.as_str() == "get_lints")
+ .expect("LintPass needs to implement get_lints")
+ .id
+ .hir_id(),
+ ),
);
- collector.visit_expr(&cx.tcx.hir().body(body_id).value);
+ collector.visit_expr(cx.tcx.hir().body(body_id).value);
}
}
}
@@ -569,7 +571,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
item.span,
"this item has an invalid `clippy::version` attribute",
None,
- "please use a valid sematic version, see `doc/adding_lints.md`",
+ "please use a valid semantic version, see `doc/adding_lints.md`",
);
}
} else {
@@ -591,8 +593,8 @@ fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Opt
attrs.iter().find_map(|attr| {
if_chain! {
// Identify attribute
- if let ast::AttrKind::Normal(ref attr_kind, _) = &attr.kind;
- if let [tool_name, attr_name] = &attr_kind.path.segments[..];
+ if let ast::AttrKind::Normal(ref attr_kind) = &attr.kind;
+ if let [tool_name, attr_name] = &attr_kind.item.path.segments[..];
if tool_name.ident.name == sym::clippy;
if attr_name.ident.name == sym::version;
if let Some(version) = attr.value_str();
@@ -651,7 +653,7 @@ impl<'tcx> LateLintPass<'tcx> for CompilerLintFunctions {
}
if_chain! {
- if let ExprKind::MethodCall(path, [self_arg, ..], _) = &expr.kind;
+ if let ExprKind::MethodCall(path, self_arg, _, _) = &expr.kind;
let fn_name = path.ident;
if let Some(sugg) = self.map.get(fn_name.as_str());
let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
@@ -683,9 +685,8 @@ impl<'tcx> LateLintPass<'tcx> for OuterExpnDataPass {
let method_names: Vec<&str> = method_names.iter().map(Symbol::as_str).collect();
if_chain! {
if let ["expn_data", "outer_expn"] = method_names.as_slice();
- let args = arg_lists[1];
- if args.len() == 1;
- let self_arg = &args[0];
+ let (self_arg, args)= arg_lists[1];
+ if args.is_empty();
let self_ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
if match_type(cx, self_ty, &paths::SYNTAX_CONTEXT);
then {
@@ -732,30 +733,30 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
if and_then_args.len() == 5;
if let ExprKind::Closure(&Closure { body, .. }) = &and_then_args[4].kind;
let body = cx.tcx.hir().body(body);
- let only_expr = peel_blocks_with_stmt(&body.value);
- if let ExprKind::MethodCall(ps, span_call_args, _) = &only_expr.kind;
- if let ExprKind::Path(..) = span_call_args[0].kind;
+ let only_expr = peel_blocks_with_stmt(body.value);
+ if let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind;
+ if let ExprKind::Path(..) = recv.kind;
then {
let and_then_snippets = get_and_then_snippets(cx, and_then_args);
let mut sle = SpanlessEq::new(cx).deny_side_effects();
match ps.ident.as_str() {
- "span_suggestion" if sle.eq_expr(&and_then_args[2], &span_call_args[1]) => {
+ "span_suggestion" if sle.eq_expr(&and_then_args[2], &span_call_args[0]) => {
suggest_suggestion(cx, expr, &and_then_snippets, &span_suggestion_snippets(cx, span_call_args));
},
- "span_help" if sle.eq_expr(&and_then_args[2], &span_call_args[1]) => {
- let help_snippet = snippet(cx, span_call_args[2].span, r#""...""#);
+ "span_help" if sle.eq_expr(&and_then_args[2], &span_call_args[0]) => {
+ let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#);
suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), true);
},
- "span_note" if sle.eq_expr(&and_then_args[2], &span_call_args[1]) => {
- let note_snippet = snippet(cx, span_call_args[2].span, r#""...""#);
+ "span_note" if sle.eq_expr(&and_then_args[2], &span_call_args[0]) => {
+ let note_snippet = snippet(cx, span_call_args[1].span, r#""...""#);
suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), true);
},
"help" => {
- let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#);
+ let help_snippet = snippet(cx, span_call_args[0].span, r#""...""#);
suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), false);
}
"note" => {
- let note_snippet = snippet(cx, span_call_args[1].span, r#""...""#);
+ let note_snippet = snippet(cx, span_call_args[0].span, r#""...""#);
suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), false);
}
_ => (),
@@ -796,9 +797,9 @@ fn span_suggestion_snippets<'a, 'hir>(
cx: &LateContext<'_>,
span_call_args: &'hir [Expr<'hir>],
) -> SpanSuggestionSnippets<'a> {
- let help_snippet = snippet(cx, span_call_args[2].span, r#""...""#);
- let sugg_snippet = snippet(cx, span_call_args[3].span, "..");
- let applicability_snippet = snippet(cx, span_call_args[4].span, "Applicability::MachineApplicable");
+ let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#);
+ let sugg_snippet = snippet(cx, span_call_args[2].span, "..");
+ let applicability_snippet = snippet(cx, span_call_args[3].span, "Applicability::MachineApplicable");
SpanSuggestionSnippets {
help: help_snippet,
@@ -952,7 +953,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
if let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(def_id) {
if let ItemKind::Const(.., body_id) | ItemKind::Static(.., body_id) = item.kind {
let body = cx.tcx.hir().body(body_id);
- return path_to_matched_type(cx, &body.value);
+ return path_to_matched_type(cx, body.value);
}
}
},
@@ -1044,7 +1045,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
if el_ty.is_str();
let body = cx.tcx.hir().body(body_id);
let typeck_results = cx.tcx.typeck_body(body_id);
- if let Some(Constant::Vec(path)) = constant_simple(cx, typeck_results, &body.value);
+ if let Some(Constant::Vec(path)) = constant_simple(cx, typeck_results, body.value);
let path: Vec<&str> = path.iter().map(|x| {
if let Constant::Str(s) = x {
s.as_str()
@@ -1175,7 +1176,7 @@ impl InterningDefinedSymbol {
};
if_chain! {
// is a method call
- if let ExprKind::MethodCall(_, [item], _) = call.kind;
+ if let ExprKind::MethodCall(_, item, [], _) = call.kind;
if let Some(did) = cx.typeck_results().type_dependent_def_id(call.hir_id);
let ty = cx.typeck_results().expr_ty(item);
// ...on either an Ident or a Symbol
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index 92934c16d..342f627e3 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -619,7 +619,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
if_chain! {
// item validation
if is_lint_ref_type(cx, ty);
- // blacklist check
+ // disallow check
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
// metadata extraction
@@ -644,7 +644,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
if_chain! {
if is_deprecated_lint(cx, ty);
- // blacklist check
+ // disallow check
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
// Metadata the little we can get from a deprecated lint
@@ -797,7 +797,7 @@ fn get_lint_group_and_level_or_lint(
let result = cx.lint_store.check_lint_name(
lint_name,
Some(sym::clippy),
- &[Ident::with_dummy_span(sym::clippy)].into_iter().collect(),
+ &std::iter::once(Ident::with_dummy_span(sym::clippy)).collect(),
);
if let CheckLintNameResult::Tool(Ok(lint_lst)) = result {
if let Some(group) = get_lint_group(cx, lint_lst[0]) {
@@ -1145,8 +1145,8 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for IsMultiSpanScanner<'a, 'hir> {
self.add_single_span_suggestion();
}
},
- ExprKind::MethodCall(path, arg, _arg_span) => {
- let (self_ty, _) = walk_ptrs_ty_depth(self.cx.typeck_results().expr_ty(&arg[0]));
+ ExprKind::MethodCall(path, recv, _, _arg_span) => {
+ let (self_ty, _) = walk_ptrs_ty_depth(self.cx.typeck_results().expr_ty(recv));
if match_type(self.cx, self_ty, &paths::DIAGNOSTIC_BUILDER) {
let called_method = path.ident.name.as_str().to_string();
for (method_name, is_multi_part) in &SUGGESTION_DIAGNOSTIC_BUILDER_METHODS {
diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
index d77a21d66..bd5be0c9d 100644
--- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
@@ -100,7 +100,7 @@ impl VecPushSearcher {
|| get_parent_expr(cx, last_place)
.map_or(false, |e| matches!(e.kind, ExprKind::AddrOf(_, Mutability::Mut, _)));
},
- ExprKind::MethodCall(_, [recv, ..], _)
+ ExprKind::MethodCall(_, recv, ..)
if recv.hir_id == e.hir_id
&& adjusted_mut == Mutability::Mut
&& !adjusted_ty.peel_refs().is_slice() =>
@@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
if let Some(init_expr) = local.init
- && let PatKind::Binding(BindingAnnotation::Mutable, id, name, None) = local.pat.kind
+ && let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind
&& !in_external_macro(cx.sess(), local.span)
&& let Some(init) = get_vec_init_kind(cx, init_expr)
&& !matches!(init, VecInitKind::WithExprCapacity(_))
@@ -201,7 +201,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
if let Some(searcher) = self.searcher.take() {
if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind
- && let ExprKind::MethodCall(name, [self_arg, _], _) = expr.kind
+ && let ExprKind::MethodCall(name, self_arg, [_], _) = expr.kind
&& path_to_local_id(self_arg, searcher.local_id)
&& name.ident.as_str() == "push"
{
diff --git a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs
deleted file mode 100644
index 0fee3e812..000000000
--- a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{match_def_path, paths};
-use if_chain::if_chain;
-use rustc_ast::LitKind;
-use rustc_errors::Applicability;
-use rustc_hir as hir;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Spanned;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Finds occurrences of `Vec::resize(0, an_int)`
- ///
- /// ### Why is this bad?
- /// This is probably an argument inversion mistake.
- ///
- /// ### Example
- /// ```rust
- /// vec!(1, 2, 3, 4, 5).resize(0, 5)
- /// ```
- ///
- /// Use instead:
- /// ```rust
- /// vec!(1, 2, 3, 4, 5).clear()
- /// ```
- #[clippy::version = "1.46.0"]
- pub VEC_RESIZE_TO_ZERO,
- correctness,
- "emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake"
-}
-
-declare_lint_pass!(VecResizeToZero => [VEC_RESIZE_TO_ZERO]);
-
-impl<'tcx> LateLintPass<'tcx> for VecResizeToZero {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if_chain! {
- if let hir::ExprKind::MethodCall(path_segment, args, _) = expr.kind;
- if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
- if match_def_path(cx, method_def_id, &paths::VEC_RESIZE) && args.len() == 3;
- if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = args[1].kind;
- if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = args[2].kind;
- then {
- let method_call_span = expr.span.with_lo(path_segment.ident.span.lo());
- span_lint_and_then(
- cx,
- VEC_RESIZE_TO_ZERO,
- expr.span,
- "emptying a vector with `resize`",
- |db| {
- db.help("the arguments may be inverted...");
- db.span_suggestion(
- method_call_span,
- "...or you can empty the vector with",
- "clear()".to_string(),
- Applicability::MaybeIncorrect,
- );
- },
- );
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs b/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs
deleted file mode 100644
index 8e2ddd225..000000000
--- a/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::paths;
-use clippy_utils::ty::match_type;
-use if_chain::if_chain;
-use rustc_hir::{Expr, ExprKind, QPath};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-
-declare_clippy_lint! {
- /// ### What it does
- /// Checks for use of File::read_to_end and File::read_to_string.
- ///
- /// ### Why is this bad?
- /// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.
- /// See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)
- ///
- /// ### Example
- /// ```rust,no_run
- /// # use std::io::Read;
- /// # use std::fs::File;
- /// let mut f = File::open("foo.txt").unwrap();
- /// let mut bytes = Vec::new();
- /// f.read_to_end(&mut bytes).unwrap();
- /// ```
- /// Can be written more concisely as
- /// ```rust,no_run
- /// # use std::fs;
- /// let mut bytes = fs::read("foo.txt").unwrap();
- /// ```
- #[clippy::version = "1.44.0"]
- pub VERBOSE_FILE_READS,
- restriction,
- "use of `File::read_to_end` or `File::read_to_string`"
-}
-
-declare_lint_pass!(VerboseFileReads => [VERBOSE_FILE_READS]);
-
-impl<'tcx> LateLintPass<'tcx> for VerboseFileReads {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if is_file_read_to_end(cx, expr) {
- span_lint_and_help(
- cx,
- VERBOSE_FILE_READS,
- expr.span,
- "use of `File::read_to_end`",
- None,
- "consider using `fs::read` instead",
- );
- } else if is_file_read_to_string(cx, expr) {
- span_lint_and_help(
- cx,
- VERBOSE_FILE_READS,
- expr.span,
- "use of `File::read_to_string`",
- None,
- "consider using `fs::read_to_string` instead",
- );
- }
- }
-}
-
-fn is_file_read_to_end<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
- if_chain! {
- if let ExprKind::MethodCall(method_name, exprs, _) = expr.kind;
- if method_name.ident.as_str() == "read_to_end";
- if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind;
- let ty = cx.typeck_results().expr_ty(&exprs[0]);
- if match_type(cx, ty, &paths::FILE);
- then {
- return true
- }
- }
- false
-}
-
-fn is_file_read_to_string<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
- if_chain! {
- if let ExprKind::MethodCall(method_name, exprs, _) = expr.kind;
- if method_name.ident.as_str() == "read_to_string";
- if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind;
- let ty = cx.typeck_results().expr_ty(&exprs[0]);
- if match_type(cx, ty, &paths::FILE);
- then {
- return true
- }
- }
- false
-}
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 32718200c..640a09a7a 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -3,8 +3,9 @@ use std::iter;
use std::ops::{Deref, Range};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet_opt, snippet_with_applicability};
+use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
use rustc_ast::ast::{Expr, ExprKind, Impl, Item, ItemKind, MacCall, Path, StrLit, StrStyle};
+use rustc_ast::ptr::P;
use rustc_ast::token::{self, LitKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_errors::{Applicability, DiagnosticBuilder};
@@ -256,6 +257,28 @@ declare_clippy_lint! {
"writing a literal with a format string"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// This lint warns when a named parameter in a format string is used as a positional one.
+ ///
+ /// ### Why is this bad?
+ /// It may be confused for an assignment and obfuscates which parameter is being used.
+ ///
+ /// ### Example
+ /// ```rust
+ /// println!("{}", x = 10);
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// println!("{x}", x = 10);
+ /// ```
+ #[clippy::version = "1.63.0"]
+ pub POSITIONAL_NAMED_FORMAT_PARAMETERS,
+ suspicious,
+ "named parameter in a format string is used positionally"
+}
+
#[derive(Default)]
pub struct Write {
in_debug_impl: bool,
@@ -270,7 +293,8 @@ impl_lint_pass!(Write => [
PRINT_LITERAL,
WRITE_WITH_NEWLINE,
WRITELN_EMPTY_STRING,
- WRITE_LITERAL
+ WRITE_LITERAL,
+ POSITIONAL_NAMED_FORMAT_PARAMETERS,
]);
impl EarlyLintPass for Write {
@@ -408,6 +432,7 @@ fn newline_span(fmtstr: &StrLit) -> (Span, bool) {
#[derive(Default)]
struct SimpleFormatArgs {
unnamed: Vec<Vec<Span>>,
+ complex_unnamed: Vec<Vec<Span>>,
named: Vec<(Symbol, Vec<Span>)>,
}
impl SimpleFormatArgs {
@@ -419,6 +444,10 @@ impl SimpleFormatArgs {
})
}
+ fn get_complex_unnamed(&self) -> impl Iterator<Item = &[Span]> {
+ self.complex_unnamed.iter().map(Vec::as_slice)
+ }
+
fn get_named(&self, n: &Path) -> &[Span] {
self.named.iter().find(|x| *n == x.0).map_or(&[], |x| x.1.as_slice())
}
@@ -479,6 +508,61 @@ impl SimpleFormatArgs {
},
};
}
+
+ fn push_to_complex(&mut self, span: Span, position: usize) {
+ if self.complex_unnamed.len() <= position {
+ self.complex_unnamed.resize_with(position, Vec::new);
+ self.complex_unnamed.push(vec![span]);
+ } else {
+ let args: &mut Vec<Span> = &mut self.complex_unnamed[position];
+ args.push(span);
+ }
+ }
+
+ fn push_complex(
+ &mut self,
+ cx: &EarlyContext<'_>,
+ arg: rustc_parse_format::Argument<'_>,
+ str_lit_span: Span,
+ fmt_span: Span,
+ ) {
+ use rustc_parse_format::{ArgumentImplicitlyIs, ArgumentIs, CountIsParam, CountIsStar};
+
+ let snippet = snippet_opt(cx, fmt_span);
+
+ let end = snippet
+ .as_ref()
+ .and_then(|s| s.find(':'))
+ .or_else(|| fmt_span.hi().0.checked_sub(fmt_span.lo().0 + 1).map(|u| u as usize));
+
+ if let (ArgumentIs(n) | ArgumentImplicitlyIs(n), Some(end)) = (arg.position, end) {
+ let span = fmt_span.from_inner(InnerSpan::new(1, end));
+ self.push_to_complex(span, n);
+ };
+
+ if let (CountIsParam(n) | CountIsStar(n), Some(span)) = (arg.format.precision, arg.format.precision_span) {
+ // We need to do this hack as precision spans should be converted from .* to .foo$
+ let hack = if snippet.as_ref().and_then(|s| s.find('*')).is_some() {
+ 0
+ } else {
+ 1
+ };
+
+ let span = str_lit_span.from_inner(InnerSpan {
+ start: span.start + 1,
+ end: span.end - hack,
+ });
+ self.push_to_complex(span, n);
+ };
+
+ if let (CountIsParam(n), Some(span)) = (arg.format.width, arg.format.width_span) {
+ let span = str_lit_span.from_inner(InnerSpan {
+ start: span.start,
+ end: span.end - 1,
+ });
+ self.push_to_complex(span, n);
+ };
+ }
}
impl Write {
@@ -511,8 +595,8 @@ impl Write {
// FIXME: modify rustc's fmt string parser to give us the current span
span_lint(cx, USE_DEBUG, span, "use of `Debug`-based formatting");
}
-
args.push(arg, span);
+ args.push_complex(cx, arg, str_lit.span, span);
}
parser.errors.is_empty().then_some(args)
@@ -566,6 +650,7 @@ impl Write {
let lint = if is_write { WRITE_LITERAL } else { PRINT_LITERAL };
let mut unnamed_args = args.get_unnamed();
+ let mut complex_unnamed_args = args.get_complex_unnamed();
loop {
if !parser.eat(&token::Comma) {
return (Some(fmtstr), expr);
@@ -577,11 +662,20 @@ impl Write {
} else {
return (Some(fmtstr), None);
};
+ let complex_unnamed_arg = complex_unnamed_args.next();
+
let (fmt_spans, lit) = match &token_expr.kind {
ExprKind::Lit(lit) => (unnamed_args.next().unwrap_or(&[]), lit),
- ExprKind::Assign(lhs, rhs, _) => match (&lhs.kind, &rhs.kind) {
- (ExprKind::Path(_, p), ExprKind::Lit(lit)) => (args.get_named(p), lit),
- _ => continue,
+ ExprKind::Assign(lhs, rhs, _) => {
+ if let Some(span) = complex_unnamed_arg {
+ for x in span {
+ Self::report_positional_named_param(cx, *x, lhs, rhs);
+ }
+ }
+ match (&lhs.kind, &rhs.kind) {
+ (ExprKind::Path(_, p), ExprKind::Lit(lit)) => (args.get_named(p), lit),
+ _ => continue,
+ }
},
_ => {
unnamed_args.next();
@@ -589,12 +683,12 @@ impl Write {
},
};
- let replacement: String = match lit.token.kind {
+ let replacement: String = match lit.token_lit.kind {
LitKind::StrRaw(_) | LitKind::ByteStrRaw(_) if matches!(fmtstr.style, StrStyle::Raw(_)) => {
- lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
+ lit.token_lit.symbol.as_str().replace('{', "{{").replace('}', "}}")
},
LitKind::Str | LitKind::ByteStr if matches!(fmtstr.style, StrStyle::Cooked) => {
- lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
+ lit.token_lit.symbol.as_str().replace('{', "{{").replace('}', "}}")
},
LitKind::StrRaw(_)
| LitKind::Str
@@ -603,7 +697,7 @@ impl Write {
| LitKind::Integer
| LitKind::Float
| LitKind::Err => continue,
- LitKind::Byte | LitKind::Char => match lit.token.symbol.as_str() {
+ LitKind::Byte | LitKind::Char => match lit.token_lit.symbol.as_str() {
"\"" if matches!(fmtstr.style, StrStyle::Cooked) => "\\\"",
"\"" if matches!(fmtstr.style, StrStyle::Raw(0)) => continue,
"\\\\" if matches!(fmtstr.style, StrStyle::Raw(_)) => "\\",
@@ -614,7 +708,7 @@ impl Write {
x => x,
}
.into(),
- LitKind::Bool => lit.token.symbol.as_str().deref().into(),
+ LitKind::Bool => lit.token_lit.symbol.as_str().deref().into(),
};
if !fmt_spans.is_empty() {
@@ -637,6 +731,29 @@ impl Write {
}
}
+ fn report_positional_named_param(cx: &EarlyContext<'_>, span: Span, lhs: &P<Expr>, _rhs: &P<Expr>) {
+ if let ExprKind::Path(_, _p) = &lhs.kind {
+ let mut applicability = Applicability::MachineApplicable;
+ let name = snippet_with_applicability(cx, lhs.span, "name", &mut applicability);
+ // We need to do this hack as precision spans should be converted from .* to .foo$
+ let hack = snippet(cx, span, "").contains('*');
+
+ span_lint_and_sugg(
+ cx,
+ POSITIONAL_NAMED_FORMAT_PARAMETERS,
+ span,
+ &format!("named parameter {} is used as a positional parameter", name),
+ "replace it with",
+ if hack {
+ format!("{}$", name)
+ } else {
+ format!("{}", name)
+ },
+ applicability,
+ );
+ };
+ }
+
fn lint_println_empty_string(&self, cx: &EarlyContext<'_>, mac: &MacCall) {
if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
if fmt_str.symbol == kw::Empty {
@@ -688,7 +805,11 @@ fn check_newlines(fmtstr: &StrLit) -> bool {
let contents = fmtstr.symbol.as_str();
let mut cb = |r: Range<usize>, c: Result<char, EscapeError>| {
- let c = c.unwrap();
+ let c = match c {
+ Ok(c) => c,
+ Err(e) if !e.is_fatal() => return,
+ Err(e) => panic!("{:?}", e),
+ };
if r.end == contents.len() && c == '\n' && !last_was_cr && !has_internal_newline {
should_lint = true;
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index bb443bdc1..c36bca065 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,12 +1,13 @@
[package]
name = "clippy_utils"
-version = "0.1.64"
+version = "0.1.65"
edition = "2021"
publish = false
[dependencies]
arrayvec = { version = "0.7", default-features = false }
if_chain = "1.0"
+itertools = "0.10.1"
rustc-semver = "1.1"
[features]
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index b22602632..e84adee9d 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -693,7 +693,7 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
l.style == r.style
&& match (&l.kind, &r.kind) {
(DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,
- (Normal(l, _), Normal(r, _)) => eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args),
+ (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_mac_args(&l.item.args, &r.item.args),
_ => false,
}
}
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 186bba09d..8ab77c881 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -59,8 +59,8 @@ pub fn get_attr<'a>(
name: &'static str,
) -> impl Iterator<Item = &'a ast::Attribute> {
attrs.iter().filter(move |attr| {
- let attr = if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
- attr
+ let attr = if let ast::AttrKind::Normal(ref normal) = attr.kind {
+ &normal.item
} else {
return false;
};
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
new file mode 100644
index 000000000..7a8d4e806
--- /dev/null
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -0,0 +1,329 @@
+//! This module handles checking if the span given is from a proc-macro or not.
+//!
+//! Proc-macros are capable of setting the span of every token they output to a few possible spans.
+//! This includes spans we can detect easily as coming from a proc-macro (e.g. the call site
+//! or the def site), and spans we can't easily detect as such (e.g. the span of any token
+//! passed into the proc macro). This capability means proc-macros are capable of generating code
+//! with a span that looks like it was written by the user, but which should not be linted by clippy
+//! as it was generated by an external macro.
+//!
+//! That brings us to this module. The current approach is to determine a small bit of text which
+//! must exist at both the start and the end of an item (e.g. an expression or a path) assuming the
+//! code was written, and check if the span contains that text. Note this will only work correctly
+//! if the span is not from a `macro_rules` based macro.
+
+use rustc_ast::ast::{IntTy, LitIntType, LitKind, StrStyle, UintTy};
+use rustc_hir::{
+ intravisit::FnKind, Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId,
+ Impl, ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, Node, QPath, TraitItem,
+ TraitItemKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource,
+};
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::ty::TyCtxt;
+use rustc_session::Session;
+use rustc_span::{Span, Symbol};
+use rustc_target::spec::abi::Abi;
+
+/// The search pattern to look for. Used by `span_matches_pat`
+#[derive(Clone, Copy)]
+pub enum Pat {
+ /// A single string.
+ Str(&'static str),
+ /// Any of the given strings.
+ MultiStr(&'static [&'static str]),
+ /// The string representation of the symbol.
+ Sym(Symbol),
+ /// Any decimal or hexadecimal digit depending on the location.
+ Num,
+}
+
+/// Checks if the start and the end of the span's text matches the patterns. This will return false
+/// if the span crosses multiple files or if source is not available.
+fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) -> bool {
+ let pos = sess.source_map().lookup_byte_offset(span.lo());
+ let Some(ref src) = pos.sf.src else {
+ return false;
+ };
+ let end = span.hi() - pos.sf.start_pos;
+ src.get(pos.pos.0 as usize..end.0 as usize).map_or(false, |s| {
+ // Spans can be wrapped in a mixture or parenthesis, whitespace, and trailing commas.
+ let start_str = s.trim_start_matches(|c: char| c.is_whitespace() || c == '(');
+ let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ',');
+ (match start_pat {
+ Pat::Str(text) => start_str.starts_with(text),
+ Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
+ Pat::Sym(sym) => start_str.starts_with(sym.as_str()),
+ Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit),
+ } && match end_pat {
+ Pat::Str(text) => end_str.ends_with(text),
+ Pat::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)),
+ Pat::Sym(sym) => end_str.ends_with(sym.as_str()),
+ Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit),
+ })
+ })
+}
+
+/// Get the search patterns to use for the given literal
+fn lit_search_pat(lit: &LitKind) -> (Pat, Pat) {
+ match lit {
+ LitKind::Str(_, StrStyle::Cooked) => (Pat::Str("\""), Pat::Str("\"")),
+ LitKind::Str(_, StrStyle::Raw(0)) => (Pat::Str("r"), Pat::Str("\"")),
+ LitKind::Str(_, StrStyle::Raw(_)) => (Pat::Str("r#"), Pat::Str("#")),
+ LitKind::ByteStr(_) => (Pat::Str("b\""), Pat::Str("\"")),
+ LitKind::Byte(_) => (Pat::Str("b'"), Pat::Str("'")),
+ LitKind::Char(_) => (Pat::Str("'"), Pat::Str("'")),
+ LitKind::Int(_, LitIntType::Signed(IntTy::Isize)) => (Pat::Num, Pat::Str("isize")),
+ LitKind::Int(_, LitIntType::Unsigned(UintTy::Usize)) => (Pat::Num, Pat::Str("usize")),
+ LitKind::Int(..) => (Pat::Num, Pat::Num),
+ LitKind::Float(..) => (Pat::Num, Pat::Str("")),
+ LitKind::Bool(true) => (Pat::Str("true"), Pat::Str("true")),
+ LitKind::Bool(false) => (Pat::Str("false"), Pat::Str("false")),
+ _ => (Pat::Str(""), Pat::Str("")),
+ }
+}
+
+/// Get the search patterns to use for the given path
+fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
+ match path {
+ QPath::Resolved(ty, path) => {
+ let start = if ty.is_some() {
+ Pat::Str("<")
+ } else {
+ path.segments
+ .first()
+ .map_or(Pat::Str(""), |seg| Pat::Sym(seg.ident.name))
+ };
+ let end = path.segments.last().map_or(Pat::Str(""), |seg| {
+ if seg.args.is_some() {
+ Pat::Str(">")
+ } else {
+ Pat::Sym(seg.ident.name)
+ }
+ });
+ (start, end)
+ },
+ QPath::TypeRelative(_, name) => (Pat::Str(""), Pat::Sym(name.ident.name)),
+ QPath::LangItem(..) => (Pat::Str(""), Pat::Str("")),
+ }
+}
+
+/// Get the search patterns to use for the given expression
+fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
+ match e.kind {
+ ExprKind::Box(e) => (Pat::Str("box"), expr_search_pat(tcx, e).1),
+ ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")),
+ ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")),
+ ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1),
+ ExprKind::Unary(UnOp::Not, e) => (Pat::Str("!"), expr_search_pat(tcx, e).1),
+ ExprKind::Unary(UnOp::Neg, e) => (Pat::Str("-"), expr_search_pat(tcx, e).1),
+ ExprKind::Lit(ref lit) => lit_search_pat(&lit.node),
+ ExprKind::Array(_) | ExprKind::Repeat(..) => (Pat::Str("["), Pat::Str("]")),
+ ExprKind::Call(e, []) | ExprKind::MethodCall(_, e, [], _) => (expr_search_pat(tcx, e).0, Pat::Str("(")),
+ ExprKind::Call(first, [.., last])
+ | ExprKind::MethodCall(_, first, [.., last], _)
+ | ExprKind::Binary(_, first, last)
+ | ExprKind::Tup([first, .., last])
+ | ExprKind::Assign(first, last, _)
+ | ExprKind::AssignOp(_, first, last) => (expr_search_pat(tcx, first).0, expr_search_pat(tcx, last).1),
+ ExprKind::Tup([e]) | ExprKind::DropTemps(e) => expr_search_pat(tcx, e),
+ ExprKind::Cast(e, _) | ExprKind::Type(e, _) => (expr_search_pat(tcx, e).0, Pat::Str("")),
+ ExprKind::Let(let_expr) => (Pat::Str("let"), expr_search_pat(tcx, let_expr.init).1),
+ ExprKind::If(..) => (Pat::Str("if"), Pat::Str("}")),
+ ExprKind::Loop(_, Some(_), _, _) | ExprKind::Block(_, Some(_)) => (Pat::Str("'"), Pat::Str("}")),
+ ExprKind::Loop(_, None, LoopSource::Loop, _) => (Pat::Str("loop"), Pat::Str("}")),
+ ExprKind::Loop(_, None, LoopSource::While, _) => (Pat::Str("while"), Pat::Str("}")),
+ ExprKind::Loop(_, None, LoopSource::ForLoop, _) | ExprKind::Match(_, _, MatchSource::ForLoopDesugar) => {
+ (Pat::Str("for"), Pat::Str("}"))
+ },
+ ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str("match"), Pat::Str("}")),
+ ExprKind::Match(e, _, MatchSource::TryDesugar) => (expr_search_pat(tcx, e).0, Pat::Str("?")),
+ ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {
+ (expr_search_pat(tcx, e).0, Pat::Str("await"))
+ },
+ ExprKind::Closure(&Closure { body, .. }) => (Pat::Str(""), expr_search_pat(tcx, tcx.hir().body(body).value).1),
+ ExprKind::Block(
+ Block {
+ rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
+ ..
+ },
+ None,
+ ) => (Pat::Str("unsafe"), Pat::Str("}")),
+ ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
+ ExprKind::Field(e, name) => (expr_search_pat(tcx, e).0, Pat::Sym(name.name)),
+ ExprKind::Index(e, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
+ ExprKind::Path(ref path) => qpath_search_pat(path),
+ ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1),
+ ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),
+ ExprKind::Break(Destination { label: Some(name), .. }, None) => (Pat::Str("break"), Pat::Sym(name.ident.name)),
+ ExprKind::Break(_, Some(e)) => (Pat::Str("break"), expr_search_pat(tcx, e).1),
+ ExprKind::Continue(Destination { label: None, .. }) => (Pat::Str("continue"), Pat::Str("continue")),
+ ExprKind::Continue(Destination { label: Some(name), .. }) => (Pat::Str("continue"), Pat::Sym(name.ident.name)),
+ ExprKind::Ret(None) => (Pat::Str("return"), Pat::Str("return")),
+ ExprKind::Ret(Some(e)) => (Pat::Str("return"), expr_search_pat(tcx, e).1),
+ ExprKind::Struct(path, _, _) => (qpath_search_pat(path).0, Pat::Str("}")),
+ ExprKind::Yield(e, YieldSource::Yield) => (Pat::Str("yield"), expr_search_pat(tcx, e).1),
+ _ => (Pat::Str(""), Pat::Str("")),
+ }
+}
+
+fn fn_header_search_pat(header: FnHeader) -> Pat {
+ if header.is_async() {
+ Pat::Str("async")
+ } else if header.is_const() {
+ Pat::Str("const")
+ } else if header.is_unsafe() {
+ Pat::Str("unsafe")
+ } else if header.abi != Abi::Rust {
+ Pat::Str("extern")
+ } else {
+ Pat::MultiStr(&["fn", "extern"])
+ }
+}
+
+fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
+ let (start_pat, end_pat) = match &item.kind {
+ ItemKind::ExternCrate(_) => (Pat::Str("extern"), Pat::Str(";")),
+ ItemKind::Static(..) => (Pat::Str("static"), Pat::Str(";")),
+ ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
+ ItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
+ ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
+ ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
+ ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
+ ItemKind::Struct(VariantData::Struct(..), _) => (Pat::Str("struct"), Pat::Str("}")),
+ ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
+ ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")),
+ ItemKind::Trait(_, Unsafety::Unsafe, ..)
+ | ItemKind::Impl(Impl {
+ unsafety: Unsafety::Unsafe,
+ ..
+ }) => (Pat::Str("unsafe"), Pat::Str("}")),
+ ItemKind::Trait(IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")),
+ ItemKind::Trait(..) => (Pat::Str("trait"), Pat::Str("}")),
+ ItemKind::Impl(_) => (Pat::Str("impl"), Pat::Str("}")),
+ _ => return (Pat::Str(""), Pat::Str("")),
+ };
+ if item.vis_span.is_empty() {
+ (start_pat, end_pat)
+ } else {
+ (Pat::Str("pub"), end_pat)
+ }
+}
+
+fn trait_item_search_pat(item: &TraitItem<'_>) -> (Pat, Pat) {
+ match &item.kind {
+ TraitItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
+ TraitItemKind::Type(..) => (Pat::Str("type"), Pat::Str(";")),
+ TraitItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
+ }
+}
+
+fn impl_item_search_pat(item: &ImplItem<'_>) -> (Pat, Pat) {
+ let (start_pat, end_pat) = match &item.kind {
+ ImplItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
+ ImplItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
+ ImplItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
+ };
+ if item.vis_span.is_empty() {
+ (start_pat, end_pat)
+ } else {
+ (Pat::Str("pub"), end_pat)
+ }
+}
+
+fn field_def_search_pat(def: &FieldDef<'_>) -> (Pat, Pat) {
+ if def.vis_span.is_empty() {
+ if def.is_positional() {
+ (Pat::Str(""), Pat::Str(""))
+ } else {
+ (Pat::Sym(def.ident.name), Pat::Str(""))
+ }
+ } else {
+ (Pat::Str("pub"), Pat::Str(""))
+ }
+}
+
+fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) {
+ match v.data {
+ VariantData::Struct(..) => (Pat::Sym(v.ident.name), Pat::Str("}")),
+ VariantData::Tuple(..) => (Pat::Sym(v.ident.name), Pat::Str("")),
+ VariantData::Unit(..) => (Pat::Sym(v.ident.name), Pat::Sym(v.ident.name)),
+ }
+}
+
+fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirId) -> (Pat, Pat) {
+ let (start_pat, end_pat) = match kind {
+ FnKind::ItemFn(.., header) => (fn_header_search_pat(*header), Pat::Str("")),
+ FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")),
+ FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, body.value).1),
+ };
+ let start_pat = match tcx.hir().get(hir_id) {
+ Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => {
+ if vis_span.is_empty() {
+ start_pat
+ } else {
+ Pat::Str("pub")
+ }
+ },
+ Node::TraitItem(_) => start_pat,
+ _ => Pat::Str(""),
+ };
+ (start_pat, end_pat)
+}
+
+pub trait WithSearchPat {
+ type Context: LintContext;
+ fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat);
+ fn span(&self) -> Span;
+}
+macro_rules! impl_with_search_pat {
+ ($cx:ident: $ty:ident with $fn:ident $(($tcx:ident))?) => {
+ impl<'cx> WithSearchPat for $ty<'cx> {
+ type Context = $cx<'cx>;
+ #[allow(unused_variables)]
+ fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) {
+ $(let $tcx = cx.tcx;)?
+ $fn($($tcx,)? self)
+ }
+ fn span(&self) -> Span {
+ self.span
+ }
+ }
+ };
+}
+impl_with_search_pat!(LateContext: Expr with expr_search_pat(tcx));
+impl_with_search_pat!(LateContext: Item with item_search_pat);
+impl_with_search_pat!(LateContext: TraitItem with trait_item_search_pat);
+impl_with_search_pat!(LateContext: ImplItem with impl_item_search_pat);
+impl_with_search_pat!(LateContext: FieldDef with field_def_search_pat);
+impl_with_search_pat!(LateContext: Variant with variant_search_pat);
+
+impl<'cx> WithSearchPat for (&FnKind<'cx>, &Body<'cx>, HirId, Span) {
+ type Context = LateContext<'cx>;
+
+ fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) {
+ fn_kind_pat(cx.tcx, self.0, self.1, self.2)
+ }
+
+ fn span(&self) -> Span {
+ self.3
+ }
+}
+
+/// Checks if the item likely came from a proc-macro.
+///
+/// This should be called after `in_external_macro` and the initial pattern matching of the ast as
+/// it is significantly slower than both of those.
+pub fn is_from_proc_macro<T: WithSearchPat>(cx: &T::Context, item: &T) -> bool {
+ let (start_pat, end_pat) = item.search_pat(cx);
+ !span_matches_pat(cx.sess(), item.span(), start_pat, end_pat)
+}
+
+/// Checks if the span actually refers to a match expression
+pub fn is_span_match(cx: &impl LintContext, span: Span) -> bool {
+ span_matches_pat(cx.sess(), span, Pat::Str("match"), Pat::Str("}"))
+}
+
+/// Checks if the span actually refers to an if expression
+pub fn is_span_if(cx: &impl LintContext, span: Span) -> bool {
+ span_matches_pat(cx.sess(), span, Pat::Str("if"), Pat::Str("}"))
+}
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 351a3f4ae..e053708ed 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -45,7 +45,7 @@ pub enum Constant {
/// A reference
Ref(Box<Constant>),
/// A literal with syntax error.
- Err(Symbol),
+ Err,
}
impl PartialEq for Constant {
@@ -118,9 +118,7 @@ impl Hash for Constant {
Self::Ref(ref r) => {
r.hash(state);
},
- Self::Err(ref s) => {
- s.hash(state);
- },
+ Self::Err => {},
}
}
}
@@ -194,7 +192,7 @@ pub fn lit_to_mir_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
_ => bug!(),
},
LitKind::Bool(b) => Constant::Bool(b),
- LitKind::Err(s) => Constant::Err(s),
+ LitKind::Err => Constant::Err,
}
}
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 7f55db3b3..ad95369b9 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -155,13 +155,7 @@ where
});
}
-pub fn span_lint_hir(
- cx: &LateContext<'_>,
- lint: &'static Lint,
- hir_id: HirId,
- sp: Span,
- msg: &str,
-) {
+pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) {
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| {
let mut diag = diag.build(msg);
docs_link(&mut diag, lint);
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 730724b95..91c9c382c 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -45,12 +45,7 @@ impl ops::BitOrAssign for EagernessSuggestion {
}
/// Determine the eagerness of the given function call.
-fn fn_eagerness<'tcx>(
- cx: &LateContext<'tcx>,
- fn_id: DefId,
- name: Symbol,
- args: &'tcx [Expr<'_>],
-) -> EagernessSuggestion {
+fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: bool) -> EagernessSuggestion {
use EagernessSuggestion::{Eager, Lazy, NoChange};
let name = name.as_str();
@@ -59,7 +54,7 @@ fn fn_eagerness<'tcx>(
None => return Lazy,
};
- if (name.starts_with("as_") || name == "len" || name == "is_empty") && args.len() == 1 {
+ if (name.starts_with("as_") || name == "len" || name == "is_empty") && have_one_arg {
if matches!(
cx.tcx.crate_name(fn_id.krate),
sym::std | sym::core | sym::alloc | sym::proc_macro
@@ -127,10 +122,11 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
},
Res::Def(_, id) => match path {
QPath::Resolved(_, p) => {
- self.eagerness |= fn_eagerness(self.cx, id, p.segments.last().unwrap().ident.name, args);
+ self.eagerness |=
+ fn_eagerness(self.cx, id, p.segments.last().unwrap().ident.name, !args.is_empty());
},
QPath::TypeRelative(_, name) => {
- self.eagerness |= fn_eagerness(self.cx, id, name.ident.name, args);
+ self.eagerness |= fn_eagerness(self.cx, id, name.ident.name, !args.is_empty());
},
QPath::LangItem(..) => self.eagerness = Lazy,
},
@@ -141,12 +137,12 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
self.eagerness |= NoChange;
return;
},
- ExprKind::MethodCall(name, args, _) => {
+ ExprKind::MethodCall(name, ..) => {
self.eagerness |= self
.cx
.typeck_results()
.type_dependent_def_id(e.hir_id)
- .map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, args));
+ .map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true));
},
ExprKind::Index(_, e) => {
let ty = self.cx.typeck_results().expr_ty_adjusted(e);
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 1834e2a2d..7212d9cd7 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -6,9 +6,9 @@ use rustc_data_structures::fx::FxHasher;
use rustc_hir::def::Res;
use rustc_hir::HirIdMap;
use rustc_hir::{
- ArrayLen, BinOpKind, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard,
- HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath,
- Stmt, StmtKind, Ty, TyKind, TypeBinding,
+ ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
+ GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path,
+ PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
};
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::LateContext;
@@ -201,8 +201,8 @@ impl HirEqInterExpr<'_, '_, '_> {
self.inner.cx.tcx.typeck_body(right),
));
let res = self.eq_expr(
- &self.inner.cx.tcx.hir().body(left).value,
- &self.inner.cx.tcx.hir().body(right).value,
+ self.inner.cx.tcx.hir().body(left).value,
+ self.inner.cx.tcx.hir().body(right).value,
);
self.inner.maybe_typeck_results = old_maybe_typeck_results;
res
@@ -282,8 +282,14 @@ impl HirEqInterExpr<'_, '_, '_> {
&& self.eq_expr(l.body, r.body)
})
},
- (&ExprKind::MethodCall(l_path, l_args, _), &ExprKind::MethodCall(r_path, r_args, _)) => {
- self.inner.allow_side_effects && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args)
+ (
+ &ExprKind::MethodCall(l_path, l_receiver, l_args, _),
+ &ExprKind::MethodCall(r_path, r_receiver, r_args, _),
+ ) => {
+ self.inner.allow_side_effects
+ && self.eq_path_segment(l_path, r_path)
+ && self.eq_expr(l_receiver, r_receiver)
+ && self.eq_exprs(l_args, r_args)
},
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
@@ -643,7 +649,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
}) => {
std::mem::discriminant(&capture_clause).hash(&mut self.s);
// closures inherit TypeckResults
- self.hash_expr(&self.cx.tcx.hir().body(body).value);
+ self.hash_expr(self.cx.tcx.hir().body(body).value);
},
ExprKind::Field(e, ref f) => {
self.hash_expr(e);
@@ -743,8 +749,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
s.hash(&mut self.s);
},
- ExprKind::MethodCall(path, args, ref _fn_span) => {
+ ExprKind::MethodCall(path, receiver, args, ref _fn_span) => {
self.hash_name(path.ident.name);
+ self.hash_expr(receiver);
self.hash_exprs(args);
},
ExprKind::ConstBlock(ref l_id) => {
@@ -815,8 +822,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
pub fn hash_pat(&mut self, pat: &Pat<'_>) {
std::mem::discriminant(&pat.kind).hash(&mut self.s);
match pat.kind {
- PatKind::Binding(ann, _, _, pat) => {
- std::mem::discriminant(&ann).hash(&mut self.s);
+ PatKind::Binding(BindingAnnotation(by_ref, mutability), _, _, pat) => {
+ std::mem::discriminant(&by_ref).hash(&mut self.s);
+ std::mem::discriminant(&mutability).hash(&mut self.s);
if let Some(pat) = pat {
self.hash_pat(pat);
}
@@ -921,7 +929,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
}
}
- pub fn hash_lifetime(&mut self, lifetime: Lifetime) {
+ pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
std::mem::discriminant(&lifetime.name).hash(&mut self.s);
if let LifetimeName::Param(param_id, ref name) = lifetime.name {
std::mem::discriminant(name).hash(&mut self.s);
@@ -979,8 +987,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
}
},
TyKind::Path(ref qpath) => self.hash_qpath(qpath),
- TyKind::OpaqueDef(_, arg_list) => {
+ TyKind::OpaqueDef(_, arg_list, in_trait) => {
self.hash_generic_args(arg_list);
+ in_trait.hash(&mut self.s);
},
TyKind::TraitObject(_, lifetime, _) => {
self.hash_lifetime(*lifetime);
@@ -1002,7 +1011,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
pub fn hash_body(&mut self, body_id: BodyId) {
// swap out TypeckResults when hashing a body
let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id));
- self.hash_expr(&self.cx.tcx.hir().body(body_id).value);
+ self.hash_expr(self.cx.tcx.hir().body(body_id).value);
self.maybe_typeck_results = old_maybe_typeck_results;
}
@@ -1010,7 +1019,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
for arg in arg_list {
match *arg {
GenericArg::Lifetime(l) => self.hash_lifetime(l),
- GenericArg::Type(ref ty) => self.hash_ty(ty),
+ GenericArg::Type(ty) => self.hash_ty(ty),
GenericArg::Const(ref ca) => self.hash_body(ca.value.body),
GenericArg::Infer(ref inf) => self.hash_ty(&inf.to_ty()),
}
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 8322df862..62da850a1 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1,9 +1,9 @@
#![feature(array_chunks)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
-#![feature(let_else)]
#![feature(let_chains)]
#![feature(lint_reasons)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![feature(rustc_private)]
#![recursion_limit = "512"]
@@ -28,6 +28,7 @@ extern crate rustc_infer;
extern crate rustc_lexer;
extern crate rustc_lint;
extern crate rustc_middle;
+extern crate rustc_parse_format;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;
@@ -39,6 +40,7 @@ pub mod sym_helper;
pub mod ast_utils;
pub mod attrs;
+mod check_proc_macro;
pub mod comparisons;
pub mod consts;
pub mod diagnostics;
@@ -59,6 +61,7 @@ pub mod usage;
pub mod visitors;
pub use self::attrs::*;
+pub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};
pub use self::hir_utils::{
both, count_eq, eq_expr_value, hash_expr, hash_stmt, over, HirEqInterExpr, SpanlessEq, SpanlessHash,
};
@@ -85,6 +88,7 @@ use rustc_hir::{
Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
TraitRef, TyKind, UnOp,
};
+use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, Level, Lint, LintContext};
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::ty as rustc_ty;
@@ -102,6 +106,7 @@ use rustc_semver::RustcVersion;
use rustc_session::Session;
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::original_sp;
+use rustc_span::source_map::SourceMap;
use rustc_span::sym;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{Span, DUMMY_SP};
@@ -187,7 +192,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<
let hir = cx.tcx.hir();
if_chain! {
if let Some(Node::Pat(pat)) = hir.find(hir_id);
- if matches!(pat.kind, PatKind::Binding(BindingAnnotation::Unannotated, ..));
+ if matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..));
let parent = hir.get_parent_node(hir_id);
if let Some(Node::Local(local)) = hir.find(parent);
then {
@@ -332,7 +337,7 @@ pub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tc
.map_or(&[][..], |a| a.args)
.iter()
.filter_map(|a| match a {
- hir::GenericArg::Type(ty) => Some(ty),
+ hir::GenericArg::Type(ty) => Some(*ty),
_ => None,
})
}
@@ -370,15 +375,19 @@ pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool {
/// If the expression is a path, resolves it to a `DefId` and checks if it matches the given path.
///
-/// Please use `is_expr_diagnostic_item` if the target is a diagnostic item.
+/// Please use `is_path_diagnostic_item` if the target is a diagnostic item.
pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[&str]) -> bool {
path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, segments))
}
-/// If the expression is a path, resolves it to a `DefId` and checks if it matches the given
-/// diagnostic item.
-pub fn is_expr_diagnostic_item(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool {
- path_def_id(cx, expr).map_or(false, |id| cx.tcx.is_diagnostic_item(diag_item, id))
+/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
+/// it matches the given diagnostic item.
+pub fn is_path_diagnostic_item<'tcx>(
+ cx: &LateContext<'_>,
+ maybe_path: &impl MaybePath<'tcx>,
+ diag_item: Symbol,
+) -> bool {
+ path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.is_diagnostic_item(diag_item, id))
}
/// THIS METHOD IS DEPRECATED and will eventually be removed since it does not match against the
@@ -1022,26 +1031,26 @@ pub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'
v.allow_closure.then_some(v.captures)
}
+/// Arguments of a method: the receiver and all the additional arguments.
+pub type MethodArguments<'tcx> = Vec<(&'tcx Expr<'tcx>, &'tcx [Expr<'tcx>])>;
+
/// Returns the method names and argument list of nested method call expressions that make up
/// `expr`. method/span lists are sorted with the most recent call first.
-pub fn method_calls<'tcx>(
- expr: &'tcx Expr<'tcx>,
- max_depth: usize,
-) -> (Vec<Symbol>, Vec<&'tcx [Expr<'tcx>]>, Vec<Span>) {
+pub fn method_calls<'tcx>(expr: &'tcx Expr<'tcx>, max_depth: usize) -> (Vec<Symbol>, MethodArguments<'tcx>, Vec<Span>) {
let mut method_names = Vec::with_capacity(max_depth);
let mut arg_lists = Vec::with_capacity(max_depth);
let mut spans = Vec::with_capacity(max_depth);
let mut current = expr;
for _ in 0..max_depth {
- if let ExprKind::MethodCall(path, args, _) = &current.kind {
- if args.iter().any(|e| e.span.from_expansion()) {
+ if let ExprKind::MethodCall(path, receiver, args, _) = &current.kind {
+ if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) {
break;
}
method_names.push(path.ident.name);
- arg_lists.push(&**args);
+ arg_lists.push((*receiver, &**args));
spans.push(path.ident.span);
- current = &args[0];
+ current = receiver;
} else {
break;
}
@@ -1056,18 +1065,18 @@ pub fn method_calls<'tcx>(
/// `method_chain_args(expr, &["bar", "baz"])` will return a `Vec`
/// containing the `Expr`s for
/// `.bar()` and `.baz()`
-pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec<&'a [Expr<'a>]>> {
+pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec<(&'a Expr<'a>, &'a [Expr<'a>])>> {
let mut current = expr;
let mut matched = Vec::with_capacity(methods.len());
for method_name in methods.iter().rev() {
// method chains are stored last -> first
- if let ExprKind::MethodCall(path, args, _) = current.kind {
+ if let ExprKind::MethodCall(path, receiver, args, _) = current.kind {
if path.ident.name.as_str() == *method_name {
- if args.iter().any(|e| e.span.from_expansion()) {
+ if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) {
return None;
}
- matched.push(args); // build up `matched` backwards
- current = &args[0]; // go to parent expression
+ matched.push((receiver, args)); // build up `matched` backwards
+ current = receiver; // go to parent expression
} else {
return None;
}
@@ -1112,7 +1121,7 @@ pub struct ContainsName {
}
impl<'tcx> Visitor<'tcx> for ContainsName {
- fn visit_name(&mut self, _: Span, name: Symbol) {
+ fn visit_name(&mut self, name: Symbol) {
if self.name == name {
self.result = true;
}
@@ -1230,8 +1239,10 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
ty_is_fn_once_param(cx.tcx, ty.skip_binder(), predicates).then_some(())
})
},
- ExprKind::MethodCall(_, args, _) => {
- let i = args.iter().position(|arg| arg.hir_id == id)?;
+ ExprKind::MethodCall(_, receiver, args, _) => {
+ let i = std::iter::once(receiver)
+ .chain(args.iter())
+ .position(|arg| arg.hir_id == id)?;
let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i];
ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(())
@@ -1541,7 +1552,8 @@ pub fn iter_input_pats<'tcx>(decl: &FnDecl<'_>, body: &'tcx Body<'_>) -> impl It
pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
fn is_ok(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
if_chain! {
- if let PatKind::TupleStruct(ref path, pat, None) = arm.pat.kind;
+ if let PatKind::TupleStruct(ref path, pat, ddpos) = arm.pat.kind;
+ if ddpos.as_opt_usize().is_none();
if is_lang_ctor(cx, path, ResultOk);
if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind;
if path_to_local_id(arm.body, hir_id);
@@ -1803,7 +1815,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool
}
};
- let mut expr = &func.value;
+ let mut expr = func.value;
loop {
match expr.kind {
#[rustfmt::skip]
@@ -1892,8 +1904,8 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
- if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
- attr.path == sym::no_std
+ if let ast::AttrKind::Normal(ref normal) = attr.kind {
+ normal.item.path == sym::no_std
} else {
false
}
@@ -1902,8 +1914,8 @@ pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
- if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
- attr.path == sym::no_core
+ if let ast::AttrKind::Normal(ref normal) = attr.kind {
+ normal.item.path == sym::no_core
} else {
false
}
@@ -2272,6 +2284,18 @@ pub fn walk_to_expr_usage<'tcx, T>(
None
}
+/// Checks whether a given span has any comment token
+/// This checks for all types of comment: line "//", block "/**", doc "///" "//!"
+pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
+ let Ok(snippet) = sm.span_to_snippet(span) else { return false };
+ return tokenize(&snippet).any(|token| {
+ matches!(
+ token.kind,
+ TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }
+ )
+ });
+}
+
macro_rules! op_utils {
($($name:ident $assign:ident)*) => {
/// Binary operation traits like `LangItem::Add`
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index a268e339b..bd89ff977 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -1,16 +1,21 @@
#![allow(clippy::similar_names)] // `expr` and `expn`
+use crate::is_path_diagnostic_item;
+use crate::source::snippet_opt;
use crate::visitors::expr_visitor_no_bodies;
use arrayvec::ArrayVec;
-use if_chain::if_chain;
+use itertools::{izip, Either, Itertools};
use rustc_ast::ast::LitKind;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
+use rustc_lexer::unescape::unescape_literal;
+use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
use rustc_lint::LateContext;
+use rustc_parse_format::{self as rpf, Alignment};
use rustc_span::def_id::DefId;
use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
-use rustc_span::{sym, ExpnData, ExpnId, ExpnKind, Span, Symbol};
+use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Pos, Span, SpanData, Symbol};
use std::ops::ControlFlow;
const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
@@ -332,121 +337,497 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) ->
}
}
-/// A parsed `format_args!` expansion
+/// The format string doesn't exist in the HIR, so we reassemble it from source code
#[derive(Debug)]
-pub struct FormatArgsExpn<'tcx> {
- /// Span of the first argument, the format string
- pub format_string_span: Span,
- /// The format string split by formatted args like `{..}`
- pub format_string_parts: Vec<Symbol>,
- /// Values passed after the format string
- pub value_args: Vec<&'tcx Expr<'tcx>>,
- /// Each element is a `value_args` index and a formatting trait (e.g. `sym::Debug`)
- pub formatters: Vec<(usize, Symbol)>,
- /// List of `fmt::v1::Argument { .. }` expressions. If this is empty,
- /// then `formatters` represents the format args (`{..}`).
- /// If this is non-empty, it represents the format args, and the `position`
- /// parameters within the struct expressions are indexes of `formatters`.
- pub specs: Vec<&'tcx Expr<'tcx>>,
+pub struct FormatString {
+ /// Span of the whole format string literal, including `[r#]"`.
+ pub span: Span,
+ /// Snippet of the whole format string literal, including `[r#]"`.
+ pub snippet: String,
+ /// If the string is raw `r"..."`/`r#""#`, how many `#`s does it have on each side.
+ pub style: Option<usize>,
+ /// The unescaped value of the format string, e.g. `"val – {}"` for the literal
+ /// `"val \u{2013} {}"`.
+ pub unescaped: String,
+ /// The format string split by format args like `{..}`.
+ pub parts: Vec<Symbol>,
}
-impl<'tcx> FormatArgsExpn<'tcx> {
- /// Parses an expanded `format_args!` or `format_args_nl!` invocation
- pub fn parse(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<Self> {
- macro_backtrace(expr.span).find(|macro_call| {
- matches!(
- cx.tcx.item_name(macro_call.def_id),
- sym::const_format_args | sym::format_args | sym::format_args_nl
- )
- })?;
- let mut format_string_span: Option<Span> = None;
- let mut format_string_parts: Vec<Symbol> = Vec::new();
- let mut value_args: Vec<&Expr<'_>> = Vec::new();
- let mut formatters: Vec<(usize, Symbol)> = Vec::new();
- let mut specs: Vec<&Expr<'_>> = Vec::new();
- expr_visitor_no_bodies(|e| {
- // if we're still inside of the macro definition...
- if e.span.ctxt() == expr.span.ctxt() {
- // ArgumentV1::new_<format_trait>(<value>)
- if_chain! {
- if let ExprKind::Call(callee, [val]) = e.kind;
- if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = callee.kind;
- if let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
- if path.segments.last().unwrap().ident.name == sym::ArgumentV1;
- if seg.ident.name.as_str().starts_with("new_");
- then {
- let val_idx = if_chain! {
- if val.span.ctxt() == expr.span.ctxt();
- if let ExprKind::Field(_, field) = val.kind;
- if let Ok(idx) = field.name.as_str().parse();
- then {
- // tuple index
- idx
- } else {
- // assume the value expression is passed directly
- formatters.len()
- }
- };
- let fmt_trait = match seg.ident.name.as_str() {
- "new_display" => "Display",
- "new_debug" => "Debug",
- "new_lower_exp" => "LowerExp",
- "new_upper_exp" => "UpperExp",
- "new_octal" => "Octal",
- "new_pointer" => "Pointer",
- "new_binary" => "Binary",
- "new_lower_hex" => "LowerHex",
- "new_upper_hex" => "UpperHex",
- _ => unreachable!(),
- };
- formatters.push((val_idx, Symbol::intern(fmt_trait)));
- }
- }
- if let ExprKind::Struct(QPath::Resolved(_, path), ..) = e.kind {
- if path.segments.last().unwrap().ident.name == sym::Argument {
- specs.push(e);
- }
+impl FormatString {
+ fn new(cx: &LateContext<'_>, pieces: &Expr<'_>) -> Option<Self> {
+ // format_args!(r"a {} b \", 1);
+ //
+ // expands to
+ //
+ // ::core::fmt::Arguments::new_v1(&["a ", " b \\"],
+ // &[::core::fmt::ArgumentV1::new_display(&1)]);
+ //
+ // where `pieces` is the expression `&["a ", " b \\"]`. It has the span of `r"a {} b \"`
+ let span = pieces.span;
+ let snippet = snippet_opt(cx, span)?;
+
+ let (inner, style) = match tokenize(&snippet).next()?.kind {
+ TokenKind::Literal { kind, .. } => {
+ let style = match kind {
+ LiteralKind::Str { .. } => None,
+ LiteralKind::RawStr { n_hashes: Some(n), .. } => Some(n.into()),
+ _ => return None,
+ };
+
+ let start = style.map_or(1, |n| 2 + n);
+ let end = snippet.len() - style.map_or(1, |n| 1 + n);
+
+ (&snippet[start..end], style)
+ },
+ _ => return None,
+ };
+
+ let mode = if style.is_some() {
+ unescape::Mode::RawStr
+ } else {
+ unescape::Mode::Str
+ };
+
+ let mut unescaped = String::with_capacity(inner.len());
+ unescape_literal(inner, mode, &mut |_, ch| match ch {
+ Ok(ch) => unescaped.push(ch),
+ Err(e) if !e.is_fatal() => (),
+ Err(e) => panic!("{:?}", e),
+ });
+
+ let mut parts = Vec::new();
+ expr_visitor_no_bodies(|expr| {
+ if let ExprKind::Lit(lit) = &expr.kind {
+ if let LitKind::Str(symbol, _) = lit.node {
+ parts.push(symbol);
}
- // walk through the macro expansion
- return true;
}
- // assume that the first expr with a differing context represents
- // (and has the span of) the format string
- if format_string_span.is_none() {
- format_string_span = Some(e.span);
- let span = e.span;
- // walk the expr and collect string literals which are format string parts
- expr_visitor_no_bodies(|e| {
- if e.span.ctxt() != span.ctxt() {
- // defensive check, probably doesn't happen
- return false;
- }
- if let ExprKind::Lit(lit) = &e.kind {
- if let LitKind::Str(symbol, _s) = lit.node {
- format_string_parts.push(symbol);
- }
- }
- true
- })
- .visit_expr(e);
+
+ true
+ })
+ .visit_expr(pieces);
+
+ Some(Self {
+ span,
+ snippet,
+ style,
+ unescaped,
+ parts,
+ })
+ }
+}
+
+struct FormatArgsValues<'tcx> {
+ /// See `FormatArgsExpn::value_args`
+ value_args: Vec<&'tcx Expr<'tcx>>,
+ /// Maps an `rt::v1::Argument::position` or an `rt::v1::Count::Param` to its index in
+ /// `value_args`
+ pos_to_value_index: Vec<usize>,
+ /// Used to check if a value is declared inline & to resolve `InnerSpan`s.
+ format_string_span: SpanData,
+}
+
+impl<'tcx> FormatArgsValues<'tcx> {
+ fn new(args: &'tcx Expr<'tcx>, format_string_span: SpanData) -> Self {
+ let mut pos_to_value_index = Vec::new();
+ let mut value_args = Vec::new();
+ expr_visitor_no_bodies(|expr| {
+ if expr.span.ctxt() == args.span.ctxt() {
+ // ArgumentV1::new_<format_trait>(<val>)
+ // ArgumentV1::from_usize(<val>)
+ if let ExprKind::Call(callee, [val]) = expr.kind
+ && let ExprKind::Path(QPath::TypeRelative(ty, _)) = callee.kind
+ && let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind
+ && path.segments.last().unwrap().ident.name == sym::ArgumentV1
+ {
+ let val_idx = if val.span.ctxt() == expr.span.ctxt()
+ && let ExprKind::Field(_, field) = val.kind
+ && let Ok(idx) = field.name.as_str().parse()
+ {
+ // tuple index
+ idx
+ } else {
+ // assume the value expression is passed directly
+ pos_to_value_index.len()
+ };
+
+ pos_to_value_index.push(val_idx);
+ }
+
+ true
} else {
- // assume that any further exprs with a differing context are value args
- value_args.push(e);
+ // assume that any expr with a differing span is a value
+ value_args.push(expr);
+
+ false
}
- // don't walk anything not from the macro expansion (e.a. inputs)
- false
})
- .visit_expr(expr);
- Some(FormatArgsExpn {
- format_string_span: format_string_span?,
- format_string_parts,
+ .visit_expr(args);
+
+ Self {
value_args,
- formatters,
- specs,
+ pos_to_value_index,
+ format_string_span,
+ }
+ }
+}
+
+/// The positions of a format argument's value, precision and width
+///
+/// A position is an index into the second argument of `Arguments::new_v1[_formatted]`
+#[derive(Debug, Default, Copy, Clone)]
+struct ParamPosition {
+ /// The position stored in `rt::v1::Argument::position`.
+ value: usize,
+ /// The position stored in `rt::v1::FormatSpec::width` if it is a `Count::Param`.
+ width: Option<usize>,
+ /// The position stored in `rt::v1::FormatSpec::precision` if it is a `Count::Param`.
+ precision: Option<usize>,
+}
+
+/// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
+fn parse_rt_fmt<'tcx>(fmt_arg: &'tcx Expr<'tcx>) -> Option<impl Iterator<Item = ParamPosition> + 'tcx> {
+ fn parse_count(expr: &Expr<'_>) -> Option<usize> {
+ // ::core::fmt::rt::v1::Count::Param(1usize),
+ if let ExprKind::Call(ctor, [val]) = expr.kind
+ && let ExprKind::Path(QPath::Resolved(_, path)) = ctor.kind
+ && path.segments.last()?.ident.name == sym::Param
+ && let ExprKind::Lit(lit) = &val.kind
+ && let LitKind::Int(pos, _) = lit.node
+ {
+ Some(pos as usize)
+ } else {
+ None
+ }
+ }
+
+ if let ExprKind::AddrOf(.., array) = fmt_arg.kind
+ && let ExprKind::Array(specs) = array.kind
+ {
+ Some(specs.iter().map(|spec| {
+ let mut position = ParamPosition::default();
+
+ // ::core::fmt::rt::v1::Argument {
+ // position: 0usize,
+ // format: ::core::fmt::rt::v1::FormatSpec {
+ // ..
+ // precision: ::core::fmt::rt::v1::Count::Implied,
+ // width: ::core::fmt::rt::v1::Count::Implied,
+ // },
+ // }
+
+ // TODO: this can be made much nicer next sync with `Visitor::visit_expr_field`
+ if let ExprKind::Struct(_, fields, _) = spec.kind {
+ for field in fields {
+ match (field.ident.name, &field.expr.kind) {
+ (sym::position, ExprKind::Lit(lit)) => {
+ if let LitKind::Int(pos, _) = lit.node {
+ position.value = pos as usize;
+ }
+ },
+ (sym::format, &ExprKind::Struct(_, spec_fields, _)) => {
+ for spec_field in spec_fields {
+ match spec_field.ident.name {
+ sym::precision => {
+ position.precision = parse_count(spec_field.expr);
+ },
+ sym::width => {
+ position.width = parse_count(spec_field.expr);
+ },
+ _ => {},
+ }
+ }
+ },
+ _ => {},
+ }
+ }
+ }
+
+ position
+ }))
+ } else {
+ None
+ }
+}
+
+/// `Span::from_inner`, but for `rustc_parse_format`'s `InnerSpan`
+fn span_from_inner(base: SpanData, inner: rpf::InnerSpan) -> Span {
+ Span::new(
+ base.lo + BytePos::from_usize(inner.start),
+ base.lo + BytePos::from_usize(inner.end),
+ base.ctxt,
+ base.parent,
+ )
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum FormatParamKind {
+ /// An implicit parameter , such as `{}` or `{:?}`.
+ Implicit,
+ /// A parameter with an explicit number, or an asterisk precision. e.g. `{1}`, `{0:?}`,
+ /// `{:.0$}` or `{:.*}`.
+ Numbered,
+ /// A named parameter with a named `value_arg`, such as the `x` in `format!("{x}", x = 1)`.
+ Named(Symbol),
+ /// An implicit named parameter, such as the `y` in `format!("{y}")`.
+ NamedInline(Symbol),
+}
+
+/// A `FormatParam` is any place in a `FormatArgument` that refers to a supplied value, e.g.
+///
+/// ```
+/// let precision = 2;
+/// format!("{:.precision$}", 0.1234);
+/// ```
+///
+/// has two `FormatParam`s, a [`FormatParamKind::Implicit`] `.kind` with a `.value` of `0.1234`
+/// and a [`FormatParamKind::NamedInline("precision")`] `.kind` with a `.value` of `2`
+#[derive(Debug, Copy, Clone)]
+pub struct FormatParam<'tcx> {
+ /// The expression this parameter refers to.
+ pub value: &'tcx Expr<'tcx>,
+ /// How this parameter refers to its `value`.
+ pub kind: FormatParamKind,
+ /// Span of the parameter, may be zero width. Includes the whitespace of implicit parameters.
+ ///
+ /// ```text
+ /// format!("{}, { }, {0}, {name}", ...);
+ /// ^ ~~ ~ ~~~~
+ /// ```
+ pub span: Span,
+}
+
+impl<'tcx> FormatParam<'tcx> {
+ fn new(
+ mut kind: FormatParamKind,
+ position: usize,
+ inner: rpf::InnerSpan,
+ values: &FormatArgsValues<'tcx>,
+ ) -> Option<Self> {
+ let value_index = *values.pos_to_value_index.get(position)?;
+ let value = *values.value_args.get(value_index)?;
+ let span = span_from_inner(values.format_string_span, inner);
+
+ // if a param is declared inline, e.g. `format!("{x}")`, the generated expr's span points
+ // into the format string
+ if let FormatParamKind::Named(name) = kind && values.format_string_span.contains(value.span.data()) {
+ kind = FormatParamKind::NamedInline(name);
+ }
+
+ Some(Self { value, kind, span })
+ }
+}
+
+/// Used by [width](https://doc.rust-lang.org/std/fmt/#width) and
+/// [precision](https://doc.rust-lang.org/std/fmt/#precision) specifiers.
+#[derive(Debug, Copy, Clone)]
+pub enum Count<'tcx> {
+ /// Specified with a literal number, stores the value.
+ Is(usize, Span),
+ /// Specified using `$` and `*` syntaxes. The `*` format is still considered to be
+ /// `FormatParamKind::Numbered`.
+ Param(FormatParam<'tcx>),
+ /// Not specified.
+ Implied,
+}
+
+impl<'tcx> Count<'tcx> {
+ fn new(
+ count: rpf::Count<'_>,
+ position: Option<usize>,
+ inner: Option<rpf::InnerSpan>,
+ values: &FormatArgsValues<'tcx>,
+ ) -> Option<Self> {
+ Some(match count {
+ rpf::Count::CountIs(val) => Self::Is(val, span_from_inner(values.format_string_span, inner?)),
+ rpf::Count::CountIsName(name, span) => Self::Param(FormatParam::new(
+ FormatParamKind::Named(Symbol::intern(name)),
+ position?,
+ span,
+ values,
+ )?),
+ rpf::Count::CountIsParam(_) | rpf::Count::CountIsStar(_) => {
+ Self::Param(FormatParam::new(FormatParamKind::Numbered, position?, inner?, values)?)
+ },
+ rpf::Count::CountImplied => Self::Implied,
+ })
+ }
+
+ pub fn is_implied(self) -> bool {
+ matches!(self, Count::Implied)
+ }
+
+ pub fn param(self) -> Option<FormatParam<'tcx>> {
+ match self {
+ Count::Param(param) => Some(param),
+ _ => None,
+ }
+ }
+}
+
+/// Specification for the formatting of an argument in the format string. See
+/// <https://doc.rust-lang.org/std/fmt/index.html#formatting-parameters> for the precise meanings.
+#[derive(Debug)]
+pub struct FormatSpec<'tcx> {
+ /// Optionally specified character to fill alignment with.
+ pub fill: Option<char>,
+ /// Optionally specified alignment.
+ pub align: Alignment,
+ /// Packed version of various flags provided, see [`rustc_parse_format::Flag`].
+ pub flags: u32,
+ /// Represents either the maximum width or the integer precision.
+ pub precision: Count<'tcx>,
+ /// The minimum width, will be padded according to `width`/`align`
+ pub width: Count<'tcx>,
+ /// The formatting trait used by the argument, e.g. `sym::Display` for `{}`, `sym::Debug` for
+ /// `{:?}`.
+ pub r#trait: Symbol,
+ pub trait_span: Option<Span>,
+}
+
+impl<'tcx> FormatSpec<'tcx> {
+ fn new(spec: rpf::FormatSpec<'_>, positions: ParamPosition, values: &FormatArgsValues<'tcx>) -> Option<Self> {
+ Some(Self {
+ fill: spec.fill,
+ align: spec.align,
+ flags: spec.flags,
+ precision: Count::new(spec.precision, positions.precision, spec.precision_span, values)?,
+ width: Count::new(spec.width, positions.width, spec.width_span, values)?,
+ r#trait: match spec.ty {
+ "" => sym::Display,
+ "?" => sym::Debug,
+ "o" => sym!(Octal),
+ "x" => sym!(LowerHex),
+ "X" => sym!(UpperHex),
+ "p" => sym::Pointer,
+ "b" => sym!(Binary),
+ "e" => sym!(LowerExp),
+ "E" => sym!(UpperExp),
+ _ => return None,
+ },
+ trait_span: spec
+ .ty_span
+ .map(|span| span_from_inner(values.format_string_span, span)),
})
}
- /// Finds a nested call to `format_args!` within a `format!`-like macro call
+ /// Returns true if this format spec would change the contents of a string when formatted
+ pub fn has_string_formatting(&self) -> bool {
+ self.r#trait != sym::Display || !self.width.is_implied() || !self.precision.is_implied()
+ }
+}
+
+/// A format argument, such as `{}`, `{foo:?}`.
+#[derive(Debug)]
+pub struct FormatArg<'tcx> {
+ /// The parameter the argument refers to.
+ pub param: FormatParam<'tcx>,
+ /// How to format `param`.
+ pub format: FormatSpec<'tcx>,
+ /// span of the whole argument, `{..}`.
+ pub span: Span,
+}
+
+/// A parsed `format_args!` expansion.
+#[derive(Debug)]
+pub struct FormatArgsExpn<'tcx> {
+ /// The format string literal.
+ pub format_string: FormatString,
+ // The format arguments, such as `{:?}`.
+ pub args: Vec<FormatArg<'tcx>>,
+ /// Has an added newline due to `println!()`/`writeln!()`/etc. The last format string part will
+ /// include this added newline.
+ pub newline: bool,
+ /// Values passed after the format string and implicit captures. `[1, z + 2, x]` for
+ /// `format!("{x} {} {y}", 1, z + 2)`.
+ value_args: Vec<&'tcx Expr<'tcx>>,
+}
+
+impl<'tcx> FormatArgsExpn<'tcx> {
+ pub fn parse(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<Self> {
+ let macro_name = macro_backtrace(expr.span)
+ .map(|macro_call| cx.tcx.item_name(macro_call.def_id))
+ .find(|&name| matches!(name, sym::const_format_args | sym::format_args | sym::format_args_nl))?;
+ let newline = macro_name == sym::format_args_nl;
+
+ // ::core::fmt::Arguments::new_v1(pieces, args)
+ // ::core::fmt::Arguments::new_v1_formatted(pieces, args, fmt, _unsafe_arg)
+ if let ExprKind::Call(callee, [pieces, args, rest @ ..]) = expr.kind
+ && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = callee.kind
+ && is_path_diagnostic_item(cx, ty, sym::Arguments)
+ && matches!(seg.ident.as_str(), "new_v1" | "new_v1_formatted")
+ {
+ let format_string = FormatString::new(cx, pieces)?;
+
+ let mut parser = rpf::Parser::new(
+ &format_string.unescaped,
+ format_string.style,
+ Some(format_string.snippet.clone()),
+ // `format_string.unescaped` does not contain the appended newline
+ false,
+ rpf::ParseMode::Format,
+ );
+
+ let parsed_args = parser
+ .by_ref()
+ .filter_map(|piece| match piece {
+ rpf::Piece::NextArgument(a) => Some(a),
+ rpf::Piece::String(_) => None,
+ })
+ .collect_vec();
+ if !parser.errors.is_empty() {
+ return None;
+ }
+
+ let positions = if let Some(fmt_arg) = rest.first() {
+ // If the argument contains format specs, `new_v1_formatted(_, _, fmt, _)`, parse
+ // them.
+
+ Either::Left(parse_rt_fmt(fmt_arg)?)
+ } else {
+ // If no format specs are given, the positions are in the given order and there are
+ // no `precision`/`width`s to consider.
+
+ Either::Right((0..).map(|n| ParamPosition {
+ value: n,
+ width: None,
+ precision: None,
+ }))
+ };
+
+ let values = FormatArgsValues::new(args, format_string.span.data());
+
+ let args = izip!(positions, parsed_args, parser.arg_places)
+ .map(|(position, parsed_arg, arg_span)| {
+ Some(FormatArg {
+ param: FormatParam::new(
+ match parsed_arg.position {
+ rpf::Position::ArgumentImplicitlyIs(_) => FormatParamKind::Implicit,
+ rpf::Position::ArgumentIs(_) => FormatParamKind::Numbered,
+ // NamedInline is handled by `FormatParam::new()`
+ rpf::Position::ArgumentNamed(name) => FormatParamKind::Named(Symbol::intern(name)),
+ },
+ position.value,
+ parsed_arg.position_span,
+ &values,
+ )?,
+ format: FormatSpec::new(parsed_arg.format, position, &values)?,
+ span: span_from_inner(values.format_string_span, arg_span),
+ })
+ })
+ .collect::<Option<Vec<_>>>()?;
+
+ Some(Self {
+ format_string,
+ args,
+ value_args: values.value_args,
+ newline,
+ })
+ } else {
+ None
+ }
+ }
+
pub fn find_nested(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expn_id: ExpnId) -> Option<Self> {
let mut format_args = None;
expr_visitor_no_bodies(|e| {
@@ -466,88 +847,23 @@ impl<'tcx> FormatArgsExpn<'tcx> {
format_args
}
- /// Returns a vector of `FormatArgsArg`.
- pub fn args(&self) -> Option<Vec<FormatArgsArg<'tcx>>> {
- if self.specs.is_empty() {
- let args = std::iter::zip(&self.value_args, &self.formatters)
- .map(|(value, &(_, format_trait))| FormatArgsArg {
- value,
- format_trait,
- spec: None,
- })
- .collect();
- return Some(args);
- }
- self.specs
- .iter()
- .map(|spec| {
- if_chain! {
- // struct `core::fmt::rt::v1::Argument`
- if let ExprKind::Struct(_, fields, _) = spec.kind;
- if let Some(position_field) = fields.iter().find(|f| f.ident.name == sym::position);
- if let ExprKind::Lit(lit) = &position_field.expr.kind;
- if let LitKind::Int(position, _) = lit.node;
- if let Ok(i) = usize::try_from(position);
- if let Some(&(j, format_trait)) = self.formatters.get(i);
- then {
- Some(FormatArgsArg {
- value: self.value_args[j],
- format_trait,
- spec: Some(spec),
- })
- } else {
- None
- }
- }
- })
- .collect()
- }
-
/// Source callsite span of all inputs
pub fn inputs_span(&self) -> Span {
match *self.value_args {
- [] => self.format_string_span,
+ [] => self.format_string.span,
[.., last] => self
- .format_string_span
- .to(hygiene::walk_chain(last.span, self.format_string_span.ctxt())),
+ .format_string
+ .span
+ .to(hygiene::walk_chain(last.span, self.format_string.span.ctxt())),
}
}
-}
-/// Type representing a `FormatArgsExpn`'s format arguments
-pub struct FormatArgsArg<'tcx> {
- /// An element of `value_args` according to `position`
- pub value: &'tcx Expr<'tcx>,
- /// An element of `args` according to `position`
- pub format_trait: Symbol,
- /// An element of `specs`
- pub spec: Option<&'tcx Expr<'tcx>>,
-}
-
-impl<'tcx> FormatArgsArg<'tcx> {
- /// Returns true if any formatting parameters are used that would have an effect on strings,
- /// like `{:+2}` instead of just `{}`.
- pub fn has_string_formatting(&self) -> bool {
- self.spec.map_or(false, |spec| {
- // `!` because these conditions check that `self` is unformatted.
- !if_chain! {
- // struct `core::fmt::rt::v1::Argument`
- if let ExprKind::Struct(_, fields, _) = spec.kind;
- if let Some(format_field) = fields.iter().find(|f| f.ident.name == sym::format);
- // struct `core::fmt::rt::v1::FormatSpec`
- if let ExprKind::Struct(_, subfields, _) = format_field.expr.kind;
- if subfields.iter().all(|field| match field.ident.name {
- sym::precision | sym::width => match field.expr.kind {
- ExprKind::Path(QPath::Resolved(_, path)) => {
- path.segments.last().unwrap().ident.name == sym::Implied
- }
- _ => false,
- }
- _ => true,
- });
- then { true } else { false }
- }
- })
+ /// Iterator of all format params, both values and those referenced by `width`/`precision`s.
+ pub fn params(&'tcx self) -> impl Iterator<Item = FormatParam<'tcx>> {
+ self.args
+ .iter()
+ .flat_map(|arg| [Some(arg.param), arg.format.precision.param(), arg.format.width.param()])
+ .flatten()
}
}
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 9e238c6f1..62020e21c 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -13,7 +13,7 @@ macro_rules! msrv_aliases {
// names may refer to stabilized feature flags or library items
msrv_aliases! {
1,62,0 { BOOL_THEN_SOME }
- 1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN }
+ 1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }
1,51,0 { BORROW_AS_PTR, UNSIGNED_ABS }
1,50,0 { BOOL_THEN }
@@ -32,8 +32,8 @@ msrv_aliases! {
1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }
1,28,0 { FROM_BOOL }
1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN }
+ 1,24,0 { IS_ASCII_DIGIT }
1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }
1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
1,16,0 { STR_REPEAT }
- 1,24,0 { IS_ASCII_DIGIT }
}
diff --git a/src/tools/clippy/clippy_utils/src/numeric_literal.rs b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
index 3fb5415ce..80098d976 100644
--- a/src/tools/clippy/clippy_utils/src/numeric_literal.rs
+++ b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
@@ -223,10 +223,12 @@ impl<'a> NumericLiteral<'a> {
fn split_suffix<'a>(src: &'a str, lit_kind: &LitKind) -> (&'a str, Option<&'a str>) {
debug_assert!(lit_kind.is_numeric());
- lit_suffix_length(lit_kind).map_or((src, None), |suffix_length| {
- let (unsuffixed, suffix) = src.split_at(src.len() - suffix_length);
- (unsuffixed, Some(suffix))
- })
+ lit_suffix_length(lit_kind)
+ .and_then(|suffix_length| src.len().checked_sub(suffix_length))
+ .map_or((src, None), |split_pos| {
+ let (unsuffixed, suffix) = src.split_at(split_pos);
+ (unsuffixed, Some(suffix))
+ })
}
fn lit_suffix_length(lit_kind: &LitKind) -> Option<usize> {
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 05429d05d..07170e2df 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -66,12 +66,9 @@ pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"];
pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"];
pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
-pub const IPADDR_V4: [&str; 5] = ["std", "net", "ip", "IpAddr", "V4"];
-pub const IPADDR_V6: [&str; 5] = ["std", "net", "ip", "IpAddr", "V6"];
pub const ITER_COUNT: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "count"];
pub const ITER_EMPTY: [&str; 5] = ["core", "iter", "sources", "empty", "Empty"];
pub const ITER_REPEAT: [&str; 5] = ["core", "iter", "sources", "repeat", "repeat"];
-#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
#[cfg(feature = "internal")]
pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
@@ -96,6 +93,7 @@ pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwL
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"];
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
+pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekable"];
pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];
#[cfg_attr(not(unix), allow(clippy::invalid_paths))]
pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
@@ -194,3 +192,5 @@ pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
pub const PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"];
+pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"];
+pub const INSTANT: [&str; 3] = ["std", "time", "Instant"];
diff --git a/src/tools/clippy/clippy_utils/src/ptr.rs b/src/tools/clippy/clippy_utils/src/ptr.rs
index 649b7b994..0226f7490 100644
--- a/src/tools/clippy/clippy_utils/src/ptr.rs
+++ b/src/tools/clippy/clippy_utils/src/ptr.rs
@@ -36,7 +36,7 @@ fn extract_clone_suggestions<'tcx>(
if abort {
return false;
}
- if let ExprKind::MethodCall(seg, [recv], _) = expr.kind {
+ if let ExprKind::MethodCall(seg, recv, [], _) = expr.kind {
if path_to_local_id(recv, id) {
if seg.ident.name.as_str() == "capacity" {
abort = true;
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 3bf75bcbe..8835b9329 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -6,8 +6,8 @@
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::{
- Body, CastKind, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
- TerminatorKind,
+ Body, CastKind, NonDivergingIntrinsic, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind,
+ Terminator, TerminatorKind,
};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
@@ -55,7 +55,7 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
body.local_decls.iter().next().unwrap().source_info.span,
)?;
- for bb in body.basic_blocks() {
+ for bb in body.basic_blocks.iter() {
check_terminator(tcx, body, bb.terminator(), msrv)?;
for stmt in &bb.statements {
check_statement(tcx, body, def_id, stmt)?;
@@ -82,7 +82,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
ty::FnPtr(..) => {
return Err((span, "function pointers in const fn are unstable".into()));
},
- ty::Dynamic(preds, _) => {
+ ty::Dynamic(preds, _, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {
@@ -161,6 +161,10 @@ fn check_rvalue<'tcx>(
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
Err((span, "casting pointers to ints is unstable in const fn".into()))
},
+ Rvalue::Cast(CastKind::DynStar, _, _) => {
+ // FIXME(dyn-star)
+ unimplemented!()
+ },
// binops are fine on integers
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
check_operand(tcx, lhs, span, body)?;
@@ -212,7 +216,11 @@ fn check_statement<'tcx>(
check_place(tcx, **place, span, body)
},
- StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => check_operand(tcx, op, span, body),
+
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
+ rustc_middle::mir::CopyNonOverlapping { dst, src, count },
+ )) => {
check_operand(tcx, dst, span, body)?;
check_operand(tcx, src, span, body)?;
check_operand(tcx, count, span, body)
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index 1197fe914..d85f591fb 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -11,24 +11,6 @@ use rustc_span::source_map::SourceMap;
use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext};
use std::borrow::Cow;
-/// Checks if the span starts with the given text. This will return false if the span crosses
-/// multiple files or if source is not available.
-///
-/// This is used to check for proc macros giving unhelpful spans to things.
-pub fn span_starts_with<T: LintContext>(cx: &T, span: Span, text: &str) -> bool {
- fn helper(sm: &SourceMap, span: Span, text: &str) -> bool {
- let pos = sm.lookup_byte_offset(span.lo());
- let Some(ref src) = pos.sf.src else {
- return false;
- };
- let end = span.hi() - pos.sf.start_pos;
- src.get(pos.pos.0 as usize..end.0 as usize)
- // Expression spans can include wrapping parenthesis. Remove them first.
- .map_or(false, |s| s.trim_start_matches('(').starts_with(text))
- }
- helper(cx.sess().source_map(), span, text)
-}
-
/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`.
/// Also takes an `Option<String>` which can be put inside the braces.
pub fn expr_block<'a, T: LintContext>(
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index bad291dfc..cca71bbf7 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -315,6 +315,12 @@ impl<'a> Sugg<'a> {
Sugg::NonParen(Cow::Owned(format!("{{ {} }}", self)))
}
+ /// Convenience method to prefix the expression with the `async` keyword.
+ /// Can be used after `blockify` to create an async block.
+ pub fn asyncify(self) -> Sugg<'static> {
+ Sugg::NonParen(Cow::Owned(format!("async {}", self)))
+ }
+
/// Convenience method to create the `<lhs>..<rhs>` or `<lhs>...<rhs>`
/// suggestion.
pub fn range(self, end: &Self, limit: ast::RangeLimits) -> Sugg<'static> {
@@ -367,12 +373,14 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
| AssocOp::LessEqual
| AssocOp::NotEqual
| AssocOp::Greater
- | AssocOp::GreaterEqual => format!(
- "{} {} {}",
- lhs,
- op.to_ast_binop().expect("Those are AST ops").to_string(),
- rhs
- ),
+ | AssocOp::GreaterEqual => {
+ format!(
+ "{} {} {}",
+ lhs,
+ op.to_ast_binop().expect("Those are AST ops").to_string(),
+ rhs
+ )
+ },
AssocOp::Assign => format!("{} = {}", lhs, rhs),
AssocOp::AssignOp(op) => {
format!("{} {}= {}", lhs, token_kind_to_string(&token::BinOp(op)), rhs)
@@ -862,15 +870,15 @@ impl<'tcx> DerefDelegate<'_, 'tcx> {
/// indicates whether the function from `parent_expr` takes its args by double reference
fn func_takes_arg_by_double_ref(&self, parent_expr: &'tcx hir::Expr<'_>, cmt_hir_id: HirId) -> bool {
let ty = match parent_expr.kind {
- ExprKind::MethodCall(_, call_args, _) => {
+ ExprKind::MethodCall(_, receiver, call_args, _) => {
if let Some(sig) = self
.cx
.typeck_results()
.type_dependent_def_id(parent_expr.hir_id)
.map(|did| self.cx.tcx.fn_sig(did).skip_binder())
{
- call_args
- .iter()
+ std::iter::once(receiver)
+ .chain(call_args.iter())
.position(|arg| arg.hir_id == cmt_hir_id)
.map(|i| sig.inputs()[i])
} else {
@@ -927,14 +935,14 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
match &parent_expr.kind {
// given expression is the self argument and will be handled completely by the compiler
// i.e.: `|x| x.is_something()`
- ExprKind::MethodCall(_, [self_expr, ..], _) if self_expr.hir_id == cmt.hir_id => {
+ ExprKind::MethodCall(_, self_expr, ..) if self_expr.hir_id == cmt.hir_id => {
let _ = write!(self.suggestion_start, "{}{}", start_snip, ident_str_with_proj);
self.next_pos = span.hi();
return;
},
// item is used in a call
// i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)`
- ExprKind::Call(_, [call_args @ ..]) | ExprKind::MethodCall(_, [_, call_args @ ..], _) => {
+ ExprKind::Call(_, [call_args @ ..]) | ExprKind::MethodCall(_, _, [call_args @ ..], _) => {
let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id);
let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind();
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index a05d633d9..a8ad6cf4f 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -43,14 +43,6 @@ pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool
}
}
-/// Walks into `ty` and returns `true` if any inner type is the same as `other_ty`
-pub fn contains_ty<'tcx>(ty: Ty<'tcx>, other_ty: Ty<'tcx>) -> bool {
- ty.walk().any(|inner| match inner.unpack() {
- GenericArgKind::Type(inner_ty) => other_ty == inner_ty,
- GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
- })
-}
-
/// Walks into `ty` and returns `true` if any inner type is an instance of the given adt
/// constructor.
pub fn contains_adt_constructor<'tcx>(ty: Ty<'tcx>, adt: AdtDef<'tcx>) -> bool {
@@ -209,7 +201,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
}
false
},
- ty::Dynamic(binder, _) => {
+ ty::Dynamic(binder, _, _) => {
for predicate in binder.iter() {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
if cx.tcx.has_attr(trait_ref.def_id, sym::must_use) {
@@ -410,7 +402,7 @@ pub fn peel_mid_ty_refs(ty: Ty<'_>) -> (Ty<'_>, usize) {
peel(ty, 0)
}
-/// Peels off all references on the type.Returns the underlying type, the number of references
+/// Peels off all references on the type. Returns the underlying type, the number of references
/// removed, and whether the pointer is ultimately mutable or not.
pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) {
fn f(ty: Ty<'_>, count: usize, mutability: Mutability) -> (Ty<'_>, usize, Mutability) {
@@ -503,7 +495,7 @@ pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator<Item = &(P
pub enum ExprFnSig<'tcx> {
Sig(Binder<'tcx, FnSig<'tcx>>, Option<DefId>),
Closure(Option<&'tcx FnDecl<'tcx>>, Binder<'tcx, FnSig<'tcx>>),
- Trait(Binder<'tcx, Ty<'tcx>>, Option<Binder<'tcx, Ty<'tcx>>>),
+ Trait(Binder<'tcx, Ty<'tcx>>, Option<Binder<'tcx, Ty<'tcx>>>, Option<DefId>),
}
impl<'tcx> ExprFnSig<'tcx> {
/// Gets the argument type at the given offset. This will return `None` when the index is out of
@@ -518,7 +510,7 @@ impl<'tcx> ExprFnSig<'tcx> {
}
},
Self::Closure(_, sig) => Some(sig.input(0).map_bound(|ty| ty.tuple_fields()[i])),
- Self::Trait(inputs, _) => Some(inputs.map_bound(|ty| ty.tuple_fields()[i])),
+ Self::Trait(inputs, _, _) => Some(inputs.map_bound(|ty| ty.tuple_fields()[i])),
}
}
@@ -541,7 +533,7 @@ impl<'tcx> ExprFnSig<'tcx> {
decl.and_then(|decl| decl.inputs.get(i)),
sig.input(0).map_bound(|ty| ty.tuple_fields()[i]),
)),
- Self::Trait(inputs, _) => Some((None, inputs.map_bound(|ty| ty.tuple_fields()[i]))),
+ Self::Trait(inputs, _, _) => Some((None, inputs.map_bound(|ty| ty.tuple_fields()[i]))),
}
}
@@ -550,12 +542,16 @@ impl<'tcx> ExprFnSig<'tcx> {
pub fn output(self) -> Option<Binder<'tcx, Ty<'tcx>>> {
match self {
Self::Sig(sig, _) | Self::Closure(_, sig) => Some(sig.output()),
- Self::Trait(_, output) => output,
+ Self::Trait(_, output, _) => output,
}
}
pub fn predicates_id(&self) -> Option<DefId> {
- if let ExprFnSig::Sig(_, id) = *self { id } else { None }
+ if let ExprFnSig::Sig(_, id) | ExprFnSig::Trait(_, _, id) = *self {
+ id
+ } else {
+ None
+ }
}
}
@@ -568,7 +564,8 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnS
}
}
-fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {
+/// If the type is function like, get the signature for it.
+pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {
if ty.is_box() {
return ty_sig(cx, ty.boxed_ty());
}
@@ -580,9 +577,9 @@ fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>>
Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
},
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs), Some(id))),
- ty::Opaque(id, _) => ty_sig(cx, cx.tcx.type_of(id)),
+ ty::Opaque(id, _) => sig_from_bounds(cx, ty, cx.tcx.item_bounds(id), cx.tcx.opt_parent(id)),
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
- ty::Dynamic(bounds, _) => {
+ ty::Dynamic(bounds, _, _) => {
let lang_items = cx.tcx.lang_items();
match bounds.principal() {
Some(bound)
@@ -594,26 +591,31 @@ fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>>
.projection_bounds()
.find(|p| lang_items.fn_once_output().map_or(false, |id| id == p.item_def_id()))
.map(|p| p.map_bound(|p| p.term.ty().unwrap()));
- Some(ExprFnSig::Trait(bound.map_bound(|b| b.substs.type_at(0)), output))
+ Some(ExprFnSig::Trait(bound.map_bound(|b| b.substs.type_at(0)), output, None))
},
_ => None,
}
},
ty::Projection(proj) => match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) {
Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty),
- _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty)),
+ _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)),
},
- ty::Param(_) => sig_from_bounds(cx, ty),
+ ty::Param(_) => sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None),
_ => None,
}
}
-fn sig_from_bounds<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {
+fn sig_from_bounds<'tcx>(
+ cx: &LateContext<'tcx>,
+ ty: Ty<'tcx>,
+ predicates: &'tcx [Predicate<'tcx>],
+ predicates_id: Option<DefId>,
+) -> Option<ExprFnSig<'tcx>> {
let mut inputs = None;
let mut output = None;
let lang_items = cx.tcx.lang_items();
- for (pred, _) in all_predicates_of(cx.tcx, cx.typeck_results().hir_owner.to_def_id()) {
+ for pred in predicates {
match pred.kind().skip_binder() {
PredicateKind::Trait(p)
if (lang_items.fn_trait() == Some(p.def_id())
@@ -621,11 +623,12 @@ fn sig_from_bounds<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnS
|| lang_items.fn_once_trait() == Some(p.def_id()))
&& p.self_ty() == ty =>
{
- if inputs.is_some() {
+ let i = pred.kind().rebind(p.trait_ref.substs.type_at(1));
+ if inputs.map_or(false, |inputs| i != inputs) {
// Multiple different fn trait impls. Is this even allowed?
return None;
}
- inputs = Some(pred.kind().rebind(p.trait_ref.substs.type_at(1)));
+ inputs = Some(i);
},
PredicateKind::Projection(p)
if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output()
@@ -641,7 +644,7 @@ fn sig_from_bounds<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnS
}
}
- inputs.map(|ty| ExprFnSig::Trait(ty, output))
+ inputs.map(|ty| ExprFnSig::Trait(ty, output, predicates_id))
}
fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> Option<ExprFnSig<'tcx>> {
@@ -661,14 +664,15 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
|| lang_items.fn_mut_trait() == Some(p.def_id())
|| lang_items.fn_once_trait() == Some(p.def_id())) =>
{
- if inputs.is_some() {
+ let i = pred
+ .map_bound(|pred| pred.kind().rebind(p.trait_ref.substs.type_at(1)))
+ .subst(cx.tcx, ty.substs);
+
+ if inputs.map_or(false, |inputs| inputs != i) {
// Multiple different fn trait impls. Is this even allowed?
return None;
}
- inputs = Some(
- pred.map_bound(|pred| pred.kind().rebind(p.trait_ref.substs.type_at(1)))
- .subst(cx.tcx, ty.substs),
- );
+ inputs = Some(i);
},
PredicateKind::Projection(p) if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output() => {
if output.is_some() {
@@ -684,7 +688,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
}
}
- inputs.map(|ty| ExprFnSig::Trait(ty, output))
+ inputs.map(|ty| ExprFnSig::Trait(ty, output, None))
}
#[derive(Clone, Copy)]
@@ -827,3 +831,53 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc
})
.unwrap_or(false)
}
+
+/// Comes up with an "at least" guesstimate for the type's size, not taking into
+/// account the layout of type parameters.
+pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {
+ use rustc_middle::ty::layout::LayoutOf;
+ if !is_normalizable(cx, cx.param_env, ty) {
+ return 0;
+ }
+ match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) {
+ (Ok(size), _) => size,
+ (Err(_), ty::Tuple(list)) => list.as_substs().types().map(|t| approx_ty_size(cx, t)).sum(),
+ (Err(_), ty::Array(t, n)) => {
+ n.try_eval_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t)
+ },
+ (Err(_), ty::Adt(def, subst)) if def.is_struct() => def
+ .variants()
+ .iter()
+ .map(|v| {
+ v.fields
+ .iter()
+ .map(|field| approx_ty_size(cx, field.ty(cx.tcx, subst)))
+ .sum::<u64>()
+ })
+ .sum(),
+ (Err(_), ty::Adt(def, subst)) if def.is_enum() => def
+ .variants()
+ .iter()
+ .map(|v| {
+ v.fields
+ .iter()
+ .map(|field| approx_ty_size(cx, field.ty(cx.tcx, subst)))
+ .sum::<u64>()
+ })
+ .max()
+ .unwrap_or_default(),
+ (Err(_), ty::Adt(def, subst)) if def.is_union() => def
+ .variants()
+ .iter()
+ .map(|v| {
+ v.fields
+ .iter()
+ .map(|field| approx_ty_size(cx, field.ty(cx.tcx, subst)))
+ .max()
+ .unwrap_or_default()
+ })
+ .max()
+ .unwrap_or_default(),
+ (Err(_), _) => 0,
+ }
+}
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index bae8ad9f5..232d57190 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -274,7 +274,7 @@ pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool {
}
!found
})
- .visit_expr(&cx.tcx.hir().body(body).value);
+ .visit_expr(cx.tcx.hir().body(body).value);
found
}
@@ -568,6 +568,7 @@ pub fn for_each_local_use_after_expr<'tcx, B>(
// Calls the given function for every unconsumed temporary created by the expression. Note the
// function is only guaranteed to be called for types which need to be dropped, but it may be called
// for other types.
+#[allow(clippy::too_many_lines)]
pub fn for_each_unconsumed_temporary<'tcx, B>(
cx: &LateContext<'tcx>,
e: &'tcx Expr<'tcx>,
@@ -620,7 +621,13 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
helper(typeck, true, arg, f)?;
}
},
- ExprKind::MethodCall(_, args, _) | ExprKind::Tup(args) | ExprKind::Array(args) => {
+ ExprKind::MethodCall(_, receiver, args, _) => {
+ helper(typeck, true, receiver, f)?;
+ for arg in args {
+ helper(typeck, true, arg, f)?;
+ }
+ },
+ ExprKind::Tup(args) | ExprKind::Array(args) => {
for arg in args {
helper(typeck, true, arg, f)?;
}
diff --git a/src/tools/clippy/lintcheck/lintcheck_crates.toml b/src/tools/clippy/lintcheck/lintcheck_crates.toml
index 4fbae8614..ebbe9c9ae 100644
--- a/src/tools/clippy/lintcheck/lintcheck_crates.toml
+++ b/src/tools/clippy/lintcheck/lintcheck_crates.toml
@@ -1,6 +1,6 @@
[crates]
# some of these are from cargotest
-cargo = {name = "cargo", versions = ['0.49.0']}
+cargo = {name = "cargo", versions = ['0.64.0']}
iron = {name = "iron", versions = ['0.6.1']}
ripgrep = {name = "ripgrep", versions = ['12.1.1']}
xsv = {name = "xsv", versions = ['0.13.0']}
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 23ba7c712..b6976366d 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2022-07-28"
+channel = "nightly-2022-09-08"
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/rustc_tools_util/src/lib.rs b/src/tools/clippy/rustc_tools_util/src/lib.rs
index 5f289918a..429dddc42 100644
--- a/src/tools/clippy/rustc_tools_util/src/lib.rs
+++ b/src/tools/clippy/rustc_tools_util/src/lib.rs
@@ -84,7 +84,7 @@ impl std::fmt::Debug for VersionInfo {
#[must_use]
pub fn get_commit_hash() -> Option<String> {
std::process::Command::new("git")
- .args(&["rev-parse", "--short", "HEAD"])
+ .args(["rev-parse", "--short", "HEAD"])
.output()
.ok()
.and_then(|r| String::from_utf8(r.stdout).ok())
@@ -93,7 +93,7 @@ pub fn get_commit_hash() -> Option<String> {
#[must_use]
pub fn get_commit_date() -> Option<String> {
std::process::Command::new("git")
- .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
+ .args(["log", "-1", "--date=short", "--pretty=format:%cd"])
.output()
.ok()
.and_then(|r| String::from_utf8(r.stdout).ok())
diff --git a/src/tools/clippy/src/docs.rs b/src/tools/clippy/src/docs.rs
new file mode 100644
index 000000000..f3a5048e7
--- /dev/null
+++ b/src/tools/clippy/src/docs.rs
@@ -0,0 +1,596 @@
+// autogenerated. Please look at /clippy_dev/src/update_lints.rs
+
+macro_rules! include_lint {
+ ($file_name: expr) => {
+ include_str!($file_name)
+ };
+}
+
+macro_rules! docs {
+ ($($lint_name: expr,)*) => {
+ pub fn explain(lint: &str) {
+ println!("{}", match lint {
+ $(
+ $lint_name => include_lint!(concat!("docs/", concat!($lint_name, ".txt"))),
+ )*
+ _ => "unknown lint",
+ })
+ }
+ }
+}
+
+docs! {
+ "absurd_extreme_comparisons",
+ "alloc_instead_of_core",
+ "allow_attributes_without_reason",
+ "almost_complete_letter_range",
+ "almost_swapped",
+ "approx_constant",
+ "arithmetic_side_effects",
+ "as_conversions",
+ "as_underscore",
+ "assertions_on_constants",
+ "assertions_on_result_states",
+ "assign_op_pattern",
+ "async_yields_async",
+ "await_holding_invalid_type",
+ "await_holding_lock",
+ "await_holding_refcell_ref",
+ "bad_bit_mask",
+ "bind_instead_of_map",
+ "blanket_clippy_restriction_lints",
+ "blocks_in_if_conditions",
+ "bool_assert_comparison",
+ "bool_comparison",
+ "bool_to_int_with_if",
+ "borrow_as_ptr",
+ "borrow_deref_ref",
+ "borrow_interior_mutable_const",
+ "borrowed_box",
+ "box_collection",
+ "boxed_local",
+ "branches_sharing_code",
+ "builtin_type_shadow",
+ "bytes_count_to_len",
+ "bytes_nth",
+ "cargo_common_metadata",
+ "case_sensitive_file_extension_comparisons",
+ "cast_abs_to_unsigned",
+ "cast_enum_constructor",
+ "cast_enum_truncation",
+ "cast_lossless",
+ "cast_possible_truncation",
+ "cast_possible_wrap",
+ "cast_precision_loss",
+ "cast_ptr_alignment",
+ "cast_ref_to_mut",
+ "cast_sign_loss",
+ "cast_slice_different_sizes",
+ "cast_slice_from_raw_parts",
+ "char_lit_as_u8",
+ "chars_last_cmp",
+ "chars_next_cmp",
+ "checked_conversions",
+ "clone_double_ref",
+ "clone_on_copy",
+ "clone_on_ref_ptr",
+ "cloned_instead_of_copied",
+ "cmp_nan",
+ "cmp_null",
+ "cmp_owned",
+ "cognitive_complexity",
+ "collapsible_else_if",
+ "collapsible_if",
+ "collapsible_match",
+ "collapsible_str_replace",
+ "comparison_chain",
+ "comparison_to_empty",
+ "copy_iterator",
+ "crate_in_macro_def",
+ "create_dir",
+ "crosspointer_transmute",
+ "dbg_macro",
+ "debug_assert_with_mut_call",
+ "decimal_literal_representation",
+ "declare_interior_mutable_const",
+ "default_instead_of_iter_empty",
+ "default_numeric_fallback",
+ "default_trait_access",
+ "default_union_representation",
+ "deprecated_cfg_attr",
+ "deprecated_semver",
+ "deref_addrof",
+ "deref_by_slicing",
+ "derivable_impls",
+ "derive_hash_xor_eq",
+ "derive_ord_xor_partial_ord",
+ "derive_partial_eq_without_eq",
+ "disallowed_methods",
+ "disallowed_names",
+ "disallowed_script_idents",
+ "disallowed_types",
+ "diverging_sub_expression",
+ "doc_link_with_quotes",
+ "doc_markdown",
+ "double_comparisons",
+ "double_must_use",
+ "double_neg",
+ "double_parens",
+ "drop_copy",
+ "drop_non_drop",
+ "drop_ref",
+ "duplicate_mod",
+ "duplicate_underscore_argument",
+ "duration_subsec",
+ "else_if_without_else",
+ "empty_drop",
+ "empty_enum",
+ "empty_line_after_outer_attr",
+ "empty_loop",
+ "empty_structs_with_brackets",
+ "enum_clike_unportable_variant",
+ "enum_glob_use",
+ "enum_variant_names",
+ "eq_op",
+ "equatable_if_let",
+ "erasing_op",
+ "err_expect",
+ "excessive_precision",
+ "exhaustive_enums",
+ "exhaustive_structs",
+ "exit",
+ "expect_fun_call",
+ "expect_used",
+ "expl_impl_clone_on_copy",
+ "explicit_auto_deref",
+ "explicit_counter_loop",
+ "explicit_deref_methods",
+ "explicit_into_iter_loop",
+ "explicit_iter_loop",
+ "explicit_write",
+ "extend_with_drain",
+ "extra_unused_lifetimes",
+ "fallible_impl_from",
+ "field_reassign_with_default",
+ "filetype_is_file",
+ "filter_map_identity",
+ "filter_map_next",
+ "filter_next",
+ "flat_map_identity",
+ "flat_map_option",
+ "float_arithmetic",
+ "float_cmp",
+ "float_cmp_const",
+ "float_equality_without_abs",
+ "fn_address_comparisons",
+ "fn_params_excessive_bools",
+ "fn_to_numeric_cast",
+ "fn_to_numeric_cast_any",
+ "fn_to_numeric_cast_with_truncation",
+ "for_kv_map",
+ "for_loops_over_fallibles",
+ "forget_copy",
+ "forget_non_drop",
+ "forget_ref",
+ "format_in_format_args",
+ "format_push_string",
+ "from_iter_instead_of_collect",
+ "from_over_into",
+ "from_str_radix_10",
+ "future_not_send",
+ "get_first",
+ "get_last_with_len",
+ "get_unwrap",
+ "identity_op",
+ "if_let_mutex",
+ "if_not_else",
+ "if_same_then_else",
+ "if_then_some_else_none",
+ "ifs_same_cond",
+ "implicit_clone",
+ "implicit_hasher",
+ "implicit_return",
+ "implicit_saturating_sub",
+ "imprecise_flops",
+ "inconsistent_digit_grouping",
+ "inconsistent_struct_constructor",
+ "index_refutable_slice",
+ "indexing_slicing",
+ "ineffective_bit_mask",
+ "inefficient_to_string",
+ "infallible_destructuring_match",
+ "infinite_iter",
+ "inherent_to_string",
+ "inherent_to_string_shadow_display",
+ "init_numbered_fields",
+ "inline_always",
+ "inline_asm_x86_att_syntax",
+ "inline_asm_x86_intel_syntax",
+ "inline_fn_without_body",
+ "inspect_for_each",
+ "int_plus_one",
+ "integer_arithmetic",
+ "integer_division",
+ "into_iter_on_ref",
+ "invalid_null_ptr_usage",
+ "invalid_regex",
+ "invalid_upcast_comparisons",
+ "invalid_utf8_in_unchecked",
+ "invisible_characters",
+ "is_digit_ascii_radix",
+ "items_after_statements",
+ "iter_cloned_collect",
+ "iter_count",
+ "iter_next_loop",
+ "iter_next_slice",
+ "iter_not_returning_iterator",
+ "iter_nth",
+ "iter_nth_zero",
+ "iter_on_empty_collections",
+ "iter_on_single_items",
+ "iter_overeager_cloned",
+ "iter_skip_next",
+ "iter_with_drain",
+ "iterator_step_by_zero",
+ "just_underscores_and_digits",
+ "large_const_arrays",
+ "large_digit_groups",
+ "large_enum_variant",
+ "large_include_file",
+ "large_stack_arrays",
+ "large_types_passed_by_value",
+ "len_without_is_empty",
+ "len_zero",
+ "let_and_return",
+ "let_underscore_drop",
+ "let_underscore_lock",
+ "let_underscore_must_use",
+ "let_unit_value",
+ "linkedlist",
+ "lossy_float_literal",
+ "macro_use_imports",
+ "main_recursion",
+ "manual_assert",
+ "manual_async_fn",
+ "manual_bits",
+ "manual_filter_map",
+ "manual_find",
+ "manual_find_map",
+ "manual_flatten",
+ "manual_instant_elapsed",
+ "manual_map",
+ "manual_memcpy",
+ "manual_non_exhaustive",
+ "manual_ok_or",
+ "manual_range_contains",
+ "manual_rem_euclid",
+ "manual_retain",
+ "manual_saturating_arithmetic",
+ "manual_split_once",
+ "manual_str_repeat",
+ "manual_string_new",
+ "manual_strip",
+ "manual_swap",
+ "manual_unwrap_or",
+ "many_single_char_names",
+ "map_clone",
+ "map_collect_result_unit",
+ "map_entry",
+ "map_err_ignore",
+ "map_flatten",
+ "map_identity",
+ "map_unwrap_or",
+ "match_as_ref",
+ "match_bool",
+ "match_like_matches_macro",
+ "match_on_vec_items",
+ "match_overlapping_arm",
+ "match_ref_pats",
+ "match_result_ok",
+ "match_same_arms",
+ "match_single_binding",
+ "match_str_case_mismatch",
+ "match_wild_err_arm",
+ "match_wildcard_for_single_variants",
+ "maybe_infinite_iter",
+ "mem_forget",
+ "mem_replace_option_with_none",
+ "mem_replace_with_default",
+ "mem_replace_with_uninit",
+ "min_max",
+ "mismatched_target_os",
+ "mismatching_type_param_order",
+ "misrefactored_assign_op",
+ "missing_const_for_fn",
+ "missing_docs_in_private_items",
+ "missing_enforced_import_renames",
+ "missing_errors_doc",
+ "missing_inline_in_public_items",
+ "missing_panics_doc",
+ "missing_safety_doc",
+ "missing_spin_loop",
+ "mistyped_literal_suffixes",
+ "mixed_case_hex_literals",
+ "mixed_read_write_in_expression",
+ "mod_module_files",
+ "module_inception",
+ "module_name_repetitions",
+ "modulo_arithmetic",
+ "modulo_one",
+ "multi_assignments",
+ "multiple_crate_versions",
+ "multiple_inherent_impl",
+ "must_use_candidate",
+ "must_use_unit",
+ "mut_from_ref",
+ "mut_mut",
+ "mut_mutex_lock",
+ "mut_range_bound",
+ "mutable_key_type",
+ "mutex_atomic",
+ "mutex_integer",
+ "naive_bytecount",
+ "needless_arbitrary_self_type",
+ "needless_bitwise_bool",
+ "needless_bool",
+ "needless_borrow",
+ "needless_borrowed_reference",
+ "needless_collect",
+ "needless_continue",
+ "needless_doctest_main",
+ "needless_for_each",
+ "needless_late_init",
+ "needless_lifetimes",
+ "needless_match",
+ "needless_option_as_deref",
+ "needless_option_take",
+ "needless_parens_on_range_literals",
+ "needless_pass_by_value",
+ "needless_question_mark",
+ "needless_range_loop",
+ "needless_return",
+ "needless_splitn",
+ "needless_update",
+ "neg_cmp_op_on_partial_ord",
+ "neg_multiply",
+ "negative_feature_names",
+ "never_loop",
+ "new_ret_no_self",
+ "new_without_default",
+ "no_effect",
+ "no_effect_replace",
+ "no_effect_underscore_binding",
+ "non_ascii_literal",
+ "non_octal_unix_permissions",
+ "non_send_fields_in_send_ty",
+ "nonminimal_bool",
+ "nonsensical_open_options",
+ "nonstandard_macro_braces",
+ "not_unsafe_ptr_arg_deref",
+ "obfuscated_if_else",
+ "octal_escapes",
+ "ok_expect",
+ "only_used_in_recursion",
+ "op_ref",
+ "option_as_ref_deref",
+ "option_env_unwrap",
+ "option_filter_map",
+ "option_if_let_else",
+ "option_map_or_none",
+ "option_map_unit_fn",
+ "option_option",
+ "or_fun_call",
+ "or_then_unwrap",
+ "out_of_bounds_indexing",
+ "overflow_check_conditional",
+ "overly_complex_bool_expr",
+ "panic",
+ "panic_in_result_fn",
+ "panicking_unwrap",
+ "partialeq_ne_impl",
+ "partialeq_to_none",
+ "path_buf_push_overwrite",
+ "pattern_type_mismatch",
+ "positional_named_format_parameters",
+ "possible_missing_comma",
+ "precedence",
+ "print_in_format_impl",
+ "print_literal",
+ "print_stderr",
+ "print_stdout",
+ "print_with_newline",
+ "println_empty_string",
+ "ptr_arg",
+ "ptr_as_ptr",
+ "ptr_eq",
+ "ptr_offset_with_cast",
+ "pub_use",
+ "question_mark",
+ "range_minus_one",
+ "range_plus_one",
+ "range_zip_with_len",
+ "rc_buffer",
+ "rc_clone_in_vec_init",
+ "rc_mutex",
+ "read_zero_byte_vec",
+ "recursive_format_impl",
+ "redundant_allocation",
+ "redundant_clone",
+ "redundant_closure",
+ "redundant_closure_call",
+ "redundant_closure_for_method_calls",
+ "redundant_else",
+ "redundant_feature_names",
+ "redundant_field_names",
+ "redundant_pattern",
+ "redundant_pattern_matching",
+ "redundant_pub_crate",
+ "redundant_slicing",
+ "redundant_static_lifetimes",
+ "ref_binding_to_reference",
+ "ref_option_ref",
+ "repeat_once",
+ "rest_pat_in_fully_bound_structs",
+ "result_large_err",
+ "result_map_or_into_option",
+ "result_map_unit_fn",
+ "result_unit_err",
+ "return_self_not_must_use",
+ "reversed_empty_ranges",
+ "same_functions_in_if_condition",
+ "same_item_push",
+ "same_name_method",
+ "search_is_some",
+ "self_assignment",
+ "self_named_constructors",
+ "self_named_module_files",
+ "semicolon_if_nothing_returned",
+ "separated_literal_suffix",
+ "serde_api_misuse",
+ "shadow_reuse",
+ "shadow_same",
+ "shadow_unrelated",
+ "short_circuit_statement",
+ "should_implement_trait",
+ "significant_drop_in_scrutinee",
+ "similar_names",
+ "single_char_add_str",
+ "single_char_lifetime_names",
+ "single_char_pattern",
+ "single_component_path_imports",
+ "single_element_loop",
+ "single_match",
+ "single_match_else",
+ "size_of_in_element_count",
+ "skip_while_next",
+ "slow_vector_initialization",
+ "stable_sort_primitive",
+ "std_instead_of_alloc",
+ "std_instead_of_core",
+ "str_to_string",
+ "string_add",
+ "string_add_assign",
+ "string_extend_chars",
+ "string_from_utf8_as_bytes",
+ "string_lit_as_bytes",
+ "string_slice",
+ "string_to_string",
+ "strlen_on_c_strings",
+ "struct_excessive_bools",
+ "suboptimal_flops",
+ "suspicious_arithmetic_impl",
+ "suspicious_assignment_formatting",
+ "suspicious_else_formatting",
+ "suspicious_map",
+ "suspicious_op_assign_impl",
+ "suspicious_operation_groupings",
+ "suspicious_splitn",
+ "suspicious_to_owned",
+ "suspicious_unary_op_formatting",
+ "swap_ptr_to_ref",
+ "tabs_in_doc_comments",
+ "temporary_assignment",
+ "to_digit_is_some",
+ "to_string_in_format_args",
+ "todo",
+ "too_many_arguments",
+ "too_many_lines",
+ "toplevel_ref_arg",
+ "trailing_empty_array",
+ "trait_duplication_in_bounds",
+ "transmute_bytes_to_str",
+ "transmute_float_to_int",
+ "transmute_int_to_bool",
+ "transmute_int_to_char",
+ "transmute_int_to_float",
+ "transmute_num_to_bytes",
+ "transmute_ptr_to_ptr",
+ "transmute_ptr_to_ref",
+ "transmute_undefined_repr",
+ "transmutes_expressible_as_ptr_casts",
+ "transmuting_null",
+ "trim_split_whitespace",
+ "trivial_regex",
+ "trivially_copy_pass_by_ref",
+ "try_err",
+ "type_complexity",
+ "type_repetition_in_bounds",
+ "undocumented_unsafe_blocks",
+ "undropped_manually_drops",
+ "unicode_not_nfc",
+ "unimplemented",
+ "uninit_assumed_init",
+ "uninit_vec",
+ "unit_arg",
+ "unit_cmp",
+ "unit_hash",
+ "unit_return_expecting_ord",
+ "unnecessary_cast",
+ "unnecessary_filter_map",
+ "unnecessary_find_map",
+ "unnecessary_fold",
+ "unnecessary_join",
+ "unnecessary_lazy_evaluations",
+ "unnecessary_mut_passed",
+ "unnecessary_operation",
+ "unnecessary_owned_empty_strings",
+ "unnecessary_self_imports",
+ "unnecessary_sort_by",
+ "unnecessary_to_owned",
+ "unnecessary_unwrap",
+ "unnecessary_wraps",
+ "unneeded_field_pattern",
+ "unneeded_wildcard_pattern",
+ "unnested_or_patterns",
+ "unreachable",
+ "unreadable_literal",
+ "unsafe_derive_deserialize",
+ "unsafe_removed_from_name",
+ "unseparated_literal_suffix",
+ "unsound_collection_transmute",
+ "unused_async",
+ "unused_io_amount",
+ "unused_peekable",
+ "unused_rounding",
+ "unused_self",
+ "unused_unit",
+ "unusual_byte_groupings",
+ "unwrap_in_result",
+ "unwrap_or_else_default",
+ "unwrap_used",
+ "upper_case_acronyms",
+ "use_debug",
+ "use_self",
+ "used_underscore_binding",
+ "useless_asref",
+ "useless_attribute",
+ "useless_conversion",
+ "useless_format",
+ "useless_let_if_seq",
+ "useless_transmute",
+ "useless_vec",
+ "vec_box",
+ "vec_init_then_push",
+ "vec_resize_to_zero",
+ "verbose_bit_mask",
+ "verbose_file_reads",
+ "vtable_address_comparisons",
+ "while_immutable_condition",
+ "while_let_loop",
+ "while_let_on_iterator",
+ "wildcard_dependencies",
+ "wildcard_enum_match_arm",
+ "wildcard_imports",
+ "wildcard_in_or_patterns",
+ "write_literal",
+ "write_with_newline",
+ "writeln_empty_string",
+ "wrong_self_convention",
+ "wrong_transmute",
+ "zero_divided_by_zero",
+ "zero_prefixed_literal",
+ "zero_ptr",
+ "zero_sized_map_values",
+ "zst_offset",
+
+}
diff --git a/src/tools/clippy/src/docs/absurd_extreme_comparisons.txt b/src/tools/clippy/src/docs/absurd_extreme_comparisons.txt
new file mode 100644
index 000000000..590bee28a
--- /dev/null
+++ b/src/tools/clippy/src/docs/absurd_extreme_comparisons.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for comparisons where one side of the relation is
+either the minimum or maximum value for its type and warns if it involves a
+case that is always true or always false. Only integer and boolean types are
+checked.
+
+### Why is this bad?
+An expression like `min <= x` may misleadingly imply
+that it is possible for `x` to be less than the minimum. Expressions like
+`max < x` are probably mistakes.
+
+### Known problems
+For `usize` the size of the current compile target will
+be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
+a comparison to detect target pointer width will trigger this lint. One can
+use `mem::sizeof` and compare its value or conditional compilation
+attributes
+like `#[cfg(target_pointer_width = "64")] ..` instead.
+
+### Example
+```
+let vec: Vec<isize> = Vec::new();
+if vec.len() <= 0 {}
+if 100 > i32::MAX {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/alloc_instead_of_core.txt b/src/tools/clippy/src/docs/alloc_instead_of_core.txt
new file mode 100644
index 000000000..488a36e92
--- /dev/null
+++ b/src/tools/clippy/src/docs/alloc_instead_of_core.txt
@@ -0,0 +1,18 @@
+### What it does
+
+Finds items imported through `alloc` when available through `core`.
+
+### Why is this bad?
+
+Crates which have `no_std` compatibility and may optionally require alloc may wish to ensure types are
+imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint
+is also useful for crates migrating to become `no_std` compatible.
+
+### Example
+```
+use alloc::slice::from_ref;
+```
+Use instead:
+```
+use core::slice::from_ref;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/allow_attributes_without_reason.txt b/src/tools/clippy/src/docs/allow_attributes_without_reason.txt
new file mode 100644
index 000000000..fcc4f49b0
--- /dev/null
+++ b/src/tools/clippy/src/docs/allow_attributes_without_reason.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for attributes that allow lints without a reason.
+
+(This requires the `lint_reasons` feature)
+
+### Why is this bad?
+Allowing a lint should always have a reason. This reason should be documented to
+ensure that others understand the reasoning
+
+### Example
+```
+#![feature(lint_reasons)]
+
+#![allow(clippy::some_lint)]
+```
+
+Use instead:
+```
+#![feature(lint_reasons)]
+
+#![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/almost_complete_letter_range.txt b/src/tools/clippy/src/docs/almost_complete_letter_range.txt
new file mode 100644
index 000000000..01cbaf9ea
--- /dev/null
+++ b/src/tools/clippy/src/docs/almost_complete_letter_range.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for ranges which almost include the entire range of letters from 'a' to 'z', but
+don't because they're a half open range.
+
+### Why is this bad?
+This (`'a'..'z'`) is almost certainly a typo meant to include all letters.
+
+### Example
+```
+let _ = 'a'..'z';
+```
+Use instead:
+```
+let _ = 'a'..='z';
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/almost_swapped.txt b/src/tools/clippy/src/docs/almost_swapped.txt
new file mode 100644
index 000000000..cd10a8d54
--- /dev/null
+++ b/src/tools/clippy/src/docs/almost_swapped.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for `foo = bar; bar = foo` sequences.
+
+### Why is this bad?
+This looks like a failed attempt to swap.
+
+### Example
+```
+a = b;
+b = a;
+```
+If swapping is intended, use `swap()` instead:
+```
+std::mem::swap(&mut a, &mut b);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/approx_constant.txt b/src/tools/clippy/src/docs/approx_constant.txt
new file mode 100644
index 000000000..393fa4b5e
--- /dev/null
+++ b/src/tools/clippy/src/docs/approx_constant.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for floating point literals that approximate
+constants which are defined in
+[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
+or
+[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
+respectively, suggesting to use the predefined constant.
+
+### Why is this bad?
+Usually, the definition in the standard library is more
+precise than what people come up with. If you find that your definition is
+actually more precise, please [file a Rust
+issue](https://github.com/rust-lang/rust/issues).
+
+### Example
+```
+let x = 3.14;
+let y = 1_f64 / x;
+```
+Use instead:
+```
+let x = std::f32::consts::PI;
+let y = std::f64::consts::FRAC_1_PI;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/arithmetic_side_effects.txt b/src/tools/clippy/src/docs/arithmetic_side_effects.txt
new file mode 100644
index 000000000..6c7d51a49
--- /dev/null
+++ b/src/tools/clippy/src/docs/arithmetic_side_effects.txt
@@ -0,0 +1,33 @@
+### What it does
+Checks any kind of arithmetic operation of any type.
+
+Operators like `+`, `-`, `*` or `<<` are usually capable of overflowing according to the [Rust
+Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
+or can panic (`/`, `%`).
+
+Known safe built-in types like `Wrapping` or `Saturing`, floats, operations in constant
+environments, allowed types and non-constant operations that won't overflow are ignored.
+
+### Why is this bad?
+For integers, overflow will trigger a panic in debug builds or wrap the result in
+release mode; division by zero will cause a panic in either mode. As a result, it is
+desirable to explicitly call checked, wrapping or saturating arithmetic methods.
+
+#### Example
+```
+// `n` can be any number, including `i32::MAX`.
+fn foo(n: i32) -> i32 {
+ n + 1
+}
+```
+
+Third-party types can also overflow or present unwanted side-effects.
+
+#### Example
+```
+use rust_decimal::Decimal;
+let _n = Decimal::MAX + Decimal::MAX;
+```
+
+### Allowed types
+Custom allowed types can be specified through the "arithmetic-side-effects-allowed" filter. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/as_conversions.txt b/src/tools/clippy/src/docs/as_conversions.txt
new file mode 100644
index 000000000..4af479bd8
--- /dev/null
+++ b/src/tools/clippy/src/docs/as_conversions.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for usage of `as` conversions.
+
+Note that this lint is specialized in linting *every single* use of `as`
+regardless of whether good alternatives exist or not.
+If you want more precise lints for `as`, please consider using these separate lints:
+`unnecessary_cast`, `cast_lossless/cast_possible_truncation/cast_possible_wrap/cast_precision_loss/cast_sign_loss`,
+`fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.
+There is a good explanation the reason why this lint should work in this way and how it is useful
+[in this issue](https://github.com/rust-lang/rust-clippy/issues/5122).
+
+### Why is this bad?
+`as` conversions will perform many kinds of
+conversions, including silently lossy conversions and dangerous coercions.
+There are cases when it makes sense to use `as`, so the lint is
+Allow by default.
+
+### Example
+```
+let a: u32;
+...
+f(a as u16);
+```
+
+Use instead:
+```
+f(a.try_into()?);
+
+// or
+
+f(a.try_into().expect("Unexpected u16 overflow in f"));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/as_underscore.txt b/src/tools/clippy/src/docs/as_underscore.txt
new file mode 100644
index 000000000..2d9b0c358
--- /dev/null
+++ b/src/tools/clippy/src/docs/as_underscore.txt
@@ -0,0 +1,21 @@
+### What it does
+Check for the usage of `as _` conversion using inferred type.
+
+### Why is this bad?
+The conversion might include lossy conversion and dangerous cast that might go
+undetected due to the type being inferred.
+
+The lint is allowed by default as using `_` is less wordy than always specifying the type.
+
+### Example
+```
+fn foo(n: usize) {}
+let n: u16 = 256;
+foo(n as _);
+```
+Use instead:
+```
+fn foo(n: usize) {}
+let n: u16 = 256;
+foo(n as usize);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/assertions_on_constants.txt b/src/tools/clippy/src/docs/assertions_on_constants.txt
new file mode 100644
index 000000000..270c1e3b6
--- /dev/null
+++ b/src/tools/clippy/src/docs/assertions_on_constants.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for `assert!(true)` and `assert!(false)` calls.
+
+### Why is this bad?
+Will be optimized out by the compiler or should probably be replaced by a
+`panic!()` or `unreachable!()`
+
+### Example
+```
+assert!(false)
+assert!(true)
+const B: bool = false;
+assert!(B)
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/assertions_on_result_states.txt b/src/tools/clippy/src/docs/assertions_on_result_states.txt
new file mode 100644
index 000000000..0889084fd
--- /dev/null
+++ b/src/tools/clippy/src/docs/assertions_on_result_states.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls.
+
+### Why is this bad?
+An assertion failure cannot output an useful message of the error.
+
+### Known problems
+The suggested replacement decreases the readability of code and log output.
+
+### Example
+```
+assert!(r.is_ok());
+assert!(r.is_err());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/assign_op_pattern.txt b/src/tools/clippy/src/docs/assign_op_pattern.txt
new file mode 100644
index 000000000..f355c0cc1
--- /dev/null
+++ b/src/tools/clippy/src/docs/assign_op_pattern.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for `a = a op b` or `a = b commutative_op a`
+patterns.
+
+### Why is this bad?
+These can be written as the shorter `a op= b`.
+
+### Known problems
+While forbidden by the spec, `OpAssign` traits may have
+implementations that differ from the regular `Op` impl.
+
+### Example
+```
+let mut a = 5;
+let b = 0;
+// ...
+
+a = a + b;
+```
+
+Use instead:
+```
+let mut a = 5;
+let b = 0;
+// ...
+
+a += b;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/async_yields_async.txt b/src/tools/clippy/src/docs/async_yields_async.txt
new file mode 100644
index 000000000..a40de6d2e
--- /dev/null
+++ b/src/tools/clippy/src/docs/async_yields_async.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for async blocks that yield values of types
+that can themselves be awaited.
+
+### Why is this bad?
+An await is likely missing.
+
+### Example
+```
+async fn foo() {}
+
+fn bar() {
+ let x = async {
+ foo()
+ };
+}
+```
+
+Use instead:
+```
+async fn foo() {}
+
+fn bar() {
+ let x = async {
+ foo().await
+ };
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/await_holding_invalid_type.txt b/src/tools/clippy/src/docs/await_holding_invalid_type.txt
new file mode 100644
index 000000000..e9c768772
--- /dev/null
+++ b/src/tools/clippy/src/docs/await_holding_invalid_type.txt
@@ -0,0 +1,29 @@
+### What it does
+Allows users to configure types which should not be held across `await`
+suspension points.
+
+### Why is this bad?
+There are some types which are perfectly "safe" to be used concurrently
+from a memory access perspective but will cause bugs at runtime if they
+are held in such a way.
+
+### Example
+
+```
+await-holding-invalid-types = [
+ # You can specify a type name
+ "CustomLockType",
+ # You can (optionally) specify a reason
+ { path = "OtherCustomLockType", reason = "Relies on a thread local" }
+]
+```
+
+```
+struct CustomLockType;
+struct OtherCustomLockType;
+async fn foo() {
+ let _x = CustomLockType;
+ let _y = OtherCustomLockType;
+ baz().await; // Lint violation
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/await_holding_lock.txt b/src/tools/clippy/src/docs/await_holding_lock.txt
new file mode 100644
index 000000000..0f450a111
--- /dev/null
+++ b/src/tools/clippy/src/docs/await_holding_lock.txt
@@ -0,0 +1,51 @@
+### What it does
+Checks for calls to await while holding a non-async-aware MutexGuard.
+
+### Why is this bad?
+The Mutex types found in std::sync and parking_lot
+are not designed to operate in an async context across await points.
+
+There are two potential solutions. One is to use an async-aware Mutex
+type. Many asynchronous foundation crates provide such a Mutex type. The
+other solution is to ensure the mutex is unlocked before calling await,
+either by introducing a scope or an explicit call to Drop::drop.
+
+### Known problems
+Will report false positive for explicitly dropped guards
+([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A workaround for this is
+to wrap the `.lock()` call in a block instead of explicitly dropping the guard.
+
+### Example
+```
+async fn foo(x: &Mutex<u32>) {
+ let mut guard = x.lock().unwrap();
+ *guard += 1;
+ baz().await;
+}
+
+async fn bar(x: &Mutex<u32>) {
+ let mut guard = x.lock().unwrap();
+ *guard += 1;
+ drop(guard); // explicit drop
+ baz().await;
+}
+```
+
+Use instead:
+```
+async fn foo(x: &Mutex<u32>) {
+ {
+ let mut guard = x.lock().unwrap();
+ *guard += 1;
+ }
+ baz().await;
+}
+
+async fn bar(x: &Mutex<u32>) {
+ {
+ let mut guard = x.lock().unwrap();
+ *guard += 1;
+ } // guard dropped here at end of scope
+ baz().await;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/await_holding_refcell_ref.txt b/src/tools/clippy/src/docs/await_holding_refcell_ref.txt
new file mode 100644
index 000000000..226a261b9
--- /dev/null
+++ b/src/tools/clippy/src/docs/await_holding_refcell_ref.txt
@@ -0,0 +1,47 @@
+### What it does
+Checks for calls to await while holding a `RefCell` `Ref` or `RefMut`.
+
+### Why is this bad?
+`RefCell` refs only check for exclusive mutable access
+at runtime. Holding onto a `RefCell` ref across an `await` suspension point
+risks panics from a mutable ref shared while other refs are outstanding.
+
+### Known problems
+Will report false positive for explicitly dropped refs
+([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). A workaround for this is
+to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.
+
+### Example
+```
+async fn foo(x: &RefCell<u32>) {
+ let mut y = x.borrow_mut();
+ *y += 1;
+ baz().await;
+}
+
+async fn bar(x: &RefCell<u32>) {
+ let mut y = x.borrow_mut();
+ *y += 1;
+ drop(y); // explicit drop
+ baz().await;
+}
+```
+
+Use instead:
+```
+async fn foo(x: &RefCell<u32>) {
+ {
+ let mut y = x.borrow_mut();
+ *y += 1;
+ }
+ baz().await;
+}
+
+async fn bar(x: &RefCell<u32>) {
+ {
+ let mut y = x.borrow_mut();
+ *y += 1;
+ } // y dropped here at end of scope
+ baz().await;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bad_bit_mask.txt b/src/tools/clippy/src/docs/bad_bit_mask.txt
new file mode 100644
index 000000000..d40024ee5
--- /dev/null
+++ b/src/tools/clippy/src/docs/bad_bit_mask.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for incompatible bit masks in comparisons.
+
+The formula for detecting if an expression of the type `_ <bit_op> m
+<cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
+{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following
+table:
+
+|Comparison |Bit Op|Example |is always|Formula |
+|------------|------|-------------|---------|----------------------|
+|`==` or `!=`| `&` |`x & 2 == 3` |`false` |`c & m != c` |
+|`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |
+|`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |
+|`==` or `!=`| `\|` |`x \| 1 == 0`|`false` |`c \| m != c` |
+|`<` or `>=`| `\|` |`x \| 1 < 1` |`false` |`m >= c` |
+|`<=` or `>` | `\|` |`x \| 1 > 0` |`true` |`m > c` |
+
+### Why is this bad?
+If the bits that the comparison cares about are always
+set to zero or one by the bit mask, the comparison is constant `true` or
+`false` (depending on mask, compared value, and operators).
+
+So the code is actively misleading, and the only reason someone would write
+this intentionally is to win an underhanded Rust contest or create a
+test-case for this lint.
+
+### Example
+```
+if (x & 1 == 2) { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bind_instead_of_map.txt b/src/tools/clippy/src/docs/bind_instead_of_map.txt
new file mode 100644
index 000000000..148575803
--- /dev/null
+++ b/src/tools/clippy/src/docs/bind_instead_of_map.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or
+`_.or_else(|x| Err(y))`.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.map(|x| y)` or `_.map_err(|x| y)`.
+
+### Example
+```
+let _ = opt().and_then(|s| Some(s.len()));
+let _ = res().and_then(|s| if s.len() == 42 { Ok(10) } else { Ok(20) });
+let _ = res().or_else(|s| if s.len() == 42 { Err(10) } else { Err(20) });
+```
+
+The correct use would be:
+
+```
+let _ = opt().map(|s| s.len());
+let _ = res().map(|s| if s.len() == 42 { 10 } else { 20 });
+let _ = res().map_err(|s| if s.len() == 42 { 10 } else { 20 });
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt b/src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt
new file mode 100644
index 000000000..28a4ebf71
--- /dev/null
+++ b/src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
+
+### Why is this bad?
+Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
+These lints should only be enabled on a lint-by-lint basis and with careful consideration.
+
+### Example
+```
+#![deny(clippy::restriction)]
+```
+
+Use instead:
+```
+#![deny(clippy::as_conversions)]
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/blocks_in_if_conditions.txt b/src/tools/clippy/src/docs/blocks_in_if_conditions.txt
new file mode 100644
index 000000000..3afa14853
--- /dev/null
+++ b/src/tools/clippy/src/docs/blocks_in_if_conditions.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for `if` conditions that use blocks containing an
+expression, statements or conditions that use closures with blocks.
+
+### Why is this bad?
+Style, using blocks in the condition makes it hard to read.
+
+### Examples
+```
+if { true } { /* ... */ }
+
+if { let x = somefunc(); x } { /* ... */ }
+```
+
+Use instead:
+```
+if true { /* ... */ }
+
+let res = { let x = somefunc(); x };
+if res { /* ... */ }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bool_assert_comparison.txt b/src/tools/clippy/src/docs/bool_assert_comparison.txt
new file mode 100644
index 000000000..df7ca00cc
--- /dev/null
+++ b/src/tools/clippy/src/docs/bool_assert_comparison.txt
@@ -0,0 +1,16 @@
+### What it does
+This lint warns about boolean comparisons in assert-like macros.
+
+### Why is this bad?
+It is shorter to use the equivalent.
+
+### Example
+```
+assert_eq!("a".is_empty(), false);
+assert_ne!("a".is_empty(), true);
+```
+
+Use instead:
+```
+assert!(!"a".is_empty());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bool_comparison.txt b/src/tools/clippy/src/docs/bool_comparison.txt
new file mode 100644
index 000000000..0996f60ce
--- /dev/null
+++ b/src/tools/clippy/src/docs/bool_comparison.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for expressions of the form `x == true`,
+`x != true` and order comparisons such as `x < true` (or vice versa) and
+suggest using the variable directly.
+
+### Why is this bad?
+Unnecessary code.
+
+### Example
+```
+if x == true {}
+if y == false {}
+```
+use `x` directly:
+```
+if x {}
+if !y {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bool_to_int_with_if.txt b/src/tools/clippy/src/docs/bool_to_int_with_if.txt
new file mode 100644
index 000000000..63535b454
--- /dev/null
+++ b/src/tools/clippy/src/docs/bool_to_int_with_if.txt
@@ -0,0 +1,26 @@
+### What it does
+Instead of using an if statement to convert a bool to an int,
+this lint suggests using a `from()` function or an `as` coercion.
+
+### Why is this bad?
+Coercion or `from()` is idiomatic way to convert bool to a number.
+Both methods are guaranteed to return 1 for true, and 0 for false.
+
+See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
+
+### Example
+```
+if condition {
+ 1_i64
+} else {
+ 0
+};
+```
+Use instead:
+```
+i64::from(condition);
+```
+or
+```
+condition as i64;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrow_as_ptr.txt b/src/tools/clippy/src/docs/borrow_as_ptr.txt
new file mode 100644
index 000000000..0be865abd
--- /dev/null
+++ b/src/tools/clippy/src/docs/borrow_as_ptr.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for the usage of `&expr as *const T` or
+`&mut expr as *mut T`, and suggest using `ptr::addr_of` or
+`ptr::addr_of_mut` instead.
+
+### Why is this bad?
+This would improve readability and avoid creating a reference
+that points to an uninitialized value or unaligned place.
+Read the `ptr::addr_of` docs for more information.
+
+### Example
+```
+let val = 1;
+let p = &val as *const i32;
+
+let mut val_mut = 1;
+let p_mut = &mut val_mut as *mut i32;
+```
+Use instead:
+```
+let val = 1;
+let p = std::ptr::addr_of!(val);
+
+let mut val_mut = 1;
+let p_mut = std::ptr::addr_of_mut!(val_mut);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrow_deref_ref.txt b/src/tools/clippy/src/docs/borrow_deref_ref.txt
new file mode 100644
index 000000000..352480d3f
--- /dev/null
+++ b/src/tools/clippy/src/docs/borrow_deref_ref.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for `&*(&T)`.
+
+### Why is this bad?
+Dereferencing and then borrowing a reference value has no effect in most cases.
+
+### Known problems
+False negative on such code:
+```
+let x = &12;
+let addr_x = &x as *const _ as usize;
+let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.
+ // But if we fix it, assert will fail.
+assert_ne!(addr_x, addr_y);
+```
+
+### Example
+```
+let s = &String::new();
+
+let a: &String = &* s;
+```
+
+Use instead:
+```
+let a: &String = s;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrow_interior_mutable_const.txt b/src/tools/clippy/src/docs/borrow_interior_mutable_const.txt
new file mode 100644
index 000000000..e55b6a77e
--- /dev/null
+++ b/src/tools/clippy/src/docs/borrow_interior_mutable_const.txt
@@ -0,0 +1,40 @@
+### What it does
+Checks if `const` items which is interior mutable (e.g.,
+contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.
+
+### Why is this bad?
+Consts are copied everywhere they are referenced, i.e.,
+every time you refer to the const a fresh instance of the `Cell` or `Mutex`
+or `AtomicXxxx` will be created, which defeats the whole purpose of using
+these types in the first place.
+
+The `const` value should be stored inside a `static` item.
+
+### Known problems
+When an enum has variants with interior mutability, use of its non
+interior mutable variants can generate false positives. See issue
+[#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
+
+Types that have underlying or potential interior mutability trigger the lint whether
+the interior mutable field is used or not. See issues
+[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
+[#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
+
+### Example
+```
+use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
+
+CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
+assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
+```
+
+Use instead:
+```
+use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
+
+static STATIC_ATOM: AtomicUsize = CONST_ATOM;
+STATIC_ATOM.store(9, SeqCst);
+assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrowed_box.txt b/src/tools/clippy/src/docs/borrowed_box.txt
new file mode 100644
index 000000000..d7089be66
--- /dev/null
+++ b/src/tools/clippy/src/docs/borrowed_box.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for use of `&Box<T>` anywhere in the code.
+Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
+
+### Why is this bad?
+A `&Box<T>` parameter requires the function caller to box `T` first before passing it to a function.
+Using `&T` defines a concrete type for the parameter and generalizes the function, this would also
+auto-deref to `&T` at the function call site if passed a `&Box<T>`.
+
+### Example
+```
+fn foo(bar: &Box<T>) { ... }
+```
+
+Better:
+
+```
+fn foo(bar: &T) { ... }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/box_collection.txt b/src/tools/clippy/src/docs/box_collection.txt
new file mode 100644
index 000000000..053f24c46
--- /dev/null
+++ b/src/tools/clippy/src/docs/box_collection.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for use of `Box<T>` where T is a collection such as Vec anywhere in the code.
+Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
+
+### Why is this bad?
+Collections already keeps their contents in a separate area on
+the heap. So if you `Box` them, you just add another level of indirection
+without any benefit whatsoever.
+
+### Example
+```
+struct X {
+ values: Box<Vec<Foo>>,
+}
+```
+
+Better:
+
+```
+struct X {
+ values: Vec<Foo>,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/boxed_local.txt b/src/tools/clippy/src/docs/boxed_local.txt
new file mode 100644
index 000000000..8b1febf14
--- /dev/null
+++ b/src/tools/clippy/src/docs/boxed_local.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for usage of `Box<T>` where an unboxed `T` would
+work fine.
+
+### Why is this bad?
+This is an unnecessary allocation, and bad for
+performance. It is only necessary to allocate if you wish to move the box
+into something.
+
+### Example
+```
+fn foo(x: Box<u32>) {}
+```
+
+Use instead:
+```
+fn foo(x: u32) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/branches_sharing_code.txt b/src/tools/clippy/src/docs/branches_sharing_code.txt
new file mode 100644
index 000000000..79be61247
--- /dev/null
+++ b/src/tools/clippy/src/docs/branches_sharing_code.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks if the `if` and `else` block contain shared code that can be
+moved out of the blocks.
+
+### Why is this bad?
+Duplicate code is less maintainable.
+
+### Known problems
+* The lint doesn't check if the moved expressions modify values that are being used in
+ the if condition. The suggestion can in that case modify the behavior of the program.
+ See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452)
+
+### Example
+```
+let foo = if … {
+ println!("Hello World");
+ 13
+} else {
+ println!("Hello World");
+ 42
+};
+```
+
+Use instead:
+```
+println!("Hello World");
+let foo = if … {
+ 13
+} else {
+ 42
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/builtin_type_shadow.txt b/src/tools/clippy/src/docs/builtin_type_shadow.txt
new file mode 100644
index 000000000..15b1c9df7
--- /dev/null
+++ b/src/tools/clippy/src/docs/builtin_type_shadow.txt
@@ -0,0 +1,15 @@
+### What it does
+Warns if a generic shadows a built-in type.
+
+### Why is this bad?
+This gives surprising type errors.
+
+### Example
+
+```
+impl<u32> Foo<u32> {
+ fn impl_func(&self) -> u32 {
+ 42
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bytes_count_to_len.txt b/src/tools/clippy/src/docs/bytes_count_to_len.txt
new file mode 100644
index 000000000..ca7bf9a38
--- /dev/null
+++ b/src/tools/clippy/src/docs/bytes_count_to_len.txt
@@ -0,0 +1,18 @@
+### What it does
+It checks for `str::bytes().count()` and suggests replacing it with
+`str::len()`.
+
+### Why is this bad?
+`str::bytes().count()` is longer and may not be as performant as using
+`str::len()`.
+
+### Example
+```
+"hello".bytes().count();
+String::from("hello").bytes().count();
+```
+Use instead:
+```
+"hello".len();
+String::from("hello").len();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bytes_nth.txt b/src/tools/clippy/src/docs/bytes_nth.txt
new file mode 100644
index 000000000..260de3433
--- /dev/null
+++ b/src/tools/clippy/src/docs/bytes_nth.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for the use of `.bytes().nth()`.
+
+### Why is this bad?
+`.as_bytes().get()` is more efficient and more
+readable.
+
+### Example
+```
+"Hello".bytes().nth(3);
+```
+
+Use instead:
+```
+"Hello".as_bytes().get(3);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cargo_common_metadata.txt b/src/tools/clippy/src/docs/cargo_common_metadata.txt
new file mode 100644
index 000000000..1998647a9
--- /dev/null
+++ b/src/tools/clippy/src/docs/cargo_common_metadata.txt
@@ -0,0 +1,33 @@
+### What it does
+Checks to see if all common metadata is defined in
+`Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
+
+### Why is this bad?
+It will be more difficult for users to discover the
+purpose of the crate, and key information related to it.
+
+### Example
+```
+[package]
+name = "clippy"
+version = "0.0.212"
+repository = "https://github.com/rust-lang/rust-clippy"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+keywords = ["clippy", "lint", "plugin"]
+categories = ["development-tools", "development-tools::cargo-plugins"]
+```
+
+Should include a description field like:
+
+```
+[package]
+name = "clippy"
+version = "0.0.212"
+description = "A bunch of helpful lints to avoid common pitfalls in Rust"
+repository = "https://github.com/rust-lang/rust-clippy"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+keywords = ["clippy", "lint", "plugin"]
+categories = ["development-tools", "development-tools::cargo-plugins"]
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt b/src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt
new file mode 100644
index 000000000..8e6e18ed4
--- /dev/null
+++ b/src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for calls to `ends_with` with possible file extensions
+and suggests to use a case-insensitive approach instead.
+
+### Why is this bad?
+`ends_with` is case-sensitive and may not detect files with a valid extension.
+
+### Example
+```
+fn is_rust_file(filename: &str) -> bool {
+ filename.ends_with(".rs")
+}
+```
+Use instead:
+```
+fn is_rust_file(filename: &str) -> bool {
+ let filename = std::path::Path::new(filename);
+ filename.extension()
+ .map_or(false, |ext| ext.eq_ignore_ascii_case("rs"))
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_abs_to_unsigned.txt b/src/tools/clippy/src/docs/cast_abs_to_unsigned.txt
new file mode 100644
index 000000000..c5d8ee034
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_abs_to_unsigned.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for uses of the `abs()` method that cast the result to unsigned.
+
+### Why is this bad?
+The `unsigned_abs()` method avoids panic when called on the MIN value.
+
+### Example
+```
+let x: i32 = -42;
+let y: u32 = x.abs() as u32;
+```
+Use instead:
+```
+let x: i32 = -42;
+let y: u32 = x.unsigned_abs();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_enum_constructor.txt b/src/tools/clippy/src/docs/cast_enum_constructor.txt
new file mode 100644
index 000000000..675c03a42
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_enum_constructor.txt
@@ -0,0 +1,11 @@
+### What it does
+Checks for casts from an enum tuple constructor to an integer.
+
+### Why is this bad?
+The cast is easily confused with casting a c-like enum value to an integer.
+
+### Example
+```
+enum E { X(i32) };
+let _ = E::X as usize;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_enum_truncation.txt b/src/tools/clippy/src/docs/cast_enum_truncation.txt
new file mode 100644
index 000000000..abe32a829
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_enum_truncation.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for casts from an enum type to an integral type which will definitely truncate the
+value.
+
+### Why is this bad?
+The resulting integral value will not match the value of the variant it came from.
+
+### Example
+```
+enum E { X = 256 };
+let _ = E::X as u8;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_lossless.txt b/src/tools/clippy/src/docs/cast_lossless.txt
new file mode 100644
index 000000000..c3a61dd47
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_lossless.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for casts between numerical types that may
+be replaced by safe conversion functions.
+
+### Why is this bad?
+Rust's `as` keyword will perform many kinds of
+conversions, including silently lossy conversions. Conversion functions such
+as `i32::from` will only perform lossless conversions. Using the conversion
+functions prevents conversions from turning into silent lossy conversions if
+the types of the input expressions ever change, and make it easier for
+people reading the code to know that the conversion is lossless.
+
+### Example
+```
+fn as_u64(x: u8) -> u64 {
+ x as u64
+}
+```
+
+Using `::from` would look like this:
+
+```
+fn as_u64(x: u8) -> u64 {
+ u64::from(x)
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_possible_truncation.txt b/src/tools/clippy/src/docs/cast_possible_truncation.txt
new file mode 100644
index 000000000..0b164848c
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_possible_truncation.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for casts between numerical types that may
+truncate large values. This is expected behavior, so the cast is `Allow` by
+default.
+
+### Why is this bad?
+In some problem domains, it is good practice to avoid
+truncation. This lint can be activated to help assess where additional
+checks could be beneficial.
+
+### Example
+```
+fn as_u8(x: u64) -> u8 {
+ x as u8
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_possible_wrap.txt b/src/tools/clippy/src/docs/cast_possible_wrap.txt
new file mode 100644
index 000000000..f883fc9cf
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_possible_wrap.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for casts from an unsigned type to a signed type of
+the same size. Performing such a cast is a 'no-op' for the compiler,
+i.e., nothing is changed at the bit level, and the binary representation of
+the value is reinterpreted. This can cause wrapping if the value is too big
+for the target signed type. However, the cast works as defined, so this lint
+is `Allow` by default.
+
+### Why is this bad?
+While such a cast is not bad in itself, the results can
+be surprising when this is not the intended behavior, as demonstrated by the
+example below.
+
+### Example
+```
+u32::MAX as i32; // will yield a value of `-1`
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_precision_loss.txt b/src/tools/clippy/src/docs/cast_precision_loss.txt
new file mode 100644
index 000000000..f915d9f8a
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_precision_loss.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for casts from any numerical to a float type where
+the receiving type cannot store all values from the original type without
+rounding errors. This possible rounding is to be expected, so this lint is
+`Allow` by default.
+
+Basically, this warns on casting any integer with 32 or more bits to `f32`
+or any 64-bit integer to `f64`.
+
+### Why is this bad?
+It's not bad at all. But in some applications it can be
+helpful to know where precision loss can take place. This lint can help find
+those places in the code.
+
+### Example
+```
+let x = u64::MAX;
+x as f64;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_ptr_alignment.txt b/src/tools/clippy/src/docs/cast_ptr_alignment.txt
new file mode 100644
index 000000000..6a6d4dcaa
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_ptr_alignment.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for casts, using `as` or `pointer::cast`,
+from a less-strictly-aligned pointer to a more-strictly-aligned pointer
+
+### Why is this bad?
+Dereferencing the resulting pointer may be undefined
+behavior.
+
+### Known problems
+Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar
+on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like
+u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
+
+### Example
+```
+let _ = (&1u8 as *const u8) as *const u16;
+let _ = (&mut 1u8 as *mut u8) as *mut u16;
+
+(&1u8 as *const u8).cast::<u16>();
+(&mut 1u8 as *mut u8).cast::<u16>();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_ref_to_mut.txt b/src/tools/clippy/src/docs/cast_ref_to_mut.txt
new file mode 100644
index 000000000..fb5b4dbb6
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_ref_to_mut.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for casts of `&T` to `&mut T` anywhere in the code.
+
+### Why is this bad?
+It’s basically guaranteed to be undefined behavior.
+`UnsafeCell` is the only way to obtain aliasable data that is considered
+mutable.
+
+### Example
+```
+fn x(r: &i32) {
+ unsafe {
+ *(r as *const _ as *mut _) += 1;
+ }
+}
+```
+
+Instead consider using interior mutability types.
+
+```
+use std::cell::UnsafeCell;
+
+fn x(r: &UnsafeCell<i32>) {
+ unsafe {
+ *r.get() += 1;
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_sign_loss.txt b/src/tools/clippy/src/docs/cast_sign_loss.txt
new file mode 100644
index 000000000..d64fe1b07
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_sign_loss.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for casts from a signed to an unsigned numerical
+type. In this case, negative values wrap around to large positive values,
+which can be quite surprising in practice. However, as the cast works as
+defined, this lint is `Allow` by default.
+
+### Why is this bad?
+Possibly surprising results. You can activate this lint
+as a one-time check to see where numerical wrapping can arise.
+
+### Example
+```
+let y: i8 = -1;
+y as u128; // will return 18446744073709551615
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_slice_different_sizes.txt b/src/tools/clippy/src/docs/cast_slice_different_sizes.txt
new file mode 100644
index 000000000..c01ef0ba9
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_slice_different_sizes.txt
@@ -0,0 +1,38 @@
+### What it does
+Checks for `as` casts between raw pointers to slices with differently sized elements.
+
+### Why is this bad?
+The produced raw pointer to a slice does not update its length metadata. The produced
+pointer will point to a different number of bytes than the original pointer because the
+length metadata of a raw slice pointer is in elements rather than bytes.
+Producing a slice reference from the raw pointer will either create a slice with
+less data (which can be surprising) or create a slice with more data and cause Undefined Behavior.
+
+### Example
+// Missing data
+```
+let a = [1_i32, 2, 3, 4];
+let p = &a as *const [i32] as *const [u8];
+unsafe {
+ println!("{:?}", &*p);
+}
+```
+// Undefined Behavior (note: also potential alignment issues)
+```
+let a = [1_u8, 2, 3, 4];
+let p = &a as *const [u8] as *const [u32];
+unsafe {
+ println!("{:?}", &*p);
+}
+```
+Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
+```
+let a = [1_i32, 2, 3, 4];
+let old_ptr = &a as *const [i32];
+// The data pointer is cast to a pointer to the target `u8` not `[u8]`
+// The length comes from the known length of 4 i32s times the 4 bytes per i32
+let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);
+unsafe {
+ println!("{:?}", &*new_ptr);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt b/src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt
new file mode 100644
index 000000000..b58c73976
--- /dev/null
+++ b/src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for a raw slice being cast to a slice pointer
+
+### Why is this bad?
+This can result in multiple `&mut` references to the same location when only a pointer is
+required.
+`ptr::slice_from_raw_parts` is a safe alternative that doesn't require
+the same [safety requirements] to be upheld.
+
+### Example
+```
+let _: *const [u8] = std::slice::from_raw_parts(ptr, len) as *const _;
+let _: *mut [u8] = std::slice::from_raw_parts_mut(ptr, len) as *mut _;
+```
+Use instead:
+```
+let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, len);
+let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);
+```
+[safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/char_lit_as_u8.txt b/src/tools/clippy/src/docs/char_lit_as_u8.txt
new file mode 100644
index 000000000..00d60b9a4
--- /dev/null
+++ b/src/tools/clippy/src/docs/char_lit_as_u8.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for expressions where a character literal is cast
+to `u8` and suggests using a byte literal instead.
+
+### Why is this bad?
+In general, casting values to smaller types is
+error-prone and should be avoided where possible. In the particular case of
+converting a character literal to u8, it is easy to avoid by just using a
+byte literal instead. As an added bonus, `b'a'` is even slightly shorter
+than `'a' as u8`.
+
+### Example
+```
+'x' as u8
+```
+
+A better version, using the byte literal:
+
+```
+b'x'
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/chars_last_cmp.txt b/src/tools/clippy/src/docs/chars_last_cmp.txt
new file mode 100644
index 000000000..4c1d88389
--- /dev/null
+++ b/src/tools/clippy/src/docs/chars_last_cmp.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for usage of `_.chars().last()` or
+`_.chars().next_back()` on a `str` to check if it ends with a given char.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.ends_with(_)`.
+
+### Example
+```
+name.chars().last() == Some('_') || name.chars().next_back() == Some('-');
+```
+
+Use instead:
+```
+name.ends_with('_') || name.ends_with('-');
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/chars_next_cmp.txt b/src/tools/clippy/src/docs/chars_next_cmp.txt
new file mode 100644
index 000000000..77cbce2de
--- /dev/null
+++ b/src/tools/clippy/src/docs/chars_next_cmp.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `.chars().next()` on a `str` to check
+if it starts with a given char.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.starts_with(_)`.
+
+### Example
+```
+let name = "foo";
+if name.chars().next() == Some('_') {};
+```
+
+Use instead:
+```
+let name = "foo";
+if name.starts_with('_') {};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/checked_conversions.txt b/src/tools/clippy/src/docs/checked_conversions.txt
new file mode 100644
index 000000000..536b01294
--- /dev/null
+++ b/src/tools/clippy/src/docs/checked_conversions.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for explicit bounds checking when casting.
+
+### Why is this bad?
+Reduces the readability of statements & is error prone.
+
+### Example
+```
+foo <= i32::MAX as u32;
+```
+
+Use instead:
+```
+i32::try_from(foo).is_ok();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/clone_double_ref.txt b/src/tools/clippy/src/docs/clone_double_ref.txt
new file mode 100644
index 000000000..2729635bd
--- /dev/null
+++ b/src/tools/clippy/src/docs/clone_double_ref.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of `.clone()` on an `&&T`.
+
+### Why is this bad?
+Cloning an `&&T` copies the inner `&T`, instead of
+cloning the underlying `T`.
+
+### Example
+```
+fn main() {
+ let x = vec![1];
+ let y = &&x;
+ let z = y.clone();
+ println!("{:p} {:p}", *y, z); // prints out the same pointer
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/clone_on_copy.txt b/src/tools/clippy/src/docs/clone_on_copy.txt
new file mode 100644
index 000000000..99a0bdb4c
--- /dev/null
+++ b/src/tools/clippy/src/docs/clone_on_copy.txt
@@ -0,0 +1,11 @@
+### What it does
+Checks for usage of `.clone()` on a `Copy` type.
+
+### Why is this bad?
+The only reason `Copy` types implement `Clone` is for
+generics, not for using the `clone` method on a concrete type.
+
+### Example
+```
+42u64.clone();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/clone_on_ref_ptr.txt b/src/tools/clippy/src/docs/clone_on_ref_ptr.txt
new file mode 100644
index 000000000..2d83f8fef
--- /dev/null
+++ b/src/tools/clippy/src/docs/clone_on_ref_ptr.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for usage of `.clone()` on a ref-counted pointer,
+(`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified
+function syntax instead (e.g., `Rc::clone(foo)`).
+
+### Why is this bad?
+Calling '.clone()' on an Rc, Arc, or Weak
+can obscure the fact that only the pointer is being cloned, not the underlying
+data.
+
+### Example
+```
+let x = Rc::new(1);
+
+x.clone();
+```
+
+Use instead:
+```
+Rc::clone(&x);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cloned_instead_of_copied.txt b/src/tools/clippy/src/docs/cloned_instead_of_copied.txt
new file mode 100644
index 000000000..2f2014d5f
--- /dev/null
+++ b/src/tools/clippy/src/docs/cloned_instead_of_copied.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usages of `cloned()` on an `Iterator` or `Option` where
+`copied()` could be used instead.
+
+### Why is this bad?
+`copied()` is better because it guarantees that the type being cloned
+implements `Copy`.
+
+### Example
+```
+[1, 2, 3].iter().cloned();
+```
+Use instead:
+```
+[1, 2, 3].iter().copied();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cmp_nan.txt b/src/tools/clippy/src/docs/cmp_nan.txt
new file mode 100644
index 000000000..e2ad04d93
--- /dev/null
+++ b/src/tools/clippy/src/docs/cmp_nan.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for comparisons to NaN.
+
+### Why is this bad?
+NaN does not compare meaningfully to anything – not
+even itself – so those comparisons are simply wrong.
+
+### Example
+```
+if x == f32::NAN { }
+```
+
+Use instead:
+```
+if x.is_nan() { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cmp_null.txt b/src/tools/clippy/src/docs/cmp_null.txt
new file mode 100644
index 000000000..02fd15124
--- /dev/null
+++ b/src/tools/clippy/src/docs/cmp_null.txt
@@ -0,0 +1,23 @@
+### What it does
+This lint checks for equality comparisons with `ptr::null`
+
+### Why is this bad?
+It's easier and more readable to use the inherent
+`.is_null()`
+method instead
+
+### Example
+```
+use std::ptr;
+
+if x == ptr::null {
+ // ..
+}
+```
+
+Use instead:
+```
+if x.is_null() {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cmp_owned.txt b/src/tools/clippy/src/docs/cmp_owned.txt
new file mode 100644
index 000000000..f8d4956ff
--- /dev/null
+++ b/src/tools/clippy/src/docs/cmp_owned.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for conversions to owned values just for the sake
+of a comparison.
+
+### Why is this bad?
+The comparison can operate on a reference, so creating
+an owned value effectively throws it away directly afterwards, which is
+needlessly consuming code and heap space.
+
+### Example
+```
+if x.to_owned() == y {}
+```
+
+Use instead:
+```
+if x == y {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cognitive_complexity.txt b/src/tools/clippy/src/docs/cognitive_complexity.txt
new file mode 100644
index 000000000..fdd75f647
--- /dev/null
+++ b/src/tools/clippy/src/docs/cognitive_complexity.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for methods with high cognitive complexity.
+
+### Why is this bad?
+Methods of high cognitive complexity tend to be hard to
+both read and maintain. Also LLVM will tend to optimize small methods better.
+
+### Known problems
+Sometimes it's hard to find a way to reduce the
+complexity.
+
+### Example
+You'll see it when you get the warning. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_else_if.txt b/src/tools/clippy/src/docs/collapsible_else_if.txt
new file mode 100644
index 000000000..4ddfca177
--- /dev/null
+++ b/src/tools/clippy/src/docs/collapsible_else_if.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for collapsible `else { if ... }` expressions
+that can be collapsed to `else if ...`.
+
+### Why is this bad?
+Each `if`-statement adds one level of nesting, which
+makes code look more complex than it really is.
+
+### Example
+```
+
+if x {
+ …
+} else {
+ if y {
+ …
+ }
+}
+```
+
+Should be written:
+
+```
+if x {
+ …
+} else if y {
+ …
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_if.txt b/src/tools/clippy/src/docs/collapsible_if.txt
new file mode 100644
index 000000000..e1264ee06
--- /dev/null
+++ b/src/tools/clippy/src/docs/collapsible_if.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for nested `if` statements which can be collapsed
+by `&&`-combining their conditions.
+
+### Why is this bad?
+Each `if`-statement adds one level of nesting, which
+makes code look more complex than it really is.
+
+### Example
+```
+if x {
+ if y {
+ // …
+ }
+}
+```
+
+Use instead:
+```
+if x && y {
+ // …
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_match.txt b/src/tools/clippy/src/docs/collapsible_match.txt
new file mode 100644
index 000000000..0d59594a0
--- /dev/null
+++ b/src/tools/clippy/src/docs/collapsible_match.txt
@@ -0,0 +1,31 @@
+### What it does
+Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together
+without adding any branches.
+
+Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only
+cases where merging would most likely make the code more readable.
+
+### Why is this bad?
+It is unnecessarily verbose and complex.
+
+### Example
+```
+fn func(opt: Option<Result<u64, String>>) {
+ let n = match opt {
+ Some(n) => match n {
+ Ok(n) => n,
+ _ => return,
+ }
+ None => return,
+ };
+}
+```
+Use instead:
+```
+fn func(opt: Option<Result<u64, String>>) {
+ let n = match opt {
+ Some(Ok(n)) => n,
+ _ => return,
+ };
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_str_replace.txt b/src/tools/clippy/src/docs/collapsible_str_replace.txt
new file mode 100644
index 000000000..c24c25a30
--- /dev/null
+++ b/src/tools/clippy/src/docs/collapsible_str_replace.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for consecutive calls to `str::replace` (2 or more)
+that can be collapsed into a single call.
+
+### Why is this bad?
+Consecutive `str::replace` calls scan the string multiple times
+with repetitive code.
+
+### Example
+```
+let hello = "hesuo worpd"
+ .replace('s', "l")
+ .replace("u", "l")
+ .replace('p', "l");
+```
+Use instead:
+```
+let hello = "hesuo worpd".replace(&['s', 'u', 'p'], "l");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/comparison_chain.txt b/src/tools/clippy/src/docs/comparison_chain.txt
new file mode 100644
index 000000000..43b09f31f
--- /dev/null
+++ b/src/tools/clippy/src/docs/comparison_chain.txt
@@ -0,0 +1,36 @@
+### What it does
+Checks comparison chains written with `if` that can be
+rewritten with `match` and `cmp`.
+
+### Why is this bad?
+`if` is not guaranteed to be exhaustive and conditionals can get
+repetitive
+
+### Known problems
+The match statement may be slower due to the compiler
+not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354)
+
+### Example
+```
+fn f(x: u8, y: u8) {
+ if x > y {
+ a()
+ } else if x < y {
+ b()
+ } else {
+ c()
+ }
+}
+```
+
+Use instead:
+```
+use std::cmp::Ordering;
+fn f(x: u8, y: u8) {
+ match x.cmp(&y) {
+ Ordering::Greater => a(),
+ Ordering::Less => b(),
+ Ordering::Equal => c()
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/comparison_to_empty.txt b/src/tools/clippy/src/docs/comparison_to_empty.txt
new file mode 100644
index 000000000..db6f74fe2
--- /dev/null
+++ b/src/tools/clippy/src/docs/comparison_to_empty.txt
@@ -0,0 +1,31 @@
+### What it does
+Checks for comparing to an empty slice such as `""` or `[]`,
+and suggests using `.is_empty()` where applicable.
+
+### Why is this bad?
+Some structures can answer `.is_empty()` much faster
+than checking for equality. So it is good to get into the habit of using
+`.is_empty()`, and having it is cheap.
+Besides, it makes the intent clearer than a manual comparison in some contexts.
+
+### Example
+
+```
+if s == "" {
+ ..
+}
+
+if arr == [] {
+ ..
+}
+```
+Use instead:
+```
+if s.is_empty() {
+ ..
+}
+
+if arr.is_empty() {
+ ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/copy_iterator.txt b/src/tools/clippy/src/docs/copy_iterator.txt
new file mode 100644
index 000000000..5f9a2a015
--- /dev/null
+++ b/src/tools/clippy/src/docs/copy_iterator.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for types that implement `Copy` as well as
+`Iterator`.
+
+### Why is this bad?
+Implicit copies can be confusing when working with
+iterator combinators.
+
+### Example
+```
+#[derive(Copy, Clone)]
+struct Countdown(u8);
+
+impl Iterator for Countdown {
+ // ...
+}
+
+let a: Vec<_> = my_iterator.take(1).collect();
+let b: Vec<_> = my_iterator.collect();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/crate_in_macro_def.txt b/src/tools/clippy/src/docs/crate_in_macro_def.txt
new file mode 100644
index 000000000..047e986de
--- /dev/null
+++ b/src/tools/clippy/src/docs/crate_in_macro_def.txt
@@ -0,0 +1,35 @@
+### What it does
+Checks for use of `crate` as opposed to `$crate` in a macro definition.
+
+### Why is this bad?
+`crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's
+crate. Rarely is the former intended. See:
+https://doc.rust-lang.org/reference/macros-by-example.html#hygiene
+
+### Example
+```
+#[macro_export]
+macro_rules! print_message {
+ () => {
+ println!("{}", crate::MESSAGE);
+ };
+}
+pub const MESSAGE: &str = "Hello!";
+```
+Use instead:
+```
+#[macro_export]
+macro_rules! print_message {
+ () => {
+ println!("{}", $crate::MESSAGE);
+ };
+}
+pub const MESSAGE: &str = "Hello!";
+```
+
+Note that if the use of `crate` is intentional, an `allow` attribute can be applied to the
+macro definition, e.g.:
+```
+#[allow(clippy::crate_in_macro_def)]
+macro_rules! ok { ... crate::foo ... }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/create_dir.txt b/src/tools/clippy/src/docs/create_dir.txt
new file mode 100644
index 000000000..e4e793768
--- /dev/null
+++ b/src/tools/clippy/src/docs/create_dir.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
+
+### Why is this bad?
+Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
+
+### Example
+```
+std::fs::create_dir("foo");
+```
+
+Use instead:
+```
+std::fs::create_dir_all("foo");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/crosspointer_transmute.txt b/src/tools/clippy/src/docs/crosspointer_transmute.txt
new file mode 100644
index 000000000..49dea1549
--- /dev/null
+++ b/src/tools/clippy/src/docs/crosspointer_transmute.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for transmutes between a type `T` and `*T`.
+
+### Why is this bad?
+It's easy to mistakenly transmute between a type and a
+pointer to that type.
+
+### Example
+```
+core::intrinsics::transmute(t) // where the result type is the same as
+ // `*t` or `&t`'s
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/dbg_macro.txt b/src/tools/clippy/src/docs/dbg_macro.txt
new file mode 100644
index 000000000..3e1a9a043
--- /dev/null
+++ b/src/tools/clippy/src/docs/dbg_macro.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of dbg!() macro.
+
+### Why is this bad?
+`dbg!` macro is intended as a debugging tool. It
+should not be in version control.
+
+### Example
+```
+dbg!(true)
+```
+
+Use instead:
+```
+true
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/debug_assert_with_mut_call.txt b/src/tools/clippy/src/docs/debug_assert_with_mut_call.txt
new file mode 100644
index 000000000..2c44abe1f
--- /dev/null
+++ b/src/tools/clippy/src/docs/debug_assert_with_mut_call.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for function/method calls with a mutable
+parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros.
+
+### Why is this bad?
+In release builds `debug_assert!` macros are optimized out by the
+compiler.
+Therefore mutating something in a `debug_assert!` macro results in different behavior
+between a release and debug build.
+
+### Example
+```
+debug_assert_eq!(vec![3].pop(), Some(3));
+
+// or
+
+debug_assert!(takes_a_mut_parameter(&mut x));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/decimal_literal_representation.txt b/src/tools/clippy/src/docs/decimal_literal_representation.txt
new file mode 100644
index 000000000..daca9bbb3
--- /dev/null
+++ b/src/tools/clippy/src/docs/decimal_literal_representation.txt
@@ -0,0 +1,13 @@
+### What it does
+Warns if there is a better representation for a numeric literal.
+
+### Why is this bad?
+Especially for big powers of 2 a hexadecimal representation is more
+readable than a decimal representation.
+
+### Example
+```
+`255` => `0xFF`
+`65_535` => `0xFFFF`
+`4_042_322_160` => `0xF0F0_F0F0`
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/declare_interior_mutable_const.txt b/src/tools/clippy/src/docs/declare_interior_mutable_const.txt
new file mode 100644
index 000000000..2801b5ccf
--- /dev/null
+++ b/src/tools/clippy/src/docs/declare_interior_mutable_const.txt
@@ -0,0 +1,46 @@
+### What it does
+Checks for declaration of `const` items which is interior
+mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).
+
+### Why is this bad?
+Consts are copied everywhere they are referenced, i.e.,
+every time you refer to the const a fresh instance of the `Cell` or `Mutex`
+or `AtomicXxxx` will be created, which defeats the whole purpose of using
+these types in the first place.
+
+The `const` should better be replaced by a `static` item if a global
+variable is wanted, or replaced by a `const fn` if a constructor is wanted.
+
+### Known problems
+A "non-constant" const item is a legacy way to supply an
+initialized value to downstream `static` items (e.g., the
+`std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
+and this lint should be suppressed.
+
+Even though the lint avoids triggering on a constant whose type has enums that have variants
+with interior mutability, and its value uses non interior mutable variants (see
+[#3962](https://github.com/rust-lang/rust-clippy/issues/3962) and
+[#3825](https://github.com/rust-lang/rust-clippy/issues/3825) for examples);
+it complains about associated constants without default values only based on its types;
+which might not be preferable.
+There're other enums plus associated constants cases that the lint cannot handle.
+
+Types that have underlying or potential interior mutability trigger the lint whether
+the interior mutable field is used or not. See issues
+[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
+
+### Example
+```
+use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+
+const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
+CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
+assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
+```
+
+Use instead:
+```
+static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
+STATIC_ATOM.store(9, SeqCst);
+assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_instead_of_iter_empty.txt b/src/tools/clippy/src/docs/default_instead_of_iter_empty.txt
new file mode 100644
index 000000000..b63ef3d18
--- /dev/null
+++ b/src/tools/clippy/src/docs/default_instead_of_iter_empty.txt
@@ -0,0 +1,15 @@
+### What it does
+It checks for `std::iter::Empty::default()` and suggests replacing it with
+`std::iter::empty()`.
+### Why is this bad?
+`std::iter::empty()` is the more idiomatic way.
+### Example
+```
+let _ = std::iter::Empty::<usize>::default();
+let iter: std::iter::Empty<usize> = std::iter::Empty::default();
+```
+Use instead:
+```
+let _ = std::iter::empty::<usize>();
+let iter: std::iter::Empty<usize> = std::iter::empty();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_numeric_fallback.txt b/src/tools/clippy/src/docs/default_numeric_fallback.txt
new file mode 100644
index 000000000..15076a0a6
--- /dev/null
+++ b/src/tools/clippy/src/docs/default_numeric_fallback.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
+inference.
+
+Default numeric fallback means that if numeric types have not yet been bound to concrete
+types at the end of type inference, then integer type is bound to `i32`, and similarly
+floating type is bound to `f64`.
+
+See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.
+
+### Why is this bad?
+For those who are very careful about types, default numeric fallback
+can be a pitfall that cause unexpected runtime behavior.
+
+### Known problems
+This lint can only be allowed at the function level or above.
+
+### Example
+```
+let i = 10;
+let f = 1.23;
+```
+
+Use instead:
+```
+let i = 10i32;
+let f = 1.23f64;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_trait_access.txt b/src/tools/clippy/src/docs/default_trait_access.txt
new file mode 100644
index 000000000..e69298969
--- /dev/null
+++ b/src/tools/clippy/src/docs/default_trait_access.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for literal calls to `Default::default()`.
+
+### Why is this bad?
+It's easier for the reader if the name of the type is used, rather than the
+generic `Default`.
+
+### Example
+```
+let s: String = Default::default();
+```
+
+Use instead:
+```
+let s = String::default();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_union_representation.txt b/src/tools/clippy/src/docs/default_union_representation.txt
new file mode 100644
index 000000000..f79ff9760
--- /dev/null
+++ b/src/tools/clippy/src/docs/default_union_representation.txt
@@ -0,0 +1,36 @@
+### What it does
+Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute).
+
+### Why is this bad?
+Unions in Rust have unspecified layout by default, despite many people thinking that they
+lay out each field at the start of the union (like C does). That is, there are no guarantees
+about the offset of the fields for unions with multiple non-ZST fields without an explicitly
+specified layout. These cases may lead to undefined behavior in unsafe blocks.
+
+### Example
+```
+union Foo {
+ a: i32,
+ b: u32,
+}
+
+fn main() {
+ let _x: u32 = unsafe {
+ Foo { a: 0_i32 }.b // Undefined behavior: `b` is allowed to be padding
+ };
+}
+```
+Use instead:
+```
+#[repr(C)]
+union Foo {
+ a: i32,
+ b: u32,
+}
+
+fn main() {
+ let _x: u32 = unsafe {
+ Foo { a: 0_i32 }.b // Now defined behavior, this is just an i32 -> u32 transmute
+ };
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deprecated_cfg_attr.txt b/src/tools/clippy/src/docs/deprecated_cfg_attr.txt
new file mode 100644
index 000000000..9f264887a
--- /dev/null
+++ b/src/tools/clippy/src/docs/deprecated_cfg_attr.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
+with `#[rustfmt::skip]`.
+
+### Why is this bad?
+Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
+are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
+
+### Known problems
+This lint doesn't detect crate level inner attributes, because they get
+processed before the PreExpansionPass lints get executed. See
+[#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
+
+### Example
+```
+#[cfg_attr(rustfmt, rustfmt_skip)]
+fn main() { }
+```
+
+Use instead:
+```
+#[rustfmt::skip]
+fn main() { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deprecated_semver.txt b/src/tools/clippy/src/docs/deprecated_semver.txt
new file mode 100644
index 000000000..c9574a99b
--- /dev/null
+++ b/src/tools/clippy/src/docs/deprecated_semver.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for `#[deprecated]` annotations with a `since`
+field that is not a valid semantic version.
+
+### Why is this bad?
+For checking the version of the deprecation, it must be
+a valid semver. Failing that, the contained information is useless.
+
+### Example
+```
+#[deprecated(since = "forever")]
+fn something_else() { /* ... */ }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deref_addrof.txt b/src/tools/clippy/src/docs/deref_addrof.txt
new file mode 100644
index 000000000..fa711b924
--- /dev/null
+++ b/src/tools/clippy/src/docs/deref_addrof.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usage of `*&` and `*&mut` in expressions.
+
+### Why is this bad?
+Immediately dereferencing a reference is no-op and
+makes the code less clear.
+
+### Known problems
+Multiple dereference/addrof pairs are not handled so
+the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.
+
+### Example
+```
+let a = f(*&mut b);
+let c = *&d;
+```
+
+Use instead:
+```
+let a = f(b);
+let c = d;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deref_by_slicing.txt b/src/tools/clippy/src/docs/deref_by_slicing.txt
new file mode 100644
index 000000000..4dad24ac0
--- /dev/null
+++ b/src/tools/clippy/src/docs/deref_by_slicing.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for slicing expressions which are equivalent to dereferencing the
+value.
+
+### Why is this bad?
+Some people may prefer to dereference rather than slice.
+
+### Example
+```
+let vec = vec![1, 2, 3];
+let slice = &vec[..];
+```
+Use instead:
+```
+let vec = vec![1, 2, 3];
+let slice = &*vec;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derivable_impls.txt b/src/tools/clippy/src/docs/derivable_impls.txt
new file mode 100644
index 000000000..5cee43956
--- /dev/null
+++ b/src/tools/clippy/src/docs/derivable_impls.txt
@@ -0,0 +1,35 @@
+### What it does
+Detects manual `std::default::Default` implementations that are identical to a derived implementation.
+
+### Why is this bad?
+It is less concise.
+
+### Example
+```
+struct Foo {
+ bar: bool
+}
+
+impl Default for Foo {
+ fn default() -> Self {
+ Self {
+ bar: false
+ }
+ }
+}
+```
+
+Use instead:
+```
+#[derive(Default)]
+struct Foo {
+ bar: bool
+}
+```
+
+### Known problems
+Derive macros [sometimes use incorrect bounds](https://github.com/rust-lang/rust/issues/26925)
+in generic types and the user defined `impl` may be more generalized or
+specialized than what derive will produce. This lint can't detect the manual `impl`
+has exactly equal bounds, and therefore this lint is disabled for types with
+generic parameters. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derive_hash_xor_eq.txt b/src/tools/clippy/src/docs/derive_hash_xor_eq.txt
new file mode 100644
index 000000000..fbf623d5a
--- /dev/null
+++ b/src/tools/clippy/src/docs/derive_hash_xor_eq.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for deriving `Hash` but implementing `PartialEq`
+explicitly or vice versa.
+
+### Why is this bad?
+The implementation of these traits must agree (for
+example for use with `HashMap`) so it’s probably a bad idea to use a
+default-generated `Hash` implementation with an explicitly defined
+`PartialEq`. In particular, the following must hold for any type:
+
+```
+k1 == k2 ⇒ hash(k1) == hash(k2)
+```
+
+### Example
+```
+#[derive(Hash)]
+struct Foo;
+
+impl PartialEq for Foo {
+ ...
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt b/src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt
new file mode 100644
index 000000000..f2107a5f6
--- /dev/null
+++ b/src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt
@@ -0,0 +1,44 @@
+### What it does
+Checks for deriving `Ord` but implementing `PartialOrd`
+explicitly or vice versa.
+
+### Why is this bad?
+The implementation of these traits must agree (for
+example for use with `sort`) so it’s probably a bad idea to use a
+default-generated `Ord` implementation with an explicitly defined
+`PartialOrd`. In particular, the following must hold for any type
+implementing `Ord`:
+
+```
+k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()
+```
+
+### Example
+```
+#[derive(Ord, PartialEq, Eq)]
+struct Foo;
+
+impl PartialOrd for Foo {
+ ...
+}
+```
+Use instead:
+```
+#[derive(PartialEq, Eq)]
+struct Foo;
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Foo {
+ ...
+}
+```
+or, if you don't need a custom ordering:
+```
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Foo;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt b/src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt
new file mode 100644
index 000000000..932fabad6
--- /dev/null
+++ b/src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for types that derive `PartialEq` and could implement `Eq`.
+
+### Why is this bad?
+If a type `T` derives `PartialEq` and all of its members implement `Eq`,
+then `T` can always implement `Eq`. Implementing `Eq` allows `T` to be used
+in APIs that require `Eq` types. It also allows structs containing `T` to derive
+`Eq` themselves.
+
+### Example
+```
+#[derive(PartialEq)]
+struct Foo {
+ i_am_eq: i32,
+ i_am_eq_too: Vec<String>,
+}
+```
+Use instead:
+```
+#[derive(PartialEq, Eq)]
+struct Foo {
+ i_am_eq: i32,
+ i_am_eq_too: Vec<String>,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_methods.txt b/src/tools/clippy/src/docs/disallowed_methods.txt
new file mode 100644
index 000000000..d8ad5b6a6
--- /dev/null
+++ b/src/tools/clippy/src/docs/disallowed_methods.txt
@@ -0,0 +1,41 @@
+### What it does
+Denies the configured methods and functions in clippy.toml
+
+Note: Even though this lint is warn-by-default, it will only trigger if
+methods are defined in the clippy.toml file.
+
+### Why is this bad?
+Some methods are undesirable in certain contexts, and it's beneficial to
+lint for them as needed.
+
+### Example
+An example clippy.toml configuration:
+```
+disallowed-methods = [
+ # Can use a string as the path of the disallowed method.
+ "std::boxed::Box::new",
+ # Can also use an inline table with a `path` key.
+ { path = "std::time::Instant::now" },
+ # When using an inline table, can add a `reason` for why the method
+ # is disallowed.
+ { path = "std::vec::Vec::leak", reason = "no leaking memory" },
+]
+```
+
+```
+// Example code where clippy issues a warning
+let xs = vec![1, 2, 3, 4];
+xs.leak(); // Vec::leak is disallowed in the config.
+// The diagnostic contains the message "no leaking memory".
+
+let _now = Instant::now(); // Instant::now is disallowed in the config.
+
+let _box = Box::new(3); // Box::new is disallowed in the config.
+```
+
+Use instead:
+```
+// Example code which does not raise clippy warning
+let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
+xs.push(123); // Vec::push is _not_ disallowed in the config.
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_names.txt b/src/tools/clippy/src/docs/disallowed_names.txt
new file mode 100644
index 000000000..f4aaee9c7
--- /dev/null
+++ b/src/tools/clippy/src/docs/disallowed_names.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for usage of disallowed names for variables, such
+as `foo`.
+
+### Why is this bad?
+These names are usually placeholder names and should be
+avoided.
+
+### Example
+```
+let foo = 3.14;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_script_idents.txt b/src/tools/clippy/src/docs/disallowed_script_idents.txt
new file mode 100644
index 000000000..2151b7a20
--- /dev/null
+++ b/src/tools/clippy/src/docs/disallowed_script_idents.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for usage of unicode scripts other than those explicitly allowed
+by the lint config.
+
+This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.
+It also ignores the `Common` script type.
+While configuring, be sure to use official script name [aliases] from
+[the list of supported scripts][supported_scripts].
+
+See also: [`non_ascii_idents`].
+
+[aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
+[supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html
+
+### Why is this bad?
+It may be not desired to have many different scripts for
+identifiers in the codebase.
+
+Note that if you only want to allow plain English, you might want to use
+built-in [`non_ascii_idents`] lint instead.
+
+[`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
+
+### Example
+```
+// Assuming that `clippy.toml` contains the following line:
+// allowed-locales = ["Latin", "Cyrillic"]
+let counter = 10; // OK, latin is allowed.
+let Ñчётчик = 10; // OK, cyrillic is allowed.
+let zähler = 10; // OK, it's still latin.
+let カウンタ = 10; // Will spawn the lint.
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_types.txt b/src/tools/clippy/src/docs/disallowed_types.txt
new file mode 100644
index 000000000..2bcbcddee
--- /dev/null
+++ b/src/tools/clippy/src/docs/disallowed_types.txt
@@ -0,0 +1,33 @@
+### What it does
+Denies the configured types in clippy.toml.
+
+Note: Even though this lint is warn-by-default, it will only trigger if
+types are defined in the clippy.toml file.
+
+### Why is this bad?
+Some types are undesirable in certain contexts.
+
+### Example:
+An example clippy.toml configuration:
+```
+disallowed-types = [
+ # Can use a string as the path of the disallowed type.
+ "std::collections::BTreeMap",
+ # Can also use an inline table with a `path` key.
+ { path = "std::net::TcpListener" },
+ # When using an inline table, can add a `reason` for why the type
+ # is disallowed.
+ { path = "std::net::Ipv4Addr", reason = "no IPv4 allowed" },
+]
+```
+
+```
+use std::collections::BTreeMap;
+// or its use
+let x = std::collections::BTreeMap::new();
+```
+Use instead:
+```
+// A similar type that is allowed by the config
+use std::collections::HashMap;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/diverging_sub_expression.txt b/src/tools/clippy/src/docs/diverging_sub_expression.txt
new file mode 100644
index 000000000..194362218
--- /dev/null
+++ b/src/tools/clippy/src/docs/diverging_sub_expression.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for diverging calls that are not match arms or
+statements.
+
+### Why is this bad?
+It is often confusing to read. In addition, the
+sub-expression evaluation order for Rust is not well documented.
+
+### Known problems
+Someone might want to use `some_bool || panic!()` as a
+shorthand.
+
+### Example
+```
+let a = b() || panic!() || c();
+// `c()` is dead, `panic!()` is only called if `b()` returns `false`
+let x = (a, b, c, panic!());
+// can simply be replaced by `panic!()`
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/doc_link_with_quotes.txt b/src/tools/clippy/src/docs/doc_link_with_quotes.txt
new file mode 100644
index 000000000..107c8ac11
--- /dev/null
+++ b/src/tools/clippy/src/docs/doc_link_with_quotes.txt
@@ -0,0 +1,16 @@
+### What it does
+Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks)
+outside of code blocks
+### Why is this bad?
+It is likely a typo when defining an intra-doc link
+
+### Example
+```
+/// See also: ['foo']
+fn bar() {}
+```
+Use instead:
+```
+/// See also: [`foo`]
+fn bar() {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/doc_markdown.txt b/src/tools/clippy/src/docs/doc_markdown.txt
new file mode 100644
index 000000000..94f54c587
--- /dev/null
+++ b/src/tools/clippy/src/docs/doc_markdown.txt
@@ -0,0 +1,35 @@
+### What it does
+Checks for the presence of `_`, `::` or camel-case words
+outside ticks in documentation.
+
+### Why is this bad?
+*Rustdoc* supports markdown formatting, `_`, `::` and
+camel-case probably indicates some code which should be included between
+ticks. `_` can also be used for emphasis in markdown, this lint tries to
+consider that.
+
+### Known problems
+Lots of bad docs won’t be fixed, what the lint checks
+for is limited, and there are still false positives. HTML elements and their
+content are not linted.
+
+In addition, when writing documentation comments, including `[]` brackets
+inside a link text would trip the parser. Therefore, documenting link with
+`[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec
+would fail.
+
+### Examples
+```
+/// Do something with the foo_bar parameter. See also
+/// that::other::module::foo.
+// ^ `foo_bar` and `that::other::module::foo` should be ticked.
+fn doit(foo_bar: usize) {}
+```
+
+```
+// Link text with `[]` brackets should be written as following:
+/// Consume the array and return the inner
+/// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].
+/// [SmallVec]: SmallVec
+fn main() {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_comparisons.txt b/src/tools/clippy/src/docs/double_comparisons.txt
new file mode 100644
index 000000000..7dc681877
--- /dev/null
+++ b/src/tools/clippy/src/docs/double_comparisons.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for double comparisons that could be simplified to a single expression.
+
+
+### Why is this bad?
+Readability.
+
+### Example
+```
+if x == y || x < y {}
+```
+
+Use instead:
+
+```
+if x <= y {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_must_use.txt b/src/tools/clippy/src/docs/double_must_use.txt
new file mode 100644
index 000000000..0017d10d4
--- /dev/null
+++ b/src/tools/clippy/src/docs/double_must_use.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for a `#[must_use]` attribute without
+further information on functions and methods that return a type already
+marked as `#[must_use]`.
+
+### Why is this bad?
+The attribute isn't needed. Not using the result
+will already be reported. Alternatively, one can add some text to the
+attribute to improve the lint message.
+
+### Examples
+```
+#[must_use]
+fn double_must_use() -> Result<(), ()> {
+ unimplemented!();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_neg.txt b/src/tools/clippy/src/docs/double_neg.txt
new file mode 100644
index 000000000..a07f67496
--- /dev/null
+++ b/src/tools/clippy/src/docs/double_neg.txt
@@ -0,0 +1,12 @@
+### What it does
+Detects expressions of the form `--x`.
+
+### Why is this bad?
+It can mislead C/C++ programmers to think `x` was
+decremented.
+
+### Example
+```
+let mut x = 3;
+--x;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_parens.txt b/src/tools/clippy/src/docs/double_parens.txt
new file mode 100644
index 000000000..260d7dd57
--- /dev/null
+++ b/src/tools/clippy/src/docs/double_parens.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for unnecessary double parentheses.
+
+### Why is this bad?
+This makes code harder to read and might indicate a
+mistake.
+
+### Example
+```
+fn simple_double_parens() -> i32 {
+ ((0))
+}
+
+foo((0));
+```
+
+Use instead:
+```
+fn simple_no_parens() -> i32 {
+ 0
+}
+
+foo(0);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/drop_copy.txt b/src/tools/clippy/src/docs/drop_copy.txt
new file mode 100644
index 000000000..f917ca8ed
--- /dev/null
+++ b/src/tools/clippy/src/docs/drop_copy.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for calls to `std::mem::drop` with a value
+that derives the Copy trait
+
+### Why is this bad?
+Calling `std::mem::drop` [does nothing for types that
+implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
+value will be copied and moved into the function on invocation.
+
+### Example
+```
+let x: i32 = 42; // i32 implements Copy
+std::mem::drop(x) // A copy of x is passed to the function, leaving the
+ // original unaffected
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/drop_non_drop.txt b/src/tools/clippy/src/docs/drop_non_drop.txt
new file mode 100644
index 000000000..ee1e3a6c2
--- /dev/null
+++ b/src/tools/clippy/src/docs/drop_non_drop.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for calls to `std::mem::drop` with a value that does not implement `Drop`.
+
+### Why is this bad?
+Calling `std::mem::drop` is no different than dropping such a type. A different value may
+have been intended.
+
+### Example
+```
+struct Foo;
+let x = Foo;
+std::mem::drop(x);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/drop_ref.txt b/src/tools/clippy/src/docs/drop_ref.txt
new file mode 100644
index 000000000..c4f7adf0c
--- /dev/null
+++ b/src/tools/clippy/src/docs/drop_ref.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for calls to `std::mem::drop` with a reference
+instead of an owned value.
+
+### Why is this bad?
+Calling `drop` on a reference will only drop the
+reference itself, which is a no-op. It will not call the `drop` method (from
+the `Drop` trait implementation) on the underlying referenced value, which
+is likely what was intended.
+
+### Example
+```
+let mut lock_guard = mutex.lock();
+std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex
+// still locked
+operation_that_requires_mutex_to_be_unlocked();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/duplicate_mod.txt b/src/tools/clippy/src/docs/duplicate_mod.txt
new file mode 100644
index 000000000..709a9aba0
--- /dev/null
+++ b/src/tools/clippy/src/docs/duplicate_mod.txt
@@ -0,0 +1,31 @@
+### What it does
+Checks for files that are included as modules multiple times.
+
+### Why is this bad?
+Loading a file as a module more than once causes it to be compiled
+multiple times, taking longer and putting duplicate content into the
+module tree.
+
+### Example
+```
+// lib.rs
+mod a;
+mod b;
+```
+```
+// a.rs
+#[path = "./b.rs"]
+mod b;
+```
+
+Use instead:
+
+```
+// lib.rs
+mod a;
+mod b;
+```
+```
+// a.rs
+use crate::b;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/duplicate_underscore_argument.txt b/src/tools/clippy/src/docs/duplicate_underscore_argument.txt
new file mode 100644
index 000000000..a8fcd6a9f
--- /dev/null
+++ b/src/tools/clippy/src/docs/duplicate_underscore_argument.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for function arguments having the similar names
+differing by an underscore.
+
+### Why is this bad?
+It affects code readability.
+
+### Example
+```
+fn foo(a: i32, _a: i32) {}
+```
+
+Use instead:
+```
+fn bar(a: i32, _b: i32) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/duration_subsec.txt b/src/tools/clippy/src/docs/duration_subsec.txt
new file mode 100644
index 000000000..e7e0ca887
--- /dev/null
+++ b/src/tools/clippy/src/docs/duration_subsec.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for calculation of subsecond microseconds or milliseconds
+from other `Duration` methods.
+
+### Why is this bad?
+It's more concise to call `Duration::subsec_micros()` or
+`Duration::subsec_millis()` than to calculate them.
+
+### Example
+```
+let micros = duration.subsec_nanos() / 1_000;
+let millis = duration.subsec_nanos() / 1_000_000;
+```
+
+Use instead:
+```
+let micros = duration.subsec_micros();
+let millis = duration.subsec_millis();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/else_if_without_else.txt b/src/tools/clippy/src/docs/else_if_without_else.txt
new file mode 100644
index 000000000..33f5d0f91
--- /dev/null
+++ b/src/tools/clippy/src/docs/else_if_without_else.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for usage of if expressions with an `else if` branch,
+but without a final `else` branch.
+
+### Why is this bad?
+Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
+
+### Example
+```
+if x.is_positive() {
+ a();
+} else if x.is_negative() {
+ b();
+}
+```
+
+Use instead:
+
+```
+if x.is_positive() {
+ a();
+} else if x.is_negative() {
+ b();
+} else {
+ // We don't care about zero.
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_drop.txt b/src/tools/clippy/src/docs/empty_drop.txt
new file mode 100644
index 000000000..d0c0c24a9
--- /dev/null
+++ b/src/tools/clippy/src/docs/empty_drop.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for empty `Drop` implementations.
+
+### Why is this bad?
+Empty `Drop` implementations have no effect when dropping an instance of the type. They are
+most likely useless. However, an empty `Drop` implementation prevents a type from being
+destructured, which might be the intention behind adding the implementation as a marker.
+
+### Example
+```
+struct S;
+
+impl Drop for S {
+ fn drop(&mut self) {}
+}
+```
+Use instead:
+```
+struct S;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_enum.txt b/src/tools/clippy/src/docs/empty_enum.txt
new file mode 100644
index 000000000..f7b41c41e
--- /dev/null
+++ b/src/tools/clippy/src/docs/empty_enum.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for `enum`s with no variants.
+
+As of this writing, the `never_type` is still a
+nightly-only experimental API. Therefore, this lint is only triggered
+if the `never_type` is enabled.
+
+### Why is this bad?
+If you want to introduce a type which
+can't be instantiated, you should use `!` (the primitive type "never"),
+or a wrapper around it, because `!` has more extensive
+compiler support (type inference, etc...) and wrappers
+around it are the conventional way to define an uninhabited type.
+For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html)
+
+
+### Example
+```
+enum Test {}
+```
+
+Use instead:
+```
+#![feature(never_type)]
+
+struct Test(!);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_line_after_outer_attr.txt b/src/tools/clippy/src/docs/empty_line_after_outer_attr.txt
new file mode 100644
index 000000000..c85242bbe
--- /dev/null
+++ b/src/tools/clippy/src/docs/empty_line_after_outer_attr.txt
@@ -0,0 +1,35 @@
+### What it does
+Checks for empty lines after outer attributes
+
+### Why is this bad?
+Most likely the attribute was meant to be an inner attribute using a '!'.
+If it was meant to be an outer attribute, then the following item
+should not be separated by empty lines.
+
+### Known problems
+Can cause false positives.
+
+From the clippy side it's difficult to detect empty lines between an attributes and the
+following item because empty lines and comments are not part of the AST. The parsing
+currently works for basic cases but is not perfect.
+
+### Example
+```
+#[allow(dead_code)]
+
+fn not_quite_good_code() { }
+```
+
+Use instead:
+```
+// Good (as inner attribute)
+#![allow(dead_code)]
+
+fn this_is_fine() { }
+
+// or
+
+// Good (as outer attribute)
+#[allow(dead_code)]
+fn this_is_fine_too() { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_loop.txt b/src/tools/clippy/src/docs/empty_loop.txt
new file mode 100644
index 000000000..fea49a74d
--- /dev/null
+++ b/src/tools/clippy/src/docs/empty_loop.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for empty `loop` expressions.
+
+### Why is this bad?
+These busy loops burn CPU cycles without doing
+anything. It is _almost always_ a better idea to `panic!` than to have
+a busy loop.
+
+If panicking isn't possible, think of the environment and either:
+ - block on something
+ - sleep the thread for some microseconds
+ - yield or pause the thread
+
+For `std` targets, this can be done with
+[`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)
+or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).
+
+For `no_std` targets, doing this is more complicated, especially because
+`#[panic_handler]`s can't panic. To stop/pause the thread, you will
+probably need to invoke some target-specific intrinsic. Examples include:
+ - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)
+ - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)
+
+### Example
+```
+loop {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_structs_with_brackets.txt b/src/tools/clippy/src/docs/empty_structs_with_brackets.txt
new file mode 100644
index 000000000..ab5e35ae2
--- /dev/null
+++ b/src/tools/clippy/src/docs/empty_structs_with_brackets.txt
@@ -0,0 +1,14 @@
+### What it does
+Finds structs without fields (a so-called "empty struct") that are declared with brackets.
+
+### Why is this bad?
+Empty brackets after a struct declaration can be omitted.
+
+### Example
+```
+struct Cookie {}
+```
+Use instead:
+```
+struct Cookie;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/enum_clike_unportable_variant.txt b/src/tools/clippy/src/docs/enum_clike_unportable_variant.txt
new file mode 100644
index 000000000..d30a973a5
--- /dev/null
+++ b/src/tools/clippy/src/docs/enum_clike_unportable_variant.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for C-like enumerations that are
+`repr(isize/usize)` and have values that don't fit into an `i32`.
+
+### Why is this bad?
+This will truncate the variant value on 32 bit
+architectures, but works fine on 64 bit.
+
+### Example
+```
+#[repr(usize)]
+enum NonPortable {
+ X = 0x1_0000_0000,
+ Y = 0,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/enum_glob_use.txt b/src/tools/clippy/src/docs/enum_glob_use.txt
new file mode 100644
index 000000000..3776822c3
--- /dev/null
+++ b/src/tools/clippy/src/docs/enum_glob_use.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for `use Enum::*`.
+
+### Why is this bad?
+It is usually better style to use the prefixed name of
+an enumeration variant, rather than importing variants.
+
+### Known problems
+Old-style enumerations that prefix the variants are
+still around.
+
+### Example
+```
+use std::cmp::Ordering::*;
+
+foo(Less);
+```
+
+Use instead:
+```
+use std::cmp::Ordering;
+
+foo(Ordering::Less)
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/enum_variant_names.txt b/src/tools/clippy/src/docs/enum_variant_names.txt
new file mode 100644
index 000000000..e726925ed
--- /dev/null
+++ b/src/tools/clippy/src/docs/enum_variant_names.txt
@@ -0,0 +1,30 @@
+### What it does
+Detects enumeration variants that are prefixed or suffixed
+by the same characters.
+
+### Why is this bad?
+Enumeration variant names should specify their variant,
+not repeat the enumeration name.
+
+### Limitations
+Characters with no casing will be considered when comparing prefixes/suffixes
+This applies to numbers and non-ascii characters without casing
+e.g. `Foo1` and `Foo2` is considered to have different prefixes
+(the prefixes are `Foo1` and `Foo2` respectively), as also `Bar螃`, `Bar蟹`
+
+### Example
+```
+enum Cake {
+ BlackForestCake,
+ HummingbirdCake,
+ BattenbergCake,
+}
+```
+Use instead:
+```
+enum Cake {
+ BlackForest,
+ Hummingbird,
+ Battenberg,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/eq_op.txt b/src/tools/clippy/src/docs/eq_op.txt
new file mode 100644
index 000000000..2d75a0ec5
--- /dev/null
+++ b/src/tools/clippy/src/docs/eq_op.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for equal operands to comparison, logical and
+bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
+`||`, `&`, `|`, `^`, `-` and `/`).
+
+### Why is this bad?
+This is usually just a typo or a copy and paste error.
+
+### Known problems
+False negatives: We had some false positives regarding
+calls (notably [racer](https://github.com/phildawes/racer) had one instance
+of `x.pop() && x.pop()`), so we removed matching any function or method
+calls. We may introduce a list of known pure functions in the future.
+
+### Example
+```
+if x + 1 == x + 1 {}
+
+// or
+
+assert_eq!(a, a);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/equatable_if_let.txt b/src/tools/clippy/src/docs/equatable_if_let.txt
new file mode 100644
index 000000000..999704695
--- /dev/null
+++ b/src/tools/clippy/src/docs/equatable_if_let.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for pattern matchings that can be expressed using equality.
+
+### Why is this bad?
+
+* It reads better and has less cognitive load because equality won't cause binding.
+* It is a [Yoda condition](https://en.wikipedia.org/wiki/Yoda_conditions). Yoda conditions are widely
+criticized for increasing the cognitive load of reading the code.
+* Equality is a simple bool expression and can be merged with `&&` and `||` and
+reuse if blocks
+
+### Example
+```
+if let Some(2) = x {
+ do_thing();
+}
+```
+Use instead:
+```
+if x == Some(2) {
+ do_thing();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/erasing_op.txt b/src/tools/clippy/src/docs/erasing_op.txt
new file mode 100644
index 000000000..3d285a6d8
--- /dev/null
+++ b/src/tools/clippy/src/docs/erasing_op.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for erasing operations, e.g., `x * 0`.
+
+### Why is this bad?
+The whole expression can be replaced by zero.
+This is most likely not the intended outcome and should probably be
+corrected
+
+### Example
+```
+let x = 1;
+0 / x;
+0 * x;
+x & 0;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/err_expect.txt b/src/tools/clippy/src/docs/err_expect.txt
new file mode 100644
index 000000000..1dc83c5ce
--- /dev/null
+++ b/src/tools/clippy/src/docs/err_expect.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for `.err().expect()` calls on the `Result` type.
+
+### Why is this bad?
+`.expect_err()` can be called directly to avoid the extra type conversion from `err()`.
+
+### Example
+```
+let x: Result<u32, &str> = Ok(10);
+x.err().expect("Testing err().expect()");
+```
+Use instead:
+```
+let x: Result<u32, &str> = Ok(10);
+x.expect_err("Testing expect_err");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/excessive_precision.txt b/src/tools/clippy/src/docs/excessive_precision.txt
new file mode 100644
index 000000000..517879c47
--- /dev/null
+++ b/src/tools/clippy/src/docs/excessive_precision.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for float literals with a precision greater
+than that supported by the underlying type.
+
+### Why is this bad?
+Rust will truncate the literal silently.
+
+### Example
+```
+let v: f32 = 0.123_456_789_9;
+println!("{}", v); // 0.123_456_789
+```
+
+Use instead:
+```
+let v: f64 = 0.123_456_789_9;
+println!("{}", v); // 0.123_456_789_9
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/exhaustive_enums.txt b/src/tools/clippy/src/docs/exhaustive_enums.txt
new file mode 100644
index 000000000..d1032a7a2
--- /dev/null
+++ b/src/tools/clippy/src/docs/exhaustive_enums.txt
@@ -0,0 +1,23 @@
+### What it does
+Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`
+
+### Why is this bad?
+Exhaustive enums are typically fine, but a project which does
+not wish to make a stability commitment around exported enums may wish to
+disable them by default.
+
+### Example
+```
+enum Foo {
+ Bar,
+ Baz
+}
+```
+Use instead:
+```
+#[non_exhaustive]
+enum Foo {
+ Bar,
+ Baz
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/exhaustive_structs.txt b/src/tools/clippy/src/docs/exhaustive_structs.txt
new file mode 100644
index 000000000..fd6e4f5ca
--- /dev/null
+++ b/src/tools/clippy/src/docs/exhaustive_structs.txt
@@ -0,0 +1,23 @@
+### What it does
+Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`
+
+### Why is this bad?
+Exhaustive structs are typically fine, but a project which does
+not wish to make a stability commitment around exported structs may wish to
+disable them by default.
+
+### Example
+```
+struct Foo {
+ bar: u8,
+ baz: String,
+}
+```
+Use instead:
+```
+#[non_exhaustive]
+struct Foo {
+ bar: u8,
+ baz: String,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/exit.txt b/src/tools/clippy/src/docs/exit.txt
new file mode 100644
index 000000000..1e6154d43
--- /dev/null
+++ b/src/tools/clippy/src/docs/exit.txt
@@ -0,0 +1,12 @@
+### What it does
+`exit()` terminates the program and doesn't provide a
+stack trace.
+
+### Why is this bad?
+Ideally a program is terminated by finishing
+the main function.
+
+### Example
+```
+std::process::exit(0)
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/expect_fun_call.txt b/src/tools/clippy/src/docs/expect_fun_call.txt
new file mode 100644
index 000000000..d82d9aa9b
--- /dev/null
+++ b/src/tools/clippy/src/docs/expect_fun_call.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,
+etc., and suggests to use `unwrap_or_else` instead
+
+### Why is this bad?
+The function will always be called.
+
+### Known problems
+If the function has side-effects, not calling it will
+change the semantics of the program, but you shouldn't rely on that anyway.
+
+### Example
+```
+foo.expect(&format!("Err {}: {}", err_code, err_msg));
+
+// or
+
+foo.expect(format!("Err {}: {}", err_code, err_msg).as_str());
+```
+
+Use instead:
+```
+foo.unwrap_or_else(|| panic!("Err {}: {}", err_code, err_msg));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/expect_used.txt b/src/tools/clippy/src/docs/expect_used.txt
new file mode 100644
index 000000000..4a6981e33
--- /dev/null
+++ b/src/tools/clippy/src/docs/expect_used.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s.
+
+### Why is this bad?
+Usually it is better to handle the `None` or `Err` case.
+Still, for a lot of quick-and-dirty code, `expect` is a good choice, which is why
+this lint is `Allow` by default.
+
+`result.expect()` will let the thread panic on `Err`
+values. Normally, you want to implement more sophisticated error handling,
+and propagate errors upwards with `?` operator.
+
+### Examples
+```
+option.expect("one");
+result.expect("one");
+```
+
+Use instead:
+```
+option?;
+
+// or
+
+result?;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt b/src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt
new file mode 100644
index 000000000..391d93b67
--- /dev/null
+++ b/src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for explicit `Clone` implementations for `Copy`
+types.
+
+### Why is this bad?
+To avoid surprising behavior, these traits should
+agree and the behavior of `Copy` cannot be overridden. In almost all
+situations a `Copy` type should have a `Clone` implementation that does
+nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
+gets you.
+
+### Example
+```
+#[derive(Copy)]
+struct Foo;
+
+impl Clone for Foo {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_auto_deref.txt b/src/tools/clippy/src/docs/explicit_auto_deref.txt
new file mode 100644
index 000000000..65b256317
--- /dev/null
+++ b/src/tools/clippy/src/docs/explicit_auto_deref.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for dereferencing expressions which would be covered by auto-deref.
+
+### Why is this bad?
+This unnecessarily complicates the code.
+
+### Example
+```
+let x = String::new();
+let y: &str = &*x;
+```
+Use instead:
+```
+let x = String::new();
+let y: &str = &x;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_counter_loop.txt b/src/tools/clippy/src/docs/explicit_counter_loop.txt
new file mode 100644
index 000000000..2661a43e1
--- /dev/null
+++ b/src/tools/clippy/src/docs/explicit_counter_loop.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks `for` loops over slices with an explicit counter
+and suggests the use of `.enumerate()`.
+
+### Why is this bad?
+Using `.enumerate()` makes the intent more clear,
+declutters the code and may be faster in some instances.
+
+### Example
+```
+let mut i = 0;
+for item in &v {
+ bar(i, *item);
+ i += 1;
+}
+```
+
+Use instead:
+```
+for (i, item) in v.iter().enumerate() { bar(i, *item); }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_deref_methods.txt b/src/tools/clippy/src/docs/explicit_deref_methods.txt
new file mode 100644
index 000000000..e14e981c7
--- /dev/null
+++ b/src/tools/clippy/src/docs/explicit_deref_methods.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for explicit `deref()` or `deref_mut()` method calls.
+
+### Why is this bad?
+Dereferencing by `&*x` or `&mut *x` is clearer and more concise,
+when not part of a method chain.
+
+### Example
+```
+use std::ops::Deref;
+let a: &mut String = &mut String::from("foo");
+let b: &str = a.deref();
+```
+
+Use instead:
+```
+let a: &mut String = &mut String::from("foo");
+let b = &*a;
+```
+
+This lint excludes:
+```
+let _ = d.unwrap().deref();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_into_iter_loop.txt b/src/tools/clippy/src/docs/explicit_into_iter_loop.txt
new file mode 100644
index 000000000..3931dfd69
--- /dev/null
+++ b/src/tools/clippy/src/docs/explicit_into_iter_loop.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for loops on `y.into_iter()` where `y` will do, and
+suggests the latter.
+
+### Why is this bad?
+Readability.
+
+### Example
+```
+// with `y` a `Vec` or slice:
+for x in y.into_iter() {
+ // ..
+}
+```
+can be rewritten to
+```
+for x in y {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_iter_loop.txt b/src/tools/clippy/src/docs/explicit_iter_loop.txt
new file mode 100644
index 000000000..cabe72e91
--- /dev/null
+++ b/src/tools/clippy/src/docs/explicit_iter_loop.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for loops on `x.iter()` where `&x` will do, and
+suggests the latter.
+
+### Why is this bad?
+Readability.
+
+### Known problems
+False negatives. We currently only warn on some known
+types.
+
+### Example
+```
+// with `y` a `Vec` or slice:
+for x in y.iter() {
+ // ..
+}
+```
+
+Use instead:
+```
+for x in &y {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_write.txt b/src/tools/clippy/src/docs/explicit_write.txt
new file mode 100644
index 000000000..eafed5d39
--- /dev/null
+++ b/src/tools/clippy/src/docs/explicit_write.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for usage of `write!()` / `writeln()!` which can be
+replaced with `(e)print!()` / `(e)println!()`
+
+### Why is this bad?
+Using `(e)println! is clearer and more concise
+
+### Example
+```
+writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap();
+writeln!(&mut std::io::stdout(), "foo: {:?}", bar).unwrap();
+```
+
+Use instead:
+```
+eprintln!("foo: {:?}", bar);
+println!("foo: {:?}", bar);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/extend_with_drain.txt b/src/tools/clippy/src/docs/extend_with_drain.txt
new file mode 100644
index 000000000..2f31dcf5f
--- /dev/null
+++ b/src/tools/clippy/src/docs/extend_with_drain.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for occurrences where one vector gets extended instead of append
+
+### Why is this bad?
+Using `append` instead of `extend` is more concise and faster
+
+### Example
+```
+let mut a = vec![1, 2, 3];
+let mut b = vec![4, 5, 6];
+
+a.extend(b.drain(..));
+```
+
+Use instead:
+```
+let mut a = vec![1, 2, 3];
+let mut b = vec![4, 5, 6];
+
+a.append(&mut b);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/extra_unused_lifetimes.txt b/src/tools/clippy/src/docs/extra_unused_lifetimes.txt
new file mode 100644
index 000000000..bc1814aa4
--- /dev/null
+++ b/src/tools/clippy/src/docs/extra_unused_lifetimes.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for lifetimes in generics that are never used
+anywhere else.
+
+### Why is this bad?
+The additional lifetimes make the code look more
+complicated, while there is nothing out of the ordinary going on. Removing
+them leads to more readable code.
+
+### Example
+```
+// unnecessary lifetimes
+fn unused_lifetime<'a>(x: u8) {
+ // ..
+}
+```
+
+Use instead:
+```
+fn no_lifetime(x: u8) {
+ // ...
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fallible_impl_from.txt b/src/tools/clippy/src/docs/fallible_impl_from.txt
new file mode 100644
index 000000000..588a5bb10
--- /dev/null
+++ b/src/tools/clippy/src/docs/fallible_impl_from.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
+
+### Why is this bad?
+`TryFrom` should be used if there's a possibility of failure.
+
+### Example
+```
+struct Foo(i32);
+
+impl From<String> for Foo {
+ fn from(s: String) -> Self {
+ Foo(s.parse().unwrap())
+ }
+}
+```
+
+Use instead:
+```
+struct Foo(i32);
+
+impl TryFrom<String> for Foo {
+ type Error = ();
+ fn try_from(s: String) -> Result<Self, Self::Error> {
+ if let Ok(parsed) = s.parse() {
+ Ok(Foo(parsed))
+ } else {
+ Err(())
+ }
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/field_reassign_with_default.txt b/src/tools/clippy/src/docs/field_reassign_with_default.txt
new file mode 100644
index 000000000..e58b7239f
--- /dev/null
+++ b/src/tools/clippy/src/docs/field_reassign_with_default.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for immediate reassignment of fields initialized
+with Default::default().
+
+### Why is this bad?
+It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).
+
+### Known problems
+Assignments to patterns that are of tuple type are not linted.
+
+### Example
+```
+let mut a: A = Default::default();
+a.i = 42;
+```
+
+Use instead:
+```
+let a = A {
+ i: 42,
+ .. Default::default()
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filetype_is_file.txt b/src/tools/clippy/src/docs/filetype_is_file.txt
new file mode 100644
index 000000000..ad14bd62c
--- /dev/null
+++ b/src/tools/clippy/src/docs/filetype_is_file.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for `FileType::is_file()`.
+
+### Why is this bad?
+When people testing a file type with `FileType::is_file`
+they are testing whether a path is something they can get bytes from. But
+`is_file` doesn't cover special file types in unix-like systems, and doesn't cover
+symlink in windows. Using `!FileType::is_dir()` is a better way to that intention.
+
+### Example
+```
+let metadata = std::fs::metadata("foo.txt")?;
+let filetype = metadata.file_type();
+
+if filetype.is_file() {
+ // read file
+}
+```
+
+should be written as:
+
+```
+let metadata = std::fs::metadata("foo.txt")?;
+let filetype = metadata.file_type();
+
+if !filetype.is_dir() {
+ // read file
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filter_map_identity.txt b/src/tools/clippy/src/docs/filter_map_identity.txt
new file mode 100644
index 000000000..83b666f2e
--- /dev/null
+++ b/src/tools/clippy/src/docs/filter_map_identity.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for usage of `filter_map(|x| x)`.
+
+### Why is this bad?
+Readability, this can be written more concisely by using `flatten`.
+
+### Example
+```
+iter.filter_map(|x| x);
+```
+Use instead:
+```
+iter.flatten();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filter_map_next.txt b/src/tools/clippy/src/docs/filter_map_next.txt
new file mode 100644
index 000000000..b38620b56
--- /dev/null
+++ b/src/tools/clippy/src/docs/filter_map_next.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of `_.filter_map(_).next()`.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.find_map(_)`.
+
+### Example
+```
+ (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next();
+```
+Can be written as
+
+```
+ (0..3).find_map(|x| if x == 2 { Some(x) } else { None });
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filter_next.txt b/src/tools/clippy/src/docs/filter_next.txt
new file mode 100644
index 000000000..898a74166
--- /dev/null
+++ b/src/tools/clippy/src/docs/filter_next.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of `_.filter(_).next()`.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.find(_)`.
+
+### Example
+```
+vec.iter().filter(|x| **x == 0).next();
+```
+
+Use instead:
+```
+vec.iter().find(|x| **x == 0);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/flat_map_identity.txt b/src/tools/clippy/src/docs/flat_map_identity.txt
new file mode 100644
index 000000000..a5ee79b49
--- /dev/null
+++ b/src/tools/clippy/src/docs/flat_map_identity.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for usage of `flat_map(|x| x)`.
+
+### Why is this bad?
+Readability, this can be written more concisely by using `flatten`.
+
+### Example
+```
+iter.flat_map(|x| x);
+```
+Can be written as
+```
+iter.flatten();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/flat_map_option.txt b/src/tools/clippy/src/docs/flat_map_option.txt
new file mode 100644
index 000000000..d50b9156d
--- /dev/null
+++ b/src/tools/clippy/src/docs/flat_map_option.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usages of `Iterator::flat_map()` where `filter_map()` could be
+used instead.
+
+### Why is this bad?
+When applicable, `filter_map()` is more clear since it shows that
+`Option` is used to produce 0 or 1 items.
+
+### Example
+```
+let nums: Vec<i32> = ["1", "2", "whee!"].iter().flat_map(|x| x.parse().ok()).collect();
+```
+Use instead:
+```
+let nums: Vec<i32> = ["1", "2", "whee!"].iter().filter_map(|x| x.parse().ok()).collect();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_arithmetic.txt b/src/tools/clippy/src/docs/float_arithmetic.txt
new file mode 100644
index 000000000..1f9bce5ab
--- /dev/null
+++ b/src/tools/clippy/src/docs/float_arithmetic.txt
@@ -0,0 +1,11 @@
+### What it does
+Checks for float arithmetic.
+
+### Why is this bad?
+For some embedded systems or kernel development, it
+can be useful to rule out floating-point numbers.
+
+### Example
+```
+a + 1.0;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_cmp.txt b/src/tools/clippy/src/docs/float_cmp.txt
new file mode 100644
index 000000000..c19907c90
--- /dev/null
+++ b/src/tools/clippy/src/docs/float_cmp.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for (in-)equality comparisons on floating-point
+values (apart from zero), except in functions called `*eq*` (which probably
+implement equality for a type involving floats).
+
+### Why is this bad?
+Floating point calculations are usually imprecise, so
+asking if two values are *exactly* equal is asking for trouble. For a good
+guide on what to do, see [the floating point
+guide](http://www.floating-point-gui.de/errors/comparison).
+
+### Example
+```
+let x = 1.2331f64;
+let y = 1.2332f64;
+
+if y == 1.23f64 { }
+if y != x {} // where both are floats
+```
+
+Use instead:
+```
+let error_margin = f64::EPSILON; // Use an epsilon for comparison
+// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
+// let error_margin = std::f64::EPSILON;
+if (y - 1.23f64).abs() < error_margin { }
+if (y - x).abs() > error_margin { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_cmp_const.txt b/src/tools/clippy/src/docs/float_cmp_const.txt
new file mode 100644
index 000000000..9208feaac
--- /dev/null
+++ b/src/tools/clippy/src/docs/float_cmp_const.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for (in-)equality comparisons on floating-point
+value and constant, except in functions called `*eq*` (which probably
+implement equality for a type involving floats).
+
+### Why is this bad?
+Floating point calculations are usually imprecise, so
+asking if two values are *exactly* equal is asking for trouble. For a good
+guide on what to do, see [the floating point
+guide](http://www.floating-point-gui.de/errors/comparison).
+
+### Example
+```
+let x: f64 = 1.0;
+const ONE: f64 = 1.00;
+
+if x == ONE { } // where both are floats
+```
+
+Use instead:
+```
+let error_margin = f64::EPSILON; // Use an epsilon for comparison
+// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
+// let error_margin = std::f64::EPSILON;
+if (x - ONE).abs() < error_margin { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_equality_without_abs.txt b/src/tools/clippy/src/docs/float_equality_without_abs.txt
new file mode 100644
index 000000000..556b574e1
--- /dev/null
+++ b/src/tools/clippy/src/docs/float_equality_without_abs.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for statements of the form `(a - b) < f32::EPSILON` or
+`(a - b) < f64::EPSILON`. Notes the missing `.abs()`.
+
+### Why is this bad?
+The code without `.abs()` is more likely to have a bug.
+
+### Known problems
+If the user can ensure that b is larger than a, the `.abs()` is
+technically unnecessary. However, it will make the code more robust and doesn't have any
+large performance implications. If the abs call was deliberately left out for performance
+reasons, it is probably better to state this explicitly in the code, which then can be done
+with an allow.
+
+### Example
+```
+pub fn is_roughly_equal(a: f32, b: f32) -> bool {
+ (a - b) < f32::EPSILON
+}
+```
+Use instead:
+```
+pub fn is_roughly_equal(a: f32, b: f32) -> bool {
+ (a - b).abs() < f32::EPSILON
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_address_comparisons.txt b/src/tools/clippy/src/docs/fn_address_comparisons.txt
new file mode 100644
index 000000000..7d2b7b681
--- /dev/null
+++ b/src/tools/clippy/src/docs/fn_address_comparisons.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for comparisons with an address of a function item.
+
+### Why is this bad?
+Function item address is not guaranteed to be unique and could vary
+between different code generation units. Furthermore different function items could have
+the same address after being merged together.
+
+### Example
+```
+type F = fn();
+fn a() {}
+let f: F = a;
+if f == a {
+ // ...
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_params_excessive_bools.txt b/src/tools/clippy/src/docs/fn_params_excessive_bools.txt
new file mode 100644
index 000000000..2eae05633
--- /dev/null
+++ b/src/tools/clippy/src/docs/fn_params_excessive_bools.txt
@@ -0,0 +1,31 @@
+### What it does
+Checks for excessive use of
+bools in function definitions.
+
+### Why is this bad?
+Calls to such functions
+are confusing and error prone, because it's
+hard to remember argument order and you have
+no type system support to back you up. Using
+two-variant enums instead of bools often makes
+API easier to use.
+
+### Example
+```
+fn f(is_round: bool, is_hot: bool) { ... }
+```
+
+Use instead:
+```
+enum Shape {
+ Round,
+ Spiky,
+}
+
+enum Temperature {
+ Hot,
+ IceCold,
+}
+
+fn f(shape: Shape, temperature: Temperature) { ... }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_to_numeric_cast.txt b/src/tools/clippy/src/docs/fn_to_numeric_cast.txt
new file mode 100644
index 000000000..1f587f6d7
--- /dev/null
+++ b/src/tools/clippy/src/docs/fn_to_numeric_cast.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for casts of function pointers to something other than usize
+
+### Why is this bad?
+Casting a function pointer to anything other than usize/isize is not portable across
+architectures, because you end up losing bits if the target type is too small or end up with a
+bunch of extra bits that waste space and add more instructions to the final binary than
+strictly necessary for the problem
+
+Casting to isize also doesn't make sense since there are no signed addresses.
+
+### Example
+```
+fn fun() -> i32 { 1 }
+let _ = fun as i64;
+```
+
+Use instead:
+```
+let _ = fun as usize;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt b/src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt
new file mode 100644
index 000000000..ee3c33d23
--- /dev/null
+++ b/src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt
@@ -0,0 +1,35 @@
+### What it does
+Checks for casts of a function pointer to any integer type.
+
+### Why is this bad?
+Casting a function pointer to an integer can have surprising results and can occur
+accidentally if parentheses are omitted from a function call. If you aren't doing anything
+low-level with function pointers then you can opt-out of casting functions to integers in
+order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function
+pointer casts in your code.
+
+### Example
+```
+// fn1 is cast as `usize`
+fn fn1() -> u16 {
+ 1
+};
+let _ = fn1 as usize;
+```
+
+Use instead:
+```
+// maybe you intended to call the function?
+fn fn2() -> u16 {
+ 1
+};
+let _ = fn2() as usize;
+
+// or
+
+// maybe you intended to cast it to a function type?
+fn fn3() -> u16 {
+ 1
+}
+let _ = fn3 as fn() -> u16;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt b/src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt
new file mode 100644
index 000000000..69f12fa31
--- /dev/null
+++ b/src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for casts of a function pointer to a numeric type not wide enough to
+store address.
+
+### Why is this bad?
+Such a cast discards some bits of the function's address. If this is intended, it would be more
+clearly expressed by casting to usize first, then casting the usize to the intended type (with
+a comment) to perform the truncation.
+
+### Example
+```
+fn fn1() -> i16 {
+ 1
+};
+let _ = fn1 as i32;
+```
+
+Use instead:
+```
+// Cast to usize first, then comment with the reason for the truncation
+fn fn1() -> i16 {
+ 1
+};
+let fn_ptr = fn1 as usize;
+let fn_ptr_truncated = fn_ptr as i32;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/for_kv_map.txt b/src/tools/clippy/src/docs/for_kv_map.txt
new file mode 100644
index 000000000..a9a2ffee9
--- /dev/null
+++ b/src/tools/clippy/src/docs/for_kv_map.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for iterating a map (`HashMap` or `BTreeMap`) and
+ignoring either the keys or values.
+
+### Why is this bad?
+Readability. There are `keys` and `values` methods that
+can be used to express that don't need the values or keys.
+
+### Example
+```
+for (k, _) in &map {
+ ..
+}
+```
+
+could be replaced by
+
+```
+for k in map.keys() {
+ ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/for_loops_over_fallibles.txt b/src/tools/clippy/src/docs/for_loops_over_fallibles.txt
new file mode 100644
index 000000000..c5a7508e4
--- /dev/null
+++ b/src/tools/clippy/src/docs/for_loops_over_fallibles.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for `for` loops over `Option` or `Result` values.
+
+### Why is this bad?
+Readability. This is more clearly expressed as an `if
+let`.
+
+### Example
+```
+for x in opt {
+ // ..
+}
+
+for x in &res {
+ // ..
+}
+
+for x in res.iter() {
+ // ..
+}
+```
+
+Use instead:
+```
+if let Some(x) = opt {
+ // ..
+}
+
+if let Ok(x) = res {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/forget_copy.txt b/src/tools/clippy/src/docs/forget_copy.txt
new file mode 100644
index 000000000..1d100912e
--- /dev/null
+++ b/src/tools/clippy/src/docs/forget_copy.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for calls to `std::mem::forget` with a value that
+derives the Copy trait
+
+### Why is this bad?
+Calling `std::mem::forget` [does nothing for types that
+implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
+value will be copied and moved into the function on invocation.
+
+An alternative, but also valid, explanation is that Copy types do not
+implement
+the Drop trait, which means they have no destructors. Without a destructor,
+there
+is nothing for `std::mem::forget` to ignore.
+
+### Example
+```
+let x: i32 = 42; // i32 implements Copy
+std::mem::forget(x) // A copy of x is passed to the function, leaving the
+ // original unaffected
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/forget_non_drop.txt b/src/tools/clippy/src/docs/forget_non_drop.txt
new file mode 100644
index 000000000..3307d654c
--- /dev/null
+++ b/src/tools/clippy/src/docs/forget_non_drop.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for calls to `std::mem::forget` with a value that does not implement `Drop`.
+
+### Why is this bad?
+Calling `std::mem::forget` is no different than dropping such a type. A different value may
+have been intended.
+
+### Example
+```
+struct Foo;
+let x = Foo;
+std::mem::forget(x);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/forget_ref.txt b/src/tools/clippy/src/docs/forget_ref.txt
new file mode 100644
index 000000000..874fb8786
--- /dev/null
+++ b/src/tools/clippy/src/docs/forget_ref.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for calls to `std::mem::forget` with a reference
+instead of an owned value.
+
+### Why is this bad?
+Calling `forget` on a reference will only forget the
+reference itself, which is a no-op. It will not forget the underlying
+referenced
+value, which is likely what was intended.
+
+### Example
+```
+let x = Box::new(1);
+std::mem::forget(&x) // Should have been forget(x), x will still be dropped
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/format_in_format_args.txt b/src/tools/clippy/src/docs/format_in_format_args.txt
new file mode 100644
index 000000000..ac498472f
--- /dev/null
+++ b/src/tools/clippy/src/docs/format_in_format_args.txt
@@ -0,0 +1,16 @@
+### What it does
+Detects `format!` within the arguments of another macro that does
+formatting such as `format!` itself, `write!` or `println!`. Suggests
+inlining the `format!` call.
+
+### Why is this bad?
+The recommended code is both shorter and avoids a temporary allocation.
+
+### Example
+```
+println!("error: {}", format!("something failed at {}", Location::caller()));
+```
+Use instead:
+```
+println!("error: something failed at {}", Location::caller());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/format_push_string.txt b/src/tools/clippy/src/docs/format_push_string.txt
new file mode 100644
index 000000000..ca409ebc7
--- /dev/null
+++ b/src/tools/clippy/src/docs/format_push_string.txt
@@ -0,0 +1,26 @@
+### What it does
+Detects cases where the result of a `format!` call is
+appended to an existing `String`.
+
+### Why is this bad?
+Introduces an extra, avoidable heap allocation.
+
+### Known problems
+`format!` returns a `String` but `write!` returns a `Result`.
+Thus you are forced to ignore the `Err` variant to achieve the same API.
+
+While using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer.
+
+### Example
+```
+let mut s = String::new();
+s += &format!("0x{:X}", 1024);
+s.push_str(&format!("0x{:X}", 1024));
+```
+Use instead:
+```
+use std::fmt::Write as _; // import without risk of name clashing
+
+let mut s = String::new();
+let _ = write!(s, "0x{:X}", 1024);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/from_iter_instead_of_collect.txt b/src/tools/clippy/src/docs/from_iter_instead_of_collect.txt
new file mode 100644
index 000000000..f3fd27597
--- /dev/null
+++ b/src/tools/clippy/src/docs/from_iter_instead_of_collect.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for `from_iter()` function calls on types that implement the `FromIterator`
+trait.
+
+### Why is this bad?
+It is recommended style to use collect. See
+[FromIterator documentation](https://doc.rust-lang.org/std/iter/trait.FromIterator.html)
+
+### Example
+```
+let five_fives = std::iter::repeat(5).take(5);
+
+let v = Vec::from_iter(five_fives);
+
+assert_eq!(v, vec![5, 5, 5, 5, 5]);
+```
+Use instead:
+```
+let five_fives = std::iter::repeat(5).take(5);
+
+let v: Vec<i32> = five_fives.collect();
+
+assert_eq!(v, vec![5, 5, 5, 5, 5]);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/from_over_into.txt b/src/tools/clippy/src/docs/from_over_into.txt
new file mode 100644
index 000000000..0770bcc42
--- /dev/null
+++ b/src/tools/clippy/src/docs/from_over_into.txt
@@ -0,0 +1,26 @@
+### What it does
+Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.
+
+### Why is this bad?
+According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
+
+### Example
+```
+struct StringWrapper(String);
+
+impl Into<StringWrapper> for String {
+ fn into(self) -> StringWrapper {
+ StringWrapper(self)
+ }
+}
+```
+Use instead:
+```
+struct StringWrapper(String);
+
+impl From<String> for StringWrapper {
+ fn from(s: String) -> StringWrapper {
+ StringWrapper(s)
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/from_str_radix_10.txt b/src/tools/clippy/src/docs/from_str_radix_10.txt
new file mode 100644
index 000000000..f6f319d3e
--- /dev/null
+++ b/src/tools/clippy/src/docs/from_str_radix_10.txt
@@ -0,0 +1,25 @@
+### What it does
+
+Checks for function invocations of the form `primitive::from_str_radix(s, 10)`
+
+### Why is this bad?
+
+This specific common use case can be rewritten as `s.parse::<primitive>()`
+(and in most cases, the turbofish can be removed), which reduces code length
+and complexity.
+
+### Known problems
+
+This lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly
+in some cases, which is correct but adds unnecessary complexity to the code.
+
+### Example
+```
+let input: &str = get_input();
+let num = u16::from_str_radix(input, 10)?;
+```
+Use instead:
+```
+let input: &str = get_input();
+let num: u16 = input.parse()?;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/future_not_send.txt b/src/tools/clippy/src/docs/future_not_send.txt
new file mode 100644
index 000000000..0aa048d27
--- /dev/null
+++ b/src/tools/clippy/src/docs/future_not_send.txt
@@ -0,0 +1,29 @@
+### What it does
+This lint requires Future implementations returned from
+functions and methods to implement the `Send` marker trait. It is mostly
+used by library authors (public and internal) that target an audience where
+multithreaded executors are likely to be used for running these Futures.
+
+### Why is this bad?
+A Future implementation captures some state that it
+needs to eventually produce its final value. When targeting a multithreaded
+executor (which is the norm on non-embedded devices) this means that this
+state may need to be transported to other threads, in other words the
+whole Future needs to implement the `Send` marker trait. If it does not,
+then the resulting Future cannot be submitted to a thread pool in the
+end user’s code.
+
+Especially for generic functions it can be confusing to leave the
+discovery of this problem to the end user: the reported error location
+will be far from its cause and can in many cases not even be fixed without
+modifying the library where the offending Future implementation is
+produced.
+
+### Example
+```
+async fn not_send(bytes: std::rc::Rc<[u8]>) {}
+```
+Use instead:
+```
+async fn is_send(bytes: std::sync::Arc<[u8]>) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/get_first.txt b/src/tools/clippy/src/docs/get_first.txt
new file mode 100644
index 000000000..c905a737d
--- /dev/null
+++ b/src/tools/clippy/src/docs/get_first.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for using `x.get(0)` instead of
+`x.first()`.
+
+### Why is this bad?
+Using `x.first()` is easier to read and has the same
+result.
+
+### Example
+```
+let x = vec![2, 3, 5];
+let first_element = x.get(0);
+```
+
+Use instead:
+```
+let x = vec![2, 3, 5];
+let first_element = x.first();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/get_last_with_len.txt b/src/tools/clippy/src/docs/get_last_with_len.txt
new file mode 100644
index 000000000..31c7f2695
--- /dev/null
+++ b/src/tools/clippy/src/docs/get_last_with_len.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for using `x.get(x.len() - 1)` instead of
+`x.last()`.
+
+### Why is this bad?
+Using `x.last()` is easier to read and has the same
+result.
+
+Note that using `x[x.len() - 1]` is semantically different from
+`x.last()`. Indexing into the array will panic on out-of-bounds
+accesses, while `x.get()` and `x.last()` will return `None`.
+
+There is another lint (get_unwrap) that covers the case of using
+`x.get(index).unwrap()` instead of `x[index]`.
+
+### Example
+```
+let x = vec![2, 3, 5];
+let last_element = x.get(x.len() - 1);
+```
+
+Use instead:
+```
+let x = vec![2, 3, 5];
+let last_element = x.last();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/get_unwrap.txt b/src/tools/clippy/src/docs/get_unwrap.txt
new file mode 100644
index 000000000..8defc2224
--- /dev/null
+++ b/src/tools/clippy/src/docs/get_unwrap.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for use of `.get().unwrap()` (or
+`.get_mut().unwrap`) on a standard library type which implements `Index`
+
+### Why is this bad?
+Using the Index trait (`[]`) is more clear and more
+concise.
+
+### Known problems
+Not a replacement for error handling: Using either
+`.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`
+if the value being accessed is `None`. If the use of `.get().unwrap()` is a
+temporary placeholder for dealing with the `Option` type, then this does
+not mitigate the need for error handling. If there is a chance that `.get()`
+will be `None` in your program, then it is advisable that the `None` case
+is handled in a future refactor instead of using `.unwrap()` or the Index
+trait.
+
+### Example
+```
+let mut some_vec = vec![0, 1, 2, 3];
+let last = some_vec.get(3).unwrap();
+*some_vec.get_mut(0).unwrap() = 1;
+```
+The correct use would be:
+```
+let mut some_vec = vec![0, 1, 2, 3];
+let last = some_vec[3];
+some_vec[0] = 1;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/identity_op.txt b/src/tools/clippy/src/docs/identity_op.txt
new file mode 100644
index 000000000..a8e40bb43
--- /dev/null
+++ b/src/tools/clippy/src/docs/identity_op.txt
@@ -0,0 +1,11 @@
+### What it does
+Checks for identity operations, e.g., `x + 0`.
+
+### Why is this bad?
+This code can be removed without changing the
+meaning. So it just obscures what's going on. Delete it mercilessly.
+
+### Example
+```
+x / 1 + 0 * 1 - 0 | 0;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_let_mutex.txt b/src/tools/clippy/src/docs/if_let_mutex.txt
new file mode 100644
index 000000000..4d873ade9
--- /dev/null
+++ b/src/tools/clippy/src/docs/if_let_mutex.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for `Mutex::lock` calls in `if let` expression
+with lock calls in any of the else blocks.
+
+### Why is this bad?
+The Mutex lock remains held for the whole
+`if let ... else` block and deadlocks.
+
+### Example
+```
+if let Ok(thing) = mutex.lock() {
+ do_thing();
+} else {
+ mutex.lock();
+}
+```
+Should be written
+```
+let locked = mutex.lock();
+if let Ok(thing) = locked {
+ do_thing(thing);
+} else {
+ use_locked(locked);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_not_else.txt b/src/tools/clippy/src/docs/if_not_else.txt
new file mode 100644
index 000000000..0e5ac4ce6
--- /dev/null
+++ b/src/tools/clippy/src/docs/if_not_else.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for usage of `!` or `!=` in an if condition with an
+else branch.
+
+### Why is this bad?
+Negations reduce the readability of statements.
+
+### Example
+```
+if !v.is_empty() {
+ a()
+} else {
+ b()
+}
+```
+
+Could be written:
+
+```
+if v.is_empty() {
+ b()
+} else {
+ a()
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_same_then_else.txt b/src/tools/clippy/src/docs/if_same_then_else.txt
new file mode 100644
index 000000000..75127016b
--- /dev/null
+++ b/src/tools/clippy/src/docs/if_same_then_else.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for `if/else` with the same body as the *then* part
+and the *else* part.
+
+### Why is this bad?
+This is probably a copy & paste error.
+
+### Example
+```
+let foo = if … {
+ 42
+} else {
+ 42
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_then_some_else_none.txt b/src/tools/clippy/src/docs/if_then_some_else_none.txt
new file mode 100644
index 000000000..13744f920
--- /dev/null
+++ b/src/tools/clippy/src/docs/if_then_some_else_none.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for if-else that could be written using either `bool::then` or `bool::then_some`.
+
+### Why is this bad?
+Looks a little redundant. Using `bool::then` is more concise and incurs no loss of clarity.
+For simple calculations and known values, use `bool::then_some`, which is eagerly evaluated
+in comparison to `bool::then`.
+
+### Example
+```
+let a = if v.is_empty() {
+ println!("true!");
+ Some(42)
+} else {
+ None
+};
+```
+
+Could be written:
+
+```
+let a = v.is_empty().then(|| {
+ println!("true!");
+ 42
+});
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ifs_same_cond.txt b/src/tools/clippy/src/docs/ifs_same_cond.txt
new file mode 100644
index 000000000..024ba5df9
--- /dev/null
+++ b/src/tools/clippy/src/docs/ifs_same_cond.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for consecutive `if`s with the same condition.
+
+### Why is this bad?
+This is probably a copy & paste error.
+
+### Example
+```
+if a == b {
+ …
+} else if a == b {
+ …
+}
+```
+
+Note that this lint ignores all conditions with a function call as it could
+have side effects:
+
+```
+if foo() {
+ …
+} else if foo() { // not linted
+ …
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_clone.txt b/src/tools/clippy/src/docs/implicit_clone.txt
new file mode 100644
index 000000000..f5aa112c5
--- /dev/null
+++ b/src/tools/clippy/src/docs/implicit_clone.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer.
+
+### Why is this bad?
+These methods do the same thing as `_.clone()` but may be confusing as
+to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned.
+
+### Example
+```
+let a = vec![1, 2, 3];
+let b = a.to_vec();
+let c = a.to_owned();
+```
+Use instead:
+```
+let a = vec![1, 2, 3];
+let b = a.clone();
+let c = a.clone();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_hasher.txt b/src/tools/clippy/src/docs/implicit_hasher.txt
new file mode 100644
index 000000000..0c1f76620
--- /dev/null
+++ b/src/tools/clippy/src/docs/implicit_hasher.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for public `impl` or `fn` missing generalization
+over different hashers and implicitly defaulting to the default hashing
+algorithm (`SipHash`).
+
+### Why is this bad?
+`HashMap` or `HashSet` with custom hashers cannot be
+used with them.
+
+### Known problems
+Suggestions for replacing constructors can contain
+false-positives. Also applying suggestions can require modification of other
+pieces of code, possibly including external crates.
+
+### Example
+```
+impl<K: Hash + Eq, V> Serialize for HashMap<K, V> { }
+
+pub fn foo(map: &mut HashMap<i32, i32>) { }
+```
+could be rewritten as
+```
+impl<K: Hash + Eq, V, S: BuildHasher> Serialize for HashMap<K, V, S> { }
+
+pub fn foo<S: BuildHasher>(map: &mut HashMap<i32, i32, S>) { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_return.txt b/src/tools/clippy/src/docs/implicit_return.txt
new file mode 100644
index 000000000..ee65a636b
--- /dev/null
+++ b/src/tools/clippy/src/docs/implicit_return.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for missing return statements at the end of a block.
+
+### Why is this bad?
+Actually omitting the return keyword is idiomatic Rust code. Programmers
+coming from other languages might prefer the expressiveness of `return`. It's possible to miss
+the last returning statement because the only difference is a missing `;`. Especially in bigger
+code with multiple return paths having a `return` keyword makes it easier to find the
+corresponding statements.
+
+### Example
+```
+fn foo(x: usize) -> usize {
+ x
+}
+```
+add return
+```
+fn foo(x: usize) -> usize {
+ return x;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_saturating_sub.txt b/src/tools/clippy/src/docs/implicit_saturating_sub.txt
new file mode 100644
index 000000000..03b47905a
--- /dev/null
+++ b/src/tools/clippy/src/docs/implicit_saturating_sub.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for implicit saturating subtraction.
+
+### Why is this bad?
+Simplicity and readability. Instead we can easily use an builtin function.
+
+### Example
+```
+let mut i: u32 = end - start;
+
+if i != 0 {
+ i -= 1;
+}
+```
+
+Use instead:
+```
+let mut i: u32 = end - start;
+
+i = i.saturating_sub(1);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/imprecise_flops.txt b/src/tools/clippy/src/docs/imprecise_flops.txt
new file mode 100644
index 000000000..e84d81cea
--- /dev/null
+++ b/src/tools/clippy/src/docs/imprecise_flops.txt
@@ -0,0 +1,23 @@
+### What it does
+Looks for floating-point expressions that
+can be expressed using built-in methods to improve accuracy
+at the cost of performance.
+
+### Why is this bad?
+Negatively impacts accuracy.
+
+### Example
+```
+let a = 3f32;
+let _ = a.powf(1.0 / 3.0);
+let _ = (1.0 + a).ln();
+let _ = a.exp() - 1.0;
+```
+
+Use instead:
+```
+let a = 3f32;
+let _ = a.cbrt();
+let _ = a.ln_1p();
+let _ = a.exp_m1();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inconsistent_digit_grouping.txt b/src/tools/clippy/src/docs/inconsistent_digit_grouping.txt
new file mode 100644
index 000000000..aa0b072de
--- /dev/null
+++ b/src/tools/clippy/src/docs/inconsistent_digit_grouping.txt
@@ -0,0 +1,17 @@
+### What it does
+Warns if an integral or floating-point constant is
+grouped inconsistently with underscores.
+
+### Why is this bad?
+Readers may incorrectly interpret inconsistently
+grouped digits.
+
+### Example
+```
+618_64_9189_73_511
+```
+
+Use instead:
+```
+61_864_918_973_511
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inconsistent_struct_constructor.txt b/src/tools/clippy/src/docs/inconsistent_struct_constructor.txt
new file mode 100644
index 000000000..eb682109a
--- /dev/null
+++ b/src/tools/clippy/src/docs/inconsistent_struct_constructor.txt
@@ -0,0 +1,40 @@
+### What it does
+Checks for struct constructors where all fields are shorthand and
+the order of the field init shorthand in the constructor is inconsistent
+with the order in the struct definition.
+
+### Why is this bad?
+Since the order of fields in a constructor doesn't affect the
+resulted instance as the below example indicates,
+
+```
+#[derive(Debug, PartialEq, Eq)]
+struct Foo {
+ x: i32,
+ y: i32,
+}
+let x = 1;
+let y = 2;
+
+// This assertion never fails:
+assert_eq!(Foo { x, y }, Foo { y, x });
+```
+
+inconsistent order can be confusing and decreases readability and consistency.
+
+### Example
+```
+struct Foo {
+ x: i32,
+ y: i32,
+}
+let x = 1;
+let y = 2;
+
+Foo { y, x };
+```
+
+Use instead:
+```
+Foo { x, y };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/index_refutable_slice.txt b/src/tools/clippy/src/docs/index_refutable_slice.txt
new file mode 100644
index 000000000..8a7d52761
--- /dev/null
+++ b/src/tools/clippy/src/docs/index_refutable_slice.txt
@@ -0,0 +1,29 @@
+### What it does
+The lint checks for slice bindings in patterns that are only used to
+access individual slice values.
+
+### Why is this bad?
+Accessing slice values using indices can lead to panics. Using refutable
+patterns can avoid these. Binding to individual values also improves the
+readability as they can be named.
+
+### Limitations
+This lint currently only checks for immutable access inside `if let`
+patterns.
+
+### Example
+```
+let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+
+if let Some(slice) = slice {
+ println!("{}", slice[0]);
+}
+```
+Use instead:
+```
+let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+
+if let Some(&[first, ..]) = slice {
+ println!("{}", first);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/indexing_slicing.txt b/src/tools/clippy/src/docs/indexing_slicing.txt
new file mode 100644
index 000000000..76ca6ed31
--- /dev/null
+++ b/src/tools/clippy/src/docs/indexing_slicing.txt
@@ -0,0 +1,33 @@
+### What it does
+Checks for usage of indexing or slicing. Arrays are special cases, this lint
+does report on arrays if we can tell that slicing operations are in bounds and does not
+lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
+
+### Why is this bad?
+Indexing and slicing can panic at runtime and there are
+safe alternatives.
+
+### Example
+```
+// Vector
+let x = vec![0; 5];
+
+x[2];
+&x[2..100];
+
+// Array
+let y = [0, 1, 2, 3];
+
+&y[10..100];
+&y[10..];
+```
+
+Use instead:
+```
+
+x.get(2);
+x.get(2..100);
+
+y.get(10);
+y.get(10..100);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ineffective_bit_mask.txt b/src/tools/clippy/src/docs/ineffective_bit_mask.txt
new file mode 100644
index 000000000..f6e7ef556
--- /dev/null
+++ b/src/tools/clippy/src/docs/ineffective_bit_mask.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for bit masks in comparisons which can be removed
+without changing the outcome. The basic structure can be seen in the
+following table:
+
+|Comparison| Bit Op |Example |equals |
+|----------|----------|------------|-------|
+|`>` / `<=`|`\|` / `^`|`x \| 2 > 3`|`x > 3`|
+|`<` / `>=`|`\|` / `^`|`x ^ 1 < 4` |`x < 4`|
+
+### Why is this bad?
+Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
+but still a bit misleading, because the bit mask is ineffective.
+
+### Known problems
+False negatives: This lint will only match instances
+where we have figured out the math (which is for a power-of-two compared
+value). This means things like `x | 1 >= 7` (which would be better written
+as `x >= 6`) will not be reported (but bit masks like this are fairly
+uncommon).
+
+### Example
+```
+if (x | 1 > 3) { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inefficient_to_string.txt b/src/tools/clippy/src/docs/inefficient_to_string.txt
new file mode 100644
index 000000000..f7061d1ce
--- /dev/null
+++ b/src/tools/clippy/src/docs/inefficient_to_string.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for usage of `.to_string()` on an `&&T` where
+`T` implements `ToString` directly (like `&&str` or `&&String`).
+
+### Why is this bad?
+This bypasses the specialized implementation of
+`ToString` and instead goes through the more expensive string formatting
+facilities.
+
+### Example
+```
+// Generic implementation for `T: Display` is used (slow)
+["foo", "bar"].iter().map(|s| s.to_string());
+
+// OK, the specialized impl is used
+["foo", "bar"].iter().map(|&s| s.to_string());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/infallible_destructuring_match.txt b/src/tools/clippy/src/docs/infallible_destructuring_match.txt
new file mode 100644
index 000000000..4b5d3c4ba
--- /dev/null
+++ b/src/tools/clippy/src/docs/infallible_destructuring_match.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for matches being used to destructure a single-variant enum
+or tuple struct where a `let` will suffice.
+
+### Why is this bad?
+Just readability – `let` doesn't nest, whereas a `match` does.
+
+### Example
+```
+enum Wrapper {
+ Data(i32),
+}
+
+let wrapper = Wrapper::Data(42);
+
+let data = match wrapper {
+ Wrapper::Data(i) => i,
+};
+```
+
+The correct use would be:
+```
+enum Wrapper {
+ Data(i32),
+}
+
+let wrapper = Wrapper::Data(42);
+let Wrapper::Data(data) = wrapper;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/infinite_iter.txt b/src/tools/clippy/src/docs/infinite_iter.txt
new file mode 100644
index 000000000..8a22fabc5
--- /dev/null
+++ b/src/tools/clippy/src/docs/infinite_iter.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for iteration that is guaranteed to be infinite.
+
+### Why is this bad?
+While there may be places where this is acceptable
+(e.g., in event streams), in most cases this is simply an error.
+
+### Example
+```
+use std::iter;
+
+iter::repeat(1_u8).collect::<Vec<_>>();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inherent_to_string.txt b/src/tools/clippy/src/docs/inherent_to_string.txt
new file mode 100644
index 000000000..b18e600e9
--- /dev/null
+++ b/src/tools/clippy/src/docs/inherent_to_string.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`.
+
+### Why is this bad?
+This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred.
+
+### Example
+```
+pub struct A;
+
+impl A {
+ pub fn to_string(&self) -> String {
+ "I am A".to_string()
+ }
+}
+```
+
+Use instead:
+```
+use std::fmt;
+
+pub struct A;
+
+impl fmt::Display for A {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "I am A")
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt b/src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt
new file mode 100644
index 000000000..a4bd0b622
--- /dev/null
+++ b/src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt
@@ -0,0 +1,37 @@
+### What it does
+Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait.
+
+### Why is this bad?
+This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`.
+
+### Example
+```
+use std::fmt;
+
+pub struct A;
+
+impl A {
+ pub fn to_string(&self) -> String {
+ "I am A".to_string()
+ }
+}
+
+impl fmt::Display for A {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "I am A, too")
+ }
+}
+```
+
+Use instead:
+```
+use std::fmt;
+
+pub struct A;
+
+impl fmt::Display for A {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "I am A")
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/init_numbered_fields.txt b/src/tools/clippy/src/docs/init_numbered_fields.txt
new file mode 100644
index 000000000..ba40af6a5
--- /dev/null
+++ b/src/tools/clippy/src/docs/init_numbered_fields.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for tuple structs initialized with field syntax.
+It will however not lint if a base initializer is present.
+The lint will also ignore code in macros.
+
+### Why is this bad?
+This may be confusing to the uninitiated and adds no
+benefit as opposed to tuple initializers
+
+### Example
+```
+struct TupleStruct(u8, u16);
+
+let _ = TupleStruct {
+ 0: 1,
+ 1: 23,
+};
+
+// should be written as
+let base = TupleStruct(1, 23);
+
+// This is OK however
+let _ = TupleStruct { 0: 42, ..base };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_always.txt b/src/tools/clippy/src/docs/inline_always.txt
new file mode 100644
index 000000000..7721da4c4
--- /dev/null
+++ b/src/tools/clippy/src/docs/inline_always.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for items annotated with `#[inline(always)]`,
+unless the annotated function is empty or simply panics.
+
+### Why is this bad?
+While there are valid uses of this annotation (and once
+you know when to use it, by all means `allow` this lint), it's a common
+newbie-mistake to pepper one's code with it.
+
+As a rule of thumb, before slapping `#[inline(always)]` on a function,
+measure if that additional function call really affects your runtime profile
+sufficiently to make up for the increase in compile time.
+
+### Known problems
+False positives, big time. This lint is meant to be
+deactivated by everyone doing serious performance work. This means having
+done the measurement.
+
+### Example
+```
+#[inline(always)]
+fn not_quite_hot_code(..) { ... }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt b/src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt
new file mode 100644
index 000000000..8eb49d122
--- /dev/null
+++ b/src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of AT&T x86 assembly syntax.
+
+### Why is this bad?
+The lint has been enabled to indicate a preference
+for Intel x86 assembly syntax.
+
+### Example
+
+```
+asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
+```
+Use instead:
+```
+asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt b/src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt
new file mode 100644
index 000000000..5aa22c8ed
--- /dev/null
+++ b/src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of Intel x86 assembly syntax.
+
+### Why is this bad?
+The lint has been enabled to indicate a preference
+for AT&T x86 assembly syntax.
+
+### Example
+
+```
+asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
+```
+Use instead:
+```
+asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_fn_without_body.txt b/src/tools/clippy/src/docs/inline_fn_without_body.txt
new file mode 100644
index 000000000..127c161aa
--- /dev/null
+++ b/src/tools/clippy/src/docs/inline_fn_without_body.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for `#[inline]` on trait methods without bodies
+
+### Why is this bad?
+Only implementations of trait methods may be inlined.
+The inline attribute is ignored for trait methods without bodies.
+
+### Example
+```
+trait Animal {
+ #[inline]
+ fn name(&self) -> &'static str;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inspect_for_each.txt b/src/tools/clippy/src/docs/inspect_for_each.txt
new file mode 100644
index 000000000..01a46d6c4
--- /dev/null
+++ b/src/tools/clippy/src/docs/inspect_for_each.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for usage of `inspect().for_each()`.
+
+### Why is this bad?
+It is the same as performing the computation
+inside `inspect` at the beginning of the closure in `for_each`.
+
+### Example
+```
+[1,2,3,4,5].iter()
+.inspect(|&x| println!("inspect the number: {}", x))
+.for_each(|&x| {
+ assert!(x >= 0);
+});
+```
+Can be written as
+```
+[1,2,3,4,5].iter()
+.for_each(|&x| {
+ println!("inspect the number: {}", x);
+ assert!(x >= 0);
+});
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/int_plus_one.txt b/src/tools/clippy/src/docs/int_plus_one.txt
new file mode 100644
index 000000000..1b68f3eeb
--- /dev/null
+++ b/src/tools/clippy/src/docs/int_plus_one.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
+
+### Why is this bad?
+Readability -- better to use `> y` instead of `>= y + 1`.
+
+### Example
+```
+if x >= y + 1 {}
+```
+
+Use instead:
+```
+if x > y {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/integer_arithmetic.txt b/src/tools/clippy/src/docs/integer_arithmetic.txt
new file mode 100644
index 000000000..ea57a2ef9
--- /dev/null
+++ b/src/tools/clippy/src/docs/integer_arithmetic.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for integer arithmetic operations which could overflow or panic.
+
+Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable
+of overflowing according to the [Rust
+Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
+or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is
+attempted.
+
+### Why is this bad?
+Integer overflow will trigger a panic in debug builds or will wrap in
+release mode. Division by zero will cause a panic in either mode. In some applications one
+wants explicitly checked, wrapping or saturating arithmetic.
+
+### Example
+```
+a + 1;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/integer_division.txt b/src/tools/clippy/src/docs/integer_division.txt
new file mode 100644
index 000000000..f6d334981
--- /dev/null
+++ b/src/tools/clippy/src/docs/integer_division.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for division of integers
+
+### Why is this bad?
+When outside of some very specific algorithms,
+integer division is very often a mistake because it discards the
+remainder.
+
+### Example
+```
+let x = 3 / 2;
+println!("{}", x);
+```
+
+Use instead:
+```
+let x = 3f32 / 2f32;
+println!("{}", x);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/into_iter_on_ref.txt b/src/tools/clippy/src/docs/into_iter_on_ref.txt
new file mode 100644
index 000000000..acb6bd474
--- /dev/null
+++ b/src/tools/clippy/src/docs/into_iter_on_ref.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for `into_iter` calls on references which should be replaced by `iter`
+or `iter_mut`.
+
+### Why is this bad?
+Readability. Calling `into_iter` on a reference will not move out its
+content into the resulting iterator, which is confusing. It is better just call `iter` or
+`iter_mut` directly.
+
+### Example
+```
+(&vec).into_iter();
+```
+
+Use instead:
+```
+(&vec).iter();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_null_ptr_usage.txt b/src/tools/clippy/src/docs/invalid_null_ptr_usage.txt
new file mode 100644
index 000000000..6fb3fa3f8
--- /dev/null
+++ b/src/tools/clippy/src/docs/invalid_null_ptr_usage.txt
@@ -0,0 +1,16 @@
+### What it does
+This lint checks for invalid usages of `ptr::null`.
+
+### Why is this bad?
+This causes undefined behavior.
+
+### Example
+```
+// Undefined behavior
+unsafe { std::slice::from_raw_parts(ptr::null(), 0); }
+```
+
+Use instead:
+```
+unsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_regex.txt b/src/tools/clippy/src/docs/invalid_regex.txt
new file mode 100644
index 000000000..6c9969b6e
--- /dev/null
+++ b/src/tools/clippy/src/docs/invalid_regex.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks [regex](https://crates.io/crates/regex) creation
+(with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct
+regex syntax.
+
+### Why is this bad?
+This will lead to a runtime panic.
+
+### Example
+```
+Regex::new("(")
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_upcast_comparisons.txt b/src/tools/clippy/src/docs/invalid_upcast_comparisons.txt
new file mode 100644
index 000000000..77cb03308
--- /dev/null
+++ b/src/tools/clippy/src/docs/invalid_upcast_comparisons.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for comparisons where the relation is always either
+true or false, but where one side has been upcast so that the comparison is
+necessary. Only integer types are checked.
+
+### Why is this bad?
+An expression like `let x : u8 = ...; (x as u32) > 300`
+will mistakenly imply that it is possible for `x` to be outside the range of
+`u8`.
+
+### Known problems
+https://github.com/rust-lang/rust-clippy/issues/886
+
+### Example
+```
+let x: u8 = 1;
+(x as u32) > 300;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt b/src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt
new file mode 100644
index 000000000..afb5acbe9
--- /dev/null
+++ b/src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for `std::str::from_utf8_unchecked` with an invalid UTF-8 literal
+
+### Why is this bad?
+Creating such a `str` would result in undefined behavior
+
+### Example
+```
+unsafe {
+ std::str::from_utf8_unchecked(b"cl\x82ippy");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invisible_characters.txt b/src/tools/clippy/src/docs/invisible_characters.txt
new file mode 100644
index 000000000..3dda38091
--- /dev/null
+++ b/src/tools/clippy/src/docs/invisible_characters.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for invisible Unicode characters in the code.
+
+### Why is this bad?
+Having an invisible character in the code makes for all
+sorts of April fools, but otherwise is very much frowned upon.
+
+### Example
+You don't see it, but there may be a zero-width space or soft hyphen
+some­where in this text. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/is_digit_ascii_radix.txt b/src/tools/clippy/src/docs/is_digit_ascii_radix.txt
new file mode 100644
index 000000000..9f11cf430
--- /dev/null
+++ b/src/tools/clippy/src/docs/is_digit_ascii_radix.txt
@@ -0,0 +1,20 @@
+### What it does
+Finds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that
+can be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or
+[`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit).
+
+### Why is this bad?
+`is_digit(..)` is slower and requires specifying the radix.
+
+### Example
+```
+let c: char = '6';
+c.is_digit(10);
+c.is_digit(16);
+```
+Use instead:
+```
+let c: char = '6';
+c.is_ascii_digit();
+c.is_ascii_hexdigit();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/items_after_statements.txt b/src/tools/clippy/src/docs/items_after_statements.txt
new file mode 100644
index 000000000..6fdfff50d
--- /dev/null
+++ b/src/tools/clippy/src/docs/items_after_statements.txt
@@ -0,0 +1,37 @@
+### What it does
+Checks for items declared after some statement in a block.
+
+### Why is this bad?
+Items live for the entire scope they are declared
+in. But statements are processed in order. This might cause confusion as
+it's hard to figure out which item is meant in a statement.
+
+### Example
+```
+fn foo() {
+ println!("cake");
+}
+
+fn main() {
+ foo(); // prints "foo"
+ fn foo() {
+ println!("foo");
+ }
+ foo(); // prints "foo"
+}
+```
+
+Use instead:
+```
+fn foo() {
+ println!("cake");
+}
+
+fn main() {
+ fn foo() {
+ println!("foo");
+ }
+ foo(); // prints "foo"
+ foo(); // prints "foo"
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_cloned_collect.txt b/src/tools/clippy/src/docs/iter_cloned_collect.txt
new file mode 100644
index 000000000..90dc9ebb4
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_cloned_collect.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for the use of `.cloned().collect()` on slice to
+create a `Vec`.
+
+### Why is this bad?
+`.to_vec()` is clearer
+
+### Example
+```
+let s = [1, 2, 3, 4, 5];
+let s2: Vec<isize> = s[..].iter().cloned().collect();
+```
+The better use would be:
+```
+let s = [1, 2, 3, 4, 5];
+let s2: Vec<isize> = s.to_vec();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_count.txt b/src/tools/clippy/src/docs/iter_count.txt
new file mode 100644
index 000000000..f3db4a26c
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_count.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for the use of `.iter().count()`.
+
+### Why is this bad?
+`.len()` is more efficient and more
+readable.
+
+### Example
+```
+let some_vec = vec![0, 1, 2, 3];
+
+some_vec.iter().count();
+&some_vec[..].iter().count();
+```
+
+Use instead:
+```
+let some_vec = vec![0, 1, 2, 3];
+
+some_vec.len();
+&some_vec[..].len();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_next_loop.txt b/src/tools/clippy/src/docs/iter_next_loop.txt
new file mode 100644
index 000000000..b33eb39d6
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_next_loop.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for loops on `x.next()`.
+
+### Why is this bad?
+`next()` returns either `Some(value)` if there was a
+value, or `None` otherwise. The insidious thing is that `Option<_>`
+implements `IntoIterator`, so that possibly one value will be iterated,
+leading to some hard to find bugs. No one will want to write such code
+[except to win an Underhanded Rust
+Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).
+
+### Example
+```
+for x in y.next() {
+ ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_next_slice.txt b/src/tools/clippy/src/docs/iter_next_slice.txt
new file mode 100644
index 000000000..1cea25eaf
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_next_slice.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of `iter().next()` on a Slice or an Array
+
+### Why is this bad?
+These can be shortened into `.get()`
+
+### Example
+```
+a[2..].iter().next();
+b.iter().next();
+```
+should be written as:
+```
+a.get(2);
+b.get(0);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_not_returning_iterator.txt b/src/tools/clippy/src/docs/iter_not_returning_iterator.txt
new file mode 100644
index 000000000..0ca862910
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_not_returning_iterator.txt
@@ -0,0 +1,26 @@
+### What it does
+Detects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`.
+
+### Why is this bad?
+Methods named `iter` or `iter_mut` conventionally return an `Iterator`.
+
+### Example
+```
+// `String` does not implement `Iterator`
+struct Data {}
+impl Data {
+ fn iter(&self) -> String {
+ todo!()
+ }
+}
+```
+Use instead:
+```
+use std::str::Chars;
+struct Data {}
+impl Data {
+ fn iter(&self) -> Chars<'static> {
+ todo!()
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_nth.txt b/src/tools/clippy/src/docs/iter_nth.txt
new file mode 100644
index 000000000..3d67d583f
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_nth.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for use of `.iter().nth()` (and the related
+`.iter_mut().nth()`) on standard library types with *O*(1) element access.
+
+### Why is this bad?
+`.get()` and `.get_mut()` are more efficient and more
+readable.
+
+### Example
+```
+let some_vec = vec![0, 1, 2, 3];
+let bad_vec = some_vec.iter().nth(3);
+let bad_slice = &some_vec[..].iter().nth(3);
+```
+The correct use would be:
+```
+let some_vec = vec![0, 1, 2, 3];
+let bad_vec = some_vec.get(3);
+let bad_slice = &some_vec[..].get(3);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_nth_zero.txt b/src/tools/clippy/src/docs/iter_nth_zero.txt
new file mode 100644
index 000000000..8efe47a16
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_nth_zero.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for the use of `iter.nth(0)`.
+
+### Why is this bad?
+`iter.next()` is equivalent to
+`iter.nth(0)`, as they both consume the next element,
+ but is more readable.
+
+### Example
+```
+let x = s.iter().nth(0);
+```
+
+Use instead:
+```
+let x = s.iter().next();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_on_empty_collections.txt b/src/tools/clippy/src/docs/iter_on_empty_collections.txt
new file mode 100644
index 000000000..87c4ec12a
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_on_empty_collections.txt
@@ -0,0 +1,25 @@
+### What it does
+
+Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections
+
+### Why is this bad?
+
+It is simpler to use the empty function from the standard library:
+
+### Example
+
+```
+use std::{slice, option};
+let a: slice::Iter<i32> = [].iter();
+let f: option::IntoIter<i32> = None.into_iter();
+```
+Use instead:
+```
+use std::iter;
+let a: iter::Empty<i32> = iter::empty();
+let b: iter::Empty<i32> = iter::empty();
+```
+
+### Known problems
+
+The type of the resulting iterator might become incompatible with its usage \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_on_single_items.txt b/src/tools/clippy/src/docs/iter_on_single_items.txt
new file mode 100644
index 000000000..d0388f25d
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_on_single_items.txt
@@ -0,0 +1,24 @@
+### What it does
+
+Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item
+
+### Why is this bad?
+
+It is simpler to use the once function from the standard library:
+
+### Example
+
+```
+let a = [123].iter();
+let b = Some(123).into_iter();
+```
+Use instead:
+```
+use std::iter;
+let a = iter::once(&123);
+let b = iter::once(123);
+```
+
+### Known problems
+
+The type of the resulting iterator might become incompatible with its usage \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_overeager_cloned.txt b/src/tools/clippy/src/docs/iter_overeager_cloned.txt
new file mode 100644
index 000000000..2f902a0c2
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_overeager_cloned.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed.
+
+### Why is this bad?
+It's often inefficient to clone all elements of an iterator, when eventually, only some
+of them will be consumed.
+
+### Known Problems
+This `lint` removes the side of effect of cloning items in the iterator.
+A code that relies on that side-effect could fail.
+
+### Examples
+```
+vec.iter().cloned().take(10);
+vec.iter().cloned().last();
+```
+
+Use instead:
+```
+vec.iter().take(10).cloned();
+vec.iter().last().cloned();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_skip_next.txt b/src/tools/clippy/src/docs/iter_skip_next.txt
new file mode 100644
index 000000000..da226b041
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_skip_next.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for use of `.skip(x).next()` on iterators.
+
+### Why is this bad?
+`.nth(x)` is cleaner
+
+### Example
+```
+let some_vec = vec![0, 1, 2, 3];
+let bad_vec = some_vec.iter().skip(3).next();
+let bad_slice = &some_vec[..].iter().skip(3).next();
+```
+The correct use would be:
+```
+let some_vec = vec![0, 1, 2, 3];
+let bad_vec = some_vec.iter().nth(3);
+let bad_slice = &some_vec[..].iter().nth(3);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_with_drain.txt b/src/tools/clippy/src/docs/iter_with_drain.txt
new file mode 100644
index 000000000..2c52b99f7
--- /dev/null
+++ b/src/tools/clippy/src/docs/iter_with_drain.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for use of `.drain(..)` on `Vec` and `VecDeque` for iteration.
+
+### Why is this bad?
+`.into_iter()` is simpler with better performance.
+
+### Example
+```
+let mut foo = vec![0, 1, 2, 3];
+let bar: HashSet<usize> = foo.drain(..).collect();
+```
+Use instead:
+```
+let foo = vec![0, 1, 2, 3];
+let bar: HashSet<usize> = foo.into_iter().collect();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iterator_step_by_zero.txt b/src/tools/clippy/src/docs/iterator_step_by_zero.txt
new file mode 100644
index 000000000..73ecc99ac
--- /dev/null
+++ b/src/tools/clippy/src/docs/iterator_step_by_zero.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for calling `.step_by(0)` on iterators which panics.
+
+### Why is this bad?
+This very much looks like an oversight. Use `panic!()` instead if you
+actually intend to panic.
+
+### Example
+```
+for x in (0..100).step_by(0) {
+ //..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/just_underscores_and_digits.txt b/src/tools/clippy/src/docs/just_underscores_and_digits.txt
new file mode 100644
index 000000000..a8790bcf2
--- /dev/null
+++ b/src/tools/clippy/src/docs/just_underscores_and_digits.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks if you have variables whose name consists of just
+underscores and digits.
+
+### Why is this bad?
+It's hard to memorize what a variable means without a
+descriptive name.
+
+### Example
+```
+let _1 = 1;
+let ___1 = 1;
+let __1___2 = 11;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_const_arrays.txt b/src/tools/clippy/src/docs/large_const_arrays.txt
new file mode 100644
index 000000000..71f67854f
--- /dev/null
+++ b/src/tools/clippy/src/docs/large_const_arrays.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for large `const` arrays that should
+be defined as `static` instead.
+
+### Why is this bad?
+Performance: const variables are inlined upon use.
+Static items result in only one instance and has a fixed location in memory.
+
+### Example
+```
+pub const a = [0u32; 1_000_000];
+```
+
+Use instead:
+```
+pub static a = [0u32; 1_000_000];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_digit_groups.txt b/src/tools/clippy/src/docs/large_digit_groups.txt
new file mode 100644
index 000000000..f60b19345
--- /dev/null
+++ b/src/tools/clippy/src/docs/large_digit_groups.txt
@@ -0,0 +1,12 @@
+### What it does
+Warns if the digits of an integral or floating-point
+constant are grouped into groups that
+are too large.
+
+### Why is this bad?
+Negatively impacts readability.
+
+### Example
+```
+let x: u64 = 6186491_8973511;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_enum_variant.txt b/src/tools/clippy/src/docs/large_enum_variant.txt
new file mode 100644
index 000000000..1f9543079
--- /dev/null
+++ b/src/tools/clippy/src/docs/large_enum_variant.txt
@@ -0,0 +1,41 @@
+### What it does
+Checks for large size differences between variants on
+`enum`s.
+
+### Why is this bad?
+Enum size is bounded by the largest variant. Having one
+large variant can penalize the memory layout of that enum.
+
+### Known problems
+This lint obviously cannot take the distribution of
+variants in your running program into account. It is possible that the
+smaller variants make up less than 1% of all instances, in which case
+the overhead is negligible and the boxing is counter-productive. Always
+measure the change this lint suggests.
+
+For types that implement `Copy`, the suggestion to `Box` a variant's
+data would require removing the trait impl. The types can of course
+still be `Clone`, but that is worse ergonomically. Depending on the
+use case it may be possible to store the large data in an auxiliary
+structure (e.g. Arena or ECS).
+
+The lint will ignore the impact of generic types to the type layout by
+assuming every type parameter is zero-sized. Depending on your use case,
+this may lead to a false positive.
+
+### Example
+```
+enum Test {
+ A(i32),
+ B([i32; 8000]),
+}
+```
+
+Use instead:
+```
+// Possibly better
+enum Test2 {
+ A(i32),
+ B(Box<[i32; 8000]>),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_include_file.txt b/src/tools/clippy/src/docs/large_include_file.txt
new file mode 100644
index 000000000..b2a54bd2e
--- /dev/null
+++ b/src/tools/clippy/src/docs/large_include_file.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for the inclusion of large files via `include_bytes!()`
+and `include_str!()`
+
+### Why is this bad?
+Including large files can increase the size of the binary
+
+### Example
+```
+let included_str = include_str!("very_large_file.txt");
+let included_bytes = include_bytes!("very_large_file.txt");
+```
+
+Use instead:
+```
+use std::fs;
+
+// You can load the file at runtime
+let string = fs::read_to_string("very_large_file.txt")?;
+let bytes = fs::read("very_large_file.txt")?;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_stack_arrays.txt b/src/tools/clippy/src/docs/large_stack_arrays.txt
new file mode 100644
index 000000000..4a6f34785
--- /dev/null
+++ b/src/tools/clippy/src/docs/large_stack_arrays.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for local arrays that may be too large.
+
+### Why is this bad?
+Large local arrays may cause stack overflow.
+
+### Example
+```
+let a = [0u32; 1_000_000];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_types_passed_by_value.txt b/src/tools/clippy/src/docs/large_types_passed_by_value.txt
new file mode 100644
index 000000000..bca07f3ac
--- /dev/null
+++ b/src/tools/clippy/src/docs/large_types_passed_by_value.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for functions taking arguments by value, where
+the argument type is `Copy` and large enough to be worth considering
+passing by reference. Does not trigger if the function is being exported,
+because that might induce API breakage, if the parameter is declared as mutable,
+or if the argument is a `self`.
+
+### Why is this bad?
+Arguments passed by value might result in an unnecessary
+shallow copy, taking up more space in the stack and requiring a call to
+`memcpy`, which can be expensive.
+
+### Example
+```
+#[derive(Clone, Copy)]
+struct TooLarge([u8; 2048]);
+
+fn foo(v: TooLarge) {}
+```
+
+Use instead:
+```
+fn foo(v: &TooLarge) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/len_without_is_empty.txt b/src/tools/clippy/src/docs/len_without_is_empty.txt
new file mode 100644
index 000000000..47a2e8575
--- /dev/null
+++ b/src/tools/clippy/src/docs/len_without_is_empty.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for items that implement `.len()` but not
+`.is_empty()`.
+
+### Why is this bad?
+It is good custom to have both methods, because for
+some data structures, asking about the length will be a costly operation,
+whereas `.is_empty()` can usually answer in constant time. Also it used to
+lead to false positives on the [`len_zero`](#len_zero) lint – currently that
+lint will ignore such entities.
+
+### Example
+```
+impl X {
+ pub fn len(&self) -> usize {
+ ..
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/len_zero.txt b/src/tools/clippy/src/docs/len_zero.txt
new file mode 100644
index 000000000..664124bd3
--- /dev/null
+++ b/src/tools/clippy/src/docs/len_zero.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for getting the length of something via `.len()`
+just to compare to zero, and suggests using `.is_empty()` where applicable.
+
+### Why is this bad?
+Some structures can answer `.is_empty()` much faster
+than calculating their length. So it is good to get into the habit of using
+`.is_empty()`, and having it is cheap.
+Besides, it makes the intent clearer than a manual comparison in some contexts.
+
+### Example
+```
+if x.len() == 0 {
+ ..
+}
+if y.len() != 0 {
+ ..
+}
+```
+instead use
+```
+if x.is_empty() {
+ ..
+}
+if !y.is_empty() {
+ ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_and_return.txt b/src/tools/clippy/src/docs/let_and_return.txt
new file mode 100644
index 000000000..eba5a90dd
--- /dev/null
+++ b/src/tools/clippy/src/docs/let_and_return.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for `let`-bindings, which are subsequently
+returned.
+
+### Why is this bad?
+It is just extraneous code. Remove it to make your code
+more rusty.
+
+### Example
+```
+fn foo() -> String {
+ let x = String::new();
+ x
+}
+```
+instead, use
+```
+fn foo() -> String {
+ String::new()
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_underscore_drop.txt b/src/tools/clippy/src/docs/let_underscore_drop.txt
new file mode 100644
index 000000000..29ce9bf50
--- /dev/null
+++ b/src/tools/clippy/src/docs/let_underscore_drop.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for `let _ = <expr>`
+where expr has a type that implements `Drop`
+
+### Why is this bad?
+This statement immediately drops the initializer
+expression instead of extending its lifetime to the end of the scope, which
+is often not intended. To extend the expression's lifetime to the end of the
+scope, use an underscore-prefixed name instead (i.e. _var). If you want to
+explicitly drop the expression, `std::mem::drop` conveys your intention
+better and is less error-prone.
+
+### Example
+```
+{
+ let _ = DroppableItem;
+ // ^ dropped here
+ /* more code */
+}
+```
+
+Use instead:
+```
+{
+ let _droppable = DroppableItem;
+ /* more code */
+ // dropped at end of scope
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_underscore_lock.txt b/src/tools/clippy/src/docs/let_underscore_lock.txt
new file mode 100644
index 000000000..bd8217fb5
--- /dev/null
+++ b/src/tools/clippy/src/docs/let_underscore_lock.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for `let _ = sync_lock`.
+This supports `mutex` and `rwlock` in `std::sync` and `parking_lot`.
+
+### Why is this bad?
+This statement immediately drops the lock instead of
+extending its lifetime to the end of the scope, which is often not intended.
+To extend lock lifetime to the end of the scope, use an underscore-prefixed
+name instead (i.e. _lock). If you want to explicitly drop the lock,
+`std::mem::drop` conveys your intention better and is less error-prone.
+
+### Example
+```
+let _ = mutex.lock();
+```
+
+Use instead:
+```
+let _lock = mutex.lock();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_underscore_must_use.txt b/src/tools/clippy/src/docs/let_underscore_must_use.txt
new file mode 100644
index 000000000..270b81d9a
--- /dev/null
+++ b/src/tools/clippy/src/docs/let_underscore_must_use.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for `let _ = <expr>` where expr is `#[must_use]`
+
+### Why is this bad?
+It's better to explicitly handle the value of a `#[must_use]`
+expr
+
+### Example
+```
+fn f() -> Result<u32, u32> {
+ Ok(0)
+}
+
+let _ = f();
+// is_ok() is marked #[must_use]
+let _ = f().is_ok();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_unit_value.txt b/src/tools/clippy/src/docs/let_unit_value.txt
new file mode 100644
index 000000000..bc16d5b3d
--- /dev/null
+++ b/src/tools/clippy/src/docs/let_unit_value.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for binding a unit value.
+
+### Why is this bad?
+A unit value cannot usefully be used anywhere. So
+binding one is kind of pointless.
+
+### Example
+```
+let x = {
+ 1;
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/linkedlist.txt b/src/tools/clippy/src/docs/linkedlist.txt
new file mode 100644
index 000000000..986ff1369
--- /dev/null
+++ b/src/tools/clippy/src/docs/linkedlist.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for usage of any `LinkedList`, suggesting to use a
+`Vec` or a `VecDeque` (formerly called `RingBuf`).
+
+### Why is this bad?
+Gankro says:
+
+> The TL;DR of `LinkedList` is that it's built on a massive amount of
+pointers and indirection.
+> It wastes memory, it has terrible cache locality, and is all-around slow.
+`RingBuf`, while
+> "only" amortized for push/pop, should be faster in the general case for
+almost every possible
+> workload, and isn't even amortized at all if you can predict the capacity
+you need.
+>
+> `LinkedList`s are only really good if you're doing a lot of merging or
+splitting of lists.
+> This is because they can just mangle some pointers instead of actually
+copying the data. Even
+> if you're doing a lot of insertion in the middle of the list, `RingBuf`
+can still be better
+> because of how expensive it is to seek to the middle of a `LinkedList`.
+
+### Known problems
+False positives – the instances where using a
+`LinkedList` makes sense are few and far between, but they can still happen.
+
+### Example
+```
+let x: LinkedList<usize> = LinkedList::new();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/lossy_float_literal.txt b/src/tools/clippy/src/docs/lossy_float_literal.txt
new file mode 100644
index 000000000..bbcb9115e
--- /dev/null
+++ b/src/tools/clippy/src/docs/lossy_float_literal.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for whole number float literals that
+cannot be represented as the underlying type without loss.
+
+### Why is this bad?
+Rust will silently lose precision during
+conversion to a float.
+
+### Example
+```
+let _: f32 = 16_777_217.0; // 16_777_216.0
+```
+
+Use instead:
+```
+let _: f32 = 16_777_216.0;
+let _: f64 = 16_777_217.0;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/macro_use_imports.txt b/src/tools/clippy/src/docs/macro_use_imports.txt
new file mode 100644
index 000000000..6a8180a60
--- /dev/null
+++ b/src/tools/clippy/src/docs/macro_use_imports.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for `#[macro_use] use...`.
+
+### Why is this bad?
+Since the Rust 2018 edition you can import
+macro's directly, this is considered idiomatic.
+
+### Example
+```
+#[macro_use]
+use some_macro;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/main_recursion.txt b/src/tools/clippy/src/docs/main_recursion.txt
new file mode 100644
index 000000000..e49becd15
--- /dev/null
+++ b/src/tools/clippy/src/docs/main_recursion.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for recursion using the entrypoint.
+
+### Why is this bad?
+Apart from special setups (which we could detect following attributes like #![no_std]),
+recursing into main() seems like an unintuitive anti-pattern we should be able to detect.
+
+### Example
+```
+fn main() {
+ main();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_assert.txt b/src/tools/clippy/src/docs/manual_assert.txt
new file mode 100644
index 000000000..93653081a
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_assert.txt
@@ -0,0 +1,18 @@
+### What it does
+Detects `if`-then-`panic!` that can be replaced with `assert!`.
+
+### Why is this bad?
+`assert!` is simpler than `if`-then-`panic!`.
+
+### Example
+```
+let sad_people: Vec<&str> = vec![];
+if !sad_people.is_empty() {
+ panic!("there are sad people: {:?}", sad_people);
+}
+```
+Use instead:
+```
+let sad_people: Vec<&str> = vec![];
+assert!(sad_people.is_empty(), "there are sad people: {:?}", sad_people);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_async_fn.txt b/src/tools/clippy/src/docs/manual_async_fn.txt
new file mode 100644
index 000000000..d01ac402e
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_async_fn.txt
@@ -0,0 +1,16 @@
+### What it does
+It checks for manual implementations of `async` functions.
+
+### Why is this bad?
+It's more idiomatic to use the dedicated syntax.
+
+### Example
+```
+use std::future::Future;
+
+fn foo() -> impl Future<Output = i32> { async { 42 } }
+```
+Use instead:
+```
+async fn foo() -> i32 { 42 }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_bits.txt b/src/tools/clippy/src/docs/manual_bits.txt
new file mode 100644
index 000000000..b96c2eb15
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_bits.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for uses of `std::mem::size_of::<T>() * 8` when
+`T::BITS` is available.
+
+### Why is this bad?
+Can be written as the shorter `T::BITS`.
+
+### Example
+```
+std::mem::size_of::<usize>() * 8;
+```
+Use instead:
+```
+usize::BITS as usize;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_filter_map.txt b/src/tools/clippy/src/docs/manual_filter_map.txt
new file mode 100644
index 000000000..3b6860798
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_filter_map.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `_.filter(_).map(_)` that can be written more simply
+as `filter_map(_)`.
+
+### Why is this bad?
+Redundant code in the `filter` and `map` operations is poor style and
+less performant.
+
+### Example
+```
+(0_i32..10)
+ .filter(|n| n.checked_add(1).is_some())
+ .map(|n| n.checked_add(1).unwrap());
+```
+
+Use instead:
+```
+(0_i32..10).filter_map(|n| n.checked_add(1));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_find.txt b/src/tools/clippy/src/docs/manual_find.txt
new file mode 100644
index 000000000..e3e07a277
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_find.txt
@@ -0,0 +1,24 @@
+### What it does
+Check for manual implementations of Iterator::find
+
+### Why is this bad?
+It doesn't affect performance, but using `find` is shorter and easier to read.
+
+### Example
+
+```
+fn example(arr: Vec<i32>) -> Option<i32> {
+ for el in arr {
+ if el == 1 {
+ return Some(el);
+ }
+ }
+ None
+}
+```
+Use instead:
+```
+fn example(arr: Vec<i32>) -> Option<i32> {
+ arr.into_iter().find(|&el| el == 1)
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_find_map.txt b/src/tools/clippy/src/docs/manual_find_map.txt
new file mode 100644
index 000000000..83b22060c
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_find_map.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `_.find(_).map(_)` that can be written more simply
+as `find_map(_)`.
+
+### Why is this bad?
+Redundant code in the `find` and `map` operations is poor style and
+less performant.
+
+### Example
+```
+(0_i32..10)
+ .find(|n| n.checked_add(1).is_some())
+ .map(|n| n.checked_add(1).unwrap());
+```
+
+Use instead:
+```
+(0_i32..10).find_map(|n| n.checked_add(1));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_flatten.txt b/src/tools/clippy/src/docs/manual_flatten.txt
new file mode 100644
index 000000000..62d5f3ec9
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_flatten.txt
@@ -0,0 +1,25 @@
+### What it does
+Check for unnecessary `if let` usage in a for loop
+where only the `Some` or `Ok` variant of the iterator element is used.
+
+### Why is this bad?
+It is verbose and can be simplified
+by first calling the `flatten` method on the `Iterator`.
+
+### Example
+
+```
+let x = vec![Some(1), Some(2), Some(3)];
+for n in x {
+ if let Some(n) = n {
+ println!("{}", n);
+ }
+}
+```
+Use instead:
+```
+let x = vec![Some(1), Some(2), Some(3)];
+for n in x.into_iter().flatten() {
+ println!("{}", n);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_instant_elapsed.txt b/src/tools/clippy/src/docs/manual_instant_elapsed.txt
new file mode 100644
index 000000000..dde3d493c
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_instant_elapsed.txt
@@ -0,0 +1,21 @@
+### What it does
+Lints subtraction between `Instant::now()` and another `Instant`.
+
+### Why is this bad?
+It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
+as `Instant` subtraction saturates.
+
+`prev_instant.elapsed()` also more clearly signals intention.
+
+### Example
+```
+use std::time::Instant;
+let prev_instant = Instant::now();
+let duration = Instant::now() - prev_instant;
+```
+Use instead:
+```
+use std::time::Instant;
+let prev_instant = Instant::now();
+let duration = prev_instant.elapsed();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_map.txt b/src/tools/clippy/src/docs/manual_map.txt
new file mode 100644
index 000000000..7f68ccd10
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_map.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for usages of `match` which could be implemented using `map`
+
+### Why is this bad?
+Using the `map` method is clearer and more concise.
+
+### Example
+```
+match Some(0) {
+ Some(x) => Some(x + 1),
+ None => None,
+};
+```
+Use instead:
+```
+Some(0).map(|x| x + 1);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_memcpy.txt b/src/tools/clippy/src/docs/manual_memcpy.txt
new file mode 100644
index 000000000..d7690bf25
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_memcpy.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for for-loops that manually copy items between
+slices that could be optimized by having a memcpy.
+
+### Why is this bad?
+It is not as fast as a memcpy.
+
+### Example
+```
+for i in 0..src.len() {
+ dst[i + 64] = src[i];
+}
+```
+
+Use instead:
+```
+dst[64..(src.len() + 64)].clone_from_slice(&src[..]);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_non_exhaustive.txt b/src/tools/clippy/src/docs/manual_non_exhaustive.txt
new file mode 100644
index 000000000..fb021393b
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_non_exhaustive.txt
@@ -0,0 +1,41 @@
+### What it does
+Checks for manual implementations of the non-exhaustive pattern.
+
+### Why is this bad?
+Using the #[non_exhaustive] attribute expresses better the intent
+and allows possible optimizations when applied to enums.
+
+### Example
+```
+struct S {
+ pub a: i32,
+ pub b: i32,
+ _c: (),
+}
+
+enum E {
+ A,
+ B,
+ #[doc(hidden)]
+ _C,
+}
+
+struct T(pub i32, pub i32, ());
+```
+Use instead:
+```
+#[non_exhaustive]
+struct S {
+ pub a: i32,
+ pub b: i32,
+}
+
+#[non_exhaustive]
+enum E {
+ A,
+ B,
+}
+
+#[non_exhaustive]
+struct T(pub i32, pub i32);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_ok_or.txt b/src/tools/clippy/src/docs/manual_ok_or.txt
new file mode 100644
index 000000000..5accdf259
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_ok_or.txt
@@ -0,0 +1,19 @@
+### What it does
+
+Finds patterns that reimplement `Option::ok_or`.
+
+### Why is this bad?
+
+Concise code helps focusing on behavior instead of boilerplate.
+
+### Examples
+```
+let foo: Option<i32> = None;
+foo.map_or(Err("error"), |v| Ok(v));
+```
+
+Use instead:
+```
+let foo: Option<i32> = None;
+foo.ok_or("error");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_range_contains.txt b/src/tools/clippy/src/docs/manual_range_contains.txt
new file mode 100644
index 000000000..0ade26951
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_range_contains.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for expressions like `x >= 3 && x < 8` that could
+be more readably expressed as `(3..8).contains(x)`.
+
+### Why is this bad?
+`contains` expresses the intent better and has less
+failure modes (such as fencepost errors or using `||` instead of `&&`).
+
+### Example
+```
+// given
+let x = 6;
+
+assert!(x >= 3 && x < 8);
+```
+Use instead:
+```
+assert!((3..8).contains(&x));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_rem_euclid.txt b/src/tools/clippy/src/docs/manual_rem_euclid.txt
new file mode 100644
index 000000000..d3bb8c613
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_rem_euclid.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation
+of `x.rem_euclid(4)`.
+
+### Why is this bad?
+It's simpler and more readable.
+
+### Example
+```
+let x: i32 = 24;
+let rem = ((x % 4) + 4) % 4;
+```
+Use instead:
+```
+let x: i32 = 24;
+let rem = x.rem_euclid(4);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_retain.txt b/src/tools/clippy/src/docs/manual_retain.txt
new file mode 100644
index 000000000..cd4f65a93
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_retain.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for code to be replaced by `.retain()`.
+### Why is this bad?
+`.retain()` is simpler and avoids needless allocation.
+### Example
+```
+let mut vec = vec![0, 1, 2];
+vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
+vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
+```
+Use instead:
+```
+let mut vec = vec![0, 1, 2];
+vec.retain(|x| x % 2 == 0);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_saturating_arithmetic.txt b/src/tools/clippy/src/docs/manual_saturating_arithmetic.txt
new file mode 100644
index 000000000..d9f5d3d11
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_saturating_arithmetic.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`.
+
+### Why is this bad?
+These can be written simply with `saturating_add/sub` methods.
+
+### Example
+```
+let add = x.checked_add(y).unwrap_or(u32::MAX);
+let sub = x.checked_sub(y).unwrap_or(u32::MIN);
+```
+
+can be written using dedicated methods for saturating addition/subtraction as:
+
+```
+let add = x.saturating_add(y);
+let sub = x.saturating_sub(y);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_split_once.txt b/src/tools/clippy/src/docs/manual_split_once.txt
new file mode 100644
index 000000000..291ae447d
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_split_once.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for usages of `str::splitn(2, _)`
+
+### Why is this bad?
+`split_once` is both clearer in intent and slightly more efficient.
+
+### Example
+```
+let s = "key=value=add";
+let (key, value) = s.splitn(2, '=').next_tuple()?;
+let value = s.splitn(2, '=').nth(1)?;
+
+let mut parts = s.splitn(2, '=');
+let key = parts.next()?;
+let value = parts.next()?;
+```
+
+Use instead:
+```
+let s = "key=value=add";
+let (key, value) = s.split_once('=')?;
+let value = s.split_once('=')?.1;
+
+let (key, value) = s.split_once('=')?;
+```
+
+### Limitations
+The multiple statement variant currently only detects `iter.next()?`/`iter.next().unwrap()`
+in two separate `let` statements that immediately follow the `splitn()` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_str_repeat.txt b/src/tools/clippy/src/docs/manual_str_repeat.txt
new file mode 100644
index 000000000..1d4a7a48e
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_str_repeat.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for manual implementations of `str::repeat`
+
+### Why is this bad?
+These are both harder to read, as well as less performant.
+
+### Example
+```
+let x: String = std::iter::repeat('x').take(10).collect();
+```
+
+Use instead:
+```
+let x: String = "x".repeat(10);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_string_new.txt b/src/tools/clippy/src/docs/manual_string_new.txt
new file mode 100644
index 000000000..4cbc43f8f
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_string_new.txt
@@ -0,0 +1,20 @@
+### What it does
+
+Checks for usage of `""` to create a `String`, such as `"".to_string()`, `"".to_owned()`,
+`String::from("")` and others.
+
+### Why is this bad?
+
+Different ways of creating an empty string makes your code less standardized, which can
+be confusing.
+
+### Example
+```
+let a = "".to_string();
+let b: String = "".into();
+```
+Use instead:
+```
+let a = String::new();
+let b = String::new();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_strip.txt b/src/tools/clippy/src/docs/manual_strip.txt
new file mode 100644
index 000000000..f32d8e7a0
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_strip.txt
@@ -0,0 +1,24 @@
+### What it does
+Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using
+the pattern's length.
+
+### Why is this bad?
+Using `str:strip_{prefix,suffix}` is safer and may have better performance as there is no
+slicing which may panic and the compiler does not need to insert this panic code. It is
+also sometimes more readable as it removes the need for duplicating or storing the pattern
+used by `str::{starts,ends}_with` and in the slicing.
+
+### Example
+```
+let s = "hello, world!";
+if s.starts_with("hello, ") {
+ assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
+}
+```
+Use instead:
+```
+let s = "hello, world!";
+if let Some(end) = s.strip_prefix("hello, ") {
+ assert_eq!(end.to_uppercase(), "WORLD!");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_swap.txt b/src/tools/clippy/src/docs/manual_swap.txt
new file mode 100644
index 000000000..bd9526288
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_swap.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for manual swapping.
+
+### Why is this bad?
+The `std::mem::swap` function exposes the intent better
+without deinitializing or copying either variable.
+
+### Example
+```
+let mut a = 42;
+let mut b = 1337;
+
+let t = b;
+b = a;
+a = t;
+```
+Use std::mem::swap():
+```
+let mut a = 1;
+let mut b = 2;
+std::mem::swap(&mut a, &mut b);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_unwrap_or.txt b/src/tools/clippy/src/docs/manual_unwrap_or.txt
new file mode 100644
index 000000000..1fd7d831b
--- /dev/null
+++ b/src/tools/clippy/src/docs/manual_unwrap_or.txt
@@ -0,0 +1,20 @@
+### What it does
+Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`.
+
+### Why is this bad?
+Concise code helps focusing on behavior instead of boilerplate.
+
+### Example
+```
+let foo: Option<i32> = None;
+match foo {
+ Some(v) => v,
+ None => 1,
+};
+```
+
+Use instead:
+```
+let foo: Option<i32> = None;
+foo.unwrap_or(1);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/many_single_char_names.txt b/src/tools/clippy/src/docs/many_single_char_names.txt
new file mode 100644
index 000000000..55ee5da55
--- /dev/null
+++ b/src/tools/clippy/src/docs/many_single_char_names.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for too many variables whose name consists of a
+single character.
+
+### Why is this bad?
+It's hard to memorize what a variable means without a
+descriptive name.
+
+### Example
+```
+let (a, b, c, d, e, f, g) = (...);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_clone.txt b/src/tools/clippy/src/docs/map_clone.txt
new file mode 100644
index 000000000..3ee27f072
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_clone.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usage of `map(|x| x.clone())` or
+dereferencing closures for `Copy` types, on `Iterator` or `Option`,
+and suggests `cloned()` or `copied()` instead
+
+### Why is this bad?
+Readability, this can be written more concisely
+
+### Example
+```
+let x = vec![42, 43];
+let y = x.iter();
+let z = y.map(|i| *i);
+```
+
+The correct use would be:
+
+```
+let x = vec![42, 43];
+let y = x.iter();
+let z = y.cloned();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_collect_result_unit.txt b/src/tools/clippy/src/docs/map_collect_result_unit.txt
new file mode 100644
index 000000000..9b7206124
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_collect_result_unit.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for usage of `_.map(_).collect::<Result<(), _>()`.
+
+### Why is this bad?
+Using `try_for_each` instead is more readable and idiomatic.
+
+### Example
+```
+(0..3).map(|t| Err(t)).collect::<Result<(), _>>();
+```
+Use instead:
+```
+(0..3).try_for_each(|t| Err(t));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_entry.txt b/src/tools/clippy/src/docs/map_entry.txt
new file mode 100644
index 000000000..20dba1798
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_entry.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for uses of `contains_key` + `insert` on `HashMap`
+or `BTreeMap`.
+
+### Why is this bad?
+Using `entry` is more efficient.
+
+### Known problems
+The suggestion may have type inference errors in some cases. e.g.
+```
+let mut map = std::collections::HashMap::new();
+let _ = if !map.contains_key(&0) {
+ map.insert(0, 0)
+} else {
+ None
+};
+```
+
+### Example
+```
+if !map.contains_key(&k) {
+ map.insert(k, v);
+}
+```
+Use instead:
+```
+map.entry(k).or_insert(v);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_err_ignore.txt b/src/tools/clippy/src/docs/map_err_ignore.txt
new file mode 100644
index 000000000..2606c13a7
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_err_ignore.txt
@@ -0,0 +1,93 @@
+### What it does
+Checks for instances of `map_err(|_| Some::Enum)`
+
+### Why is this bad?
+This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error
+
+### Example
+Before:
+```
+use std::fmt;
+
+#[derive(Debug)]
+enum Error {
+ Indivisible,
+ Remainder(u8),
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Error::Indivisible => write!(f, "could not divide input by three"),
+ Error::Remainder(remainder) => write!(
+ f,
+ "input is not divisible by three, remainder = {}",
+ remainder
+ ),
+ }
+ }
+}
+
+impl std::error::Error for Error {}
+
+fn divisible_by_3(input: &str) -> Result<(), Error> {
+ input
+ .parse::<i32>()
+ .map_err(|_| Error::Indivisible)
+ .map(|v| v % 3)
+ .and_then(|remainder| {
+ if remainder == 0 {
+ Ok(())
+ } else {
+ Err(Error::Remainder(remainder as u8))
+ }
+ })
+}
+ ```
+
+ After:
+ ```rust
+use std::{fmt, num::ParseIntError};
+
+#[derive(Debug)]
+enum Error {
+ Indivisible(ParseIntError),
+ Remainder(u8),
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Error::Indivisible(_) => write!(f, "could not divide input by three"),
+ Error::Remainder(remainder) => write!(
+ f,
+ "input is not divisible by three, remainder = {}",
+ remainder
+ ),
+ }
+ }
+}
+
+impl std::error::Error for Error {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Error::Indivisible(source) => Some(source),
+ _ => None,
+ }
+ }
+}
+
+fn divisible_by_3(input: &str) -> Result<(), Error> {
+ input
+ .parse::<i32>()
+ .map_err(Error::Indivisible)
+ .map(|v| v % 3)
+ .and_then(|remainder| {
+ if remainder == 0 {
+ Ok(())
+ } else {
+ Err(Error::Remainder(remainder as u8))
+ }
+ })
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_flatten.txt b/src/tools/clippy/src/docs/map_flatten.txt
new file mode 100644
index 000000000..73c0e5140
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_flatten.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.flat_map(_)` for `Iterator` or `_.and_then(_)` for `Option`
+
+### Example
+```
+let vec = vec![vec![1]];
+let opt = Some(5);
+
+vec.iter().map(|x| x.iter()).flatten();
+opt.map(|x| Some(x * 2)).flatten();
+```
+
+Use instead:
+```
+vec.iter().flat_map(|x| x.iter());
+opt.and_then(|x| Some(x * 2));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_identity.txt b/src/tools/clippy/src/docs/map_identity.txt
new file mode 100644
index 000000000..e2e7af0be
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_identity.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for instances of `map(f)` where `f` is the identity function.
+
+### Why is this bad?
+It can be written more concisely without the call to `map`.
+
+### Example
+```
+let x = [1, 2, 3];
+let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
+```
+Use instead:
+```
+let x = [1, 2, 3];
+let y: Vec<_> = x.iter().map(|x| 2*x).collect();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_unwrap_or.txt b/src/tools/clippy/src/docs/map_unwrap_or.txt
new file mode 100644
index 000000000..485b29f01
--- /dev/null
+++ b/src/tools/clippy/src/docs/map_unwrap_or.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or
+`result.map(_).unwrap_or_else(_)`.
+
+### Why is this bad?
+Readability, these can be written more concisely (resp.) as
+`option.map_or(_, _)`, `option.map_or_else(_, _)` and `result.map_or_else(_, _)`.
+
+### Known problems
+The order of the arguments is not in execution order
+
+### Examples
+```
+option.map(|a| a + 1).unwrap_or(0);
+result.map(|a| a + 1).unwrap_or_else(some_function);
+```
+
+Use instead:
+```
+option.map_or(0, |a| a + 1);
+result.map_or_else(some_function, |a| a + 1);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_as_ref.txt b/src/tools/clippy/src/docs/match_as_ref.txt
new file mode 100644
index 000000000..5e5f3d645
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_as_ref.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for match which is used to add a reference to an
+`Option` value.
+
+### Why is this bad?
+Using `as_ref()` or `as_mut()` instead is shorter.
+
+### Example
+```
+let x: Option<()> = None;
+
+let r: Option<&()> = match x {
+ None => None,
+ Some(ref v) => Some(v),
+};
+```
+
+Use instead:
+```
+let x: Option<()> = None;
+
+let r: Option<&()> = x.as_ref();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_bool.txt b/src/tools/clippy/src/docs/match_bool.txt
new file mode 100644
index 000000000..96f9e1f8b
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_bool.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for matches where match expression is a `bool`. It
+suggests to replace the expression with an `if...else` block.
+
+### Why is this bad?
+It makes the code less readable.
+
+### Example
+```
+let condition: bool = true;
+match condition {
+ true => foo(),
+ false => bar(),
+}
+```
+Use if/else instead:
+```
+let condition: bool = true;
+if condition {
+ foo();
+} else {
+ bar();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_like_matches_macro.txt b/src/tools/clippy/src/docs/match_like_matches_macro.txt
new file mode 100644
index 000000000..643e2ddc9
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_like_matches_macro.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for `match` or `if let` expressions producing a
+`bool` that could be written using `matches!`
+
+### Why is this bad?
+Readability and needless complexity.
+
+### Known problems
+This lint falsely triggers, if there are arms with
+`cfg` attributes that remove an arm evaluating to `false`.
+
+### Example
+```
+let x = Some(5);
+
+let a = match x {
+ Some(0) => true,
+ _ => false,
+};
+
+let a = if let Some(0) = x {
+ true
+} else {
+ false
+};
+```
+
+Use instead:
+```
+let x = Some(5);
+let a = matches!(x, Some(0));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_on_vec_items.txt b/src/tools/clippy/src/docs/match_on_vec_items.txt
new file mode 100644
index 000000000..981d18d0f
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_on_vec_items.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for `match vec[idx]` or `match vec[n..m]`.
+
+### Why is this bad?
+This can panic at runtime.
+
+### Example
+```
+let arr = vec![0, 1, 2, 3];
+let idx = 1;
+
+match arr[idx] {
+ 0 => println!("{}", 0),
+ 1 => println!("{}", 3),
+ _ => {},
+}
+```
+
+Use instead:
+```
+let arr = vec![0, 1, 2, 3];
+let idx = 1;
+
+match arr.get(idx) {
+ Some(0) => println!("{}", 0),
+ Some(1) => println!("{}", 3),
+ _ => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_overlapping_arm.txt b/src/tools/clippy/src/docs/match_overlapping_arm.txt
new file mode 100644
index 000000000..841c091bd
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_overlapping_arm.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for overlapping match arms.
+
+### Why is this bad?
+It is likely to be an error and if not, makes the code
+less obvious.
+
+### Example
+```
+let x = 5;
+match x {
+ 1..=10 => println!("1 ... 10"),
+ 5..=15 => println!("5 ... 15"),
+ _ => (),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_ref_pats.txt b/src/tools/clippy/src/docs/match_ref_pats.txt
new file mode 100644
index 000000000..b1d902995
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_ref_pats.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for matches where all arms match a reference,
+suggesting to remove the reference and deref the matched expression
+instead. It also checks for `if let &foo = bar` blocks.
+
+### Why is this bad?
+It just makes the code less readable. That reference
+destructuring adds nothing to the code.
+
+### Example
+```
+match x {
+ &A(ref y) => foo(y),
+ &B => bar(),
+ _ => frob(&x),
+}
+```
+
+Use instead:
+```
+match *x {
+ A(ref y) => foo(y),
+ B => bar(),
+ _ => frob(x),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_result_ok.txt b/src/tools/clippy/src/docs/match_result_ok.txt
new file mode 100644
index 000000000..eea7c8e00
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_result_ok.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for unnecessary `ok()` in `while let`.
+
+### Why is this bad?
+Calling `ok()` in `while let` is unnecessary, instead match
+on `Ok(pat)`
+
+### Example
+```
+while let Some(value) = iter.next().ok() {
+ vec.push(value)
+}
+
+if let Some(value) = iter.next().ok() {
+ vec.push(value)
+}
+```
+Use instead:
+```
+while let Ok(value) = iter.next() {
+ vec.push(value)
+}
+
+if let Ok(value) = iter.next() {
+ vec.push(value)
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_same_arms.txt b/src/tools/clippy/src/docs/match_same_arms.txt
new file mode 100644
index 000000000..14edf1203
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_same_arms.txt
@@ -0,0 +1,38 @@
+### What it does
+Checks for `match` with identical arm bodies.
+
+### Why is this bad?
+This is probably a copy & paste error. If arm bodies
+are the same on purpose, you can factor them
+[using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).
+
+### Known problems
+False positive possible with order dependent `match`
+(see issue
+[#860](https://github.com/rust-lang/rust-clippy/issues/860)).
+
+### Example
+```
+match foo {
+ Bar => bar(),
+ Quz => quz(),
+ Baz => bar(), // <= oops
+}
+```
+
+This should probably be
+```
+match foo {
+ Bar => bar(),
+ Quz => quz(),
+ Baz => baz(), // <= fixed
+}
+```
+
+or if the original code was not a typo:
+```
+match foo {
+ Bar | Baz => bar(), // <= shows the intent better
+ Quz => quz(),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_single_binding.txt b/src/tools/clippy/src/docs/match_single_binding.txt
new file mode 100644
index 000000000..67ded0bbd
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_single_binding.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for useless match that binds to only one value.
+
+### Why is this bad?
+Readability and needless complexity.
+
+### Known problems
+ Suggested replacements may be incorrect when `match`
+is actually binding temporary value, bringing a 'dropped while borrowed' error.
+
+### Example
+```
+match (a, b) {
+ (c, d) => {
+ // useless match
+ }
+}
+```
+
+Use instead:
+```
+let (c, d) = (a, b);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_str_case_mismatch.txt b/src/tools/clippy/src/docs/match_str_case_mismatch.txt
new file mode 100644
index 000000000..19e74c208
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_str_case_mismatch.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for `match` expressions modifying the case of a string with non-compliant arms
+
+### Why is this bad?
+The arm is unreachable, which is likely a mistake
+
+### Example
+```
+match &*text.to_ascii_lowercase() {
+ "foo" => {},
+ "Bar" => {},
+ _ => {},
+}
+```
+Use instead:
+```
+match &*text.to_ascii_lowercase() {
+ "foo" => {},
+ "bar" => {},
+ _ => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_wild_err_arm.txt b/src/tools/clippy/src/docs/match_wild_err_arm.txt
new file mode 100644
index 000000000..f89b3a23a
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_wild_err_arm.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for arm which matches all errors with `Err(_)`
+and take drastic actions like `panic!`.
+
+### Why is this bad?
+It is generally a bad practice, similar to
+catching all exceptions in java with `catch(Exception)`
+
+### Example
+```
+let x: Result<i32, &str> = Ok(3);
+match x {
+ Ok(_) => println!("ok"),
+ Err(_) => panic!("err"),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt b/src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt
new file mode 100644
index 000000000..25559b9ec
--- /dev/null
+++ b/src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for wildcard enum matches for a single variant.
+
+### Why is this bad?
+New enum variants added by library updates can be missed.
+
+### Known problems
+Suggested replacements may not use correct path to enum
+if it's not present in the current scope.
+
+### Example
+```
+match x {
+ Foo::A => {},
+ Foo::B => {},
+ _ => {},
+}
+```
+
+Use instead:
+```
+match x {
+ Foo::A => {},
+ Foo::B => {},
+ Foo::C => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/maybe_infinite_iter.txt b/src/tools/clippy/src/docs/maybe_infinite_iter.txt
new file mode 100644
index 000000000..1204a49b4
--- /dev/null
+++ b/src/tools/clippy/src/docs/maybe_infinite_iter.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for iteration that may be infinite.
+
+### Why is this bad?
+While there may be places where this is acceptable
+(e.g., in event streams), in most cases this is simply an error.
+
+### Known problems
+The code may have a condition to stop iteration, but
+this lint is not clever enough to analyze it.
+
+### Example
+```
+let infinite_iter = 0..;
+[0..].iter().zip(infinite_iter.take_while(|x| *x > 5));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_forget.txt b/src/tools/clippy/src/docs/mem_forget.txt
new file mode 100644
index 000000000..a6888c48f
--- /dev/null
+++ b/src/tools/clippy/src/docs/mem_forget.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for usage of `std::mem::forget(t)` where `t` is
+`Drop`.
+
+### Why is this bad?
+`std::mem::forget(t)` prevents `t` from running its
+destructor, possibly causing leaks.
+
+### Example
+```
+mem::forget(Rc::new(55))
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_replace_option_with_none.txt b/src/tools/clippy/src/docs/mem_replace_option_with_none.txt
new file mode 100644
index 000000000..7f243d1c1
--- /dev/null
+++ b/src/tools/clippy/src/docs/mem_replace_option_with_none.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for `mem::replace()` on an `Option` with
+`None`.
+
+### Why is this bad?
+`Option` already has the method `take()` for
+taking its current value (Some(..) or None) and replacing it with
+`None`.
+
+### Example
+```
+use std::mem;
+
+let mut an_option = Some(0);
+let replaced = mem::replace(&mut an_option, None);
+```
+Is better expressed with:
+```
+let mut an_option = Some(0);
+let taken = an_option.take();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_replace_with_default.txt b/src/tools/clippy/src/docs/mem_replace_with_default.txt
new file mode 100644
index 000000000..24e0913a3
--- /dev/null
+++ b/src/tools/clippy/src/docs/mem_replace_with_default.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for `std::mem::replace` on a value of type
+`T` with `T::default()`.
+
+### Why is this bad?
+`std::mem` module already has the method `take` to
+take the current value and replace it with the default value of that type.
+
+### Example
+```
+let mut text = String::from("foo");
+let replaced = std::mem::replace(&mut text, String::default());
+```
+Is better expressed with:
+```
+let mut text = String::from("foo");
+let taken = std::mem::take(&mut text);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_replace_with_uninit.txt b/src/tools/clippy/src/docs/mem_replace_with_uninit.txt
new file mode 100644
index 000000000..0bb483668
--- /dev/null
+++ b/src/tools/clippy/src/docs/mem_replace_with_uninit.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for `mem::replace(&mut _, mem::uninitialized())`
+and `mem::replace(&mut _, mem::zeroed())`.
+
+### Why is this bad?
+This will lead to undefined behavior even if the
+value is overwritten later, because the uninitialized value may be
+observed in the case of a panic.
+
+### Example
+```
+use std::mem;
+
+#[allow(deprecated, invalid_value)]
+fn myfunc (v: &mut Vec<i32>) {
+ let taken_v = unsafe { mem::replace(v, mem::uninitialized()) };
+ let new_v = may_panic(taken_v); // undefined behavior on panic
+ mem::forget(mem::replace(v, new_v));
+}
+```
+
+The [take_mut](https://docs.rs/take_mut) crate offers a sound solution,
+at the cost of either lazily creating a replacement value or aborting
+on panic, to ensure that the uninitialized value cannot be observed. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/min_max.txt b/src/tools/clippy/src/docs/min_max.txt
new file mode 100644
index 000000000..6acf0f932
--- /dev/null
+++ b/src/tools/clippy/src/docs/min_max.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for expressions where `std::cmp::min` and `max` are
+used to clamp values, but switched so that the result is constant.
+
+### Why is this bad?
+This is in all probability not the intended outcome. At
+the least it hurts readability of the code.
+
+### Example
+```
+min(0, max(100, x))
+
+// or
+
+x.max(100).min(0)
+```
+It will always be equal to `0`. Probably the author meant to clamp the value
+between 0 and 100, but has erroneously swapped `min` and `max`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mismatched_target_os.txt b/src/tools/clippy/src/docs/mismatched_target_os.txt
new file mode 100644
index 000000000..51e5ec6e7
--- /dev/null
+++ b/src/tools/clippy/src/docs/mismatched_target_os.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for cfg attributes having operating systems used in target family position.
+
+### Why is this bad?
+The configuration option will not be recognised and the related item will not be included
+by the conditional compilation engine.
+
+### Example
+```
+#[cfg(linux)]
+fn conditional() { }
+```
+
+Use instead:
+```
+#[cfg(target_os = "linux")]
+fn conditional() { }
+
+// or
+
+#[cfg(unix)]
+fn conditional() { }
+```
+Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mismatching_type_param_order.txt b/src/tools/clippy/src/docs/mismatching_type_param_order.txt
new file mode 100644
index 000000000..ffc7f32d0
--- /dev/null
+++ b/src/tools/clippy/src/docs/mismatching_type_param_order.txt
@@ -0,0 +1,33 @@
+### What it does
+Checks for type parameters which are positioned inconsistently between
+a type definition and impl block. Specifically, a parameter in an impl
+block which has the same name as a parameter in the type def, but is in
+a different place.
+
+### Why is this bad?
+Type parameters are determined by their position rather than name.
+Naming type parameters inconsistently may cause you to refer to the
+wrong type parameter.
+
+### Limitations
+This lint only applies to impl blocks with simple generic params, e.g.
+`A`. If there is anything more complicated, such as a tuple, it will be
+ignored.
+
+### Example
+```
+struct Foo<A, B> {
+ x: A,
+ y: B,
+}
+// inside the impl, B refers to Foo::A
+impl<B, A> Foo<B, A> {}
+```
+Use instead:
+```
+struct Foo<A, B> {
+ x: A,
+ y: B,
+}
+impl<A, B> Foo<A, B> {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/misrefactored_assign_op.txt b/src/tools/clippy/src/docs/misrefactored_assign_op.txt
new file mode 100644
index 000000000..3d691fe41
--- /dev/null
+++ b/src/tools/clippy/src/docs/misrefactored_assign_op.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for `a op= a op b` or `a op= b op a` patterns.
+
+### Why is this bad?
+Most likely these are bugs where one meant to write `a
+op= b`.
+
+### Known problems
+Clippy cannot know for sure if `a op= a op b` should have
+been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.
+If `a op= a op b` is really the correct behavior it should be
+written as `a = a op a op b` as it's less confusing.
+
+### Example
+```
+let mut a = 5;
+let b = 2;
+// ...
+a += a + b;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_const_for_fn.txt b/src/tools/clippy/src/docs/missing_const_for_fn.txt
new file mode 100644
index 000000000..067614d4c
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_const_for_fn.txt
@@ -0,0 +1,40 @@
+### What it does
+Suggests the use of `const` in functions and methods where possible.
+
+### Why is this bad?
+Not having the function const prevents callers of the function from being const as well.
+
+### Known problems
+Const functions are currently still being worked on, with some features only being available
+on nightly. This lint does not consider all edge cases currently and the suggestions may be
+incorrect if you are using this lint on stable.
+
+Also, the lint only runs one pass over the code. Consider these two non-const functions:
+
+```
+fn a() -> i32 {
+ 0
+}
+fn b() -> i32 {
+ a()
+}
+```
+
+When running Clippy, the lint will only suggest to make `a` const, because `b` at this time
+can't be const as it calls a non-const function. Making `a` const and running Clippy again,
+will suggest to make `b` const, too.
+
+### Example
+```
+fn new() -> Self {
+ Self { random_number: 42 }
+}
+```
+
+Could be a const fn:
+
+```
+const fn new() -> Self {
+ Self { random_number: 42 }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_docs_in_private_items.txt b/src/tools/clippy/src/docs/missing_docs_in_private_items.txt
new file mode 100644
index 000000000..5d37505bb
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_docs_in_private_items.txt
@@ -0,0 +1,9 @@
+### What it does
+Warns if there is missing doc for any documentable item
+(public or private).
+
+### Why is this bad?
+Doc is good. *rustc* has a `MISSING_DOCS`
+allowed-by-default lint for
+public members, but has no way to enforce documentation of private items.
+This lint fixes that. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_enforced_import_renames.txt b/src/tools/clippy/src/docs/missing_enforced_import_renames.txt
new file mode 100644
index 000000000..8f4649bd5
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_enforced_import_renames.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for imports that do not rename the item as specified
+in the `enforce-import-renames` config option.
+
+### Why is this bad?
+Consistency is important, if a project has defined import
+renames they should be followed. More practically, some item names are too
+vague outside of their defining scope this can enforce a more meaningful naming.
+
+### Example
+An example clippy.toml configuration:
+```
+enforced-import-renames = [ { path = "serde_json::Value", rename = "JsonValue" }]
+```
+
+```
+use serde_json::Value;
+```
+Use instead:
+```
+use serde_json::Value as JsonValue;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_errors_doc.txt b/src/tools/clippy/src/docs/missing_errors_doc.txt
new file mode 100644
index 000000000..028778d85
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_errors_doc.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks the doc comments of publicly visible functions that
+return a `Result` type and warns if there is no `# Errors` section.
+
+### Why is this bad?
+Documenting the type of errors that can be returned from a
+function can help callers write code to handle the errors appropriately.
+
+### Examples
+Since the following function returns a `Result` it has an `# Errors` section in
+its doc comment:
+
+```
+/// # Errors
+///
+/// Will return `Err` if `filename` does not exist or the user does not have
+/// permission to read it.
+pub fn read(filename: String) -> io::Result<String> {
+ unimplemented!();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_inline_in_public_items.txt b/src/tools/clippy/src/docs/missing_inline_in_public_items.txt
new file mode 100644
index 000000000..d90c50fe7
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_inline_in_public_items.txt
@@ -0,0 +1,45 @@
+### What it does
+It lints if an exported function, method, trait method with default impl,
+or trait method impl is not `#[inline]`.
+
+### Why is this bad?
+In general, it is not. Functions can be inlined across
+crates when that's profitable as long as any form of LTO is used. When LTO is disabled,
+functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates
+might intend for most of the methods in their public API to be able to be inlined across
+crates even when LTO is disabled. For these types of crates, enabling this lint might make
+sense. It allows the crate to require all exported methods to be `#[inline]` by default, and
+then opt out for specific methods where this might not make sense.
+
+### Example
+```
+pub fn foo() {} // missing #[inline]
+fn ok() {} // ok
+#[inline] pub fn bar() {} // ok
+#[inline(always)] pub fn baz() {} // ok
+
+pub trait Bar {
+ fn bar(); // ok
+ fn def_bar() {} // missing #[inline]
+}
+
+struct Baz;
+impl Baz {
+ fn private() {} // ok
+}
+
+impl Bar for Baz {
+ fn bar() {} // ok - Baz is not exported
+}
+
+pub struct PubBaz;
+impl PubBaz {
+ fn private() {} // ok
+ pub fn not_private() {} // missing #[inline]
+}
+
+impl Bar for PubBaz {
+ fn bar() {} // missing #[inline]
+ fn def_bar() {} // missing #[inline]
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_panics_doc.txt b/src/tools/clippy/src/docs/missing_panics_doc.txt
new file mode 100644
index 000000000..e5e39a824
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_panics_doc.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks the doc comments of publicly visible functions that
+may panic and warns if there is no `# Panics` section.
+
+### Why is this bad?
+Documenting the scenarios in which panicking occurs
+can help callers who do not want to panic to avoid those situations.
+
+### Examples
+Since the following function may panic it has a `# Panics` section in
+its doc comment:
+
+```
+/// # Panics
+///
+/// Will panic if y is 0
+pub fn divide_by(x: i32, y: i32) -> i32 {
+ if y == 0 {
+ panic!("Cannot divide by 0")
+ } else {
+ x / y
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_safety_doc.txt b/src/tools/clippy/src/docs/missing_safety_doc.txt
new file mode 100644
index 000000000..6492eb84f
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_safety_doc.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for the doc comments of publicly visible
+unsafe functions and warns if there is no `# Safety` section.
+
+### Why is this bad?
+Unsafe functions should document their safety
+preconditions, so that users can be sure they are using them safely.
+
+### Examples
+```
+/// This function should really be documented
+pub unsafe fn start_apocalypse(u: &mut Universe) {
+ unimplemented!();
+}
+```
+
+At least write a line about safety:
+
+```
+/// # Safety
+///
+/// This function should not be called before the horsemen are ready.
+pub unsafe fn start_apocalypse(u: &mut Universe) {
+ unimplemented!();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_spin_loop.txt b/src/tools/clippy/src/docs/missing_spin_loop.txt
new file mode 100644
index 000000000..3a06a91d7
--- /dev/null
+++ b/src/tools/clippy/src/docs/missing_spin_loop.txt
@@ -0,0 +1,27 @@
+### What it does
+Check for empty spin loops
+
+### Why is this bad?
+The loop body should have something like `thread::park()` or at least
+`std::hint::spin_loop()` to avoid needlessly burning cycles and conserve
+energy. Perhaps even better use an actual lock, if possible.
+
+### Known problems
+This lint doesn't currently trigger on `while let` or
+`loop { match .. { .. } }` loops, which would be considered idiomatic in
+combination with e.g. `AtomicBool::compare_exchange_weak`.
+
+### Example
+
+```
+use core::sync::atomic::{AtomicBool, Ordering};
+let b = AtomicBool::new(true);
+// give a ref to `b` to another thread,wait for it to become false
+while b.load(Ordering::Acquire) {};
+```
+Use instead:
+```
+while b.load(Ordering::Acquire) {
+ std::hint::spin_loop()
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mistyped_literal_suffixes.txt b/src/tools/clippy/src/docs/mistyped_literal_suffixes.txt
new file mode 100644
index 000000000..1760fcbfe
--- /dev/null
+++ b/src/tools/clippy/src/docs/mistyped_literal_suffixes.txt
@@ -0,0 +1,15 @@
+### What it does
+Warns for mistyped suffix in literals
+
+### Why is this bad?
+This is most probably a typo
+
+### Known problems
+- Does not match on integers too large to fit in the corresponding unsigned type
+- Does not match on `_127` since that is a valid grouping for decimal and octal numbers
+
+### Example
+```
+`2_32` => `2_i32`
+`250_8 => `250_u8`
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mixed_case_hex_literals.txt b/src/tools/clippy/src/docs/mixed_case_hex_literals.txt
new file mode 100644
index 000000000..d2d01e0c9
--- /dev/null
+++ b/src/tools/clippy/src/docs/mixed_case_hex_literals.txt
@@ -0,0 +1,16 @@
+### What it does
+Warns on hexadecimal literals with mixed-case letter
+digits.
+
+### Why is this bad?
+It looks confusing.
+
+### Example
+```
+0x1a9BAcD
+```
+
+Use instead:
+```
+0x1A9BACD
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mixed_read_write_in_expression.txt b/src/tools/clippy/src/docs/mixed_read_write_in_expression.txt
new file mode 100644
index 000000000..02d1c5d05
--- /dev/null
+++ b/src/tools/clippy/src/docs/mixed_read_write_in_expression.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for a read and a write to the same variable where
+whether the read occurs before or after the write depends on the evaluation
+order of sub-expressions.
+
+### Why is this bad?
+It is often confusing to read. As described [here](https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands),
+the operands of these expressions are evaluated before applying the effects of the expression.
+
+### Known problems
+Code which intentionally depends on the evaluation
+order, or which is correct for any evaluation order.
+
+### Example
+```
+let mut x = 0;
+
+let a = {
+ x = 1;
+ 1
+} + x;
+// Unclear whether a is 1 or 2.
+```
+
+Use instead:
+```
+let tmp = {
+ x = 1;
+ 1
+};
+let a = tmp + x;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mod_module_files.txt b/src/tools/clippy/src/docs/mod_module_files.txt
new file mode 100644
index 000000000..95bca583a
--- /dev/null
+++ b/src/tools/clippy/src/docs/mod_module_files.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks that module layout uses only self named module files, bans `mod.rs` files.
+
+### Why is this bad?
+Having multiple module layout styles in a project can be confusing.
+
+### Example
+```
+src/
+ stuff/
+ stuff_files.rs
+ mod.rs
+ lib.rs
+```
+Use instead:
+```
+src/
+ stuff/
+ stuff_files.rs
+ stuff.rs
+ lib.rs
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/module_inception.txt b/src/tools/clippy/src/docs/module_inception.txt
new file mode 100644
index 000000000..d80a1b8d8
--- /dev/null
+++ b/src/tools/clippy/src/docs/module_inception.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for modules that have the same name as their
+parent module
+
+### Why is this bad?
+A typical beginner mistake is to have `mod foo;` and
+again `mod foo { ..
+}` in `foo.rs`.
+The expectation is that items inside the inner `mod foo { .. }` are then
+available
+through `foo::x`, but they are only available through
+`foo::foo::x`.
+If this is done on purpose, it would be better to choose a more
+representative module name.
+
+### Example
+```
+// lib.rs
+mod foo;
+// foo.rs
+mod foo {
+ ...
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/module_name_repetitions.txt b/src/tools/clippy/src/docs/module_name_repetitions.txt
new file mode 100644
index 000000000..3bc05d027
--- /dev/null
+++ b/src/tools/clippy/src/docs/module_name_repetitions.txt
@@ -0,0 +1,20 @@
+### What it does
+Detects type names that are prefixed or suffixed by the
+containing module's name.
+
+### Why is this bad?
+It requires the user to type the module name twice.
+
+### Example
+```
+mod cake {
+ struct BlackForestCake;
+}
+```
+
+Use instead:
+```
+mod cake {
+ struct BlackForest;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/modulo_arithmetic.txt b/src/tools/clippy/src/docs/modulo_arithmetic.txt
new file mode 100644
index 000000000..ff7296f3c
--- /dev/null
+++ b/src/tools/clippy/src/docs/modulo_arithmetic.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for modulo arithmetic.
+
+### Why is this bad?
+The results of modulo (%) operation might differ
+depending on the language, when negative numbers are involved.
+If you interop with different languages it might be beneficial
+to double check all places that use modulo arithmetic.
+
+For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.
+
+### Example
+```
+let x = -17 % 3;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/modulo_one.txt b/src/tools/clippy/src/docs/modulo_one.txt
new file mode 100644
index 000000000..bc8f95b0b
--- /dev/null
+++ b/src/tools/clippy/src/docs/modulo_one.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for getting the remainder of a division by one or minus
+one.
+
+### Why is this bad?
+The result for a divisor of one can only ever be zero; for
+minus one it can cause panic/overflow (if the left operand is the minimal value of
+the respective integer type) or results in zero. No one will write such code
+deliberately, unless trying to win an Underhanded Rust Contest. Even for that
+contest, it's probably a bad idea. Use something more underhanded.
+
+### Example
+```
+let a = x % 1;
+let a = x % -1;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/multi_assignments.txt b/src/tools/clippy/src/docs/multi_assignments.txt
new file mode 100644
index 000000000..ed1f1b420
--- /dev/null
+++ b/src/tools/clippy/src/docs/multi_assignments.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for nested assignments.
+
+### Why is this bad?
+While this is in most cases already a type mismatch,
+the result of an assignment being `()` can throw off people coming from languages like python or C,
+where such assignments return a copy of the assigned value.
+
+### Example
+```
+a = b = 42;
+```
+Use instead:
+```
+b = 42;
+a = b;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/multiple_crate_versions.txt b/src/tools/clippy/src/docs/multiple_crate_versions.txt
new file mode 100644
index 000000000..cf2d2c6ab
--- /dev/null
+++ b/src/tools/clippy/src/docs/multiple_crate_versions.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks to see if multiple versions of a crate are being
+used.
+
+### Why is this bad?
+This bloats the size of targets, and can lead to
+confusing error messages when structs or traits are used interchangeably
+between different versions of a crate.
+
+### Known problems
+Because this can be caused purely by the dependencies
+themselves, it's not always possible to fix this issue.
+
+### Example
+```
+[dependencies]
+ctrlc = "=3.1.0"
+ansi_term = "=0.11.0"
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/multiple_inherent_impl.txt b/src/tools/clippy/src/docs/multiple_inherent_impl.txt
new file mode 100644
index 000000000..9d4228656
--- /dev/null
+++ b/src/tools/clippy/src/docs/multiple_inherent_impl.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for multiple inherent implementations of a struct
+
+### Why is this bad?
+Splitting the implementation of a type makes the code harder to navigate.
+
+### Example
+```
+struct X;
+impl X {
+ fn one() {}
+}
+impl X {
+ fn other() {}
+}
+```
+
+Could be written:
+
+```
+struct X;
+impl X {
+ fn one() {}
+ fn other() {}
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/must_use_candidate.txt b/src/tools/clippy/src/docs/must_use_candidate.txt
new file mode 100644
index 000000000..70890346f
--- /dev/null
+++ b/src/tools/clippy/src/docs/must_use_candidate.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for public functions that have no
+`#[must_use]` attribute, but return something not already marked
+must-use, have no mutable arg and mutate no statics.
+
+### Why is this bad?
+Not bad at all, this lint just shows places where
+you could add the attribute.
+
+### Known problems
+The lint only checks the arguments for mutable
+types without looking if they are actually changed. On the other hand,
+it also ignores a broad range of potentially interesting side effects,
+because we cannot decide whether the programmer intends the function to
+be called for the side effect or the result. Expect many false
+positives. At least we don't lint if the result type is unit or already
+`#[must_use]`.
+
+### Examples
+```
+// this could be annotated with `#[must_use]`.
+fn id<T>(t: T) -> T { t }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/must_use_unit.txt b/src/tools/clippy/src/docs/must_use_unit.txt
new file mode 100644
index 000000000..cabbb23f8
--- /dev/null
+++ b/src/tools/clippy/src/docs/must_use_unit.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for a `#[must_use]` attribute on
+unit-returning functions and methods.
+
+### Why is this bad?
+Unit values are useless. The attribute is likely
+a remnant of a refactoring that removed the return type.
+
+### Examples
+```
+#[must_use]
+fn useless() { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_from_ref.txt b/src/tools/clippy/src/docs/mut_from_ref.txt
new file mode 100644
index 000000000..cc1da1254
--- /dev/null
+++ b/src/tools/clippy/src/docs/mut_from_ref.txt
@@ -0,0 +1,26 @@
+### What it does
+This lint checks for functions that take immutable references and return
+mutable ones. This will not trigger if no unsafe code exists as there
+are multiple safe functions which will do this transformation
+
+To be on the conservative side, if there's at least one mutable
+reference with the output lifetime, this lint will not trigger.
+
+### Why is this bad?
+Creating a mutable reference which can be repeatably derived from an
+immutable reference is unsound as it allows creating multiple live
+mutable references to the same object.
+
+This [error](https://github.com/rust-lang/rust/issues/39465) actually
+lead to an interim Rust release 1.15.1.
+
+### Known problems
+This pattern is used by memory allocators to allow allocating multiple
+objects while returning mutable references to each one. So long as
+different mutable references are returned each time such a function may
+be safe.
+
+### Example
+```
+fn foo(&Foo) -> &mut Bar { .. }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_mut.txt b/src/tools/clippy/src/docs/mut_mut.txt
new file mode 100644
index 000000000..0bd34dd24
--- /dev/null
+++ b/src/tools/clippy/src/docs/mut_mut.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for instances of `mut mut` references.
+
+### Why is this bad?
+Multiple `mut`s don't add anything meaningful to the
+source. This is either a copy'n'paste error, or it shows a fundamental
+misunderstanding of references.
+
+### Example
+```
+let x = &mut &mut y;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_mutex_lock.txt b/src/tools/clippy/src/docs/mut_mutex_lock.txt
new file mode 100644
index 000000000..5e9ad8a3f
--- /dev/null
+++ b/src/tools/clippy/src/docs/mut_mutex_lock.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for `&mut Mutex::lock` calls
+
+### Why is this bad?
+`Mutex::lock` is less efficient than
+calling `Mutex::get_mut`. In addition you also have a statically
+guarantee that the mutex isn't locked, instead of just a runtime
+guarantee.
+
+### Example
+```
+use std::sync::{Arc, Mutex};
+
+let mut value_rc = Arc::new(Mutex::new(42_u8));
+let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
+
+let mut value = value_mutex.lock().unwrap();
+*value += 1;
+```
+Use instead:
+```
+use std::sync::{Arc, Mutex};
+
+let mut value_rc = Arc::new(Mutex::new(42_u8));
+let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
+
+let value = value_mutex.get_mut().unwrap();
+*value += 1;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_range_bound.txt b/src/tools/clippy/src/docs/mut_range_bound.txt
new file mode 100644
index 000000000..e9c38a543
--- /dev/null
+++ b/src/tools/clippy/src/docs/mut_range_bound.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for loops which have a range bound that is a mutable variable
+
+### Why is this bad?
+One might think that modifying the mutable variable changes the loop bounds
+
+### Known problems
+False positive when mutation is followed by a `break`, but the `break` is not immediately
+after the mutation:
+
+```
+let mut x = 5;
+for _ in 0..x {
+ x += 1; // x is a range bound that is mutated
+ ..; // some other expression
+ break; // leaves the loop, so mutation is not an issue
+}
+```
+
+False positive on nested loops ([#6072](https://github.com/rust-lang/rust-clippy/issues/6072))
+
+### Example
+```
+let mut foo = 42;
+for i in 0..foo {
+ foo -= 1;
+ println!("{}", i); // prints numbers from 0 to 42, not 0 to 21
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mutable_key_type.txt b/src/tools/clippy/src/docs/mutable_key_type.txt
new file mode 100644
index 000000000..15fe34f2b
--- /dev/null
+++ b/src/tools/clippy/src/docs/mutable_key_type.txt
@@ -0,0 +1,61 @@
+### What it does
+Checks for sets/maps with mutable key types.
+
+### Why is this bad?
+All of `HashMap`, `HashSet`, `BTreeMap` and
+`BtreeSet` rely on either the hash or the order of keys be unchanging,
+so having types with interior mutability is a bad idea.
+
+### Known problems
+
+#### False Positives
+It's correct to use a struct that contains interior mutability as a key, when its
+implementation of `Hash` or `Ord` doesn't access any of the interior mutable types.
+However, this lint is unable to recognize this, so it will often cause false positives in
+theses cases. The `bytes` crate is a great example of this.
+
+#### False Negatives
+For custom `struct`s/`enum`s, this lint is unable to check for interior mutability behind
+indirection. For example, `struct BadKey<'a>(&'a Cell<usize>)` will be seen as immutable
+and cause a false negative if its implementation of `Hash`/`Ord` accesses the `Cell`.
+
+This lint does check a few cases for indirection. Firstly, using some standard library
+types (`Option`, `Result`, `Box`, `Rc`, `Arc`, `Vec`, `VecDeque`, `BTreeMap` and
+`BTreeSet`) directly as keys (e.g. in `HashMap<Box<Cell<usize>>, ()>`) **will** trigger the
+lint, because the impls of `Hash`/`Ord` for these types directly call `Hash`/`Ord` on their
+contained type.
+
+Secondly, the implementations of `Hash` and `Ord` for raw pointers (`*const T` or `*mut T`)
+apply only to the **address** of the contained value. Therefore, interior mutability
+behind raw pointers (e.g. in `HashSet<*mut Cell<usize>>`) can't impact the value of `Hash`
+or `Ord`, and therefore will not trigger this link. For more info, see issue
+[#6745](https://github.com/rust-lang/rust-clippy/issues/6745).
+
+### Example
+```
+use std::cmp::{PartialEq, Eq};
+use std::collections::HashSet;
+use std::hash::{Hash, Hasher};
+use std::sync::atomic::AtomicUsize;
+
+struct Bad(AtomicUsize);
+impl PartialEq for Bad {
+ fn eq(&self, rhs: &Self) -> bool {
+ ..
+; unimplemented!();
+ }
+}
+
+impl Eq for Bad {}
+
+impl Hash for Bad {
+ fn hash<H: Hasher>(&self, h: &mut H) {
+ ..
+; unimplemented!();
+ }
+}
+
+fn main() {
+ let _: HashSet<Bad> = HashSet::new();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mutex_atomic.txt b/src/tools/clippy/src/docs/mutex_atomic.txt
new file mode 100644
index 000000000..062ac8b32
--- /dev/null
+++ b/src/tools/clippy/src/docs/mutex_atomic.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usages of `Mutex<X>` where an atomic will do.
+
+### Why is this bad?
+Using a mutex just to make access to a plain bool or
+reference sequential is shooting flies with cannons.
+`std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and
+faster.
+
+### Known problems
+This lint cannot detect if the mutex is actually used
+for waiting before a critical section.
+
+### Example
+```
+let x = Mutex::new(&y);
+```
+
+Use instead:
+```
+let x = AtomicBool::new(y);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mutex_integer.txt b/src/tools/clippy/src/docs/mutex_integer.txt
new file mode 100644
index 000000000..f9dbdfb90
--- /dev/null
+++ b/src/tools/clippy/src/docs/mutex_integer.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usages of `Mutex<X>` where `X` is an integral
+type.
+
+### Why is this bad?
+Using a mutex just to make access to a plain integer
+sequential is
+shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.
+
+### Known problems
+This lint cannot detect if the mutex is actually used
+for waiting before a critical section.
+
+### Example
+```
+let x = Mutex::new(0usize);
+```
+
+Use instead:
+```
+let x = AtomicUsize::new(0usize);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/naive_bytecount.txt b/src/tools/clippy/src/docs/naive_bytecount.txt
new file mode 100644
index 000000000..24659dc79
--- /dev/null
+++ b/src/tools/clippy/src/docs/naive_bytecount.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for naive byte counts
+
+### Why is this bad?
+The [`bytecount`](https://crates.io/crates/bytecount)
+crate has methods to count your bytes faster, especially for large slices.
+
+### Known problems
+If you have predominantly small slices, the
+`bytecount::count(..)` method may actually be slower. However, if you can
+ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
+faster in those cases.
+
+### Example
+```
+let count = vec.iter().filter(|x| **x == 0u8).count();
+```
+
+Use instead:
+```
+let count = bytecount::count(&vec, 0u8);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_arbitrary_self_type.txt b/src/tools/clippy/src/docs/needless_arbitrary_self_type.txt
new file mode 100644
index 000000000..8216a3a3f
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_arbitrary_self_type.txt
@@ -0,0 +1,44 @@
+### What it does
+The lint checks for `self` in fn parameters that
+specify the `Self`-type explicitly
+### Why is this bad?
+Increases the amount and decreases the readability of code
+
+### Example
+```
+enum ValType {
+ I32,
+ I64,
+ F32,
+ F64,
+}
+
+impl ValType {
+ pub fn bytes(self: Self) -> usize {
+ match self {
+ Self::I32 | Self::F32 => 4,
+ Self::I64 | Self::F64 => 8,
+ }
+ }
+}
+```
+
+Could be rewritten as
+
+```
+enum ValType {
+ I32,
+ I64,
+ F32,
+ F64,
+}
+
+impl ValType {
+ pub fn bytes(self) -> usize {
+ match self {
+ Self::I32 | Self::F32 => 4,
+ Self::I64 | Self::F64 => 8,
+ }
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_bitwise_bool.txt b/src/tools/clippy/src/docs/needless_bitwise_bool.txt
new file mode 100644
index 000000000..fcd7b730a
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_bitwise_bool.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using
+a lazy and.
+
+### Why is this bad?
+The bitwise operators do not support short-circuiting, so it may hinder code performance.
+Additionally, boolean logic "masked" as bitwise logic is not caught by lints like `unnecessary_fold`
+
+### Known problems
+This lint evaluates only when the right side is determined to have no side effects. At this time, that
+determination is quite conservative.
+
+### Example
+```
+let (x,y) = (true, false);
+if x & !y {} // where both x and y are booleans
+```
+Use instead:
+```
+let (x,y) = (true, false);
+if x && !y {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_bool.txt b/src/tools/clippy/src/docs/needless_bool.txt
new file mode 100644
index 000000000..b5c78871f
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_bool.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for expressions of the form `if c { true } else {
+false }` (or vice versa) and suggests using the condition directly.
+
+### Why is this bad?
+Redundant code.
+
+### Known problems
+Maybe false positives: Sometimes, the two branches are
+painstakingly documented (which we, of course, do not detect), so they *may*
+have some value. Even then, the documentation can be rewritten to match the
+shorter code.
+
+### Example
+```
+if x {
+ false
+} else {
+ true
+}
+```
+
+Use instead:
+```
+!x
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_borrow.txt b/src/tools/clippy/src/docs/needless_borrow.txt
new file mode 100644
index 000000000..4debcf473
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_borrow.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for address of operations (`&`) that are going to
+be dereferenced immediately by the compiler.
+
+### Why is this bad?
+Suggests that the receiver of the expression borrows
+the expression.
+
+### Example
+```
+fn fun(_a: &i32) {}
+
+let x: &i32 = &&&&&&5;
+fun(&x);
+```
+
+Use instead:
+```
+let x: &i32 = &5;
+fun(x);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_borrowed_reference.txt b/src/tools/clippy/src/docs/needless_borrowed_reference.txt
new file mode 100644
index 000000000..55faa0cf5
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_borrowed_reference.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for bindings that destructure a reference and borrow the inner
+value with `&ref`.
+
+### Why is this bad?
+This pattern has no effect in almost all cases.
+
+### Known problems
+In some cases, `&ref` is needed to avoid a lifetime mismatch error.
+Example:
+```
+fn foo(a: &Option<String>, b: &Option<String>) {
+ match (a, b) {
+ (None, &ref c) | (&ref c, None) => (),
+ (&Some(ref c), _) => (),
+ };
+}
+```
+
+### Example
+```
+let mut v = Vec::<String>::new();
+v.iter_mut().filter(|&ref a| a.is_empty());
+```
+
+Use instead:
+```
+let mut v = Vec::<String>::new();
+v.iter_mut().filter(|a| a.is_empty());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_collect.txt b/src/tools/clippy/src/docs/needless_collect.txt
new file mode 100644
index 000000000..275c39afc
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_collect.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for functions collecting an iterator when collect
+is not needed.
+
+### Why is this bad?
+`collect` causes the allocation of a new data structure,
+when this allocation may not be needed.
+
+### Example
+```
+let len = iterator.clone().collect::<Vec<_>>().len();
+// should be
+let len = iterator.count();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_continue.txt b/src/tools/clippy/src/docs/needless_continue.txt
new file mode 100644
index 000000000..2cee621c1
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_continue.txt
@@ -0,0 +1,61 @@
+### What it does
+The lint checks for `if`-statements appearing in loops
+that contain a `continue` statement in either their main blocks or their
+`else`-blocks, when omitting the `else`-block possibly with some
+rearrangement of code can make the code easier to understand.
+
+### Why is this bad?
+Having explicit `else` blocks for `if` statements
+containing `continue` in their THEN branch adds unnecessary branching and
+nesting to the code. Having an else block containing just `continue` can
+also be better written by grouping the statements following the whole `if`
+statement within the THEN block and omitting the else block completely.
+
+### Example
+```
+while condition() {
+ update_condition();
+ if x {
+ // ...
+ } else {
+ continue;
+ }
+ println!("Hello, world");
+}
+```
+
+Could be rewritten as
+
+```
+while condition() {
+ update_condition();
+ if x {
+ // ...
+ println!("Hello, world");
+ }
+}
+```
+
+As another example, the following code
+
+```
+loop {
+ if waiting() {
+ continue;
+ } else {
+ // Do something useful
+ }
+ # break;
+}
+```
+Could be rewritten as
+
+```
+loop {
+ if waiting() {
+ continue;
+ }
+ // Do something useful
+ # break;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_doctest_main.txt b/src/tools/clippy/src/docs/needless_doctest_main.txt
new file mode 100644
index 000000000..8f91a7baa
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_doctest_main.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for `fn main() { .. }` in doctests
+
+### Why is this bad?
+The test can be shorter (and likely more readable)
+if the `fn main()` is left implicit.
+
+### Examples
+```
+/// An example of a doctest with a `main()` function
+///
+/// # Examples
+///
+/// ```
+/// fn main() {
+/// // this needs not be in an `fn`
+/// }
+/// ```
+fn needless_main() {
+ unimplemented!();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_for_each.txt b/src/tools/clippy/src/docs/needless_for_each.txt
new file mode 100644
index 000000000..9ae6dd360
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_for_each.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for usage of `for_each` that would be more simply written as a
+`for` loop.
+
+### Why is this bad?
+`for_each` may be used after applying iterator transformers like
+`filter` for better readability and performance. It may also be used to fit a simple
+operation on one line.
+But when none of these apply, a simple `for` loop is more idiomatic.
+
+### Example
+```
+let v = vec![0, 1, 2];
+v.iter().for_each(|elem| {
+ println!("{}", elem);
+})
+```
+Use instead:
+```
+let v = vec![0, 1, 2];
+for elem in v.iter() {
+ println!("{}", elem);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_late_init.txt b/src/tools/clippy/src/docs/needless_late_init.txt
new file mode 100644
index 000000000..9e7bbcea9
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_late_init.txt
@@ -0,0 +1,42 @@
+### What it does
+Checks for late initializations that can be replaced by a `let` statement
+with an initializer.
+
+### Why is this bad?
+Assigning in the `let` statement is less repetitive.
+
+### Example
+```
+let a;
+a = 1;
+
+let b;
+match 3 {
+ 0 => b = "zero",
+ 1 => b = "one",
+ _ => b = "many",
+}
+
+let c;
+if true {
+ c = 1;
+} else {
+ c = -1;
+}
+```
+Use instead:
+```
+let a = 1;
+
+let b = match 3 {
+ 0 => "zero",
+ 1 => "one",
+ _ => "many",
+};
+
+let c = if true {
+ 1
+} else {
+ -1
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_lifetimes.txt b/src/tools/clippy/src/docs/needless_lifetimes.txt
new file mode 100644
index 000000000..b280caa66
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_lifetimes.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for lifetime annotations which can be removed by
+relying on lifetime elision.
+
+### Why is this bad?
+The additional lifetimes make the code look more
+complicated, while there is nothing out of the ordinary going on. Removing
+them leads to more readable code.
+
+### Known problems
+- We bail out if the function has a `where` clause where lifetimes
+are mentioned due to potential false positives.
+- Lifetime bounds such as `impl Foo + 'a` and `T: 'a` must be elided with the
+placeholder notation `'_` because the fully elided notation leaves the type bound to `'static`.
+
+### Example
+```
+// Unnecessary lifetime annotations
+fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {
+ x
+}
+```
+
+Use instead:
+```
+fn elided(x: &u8, y: u8) -> &u8 {
+ x
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_match.txt b/src/tools/clippy/src/docs/needless_match.txt
new file mode 100644
index 000000000..92b40a5df
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_match.txt
@@ -0,0 +1,36 @@
+### What it does
+Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result`
+when function signatures are the same.
+
+### Why is this bad?
+This `match` block does nothing and might not be what the coder intended.
+
+### Example
+```
+fn foo() -> Result<(), i32> {
+ match result {
+ Ok(val) => Ok(val),
+ Err(err) => Err(err),
+ }
+}
+
+fn bar() -> Option<i32> {
+ if let Some(val) = option {
+ Some(val)
+ } else {
+ None
+ }
+}
+```
+
+Could be replaced as
+
+```
+fn foo() -> Result<(), i32> {
+ result
+}
+
+fn bar() -> Option<i32> {
+ option
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_option_as_deref.txt b/src/tools/clippy/src/docs/needless_option_as_deref.txt
new file mode 100644
index 000000000..226396c97
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_option_as_deref.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for no-op uses of `Option::{as_deref, as_deref_mut}`,
+for example, `Option<&T>::as_deref()` returns the same type.
+
+### Why is this bad?
+Redundant code and improving readability.
+
+### Example
+```
+let a = Some(&1);
+let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
+```
+
+Use instead:
+```
+let a = Some(&1);
+let b = a;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_option_take.txt b/src/tools/clippy/src/docs/needless_option_take.txt
new file mode 100644
index 000000000..6bac65a13
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_option_take.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for calling `take` function after `as_ref`.
+
+### Why is this bad?
+Redundant code. `take` writes `None` to its argument.
+In this case the modification is useless as it's a temporary that cannot be read from afterwards.
+
+### Example
+```
+let x = Some(3);
+x.as_ref().take();
+```
+Use instead:
+```
+let x = Some(3);
+x.as_ref();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_parens_on_range_literals.txt b/src/tools/clippy/src/docs/needless_parens_on_range_literals.txt
new file mode 100644
index 000000000..85fab10cb
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_parens_on_range_literals.txt
@@ -0,0 +1,23 @@
+### What it does
+The lint checks for parenthesis on literals in range statements that are
+superfluous.
+
+### Why is this bad?
+Having superfluous parenthesis makes the code less readable
+overhead when reading.
+
+### Example
+
+```
+for i in (0)..10 {
+ println!("{i}");
+}
+```
+
+Use instead:
+
+```
+for i in 0..10 {
+ println!("{i}");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_pass_by_value.txt b/src/tools/clippy/src/docs/needless_pass_by_value.txt
new file mode 100644
index 000000000..58c420b19
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_pass_by_value.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for functions taking arguments by value, but not
+consuming them in its
+body.
+
+### Why is this bad?
+Taking arguments by reference is more flexible and can
+sometimes avoid
+unnecessary allocations.
+
+### Known problems
+* This lint suggests taking an argument by reference,
+however sometimes it is better to let users decide the argument type
+(by using `Borrow` trait, for example), depending on how the function is used.
+
+### Example
+```
+fn foo(v: Vec<i32>) {
+ assert_eq!(v.len(), 42);
+}
+```
+should be
+```
+fn foo(v: &[i32]) {
+ assert_eq!(v.len(), 42);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_question_mark.txt b/src/tools/clippy/src/docs/needless_question_mark.txt
new file mode 100644
index 000000000..540739fd4
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_question_mark.txt
@@ -0,0 +1,43 @@
+### What it does
+Suggests alternatives for useless applications of `?` in terminating expressions
+
+### Why is this bad?
+There's no reason to use `?` to short-circuit when execution of the body will end there anyway.
+
+### Example
+```
+struct TO {
+ magic: Option<usize>,
+}
+
+fn f(to: TO) -> Option<usize> {
+ Some(to.magic?)
+}
+
+struct TR {
+ magic: Result<usize, bool>,
+}
+
+fn g(tr: Result<TR, bool>) -> Result<usize, bool> {
+ tr.and_then(|t| Ok(t.magic?))
+}
+
+```
+Use instead:
+```
+struct TO {
+ magic: Option<usize>,
+}
+
+fn f(to: TO) -> Option<usize> {
+ to.magic
+}
+
+struct TR {
+ magic: Result<usize, bool>,
+}
+
+fn g(tr: Result<TR, bool>) -> Result<usize, bool> {
+ tr.and_then(|t| t.magic)
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_range_loop.txt b/src/tools/clippy/src/docs/needless_range_loop.txt
new file mode 100644
index 000000000..583c09b28
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_range_loop.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for looping over the range of `0..len` of some
+collection just to get the values by index.
+
+### Why is this bad?
+Just iterating the collection itself makes the intent
+more clear and is probably faster.
+
+### Example
+```
+let vec = vec!['a', 'b', 'c'];
+for i in 0..vec.len() {
+ println!("{}", vec[i]);
+}
+```
+
+Use instead:
+```
+let vec = vec!['a', 'b', 'c'];
+for i in vec {
+ println!("{}", i);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_return.txt b/src/tools/clippy/src/docs/needless_return.txt
new file mode 100644
index 000000000..48782cb0c
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_return.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for return statements at the end of a block.
+
+### Why is this bad?
+Removing the `return` and semicolon will make the code
+more rusty.
+
+### Example
+```
+fn foo(x: usize) -> usize {
+ return x;
+}
+```
+simplify to
+```
+fn foo(x: usize) -> usize {
+ x
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_splitn.txt b/src/tools/clippy/src/docs/needless_splitn.txt
new file mode 100644
index 000000000..b10a84fbc
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_splitn.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usages of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same.
+### Why is this bad?
+The function `split` is simpler and there is no performance difference in these cases, considering
+that both functions return a lazy iterator.
+### Example
+```
+let str = "key=value=add";
+let _ = str.splitn(3, '=').next().unwrap();
+```
+
+Use instead:
+```
+let str = "key=value=add";
+let _ = str.split('=').next().unwrap();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_update.txt b/src/tools/clippy/src/docs/needless_update.txt
new file mode 100644
index 000000000..82adabf64
--- /dev/null
+++ b/src/tools/clippy/src/docs/needless_update.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for needlessly including a base struct on update
+when all fields are changed anyway.
+
+This lint is not applied to structs marked with
+[non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html).
+
+### Why is this bad?
+This will cost resources (because the base has to be
+somewhere), and make the code less readable.
+
+### Example
+```
+Point {
+ x: 1,
+ y: 1,
+ z: 1,
+ ..zero_point
+};
+```
+
+Use instead:
+```
+// Missing field `z`
+Point {
+ x: 1,
+ y: 1,
+ ..zero_point
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt b/src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt
new file mode 100644
index 000000000..fa55c6cfd
--- /dev/null
+++ b/src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for the usage of negated comparison operators on types which only implement
+`PartialOrd` (e.g., `f64`).
+
+### Why is this bad?
+These operators make it easy to forget that the underlying types actually allow not only three
+potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is
+especially easy to miss if the operator based comparison result is negated.
+
+### Example
+```
+let a = 1.0;
+let b = f64::NAN;
+
+let not_less_or_equal = !(a <= b);
+```
+
+Use instead:
+```
+use std::cmp::Ordering;
+
+let _not_less_or_equal = match a.partial_cmp(&b) {
+ None | Some(Ordering::Greater) => true,
+ _ => false,
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/neg_multiply.txt b/src/tools/clippy/src/docs/neg_multiply.txt
new file mode 100644
index 000000000..4e8b096eb
--- /dev/null
+++ b/src/tools/clippy/src/docs/neg_multiply.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for multiplication by -1 as a form of negation.
+
+### Why is this bad?
+It's more readable to just negate.
+
+### Known problems
+This only catches integers (for now).
+
+### Example
+```
+let a = x * -1;
+```
+
+Use instead:
+```
+let a = -x;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/negative_feature_names.txt b/src/tools/clippy/src/docs/negative_feature_names.txt
new file mode 100644
index 000000000..01ee9efb3
--- /dev/null
+++ b/src/tools/clippy/src/docs/negative_feature_names.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for negative feature names with prefix `no-` or `not-`
+
+### Why is this bad?
+Features are supposed to be additive, and negatively-named features violate it.
+
+### Example
+```
+[features]
+default = []
+no-abc = []
+not-def = []
+
+```
+Use instead:
+```
+[features]
+default = ["abc", "def"]
+abc = []
+def = []
+
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/never_loop.txt b/src/tools/clippy/src/docs/never_loop.txt
new file mode 100644
index 000000000..737ccf415
--- /dev/null
+++ b/src/tools/clippy/src/docs/never_loop.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for loops that will always `break`, `return` or
+`continue` an outer loop.
+
+### Why is this bad?
+This loop never loops, all it does is obfuscating the
+code.
+
+### Example
+```
+loop {
+ ..;
+ break;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/new_ret_no_self.txt b/src/tools/clippy/src/docs/new_ret_no_self.txt
new file mode 100644
index 000000000..291bad24a
--- /dev/null
+++ b/src/tools/clippy/src/docs/new_ret_no_self.txt
@@ -0,0 +1,47 @@
+### What it does
+Checks for `new` not returning a type that contains `Self`.
+
+### Why is this bad?
+As a convention, `new` methods are used to make a new
+instance of a type.
+
+### Example
+In an impl block:
+```
+impl Foo {
+ fn new() -> NotAFoo {
+ }
+}
+```
+
+```
+struct Bar(Foo);
+impl Foo {
+ // Bad. The type name must contain `Self`
+ fn new() -> Bar {
+ }
+}
+```
+
+```
+impl Foo {
+ // Good. Return type contains `Self`
+ fn new() -> Result<Foo, FooError> {
+ }
+}
+```
+
+Or in a trait definition:
+```
+pub trait Trait {
+ // Bad. The type name must contain `Self`
+ fn new();
+}
+```
+
+```
+pub trait Trait {
+ // Good. Return type contains `Self`
+ fn new() -> Self;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/new_without_default.txt b/src/tools/clippy/src/docs/new_without_default.txt
new file mode 100644
index 000000000..662d39c8e
--- /dev/null
+++ b/src/tools/clippy/src/docs/new_without_default.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for public types with a `pub fn new() -> Self` method and no
+implementation of
+[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).
+
+### Why is this bad?
+The user might expect to be able to use
+[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the
+type can be constructed without arguments.
+
+### Example
+```
+pub struct Foo(Bar);
+
+impl Foo {
+ pub fn new() -> Self {
+ Foo(Bar::new())
+ }
+}
+```
+
+To fix the lint, add a `Default` implementation that delegates to `new`:
+
+```
+pub struct Foo(Bar);
+
+impl Default for Foo {
+ fn default() -> Self {
+ Foo::new()
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/no_effect.txt b/src/tools/clippy/src/docs/no_effect.txt
new file mode 100644
index 000000000..d4cc08fa8
--- /dev/null
+++ b/src/tools/clippy/src/docs/no_effect.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for statements which have no effect.
+
+### Why is this bad?
+Unlike dead code, these statements are actually
+executed. However, as they have no effect, all they do is make the code less
+readable.
+
+### Example
+```
+0;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/no_effect_replace.txt b/src/tools/clippy/src/docs/no_effect_replace.txt
new file mode 100644
index 000000000..646d45287
--- /dev/null
+++ b/src/tools/clippy/src/docs/no_effect_replace.txt
@@ -0,0 +1,11 @@
+### What it does
+Checks for `replace` statements which have no effect.
+
+### Why is this bad?
+It's either a mistake or confusing.
+
+### Example
+```
+"1234".replace("12", "12");
+"1234".replacen("12", "12", 1);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/no_effect_underscore_binding.txt b/src/tools/clippy/src/docs/no_effect_underscore_binding.txt
new file mode 100644
index 000000000..972f60dd0
--- /dev/null
+++ b/src/tools/clippy/src/docs/no_effect_underscore_binding.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for binding to underscore prefixed variable without side-effects.
+
+### Why is this bad?
+Unlike dead code, these bindings are actually
+executed. However, as they have no effect and shouldn't be used further on, all they
+do is make the code less readable.
+
+### Known problems
+Further usage of this variable is not checked, which can lead to false positives if it is
+used later in the code.
+
+### Example
+```
+let _i_serve_no_purpose = 1;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/non_ascii_literal.txt b/src/tools/clippy/src/docs/non_ascii_literal.txt
new file mode 100644
index 000000000..164902b47
--- /dev/null
+++ b/src/tools/clippy/src/docs/non_ascii_literal.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for non-ASCII characters in string and char literals.
+
+### Why is this bad?
+Yeah, we know, the 90's called and wanted their charset
+back. Even so, there still are editors and other programs out there that
+don't work well with Unicode. So if the code is meant to be used
+internationally, on multiple operating systems, or has other portability
+requirements, activating this lint could be useful.
+
+### Example
+```
+let x = String::from("€");
+```
+
+Use instead:
+```
+let x = String::from("\u{20ac}");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/non_octal_unix_permissions.txt b/src/tools/clippy/src/docs/non_octal_unix_permissions.txt
new file mode 100644
index 000000000..4a468e94d
--- /dev/null
+++ b/src/tools/clippy/src/docs/non_octal_unix_permissions.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for non-octal values used to set Unix file permissions.
+
+### Why is this bad?
+They will be converted into octal, creating potentially
+unintended file permissions.
+
+### Example
+```
+use std::fs::OpenOptions;
+use std::os::unix::fs::OpenOptionsExt;
+
+let mut options = OpenOptions::new();
+options.mode(644);
+```
+Use instead:
+```
+use std::fs::OpenOptions;
+use std::os::unix::fs::OpenOptionsExt;
+
+let mut options = OpenOptions::new();
+options.mode(0o644);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt b/src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt
new file mode 100644
index 000000000..11e6f6e16
--- /dev/null
+++ b/src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt
@@ -0,0 +1,36 @@
+### What it does
+This lint warns about a `Send` implementation for a type that
+contains fields that are not safe to be sent across threads.
+It tries to detect fields that can cause a soundness issue
+when sent to another thread (e.g., `Rc`) while allowing `!Send` fields
+that are expected to exist in a `Send` type, such as raw pointers.
+
+### Why is this bad?
+Sending the struct to another thread effectively sends all of its fields,
+and the fields that do not implement `Send` can lead to soundness bugs
+such as data races when accessed in a thread
+that is different from the thread that created it.
+
+See:
+* [*The Rustonomicon* about *Send and Sync*](https://doc.rust-lang.org/nomicon/send-and-sync.html)
+* [The documentation of `Send`](https://doc.rust-lang.org/std/marker/trait.Send.html)
+
+### Known Problems
+This lint relies on heuristics to distinguish types that are actually
+unsafe to be sent across threads and `!Send` types that are expected to
+exist in `Send` type. Its rule can filter out basic cases such as
+`Vec<*const T>`, but it's not perfect. Feel free to create an issue if
+you have a suggestion on how this heuristic can be improved.
+
+### Example
+```
+struct ExampleStruct<T> {
+ rc_is_not_send: Rc<String>,
+ unbounded_generic_field: T,
+}
+
+// This impl is unsound because it allows sending `!Send` types through `ExampleStruct`
+unsafe impl<T> Send for ExampleStruct<T> {}
+```
+Use thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)
+or specify correct bounds on generic type parameters (`T: Send`). \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/nonminimal_bool.txt b/src/tools/clippy/src/docs/nonminimal_bool.txt
new file mode 100644
index 000000000..488980ddf
--- /dev/null
+++ b/src/tools/clippy/src/docs/nonminimal_bool.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for boolean expressions that can be written more
+concisely.
+
+### Why is this bad?
+Readability of boolean expressions suffers from
+unnecessary duplication.
+
+### Known problems
+Ignores short circuiting behavior of `||` and
+`&&`. Ignores `|`, `&` and `^`.
+
+### Example
+```
+if a && true {}
+if !(a == b) {}
+```
+
+Use instead:
+```
+if a {}
+if a != b {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/nonsensical_open_options.txt b/src/tools/clippy/src/docs/nonsensical_open_options.txt
new file mode 100644
index 000000000..7a95443b5
--- /dev/null
+++ b/src/tools/clippy/src/docs/nonsensical_open_options.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for duplicate open options as well as combinations
+that make no sense.
+
+### Why is this bad?
+In the best case, the code will be harder to read than
+necessary. I don't know the worst case.
+
+### Example
+```
+use std::fs::OpenOptions;
+
+OpenOptions::new().read(true).truncate(true);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/nonstandard_macro_braces.txt b/src/tools/clippy/src/docs/nonstandard_macro_braces.txt
new file mode 100644
index 000000000..7e8d0d2d3
--- /dev/null
+++ b/src/tools/clippy/src/docs/nonstandard_macro_braces.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks that common macros are used with consistent bracing.
+
+### Why is this bad?
+This is mostly a consistency lint although using () or []
+doesn't give you a semicolon in item position, which can be unexpected.
+
+### Example
+```
+vec!{1, 2, 3};
+```
+Use instead:
+```
+vec![1, 2, 3];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt b/src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt
new file mode 100644
index 000000000..31355fbb7
--- /dev/null
+++ b/src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for public functions that dereference raw pointer
+arguments but are not marked `unsafe`.
+
+### Why is this bad?
+The function should probably be marked `unsafe`, since
+for an arbitrary raw pointer, there is no way of telling for sure if it is
+valid.
+
+### Known problems
+* It does not check functions recursively so if the pointer is passed to a
+private non-`unsafe` function which does the dereferencing, the lint won't
+trigger.
+* It only checks for arguments whose type are raw pointers, not raw pointers
+got from an argument in some other way (`fn foo(bar: &[*const u8])` or
+`some_argument.get_raw_ptr()`).
+
+### Example
+```
+pub fn foo(x: *const u8) {
+ println!("{}", unsafe { *x });
+}
+```
+
+Use instead:
+```
+pub unsafe fn foo(x: *const u8) {
+ println!("{}", unsafe { *x });
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/obfuscated_if_else.txt b/src/tools/clippy/src/docs/obfuscated_if_else.txt
new file mode 100644
index 000000000..638f63b0d
--- /dev/null
+++ b/src/tools/clippy/src/docs/obfuscated_if_else.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for usages of `.then_some(..).unwrap_or(..)`
+
+### Why is this bad?
+This can be written more clearly with `if .. else ..`
+
+### Limitations
+This lint currently only looks for usages of
+`.then_some(..).unwrap_or(..)`, but will be expanded
+to account for similar patterns.
+
+### Example
+```
+let x = true;
+x.then_some("a").unwrap_or("b");
+```
+Use instead:
+```
+let x = true;
+if x { "a" } else { "b" };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/octal_escapes.txt b/src/tools/clippy/src/docs/octal_escapes.txt
new file mode 100644
index 000000000..eee820587
--- /dev/null
+++ b/src/tools/clippy/src/docs/octal_escapes.txt
@@ -0,0 +1,33 @@
+### What it does
+Checks for `\0` escapes in string and byte literals that look like octal
+character escapes in C.
+
+### Why is this bad?
+
+C and other languages support octal character escapes in strings, where
+a backslash is followed by up to three octal digits. For example, `\033`
+stands for the ASCII character 27 (ESC). Rust does not support this
+notation, but has the escape code `\0` which stands for a null
+byte/character, and any following digits do not form part of the escape
+sequence. Therefore, `\033` is not a compiler error but the result may
+be surprising.
+
+### Known problems
+The actual meaning can be the intended one. `\x00` can be used in these
+cases to be unambiguous.
+
+The lint does not trigger for format strings in `print!()`, `write!()`
+and friends since the string is already preprocessed when Clippy lints
+can see it.
+
+### Example
+```
+let one = "\033[1m Bold? \033[0m"; // \033 intended as escape
+let two = "\033\0"; // \033 intended as null-3-3
+```
+
+Use instead:
+```
+let one = "\x1b[1mWill this be bold?\x1b[0m";
+let two = "\x0033\x00";
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ok_expect.txt b/src/tools/clippy/src/docs/ok_expect.txt
new file mode 100644
index 000000000..fd5205d49
--- /dev/null
+++ b/src/tools/clippy/src/docs/ok_expect.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `ok().expect(..)`.
+
+### Why is this bad?
+Because you usually call `expect()` on the `Result`
+directly to get a better error message.
+
+### Known problems
+The error type needs to implement `Debug`
+
+### Example
+```
+x.ok().expect("why did I do this again?");
+```
+
+Use instead:
+```
+x.expect("why did I do this again?");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/only_used_in_recursion.txt b/src/tools/clippy/src/docs/only_used_in_recursion.txt
new file mode 100644
index 000000000..f19f47ff9
--- /dev/null
+++ b/src/tools/clippy/src/docs/only_used_in_recursion.txt
@@ -0,0 +1,58 @@
+### What it does
+Checks for arguments that are only used in recursion with no side-effects.
+
+### Why is this bad?
+It could contain a useless calculation and can make function simpler.
+
+The arguments can be involved in calculations and assignments but as long as
+the calculations have no side-effects (function calls or mutating dereference)
+and the assigned variables are also only in recursion, it is useless.
+
+### Known problems
+Too many code paths in the linting code are currently untested and prone to produce false
+positives or are prone to have performance implications.
+
+In some cases, this would not catch all useless arguments.
+
+```
+fn foo(a: usize, b: usize) -> usize {
+ let f = |x| x + 1;
+
+ if a == 0 {
+ 1
+ } else {
+ foo(a - 1, f(b))
+ }
+}
+```
+
+For example, the argument `b` is only used in recursion, but the lint would not catch it.
+
+List of some examples that can not be caught:
+- binary operation of non-primitive types
+- closure usage
+- some `break` relative operations
+- struct pattern binding
+
+Also, when you recurse the function name with path segments, it is not possible to detect.
+
+### Example
+```
+fn f(a: usize, b: usize) -> usize {
+ if a == 0 {
+ 1
+ } else {
+ f(a - 1, b + 1)
+ }
+}
+```
+Use instead:
+```
+fn f(a: usize) -> usize {
+ if a == 0 {
+ 1
+ } else {
+ f(a - 1)
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/op_ref.txt b/src/tools/clippy/src/docs/op_ref.txt
new file mode 100644
index 000000000..7a7ed1bc9
--- /dev/null
+++ b/src/tools/clippy/src/docs/op_ref.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for arguments to `==` which have their address
+taken to satisfy a bound
+and suggests to dereference the other argument instead
+
+### Why is this bad?
+It is more idiomatic to dereference the other argument.
+
+### Example
+```
+&x == y
+```
+
+Use instead:
+```
+x == *y
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_as_ref_deref.txt b/src/tools/clippy/src/docs/option_as_ref_deref.txt
new file mode 100644
index 000000000..ad7411d3d
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_as_ref_deref.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str).
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.as_deref()`.
+
+### Example
+```
+opt.as_ref().map(String::as_str)
+```
+Can be written as
+```
+opt.as_deref()
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_env_unwrap.txt b/src/tools/clippy/src/docs/option_env_unwrap.txt
new file mode 100644
index 000000000..c952cba8e
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_env_unwrap.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `option_env!(...).unwrap()` and
+suggests usage of the `env!` macro.
+
+### Why is this bad?
+Unwrapping the result of `option_env!` will panic
+at run-time if the environment variable doesn't exist, whereas `env!`
+catches it at compile-time.
+
+### Example
+```
+let _ = option_env!("HOME").unwrap();
+```
+
+Is better expressed as:
+
+```
+let _ = env!("HOME");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_filter_map.txt b/src/tools/clippy/src/docs/option_filter_map.txt
new file mode 100644
index 000000000..25f7bde7b
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_filter_map.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for indirect collection of populated `Option`
+
+### Why is this bad?
+`Option` is like a collection of 0-1 things, so `flatten`
+automatically does this without suspicious-looking `unwrap` calls.
+
+### Example
+```
+let _ = std::iter::empty::<Option<i32>>().filter(Option::is_some).map(Option::unwrap);
+```
+Use instead:
+```
+let _ = std::iter::empty::<Option<i32>>().flatten();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_if_let_else.txt b/src/tools/clippy/src/docs/option_if_let_else.txt
new file mode 100644
index 000000000..43652db51
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_if_let_else.txt
@@ -0,0 +1,46 @@
+### What it does
+Lints usage of `if let Some(v) = ... { y } else { x }` and
+`match .. { Some(v) => y, None/_ => x }` which are more
+idiomatically done with `Option::map_or` (if the else bit is a pure
+expression) or `Option::map_or_else` (if the else bit is an impure
+expression).
+
+### Why is this bad?
+Using the dedicated functions of the `Option` type is clearer and
+more concise than an `if let` expression.
+
+### Known problems
+This lint uses a deliberately conservative metric for checking
+if the inside of either body contains breaks or continues which will
+cause it to not suggest a fix if either block contains a loop with
+continues or breaks contained within the loop.
+
+### Example
+```
+let _ = if let Some(foo) = optional {
+ foo
+} else {
+ 5
+};
+let _ = match optional {
+ Some(val) => val + 1,
+ None => 5
+};
+let _ = if let Some(foo) = optional {
+ foo
+} else {
+ let y = do_complicated_function();
+ y*y
+};
+```
+
+should be
+
+```
+let _ = optional.map_or(5, |foo| foo);
+let _ = optional.map_or(5, |val| val + 1);
+let _ = optional.map_or_else(||{
+ let y = do_complicated_function();
+ y*y
+}, |foo| foo);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_map_or_none.txt b/src/tools/clippy/src/docs/option_map_or_none.txt
new file mode 100644
index 000000000..c86c65215
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_map_or_none.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `_.map_or(None, _)`.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.and_then(_)`.
+
+### Known problems
+The order of the arguments is not in execution order.
+
+### Example
+```
+opt.map_or(None, |a| Some(a + 1));
+```
+
+Use instead:
+```
+opt.and_then(|a| Some(a + 1));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_map_unit_fn.txt b/src/tools/clippy/src/docs/option_map_unit_fn.txt
new file mode 100644
index 000000000..fc4b528f0
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_map_unit_fn.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for usage of `option.map(f)` where f is a function
+or closure that returns the unit type `()`.
+
+### Why is this bad?
+Readability, this can be written more clearly with
+an if let statement
+
+### Example
+```
+let x: Option<String> = do_stuff();
+x.map(log_err_msg);
+x.map(|msg| log_err_msg(format_msg(msg)));
+```
+
+The correct use would be:
+
+```
+let x: Option<String> = do_stuff();
+if let Some(msg) = x {
+ log_err_msg(msg);
+}
+
+if let Some(msg) = x {
+ log_err_msg(format_msg(msg));
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_option.txt b/src/tools/clippy/src/docs/option_option.txt
new file mode 100644
index 000000000..b4324bd83
--- /dev/null
+++ b/src/tools/clippy/src/docs/option_option.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for use of `Option<Option<_>>` in function signatures and type
+definitions
+
+### Why is this bad?
+`Option<_>` represents an optional value. `Option<Option<_>>`
+represents an optional optional value which is logically the same thing as an optional
+value but has an unneeded extra level of wrapping.
+
+If you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases,
+consider a custom `enum` instead, with clear names for each case.
+
+### Example
+```
+fn get_data() -> Option<Option<u32>> {
+ None
+}
+```
+
+Better:
+
+```
+pub enum Contents {
+ Data(Vec<u8>), // Was Some(Some(Vec<u8>))
+ NotYetFetched, // Was Some(None)
+ None, // Was None
+}
+
+fn get_data() -> Contents {
+ Contents::None
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/or_fun_call.txt b/src/tools/clippy/src/docs/or_fun_call.txt
new file mode 100644
index 000000000..6ce77cc26
--- /dev/null
+++ b/src/tools/clippy/src/docs/or_fun_call.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,
+`.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`,
+`.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()`
+etc. instead.
+
+### Why is this bad?
+The function will always be called and potentially
+allocate an object acting as the default.
+
+### Known problems
+If the function has side-effects, not calling it will
+change the semantic of the program, but you shouldn't rely on that anyway.
+
+### Example
+```
+foo.unwrap_or(String::new());
+```
+
+Use instead:
+```
+foo.unwrap_or_else(String::new);
+
+// or
+
+foo.unwrap_or_default();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/or_then_unwrap.txt b/src/tools/clippy/src/docs/or_then_unwrap.txt
new file mode 100644
index 000000000..64ac53749
--- /dev/null
+++ b/src/tools/clippy/src/docs/or_then_unwrap.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for `.or(…).unwrap()` calls to Options and Results.
+
+### Why is this bad?
+You should use `.unwrap_or(…)` instead for clarity.
+
+### Example
+```
+// Result
+let value = result.or::<Error>(Ok(fallback)).unwrap();
+
+// Option
+let value = option.or(Some(fallback)).unwrap();
+```
+Use instead:
+```
+// Result
+let value = result.unwrap_or(fallback);
+
+// Option
+let value = option.unwrap_or(fallback);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/out_of_bounds_indexing.txt b/src/tools/clippy/src/docs/out_of_bounds_indexing.txt
new file mode 100644
index 000000000..5802eea29
--- /dev/null
+++ b/src/tools/clippy/src/docs/out_of_bounds_indexing.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for out of bounds array indexing with a constant
+index.
+
+### Why is this bad?
+This will always panic at runtime.
+
+### Example
+```
+let x = [1, 2, 3, 4];
+
+x[9];
+&x[2..9];
+```
+
+Use instead:
+```
+// Index within bounds
+
+x[0];
+x[3];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/overflow_check_conditional.txt b/src/tools/clippy/src/docs/overflow_check_conditional.txt
new file mode 100644
index 000000000..a09cc18a0
--- /dev/null
+++ b/src/tools/clippy/src/docs/overflow_check_conditional.txt
@@ -0,0 +1,11 @@
+### What it does
+Detects classic underflow/overflow checks.
+
+### Why is this bad?
+Most classic C underflow/overflow checks will fail in
+Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead.
+
+### Example
+```
+a + b < a;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/overly_complex_bool_expr.txt b/src/tools/clippy/src/docs/overly_complex_bool_expr.txt
new file mode 100644
index 000000000..65ca18392
--- /dev/null
+++ b/src/tools/clippy/src/docs/overly_complex_bool_expr.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for boolean expressions that contain terminals that
+can be eliminated.
+
+### Why is this bad?
+This is most likely a logic bug.
+
+### Known problems
+Ignores short circuiting behavior.
+
+### Example
+```
+// The `b` is unnecessary, the expression is equivalent to `if a`.
+if a && b || a { ... }
+```
+
+Use instead:
+```
+if a {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/panic.txt b/src/tools/clippy/src/docs/panic.txt
new file mode 100644
index 000000000..f9bdc6e87
--- /dev/null
+++ b/src/tools/clippy/src/docs/panic.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for usage of `panic!`.
+
+### Why is this bad?
+`panic!` will stop the execution of the executable
+
+### Example
+```
+panic!("even with a good reason");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/panic_in_result_fn.txt b/src/tools/clippy/src/docs/panic_in_result_fn.txt
new file mode 100644
index 000000000..51c2f8ae5
--- /dev/null
+++ b/src/tools/clippy/src/docs/panic_in_result_fn.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result.
+
+### Why is this bad?
+For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided.
+
+### Known problems
+Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked.
+
+### Example
+```
+fn result_with_panic() -> Result<bool, String>
+{
+ panic!("error");
+}
+```
+Use instead:
+```
+fn result_without_panic() -> Result<bool, String> {
+ Err(String::from("error"))
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/panicking_unwrap.txt b/src/tools/clippy/src/docs/panicking_unwrap.txt
new file mode 100644
index 000000000..1fbc245c8
--- /dev/null
+++ b/src/tools/clippy/src/docs/panicking_unwrap.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for calls of `unwrap[_err]()` that will always fail.
+
+### Why is this bad?
+If panicking is desired, an explicit `panic!()` should be used.
+
+### Known problems
+This lint only checks `if` conditions not assignments.
+So something like `let x: Option<()> = None; x.unwrap();` will not be recognized.
+
+### Example
+```
+if option.is_none() {
+ do_something_with(option.unwrap())
+}
+```
+
+This code will always panic. The if condition should probably be inverted. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/partialeq_ne_impl.txt b/src/tools/clippy/src/docs/partialeq_ne_impl.txt
new file mode 100644
index 000000000..78f55188b
--- /dev/null
+++ b/src/tools/clippy/src/docs/partialeq_ne_impl.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for manual re-implementations of `PartialEq::ne`.
+
+### Why is this bad?
+`PartialEq::ne` is required to always return the
+negated result of `PartialEq::eq`, which is exactly what the default
+implementation does. Therefore, there should never be any need to
+re-implement it.
+
+### Example
+```
+struct Foo;
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &Foo) -> bool { true }
+ fn ne(&self, other: &Foo) -> bool { !(self == other) }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/partialeq_to_none.txt b/src/tools/clippy/src/docs/partialeq_to_none.txt
new file mode 100644
index 000000000..5cc07bf88
--- /dev/null
+++ b/src/tools/clippy/src/docs/partialeq_to_none.txt
@@ -0,0 +1,24 @@
+### What it does
+
+Checks for binary comparisons to a literal `Option::None`.
+
+### Why is this bad?
+
+A programmer checking if some `foo` is `None` via a comparison `foo == None`
+is usually inspired from other programming languages (e.g. `foo is None`
+in Python).
+Checking if a value of type `Option<T>` is (not) equal to `None` in that
+way relies on `T: PartialEq` to do the comparison, which is unneeded.
+
+### Example
+```
+fn foo(f: Option<u32>) -> &'static str {
+ if f != None { "yay" } else { "nay" }
+}
+```
+Use instead:
+```
+fn foo(f: Option<u32>) -> &'static str {
+ if f.is_some() { "yay" } else { "nay" }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/path_buf_push_overwrite.txt b/src/tools/clippy/src/docs/path_buf_push_overwrite.txt
new file mode 100644
index 000000000..34f8901da
--- /dev/null
+++ b/src/tools/clippy/src/docs/path_buf_push_overwrite.txt
@@ -0,0 +1,25 @@
+### What it does
+* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
+calls on `PathBuf` that can cause overwrites.
+
+### Why is this bad?
+Calling `push` with a root path at the start can overwrite the
+previous defined path.
+
+### Example
+```
+use std::path::PathBuf;
+
+let mut x = PathBuf::from("/foo");
+x.push("/bar");
+assert_eq!(x, PathBuf::from("/bar"));
+```
+Could be written:
+
+```
+use std::path::PathBuf;
+
+let mut x = PathBuf::from("/foo");
+x.push("bar");
+assert_eq!(x, PathBuf::from("/foo/bar"));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/pattern_type_mismatch.txt b/src/tools/clippy/src/docs/pattern_type_mismatch.txt
new file mode 100644
index 000000000..64da881d5
--- /dev/null
+++ b/src/tools/clippy/src/docs/pattern_type_mismatch.txt
@@ -0,0 +1,64 @@
+### What it does
+Checks for patterns that aren't exact representations of the types
+they are applied to.
+
+To satisfy this lint, you will have to adjust either the expression that is matched
+against or the pattern itself, as well as the bindings that are introduced by the
+adjusted patterns. For matching you will have to either dereference the expression
+with the `*` operator, or amend the patterns to explicitly match against `&<pattern>`
+or `&mut <pattern>` depending on the reference mutability. For the bindings you need
+to use the inverse. You can leave them as plain bindings if you wish for the value
+to be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct
+a reference into the matched structure.
+
+If you are looking for a way to learn about ownership semantics in more detail, it
+is recommended to look at IDE options available to you to highlight types, lifetimes
+and reference semantics in your code. The available tooling would expose these things
+in a general way even outside of the various pattern matching mechanics. Of course
+this lint can still be used to highlight areas of interest and ensure a good understanding
+of ownership semantics.
+
+### Why is this bad?
+It isn't bad in general. But in some contexts it can be desirable
+because it increases ownership hints in the code, and will guard against some changes
+in ownership.
+
+### Example
+This example shows the basic adjustments necessary to satisfy the lint. Note how
+the matched expression is explicitly dereferenced with `*` and the `inner` variable
+is bound to a shared borrow via `ref inner`.
+
+```
+// Bad
+let value = &Some(Box::new(23));
+match value {
+ Some(inner) => println!("{}", inner),
+ None => println!("none"),
+}
+
+// Good
+let value = &Some(Box::new(23));
+match *value {
+ Some(ref inner) => println!("{}", inner),
+ None => println!("none"),
+}
+```
+
+The following example demonstrates one of the advantages of the more verbose style.
+Note how the second version uses `ref mut a` to explicitly declare `a` a shared mutable
+borrow, while `b` is simply taken by value. This ensures that the loop body cannot
+accidentally modify the wrong part of the structure.
+
+```
+// Bad
+let mut values = vec![(2, 3), (3, 4)];
+for (a, b) in &mut values {
+ *a += *b;
+}
+
+// Good
+let mut values = vec![(2, 3), (3, 4)];
+for &mut (ref mut a, b) in &mut values {
+ *a += b;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/positional_named_format_parameters.txt b/src/tools/clippy/src/docs/positional_named_format_parameters.txt
new file mode 100644
index 000000000..e391d2406
--- /dev/null
+++ b/src/tools/clippy/src/docs/positional_named_format_parameters.txt
@@ -0,0 +1,15 @@
+### What it does
+This lint warns when a named parameter in a format string is used as a positional one.
+
+### Why is this bad?
+It may be confused for an assignment and obfuscates which parameter is being used.
+
+### Example
+```
+println!("{}", x = 10);
+```
+
+Use instead:
+```
+println!("{x}", x = 10);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/possible_missing_comma.txt b/src/tools/clippy/src/docs/possible_missing_comma.txt
new file mode 100644
index 000000000..5d92f4cae
--- /dev/null
+++ b/src/tools/clippy/src/docs/possible_missing_comma.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for possible missing comma in an array. It lints if
+an array element is a binary operator expression and it lies on two lines.
+
+### Why is this bad?
+This could lead to unexpected results.
+
+### Example
+```
+let a = &[
+ -1, -2, -3 // <= no comma here
+ -4, -5, -6
+];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/precedence.txt b/src/tools/clippy/src/docs/precedence.txt
new file mode 100644
index 000000000..fda0b831f
--- /dev/null
+++ b/src/tools/clippy/src/docs/precedence.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for operations where precedence may be unclear
+and suggests to add parentheses. Currently it catches the following:
+* mixed usage of arithmetic and bit shifting/combining operators without
+parentheses
+* a "negative" numeric literal (which is really a unary `-` followed by a
+numeric literal)
+ followed by a method call
+
+### Why is this bad?
+Not everyone knows the precedence of those operators by
+heart, so expressions like these may trip others trying to reason about the
+code.
+
+### Example
+* `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
+* `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1 \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_in_format_impl.txt b/src/tools/clippy/src/docs/print_in_format_impl.txt
new file mode 100644
index 000000000..140d23d6f
--- /dev/null
+++ b/src/tools/clippy/src/docs/print_in_format_impl.txt
@@ -0,0 +1,34 @@
+### What it does
+Checks for use of `println`, `print`, `eprintln` or `eprint` in an
+implementation of a formatting trait.
+
+### Why is this bad?
+Using a print macro is likely unintentional since formatting traits
+should write to the `Formatter`, not stdout/stderr.
+
+### Example
+```
+use std::fmt::{Display, Error, Formatter};
+
+struct S;
+impl Display for S {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ println!("S");
+
+ Ok(())
+ }
+}
+```
+Use instead:
+```
+use std::fmt::{Display, Error, Formatter};
+
+struct S;
+impl Display for S {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ writeln!(f, "S");
+
+ Ok(())
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_literal.txt b/src/tools/clippy/src/docs/print_literal.txt
new file mode 100644
index 000000000..160073414
--- /dev/null
+++ b/src/tools/clippy/src/docs/print_literal.txt
@@ -0,0 +1,20 @@
+### What it does
+This lint warns about the use of literals as `print!`/`println!` args.
+
+### Why is this bad?
+Using literals as `println!` args is inefficient
+(c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary
+(i.e., just put the literal in the format string)
+
+### Known problems
+Will also warn with macro calls as arguments that expand to literals
+-- e.g., `println!("{}", env!("FOO"))`.
+
+### Example
+```
+println!("{}", "foo");
+```
+use the literal without formatting:
+```
+println!("foo");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_stderr.txt b/src/tools/clippy/src/docs/print_stderr.txt
new file mode 100644
index 000000000..fc14511cd
--- /dev/null
+++ b/src/tools/clippy/src/docs/print_stderr.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for printing on *stderr*. The purpose of this lint
+is to catch debugging remnants.
+
+### Why is this bad?
+People often print on *stderr* while debugging an
+application and might forget to remove those prints afterward.
+
+### Known problems
+* Only catches `eprint!` and `eprintln!` calls.
+* The lint level is unaffected by crate attributes. The level can still
+ be set for functions, modules and other items. To change the level for
+ the entire crate, please use command line flags. More information and a
+ configuration example can be found in [clippy#6610].
+
+[clippy#6610]: https://github.com/rust-lang/rust-clippy/issues/6610#issuecomment-977120558
+
+### Example
+```
+eprintln!("Hello world!");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_stdout.txt b/src/tools/clippy/src/docs/print_stdout.txt
new file mode 100644
index 000000000..6c9a4b98e
--- /dev/null
+++ b/src/tools/clippy/src/docs/print_stdout.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for printing on *stdout*. The purpose of this lint
+is to catch debugging remnants.
+
+### Why is this bad?
+People often print on *stdout* while debugging an
+application and might forget to remove those prints afterward.
+
+### Known problems
+* Only catches `print!` and `println!` calls.
+* The lint level is unaffected by crate attributes. The level can still
+ be set for functions, modules and other items. To change the level for
+ the entire crate, please use command line flags. More information and a
+ configuration example can be found in [clippy#6610].
+
+[clippy#6610]: https://github.com/rust-lang/rust-clippy/issues/6610#issuecomment-977120558
+
+### Example
+```
+println!("Hello world!");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_with_newline.txt b/src/tools/clippy/src/docs/print_with_newline.txt
new file mode 100644
index 000000000..640323e82
--- /dev/null
+++ b/src/tools/clippy/src/docs/print_with_newline.txt
@@ -0,0 +1,16 @@
+### What it does
+This lint warns when you use `print!()` with a format
+string that ends in a newline.
+
+### Why is this bad?
+You should use `println!()` instead, which appends the
+newline.
+
+### Example
+```
+print!("Hello {}!\n", name);
+```
+use println!() instead
+```
+println!("Hello {}!", name);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/println_empty_string.txt b/src/tools/clippy/src/docs/println_empty_string.txt
new file mode 100644
index 000000000..b98041302
--- /dev/null
+++ b/src/tools/clippy/src/docs/println_empty_string.txt
@@ -0,0 +1,16 @@
+### What it does
+This lint warns when you use `println!("")` to
+print a newline.
+
+### Why is this bad?
+You should use `println!()`, which is simpler.
+
+### Example
+```
+println!("");
+```
+
+Use instead:
+```
+println!();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_arg.txt b/src/tools/clippy/src/docs/ptr_arg.txt
new file mode 100644
index 000000000..796b0a65b
--- /dev/null
+++ b/src/tools/clippy/src/docs/ptr_arg.txt
@@ -0,0 +1,29 @@
+### What it does
+This lint checks for function arguments of type `&String`, `&Vec`,
+`&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls
+with the appropriate `.to_owned()`/`to_string()` calls.
+
+### Why is this bad?
+Requiring the argument to be of the specific size
+makes the function less useful for no benefit; slices in the form of `&[T]`
+or `&str` usually suffice and can be obtained from other types, too.
+
+### Known problems
+There may be `fn(&Vec)`-typed references pointing to your function.
+If you have them, you will get a compiler error after applying this lint's
+suggestions. You then have the choice to undo your changes or change the
+type of the reference.
+
+Note that if the function is part of your public interface, there may be
+other crates referencing it, of which you may not be aware. Carefully
+deprecate the function before applying the lint suggestions in this case.
+
+### Example
+```
+fn foo(&Vec<u32>) { .. }
+```
+
+Use instead:
+```
+fn foo(&[u32]) { .. }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_as_ptr.txt b/src/tools/clippy/src/docs/ptr_as_ptr.txt
new file mode 100644
index 000000000..8fb35c4aa
--- /dev/null
+++ b/src/tools/clippy/src/docs/ptr_as_ptr.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for `as` casts between raw pointers without changing its mutability,
+namely `*const T` to `*const U` and `*mut T` to `*mut U`.
+
+### Why is this bad?
+Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because
+it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
+
+### Example
+```
+let ptr: *const u32 = &42_u32;
+let mut_ptr: *mut u32 = &mut 42_u32;
+let _ = ptr as *const i32;
+let _ = mut_ptr as *mut i32;
+```
+Use instead:
+```
+let ptr: *const u32 = &42_u32;
+let mut_ptr: *mut u32 = &mut 42_u32;
+let _ = ptr.cast::<i32>();
+let _ = mut_ptr.cast::<i32>();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_eq.txt b/src/tools/clippy/src/docs/ptr_eq.txt
new file mode 100644
index 000000000..06b36ca55
--- /dev/null
+++ b/src/tools/clippy/src/docs/ptr_eq.txt
@@ -0,0 +1,22 @@
+### What it does
+Use `std::ptr::eq` when applicable
+
+### Why is this bad?
+`ptr::eq` can be used to compare `&T` references
+(which coerce to `*const T` implicitly) by their address rather than
+comparing the values they point to.
+
+### Example
+```
+let a = &[1, 2, 3];
+let b = &[1, 2, 3];
+
+assert!(a as *const _ as usize == b as *const _ as usize);
+```
+Use instead:
+```
+let a = &[1, 2, 3];
+let b = &[1, 2, 3];
+
+assert!(std::ptr::eq(a, b));
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_offset_with_cast.txt b/src/tools/clippy/src/docs/ptr_offset_with_cast.txt
new file mode 100644
index 000000000..f204e769b
--- /dev/null
+++ b/src/tools/clippy/src/docs/ptr_offset_with_cast.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for usage of the `offset` pointer method with a `usize` casted to an
+`isize`.
+
+### Why is this bad?
+If we’re always increasing the pointer address, we can avoid the numeric
+cast by using the `add` method instead.
+
+### Example
+```
+let vec = vec![b'a', b'b', b'c'];
+let ptr = vec.as_ptr();
+let offset = 1_usize;
+
+unsafe {
+ ptr.offset(offset as isize);
+}
+```
+
+Could be written:
+
+```
+let vec = vec![b'a', b'b', b'c'];
+let ptr = vec.as_ptr();
+let offset = 1_usize;
+
+unsafe {
+ ptr.add(offset);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/pub_use.txt b/src/tools/clippy/src/docs/pub_use.txt
new file mode 100644
index 000000000..407cafa01
--- /dev/null
+++ b/src/tools/clippy/src/docs/pub_use.txt
@@ -0,0 +1,28 @@
+### What it does
+
+Restricts the usage of `pub use ...`
+
+### Why is this bad?
+
+`pub use` is usually fine, but a project may wish to limit `pub use` instances to prevent
+unintentional exports or to encourage placing exported items directly in public modules
+
+### Example
+```
+pub mod outer {
+ mod inner {
+ pub struct Test {}
+ }
+ pub use inner::Test;
+}
+
+use outer::Test;
+```
+Use instead:
+```
+pub mod outer {
+ pub struct Test {}
+}
+
+use outer::Test;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/question_mark.txt b/src/tools/clippy/src/docs/question_mark.txt
new file mode 100644
index 000000000..4dc987be8
--- /dev/null
+++ b/src/tools/clippy/src/docs/question_mark.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for expressions that could be replaced by the question mark operator.
+
+### Why is this bad?
+Question mark usage is more idiomatic.
+
+### Example
+```
+if option.is_none() {
+ return None;
+}
+```
+
+Could be written:
+
+```
+option?;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/range_minus_one.txt b/src/tools/clippy/src/docs/range_minus_one.txt
new file mode 100644
index 000000000..fcb96dcc3
--- /dev/null
+++ b/src/tools/clippy/src/docs/range_minus_one.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for inclusive ranges where 1 is subtracted from
+the upper bound, e.g., `x..=(y-1)`.
+
+### Why is this bad?
+The code is more readable with an exclusive range
+like `x..y`.
+
+### Known problems
+This will cause a warning that cannot be fixed if
+the consumer of the range only accepts a specific range type, instead of
+the generic `RangeBounds` trait
+([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).
+
+### Example
+```
+for i in x..=(y-1) {
+ // ..
+}
+```
+
+Use instead:
+```
+for i in x..y {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/range_plus_one.txt b/src/tools/clippy/src/docs/range_plus_one.txt
new file mode 100644
index 000000000..193c85f9c
--- /dev/null
+++ b/src/tools/clippy/src/docs/range_plus_one.txt
@@ -0,0 +1,36 @@
+### What it does
+Checks for exclusive ranges where 1 is added to the
+upper bound, e.g., `x..(y+1)`.
+
+### Why is this bad?
+The code is more readable with an inclusive range
+like `x..=y`.
+
+### Known problems
+Will add unnecessary pair of parentheses when the
+expression is not wrapped in a pair but starts with an opening parenthesis
+and ends with a closing one.
+I.e., `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`.
+
+Also in many cases, inclusive ranges are still slower to run than
+exclusive ranges, because they essentially add an extra branch that
+LLVM may fail to hoist out of the loop.
+
+This will cause a warning that cannot be fixed if the consumer of the
+range only accepts a specific range type, instead of the generic
+`RangeBounds` trait
+([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).
+
+### Example
+```
+for i in x..(y+1) {
+ // ..
+}
+```
+
+Use instead:
+```
+for i in x..=y {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/range_zip_with_len.txt b/src/tools/clippy/src/docs/range_zip_with_len.txt
new file mode 100644
index 000000000..24c1efec7
--- /dev/null
+++ b/src/tools/clippy/src/docs/range_zip_with_len.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for zipping a collection with the range of
+`0.._.len()`.
+
+### Why is this bad?
+The code is better expressed with `.enumerate()`.
+
+### Example
+```
+let _ = x.iter().zip(0..x.len());
+```
+
+Use instead:
+```
+let _ = x.iter().enumerate();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rc_buffer.txt b/src/tools/clippy/src/docs/rc_buffer.txt
new file mode 100644
index 000000000..82ac58eeb
--- /dev/null
+++ b/src/tools/clippy/src/docs/rc_buffer.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`.
+
+### Why is this bad?
+Expressions such as `Rc<String>` usually have no advantage over `Rc<str>`, since
+it is larger and involves an extra level of indirection, and doesn't implement `Borrow<str>`.
+
+While mutating a buffer type would still be possible with `Rc::get_mut()`, it only
+works if there are no additional references yet, which usually defeats the purpose of
+enclosing it in a shared ownership type. Instead, additionally wrapping the inner
+type with an interior mutable container (such as `RefCell` or `Mutex`) would normally
+be used.
+
+### Known problems
+This pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for
+cases where mutation only happens before there are any additional references.
+
+### Example
+```
+fn foo(interned: Rc<String>) { ... }
+```
+
+Better:
+
+```
+fn foo(interned: Rc<str>) { ... }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rc_clone_in_vec_init.txt b/src/tools/clippy/src/docs/rc_clone_in_vec_init.txt
new file mode 100644
index 000000000..6fc08aaf9
--- /dev/null
+++ b/src/tools/clippy/src/docs/rc_clone_in_vec_init.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`)
+in `vec![elem; len]`
+
+### Why is this bad?
+This will create `elem` once and clone it `len` times - doing so with `Arc`/`Rc`/`Weak`
+is a bit misleading, as it will create references to the same pointer, rather
+than different instances.
+
+### Example
+```
+let v = vec![std::sync::Arc::new("some data".to_string()); 100];
+// or
+let v = vec![std::rc::Rc::new("some data".to_string()); 100];
+```
+Use instead:
+```
+// Initialize each value separately:
+let mut data = Vec::with_capacity(100);
+for _ in 0..100 {
+ data.push(std::rc::Rc::new("some data".to_string()));
+}
+
+// Or if you want clones of the same reference,
+// Create the reference beforehand to clarify that
+// it should be cloned for each value
+let data = std::rc::Rc::new("some data".to_string());
+let v = vec![data; 100];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rc_mutex.txt b/src/tools/clippy/src/docs/rc_mutex.txt
new file mode 100644
index 000000000..ed7a1e344
--- /dev/null
+++ b/src/tools/clippy/src/docs/rc_mutex.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for `Rc<Mutex<T>>`.
+
+### Why is this bad?
+`Rc` is used in single thread and `Mutex` is used in multi thread.
+Consider using `Rc<RefCell<T>>` in single thread or `Arc<Mutex<T>>` in multi thread.
+
+### Known problems
+Sometimes combining generic types can lead to the requirement that a
+type use Rc in conjunction with Mutex. We must consider those cases false positives, but
+alas they are quite hard to rule out. Luckily they are also rare.
+
+### Example
+```
+use std::rc::Rc;
+use std::sync::Mutex;
+fn foo(interned: Rc<Mutex<i32>>) { ... }
+```
+
+Better:
+
+```
+use std::rc::Rc;
+use std::cell::RefCell
+fn foo(interned: Rc<RefCell<i32>>) { ... }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/read_zero_byte_vec.txt b/src/tools/clippy/src/docs/read_zero_byte_vec.txt
new file mode 100644
index 000000000..cef5604e0
--- /dev/null
+++ b/src/tools/clippy/src/docs/read_zero_byte_vec.txt
@@ -0,0 +1,30 @@
+### What it does
+This lint catches reads into a zero-length `Vec`.
+Especially in the case of a call to `with_capacity`, this lint warns that read
+gets the number of bytes from the `Vec`'s length, not its capacity.
+
+### Why is this bad?
+Reading zero bytes is almost certainly not the intended behavior.
+
+### Known problems
+In theory, a very unusual read implementation could assign some semantic meaning
+to zero-byte reads. But it seems exceptionally unlikely that code intending to do
+a zero-byte read would allocate a `Vec` for it.
+
+### Example
+```
+use std::io;
+fn foo<F: io::Read>(mut f: F) {
+ let mut data = Vec::with_capacity(100);
+ f.read(&mut data).unwrap();
+}
+```
+Use instead:
+```
+use std::io;
+fn foo<F: io::Read>(mut f: F) {
+ let mut data = Vec::with_capacity(100);
+ data.resize(100, 0);
+ f.read(&mut data).unwrap();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/recursive_format_impl.txt b/src/tools/clippy/src/docs/recursive_format_impl.txt
new file mode 100644
index 000000000..32fffd84c
--- /dev/null
+++ b/src/tools/clippy/src/docs/recursive_format_impl.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for format trait implementations (e.g. `Display`) with a recursive call to itself
+which uses `self` as a parameter.
+This is typically done indirectly with the `write!` macro or with `to_string()`.
+
+### Why is this bad?
+This will lead to infinite recursion and a stack overflow.
+
+### Example
+
+```
+use std::fmt;
+
+struct Structure(i32);
+impl fmt::Display for Structure {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.to_string())
+ }
+}
+
+```
+Use instead:
+```
+use std::fmt;
+
+struct Structure(i32);
+impl fmt::Display for Structure {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.0)
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_allocation.txt b/src/tools/clippy/src/docs/redundant_allocation.txt
new file mode 100644
index 000000000..86bf51e8d
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_allocation.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for use of redundant allocations anywhere in the code.
+
+### Why is this bad?
+Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, `Arc<&T>`, `Arc<Rc<T>>`,
+`Arc<Arc<T>>`, `Arc<Box<T>>`, `Box<&T>`, `Box<Rc<T>>`, `Box<Arc<T>>`, `Box<Box<T>>`, add an unnecessary level of indirection.
+
+### Example
+```
+fn foo(bar: Rc<&usize>) {}
+```
+
+Better:
+
+```
+fn foo(bar: &usize) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_clone.txt b/src/tools/clippy/src/docs/redundant_clone.txt
new file mode 100644
index 000000000..b29aed0b5
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_clone.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for a redundant `clone()` (and its relatives) which clones an owned
+value that is going to be dropped without further use.
+
+### Why is this bad?
+It is not always possible for the compiler to eliminate useless
+allocations and deallocations generated by redundant `clone()`s.
+
+### Known problems
+False-negatives: analysis performed by this lint is conservative and limited.
+
+### Example
+```
+{
+ let x = Foo::new();
+ call(x.clone());
+ call(x.clone()); // this can just pass `x`
+}
+
+["lorem", "ipsum"].join(" ").to_string();
+
+Path::new("/a/b").join("c").to_path_buf();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_closure.txt b/src/tools/clippy/src/docs/redundant_closure.txt
new file mode 100644
index 000000000..0faa9513f
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_closure.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for closures which just call another function where
+the function can be called directly. `unsafe` functions or calls where types
+get adjusted are ignored.
+
+### Why is this bad?
+Needlessly creating a closure adds code for no benefit
+and gives the optimizer more work.
+
+### Known problems
+If creating the closure inside the closure has a side-
+effect then moving the closure creation out will change when that side-
+effect runs.
+See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details.
+
+### Example
+```
+xs.map(|x| foo(x))
+```
+
+Use instead:
+```
+// where `foo(_)` is a plain function that takes the exact argument type of `x`.
+xs.map(foo)
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_closure_call.txt b/src/tools/clippy/src/docs/redundant_closure_call.txt
new file mode 100644
index 000000000..913d1a705
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_closure_call.txt
@@ -0,0 +1,17 @@
+### What it does
+Detects closures called in the same expression where they
+are defined.
+
+### Why is this bad?
+It is unnecessarily adding to the expression's
+complexity.
+
+### Example
+```
+let a = (|| 42)();
+```
+
+Use instead:
+```
+let a = 42;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt b/src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt
new file mode 100644
index 000000000..865510e14
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for closures which only invoke a method on the closure
+argument and can be replaced by referencing the method directly.
+
+### Why is this bad?
+It's unnecessary to create the closure.
+
+### Example
+```
+Some('a').map(|s| s.to_uppercase());
+```
+may be rewritten as
+```
+Some('a').map(char::to_uppercase);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_else.txt b/src/tools/clippy/src/docs/redundant_else.txt
new file mode 100644
index 000000000..3f4e86917
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_else.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for `else` blocks that can be removed without changing semantics.
+
+### Why is this bad?
+The `else` block adds unnecessary indentation and verbosity.
+
+### Known problems
+Some may prefer to keep the `else` block for clarity.
+
+### Example
+```
+fn my_func(count: u32) {
+ if count == 0 {
+ print!("Nothing to do");
+ return;
+ } else {
+ print!("Moving on...");
+ }
+}
+```
+Use instead:
+```
+fn my_func(count: u32) {
+ if count == 0 {
+ print!("Nothing to do");
+ return;
+ }
+ print!("Moving on...");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_feature_names.txt b/src/tools/clippy/src/docs/redundant_feature_names.txt
new file mode 100644
index 000000000..5bd6925ed
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_feature_names.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for feature names with prefix `use-`, `with-` or suffix `-support`
+
+### Why is this bad?
+These prefixes and suffixes have no significant meaning.
+
+### Example
+```
+[features]
+default = ["use-abc", "with-def", "ghi-support"]
+use-abc = [] // redundant
+with-def = [] // redundant
+ghi-support = [] // redundant
+```
+
+Use instead:
+```
+[features]
+default = ["abc", "def", "ghi"]
+abc = []
+def = []
+ghi = []
+```
diff --git a/src/tools/clippy/src/docs/redundant_field_names.txt b/src/tools/clippy/src/docs/redundant_field_names.txt
new file mode 100644
index 000000000..35f20a466
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_field_names.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for fields in struct literals where shorthands
+could be used.
+
+### Why is this bad?
+If the field and variable names are the same,
+the field name is redundant.
+
+### Example
+```
+let bar: u8 = 123;
+
+struct Foo {
+ bar: u8,
+}
+
+let foo = Foo { bar: bar };
+```
+the last line can be simplified to
+```
+let foo = Foo { bar };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_pattern.txt b/src/tools/clippy/src/docs/redundant_pattern.txt
new file mode 100644
index 000000000..45f6cfc86
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_pattern.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for patterns in the form `name @ _`.
+
+### Why is this bad?
+It's almost always more readable to just use direct
+bindings.
+
+### Example
+```
+match v {
+ Some(x) => (),
+ y @ _ => (),
+}
+```
+
+Use instead:
+```
+match v {
+ Some(x) => (),
+ y => (),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_pattern_matching.txt b/src/tools/clippy/src/docs/redundant_pattern_matching.txt
new file mode 100644
index 000000000..77b1021e0
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_pattern_matching.txt
@@ -0,0 +1,45 @@
+### What it does
+Lint for redundant pattern matching over `Result`, `Option`,
+`std::task::Poll` or `std::net::IpAddr`
+
+### Why is this bad?
+It's more concise and clear to just use the proper
+utility function
+
+### Known problems
+This will change the drop order for the matched type. Both `if let` and
+`while let` will drop the value at the end of the block, both `if` and `while` will drop the
+value before entering the block. For most types this change will not matter, but for a few
+types this will not be an acceptable change (e.g. locks). See the
+[reference](https://doc.rust-lang.org/reference/destructors.html#drop-scopes) for more about
+drop order.
+
+### Example
+```
+if let Ok(_) = Ok::<i32, i32>(42) {}
+if let Err(_) = Err::<i32, i32>(42) {}
+if let None = None::<()> {}
+if let Some(_) = Some(42) {}
+if let Poll::Pending = Poll::Pending::<()> {}
+if let Poll::Ready(_) = Poll::Ready(42) {}
+if let IpAddr::V4(_) = IpAddr::V4(Ipv4Addr::LOCALHOST) {}
+if let IpAddr::V6(_) = IpAddr::V6(Ipv6Addr::LOCALHOST) {}
+match Ok::<i32, i32>(42) {
+ Ok(_) => true,
+ Err(_) => false,
+};
+```
+
+The more idiomatic use would be:
+
+```
+if Ok::<i32, i32>(42).is_ok() {}
+if Err::<i32, i32>(42).is_err() {}
+if None::<()>.is_none() {}
+if Some(42).is_some() {}
+if Poll::Pending::<()>.is_pending() {}
+if Poll::Ready(42).is_ready() {}
+if IpAddr::V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
+if IpAddr::V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
+Ok::<i32, i32>(42).is_ok();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_pub_crate.txt b/src/tools/clippy/src/docs/redundant_pub_crate.txt
new file mode 100644
index 000000000..a527bb5ac
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_pub_crate.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for items declared `pub(crate)` that are not crate visible because they
+are inside a private module.
+
+### Why is this bad?
+Writing `pub(crate)` is misleading when it's redundant due to the parent
+module's visibility.
+
+### Example
+```
+mod internal {
+ pub(crate) fn internal_fn() { }
+}
+```
+This function is not visible outside the module and it can be declared with `pub` or
+private visibility
+```
+mod internal {
+ pub fn internal_fn() { }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_slicing.txt b/src/tools/clippy/src/docs/redundant_slicing.txt
new file mode 100644
index 000000000..6798911ed
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_slicing.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for redundant slicing expressions which use the full range, and
+do not change the type.
+
+### Why is this bad?
+It unnecessarily adds complexity to the expression.
+
+### Known problems
+If the type being sliced has an implementation of `Index<RangeFull>`
+that actually changes anything then it can't be removed. However, this would be surprising
+to people reading the code and should have a note with it.
+
+### Example
+```
+fn get_slice(x: &[u32]) -> &[u32] {
+ &x[..]
+}
+```
+Use instead:
+```
+fn get_slice(x: &[u32]) -> &[u32] {
+ x
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_static_lifetimes.txt b/src/tools/clippy/src/docs/redundant_static_lifetimes.txt
new file mode 100644
index 000000000..edb8e7b5c
--- /dev/null
+++ b/src/tools/clippy/src/docs/redundant_static_lifetimes.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for constants and statics with an explicit `'static` lifetime.
+
+### Why is this bad?
+Adding `'static` to every reference can create very
+complicated types.
+
+### Example
+```
+const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =
+&[...]
+static FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =
+&[...]
+```
+This code can be rewritten as
+```
+ const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]
+ static FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ref_binding_to_reference.txt b/src/tools/clippy/src/docs/ref_binding_to_reference.txt
new file mode 100644
index 000000000..dc391cd98
--- /dev/null
+++ b/src/tools/clippy/src/docs/ref_binding_to_reference.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for `ref` bindings which create a reference to a reference.
+
+### Why is this bad?
+The address-of operator at the use site is clearer about the need for a reference.
+
+### Example
+```
+let x = Some("");
+if let Some(ref x) = x {
+ // use `x` here
+}
+```
+
+Use instead:
+```
+let x = Some("");
+if let Some(x) = x {
+ // use `&x` here
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ref_option_ref.txt b/src/tools/clippy/src/docs/ref_option_ref.txt
new file mode 100644
index 000000000..951c7bd7f
--- /dev/null
+++ b/src/tools/clippy/src/docs/ref_option_ref.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for usage of `&Option<&T>`.
+
+### Why is this bad?
+Since `&` is Copy, it's useless to have a
+reference on `Option<&T>`.
+
+### Known problems
+It may be irrelevant to use this lint on
+public API code as it will make a breaking change to apply it.
+
+### Example
+```
+let x: &Option<&u32> = &Some(&0u32);
+```
+Use instead:
+```
+let x: Option<&u32> = Some(&0u32);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/repeat_once.txt b/src/tools/clippy/src/docs/repeat_once.txt
new file mode 100644
index 000000000..3ba189c19
--- /dev/null
+++ b/src/tools/clippy/src/docs/repeat_once.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for usage of `.repeat(1)` and suggest the following method for each types.
+- `.to_string()` for `str`
+- `.clone()` for `String`
+- `.to_vec()` for `slice`
+
+The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if
+they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))
+
+### Why is this bad?
+For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning
+the string is the intention behind this, `clone()` should be used.
+
+### Example
+```
+fn main() {
+ let x = String::from("hello world").repeat(1);
+}
+```
+Use instead:
+```
+fn main() {
+ let x = String::from("hello world").clone();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt b/src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt
new file mode 100644
index 000000000..40ebbe754
--- /dev/null
+++ b/src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched.
+
+### Why is this bad?
+Correctness and readability. It's like having a wildcard pattern after
+matching all enum variants explicitly.
+
+### Example
+```
+let a = A { a: 5 };
+
+match a {
+ A { a: 5, .. } => {},
+ _ => {},
+}
+```
+
+Use instead:
+```
+match a {
+ A { a: 5 } => {},
+ _ => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_large_err.txt b/src/tools/clippy/src/docs/result_large_err.txt
new file mode 100644
index 000000000..e5fab3c5c
--- /dev/null
+++ b/src/tools/clippy/src/docs/result_large_err.txt
@@ -0,0 +1,36 @@
+### What it does
+Checks for functions that return `Result` with an unusually large
+`Err`-variant.
+
+### Why is this bad?
+A `Result` is at least as large as the `Err`-variant. While we
+expect that variant to be seldomly used, the compiler needs to reserve
+and move that much memory every single time.
+
+### Known problems
+The size determined by Clippy is platform-dependent.
+
+### Examples
+```
+pub enum ParseError {
+ UnparsedBytes([u8; 512]),
+ UnexpectedEof,
+}
+
+// The `Result` has at least 512 bytes, even in the `Ok`-case
+pub fn parse() -> Result<(), ParseError> {
+ Ok(())
+}
+```
+should be
+```
+pub enum ParseError {
+ UnparsedBytes(Box<[u8; 512]>),
+ UnexpectedEof,
+}
+
+// The `Result` is slightly larger than a pointer
+pub fn parse() -> Result<(), ParseError> {
+ Ok(())
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_map_or_into_option.txt b/src/tools/clippy/src/docs/result_map_or_into_option.txt
new file mode 100644
index 000000000..899d98c30
--- /dev/null
+++ b/src/tools/clippy/src/docs/result_map_or_into_option.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of `_.map_or(None, Some)`.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.ok()`.
+
+### Example
+```
+assert_eq!(Some(1), r.map_or(None, Some));
+```
+
+Use instead:
+```
+assert_eq!(Some(1), r.ok());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_map_unit_fn.txt b/src/tools/clippy/src/docs/result_map_unit_fn.txt
new file mode 100644
index 000000000..3455c5c1f
--- /dev/null
+++ b/src/tools/clippy/src/docs/result_map_unit_fn.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for usage of `result.map(f)` where f is a function
+or closure that returns the unit type `()`.
+
+### Why is this bad?
+Readability, this can be written more clearly with
+an if let statement
+
+### Example
+```
+let x: Result<String, String> = do_stuff();
+x.map(log_err_msg);
+x.map(|msg| log_err_msg(format_msg(msg)));
+```
+
+The correct use would be:
+
+```
+let x: Result<String, String> = do_stuff();
+if let Ok(msg) = x {
+ log_err_msg(msg);
+};
+if let Ok(msg) = x {
+ log_err_msg(format_msg(msg));
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_unit_err.txt b/src/tools/clippy/src/docs/result_unit_err.txt
new file mode 100644
index 000000000..7c8ec2ffc
--- /dev/null
+++ b/src/tools/clippy/src/docs/result_unit_err.txt
@@ -0,0 +1,40 @@
+### What it does
+Checks for public functions that return a `Result`
+with an `Err` type of `()`. It suggests using a custom type that
+implements `std::error::Error`.
+
+### Why is this bad?
+Unit does not implement `Error` and carries no
+further information about what went wrong.
+
+### Known problems
+Of course, this lint assumes that `Result` is used
+for a fallible operation (which is after all the intended use). However
+code may opt to (mis)use it as a basic two-variant-enum. In that case,
+the suggestion is misguided, and the code should use a custom enum
+instead.
+
+### Examples
+```
+pub fn read_u8() -> Result<u8, ()> { Err(()) }
+```
+should become
+```
+use std::fmt;
+
+#[derive(Debug)]
+pub struct EndOfStream;
+
+impl fmt::Display for EndOfStream {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "End of Stream")
+ }
+}
+
+impl std::error::Error for EndOfStream { }
+
+pub fn read_u8() -> Result<u8, EndOfStream> { Err(EndOfStream) }
+```
+
+Note that there are crates that simplify creating the error type, e.g.
+[`thiserror`](https://docs.rs/thiserror). \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/return_self_not_must_use.txt b/src/tools/clippy/src/docs/return_self_not_must_use.txt
new file mode 100644
index 000000000..4a4fd2c6e
--- /dev/null
+++ b/src/tools/clippy/src/docs/return_self_not_must_use.txt
@@ -0,0 +1,46 @@
+### What it does
+This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute.
+
+### Why is this bad?
+Methods returning `Self` often create new values, having the `#[must_use]` attribute
+prevents users from "forgetting" to use the newly created value.
+
+The `#[must_use]` attribute can be added to the type itself to ensure that instances
+are never forgotten. Functions returning a type marked with `#[must_use]` will not be
+linted, as the usage is already enforced by the type attribute.
+
+### Limitations
+This lint is only applied on methods taking a `self` argument. It would be mostly noise
+if it was added on constructors for example.
+
+### Example
+```
+pub struct Bar;
+impl Bar {
+ // Missing attribute
+ pub fn bar(&self) -> Self {
+ Self
+ }
+}
+```
+
+Use instead:
+```
+// It's better to have the `#[must_use]` attribute on the method like this:
+pub struct Bar;
+impl Bar {
+ #[must_use]
+ pub fn bar(&self) -> Self {
+ Self
+ }
+}
+
+// Or on the type definition like this:
+#[must_use]
+pub struct Bar;
+impl Bar {
+ pub fn bar(&self) -> Self {
+ Self
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/reversed_empty_ranges.txt b/src/tools/clippy/src/docs/reversed_empty_ranges.txt
new file mode 100644
index 000000000..39f481193
--- /dev/null
+++ b/src/tools/clippy/src/docs/reversed_empty_ranges.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for range expressions `x..y` where both `x` and `y`
+are constant and `x` is greater or equal to `y`.
+
+### Why is this bad?
+Empty ranges yield no values so iterating them is a no-op.
+Moreover, trying to use a reversed range to index a slice will panic at run-time.
+
+### Example
+```
+fn main() {
+ (10..=0).for_each(|x| println!("{}", x));
+
+ let arr = [1, 2, 3, 4, 5];
+ let sub = &arr[3..1];
+}
+```
+Use instead:
+```
+fn main() {
+ (0..=10).rev().for_each(|x| println!("{}", x));
+
+ let arr = [1, 2, 3, 4, 5];
+ let sub = &arr[1..3];
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/same_functions_in_if_condition.txt b/src/tools/clippy/src/docs/same_functions_in_if_condition.txt
new file mode 100644
index 000000000..a0a90eec6
--- /dev/null
+++ b/src/tools/clippy/src/docs/same_functions_in_if_condition.txt
@@ -0,0 +1,41 @@
+### What it does
+Checks for consecutive `if`s with the same function call.
+
+### Why is this bad?
+This is probably a copy & paste error.
+Despite the fact that function can have side effects and `if` works as
+intended, such an approach is implicit and can be considered a "code smell".
+
+### Example
+```
+if foo() == bar {
+ …
+} else if foo() == bar {
+ …
+}
+```
+
+This probably should be:
+```
+if foo() == bar {
+ …
+} else if foo() == baz {
+ …
+}
+```
+
+or if the original code was not a typo and called function mutates a state,
+consider move the mutation out of the `if` condition to avoid similarity to
+a copy & paste error:
+
+```
+let first = foo();
+if first == bar {
+ …
+} else {
+ let second = foo();
+ if second == bar {
+ …
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/same_item_push.txt b/src/tools/clippy/src/docs/same_item_push.txt
new file mode 100644
index 000000000..7e724073f
--- /dev/null
+++ b/src/tools/clippy/src/docs/same_item_push.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks whether a for loop is being used to push a constant
+value into a Vec.
+
+### Why is this bad?
+This kind of operation can be expressed more succinctly with
+`vec![item; SIZE]` or `vec.resize(NEW_SIZE, item)` and using these alternatives may also
+have better performance.
+
+### Example
+```
+let item1 = 2;
+let item2 = 3;
+let mut vec: Vec<u8> = Vec::new();
+for _ in 0..20 {
+ vec.push(item1);
+}
+for _ in 0..30 {
+ vec.push(item2);
+}
+```
+
+Use instead:
+```
+let item1 = 2;
+let item2 = 3;
+let mut vec: Vec<u8> = vec![item1; 20];
+vec.resize(20 + 30, item2);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/same_name_method.txt b/src/tools/clippy/src/docs/same_name_method.txt
new file mode 100644
index 000000000..792dd717f
--- /dev/null
+++ b/src/tools/clippy/src/docs/same_name_method.txt
@@ -0,0 +1,23 @@
+### What it does
+It lints if a struct has two methods with the same name:
+one from a trait, another not from trait.
+
+### Why is this bad?
+Confusing.
+
+### Example
+```
+trait T {
+ fn foo(&self) {}
+}
+
+struct S;
+
+impl T for S {
+ fn foo(&self) {}
+}
+
+impl S {
+ fn foo(&self) {}
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/search_is_some.txt b/src/tools/clippy/src/docs/search_is_some.txt
new file mode 100644
index 000000000..67292d545
--- /dev/null
+++ b/src/tools/clippy/src/docs/search_is_some.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for an iterator or string search (such as `find()`,
+`position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`.
+
+### Why is this bad?
+Readability, this can be written more concisely as:
+* `_.any(_)`, or `_.contains(_)` for `is_some()`,
+* `!_.any(_)`, or `!_.contains(_)` for `is_none()`.
+
+### Example
+```
+let vec = vec![1];
+vec.iter().find(|x| **x == 0).is_some();
+
+"hello world".find("world").is_none();
+```
+
+Use instead:
+```
+let vec = vec![1];
+vec.iter().any(|x| *x == 0);
+
+!"hello world".contains("world");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/self_assignment.txt b/src/tools/clippy/src/docs/self_assignment.txt
new file mode 100644
index 000000000..ea60ea077
--- /dev/null
+++ b/src/tools/clippy/src/docs/self_assignment.txt
@@ -0,0 +1,32 @@
+### What it does
+Checks for explicit self-assignments.
+
+### Why is this bad?
+Self-assignments are redundant and unlikely to be
+intentional.
+
+### Known problems
+If expression contains any deref coercions or
+indexing operations they are assumed not to have any side effects.
+
+### Example
+```
+struct Event {
+ x: i32,
+}
+
+fn copy_position(a: &mut Event, b: &Event) {
+ a.x = a.x;
+}
+```
+
+Should be:
+```
+struct Event {
+ x: i32,
+}
+
+fn copy_position(a: &mut Event, b: &Event) {
+ a.x = b.x;
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/self_named_constructors.txt b/src/tools/clippy/src/docs/self_named_constructors.txt
new file mode 100644
index 000000000..a01669a84
--- /dev/null
+++ b/src/tools/clippy/src/docs/self_named_constructors.txt
@@ -0,0 +1,26 @@
+### What it does
+Warns when constructors have the same name as their types.
+
+### Why is this bad?
+Repeating the name of the type is redundant.
+
+### Example
+```
+struct Foo {}
+
+impl Foo {
+ pub fn foo() -> Foo {
+ Foo {}
+ }
+}
+```
+Use instead:
+```
+struct Foo {}
+
+impl Foo {
+ pub fn new() -> Foo {
+ Foo {}
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/self_named_module_files.txt b/src/tools/clippy/src/docs/self_named_module_files.txt
new file mode 100644
index 000000000..73e805136
--- /dev/null
+++ b/src/tools/clippy/src/docs/self_named_module_files.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks that module layout uses only `mod.rs` files.
+
+### Why is this bad?
+Having multiple module layout styles in a project can be confusing.
+
+### Example
+```
+src/
+ stuff/
+ stuff_files.rs
+ stuff.rs
+ lib.rs
+```
+Use instead:
+```
+src/
+ stuff/
+ stuff_files.rs
+ mod.rs
+ lib.rs
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt b/src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt
new file mode 100644
index 000000000..30c963ca2
--- /dev/null
+++ b/src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt
@@ -0,0 +1,20 @@
+### What it does
+Looks for blocks of expressions and fires if the last expression returns
+`()` but is not followed by a semicolon.
+
+### Why is this bad?
+The semicolon might be optional but when extending the block with new
+code, it doesn't require a change in previous last line.
+
+### Example
+```
+fn main() {
+ println!("Hello world")
+}
+```
+Use instead:
+```
+fn main() {
+ println!("Hello world");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/separated_literal_suffix.txt b/src/tools/clippy/src/docs/separated_literal_suffix.txt
new file mode 100644
index 000000000..226a6b8a9
--- /dev/null
+++ b/src/tools/clippy/src/docs/separated_literal_suffix.txt
@@ -0,0 +1,17 @@
+### What it does
+Warns if literal suffixes are separated by an underscore.
+To enforce separated literal suffix style,
+see the `unseparated_literal_suffix` lint.
+
+### Why is this bad?
+Suffix style should be consistent.
+
+### Example
+```
+123832_i32
+```
+
+Use instead:
+```
+123832i32
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/serde_api_misuse.txt b/src/tools/clippy/src/docs/serde_api_misuse.txt
new file mode 100644
index 000000000..8a3c89ac1
--- /dev/null
+++ b/src/tools/clippy/src/docs/serde_api_misuse.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for mis-uses of the serde API.
+
+### Why is this bad?
+Serde is very finnicky about how its API should be
+used, but the type system can't be used to enforce it (yet?).
+
+### Example
+Implementing `Visitor::visit_string` but not
+`Visitor::visit_str`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/shadow_reuse.txt b/src/tools/clippy/src/docs/shadow_reuse.txt
new file mode 100644
index 000000000..9eb8e7ad1
--- /dev/null
+++ b/src/tools/clippy/src/docs/shadow_reuse.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for bindings that shadow other bindings already in
+scope, while reusing the original value.
+
+### Why is this bad?
+Not too much, in fact it's a common pattern in Rust
+code. Still, some argue that name shadowing like this hurts readability,
+because a value may be bound to different things depending on position in
+the code.
+
+### Example
+```
+let x = 2;
+let x = x + 1;
+```
+use different variable name:
+```
+let x = 2;
+let y = x + 1;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/shadow_same.txt b/src/tools/clippy/src/docs/shadow_same.txt
new file mode 100644
index 000000000..3cd96f560
--- /dev/null
+++ b/src/tools/clippy/src/docs/shadow_same.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for bindings that shadow other bindings already in
+scope, while just changing reference level or mutability.
+
+### Why is this bad?
+Not much, in fact it's a very common pattern in Rust
+code. Still, some may opt to avoid it in their code base, they can set this
+lint to `Warn`.
+
+### Example
+```
+let x = &x;
+```
+
+Use instead:
+```
+let y = &x; // use different variable name
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/shadow_unrelated.txt b/src/tools/clippy/src/docs/shadow_unrelated.txt
new file mode 100644
index 000000000..436251c52
--- /dev/null
+++ b/src/tools/clippy/src/docs/shadow_unrelated.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for bindings that shadow other bindings already in
+scope, either without an initialization or with one that does not even use
+the original value.
+
+### Why is this bad?
+Name shadowing can hurt readability, especially in
+large code bases, because it is easy to lose track of the active binding at
+any place in the code. This can be alleviated by either giving more specific
+names to bindings or introducing more scopes to contain the bindings.
+
+### Example
+```
+let x = y;
+let x = z; // shadows the earlier binding
+```
+
+Use instead:
+```
+let x = y;
+let w = z; // use different variable name
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/short_circuit_statement.txt b/src/tools/clippy/src/docs/short_circuit_statement.txt
new file mode 100644
index 000000000..31492bed0
--- /dev/null
+++ b/src/tools/clippy/src/docs/short_circuit_statement.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for the use of short circuit boolean conditions as
+a
+statement.
+
+### Why is this bad?
+Using a short circuit boolean condition as a statement
+may hide the fact that the second part is executed or not depending on the
+outcome of the first part.
+
+### Example
+```
+f() && g(); // We should write `if f() { g(); }`.
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/should_implement_trait.txt b/src/tools/clippy/src/docs/should_implement_trait.txt
new file mode 100644
index 000000000..02e74751a
--- /dev/null
+++ b/src/tools/clippy/src/docs/should_implement_trait.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for methods that should live in a trait
+implementation of a `std` trait (see [llogiq's blog
+post](http://llogiq.github.io/2015/07/30/traits.html) for further
+information) instead of an inherent implementation.
+
+### Why is this bad?
+Implementing the traits improve ergonomics for users of
+the code, often with very little cost. Also people seeing a `mul(...)`
+method
+may expect `*` to work equally, so you should have good reason to disappoint
+them.
+
+### Example
+```
+struct X;
+impl X {
+ fn add(&self, other: &X) -> X {
+ // ..
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt b/src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt
new file mode 100644
index 000000000..f869def0d
--- /dev/null
+++ b/src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt
@@ -0,0 +1,43 @@
+### What it does
+Check for temporaries returned from function calls in a match scrutinee that have the
+`clippy::has_significant_drop` attribute.
+
+### Why is this bad?
+The `clippy::has_significant_drop` attribute can be added to types whose Drop impls have
+an important side-effect, such as unlocking a mutex, making it important for users to be
+able to accurately understand their lifetimes. When a temporary is returned in a function
+call in a match scrutinee, its lifetime lasts until the end of the match block, which may
+be surprising.
+
+For `Mutex`es this can lead to a deadlock. This happens when the match scrutinee uses a
+function call that returns a `MutexGuard` and then tries to lock again in one of the match
+arms. In that case the `MutexGuard` in the scrutinee will not be dropped until the end of
+the match block and thus will not unlock.
+
+### Example
+```
+let mutex = Mutex::new(State {});
+
+match mutex.lock().unwrap().foo() {
+ true => {
+ mutex.lock().unwrap().bar(); // Deadlock!
+ }
+ false => {}
+};
+
+println!("All done!");
+```
+Use instead:
+```
+let mutex = Mutex::new(State {});
+
+let is_foo = mutex.lock().unwrap().foo();
+match is_foo {
+ true => {
+ mutex.lock().unwrap().bar();
+ }
+ false => {}
+};
+
+println!("All done!");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/similar_names.txt b/src/tools/clippy/src/docs/similar_names.txt
new file mode 100644
index 000000000..13aca9c0b
--- /dev/null
+++ b/src/tools/clippy/src/docs/similar_names.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for names that are very similar and thus confusing.
+
+### Why is this bad?
+It's hard to distinguish between names that differ only
+by a single character.
+
+### Example
+```
+let checked_exp = something;
+let checked_expr = something_else;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_char_add_str.txt b/src/tools/clippy/src/docs/single_char_add_str.txt
new file mode 100644
index 000000000..cf23dc0c8
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_char_add_str.txt
@@ -0,0 +1,18 @@
+### What it does
+Warns when using `push_str`/`insert_str` with a single-character string literal
+where `push`/`insert` with a `char` would work fine.
+
+### Why is this bad?
+It's less clear that we are pushing a single character.
+
+### Example
+```
+string.insert_str(0, "R");
+string.push_str("R");
+```
+
+Use instead:
+```
+string.insert(0, 'R');
+string.push('R');
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_char_lifetime_names.txt b/src/tools/clippy/src/docs/single_char_lifetime_names.txt
new file mode 100644
index 000000000..92dd24bf2
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_char_lifetime_names.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for lifetimes with names which are one character
+long.
+
+### Why is this bad?
+A single character is likely not enough to express the
+purpose of a lifetime. Using a longer name can make code
+easier to understand, especially for those who are new to
+Rust.
+
+### Known problems
+Rust programmers and learning resources tend to use single
+character lifetimes, so this lint is at odds with the
+ecosystem at large. In addition, the lifetime's purpose may
+be obvious or, rarely, expressible in one character.
+
+### Example
+```
+struct DiagnosticCtx<'a> {
+ source: &'a str,
+}
+```
+Use instead:
+```
+struct DiagnosticCtx<'src> {
+ source: &'src str,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_char_pattern.txt b/src/tools/clippy/src/docs/single_char_pattern.txt
new file mode 100644
index 000000000..9e5ad1e7d
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_char_pattern.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for string methods that receive a single-character
+`str` as an argument, e.g., `_.split("x")`.
+
+### Why is this bad?
+Performing these methods using a `char` is faster than
+using a `str`.
+
+### Known problems
+Does not catch multi-byte unicode characters.
+
+### Example
+```
+_.split("x");
+```
+
+Use instead:
+```
+_.split('x');
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_component_path_imports.txt b/src/tools/clippy/src/docs/single_component_path_imports.txt
new file mode 100644
index 000000000..3a0263881
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_component_path_imports.txt
@@ -0,0 +1,21 @@
+### What it does
+Checking for imports with single component use path.
+
+### Why is this bad?
+Import with single component use path such as `use cratename;`
+is not necessary, and thus should be removed.
+
+### Example
+```
+use regex;
+
+fn main() {
+ regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
+}
+```
+Better as
+```
+fn main() {
+ regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_element_loop.txt b/src/tools/clippy/src/docs/single_element_loop.txt
new file mode 100644
index 000000000..6f0c15a85
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_element_loop.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks whether a for loop has a single element.
+
+### Why is this bad?
+There is no reason to have a loop of a
+single element.
+
+### Example
+```
+let item1 = 2;
+for item in &[item1] {
+ println!("{}", item);
+}
+```
+
+Use instead:
+```
+let item1 = 2;
+let item = &item1;
+println!("{}", item);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_match.txt b/src/tools/clippy/src/docs/single_match.txt
new file mode 100644
index 000000000..31dde4da8
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_match.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for matches with a single arm where an `if let`
+will usually suffice.
+
+### Why is this bad?
+Just readability – `if let` nests less than a `match`.
+
+### Example
+```
+match x {
+ Some(ref foo) => bar(foo),
+ _ => (),
+}
+```
+
+Use instead:
+```
+if let Some(ref foo) = x {
+ bar(foo);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_match_else.txt b/src/tools/clippy/src/docs/single_match_else.txt
new file mode 100644
index 000000000..29a447af0
--- /dev/null
+++ b/src/tools/clippy/src/docs/single_match_else.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for matches with two arms where an `if let else` will
+usually suffice.
+
+### Why is this bad?
+Just readability – `if let` nests less than a `match`.
+
+### Known problems
+Personal style preferences may differ.
+
+### Example
+Using `match`:
+
+```
+match x {
+ Some(ref foo) => bar(foo),
+ _ => bar(&other_ref),
+}
+```
+
+Using `if let` with `else`:
+
+```
+if let Some(ref foo) = x {
+ bar(foo);
+} else {
+ bar(&other_ref);
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/size_of_in_element_count.txt b/src/tools/clippy/src/docs/size_of_in_element_count.txt
new file mode 100644
index 000000000..d893ec6a2
--- /dev/null
+++ b/src/tools/clippy/src/docs/size_of_in_element_count.txt
@@ -0,0 +1,16 @@
+### What it does
+Detects expressions where
+`size_of::<T>` or `size_of_val::<T>` is used as a
+count of elements of type `T`
+
+### Why is this bad?
+These functions expect a count
+of `T` and not a number of bytes
+
+### Example
+```
+const SIZE: usize = 128;
+let x = [2u8; SIZE];
+let mut y = [2u8; SIZE];
+unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/skip_while_next.txt b/src/tools/clippy/src/docs/skip_while_next.txt
new file mode 100644
index 000000000..1ec8a3a28
--- /dev/null
+++ b/src/tools/clippy/src/docs/skip_while_next.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for usage of `_.skip_while(condition).next()`.
+
+### Why is this bad?
+Readability, this can be written more concisely as
+`_.find(!condition)`.
+
+### Example
+```
+vec.iter().skip_while(|x| **x == 0).next();
+```
+
+Use instead:
+```
+vec.iter().find(|x| **x != 0);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/slow_vector_initialization.txt b/src/tools/clippy/src/docs/slow_vector_initialization.txt
new file mode 100644
index 000000000..53442e179
--- /dev/null
+++ b/src/tools/clippy/src/docs/slow_vector_initialization.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks slow zero-filled vector initialization
+
+### Why is this bad?
+These structures are non-idiomatic and less efficient than simply using
+`vec![0; len]`.
+
+### Example
+```
+let mut vec1 = Vec::with_capacity(len);
+vec1.resize(len, 0);
+
+let mut vec1 = Vec::with_capacity(len);
+vec1.resize(vec1.capacity(), 0);
+
+let mut vec2 = Vec::with_capacity(len);
+vec2.extend(repeat(0).take(len));
+```
+
+Use instead:
+```
+let mut vec1 = vec![0; len];
+let mut vec2 = vec![0; len];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/stable_sort_primitive.txt b/src/tools/clippy/src/docs/stable_sort_primitive.txt
new file mode 100644
index 000000000..6465dbee4
--- /dev/null
+++ b/src/tools/clippy/src/docs/stable_sort_primitive.txt
@@ -0,0 +1,31 @@
+### What it does
+When sorting primitive values (integers, bools, chars, as well
+as arrays, slices, and tuples of such items), it is typically better to
+use an unstable sort than a stable sort.
+
+### Why is this bad?
+Typically, using a stable sort consumes more memory and cpu cycles.
+Because values which compare equal are identical, preserving their
+relative order (the guarantee that a stable sort provides) means
+nothing, while the extra costs still apply.
+
+### Known problems
+
+As pointed out in
+[issue #8241](https://github.com/rust-lang/rust-clippy/issues/8241),
+a stable sort can instead be significantly faster for certain scenarios
+(eg. when a sorted vector is extended with new data and resorted).
+
+For more information and benchmarking results, please refer to the
+issue linked above.
+
+### Example
+```
+let mut vec = vec![2, 1, 3];
+vec.sort();
+```
+Use instead:
+```
+let mut vec = vec![2, 1, 3];
+vec.sort_unstable();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/std_instead_of_alloc.txt b/src/tools/clippy/src/docs/std_instead_of_alloc.txt
new file mode 100644
index 000000000..c2d32704e
--- /dev/null
+++ b/src/tools/clippy/src/docs/std_instead_of_alloc.txt
@@ -0,0 +1,18 @@
+### What it does
+
+Finds items imported through `std` when available through `alloc`.
+
+### Why is this bad?
+
+Crates which have `no_std` compatibility and require alloc may wish to ensure types are imported from
+alloc to ensure disabling `std` does not cause the crate to fail to compile. This lint is also useful
+for crates migrating to become `no_std` compatible.
+
+### Example
+```
+use std::vec::Vec;
+```
+Use instead:
+```
+use alloc::vec::Vec;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/std_instead_of_core.txt b/src/tools/clippy/src/docs/std_instead_of_core.txt
new file mode 100644
index 000000000..f1e1518c6
--- /dev/null
+++ b/src/tools/clippy/src/docs/std_instead_of_core.txt
@@ -0,0 +1,18 @@
+### What it does
+
+Finds items imported through `std` when available through `core`.
+
+### Why is this bad?
+
+Crates which have `no_std` compatibility may wish to ensure types are imported from core to ensure
+disabling `std` does not cause the crate to fail to compile. This lint is also useful for crates
+migrating to become `no_std` compatible.
+
+### Example
+```
+use std::hash::Hasher;
+```
+Use instead:
+```
+use core::hash::Hasher;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/str_to_string.txt b/src/tools/clippy/src/docs/str_to_string.txt
new file mode 100644
index 000000000..a24755223
--- /dev/null
+++ b/src/tools/clippy/src/docs/str_to_string.txt
@@ -0,0 +1,18 @@
+### What it does
+This lint checks for `.to_string()` method calls on values of type `&str`.
+
+### Why is this bad?
+The `to_string` method is also used on other types to convert them to a string.
+When called on a `&str` it turns the `&str` into the owned variant `String`, which can be better
+expressed with `.to_owned()`.
+
+### Example
+```
+// example code where clippy issues a warning
+let _ = "str".to_string();
+```
+Use instead:
+```
+// example code which does not raise clippy warning
+let _ = "str".to_owned();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_add.txt b/src/tools/clippy/src/docs/string_add.txt
new file mode 100644
index 000000000..23dafd0d0
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_add.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for all instances of `x + _` where `x` is of type
+`String`, but only if [`string_add_assign`](#string_add_assign) does *not*
+match.
+
+### Why is this bad?
+It's not bad in and of itself. However, this particular
+`Add` implementation is asymmetric (the other operand need not be `String`,
+but `x` does), while addition as mathematically defined is symmetric, also
+the `String::push_str(_)` function is a perfectly good replacement.
+Therefore, some dislike it and wish not to have it in their code.
+
+That said, other people think that string addition, having a long tradition
+in other languages is actually fine, which is why we decided to make this
+particular lint `allow` by default.
+
+### Example
+```
+let x = "Hello".to_owned();
+x + ", World";
+```
+
+Use instead:
+```
+let mut x = "Hello".to_owned();
+x.push_str(", World");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_add_assign.txt b/src/tools/clippy/src/docs/string_add_assign.txt
new file mode 100644
index 000000000..7438be855
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_add_assign.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for string appends of the form `x = x + y` (without
+`let`!).
+
+### Why is this bad?
+It's not really bad, but some people think that the
+`.push_str(_)` method is more readable.
+
+### Example
+```
+let mut x = "Hello".to_owned();
+x = x + ", World";
+
+// More readable
+x += ", World";
+x.push_str(", World");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_extend_chars.txt b/src/tools/clippy/src/docs/string_extend_chars.txt
new file mode 100644
index 000000000..619ea3e11
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_extend_chars.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for the use of `.extend(s.chars())` where s is a
+`&str` or `String`.
+
+### Why is this bad?
+`.push_str(s)` is clearer
+
+### Example
+```
+let abc = "abc";
+let def = String::from("def");
+let mut s = String::new();
+s.extend(abc.chars());
+s.extend(def.chars());
+```
+The correct use would be:
+```
+let abc = "abc";
+let def = String::from("def");
+let mut s = String::new();
+s.push_str(abc);
+s.push_str(&def);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt b/src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt
new file mode 100644
index 000000000..9102d7347
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt
@@ -0,0 +1,15 @@
+### What it does
+Check if the string is transformed to byte array and casted back to string.
+
+### Why is this bad?
+It's unnecessary, the string can be used directly.
+
+### Example
+```
+std::str::from_utf8(&"Hello World!".as_bytes()[6..11]).unwrap();
+```
+
+Use instead:
+```
+&"Hello World!"[6..11];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_lit_as_bytes.txt b/src/tools/clippy/src/docs/string_lit_as_bytes.txt
new file mode 100644
index 000000000..a125b97ed
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_lit_as_bytes.txt
@@ -0,0 +1,39 @@
+### What it does
+Checks for the `as_bytes` method called on string literals
+that contain only ASCII characters.
+
+### Why is this bad?
+Byte string literals (e.g., `b"foo"`) can be used
+instead. They are shorter but less discoverable than `as_bytes()`.
+
+### Known problems
+`"str".as_bytes()` and the suggested replacement of `b"str"` are not
+equivalent because they have different types. The former is `&[u8]`
+while the latter is `&[u8; 3]`. That means in general they will have a
+different set of methods and different trait implementations.
+
+```
+fn f(v: Vec<u8>) {}
+
+f("...".as_bytes().to_owned()); // works
+f(b"...".to_owned()); // does not work, because arg is [u8; 3] not Vec<u8>
+
+fn g(r: impl std::io::Read) {}
+
+g("...".as_bytes()); // works
+g(b"..."); // does not work
+```
+
+The actual equivalent of `"str".as_bytes()` with the same type is not
+`b"str"` but `&b"str"[..]`, which is a great deal of punctuation and not
+more readable than a function call.
+
+### Example
+```
+let bstr = "a byte string".as_bytes();
+```
+
+Use instead:
+```
+let bstr = b"a byte string";
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_slice.txt b/src/tools/clippy/src/docs/string_slice.txt
new file mode 100644
index 000000000..3d9e49dd3
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_slice.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for slice operations on strings
+
+### Why is this bad?
+UTF-8 characters span multiple bytes, and it is easy to inadvertently confuse character
+counts and string indices. This may lead to panics, and should warrant some test cases
+containing wide UTF-8 characters. This lint is most useful in code that should avoid
+panics at all costs.
+
+### Known problems
+Probably lots of false positives. If an index comes from a known valid position (e.g.
+obtained via `char_indices` over the same string), it is totally OK.
+
+# Example
+```
+&"Ölkanne"[1..];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_to_string.txt b/src/tools/clippy/src/docs/string_to_string.txt
new file mode 100644
index 000000000..deb7eebe7
--- /dev/null
+++ b/src/tools/clippy/src/docs/string_to_string.txt
@@ -0,0 +1,19 @@
+### What it does
+This lint checks for `.to_string()` method calls on values of type `String`.
+
+### Why is this bad?
+The `to_string` method is also used on other types to convert them to a string.
+When called on a `String` it only clones the `String`, which can be better expressed with `.clone()`.
+
+### Example
+```
+// example code where clippy issues a warning
+let msg = String::from("Hello World");
+let _ = msg.to_string();
+```
+Use instead:
+```
+// example code which does not raise clippy warning
+let msg = String::from("Hello World");
+let _ = msg.clone();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/strlen_on_c_strings.txt b/src/tools/clippy/src/docs/strlen_on_c_strings.txt
new file mode 100644
index 000000000..0454abf55
--- /dev/null
+++ b/src/tools/clippy/src/docs/strlen_on_c_strings.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for usage of `libc::strlen` on a `CString` or `CStr` value,
+and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead.
+
+### Why is this bad?
+This avoids calling an unsafe `libc` function.
+Currently, it also avoids calculating the length.
+
+### Example
+```
+use std::ffi::CString;
+let cstring = CString::new("foo").expect("CString::new failed");
+let len = unsafe { libc::strlen(cstring.as_ptr()) };
+```
+Use instead:
+```
+use std::ffi::CString;
+let cstring = CString::new("foo").expect("CString::new failed");
+let len = cstring.as_bytes().len();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/struct_excessive_bools.txt b/src/tools/clippy/src/docs/struct_excessive_bools.txt
new file mode 100644
index 000000000..9e197c786
--- /dev/null
+++ b/src/tools/clippy/src/docs/struct_excessive_bools.txt
@@ -0,0 +1,29 @@
+### What it does
+Checks for excessive
+use of bools in structs.
+
+### Why is this bad?
+Excessive bools in a struct
+is often a sign that it's used as a state machine,
+which is much better implemented as an enum.
+If it's not the case, excessive bools usually benefit
+from refactoring into two-variant enums for better
+readability and API.
+
+### Example
+```
+struct S {
+ is_pending: bool,
+ is_processing: bool,
+ is_finished: bool,
+}
+```
+
+Use instead:
+```
+enum S {
+ Pending,
+ Processing,
+ Finished,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suboptimal_flops.txt b/src/tools/clippy/src/docs/suboptimal_flops.txt
new file mode 100644
index 000000000..f1c9c665b
--- /dev/null
+++ b/src/tools/clippy/src/docs/suboptimal_flops.txt
@@ -0,0 +1,50 @@
+### What it does
+Looks for floating-point expressions that
+can be expressed using built-in methods to improve both
+accuracy and performance.
+
+### Why is this bad?
+Negatively impacts accuracy and performance.
+
+### Example
+```
+use std::f32::consts::E;
+
+let a = 3f32;
+let _ = (2f32).powf(a);
+let _ = E.powf(a);
+let _ = a.powf(1.0 / 2.0);
+let _ = a.log(2.0);
+let _ = a.log(10.0);
+let _ = a.log(E);
+let _ = a.powf(2.0);
+let _ = a * 2.0 + 4.0;
+let _ = if a < 0.0 {
+ -a
+} else {
+ a
+};
+let _ = if a < 0.0 {
+ a
+} else {
+ -a
+};
+```
+
+is better expressed as
+
+```
+use std::f32::consts::E;
+
+let a = 3f32;
+let _ = a.exp2();
+let _ = a.exp();
+let _ = a.sqrt();
+let _ = a.log2();
+let _ = a.log10();
+let _ = a.ln();
+let _ = a.powi(2);
+let _ = a.mul_add(2.0, 4.0);
+let _ = a.abs();
+let _ = -a.abs();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt b/src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt
new file mode 100644
index 000000000..d67ff2793
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt
@@ -0,0 +1,17 @@
+### What it does
+Lints for suspicious operations in impls of arithmetic operators, e.g.
+subtracting elements in an Add impl.
+
+### Why is this bad?
+This is probably a typo or copy-and-paste error and not intended.
+
+### Example
+```
+impl Add for Foo {
+ type Output = Foo;
+
+ fn add(self, other: Foo) -> Foo {
+ Foo(self.0 - other.0)
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_assignment_formatting.txt b/src/tools/clippy/src/docs/suspicious_assignment_formatting.txt
new file mode 100644
index 000000000..b889827cd
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_assignment_formatting.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for use of the non-existent `=*`, `=!` and `=-`
+operators.
+
+### Why is this bad?
+This is either a typo of `*=`, `!=` or `-=` or
+confusing.
+
+### Example
+```
+a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_else_formatting.txt b/src/tools/clippy/src/docs/suspicious_else_formatting.txt
new file mode 100644
index 000000000..3cf2f7486
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_else_formatting.txt
@@ -0,0 +1,30 @@
+### What it does
+Checks for formatting of `else`. It lints if the `else`
+is followed immediately by a newline or the `else` seems to be missing.
+
+### Why is this bad?
+This is probably some refactoring remnant, even if the
+code is correct, it might look confusing.
+
+### Example
+```
+if foo {
+} { // looks like an `else` is missing here
+}
+
+if foo {
+} if bar { // looks like an `else` is missing here
+}
+
+if foo {
+} else
+
+{ // this is the `else` block of the previous `if`, but should it be?
+}
+
+if foo {
+} else
+
+if bar { // this is the `else` block of the previous `if`, but should it be?
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_map.txt b/src/tools/clippy/src/docs/suspicious_map.txt
new file mode 100644
index 000000000..d8fa52c43
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_map.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for calls to `map` followed by a `count`.
+
+### Why is this bad?
+It looks suspicious. Maybe `map` was confused with `filter`.
+If the `map` call is intentional, this should be rewritten
+using `inspect`. Or, if you intend to drive the iterator to
+completion, you can just use `for_each` instead.
+
+### Example
+```
+let _ = (0..3).map(|x| x + 2).count();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_op_assign_impl.txt b/src/tools/clippy/src/docs/suspicious_op_assign_impl.txt
new file mode 100644
index 000000000..81abfbeca
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_op_assign_impl.txt
@@ -0,0 +1,15 @@
+### What it does
+Lints for suspicious operations in impls of OpAssign, e.g.
+subtracting elements in an AddAssign impl.
+
+### Why is this bad?
+This is probably a typo or copy-and-paste error and not intended.
+
+### Example
+```
+impl AddAssign for Foo {
+ fn add_assign(&mut self, other: Foo) {
+ *self = *self - other;
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_operation_groupings.txt b/src/tools/clippy/src/docs/suspicious_operation_groupings.txt
new file mode 100644
index 000000000..81ede5d3d
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_operation_groupings.txt
@@ -0,0 +1,41 @@
+### What it does
+Checks for unlikely usages of binary operators that are almost
+certainly typos and/or copy/paste errors, given the other usages
+of binary operators nearby.
+
+### Why is this bad?
+They are probably bugs and if they aren't then they look like bugs
+and you should add a comment explaining why you are doing such an
+odd set of operations.
+
+### Known problems
+There may be some false positives if you are trying to do something
+unusual that happens to look like a typo.
+
+### Example
+```
+struct Vec3 {
+ x: f64,
+ y: f64,
+ z: f64,
+}
+
+impl Eq for Vec3 {}
+
+impl PartialEq for Vec3 {
+ fn eq(&self, other: &Self) -> bool {
+ // This should trigger the lint because `self.x` is compared to `other.y`
+ self.x == other.y && self.y == other.y && self.z == other.z
+ }
+}
+```
+Use instead:
+```
+// same as above except:
+impl PartialEq for Vec3 {
+ fn eq(&self, other: &Self) -> bool {
+ // Note we now compare other.x to self.x
+ self.x == other.x && self.y == other.y && self.z == other.z
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_splitn.txt b/src/tools/clippy/src/docs/suspicious_splitn.txt
new file mode 100644
index 000000000..79a3dbfa6
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_splitn.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for calls to [`splitn`]
+(https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and
+related functions with either zero or one splits.
+
+### Why is this bad?
+These calls don't actually split the value and are
+likely to be intended as a different number.
+
+### Example
+```
+for x in s.splitn(1, ":") {
+ // ..
+}
+```
+
+Use instead:
+```
+for x in s.splitn(2, ":") {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_to_owned.txt b/src/tools/clippy/src/docs/suspicious_to_owned.txt
new file mode 100644
index 000000000..8cbf61dc7
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_to_owned.txt
@@ -0,0 +1,39 @@
+### What it does
+Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`.
+
+### Why is this bad?
+Calling `to_owned()` on a `Cow` creates a clone of the `Cow`
+itself, without taking ownership of the `Cow` contents (i.e.
+it's equivalent to calling `Cow::clone`).
+The similarly named `into_owned` method, on the other hand,
+clones the `Cow` contents, effectively turning any `Cow::Borrowed`
+into a `Cow::Owned`.
+
+Given the potential ambiguity, consider replacing `to_owned`
+with `clone` for better readability or, if getting a `Cow::Owned`
+was the original intent, using `into_owned` instead.
+
+### Example
+```
+let s = "Hello world!";
+let cow = Cow::Borrowed(s);
+
+let data = cow.to_owned();
+assert!(matches!(data, Cow::Borrowed(_)))
+```
+Use instead:
+```
+let s = "Hello world!";
+let cow = Cow::Borrowed(s);
+
+let data = cow.clone();
+assert!(matches!(data, Cow::Borrowed(_)))
+```
+or
+```
+let s = "Hello world!";
+let cow = Cow::Borrowed(s);
+
+let data = cow.into_owned();
+assert!(matches!(data, String))
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt b/src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt
new file mode 100644
index 000000000..06fb09db7
--- /dev/null
+++ b/src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks the formatting of a unary operator on the right hand side
+of a binary operator. It lints if there is no space between the binary and unary operators,
+but there is a space between the unary and its operand.
+
+### Why is this bad?
+This is either a typo in the binary operator or confusing.
+
+### Example
+```
+// &&! looks like a different operator
+if foo &&! bar {}
+```
+
+Use instead:
+```
+if foo && !bar {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/swap_ptr_to_ref.txt b/src/tools/clippy/src/docs/swap_ptr_to_ref.txt
new file mode 100644
index 000000000..0215d1e8a
--- /dev/null
+++ b/src/tools/clippy/src/docs/swap_ptr_to_ref.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for calls to `core::mem::swap` where either parameter is derived from a pointer
+
+### Why is this bad?
+When at least one parameter to `swap` is derived from a pointer it may overlap with the
+other. This would then lead to undefined behavior.
+
+### Example
+```
+unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {
+ for (&x, &y) in x.iter().zip(y) {
+ core::mem::swap(&mut *x, &mut *y);
+ }
+}
+```
+Use instead:
+```
+unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {
+ for (&x, &y) in x.iter().zip(y) {
+ core::ptr::swap(x, y);
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/tabs_in_doc_comments.txt b/src/tools/clippy/src/docs/tabs_in_doc_comments.txt
new file mode 100644
index 000000000..f83dbe2b7
--- /dev/null
+++ b/src/tools/clippy/src/docs/tabs_in_doc_comments.txt
@@ -0,0 +1,44 @@
+### What it does
+Checks doc comments for usage of tab characters.
+
+### Why is this bad?
+The rust style-guide promotes spaces instead of tabs for indentation.
+To keep a consistent view on the source, also doc comments should not have tabs.
+Also, explaining ascii-diagrams containing tabs can get displayed incorrectly when the
+display settings of the author and reader differ.
+
+### Example
+```
+///
+/// Struct to hold two strings:
+/// - first one
+/// - second one
+pub struct DoubleString {
+ ///
+ /// - First String:
+ /// - needs to be inside here
+ first_string: String,
+ ///
+ /// - Second String:
+ /// - needs to be inside here
+ second_string: String,
+}
+```
+
+Will be converted to:
+```
+///
+/// Struct to hold two strings:
+/// - first one
+/// - second one
+pub struct DoubleString {
+ ///
+ /// - First String:
+ /// - needs to be inside here
+ first_string: String,
+ ///
+ /// - Second String:
+ /// - needs to be inside here
+ second_string: String,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/temporary_assignment.txt b/src/tools/clippy/src/docs/temporary_assignment.txt
new file mode 100644
index 000000000..195b42cf0
--- /dev/null
+++ b/src/tools/clippy/src/docs/temporary_assignment.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for construction of a structure or tuple just to
+assign a value in it.
+
+### Why is this bad?
+Readability. If the structure is only created to be
+updated, why not write the structure you want in the first place?
+
+### Example
+```
+(0, 0).0 = 1
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/to_digit_is_some.txt b/src/tools/clippy/src/docs/to_digit_is_some.txt
new file mode 100644
index 000000000..eee8375ad
--- /dev/null
+++ b/src/tools/clippy/src/docs/to_digit_is_some.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for `.to_digit(..).is_some()` on `char`s.
+
+### Why is this bad?
+This is a convoluted way of checking if a `char` is a digit. It's
+more straight forward to use the dedicated `is_digit` method.
+
+### Example
+```
+let is_digit = c.to_digit(radix).is_some();
+```
+can be written as:
+```
+let is_digit = c.is_digit(radix);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/to_string_in_format_args.txt b/src/tools/clippy/src/docs/to_string_in_format_args.txt
new file mode 100644
index 000000000..34b205835
--- /dev/null
+++ b/src/tools/clippy/src/docs/to_string_in_format_args.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string)
+applied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html)
+in a macro that does formatting.
+
+### Why is this bad?
+Since the type implements `Display`, the use of `to_string` is
+unnecessary.
+
+### Example
+```
+println!("error: something failed at {}", Location::caller().to_string());
+```
+Use instead:
+```
+println!("error: something failed at {}", Location::caller());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/todo.txt b/src/tools/clippy/src/docs/todo.txt
new file mode 100644
index 000000000..661eb1ac5
--- /dev/null
+++ b/src/tools/clippy/src/docs/todo.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for usage of `todo!`.
+
+### Why is this bad?
+This macro should not be present in production code
+
+### Example
+```
+todo!();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/too_many_arguments.txt b/src/tools/clippy/src/docs/too_many_arguments.txt
new file mode 100644
index 000000000..4669f9f82
--- /dev/null
+++ b/src/tools/clippy/src/docs/too_many_arguments.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for functions with too many parameters.
+
+### Why is this bad?
+Functions with lots of parameters are considered bad
+style and reduce readability (“what does the 5th parameter mean?â€). Consider
+grouping some parameters into a new type.
+
+### Example
+```
+fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
+ // ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/too_many_lines.txt b/src/tools/clippy/src/docs/too_many_lines.txt
new file mode 100644
index 000000000..425db348b
--- /dev/null
+++ b/src/tools/clippy/src/docs/too_many_lines.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for functions with a large amount of lines.
+
+### Why is this bad?
+Functions with a lot of lines are harder to understand
+due to having to look at a larger amount of code to understand what the
+function is doing. Consider splitting the body of the function into
+multiple functions.
+
+### Example
+```
+fn im_too_long() {
+ println!("");
+ // ... 100 more LoC
+ println!("");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/toplevel_ref_arg.txt b/src/tools/clippy/src/docs/toplevel_ref_arg.txt
new file mode 100644
index 000000000..96a9e2db8
--- /dev/null
+++ b/src/tools/clippy/src/docs/toplevel_ref_arg.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for function arguments and let bindings denoted as
+`ref`.
+
+### Why is this bad?
+The `ref` declaration makes the function take an owned
+value, but turns the argument into a reference (which means that the value
+is destroyed when exiting the function). This adds not much value: either
+take a reference type, or take an owned value and create references in the
+body.
+
+For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The
+type of `x` is more obvious with the former.
+
+### Known problems
+If the argument is dereferenced within the function,
+removing the `ref` will lead to errors. This can be fixed by removing the
+dereferences, e.g., changing `*x` to `x` within the function.
+
+### Example
+```
+fn foo(ref _x: u8) {}
+```
+
+Use instead:
+```
+fn foo(_x: &u8) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trailing_empty_array.txt b/src/tools/clippy/src/docs/trailing_empty_array.txt
new file mode 100644
index 000000000..db1908cc9
--- /dev/null
+++ b/src/tools/clippy/src/docs/trailing_empty_array.txt
@@ -0,0 +1,22 @@
+### What it does
+Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute.
+
+### Why is this bad?
+Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjunction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed.
+
+### Example
+```
+struct RarelyUseful {
+ some_field: u32,
+ last: [u32; 0],
+}
+```
+
+Use instead:
+```
+#[repr(C)]
+struct MoreOftenUseful {
+ some_field: usize,
+ last: [u32; 0],
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trait_duplication_in_bounds.txt b/src/tools/clippy/src/docs/trait_duplication_in_bounds.txt
new file mode 100644
index 000000000..509736bb3
--- /dev/null
+++ b/src/tools/clippy/src/docs/trait_duplication_in_bounds.txt
@@ -0,0 +1,37 @@
+### What it does
+Checks for cases where generics are being used and multiple
+syntax specifications for trait bounds are used simultaneously.
+
+### Why is this bad?
+Duplicate bounds makes the code
+less readable than specifying them only once.
+
+### Example
+```
+fn func<T: Clone + Default>(arg: T) where T: Clone + Default {}
+```
+
+Use instead:
+```
+fn func<T: Clone + Default>(arg: T) {}
+
+// or
+
+fn func<T>(arg: T) where T: Clone + Default {}
+```
+
+```
+fn foo<T: Default + Default>(bar: T) {}
+```
+Use instead:
+```
+fn foo<T: Default>(bar: T) {}
+```
+
+```
+fn foo<T>(bar: T) where T: Default + Default {}
+```
+Use instead:
+```
+fn foo<T>(bar: T) where T: Default {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_bytes_to_str.txt b/src/tools/clippy/src/docs/transmute_bytes_to_str.txt
new file mode 100644
index 000000000..75889b9c7
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_bytes_to_str.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for transmutes from a `&[u8]` to a `&str`.
+
+### Why is this bad?
+Not every byte slice is a valid UTF-8 string.
+
+### Known problems
+- [`from_utf8`] which this lint suggests using is slower than `transmute`
+as it needs to validate the input.
+If you are certain that the input is always a valid UTF-8,
+use [`from_utf8_unchecked`] which is as fast as `transmute`
+but has a semantically meaningful name.
+- You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`.
+
+[`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html
+[`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html
+
+### Example
+```
+let b: &[u8] = &[1_u8, 2_u8];
+unsafe {
+ let _: &str = std::mem::transmute(b); // where b: &[u8]
+}
+
+// should be:
+let _ = std::str::from_utf8(b).unwrap();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_float_to_int.txt b/src/tools/clippy/src/docs/transmute_float_to_int.txt
new file mode 100644
index 000000000..1877e5a46
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_float_to_int.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for transmutes from a float to an integer.
+
+### Why is this bad?
+Transmutes are dangerous and error-prone, whereas `to_bits` is intuitive
+and safe.
+
+### Example
+```
+unsafe {
+ let _: u32 = std::mem::transmute(1f32);
+}
+
+// should be:
+let _: u32 = 1f32.to_bits();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_int_to_bool.txt b/src/tools/clippy/src/docs/transmute_int_to_bool.txt
new file mode 100644
index 000000000..07c10f8d0
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_int_to_bool.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for transmutes from an integer to a `bool`.
+
+### Why is this bad?
+This might result in an invalid in-memory representation of a `bool`.
+
+### Example
+```
+let x = 1_u8;
+unsafe {
+ let _: bool = std::mem::transmute(x); // where x: u8
+}
+
+// should be:
+let _: bool = x != 0;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_int_to_char.txt b/src/tools/clippy/src/docs/transmute_int_to_char.txt
new file mode 100644
index 000000000..836d22d3f
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_int_to_char.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for transmutes from an integer to a `char`.
+
+### Why is this bad?
+Not every integer is a Unicode scalar value.
+
+### Known problems
+- [`from_u32`] which this lint suggests using is slower than `transmute`
+as it needs to validate the input.
+If you are certain that the input is always a valid Unicode scalar value,
+use [`from_u32_unchecked`] which is as fast as `transmute`
+but has a semantically meaningful name.
+- You might want to handle `None` returned from [`from_u32`] instead of calling `unwrap`.
+
+[`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html
+[`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html
+
+### Example
+```
+let x = 1_u32;
+unsafe {
+ let _: char = std::mem::transmute(x); // where x: u32
+}
+
+// should be:
+let _ = std::char::from_u32(x).unwrap();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_int_to_float.txt b/src/tools/clippy/src/docs/transmute_int_to_float.txt
new file mode 100644
index 000000000..75cdc62e9
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_int_to_float.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for transmutes from an integer to a float.
+
+### Why is this bad?
+Transmutes are dangerous and error-prone, whereas `from_bits` is intuitive
+and safe.
+
+### Example
+```
+unsafe {
+ let _: f32 = std::mem::transmute(1_u32); // where x: u32
+}
+
+// should be:
+let _: f32 = f32::from_bits(1_u32);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_num_to_bytes.txt b/src/tools/clippy/src/docs/transmute_num_to_bytes.txt
new file mode 100644
index 000000000..a2c39a1b9
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_num_to_bytes.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for transmutes from a number to an array of `u8`
+
+### Why this is bad?
+Transmutes are dangerous and error-prone, whereas `to_ne_bytes`
+is intuitive and safe.
+
+### Example
+```
+unsafe {
+ let x: [u8; 8] = std::mem::transmute(1i64);
+}
+
+// should be
+let x: [u8; 8] = 0i64.to_ne_bytes();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt b/src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt
new file mode 100644
index 000000000..65777db98
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for transmutes from a pointer to a pointer, or
+from a reference to a reference.
+
+### Why is this bad?
+Transmutes are dangerous, and these can instead be
+written as casts.
+
+### Example
+```
+let ptr = &1u32 as *const u32;
+unsafe {
+ // pointer-to-pointer transmute
+ let _: *const f32 = std::mem::transmute(ptr);
+ // ref-ref transmute
+ let _: &f32 = std::mem::transmute(&1u32);
+}
+// These can be respectively written:
+let _ = ptr as *const f32;
+let _ = unsafe{ &*(&1u32 as *const u32 as *const f32) };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_ptr_to_ref.txt b/src/tools/clippy/src/docs/transmute_ptr_to_ref.txt
new file mode 100644
index 000000000..aca550f50
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_ptr_to_ref.txt
@@ -0,0 +1,21 @@
+### What it does
+Checks for transmutes from a pointer to a reference.
+
+### Why is this bad?
+This can always be rewritten with `&` and `*`.
+
+### Known problems
+- `mem::transmute` in statics and constants is stable from Rust 1.46.0,
+while dereferencing raw pointer is not stable yet.
+If you need to do this in those places,
+you would have to use `transmute` instead.
+
+### Example
+```
+unsafe {
+ let _: &T = std::mem::transmute(p); // where p: *const T
+}
+
+// can be written:
+let _: &T = &*p;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_undefined_repr.txt b/src/tools/clippy/src/docs/transmute_undefined_repr.txt
new file mode 100644
index 000000000..5ee6aaf4c
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmute_undefined_repr.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for transmutes between types which do not have a representation defined relative to
+each other.
+
+### Why is this bad?
+The results of such a transmute are not defined.
+
+### Known problems
+This lint has had multiple problems in the past and was moved to `nursery`. See issue
+[#8496](https://github.com/rust-lang/rust-clippy/issues/8496) for more details.
+
+### Example
+```
+struct Foo<T>(u32, T);
+let _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };
+```
+Use instead:
+```
+#[repr(C)]
+struct Foo<T>(u32, T);
+let _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt b/src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt
new file mode 100644
index 000000000..b68a8cda9
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt
@@ -0,0 +1,16 @@
+### What it does
+Checks for transmutes that could be a pointer cast.
+
+### Why is this bad?
+Readability. The code tricks people into thinking that
+something complex is going on.
+
+### Example
+
+```
+unsafe { std::mem::transmute::<*const [i32], *const [u16]>(p) };
+```
+Use instead:
+```
+p as *const [u16];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmuting_null.txt b/src/tools/clippy/src/docs/transmuting_null.txt
new file mode 100644
index 000000000..f8bacfc0b
--- /dev/null
+++ b/src/tools/clippy/src/docs/transmuting_null.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for transmute calls which would receive a null pointer.
+
+### Why is this bad?
+Transmuting a null pointer is undefined behavior.
+
+### Known problems
+Not all cases can be detected at the moment of this writing.
+For example, variables which hold a null pointer and are then fed to a `transmute`
+call, aren't detectable yet.
+
+### Example
+```
+let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trim_split_whitespace.txt b/src/tools/clippy/src/docs/trim_split_whitespace.txt
new file mode 100644
index 000000000..f7e3e7858
--- /dev/null
+++ b/src/tools/clippy/src/docs/trim_split_whitespace.txt
@@ -0,0 +1,14 @@
+### What it does
+Warns about calling `str::trim` (or variants) before `str::split_whitespace`.
+
+### Why is this bad?
+`split_whitespace` already ignores leading and trailing whitespace.
+
+### Example
+```
+" A B C ".trim().split_whitespace();
+```
+Use instead:
+```
+" A B C ".split_whitespace();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trivial_regex.txt b/src/tools/clippy/src/docs/trivial_regex.txt
new file mode 100644
index 000000000..f71d667fd
--- /dev/null
+++ b/src/tools/clippy/src/docs/trivial_regex.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for trivial [regex](https://crates.io/crates/regex)
+creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`).
+
+### Why is this bad?
+Matching the regex can likely be replaced by `==` or
+`str::starts_with`, `str::ends_with` or `std::contains` or other `str`
+methods.
+
+### Known problems
+If the same regex is going to be applied to multiple
+inputs, the precomputations done by `Regex` construction can give
+significantly better performance than any of the `str`-based methods.
+
+### Example
+```
+Regex::new("^foobar")
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt b/src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt
new file mode 100644
index 000000000..f54cce5e2
--- /dev/null
+++ b/src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt
@@ -0,0 +1,43 @@
+### What it does
+Checks for functions taking arguments by reference, where
+the argument type is `Copy` and small enough to be more efficient to always
+pass by value.
+
+### Why is this bad?
+In many calling conventions instances of structs will
+be passed through registers if they fit into two or less general purpose
+registers.
+
+### Known problems
+This lint is target register size dependent, it is
+limited to 32-bit to try and reduce portability problems between 32 and
+64-bit, but if you are compiling for 8 or 16-bit targets then the limit
+will be different.
+
+The configuration option `trivial_copy_size_limit` can be set to override
+this limit for a project.
+
+This lint attempts to allow passing arguments by reference if a reference
+to that argument is returned. This is implemented by comparing the lifetime
+of the argument and return value for equality. However, this can cause
+false positives in cases involving multiple lifetimes that are bounded by
+each other.
+
+Also, it does not take account of other similar cases where getting memory addresses
+matters; namely, returning the pointer to the argument in question,
+and passing the argument, as both references and pointers,
+to a function that needs the memory address. For further details, refer to
+[this issue](https://github.com/rust-lang/rust-clippy/issues/5953)
+that explains a real case in which this false positive
+led to an **undefined behavior** introduced with unsafe code.
+
+### Example
+
+```
+fn foo(v: &u32) {}
+```
+
+Use instead:
+```
+fn foo(v: u32) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/try_err.txt b/src/tools/clippy/src/docs/try_err.txt
new file mode 100644
index 000000000..e3d4ef3a0
--- /dev/null
+++ b/src/tools/clippy/src/docs/try_err.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for usages of `Err(x)?`.
+
+### Why is this bad?
+The `?` operator is designed to allow calls that
+can fail to be easily chained. For example, `foo()?.bar()` or
+`foo(bar()?)`. Because `Err(x)?` can't be used that way (it will
+always return), it is more clear to write `return Err(x)`.
+
+### Example
+```
+fn foo(fail: bool) -> Result<i32, String> {
+ if fail {
+ Err("failed")?;
+ }
+ Ok(0)
+}
+```
+Could be written:
+
+```
+fn foo(fail: bool) -> Result<i32, String> {
+ if fail {
+ return Err("failed".into());
+ }
+ Ok(0)
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/type_complexity.txt b/src/tools/clippy/src/docs/type_complexity.txt
new file mode 100644
index 000000000..69cd87500
--- /dev/null
+++ b/src/tools/clippy/src/docs/type_complexity.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for types used in structs, parameters and `let`
+declarations above a certain complexity threshold.
+
+### Why is this bad?
+Too complex types make the code less readable. Consider
+using a `type` definition to simplify them.
+
+### Example
+```
+struct Foo {
+ inner: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>>,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/type_repetition_in_bounds.txt b/src/tools/clippy/src/docs/type_repetition_in_bounds.txt
new file mode 100644
index 000000000..18ed372fd
--- /dev/null
+++ b/src/tools/clippy/src/docs/type_repetition_in_bounds.txt
@@ -0,0 +1,16 @@
+### What it does
+This lint warns about unnecessary type repetitions in trait bounds
+
+### Why is this bad?
+Repeating the type for every bound makes the code
+less readable than combining the bounds
+
+### Example
+```
+pub fn foo<T>(t: T) where T: Copy, T: Clone {}
+```
+
+Use instead:
+```
+pub fn foo<T>(t: T) where T: Copy + Clone {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt b/src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt
new file mode 100644
index 000000000..f3af4753c
--- /dev/null
+++ b/src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt
@@ -0,0 +1,43 @@
+### What it does
+Checks for `unsafe` blocks and impls without a `// SAFETY: ` comment
+explaining why the unsafe operations performed inside
+the block are safe.
+
+Note the comment must appear on the line(s) preceding the unsafe block
+with nothing appearing in between. The following is ok:
+```
+foo(
+ // SAFETY:
+ // This is a valid safety comment
+ unsafe { *x }
+)
+```
+But neither of these are:
+```
+// SAFETY:
+// This is not a valid safety comment
+foo(
+ /* SAFETY: Neither is this */ unsafe { *x },
+);
+```
+
+### Why is this bad?
+Undocumented unsafe blocks and impls can make it difficult to
+read and maintain code, as well as uncover unsoundness
+and bugs.
+
+### Example
+```
+use std::ptr::NonNull;
+let a = &mut 42;
+
+let ptr = unsafe { NonNull::new_unchecked(a) };
+```
+Use instead:
+```
+use std::ptr::NonNull;
+let a = &mut 42;
+
+// SAFETY: references are guaranteed to be non-null.
+let ptr = unsafe { NonNull::new_unchecked(a) };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/undropped_manually_drops.txt b/src/tools/clippy/src/docs/undropped_manually_drops.txt
new file mode 100644
index 000000000..85e3ec566
--- /dev/null
+++ b/src/tools/clippy/src/docs/undropped_manually_drops.txt
@@ -0,0 +1,22 @@
+### What it does
+Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`.
+
+### Why is this bad?
+The safe `drop` function does not drop the inner value of a `ManuallyDrop`.
+
+### Known problems
+Does not catch cases if the user binds `std::mem::drop`
+to a different name and calls it that way.
+
+### Example
+```
+struct S;
+drop(std::mem::ManuallyDrop::new(S));
+```
+Use instead:
+```
+struct S;
+unsafe {
+ std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unicode_not_nfc.txt b/src/tools/clippy/src/docs/unicode_not_nfc.txt
new file mode 100644
index 000000000..c660c51da
--- /dev/null
+++ b/src/tools/clippy/src/docs/unicode_not_nfc.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for string literals that contain Unicode in a form
+that is not equal to its
+[NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms).
+
+### Why is this bad?
+If such a string is compared to another, the results
+may be surprising.
+
+### Example
+You may not see it, but "à"" and "à"" aren't the same string. The
+former when escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unimplemented.txt b/src/tools/clippy/src/docs/unimplemented.txt
new file mode 100644
index 000000000..7095594fb
--- /dev/null
+++ b/src/tools/clippy/src/docs/unimplemented.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for usage of `unimplemented!`.
+
+### Why is this bad?
+This macro should not be present in production code
+
+### Example
+```
+unimplemented!();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/uninit_assumed_init.txt b/src/tools/clippy/src/docs/uninit_assumed_init.txt
new file mode 100644
index 000000000..cca24093d
--- /dev/null
+++ b/src/tools/clippy/src/docs/uninit_assumed_init.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for `MaybeUninit::uninit().assume_init()`.
+
+### Why is this bad?
+For most types, this is undefined behavior.
+
+### Known problems
+For now, we accept empty tuples and tuples / arrays
+of `MaybeUninit`. There may be other types that allow uninitialized
+data, but those are not yet rigorously defined.
+
+### Example
+```
+// Beware the UB
+use std::mem::MaybeUninit;
+
+let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
+```
+
+Note that the following is OK:
+
+```
+use std::mem::MaybeUninit;
+
+let _: [MaybeUninit<bool>; 5] = unsafe {
+ MaybeUninit::uninit().assume_init()
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/uninit_vec.txt b/src/tools/clippy/src/docs/uninit_vec.txt
new file mode 100644
index 000000000..cd50afe78
--- /dev/null
+++ b/src/tools/clippy/src/docs/uninit_vec.txt
@@ -0,0 +1,41 @@
+### What it does
+Checks for `set_len()` call that creates `Vec` with uninitialized elements.
+This is commonly caused by calling `set_len()` right after allocating or
+reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`.
+
+### Why is this bad?
+It creates a `Vec` with uninitialized data, which leads to
+undefined behavior with most safe operations. Notably, uninitialized
+`Vec<u8>` must not be used with generic `Read`.
+
+Moreover, calling `set_len()` on a `Vec` created with `new()` or `default()`
+creates out-of-bound values that lead to heap memory corruption when used.
+
+### Known Problems
+This lint only checks directly adjacent statements.
+
+### Example
+```
+let mut vec: Vec<u8> = Vec::with_capacity(1000);
+unsafe { vec.set_len(1000); }
+reader.read(&mut vec); // undefined behavior!
+```
+
+### How to fix?
+1. Use an initialized buffer:
+ ```rust,ignore
+ let mut vec: Vec<u8> = vec![0; 1000];
+ reader.read(&mut vec);
+ ```
+2. Wrap the content in `MaybeUninit`:
+ ```rust,ignore
+ let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);
+ vec.set_len(1000); // `MaybeUninit` can be uninitialized
+ ```
+3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available:
+ ```rust,ignore
+ let mut vec: Vec<u8> = Vec::with_capacity(1000);
+ let remaining = vec.spare_capacity_mut(); // `&mut [MaybeUninit<u8>]`
+ // perform initialization with `remaining`
+ vec.set_len(...); // Safe to call `set_len()` on initialized part
+ ``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_arg.txt b/src/tools/clippy/src/docs/unit_arg.txt
new file mode 100644
index 000000000..eb83403bb
--- /dev/null
+++ b/src/tools/clippy/src/docs/unit_arg.txt
@@ -0,0 +1,14 @@
+### What it does
+Checks for passing a unit value as an argument to a function without using a
+unit literal (`()`).
+
+### Why is this bad?
+This is likely the result of an accidental semicolon.
+
+### Example
+```
+foo({
+ let a = bar();
+ baz(a);
+})
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_cmp.txt b/src/tools/clippy/src/docs/unit_cmp.txt
new file mode 100644
index 000000000..6f3d62010
--- /dev/null
+++ b/src/tools/clippy/src/docs/unit_cmp.txt
@@ -0,0 +1,33 @@
+### What it does
+Checks for comparisons to unit. This includes all binary
+comparisons (like `==` and `<`) and asserts.
+
+### Why is this bad?
+Unit is always equal to itself, and thus is just a
+clumsily written constant. Mostly this happens when someone accidentally
+adds semicolons at the end of the operands.
+
+### Example
+```
+if {
+ foo();
+} == {
+ bar();
+} {
+ baz();
+}
+```
+is equal to
+```
+{
+ foo();
+ bar();
+ baz();
+}
+```
+
+For asserts:
+```
+assert_eq!({ foo(); }, { bar(); });
+```
+will always succeed \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_hash.txt b/src/tools/clippy/src/docs/unit_hash.txt
new file mode 100644
index 000000000..a22d29946
--- /dev/null
+++ b/src/tools/clippy/src/docs/unit_hash.txt
@@ -0,0 +1,20 @@
+### What it does
+Detects `().hash(_)`.
+
+### Why is this bad?
+Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
+
+### Example
+```
+match my_enum {
+ Empty => ().hash(&mut state),
+ WithValue(x) => x.hash(&mut state),
+}
+```
+Use instead:
+```
+match my_enum {
+ Empty => 0_u8.hash(&mut state),
+ WithValue(x) => x.hash(&mut state),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_return_expecting_ord.txt b/src/tools/clippy/src/docs/unit_return_expecting_ord.txt
new file mode 100644
index 000000000..781feac5a
--- /dev/null
+++ b/src/tools/clippy/src/docs/unit_return_expecting_ord.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for functions that expect closures of type
+Fn(...) -> Ord where the implemented closure returns the unit type.
+The lint also suggests to remove the semi-colon at the end of the statement if present.
+
+### Why is this bad?
+Likely, returning the unit type is unintentional, and
+could simply be caused by an extra semi-colon. Since () implements Ord
+it doesn't cause a compilation error.
+This is the same reasoning behind the unit_cmp lint.
+
+### Known problems
+If returning unit is intentional, then there is no
+way of specifying this without triggering needless_return lint
+
+### Example
+```
+let mut twins = vec!((1, 1), (2, 2));
+twins.sort_by_key(|x| { x.1; });
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_cast.txt b/src/tools/clippy/src/docs/unnecessary_cast.txt
new file mode 100644
index 000000000..603f26060
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_cast.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for casts to the same type, casts of int literals to integer types
+and casts of float literals to float types.
+
+### Why is this bad?
+It's just unnecessary.
+
+### Example
+```
+let _ = 2i32 as i32;
+let _ = 0.5 as f32;
+```
+
+Better:
+
+```
+let _ = 2_i32;
+let _ = 0.5_f32;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_filter_map.txt b/src/tools/clippy/src/docs/unnecessary_filter_map.txt
new file mode 100644
index 000000000..b19341ecf
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_filter_map.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for `filter_map` calls that could be replaced by `filter` or `map`.
+More specifically it checks if the closure provided is only performing one of the
+filter or map operations and suggests the appropriate option.
+
+### Why is this bad?
+Complexity. The intent is also clearer if only a single
+operation is being performed.
+
+### Example
+```
+let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None });
+
+// As there is no transformation of the argument this could be written as:
+let _ = (0..3).filter(|&x| x > 2);
+```
+
+```
+let _ = (0..4).filter_map(|x| Some(x + 1));
+
+// As there is no conditional check on the argument this could be written as:
+let _ = (0..4).map(|x| x + 1);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_find_map.txt b/src/tools/clippy/src/docs/unnecessary_find_map.txt
new file mode 100644
index 000000000..f9444dc48
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_find_map.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for `find_map` calls that could be replaced by `find` or `map`. More
+specifically it checks if the closure provided is only performing one of the
+find or map operations and suggests the appropriate option.
+
+### Why is this bad?
+Complexity. The intent is also clearer if only a single
+operation is being performed.
+
+### Example
+```
+let _ = (0..3).find_map(|x| if x > 2 { Some(x) } else { None });
+
+// As there is no transformation of the argument this could be written as:
+let _ = (0..3).find(|&x| x > 2);
+```
+
+```
+let _ = (0..4).find_map(|x| Some(x + 1));
+
+// As there is no conditional check on the argument this could be written as:
+let _ = (0..4).map(|x| x + 1).next();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_fold.txt b/src/tools/clippy/src/docs/unnecessary_fold.txt
new file mode 100644
index 000000000..e1b0e65f5
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_fold.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for using `fold` when a more succinct alternative exists.
+Specifically, this checks for `fold`s which could be replaced by `any`, `all`,
+`sum` or `product`.
+
+### Why is this bad?
+Readability.
+
+### Example
+```
+(0..3).fold(false, |acc, x| acc || x > 2);
+```
+
+Use instead:
+```
+(0..3).any(|x| x > 2);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_join.txt b/src/tools/clippy/src/docs/unnecessary_join.txt
new file mode 100644
index 000000000..ee4e78601
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_join.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for use of `.collect::<Vec<String>>().join("")` on iterators.
+
+### Why is this bad?
+`.collect::<String>()` is more concise and might be more performant
+
+### Example
+```
+let vector = vec!["hello", "world"];
+let output = vector.iter().map(|item| item.to_uppercase()).collect::<Vec<String>>().join("");
+println!("{}", output);
+```
+The correct use would be:
+```
+let vector = vec!["hello", "world"];
+let output = vector.iter().map(|item| item.to_uppercase()).collect::<String>();
+println!("{}", output);
+```
+### Known problems
+While `.collect::<String>()` is sometimes more performant, there are cases where
+using `.collect::<String>()` over `.collect::<Vec<String>>().join("")`
+will prevent loop unrolling and will result in a negative performance impact.
+
+Additionally, differences have been observed between aarch64 and x86_64 assembly output,
+with aarch64 tending to producing faster assembly in more cases when using `.collect::<String>()` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt b/src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt
new file mode 100644
index 000000000..208188ce9
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt
@@ -0,0 +1,32 @@
+### What it does
+As the counterpart to `or_fun_call`, this lint looks for unnecessary
+lazily evaluated closures on `Option` and `Result`.
+
+This lint suggests changing the following functions, when eager evaluation results in
+simpler code:
+ - `unwrap_or_else` to `unwrap_or`
+ - `and_then` to `and`
+ - `or_else` to `or`
+ - `get_or_insert_with` to `get_or_insert`
+ - `ok_or_else` to `ok_or`
+
+### Why is this bad?
+Using eager evaluation is shorter and simpler in some cases.
+
+### Known problems
+It is possible, but not recommended for `Deref` and `Index` to have
+side effects. Eagerly evaluating them can change the semantics of the program.
+
+### Example
+```
+// example code where clippy issues a warning
+let opt: Option<u32> = None;
+
+opt.unwrap_or_else(|| 42);
+```
+Use instead:
+```
+let opt: Option<u32> = None;
+
+opt.unwrap_or(42);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_mut_passed.txt b/src/tools/clippy/src/docs/unnecessary_mut_passed.txt
new file mode 100644
index 000000000..2f8bdd113
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_mut_passed.txt
@@ -0,0 +1,17 @@
+### What it does
+Detects passing a mutable reference to a function that only
+requires an immutable reference.
+
+### Why is this bad?
+The mutable reference rules out all other references to
+the value. Also the code misleads about the intent of the call site.
+
+### Example
+```
+vec.push(&mut value);
+```
+
+Use instead:
+```
+vec.push(&value);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_operation.txt b/src/tools/clippy/src/docs/unnecessary_operation.txt
new file mode 100644
index 000000000..7f455e264
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_operation.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for expression statements that can be reduced to a
+sub-expression.
+
+### Why is this bad?
+Expressions by themselves often have no side-effects.
+Having such expressions reduces readability.
+
+### Example
+```
+compute_array()[0];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt b/src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt
new file mode 100644
index 000000000..8cd9fba60
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt
@@ -0,0 +1,16 @@
+### What it does
+
+Detects cases of owned empty strings being passed as an argument to a function expecting `&str`
+
+### Why is this bad?
+
+This results in longer and less readable code
+
+### Example
+```
+vec!["1", "2", "3"].join(&String::new());
+```
+Use instead:
+```
+vec!["1", "2", "3"].join("");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_self_imports.txt b/src/tools/clippy/src/docs/unnecessary_self_imports.txt
new file mode 100644
index 000000000..b909cd5a7
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_self_imports.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for imports ending in `::{self}`.
+
+### Why is this bad?
+In most cases, this can be written much more cleanly by omitting `::{self}`.
+
+### Known problems
+Removing `::{self}` will cause any non-module items at the same path to also be imported.
+This might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt
+to detect this scenario and that is why it is a restriction lint.
+
+### Example
+```
+use std::io::{self};
+```
+Use instead:
+```
+use std::io;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_sort_by.txt b/src/tools/clippy/src/docs/unnecessary_sort_by.txt
new file mode 100644
index 000000000..6913b62c4
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_sort_by.txt
@@ -0,0 +1,21 @@
+### What it does
+Detects uses of `Vec::sort_by` passing in a closure
+which compares the two arguments, either directly or indirectly.
+
+### Why is this bad?
+It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if
+possible) than to use `Vec::sort_by` and a more complicated
+closure.
+
+### Known problems
+If the suggested `Vec::sort_by_key` uses Reverse and it isn't already
+imported by a use statement, then it will need to be added manually.
+
+### Example
+```
+vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
+```
+Use instead:
+```
+vec.sort_by_key(|a| a.foo());
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_to_owned.txt b/src/tools/clippy/src/docs/unnecessary_to_owned.txt
new file mode 100644
index 000000000..5d4213bda
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_to_owned.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned)
+and other `to_owned`-like functions.
+
+### Why is this bad?
+The unnecessary calls result in useless allocations.
+
+### Known problems
+`unnecessary_to_owned` can falsely trigger if `IntoIterator::into_iter` is applied to an
+owned copy of a resource and the resource is later used mutably. See
+[#8148](https://github.com/rust-lang/rust-clippy/issues/8148).
+
+### Example
+```
+let path = std::path::Path::new("x");
+foo(&path.to_string_lossy().to_string());
+fn foo(s: &str) {}
+```
+Use instead:
+```
+let path = std::path::Path::new("x");
+foo(&path.to_string_lossy());
+fn foo(s: &str) {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_unwrap.txt b/src/tools/clippy/src/docs/unnecessary_unwrap.txt
new file mode 100644
index 000000000..50ae845bb
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_unwrap.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for calls of `unwrap[_err]()` that cannot fail.
+
+### Why is this bad?
+Using `if let` or `match` is more idiomatic.
+
+### Example
+```
+if option.is_some() {
+ do_something_with(option.unwrap())
+}
+```
+
+Could be written:
+
+```
+if let Some(value) = option {
+ do_something_with(value)
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_wraps.txt b/src/tools/clippy/src/docs/unnecessary_wraps.txt
new file mode 100644
index 000000000..c0a23d492
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnecessary_wraps.txt
@@ -0,0 +1,36 @@
+### What it does
+Checks for private functions that only return `Ok` or `Some`.
+
+### Why is this bad?
+It is not meaningful to wrap values when no `None` or `Err` is returned.
+
+### Known problems
+There can be false positives if the function signature is designed to
+fit some external requirement.
+
+### Example
+```
+fn get_cool_number(a: bool, b: bool) -> Option<i32> {
+ if a && b {
+ return Some(50);
+ }
+ if a {
+ Some(0)
+ } else {
+ Some(10)
+ }
+}
+```
+Use instead:
+```
+fn get_cool_number(a: bool, b: bool) -> i32 {
+ if a && b {
+ return 50;
+ }
+ if a {
+ 0
+ } else {
+ 10
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unneeded_field_pattern.txt b/src/tools/clippy/src/docs/unneeded_field_pattern.txt
new file mode 100644
index 000000000..3cd00a0f3
--- /dev/null
+++ b/src/tools/clippy/src/docs/unneeded_field_pattern.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for structure field patterns bound to wildcards.
+
+### Why is this bad?
+Using `..` instead is shorter and leaves the focus on
+the fields that are actually bound.
+
+### Example
+```
+let f = Foo { a: 0, b: 0, c: 0 };
+
+match f {
+ Foo { a: _, b: 0, .. } => {},
+ Foo { a: _, b: _, c: _ } => {},
+}
+```
+
+Use instead:
+```
+let f = Foo { a: 0, b: 0, c: 0 };
+
+match f {
+ Foo { b: 0, .. } => {},
+ Foo { .. } => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt b/src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt
new file mode 100644
index 000000000..817061efd
--- /dev/null
+++ b/src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt
@@ -0,0 +1,28 @@
+### What it does
+Checks for tuple patterns with a wildcard
+pattern (`_`) is next to a rest pattern (`..`).
+
+_NOTE_: While `_, ..` means there is at least one element left, `..`
+means there are 0 or more elements left. This can make a difference
+when refactoring, but shouldn't result in errors in the refactored code,
+since the wildcard pattern isn't used anyway.
+
+### Why is this bad?
+The wildcard pattern is unneeded as the rest pattern
+can match that element as well.
+
+### Example
+```
+match t {
+ TupleStruct(0, .., _) => (),
+ _ => (),
+}
+```
+
+Use instead:
+```
+match t {
+ TupleStruct(0, ..) => (),
+ _ => (),
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnested_or_patterns.txt b/src/tools/clippy/src/docs/unnested_or_patterns.txt
new file mode 100644
index 000000000..49c45d4ee
--- /dev/null
+++ b/src/tools/clippy/src/docs/unnested_or_patterns.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and
+suggests replacing the pattern with a nested one, `Some(0 | 2)`.
+
+Another way to think of this is that it rewrites patterns in
+*disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*.
+
+### Why is this bad?
+In the example above, `Some` is repeated, which unnecessarily complicates the pattern.
+
+### Example
+```
+fn main() {
+ if let Some(0) | Some(2) = Some(0) {}
+}
+```
+Use instead:
+```
+fn main() {
+ if let Some(0 | 2) = Some(0) {}
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unreachable.txt b/src/tools/clippy/src/docs/unreachable.txt
new file mode 100644
index 000000000..10469ca77
--- /dev/null
+++ b/src/tools/clippy/src/docs/unreachable.txt
@@ -0,0 +1,10 @@
+### What it does
+Checks for usage of `unreachable!`.
+
+### Why is this bad?
+This macro can cause code to panic
+
+### Example
+```
+unreachable!();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unreadable_literal.txt b/src/tools/clippy/src/docs/unreadable_literal.txt
new file mode 100644
index 000000000..e168f90a8
--- /dev/null
+++ b/src/tools/clippy/src/docs/unreadable_literal.txt
@@ -0,0 +1,16 @@
+### What it does
+Warns if a long integral or floating-point constant does
+not contain underscores.
+
+### Why is this bad?
+Reading long numbers is difficult without separators.
+
+### Example
+```
+61864918973511
+```
+
+Use instead:
+```
+61_864_918_973_511
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unsafe_derive_deserialize.txt b/src/tools/clippy/src/docs/unsafe_derive_deserialize.txt
new file mode 100644
index 000000000..f56c48044
--- /dev/null
+++ b/src/tools/clippy/src/docs/unsafe_derive_deserialize.txt
@@ -0,0 +1,27 @@
+### What it does
+Checks for deriving `serde::Deserialize` on a type that
+has methods using `unsafe`.
+
+### Why is this bad?
+Deriving `serde::Deserialize` will create a constructor
+that may violate invariants hold by another constructor.
+
+### Example
+```
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+pub struct Foo {
+ // ..
+}
+
+impl Foo {
+ pub fn new() -> Self {
+ // setup here ..
+ }
+
+ pub unsafe fn parts() -> (&str, &str) {
+ // assumes invariants hold
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unsafe_removed_from_name.txt b/src/tools/clippy/src/docs/unsafe_removed_from_name.txt
new file mode 100644
index 000000000..6f55c1815
--- /dev/null
+++ b/src/tools/clippy/src/docs/unsafe_removed_from_name.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for imports that remove "unsafe" from an item's
+name.
+
+### Why is this bad?
+Renaming makes it less clear which traits and
+structures are unsafe.
+
+### Example
+```
+use std::cell::{UnsafeCell as TotallySafeCell};
+
+extern crate crossbeam;
+use crossbeam::{spawn_unsafe as spawn};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unseparated_literal_suffix.txt b/src/tools/clippy/src/docs/unseparated_literal_suffix.txt
new file mode 100644
index 000000000..d80248e34
--- /dev/null
+++ b/src/tools/clippy/src/docs/unseparated_literal_suffix.txt
@@ -0,0 +1,18 @@
+### What it does
+Warns if literal suffixes are not separated by an
+underscore.
+To enforce unseparated literal suffix style,
+see the `separated_literal_suffix` lint.
+
+### Why is this bad?
+Suffix style should be consistent.
+
+### Example
+```
+123832i32
+```
+
+Use instead:
+```
+123832_i32
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unsound_collection_transmute.txt b/src/tools/clippy/src/docs/unsound_collection_transmute.txt
new file mode 100644
index 000000000..29db9258e
--- /dev/null
+++ b/src/tools/clippy/src/docs/unsound_collection_transmute.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for transmutes between collections whose
+types have different ABI, size or alignment.
+
+### Why is this bad?
+This is undefined behavior.
+
+### Known problems
+Currently, we cannot know whether a type is a
+collection, so we just lint the ones that come with `std`.
+
+### Example
+```
+// different size, therefore likely out-of-bounds memory access
+// You absolutely do not want this in your code!
+unsafe {
+ std::mem::transmute::<_, Vec<u32>>(vec![2_u16])
+};
+```
+
+You must always iterate, map and collect the values:
+
+```
+vec![2_u16].into_iter().map(u32::from).collect::<Vec<_>>();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_async.txt b/src/tools/clippy/src/docs/unused_async.txt
new file mode 100644
index 000000000..26def11aa
--- /dev/null
+++ b/src/tools/clippy/src/docs/unused_async.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for functions that are declared `async` but have no `.await`s inside of them.
+
+### Why is this bad?
+Async functions with no async code create overhead, both mentally and computationally.
+Callers of async methods either need to be calling from an async function themselves or run it on an executor, both of which
+causes runtime overhead and hassle for the caller.
+
+### Example
+```
+async fn get_random_number() -> i64 {
+ 4 // Chosen by fair dice roll. Guaranteed to be random.
+}
+let number_future = get_random_number();
+```
+
+Use instead:
+```
+fn get_random_number_improved() -> i64 {
+ 4 // Chosen by fair dice roll. Guaranteed to be random.
+}
+let number_future = async { get_random_number_improved() };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_io_amount.txt b/src/tools/clippy/src/docs/unused_io_amount.txt
new file mode 100644
index 000000000..fbc4c299c
--- /dev/null
+++ b/src/tools/clippy/src/docs/unused_io_amount.txt
@@ -0,0 +1,31 @@
+### What it does
+Checks for unused written/read amount.
+
+### Why is this bad?
+`io::Write::write(_vectored)` and
+`io::Read::read(_vectored)` are not guaranteed to
+process the entire buffer. They return how many bytes were processed, which
+might be smaller
+than a given buffer's length. If you don't need to deal with
+partial-write/read, use
+`write_all`/`read_exact` instead.
+
+When working with asynchronous code (either with the `futures`
+crate or with `tokio`), a similar issue exists for
+`AsyncWriteExt::write()` and `AsyncReadExt::read()` : these
+functions are also not guaranteed to process the entire
+buffer. Your code should either handle partial-writes/reads, or
+call the `write_all`/`read_exact` methods on those traits instead.
+
+### Known problems
+Detects only common patterns.
+
+### Examples
+```
+use std::io;
+fn foo<W: io::Write>(w: &mut W) -> io::Result<()> {
+ // must be `w.write_all(b"foo")?;`
+ w.write(b"foo")?;
+ Ok(())
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_peekable.txt b/src/tools/clippy/src/docs/unused_peekable.txt
new file mode 100644
index 000000000..268de1ce3
--- /dev/null
+++ b/src/tools/clippy/src/docs/unused_peekable.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for the creation of a `peekable` iterator that is never `.peek()`ed
+
+### Why is this bad?
+Creating a peekable iterator without using any of its methods is likely a mistake,
+or just a leftover after a refactor.
+
+### Example
+```
+let collection = vec![1, 2, 3];
+let iter = collection.iter().peekable();
+
+for item in iter {
+ // ...
+}
+```
+
+Use instead:
+```
+let collection = vec![1, 2, 3];
+let iter = collection.iter();
+
+for item in iter {
+ // ...
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_rounding.txt b/src/tools/clippy/src/docs/unused_rounding.txt
new file mode 100644
index 000000000..70947acee
--- /dev/null
+++ b/src/tools/clippy/src/docs/unused_rounding.txt
@@ -0,0 +1,17 @@
+### What it does
+
+Detects cases where a whole-number literal float is being rounded, using
+the `floor`, `ceil`, or `round` methods.
+
+### Why is this bad?
+
+This is unnecessary and confusing to the reader. Doing this is probably a mistake.
+
+### Example
+```
+let x = 1f32.ceil();
+```
+Use instead:
+```
+let x = 1f32;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_self.txt b/src/tools/clippy/src/docs/unused_self.txt
new file mode 100644
index 000000000..a8d0fc759
--- /dev/null
+++ b/src/tools/clippy/src/docs/unused_self.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks methods that contain a `self` argument but don't use it
+
+### Why is this bad?
+It may be clearer to define the method as an associated function instead
+of an instance method if it doesn't require `self`.
+
+### Example
+```
+struct A;
+impl A {
+ fn method(&self) {}
+}
+```
+
+Could be written:
+
+```
+struct A;
+impl A {
+ fn method() {}
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_unit.txt b/src/tools/clippy/src/docs/unused_unit.txt
new file mode 100644
index 000000000..48d16ca65
--- /dev/null
+++ b/src/tools/clippy/src/docs/unused_unit.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for unit (`()`) expressions that can be removed.
+
+### Why is this bad?
+Such expressions add no value, but can make the code
+less readable. Depending on formatting they can make a `break` or `return`
+statement look like a function call.
+
+### Example
+```
+fn return_unit() -> () {
+ ()
+}
+```
+is equivalent to
+```
+fn return_unit() {}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unusual_byte_groupings.txt b/src/tools/clippy/src/docs/unusual_byte_groupings.txt
new file mode 100644
index 000000000..9a1f132a6
--- /dev/null
+++ b/src/tools/clippy/src/docs/unusual_byte_groupings.txt
@@ -0,0 +1,12 @@
+### What it does
+Warns if hexadecimal or binary literals are not grouped
+by nibble or byte.
+
+### Why is this bad?
+Negatively impacts readability.
+
+### Example
+```
+let x: u32 = 0xFFF_FFF;
+let y: u8 = 0b01_011_101;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unwrap_in_result.txt b/src/tools/clippy/src/docs/unwrap_in_result.txt
new file mode 100644
index 000000000..7497dd863
--- /dev/null
+++ b/src/tools/clippy/src/docs/unwrap_in_result.txt
@@ -0,0 +1,39 @@
+### What it does
+Checks for functions of type `Result` that contain `expect()` or `unwrap()`
+
+### Why is this bad?
+These functions promote recoverable errors to non-recoverable errors which may be undesirable in code bases which wish to avoid panics.
+
+### Known problems
+This can cause false positives in functions that handle both recoverable and non recoverable errors.
+
+### Example
+Before:
+```
+fn divisible_by_3(i_str: String) -> Result<(), String> {
+ let i = i_str
+ .parse::<i32>()
+ .expect("cannot divide the input by three");
+
+ if i % 3 != 0 {
+ Err("Number is not divisible by 3")?
+ }
+
+ Ok(())
+}
+```
+
+After:
+```
+fn divisible_by_3(i_str: String) -> Result<(), String> {
+ let i = i_str
+ .parse::<i32>()
+ .map_err(|e| format!("cannot divide the input by three: {}", e))?;
+
+ if i % 3 != 0 {
+ Err("Number is not divisible by 3")?
+ }
+
+ Ok(())
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unwrap_or_else_default.txt b/src/tools/clippy/src/docs/unwrap_or_else_default.txt
new file mode 100644
index 000000000..34b4cf088
--- /dev/null
+++ b/src/tools/clippy/src/docs/unwrap_or_else_default.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for usages of `_.unwrap_or_else(Default::default)` on `Option` and
+`Result` values.
+
+### Why is this bad?
+Readability, these can be written as `_.unwrap_or_default`, which is
+simpler and more concise.
+
+### Examples
+```
+x.unwrap_or_else(Default::default);
+x.unwrap_or_else(u32::default);
+```
+
+Use instead:
+```
+x.unwrap_or_default();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unwrap_used.txt b/src/tools/clippy/src/docs/unwrap_used.txt
new file mode 100644
index 000000000..9b4713df5
--- /dev/null
+++ b/src/tools/clippy/src/docs/unwrap_used.txt
@@ -0,0 +1,37 @@
+### What it does
+Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s.
+
+### Why is this bad?
+It is better to handle the `None` or `Err` case,
+or at least call `.expect(_)` with a more helpful message. Still, for a lot of
+quick-and-dirty code, `unwrap` is a good choice, which is why this lint is
+`Allow` by default.
+
+`result.unwrap()` will let the thread panic on `Err` values.
+Normally, you want to implement more sophisticated error handling,
+and propagate errors upwards with `?` operator.
+
+Even if you want to panic on errors, not all `Error`s implement good
+messages on display. Therefore, it may be beneficial to look at the places
+where they may get displayed. Activate this lint to do just that.
+
+### Examples
+```
+option.unwrap();
+result.unwrap();
+```
+
+Use instead:
+```
+option.expect("more helpful message");
+result.expect("more helpful message");
+```
+
+If [expect_used](#expect_used) is enabled, instead:
+```
+option?;
+
+// or
+
+result?;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/upper_case_acronyms.txt b/src/tools/clippy/src/docs/upper_case_acronyms.txt
new file mode 100644
index 000000000..a1e39c7e1
--- /dev/null
+++ b/src/tools/clippy/src/docs/upper_case_acronyms.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for fully capitalized names and optionally names containing a capitalized acronym.
+
+### Why is this bad?
+In CamelCase, acronyms count as one word.
+See [naming conventions](https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case)
+for more.
+
+By default, the lint only triggers on fully-capitalized names.
+You can use the `upper-case-acronyms-aggressive: true` config option to enable linting
+on all camel case names
+
+### Known problems
+When two acronyms are contiguous, the lint can't tell where
+the first acronym ends and the second starts, so it suggests to lowercase all of
+the letters in the second acronym.
+
+### Example
+```
+struct HTTPResponse;
+```
+Use instead:
+```
+struct HttpResponse;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/use_debug.txt b/src/tools/clippy/src/docs/use_debug.txt
new file mode 100644
index 000000000..94d4a6fd2
--- /dev/null
+++ b/src/tools/clippy/src/docs/use_debug.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for use of `Debug` formatting. The purpose of this
+lint is to catch debugging remnants.
+
+### Why is this bad?
+The purpose of the `Debug` trait is to facilitate
+debugging Rust code. It should not be used in user-facing output.
+
+### Example
+```
+println!("{:?}", foo);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/use_self.txt b/src/tools/clippy/src/docs/use_self.txt
new file mode 100644
index 000000000..bd37ed1e0
--- /dev/null
+++ b/src/tools/clippy/src/docs/use_self.txt
@@ -0,0 +1,31 @@
+### What it does
+Checks for unnecessary repetition of structure name when a
+replacement with `Self` is applicable.
+
+### Why is this bad?
+Unnecessary repetition. Mixed use of `Self` and struct
+name
+feels inconsistent.
+
+### Known problems
+- Unaddressed false negative in fn bodies of trait implementations
+- False positive with associated types in traits (#4140)
+
+### Example
+```
+struct Foo;
+impl Foo {
+ fn new() -> Foo {
+ Foo {}
+ }
+}
+```
+could be
+```
+struct Foo;
+impl Foo {
+ fn new() -> Self {
+ Self {}
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/used_underscore_binding.txt b/src/tools/clippy/src/docs/used_underscore_binding.txt
new file mode 100644
index 000000000..ed67c41eb
--- /dev/null
+++ b/src/tools/clippy/src/docs/used_underscore_binding.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for the use of bindings with a single leading
+underscore.
+
+### Why is this bad?
+A single leading underscore is usually used to indicate
+that a binding will not be used. Using such a binding breaks this
+expectation.
+
+### Known problems
+The lint does not work properly with desugaring and
+macro, it has been allowed in the mean time.
+
+### Example
+```
+let _x = 0;
+let y = _x + 1; // Here we are using `_x`, even though it has a leading
+ // underscore. We should rename `_x` to `x`
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_asref.txt b/src/tools/clippy/src/docs/useless_asref.txt
new file mode 100644
index 000000000..f777cd377
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_asref.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for usage of `.as_ref()` or `.as_mut()` where the
+types before and after the call are the same.
+
+### Why is this bad?
+The call is unnecessary.
+
+### Example
+```
+let x: &[i32] = &[1, 2, 3, 4, 5];
+do_stuff(x.as_ref());
+```
+The correct use would be:
+```
+let x: &[i32] = &[1, 2, 3, 4, 5];
+do_stuff(x);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_attribute.txt b/src/tools/clippy/src/docs/useless_attribute.txt
new file mode 100644
index 000000000..e02d4c907
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_attribute.txt
@@ -0,0 +1,36 @@
+### What it does
+Checks for `extern crate` and `use` items annotated with
+lint attributes.
+
+This lint permits lint attributes for lints emitted on the items themself.
+For `use` items these lints are:
+* deprecated
+* unreachable_pub
+* unused_imports
+* clippy::enum_glob_use
+* clippy::macro_use_imports
+* clippy::wildcard_imports
+
+For `extern crate` items these lints are:
+* `unused_imports` on items with `#[macro_use]`
+
+### Why is this bad?
+Lint attributes have no effect on crate imports. Most
+likely a `!` was forgotten.
+
+### Example
+```
+#[deny(dead_code)]
+extern crate foo;
+#[forbid(dead_code)]
+use foo::bar;
+```
+
+Use instead:
+```
+#[allow(unused_imports)]
+use foo::baz;
+#[allow(unused_imports)]
+#[macro_use]
+extern crate baz;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_conversion.txt b/src/tools/clippy/src/docs/useless_conversion.txt
new file mode 100644
index 000000000..06000a7ad
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_conversion.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls
+which uselessly convert to the same type.
+
+### Why is this bad?
+Redundant code.
+
+### Example
+```
+// format!() returns a `String`
+let s: String = format!("hello").into();
+```
+
+Use instead:
+```
+let s: String = format!("hello");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_format.txt b/src/tools/clippy/src/docs/useless_format.txt
new file mode 100644
index 000000000..eb4819da1
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_format.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for the use of `format!("string literal with no
+argument")` and `format!("{}", foo)` where `foo` is a string.
+
+### Why is this bad?
+There is no point of doing that. `format!("foo")` can
+be replaced by `"foo".to_owned()` if you really need a `String`. The even
+worse `&format!("foo")` is often encountered in the wild. `format!("{}",
+foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`
+if `foo: &str`.
+
+### Examples
+```
+let foo = "foo";
+format!("{}", foo);
+```
+
+Use instead:
+```
+let foo = "foo";
+foo.to_owned();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_let_if_seq.txt b/src/tools/clippy/src/docs/useless_let_if_seq.txt
new file mode 100644
index 000000000..c6dcd57eb
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_let_if_seq.txt
@@ -0,0 +1,39 @@
+### What it does
+Checks for variable declarations immediately followed by a
+conditional affectation.
+
+### Why is this bad?
+This is not idiomatic Rust.
+
+### Example
+```
+let foo;
+
+if bar() {
+ foo = 42;
+} else {
+ foo = 0;
+}
+
+let mut baz = None;
+
+if bar() {
+ baz = Some(42);
+}
+```
+
+should be written
+
+```
+let foo = if bar() {
+ 42
+} else {
+ 0
+};
+
+let baz = if bar() {
+ Some(42)
+} else {
+ None
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_transmute.txt b/src/tools/clippy/src/docs/useless_transmute.txt
new file mode 100644
index 000000000..1d3a17588
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_transmute.txt
@@ -0,0 +1,12 @@
+### What it does
+Checks for transmutes to the original type of the object
+and transmutes that could be a cast.
+
+### Why is this bad?
+Readability. The code tricks people into thinking that
+something complex is going on.
+
+### Example
+```
+core::intrinsics::transmute(t); // where the result type is the same as `t`'s
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_vec.txt b/src/tools/clippy/src/docs/useless_vec.txt
new file mode 100644
index 000000000..ee5afc99e
--- /dev/null
+++ b/src/tools/clippy/src/docs/useless_vec.txt
@@ -0,0 +1,18 @@
+### What it does
+Checks for usage of `&vec![..]` when using `&[..]` would
+be possible.
+
+### Why is this bad?
+This is less efficient.
+
+### Example
+```
+fn foo(_x: &[u8]) {}
+
+foo(&vec![1, 2]);
+```
+
+Use instead:
+```
+foo(&[1, 2]);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vec_box.txt b/src/tools/clippy/src/docs/vec_box.txt
new file mode 100644
index 000000000..701b1c9ce
--- /dev/null
+++ b/src/tools/clippy/src/docs/vec_box.txt
@@ -0,0 +1,26 @@
+### What it does
+Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.
+Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
+
+### Why is this bad?
+`Vec` already keeps its contents in a separate area on
+the heap. So if you `Box` its contents, you just add another level of indirection.
+
+### Known problems
+Vec<Box<T: Sized>> makes sense if T is a large type (see [#3530](https://github.com/rust-lang/rust-clippy/issues/3530),
+1st comment).
+
+### Example
+```
+struct X {
+ values: Vec<Box<i32>>,
+}
+```
+
+Better:
+
+```
+struct X {
+ values: Vec<i32>,
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vec_init_then_push.txt b/src/tools/clippy/src/docs/vec_init_then_push.txt
new file mode 100644
index 000000000..445f28747
--- /dev/null
+++ b/src/tools/clippy/src/docs/vec_init_then_push.txt
@@ -0,0 +1,23 @@
+### What it does
+Checks for calls to `push` immediately after creating a new `Vec`.
+
+If the `Vec` is created using `with_capacity` this will only lint if the capacity is a
+constant and the number of pushes is greater than or equal to the initial capacity.
+
+If the `Vec` is extended after the initial sequence of pushes and it was default initialized
+then this will only lint after there were at least four pushes. This number may change in
+the future.
+
+### Why is this bad?
+The `vec![]` macro is both more performant and easier to read than
+multiple `push` calls.
+
+### Example
+```
+let mut v = Vec::new();
+v.push(0);
+```
+Use instead:
+```
+let v = vec![0];
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vec_resize_to_zero.txt b/src/tools/clippy/src/docs/vec_resize_to_zero.txt
new file mode 100644
index 000000000..0b9268677
--- /dev/null
+++ b/src/tools/clippy/src/docs/vec_resize_to_zero.txt
@@ -0,0 +1,15 @@
+### What it does
+Finds occurrences of `Vec::resize(0, an_int)`
+
+### Why is this bad?
+This is probably an argument inversion mistake.
+
+### Example
+```
+vec!(1, 2, 3, 4, 5).resize(0, 5)
+```
+
+Use instead:
+```
+vec!(1, 2, 3, 4, 5).clear()
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/verbose_bit_mask.txt b/src/tools/clippy/src/docs/verbose_bit_mask.txt
new file mode 100644
index 000000000..87a847029
--- /dev/null
+++ b/src/tools/clippy/src/docs/verbose_bit_mask.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for bit masks that can be replaced by a call
+to `trailing_zeros`
+
+### Why is this bad?
+`x.trailing_zeros() > 4` is much clearer than `x & 15
+== 0`
+
+### Known problems
+llvm generates better code for `x & 15 == 0` on x86
+
+### Example
+```
+if x & 0b1111 == 0 { }
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/verbose_file_reads.txt b/src/tools/clippy/src/docs/verbose_file_reads.txt
new file mode 100644
index 000000000..9703df423
--- /dev/null
+++ b/src/tools/clippy/src/docs/verbose_file_reads.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for use of File::read_to_end and File::read_to_string.
+
+### Why is this bad?
+`fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.
+See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)
+
+### Example
+```
+let mut f = File::open("foo.txt").unwrap();
+let mut bytes = Vec::new();
+f.read_to_end(&mut bytes).unwrap();
+```
+Can be written more concisely as
+```
+let mut bytes = fs::read("foo.txt").unwrap();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vtable_address_comparisons.txt b/src/tools/clippy/src/docs/vtable_address_comparisons.txt
new file mode 100644
index 000000000..4a34e4ba7
--- /dev/null
+++ b/src/tools/clippy/src/docs/vtable_address_comparisons.txt
@@ -0,0 +1,17 @@
+### What it does
+Checks for comparisons with an address of a trait vtable.
+
+### Why is this bad?
+Comparing trait objects pointers compares an vtable addresses which
+are not guaranteed to be unique and could vary between different code generation units.
+Furthermore vtables for different types could have the same address after being merged
+together.
+
+### Example
+```
+let a: Rc<dyn Trait> = ...
+let b: Rc<dyn Trait> = ...
+if Rc::ptr_eq(&a, &b) {
+ ...
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/while_immutable_condition.txt b/src/tools/clippy/src/docs/while_immutable_condition.txt
new file mode 100644
index 000000000..71800701f
--- /dev/null
+++ b/src/tools/clippy/src/docs/while_immutable_condition.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks whether variables used within while loop condition
+can be (and are) mutated in the body.
+
+### Why is this bad?
+If the condition is unchanged, entering the body of the loop
+will lead to an infinite loop.
+
+### Known problems
+If the `while`-loop is in a closure, the check for mutation of the
+condition variables in the body can cause false negatives. For example when only `Upvar` `a` is
+in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger.
+
+### Example
+```
+let i = 0;
+while i > 10 {
+ println!("let me loop forever!");
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/while_let_loop.txt b/src/tools/clippy/src/docs/while_let_loop.txt
new file mode 100644
index 000000000..ab7bf6097
--- /dev/null
+++ b/src/tools/clippy/src/docs/while_let_loop.txt
@@ -0,0 +1,25 @@
+### What it does
+Detects `loop + match` combinations that are easier
+written as a `while let` loop.
+
+### Why is this bad?
+The `while let` loop is usually shorter and more
+readable.
+
+### Known problems
+Sometimes the wrong binding is displayed ([#383](https://github.com/rust-lang/rust-clippy/issues/383)).
+
+### Example
+```
+loop {
+ let x = match y {
+ Some(x) => x,
+ None => break,
+ };
+ // .. do something with x
+}
+// is easier written as
+while let Some(x) = y {
+ // .. do something with x
+};
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/while_let_on_iterator.txt b/src/tools/clippy/src/docs/while_let_on_iterator.txt
new file mode 100644
index 000000000..af053c541
--- /dev/null
+++ b/src/tools/clippy/src/docs/while_let_on_iterator.txt
@@ -0,0 +1,20 @@
+### What it does
+Checks for `while let` expressions on iterators.
+
+### Why is this bad?
+Readability. A simple `for` loop is shorter and conveys
+the intent better.
+
+### Example
+```
+while let Some(val) = iter.next() {
+ ..
+}
+```
+
+Use instead:
+```
+for val in &mut iter {
+ ..
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_dependencies.txt b/src/tools/clippy/src/docs/wildcard_dependencies.txt
new file mode 100644
index 000000000..2affaf974
--- /dev/null
+++ b/src/tools/clippy/src/docs/wildcard_dependencies.txt
@@ -0,0 +1,13 @@
+### What it does
+Checks for wildcard dependencies in the `Cargo.toml`.
+
+### Why is this bad?
+[As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html),
+it is highly unlikely that you work with any possible version of your dependency,
+and wildcard dependencies would cause unnecessary breakage in the ecosystem.
+
+### Example
+```
+[dependencies]
+regex = "*"
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_enum_match_arm.txt b/src/tools/clippy/src/docs/wildcard_enum_match_arm.txt
new file mode 100644
index 000000000..09807c01c
--- /dev/null
+++ b/src/tools/clippy/src/docs/wildcard_enum_match_arm.txt
@@ -0,0 +1,25 @@
+### What it does
+Checks for wildcard enum matches using `_`.
+
+### Why is this bad?
+New enum variants added by library updates can be missed.
+
+### Known problems
+Suggested replacements may be incorrect if guards exhaustively cover some
+variants, and also may not use correct path to enum if it's not present in the current scope.
+
+### Example
+```
+match x {
+ Foo::A(_) => {},
+ _ => {},
+}
+```
+
+Use instead:
+```
+match x {
+ Foo::A(_) => {},
+ Foo::B(_) => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_imports.txt b/src/tools/clippy/src/docs/wildcard_imports.txt
new file mode 100644
index 000000000..bd56aa5b0
--- /dev/null
+++ b/src/tools/clippy/src/docs/wildcard_imports.txt
@@ -0,0 +1,45 @@
+### What it does
+Checks for wildcard imports `use _::*`.
+
+### Why is this bad?
+wildcard imports can pollute the namespace. This is especially bad if
+you try to import something through a wildcard, that already has been imported by name from
+a different source:
+
+```
+use crate1::foo; // Imports a function named foo
+use crate2::*; // Has a function named foo
+
+foo(); // Calls crate1::foo
+```
+
+This can lead to confusing error messages at best and to unexpected behavior at worst.
+
+### Exceptions
+Wildcard imports are allowed from modules named `prelude`. Many crates (including the standard library)
+provide modules named "prelude" specifically designed for wildcard import.
+
+`use super::*` is allowed in test modules. This is defined as any module with "test" in the name.
+
+These exceptions can be disabled using the `warn-on-all-wildcard-imports` configuration flag.
+
+### Known problems
+If macros are imported through the wildcard, this macro is not included
+by the suggestion and has to be added by hand.
+
+Applying the suggestion when explicit imports of the things imported with a glob import
+exist, may result in `unused_imports` warnings.
+
+### Example
+```
+use crate1::*;
+
+foo();
+```
+
+Use instead:
+```
+use crate1::foo;
+
+foo();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_in_or_patterns.txt b/src/tools/clippy/src/docs/wildcard_in_or_patterns.txt
new file mode 100644
index 000000000..70468ca41
--- /dev/null
+++ b/src/tools/clippy/src/docs/wildcard_in_or_patterns.txt
@@ -0,0 +1,22 @@
+### What it does
+Checks for wildcard pattern used with others patterns in same match arm.
+
+### Why is this bad?
+Wildcard pattern already covers any other pattern as it will match anyway.
+It makes the code less readable, especially to spot wildcard pattern use in match arm.
+
+### Example
+```
+match s {
+ "a" => {},
+ "bar" | _ => {},
+}
+```
+
+Use instead:
+```
+match s {
+ "a" => {},
+ _ => {},
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/write_literal.txt b/src/tools/clippy/src/docs/write_literal.txt
new file mode 100644
index 000000000..9c41a48f9
--- /dev/null
+++ b/src/tools/clippy/src/docs/write_literal.txt
@@ -0,0 +1,21 @@
+### What it does
+This lint warns about the use of literals as `write!`/`writeln!` args.
+
+### Why is this bad?
+Using literals as `writeln!` args is inefficient
+(c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary
+(i.e., just put the literal in the format string)
+
+### Known problems
+Will also warn with macro calls as arguments that expand to literals
+-- e.g., `writeln!(buf, "{}", env!("FOO"))`.
+
+### Example
+```
+writeln!(buf, "{}", "foo");
+```
+
+Use instead:
+```
+writeln!(buf, "foo");
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/write_with_newline.txt b/src/tools/clippy/src/docs/write_with_newline.txt
new file mode 100644
index 000000000..22845fd65
--- /dev/null
+++ b/src/tools/clippy/src/docs/write_with_newline.txt
@@ -0,0 +1,18 @@
+### What it does
+This lint warns when you use `write!()` with a format
+string that
+ends in a newline.
+
+### Why is this bad?
+You should use `writeln!()` instead, which appends the
+newline.
+
+### Example
+```
+write!(buf, "Hello {}!\n", name);
+```
+
+Use instead:
+```
+writeln!(buf, "Hello {}!", name);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/writeln_empty_string.txt b/src/tools/clippy/src/docs/writeln_empty_string.txt
new file mode 100644
index 000000000..3b3aeb79a
--- /dev/null
+++ b/src/tools/clippy/src/docs/writeln_empty_string.txt
@@ -0,0 +1,16 @@
+### What it does
+This lint warns when you use `writeln!(buf, "")` to
+print a newline.
+
+### Why is this bad?
+You should use `writeln!(buf)`, which is simpler.
+
+### Example
+```
+writeln!(buf, "");
+```
+
+Use instead:
+```
+writeln!(buf);
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wrong_self_convention.txt b/src/tools/clippy/src/docs/wrong_self_convention.txt
new file mode 100644
index 000000000..d6b69ab87
--- /dev/null
+++ b/src/tools/clippy/src/docs/wrong_self_convention.txt
@@ -0,0 +1,39 @@
+### What it does
+Checks for methods with certain name prefixes and which
+doesn't match how self is taken. The actual rules are:
+
+|Prefix |Postfix |`self` taken | `self` type |
+|-------|------------|-------------------------------|--------------|
+|`as_` | none |`&self` or `&mut self` | any |
+|`from_`| none | none | any |
+|`into_`| none |`self` | any |
+|`is_` | none |`&mut self` or `&self` or none | any |
+|`to_` | `_mut` |`&mut self` | any |
+|`to_` | not `_mut` |`self` | `Copy` |
+|`to_` | not `_mut` |`&self` | not `Copy` |
+
+Note: Clippy doesn't trigger methods with `to_` prefix in:
+- Traits definition.
+Clippy can not tell if a type that implements a trait is `Copy` or not.
+- Traits implementation, when `&self` is taken.
+The method signature is controlled by the trait and often `&self` is required for all types that implement the trait
+(see e.g. the `std::string::ToString` trait).
+
+Clippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is required.
+
+Please find more info here:
+https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv
+
+### Why is this bad?
+Consistency breeds readability. If you follow the
+conventions, your users won't be surprised that they, e.g., need to supply a
+mutable reference to a `as_..` function.
+
+### Example
+```
+impl X {
+ fn as_str(self) -> &'static str {
+ // ..
+ }
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wrong_transmute.txt b/src/tools/clippy/src/docs/wrong_transmute.txt
new file mode 100644
index 000000000..9fc71e0e3
--- /dev/null
+++ b/src/tools/clippy/src/docs/wrong_transmute.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for transmutes that can't ever be correct on any
+architecture.
+
+### Why is this bad?
+It's basically guaranteed to be undefined behavior.
+
+### Known problems
+When accessing C, users might want to store pointer
+sized objects in `extradata` arguments to save an allocation.
+
+### Example
+```
+let ptr: *const T = core::intrinsics::transmute('x')
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_divided_by_zero.txt b/src/tools/clippy/src/docs/zero_divided_by_zero.txt
new file mode 100644
index 000000000..394de20c0
--- /dev/null
+++ b/src/tools/clippy/src/docs/zero_divided_by_zero.txt
@@ -0,0 +1,15 @@
+### What it does
+Checks for `0.0 / 0.0`.
+
+### Why is this bad?
+It's less readable than `f32::NAN` or `f64::NAN`.
+
+### Example
+```
+let nan = 0.0f32 / 0.0;
+```
+
+Use instead:
+```
+let nan = f32::NAN;
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_prefixed_literal.txt b/src/tools/clippy/src/docs/zero_prefixed_literal.txt
new file mode 100644
index 000000000..5c5588725
--- /dev/null
+++ b/src/tools/clippy/src/docs/zero_prefixed_literal.txt
@@ -0,0 +1,32 @@
+### What it does
+Warns if an integral constant literal starts with `0`.
+
+### Why is this bad?
+In some languages (including the infamous C language
+and most of its
+family), this marks an octal constant. In Rust however, this is a decimal
+constant. This could
+be confusing for both the writer and a reader of the constant.
+
+### Example
+
+In Rust:
+```
+fn main() {
+ let a = 0123;
+ println!("{}", a);
+}
+```
+
+prints `123`, while in C:
+
+```
+#include <stdio.h>
+
+int main() {
+ int a = 0123;
+ printf("%d\n", a);
+}
+```
+
+prints `83` (as `83 == 0o123` while `123 == 0o173`). \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_ptr.txt b/src/tools/clippy/src/docs/zero_ptr.txt
new file mode 100644
index 000000000..e768a0236
--- /dev/null
+++ b/src/tools/clippy/src/docs/zero_ptr.txt
@@ -0,0 +1,16 @@
+### What it does
+Catch casts from `0` to some pointer type
+
+### Why is this bad?
+This generally means `null` and is better expressed as
+{`std`, `core`}`::ptr::`{`null`, `null_mut`}.
+
+### Example
+```
+let a = 0 as *const u32;
+```
+
+Use instead:
+```
+let a = std::ptr::null::<u32>();
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_sized_map_values.txt b/src/tools/clippy/src/docs/zero_sized_map_values.txt
new file mode 100644
index 000000000..0502bdbf3
--- /dev/null
+++ b/src/tools/clippy/src/docs/zero_sized_map_values.txt
@@ -0,0 +1,24 @@
+### What it does
+Checks for maps with zero-sized value types anywhere in the code.
+
+### Why is this bad?
+Since there is only a single value for a zero-sized type, a map
+containing zero sized values is effectively a set. Using a set in that case improves
+readability and communicates intent more clearly.
+
+### Known problems
+* A zero-sized type cannot be recovered later if it contains private fields.
+* This lints the signature of public items
+
+### Example
+```
+fn unique_words(text: &str) -> HashMap<&str, ()> {
+ todo!();
+}
+```
+Use instead:
+```
+fn unique_words(text: &str) -> HashSet<&str> {
+ todo!();
+}
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zst_offset.txt b/src/tools/clippy/src/docs/zst_offset.txt
new file mode 100644
index 000000000..5810455ee
--- /dev/null
+++ b/src/tools/clippy/src/docs/zst_offset.txt
@@ -0,0 +1,11 @@
+### What it does
+Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to
+zero-sized types
+
+### Why is this bad?
+This is a no-op, and likely unintended
+
+### Example
+```
+unsafe { (&() as *const ()).offset(1) };
+``` \ No newline at end of file
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index c1ec2bd5b..235eae5af 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -95,7 +95,7 @@ struct ClippyCallbacks {
impl rustc_driver::Callbacks for ClippyCallbacks {
// JUSTIFICATION: necessary in clippy driver to set `mir_opt_level`
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
fn config(&mut self, config: &mut interface::Config) {
let previous = config.register_lints.take();
let clippy_args_var = self.clippy_args_var.take();
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index 9ee4a40cb..4a32e0e54 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -7,6 +7,8 @@ use std::env;
use std::path::PathBuf;
use std::process::{self, Command};
+mod docs;
+
const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.
Usage:
@@ -17,6 +19,7 @@ Common options:
--fix Automatically apply lint suggestions. This flag implies `--no-deps`
-h, --help Print this message
-V, --version Print version info and exit
+ --explain LINT Print the documentation for a given lint
Other options are the same as `cargo check`.
@@ -54,6 +57,16 @@ pub fn main() {
return;
}
+ if let Some(pos) = env::args().position(|a| a == "--explain") {
+ if let Some(mut lint) = env::args().nth(pos + 1) {
+ lint.make_ascii_lowercase();
+ docs::explain(&lint.strip_prefix("clippy::").unwrap_or(&lint).replace('-', "_"));
+ } else {
+ show_help();
+ }
+ return;
+ }
+
if let Err(code) = process(env::args().skip(2)) {
process::exit(code);
}
diff --git a/src/tools/clippy/tests/check-fmt.rs b/src/tools/clippy/tests/check-fmt.rs
index 0defd45b6..e106583de 100644
--- a/src/tools/clippy/tests/check-fmt.rs
+++ b/src/tools/clippy/tests/check-fmt.rs
@@ -13,7 +13,7 @@ fn fmt() {
let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let output = Command::new("cargo")
.current_dir(root_dir)
- .args(&["dev", "fmt", "--check"])
+ .args(["dev", "fmt", "--check"])
.output()
.unwrap();
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 92ac1a2be..ba6186e59 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -393,8 +393,8 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
"search_is_some.rs",
"single_component_path_imports_nested_first.rs",
"string_add.rs",
+ "suspicious_to_owned.rs",
"toplevel_ref_arg_non_rustfix.rs",
- "trait_duplication_in_bounds.rs",
"unit_arg.rs",
"unnecessary_clone.rs",
"unnecessary_lazy_eval_unfixable.rs",
@@ -404,16 +404,23 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
];
fn check_rustfix_coverage() {
- let missing_coverage_path = Path::new("target/debug/test/ui/rustfix_missing_coverage.txt");
+ let missing_coverage_path = Path::new("debug/test/ui/rustfix_missing_coverage.txt");
+ let missing_coverage_path = if let Ok(target_dir) = std::env::var("CARGO_TARGET_DIR") {
+ PathBuf::from(target_dir).join(missing_coverage_path)
+ } else {
+ missing_coverage_path.to_path_buf()
+ };
if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.iter().is_sorted_by_key(Path::new));
- for rs_path in missing_coverage_contents.lines() {
- if Path::new(rs_path).starts_with("tests/ui/crashes") {
+ for rs_file in missing_coverage_contents.lines() {
+ let rs_path = Path::new(rs_file);
+ if rs_path.starts_with("tests/ui/crashes") {
continue;
}
- let filename = Path::new(rs_path).strip_prefix("tests/ui/").unwrap();
+ assert!(rs_path.starts_with("tests/ui/"), "{:?}", rs_file);
+ let filename = rs_path.strip_prefix("tests/ui/").unwrap();
assert!(
RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS
.binary_search_by_key(&filename, Path::new)
@@ -421,7 +428,7 @@ fn check_rustfix_coverage() {
"`{}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
Please either add `// run-rustfix` at the top of the file or add the file to \
`RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
- rs_path,
+ rs_file,
);
}
}
diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs
index 5697e8680..961525bbd 100644
--- a/src/tools/clippy/tests/dogfood.rs
+++ b/src/tools/clippy/tests/dogfood.rs
@@ -87,11 +87,11 @@ fn run_clippy_for_package(project: &str, args: &[&str]) {
if cfg!(feature = "internal") {
// internal lints only exist if we build with the internal feature
- command.args(&["-D", "clippy::internal"]);
+ command.args(["-D", "clippy::internal"]);
} else {
// running a clippy built without internal lints on the clippy source
// that contains e.g. `allow(clippy::invalid_paths)`
- command.args(&["-A", "unknown_lints"]);
+ command.args(["-A", "unknown_lints"]);
}
let output = command.output().unwrap();
diff --git a/src/tools/clippy/tests/integration.rs b/src/tools/clippy/tests/integration.rs
index c64425fa0..23a9bef3c 100644
--- a/src/tools/clippy/tests/integration.rs
+++ b/src/tools/clippy/tests/integration.rs
@@ -19,7 +19,7 @@ fn integration_test() {
repo_dir.push(crate_name);
let st = Command::new("git")
- .args(&[
+ .args([
OsStr::new("clone"),
OsStr::new("--depth=1"),
OsStr::new(&repo_url),
@@ -37,7 +37,7 @@ fn integration_test() {
.current_dir(repo_dir)
.env("RUST_BACKTRACE", "full")
.env("CARGO_TARGET_DIR", target_dir)
- .args(&[
+ .args([
"clippy",
"--all-targets",
"--all-features",
diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs
index c3aae1a9a..2e0f4e760 100644
--- a/src/tools/clippy/tests/lint_message_convention.rs
+++ b/src/tools/clippy/tests/lint_message_convention.rs
@@ -19,7 +19,7 @@ impl Message {
// we don't want the first letter after "error: ", "help: " ... to be capitalized
// also no punctuation (except for "?" ?) at the end of a line
static REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
- RegexSet::new(&[
+ RegexSet::new([
r"error: [A-Z]",
r"help: [A-Z]",
r"warning: [A-Z]",
@@ -37,7 +37,7 @@ impl Message {
// sometimes the first character is capitalized and it is legal (like in "C-like enum variants") or
// we want to ask a question ending in "?"
static EXCEPTIONS_SET: LazyLock<RegexSet> = LazyLock::new(|| {
- RegexSet::new(&[
+ RegexSet::new([
r"\.\.\.$",
r".*C-like enum variant discriminant is not portable to 32-bit targets",
r".*Intel x86 assembly syntax used",
diff --git a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
index 533107588..2aa4de490 100644
--- a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
+++ b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
@@ -16,7 +16,7 @@ note: the lint level is defined here
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
= note: `#[deny(clippy::invalid_clippy_version_attribute)]` implied by `#[deny(clippy::internal)]`
- = help: please use a valid sematic version, see `doc/adding_lints.md`
+ = help: please use a valid semantic version, see `doc/adding_lints.md`
= note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this item has an invalid `clippy::version` attribute
@@ -31,7 +31,7 @@ LL | | report_in_external_macro: true
LL | | }
| |_^
|
- = help: please use a valid sematic version, see `doc/adding_lints.md`
+ = help: please use a valid semantic version, see `doc/adding_lints.md`
= note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this lint is missing the `clippy::version` attribute or version value
diff --git a/src/tools/clippy/tests/ui-toml/arithmetic_allowed/clippy.toml b/src/tools/clippy/tests/ui-toml/arithmetic_allowed/clippy.toml
deleted file mode 100644
index cc40570b1..000000000
--- a/src/tools/clippy/tests/ui-toml/arithmetic_allowed/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-arithmetic-allowed = ["Point"]
diff --git a/src/tools/clippy/tests/ui-toml/arithmetic_allowed/arithmetic_allowed.rs b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs
index 195fabdbf..1aed09b7c 100644
--- a/src/tools/clippy/tests/ui-toml/arithmetic_allowed/arithmetic_allowed.rs
+++ b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs
@@ -1,4 +1,4 @@
-#![warn(clippy::arithmetic)]
+#![warn(clippy::arithmetic_side_effects)]
use core::ops::Add;
diff --git a/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/clippy.toml b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/clippy.toml
new file mode 100644
index 000000000..e736256f2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/clippy.toml
@@ -0,0 +1 @@
+arithmetic-side-effects-allowed = ["Point"]
diff --git a/src/tools/clippy/tests/ui-toml/bad_toml_type/clippy.toml b/src/tools/clippy/tests/ui-toml/bad_toml_type/clippy.toml
index 168675394..d48bab08f 100644
--- a/src/tools/clippy/tests/ui-toml/bad_toml_type/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/bad_toml_type/clippy.toml
@@ -1 +1 @@
-blacklisted-names = 42
+disallowed-names = 42
diff --git a/src/tools/clippy/tests/ui-toml/bad_toml_type/conf_bad_type.stderr b/src/tools/clippy/tests/ui-toml/bad_toml_type/conf_bad_type.stderr
index c7bc261de..e3ec60192 100644
--- a/src/tools/clippy/tests/ui-toml/bad_toml_type/conf_bad_type.stderr
+++ b/src/tools/clippy/tests/ui-toml/bad_toml_type/conf_bad_type.stderr
@@ -1,4 +1,4 @@
-error: error reading Clippy's configuration file `$DIR/clippy.toml`: invalid type: integer `42`, expected a sequence for key `blacklisted-names`
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: invalid type: integer `42`, expected a sequence for key `disallowed-names`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.stderr b/src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.stderr
deleted file mode 100644
index 9169bb0e8..000000000
--- a/src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error: use of a blacklisted/placeholder name `foo`
- --> $DIR/blacklisted_names.rs:5:9
- |
-LL | let foo = "bar";
- | ^^^
- |
- = note: `-D clippy::blacklisted-name` implied by `-D warnings`
-
-error: use of a blacklisted/placeholder name `ducks`
- --> $DIR/blacklisted_names.rs:7:9
- |
-LL | let ducks = ["quack", "quack"];
- | ^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/src/tools/clippy/tests/ui-toml/blacklisted_names_append/clippy.toml b/src/tools/clippy/tests/ui-toml/blacklisted_names_append/clippy.toml
deleted file mode 100644
index 0e052ef50..000000000
--- a/src/tools/clippy/tests/ui-toml/blacklisted_names_append/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-blacklisted-names = ["ducks", ".."]
diff --git a/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.stderr b/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.stderr
deleted file mode 100644
index ec6f7f084..000000000
--- a/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: use of a blacklisted/placeholder name `ducks`
- --> $DIR/blacklisted_names.rs:7:9
- |
-LL | let ducks = ["quack", "quack"];
- | ^^^^^
- |
- = note: `-D clippy::blacklisted-name` implied by `-D warnings`
-
-error: aborting due to previous error
-
diff --git a/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/clippy.toml b/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/clippy.toml
deleted file mode 100644
index 4582f1c06..000000000
--- a/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-blacklisted-names = ["ducks"]
diff --git a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/clippy.toml b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/clippy.toml
index ac47b1950..d79a98d05 100644
--- a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/clippy.toml
@@ -1,5 +1,6 @@
-# that one is an error
-cyclomatic-complexity-threshold = 42
+# Expect errors from these deprecated configs
+cyclomatic-complexity-threshold = 2
+blacklisted-names = [ "..", "wibble" ]
# that one is white-listed
[third-party]
diff --git a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs
index f328e4d9d..b4e677ea1 100644
--- a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs
+++ b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs
@@ -1 +1,11 @@
fn main() {}
+
+#[warn(clippy::cognitive_complexity)]
+fn cognitive_complexity() {
+ let x = vec![1, 2, 3];
+ for i in x {
+ if i == 1 {
+ println!("{}", i);
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
index 90021a034..4c560299e 100644
--- a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
@@ -1,4 +1,15 @@
-error: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead
+warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead
-error: aborting due to previous error
+warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `blacklisted-names`. Please use `disallowed-names` instead
+
+error: the function has a cognitive complexity of (3/2)
+ --> $DIR/conf_deprecated_key.rs:4:4
+ |
+LL | fn cognitive_complexity() {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
+ = help: you could split it up into multiple smaller functions
+
+error: aborting due to previous error; 2 warnings emitted
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_append/clippy.toml b/src/tools/clippy/tests/ui-toml/disallowed_names_append/clippy.toml
new file mode 100644
index 000000000..6df96a3c2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_append/clippy.toml
@@ -0,0 +1 @@
+disallowed-names = ["ducks", ".."]
diff --git a/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.rs b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs
index fb2395cf9..a2e2b46c4 100644
--- a/src/tools/clippy/tests/ui-toml/blacklisted_names_replace/blacklisted_names.rs
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs
@@ -1,9 +1,9 @@
-#[warn(clippy::blacklisted_name)]
+#[warn(clippy::disallowed_names)]
fn main() {
// `foo` is part of the default configuration
let foo = "bar";
- // `ducks` was unrightfully blacklisted
+ // `ducks` was unrightfully disallowed
let ducks = ["quack", "quack"];
// `fox` is okay
let fox = ["what", "does", "the", "fox", "say", "?"];
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr
new file mode 100644
index 000000000..23c3e96a8
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr
@@ -0,0 +1,16 @@
+error: use of a disallowed/placeholder name `foo`
+ --> $DIR/disallowed_names.rs:5:9
+ |
+LL | let foo = "bar";
+ | ^^^
+ |
+ = note: `-D clippy::disallowed-names` implied by `-D warnings`
+
+error: use of a disallowed/placeholder name `ducks`
+ --> $DIR/disallowed_names.rs:7:9
+ |
+LL | let ducks = ["quack", "quack"];
+ | ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_replace/clippy.toml b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/clippy.toml
new file mode 100644
index 000000000..a1c515652
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/clippy.toml
@@ -0,0 +1 @@
+disallowed-names = ["ducks"]
diff --git a/src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.rs b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs
index fb2395cf9..a2e2b46c4 100644
--- a/src/tools/clippy/tests/ui-toml/blacklisted_names_append/blacklisted_names.rs
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs
@@ -1,9 +1,9 @@
-#[warn(clippy::blacklisted_name)]
+#[warn(clippy::disallowed_names)]
fn main() {
// `foo` is part of the default configuration
let foo = "bar";
- // `ducks` was unrightfully blacklisted
+ // `ducks` was unrightfully disallowed
let ducks = ["quack", "quack"];
// `fox` is okay
let fox = ["what", "does", "the", "fox", "say", "?"];
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr
new file mode 100644
index 000000000..d961fa340
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr
@@ -0,0 +1,10 @@
+error: use of a disallowed/placeholder name `ducks`
+ --> $DIR/disallowed_names.rs:7:9
+ |
+LL | let ducks = ["quack", "quack"];
+ | ^^^^^
+ |
+ = note: `-D clippy::disallowed-names` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/duplicated_keys/clippy.toml b/src/tools/clippy/tests/ui-toml/duplicated_keys/clippy.toml
new file mode 100644
index 000000000..63a893cc6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/duplicated_keys/clippy.toml
@@ -0,0 +1,5 @@
+cognitive-complexity-threshold = 2
+# This is the deprecated name for the same key
+cyclomatic-complexity-threshold = 3
+# Check we get duplication warning regardless of order
+cognitive-complexity-threshold = 4
diff --git a/src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.rs b/src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.rs
new file mode 100644
index 000000000..f328e4d9d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.stderr b/src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.stderr
new file mode 100644
index 000000000..d99490a24
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/duplicated_keys/duplicated_keys.stderr
@@ -0,0 +1,8 @@
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: duplicate field `cognitive_complexity_threshold` (provided as `cyclomatic_complexity_threshold`)
+
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: duplicate field `cognitive-complexity-threshold`
+
+warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
index 9cb2199ed..c5d95cb8a 100644
--- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
@@ -5,7 +5,7 @@ LL | let _ = opt.expect("");
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::expect-used` implied by `-D warnings`
- = help: if this value is an `None`, it will panic
+ = help: if this value is `None`, it will panic
error: used `expect()` on `a Result` value
--> $DIR/expect_used.rs:11:13
diff --git a/src/tools/clippy/tests/ui-toml/toml_blacklist/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_blacklist/clippy.toml
deleted file mode 100644
index 6abe5a3bb..000000000
--- a/src/tools/clippy/tests/ui-toml/toml_blacklist/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-blacklisted-names = ["toto", "tata", "titi"]
diff --git a/src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.stderr b/src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.stderr
deleted file mode 100644
index 84ba77851..000000000
--- a/src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.stderr
+++ /dev/null
@@ -1,46 +0,0 @@
-error: use of a blacklisted/placeholder name `toto`
- --> $DIR/conf_french_blacklisted_name.rs:6:9
- |
-LL | fn test(toto: ()) {}
- | ^^^^
- |
- = note: `-D clippy::blacklisted-name` implied by `-D warnings`
-
-error: use of a blacklisted/placeholder name `toto`
- --> $DIR/conf_french_blacklisted_name.rs:9:9
- |
-LL | let toto = 42;
- | ^^^^
-
-error: use of a blacklisted/placeholder name `tata`
- --> $DIR/conf_french_blacklisted_name.rs:10:9
- |
-LL | let tata = 42;
- | ^^^^
-
-error: use of a blacklisted/placeholder name `titi`
- --> $DIR/conf_french_blacklisted_name.rs:11:9
- |
-LL | let titi = 42;
- | ^^^^
-
-error: use of a blacklisted/placeholder name `toto`
- --> $DIR/conf_french_blacklisted_name.rs:17:10
- |
-LL | (toto, Some(tata), titi @ Some(_)) => (),
- | ^^^^
-
-error: use of a blacklisted/placeholder name `tata`
- --> $DIR/conf_french_blacklisted_name.rs:17:21
- |
-LL | (toto, Some(tata), titi @ Some(_)) => (),
- | ^^^^
-
-error: use of a blacklisted/placeholder name `titi`
- --> $DIR/conf_french_blacklisted_name.rs:17:28
- |
-LL | (toto, Some(tata), titi @ Some(_)) => (),
- | ^^^^
-
-error: aborting due to 7 previous errors
-
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallow/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_disallow/clippy.toml
new file mode 100644
index 000000000..e4f0cb6df
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/toml_disallow/clippy.toml
@@ -0,0 +1 @@
+disallowed-names = ["toto", "tata", "titi"]
diff --git a/src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.rs b/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs
index cb35d0e85..2f86b3eda 100644
--- a/src/tools/clippy/tests/ui-toml/toml_blacklist/conf_french_blacklisted_name.rs
+++ b/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs
@@ -1,7 +1,7 @@
#![allow(dead_code)]
#![allow(clippy::single_match)]
#![allow(unused_variables)]
-#![warn(clippy::blacklisted_name)]
+#![warn(clippy::disallowed_names)]
fn test(toto: ()) {}
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr b/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr
new file mode 100644
index 000000000..9082c1c54
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr
@@ -0,0 +1,46 @@
+error: use of a disallowed/placeholder name `toto`
+ --> $DIR/conf_french_disallowed_name.rs:6:9
+ |
+LL | fn test(toto: ()) {}
+ | ^^^^
+ |
+ = note: `-D clippy::disallowed-names` implied by `-D warnings`
+
+error: use of a disallowed/placeholder name `toto`
+ --> $DIR/conf_french_disallowed_name.rs:9:9
+ |
+LL | let toto = 42;
+ | ^^^^
+
+error: use of a disallowed/placeholder name `tata`
+ --> $DIR/conf_french_disallowed_name.rs:10:9
+ |
+LL | let tata = 42;
+ | ^^^^
+
+error: use of a disallowed/placeholder name `titi`
+ --> $DIR/conf_french_disallowed_name.rs:11:9
+ |
+LL | let titi = 42;
+ | ^^^^
+
+error: use of a disallowed/placeholder name `toto`
+ --> $DIR/conf_french_disallowed_name.rs:17:10
+ |
+LL | (toto, Some(tata), titi @ Some(_)) => (),
+ | ^^^^
+
+error: use of a disallowed/placeholder name `tata`
+ --> $DIR/conf_french_disallowed_name.rs:17:21
+ |
+LL | (toto, Some(tata), titi @ Some(_)) => (),
+ | ^^^^
+
+error: use of a disallowed/placeholder name `titi`
+ --> $DIR/conf_french_disallowed_name.rs:17:28
+ |
+LL | (toto, Some(tata), titi @ Some(_)) => (),
+ | ^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index fe5139c47..f27f78d15 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -3,7 +3,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
allow-expect-in-tests
allow-unwrap-in-tests
allowed-scripts
- arithmetic-allowed
+ arithmetic-side-effects-allowed
array-size-threshold
avoid-breaking-exported-api
await-holding-invalid-types
@@ -12,12 +12,14 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
cognitive-complexity-threshold
cyclomatic-complexity-threshold
disallowed-methods
+ disallowed-names
disallowed-types
doc-valid-idents
enable-raw-pointer-heuristic-for-send
enforced-import-renames
enum-variant-name-threshold
enum-variant-size-threshold
+ large-error-threshold
literal-representation-threshold
max-fn-params-bools
max-include-file-size
diff --git a/src/tools/clippy/tests/ui/arithmetic.fixed b/src/tools/clippy/tests/ui/arithmetic.fixed
deleted file mode 100644
index a2a1c4394..000000000
--- a/src/tools/clippy/tests/ui/arithmetic.fixed
+++ /dev/null
@@ -1,27 +0,0 @@
-// run-rustfix
-
-#![allow(clippy::unnecessary_owned_empty_strings)]
-#![feature(saturating_int_impl)]
-#![warn(clippy::arithmetic)]
-
-use core::num::{Saturating, Wrapping};
-
-pub fn hard_coded_allowed() {
- let _ = Saturating(0u32) + Saturating(0u32);
- let _ = String::new() + "";
- let _ = Wrapping(0u32) + Wrapping(0u32);
-
- let saturating: Saturating<u32> = Saturating(0u32);
- let string: String = String::new();
- let wrapping: Wrapping<u32> = Wrapping(0u32);
-
- let inferred_saturating = saturating + saturating;
- let inferred_string = string + "";
- let inferred_wrapping = wrapping + wrapping;
-
- let _ = inferred_saturating + inferred_saturating;
- let _ = inferred_string + "";
- let _ = inferred_wrapping + inferred_wrapping;
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic.rs b/src/tools/clippy/tests/ui/arithmetic.rs
deleted file mode 100644
index a2a1c4394..000000000
--- a/src/tools/clippy/tests/ui/arithmetic.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// run-rustfix
-
-#![allow(clippy::unnecessary_owned_empty_strings)]
-#![feature(saturating_int_impl)]
-#![warn(clippy::arithmetic)]
-
-use core::num::{Saturating, Wrapping};
-
-pub fn hard_coded_allowed() {
- let _ = Saturating(0u32) + Saturating(0u32);
- let _ = String::new() + "";
- let _ = Wrapping(0u32) + Wrapping(0u32);
-
- let saturating: Saturating<u32> = Saturating(0u32);
- let string: String = String::new();
- let wrapping: Wrapping<u32> = Wrapping(0u32);
-
- let inferred_saturating = saturating + saturating;
- let inferred_string = string + "";
- let inferred_wrapping = wrapping + wrapping;
-
- let _ = inferred_saturating + inferred_saturating;
- let _ = inferred_string + "";
- let _ = inferred_wrapping + inferred_wrapping;
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
new file mode 100644
index 000000000..f5390c746
--- /dev/null
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -0,0 +1,57 @@
+#![allow(clippy::assign_op_pattern, clippy::unnecessary_owned_empty_strings)]
+#![feature(inline_const, saturating_int_impl)]
+#![warn(clippy::arithmetic_side_effects)]
+
+use core::num::{Saturating, Wrapping};
+
+pub fn hard_coded_allowed() {
+ let _ = 1f32 + 1f32;
+ let _ = 1f64 + 1f64;
+
+ let _ = Saturating(0u32) + Saturating(0u32);
+ let _ = String::new() + "";
+ let _ = Wrapping(0u32) + Wrapping(0u32);
+
+ let saturating: Saturating<u32> = Saturating(0u32);
+ let string: String = String::new();
+ let wrapping: Wrapping<u32> = Wrapping(0u32);
+
+ let inferred_saturating = saturating + saturating;
+ let inferred_string = string + "";
+ let inferred_wrapping = wrapping + wrapping;
+
+ let _ = inferred_saturating + inferred_saturating;
+ let _ = inferred_string + "";
+ let _ = inferred_wrapping + inferred_wrapping;
+}
+
+#[rustfmt::skip]
+pub fn non_overflowing_ops() {
+ const _: i32 = { let mut n = 1; n += 1; n };
+ let _ = const { let mut n = 1; n += 1; n };
+
+ const _: i32 = { let mut n = 1; n = n + 1; n };
+ let _ = const { let mut n = 1; n = n + 1; n };
+
+ const _: i32 = { let mut n = 1; n = 1 + n; n };
+ let _ = const { let mut n = 1; n = 1 + n; n };
+
+ const _: i32 = 1 + 1;
+ let _ = 1 + 1;
+ let _ = const { 1 + 1 };
+
+ let mut _a = 1;
+ _a *= 1;
+ _a /= 1;
+}
+
+#[rustfmt::skip]
+pub fn overflowing_ops() {
+ let mut _a = 1; _a += 1;
+
+ let mut _b = 1; _b = _b + 1;
+
+ let mut _c = 1; _c = 1 + _c;
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
new file mode 100644
index 000000000..6c4c8bdec
--- /dev/null
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -0,0 +1,22 @@
+error: arithmetic detected
+ --> $DIR/arithmetic_side_effects.rs:50:21
+ |
+LL | let mut _a = 1; _a += 1;
+ | ^^^^^^^
+ |
+ = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
+
+error: arithmetic detected
+ --> $DIR/arithmetic_side_effects.rs:52:26
+ |
+LL | let mut _b = 1; _b = _b + 1;
+ | ^^^^^^
+
+error: arithmetic detected
+ --> $DIR/arithmetic_side_effects.rs:54:26
+ |
+LL | let mut _c = 1; _c = 1 + _c;
+ | ^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
index 7bde72e4b..795f435f2 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
@@ -27,6 +27,14 @@ fn main() {
let r: Result<Foo, Foo> = Ok(Foo);
assert!(r.is_ok());
+ // test ok with some messages
+ let r: Result<Foo, DebugFoo> = Ok(Foo);
+ assert!(r.is_ok(), "oops");
+
+ // test ok with unit error
+ let r: Result<Foo, ()> = Ok(Foo);
+ assert!(r.is_ok());
+
// test temporary ok
fn get_ok() -> Result<Foo, DebugFoo> {
Ok(Foo)
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.rs b/src/tools/clippy/tests/ui/assertions_on_result_states.rs
index 4c5af81ef..1101aec1e 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.rs
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.rs
@@ -27,6 +27,14 @@ fn main() {
let r: Result<Foo, Foo> = Ok(Foo);
assert!(r.is_ok());
+ // test ok with some messages
+ let r: Result<Foo, DebugFoo> = Ok(Foo);
+ assert!(r.is_ok(), "oops");
+
+ // test ok with unit error
+ let r: Result<Foo, ()> = Ok(Foo);
+ assert!(r.is_ok());
+
// test temporary ok
fn get_ok() -> Result<Foo, DebugFoo> {
Ok(Foo)
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
index 13c2dd877..97a5f3dfc 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
@@ -7,31 +7,31 @@ LL | assert!(r.is_ok());
= note: `-D clippy::assertions-on-result-states` implied by `-D warnings`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:34:5
+ --> $DIR/assertions_on_result_states.rs:42:5
|
LL | assert!(get_ok().is_ok());
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok().unwrap()`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:37:5
+ --> $DIR/assertions_on_result_states.rs:45:5
|
LL | assert!(get_ok_macro!().is_ok());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok_macro!().unwrap()`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:50:5
+ --> $DIR/assertions_on_result_states.rs:58:5
|
LL | assert!(r.is_ok());
| ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:56:9
+ --> $DIR/assertions_on_result_states.rs:64:9
|
LL | assert!(r.is_ok());
| ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`
error: called `assert!` with `Result::is_err`
- --> $DIR/assertions_on_result_states.rs:64:5
+ --> $DIR/assertions_on_result_states.rs:72:5
|
LL | assert!(r.is_err());
| ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()`
diff --git a/src/tools/clippy/tests/ui/author.stdout b/src/tools/clippy/tests/ui/author.stdout
index 312586303..597318a55 100644
--- a/src/tools/clippy/tests/ui/author.stdout
+++ b/src/tools/clippy/tests/ui/author.stdout
@@ -6,7 +6,7 @@ if_chain! {
if match_qpath(qpath, &["char"]);
if let ExprKind::Lit(ref lit) = expr.kind;
if let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node;
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind;
if name.as_str() == "x";
then {
// report your lint here
diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout
index 2fc4a7d1f..a529981e2 100644
--- a/src/tools/clippy/tests/ui/author/blocks.stdout
+++ b/src/tools/clippy/tests/ui/author/blocks.stdout
@@ -5,13 +5,13 @@ if_chain! {
if let Some(init) = local.init;
if let ExprKind::Lit(ref lit) = init.kind;
if let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node;
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind;
if name.as_str() == "x";
if let StmtKind::Local(local1) = block.stmts[1].kind;
if let Some(init1) = local1.init;
if let ExprKind::Lit(ref lit1) = init1.kind;
if let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node;
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local1.pat.kind;
if name1.as_str() == "_t";
if let StmtKind::Semi(e) = block.stmts[2].kind;
if let ExprKind::Unary(UnOp::Neg, inner) = e.kind;
@@ -31,7 +31,7 @@ if_chain! {
if let ExprKind::Path(ref qpath) = func.kind;
if match_qpath(qpath, &["String", "new"]);
if args.is_empty();
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind;
if name.as_str() == "expr";
if let Some(trailing_expr) = block.expr;
if let ExprKind::Call(func1, args1) = trailing_expr.kind;
diff --git a/src/tools/clippy/tests/ui/author/loop.stdout b/src/tools/clippy/tests/ui/author/loop.stdout
index 3d9560f69..ceb53fcd4 100644
--- a/src/tools/clippy/tests/ui/author/loop.stdout
+++ b/src/tools/clippy/tests/ui/author/loop.stdout
@@ -1,6 +1,6 @@
if_chain! {
if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr);
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind;
if name.as_str() == "y";
if let ExprKind::Struct(qpath, fields, None) = arg.kind;
if matches!(qpath, QPath::LangItem(LangItem::Range, _));
@@ -17,7 +17,7 @@ if_chain! {
if let Some(init) = local.init;
if let ExprKind::Path(ref qpath1) = init.kind;
if match_qpath(qpath1, &["y"]);
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind;
if name1.as_str() == "z";
if block.expr.is_none();
then {
diff --git a/src/tools/clippy/tests/ui/author/matches.stdout b/src/tools/clippy/tests/ui/author/matches.stdout
index 38444a009..2cf69a035 100644
--- a/src/tools/clippy/tests/ui/author/matches.stdout
+++ b/src/tools/clippy/tests/ui/author/matches.stdout
@@ -21,7 +21,7 @@ if_chain! {
if let Some(init1) = local1.init;
if let ExprKind::Lit(ref lit4) = init1.kind;
if let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node;
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local1.pat.kind;
if name.as_str() == "x";
if let Some(trailing_expr) = block.expr;
if let ExprKind::Path(ref qpath) = trailing_expr.kind;
@@ -30,7 +30,7 @@ if_chain! {
if arms[2].guard.is_none();
if let ExprKind::Lit(ref lit5) = arms[2].body.kind;
if let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node;
- if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind;
+ if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind;
if name1.as_str() == "a";
then {
// report your lint here
diff --git a/src/tools/clippy/tests/ui/author/struct.rs b/src/tools/clippy/tests/ui/author/struct.rs
index 5fdf3433a..a99bdfc13 100644
--- a/src/tools/clippy/tests/ui/author/struct.rs
+++ b/src/tools/clippy/tests/ui/author/struct.rs
@@ -1,4 +1,9 @@
-#[allow(clippy::unnecessary_operation, clippy::single_match)]
+#![allow(
+ clippy::unnecessary_operation,
+ clippy::single_match,
+ clippy::no_effect,
+ clippy::bool_to_int_with_if
+)]
fn main() {
struct Test {
field: u32,
diff --git a/src/tools/clippy/tests/ui/author/struct.stdout b/src/tools/clippy/tests/ui/author/struct.stdout
index 5e78b7c9d..b5bbc9e21 100644
--- a/src/tools/clippy/tests/ui/author/struct.stdout
+++ b/src/tools/clippy/tests/ui/author/struct.stdout
@@ -53,11 +53,11 @@ if_chain! {
}
}
if_chain! {
- if let ExprKind::MethodCall(method_name, args, _) = expr.kind;
+ if let ExprKind::MethodCall(method_name, receiver, args, _) = expr.kind;
if method_name.ident.as_str() == "test";
- if args.len() == 1;
- if let ExprKind::Path(ref qpath) = args[0].kind;
+ if let ExprKind::Path(ref qpath) = receiver.kind;
if match_qpath(qpath, &["test_method_call"]);
+ if args.is_empty();
then {
// report your lint here
}
diff --git a/src/tools/clippy/tests/ui/blacklisted_name.stderr b/src/tools/clippy/tests/ui/blacklisted_name.stderr
deleted file mode 100644
index 70dbdaece..000000000
--- a/src/tools/clippy/tests/ui/blacklisted_name.stderr
+++ /dev/null
@@ -1,88 +0,0 @@
-error: use of a blacklisted/placeholder name `foo`
- --> $DIR/blacklisted_name.rs:11:9
- |
-LL | fn test(foo: ()) {}
- | ^^^
- |
- = note: `-D clippy::blacklisted-name` implied by `-D warnings`
-
-error: use of a blacklisted/placeholder name `foo`
- --> $DIR/blacklisted_name.rs:14:9
- |
-LL | let foo = 42;
- | ^^^
-
-error: use of a blacklisted/placeholder name `baz`
- --> $DIR/blacklisted_name.rs:15:9
- |
-LL | let baz = 42;
- | ^^^
-
-error: use of a blacklisted/placeholder name `quux`
- --> $DIR/blacklisted_name.rs:16:9
- |
-LL | let quux = 42;
- | ^^^^
-
-error: use of a blacklisted/placeholder name `foo`
- --> $DIR/blacklisted_name.rs:27:10
- |
-LL | (foo, Some(baz), quux @ Some(_)) => (),
- | ^^^
-
-error: use of a blacklisted/placeholder name `baz`
- --> $DIR/blacklisted_name.rs:27:20
- |
-LL | (foo, Some(baz), quux @ Some(_)) => (),
- | ^^^
-
-error: use of a blacklisted/placeholder name `quux`
- --> $DIR/blacklisted_name.rs:27:26
- |
-LL | (foo, Some(baz), quux @ Some(_)) => (),
- | ^^^^
-
-error: use of a blacklisted/placeholder name `foo`
- --> $DIR/blacklisted_name.rs:32:19
- |
-LL | fn issue_1647(mut foo: u8) {
- | ^^^
-
-error: use of a blacklisted/placeholder name `baz`
- --> $DIR/blacklisted_name.rs:33:13
- |
-LL | let mut baz = 0;
- | ^^^
-
-error: use of a blacklisted/placeholder name `quux`
- --> $DIR/blacklisted_name.rs:34:21
- |
-LL | if let Some(mut quux) = Some(42) {}
- | ^^^^
-
-error: use of a blacklisted/placeholder name `baz`
- --> $DIR/blacklisted_name.rs:38:13
- |
-LL | let ref baz = 0;
- | ^^^
-
-error: use of a blacklisted/placeholder name `quux`
- --> $DIR/blacklisted_name.rs:39:21
- |
-LL | if let Some(ref quux) = Some(42) {}
- | ^^^^
-
-error: use of a blacklisted/placeholder name `baz`
- --> $DIR/blacklisted_name.rs:43:17
- |
-LL | let ref mut baz = 0;
- | ^^^
-
-error: use of a blacklisted/placeholder name `quux`
- --> $DIR/blacklisted_name.rs:44:25
- |
-LL | if let Some(ref mut quux) = Some(42) {}
- | ^^^^
-
-error: aborting due to 14 previous errors
-
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed
new file mode 100644
index 000000000..9c1098dc4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed
@@ -0,0 +1,85 @@
+// run-rustfix
+
+#![warn(clippy::bool_to_int_with_if)]
+#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
+
+fn main() {
+ let a = true;
+ let b = false;
+
+ let x = 1;
+ let y = 2;
+
+ // Should lint
+ // precedence
+ i32::from(a);
+ i32::from(!a);
+ i32::from(a || b);
+ i32::from(cond(a, b));
+ i32::from(x + y < 4);
+
+ // if else if
+ if a {
+ 123
+ } else {i32::from(b)};
+
+ // Shouldn't lint
+
+ if a {
+ 1
+ } else if b {
+ 0
+ } else {
+ 3
+ };
+
+ if a {
+ 3
+ } else if b {
+ 1
+ } else {
+ -2
+ };
+
+ if a {
+ 3
+ } else {
+ 0
+ };
+ if a {
+ side_effect();
+ 1
+ } else {
+ 0
+ };
+ if a {
+ 1
+ } else {
+ side_effect();
+ 0
+ };
+
+ // multiple else ifs
+ if a {
+ 123
+ } else if b {
+ 1
+ } else if a | b {
+ 0
+ } else {
+ 123
+ };
+
+ some_fn(a);
+}
+
+// Lint returns and type inference
+fn some_fn(a: bool) -> u8 {
+ u8::from(a)
+}
+
+fn side_effect() {}
+
+fn cond(a: bool, b: bool) -> bool {
+ a || b
+}
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs
new file mode 100644
index 000000000..0c967dac6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs
@@ -0,0 +1,109 @@
+// run-rustfix
+
+#![warn(clippy::bool_to_int_with_if)]
+#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
+
+fn main() {
+ let a = true;
+ let b = false;
+
+ let x = 1;
+ let y = 2;
+
+ // Should lint
+ // precedence
+ if a {
+ 1
+ } else {
+ 0
+ };
+ if !a {
+ 1
+ } else {
+ 0
+ };
+ if a || b {
+ 1
+ } else {
+ 0
+ };
+ if cond(a, b) {
+ 1
+ } else {
+ 0
+ };
+ if x + y < 4 {
+ 1
+ } else {
+ 0
+ };
+
+ // if else if
+ if a {
+ 123
+ } else if b {
+ 1
+ } else {
+ 0
+ };
+
+ // Shouldn't lint
+
+ if a {
+ 1
+ } else if b {
+ 0
+ } else {
+ 3
+ };
+
+ if a {
+ 3
+ } else if b {
+ 1
+ } else {
+ -2
+ };
+
+ if a {
+ 3
+ } else {
+ 0
+ };
+ if a {
+ side_effect();
+ 1
+ } else {
+ 0
+ };
+ if a {
+ 1
+ } else {
+ side_effect();
+ 0
+ };
+
+ // multiple else ifs
+ if a {
+ 123
+ } else if b {
+ 1
+ } else if a | b {
+ 0
+ } else {
+ 123
+ };
+
+ some_fn(a);
+}
+
+// Lint returns and type inference
+fn some_fn(a: bool) -> u8 {
+ if a { 1 } else { 0 }
+}
+
+fn side_effect() {}
+
+fn cond(a: bool, b: bool) -> bool {
+ a || b
+}
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
new file mode 100644
index 000000000..8647a9cff
--- /dev/null
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
@@ -0,0 +1,84 @@
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:15:5
+ |
+LL | / if a {
+LL | | 1
+LL | | } else {
+LL | | 0
+LL | | };
+ | |_____^ help: replace with from: `i32::from(a)`
+ |
+ = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`
+ = note: `a as i32` or `a.into()` can also be valid options
+
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:20:5
+ |
+LL | / if !a {
+LL | | 1
+LL | | } else {
+LL | | 0
+LL | | };
+ | |_____^ help: replace with from: `i32::from(!a)`
+ |
+ = note: `!a as i32` or `!a.into()` can also be valid options
+
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:25:5
+ |
+LL | / if a || b {
+LL | | 1
+LL | | } else {
+LL | | 0
+LL | | };
+ | |_____^ help: replace with from: `i32::from(a || b)`
+ |
+ = note: `(a || b) as i32` or `(a || b).into()` can also be valid options
+
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:30:5
+ |
+LL | / if cond(a, b) {
+LL | | 1
+LL | | } else {
+LL | | 0
+LL | | };
+ | |_____^ help: replace with from: `i32::from(cond(a, b))`
+ |
+ = note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options
+
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:35:5
+ |
+LL | / if x + y < 4 {
+LL | | 1
+LL | | } else {
+LL | | 0
+LL | | };
+ | |_____^ help: replace with from: `i32::from(x + y < 4)`
+ |
+ = note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options
+
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:44:12
+ |
+LL | } else if b {
+ | ____________^
+LL | | 1
+LL | | } else {
+LL | | 0
+LL | | };
+ | |_____^ help: replace with from: `{i32::from(b)}`
+ |
+ = note: `b as i32` or `b.into()` can also be valid options
+
+error: boolean to int conversion using if
+ --> $DIR/bool_to_int_with_if.rs:102:5
+ |
+LL | if a { 1 } else { 0 }
+ | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`
+ |
+ = note: `a as u8` or `a.into()` can also be valid options
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/borrow_box.rs b/src/tools/clippy/tests/ui/borrow_box.rs
index b606f773c..35ed87b0f 100644
--- a/src/tools/clippy/tests/ui/borrow_box.rs
+++ b/src/tools/clippy/tests/ui/borrow_box.rs
@@ -1,5 +1,5 @@
#![deny(clippy::borrowed_box)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
#![allow(unused_variables)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/box_collection.rs b/src/tools/clippy/tests/ui/box_collection.rs
index 1a74cdb3f..0780c8f05 100644
--- a/src/tools/clippy/tests/ui/box_collection.rs
+++ b/src/tools/clippy/tests/ui/box_collection.rs
@@ -2,7 +2,7 @@
#![allow(
clippy::boxed_local,
clippy::needless_pass_by_value,
- clippy::blacklisted_name,
+ clippy::disallowed_names,
unused
)]
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
index 0d65071af..6f0485b52 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
@@ -14,31 +14,31 @@ fn is_rust_file(filename: &str) -> bool {
fn main() {
// std::string::String and &str should trigger the lint failure with .ext12
- let _ = String::from("").ends_with(".ext12");
+ let _ = String::new().ends_with(".ext12");
let _ = "str".ends_with(".ext12");
// The test struct should not trigger the lint failure with .ext12
TestStruct {}.ends_with(".ext12");
// std::string::String and &str should trigger the lint failure with .EXT12
- let _ = String::from("").ends_with(".EXT12");
+ let _ = String::new().ends_with(".EXT12");
let _ = "str".ends_with(".EXT12");
// The test struct should not trigger the lint failure with .EXT12
TestStruct {}.ends_with(".EXT12");
// Should not trigger the lint failure with .eXT12
- let _ = String::from("").ends_with(".eXT12");
+ let _ = String::new().ends_with(".eXT12");
let _ = "str".ends_with(".eXT12");
TestStruct {}.ends_with(".eXT12");
// Should not trigger the lint failure with .EXT123 (too long)
- let _ = String::from("").ends_with(".EXT123");
+ let _ = String::new().ends_with(".EXT123");
let _ = "str".ends_with(".EXT123");
TestStruct {}.ends_with(".EXT123");
// Shouldn't fail if it doesn't start with a dot
- let _ = String::from("").ends_with("a.ext");
+ let _ = String::new().ends_with("a.ext");
let _ = "str".ends_with("a.extA");
TestStruct {}.ends_with("a.ext");
}
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
index 05b98169f..5d9a043ed 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
@@ -8,10 +8,10 @@ LL | filename.ends_with(".rs")
= help: consider using a case-insensitive comparison instead
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:17:30
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:17:27
|
-LL | let _ = String::from("").ends_with(".ext12");
- | ^^^^^^^^^^^^^^^^^^^
+LL | let _ = String::new().ends_with(".ext12");
+ | ^^^^^^^^^^^^^^^^^^^
|
= help: consider using a case-insensitive comparison instead
@@ -24,10 +24,10 @@ LL | let _ = "str".ends_with(".ext12");
= help: consider using a case-insensitive comparison instead
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:24:30
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:24:27
|
-LL | let _ = String::from("").ends_with(".EXT12");
- | ^^^^^^^^^^^^^^^^^^^
+LL | let _ = String::new().ends_with(".EXT12");
+ | ^^^^^^^^^^^^^^^^^^^
|
= help: consider using a case-insensitive comparison instead
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
index a68b32b09..7ecefd7b1 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
@@ -26,4 +26,6 @@ fn main() {
let _ = a.unsigned_abs() as u32;
let _ = a.unsigned_abs() as u64;
let _ = a.unsigned_abs() as u128;
+
+ let _ = (x as i64 - y as i64).unsigned_abs() as u32;
}
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
index 110fbc6c2..30c603fca 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
@@ -26,4 +26,6 @@ fn main() {
let _ = a.abs() as u32;
let _ = a.abs() as u64;
let _ = a.abs() as u128;
+
+ let _ = (x as i64 - y as i64).abs() as u32;
}
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
index 02c24e106..045537745 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
@@ -96,5 +96,11 @@ error: casting the result of `isize::abs()` to u128
LL | let _ = a.abs() as u128;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
-error: aborting due to 16 previous errors
+error: casting the result of `i64::abs()` to u32
+ --> $DIR/cast_abs_to_unsigned.rs:30:13
+ |
+LL | let _ = (x as i64 - y as i64).abs() as u32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(x as i64 - y as i64).unsigned_abs()`
+
+error: aborting due to 17 previous errors
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
new file mode 100644
index 000000000..b70c19129
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
@@ -0,0 +1,24 @@
+// run-rustfix
+#![warn(clippy::cast_slice_from_raw_parts)]
+
+#[allow(unused_imports, unused_unsafe)]
+fn main() {
+ let mut vec = vec![0u8; 1];
+ let ptr: *const u8 = vec.as_ptr();
+ let mptr = vec.as_mut_ptr();
+ let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) };
+ let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) };
+ let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+ {
+ use core::slice;
+ let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+ use slice as one;
+ let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+ }
+ {
+ use std::slice;
+ let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+ use slice as one;
+ let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+ }
+}
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
new file mode 100644
index 000000000..c1b316765
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
@@ -0,0 +1,24 @@
+// run-rustfix
+#![warn(clippy::cast_slice_from_raw_parts)]
+
+#[allow(unused_imports, unused_unsafe)]
+fn main() {
+ let mut vec = vec![0u8; 1];
+ let ptr: *const u8 = vec.as_ptr();
+ let mptr = vec.as_mut_ptr();
+ let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] };
+ let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };
+ let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8];
+ {
+ use core::slice;
+ let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+ use slice as one;
+ let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+ }
+ {
+ use std::slice;
+ let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+ use slice as one;
+ let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+ }
+}
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
new file mode 100644
index 000000000..f07801c19
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
@@ -0,0 +1,46 @@
+error: casting the result of `from_raw_parts` to *const [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:9:35
+ |
+LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+ |
+ = note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings`
+
+error: casting the result of `from_raw_parts_mut` to *mut [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:10:35
+ |
+LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:11:26
+ |
+LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:14:30
+ |
+LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:16:30
+ |
+LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:20:30
+ |
+LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+ --> $DIR/cast_raw_slice_pointer_cast.rs:22:30
+ |
+LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.fixed b/src/tools/clippy/tests/ui/clone_on_copy.fixed
index dc0627626..72b122270 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.fixed
+++ b/src/tools/clippy/tests/ui/clone_on_copy.fixed
@@ -21,7 +21,7 @@ fn is_ascii(ch: char) -> bool {
ch.is_ascii()
}
-fn clone_on_copy() {
+fn clone_on_copy() -> Option<(i32)> {
42;
vec![1].clone(); // ok, not a Copy type
@@ -71,4 +71,9 @@ fn clone_on_copy() {
// Issue #5436
let mut vec = Vec::new();
vec.push(42);
+
+ // Issue #9277
+ let opt: &Option<i32> = &None;
+ let value = (*opt)?; // operator precedence needed (*opt)?
+ None
}
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.rs b/src/tools/clippy/tests/ui/clone_on_copy.rs
index 8c39d0d55..03e210eba 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.rs
+++ b/src/tools/clippy/tests/ui/clone_on_copy.rs
@@ -21,7 +21,7 @@ fn is_ascii(ch: char) -> bool {
ch.is_ascii()
}
-fn clone_on_copy() {
+fn clone_on_copy() -> Option<(i32)> {
42.clone();
vec![1].clone(); // ok, not a Copy type
@@ -71,4 +71,9 @@ fn clone_on_copy() {
// Issue #5436
let mut vec = Vec::new();
vec.push(42.clone());
+
+ // Issue #9277
+ let opt: &Option<i32> = &None;
+ let value = opt.clone()?; // operator precedence needed (*opt)?
+ None
}
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.stderr b/src/tools/clippy/tests/ui/clone_on_copy.stderr
index 861543d0a..42ae22777 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.stderr
+++ b/src/tools/clippy/tests/ui/clone_on_copy.stderr
@@ -48,5 +48,11 @@ error: using `clone` on type `i32` which implements the `Copy` trait
LL | vec.push(42.clone());
| ^^^^^^^^^^ help: try removing the `clone` call: `42`
-error: aborting due to 8 previous errors
+error: using `clone` on type `std::option::Option<i32>` which implements the `Copy` trait
+ --> $DIR/clone_on_copy.rs:77:17
+ |
+LL | let value = opt.clone()?; // operator precedence needed (*opt)?
+ | ^^^^^^^^^^^ help: try dereferencing it: `(*opt)`
+
+error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.fixed b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed
new file mode 100644
index 000000000..49fc9a962
--- /dev/null
+++ b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+#![warn(clippy::collapsible_str_replace)]
+
+fn get_filter() -> char {
+ 'u'
+}
+
+fn main() {
+ let d = 'd';
+ let p = 'p';
+ let s = 's';
+ let u = 'u';
+ let l = "l";
+
+ let mut iter = ["l", "z"].iter();
+
+ // LINT CASES
+ let _ = "hesuo worpd".replace(['s', 'u'], "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u'], l);
+
+ let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l");
+
+ let _ = "hesuo worpd"
+ .replace(['s', 'u', 'p', 'd'], "l");
+
+ let _ = "hesuo world".replace([s, 'u'], "l");
+
+ let _ = "hesuo worpd".replace([s, 'u', 'p'], "l");
+
+ let _ = "hesuo worpd".replace([s, u, 'p'], "l");
+
+ let _ = "hesuo worpd".replace([s, u, p], "l");
+
+ let _ = "hesuo worlp".replace(['s', 'u'], "l").replace('p', "d");
+
+ let _ = "hesuo worpd".replace('s', "x").replace(['u', 'p'], "l");
+
+ // Note: Future iterations could lint `replace(|c| matches!(c, "su" | 'd' | 'p'), "l")`
+ let _ = "hesudo worpd".replace("su", "l").replace(['d', 'p'], "l");
+
+ let _ = "hesudo worpd".replace([d, 'p'], "l").replace("su", "l");
+
+ let _ = "hesuo world".replace([get_filter(), 's'], "l");
+
+ // NO LINT CASES
+ let _ = "hesuo world".replace('s', "l").replace('u', "p");
+
+ let _ = "hesuo worpd".replace('s', "l").replace('p', l);
+
+ let _ = "hesudo worpd".replace('d', "l").replace("su", "l").replace('p', "l");
+
+ // Note: Future iterations of `collapsible_str_replace` might lint this and combine to `[s, u, p]`
+ let _ = "hesuo worpd".replace([s, u], "l").replace([u, p], "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u'], "l").replace(['u', 'p'], "l");
+
+ let _ = "hesuo worpd".replace('s', "l").replace(['u', 'p'], "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l").replace('r', "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u', 'p'], l).replace('r', l);
+
+ let _ = "hesuo worpd".replace(['s', u, 'p'], "l").replace('r', "l");
+
+ let _ = "hesuo worpd".replace([s, u], "l").replace(p, "l");
+
+ // Regression test
+ let _ = "hesuo worpd"
+ .replace('u', iter.next().unwrap())
+ .replace('s', iter.next().unwrap());
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.rs b/src/tools/clippy/tests/ui/collapsible_str_replace.rs
new file mode 100644
index 000000000..e3e25c414
--- /dev/null
+++ b/src/tools/clippy/tests/ui/collapsible_str_replace.rs
@@ -0,0 +1,76 @@
+// run-rustfix
+
+#![warn(clippy::collapsible_str_replace)]
+
+fn get_filter() -> char {
+ 'u'
+}
+
+fn main() {
+ let d = 'd';
+ let p = 'p';
+ let s = 's';
+ let u = 'u';
+ let l = "l";
+
+ let mut iter = ["l", "z"].iter();
+
+ // LINT CASES
+ let _ = "hesuo worpd".replace('s', "l").replace('u', "l");
+
+ let _ = "hesuo worpd".replace('s', l).replace('u', l);
+
+ let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l");
+
+ let _ = "hesuo worpd"
+ .replace('s', "l")
+ .replace('u', "l")
+ .replace('p', "l")
+ .replace('d', "l");
+
+ let _ = "hesuo world".replace(s, "l").replace('u', "l");
+
+ let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l");
+
+ let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l");
+
+ let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l");
+
+ let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d");
+
+ let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l");
+
+ // Note: Future iterations could lint `replace(|c| matches!(c, "su" | 'd' | 'p'), "l")`
+ let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l");
+
+ let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l");
+
+ let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l");
+
+ // NO LINT CASES
+ let _ = "hesuo world".replace('s', "l").replace('u', "p");
+
+ let _ = "hesuo worpd".replace('s', "l").replace('p', l);
+
+ let _ = "hesudo worpd".replace('d', "l").replace("su", "l").replace('p', "l");
+
+ // Note: Future iterations of `collapsible_str_replace` might lint this and combine to `[s, u, p]`
+ let _ = "hesuo worpd".replace([s, u], "l").replace([u, p], "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u'], "l").replace(['u', 'p'], "l");
+
+ let _ = "hesuo worpd".replace('s', "l").replace(['u', 'p'], "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l").replace('r', "l");
+
+ let _ = "hesuo worpd".replace(['s', 'u', 'p'], l).replace('r', l);
+
+ let _ = "hesuo worpd".replace(['s', u, 'p'], "l").replace('r', "l");
+
+ let _ = "hesuo worpd".replace([s, u], "l").replace(p, "l");
+
+ // Regression test
+ let _ = "hesuo worpd"
+ .replace('u', iter.next().unwrap())
+ .replace('s', iter.next().unwrap());
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.stderr b/src/tools/clippy/tests/ui/collapsible_str_replace.stderr
new file mode 100644
index 000000000..8e3daf3b8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/collapsible_str_replace.stderr
@@ -0,0 +1,86 @@
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:19:27
+ |
+LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")`
+ |
+ = note: `-D clippy::collapsible-str-replace` implied by `-D warnings`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:21:27
+ |
+LL | let _ = "hesuo worpd".replace('s', l).replace('u', l);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], l)`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:23:27
+ |
+LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u', 'p'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:26:10
+ |
+LL | .replace('s', "l")
+ | __________^
+LL | | .replace('u', "l")
+LL | | .replace('p', "l")
+LL | | .replace('d', "l");
+ | |__________________________^ help: replace with: `replace(['s', 'u', 'p', 'd'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:31:27
+ |
+LL | let _ = "hesuo world".replace(s, "l").replace('u', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:33:27
+ |
+LL | let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u', 'p'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:35:27
+ |
+LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, 'p'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:37:27
+ |
+LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, p], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:39:27
+ |
+LL | let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:41:45
+ |
+LL | let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['u', 'p'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:44:47
+ |
+LL | let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['d', 'p'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:46:28
+ |
+LL | let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([d, 'p'], "l")`
+
+error: used consecutive `str::replace` call
+ --> $DIR/collapsible_str_replace.rs:48:27
+ |
+LL | let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([get_filter(), 's'], "l")`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2760.rs b/src/tools/clippy/tests/ui/crashes/ice-2760.rs
index f1a229f3f..61ef24804 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2760.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2760.rs
@@ -1,6 +1,6 @@
#![allow(
unused_variables,
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::needless_pass_by_value,
dead_code
)]
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3462.rs b/src/tools/clippy/tests/ui/crashes/ice-3462.rs
index 02c49aa0d..b40205288 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3462.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3462.rs
@@ -1,5 +1,5 @@
#![warn(clippy::all)]
-#![allow(clippy::blacklisted_name, clippy::equatable_if_let)]
+#![allow(clippy::disallowed_names, clippy::equatable_if_let)]
#![allow(unused)]
/// Test for https://github.com/rust-lang/rust-clippy/issues/3462
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9405.rs b/src/tools/clippy/tests/ui/crashes/ice-9405.rs
new file mode 100644
index 000000000..e2d274aeb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-9405.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::useless_format)]
+#![allow(clippy::print_literal)]
+
+fn main() {
+ println!(
+ "\
+
+ {}",
+ "multiple skipped lines"
+ );
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9405.stderr b/src/tools/clippy/tests/ui/crashes/ice-9405.stderr
new file mode 100644
index 000000000..9a6e410f2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-9405.stderr
@@ -0,0 +1,11 @@
+warning: multiple lines skipped by escaped newline
+ --> $DIR/ice-9405.rs:6:10
+ |
+LL | "/
+ | __________^
+LL | |
+LL | | {}",
+ | |____________^ skipping everything up to and including this point
+
+warning: 1 warning emitted
+
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9414.rs b/src/tools/clippy/tests/ui/crashes/ice-9414.rs
new file mode 100644
index 000000000..02cf5d5c2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-9414.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::result_large_err)]
+
+trait T {}
+fn f(_: &u32) -> Result<(), *const (dyn '_ + T)> {
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/regressions.rs b/src/tools/clippy/tests/ui/crashes/regressions.rs
index 6f9d98bbf..55a8b4034 100644
--- a/src/tools/clippy/tests/ui/crashes/regressions.rs
+++ b/src/tools/clippy/tests/ui/crashes/regressions.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
pub fn foo(bar: *const u8) {
println!("{:#p}", bar);
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs
index 156c88e2e..a7da8f89a 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.rs
+++ b/src/tools/clippy/tests/ui/def_id_nocore.rs
@@ -1,4 +1,3 @@
-// ignore-windows
// ignore-macos
#![feature(no_core, lang_items, start)]
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr
index 40d355e9a..6210d7c6c 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.stderr
+++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr
@@ -1,5 +1,5 @@
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
- --> $DIR/def_id_nocore.rs:28:19
+ --> $DIR/def_id_nocore.rs:27:19
|
LL | pub fn as_ref(self) -> &'static str {
| ^^^^
diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed
index 264dd4efa..fce66eb17 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.fixed
+++ b/src/tools/clippy/tests/ui/default_trait_access.fixed
@@ -1,8 +1,12 @@
// run-rustfix
+// aux-build: proc_macro_with_span.rs
#![allow(unused_imports, dead_code)]
#![deny(clippy::default_trait_access)]
+extern crate proc_macro_with_span;
+
+use proc_macro_with_span::with_span;
use std::default;
use std::default::Default as D2;
use std::string;
@@ -51,6 +55,8 @@ fn main() {
..Default::default()
};
+ let _s21: String = with_span!(s Default::default());
+
println!(
"[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]",
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20,
diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs
index a0930fab8..3e8e898b7 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.rs
+++ b/src/tools/clippy/tests/ui/default_trait_access.rs
@@ -1,8 +1,12 @@
// run-rustfix
+// aux-build: proc_macro_with_span.rs
#![allow(unused_imports, dead_code)]
#![deny(clippy::default_trait_access)]
+extern crate proc_macro_with_span;
+
+use proc_macro_with_span::with_span;
use std::default;
use std::default::Default as D2;
use std::string;
@@ -51,6 +55,8 @@ fn main() {
..Default::default()
};
+ let _s21: String = with_span!(s Default::default());
+
println!(
"[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]",
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20,
diff --git a/src/tools/clippy/tests/ui/default_trait_access.stderr b/src/tools/clippy/tests/ui/default_trait_access.stderr
index df8a5b94d..3493de37a 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.stderr
+++ b/src/tools/clippy/tests/ui/default_trait_access.stderr
@@ -1,53 +1,53 @@
error: calling `std::string::String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:11:22
+ --> $DIR/default_trait_access.rs:15:22
|
LL | let s1: String = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
|
note: the lint level is defined here
- --> $DIR/default_trait_access.rs:4:9
+ --> $DIR/default_trait_access.rs:5:9
|
LL | #![deny(clippy::default_trait_access)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `std::string::String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:15:22
+ --> $DIR/default_trait_access.rs:19:22
|
LL | let s3: String = D2::default();
| ^^^^^^^^^^^^^ help: try: `std::string::String::default()`
error: calling `std::string::String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:17:22
+ --> $DIR/default_trait_access.rs:21:22
|
LL | let s4: String = std::default::Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
error: calling `std::string::String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:21:22
+ --> $DIR/default_trait_access.rs:25:22
|
LL | let s6: String = default::Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
error: calling `GenericDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:31:46
+ --> $DIR/default_trait_access.rs:35:46
|
LL | let s11: GenericDerivedDefault<String> = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()`
error: calling `TupleDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:37:36
+ --> $DIR/default_trait_access.rs:41:36
|
LL | let s14: TupleDerivedDefault = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()`
error: calling `ArrayDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:39:36
+ --> $DIR/default_trait_access.rs:43:36
|
LL | let s15: ArrayDerivedDefault = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()`
error: calling `TupleStructDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:43:42
+ --> $DIR/default_trait_access.rs:47:42
|
LL | let s17: TupleStructDerivedDefault = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()`
diff --git a/src/tools/clippy/tests/ui/blacklisted_name.rs b/src/tools/clippy/tests/ui/disallowed_names.rs
index 27df732a0..e937c49f3 100644
--- a/src/tools/clippy/tests/ui/blacklisted_name.rs
+++ b/src/tools/clippy/tests/ui/disallowed_names.rs
@@ -6,7 +6,7 @@
unused_mut,
unused_variables
)]
-#![warn(clippy::blacklisted_name)]
+#![warn(clippy::disallowed_names)]
fn test(foo: ()) {}
@@ -46,7 +46,7 @@ fn issue_1647_ref_mut() {
mod tests {
fn issue_7305() {
- // `blacklisted_name` lint should not be triggered inside of the test code.
+ // `disallowed_names` lint should not be triggered inside of the test code.
let foo = 0;
// Check that even in nested functions warning is still not triggered.
diff --git a/src/tools/clippy/tests/ui/disallowed_names.stderr b/src/tools/clippy/tests/ui/disallowed_names.stderr
new file mode 100644
index 000000000..78cb55096
--- /dev/null
+++ b/src/tools/clippy/tests/ui/disallowed_names.stderr
@@ -0,0 +1,88 @@
+error: use of a disallowed/placeholder name `foo`
+ --> $DIR/disallowed_names.rs:11:9
+ |
+LL | fn test(foo: ()) {}
+ | ^^^
+ |
+ = note: `-D clippy::disallowed-names` implied by `-D warnings`
+
+error: use of a disallowed/placeholder name `foo`
+ --> $DIR/disallowed_names.rs:14:9
+ |
+LL | let foo = 42;
+ | ^^^
+
+error: use of a disallowed/placeholder name `baz`
+ --> $DIR/disallowed_names.rs:15:9
+ |
+LL | let baz = 42;
+ | ^^^
+
+error: use of a disallowed/placeholder name `quux`
+ --> $DIR/disallowed_names.rs:16:9
+ |
+LL | let quux = 42;
+ | ^^^^
+
+error: use of a disallowed/placeholder name `foo`
+ --> $DIR/disallowed_names.rs:27:10
+ |
+LL | (foo, Some(baz), quux @ Some(_)) => (),
+ | ^^^
+
+error: use of a disallowed/placeholder name `baz`
+ --> $DIR/disallowed_names.rs:27:20
+ |
+LL | (foo, Some(baz), quux @ Some(_)) => (),
+ | ^^^
+
+error: use of a disallowed/placeholder name `quux`
+ --> $DIR/disallowed_names.rs:27:26
+ |
+LL | (foo, Some(baz), quux @ Some(_)) => (),
+ | ^^^^
+
+error: use of a disallowed/placeholder name `foo`
+ --> $DIR/disallowed_names.rs:32:19
+ |
+LL | fn issue_1647(mut foo: u8) {
+ | ^^^
+
+error: use of a disallowed/placeholder name `baz`
+ --> $DIR/disallowed_names.rs:33:13
+ |
+LL | let mut baz = 0;
+ | ^^^
+
+error: use of a disallowed/placeholder name `quux`
+ --> $DIR/disallowed_names.rs:34:21
+ |
+LL | if let Some(mut quux) = Some(42) {}
+ | ^^^^
+
+error: use of a disallowed/placeholder name `baz`
+ --> $DIR/disallowed_names.rs:38:13
+ |
+LL | let ref baz = 0;
+ | ^^^
+
+error: use of a disallowed/placeholder name `quux`
+ --> $DIR/disallowed_names.rs:39:21
+ |
+LL | if let Some(ref quux) = Some(42) {}
+ | ^^^^
+
+error: use of a disallowed/placeholder name `baz`
+ --> $DIR/disallowed_names.rs:43:17
+ |
+LL | let ref mut baz = 0;
+ | ^^^
+
+error: use of a disallowed/placeholder name `quux`
+ --> $DIR/disallowed_names.rs:44:25
+ |
+LL | if let Some(ref mut quux) = Some(42) {}
+ | ^^^^
+
+error: aborting due to 14 previous errors
+
diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.rs b/src/tools/clippy/tests/ui/diverging_sub_expression.rs
index e27f9fea7..e8f992e6d 100644
--- a/src/tools/clippy/tests/ui/diverging_sub_expression.rs
+++ b/src/tools/clippy/tests/ui/diverging_sub_expression.rs
@@ -1,5 +1,5 @@
#![warn(clippy::diverging_sub_expression)]
-#![allow(clippy::match_same_arms, clippy::logic_bug)]
+#![allow(clippy::match_same_arms, clippy::overly_complex_bool_expr)]
#[allow(clippy::empty_loop)]
fn diverge() -> ! {
loop {}
diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.rs b/src/tools/clippy/tests/ui/empty_loop_no_std.rs
index 235e0fc51..e742b396f 100644
--- a/src/tools/clippy/tests/ui/empty_loop_no_std.rs
+++ b/src/tools/clippy/tests/ui/empty_loop_no_std.rs
@@ -1,6 +1,5 @@
// compile-flags: -Clink-arg=-nostartfiles
// ignore-macos
-// ignore-windows
#![warn(clippy::empty_loop)]
#![feature(lang_items, start, libc)]
diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
index 520248fcb..5ded35a6f 100644
--- a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
+++ b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
@@ -1,5 +1,5 @@
error: empty `loop {}` wastes CPU cycles
- --> $DIR/empty_loop_no_std.rs:14:5
+ --> $DIR/empty_loop_no_std.rs:13:5
|
LL | loop {}
| ^^^^^^^
@@ -8,7 +8,7 @@ LL | loop {}
= help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body
error: empty `loop {}` wastes CPU cycles
- --> $DIR/empty_loop_no_std.rs:26:5
+ --> $DIR/empty_loop_no_std.rs:25:5
|
LL | loop {}
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/expect.rs b/src/tools/clippy/tests/ui/expect.rs
index 1073acf6f..d742595e1 100644
--- a/src/tools/clippy/tests/ui/expect.rs
+++ b/src/tools/clippy/tests/ui/expect.rs
@@ -6,8 +6,9 @@ fn expect_option() {
}
fn expect_result() {
- let res: Result<u8, ()> = Ok(0);
+ let res: Result<u8, u8> = Ok(0);
let _ = res.expect("");
+ let _ = res.expect_err("");
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr
index 9d3fc7df1..904c09046 100644
--- a/src/tools/clippy/tests/ui/expect.stderr
+++ b/src/tools/clippy/tests/ui/expect.stderr
@@ -5,7 +5,7 @@ LL | let _ = opt.expect("");
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::expect-used` implied by `-D warnings`
- = help: if this value is an `None`, it will panic
+ = help: if this value is `None`, it will panic
error: used `expect()` on `a Result` value
--> $DIR/expect.rs:10:13
@@ -15,5 +15,13 @@ LL | let _ = res.expect("");
|
= help: if this value is an `Err`, it will panic
-error: aborting due to 2 previous errors
+error: used `expect_err()` on `a Result` value
+ --> $DIR/expect.rs:11:13
+ |
+LL | let _ = res.expect_err("");
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: if this value is an `Ok`, it will panic
+
+error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
index 28b37f96e..0415e33b3 100644
--- a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
+++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
@@ -98,7 +98,7 @@ mod clippy_ok {
let _ = if true { 42 } else { 42 };
}
- #[expect(clippy::logic_bug)]
+ #[expect(clippy::overly_complex_bool_expr)]
fn burger() {
let a = false;
let b = true;
@@ -127,7 +127,7 @@ mod clippy_warn {
let _ = if true { 33 } else { 42 };
}
- #[expect(clippy::logic_bug)]
+ #[expect(clippy::overly_complex_bool_expr)]
fn burger() {
let a = false;
let b = true;
diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
index db29e85a8..7ce9e855b 100644
--- a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
+++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
@@ -33,8 +33,8 @@ LL | #[expect(clippy::if_same_then_else)]
error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:130:14
|
-LL | #[expect(clippy::logic_bug)]
- | ^^^^^^^^^^^^^^^^^
+LL | #[expect(clippy::overly_complex_bool_expr)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
index a650fdc1f..d1d35e5c0 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
@@ -1,5 +1,6 @@
// run-rustfix
+#![feature(closure_lifetime_binder)]
#![warn(clippy::explicit_auto_deref)]
#![allow(
dead_code,
@@ -67,6 +68,8 @@ fn main() {
let s = String::new();
let _: &str = &s;
+ let _: &str = &{ String::new() };
+ let _: &str = &mut { String::new() };
let _ = &*s; // Don't lint. Inferred type would change.
let _: &_ = &*s; // Don't lint. Inferred type would change.
@@ -215,4 +218,52 @@ fn main() {
let s = &"str";
let _ = || return *s;
let _ = || -> &'static str { return s };
+
+ struct X;
+ struct Y(X);
+ impl core::ops::Deref for Y {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ let _: &X = &*{ Y(X) };
+ let _: &X = &*match 0 {
+ #[rustfmt::skip]
+ 0 => { Y(X) },
+ _ => panic!(),
+ };
+ let _: &X = &*if true { Y(X) } else { panic!() };
+
+ fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U {
+ x
+ }
+
+ let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x };
+ fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any {
+ &**x
+ }
+
+ let x = String::new();
+ let _: *const str = &*x;
+
+ struct S7([u32; 1]);
+ impl core::ops::Deref for S7 {
+ type Target = [u32; 1];
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ let x = S7([0]);
+ let _: &[u32] = &*x;
+
+ let c1 = |_: &Vec<&u32>| {};
+ let x = &&vec![&1u32];
+ c1(x);
+ let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {
+ if b {
+ return x;
+ }
+ x
+ };
}
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
index 8f4f35257..deedafad1 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
@@ -1,5 +1,6 @@
// run-rustfix
+#![feature(closure_lifetime_binder)]
#![warn(clippy::explicit_auto_deref)]
#![allow(
dead_code,
@@ -67,6 +68,8 @@ fn main() {
let s = String::new();
let _: &str = &*s;
+ let _: &str = &*{ String::new() };
+ let _: &str = &mut *{ String::new() };
let _ = &*s; // Don't lint. Inferred type would change.
let _: &_ = &*s; // Don't lint. Inferred type would change.
@@ -215,4 +218,52 @@ fn main() {
let s = &"str";
let _ = || return *s;
let _ = || -> &'static str { return *s };
+
+ struct X;
+ struct Y(X);
+ impl core::ops::Deref for Y {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ let _: &X = &*{ Y(X) };
+ let _: &X = &*match 0 {
+ #[rustfmt::skip]
+ 0 => { Y(X) },
+ _ => panic!(),
+ };
+ let _: &X = &*if true { Y(X) } else { panic!() };
+
+ fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U {
+ &**x
+ }
+
+ let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x };
+ fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any {
+ &**x
+ }
+
+ let x = String::new();
+ let _: *const str = &*x;
+
+ struct S7([u32; 1]);
+ impl core::ops::Deref for S7 {
+ type Target = [u32; 1];
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ let x = S7([0]);
+ let _: &[u32] = &*x;
+
+ let c1 = |_: &Vec<&u32>| {};
+ let x = &&vec![&1u32];
+ c1(*x);
+ let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {
+ if b {
+ return *x;
+ }
+ *x
+ };
}
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
index 92765307e..91863abcc 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
@@ -1,202 +1,238 @@
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:69:20
+ --> $DIR/explicit_auto_deref.rs:70:19
|
LL | let _: &str = &*s;
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
|
= note: `-D clippy::explicit-auto-deref` implied by `-D warnings`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:73:12
+ --> $DIR/explicit_auto_deref.rs:71:19
+ |
+LL | let _: &str = &*{ String::new() };
+ | ^^^^^^^^^^^^^^^^^^^ help: try this: `&{ String::new() }`
+
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:72:19
+ |
+LL | let _: &str = &mut *{ String::new() };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut { String::new() }`
+
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:76:11
|
LL | f_str(&*s);
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:77:14
+ --> $DIR/explicit_auto_deref.rs:80:13
|
LL | f_str_t(&*s, &*s); // Don't lint second param.
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:80:25
+ --> $DIR/explicit_auto_deref.rs:83:24
|
LL | let _: &Box<i32> = &**b;
- | ^^^ help: try this: `b`
+ | ^^^^ help: try this: `&b`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:86:8
+ --> $DIR/explicit_auto_deref.rs:89:7
|
LL | c(&*s);
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:92:9
+ --> $DIR/explicit_auto_deref.rs:95:9
|
LL | &**x
| ^^^^ help: try this: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:96:11
+ --> $DIR/explicit_auto_deref.rs:99:11
|
LL | { &**x }
| ^^^^ help: try this: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:100:9
+ --> $DIR/explicit_auto_deref.rs:103:9
|
LL | &**{ x }
| ^^^^^^^^ help: try this: `{ x }`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:104:9
+ --> $DIR/explicit_auto_deref.rs:107:9
|
LL | &***x
| ^^^^^ help: try this: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:121:13
+ --> $DIR/explicit_auto_deref.rs:124:12
|
LL | f1(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:122:13
+ --> $DIR/explicit_auto_deref.rs:125:12
|
LL | f2(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:123:13
+ --> $DIR/explicit_auto_deref.rs:126:12
|
LL | f3(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:124:28
+ --> $DIR/explicit_auto_deref.rs:127:27
|
LL | f4.callable_str()(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:125:13
+ --> $DIR/explicit_auto_deref.rs:128:12
|
LL | f5(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:126:13
+ --> $DIR/explicit_auto_deref.rs:129:12
|
LL | f6(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:127:28
+ --> $DIR/explicit_auto_deref.rs:130:27
|
LL | f7.callable_str()(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:128:26
+ --> $DIR/explicit_auto_deref.rs:131:25
|
LL | f8.callable_t()(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:129:13
+ --> $DIR/explicit_auto_deref.rs:132:12
|
LL | f9(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:130:14
+ --> $DIR/explicit_auto_deref.rs:133:13
|
LL | f10(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:131:27
+ --> $DIR/explicit_auto_deref.rs:134:26
|
LL | f11.callable_t()(&*x);
- | ^^ help: try this: `x`
+ | ^^^ help: try this: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:135:17
+ --> $DIR/explicit_auto_deref.rs:138:16
|
LL | let _ = S1(&*s);
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:140:22
+ --> $DIR/explicit_auto_deref.rs:143:21
|
LL | let _ = S2 { s: &*s };
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:156:30
+ --> $DIR/explicit_auto_deref.rs:159:30
|
LL | let _ = Self::S1(&**s);
| ^^^^ help: try this: `s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:157:35
+ --> $DIR/explicit_auto_deref.rs:160:35
|
LL | let _ = Self::S2 { s: &**s };
| ^^^^ help: try this: `s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:160:21
+ --> $DIR/explicit_auto_deref.rs:163:20
|
LL | let _ = E1::S1(&*s);
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:161:26
+ --> $DIR/explicit_auto_deref.rs:164:25
|
LL | let _ = E1::S2 { s: &*s };
- | ^^ help: try this: `s`
+ | ^^^ help: try this: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:179:13
+ --> $DIR/explicit_auto_deref.rs:182:13
|
LL | let _ = (*b).foo;
| ^^^^ help: try this: `b`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:180:13
+ --> $DIR/explicit_auto_deref.rs:183:13
|
LL | let _ = (**b).foo;
| ^^^^^ help: try this: `b`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:195:19
+ --> $DIR/explicit_auto_deref.rs:198:19
|
LL | let _ = f_str(*ref_str);
| ^^^^^^^^ help: try this: `ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:197:19
+ --> $DIR/explicit_auto_deref.rs:200:19
|
LL | let _ = f_str(**ref_ref_str);
| ^^^^^^^^^^^^^ help: try this: `ref_ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:207:13
+ --> $DIR/explicit_auto_deref.rs:210:13
|
LL | f_str(&&*ref_str); // `needless_borrow` will suggest removing both references
| ^^^^^^^^ help: try this: `ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:208:12
+ --> $DIR/explicit_auto_deref.rs:211:12
|
LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
| ^^^^^^^^^^ help: try this: `ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:217:41
+ --> $DIR/explicit_auto_deref.rs:220:41
|
LL | let _ = || -> &'static str { return *s };
| ^^ help: try this: `s`
-error: aborting due to 33 previous errors
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:239:9
+ |
+LL | &**x
+ | ^^^^ help: try this: `x`
+
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:262:8
+ |
+LL | c1(*x);
+ | ^^ help: try this: `x`
+
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:265:20
+ |
+LL | return *x;
+ | ^^ help: try this: `x`
+
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:267:9
+ |
+LL | *x
+ | ^^ help: try this: `x`
+
+error: aborting due to 39 previous errors
diff --git a/src/tools/clippy/tests/ui/floating_point_exp.fixed b/src/tools/clippy/tests/ui/floating_point_exp.fixed
index ae7805fdf..c86a502d1 100644
--- a/src/tools/clippy/tests/ui/floating_point_exp.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_exp.fixed
@@ -5,6 +5,7 @@ fn main() {
let x = 2f32;
let _ = x.exp_m1();
let _ = x.exp_m1() + 2.0;
+ let _ = (x as f32).exp_m1() + 2.0;
// Cases where the lint shouldn't be applied
let _ = x.exp() - 2.0;
let _ = x.exp() - 1.0 * 2.0;
diff --git a/src/tools/clippy/tests/ui/floating_point_exp.rs b/src/tools/clippy/tests/ui/floating_point_exp.rs
index 27e0b9bcb..e59589f91 100644
--- a/src/tools/clippy/tests/ui/floating_point_exp.rs
+++ b/src/tools/clippy/tests/ui/floating_point_exp.rs
@@ -5,6 +5,7 @@ fn main() {
let x = 2f32;
let _ = x.exp() - 1.0;
let _ = x.exp() - 1.0 + 2.0;
+ let _ = (x as f32).exp() - 1.0 + 2.0;
// Cases where the lint shouldn't be applied
let _ = x.exp() - 2.0;
let _ = x.exp() - 1.0 * 2.0;
diff --git a/src/tools/clippy/tests/ui/floating_point_exp.stderr b/src/tools/clippy/tests/ui/floating_point_exp.stderr
index 5cd999ad4..f84eede19 100644
--- a/src/tools/clippy/tests/ui/floating_point_exp.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_exp.stderr
@@ -13,16 +13,22 @@ LL | let _ = x.exp() - 1.0 + 2.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:13:13
+ --> $DIR/floating_point_exp.rs:8:13
+ |
+LL | let _ = (x as f32).exp() - 1.0 + 2.0;
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()`
+
+error: (e.pow(x) - 1) can be computed more accurately
+ --> $DIR/floating_point_exp.rs:14:13
|
LL | let _ = x.exp() - 1.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:14:13
+ --> $DIR/floating_point_exp.rs:15:13
|
LL | let _ = x.exp() - 1.0 + 2.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/floating_point_log.fixed b/src/tools/clippy/tests/ui/floating_point_log.fixed
index 5b487bb8f..4def9300b 100644
--- a/src/tools/clippy/tests/ui/floating_point_log.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_log.fixed
@@ -12,6 +12,7 @@ fn check_log_base() {
let _ = x.ln();
let _ = x.log2();
let _ = x.ln();
+ let _ = (x as f32).log2();
let x = 1f64;
let _ = x.log2();
diff --git a/src/tools/clippy/tests/ui/floating_point_log.rs b/src/tools/clippy/tests/ui/floating_point_log.rs
index 01181484e..1e04caa7d 100644
--- a/src/tools/clippy/tests/ui/floating_point_log.rs
+++ b/src/tools/clippy/tests/ui/floating_point_log.rs
@@ -12,6 +12,7 @@ fn check_log_base() {
let _ = x.log(std::f32::consts::E);
let _ = x.log(TWO);
let _ = x.log(E);
+ let _ = (x as f32).log(2f32);
let x = 1f64;
let _ = x.log(2f64);
diff --git a/src/tools/clippy/tests/ui/floating_point_log.stderr b/src/tools/clippy/tests/ui/floating_point_log.stderr
index 96e5a1544..89800a13a 100644
--- a/src/tools/clippy/tests/ui/floating_point_log.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_log.stderr
@@ -31,25 +31,31 @@ LL | let _ = x.log(E);
| ^^^^^^^^ help: consider using: `x.ln()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:17:13
+ --> $DIR/floating_point_log.rs:15:13
+ |
+LL | let _ = (x as f32).log(2f32);
+ | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log2()`
+
+error: logarithm for bases 2, 10 and e can be computed more accurately
+ --> $DIR/floating_point_log.rs:18:13
|
LL | let _ = x.log(2f64);
| ^^^^^^^^^^^ help: consider using: `x.log2()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:18:13
+ --> $DIR/floating_point_log.rs:19:13
|
LL | let _ = x.log(10f64);
| ^^^^^^^^^^^^ help: consider using: `x.log10()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:19:13
+ --> $DIR/floating_point_log.rs:20:13
|
LL | let _ = x.log(std::f64::consts::E);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:24:13
+ --> $DIR/floating_point_log.rs:25:13
|
LL | let _ = (1f32 + 2.).ln();
| ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()`
@@ -57,118 +63,118 @@ LL | let _ = (1f32 + 2.).ln();
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:25:13
+ --> $DIR/floating_point_log.rs:26:13
|
LL | let _ = (1f32 + 2.0).ln();
| ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:26:13
+ --> $DIR/floating_point_log.rs:27:13
|
LL | let _ = (1.0 + x).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:27:13
+ --> $DIR/floating_point_log.rs:28:13
|
LL | let _ = (1.0 + x / 2.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:28:13
+ --> $DIR/floating_point_log.rs:29:13
|
LL | let _ = (1.0 + x.powi(3)).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:29:13
+ --> $DIR/floating_point_log.rs:30:13
|
LL | let _ = (1.0 + x.powi(3) / 2.0).ln();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:30:13
+ --> $DIR/floating_point_log.rs:31:13
|
LL | let _ = (1.0 + (std::f32::consts::E - 1.0)).ln();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(std::f32::consts::E - 1.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:31:13
+ --> $DIR/floating_point_log.rs:32:13
|
LL | let _ = (x + 1.0).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:32:13
+ --> $DIR/floating_point_log.rs:33:13
|
LL | let _ = (x.powi(3) + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:33:13
+ --> $DIR/floating_point_log.rs:34:13
|
LL | let _ = (x + 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:34:13
+ --> $DIR/floating_point_log.rs:35:13
|
LL | let _ = (x / 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:42:13
+ --> $DIR/floating_point_log.rs:43:13
|
LL | let _ = (1f64 + 2.).ln();
| ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:43:13
+ --> $DIR/floating_point_log.rs:44:13
|
LL | let _ = (1f64 + 2.0).ln();
| ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:44:13
+ --> $DIR/floating_point_log.rs:45:13
|
LL | let _ = (1.0 + x).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:45:13
+ --> $DIR/floating_point_log.rs:46:13
|
LL | let _ = (1.0 + x / 2.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:46:13
+ --> $DIR/floating_point_log.rs:47:13
|
LL | let _ = (1.0 + x.powi(3)).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:47:13
+ --> $DIR/floating_point_log.rs:48:13
|
LL | let _ = (x + 1.0).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:48:13
+ --> $DIR/floating_point_log.rs:49:13
|
LL | let _ = (x.powi(3) + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:49:13
+ --> $DIR/floating_point_log.rs:50:13
|
LL | let _ = (x + 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:50:13
+ --> $DIR/floating_point_log.rs:51:13
|
LL | let _ = (x / 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
-error: aborting due to 28 previous errors
+error: aborting due to 29 previous errors
diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.fixed b/src/tools/clippy/tests/ui/floating_point_logbase.fixed
index 13962a272..936462f94 100644
--- a/src/tools/clippy/tests/ui/floating_point_logbase.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_logbase.fixed
@@ -5,6 +5,7 @@ fn main() {
let x = 3f32;
let y = 5f32;
let _ = x.log(y);
+ let _ = (x as f32).log(y);
let _ = x.log(y);
let _ = x.log(y);
let _ = x.log(y);
diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.rs b/src/tools/clippy/tests/ui/floating_point_logbase.rs
index 26bc20d53..0b56fa8fa 100644
--- a/src/tools/clippy/tests/ui/floating_point_logbase.rs
+++ b/src/tools/clippy/tests/ui/floating_point_logbase.rs
@@ -5,6 +5,7 @@ fn main() {
let x = 3f32;
let y = 5f32;
let _ = x.ln() / y.ln();
+ let _ = (x as f32).ln() / y.ln();
let _ = x.log2() / y.log2();
let _ = x.log10() / y.log10();
let _ = x.log(5f32) / y.log(5f32);
diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.stderr b/src/tools/clippy/tests/ui/floating_point_logbase.stderr
index 78354c2f6..384e3554c 100644
--- a/src/tools/clippy/tests/ui/floating_point_logbase.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_logbase.stderr
@@ -9,20 +9,26 @@ LL | let _ = x.ln() / y.ln();
error: log base can be expressed more clearly
--> $DIR/floating_point_logbase.rs:8:13
|
+LL | let _ = (x as f32).ln() / y.ln();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log(y)`
+
+error: log base can be expressed more clearly
+ --> $DIR/floating_point_logbase.rs:9:13
+ |
LL | let _ = x.log2() / y.log2();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:9:13
+ --> $DIR/floating_point_logbase.rs:10:13
|
LL | let _ = x.log10() / y.log10();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:10:13
+ --> $DIR/floating_point_logbase.rs:11:13
|
LL | let _ = x.log(5f32) / y.log(5f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/floating_point_powf.fixed b/src/tools/clippy/tests/ui/floating_point_powf.fixed
index b0641a100..e7ef45634 100644
--- a/src/tools/clippy/tests/ui/floating_point_powf.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_powf.fixed
@@ -11,10 +11,18 @@ fn main() {
let _ = (-3.1f32).exp();
let _ = x.sqrt();
let _ = x.cbrt();
+ let _ = (x as f32).cbrt();
let _ = x.powi(3);
let _ = x.powi(-2);
let _ = x.powi(16_777_215);
let _ = x.powi(-16_777_215);
+ let _ = (x as f32).powi(-16_777_215);
+ let _ = (x as f32).powi(3);
+ let _ = (1.5_f32 + 1.0).cbrt();
+ let _ = 1.5_f64.cbrt();
+ let _ = 1.5_f64.sqrt();
+ let _ = 1.5_f64.powi(3);
+
// Cases where the lint shouldn't be applied
let _ = x.powf(2.1);
let _ = x.powf(-2.1);
diff --git a/src/tools/clippy/tests/ui/floating_point_powf.rs b/src/tools/clippy/tests/ui/floating_point_powf.rs
index a0a2c9739..d749aa2d4 100644
--- a/src/tools/clippy/tests/ui/floating_point_powf.rs
+++ b/src/tools/clippy/tests/ui/floating_point_powf.rs
@@ -11,10 +11,18 @@ fn main() {
let _ = std::f32::consts::E.powf(-3.1);
let _ = x.powf(1.0 / 2.0);
let _ = x.powf(1.0 / 3.0);
+ let _ = (x as f32).powf(1.0 / 3.0);
let _ = x.powf(3.0);
let _ = x.powf(-2.0);
let _ = x.powf(16_777_215.0);
let _ = x.powf(-16_777_215.0);
+ let _ = (x as f32).powf(-16_777_215.0);
+ let _ = (x as f32).powf(3.0);
+ let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0);
+ let _ = 1.5_f64.powf(1.0 / 3.0);
+ let _ = 1.5_f64.powf(1.0 / 2.0);
+ let _ = 1.5_f64.powf(3.0);
+
// Cases where the lint shouldn't be applied
let _ = x.powf(2.1);
let _ = x.powf(-2.1);
diff --git a/src/tools/clippy/tests/ui/floating_point_powf.stderr b/src/tools/clippy/tests/ui/floating_point_powf.stderr
index 2422eb911..e9693de8f 100644
--- a/src/tools/clippy/tests/ui/floating_point_powf.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_powf.stderr
@@ -50,101 +50,143 @@ LL | let _ = x.powf(1.0 / 3.0);
|
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
-error: exponentiation with integer powers can be computed more efficiently
+error: cube-root of a number can be computed more accurately
--> $DIR/floating_point_powf.rs:14:13
|
+LL | let _ = (x as f32).powf(1.0 / 3.0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()`
+
+error: exponentiation with integer powers can be computed more efficiently
+ --> $DIR/floating_point_powf.rs:15:13
+ |
LL | let _ = x.powf(3.0);
| ^^^^^^^^^^^ help: consider using: `x.powi(3)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:15:13
+ --> $DIR/floating_point_powf.rs:16:13
|
LL | let _ = x.powf(-2.0);
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:16:13
+ --> $DIR/floating_point_powf.rs:17:13
|
LL | let _ = x.powf(16_777_215.0);
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:17:13
+ --> $DIR/floating_point_powf.rs:18:13
|
LL | let _ = x.powf(-16_777_215.0);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)`
+error: exponentiation with integer powers can be computed more efficiently
+ --> $DIR/floating_point_powf.rs:19:13
+ |
+LL | let _ = (x as f32).powf(-16_777_215.0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)`
+
+error: exponentiation with integer powers can be computed more efficiently
+ --> $DIR/floating_point_powf.rs:20:13
+ |
+LL | let _ = (x as f32).powf(3.0);
+ | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)`
+
+error: cube-root of a number can be computed more accurately
+ --> $DIR/floating_point_powf.rs:21:13
+ |
+LL | let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()`
+
+error: cube-root of a number can be computed more accurately
+ --> $DIR/floating_point_powf.rs:22:13
+ |
+LL | let _ = 1.5_f64.powf(1.0 / 3.0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()`
+
+error: square-root of a number can be computed more efficiently and accurately
+ --> $DIR/floating_point_powf.rs:23:13
+ |
+LL | let _ = 1.5_f64.powf(1.0 / 2.0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()`
+
+error: exponentiation with integer powers can be computed more efficiently
+ --> $DIR/floating_point_powf.rs:24:13
+ |
+LL | let _ = 1.5_f64.powf(3.0);
+ | ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)`
+
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:25:13
+ --> $DIR/floating_point_powf.rs:33:13
|
LL | let _ = 2f64.powf(x);
| ^^^^^^^^^^^^ help: consider using: `x.exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:26:13
+ --> $DIR/floating_point_powf.rs:34:13
|
LL | let _ = 2f64.powf(3.1);
| ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:27:13
+ --> $DIR/floating_point_powf.rs:35:13
|
LL | let _ = 2f64.powf(-3.1);
| ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:28:13
+ --> $DIR/floating_point_powf.rs:36:13
|
LL | let _ = std::f64::consts::E.powf(x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:29:13
+ --> $DIR/floating_point_powf.rs:37:13
|
LL | let _ = std::f64::consts::E.powf(3.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:30:13
+ --> $DIR/floating_point_powf.rs:38:13
|
LL | let _ = std::f64::consts::E.powf(-3.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()`
error: square-root of a number can be computed more efficiently and accurately
- --> $DIR/floating_point_powf.rs:31:13
+ --> $DIR/floating_point_powf.rs:39:13
|
LL | let _ = x.powf(1.0 / 2.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`
error: cube-root of a number can be computed more accurately
- --> $DIR/floating_point_powf.rs:32:13
+ --> $DIR/floating_point_powf.rs:40:13
|
LL | let _ = x.powf(1.0 / 3.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:33:13
+ --> $DIR/floating_point_powf.rs:41:13
|
LL | let _ = x.powf(3.0);
| ^^^^^^^^^^^ help: consider using: `x.powi(3)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:34:13
+ --> $DIR/floating_point_powf.rs:42:13
|
LL | let _ = x.powf(-2.0);
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:35:13
+ --> $DIR/floating_point_powf.rs:43:13
|
LL | let _ = x.powf(-2_147_483_648.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:36:13
+ --> $DIR/floating_point_powf.rs:44:13
|
LL | let _ = x.powf(2_147_483_647.0);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)`
-error: aborting due to 24 previous errors
+error: aborting due to 31 previous errors
diff --git a/src/tools/clippy/tests/ui/floating_point_powi.fixed b/src/tools/clippy/tests/ui/floating_point_powi.fixed
index 85f7c531e..5758db7c6 100644
--- a/src/tools/clippy/tests/ui/floating_point_powi.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_powi.fixed
@@ -8,6 +8,7 @@ fn main() {
let y = 4f32;
let _ = x.mul_add(x, y);
let _ = y.mul_add(y, x);
+ let _ = (y as f32).mul_add(y as f32, x);
let _ = x.mul_add(x, y).sqrt();
let _ = y.mul_add(y, x).sqrt();
// Cases where the lint shouldn't be applied
diff --git a/src/tools/clippy/tests/ui/floating_point_powi.rs b/src/tools/clippy/tests/ui/floating_point_powi.rs
index ece61d1be..5926bf1b0 100644
--- a/src/tools/clippy/tests/ui/floating_point_powi.rs
+++ b/src/tools/clippy/tests/ui/floating_point_powi.rs
@@ -8,6 +8,7 @@ fn main() {
let y = 4f32;
let _ = x.powi(2) + y;
let _ = x + y.powi(2);
+ let _ = x + (y as f32).powi(2);
let _ = (x.powi(2) + y).sqrt();
let _ = (x + y.powi(2)).sqrt();
// Cases where the lint shouldn't be applied
diff --git a/src/tools/clippy/tests/ui/floating_point_powi.stderr b/src/tools/clippy/tests/ui/floating_point_powi.stderr
index 37d840988..a3c745442 100644
--- a/src/tools/clippy/tests/ui/floating_point_powi.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_powi.stderr
@@ -15,14 +15,20 @@ LL | let _ = x + y.powi(2);
error: multiply and add expressions can be calculated more efficiently and accurately
--> $DIR/floating_point_powi.rs:11:13
|
+LL | let _ = x + (y as f32).powi(2);
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+ --> $DIR/floating_point_powi.rs:12:13
+ |
LL | let _ = (x.powi(2) + y).sqrt();
| ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:12:13
+ --> $DIR/floating_point_powi.rs:13:13
|
LL | let _ = (x + y.powi(2)).sqrt();
| ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.fixed b/src/tools/clippy/tests/ui/floating_point_rad.fixed
index ce91fe176..27674b8a4 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_rad.fixed
@@ -8,6 +8,11 @@ pub const fn const_context() {
let _ = x * 180f32 / std::f32::consts::PI;
}
+pub fn issue9391(degrees: i64) {
+ let _ = (degrees as f64).to_radians();
+ let _ = (degrees as f64).to_degrees();
+}
+
fn main() {
let x = 3f32;
let _ = x.to_degrees();
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.rs b/src/tools/clippy/tests/ui/floating_point_rad.rs
index 8f3234986..f1ea73df3 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.rs
+++ b/src/tools/clippy/tests/ui/floating_point_rad.rs
@@ -8,6 +8,11 @@ pub const fn const_context() {
let _ = x * 180f32 / std::f32::consts::PI;
}
+pub fn issue9391(degrees: i64) {
+ let _ = degrees as f64 * std::f64::consts::PI / 180.0;
+ let _ = degrees as f64 * 180.0 / std::f64::consts::PI;
+}
+
fn main() {
let x = 3f32;
let _ = x * 180f32 / std::f32::consts::PI;
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.stderr b/src/tools/clippy/tests/ui/floating_point_rad.stderr
index f12d3d23f..979442f2c 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_rad.stderr
@@ -1,40 +1,52 @@
+error: conversion to radians can be done more accurately
+ --> $DIR/floating_point_rad.rs:12:13
+ |
+LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()`
+ |
+ = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+
error: conversion to degrees can be done more accurately
--> $DIR/floating_point_rad.rs:13:13
|
+LL | let _ = degrees as f64 * 180.0 / std::f64::consts::PI;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()`
+
+error: conversion to degrees can be done more accurately
+ --> $DIR/floating_point_rad.rs:18:13
+ |
LL | let _ = x * 180f32 / std::f32::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`
- |
- = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
error: conversion to degrees can be done more accurately
- --> $DIR/floating_point_rad.rs:14:13
+ --> $DIR/floating_point_rad.rs:19:13
|
LL | let _ = 90. * 180f64 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()`
error: conversion to degrees can be done more accurately
- --> $DIR/floating_point_rad.rs:15:13
+ --> $DIR/floating_point_rad.rs:20:13
|
LL | let _ = 90.5 * 180f64 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()`
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:16:13
+ --> $DIR/floating_point_rad.rs:21:13
|
LL | let _ = x * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:17:13
+ --> $DIR/floating_point_rad.rs:22:13
|
LL | let _ = 90. * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()`
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:18:13
+ --> $DIR/floating_point_rad.rs:23:13
|
LL | let _ = 90.5 * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()`
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed
index 6b754f3bd..b56d6aec5 100644
--- a/src/tools/clippy/tests/ui/format.fixed
+++ b/src/tools/clippy/tests/ui/format.fixed
@@ -33,7 +33,7 @@ fn main() {
format!("foo {}", "bar");
format!("{} bar", "foo");
- let arg: String = "".to_owned();
+ let arg = String::new();
arg.to_string();
format!("{:?}", arg); // Don't warn about debug.
format!("{:8}", arg);
diff --git a/src/tools/clippy/tests/ui/format.rs b/src/tools/clippy/tests/ui/format.rs
index ca9826b35..4c1a3a840 100644
--- a/src/tools/clippy/tests/ui/format.rs
+++ b/src/tools/clippy/tests/ui/format.rs
@@ -35,7 +35,7 @@ fn main() {
format!("foo {}", "bar");
format!("{} bar", "foo");
- let arg: String = "".to_owned();
+ let arg = String::new();
format!("{}", arg);
format!("{:?}", arg); // Don't warn about debug.
format!("{:8}", arg);
diff --git a/src/tools/clippy/tests/ui/format_args.fixed b/src/tools/clippy/tests/ui/format_args.fixed
index 69b5e1c72..e1c2d4d70 100644
--- a/src/tools/clippy/tests/ui/format_args.fixed
+++ b/src/tools/clippy/tests/ui/format_args.fixed
@@ -1,8 +1,6 @@
// run-rustfix
-#![allow(unreachable_code)]
-#![allow(unused_macros)]
-#![allow(unused_variables)]
+#![allow(unused)]
#![allow(clippy::assertions_on_constants)]
#![allow(clippy::eq_op)]
#![allow(clippy::print_literal)]
@@ -115,3 +113,50 @@ fn main() {
// https://github.com/rust-lang/rust-clippy/issues/7903
println!("{foo}{foo:?}", foo = "foo".to_string());
}
+
+fn issue8643(vendor_id: usize, product_id: usize, name: &str) {
+ println!(
+ "{:<9} {:<10} {}",
+ format!("0x{:x}", vendor_id),
+ format!("0x{:x}", product_id),
+ name
+ );
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/8855
+mod issue_8855 {
+ #![allow(dead_code)]
+
+ struct A {}
+
+ impl std::fmt::Display for A {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "test")
+ }
+ }
+
+ fn main() {
+ let a = A {};
+ let b = A {};
+
+ let x = format!("{} {}", a, b);
+ dbg!(x);
+
+ let x = format!("{:>6} {:>6}", a, b.to_string());
+ dbg!(x);
+ }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/9256
+mod issue_9256 {
+ #![allow(dead_code)]
+
+ fn print_substring(original: &str) {
+ assert!(original.len() > 10);
+ println!("{}", &original[..10]);
+ }
+
+ fn main() {
+ print_substring("Hello, world!");
+ }
+}
diff --git a/src/tools/clippy/tests/ui/format_args.rs b/src/tools/clippy/tests/ui/format_args.rs
index 3a434c5bf..b9a4d66c2 100644
--- a/src/tools/clippy/tests/ui/format_args.rs
+++ b/src/tools/clippy/tests/ui/format_args.rs
@@ -1,8 +1,6 @@
// run-rustfix
-#![allow(unreachable_code)]
-#![allow(unused_macros)]
-#![allow(unused_variables)]
+#![allow(unused)]
#![allow(clippy::assertions_on_constants)]
#![allow(clippy::eq_op)]
#![allow(clippy::print_literal)]
@@ -115,3 +113,50 @@ fn main() {
// https://github.com/rust-lang/rust-clippy/issues/7903
println!("{foo}{foo:?}", foo = "foo".to_string());
}
+
+fn issue8643(vendor_id: usize, product_id: usize, name: &str) {
+ println!(
+ "{:<9} {:<10} {}",
+ format!("0x{:x}", vendor_id),
+ format!("0x{:x}", product_id),
+ name
+ );
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/8855
+mod issue_8855 {
+ #![allow(dead_code)]
+
+ struct A {}
+
+ impl std::fmt::Display for A {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "test")
+ }
+ }
+
+ fn main() {
+ let a = A {};
+ let b = A {};
+
+ let x = format!("{} {}", a, b.to_string());
+ dbg!(x);
+
+ let x = format!("{:>6} {:>6}", a, b.to_string());
+ dbg!(x);
+ }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/9256
+mod issue_9256 {
+ #![allow(dead_code)]
+
+ fn print_substring(original: &str) {
+ assert!(original.len() > 10);
+ println!("{}", original[..10].to_string());
+ }
+
+ fn main() {
+ print_substring("Hello, world!");
+ }
+}
diff --git a/src/tools/clippy/tests/ui/format_args.stderr b/src/tools/clippy/tests/ui/format_args.stderr
index c0cbca507..aa6e3659b 100644
--- a/src/tools/clippy/tests/ui/format_args.stderr
+++ b/src/tools/clippy/tests/ui/format_args.stderr
@@ -1,5 +1,5 @@
error: `to_string` applied to a type that implements `Display` in `format!` args
- --> $DIR/format_args.rs:76:72
+ --> $DIR/format_args.rs:74:72
|
LL | let _ = format!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
@@ -7,124 +7,136 @@ LL | let _ = format!("error: something failed at {}", Location::caller().to_
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
error: `to_string` applied to a type that implements `Display` in `write!` args
- --> $DIR/format_args.rs:80:27
+ --> $DIR/format_args.rs:78:27
|
LL | Location::caller().to_string()
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `writeln!` args
- --> $DIR/format_args.rs:85:27
+ --> $DIR/format_args.rs:83:27
|
LL | Location::caller().to_string()
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `print!` args
- --> $DIR/format_args.rs:87:63
+ --> $DIR/format_args.rs:85:63
|
LL | print!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:88:65
+ --> $DIR/format_args.rs:86:65
|
LL | println!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `eprint!` args
- --> $DIR/format_args.rs:89:64
+ --> $DIR/format_args.rs:87:64
|
LL | eprint!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `eprintln!` args
- --> $DIR/format_args.rs:90:66
+ --> $DIR/format_args.rs:88:66
|
LL | eprintln!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `format_args!` args
- --> $DIR/format_args.rs:91:77
+ --> $DIR/format_args.rs:89:77
|
LL | let _ = format_args!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `assert!` args
- --> $DIR/format_args.rs:92:70
+ --> $DIR/format_args.rs:90:70
|
LL | assert!(true, "error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `assert_eq!` args
- --> $DIR/format_args.rs:93:73
+ --> $DIR/format_args.rs:91:73
|
LL | assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `assert_ne!` args
- --> $DIR/format_args.rs:94:73
+ --> $DIR/format_args.rs:92:73
|
LL | assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `panic!` args
- --> $DIR/format_args.rs:95:63
+ --> $DIR/format_args.rs:93:63
|
LL | panic!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:96:20
+ --> $DIR/format_args.rs:94:20
|
LL | println!("{}", X(1).to_string());
| ^^^^^^^^^^^^^^^^ help: use this: `*X(1)`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:97:20
+ --> $DIR/format_args.rs:95:20
|
LL | println!("{}", Y(&X(1)).to_string());
| ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:98:24
+ --> $DIR/format_args.rs:96:24
|
LL | println!("{}", Z(1).to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:99:20
+ --> $DIR/format_args.rs:97:20
|
LL | println!("{}", x.to_string());
| ^^^^^^^^^^^^^ help: use this: `**x`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:100:20
+ --> $DIR/format_args.rs:98:20
|
LL | println!("{}", x_ref.to_string());
| ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:102:39
+ --> $DIR/format_args.rs:100:39
|
LL | println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:103:52
+ --> $DIR/format_args.rs:101:52
|
LL | println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:104:39
+ --> $DIR/format_args.rs:102:39
|
LL | println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:105:52
+ --> $DIR/format_args.rs:103:52
|
LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
| ^^^^^^^^^^^^ help: remove this
-error: aborting due to 21 previous errors
+error: `to_string` applied to a type that implements `Display` in `format!` args
+ --> $DIR/format_args.rs:142:38
+ |
+LL | let x = format!("{} {}", a, b.to_string());
+ | ^^^^^^^^^^^^ help: remove this
+
+error: `to_string` applied to a type that implements `Display` in `println!` args
+ --> $DIR/format_args.rs:156:24
+ |
+LL | println!("{}", original[..10].to_string());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`
+
+error: aborting due to 23 previous errors
diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed
index 5f9cebe21..fa564e23c 100644
--- a/src/tools/clippy/tests/ui/identity_op.fixed
+++ b/src/tools/clippy/tests/ui/identity_op.fixed
@@ -68,7 +68,7 @@ fn main() {
&x;
x;
- let mut a = A("".into());
+ let mut a = A(String::new());
let b = a << 0; // no error: non-integer
1 * Meter; // no error: non-integer
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index ca799c9cf..3d06d2a73 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -68,7 +68,7 @@ fn main() {
&x >> 0;
x >> &0;
- let mut a = A("".into());
+ let mut a = A(String::new());
let b = a << 0; // no error: non-integer
1 * Meter; // no error: non-integer
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.rs b/src/tools/clippy/tests/ui/if_let_mutex.rs
index 6cbfafbb3..321feb022 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.rs
+++ b/src/tools/clippy/tests/ui/if_let_mutex.rs
@@ -39,4 +39,12 @@ fn if_let_different_mutex() {
};
}
+fn mutex_ref(mutex: &Mutex<i32>) {
+ if let Ok(i) = mutex.lock() {
+ do_stuff(i);
+ } else {
+ let _x = mutex.lock();
+ };
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.stderr
index e9c4d9163..8a4d5dbac 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.stderr
+++ b/src/tools/clippy/tests/ui/if_let_mutex.stderr
@@ -1,10 +1,14 @@
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
--> $DIR/if_let_mutex.rs:10:5
|
-LL | / if let Err(locked) = m.lock() {
+LL | if let Err(locked) = m.lock() {
+ | ^ - this Mutex will remain locked for the entire `if let`-block...
+ | _____|
+ | |
LL | | do_stuff(locked);
LL | | } else {
LL | | let lock = m.lock().unwrap();
+ | | - ... and is tried to lock again here, which will always deadlock.
LL | | do_stuff(lock);
LL | | };
| |_____^
@@ -15,15 +19,35 @@ LL | | };
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
--> $DIR/if_let_mutex.rs:22:5
|
-LL | / if let Some(locked) = m.lock().unwrap().deref() {
+LL | if let Some(locked) = m.lock().unwrap().deref() {
+ | ^ - this Mutex will remain locked for the entire `if let`-block...
+ | _____|
+ | |
LL | | do_stuff(locked);
LL | | } else {
LL | | let lock = m.lock().unwrap();
+ | | - ... and is tried to lock again here, which will always deadlock.
LL | | do_stuff(lock);
LL | | };
| |_____^
|
= help: move the lock call outside of the `if let ...` expression
-error: aborting due to 2 previous errors
+error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
+ --> $DIR/if_let_mutex.rs:43:5
+ |
+LL | if let Ok(i) = mutex.lock() {
+ | ^ ----- this Mutex will remain locked for the entire `if let`-block...
+ | _____|
+ | |
+LL | | do_stuff(i);
+LL | | } else {
+LL | | let _x = mutex.lock();
+ | | ----- ... and is tried to lock again here, which will always deadlock.
+LL | | };
+ | |_____^
+ |
+ = help: move the lock call outside of the `if let ...` expression
+
+error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/if_same_then_else.rs b/src/tools/clippy/tests/ui/if_same_then_else.rs
index 2598c2ab4..07d2002eb 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else.rs
@@ -1,6 +1,6 @@
#![warn(clippy::if_same_then_else)]
#![allow(
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::eq_op,
clippy::never_loop,
clippy::no_effect,
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs
index 0016009a0..58167f444 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs
@@ -1,6 +1,6 @@
#![warn(clippy::if_same_then_else)]
#![allow(
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::collapsible_else_if,
clippy::equatable_if_let,
clippy::collapsible_if,
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
index 8cb22d569..c22ace30d 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
@@ -27,21 +27,21 @@ LL | | };
|
= help: consider using `bool::then` like: `matches!(true, true).then(|| { /* snippet */ matches!(true, false) })`
-error: this could be simplified with `bool::then`
+error: this could be simplified with `bool::then_some`
--> $DIR/if_then_some_else_none.rs:23:28
|
LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: consider using `bool::then` like: `(o < 32).then(|| o)`
+ = help: consider using `bool::then_some` like: `(o < 32).then_some(o)`
-error: this could be simplified with `bool::then`
+error: this could be simplified with `bool::then_some`
--> $DIR/if_then_some_else_none.rs:27:13
|
LL | let _ = if !x { Some(0) } else { None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: consider using `bool::then` like: `(!x).then(|| 0)`
+ = help: consider using `bool::then_some` like: `(!x).then_some(0)`
error: this could be simplified with `bool::then`
--> $DIR/if_then_some_else_none.rs:82:13
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.rs b/src/tools/clippy/tests/ui/ifs_same_cond.rs
index 80e9839ff..9850fc091 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.rs
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.rs
@@ -32,9 +32,9 @@ fn ifs_same_cond() {
};
let mut v = vec![1];
- if v.pop() == None {
+ if v.pop().is_none() {
// ok, functions
- } else if v.pop() == None {
+ } else if v.pop().is_none() {
}
if v.len() == 42 {
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index 45a430edc..7ebf6ee99 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -3,7 +3,7 @@
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
#![warn(clippy::out_of_bounds_indexing)]
-#![allow(const_err, clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(const_err, unconditional_panic, clippy::no_effect, clippy::unnecessary_operation)]
const ARR: [i32; 2] = [1, 2];
const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr.
diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed
new file mode 100644
index 000000000..bd9b07aef
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed
@@ -0,0 +1,63 @@
+// run-rustfix
+#![warn(clippy::iter_on_empty_collections)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ assert_eq!(std::iter::empty().next(), Option::<i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<&i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<&i32>::None);
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = None.clone();
+ let _: [String; 0] = [].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].iter(),
+ };
+
+ let _ = if false { ["test"].iter() } else { [].iter() };
+}
+
+macro_rules! in_macros {
+ () => {
+ assert_eq!([].into_iter().next(), Option::<i32>::None);
+ assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!([].iter().next(), Option::<&i32>::None);
+ assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!(None.iter().next(), Option::<&i32>::None);
+ };
+}
+
+// Don't trigger on a `None` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ None.iter();
+ None.iter_mut();
+ None.into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs
new file mode 100644
index 000000000..e15ba94bd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs
@@ -0,0 +1,63 @@
+// run-rustfix
+#![warn(clippy::iter_on_empty_collections)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ assert_eq!([].into_iter().next(), Option::<i32>::None);
+ assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!([].iter().next(), Option::<&i32>::None);
+ assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!(None.iter().next(), Option::<&i32>::None);
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = None.clone();
+ let _: [String; 0] = [].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].iter(),
+ };
+
+ let _ = if false { ["test"].iter() } else { [].iter() };
+}
+
+macro_rules! in_macros {
+ () => {
+ assert_eq!([].into_iter().next(), Option::<i32>::None);
+ assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!([].iter().next(), Option::<&i32>::None);
+ assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!(None.iter().next(), Option::<&i32>::None);
+ };
+}
+
+// Don't trigger on a `None` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ None.iter();
+ None.iter_mut();
+ None.into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr
new file mode 100644
index 000000000..cbd611769
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr
@@ -0,0 +1,40 @@
+error: `into_iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:6:16
+ |
+LL | assert_eq!([].into_iter().next(), Option::<i32>::None);
+ | ^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+ |
+ = note: `-D clippy::iter-on-empty-collections` implied by `-D warnings`
+
+error: `iter_mut` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:7:16
+ |
+LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ | ^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:8:16
+ |
+LL | assert_eq!([].iter().next(), Option::<&i32>::None);
+ | ^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `into_iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:9:16
+ |
+LL | assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ | ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `iter_mut` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:10:16
+ |
+LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ | ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:11:16
+ |
+LL | assert_eq!(None.iter().next(), Option::<&i32>::None);
+ | ^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.fixed b/src/tools/clippy/tests/ui/iter_on_single_items.fixed
new file mode 100644
index 000000000..1fa4b0364
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.fixed
@@ -0,0 +1,63 @@
+// run-rustfix
+#![warn(clippy::iter_on_single_items)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ assert_eq!(std::iter::once(123).next(), Some(123));
+ assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123));
+ assert_eq!(std::iter::once(&123).next(), Some(&123));
+ assert_eq!(std::iter::once(123).next(), Some(123));
+ assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123));
+ assert_eq!(std::iter::once(&123).next(), Some(&123));
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = Some("test".to_string()).clone();
+ let _: [String; 1] = ["test".to_string()].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].iter(),
+ };
+
+ let _ = if false { ["test"].iter() } else { [].iter() };
+}
+
+macro_rules! in_macros {
+ () => {
+ assert_eq!([123].into_iter().next(), Some(123));
+ assert_eq!([123].iter_mut().next(), Some(&mut 123));
+ assert_eq!([123].iter().next(), Some(&123));
+ assert_eq!(Some(123).into_iter().next(), Some(123));
+ assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
+ assert_eq!(Some(123).iter().next(), Some(&123));
+ };
+}
+
+// Don't trigger on a `Some` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ Some(3).iter();
+ Some(3).iter_mut();
+ Some(3).into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.rs b/src/tools/clippy/tests/ui/iter_on_single_items.rs
new file mode 100644
index 000000000..ea96d8066
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.rs
@@ -0,0 +1,63 @@
+// run-rustfix
+#![warn(clippy::iter_on_single_items)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ assert_eq!([123].into_iter().next(), Some(123));
+ assert_eq!([123].iter_mut().next(), Some(&mut 123));
+ assert_eq!([123].iter().next(), Some(&123));
+ assert_eq!(Some(123).into_iter().next(), Some(123));
+ assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
+ assert_eq!(Some(123).iter().next(), Some(&123));
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = Some("test".to_string()).clone();
+ let _: [String; 1] = ["test".to_string()].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].iter(),
+ };
+
+ let _ = if false { ["test"].iter() } else { [].iter() };
+}
+
+macro_rules! in_macros {
+ () => {
+ assert_eq!([123].into_iter().next(), Some(123));
+ assert_eq!([123].iter_mut().next(), Some(&mut 123));
+ assert_eq!([123].iter().next(), Some(&123));
+ assert_eq!(Some(123).into_iter().next(), Some(123));
+ assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
+ assert_eq!(Some(123).iter().next(), Some(&123));
+ };
+}
+
+// Don't trigger on a `Some` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ Some(3).iter();
+ Some(3).iter_mut();
+ Some(3).into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.stderr b/src/tools/clippy/tests/ui/iter_on_single_items.stderr
new file mode 100644
index 000000000..d6c547116
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.stderr
@@ -0,0 +1,40 @@
+error: `into_iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:6:16
+ |
+LL | assert_eq!([123].into_iter().next(), Some(123));
+ | ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
+ |
+ = note: `-D clippy::iter-on-single-items` implied by `-D warnings`
+
+error: `iter_mut` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:7:16
+ |
+LL | assert_eq!([123].iter_mut().next(), Some(&mut 123));
+ | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
+
+error: `iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:8:16
+ |
+LL | assert_eq!([123].iter().next(), Some(&123));
+ | ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
+
+error: `into_iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:9:16
+ |
+LL | assert_eq!(Some(123).into_iter().next(), Some(123));
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
+
+error: `iter_mut` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:10:16
+ |
+LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
+ | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
+
+error: `iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:11:16
+ |
+LL | assert_eq!(Some(123).iter().next(), Some(&123));
+ | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/iter_skip_next.fixed b/src/tools/clippy/tests/ui/iter_skip_next.fixed
index 2db4c2bee..d56d623b5 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next.fixed
+++ b/src/tools/clippy/tests/ui/iter_skip_next.fixed
@@ -2,7 +2,7 @@
// aux-build:option_helpers.rs
#![warn(clippy::iter_skip_next)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
#![allow(clippy::iter_nth)]
#![allow(unused_mut, dead_code)]
diff --git a/src/tools/clippy/tests/ui/iter_skip_next.rs b/src/tools/clippy/tests/ui/iter_skip_next.rs
index 692edb9ae..3ec5d1b82 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next.rs
+++ b/src/tools/clippy/tests/ui/iter_skip_next.rs
@@ -2,7 +2,7 @@
// aux-build:option_helpers.rs
#![warn(clippy::iter_skip_next)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
#![allow(clippy::iter_nth)]
#![allow(unused_mut, dead_code)]
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.rs b/src/tools/clippy/tests/ui/large_enum_variant.rs
index 23152a133..717009e4c 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.rs
+++ b/src/tools/clippy/tests/ui/large_enum_variant.rs
@@ -130,6 +130,30 @@ impl<T: Copy> Clone for SomeGenericPossiblyCopyEnum<T> {
impl<T: Copy> Copy for SomeGenericPossiblyCopyEnum<T> {}
+enum LargeEnumWithGenerics<T> {
+ Small,
+ Large((T, [u8; 512])),
+}
+
+struct Foo<T> {
+ foo: T,
+}
+
+enum WithGenerics {
+ Large([Foo<u64>; 64]),
+ Small(u8),
+}
+
+enum PossiblyLargeEnumWithConst<const U: usize> {
+ SmallBuffer([u8; 4]),
+ MightyBuffer([u16; U]),
+}
+
+enum LargeEnumOfConst {
+ Ok,
+ Error(PossiblyLargeEnumWithConst<256>),
+}
+
fn main() {
large_enum_variant!();
}
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.stderr b/src/tools/clippy/tests/ui/large_enum_variant.stderr
index 024832726..c6ed97487 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.stderr
+++ b/src/tools/clippy/tests/ui/large_enum_variant.stderr
@@ -1,143 +1,177 @@
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:12:5
+ --> $DIR/large_enum_variant.rs:10:1
|
-LL | B([i32; 8000]),
- | ^^^^^^^^^^^^^^ this variant is 32000 bytes
+LL | / enum LargeEnum {
+LL | | A(i32),
+ | | ------ the second-largest variant contains at least 4 bytes
+LL | | B([i32; 8000]),
+ | | -------------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
-note: and the second-largest variant is 4 bytes:
- --> $DIR/large_enum_variant.rs:11:5
- |
-LL | A(i32),
- | ^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | B(Box<[i32; 8000]>),
| ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:36:5
- |
-LL | ContainingLargeEnum(LargeEnum),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
+ --> $DIR/large_enum_variant.rs:34:1
|
-note: and the second-largest variant is 8 bytes:
- --> $DIR/large_enum_variant.rs:35:5
+LL | / enum LargeEnum2 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | ContainingLargeEnum(LargeEnum),
+ | | ------------------------------ the largest variant contains at least 32004 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
|
-LL | VariantOk(i32, u32),
- | ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | ContainingLargeEnum(Box<LargeEnum>),
| ~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:40:5
- |
-LL | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70004 bytes
+ --> $DIR/large_enum_variant.rs:39:1
|
-note: and the second-largest variant is 8 bytes:
- --> $DIR/large_enum_variant.rs:42:5
+LL | / enum LargeEnum3 {
+LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
+ | | --------------------------------------------------------- the largest variant contains at least 70004 bytes
+LL | | VoidVariant,
+LL | | StructLikeLittle { x: i32, y: i32 },
+ | | ----------------------------------- the second-largest variant contains at least 8 bytes
+LL | | }
+ | |_^ the entire enum is at least 70008 bytes
|
-LL | StructLikeLittle { x: i32, y: i32 },
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:47:5
+ --> $DIR/large_enum_variant.rs:45:1
|
-LL | StructLikeLarge { x: [i32; 8000], y: i32 },
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
+LL | / enum LargeEnum4 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | StructLikeLarge { x: [i32; 8000], y: i32 },
+ | | ------------------------------------------ the largest variant contains at least 32004 bytes
+LL | | }
+ | |_^ the entire enum is at least 32008 bytes
|
-note: and the second-largest variant is 8 bytes:
- --> $DIR/large_enum_variant.rs:46:5
- |
-LL | VariantOk(i32, u32),
- | ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
| ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:52:5
- |
-LL | StructLikeLarge2 { x: [i32; 8000] },
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32000 bytes
+ --> $DIR/large_enum_variant.rs:50:1
|
-note: and the second-largest variant is 8 bytes:
- --> $DIR/large_enum_variant.rs:51:5
+LL | / enum LargeEnum5 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | StructLikeLarge2 { x: [i32; 8000] },
+ | | ----------------------------------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
|
-LL | VariantOk(i32, u32),
- | ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | StructLikeLarge2 { x: Box<[i32; 8000]> },
| ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:68:5
- |
-LL | B([u8; 1255]),
- | ^^^^^^^^^^^^^ this variant is 1255 bytes
+ --> $DIR/large_enum_variant.rs:66:1
|
-note: and the second-largest variant is 200 bytes:
- --> $DIR/large_enum_variant.rs:69:5
+LL | / enum LargeEnum7 {
+LL | | A,
+LL | | B([u8; 1255]),
+ | | ------------- the largest variant contains at least 1255 bytes
+LL | | C([u8; 200]),
+ | | ------------ the second-largest variant contains at least 200 bytes
+LL | | }
+ | |_^ the entire enum is at least 1256 bytes
|
-LL | C([u8; 200]),
- | ^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | B(Box<[u8; 1255]>),
| ~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:74:5
+ --> $DIR/large_enum_variant.rs:72:1
|
-LL | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70128 bytes
+LL | / enum LargeEnum8 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
+ | | ------------------------------------------------------------------------- the largest variant contains at least 70128 bytes
+LL | | }
+ | |_^ the entire enum is at least 70132 bytes
|
-note: and the second-largest variant is 8 bytes:
- --> $DIR/large_enum_variant.rs:73:5
- |
-LL | VariantOk(i32, u32),
- | ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:79:5
+ --> $DIR/large_enum_variant.rs:77:1
+ |
+LL | / enum LargeEnum9 {
+LL | | A(Struct<()>),
+ | | ------------- the second-largest variant contains at least 4 bytes
+LL | | B(Struct2),
+ | | ---------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
|
-LL | B(Struct2),
- | ^^^^^^^^^^ this variant is 32000 bytes
+LL | B(Box<Struct2>),
+ | ~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:82:1
|
-note: and the second-largest variant is 4 bytes:
- --> $DIR/large_enum_variant.rs:78:5
+LL | / enum LargeEnumOk2<T> {
+LL | | A(T),
+ | | ---- the second-largest variant contains at least 0 bytes
+LL | | B(Struct2),
+ | | ---------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32000 bytes
|
-LL | A(Struct<()>),
- | ^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | B(Box<Struct2>),
| ~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:104:5
+ --> $DIR/large_enum_variant.rs:87:1
|
-LL | B([u128; 4000]),
- | ^^^^^^^^^^^^^^^ this variant is 64000 bytes
+LL | / enum LargeEnumOk3<T> {
+LL | | A(Struct<T>),
+ | | ------------ the second-largest variant contains at least 4 bytes
+LL | | B(Struct2),
+ | | ---------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32000 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
|
-note: and the second-largest variant is 1 bytes:
- --> $DIR/large_enum_variant.rs:103:5
+LL | B(Box<Struct2>),
+ | ~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:102:1
+ |
+LL | / enum CopyableLargeEnum {
+LL | | A(bool),
+ | | ------- the second-largest variant contains at least 1 bytes
+LL | | B([u128; 4000]),
+ | | --------------- the largest variant contains at least 64000 bytes
+LL | | }
+ | |_^ the entire enum is at least 64008 bytes
|
-LL | A(bool),
- | ^^^^^^^
note: boxing a variant would require the type no longer be `Copy`
--> $DIR/large_enum_variant.rs:102:6
|
@@ -150,16 +184,16 @@ LL | B([u128; 4000]),
| ^^^^^^^^^^^^^^^
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:109:5
+ --> $DIR/large_enum_variant.rs:107:1
|
-LL | B([u128; 4000]),
- | ^^^^^^^^^^^^^^^ this variant is 64000 bytes
- |
-note: and the second-largest variant is 1 bytes:
- --> $DIR/large_enum_variant.rs:108:5
+LL | / enum ManuallyCopyLargeEnum {
+LL | | A(bool),
+ | | ------- the second-largest variant contains at least 1 bytes
+LL | | B([u128; 4000]),
+ | | --------------- the largest variant contains at least 64000 bytes
+LL | | }
+ | |_^ the entire enum is at least 64008 bytes
|
-LL | A(bool),
- | ^^^^^^^
note: boxing a variant would require the type no longer be `Copy`
--> $DIR/large_enum_variant.rs:107:6
|
@@ -172,16 +206,16 @@ LL | B([u128; 4000]),
| ^^^^^^^^^^^^^^^
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:122:5
+ --> $DIR/large_enum_variant.rs:120:1
|
-LL | B([u64; 4000]),
- | ^^^^^^^^^^^^^^ this variant is 32000 bytes
- |
-note: and the second-largest variant is 1 bytes:
- --> $DIR/large_enum_variant.rs:121:5
+LL | / enum SomeGenericPossiblyCopyEnum<T> {
+LL | | A(bool, std::marker::PhantomData<T>),
+ | | ------------------------------------ the second-largest variant contains at least 1 bytes
+LL | | B([u64; 4000]),
+ | | -------------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32008 bytes
|
-LL | A(bool, std::marker::PhantomData<T>),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: boxing a variant would require the type no longer be `Copy`
--> $DIR/large_enum_variant.rs:120:6
|
@@ -193,5 +227,53 @@ help: consider boxing the large fields to reduce the total size of the enum
LL | B([u64; 4000]),
| ^^^^^^^^^^^^^^
-error: aborting due to 11 previous errors
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:133:1
+ |
+LL | / enum LargeEnumWithGenerics<T> {
+LL | | Small,
+ | | ----- the second-largest variant carries no data at all
+LL | | Large((T, [u8; 512])),
+ | | --------------------- the largest variant contains at least 512 bytes
+LL | | }
+ | |_^ the entire enum is at least 512 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | Large(Box<(T, [u8; 512])>),
+ | ~~~~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:142:1
+ |
+LL | / enum WithGenerics {
+LL | | Large([Foo<u64>; 64]),
+ | | --------------------- the largest variant contains at least 512 bytes
+LL | | Small(u8),
+ | | --------- the second-largest variant contains at least 1 bytes
+LL | | }
+ | |_^ the entire enum is at least 520 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | Large(Box<[Foo<u64>; 64]>),
+ | ~~~~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:152:1
+ |
+LL | / enum LargeEnumOfConst {
+LL | | Ok,
+ | | -- the second-largest variant carries no data at all
+LL | | Error(PossiblyLargeEnumWithConst<256>),
+ | | -------------------------------------- the largest variant contains at least 514 bytes
+LL | | }
+ | |_^ the entire enum is at least 514 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | Error(Box<PossiblyLargeEnumWithConst<256>>),
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/let_if_seq.rs b/src/tools/clippy/tests/ui/let_if_seq.rs
index c5cb2eb1f..959567f68 100644
--- a/src/tools/clippy/tests/ui/let_if_seq.rs
+++ b/src/tools/clippy/tests/ui/let_if_seq.rs
@@ -2,7 +2,7 @@
unused_variables,
unused_assignments,
clippy::similar_names,
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::branches_sharing_code,
clippy::needless_late_init
)]
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
index d0bc640db..65598f1ea 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
@@ -17,7 +17,7 @@ fn main() {
let c = Some(2);
if !a.is_empty()
&& a.len() == 3
- && c != None
+ && c.is_some()
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
index d0bc640db..65598f1ea 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
@@ -17,7 +17,7 @@ fn main() {
let c = Some(2);
if !a.is_empty()
&& a.len() == 3
- && c != None
+ && c.is_some()
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
diff --git a/src/tools/clippy/tests/ui/manual_assert.fixed b/src/tools/clippy/tests/ui/manual_assert.fixed
index 6c2a25c37..a2393674f 100644
--- a/src/tools/clippy/tests/ui/manual_assert.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.fixed
@@ -11,7 +11,7 @@ fn main() {
let c = Some(2);
if !a.is_empty()
&& a.len() == 3
- && c != None
+ && c.is_some()
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs
index 027747d83..4d2706dd6 100644
--- a/src/tools/clippy/tests/ui/manual_assert.rs
+++ b/src/tools/clippy/tests/ui/manual_assert.rs
@@ -17,7 +17,7 @@ fn main() {
let c = Some(2);
if !a.is_empty()
&& a.len() == 3
- && c != None
+ && c.is_some()
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
new file mode 100644
index 000000000..0fa776b7b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
@@ -0,0 +1,27 @@
+// run-rustfix
+#![warn(clippy::manual_instant_elapsed)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(unused_variables)]
+#![allow(unused_must_use)]
+
+use std::time::Instant;
+
+fn main() {
+ let prev_instant = Instant::now();
+
+ {
+ // don't influence
+ let another_instant = Instant::now();
+ }
+
+ let duration = prev_instant.elapsed();
+
+ // don't catch
+ let duration = prev_instant.elapsed();
+
+ Instant::now() - duration;
+
+ let ref_to_instant = &Instant::now();
+
+ (*ref_to_instant).elapsed(); // to ensure parens are added correctly
+}
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
new file mode 100644
index 000000000..5b11b8453
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
@@ -0,0 +1,27 @@
+// run-rustfix
+#![warn(clippy::manual_instant_elapsed)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(unused_variables)]
+#![allow(unused_must_use)]
+
+use std::time::Instant;
+
+fn main() {
+ let prev_instant = Instant::now();
+
+ {
+ // don't influence
+ let another_instant = Instant::now();
+ }
+
+ let duration = Instant::now() - prev_instant;
+
+ // don't catch
+ let duration = prev_instant.elapsed();
+
+ Instant::now() - duration;
+
+ let ref_to_instant = &Instant::now();
+
+ Instant::now() - *ref_to_instant; // to ensure parens are added correctly
+}
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
new file mode 100644
index 000000000..5537f5642
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
@@ -0,0 +1,16 @@
+error: manual implementation of `Instant::elapsed`
+ --> $DIR/manual_instant_elapsed.rs:17:20
+ |
+LL | let duration = Instant::now() - prev_instant;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `prev_instant.elapsed()`
+ |
+ = note: `-D clippy::manual-instant-elapsed` implied by `-D warnings`
+
+error: manual implementation of `Instant::elapsed`
+ --> $DIR/manual_instant_elapsed.rs:26:5
+ |
+LL | Instant::now() - *ref_to_instant; // to ensure parens are added correctly
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.fixed b/src/tools/clippy/tests/ui/manual_ok_or.fixed
index 887a97d7a..d864f8554 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.fixed
+++ b/src/tools/clippy/tests/ui/manual_ok_or.fixed
@@ -1,6 +1,6 @@
// run-rustfix
#![warn(clippy::manual_ok_or)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
#![allow(clippy::redundant_closure)]
#![allow(dead_code)]
#![allow(unused_must_use)]
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.rs b/src/tools/clippy/tests/ui/manual_ok_or.rs
index 3c99872f5..626476846 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.rs
+++ b/src/tools/clippy/tests/ui/manual_ok_or.rs
@@ -1,6 +1,6 @@
// run-rustfix
#![warn(clippy::manual_ok_or)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
#![allow(clippy::redundant_closure)]
#![allow(dead_code)]
#![allow(unused_must_use)]
diff --git a/src/tools/clippy/tests/ui/manual_string_new.fixed b/src/tools/clippy/tests/ui/manual_string_new.fixed
new file mode 100644
index 000000000..a376411bf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_string_new.fixed
@@ -0,0 +1,63 @@
+// run-rustfix
+
+#![warn(clippy::manual_string_new)]
+
+macro_rules! create_strings_from_macro {
+ // When inside a macro, nothing should warn to prevent false positives.
+ ($some_str:expr) => {
+ let _: String = $some_str.into();
+ let _ = $some_str.to_string();
+ };
+}
+
+fn main() {
+ // Method calls
+ let _ = String::new();
+ let _ = "no warning".to_string();
+
+ let _ = String::new();
+ let _ = "no warning".to_owned();
+
+ let _: String = String::new();
+ let _: String = "no warning".into();
+
+ let _: SomeOtherStruct = "no warning".into();
+ let _: SomeOtherStruct = "".into(); // No warning too. We are not converting into String.
+
+ // Calls
+ let _ = String::new();
+ let _ = String::new();
+ let _ = String::from("no warning");
+ let _ = SomeOtherStruct::from("no warning");
+ let _ = SomeOtherStruct::from(""); // Again: no warning.
+
+ let _ = String::new();
+ let _ = String::try_from("no warning").unwrap();
+ let _ = String::try_from("no warning").expect("this should not warn");
+ let _ = SomeOtherStruct::try_from("no warning").unwrap();
+ let _ = SomeOtherStruct::try_from("").unwrap(); // Again: no warning.
+
+ let _: String = String::new();
+ let _: String = From::from("no warning");
+ let _: SomeOtherStruct = From::from("no warning");
+ let _: SomeOtherStruct = From::from(""); // Again: no warning.
+
+ let _: String = String::new();
+ let _: String = TryFrom::try_from("no warning").unwrap();
+ let _: String = TryFrom::try_from("no warning").expect("this should not warn");
+ let _: String = String::new();
+ let _: SomeOtherStruct = TryFrom::try_from("no_warning").unwrap();
+ let _: SomeOtherStruct = TryFrom::try_from("").unwrap(); // Again: no warning.
+
+ // Macros (never warn)
+ create_strings_from_macro!("");
+ create_strings_from_macro!("Hey");
+}
+
+struct SomeOtherStruct {}
+
+impl From<&str> for SomeOtherStruct {
+ fn from(_value: &str) -> Self {
+ Self {}
+ }
+}
diff --git a/src/tools/clippy/tests/ui/manual_string_new.rs b/src/tools/clippy/tests/ui/manual_string_new.rs
new file mode 100644
index 000000000..6bfc52fb1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_string_new.rs
@@ -0,0 +1,63 @@
+// run-rustfix
+
+#![warn(clippy::manual_string_new)]
+
+macro_rules! create_strings_from_macro {
+ // When inside a macro, nothing should warn to prevent false positives.
+ ($some_str:expr) => {
+ let _: String = $some_str.into();
+ let _ = $some_str.to_string();
+ };
+}
+
+fn main() {
+ // Method calls
+ let _ = "".to_string();
+ let _ = "no warning".to_string();
+
+ let _ = "".to_owned();
+ let _ = "no warning".to_owned();
+
+ let _: String = "".into();
+ let _: String = "no warning".into();
+
+ let _: SomeOtherStruct = "no warning".into();
+ let _: SomeOtherStruct = "".into(); // No warning too. We are not converting into String.
+
+ // Calls
+ let _ = String::from("");
+ let _ = <String>::from("");
+ let _ = String::from("no warning");
+ let _ = SomeOtherStruct::from("no warning");
+ let _ = SomeOtherStruct::from(""); // Again: no warning.
+
+ let _ = String::try_from("").unwrap();
+ let _ = String::try_from("no warning").unwrap();
+ let _ = String::try_from("no warning").expect("this should not warn");
+ let _ = SomeOtherStruct::try_from("no warning").unwrap();
+ let _ = SomeOtherStruct::try_from("").unwrap(); // Again: no warning.
+
+ let _: String = From::from("");
+ let _: String = From::from("no warning");
+ let _: SomeOtherStruct = From::from("no warning");
+ let _: SomeOtherStruct = From::from(""); // Again: no warning.
+
+ let _: String = TryFrom::try_from("").unwrap();
+ let _: String = TryFrom::try_from("no warning").unwrap();
+ let _: String = TryFrom::try_from("no warning").expect("this should not warn");
+ let _: String = TryFrom::try_from("").expect("this should warn");
+ let _: SomeOtherStruct = TryFrom::try_from("no_warning").unwrap();
+ let _: SomeOtherStruct = TryFrom::try_from("").unwrap(); // Again: no warning.
+
+ // Macros (never warn)
+ create_strings_from_macro!("");
+ create_strings_from_macro!("Hey");
+}
+
+struct SomeOtherStruct {}
+
+impl From<&str> for SomeOtherStruct {
+ fn from(_value: &str) -> Self {
+ Self {}
+ }
+}
diff --git a/src/tools/clippy/tests/ui/manual_string_new.stderr b/src/tools/clippy/tests/ui/manual_string_new.stderr
new file mode 100644
index 000000000..e5ecfc619
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_string_new.stderr
@@ -0,0 +1,58 @@
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:15:13
+ |
+LL | let _ = "".to_string();
+ | ^^^^^^^^^^^^^^ help: consider using: `String::new()`
+ |
+ = note: `-D clippy::manual-string-new` implied by `-D warnings`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:18:13
+ |
+LL | let _ = "".to_owned();
+ | ^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:21:21
+ |
+LL | let _: String = "".into();
+ | ^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:28:13
+ |
+LL | let _ = String::from("");
+ | ^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:29:13
+ |
+LL | let _ = <String>::from("");
+ | ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:34:13
+ |
+LL | let _ = String::try_from("").unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:40:21
+ |
+LL | let _: String = From::from("");
+ | ^^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:45:21
+ |
+LL | let _: String = TryFrom::try_from("").unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: empty String is being created manually
+ --> $DIR/manual_string_new.rs:48:21
+ |
+LL | let _: String = TryFrom::try_from("").expect("this should warn");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
+
+error: aborting due to 9 previous errors
+
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
index 1ccbfda64..95ca571d0 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
@@ -167,4 +167,29 @@ fn main() {
_ => false,
};
}
+
+ let x = ' ';
+ // ignore if match block contains comment
+ let _line_comments = match x {
+ // numbers are bad!
+ '1' | '2' | '3' => true,
+ // spaces are very important to be true.
+ ' ' => true,
+ // as are dots
+ '.' => true,
+ _ => false,
+ };
+
+ let _block_comments = match x {
+ /* numbers are bad!
+ */
+ '1' | '2' | '3' => true,
+ /* spaces are very important to be true.
+ */
+ ' ' => true,
+ /* as are dots
+ */
+ '.' => true,
+ _ => false,
+ };
}
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
index a49991f59..3b9c8cada 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
@@ -208,4 +208,29 @@ fn main() {
_ => false,
};
}
+
+ let x = ' ';
+ // ignore if match block contains comment
+ let _line_comments = match x {
+ // numbers are bad!
+ '1' | '2' | '3' => true,
+ // spaces are very important to be true.
+ ' ' => true,
+ // as are dots
+ '.' => true,
+ _ => false,
+ };
+
+ let _block_comments = match x {
+ /* numbers are bad!
+ */
+ '1' | '2' | '3' => true,
+ /* spaces are very important to be true.
+ */
+ ' ' => true,
+ /* as are dots
+ */
+ '.' => true,
+ _ => false,
+ };
}
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.rs b/src/tools/clippy/tests/ui/match_same_arms2.rs
index 7aba5b447..61793e80c 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.rs
+++ b/src/tools/clippy/tests/ui/match_same_arms2.rs
@@ -1,5 +1,5 @@
#![warn(clippy::match_same_arms)]
-#![allow(clippy::blacklisted_name, clippy::diverging_sub_expression)]
+#![allow(clippy::disallowed_names, clippy::diverging_sub_expression)]
fn bar<T>(_: T) {}
fn foo() -> bool {
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
index 2a4012039..2d66daea8 100644
--- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
@@ -5,7 +5,7 @@ LL | Err(_) => panic!("err"),
| ^^^^^^
|
= note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_)` matches all errors
--> $DIR/match_wild_err_arm.rs:20:9
@@ -13,7 +13,7 @@ error: `Err(_)` matches all errors
LL | Err(_) => panic!(),
| ^^^^^^
|
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_)` matches all errors
--> $DIR/match_wild_err_arm.rs:26:9
@@ -21,7 +21,7 @@ error: `Err(_)` matches all errors
LL | Err(_) => {
| ^^^^^^
|
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_e)` matches all errors
--> $DIR/match_wild_err_arm.rs:34:9
@@ -29,7 +29,7 @@ error: `Err(_e)` matches all errors
LL | Err(_e) => panic!(),
| ^^^^^^^
|
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
index 2a4012039..2d66daea8 100644
--- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
@@ -5,7 +5,7 @@ LL | Err(_) => panic!("err"),
| ^^^^^^
|
= note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_)` matches all errors
--> $DIR/match_wild_err_arm.rs:20:9
@@ -13,7 +13,7 @@ error: `Err(_)` matches all errors
LL | Err(_) => panic!(),
| ^^^^^^
|
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_)` matches all errors
--> $DIR/match_wild_err_arm.rs:26:9
@@ -21,7 +21,7 @@ error: `Err(_)` matches all errors
LL | Err(_) => {
| ^^^^^^
|
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_e)` matches all errors
--> $DIR/match_wild_err_arm.rs:34:9
@@ -29,7 +29,7 @@ error: `Err(_e)` matches all errors
LL | Err(_e) => panic!(),
| ^^^^^^^
|
- = note: match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable
+ = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/methods.rs b/src/tools/clippy/tests/ui/methods.rs
index 1970c2eae..6f22366ea 100644
--- a/src/tools/clippy/tests/ui/methods.rs
+++ b/src/tools/clippy/tests/ui/methods.rs
@@ -2,7 +2,7 @@
#![warn(clippy::all, clippy::pedantic)]
#![allow(
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::default_trait_access,
clippy::missing_docs_in_private_items,
clippy::missing_safety_doc,
diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
index 8c0da84d8..40c1fcae1 100644
--- a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
+++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
@@ -1,5 +1,5 @@
#![warn(clippy::mismatching_type_param_order)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
fn main() {
struct Foo<A, B> {
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
index aa60d0504..b950248ef 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
@@ -3,12 +3,16 @@
//! The .stderr output of this test should be empty. Otherwise it's a bug somewhere.
// aux-build:helper.rs
+// aux-build:../../auxiliary/proc_macro_with_span.rs
#![warn(clippy::missing_const_for_fn)]
#![feature(start)]
#![feature(custom_inner_attributes)]
extern crate helper;
+extern crate proc_macro_with_span;
+
+use proc_macro_with_span::with_span;
struct Game;
@@ -119,3 +123,8 @@ mod const_fn_stabilized_after_msrv {
byte.is_ascii_digit();
}
}
+
+with_span! {
+ span
+ fn dont_check_in_proc_macro() {}
+}
diff --git a/src/tools/clippy/tests/ui/missing-doc.rs b/src/tools/clippy/tests/ui/missing_doc.rs
index 6e2e710e2..29cc026a8 100644
--- a/src/tools/clippy/tests/ui/missing-doc.rs
+++ b/src/tools/clippy/tests/ui/missing_doc.rs
@@ -1,3 +1,5 @@
+// aux-build: proc_macro_with_span.rs
+
#![warn(clippy::missing_docs_in_private_items)]
// When denying at the crate level, be sure to not get random warnings from the
// injected intrinsics by the compiler.
@@ -5,6 +7,9 @@
//! Some garbage docs for the crate here
#![doc = "More garbage"]
+extern crate proc_macro_with_span;
+
+use proc_macro_with_span::with_span;
use std::arch::global_asm;
type Typedef = String;
@@ -100,3 +105,11 @@ fn main() {}
// Ensure global asm doesn't require documentation.
global_asm! { "" }
+
+// Don't lint proc macro output with an unexpected span.
+with_span!(span pub struct FooPm { pub field: u32});
+with_span!(span pub struct FooPm2;);
+with_span!(span pub enum FooPm3 { A, B(u32), C { field: u32 }});
+with_span!(span pub fn foo_pm() {});
+with_span!(span pub static FOO_PM: u32 = 0;);
+with_span!(span pub const FOO2_PM: u32 = 0;);
diff --git a/src/tools/clippy/tests/ui/missing-doc.stderr b/src/tools/clippy/tests/ui/missing_doc.stderr
index a876dc078..6c8e66f46 100644
--- a/src/tools/clippy/tests/ui/missing-doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc.stderr
@@ -1,5 +1,5 @@
error: missing documentation for a type alias
- --> $DIR/missing-doc.rs:10:1
+ --> $DIR/missing_doc.rs:15:1
|
LL | type Typedef = String;
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,37 +7,37 @@ LL | type Typedef = String;
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
error: missing documentation for a type alias
- --> $DIR/missing-doc.rs:11:1
+ --> $DIR/missing_doc.rs:16:1
|
LL | pub type PubTypedef = String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a module
- --> $DIR/missing-doc.rs:13:1
+ --> $DIR/missing_doc.rs:18:1
|
LL | mod module_no_dox {}
| ^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a module
- --> $DIR/missing-doc.rs:14:1
+ --> $DIR/missing_doc.rs:19:1
|
LL | pub mod pub_module_no_dox {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:18:1
+ --> $DIR/missing_doc.rs:23:1
|
LL | pub fn foo2() {}
| ^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:19:1
+ --> $DIR/missing_doc.rs:24:1
|
LL | fn foo3() {}
| ^^^^^^^^^^^^
error: missing documentation for an enum
- --> $DIR/missing-doc.rs:33:1
+ --> $DIR/missing_doc.rs:38:1
|
LL | / enum Baz {
LL | | BazA { a: isize, b: isize },
@@ -46,31 +46,31 @@ LL | | }
| |_^
error: missing documentation for a variant
- --> $DIR/missing-doc.rs:34:5
+ --> $DIR/missing_doc.rs:39:5
|
LL | BazA { a: isize, b: isize },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/missing-doc.rs:34:12
+ --> $DIR/missing_doc.rs:39:12
|
LL | BazA { a: isize, b: isize },
| ^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/missing-doc.rs:34:22
+ --> $DIR/missing_doc.rs:39:22
|
LL | BazA { a: isize, b: isize },
| ^^^^^^^^
error: missing documentation for a variant
- --> $DIR/missing-doc.rs:35:5
+ --> $DIR/missing_doc.rs:40:5
|
LL | BarB,
| ^^^^
error: missing documentation for an enum
- --> $DIR/missing-doc.rs:38:1
+ --> $DIR/missing_doc.rs:43:1
|
LL | / pub enum PubBaz {
LL | | PubBazA { a: isize },
@@ -78,43 +78,43 @@ LL | | }
| |_^
error: missing documentation for a variant
- --> $DIR/missing-doc.rs:39:5
+ --> $DIR/missing_doc.rs:44:5
|
LL | PubBazA { a: isize },
| ^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/missing-doc.rs:39:15
+ --> $DIR/missing_doc.rs:44:15
|
LL | PubBazA { a: isize },
| ^^^^^^^^
error: missing documentation for a constant
- --> $DIR/missing-doc.rs:59:1
+ --> $DIR/missing_doc.rs:64:1
|
LL | const FOO: u32 = 0;
| ^^^^^^^^^^^^^^^^^^^
error: missing documentation for a constant
- --> $DIR/missing-doc.rs:66:1
+ --> $DIR/missing_doc.rs:71:1
|
LL | pub const FOO4: u32 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a static
- --> $DIR/missing-doc.rs:68:1
+ --> $DIR/missing_doc.rs:73:1
|
LL | static BAR: u32 = 0;
| ^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a static
- --> $DIR/missing-doc.rs:75:1
+ --> $DIR/missing_doc.rs:80:1
|
LL | pub static BAR4: u32 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a module
- --> $DIR/missing-doc.rs:77:1
+ --> $DIR/missing_doc.rs:82:1
|
LL | / mod internal_impl {
LL | | /// dox
@@ -126,31 +126,31 @@ LL | | }
| |_^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:80:5
+ --> $DIR/missing_doc.rs:85:5
|
LL | pub fn undocumented1() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:81:5
+ --> $DIR/missing_doc.rs:86:5
|
LL | pub fn undocumented2() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:82:5
+ --> $DIR/missing_doc.rs:87:5
|
LL | fn undocumented3() {}
| ^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:87:9
+ --> $DIR/missing_doc.rs:92:9
|
LL | pub fn also_undocumented1() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/missing-doc.rs:88:9
+ --> $DIR/missing_doc.rs:93:9
|
LL | fn also_undocumented2() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing-doc-crate.rs b/src/tools/clippy/tests/ui/missing_doc_crate.rs
index e00c7fbfe..e00c7fbfe 100644
--- a/src/tools/clippy/tests/ui/missing-doc-crate.rs
+++ b/src/tools/clippy/tests/ui/missing_doc_crate.rs
diff --git a/src/tools/clippy/tests/ui/missing-doc-crate-missing.rs b/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs
index 51fd57df8..51fd57df8 100644
--- a/src/tools/clippy/tests/ui/missing-doc-crate-missing.rs
+++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs
diff --git a/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
index d56c5cc4c..19516bf5f 100644
--- a/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
@@ -1,5 +1,5 @@
error: missing documentation for the crate
- --> $DIR/missing-doc-crate-missing.rs:1:1
+ --> $DIR/missing_doc_crate_missing.rs:1:1
|
LL | / #![warn(clippy::missing_docs_in_private_items)]
LL | |
diff --git a/src/tools/clippy/tests/ui/missing-doc-impl.rs b/src/tools/clippy/tests/ui/missing_doc_impl.rs
index d5724bf66..0396d1193 100644
--- a/src/tools/clippy/tests/ui/missing-doc-impl.rs
+++ b/src/tools/clippy/tests/ui/missing_doc_impl.rs
@@ -1,3 +1,5 @@
+// aux-build: proc_macro_with_span.rs
+
#![warn(clippy::missing_docs_in_private_items)]
#![allow(dead_code)]
#![feature(associated_type_defaults)]
@@ -5,6 +7,9 @@
//! Some garbage docs for the crate here
#![doc = "More garbage"]
+extern crate proc_macro_with_span;
+use proc_macro_with_span::with_span;
+
struct Foo {
a: isize,
b: isize,
@@ -90,3 +95,13 @@ impl F for Foo {
}
fn main() {}
+
+// don't lint proc macro output
+with_span!(span
+ pub struct FooPm;
+ impl FooPm {
+ pub fn foo() {}
+ pub const fn bar() {}
+ pub const X: u32 = 0;
+ }
+);
diff --git a/src/tools/clippy/tests/ui/missing-doc-impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr
index bda63d66a..f22fa19db 100644
--- a/src/tools/clippy/tests/ui/missing-doc-impl.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr
@@ -1,5 +1,5 @@
error: missing documentation for a struct
- --> $DIR/missing-doc-impl.rs:8:1
+ --> $DIR/missing_doc_impl.rs:13:1
|
LL | / struct Foo {
LL | | a: isize,
@@ -10,19 +10,19 @@ LL | | }
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
error: missing documentation for a struct field
- --> $DIR/missing-doc-impl.rs:9:5
+ --> $DIR/missing_doc_impl.rs:14:5
|
LL | a: isize,
| ^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/missing-doc-impl.rs:10:5
+ --> $DIR/missing_doc_impl.rs:15:5
|
LL | b: isize,
| ^^^^^^^^
error: missing documentation for a struct
- --> $DIR/missing-doc-impl.rs:13:1
+ --> $DIR/missing_doc_impl.rs:18:1
|
LL | / pub struct PubFoo {
LL | | pub a: isize,
@@ -31,19 +31,19 @@ LL | | }
| |_^
error: missing documentation for a struct field
- --> $DIR/missing-doc-impl.rs:14:5
+ --> $DIR/missing_doc_impl.rs:19:5
|
LL | pub a: isize,
| ^^^^^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/missing-doc-impl.rs:15:5
+ --> $DIR/missing_doc_impl.rs:20:5
|
LL | b: isize,
| ^^^^^^^^
error: missing documentation for a trait
- --> $DIR/missing-doc-impl.rs:38:1
+ --> $DIR/missing_doc_impl.rs:43:1
|
LL | / pub trait C {
LL | | fn foo(&self);
@@ -52,31 +52,31 @@ LL | | }
| |_^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:39:5
+ --> $DIR/missing_doc_impl.rs:44:5
|
LL | fn foo(&self);
| ^^^^^^^^^^^^^^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:40:5
+ --> $DIR/missing_doc_impl.rs:45:5
|
LL | fn foo_with_impl(&self) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for an associated type
- --> $DIR/missing-doc-impl.rs:50:5
+ --> $DIR/missing_doc_impl.rs:55:5
|
LL | type AssociatedType;
| ^^^^^^^^^^^^^^^^^^^^
error: missing documentation for an associated type
- --> $DIR/missing-doc-impl.rs:51:5
+ --> $DIR/missing_doc_impl.rs:56:5
|
LL | type AssociatedTypeDef = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:62:5
+ --> $DIR/missing_doc_impl.rs:67:5
|
LL | / pub fn new() -> Self {
LL | | Foo { a: 0, b: 0 }
@@ -84,19 +84,19 @@ LL | | }
| |_____^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:65:5
+ --> $DIR/missing_doc_impl.rs:70:5
|
LL | fn bar() {}
| ^^^^^^^^^^^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:69:5
+ --> $DIR/missing_doc_impl.rs:74:5
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:73:5
+ --> $DIR/missing_doc_impl.rs:78:5
|
LL | / fn foo2() -> u32 {
LL | | 1
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
index a7b36d53c..becb9562a 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
@@ -1,4 +1,5 @@
// run-rustfix
+// aux-build: proc_macro_with_span.rs
#![allow(
dead_code,
@@ -9,6 +10,9 @@
clippy::unusual_byte_groupings
)]
+extern crate proc_macro_with_span;
+use proc_macro_with_span::with_span;
+
fn main() {
let fail14 = 2_i32;
let fail15 = 4_i64;
@@ -40,4 +44,6 @@ fn main() {
let ok38 = 124_64.0;
let _ = 1.123_45E1_f32;
+
+ let _ = with_span!(1 2_u32);
}
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
index c97b31965..ee841bcd7 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
@@ -1,4 +1,5 @@
// run-rustfix
+// aux-build: proc_macro_with_span.rs
#![allow(
dead_code,
@@ -9,6 +10,9 @@
clippy::unusual_byte_groupings
)]
+extern crate proc_macro_with_span;
+use proc_macro_with_span::with_span;
+
fn main() {
let fail14 = 2_32;
let fail15 = 4_64;
@@ -40,4 +44,6 @@ fn main() {
let ok38 = 124_64.0;
let _ = 1.12345E1_32;
+
+ let _ = with_span!(1 2_u32);
}
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
index fb761d9bd..ef8e6a33d 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
@@ -1,5 +1,5 @@
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:13:18
+ --> $DIR/mistyped_literal_suffix.rs:17:18
|
LL | let fail14 = 2_32;
| ^^^^ help: did you mean to write: `2_i32`
@@ -7,91 +7,91 @@ LL | let fail14 = 2_32;
= note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:14:18
+ --> $DIR/mistyped_literal_suffix.rs:18:18
|
LL | let fail15 = 4_64;
| ^^^^ help: did you mean to write: `4_i64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:15:18
+ --> $DIR/mistyped_literal_suffix.rs:19:18
|
LL | let fail16 = 7_8; //
| ^^^ help: did you mean to write: `7_i8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:16:18
+ --> $DIR/mistyped_literal_suffix.rs:20:18
|
LL | let fail17 = 23_16; //
| ^^^^^ help: did you mean to write: `23_i16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:19:18
+ --> $DIR/mistyped_literal_suffix.rs:23:18
|
LL | let fail20 = 2__8; //
| ^^^^ help: did you mean to write: `2_i8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:20:18
+ --> $DIR/mistyped_literal_suffix.rs:24:18
|
LL | let fail21 = 4___16; //
| ^^^^^^ help: did you mean to write: `4_i16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:23:18
+ --> $DIR/mistyped_literal_suffix.rs:27:18
|
LL | let fail25 = 1E2_32;
| ^^^^^^ help: did you mean to write: `1E2_f32`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:24:18
+ --> $DIR/mistyped_literal_suffix.rs:28:18
|
LL | let fail26 = 43E7_64;
| ^^^^^^^ help: did you mean to write: `43E7_f64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:25:18
+ --> $DIR/mistyped_literal_suffix.rs:29:18
|
LL | let fail27 = 243E17_32;
| ^^^^^^^^^ help: did you mean to write: `243E17_f32`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:26:18
+ --> $DIR/mistyped_literal_suffix.rs:30:18
|
LL | let fail28 = 241251235E723_64;
| ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:30:18
+ --> $DIR/mistyped_literal_suffix.rs:34:18
|
LL | let fail30 = 127_8; // should be i8
| ^^^^^ help: did you mean to write: `127_i8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:31:18
+ --> $DIR/mistyped_literal_suffix.rs:35:18
|
LL | let fail31 = 240_8; // should be u8
| ^^^^^ help: did you mean to write: `240_u8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:33:18
+ --> $DIR/mistyped_literal_suffix.rs:37:18
|
LL | let fail33 = 0x1234_16;
| ^^^^^^^^^ help: did you mean to write: `0x1234_i16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:34:18
+ --> $DIR/mistyped_literal_suffix.rs:38:18
|
LL | let fail34 = 0xABCD_16;
| ^^^^^^^^^ help: did you mean to write: `0xABCD_u16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:36:18
+ --> $DIR/mistyped_literal_suffix.rs:40:18
|
LL | let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:42:13
+ --> $DIR/mistyped_literal_suffix.rs:46:13
|
LL | let _ = 1.12345E1_32;
| ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32`
diff --git a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs
index 7640057ab..6efc7657e 100644
--- a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs
@@ -4,7 +4,7 @@
unused_variables,
clippy::no_effect,
dead_code,
- clippy::blacklisted_name
+ clippy::disallowed_names
)]
fn main() {
let mut x = 0;
diff --git a/src/tools/clippy/tests/ui/multi_assignments.rs b/src/tools/clippy/tests/ui/multi_assignments.rs
new file mode 100644
index 000000000..b186bf8bb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/multi_assignments.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::multi_assignments)]
+fn main() {
+ let (mut a, mut b, mut c, mut d) = ((), (), (), ());
+ a = b = c;
+ a = b = c = d;
+ a = b = { c };
+ a = { b = c };
+ a = (b = c);
+}
diff --git a/src/tools/clippy/tests/ui/multi_assignments.stderr b/src/tools/clippy/tests/ui/multi_assignments.stderr
new file mode 100644
index 000000000..d6c42bb69
--- /dev/null
+++ b/src/tools/clippy/tests/ui/multi_assignments.stderr
@@ -0,0 +1,40 @@
+error: assignments don't nest intuitively
+ --> $DIR/multi_assignments.rs:4:5
+ |
+LL | a = b = c;
+ | ^^^^^^^^^
+ |
+ = note: `-D clippy::multi-assignments` implied by `-D warnings`
+
+error: assignments don't nest intuitively
+ --> $DIR/multi_assignments.rs:5:5
+ |
+LL | a = b = c = d;
+ | ^^^^^^^^^^^^^
+
+error: assignments don't nest intuitively
+ --> $DIR/multi_assignments.rs:5:9
+ |
+LL | a = b = c = d;
+ | ^^^^^^^^^
+
+error: assignments don't nest intuitively
+ --> $DIR/multi_assignments.rs:6:5
+ |
+LL | a = b = { c };
+ | ^^^^^^^^^^^^^
+
+error: assignments don't nest intuitively
+ --> $DIR/multi_assignments.rs:7:5
+ |
+LL | a = { b = c };
+ | ^^^^^^^^^^^^^
+
+error: assignments don't nest intuitively
+ --> $DIR/multi_assignments.rs:8:5
+ |
+LL | a = (b = c);
+ | ^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
index 36bc52e33..ecad10a82 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
@@ -18,4 +18,11 @@ fn no_owned_mutex_lock() {
*value += 1;
}
+fn issue9415() {
+ let mut arc_mutex = Arc::new(Mutex::new(42_u8));
+ let arc_mutex: &mut Arc<Mutex<u8>> = &mut arc_mutex;
+ let mut guard = arc_mutex.lock().unwrap();
+ *guard += 1;
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.rs b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
index ea60df5ae..f2b1d6fbf 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.rs
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
@@ -18,4 +18,11 @@ fn no_owned_mutex_lock() {
*value += 1;
}
+fn issue9415() {
+ let mut arc_mutex = Arc::new(Mutex::new(42_u8));
+ let arc_mutex: &mut Arc<Mutex<u8>> = &mut arc_mutex;
+ let mut guard = arc_mutex.lock().unwrap();
+ *guard += 1;
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index bfd2725ec..8cf93bd24 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(lint_reasons)]
+#![feature(custom_inner_attributes, lint_reasons)]
#[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables, clippy::unnecessary_mut_passed)]
@@ -127,6 +127,20 @@ fn main() {
0
}
}
+
+ let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
+ let _ = std::path::Path::new(".").join(".");
+ deref_target_is_x(X);
+ multiple_constraints([[""]]);
+ multiple_constraints_normalizes_to_same(X, X);
+ let _ = Some("").unwrap_or("");
+
+ only_sized(&""); // Don't lint. `Sized` is only bound
+ let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
+ let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+ ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+ refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+ multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
}
#[allow(clippy::needless_borrowed_reference)]
@@ -183,3 +197,104 @@ mod issue9160 {
}
}
}
+
+#[derive(Clone, Copy)]
+struct X;
+
+impl std::ops::Deref for X {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+}
+
+fn deref_target_is_x<T>(_: T)
+where
+ T: std::ops::Deref<Target = X>,
+{
+}
+
+fn multiple_constraints<T, U, V, X, Y>(_: T)
+where
+ T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+ X: IntoIterator<Item = Y>,
+ Y: AsRef<std::ffi::OsStr>,
+{
+}
+
+fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+where
+ T: std::ops::Deref<Target = U>,
+ U: std::ops::Deref<Target = V>,
+{
+}
+
+fn only_sized<T>(_: T) {}
+
+fn ref_as_ref_path<T: 'static>(_: &'static T)
+where
+ &'static T: AsRef<std::path::Path>,
+{
+}
+
+trait RefsOnly {
+ type Referent;
+}
+
+impl<T> RefsOnly for &T {
+ type Referent = T;
+}
+
+fn refs_only<T, U>(_: T)
+where
+ T: RefsOnly<Referent = U>,
+{
+}
+
+fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+where
+ T: IntoIterator<Item = U>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+{
+}
+
+// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+#[allow(dead_code)]
+mod copyable_iterator {
+ #[derive(Clone, Copy)]
+ struct Iter;
+ impl Iterator for Iter {
+ type Item = ();
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+ }
+ fn takes_iter(_: impl Iterator) {}
+ fn dont_warn(mut x: Iter) {
+ takes_iter(&mut x);
+ }
+ fn warn(mut x: &mut Iter) {
+ takes_iter(&mut x)
+ }
+}
+
+mod under_msrv {
+ #![allow(dead_code)]
+ #![clippy::msrv = "1.52.0"]
+
+ fn foo() {
+ let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ }
+}
+
+mod meets_msrv {
+ #![allow(dead_code)]
+ #![clippy::msrv = "1.53.0"]
+
+ fn foo() {
+ let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index c457d8c54..fd9b2a11d 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(lint_reasons)]
+#![feature(custom_inner_attributes, lint_reasons)]
#[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables, clippy::unnecessary_mut_passed)]
@@ -127,6 +127,20 @@ fn main() {
0
}
}
+
+ let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ let _ = std::path::Path::new(".").join(&&".");
+ deref_target_is_x(&X);
+ multiple_constraints(&[[""]]);
+ multiple_constraints_normalizes_to_same(&X, X);
+ let _ = Some("").unwrap_or(&"");
+
+ only_sized(&""); // Don't lint. `Sized` is only bound
+ let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
+ let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+ ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+ refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+ multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
}
#[allow(clippy::needless_borrowed_reference)]
@@ -183,3 +197,104 @@ mod issue9160 {
}
}
}
+
+#[derive(Clone, Copy)]
+struct X;
+
+impl std::ops::Deref for X {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+}
+
+fn deref_target_is_x<T>(_: T)
+where
+ T: std::ops::Deref<Target = X>,
+{
+}
+
+fn multiple_constraints<T, U, V, X, Y>(_: T)
+where
+ T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+ X: IntoIterator<Item = Y>,
+ Y: AsRef<std::ffi::OsStr>,
+{
+}
+
+fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+where
+ T: std::ops::Deref<Target = U>,
+ U: std::ops::Deref<Target = V>,
+{
+}
+
+fn only_sized<T>(_: T) {}
+
+fn ref_as_ref_path<T: 'static>(_: &'static T)
+where
+ &'static T: AsRef<std::path::Path>,
+{
+}
+
+trait RefsOnly {
+ type Referent;
+}
+
+impl<T> RefsOnly for &T {
+ type Referent = T;
+}
+
+fn refs_only<T, U>(_: T)
+where
+ T: RefsOnly<Referent = U>,
+{
+}
+
+fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+where
+ T: IntoIterator<Item = U>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+{
+}
+
+// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+#[allow(dead_code)]
+mod copyable_iterator {
+ #[derive(Clone, Copy)]
+ struct Iter;
+ impl Iterator for Iter {
+ type Item = ();
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+ }
+ fn takes_iter(_: impl Iterator) {}
+ fn dont_warn(mut x: Iter) {
+ takes_iter(&mut x);
+ }
+ fn warn(mut x: &mut Iter) {
+ takes_iter(&mut x)
+ }
+}
+
+mod under_msrv {
+ #![allow(dead_code)]
+ #![clippy::msrv = "1.52.0"]
+
+ fn foo() {
+ let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ }
+}
+
+mod meets_msrv {
+ #![allow(dead_code)]
+ #![clippy::msrv = "1.53.0"]
+
+ fn foo() {
+ let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index 66588689d..5af68706d 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -120,17 +120,59 @@ error: this expression creates a reference which is immediately dereferenced by
LL | (&&5).foo();
| ^^^^^ help: change this to: `(&5)`
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:131:51
+ |
+LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:132:44
+ |
+LL | let _ = std::path::Path::new(".").join(&&".");
+ | ^^^^^ help: change this to: `"."`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:133:23
+ |
+LL | deref_target_is_x(&X);
+ | ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:134:26
+ |
+LL | multiple_constraints(&[[""]]);
+ | ^^^^^^^ help: change this to: `[[""]]`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:135:45
+ |
+LL | multiple_constraints_normalizes_to_same(&X, X);
+ | ^^ help: change this to: `X`
+
+error: this expression creates a reference which is immediately dereferenced by the compiler
+ --> $DIR/needless_borrow.rs:136:32
+ |
+LL | let _ = Some("").unwrap_or(&"");
+ | ^^^ help: change this to: `""`
+
error: this expression borrows a value the compiler would automatically borrow
- --> $DIR/needless_borrow.rs:173:13
+ --> $DIR/needless_borrow.rs:187:13
|
LL | (&self.f)()
| ^^^^^^^^^ help: change this to: `(self.f)`
error: this expression borrows a value the compiler would automatically borrow
- --> $DIR/needless_borrow.rs:182:13
+ --> $DIR/needless_borrow.rs:196:13
|
LL | (&mut self.f)()
| ^^^^^^^^^^^^^ help: change this to: `(self.f)`
-error: aborting due to 22 previous errors
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:298:55
+ |
+LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+
+error: aborting due to 29 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.rs b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
index 1f11d1f8d..12a9ace1e 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
@@ -112,3 +112,192 @@ fn allow_test() {
let v = [1].iter().collect::<Vec<_>>();
v.into_iter().collect::<HashSet<_>>();
}
+
+mod issue_8553 {
+ fn test_for() {
+ let vec = vec![1, 2];
+ let w: Vec<usize> = vec.iter().map(|i| i * i).collect();
+
+ for i in 0..2 {
+ // Do not lint, because this method call is in the loop
+ w.contains(&i);
+ }
+
+ for i in 0..2 {
+ let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ // Do lint
+ y.contains(&i);
+ for j in 0..2 {
+ // Do not lint, because this method call is in the loop
+ z.contains(&j);
+ }
+ }
+
+ // Do not lint, because this variable is used.
+ w.contains(&0);
+ }
+
+ fn test_while() {
+ let vec = vec![1, 2];
+ let x: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let mut n = 0;
+ while n > 1 {
+ // Do not lint, because this method call is in the loop
+ x.contains(&n);
+ n += 1;
+ }
+
+ while n > 2 {
+ let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ // Do lint
+ y.contains(&n);
+ n += 1;
+ while n > 4 {
+ // Do not lint, because this method call is in the loop
+ z.contains(&n);
+ n += 1;
+ }
+ }
+ }
+
+ fn test_loop() {
+ let vec = vec![1, 2];
+ let x: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let mut n = 0;
+ loop {
+ if n < 1 {
+ // Do not lint, because this method call is in the loop
+ x.contains(&n);
+ n += 1;
+ } else {
+ break;
+ }
+ }
+
+ loop {
+ if n < 2 {
+ let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ // Do lint
+ y.contains(&n);
+ n += 1;
+ loop {
+ if n < 4 {
+ // Do not lint, because this method call is in the loop
+ z.contains(&n);
+ n += 1;
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ fn test_while_let() {
+ let vec = vec![1, 2];
+ let x: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let optional = Some(0);
+ let mut n = 0;
+ while let Some(value) = optional {
+ if n < 1 {
+ // Do not lint, because this method call is in the loop
+ x.contains(&n);
+ n += 1;
+ } else {
+ break;
+ }
+ }
+
+ while let Some(value) = optional {
+ let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ if n < 2 {
+ // Do lint
+ y.contains(&n);
+ n += 1;
+ } else {
+ break;
+ }
+
+ while let Some(value) = optional {
+ if n < 4 {
+ // Do not lint, because this method call is in the loop
+ z.contains(&n);
+ n += 1;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ fn test_if_cond() {
+ let vec = vec![1, 2];
+ let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let w = v.iter().collect::<Vec<_>>();
+ // Do lint
+ for _ in 0..w.len() {
+ todo!();
+ }
+ }
+
+ fn test_if_cond_false_case() {
+ let vec = vec![1, 2];
+ let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let w = v.iter().collect::<Vec<_>>();
+ // Do not lint, because w is used.
+ for _ in 0..w.len() {
+ todo!();
+ }
+
+ w.len();
+ }
+
+ fn test_while_cond() {
+ let mut vec = vec![1, 2];
+ let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let mut w = v.iter().collect::<Vec<_>>();
+ // Do lint
+ while 1 == w.len() {
+ todo!();
+ }
+ }
+
+ fn test_while_cond_false_case() {
+ let mut vec = vec![1, 2];
+ let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let mut w = v.iter().collect::<Vec<_>>();
+ // Do not lint, because w is used.
+ while 1 == w.len() {
+ todo!();
+ }
+
+ w.len();
+ }
+
+ fn test_while_let_cond() {
+ let mut vec = vec![1, 2];
+ let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let mut w = v.iter().collect::<Vec<_>>();
+ // Do lint
+ while let Some(i) = Some(w.len()) {
+ todo!();
+ }
+ }
+
+ fn test_while_let_cond_false_case() {
+ let mut vec = vec![1, 2];
+ let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
+ let mut w = v.iter().collect::<Vec<_>>();
+ // Do not lint, because w is used.
+ while let Some(i) = Some(w.len()) {
+ todo!();
+ }
+ w.len();
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
index 0f5e78f91..9f0880cc6 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
@@ -125,5 +125,122 @@ LL ~
LL ~ sample.iter().count()
|
-error: aborting due to 9 previous errors
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:127:59
+ |
+LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ | ^^^^^^^
+...
+LL | y.contains(&i);
+ | -------------- the iterator could be used here instead
+ |
+help: check if the original Iterator contains an element instead of collecting then checking
+ |
+LL ~
+LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+LL | // Do lint
+LL ~ vec.iter().map(|k| k * k).any(|x| x == i);
+ |
+
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:152:59
+ |
+LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ | ^^^^^^^
+...
+LL | y.contains(&n);
+ | -------------- the iterator could be used here instead
+ |
+help: check if the original Iterator contains an element instead of collecting then checking
+ |
+LL ~
+LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+LL | // Do lint
+LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
+ |
+
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:181:63
+ |
+LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ | ^^^^^^^
+...
+LL | y.contains(&n);
+ | -------------- the iterator could be used here instead
+ |
+help: check if the original Iterator contains an element instead of collecting then checking
+ |
+LL ~
+LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+LL | // Do lint
+LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
+ |
+
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:217:59
+ |
+LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ | ^^^^^^^
+...
+LL | y.contains(&n);
+ | -------------- the iterator could be used here instead
+ |
+help: check if the original Iterator contains an element instead of collecting then checking
+ |
+LL ~
+LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
+LL | if n < 2 {
+LL | // Do lint
+LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
+ |
+
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:242:26
+ |
+LL | let w = v.iter().collect::<Vec<_>>();
+ | ^^^^^^^
+LL | // Do lint
+LL | for _ in 0..w.len() {
+ | ------- the iterator could be used here instead
+ |
+help: take the original Iterator's count instead of collecting it and finding the length
+ |
+LL ~
+LL | // Do lint
+LL ~ for _ in 0..v.iter().count() {
+ |
+
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:264:30
+ |
+LL | let mut w = v.iter().collect::<Vec<_>>();
+ | ^^^^^^^
+LL | // Do lint
+LL | while 1 == w.len() {
+ | ------- the iterator could be used here instead
+ |
+help: take the original Iterator's count instead of collecting it and finding the length
+ |
+LL ~
+LL | // Do lint
+LL ~ while 1 == v.iter().count() {
+ |
+
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect_indirect.rs:286:30
+ |
+LL | let mut w = v.iter().collect::<Vec<_>>();
+ | ^^^^^^^
+LL | // Do lint
+LL | while let Some(i) = Some(w.len()) {
+ | ------- the iterator could be used here instead
+ |
+help: take the original Iterator's count instead of collecting it and finding the length
+ |
+LL ~
+LL | // Do lint
+LL ~ while let Some(i) = Some(v.iter().count()) {
+ |
+
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed
index 0c9178fb8..7e4740679 100644
--- a/src/tools/clippy/tests/ui/needless_match.fixed
+++ b/src/tools/clippy/tests/ui/needless_match.fixed
@@ -207,4 +207,43 @@ impl Tr for Result<i32, i32> {
}
}
+mod issue9084 {
+ fn wildcard_if() {
+ let mut some_bool = true;
+ let e = Some(1);
+
+ // should lint
+ let _ = e;
+
+ // should lint
+ let _ = e;
+
+ // should not lint
+ let _ = match e {
+ _ if some_bool => e,
+ _ => Some(2),
+ };
+
+ // should not lint
+ let _ = match e {
+ Some(i) => Some(i + 1),
+ _ if some_bool => e,
+ _ => e,
+ };
+
+ // should not lint (guard has side effects)
+ let _ = match e {
+ Some(i) => Some(i),
+ _ if {
+ some_bool = false;
+ some_bool
+ } =>
+ {
+ e
+ },
+ _ => e,
+ };
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs
index f66f01d7c..809c694bf 100644
--- a/src/tools/clippy/tests/ui/needless_match.rs
+++ b/src/tools/clippy/tests/ui/needless_match.rs
@@ -244,4 +244,50 @@ impl Tr for Result<i32, i32> {
}
}
+mod issue9084 {
+ fn wildcard_if() {
+ let mut some_bool = true;
+ let e = Some(1);
+
+ // should lint
+ let _ = match e {
+ _ if some_bool => e,
+ _ => e,
+ };
+
+ // should lint
+ let _ = match e {
+ Some(i) => Some(i),
+ _ if some_bool => e,
+ _ => e,
+ };
+
+ // should not lint
+ let _ = match e {
+ _ if some_bool => e,
+ _ => Some(2),
+ };
+
+ // should not lint
+ let _ = match e {
+ Some(i) => Some(i + 1),
+ _ if some_bool => e,
+ _ => e,
+ };
+
+ // should not lint (guard has side effects)
+ let _ = match e {
+ Some(i) => Some(i),
+ _ if {
+ some_bool = false;
+ some_bool
+ } =>
+ {
+ e
+ },
+ _ => e,
+ };
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_match.stderr b/src/tools/clippy/tests/ui/needless_match.stderr
index 5bc79800a..28e78441c 100644
--- a/src/tools/clippy/tests/ui/needless_match.stderr
+++ b/src/tools/clippy/tests/ui/needless_match.stderr
@@ -109,5 +109,26 @@ LL | | Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(
LL | | };
| |_________^ help: replace it with: `ce`
-error: aborting due to 11 previous errors
+error: this match expression is unnecessary
+ --> $DIR/needless_match.rs:253:17
+ |
+LL | let _ = match e {
+ | _________________^
+LL | | _ if some_bool => e,
+LL | | _ => e,
+LL | | };
+ | |_________^ help: replace it with: `e`
+
+error: this match expression is unnecessary
+ --> $DIR/needless_match.rs:259:17
+ |
+LL | let _ = match e {
+ | _________________^
+LL | | Some(i) => Some(i),
+LL | | _ if some_bool => e,
+LL | | _ => e,
+LL | | };
+ | |_________^ help: replace it with: `e`
+
+error: aborting due to 13 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index 0bc0d0011..695883e8d 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -1,7 +1,6 @@
// run-rustfix
#![feature(lint_reasons)]
-#![feature(let_else)]
#![allow(unused)]
#![allow(
clippy::if_same_then_else,
@@ -228,13 +227,9 @@ fn needless_return_macro() -> String {
format!("Hello {}", "world!")
}
-fn check_expect() -> bool {
- if true {
- // no error!
- return true;
- }
- #[expect(clippy::needless_return)]
- return true;
+fn issue_9361() -> i32 {
+ #[allow(clippy::integer_arithmetic)]
+ return 1 + 2;
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index eb9f72e8e..63d9fe9ec 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -1,7 +1,6 @@
// run-rustfix
#![feature(lint_reasons)]
-#![feature(let_else)]
#![allow(unused)]
#![allow(
clippy::if_same_then_else,
@@ -228,13 +227,9 @@ fn needless_return_macro() -> String {
return format!("Hello {}", "world!");
}
-fn check_expect() -> bool {
- if true {
- // no error!
- return true;
- }
- #[expect(clippy::needless_return)]
- return true;
+fn issue_9361() -> i32 {
+ #[allow(clippy::integer_arithmetic)]
+ return 1 + 2;
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index 83ff07638..cadee6e00 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -1,5 +1,5 @@
error: unneeded `return` statement
- --> $DIR/needless_return.rs:27:5
+ --> $DIR/needless_return.rs:26:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
@@ -7,217 +7,217 @@ LL | return true;
= note: `-D clippy::needless-return` implied by `-D warnings`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:31:5
+ --> $DIR/needless_return.rs:30:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:36:9
+ --> $DIR/needless_return.rs:35:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:38:9
+ --> $DIR/needless_return.rs:37:9
|
LL | return false;
| ^^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:44:17
+ --> $DIR/needless_return.rs:43:17
|
LL | true => return false,
| ^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:46:13
+ --> $DIR/needless_return.rs:45:13
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:53:9
+ --> $DIR/needless_return.rs:52:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:55:16
+ --> $DIR/needless_return.rs:54:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:59:5
+ --> $DIR/needless_return.rs:58:5
|
LL | return the_answer!();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:63:5
+ --> $DIR/needless_return.rs:62:5
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:68:9
+ --> $DIR/needless_return.rs:67:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:70:9
+ --> $DIR/needless_return.rs:69:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:77:14
+ --> $DIR/needless_return.rs:76:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with a unit value: `()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:86:13
+ --> $DIR/needless_return.rs:85:13
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:88:14
+ --> $DIR/needless_return.rs:87:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with a unit value: `()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:101:9
+ --> $DIR/needless_return.rs:100:9
|
LL | return String::from("test");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:103:9
+ --> $DIR/needless_return.rs:102:9
|
LL | return String::new();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:125:32
+ --> $DIR/needless_return.rs:124:32
|
LL | bar.unwrap_or_else(|_| return)
| ^^^^^^ help: replace `return` with an empty block: `{}`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:130:13
+ --> $DIR/needless_return.rs:129:13
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:132:20
+ --> $DIR/needless_return.rs:131:20
|
LL | let _ = || return;
| ^^^^^^ help: replace `return` with an empty block: `{}`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:138:32
+ --> $DIR/needless_return.rs:137:32
|
LL | res.unwrap_or_else(|_| return Foo)
| ^^^^^^^^^^ help: remove `return`: `Foo`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:147:5
+ --> $DIR/needless_return.rs:146:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:151:5
+ --> $DIR/needless_return.rs:150:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:156:9
+ --> $DIR/needless_return.rs:155:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:158:9
+ --> $DIR/needless_return.rs:157:9
|
LL | return false;
| ^^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:164:17
+ --> $DIR/needless_return.rs:163:17
|
LL | true => return false,
| ^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:166:13
+ --> $DIR/needless_return.rs:165:13
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:173:9
+ --> $DIR/needless_return.rs:172:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:175:16
+ --> $DIR/needless_return.rs:174:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:179:5
+ --> $DIR/needless_return.rs:178:5
|
LL | return the_answer!();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:183:5
+ --> $DIR/needless_return.rs:182:5
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:188:9
+ --> $DIR/needless_return.rs:187:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:190:9
+ --> $DIR/needless_return.rs:189:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:197:14
+ --> $DIR/needless_return.rs:196:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with a unit value: `()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:210:9
+ --> $DIR/needless_return.rs:209:9
|
LL | return String::from("test");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:212:9
+ --> $DIR/needless_return.rs:211:9
|
LL | return String::new();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:228:5
+ --> $DIR/needless_return.rs:227:5
|
LL | return format!("Hello {}", "world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `format!("Hello {}", "world!")`
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.rs b/src/tools/clippy/tests/ui/only_used_in_recursion.rs
index 5768434f9..f71e8ead5 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion.rs
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion.rs
@@ -1,122 +1,113 @@
#![warn(clippy::only_used_in_recursion)]
-fn simple(a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { simple(a - 1, b) }
+fn _simple(x: u32) -> u32 {
+ x
}
-fn with_calc(a: usize, b: isize) -> usize {
- if a == 0 { 1 } else { with_calc(a - 1, -b + 1) }
+fn _simple2(x: u32) -> u32 {
+ _simple(x)
}
-fn tuple((a, b): (usize, usize)) -> usize {
- if a == 0 { 1 } else { tuple((a - 1, b + 1)) }
+fn _one_unused(flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { _one_unused(flag - 1, a) }
}
-fn let_tuple(a: usize, b: usize) -> usize {
- let (c, d) = (a, b);
- if c == 0 { 1 } else { let_tuple(c - 1, d + 1) }
+fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
+ if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
}
-fn array([a, b]: [usize; 2]) -> usize {
- if a == 0 { 1 } else { array([a - 1, b + 1]) }
-}
-
-fn index(a: usize, mut b: &[usize], c: usize) -> usize {
- if a == 0 { 1 } else { index(a - 1, b, c + b[0]) }
-}
-
-fn break_(a: usize, mut b: usize, mut c: usize) -> usize {
- let c = loop {
- b += 1;
- c += 1;
- if c == 10 {
- break b;
- }
- };
-
- if a == 0 { 1 } else { break_(a - 1, c, c) }
+fn _with_calc(flag: u32, a: i64) -> usize {
+ if flag == 0 {
+ 0
+ } else {
+ _with_calc(flag - 1, (-a + 10) * 5)
+ }
}
-// this has a side effect
-fn mut_ref(a: usize, b: &mut usize) -> usize {
- *b = 1;
- if a == 0 { 1 } else { mut_ref(a - 1, b) }
+// Don't lint
+fn _used_with_flag(flag: u32, a: u32) -> usize {
+ if flag == 0 { 0 } else { _used_with_flag(flag ^ a, a - 1) }
}
-fn mut_ref2(a: usize, b: &mut usize) -> usize {
- let mut c = *b;
- if a == 0 { 1 } else { mut_ref2(a - 1, &mut c) }
+fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
+ if flag == 0 {
+ 0
+ } else {
+ _used_with_unused(flag - 1, -a, a + b)
+ }
}
-fn not_primitive(a: usize, b: String) -> usize {
- if a == 0 { 1 } else { not_primitive(a - 1, b) }
+fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
+ if flag == 0 {
+ 0
+ } else {
+ _codependent_unused(flag - 1, a * b, a + b)
+ }
}
-// this doesn't have a side effect,
-// but `String` is not primitive.
-fn not_primitive_op(a: usize, b: String, c: &str) -> usize {
- if a == 1 { 1 } else { not_primitive_op(a, b + c, c) }
+fn _not_primitive(flag: u32, b: String) -> usize {
+ if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }
}
struct A;
impl A {
- fn method(a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { A::method(a - 1, b - 1) }
+ fn _method(flag: usize, a: usize) -> usize {
+ if flag == 0 { 0 } else { Self::_method(flag - 1, a) }
}
- fn method2(&self, a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { self.method2(a - 1, b + 1) }
+ fn _method_self(&self, flag: usize, a: usize) -> usize {
+ if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
}
}
trait B {
- fn hello(a: usize, b: usize) -> usize;
-
- fn hello2(&self, a: usize, b: usize) -> usize;
+ fn method(flag: u32, a: usize) -> usize;
+ fn method_self(&self, flag: u32, a: usize) -> usize;
}
impl B for A {
- fn hello(a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { A::hello(a - 1, b + 1) }
+ fn method(flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { Self::method(flag - 1, a) }
}
- fn hello2(&self, a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { self.hello2(a - 1, b + 1) }
+ fn method_self(&self, flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
}
}
-trait C {
- fn hello(a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { Self::hello(a - 1, b + 1) }
+impl B for () {
+ fn method(flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { a }
}
- fn hello2(&self, a: usize, b: usize) -> usize {
- if a == 0 { 1 } else { self.hello2(a - 1, b + 1) }
+ fn method_self(&self, flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { a }
}
}
-fn ignore(a: usize, _: usize) -> usize {
- if a == 1 { 1 } else { ignore(a - 1, 0) }
-}
+impl B for u32 {
+ fn method(flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { <() as B>::method(flag, a) }
+ }
-fn ignore2(a: usize, _b: usize) -> usize {
- if a == 1 { 1 } else { ignore2(a - 1, _b) }
+ fn method_self(&self, flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { ().method_self(flag, a) }
+ }
}
-fn f1(a: u32) -> u32 {
- a
-}
+trait C {
+ fn method(flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { Self::method(flag - 1, a) }
+ }
-fn f2(a: u32) -> u32 {
- f1(a)
+ fn method_self(&self, flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
+ }
}
-fn inner_fn(a: u32) -> u32 {
- fn inner_fn(a: u32) -> u32 {
- a
- }
- inner_fn(a)
+fn _ignore(flag: usize, _a: usize) -> usize {
+ if flag == 0 { 0 } else { _ignore(flag - 1, _a) }
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
index 6fe9361bf..74057ddcf 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
@@ -1,82 +1,195 @@
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:3:21
+ --> $DIR/only_used_in_recursion.rs:11:27
|
-LL | fn simple(a: usize, b: usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | fn _one_unused(flag: u32, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
|
= note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:12:53
+ |
+LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) }
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion.rs:15:27
+ |
+LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:16:53
+ |
+LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion.rs:15:35
+ |
+LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:16:56
+ |
+LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion.rs:19:26
+ |
+LL | fn _with_calc(flag: u32, a: i64) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:23:32
+ |
+LL | _with_calc(flag - 1, (-a + 10) * 5)
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:7:24
+ --> $DIR/only_used_in_recursion.rs:32:33
+ |
+LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:36:38
|
-LL | fn with_calc(a: usize, b: isize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | _used_with_unused(flag - 1, -a, a + b)
+ | ^ ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:11:14
+ --> $DIR/only_used_in_recursion.rs:32:41
+ |
+LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:36:45
|
-LL | fn tuple((a, b): (usize, usize)) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | _used_with_unused(flag - 1, -a, a + b)
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:15:24
+ --> $DIR/only_used_in_recursion.rs:40:35
|
-LL | fn let_tuple(a: usize, b: usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:44:39
+ |
+LL | _codependent_unused(flag - 1, a * b, a + b)
+ | ^ ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:20:14
+ --> $DIR/only_used_in_recursion.rs:40:43
+ |
+LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
|
-LL | fn array([a, b]: [usize; 2]) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:44:43
+ |
+LL | _codependent_unused(flag - 1, a * b, a + b)
+ | ^ ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:24:20
+ --> $DIR/only_used_in_recursion.rs:48:30
+ |
+LL | fn _not_primitive(flag: u32, b: String) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
|
-LL | fn index(a: usize, mut b: &[usize], c: usize) -> usize {
- | ^^^^^ help: if this is intentional, prefix with an underscore: `_b`
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:49:56
+ |
+LL | if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:24:37
+ --> $DIR/only_used_in_recursion.rs:55:29
+ |
+LL | fn _method(flag: usize, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:56:59
|
-LL | fn index(a: usize, mut b: &[usize], c: usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_c`
+LL | if flag == 0 { 0 } else { Self::_method(flag - 1, a) }
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:28:21
+ --> $DIR/only_used_in_recursion.rs:59:22
+ |
+LL | fn _method_self(&self, flag: usize, a: usize) -> usize {
+ | ^^^^
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:60:35
|
-LL | fn break_(a: usize, mut b: usize, mut c: usize) -> usize {
- | ^^^^^ help: if this is intentional, prefix with an underscore: `_b`
+LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
+ | ^^^^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:46:23
+ --> $DIR/only_used_in_recursion.rs:59:41
|
-LL | fn mut_ref2(a: usize, b: &mut usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | fn _method_self(&self, flag: usize, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:60:63
+ |
+LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:51:28
+ --> $DIR/only_used_in_recursion.rs:70:26
+ |
+LL | fn method(flag: u32, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
|
-LL | fn not_primitive(a: usize, b: String) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:71:58
+ |
+LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) }
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:68:33
+ --> $DIR/only_used_in_recursion.rs:74:38
+ |
+LL | fn method_self(&self, flag: u32, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
|
-LL | fn method2(&self, a: usize, b: usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:75:62
+ |
+LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:90:24
+ --> $DIR/only_used_in_recursion.rs:100:26
+ |
+LL | fn method(flag: u32, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:101:58
|
-LL | fn hello(a: usize, b: usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) }
+ | ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:94:32
+ --> $DIR/only_used_in_recursion.rs:104:38
+ |
+LL | fn method_self(&self, flag: u32, a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion.rs:105:62
|
-LL | fn hello2(&self, a: usize, b: usize) -> usize {
- | ^ help: if this is intentional, prefix with an underscore: `_b`
+LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
+ | ^
-error: aborting due to 13 previous errors
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.rs b/src/tools/clippy/tests/ui/only_used_in_recursion2.rs
new file mode 100644
index 000000000..45dd0553f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.rs
@@ -0,0 +1,91 @@
+#![warn(clippy::only_used_in_recursion)]
+
+fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
+ fn inner(flag: u32, a: u32) -> u32 {
+ if flag == 0 { 0 } else { inner(flag, a) }
+ }
+
+ let x = inner(flag, a);
+ if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }
+}
+
+fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {
+ if let Some(x) = a.and_then(|x| f(x, x)) {
+ _with_closure(Some(x), b, f)
+ } else {
+ 0
+ }
+}
+
+// Issue #8560
+trait D {
+ fn foo(&mut self, arg: u32) -> u32;
+}
+
+mod m {
+ pub struct S(u32);
+ impl S {
+ pub fn foo(&mut self, arg: u32) -> u32 {
+ arg + self.0
+ }
+ }
+}
+
+impl D for m::S {
+ fn foo(&mut self, arg: u32) -> u32 {
+ self.foo(arg)
+ }
+}
+
+// Issue #8782
+fn only_let(x: u32) {
+ let y = 10u32;
+ let _z = x * y;
+}
+
+trait E<T: E<()>> {
+ fn method(flag: u32, a: usize) -> usize {
+ if flag == 0 {
+ 0
+ } else {
+ <T as E<()>>::method(flag - 1, a)
+ }
+ }
+}
+
+impl E<()> for () {
+ fn method(flag: u32, a: usize) -> usize {
+ if flag == 0 { 0 } else { a }
+ }
+}
+
+fn overwritten_param(flag: u32, mut a: usize) -> usize {
+ if flag == 0 {
+ return 0;
+ } else if flag > 5 {
+ a += flag as usize;
+ } else {
+ a = 5;
+ }
+ overwritten_param(flag, a)
+}
+
+fn field_direct(flag: u32, mut a: (usize,)) -> usize {
+ if flag == 0 {
+ 0
+ } else {
+ a.0 += 5;
+ field_direct(flag - 1, a)
+ }
+}
+
+fn field_deref(flag: u32, a: &mut Box<(usize,)>) -> usize {
+ if flag == 0 {
+ 0
+ } else {
+ a.0 += 5;
+ field_deref(flag - 1, a)
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
new file mode 100644
index 000000000..23f6ffd30
--- /dev/null
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
@@ -0,0 +1,63 @@
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion2.rs:3:35
+ |
+LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+ |
+ = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
+note: parameter used here
+ --> $DIR/only_used_in_recursion2.rs:9:52
+ |
+LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion2.rs:4:25
+ |
+LL | fn inner(flag: u32, a: u32) -> u32 {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion2.rs:5:47
+ |
+LL | if flag == 0 { 0 } else { inner(flag, a) }
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion2.rs:12:34
+ |
+LL | fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion2.rs:14:32
+ |
+LL | _with_closure(Some(x), b, f)
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion2.rs:62:37
+ |
+LL | fn overwritten_param(flag: u32, mut a: usize) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion2.rs:70:29
+ |
+LL | overwritten_param(flag, a)
+ | ^
+
+error: parameter is only used in recursion
+ --> $DIR/only_used_in_recursion2.rs:73:32
+ |
+LL | fn field_direct(flag: u32, mut a: (usize,)) -> usize {
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: parameter used here
+ --> $DIR/only_used_in_recursion2.rs:78:32
+ |
+LL | field_direct(flag - 1, a)
+ | ^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/op_ref.rs b/src/tools/clippy/tests/ui/op_ref.rs
index d8bf66603..07226b0a1 100644
--- a/src/tools/clippy/tests/ui/op_ref.rs
+++ b/src/tools/clippy/tests/ui/op_ref.rs
@@ -1,4 +1,4 @@
-#![allow(unused_variables, clippy::blacklisted_name)]
+#![allow(unused_variables, clippy::disallowed_names)]
#![warn(clippy::op_ref)]
use std::collections::HashSet;
use std::ops::{BitAnd, Mul};
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index b6d5e106f..f15ac551b 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -179,4 +179,13 @@ fn main() {
let _ = pattern_to_vec("hello world");
let _ = complex_subpat();
+
+ // issue #8492
+ let _ = s.map_or(1, |string| string.len());
+ let _ = Some(10).map_or(5, |a| a + 1);
+
+ let res: Result<i32, i32> = Ok(5);
+ let _ = res.map_or(1, |a| a + 1);
+ let _ = res.map_or(1, |a| a + 1);
+ let _ = res.map_or(5, |a| a + 1);
}
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index 35bae1593..9eeaea12d 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -208,4 +208,25 @@ fn main() {
let _ = pattern_to_vec("hello world");
let _ = complex_subpat();
+
+ // issue #8492
+ let _ = match s {
+ Some(string) => string.len(),
+ None => 1,
+ };
+ let _ = match Some(10) {
+ Some(a) => a + 1,
+ None => 5,
+ };
+
+ let res: Result<i32, i32> = Ok(5);
+ let _ = match res {
+ Ok(a) => a + 1,
+ _ => 1,
+ };
+ let _ = match res {
+ Err(_) => 1,
+ Ok(a) => a + 1,
+ };
+ let _ = if let Ok(a) = res { a + 1 } else { 5 };
}
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index daba60600..a5dbf6e1f 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -206,5 +206,51 @@ LL + s.len() + x
LL ~ });
|
-error: aborting due to 15 previous errors
+error: use Option::map_or instead of an if let/else
+ --> $DIR/option_if_let_else.rs:213:13
+ |
+LL | let _ = match s {
+ | _____________^
+LL | | Some(string) => string.len(),
+LL | | None => 1,
+LL | | };
+ | |_____^ help: try: `s.map_or(1, |string| string.len())`
+
+error: use Option::map_or instead of an if let/else
+ --> $DIR/option_if_let_else.rs:217:13
+ |
+LL | let _ = match Some(10) {
+ | _____________^
+LL | | Some(a) => a + 1,
+LL | | None => 5,
+LL | | };
+ | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`
+
+error: use Option::map_or instead of an if let/else
+ --> $DIR/option_if_let_else.rs:223:13
+ |
+LL | let _ = match res {
+ | _____________^
+LL | | Ok(a) => a + 1,
+LL | | _ => 1,
+LL | | };
+ | |_____^ help: try: `res.map_or(1, |a| a + 1)`
+
+error: use Option::map_or instead of an if let/else
+ --> $DIR/option_if_let_else.rs:227:13
+ |
+LL | let _ = match res {
+ | _____________^
+LL | | Err(_) => 1,
+LL | | Ok(a) => a + 1,
+LL | | };
+ | |_____^ help: try: `res.map_or(1, |a| a + 1)`
+
+error: use Option::map_or instead of an if let/else
+ --> $DIR/option_if_let_else.rs:231:13
+ |
+LL | let _ = if let Ok(a) = res { a + 1 } else { 5 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`
+
+error: aborting due to 20 previous errors
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index fdb08d953..5991188ab 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -79,19 +79,19 @@ fn or_fun_call() {
without_default.unwrap_or_else(Foo::new);
let mut map = HashMap::<u64, String>::new();
- map.entry(42).or_insert(String::new());
+ map.entry(42).or_default();
let mut map_vec = HashMap::<u64, Vec<i32>>::new();
- map_vec.entry(42).or_insert(vec![]);
+ map_vec.entry(42).or_default();
let mut btree = BTreeMap::<u64, String>::new();
- btree.entry(42).or_insert(String::new());
+ btree.entry(42).or_default();
let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();
- btree_vec.entry(42).or_insert(vec![]);
+ btree_vec.entry(42).or_default();
- let stringy = Some(String::from(""));
- let _ = stringy.unwrap_or_else(|| "".to_owned());
+ let stringy = Some(String::new());
+ let _ = stringy.unwrap_or_default();
let opt = Some(1);
let hello = "Hello";
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index 57ab5f03e..c353b41e4 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -90,8 +90,8 @@ fn or_fun_call() {
let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();
btree_vec.entry(42).or_insert(vec![]);
- let stringy = Some(String::from(""));
- let _ = stringy.unwrap_or("".to_owned());
+ let stringy = Some(String::new());
+ let _ = stringy.unwrap_or(String::new());
let opt = Some(1);
let hello = "Hello";
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 4c5938ab8..e3dab4cb1 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -66,11 +66,35 @@ error: use of `unwrap_or` followed by a function call
LL | without_default.unwrap_or(Foo::new());
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)`
-error: use of `unwrap_or` followed by a function call
+error: use of `or_insert` followed by a call to `new`
+ --> $DIR/or_fun_call.rs:82:19
+ |
+LL | map.entry(42).or_insert(String::new());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_default()`
+
+error: use of `or_insert` followed by a call to `new`
+ --> $DIR/or_fun_call.rs:85:23
+ |
+LL | map_vec.entry(42).or_insert(vec![]);
+ | ^^^^^^^^^^^^^^^^^ help: try this: `or_default()`
+
+error: use of `or_insert` followed by a call to `new`
+ --> $DIR/or_fun_call.rs:88:21
+ |
+LL | btree.entry(42).or_insert(String::new());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_default()`
+
+error: use of `or_insert` followed by a call to `new`
+ --> $DIR/or_fun_call.rs:91:25
+ |
+LL | btree_vec.entry(42).or_insert(vec![]);
+ | ^^^^^^^^^^^^^^^^^ help: try this: `or_default()`
+
+error: use of `unwrap_or` followed by a call to `new`
--> $DIR/or_fun_call.rs:94:21
|
-LL | let _ = stringy.unwrap_or("".to_owned());
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())`
+LL | let _ = stringy.unwrap_or(String::new());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:102:21
@@ -132,5 +156,5 @@ error: use of `unwrap_or` followed by a call to `new`
LL | .unwrap_or(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()`
-error: aborting due to 22 previous errors
+error: aborting due to 26 previous errors
diff --git a/src/tools/clippy/tests/ui/logic_bug.rs b/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs
index dd6b1db5f..04a30a832 100644
--- a/src/tools/clippy/tests/ui/logic_bug.rs
+++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs
@@ -1,6 +1,6 @@
#![feature(lint_reasons)]
#![allow(unused, clippy::diverging_sub_expression)]
-#![warn(clippy::logic_bug)]
+#![warn(clippy::overly_complex_bool_expr)]
fn main() {
let a: bool = unimplemented!();
@@ -29,6 +29,6 @@ fn equality_stuff() {
fn check_expect() {
let a: i32 = unimplemented!();
let b: i32 = unimplemented!();
- #[expect(clippy::logic_bug)]
+ #[expect(clippy::overly_complex_bool_expr)]
let _ = a < b && a >= b;
}
diff --git a/src/tools/clippy/tests/ui/logic_bug.stderr b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
index 4021fbf45..158cae8b8 100644
--- a/src/tools/clippy/tests/ui/logic_bug.stderr
+++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
@@ -1,60 +1,60 @@
error: this boolean expression contains a logic bug
- --> $DIR/logic_bug.rs:11:13
+ --> $DIR/overly_complex_bool_expr.rs:11:13
|
LL | let _ = a && b || a;
| ^^^^^^^^^^^ help: it would look like the following: `a`
|
- = note: `-D clippy::logic-bug` implied by `-D warnings`
+ = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings`
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/logic_bug.rs:11:18
+ --> $DIR/overly_complex_bool_expr.rs:11:18
|
LL | let _ = a && b || a;
| ^
error: this boolean expression contains a logic bug
- --> $DIR/logic_bug.rs:13:13
+ --> $DIR/overly_complex_bool_expr.rs:13:13
|
LL | let _ = false && a;
| ^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/logic_bug.rs:13:22
+ --> $DIR/overly_complex_bool_expr.rs:13:22
|
LL | let _ = false && a;
| ^
error: this boolean expression contains a logic bug
- --> $DIR/logic_bug.rs:23:13
+ --> $DIR/overly_complex_bool_expr.rs:23:13
|
LL | let _ = a == b && a != b;
| ^^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/logic_bug.rs:23:13
+ --> $DIR/overly_complex_bool_expr.rs:23:13
|
LL | let _ = a == b && a != b;
| ^^^^^^
error: this boolean expression contains a logic bug
- --> $DIR/logic_bug.rs:24:13
+ --> $DIR/overly_complex_bool_expr.rs:24:13
|
LL | let _ = a < b && a >= b;
| ^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/logic_bug.rs:24:13
+ --> $DIR/overly_complex_bool_expr.rs:24:13
|
LL | let _ = a < b && a >= b;
| ^^^^^
error: this boolean expression contains a logic bug
- --> $DIR/logic_bug.rs:25:13
+ --> $DIR/overly_complex_bool_expr.rs:25:13
|
LL | let _ = a > b && a <= b;
| ^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/logic_bug.rs:25:13
+ --> $DIR/overly_complex_bool_expr.rs:25:13
|
LL | let _ = a > b && a <= b;
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.fixed b/src/tools/clippy/tests/ui/partialeq_to_none.fixed
new file mode 100644
index 000000000..4644ea8f5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/partialeq_to_none.fixed
@@ -0,0 +1,74 @@
+// run-rustfix
+#![warn(clippy::partialeq_to_none)]
+
+struct Foobar;
+
+impl PartialEq<Option<()>> for Foobar {
+ fn eq(&self, _: &Option<()>) -> bool {
+ false
+ }
+}
+
+#[allow(dead_code)]
+fn foo(f: Option<u32>) -> &'static str {
+ if f.is_some() { "yay" } else { "nay" }
+}
+
+fn foobar() -> Option<()> {
+ None
+}
+
+fn bar() -> Result<(), ()> {
+ Ok(())
+}
+
+fn optref() -> &'static &'static Option<()> {
+ &&None
+}
+
+pub fn macro_expansion() {
+ macro_rules! foo {
+ () => {
+ None::<()>
+ };
+ }
+
+ let _ = foobar() == foo!();
+ let _ = foo!() == foobar();
+ let _ = foo!() == foo!();
+}
+
+fn main() {
+ let x = Some(0);
+
+ let _ = x.is_none();
+ let _ = x.is_some();
+ let _ = x.is_none();
+ let _ = x.is_some();
+
+ if foobar().is_none() {}
+
+ if bar().ok().is_some() {}
+
+ let _ = Some(1 + 2).is_some();
+
+ let _ = { Some(0) }.is_none();
+
+ let _ = {
+ /*
+ This comment runs long
+ */
+ Some(1)
+ }.is_some();
+
+ // Should not trigger, as `Foobar` is not an `Option` and has no `is_none`
+ let _ = Foobar == None;
+
+ let _ = optref().is_none();
+ let _ = optref().is_some();
+ let _ = optref().is_none();
+ let _ = optref().is_some();
+
+ let x = Box::new(Option::<()>::None);
+ let _ = (*x).is_some();
+}
diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.rs b/src/tools/clippy/tests/ui/partialeq_to_none.rs
new file mode 100644
index 000000000..61011b3a8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/partialeq_to_none.rs
@@ -0,0 +1,74 @@
+// run-rustfix
+#![warn(clippy::partialeq_to_none)]
+
+struct Foobar;
+
+impl PartialEq<Option<()>> for Foobar {
+ fn eq(&self, _: &Option<()>) -> bool {
+ false
+ }
+}
+
+#[allow(dead_code)]
+fn foo(f: Option<u32>) -> &'static str {
+ if f != None { "yay" } else { "nay" }
+}
+
+fn foobar() -> Option<()> {
+ None
+}
+
+fn bar() -> Result<(), ()> {
+ Ok(())
+}
+
+fn optref() -> &'static &'static Option<()> {
+ &&None
+}
+
+pub fn macro_expansion() {
+ macro_rules! foo {
+ () => {
+ None::<()>
+ };
+ }
+
+ let _ = foobar() == foo!();
+ let _ = foo!() == foobar();
+ let _ = foo!() == foo!();
+}
+
+fn main() {
+ let x = Some(0);
+
+ let _ = x == None;
+ let _ = x != None;
+ let _ = None == x;
+ let _ = None != x;
+
+ if foobar() == None {}
+
+ if bar().ok() != None {}
+
+ let _ = Some(1 + 2) != None;
+
+ let _ = { Some(0) } == None;
+
+ let _ = {
+ /*
+ This comment runs long
+ */
+ Some(1)
+ } != None;
+
+ // Should not trigger, as `Foobar` is not an `Option` and has no `is_none`
+ let _ = Foobar == None;
+
+ let _ = optref() == &&None;
+ let _ = &&None != optref();
+ let _ = **optref() == None;
+ let _ = &None != *optref();
+
+ let x = Box::new(Option::<()>::None);
+ let _ = None != *x;
+}
diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.stderr b/src/tools/clippy/tests/ui/partialeq_to_none.stderr
new file mode 100644
index 000000000..d06ab7aee
--- /dev/null
+++ b/src/tools/clippy/tests/ui/partialeq_to_none.stderr
@@ -0,0 +1,110 @@
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:14:8
+ |
+LL | if f != None { "yay" } else { "nay" }
+ | ^^^^^^^^^ help: use `Option::is_some()` instead: `f.is_some()`
+ |
+ = note: `-D clippy::partialeq-to-none` implied by `-D warnings`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:44:13
+ |
+LL | let _ = x == None;
+ | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:45:13
+ |
+LL | let _ = x != None;
+ | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:46:13
+ |
+LL | let _ = None == x;
+ | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:47:13
+ |
+LL | let _ = None != x;
+ | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:49:8
+ |
+LL | if foobar() == None {}
+ | ^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `foobar().is_none()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:51:8
+ |
+LL | if bar().ok() != None {}
+ | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `bar().ok().is_some()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:53:13
+ |
+LL | let _ = Some(1 + 2) != None;
+ | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `Some(1 + 2).is_some()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:55:13
+ |
+LL | let _ = { Some(0) } == None;
+ | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `{ Some(0) }.is_none()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:57:13
+ |
+LL | let _ = {
+ | _____________^
+LL | | /*
+LL | | This comment runs long
+LL | | */
+LL | | Some(1)
+LL | | } != None;
+ | |_____________^
+ |
+help: use `Option::is_some()` instead
+ |
+LL ~ let _ = {
+LL + /*
+LL + This comment runs long
+LL + */
+LL + Some(1)
+LL ~ }.is_some();
+ |
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:67:13
+ |
+LL | let _ = optref() == &&None;
+ | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:68:13
+ |
+LL | let _ = &&None != optref();
+ | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:69:13
+ |
+LL | let _ = **optref() == None;
+ | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:70:13
+ |
+LL | let _ = &None != *optref();
+ | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()`
+
+error: binary comparison to literal `Option::None`
+ --> $DIR/partialeq_to_none.rs:73:13
+ |
+LL | let _ = None != *x;
+ | ^^^^^^^^^^ help: use `Option::is_some()` instead: `(*x).is_some()`
+
+error: aborting due to 15 previous errors
+
diff --git a/src/tools/clippy/tests/ui/positional_named_format_parameters.fixed b/src/tools/clippy/tests/ui/positional_named_format_parameters.fixed
new file mode 100644
index 000000000..4170e1098
--- /dev/null
+++ b/src/tools/clippy/tests/ui/positional_named_format_parameters.fixed
@@ -0,0 +1,56 @@
+// run-rustfix
+#![allow(unused_must_use)]
+#![allow(named_arguments_used_positionally)] // Unstable at time of writing.
+#![warn(clippy::positional_named_format_parameters)]
+
+use std::io::Write;
+
+fn main() {
+ let mut v = Vec::new();
+ let hello = "Hello";
+
+ println!("{hello:.foo$}", foo = 2);
+ writeln!(v, "{hello:.foo$}", foo = 2);
+
+ // Warnings
+ println!("{zero} {one:?}", zero = 0, one = 1);
+ println!("This is a test {zero} {one:?}", zero = 0, one = 1);
+ println!("Hello {one} is {two:.zero$}", zero = 5, one = hello, two = 0.01);
+ println!("Hello {one:zero$}!", zero = 5, one = 1);
+ println!("Hello {zero:one$}!", zero = 4, one = 1);
+ println!("Hello {zero:0one$}!", zero = 4, one = 1);
+ println!("Hello is {one:.zero$}", zero = 5, one = 0.01);
+ println!("Hello is {one:<6.zero$}", zero = 5, one = 0.01);
+ println!("{zero}, `{two:>8.one$}` has 3", zero = hello, one = 3, two = hello);
+ println!("Hello {one} is {two:.zero$}", zero = 5, one = hello, two = 0.01);
+ println!("Hello {world} {world}!", world = 5);
+
+ writeln!(v, "{zero} {one:?}", zero = 0, one = 1);
+ writeln!(v, "This is a test {zero} {one:?}", zero = 0, one = 1);
+ writeln!(v, "Hello {one} is {two:.zero$}", zero = 5, one = hello, two = 0.01);
+ writeln!(v, "Hello {one:zero$}!", zero = 4, one = 1);
+ writeln!(v, "Hello {zero:one$}!", zero = 4, one = 1);
+ writeln!(v, "Hello {zero:0one$}!", zero = 4, one = 1);
+ writeln!(v, "Hello is {one:.zero$}", zero = 3, one = 0.01);
+ writeln!(v, "Hello is {one:<6.zero$}", zero = 2, one = 0.01);
+ writeln!(v, "{zero}, `{two:>8.one$}` has 3", zero = hello, one = 3, two = hello);
+ writeln!(v, "Hello {one} is {two:.zero$}", zero = 1, one = hello, two = 0.01);
+ writeln!(v, "Hello {world} {world}!", world = 0);
+
+ // Tests from other files
+ println!("{w:w$}", w = 1);
+ println!("{p:.p$}", p = 1);
+ println!("{v}", v = 1);
+ println!("{v:v$}", v = 1);
+ println!("{v:v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{v:v$.v$}", v = 1);
+ println!("{w:w$}", w = 1);
+ println!("{p:.p$}", p = 1);
+ println!("{:p$.w$}", 1, w = 1, p = 1);
+}
diff --git a/src/tools/clippy/tests/ui/positional_named_format_parameters.rs b/src/tools/clippy/tests/ui/positional_named_format_parameters.rs
new file mode 100644
index 000000000..553d8494e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/positional_named_format_parameters.rs
@@ -0,0 +1,56 @@
+// run-rustfix
+#![allow(unused_must_use)]
+#![allow(named_arguments_used_positionally)] // Unstable at time of writing.
+#![warn(clippy::positional_named_format_parameters)]
+
+use std::io::Write;
+
+fn main() {
+ let mut v = Vec::new();
+ let hello = "Hello";
+
+ println!("{hello:.foo$}", foo = 2);
+ writeln!(v, "{hello:.foo$}", foo = 2);
+
+ // Warnings
+ println!("{} {1:?}", zero = 0, one = 1);
+ println!("This is a test { } {000001:?}", zero = 0, one = 1);
+ println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ println!("Hello {1:0$}!", zero = 5, one = 1);
+ println!("Hello {0:1$}!", zero = 4, one = 1);
+ println!("Hello {0:01$}!", zero = 4, one = 1);
+ println!("Hello is {1:.*}", zero = 5, one = 0.01);
+ println!("Hello is {:<6.*}", zero = 5, one = 0.01);
+ println!("{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello);
+ println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ println!("Hello {world} {}!", world = 5);
+
+ writeln!(v, "{} {1:?}", zero = 0, one = 1);
+ writeln!(v, "This is a test { } {000001:?}", zero = 0, one = 1);
+ writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ writeln!(v, "Hello {1:0$}!", zero = 4, one = 1);
+ writeln!(v, "Hello {0:1$}!", zero = 4, one = 1);
+ writeln!(v, "Hello {0:01$}!", zero = 4, one = 1);
+ writeln!(v, "Hello is {1:.*}", zero = 3, one = 0.01);
+ writeln!(v, "Hello is {:<6.*}", zero = 2, one = 0.01);
+ writeln!(v, "{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello);
+ writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01);
+ writeln!(v, "Hello {world} {}!", world = 0);
+
+ // Tests from other files
+ println!("{:w$}", w = 1);
+ println!("{:.p$}", p = 1);
+ println!("{}", v = 1);
+ println!("{:0$}", v = 1);
+ println!("{0:0$}", v = 1);
+ println!("{:0$.0$}", v = 1);
+ println!("{0:0$.0$}", v = 1);
+ println!("{0:0$.v$}", v = 1);
+ println!("{0:v$.0$}", v = 1);
+ println!("{v:0$.0$}", v = 1);
+ println!("{v:v$.0$}", v = 1);
+ println!("{v:0$.v$}", v = 1);
+ println!("{:w$}", w = 1);
+ println!("{:.p$}", p = 1);
+ println!("{:p$.w$}", 1, w = 1, p = 1);
+}
diff --git a/src/tools/clippy/tests/ui/positional_named_format_parameters.stderr b/src/tools/clippy/tests/ui/positional_named_format_parameters.stderr
new file mode 100644
index 000000000..48ddb6d67
--- /dev/null
+++ b/src/tools/clippy/tests/ui/positional_named_format_parameters.stderr
@@ -0,0 +1,418 @@
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:16:16
+ |
+LL | println!("{} {1:?}", zero = 0, one = 1);
+ | ^ help: replace it with: `zero`
+ |
+ = note: `-D clippy::positional-named-format-parameters` implied by `-D warnings`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:16:19
+ |
+LL | println!("{} {1:?}", zero = 0, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:17:31
+ |
+LL | println!("This is a test { } {000001:?}", zero = 0, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:17:35
+ |
+LL | println!("This is a test { } {000001:?}", zero = 0, one = 1);
+ | ^^^^^^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:18:32
+ |
+LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:18:22
+ |
+LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter two is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:18:29
+ |
+LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `two`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:19:24
+ |
+LL | println!("Hello {1:0$}!", zero = 5, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:19:22
+ |
+LL | println!("Hello {1:0$}!", zero = 5, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:20:22
+ |
+LL | println!("Hello {0:1$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:20:24
+ |
+LL | println!("Hello {0:1$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:21:22
+ |
+LL | println!("Hello {0:01$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:21:25
+ |
+LL | println!("Hello {0:01$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:22:28
+ |
+LL | println!("Hello is {1:.*}", zero = 5, one = 0.01);
+ | ^ help: replace it with: `zero$`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:22:25
+ |
+LL | println!("Hello is {1:.*}", zero = 5, one = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:23:29
+ |
+LL | println!("Hello is {:<6.*}", zero = 5, one = 0.01);
+ | ^ help: replace it with: `zero$`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:23:25
+ |
+LL | println!("Hello is {:<6.*}", zero = 5, one = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:24:16
+ |
+LL | println!("{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:24:28
+ |
+LL | println!("{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello);
+ | ^ help: replace it with: `one$`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:25:32
+ |
+LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:25:22
+ |
+LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter two is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:25:29
+ |
+LL | println!("Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `two`
+
+error: named parameter world is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:26:30
+ |
+LL | println!("Hello {world} {}!", world = 5);
+ | ^ help: replace it with: `world`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:28:19
+ |
+LL | writeln!(v, "{} {1:?}", zero = 0, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:28:22
+ |
+LL | writeln!(v, "{} {1:?}", zero = 0, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:29:34
+ |
+LL | writeln!(v, "This is a test { } {000001:?}", zero = 0, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:29:38
+ |
+LL | writeln!(v, "This is a test { } {000001:?}", zero = 0, one = 1);
+ | ^^^^^^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:30:35
+ |
+LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:30:25
+ |
+LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter two is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:30:32
+ |
+LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 5, one = hello, two = 0.01);
+ | ^ help: replace it with: `two`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:31:27
+ |
+LL | writeln!(v, "Hello {1:0$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:31:25
+ |
+LL | writeln!(v, "Hello {1:0$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:32:25
+ |
+LL | writeln!(v, "Hello {0:1$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:32:27
+ |
+LL | writeln!(v, "Hello {0:1$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:33:25
+ |
+LL | writeln!(v, "Hello {0:01$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:33:28
+ |
+LL | writeln!(v, "Hello {0:01$}!", zero = 4, one = 1);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:34:31
+ |
+LL | writeln!(v, "Hello is {1:.*}", zero = 3, one = 0.01);
+ | ^ help: replace it with: `zero$`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:34:28
+ |
+LL | writeln!(v, "Hello is {1:.*}", zero = 3, one = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:35:32
+ |
+LL | writeln!(v, "Hello is {:<6.*}", zero = 2, one = 0.01);
+ | ^ help: replace it with: `zero$`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:35:28
+ |
+LL | writeln!(v, "Hello is {:<6.*}", zero = 2, one = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:36:19
+ |
+LL | writeln!(v, "{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:36:31
+ |
+LL | writeln!(v, "{}, `{two:>8.*}` has 3", zero = hello, one = 3, two = hello);
+ | ^ help: replace it with: `one$`
+
+error: named parameter zero is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:37:35
+ |
+LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01);
+ | ^ help: replace it with: `zero`
+
+error: named parameter one is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:37:25
+ |
+LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01);
+ | ^ help: replace it with: `one`
+
+error: named parameter two is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:37:32
+ |
+LL | writeln!(v, "Hello {1} is {2:.0$}", zero = 1, one = hello, two = 0.01);
+ | ^ help: replace it with: `two`
+
+error: named parameter world is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:38:33
+ |
+LL | writeln!(v, "Hello {world} {}!", world = 0);
+ | ^ help: replace it with: `world`
+
+error: named parameter w is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:41:16
+ |
+LL | println!("{:w$}", w = 1);
+ | ^ help: replace it with: `w`
+
+error: named parameter p is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:42:16
+ |
+LL | println!("{:.p$}", p = 1);
+ | ^ help: replace it with: `p`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:43:16
+ |
+LL | println!("{}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:44:16
+ |
+LL | println!("{:0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:44:17
+ |
+LL | println!("{:0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:45:16
+ |
+LL | println!("{0:0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:45:18
+ |
+LL | println!("{0:0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:46:16
+ |
+LL | println!("{:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:46:20
+ |
+LL | println!("{:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:46:17
+ |
+LL | println!("{:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:47:16
+ |
+LL | println!("{0:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:47:21
+ |
+LL | println!("{0:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:47:18
+ |
+LL | println!("{0:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:48:16
+ |
+LL | println!("{0:0$.v$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:48:18
+ |
+LL | println!("{0:0$.v$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:49:16
+ |
+LL | println!("{0:v$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:49:21
+ |
+LL | println!("{0:v$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:50:21
+ |
+LL | println!("{v:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:50:18
+ |
+LL | println!("{v:0$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:51:21
+ |
+LL | println!("{v:v$.0$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter v is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:52:18
+ |
+LL | println!("{v:0$.v$}", v = 1);
+ | ^ help: replace it with: `v`
+
+error: named parameter w is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:53:16
+ |
+LL | println!("{:w$}", w = 1);
+ | ^ help: replace it with: `w`
+
+error: named parameter p is used as a positional parameter
+ --> $DIR/positional_named_format_parameters.rs:54:16
+ |
+LL | println!("{:.p$}", p = 1);
+ | ^ help: replace it with: `p`
+
+error: aborting due to 69 previous errors
+
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index c4c9c8214..57f23bd19 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -207,4 +207,19 @@ fn option_map() -> Option<bool> {
}
}
+pub struct PatternedError {
+ flag: bool,
+}
+
+// No warning
+fn pattern() -> Result<(), PatternedError> {
+ let res = Ok(());
+
+ if let Err(err @ PatternedError { flag: true }) = res {
+ return Err(err);
+ }
+
+ res
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index cdbc7b160..436f027c2 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -243,4 +243,19 @@ fn option_map() -> Option<bool> {
}
}
+pub struct PatternedError {
+ flag: bool,
+}
+
+// No warning
+fn pattern() -> Result<(), PatternedError> {
+ let res = Ok(());
+
+ if let Err(err @ PatternedError { flag: true }) = res {
+ return Err(err);
+ }
+
+ res
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
index 40d7791df..a16a3e54d 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
@@ -6,6 +6,22 @@ fn f() -> usize {
42
}
+macro_rules! macro_plus_one {
+ ($m: literal) => {
+ for i in 0..$m + 1 {
+ println!("{}", i);
+ }
+ };
+}
+
+macro_rules! macro_minus_one {
+ ($m: literal) => {
+ for i in 0..=$m - 1 {
+ println!("{}", i);
+ }
+ };
+}
+
#[warn(clippy::range_plus_one)]
#[warn(clippy::range_minus_one)]
fn main() {
@@ -39,4 +55,7 @@ fn main() {
let mut vec: Vec<()> = std::vec::Vec::new();
vec.drain(..);
+
+ macro_plus_one!(5);
+ macro_minus_one!(5);
}
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.rs b/src/tools/clippy/tests/ui/range_plus_minus_one.rs
index a8ddd9b5f..bd6cb4d21 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.rs
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.rs
@@ -6,6 +6,22 @@ fn f() -> usize {
42
}
+macro_rules! macro_plus_one {
+ ($m: literal) => {
+ for i in 0..$m + 1 {
+ println!("{}", i);
+ }
+ };
+}
+
+macro_rules! macro_minus_one {
+ ($m: literal) => {
+ for i in 0..=$m - 1 {
+ println!("{}", i);
+ }
+ };
+}
+
#[warn(clippy::range_plus_one)]
#[warn(clippy::range_minus_one)]
fn main() {
@@ -39,4 +55,7 @@ fn main() {
let mut vec: Vec<()> = std::vec::Vec::new();
vec.drain(..);
+
+ macro_plus_one!(5);
+ macro_minus_one!(5);
}
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
index fb4f16585..022369624 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
@@ -1,5 +1,5 @@
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:15:14
+ --> $DIR/range_plus_minus_one.rs:31:14
|
LL | for _ in 0..3 + 1 {}
| ^^^^^^^^ help: use: `0..=3`
@@ -7,25 +7,25 @@ LL | for _ in 0..3 + 1 {}
= note: `-D clippy::range-plus-one` implied by `-D warnings`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:18:14
+ --> $DIR/range_plus_minus_one.rs:34:14
|
LL | for _ in 0..1 + 5 {}
| ^^^^^^^^ help: use: `0..=5`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:21:14
+ --> $DIR/range_plus_minus_one.rs:37:14
|
LL | for _ in 1..1 + 1 {}
| ^^^^^^^^ help: use: `1..=1`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:27:14
+ --> $DIR/range_plus_minus_one.rs:43:14
|
LL | for _ in 0..(1 + f()) {}
| ^^^^^^^^^^^^ help: use: `0..=f()`
error: an exclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:31:13
+ --> $DIR/range_plus_minus_one.rs:47:13
|
LL | let _ = ..=11 - 1;
| ^^^^^^^^^ help: use: `..11`
@@ -33,25 +33,25 @@ LL | let _ = ..=11 - 1;
= note: `-D clippy::range-minus-one` implied by `-D warnings`
error: an exclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:32:13
+ --> $DIR/range_plus_minus_one.rs:48:13
|
LL | let _ = ..=(11 - 1);
| ^^^^^^^^^^^ help: use: `..11`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:33:13
+ --> $DIR/range_plus_minus_one.rs:49:13
|
LL | let _ = (1..11 + 1);
| ^^^^^^^^^^^ help: use: `(1..=11)`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:34:13
+ --> $DIR/range_plus_minus_one.rs:50:13
|
LL | let _ = (f() + 1)..(f() + 1);
| ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:38:14
+ --> $DIR/range_plus_minus_one.rs:54:14
|
LL | for _ in 1..ONE + ONE {}
| ^^^^^^^^^^^^ help: use: `1..=ONE`
diff --git a/src/tools/clippy/tests/ui/rc_mutex.rs b/src/tools/clippy/tests/ui/rc_mutex.rs
index 18e8a2e01..432972bbc 100644
--- a/src/tools/clippy/tests/ui/rc_mutex.rs
+++ b/src/tools/clippy/tests/ui/rc_mutex.rs
@@ -1,5 +1,5 @@
#![warn(clippy::rc_mutex)]
-#![allow(unused, clippy::blacklisted_name)]
+#![allow(unused, clippy::disallowed_names)]
use std::rc::Rc;
use std::sync::Mutex;
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs
index cf7d8c6e3..574d34aed 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation.rs
@@ -1,7 +1,5 @@
#![warn(clippy::all)]
-#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
-#![allow(clippy::blacklisted_name, unused_variables, dead_code)]
-#![allow(unused_imports)]
+#![allow(clippy::boxed_local, clippy::disallowed_names)]
pub struct MyStruct;
@@ -9,13 +7,7 @@ pub struct SubT<T> {
foo: T,
}
-pub enum MyEnum {
- One,
- Two,
-}
-
mod outer_box {
- use crate::MyEnum;
use crate::MyStruct;
use crate::SubT;
use std::boxed::Box;
@@ -36,7 +28,6 @@ mod outer_box {
}
mod outer_rc {
- use crate::MyEnum;
use crate::MyStruct;
use crate::SubT;
use std::boxed::Box;
@@ -57,7 +48,6 @@ mod outer_rc {
}
mod outer_arc {
- use crate::MyEnum;
use crate::MyStruct;
use crate::SubT;
use std::boxed::Box;
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.stderr b/src/tools/clippy/tests/ui/redundant_allocation.stderr
index fab1b069f..54d4d88db 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.stderr
+++ b/src/tools/clippy/tests/ui/redundant_allocation.stderr
@@ -1,5 +1,5 @@
error: usage of `Box<Rc<T>>`
- --> $DIR/redundant_allocation.rs:25:30
+ --> $DIR/redundant_allocation.rs:17:30
|
LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
| ^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
= help: consider using just `Box<T>` or `Rc<T>`
error: usage of `Box<Arc<T>>`
- --> $DIR/redundant_allocation.rs:27:30
+ --> $DIR/redundant_allocation.rs:19:30
|
LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
| ^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
= help: consider using just `Box<T>` or `Arc<T>`
error: usage of `Box<Rc<SubT<usize>>>`
- --> $DIR/redundant_allocation.rs:29:27
+ --> $DIR/redundant_allocation.rs:21:27
|
LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
= help: consider using just `Box<SubT<usize>>` or `Rc<SubT<usize>>`
error: usage of `Box<Arc<T>>`
- --> $DIR/redundant_allocation.rs:33:30
+ --> $DIR/redundant_allocation.rs:25:30
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
| ^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
= help: consider using just `Box<T>` or `Arc<T>`
error: usage of `Box<Arc<SubT<T>>>`
- --> $DIR/redundant_allocation.rs:33:46
+ --> $DIR/redundant_allocation.rs:25:46
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
= help: consider using just `Box<SubT<T>>` or `Arc<SubT<T>>`
error: usage of `Rc<Box<bool>>`
- --> $DIR/redundant_allocation.rs:46:24
+ --> $DIR/redundant_allocation.rs:37:24
|
LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
| ^^^^^^^^^^^^^
@@ -54,7 +54,7 @@ LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
= help: consider using just `Rc<bool>` or `Box<bool>`
error: usage of `Rc<Arc<bool>>`
- --> $DIR/redundant_allocation.rs:48:24
+ --> $DIR/redundant_allocation.rs:39:24
|
LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
| ^^^^^^^^^^^^^
@@ -63,7 +63,7 @@ LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
= help: consider using just `Rc<bool>` or `Arc<bool>`
error: usage of `Rc<Box<SubT<usize>>>`
- --> $DIR/redundant_allocation.rs:50:26
+ --> $DIR/redundant_allocation.rs:41:26
|
LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
= help: consider using just `Rc<SubT<usize>>` or `Box<SubT<usize>>`
error: usage of `Rc<Arc<T>>`
- --> $DIR/redundant_allocation.rs:54:29
+ --> $DIR/redundant_allocation.rs:45:29
|
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
| ^^^^^^^^^^
@@ -81,7 +81,7 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
= help: consider using just `Rc<T>` or `Arc<T>`
error: usage of `Rc<Arc<SubT<T>>>`
- --> $DIR/redundant_allocation.rs:54:44
+ --> $DIR/redundant_allocation.rs:45:44
|
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
= help: consider using just `Rc<SubT<T>>` or `Arc<SubT<T>>`
error: usage of `Arc<Box<bool>>`
- --> $DIR/redundant_allocation.rs:67:25
+ --> $DIR/redundant_allocation.rs:57:25
|
LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
| ^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
= help: consider using just `Arc<bool>` or `Box<bool>`
error: usage of `Arc<Rc<bool>>`
- --> $DIR/redundant_allocation.rs:69:25
+ --> $DIR/redundant_allocation.rs:59:25
|
LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
| ^^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
= help: consider using just `Arc<bool>` or `Rc<bool>`
error: usage of `Arc<Box<SubT<usize>>>`
- --> $DIR/redundant_allocation.rs:71:27
+ --> $DIR/redundant_allocation.rs:61:27
|
LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
= help: consider using just `Arc<SubT<usize>>` or `Box<SubT<usize>>`
error: usage of `Arc<Rc<T>>`
- --> $DIR/redundant_allocation.rs:75:30
+ --> $DIR/redundant_allocation.rs:65:30
|
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
| ^^^^^^^^^^
@@ -126,7 +126,7 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
= help: consider using just `Arc<T>` or `Rc<T>`
error: usage of `Arc<Rc<SubT<T>>>`
- --> $DIR/redundant_allocation.rs:75:45
+ --> $DIR/redundant_allocation.rs:65:45
|
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
= help: consider using just `Arc<SubT<T>>` or `Rc<SubT<T>>`
error: usage of `Rc<Box<Box<dyn T>>>`
- --> $DIR/redundant_allocation.rs:97:27
+ --> $DIR/redundant_allocation.rs:87:27
|
LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}
| ^^^^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}
= help: consider using just `Rc<Box<dyn T>>` or `Box<Box<dyn T>>`
error: usage of `Rc<Box<Box<str>>>`
- --> $DIR/redundant_allocation.rs:129:31
+ --> $DIR/redundant_allocation.rs:119:31
|
LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}
| ^^^^^^^^^^^^^^^^^
@@ -153,7 +153,7 @@ LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}
= help: consider using just `Rc<Box<str>>` or `Box<Box<str>>`
error: usage of `Rc<Box<Box<[usize]>>>`
- --> $DIR/redundant_allocation.rs:130:33
+ --> $DIR/redundant_allocation.rs:120:33
|
LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^
@@ -162,7 +162,7 @@ LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}
= help: consider using just `Rc<Box<[usize]>>` or `Box<Box<[usize]>>`
error: usage of `Rc<Box<Box<Path>>>`
- --> $DIR/redundant_allocation.rs:131:32
+ --> $DIR/redundant_allocation.rs:121:32
|
LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}
| ^^^^^^^^^^^^^^^^^^
@@ -171,7 +171,7 @@ LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}
= help: consider using just `Rc<Box<Path>>` or `Box<Box<Path>>`
error: usage of `Rc<Box<Box<DynSized>>>`
- --> $DIR/redundant_allocation.rs:132:34
+ --> $DIR/redundant_allocation.rs:122:34
|
LL | pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
index e7ed84731..6db02718c 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
@@ -1,7 +1,7 @@
// run-rustfix
#![warn(clippy::all)]
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
-#![allow(clippy::blacklisted_name, unused_variables, dead_code)]
+#![allow(clippy::disallowed_names, unused_variables, dead_code)]
#![allow(unused_imports)]
pub struct MyStruct;
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
index de763f98b..c15806f30 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
@@ -1,7 +1,7 @@
// run-rustfix
#![warn(clippy::all)]
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
-#![allow(clippy::blacklisted_name, unused_variables, dead_code)]
+#![allow(clippy::disallowed_names, unused_variables, dead_code)]
#![allow(unused_imports)]
pub struct MyStruct;
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index 0abca6fca..7cd687c95 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -1,8 +1,28 @@
// run-rustfix
+#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(unused)]
+async fn something() -> u32 {
+ 21
+}
+
+async fn something_else() -> u32 {
+ 2
+}
+
fn main() {
let a = 42;
+ let b = async {
+ let x = something().await;
+ let y = something_else().await;
+ x * y
+ };
+ let c = {
+ let x = 21;
+ let y = 2;
+ x * y
+ };
+ let d = async { something().await };
}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index f8b9d37a5..37e4d2238 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -1,8 +1,28 @@
// run-rustfix
+#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(unused)]
+async fn something() -> u32 {
+ 21
+}
+
+async fn something_else() -> u32 {
+ 2
+}
+
fn main() {
let a = (|| 42)();
+ let b = (async || {
+ let x = something().await;
+ let y = something_else().await;
+ x * y
+ })();
+ let c = (|| {
+ let x = 21;
+ let y = 2;
+ x * y
+ })();
+ let d = (async || something().await)();
}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
index afd704ef1..56a8e57c0 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
@@ -1,10 +1,56 @@
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:7:13
+ --> $DIR/redundant_closure_call_fixable.rs:16:13
|
LL | let a = (|| 42)();
| ^^^^^^^^^ help: try doing something like: `42`
|
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
-error: aborting due to previous error
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:17:13
+ |
+LL | let b = (async || {
+ | _____________^
+LL | | let x = something().await;
+LL | | let y = something_else().await;
+LL | | x * y
+LL | | })();
+ | |________^
+ |
+help: try doing something like
+ |
+LL ~ let b = async {
+LL + let x = something().await;
+LL + let y = something_else().await;
+LL + x * y
+LL ~ };
+ |
+
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:22:13
+ |
+LL | let c = (|| {
+ | _____________^
+LL | | let x = 21;
+LL | | let y = 2;
+LL | | x * y
+LL | | })();
+ | |________^
+ |
+help: try doing something like
+ |
+LL ~ let c = {
+LL + let x = 21;
+LL + let y = 2;
+LL + x * y
+LL ~ };
+ |
+
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:27:13
+ |
+LL | let d = (async || something().await)();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
+
+error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs
index f7f3b195c..f0e1a8128 100644
--- a/src/tools/clippy/tests/ui/regex.rs
+++ b/src/tools/clippy/tests/ui/regex.rs
@@ -1,4 +1,4 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_borrow)]
#![warn(clippy::invalid_regex, clippy::trivial_regex)]
extern crate regex;
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 53288be94..9cbad2269 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -4,6 +4,7 @@
// run-rustfix
+#![allow(clippy::disallowed_names)]
#![allow(clippy::blocks_in_if_conditions)]
#![allow(clippy::box_collection)]
#![allow(clippy::redundant_static_lifetimes)]
@@ -14,6 +15,7 @@
#![allow(clippy::for_loops_over_fallibles)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
+#![allow(clippy::overly_complex_bool_expr)]
#![allow(clippy::new_without_default)]
#![allow(clippy::bind_instead_of_map)]
#![allow(clippy::expect_used)]
@@ -33,6 +35,7 @@
#![allow(temporary_cstring_as_ptr)]
#![allow(unknown_lints)]
#![allow(unused_labels)]
+#![warn(clippy::disallowed_names)]
#![warn(clippy::blocks_in_if_conditions)]
#![warn(clippy::blocks_in_if_conditions)]
#![warn(clippy::box_collection)]
@@ -45,6 +48,7 @@
#![warn(clippy::for_loops_over_fallibles)]
#![warn(clippy::useless_conversion)]
#![warn(clippy::match_result_ok)]
+#![warn(clippy::overly_complex_bool_expr)]
#![warn(clippy::new_without_default)]
#![warn(clippy::bind_instead_of_map)]
#![warn(clippy::expect_used)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 539f34f84..9153c0dab 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -4,6 +4,7 @@
// run-rustfix
+#![allow(clippy::disallowed_names)]
#![allow(clippy::blocks_in_if_conditions)]
#![allow(clippy::box_collection)]
#![allow(clippy::redundant_static_lifetimes)]
@@ -14,6 +15,7 @@
#![allow(clippy::for_loops_over_fallibles)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
+#![allow(clippy::overly_complex_bool_expr)]
#![allow(clippy::new_without_default)]
#![allow(clippy::bind_instead_of_map)]
#![allow(clippy::expect_used)]
@@ -33,6 +35,7 @@
#![allow(temporary_cstring_as_ptr)]
#![allow(unknown_lints)]
#![allow(unused_labels)]
+#![warn(clippy::blacklisted_name)]
#![warn(clippy::block_in_if_condition_expr)]
#![warn(clippy::block_in_if_condition_stmt)]
#![warn(clippy::box_vec)]
@@ -45,6 +48,7 @@
#![warn(clippy::for_loop_over_result)]
#![warn(clippy::identity_conversion)]
#![warn(clippy::if_let_some_result)]
+#![warn(clippy::logic_bug)]
#![warn(clippy::new_without_default_derive)]
#![warn(clippy::option_and_then_some)]
#![warn(clippy::option_expect_used)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 8ea46b580..9c03ea914 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,214 +1,226 @@
+error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
+ --> $DIR/rename.rs:38:9
+ |
+LL | #![warn(clippy::blacklisted_name)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
+ |
+ = note: `-D renamed-and-removed-lints` implied by `-D warnings`
+
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
- --> $DIR/rename.rs:36:9
+ --> $DIR/rename.rs:39:9
|
LL | #![warn(clippy::block_in_if_condition_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
- |
- = note: `-D renamed-and-removed-lints` implied by `-D warnings`
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
- --> $DIR/rename.rs:37:9
+ --> $DIR/rename.rs:40:9
|
LL | #![warn(clippy::block_in_if_condition_stmt)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
- --> $DIR/rename.rs:38:9
+ --> $DIR/rename.rs:41:9
|
LL | #![warn(clippy::box_vec)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
- --> $DIR/rename.rs:39:9
+ --> $DIR/rename.rs:42:9
|
LL | #![warn(clippy::const_static_lifetime)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
- --> $DIR/rename.rs:40:9
+ --> $DIR/rename.rs:43:9
|
LL | #![warn(clippy::cyclomatic_complexity)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
- --> $DIR/rename.rs:41:9
+ --> $DIR/rename.rs:44:9
|
LL | #![warn(clippy::disallowed_method)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
- --> $DIR/rename.rs:42:9
+ --> $DIR/rename.rs:45:9
|
LL | #![warn(clippy::disallowed_type)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
- --> $DIR/rename.rs:43:9
+ --> $DIR/rename.rs:46:9
|
LL | #![warn(clippy::eval_order_dependence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles`
- --> $DIR/rename.rs:44:9
+ --> $DIR/rename.rs:47:9
|
LL | #![warn(clippy::for_loop_over_option)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles`
- --> $DIR/rename.rs:45:9
+ --> $DIR/rename.rs:48:9
|
LL | #![warn(clippy::for_loop_over_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
- --> $DIR/rename.rs:46:9
+ --> $DIR/rename.rs:49:9
|
LL | #![warn(clippy::identity_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
- --> $DIR/rename.rs:47:9
+ --> $DIR/rename.rs:50:9
|
LL | #![warn(clippy::if_let_some_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
+error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
+ --> $DIR/rename.rs:51:9
+ |
+LL | #![warn(clippy::logic_bug)]
+ | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
+
error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
- --> $DIR/rename.rs:48:9
+ --> $DIR/rename.rs:52:9
|
LL | #![warn(clippy::new_without_default_derive)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
- --> $DIR/rename.rs:49:9
+ --> $DIR/rename.rs:53:9
|
LL | #![warn(clippy::option_and_then_some)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
- --> $DIR/rename.rs:50:9
+ --> $DIR/rename.rs:54:9
|
LL | #![warn(clippy::option_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
- --> $DIR/rename.rs:51:9
+ --> $DIR/rename.rs:55:9
|
LL | #![warn(clippy::option_map_unwrap_or)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
- --> $DIR/rename.rs:52:9
+ --> $DIR/rename.rs:56:9
|
LL | #![warn(clippy::option_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
- --> $DIR/rename.rs:53:9
+ --> $DIR/rename.rs:57:9
|
LL | #![warn(clippy::option_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
- --> $DIR/rename.rs:54:9
+ --> $DIR/rename.rs:58:9
|
LL | #![warn(clippy::ref_in_deref)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
- --> $DIR/rename.rs:55:9
+ --> $DIR/rename.rs:59:9
|
LL | #![warn(clippy::result_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
- --> $DIR/rename.rs:56:9
+ --> $DIR/rename.rs:60:9
|
LL | #![warn(clippy::result_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
- --> $DIR/rename.rs:57:9
+ --> $DIR/rename.rs:61:9
|
LL | #![warn(clippy::result_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
- --> $DIR/rename.rs:58:9
+ --> $DIR/rename.rs:62:9
|
LL | #![warn(clippy::single_char_push_str)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
- --> $DIR/rename.rs:59:9
+ --> $DIR/rename.rs:63:9
|
LL | #![warn(clippy::stutter)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
- --> $DIR/rename.rs:60:9
+ --> $DIR/rename.rs:64:9
|
LL | #![warn(clippy::to_string_in_display)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
- --> $DIR/rename.rs:61:9
+ --> $DIR/rename.rs:65:9
|
LL | #![warn(clippy::zero_width_space)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
- --> $DIR/rename.rs:62:9
+ --> $DIR/rename.rs:66:9
|
LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
- --> $DIR/rename.rs:63:9
+ --> $DIR/rename.rs:67:9
|
LL | #![warn(clippy::into_iter_on_array)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
- --> $DIR/rename.rs:64:9
+ --> $DIR/rename.rs:68:9
|
LL | #![warn(clippy::invalid_atomic_ordering)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
- --> $DIR/rename.rs:65:9
+ --> $DIR/rename.rs:69:9
|
LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
- --> $DIR/rename.rs:66:9
+ --> $DIR/rename.rs:70:9
|
LL | #![warn(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
- --> $DIR/rename.rs:67:9
+ --> $DIR/rename.rs:71:9
|
LL | #![warn(clippy::panic_params)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
- --> $DIR/rename.rs:68:9
+ --> $DIR/rename.rs:72:9
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
- --> $DIR/rename.rs:69:9
+ --> $DIR/rename.rs:73:9
|
LL | #![warn(clippy::unknown_clippy_lints)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
error: lint `clippy::unused_label` has been renamed to `unused_labels`
- --> $DIR/rename.rs:70:9
+ --> $DIR/rename.rs:74:9
|
LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
-error: aborting due to 35 previous errors
+error: aborting due to 37 previous errors
diff --git a/src/tools/clippy/tests/ui/result_large_err.rs b/src/tools/clippy/tests/ui/result_large_err.rs
new file mode 100644
index 000000000..f7df3b856
--- /dev/null
+++ b/src/tools/clippy/tests/ui/result_large_err.rs
@@ -0,0 +1,99 @@
+#![warn(clippy::result_large_err)]
+#![allow(clippy::large_enum_variant)]
+
+pub fn small_err() -> Result<(), u128> {
+ Ok(())
+}
+
+pub fn large_err() -> Result<(), [u8; 512]> {
+ Ok(())
+}
+
+pub struct FullyDefinedLargeError {
+ _foo: u128,
+ _bar: [u8; 100],
+ _foobar: [u8; 120],
+}
+
+impl FullyDefinedLargeError {
+ pub fn ret() -> Result<(), Self> {
+ Ok(())
+ }
+}
+
+pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
+ Ok(())
+}
+
+type Fdlr<T> = std::result::Result<T, FullyDefinedLargeError>;
+pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
+ Ok(x)
+}
+
+pub fn param_small_error<R>() -> Result<(), (R, u128)> {
+ Ok(())
+}
+
+pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
+ Ok(())
+}
+
+pub enum LargeErrorVariants<T> {
+ _Small(u8),
+ _Omg([u8; 512]),
+ _Param(T),
+}
+
+impl LargeErrorVariants<()> {
+ pub fn large_enum_error() -> Result<(), Self> {
+ Ok(())
+ }
+}
+
+trait TraitForcesLargeError {
+ fn large_error() -> Result<(), [u8; 512]> {
+ Ok(())
+ }
+}
+
+struct TraitImpl;
+
+impl TraitForcesLargeError for TraitImpl {
+ // Should not lint
+ fn large_error() -> Result<(), [u8; 512]> {
+ Ok(())
+ }
+}
+
+pub union FullyDefinedUnionError {
+ _maybe: u8,
+ _or_even: [[u8; 16]; 32],
+}
+
+pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
+ Ok(())
+}
+
+pub union UnionError<T: Copy> {
+ _maybe: T,
+ _or_perhaps_even: (T, [u8; 512]),
+}
+
+pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
+ Ok(())
+}
+
+pub struct ArrayError<T, U> {
+ _large_array: [T; 32],
+ _other_stuff: U,
+}
+
+pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
+ Ok(())
+}
+
+pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_large_err.stderr b/src/tools/clippy/tests/ui/result_large_err.stderr
new file mode 100644
index 000000000..ef19f2854
--- /dev/null
+++ b/src/tools/clippy/tests/ui/result_large_err.stderr
@@ -0,0 +1,91 @@
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:8:23
+ |
+LL | pub fn large_err() -> Result<(), [u8; 512]> {
+ | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+ |
+ = note: `-D clippy::result-large-err` implied by `-D warnings`
+ = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:19:21
+ |
+LL | pub fn ret() -> Result<(), Self> {
+ | ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
+ |
+ = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:24:26
+ |
+LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
+ |
+ = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:29:45
+ |
+LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
+ | ^^^^^^^ the `Err`-variant is at least 240 bytes
+ |
+ = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:37:34
+ |
+LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes
+ |
+ = help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:48:34
+ |
+LL | pub fn large_enum_error() -> Result<(), Self> {
+ | ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 513 bytes
+ |
+ = help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box<LargeErrorVariants<()>>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:54:25
+ |
+LL | fn large_error() -> Result<(), [u8; 512]> {
+ | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+ |
+ = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:73:29
+ |
+LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+ |
+ = help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box<FullyDefinedUnionError>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:82:40
+ |
+LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+ |
+ = help: try reducing the size of `UnionError<T>`, for example by boxing large elements or replacing it with `Box<UnionError<T>>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:91:34
+ |
+LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
+ |
+ = help: try reducing the size of `ArrayError<i32, U>`, for example by boxing large elements or replacing it with `Box<ArrayError<i32, U>>`
+
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:95:31
+ |
+LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
+ |
+ = help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box<ArrayError<(i32, T), U>>`
+
+error: aborting due to 11 previous errors
+
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
index 3d2295912..a48829caa 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
@@ -48,9 +48,9 @@ fn ifs_same_cond_fn() {
}
let mut v = vec![1];
- if v.pop() == None {
+ if v.pop().is_none() {
//~ ERROR ifs same condition
- } else if v.pop() == None {
+ } else if v.pop().is_none() {
}
if v.len() == 42 {
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
index 71e82910e..cd438b830 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
@@ -50,14 +50,14 @@ LL | if obj.method_arg(a) {
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:53:15
|
-LL | } else if v.pop() == None {
- | ^^^^^^^^^^^^^^^
+LL | } else if v.pop().is_none() {
+ | ^^^^^^^^^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:51:8
|
-LL | if v.pop() == None {
- | ^^^^^^^^^^^^^^^
+LL | if v.pop().is_none() {
+ | ^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:58:15
diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs
index 99964f0de..af01a8df7 100644
--- a/src/tools/clippy/tests/ui/same_item_push.rs
+++ b/src/tools/clippy/tests/ui/same_item_push.rs
@@ -151,6 +151,7 @@ fn main() {
// Fix #6987
let mut vec = Vec::new();
+ #[allow(clippy::needless_borrow)]
for _ in 0..10 {
vec.push(1);
vec.extend(&[2]);
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
index 91916e748..c4dfbd921 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
@@ -1,7 +1,5 @@
#![warn(clippy::semicolon_if_nothing_returned)]
#![allow(clippy::redundant_closure)]
-#![feature(label_break_value)]
-#![feature(let_else)]
fn get_unit() {}
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
index 41d2c1cfb..8d9a67585 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
@@ -1,5 +1,5 @@
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:10:5
+ --> $DIR/semicolon_if_nothing_returned.rs:8:5
|
LL | println!("Hello")
| ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");`
@@ -7,25 +7,25 @@ LL | println!("Hello")
= note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:14:5
+ --> $DIR/semicolon_if_nothing_returned.rs:12:5
|
LL | get_unit()
| ^^^^^^^^^^ help: add a `;` here: `get_unit();`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:19:5
+ --> $DIR/semicolon_if_nothing_returned.rs:17:5
|
LL | y = x + 1
| ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:25:9
+ --> $DIR/semicolon_if_nothing_returned.rs:23:9
|
LL | hello()
| ^^^^^^^ help: add a `;` here: `hello();`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:36:9
+ --> $DIR/semicolon_if_nothing_returned.rs:34:9
|
LL | ptr::drop_in_place(s.as_mut_ptr())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
diff --git a/src/tools/clippy/tests/ui/skip_while_next.rs b/src/tools/clippy/tests/ui/skip_while_next.rs
index a522c0f08..a551c19d9 100644
--- a/src/tools/clippy/tests/ui/skip_while_next.rs
+++ b/src/tools/clippy/tests/ui/skip_while_next.rs
@@ -1,7 +1,7 @@
// aux-build:option_helpers.rs
#![warn(clippy::skip_while_next)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::disallowed_names)]
extern crate option_helpers;
use option_helpers::IteratorFalsePositives;
diff --git a/src/tools/clippy/tests/ui/string_add.rs b/src/tools/clippy/tests/ui/string_add.rs
index 30fd17c59..16673c01e 100644
--- a/src/tools/clippy/tests/ui/string_add.rs
+++ b/src/tools/clippy/tests/ui/string_add.rs
@@ -7,13 +7,13 @@ extern crate macro_rules;
#[allow(clippy::string_add_assign, unused)]
fn main() {
// ignores assignment distinction
- let mut x = "".to_owned();
+ let mut x = String::new();
for _ in 1..3 {
x = x + ".";
}
- let y = "".to_owned();
+ let y = String::new();
let z = y + "...";
assert_eq!(&x, &z);
diff --git a/src/tools/clippy/tests/ui/string_add_assign.fixed b/src/tools/clippy/tests/ui/string_add_assign.fixed
index db71bab1e..b687f43b2 100644
--- a/src/tools/clippy/tests/ui/string_add_assign.fixed
+++ b/src/tools/clippy/tests/ui/string_add_assign.fixed
@@ -4,13 +4,13 @@
#[warn(clippy::string_add_assign)]
fn main() {
// ignores assignment distinction
- let mut x = "".to_owned();
+ let mut x = String::new();
for _ in 1..3 {
x += ".";
}
- let y = "".to_owned();
+ let y = String::new();
let z = y + "...";
assert_eq!(&x, &z);
diff --git a/src/tools/clippy/tests/ui/string_add_assign.rs b/src/tools/clippy/tests/ui/string_add_assign.rs
index 644991945..e5dbde108 100644
--- a/src/tools/clippy/tests/ui/string_add_assign.rs
+++ b/src/tools/clippy/tests/ui/string_add_assign.rs
@@ -4,13 +4,13 @@
#[warn(clippy::string_add_assign)]
fn main() {
// ignores assignment distinction
- let mut x = "".to_owned();
+ let mut x = String::new();
for _ in 1..3 {
x = x + ".";
}
- let y = "".to_owned();
+ let y = String::new();
let z = y + "...";
assert_eq!(&x, &z);
diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.rs b/src/tools/clippy/tests/ui/suspicious_to_owned.rs
new file mode 100644
index 000000000..cba21bf4a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_to_owned.rs
@@ -0,0 +1,62 @@
+#![warn(clippy::suspicious_to_owned)]
+#![warn(clippy::implicit_clone)]
+#![allow(clippy::redundant_clone)]
+use std::borrow::Cow;
+use std::ffi::{c_char, CStr};
+
+fn main() {
+ let moo = "Moooo";
+ let c_moo = b"Moooo\0";
+ let c_moo_ptr = c_moo.as_ptr() as *const c_char;
+ let moos = ['M', 'o', 'o'];
+ let moos_vec = moos.to_vec();
+
+ // we expect this to be linted
+ let cow = Cow::Borrowed(moo);
+ let _ = cow.to_owned();
+ // we expect no lints for this
+ let cow = Cow::Borrowed(moo);
+ let _ = cow.into_owned();
+ // we expect no lints for this
+ let cow = Cow::Borrowed(moo);
+ let _ = cow.clone();
+
+ // we expect this to be linted
+ let cow = Cow::Borrowed(&moos);
+ let _ = cow.to_owned();
+ // we expect no lints for this
+ let cow = Cow::Borrowed(&moos);
+ let _ = cow.into_owned();
+ // we expect no lints for this
+ let cow = Cow::Borrowed(&moos);
+ let _ = cow.clone();
+
+ // we expect this to be linted
+ let cow = Cow::Borrowed(&moos_vec);
+ let _ = cow.to_owned();
+ // we expect no lints for this
+ let cow = Cow::Borrowed(&moos_vec);
+ let _ = cow.into_owned();
+ // we expect no lints for this
+ let cow = Cow::Borrowed(&moos_vec);
+ let _ = cow.clone();
+
+ // we expect this to be linted
+ let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();
+ let _ = cow.to_owned();
+ // we expect no lints for this
+ let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();
+ let _ = cow.into_owned();
+ // we expect no lints for this
+ let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();
+ let _ = cow.clone();
+
+ // we expect no lints for these
+ let _ = moo.to_owned();
+ let _ = c_moo.to_owned();
+ let _ = moos.to_owned();
+
+ // we expect implicit_clone lints for these
+ let _ = String::from(moo).to_owned();
+ let _ = moos_vec.to_owned();
+}
diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
new file mode 100644
index 000000000..92e1024bf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
@@ -0,0 +1,42 @@
+error: this `to_owned` call clones the std::borrow::Cow<str> itself and does not cause the std::borrow::Cow<str> contents to become owned
+ --> $DIR/suspicious_to_owned.rs:16:13
+ |
+LL | let _ = cow.to_owned();
+ | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()`
+ |
+ = note: `-D clippy::suspicious-to-owned` implied by `-D warnings`
+
+error: this `to_owned` call clones the std::borrow::Cow<[char; 3]> itself and does not cause the std::borrow::Cow<[char; 3]> contents to become owned
+ --> $DIR/suspicious_to_owned.rs:26:13
+ |
+LL | let _ = cow.to_owned();
+ | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()`
+
+error: this `to_owned` call clones the std::borrow::Cow<std::vec::Vec<char>> itself and does not cause the std::borrow::Cow<std::vec::Vec<char>> contents to become owned
+ --> $DIR/suspicious_to_owned.rs:36:13
+ |
+LL | let _ = cow.to_owned();
+ | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()`
+
+error: this `to_owned` call clones the std::borrow::Cow<str> itself and does not cause the std::borrow::Cow<str> contents to become owned
+ --> $DIR/suspicious_to_owned.rs:46:13
+ |
+LL | let _ = cow.to_owned();
+ | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()`
+
+error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
+ --> $DIR/suspicious_to_owned.rs:60:13
+ |
+LL | let _ = String::from(moo).to_owned();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()`
+ |
+ = note: `-D clippy::implicit-clone` implied by `-D warnings`
+
+error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
+ --> $DIR/suspicious_to_owned.rs:61:13
+ |
+LL | let _ = moos_vec.to_owned();
+ | ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed
index 3329efbd4..24b229235 100644
--- a/src/tools/clippy/tests/ui/swap.fixed
+++ b/src/tools/clippy/tests/ui/swap.fixed
@@ -2,7 +2,7 @@
#![warn(clippy::all)]
#![allow(
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::no_effect,
clippy::redundant_clone,
redundant_semicolons,
diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs
index 8179ac1f2..a318c2791 100644
--- a/src/tools/clippy/tests/ui/swap.rs
+++ b/src/tools/clippy/tests/ui/swap.rs
@@ -2,7 +2,7 @@
#![warn(clippy::all)]
#![allow(
- clippy::blacklisted_name,
+ clippy::disallowed_names,
clippy::no_effect,
clippy::redundant_clone,
redundant_semicolons,
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
new file mode 100644
index 000000000..4ce5d4217
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
@@ -0,0 +1,112 @@
+// run-rustfix
+#![deny(clippy::trait_duplication_in_bounds)]
+#![allow(unused)]
+
+fn bad_foo<T: Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
+ unimplemented!();
+}
+
+fn bad_bar<T, U>(arg0: T, arg1: U)
+where
+ T: Clone + Copy,
+ U: Clone + Copy,
+{
+ unimplemented!();
+}
+
+fn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) {
+ unimplemented!();
+}
+
+fn good_foo<T, U>(arg0: T, arg1: U)
+where
+ T: Clone + Copy,
+ U: Clone + Copy,
+{
+ unimplemented!();
+}
+
+trait GoodSelfTraitBound: Clone + Copy {
+ fn f();
+}
+
+trait GoodSelfWhereClause {
+ fn f()
+ where
+ Self: Clone + Copy;
+}
+
+trait BadSelfTraitBound: Clone {
+ fn f();
+}
+
+trait BadSelfWhereClause {
+ fn f()
+ where
+ Self: Clone;
+}
+
+trait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> {
+ fn f();
+}
+
+trait GoodWhereClause<T, U> {
+ fn f()
+ where
+ T: Clone + Copy,
+ U: Clone + Copy;
+}
+
+trait BadTraitBound<T: Clone + Copy, U: Clone + Copy> {
+ fn f();
+}
+
+trait BadWhereClause<T, U> {
+ fn f()
+ where
+ T: Clone + Copy,
+ U: Clone + Copy;
+}
+
+struct GoodStructBound<T: Clone + Copy, U: Clone + Copy> {
+ t: T,
+ u: U,
+}
+
+impl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> {
+ // this should not warn
+ fn f() {}
+}
+
+struct GoodStructWhereClause;
+
+impl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause
+where
+ T: Clone + Copy,
+ U: Clone + Copy,
+{
+ // this should not warn
+ fn f() {}
+}
+
+fn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {}
+
+trait GenericTrait<T> {}
+
+fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {
+ unimplemented!();
+}
+
+fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {
+ unimplemented!();
+}
+
+mod foo {
+ pub trait Clone {}
+}
+
+fn qualified_path<T: std::clone::Clone + foo::Clone>(arg0: T) {
+ unimplemented!();
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index a5751c58a..7f2e96a22 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -1,212 +1,112 @@
+// run-rustfix
#![deny(clippy::trait_duplication_in_bounds)]
#![allow(unused)]
-use std::collections::BTreeMap;
-use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
+ unimplemented!();
+}
-fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
+fn bad_bar<T, U>(arg0: T, arg1: U)
where
- T: Clone,
- T: Default,
+ T: Clone + Clone + Clone + Copy,
+ U: Clone + Copy,
{
unimplemented!();
}
-fn good_bar<T: Clone + Default>(arg: T) {
+fn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) {
unimplemented!();
}
-fn good_foo<T>(arg: T)
+fn good_foo<T, U>(arg0: T, arg1: U)
where
- T: Clone + Default,
+ T: Clone + Copy,
+ U: Clone + Copy,
{
unimplemented!();
}
-fn good_foobar<T: Default>(arg: T)
-where
- T: Clone,
-{
- unimplemented!();
+trait GoodSelfTraitBound: Clone + Copy {
+ fn f();
}
-trait T: Default {
+trait GoodSelfWhereClause {
fn f()
where
- Self: Default;
+ Self: Clone + Copy;
}
-trait U: Default {
+trait BadSelfTraitBound: Clone + Clone + Clone {
+ fn f();
+}
+
+trait BadSelfWhereClause {
fn f()
where
- Self: Clone;
+ Self: Clone + Clone + Clone;
+}
+
+trait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> {
+ fn f();
}
-trait ZZ: Default {
- fn g();
- fn h();
+trait GoodWhereClause<T, U> {
fn f()
where
- Self: Default + Clone;
+ T: Clone + Copy,
+ U: Clone + Copy;
}
-trait BadTrait: Default + Clone {
+trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
+ fn f();
+}
+
+trait BadWhereClause<T, U> {
fn f()
where
- Self: Default + Clone;
- fn g()
- where
- Self: Default;
- fn h()
- where
- Self: Copy;
+ T: Clone + Clone + Clone + Copy,
+ U: Clone + Copy;
}
-#[derive(Default, Clone)]
-struct Life;
+struct GoodStructBound<T: Clone + Copy, U: Clone + Copy> {
+ t: T,
+ u: U,
+}
-impl T for Life {
+impl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> {
// this should not warn
fn f() {}
}
-impl U for Life {
+struct GoodStructWhereClause;
+
+impl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause
+where
+ T: Clone + Copy,
+ U: Clone + Copy,
+{
// this should not warn
fn f() {}
}
-// should not warn
-trait Iter: Iterator {
- fn into_group_btreemap<K, V>(self) -> BTreeMap<K, Vec<V>>
- where
- Self: Iterator<Item = (K, V)> + Sized,
- K: Ord + Eq,
- {
- unimplemented!();
- }
-}
+fn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {}
-struct Foo;
+trait GenericTrait<T> {}
-trait FooIter: Iterator<Item = Foo> {
- fn bar()
- where
- Self: Iterator<Item = Foo>,
- {
- }
+fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {
+ unimplemented!();
}
-// This should not lint
-fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
-
-mod repeated_where_clauses_or_trait_bounds {
- fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
- unimplemented!();
- }
-
- fn bad_bar<T, U>(arg0: T, arg1: U)
- where
- T: Clone + Clone + Clone + Copy,
- U: Clone + Copy,
- {
- unimplemented!();
- }
-
- fn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) {
- unimplemented!();
- }
-
- fn good_foo<T, U>(arg0: T, arg1: U)
- where
- T: Clone + Copy,
- U: Clone + Copy,
- {
- unimplemented!();
- }
-
- trait GoodSelfTraitBound: Clone + Copy {
- fn f();
- }
-
- trait GoodSelfWhereClause {
- fn f()
- where
- Self: Clone + Copy;
- }
-
- trait BadSelfTraitBound: Clone + Clone + Clone {
- fn f();
- }
-
- trait BadSelfWhereClause {
- fn f()
- where
- Self: Clone + Clone + Clone;
- }
-
- trait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> {
- fn f();
- }
-
- trait GoodWhereClause<T, U> {
- fn f()
- where
- T: Clone + Copy,
- U: Clone + Copy;
- }
-
- trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
- fn f();
- }
-
- trait BadWhereClause<T, U> {
- fn f()
- where
- T: Clone + Clone + Clone + Copy,
- U: Clone + Copy;
- }
-
- struct GoodStructBound<T: Clone + Copy, U: Clone + Copy> {
- t: T,
- u: U,
- }
-
- impl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> {
- // this should not warn
- fn f() {}
- }
-
- struct GoodStructWhereClause;
-
- impl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause
- where
- T: Clone + Copy,
- U: Clone + Copy,
- {
- // this should not warn
- fn f() {}
- }
-
- fn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {}
-
- trait GenericTrait<T> {}
-
- // This should not warn but currently does see #8757
- fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {
- unimplemented!();
- }
-
- fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
- unimplemented!();
- }
+fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
+ unimplemented!();
+}
- mod foo {
- pub trait Clone {}
- }
+mod foo {
+ pub trait Clone {}
+}
- fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
- unimplemented!();
- }
+fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
+ unimplemented!();
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
index 7ef04e527..af800ba78 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
@@ -1,167 +1,56 @@
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:7:15
+error: these bounds contain repeated elements
+ --> $DIR/trait_duplication_in_bounds.rs:5:15
|
-LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
- | ^^^^^
+LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
|
note: the lint level is defined here
- --> $DIR/trait_duplication_in_bounds.rs:1:9
+ --> $DIR/trait_duplication_in_bounds.rs:2:9
|
LL | #![deny(clippy::trait_duplication_in_bounds)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:7:23
- |
-LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
- | ^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:36:15
- |
-LL | Self: Default;
- | ^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:50:15
- |
-LL | Self: Default + Clone;
- | ^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:56:15
- |
-LL | Self: Default + Clone;
- | ^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:56:25
- |
-LL | Self: Default + Clone;
- | ^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:59:15
- |
-LL | Self: Default;
- | ^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:94:15
- |
-LL | Self: Iterator<Item = Foo>,
- | ^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:103:19
- |
-LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
- | ^^^^^
- |
- = help: consider removing this trait bound
-
-error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:103:19
- |
-LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:109:12
- |
-LL | T: Clone + Clone + Clone + Copy,
- | ^^^^^
- |
- = help: consider removing this trait bound
error: these where clauses contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:109:12
+ --> $DIR/trait_duplication_in_bounds.rs:11:8
|
-LL | T: Clone + Clone + Clone + Copy,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
+LL | T: Clone + Clone + Clone + Copy,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:137:30
+ --> $DIR/trait_duplication_in_bounds.rs:39:26
|
-LL | trait BadSelfTraitBound: Clone + Clone + Clone {
- | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
+LL | trait BadSelfTraitBound: Clone + Clone + Clone {
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
error: these where clauses contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:144:19
- |
-LL | Self: Clone + Clone + Clone;
- | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:158:28
+ --> $DIR/trait_duplication_in_bounds.rs:46:15
|
-LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
- | ^^^^^
- |
- = help: consider removing this trait bound
+LL | Self: Clone + Clone + Clone;
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:158:28
+ --> $DIR/trait_duplication_in_bounds.rs:60:24
|
-LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
+LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
error: these where clauses contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:165:16
- |
-LL | T: Clone + Clone + Clone + Copy,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:195:24
- |
-LL | fn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider removing this trait bound
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:199:23
+ --> $DIR/trait_duplication_in_bounds.rs:67:12
|
-LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider removing this trait bound
+LL | T: Clone + Clone + Clone + Copy,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:199:23
- |
-LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u32> + GenericTrait<u64>`
-
-error: this trait bound is already specified in the where clause
- --> $DIR/trait_duplication_in_bounds.rs:207:26
- |
-LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
- | ^^^^^^^^^^^^^^^^^
+ --> $DIR/trait_duplication_in_bounds.rs:100:19
|
- = help: consider removing this trait bound
+LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u64> + GenericTrait<u32>`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:207:26
+ --> $DIR/trait_duplication_in_bounds.rs:108:22
|
-LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + foo::Clone`
+LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone`
-error: aborting due to 22 previous errors
+error: aborting due to 8 previous errors
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs
new file mode 100644
index 000000000..5630a0345
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs
@@ -0,0 +1,166 @@
+#![deny(clippy::trait_duplication_in_bounds)]
+
+use std::collections::BTreeMap;
+use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+
+fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
+where
+ T: Clone,
+ T: Default,
+{
+ unimplemented!();
+}
+
+fn good_bar<T: Clone + Default>(arg: T) {
+ unimplemented!();
+}
+
+fn good_foo<T>(arg: T)
+where
+ T: Clone + Default,
+{
+ unimplemented!();
+}
+
+fn good_foobar<T: Default>(arg: T)
+where
+ T: Clone,
+{
+ unimplemented!();
+}
+
+trait T: Default {
+ fn f()
+ where
+ Self: Default;
+}
+
+trait U: Default {
+ fn f()
+ where
+ Self: Clone;
+}
+
+trait ZZ: Default {
+ fn g();
+ fn h();
+ fn f()
+ where
+ Self: Default + Clone;
+}
+
+trait BadTrait: Default + Clone {
+ fn f()
+ where
+ Self: Default + Clone;
+ fn g()
+ where
+ Self: Default;
+ fn h()
+ where
+ Self: Copy;
+}
+
+#[derive(Default, Clone)]
+struct Life;
+
+impl T for Life {
+ // this should not warn
+ fn f() {}
+}
+
+impl U for Life {
+ // this should not warn
+ fn f() {}
+}
+
+// should not warn
+trait Iter: Iterator {
+ fn into_group_btreemap<K, V>(self) -> BTreeMap<K, Vec<V>>
+ where
+ Self: Iterator<Item = (K, V)> + Sized,
+ K: Ord + Eq,
+ {
+ unimplemented!();
+ }
+}
+
+struct Foo;
+
+trait FooIter: Iterator<Item = Foo> {
+ fn bar()
+ where
+ Self: Iterator<Item = Foo>,
+ {
+ }
+}
+
+// The below should not lint and exist to guard against false positives
+fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+
+pub mod one {
+ #[derive(Clone, Debug)]
+ struct MultiProductIter<I>
+ where
+ I: Iterator + Clone,
+ I::Item: Clone,
+ {
+ _marker: I,
+ }
+
+ pub struct MultiProduct<I>(Vec<MultiProductIter<I>>)
+ where
+ I: Iterator + Clone,
+ I::Item: Clone;
+
+ pub fn multi_cartesian_product<H>(_: H) -> MultiProduct<<H::Item as IntoIterator>::IntoIter>
+ where
+ H: Iterator,
+ H::Item: IntoIterator,
+ <H::Item as IntoIterator>::IntoIter: Clone,
+ <H::Item as IntoIterator>::Item: Clone,
+ {
+ todo!()
+ }
+}
+
+pub mod two {
+ use std::iter::Peekable;
+
+ pub struct MergeBy<I, J, F>
+ where
+ I: Iterator,
+ J: Iterator<Item = I::Item>,
+ {
+ _i: Peekable<I>,
+ _j: Peekable<J>,
+ _f: F,
+ }
+
+ impl<I, J, F> Clone for MergeBy<I, J, F>
+ where
+ I: Iterator,
+ J: Iterator<Item = I::Item>,
+ std::iter::Peekable<I>: Clone,
+ std::iter::Peekable<J>: Clone,
+ F: Clone,
+ {
+ fn clone(&self) -> Self {
+ Self {
+ _i: self._i.clone(),
+ _j: self._j.clone(),
+ _f: self._f.clone(),
+ }
+ }
+ }
+}
+
+pub trait Trait {}
+
+pub fn f(_a: impl Trait, _b: impl Trait) {}
+
+pub trait ImplTrait<T> {}
+
+impl<A, B> ImplTrait<(A, B)> for Foo where Foo: ImplTrait<A> + ImplTrait<B> {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
new file mode 100644
index 000000000..fbd9abb00
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
@@ -0,0 +1,71 @@
+error: this trait bound is already specified in the where clause
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:6:15
+ |
+LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:1:9
+ |
+LL | #![deny(clippy::trait_duplication_in_bounds)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in the where clause
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23
+ |
+LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
+ | ^^^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in trait declaration
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:35:15
+ |
+LL | Self: Default;
+ | ^^^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in trait declaration
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:49:15
+ |
+LL | Self: Default + Clone;
+ | ^^^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in trait declaration
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:55:15
+ |
+LL | Self: Default + Clone;
+ | ^^^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in trait declaration
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:55:25
+ |
+LL | Self: Default + Clone;
+ | ^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in trait declaration
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:58:15
+ |
+LL | Self: Default;
+ | ^^^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: this trait bound is already specified in trait declaration
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:93:15
+ |
+LL | Self: Iterator<Item = Foo>,
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider removing this trait bound
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
index ebcaa7a84..5aad0b442 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
@@ -4,6 +4,7 @@
use core::any::TypeId;
use core::ffi::c_void;
use core::mem::{size_of, transmute, MaybeUninit};
+use core::ptr::NonNull;
fn value<T>() -> T {
unimplemented!()
@@ -109,6 +110,17 @@ fn main() {
let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>()); // Ok
let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>()); // Ok
+
+ let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>()); // Ok
+ let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
+ let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>()); // Ok
+ let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
+
+ let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
+ let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
+
+ let _: NonNull<u8> = transmute(value::<NonNull<(String, String)>>()); // Ok
+ let _: NonNull<(String, String)> = transmute(value::<NonNull<u8>>()); // Ok
}
}
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
index 28bfba6c7..e50a77329 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
@@ -1,5 +1,5 @@
error: transmute from `Ty2<u32, i32>` which has an undefined layout
- --> $DIR/transmute_undefined_repr.rs:27:33
+ --> $DIR/transmute_undefined_repr.rs:28:33
|
LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,13 +7,13 @@ LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lin
= note: `-D clippy::transmute-undefined-repr` implied by `-D warnings`
error: transmute into `Ty2<u32, i32>` which has an undefined layout
- --> $DIR/transmute_undefined_repr.rs:28:32
+ --> $DIR/transmute_undefined_repr.rs:29:32
|
LL | let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:33:32
+ --> $DIR/transmute_undefined_repr.rs:34:32
|
LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -21,7 +21,7 @@ LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); //
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:34:36
+ --> $DIR/transmute_undefined_repr.rs:35:36
|
LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +29,7 @@ LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); //
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:39:33
+ --> $DIR/transmute_undefined_repr.rs:40:33
|
LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); /
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:40:37
+ --> $DIR/transmute_undefined_repr.rs:41:37
|
LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); /
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:57:45
+ --> $DIR/transmute_undefined_repr.rs:58:45
|
LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -53,15 +53,31 @@ LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32,
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:58:37
+ --> $DIR/transmute_undefined_repr.rs:59:37
|
LL | let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
+error: transmute into `*const Ty2<u32, u32>` which has an undefined layout
+ --> $DIR/transmute_undefined_repr.rs:119:39
+ |
+LL | let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the contained type `Ty2<u32, u32>` has an undefined layout
+
+error: transmute from `*const Ty2<u32, u32>` which has an undefined layout
+ --> $DIR/transmute_undefined_repr.rs:120:50
+ |
+LL | let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the contained type `Ty2<u32, u32>` has an undefined layout
+
error: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:138:35
+ --> $DIR/transmute_undefined_repr.rs:150:35
|
LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); // Err
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,12 +85,12 @@ LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); /
= note: two instances of the same generic type (`Vec`) may have different layouts
error: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:139:35
+ --> $DIR/transmute_undefined_repr.rs:151:35
|
LL | let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>()); // Err
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Vec`) may have different layouts
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
index 8f78f16a0..c0c64ebca 100644
--- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
+++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
@@ -2,7 +2,7 @@
// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)"
#![deny(clippy::trivially_copy_pass_by_ref)]
-#![allow(clippy::blacklisted_name, clippy::redundant_field_names)]
+#![allow(clippy::disallowed_names, clippy::redundant_field_names)]
#[derive(Copy, Clone)]
struct Foo(u32);
diff --git a/src/tools/clippy/tests/ui/unicode.fixed b/src/tools/clippy/tests/ui/unicode.fixed
index 328cda369..94b472345 100644
--- a/src/tools/clippy/tests/ui/unicode.fixed
+++ b/src/tools/clippy/tests/ui/unicode.fixed
@@ -1,4 +1,7 @@
// run-rustfix
+// compile-flags: --test
+#![allow(dead_code)]
+
#[warn(clippy::invisible_characters)]
fn zero() {
print!("Here >\u{200B}< is a ZWS, and \u{200B}another");
@@ -15,22 +18,43 @@ fn canon() {
print!("a\u{0300}h?"); // also ok
}
-#[warn(clippy::non_ascii_literal)]
-fn uni() {
- print!("\u{dc}ben!");
- print!("\u{DC}ben!"); // this is ok
-}
+mod non_ascii_literal {
+ #![deny(clippy::non_ascii_literal)]
+
+ fn uni() {
+ print!("\u{dc}ben!");
+ print!("\u{DC}ben!"); // this is ok
+ }
+
+ // issue 8013
+ fn single_quote() {
+ const _EMPTY_BLOCK: char = '\u{25b1}';
+ const _FULL_BLOCK: char = '\u{25b0}';
+ }
+
+ #[test]
+ pub fn issue_7739() {
+ // Ryū crate: https://github.com/dtolnay/ryu
+ }
+
+ mod issue_8263 {
+ #![deny(clippy::non_ascii_literal)]
+
+ // Re-allow for a single test
+ #[test]
+ #[allow(clippy::non_ascii_literal)]
+ fn allowed() {
+ let _ = "悲ã—ã„ã‹ãªã€ã“ã“ã«æ—¥æœ¬èªžã‚’書ãã“ã¨ã¯ã§ããªã„。";
+ }
-// issue 8013
-#[warn(clippy::non_ascii_literal)]
-fn single_quote() {
- const _EMPTY_BLOCK: char = '\u{25b1}';
- const _FULL_BLOCK: char = '\u{25b0}';
+ #[test]
+ fn denied() {
+ let _ = "\u{60b2}\u{3057}\u{3044}\u{304b}\u{306a}\u{3001}\u{3053}\u{3053}\u{306b}\u{65e5}\u{672c}\u{8a9e}\u{3092}\u{66f8}\u{304f}\u{3053}\u{3068}\u{306f}\u{3067}\u{304d}\u{306a}\u{3044}\u{3002}";
+ }
+ }
}
fn main() {
zero();
- uni();
canon();
- single_quote();
}
diff --git a/src/tools/clippy/tests/ui/unicode.rs b/src/tools/clippy/tests/ui/unicode.rs
index 7828d6bcb..6ad0b255b 100644
--- a/src/tools/clippy/tests/ui/unicode.rs
+++ b/src/tools/clippy/tests/ui/unicode.rs
@@ -1,4 +1,7 @@
// run-rustfix
+// compile-flags: --test
+#![allow(dead_code)]
+
#[warn(clippy::invisible_characters)]
fn zero() {
print!("Here >​< is a ZWS, and ​another");
@@ -15,22 +18,43 @@ fn canon() {
print!("a\u{0300}h?"); // also ok
}
-#[warn(clippy::non_ascii_literal)]
-fn uni() {
- print!("Ãœben!");
- print!("\u{DC}ben!"); // this is ok
-}
+mod non_ascii_literal {
+ #![deny(clippy::non_ascii_literal)]
+
+ fn uni() {
+ print!("Ãœben!");
+ print!("\u{DC}ben!"); // this is ok
+ }
+
+ // issue 8013
+ fn single_quote() {
+ const _EMPTY_BLOCK: char = 'â–±';
+ const _FULL_BLOCK: char = 'â–°';
+ }
+
+ #[test]
+ pub fn issue_7739() {
+ // Ryū crate: https://github.com/dtolnay/ryu
+ }
+
+ mod issue_8263 {
+ #![deny(clippy::non_ascii_literal)]
+
+ // Re-allow for a single test
+ #[test]
+ #[allow(clippy::non_ascii_literal)]
+ fn allowed() {
+ let _ = "悲ã—ã„ã‹ãªã€ã“ã“ã«æ—¥æœ¬èªžã‚’書ãã“ã¨ã¯ã§ããªã„。";
+ }
-// issue 8013
-#[warn(clippy::non_ascii_literal)]
-fn single_quote() {
- const _EMPTY_BLOCK: char = 'â–±';
- const _FULL_BLOCK: char = 'â–°';
+ #[test]
+ fn denied() {
+ let _ = "悲ã—ã„ã‹ãªã€ã“ã“ã«æ—¥æœ¬èªžã‚’書ãã“ã¨ã¯ã§ããªã„。";
+ }
+ }
}
fn main() {
zero();
- uni();
canon();
- single_quote();
}
diff --git a/src/tools/clippy/tests/ui/unicode.stderr b/src/tools/clippy/tests/ui/unicode.stderr
index 01d3f3c02..ea74a8145 100644
--- a/src/tools/clippy/tests/ui/unicode.stderr
+++ b/src/tools/clippy/tests/ui/unicode.stderr
@@ -1,5 +1,5 @@
error: invisible character detected
- --> $DIR/unicode.rs:4:12
+ --> $DIR/unicode.rs:7:12
|
LL | print!("Here >​< is a ZWS, and ​another");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"`
@@ -7,19 +7,19 @@ LL | print!("Here >​< is a ZWS, and ​another");
= note: `-D clippy::invisible-characters` implied by `-D warnings`
error: invisible character detected
- --> $DIR/unicode.rs:6:12
+ --> $DIR/unicode.rs:9:12
|
LL | print!("Here >­< is a SHY, and ­another");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"`
error: invisible character detected
- --> $DIR/unicode.rs:8:12
+ --> $DIR/unicode.rs:11:12
|
LL | print!("Here >â < is a WJ, and â another");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"`
error: non-NFC Unicode sequence detected
- --> $DIR/unicode.rs:14:12
+ --> $DIR/unicode.rs:17:12
|
LL | print!("̀àh?");
| ^^^^^ help: consider replacing the string with: `"̀àh?"`
@@ -27,24 +27,40 @@ LL | print!("̀àh?");
= note: `-D clippy::unicode-not-nfc` implied by `-D warnings`
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:20:12
+ --> $DIR/unicode.rs:25:16
|
-LL | print!("Ãœben!");
- | ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"`
+LL | print!("Ãœben!");
+ | ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"`
|
- = note: `-D clippy::non-ascii-literal` implied by `-D warnings`
+note: the lint level is defined here
+ --> $DIR/unicode.rs:22:13
+ |
+LL | #![deny(clippy::non_ascii_literal)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: literal non-ASCII character detected
+ --> $DIR/unicode.rs:31:36
+ |
+LL | const _EMPTY_BLOCK: char = 'â–±';
+ | ^^^ help: consider replacing the string with: `'/u{25b1}'`
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:27:32
+ --> $DIR/unicode.rs:32:35
|
-LL | const _EMPTY_BLOCK: char = 'â–±';
- | ^^^ help: consider replacing the string with: `'/u{25b1}'`
+LL | const _FULL_BLOCK: char = 'â–°';
+ | ^^^ help: consider replacing the string with: `'/u{25b0}'`
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:28:31
+ --> $DIR/unicode.rs:52:21
+ |
+LL | let _ = "悲ã—ã„ã‹ãªã€ã“ã“ã«æ—¥æœ¬èªžã‚’書ãã“ã¨ã¯ã§ããªã„。";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"/u{60b2}/u{3057}/u{3044}/u{304b}/u{306a}/u{3001}/u{3053}/u{3053}/u{306b}/u{65e5}/u{672c}/u{8a9e}/u{3092}/u{66f8}/u{304f}/u{3053}/u{3068}/u{306f}/u{3067}/u{304d}/u{306a}/u{3044}/u{3002}"`
+ |
+note: the lint level is defined here
+ --> $DIR/unicode.rs:41:17
|
-LL | const _FULL_BLOCK: char = 'â–°';
- | ^^^ help: consider replacing the string with: `'/u{25b0}'`
+LL | #![deny(clippy::non_ascii_literal)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
diff --git a/src/tools/clippy/tests/ui/uninit.rs b/src/tools/clippy/tests/ui/uninit.rs
index dac5ce272..211317317 100644
--- a/src/tools/clippy/tests/ui/uninit.rs
+++ b/src/tools/clippy/tests/ui/uninit.rs
@@ -1,5 +1,5 @@
#![feature(stmt_expr_attributes)]
-#![allow(clippy::let_unit_value)]
+#![allow(clippy::let_unit_value, invalid_value)]
use std::mem::{self, MaybeUninit};
diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs
index 38be87bdd..7bf3adc07 100644
--- a/src/tools/clippy/tests/ui/unit_arg.rs
+++ b/src/tools/clippy/tests/ui/unit_arg.rs
@@ -1,3 +1,5 @@
+// aux-build: proc_macro_with_span.rs
+
#![warn(clippy::unit_arg)]
#![allow(
clippy::no_effect,
@@ -8,9 +10,13 @@
clippy::or_fun_call,
clippy::needless_question_mark,
clippy::self_named_constructors,
- clippy::let_unit_value
+ clippy::let_unit_value,
+ clippy::never_loop
)]
+extern crate proc_macro_with_span;
+
+use proc_macro_with_span::with_span;
use std::fmt::Debug;
fn foo<T: Debug>(t: T) {
@@ -127,6 +133,10 @@ fn returning_expr() -> Option<()> {
fn taking_multiple_units(a: (), b: ()) {}
+fn proc_macro() {
+ with_span!(span taking_multiple_units(unsafe { (); }, 'x: loop { break 'x (); }));
+}
+
fn main() {
bad();
ok();
diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr
index 11cfe66a3..1de9d44bb 100644
--- a/src/tools/clippy/tests/ui/unit_arg.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg.stderr
@@ -1,5 +1,5 @@
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:57:5
+ --> $DIR/unit_arg.rs:63:5
|
LL | / foo({
LL | | 1;
@@ -20,7 +20,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:60:5
+ --> $DIR/unit_arg.rs:66:5
|
LL | foo(foo(1));
| ^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:61:5
+ --> $DIR/unit_arg.rs:67:5
|
LL | / foo({
LL | | foo(1);
@@ -54,7 +54,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:66:5
+ --> $DIR/unit_arg.rs:72:5
|
LL | / b.bar({
LL | | 1;
@@ -74,7 +74,7 @@ LL ~ b.bar(());
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:69:5
+ --> $DIR/unit_arg.rs:75:5
|
LL | taking_multiple_units(foo(0), foo(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL ~ taking_multiple_units((), ());
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:70:5
+ --> $DIR/unit_arg.rs:76:5
|
LL | / taking_multiple_units(foo(0), {
LL | | foo(1);
@@ -110,7 +110,7 @@ LL ~ taking_multiple_units((), ());
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:74:5
+ --> $DIR/unit_arg.rs:80:5
|
LL | / taking_multiple_units(
LL | | {
@@ -146,7 +146,7 @@ LL ~ );
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:85:13
+ --> $DIR/unit_arg.rs:91:13
|
LL | None.or(Some(foo(2)));
| ^^^^^^^^^^^^
@@ -160,7 +160,7 @@ LL ~ });
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:88:5
+ --> $DIR/unit_arg.rs:94:5
|
LL | foo(foo(()));
| ^^^^^^^^^^^^
@@ -172,7 +172,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:125:5
+ --> $DIR/unit_arg.rs:131:5
|
LL | Some(foo(1))
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
index b352b285c..ee9f15734 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
@@ -88,4 +88,13 @@ mod fixable {
}
type I32Alias = i32;
+
+ fn issue_9380() {
+ let _: i32 = -1_i32;
+ let _: f32 = -(1) as f32;
+ let _: i64 = -1_i64;
+ let _: i64 = -(1.0) as i64;
+
+ let _ = -(1 + 1) as i64;
+ }
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index 6c8cc3eff..5b7041242 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -88,4 +88,13 @@ mod fixable {
}
type I32Alias = i32;
+
+ fn issue_9380() {
+ let _: i32 = -(1) as i32;
+ let _: f32 = -(1) as f32;
+ let _: i64 = -(1) as i64;
+ let _: i64 = -(1.0) as i64;
+
+ let _ = -(1 + 1) as i64;
+ }
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.stderr b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
index bad45f002..f7829ff3b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
@@ -150,5 +150,17 @@ error: casting float literal to `f32` is unnecessary
LL | let _ = -1.0 as f32;
| ^^^^^^^^^^^ help: try: `-1.0_f32`
-error: aborting due to 25 previous errors
+error: casting integer literal to `i32` is unnecessary
+ --> $DIR/unnecessary_cast.rs:93:22
+ |
+LL | let _: i32 = -(1) as i32;
+ | ^^^^^^^^^^^ help: try: `-1_i32`
+
+error: casting integer literal to `i64` is unnecessary
+ --> $DIR/unnecessary_cast.rs:95:22
+ |
+LL | let _: i64 = -(1) as i64;
+ | ^^^^^^^^^^^ help: try: `-1_i64`
+
+error: aborting due to 27 previous errors
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
index f95f91329..40052c410 100644
--- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
@@ -12,6 +12,7 @@ fn main() {
ref_str_argument("");
// should be linted
+ #[allow(clippy::manual_string_new)]
ref_str_argument("");
// should not be linted
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
index 0cbdc151e..2304dff51 100644
--- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
@@ -12,6 +12,7 @@ fn main() {
ref_str_argument(&String::new());
// should be linted
+ #[allow(clippy::manual_string_new)]
ref_str_argument(&String::from(""));
// should not be linted
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
index 46bc4597b..1eb198a86 100644
--- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
@@ -7,7 +7,7 @@ LL | ref_str_argument(&String::new());
= note: `-D clippy::unnecessary-owned-empty-strings` implied by `-D warnings`
error: usage of `&String::from("")` for a function expecting a `&str` argument
- --> $DIR/unnecessary_owned_empty_strings.rs:15:22
+ --> $DIR/unnecessary_owned_empty_strings.rs:16:22
|
LL | ref_str_argument(&String::from(""));
| ^^^^^^^^^^^^^^^^^ help: try: `""`
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index f4f76cd3d..a920c63b1 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -329,3 +329,91 @@ mod issue_8759_variant {
rw.set_view(&rw.default_view().to_owned());
}
}
+
+mod issue_9317 {
+ #![allow(dead_code)]
+
+ struct Bytes {}
+
+ impl ToString for Bytes {
+ fn to_string(&self) -> String {
+ "123".to_string()
+ }
+ }
+
+ impl AsRef<[u8]> for Bytes {
+ fn as_ref(&self) -> &[u8] {
+ &[1, 2, 3]
+ }
+ }
+
+ fn consume<C: AsRef<[u8]>>(c: C) {
+ let _ = c;
+ }
+
+ pub fn main() {
+ let b = Bytes {};
+ // Should not lint.
+ consume(b.to_string());
+ }
+}
+
+mod issue_9351 {
+ #![allow(dead_code)]
+
+ use std::ops::Deref;
+ use std::path::{Path, PathBuf};
+
+ fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
+ x
+ }
+
+ fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
+
+ fn id<T: AsRef<str>>(x: T) -> T {
+ x
+ }
+
+ fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
+
+ // Should lint
+ fn single_return() -> impl AsRef<str> {
+ id("abc")
+ }
+
+ // Should not lint
+ fn multiple_returns(b: bool) -> impl AsRef<str> {
+ if b {
+ return String::new();
+ }
+
+ id("abc".to_string())
+ }
+
+ struct S1(String);
+
+ // Should not lint
+ fn fields1() -> S1 {
+ S1(id("abc".to_string()))
+ }
+
+ struct S2 {
+ s: String,
+ }
+
+ // Should not lint
+ fn fields2() {
+ let mut s = S2 { s: "abc".into() };
+ s.s = id("abc".to_string());
+ }
+
+ pub fn main() {
+ let path = std::path::Path::new("x");
+ let path_buf = path.to_owned();
+
+ // Should not lint.
+ let _x: PathBuf = require_deref_path(path.to_owned());
+ generic_arg_used_elsewhere(path.to_owned(), path_buf);
+ predicates_are_satisfied(id("abc".to_string()));
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index fe09a489a..2128bdacd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -329,3 +329,91 @@ mod issue_8759_variant {
rw.set_view(&rw.default_view().to_owned());
}
}
+
+mod issue_9317 {
+ #![allow(dead_code)]
+
+ struct Bytes {}
+
+ impl ToString for Bytes {
+ fn to_string(&self) -> String {
+ "123".to_string()
+ }
+ }
+
+ impl AsRef<[u8]> for Bytes {
+ fn as_ref(&self) -> &[u8] {
+ &[1, 2, 3]
+ }
+ }
+
+ fn consume<C: AsRef<[u8]>>(c: C) {
+ let _ = c;
+ }
+
+ pub fn main() {
+ let b = Bytes {};
+ // Should not lint.
+ consume(b.to_string());
+ }
+}
+
+mod issue_9351 {
+ #![allow(dead_code)]
+
+ use std::ops::Deref;
+ use std::path::{Path, PathBuf};
+
+ fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
+ x
+ }
+
+ fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
+
+ fn id<T: AsRef<str>>(x: T) -> T {
+ x
+ }
+
+ fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
+
+ // Should lint
+ fn single_return() -> impl AsRef<str> {
+ id("abc".to_string())
+ }
+
+ // Should not lint
+ fn multiple_returns(b: bool) -> impl AsRef<str> {
+ if b {
+ return String::new();
+ }
+
+ id("abc".to_string())
+ }
+
+ struct S1(String);
+
+ // Should not lint
+ fn fields1() -> S1 {
+ S1(id("abc".to_string()))
+ }
+
+ struct S2 {
+ s: String,
+ }
+
+ // Should not lint
+ fn fields2() {
+ let mut s = S2 { s: "abc".into() };
+ s.s = id("abc".to_string());
+ }
+
+ pub fn main() {
+ let path = std::path::Path::new("x");
+ let path_buf = path.to_owned();
+
+ // Should not lint.
+ let _x: PathBuf = require_deref_path(path.to_owned());
+ generic_arg_used_elsewhere(path.to_owned(), path_buf);
+ predicates_are_satisfied(id("abc".to_string()));
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index 243b4599d..7deb90b06 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -509,5 +509,11 @@ error: unnecessary use of `to_string`
LL | Box::new(build(y.to_string()))
| ^^^^^^^^^^^^^ help: use: `y`
-error: aborting due to 78 previous errors
+error: unnecessary use of `to_string`
+ --> $DIR/unnecessary_to_owned.rs:381:12
+ |
+LL | id("abc".to_string())
+ | ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
+
+error: aborting due to 79 previous errors
diff --git a/src/tools/clippy/tests/ui/unused_peekable.rs b/src/tools/clippy/tests/ui/unused_peekable.rs
new file mode 100644
index 000000000..153457e36
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_peekable.rs
@@ -0,0 +1,144 @@
+#![warn(clippy::unused_peekable)]
+#![allow(clippy::no_effect)]
+
+use std::iter::Empty;
+use std::iter::Peekable;
+
+fn main() {
+ invalid();
+ valid();
+}
+
+#[allow(clippy::unused_unit)]
+fn invalid() {
+ let peekable = std::iter::empty::<u32>().peekable();
+
+ // Only lint `new_local`
+ let old_local = std::iter::empty::<u32>().peekable();
+ let new_local = old_local;
+
+ // Behind mut ref
+ let mut by_mut_ref_test = std::iter::empty::<u32>().peekable();
+ let by_mut_ref = &mut by_mut_ref_test;
+
+ // Explicitly returns `Peekable`
+ fn returns_peekable() -> Peekable<Empty<u32>> {
+ std::iter::empty().peekable()
+ }
+
+ let peekable_from_fn = returns_peekable();
+
+ // Using a method not exclusive to `Peekable`
+ let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable();
+ peekable_using_iterator_method.next();
+
+ // Passed by ref to another function
+ fn takes_ref(_peek: &Peekable<Empty<u32>>) {}
+ let passed_along_ref = std::iter::empty::<u32>().peekable();
+ takes_ref(&passed_along_ref);
+
+ // `by_ref` without `peek`
+ let mut by_ref_test = std::iter::empty::<u32>().peekable();
+ let _by_ref = by_ref_test.by_ref();
+
+ let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable();
+ for x in peekable_in_for_loop {}
+}
+
+fn valid() {
+ fn takes_peekable(_peek: Peekable<Empty<u32>>) {}
+
+ // Passed to another function
+ let passed_along = std::iter::empty::<u32>().peekable();
+ takes_peekable(passed_along);
+
+ // Passed to another method
+ struct PeekableConsumer;
+ impl PeekableConsumer {
+ fn consume(&self, _: Peekable<Empty<u32>>) {}
+ fn consume_mut_ref(&self, _: &mut Peekable<Empty<u32>>) {}
+ }
+
+ let peekable_consumer = PeekableConsumer;
+ let mut passed_along_to_method = std::iter::empty::<u32>().peekable();
+ peekable_consumer.consume_mut_ref(&mut passed_along_to_method);
+ peekable_consumer.consume(passed_along_to_method);
+
+ // `peek` called in another block
+ let mut peekable_in_block = std::iter::empty::<u32>().peekable();
+ {
+ peekable_in_block.peek();
+ }
+
+ // Check the other `Peekable` methods :)
+ {
+ let mut peekable_with_peek_mut = std::iter::empty::<u32>().peekable();
+ peekable_with_peek_mut.peek_mut();
+
+ let mut peekable_with_next_if = std::iter::empty::<u32>().peekable();
+ peekable_with_next_if.next_if(|_| true);
+
+ let mut peekable_with_next_if_eq = std::iter::empty::<u32>().peekable();
+ peekable_with_next_if_eq.next_if_eq(&3);
+ }
+
+ let mut peekable_in_closure = std::iter::empty::<u32>().peekable();
+ let call_peek = |p: &mut Peekable<Empty<u32>>| {
+ p.peek();
+ };
+ call_peek(&mut peekable_in_closure);
+
+ // From a macro
+ macro_rules! make_me_a_peekable_please {
+ () => {
+ std::iter::empty::<u32>().peekable()
+ };
+ }
+
+ let _unsuspecting_macro_user = make_me_a_peekable_please!();
+
+ // Generic Iterator returned
+ fn return_an_iter() -> impl Iterator<Item = u32> {
+ std::iter::empty::<u32>().peekable()
+ }
+
+ let _unsuspecting_user = return_an_iter();
+
+ // Call `peek` in a macro
+ macro_rules! peek_iter {
+ ($iter:ident) => {
+ $iter.peek();
+ };
+ }
+
+ let mut peek_in_macro = std::iter::empty::<u32>().peekable();
+ peek_iter!(peek_in_macro);
+
+ // Behind mut ref
+ let mut by_mut_ref_test = std::iter::empty::<u32>().peekable();
+ let by_mut_ref = &mut by_mut_ref_test;
+ by_mut_ref.peek();
+
+ // Behind ref
+ let mut by_ref_test = std::iter::empty::<u32>().peekable();
+ let by_ref = &by_ref_test;
+ by_ref_test.peek();
+
+ // In struct
+ struct PeekableWrapper {
+ f: Peekable<Empty<u32>>,
+ }
+
+ let struct_test = std::iter::empty::<u32>().peekable();
+ PeekableWrapper { f: struct_test };
+
+ // `by_ref` before `peek`
+ let mut by_ref_test = std::iter::empty::<u32>().peekable();
+ let peeked_val = by_ref_test.by_ref().peek();
+
+ // `peek` called in another block as the last expression
+ let mut peekable_last_expr = std::iter::empty::<u32>().peekable();
+ {
+ peekable_last_expr.peek();
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unused_peekable.stderr b/src/tools/clippy/tests/ui/unused_peekable.stderr
new file mode 100644
index 000000000..d557f5417
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_peekable.stderr
@@ -0,0 +1,67 @@
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:14:9
+ |
+LL | let peekable = std::iter::empty::<u32>().peekable();
+ | ^^^^^^^^
+ |
+ = note: `-D clippy::unused-peekable` implied by `-D warnings`
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:18:9
+ |
+LL | let new_local = old_local;
+ | ^^^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:22:9
+ |
+LL | let by_mut_ref = &mut by_mut_ref_test;
+ | ^^^^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:29:9
+ |
+LL | let peekable_from_fn = returns_peekable();
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:32:13
+ |
+LL | let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:37:9
+ |
+LL | let passed_along_ref = std::iter::empty::<u32>().peekable();
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:42:9
+ |
+LL | let _by_ref = by_ref_test.by_ref();
+ | ^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: `peek` never called on `Peekable` iterator
+ --> $DIR/unused_peekable.rs:44:13
+ |
+LL | let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable();
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider removing the call to `peekable`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unwrap.rs b/src/tools/clippy/tests/ui/unwrap.rs
index a4a3cd1d3..d9fd402e7 100644
--- a/src/tools/clippy/tests/ui/unwrap.rs
+++ b/src/tools/clippy/tests/ui/unwrap.rs
@@ -6,8 +6,9 @@ fn unwrap_option() {
}
fn unwrap_result() {
- let res: Result<u8, ()> = Ok(0);
+ let res: Result<u8, u8> = Ok(0);
let _ = res.unwrap();
+ let _ = res.unwrap_err();
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/unwrap.stderr b/src/tools/clippy/tests/ui/unwrap.stderr
index 4f0858005..784227578 100644
--- a/src/tools/clippy/tests/ui/unwrap.stderr
+++ b/src/tools/clippy/tests/ui/unwrap.stderr
@@ -15,5 +15,13 @@ LL | let _ = res.unwrap();
|
= help: if you don't want to handle the `Err` case gracefully, consider using `expect()` to provide a better panic message
-error: aborting due to 2 previous errors
+error: used `unwrap_err()` on `a Result` value
+ --> $DIR/unwrap.rs:11:13
+ |
+LL | let _ = res.unwrap_err();
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: if you don't want to handle the `Ok` case gracefully, consider using `expect_err()` to provide a better panic message
+
+error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.rs b/src/tools/clippy/tests/ui/unwrap_expect_used.rs
new file mode 100644
index 000000000..9f27fef82
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unwrap_expect_used.rs
@@ -0,0 +1,35 @@
+#![warn(clippy::unwrap_used, clippy::expect_used)]
+
+trait OptionExt {
+ type Item;
+
+ fn unwrap_err(self) -> Self::Item;
+
+ fn expect_err(self, msg: &str) -> Self::Item;
+}
+
+impl<T> OptionExt for Option<T> {
+ type Item = T;
+ fn unwrap_err(self) -> T {
+ panic!();
+ }
+
+ fn expect_err(self, msg: &str) -> T {
+ panic!();
+ }
+}
+
+fn main() {
+ Some(3).unwrap();
+ Some(3).expect("Hello world!");
+
+ // Don't trigger on unwrap_err on an option
+ Some(3).unwrap_err();
+ Some(3).expect_err("Hellow none!");
+
+ let a: Result<i32, i32> = Ok(3);
+ a.unwrap();
+ a.expect("Hello world!");
+ a.unwrap_err();
+ a.expect_err("Hello error!");
+}
diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
new file mode 100644
index 000000000..1a19459b2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
@@ -0,0 +1,52 @@
+error: used `unwrap()` on `an Option` value
+ --> $DIR/unwrap_expect_used.rs:23:5
+ |
+LL | Some(3).unwrap();
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::unwrap-used` implied by `-D warnings`
+ = help: if this value is `None`, it will panic
+
+error: used `expect()` on `an Option` value
+ --> $DIR/unwrap_expect_used.rs:24:5
+ |
+LL | Some(3).expect("Hello world!");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::expect-used` implied by `-D warnings`
+ = help: if this value is `None`, it will panic
+
+error: used `unwrap()` on `a Result` value
+ --> $DIR/unwrap_expect_used.rs:31:5
+ |
+LL | a.unwrap();
+ | ^^^^^^^^^^
+ |
+ = help: if this value is an `Err`, it will panic
+
+error: used `expect()` on `a Result` value
+ --> $DIR/unwrap_expect_used.rs:32:5
+ |
+LL | a.expect("Hello world!");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: if this value is an `Err`, it will panic
+
+error: used `unwrap_err()` on `a Result` value
+ --> $DIR/unwrap_expect_used.rs:33:5
+ |
+LL | a.unwrap_err();
+ | ^^^^^^^^^^^^^^
+ |
+ = help: if this value is an `Ok`, it will panic
+
+error: used `expect_err()` on `a Result` value
+ --> $DIR/unwrap_expect_used.rs:34:5
+ |
+LL | a.expect_err("Hello error!");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: if this value is an `Ok`, it will panic
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed
index c2b9bd2c8..84f779569 100644
--- a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed
+++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed
@@ -69,6 +69,9 @@ fn unwrap_or_else_default() {
let with_default_type: Option<Vec<u64>> = None;
with_default_type.unwrap_or_default();
+
+ let empty_string = None::<String>;
+ empty_string.unwrap_or_default();
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs
index d55664990..1735bd580 100644
--- a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs
+++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs
@@ -69,6 +69,9 @@ fn unwrap_or_else_default() {
let with_default_type: Option<Vec<u64>> = None;
with_default_type.unwrap_or_else(Vec::new);
+
+ let empty_string = None::<String>;
+ empty_string.unwrap_or_else(|| "".to_string());
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr b/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr
index 53e31d85e..d2b921222 100644
--- a/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr
@@ -30,5 +30,11 @@ error: use of `.unwrap_or_else(..)` to construct default value
LL | with_default_type.unwrap_or_else(Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_default_type.unwrap_or_default()`
-error: aborting due to 5 previous errors
+error: use of `.unwrap_or_else(..)` to construct default value
+ --> $DIR/unwrap_or_else_default.rs:74:5
+ |
+LL | empty_string.unwrap_or_else(|| "".to_string());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `empty_string.unwrap_or_default()`
+
+error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs
index d20977d55..322083511 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.rs
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs
@@ -2,7 +2,7 @@
#![feature(rustc_private)]
#![warn(clippy::all)]
-#![allow(clippy::blacklisted_name, clippy::eq_op)]
+#![allow(clippy::disallowed_names, clippy::eq_op)]
#![warn(clippy::used_underscore_binding)]
#[macro_use]
diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.rs b/src/tools/clippy/tests/ui/useless_conversion_try.rs
index 39f54c27b..4acf5b5fa 100644
--- a/src/tools/clippy/tests/ui/useless_conversion_try.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion_try.rs
@@ -29,10 +29,10 @@ fn main() {
let _ = String::try_from("foo".to_string()).unwrap();
let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
let _: String = format!("Hello {}", "world").try_into().unwrap();
- let _: String = "".to_owned().try_into().unwrap();
+ let _: String = String::new().try_into().unwrap();
let _: String = match String::from("_").try_into() {
Ok(a) => a,
- Err(_) => "".into(),
+ Err(_) => String::new(),
};
// FIXME this is a false negative
#[allow(clippy::cmp_owned)]
diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.stderr b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
index b691c13f7..12e74d614 100644
--- a/src/tools/clippy/tests/ui/useless_conversion_try.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
@@ -62,7 +62,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap();
error: useless conversion to the same type: `std::string::String`
--> $DIR/useless_conversion_try.rs:32:21
|
-LL | let _: String = "".to_owned().try_into().unwrap();
+LL | let _: String = String::new().try_into().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider removing `.try_into()`
diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.rs b/src/tools/clippy/tests/ui/vec_resize_to_zero.rs
index 7ed27439e..a8307e741 100644
--- a/src/tools/clippy/tests/ui/vec_resize_to_zero.rs
+++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.rs
@@ -1,15 +1,19 @@
#![warn(clippy::vec_resize_to_zero)]
fn main() {
+ let mut v = vec![1, 2, 3, 4, 5];
+
// applicable here
- vec![1, 2, 3, 4, 5].resize(0, 5);
+ v.resize(0, 5);
// not applicable
- vec![1, 2, 3, 4, 5].resize(2, 5);
+ v.resize(2, 5);
+
+ let mut v = vec!["foo", "bar", "baz"];
// applicable here, but only implemented for integer literals for now
- vec!["foo", "bar", "baz"].resize(0, "bar");
+ v.resize(0, "bar");
// not applicable
- vec!["foo", "bar", "baz"].resize(2, "bar")
+ v.resize(2, "bar")
}
diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
index feb846298..7428cf62d 100644
--- a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
+++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
@@ -1,10 +1,10 @@
error: emptying a vector with `resize`
- --> $DIR/vec_resize_to_zero.rs:5:5
+ --> $DIR/vec_resize_to_zero.rs:7:5
|
-LL | vec![1, 2, 3, 4, 5].resize(0, 5);
- | ^^^^^^^^^^^^^^^^^^^^------------
- | |
- | help: ...or you can empty the vector with: `clear()`
+LL | v.resize(0, 5);
+ | ^^------------
+ | |
+ | help: ...or you can empty the vector with: `clear()`
|
= note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
= help: the arguments may be inverted...
diff --git a/src/tools/clippy/tests/ui/verbose_file_reads.rs b/src/tools/clippy/tests/ui/verbose_file_reads.rs
index e0065e05a..df267e987 100644
--- a/src/tools/clippy/tests/ui/verbose_file_reads.rs
+++ b/src/tools/clippy/tests/ui/verbose_file_reads.rs
@@ -18,7 +18,7 @@ fn main() -> std::io::Result<()> {
s.read_to_end();
s.read_to_string();
// Should catch this
- let mut f = File::open(&path)?;
+ let mut f = File::open(path)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
// ...and this
diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs
index e13efb3e0..95325e060 100644
--- a/src/tools/clippy/tests/workspace.rs
+++ b/src/tools/clippy/tests/workspace.rs
@@ -20,8 +20,8 @@ fn test_no_deps_ignores_path_deps_in_workspaces() {
.current_dir(&cwd)
.env("CARGO_TARGET_DIR", &target_dir)
.arg("clean")
- .args(&["-p", "subcrate"])
- .args(&["-p", "path_dep"])
+ .args(["-p", "subcrate"])
+ .args(["-p", "path_dep"])
.output()
.unwrap();
@@ -32,11 +32,11 @@ fn test_no_deps_ignores_path_deps_in_workspaces() {
.env("CARGO_INCREMENTAL", "0")
.env("CARGO_TARGET_DIR", &target_dir)
.arg("clippy")
- .args(&["-p", "subcrate"])
+ .args(["-p", "subcrate"])
.arg("--no-deps")
.arg("--")
.arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
- .args(&["--cfg", r#"feature="primary_package_test""#])
+ .args(["--cfg", r#"feature="primary_package_test""#])
.output()
.unwrap();
println!("status: {}", output.status);
@@ -52,10 +52,10 @@ fn test_no_deps_ignores_path_deps_in_workspaces() {
.env("CARGO_INCREMENTAL", "0")
.env("CARGO_TARGET_DIR", &target_dir)
.arg("clippy")
- .args(&["-p", "subcrate"])
+ .args(["-p", "subcrate"])
.arg("--")
.arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
- .args(&["--cfg", r#"feature="primary_package_test""#])
+ .args(["--cfg", r#"feature="primary_package_test""#])
.output()
.unwrap();
println!("status: {}", output.status);
@@ -79,7 +79,7 @@ fn test_no_deps_ignores_path_deps_in_workspaces() {
.env("CARGO_INCREMENTAL", "0")
.env("CARGO_TARGET_DIR", &target_dir)
.arg("clippy")
- .args(&["-p", "subcrate"])
+ .args(["-p", "subcrate"])
.arg("--")
.arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
.output()
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 23e495399..41f97e432 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -17,6 +17,7 @@ rustfix = "0.6.0"
lazy_static = "1.0"
walkdir = "2"
glob = "0.3.0"
+lazycell = "1.3.0"
[target.'cfg(unix)'.dependencies]
libc = "0.2"
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index be81ff881..64df76e27 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -3,9 +3,11 @@ pub use self::Mode::*;
use std::ffi::OsString;
use std::fmt;
use std::path::{Path, PathBuf};
+use std::process::Command;
use std::str::FromStr;
use crate::util::PathBufExt;
+use lazycell::LazyCell;
use test::ColorConfig;
#[derive(Clone, Copy, PartialEq, Debug)]
@@ -201,6 +203,9 @@ pub struct Config {
/// The jsondocck executable.
pub jsondocck_path: Option<String>,
+ /// The jsondoclint executable.
+ pub jsondoclint_path: Option<String>,
+
/// The LLVM `FileCheck` binary path.
pub llvm_filecheck: Option<PathBuf>,
@@ -371,6 +376,8 @@ pub struct Config {
/// Whether to rerun tests even if the inputs are unchanged.
pub force_rerun: bool,
+
+ pub target_cfg: LazyCell<TargetCfg>,
}
impl Config {
@@ -380,6 +387,131 @@ impl Config {
!self.target.ends_with("-fuchsia")
})
}
+
+ fn target_cfg(&self) -> &TargetCfg {
+ self.target_cfg.borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target))
+ }
+
+ pub fn matches_arch(&self, arch: &str) -> bool {
+ self.target_cfg().arch == arch ||
+ // Shorthand for convenience. The arch for
+ // asmjs-unknown-emscripten is actually wasm32.
+ (arch == "asmjs" && self.target.starts_with("asmjs")) ||
+ // Matching all the thumb variants as one can be convenient.
+ // (thumbv6m, thumbv7em, thumbv7m, etc.)
+ (arch == "thumb" && self.target.starts_with("thumb"))
+ }
+
+ pub fn matches_os(&self, os: &str) -> bool {
+ self.target_cfg().os == os
+ }
+
+ pub fn matches_env(&self, env: &str) -> bool {
+ self.target_cfg().env == env
+ }
+
+ pub fn matches_abi(&self, abi: &str) -> bool {
+ self.target_cfg().abi == abi
+ }
+
+ pub fn matches_family(&self, family: &str) -> bool {
+ self.target_cfg().families.iter().any(|f| f == family)
+ }
+
+ pub fn is_big_endian(&self) -> bool {
+ self.target_cfg().endian == Endian::Big
+ }
+
+ pub fn get_pointer_width(&self) -> u32 {
+ *&self.target_cfg().pointer_width
+ }
+
+ pub fn has_asm_support(&self) -> bool {
+ static ASM_SUPPORTED_ARCHS: &[&str] = &[
+ "x86", "x86_64", "arm", "aarch64", "riscv32",
+ "riscv64",
+ // These targets require an additional asm_experimental_arch feature.
+ // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32",
+ ];
+ ASM_SUPPORTED_ARCHS.contains(&self.target_cfg().arch.as_str())
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct TargetCfg {
+ arch: String,
+ os: String,
+ env: String,
+ abi: String,
+ families: Vec<String>,
+ pointer_width: u32,
+ endian: Endian,
+}
+
+#[derive(Eq, PartialEq, Clone, Debug)]
+pub enum Endian {
+ Little,
+ Big,
+}
+
+impl TargetCfg {
+ fn new(rustc_path: &Path, target: &str) -> TargetCfg {
+ let output = match Command::new(rustc_path)
+ .arg("--print=cfg")
+ .arg("--target")
+ .arg(target)
+ .output()
+ {
+ Ok(output) => output,
+ Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path),
+ };
+ if !output.status.success() {
+ panic!(
+ "error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}",
+ rustc_path,
+ String::from_utf8(output.stdout).unwrap(),
+ String::from_utf8(output.stderr).unwrap(),
+ );
+ }
+ let print_cfg = String::from_utf8(output.stdout).unwrap();
+ let mut arch = None;
+ let mut os = None;
+ let mut env = None;
+ let mut abi = None;
+ let mut families = Vec::new();
+ let mut pointer_width = None;
+ let mut endian = None;
+ for line in print_cfg.lines() {
+ if let Some((name, value)) = line.split_once('=') {
+ let value = value.trim_matches('"');
+ match name {
+ "target_arch" => arch = Some(value),
+ "target_os" => os = Some(value),
+ "target_env" => env = Some(value),
+ "target_abi" => abi = Some(value),
+ "target_family" => families.push(value.to_string()),
+ "target_pointer_width" => pointer_width = Some(value.parse().unwrap()),
+ "target_endian" => {
+ endian = Some(match value {
+ "little" => Endian::Little,
+ "big" => Endian::Big,
+ s => panic!("unexpected {s}"),
+ })
+ }
+ _ => {}
+ }
+ }
+ }
+ TargetCfg {
+ arch: arch.unwrap().to_string(),
+ os: os.unwrap().to_string(),
+ env: env.unwrap().to_string(),
+ abi: abi.unwrap().to_string(),
+ families,
+ pointer_width: pointer_width.unwrap(),
+ endian: endian.unwrap(),
+ }
+ }
}
#[derive(Debug, Clone)]
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index f8f193ddf..3ff1cbf20 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -661,17 +661,36 @@ impl Config {
let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap();
+ let matches_pointer_width = || {
+ name.strip_suffix("bit")
+ .and_then(|width| width.parse::<u32>().ok())
+ .map(|width| self.get_pointer_width() == width)
+ .unwrap_or(false)
+ };
+
+ // If something is ignored for emscripten, it likely also needs to be
+ // ignored for wasm32-unknown-unknown.
+ // `wasm32-bare` is an alias to refer to just wasm32-unknown-unknown
+ // (in contrast to `wasm32` which also matches non-bare targets like
+ // asmjs-unknown-emscripten).
+ let matches_wasm32_alias = || {
+ self.target == "wasm32-unknown-unknown" && matches!(name, "emscripten" | "wasm32-bare")
+ };
+
let is_match = name == "test" ||
self.target == name || // triple
- util::matches_os(&self.target, name) || // target
- util::matches_env(&self.target, name) || // env
+ self.matches_os(name) ||
+ self.matches_env(name) ||
+ self.matches_abi(name) ||
+ self.matches_family(name) ||
self.target.ends_with(name) || // target and env
- name == util::get_arch(&self.target) || // architecture
- name == util::get_pointer_width(&self.target) || // pointer width
+ self.matches_arch(name) ||
+ matches_wasm32_alias() ||
+ matches_pointer_width() ||
name == self.stage_id.split('-').next().unwrap() || // stage
name == self.channel || // channel
(self.target != self.host && name == "cross-compile") ||
- (name == "endian-big" && util::is_big_endian(&self.target)) ||
+ (name == "endian-big" && self.is_big_endian()) ||
(self.remote_test_client.is_some() && name == "remote") ||
match self.compare_mode {
Some(CompareMode::Polonius) => name == "compare-mode-polonius",
@@ -869,7 +888,7 @@ pub fn make_test_description<R: Read>(
let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
- let has_asm_support = util::has_asm_support(&config.target);
+ let has_asm_support = config.has_asm_support();
let has_asan = util::ASAN_SUPPORTED_TARGETS.contains(&&*config.target);
let has_cfi = util::CFI_SUPPORTED_TARGETS.contains(&&*config.target);
let has_lsan = util::LSAN_SUPPORTED_TARGETS.contains(&&*config.target);
@@ -878,15 +897,27 @@ pub fn make_test_description<R: Read>(
let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
let has_memtag = util::MEMTAG_SUPPORTED_TARGETS.contains(&&*config.target);
let has_shadow_call_stack = util::SHADOWCALLSTACK_SUPPORTED_TARGETS.contains(&&*config.target);
- // for `-Z gcc-ld=lld`
+
+ // For tests using the `needs-rust-lld` directive (e.g. for `-Zgcc-ld=lld`), we need to find
+ // whether `rust-lld` is present in the compiler under test.
+ //
+ // The --compile-lib-path is the path to host shared libraries, but depends on the OS. For
+ // example:
+ // - on linux, it can be <sysroot>/lib
+ // - on windows, it can be <sysroot>/bin
+ //
+ // However, `rust-lld` is only located under the lib path, so we look for it there.
let has_rust_lld = config
.compile_lib_path
+ .parent()
+ .expect("couldn't traverse to the parent of the specified --compile-lib-path")
+ .join("lib")
.join("rustlib")
.join(&config.target)
.join("bin")
- .join("gcc-ld")
- .join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
+ .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" })
.exists();
+
iter_header(path, src, &mut |revision, ln| {
if revision.is_some() && revision != cfg {
return;
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index a8fd4880f..bcd222b5a 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -42,7 +42,6 @@ fn config() -> Config {
"--suite=ui",
"--compile-lib-path=",
"--run-lib-path=",
- "--rustc-path=",
"--python=",
"--jsondocck-path=",
"--src-base=",
@@ -57,7 +56,24 @@ fn config() -> Config {
"--target=x86_64-unknown-linux-gnu",
"--channel=nightly",
];
- let args = args.iter().map(ToString::to_string).collect();
+ let mut args: Vec<String> = args.iter().map(ToString::to_string).collect();
+ args.push("--rustc-path".to_string());
+ // This is a subtle/fragile thing. On rust-lang CI, there is no global
+ // `rustc`, and Cargo doesn't offer a convenient way to get the path to
+ // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing
+ // to the stage0 compiler.
+ //
+ // Otherwise, if you are running compiletests's tests manually, you
+ // probably don't have `RUSTC` set, in which case this falls back to the
+ // global rustc. If your global rustc is too far out of sync with stage0,
+ // then this may cause confusing errors. Or if for some reason you don't
+ // have rustc in PATH, that would also fail.
+ args.push(std::env::var("RUSTC").unwrap_or_else(|_| {
+ eprintln!(
+ "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)"
+ );
+ "rustc".to_string()
+ }));
crate::parse_config(args)
}
@@ -237,13 +253,20 @@ fn sanitizers() {
#[test]
fn asm_support() {
- let mut config = config();
-
- config.target = "avr-unknown-gnu-atmega328".to_owned();
- assert!(check_ignore(&config, "// needs-asm-support"));
-
- config.target = "i686-unknown-netbsd".to_owned();
- assert!(!check_ignore(&config, "// needs-asm-support"));
+ let asms = [
+ ("avr-unknown-gnu-atmega328", false),
+ ("i686-unknown-netbsd", true),
+ ("riscv32gc-unknown-linux-gnu", true),
+ ("riscv64imac-unknown-none-elf", true),
+ ("x86_64-unknown-linux-gnu", true),
+ ("i686-unknown-netbsd", true),
+ ];
+ for (target, has_asm) in asms {
+ let mut config = config();
+ config.target = target.to_string();
+ assert_eq!(config.has_asm_support(), has_asm);
+ assert_eq!(check_ignore(&config, "// needs-asm-support"), !has_asm)
+ }
}
#[test]
@@ -281,3 +304,155 @@ fn test_duplicate_revisions() {
let config = config();
parse_rs(&config, "// revisions: rpass1 rpass1");
}
+
+#[test]
+fn ignore_arch() {
+ let archs = [
+ ("x86_64-unknown-linux-gnu", "x86_64"),
+ ("i686-unknown-linux-gnu", "x86"),
+ ("nvptx64-nvidia-cuda", "nvptx64"),
+ ("asmjs-unknown-emscripten", "wasm32"),
+ ("asmjs-unknown-emscripten", "asmjs"),
+ ("thumbv7m-none-eabi", "thumb"),
+ ];
+ for (target, arch) in archs {
+ let mut config = config();
+ config.target = target.to_string();
+ assert!(config.matches_arch(arch), "{target} {arch}");
+ assert!(check_ignore(&config, &format!("// ignore-{arch}")));
+ }
+}
+
+#[test]
+fn matches_os() {
+ let oss = [
+ ("x86_64-unknown-linux-gnu", "linux"),
+ ("x86_64-fortanix-unknown-sgx", "unknown"),
+ ("wasm32-unknown-unknown", "unknown"),
+ ("x86_64-unknown-none", "none"),
+ ];
+ for (target, os) in oss {
+ let mut config = config();
+ config.target = target.to_string();
+ assert!(config.matches_os(os), "{target} {os}");
+ assert!(check_ignore(&config, &format!("// ignore-{os}")));
+ }
+}
+
+#[test]
+fn matches_env() {
+ let envs = [
+ ("x86_64-unknown-linux-gnu", "gnu"),
+ ("x86_64-fortanix-unknown-sgx", "sgx"),
+ ("arm-unknown-linux-musleabi", "musl"),
+ ];
+ for (target, env) in envs {
+ let mut config = config();
+ config.target = target.to_string();
+ assert!(config.matches_env(env), "{target} {env}");
+ assert!(check_ignore(&config, &format!("// ignore-{env}")));
+ }
+}
+
+#[test]
+fn matches_abi() {
+ let abis = [
+ ("aarch64-apple-ios-macabi", "macabi"),
+ ("x86_64-unknown-linux-gnux32", "x32"),
+ ("arm-unknown-linux-gnueabi", "eabi"),
+ ];
+ for (target, abi) in abis {
+ let mut config = config();
+ config.target = target.to_string();
+ assert!(config.matches_abi(abi), "{target} {abi}");
+ assert!(check_ignore(&config, &format!("// ignore-{abi}")));
+ }
+}
+
+#[test]
+fn is_big_endian() {
+ let endians = [
+ ("x86_64-unknown-linux-gnu", false),
+ ("bpfeb-unknown-none", true),
+ ("m68k-unknown-linux-gnu", true),
+ ("aarch64_be-unknown-linux-gnu", true),
+ ("powerpc64-unknown-linux-gnu", true),
+ ];
+ for (target, is_big) in endians {
+ let mut config = config();
+ config.target = target.to_string();
+ assert_eq!(config.is_big_endian(), is_big, "{target} {is_big}");
+ assert_eq!(check_ignore(&config, "// ignore-endian-big"), is_big);
+ }
+}
+
+#[test]
+fn pointer_width() {
+ let widths = [
+ ("x86_64-unknown-linux-gnu", 64),
+ ("i686-unknown-linux-gnu", 32),
+ ("arm64_32-apple-watchos", 32),
+ ("msp430-none-elf", 16),
+ ];
+ for (target, width) in widths {
+ let mut config = config();
+ config.target = target.to_string();
+ assert_eq!(config.get_pointer_width(), width, "{target} {width}");
+ assert_eq!(check_ignore(&config, "// ignore-16bit"), width == 16);
+ assert_eq!(check_ignore(&config, "// ignore-32bit"), width == 32);
+ assert_eq!(check_ignore(&config, "// ignore-64bit"), width == 64);
+ }
+}
+
+#[test]
+fn wasm_special() {
+ let ignores = [
+ ("wasm32-unknown-unknown", "emscripten", true),
+ ("wasm32-unknown-unknown", "wasm32", true),
+ ("wasm32-unknown-unknown", "wasm32-bare", true),
+ ("wasm32-unknown-unknown", "wasm64", false),
+ ("asmjs-unknown-emscripten", "emscripten", true),
+ ("asmjs-unknown-emscripten", "wasm32", true),
+ ("asmjs-unknown-emscripten", "wasm32-bare", false),
+ ("wasm32-unknown-emscripten", "emscripten", true),
+ ("wasm32-unknown-emscripten", "wasm32", true),
+ ("wasm32-unknown-emscripten", "wasm32-bare", false),
+ ("wasm32-wasi", "emscripten", false),
+ ("wasm32-wasi", "wasm32", true),
+ ("wasm32-wasi", "wasm32-bare", false),
+ ("wasm32-wasi", "wasi", true),
+ ("wasm64-unknown-unknown", "emscripten", false),
+ ("wasm64-unknown-unknown", "wasm32", false),
+ ("wasm64-unknown-unknown", "wasm32-bare", false),
+ ("wasm64-unknown-unknown", "wasm64", true),
+ ];
+ for (target, pattern, ignore) in ignores {
+ let mut config = config();
+ config.target = target.to_string();
+ assert_eq!(
+ check_ignore(&config, &format!("// ignore-{pattern}")),
+ ignore,
+ "{target} {pattern}"
+ );
+ }
+}
+
+#[test]
+fn families() {
+ let families = [
+ ("x86_64-unknown-linux-gnu", "unix"),
+ ("x86_64-pc-windows-gnu", "windows"),
+ ("wasm32-unknown-unknown", "wasm"),
+ ("wasm32-unknown-emscripten", "wasm"),
+ ("wasm32-unknown-emscripten", "unix"),
+ ];
+ for (target, family) in families {
+ let mut config = config();
+ config.target = target.to_string();
+ assert!(config.matches_family(family));
+ let other = if family == "windows" { "unix" } else { "windows" };
+ assert!(!config.matches_family(other));
+ assert!(check_ignore(&config, &format!("// ignore-{family}")));
+ assert!(!check_ignore(&config, &format!("// ignore-{other}")));
+ }
+}
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index a8a151ca1..38c7b87fc 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -11,6 +11,7 @@ use crate::common::{
use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, TestPaths};
use crate::util::logv;
use getopts::Options;
+use lazycell::LazyCell;
use std::env;
use std::ffi::OsString;
use std::fs;
@@ -63,6 +64,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
.optopt("", "rust-demangler-path", "path to rust-demangler to use in tests", "PATH")
.reqopt("", "python", "path to python to use for doc tests", "PATH")
.optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH")
+ .optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH")
.optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM")
.optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind")
.optopt("", "run-clang-based-tests-with", "path to Clang executable", "PATH")
@@ -225,6 +227,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
rust_demangler_path: matches.opt_str("rust-demangler-path").map(PathBuf::from),
python: matches.opt_str("python").unwrap(),
jsondocck_path: matches.opt_str("jsondocck-path"),
+ jsondoclint_path: matches.opt_str("jsondoclint-path"),
valgrind_path: matches.opt_str("valgrind-path"),
force_valgrind: matches.opt_present("force-valgrind"),
run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"),
@@ -299,6 +302,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
npm: matches.opt_str("npm"),
force_rerun: matches.opt_present("force-rerun"),
+
+ target_cfg: LazyCell::new(),
}
}
@@ -441,7 +446,7 @@ fn configure_cdb(config: &Config) -> Option<Config> {
fn configure_gdb(config: &Config) -> Option<Config> {
config.gdb_version?;
- if util::matches_env(&config.target, "msvc") {
+ if config.matches_env("msvc") {
return None;
}
@@ -542,6 +547,8 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
stamp.add_path(&path);
}
+ stamp.add_dir(&rust_src_dir.join("src/etc/natvis"));
+
stamp.add_dir(&config.run_lib_path);
if let Some(ref rustdoc_path) = config.rustdoc_path {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index d3e5a2dd6..8f289876f 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -13,7 +13,6 @@ use crate::errors::{self, Error, ErrorKind};
use crate::header::TestProps;
use crate::json;
use crate::read2::read2_abbreviated;
-use crate::util::get_pointer_width;
use crate::util::{logv, PathBufExt};
use crate::ColorConfig;
use regex::{Captures, Regex};
@@ -1104,6 +1103,7 @@ impl<'test> TestCx<'test> {
"^(core::([a-z_]+::)+)Ref<.+>$",
"^(core::([a-z_]+::)+)RefMut<.+>$",
"^(core::([a-z_]+::)+)RefCell<.+>$",
+ "^core::num::([a-z_]+::)*NonZero.+$",
];
script_str
@@ -1703,7 +1703,7 @@ impl<'test> TestCx<'test> {
fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
let aux_dir = self.build_all_auxiliary(&mut rustc);
- self.props.unset_rustc_env.clone().iter().fold(&mut rustc, |rustc, v| rustc.env_remove(v));
+ self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
rustc.envs(self.props.rustc_env.clone());
self.compose_and_run(
rustc,
@@ -2016,11 +2016,14 @@ impl<'test> TestCx<'test> {
Some(CompareMode::Chalk) => {
rustc.args(&["-Zchalk"]);
}
- Some(CompareMode::SplitDwarf) => {
+ Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => {
rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]);
}
+ Some(CompareMode::SplitDwarf) => {
+ rustc.args(&["-Csplit-debuginfo=unpacked"]);
+ }
Some(CompareMode::SplitDwarfSingle) => {
- rustc.args(&["-Csplit-debuginfo=packed", "-Zunstable-options"]);
+ rustc.args(&["-Csplit-debuginfo=packed"]);
}
None => {}
}
@@ -2560,14 +2563,13 @@ impl<'test> TestCx<'test> {
let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
json_out.set_extension("json");
+
let res = self.cmd2procres(
- Command::new(&self.config.python)
- .arg(root.join("src/etc/check_missing_items.py"))
- .arg(&json_out),
+ Command::new(self.config.jsondoclint_path.as_ref().unwrap()).arg(&json_out),
);
if !res.status.success() {
- self.fatal_proc_rec("check_missing_items failed!", &res);
+ self.fatal_proc_rec("jsondoclint failed!", &res);
}
}
@@ -2591,7 +2593,7 @@ impl<'test> TestCx<'test> {
}
None
} else {
- let sline = line.split("///").last().unwrap_or("");
+ let sline = line.rsplit("///").next().unwrap();
let line = sline.trim_start();
if line.starts_with("```") {
if ignore {
@@ -3127,7 +3129,7 @@ impl<'test> TestCx<'test> {
output_kind: TestOutput,
explicit_format: bool,
) -> usize {
- let stderr_bits = format!("{}.stderr", get_pointer_width(&self.config.target));
+ let stderr_bits = format!("{}bit.stderr", self.config.get_pointer_width());
let (stderr_kind, stdout_kind) = match output_kind {
TestOutput::Compile => (
{
@@ -3402,7 +3404,7 @@ impl<'test> TestCx<'test> {
let mut bit_width = String::new();
if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
- bit_width = format!(".{}", get_pointer_width(&self.config.target));
+ bit_width = format!(".{}bit", self.config.get_pointer_width());
}
if self.config.bless {
@@ -3762,7 +3764,7 @@ impl<'test> TestCx<'test> {
fn delete_file(&self, file: &PathBuf) {
if !file.exists() {
- // Deleting a nonexistant file would error.
+ // Deleting a nonexistent file would error.
return;
}
if let Err(e) = fs::remove_file(file) {
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 22df18ee9..9d047b63c 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -8,84 +8,6 @@ use tracing::*;
#[cfg(test)]
mod tests;
-/// Conversion table from triple OS name to Rust SYSNAME
-const OS_TABLE: &[(&str, &str)] = &[
- ("android", "android"),
- ("androideabi", "android"),
- ("cuda", "cuda"),
- ("darwin", "macos"),
- ("dragonfly", "dragonfly"),
- ("emscripten", "emscripten"),
- ("freebsd", "freebsd"),
- ("fuchsia", "fuchsia"),
- ("haiku", "haiku"),
- ("hermit", "hermit"),
- ("illumos", "illumos"),
- ("ios", "ios"),
- ("l4re", "l4re"),
- ("linux", "linux"),
- ("mingw32", "windows"),
- ("none", "none"),
- ("netbsd", "netbsd"),
- ("openbsd", "openbsd"),
- ("redox", "redox"),
- ("sgx", "sgx"),
- ("solaris", "solaris"),
- ("watchos", "watchos"),
- ("win32", "windows"),
- ("windows", "windows"),
- ("vxworks", "vxworks"),
-];
-
-const ARCH_TABLE: &[(&str, &str)] = &[
- ("aarch64", "aarch64"),
- ("aarch64_be", "aarch64"),
- ("amd64", "x86_64"),
- ("arm", "arm"),
- ("arm64", "aarch64"),
- ("armv4t", "arm"),
- ("armv5te", "arm"),
- ("armv7", "arm"),
- ("armv7s", "arm"),
- ("asmjs", "asmjs"),
- ("avr", "avr"),
- ("bpfeb", "bpf"),
- ("bpfel", "bpf"),
- ("hexagon", "hexagon"),
- ("i386", "x86"),
- ("i586", "x86"),
- ("i686", "x86"),
- ("m68k", "m68k"),
- ("mips", "mips"),
- ("mips64", "mips64"),
- ("mips64el", "mips64"),
- ("mipsisa32r6", "mips"),
- ("mipsisa32r6el", "mips"),
- ("mipsisa64r6", "mips64"),
- ("mipsisa64r6el", "mips64"),
- ("mipsel", "mips"),
- ("mipsisa32r6", "mips"),
- ("mipsisa32r6el", "mips"),
- ("mipsisa64r6", "mips64"),
- ("mipsisa64r6el", "mips64"),
- ("msp430", "msp430"),
- ("nvptx64", "nvptx64"),
- ("powerpc", "powerpc"),
- ("powerpc64", "powerpc64"),
- ("powerpc64le", "powerpc64"),
- ("riscv64gc", "riscv64"),
- ("s390x", "s390x"),
- ("sparc", "sparc"),
- ("sparc64", "sparc64"),
- ("sparcv9", "sparc64"),
- ("thumbv6m", "thumb"),
- ("thumbv7em", "thumb"),
- ("thumbv7m", "thumb"),
- ("wasm32", "wasm32"),
- ("x86_64", "x86_64"),
- ("xcore", "xcore"),
-];
-
pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-fuchsia",
@@ -140,80 +62,6 @@ pub const MEMTAG_SUPPORTED_TARGETS: &[&str] =
pub const SHADOWCALLSTACK_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-android"];
-const BIG_ENDIAN: &[&str] = &[
- "aarch64_be",
- "armebv7r",
- "mips",
- "mips64",
- "mipsisa32r6",
- "mipsisa64r6",
- "powerpc",
- "powerpc64",
- "s390x",
- "sparc",
- "sparc64",
- "sparcv9",
-];
-
-static ASM_SUPPORTED_ARCHS: &[&str] = &[
- "x86", "x86_64", "arm", "aarch64", "riscv32",
- "riscv64",
- // These targets require an additional asm_experimental_arch feature.
- // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32",
-];
-
-pub fn has_asm_support(triple: &str) -> bool {
- ASM_SUPPORTED_ARCHS.contains(&get_arch(triple))
-}
-
-pub fn matches_os(triple: &str, name: &str) -> bool {
- // For the wasm32 bare target we ignore anything also ignored on emscripten
- // and then we also recognize `wasm32-bare` as the os for the target
- if triple == "wasm32-unknown-unknown" {
- return name == "emscripten" || name == "wasm32-bare";
- }
- let triple: Vec<_> = triple.split('-').collect();
- for &(triple_os, os) in OS_TABLE {
- if triple.contains(&triple_os) {
- return os == name;
- }
- }
- panic!("Cannot determine OS from triple");
-}
-
-/// Determine the architecture from `triple`
-pub fn get_arch(triple: &str) -> &'static str {
- let triple: Vec<_> = triple.split('-').collect();
- for &(triple_arch, arch) in ARCH_TABLE {
- if triple.contains(&triple_arch) {
- return arch;
- }
- }
- panic!("Cannot determine Architecture from triple");
-}
-
-/// Determine the endianness from `triple`
-pub fn is_big_endian(triple: &str) -> bool {
- let triple_arch = triple.split('-').next().unwrap();
- BIG_ENDIAN.contains(&triple_arch)
-}
-
-pub fn matches_env(triple: &str, name: &str) -> bool {
- if let Some(env) = triple.split('-').nth(3) { env.starts_with(name) } else { false }
-}
-
-pub fn get_pointer_width(triple: &str) -> &'static str {
- if (triple.contains("64") && !triple.ends_with("gnux32") && !triple.ends_with("gnu_ilp32"))
- || triple.starts_with("s390x")
- {
- "64bit"
- } else if triple.starts_with("avr") {
- "16bit"
- } else {
- "32bit"
- }
-}
-
pub fn make_new_path(path: &str) -> String {
assert!(cfg!(windows));
// Windows just uses PATH as the library search path, so we have to
diff --git a/src/tools/compiletest/src/util/tests.rs b/src/tools/compiletest/src/util/tests.rs
index 663027173..b09a183b1 100644
--- a/src/tools/compiletest/src/util/tests.rs
+++ b/src/tools/compiletest/src/util/tests.rs
@@ -1,43 +1,6 @@
use super::*;
#[test]
-#[should_panic(expected = "Cannot determine Architecture from triple")]
-fn test_get_arch_failure() {
- get_arch("abc");
-}
-
-#[test]
-fn test_get_arch() {
- assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu"));
- assert_eq!("x86_64", get_arch("amd64"));
- assert_eq!("nvptx64", get_arch("nvptx64-nvidia-cuda"));
-}
-
-#[test]
-#[should_panic(expected = "Cannot determine OS from triple")]
-fn test_matches_os_failure() {
- matches_os("abc", "abc");
-}
-
-#[test]
-fn test_matches_os() {
- assert!(matches_os("x86_64-unknown-linux-gnu", "linux"));
- assert!(matches_os("wasm32-unknown-unknown", "emscripten"));
- assert!(matches_os("wasm32-unknown-unknown", "wasm32-bare"));
- assert!(!matches_os("wasm32-unknown-unknown", "windows"));
- assert!(matches_os("thumbv6m0-none-eabi", "none"));
- assert!(matches_os("riscv32imc-unknown-none-elf", "none"));
- assert!(matches_os("nvptx64-nvidia-cuda", "cuda"));
- assert!(matches_os("x86_64-fortanix-unknown-sgx", "sgx"));
-}
-
-#[test]
-fn is_big_endian_test() {
- assert!(!is_big_endian("no"));
- assert!(is_big_endian("sparc-unknown-unknown"));
-}
-
-#[test]
fn path_buf_with_extra_extension_test() {
assert_eq!(
PathBuf::from("foo.rs.stderr"),
diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml
index c84b79e11..f4dac6e94 100644
--- a/src/tools/error_index_generator/Cargo.toml
+++ b/src/tools/error_index_generator/Cargo.toml
@@ -4,10 +4,7 @@ version = "0.0.0"
edition = "2021"
[dependencies]
-rustdoc = { path = "../../librustdoc" }
-
-[build-dependencies]
-walkdir = "2"
+mdbook = { version = "0.4", default-features = false, features = ["search"] }
[[bin]]
name = "error_index_generator"
diff --git a/src/tools/error_index_generator/book_config.toml b/src/tools/error_index_generator/book_config.toml
new file mode 100644
index 000000000..885100ae3
--- /dev/null
+++ b/src/tools/error_index_generator/book_config.toml
@@ -0,0 +1,19 @@
+[book]
+title = "Error codes index"
+description = "Book listing all Rust error codes"
+src = ""
+
+[output.html]
+git-repository-url = "https://github.com/rust-lang/rust/"
+additional-css = ["error-index.css"]
+additional-js = ["error-index.js"]
+
+[output.html.search]
+enable = true
+limit-results = 20
+use-boolean-and = true
+boost-title = 2
+boost-hierarchy = 2
+boost-paragraph = 1
+expand = true
+heading-split-level = 0
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
deleted file mode 100644
index 70b00b36c..000000000
--- a/src/tools/error_index_generator/build.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use std::path::PathBuf;
-use std::{env, fs};
-use walkdir::WalkDir;
-
-fn main() {
- // The src directory (we are in src/tools/error_index_generator)
- // Note that we could skip one of the .. but this ensures we at least loosely find the right
- // directory.
- let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
-
- let error_codes_path = "../../../compiler/rustc_error_codes/src/error_codes.rs";
-
- println!("cargo:rerun-if-changed={}", error_codes_path);
- let file = fs::read_to_string(error_codes_path)
- .unwrap()
- .replace(": include_str!(\"./error_codes/", ": include_str!(\"./");
- let contents = format!("(|| {{\n{}\n}})()", file);
- fs::write(&out_dir.join("all_error_codes.rs"), &contents).unwrap();
-
- // We copy the md files as well to the target directory.
- for entry in WalkDir::new("../../../compiler/rustc_error_codes/src/error_codes") {
- let entry = entry.unwrap();
- match entry.path().extension() {
- Some(s) if s == "md" => {}
- _ => continue,
- }
- println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
- let md_content = fs::read_to_string(entry.path()).unwrap();
- fs::write(&out_dir.join(entry.file_name()), &md_content).unwrap();
- }
-}
diff --git a/src/tools/error_index_generator/error-index.css b/src/tools/error_index_generator/error-index.css
new file mode 100644
index 000000000..8975af82d
--- /dev/null
+++ b/src/tools/error_index_generator/error-index.css
@@ -0,0 +1,38 @@
+code.compile_fail {
+ border-left: 2px solid red;
+}
+
+pre .tooltip {
+ position: absolute;
+ left: -25px;
+ top: 0;
+ z-index: 1;
+ color: red;
+ cursor: pointer;
+}
+pre .tooltip::after {
+ display: none;
+ content: "This example deliberately fails to compile";
+ background-color: #000;
+ color: #fff;
+ border-color: #000;
+ text-align: center;
+ padding: 5px 3px 3px 3px;
+ border-radius: 6px;
+ margin-left: 5px;
+}
+pre .tooltip::before {
+ display: none;
+ border-color: transparent black transparent transparent;
+ content: " ";
+ position: absolute;
+ top: 50%;
+ left: 16px;
+ margin-top: -5px;
+ border-width: 5px;
+ border-style: solid;
+}
+
+pre .tooltip:hover::before, pre .tooltip:hover::after {
+ display: inline;
+}
diff --git a/src/tools/error_index_generator/error-index.js b/src/tools/error_index_generator/error-index.js
new file mode 100644
index 000000000..39b371be0
--- /dev/null
+++ b/src/tools/error_index_generator/error-index.js
@@ -0,0 +1,9 @@
+for (const elem of document.querySelectorAll("pre.playground")) {
+ if (elem.querySelector(".compile_fail") === null) {
+ continue;
+ }
+ const child = document.createElement("div");
+ child.className = "tooltip";
+ child.textContent = "ⓘ";
+ elem.appendChild(child);
+}
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 1ce02e48c..1bde8e007 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -1,267 +1,195 @@
#![feature(rustc_private)]
extern crate rustc_driver;
-extern crate rustc_span;
-use std::cell::RefCell;
-use std::collections::BTreeMap;
+// We use the function we generate from `register_diagnostics!`.
+use crate::error_codes::error_codes;
+
use std::env;
use std::error::Error;
-use std::fs::File;
+use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
-use rustc_span::edition::DEFAULT_EDITION;
+use std::str::FromStr;
-use rustdoc::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, Playground};
+use mdbook::book::{parse_summary, BookItem, Chapter};
+use mdbook::{Config, MDBook};
-pub struct ErrorMetadata {
- pub description: Option<String>,
+macro_rules! register_diagnostics {
+ ($($error_code:ident: $message:expr,)+ ; $($undocumented:ident,)* ) => {
+ pub fn error_codes() -> Vec<(&'static str, Option<&'static str>)> {
+ let mut errors: Vec<(&str, Option<&str>)> = vec![
+ $((stringify!($error_code), Some($message)),)+
+ $((stringify!($undocumented), None),)+
+ ];
+ errors.sort();
+ errors
+ }
+ }
}
-/// Mapping from error codes to metadata that can be (de)serialized.
-pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
+#[path = "../../../compiler/rustc_error_codes/src/error_codes.rs"]
+mod error_codes;
enum OutputFormat {
- HTML(HTMLFormatter),
- Markdown(MarkdownFormatter),
+ HTML,
+ Markdown,
Unknown(String),
}
impl OutputFormat {
- fn from(format: &str, resource_suffix: &str) -> OutputFormat {
+ fn from(format: &str) -> OutputFormat {
match &*format.to_lowercase() {
- "html" => OutputFormat::HTML(HTMLFormatter(
- RefCell::new(IdMap::new()),
- resource_suffix.to_owned(),
- )),
- "markdown" => OutputFormat::Markdown(MarkdownFormatter),
+ "html" => OutputFormat::HTML,
+ "markdown" => OutputFormat::Markdown,
s => OutputFormat::Unknown(s.to_owned()),
}
}
}
-trait Formatter {
- fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
- fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
- fn error_code_block(
- &self,
- output: &mut dyn Write,
- info: &ErrorMetadata,
- err_code: &str,
- ) -> Result<(), Box<dyn Error>>;
- fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
-}
-
-struct HTMLFormatter(RefCell<IdMap>, String);
-struct MarkdownFormatter;
+/// Output an HTML page for the errors in `err_map` to `output_path`.
+fn render_markdown(output_path: &Path) -> Result<(), Box<dyn Error>> {
+ let mut output_file = File::create(output_path)?;
-impl Formatter for HTMLFormatter {
- fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
- write!(
- output,
- r##"<!DOCTYPE html>
-<html>
-<head>
-<title>Rust Compiler Error Index</title>
-<meta charset="utf-8">
-<!-- Include rust.css after light.css so its rules take priority. -->
-<link rel="stylesheet" type="text/css" href="rustdoc{suffix}.css"/>
-<link rel="stylesheet" type="text/css" href="light{suffix}.css"/>
-<link rel="stylesheet" type="text/css" href="rust.css"/>
-<style>
-.error-undescribed {{
- display: none;
-}}
-</style>
-</head>
-<body>
-"##,
- suffix = self.1
- )?;
- Ok(())
- }
+ write!(output_file, "# Rust Compiler Error Index\n")?;
- fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
- write!(output, "<h1>Rust Compiler Error Index</h1>\n")?;
- Ok(())
+ for (err_code, description) in error_codes().iter() {
+ match description {
+ Some(ref desc) => write!(output_file, "## {}\n{}\n", err_code, desc)?,
+ None => {}
+ }
}
- fn error_code_block(
- &self,
- output: &mut dyn Write,
- info: &ErrorMetadata,
- err_code: &str,
- ) -> Result<(), Box<dyn Error>> {
- // Enclose each error in a div so they can be shown/hidden en masse.
- let desc_desc = match info.description {
- Some(_) => "error-described",
- None => "error-undescribed",
- };
- write!(output, "<div class=\"{}\">", desc_desc)?;
-
- // Error title (with self-link).
- write!(
- output,
- "<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
- err_code
- )?;
+ Ok(())
+}
- // Description rendered as markdown.
- match info.description {
- Some(ref desc) => {
- let mut id_map = self.0.borrow_mut();
- let playground = Playground {
- crate_name: None,
- url: String::from("https://play.rust-lang.org/"),
- };
- write!(
- output,
- "{}",
- Markdown {
- content: desc,
- links: &[],
- ids: &mut id_map,
- error_codes: ErrorCodes::Yes,
- edition: DEFAULT_EDITION,
- playground: &Some(playground),
- heading_offset: HeadingOffset::H1,
+// By default, mdbook doesn't consider code blocks as Rust ones contrary to rustdoc so we have
+// to manually add `rust` attribute whenever needed.
+fn add_rust_attribute_on_codeblock(explanation: &str) -> String {
+ // Very hacky way to add the rust attribute on all code blocks.
+ let mut skip = true;
+ explanation.split("\n```").fold(String::new(), |mut acc, part| {
+ if !acc.is_empty() {
+ acc.push_str("\n```");
+ }
+ if !skip {
+ if let Some(attrs) = part.split('\n').next() {
+ if !attrs.contains("rust")
+ && (attrs.is_empty()
+ || attrs.contains("compile_fail")
+ || attrs.contains("ignore")
+ || attrs.contains("edition"))
+ {
+ if !attrs.is_empty() {
+ acc.push_str("rust,");
+ } else {
+ acc.push_str("rust");
}
- .into_string()
- )?
+ }
}
- None => write!(output, "<p>No description.</p>\n")?,
}
-
- write!(output, "</div>\n")?;
- Ok(())
- }
-
- fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
- write!(
- output,
- r##"<script>
-function onEach(arr, func) {{
- if (arr && arr.length > 0 && func) {{
- var length = arr.length;
- var i;
- for (i = 0; i < length; ++i) {{
- if (func(arr[i])) {{
- return true;
- }}
- }}
- }}
- return false;
-}}
-
-function onEachLazy(lazyArray, func) {{
- return onEach(
- Array.prototype.slice.call(lazyArray),
- func);
-}}
-
-function hasClass(elem, className) {{
- return elem && elem.classList && elem.classList.contains(className);
-}}
-
-onEachLazy(document.getElementsByClassName('rust-example-rendered'), function(e) {{
- if (hasClass(e, 'compile_fail')) {{
- e.addEventListener("mouseover", function(event) {{
- e.parentElement.previousElementSibling.childNodes[0].style.color = '#f00';
- }});
- e.addEventListener("mouseout", function(event) {{
- e.parentElement.previousElementSibling.childNodes[0].style.color = '';
- }});
- }} else if (hasClass(e, 'ignore')) {{
- e.addEventListener("mouseover", function(event) {{
- e.parentElement.previousElementSibling.childNodes[0].style.color = '#ff9200';
- }});
- e.addEventListener("mouseout", function(event) {{
- e.parentElement.previousElementSibling.childNodes[0].style.color = '';
- }});
- }}
-}});
-</script>
-</body>
-</html>"##
- )?;
- Ok(())
- }
+ skip = !skip;
+ acc.push_str(part);
+ acc
+ })
}
-impl Formatter for MarkdownFormatter {
- #[allow(unused_variables)]
- fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
- Ok(())
- }
-
- fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
- write!(output, "# Rust Compiler Error Index\n")?;
- Ok(())
- }
-
- fn error_code_block(
- &self,
- output: &mut dyn Write,
- info: &ErrorMetadata,
- err_code: &str,
- ) -> Result<(), Box<dyn Error>> {
- Ok(match info.description {
- Some(ref desc) => write!(output, "## {}\n{}\n", err_code, desc)?,
- None => (),
- })
- }
-
- #[allow(unused_variables)]
- fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
- Ok(())
+fn render_html(output_path: &Path) -> Result<(), Box<dyn Error>> {
+ let mut introduction = format!(
+ "<script src='redirect.js'></script>
+# Rust error codes index
+
+This page lists all the error codes emitted by the Rust compiler.
+
+"
+ );
+
+ let err_codes = error_codes();
+ let mut chapters = Vec::with_capacity(err_codes.len());
+
+ for (err_code, explanation) in err_codes.iter() {
+ if let Some(explanation) = explanation {
+ introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code));
+
+ let content = add_rust_attribute_on_codeblock(explanation);
+ chapters.push(BookItem::Chapter(Chapter {
+ name: err_code.to_string(),
+ content: format!("# Error code {}\n\n{}\n", err_code, content),
+ number: None,
+ sub_items: Vec::new(),
+ // We generate it into the `error_codes` folder.
+ path: Some(PathBuf::from(&format!("{}.html", err_code))),
+ source_path: None,
+ parent_names: Vec::new(),
+ }));
+ } else {
+ introduction.push_str(&format!(" * {}\n", err_code));
+ }
}
-}
-
-/// Output an HTML page for the errors in `err_map` to `output_path`.
-fn render_error_page<T: Formatter>(
- err_map: &ErrorMetadataMap,
- output_path: &Path,
- formatter: T,
-) -> Result<(), Box<dyn Error>> {
- let mut output_file = File::create(output_path)?;
-
- formatter.header(&mut output_file)?;
- formatter.title(&mut output_file)?;
- for (err_code, info) in err_map {
- formatter.error_code_block(&mut output_file, info, err_code)?;
- }
+ let mut config = Config::from_str(include_str!("book_config.toml"))?;
+ config.build.build_dir = output_path.join("error_codes").to_path_buf();
+ let mut book = MDBook::load_with_config_and_summary(
+ env!("CARGO_MANIFEST_DIR"),
+ config,
+ parse_summary("")?,
+ )?;
+ let chapter = Chapter {
+ name: "Rust error codes index".to_owned(),
+ content: introduction,
+ number: None,
+ sub_items: chapters,
+ // Very important: this file is named as `error-index.html` and not `index.html`!
+ path: Some(PathBuf::from("error-index.html")),
+ source_path: None,
+ parent_names: Vec::new(),
+ };
+ book.book.sections.push(BookItem::Chapter(chapter));
+ book.build()?;
+
+ // We can't put this content into another file, otherwise `mbdbook` will also put it into the
+ // output directory, making a duplicate.
+ fs::write(
+ output_path.join("error-index.html"),
+ r#"<!DOCTYPE html>
+<html>
+ <head>
+ <title>Rust error codes index - Error codes index</title>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+ <meta name="description" content="Book listing all Rust error codes">
+ <script src="error_codes/redirect.js"></script>
+ </head>
+ <body>
+ <div>If you are not automatically redirected to the error code index, please <a id="index-link" href="./error_codes/error-index.html">here</a>.
+ <script>document.getElementById("index-link").click()</script>
+ </body>
+</html>"#,
+ )?;
+
+ // No need for a 404 file, it's already handled by the server.
+ fs::remove_file(output_path.join("error_codes/404.html"))?;
- formatter.footer(&mut output_file)
+ Ok(())
}
fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
- let long_codes = register_all();
- let mut err_map = BTreeMap::new();
- for (code, desc) in long_codes {
- err_map.insert(code.to_string(), ErrorMetadata { description: desc.map(String::from) });
- }
match format {
OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s),
- OutputFormat::HTML(h) => render_error_page(&err_map, dst, h)?,
- OutputFormat::Markdown(m) => render_error_page(&err_map, dst, m)?,
+ OutputFormat::HTML => render_html(dst),
+ OutputFormat::Markdown => render_markdown(dst),
}
- Ok(())
}
fn parse_args() -> (OutputFormat, PathBuf) {
let mut args = env::args().skip(1);
let format = args.next();
let dst = args.next();
- let resource_suffix = args.next().unwrap_or_else(String::new);
- let format = format
- .map(|a| OutputFormat::from(&a, &resource_suffix))
- .unwrap_or(OutputFormat::from("html", &resource_suffix));
+ let format = format.map(|a| OutputFormat::from(&a)).unwrap_or(OutputFormat::from("html"));
let dst = dst.map(PathBuf::from).unwrap_or_else(|| match format {
- OutputFormat::HTML(..) => PathBuf::from("doc/error-index.html"),
- OutputFormat::Markdown(..) => PathBuf::from("doc/error-index.md"),
+ OutputFormat::HTML => PathBuf::from("doc"),
+ OutputFormat::Markdown => PathBuf::from("doc/error-index.md"),
OutputFormat::Unknown(..) => PathBuf::from("<nul>"),
});
(format, dst)
@@ -270,29 +198,8 @@ fn parse_args() -> (OutputFormat, PathBuf) {
fn main() {
rustc_driver::init_env_logger("RUST_LOG");
let (format, dst) = parse_args();
- let result =
- rustc_span::create_default_session_globals_then(move || main_with_result(format, &dst));
+ let result = main_with_result(format, &dst);
if let Err(e) = result {
- panic!("{}", e.to_string());
- }
-}
-
-fn register_all() -> Vec<(&'static str, Option<&'static str>)> {
- let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();
- macro_rules! register_diagnostics {
- ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
- $(
- {long_codes.extend([
- (stringify!($ecode), Some($message)),
- ].iter());}
- )*
- $(
- {long_codes.extend([
- stringify!($code),
- ].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());}
- )*
- )
+ panic!("{:?}", e);
}
- include!(concat!(env!("OUT_DIR"), "/all_error_codes.rs"));
- long_codes
}
diff --git a/src/tools/error_index_generator/redirect.js b/src/tools/error_index_generator/redirect.js
new file mode 100644
index 000000000..8c907f579
--- /dev/null
+++ b/src/tools/error_index_generator/redirect.js
@@ -0,0 +1,16 @@
+(function() {
+ if (window.location.hash) {
+ let code = window.location.hash.replace(/^#/, '');
+ // We have to make sure this pattern matches to avoid inadvertently creating an
+ // open redirect.
+ if (!/^E[0-9]+$/.test(code)) {
+ return;
+ }
+ if (window.location.pathname.indexOf("/error_codes/") !== -1) {
+ // We're not at the top level, so we don't prepend with "./error_codes/".
+ window.location = './' + code + '.html';
+ } else {
+ window.location = './error_codes/' + code + '.html';
+ }
+ }
+})()
diff --git a/src/tools/jsondocck/src/cache.rs b/src/tools/jsondocck/src/cache.rs
index a188750c5..f9e542327 100644
--- a/src/tools/jsondocck/src/cache.rs
+++ b/src/tools/jsondocck/src/cache.rs
@@ -1,77 +1,31 @@
-use crate::error::CkError;
+use crate::config::Config;
use serde_json::Value;
use std::collections::HashMap;
-use std::io;
-use std::path::{Path, PathBuf};
+use std::path::Path;
use fs_err as fs;
#[derive(Debug)]
pub struct Cache {
- root: PathBuf,
- files: HashMap<PathBuf, String>,
- values: HashMap<PathBuf, Value>,
+ value: Value,
pub variables: HashMap<String, Value>,
- last_path: Option<PathBuf>,
}
impl Cache {
/// Create a new cache, used to read files only once and otherwise store their contents.
- pub fn new(doc_dir: &str) -> Cache {
+ pub fn new(config: &Config) -> Cache {
+ let root = Path::new(&config.doc_dir);
+ let filename = Path::new(&config.template).file_stem().unwrap();
+ let file_path = root.join(&Path::with_extension(Path::new(filename), "json"));
+ let content = fs::read_to_string(&file_path).expect("failed to read JSON file");
+
Cache {
- root: Path::new(doc_dir).to_owned(),
- files: HashMap::new(),
- values: HashMap::new(),
+ value: serde_json::from_str::<Value>(&content).expect("failed to convert from JSON"),
variables: HashMap::new(),
- last_path: None,
}
}
- fn resolve_path(&mut self, path: &String) -> PathBuf {
- if path != "-" {
- let resolve = self.root.join(path);
- self.last_path = Some(resolve.clone());
- resolve
- } else {
- self.last_path
- .as_ref()
- // FIXME: Point to a line number
- .expect("No last path set. Make sure to specify a full path before using `-`")
- .clone()
- }
- }
-
- fn read_file(&mut self, path: PathBuf) -> Result<String, io::Error> {
- if let Some(f) = self.files.get(&path) {
- return Ok(f.clone());
- }
-
- let file = fs::read_to_string(&path)?;
-
- self.files.insert(path, file.clone());
-
- Ok(file)
- }
-
- /// Get the text from a file. If called multiple times, the file will only be read once
- pub fn get_file(&mut self, path: &String) -> Result<String, io::Error> {
- let path = self.resolve_path(path);
- self.read_file(path)
- }
-
- /// Parse the JSON from a file. If called multiple times, the file will only be read once.
- pub fn get_value(&mut self, path: &String) -> Result<Value, CkError> {
- let path = self.resolve_path(path);
-
- if let Some(v) = self.values.get(&path) {
- return Ok(v.clone());
- }
-
- let content = self.read_file(path.clone())?;
- let val = serde_json::from_str::<Value>(&content)?;
-
- self.values.insert(path, val.clone());
-
- Ok(val)
+ pub fn value(&self) -> &Value {
+ &self.value
}
}
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index c44624666..76770fe36 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -17,7 +17,7 @@ fn main() -> Result<(), String> {
let config = parse_config(env::args().collect());
let mut failed = Vec::new();
- let mut cache = Cache::new(&config.doc_dir);
+ let mut cache = Cache::new(&config);
let commands = get_commands(&config.template)
.map_err(|_| format!("Jsondocck failed for {}", &config.template))?;
@@ -50,15 +50,17 @@ pub enum CommandKind {
Has,
Count,
Is,
+ IsMany,
Set,
}
impl CommandKind {
- fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool {
+ fn validate(&self, args: &[String], lineno: usize) -> bool {
let count = match self {
- CommandKind::Has => (1..=3).contains(&args.len()),
- CommandKind::Count | CommandKind::Is => 3 == args.len(),
- CommandKind::Set => 4 == args.len(),
+ CommandKind::Has => (1..=2).contains(&args.len()),
+ CommandKind::IsMany => args.len() >= 2,
+ CommandKind::Count | CommandKind::Is => 2 == args.len(),
+ CommandKind::Set => 3 == args.len(),
};
if !count {
@@ -66,15 +68,10 @@ impl CommandKind {
return false;
}
- if args[0] == "-" && command_num == 0 {
- print_err(&format!("Tried to use the previous path in the first command"), lineno);
- return false;
- }
-
if let CommandKind::Count = self {
- if args[2].parse::<usize>().is_err() {
+ if args[1].parse::<usize>().is_err() {
print_err(
- &format!("Third argument to @count must be a valid usize (got `{}`)", args[2]),
+ &format!("Second argument to @count must be a valid usize (got `{}`)", args[2]),
lineno,
);
return false;
@@ -89,6 +86,7 @@ impl fmt::Display for CommandKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let text = match self {
CommandKind::Has => "has",
+ CommandKind::IsMany => "ismany",
CommandKind::Count => "count",
CommandKind::Is => "is",
CommandKind::Set => "set",
@@ -137,6 +135,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
"has" => CommandKind::Has,
"count" => CommandKind::Count,
"is" => CommandKind::Is,
+ "ismany" => CommandKind::IsMany,
"set" => CommandKind::Set,
_ => {
print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
@@ -177,7 +176,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
}
};
- if !cmd.validate(&args, commands.len(), lineno) {
+ if !cmd.validate(&args, lineno) {
errors = true;
continue;
}
@@ -195,26 +194,24 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
let result = match command.kind {
CommandKind::Has => {
match command.args.len() {
- // @has <path> = file existence
- 1 => cache.get_file(&command.args[0]).is_ok(),
- // @has <path> <jsonpath> = check path exists
- 2 => {
- let val = cache.get_value(&command.args[0])?;
- let results = select(&val, &command.args[1]).unwrap();
+ // @has <jsonpath> = check path exists
+ 1 => {
+ let val = cache.value();
+ let results = select(val, &command.args[0]).unwrap();
!results.is_empty()
}
- // @has <path> <jsonpath> <value> = check *any* item matched by path equals value
- 3 => {
- let val = cache.get_value(&command.args[0])?;
- let results = select(&val, &command.args[1]).unwrap();
- let pat = string_to_value(&command.args[2], cache);
+ // @has <jsonpath> <value> = check *any* item matched by path equals value
+ 2 => {
+ let val = cache.value().clone();
+ let results = select(&val, &command.args[0]).unwrap();
+ let pat = string_to_value(&command.args[1], cache);
let has = results.contains(&pat.as_ref());
// Give better error for when @has check fails
if !command.negated && !has {
return Err(CkError::FailedCheck(
format!(
"{} matched to {:?} but didn't have {:?}",
- &command.args[1],
+ &command.args[0],
results,
pat.as_ref()
),
@@ -227,19 +224,56 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
_ => unreachable!(),
}
}
- CommandKind::Count => {
- // @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
- assert_eq!(command.args.len(), 3);
- let expected: usize = command.args[2].parse().unwrap();
+ CommandKind::IsMany => {
+ // @ismany <path> <jsonpath> <value>...
+ let (query, values) = if let [query, values @ ..] = &command.args[..] {
+ (query, values)
+ } else {
+ unreachable!("Checked in CommandKind::validate")
+ };
+ let val = cache.value();
+ let got_values = select(val, &query).unwrap();
+ assert!(!command.negated, "`@!ismany` is not supported");
- let val = cache.get_value(&command.args[0])?;
- let results = select(&val, &command.args[1]).unwrap();
+ // Serde json doesn't implement Ord or Hash for Value, so we must
+ // use a Vec here. While in theory that makes setwize equality
+ // O(n^2), in practice n will never be large enought to matter.
+ let expected_values =
+ values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>();
+ if expected_values.len() != got_values.len() {
+ return Err(CkError::FailedCheck(
+ format!(
+ "Expected {} values, but `{}` matched to {} values ({:?})",
+ expected_values.len(),
+ query,
+ got_values.len(),
+ got_values
+ ),
+ command,
+ ));
+ };
+ for got_value in got_values {
+ if !expected_values.iter().any(|exp| &**exp == got_value) {
+ return Err(CkError::FailedCheck(
+ format!("`{}` has match {:?}, which was not expected", query, got_value),
+ command,
+ ));
+ }
+ }
+ true
+ }
+ CommandKind::Count => {
+ // @count <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
+ assert_eq!(command.args.len(), 2);
+ let expected: usize = command.args[1].parse().unwrap();
+ let val = cache.value();
+ let results = select(val, &command.args[0]).unwrap();
let eq = results.len() == expected;
if !command.negated && !eq {
return Err(CkError::FailedCheck(
format!(
"`{}` matched to `{:?}` with length {}, but expected length {}",
- &command.args[1],
+ &command.args[0],
results,
results.len(),
expected
@@ -251,17 +285,17 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
}
}
CommandKind::Is => {
- // @has <path> <jsonpath> <value> = check *exactly one* item matched by path, and it equals value
- assert_eq!(command.args.len(), 3);
- let val = cache.get_value(&command.args[0])?;
- let results = select(&val, &command.args[1]).unwrap();
- let pat = string_to_value(&command.args[2], cache);
+ // @has <jsonpath> <value> = check *exactly one* item matched by path, and it equals value
+ assert_eq!(command.args.len(), 2);
+ let val = cache.value().clone();
+ let results = select(&val, &command.args[0]).unwrap();
+ let pat = string_to_value(&command.args[1], cache);
let is = results.len() == 1 && results[0] == pat.as_ref();
if !command.negated && !is {
return Err(CkError::FailedCheck(
format!(
"{} matched to {:?}, but expected {:?}",
- &command.args[1],
+ &command.args[0],
results,
pat.as_ref()
),
@@ -272,16 +306,16 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
}
}
CommandKind::Set => {
- // @set <name> = <path> <jsonpath>
- assert_eq!(command.args.len(), 4);
+ // @set <name> = <jsonpath>
+ assert_eq!(command.args.len(), 3);
assert_eq!(command.args[1], "=", "Expected an `=`");
- let val = cache.get_value(&command.args[2])?;
- let results = select(&val, &command.args[3]).unwrap();
+ let val = cache.value().clone();
+ let results = select(&val, &command.args[2]).unwrap();
assert_eq!(
results.len(),
1,
"Expected 1 match for `{}` (because of @set): matched to {:?}",
- command.args[3],
+ command.args[2],
results
);
match results.len() {
@@ -294,7 +328,7 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
_ => {
panic!(
"Got multiple results in `@set` for `{}`: {:?}",
- &command.args[3], results
+ &command.args[2], results,
);
}
}
diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml
new file mode 100644
index 000000000..84a6c7f96
--- /dev/null
+++ b/src/tools/jsondoclint/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "jsondoclint"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+anyhow = "1.0.62"
+fs-err = "2.8.1"
+rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" }
+serde_json = "1.0.85"
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
new file mode 100644
index 000000000..ad8e96a0b
--- /dev/null
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -0,0 +1,184 @@
+use rustdoc_json_types::{Item, ItemEnum, ItemKind, ItemSummary};
+
+/// A univeral way to represent an [`ItemEnum`] or [`ItemKind`]
+#[derive(Debug)]
+pub(crate) enum Kind {
+ Module,
+ ExternCrate,
+ Import,
+ Struct,
+ StructField,
+ Union,
+ Enum,
+ Variant,
+ Function,
+ Typedef,
+ OpaqueTy,
+ Constant,
+ Trait,
+ TraitAlias,
+ Method,
+ Impl,
+ Static,
+ ForeignType,
+ Macro,
+ ProcAttribute,
+ ProcDerive,
+ AssocConst,
+ AssocType,
+ Primitive,
+ Keyword,
+ // Not in ItemKind
+ ProcMacro,
+}
+
+impl Kind {
+ pub fn can_appear_in_mod(self) -> bool {
+ use Kind::*;
+ match self {
+ Module => true,
+ ExternCrate => true,
+ Import => true,
+ Union => true,
+ Struct => true,
+ Enum => true,
+ Function => true,
+ Trait => true,
+ TraitAlias => true,
+ Impl => true,
+ Typedef => true,
+ Constant => true,
+ Static => true,
+ Macro => true,
+ ProcMacro => true,
+ Primitive => true,
+ ForeignType => true,
+
+ // FIXME(adotinthevoid): I'm not sure if these are corrent
+ Keyword => false,
+ OpaqueTy => false,
+ ProcAttribute => false,
+ ProcDerive => false,
+
+ // Only in traits
+ AssocConst => false,
+ AssocType => false,
+ Method => false,
+
+ StructField => false, // Only in structs or variants
+ Variant => false, // Only in enums
+ }
+ }
+
+ pub fn can_appear_in_trait(self) -> bool {
+ match self {
+ Kind::AssocConst => true,
+ Kind::AssocType => true,
+ Kind::Method => true,
+
+ Kind::Module => false,
+ Kind::ExternCrate => false,
+ Kind::Import => false,
+ Kind::Struct => false,
+ Kind::StructField => false,
+ Kind::Union => false,
+ Kind::Enum => false,
+ Kind::Variant => false,
+ Kind::Function => false,
+ Kind::Typedef => false,
+ Kind::OpaqueTy => false,
+ Kind::Constant => false,
+ Kind::Trait => false,
+ Kind::TraitAlias => false,
+ Kind::Impl => false,
+ Kind::Static => false,
+ Kind::ForeignType => false,
+ Kind::Macro => false,
+ Kind::ProcAttribute => false,
+ Kind::ProcDerive => false,
+ Kind::Primitive => false,
+ Kind::Keyword => false,
+ Kind::ProcMacro => false,
+ }
+ }
+
+ pub fn is_struct_field(self) -> bool {
+ matches!(self, Kind::StructField)
+ }
+ pub fn is_module(self) -> bool {
+ matches!(self, Kind::Module)
+ }
+ pub fn is_impl(self) -> bool {
+ matches!(self, Kind::Impl)
+ }
+ pub fn is_variant(self) -> bool {
+ matches!(self, Kind::Variant)
+ }
+ pub fn is_trait(self) -> bool {
+ matches!(self, Kind::Trait)
+ }
+ pub fn is_struct_enum_union(self) -> bool {
+ matches!(self, Kind::Struct | Kind::Enum | Kind::Union)
+ }
+
+ pub fn from_item(i: &Item) -> Self {
+ use Kind::*;
+ match i.inner {
+ ItemEnum::Module(_) => Module,
+ ItemEnum::Import(_) => Import,
+ ItemEnum::Union(_) => Union,
+ ItemEnum::Struct(_) => Struct,
+ ItemEnum::StructField(_) => StructField,
+ ItemEnum::Enum(_) => Enum,
+ ItemEnum::Variant(_) => Variant,
+ ItemEnum::Function(_) => Function,
+ ItemEnum::Trait(_) => Trait,
+ ItemEnum::TraitAlias(_) => TraitAlias,
+ ItemEnum::Method(_) => Method,
+ ItemEnum::Impl(_) => Impl,
+ ItemEnum::Typedef(_) => Typedef,
+ ItemEnum::OpaqueTy(_) => OpaqueTy,
+ ItemEnum::Constant(_) => Constant,
+ ItemEnum::Static(_) => Static,
+ ItemEnum::Macro(_) => Macro,
+ ItemEnum::ProcMacro(_) => ProcMacro,
+ // https://github.com/rust-lang/rust/issues/100961
+ ItemEnum::PrimitiveType(_) => Primitive,
+ ItemEnum::ForeignType => ForeignType,
+ ItemEnum::ExternCrate { .. } => ExternCrate,
+ ItemEnum::AssocConst { .. } => AssocConst,
+ ItemEnum::AssocType { .. } => AssocType,
+ }
+ }
+
+ pub fn from_summary(s: &ItemSummary) -> Self {
+ use Kind::*;
+ match s.kind {
+ ItemKind::AssocConst => AssocConst,
+ ItemKind::AssocType => AssocType,
+ ItemKind::Constant => Constant,
+ ItemKind::Enum => Enum,
+ ItemKind::ExternCrate => ExternCrate,
+ ItemKind::ForeignType => ForeignType,
+ ItemKind::Function => Function,
+ ItemKind::Impl => Impl,
+ ItemKind::Import => Import,
+ ItemKind::Keyword => Keyword,
+ ItemKind::Macro => Macro,
+ ItemKind::Method => Method,
+ ItemKind::Module => Module,
+ ItemKind::OpaqueTy => OpaqueTy,
+ ItemKind::Primitive => Primitive,
+ ItemKind::ProcAttribute => ProcAttribute,
+ ItemKind::ProcDerive => ProcDerive,
+ ItemKind::Static => Static,
+ ItemKind::Struct => Struct,
+ ItemKind::StructField => StructField,
+ ItemKind::Trait => Trait,
+ ItemKind::TraitAlias => TraitAlias,
+ ItemKind::Typedef => Typedef,
+ ItemKind::Union => Union,
+ ItemKind::Variant => Variant,
+ }
+ }
+}
diff --git a/src/tools/jsondoclint/src/json_find.rs b/src/tools/jsondoclint/src/json_find.rs
new file mode 100644
index 000000000..95ea88666
--- /dev/null
+++ b/src/tools/jsondoclint/src/json_find.rs
@@ -0,0 +1,74 @@
+use std::fmt::Write;
+
+use serde_json::Value;
+
+#[derive(Debug, Clone)]
+pub enum SelectorPart {
+ Field(String),
+ Index(usize),
+}
+
+pub type Selector = Vec<SelectorPart>;
+
+pub fn to_jsonpath(sel: &Selector) -> String {
+ let mut s = String::from("$");
+ for part in sel {
+ match part {
+ SelectorPart::Field(name) => {
+ if is_jsonpath_safe(name) {
+ write!(&mut s, ".{}", name).unwrap();
+ } else {
+ // This is probably wrong in edge cases, but all Id's are
+ // just ascii alphanumerics, `-` `_`, and `:`
+ write!(&mut s, "[{name:?}]").unwrap();
+ }
+ }
+ SelectorPart::Index(idx) => write!(&mut s, "[{idx}]").unwrap(),
+ }
+ }
+ s
+}
+
+fn is_jsonpath_safe(s: &str) -> bool {
+ s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
+}
+
+pub fn find_selector(haystack: &Value, needle: &Value) -> Vec<Selector> {
+ let mut result = Vec::new();
+ let mut sel = Selector::new();
+ find_selector_recursive(haystack, needle, &mut result, &mut sel);
+ result
+}
+
+fn find_selector_recursive(
+ haystack: &Value,
+ needle: &Value,
+ result: &mut Vec<Selector>,
+ pos: &mut Selector,
+) {
+ if needle == haystack {
+ result.push(pos.clone());
+ // Haystack cant both contain needle and be needle
+ } else {
+ match haystack {
+ Value::Null => {}
+ Value::Bool(_) => {}
+ Value::Number(_) => {}
+ Value::String(_) => {}
+ Value::Array(arr) => {
+ for (idx, subhaystack) in arr.iter().enumerate() {
+ pos.push(SelectorPart::Index(idx));
+ find_selector_recursive(subhaystack, needle, result, pos);
+ pos.pop().unwrap();
+ }
+ }
+ Value::Object(obj) => {
+ for (key, subhaystack) in obj {
+ pos.push(SelectorPart::Field(key.clone()));
+ find_selector_recursive(subhaystack, needle, result, pos);
+ pos.pop().unwrap();
+ }
+ }
+ }
+ }
+}
diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs
new file mode 100644
index 000000000..70d7a82a5
--- /dev/null
+++ b/src/tools/jsondoclint/src/main.rs
@@ -0,0 +1,64 @@
+use std::env;
+
+use anyhow::{anyhow, bail, Result};
+use fs_err as fs;
+use rustdoc_json_types::{Crate, Id, FORMAT_VERSION};
+use serde_json::Value;
+
+pub(crate) mod item_kind;
+mod json_find;
+mod validator;
+
+#[derive(Debug)]
+struct Error {
+ kind: ErrorKind,
+ id: Id,
+}
+
+#[derive(Debug)]
+enum ErrorKind {
+ NotFound,
+ Custom(String),
+}
+
+fn main() -> Result<()> {
+ let path = env::args().nth(1).ok_or_else(|| anyhow!("no path given"))?;
+ let contents = fs::read_to_string(&path)?;
+ let krate: Crate = serde_json::from_str(&contents)?;
+ assert_eq!(krate.format_version, FORMAT_VERSION);
+
+ let mut validator = validator::Validator::new(&krate);
+ validator.check_crate();
+
+ if !validator.errs.is_empty() {
+ for err in validator.errs {
+ match err.kind {
+ ErrorKind::NotFound => {
+ let krate_json: Value = serde_json::from_str(&contents)?;
+
+ let sels =
+ json_find::find_selector(&krate_json, &Value::String(err.id.0.clone()));
+ match &sels[..] {
+ [] => unreachable!(
+ "id must be in crate, or it wouldn't be reported as not found"
+ ),
+ [sel] => eprintln!(
+ "{} not in index or paths, but refered to at '{}'",
+ err.id.0,
+ json_find::to_jsonpath(&sel)
+ ),
+ [sel, ..] => eprintln!(
+ "{} not in index or paths, but refered to at '{}' and more",
+ err.id.0,
+ json_find::to_jsonpath(&sel)
+ ),
+ }
+ }
+ ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg),
+ }
+ }
+ bail!("Errors validating json {path}");
+ }
+
+ Ok(())
+}
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
new file mode 100644
index 000000000..a0e77127d
--- /dev/null
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -0,0 +1,442 @@
+use std::collections::HashSet;
+use std::hash::Hash;
+
+use rustdoc_json_types::{
+ Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs,
+ GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, Method, Module, OpaqueTy,
+ Path, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding,
+ TypeBindingKind, Typedef, Union, Variant, WherePredicate,
+};
+
+use crate::{item_kind::Kind, Error, ErrorKind};
+
+/// The Validator walks over the JSON tree, and ensures it is well formed.
+/// It is made of several parts.
+///
+/// - `check_*`: These take a type from [`rustdoc_json_types`], and check that
+/// it is well formed. This involves calling `check_*` functions on
+/// fields of that item, and `add_*` functions on [`Id`]s.
+/// - `add_*`: These add an [`Id`] to the worklist, after validating it to check if
+/// the `Id` is a kind expected in this suituation.
+#[derive(Debug)]
+pub struct Validator<'a> {
+ pub(crate) errs: Vec<Error>,
+ krate: &'a Crate,
+ /// Worklist of Ids to check.
+ todo: HashSet<&'a Id>,
+ /// Ids that have already been visited, so don't need to be checked again.
+ seen_ids: HashSet<&'a Id>,
+ /// Ids that have already been reported missing.
+ missing_ids: HashSet<&'a Id>,
+}
+
+enum PathKind {
+ Trait,
+ StructEnumUnion,
+}
+
+impl<'a> Validator<'a> {
+ pub fn new(krate: &'a Crate) -> Self {
+ Self {
+ krate,
+ errs: Vec::new(),
+ seen_ids: HashSet::new(),
+ todo: HashSet::new(),
+ missing_ids: HashSet::new(),
+ }
+ }
+
+ pub fn check_crate(&mut self) {
+ let root = &self.krate.root;
+ self.add_mod_id(root);
+ while let Some(id) = set_remove(&mut self.todo) {
+ self.seen_ids.insert(id);
+ self.check_item(id);
+ }
+ }
+
+ fn check_item(&mut self, id: &'a Id) {
+ if let Some(item) = &self.krate.index.get(id) {
+ match &item.inner {
+ ItemEnum::Import(x) => self.check_import(x),
+ ItemEnum::Union(x) => self.check_union(x),
+ ItemEnum::Struct(x) => self.check_struct(x),
+ ItemEnum::StructField(x) => self.check_struct_field(x),
+ ItemEnum::Enum(x) => self.check_enum(x),
+ ItemEnum::Variant(x) => self.check_variant(x, id),
+ ItemEnum::Function(x) => self.check_function(x),
+ ItemEnum::Trait(x) => self.check_trait(x),
+ ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
+ ItemEnum::Method(x) => self.check_method(x),
+ ItemEnum::Impl(x) => self.check_impl(x),
+ ItemEnum::Typedef(x) => self.check_typedef(x),
+ ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
+ ItemEnum::Constant(x) => self.check_constant(x),
+ ItemEnum::Static(x) => self.check_static(x),
+ ItemEnum::ForeignType => {} // nop
+ ItemEnum::Macro(x) => self.check_macro(x),
+ ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
+ ItemEnum::PrimitiveType(x) => self.check_primitive_type(x),
+ ItemEnum::Module(x) => self.check_module(x),
+ // FIXME: Why don't these have their own structs?
+ ItemEnum::ExternCrate { .. } => {}
+ ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_),
+ ItemEnum::AssocType { generics, bounds, default } => {
+ self.check_generics(generics);
+ bounds.iter().for_each(|b| self.check_generic_bound(b));
+ if let Some(ty) = default {
+ self.check_type(ty);
+ }
+ }
+ }
+ } else {
+ assert!(self.krate.paths.contains_key(id));
+ }
+ }
+
+ // Core checkers
+ fn check_module(&mut self, module: &'a Module) {
+ module.items.iter().for_each(|i| self.add_mod_item_id(i));
+ }
+
+ fn check_import(&mut self, x: &'a Import) {
+ if x.glob {
+ self.add_mod_id(x.id.as_ref().unwrap());
+ } else if let Some(id) = &x.id {
+ self.add_mod_item_id(id);
+ }
+ }
+
+ fn check_union(&mut self, x: &'a Union) {
+ self.check_generics(&x.generics);
+ x.fields.iter().for_each(|i| self.add_field_id(i));
+ x.impls.iter().for_each(|i| self.add_impl_id(i));
+ }
+
+ fn check_struct(&mut self, x: &'a Struct) {
+ self.check_generics(&x.generics);
+ match &x.kind {
+ StructKind::Unit => {}
+ StructKind::Tuple(fields) => fields.iter().flatten().for_each(|f| self.add_field_id(f)),
+ StructKind::Plain { fields, fields_stripped: _ } => {
+ fields.iter().for_each(|f| self.add_field_id(f))
+ }
+ }
+ x.impls.iter().for_each(|i| self.add_impl_id(i));
+ }
+
+ fn check_struct_field(&mut self, x: &'a Type) {
+ self.check_type(x);
+ }
+
+ fn check_enum(&mut self, x: &'a Enum) {
+ self.check_generics(&x.generics);
+ x.variants.iter().for_each(|i| self.add_variant_id(i));
+ x.impls.iter().for_each(|i| self.add_impl_id(i));
+ }
+
+ fn check_variant(&mut self, x: &'a Variant, id: &'a Id) {
+ match x {
+ Variant::Plain(discr) => {
+ if let Some(discr) = discr {
+ if let (Err(_), Err(_)) =
+ (discr.value.parse::<i128>(), discr.value.parse::<u128>())
+ {
+ self.fail(
+ id,
+ ErrorKind::Custom(format!(
+ "Failed to parse discriminant value `{}`",
+ discr.value
+ )),
+ );
+ }
+ }
+ }
+ Variant::Tuple(tys) => tys.iter().flatten().for_each(|t| self.add_field_id(t)),
+ Variant::Struct { fields, fields_stripped: _ } => {
+ fields.iter().for_each(|f| self.add_field_id(f))
+ }
+ }
+ }
+
+ fn check_function(&mut self, x: &'a Function) {
+ self.check_generics(&x.generics);
+ self.check_fn_decl(&x.decl);
+ }
+
+ fn check_trait(&mut self, x: &'a Trait) {
+ self.check_generics(&x.generics);
+ x.items.iter().for_each(|i| self.add_trait_item_id(i));
+ x.bounds.iter().for_each(|i| self.check_generic_bound(i));
+ x.implementations.iter().for_each(|i| self.add_impl_id(i));
+ }
+
+ fn check_trait_alias(&mut self, x: &'a TraitAlias) {
+ self.check_generics(&x.generics);
+ x.params.iter().for_each(|i| self.check_generic_bound(i));
+ }
+
+ fn check_method(&mut self, x: &'a Method) {
+ self.check_fn_decl(&x.decl);
+ self.check_generics(&x.generics);
+ }
+
+ fn check_impl(&mut self, x: &'a Impl) {
+ self.check_generics(&x.generics);
+ if let Some(path) = &x.trait_ {
+ self.check_path(path, PathKind::Trait);
+ }
+ self.check_type(&x.for_);
+ x.items.iter().for_each(|i| self.add_trait_item_id(i));
+ if let Some(blanket_impl) = &x.blanket_impl {
+ self.check_type(blanket_impl)
+ }
+ }
+
+ fn check_typedef(&mut self, x: &'a Typedef) {
+ self.check_generics(&x.generics);
+ self.check_type(&x.type_);
+ }
+
+ fn check_opaque_ty(&mut self, x: &'a OpaqueTy) {
+ x.bounds.iter().for_each(|b| self.check_generic_bound(b));
+ self.check_generics(&x.generics);
+ }
+
+ fn check_constant(&mut self, x: &'a Constant) {
+ self.check_type(&x.type_);
+ }
+
+ fn check_static(&mut self, x: &'a Static) {
+ self.check_type(&x.type_);
+ }
+
+ fn check_macro(&mut self, _: &'a str) {
+ // nop
+ }
+
+ fn check_proc_macro(&mut self, _: &'a ProcMacro) {
+ // nop
+ }
+
+ fn check_primitive_type(&mut self, _: &'a str) {
+ // nop
+ }
+
+ fn check_generics(&mut self, x: &'a Generics) {
+ x.params.iter().for_each(|p| self.check_generic_param_def(p));
+ x.where_predicates.iter().for_each(|w| self.check_where_predicate(w));
+ }
+
+ fn check_type(&mut self, x: &'a Type) {
+ match x {
+ Type::ResolvedPath(path) => self.check_path(path, PathKind::StructEnumUnion),
+ Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait),
+ Type::Generic(_) => {}
+ Type::Primitive(_) => {}
+ Type::FunctionPointer(fp) => self.check_function_pointer(&**fp),
+ Type::Tuple(tys) => tys.iter().for_each(|ty| self.check_type(ty)),
+ Type::Slice(inner) => self.check_type(&**inner),
+ Type::Array { type_, len: _ } => self.check_type(&**type_),
+ Type::ImplTrait(bounds) => bounds.iter().for_each(|b| self.check_generic_bound(b)),
+ Type::Infer => {}
+ Type::RawPointer { mutable: _, type_ } => self.check_type(&**type_),
+ Type::BorrowedRef { lifetime: _, mutable: _, type_ } => self.check_type(&**type_),
+ Type::QualifiedPath { name: _, args, self_type, trait_ } => {
+ self.check_generic_args(&**args);
+ self.check_type(&**self_type);
+ self.check_path(trait_, PathKind::Trait);
+ }
+ }
+ }
+
+ fn check_fn_decl(&mut self, x: &'a FnDecl) {
+ x.inputs.iter().for_each(|(_name, ty)| self.check_type(ty));
+ if let Some(output) = &x.output {
+ self.check_type(output);
+ }
+ }
+
+ fn check_generic_bound(&mut self, x: &'a GenericBound) {
+ match x {
+ GenericBound::TraitBound { trait_, generic_params, modifier: _ } => {
+ self.check_path(trait_, PathKind::Trait);
+ generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
+ }
+ GenericBound::Outlives(_) => {}
+ }
+ }
+
+ fn check_path(&mut self, x: &'a Path, kind: PathKind) {
+ match kind {
+ PathKind::Trait => self.add_trait_id(&x.id),
+ PathKind::StructEnumUnion => self.add_struct_enum_union_id(&x.id),
+ }
+ if let Some(args) = &x.args {
+ self.check_generic_args(&**args);
+ }
+ }
+
+ fn check_generic_args(&mut self, x: &'a GenericArgs) {
+ match x {
+ GenericArgs::AngleBracketed { args, bindings } => {
+ args.iter().for_each(|arg| self.check_generic_arg(arg));
+ bindings.iter().for_each(|bind| self.check_type_binding(bind));
+ }
+ GenericArgs::Parenthesized { inputs, output } => {
+ inputs.iter().for_each(|ty| self.check_type(ty));
+ if let Some(o) = output {
+ self.check_type(o);
+ }
+ }
+ }
+ }
+
+ fn check_generic_param_def(&mut self, gpd: &'a GenericParamDef) {
+ match &gpd.kind {
+ rustdoc_json_types::GenericParamDefKind::Lifetime { outlives: _ } => {}
+ rustdoc_json_types::GenericParamDefKind::Type { bounds, default, synthetic: _ } => {
+ bounds.iter().for_each(|b| self.check_generic_bound(b));
+ if let Some(ty) = default {
+ self.check_type(ty);
+ }
+ }
+ rustdoc_json_types::GenericParamDefKind::Const { type_, default: _ } => {
+ self.check_type(type_)
+ }
+ }
+ }
+
+ fn check_generic_arg(&mut self, arg: &'a GenericArg) {
+ match arg {
+ GenericArg::Lifetime(_) => {}
+ GenericArg::Type(ty) => self.check_type(ty),
+ GenericArg::Const(c) => self.check_constant(c),
+ GenericArg::Infer => {}
+ }
+ }
+
+ fn check_type_binding(&mut self, bind: &'a TypeBinding) {
+ self.check_generic_args(&bind.args);
+ match &bind.binding {
+ TypeBindingKind::Equality(term) => self.check_term(term),
+ TypeBindingKind::Constraint(bounds) => {
+ bounds.iter().for_each(|b| self.check_generic_bound(b))
+ }
+ }
+ }
+
+ fn check_term(&mut self, term: &'a Term) {
+ match term {
+ Term::Type(ty) => self.check_type(ty),
+ Term::Constant(con) => self.check_constant(con),
+ }
+ }
+
+ fn check_where_predicate(&mut self, w: &'a WherePredicate) {
+ match w {
+ WherePredicate::BoundPredicate { type_, bounds, generic_params } => {
+ self.check_type(type_);
+ bounds.iter().for_each(|b| self.check_generic_bound(b));
+ generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
+ }
+ WherePredicate::RegionPredicate { lifetime: _, bounds } => {
+ bounds.iter().for_each(|b| self.check_generic_bound(b));
+ }
+ WherePredicate::EqPredicate { lhs, rhs } => {
+ self.check_type(lhs);
+ self.check_term(rhs);
+ }
+ }
+ }
+
+ fn check_dyn_trait(&mut self, dyn_trait: &'a DynTrait) {
+ for pt in &dyn_trait.traits {
+ self.check_path(&pt.trait_, PathKind::Trait);
+ pt.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
+ }
+ }
+
+ fn check_function_pointer(&mut self, fp: &'a FunctionPointer) {
+ self.check_fn_decl(&fp.decl);
+ fp.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
+ }
+
+ fn add_id_checked(&mut self, id: &'a Id, valid: fn(Kind) -> bool, expected: &str) {
+ if let Some(kind) = self.kind_of(id) {
+ if valid(kind) {
+ if !self.seen_ids.contains(id) {
+ self.todo.insert(id);
+ }
+ } else {
+ self.fail_expecting(id, expected);
+ }
+ } else {
+ if !self.missing_ids.contains(id) {
+ self.missing_ids.insert(id);
+ self.fail(id, ErrorKind::NotFound)
+ }
+ }
+ }
+
+ fn add_field_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_struct_field, "StructField");
+ }
+
+ fn add_mod_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_module, "Module");
+ }
+ fn add_impl_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_impl, "Impl");
+ }
+
+ fn add_variant_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_variant, "Variant");
+ }
+
+ fn add_trait_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_trait, "Trait");
+ }
+
+ fn add_struct_enum_union_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_struct_enum_union, "Struct or Enum or Union");
+ }
+
+ /// Add an Id that appeared in a trait
+ fn add_trait_item_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::can_appear_in_trait, "Trait inner item");
+ }
+
+ /// Add an Id that appeared in a mod
+ fn add_mod_item_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::can_appear_in_mod, "Module inner item")
+ }
+
+ fn fail_expecting(&mut self, id: &Id, expected: &str) {
+ let kind = self.kind_of(id).unwrap(); // We know it has a kind, as it's wrong.
+ self.fail(id, ErrorKind::Custom(format!("Expected {expected} but found {kind:?}")));
+ }
+
+ fn fail(&mut self, id: &Id, kind: ErrorKind) {
+ self.errs.push(Error { id: id.clone(), kind });
+ }
+
+ fn kind_of(&mut self, id: &Id) -> Option<Kind> {
+ if let Some(item) = self.krate.index.get(id) {
+ Some(Kind::from_item(item))
+ } else if let Some(summary) = self.krate.paths.get(id) {
+ Some(Kind::from_summary(summary))
+ } else {
+ None
+ }
+ }
+}
+
+fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
+ if let Some(id) = set.iter().next() {
+ let id = id.clone();
+ set.take(&id)
+ } else {
+ None
+ }
+}
diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs
index 9696e35b7..2a923a61b 100644
--- a/src/tools/lint-docs/src/groups.rs
+++ b/src/tools/lint-docs/src/groups.rs
@@ -8,6 +8,7 @@ use std::process::Command;
/// Descriptions of rustc lint groups.
static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
("unused", "Lints that detect things being declared but not used, or excess syntax"),
+ ("let-underscore", "Lints that detect wildcard let bindings that are likely to be invalid"),
("rustdoc", "Rustdoc-specific lints"),
("rust-2018-idioms", "Lints to nudge you toward idiomatic features of Rust 2018"),
("nonstandard-style", "Violation of standard naming conventions"),
diff --git a/src/tools/lld-wrapper/src/main.rs b/src/tools/lld-wrapper/src/main.rs
index 90bd24a75..b5e977b26 100644
--- a/src/tools/lld-wrapper/src/main.rs
+++ b/src/tools/lld-wrapper/src/main.rs
@@ -8,12 +8,13 @@
//! make gcc/clang pass `-flavor <flavor>` as the first two arguments in the linker invocation
//! and since Windows does not support symbolic links for files this wrapper is used in place of a
//! symbolic link. It execs `../rust-lld -flavor <flavor>` by propagating the flavor argument
-//! passed to the wrapper as the first two arguments. On Windows it spawns a `..\rust-lld.exe`
-//! child process.
+//! obtained from the wrapper's name as the first two arguments.
+//! On Windows it spawns a `..\rust-lld.exe` child process.
+use std::env::{self, consts::EXE_SUFFIX};
use std::fmt::Display;
use std::path::{Path, PathBuf};
-use std::{env, process};
+use std::process;
trait UnwrapOrExitWith<T> {
fn unwrap_or_exit_with(self, context: &str) -> T;
@@ -42,7 +43,7 @@ impl<T, E: Display> UnwrapOrExitWith<T> for Result<T, E> {
/// Exits if the parent directory cannot be determined.
fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf {
let mut rust_lld_exe_name = "rust-lld".to_owned();
- rust_lld_exe_name.push_str(env::consts::EXE_SUFFIX);
+ rust_lld_exe_name.push_str(EXE_SUFFIX);
let mut rust_lld_path = current_exe_path
.parent()
.unwrap_or_exit_with("directory containing current executable could not be determined")
@@ -53,29 +54,33 @@ fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf {
rust_lld_path
}
+/// Extract LLD flavor name from the lld-wrapper executable name.
+fn get_lld_flavor(current_exe_path: &Path) -> Result<&'static str, String> {
+ let file = current_exe_path.file_name();
+ let stem = file.and_then(|s| s.to_str()).map(|s| s.trim_end_matches(EXE_SUFFIX));
+ Ok(match stem {
+ Some("ld.lld") => "gnu",
+ Some("ld64.lld") => "darwin",
+ Some("lld-link") => "link",
+ Some("wasm-ld") => "wasm",
+ _ => return Err(format!("{:?}", file)),
+ })
+}
+
/// Returns the command for invoking rust-lld with the correct flavor.
-/// LLD only accepts the flavor argument at the first two arguments, so move it there.
+/// LLD only accepts the flavor argument at the first two arguments, so pass it there.
///
/// Exits on error.
fn get_rust_lld_command(current_exe_path: &Path) -> process::Command {
let rust_lld_path = get_rust_lld_path(current_exe_path);
let mut command = process::Command::new(rust_lld_path);
- let mut flavor = None;
- let args = env::args_os()
- .skip(1)
- .filter(|arg| match arg.to_str().and_then(|s| s.strip_prefix("-rustc-lld-flavor=")) {
- Some(suffix) => {
- flavor = Some(suffix.to_string());
- false
- }
- None => true,
- })
- .collect::<Vec<_>>();
+ let flavor =
+ get_lld_flavor(current_exe_path).unwrap_or_exit_with("executable has unexpected name");
command.arg("-flavor");
- command.arg(flavor.unwrap_or_exit_with("-rustc-lld-flavor=<flavor> is not passed"));
- command.args(args);
+ command.arg(flavor);
+ command.args(env::args_os().skip(1));
command
}
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index fe5195738..c0cef8f7b 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -31,21 +31,17 @@ except ImportError:
# read privileges on it). CI will fail otherwise.
MAINTAINERS = {
'miri': {'oli-obk', 'RalfJung'},
- 'rls': {'Xanewok'},
- 'rustfmt': {'topecongiro', 'calebcartwright'},
- 'book': {'carols10cents', 'steveklabnik'},
+ 'book': {'carols10cents'},
'nomicon': {'frewsxcv', 'Gankra', 'JohnTitor'},
- 'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'},
- 'rust-by-example': {'steveklabnik', 'marioidival'},
+ 'reference': {'Havvy', 'matthewjasper', 'ehuss'},
+ 'rust-by-example': {'marioidival'},
'embedded-book': {'adamgreig', 'andre-richter', 'jamesmunns', 'therealprof'},
- 'edition-guide': {'ehuss', 'steveklabnik'},
+ 'edition-guide': {'ehuss'},
'rustc-dev-guide': {'spastorino', 'amanjeev', 'JohnTitor'},
}
LABELS = {
'miri': ['A-miri', 'C-bug'],
- 'rls': ['A-rls', 'C-bug'],
- 'rustfmt': ['A-rustfmt', 'C-bug'],
'book': ['C-bug'],
'nomicon': ['C-bug'],
'reference': ['C-bug'],
@@ -57,8 +53,6 @@ LABELS = {
REPOS = {
'miri': 'https://github.com/rust-lang/miri',
- 'rls': 'https://github.com/rust-lang/rls',
- 'rustfmt': 'https://github.com/rust-lang/rustfmt',
'book': 'https://github.com/rust-lang/book',
'nomicon': 'https://github.com/rust-lang/nomicon',
'reference': 'https://github.com/rust-lang/reference',
diff --git a/src/tools/replace-version-placeholder/Cargo.toml b/src/tools/replace-version-placeholder/Cargo.toml
new file mode 100644
index 000000000..346ce6bd1
--- /dev/null
+++ b/src/tools/replace-version-placeholder/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "replace-version-placeholder"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+tidy = { path = "../tidy" }
+walkdir = "2"
diff --git a/src/tools/replace-version-placeholder/src/main.rs b/src/tools/replace-version-placeholder/src/main.rs
new file mode 100644
index 000000000..33b35d054
--- /dev/null
+++ b/src/tools/replace-version-placeholder/src/main.rs
@@ -0,0 +1,30 @@
+use std::path::PathBuf;
+use tidy::{t, walk};
+
+pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
+
+fn main() {
+ let root_path: PathBuf = std::env::args_os().nth(1).expect("need path to root of repo").into();
+ let version_path = root_path.join("src").join("version");
+ let version_str = t!(std::fs::read_to_string(&version_path), version_path);
+ let version_str = version_str.trim();
+ walk::walk(
+ &root_path,
+ &mut |path| {
+ walk::filter_dirs(path)
+ // We exempt these as they require the placeholder
+ // for their operation
+ || path.ends_with("compiler/rustc_attr/src/builtin.rs")
+ || path.ends_with("src/tools/tidy/src/features/version.rs")
+ || path.ends_with("src/tools/replace-version-placeholder")
+ },
+ &mut |entry, contents| {
+ if !contents.contains(VERSION_PLACEHOLDER) {
+ return;
+ }
+ let new_contents = contents.replace(VERSION_PLACEHOLDER, version_str);
+ let path = entry.path();
+ t!(std::fs::write(&path, new_contents), path);
+ },
+ );
+}
diff --git a/src/tools/rust-analyzer/.vscode/launch.json b/src/tools/rust-analyzer/.vscode/launch.json
index 021b8f048..1e21214ff 100644
--- a/src/tools/rust-analyzer/.vscode/launch.json
+++ b/src/tools/rust-analyzer/.vscode/launch.json
@@ -78,7 +78,7 @@
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
- "--disable-extension", "matklad.rust-analyzer",
+ "--disable-extension", "rust-lang.rust-analyzer",
"--extensionDevelopmentPath=${workspaceFolder}/editors/code"
],
"outFiles": [
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 703f0e5b8..9f10d92c4 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -37,9 +37,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.58"
+version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
+checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
[[package]]
name = "anymap"
@@ -78,16 +78,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backtrace"
-version = "0.3.65"
+version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
+checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
- "object 0.28.4",
+ "object",
"rustc-demangle",
]
@@ -114,9 +114,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "camino"
-version = "1.0.9"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"
+checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e"
dependencies = [
"serde",
]
@@ -171,9 +171,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chalk-derive"
-version = "0.83.0"
+version = "0.84.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83553c2ef7717e58aecdf42dd9e3c876229f5a1f35a16435b5ddc4addef81827"
+checksum = "cf29c109d57f8d57b0e7675391be37a9285d86dd93278bd5f14a0ad3c447a6c2"
dependencies = [
"proc-macro2",
"quote",
@@ -183,9 +183,9 @@ dependencies = [
[[package]]
name = "chalk-ir"
-version = "0.83.0"
+version = "0.84.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dd42107d579d8ec2a5af20a8de62a37524a67bf6a4c0ff08a950068f0bfea91"
+checksum = "d391763027b5e50a5e15caf6d2857ec585fd68160367bbeac9e1804209620918"
dependencies = [
"bitflags",
"chalk-derive",
@@ -194,9 +194,9 @@ dependencies = [
[[package]]
name = "chalk-recursive"
-version = "0.83.0"
+version = "0.84.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c444031541a76c13c145e76d91f1548e9feb2240e7f0c3e77879ceb694994f2d"
+checksum = "afafd92dcdc7fe0ea940ee94bdd8cc5bd18f4a4a84c593d6d7025fe16c150478"
dependencies = [
"chalk-derive",
"chalk-ir",
@@ -207,9 +207,9 @@ dependencies = [
[[package]]
name = "chalk-solve"
-version = "0.83.0"
+version = "0.84.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c76f2db19c5e8a3d42340cf5b4d90b8c218750536fca35e2bb285ab6653c0bc8"
+checksum = "3af1d111f11c91c48ace02e93e470c5bae6d2631bd112e4545317da53660d7fc"
dependencies = [
"chalk-derive",
"chalk-ir",
@@ -248,24 +248,10 @@ dependencies = [
]
[[package]]
-name = "crossbeam"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
-dependencies = [
- "cfg-if",
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-epoch",
- "crossbeam-queue",
- "crossbeam-utils",
-]
-
-[[package]]
name = "crossbeam-channel"
-version = "0.5.5"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
@@ -273,9 +259,9 @@ dependencies = [
[[package]]
name = "crossbeam-deque"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
@@ -284,9 +270,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
-version = "0.9.9"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
+checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
dependencies = [
"autocfg",
"cfg-if",
@@ -297,20 +283,10 @@ dependencies = [
]
[[package]]
-name = "crossbeam-queue"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
name = "crossbeam-utils"
-version = "0.8.10"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
+checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if",
"once_cell",
@@ -359,9 +335,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1"
[[package]]
name = "either"
-version = "1.7.0"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "ena"
@@ -458,15 +434,15 @@ checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a"
[[package]]
name = "gimli"
-version = "0.26.1"
+version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
+checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
[[package]]
name = "hashbrown"
-version = "0.12.1"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heck"
@@ -710,6 +686,7 @@ dependencies = [
"ide-db",
"itertools",
"profile",
+ "serde_json",
"sourcegen",
"stdx",
"syntax",
@@ -727,6 +704,7 @@ dependencies = [
"ide-db",
"itertools",
"parser",
+ "stdx",
"syntax",
"test-utils",
"text-edit",
@@ -793,9 +771,9 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
+checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
[[package]]
name = "jod-thread"
@@ -835,9 +813,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]]
name = "libloading"
@@ -894,9 +872,9 @@ dependencies = [
[[package]]
name = "lsp-types"
-version = "0.93.0"
+version = "0.93.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70c74e2173b2b31f8655d33724b4b45ac13f439386f66290f539c22b144c2212"
+checksum = "a3bcfee315dde785ba887edb540b08765fd7df75a7d948844be6bf5712246734"
dependencies = [
"bitflags",
"serde",
@@ -943,9 +921,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memmap2"
-version = "0.5.4"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae"
+checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
dependencies = [
"libc",
]
@@ -1000,9 +978,9 @@ dependencies = [
[[package]]
name = "notify"
-version = "5.0.0-pre.15"
+version = "5.0.0-pre.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "553f9844ad0b0824605c20fb55a661679782680410abfb1a8144c2e7e437e7a7"
+checksum = "530f6314d6904508082f4ea424a0275cf62d341e118b313663f266429cb19693"
dependencies = [
"bitflags",
"crossbeam-channel",
@@ -1028,15 +1006,6 @@ dependencies = [
[[package]]
name = "object"
-version = "0.28.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "object"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
@@ -1046,9 +1015,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.13.0"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
+checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
[[package]]
name = "oorandom"
@@ -1117,9 +1086,9 @@ dependencies = [
[[package]]
name = "paste"
-version = "1.0.7"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
+checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22"
[[package]]
name = "paths"
@@ -1171,7 +1140,7 @@ name = "proc-macro-api"
version = "0.0.0"
dependencies = [
"memmap2",
- "object 0.29.0",
+ "object",
"paths",
"profile",
"serde",
@@ -1186,12 +1155,11 @@ dependencies = [
name = "proc-macro-srv"
version = "0.0.0"
dependencies = [
- "crossbeam",
"expect-test",
"libloading",
"mbe",
"memmap2",
- "object 0.29.0",
+ "object",
"paths",
"proc-macro-api",
"proc-macro-test",
@@ -1220,9 +1188,9 @@ version = "0.0.0"
[[package]]
name = "proc-macro2"
-version = "1.0.40"
+version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
+checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
dependencies = [
"unicode-ident",
]
@@ -1263,10 +1231,30 @@ dependencies = [
]
[[package]]
+name = "protobuf"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ee4a7d8b91800c8f167a6268d1a1026607368e1adc84e98fe044aeb905302f7"
+dependencies = [
+ "once_cell",
+ "protobuf-support",
+ "thiserror",
+]
+
+[[package]]
+name = "protobuf-support"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ca157fe12fc7ee2e315f2f735e27df41b3d97cdd70ea112824dac1ffb08ee1c"
+dependencies = [
+ "thiserror",
+]
+
+[[package]]
name = "pulldown-cmark"
-version = "0.9.1"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
+checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63"
dependencies = [
"bitflags",
"memchr",
@@ -1284,9 +1272,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.20"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
@@ -1317,18 +1305,18 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.2.13"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
-version = "1.5.6"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"regex-syntax",
]
@@ -1344,9 +1332,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.26"
+version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "rowan"
@@ -1393,6 +1381,7 @@ dependencies = [
"project-model",
"rayon",
"rustc-hash",
+ "scip",
"serde",
"serde_json",
"sourcegen",
@@ -1437,9 +1426,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "ryu"
-version = "1.0.10"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "salsa"
@@ -1480,6 +1469,15 @@ dependencies = [
]
[[package]]
+name = "scip"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2bfbb10286f69fad7c78db71004b7839bf957788359fe0c479f029f9849136b"
+dependencies = [
+ "protobuf",
+]
+
+[[package]]
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1493,27 +1491,27 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
+checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
dependencies = [
"serde",
]
[[package]]
name = "serde"
-version = "1.0.138"
+version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
+checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.138"
+version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
+checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
dependencies = [
"proc-macro2",
"quote",
@@ -1522,9 +1520,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.82"
+version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
+checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
dependencies = [
"indexmap",
"itoa",
@@ -1534,9 +1532,9 @@ dependencies = [
[[package]]
name = "serde_repr"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed"
+checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
dependencies = [
"proc-macro2",
"quote",
@@ -1593,9 +1591,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.98"
+version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
+checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
dependencies = [
"proc-macro2",
"quote",
@@ -1665,6 +1663,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a"
[[package]]
+name = "thiserror"
+version = "1.0.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1738,9 +1756,9 @@ dependencies = [
[[package]]
name = "tracing"
-version = "0.1.35"
+version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
+checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
dependencies = [
"cfg-if",
"pin-project-lite",
@@ -1761,9 +1779,9 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.28"
+version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
+checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
dependencies = [
"once_cell",
"valuable",
@@ -1782,9 +1800,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.14"
+version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59"
+checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"
dependencies = [
"matchers",
"once_cell",
@@ -1904,6 +1922,7 @@ dependencies = [
"indexmap",
"paths",
"rustc-hash",
+ "stdx",
]
[[package]]
diff --git a/src/tools/rust-analyzer/README.md b/src/tools/rust-analyzer/README.md
index 8bb0517ed..8c3f6f846 100644
--- a/src/tools/rust-analyzer/README.md
+++ b/src/tools/rust-analyzer/README.md
@@ -43,7 +43,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer
## License
-Rust analyzer is primarily distributed under the terms of both the MIT
+rust-analyzer is primarily distributed under the terms of both the MIT
license and the Apache License (Version 2.0).
See LICENSE-APACHE and LICENSE-MIT for details.
diff --git a/src/tools/rust-analyzer/bench_data/glorious_old_parser b/src/tools/rust-analyzer/bench_data/glorious_old_parser
index 7e900dfeb..764893daa 100644
--- a/src/tools/rust-analyzer/bench_data/glorious_old_parser
+++ b/src/tools/rust-analyzer/bench_data/glorious_old_parser
@@ -1988,7 +1988,7 @@ impl<'a> Parser<'a> {
err.span_suggestion(
span,
"declare the type after the parameter binding",
- String::from("<identifier>: <type>"),
+ "<identifier>: <type>",
Applicability::HasPlaceholders,
);
} else if require_name && is_trait_item {
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index 9b5a10acf..b388e47de 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -6,13 +6,14 @@
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
//! actual IO is done and lowered to input.
-use std::{fmt, iter::FromIterator, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
+use std::{fmt, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
use cfg::CfgOptions;
-use rustc_hash::{FxHashMap, FxHashSet};
+use rustc_hash::FxHashMap;
+use stdx::hash::{NoHashHashMap, NoHashHashSet};
use syntax::SmolStr;
use tt::Subtree;
-use vfs::{file_set::FileSet, FileId, VfsPath};
+use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath};
/// Files are grouped into source roots. A source root is a directory on the
/// file systems which is watched for changes. Typically it corresponds to a
@@ -31,22 +32,30 @@ pub struct SourceRoot {
/// Libraries are considered mostly immutable, this assumption is used to
/// optimize salsa's query structure
pub is_library: bool,
- pub(crate) file_set: FileSet,
+ file_set: FileSet,
}
impl SourceRoot {
pub fn new_local(file_set: FileSet) -> SourceRoot {
SourceRoot { is_library: false, file_set }
}
+
pub fn new_library(file_set: FileSet) -> SourceRoot {
SourceRoot { is_library: true, file_set }
}
+
pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> {
self.file_set.path_for_file(file)
}
+
pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> {
self.file_set.file_for_path(path)
}
+
+ pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
+ self.file_set.resolve_path(path)
+ }
+
pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ {
self.file_set.iter()
}
@@ -72,12 +81,19 @@ impl SourceRoot {
/// <https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/architecture.md#serialization>
#[derive(Debug, Clone, Default /* Serialize, Deserialize */)]
pub struct CrateGraph {
- arena: FxHashMap<CrateId, CrateData>,
+ arena: NoHashHashMap<CrateId, CrateData>,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct CrateId(pub u32);
+impl stdx::hash::NoHashHashable for CrateId {}
+impl std::hash::Hash for CrateId {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.0.hash(state);
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CrateName(SmolStr);
@@ -342,7 +358,7 @@ impl CrateGraph {
// Check if adding a dep from `from` to `to` creates a cycle. To figure
// that out, look for a path in the *opposite* direction, from `to` to
// `from`.
- if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) {
+ if let Some(path) = self.find_path(&mut NoHashHashSet::default(), dep.crate_id, from) {
let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect();
let err = CyclicDependenciesError { path };
assert!(err.from().0 == from && err.to().0 == dep.crate_id);
@@ -365,7 +381,7 @@ impl CrateGraph {
/// including the crate itself.
pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
let mut worklist = vec![of];
- let mut deps = FxHashSet::default();
+ let mut deps = NoHashHashSet::default();
while let Some(krate) = worklist.pop() {
if !deps.insert(krate) {
@@ -382,10 +398,10 @@ impl CrateGraph {
/// including the crate itself.
pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
let mut worklist = vec![of];
- let mut rev_deps = FxHashSet::default();
+ let mut rev_deps = NoHashHashSet::default();
rev_deps.insert(of);
- let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
+ let mut inverted_graph = NoHashHashMap::<_, Vec<_>>::default();
self.arena.iter().for_each(|(&krate, data)| {
data.dependencies
.iter()
@@ -409,7 +425,7 @@ impl CrateGraph {
/// come before the crate itself).
pub fn crates_in_topological_order(&self) -> Vec<CrateId> {
let mut res = Vec::new();
- let mut visited = FxHashSet::default();
+ let mut visited = NoHashHashSet::default();
for krate in self.arena.keys().copied() {
go(self, &mut visited, &mut res, krate);
@@ -419,7 +435,7 @@ impl CrateGraph {
fn go(
graph: &CrateGraph,
- visited: &mut FxHashSet<CrateId>,
+ visited: &mut NoHashHashSet<CrateId>,
res: &mut Vec<CrateId>,
source: CrateId,
) {
@@ -459,7 +475,7 @@ impl CrateGraph {
fn find_path(
&self,
- visited: &mut FxHashSet<CrateId>,
+ visited: &mut NoHashHashSet<CrateId>,
from: CrateId,
to: CrateId,
) -> Option<Vec<CrateId>> {
diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
index 2d0a95b09..da11e4ae7 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
@@ -8,7 +8,7 @@ pub mod fixture;
use std::{panic, sync::Arc};
-use rustc_hash::FxHashSet;
+use stdx::hash::NoHashHashSet;
use syntax::{ast, Parse, SourceFile, TextRange, TextSize};
pub use crate::{
@@ -58,7 +58,7 @@ pub trait FileLoader {
/// Text of the file.
fn file_text(&self, file_id: FileId) -> Arc<String>;
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId>;
- fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>;
+ fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>>;
}
/// Database which stores all significant input facts: source code and project
@@ -94,10 +94,10 @@ pub trait SourceDatabaseExt: SourceDatabase {
#[salsa::input]
fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>;
- fn source_root_crates(&self, id: SourceRootId) -> Arc<FxHashSet<CrateId>>;
+ fn source_root_crates(&self, id: SourceRootId) -> Arc<NoHashHashSet<CrateId>>;
}
-fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc<FxHashSet<CrateId>> {
+fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc<NoHashHashSet<CrateId>> {
let graph = db.crate_graph();
let res = graph
.iter()
@@ -120,10 +120,10 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
// FIXME: this *somehow* should be platform agnostic...
let source_root = self.0.file_source_root(path.anchor);
let source_root = self.0.source_root(source_root);
- source_root.file_set.resolve_path(path)
+ source_root.resolve_path(path)
}
- fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+ fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
let _p = profile::span("relevant_crates");
let source_root = self.0.file_source_root(file_id);
self.0.source_root_crates(source_root)
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
index 4e8bc881a..d9f4ef5b7 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
@@ -57,6 +57,7 @@ pub struct FlycheckHandle {
// XXX: drop order is significant
sender: Sender<Restart>,
_thread: jod_thread::JoinHandle,
+ id: usize,
}
impl FlycheckHandle {
@@ -72,18 +73,27 @@ impl FlycheckHandle {
.name("Flycheck".to_owned())
.spawn(move || actor.run(receiver))
.expect("failed to spawn thread");
- FlycheckHandle { sender, _thread: thread }
+ FlycheckHandle { id, sender, _thread: thread }
}
/// Schedule a re-start of the cargo check worker.
- pub fn update(&self) {
- self.sender.send(Restart).unwrap();
+ pub fn restart(&self) {
+ self.sender.send(Restart::Yes).unwrap();
+ }
+
+ /// Stop this cargo check worker.
+ pub fn cancel(&self) {
+ self.sender.send(Restart::No).unwrap();
+ }
+
+ pub fn id(&self) -> usize {
+ self.id
}
}
pub enum Message {
/// Request adding a diagnostic with fixes included to a file
- AddDiagnostic { workspace_root: AbsPathBuf, diagnostic: Diagnostic },
+ AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic },
/// Request check progress notification to client
Progress {
@@ -96,8 +106,9 @@ pub enum Message {
impl fmt::Debug for Message {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
- Message::AddDiagnostic { workspace_root, diagnostic } => f
+ Message::AddDiagnostic { id, workspace_root, diagnostic } => f
.debug_struct("AddDiagnostic")
+ .field("id", id)
.field("workspace_root", workspace_root)
.field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code))
.finish(),
@@ -114,9 +125,13 @@ pub enum Progress {
DidCheckCrate(String),
DidFinish(io::Result<()>),
DidCancel,
+ DidFailToRestart(String),
}
-struct Restart;
+enum Restart {
+ Yes,
+ No,
+}
struct FlycheckActor {
id: usize,
@@ -143,6 +158,7 @@ impl FlycheckActor {
config: FlycheckConfig,
workspace_root: AbsPathBuf,
) -> FlycheckActor {
+ tracing::info!(%id, ?workspace_root, "Spawning flycheck");
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
}
fn progress(&self, progress: Progress) {
@@ -158,10 +174,13 @@ impl FlycheckActor {
fn run(mut self, inbox: Receiver<Restart>) {
while let Some(event) = self.next_event(&inbox) {
match event {
- Event::Restart(Restart) => {
+ Event::Restart(Restart::No) => {
+ self.cancel_check_process();
+ }
+ Event::Restart(Restart::Yes) => {
// Cancel the previously spawned process
self.cancel_check_process();
- while let Ok(Restart) = inbox.recv_timeout(Duration::from_millis(50)) {}
+ while let Ok(_) = inbox.recv_timeout(Duration::from_millis(50)) {}
let command = self.check_command();
tracing::debug!(?command, "will restart flycheck");
@@ -175,15 +194,16 @@ impl FlycheckActor {
self.progress(Progress::DidStart);
}
Err(error) => {
- tracing::error!(
- command = ?self.check_command(),
- %error, "failed to restart flycheck"
- );
+ self.progress(Progress::DidFailToRestart(format!(
+ "Failed to run the following command: {:?} error={}",
+ self.check_command(),
+ error
+ )));
}
}
}
Event::CheckEvent(None) => {
- tracing::debug!("flycheck finished");
+ tracing::debug!(flycheck_id = self.id, "flycheck finished");
// Watcher finished
let cargo_handle = self.cargo_handle.take().unwrap();
@@ -203,6 +223,7 @@ impl FlycheckActor {
CargoMessage::Diagnostic(msg) => {
self.send(Message::AddDiagnostic {
+ id: self.id,
workspace_root: self.workspace_root.clone(),
diagnostic: msg,
});
@@ -216,6 +237,10 @@ impl FlycheckActor {
fn cancel_check_process(&mut self) {
if let Some(cargo_handle) = self.cargo_handle.take() {
+ tracing::debug!(
+ command = ?self.check_command(),
+ "did cancel flycheck"
+ );
cargo_handle.cancel();
self.progress(Progress::DidCancel);
}
@@ -338,7 +363,7 @@ impl CargoActor {
//
// Because cargo only outputs one JSON object per line, we can
// simply skip a line if it doesn't parse, which just ignores any
- // erroneus output.
+ // erroneous output.
let mut error = String::new();
let mut read_at_least_one_message = false;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
index 080a307b1..22f5fb992 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
@@ -4,6 +4,7 @@ mod lower;
#[cfg(test)]
mod tests;
pub mod scope;
+mod pretty;
use std::{ops::Index, sync::Arc};
@@ -249,6 +250,10 @@ pub type PatSource = InFile<PatPtr>;
pub type LabelPtr = AstPtr<ast::Label>;
pub type LabelSource = InFile<LabelPtr>;
+
+pub type FieldPtr = AstPtr<ast::RecordExprField>;
+pub type FieldSource = InFile<FieldPtr>;
+
/// An item body together with the mapping from syntax nodes to HIR expression
/// IDs. This is needed to go from e.g. a position in a file to the HIR
/// expression containing it; but for type inference etc., we want to operate on
@@ -263,18 +268,18 @@ pub type LabelSource = InFile<LabelPtr>;
#[derive(Default, Debug, Eq, PartialEq)]
pub struct BodySourceMap {
expr_map: FxHashMap<ExprSource, ExprId>,
- expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
+ expr_map_back: ArenaMap<ExprId, ExprSource>,
pat_map: FxHashMap<PatSource, PatId>,
- pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
+ pat_map_back: ArenaMap<PatId, PatSource>,
label_map: FxHashMap<LabelSource, LabelId>,
label_map_back: ArenaMap<LabelId, LabelSource>,
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
/// Instead, we use id of expression (`92`) to identify the field.
- field_map: FxHashMap<InFile<AstPtr<ast::RecordExprField>>, ExprId>,
- field_map_back: FxHashMap<ExprId, InFile<AstPtr<ast::RecordExprField>>>,
+ field_map: FxHashMap<FieldSource, ExprId>,
+ field_map_back: FxHashMap<ExprId, FieldSource>,
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
@@ -352,6 +357,10 @@ impl Body {
}
}
+ pub fn pretty_print(&self, db: &dyn DefDatabase, owner: DefWithBodyId) -> String {
+ pretty::print_body_hir(db, self, owner)
+ }
+
fn new(
db: &dyn DefDatabase,
expander: Expander,
@@ -415,7 +424,7 @@ impl Index<LabelId> for Body {
// Perhaps `expr_syntax` and `expr_id`?
impl BodySourceMap {
pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
- self.expr_map_back[expr].clone()
+ self.expr_map_back.get(expr).cloned().ok_or(SyntheticSyntax)
}
pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
@@ -429,7 +438,7 @@ impl BodySourceMap {
}
pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> {
- self.pat_map_back[pat].clone()
+ self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
}
pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
@@ -451,9 +460,10 @@ impl BodySourceMap {
self.label_map.get(&src).cloned()
}
- pub fn field_syntax(&self, expr: ExprId) -> InFile<AstPtr<ast::RecordExprField>> {
+ pub fn field_syntax(&self, expr: ExprId) -> FieldSource {
self.field_map_back[&expr].clone()
}
+
pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> {
let src = node.map(AstPtr::new);
self.field_map.get(&src).cloned()
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
index 66f9c24e8..3b3297f78 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
@@ -24,7 +24,7 @@ use syntax::{
use crate::{
adt::StructKind,
- body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
+ body::{Body, BodySourceMap, Expander, ExprPtr, LabelPtr, LabelSource, PatPtr},
body::{BodyDiagnostic, ExprSource, PatSource},
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
db::DefDatabase,
@@ -150,21 +150,21 @@ impl ExprCollector<'_> {
LowerCtx::new(self.db, self.expander.current_file_id)
}
- fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
+ fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
let src = self.expander.to_source(ptr);
- let id = self.make_expr(expr, Ok(src.clone()));
+ let id = self.make_expr(expr, src.clone());
self.source_map.expr_map.insert(src, id);
id
}
// desugared exprs don't have ptr, that's wrong and should be fixed
// somehow.
fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
- self.make_expr(expr, Err(SyntheticSyntax))
+ self.body.exprs.alloc(expr)
}
fn missing_expr(&mut self) -> ExprId {
self.alloc_expr_desugared(Expr::Missing)
}
- fn make_expr(&mut self, expr: Expr, src: Result<ExprSource, SyntheticSyntax>) -> ExprId {
+ fn make_expr(&mut self, expr: Expr, src: ExprSource) -> ExprId {
let id = self.body.exprs.alloc(expr);
self.source_map.expr_map_back.insert(id, src);
id
@@ -172,20 +172,20 @@ impl ExprCollector<'_> {
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
let src = self.expander.to_source(ptr);
- let id = self.make_pat(pat, Ok(src.clone()));
+ let id = self.make_pat(pat, src.clone());
self.source_map.pat_map.insert(src, id);
id
}
fn missing_pat(&mut self) -> PatId {
- self.make_pat(Pat::Missing, Err(SyntheticSyntax))
+ self.body.pats.alloc(Pat::Missing)
}
- fn make_pat(&mut self, pat: Pat, src: Result<PatSource, SyntheticSyntax>) -> PatId {
+ fn make_pat(&mut self, pat: Pat, src: PatSource) -> PatId {
let id = self.body.pats.alloc(pat);
self.source_map.pat_map_back.insert(id, src);
id
}
- fn alloc_label(&mut self, label: Label, ptr: AstPtr<ast::Label>) -> LabelId {
+ fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId {
let src = self.expander.to_source(ptr);
let id = self.make_label(label, src.clone());
self.source_map.label_map.insert(src, id);
@@ -550,12 +550,6 @@ impl ExprCollector<'_> {
None => self.alloc_expr(Expr::Missing, syntax_ptr),
}
}
- ast::Expr::MacroStmts(e) => {
- let statements = e.statements().filter_map(|s| self.collect_stmt(s)).collect();
- let tail = e.expr().map(|e| self.collect_expr(e));
-
- self.alloc_expr(Expr::MacroStmts { tail, statements }, syntax_ptr)
- }
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
})
}
@@ -632,11 +626,46 @@ impl ExprCollector<'_> {
}
}
- fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Statement> {
+ fn collect_macro_as_stmt(
+ &mut self,
+ statements: &mut Vec<Statement>,
+ mac: ast::MacroExpr,
+ ) -> Option<ExprId> {
+ let mac_call = mac.macro_call()?;
+ let syntax_ptr = AstPtr::new(&ast::Expr::from(mac));
+ let macro_ptr = AstPtr::new(&mac_call);
+ let expansion = self.collect_macro_call(
+ mac_call,
+ macro_ptr,
+ false,
+ |this, expansion: Option<ast::MacroStmts>| match expansion {
+ Some(expansion) => {
+ expansion.statements().for_each(|stmt| this.collect_stmt(statements, stmt));
+ expansion.expr().and_then(|expr| match expr {
+ ast::Expr::MacroExpr(mac) => this.collect_macro_as_stmt(statements, mac),
+ expr => Some(this.collect_expr(expr)),
+ })
+ }
+ None => None,
+ },
+ );
+ match expansion {
+ Some(tail) => {
+ // Make the macro-call point to its expanded expression so we can query
+ // semantics on syntax pointers to the macro
+ let src = self.expander.to_source(syntax_ptr);
+ self.source_map.expr_map.insert(src, tail);
+ Some(tail)
+ }
+ None => None,
+ }
+ }
+
+ fn collect_stmt(&mut self, statements: &mut Vec<Statement>, s: ast::Stmt) {
match s {
ast::Stmt::LetStmt(stmt) => {
if self.check_cfg(&stmt).is_none() {
- return None;
+ return;
}
let pat = self.collect_pat_opt(stmt.pat());
let type_ref =
@@ -646,61 +675,26 @@ impl ExprCollector<'_> {
.let_else()
.and_then(|let_else| let_else.block_expr())
.map(|block| self.collect_block(block));
- Some(Statement::Let { pat, type_ref, initializer, else_branch })
+ statements.push(Statement::Let { pat, type_ref, initializer, else_branch });
}
ast::Stmt::ExprStmt(stmt) => {
let expr = stmt.expr();
- if let Some(expr) = &expr {
- if self.check_cfg(expr).is_none() {
- return None;
- }
+ match &expr {
+ Some(expr) if self.check_cfg(expr).is_none() => return,
+ _ => (),
}
let has_semi = stmt.semicolon_token().is_some();
// Note that macro could be expanded to multiple statements
- if let Some(expr @ ast::Expr::MacroExpr(mac)) = &expr {
- let mac_call = mac.macro_call()?;
- let syntax_ptr = AstPtr::new(expr);
- let macro_ptr = AstPtr::new(&mac_call);
- let stmt = self.collect_macro_call(
- mac_call,
- macro_ptr,
- false,
- |this, expansion: Option<ast::MacroStmts>| match expansion {
- Some(expansion) => {
- let statements = expansion
- .statements()
- .filter_map(|stmt| this.collect_stmt(stmt))
- .collect();
- let tail = expansion.expr().map(|expr| this.collect_expr(expr));
-
- let mac_stmts = this.alloc_expr(
- Expr::MacroStmts { tail, statements },
- AstPtr::new(&ast::Expr::MacroStmts(expansion)),
- );
-
- Some(mac_stmts)
- }
- None => None,
- },
- );
-
- let expr = match stmt {
- Some(expr) => {
- // Make the macro-call point to its expanded expression so we can query
- // semantics on syntax pointers to the macro
- let src = self.expander.to_source(syntax_ptr);
- self.source_map.expr_map.insert(src, expr);
- expr
- }
- None => self.alloc_expr(Expr::Missing, syntax_ptr),
- };
- Some(Statement::Expr { expr, has_semi })
+ if let Some(ast::Expr::MacroExpr(mac)) = expr {
+ if let Some(expr) = self.collect_macro_as_stmt(statements, mac) {
+ statements.push(Statement::Expr { expr, has_semi })
+ }
} else {
let expr = self.collect_expr_opt(expr);
- Some(Statement::Expr { expr, has_semi })
+ statements.push(Statement::Expr { expr, has_semi });
}
}
- ast::Stmt::Item(_item) => None,
+ ast::Stmt::Item(_item) => (),
}
}
@@ -721,9 +715,12 @@ impl ExprCollector<'_> {
let prev_def_map = mem::replace(&mut self.expander.def_map, def_map);
let prev_local_module = mem::replace(&mut self.expander.module, module);
- let mut statements: Vec<_> =
- block.statements().filter_map(|s| self.collect_stmt(s)).collect();
- let tail = block.tail_expr().and_then(|e| self.maybe_collect_expr(e));
+ let mut statements = Vec::new();
+ block.statements().for_each(|s| self.collect_stmt(&mut statements, s));
+ let tail = block.tail_expr().and_then(|e| match e {
+ ast::Expr::MacroExpr(mac) => self.collect_macro_as_stmt(&mut statements, mac),
+ expr => self.maybe_collect_expr(expr),
+ });
let tail = tail.or_else(|| {
let stmt = statements.pop()?;
if let Statement::Expr { expr, has_semi: false } = stmt {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
new file mode 100644
index 000000000..f2fed9544
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
@@ -0,0 +1,608 @@
+//! A pretty-printer for HIR.
+
+use std::fmt::{self, Write};
+
+use crate::{
+ expr::{Array, BindingAnnotation, Literal, Statement},
+ pretty::{print_generic_args, print_path, print_type_ref},
+ type_ref::TypeRef,
+};
+
+use super::*;
+
+pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String {
+ let needs_semi;
+ let header = match owner {
+ DefWithBodyId::FunctionId(it) => {
+ needs_semi = false;
+ let item_tree_id = it.lookup(db).id;
+ format!("fn {}(…) ", item_tree_id.item_tree(db)[item_tree_id.value].name)
+ }
+ DefWithBodyId::StaticId(it) => {
+ needs_semi = true;
+ let item_tree_id = it.lookup(db).id;
+ format!("static {} = ", item_tree_id.item_tree(db)[item_tree_id.value].name)
+ }
+ DefWithBodyId::ConstId(it) => {
+ needs_semi = true;
+ let item_tree_id = it.lookup(db).id;
+ let name = match &item_tree_id.item_tree(db)[item_tree_id.value].name {
+ Some(name) => name.to_string(),
+ None => "_".to_string(),
+ };
+ format!("const {} = ", name)
+ }
+ };
+
+ let mut p = Printer { body, buf: header, indent_level: 0, needs_indent: false };
+ p.print_expr(body.body_expr);
+ if needs_semi {
+ p.buf.push(';');
+ }
+ p.buf
+}
+
+macro_rules! w {
+ ($dst:expr, $($arg:tt)*) => {
+ { let _ = write!($dst, $($arg)*); }
+ };
+}
+
+macro_rules! wln {
+ ($dst:expr) => {
+ { let _ = writeln!($dst); }
+ };
+ ($dst:expr, $($arg:tt)*) => {
+ { let _ = writeln!($dst, $($arg)*); }
+ };
+}
+
+struct Printer<'a> {
+ body: &'a Body,
+ buf: String,
+ indent_level: usize,
+ needs_indent: bool,
+}
+
+impl<'a> Write for Printer<'a> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for line in s.split_inclusive('\n') {
+ if self.needs_indent {
+ match self.buf.chars().rev().skip_while(|ch| *ch == ' ').next() {
+ Some('\n') | None => {}
+ _ => self.buf.push('\n'),
+ }
+ self.buf.push_str(&" ".repeat(self.indent_level));
+ self.needs_indent = false;
+ }
+
+ self.buf.push_str(line);
+ self.needs_indent = line.ends_with('\n');
+ }
+
+ Ok(())
+ }
+}
+
+impl<'a> Printer<'a> {
+ fn indented(&mut self, f: impl FnOnce(&mut Self)) {
+ self.indent_level += 1;
+ wln!(self);
+ f(self);
+ self.indent_level -= 1;
+ self.buf = self.buf.trim_end_matches('\n').to_string();
+ }
+
+ fn whitespace(&mut self) {
+ match self.buf.chars().next_back() {
+ None | Some('\n' | ' ') => {}
+ _ => self.buf.push(' '),
+ }
+ }
+
+ fn newline(&mut self) {
+ match self.buf.chars().rev().skip_while(|ch| *ch == ' ').next() {
+ Some('\n') | None => {}
+ _ => writeln!(self).unwrap(),
+ }
+ }
+
+ fn print_expr(&mut self, expr: ExprId) {
+ let expr = &self.body[expr];
+
+ match expr {
+ Expr::Missing => w!(self, "�"),
+ Expr::Underscore => w!(self, "_"),
+ Expr::Path(path) => self.print_path(path),
+ Expr::If { condition, then_branch, else_branch } => {
+ w!(self, "if ");
+ self.print_expr(*condition);
+ w!(self, " ");
+ self.print_expr(*then_branch);
+ if let Some(els) = *else_branch {
+ w!(self, " else ");
+ self.print_expr(els);
+ }
+ }
+ Expr::Let { pat, expr } => {
+ w!(self, "let ");
+ self.print_pat(*pat);
+ w!(self, " = ");
+ self.print_expr(*expr);
+ }
+ Expr::Loop { body, label } => {
+ if let Some(lbl) = label {
+ w!(self, "{}: ", self.body[*lbl].name);
+ }
+ w!(self, "loop ");
+ self.print_expr(*body);
+ }
+ Expr::While { condition, body, label } => {
+ if let Some(lbl) = label {
+ w!(self, "{}: ", self.body[*lbl].name);
+ }
+ w!(self, "while ");
+ self.print_expr(*condition);
+ self.print_expr(*body);
+ }
+ Expr::For { iterable, pat, body, label } => {
+ if let Some(lbl) = label {
+ w!(self, "{}: ", self.body[*lbl].name);
+ }
+ w!(self, "for ");
+ self.print_pat(*pat);
+ w!(self, " in ");
+ self.print_expr(*iterable);
+ self.print_expr(*body);
+ }
+ Expr::Call { callee, args, is_assignee_expr: _ } => {
+ self.print_expr(*callee);
+ w!(self, "(");
+ if !args.is_empty() {
+ self.indented(|p| {
+ for arg in &**args {
+ p.print_expr(*arg);
+ wln!(p, ",");
+ }
+ });
+ }
+ w!(self, ")");
+ }
+ Expr::MethodCall { receiver, method_name, args, generic_args } => {
+ self.print_expr(*receiver);
+ w!(self, ".{}", method_name);
+ if let Some(args) = generic_args {
+ w!(self, "::<");
+ print_generic_args(args, self).unwrap();
+ w!(self, ">");
+ }
+ w!(self, "(");
+ if !args.is_empty() {
+ self.indented(|p| {
+ for arg in &**args {
+ p.print_expr(*arg);
+ wln!(p, ",");
+ }
+ });
+ }
+ w!(self, ")");
+ }
+ Expr::Match { expr, arms } => {
+ w!(self, "match ");
+ self.print_expr(*expr);
+ w!(self, " {{");
+ self.indented(|p| {
+ for arm in &**arms {
+ p.print_pat(arm.pat);
+ if let Some(guard) = arm.guard {
+ w!(p, " if ");
+ p.print_expr(guard);
+ }
+ w!(p, " => ");
+ p.print_expr(arm.expr);
+ wln!(p, ",");
+ }
+ });
+ wln!(self, "}}");
+ }
+ Expr::Continue { label } => {
+ w!(self, "continue");
+ if let Some(label) = label {
+ w!(self, " {}", label);
+ }
+ }
+ Expr::Break { expr, label } => {
+ w!(self, "break");
+ if let Some(label) = label {
+ w!(self, " {}", label);
+ }
+ if let Some(expr) = expr {
+ self.whitespace();
+ self.print_expr(*expr);
+ }
+ }
+ Expr::Return { expr } => {
+ w!(self, "return");
+ if let Some(expr) = expr {
+ self.whitespace();
+ self.print_expr(*expr);
+ }
+ }
+ Expr::Yield { expr } => {
+ w!(self, "yield");
+ if let Some(expr) = expr {
+ self.whitespace();
+ self.print_expr(*expr);
+ }
+ }
+ Expr::RecordLit { path, fields, spread, ellipsis, is_assignee_expr: _ } => {
+ match path {
+ Some(path) => self.print_path(path),
+ None => w!(self, "�"),
+ }
+
+ w!(self, "{{");
+ self.indented(|p| {
+ for field in &**fields {
+ w!(p, "{}: ", field.name);
+ p.print_expr(field.expr);
+ wln!(p, ",");
+ }
+ if let Some(spread) = spread {
+ w!(p, "..");
+ p.print_expr(*spread);
+ wln!(p);
+ }
+ if *ellipsis {
+ wln!(p, "..");
+ }
+ });
+ w!(self, "}}");
+ }
+ Expr::Field { expr, name } => {
+ self.print_expr(*expr);
+ w!(self, ".{}", name);
+ }
+ Expr::Await { expr } => {
+ self.print_expr(*expr);
+ w!(self, ".await");
+ }
+ Expr::Try { expr } => {
+ self.print_expr(*expr);
+ w!(self, "?");
+ }
+ Expr::TryBlock { body } => {
+ w!(self, "try ");
+ self.print_expr(*body);
+ }
+ Expr::Async { body } => {
+ w!(self, "async ");
+ self.print_expr(*body);
+ }
+ Expr::Const { body } => {
+ w!(self, "const ");
+ self.print_expr(*body);
+ }
+ Expr::Cast { expr, type_ref } => {
+ self.print_expr(*expr);
+ w!(self, " as ");
+ self.print_type_ref(type_ref);
+ }
+ Expr::Ref { expr, rawness, mutability } => {
+ w!(self, "&");
+ if rawness.is_raw() {
+ w!(self, "raw ");
+ }
+ if mutability.is_mut() {
+ w!(self, "mut ");
+ }
+ self.print_expr(*expr);
+ }
+ Expr::Box { expr } => {
+ w!(self, "box ");
+ self.print_expr(*expr);
+ }
+ Expr::UnaryOp { expr, op } => {
+ let op = match op {
+ ast::UnaryOp::Deref => "*",
+ ast::UnaryOp::Not => "!",
+ ast::UnaryOp::Neg => "-",
+ };
+ w!(self, "{}", op);
+ self.print_expr(*expr);
+ }
+ Expr::BinaryOp { lhs, rhs, op } => {
+ let (bra, ket) = match op {
+ None | Some(ast::BinaryOp::Assignment { .. }) => ("", ""),
+ _ => ("(", ")"),
+ };
+ w!(self, "{}", bra);
+ self.print_expr(*lhs);
+ w!(self, "{} ", ket);
+ match op {
+ Some(op) => w!(self, "{}", op),
+ None => w!(self, "�"), // :)
+ }
+ w!(self, " {}", bra);
+ self.print_expr(*rhs);
+ w!(self, "{}", ket);
+ }
+ Expr::Range { lhs, rhs, range_type } => {
+ if let Some(lhs) = lhs {
+ w!(self, "(");
+ self.print_expr(*lhs);
+ w!(self, ") ");
+ }
+ let range = match range_type {
+ ast::RangeOp::Exclusive => "..",
+ ast::RangeOp::Inclusive => "..=",
+ };
+ w!(self, "{}", range);
+ if let Some(rhs) = rhs {
+ w!(self, "(");
+ self.print_expr(*rhs);
+ w!(self, ") ");
+ }
+ }
+ Expr::Index { base, index } => {
+ self.print_expr(*base);
+ w!(self, "[");
+ self.print_expr(*index);
+ w!(self, "]");
+ }
+ Expr::Closure { args, arg_types, ret_type, body } => {
+ w!(self, "|");
+ for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
+ if i != 0 {
+ w!(self, ", ");
+ }
+ self.print_pat(*pat);
+ if let Some(ty) = ty {
+ w!(self, ": ");
+ self.print_type_ref(ty);
+ }
+ }
+ w!(self, "|");
+ if let Some(ret_ty) = ret_type {
+ w!(self, " -> ");
+ self.print_type_ref(ret_ty);
+ }
+ self.whitespace();
+ self.print_expr(*body);
+ }
+ Expr::Tuple { exprs, is_assignee_expr: _ } => {
+ w!(self, "(");
+ for expr in exprs.iter() {
+ self.print_expr(*expr);
+ w!(self, ", ");
+ }
+ w!(self, ")");
+ }
+ Expr::Unsafe { body } => {
+ w!(self, "unsafe ");
+ self.print_expr(*body);
+ }
+ Expr::Array(arr) => {
+ w!(self, "[");
+ if !matches!(arr, Array::ElementList { elements, .. } if elements.is_empty()) {
+ self.indented(|p| match arr {
+ Array::ElementList { elements, is_assignee_expr: _ } => {
+ for elem in elements.iter() {
+ p.print_expr(*elem);
+ w!(p, ", ");
+ }
+ }
+ Array::Repeat { initializer, repeat } => {
+ p.print_expr(*initializer);
+ w!(p, "; ");
+ p.print_expr(*repeat);
+ }
+ });
+ self.newline();
+ }
+ w!(self, "]");
+ }
+ Expr::Literal(lit) => self.print_literal(lit),
+ Expr::Block { id: _, statements, tail, label } => {
+ self.whitespace();
+ if let Some(lbl) = label {
+ w!(self, "{}: ", self.body[*lbl].name);
+ }
+ w!(self, "{{");
+ if !statements.is_empty() || tail.is_some() {
+ self.indented(|p| {
+ for stmt in &**statements {
+ p.print_stmt(stmt);
+ }
+ if let Some(tail) = tail {
+ p.print_expr(*tail);
+ }
+ p.newline();
+ });
+ }
+ w!(self, "}}");
+ }
+ }
+ }
+
+ fn print_pat(&mut self, pat: PatId) {
+ let pat = &self.body[pat];
+
+ match pat {
+ Pat::Missing => w!(self, "�"),
+ Pat::Wild => w!(self, "_"),
+ Pat::Tuple { args, ellipsis } => {
+ w!(self, "(");
+ for (i, pat) in args.iter().enumerate() {
+ if i != 0 {
+ w!(self, ", ");
+ }
+ if *ellipsis == Some(i) {
+ w!(self, ".., ");
+ }
+ self.print_pat(*pat);
+ }
+ w!(self, ")");
+ }
+ Pat::Or(pats) => {
+ for (i, pat) in pats.iter().enumerate() {
+ if i != 0 {
+ w!(self, " | ");
+ }
+ self.print_pat(*pat);
+ }
+ }
+ Pat::Record { path, args, ellipsis } => {
+ match path {
+ Some(path) => self.print_path(path),
+ None => w!(self, "�"),
+ }
+
+ w!(self, " {{");
+ self.indented(|p| {
+ for arg in args.iter() {
+ w!(p, "{}: ", arg.name);
+ p.print_pat(arg.pat);
+ wln!(p, ",");
+ }
+ if *ellipsis {
+ wln!(p, "..");
+ }
+ });
+ w!(self, "}}");
+ }
+ Pat::Range { start, end } => {
+ self.print_expr(*start);
+ w!(self, "...");
+ self.print_expr(*end);
+ }
+ Pat::Slice { prefix, slice, suffix } => {
+ w!(self, "[");
+ for pat in prefix.iter() {
+ self.print_pat(*pat);
+ w!(self, ", ");
+ }
+ if let Some(pat) = slice {
+ self.print_pat(*pat);
+ w!(self, ", ");
+ }
+ for pat in suffix.iter() {
+ self.print_pat(*pat);
+ w!(self, ", ");
+ }
+ w!(self, "]");
+ }
+ Pat::Path(path) => self.print_path(path),
+ Pat::Lit(expr) => self.print_expr(*expr),
+ Pat::Bind { mode, name, subpat } => {
+ let mode = match mode {
+ BindingAnnotation::Unannotated => "",
+ BindingAnnotation::Mutable => "mut ",
+ BindingAnnotation::Ref => "ref ",
+ BindingAnnotation::RefMut => "ref mut ",
+ };
+ w!(self, "{}{}", mode, name);
+ if let Some(pat) = subpat {
+ self.whitespace();
+ self.print_pat(*pat);
+ }
+ }
+ Pat::TupleStruct { path, args, ellipsis } => {
+ match path {
+ Some(path) => self.print_path(path),
+ None => w!(self, "�"),
+ }
+ w!(self, "(");
+ for (i, arg) in args.iter().enumerate() {
+ if i != 0 {
+ w!(self, ", ");
+ }
+ if *ellipsis == Some(i) {
+ w!(self, ", ..");
+ }
+ self.print_pat(*arg);
+ }
+ w!(self, ")");
+ }
+ Pat::Ref { pat, mutability } => {
+ w!(self, "&");
+ if mutability.is_mut() {
+ w!(self, "mut ");
+ }
+ self.print_pat(*pat);
+ }
+ Pat::Box { inner } => {
+ w!(self, "box ");
+ self.print_pat(*inner);
+ }
+ Pat::ConstBlock(c) => {
+ w!(self, "const ");
+ self.print_expr(*c);
+ }
+ }
+ }
+
+ fn print_stmt(&mut self, stmt: &Statement) {
+ match stmt {
+ Statement::Let { pat, type_ref, initializer, else_branch } => {
+ w!(self, "let ");
+ self.print_pat(*pat);
+ if let Some(ty) = type_ref {
+ w!(self, ": ");
+ self.print_type_ref(ty);
+ }
+ if let Some(init) = initializer {
+ w!(self, " = ");
+ self.print_expr(*init);
+ }
+ if let Some(els) = else_branch {
+ w!(self, " else ");
+ self.print_expr(*els);
+ }
+ wln!(self, ";");
+ }
+ Statement::Expr { expr, has_semi } => {
+ self.print_expr(*expr);
+ if *has_semi {
+ w!(self, ";");
+ }
+ wln!(self);
+ }
+ }
+ }
+
+ fn print_literal(&mut self, literal: &Literal) {
+ match literal {
+ Literal::String(it) => w!(self, "{:?}", it),
+ Literal::ByteString(it) => w!(self, "\"{}\"", it.escape_ascii()),
+ Literal::Char(it) => w!(self, "'{}'", it.escape_debug()),
+ Literal::Bool(it) => w!(self, "{}", it),
+ Literal::Int(i, suffix) => {
+ w!(self, "{}", i);
+ if let Some(suffix) = suffix {
+ w!(self, "{}", suffix);
+ }
+ }
+ Literal::Uint(i, suffix) => {
+ w!(self, "{}", i);
+ if let Some(suffix) = suffix {
+ w!(self, "{}", suffix);
+ }
+ }
+ Literal::Float(f, suffix) => {
+ w!(self, "{}", f);
+ if let Some(suffix) = suffix {
+ w!(self, "{}", suffix);
+ }
+ }
+ }
+ }
+
+ fn print_type_ref(&mut self, ty: &TypeRef) {
+ print_type_ref(ty, self).unwrap();
+ }
+
+ fn print_path(&mut self, path: &Path) {
+ print_path(path, self).unwrap();
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
index f4c390dce..45f64ebb0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
@@ -47,16 +47,9 @@ pub struct ScopeData {
impl ExprScopes {
pub(crate) fn expr_scopes_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> {
let body = db.body(def);
- Arc::new(ExprScopes::new(&*body))
- }
-
- fn new(body: &Body) -> ExprScopes {
- let mut scopes =
- ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() };
- let mut root = scopes.root_scope();
- scopes.add_params_bindings(body, root, &body.params);
- compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
- scopes
+ let mut scopes = ExprScopes::new(&*body);
+ scopes.shrink_to_fit();
+ Arc::new(scopes)
}
pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] {
@@ -89,6 +82,17 @@ impl ExprScopes {
pub fn scope_by_expr(&self) -> &FxHashMap<ExprId, ScopeId> {
&self.scope_by_expr
}
+}
+
+impl ExprScopes {
+ fn new(body: &Body) -> ExprScopes {
+ let mut scopes =
+ ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() };
+ let mut root = scopes.root_scope();
+ scopes.add_params_bindings(body, root, &body.params);
+ compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
+ scopes
+ }
fn root_scope(&mut self) -> ScopeId {
self.scopes.alloc(ScopeData { parent: None, block: None, label: None, entries: vec![] })
@@ -138,6 +142,13 @@ impl ExprScopes {
fn set_scope(&mut self, node: ExprId, scope: ScopeId) {
self.scope_by_expr.insert(node, scope);
}
+
+ fn shrink_to_fit(&mut self) {
+ let ExprScopes { scopes, scope_by_expr } = self;
+ scopes.shrink_to_fit();
+ scopes.values_mut().for_each(|it| it.entries.shrink_to_fit());
+ scope_by_expr.shrink_to_fit();
+ }
}
fn compute_block_scopes(
@@ -176,9 +187,6 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
scopes.set_scope(expr, *scope);
match &body[expr] {
- Expr::MacroStmts { statements, tail } => {
- compute_block_scopes(statements, *tail, body, scopes, scope);
- }
Expr::Block { statements, tail, id, label } => {
let mut scope = scopes.new_block_scope(*scope, *id, make_label(label));
// Overwrite the old scope for the block expr, so that every block scope can be found
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs
index 25a408036..dd69c3ab4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs
@@ -156,3 +156,38 @@ impl BuiltinFloat {
Some(res)
}
}
+
+impl fmt::Display for BuiltinInt {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(match self {
+ BuiltinInt::Isize => "isize",
+ BuiltinInt::I8 => "i8",
+ BuiltinInt::I16 => "i16",
+ BuiltinInt::I32 => "i32",
+ BuiltinInt::I64 => "i64",
+ BuiltinInt::I128 => "i128",
+ })
+ }
+}
+
+impl fmt::Display for BuiltinUint {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(match self {
+ BuiltinUint::Usize => "usize",
+ BuiltinUint::U8 => "u8",
+ BuiltinUint::U16 => "u16",
+ BuiltinUint::U32 => "u32",
+ BuiltinUint::U64 => "u64",
+ BuiltinUint::U128 => "u128",
+ })
+ }
+}
+
+impl fmt::Display for BuiltinFloat {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(match self {
+ BuiltinFloat::F32 => "f32",
+ BuiltinFloat::F64 => "f64",
+ })
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 35c870895..631ae3cf1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -2,7 +2,7 @@
use std::sync::Arc;
-use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, MacroCallId, MacroDefKind};
+use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroDefKind};
use smallvec::SmallVec;
use syntax::ast;
@@ -12,7 +12,10 @@ use crate::{
db::DefDatabase,
intern::Interned,
item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, ModItem, Param, TreeId},
- nameres::{attr_resolution::ResolvedAttr, proc_macro::ProcMacroKind, DefMap},
+ nameres::{
+ attr_resolution::ResolvedAttr, diagnostics::DefDiagnostic, proc_macro::ProcMacroKind,
+ DefMap,
+ },
type_ref::{TraitRef, TypeBound, TypeRef},
visibility::RawVisibility,
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -210,6 +213,13 @@ pub struct TraitData {
impl TraitData {
pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> {
+ db.trait_data_with_diagnostics(tr).0
+ }
+
+ pub(crate) fn trait_data_with_diagnostics_query(
+ db: &dyn DefDatabase,
+ tr: TraitId,
+ ) -> (Arc<TraitData>, Arc<Vec<DefDiagnostic>>) {
let tr_loc @ ItemLoc { container: module_id, id: tree_id } = tr.lookup(db);
let item_tree = tree_id.item_tree(db);
let tr_def = &item_tree[tree_id.value];
@@ -229,17 +239,20 @@ impl TraitData {
let mut collector =
AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
- let (items, attribute_calls) = collector.finish();
-
- Arc::new(TraitData {
- name,
- attribute_calls,
- items,
- is_auto,
- is_unsafe,
- visibility,
- skip_array_during_method_dispatch,
- })
+ let (items, attribute_calls, diagnostics) = collector.finish();
+
+ (
+ Arc::new(TraitData {
+ name,
+ attribute_calls,
+ items,
+ is_auto,
+ is_unsafe,
+ visibility,
+ skip_array_during_method_dispatch,
+ }),
+ Arc::new(diagnostics),
+ )
}
pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
@@ -280,7 +293,14 @@ pub struct ImplData {
impl ImplData {
pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc<ImplData> {
- let _p = profile::span("impl_data_query");
+ db.impl_data_with_diagnostics(id).0
+ }
+
+ pub(crate) fn impl_data_with_diagnostics_query(
+ db: &dyn DefDatabase,
+ id: ImplId,
+ ) -> (Arc<ImplData>, Arc<Vec<DefDiagnostic>>) {
+ let _p = profile::span("impl_data_with_diagnostics_query");
let ItemLoc { container: module_id, id: tree_id } = id.lookup(db);
let item_tree = tree_id.item_tree(db);
@@ -293,10 +313,13 @@ impl ImplData {
AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::ImplId(id));
collector.collect(&item_tree, tree_id.tree_id(), &impl_def.items);
- let (items, attribute_calls) = collector.finish();
+ let (items, attribute_calls, diagnostics) = collector.finish();
let items = items.into_iter().map(|(_, item)| item).collect();
- Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls })
+ (
+ Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls }),
+ Arc::new(diagnostics),
+ )
}
pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
@@ -437,6 +460,7 @@ struct AssocItemCollector<'a> {
db: &'a dyn DefDatabase,
module_id: ModuleId,
def_map: Arc<DefMap>,
+ inactive_diagnostics: Vec<DefDiagnostic>,
container: ItemContainerId,
expander: Expander,
@@ -459,15 +483,21 @@ impl<'a> AssocItemCollector<'a> {
expander: Expander::new(db, file_id, module_id),
items: Vec::new(),
attr_calls: Vec::new(),
+ inactive_diagnostics: Vec::new(),
}
}
fn finish(
self,
- ) -> (Vec<(Name, AssocItemId)>, Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>) {
+ ) -> (
+ Vec<(Name, AssocItemId)>,
+ Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
+ Vec<DefDiagnostic>,
+ ) {
(
self.items,
if self.attr_calls.is_empty() { None } else { Some(Box::new(self.attr_calls)) },
+ self.inactive_diagnostics,
)
}
@@ -479,6 +509,12 @@ impl<'a> AssocItemCollector<'a> {
'items: for &item in assoc_items {
let attrs = item_tree.attrs(self.db, self.module_id.krate, ModItem::from(item).into());
if !attrs.is_cfg_enabled(self.expander.cfg_options()) {
+ self.inactive_diagnostics.push(DefDiagnostic::unconfigured_code(
+ self.module_id.local_id,
+ InFile::new(self.expander.current_file_id(), item.ast_id(&item_tree).upcast()),
+ attrs.cfg().unwrap(),
+ self.expander.cfg_options().clone(),
+ ));
continue;
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index df6dcb024..40b2f734b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -20,7 +20,7 @@ use crate::{
intern::Interned,
item_tree::{AttrOwner, ItemTree},
lang_item::{LangItemTarget, LangItems},
- nameres::DefMap,
+ nameres::{diagnostics::DefDiagnostic, DefMap},
visibility::{self, Visibility},
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
@@ -106,9 +106,16 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
#[salsa::invoke(ImplData::impl_data_query)]
fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
+ #[salsa::invoke(ImplData::impl_data_with_diagnostics_query)]
+ fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc<ImplData>, Arc<Vec<DefDiagnostic>>);
+
#[salsa::invoke(TraitData::trait_data_query)]
fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
+ #[salsa::invoke(TraitData::trait_data_with_diagnostics_query)]
+ fn trait_data_with_diagnostics(&self, tr: TraitId)
+ -> (Arc<TraitData>, Arc<Vec<DefDiagnostic>>);
+
#[salsa::invoke(TypeAliasData::type_alias_data_query)]
fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr.rs
index c1b3788ac..419d3feec 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr.rs
@@ -12,6 +12,8 @@
//!
//! See also a neighboring `body` module.
+use std::fmt;
+
use hir_expand::name::Name;
use la_arena::{Idx, RawIdx};
@@ -52,8 +54,8 @@ impl FloatTypeWrapper {
}
}
-impl std::fmt::Display for FloatTypeWrapper {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl fmt::Display for FloatTypeWrapper {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", f64::from_bits(self.0))
}
}
@@ -204,10 +206,6 @@ pub enum Expr {
Unsafe {
body: ExprId,
},
- MacroStmts {
- statements: Box<[Statement]>,
- tail: Option<ExprId>,
- },
Array(Array),
Literal(Literal),
Underscore,
@@ -261,7 +259,7 @@ impl Expr {
Expr::Let { expr, .. } => {
f(*expr);
}
- Expr::MacroStmts { tail, statements } | Expr::Block { statements, tail, .. } => {
+ Expr::Block { statements, tail, .. } => {
for stmt in statements.iter() {
match stmt {
Statement::Let { initializer, .. } => {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
index 2397cf501..469b28c2d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
@@ -451,7 +451,7 @@ impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
if let GenericDefId::TraitId(id) = *self {
let trait_ref = id.lookup(db).source(db).value;
let idx = idx_iter.next().unwrap();
- params.insert(idx, Either::Right(trait_ref))
+ params.insert(idx, Either::Right(trait_ref));
}
if let Some(generic_params_list) = generic_params_list {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index 375587ee9..3342d4db4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -14,7 +14,7 @@
//! unaffected, so we don't have to recompute name resolution results or item data (see `data.rs`).
//!
//! The `ItemTree` for the currently open file can be displayed by using the VS Code command
-//! "Rust Analyzer: Debug ItemTree".
+//! "rust-analyzer: Debug ItemTree".
//!
//! Compared to rustc's architecture, `ItemTree` has properties from both rustc's AST and HIR: many
//! syntax-level Rust features are already desugared to simpler forms in the `ItemTree`, but name
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index f12d9a127..34dd817fd 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -2,13 +2,10 @@
use std::fmt::{self, Write};
-use itertools::Itertools;
-
use crate::{
attr::RawAttrs,
generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget},
- path::GenericArg,
- type_ref::TraitBoundModifier,
+ pretty::{print_path, print_type_bounds, print_type_ref},
visibility::RawVisibility,
};
@@ -464,183 +461,15 @@ impl<'a> Printer<'a> {
}
fn print_type_ref(&mut self, type_ref: &TypeRef) {
- // FIXME: deduplicate with `HirDisplay` impl
- match type_ref {
- TypeRef::Never => w!(self, "!"),
- TypeRef::Placeholder => w!(self, "_"),
- TypeRef::Tuple(fields) => {
- w!(self, "(");
- for (i, field) in fields.iter().enumerate() {
- if i != 0 {
- w!(self, ", ");
- }
- self.print_type_ref(field);
- }
- w!(self, ")");
- }
- TypeRef::Path(path) => self.print_path(path),
- TypeRef::RawPtr(pointee, mtbl) => {
- let mtbl = match mtbl {
- Mutability::Shared => "*const",
- Mutability::Mut => "*mut",
- };
- w!(self, "{} ", mtbl);
- self.print_type_ref(pointee);
- }
- TypeRef::Reference(pointee, lt, mtbl) => {
- let mtbl = match mtbl {
- Mutability::Shared => "",
- Mutability::Mut => "mut ",
- };
- w!(self, "&");
- if let Some(lt) = lt {
- w!(self, "{} ", lt.name);
- }
- w!(self, "{}", mtbl);
- self.print_type_ref(pointee);
- }
- TypeRef::Array(elem, len) => {
- w!(self, "[");
- self.print_type_ref(elem);
- w!(self, "; {}]", len);
- }
- TypeRef::Slice(elem) => {
- w!(self, "[");
- self.print_type_ref(elem);
- w!(self, "]");
- }
- TypeRef::Fn(args_and_ret, varargs) => {
- let ((_, return_type), args) =
- args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
- w!(self, "fn(");
- for (i, (_, typeref)) in args.iter().enumerate() {
- if i != 0 {
- w!(self, ", ");
- }
- self.print_type_ref(typeref);
- }
- if *varargs {
- if !args.is_empty() {
- w!(self, ", ");
- }
- w!(self, "...");
- }
- w!(self, ") -> ");
- self.print_type_ref(return_type);
- }
- TypeRef::Macro(_ast_id) => {
- w!(self, "<macro>");
- }
- TypeRef::Error => w!(self, "{{unknown}}"),
- TypeRef::ImplTrait(bounds) => {
- w!(self, "impl ");
- self.print_type_bounds(bounds);
- }
- TypeRef::DynTrait(bounds) => {
- w!(self, "dyn ");
- self.print_type_bounds(bounds);
- }
- }
+ print_type_ref(type_ref, self).unwrap();
}
fn print_type_bounds(&mut self, bounds: &[Interned<TypeBound>]) {
- for (i, bound) in bounds.iter().enumerate() {
- if i != 0 {
- w!(self, " + ");
- }
-
- match bound.as_ref() {
- TypeBound::Path(path, modifier) => {
- match modifier {
- TraitBoundModifier::None => (),
- TraitBoundModifier::Maybe => w!(self, "?"),
- }
- self.print_path(path)
- }
- TypeBound::ForLifetime(lifetimes, path) => {
- w!(self, "for<{}> ", lifetimes.iter().format(", "));
- self.print_path(path);
- }
- TypeBound::Lifetime(lt) => w!(self, "{}", lt.name),
- TypeBound::Error => w!(self, "{{unknown}}"),
- }
- }
+ print_type_bounds(bounds, self).unwrap();
}
fn print_path(&mut self, path: &Path) {
- match path.type_anchor() {
- Some(anchor) => {
- w!(self, "<");
- self.print_type_ref(anchor);
- w!(self, ">::");
- }
- None => match path.kind() {
- PathKind::Plain => {}
- PathKind::Super(0) => w!(self, "self::"),
- PathKind::Super(n) => {
- for _ in 0..*n {
- w!(self, "super::");
- }
- }
- PathKind::Crate => w!(self, "crate::"),
- PathKind::Abs => w!(self, "::"),
- PathKind::DollarCrate(_) => w!(self, "$crate::"),
- },
- }
-
- for (i, segment) in path.segments().iter().enumerate() {
- if i != 0 {
- w!(self, "::");
- }
-
- w!(self, "{}", segment.name);
- if let Some(generics) = segment.args_and_bindings {
- // NB: these are all in type position, so `::<` turbofish syntax is not necessary
- w!(self, "<");
- let mut first = true;
- let args = if generics.has_self_type {
- let (self_ty, args) = generics.args.split_first().unwrap();
- w!(self, "Self=");
- self.print_generic_arg(self_ty);
- first = false;
- args
- } else {
- &generics.args
- };
- for arg in args {
- if !first {
- w!(self, ", ");
- }
- first = false;
- self.print_generic_arg(arg);
- }
- for binding in &generics.bindings {
- if !first {
- w!(self, ", ");
- }
- first = false;
- w!(self, "{}", binding.name);
- if !binding.bounds.is_empty() {
- w!(self, ": ");
- self.print_type_bounds(&binding.bounds);
- }
- if let Some(ty) = &binding.type_ref {
- w!(self, " = ");
- self.print_type_ref(ty);
- }
- }
-
- w!(self, ">");
- }
- }
- }
-
- fn print_generic_arg(&mut self, arg: &GenericArg) {
- match arg {
- GenericArg::Type(ty) => self.print_type_ref(ty),
- GenericArg::Const(c) => w!(self, "{}", c),
- GenericArg::Lifetime(lt) => w!(self, "{}", lt.name),
- }
+ print_path(path, self).unwrap();
}
fn print_generic_params(&mut self, params: &GenericParams) {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
index 5cdf36cc6..e30d9652b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
@@ -283,10 +283,10 @@ struct S {
"#,
expect![[r#"
pub(self) struct S {
- pub(self) a: Mixed<'a, T, Item = (), OtherItem = u8>,
- pub(self) b: Qualified<Self=Fully>::Syntax,
- pub(self) c: <TypeAnchored>::Path<'a>,
- pub(self) d: dyn for<'a> Trait<'a>,
+ pub(self) a: Mixed::<'a, T, Item = (), OtherItem = u8>,
+ pub(self) b: Qualified::<Self=Fully>::Syntax,
+ pub(self) c: <TypeAnchored>::Path::<'a>,
+ pub(self) d: dyn for<'a> Trait::<'a>,
}
"#]],
)
@@ -329,7 +329,7 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
T: Copy,
U: ?Sized;
- impl<'a, 'b, T, const K: u8> S<'a, 'b, T, K>
+ impl<'a, 'b, T, const K: u8> S::<'a, 'b, T, K>
where
T: Copy,
T: 'a,
@@ -352,7 +352,7 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
where
Self: Super,
T: 'a,
- Self: for<'a> Tr<'a, T>
+ Self: for<'a> Tr::<'a, T>
{
}
"#]],
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 56603f4b1..32ebfda4f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -53,6 +53,7 @@ pub mod import_map;
mod test_db;
#[cfg(test)]
mod macro_expansion_tests;
+mod pretty;
use std::{
hash::{Hash, Hasher},
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 92dffa7f3..4f626105a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -295,13 +295,13 @@ fn test_concat_expand() {
#[rustc_builtin_macro]
macro_rules! concat {}
-fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false); }
+fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false, '"', '\0'); }
"##,
expect![[r##"
#[rustc_builtin_macro]
macro_rules! concat {}
-fn main() { "foor0bar\nfalse"; }
+fn main() { "foor0bar\nfalse\"\u{0}"; }
"##]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
index 30d39d52f..457e43925 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -885,7 +885,7 @@ macro_rules! m {
($t:ty) => ( fn bar() -> $ t {} )
}
-fn bar() -> & 'a Baz<u8> {}
+fn bar() -> &'a Baz<u8> {}
fn bar() -> extern "Rust"fn() -> Ret {}
"#]],
@@ -1578,7 +1578,7 @@ macro_rules !register_methods {
($$($val: expr), *) = > {
struct Foo;
impl Foo {
- $(fn $method()-> & 'static[u32] {
+ $(fn $method()-> &'static[u32] {
&[$$($$val), *]
}
)*
@@ -1591,10 +1591,10 @@ macro_rules !implement_methods {
($($val: expr), *) = > {
struct Foo;
impl Foo {
- fn alpha()-> & 'static[u32] {
+ fn alpha()-> &'static[u32] {
&[$($val), *]
}
- fn beta()-> & 'static[u32] {
+ fn beta()-> &'static[u32] {
&[$($val), *]
}
}
@@ -1602,10 +1602,10 @@ macro_rules !implement_methods {
}
struct Foo;
impl Foo {
- fn alpha() -> & 'static[u32] {
+ fn alpha() -> &'static[u32] {
&[1, 2, 3]
}
- fn beta() -> & 'static[u32] {
+ fn beta() -> &'static[u32] {
&[1, 2, 3]
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index 2dff4adf2..d2505e7ca 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -166,7 +166,7 @@ macro_rules! int_base {
}
}
#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Binary for isize {
- fn fmt(&self , f: &mut fmt::Formatter< '_>) -> fmt::Result {
+ fn fmt(&self , f: &mut fmt::Formatter<'_>) -> fmt::Result {
Binary.fmt_int(*self as usize, f)
}
}
@@ -724,7 +724,7 @@ macro_rules! delegate_impl {
}
}
}
-impl <> Data for & 'amut G where G: Data {}
+impl <> Data for &'amut G where G: Data {}
"##]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
index 0710b1ac3..b8d2ca687 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -78,7 +78,7 @@ m!(static bar: &'static str = "hello";);
macro_rules! m {
($($t:tt)*) => { $($t)*}
}
-static bar: & 'static str = "hello";
+static bar: &'static str = "hello";
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
index 72c44a0fb..029821e5e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
@@ -87,7 +87,7 @@ fn foo() { bar.; blub }
fn foo() { bar.; blub }
fn foo() {
- bar. ;
+ bar.;
blub
}"##]],
);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index 6eb530ecc..9b4ce9f97 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -64,7 +64,7 @@ use hir_expand::{name::Name, InFile, MacroCallId, MacroDefId};
use itertools::Itertools;
use la_arena::Arena;
use profile::Count;
-use rustc_hash::FxHashMap;
+use rustc_hash::{FxHashMap, FxHashSet};
use stdx::format_to;
use syntax::{ast, SmolStr};
@@ -98,7 +98,11 @@ pub struct DefMap {
/// The prelude module for this crate. This either comes from an import
/// marked with the `prelude_import` attribute, or (in the normal case) from
/// a dependency (`std` or `core`).
+ /// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
+ /// but that attribute is nightly and when used in a block, it affects resolution globally
+ /// so we aren't handling this correctly anyways).
prelude: Option<ModuleId>,
+ /// The extern prelude is only populated for non-block DefMaps
extern_prelude: FxHashMap<Name, ModuleId>,
/// Side table for resolving derive helpers.
@@ -114,6 +118,8 @@ pub struct DefMap {
registered_attrs: Vec<SmolStr>,
/// Custom tool modules registered with `#![register_tool]`.
registered_tools: Vec<SmolStr>,
+ /// Unstable features of Rust enabled with `#![feature(A, B)]`.
+ unstable_features: FxHashSet<SmolStr>,
edition: Edition,
recursion_limit: Option<u32>,
@@ -284,6 +290,7 @@ impl DefMap {
modules,
registered_attrs: Vec::new(),
registered_tools: Vec::new(),
+ unstable_features: FxHashSet::default(),
diagnostics: Vec::new(),
}
}
@@ -314,6 +321,10 @@ impl DefMap {
&self.registered_attrs
}
+ pub fn is_unstable_feature_enabled(&self, feature: &str) -> bool {
+ self.unstable_features.contains(feature)
+ }
+
pub fn root(&self) -> LocalModuleId {
self.root
}
@@ -479,6 +490,7 @@ impl DefMap {
registered_tools,
fn_proc_macro_mapping,
derive_helpers_in_scope,
+ unstable_features,
proc_macro_loading_error: _,
block: _,
edition: _,
@@ -496,6 +508,7 @@ impl DefMap {
registered_tools.shrink_to_fit();
fn_proc_macro_mapping.shrink_to_fit();
derive_helpers_in_scope.shrink_to_fit();
+ unstable_features.shrink_to_fit();
for (_, module) in modules.iter_mut() {
module.children.shrink_to_fit();
module.scope.shrink_to_fit();
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 8a6bb929c..495bbe457 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -294,6 +294,17 @@ impl DefCollector<'_> {
continue;
}
+ if *attr_name == hir_expand::name![feature] {
+ let features =
+ attr.parse_path_comma_token_tree().into_iter().flatten().filter_map(
+ |feat| match feat.segments() {
+ [name] => Some(name.to_smol_str()),
+ _ => None,
+ },
+ );
+ self.def_map.unstable_features.extend(features);
+ }
+
let attr_is_register_like = *attr_name == hir_expand::name![register_attr]
|| *attr_name == hir_expand::name![register_tool];
if !attr_is_register_like {
@@ -501,10 +512,9 @@ impl DefCollector<'_> {
Edition::Edition2021 => name![rust_2021],
};
- let path_kind = if self.def_map.edition == Edition::Edition2015 {
- PathKind::Plain
- } else {
- PathKind::Abs
+ let path_kind = match self.def_map.edition {
+ Edition::Edition2015 => PathKind::Plain,
+ _ => PathKind::Abs,
};
let path =
ModPath::from_segments(path_kind, [krate.clone(), name![prelude], edition].into_iter());
@@ -524,7 +534,6 @@ impl DefCollector<'_> {
match per_ns.types {
Some((ModuleDefId::ModuleId(m), _)) => {
self.def_map.prelude = Some(m);
- return;
}
types => {
tracing::debug!(
@@ -839,7 +848,10 @@ impl DefCollector<'_> {
tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
- if import.is_extern_crate && module_id == self.def_map.root {
+ if import.is_extern_crate
+ && self.def_map.block.is_none()
+ && module_id == self.def_map.root
+ {
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
{
self.def_map.extern_prelude.insert(name.clone(), def);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs
index 0d01f6d0a..ed7e920fd 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs
@@ -73,7 +73,7 @@ impl DefDiagnostic {
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { id, index } }
}
- pub(super) fn unconfigured_code(
+ pub fn unconfigured_code(
container: LocalModuleId,
ast: AstId<ast::Item>,
cfg: CfgExpr,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
index 52a620fe2..ca7bcc814 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
@@ -65,6 +65,7 @@ impl ModDir {
name: &Name,
attr_path: Option<&SmolStr>,
) -> Result<(FileId, bool, ModDir), Box<[String]>> {
+ let name = name.unescaped();
let orig_file_id = file_id.original_file(db.upcast());
let mut candidate_files = ArrayVec::<_, 2>::new();
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
index c579bc919..8dfda6df6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
@@ -399,14 +399,15 @@ impl DefMap {
Some(_) | None => from_scope.or(from_builtin),
},
};
- let from_extern_prelude = self
- .extern_prelude
- .get(name)
- .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public));
- let from_prelude = self.resolve_in_prelude(db, name);
+ let extern_prelude = || {
+ self.extern_prelude
+ .get(name)
+ .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
+ };
+ let prelude = || self.resolve_in_prelude(db, name);
- from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude)
+ from_legacy_macro.or(from_scope_or_builtin).or_else(extern_prelude).or_else(prelude)
}
fn resolve_name_in_crate_root_or_extern_prelude(
@@ -414,20 +415,19 @@ impl DefMap {
db: &dyn DefDatabase,
name: &Name,
) -> PerNs {
- let arc;
- let crate_def_map = match self.block {
+ let from_crate_root = match self.block {
Some(_) => {
- arc = self.crate_root(db).def_map(db);
- &arc
+ let def_map = self.crate_root(db).def_map(db);
+ def_map[def_map.root].scope.get(name)
}
- None => self,
+ None => self[self.root].scope.get(name),
+ };
+ let from_extern_prelude = || {
+ self.resolve_name_in_extern_prelude(db, name)
+ .map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
};
- let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name);
- let from_extern_prelude = self
- .resolve_name_in_extern_prelude(db, name)
- .map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public));
- from_crate_root.or(from_extern_prelude)
+ from_crate_root.or_else(from_extern_prelude)
}
fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs
index 5089ef2d8..52b79cd0f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs
@@ -45,7 +45,7 @@ impl Attrs {
kind: ProcMacroKind::CustomDerive { helpers: Box::new([]) },
}),
- // `#[proc_macro_derive(Trait, attibutes(helper1, helper2, ...))]`
+ // `#[proc_macro_derive(Trait, attributes(helper1, helper2, ...))]`
[
TokenTree::Leaf(Leaf::Ident(trait_name)),
TokenTree::Leaf(Leaf::Punct(comma)),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
index 79a74873b..ba3bf8b5a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
@@ -127,15 +127,31 @@ mod r#async;
use self::r#async::Bar;
//- /async.rs
+mod foo;
+mod r#async;
pub struct Bar;
+
+//- /async/foo.rs
+pub struct Foo;
+
+//- /async/async.rs
+pub struct Baz;
"#,
expect![[r#"
crate
Bar: t v
- async: t
+ r#async: t
- crate::async
+ crate::r#async
Bar: t v
+ foo: t
+ r#async: t
+
+ crate::r#async::foo
+ Foo: t v
+
+ crate::r#async::r#async
+ Baz: t v
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
index bf5bf10c4..2bc1f8e92 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
@@ -43,6 +43,10 @@ impl PerNs {
self.types.is_none() && self.values.is_none() && self.macros.is_none()
}
+ pub fn is_full(&self) -> bool {
+ self.types.is_some() && self.values.is_some() && self.macros.is_some()
+ }
+
pub fn take_types(self) -> Option<ModuleDefId> {
self.types.map(|it| it.0)
}
@@ -84,6 +88,14 @@ impl PerNs {
}
}
+ pub fn or_else(self, f: impl FnOnce() -> PerNs) -> PerNs {
+ if self.is_full() {
+ self
+ } else {
+ self.or(f())
+ }
+ }
+
pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
let _p = profile::span("PerNs::iter_items");
self.types
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
new file mode 100644
index 000000000..6636c8a23
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
@@ -0,0 +1,209 @@
+//! Display and pretty printing routines.
+
+use std::fmt::{self, Write};
+
+use hir_expand::mod_path::PathKind;
+use itertools::Itertools;
+
+use crate::{
+ intern::Interned,
+ path::{GenericArg, GenericArgs, Path},
+ type_ref::{Mutability, TraitBoundModifier, TypeBound, TypeRef},
+};
+
+pub(crate) fn print_path(path: &Path, buf: &mut dyn Write) -> fmt::Result {
+ match path.type_anchor() {
+ Some(anchor) => {
+ write!(buf, "<")?;
+ print_type_ref(anchor, buf)?;
+ write!(buf, ">::")?;
+ }
+ None => match path.kind() {
+ PathKind::Plain => {}
+ PathKind::Super(0) => write!(buf, "self")?,
+ PathKind::Super(n) => {
+ for i in 0..*n {
+ if i == 0 {
+ buf.write_str("super")?;
+ } else {
+ buf.write_str("::super")?;
+ }
+ }
+ }
+ PathKind::Crate => write!(buf, "crate")?,
+ PathKind::Abs => {}
+ PathKind::DollarCrate(_) => write!(buf, "$crate")?,
+ },
+ }
+
+ for (i, segment) in path.segments().iter().enumerate() {
+ if i != 0 || !matches!(path.kind(), PathKind::Plain) {
+ write!(buf, "::")?;
+ }
+
+ write!(buf, "{}", segment.name)?;
+ if let Some(generics) = segment.args_and_bindings {
+ write!(buf, "::<")?;
+ print_generic_args(generics, buf)?;
+
+ write!(buf, ">")?;
+ }
+ }
+
+ Ok(())
+}
+
+pub(crate) fn print_generic_args(generics: &GenericArgs, buf: &mut dyn Write) -> fmt::Result {
+ let mut first = true;
+ let args = if generics.has_self_type {
+ let (self_ty, args) = generics.args.split_first().unwrap();
+ write!(buf, "Self=")?;
+ print_generic_arg(self_ty, buf)?;
+ first = false;
+ args
+ } else {
+ &generics.args
+ };
+ for arg in args {
+ if !first {
+ write!(buf, ", ")?;
+ }
+ first = false;
+ print_generic_arg(arg, buf)?;
+ }
+ for binding in &generics.bindings {
+ if !first {
+ write!(buf, ", ")?;
+ }
+ first = false;
+ write!(buf, "{}", binding.name)?;
+ if !binding.bounds.is_empty() {
+ write!(buf, ": ")?;
+ print_type_bounds(&binding.bounds, buf)?;
+ }
+ if let Some(ty) = &binding.type_ref {
+ write!(buf, " = ")?;
+ print_type_ref(ty, buf)?;
+ }
+ }
+ Ok(())
+}
+
+pub(crate) fn print_generic_arg(arg: &GenericArg, buf: &mut dyn Write) -> fmt::Result {
+ match arg {
+ GenericArg::Type(ty) => print_type_ref(ty, buf),
+ GenericArg::Const(c) => write!(buf, "{}", c),
+ GenericArg::Lifetime(lt) => write!(buf, "{}", lt.name),
+ }
+}
+
+pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Result {
+ // FIXME: deduplicate with `HirDisplay` impl
+ match type_ref {
+ TypeRef::Never => write!(buf, "!")?,
+ TypeRef::Placeholder => write!(buf, "_")?,
+ TypeRef::Tuple(fields) => {
+ write!(buf, "(")?;
+ for (i, field) in fields.iter().enumerate() {
+ if i != 0 {
+ write!(buf, ", ")?;
+ }
+ print_type_ref(field, buf)?;
+ }
+ write!(buf, ")")?;
+ }
+ TypeRef::Path(path) => print_path(path, buf)?,
+ TypeRef::RawPtr(pointee, mtbl) => {
+ let mtbl = match mtbl {
+ Mutability::Shared => "*const",
+ Mutability::Mut => "*mut",
+ };
+ write!(buf, "{} ", mtbl)?;
+ print_type_ref(pointee, buf)?;
+ }
+ TypeRef::Reference(pointee, lt, mtbl) => {
+ let mtbl = match mtbl {
+ Mutability::Shared => "",
+ Mutability::Mut => "mut ",
+ };
+ write!(buf, "&")?;
+ if let Some(lt) = lt {
+ write!(buf, "{} ", lt.name)?;
+ }
+ write!(buf, "{}", mtbl)?;
+ print_type_ref(pointee, buf)?;
+ }
+ TypeRef::Array(elem, len) => {
+ write!(buf, "[")?;
+ print_type_ref(elem, buf)?;
+ write!(buf, "; {}]", len)?;
+ }
+ TypeRef::Slice(elem) => {
+ write!(buf, "[")?;
+ print_type_ref(elem, buf)?;
+ write!(buf, "]")?;
+ }
+ TypeRef::Fn(args_and_ret, varargs) => {
+ let ((_, return_type), args) =
+ args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
+ write!(buf, "fn(")?;
+ for (i, (_, typeref)) in args.iter().enumerate() {
+ if i != 0 {
+ write!(buf, ", ")?;
+ }
+ print_type_ref(typeref, buf)?;
+ }
+ if *varargs {
+ if !args.is_empty() {
+ write!(buf, ", ")?;
+ }
+ write!(buf, "...")?;
+ }
+ write!(buf, ") -> ")?;
+ print_type_ref(return_type, buf)?;
+ }
+ TypeRef::Macro(_ast_id) => {
+ write!(buf, "<macro>")?;
+ }
+ TypeRef::Error => write!(buf, "{{unknown}}")?,
+ TypeRef::ImplTrait(bounds) => {
+ write!(buf, "impl ")?;
+ print_type_bounds(bounds, buf)?;
+ }
+ TypeRef::DynTrait(bounds) => {
+ write!(buf, "dyn ")?;
+ print_type_bounds(bounds, buf)?;
+ }
+ }
+
+ Ok(())
+}
+
+pub(crate) fn print_type_bounds(
+ bounds: &[Interned<TypeBound>],
+ buf: &mut dyn Write,
+) -> fmt::Result {
+ for (i, bound) in bounds.iter().enumerate() {
+ if i != 0 {
+ write!(buf, " + ")?;
+ }
+
+ match bound.as_ref() {
+ TypeBound::Path(path, modifier) => {
+ match modifier {
+ TraitBoundModifier::None => (),
+ TraitBoundModifier::Maybe => write!(buf, "?")?,
+ }
+ print_path(path, buf)?;
+ }
+ TypeBound::ForLifetime(lifetimes, path) => {
+ write!(buf, "for<{}> ", lifetimes.iter().format(", "))?;
+ print_path(path, buf)?;
+ }
+ TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name)?,
+ TypeBound::Error => write!(buf, "{{unknown}}")?,
+ }
+ }
+
+ Ok(())
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 3163fa0f9..8aa5973ca 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -31,12 +31,10 @@ pub struct Resolver {
///
/// When using, you generally want to process the scopes in reverse order,
/// there's `scopes` *method* for that.
- ///
- /// Invariant: There exists at least one Scope::ModuleScope at the start of the vec.
scopes: Vec<Scope>,
+ module_scope: ModuleItemMap,
}
-// FIXME how to store these best
#[derive(Debug, Clone)]
struct ModuleItemMap {
def_map: Arc<DefMap>,
@@ -53,7 +51,7 @@ struct ExprScope {
#[derive(Debug, Clone)]
enum Scope {
/// All the items and imported names of a module
- ModuleScope(ModuleItemMap),
+ BlockScope(ModuleItemMap),
/// Brings the generic parameters of an item into scope
GenericParams { def: GenericDefId, params: Interned<GenericParams> },
/// Brings `Self` in `impl` block into scope
@@ -127,24 +125,6 @@ impl Resolver {
}
}
- fn scopes(&self) -> impl Iterator<Item = &Scope> {
- self.scopes.iter().rev()
- }
-
- fn resolve_module_path(
- &self,
- db: &dyn DefDatabase,
- path: &ModPath,
- shadow: BuiltinShadowMode,
- ) -> PerNs {
- let (item_map, module) = self.module_scope();
- let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow);
- if segment_index.is_some() {
- return PerNs::none();
- }
- module_res
- }
-
pub fn resolve_module_path_in_items(&self, db: &dyn DefDatabase, path: &ModPath) -> PerNs {
self.resolve_module_path(db, path, BuiltinShadowMode::Module)
}
@@ -155,7 +135,7 @@ impl Resolver {
db: &dyn DefDatabase,
path: &ModPath,
) -> Option<PerNs> {
- let (item_map, module) = self.module_scope();
+ let (item_map, module) = self.item_scope();
let (module_res, idx) = item_map.resolve_path(db, module, path, BuiltinShadowMode::Module);
match module_res.take_types()? {
ModuleDefId::TraitId(it) => {
@@ -183,37 +163,38 @@ impl Resolver {
) -> Option<(TypeNs, Option<usize>)> {
let first_name = path.segments().first()?;
let skip_to_mod = path.kind != PathKind::Plain;
+ if skip_to_mod {
+ return self.module_scope.resolve_path_in_type_ns(db, path);
+ }
+
+ let remaining_idx = || if path.segments().len() == 1 { None } else { Some(1) };
+
for scope in self.scopes() {
match scope {
Scope::ExprScope(_) => continue,
- Scope::GenericParams { .. } | Scope::ImplDefScope(_) if skip_to_mod => continue,
-
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_type_by_name(first_name, *def) {
- let idx = if path.segments().len() == 1 { None } else { Some(1) };
- return Some((TypeNs::GenericParam(id), idx));
+ return Some((TypeNs::GenericParam(id), remaining_idx()));
}
}
- Scope::ImplDefScope(impl_) => {
+ &Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- let idx = if path.segments().len() == 1 { None } else { Some(1) };
- return Some((TypeNs::SelfType(*impl_), idx));
+ return Some((TypeNs::SelfType(impl_), remaining_idx()));
}
}
- Scope::AdtScope(adt) => {
+ &Scope::AdtScope(adt) => {
if first_name == &name![Self] {
- let idx = if path.segments().len() == 1 { None } else { Some(1) };
- return Some((TypeNs::AdtSelfType(*adt), idx));
+ return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
}
}
- Scope::ModuleScope(m) => {
+ Scope::BlockScope(m) => {
if let Some(res) = m.resolve_path_in_type_ns(db, path) {
return Some(res);
}
}
}
}
- None
+ self.module_scope.resolve_path_in_type_ns(db, path)
}
pub fn resolve_path_in_type_ns_fully(
@@ -235,7 +216,7 @@ impl Resolver {
) -> Option<Visibility> {
match visibility {
RawVisibility::Module(_) => {
- let (item_map, module) = self.module_scope();
+ let (item_map, module) = self.item_scope();
item_map.resolve_visibility(db, module, visibility)
}
RawVisibility::Public => Some(Visibility::Public),
@@ -251,18 +232,14 @@ impl Resolver {
let tmp = name![self];
let first_name = if path.is_self() { &tmp } else { path.segments().first()? };
let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
+ if skip_to_mod {
+ return self.module_scope.resolve_path_in_value_ns(db, path);
+ }
+
for scope in self.scopes() {
match scope {
- Scope::AdtScope(_)
- | Scope::ExprScope(_)
- | Scope::GenericParams { .. }
- | Scope::ImplDefScope(_)
- if skip_to_mod =>
- {
- continue
- }
-
- Scope::ExprScope(scope) if n_segments <= 1 => {
+ Scope::ExprScope(_) if n_segments > 1 => continue,
+ Scope::ExprScope(scope) => {
let entry = scope
.expr_scopes
.entries(scope.scope_id)
@@ -273,44 +250,39 @@ impl Resolver {
return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.pat())));
}
}
- Scope::ExprScope(_) => continue,
-
Scope::GenericParams { params, def } if n_segments > 1 => {
if let Some(id) = params.find_type_by_name(first_name, *def) {
let ty = TypeNs::GenericParam(id);
return Some(ResolveValueResult::Partial(ty, 1));
}
}
- Scope::GenericParams { params, def } if n_segments == 1 => {
+ Scope::GenericParams { .. } if n_segments != 1 => continue,
+ Scope::GenericParams { params, def } => {
if let Some(id) = params.find_const_by_name(first_name, *def) {
let val = ValueNs::GenericParam(id);
return Some(ResolveValueResult::ValueNs(val));
}
}
- Scope::GenericParams { .. } => continue,
- Scope::ImplDefScope(impl_) => {
+ &Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- if n_segments > 1 {
- let ty = TypeNs::SelfType(*impl_);
- return Some(ResolveValueResult::Partial(ty, 1));
+ return Some(if n_segments > 1 {
+ ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1)
} else {
- return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(*impl_)));
- }
+ ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_))
+ });
}
}
+ // bare `Self` doesn't work in the value namespace in a struct/enum definition
+ Scope::AdtScope(_) if n_segments == 1 => continue,
Scope::AdtScope(adt) => {
- if n_segments == 1 {
- // bare `Self` doesn't work in the value namespace in a struct/enum definition
- continue;
- }
if first_name == &name![Self] {
let ty = TypeNs::AdtSelfType(*adt);
return Some(ResolveValueResult::Partial(ty, 1));
}
}
- Scope::ModuleScope(m) => {
+ Scope::BlockScope(m) => {
if let Some(def) = m.resolve_path_in_value_ns(db, path) {
return Some(def);
}
@@ -318,15 +290,16 @@ impl Resolver {
}
}
+ if let res @ Some(_) = self.module_scope.resolve_path_in_value_ns(db, path) {
+ return res;
+ }
+
// If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
// to resolving to the primitive type, to allow this to still work in the presence of
// `use core::u16;`.
if path.kind == PathKind::Plain && path.segments().len() > 1 {
- match BuiltinType::by_name(&path.segments()[0]) {
- Some(builtin) => {
- return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
- }
- None => {}
+ if let Some(builtin) = BuiltinType::by_name(&path.segments()[0]) {
+ return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
}
}
@@ -345,7 +318,7 @@ impl Resolver {
}
pub fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroId> {
- let (item_map, module) = self.module_scope();
+ let (item_map, module) = self.item_scope();
item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros()
}
@@ -395,30 +368,43 @@ impl Resolver {
for scope in self.scopes() {
scope.process_names(&mut res, db);
}
+ let ModuleItemMap { ref def_map, module_id } = self.module_scope;
+ // FIXME: should we provide `self` here?
+ // f(
+ // Name::self_param(),
+ // PerNs::types(Resolution::Def {
+ // def: m.module.into(),
+ // }),
+ // );
+ def_map[module_id].scope.entries().for_each(|(name, def)| {
+ res.add_per_ns(name, def);
+ });
+ def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| {
+ macs.iter().for_each(|&mac| {
+ res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))));
+ })
+ });
+ def_map.extern_prelude().for_each(|(name, &def)| {
+ res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
+ });
+ BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
+ res.add_per_ns(name, def);
+ });
+ if let Some(prelude) = def_map.prelude() {
+ let prelude_def_map = prelude.def_map(db);
+ for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
+ res.add_per_ns(name, def)
+ }
+ }
res.map
}
pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
let mut traits = FxHashSet::default();
+
for scope in self.scopes() {
match scope {
- Scope::ModuleScope(m) => {
- if let Some(prelude) = m.def_map.prelude() {
- let prelude_def_map = prelude.def_map(db);
- traits.extend(prelude_def_map[prelude.local_id].scope.traits());
- }
- traits.extend(m.def_map[m.module_id].scope.traits());
-
- // Add all traits that are in scope because of the containing DefMaps
- m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
- if let Some(prelude) = def_map.prelude() {
- let prelude_def_map = prelude.def_map(db);
- traits.extend(prelude_def_map[prelude.local_id].scope.traits());
- }
- traits.extend(def_map[module].scope.traits());
- None::<()>
- });
- }
+ Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
&Scope::ImplDefScope(impl_) => {
if let Some(target_trait) = &db.impl_data(impl_).target_trait {
if let Some(TypeNs::TraitId(trait_)) =
@@ -431,35 +417,28 @@ impl Resolver {
_ => (),
}
}
- traits
- }
- fn module_scope(&self) -> (&DefMap, LocalModuleId) {
- self.scopes()
- .find_map(|scope| match scope {
- Scope::ModuleScope(m) => Some((&*m.def_map, m.module_id)),
- _ => None,
- })
- .expect("module scope invariant violated")
+ // Fill in the prelude traits
+ if let Some(prelude) = self.module_scope.def_map.prelude() {
+ let prelude_def_map = prelude.def_map(db);
+ traits.extend(prelude_def_map[prelude.local_id].scope.traits());
+ }
+ // Fill in module visible traits
+ traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits());
+ traits
}
pub fn module(&self) -> ModuleId {
- let (def_map, local_id) = self.module_scope();
+ let (def_map, local_id) = self.item_scope();
def_map.module_id(local_id)
}
pub fn krate(&self) -> CrateId {
- self.def_map().krate()
+ self.module_scope.def_map.krate()
}
pub fn def_map(&self) -> &DefMap {
- self.scopes
- .get(0)
- .and_then(|scope| match scope {
- Scope::ModuleScope(m) => Some(&m.def_map),
- _ => None,
- })
- .expect("module scope invariant violated")
+ self.item_scope().0
}
pub fn where_predicates_in_scope(
@@ -488,6 +467,36 @@ impl Resolver {
}
}
+impl Resolver {
+ fn scopes(&self) -> impl Iterator<Item = &Scope> {
+ self.scopes.iter().rev()
+ }
+
+ fn resolve_module_path(
+ &self,
+ db: &dyn DefDatabase,
+ path: &ModPath,
+ shadow: BuiltinShadowMode,
+ ) -> PerNs {
+ let (item_map, module) = self.item_scope();
+ let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow);
+ if segment_index.is_some() {
+ return PerNs::none();
+ }
+ module_res
+ }
+
+ /// The innermost block scope that contains items or the module scope that contains this resolver.
+ fn item_scope(&self) -> (&DefMap, LocalModuleId) {
+ self.scopes()
+ .find_map(|scope| match scope {
+ Scope::BlockScope(m) => Some((&*m.def_map, m.module_id)),
+ _ => None,
+ })
+ .unwrap_or((&self.module_scope.def_map, self.module_scope.module_id))
+ }
+}
+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ScopeDef {
ModuleDef(ModuleDefId),
@@ -502,14 +511,7 @@ pub enum ScopeDef {
impl Scope {
fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) {
match self {
- Scope::ModuleScope(m) => {
- // FIXME: should we provide `self` here?
- // f(
- // Name::self_param(),
- // PerNs::types(Resolution::Def {
- // def: m.module.into(),
- // }),
- // );
+ Scope::BlockScope(m) => {
m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
acc.add_per_ns(name, def);
});
@@ -521,18 +523,6 @@ impl Scope {
);
})
});
- m.def_map.extern_prelude().for_each(|(name, &def)| {
- acc.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
- });
- BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
- acc.add_per_ns(name, def);
- });
- if let Some(prelude) = m.def_map.prelude() {
- let prelude_def_map = prelude.def_map(db);
- for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
- acc.add_per_ns(name, def)
- }
- }
}
Scope::GenericParams { params, def: parent } => {
let parent = *parent;
@@ -596,7 +586,7 @@ pub fn resolver_for_scope(
if let Some(block) = scopes.block(scope) {
if let Some(def_map) = db.block_def_map(block) {
let root = def_map.root();
- r = r.push_module_scope(def_map, root);
+ r = r.push_block_scope(def_map, root);
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
// already traverses all parents, so this is O(n²). I think we could only store the
// innermost module scope instead?
@@ -623,8 +613,8 @@ impl Resolver {
self.push_scope(Scope::ImplDefScope(impl_def))
}
- fn push_module_scope(self, def_map: Arc<DefMap>, module_id: LocalModuleId) -> Resolver {
- self.push_scope(Scope::ModuleScope(ModuleItemMap { def_map, module_id }))
+ fn push_block_scope(self, def_map: Arc<DefMap>, module_id: LocalModuleId) -> Resolver {
+ self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, module_id }))
}
fn push_expr_scope(
@@ -768,14 +758,19 @@ pub trait HasResolver: Copy {
impl HasResolver for ModuleId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
let mut def_map = self.def_map(db);
- let mut modules: SmallVec<[_; 2]> = smallvec![(def_map.clone(), self.local_id)];
+ let mut modules: SmallVec<[_; 1]> = smallvec![];
+ let mut module_id = self.local_id;
while let Some(parent) = def_map.parent() {
+ modules.push((def_map, module_id));
def_map = parent.def_map(db);
- modules.push((def_map.clone(), parent.local_id));
+ module_id = parent.local_id;
}
- let mut resolver = Resolver { scopes: Vec::with_capacity(modules.len()) };
+ let mut resolver = Resolver {
+ scopes: Vec::with_capacity(modules.len()),
+ module_scope: ModuleItemMap { def_map, module_id },
+ };
for (def_map, module) in modules.into_iter().rev() {
- resolver = resolver.push_module_scope(def_map, module);
+ resolver = resolver.push_block_scope(def_map, module);
}
resolver
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
index 9cdc18d6b..b7908bdda 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
@@ -10,7 +10,7 @@ use base_db::{
SourceDatabase, Upcast,
};
use hir_expand::{db::AstDatabase, InFile};
-use rustc_hash::FxHashSet;
+use stdx::hash::NoHashHashSet;
use syntax::{algo, ast, AstNode};
use crate::{
@@ -76,7 +76,7 @@ impl FileLoader for TestDB {
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
FileLoaderDelegate(self).resolve_path(path)
}
- fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+ fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
FileLoaderDelegate(self).relevant_crates(file_id)
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
index 924805962..5b4c71be7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
@@ -77,6 +77,10 @@ impl Rawness {
Rawness::Ref
}
}
+
+ pub fn is_raw(&self) -> bool {
+ matches!(self, Self::RawPtr)
+ }
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
index 6e22a877a..087268a9e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
@@ -224,7 +224,7 @@ pub(crate) fn field_visibilities_query(
let resolver = variant_id.module(db).resolver(db);
let mut res = ArenaMap::default();
for (field_id, field_data) in var_data.fields().iter() {
- res.insert(field_id, field_data.visibility.resolve(db, &resolver))
+ res.insert(field_id, field_data.visibility.resolve(db, &resolver));
}
Arc::new(res)
}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/ast_id_map.rs b/src/tools/rust-analyzer/crates/hir-expand/src/ast_id_map.rs
index c1ddef03b..11c0a6764 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/ast_id_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/ast_id_map.rs
@@ -15,7 +15,7 @@ use std::{
use la_arena::{Arena, Idx};
use profile::Count;
use rustc_hash::FxHasher;
-use syntax::{ast, match_ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
+use syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
/// `AstId` points to an AST node in a specific file.
pub struct FileAstId<N: AstNode> {
@@ -92,18 +92,12 @@ impl AstIdMap {
// change parent's id. This means that, say, adding a new function to a
// trait does not change ids of top-level items, which helps caching.
bdfs(node, |it| {
- match_ast! {
- match it {
- ast::Item(module_item) => {
- res.alloc(module_item.syntax());
- true
- },
- ast::BlockExpr(block) => {
- res.alloc(block.syntax());
- true
- },
- _ => false,
- }
+ let kind = it.kind();
+ if ast::Item::can_cast(kind) || ast::BlockExpr::can_cast(kind) {
+ res.alloc(&it);
+ true
+ } else {
+ false
}
});
res.map = hashbrown::HashMap::with_capacity_and_hasher(res.arena.len(), ());
@@ -123,6 +117,7 @@ impl AstIdMap {
let raw = self.erased_ast_id(item.syntax());
FileAstId { raw, _ty: PhantomData }
}
+
fn erased_ast_id(&self, item: &SyntaxNode) -> ErasedFileAstId {
let ptr = SyntaxNodePtr::new(item);
let hash = hash_ptr(&ptr);
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
index 76da7c9f1..8befa7f7d 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
@@ -251,9 +251,13 @@ fn format_args_expand(
}
for arg in &mut args {
// Remove `key =`.
- if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint)
+ if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=')
{
- arg.token_trees.drain(..2);
+ // but not with `==`
+ if !matches!(arg.token_trees.get(2), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' )
+ {
+ arg.token_trees.drain(..2);
+ }
}
}
let _format_string = args.remove(0);
@@ -357,6 +361,12 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
token.value().map(|it| it.into_owned())
}
+fn unquote_char(lit: &tt::Literal) -> Option<char> {
+ let lit = ast::make::tokens::literal(&lit.to_string());
+ let token = ast::Char::cast(lit)?;
+ token.value()
+}
+
fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
let lit = ast::make::tokens::literal(&lit.to_string());
let token = ast::ByteString::cast(lit)?;
@@ -408,8 +418,12 @@ fn concat_expand(
// concat works with string and char literals, so remove any quotes.
// It also works with integer, float and boolean literals, so just use the rest
// as-is.
- let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
- text.push_str(&component);
+ if let Some(c) = unquote_char(it) {
+ text.push(c);
+ } else {
+ let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
+ text.push_str(&component);
+ }
}
// handle boolean literals
tt::TokenTree::Leaf(tt::Leaf::Ident(id))
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
index bd60c3d26..bc97ee15c 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
@@ -321,7 +321,11 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<Sy
ast::Item::cast(node.clone())?
.attrs()
.take(derive_attr_index as usize + 1)
- // FIXME
+ // FIXME, this resolution should not be done syntactically
+ // derive is a proper macro now, no longer builtin
+ // But we do not have resolution at this stage, this means
+ // we need to know about all macro calls for the given ast item here
+ // so we require some kind of mapping...
.filter(|attr| attr.simple_name().as_deref() == Some("derive"))
.map(|it| it.syntax().clone())
.collect()
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
index 9999790fa..893e6fe4b 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
@@ -5,7 +5,7 @@ use std::mem;
use mbe::{SyntheticToken, SyntheticTokenId, TokenMap};
use rustc_hash::FxHashMap;
use syntax::{
- ast::{self, AstNode},
+ ast::{self, AstNode, HasLoopBody},
match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange,
};
use tt::Subtree;
@@ -67,7 +67,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
preorder.skip_subtree();
continue;
}
-
// In some other situations, we can fix things by just appending some tokens.
let end_range = TextRange::empty(node.text_range().end());
match_ast! {
@@ -142,8 +141,127 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
]);
}
},
+ ast::WhileExpr(it) => {
+ if it.condition().is_none() {
+ // insert placeholder token after the while token
+ let while_token = match it.while_token() {
+ Some(t) => t,
+ None => continue,
+ };
+ append.insert(while_token.into(), vec![
+ SyntheticToken {
+ kind: SyntaxKind::IDENT,
+ text: "__ra_fixup".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ ]);
+ }
+ if it.loop_body().is_none() {
+ append.insert(node.clone().into(), vec![
+ SyntheticToken {
+ kind: SyntaxKind::L_CURLY,
+ text: "{".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ SyntheticToken {
+ kind: SyntaxKind::R_CURLY,
+ text: "}".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ ]);
+ }
+ },
+ ast::LoopExpr(it) => {
+ if it.loop_body().is_none() {
+ append.insert(node.clone().into(), vec![
+ SyntheticToken {
+ kind: SyntaxKind::L_CURLY,
+ text: "{".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ SyntheticToken {
+ kind: SyntaxKind::R_CURLY,
+ text: "}".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ ]);
+ }
+ },
// FIXME: foo::
- // FIXME: for, loop, match etc.
+ ast::MatchExpr(it) => {
+ if it.expr().is_none() {
+ let match_token = match it.match_token() {
+ Some(t) => t,
+ None => continue
+ };
+ append.insert(match_token.into(), vec![
+ SyntheticToken {
+ kind: SyntaxKind::IDENT,
+ text: "__ra_fixup".into(),
+ range: end_range,
+ id: EMPTY_ID
+ },
+ ]);
+ }
+ if it.match_arm_list().is_none() {
+ // No match arms
+ append.insert(node.clone().into(), vec![
+ SyntheticToken {
+ kind: SyntaxKind::L_CURLY,
+ text: "{".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ SyntheticToken {
+ kind: SyntaxKind::R_CURLY,
+ text: "}".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ ]);
+ }
+ },
+ ast::ForExpr(it) => {
+ let for_token = match it.for_token() {
+ Some(token) => token,
+ None => continue
+ };
+
+ let [pat, in_token, iter] = [
+ (SyntaxKind::UNDERSCORE, "_"),
+ (SyntaxKind::IN_KW, "in"),
+ (SyntaxKind::IDENT, "__ra_fixup")
+ ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID});
+
+ if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
+ append.insert(for_token.into(), vec![pat, in_token, iter]);
+ // does something funky -- see test case for_no_pat
+ } else if it.pat().is_none() {
+ append.insert(for_token.into(), vec![pat]);
+ }
+
+ if it.loop_body().is_none() {
+ append.insert(node.clone().into(), vec![
+ SyntheticToken {
+ kind: SyntaxKind::L_CURLY,
+ text: "{".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ SyntheticToken {
+ kind: SyntaxKind::R_CURLY,
+ text: "}".into(),
+ range: end_range,
+ id: EMPTY_ID,
+ },
+ ]);
+ }
+ },
_ => (),
}
}
@@ -237,6 +355,111 @@ mod tests {
}
#[test]
+ fn just_for_token() {
+ check(
+ r#"
+fn foo() {
+ for
+}
+"#,
+ expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+ )
+ }
+
+ #[test]
+ fn for_no_iter_pattern() {
+ check(
+ r#"
+fn foo() {
+ for {}
+}
+"#,
+ expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+ )
+ }
+
+ #[test]
+ fn for_no_body() {
+ check(
+ r#"
+fn foo() {
+ for bar in qux
+}
+"#,
+ expect![[r#"
+fn foo () {for bar in qux {}}
+"#]],
+ )
+ }
+
+ // FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
+ #[test]
+ fn for_no_pat() {
+ check(
+ r#"
+fn foo() {
+ for in qux {
+
+ }
+}
+"#,
+ expect![[r#"
+fn foo () {__ra_fixup}
+"#]],
+ )
+ }
+
+ #[test]
+ fn match_no_expr_no_arms() {
+ check(
+ r#"
+fn foo() {
+ match
+}
+"#,
+ expect![[r#"
+fn foo () {match __ra_fixup {}}
+"#]],
+ )
+ }
+
+ #[test]
+ fn match_expr_no_arms() {
+ check(
+ r#"
+fn foo() {
+ match x {
+
+ }
+}
+"#,
+ expect![[r#"
+fn foo () {match x {}}
+"#]],
+ )
+ }
+
+ #[test]
+ fn match_no_expr() {
+ check(
+ r#"
+fn foo() {
+ match {
+ _ => {}
+ }
+}
+"#,
+ expect![[r#"
+fn foo () {match __ra_fixup {}}
+"#]],
+ )
+ }
+
+ #[test]
fn incomplete_field_expr_1() {
check(
r#"
@@ -245,7 +468,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {a . __ra_fixup}
+fn foo () {a .__ra_fixup}
"#]],
)
}
@@ -255,11 +478,11 @@ fn foo () {a . __ra_fixup}
check(
r#"
fn foo() {
- a. ;
+ a.;
}
"#,
expect![[r#"
-fn foo () {a . __ra_fixup ;}
+fn foo () {a .__ra_fixup ;}
"#]],
)
}
@@ -269,12 +492,12 @@ fn foo () {a . __ra_fixup ;}
check(
r#"
fn foo() {
- a. ;
+ a.;
bar();
}
"#,
expect![[r#"
-fn foo () {a . __ra_fixup ; bar () ;}
+fn foo () {a .__ra_fixup ; bar () ;}
"#]],
)
}
@@ -302,7 +525,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {let x = a . __ra_fixup ;}
+fn foo () {let x = a .__ra_fixup ;}
"#]],
)
}
@@ -318,7 +541,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {a . b ; bar () ;}
+fn foo () {a .b ; bar () ;}
"#]],
)
}
@@ -379,4 +602,59 @@ fn foo () {if {} {}}
"#]],
)
}
+
+ #[test]
+ fn fixup_while_1() {
+ check(
+ r#"
+fn foo() {
+ while
+}
+"#,
+ expect![[r#"
+fn foo () {while __ra_fixup {}}
+"#]],
+ )
+ }
+
+ #[test]
+ fn fixup_while_2() {
+ check(
+ r#"
+fn foo() {
+ while foo
+}
+"#,
+ expect![[r#"
+fn foo () {while foo {}}
+"#]],
+ )
+ }
+ #[test]
+ fn fixup_while_3() {
+ check(
+ r#"
+fn foo() {
+ while {}
+}
+"#,
+ expect![[r#"
+fn foo () {while __ra_fixup {}}
+"#]],
+ )
+ }
+
+ #[test]
+ fn fixup_loop() {
+ check(
+ r#"
+fn foo() {
+ loop
+}
+"#,
+ expect![[r#"
+fn foo () {loop {}}
+"#]],
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index 252293090..fc128102f 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -130,7 +130,6 @@ pub struct MacroDefId {
pub enum MacroDefKind {
Declarative(AstId<ast::Macro>),
BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>),
- // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander
BuiltInAttr(BuiltinAttrExpander, AstId<ast::Macro>),
BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>),
BuiltInEager(EagerExpander, AstId<ast::Macro>),
@@ -617,7 +616,7 @@ impl ExpansionInfo {
let token_id = match token_id_in_attr_input {
Some(token_id) => token_id,
- // the token is not inside an attribute's input so do the lookup in the macro_arg as ususal
+ // the token is not inside an attribute's input so do the lookup in the macro_arg as usual
None => {
let relative_range =
token.value.text_range().checked_sub(self.arg.value.text_range().start())?;
@@ -970,7 +969,7 @@ impl ExpandTo {
if parent.kind() == MACRO_EXPR
&& parent
.parent()
- .map_or(true, |p| matches!(p.kind(), EXPR_STMT | STMT_LIST | MACRO_STMTS))
+ .map_or(false, |p| matches!(p.kind(), EXPR_STMT | STMT_LIST | MACRO_STMTS))
{
return ExpandTo::Statements;
}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
index fea09521e..d7586d129 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
@@ -22,7 +22,7 @@ pub struct ModPath {
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct EscapedModPath<'a>(&'a ModPath);
+pub struct UnescapedModPath<'a>(&'a ModPath);
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum PathKind {
@@ -102,8 +102,8 @@ impl ModPath {
}
}
- pub fn escaped(&self) -> EscapedModPath<'_> {
- EscapedModPath(self)
+ pub fn unescaped(&self) -> UnescapedModPath<'_> {
+ UnescapedModPath(self)
}
fn _fmt(&self, f: &mut fmt::Formatter<'_>, escaped: bool) -> fmt::Result {
@@ -134,9 +134,9 @@ impl ModPath {
}
first_segment = false;
if escaped {
- segment.escaped().fmt(f)?
- } else {
segment.fmt(f)?
+ } else {
+ segment.unescaped().fmt(f)?
};
}
Ok(())
@@ -145,13 +145,13 @@ impl ModPath {
impl Display for ModPath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self._fmt(f, false)
+ self._fmt(f, true)
}
}
-impl<'a> Display for EscapedModPath<'a> {
+impl<'a> Display for UnescapedModPath<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0._fmt(f, true)
+ self.0._fmt(f, false)
}
}
@@ -257,6 +257,7 @@ macro_rules! __known_path {
(core::ops::RangeToInclusive) => {};
(core::ops::RangeInclusive) => {};
(core::future::Future) => {};
+ (core::future::IntoFuture) => {};
(core::ops::Try) => {};
($path:path) => {
compile_error!("Please register your known path in the path module")
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
index 85b0a7735..4ce21a579 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
@@ -7,12 +7,16 @@ use syntax::{ast, SmolStr, SyntaxKind};
/// `Name` is a wrapper around string, which is used in hir for both references
/// and declarations. In theory, names should also carry hygiene info, but we are
/// not there yet!
+///
+/// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it
+/// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the
+/// name without "r#".
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Name(Repr);
-/// `EscapedName` will add a prefix "r#" to the wrapped `Name` when it is a raw identifier
+/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct EscapedName<'a>(&'a Name);
+pub struct UnescapedName<'a>(&'a Name);
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
enum Repr {
@@ -34,37 +38,26 @@ fn is_raw_identifier(name: &str) -> bool {
is_keyword && !matches!(name, "self" | "crate" | "super" | "Self")
}
-impl<'a> fmt::Display for EscapedName<'a> {
+impl<'a> fmt::Display for UnescapedName<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 .0 {
Repr::Text(text) => {
- if is_raw_identifier(text) {
- write!(f, "r#{}", &text)
- } else {
- fmt::Display::fmt(&text, f)
- }
+ let text = text.strip_prefix("r#").unwrap_or(text);
+ fmt::Display::fmt(&text, f)
}
Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
}
}
}
-impl<'a> EscapedName<'a> {
- pub fn is_escaped(&self) -> bool {
- match &self.0 .0 {
- Repr::Text(it) => is_raw_identifier(&it),
- Repr::TupleField(_) => false,
- }
- }
-
- /// Returns the textual representation of this name as a [`SmolStr`].
- /// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in
- /// the general case.
+impl<'a> UnescapedName<'a> {
+ /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over
+ /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case.
pub fn to_smol_str(&self) -> SmolStr {
match &self.0 .0 {
Repr::Text(it) => {
- if is_raw_identifier(&it) {
- SmolStr::from_iter(["r#", &it])
+ if let Some(stripped) = it.strip_prefix("r#") {
+ SmolStr::new(stripped)
} else {
it.clone()
}
@@ -98,8 +91,16 @@ impl Name {
/// Resolve a name from the text of token.
fn resolve(raw_text: &str) -> Name {
match raw_text.strip_prefix("r#") {
- Some(text) => Name::new_text(SmolStr::new(text)),
- None => Name::new_text(raw_text.into()),
+ // When `raw_text` starts with "r#" but the name does not coincide with any
+ // keyword, we never need the prefix so we strip it.
+ Some(text) if !is_raw_identifier(text) => Name::new_text(SmolStr::new(text)),
+ // Keywords (in the current edition) *can* be used as a name in earlier editions of
+ // Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their
+ // escaped form.
+ None if is_raw_identifier(raw_text) => {
+ Name::new_text(SmolStr::from_iter(["r#", raw_text]))
+ }
+ _ => Name::new_text(raw_text.into()),
}
}
@@ -142,8 +143,15 @@ impl Name {
}
}
- pub fn escaped(&self) -> EscapedName<'_> {
- EscapedName(self)
+ pub fn unescaped(&self) -> UnescapedName<'_> {
+ UnescapedName(self)
+ }
+
+ pub fn is_escaped(&self) -> bool {
+ match &self.0 {
+ Repr::Text(it) => it.starts_with("r#"),
+ Repr::TupleField(_) => false,
+ }
}
}
@@ -258,6 +266,7 @@ pub mod known {
Try,
Ok,
Future,
+ IntoFuture,
Result,
Option,
Output,
@@ -327,6 +336,7 @@ pub mod known {
test,
test_case,
recursion_limit,
+ feature,
// Safe intrinsics
abort,
add_with_overflow,
@@ -381,6 +391,7 @@ pub mod known {
bitor,
bitxor_assign,
bitxor,
+ branch,
deref_mut,
deref,
div_assign,
@@ -390,12 +401,14 @@ pub mod known {
future_trait,
index,
index_mut,
+ into_future,
mul_assign,
mul,
neg,
not,
owned_box,
partial_ord,
+ poll,
r#fn,
rem_assign,
rem,
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs
index 82f410ecd..e839e97bf 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs
@@ -196,8 +196,8 @@ impl_to_to_tokentrees! {
tt::Literal => self { self };
tt::Ident => self { self };
tt::Punct => self { self };
- &str => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}};
- String => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}}
+ &str => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}};
+ String => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}}
}
#[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
index 5cd444c1a..7f143f396 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
@@ -18,9 +18,9 @@ ena = "0.14.0"
tracing = "0.1.35"
rustc-hash = "1.1.0"
scoped-tls = "1.0.0"
-chalk-solve = { version = "0.83.0", default-features = false }
-chalk-ir = "0.83.0"
-chalk-recursive = { version = "0.83.0", default-features = false }
+chalk-solve = { version = "0.84.0", default-features = false }
+chalk-ir = "0.84.0"
+chalk-recursive = { version = "0.84.0", default-features = false }
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
once_cell = "1.12.0"
typed-arena = "2.0.1"
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
index b6f226dbf..344036dd8 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
@@ -104,8 +104,7 @@ pub(crate) fn deref(table: &mut InferenceTable<'_>, ty: Ty) -> Option<Ty> {
fn builtin_deref(ty: &Ty) -> Option<&Ty> {
match ty.kind(Interner) {
- TyKind::Ref(.., ty) => Some(ty),
- TyKind::Raw(.., ty) => Some(ty),
+ TyKind::Ref(.., ty) | TyKind::Raw(.., ty) => Some(ty),
_ => None,
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
index a9c124b42..4a5533c64 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
@@ -164,6 +164,8 @@ impl TyExt for Ty {
fn dyn_trait(&self) -> Option<TraitId> {
let trait_ref = match self.kind(Interner) {
+ // The principal trait bound should be the first element of the bounds. This is an
+ // invariant ensured by `TyLoweringContext::lower_dyn_trait()`.
TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| {
match b.skip_binders() {
WhereClause::Implemented(trait_ref) => Some(trait_ref),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
index 0495a4e64..6ecb6e6fd 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -2,7 +2,6 @@
use std::{
collections::HashMap,
- convert::TryInto,
fmt::{Display, Write},
};
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
index 642e03edd..c8df4c796 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
@@ -159,12 +159,7 @@ impl ExprValidator {
}
let pattern_arena = Arena::new();
- let cx = MatchCheckCtx {
- module: self.owner.module(db.upcast()),
- body: self.owner,
- db,
- pattern_arena: &pattern_arena,
- };
+ let cx = MatchCheckCtx::new(self.owner.module(db.upcast()), self.owner, db, &pattern_arena);
let mut m_arms = Vec::with_capacity(arms.len());
let mut has_lowering_errors = false;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs
index bbbe539c1..47d60fc41 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs
@@ -52,7 +52,10 @@ use hir_def::{EnumVariantId, HasModule, LocalFieldId, VariantId};
use smallvec::{smallvec, SmallVec};
use stdx::never;
-use crate::{infer::normalize, AdtId, Interner, Scalar, Ty, TyExt, TyKind};
+use crate::{
+ infer::normalize, inhabitedness::is_enum_variant_uninhabited_from, AdtId, Interner, Scalar, Ty,
+ TyExt, TyKind,
+};
use super::{
is_box,
@@ -557,8 +560,8 @@ impl SplitWildcard {
TyKind::Scalar(Scalar::Bool) => smallvec![make_range(0, 1, Scalar::Bool)],
// TyKind::Array(..) if ... => unhandled(),
TyKind::Array(..) | TyKind::Slice(..) => unhandled(),
- &TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => {
- let enum_data = cx.db.enum_data(enum_id);
+ TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), subst) => {
+ let enum_data = cx.db.enum_data(*enum_id);
// If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
// additional "unknown" constructor.
@@ -591,14 +594,15 @@ impl SplitWildcard {
let mut ctors: SmallVec<[_; 1]> = enum_data
.variants
.iter()
- .filter(|&(_, _v)| {
+ .map(|(local_id, _)| EnumVariantId { parent: *enum_id, local_id })
+ .filter(|&variant| {
// If `exhaustive_patterns` is enabled, we exclude variants known to be
// uninhabited.
let is_uninhabited = is_exhaustive_pat_feature
- && unimplemented!("after MatchCheckCtx.feature_exhaustive_patterns()");
+ && is_enum_variant_uninhabited_from(variant, subst, cx.module, cx.db);
!is_uninhabited
})
- .map(|(local_id, _)| Variant(EnumVariantId { parent: enum_id, local_id }))
+ .map(Variant)
.collect();
if is_secretly_empty || is_declared_nonexhaustive {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/usefulness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/usefulness.rs
index 1221327b9..c4d709a97 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/usefulness.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/usefulness.rs
@@ -277,7 +277,7 @@ use hir_def::{AdtId, DefWithBodyId, HasModule, ModuleId};
use smallvec::{smallvec, SmallVec};
use typed_arena::Arena;
-use crate::{db::HirDatabase, Ty, TyExt};
+use crate::{db::HirDatabase, inhabitedness::is_ty_uninhabited_from, Ty, TyExt};
use super::deconstruct_pat::{Constructor, DeconstructedPat, Fields, SplitWildcard};
@@ -289,13 +289,27 @@ pub(crate) struct MatchCheckCtx<'a, 'p> {
pub(crate) db: &'a dyn HirDatabase,
/// Lowered patterns from arms plus generated by the check.
pub(crate) pattern_arena: &'p Arena<DeconstructedPat<'p>>,
+ exhaustive_patterns: bool,
}
impl<'a, 'p> MatchCheckCtx<'a, 'p> {
- pub(super) fn is_uninhabited(&self, _ty: &Ty) -> bool {
- // FIXME(iDawer) implement exhaustive_patterns feature. More info in:
- // Tracking issue for RFC 1872: exhaustive_patterns feature https://github.com/rust-lang/rust/issues/51085
- false
+ pub(crate) fn new(
+ module: ModuleId,
+ body: DefWithBodyId,
+ db: &'a dyn HirDatabase,
+ pattern_arena: &'p Arena<DeconstructedPat<'p>>,
+ ) -> Self {
+ let def_map = db.crate_def_map(module.krate());
+ let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns");
+ Self { module, body, db, pattern_arena, exhaustive_patterns }
+ }
+
+ pub(super) fn is_uninhabited(&self, ty: &Ty) -> bool {
+ if self.feature_exhaustive_patterns() {
+ is_ty_uninhabited_from(ty, self.module, self.db)
+ } else {
+ false
+ }
}
/// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.
@@ -311,10 +325,9 @@ impl<'a, 'p> MatchCheckCtx<'a, 'p> {
}
}
- // Rust feature described as "Allows exhaustive pattern matching on types that contain uninhabited types."
+ // Rust's unstable feature described as "Allows exhaustive pattern matching on types that contain uninhabited types."
pub(super) fn feature_exhaustive_patterns(&self) -> bool {
- // FIXME see MatchCheckCtx::is_uninhabited
- false
+ self.exhaustive_patterns
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 46eeea0e6..10ffde87e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -182,7 +182,7 @@ pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InferenceDiagnostic {
NoSuchField { expr: ExprId },
- BreakOutsideOfLoop { expr: ExprId },
+ BreakOutsideOfLoop { expr: ExprId, is_break: bool },
MismatchedArgCount { call_expr: ExprId, expected: usize, found: usize },
}
@@ -418,18 +418,45 @@ pub(crate) struct InferenceContext<'a> {
#[derive(Clone, Debug)]
struct BreakableContext {
+ /// Whether this context contains at least one break expression.
may_break: bool,
+ /// The coercion target of the context.
coerce: CoerceMany,
+ /// The optional label of the context.
label: Option<name::Name>,
+ kind: BreakableKind,
+}
+
+#[derive(Clone, Debug)]
+enum BreakableKind {
+ Block,
+ Loop,
+ /// A border is something like an async block, closure etc. Anything that prevents
+ /// breaking/continuing through
+ Border,
}
fn find_breakable<'c>(
ctxs: &'c mut [BreakableContext],
label: Option<&name::Name>,
) -> Option<&'c mut BreakableContext> {
+ let mut ctxs = ctxs
+ .iter_mut()
+ .rev()
+ .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
+ match label {
+ Some(_) => ctxs.find(|ctx| ctx.label.as_ref() == label),
+ None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
+ }
+}
+
+fn find_continuable<'c>(
+ ctxs: &'c mut [BreakableContext],
+ label: Option<&name::Name>,
+) -> Option<&'c mut BreakableContext> {
match label {
- Some(_) => ctxs.iter_mut().rev().find(|ctx| ctx.label.as_ref() == label),
- None => ctxs.last_mut(),
+ Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
+ None => find_breakable(ctxs, label),
}
}
@@ -734,6 +761,7 @@ impl<'a> InferenceContext<'a> {
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
return (ty, Some(strukt.into()));
}
+ ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
_ => return (self.err_ty(), None),
},
Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
@@ -875,7 +903,10 @@ impl<'a> InferenceContext<'a> {
}
fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
- let trait_ = self.resolve_lang_item(name![future_trait])?.as_trait()?;
+ let trait_ = self
+ .resolver
+ .resolve_known_trait(self.db.upcast(), &path![core::future::IntoFuture])
+ .or_else(|| self.resolve_lang_item(name![future_trait])?.as_trait())?;
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index d164e64a8..2d04a864a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -10,25 +10,25 @@ use chalk_ir::{
cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
};
use hir_def::{
- expr::{ArithOp, Array, BinaryOp, CmpOp, Expr, ExprId, Literal, Ordering, Statement, UnaryOp},
+ expr::{ArithOp, Array, BinaryOp, CmpOp, Expr, ExprId, LabelId, Literal, Statement, UnaryOp},
generics::TypeOrConstParamData,
path::{GenericArg, GenericArgs},
resolver::resolver_for_expr,
- ConstParamId, FieldId, FunctionId, ItemContainerId, Lookup,
+ ConstParamId, FieldId, ItemContainerId, Lookup,
};
-use hir_expand::name::{name, Name};
+use hir_expand::name::Name;
use stdx::always;
use syntax::ast::RangeOp;
use crate::{
autoderef::{self, Autoderef},
consteval,
- infer::coerce::CoerceMany,
+ infer::{coerce::CoerceMany, find_continuable, BreakableKind},
lower::{
const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode,
},
mapping::{from_chalk, ToChalk},
- method_resolution::{self, VisibleFromModule},
+ method_resolution::{self, lang_names_for_bin_op, VisibleFromModule},
primitive::{self, UintTy},
static_lifetime, to_chalk_trait_id,
utils::{generics, Generics},
@@ -120,32 +120,37 @@ impl<'a> InferenceContext<'a> {
let ty = match label {
Some(_) => {
let break_ty = self.table.new_type_var();
- self.breakables.push(BreakableContext {
- may_break: false,
- coerce: CoerceMany::new(break_ty.clone()),
- label: label.map(|label| self.body[label].name.clone()),
- });
- let ty = self.infer_block(
- tgt_expr,
- statements,
- *tail,
- &Expectation::has_type(break_ty),
+ let (breaks, ty) = self.with_breakable_ctx(
+ BreakableKind::Block,
+ break_ty.clone(),
+ *label,
+ |this| {
+ this.infer_block(
+ tgt_expr,
+ statements,
+ *tail,
+ &Expectation::has_type(break_ty),
+ )
+ },
);
- let ctxt = self.breakables.pop().expect("breakable stack broken");
- if ctxt.may_break {
- ctxt.coerce.complete()
- } else {
- ty
- }
+ breaks.unwrap_or(ty)
}
None => self.infer_block(tgt_expr, statements, *tail, expected),
};
self.resolver = old_resolver;
ty
}
- Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected),
+ Expr::Unsafe { body } => self.infer_expr(*body, expected),
+ Expr::Const { body } => {
+ self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+ this.infer_expr(*body, expected)
+ })
+ .1
+ }
Expr::TryBlock { body } => {
- let _inner = self.infer_expr(*body, expected);
+ self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+ let _inner = this.infer_expr(*body, expected);
+ });
// FIXME should be std::result::Result<{inner}, _>
self.err_ty()
}
@@ -154,7 +159,10 @@ impl<'a> InferenceContext<'a> {
let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
- let inner_ty = self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
+ let (_, inner_ty) =
+ self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+ this.infer_expr_coerce(*body, &Expectation::has_type(ret_ty))
+ });
self.diverges = prev_diverges;
self.return_ty = prev_ret_ty;
@@ -166,54 +174,44 @@ impl<'a> InferenceContext<'a> {
TyKind::OpaqueType(opaque_ty_id, Substitution::from1(Interner, inner_ty))
.intern(Interner)
}
- Expr::Loop { body, label } => {
- self.breakables.push(BreakableContext {
- may_break: false,
- coerce: CoerceMany::new(self.table.new_type_var()),
- label: label.map(|label| self.body[label].name.clone()),
- });
- self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
-
- let ctxt = self.breakables.pop().expect("breakable stack broken");
+ &Expr::Loop { body, label } => {
+ let ty = self.table.new_type_var();
+ let (breaks, ()) =
+ self.with_breakable_ctx(BreakableKind::Loop, ty, label, |this| {
+ this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
+ });
- if ctxt.may_break {
- self.diverges = Diverges::Maybe;
- ctxt.coerce.complete()
- } else {
- TyKind::Never.intern(Interner)
+ match breaks {
+ Some(breaks) => {
+ self.diverges = Diverges::Maybe;
+ breaks
+ }
+ None => TyKind::Never.intern(Interner),
}
}
- Expr::While { condition, body, label } => {
- self.breakables.push(BreakableContext {
- may_break: false,
- coerce: CoerceMany::new(self.err_ty()),
- label: label.map(|label| self.body[label].name.clone()),
+ &Expr::While { condition, body, label } => {
+ self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
+ this.infer_expr(
+ condition,
+ &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
+ );
+ this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
});
- self.infer_expr(
- *condition,
- &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
- );
- self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
- let _ctxt = self.breakables.pop().expect("breakable stack broken");
+
// the body may not run, so it diverging doesn't mean we diverge
self.diverges = Diverges::Maybe;
TyBuilder::unit()
}
- Expr::For { iterable, body, pat, label } => {
- let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
-
- self.breakables.push(BreakableContext {
- may_break: false,
- coerce: CoerceMany::new(self.err_ty()),
- label: label.map(|label| self.body[label].name.clone()),
- });
+ &Expr::For { iterable, body, pat, label } => {
+ let iterable_ty = self.infer_expr(iterable, &Expectation::none());
let pat_ty =
self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
- self.infer_pat(*pat, &pat_ty, BindingMode::default());
+ self.infer_pat(pat, &pat_ty, BindingMode::default());
+ self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
+ this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
+ });
- self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
- let _ctxt = self.breakables.pop().expect("breakable stack broken");
// the body may not run, so it diverging doesn't mean we diverge
self.diverges = Diverges::Maybe;
TyBuilder::unit()
@@ -269,7 +267,9 @@ impl<'a> InferenceContext<'a> {
let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
- self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
+ self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
+ this.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
+ });
self.diverges = prev_diverges;
self.return_ty = prev_ret_ty;
@@ -372,37 +372,45 @@ impl<'a> InferenceContext<'a> {
let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or_else(|| self.err_ty())
}
- Expr::Continue { .. } => TyKind::Never.intern(Interner),
- Expr::Break { expr, label } => {
- let mut coerce = match find_breakable(&mut self.breakables, label.as_ref()) {
- Some(ctxt) => {
- // avoiding the borrowck
- mem::replace(
- &mut ctxt.coerce,
- CoerceMany::new(self.result.standard_types.unknown.clone()),
- )
- }
- None => CoerceMany::new(self.result.standard_types.unknown.clone()),
+ Expr::Continue { label } => {
+ if let None = find_continuable(&mut self.breakables, label.as_ref()) {
+ self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
+ expr: tgt_expr,
+ is_break: false,
+ });
};
-
+ TyKind::Never.intern(Interner)
+ }
+ Expr::Break { expr, label } => {
let val_ty = if let Some(expr) = *expr {
self.infer_expr(expr, &Expectation::none())
} else {
TyBuilder::unit()
};
- // FIXME: create a synthetic `()` during lowering so we have something to refer to here?
- coerce.coerce(self, *expr, &val_ty);
+ match find_breakable(&mut self.breakables, label.as_ref()) {
+ Some(ctxt) => {
+ // avoiding the borrowck
+ let mut coerce = mem::replace(
+ &mut ctxt.coerce,
+ CoerceMany::new(self.result.standard_types.unknown.clone()),
+ );
- if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
- ctxt.coerce = coerce;
- ctxt.may_break = true;
- } else {
- self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
- expr: tgt_expr,
- });
- };
+ // FIXME: create a synthetic `()` during lowering so we have something to refer to here?
+ coerce.coerce(self, *expr, &val_ty);
+ let ctxt = find_breakable(&mut self.breakables, label.as_ref())
+ .expect("breakable stack changed during coercion");
+ ctxt.coerce = coerce;
+ ctxt.may_break = true;
+ }
+ None => {
+ self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
+ expr: tgt_expr,
+ is_break: true,
+ });
+ }
+ }
TyKind::Never.intern(Interner)
}
Expr::Return { expr } => {
@@ -794,9 +802,6 @@ impl<'a> InferenceContext<'a> {
None => self.table.new_float_var(),
},
},
- Expr::MacroStmts { tail, statements } => {
- self.infer_block(tgt_expr, statements, *tail, expected)
- }
Expr::Underscore => {
// Underscore expressions may only appear in assignee expressions,
// which are handled by `infer_assignee_expr()`, so any underscore
@@ -947,7 +952,9 @@ impl<'a> InferenceContext<'a> {
let lhs_ty = self.infer_expr(lhs, &lhs_expectation);
let rhs_ty = self.table.new_type_var();
- let func = self.resolve_binop_method(op);
+ let func = lang_names_for_bin_op(op).and_then(|(name, lang_item)| {
+ self.db.trait_data(self.resolve_lang_item(lang_item)?.as_trait()?).method_by_name(&name)
+ });
let func = match func {
Some(func) => func,
None => {
@@ -1474,54 +1481,19 @@ impl<'a> InferenceContext<'a> {
})
}
- fn resolve_binop_method(&self, op: BinaryOp) -> Option<FunctionId> {
- let (name, lang_item) = match op {
- BinaryOp::LogicOp(_) => return None,
- BinaryOp::ArithOp(aop) => match aop {
- ArithOp::Add => (name!(add), name!(add)),
- ArithOp::Mul => (name!(mul), name!(mul)),
- ArithOp::Sub => (name!(sub), name!(sub)),
- ArithOp::Div => (name!(div), name!(div)),
- ArithOp::Rem => (name!(rem), name!(rem)),
- ArithOp::Shl => (name!(shl), name!(shl)),
- ArithOp::Shr => (name!(shr), name!(shr)),
- ArithOp::BitXor => (name!(bitxor), name!(bitxor)),
- ArithOp::BitOr => (name!(bitor), name!(bitor)),
- ArithOp::BitAnd => (name!(bitand), name!(bitand)),
- },
- BinaryOp::Assignment { op: Some(aop) } => match aop {
- ArithOp::Add => (name!(add_assign), name!(add_assign)),
- ArithOp::Mul => (name!(mul_assign), name!(mul_assign)),
- ArithOp::Sub => (name!(sub_assign), name!(sub_assign)),
- ArithOp::Div => (name!(div_assign), name!(div_assign)),
- ArithOp::Rem => (name!(rem_assign), name!(rem_assign)),
- ArithOp::Shl => (name!(shl_assign), name!(shl_assign)),
- ArithOp::Shr => (name!(shr_assign), name!(shr_assign)),
- ArithOp::BitXor => (name!(bitxor_assign), name!(bitxor_assign)),
- ArithOp::BitOr => (name!(bitor_assign), name!(bitor_assign)),
- ArithOp::BitAnd => (name!(bitand_assign), name!(bitand_assign)),
- },
- BinaryOp::CmpOp(cop) => match cop {
- CmpOp::Eq { negated: false } => (name!(eq), name!(eq)),
- CmpOp::Eq { negated: true } => (name!(ne), name!(eq)),
- CmpOp::Ord { ordering: Ordering::Less, strict: false } => {
- (name!(le), name!(partial_ord))
- }
- CmpOp::Ord { ordering: Ordering::Less, strict: true } => {
- (name!(lt), name!(partial_ord))
- }
- CmpOp::Ord { ordering: Ordering::Greater, strict: false } => {
- (name!(ge), name!(partial_ord))
- }
- CmpOp::Ord { ordering: Ordering::Greater, strict: true } => {
- (name!(gt), name!(partial_ord))
- }
- },
- BinaryOp::Assignment { op: None } => return None,
- };
-
- let trait_ = self.resolve_lang_item(lang_item)?.as_trait()?;
-
- self.db.trait_data(trait_).method_by_name(&name)
+ fn with_breakable_ctx<T>(
+ &mut self,
+ kind: BreakableKind,
+ ty: Ty,
+ label: Option<LabelId>,
+ cb: impl FnOnce(&mut Self) -> T,
+ ) -> (Option<Ty>, T) {
+ self.breakables.push({
+ let label = label.map(|label| self.body[label].name.clone());
+ BreakableContext { kind, may_break: false, coerce: CoerceMany::new(ty), label }
+ });
+ let res = cb(self);
+ let ctx = self.breakables.pop().expect("breakable stack broken");
+ (ctx.may_break.then(|| ctx.coerce.complete()), res)
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index 5e7320a5d..53259d66d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -14,8 +14,9 @@ use crate::{
consteval::intern_const_scalar,
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
lower::lower_to_chalk_mutability,
- static_lifetime, ConcreteConst, ConstValue, Interner, Substitution, Ty, TyBuilder, TyExt,
- TyKind,
+ primitive::UintTy,
+ static_lifetime, ConcreteConst, ConstValue, Interner, Scalar, Substitution, Ty, TyBuilder,
+ TyExt, TyKind,
};
use super::PatLike;
@@ -294,7 +295,29 @@ impl<'a> InferenceContext<'a> {
let start_ty = self.infer_expr(*start, &Expectation::has_type(expected.clone()));
self.infer_expr(*end, &Expectation::has_type(start_ty))
}
- Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
+ &Pat::Lit(expr) => {
+ // FIXME: using `Option` here is a workaround until we can use if-let chains in stable.
+ let mut pat_ty = None;
+
+ // Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`.
+ if let Expr::Literal(Literal::ByteString(_)) = self.body[expr] {
+ if let Some((inner, ..)) = expected.as_reference() {
+ let inner = self.resolve_ty_shallow(inner);
+ if matches!(inner.kind(Interner), TyKind::Slice(_)) {
+ let elem_ty = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
+ let slice_ty = TyKind::Slice(elem_ty).intern(Interner);
+ let ty = TyKind::Ref(Mutability::Not, static_lifetime(), slice_ty)
+ .intern(Interner);
+ self.write_expr_ty(expr, ty.clone());
+ pat_ty = Some(ty);
+ }
+ }
+ }
+
+ pat_ty.unwrap_or_else(|| {
+ self.infer_expr(expr, &Expectation::has_type(expected.clone()))
+ })
+ }
Pat::Box { inner } => match self.resolve_boxed_box() {
Some(box_adt) => {
let (inner_ty, alloc_ty) = match expected.as_adt() {
@@ -343,7 +366,9 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
// FIXME: ConstBlock/Path/Lit might actually evaluate to ref, but inference is unimplemented.
Pat::Path(..) => true,
Pat::ConstBlock(..) => true,
- Pat::Lit(expr) => !matches!(body[*expr], Expr::Literal(Literal::String(..))),
+ Pat::Lit(expr) => {
+ !matches!(body[*expr], Expr::Literal(Literal::String(..) | Literal::ByteString(..)))
+ }
Pat::Bind {
mode: BindingAnnotation::Mutable | BindingAnnotation::Unannotated,
subpat: Some(subpat),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
new file mode 100644
index 000000000..0c547192a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
@@ -0,0 +1,173 @@
+//! Type inhabitedness logic.
+use std::ops::ControlFlow::{self, Break, Continue};
+
+use chalk_ir::{
+ visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
+ DebruijnIndex,
+};
+use hir_def::{
+ adt::VariantData, attr::Attrs, type_ref::ConstScalar, visibility::Visibility, AdtId,
+ EnumVariantId, HasModule, Lookup, ModuleId, VariantId,
+};
+
+use crate::{
+ db::HirDatabase, Binders, ConcreteConst, Const, ConstValue, Interner, Substitution, Ty, TyKind,
+};
+
+/// Checks whether a type is visibly uninhabited from a particular module.
+pub(crate) fn is_ty_uninhabited_from(ty: &Ty, target_mod: ModuleId, db: &dyn HirDatabase) -> bool {
+ let mut uninhabited_from = UninhabitedFrom { target_mod, db };
+ let inhabitedness = ty.visit_with(&mut uninhabited_from, DebruijnIndex::INNERMOST);
+ inhabitedness == BREAK_VISIBLY_UNINHABITED
+}
+
+/// Checks whether a variant is visibly uninhabited from a particular module.
+pub(crate) fn is_enum_variant_uninhabited_from(
+ variant: EnumVariantId,
+ subst: &Substitution,
+ target_mod: ModuleId,
+ db: &dyn HirDatabase,
+) -> bool {
+ let enum_data = db.enum_data(variant.parent);
+ let vars_attrs = db.variants_attrs(variant.parent);
+ let is_local = variant.parent.lookup(db.upcast()).container.krate() == target_mod.krate();
+
+ let mut uninhabited_from = UninhabitedFrom { target_mod, db };
+ let inhabitedness = uninhabited_from.visit_variant(
+ variant.into(),
+ &enum_data.variants[variant.local_id].variant_data,
+ subst,
+ &vars_attrs[variant.local_id],
+ is_local,
+ );
+ inhabitedness == BREAK_VISIBLY_UNINHABITED
+}
+
+struct UninhabitedFrom<'a> {
+ target_mod: ModuleId,
+ db: &'a dyn HirDatabase,
+}
+
+const CONTINUE_OPAQUELY_INHABITED: ControlFlow<VisiblyUninhabited> = Continue(());
+const BREAK_VISIBLY_UNINHABITED: ControlFlow<VisiblyUninhabited> = Break(VisiblyUninhabited);
+#[derive(PartialEq, Eq)]
+struct VisiblyUninhabited;
+
+impl TypeVisitor<Interner> for UninhabitedFrom<'_> {
+ type BreakTy = VisiblyUninhabited;
+
+ fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = VisiblyUninhabited> {
+ self
+ }
+
+ fn visit_ty(
+ &mut self,
+ ty: &Ty,
+ outer_binder: DebruijnIndex,
+ ) -> ControlFlow<VisiblyUninhabited> {
+ match ty.kind(Interner) {
+ TyKind::Adt(adt, subst) => self.visit_adt(adt.0, subst),
+ TyKind::Never => BREAK_VISIBLY_UNINHABITED,
+ TyKind::Tuple(..) => ty.super_visit_with(self, outer_binder),
+ TyKind::Array(item_ty, len) => match try_usize_const(len) {
+ Some(0) | None => CONTINUE_OPAQUELY_INHABITED,
+ Some(1..) => item_ty.super_visit_with(self, outer_binder),
+ },
+
+ TyKind::Ref(..) | _ => CONTINUE_OPAQUELY_INHABITED,
+ }
+ }
+
+ fn interner(&self) -> Interner {
+ Interner
+ }
+}
+
+impl UninhabitedFrom<'_> {
+ fn visit_adt(&mut self, adt: AdtId, subst: &Substitution) -> ControlFlow<VisiblyUninhabited> {
+ let attrs = self.db.attrs(adt.into());
+ let adt_non_exhaustive = attrs.by_key("non_exhaustive").exists();
+ let is_local = adt.module(self.db.upcast()).krate() == self.target_mod.krate();
+ if adt_non_exhaustive && !is_local {
+ return CONTINUE_OPAQUELY_INHABITED;
+ }
+
+ // An ADT is uninhabited iff all its variants uninhabited.
+ match adt {
+ // rustc: For now, `union`s are never considered uninhabited.
+ AdtId::UnionId(_) => CONTINUE_OPAQUELY_INHABITED,
+ AdtId::StructId(s) => {
+ let struct_data = self.db.struct_data(s);
+ self.visit_variant(s.into(), &struct_data.variant_data, subst, &attrs, is_local)
+ }
+ AdtId::EnumId(e) => {
+ let vars_attrs = self.db.variants_attrs(e);
+ let enum_data = self.db.enum_data(e);
+
+ for (local_id, enum_var) in enum_data.variants.iter() {
+ let variant_inhabitedness = self.visit_variant(
+ EnumVariantId { parent: e, local_id }.into(),
+ &enum_var.variant_data,
+ subst,
+ &vars_attrs[local_id],
+ is_local,
+ );
+ match variant_inhabitedness {
+ Break(VisiblyUninhabited) => continue,
+ Continue(()) => return CONTINUE_OPAQUELY_INHABITED,
+ }
+ }
+ BREAK_VISIBLY_UNINHABITED
+ }
+ }
+ }
+
+ fn visit_variant(
+ &mut self,
+ variant: VariantId,
+ variant_data: &VariantData,
+ subst: &Substitution,
+ attrs: &Attrs,
+ is_local: bool,
+ ) -> ControlFlow<VisiblyUninhabited> {
+ let non_exhaustive_field_list = attrs.by_key("non_exhaustive").exists();
+ if non_exhaustive_field_list && !is_local {
+ return CONTINUE_OPAQUELY_INHABITED;
+ }
+
+ let is_enum = matches!(variant, VariantId::EnumVariantId(..));
+ let field_tys = self.db.field_types(variant);
+ let field_vis = self.db.field_visibilities(variant);
+
+ for (fid, _) in variant_data.fields().iter() {
+ self.visit_field(field_vis[fid], &field_tys[fid], subst, is_enum)?;
+ }
+ CONTINUE_OPAQUELY_INHABITED
+ }
+
+ fn visit_field(
+ &mut self,
+ vis: Visibility,
+ ty: &Binders<Ty>,
+ subst: &Substitution,
+ is_enum: bool,
+ ) -> ControlFlow<VisiblyUninhabited> {
+ if is_enum || vis.is_visible_from(self.db.upcast(), self.target_mod) {
+ let ty = ty.clone().substitute(Interner, subst);
+ ty.visit_with(self, DebruijnIndex::INNERMOST)
+ } else {
+ CONTINUE_OPAQUELY_INHABITED
+ }
+ }
+}
+
+fn try_usize_const(c: &Const) -> Option<u128> {
+ let data = &c.data(Interner);
+ if data.ty.kind(Interner) != &TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)) {
+ return None;
+ }
+ match data.value {
+ ConstValue::Concrete(ConcreteConst { interned: ConstScalar::UInt(value) }) => Some(value),
+ _ => None,
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 5a5d610e3..a82a331d4 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -14,6 +14,7 @@ mod chalk_db;
mod chalk_ext;
pub mod consteval;
mod infer;
+mod inhabitedness;
mod interner;
mod lower;
mod mapping;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 3ed9c941f..532544fee 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -1,12 +1,12 @@
//! Methods for lowering the HIR to types. There are two main cases here:
//!
//! - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
-//! type: The entry point for this is `Ty::from_hir`.
-//! - Building the type for an item: This happens through the `type_for_def` query.
+//! type: The entry point for this is `TyLoweringContext::lower_ty`.
+//! - Building the type for an item: This happens through the `ty` query.
//!
//! This usually involves resolving names, collecting generic arguments etc.
use std::{
- cell::{Cell, RefCell},
+ cell::{Cell, RefCell, RefMut},
iter,
sync::Arc,
};
@@ -47,7 +47,7 @@ use crate::{
consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic},
db::HirDatabase,
make_binders,
- mapping::ToChalk,
+ mapping::{from_chalk_trait_id, ToChalk},
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
utils::Generics,
utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
@@ -238,18 +238,7 @@ impl<'a> TyLoweringContext<'a> {
})
.intern(Interner)
}
- TypeRef::DynTrait(bounds) => {
- let self_ty =
- TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
- let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
- QuantifiedWhereClauses::from_iter(
- Interner,
- bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
- )
- });
- let bounds = crate::make_single_type_binders(bounds);
- TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
- }
+ TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
TypeRef::ImplTrait(bounds) => {
match self.impl_trait_mode {
ImplTraitLoweringMode::Opaque => {
@@ -341,26 +330,29 @@ impl<'a> TyLoweringContext<'a> {
}
}
TypeRef::Macro(macro_call) => {
- let (expander, recursion_start) = {
- let mut expander = self.expander.borrow_mut();
- if expander.is_some() {
- (Some(expander), false)
- } else {
- *expander = Some(Expander::new(
- self.db.upcast(),
- macro_call.file_id,
- self.resolver.module(),
- ));
- (Some(expander), true)
+ let (mut expander, recursion_start) = {
+ match RefMut::filter_map(self.expander.borrow_mut(), Option::as_mut) {
+ // There already is an expander here, this means we are already recursing
+ Ok(expander) => (expander, false),
+ // No expander was created yet, so we are at the start of the expansion recursion
+ // and therefore have to create an expander.
+ Err(expander) => (
+ RefMut::map(expander, |it| {
+ it.insert(Expander::new(
+ self.db.upcast(),
+ macro_call.file_id,
+ self.resolver.module(),
+ ))
+ }),
+ true,
+ ),
}
};
- let ty = if let Some(mut expander) = expander {
- let expander_mut = expander.as_mut().unwrap();
+ let ty = {
let macro_call = macro_call.to_node(self.db.upcast());
- match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
+ match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
- let ctx =
- LowerCtx::new(self.db.upcast(), expander_mut.current_file_id());
+ let ctx = LowerCtx::new(self.db.upcast(), expander.current_file_id());
let type_ref = TypeRef::from_ast(&ctx, expanded);
drop(expander);
@@ -373,11 +365,14 @@ impl<'a> TyLoweringContext<'a> {
.exit(self.db.upcast(), mark);
Some(ty)
}
- _ => None,
+ _ => {
+ drop(expander);
+ None
+ }
}
- } else {
- None
};
+
+ // drop the expander, resetting it to pre-recursion state
if recursion_start {
*self.expander.borrow_mut() = None;
}
@@ -468,29 +463,10 @@ impl<'a> TyLoweringContext<'a> {
}
}
0 => {
- let self_ty = Some(
- TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
- .intern(Interner),
- );
- let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
- ctx.lower_trait_ref_from_resolved_path(
- trait_,
- resolved_segment,
- self_ty,
- )
- });
- let dyn_ty = DynTy {
- bounds: crate::make_single_type_binders(
- QuantifiedWhereClauses::from_iter(
- Interner,
- Some(crate::wrap_empty_binders(WhereClause::Implemented(
- trait_ref,
- ))),
- ),
- ),
- lifetime: static_lifetime(),
- };
- TyKind::Dyn(dyn_ty).intern(Interner)
+ // Trait object type without dyn; this should be handled in upstream. See
+ // `lower_path()`.
+ stdx::never!("unexpected fully resolved trait path");
+ TyKind::Error.intern(Interner)
}
_ => {
// FIXME report error (ambiguous associated type)
@@ -509,7 +485,14 @@ impl<'a> TyLoweringContext<'a> {
TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
}
ParamLoweringMode::Variable => {
- let idx = generics.param_idx(param_id.into()).expect("matching generics");
+ let idx = match generics.param_idx(param_id.into()) {
+ None => {
+ never!("no matching generics");
+ return (TyKind::Error.intern(Interner), None);
+ }
+ Some(idx) => idx,
+ };
+
TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
}
}
@@ -555,11 +538,20 @@ impl<'a> TyLoweringContext<'a> {
let (ty, res) = self.lower_ty_ext(type_ref);
return self.lower_ty_relative_path(ty, res, path.segments());
}
+
let (resolution, remaining_index) =
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
Some(it) => it,
None => return (TyKind::Error.intern(Interner), None),
};
+
+ if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
+ // trait object type without dyn
+ let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
+ let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
+ return (ty, None);
+ }
+
let (resolved_segment, remaining_segments) = match remaining_index {
None => (
path.segments().last().expect("resolved path has at least one element"),
@@ -987,6 +979,78 @@ impl<'a> TyLoweringContext<'a> {
})
}
+ fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
+ let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
+ // INVARIANT: The principal trait bound must come first. Others may be in any order but
+ // should be in the same order for the same set but possibly different order of bounds in
+ // the input.
+ // This invariant is used by `TyExt::dyn_trait()` and chalk.
+ let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
+ let mut bounds: Vec<_> = bounds
+ .iter()
+ .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
+ .collect();
+
+ let mut multiple_regular_traits = false;
+ let mut multiple_same_projection = false;
+ bounds.sort_unstable_by(|lhs, rhs| {
+ use std::cmp::Ordering;
+ match (lhs.skip_binders(), rhs.skip_binders()) {
+ (WhereClause::Implemented(lhs), WhereClause::Implemented(rhs)) => {
+ let lhs_id = lhs.trait_id;
+ let lhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(lhs_id)).is_auto;
+ let rhs_id = rhs.trait_id;
+ let rhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(rhs_id)).is_auto;
+
+ if !lhs_is_auto && !rhs_is_auto {
+ multiple_regular_traits = true;
+ }
+ // Note that the ordering here is important; this ensures the invariant
+ // mentioned above.
+ (lhs_is_auto, lhs_id).cmp(&(rhs_is_auto, rhs_id))
+ }
+ (WhereClause::Implemented(_), _) => Ordering::Less,
+ (_, WhereClause::Implemented(_)) => Ordering::Greater,
+ (WhereClause::AliasEq(lhs), WhereClause::AliasEq(rhs)) => {
+ match (&lhs.alias, &rhs.alias) {
+ (AliasTy::Projection(lhs_proj), AliasTy::Projection(rhs_proj)) => {
+ // We only compare the `associated_ty_id`s. We shouldn't have
+ // multiple bounds for an associated type in the correct Rust code,
+ // and if we do, we error out.
+ if lhs_proj.associated_ty_id == rhs_proj.associated_ty_id {
+ multiple_same_projection = true;
+ }
+ lhs_proj.associated_ty_id.cmp(&rhs_proj.associated_ty_id)
+ }
+ // We don't produce `AliasTy::Opaque`s yet.
+ _ => unreachable!(),
+ }
+ }
+ // We don't produce `WhereClause::{TypeOutlives, LifetimeOutlives}` yet.
+ _ => unreachable!(),
+ }
+ });
+
+ if multiple_regular_traits || multiple_same_projection {
+ return None;
+ }
+
+ // As multiple occurrences of the same auto traits *are* permitted, we dedulicate the
+ // bounds. We shouldn't have repeated elements besides auto traits at this point.
+ bounds.dedup();
+
+ Some(QuantifiedWhereClauses::from_iter(Interner, bounds))
+ });
+
+ if let Some(bounds) = bounds {
+ let bounds = crate::make_single_type_binders(bounds);
+ TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
+ } else {
+ // FIXME: report error (additional non-auto traits or associated type rebound)
+ TyKind::Error.intern(Interner)
+ }
+ }
+
fn lower_impl_trait(
&self,
bounds: &[Interned<TypeBound>],
@@ -1126,7 +1190,7 @@ pub(crate) fn field_types_query(
let ctx =
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
for (field_id, field_data) in var_data.fields().iter() {
- res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)))
+ res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
}
Arc::new(res)
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
index 15df7b3dd..9a63d5013 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -336,7 +336,7 @@ impl InherentImpls {
}
}
-pub fn inherent_impl_crates_query(
+pub(crate) fn inherent_impl_crates_query(
db: &dyn HirDatabase,
krate: CrateId,
fp: TyFingerprint,
@@ -419,6 +419,55 @@ pub fn def_crates(
}
}
+pub fn lang_names_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Name, Name)> {
+ use hir_expand::name;
+ use syntax::ast::{ArithOp, BinaryOp, CmpOp, Ordering};
+ Some(match op {
+ BinaryOp::LogicOp(_) => return None,
+ BinaryOp::ArithOp(aop) => match aop {
+ ArithOp::Add => (name!(add), name!(add)),
+ ArithOp::Mul => (name!(mul), name!(mul)),
+ ArithOp::Sub => (name!(sub), name!(sub)),
+ ArithOp::Div => (name!(div), name!(div)),
+ ArithOp::Rem => (name!(rem), name!(rem)),
+ ArithOp::Shl => (name!(shl), name!(shl)),
+ ArithOp::Shr => (name!(shr), name!(shr)),
+ ArithOp::BitXor => (name!(bitxor), name!(bitxor)),
+ ArithOp::BitOr => (name!(bitor), name!(bitor)),
+ ArithOp::BitAnd => (name!(bitand), name!(bitand)),
+ },
+ BinaryOp::Assignment { op: Some(aop) } => match aop {
+ ArithOp::Add => (name!(add_assign), name!(add_assign)),
+ ArithOp::Mul => (name!(mul_assign), name!(mul_assign)),
+ ArithOp::Sub => (name!(sub_assign), name!(sub_assign)),
+ ArithOp::Div => (name!(div_assign), name!(div_assign)),
+ ArithOp::Rem => (name!(rem_assign), name!(rem_assign)),
+ ArithOp::Shl => (name!(shl_assign), name!(shl_assign)),
+ ArithOp::Shr => (name!(shr_assign), name!(shr_assign)),
+ ArithOp::BitXor => (name!(bitxor_assign), name!(bitxor_assign)),
+ ArithOp::BitOr => (name!(bitor_assign), name!(bitor_assign)),
+ ArithOp::BitAnd => (name!(bitand_assign), name!(bitand_assign)),
+ },
+ BinaryOp::CmpOp(cop) => match cop {
+ CmpOp::Eq { negated: false } => (name!(eq), name!(eq)),
+ CmpOp::Eq { negated: true } => (name!(ne), name!(eq)),
+ CmpOp::Ord { ordering: Ordering::Less, strict: false } => {
+ (name!(le), name!(partial_ord))
+ }
+ CmpOp::Ord { ordering: Ordering::Less, strict: true } => {
+ (name!(lt), name!(partial_ord))
+ }
+ CmpOp::Ord { ordering: Ordering::Greater, strict: false } => {
+ (name!(ge), name!(partial_ord))
+ }
+ CmpOp::Ord { ordering: Ordering::Greater, strict: true } => {
+ (name!(gt), name!(partial_ord))
+ }
+ },
+ BinaryOp::Assignment { op: None } => return None,
+ })
+}
+
/// Look up the method with the given name.
pub(crate) fn lookup_method(
ty: &Canonical<Ty>,
@@ -1015,6 +1064,14 @@ pub fn resolve_indexing_op(
None
}
+macro_rules! check_that {
+ ($cond:expr) => {
+ if !$cond {
+ return false;
+ }
+ };
+}
+
fn is_valid_candidate(
table: &mut InferenceTable<'_>,
name: Option<&Name>,
@@ -1023,54 +1080,10 @@ fn is_valid_candidate(
self_ty: &Ty,
visible_from_module: Option<ModuleId>,
) -> bool {
- macro_rules! check_that {
- ($cond:expr) => {
- if !$cond {
- return false;
- }
- };
- }
-
let db = table.db;
match item {
AssocItemId::FunctionId(m) => {
- let data = db.function_data(m);
-
- check_that!(name.map_or(true, |n| n == &data.name));
- check_that!(visible_from_module.map_or(true, |from_module| {
- let v = db.function_visibility(m).is_visible_from(db.upcast(), from_module);
- if !v {
- cov_mark::hit!(autoderef_candidate_not_visible);
- }
- v
- }));
-
- table.run_in_snapshot(|table| {
- let subst = TyBuilder::subst_for_def(db, m).fill_with_inference_vars(table).build();
- let expect_self_ty = match m.lookup(db.upcast()).container {
- ItemContainerId::TraitId(_) => {
- subst.at(Interner, 0).assert_ty_ref(Interner).clone()
- }
- ItemContainerId::ImplId(impl_id) => {
- subst.apply(db.impl_self_ty(impl_id).skip_binders().clone(), Interner)
- }
- // We should only get called for associated items (impl/trait)
- ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
- unreachable!()
- }
- };
- check_that!(table.unify(&expect_self_ty, self_ty));
- if let Some(receiver_ty) = receiver_ty {
- check_that!(data.has_self_param());
-
- let sig = db.callable_item_signature(m.into());
- let expected_receiver =
- sig.map(|s| s.params()[0].clone()).substitute(Interner, &subst);
-
- check_that!(table.unify(&receiver_ty, &expected_receiver));
- }
- true
- })
+ is_valid_fn_candidate(table, m, name, receiver_ty, self_ty, visible_from_module)
}
AssocItemId::ConstId(c) => {
let data = db.const_data(c);
@@ -1103,6 +1116,94 @@ fn is_valid_candidate(
}
}
+fn is_valid_fn_candidate(
+ table: &mut InferenceTable<'_>,
+ fn_id: FunctionId,
+ name: Option<&Name>,
+ receiver_ty: Option<&Ty>,
+ self_ty: &Ty,
+ visible_from_module: Option<ModuleId>,
+) -> bool {
+ let db = table.db;
+ let data = db.function_data(fn_id);
+
+ check_that!(name.map_or(true, |n| n == &data.name));
+ check_that!(visible_from_module.map_or(true, |from_module| {
+ let v = db.function_visibility(fn_id).is_visible_from(db.upcast(), from_module);
+ if !v {
+ cov_mark::hit!(autoderef_candidate_not_visible);
+ }
+ v
+ }));
+
+ table.run_in_snapshot(|table| {
+ let container = fn_id.lookup(db.upcast()).container;
+ let impl_subst = match container {
+ ItemContainerId::ImplId(it) => {
+ TyBuilder::subst_for_def(db, it).fill_with_inference_vars(table).build()
+ }
+ ItemContainerId::TraitId(it) => {
+ TyBuilder::subst_for_def(db, it).fill_with_inference_vars(table).build()
+ }
+ _ => unreachable!(),
+ };
+
+ let fn_subst = TyBuilder::subst_for_def(db, fn_id)
+ .use_parent_substs(&impl_subst)
+ .fill_with_inference_vars(table)
+ .build();
+
+ let expect_self_ty = match container {
+ ItemContainerId::TraitId(_) => fn_subst.at(Interner, 0).assert_ty_ref(Interner).clone(),
+ ItemContainerId::ImplId(impl_id) => {
+ fn_subst.apply(db.impl_self_ty(impl_id).skip_binders().clone(), Interner)
+ }
+ // We should only get called for associated items (impl/trait)
+ ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
+ unreachable!()
+ }
+ };
+ check_that!(table.unify(&expect_self_ty, self_ty));
+
+ if let Some(receiver_ty) = receiver_ty {
+ check_that!(data.has_self_param());
+
+ let sig = db.callable_item_signature(fn_id.into());
+ let expected_receiver =
+ sig.map(|s| s.params()[0].clone()).substitute(Interner, &fn_subst);
+
+ check_that!(table.unify(&receiver_ty, &expected_receiver));
+ }
+
+ if let ItemContainerId::ImplId(impl_id) = container {
+ // We need to consider the bounds on the impl to distinguish functions of the same name
+ // for a type.
+ let predicates = db.generic_predicates(impl_id.into());
+ predicates
+ .iter()
+ .map(|predicate| {
+ let (p, b) = predicate
+ .clone()
+ .substitute(Interner, &impl_subst)
+ // Skipping the inner binders is ok, as we don't handle quantified where
+ // clauses yet.
+ .into_value_and_skipped_binders();
+ stdx::always!(b.len(Interner) == 0);
+ p
+ })
+ // It's ok to get ambiguity here, as we may not have enough information to prove
+ // obligations. We'll check if the user is calling the selected method properly
+ // later anyway.
+ .all(|p| table.try_obligation(p.cast(Interner)).is_some())
+ } else {
+ // For `ItemContainerId::TraitId`, we check if `self_ty` implements the trait in
+ // `iterate_trait_method_candidates()`.
+ // For others, this function shouldn't be called.
+ true
+ }
+ })
+}
+
pub fn implements_trait(
ty: &Canonical<Ty>,
db: &dyn HirDatabase,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
index dc7252f70..118e5311e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
@@ -10,7 +10,7 @@ use base_db::{
};
use hir_def::{db::DefDatabase, ModuleId};
use hir_expand::db::AstDatabase;
-use rustc_hash::{FxHashMap, FxHashSet};
+use stdx::hash::{NoHashHashMap, NoHashHashSet};
use syntax::TextRange;
use test_utils::extract_annotations;
@@ -80,7 +80,7 @@ impl FileLoader for TestDB {
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
FileLoaderDelegate(self).resolve_path(path)
}
- fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+ fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
FileLoaderDelegate(self).relevant_crates(file_id)
}
}
@@ -102,7 +102,7 @@ impl TestDB {
self.module_for_file_opt(file_id).unwrap()
}
- pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
+ pub(crate) fn extract_annotations(&self) -> NoHashHashMap<FileId, Vec<(TextRange, String)>> {
let mut files = Vec::new();
let crate_graph = self.crate_graph();
for krate in crate_graph.iter() {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
index a1ab6060e..b3adafaaf 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
@@ -193,8 +193,6 @@ fn expr_macro_def_expanded_in_various_places() {
!0..6 '1isize': isize
!0..6 '1isize': isize
!0..6 '1isize': isize
- !0..6 '1isize': isize
- !0..6 '1isize': isize
39..442 '{ ...!(); }': ()
73..94 'spam!(...am!())': {unknown}
100..119 'for _ ...!() {}': ()
@@ -276,8 +274,6 @@ fn expr_macro_rules_expanded_in_various_places() {
!0..6 '1isize': isize
!0..6 '1isize': isize
!0..6 '1isize': isize
- !0..6 '1isize': isize
- !0..6 '1isize': isize
53..456 '{ ...!(); }': ()
87..108 'spam!(...am!())': {unknown}
114..133 'for _ ...!() {}': ()
@@ -312,7 +308,6 @@ fn expr_macro_expanded_in_stmts() {
}
"#,
expect![[r#"
- !0..8 'leta=();': ()
!3..4 'a': ()
!5..7 '()': ()
57..84 '{ ...); } }': ()
@@ -321,7 +316,7 @@ fn expr_macro_expanded_in_stmts() {
}
#[test]
-fn recurisve_macro_expanded_in_stmts() {
+fn recursive_macro_expanded_in_stmts() {
check_infer(
r#"
macro_rules! ng {
@@ -340,11 +335,6 @@ fn recurisve_macro_expanded_in_stmts() {
}
"#,
expect![[r#"
- !0..7 'leta=3;': ()
- !0..13 'ng!{[leta=3]}': ()
- !0..13 'ng!{[leta=]3}': ()
- !0..13 'ng!{[leta]=3}': ()
- !0..13 'ng!{[let]a=3}': ()
!3..4 'a': i32
!5..6 '3': i32
196..237 '{ ...= a; }': ()
@@ -369,8 +359,6 @@ fn recursive_inner_item_macro_rules() {
"#,
expect![[r#"
!0..1 '1': i32
- !0..7 'mac!($)': ()
- !0..26 'macro_...>{1};}': ()
107..143 '{ ...!(); }': ()
129..130 'a': i32
"#]],
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
index 68463dc06..81588a7c4 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
@@ -1790,3 +1790,46 @@ impl u16 {
"#,
)
}
+
+#[test]
+fn with_impl_bounds() {
+ check_types(
+ r#"
+trait Trait {}
+struct Foo<T>(T);
+impl Trait for isize {}
+
+impl<T: Trait> Foo<T> {
+ fn foo() -> isize { 0 }
+ fn bar(&self) -> isize { 0 }
+}
+
+impl Foo<()> {
+ fn foo() {}
+ fn bar(&self) {}
+}
+
+fn f() {
+ let _ = Foo::<isize>::foo();
+ //^isize
+ let _ = Foo(0isize).bar();
+ //^isize
+ let _ = Foo::<()>::foo();
+ //^()
+ let _ = Foo(()).bar();
+ //^()
+ let _ = Foo::<usize>::foo();
+ //^{unknown}
+ let _ = Foo(0usize).bar();
+ //^{unknown}
+}
+
+fn g<T: Trait>(a: T) {
+ let _ = Foo::<T>::foo();
+ //^isize
+ let _ = Foo(a).bar();
+ //^isize
+}
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
index 399553356..eb04bf877 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
@@ -316,6 +316,51 @@ fn infer_pattern_match_string_literal() {
}
#[test]
+fn infer_pattern_match_byte_string_literal() {
+ check_infer_with_mismatches(
+ r#"
+ //- minicore: index
+ struct S;
+ impl<T, const N: usize> core::ops::Index<S> for [T; N] {
+ type Output = [u8];
+ fn index(&self, index: core::ops::RangeFull) -> &Self::Output {
+ loop {}
+ }
+ }
+ fn test(v: [u8; 3]) {
+ if let b"foo" = &v[S] {}
+ if let b"foo" = &v {}
+ }
+ "#,
+ expect![[r#"
+ 105..109 'self': &[T; N]
+ 111..116 'index': {unknown}
+ 157..180 '{ ... }': &[u8]
+ 167..174 'loop {}': !
+ 172..174 '{}': ()
+ 191..192 'v': [u8; 3]
+ 203..261 '{ ...v {} }': ()
+ 209..233 'if let...[S] {}': ()
+ 212..230 'let b"... &v[S]': bool
+ 216..222 'b"foo"': &[u8]
+ 216..222 'b"foo"': &[u8]
+ 225..230 '&v[S]': &[u8]
+ 226..227 'v': [u8; 3]
+ 226..230 'v[S]': [u8]
+ 228..229 'S': S
+ 231..233 '{}': ()
+ 238..259 'if let... &v {}': ()
+ 241..256 'let b"foo" = &v': bool
+ 245..251 'b"foo"': &[u8; 3]
+ 245..251 'b"foo"': &[u8; 3]
+ 254..256 '&v': &[u8; 3]
+ 255..256 'v': [u8; 3]
+ 257..259 '{}': ()
+ "#]],
+ );
+}
+
+#[test]
fn infer_pattern_match_or() {
check_infer_with_mismatches(
r#"
@@ -444,6 +489,42 @@ fn infer_adt_pattern() {
}
#[test]
+fn tuple_struct_destructured_with_self() {
+ check_infer(
+ r#"
+struct Foo(usize,);
+impl Foo {
+ fn f() {
+ let Self(s,) = &Foo(0,);
+ let Self(s,) = &mut Foo(0,);
+ let Self(s,) = Foo(0,);
+ }
+}
+ "#,
+ expect![[r#"
+ 42..151 '{ ... }': ()
+ 56..64 'Self(s,)': Foo
+ 61..62 's': &usize
+ 67..75 '&Foo(0,)': &Foo
+ 68..71 'Foo': Foo(usize) -> Foo
+ 68..75 'Foo(0,)': Foo
+ 72..73 '0': usize
+ 89..97 'Self(s,)': Foo
+ 94..95 's': &mut usize
+ 100..112 '&mut Foo(0,)': &mut Foo
+ 105..108 'Foo': Foo(usize) -> Foo
+ 105..112 'Foo(0,)': Foo
+ 109..110 '0': usize
+ 126..134 'Self(s,)': Foo
+ 131..132 's': usize
+ 137..140 'Foo': Foo(usize) -> Foo
+ 137..144 'Foo(0,)': Foo
+ 141..142 '0': usize
+ "#]],
+ );
+}
+
+#[test]
fn enum_variant_through_self_in_pattern() {
check_infer(
r#"
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
index 93a88ab58..23e51a9c1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -573,7 +573,6 @@ fn issue_6811() {
}
"#,
expect![[r#"
- !0..16 'let_a=...t_b=1;': ()
!3..5 '_a': i32
!6..7 '1': i32
!11..13 '_b': i32
@@ -1527,6 +1526,34 @@ unsafe impl Storage for InlineStorage {
}
#[test]
+fn gat_crash_3() {
+ // FIXME: This test currently crashes rust analyzer in a debug build but not in a
+ // release build (i.e. for the user). With the assumption that tests will always be run
+ // in debug mode, we catch the unwind and expect that it panicked. See the
+ // [`crate::utils::generics`] function for more information.
+ cov_mark::check!(ignore_gats);
+ std::panic::catch_unwind(|| {
+ check_no_mismatches(
+ r#"
+trait Collection {
+ type Item;
+ type Member<T>: Collection<Item = T>;
+ fn add(&mut self, value: Self::Item) -> Result<(), Self::Error>;
+}
+struct ConstGen<T, const N: usize> {
+ data: [T; N],
+}
+impl<T, const N: usize> Collection for ConstGen<T, N> {
+ type Item = T;
+ type Member<U> = ConstGen<U, N>;
+}
+ "#,
+ );
+ })
+ .expect_err("must panic");
+}
+
+#[test]
fn cfgd_out_self_param() {
cov_mark::check!(cfgd_out_self_param);
check_no_mismatches(
@@ -1648,3 +1675,19 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn trailing_empty_macro() {
+ check_no_mismatches(
+ r#"
+macro_rules! m2 {
+ ($($t:tt)*) => {$($t)*};
+}
+
+fn macrostmts() -> u8 {
+ m2! { 0 }
+ m2! {}
+}
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
index 5b08f5521..4ea103e5d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
@@ -2549,7 +2549,6 @@ impl B for Astruct {}
expect![[r#"
569..573 'self': Box<[T], A>
602..634 '{ ... }': Vec<T, A>
- 612..628 'unimpl...ted!()': Vec<T, A>
648..761 '{ ...t]); }': ()
658..661 'vec': Vec<i32, Global>
664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
@@ -3070,3 +3069,17 @@ fn main() {
"#,
);
}
+
+#[test]
+fn nested_break() {
+ check_no_mismatches(
+ r#"
+fn func() {
+ let int = loop {
+ break 0;
+ break (break 0);
+ };
+}
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
index 75802a5eb..21a863197 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -138,6 +138,31 @@ fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
}
#[test]
+fn into_future_trait() {
+ check_types(
+ r#"
+//- minicore: future
+struct Futurable;
+impl core::future::IntoFuture for Futurable {
+ type Output = u64;
+ type IntoFuture = IntFuture;
+}
+
+struct IntFuture;
+impl core::future::Future for IntFuture {
+ type Output = u64;
+}
+
+fn test() {
+ let r = Futurable;
+ let v = r.await;
+ v;
+} //^ u64
+"#,
+ );
+}
+
+#[test]
fn infer_try() {
check_types(
r#"
@@ -1476,6 +1501,34 @@ fn test(x: Trait, y: &Trait) -> u64 {
165..172 'z.foo()': u64
"#]],
);
+
+ check_infer_with_mismatches(
+ r#"
+//- minicore: fn, coerce_unsized
+struct S;
+impl S {
+ fn foo(&self) {}
+}
+fn f(_: &Fn(S)) {}
+fn main() {
+ f(&|number| number.foo());
+}
+ "#,
+ expect![[r#"
+ 31..35 'self': &S
+ 37..39 '{}': ()
+ 47..48 '_': &dyn Fn(S)
+ 58..60 '{}': ()
+ 71..105 '{ ...()); }': ()
+ 77..78 'f': fn f(&dyn Fn(S))
+ 77..102 'f(&|nu...foo())': ()
+ 79..101 '&|numb....foo()': &|S| -> ()
+ 80..101 '|numbe....foo()': |S| -> ()
+ 81..87 'number': S
+ 89..95 'number': S
+ 89..101 'number.foo()': ()
+ "#]],
+ )
}
#[test]
@@ -3780,3 +3833,123 @@ fn test() {
"#,
)
}
+
+#[test]
+fn dyn_multiple_auto_traits_in_different_order() {
+ check_no_mismatches(
+ r#"
+auto trait Send {}
+auto trait Sync {}
+
+fn f(t: &(dyn Sync + Send)) {}
+fn g(t: &(dyn Send + Sync)) {
+ f(t);
+}
+ "#,
+ );
+
+ check_no_mismatches(
+ r#"
+auto trait Send {}
+auto trait Sync {}
+trait T {}
+
+fn f(t: &(dyn T + Send + Sync)) {}
+fn g(t: &(dyn Sync + T + Send)) {
+ f(t);
+}
+ "#,
+ );
+
+ check_infer_with_mismatches(
+ r#"
+auto trait Send {}
+auto trait Sync {}
+trait T1 {}
+trait T2 {}
+
+fn f(t: &(dyn T1 + T2 + Send + Sync)) {}
+fn g(t: &(dyn Sync + T2 + T1 + Send)) {
+ f(t);
+}
+ "#,
+ expect![[r#"
+ 68..69 't': &{unknown}
+ 101..103 '{}': ()
+ 109..110 't': &{unknown}
+ 142..155 '{ f(t); }': ()
+ 148..149 'f': fn f(&{unknown})
+ 148..152 'f(t)': ()
+ 150..151 't': &{unknown}
+ "#]],
+ );
+
+ check_no_mismatches(
+ r#"
+auto trait Send {}
+auto trait Sync {}
+trait T {
+ type Proj: Send + Sync;
+}
+
+fn f(t: &(dyn T<Proj = ()> + Send + Sync)) {}
+fn g(t: &(dyn Sync + T<Proj = ()> + Send)) {
+ f(t);
+}
+ "#,
+ );
+}
+
+#[test]
+fn dyn_multiple_projection_bounds() {
+ check_no_mismatches(
+ r#"
+trait Trait {
+ type T;
+ type U;
+}
+
+fn f(t: &dyn Trait<T = (), U = ()>) {}
+fn g(t: &dyn Trait<U = (), T = ()>) {
+ f(t);
+}
+ "#,
+ );
+
+ check_types(
+ r#"
+trait Trait {
+ type T;
+}
+
+fn f(t: &dyn Trait<T = (), T = ()>) {}
+ //^&{unknown}
+ "#,
+ );
+}
+
+#[test]
+fn dyn_duplicate_auto_trait() {
+ check_no_mismatches(
+ r#"
+auto trait Send {}
+
+fn f(t: &(dyn Send + Send)) {}
+fn g(t: &(dyn Send)) {
+ f(t);
+}
+ "#,
+ );
+
+ check_no_mismatches(
+ r#"
+auto trait Send {}
+trait T {}
+
+fn f(t: &(dyn T + Send + Send)) {}
+fn g(t: &(dyn T + Send)) {
+ f(t);
+}
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index 83319755d..d6638db02 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -176,10 +176,19 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
if parent_generics.is_some() && matches!(def, GenericDefId::TypeAliasId(_)) {
let params = db.generic_params(def);
+ let parent_params = &parent_generics.as_ref().unwrap().params;
let has_consts =
params.iter().any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_)));
- return if has_consts {
- // XXX: treat const generic associated types as not existing to avoid crashes (#11769)
+ let parent_has_consts =
+ parent_params.iter().any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_)));
+ return if has_consts || parent_has_consts {
+ // XXX: treat const generic associated types as not existing to avoid crashes
+ // (#11769)
+ //
+ // Note: Also crashes when the parent has const generics (also even if the GAT
+ // doesn't use them), see `tests::regression::gat_crash_3` for an example.
+ // Avoids that by disabling GATs when the parent (i.e. `impl` block) has
+ // const generics (#12193).
//
// Chalk expects the inner associated type's parameters to come
// *before*, not after the trait's generics as we've always done it.
@@ -264,12 +273,8 @@ impl Generics {
fn find_param(&self, param: TypeOrConstParamId) -> Option<(usize, &TypeOrConstParamData)> {
if param.parent == self.def {
- let (idx, (_local_id, data)) = self
- .params
- .iter()
- .enumerate()
- .find(|(_, (idx, _))| *idx == param.local_id)
- .unwrap();
+ let (idx, (_local_id, data)) =
+ self.params.iter().enumerate().find(|(_, (idx, _))| *idx == param.local_id)?;
let parent_len = self.parent_generics().map_or(0, Generics::len);
Some((parent_len + idx, data))
} else {
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index 6c6c11ea4..5edc16d8b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -14,6 +14,7 @@ use crate::{MacroKind, Type};
macro_rules! diagnostics {
($($diag:ident,)*) => {
+ #[derive(Debug)]
pub enum AnyDiagnostic {$(
$diag(Box<$diag>),
)*}
@@ -123,6 +124,7 @@ pub struct NoSuchField {
#[derive(Debug)]
pub struct BreakOutsideOfLoop {
pub expr: InFile<AstPtr<ast::Expr>>,
+ pub is_break: bool,
}
#[derive(Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 8f984210e..e4bb63a86 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -72,7 +72,7 @@ use itertools::Itertools;
use nameres::diagnostics::DefDiagnosticKind;
use once_cell::unsync::Lazy;
use rustc_hash::FxHashSet;
-use stdx::{format_to, impl_from, never};
+use stdx::{impl_from, never};
use syntax::{
ast::{self, HasAttrs as _, HasDocComments, HasName},
AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T,
@@ -511,6 +511,7 @@ impl Module {
.collect()
}
+ /// Fills `acc` with the module's diagnostics.
pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
let _p = profile::span("Module::diagnostics").detail(|| {
format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string()))
@@ -531,11 +532,21 @@ impl Module {
m.diagnostics(db, acc)
}
}
+ ModuleDef::Trait(t) => {
+ for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
+ emit_def_diagnostic(db, acc, diag);
+ }
+ acc.extend(decl.diagnostics(db))
+ }
_ => acc.extend(decl.diagnostics(db)),
}
}
for impl_def in self.impl_defs(db) {
+ for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() {
+ emit_def_diagnostic(db, acc, diag);
+ }
+
for item in impl_def.items(db) {
let def: DefWithBody = match item {
AssocItem::Function(it) => it.into(),
@@ -1136,6 +1147,20 @@ impl DefWithBody {
}
}
+ fn id(&self) -> DefWithBodyId {
+ match self {
+ DefWithBody::Function(it) => it.id.into(),
+ DefWithBody::Static(it) => it.id.into(),
+ DefWithBody::Const(it) => it.id.into(),
+ }
+ }
+
+ /// A textual representation of the HIR of this def's body for debugging purposes.
+ pub fn debug_hir(self, db: &dyn HirDatabase) -> String {
+ let body = db.body(self.id());
+ body.pretty_print(db.upcast(), self.id())
+ }
+
pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
let krate = self.module(db).id.krate();
@@ -1191,11 +1216,11 @@ impl DefWithBody {
let field = source_map.field_syntax(*expr);
acc.push(NoSuchField { field }.into())
}
- hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
+ &hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr, is_break } => {
let expr = source_map
- .expr_syntax(*expr)
+ .expr_syntax(expr)
.expect("break outside of loop in synthetic syntax");
- acc.push(BreakOutsideOfLoop { expr }.into())
+ acc.push(BreakOutsideOfLoop { expr, is_break }.into())
}
hir_ty::InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
match source_map.expr_syntax(*call_expr) {
@@ -1470,19 +1495,6 @@ impl Function {
let def_map = db.crate_def_map(loc.krate(db).into());
def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() })
}
-
- /// A textual representation of the HIR of this function for debugging purposes.
- pub fn debug_hir(self, db: &dyn HirDatabase) -> String {
- let body = db.body(self.id.into());
-
- let mut result = String::new();
- format_to!(result, "HIR expressions in the body of `{}`:\n", self.name(db));
- for (id, expr) in body.exprs.iter() {
- format_to!(result, "{:?}: {:?}\n", id, expr);
- }
-
- result
- }
}
// Note: logically, this belongs to `hir_ty`, but we are not using it there yet.
@@ -2777,20 +2789,32 @@ impl Type {
self.ty.is_unknown()
}
- /// Checks that particular type `ty` implements `std::future::Future`.
+ /// Checks that particular type `ty` implements `std::future::IntoFuture` or
+ /// `std::future::Future`.
/// This function is used in `.await` syntax completion.
- pub fn impls_future(&self, db: &dyn HirDatabase) -> bool {
- let std_future_trait = db
- .lang_item(self.env.krate, SmolStr::new_inline("future_trait"))
- .and_then(|it| it.as_trait());
- let std_future_trait = match std_future_trait {
+ pub fn impls_into_future(&self, db: &dyn HirDatabase) -> bool {
+ let trait_ = db
+ .lang_item(self.env.krate, SmolStr::new_inline("into_future"))
+ .and_then(|it| {
+ let into_future_fn = it.as_function()?;
+ let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
+ let into_future_trait = assoc_item.containing_trait_or_trait_impl(db)?;
+ Some(into_future_trait.id)
+ })
+ .or_else(|| {
+ let future_trait =
+ db.lang_item(self.env.krate, SmolStr::new_inline("future_trait"))?;
+ future_trait.as_trait()
+ });
+
+ let trait_ = match trait_ {
Some(it) => it,
None => return false,
};
let canonical_ty =
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
- method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), std_future_trait)
+ method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), trait_)
}
/// Checks that particular type `ty` implements `std::ops::FnOnce`.
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index c84318b2f..416b6f580 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -357,6 +357,26 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.resolve_method_call(call).map(Function::from)
}
+ pub fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option<Function> {
+ self.imp.resolve_await_to_poll(await_expr).map(Function::from)
+ }
+
+ pub fn resolve_prefix_expr(&self, prefix_expr: &ast::PrefixExpr) -> Option<Function> {
+ self.imp.resolve_prefix_expr(prefix_expr).map(Function::from)
+ }
+
+ pub fn resolve_index_expr(&self, index_expr: &ast::IndexExpr) -> Option<Function> {
+ self.imp.resolve_index_expr(index_expr).map(Function::from)
+ }
+
+ pub fn resolve_bin_expr(&self, bin_expr: &ast::BinExpr) -> Option<Function> {
+ self.imp.resolve_bin_expr(bin_expr).map(Function::from)
+ }
+
+ pub fn resolve_try_expr(&self, try_expr: &ast::TryExpr) -> Option<Function> {
+ self.imp.resolve_try_expr(try_expr).map(Function::from)
+ }
+
pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
self.imp.resolve_method_call_as_callable(call)
}
@@ -1066,6 +1086,26 @@ impl<'db> SemanticsImpl<'db> {
self.analyze(call.syntax())?.resolve_method_call(self.db, call)
}
+ fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option<FunctionId> {
+ self.analyze(await_expr.syntax())?.resolve_await_to_poll(self.db, await_expr)
+ }
+
+ fn resolve_prefix_expr(&self, prefix_expr: &ast::PrefixExpr) -> Option<FunctionId> {
+ self.analyze(prefix_expr.syntax())?.resolve_prefix_expr(self.db, prefix_expr)
+ }
+
+ fn resolve_index_expr(&self, index_expr: &ast::IndexExpr) -> Option<FunctionId> {
+ self.analyze(index_expr.syntax())?.resolve_index_expr(self.db, index_expr)
+ }
+
+ fn resolve_bin_expr(&self, bin_expr: &ast::BinExpr) -> Option<FunctionId> {
+ self.analyze(bin_expr.syntax())?.resolve_bin_expr(self.db, bin_expr)
+ }
+
+ fn resolve_try_expr(&self, try_expr: &ast::TryExpr) -> Option<FunctionId> {
+ self.analyze(try_expr.syntax())?.resolve_try_expr(self.db, try_expr)
+ }
+
fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call)
}
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 1eb51b20c..342912b67 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -25,15 +25,21 @@ use hir_def::{
Lookup, ModuleDefId, VariantId,
};
use hir_expand::{
- builtin_fn_macro::BuiltinFnLikeExpander, hygiene::Hygiene, name::AsName, HirFileId, InFile,
+ builtin_fn_macro::BuiltinFnLikeExpander,
+ hygiene::Hygiene,
+ mod_path::path,
+ name,
+ name::{AsName, Name},
+ HirFileId, InFile,
};
use hir_ty::{
diagnostics::{
record_literal_missing_fields, record_pattern_missing_fields, unsafe_expressions,
UnsafeExpr,
},
- method_resolution, Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution,
- TyExt, TyKind, TyLoweringContext,
+ method_resolution::{self, lang_names_for_bin_op},
+ Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind,
+ TyLoweringContext,
};
use itertools::Itertools;
use smallvec::SmallVec;
@@ -134,11 +140,19 @@ impl SourceAnalyzer {
) -> Option<InFile<ast::Expr>> {
let macro_file = self.body_source_map()?.node_macro_file(expr.as_ref())?;
let expanded = db.parse_or_expand(macro_file)?;
-
- let res = match ast::MacroCall::cast(expanded.clone()) {
- Some(call) => self.expand_expr(db, InFile::new(macro_file, call))?,
- _ => InFile::new(macro_file, ast::Expr::cast(expanded)?),
+ let res = if let Some(stmts) = ast::MacroStmts::cast(expanded.clone()) {
+ match stmts.expr()? {
+ ast::Expr::MacroExpr(mac) => {
+ self.expand_expr(db, InFile::new(macro_file, mac.macro_call()?))?
+ }
+ expr => InFile::new(macro_file, expr),
+ }
+ } else if let Some(call) = ast::MacroCall::cast(expanded.clone()) {
+ self.expand_expr(db, InFile::new(macro_file, call))?
+ } else {
+ InFile::new(macro_file, ast::Expr::cast(expanded)?)
};
+
Some(res)
}
@@ -255,8 +269,111 @@ impl SourceAnalyzer {
) -> Option<FunctionId> {
let expr_id = self.expr_id(db, &call.clone().into())?;
let (f_in_trait, substs) = self.infer.as_ref()?.method_resolution(expr_id)?;
- let f_in_impl = self.resolve_impl_method(db, f_in_trait, &substs);
- f_in_impl.or(Some(f_in_trait))
+
+ Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, &substs))
+ }
+
+ pub(crate) fn resolve_await_to_poll(
+ &self,
+ db: &dyn HirDatabase,
+ await_expr: &ast::AwaitExpr,
+ ) -> Option<FunctionId> {
+ let mut ty = self.ty_of_expr(db, &await_expr.expr()?.into())?.clone();
+
+ let into_future_trait = self
+ .resolver
+ .resolve_known_trait(db.upcast(), &path![core::future::IntoFuture])
+ .map(Trait::from);
+
+ if let Some(into_future_trait) = into_future_trait {
+ let type_ = Type::new_with_resolver(db, &self.resolver, ty.clone());
+ if type_.impls_trait(db, into_future_trait, &[]) {
+ let items = into_future_trait.items(db);
+ let into_future_type = items.into_iter().find_map(|item| match item {
+ AssocItem::TypeAlias(alias)
+ if alias.name(db) == hir_expand::name![IntoFuture] =>
+ {
+ Some(alias)
+ }
+ _ => None,
+ })?;
+ let future_trait = type_.normalize_trait_assoc_type(db, &[], into_future_type)?;
+ ty = future_trait.ty;
+ }
+ }
+
+ let poll_fn = db
+ .lang_item(self.resolver.krate(), hir_expand::name![poll].to_smol_str())?
+ .as_function()?;
+ let substs = hir_ty::TyBuilder::subst_for_def(db, poll_fn).push(ty.clone()).build();
+ Some(self.resolve_impl_method_or_trait_def(db, poll_fn, &substs))
+ }
+
+ pub(crate) fn resolve_prefix_expr(
+ &self,
+ db: &dyn HirDatabase,
+ prefix_expr: &ast::PrefixExpr,
+ ) -> Option<FunctionId> {
+ let lang_item_name = match prefix_expr.op_kind()? {
+ ast::UnaryOp::Deref => name![deref],
+ ast::UnaryOp::Not => name![not],
+ ast::UnaryOp::Neg => name![neg],
+ };
+ let ty = self.ty_of_expr(db, &prefix_expr.expr()?.into())?;
+
+ let op_fn = self.lang_trait_fn(db, &lang_item_name, &lang_item_name)?;
+ let substs = hir_ty::TyBuilder::subst_for_def(db, op_fn).push(ty.clone()).build();
+
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ }
+
+ pub(crate) fn resolve_index_expr(
+ &self,
+ db: &dyn HirDatabase,
+ index_expr: &ast::IndexExpr,
+ ) -> Option<FunctionId> {
+ let base_ty = self.ty_of_expr(db, &index_expr.base()?.into())?;
+ let index_ty = self.ty_of_expr(db, &index_expr.index()?.into())?;
+
+ let lang_item_name = name![index];
+
+ let op_fn = self.lang_trait_fn(db, &lang_item_name, &lang_item_name)?;
+ let substs = hir_ty::TyBuilder::subst_for_def(db, op_fn)
+ .push(base_ty.clone())
+ .push(index_ty.clone())
+ .build();
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ }
+
+ pub(crate) fn resolve_bin_expr(
+ &self,
+ db: &dyn HirDatabase,
+ binop_expr: &ast::BinExpr,
+ ) -> Option<FunctionId> {
+ let op = binop_expr.op_kind()?;
+ let lhs = self.ty_of_expr(db, &binop_expr.lhs()?.into())?;
+ let rhs = self.ty_of_expr(db, &binop_expr.rhs()?.into())?;
+
+ let op_fn = lang_names_for_bin_op(op)
+ .and_then(|(name, lang_item)| self.lang_trait_fn(db, &lang_item, &name))?;
+ let substs =
+ hir_ty::TyBuilder::subst_for_def(db, op_fn).push(lhs.clone()).push(rhs.clone()).build();
+
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ }
+
+ pub(crate) fn resolve_try_expr(
+ &self,
+ db: &dyn HirDatabase,
+ try_expr: &ast::TryExpr,
+ ) -> Option<FunctionId> {
+ let ty = self.ty_of_expr(db, &try_expr.expr()?.into())?;
+
+ let op_fn =
+ db.lang_item(self.resolver.krate(), name![branch].to_smol_str())?.as_function()?;
+ let substs = hir_ty::TyBuilder::subst_for_def(db, op_fn).push(ty.clone()).build();
+
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
}
pub(crate) fn resolve_field(
@@ -281,6 +398,7 @@ impl SourceAnalyzer {
let local = if field.name_ref().is_some() {
None
} else {
+ // Shorthand syntax, resolve to the local
let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone()));
match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
Some(ValueNs::LocalBinding(pat_id)) => {
@@ -666,6 +784,29 @@ impl SourceAnalyzer {
let fun_data = db.function_data(func);
method_resolution::lookup_impl_method(self_ty, db, trait_env, impled_trait, &fun_data.name)
}
+
+ fn resolve_impl_method_or_trait_def(
+ &self,
+ db: &dyn HirDatabase,
+ func: FunctionId,
+ substs: &Substitution,
+ ) -> FunctionId {
+ self.resolve_impl_method(db, func, substs).unwrap_or(func)
+ }
+
+ fn lang_trait_fn(
+ &self,
+ db: &dyn HirDatabase,
+ lang_trait: &Name,
+ method_name: &Name,
+ ) -> Option<FunctionId> {
+ db.trait_data(db.lang_item(self.resolver.krate(), lang_trait.to_smol_str())?.as_trait()?)
+ .method_by_name(method_name)
+ }
+
+ fn ty_of_expr(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<&Ty> {
+ self.infer.as_ref()?.type_of_expr.get(self.expr_id(db, &expr)?)
+ }
}
fn scope_for(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
index f9b426614..8c7670e0c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
@@ -1,28 +1,20 @@
//! See [`AssistContext`].
-use std::mem;
-
use hir::Semantics;
-use ide_db::{
- base_db::{AnchoredPathBuf, FileId, FileRange},
- SnippetCap,
-};
-use ide_db::{
- label::Label,
- source_change::{FileSystemEdit, SourceChange},
- RootDatabase,
-};
+use ide_db::base_db::{FileId, FileRange};
+use ide_db::{label::Label, RootDatabase};
use syntax::{
algo::{self, find_node_at_offset, find_node_at_range},
- AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
- SyntaxToken, TextRange, TextSize, TokenAtOffset,
+ AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange,
+ TextSize, TokenAtOffset,
};
-use text_edit::{TextEdit, TextEditBuilder};
use crate::{
assist_config::AssistConfig, Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel,
};
+pub(crate) use ide_db::source_change::{SourceChangeBuilder, TreeMutator};
+
/// `AssistContext` allows to apply an assist or check if it could be applied.
///
/// Assists use a somewhat over-engineered approach, given the current needs.
@@ -163,7 +155,7 @@ impl Assists {
id: AssistId,
label: impl Into<String>,
target: TextRange,
- f: impl FnOnce(&mut AssistBuilder),
+ f: impl FnOnce(&mut SourceChangeBuilder),
) -> Option<()> {
let mut f = Some(f);
self.add_impl(None, id, label.into(), target, &mut |it| f.take().unwrap()(it))
@@ -175,7 +167,7 @@ impl Assists {
id: AssistId,
label: impl Into<String>,
target: TextRange,
- f: impl FnOnce(&mut AssistBuilder),
+ f: impl FnOnce(&mut SourceChangeBuilder),
) -> Option<()> {
let mut f = Some(f);
self.add_impl(Some(group), id, label.into(), target, &mut |it| f.take().unwrap()(it))
@@ -187,7 +179,7 @@ impl Assists {
id: AssistId,
label: String,
target: TextRange,
- f: &mut dyn FnMut(&mut AssistBuilder),
+ f: &mut dyn FnMut(&mut SourceChangeBuilder),
) -> Option<()> {
if !self.is_allowed(&id) {
return None;
@@ -195,7 +187,7 @@ impl Assists {
let mut trigger_signature_help = false;
let source_change = if self.resolve.should_resolve(&id) {
- let mut builder = AssistBuilder::new(self.file);
+ let mut builder = SourceChangeBuilder::new(self.file);
f(&mut builder);
trigger_signature_help = builder.trigger_signature_help;
Some(builder.finish())
@@ -216,132 +208,3 @@ impl Assists {
}
}
}
-
-pub(crate) struct AssistBuilder {
- edit: TextEditBuilder,
- file_id: FileId,
- source_change: SourceChange,
- trigger_signature_help: bool,
-
- /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
- mutated_tree: Option<TreeMutator>,
-}
-
-pub(crate) struct TreeMutator {
- immutable: SyntaxNode,
- mutable_clone: SyntaxNode,
-}
-
-impl TreeMutator {
- pub(crate) fn new(immutable: &SyntaxNode) -> TreeMutator {
- let immutable = immutable.ancestors().last().unwrap();
- let mutable_clone = immutable.clone_for_update();
- TreeMutator { immutable, mutable_clone }
- }
-
- pub(crate) fn make_mut<N: AstNode>(&self, node: &N) -> N {
- N::cast(self.make_syntax_mut(node.syntax())).unwrap()
- }
-
- pub(crate) fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
- let ptr = SyntaxNodePtr::new(node);
- ptr.to_node(&self.mutable_clone)
- }
-}
-
-impl AssistBuilder {
- pub(crate) fn new(file_id: FileId) -> AssistBuilder {
- AssistBuilder {
- edit: TextEdit::builder(),
- file_id,
- source_change: SourceChange::default(),
- trigger_signature_help: false,
- mutated_tree: None,
- }
- }
-
- pub(crate) fn edit_file(&mut self, file_id: FileId) {
- self.commit();
- self.file_id = file_id;
- }
-
- fn commit(&mut self) {
- if let Some(tm) = self.mutated_tree.take() {
- algo::diff(&tm.immutable, &tm.mutable_clone).into_text_edit(&mut self.edit)
- }
-
- let edit = mem::take(&mut self.edit).finish();
- if !edit.is_empty() {
- self.source_change.insert_source_edit(self.file_id, edit);
- }
- }
-
- pub(crate) fn make_mut<N: AstNode>(&mut self, node: N) -> N {
- self.mutated_tree.get_or_insert_with(|| TreeMutator::new(node.syntax())).make_mut(&node)
- }
- /// Returns a copy of the `node`, suitable for mutation.
- ///
- /// Syntax trees in rust-analyzer are typically immutable, and mutating
- /// operations panic at runtime. However, it is possible to make a copy of
- /// the tree and mutate the copy freely. Mutation is based on interior
- /// mutability, and different nodes in the same tree see the same mutations.
- ///
- /// The typical pattern for an assist is to find specific nodes in the read
- /// phase, and then get their mutable couterparts using `make_mut` in the
- /// mutable state.
- pub(crate) fn make_syntax_mut(&mut self, node: SyntaxNode) -> SyntaxNode {
- self.mutated_tree.get_or_insert_with(|| TreeMutator::new(&node)).make_syntax_mut(&node)
- }
-
- /// Remove specified `range` of text.
- pub(crate) fn delete(&mut self, range: TextRange) {
- self.edit.delete(range)
- }
- /// Append specified `text` at the given `offset`
- pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
- self.edit.insert(offset, text.into())
- }
- /// Append specified `snippet` at the given `offset`
- pub(crate) fn insert_snippet(
- &mut self,
- _cap: SnippetCap,
- offset: TextSize,
- snippet: impl Into<String>,
- ) {
- self.source_change.is_snippet = true;
- self.insert(offset, snippet);
- }
- /// Replaces specified `range` of text with a given string.
- pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
- self.edit.replace(range, replace_with.into())
- }
- /// Replaces specified `range` of text with a given `snippet`.
- pub(crate) fn replace_snippet(
- &mut self,
- _cap: SnippetCap,
- range: TextRange,
- snippet: impl Into<String>,
- ) {
- self.source_change.is_snippet = true;
- self.replace(range, snippet);
- }
- pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
- algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
- }
- pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
- let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
- self.source_change.push_file_system_edit(file_system_edit);
- }
- pub(crate) fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
- let file_system_edit = FileSystemEdit::MoveFile { src, dst };
- self.source_change.push_file_system_edit(file_system_edit);
- }
- pub(crate) fn trigger_signature_help(&mut self) {
- self.trigger_signature_help = true;
- }
-
- fn finish(mut self) -> SourceChange {
- self.commit();
- mem::take(&mut self.source_change)
- }
-}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index c808c010c..62cf5ab4f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -944,7 +944,7 @@ foo!();
struct Foo(usize);
impl FooB for Foo {
- $0fn foo< 'lt>(& 'lt self){}
+ $0fn foo<'lt>(&'lt self){}
}
"#,
)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index b16f6fe03..1a7919a5a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -5,6 +5,7 @@ use hir::{Adt, Crate, HasAttrs, HasSource, ModuleDef, Semantics};
use ide_db::RootDatabase;
use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast};
use itertools::Itertools;
+use syntax::ast::edit_in_place::Removable;
use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat};
use crate::{
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index 4ab8e93a2..d8f522708 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -5,7 +5,7 @@ use syntax::{
match_ast, SyntaxNode,
};
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
// Assist: convert_tuple_struct_to_named_struct
//
@@ -80,7 +80,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
fn edit_struct_def(
ctx: &AssistContext<'_>,
- edit: &mut AssistBuilder,
+ edit: &mut SourceChangeBuilder,
strukt: &Either<ast::Struct, ast::Variant>,
tuple_fields: ast::TupleFieldList,
names: Vec<ast::Name>,
@@ -122,7 +122,7 @@ fn edit_struct_def(
fn edit_struct_references(
ctx: &AssistContext<'_>,
- edit: &mut AssistBuilder,
+ edit: &mut SourceChangeBuilder,
strukt: Either<hir::Struct, hir::Variant>,
names: &[ast::Name],
) {
@@ -132,7 +132,7 @@ fn edit_struct_references(
};
let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
- let edit_node = |edit: &mut AssistBuilder, node: SyntaxNode| -> Option<()> {
+ let edit_node = |edit: &mut SourceChangeBuilder, node: SyntaxNode| -> Option<()> {
match_ast! {
match node {
ast::TupleStructPat(tuple_struct_pat) => {
@@ -203,7 +203,7 @@ fn edit_struct_references(
fn edit_field_references(
ctx: &AssistContext<'_>,
- edit: &mut AssistBuilder,
+ edit: &mut SourceChangeBuilder,
fields: impl Iterator<Item = ast::TupleField>,
names: &[ast::Name],
) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
new file mode 100644
index 000000000..54a7f480a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
@@ -0,0 +1,294 @@
+use syntax::ast::{self, AstNode};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: convert_two_arm_bool_match_to_matches_macro
+//
+// Convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation.
+//
+// ```
+// fn main() {
+// match scrutinee$0 {
+// Some(val) if val.cond() => true,
+// _ => false,
+// }
+// }
+// ```
+// ->
+// ```
+// fn main() {
+// matches!(scrutinee, Some(val) if val.cond())
+// }
+// ```
+pub(crate) fn convert_two_arm_bool_match_to_matches_macro(
+ acc: &mut Assists,
+ ctx: &AssistContext<'_>,
+) -> Option<()> {
+ let match_expr = ctx.find_node_at_offset::<ast::MatchExpr>()?;
+ let match_arm_list = match_expr.match_arm_list()?;
+ let mut arms = match_arm_list.arms();
+ let first_arm = arms.next()?;
+ let second_arm = arms.next()?;
+ if arms.next().is_some() {
+ cov_mark::hit!(non_two_arm_match);
+ return None;
+ }
+ let first_arm_expr = first_arm.expr();
+ let second_arm_expr = second_arm.expr();
+
+ let invert_matches = if is_bool_literal_expr(&first_arm_expr, true)
+ && is_bool_literal_expr(&second_arm_expr, false)
+ {
+ false
+ } else if is_bool_literal_expr(&first_arm_expr, false)
+ && is_bool_literal_expr(&second_arm_expr, true)
+ {
+ true
+ } else {
+ cov_mark::hit!(non_invert_bool_literal_arms);
+ return None;
+ };
+
+ let target_range = ctx.sema.original_range(match_expr.syntax()).range;
+ let expr = match_expr.expr()?;
+
+ acc.add(
+ AssistId("convert_two_arm_bool_match_to_matches_macro", AssistKind::RefactorRewrite),
+ "Convert to matches!",
+ target_range,
+ |builder| {
+ let mut arm_str = String::new();
+ if let Some(ref pat) = first_arm.pat() {
+ arm_str += &pat.to_string();
+ }
+ if let Some(ref guard) = first_arm.guard() {
+ arm_str += &format!(" {}", &guard.to_string());
+ }
+ if invert_matches {
+ builder.replace(target_range, format!("!matches!({}, {})", expr, arm_str));
+ } else {
+ builder.replace(target_range, format!("matches!({}, {})", expr, arm_str));
+ }
+ },
+ )
+}
+
+fn is_bool_literal_expr(expr: &Option<ast::Expr>, expect_bool: bool) -> bool {
+ if let Some(ast::Expr::Literal(lit)) = expr {
+ if let ast::LiteralKind::Bool(b) = lit.kind() {
+ return b == expect_bool;
+ }
+ }
+
+ return false;
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
+
+ use super::convert_two_arm_bool_match_to_matches_macro;
+
+ #[test]
+ fn not_applicable_outside_of_range_left() {
+ check_assist_not_applicable(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ $0 match a {
+ Some(_val) => true,
+ _ => false
+ }
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn not_applicable_non_two_arm_match() {
+ cov_mark::check!(non_two_arm_match);
+ check_assist_not_applicable(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(3) => true,
+ Some(4) => true,
+ _ => false
+ }
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn not_applicable_non_bool_literal_arms() {
+ cov_mark::check!(non_invert_bool_literal_arms);
+ check_assist_not_applicable(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(val) => val == 3,
+ _ => false
+ }
+}
+ "#,
+ );
+ }
+ #[test]
+ fn not_applicable_both_false_arms() {
+ cov_mark::check!(non_invert_bool_literal_arms);
+ check_assist_not_applicable(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(val) => false,
+ _ => false
+ }
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn not_applicable_both_true_arms() {
+ cov_mark::check!(non_invert_bool_literal_arms);
+ check_assist_not_applicable(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(val) => true,
+ _ => true
+ }
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn convert_simple_case() {
+ check_assist(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(_val) => true,
+ _ => false
+ }
+}
+"#,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ matches!(a, Some(_val))
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn convert_simple_invert_case() {
+ check_assist(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(_val) => false,
+ _ => true
+ }
+}
+"#,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ !matches!(a, Some(_val))
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn convert_with_guard_case() {
+ check_assist(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(val) if val > 3 => true,
+ _ => false
+ }
+}
+"#,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ matches!(a, Some(val) if val > 3)
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn convert_enum_match_cases() {
+ check_assist(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+enum X { A, B }
+
+fn foo(a: X) -> bool {
+ match a$0 {
+ X::A => true,
+ _ => false
+ }
+}
+"#,
+ r#"
+enum X { A, B }
+
+fn foo(a: X) -> bool {
+ matches!(a, X::A)
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn convert_target_simple() {
+ check_assist_target(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+fn foo(a: Option<u32>) -> bool {
+ match a$0 {
+ Some(val) => true,
+ _ => false
+ }
+}
+"#,
+ r#"match a {
+ Some(val) => true,
+ _ => false
+ }"#,
+ );
+ }
+
+ #[test]
+ fn convert_target_complex() {
+ check_assist_target(
+ convert_two_arm_bool_match_to_matches_macro,
+ r#"
+enum E { X, Y }
+
+fn main() {
+ match E::X$0 {
+ E::X => true,
+ _ => false,
+ }
+}
+"#,
+ "match E::X {
+ E::X => true,
+ _ => false,
+ }",
+ );
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
index c1f57532b..dc581ff3b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -8,7 +8,7 @@ use syntax::{
TextRange,
};
-use crate::assist_context::{AssistBuilder, AssistContext, Assists};
+use crate::assist_context::{AssistContext, Assists, SourceChangeBuilder};
// Assist: destructure_tuple_binding
//
@@ -151,7 +151,7 @@ struct TupleData {
}
fn edit_tuple_assignment(
ctx: &AssistContext<'_>,
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
data: &TupleData,
in_sub_pattern: bool,
) {
@@ -195,7 +195,7 @@ fn edit_tuple_assignment(
fn edit_tuple_usages(
data: &TupleData,
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
ctx: &AssistContext<'_>,
in_sub_pattern: bool,
) {
@@ -211,7 +211,7 @@ fn edit_tuple_usages(
}
fn edit_tuple_usage(
ctx: &AssistContext<'_>,
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
usage: &FileReference,
data: &TupleData,
in_sub_pattern: bool,
@@ -239,7 +239,7 @@ fn edit_tuple_usage(
fn edit_tuple_field_usage(
ctx: &AssistContext<'_>,
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
data: &TupleData,
index: TupleIndex,
) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
index b3c4d306a..897980c66 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
@@ -29,7 +29,7 @@ use super::remove_unused_param::range_to_remove;
// Assist: extract_module
//
-// Extracts a selected region as seperate module. All the references, visibility and imports are
+// Extracts a selected region as separate module. All the references, visibility and imports are
// resolved.
//
// ```
@@ -105,7 +105,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
//
//- Thirdly, resolving all the imports this includes removing paths from imports
// outside the module, shifting/cloning them inside new module, or shifting the imports, or making
- // new import statemnts
+ // new import statements
//We are getting item usages and record_fields together, record_fields
//for change_visibility and usages for first point mentioned above in the process
@@ -661,7 +661,7 @@ fn check_intersection_and_push(
import_path: TextRange,
) {
if import_paths_to_be_removed.len() > 0 {
- // Text ranges recieved here for imports are extended to the
+ // Text ranges received here for imports are extended to the
// next/previous comma which can cause intersections among them
// and later deletion of these can cause panics similar
// to reported in #11766. So to mitigate it, we
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index a93648f2d..ddc2052e7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -20,7 +20,7 @@ use syntax::{
SyntaxNode, T,
};
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
// Assist: extract_struct_from_enum_variant
//
@@ -101,21 +101,22 @@ pub(crate) fn extract_struct_from_enum_variant(
});
}
- let indent = enum_ast.indent_level();
let generic_params = enum_ast
.generic_param_list()
.and_then(|known_generics| extract_generic_params(&known_generics, &field_list));
let generics = generic_params.as_ref().map(|generics| generics.clone_for_update());
let def =
create_struct_def(variant_name.clone(), &variant, &field_list, generics, &enum_ast);
+
+ let enum_ast = variant.parent_enum();
+ let indent = enum_ast.indent_level();
def.reindent_to(indent);
- let start_offset = &variant.parent_enum().syntax().clone();
- ted::insert_all_raw(
- ted::Position::before(start_offset),
+ ted::insert_all(
+ ted::Position::before(enum_ast.syntax()),
vec![
def.syntax().clone().into(),
- make::tokens::whitespace(&format!("\n\n{}", indent)).into(),
+ make::tokens::whitespace(&format!("\n\n{indent}")).into(),
],
);
@@ -227,7 +228,7 @@ fn tag_generics_in_variant(ty: &ast::Type, generics: &mut [(ast::GenericParam, b
}
fn create_struct_def(
- variant_name: ast::Name,
+ name: ast::Name,
variant: &ast::Variant,
field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>,
generics: Option<ast::GenericParamList>,
@@ -269,43 +270,27 @@ fn create_struct_def(
field_list.into()
}
};
-
field_list.reindent_to(IndentLevel::single());
- let strukt = make::struct_(enum_vis, variant_name, generics, field_list).clone_for_update();
-
- // FIXME: Consider making this an actual function somewhere (like in `AttrsOwnerEdit`) after some deliberation
- let attrs_and_docs = |node: &SyntaxNode| {
- let mut select_next_ws = false;
- node.children_with_tokens().filter(move |child| {
- let accept = match child.kind() {
- ATTR | COMMENT => {
- select_next_ws = true;
- return true;
- }
- WHITESPACE if select_next_ws => true,
- _ => false,
- };
- select_next_ws = false;
-
- accept
- })
- };
+ let strukt = make::struct_(enum_vis, name, generics, field_list).clone_for_update();
- // copy attributes & comments from variant
- let variant_attrs = attrs_and_docs(variant.syntax())
- .map(|tok| match tok.kind() {
- WHITESPACE => make::tokens::single_newline().into(),
- _ => tok,
- })
- .collect();
- ted::insert_all(ted::Position::first_child_of(strukt.syntax()), variant_attrs);
+ // take comments from variant
+ ted::insert_all(
+ ted::Position::first_child_of(strukt.syntax()),
+ take_all_comments(variant.syntax()),
+ );
// copy attributes from enum
ted::insert_all(
ted::Position::first_child_of(strukt.syntax()),
- enum_.attrs().map(|it| it.syntax().clone_for_update().into()).collect(),
+ enum_
+ .attrs()
+ .flat_map(|it| {
+ vec![it.syntax().clone_for_update().into(), make::tokens::single_newline().into()]
+ })
+ .collect(),
);
+
strukt
}
@@ -346,16 +331,48 @@ fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList
})
.unwrap_or_else(|| make::ty(&name.text()));
+ // change from a record to a tuple field list
let tuple_field = make::tuple_field(None, ty);
- let replacement = make::variant(
- name,
- Some(ast::FieldList::TupleFieldList(make::tuple_field_list(iter::once(tuple_field)))),
- )
- .clone_for_update();
- ted::replace(variant.syntax(), replacement.syntax());
+ let field_list = make::tuple_field_list(iter::once(tuple_field)).clone_for_update();
+ ted::replace(variant.field_list()?.syntax(), field_list.syntax());
+
+ // remove any ws after the name
+ if let Some(ws) = name
+ .syntax()
+ .siblings_with_tokens(syntax::Direction::Next)
+ .find_map(|tok| tok.into_token().filter(|tok| tok.kind() == WHITESPACE))
+ {
+ ted::remove(SyntaxElement::Token(ws));
+ }
+
Some(())
}
+// Note: this also detaches whitespace after comments,
+// since `SyntaxNode::splice_children` (and by extension `ted::insert_all_raw`)
+// detaches nodes. If we only took the comments, we'd leave behind the old whitespace.
+fn take_all_comments(node: &SyntaxNode) -> Vec<SyntaxElement> {
+ let mut remove_next_ws = false;
+ node.children_with_tokens()
+ .filter_map(move |child| match child.kind() {
+ COMMENT => {
+ remove_next_ws = true;
+ child.detach();
+ Some(child)
+ }
+ WHITESPACE if remove_next_ws => {
+ remove_next_ws = false;
+ child.detach();
+ Some(make::tokens::single_newline().into())
+ }
+ _ => {
+ remove_next_ws = false;
+ None
+ }
+ })
+ .collect()
+}
+
fn apply_references(
insert_use_cfg: InsertUseConfig,
segment: ast::PathSegment,
@@ -374,7 +391,7 @@ fn apply_references(
fn process_references(
ctx: &AssistContext<'_>,
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
visited_modules: &mut FxHashSet<Module>,
enum_module_def: &ModuleDef,
variant_hir_name: &Name,
@@ -480,10 +497,14 @@ enum En<T> { Var(Var<T>) }"#,
fn test_extract_struct_carries_over_attributes() {
check_assist(
extract_struct_from_enum_variant,
- r#"#[derive(Debug)]
+ r#"
+#[derive(Debug)]
#[derive(Clone)]
enum Enum { Variant{ field: u32$0 } }"#,
- r#"#[derive(Debug)]#[derive(Clone)] struct Variant{ field: u32 }
+ r#"
+#[derive(Debug)]
+#[derive(Clone)]
+struct Variant{ field: u32 }
#[derive(Debug)]
#[derive(Clone)]
@@ -614,7 +635,7 @@ enum A { One(One) }"#,
}
#[test]
- fn test_extract_struct_keep_comments_and_attrs_on_variant_struct() {
+ fn test_extract_struct_move_struct_variant_comments() {
check_assist(
extract_struct_from_enum_variant,
r#"
@@ -631,19 +652,19 @@ enum A {
/* comment */
// other
/// comment
-#[attr]
struct One{
a: u32
}
enum A {
+ #[attr]
One(One)
}"#,
);
}
#[test]
- fn test_extract_struct_keep_comments_and_attrs_on_variant_tuple() {
+ fn test_extract_struct_move_tuple_variant_comments() {
check_assist(
extract_struct_from_enum_variant,
r#"
@@ -658,10 +679,10 @@ enum A {
/* comment */
// other
/// comment
-#[attr]
struct One(u32, u32);
enum A {
+ #[attr]
One(One)
}"#,
);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
index af584cdb4..03aa8601d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
@@ -171,6 +171,25 @@ fn collect_used_generics<'gp>(
ast::Type::RefType(ref_) => generics.extend(
ref_.lifetime().and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
),
+ ast::Type::ArrayType(ar) => {
+ if let Some(expr) = ar.expr() {
+ if let ast::Expr::PathExpr(p) = expr {
+ if let Some(path) = p.path() {
+ if let Some(name_ref) = path.as_single_name_ref() {
+ if let Some(param) = known_generics.iter().find(|gp| {
+ if let ast::GenericParam::ConstParam(cp) = gp {
+ cp.name().map_or(false, |n| n.text() == name_ref.text())
+ } else {
+ false
+ }
+ }) {
+ generics.push(param);
+ }
+ }
+ }
+ }
+ }
+ }
_ => (),
});
// stable resort to lifetime, type, const
@@ -357,4 +376,29 @@ impl<'outer, Outer, const OUTER: usize> () {
"#,
);
}
+
+ #[test]
+ fn issue_11197() {
+ check_assist(
+ extract_type_alias,
+ r#"
+struct Foo<T, const N: usize>
+where
+ [T; N]: Sized,
+{
+ arr: $0[T; N]$0,
+}
+ "#,
+ r#"
+type $0Type<T, const N: usize> = [T; N];
+
+struct Foo<T, const N: usize>
+where
+ [T; N]: Sized,
+{
+ arr: Type<T, N>,
+}
+ "#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
index b9637ee8d..b48463512 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
@@ -8,7 +8,7 @@ use syntax::{
};
use crate::{
- assist_context::{AssistBuilder, AssistContext, Assists},
+ assist_context::{AssistContext, Assists, SourceChangeBuilder},
utils::generate_trait_impl_text,
AssistId, AssistKind,
};
@@ -120,7 +120,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
}
fn generate_edit(
- edit: &mut AssistBuilder,
+ edit: &mut SourceChangeBuilder,
strukt: ast::Struct,
field_type_syntax: &SyntaxNode,
field_name: impl Display,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs
index 4461fbd5a..35cd42908 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs
@@ -1,8 +1,8 @@
-use hir::{HasSource, InFile};
+use hir::{HasSource, HirDisplay, InFile};
use ide_db::assists::{AssistId, AssistKind};
use syntax::{
- ast::{self, edit::IndentLevel},
- AstNode, TextSize,
+ ast::{self, make, HasArgList},
+ match_ast, AstNode, SyntaxNode,
};
use crate::assist_context::{AssistContext, Assists};
@@ -32,8 +32,8 @@ use crate::assist_context::{AssistContext, Assists};
// }
// ```
pub(crate) fn generate_enum_variant(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
- let path_expr: ast::PathExpr = ctx.find_node_at_offset()?;
- let path = path_expr.path()?;
+ let path: ast::Path = ctx.find_node_at_offset()?;
+ let parent = path_parent(&path)?;
if ctx.sema.resolve_path(&path).is_some() {
// No need to generate anything if the path resolves
@@ -50,26 +50,71 @@ pub(crate) fn generate_enum_variant(acc: &mut Assists, ctx: &AssistContext<'_>)
ctx.sema.resolve_path(&path.qualifier()?)
{
let target = path.syntax().text_range();
- return add_variant_to_accumulator(acc, ctx, target, e, &name_ref);
+ return add_variant_to_accumulator(acc, ctx, target, e, &name_ref, parent);
}
None
}
+#[derive(Debug)]
+enum PathParent {
+ PathExpr(ast::PathExpr),
+ RecordExpr(ast::RecordExpr),
+ PathPat(ast::PathPat),
+ UseTree(ast::UseTree),
+}
+
+impl PathParent {
+ fn syntax(&self) -> &SyntaxNode {
+ match self {
+ PathParent::PathExpr(it) => it.syntax(),
+ PathParent::RecordExpr(it) => it.syntax(),
+ PathParent::PathPat(it) => it.syntax(),
+ PathParent::UseTree(it) => it.syntax(),
+ }
+ }
+
+ fn make_field_list(&self, ctx: &AssistContext<'_>) -> Option<ast::FieldList> {
+ let scope = ctx.sema.scope(self.syntax())?;
+
+ match self {
+ PathParent::PathExpr(it) => {
+ if let Some(call_expr) = it.syntax().parent().and_then(ast::CallExpr::cast) {
+ make_tuple_field_list(call_expr, ctx, &scope)
+ } else {
+ None
+ }
+ }
+ PathParent::RecordExpr(it) => make_record_field_list(it, ctx, &scope),
+ PathParent::UseTree(_) | PathParent::PathPat(_) => None,
+ }
+ }
+}
+
+fn path_parent(path: &ast::Path) -> Option<PathParent> {
+ let parent = path.syntax().parent()?;
+
+ match_ast! {
+ match parent {
+ ast::PathExpr(it) => Some(PathParent::PathExpr(it)),
+ ast::RecordExpr(it) => Some(PathParent::RecordExpr(it)),
+ ast::PathPat(it) => Some(PathParent::PathPat(it)),
+ ast::UseTree(it) => Some(PathParent::UseTree(it)),
+ _ => None
+ }
+ }
+}
+
fn add_variant_to_accumulator(
acc: &mut Assists,
ctx: &AssistContext<'_>,
target: syntax::TextRange,
adt: hir::Enum,
name_ref: &ast::NameRef,
+ parent: PathParent,
) -> Option<()> {
let db = ctx.db();
let InFile { file_id, value: enum_node } = adt.source(db)?.original_ast_node(db)?;
- let enum_indent = IndentLevel::from_node(&enum_node.syntax());
-
- let variant_list = enum_node.variant_list()?;
- let offset = variant_list.syntax().text_range().end() - TextSize::of('}');
- let empty_enum = variant_list.variants().next().is_none();
acc.add(
AssistId("generate_enum_variant", AssistKind::Generate),
@@ -77,18 +122,80 @@ fn add_variant_to_accumulator(
target,
|builder| {
builder.edit_file(file_id.original_file(db));
- let text = format!(
- "{maybe_newline}{indent_1}{name},\n{enum_indent}",
- maybe_newline = if empty_enum { "\n" } else { "" },
- indent_1 = IndentLevel(1),
- name = name_ref,
- enum_indent = enum_indent
- );
- builder.insert(offset, text)
+ let node = builder.make_mut(enum_node);
+ let variant = make_variant(ctx, name_ref, parent);
+ node.variant_list().map(|it| it.add_variant(variant.clone_for_update()));
},
)
}
+fn make_variant(
+ ctx: &AssistContext<'_>,
+ name_ref: &ast::NameRef,
+ parent: PathParent,
+) -> ast::Variant {
+ let field_list = parent.make_field_list(ctx);
+ make::variant(make::name(&name_ref.text()), field_list)
+}
+
+fn make_record_field_list(
+ record: &ast::RecordExpr,
+ ctx: &AssistContext<'_>,
+ scope: &hir::SemanticsScope<'_>,
+) -> Option<ast::FieldList> {
+ let fields = record.record_expr_field_list()?.fields();
+ let record_fields = fields.map(|field| {
+ let name = name_from_field(&field);
+
+ let ty = field
+ .expr()
+ .and_then(|it| expr_ty(ctx, it, scope))
+ .unwrap_or_else(make::ty_placeholder);
+
+ make::record_field(None, name, ty)
+ });
+ Some(make::record_field_list(record_fields).into())
+}
+
+fn name_from_field(field: &ast::RecordExprField) -> ast::Name {
+ let text = match field.name_ref() {
+ Some(it) => it.to_string(),
+ None => name_from_field_shorthand(field).unwrap_or("unknown".to_string()),
+ };
+ make::name(&text)
+}
+
+fn name_from_field_shorthand(field: &ast::RecordExprField) -> Option<String> {
+ let path = match field.expr()? {
+ ast::Expr::PathExpr(path_expr) => path_expr.path(),
+ _ => None,
+ }?;
+ Some(path.as_single_name_ref()?.to_string())
+}
+
+fn make_tuple_field_list(
+ call_expr: ast::CallExpr,
+ ctx: &AssistContext<'_>,
+ scope: &hir::SemanticsScope<'_>,
+) -> Option<ast::FieldList> {
+ let args = call_expr.arg_list()?.args();
+ let tuple_fields = args.map(|arg| {
+ let ty = expr_ty(ctx, arg, &scope).unwrap_or_else(make::ty_placeholder);
+ make::tuple_field(None, ty)
+ });
+ Some(make::tuple_field_list(tuple_fields).into())
+}
+
+fn expr_ty(
+ ctx: &AssistContext<'_>,
+ arg: ast::Expr,
+ scope: &hir::SemanticsScope<'_>,
+) -> Option<ast::Type> {
+ let ty = ctx.sema.type_of_expr(&arg).map(|it| it.adjusted())?;
+ let text = ty.display_source_code(ctx.db(), scope.module().into()).ok()?;
+ Some(make::ty(&text))
+}
+
#[cfg(test)]
mod tests {
use crate::tests::{check_assist, check_assist_not_applicable};
@@ -224,4 +331,234 @@ fn main() {
",
)
}
+
+ #[test]
+ fn associated_single_element_tuple() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn main() {
+ Foo::Bar$0(true)
+}
+",
+ r"
+enum Foo {
+ Bar(bool),
+}
+fn main() {
+ Foo::Bar(true)
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_single_element_tuple_unknown_type() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn main() {
+ Foo::Bar$0(x)
+}
+",
+ r"
+enum Foo {
+ Bar(_),
+}
+fn main() {
+ Foo::Bar(x)
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_multi_element_tuple() {
+ check_assist(
+ generate_enum_variant,
+ r"
+struct Struct {}
+enum Foo {}
+fn main() {
+ Foo::Bar$0(true, x, Struct {})
+}
+",
+ r"
+struct Struct {}
+enum Foo {
+ Bar(bool, _, Struct),
+}
+fn main() {
+ Foo::Bar(true, x, Struct {})
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_record() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn main() {
+ Foo::$0Bar { x: true }
+}
+",
+ r"
+enum Foo {
+ Bar { x: bool },
+}
+fn main() {
+ Foo::Bar { x: true }
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_record_unknown_type() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn main() {
+ Foo::$0Bar { x: y }
+}
+",
+ r"
+enum Foo {
+ Bar { x: _ },
+}
+fn main() {
+ Foo::Bar { x: y }
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_record_field_shorthand() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn main() {
+ let x = true;
+ Foo::$0Bar { x }
+}
+",
+ r"
+enum Foo {
+ Bar { x: bool },
+}
+fn main() {
+ let x = true;
+ Foo::Bar { x }
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_record_field_shorthand_unknown_type() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn main() {
+ Foo::$0Bar { x }
+}
+",
+ r"
+enum Foo {
+ Bar { x: _ },
+}
+fn main() {
+ Foo::Bar { x }
+}
+",
+ )
+ }
+
+ #[test]
+ fn associated_record_field_multiple_fields() {
+ check_assist(
+ generate_enum_variant,
+ r"
+struct Struct {}
+enum Foo {}
+fn main() {
+ Foo::$0Bar { x, y: x, s: Struct {} }
+}
+",
+ r"
+struct Struct {}
+enum Foo {
+ Bar { x: _, y: _, s: Struct },
+}
+fn main() {
+ Foo::Bar { x, y: x, s: Struct {} }
+}
+",
+ )
+ }
+
+ #[test]
+ fn use_tree() {
+ check_assist(
+ generate_enum_variant,
+ r"
+//- /main.rs
+mod foo;
+use foo::Foo::Bar$0;
+
+//- /foo.rs
+enum Foo {}
+",
+ r"
+enum Foo {
+ Bar,
+}
+",
+ )
+ }
+
+ #[test]
+ fn not_applicable_for_path_type() {
+ check_assist_not_applicable(
+ generate_enum_variant,
+ r"
+enum Foo {}
+impl Foo::Bar$0 {}
+",
+ )
+ }
+
+ #[test]
+ fn path_pat() {
+ check_assist(
+ generate_enum_variant,
+ r"
+enum Foo {}
+fn foo(x: Foo) {
+ match x {
+ Foo::Bar$0 =>
+ }
+}
+",
+ r"
+enum Foo {
+ Bar,
+}
+fn foo(x: Foo) {
+ match x {
+ Foo::Bar =>
+ }
+}
+",
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index d564a0540..e26c76da1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -61,56 +61,72 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
}
let fn_name = &*name_ref.text();
- let target_module;
- let mut adt_name = None;
+ let TargetInfo { target_module, adt_name, target, file, insert_offset } =
+ fn_target_info(ctx, path, &call, fn_name)?;
+ let function_builder = FunctionBuilder::from_call(ctx, &call, fn_name, target_module, target)?;
+ let text_range = call.syntax().text_range();
+ let label = format!("Generate {} function", function_builder.fn_name);
+ add_func_to_accumulator(
+ acc,
+ ctx,
+ text_range,
+ function_builder,
+ insert_offset,
+ file,
+ adt_name,
+ label,
+ )
+}
+
+struct TargetInfo {
+ target_module: Option<Module>,
+ adt_name: Option<hir::Name>,
+ target: GeneratedFunctionTarget,
+ file: FileId,
+ insert_offset: TextSize,
+}
- let (target, file, insert_offset) = match path.qualifier() {
+impl TargetInfo {
+ fn new(
+ target_module: Option<Module>,
+ adt_name: Option<hir::Name>,
+ target: GeneratedFunctionTarget,
+ file: FileId,
+ insert_offset: TextSize,
+ ) -> Self {
+ Self { target_module, adt_name, target, file, insert_offset }
+ }
+}
+
+fn fn_target_info(
+ ctx: &AssistContext<'_>,
+ path: ast::Path,
+ call: &CallExpr,
+ fn_name: &str,
+) -> Option<TargetInfo> {
+ match path.qualifier() {
Some(qualifier) => match ctx.sema.resolve_path(&qualifier) {
Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) => {
- target_module = Some(module);
- get_fn_target(ctx, &target_module, call.clone())?
+ get_fn_target_info(ctx, &Some(module), call.clone())
}
Some(hir::PathResolution::Def(hir::ModuleDef::Adt(adt))) => {
if let hir::Adt::Enum(_) = adt {
// Don't suggest generating function if the name starts with an uppercase letter
- if name_ref.text().starts_with(char::is_uppercase) {
+ if fn_name.starts_with(char::is_uppercase) {
return None;
}
}
- let current_module = ctx.sema.scope(call.syntax())?.module();
- let module = adt.module(ctx.sema.db);
- target_module = if current_module == module { None } else { Some(module) };
- if current_module.krate() != module.krate() {
- return None;
- }
- let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?;
- let (target, insert_offset) = get_method_target(ctx, &module, &impl_)?;
- adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None };
- (target, file, insert_offset)
+ assoc_fn_target_info(ctx, call, adt, fn_name)
}
- _ => {
- return None;
+ Some(hir::PathResolution::SelfType(impl_)) => {
+ let adt = impl_.self_ty(ctx.db()).as_adt()?;
+ assoc_fn_target_info(ctx, call, adt, fn_name)
}
+ _ => None,
},
- _ => {
- target_module = None;
- get_fn_target(ctx, &target_module, call.clone())?
- }
- };
- let function_builder = FunctionBuilder::from_call(ctx, &call, fn_name, target_module, target)?;
- let text_range = call.syntax().text_range();
- let label = format!("Generate {} function", function_builder.fn_name);
- add_func_to_accumulator(
- acc,
- ctx,
- text_range,
- function_builder,
- insert_offset,
- file,
- adt_name,
- label,
- )
+ _ => get_fn_target_info(ctx, &None, call.clone()),
+ }
}
fn gen_method(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
@@ -366,6 +382,15 @@ fn make_return_type(
(ret_type, should_focus_return_type)
}
+fn get_fn_target_info(
+ ctx: &AssistContext<'_>,
+ target_module: &Option<Module>,
+ call: CallExpr,
+) -> Option<TargetInfo> {
+ let (target, file, insert_offset) = get_fn_target(ctx, target_module, call)?;
+ Some(TargetInfo::new(*target_module, None, target, file, insert_offset))
+}
+
fn get_fn_target(
ctx: &AssistContext<'_>,
target_module: &Option<Module>,
@@ -399,6 +424,24 @@ fn get_method_target(
Some((target.clone(), get_insert_offset(&target)))
}
+fn assoc_fn_target_info(
+ ctx: &AssistContext<'_>,
+ call: &CallExpr,
+ adt: hir::Adt,
+ fn_name: &str,
+) -> Option<TargetInfo> {
+ let current_module = ctx.sema.scope(call.syntax())?.module();
+ let module = adt.module(ctx.sema.db);
+ let target_module = if current_module == module { None } else { Some(module) };
+ if current_module.krate() != module.krate() {
+ return None;
+ }
+ let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?;
+ let (target, insert_offset) = get_method_target(ctx, &module, &impl_)?;
+ let adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None };
+ Some(TargetInfo::new(target_module, adt_name, target, file, insert_offset))
+}
+
fn get_insert_offset(target: &GeneratedFunctionTarget) -> TextSize {
match &target {
GeneratedFunctionTarget::BehindItem(it) => it.text_range().end(),
@@ -1634,6 +1677,33 @@ fn bar() ${0:-> _} {
}
#[test]
+ fn create_static_method_within_an_impl_with_self_syntax() {
+ check_assist(
+ generate_function,
+ r"
+struct S;
+impl S {
+ fn foo(&self) {
+ Self::bar$0();
+ }
+}
+",
+ r"
+struct S;
+impl S {
+ fn foo(&self) {
+ Self::bar();
+ }
+
+ fn bar() ${0:-> _} {
+ todo!()
+ }
+}
+",
+ )
+ }
+
+ #[test]
fn no_panic_on_invalid_global_path() {
check_assist(
generate_function,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
index 80d3b9255..9f51cdaf8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
@@ -7,13 +7,14 @@ use ide_db::{
imports::insert_use::remove_path_if_in_use_stmt,
path_transform::PathTransform,
search::{FileReference, SearchScope},
+ source_change::SourceChangeBuilder,
syntax_helpers::{insert_whitespace_into_node::insert_ws_into, node_ext::expr_as_name_ref},
RootDatabase,
};
use itertools::{izip, Itertools};
use syntax::{
ast::{self, edit_in_place::Indent, HasArgList, PathExpr},
- ted, AstNode,
+ ted, AstNode, NodeOrToken, SyntaxKind,
};
use crate::{
@@ -100,18 +101,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) ->
builder.edit_file(file_id);
let count = refs.len();
// The collects are required as we are otherwise iterating while mutating 🙅â€â™€ï¸ðŸ™…â€â™‚ï¸
- let (name_refs, name_refs_use): (Vec<_>, Vec<_>) = refs
- .into_iter()
- .filter_map(|file_ref| match file_ref.name {
- ast::NameLike::NameRef(name_ref) => Some(name_ref),
- _ => None,
- })
- .partition_map(|name_ref| {
- match name_ref.syntax().ancestors().find_map(ast::UseTree::cast) {
- Some(use_tree) => Either::Right(builder.make_mut(use_tree)),
- None => Either::Left(name_ref),
- }
- });
+ let (name_refs, name_refs_use) = split_refs_and_uses(builder, refs, Some);
let call_infos: Vec<_> = name_refs
.into_iter()
.filter_map(CallInfo::from_name_ref)
@@ -130,11 +120,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) ->
.count();
if replaced + name_refs_use.len() == count {
// we replaced all usages in this file, so we can remove the imports
- name_refs_use.into_iter().for_each(|use_tree| {
- if let Some(path) = use_tree.path() {
- remove_path_if_in_use_stmt(&path);
- }
- })
+ name_refs_use.iter().for_each(remove_path_if_in_use_stmt);
} else {
remove_def = false;
}
@@ -153,6 +139,23 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) ->
)
}
+pub(super) fn split_refs_and_uses<T: ast::AstNode>(
+ builder: &mut SourceChangeBuilder,
+ iter: impl IntoIterator<Item = FileReference>,
+ mut map_ref: impl FnMut(ast::NameRef) -> Option<T>,
+) -> (Vec<T>, Vec<ast::Path>) {
+ iter.into_iter()
+ .filter_map(|file_ref| match file_ref.name {
+ ast::NameLike::NameRef(name_ref) => Some(name_ref),
+ _ => None,
+ })
+ .filter_map(|name_ref| match name_ref.syntax().ancestors().find_map(ast::UseTree::cast) {
+ Some(use_tree) => builder.make_mut(use_tree).path().map(Either::Right),
+ None => map_ref(name_ref).map(Either::Left),
+ })
+ .partition_map(|either| either)
+}
+
// Assist: inline_call
//
// Inlines a function or method body creating a `let` statement per parameter unless the parameter
@@ -311,6 +314,17 @@ fn inline(
} else {
fn_body.clone_for_update()
};
+ if let Some(imp) = body.syntax().ancestors().find_map(ast::Impl::cast) {
+ if !node.syntax().ancestors().any(|anc| &anc == imp.syntax()) {
+ if let Some(t) = imp.self_ty() {
+ body.syntax()
+ .descendants_with_tokens()
+ .filter_map(NodeOrToken::into_token)
+ .filter(|tok| tok.kind() == SyntaxKind::SELF_TYPE_KW)
+ .for_each(|tok| ted::replace(tok, t.syntax()));
+ }
+ }
+ }
let usages_for_locals = |local| {
Definition::Local(local)
.usages(sema)
@@ -345,6 +359,7 @@ fn inline(
}
})
.collect();
+
if function.self_param(sema.db).is_some() {
let this = || make::name_ref("this").syntax().clone_for_update();
if let Some(self_local) = params[0].2.as_local(sema.db) {
@@ -1191,4 +1206,54 @@ fn bar() -> u32 {
"#,
)
}
+
+ #[test]
+ fn inline_call_with_self_type() {
+ check_assist(
+ inline_call,
+ r#"
+struct A(u32);
+impl A {
+ fn f() -> Self { Self(114514) }
+}
+fn main() {
+ A::f$0();
+}
+"#,
+ r#"
+struct A(u32);
+impl A {
+ fn f() -> Self { Self(114514) }
+}
+fn main() {
+ A(114514);
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn inline_call_with_self_type_but_within_same_impl() {
+ check_assist(
+ inline_call,
+ r#"
+struct A(u32);
+impl A {
+ fn f() -> Self { Self(1919810) }
+ fn main() {
+ Self::f$0();
+ }
+}
+"#,
+ r#"
+struct A(u32);
+impl A {
+ fn f() -> Self { Self(1919810) }
+ fn main() {
+ Self(1919810);
+ }
+}
+"#,
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
index 054663a06..353d467ed 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
@@ -1,9 +1,12 @@
// Some ideas for future improvements:
// - Support replacing aliases which are used in expressions, e.g. `A::new()`.
-// - "inline_alias_to_users" assist #10881.
// - Remove unused aliases if there are no longer any users, see inline_call.rs.
use hir::{HasSource, PathResolution};
+use ide_db::{
+ defs::Definition, imports::insert_use::ast_to_remove_for_path_in_use_stmt,
+ search::FileReference,
+};
use itertools::Itertools;
use std::collections::HashMap;
use syntax::{
@@ -16,6 +19,89 @@ use crate::{
AssistId, AssistKind,
};
+use super::inline_call::split_refs_and_uses;
+
+// Assist: inline_type_alias_uses
+//
+// Inline a type alias into all of its uses where possible.
+//
+// ```
+// type $0A = i32;
+// fn id(x: A) -> A {
+// x
+// };
+// fn foo() {
+// let _: A = 3;
+// }
+// ```
+// ->
+// ```
+//
+// fn id(x: i32) -> i32 {
+// x
+// };
+// fn foo() {
+// let _: i32 = 3;
+// }
+pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let name = ctx.find_node_at_offset::<ast::Name>()?;
+ let ast_alias = name.syntax().parent().and_then(ast::TypeAlias::cast)?;
+
+ let hir_alias = ctx.sema.to_def(&ast_alias)?;
+ let concrete_type = ast_alias.ty()?;
+
+ let usages = Definition::TypeAlias(hir_alias).usages(&ctx.sema);
+ if !usages.at_least_one() {
+ return None;
+ }
+
+ // until this is ok
+
+ acc.add(
+ AssistId("inline_type_alias_uses", AssistKind::RefactorInline),
+ "Inline type alias into all uses",
+ name.syntax().text_range(),
+ |builder| {
+ let usages = usages.all();
+ let mut definition_deleted = false;
+
+ let mut inline_refs_for_file = |file_id, refs: Vec<FileReference>| {
+ builder.edit_file(file_id);
+
+ let (path_types, path_type_uses) =
+ split_refs_and_uses(builder, refs, |path_type| {
+ path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast)
+ });
+
+ path_type_uses
+ .iter()
+ .flat_map(ast_to_remove_for_path_in_use_stmt)
+ .for_each(|x| builder.delete(x.syntax().text_range()));
+ for (target, replacement) in path_types.into_iter().filter_map(|path_type| {
+ let replacement = inline(&ast_alias, &path_type)?.to_text(&concrete_type);
+ let target = path_type.syntax().text_range();
+ Some((target, replacement))
+ }) {
+ builder.replace(target, replacement);
+ }
+
+ if file_id == ctx.file_id() {
+ builder.delete(ast_alias.syntax().text_range());
+ definition_deleted = true;
+ }
+ };
+
+ for (file_id, refs) in usages.into_iter() {
+ inline_refs_for_file(file_id, refs);
+ }
+ if !definition_deleted {
+ builder.edit_file(ctx.file_id());
+ builder.delete(ast_alias.syntax().text_range());
+ }
+ },
+ )
+}
+
// Assist: inline_type_alias
//
// Replace a type alias with its concrete type.
@@ -36,11 +122,6 @@ use crate::{
// }
// ```
pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
- enum Replacement {
- Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
- Plain,
- }
-
let alias_instance = ctx.find_node_at_offset::<ast::PathType>()?;
let concrete_type;
let replacement;
@@ -59,23 +140,7 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
_ => {
let alias = get_type_alias(&ctx, &alias_instance)?;
concrete_type = alias.ty()?;
-
- replacement = if let Some(alias_generics) = alias.generic_param_list() {
- if alias_generics.generic_params().next().is_none() {
- cov_mark::hit!(no_generics_params);
- return None;
- }
-
- let instance_args =
- alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
-
- Replacement::Generic {
- lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
- const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
- }
- } else {
- Replacement::Plain
- };
+ replacement = inline(&alias, &alias_instance)?;
}
}
@@ -85,19 +150,45 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
AssistId("inline_type_alias", AssistKind::RefactorInline),
"Inline type alias",
target,
- |builder| {
- let replacement_text = match replacement {
- Replacement::Generic { lifetime_map, const_and_type_map } => {
- create_replacement(&lifetime_map, &const_and_type_map, &concrete_type)
- }
- Replacement::Plain => concrete_type.to_string(),
- };
-
- builder.replace(target, replacement_text);
- },
+ |builder| builder.replace(target, replacement.to_text(&concrete_type)),
)
}
+impl Replacement {
+ fn to_text(&self, concrete_type: &ast::Type) -> String {
+ match self {
+ Replacement::Generic { lifetime_map, const_and_type_map } => {
+ create_replacement(&lifetime_map, &const_and_type_map, &concrete_type)
+ }
+ Replacement::Plain => concrete_type.to_string(),
+ }
+ }
+}
+
+enum Replacement {
+ Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
+ Plain,
+}
+
+fn inline(alias_def: &ast::TypeAlias, alias_instance: &ast::PathType) -> Option<Replacement> {
+ let repl = if let Some(alias_generics) = alias_def.generic_param_list() {
+ if alias_generics.generic_params().next().is_none() {
+ cov_mark::hit!(no_generics_params);
+ return None;
+ }
+ let instance_args =
+ alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
+
+ Replacement::Generic {
+ lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
+ const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
+ }
+ } else {
+ Replacement::Plain
+ };
+ Some(repl)
+}
+
struct LifetimeMap(HashMap<String, ast::Lifetime>);
impl LifetimeMap {
@@ -835,4 +926,95 @@ trait Tr {
"#,
);
}
+
+ mod inline_type_alias_uses {
+ use crate::{handlers::inline_type_alias::inline_type_alias_uses, tests::check_assist};
+
+ #[test]
+ fn inline_uses() {
+ check_assist(
+ inline_type_alias_uses,
+ r#"
+type $0A = u32;
+
+fn foo() {
+ let _: A = 3;
+ let _: A = 4;
+}
+"#,
+ r#"
+
+
+fn foo() {
+ let _: u32 = 3;
+ let _: u32 = 4;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn inline_uses_across_files() {
+ check_assist(
+ inline_type_alias_uses,
+ r#"
+//- /lib.rs
+mod foo;
+type $0T<E> = Vec<E>;
+fn f() -> T<&str> {
+ vec!["hello"]
+}
+
+//- /foo.rs
+use super::T;
+fn foo() {
+ let _: T<i8> = Vec::new();
+}
+"#,
+ r#"
+//- /lib.rs
+mod foo;
+
+fn f() -> Vec<&str> {
+ vec!["hello"]
+}
+
+//- /foo.rs
+
+fn foo() {
+ let _: Vec<i8> = Vec::new();
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn inline_uses_across_files_2() {
+ check_assist(
+ inline_type_alias_uses,
+ r#"
+//- /lib.rs
+mod foo;
+type $0I = i32;
+
+//- /foo.rs
+use super::I;
+fn foo() {
+ let _: I = 0;
+}
+"#,
+ r#"
+//- /lib.rs
+mod foo;
+
+
+//- /foo.rs
+
+fn foo() {
+ let _: i32 = 0;
+}
+"#,
+ );
+ }
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
index ce91dd237..2fc754e3e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
@@ -5,7 +5,7 @@ use syntax::{
AstNode, TextRange,
};
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
static ASSIST_NAME: &str = "introduce_named_lifetime";
static ASSIST_LABEL: &str = "Introduce named lifetime";
@@ -140,7 +140,7 @@ enum NeedsLifetime {
}
impl NeedsLifetime {
- fn make_mut(self, builder: &mut AssistBuilder) -> Self {
+ fn make_mut(self, builder: &mut SourceChangeBuilder) -> Self {
match self {
Self::SelfParam(it) => Self::SelfParam(builder.make_mut(it)),
Self::RefType(it) => Self::RefType(builder.make_mut(it)),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
index 7e102ceba..2bdbec93b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
@@ -1,6 +1,10 @@
use either::Either;
use ide_db::imports::merge_imports::{try_merge_imports, try_merge_trees, MergeBehavior};
-use syntax::{algo::neighbor, ast, match_ast, ted, AstNode, SyntaxElement, SyntaxNode};
+use syntax::{
+ algo::neighbor,
+ ast::{self, edit_in_place::Removable},
+ match_ast, ted, AstNode, SyntaxElement, SyntaxNode,
+};
use crate::{
assist_context::{AssistContext, Assists},
@@ -76,7 +80,7 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
.collect();
for edit in edits_mut {
match edit {
- Remove(it) => it.as_ref().either(ast::Use::remove, ast::UseTree::remove),
+ Remove(it) => it.as_ref().either(Removable::remove, Removable::remove),
Replace(old, new) => ted::replace(old, new),
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs
index 176a3bf58..1dd376ac3 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_bounds.rs
@@ -1,5 +1,9 @@
use syntax::{
- ast::{self, edit_in_place::GenericParamsOwnerEdit, make, AstNode, HasName, HasTypeBounds},
+ ast::{
+ self,
+ edit_in_place::{GenericParamsOwnerEdit, Removable},
+ make, AstNode, HasName, HasTypeBounds,
+ },
match_ast,
};
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
index 59ea94ea1..bd2e8fbe3 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
@@ -8,7 +8,8 @@ use syntax::{
use SyntaxKind::WHITESPACE;
use crate::{
- assist_context::AssistBuilder, utils::next_prev, AssistContext, AssistId, AssistKind, Assists,
+ assist_context::SourceChangeBuilder, utils::next_prev, AssistContext, AssistId, AssistKind,
+ Assists,
};
// Assist: remove_unused_param
@@ -88,7 +89,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) ->
fn process_usages(
ctx: &AssistContext<'_>,
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
file_id: FileId,
references: Vec<FileReference>,
arg_to_remove: usize,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index bd50208da..d139f78a6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -10,7 +10,7 @@ use syntax::{
};
use crate::{
- assist_context::{AssistBuilder, AssistContext, Assists},
+ assist_context::{AssistContext, Assists, SourceChangeBuilder},
utils::{
add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_fn_body,
generate_trait_impl_text, render_snippet, Cursor, DefaultMethods,
@@ -224,7 +224,7 @@ fn impl_def_from_trait(
}
fn update_attribute(
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
old_derives: &[ast::Path],
old_tree: &ast::TokenTree,
old_trait_path: &ast::Path,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
new file mode 100644
index 000000000..7d91be621
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
@@ -0,0 +1,364 @@
+use ide_db::{
+ assists::{AssistId, AssistKind},
+ famous_defs::FamousDefs,
+};
+use syntax::{
+ ast::{self, make, Expr, HasArgList},
+ AstNode,
+};
+
+use crate::{AssistContext, Assists};
+
+// Assist: replace_or_with_or_else
+//
+// Replace `unwrap_or` with `unwrap_or_else` and `ok_or` with `ok_or_else`.
+//
+// ```
+// # //- minicore:option
+// fn foo() {
+// let a = Some(1);
+// a.unwra$0p_or(2);
+// }
+// ```
+// ->
+// ```
+// fn foo() {
+// let a = Some(1);
+// a.unwrap_or_else(|| 2);
+// }
+// ```
+pub(crate) fn replace_or_with_or_else(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let call: ast::MethodCallExpr = ctx.find_node_at_offset()?;
+
+ let kind = is_option_or_result(call.receiver()?, ctx)?;
+
+ let (name, arg_list) = (call.name_ref()?, call.arg_list()?);
+
+ let mut map_or = false;
+
+ let replace = match &*name.text() {
+ "unwrap_or" => "unwrap_or_else".to_string(),
+ "or" => "or_else".to_string(),
+ "ok_or" if kind == Kind::Option => "ok_or_else".to_string(),
+ "map_or" => {
+ map_or = true;
+ "map_or_else".to_string()
+ }
+ _ => return None,
+ };
+
+ let arg = match arg_list.args().collect::<Vec<_>>().as_slice() {
+ [] => make::arg_list(Vec::new()),
+ [first] => {
+ let param = into_closure(first);
+ make::arg_list(vec![param])
+ }
+ [first, second] if map_or => {
+ let param = into_closure(first);
+ make::arg_list(vec![param, second.clone()])
+ }
+ _ => return None,
+ };
+
+ acc.add(
+ AssistId("replace_or_with_or_else", AssistKind::RefactorRewrite),
+ format!("Replace {} with {}", name.text(), replace),
+ call.syntax().text_range(),
+ |builder| {
+ builder.replace(name.syntax().text_range(), replace);
+ builder.replace_ast(arg_list, arg)
+ },
+ )
+}
+
+fn into_closure(param: &Expr) -> Expr {
+ (|| {
+ if let ast::Expr::CallExpr(call) = param {
+ if call.arg_list()?.args().count() == 0 {
+ Some(call.expr()?.clone())
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ })()
+ .unwrap_or_else(|| make::expr_closure(None, param.clone()))
+}
+
+// Assist: replace_or_else_with_or
+//
+// Replace `unwrap_or_else` with `unwrap_or` and `ok_or_else` with `ok_or`.
+//
+// ```
+// # //- minicore:option
+// fn foo() {
+// let a = Some(1);
+// a.unwra$0p_or_else(|| 2);
+// }
+// ```
+// ->
+// ```
+// fn foo() {
+// let a = Some(1);
+// a.unwrap_or(2);
+// }
+// ```
+pub(crate) fn replace_or_else_with_or(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let call: ast::MethodCallExpr = ctx.find_node_at_offset()?;
+
+ let kind = is_option_or_result(call.receiver()?, ctx)?;
+
+ let (name, arg_list) = (call.name_ref()?, call.arg_list()?);
+
+ let mut map_or = false;
+ let replace = match &*name.text() {
+ "unwrap_or_else" => "unwrap_or".to_string(),
+ "or_else" => "or".to_string(),
+ "ok_or_else" if kind == Kind::Option => "ok_or".to_string(),
+ "map_or_else" => {
+ map_or = true;
+ "map_or".to_string()
+ }
+ _ => return None,
+ };
+
+ let arg = match arg_list.args().collect::<Vec<_>>().as_slice() {
+ [] => make::arg_list(Vec::new()),
+ [first] => {
+ let param = into_call(first);
+ make::arg_list(vec![param])
+ }
+ [first, second] if map_or => {
+ let param = into_call(first);
+ make::arg_list(vec![param, second.clone()])
+ }
+ _ => return None,
+ };
+
+ acc.add(
+ AssistId("replace_or_else_with_or", AssistKind::RefactorRewrite),
+ format!("Replace {} with {}", name.text(), replace),
+ call.syntax().text_range(),
+ |builder| {
+ builder.replace(name.syntax().text_range(), replace);
+ builder.replace_ast(arg_list, arg)
+ },
+ )
+}
+
+fn into_call(param: &Expr) -> Expr {
+ (|| {
+ if let ast::Expr::ClosureExpr(closure) = param {
+ if closure.param_list()?.params().count() == 0 {
+ Some(closure.body()?.clone())
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ })()
+ .unwrap_or_else(|| make::expr_call(param.clone(), make::arg_list(Vec::new())))
+}
+
+#[derive(PartialEq, Eq)]
+enum Kind {
+ Option,
+ Result,
+}
+
+fn is_option_or_result(receiver: Expr, ctx: &AssistContext<'_>) -> Option<Kind> {
+ let ty = ctx.sema.type_of_expr(&receiver)?.adjusted().as_adt()?.as_enum()?;
+ let option_enum =
+ FamousDefs(&ctx.sema, ctx.sema.scope(receiver.syntax())?.krate()).core_option_Option();
+
+ if let Some(option_enum) = option_enum {
+ if ty == option_enum {
+ return Some(Kind::Option);
+ }
+ }
+
+ let result_enum =
+ FamousDefs(&ctx.sema, ctx.sema.scope(receiver.syntax())?.krate()).core_result_Result();
+
+ if let Some(result_enum) = result_enum {
+ if ty == result_enum {
+ return Some(Kind::Result);
+ }
+ }
+
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::{check_assist, check_assist_not_applicable};
+
+ use super::*;
+
+ #[test]
+ fn replace_or_with_or_else_simple() {
+ check_assist(
+ replace_or_with_or_else,
+ r#"
+//- minicore: option
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_$0or(2);
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_or_else(|| 2);
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_with_or_else_call() {
+ check_assist(
+ replace_or_with_or_else,
+ r#"
+//- minicore: option
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_$0or(x());
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_or_else(x);
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_with_or_else_block() {
+ check_assist(
+ replace_or_with_or_else,
+ r#"
+//- minicore: option
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_$0or({
+ let mut x = bar();
+ for i in 0..10 {
+ x += i;
+ }
+ x
+ });
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_or_else(|| {
+ let mut x = bar();
+ for i in 0..10 {
+ x += i;
+ }
+ x
+ });
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_else_with_or_simple() {
+ check_assist(
+ replace_or_else_with_or,
+ r#"
+//- minicore: option
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_$0or_else(|| 2);
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_or(2);
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_else_with_or_call() {
+ check_assist(
+ replace_or_else_with_or,
+ r#"
+//- minicore: option
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_$0or_else(x);
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Some(1);
+ return foo.unwrap_or(x());
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_else_with_or_result() {
+ check_assist(
+ replace_or_else_with_or,
+ r#"
+//- minicore: result
+fn foo() {
+ let foo = Ok(1);
+ return foo.unwrap_$0or_else(x);
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Ok(1);
+ return foo.unwrap_or(x());
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_else_with_or_map() {
+ check_assist(
+ replace_or_else_with_or,
+ r#"
+//- minicore: result
+fn foo() {
+ let foo = Ok("foo");
+ return foo.map$0_or_else(|| 42, |v| v.len());
+}
+"#,
+ r#"
+fn foo() {
+ let foo = Ok("foo");
+ return foo.map_or(42, |v| v.len());
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn replace_or_else_with_or_not_applicable() {
+ check_assist_not_applicable(
+ replace_or_else_with_or,
+ r#"
+fn foo() {
+ let foo = Ok(1);
+ return foo.unwrap_$0or_else(x);
+}
+"#,
+ )
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
index 6112e0945..521447c26 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
@@ -1,5 +1,6 @@
+use hir::HirDisplay;
use syntax::{
- ast::{Expr, GenericArg},
+ ast::{Expr, GenericArg, GenericArgList},
ast::{LetStmt, Type::InferType},
AstNode, TextRange,
};
@@ -34,21 +35,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
let initializer = let_stmt.initializer()?;
- let generic_args = match &initializer {
- Expr::MethodCallExpr(ce) => ce.generic_arg_list()?,
- Expr::CallExpr(ce) => {
- if let Expr::PathExpr(pe) = ce.expr()? {
- pe.path()?.segment()?.generic_arg_list()?
- } else {
- cov_mark::hit!(not_applicable_if_non_path_function_call);
- return None;
- }
- }
- _ => {
- cov_mark::hit!(not_applicable_if_non_function_call_initializer);
- return None;
- }
- };
+ let generic_args = generic_arg_list(&initializer)?;
// Find range of ::<_>
let colon2 = generic_args.coloncolon_token()?;
@@ -65,7 +52,16 @@ pub(crate) fn replace_turbofish_with_explicit_type(
// An improvement would be to check that this is correctly part of the return value of the
// function call, or sub in the actual return type.
- let turbofish_type = &turbofish_args[0];
+ let returned_type = match ctx.sema.type_of_expr(&initializer) {
+ Some(returned_type) if !returned_type.original.contains_unknown() => {
+ let module = ctx.sema.scope(let_stmt.syntax())?.module();
+ returned_type.original.display_source_code(ctx.db(), module.into()).ok()?
+ }
+ _ => {
+ cov_mark::hit!(fallback_to_turbofish_type_if_type_info_not_available);
+ turbofish_args[0].to_string()
+ }
+ };
let initializer_start = initializer.syntax().text_range().start();
if ctx.offset() > turbofish_range.end() || ctx.offset() < initializer_start {
@@ -83,12 +79,12 @@ pub(crate) fn replace_turbofish_with_explicit_type(
"Replace turbofish with explicit type",
TextRange::new(initializer_start, turbofish_range.end()),
|builder| {
- builder.insert(ident_range.end(), format!(": {}", turbofish_type));
+ builder.insert(ident_range.end(), format!(": {}", returned_type));
builder.delete(turbofish_range);
},
);
} else if let Some(InferType(t)) = let_stmt.ty() {
- // If there's a type inferrence underscore, we can offer to replace it with the type in
+ // If there's a type inference underscore, we can offer to replace it with the type in
// the turbofish.
// let x: _ = fn::<...>();
let underscore_range = t.syntax().text_range();
@@ -98,7 +94,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
"Replace `_` with turbofish type",
turbofish_range,
|builder| {
- builder.replace(underscore_range, turbofish_type.to_string());
+ builder.replace(underscore_range, returned_type);
builder.delete(turbofish_range);
},
);
@@ -107,6 +103,26 @@ pub(crate) fn replace_turbofish_with_explicit_type(
None
}
+fn generic_arg_list(expr: &Expr) -> Option<GenericArgList> {
+ match expr {
+ Expr::MethodCallExpr(expr) => expr.generic_arg_list(),
+ Expr::CallExpr(expr) => {
+ if let Expr::PathExpr(pe) = expr.expr()? {
+ pe.path()?.segment()?.generic_arg_list()
+ } else {
+ cov_mark::hit!(not_applicable_if_non_path_function_call);
+ return None;
+ }
+ }
+ Expr::AwaitExpr(expr) => generic_arg_list(&expr.expr()?),
+ Expr::TryExpr(expr) => generic_arg_list(&expr.expr()?),
+ _ => {
+ cov_mark::hit!(not_applicable_if_non_function_call_initializer);
+ None
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -115,6 +131,7 @@ mod tests {
#[test]
fn replaces_turbofish_for_vec_string() {
+ cov_mark::check!(fallback_to_turbofish_type_if_type_info_not_available);
check_assist(
replace_turbofish_with_explicit_type,
r#"
@@ -135,6 +152,7 @@ fn main() {
#[test]
fn replaces_method_calls() {
// foo.make() is a method call which uses a different expr in the let initializer
+ cov_mark::check!(fallback_to_turbofish_type_if_type_info_not_available);
check_assist(
replace_turbofish_with_explicit_type,
r#"
@@ -240,4 +258,108 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn replaces_turbofish_for_known_type() {
+ check_assist(
+ replace_turbofish_with_explicit_type,
+ r#"
+fn make<T>() -> T {}
+fn main() {
+ let a = make$0::<i32>();
+}
+"#,
+ r#"
+fn make<T>() -> T {}
+fn main() {
+ let a: i32 = make();
+}
+"#,
+ );
+ check_assist(
+ replace_turbofish_with_explicit_type,
+ r#"
+//- minicore: option
+fn make<T>() -> T {}
+fn main() {
+ let a = make$0::<Option<bool>>();
+}
+"#,
+ r#"
+fn make<T>() -> T {}
+fn main() {
+ let a: Option<bool> = make();
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn replaces_turbofish_not_same_type() {
+ check_assist(
+ replace_turbofish_with_explicit_type,
+ r#"
+//- minicore: option
+fn make<T>() -> Option<T> {}
+fn main() {
+ let a = make$0::<u128>();
+}
+"#,
+ r#"
+fn make<T>() -> Option<T> {}
+fn main() {
+ let a: Option<u128> = make();
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn replaces_turbofish_for_type_with_defaulted_generic_param() {
+ check_assist(
+ replace_turbofish_with_explicit_type,
+ r#"
+struct HasDefault<T, U = i32>(T, U);
+fn make<T>() -> HasDefault<T> {}
+fn main() {
+ let a = make$0::<bool>();
+}
+"#,
+ r#"
+struct HasDefault<T, U = i32>(T, U);
+fn make<T>() -> HasDefault<T> {}
+fn main() {
+ let a: HasDefault<bool> = make();
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn replaces_turbofish_try_await() {
+ check_assist(
+ replace_turbofish_with_explicit_type,
+ r#"
+//- minicore: option, future
+struct Fut<T>(T);
+impl<T> core::future::Future for Fut<T> {
+ type Output = Option<T>;
+}
+fn make<T>() -> Fut<T> {}
+fn main() {
+ let a = make$0::<bool>().await?;
+}
+"#,
+ r#"
+struct Fut<T>(T);
+impl<T> core::future::Future for Fut<T> {
+ type Output = Option<T>;
+}
+fn make<T>() -> Fut<T> {}
+fn main() {
+ let a: bool = make().await?;
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
new file mode 100644
index 000000000..9565f0ee6
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
@@ -0,0 +1,293 @@
+use syntax::{
+ algo::neighbor,
+ ast::{self, edit::IndentLevel, make, AstNode},
+ ted::{self, Position},
+ Direction, SyntaxKind, T,
+};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: unmerge_match_arm
+//
+// Splits the current match with a `|` pattern into two arms with identical bodies.
+//
+// ```
+// enum Action { Move { distance: u32 }, Stop }
+//
+// fn handle(action: Action) {
+// match action {
+// Action::Move(..) $0| Action::Stop => foo(),
+// }
+// }
+// ```
+// ->
+// ```
+// enum Action { Move { distance: u32 }, Stop }
+//
+// fn handle(action: Action) {
+// match action {
+// Action::Move(..) => foo(),
+// Action::Stop => foo(),
+// }
+// }
+// ```
+pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let pipe_token = ctx.find_token_syntax_at_offset(T![|])?;
+ let or_pat = ast::OrPat::cast(pipe_token.parent()?)?.clone_for_update();
+ let match_arm = ast::MatchArm::cast(or_pat.syntax().parent()?)?;
+ let match_arm_body = match_arm.expr()?;
+
+ // We don't need to check for leading pipe because it is directly under `MatchArm`
+ // without `OrPat`.
+
+ let new_parent = match_arm.syntax().parent()?;
+ let old_parent_range = new_parent.text_range();
+
+ acc.add(
+ AssistId("unmerge_match_arm", AssistKind::RefactorRewrite),
+ "Unmerge match arm",
+ pipe_token.text_range(),
+ |edit| {
+ let pats_after = pipe_token
+ .siblings_with_tokens(Direction::Next)
+ .filter_map(|it| ast::Pat::cast(it.into_node()?));
+ // FIXME: We should add a leading pipe if the original arm has one.
+ let new_match_arm = make::match_arm(
+ pats_after,
+ match_arm.guard().and_then(|guard| guard.condition()),
+ match_arm_body,
+ )
+ .clone_for_update();
+
+ let mut pipe_index = pipe_token.index();
+ if pipe_token
+ .prev_sibling_or_token()
+ .map_or(false, |it| it.kind() == SyntaxKind::WHITESPACE)
+ {
+ pipe_index -= 1;
+ }
+ or_pat.syntax().splice_children(
+ pipe_index..or_pat.syntax().children_with_tokens().count(),
+ Vec::new(),
+ );
+
+ let mut insert_after_old_arm = Vec::new();
+
+ // A comma can be:
+ // - After the arm. In this case we always want to insert a comma after the newly
+ // inserted arm.
+ // - Missing after the arm, with no arms after. In this case we want to insert a
+ // comma before the newly inserted arm. It can not be necessary if there arm
+ // body is a block, but we don't bother to check that.
+ // - Missing after the arm with arms after, if the arm body is a block. In this case
+ // we don't want to insert a comma at all.
+ let has_comma_after =
+ std::iter::successors(match_arm.syntax().last_child_or_token(), |it| {
+ it.prev_sibling_or_token()
+ })
+ .map(|it| it.kind())
+ .skip_while(|it| it.is_trivia())
+ .next()
+ == Some(T![,]);
+ let has_arms_after = neighbor(&match_arm, Direction::Next).is_some();
+ if !has_comma_after && !has_arms_after {
+ insert_after_old_arm.push(make::token(T![,]).into());
+ }
+
+ let indent = IndentLevel::from_node(match_arm.syntax());
+ insert_after_old_arm.push(make::tokens::whitespace(&format!("\n{indent}")).into());
+
+ insert_after_old_arm.push(new_match_arm.syntax().clone().into());
+
+ ted::insert_all_raw(Position::after(match_arm.syntax()), insert_after_old_arm);
+
+ if has_comma_after {
+ ted::insert_raw(
+ Position::last_child_of(new_match_arm.syntax()),
+ make::token(T![,]),
+ );
+ }
+
+ edit.replace(old_parent_range, new_parent.to_string());
+ },
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::{check_assist, check_assist_not_applicable};
+
+ use super::*;
+
+ #[test]
+ fn unmerge_match_arm_single_pipe() {
+ check_assist(
+ unmerge_match_arm,
+ r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A $0| X::B => { 1i32 }
+ X::C => { 2i32 }
+ };
+}
+"#,
+ r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A => { 1i32 }
+ X::B => { 1i32 }
+ X::C => { 2i32 }
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn unmerge_match_arm_guard() {
+ check_assist(
+ unmerge_match_arm,
+ r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A $0| X::B if true => { 1i32 }
+ _ => { 2i32 }
+ };
+}
+"#,
+ r#"
+#[derive(Debug)]
+enum X { A, B, C }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A if true => { 1i32 }
+ X::B if true => { 1i32 }
+ _ => { 2i32 }
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn unmerge_match_arm_leading_pipe() {
+ check_assist_not_applicable(
+ unmerge_match_arm,
+ r#"
+
+fn main() {
+ let y = match 0 {
+ |$0 0 => { 1i32 }
+ 1 => { 2i32 }
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn unmerge_match_arm_multiple_pipes() {
+ check_assist(
+ unmerge_match_arm,
+ r#"
+#[derive(Debug)]
+enum X { A, B, C, D, E }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A | X::B |$0 X::C | X::D => 1i32,
+ X::E => 2i32,
+ };
+}
+"#,
+ r#"
+#[derive(Debug)]
+enum X { A, B, C, D, E }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A | X::B => 1i32,
+ X::C | X::D => 1i32,
+ X::E => 2i32,
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn unmerge_match_arm_inserts_comma_if_required() {
+ check_assist(
+ unmerge_match_arm,
+ r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A $0| X::B => 1i32
+ };
+}
+"#,
+ r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+ let x = X::A;
+ let y = match x {
+ X::A => 1i32,
+ X::B => 1i32
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn unmerge_match_arm_inserts_comma_if_had_after() {
+ check_assist(
+ unmerge_match_arm,
+ r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+ let x = X::A;
+ match x {
+ X::A $0| X::B => {},
+ }
+}
+"#,
+ r#"
+#[derive(Debug)]
+enum X { A, B }
+
+fn main() {
+ let x = X::A;
+ match x {
+ X::A => {},
+ X::B => {},
+ }
+}
+"#,
+ );
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs
index 3ce028e93..dac216b69 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs
@@ -1,5 +1,5 @@
use syntax::{
- ast::{self, make, HasVisibility},
+ ast::{self, edit_in_place::Removable, make, HasVisibility},
ted::{self, Position},
AstNode, SyntaxKind,
};
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
index fe87aa15f..e52544db5 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
@@ -122,6 +122,7 @@ mod handlers {
mod convert_let_else_to_match;
mod convert_tuple_struct_to_named_struct;
mod convert_to_guarded_return;
+ mod convert_two_arm_bool_match_to_matches_macro;
mod convert_while_to_loop;
mod destructure_tuple_binding;
mod expand_glob_import;
@@ -179,12 +180,14 @@ mod handlers {
mod replace_try_expr_with_match;
mod replace_derive_with_manual_impl;
mod replace_if_let_with_match;
+ mod replace_or_with_or_else;
mod introduce_named_generic;
mod replace_let_with_if_let;
mod replace_qualified_name_with_use;
mod replace_string_with_char;
mod replace_turbofish_with_explicit_type;
mod split_import;
+ mod unmerge_match_arm;
mod sort_items;
mod toggle_ignore;
mod unmerge_use;
@@ -215,6 +218,7 @@ mod handlers {
convert_let_else_to_match::convert_let_else_to_match,
convert_to_guarded_return::convert_to_guarded_return,
convert_tuple_struct_to_named_struct::convert_tuple_struct_to_named_struct,
+ convert_two_arm_bool_match_to_matches_macro::convert_two_arm_bool_match_to_matches_macro,
convert_while_to_loop::convert_while_to_loop,
destructure_tuple_binding::destructure_tuple_binding,
expand_glob_import::expand_glob_import,
@@ -243,6 +247,7 @@ mod handlers {
inline_call::inline_into_callers,
inline_local_variable::inline_local_variable,
inline_type_alias::inline_type_alias,
+ inline_type_alias::inline_type_alias_uses,
introduce_named_generic::introduce_named_generic,
introduce_named_lifetime::introduce_named_lifetime,
invert_if::invert_if,
@@ -272,11 +277,14 @@ mod handlers {
replace_if_let_with_match::replace_if_let_with_match,
replace_if_let_with_match::replace_match_with_if_let,
replace_let_with_if_let::replace_let_with_if_let,
+ replace_or_with_or_else::replace_or_else_with_or,
+ replace_or_with_or_else::replace_or_with_or_else,
replace_turbofish_with_explicit_type::replace_turbofish_with_explicit_type,
replace_qualified_name_with_use::replace_qualified_name_with_use,
sort_items::sort_items,
split_import::split_import,
toggle_ignore::toggle_ignore,
+ unmerge_match_arm::unmerge_match_arm,
unmerge_use::unmerge_use,
unnecessary_async::unnecessary_async,
unwrap_block::unwrap_block,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 6eaab48a3..227e2300f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -473,6 +473,26 @@ impl Point {
}
#[test]
+fn doctest_convert_two_arm_bool_match_to_matches_macro() {
+ check_doc_test(
+ "convert_two_arm_bool_match_to_matches_macro",
+ r#####"
+fn main() {
+ match scrutinee$0 {
+ Some(val) if val.cond() => true,
+ _ => false,
+ }
+}
+"#####,
+ r#####"
+fn main() {
+ matches!(scrutinee, Some(val) if val.cond())
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_convert_while_to_loop() {
check_doc_test(
"convert_while_to_loop",
@@ -1357,6 +1377,31 @@ fn main() {
}
#[test]
+fn doctest_inline_type_alias_uses() {
+ check_doc_test(
+ "inline_type_alias_uses",
+ r#####"
+type $0A = i32;
+fn id(x: A) -> A {
+ x
+};
+fn foo() {
+ let _: A = 3;
+}
+"#####,
+ r#####"
+
+fn id(x: i32) -> i32 {
+ x
+};
+fn foo() {
+ let _: i32 = 3;
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_introduce_named_generic() {
check_doc_test(
"introduce_named_generic",
@@ -1985,6 +2030,46 @@ fn handle(action: Action) {
}
#[test]
+fn doctest_replace_or_else_with_or() {
+ check_doc_test(
+ "replace_or_else_with_or",
+ r#####"
+//- minicore:option
+fn foo() {
+ let a = Some(1);
+ a.unwra$0p_or_else(|| 2);
+}
+"#####,
+ r#####"
+fn foo() {
+ let a = Some(1);
+ a.unwrap_or(2);
+}
+"#####,
+ )
+}
+
+#[test]
+fn doctest_replace_or_with_or_else() {
+ check_doc_test(
+ "replace_or_with_or_else",
+ r#####"
+//- minicore:option
+fn foo() {
+ let a = Some(1);
+ a.unwra$0p_or(2);
+}
+"#####,
+ r#####"
+fn foo() {
+ let a = Some(1);
+ a.unwrap_or_else(|| 2);
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_replace_qualified_name_with_use() {
check_doc_test(
"replace_qualified_name_with_use",
@@ -2183,6 +2268,32 @@ fn arithmetics {
}
#[test]
+fn doctest_unmerge_match_arm() {
+ check_doc_test(
+ "unmerge_match_arm",
+ r#####"
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move(..) $0| Action::Stop => foo(),
+ }
+}
+"#####,
+ r#####"
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move(..) => foo(),
+ Action::Stop => foo(),
+ }
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_unmerge_use() {
check_doc_test(
"unmerge_use",
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index 3e61d0741..4ab6e2627 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -12,7 +12,7 @@ use syntax::{
ast::{
self,
edit::{self, AstNodeEdit},
- edit_in_place::AttrsOwnerEdit,
+ edit_in_place::{AttrsOwnerEdit, Removable},
make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
},
ted, AstNode, AstToken, Direction, SmolStr, SourceFile,
@@ -20,7 +20,7 @@ use syntax::{
SyntaxNode, TextRange, TextSize, T,
};
-use crate::assist_context::{AssistBuilder, AssistContext};
+use crate::assist_context::{AssistContext, SourceChangeBuilder};
pub(crate) mod suggest_name;
mod gen_trait_fn_body;
@@ -484,7 +484,7 @@ fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str
}
pub(crate) fn add_method_to_adt(
- builder: &mut AssistBuilder,
+ builder: &mut SourceChangeBuilder,
adt: &ast::Adt,
impl_def: Option<ast::Impl>,
method: &str,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs
index 779cdbc93..c521a10fc 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs
@@ -55,6 +55,7 @@ const USELESS_METHODS: &[&str] = &[
"iter",
"into_iter",
"iter_mut",
+ "into_future",
];
pub(crate) fn for_generic_parameter(ty: &ast::ImplTraitType) -> SmolStr {
@@ -75,7 +76,7 @@ pub(crate) fn for_generic_parameter(ty: &ast::ImplTraitType) -> SmolStr {
/// In current implementation, the function tries to get the name from
/// the following sources:
///
-/// * if expr is an argument to function/method, use paramter name
+/// * if expr is an argument to function/method, use parameter name
/// * if expr is a function/method call, use function name
/// * expression type name if it exists (E.g. `()`, `fn() -> ()` or `!` do not have names)
/// * fallback: `var_name`
@@ -85,7 +86,7 @@ pub(crate) fn for_generic_parameter(ty: &ast::ImplTraitType) -> SmolStr {
/// Currently it sticks to the first name found.
// FIXME: Microoptimize and return a `SmolStr` here.
pub(crate) fn for_variable(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> String {
- // `from_param` does not benifit from stripping
+ // `from_param` does not benefit from stripping
// it need the largest context possible
// so we check firstmost
if let Some(name) = from_param(expr, sema) {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 72579e602..55c3e2839 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -617,7 +617,6 @@ pub(super) fn complete_name_ref(
dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx);
item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx);
- record::complete_record_expr_func_update(acc, ctx, path_ctx, expr_ctx);
snippet::complete_expr_snippet(acc, ctx, path_ctx, expr_ctx);
}
PathKind::Type { location } => {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs
index cf40ca489..02004ff7b 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs
@@ -19,7 +19,7 @@ pub(crate) fn complete_dot(
};
// Suggest .await syntax for types that implement Future trait
- if receiver_ty.impls_future(ctx.db) {
+ if receiver_ty.impls_into_future(ctx.db) {
let mut item =
CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await");
item.detail("expr.await");
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
index 5d0ddaaf2..588b52cc1 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
@@ -1,8 +1,10 @@
//! Completion of names from the current scope in expression position.
use hir::ScopeDef;
+use syntax::ast;
use crate::{
+ completions::record::add_default_update,
context::{ExprCtx, PathCompletionCtx, Qualified},
CompletionContext, Completions,
};
@@ -219,60 +221,90 @@ pub(crate) fn complete_expr_path(
_ => (),
});
- if is_func_update.is_none() {
- let mut add_keyword =
- |kw, snippet| acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet);
+ match is_func_update {
+ Some(record_expr) => {
+ let ty = ctx.sema.type_of_expr(&ast::Expr::RecordExpr(record_expr.clone()));
- if !in_block_expr {
- add_keyword("unsafe", "unsafe {\n $0\n}");
- }
- add_keyword("match", "match $1 {\n $0\n}");
- add_keyword("while", "while $1 {\n $0\n}");
- add_keyword("while let", "while let $1 = $2 {\n $0\n}");
- add_keyword("loop", "loop {\n $0\n}");
- if in_match_guard {
- add_keyword("if", "if $0");
- } else {
- add_keyword("if", "if $1 {\n $0\n}");
+ match ty.as_ref().and_then(|t| t.original.as_adt()) {
+ Some(hir::Adt::Union(_)) => (),
+ _ => {
+ cov_mark::hit!(functional_update);
+ let missing_fields =
+ ctx.sema.record_literal_missing_fields(record_expr);
+ if !missing_fields.is_empty() {
+ add_default_update(acc, ctx, ty);
+ }
+ }
+ };
}
- add_keyword("if let", "if let $1 = $2 {\n $0\n}");
- add_keyword("for", "for $1 in $2 {\n $0\n}");
- add_keyword("true", "true");
- add_keyword("false", "false");
+ None => {
+ let mut add_keyword = |kw, snippet| {
+ acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet)
+ };
- if in_condition || in_block_expr {
- add_keyword("let", "let");
- }
+ if !in_block_expr {
+ add_keyword("unsafe", "unsafe {\n $0\n}");
+ }
+ add_keyword("match", "match $1 {\n $0\n}");
+ add_keyword("while", "while $1 {\n $0\n}");
+ add_keyword("while let", "while let $1 = $2 {\n $0\n}");
+ add_keyword("loop", "loop {\n $0\n}");
+ if in_match_guard {
+ add_keyword("if", "if $0");
+ } else {
+ add_keyword("if", "if $1 {\n $0\n}");
+ }
+ add_keyword("if let", "if let $1 = $2 {\n $0\n}");
+ add_keyword("for", "for $1 in $2 {\n $0\n}");
+ add_keyword("true", "true");
+ add_keyword("false", "false");
- if after_if_expr {
- add_keyword("else", "else {\n $0\n}");
- add_keyword("else if", "else if $1 {\n $0\n}");
- }
+ if in_condition || in_block_expr {
+ add_keyword("let", "let");
+ }
- if wants_mut_token {
- add_keyword("mut", "mut ");
- }
+ if after_if_expr {
+ add_keyword("else", "else {\n $0\n}");
+ add_keyword("else if", "else if $1 {\n $0\n}");
+ }
- if in_loop_body {
- if in_block_expr {
- add_keyword("continue", "continue;");
- add_keyword("break", "break;");
- } else {
- add_keyword("continue", "continue");
- add_keyword("break", "break");
+ if wants_mut_token {
+ add_keyword("mut", "mut ");
+ }
+
+ if in_loop_body {
+ if in_block_expr {
+ add_keyword("continue", "continue;");
+ add_keyword("break", "break;");
+ } else {
+ add_keyword("continue", "continue");
+ add_keyword("break", "break");
+ }
}
- }
- if let Some(ty) = innermost_ret_ty {
- add_keyword(
- "return",
- match (in_block_expr, ty.is_unit()) {
- (true, true) => "return ;",
- (true, false) => "return;",
- (false, true) => "return $0",
- (false, false) => "return",
- },
- );
+ if let Some(ret_ty) = innermost_ret_ty {
+ add_keyword(
+ "return",
+ match (ret_ty.is_unit(), in_block_expr) {
+ (true, true) => {
+ cov_mark::hit!(return_unit_block);
+ "return;"
+ }
+ (true, false) => {
+ cov_mark::hit!(return_unit_no_block);
+ "return"
+ }
+ (false, true) => {
+ cov_mark::hit!(return_value_block);
+ "return $0;"
+ }
+ (false, false) => {
+ cov_mark::hit!(return_value_no_block);
+ "return $0"
+ }
+ },
+ );
+ }
}
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
index e9256803c..785db6fde 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -233,7 +233,8 @@ fn add_type_alias_impl(
type_alias: hir::TypeAlias,
) {
let alias_name = type_alias.name(ctx.db);
- let (alias_name, escaped_name) = (alias_name.to_smol_str(), alias_name.escaped().to_smol_str());
+ let (alias_name, escaped_name) =
+ (alias_name.unescaped().to_smol_str(), alias_name.to_smol_str());
let label = format!("type {} =", alias_name);
let replacement = format!("type {} = ", escaped_name);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
index 3989a451b..1d03c8cc5 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
@@ -75,16 +75,17 @@ impl Future for A {}
fn foo(a: A) { a.$0 }
"#,
expect![[r#"
- kw await expr.await
- sn box Box::new(expr)
- sn call function(expr)
- sn dbg dbg!(expr)
- sn dbgr dbg!(&expr)
- sn let let
- sn letm let mut
- sn match match expr {}
- sn ref &expr
- sn refm &mut expr
+ kw await expr.await
+ me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
+ sn box Box::new(expr)
+ sn call function(expr)
+ sn dbg dbg!(expr)
+ sn dbgr dbg!(&expr)
+ sn let let
+ sn letm let mut
+ sn match match expr {}
+ sn ref &expr
+ sn refm &mut expr
"#]],
);
@@ -98,18 +99,45 @@ fn foo() {
}
"#,
expect![[r#"
- kw await expr.await
- sn box Box::new(expr)
- sn call function(expr)
- sn dbg dbg!(expr)
- sn dbgr dbg!(&expr)
- sn let let
- sn letm let mut
- sn match match expr {}
- sn ref &expr
- sn refm &mut expr
+ kw await expr.await
+ me into_future() (use core::future::IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
+ sn box Box::new(expr)
+ sn call function(expr)
+ sn dbg dbg!(expr)
+ sn dbgr dbg!(&expr)
+ sn let let
+ sn letm let mut
+ sn match match expr {}
+ sn ref &expr
+ sn refm &mut expr
"#]],
- )
+ );
+ }
+
+ #[test]
+ fn test_completion_await_impls_into_future() {
+ check(
+ r#"
+//- minicore: future
+use core::future::*;
+struct A {}
+impl IntoFuture for A {}
+fn foo(a: A) { a.$0 }
+"#,
+ expect![[r#"
+ kw await expr.await
+ me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
+ sn box Box::new(expr)
+ sn call function(expr)
+ sn dbg dbg!(expr)
+ sn dbgr dbg!(&expr)
+ sn let let
+ sn letm let mut
+ sn match match expr {}
+ sn ref &expr
+ sn refm &mut expr
+ "#]],
+ );
}
#[test]
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs
index 9c975b929..950731eb4 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs
@@ -53,6 +53,7 @@ pub(crate) fn complete_mod(
let existing_mod_declarations = current_module
.children(ctx.db)
.filter_map(|module| Some(module.name(ctx.db)?.to_string()))
+ .filter(|module| module != ctx.original_token.text())
.collect::<FxHashSet<_>>();
let module_declaration_file =
@@ -351,4 +352,23 @@ fn ignored_bar() {}
"#]],
);
}
+
+ #[test]
+ fn semi_colon_completion() {
+ check(
+ r#"
+//- /lib.rs
+mod foo;
+//- /foo.rs
+mod bar {
+ mod baz$0
+}
+//- /foo/bar/baz.rs
+fn baz() {}
+"#,
+ expect![[r#"
+ md baz;
+ "#]],
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs
index 6b94347e0..b273a4cb5 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix/format_like.rs
@@ -173,7 +173,7 @@ impl FormatStrParser {
}
}
(State::Expr, ':') if chars.peek().copied() == Some(':') => {
- // path seperator
+ // path separator
current_expr.push_str("::");
chars.next();
}
@@ -185,7 +185,7 @@ impl FormatStrParser {
current_expr = String::new();
self.state = State::FormatOpts;
} else {
- // We're inside of braced expression, assume that it's a struct field name/value delimeter.
+ // We're inside of braced expression, assume that it's a struct field name/value delimiter.
current_expr.push(chr);
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs
index 1c9042390..5d96fbd30 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs
@@ -3,7 +3,7 @@ use ide_db::SymbolKind;
use syntax::ast::{self, Expr};
use crate::{
- context::{DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, PatternContext, Qualified},
+ context::{DotAccess, DotAccessKind, PatternContext},
CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
CompletionRelevancePostfixMatch, Completions,
};
@@ -14,7 +14,24 @@ pub(crate) fn complete_record_pattern_fields(
pattern_ctx: &PatternContext,
) {
if let PatternContext { record_pat: Some(record_pat), .. } = pattern_ctx {
- complete_fields(acc, ctx, ctx.sema.record_pattern_missing_fields(record_pat));
+ let ty = ctx.sema.type_of_pat(&ast::Pat::RecordPat(record_pat.clone()));
+ let missing_fields = match ty.as_ref().and_then(|t| t.original.as_adt()) {
+ Some(hir::Adt::Union(un)) => {
+ // ctx.sema.record_pat_missing_fields will always return
+ // an empty Vec on a union literal. This is normally
+ // reasonable, but here we'd like to present the full list
+ // of fields if the literal is empty.
+ let were_fields_specified =
+ record_pat.record_pat_field_list().and_then(|fl| fl.fields().next()).is_some();
+
+ match were_fields_specified {
+ false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
+ true => return,
+ }
+ }
+ _ => ctx.sema.record_pattern_missing_fields(record_pat),
+ };
+ complete_fields(acc, ctx, missing_fields);
}
}
@@ -42,8 +59,13 @@ pub(crate) fn complete_record_expr_fields(
}
_ => {
let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
- add_default_update(acc, ctx, ty, &missing_fields);
+
+ if !missing_fields.is_empty() {
+ cov_mark::hit!(functional_update_field);
+ add_default_update(acc, ctx, ty);
+ }
if dot_prefix {
+ cov_mark::hit!(functional_update_one_dot);
let mut item =
CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
item.insert_text(".");
@@ -56,41 +78,18 @@ pub(crate) fn complete_record_expr_fields(
complete_fields(acc, ctx, missing_fields);
}
-// FIXME: This should probably be part of complete_path_expr
-pub(crate) fn complete_record_expr_func_update(
- acc: &mut Completions,
- ctx: &CompletionContext<'_>,
- path_ctx: &PathCompletionCtx,
- expr_ctx: &ExprCtx,
-) {
- if !matches!(path_ctx.qualified, Qualified::No) {
- return;
- }
- if let ExprCtx { is_func_update: Some(record_expr), .. } = expr_ctx {
- let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
-
- match ty.as_ref().and_then(|t| t.original.as_adt()) {
- Some(hir::Adt::Union(_)) => (),
- _ => {
- let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
- add_default_update(acc, ctx, ty, &missing_fields);
- }
- };
- }
-}
-
-fn add_default_update(
+pub(crate) fn add_default_update(
acc: &mut Completions,
ctx: &CompletionContext<'_>,
ty: Option<hir::TypeInfo>,
- missing_fields: &[(hir::Field, hir::Type)],
) {
let default_trait = ctx.famous_defs().core_default_Default();
- let impl_default_trait = default_trait
+ let impls_default_trait = default_trait
.zip(ty.as_ref())
.map_or(false, |(default_trait, ty)| ty.original.impls_trait(ctx.db, default_trait, &[]));
- if impl_default_trait && !missing_fields.is_empty() {
+ if impls_default_trait {
// FIXME: This should make use of scope_def like completions so we get all the other goodies
+ // that is we should handle this like actually completing the default function
let completion_text = "..Default::default()";
let mut item = CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
let completion_text =
@@ -130,7 +129,7 @@ mod tests {
#[test]
fn literal_struct_completion_edit() {
check_edit(
- "FooDesc {…}",
+ "FooDesc{}",
r#"
struct FooDesc { pub bar: bool }
@@ -155,7 +154,7 @@ fn baz() {
#[test]
fn literal_struct_impl_self_completion() {
check_edit(
- "Self {…}",
+ "Self{}",
r#"
struct Foo {
bar: u64,
@@ -181,7 +180,7 @@ impl Foo {
);
check_edit(
- "Self(…)",
+ "Self()",
r#"
mod submod {
pub struct Foo(pub u64);
@@ -210,7 +209,7 @@ impl submod::Foo {
#[test]
fn literal_struct_completion_from_sub_modules() {
check_edit(
- "submod::Struct {…}",
+ "submod::Struct{}",
r#"
mod submod {
pub struct Struct {
@@ -239,7 +238,7 @@ fn f() -> submod::Struct {
#[test]
fn literal_struct_complexion_module() {
check_edit(
- "FooDesc {…}",
+ "FooDesc{}",
r#"
mod _69latrick {
pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index e35f79d2b..a5e854b74 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -64,8 +64,11 @@ pub(crate) struct PathCompletionCtx {
pub(super) qualified: Qualified,
/// The parent of the path we are completing.
pub(super) parent: Option<ast::Path>,
+ #[allow(dead_code)]
/// The path of which we are completing the segment
pub(super) path: ast::Path,
+ /// The path of which we are completing the segment in the original file
+ pub(crate) original_path: Option<ast::Path>,
pub(super) kind: PathKind,
/// Whether the path segment has type args or not.
pub(super) has_type_args: bool,
@@ -134,6 +137,7 @@ pub(crate) struct ExprCtx {
pub(crate) in_condition: bool,
pub(crate) incomplete_let: bool,
pub(crate) ref_expr_parent: Option<ast::RefExpr>,
+ /// The surrounding RecordExpression we are completing a functional update
pub(crate) is_func_update: Option<ast::RecordExpr>,
pub(crate) self_param: Option<hir::SelfParam>,
pub(crate) innermost_ret_ty: Option<hir::Type>,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 22ec7cead..01dd9a234 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -588,12 +588,15 @@ impl<'a> CompletionContext<'a> {
};
let path = segment.parent_path();
+ let original_path = find_node_in_file_compensated(sema, original_file, &path);
+
let mut path_ctx = PathCompletionCtx {
has_call_parens: false,
has_macro_bang: false,
qualified: Qualified::No,
parent: None,
path: path.clone(),
+ original_path,
kind: PathKind::Item { kind: ItemListKind::SourceFile },
has_type_args: false,
use_tree_parent: false,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
index 946134b0f..86302cb06 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -117,7 +117,7 @@ pub(crate) fn render_field(
) -> CompletionItem {
let is_deprecated = ctx.is_deprecated(field);
let name = field.name(ctx.db());
- let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+ let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
let mut item = CompletionItem::new(
SymbolKind::Field,
ctx.source_range(),
@@ -283,8 +283,8 @@ fn render_resolution_path(
let name = local_name.to_smol_str();
let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution);
- if local_name.escaped().is_escaped() {
- item.insert_text(local_name.escaped().to_smol_str());
+ if local_name.is_escaped() {
+ item.insert_text(local_name.to_smol_str());
}
// Add `<>` for generic types
let type_path_no_ty_args = matches!(
@@ -306,7 +306,7 @@ fn render_resolution_path(
item.lookup_by(name.clone())
.label(SmolStr::from_iter([&name, "<…>"]))
.trigger_call_info()
- .insert_snippet(cap, format!("{}<$0>", local_name.escaped()));
+ .insert_snippet(cap, format!("{}<$0>", local_name));
}
}
}
@@ -323,9 +323,7 @@ fn render_resolution_path(
..CompletionRelevance::default()
});
- if let Some(ref_match) = compute_ref_match(completion, &ty) {
- item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
- }
+ path_ref_match(completion, path_ctx, &ty, &mut item);
};
item
}
@@ -342,7 +340,8 @@ fn render_resolution_simple_(
let ctx = ctx.import_to_add(import_to_add);
let kind = res_to_kind(resolution);
- let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str());
+ let mut item =
+ CompletionItem::new(kind, ctx.source_range(), local_name.unescaped().to_smol_str());
item.set_relevance(ctx.completion_relevance())
.set_documentation(scope_def_docs(db, resolution))
.set_deprecated(scope_def_is_deprecated(&ctx, resolution));
@@ -452,6 +451,29 @@ fn compute_ref_match(
None
}
+fn path_ref_match(
+ completion: &CompletionContext<'_>,
+ path_ctx: &PathCompletionCtx,
+ ty: &hir::Type,
+ item: &mut Builder,
+) {
+ if let Some(original_path) = &path_ctx.original_path {
+ // At least one char was typed by the user already, in that case look for the original path
+ if let Some(original_path) = completion.sema.original_ast_node(original_path.clone()) {
+ if let Some(ref_match) = compute_ref_match(completion, ty) {
+ item.ref_match(ref_match, original_path.syntax().text_range().start());
+ }
+ }
+ } else {
+ // completion requested on an empty identifier, there is no path here yet.
+ // FIXME: This might create inconsistent completions where we show a ref match in macro inputs
+ // as long as nothing was typed yet
+ if let Some(ref_match) = compute_ref_match(completion, ty) {
+ item.ref_match(ref_match, completion.position.offset);
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use std::cmp;
@@ -564,6 +586,7 @@ fn main() { Foo::Fo$0 }
kind: SymbolKind(
Variant,
),
+ lookup: "Foo{}",
detail: "Foo { x: i32, y: i32 }",
},
]
@@ -590,6 +613,7 @@ fn main() { Foo::Fo$0 }
kind: SymbolKind(
Variant,
),
+ lookup: "Foo()",
detail: "Foo(i32, i32)",
},
]
@@ -706,7 +730,7 @@ fn main() { let _: m::Spam = S$0 }
kind: SymbolKind(
Variant,
),
- lookup: "Spam::Bar(…)",
+ lookup: "Spam::Bar()",
detail: "m::Spam::Bar(i32)",
relevance: CompletionRelevance {
exact_name_match: false,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
index a810eef18..93ea825e0 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
@@ -13,7 +13,7 @@ pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option
fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
let db = ctx.db();
let name = const_.name(db)?;
- let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+ let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
let detail = const_.display(db).to_string();
let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name.clone());
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
index 4b5535718..376120846 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
@@ -52,10 +52,10 @@ fn render(
let (call, escaped_call) = match &func_kind {
FuncKind::Method(_, Some(receiver)) => (
- format!("{}.{}", receiver, &name).into(),
- format!("{}.{}", receiver.escaped(), name.escaped()).into(),
+ format!("{}.{}", receiver.unescaped(), name.unescaped()).into(),
+ format!("{}.{}", receiver, name).into(),
),
- _ => (name.to_smol_str(), name.escaped().to_smol_str()),
+ _ => (name.unescaped().to_smol_str(), name.to_smol_str()),
};
let mut item = CompletionItem::new(
if func.self_param(db).is_some() {
@@ -79,24 +79,24 @@ fn render(
..ctx.completion_relevance()
});
- if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
- match func_kind {
- FuncKind::Function(path_ctx) => {
- item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
- }
- FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
- if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
+ match func_kind {
+ FuncKind::Function(path_ctx) => {
+ super::path_ref_match(completion, path_ctx, &ret_type, &mut item);
+ }
+ FuncKind::Method(DotAccess { receiver: Some(receiver), .. }, _) => {
+ if let Some(original_expr) = completion.sema.original_ast_node(receiver.clone()) {
+ if let Some(ref_match) = compute_ref_match(completion, &ret_type) {
item.ref_match(ref_match, original_expr.syntax().text_range().start());
}
}
- _ => (),
}
+ _ => (),
}
item.set_documentation(ctx.docs(func))
.set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func))
.detail(detail(db, func))
- .lookup_by(name.to_smol_str());
+ .lookup_by(name.unescaped().to_smol_str());
match ctx.completion.config.snippet_cap {
Some(cap) => {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
index 91a253f8f..0c791ac57 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
@@ -2,16 +2,15 @@
use hir::{db::HirDatabase, Documentation, HasAttrs, StructKind};
use ide_db::SymbolKind;
-use syntax::AstNode;
use crate::{
context::{CompletionContext, PathCompletionCtx, PathKind},
item::{Builder, CompletionItem},
render::{
- compute_ref_match, compute_type_match,
+ compute_type_match,
variant::{
- format_literal_label, render_record_lit, render_tuple_lit, visible_fields,
- RenderedLiteral,
+ format_literal_label, format_literal_lookup, render_record_lit, render_tuple_lit,
+ visible_fields, RenderedLiteral,
},
RenderContext,
},
@@ -73,7 +72,7 @@ fn render(
None => (name.clone().into(), name.into(), false),
};
let (qualified_name, escaped_qualified_name) =
- (qualified_name.to_string(), qualified_name.escaped().to_string());
+ (qualified_name.unescaped().to_string(), qualified_name.to_string());
let snippet_cap = ctx.snippet_cap();
let mut rendered = match kind {
@@ -97,13 +96,20 @@ fn render(
if !should_add_parens {
kind = StructKind::Unit;
}
+ let label = format_literal_label(&qualified_name, kind);
+ let lookup = if qualified {
+ format_literal_lookup(&short_qualified_name.to_string(), kind)
+ } else {
+ format_literal_lookup(&qualified_name, kind)
+ };
let mut item = CompletionItem::new(
CompletionItemKind::SymbolKind(thing.symbol_kind()),
ctx.source_range(),
- format_literal_label(&qualified_name, kind),
+ label,
);
+ item.lookup_by(lookup);
item.detail(rendered.detail);
match snippet_cap {
@@ -111,9 +117,6 @@ fn render(
None => item.insert_text(rendered.literal),
};
- if qualified {
- item.lookup_by(format_literal_label(&short_qualified_name.to_string(), kind));
- }
item.set_documentation(thing.docs(db)).set_deprecated(thing.is_deprecated(&ctx));
let ty = thing.ty(db);
@@ -121,9 +124,8 @@ fn render(
type_match: compute_type_match(ctx.completion, &ty),
..ctx.completion_relevance()
});
- if let Some(ref_match) = compute_ref_match(completion, &ty) {
- item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
- }
+
+ super::path_ref_match(completion, path_ctx, &ty, &mut item);
if let Some(import_to_add) = ctx.import_to_add {
item.add_import(import_to_add);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
index ca2269f13..eabd0bd17 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
@@ -46,7 +46,7 @@ fn render(
ctx.source_range()
};
- let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+ let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
let docs = ctx.docs(macro_);
let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default();
let is_fn_like = macro_.is_fn_like(completion.db);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
index 34a384f2f..c845ff21a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
@@ -8,7 +8,7 @@ use syntax::SmolStr;
use crate::{
context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext},
render::{
- variant::{format_literal_label, visible_fields},
+ variant::{format_literal_label, format_literal_lookup, visible_fields},
RenderContext,
},
CompletionItem, CompletionItemKind,
@@ -31,12 +31,13 @@ pub(crate) fn render_struct_pat(
}
let name = local_name.unwrap_or_else(|| strukt.name(ctx.db()));
- let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+ let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
let kind = strukt.kind(ctx.db());
let label = format_literal_label(name.as_str(), kind);
+ let lookup = format_literal_lookup(name.as_str(), kind);
let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?;
- Some(build_completion(ctx, label, pat, strukt))
+ Some(build_completion(ctx, label, lookup, pat, strukt))
}
pub(crate) fn render_variant_pat(
@@ -53,18 +54,21 @@ pub(crate) fn render_variant_pat(
let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?;
let (name, escaped_name) = match path {
- Some(path) => (path.to_string().into(), path.escaped().to_string().into()),
+ Some(path) => (path.unescaped().to_string().into(), path.to_string().into()),
None => {
let name = local_name.unwrap_or_else(|| variant.name(ctx.db()));
- (name.to_smol_str(), name.escaped().to_smol_str())
+ (name.unescaped().to_smol_str(), name.to_smol_str())
}
};
- let (label, pat) = match path_ctx {
- Some(PathCompletionCtx { has_call_parens: true, .. }) => (name, escaped_name.to_string()),
+ let (label, lookup, pat) = match path_ctx {
+ Some(PathCompletionCtx { has_call_parens: true, .. }) => {
+ (name.clone(), name, escaped_name.to_string())
+ }
_ => {
let kind = variant.kind(ctx.db());
let label = format_literal_label(name.as_str(), kind);
+ let lookup = format_literal_lookup(name.as_str(), kind);
let pat = render_pat(
&ctx,
pattern_ctx,
@@ -73,16 +77,17 @@ pub(crate) fn render_variant_pat(
&visible_fields,
fields_omitted,
)?;
- (label, pat)
+ (label, lookup, pat)
}
};
- Some(build_completion(ctx, label, pat, variant))
+ Some(build_completion(ctx, label, lookup, pat, variant))
}
fn build_completion(
ctx: RenderContext<'_>,
label: SmolStr,
+ lookup: SmolStr,
pat: String,
def: impl HasAttrs + Copy,
) -> CompletionItem {
@@ -90,6 +95,7 @@ fn build_completion(
item.set_documentation(ctx.docs(def))
.set_deprecated(ctx.is_deprecated(def))
.detail(&pat)
+ .lookup_by(lookup)
.set_relevance(ctx.completion_relevance());
match ctx.snippet_cap() {
Some(snippet_cap) => item.insert_snippet(snippet_cap, pat),
@@ -146,7 +152,7 @@ fn render_record_as_pat(
format!(
"{name} {{ {}{} }}",
fields.enumerate().format_with(", ", |(idx, field), f| {
- f(&format_args!("{}${}", field.name(db).escaped(), idx + 1))
+ f(&format_args!("{}${}", field.name(db), idx + 1))
}),
if fields_omitted { ", .." } else { "" },
name = name
@@ -155,7 +161,7 @@ fn render_record_as_pat(
None => {
format!(
"{name} {{ {}{} }}",
- fields.map(|field| field.name(db).escaped().to_smol_str()).format(", "),
+ fields.map(|field| field.name(db).to_smol_str()).format(", "),
if fields_omitted { ", .." } else { "" },
name = name
)
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
index f1b23c76e..de919429f 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
@@ -32,11 +32,11 @@ fn render(
let name = type_alias.name(db);
let (name, escaped_name) = if with_eq {
(
+ SmolStr::from_iter([&name.unescaped().to_smol_str(), " = "]),
SmolStr::from_iter([&name.to_smol_str(), " = "]),
- SmolStr::from_iter([&name.escaped().to_smol_str(), " = "]),
)
} else {
- (name.to_smol_str(), name.escaped().to_smol_str())
+ (name.unescaped().to_smol_str(), name.to_smol_str())
};
let detail = type_alias.display(db).to_string();
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs
index 9c9540a9b..54e97dd57 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs
@@ -6,7 +6,7 @@ use itertools::Itertools;
use crate::{
render::{
- variant::{format_literal_label, visible_fields},
+ variant::{format_literal_label, format_literal_lookup, visible_fields},
RenderContext,
},
CompletionItem, CompletionItemKind,
@@ -21,16 +21,19 @@ pub(crate) fn render_union_literal(
let name = local_name.unwrap_or_else(|| un.name(ctx.db()));
let (qualified_name, escaped_qualified_name) = match path {
- Some(p) => (p.to_string(), p.escaped().to_string()),
- None => (name.to_string(), name.escaped().to_string()),
+ Some(p) => (p.unescaped().to_string(), p.to_string()),
+ None => (name.unescaped().to_string(), name.to_string()),
};
-
+ let label = format_literal_label(&name.to_smol_str(), StructKind::Record);
+ let lookup = format_literal_lookup(&name.to_smol_str(), StructKind::Record);
let mut item = CompletionItem::new(
CompletionItemKind::SymbolKind(SymbolKind::Union),
ctx.source_range(),
- format_literal_label(&name.to_smol_str(), StructKind::Record),
+ label,
);
+ item.lookup_by(lookup);
+
let fields = un.fields(ctx.db());
let (fields, fields_omitted) = visible_fields(ctx.completion, &fields, un)?;
@@ -42,15 +45,15 @@ pub(crate) fn render_union_literal(
format!(
"{} {{ ${{1|{}|}}: ${{2:()}} }}$0",
escaped_qualified_name,
- fields.iter().map(|field| field.name(ctx.db()).escaped().to_smol_str()).format(",")
+ fields.iter().map(|field| field.name(ctx.db()).to_smol_str()).format(",")
)
} else {
format!(
"{} {{ {} }}",
escaped_qualified_name,
- fields.iter().format_with(", ", |field, f| {
- f(&format_args!("{}: ()", field.name(ctx.db()).escaped()))
- })
+ fields
+ .iter()
+ .format_with(", ", |field, f| { f(&format_args!("{}: ()", field.name(ctx.db()))) })
)
};
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs
index 003a0c11e..24e6abdc9 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs
@@ -24,9 +24,9 @@ pub(crate) fn render_record_lit(
) -> RenderedLiteral {
let completions = fields.iter().enumerate().format_with(", ", |(idx, field), f| {
if snippet_cap.is_some() {
- f(&format_args!("{}: ${{{}:()}}", field.name(db).escaped(), idx + 1))
+ f(&format_args!("{}: ${{{}:()}}", field.name(db), idx + 1))
} else {
- f(&format_args!("{}: ()", field.name(db).escaped()))
+ f(&format_args!("{}: ()", field.name(db)))
}
});
@@ -94,3 +94,12 @@ pub(crate) fn format_literal_label(name: &str, kind: StructKind) -> SmolStr {
StructKind::Unit => name.into(),
}
}
+
+/// Format a struct, etc. literal option for lookup used in completions filtering.
+pub(crate) fn format_literal_lookup(name: &str, kind: StructKind) -> SmolStr {
+ match kind {
+ StructKind::Tuple => SmolStr::from_iter([name, "()"]),
+ StructKind::Record => SmolStr::from_iter([name, "{}"]),
+ StructKind::Unit => name.into(),
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
index 925081ebf..8e26d889f 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
@@ -1,7 +1,7 @@
//! Completion tests for expressions.
use expect_test::{expect, Expect};
-use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
+use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE};
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(&format!("{}{}", BASE_ITEMS_FIXTURE, ra_fixture));
@@ -670,3 +670,78 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn varaiant_with_struct() {
+ check_empty(
+ r#"
+pub struct YoloVariant {
+ pub f: usize
+}
+
+pub enum HH {
+ Yolo(YoloVariant),
+}
+
+fn brr() {
+ let t = HH::Yolo(Y$0);
+}
+"#,
+ expect![[r#"
+ en HH
+ fn brr() fn()
+ st YoloVariant
+ st YoloVariant {…} YoloVariant { f: usize }
+ bt u32
+ kw crate::
+ kw false
+ kw for
+ kw if
+ kw if let
+ kw loop
+ kw match
+ kw return
+ kw self::
+ kw true
+ kw unsafe
+ kw while
+ kw while let
+ "#]],
+ );
+}
+
+#[test]
+fn return_unit_block() {
+ cov_mark::check!(return_unit_block);
+ check_edit("return", r#"fn f() { if true { $0 } }"#, r#"fn f() { if true { return; } }"#);
+}
+
+#[test]
+fn return_unit_no_block() {
+ cov_mark::check!(return_unit_no_block);
+ check_edit(
+ "return",
+ r#"fn f() { match () { () => $0 } }"#,
+ r#"fn f() { match () { () => return } }"#,
+ );
+}
+
+#[test]
+fn return_value_block() {
+ cov_mark::check!(return_value_block);
+ check_edit(
+ "return",
+ r#"fn f() -> i32 { if true { $0 } }"#,
+ r#"fn f() -> i32 { if true { return $0; } }"#,
+ );
+}
+
+#[test]
+fn return_value_no_block() {
+ cov_mark::check!(return_value_no_block);
+ check_edit(
+ "return",
+ r#"fn f() -> i32 { match () { () => $0 } }"#,
+ r#"fn f() -> i32 { match () { () => return $0 } }"#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
index 0bba7f245..a63ef0068 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
@@ -159,7 +159,7 @@ pub mod some_module {
pub struct ThiiiiiirdStruct;
// contains all letters from the query, but not in the beginning, displayed second
pub struct AfterThirdStruct;
- // contains all letters from the query in the begginning, displayed first
+ // contains all letters from the query in the beginning, displayed first
pub struct ThirdStruct;
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs
index 30ddbe2dc..85c4dbd66 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs
@@ -467,7 +467,7 @@ fn foo() {
fn completes_enum_variant_pat() {
cov_mark::check!(enum_variant_pattern_path);
check_edit(
- "RecordVariant {…}",
+ "RecordVariant{}",
r#"
enum Enum {
RecordVariant { field: u32 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs
index f6accc68e..328faaa06 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs
@@ -103,8 +103,9 @@ fn foo(f: Struct) {
}
#[test]
-fn functional_update() {
- // FIXME: This should filter out all completions that do not have the type `Foo`
+fn in_functional_update() {
+ cov_mark::check!(functional_update);
+
check(
r#"
//- minicore:default
@@ -116,13 +117,21 @@ impl Default for Foo {
fn main() {
let thing = 1;
let foo = Foo { foo1: 0, foo2: 0 };
- let foo2 = Foo { thing, $0 }
+ let foo2 = Foo { thing, ..$0 }
}
"#,
expect![[r#"
fd ..Default::default()
- fd foo1 u32
- fd foo2 u32
+ fn main() fn()
+ lc foo Foo
+ lc thing i32
+ md core
+ st Foo
+ st Foo {…} Foo { foo1: u32, foo2: u32 }
+ tt Default
+ bt u32
+ kw crate::
+ kw self::
"#]],
);
check(
@@ -136,14 +145,19 @@ impl Default for Foo {
fn main() {
let thing = 1;
let foo = Foo { foo1: 0, foo2: 0 };
- let foo2 = Foo { thing, .$0 }
+ let foo2 = Foo { thing, ..Default::$0 }
}
"#,
expect![[r#"
- fd ..Default::default()
- sn ..
+ fn default() (as Default) fn() -> Self
"#]],
);
+}
+
+#[test]
+fn functional_update_no_dot() {
+ cov_mark::check!(functional_update_field);
+ // FIXME: This should filter out all completions that do not have the type `Foo`
check(
r#"
//- minicore:default
@@ -155,23 +169,20 @@ impl Default for Foo {
fn main() {
let thing = 1;
let foo = Foo { foo1: 0, foo2: 0 };
- let foo2 = Foo { thing, ..$0 }
+ let foo2 = Foo { thing, $0 }
}
"#,
expect![[r#"
fd ..Default::default()
- fn main() fn()
- lc foo Foo
- lc thing i32
- md core
- st Foo
- st Foo {…} Foo { foo1: u32, foo2: u32 }
- tt Default
- bt u32
- kw crate::
- kw self::
+ fd foo1 u32
+ fd foo2 u32
"#]],
);
+}
+
+#[test]
+fn functional_update_one_dot() {
+ cov_mark::check!(functional_update_one_dot);
check(
r#"
//- minicore:default
@@ -183,11 +194,12 @@ impl Default for Foo {
fn main() {
let thing = 1;
let foo = Foo { foo1: 0, foo2: 0 };
- let foo2 = Foo { thing, ..Default::$0 }
+ let foo2 = Foo { thing, .$0 }
}
"#,
expect![[r#"
- fn default() (as Default) fn() -> Self
+ fd ..Default::default()
+ sn ..
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs
index 7303ef8b7..7109c6fd1 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs
@@ -12,7 +12,7 @@ use crate::RootDatabase;
#[derive(Debug)]
pub struct ActiveParameter {
pub ty: Type,
- pub pat: Either<ast::SelfParam, ast::Pat>,
+ pub pat: Option<Either<ast::SelfParam, ast::Pat>>,
}
impl ActiveParameter {
@@ -27,12 +27,12 @@ impl ActiveParameter {
return None;
}
let (pat, ty) = params.swap_remove(idx);
- pat.map(|pat| ActiveParameter { ty, pat })
+ Some(ActiveParameter { ty, pat })
}
pub fn ident(&self) -> Option<ast::Name> {
- self.pat.as_ref().right().and_then(|param| match param {
- ast::Pat::IdentPat(ident) => ident.name(),
+ self.pat.as_ref().and_then(|param| match param {
+ Either::Right(ast::Pat::IdentPat(ident)) => ident.name(),
_ => None,
})
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
index 98b0e9c94..b1ee9b58d 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
@@ -20,7 +20,7 @@ impl RootDatabase {
pub fn apply_change(&mut self, change: Change) {
let _p = profile::span("RootDatabase::apply_change");
self.request_cancellation();
- tracing::info!("apply_change {:?}", change);
+ tracing::trace!("apply_change {:?}", change);
if let Some(roots) = &change.roots {
let mut local_roots = FxHashSet::default();
let mut library_roots = FxHashSet::default();
@@ -45,7 +45,7 @@ impl RootDatabase {
// |===
// | Editor | Action Name
//
- // | VS Code | **Rust Analyzer: Memory Usage (Clears Database)**
+ // | VS Code | **rust-analyzer: Memory Usage (Clears Database)**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif[]
pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
index aeaca00ec..6c13c0397 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -127,10 +127,12 @@ impl Definition {
}
}
+// FIXME: IdentClass as a name no longer fits
#[derive(Debug)]
pub enum IdentClass {
NameClass(NameClass),
NameRefClass(NameRefClass),
+ Operator(OperatorClass),
}
impl IdentClass {
@@ -147,6 +149,11 @@ impl IdentClass {
.map(IdentClass::NameClass)
.or_else(|| NameRefClass::classify_lifetime(sema, &lifetime).map(IdentClass::NameRefClass))
},
+ ast::AwaitExpr(await_expr) => OperatorClass::classify_await(sema, &await_expr).map(IdentClass::Operator),
+ ast::BinExpr(bin_expr) => OperatorClass::classify_bin(sema, &bin_expr).map(IdentClass::Operator),
+ ast::IndexExpr(index_expr) => OperatorClass::classify_index(sema, &index_expr).map(IdentClass::Operator),
+ ast::PrefixExpr(prefix_expr) => OperatorClass::classify_prefix(sema,&prefix_expr).map(IdentClass::Operator),
+ ast::TryExpr(try_expr) => OperatorClass::classify_try(sema,&try_expr).map(IdentClass::Operator),
_ => None,
}
}
@@ -184,6 +191,33 @@ impl IdentClass {
res.push(Definition::Local(local_ref));
res.push(Definition::Field(field_ref));
}
+ IdentClass::Operator(
+ OperatorClass::Await(func)
+ | OperatorClass::Prefix(func)
+ | OperatorClass::Bin(func)
+ | OperatorClass::Index(func)
+ | OperatorClass::Try(func),
+ ) => res.push(Definition::Function(func)),
+ }
+ res
+ }
+
+ pub fn definitions_no_ops(self) -> ArrayVec<Definition, 2> {
+ let mut res = ArrayVec::new();
+ match self {
+ IdentClass::NameClass(NameClass::Definition(it) | NameClass::ConstReference(it)) => {
+ res.push(it)
+ }
+ IdentClass::NameClass(NameClass::PatFieldShorthand { local_def, field_ref }) => {
+ res.push(Definition::Local(local_def));
+ res.push(Definition::Field(field_ref));
+ }
+ IdentClass::NameRefClass(NameRefClass::Definition(it)) => res.push(it),
+ IdentClass::NameRefClass(NameRefClass::FieldShorthand { local_ref, field_ref }) => {
+ res.push(Definition::Local(local_ref));
+ res.push(Definition::Field(field_ref));
+ }
+ IdentClass::Operator(_) => (),
}
res
}
@@ -332,6 +366,52 @@ impl NameClass {
}
}
+#[derive(Debug)]
+pub enum OperatorClass {
+ Await(Function),
+ Prefix(Function),
+ Index(Function),
+ Try(Function),
+ Bin(Function),
+}
+
+impl OperatorClass {
+ pub fn classify_await(
+ sema: &Semantics<'_, RootDatabase>,
+ await_expr: &ast::AwaitExpr,
+ ) -> Option<OperatorClass> {
+ sema.resolve_await_to_poll(await_expr).map(OperatorClass::Await)
+ }
+
+ pub fn classify_prefix(
+ sema: &Semantics<'_, RootDatabase>,
+ prefix_expr: &ast::PrefixExpr,
+ ) -> Option<OperatorClass> {
+ sema.resolve_prefix_expr(prefix_expr).map(OperatorClass::Prefix)
+ }
+
+ pub fn classify_try(
+ sema: &Semantics<'_, RootDatabase>,
+ try_expr: &ast::TryExpr,
+ ) -> Option<OperatorClass> {
+ sema.resolve_try_expr(try_expr).map(OperatorClass::Try)
+ }
+
+ pub fn classify_index(
+ sema: &Semantics<'_, RootDatabase>,
+ index_expr: &ast::IndexExpr,
+ ) -> Option<OperatorClass> {
+ sema.resolve_index_expr(index_expr).map(OperatorClass::Index)
+ }
+
+ pub fn classify_bin(
+ sema: &Semantics<'_, RootDatabase>,
+ bin_expr: &ast::BinExpr,
+ ) -> Option<OperatorClass> {
+ sema.resolve_bin_expr(bin_expr).map(OperatorClass::Bin)
+ }
+}
+
/// This is similar to [`NameClass`], but works for [`ast::NameRef`] rather than
/// for [`ast::Name`]. Similarly, what looks like a reference in syntax is a
/// reference most of the time, but there are a couple of annoying exceptions.
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs
index c14182279..9be1d3663 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs
@@ -7,7 +7,10 @@ use std::cmp::Ordering;
use hir::Semantics;
use syntax::{
algo,
- ast::{self, make, AstNode, HasAttrs, HasModuleItem, HasVisibility, PathSegmentKind},
+ ast::{
+ self, edit_in_place::Removable, make, AstNode, HasAttrs, HasModuleItem, HasVisibility,
+ PathSegmentKind,
+ },
ted, Direction, NodeOrToken, SyntaxKind, SyntaxNode,
};
@@ -192,20 +195,24 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
insert_use_(scope, &path, cfg.group, use_item);
}
-pub fn remove_path_if_in_use_stmt(path: &ast::Path) {
+pub fn ast_to_remove_for_path_in_use_stmt(path: &ast::Path) -> Option<Box<dyn Removable>> {
// FIXME: improve this
if path.parent_path().is_some() {
- return;
+ return None;
}
- if let Some(use_tree) = path.syntax().parent().and_then(ast::UseTree::cast) {
- if use_tree.use_tree_list().is_some() || use_tree.star_token().is_some() {
- return;
- }
- if let Some(use_) = use_tree.syntax().parent().and_then(ast::Use::cast) {
- use_.remove();
- return;
- }
- use_tree.remove();
+ let use_tree = path.syntax().parent().and_then(ast::UseTree::cast)?;
+ if use_tree.use_tree_list().is_some() || use_tree.star_token().is_some() {
+ return None;
+ }
+ if let Some(use_) = use_tree.syntax().parent().and_then(ast::Use::cast) {
+ return Some(Box::new(use_));
+ }
+ Some(Box::new(use_tree))
+}
+
+pub fn remove_path_if_in_use_stmt(path: &ast::Path) {
+ if let Some(node) = ast_to_remove_for_path_in_use_stmt(path) {
+ node.remove();
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index 966bba616..1ec62a842 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -52,6 +52,7 @@ use hir::{
db::{AstDatabase, DefDatabase, HirDatabase},
symbols::FileSymbolKind,
};
+use stdx::hash::NoHashHashSet;
use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
@@ -118,7 +119,7 @@ impl FileLoader for RootDatabase {
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
FileLoaderDelegate(self).resolve_path(path)
}
- fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
+ fn relevant_crates(&self, file_id: FileId) -> Arc<NoHashHashSet<CrateId>> {
FileLoaderDelegate(self).relevant_crates(file_id)
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs
index 68ad07ee8..75d49ff2f 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs
@@ -2,7 +2,7 @@
//! representation.
use std::{iter, mem};
-use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
use syntax::{TextRange, TextSize};
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -10,7 +10,7 @@ pub struct LineIndex {
/// Offset the the beginning of each line, zero-based
pub(crate) newlines: Vec<TextSize>,
/// List of non-ASCII characters on each line
- pub(crate) utf16_lines: FxHashMap<u32, Vec<Utf16Char>>,
+ pub(crate) utf16_lines: NoHashHashMap<u32, Vec<Utf16Char>>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -55,7 +55,7 @@ impl Utf16Char {
impl LineIndex {
pub fn new(text: &str) -> LineIndex {
- let mut utf16_lines = FxHashMap::default();
+ let mut utf16_lines = NoHashHashMap::default();
let mut utf16_chars = Vec::new();
let mut newlines = vec![0.into()];
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
index 517fe3f24..49b81265e 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
@@ -82,7 +82,7 @@ impl Definition {
}
/// Textual range of the identifier which will change when renaming this
- /// `Definition`. Note that some definitions, like buitin types, can't be
+ /// `Definition`. Note that some definitions, like builtin types, can't be
/// renamed.
pub fn range_for_rename(self, sema: &Semantics<'_, RootDatabase>) -> Option<FileRange> {
let res = match self {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index bd038cdaa..7deffe8e0 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -4,12 +4,12 @@
//! get a super-set of matches. Then, we we confirm each match using precise
//! name resolution.
-use std::{convert::TryInto, mem, sync::Arc};
+use std::{mem, sync::Arc};
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
use once_cell::unsync::Lazy;
-use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
use crate::{
@@ -20,7 +20,7 @@ use crate::{
#[derive(Debug, Default, Clone)]
pub struct UsageSearchResult {
- pub references: FxHashMap<FileId, Vec<FileReference>>,
+ pub references: NoHashHashMap<FileId, Vec<FileReference>>,
}
impl UsageSearchResult {
@@ -45,7 +45,7 @@ impl UsageSearchResult {
impl IntoIterator for UsageSearchResult {
type Item = (FileId, Vec<FileReference>);
- type IntoIter = <FxHashMap<FileId, Vec<FileReference>> as IntoIterator>::IntoIter;
+ type IntoIter = <NoHashHashMap<FileId, Vec<FileReference>> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.references.into_iter()
@@ -78,17 +78,17 @@ pub enum ReferenceCategory {
/// e.g. for things like local variables.
#[derive(Clone, Debug)]
pub struct SearchScope {
- entries: FxHashMap<FileId, Option<TextRange>>,
+ entries: NoHashHashMap<FileId, Option<TextRange>>,
}
impl SearchScope {
- fn new(entries: FxHashMap<FileId, Option<TextRange>>) -> SearchScope {
+ fn new(entries: NoHashHashMap<FileId, Option<TextRange>>) -> SearchScope {
SearchScope { entries }
}
/// Build a search scope spanning the entire crate graph of files.
fn crate_graph(db: &RootDatabase) -> SearchScope {
- let mut entries = FxHashMap::default();
+ let mut entries = NoHashHashMap::default();
let graph = db.crate_graph();
for krate in graph.iter() {
@@ -102,7 +102,7 @@ impl SearchScope {
/// Build a search scope spanning all the reverse dependencies of the given crate.
fn reverse_dependencies(db: &RootDatabase, of: hir::Crate) -> SearchScope {
- let mut entries = FxHashMap::default();
+ let mut entries = NoHashHashMap::default();
for rev_dep in of.transitive_reverse_dependencies(db) {
let root_file = rev_dep.root_file(db);
let source_root_id = db.file_source_root(root_file);
@@ -117,14 +117,12 @@ impl SearchScope {
let root_file = of.root_file(db);
let source_root_id = db.file_source_root(root_file);
let source_root = db.source_root(source_root_id);
- SearchScope {
- entries: source_root.iter().map(|id| (id, None)).collect::<FxHashMap<_, _>>(),
- }
+ SearchScope { entries: source_root.iter().map(|id| (id, None)).collect() }
}
/// Build a search scope spanning the given module and all its submodules.
fn module_and_children(db: &RootDatabase, module: hir::Module) -> SearchScope {
- let mut entries = FxHashMap::default();
+ let mut entries = NoHashHashMap::default();
let (file_id, range) = {
let InFile { file_id, value } = module.definition_source(db);
@@ -157,7 +155,7 @@ impl SearchScope {
/// Build an empty search scope.
pub fn empty() -> SearchScope {
- SearchScope::new(FxHashMap::default())
+ SearchScope::new(NoHashHashMap::default())
}
/// Build a empty search scope spanning the given file.
@@ -402,7 +400,9 @@ impl<'a> FindUsages<'a> {
.or_else(|| ty.as_builtin().map(|builtin| builtin.name()))
})
};
- self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.to_smol_str())
+ // We need to unescape the name in case it is written without "r#" in earlier
+ // editions of Rust where it isn't a keyword.
+ self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.unescaped().to_smol_str())
}
};
let name = match &name {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
index 8132c73ef..8e338061d 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
@@ -3,16 +3,18 @@
//!
//! It can be viewed as a dual for `Change`.
-use std::{collections::hash_map::Entry, iter};
+use std::{collections::hash_map::Entry, iter, mem};
use base_db::{AnchoredPathBuf, FileId};
-use rustc_hash::FxHashMap;
-use stdx::never;
-use text_edit::TextEdit;
+use stdx::{hash::NoHashHashMap, never};
+use syntax::{algo, AstNode, SyntaxNode, SyntaxNodePtr, TextRange, TextSize};
+use text_edit::{TextEdit, TextEditBuilder};
+
+use crate::SnippetCap;
#[derive(Default, Debug, Clone)]
pub struct SourceChange {
- pub source_file_edits: FxHashMap<FileId, TextEdit>,
+ pub source_file_edits: NoHashHashMap<FileId, TextEdit>,
pub file_system_edits: Vec<FileSystemEdit>,
pub is_snippet: bool,
}
@@ -21,7 +23,7 @@ impl SourceChange {
/// Creates a new SourceChange with the given label
/// from the edits.
pub fn from_edits(
- source_file_edits: FxHashMap<FileId, TextEdit>,
+ source_file_edits: NoHashHashMap<FileId, TextEdit>,
file_system_edits: Vec<FileSystemEdit>,
) -> Self {
SourceChange { source_file_edits, file_system_edits, is_snippet: false }
@@ -75,12 +77,141 @@ impl Extend<FileSystemEdit> for SourceChange {
}
}
-impl From<FxHashMap<FileId, TextEdit>> for SourceChange {
- fn from(source_file_edits: FxHashMap<FileId, TextEdit>) -> SourceChange {
+impl From<NoHashHashMap<FileId, TextEdit>> for SourceChange {
+ fn from(source_file_edits: NoHashHashMap<FileId, TextEdit>) -> SourceChange {
SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false }
}
}
+pub struct SourceChangeBuilder {
+ pub edit: TextEditBuilder,
+ pub file_id: FileId,
+ pub source_change: SourceChange,
+ pub trigger_signature_help: bool,
+
+ /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
+ pub mutated_tree: Option<TreeMutator>,
+}
+
+pub struct TreeMutator {
+ immutable: SyntaxNode,
+ mutable_clone: SyntaxNode,
+}
+
+impl TreeMutator {
+ pub fn new(immutable: &SyntaxNode) -> TreeMutator {
+ let immutable = immutable.ancestors().last().unwrap();
+ let mutable_clone = immutable.clone_for_update();
+ TreeMutator { immutable, mutable_clone }
+ }
+
+ pub fn make_mut<N: AstNode>(&self, node: &N) -> N {
+ N::cast(self.make_syntax_mut(node.syntax())).unwrap()
+ }
+
+ pub fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
+ let ptr = SyntaxNodePtr::new(node);
+ ptr.to_node(&self.mutable_clone)
+ }
+}
+
+impl SourceChangeBuilder {
+ pub fn new(file_id: FileId) -> SourceChangeBuilder {
+ SourceChangeBuilder {
+ edit: TextEdit::builder(),
+ file_id,
+ source_change: SourceChange::default(),
+ trigger_signature_help: false,
+ mutated_tree: None,
+ }
+ }
+
+ pub fn edit_file(&mut self, file_id: FileId) {
+ self.commit();
+ self.file_id = file_id;
+ }
+
+ fn commit(&mut self) {
+ if let Some(tm) = self.mutated_tree.take() {
+ algo::diff(&tm.immutable, &tm.mutable_clone).into_text_edit(&mut self.edit)
+ }
+
+ let edit = mem::take(&mut self.edit).finish();
+ if !edit.is_empty() {
+ self.source_change.insert_source_edit(self.file_id, edit);
+ }
+ }
+
+ pub fn make_mut<N: AstNode>(&mut self, node: N) -> N {
+ self.mutated_tree.get_or_insert_with(|| TreeMutator::new(node.syntax())).make_mut(&node)
+ }
+ /// Returns a copy of the `node`, suitable for mutation.
+ ///
+ /// Syntax trees in rust-analyzer are typically immutable, and mutating
+ /// operations panic at runtime. However, it is possible to make a copy of
+ /// the tree and mutate the copy freely. Mutation is based on interior
+ /// mutability, and different nodes in the same tree see the same mutations.
+ ///
+ /// The typical pattern for an assist is to find specific nodes in the read
+ /// phase, and then get their mutable couterparts using `make_mut` in the
+ /// mutable state.
+ pub fn make_syntax_mut(&mut self, node: SyntaxNode) -> SyntaxNode {
+ self.mutated_tree.get_or_insert_with(|| TreeMutator::new(&node)).make_syntax_mut(&node)
+ }
+
+ /// Remove specified `range` of text.
+ pub fn delete(&mut self, range: TextRange) {
+ self.edit.delete(range)
+ }
+ /// Append specified `text` at the given `offset`
+ pub fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
+ self.edit.insert(offset, text.into())
+ }
+ /// Append specified `snippet` at the given `offset`
+ pub fn insert_snippet(
+ &mut self,
+ _cap: SnippetCap,
+ offset: TextSize,
+ snippet: impl Into<String>,
+ ) {
+ self.source_change.is_snippet = true;
+ self.insert(offset, snippet);
+ }
+ /// Replaces specified `range` of text with a given string.
+ pub fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
+ self.edit.replace(range, replace_with.into())
+ }
+ /// Replaces specified `range` of text with a given `snippet`.
+ pub fn replace_snippet(
+ &mut self,
+ _cap: SnippetCap,
+ range: TextRange,
+ snippet: impl Into<String>,
+ ) {
+ self.source_change.is_snippet = true;
+ self.replace(range, snippet);
+ }
+ pub fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
+ algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
+ }
+ pub fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
+ let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
+ self.source_change.push_file_system_edit(file_system_edit);
+ }
+ pub fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
+ let file_system_edit = FileSystemEdit::MoveFile { src, dst };
+ self.source_change.push_file_system_edit(file_system_edit);
+ }
+ pub fn trigger_signature_help(&mut self) {
+ self.trigger_signature_help = true;
+ }
+
+ pub fn finish(mut self) -> SourceChange {
+ self.commit();
+ mem::take(&mut self.source_change)
+ }
+}
+
#[derive(Debug, Clone)]
pub enum FileSystemEdit {
CreateFile { dst: AnchoredPathBuf, initial_contents: String },
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
index f54ae6c92..8bc093a85 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
@@ -95,7 +95,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
AS_KW | DYN_KW | IMPL_KW | CONST_KW => {
mods.push(do_ws(after, tok));
}
- T![;] => {
+ T![;] if is_next(|it| it != R_CURLY, true) => {
if indent > 0 {
mods.push(do_indent(after, tok, indent));
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
index 84bde4d44..b890e2b58 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
@@ -315,7 +315,6 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
| ast::Expr::IndexExpr(_)
| ast::Expr::Literal(_)
| ast::Expr::MacroExpr(_)
- | ast::Expr::MacroStmts(_)
| ast::Expr::MethodCallExpr(_)
| ast::Expr::ParenExpr(_)
| ast::Expr::PathExpr(_)
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
index e221425ed..9b9e21a4d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
@@ -15,6 +15,7 @@ itertools = "0.10.3"
either = "1.7.0"
+serde_json = "1.0.82"
profile = { path = "../profile", version = "0.0.0" }
stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
index d12594a4c..0c92e706b 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
@@ -7,9 +7,10 @@ pub(crate) fn break_outside_of_loop(
ctx: &DiagnosticsContext<'_>,
d: &hir::BreakOutsideOfLoop,
) -> Diagnostic {
+ let construct = if d.is_break { "break" } else { "continue" };
Diagnostic::new(
"break-outside-of-loop",
- "break outside of loop",
+ format!("{construct} outside of loop"),
ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
)
}
@@ -19,11 +20,122 @@ mod tests {
use crate::tests::check_diagnostics;
#[test]
- fn break_outside_of_loop() {
+ fn outside_of_loop() {
check_diagnostics(
r#"
-fn foo() { break; }
- //^^^^^ error: break outside of loop
+fn foo() {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn try_blocks_are_borders() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ try {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn async_blocks_are_borders() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ try {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn closures_are_borders() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ try {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn blocks_pass_through() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ {
+ break;
+ break 'a;
+ continue;
+ continue 'a;
+ }
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn label_blocks() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ }
+}
"#,
);
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs
index 97ea5c456..04918891b 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -43,7 +43,7 @@ mod tests {
use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig};
pub(crate) fn check(ra_fixture: &str) {
- let config = DiagnosticsConfig::default();
+ let config = DiagnosticsConfig::test_sample();
check_diagnostics_with_config(config, ra_fixture)
}
@@ -106,18 +106,17 @@ fn f() {
#[test]
fn inactive_assoc_item() {
- // FIXME these currently don't work, hence the *
check(
r#"
struct Foo;
impl Foo {
#[cfg(any())] pub fn f() {}
- //*************************** weak: code is inactive due to #[cfg] directives
+ //^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives
}
trait Bar {
#[cfg(any())] pub fn f() {}
- //*************************** weak: code is inactive due to #[cfg] directives
+ //^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives
}
"#,
);
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
new file mode 100644
index 000000000..a21db5b2c
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -0,0 +1,310 @@
+//! This diagnostic provides an assist for creating a struct definition from a JSON
+//! example.
+
+use hir::{PathResolution, Semantics};
+use ide_db::{
+ base_db::FileId,
+ helpers::mod_path_to_ast,
+ imports::insert_use::{insert_use, ImportScope},
+ source_change::SourceChangeBuilder,
+ RootDatabase,
+};
+use itertools::Itertools;
+use stdx::{format_to, never};
+use syntax::{
+ ast::{self, make},
+ SyntaxKind, SyntaxNode,
+};
+use text_edit::TextEdit;
+
+use crate::{fix, Diagnostic, DiagnosticsConfig, Severity};
+
+#[derive(Default)]
+struct State {
+ result: String,
+ struct_counts: usize,
+ has_serialize: bool,
+ has_deserialize: bool,
+}
+
+impl State {
+ fn generate_new_name(&mut self) -> ast::Name {
+ self.struct_counts += 1;
+ make::name(&format!("Struct{}", self.struct_counts))
+ }
+
+ fn serde_derive(&self) -> String {
+ let mut v = vec![];
+ if self.has_serialize {
+ v.push("Serialize");
+ }
+ if self.has_deserialize {
+ v.push("Deserialize");
+ }
+ match v.as_slice() {
+ [] => "".to_string(),
+ [x] => format!("#[derive({x})]\n"),
+ [x, y] => format!("#[derive({x}, {y})]\n"),
+ _ => {
+ never!();
+ "".to_string()
+ }
+ }
+ }
+
+ fn build_struct(&mut self, value: &serde_json::Map<String, serde_json::Value>) -> ast::Type {
+ let name = self.generate_new_name();
+ let ty = make::ty(&name.to_string());
+ let strukt = make::struct_(
+ None,
+ name,
+ None,
+ make::record_field_list(value.iter().sorted_unstable_by_key(|x| x.0).map(
+ |(name, value)| make::record_field(None, make::name(name), self.type_of(value)),
+ ))
+ .into(),
+ );
+ format_to!(self.result, "{}{}\n", self.serde_derive(), strukt);
+ ty
+ }
+
+ fn type_of(&mut self, value: &serde_json::Value) -> ast::Type {
+ match value {
+ serde_json::Value::Null => make::ty_unit(),
+ serde_json::Value::Bool(_) => make::ty("bool"),
+ serde_json::Value::Number(it) => make::ty(if it.is_i64() { "i64" } else { "f64" }),
+ serde_json::Value::String(_) => make::ty("String"),
+ serde_json::Value::Array(it) => {
+ let ty = match it.iter().next() {
+ Some(x) => self.type_of(x),
+ None => make::ty_placeholder(),
+ };
+ make::ty(&format!("Vec<{ty}>"))
+ }
+ serde_json::Value::Object(x) => self.build_struct(x),
+ }
+ }
+}
+
+pub(crate) fn json_in_items(
+ sema: &Semantics<'_, RootDatabase>,
+ acc: &mut Vec<Diagnostic>,
+ file_id: FileId,
+ node: &SyntaxNode,
+ config: &DiagnosticsConfig,
+) {
+ (|| {
+ if node.kind() == SyntaxKind::ERROR
+ && node.first_token().map(|x| x.kind()) == Some(SyntaxKind::L_CURLY)
+ && node.last_token().map(|x| x.kind()) == Some(SyntaxKind::R_CURLY)
+ {
+ let node_string = node.to_string();
+ if let Ok(it) = serde_json::from_str(&node_string) {
+ if let serde_json::Value::Object(it) = it {
+ let import_scope = ImportScope::find_insert_use_container(node, sema)?;
+ let range = node.text_range();
+ let mut edit = TextEdit::builder();
+ edit.delete(range);
+ let mut state = State::default();
+ let semantics_scope = sema.scope(node)?;
+ let scope_resolve =
+ |it| semantics_scope.speculative_resolve(&make::path_from_text(it));
+ let scope_has = |it| scope_resolve(it).is_some();
+ let deserialize_resolved = scope_resolve("::serde::Deserialize");
+ let serialize_resolved = scope_resolve("::serde::Serialize");
+ state.has_deserialize = deserialize_resolved.is_some();
+ state.has_serialize = serialize_resolved.is_some();
+ state.build_struct(&it);
+ edit.insert(range.start(), state.result);
+ acc.push(
+ Diagnostic::new(
+ "json-is-not-rust",
+ "JSON syntax is not valid as a Rust item",
+ range,
+ )
+ .severity(Severity::WeakWarning)
+ .with_fixes(Some(vec![{
+ let mut scb = SourceChangeBuilder::new(file_id);
+ let scope = match import_scope.clone() {
+ ImportScope::File(it) => ImportScope::File(scb.make_mut(it)),
+ ImportScope::Module(it) => ImportScope::Module(scb.make_mut(it)),
+ ImportScope::Block(it) => ImportScope::Block(scb.make_mut(it)),
+ };
+ let current_module = semantics_scope.module();
+ if !scope_has("Serialize") {
+ if let Some(PathResolution::Def(it)) = serialize_resolved {
+ if let Some(it) = current_module.find_use_path_prefixed(
+ sema.db,
+ it,
+ config.insert_use.prefix_kind,
+ ) {
+ insert_use(
+ &scope,
+ mod_path_to_ast(&it),
+ &config.insert_use,
+ );
+ }
+ }
+ }
+ if !scope_has("Deserialize") {
+ if let Some(PathResolution::Def(it)) = deserialize_resolved {
+ if let Some(it) = current_module.find_use_path_prefixed(
+ sema.db,
+ it,
+ config.insert_use.prefix_kind,
+ ) {
+ insert_use(
+ &scope,
+ mod_path_to_ast(&it),
+ &config.insert_use,
+ );
+ }
+ }
+ }
+ let mut sc = scb.finish();
+ sc.insert_source_edit(file_id, edit.finish());
+ fix("convert_json_to_struct", "Convert JSON to struct", sc, range)
+ }])),
+ );
+ }
+ }
+ }
+ Some(())
+ })();
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{
+ tests::{check_diagnostics_with_config, check_fix, check_no_fix},
+ DiagnosticsConfig,
+ };
+
+ #[test]
+ fn diagnostic_for_simple_case() {
+ let mut config = DiagnosticsConfig::test_sample();
+ config.disabled.insert("syntax-error".to_string());
+ check_diagnostics_with_config(
+ config,
+ r#"
+ { "foo": "bar" }
+ // ^^^^^^^^^^^^^^^^ 💡 weak: JSON syntax is not valid as a Rust item
+"#,
+ );
+ }
+
+ #[test]
+ fn types_of_primitives() {
+ check_fix(
+ r#"
+ //- /lib.rs crate:lib deps:serde
+ use serde::Serialize;
+
+ fn some_garbage() {
+
+ }
+
+ {$0
+ "foo": "bar",
+ "bar": 2.3,
+ "baz": null,
+ "bay": 57,
+ "box": true
+ }
+ //- /serde.rs crate:serde
+
+ pub trait Serialize {
+ fn serialize() -> u8;
+ }
+ "#,
+ r#"
+ use serde::Serialize;
+
+ fn some_garbage() {
+
+ }
+
+ #[derive(Serialize)]
+ struct Struct1{ bar: f64, bay: i64, baz: (), r#box: bool, foo: String }
+
+ "#,
+ );
+ }
+
+ #[test]
+ fn nested_structs() {
+ check_fix(
+ r#"
+ {$0
+ "foo": "bar",
+ "bar": {
+ "kind": "Object",
+ "value": {}
+ }
+ }
+ "#,
+ r#"
+ struct Struct3{ }
+ struct Struct2{ kind: String, value: Struct3 }
+ struct Struct1{ bar: Struct2, foo: String }
+
+ "#,
+ );
+ }
+
+ #[test]
+ fn arrays() {
+ check_fix(
+ r#"
+ //- /lib.rs crate:lib deps:serde
+ {
+ "of_string": ["foo", "2", "x"], $0
+ "of_object": [{
+ "x": 10,
+ "y": 20
+ }, {
+ "x": 10,
+ "y": 20
+ }],
+ "nested": [[[2]]],
+ "empty": []
+ }
+ //- /serde.rs crate:serde
+
+ pub trait Serialize {
+ fn serialize() -> u8;
+ }
+ pub trait Deserialize {
+ fn deserialize() -> u8;
+ }
+ "#,
+ r#"
+ use serde::Serialize;
+ use serde::Deserialize;
+
+ #[derive(Serialize, Deserialize)]
+ struct Struct2{ x: i64, y: i64 }
+ #[derive(Serialize, Deserialize)]
+ struct Struct1{ empty: Vec<_>, nested: Vec<Vec<Vec<i64>>>, of_object: Vec<Struct2>, of_string: Vec<String> }
+
+ "#,
+ );
+ }
+
+ #[test]
+ fn no_emit_outside_of_item_position() {
+ check_no_fix(
+ r#"
+ fn foo() {
+ let json = {$0
+ "foo": "bar",
+ "bar": {
+ "kind": "Object",
+ "value": {}
+ }
+ };
+ }
+ "#,
+ );
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
index d6a66dc15..43ff4ed5a 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
@@ -79,7 +79,7 @@ pub macro panic {
#[test]
fn include_macro_should_allow_empty_content() {
- let mut config = DiagnosticsConfig::default();
+ let mut config = DiagnosticsConfig::test_sample();
// FIXME: This is a false-positive, the file is actually linked in via
// `include!` macro
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
index 9e66fbfb7..c24430ce6 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
@@ -750,7 +750,7 @@ fn main() {
enum Foo { A }
fn main() {
// FIXME: this should not bail out but current behavior is such as the old algorithm.
- // ExprValidator::validate_match(..) checks types of top level patterns incorrecly.
+ // ExprValidator::validate_match(..) checks types of top level patterns incorrectly.
match Foo::A {
ref _x => {}
Foo::A => {}
@@ -947,6 +947,50 @@ fn f() {
);
}
+ mod rust_unstable {
+ use super::*;
+
+ #[test]
+ fn rfc_1872_exhaustive_patterns() {
+ check_diagnostics_no_bails(
+ r"
+//- minicore: option, result
+#![feature(exhaustive_patterns)]
+enum Void {}
+fn test() {
+ match None::<!> { None => () }
+ match Result::<u8, !>::Ok(2) { Ok(_) => () }
+ match Result::<u8, Void>::Ok(2) { Ok(_) => () }
+ match (2, loop {}) {}
+ match Result::<!, !>::Ok(loop {}) {}
+ match (&loop {}) {} // https://github.com/rust-lang/rust/issues/50642#issuecomment-388234919
+ // ^^^^^^^^^^ error: missing match arm: type `&!` is non-empty
+}",
+ );
+ }
+
+ #[test]
+ fn rfc_1872_private_uninhabitedness() {
+ check_diagnostics_no_bails(
+ r"
+//- minicore: option
+//- /lib.rs crate:lib
+#![feature(exhaustive_patterns)]
+pub struct PrivatelyUninhabited { private_field: Void }
+enum Void {}
+fn test_local(x: Option<PrivatelyUninhabited>) {
+ match x {}
+} // ^ error: missing match arm: `None` not covered
+//- /main.rs crate:main deps:lib
+#![feature(exhaustive_patterns)]
+fn test(x: Option<lib::PrivatelyUninhabited>) {
+ match x {}
+ // ^ error: missing match arm: `None` and `Some(_)` not covered
+}",
+ );
+ }
+ }
+
mod false_negatives {
//! The implementation of match checking here is a work in progress. As we roll this out, we
//! prefer false negatives to false positives (ideally there would be no false positives). This
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
index e032c578f..a80299106 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
@@ -68,7 +68,7 @@ fn missing_record_expr_field_fixes(
}
let new_field = make::record_field(
None,
- make::name(&record_expr_field.field_name()?.text()),
+ make::name(&record_expr_field.field_name()?.ident_token()?.text()),
make::ty(&new_field_type.display_source_code(sema.db, module.into()).ok()?),
);
@@ -109,7 +109,7 @@ fn missing_record_expr_field_fixes(
#[cfg(test)]
mod tests {
- use crate::tests::{check_diagnostics, check_fix};
+ use crate::tests::{check_diagnostics, check_fix, check_no_fix};
#[test]
fn no_such_field_diagnostics() {
@@ -280,4 +280,18 @@ struct Foo {
"#,
)
}
+
+ #[test]
+ fn test_tuple_field_on_record_struct() {
+ check_no_fix(
+ r#"
+struct Struct {}
+fn main() {
+ Struct {
+ 0$0: 0
+ }
+}
+"#,
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index 41abaa836..61e63ea7a 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -50,6 +50,7 @@ mod handlers {
pub(crate) mod field_shorthand;
pub(crate) mod useless_braces;
pub(crate) mod unlinked_file;
+ pub(crate) mod json_is_not_rust;
}
#[cfg(test)]
@@ -59,6 +60,7 @@ use hir::{diagnostics::AnyDiagnostic, InFile, Semantics};
use ide_db::{
assists::{Assist, AssistId, AssistKind, AssistResolveStrategy},
base_db::{FileId, FileRange, SourceDatabase},
+ imports::insert_use::InsertUseConfig,
label::Label,
source_change::SourceChange,
FxHashSet, RootDatabase,
@@ -139,13 +141,37 @@ impl Default for ExprFillDefaultMode {
}
}
-#[derive(Default, Debug, Clone)]
+#[derive(Debug, Clone)]
pub struct DiagnosticsConfig {
pub proc_macros_enabled: bool,
pub proc_attr_macros_enabled: bool,
pub disable_experimental: bool,
pub disabled: FxHashSet<String>,
pub expr_fill_default: ExprFillDefaultMode,
+ // FIXME: We may want to include a whole `AssistConfig` here
+ pub insert_use: InsertUseConfig,
+}
+
+impl DiagnosticsConfig {
+ pub fn test_sample() -> Self {
+ use hir::PrefixKind;
+ use ide_db::imports::insert_use::ImportGranularity;
+
+ Self {
+ proc_macros_enabled: Default::default(),
+ proc_attr_macros_enabled: Default::default(),
+ disable_experimental: Default::default(),
+ disabled: Default::default(),
+ expr_fill_default: Default::default(),
+ insert_use: InsertUseConfig {
+ granularity: ImportGranularity::Preserve,
+ enforce_granularity: false,
+ prefix_kind: PrefixKind::Plain,
+ group: false,
+ skip_glob_imports: false,
+ },
+ }
+ }
}
struct DiagnosticsContext<'a> {
@@ -172,9 +198,12 @@ pub fn diagnostics(
}),
);
- for node in parse.tree().syntax().descendants() {
+ let parse = sema.parse(file_id);
+
+ for node in parse.syntax().descendants() {
handlers::useless_braces::useless_braces(&mut res, file_id, &node);
handlers::field_shorthand::field_shorthand(&mut res, file_id, &node);
+ handlers::json_is_not_rust::json_in_items(&sema, &mut res, file_id, &node, &config);
}
let module = sema.to_module_def(file_id);
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
index 7312bca32..729619cfd 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
@@ -37,7 +37,7 @@ fn check_nth_fix(nth: usize, ra_fixture_before: &str, ra_fixture_after: &str) {
let after = trim_indent(ra_fixture_after);
let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
- let mut conf = DiagnosticsConfig::default();
+ let mut conf = DiagnosticsConfig::test_sample();
conf.expr_fill_default = ExprFillDefaultMode::Default;
let diagnostic =
super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id)
@@ -69,7 +69,7 @@ pub(crate) fn check_no_fix(ra_fixture: &str) {
let (db, file_position) = RootDatabase::with_position(ra_fixture);
let diagnostic = super::diagnostics(
&db,
- &DiagnosticsConfig::default(),
+ &DiagnosticsConfig::test_sample(),
&AssistResolveStrategy::All,
file_position.file_id,
)
@@ -82,7 +82,7 @@ pub(crate) fn check_expect(ra_fixture: &str, expect: Expect) {
let (db, file_id) = RootDatabase::with_single_file(ra_fixture);
let diagnostics = super::diagnostics(
&db,
- &DiagnosticsConfig::default(),
+ &DiagnosticsConfig::test_sample(),
&AssistResolveStrategy::All,
file_id,
);
@@ -91,7 +91,7 @@ pub(crate) fn check_expect(ra_fixture: &str, expect: Expect) {
#[track_caller]
pub(crate) fn check_diagnostics(ra_fixture: &str) {
- let mut config = DiagnosticsConfig::default();
+ let mut config = DiagnosticsConfig::test_sample();
config.disabled.insert("inactive-code".to_string());
check_diagnostics_with_config(config, ra_fixture)
}
@@ -127,7 +127,7 @@ pub(crate) fn check_diagnostics_with_config(config: DiagnosticsConfig, ra_fixtur
#[test]
fn test_disabled_diagnostics() {
- let mut config = DiagnosticsConfig::default();
+ let mut config = DiagnosticsConfig::test_sample();
config.disabled.insert("unresolved-module".into());
let (db, file_id) = RootDatabase::with_single_file(r#"mod foo;"#);
@@ -137,7 +137,7 @@ fn test_disabled_diagnostics() {
let diagnostics = super::diagnostics(
&db,
- &DiagnosticsConfig::default(),
+ &DiagnosticsConfig::test_sample(),
&AssistResolveStrategy::All,
file_id,
);
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
index d36dd02d4..73314e0f3 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
@@ -20,6 +20,7 @@ parser = { path = "../parser", version = "0.0.0" }
syntax = { path = "../syntax", version = "0.0.0" }
ide-db = { path = "../ide-db", version = "0.0.0" }
hir = { path = "../hir", version = "0.0.0" }
+stdx = { path = "../stdx", version = "0.0.0" }
[dev-dependencies]
test-utils = { path = "../test-utils" }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
index a5e24daa9..d9834ee63 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs
@@ -57,7 +57,7 @@
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Structural Search Replace**
+// | VS Code | **rust-analyzer: Structural Search Replace**
// |===
//
// Also available as an assist, by writing a comment containing the structural
@@ -86,11 +86,9 @@ pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Matc
use crate::{errors::bail, matching::MatchFailureReason};
use hir::Semantics;
-use ide_db::{
- base_db::{FileId, FilePosition, FileRange},
- FxHashMap,
-};
+use ide_db::base_db::{FileId, FilePosition, FileRange};
use resolving::ResolvedRule;
+use stdx::hash::NoHashHashMap;
use syntax::{ast, AstNode, SyntaxNode, TextRange};
use text_edit::TextEdit;
@@ -170,9 +168,9 @@ impl<'db> MatchFinder<'db> {
}
/// Finds matches for all added rules and returns edits for all found matches.
- pub fn edits(&self) -> FxHashMap<FileId, TextEdit> {
+ pub fn edits(&self) -> NoHashHashMap<FileId, TextEdit> {
use ide_db::base_db::SourceDatabaseExt;
- let mut matches_by_file = FxHashMap::default();
+ let mut matches_by_file = NoHashHashMap::default();
for m in self.matches().matches {
matches_by_file
.entry(m.range.file_id)
diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
index a18a6bea9..5a8cda8fb 100644
--- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
@@ -7,7 +7,7 @@ use ide_db::{
search::FileReference,
FxIndexMap, RootDatabase,
};
-use syntax::{ast, AstNode, SyntaxKind::NAME, TextRange};
+use syntax::{ast, AstNode, SyntaxKind::IDENT, TextRange};
use crate::{goto_definition, FilePosition, NavigationTarget, RangeInfo, TryToNav};
@@ -79,7 +79,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
let file = sema.parse(file_id);
let file = file.syntax();
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
- NAME => 1,
+ IDENT => 1,
_ => 0,
})?;
let mut calls = CallLocations::default();
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index 582e9fe7e..92ce26b42 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -184,10 +184,10 @@ pub(crate) fn resolve_doc_path_for_def(
Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
+ Definition::SelfType(it) => it.resolve_doc_path(db, link, ns),
Definition::BuiltinAttr(_)
| Definition::ToolModule(_)
| Definition::BuiltinType(_)
- | Definition::SelfType(_)
| Definition::Local(_)
| Definition::GenericParam(_)
| Definition::Label(_)
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index efa8551a0..93252339c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -19,7 +19,7 @@ pub struct ExpandedMacro {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Expand macro recursively**
+// | VS Code | **rust-analyzer: Expand macro recursively**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[]
@@ -32,7 +32,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
_ => 0,
})?;
- // due to how Rust Analyzer works internally, we need to special case derive attributes,
+ // due to how rust-analyzer works internally, we need to special case derive attributes,
// otherwise they might not get found, e.g. here with the cursor at $0 `#[attr]` would expand:
// ```
// #[attr]
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index d9c97751c..36a648fe4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -1,4 +1,4 @@
-use std::{convert::TryInto, mem::discriminant};
+use std::mem::discriminant;
use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, TryToNav};
use hir::{AsAssocItem, AssocItem, Semantics};
@@ -39,7 +39,11 @@ pub(crate) fn goto_definition(
| T![super]
| T![crate]
| T![Self]
- | COMMENT => 2,
+ | COMMENT => 4,
+ // index and prefix ops
+ T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
+ kind if kind.is_keyword() => 2,
+ T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
})?;
@@ -1631,4 +1635,154 @@ foo!(bar$0);
"#,
);
}
+
+ #[test]
+ fn goto_await_poll() {
+ check(
+ r#"
+//- minicore: future
+
+struct MyFut;
+
+impl core::future::Future for MyFut {
+ type Output = ();
+
+ fn poll(
+ //^^^^
+ self: std::pin::Pin<&mut Self>,
+ cx: &mut std::task::Context<'_>
+ ) -> std::task::Poll<Self::Output>
+ {
+ ()
+ }
+}
+
+fn f() {
+ MyFut.await$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_await_into_future_poll() {
+ check(
+ r#"
+//- minicore: future
+
+struct Futurable;
+
+impl core::future::IntoFuture for Futurable {
+ type IntoFuture = MyFut;
+}
+
+struct MyFut;
+
+impl core::future::Future for MyFut {
+ type Output = ();
+
+ fn poll(
+ //^^^^
+ self: std::pin::Pin<&mut Self>,
+ cx: &mut std::task::Context<'_>
+ ) -> std::task::Poll<Self::Output>
+ {
+ ()
+ }
+}
+
+fn f() {
+ Futurable.await$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_try_op() {
+ check(
+ r#"
+//- minicore: try
+
+struct Struct;
+
+impl core::ops::Try for Struct {
+ fn branch(
+ //^^^^^^
+ self
+ ) {}
+}
+
+fn f() {
+ Struct?$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_index_op() {
+ check(
+ r#"
+//- minicore: index
+
+struct Struct;
+
+impl core::ops::Index<usize> for Struct {
+ fn index(
+ //^^^^^
+ self
+ ) {}
+}
+
+fn f() {
+ Struct[0]$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_prefix_op() {
+ check(
+ r#"
+//- minicore: deref
+
+struct Struct;
+
+impl core::ops::Deref for Struct {
+ fn deref(
+ //^^^^^
+ self
+ ) {}
+}
+
+fn f() {
+ $0*Struct;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_bin_op() {
+ check(
+ r#"
+//- minicore: add
+
+struct Struct;
+
+impl core::ops::Add for Struct {
+ fn add(
+ //^^^
+ self
+ ) {}
+}
+
+fn f() {
+ Struct +$0 Struct;
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
index 04b51c839..b3f711b6b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
@@ -30,7 +30,7 @@ pub(crate) fn goto_implementation(
let original_token =
pick_best_token(syntax.token_at_offset(position.offset), |kind| match kind {
- IDENT | T![self] => 1,
+ IDENT | T![self] | INT_NUMBER => 1,
_ => 0,
})?;
let range = original_token.text_range();
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index f2d7029ea..f190da326 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -333,7 +333,8 @@ fn cover_range(r0: Option<TextRange>, r1: Option<TextRange>) -> Option<TextRange
fn find_defs(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> FxHashSet<Definition> {
sema.descend_into_macros(token)
.into_iter()
- .filter_map(|token| IdentClass::classify_token(sema, &token).map(IdentClass::definitions))
+ .filter_map(|token| IdentClass::classify_token(sema, &token))
+ .map(IdentClass::definitions_no_ops)
.flatten()
.collect()
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 59c97f2dc..3687b597f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -9,7 +9,7 @@ use either::Either;
use hir::{HasSource, Semantics};
use ide_db::{
base_db::FileRange,
- defs::{Definition, IdentClass},
+ defs::{Definition, IdentClass, OperatorClass},
famous_defs::FamousDefs,
helpers::pick_best_token,
FxIndexSet, RootDatabase,
@@ -27,6 +27,7 @@ use crate::{
pub struct HoverConfig {
pub links_in_hover: bool,
pub documentation: Option<HoverDocFormat>,
+ pub keywords: bool,
}
impl HoverConfig {
@@ -101,7 +102,10 @@ pub(crate) fn hover(
let offset = range.start();
let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
- IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] => 3,
+ IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] => 4,
+ // index and prefix ops
+ T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
+ kind if kind.is_keyword() => 2,
T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
@@ -116,6 +120,8 @@ pub(crate) fn hover(
}
let in_attr = matches!(original_token.parent().and_then(ast::TokenTree::cast), Some(tt) if tt.syntax().ancestors().any(|it| ast::Meta::can_cast(it.kind())));
+ // prefer descending the same token kind in attribute expansions, in normal macros text
+ // equivalency is more important
let descended = if in_attr {
[sema.descend_into_macros_with_kind_preference(original_token.clone())].into()
} else {
@@ -136,6 +142,11 @@ pub(crate) fn hover(
.filter_map(|token| {
let node = token.parent()?;
let class = IdentClass::classify_token(sema, token)?;
+ if let IdentClass::Operator(OperatorClass::Await(_)) = class {
+ // It's better for us to fall back to the keyword hover here,
+ // rendering poll is very confusing
+ return None;
+ }
Some(class.definitions().into_iter().zip(iter::once(node).cycle()))
})
.flatten()
@@ -232,10 +243,12 @@ fn hover_type_fallback(
token: &SyntaxToken,
original_token: &SyntaxToken,
) -> Option<RangeInfo<HoverResult>> {
- let node = token
- .parent_ancestors()
- .take_while(|it| !ast::Item::can_cast(it.kind()))
- .find(|n| ast::Expr::can_cast(n.kind()) || ast::Pat::can_cast(n.kind()))?;
+ let node =
+ token.parent_ancestors().take_while(|it| !ast::Item::can_cast(it.kind())).find(|n| {
+ ast::Expr::can_cast(n.kind())
+ || ast::Pat::can_cast(n.kind())
+ || ast::Type::can_cast(n.kind())
+ })?;
let expr_or_pat = match_ast! {
match node {
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 6c50a4e6a..c5c50d88d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -2,12 +2,13 @@
use std::fmt::Display;
use either::Either;
-use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HirDisplay, Semantics, TypeInfo};
+use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
use ide_db::{
base_db::SourceDatabase,
defs::Definition,
famous_defs::FamousDefs,
generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
+ syntax_helpers::insert_whitespace_into_node,
RootDatabase,
};
use itertools::Itertools;
@@ -230,7 +231,7 @@ pub(super) fn keyword(
config: &HoverConfig,
token: &SyntaxToken,
) -> Option<HoverResult> {
- if !token.kind().is_keyword() || !config.documentation.is_some() {
+ if !token.kind().is_keyword() || !config.documentation.is_some() || !config.keywords {
return None;
}
let parent = token.parent()?;
@@ -350,10 +351,24 @@ pub(super) fn definition(
let body = it.eval(db);
match body {
Ok(x) => Some(format!("{}", x)),
- Err(_) => it.value(db).map(|x| format!("{}", x)),
+ Err(_) => {
+ let source = it.source(db)?;
+ let mut body = source.value.body()?.syntax().clone();
+ if source.file_id.is_macro() {
+ body = insert_whitespace_into_node::insert_ws_into(body);
+ }
+ Some(body.to_string())
+ }
+ }
+ }),
+ Definition::Static(it) => label_value_and_docs(db, it, |it| {
+ let source = it.source(db)?;
+ let mut body = source.value.body()?.syntax().clone();
+ if source.file_id.is_macro() {
+ body = insert_whitespace_into_node::insert_ws_into(body);
}
+ Some(body.to_string())
}),
- Definition::Static(it) => label_value_and_docs(db, it, |it| it.value(db)),
Definition::Trait(it) => label_and_docs(db, it),
Definition::TypeAlias(it) => label_and_docs(db, it),
Definition::BuiltinType(it) => {
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 867d1f54d..4b8b47783 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -8,7 +8,11 @@ fn check_hover_no_result(ra_fixture: &str) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap();
@@ -20,7 +24,11 @@ fn check(ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap()
@@ -37,7 +45,11 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: false,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap()
@@ -54,7 +66,11 @@ fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::PlainText) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::PlainText),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap()
@@ -71,7 +87,11 @@ fn check_actions(ra_fixture: &str, expect: Expect) {
let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id, range: position.range_or_empty() },
)
.unwrap()
@@ -83,7 +103,11 @@ fn check_hover_range(ra_fixture: &str, expect: Expect) {
let (analysis, range) = fixture::range(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: false,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
range,
)
.unwrap()
@@ -95,7 +119,11 @@ fn check_hover_range_no_results(ra_fixture: &str) {
let (analysis, range) = fixture::range(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: false,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
range,
)
.unwrap();
@@ -5051,3 +5079,95 @@ fn f() {
```"#]],
);
}
+
+#[test]
+fn hover_deref() {
+ check(
+ r#"
+//- minicore: deref
+
+struct Struct(usize);
+
+impl core::ops::Deref for Struct {
+ type Target = usize;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+fn f() {
+ $0*Struct(0);
+}
+"#,
+ expect![[r#"
+ ***
+
+ ```rust
+ test::Struct
+ ```
+
+ ```rust
+ fn deref(&self) -> &Self::Target
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn static_const_macro_expanded_body() {
+ check(
+ r#"
+macro_rules! m {
+ () => {
+ pub const V: i8 = {
+ let e = 123;
+ f(e) // Prevent const eval from evaluating this constant, we want to print the body's code.
+ };
+ };
+}
+m!();
+fn main() { $0V; }
+"#,
+ expect![[r#"
+ *V*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ pub const V: i8 = {
+ let e = 123;
+ f(e)
+ }
+ ```
+ "#]],
+ );
+ check(
+ r#"
+macro_rules! m {
+ () => {
+ pub static V: i8 = {
+ let e = 123;
+ };
+ };
+}
+m!();
+fn main() { $0V; }
+"#,
+ expect![[r#"
+ *V*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ pub static V: i8 = {
+ let e = 123;
+ }
+ ```
+ "#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 5aae669aa..d1b1d2c33 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -1,3 +1,5 @@
+use std::fmt;
+
use either::Either;
use hir::{known, Callable, HasVisibility, HirDisplay, Mutability, Semantics, TypeInfo};
use ide_db::{
@@ -69,7 +71,7 @@ pub enum InlayKind {
pub struct InlayHint {
pub range: TextRange,
pub kind: InlayKind,
- pub label: String,
+ pub label: InlayHintLabel,
pub tooltip: Option<InlayTooltip>,
}
@@ -80,6 +82,83 @@ pub enum InlayTooltip {
HoverOffset(FileId, TextSize),
}
+pub struct InlayHintLabel {
+ pub parts: Vec<InlayHintLabelPart>,
+}
+
+impl InlayHintLabel {
+ pub fn as_simple_str(&self) -> Option<&str> {
+ match &*self.parts {
+ [part] => part.as_simple_str(),
+ _ => None,
+ }
+ }
+
+ pub fn prepend_str(&mut self, s: &str) {
+ match &mut *self.parts {
+ [part, ..] if part.as_simple_str().is_some() => part.text = format!("{s}{}", part.text),
+ _ => self.parts.insert(0, InlayHintLabelPart { text: s.into(), linked_location: None }),
+ }
+ }
+
+ pub fn append_str(&mut self, s: &str) {
+ match &mut *self.parts {
+ [.., part] if part.as_simple_str().is_some() => part.text.push_str(s),
+ _ => self.parts.push(InlayHintLabelPart { text: s.into(), linked_location: None }),
+ }
+ }
+}
+
+impl From<String> for InlayHintLabel {
+ fn from(s: String) -> Self {
+ Self { parts: vec![InlayHintLabelPart { text: s, linked_location: None }] }
+ }
+}
+
+impl fmt::Display for InlayHintLabel {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.parts.iter().map(|part| &part.text).format(""))
+ }
+}
+
+impl fmt::Debug for InlayHintLabel {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list().entries(&self.parts).finish()
+ }
+}
+
+pub struct InlayHintLabelPart {
+ pub text: String,
+ /// Source location represented by this label part. The client will use this to fetch the part's
+ /// hover tooltip, and Ctrl+Clicking the label part will navigate to the definition the location
+ /// refers to (not necessarily the location itself).
+ /// When setting this, no tooltip must be set on the containing hint, or VS Code will display
+ /// them both.
+ pub linked_location: Option<FileRange>,
+}
+
+impl InlayHintLabelPart {
+ pub fn as_simple_str(&self) -> Option<&str> {
+ match self {
+ Self { text, linked_location: None } => Some(text),
+ _ => None,
+ }
+ }
+}
+
+impl fmt::Debug for InlayHintLabelPart {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self.as_simple_str() {
+ Some(string) => string.fmt(f),
+ None => f
+ .debug_struct("InlayHintLabelPart")
+ .field("text", &self.text)
+ .field("linked_location", &self.linked_location)
+ .finish(),
+ }
+ }
+}
+
// Feature: Inlay Hints
//
// rust-analyzer shows additional information inline with the source code.
@@ -100,7 +179,7 @@ pub enum InlayTooltip {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Toggle inlay hints*
+// | VS Code | **rust-analyzer: Toggle inlay hints*
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[]
@@ -192,10 +271,10 @@ fn closing_brace_hints(
) -> Option<()> {
let min_lines = config.closing_brace_hints_min_lines?;
- let name = |it: ast::Name| it.syntax().text_range().start();
+ let name = |it: ast::Name| it.syntax().text_range();
let mut closing_token;
- let (label, name_offset) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
+ let (label, name_range) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
closing_token = item_list.r_curly_token()?;
let parent = item_list.syntax().parent()?;
@@ -205,11 +284,11 @@ fn closing_brace_hints(
let imp = sema.to_def(&imp)?;
let ty = imp.self_ty(sema.db);
let trait_ = imp.trait_(sema.db);
-
- (match trait_ {
+ let hint_text = match trait_ {
Some(tr) => format!("impl {} for {}", tr.name(sema.db), ty.display_truncated(sema.db, config.max_length)),
None => format!("impl {}", ty.display_truncated(sema.db, config.max_length)),
- }, None)
+ };
+ (hint_text, None)
},
ast::Trait(tr) => {
(format!("trait {}", tr.name()?), tr.name().map(name))
@@ -253,7 +332,7 @@ fn closing_brace_hints(
(
format!("{}!", mac.path()?),
- mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range().start()),
+ mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range()),
)
} else {
return None;
@@ -278,11 +357,12 @@ fn closing_brace_hints(
return None;
}
+ let linked_location = name_range.map(|range| FileRange { file_id, range });
acc.push(InlayHint {
range: closing_token.text_range(),
kind: InlayKind::ClosingBraceHint,
- label,
- tooltip: name_offset.map(|it| InlayTooltip::HoverOffset(file_id, it)),
+ label: InlayHintLabel { parts: vec![InlayHintLabelPart { text: label, linked_location }] },
+ tooltip: None, // provided by label part location
});
None
@@ -311,7 +391,7 @@ fn implicit_static_hints(
acc.push(InlayHint {
range: t.text_range(),
kind: InlayKind::LifetimeHint,
- label: "'static".to_owned(),
+ label: "'static".to_owned().into(),
tooltip: Some(InlayTooltip::String("Elided static lifetime".into())),
});
}
@@ -329,10 +409,10 @@ fn fn_lifetime_fn_hints(
return None;
}
- let mk_lt_hint = |t: SyntaxToken, label| InlayHint {
+ let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
range: t.text_range(),
kind: InlayKind::LifetimeHint,
- label,
+ label: label.into(),
tooltip: Some(InlayTooltip::String("Elided lifetime".into())),
};
@@ -486,7 +566,8 @@ fn fn_lifetime_fn_hints(
"{}{}",
allocated_lifetimes.iter().format(", "),
if is_empty { "" } else { ", " }
- ),
+ )
+ .into(),
tooltip: Some(InlayTooltip::String("Elided lifetimes".into())),
});
}
@@ -535,7 +616,8 @@ fn closure_ret_hints(
range: param_list.syntax().text_range(),
kind: InlayKind::ClosureReturnTypeHint,
label: hint_iterator(sema, &famous_defs, config, &ty)
- .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()),
+ .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string())
+ .into(),
tooltip: Some(InlayTooltip::HoverRanged(file_id, param_list.syntax().text_range())),
});
Some(())
@@ -562,7 +644,7 @@ fn reborrow_hints(
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::ImplicitReborrowHint,
- label: label.to_string(),
+ label: label.to_string().into(),
tooltip: Some(InlayTooltip::String("Compiler inserted reborrow".into())),
});
Some(())
@@ -620,9 +702,9 @@ fn chaining_hints(
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::ChainingHint,
- label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
- ty.display_truncated(sema.db, config.max_length).to_string()
- }),
+ label: hint_iterator(sema, &famous_defs, config, &ty)
+ .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string())
+ .into(),
tooltip: Some(InlayTooltip::HoverRanged(file_id, expr.syntax().text_range())),
});
}
@@ -674,7 +756,7 @@ fn param_name_hints(
InlayHint {
range,
kind: InlayKind::ParameterHint,
- label: param_name,
+ label: param_name.into(),
tooltip: tooltip.map(|it| InlayTooltip::HoverOffset(it.file_id, it.range.start())),
}
});
@@ -705,7 +787,7 @@ fn binding_mode_hints(
acc.push(InlayHint {
range,
kind: InlayKind::BindingModeHint,
- label: r.to_string(),
+ label: r.to_string().into(),
tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
});
});
@@ -720,7 +802,7 @@ fn binding_mode_hints(
acc.push(InlayHint {
range,
kind: InlayKind::BindingModeHint,
- label: bm.to_string(),
+ label: bm.to_string().into(),
tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
});
}
@@ -772,7 +854,7 @@ fn bind_pat_hints(
None => pat.syntax().text_range(),
},
kind: InlayKind::TypeHint,
- label,
+ label: label.into(),
tooltip: pat
.name()
.map(|it| it.syntax().text_range())
@@ -1910,7 +1992,7 @@ impl<T> Vec<T> {
pub struct Box<T> {}
trait Display {}
-trait Sync {}
+auto trait Sync {}
fn main() {
// The block expression wrapping disables the constructor hint hiding logic
@@ -2223,7 +2305,9 @@ fn main() {
InlayHint {
range: 147..172,
kind: ChainingHint,
- label: "B",
+ label: [
+ "B",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2236,7 +2320,9 @@ fn main() {
InlayHint {
range: 147..154,
kind: ChainingHint,
- label: "A",
+ label: [
+ "A",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2294,7 +2380,9 @@ fn main() {
InlayHint {
range: 143..190,
kind: ChainingHint,
- label: "C",
+ label: [
+ "C",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2307,7 +2395,9 @@ fn main() {
InlayHint {
range: 143..179,
kind: ChainingHint,
- label: "B",
+ label: [
+ "B",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2350,7 +2440,9 @@ fn main() {
InlayHint {
range: 246..283,
kind: ChainingHint,
- label: "B<X<i32, bool>>",
+ label: [
+ "B<X<i32, bool>>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2363,7 +2455,9 @@ fn main() {
InlayHint {
range: 246..265,
kind: ChainingHint,
- label: "A<X<i32, bool>>",
+ label: [
+ "A<X<i32, bool>>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2408,7 +2502,9 @@ fn main() {
InlayHint {
range: 174..241,
kind: ChainingHint,
- label: "impl Iterator<Item = ()>",
+ label: [
+ "impl Iterator<Item = ()>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2421,7 +2517,9 @@ fn main() {
InlayHint {
range: 174..224,
kind: ChainingHint,
- label: "impl Iterator<Item = ()>",
+ label: [
+ "impl Iterator<Item = ()>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2434,7 +2532,9 @@ fn main() {
InlayHint {
range: 174..206,
kind: ChainingHint,
- label: "impl Iterator<Item = ()>",
+ label: [
+ "impl Iterator<Item = ()>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2447,7 +2547,9 @@ fn main() {
InlayHint {
range: 174..189,
kind: ChainingHint,
- label: "&mut MyIter",
+ label: [
+ "&mut MyIter",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2489,7 +2591,9 @@ fn main() {
InlayHint {
range: 124..130,
kind: TypeHint,
- label: "Struct",
+ label: [
+ "Struct",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2502,7 +2606,9 @@ fn main() {
InlayHint {
range: 145..185,
kind: ChainingHint,
- label: "Struct",
+ label: [
+ "Struct",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2515,7 +2621,9 @@ fn main() {
InlayHint {
range: 145..168,
kind: ChainingHint,
- label: "Struct",
+ label: [
+ "Struct",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2528,7 +2636,9 @@ fn main() {
InlayHint {
range: 222..228,
kind: ParameterHint,
- label: "self",
+ label: [
+ "self",
+ ],
tooltip: Some(
HoverOffset(
FileId(
diff --git a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
index 08621adde..edc48e84d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
@@ -28,7 +28,7 @@ pub struct JoinLinesConfig {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Join lines**
+// | VS Code | **rust-analyzer: Join lines**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index dd108fa79..055233081 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -82,12 +82,12 @@ pub use crate::{
highlight_related::{HighlightRelatedConfig, HighlightedRange},
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
inlay_hints::{
- ClosureReturnTypeHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
- LifetimeElisionHints, ReborrowHints,
+ ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
+ InlayTooltip, LifetimeElisionHints, ReborrowHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
- moniker::{MonikerKind, MonikerResult, PackageInformation},
+ moniker::{MonikerDescriptorKind, MonikerKind, MonikerResult, PackageInformation},
move_item::Direction,
navigation_target::NavigationTarget,
prime_caches::ParallelPrimeCachesProgress,
@@ -98,7 +98,7 @@ pub use crate::{
static_index::{StaticIndex, StaticIndexedFile, TokenId, TokenStaticData},
syntax_highlighting::{
tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
- HlRange,
+ HighlightConfig, HlRange,
},
};
pub use hir::{Documentation, Semantics};
@@ -517,8 +517,12 @@ impl Analysis {
}
/// Computes syntax highlighting for the given file
- pub fn highlight(&self, file_id: FileId) -> Cancellable<Vec<HlRange>> {
- self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false))
+ pub fn highlight(
+ &self,
+ highlight_config: HighlightConfig,
+ file_id: FileId,
+ ) -> Cancellable<Vec<HlRange>> {
+ self.with_db(|db| syntax_highlighting::highlight(db, highlight_config, file_id, None))
}
/// Computes all ranges to highlight for a given item in a file.
@@ -533,9 +537,13 @@ impl Analysis {
}
/// Computes syntax highlighting for the given file range.
- pub fn highlight_range(&self, frange: FileRange) -> Cancellable<Vec<HlRange>> {
+ pub fn highlight_range(
+ &self,
+ highlight_config: HighlightConfig,
+ frange: FileRange,
+ ) -> Cancellable<Vec<HlRange>> {
self.with_db(|db| {
- syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false)
+ syntax_highlighting::highlight(db, highlight_config, frange.file_id, Some(frange.range))
})
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
index da70cecdd..6e8a6d020 100644
--- a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
@@ -12,7 +12,7 @@ use syntax::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Find matching brace**
+// | VS Code | **rust-analyzer: Find matching brace**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 6bab9fa1e..600a52630 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -14,16 +14,38 @@ use syntax::{AstNode, SyntaxKind::*, T};
use crate::{doc_links::token_as_doc_comment, RangeInfo};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum MonikerDescriptorKind {
+ Namespace,
+ Type,
+ Term,
+ Method,
+ TypeParameter,
+ Parameter,
+ Macro,
+ Meta,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct MonikerDescriptor {
+ pub name: Name,
+ pub desc: MonikerDescriptorKind,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MonikerIdentifier {
- crate_name: String,
- path: Vec<Name>,
+ pub crate_name: String,
+ pub description: Vec<MonikerDescriptor>,
}
impl ToString for MonikerIdentifier {
fn to_string(&self) -> String {
match self {
- MonikerIdentifier { path, crate_name } => {
- format!("{}::{}", crate_name, path.iter().map(|x| x.to_string()).join("::"))
+ MonikerIdentifier { description, crate_name } => {
+ format!(
+ "{}::{}",
+ crate_name,
+ description.iter().map(|x| x.name.to_string()).join("::")
+ )
}
}
}
@@ -42,6 +64,12 @@ pub struct MonikerResult {
pub package_information: PackageInformation,
}
+impl MonikerResult {
+ pub fn from_def(db: &RootDatabase, def: Definition, from_crate: Crate) -> Option<Self> {
+ def_to_moniker(db, def, from_crate)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PackageInformation {
pub name: String,
@@ -90,7 +118,7 @@ pub(crate) fn moniker(
.descend_into_macros(original_token.clone())
.into_iter()
.filter_map(|token| {
- IdentClass::classify_token(sema, &token).map(IdentClass::definitions).map(|it| {
+ IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops).map(|it| {
it.into_iter().flat_map(|def| def_to_moniker(sema.db, def, current_crate))
})
})
@@ -105,13 +133,23 @@ pub(crate) fn def_to_moniker(
def: Definition,
from_crate: Crate,
) -> Option<MonikerResult> {
- if matches!(def, Definition::GenericParam(_) | Definition::SelfType(_) | Definition::Local(_)) {
+ if matches!(
+ def,
+ Definition::GenericParam(_)
+ | Definition::Label(_)
+ | Definition::DeriveHelper(_)
+ | Definition::BuiltinAttr(_)
+ | Definition::ToolModule(_)
+ ) {
return None;
}
+
let module = def.module(db)?;
let krate = module.krate();
- let mut path = vec![];
- path.extend(module.path_to_root(db).into_iter().filter_map(|x| x.name(db)));
+ let mut description = vec![];
+ description.extend(module.path_to_root(db).into_iter().filter_map(|x| {
+ Some(MonikerDescriptor { name: x.name(db)?, desc: MonikerDescriptorKind::Namespace })
+ }));
// Handle associated items within a trait
if let Some(assoc) = def.as_assoc_item(db) {
@@ -120,31 +158,98 @@ pub(crate) fn def_to_moniker(
AssocItemContainer::Trait(trait_) => {
// Because different traits can have functions with the same name,
// we have to include the trait name as part of the moniker for uniqueness.
- path.push(trait_.name(db));
+ description.push(MonikerDescriptor {
+ name: trait_.name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
AssocItemContainer::Impl(impl_) => {
// Because a struct can implement multiple traits, for implementations
// we add both the struct name and the trait name to the path
if let Some(adt) = impl_.self_ty(db).as_adt() {
- path.push(adt.name(db));
+ description.push(MonikerDescriptor {
+ name: adt.name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
if let Some(trait_) = impl_.trait_(db) {
- path.push(trait_.name(db));
+ description.push(MonikerDescriptor {
+ name: trait_.name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
}
}
}
if let Definition::Field(it) = def {
- path.push(it.parent_def(db).name(db));
+ description.push(MonikerDescriptor {
+ name: it.parent_def(db).name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
- path.push(def.name(db)?);
+ let name_desc = match def {
+ // These are handled by top-level guard (for performance).
+ Definition::GenericParam(_)
+ | Definition::Label(_)
+ | Definition::DeriveHelper(_)
+ | Definition::BuiltinAttr(_)
+ | Definition::ToolModule(_) => return None,
+
+ Definition::Local(local) => {
+ if !local.is_param(db) {
+ return None;
+ }
+
+ MonikerDescriptor { name: local.name(db), desc: MonikerDescriptorKind::Parameter }
+ }
+ Definition::Macro(m) => {
+ MonikerDescriptor { name: m.name(db), desc: MonikerDescriptorKind::Macro }
+ }
+ Definition::Function(f) => {
+ MonikerDescriptor { name: f.name(db), desc: MonikerDescriptorKind::Method }
+ }
+ Definition::Variant(v) => {
+ MonikerDescriptor { name: v.name(db), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::Const(c) => {
+ MonikerDescriptor { name: c.name(db)?, desc: MonikerDescriptorKind::Term }
+ }
+ Definition::Trait(trait_) => {
+ MonikerDescriptor { name: trait_.name(db), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::TypeAlias(ta) => {
+ MonikerDescriptor { name: ta.name(db), desc: MonikerDescriptorKind::TypeParameter }
+ }
+ Definition::Module(m) => {
+ MonikerDescriptor { name: m.name(db)?, desc: MonikerDescriptorKind::Namespace }
+ }
+ Definition::BuiltinType(b) => {
+ MonikerDescriptor { name: b.name(), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::SelfType(imp) => MonikerDescriptor {
+ name: imp.self_ty(db).as_adt()?.name(db),
+ desc: MonikerDescriptorKind::Type,
+ },
+ Definition::Field(it) => {
+ MonikerDescriptor { name: it.name(db), desc: MonikerDescriptorKind::Term }
+ }
+ Definition::Adt(adt) => {
+ MonikerDescriptor { name: adt.name(db), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::Static(s) => {
+ MonikerDescriptor { name: s.name(db), desc: MonikerDescriptorKind::Meta }
+ }
+ };
+
+ description.push(name_desc);
+
Some(MonikerResult {
identifier: MonikerIdentifier {
crate_name: krate.display_name(db)?.crate_name().to_string(),
- path,
+ description,
},
kind: if krate == from_crate { MonikerKind::Export } else { MonikerKind::Import },
package_information: {
diff --git a/src/tools/rust-analyzer/crates/ide/src/move_item.rs b/src/tools/rust-analyzer/crates/ide/src/move_item.rs
index 02e9fb8b5..ffc4bdd7d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/move_item.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/move_item.rs
@@ -19,8 +19,8 @@ pub enum Direction {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Move item up**
-// | VS Code | **Rust Analyzer: Move item down**
+// | VS Code | **rust-analyzer: Move item up**
+// | VS Code | **rust-analyzer: Move item down**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
index 9b1f48044..8f3cc8687 100644
--- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
@@ -18,7 +18,7 @@ use crate::NavigationTarget;
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Locate parent module**
+// | VS Code | **rust-analyzer: Locate parent module**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs
index 296270036..87b3ef380 100644
--- a/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs
@@ -12,8 +12,9 @@ use ide_db::{
salsa::{Database, ParallelDatabase, Snapshot},
Cancelled, CrateGraph, CrateId, SourceDatabase, SourceDatabaseExt,
},
- FxHashSet, FxIndexMap,
+ FxIndexMap,
};
+use stdx::hash::NoHashHashSet;
use crate::RootDatabase;
@@ -141,7 +142,7 @@ pub(crate) fn parallel_prime_caches(
}
}
-fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> FxHashSet<CrateId> {
+fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> NoHashHashSet<CrateId> {
// We're only interested in the workspace crates and the `ImportMap`s of their direct
// dependencies, though in practice the latter also compute the `DefMap`s.
// We don't prime transitive dependencies because they're generally not visible in
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index 1a6beec18..99614b645 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -14,8 +14,9 @@ use ide_db::{
base_db::FileId,
defs::{Definition, NameClass, NameRefClass},
search::{ReferenceCategory, SearchScope, UsageSearchResult},
- FxHashMap, RootDatabase,
+ RootDatabase,
};
+use stdx::hash::NoHashHashMap;
use syntax::{
algo::find_node_at_offset,
ast::{self, HasName},
@@ -29,7 +30,7 @@ use crate::{FilePosition, NavigationTarget, TryToNav};
#[derive(Debug, Clone)]
pub struct ReferenceSearchResult {
pub declaration: Option<Declaration>,
- pub references: FxHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
+ pub references: NoHashHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
}
#[derive(Debug, Clone)]
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index bec770ed9..0181c6b8e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -116,7 +116,7 @@ impl Runnable {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Run**
+// | VS Code | **rust-analyzer: Run**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif[]
pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
@@ -202,7 +202,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Peek related tests**
+// | VS Code | **rust-analyzer: Peek related tests**
// |===
pub(crate) fn related_tests(
db: &RootDatabase,
@@ -373,11 +373,13 @@ pub(crate) fn runnable_impl(
let adt_name = ty.as_adt()?.name(sema.db);
let mut ty_args = ty.type_arguments().peekable();
let params = if ty_args.peek().is_some() {
- format!("<{}>", ty_args.format_with(", ", |ty, cb| cb(&ty.display(sema.db))))
+ format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty.display(sema.db))))
} else {
String::new()
};
- let test_id = TestId::Path(format!("{}{}", adt_name, params));
+ let mut test_id = format!("{}{}", adt_name, params);
+ test_id.retain(|c| c != ' ');
+ let test_id = TestId::Path(test_id);
Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::DocTest { test_id }, cfg })
}
@@ -441,10 +443,11 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
format_to!(
path,
"<{}>",
- ty_args.format_with(", ", |ty, cb| cb(&ty.display(db)))
+ ty_args.format_with(",", |ty, cb| cb(&ty.display(db)))
);
}
format_to!(path, "::{}", def_name);
+ path.retain(|c| c != ' ');
return Some(path);
}
}
@@ -2067,13 +2070,23 @@ mod tests {
$0
struct Foo<T, U>;
+/// ```
+/// ```
impl<T, U> Foo<T, U> {
/// ```rust
/// ````
fn t() {}
}
+
+/// ```
+/// ```
+impl Foo<Foo<(), ()>, ()> {
+ /// ```
+ /// ```
+ fn t() {}
+}
"#,
- &[DocTest],
+ &[DocTest, DocTest, DocTest, DocTest],
expect![[r#"
[
Runnable {
@@ -2082,12 +2095,64 @@ impl<T, U> Foo<T, U> {
file_id: FileId(
0,
),
- full_range: 47..85,
+ full_range: 20..103,
+ focus_range: 47..56,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Foo<T,U>",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 63..101,
+ name: "t",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Foo<T,U>::t",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 105..188,
+ focus_range: 126..146,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Foo<Foo<(),()>,()>",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 153..186,
name: "t",
},
kind: DocTest {
test_id: Path(
- "Foo<T, U>::t",
+ "Foo<Foo<(),()>,()>::t",
),
},
cfg: None,
@@ -2160,4 +2225,190 @@ macro_rules! foo {
"#]],
);
}
+
+ #[test]
+ fn test_paths_with_raw_ident() {
+ check(
+ r#"
+//- /lib.rs
+$0
+mod r#mod {
+ #[test]
+ fn r#fn() {}
+
+ /// ```
+ /// ```
+ fn r#for() {}
+
+ /// ```
+ /// ```
+ struct r#struct<r#type>(r#type);
+
+ /// ```
+ /// ```
+ impl<r#type> r#struct<r#type> {
+ /// ```
+ /// ```
+ fn r#fn() {}
+ }
+
+ enum r#enum {}
+ impl r#struct<r#enum> {
+ /// ```
+ /// ```
+ fn r#fn() {}
+ }
+
+ trait r#trait {}
+
+ /// ```
+ /// ```
+ impl<T> r#trait for r#struct<T> {}
+}
+"#,
+ &[TestMod, Test, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..461,
+ focus_range: 5..10,
+ name: "r#mod",
+ kind: Module,
+ description: "mod r#mod",
+ },
+ kind: TestMod {
+ path: "r#mod",
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 17..41,
+ focus_range: 32..36,
+ name: "r#fn",
+ kind: Function,
+ },
+ kind: Test {
+ test_id: Path(
+ "r#mod::r#fn",
+ ),
+ attr: TestAttr {
+ ignore: false,
+ },
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 47..84,
+ name: "r#for",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#for",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 90..146,
+ name: "r#struct",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#struct",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 152..266,
+ focus_range: 189..205,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#struct<r#type>",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 216..260,
+ name: "r#fn",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#struct<r#type>::r#fn",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 323..367,
+ name: "r#fn",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#struct<r#enum>::r#fn",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 401..459,
+ focus_range: 445..456,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#struct<T>",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs
index 15cb89dcc..2d8662764 100644
--- a/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs
@@ -12,7 +12,7 @@ use ide_db::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Shuffle Crate Graph**
+// | VS Code | **rust-analyzer: Shuffle Crate Graph**
// |===
pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
let crate_graph = db.crate_graph();
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index d74b64041..9e5eb9095 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -130,8 +130,11 @@ impl StaticIndex<'_> {
syntax::NodeOrToken::Node(_) => None,
syntax::NodeOrToken::Token(x) => Some(x),
});
- let hover_config =
- HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) };
+ let hover_config = HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ };
let tokens = tokens.filter(|token| {
matches!(
token.kind(),
@@ -204,7 +207,7 @@ impl StaticIndex<'_> {
fn get_definition(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option<Definition> {
for token in sema.descend_into_macros(token) {
- let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions);
+ let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
if let Some(&[x]) = def.as_deref() {
return Some(x);
} else {
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index 3191870eb..f4d038744 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -1,4 +1,4 @@
-use std::{fmt, iter::FromIterator, sync::Arc};
+use std::{fmt, sync::Arc};
use hir::{ExpandResult, MacroFile};
use ide_db::base_db::{
@@ -29,7 +29,7 @@ fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Status**
+// | VS Code | **rust-analyzer: Status**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif[]
pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
index 3fb49b45d..50371d620 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -14,7 +14,7 @@ mod html;
mod tests;
use hir::{Name, Semantics};
-use ide_db::{FxHashMap, RootDatabase};
+use ide_db::{FxHashMap, RootDatabase, SymbolKind};
use syntax::{
ast, AstNode, AstToken, NodeOrToken, SyntaxKind::*, SyntaxNode, TextRange, WalkEvent, T,
};
@@ -24,7 +24,7 @@ use crate::{
escape::highlight_escape_string, format::highlight_format_string, highlights::Highlights,
macro_::MacroHighlighter, tags::Highlight,
},
- FileId, HlMod, HlTag,
+ FileId, HlMod, HlOperator, HlPunct, HlTag,
};
pub(crate) use html::highlight_as_html;
@@ -36,6 +36,26 @@ pub struct HlRange {
pub binding_hash: Option<u64>,
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct HighlightConfig {
+ /// Whether to highlight strings
+ pub strings: bool,
+ /// Whether to highlight punctuation
+ pub punctuation: bool,
+ /// Whether to specialize punctuation highlights
+ pub specialize_punctuation: bool,
+ /// Whether to highlight operator
+ pub operator: bool,
+ /// Whether to specialize operator highlights
+ pub specialize_operator: bool,
+ /// Whether to inject highlights into doc comments
+ pub inject_doc_comment: bool,
+ /// Whether to highlight the macro call bang
+ pub macro_bang: bool,
+ /// Whether to highlight unresolved things be their syntax
+ pub syntactic_name_ref_highlighting: bool,
+}
+
// Feature: Semantic Syntax Highlighting
//
// rust-analyzer highlights the code semantically.
@@ -155,9 +175,9 @@ pub struct HlRange {
// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
pub(crate) fn highlight(
db: &RootDatabase,
+ config: HighlightConfig,
file_id: FileId,
range_to_highlight: Option<TextRange>,
- syntactic_name_ref_highlighting: bool,
) -> Vec<HlRange> {
let _p = profile::span("highlight");
let sema = Semantics::new(db);
@@ -183,26 +203,18 @@ pub(crate) fn highlight(
Some(it) => it.krate(),
None => return hl.to_vec(),
};
- traverse(
- &mut hl,
- &sema,
- file_id,
- &root,
- krate,
- range_to_highlight,
- syntactic_name_ref_highlighting,
- );
+ traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight);
hl.to_vec()
}
fn traverse(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
+ config: HighlightConfig,
file_id: FileId,
root: &SyntaxNode,
krate: hir::Crate,
range_to_highlight: TextRange,
- syntactic_name_ref_highlighting: bool,
) {
let is_unlinked = sema.to_module_def(file_id).is_none();
let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default();
@@ -323,9 +335,11 @@ fn traverse(
Enter(it) => it,
Leave(NodeOrToken::Token(_)) => continue,
Leave(NodeOrToken::Node(node)) => {
- // Doc comment highlighting injection, we do this when leaving the node
- // so that we overwrite the highlighting of the doc comment itself.
- inject::doc_comment(hl, sema, file_id, &node);
+ if config.inject_doc_comment {
+ // Doc comment highlighting injection, we do this when leaving the node
+ // so that we overwrite the highlighting of the doc comment itself.
+ inject::doc_comment(hl, sema, config, file_id, &node);
+ }
continue;
}
};
@@ -400,7 +414,8 @@ fn traverse(
let string_to_highlight = ast::String::cast(descended_token.clone());
if let Some((string, expanded_string)) = string.zip(string_to_highlight) {
if string.is_raw() {
- if inject::ra_fixture(hl, sema, &string, &expanded_string).is_some() {
+ if inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some()
+ {
continue;
}
}
@@ -421,7 +436,7 @@ fn traverse(
sema,
krate,
&mut bindings_shadow_count,
- syntactic_name_ref_highlighting,
+ config.syntactic_name_ref_highlighting,
name_like,
),
NodeOrToken::Token(token) => highlight::token(sema, token).zip(Some(None)),
@@ -439,6 +454,29 @@ fn traverse(
// something unresolvable. FIXME: There should be a way to prevent that
continue;
}
+
+ // apply config filtering
+ match &mut highlight.tag {
+ HlTag::StringLiteral if !config.strings => continue,
+ // If punctuation is disabled, make the macro bang part of the macro call again.
+ tag @ HlTag::Punctuation(HlPunct::MacroBang) => {
+ if !config.macro_bang {
+ *tag = HlTag::Symbol(SymbolKind::Macro);
+ } else if !config.specialize_punctuation {
+ *tag = HlTag::Punctuation(HlPunct::Other);
+ }
+ }
+ HlTag::Punctuation(_) if !config.punctuation => continue,
+ tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
+ *tag = HlTag::Punctuation(HlPunct::Other);
+ }
+ HlTag::Operator(_) if !config.operator && highlight.mods.is_empty() => continue,
+ tag @ HlTag::Operator(_) if !config.specialize_operator => {
+ *tag = HlTag::Operator(HlOperator::Other);
+ }
+ _ => (),
+ }
+
if inside_attribute {
highlight |= HlMod::Attribute
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs
index 9777c014c..e91fd7f12 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs
@@ -5,7 +5,10 @@ use oorandom::Rand32;
use stdx::format_to;
use syntax::AstNode;
-use crate::{syntax_highlighting::highlight, FileId, RootDatabase};
+use crate::{
+ syntax_highlighting::{highlight, HighlightConfig},
+ FileId, RootDatabase,
+};
pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
let parse = db.parse(file_id);
@@ -20,7 +23,21 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
)
}
- let hl_ranges = highlight(db, file_id, None, false);
+ let hl_ranges = highlight(
+ db,
+ HighlightConfig {
+ strings: true,
+ punctuation: true,
+ specialize_punctuation: true,
+ specialize_operator: true,
+ operator: true,
+ inject_doc_comment: true,
+ macro_bang: true,
+ syntactic_name_ref_highlighting: false,
+ },
+ file_id,
+ None,
+ );
let text = parse.tree().syntax().to_string();
let mut buf = String::new();
buf.push_str(STYLE);
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
index f376f9fda..9139528c7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
@@ -15,13 +15,14 @@ use syntax::{
use crate::{
doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def},
- syntax_highlighting::{highlights::Highlights, injector::Injector},
+ syntax_highlighting::{highlights::Highlights, injector::Injector, HighlightConfig},
Analysis, HlMod, HlRange, HlTag, RootDatabase,
};
pub(super) fn ra_fixture(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
+ config: HighlightConfig,
literal: &ast::String,
expanded: &ast::String,
) -> Option<()> {
@@ -63,7 +64,13 @@ pub(super) fn ra_fixture(
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
- for mut hl_range in analysis.highlight(tmp_file_id).unwrap() {
+ for mut hl_range in analysis
+ .highlight(
+ HighlightConfig { syntactic_name_ref_highlighting: false, ..config },
+ tmp_file_id,
+ )
+ .unwrap()
+ {
for range in inj.map_range_up(hl_range.range) {
if let Some(range) = literal.map_range_up(range) {
hl_range.range = range;
@@ -86,6 +93,7 @@ const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
pub(super) fn doc_comment(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
+ config: HighlightConfig,
src_file_id: FileId,
node: &SyntaxNode,
) {
@@ -206,7 +214,14 @@ pub(super) fn doc_comment(
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
- if let Ok(ranges) = analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)) {
+ if let Ok(ranges) = analysis.with_db(|db| {
+ super::highlight(
+ db,
+ HighlightConfig { syntactic_name_ref_highlighting: true, ..config },
+ tmp_file_id,
+ None,
+ )
+ }) {
for HlRange { range, highlight, binding_hash } in ranges {
for range in inj.map_range_up(range) {
hl.add(HlRange { range, highlight: highlight | HlMod::Injected, binding_hash });
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs
index 5262770f3..3949f1189 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs
@@ -199,7 +199,7 @@ impl fmt::Display for HlTag {
}
impl HlMod {
- const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[
+ const ALL: &'static [HlMod; 19] = &[
HlMod::Associated,
HlMod::Async,
HlMod::Attribute,
@@ -296,7 +296,7 @@ impl Highlight {
Highlight { tag, mods: HlMods::default() }
}
pub fn is_empty(&self) -> bool {
- self.tag == HlTag::None && self.mods == HlMods::default()
+ self.tag == HlTag::None && self.mods.is_empty()
}
}
@@ -330,6 +330,10 @@ impl ops::BitOr<HlMod> for Highlight {
}
impl HlMods {
+ pub fn is_empty(&self) -> bool {
+ self.0 == 0
+ }
+
pub fn contains(self, m: HlMod) -> bool {
self.0 & m.mask() == m.mask()
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index a747b4bc1..eef5baea9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -56,7 +56,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="field declaration">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span><span class="comma">,</span>
<span class="brace">}</span>
-<span class="comment documentation">/// This is an impl with a code block.</span>
+<span class="comment documentation">/// This is an impl of </span><span class="struct documentation injected intra_doc_link">[`Foo`]</span><span class="comment documentation"> with a code block.</span>
<span class="comment documentation">///</span>
<span class="comment documentation">/// ```</span>
<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">foo</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
index 99be7c664..46cc667fc 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
@@ -4,7 +4,18 @@ use expect_test::{expect_file, ExpectFile};
use ide_db::SymbolKind;
use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear};
-use crate::{fixture, FileRange, HlTag, TextRange};
+use crate::{fixture, FileRange, HighlightConfig, HlTag, TextRange};
+
+const HL_CONFIG: HighlightConfig = HighlightConfig {
+ strings: true,
+ punctuation: true,
+ specialize_punctuation: true,
+ specialize_operator: true,
+ operator: true,
+ inject_doc_comment: true,
+ macro_bang: true,
+ syntactic_name_ref_highlighting: false,
+};
#[test]
fn attributes() {
@@ -613,7 +624,7 @@ struct Foo {
bar: bool,
}
-/// This is an impl with a code block.
+/// This is an impl of [`Foo`] with a code block.
///
/// ```
/// fn foo() {
@@ -958,7 +969,7 @@ pub struct Struct;
#[test]
#[cfg_attr(
- all(unix, not(target_pointer_width = "64")),
+ not(all(unix, target_pointer_width = "64")),
ignore = "depends on `DefaultHasher` outputs"
)]
fn test_rainbow_highlighting() {
@@ -996,7 +1007,10 @@ struct Foo {
// The "x"
let highlights = &analysis
- .highlight_range(FileRange { file_id, range: TextRange::at(45.into(), 1.into()) })
+ .highlight_range(
+ HL_CONFIG,
+ FileRange { file_id, range: TextRange::at(45.into(), 1.into()) },
+ )
.unwrap();
assert_eq!(&highlights[0].highlight.to_string(), "field.declaration.public");
@@ -1011,7 +1025,7 @@ macro_rules! test {}
}"#
.trim(),
);
- let _ = analysis.highlight(file_id).unwrap();
+ let _ = analysis.highlight(HL_CONFIG, file_id).unwrap();
}
/// Highlights the code given by the `ra_fixture` argument, renders the
@@ -1035,7 +1049,7 @@ fn benchmark_syntax_highlighting_long_struct() {
let hash = {
let _pt = bench("syntax highlighting long struct");
analysis
- .highlight(file_id)
+ .highlight(HL_CONFIG, file_id)
.unwrap()
.iter()
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
@@ -1061,7 +1075,7 @@ fn syntax_highlighting_not_quadratic() {
let time = Instant::now();
let hash = analysis
- .highlight(file_id)
+ .highlight(HL_CONFIG, file_id)
.unwrap()
.iter()
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
@@ -1086,7 +1100,7 @@ fn benchmark_syntax_highlighting_parser() {
let hash = {
let _pt = bench("syntax highlighting parser");
analysis
- .highlight(file_id)
+ .highlight(HL_CONFIG, file_id)
.unwrap()
.iter()
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function))
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
index 9003e7cd3..4256fea0f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
@@ -12,7 +12,7 @@ use syntax::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Show Syntax Tree**
+// | VS Code | **rust-analyzer: Show Syntax Tree**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065586-068bdb80-91b1-11eb-9507-fee67f9f45a0.gif[]
pub(crate) fn syntax_tree(
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
index 51291a645..17a1e385b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
@@ -3,8 +3,9 @@ use std::sync::Arc;
use dot::{Id, LabelText};
use ide_db::{
base_db::{CrateGraph, CrateId, Dependency, SourceDatabase, SourceDatabaseExt},
- FxHashSet, RootDatabase,
+ RootDatabase,
};
+use stdx::hash::NoHashHashSet;
// Feature: View Crate Graph
//
@@ -16,7 +17,7 @@ use ide_db::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: View Crate Graph**
+// | VS Code | **rust-analyzer: View Crate Graph**
// |===
pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String, String> {
let crate_graph = db.crate_graph();
@@ -41,7 +42,7 @@ pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String,
struct DotCrateGraph {
graph: Arc<CrateGraph>,
- crates_to_render: FxHashSet<CrateId>,
+ crates_to_render: NoHashHashSet<CrateId>,
}
type Edge<'a> = (CrateId, &'a Dependency);
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
index 7312afe53..d2bbbf6d2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
@@ -1,4 +1,4 @@
-use hir::{Function, Semantics};
+use hir::{DefWithBody, Semantics};
use ide_db::base_db::FilePosition;
use ide_db::RootDatabase;
use syntax::{algo::find_node_at_offset, ast, AstNode};
@@ -8,7 +8,7 @@ use syntax::{algo::find_node_at_offset, ast, AstNode};
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: View Hir**
+// | VS Code | **rust-analyzer: View Hir**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif[]
pub(crate) fn view_hir(db: &RootDatabase, position: FilePosition) -> String {
@@ -19,8 +19,12 @@ fn body_hir(db: &RootDatabase, position: FilePosition) -> Option<String> {
let sema = Semantics::new(db);
let source_file = sema.parse(position.file_id);
- let function = find_node_at_offset::<ast::Fn>(source_file.syntax(), position.offset)?;
-
- let function: Function = sema.to_def(&function)?;
- Some(function.debug_hir(db))
+ let item = find_node_at_offset::<ast::Item>(source_file.syntax(), position.offset)?;
+ let def: DefWithBody = match item {
+ ast::Item::Fn(it) => sema.to_def(&it)?.into(),
+ ast::Item::Const(it) => sema.to_def(&it)?.into(),
+ ast::Item::Static(it) => sema.to_def(&it)?.into(),
+ _ => return None,
+ };
+ Some(def.debug_hir(db))
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
index 3dc03085d..9c1f93356 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
@@ -9,7 +9,7 @@ use ide_db::RootDatabase;
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Debug ItemTree**
+// | VS Code | **rust-analyzer: Debug ItemTree**
// |===
pub(crate) fn view_item_tree(db: &RootDatabase, file_id: FileId) -> String {
db.file_item_tree(file_id.into()).pretty_print()
diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs
index 5020e9aba..c1aa14d6b 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs
@@ -321,7 +321,7 @@ struct MatchState<'t> {
/// The KleeneOp of this sequence if we are in a repetition.
sep_kind: Option<RepeatKind>,
- /// Number of tokens of seperator parsed
+ /// Number of tokens of separator parsed
sep_parsed: Option<usize>,
/// Matched meta variables bindings
diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
index aca6ecd42..e4c56565b 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
@@ -228,16 +228,7 @@ fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
}
let spacing = match conv.peek().map(|next| next.kind(conv)) {
- Some(kind)
- if !kind.is_trivia()
- && kind.is_punct()
- && kind != T!['[']
- && kind != T!['{']
- && kind != T!['(']
- && kind != UNDERSCORE =>
- {
- tt::Spacing::Joint
- }
+ Some(kind) if !kind.is_trivia() => tt::Spacing::Joint,
_ => tt::Spacing::Alone,
};
let char = match token.to_char(conv) {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
index e7402104e..dcaceade6 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
@@ -564,8 +564,10 @@ fn path_expr(p: &mut Parser<'_>, r: Restrictions) -> (CompletedMarker, BlockLike
// test record_lit
// fn foo() {
// S {};
+// S { x };
// S { x, y: 32, };
// S { x, y: 32, ..Default::default() };
+// S { x: ::default() };
// TupleStruct { 0: 1 };
// }
pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
@@ -582,16 +584,26 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
match p.current() {
IDENT | INT_NUMBER => {
- // test_err record_literal_before_ellipsis_recovery
+ // test_err record_literal_missing_ellipsis_recovery
// fn main() {
- // S { field ..S::default() }
+ // S { S::default() }
// }
- if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
- name_ref_or_index(p);
- p.expect(T![:]);
+ if p.nth_at(1, T![::]) {
+ m.abandon(p);
+ p.expect(T![..]);
+ expr(p);
+ } else {
+ // test_err record_literal_before_ellipsis_recovery
+ // fn main() {
+ // S { field ..S::default() }
+ // }
+ if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
+ name_ref_or_index(p);
+ p.expect(T![:]);
+ }
+ expr(p);
+ m.complete(p, RECORD_EXPR_FIELD);
}
- expr(p);
- m.complete(p, RECORD_EXPR_FIELD);
}
T![.] if p.at(T![..]) => {
m.abandon(p);
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
index 8de5d33a1..5dc9c6c82 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
@@ -118,6 +118,11 @@ fn opt_path_type_args(p: &mut Parser<'_>, mode: Mode) {
match mode {
Mode::Use => {}
Mode::Type => {
+ // test typepathfn_with_coloncolon
+ // type F = Start::(Middle) -> (Middle)::End;
+ if p.at(T![::]) && p.nth_at(2, T!['(']) {
+ p.bump(T![::]);
+ }
// test path_fn_trait_args
// type F = Box<Fn(i32) -> ()>;
if p.at(T!['(']) {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
index 4cbf10306..bc1224af9 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
@@ -13,6 +13,8 @@ pub(super) const PATTERN_FIRST: TokenSet =
T![.],
]));
+const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]]));
+
pub(crate) fn pattern(p: &mut Parser<'_>) {
pattern_r(p, PAT_RECOVERY_SET);
}
@@ -75,6 +77,16 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
// Some(1..) => ()
// }
//
+ // match () {
+ // S { a: 0 } => (),
+ // S { a: 1.. } => (),
+ // }
+ //
+ // match () {
+ // [0] => (),
+ // [1..] => (),
+ // }
+ //
// match (10 as u8, 5 as u8) {
// (0, _) => (),
// (1.., _) => ()
@@ -88,11 +100,27 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
let m = lhs.precede(p);
p.bump(range_op);
- // `0 .. =>` or `let 0 .. =` or `Some(0 .. )`
- // ^ ^ ^
- if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) {
+ // testing if we're at one of the following positions:
+ // `0 .. =>`
+ // ^
+ // `let 0 .. =`
+ // ^
+ // `let 0..: _ =`
+ // ^
+ // (1.., _)
+ // ^
+ // `Some(0 .. )`
+ // ^
+ // `S { t: 0.. }`
+ // ^
+ // `[0..]`
+ // ^
+ if matches!(p.current(), T![=] | T![,] | T![:] | T![')'] | T!['}'] | T![']']) {
// test half_open_range_pat
- // fn f() { let 0 .. = 1u32; }
+ // fn f() {
+ // let 0 .. = 1u32;
+ // let 0..: _ = 1u32;
+ // }
} else {
atom_pat(p, recovery_set);
}
@@ -202,6 +230,7 @@ fn path_or_macro_pat(p: &mut Parser<'_>) -> CompletedMarker {
// let S(_) = ();
// let S(_,) = ();
// let S(_, .. , x) = ();
+// let S(| a) = ();
// }
fn tuple_pat_fields(p: &mut Parser<'_>) {
assert!(p.at(T!['(']));
@@ -337,6 +366,7 @@ fn ref_pat(p: &mut Parser<'_>) -> CompletedMarker {
// let (a,) = ();
// let (..) = ();
// let () = ();
+// let (| a | a, | b) = ((),());
// }
fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(T!['(']));
@@ -347,13 +377,13 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
let mut has_rest = false;
while !p.at(EOF) && !p.at(T![')']) {
has_pat = true;
- if !p.at_ts(PATTERN_FIRST) {
+ if !p.at_ts(PAT_TOP_FIRST) {
p.error("expected a pattern");
break;
}
has_rest |= p.at(T![..]);
- pattern(p);
+ pattern_top(p);
if !p.at(T![')']) {
has_comma = true;
p.expect(T![,]);
@@ -367,6 +397,7 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
// test slice_pat
// fn main() {
// let [a, b, ..] = [];
+// let [| a, ..] = [];
// }
fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(T!['[']));
@@ -379,12 +410,12 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
while !p.at(EOF) && !p.at(ket) {
- if !p.at_ts(PATTERN_FIRST) {
+ if !p.at_ts(PAT_TOP_FIRST) {
p.error("expected a pattern");
break;
}
- pattern(p);
+ pattern_top(p);
if !p.at(ket) {
p.expect(T![,]);
}
diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
index 628fa745e..c84f45f1f 100644
--- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
@@ -262,33 +262,117 @@ pub enum SyntaxKind {
use self::SyntaxKind::*;
impl SyntaxKind {
pub fn is_keyword(self) -> bool {
- match self {
- AS_KW | ASYNC_KW | AWAIT_KW | BOX_KW | BREAK_KW | CONST_KW | CONTINUE_KW | CRATE_KW
- | DYN_KW | ELSE_KW | ENUM_KW | EXTERN_KW | FALSE_KW | FN_KW | FOR_KW | IF_KW
- | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW
- | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | SELF_TYPE_KW | STATIC_KW
- | STRUCT_KW | SUPER_KW | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW
- | WHERE_KW | WHILE_KW | YIELD_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW
- | RAW_KW | MACRO_RULES_KW => true,
- _ => false,
- }
+ matches!(
+ self,
+ AS_KW
+ | ASYNC_KW
+ | AWAIT_KW
+ | BOX_KW
+ | BREAK_KW
+ | CONST_KW
+ | CONTINUE_KW
+ | CRATE_KW
+ | DYN_KW
+ | ELSE_KW
+ | ENUM_KW
+ | EXTERN_KW
+ | FALSE_KW
+ | FN_KW
+ | FOR_KW
+ | IF_KW
+ | IMPL_KW
+ | IN_KW
+ | LET_KW
+ | LOOP_KW
+ | MACRO_KW
+ | MATCH_KW
+ | MOD_KW
+ | MOVE_KW
+ | MUT_KW
+ | PUB_KW
+ | REF_KW
+ | RETURN_KW
+ | SELF_KW
+ | SELF_TYPE_KW
+ | STATIC_KW
+ | STRUCT_KW
+ | SUPER_KW
+ | TRAIT_KW
+ | TRUE_KW
+ | TRY_KW
+ | TYPE_KW
+ | UNSAFE_KW
+ | USE_KW
+ | WHERE_KW
+ | WHILE_KW
+ | YIELD_KW
+ | AUTO_KW
+ | DEFAULT_KW
+ | EXISTENTIAL_KW
+ | UNION_KW
+ | RAW_KW
+ | MACRO_RULES_KW
+ )
}
pub fn is_punct(self) -> bool {
- match self {
- SEMICOLON | COMMA | L_PAREN | R_PAREN | L_CURLY | R_CURLY | L_BRACK | R_BRACK
- | L_ANGLE | R_ANGLE | AT | POUND | TILDE | QUESTION | DOLLAR | AMP | PIPE | PLUS
- | STAR | SLASH | CARET | PERCENT | UNDERSCORE | DOT | DOT2 | DOT3 | DOT2EQ | COLON
- | COLON2 | EQ | EQ2 | FAT_ARROW | BANG | NEQ | MINUS | THIN_ARROW | LTEQ | GTEQ
- | PLUSEQ | MINUSEQ | PIPEEQ | AMPEQ | CARETEQ | SLASHEQ | STAREQ | PERCENTEQ | AMP2
- | PIPE2 | SHL | SHR | SHLEQ | SHREQ => true,
- _ => false,
- }
+ matches!(
+ self,
+ SEMICOLON
+ | COMMA
+ | L_PAREN
+ | R_PAREN
+ | L_CURLY
+ | R_CURLY
+ | L_BRACK
+ | R_BRACK
+ | L_ANGLE
+ | R_ANGLE
+ | AT
+ | POUND
+ | TILDE
+ | QUESTION
+ | DOLLAR
+ | AMP
+ | PIPE
+ | PLUS
+ | STAR
+ | SLASH
+ | CARET
+ | PERCENT
+ | UNDERSCORE
+ | DOT
+ | DOT2
+ | DOT3
+ | DOT2EQ
+ | COLON
+ | COLON2
+ | EQ
+ | EQ2
+ | FAT_ARROW
+ | BANG
+ | NEQ
+ | MINUS
+ | THIN_ARROW
+ | LTEQ
+ | GTEQ
+ | PLUSEQ
+ | MINUSEQ
+ | PIPEEQ
+ | AMPEQ
+ | CARETEQ
+ | SLASHEQ
+ | STAREQ
+ | PERCENTEQ
+ | AMP2
+ | PIPE2
+ | SHL
+ | SHR
+ | SHLEQ
+ | SHREQ
+ )
}
pub fn is_literal(self) -> bool {
- match self {
- INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE | STRING | BYTE_STRING => true,
- _ => false,
- }
+ matches!(self, INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE | STRING | BYTE_STRING)
}
pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
let kw = match ident {
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
new file mode 100644
index 000000000..0c5b618e6
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
@@ -0,0 +1,43 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "main"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ RECORD_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ CALL_EXPR
+ PATH_EXPR
+ PATH
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ COLON2 "::"
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "default"
+ ARG_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ R_CURLY "}"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
+error 19: expected DOT2
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
new file mode 100644
index 000000000..1b594e8ab
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
@@ -0,0 +1,3 @@
+fn main() {
+ S { S::default() }
+}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast
index 235a9d7f4..dff72ba88 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast
@@ -37,6 +37,29 @@ SOURCE_FILE
L_BRACK "["
R_BRACK "]"
SEMICOLON ";"
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ SLICE_PAT
+ L_BRACK "["
+ PIPE "|"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "a"
+ COMMA ","
+ WHITESPACE " "
+ REST_PAT
+ DOT2 ".."
+ R_BRACK "]"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ ARRAY_EXPR
+ L_BRACK "["
+ R_BRACK "]"
+ SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs
index 7955973b9..855ba89b1 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs
@@ -1,3 +1,4 @@
fn main() {
let [a, b, ..] = [];
+ let [| a, ..] = [];
}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast
index 3cdaf32b5..55baf2fdc 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast
@@ -100,6 +100,29 @@ SOURCE_FILE
L_PAREN "("
R_PAREN ")"
SEMICOLON ";"
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ TUPLE_STRUCT_PAT
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ L_PAREN "("
+ PIPE "|"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "a"
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs
index 0dfe63629..8ec6f4ca9 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs
@@ -3,4 +3,5 @@ fn foo() {
let S(_) = ();
let S(_,) = ();
let S(_, .. , x) = ();
+ let S(| a) = ();
}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
index 44c967e8d..cfef5d3f9 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
@@ -172,6 +172,122 @@ SOURCE_FILE
WHITESPACE "\n "
R_CURLY "}"
WHITESPACE "\n\n "
+ EXPR_STMT
+ MATCH_EXPR
+ MATCH_KW "match"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ MATCH_ARM_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ MATCH_ARM
+ RECORD_PAT
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_PAT_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ RECORD_PAT_FIELD
+ NAME_REF
+ IDENT "a"
+ COLON ":"
+ WHITESPACE " "
+ LITERAL_PAT
+ LITERAL
+ INT_NUMBER "0"
+ WHITESPACE " "
+ R_CURLY "}"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ RECORD_PAT
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_PAT_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ RECORD_PAT_FIELD
+ NAME_REF
+ IDENT "a"
+ COLON ":"
+ WHITESPACE " "
+ RANGE_PAT
+ LITERAL_PAT
+ LITERAL
+ INT_NUMBER "1"
+ DOT2 ".."
+ WHITESPACE " "
+ R_CURLY "}"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ R_CURLY "}"
+ WHITESPACE "\n\n "
+ EXPR_STMT
+ MATCH_EXPR
+ MATCH_KW "match"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ MATCH_ARM_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ MATCH_ARM
+ SLICE_PAT
+ L_BRACK "["
+ LITERAL_PAT
+ LITERAL
+ INT_NUMBER "0"
+ R_BRACK "]"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ SLICE_PAT
+ L_BRACK "["
+ RANGE_PAT
+ LITERAL_PAT
+ LITERAL
+ INT_NUMBER "1"
+ DOT2 ".."
+ R_BRACK "]"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ R_CURLY "}"
+ WHITESPACE "\n\n "
MATCH_EXPR
MATCH_KW "match"
WHITESPACE " "
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
index 6c586a895..2411d5109 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
@@ -11,6 +11,16 @@ fn main() {
Some(1..) => ()
}
+ match () {
+ S { a: 0 } => (),
+ S { a: 1.. } => (),
+ }
+
+ match () {
+ [0] => (),
+ [1..] => (),
+ }
+
match (10 as u8, 5 as u8) {
(0, _) => (),
(1.., _) => ()
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
index 9997d0ae3..00948c322 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
@@ -40,6 +40,26 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "x"
+ WHITESPACE " "
+ R_CURLY "}"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ EXPR_STMT
+ RECORD_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "x"
COMMA ","
WHITESPACE " "
RECORD_EXPR_FIELD
@@ -105,6 +125,35 @@ SOURCE_FILE
PATH
PATH_SEGMENT
NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD
+ NAME_REF
+ IDENT "x"
+ COLON ":"
+ WHITESPACE " "
+ CALL_EXPR
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ COLON2 "::"
+ NAME_REF
+ IDENT "default"
+ ARG_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ R_CURLY "}"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ EXPR_STMT
+ RECORD_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
IDENT "TupleStruct"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
index 6285e5549..86411fbb7 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
@@ -1,6 +1,8 @@
fn foo() {
S {};
+ S { x };
S { x, y: 32, };
S { x, y: 32, ..Default::default() };
+ S { x: ::default() };
TupleStruct { 0: 1 };
}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast
index cebe98c43..1a01e0f69 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast
@@ -85,6 +85,46 @@ SOURCE_FILE
L_PAREN "("
R_PAREN ")"
SEMICOLON ";"
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ TUPLE_PAT
+ L_PAREN "("
+ PIPE "|"
+ WHITESPACE " "
+ OR_PAT
+ IDENT_PAT
+ NAME
+ IDENT "a"
+ WHITESPACE " "
+ PIPE "|"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "a"
+ COMMA ","
+ WHITESPACE " "
+ PIPE "|"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "b"
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ R_PAREN ")"
+ SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs
index ba719879d..fbd7f48f6 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs
@@ -3,4 +3,5 @@ fn main() {
let (a,) = ();
let (..) = ();
let () = ();
+ let (| a | a, | b) = ((),());
}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
index 3d3587a70..4b401b60d 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
@@ -11,7 +11,7 @@ SOURCE_FILE
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
- WHITESPACE " "
+ WHITESPACE "\n "
LET_STMT
LET_KW "let"
WHITESPACE " "
@@ -27,6 +27,25 @@ SOURCE_FILE
LITERAL
INT_NUMBER "1u32"
SEMICOLON ";"
- WHITESPACE " "
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ RANGE_PAT
+ LITERAL_PAT
+ LITERAL
+ INT_NUMBER "0"
+ DOT2 ".."
+ COLON ":"
+ WHITESPACE " "
+ INFER_TYPE
+ UNDERSCORE "_"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ LITERAL
+ INT_NUMBER "1u32"
+ SEMICOLON ";"
+ WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
index 1360eda05..c9386a221 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
@@ -1 +1,4 @@
-fn f() { let 0 .. = 1u32; }
+fn f() {
+ let 0 .. = 1u32;
+ let 0..: _ = 1u32;
+}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast
new file mode 100644
index 000000000..b47a5a5c1
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast
@@ -0,0 +1,43 @@
+SOURCE_FILE
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "F"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Start"
+ COLON2 "::"
+ PARAM_LIST
+ L_PAREN "("
+ PARAM
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Middle"
+ R_PAREN ")"
+ WHITESPACE " "
+ RET_TYPE
+ THIN_ARROW "->"
+ WHITESPACE " "
+ PAREN_TYPE
+ L_PAREN "("
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Middle"
+ R_PAREN ")"
+ COLON2 "::"
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "End"
+ SEMICOLON ";"
+ WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs
new file mode 100644
index 000000000..8efd93a7f
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs
@@ -0,0 +1 @@
+type F = Start::(Middle) -> (Middle)::End;
diff --git a/src/tools/rust-analyzer/crates/paths/src/lib.rs b/src/tools/rust-analyzer/crates/paths/src/lib.rs
index 025093f4a..6ae23ac84 100644
--- a/src/tools/rust-analyzer/crates/paths/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/paths/src/lib.rs
@@ -106,6 +106,14 @@ impl AsRef<Path> for AbsPath {
}
}
+impl ToOwned for AbsPath {
+ type Owned = AbsPathBuf;
+
+ fn to_owned(&self) -> Self::Owned {
+ AbsPathBuf(self.0.to_owned())
+ }
+}
+
impl<'a> TryFrom<&'a Path> for &'a AbsPath {
type Error = &'a Path;
fn try_from(path: &'a Path) -> Result<&'a AbsPath, &'a Path> {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
index d7010e825..a3ea05f4a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
@@ -60,7 +60,7 @@ impl MacroDylib {
let info = version::read_dylib_info(&path)?;
if info.version.0 < 1 || info.version.1 < 47 {
- let msg = format!("proc-macro {} built by {:#?} is not supported by Rust Analyzer, please update your rust version.", path.display(), info);
+ let msg = format!("proc-macro {} built by {:#?} is not supported by rust-analyzer, please update your Rust version.", path.display(), info);
return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
index 8437444e1..268a03bb5 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
@@ -35,10 +35,7 @@
//! as we don't have bincode in Cargo.toml yet, lets stick with serde_json for
//! the time being.
-use std::{
- collections::{HashMap, VecDeque},
- convert::TryInto,
-};
+use std::collections::{HashMap, VecDeque};
use serde::{Deserialize, Serialize};
use tt::TokenId;
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index 5746eac0b..e39026ac7 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -24,7 +24,6 @@ tt = { path = "../tt", version = "0.0.0" }
mbe = { path = "../mbe", version = "0.0.0" }
paths = { path = "../paths", version = "0.0.0" }
proc-macro-api = { path = "../proc-macro-api", version = "0.0.0" }
-crossbeam = "0.8.1"
[dev-dependencies]
expect-test = "1.4.0"
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
index 4a07f2277..a405497f3 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
@@ -157,7 +157,7 @@ impl From<TokenTree> for TokenStream {
}
/// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
trees.into_iter().map(TokenStream::from).collect()
}
@@ -165,7 +165,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
/// A "flattening" operation on token streams, collects token trees
/// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
let mut builder = bridge::client::TokenStreamBuilder::new();
streams.into_iter().for_each(|stream| builder.push(stream.0));
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
index ebdfca00d..b1e982f47 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
use std::collections::HashMap;
use std::hash::Hash;
-use std::iter::FromIterator;
use std::ops::Bound;
use std::{ascii, vec::IntoIter};
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
index c50a16bf4..7ab1f421d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
@@ -207,7 +207,7 @@ impl ConcatStreamsHelper {
}
/// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
trees.into_iter().map(TokenStream::from).collect()
}
@@ -215,7 +215,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
/// A "flattening" operation on token streams, collects token trees
/// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
let iter = streams.into_iter();
let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
index 05a565fbf..ed49cc759 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
use std::collections::HashMap;
use std::hash::Hash;
-use std::iter::FromIterator;
use std::ops::Bound;
use std::{ascii, vec::IntoIter};
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
deleted file mode 100644
index 9d56f0eaf..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-//! Proc macro ABI.
-
-#[allow(dead_code)]
-#[doc(hidden)]
-mod proc_macro;
-
-#[allow(dead_code)]
-#[doc(hidden)]
-mod ra_server;
-
-use libloading::Library;
-use proc_macro_api::ProcMacroKind;
-
-use super::PanicMessage;
-
-pub use ra_server::TokenStream;
-
-pub(crate) struct Abi {
- exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
-}
-
-impl From<proc_macro::bridge::PanicMessage> for PanicMessage {
- fn from(p: proc_macro::bridge::PanicMessage) -> Self {
- Self { message: p.as_str().map(|s| s.to_string()) }
- }
-}
-
-impl Abi {
- pub unsafe fn from_lib(lib: &Library, symbol_name: String) -> Result<Abi, libloading::Error> {
- let macros: libloading::Symbol<'_, &&[proc_macro::bridge::client::ProcMacro]> =
- lib.get(symbol_name.as_bytes())?;
- Ok(Self { exported_macros: macros.to_vec() })
- }
-
- pub fn expand(
- &self,
- macro_name: &str,
- macro_body: &tt::Subtree,
- attributes: Option<&tt::Subtree>,
- ) -> Result<tt::Subtree, PanicMessage> {
- let parsed_body = TokenStream::with_subtree(macro_body.clone());
-
- let parsed_attributes =
- attributes.map_or(TokenStream::new(), |attr| TokenStream::with_subtree(attr.clone()));
-
- for proc_macro in &self.exported_macros {
- match proc_macro {
- proc_macro::bridge::client::ProcMacro::CustomDerive {
- trait_name, client, ..
- } if *trait_name == macro_name => {
- let res = client.run(
- &proc_macro::bridge::server::SameThread,
- ra_server::RustAnalyzer::default(),
- parsed_body,
- true,
- );
- return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
- }
- proc_macro::bridge::client::ProcMacro::Bang { name, client }
- if *name == macro_name =>
- {
- let res = client.run(
- &proc_macro::bridge::server::SameThread,
- ra_server::RustAnalyzer::default(),
- parsed_body,
- true,
- );
- return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
- }
- proc_macro::bridge::client::ProcMacro::Attr { name, client }
- if *name == macro_name =>
- {
- let res = client.run(
- &proc_macro::bridge::server::SameThread,
- ra_server::RustAnalyzer::default(),
- parsed_attributes,
- parsed_body,
- true,
- );
- return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
- }
- _ => continue,
- }
- }
-
- Err(proc_macro::bridge::PanicMessage::String("Nothing to expand".to_string()).into())
- }
-
- pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
- self.exported_macros
- .iter()
- .map(|proc_macro| match proc_macro {
- proc_macro::bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
- (trait_name.to_string(), ProcMacroKind::CustomDerive)
- }
- proc_macro::bridge::client::ProcMacro::Bang { name, .. } => {
- (name.to_string(), ProcMacroKind::FuncLike)
- }
- proc_macro::bridge::client::ProcMacro::Attr { name, .. } => {
- (name.to_string(), ProcMacroKind::Attr)
- }
- })
- .collect()
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
deleted file mode 100644
index 48030f8d8..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-//! Buffer management for same-process client<->server communication.
-
-use std::io::{self, Write};
-use std::mem;
-use std::ops::{Deref, DerefMut};
-use std::slice;
-
-#[repr(C)]
-pub struct Buffer {
- data: *mut u8,
- len: usize,
- capacity: usize,
- reserve: extern "C" fn(Buffer, usize) -> Buffer,
- drop: extern "C" fn(Buffer),
-}
-
-unsafe impl Sync for Buffer {}
-unsafe impl Send for Buffer {}
-
-impl Default for Buffer {
- #[inline]
- fn default() -> Self {
- Self::from(vec![])
- }
-}
-
-impl Deref for Buffer {
- type Target = [u8];
- #[inline]
- fn deref(&self) -> &[u8] {
- unsafe { slice::from_raw_parts(self.data as *const u8, self.len) }
- }
-}
-
-impl DerefMut for Buffer {
- #[inline]
- fn deref_mut(&mut self) -> &mut [u8] {
- unsafe { slice::from_raw_parts_mut(self.data, self.len) }
- }
-}
-
-impl Buffer {
- #[inline]
- pub(super) fn new() -> Self {
- Self::default()
- }
-
- #[inline]
- pub(super) fn clear(&mut self) {
- self.len = 0;
- }
-
- #[inline]
- pub(super) fn take(&mut self) -> Self {
- mem::take(self)
- }
-
- // We have the array method separate from extending from a slice. This is
- // because in the case of small arrays, codegen can be more efficient
- // (avoiding a memmove call). With extend_from_slice, LLVM at least
- // currently is not able to make that optimization.
- #[inline]
- pub(super) fn extend_from_array<const N: usize>(&mut self, xs: &[u8; N]) {
- if xs.len() > (self.capacity - self.len) {
- let b = self.take();
- *self = (b.reserve)(b, xs.len());
- }
- unsafe {
- xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
- self.len += xs.len();
- }
- }
-
- #[inline]
- pub(super) fn extend_from_slice(&mut self, xs: &[u8]) {
- if xs.len() > (self.capacity - self.len) {
- let b = self.take();
- *self = (b.reserve)(b, xs.len());
- }
- unsafe {
- xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
- self.len += xs.len();
- }
- }
-
- #[inline]
- pub(super) fn push(&mut self, v: u8) {
- // The code here is taken from Vec::push, and we know that reserve()
- // will panic if we're exceeding isize::MAX bytes and so there's no need
- // to check for overflow.
- if self.len == self.capacity {
- let b = self.take();
- *self = (b.reserve)(b, 1);
- }
- unsafe {
- *self.data.add(self.len) = v;
- self.len += 1;
- }
- }
-}
-
-impl Write for Buffer {
- #[inline]
- fn write(&mut self, xs: &[u8]) -> io::Result<usize> {
- self.extend_from_slice(xs);
- Ok(xs.len())
- }
-
- #[inline]
- fn write_all(&mut self, xs: &[u8]) -> io::Result<()> {
- self.extend_from_slice(xs);
- Ok(())
- }
-
- #[inline]
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-impl Drop for Buffer {
- #[inline]
- fn drop(&mut self) {
- let b = self.take();
- (b.drop)(b);
- }
-}
-
-impl From<Vec<u8>> for Buffer {
- fn from(mut v: Vec<u8>) -> Self {
- let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity());
- mem::forget(v);
-
- // This utility function is nested in here because it can *only*
- // be safely called on `Buffer`s created by *this* `proc_macro`.
- fn to_vec(b: Buffer) -> Vec<u8> {
- unsafe {
- let Buffer { data, len, capacity, .. } = b;
- mem::forget(b);
- Vec::from_raw_parts(data, len, capacity)
- }
- }
-
- extern "C" fn reserve(b: Buffer, additional: usize) -> Buffer {
- let mut v = to_vec(b);
- v.reserve(additional);
- Buffer::from(v)
- }
-
- extern "C" fn drop(b: Buffer) {
- mem::drop(to_vec(b));
- }
-
- Buffer { data, len, capacity, reserve, drop }
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
deleted file mode 100644
index 22bda8ba5..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
+++ /dev/null
@@ -1,529 +0,0 @@
-//! Client-side types.
-
-use super::*;
-
-use std::marker::PhantomData;
-
-macro_rules! define_handles {
- (
- 'owned: $($oty:ident,)*
- 'interned: $($ity:ident,)*
- ) => {
- #[repr(C)]
- #[allow(non_snake_case)]
- pub struct HandleCounters {
- $($oty: AtomicUsize,)*
- $($ity: AtomicUsize,)*
- }
-
- impl HandleCounters {
- // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
- // a wrapper `fn` pointer, once `const fn` can reference `static`s.
- extern "C" fn get() -> &'static Self {
- static COUNTERS: HandleCounters = HandleCounters {
- $($oty: AtomicUsize::new(1),)*
- $($ity: AtomicUsize::new(1),)*
- };
- &COUNTERS
- }
- }
-
- // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
- #[repr(C)]
- #[allow(non_snake_case)]
- pub(super) struct HandleStore<S: server::Types> {
- $($oty: handle::OwnedStore<S::$oty>,)*
- $($ity: handle::InternedStore<S::$ity>,)*
- }
-
- impl<S: server::Types> HandleStore<S> {
- pub(super) fn new(handle_counters: &'static HandleCounters) -> Self {
- HandleStore {
- $($oty: handle::OwnedStore::new(&handle_counters.$oty),)*
- $($ity: handle::InternedStore::new(&handle_counters.$ity),)*
- }
- }
- }
-
- $(
- #[repr(C)]
- pub(crate) struct $oty {
- handle: handle::Handle,
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
- // way of doing this, but that requires unstable features.
- // rust-analyzer uses this code and avoids unstable features.
- _marker: PhantomData<*mut ()>,
- }
-
- // Forward `Drop::drop` to the inherent `drop` method.
- impl Drop for $oty {
- fn drop(&mut self) {
- $oty {
- handle: self.handle,
- _marker: PhantomData,
- }.drop();
- }
- }
-
- impl<S> Encode<S> for $oty {
- fn encode(self, w: &mut Writer, s: &mut S) {
- let handle = self.handle;
- mem::forget(self);
- handle.encode(w, s);
- }
- }
-
- impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
- for Marked<S::$oty, $oty>
- {
- fn decode(r: &mut Reader<'_>, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
- s.$oty.take(handle::Handle::decode(r, &mut ()))
- }
- }
-
- impl<S> Encode<S> for &$oty {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.handle.encode(w, s);
- }
- }
-
- impl<'s, S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>>
- for &'s Marked<S::$oty, $oty>
- {
- fn decode(r: &mut Reader<'_>, s: &'s HandleStore<server::MarkedTypes<S>>) -> Self {
- &s.$oty[handle::Handle::decode(r, &mut ())]
- }
- }
-
- impl<S> Encode<S> for &mut $oty {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.handle.encode(w, s);
- }
- }
-
- impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>>
- for &'s mut Marked<S::$oty, $oty>
- {
- fn decode(
- r: &mut Reader<'_>,
- s: &'s mut HandleStore<server::MarkedTypes<S>>
- ) -> Self {
- &mut s.$oty[handle::Handle::decode(r, &mut ())]
- }
- }
-
- impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
- for Marked<S::$oty, $oty>
- {
- fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
- s.$oty.alloc(self).encode(w, s);
- }
- }
-
- impl<S> DecodeMut<'_, '_, S> for $oty {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- $oty {
- handle: handle::Handle::decode(r, s),
- _marker: PhantomData,
- }
- }
- }
- )*
-
- $(
- #[repr(C)]
- #[derive(Copy, Clone, PartialEq, Eq, Hash)]
- pub(crate) struct $ity {
- handle: handle::Handle,
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
- // way of doing this, but that requires unstable features.
- // rust-analyzer uses this code and avoids unstable features.
- _marker: PhantomData<*mut ()>,
- }
-
- impl<S> Encode<S> for $ity {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.handle.encode(w, s);
- }
- }
-
- impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
- for Marked<S::$ity, $ity>
- {
- fn decode(r: &mut Reader<'_>, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
- s.$ity.copy(handle::Handle::decode(r, &mut ()))
- }
- }
-
- impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
- for Marked<S::$ity, $ity>
- {
- fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
- s.$ity.alloc(self).encode(w, s);
- }
- }
-
- impl<S> DecodeMut<'_, '_, S> for $ity {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- $ity {
- handle: handle::Handle::decode(r, s),
- _marker: PhantomData,
- }
- }
- }
- )*
- }
-}
-define_handles! {
- 'owned:
- FreeFunctions,
- TokenStream,
- Literal,
- SourceFile,
- MultiSpan,
- Diagnostic,
-
- 'interned:
- Ident,
- Span,
-}
-
-// FIXME(eddyb) generate these impls by pattern-matching on the
-// names of methods - also could use the presence of `fn drop`
-// to distinguish between 'owned and 'interned, above.
-// Alternatively, special "modes" could be listed of types in with_api
-// instead of pattern matching on methods, here and in server decl.
-
-impl Clone for TokenStream {
- fn clone(&self) -> Self {
- self.clone()
- }
-}
-
-impl Clone for Literal {
- fn clone(&self) -> Self {
- self.clone()
- }
-}
-
-impl fmt::Debug for Literal {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Literal")
- // format the kind without quotes, as in `kind: Float`
- .field("kind", &format_args!("{}", &self.debug_kind()))
- .field("symbol", &self.symbol())
- // format `Some("...")` on one line even in {:#?} mode
- .field("suffix", &format_args!("{:?}", &self.suffix()))
- .field("span", &self.span())
- .finish()
- }
-}
-
-impl Clone for SourceFile {
- fn clone(&self) -> Self {
- self.clone()
- }
-}
-
-impl Span {
- pub(crate) fn def_site() -> Span {
- Bridge::with(|bridge| bridge.globals.def_site)
- }
-
- pub(crate) fn call_site() -> Span {
- Bridge::with(|bridge| bridge.globals.call_site)
- }
-
- pub(crate) fn mixed_site() -> Span {
- Bridge::with(|bridge| bridge.globals.mixed_site)
- }
-}
-
-impl fmt::Debug for Span {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.debug())
- }
-}
-
-macro_rules! define_client_side {
- ($($name:ident {
- $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
- }),* $(,)?) => {
- $(impl $name {
- $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)* {
- Bridge::with(|bridge| {
- let mut buf = bridge.cached_buffer.take();
-
- buf.clear();
- api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ());
- reverse_encode!(buf; $($arg),*);
-
- buf = bridge.dispatch.call(buf);
-
- let r = Result::<_, PanicMessage>::decode(&mut &buf[..], &mut ());
-
- bridge.cached_buffer = buf;
-
- r.unwrap_or_else(|e| panic::resume_unwind(e.into()))
- })
- })*
- })*
- }
-}
-with_api!(self, self, define_client_side);
-
-struct Bridge<'a> {
- /// Reusable buffer (only `clear`-ed, never shrunk), primarily
- /// used for making requests.
- cached_buffer: Buffer,
-
- /// Server-side function that the client uses to make requests.
- dispatch: closure::Closure<'a, Buffer, Buffer>,
-
- /// Provided globals for this macro expansion.
- globals: ExpnGlobals<Span>,
-}
-
-enum BridgeState<'a> {
- /// No server is currently connected to this client.
- NotConnected,
-
- /// A server is connected and available for requests.
- Connected(Bridge<'a>),
-
- /// Access to the bridge is being exclusively acquired
- /// (e.g., during `BridgeState::with`).
- InUse,
-}
-
-enum BridgeStateL {}
-
-impl<'a> scoped_cell::ApplyL<'a> for BridgeStateL {
- type Out = BridgeState<'a>;
-}
-
-thread_local! {
- static BRIDGE_STATE: scoped_cell::ScopedCell<BridgeStateL> =
- scoped_cell::ScopedCell::new(BridgeState::NotConnected);
-}
-
-impl BridgeState<'_> {
- /// Take exclusive control of the thread-local
- /// `BridgeState`, and pass it to `f`, mutably.
- /// The state will be restored after `f` exits, even
- /// by panic, including modifications made to it by `f`.
- ///
- /// N.B., while `f` is running, the thread-local state
- /// is `BridgeState::InUse`.
- fn with<R>(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R {
- BRIDGE_STATE.with(|state| {
- state.replace(BridgeState::InUse, |mut state| {
- // FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone
- f(&mut *state)
- })
- })
- }
-}
-
-impl Bridge<'_> {
- fn with<R>(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R {
- BridgeState::with(|state| match state {
- BridgeState::NotConnected => {
- panic!("procedural macro API is used outside of a procedural macro");
- }
- BridgeState::InUse => {
- panic!("procedural macro API is used while it's already in use");
- }
- BridgeState::Connected(bridge) => f(bridge),
- })
- }
-}
-
-pub(crate) fn is_available() -> bool {
- BridgeState::with(|state| match state {
- BridgeState::Connected(_) | BridgeState::InUse => true,
- BridgeState::NotConnected => false,
- })
-}
-
-/// A client-side RPC entry-point, which may be using a different `proc_macro`
-/// from the one used by the server, but can be invoked compatibly.
-///
-/// Note that the (phantom) `I` ("input") and `O` ("output") type parameters
-/// decorate the `Client<I, O>` with the RPC "interface" of the entry-point, but
-/// do not themselves participate in ABI, at all, only facilitate type-checking.
-///
-/// E.g. `Client<TokenStream, TokenStream>` is the common proc macro interface,
-/// used for `#[proc_macro] fn foo(input: TokenStream) -> TokenStream`,
-/// indicating that the RPC input and output will be serialized token streams,
-/// and forcing the use of APIs that take/return `S::TokenStream`, server-side.
-#[repr(C)]
-pub struct Client<I, O> {
- // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
- // a wrapper `fn` pointer, once `const fn` can reference `static`s.
- pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters,
-
- pub(super) run: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-
- pub(super) _marker: PhantomData<fn(I) -> O>,
-}
-
-impl<I, O> Copy for Client<I, O> {}
-impl<I, O> Clone for Client<I, O> {
- fn clone(&self) -> Self {
- *self
- }
-}
-
-fn maybe_install_panic_hook(force_show_panics: bool) {
- // Hide the default panic output within `proc_macro` expansions.
- // NB. the server can't do this because it may use a different libstd.
- static HIDE_PANICS_DURING_EXPANSION: Once = Once::new();
- HIDE_PANICS_DURING_EXPANSION.call_once(|| {
- let prev = panic::take_hook();
- panic::set_hook(Box::new(move |info| {
- let show = BridgeState::with(|state| match state {
- BridgeState::NotConnected => true,
- BridgeState::Connected(_) | BridgeState::InUse => force_show_panics,
- });
- if show {
- prev(info)
- }
- }));
- });
-}
-
-/// Client-side helper for handling client panics, entering the bridge,
-/// deserializing input and serializing output.
-// FIXME(eddyb) maybe replace `Bridge::enter` with this?
-fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
- config: BridgeConfig<'_>,
- f: impl FnOnce(A) -> R,
-) -> Buffer {
- let BridgeConfig { input: mut buf, dispatch, force_show_panics, .. } = config;
-
- panic::catch_unwind(panic::AssertUnwindSafe(|| {
- maybe_install_panic_hook(force_show_panics);
-
- let reader = &mut &buf[..];
- let (globals, input) = <(ExpnGlobals<Span>, A)>::decode(reader, &mut ());
-
- // Put the buffer we used for input back in the `Bridge` for requests.
- let new_state =
- BridgeState::Connected(Bridge { cached_buffer: buf.take(), dispatch, globals });
-
- BRIDGE_STATE.with(|state| {
- state.set(new_state, || {
- let output = f(input);
-
- // Take the `cached_buffer` back out, for the output value.
- buf = Bridge::with(|bridge| bridge.cached_buffer.take());
-
- // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
- // from encoding a panic (`Err(e: PanicMessage)`) to avoid
- // having handles outside the `bridge.enter(|| ...)` scope, and
- // to catch panics that could happen while encoding the success.
- //
- // Note that panics should be impossible beyond this point, but
- // this is defensively trying to avoid any accidental panicking
- // reaching the `extern "C"` (which should `abort` but might not
- // at the moment, so this is also potentially preventing UB).
- buf.clear();
- Ok::<_, ()>(output).encode(&mut buf, &mut ());
- })
- })
- }))
- .map_err(PanicMessage::from)
- .unwrap_or_else(|e| {
- buf.clear();
- Err::<(), _>(e).encode(&mut buf, &mut ());
- });
- buf
-}
-
-impl Client<super::super::TokenStream, super::super::TokenStream> {
- pub const fn expand1(
- f: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
- ) -> Self {
- Client {
- get_handle_counters: HandleCounters::get,
- run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| {
- run_client(bridge, |input| f(super::super::TokenStream(input)).0)
- }),
- _marker: PhantomData,
- }
- }
-}
-
-impl Client<(super::super::TokenStream, super::super::TokenStream), super::super::TokenStream> {
- pub const fn expand2(
- f: impl Fn(super::super::TokenStream, super::super::TokenStream) -> super::super::TokenStream
- + Copy,
- ) -> Self {
- Client {
- get_handle_counters: HandleCounters::get,
- run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| {
- run_client(bridge, |(input, input2)| {
- f(super::super::TokenStream(input), super::super::TokenStream(input2)).0
- })
- }),
- _marker: PhantomData,
- }
- }
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum ProcMacro {
- CustomDerive {
- trait_name: &'static str,
- attributes: &'static [&'static str],
- client: Client<super::super::TokenStream, super::super::TokenStream>,
- },
-
- Attr {
- name: &'static str,
- client: Client<
- (super::super::TokenStream, super::super::TokenStream),
- super::super::TokenStream,
- >,
- },
-
- Bang {
- name: &'static str,
- client: Client<super::super::TokenStream, super::super::TokenStream>,
- },
-}
-
-impl ProcMacro {
- pub fn name(&self) -> &'static str {
- match self {
- ProcMacro::CustomDerive { trait_name, .. } => trait_name,
- ProcMacro::Attr { name, .. } => name,
- ProcMacro::Bang { name, .. } => name,
- }
- }
-
- pub const fn custom_derive(
- trait_name: &'static str,
- attributes: &'static [&'static str],
- expand: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
- ) -> Self {
- ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) }
- }
-
- pub const fn attr(
- name: &'static str,
- expand: impl Fn(super::super::TokenStream, super::super::TokenStream) -> super::super::TokenStream
- + Copy,
- ) -> Self {
- ProcMacro::Attr { name, client: Client::expand2(expand) }
- }
-
- pub const fn bang(
- name: &'static str,
- expand: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
- ) -> Self {
- ProcMacro::Bang { name, client: Client::expand1(expand) }
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
deleted file mode 100644
index d371ae3ce..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-//! Closure type (equivalent to `&mut dyn FnMut(A) -> R`) that's `repr(C)`.
-
-use std::marker::PhantomData;
-
-#[repr(C)]
-pub struct Closure<'a, A, R> {
- call: unsafe extern "C" fn(*mut Env, A) -> R,
- env: *mut Env,
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
- // this, but that requires unstable features. rust-analyzer uses this code
- // and avoids unstable features.
- //
- // The `'a` lifetime parameter represents the lifetime of `Env`.
- _marker: PhantomData<*mut &'a mut ()>,
-}
-
-struct Env;
-
-impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> {
- fn from(f: &'a mut F) -> Self {
- unsafe extern "C" fn call<A, R, F: FnMut(A) -> R>(env: *mut Env, arg: A) -> R {
- (*(env as *mut _ as *mut F))(arg)
- }
- Closure { call: call::<A, R, F>, env: f as *mut _ as *mut Env, _marker: PhantomData }
- }
-}
-
-impl<'a, A, R> Closure<'a, A, R> {
- pub fn call(&mut self, arg: A) -> R {
- unsafe { (self.call)(self.env, arg) }
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
deleted file mode 100644
index c219a9465..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-//! Server-side handles and storage for per-handle data.
-
-use std::collections::{BTreeMap, HashMap};
-use std::hash::{BuildHasher, Hash};
-use std::num::NonZeroU32;
-use std::ops::{Index, IndexMut};
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-pub(super) type Handle = NonZeroU32;
-
-/// A store that associates values of type `T` with numeric handles. A value can
-/// be looked up using its handle.
-pub(super) struct OwnedStore<T: 'static> {
- counter: &'static AtomicUsize,
- data: BTreeMap<Handle, T>,
-}
-
-impl<T> OwnedStore<T> {
- pub(super) fn new(counter: &'static AtomicUsize) -> Self {
- // Ensure the handle counter isn't 0, which would panic later,
- // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`.
- assert_ne!(counter.load(Ordering::SeqCst), 0);
-
- OwnedStore { counter, data: BTreeMap::new() }
- }
-}
-
-impl<T> OwnedStore<T> {
- pub(super) fn alloc(&mut self, x: T) -> Handle {
- let counter = self.counter.fetch_add(1, Ordering::SeqCst);
- let handle = Handle::new(counter as u32).expect("`proc_macro` handle counter overflowed");
- assert!(self.data.insert(handle, x).is_none());
- handle
- }
-
- pub(super) fn take(&mut self, h: Handle) -> T {
- self.data.remove(&h).expect("use-after-free in `proc_macro` handle")
- }
-}
-
-impl<T> Index<Handle> for OwnedStore<T> {
- type Output = T;
- fn index(&self, h: Handle) -> &T {
- self.data.get(&h).expect("use-after-free in `proc_macro` handle")
- }
-}
-
-impl<T> IndexMut<Handle> for OwnedStore<T> {
- fn index_mut(&mut self, h: Handle) -> &mut T {
- self.data.get_mut(&h).expect("use-after-free in `proc_macro` handle")
- }
-}
-
-// HACK(eddyb) deterministic `std::collections::hash_map::RandomState` replacement
-// that doesn't require adding any dependencies to `proc_macro` (like `rustc-hash`).
-#[derive(Clone)]
-struct NonRandomState;
-
-impl BuildHasher for NonRandomState {
- type Hasher = std::collections::hash_map::DefaultHasher;
- #[inline]
- fn build_hasher(&self) -> Self::Hasher {
- Self::Hasher::new()
- }
-}
-
-/// Like `OwnedStore`, but avoids storing any value more than once.
-pub(super) struct InternedStore<T: 'static> {
- owned: OwnedStore<T>,
- interner: HashMap<T, Handle, NonRandomState>,
-}
-
-impl<T: Copy + Eq + Hash> InternedStore<T> {
- pub(super) fn new(counter: &'static AtomicUsize) -> Self {
- InternedStore {
- owned: OwnedStore::new(counter),
- interner: HashMap::with_hasher(NonRandomState),
- }
- }
-
- pub(super) fn alloc(&mut self, x: T) -> Handle {
- let owned = &mut self.owned;
- *self.interner.entry(x).or_insert_with(|| owned.alloc(x))
- }
-
- pub(super) fn copy(&mut self, h: Handle) -> T {
- self.owned[h]
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
deleted file mode 100644
index ffd440793..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
+++ /dev/null
@@ -1,493 +0,0 @@
-//! Internal interface for communicating between a `proc_macro` client
-//! (a proc macro crate) and a `proc_macro` server (a compiler front-end).
-//!
-//! Serialization (with C ABI buffers) and unique integer handles are employed
-//! to allow safely interfacing between two copies of `proc_macro` built
-//! (from the same source) by different compilers with potentially mismatching
-//! Rust ABIs (e.g., stage0/bin/rustc vs stage1/bin/rustc during bootstrap).
-
-#![deny(unsafe_code)]
-
-pub use super::{Delimiter, Level, LineColumn, Spacing};
-use std::fmt;
-use std::hash::Hash;
-use std::marker;
-use std::mem;
-use std::ops::Bound;
-use std::panic;
-use std::sync::atomic::AtomicUsize;
-use std::sync::Once;
-use std::thread;
-
-/// Higher-order macro describing the server RPC API, allowing automatic
-/// generation of type-safe Rust APIs, both client-side and server-side.
-///
-/// `with_api!(MySelf, my_self, my_macro)` expands to:
-/// ```rust,ignore (pseudo-code)
-/// my_macro! {
-/// // ...
-/// Literal {
-/// // ...
-/// fn character(ch: char) -> MySelf::Literal;
-/// // ...
-/// fn span(my_self: &MySelf::Literal) -> MySelf::Span;
-/// fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
-/// },
-/// // ...
-/// }
-/// ```
-///
-/// The first two arguments serve to customize the arguments names
-/// and argument/return types, to enable several different usecases:
-///
-/// If `my_self` is just `self`, then each `fn` signature can be used
-/// as-is for a method. If it's anything else (`self_` in practice),
-/// then the signatures don't have a special `self` argument, and
-/// can, therefore, have a different one introduced.
-///
-/// If `MySelf` is just `Self`, then the types are only valid inside
-/// a trait or a trait impl, where the trait has associated types
-/// for each of the API types. If non-associated types are desired,
-/// a module name (`self` in practice) can be used instead of `Self`.
-macro_rules! with_api {
- ($S:ident, $self:ident, $m:ident) => {
- $m! {
- FreeFunctions {
- fn drop($self: $S::FreeFunctions);
- fn track_env_var(var: &str, value: Option<&str>);
- fn track_path(path: &str);
- },
- TokenStream {
- fn drop($self: $S::TokenStream);
- fn clone($self: &$S::TokenStream) -> $S::TokenStream;
- fn is_empty($self: &$S::TokenStream) -> bool;
- fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>;
- fn from_str(src: &str) -> $S::TokenStream;
- fn to_string($self: &$S::TokenStream) -> String;
- fn from_token_tree(
- tree: TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>,
- ) -> $S::TokenStream;
- fn concat_trees(
- base: Option<$S::TokenStream>,
- trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>,
- ) -> $S::TokenStream;
- fn concat_streams(
- base: Option<$S::TokenStream>,
- streams: Vec<$S::TokenStream>,
- ) -> $S::TokenStream;
- fn into_trees(
- $self: $S::TokenStream
- ) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>;
- },
- Ident {
- fn new(string: &str, span: $S::Span, is_raw: bool) -> $S::Ident;
- fn span($self: $S::Ident) -> $S::Span;
- fn with_span($self: $S::Ident, span: $S::Span) -> $S::Ident;
- },
- Literal {
- fn drop($self: $S::Literal);
- fn clone($self: &$S::Literal) -> $S::Literal;
- fn from_str(s: &str) -> Result<$S::Literal, ()>;
- fn to_string($self: &$S::Literal) -> String;
- fn debug_kind($self: &$S::Literal) -> String;
- fn symbol($self: &$S::Literal) -> String;
- fn suffix($self: &$S::Literal) -> Option<String>;
- fn integer(n: &str) -> $S::Literal;
- fn typed_integer(n: &str, kind: &str) -> $S::Literal;
- fn float(n: &str) -> $S::Literal;
- fn f32(n: &str) -> $S::Literal;
- fn f64(n: &str) -> $S::Literal;
- fn string(string: &str) -> $S::Literal;
- fn character(ch: char) -> $S::Literal;
- fn byte_string(bytes: &[u8]) -> $S::Literal;
- fn span($self: &$S::Literal) -> $S::Span;
- fn set_span($self: &mut $S::Literal, span: $S::Span);
- fn subspan(
- $self: &$S::Literal,
- start: Bound<usize>,
- end: Bound<usize>,
- ) -> Option<$S::Span>;
- },
- SourceFile {
- fn drop($self: $S::SourceFile);
- fn clone($self: &$S::SourceFile) -> $S::SourceFile;
- fn eq($self: &$S::SourceFile, other: &$S::SourceFile) -> bool;
- fn path($self: &$S::SourceFile) -> String;
- fn is_real($self: &$S::SourceFile) -> bool;
- },
- MultiSpan {
- fn drop($self: $S::MultiSpan);
- fn new() -> $S::MultiSpan;
- fn push($self: &mut $S::MultiSpan, span: $S::Span);
- },
- Diagnostic {
- fn drop($self: $S::Diagnostic);
- fn new(level: Level, msg: &str, span: $S::MultiSpan) -> $S::Diagnostic;
- fn sub(
- $self: &mut $S::Diagnostic,
- level: Level,
- msg: &str,
- span: $S::MultiSpan,
- );
- fn emit($self: $S::Diagnostic);
- },
- Span {
- fn debug($self: $S::Span) -> String;
- fn source_file($self: $S::Span) -> $S::SourceFile;
- fn parent($self: $S::Span) -> Option<$S::Span>;
- fn source($self: $S::Span) -> $S::Span;
- fn start($self: $S::Span) -> LineColumn;
- fn end($self: $S::Span) -> LineColumn;
- fn before($self: $S::Span) -> $S::Span;
- fn after($self: $S::Span) -> $S::Span;
- fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
- fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
- fn source_text($self: $S::Span) -> Option<String>;
- fn save_span($self: $S::Span) -> usize;
- fn recover_proc_macro_span(id: usize) -> $S::Span;
- },
- }
- };
-}
-
-// FIXME(eddyb) this calls `encode` for each argument, but in reverse,
-// to match the ordering in `reverse_decode`.
-macro_rules! reverse_encode {
- ($writer:ident;) => {};
- ($writer:ident; $first:ident $(, $rest:ident)*) => {
- reverse_encode!($writer; $($rest),*);
- $first.encode(&mut $writer, &mut ());
- }
-}
-
-// FIXME(eddyb) this calls `decode` for each argument, but in reverse,
-// to avoid borrow conflicts from borrows started by `&mut` arguments.
-macro_rules! reverse_decode {
- ($reader:ident, $s:ident;) => {};
- ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
- reverse_decode!($reader, $s; $($rest: $rest_ty),*);
- let $first = <$first_ty>::decode(&mut $reader, $s);
- }
-}
-
-#[allow(unsafe_code)]
-mod buffer;
-#[forbid(unsafe_code)]
-pub mod client;
-#[allow(unsafe_code)]
-mod closure;
-#[forbid(unsafe_code)]
-mod handle;
-#[macro_use]
-#[forbid(unsafe_code)]
-mod rpc;
-#[allow(unsafe_code)]
-mod scoped_cell;
-#[allow(unsafe_code)]
-mod selfless_reify;
-#[forbid(unsafe_code)]
-pub mod server;
-
-use buffer::Buffer;
-pub use rpc::PanicMessage;
-use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
-
-/// Configuration for establishing an active connection between a server and a
-/// client. The server creates the bridge config (`run_server` in `server.rs`),
-/// then passes it to the client through the function pointer in the `run` field
-/// of `client::Client`. The client constructs a local `Bridge` from the config
-/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
-#[repr(C)]
-pub struct BridgeConfig<'a> {
- /// Buffer used to pass initial input to the client.
- input: Buffer,
-
- /// Server-side function that the client uses to make requests.
- dispatch: closure::Closure<'a, Buffer, Buffer>,
-
- /// If 'true', always invoke the default panic hook
- force_show_panics: bool,
-
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
- // this, but that requires unstable features. rust-analyzer uses this code
- // and avoids unstable features.
- _marker: marker::PhantomData<*mut ()>,
-}
-
-#[forbid(unsafe_code)]
-#[allow(non_camel_case_types)]
-mod api_tags {
- use super::rpc::{DecodeMut, Encode, Reader, Writer};
-
- macro_rules! declare_tags {
- ($($name:ident {
- $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
- }),* $(,)?) => {
- $(
- pub(super) enum $name {
- $($method),*
- }
- rpc_encode_decode!(enum $name { $($method),* });
- )*
-
- pub(super) enum Method {
- $($name($name)),*
- }
- rpc_encode_decode!(enum Method { $($name(m)),* });
- }
- }
- with_api!(self, self, declare_tags);
-}
-
-/// Helper to wrap associated types to allow trait impl dispatch.
-/// That is, normally a pair of impls for `T::Foo` and `T::Bar`
-/// can overlap, but if the impls are, instead, on types like
-/// `Marked<T::Foo, Foo>` and `Marked<T::Bar, Bar>`, they can't.
-trait Mark {
- type Unmarked;
- fn mark(unmarked: Self::Unmarked) -> Self;
-}
-
-/// Unwrap types wrapped by `Mark::mark` (see `Mark` for details).
-trait Unmark {
- type Unmarked;
- fn unmark(self) -> Self::Unmarked;
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-struct Marked<T, M> {
- value: T,
- _marker: marker::PhantomData<M>,
-}
-
-impl<T, M> Mark for Marked<T, M> {
- type Unmarked = T;
- fn mark(unmarked: Self::Unmarked) -> Self {
- Marked { value: unmarked, _marker: marker::PhantomData }
- }
-}
-impl<T, M> Unmark for Marked<T, M> {
- type Unmarked = T;
- fn unmark(self) -> Self::Unmarked {
- self.value
- }
-}
-impl<'a, T, M> Unmark for &'a Marked<T, M> {
- type Unmarked = &'a T;
- fn unmark(self) -> Self::Unmarked {
- &self.value
- }
-}
-impl<'a, T, M> Unmark for &'a mut Marked<T, M> {
- type Unmarked = &'a mut T;
- fn unmark(self) -> Self::Unmarked {
- &mut self.value
- }
-}
-
-impl<T: Mark> Mark for Vec<T> {
- type Unmarked = Vec<T::Unmarked>;
- fn mark(unmarked: Self::Unmarked) -> Self {
- // Should be a no-op due to std's in-place collect optimizations.
- unmarked.into_iter().map(T::mark).collect()
- }
-}
-impl<T: Unmark> Unmark for Vec<T> {
- type Unmarked = Vec<T::Unmarked>;
- fn unmark(self) -> Self::Unmarked {
- // Should be a no-op due to std's in-place collect optimizations.
- self.into_iter().map(T::unmark).collect()
- }
-}
-
-macro_rules! mark_noop {
- ($($ty:ty),* $(,)?) => {
- $(
- impl Mark for $ty {
- type Unmarked = Self;
- fn mark(unmarked: Self::Unmarked) -> Self {
- unmarked
- }
- }
- impl Unmark for $ty {
- type Unmarked = Self;
- fn unmark(self) -> Self::Unmarked {
- self
- }
- }
- )*
- }
-}
-mark_noop! {
- (),
- bool,
- char,
- &'_ [u8],
- &'_ str,
- String,
- u8,
- usize,
- Delimiter,
- Level,
- LineColumn,
- Spacing,
-}
-
-rpc_encode_decode!(
- enum Delimiter {
- Parenthesis,
- Brace,
- Bracket,
- None,
- }
-);
-rpc_encode_decode!(
- enum Level {
- Error,
- Warning,
- Note,
- Help,
- }
-);
-rpc_encode_decode!(struct LineColumn { line, column });
-rpc_encode_decode!(
- enum Spacing {
- Alone,
- Joint,
- }
-);
-
-macro_rules! mark_compound {
- (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
- impl<$($T: Mark),+> Mark for $name <$($T),+> {
- type Unmarked = $name <$($T::Unmarked),+>;
- fn mark(unmarked: Self::Unmarked) -> Self {
- $name {
- $($field: Mark::mark(unmarked.$field)),*
- }
- }
- }
- impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
- type Unmarked = $name <$($T::Unmarked),+>;
- fn unmark(self) -> Self::Unmarked {
- $name {
- $($field: Unmark::unmark(self.$field)),*
- }
- }
- }
- };
- (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
- impl<$($T: Mark),+> Mark for $name <$($T),+> {
- type Unmarked = $name <$($T::Unmarked),+>;
- fn mark(unmarked: Self::Unmarked) -> Self {
- match unmarked {
- $($name::$variant $(($field))? => {
- $name::$variant $((Mark::mark($field)))?
- })*
- }
- }
- }
- impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
- type Unmarked = $name <$($T::Unmarked),+>;
- fn unmark(self) -> Self::Unmarked {
- match self {
- $($name::$variant $(($field))? => {
- $name::$variant $((Unmark::unmark($field)))?
- })*
- }
- }
- }
- }
-}
-
-macro_rules! compound_traits {
- ($($t:tt)*) => {
- rpc_encode_decode!($($t)*);
- mark_compound!($($t)*);
- };
-}
-
-compound_traits!(
- enum Bound<T> {
- Included(x),
- Excluded(x),
- Unbounded,
- }
-);
-
-compound_traits!(
- enum Option<T> {
- Some(t),
- None,
- }
-);
-
-compound_traits!(
- enum Result<T, E> {
- Ok(t),
- Err(e),
- }
-);
-
-#[derive(Copy, Clone)]
-pub struct DelimSpan<Span> {
- pub open: Span,
- pub close: Span,
- pub entire: Span,
-}
-
-impl<Span: Copy> DelimSpan<Span> {
- pub fn from_single(span: Span) -> Self {
- DelimSpan { open: span, close: span, entire: span }
- }
-}
-
-compound_traits!(struct DelimSpan<Span> { open, close, entire });
-
-#[derive(Clone)]
-pub struct Group<TokenStream, Span> {
- pub delimiter: Delimiter,
- pub stream: Option<TokenStream>,
- pub span: DelimSpan<Span>,
-}
-
-compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
-
-#[derive(Clone)]
-pub struct Punct<Span> {
- pub ch: u8,
- pub joint: bool,
- pub span: Span,
-}
-
-compound_traits!(struct Punct<Span> { ch, joint, span });
-
-#[derive(Clone)]
-pub enum TokenTree<TokenStream, Span, Ident, Literal> {
- Group(Group<TokenStream, Span>),
- Punct(Punct<Span>),
- Ident(Ident),
- Literal(Literal),
-}
-
-compound_traits!(
- enum TokenTree<TokenStream, Span, Ident, Literal> {
- Group(tt),
- Punct(tt),
- Ident(tt),
- Literal(tt),
- }
-);
-
-/// Globals provided alongside the initial inputs for a macro expansion.
-/// Provides values such as spans which are used frequently to avoid RPC.
-#[derive(Clone)]
-pub struct ExpnGlobals<Span> {
- pub def_site: Span,
- pub call_site: Span,
- pub mixed_site: Span,
-}
-
-compound_traits!(
- struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
-);
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
deleted file mode 100644
index e9d7a46c0..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
+++ /dev/null
@@ -1,304 +0,0 @@
-//! Serialization for client-server communication.
-
-use std::any::Any;
-use std::char;
-use std::io::Write;
-use std::num::NonZeroU32;
-use std::str;
-
-pub(super) type Writer = super::buffer::Buffer;
-
-pub(super) trait Encode<S>: Sized {
- fn encode(self, w: &mut Writer, s: &mut S);
-}
-
-pub(super) type Reader<'a> = &'a [u8];
-
-pub(super) trait Decode<'a, 's, S>: Sized {
- fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
-}
-
-pub(super) trait DecodeMut<'a, 's, S>: Sized {
- fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
-}
-
-macro_rules! rpc_encode_decode {
- (le $ty:ty) => {
- impl<S> Encode<S> for $ty {
- fn encode(self, w: &mut Writer, _: &mut S) {
- w.extend_from_array(&self.to_le_bytes());
- }
- }
-
- impl<S> DecodeMut<'_, '_, S> for $ty {
- fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
- const N: usize = ::std::mem::size_of::<$ty>();
-
- let mut bytes = [0; N];
- bytes.copy_from_slice(&r[..N]);
- *r = &r[N..];
-
- Self::from_le_bytes(bytes)
- }
- }
- };
- (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
- impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
- fn encode(self, w: &mut Writer, s: &mut S) {
- $(self.$field.encode(w, s);)*
- }
- }
-
- impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
- for $name $(<$($T),+>)?
- {
- fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
- $name {
- $($field: DecodeMut::decode(r, s)),*
- }
- }
- }
- };
- (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
- impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
- fn encode(self, w: &mut Writer, s: &mut S) {
- // HACK(eddyb): `Tag` enum duplicated between the
- // two impls as there's no other place to stash it.
- #[allow(non_upper_case_globals)]
- mod tag {
- #[repr(u8)] enum Tag { $($variant),* }
-
- $(pub const $variant: u8 = Tag::$variant as u8;)*
- }
-
- match self {
- $($name::$variant $(($field))* => {
- tag::$variant.encode(w, s);
- $($field.encode(w, s);)*
- })*
- }
- }
- }
-
- impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
- for $name $(<$($T),+>)?
- {
- fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
- // HACK(eddyb): `Tag` enum duplicated between the
- // two impls as there's no other place to stash it.
- #[allow(non_upper_case_globals)]
- mod tag {
- #[repr(u8)] enum Tag { $($variant),* }
-
- $(pub const $variant: u8 = Tag::$variant as u8;)*
- }
-
- match u8::decode(r, s) {
- $(tag::$variant => {
- $(let $field = DecodeMut::decode(r, s);)*
- $name::$variant $(($field))*
- })*
- _ => unreachable!(),
- }
- }
- }
- }
-}
-
-impl<S> Encode<S> for () {
- fn encode(self, _: &mut Writer, _: &mut S) {}
-}
-
-impl<S> DecodeMut<'_, '_, S> for () {
- fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
-}
-
-impl<S> Encode<S> for u8 {
- fn encode(self, w: &mut Writer, _: &mut S) {
- w.push(self);
- }
-}
-
-impl<S> DecodeMut<'_, '_, S> for u8 {
- fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
- let x = r[0];
- *r = &r[1..];
- x
- }
-}
-
-rpc_encode_decode!(le u32);
-rpc_encode_decode!(le usize);
-
-impl<S> Encode<S> for bool {
- fn encode(self, w: &mut Writer, s: &mut S) {
- (self as u8).encode(w, s);
- }
-}
-
-impl<S> DecodeMut<'_, '_, S> for bool {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- match u8::decode(r, s) {
- 0 => false,
- 1 => true,
- _ => unreachable!(),
- }
- }
-}
-
-impl<S> Encode<S> for char {
- fn encode(self, w: &mut Writer, s: &mut S) {
- (self as u32).encode(w, s);
- }
-}
-
-impl<S> DecodeMut<'_, '_, S> for char {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- char::from_u32(u32::decode(r, s)).unwrap()
- }
-}
-
-impl<S> Encode<S> for NonZeroU32 {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.get().encode(w, s);
- }
-}
-
-impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- Self::new(u32::decode(r, s)).unwrap()
- }
-}
-
-impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.0.encode(w, s);
- self.1.encode(w, s);
- }
-}
-
-impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
- for (A, B)
-{
- fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
- (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
- }
-}
-
-impl<S> Encode<S> for &[u8] {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.len().encode(w, s);
- w.write_all(self).unwrap();
- }
-}
-
-impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
- fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
- let len = usize::decode(r, s);
- let xs = &r[..len];
- *r = &r[len..];
- xs
- }
-}
-
-impl<S> Encode<S> for &str {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.as_bytes().encode(w, s);
- }
-}
-
-impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
- fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
- str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
- }
-}
-
-impl<S> Encode<S> for String {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self[..].encode(w, s);
- }
-}
-
-impl<S> DecodeMut<'_, '_, S> for String {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- <&str>::decode(r, s).to_string()
- }
-}
-
-impl<S, T: Encode<S>> Encode<S> for Vec<T> {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.len().encode(w, s);
- for x in self {
- x.encode(w, s);
- }
- }
-}
-
-impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
- fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
- let len = usize::decode(r, s);
- let mut vec = Vec::with_capacity(len);
- for _ in 0..len {
- vec.push(T::decode(r, s));
- }
- vec
- }
-}
-
-/// Simplified version of panic payloads, ignoring
-/// types other than `&'static str` and `String`.
-pub enum PanicMessage {
- StaticStr(&'static str),
- String(String),
- Unknown,
-}
-
-impl From<Box<dyn Any + Send>> for PanicMessage {
- fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
- if let Some(s) = payload.downcast_ref::<&'static str>() {
- return PanicMessage::StaticStr(s);
- }
- if let Ok(s) = payload.downcast::<String>() {
- return PanicMessage::String(*s);
- }
- PanicMessage::Unknown
- }
-}
-
-impl Into<Box<dyn Any + Send>> for PanicMessage {
- fn into(self) -> Box<dyn Any + Send> {
- match self {
- PanicMessage::StaticStr(s) => Box::new(s),
- PanicMessage::String(s) => Box::new(s),
- PanicMessage::Unknown => {
- struct UnknownPanicMessage;
- Box::new(UnknownPanicMessage)
- }
- }
- }
-}
-
-impl PanicMessage {
- pub fn as_str(&self) -> Option<&str> {
- match self {
- PanicMessage::StaticStr(s) => Some(s),
- PanicMessage::String(s) => Some(s),
- PanicMessage::Unknown => None,
- }
- }
-}
-
-impl<S> Encode<S> for PanicMessage {
- fn encode(self, w: &mut Writer, s: &mut S) {
- self.as_str().encode(w, s);
- }
-}
-
-impl<S> DecodeMut<'_, '_, S> for PanicMessage {
- fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
- match Option::<String>::decode(r, s) {
- Some(s) => PanicMessage::String(s),
- None => PanicMessage::Unknown,
- }
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
deleted file mode 100644
index 2cde1f65a..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-//! `Cell` variant for (scoped) existential lifetimes.
-
-use std::cell::Cell;
-use std::mem;
-use std::ops::{Deref, DerefMut};
-
-/// Type lambda application, with a lifetime.
-#[allow(unused_lifetimes)]
-pub trait ApplyL<'a> {
- type Out;
-}
-
-/// Type lambda taking a lifetime, i.e., `Lifetime -> Type`.
-pub trait LambdaL: for<'a> ApplyL<'a> {}
-
-impl<T: for<'a> ApplyL<'a>> LambdaL for T {}
-
-// HACK(eddyb) work around projection limitations with a newtype
-// FIXME(#52812) replace with `&'a mut <T as ApplyL<'b>>::Out`
-pub struct RefMutL<'a, 'b, T: LambdaL>(&'a mut <T as ApplyL<'b>>::Out);
-
-impl<'a, 'b, T: LambdaL> Deref for RefMutL<'a, 'b, T> {
- type Target = <T as ApplyL<'b>>::Out;
- fn deref(&self) -> &Self::Target {
- self.0
- }
-}
-
-impl<'a, 'b, T: LambdaL> DerefMut for RefMutL<'a, 'b, T> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- self.0
- }
-}
-
-pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
-
-impl<T: LambdaL> ScopedCell<T> {
- pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
- ScopedCell(Cell::new(value))
- }
-
- /// Sets the value in `self` to `replacement` while
- /// running `f`, which gets the old value, mutably.
- /// The old value will be restored after `f` exits, even
- /// by panic, including modifications made to it by `f`.
- pub fn replace<'a, R>(
- &self,
- replacement: <T as ApplyL<'a>>::Out,
- f: impl for<'b, 'c> FnOnce(RefMutL<'b, 'c, T>) -> R,
- ) -> R {
- /// Wrapper that ensures that the cell always gets filled
- /// (with the original state, optionally changed by `f`),
- /// even if `f` had panicked.
- struct PutBackOnDrop<'a, T: LambdaL> {
- cell: &'a ScopedCell<T>,
- value: Option<<T as ApplyL<'static>>::Out>,
- }
-
- impl<'a, T: LambdaL> Drop for PutBackOnDrop<'a, T> {
- fn drop(&mut self) {
- self.cell.0.set(self.value.take().unwrap());
- }
- }
-
- let mut put_back_on_drop = PutBackOnDrop {
- cell: self,
- value: Some(self.0.replace(unsafe {
- let erased = mem::transmute_copy(&replacement);
- mem::forget(replacement);
- erased
- })),
- };
-
- f(RefMutL(put_back_on_drop.value.as_mut().unwrap()))
- }
-
- /// Sets the value in `self` to `value` while running `f`.
- pub fn set<R>(&self, value: <T as ApplyL<'_>>::Out, f: impl FnOnce() -> R) -> R {
- self.replace(value, |_| f())
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
deleted file mode 100644
index 907ad256e..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-//! Abstraction for creating `fn` pointers from any callable that *effectively*
-//! has the equivalent of implementing `Default`, even if the compiler neither
-//! provides `Default` nor allows reifying closures (i.e. creating `fn` pointers)
-//! other than those with absolutely no captures.
-//!
-//! More specifically, for a closure-like type to be "effectively `Default`":
-//! * it must be a ZST (zero-sized type): no information contained within, so
-//! that `Default`'s return value (if it were implemented) is unambiguous
-//! * it must be `Copy`: no captured "unique ZST tokens" or any other similar
-//! types that would make duplicating values at will unsound
-//! * combined with the ZST requirement, this confers a kind of "telecopy"
-//! ability: similar to `Copy`, but without keeping the value around, and
-//! instead "reconstructing" it (a noop given it's a ZST) when needed
-//! * it must be *provably* inhabited: no captured uninhabited types or any
-//! other types that cannot be constructed by the user of this abstraction
-//! * the proof is a value of the closure-like type itself, in a sense the
-//! "seed" for the "telecopy" process made possible by ZST + `Copy`
-//! * this requirement is the only reason an abstraction limited to a specific
-//! usecase is required: ZST + `Copy` can be checked with *at worst* a panic
-//! at the "attempted `::default()` call" time, but that doesn't guarantee
-//! that the value can be soundly created, and attempting to use the typical
-//! "proof ZST token" approach leads yet again to having a ZST + `Copy` type
-//! that is not proof of anything without a value (i.e. isomorphic to a
-//! newtype of the type it's trying to prove the inhabitation of)
-//!
-//! A more flexible (and safer) solution to the general problem could exist once
-//! `const`-generic parameters can have type parameters in their types:
-//!
-//! ```rust,ignore (needs future const-generics)
-//! extern "C" fn ffi_wrapper<
-//! A, R,
-//! F: Fn(A) -> R,
-//! const f: F, // <-- this `const`-generic is not yet allowed
-//! >(arg: A) -> R {
-//! f(arg)
-//! }
-//! ```
-
-use std::mem;
-
-// FIXME(eddyb) this could be `trait` impls except for the `const fn` requirement.
-macro_rules! define_reify_functions {
- ($(
- fn $name:ident $(<$($param:ident),*>)?
- for $(extern $abi:tt)? fn($($arg:ident: $arg_ty:ty),*) -> $ret_ty:ty;
- )+) => {
- $(pub const fn $name<
- $($($param,)*)?
- F: Fn($($arg_ty),*) -> $ret_ty + Copy
- >(f: F) -> $(extern $abi)? fn($($arg_ty),*) -> $ret_ty {
- // FIXME(eddyb) describe the `F` type (e.g. via `type_name::<F>`) once panic
- // formatting becomes possible in `const fn`.
- assert!(mem::size_of::<F>() == 0, "selfless_reify: closure must be zero-sized");
-
- $(extern $abi)? fn wrapper<
- $($($param,)*)?
- F: Fn($($arg_ty),*) -> $ret_ty + Copy
- >($($arg: $arg_ty),*) -> $ret_ty {
- let f = unsafe {
- // SAFETY: `F` satisfies all criteria for "out of thin air"
- // reconstructability (see module-level doc comment).
- mem::MaybeUninit::<F>::uninit().assume_init()
- };
- f($($arg),*)
- }
- let _f_proof = f;
- wrapper::<
- $($($param,)*)?
- F
- >
- })+
- }
-}
-
-define_reify_functions! {
- fn _reify_to_extern_c_fn_unary<A, R> for extern "C" fn(arg: A) -> R;
-
- // HACK(eddyb) this abstraction is used with `for<'a> fn(BridgeConfig<'a>)
- // -> T` but that doesn't work with just `reify_to_extern_c_fn_unary`
- // because of the `fn` pointer type being "higher-ranked" (i.e. the
- // `for<'a>` binder).
- // FIXME(eddyb) try to remove the lifetime from `BridgeConfig`, that'd help.
- fn reify_to_extern_c_fn_hrt_bridge<R> for extern "C" fn(bridge: super::BridgeConfig<'_>) -> R;
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
deleted file mode 100644
index 6e7a8d8c1..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-//! Server-side traits.
-
-use super::*;
-
-// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
-use super::client::HandleStore;
-
-pub trait Types {
- type FreeFunctions: 'static;
- type TokenStream: 'static + Clone;
- type Ident: 'static + Copy + Eq + Hash;
- type Literal: 'static + Clone;
- type SourceFile: 'static + Clone;
- type MultiSpan: 'static;
- type Diagnostic: 'static;
- type Span: 'static + Copy + Eq + Hash;
-}
-
-/// Declare an associated fn of one of the traits below, adding necessary
-/// default bodies.
-macro_rules! associated_fn {
- (fn drop(&mut self, $arg:ident: $arg_ty:ty)) =>
- (fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) });
-
- (fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) =>
- (fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() });
-
- ($($item:tt)*) => ($($item)*;)
-}
-
-macro_rules! declare_server_traits {
- ($($name:ident {
- $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
- }),* $(,)?) => {
- $(pub trait $name: Types {
- $(associated_fn!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
- })*
-
- pub trait Server: Types $(+ $name)* {
- fn globals(&mut self) -> ExpnGlobals<Self::Span>;
- }
- }
-}
-with_api!(Self, self_, declare_server_traits);
-
-pub(super) struct MarkedTypes<S: Types>(S);
-
-impl<S: Server> Server for MarkedTypes<S> {
- fn globals(&mut self) -> ExpnGlobals<Self::Span> {
- <_>::mark(Server::globals(&mut self.0))
- }
-}
-
-macro_rules! define_mark_types_impls {
- ($($name:ident {
- $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
- }),* $(,)?) => {
- impl<S: Types> Types for MarkedTypes<S> {
- $(type $name = Marked<S::$name, client::$name>;)*
- }
-
- $(impl<S: $name> $name for MarkedTypes<S> {
- $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? {
- <_>::mark($name::$method(&mut self.0, $($arg.unmark()),*))
- })*
- })*
- }
-}
-with_api!(Self, self_, define_mark_types_impls);
-
-struct Dispatcher<S: Types> {
- handle_store: HandleStore<S>,
- server: S,
-}
-
-macro_rules! define_dispatcher_impl {
- ($($name:ident {
- $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
- }),* $(,)?) => {
- // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
- pub trait DispatcherTrait {
- // HACK(eddyb) these are here to allow `Self::$name` to work below.
- $(type $name;)*
- fn dispatch(&mut self, buf: Buffer) -> Buffer;
- }
-
- impl<S: Server> DispatcherTrait for Dispatcher<MarkedTypes<S>> {
- $(type $name = <MarkedTypes<S> as Types>::$name;)*
- fn dispatch(&mut self, mut buf: Buffer) -> Buffer {
- let Dispatcher { handle_store, server } = self;
-
- let mut reader = &buf[..];
- match api_tags::Method::decode(&mut reader, &mut ()) {
- $(api_tags::Method::$name(m) => match m {
- $(api_tags::$name::$method => {
- let mut call_method = || {
- reverse_decode!(reader, handle_store; $($arg: $arg_ty),*);
- $name::$method(server, $($arg),*)
- };
- // HACK(eddyb) don't use `panic::catch_unwind` in a panic.
- // If client and server happen to use the same `libstd`,
- // `catch_unwind` asserts that the panic counter was 0,
- // even when the closure passed to it didn't panic.
- let r = if thread::panicking() {
- Ok(call_method())
- } else {
- panic::catch_unwind(panic::AssertUnwindSafe(call_method))
- .map_err(PanicMessage::from)
- };
-
- buf.clear();
- r.encode(&mut buf, handle_store);
- })*
- }),*
- }
- buf
- }
- }
- }
-}
-with_api!(Self, self_, define_dispatcher_impl);
-
-pub trait ExecutionStrategy {
- fn run_bridge_and_client(
- &self,
- dispatcher: &mut impl DispatcherTrait,
- input: Buffer,
- run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
- force_show_panics: bool,
- ) -> Buffer;
-}
-
-pub struct SameThread;
-
-impl ExecutionStrategy for SameThread {
- fn run_bridge_and_client(
- &self,
- dispatcher: &mut impl DispatcherTrait,
- input: Buffer,
- run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
- force_show_panics: bool,
- ) -> Buffer {
- let mut dispatch = |buf| dispatcher.dispatch(buf);
-
- run_client(BridgeConfig {
- input,
- dispatch: (&mut dispatch).into(),
- force_show_panics,
- _marker: marker::PhantomData,
- })
- }
-}
-
-// NOTE(eddyb) Two implementations are provided, the second one is a bit
-// faster but neither is anywhere near as fast as same-thread execution.
-
-pub struct CrossThread1;
-
-impl ExecutionStrategy for CrossThread1 {
- fn run_bridge_and_client(
- &self,
- dispatcher: &mut impl DispatcherTrait,
- input: Buffer,
- run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
- force_show_panics: bool,
- ) -> Buffer {
- use std::sync::mpsc::channel;
-
- let (req_tx, req_rx) = channel();
- let (res_tx, res_rx) = channel();
-
- let join_handle = thread::spawn(move || {
- let mut dispatch = |buf| {
- req_tx.send(buf).unwrap();
- res_rx.recv().unwrap()
- };
-
- run_client(BridgeConfig {
- input,
- dispatch: (&mut dispatch).into(),
- force_show_panics,
- _marker: marker::PhantomData,
- })
- });
-
- for b in req_rx {
- res_tx.send(dispatcher.dispatch(b)).unwrap();
- }
-
- join_handle.join().unwrap()
- }
-}
-
-pub struct CrossThread2;
-
-impl ExecutionStrategy for CrossThread2 {
- fn run_bridge_and_client(
- &self,
- dispatcher: &mut impl DispatcherTrait,
- input: Buffer,
- run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
- force_show_panics: bool,
- ) -> Buffer {
- use std::sync::{Arc, Mutex};
-
- enum State<T> {
- Req(T),
- Res(T),
- }
-
- let mut state = Arc::new(Mutex::new(State::Res(Buffer::new())));
-
- let server_thread = thread::current();
- let state2 = state.clone();
- let join_handle = thread::spawn(move || {
- let mut dispatch = |b| {
- *state2.lock().unwrap() = State::Req(b);
- server_thread.unpark();
- loop {
- thread::park();
- if let State::Res(b) = &mut *state2.lock().unwrap() {
- break b.take();
- }
- }
- };
-
- let r = run_client(BridgeConfig {
- input,
- dispatch: (&mut dispatch).into(),
- force_show_panics,
- _marker: marker::PhantomData,
- });
-
- // Wake up the server so it can exit the dispatch loop.
- drop(state2);
- server_thread.unpark();
-
- r
- });
-
- // Check whether `state2` was dropped, to know when to stop.
- while Arc::get_mut(&mut state).is_none() {
- thread::park();
- let mut b = match &mut *state.lock().unwrap() {
- State::Req(b) => b.take(),
- _ => continue,
- };
- b = dispatcher.dispatch(b.take());
- *state.lock().unwrap() = State::Res(b);
- join_handle.thread().unpark();
- }
-
- join_handle.join().unwrap()
- }
-}
-
-fn run_server<
- S: Server,
- I: Encode<HandleStore<MarkedTypes<S>>>,
- O: for<'a, 's> DecodeMut<'a, 's, HandleStore<MarkedTypes<S>>>,
->(
- strategy: &impl ExecutionStrategy,
- handle_counters: &'static client::HandleCounters,
- server: S,
- input: I,
- run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
- force_show_panics: bool,
-) -> Result<O, PanicMessage> {
- let mut dispatcher =
- Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) };
-
- let globals = dispatcher.server.globals();
-
- let mut buf = Buffer::new();
- (globals, input).encode(&mut buf, &mut dispatcher.handle_store);
-
- buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics);
-
- Result::decode(&mut &buf[..], &mut dispatcher.handle_store)
-}
-
-impl client::Client<super::super::TokenStream, super::super::TokenStream> {
- pub fn run<S>(
- &self,
- strategy: &impl ExecutionStrategy,
- server: S,
- input: S::TokenStream,
- force_show_panics: bool,
- ) -> Result<S::TokenStream, PanicMessage>
- where
- S: Server,
- S::TokenStream: Default,
- {
- let client::Client { get_handle_counters, run, _marker } = *self;
- run_server(
- strategy,
- get_handle_counters(),
- server,
- <MarkedTypes<S> as Types>::TokenStream::mark(input),
- run,
- force_show_panics,
- )
- .map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
- }
-}
-
-impl
- client::Client<
- (super::super::TokenStream, super::super::TokenStream),
- super::super::TokenStream,
- >
-{
- pub fn run<S>(
- &self,
- strategy: &impl ExecutionStrategy,
- server: S,
- input: S::TokenStream,
- input2: S::TokenStream,
- force_show_panics: bool,
- ) -> Result<S::TokenStream, PanicMessage>
- where
- S: Server,
- S::TokenStream: Default,
- {
- let client::Client { get_handle_counters, run, _marker } = *self;
- run_server(
- strategy,
- get_handle_counters(),
- server,
- (
- <MarkedTypes<S> as Types>::TokenStream::mark(input),
- <MarkedTypes<S> as Types>::TokenStream::mark(input2),
- ),
- run,
- force_show_panics,
- )
- .map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
deleted file mode 100644
index 3fade2dc4..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-//! lib-proc-macro diagnostic
-//!
-//! Copy from <https://github.com/rust-lang/rust/blob/e45d9973b2665897a768312e971b82cc62633103/src/libproc_macro/diagnostic.rs>
-//! augmented with removing unstable features
-
-use super::Span;
-
-/// An enum representing a diagnostic level.
-#[derive(Copy, Clone, Debug)]
-#[non_exhaustive]
-pub enum Level {
- /// An error.
- Error,
- /// A warning.
- Warning,
- /// A note.
- Note,
- /// A help message.
- Help,
-}
-
-/// Trait implemented by types that can be converted into a set of `Span`s.
-pub trait MultiSpan {
- /// Converts `self` into a `Vec<Span>`.
- fn into_spans(self) -> Vec<Span>;
-}
-
-impl MultiSpan for Span {
- fn into_spans(self) -> Vec<Span> {
- vec![self]
- }
-}
-
-impl MultiSpan for Vec<Span> {
- fn into_spans(self) -> Vec<Span> {
- self
- }
-}
-
-impl<'a> MultiSpan for &'a [Span] {
- fn into_spans(self) -> Vec<Span> {
- self.to_vec()
- }
-}
-
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
- level: Level,
- message: String,
- spans: Vec<Span>,
- children: Vec<Diagnostic>,
-}
-
-macro_rules! diagnostic_child_methods {
- ($spanned:ident, $regular:ident, $level:expr) => {
- #[doc = concat!("Adds a new child diagnostics message to `self` with the [`",
- stringify!($level), "`] level, and the given `spans` and `message`.")]
- pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
- where
- S: MultiSpan,
- T: Into<String>,
- {
- self.children.push(Diagnostic::spanned(spans, $level, message));
- self
- }
-
- #[doc = concat!("Adds a new child diagnostic message to `self` with the [`",
- stringify!($level), "`] level, and the given `message`.")]
- pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
- self.children.push(Diagnostic::new($level, message));
- self
- }
- };
-}
-
-/// Iterator over the children diagnostics of a `Diagnostic`.
-#[derive(Debug, Clone)]
-pub struct Children<'a>(std::slice::Iter<'a, Diagnostic>);
-
-impl<'a> Iterator for Children<'a> {
- type Item = &'a Diagnostic;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.0.next()
- }
-}
-
-impl Diagnostic {
- /// Creates a new diagnostic with the given `level` and `message`.
- pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
- Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
- }
-
- /// Creates a new diagnostic with the given `level` and `message` pointing to
- /// the given set of `spans`.
- pub fn spanned<S, T>(spans: S, level: Level, message: T) -> Diagnostic
- where
- S: MultiSpan,
- T: Into<String>,
- {
- Diagnostic { level, message: message.into(), spans: spans.into_spans(), children: vec![] }
- }
-
- diagnostic_child_methods!(span_error, error, Level::Error);
- diagnostic_child_methods!(span_warning, warning, Level::Warning);
- diagnostic_child_methods!(span_note, note, Level::Note);
- diagnostic_child_methods!(span_help, help, Level::Help);
-
- /// Returns the diagnostic `level` for `self`.
- pub fn level(&self) -> Level {
- self.level
- }
-
- /// Sets the level in `self` to `level`.
- pub fn set_level(&mut self, level: Level) {
- self.level = level;
- }
-
- /// Returns the message in `self`.
- pub fn message(&self) -> &str {
- &self.message
- }
-
- /// Sets the message in `self` to `message`.
- pub fn set_message<T: Into<String>>(&mut self, message: T) {
- self.message = message.into();
- }
-
- /// Returns the `Span`s in `self`.
- pub fn spans(&self) -> &[Span] {
- &self.spans
- }
-
- /// Sets the `Span`s in `self` to `spans`.
- pub fn set_spans<S: MultiSpan>(&mut self, spans: S) {
- self.spans = spans.into_spans();
- }
-
- /// Returns an iterator over the children diagnostics of `self`.
- pub fn children(&self) -> Children<'_> {
- Children(self.children.iter())
- }
-
- /// Emit the diagnostic.
- pub fn emit(self) {
- fn to_internal(spans: Vec<Span>) -> super::bridge::client::MultiSpan {
- let mut multi_span = super::bridge::client::MultiSpan::new();
- for span in spans {
- multi_span.push(span.0);
- }
- multi_span
- }
-
- let mut diag = super::bridge::client::Diagnostic::new(
- self.level,
- &self.message[..],
- to_internal(self.spans),
- );
- for c in self.children {
- diag.sub(c.level, &c.message[..], to_internal(c.spans));
- }
- diag.emit();
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
deleted file mode 100644
index be62c73ef..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
+++ /dev/null
@@ -1,1125 +0,0 @@
-//! A support library for macro authors when defining new macros.
-//!
-//! This library, provided by the standard distribution, provides the types
-//! consumed in the interfaces of procedurally defined macro definitions such as
-//! function-like macros `#[proc_macro]`, macro attributes `#[proc_macro_attribute]` and
-//! custom derive attributes`#[proc_macro_derive]`.
-//!
-//! See [the book] for more.
-//!
-//! [the book]: ../book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes
-
-#[doc(hidden)]
-pub mod bridge;
-
-mod diagnostic;
-
-pub use diagnostic::{Diagnostic, Level, MultiSpan};
-
-use std::cmp::Ordering;
-use std::ops::RangeBounds;
-use std::path::PathBuf;
-use std::str::FromStr;
-use std::{error, fmt, iter, mem};
-
-/// Determines whether proc_macro has been made accessible to the currently
-/// running program.
-///
-/// The proc_macro crate is only intended for use inside the implementation of
-/// procedural macros. All the functions in this crate panic if invoked from
-/// outside of a procedural macro, such as from a build script or unit test or
-/// ordinary Rust binary.
-///
-/// With consideration for Rust libraries that are designed to support both
-/// macro and non-macro use cases, `proc_macro::is_available()` provides a
-/// non-panicking way to detect whether the infrastructure required to use the
-/// API of proc_macro is presently available. Returns true if invoked from
-/// inside of a procedural macro, false if invoked from any other binary.
-pub fn is_available() -> bool {
- bridge::client::is_available()
-}
-
-/// The main type provided by this crate, representing an abstract stream of
-/// tokens, or, more specifically, a sequence of token trees.
-/// The type provide interfaces for iterating over those token trees and, conversely,
-/// collecting a number of token trees into one stream.
-///
-/// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
-/// and `#[proc_macro_derive]` definitions.
-#[derive(Clone)]
-pub struct TokenStream(Option<bridge::client::TokenStream>);
-
-/// Error returned from `TokenStream::from_str`.
-#[non_exhaustive]
-#[derive(Debug)]
-pub struct LexError;
-
-impl fmt::Display for LexError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("cannot parse string into token stream")
- }
-}
-
-impl error::Error for LexError {}
-
-/// Error returned from `TokenStream::expand_expr`.
-#[non_exhaustive]
-#[derive(Debug)]
-pub struct ExpandError;
-
-impl fmt::Display for ExpandError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("macro expansion failed")
- }
-}
-
-impl error::Error for ExpandError {}
-
-impl TokenStream {
- /// Returns an empty `TokenStream` containing no token trees.
- pub fn new() -> TokenStream {
- TokenStream(None)
- }
-
- /// Checks if this `TokenStream` is empty.
- pub fn is_empty(&self) -> bool {
- self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
- }
-
- /// Parses this `TokenStream` as an expression and attempts to expand any
- /// macros within it. Returns the expanded `TokenStream`.
- ///
- /// Currently only expressions expanding to literals will succeed, although
- /// this may be relaxed in the future.
- ///
- /// NOTE: In error conditions, `expand_expr` may leave macros unexpanded,
- /// report an error, failing compilation, and/or return an `Err(..)`. The
- /// specific behavior for any error condition, and what conditions are
- /// considered errors, is unspecified and may change in the future.
- pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
- let stream = self.0.as_ref().ok_or(ExpandError)?;
- match bridge::client::TokenStream::expand_expr(stream) {
- Ok(stream) => Ok(TokenStream(Some(stream))),
- Err(_) => Err(ExpandError),
- }
- }
-}
-
-/// Attempts to break the string into tokens and parse those tokens into a token stream.
-/// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
-/// or characters not existing in the language.
-/// All tokens in the parsed stream get `Span::call_site()` spans.
-///
-/// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
-/// change these errors into `LexError`s later.
-impl FromStr for TokenStream {
- type Err = LexError;
-
- fn from_str(src: &str) -> Result<TokenStream, LexError> {
- Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
- }
-}
-
-/// Prints the token stream as a string that is supposed to be losslessly convertible back
-/// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters and negative numeric literals.
-impl fmt::Display for TokenStream {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.to_string())
- }
-}
-
-/// Prints token in a form convenient for debugging.
-impl fmt::Debug for TokenStream {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("TokenStream ")?;
- f.debug_list().entries(self.clone()).finish()
- }
-}
-
-impl Default for TokenStream {
- fn default() -> Self {
- TokenStream::new()
- }
-}
-
-pub use quote::{quote, quote_span};
-
-fn tree_to_bridge_tree(
- tree: TokenTree,
-) -> bridge::TokenTree<
- bridge::client::TokenStream,
- bridge::client::Span,
- bridge::client::Ident,
- bridge::client::Literal,
-> {
- match tree {
- TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
- TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
- TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
- TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
- }
-}
-
-/// Creates a token stream containing a single token tree.
-impl From<TokenTree> for TokenStream {
- fn from(tree: TokenTree) -> TokenStream {
- TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
- }
-}
-
-/// Non-generic helper for implementing `FromIterator<TokenStream>` and
-/// `Extend<TokenStream>` with less monomorphization in calling crates.
-struct ConcatStreamsHelper {
- streams: Vec<bridge::client::TokenStream>,
-}
-
-impl ConcatStreamsHelper {
- fn new(capacity: usize) -> Self {
- ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
- }
-
- fn push(&mut self, stream: TokenStream) {
- if let Some(stream) = stream.0 {
- self.streams.push(stream);
- }
- }
-
- fn build(mut self) -> TokenStream {
- if self.streams.len() <= 1 {
- TokenStream(self.streams.pop())
- } else {
- TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
- }
- }
-
- fn append_to(mut self, stream: &mut TokenStream) {
- if self.streams.is_empty() {
- return;
- }
- let base = stream.0.take();
- if base.is_none() && self.streams.len() == 1 {
- stream.0 = self.streams.pop();
- } else {
- stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
- }
- }
-}
-
-/// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
- fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
- trees.into_iter().map(TokenStream::from).collect()
- }
-}
-
-/// A "flattening" operation on token streams, collects token trees
-/// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
- fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
- let iter = streams.into_iter();
- let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
- iter.for_each(|stream| builder.push(stream));
- builder.build()
- }
-}
-
-impl Extend<TokenTree> for TokenStream {
- fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
- self.extend(trees.into_iter().map(TokenStream::from));
- }
-}
-
-impl Extend<TokenStream> for TokenStream {
- fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
- // FIXME(eddyb) Use an optimized implementation if/when possible.
- *self = iter::once(mem::replace(self, Self::new())).chain(streams).collect();
- }
-}
-
-/// Public implementation details for the `TokenStream` type, such as iterators.
-pub mod token_stream {
- use super::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree};
-
- /// An iterator over `TokenStream`'s `TokenTree`s.
- /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
- /// and returns whole groups as token trees.
- #[derive(Clone)]
- pub struct IntoIter(
- std::vec::IntoIter<
- bridge::TokenTree<
- bridge::client::TokenStream,
- bridge::client::Span,
- bridge::client::Ident,
- bridge::client::Literal,
- >,
- >,
- );
-
- impl Iterator for IntoIter {
- type Item = TokenTree;
-
- fn next(&mut self) -> Option<TokenTree> {
- self.0.next().map(|tree| match tree {
- bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
- bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
- bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
- bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
- })
- }
- }
-
- impl IntoIterator for TokenStream {
- type Item = TokenTree;
- type IntoIter = IntoIter;
-
- fn into_iter(self) -> IntoIter {
- IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
- }
- }
-}
-
-#[doc(hidden)]
-mod quote;
-
-/// A region of source code, along with macro expansion information.
-#[derive(Copy, Clone)]
-pub struct Span(bridge::client::Span);
-
-macro_rules! diagnostic_method {
- ($name:ident, $level:expr) => {
- /// Creates a new `Diagnostic` with the given `message` at the span
- /// `self`.
- pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
- Diagnostic::spanned(self, $level, message)
- }
- };
-}
-
-impl Span {
- /// A span that resolves at the macro definition site.
- pub fn def_site() -> Span {
- Span(bridge::client::Span::def_site())
- }
-
- /// The span of the invocation of the current procedural macro.
- /// Identifiers created with this span will be resolved as if they were written
- /// directly at the macro call location (call-site hygiene) and other code
- /// at the macro call site will be able to refer to them as well.
- pub fn call_site() -> Span {
- Span(bridge::client::Span::call_site())
- }
-
- /// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
- /// definition site (local variables, labels, `$crate`) and sometimes at the macro
- /// call site (everything else).
- /// The span location is taken from the call-site.
- pub fn mixed_site() -> Span {
- Span(bridge::client::Span::mixed_site())
- }
-
- /// The original source file into which this span points.
- pub fn source_file(&self) -> SourceFile {
- SourceFile(self.0.source_file())
- }
-
- /// The `Span` for the tokens in the previous macro expansion from which
- /// `self` was generated from, if any.
- pub fn parent(&self) -> Option<Span> {
- self.0.parent().map(Span)
- }
-
- /// The span for the origin source code that `self` was generated from. If
- /// this `Span` wasn't generated from other macro expansions then the return
- /// value is the same as `*self`.
- pub fn source(&self) -> Span {
- Span(self.0.source())
- }
-
- /// Gets the starting line/column in the source file for this span.
- pub fn start(&self) -> LineColumn {
- self.0.start().add_1_to_column()
- }
-
- /// Gets the ending line/column in the source file for this span.
- pub fn end(&self) -> LineColumn {
- self.0.end().add_1_to_column()
- }
-
- /// Creates an empty span pointing to directly before this span.
- pub fn before(&self) -> Span {
- Span(self.0.before())
- }
-
- /// Creates an empty span pointing to directly after this span.
- pub fn after(&self) -> Span {
- Span(self.0.after())
- }
-
- /// Creates a new span encompassing `self` and `other`.
- ///
- /// Returns `None` if `self` and `other` are from different files.
- pub fn join(&self, other: Span) -> Option<Span> {
- self.0.join(other.0).map(Span)
- }
-
- /// Creates a new span with the same line/column information as `self` but
- /// that resolves symbols as though it were at `other`.
- pub fn resolved_at(&self, other: Span) -> Span {
- Span(self.0.resolved_at(other.0))
- }
-
- /// Creates a new span with the same name resolution behavior as `self` but
- /// with the line/column information of `other`.
- pub fn located_at(&self, other: Span) -> Span {
- other.resolved_at(*self)
- }
-
- /// Compares to spans to see if they're equal.
- pub fn eq(&self, other: &Span) -> bool {
- self.0 == other.0
- }
-
- /// Returns the source text behind a span. This preserves the original source
- /// code, including spaces and comments. It only returns a result if the span
- /// corresponds to real source code.
- ///
- /// Note: The observable result of a macro should only rely on the tokens and
- /// not on this source text. The result of this function is a best effort to
- /// be used for diagnostics only.
- pub fn source_text(&self) -> Option<String> {
- self.0.source_text()
- }
-
- // Used by the implementation of `Span::quote`
- #[doc(hidden)]
- pub fn save_span(&self) -> usize {
- self.0.save_span()
- }
-
- // Used by the implementation of `Span::quote`
- #[doc(hidden)]
- pub fn recover_proc_macro_span(id: usize) -> Span {
- Span(bridge::client::Span::recover_proc_macro_span(id))
- }
-
- diagnostic_method!(error, Level::Error);
- diagnostic_method!(warning, Level::Warning);
- diagnostic_method!(note, Level::Note);
- diagnostic_method!(help, Level::Help);
-}
-
-/// Prints a span in a form convenient for debugging.
-impl fmt::Debug for Span {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-/// A line-column pair representing the start or end of a `Span`.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct LineColumn {
- /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
- pub line: usize,
- /// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
- /// file on which the span starts or ends (inclusive).
- pub column: usize,
-}
-
-impl LineColumn {
- fn add_1_to_column(self) -> Self {
- LineColumn { line: self.line, column: self.column + 1 }
- }
-}
-
-impl Ord for LineColumn {
- fn cmp(&self, other: &Self) -> Ordering {
- self.line.cmp(&other.line).then(self.column.cmp(&other.column))
- }
-}
-
-impl PartialOrd for LineColumn {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-/// The source file of a given `Span`.
-#[derive(Clone)]
-pub struct SourceFile(bridge::client::SourceFile);
-
-impl SourceFile {
- /// Gets the path to this source file.
- ///
- /// ### Note
- /// If the code span associated with this `SourceFile` was generated by an external macro, this
- /// macro, this might not be an actual path on the filesystem. Use [`is_real`] to check.
- ///
- /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
- /// the command line, the path as given might not actually be valid.
- ///
- /// [`is_real`]: Self::is_real
- pub fn path(&self) -> PathBuf {
- PathBuf::from(self.0.path())
- }
-
- /// Returns `true` if this source file is a real source file, and not generated by an external
- /// macro's expansion.
- pub fn is_real(&self) -> bool {
- // This is a hack until intercrate spans are implemented and we can have real source files
- // for spans generated in external macros.
- // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
- self.0.is_real()
- }
-}
-
-impl fmt::Debug for SourceFile {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SourceFile")
- .field("path", &self.path())
- .field("is_real", &self.is_real())
- .finish()
- }
-}
-
-impl PartialEq for SourceFile {
- fn eq(&self, other: &Self) -> bool {
- self.0.eq(&other.0)
- }
-}
-
-impl Eq for SourceFile {}
-
-/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
-#[derive(Clone)]
-pub enum TokenTree {
- /// A token stream surrounded by bracket delimiters.
- Group(Group),
- /// An identifier.
- Ident(Ident),
- /// A single punctuation character (`+`, `,`, `$`, etc.).
- Punct(Punct),
- /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
- Literal(Literal),
-}
-
-impl TokenTree {
- /// Returns the span of this tree, delegating to the `span` method of
- /// the contained token or a delimited stream.
- pub fn span(&self) -> Span {
- match *self {
- TokenTree::Group(ref t) => t.span(),
- TokenTree::Ident(ref t) => t.span(),
- TokenTree::Punct(ref t) => t.span(),
- TokenTree::Literal(ref t) => t.span(),
- }
- }
-
- /// Configures the span for *only this token*.
- ///
- /// Note that if this token is a `Group` then this method will not configure
- /// the span of each of the internal tokens, this will simply delegate to
- /// the `set_span` method of each variant.
- pub fn set_span(&mut self, span: Span) {
- match *self {
- TokenTree::Group(ref mut t) => t.set_span(span),
- TokenTree::Ident(ref mut t) => t.set_span(span),
- TokenTree::Punct(ref mut t) => t.set_span(span),
- TokenTree::Literal(ref mut t) => t.set_span(span),
- }
- }
-}
-
-/// Prints token tree in a form convenient for debugging.
-impl fmt::Debug for TokenTree {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // Each of these has the name in the struct type in the derived debug,
- // so don't bother with an extra layer of indirection
- match *self {
- TokenTree::Group(ref tt) => tt.fmt(f),
- TokenTree::Ident(ref tt) => tt.fmt(f),
- TokenTree::Punct(ref tt) => tt.fmt(f),
- TokenTree::Literal(ref tt) => tt.fmt(f),
- }
- }
-}
-
-impl From<Group> for TokenTree {
- fn from(g: Group) -> TokenTree {
- TokenTree::Group(g)
- }
-}
-
-impl From<Ident> for TokenTree {
- fn from(g: Ident) -> TokenTree {
- TokenTree::Ident(g)
- }
-}
-
-impl From<Punct> for TokenTree {
- fn from(g: Punct) -> TokenTree {
- TokenTree::Punct(g)
- }
-}
-
-impl From<Literal> for TokenTree {
- fn from(g: Literal) -> TokenTree {
- TokenTree::Literal(g)
- }
-}
-
-/// Prints the token tree as a string that is supposed to be losslessly convertible back
-/// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters and negative numeric literals.
-impl fmt::Display for TokenTree {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.to_string())
- }
-}
-
-/// A delimited token stream.
-///
-/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
-#[derive(Clone)]
-pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
-
-/// Describes how a sequence of token trees is delimited.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Delimiter {
- /// `( ... )`
- Parenthesis,
- /// `{ ... }`
- Brace,
- /// `[ ... ]`
- Bracket,
- /// `Ø ... Ø`
- /// An invisible delimiter, that may, for example, appear around tokens coming from a
- /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
- /// `$var * 3` where `$var` is `1 + 2`.
- /// Invisible delimiters might not survive roundtrip of a token stream through a string.
- None,
-}
-
-impl Group {
- /// Creates a new `Group` with the given delimiter and token stream.
- ///
- /// This constructor will set the span for this group to
- /// `Span::call_site()`. To change the span you can use the `set_span`
- /// method below.
- pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
- Group(bridge::Group {
- delimiter,
- stream: stream.0,
- span: bridge::DelimSpan::from_single(Span::call_site().0),
- })
- }
-
- /// Returns the delimiter of this `Group`
- pub fn delimiter(&self) -> Delimiter {
- self.0.delimiter
- }
-
- /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
- ///
- /// Note that the returned token stream does not include the delimiter
- /// returned above.
- pub fn stream(&self) -> TokenStream {
- TokenStream(self.0.stream.clone())
- }
-
- /// Returns the span for the delimiters of this token stream, spanning the
- /// entire `Group`.
- ///
- /// ```text
- /// pub fn span(&self) -> Span {
- /// ^^^^^^^
- /// ```
- pub fn span(&self) -> Span {
- Span(self.0.span.entire)
- }
-
- /// Returns the span pointing to the opening delimiter of this group.
- ///
- /// ```text
- /// pub fn span_open(&self) -> Span {
- /// ^
- /// ```
- pub fn span_open(&self) -> Span {
- Span(self.0.span.open)
- }
-
- /// Returns the span pointing to the closing delimiter of this group.
- ///
- /// ```text
- /// pub fn span_close(&self) -> Span {
- /// ^
- /// ```
- pub fn span_close(&self) -> Span {
- Span(self.0.span.close)
- }
-
- /// Configures the span for this `Group`'s delimiters, but not its internal
- /// tokens.
- ///
- /// This method will **not** set the span of all the internal tokens spanned
- /// by this group, but rather it will only set the span of the delimiter
- /// tokens at the level of the `Group`.
- pub fn set_span(&mut self, span: Span) {
- self.0.span = bridge::DelimSpan::from_single(span.0);
- }
-}
-
-/// Prints the group as a string that should be losslessly convertible back
-/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters.
-impl fmt::Display for Group {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.to_string())
- }
-}
-
-impl fmt::Debug for Group {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Group")
- .field("delimiter", &self.delimiter())
- .field("stream", &self.stream())
- .field("span", &self.span())
- .finish()
- }
-}
-
-/// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
-///
-/// Multi-character operators like `+=` are represented as two instances of `Punct` with different
-/// forms of `Spacing` returned.
-#[derive(Clone)]
-pub struct Punct(bridge::Punct<bridge::client::Span>);
-
-/// Describes whether a `Punct` is followed immediately by another `Punct` ([`Spacing::Joint`]) or
-/// by a different token or whitespace ([`Spacing::Alone`]).
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Spacing {
- /// A `Punct` is not immediately followed by another `Punct`.
- /// E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`.
- Alone,
- /// A `Punct` is immediately followed by another `Punct`.
- /// E.g. `+` is `Joint` in `+=` and `++`.
- ///
- /// Additionally, single quote `'` can join with identifiers to form lifetimes: `'ident`.
- Joint,
-}
-
-impl Punct {
- /// Creates a new `Punct` from the given character and spacing.
- /// The `ch` argument must be a valid punctuation character permitted by the language,
- /// otherwise the function will panic.
- ///
- /// The returned `Punct` will have the default span of `Span::call_site()`
- /// which can be further configured with the `set_span` method below.
- pub fn new(ch: char, spacing: Spacing) -> Punct {
- const LEGAL_CHARS: &[char] = &[
- '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
- ':', '#', '$', '?', '\'',
- ];
- if !LEGAL_CHARS.contains(&ch) {
- panic!("unsupported character `{:?}`", ch);
- }
- Punct(bridge::Punct {
- ch: ch as u8,
- joint: spacing == Spacing::Joint,
- span: Span::call_site().0,
- })
- }
-
- /// Returns the value of this punctuation character as `char`.
- pub fn as_char(&self) -> char {
- self.0.ch as char
- }
-
- /// Returns the spacing of this punctuation character, indicating whether it's immediately
- /// followed by another `Punct` in the token stream, so they can potentially be combined into
- /// a multi-character operator (`Joint`), or it's followed by some other token or whitespace
- /// (`Alone`) so the operator has certainly ended.
- pub fn spacing(&self) -> Spacing {
- if self.0.joint {
- Spacing::Joint
- } else {
- Spacing::Alone
- }
- }
-
- /// Returns the span for this punctuation character.
- pub fn span(&self) -> Span {
- Span(self.0.span)
- }
-
- /// Configure the span for this punctuation character.
- pub fn set_span(&mut self, span: Span) {
- self.0.span = span.0;
- }
-}
-
-/// Prints the punctuation character as a string that should be losslessly convertible
-/// back into the same character.
-impl fmt::Display for Punct {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.to_string())
- }
-}
-
-impl fmt::Debug for Punct {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Punct")
- .field("ch", &self.as_char())
- .field("spacing", &self.spacing())
- .field("span", &self.span())
- .finish()
- }
-}
-
-impl PartialEq<char> for Punct {
- fn eq(&self, rhs: &char) -> bool {
- self.as_char() == *rhs
- }
-}
-
-impl PartialEq<Punct> for char {
- fn eq(&self, rhs: &Punct) -> bool {
- *self == rhs.as_char()
- }
-}
-
-/// An identifier (`ident`).
-#[derive(Clone)]
-pub struct Ident(bridge::client::Ident);
-
-impl Ident {
- /// Creates a new `Ident` with the given `string` as well as the specified
- /// `span`.
- /// The `string` argument must be a valid identifier permitted by the
- /// language (including keywords, e.g. `self` or `fn`). Otherwise, the function will panic.
- ///
- /// Note that `span`, currently in rustc, configures the hygiene information
- /// for this identifier.
- ///
- /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
- /// meaning that identifiers created with this span will be resolved as if they were written
- /// directly at the location of the macro call, and other code at the macro call site will be
- /// able to refer to them as well.
- ///
- /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
- /// meaning that identifiers created with this span will be resolved at the location of the
- /// macro definition and other code at the macro call site will not be able to refer to them.
- ///
- /// Due to the current importance of hygiene this constructor, unlike other
- /// tokens, requires a `Span` to be specified at construction.
- pub fn new(string: &str, span: Span) -> Ident {
- Ident(bridge::client::Ident::new(string, span.0, false))
- }
-
- /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
- /// The `string` argument be a valid identifier permitted by the language
- /// (including keywords, e.g. `fn`). Keywords which are usable in path segments
- /// (e.g. `self`, `super`) are not supported, and will cause a panic.
- pub fn new_raw(string: &str, span: Span) -> Ident {
- Ident(bridge::client::Ident::new(string, span.0, true))
- }
-
- /// Returns the span of this `Ident`, encompassing the entire string returned
- /// by [`to_string`](Self::to_string).
- pub fn span(&self) -> Span {
- Span(self.0.span())
- }
-
- /// Configures the span of this `Ident`, possibly changing its hygiene context.
- pub fn set_span(&mut self, span: Span) {
- self.0 = self.0.with_span(span.0);
- }
-}
-
-/// Prints the identifier as a string that should be losslessly convertible
-/// back into the same identifier.
-impl fmt::Display for Ident {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.to_string())
- }
-}
-
-impl fmt::Debug for Ident {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Ident")
- .field("ident", &self.to_string())
- .field("span", &self.span())
- .finish()
- }
-}
-
-/// A literal string (`"hello"`), byte string (`b"hello"`),
-/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
-/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
-/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
-#[derive(Clone)]
-pub struct Literal(bridge::client::Literal);
-
-macro_rules! suffixed_int_literals {
- ($($name:ident => $kind:ident,)*) => ($(
- /// Creates a new suffixed integer literal with the specified value.
- ///
- /// This function will create an integer like `1u32` where the integer
- /// value specified is the first part of the token and the integral is
- /// also suffixed at the end.
- /// Literals created from negative numbers might not survive round-trips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
- ///
- /// Literals created through this method have the `Span::call_site()`
- /// span by default, which can be configured with the `set_span` method
- /// below.
- pub fn $name(n: $kind) -> Literal {
- Literal(bridge::client::Literal::typed_integer(&n.to_string(), stringify!($kind)))
- }
- )*)
-}
-
-macro_rules! unsuffixed_int_literals {
- ($($name:ident => $kind:ident,)*) => ($(
- /// Creates a new unsuffixed integer literal with the specified value.
- ///
- /// This function will create an integer like `1` where the integer
- /// value specified is the first part of the token. No suffix is
- /// specified on this token, meaning that invocations like
- /// `Literal::i8_unsuffixed(1)` are equivalent to
- /// `Literal::u32_unsuffixed(1)`.
- /// Literals created from negative numbers might not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
- ///
- /// Literals created through this method have the `Span::call_site()`
- /// span by default, which can be configured with the `set_span` method
- /// below.
- pub fn $name(n: $kind) -> Literal {
- Literal(bridge::client::Literal::integer(&n.to_string()))
- }
- )*)
-}
-
-impl Literal {
- suffixed_int_literals! {
- u8_suffixed => u8,
- u16_suffixed => u16,
- u32_suffixed => u32,
- u64_suffixed => u64,
- u128_suffixed => u128,
- usize_suffixed => usize,
- i8_suffixed => i8,
- i16_suffixed => i16,
- i32_suffixed => i32,
- i64_suffixed => i64,
- i128_suffixed => i128,
- isize_suffixed => isize,
- }
-
- unsuffixed_int_literals! {
- u8_unsuffixed => u8,
- u16_unsuffixed => u16,
- u32_unsuffixed => u32,
- u64_unsuffixed => u64,
- u128_unsuffixed => u128,
- usize_unsuffixed => usize,
- i8_unsuffixed => i8,
- i16_unsuffixed => i16,
- i32_unsuffixed => i32,
- i64_unsuffixed => i64,
- i128_unsuffixed => i128,
- isize_unsuffixed => isize,
- }
-
- /// Creates a new unsuffixed floating-point literal.
- ///
- /// This constructor is similar to those like `Literal::i8_unsuffixed` where
- /// the float's value is emitted directly into the token but no suffix is
- /// used, so it may be inferred to be a `f64` later in the compiler.
- /// Literals created from negative numbers might not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
- ///
- /// # Panics
- ///
- /// This function requires that the specified float is finite, for
- /// example if it is infinity or NaN this function will panic.
- pub fn f32_unsuffixed(n: f32) -> Literal {
- if !n.is_finite() {
- panic!("Invalid float literal {n}");
- }
- let mut repr = n.to_string();
- if !repr.contains('.') {
- repr.push_str(".0");
- }
- Literal(bridge::client::Literal::float(&repr))
- }
-
- /// Creates a new suffixed floating-point literal.
- ///
- /// This constructor will create a literal like `1.0f32` where the value
- /// specified is the preceding part of the token and `f32` is the suffix of
- /// the token. This token will always be inferred to be an `f32` in the
- /// compiler.
- /// Literals created from negative numbers might not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
- ///
- /// # Panics
- ///
- /// This function requires that the specified float is finite, for
- /// example if it is infinity or NaN this function will panic.
- pub fn f32_suffixed(n: f32) -> Literal {
- if !n.is_finite() {
- panic!("Invalid float literal {n}");
- }
- Literal(bridge::client::Literal::f32(&n.to_string()))
- }
-
- /// Creates a new unsuffixed floating-point literal.
- ///
- /// This constructor is similar to those like `Literal::i8_unsuffixed` where
- /// the float's value is emitted directly into the token but no suffix is
- /// used, so it may be inferred to be a `f64` later in the compiler.
- /// Literals created from negative numbers might not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
- ///
- /// # Panics
- ///
- /// This function requires that the specified float is finite, for
- /// example if it is infinity or NaN this function will panic.
- pub fn f64_unsuffixed(n: f64) -> Literal {
- if !n.is_finite() {
- panic!("Invalid float literal {n}");
- }
- let mut repr = n.to_string();
- if !repr.contains('.') {
- repr.push_str(".0");
- }
- Literal(bridge::client::Literal::float(&repr))
- }
-
- /// Creates a new suffixed floating-point literal.
- ///
- /// This constructor will create a literal like `1.0f64` where the value
- /// specified is the preceding part of the token and `f64` is the suffix of
- /// the token. This token will always be inferred to be an `f64` in the
- /// compiler.
- /// Literals created from negative numbers might not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
- ///
- /// # Panics
- ///
- /// This function requires that the specified float is finite, for
- /// example if it is infinity or NaN this function will panic.
- pub fn f64_suffixed(n: f64) -> Literal {
- if !n.is_finite() {
- panic!("Invalid float literal {n}");
- }
- Literal(bridge::client::Literal::f64(&n.to_string()))
- }
-
- /// String literal.
- pub fn string(string: &str) -> Literal {
- Literal(bridge::client::Literal::string(string))
- }
-
- /// Character literal.
- pub fn character(ch: char) -> Literal {
- Literal(bridge::client::Literal::character(ch))
- }
-
- /// Byte string literal.
- pub fn byte_string(bytes: &[u8]) -> Literal {
- Literal(bridge::client::Literal::byte_string(bytes))
- }
-
- /// Returns the span encompassing this literal.
- pub fn span(&self) -> Span {
- Span(self.0.span())
- }
-
- /// Configures the span associated for this literal.
- pub fn set_span(&mut self, span: Span) {
- self.0.set_span(span.0);
- }
-
- /// Returns a `Span` that is a subset of `self.span()` containing only the
- /// source bytes in range `range`. Returns `None` if the would-be trimmed
- /// span is outside the bounds of `self`.
- // FIXME(SergioBenitez): check that the byte range starts and ends at a
- // UTF-8 boundary of the source. otherwise, it's likely that a panic will
- // occur elsewhere when the source text is printed.
- // FIXME(SergioBenitez): there is no way for the user to know what
- // `self.span()` actually maps to, so this method can currently only be
- // called blindly. For example, `to_string()` for the character 'c' returns
- // "'\u{63}'"; there is no way for the user to know whether the source text
- // was 'c' or whether it was '\u{63}'.
- pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
- self.0.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
- }
-}
-
-/// Parse a single literal from its stringified representation.
-///
-/// In order to parse successfully, the input string must not contain anything
-/// but the literal token. Specifically, it must not contain whitespace or
-/// comments in addition to the literal.
-///
-/// The resulting literal token will have a `Span::call_site()` span.
-///
-/// NOTE: some errors may cause panics instead of returning `LexError`. We
-/// reserve the right to change these errors into `LexError`s later.
-impl FromStr for Literal {
- type Err = LexError;
-
- fn from_str(src: &str) -> Result<Self, LexError> {
- match bridge::client::Literal::from_str(src) {
- Ok(literal) => Ok(Literal(literal)),
- Err(()) => Err(LexError),
- }
- }
-}
-
-/// Prints the literal as a string that should be losslessly convertible
-/// back into the same literal (except for possible rounding for floating point literals).
-impl fmt::Display for Literal {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.to_string())
- }
-}
-
-impl fmt::Debug for Literal {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-/// Tracked access to environment variables.
-pub mod tracked_env {
- use std::env::{self, VarError};
- use std::ffi::OsStr;
-
- /// Retrieve an environment variable and add it to build dependency info.
- /// Build system executing the compiler will know that the variable was accessed during
- /// compilation, and will be able to rerun the build when the value of that variable changes.
- /// Besides the dependency tracking this function should be equivalent to `env::var` from the
- /// standard library, except that the argument must be UTF-8.
- pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
- let key: &str = key.as_ref();
- let value = env::var(key);
- super::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
- value
- }
-}
-
-/// Tracked access to additional files.
-pub mod tracked_path {
-
- /// Track a file explicitly.
- ///
- /// Commonly used for tracking asset preprocessing.
- pub fn path<P: AsRef<str>>(path: P) {
- let path: &str = path.as_ref();
- super::bridge::client::FreeFunctions::track_path(path);
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
deleted file mode 100644
index 39309faa4..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-//! # Quasiquoter
-//! This file contains the implementation internals of the quasiquoter provided by `quote!`.
-
-//! This quasiquoter uses macros 2.0 hygiene to reliably access
-//! items from `proc_macro`, to build a `proc_macro::TokenStream`.
-
-use super::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
-
-macro_rules! quote_tt {
- (($($t:tt)*)) => { Group::new(Delimiter::Parenthesis, quote!($($t)*)) };
- ([$($t:tt)*]) => { Group::new(Delimiter::Bracket, quote!($($t)*)) };
- ({$($t:tt)*}) => { Group::new(Delimiter::Brace, quote!($($t)*)) };
- (,) => { Punct::new(',', Spacing::Alone) };
- (.) => { Punct::new('.', Spacing::Alone) };
- (;) => { Punct::new(';', Spacing::Alone) };
- (!) => { Punct::new('!', Spacing::Alone) };
- (<) => { Punct::new('<', Spacing::Alone) };
- (>) => { Punct::new('>', Spacing::Alone) };
- (&) => { Punct::new('&', Spacing::Alone) };
- (=) => { Punct::new('=', Spacing::Alone) };
- ($i:ident) => { Ident::new(stringify!($i), Span::def_site()) };
-}
-
-macro_rules! quote_ts {
- ((@ $($t:tt)*)) => { $($t)* };
- (::) => {
- [
- TokenTree::from(Punct::new(':', Spacing::Joint)),
- TokenTree::from(Punct::new(':', Spacing::Alone)),
- ].iter()
- .cloned()
- .map(|mut x| {
- x.set_span(Span::def_site());
- x
- })
- .collect::<TokenStream>()
- };
- ($t:tt) => { TokenTree::from(quote_tt!($t)) };
-}
-
-/// Simpler version of the real `quote!` macro, implemented solely
-/// through `macro_rules`, for bootstrapping the real implementation
-/// (see the `quote` function), which does not have access to the
-/// real `quote!` macro due to the `proc_macro` crate not being
-/// able to depend on itself.
-///
-/// Note: supported tokens are a subset of the real `quote!`, but
-/// unquoting is different: instead of `$x`, this uses `(@ expr)`.
-macro_rules! quote {
- () => { TokenStream::new() };
- ($($t:tt)*) => {
- [
- $(TokenStream::from(quote_ts!($t)),)*
- ].iter().cloned().collect::<TokenStream>()
- };
-}
-
-/// Quote a `TokenStream` into a `TokenStream`.
-/// This is the actual implementation of the `quote!()` proc macro.
-///
-/// It is loaded by the compiler in `register_builtin_macros`.
-pub fn quote(stream: TokenStream) -> TokenStream {
- if stream.is_empty() {
- return quote!(super::TokenStream::new());
- }
- let proc_macro_crate = quote!(crate);
- let mut after_dollar = false;
- let tokens = stream
- .into_iter()
- .filter_map(|tree| {
- if after_dollar {
- after_dollar = false;
- match tree {
- TokenTree::Ident(_) => {
- return Some(quote!(Into::<super::TokenStream>::into(
- Clone::clone(&(@ tree))),));
- }
- TokenTree::Punct(ref tt) if tt.as_char() == '$' => {}
- _ => panic!("`$` must be followed by an ident or `$` in `quote!`"),
- }
- } else if let TokenTree::Punct(ref tt) = tree {
- if tt.as_char() == '$' {
- after_dollar = true;
- return None;
- }
- }
-
- Some(quote!(super::TokenStream::from((@ match tree {
- TokenTree::Punct(tt) => quote!(super::TokenTree::Punct(super::Punct::new(
- (@ TokenTree::from(Literal::character(tt.as_char()))),
- (@ match tt.spacing() {
- Spacing::Alone => quote!(super::Spacing::Alone),
- Spacing::Joint => quote!(super::Spacing::Joint),
- }),
- ))),
- TokenTree::Group(tt) => quote!(super::TokenTree::Group(super::Group::new(
- (@ match tt.delimiter() {
- Delimiter::Parenthesis => quote!(super::Delimiter::Parenthesis),
- Delimiter::Brace => quote!(super::Delimiter::Brace),
- Delimiter::Bracket => quote!(super::Delimiter::Bracket),
- Delimiter::None => quote!(super::Delimiter::None),
- }),
- (@ quote(tt.stream())),
- ))),
- TokenTree::Ident(tt) => quote!(super::TokenTree::Ident(super::Ident::new(
- (@ TokenTree::from(Literal::string(&tt.to_string()))),
- (@ quote_span(proc_macro_crate.clone(), tt.span())),
- ))),
- TokenTree::Literal(tt) => quote!(super::TokenTree::Literal({
- let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string())))
- .parse::<super::TokenStream>()
- .unwrap()
- .into_iter();
- if let (Some(super::TokenTree::Literal(mut lit)), None) =
- (iter.next(), iter.next())
- {
- lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
- lit
- } else {
- unreachable!()
- }
- }))
- })),))
- })
- .collect::<TokenStream>();
-
- if after_dollar {
- panic!("unexpected trailing `$` in `quote!`");
- }
-
- quote!([(@ tokens)].iter().cloned().collect::<super::TokenStream>())
-}
-
-/// Quote a `Span` into a `TokenStream`.
-/// This is needed to implement a custom quoter.
-pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
- let id = span.save_span();
- quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
deleted file mode 100644
index 7e8e67856..000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
+++ /dev/null
@@ -1,792 +0,0 @@
-//! Rustc proc-macro server implementation with tt
-//!
-//! Based on idea from <https://github.com/fedochet/rust-proc-macro-expander>
-//! The lib-proc-macro server backend is `TokenStream`-agnostic, such that
-//! we could provide any TokenStream implementation.
-//! The original idea from fedochet is using proc-macro2 as backend,
-//! we use tt instead for better integration with RA.
-//!
-//! FIXME: No span and source file information is implemented yet
-
-use super::proc_macro::bridge::{self, server};
-
-use std::collections::HashMap;
-use std::hash::Hash;
-use std::iter::FromIterator;
-use std::ops::Bound;
-use std::{ascii, vec::IntoIter};
-
-type Group = tt::Subtree;
-type TokenTree = tt::TokenTree;
-type Punct = tt::Punct;
-type Spacing = tt::Spacing;
-type Literal = tt::Literal;
-type Span = tt::TokenId;
-
-#[derive(Debug, Default, Clone)]
-pub struct TokenStream {
- pub token_trees: Vec<TokenTree>,
-}
-
-impl TokenStream {
- pub fn new() -> Self {
- TokenStream::default()
- }
-
- pub fn with_subtree(subtree: tt::Subtree) -> Self {
- if subtree.delimiter.is_some() {
- TokenStream { token_trees: vec![TokenTree::Subtree(subtree)] }
- } else {
- TokenStream { token_trees: subtree.token_trees }
- }
- }
-
- pub fn into_subtree(self) -> tt::Subtree {
- tt::Subtree { delimiter: None, token_trees: self.token_trees }
- }
-
- pub fn is_empty(&self) -> bool {
- self.token_trees.is_empty()
- }
-}
-
-/// Creates a token stream containing a single token tree.
-impl From<TokenTree> for TokenStream {
- fn from(tree: TokenTree) -> TokenStream {
- TokenStream { token_trees: vec![tree] }
- }
-}
-
-/// Collects a number of token trees into a single stream.
-impl FromIterator<TokenTree> for TokenStream {
- fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
- trees.into_iter().map(TokenStream::from).collect()
- }
-}
-
-/// A "flattening" operation on token streams, collects token trees
-/// from multiple token streams into a single stream.
-impl FromIterator<TokenStream> for TokenStream {
- fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
- let mut builder = TokenStreamBuilder::new();
- streams.into_iter().for_each(|stream| builder.push(stream));
- builder.build()
- }
-}
-
-impl Extend<TokenTree> for TokenStream {
- fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
- self.extend(trees.into_iter().map(TokenStream::from));
- }
-}
-
-impl Extend<TokenStream> for TokenStream {
- fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
- for item in streams {
- for tkn in item {
- match tkn {
- tt::TokenTree::Subtree(subtree) if subtree.delimiter.is_none() => {
- self.token_trees.extend(subtree.token_trees);
- }
- _ => {
- self.token_trees.push(tkn);
- }
- }
- }
- }
- }
-}
-
-#[derive(Clone)]
-pub struct SourceFile {
- // FIXME stub
-}
-
-type Level = super::proc_macro::Level;
-type LineColumn = super::proc_macro::LineColumn;
-
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
- level: Level,
- message: String,
- spans: Vec<Span>,
- children: Vec<Diagnostic>,
-}
-
-impl Diagnostic {
- /// Creates a new diagnostic with the given `level` and `message`.
- pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
- Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
- }
-}
-
-// Rustc Server Ident has to be `Copyable`
-// We use a stub here for bypassing
-#[derive(Hash, Eq, PartialEq, Copy, Clone)]
-pub struct IdentId(u32);
-
-#[derive(Clone, Hash, Eq, PartialEq)]
-struct IdentData(tt::Ident);
-
-#[derive(Default)]
-struct IdentInterner {
- idents: HashMap<IdentData, u32>,
- ident_data: Vec<IdentData>,
-}
-
-impl IdentInterner {
- fn intern(&mut self, data: &IdentData) -> u32 {
- if let Some(index) = self.idents.get(data) {
- return *index;
- }
-
- let index = self.idents.len() as u32;
- self.ident_data.push(data.clone());
- self.idents.insert(data.clone(), index);
- index
- }
-
- fn get(&self, index: u32) -> &IdentData {
- &self.ident_data[index as usize]
- }
-
- #[allow(unused)]
- fn get_mut(&mut self, index: u32) -> &mut IdentData {
- self.ident_data.get_mut(index as usize).expect("Should be consistent")
- }
-}
-
-pub struct TokenStreamBuilder {
- acc: TokenStream,
-}
-
-/// Public implementation details for the `TokenStream` type, such as iterators.
-pub mod token_stream {
- use std::str::FromStr;
-
- use super::{TokenStream, TokenTree};
-
- /// An iterator over `TokenStream`'s `TokenTree`s.
- /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
- /// and returns whole groups as token trees.
- impl IntoIterator for TokenStream {
- type Item = TokenTree;
- type IntoIter = super::IntoIter<TokenTree>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.token_trees.into_iter()
- }
- }
-
- type LexError = String;
-
- /// Attempts to break the string into tokens and parse those tokens into a token stream.
- /// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
- /// or characters not existing in the language.
- /// All tokens in the parsed stream get `Span::call_site()` spans.
- ///
- /// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
- /// change these errors into `LexError`s later.
- impl FromStr for TokenStream {
- type Err = LexError;
-
- fn from_str(src: &str) -> Result<TokenStream, LexError> {
- let (subtree, _token_map) =
- mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
-
- let subtree = subtree_replace_token_ids_with_unspecified(subtree);
- Ok(TokenStream::with_subtree(subtree))
- }
- }
-
- impl ToString for TokenStream {
- fn to_string(&self) -> String {
- tt::pretty(&self.token_trees)
- }
- }
-
- fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
- tt::Subtree {
- delimiter: subtree
- .delimiter
- .map(|d| tt::Delimiter { id: tt::TokenId::unspecified(), ..d }),
- token_trees: subtree
- .token_trees
- .into_iter()
- .map(token_tree_replace_token_ids_with_unspecified)
- .collect(),
- }
- }
-
- fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
- match tt {
- tt::TokenTree::Leaf(leaf) => {
- tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
- }
- tt::TokenTree::Subtree(subtree) => {
- tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
- }
- }
- }
-
- fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
- match leaf {
- tt::Leaf::Literal(lit) => {
- tt::Leaf::Literal(tt::Literal { id: tt::TokenId::unspecified(), ..lit })
- }
- tt::Leaf::Punct(punct) => {
- tt::Leaf::Punct(tt::Punct { id: tt::TokenId::unspecified(), ..punct })
- }
- tt::Leaf::Ident(ident) => {
- tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), ..ident })
- }
- }
- }
-}
-
-impl TokenStreamBuilder {
- fn new() -> TokenStreamBuilder {
- TokenStreamBuilder { acc: TokenStream::new() }
- }
-
- fn push(&mut self, stream: TokenStream) {
- self.acc.extend(stream.into_iter())
- }
-
- fn build(self) -> TokenStream {
- self.acc
- }
-}
-
-pub struct FreeFunctions;
-
-#[derive(Clone)]
-pub struct TokenStreamIter {
- trees: IntoIter<TokenTree>,
-}
-
-#[derive(Default)]
-pub struct RustAnalyzer {
- ident_interner: IdentInterner,
- // FIXME: store span information here.
-}
-
-impl server::Types for RustAnalyzer {
- type FreeFunctions = FreeFunctions;
- type TokenStream = TokenStream;
- type Ident = IdentId;
- type Literal = Literal;
- type SourceFile = SourceFile;
- type Diagnostic = Diagnostic;
- type Span = Span;
- type MultiSpan = Vec<Span>;
-}
-
-impl server::FreeFunctions for RustAnalyzer {
- fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {
- // FIXME: track env var accesses
- // https://github.com/rust-lang/rust/pull/71858
- }
- fn track_path(&mut self, _path: &str) {}
-}
-
-impl server::TokenStream for RustAnalyzer {
- fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
- stream.is_empty()
- }
- fn from_str(&mut self, src: &str) -> Self::TokenStream {
- use std::str::FromStr;
-
- Self::TokenStream::from_str(src).expect("cannot parse string")
- }
- fn to_string(&mut self, stream: &Self::TokenStream) -> String {
- stream.to_string()
- }
- fn from_token_tree(
- &mut self,
- tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>,
- ) -> Self::TokenStream {
- match tree {
- bridge::TokenTree::Group(group) => {
- let group = Group {
- delimiter: delim_to_internal(group.delimiter),
- token_trees: match group.stream {
- Some(stream) => stream.into_iter().collect(),
- None => Vec::new(),
- },
- };
- let tree = TokenTree::from(group);
- Self::TokenStream::from_iter(vec![tree])
- }
-
- bridge::TokenTree::Ident(IdentId(index)) => {
- let IdentData(ident) = self.ident_interner.get(index).clone();
- let ident: tt::Ident = ident;
- let leaf = tt::Leaf::from(ident);
- let tree = TokenTree::from(leaf);
- Self::TokenStream::from_iter(vec![tree])
- }
-
- bridge::TokenTree::Literal(literal) => {
- let leaf = tt::Leaf::from(literal);
- let tree = TokenTree::from(leaf);
- Self::TokenStream::from_iter(vec![tree])
- }
-
- bridge::TokenTree::Punct(p) => {
- let punct = tt::Punct {
- char: p.ch as char,
- spacing: if p.joint { Spacing::Joint } else { Spacing::Alone },
- id: p.span,
- };
- let leaf = tt::Leaf::from(punct);
- let tree = TokenTree::from(leaf);
- Self::TokenStream::from_iter(vec![tree])
- }
- }
- }
-
- fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
- Ok(self_.clone())
- }
-
- fn concat_trees(
- &mut self,
- base: Option<Self::TokenStream>,
- trees: Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>>,
- ) -> Self::TokenStream {
- let mut builder = TokenStreamBuilder::new();
- if let Some(base) = base {
- builder.push(base);
- }
- for tree in trees {
- builder.push(self.from_token_tree(tree));
- }
- builder.build()
- }
-
- fn concat_streams(
- &mut self,
- base: Option<Self::TokenStream>,
- streams: Vec<Self::TokenStream>,
- ) -> Self::TokenStream {
- let mut builder = TokenStreamBuilder::new();
- if let Some(base) = base {
- builder.push(base);
- }
- for stream in streams {
- builder.push(stream);
- }
- builder.build()
- }
-
- fn into_trees(
- &mut self,
- stream: Self::TokenStream,
- ) -> Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>> {
- stream
- .into_iter()
- .map(|tree| match tree {
- tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
- bridge::TokenTree::Ident(IdentId(self.ident_interner.intern(&IdentData(ident))))
- }
- tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => bridge::TokenTree::Literal(lit),
- tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {
- bridge::TokenTree::Punct(bridge::Punct {
- ch: punct.char as u8,
- joint: punct.spacing == Spacing::Joint,
- span: punct.id,
- })
- }
- tt::TokenTree::Subtree(subtree) => bridge::TokenTree::Group(bridge::Group {
- delimiter: delim_to_external(subtree.delimiter),
- stream: if subtree.token_trees.is_empty() {
- None
- } else {
- Some(subtree.token_trees.into_iter().collect())
- },
- span: bridge::DelimSpan::from_single(
- subtree.delimiter.map_or(Span::unspecified(), |del| del.id),
- ),
- }),
- })
- .collect()
- }
-}
-
-fn delim_to_internal(d: bridge::Delimiter) -> Option<tt::Delimiter> {
- let kind = match d {
- bridge::Delimiter::Parenthesis => tt::DelimiterKind::Parenthesis,
- bridge::Delimiter::Brace => tt::DelimiterKind::Brace,
- bridge::Delimiter::Bracket => tt::DelimiterKind::Bracket,
- bridge::Delimiter::None => return None,
- };
- Some(tt::Delimiter { id: tt::TokenId::unspecified(), kind })
-}
-
-fn delim_to_external(d: Option<tt::Delimiter>) -> bridge::Delimiter {
- match d.map(|it| it.kind) {
- Some(tt::DelimiterKind::Parenthesis) => bridge::Delimiter::Parenthesis,
- Some(tt::DelimiterKind::Brace) => bridge::Delimiter::Brace,
- Some(tt::DelimiterKind::Bracket) => bridge::Delimiter::Bracket,
- None => bridge::Delimiter::None,
- }
-}
-
-fn spacing_to_internal(spacing: bridge::Spacing) -> Spacing {
- match spacing {
- bridge::Spacing::Alone => Spacing::Alone,
- bridge::Spacing::Joint => Spacing::Joint,
- }
-}
-
-fn spacing_to_external(spacing: Spacing) -> bridge::Spacing {
- match spacing {
- Spacing::Alone => bridge::Spacing::Alone,
- Spacing::Joint => bridge::Spacing::Joint,
- }
-}
-
-impl server::Ident for RustAnalyzer {
- fn new(&mut self, string: &str, span: Self::Span, _is_raw: bool) -> Self::Ident {
- IdentId(self.ident_interner.intern(&IdentData(tt::Ident { text: string.into(), id: span })))
- }
-
- fn span(&mut self, ident: Self::Ident) -> Self::Span {
- self.ident_interner.get(ident.0).0.id
- }
- fn with_span(&mut self, ident: Self::Ident, span: Self::Span) -> Self::Ident {
- let data = self.ident_interner.get(ident.0);
- let new = IdentData(tt::Ident { id: span, ..data.0.clone() });
- IdentId(self.ident_interner.intern(&new))
- }
-}
-
-impl server::Literal for RustAnalyzer {
- fn debug_kind(&mut self, _literal: &Self::Literal) -> String {
- // r-a: debug_kind and suffix are unsupported; corresponding client code has been changed to not call these.
- // They must still be present to be ABI-compatible and work with upstream proc_macro.
- "".to_owned()
- }
- fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
- Ok(Literal { text: s.into(), id: tt::TokenId::unspecified() })
- }
- fn symbol(&mut self, literal: &Self::Literal) -> String {
- literal.text.to_string()
- }
- fn suffix(&mut self, _literal: &Self::Literal) -> Option<String> {
- None
- }
-
- fn to_string(&mut self, literal: &Self::Literal) -> String {
- literal.to_string()
- }
-
- fn integer(&mut self, n: &str) -> Self::Literal {
- let n = match n.parse::<i128>() {
- Ok(n) => n.to_string(),
- Err(_) => n.parse::<u128>().unwrap().to_string(),
- };
- Literal { text: n.into(), id: tt::TokenId::unspecified() }
- }
-
- fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal {
- macro_rules! def_suffixed_integer {
- ($kind:ident, $($ty:ty),*) => {
- match $kind {
- $(
- stringify!($ty) => {
- let n: $ty = n.parse().unwrap();
- format!(concat!("{}", stringify!($ty)), n)
- }
- )*
- _ => unimplemented!("unknown args for typed_integer: n {}, kind {}", n, $kind),
- }
- }
- }
-
- let text = def_suffixed_integer! {kind, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize};
-
- Literal { text: text.into(), id: tt::TokenId::unspecified() }
- }
-
- fn float(&mut self, n: &str) -> Self::Literal {
- let n: f64 = n.parse().unwrap();
- let mut text = f64::to_string(&n);
- if !text.contains('.') {
- text += ".0"
- }
- Literal { text: text.into(), id: tt::TokenId::unspecified() }
- }
-
- fn f32(&mut self, n: &str) -> Self::Literal {
- let n: f32 = n.parse().unwrap();
- let text = format!("{}f32", n);
- Literal { text: text.into(), id: tt::TokenId::unspecified() }
- }
-
- fn f64(&mut self, n: &str) -> Self::Literal {
- let n: f64 = n.parse().unwrap();
- let text = format!("{}f64", n);
- Literal { text: text.into(), id: tt::TokenId::unspecified() }
- }
-
- fn string(&mut self, string: &str) -> Self::Literal {
- let mut escaped = String::new();
- for ch in string.chars() {
- escaped.extend(ch.escape_debug());
- }
- Literal { text: format!("\"{}\"", escaped).into(), id: tt::TokenId::unspecified() }
- }
-
- fn character(&mut self, ch: char) -> Self::Literal {
- Literal { text: format!("'{}'", ch).into(), id: tt::TokenId::unspecified() }
- }
-
- fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
- let string = bytes
- .iter()
- .cloned()
- .flat_map(ascii::escape_default)
- .map(Into::<char>::into)
- .collect::<String>();
-
- Literal { text: format!("b\"{}\"", string).into(), id: tt::TokenId::unspecified() }
- }
-
- fn span(&mut self, literal: &Self::Literal) -> Self::Span {
- literal.id
- }
-
- fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) {
- literal.id = span;
- }
-
- fn subspan(
- &mut self,
- _literal: &Self::Literal,
- _start: Bound<usize>,
- _end: Bound<usize>,
- ) -> Option<Self::Span> {
- // FIXME handle span
- None
- }
-}
-
-impl server::SourceFile for RustAnalyzer {
- // FIXME these are all stubs
- fn eq(&mut self, _file1: &Self::SourceFile, _file2: &Self::SourceFile) -> bool {
- true
- }
- fn path(&mut self, _file: &Self::SourceFile) -> String {
- String::new()
- }
- fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
- true
- }
-}
-
-impl server::Diagnostic for RustAnalyzer {
- fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
- let mut diag = Diagnostic::new(level, msg);
- diag.spans = spans;
- diag
- }
-
- fn sub(
- &mut self,
- _diag: &mut Self::Diagnostic,
- _level: Level,
- _msg: &str,
- _spans: Self::MultiSpan,
- ) {
- // FIXME handle diagnostic
- //
- }
-
- fn emit(&mut self, _diag: Self::Diagnostic) {
- // FIXME handle diagnostic
- // diag.emit()
- }
-}
-
-impl server::Span for RustAnalyzer {
- fn debug(&mut self, span: Self::Span) -> String {
- format!("{:?}", span.0)
- }
- fn source_file(&mut self, _span: Self::Span) -> Self::SourceFile {
- SourceFile {}
- }
- fn save_span(&mut self, _span: Self::Span) -> usize {
- // FIXME stub
- 0
- }
- fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
- // FIXME stub
- tt::TokenId::unspecified()
- }
- /// Recent feature, not yet in the proc_macro
- ///
- /// See PR:
- /// https://github.com/rust-lang/rust/pull/55780
- fn source_text(&mut self, _span: Self::Span) -> Option<String> {
- None
- }
-
- fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
- // FIXME handle span
- None
- }
- fn source(&mut self, span: Self::Span) -> Self::Span {
- // FIXME handle span
- span
- }
- fn start(&mut self, _span: Self::Span) -> LineColumn {
- // FIXME handle span
- LineColumn { line: 0, column: 0 }
- }
- fn end(&mut self, _span: Self::Span) -> LineColumn {
- // FIXME handle span
- LineColumn { line: 0, column: 0 }
- }
- fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
- // Just return the first span again, because some macros will unwrap the result.
- Some(first)
- }
- fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
- // FIXME handle span
- tt::TokenId::unspecified()
- }
-
- fn after(&mut self, _self_: Self::Span) -> Self::Span {
- tt::TokenId::unspecified()
- }
-
- fn before(&mut self, _self_: Self::Span) -> Self::Span {
- tt::TokenId::unspecified()
- }
-}
-
-impl server::MultiSpan for RustAnalyzer {
- fn new(&mut self) -> Self::MultiSpan {
- // FIXME handle span
- vec![]
- }
-
- fn push(&mut self, other: &mut Self::MultiSpan, span: Self::Span) {
- //TODP
- other.push(span)
- }
-}
-
-impl server::Server for RustAnalyzer {
- fn globals(&mut self) -> bridge::ExpnGlobals<Self::Span> {
- bridge::ExpnGlobals {
- def_site: Span::unspecified(),
- call_site: Span::unspecified(),
- mixed_site: Span::unspecified(),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::super::proc_macro::bridge::server::Literal;
- use super::*;
-
- #[test]
- fn test_ra_server_literals() {
- let mut srv = RustAnalyzer { ident_interner: IdentInterner::default() };
- assert_eq!(srv.integer("1234").text, "1234");
-
- assert_eq!(srv.typed_integer("12", "u8").text, "12u8");
- assert_eq!(srv.typed_integer("255", "u16").text, "255u16");
- assert_eq!(srv.typed_integer("1234", "u32").text, "1234u32");
- assert_eq!(srv.typed_integer("15846685", "u64").text, "15846685u64");
- assert_eq!(srv.typed_integer("15846685258", "u128").text, "15846685258u128");
- assert_eq!(srv.typed_integer("156788984", "usize").text, "156788984usize");
- assert_eq!(srv.typed_integer("127", "i8").text, "127i8");
- assert_eq!(srv.typed_integer("255", "i16").text, "255i16");
- assert_eq!(srv.typed_integer("1234", "i32").text, "1234i32");
- assert_eq!(srv.typed_integer("15846685", "i64").text, "15846685i64");
- assert_eq!(srv.typed_integer("15846685258", "i128").text, "15846685258i128");
- assert_eq!(srv.float("0").text, "0.0");
- assert_eq!(srv.float("15684.5867").text, "15684.5867");
- assert_eq!(srv.f32("15684.58").text, "15684.58f32");
- assert_eq!(srv.f64("15684.58").text, "15684.58f64");
-
- assert_eq!(srv.string("hello_world").text, "\"hello_world\"");
- assert_eq!(srv.character('c').text, "'c'");
- assert_eq!(srv.byte_string(b"1234586\x88").text, "b\"1234586\\x88\"");
-
- // u128::max
- assert_eq!(
- srv.integer("340282366920938463463374607431768211455").text,
- "340282366920938463463374607431768211455"
- );
- // i128::min
- assert_eq!(
- srv.integer("-170141183460469231731687303715884105728").text,
- "-170141183460469231731687303715884105728"
- );
- }
-
- #[test]
- fn test_ra_server_to_string() {
- let s = TokenStream {
- token_trees: vec![
- tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
- text: "struct".into(),
- id: tt::TokenId::unspecified(),
- })),
- tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
- text: "T".into(),
- id: tt::TokenId::unspecified(),
- })),
- tt::TokenTree::Subtree(tt::Subtree {
- delimiter: Some(tt::Delimiter {
- id: tt::TokenId::unspecified(),
- kind: tt::DelimiterKind::Brace,
- }),
- token_trees: vec![],
- }),
- ],
- };
-
- assert_eq!(s.to_string(), "struct T {}");
- }
-
- #[test]
- fn test_ra_server_from_str() {
- use std::str::FromStr;
- let subtree_paren_a = tt::TokenTree::Subtree(tt::Subtree {
- delimiter: Some(tt::Delimiter {
- id: tt::TokenId::unspecified(),
- kind: tt::DelimiterKind::Parenthesis,
- }),
- token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
- text: "a".into(),
- id: tt::TokenId::unspecified(),
- }))],
- });
-
- let t1 = TokenStream::from_str("(a)").unwrap();
- assert_eq!(t1.token_trees.len(), 1);
- assert_eq!(t1.token_trees[0], subtree_paren_a);
-
- let t2 = TokenStream::from_str("(a);").unwrap();
- assert_eq!(t2.token_trees.len(), 2);
- assert_eq!(t2.token_trees[0], subtree_paren_a);
-
- let underscore = TokenStream::from_str("_").unwrap();
- assert_eq!(
- underscore.token_trees[0],
- tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
- text: "_".into(),
- id: tt::TokenId::unspecified(),
- }))
- );
- }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
index 46882845a..e4e43e97d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
@@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder;
mod symbol;
pub use symbol::*;
-use std::{iter::FromIterator, ops::Bound};
+use std::ops::Bound;
type Group = tt::Subtree;
type TokenTree = tt::TokenTree;
@@ -37,23 +37,6 @@ pub struct SourceFile {
type Level = super::proc_macro::Level;
type LineColumn = super::proc_macro::LineColumn;
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
- level: Level,
- message: String,
- spans: Vec<Span>,
- children: Vec<Diagnostic>,
-}
-
-impl Diagnostic {
- /// Creates a new diagnostic with the given `level` and `message`.
- pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
- Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
- }
-}
-
pub struct FreeFunctions;
#[derive(Default)]
@@ -65,8 +48,6 @@ impl server::Types for RustAnalyzer {
type FreeFunctions = FreeFunctions;
type TokenStream = TokenStream;
type SourceFile = SourceFile;
- type MultiSpan = Vec<Span>;
- type Diagnostic = Diagnostic;
type Span = Span;
type Symbol = Symbol;
}
@@ -90,6 +71,10 @@ impl server::FreeFunctions for RustAnalyzer {
span: tt::TokenId::unspecified(),
})
}
+
+ fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
+ // FIXME handle diagnostic
+ }
}
impl server::TokenStream for RustAnalyzer {
@@ -282,30 +267,6 @@ impl server::SourceFile for RustAnalyzer {
}
}
-impl server::Diagnostic for RustAnalyzer {
- fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
- let mut diag = Diagnostic::new(level, msg);
- diag.spans = spans;
- diag
- }
-
- fn sub(
- &mut self,
- _diag: &mut Self::Diagnostic,
- _level: Level,
- _msg: &str,
- _spans: Self::MultiSpan,
- ) {
- // FIXME handle diagnostic
- //
- }
-
- fn emit(&mut self, _diag: Self::Diagnostic) {
- // FIXME handle diagnostic
- // diag.emit()
- }
-}
-
impl server::Span for RustAnalyzer {
fn debug(&mut self, span: Self::Span) -> String {
format!("{:?}", span.0)
@@ -372,18 +333,6 @@ impl server::Span for RustAnalyzer {
}
}
-impl server::MultiSpan for RustAnalyzer {
- fn new(&mut self) -> Self::MultiSpan {
- // FIXME handle span
- vec![]
- }
-
- fn push(&mut self, other: &mut Self::MultiSpan, span: Self::Span) {
- //TODP
- other.push(span)
- }
-}
-
impl server::Symbol for RustAnalyzer {
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
// FIXME: nfc-normalize and validate idents
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
index bcf3f1184..f7d3a3091 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
@@ -5,7 +5,7 @@
//! compiler into submodules of this module (e.g proc_macro_srv::abis::abi_1_47).
//!
//! All of these ABIs are subsumed in the `Abi` enum, which exposes a simple
-//! interface the rest of rust analyzer can use to talk to the macro
+//! interface the rest of rust-analyzer can use to talk to the macro
//! provider.
//!
//! # Adding a new ABI
@@ -25,7 +25,6 @@
mod abi_1_58;
mod abi_1_63;
-mod abi_1_64;
#[cfg(feature = "sysroot-abi")]
mod abi_sysroot;
@@ -34,12 +33,11 @@ include!(concat!(env!("OUT_DIR"), "/rustc_version.rs"));
// Used by `test/utils.rs`
#[cfg(test)]
-pub(crate) use abi_1_64::TokenStream as TestTokenStream;
+pub(crate) use abi_1_63::TokenStream as TestTokenStream;
use super::dylib::LoadProcMacroDylibError;
pub(crate) use abi_1_58::Abi as Abi_1_58;
pub(crate) use abi_1_63::Abi as Abi_1_63;
-pub(crate) use abi_1_64::Abi as Abi_1_64;
#[cfg(feature = "sysroot-abi")]
pub(crate) use abi_sysroot::Abi as Abi_Sysroot;
use libloading::Library;
@@ -58,7 +56,6 @@ impl PanicMessage {
pub(crate) enum Abi {
Abi1_58(Abi_1_58),
Abi1_63(Abi_1_63),
- Abi1_64(Abi_1_64),
#[cfg(feature = "sysroot-abi")]
AbiSysroot(Abi_Sysroot),
}
@@ -120,10 +117,6 @@ impl Abi {
let inner = unsafe { Abi_1_63::from_lib(lib, symbol_name) }?;
Ok(Abi::Abi1_63(inner))
}
- (1, 64..) => {
- let inner = unsafe { Abi_1_64::from_lib(lib, symbol_name) }?;
- Ok(Abi::Abi1_64(inner))
- }
_ => Err(LoadProcMacroDylibError::UnsupportedABI),
}
}
@@ -137,7 +130,6 @@ impl Abi {
match self {
Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
Self::Abi1_63(abi) => abi.expand(macro_name, macro_body, attributes),
- Self::Abi1_64(abi) => abi.expand(macro_name, macro_body, attributes),
#[cfg(feature = "sysroot-abi")]
Self::AbiSysroot(abi) => abi.expand(macro_name, macro_body, attributes),
}
@@ -147,7 +139,6 @@ impl Abi {
match self {
Self::Abi1_58(abi) => abi.list_macros(),
Self::Abi1_63(abi) => abi.list_macros(),
- Self::Abi1_64(abi) => abi.list_macros(),
#[cfg(feature = "sysroot-abi")]
Self::AbiSysroot(abi) => abi.list_macros(),
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
index 2b6c070fe..7aba74e53 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
@@ -1,7 +1,6 @@
//! Handles dynamic library loading for proc macro
use std::{
- convert::TryInto,
fmt,
fs::File,
io,
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
index 4c205b9ca..3679bfc43 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
@@ -26,6 +26,7 @@ use std::{
ffi::OsString,
fs,
path::{Path, PathBuf},
+ thread,
time::SystemTime,
};
@@ -65,18 +66,16 @@ impl ProcMacroSrv {
let macro_body = task.macro_body.to_subtree();
let attributes = task.attributes.map(|it| it.to_subtree());
- // FIXME: replace this with std's scoped threads once they stabilize
- // (then remove dependency on crossbeam)
- let result = crossbeam::scope(|s| {
- let res = match s
- .builder()
+ let result = thread::scope(|s| {
+ let thread = thread::Builder::new()
.stack_size(EXPANDER_STACK_SIZE)
.name(task.macro_name.clone())
- .spawn(|_| {
+ .spawn_scoped(s, || {
expander
.expand(&task.macro_name, &macro_body, attributes.as_ref())
.map(|it| FlatTree::new(&it))
- }) {
+ });
+ let res = match thread {
Ok(handle) => handle.join(),
Err(e) => std::panic::resume_unwind(Box::new(e)),
};
@@ -86,10 +85,6 @@ impl ProcMacroSrv {
Err(e) => std::panic::resume_unwind(e),
}
});
- let result = match result {
- Ok(result) => result,
- Err(e) => std::panic::resume_unwind(e),
- };
prev_env.rollback();
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
index 07222907f..6339d56d0 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
@@ -19,7 +19,7 @@ fn test_derive_error() {
expect![[r##"
SUBTREE $
IDENT compile_error 4294967295
- PUNCH ! [alone] 4294967295
+ PUNCH ! [joint] 4294967295
SUBTREE () 4294967295
LITERAL "#[derive(DeriveError)] struct S ;" 4294967295
PUNCH ; [alone] 4294967295"##]],
@@ -109,7 +109,7 @@ fn test_fn_like_macro_clone_literals() {
PUNCH , [alone] 4294967295
LITERAL 2_u32 4294967295
PUNCH , [alone] 4294967295
- PUNCH - [alone] 4294967295
+ PUNCH - [joint] 4294967295
LITERAL 4i64 4294967295
PUNCH , [alone] 4294967295
LITERAL 3.14f32 4294967295
@@ -130,7 +130,7 @@ fn test_attr_macro() {
expect![[r##"
SUBTREE $
IDENT compile_error 4294967295
- PUNCH ! [alone] 4294967295
+ PUNCH ! [joint] 4294967295
SUBTREE () 4294967295
LITERAL "#[attr_error(some arguments)] mod m {}" 4294967295
PUNCH ; [alone] 4294967295"##]],
diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
index ee7f8339a..84e772d16 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
@@ -12,6 +12,7 @@ use cargo_metadata::{camino::Utf8Path, Message};
use la_arena::ArenaMap;
use paths::AbsPathBuf;
use rustc_hash::FxHashMap;
+use semver::Version;
use serde::Deserialize;
use crate::{cfg_flag::CfgFlag, CargoConfig, CargoWorkspace, Package};
@@ -77,9 +78,32 @@ impl WorkspaceBuildScripts {
config: &CargoConfig,
workspace: &CargoWorkspace,
progress: &dyn Fn(String),
+ toolchain: &Option<Version>,
) -> io::Result<WorkspaceBuildScripts> {
- let mut cmd = Self::build_command(config);
+ const RUST_1_62: Version = Version::new(1, 62, 0);
+ match Self::run_(Self::build_command(config), config, workspace, progress) {
+ Ok(WorkspaceBuildScripts { error: Some(error), .. })
+ if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
+ {
+ // building build scripts failed, attempt to build with --keep-going so
+ // that we potentially get more build data
+ let mut cmd = Self::build_command(config);
+ cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
+ let mut res = Self::run_(cmd, config, workspace, progress)?;
+ res.error = Some(error);
+ Ok(res)
+ }
+ res => res,
+ }
+ }
+
+ fn run_(
+ mut cmd: Command,
+ config: &CargoConfig,
+ workspace: &CargoWorkspace,
+ progress: &dyn Fn(String),
+ ) -> io::Result<WorkspaceBuildScripts> {
if config.wrap_rustc_in_build_scripts {
// Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
// that to compile only proc macros and build scripts during the initial
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index 597880c2c..eed955b42 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -19,7 +19,7 @@ use crate::{utf8_stdout, ManifestPath};
/// [`CargoWorkspace`] represents the logical structure of, well, a Cargo
/// workspace. It pretty closely mirrors `cargo metadata` output.
///
-/// Note that internally, rust analyzer uses a different structure:
+/// Note that internally, rust-analyzer uses a different structure:
/// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates,
/// while this knows about `Packages` & `Targets`: purely cargo-related
/// concepts.
diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs
index e3f83084a..b81b7432f 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs
@@ -3,7 +3,7 @@
//!
//! Pure model is represented by the [`base_db::CrateGraph`] from another crate.
//!
-//! In this crate, we are conserned with "real world" project models.
+//! In this crate, we are concerned with "real world" project models.
//!
//! Specifically, here we have a representation for a Cargo project
//! ([`CargoWorkspace`]) and for manually specified layout ([`ProjectJson`]).
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index e304a59c0..9ccb6e910 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -28,6 +28,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr
rustc: None,
rustc_cfg: Vec::new(),
cfg_overrides,
+ toolchain: None,
};
to_crate_graph(project_workspace)
}
@@ -184,10 +185,10 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
is_proc_macro: false,
},
CrateId(
- 2,
+ 1,
): CrateData {
root_file_id: FileId(
- 3,
+ 2,
),
edition: Edition2018,
version: Some(
@@ -196,9 +197,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "an_example",
+ "hello_world",
),
- canonical_name: "an-example",
+ canonical_name: "hello-world",
},
),
cfg_options: CfgOptions(
@@ -259,77 +260,85 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
is_proc_macro: false,
},
CrateId(
- 4,
+ 2,
): CrateData {
root_file_id: FileId(
- 5,
+ 3,
),
- edition: Edition2015,
+ edition: Edition2018,
version: Some(
- "0.2.98",
+ "0.1.0",
),
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "libc",
+ "an_example",
),
- canonical_name: "libc",
+ canonical_name: "an-example",
},
),
cfg_options: CfgOptions(
[
"debug_assertions",
- "feature=default",
- "feature=std",
],
),
potential_cfg_options: CfgOptions(
[
"debug_assertions",
- "feature=align",
- "feature=const-extern-fn",
- "feature=default",
- "feature=extra_traits",
- "feature=rustc-dep-of-std",
- "feature=std",
- "feature=use_std",
],
),
env: Env {
entries: {
"CARGO_PKG_LICENSE": "",
"CARGO_PKG_VERSION_MAJOR": "0",
- "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
- "CARGO_PKG_VERSION": "0.2.98",
+ "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
+ "CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "libc",
+ "CARGO_CRATE_NAME": "hello_world",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
- "CARGO_PKG_NAME": "libc",
- "CARGO_PKG_VERSION_PATCH": "98",
+ "CARGO_PKG_NAME": "hello-world",
+ "CARGO_PKG_VERSION_PATCH": "0",
"CARGO": "cargo",
"CARGO_PKG_REPOSITORY": "",
- "CARGO_PKG_VERSION_MINOR": "2",
+ "CARGO_PKG_VERSION_MINOR": "1",
"CARGO_PKG_VERSION_PRE": "",
},
},
- dependencies: [],
+ dependencies: [
+ Dependency {
+ crate_id: CrateId(
+ 0,
+ ),
+ name: CrateName(
+ "hello_world",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 4,
+ ),
+ name: CrateName(
+ "libc",
+ ),
+ prelude: true,
+ },
+ ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo {
- repo: Some(
- "https://github.com/rust-lang/libc",
- ),
+ repo: None,
},
is_proc_macro: false,
},
CrateId(
- 1,
+ 3,
): CrateData {
root_file_id: FileId(
- 2,
+ 4,
),
edition: Edition2018,
version: Some(
@@ -338,9 +347,9 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "hello_world",
+ "it",
),
- canonical_name: "hello-world",
+ canonical_name: "it",
},
),
cfg_options: CfgOptions(
@@ -401,77 +410,69 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
is_proc_macro: false,
},
CrateId(
- 3,
+ 4,
): CrateData {
root_file_id: FileId(
- 4,
+ 5,
),
- edition: Edition2018,
+ edition: Edition2015,
version: Some(
- "0.1.0",
+ "0.2.98",
),
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "it",
+ "libc",
),
- canonical_name: "it",
+ canonical_name: "libc",
},
),
cfg_options: CfgOptions(
[
"debug_assertions",
+ "feature=default",
+ "feature=std",
],
),
potential_cfg_options: CfgOptions(
[
"debug_assertions",
+ "feature=align",
+ "feature=const-extern-fn",
+ "feature=default",
+ "feature=extra_traits",
+ "feature=rustc-dep-of-std",
+ "feature=std",
+ "feature=use_std",
],
),
env: Env {
entries: {
"CARGO_PKG_LICENSE": "",
"CARGO_PKG_VERSION_MAJOR": "0",
- "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
- "CARGO_PKG_VERSION": "0.1.0",
+ "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
+ "CARGO_PKG_VERSION": "0.2.98",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "libc",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
- "CARGO_PKG_NAME": "hello-world",
- "CARGO_PKG_VERSION_PATCH": "0",
+ "CARGO_PKG_NAME": "libc",
+ "CARGO_PKG_VERSION_PATCH": "98",
"CARGO": "cargo",
"CARGO_PKG_REPOSITORY": "",
- "CARGO_PKG_VERSION_MINOR": "1",
+ "CARGO_PKG_VERSION_MINOR": "2",
"CARGO_PKG_VERSION_PRE": "",
},
},
- dependencies: [
- Dependency {
- crate_id: CrateId(
- 0,
- ),
- name: CrateName(
- "hello_world",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 4,
- ),
- name: CrateName(
- "libc",
- ),
- prelude: true,
- },
- ],
+ dependencies: [],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo {
- repo: None,
+ repo: Some(
+ "https://github.com/rust-lang/libc",
+ ),
},
is_proc_macro: false,
},
@@ -566,10 +567,10 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
is_proc_macro: false,
},
CrateId(
- 2,
+ 1,
): CrateData {
root_file_id: FileId(
- 3,
+ 2,
),
edition: Edition2018,
version: Some(
@@ -578,9 +579,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "an_example",
+ "hello_world",
),
- canonical_name: "an-example",
+ canonical_name: "hello-world",
},
),
cfg_options: CfgOptions(
@@ -643,77 +644,87 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
is_proc_macro: false,
},
CrateId(
- 4,
+ 2,
): CrateData {
root_file_id: FileId(
- 5,
+ 3,
),
- edition: Edition2015,
+ edition: Edition2018,
version: Some(
- "0.2.98",
+ "0.1.0",
),
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "libc",
+ "an_example",
),
- canonical_name: "libc",
+ canonical_name: "an-example",
},
),
cfg_options: CfgOptions(
[
"debug_assertions",
- "feature=default",
- "feature=std",
+ "test",
],
),
potential_cfg_options: CfgOptions(
[
"debug_assertions",
- "feature=align",
- "feature=const-extern-fn",
- "feature=default",
- "feature=extra_traits",
- "feature=rustc-dep-of-std",
- "feature=std",
- "feature=use_std",
+ "test",
],
),
env: Env {
entries: {
"CARGO_PKG_LICENSE": "",
"CARGO_PKG_VERSION_MAJOR": "0",
- "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
- "CARGO_PKG_VERSION": "0.2.98",
+ "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
+ "CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "libc",
+ "CARGO_CRATE_NAME": "hello_world",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
- "CARGO_PKG_NAME": "libc",
- "CARGO_PKG_VERSION_PATCH": "98",
+ "CARGO_PKG_NAME": "hello-world",
+ "CARGO_PKG_VERSION_PATCH": "0",
"CARGO": "cargo",
"CARGO_PKG_REPOSITORY": "",
- "CARGO_PKG_VERSION_MINOR": "2",
+ "CARGO_PKG_VERSION_MINOR": "1",
"CARGO_PKG_VERSION_PRE": "",
},
},
- dependencies: [],
+ dependencies: [
+ Dependency {
+ crate_id: CrateId(
+ 0,
+ ),
+ name: CrateName(
+ "hello_world",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 4,
+ ),
+ name: CrateName(
+ "libc",
+ ),
+ prelude: true,
+ },
+ ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo {
- repo: Some(
- "https://github.com/rust-lang/libc",
- ),
+ repo: None,
},
is_proc_macro: false,
},
CrateId(
- 1,
+ 3,
): CrateData {
root_file_id: FileId(
- 2,
+ 4,
),
edition: Edition2018,
version: Some(
@@ -722,9 +733,9 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "hello_world",
+ "it",
),
- canonical_name: "hello-world",
+ canonical_name: "it",
},
),
cfg_options: CfgOptions(
@@ -787,79 +798,69 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
is_proc_macro: false,
},
CrateId(
- 3,
+ 4,
): CrateData {
root_file_id: FileId(
- 4,
+ 5,
),
- edition: Edition2018,
+ edition: Edition2015,
version: Some(
- "0.1.0",
+ "0.2.98",
),
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "it",
+ "libc",
),
- canonical_name: "it",
+ canonical_name: "libc",
},
),
cfg_options: CfgOptions(
[
"debug_assertions",
- "test",
+ "feature=default",
+ "feature=std",
],
),
potential_cfg_options: CfgOptions(
[
"debug_assertions",
- "test",
+ "feature=align",
+ "feature=const-extern-fn",
+ "feature=default",
+ "feature=extra_traits",
+ "feature=rustc-dep-of-std",
+ "feature=std",
+ "feature=use_std",
],
),
env: Env {
entries: {
"CARGO_PKG_LICENSE": "",
"CARGO_PKG_VERSION_MAJOR": "0",
- "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
- "CARGO_PKG_VERSION": "0.1.0",
+ "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
+ "CARGO_PKG_VERSION": "0.2.98",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "libc",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
- "CARGO_PKG_NAME": "hello-world",
- "CARGO_PKG_VERSION_PATCH": "0",
+ "CARGO_PKG_NAME": "libc",
+ "CARGO_PKG_VERSION_PATCH": "98",
"CARGO": "cargo",
"CARGO_PKG_REPOSITORY": "",
- "CARGO_PKG_VERSION_MINOR": "1",
+ "CARGO_PKG_VERSION_MINOR": "2",
"CARGO_PKG_VERSION_PRE": "",
},
},
- dependencies: [
- Dependency {
- crate_id: CrateId(
- 0,
- ),
- name: CrateName(
- "hello_world",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 4,
- ),
- name: CrateName(
- "libc",
- ),
- prelude: true,
- },
- ],
+ dependencies: [],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo {
- repo: None,
+ repo: Some(
+ "https://github.com/rust-lang/libc",
+ ),
},
is_proc_macro: false,
},
@@ -945,10 +946,10 @@ fn cargo_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 2,
+ 1,
): CrateData {
root_file_id: FileId(
- 3,
+ 2,
),
edition: Edition2018,
version: Some(
@@ -957,9 +958,9 @@ fn cargo_hello_world_project_model() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "an_example",
+ "hello_world",
),
- canonical_name: "an-example",
+ canonical_name: "hello-world",
},
),
cfg_options: CfgOptions(
@@ -1022,77 +1023,87 @@ fn cargo_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 4,
+ 2,
): CrateData {
root_file_id: FileId(
- 5,
+ 3,
),
- edition: Edition2015,
+ edition: Edition2018,
version: Some(
- "0.2.98",
+ "0.1.0",
),
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "libc",
+ "an_example",
),
- canonical_name: "libc",
+ canonical_name: "an-example",
},
),
cfg_options: CfgOptions(
[
"debug_assertions",
- "feature=default",
- "feature=std",
+ "test",
],
),
potential_cfg_options: CfgOptions(
[
"debug_assertions",
- "feature=align",
- "feature=const-extern-fn",
- "feature=default",
- "feature=extra_traits",
- "feature=rustc-dep-of-std",
- "feature=std",
- "feature=use_std",
+ "test",
],
),
env: Env {
entries: {
"CARGO_PKG_LICENSE": "",
"CARGO_PKG_VERSION_MAJOR": "0",
- "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
- "CARGO_PKG_VERSION": "0.2.98",
+ "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
+ "CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "libc",
+ "CARGO_CRATE_NAME": "hello_world",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
- "CARGO_PKG_NAME": "libc",
- "CARGO_PKG_VERSION_PATCH": "98",
+ "CARGO_PKG_NAME": "hello-world",
+ "CARGO_PKG_VERSION_PATCH": "0",
"CARGO": "cargo",
"CARGO_PKG_REPOSITORY": "",
- "CARGO_PKG_VERSION_MINOR": "2",
+ "CARGO_PKG_VERSION_MINOR": "1",
"CARGO_PKG_VERSION_PRE": "",
},
},
- dependencies: [],
+ dependencies: [
+ Dependency {
+ crate_id: CrateId(
+ 0,
+ ),
+ name: CrateName(
+ "hello_world",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 4,
+ ),
+ name: CrateName(
+ "libc",
+ ),
+ prelude: true,
+ },
+ ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo {
- repo: Some(
- "https://github.com/rust-lang/libc",
- ),
+ repo: None,
},
is_proc_macro: false,
},
CrateId(
- 1,
+ 3,
): CrateData {
root_file_id: FileId(
- 2,
+ 4,
),
edition: Edition2018,
version: Some(
@@ -1101,9 +1112,9 @@ fn cargo_hello_world_project_model() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "hello_world",
+ "it",
),
- canonical_name: "hello-world",
+ canonical_name: "it",
},
),
cfg_options: CfgOptions(
@@ -1166,79 +1177,69 @@ fn cargo_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 3,
+ 4,
): CrateData {
root_file_id: FileId(
- 4,
+ 5,
),
- edition: Edition2018,
+ edition: Edition2015,
version: Some(
- "0.1.0",
+ "0.2.98",
),
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "it",
+ "libc",
),
- canonical_name: "it",
+ canonical_name: "libc",
},
),
cfg_options: CfgOptions(
[
"debug_assertions",
- "test",
+ "feature=default",
+ "feature=std",
],
),
potential_cfg_options: CfgOptions(
[
"debug_assertions",
- "test",
+ "feature=align",
+ "feature=const-extern-fn",
+ "feature=default",
+ "feature=extra_traits",
+ "feature=rustc-dep-of-std",
+ "feature=std",
+ "feature=use_std",
],
),
env: Env {
entries: {
"CARGO_PKG_LICENSE": "",
"CARGO_PKG_VERSION_MAJOR": "0",
- "CARGO_MANIFEST_DIR": "$ROOT$hello-world",
- "CARGO_PKG_VERSION": "0.1.0",
+ "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
+ "CARGO_PKG_VERSION": "0.2.98",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "libc",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
- "CARGO_PKG_NAME": "hello-world",
- "CARGO_PKG_VERSION_PATCH": "0",
+ "CARGO_PKG_NAME": "libc",
+ "CARGO_PKG_VERSION_PATCH": "98",
"CARGO": "cargo",
"CARGO_PKG_REPOSITORY": "",
- "CARGO_PKG_VERSION_MINOR": "1",
+ "CARGO_PKG_VERSION_MINOR": "2",
"CARGO_PKG_VERSION_PRE": "",
},
},
- dependencies: [
- Dependency {
- crate_id: CrateId(
- 0,
- ),
- name: CrateName(
- "hello_world",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 4,
- ),
- name: CrateName(
- "libc",
- ),
- prelude: true,
- },
- ],
+ dependencies: [],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo {
- repo: None,
+ repo: Some(
+ "https://github.com/rust-lang/libc",
+ ),
},
is_proc_macro: false,
},
@@ -1300,19 +1301,53 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 10,
+ 1,
): CrateData {
root_file_id: FileId(
- 11,
+ 2,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "unwind",
+ "core",
),
- canonical_name: "unwind",
+ canonical_name: "core",
+ },
+ ),
+ cfg_options: CfgOptions(
+ [],
+ ),
+ potential_cfg_options: CfgOptions(
+ [],
+ ),
+ env: Env {
+ entries: {},
+ },
+ dependencies: [],
+ proc_macro: Err(
+ "no proc macro loaded for sysroot crate",
+ ),
+ origin: Lang(
+ Core,
+ ),
+ is_proc_macro: false,
+ },
+ CrateId(
+ 2,
+ ): CrateData {
+ root_file_id: FileId(
+ 3,
+ ),
+ edition: Edition2018,
+ version: None,
+ display_name: Some(
+ CrateDisplayName {
+ crate_name: CrateName(
+ "panic_abort",
+ ),
+ canonical_name: "panic_abort",
},
),
cfg_options: CfgOptions(
@@ -1334,19 +1369,19 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 7,
+ 3,
): CrateData {
root_file_id: FileId(
- 8,
+ 4,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "std_detect",
+ "panic_unwind",
),
- canonical_name: "std_detect",
+ canonical_name: "panic_unwind",
},
),
cfg_options: CfgOptions(
@@ -1412,19 +1447,19 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 1,
+ 5,
): CrateData {
root_file_id: FileId(
- 2,
+ 6,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "core",
+ "profiler_builtins",
),
- canonical_name: "core",
+ canonical_name: "profiler_builtins",
},
),
cfg_options: CfgOptions(
@@ -1441,24 +1476,24 @@ fn rust_project_hello_world_project_model() {
"no proc macro loaded for sysroot crate",
),
origin: Lang(
- Core,
+ Other,
),
is_proc_macro: false,
},
CrateId(
- 11,
+ 6,
): CrateData {
root_file_id: FileId(
- 12,
+ 7,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "hello_world",
+ "std",
),
- canonical_name: "hello_world",
+ canonical_name: "std",
},
),
cfg_options: CfgOptions(
@@ -1473,6 +1508,15 @@ fn rust_project_hello_world_project_model() {
dependencies: [
Dependency {
crate_id: CrateId(
+ 0,
+ ),
+ name: CrateName(
+ "alloc",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
1,
),
name: CrateName(
@@ -1482,19 +1526,46 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 0,
+ 2,
),
name: CrateName(
- "alloc",
+ "panic_abort",
),
prelude: true,
},
Dependency {
crate_id: CrateId(
- 6,
+ 3,
),
name: CrateName(
- "std",
+ "panic_unwind",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 5,
+ ),
+ name: CrateName(
+ "profiler_builtins",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 7,
+ ),
+ name: CrateName(
+ "std_detect",
+ ),
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 8,
+ ),
+ name: CrateName(
+ "term",
),
prelude: true,
},
@@ -1505,31 +1576,40 @@ fn rust_project_hello_world_project_model() {
name: CrateName(
"test",
),
- prelude: false,
+ prelude: true,
+ },
+ Dependency {
+ crate_id: CrateId(
+ 10,
+ ),
+ name: CrateName(
+ "unwind",
+ ),
+ prelude: true,
},
],
proc_macro: Err(
- "no proc macro dylib present",
+ "no proc macro loaded for sysroot crate",
+ ),
+ origin: Lang(
+ Std,
),
- origin: CratesIo {
- repo: None,
- },
is_proc_macro: false,
},
CrateId(
- 8,
+ 7,
): CrateData {
root_file_id: FileId(
- 9,
+ 8,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "term",
+ "std_detect",
),
- canonical_name: "term",
+ canonical_name: "std_detect",
},
),
cfg_options: CfgOptions(
@@ -1551,19 +1631,19 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 5,
+ 8,
): CrateData {
root_file_id: FileId(
- 6,
+ 9,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "profiler_builtins",
+ "term",
),
- canonical_name: "profiler_builtins",
+ canonical_name: "term",
},
),
cfg_options: CfgOptions(
@@ -1585,19 +1665,19 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 2,
+ 9,
): CrateData {
root_file_id: FileId(
- 3,
+ 10,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "panic_abort",
+ "test",
),
- canonical_name: "panic_abort",
+ canonical_name: "test",
},
),
cfg_options: CfgOptions(
@@ -1614,24 +1694,24 @@ fn rust_project_hello_world_project_model() {
"no proc macro loaded for sysroot crate",
),
origin: Lang(
- Other,
+ Test,
),
is_proc_macro: false,
},
CrateId(
- 9,
+ 10,
): CrateData {
root_file_id: FileId(
- 10,
+ 11,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "test",
+ "unwind",
),
- canonical_name: "test",
+ canonical_name: "unwind",
},
),
cfg_options: CfgOptions(
@@ -1648,24 +1728,24 @@ fn rust_project_hello_world_project_model() {
"no proc macro loaded for sysroot crate",
),
origin: Lang(
- Test,
+ Other,
),
is_proc_macro: false,
},
CrateId(
- 6,
+ 11,
): CrateData {
root_file_id: FileId(
- 7,
+ 12,
),
edition: Edition2018,
version: None,
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "std",
+ "hello_world",
),
- canonical_name: "std",
+ canonical_name: "hello_world",
},
),
cfg_options: CfgOptions(
@@ -1680,15 +1760,6 @@ fn rust_project_hello_world_project_model() {
dependencies: [
Dependency {
crate_id: CrateId(
- 0,
- ),
- name: CrateName(
- "alloc",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
1,
),
name: CrateName(
@@ -1698,46 +1769,19 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 2,
- ),
- name: CrateName(
- "panic_abort",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 3,
- ),
- name: CrateName(
- "panic_unwind",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 5,
- ),
- name: CrateName(
- "profiler_builtins",
- ),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 7,
+ 0,
),
name: CrateName(
- "std_detect",
+ "alloc",
),
prelude: true,
},
Dependency {
crate_id: CrateId(
- 8,
+ 6,
),
name: CrateName(
- "term",
+ "std",
),
prelude: true,
},
@@ -1748,58 +1792,15 @@ fn rust_project_hello_world_project_model() {
name: CrateName(
"test",
),
- prelude: true,
- },
- Dependency {
- crate_id: CrateId(
- 10,
- ),
- name: CrateName(
- "unwind",
- ),
- prelude: true,
+ prelude: false,
},
],
proc_macro: Err(
- "no proc macro loaded for sysroot crate",
- ),
- origin: Lang(
- Std,
- ),
- is_proc_macro: false,
- },
- CrateId(
- 3,
- ): CrateData {
- root_file_id: FileId(
- 4,
- ),
- edition: Edition2018,
- version: None,
- display_name: Some(
- CrateDisplayName {
- crate_name: CrateName(
- "panic_unwind",
- ),
- canonical_name: "panic_unwind",
- },
- ),
- cfg_options: CfgOptions(
- [],
- ),
- potential_cfg_options: CfgOptions(
- [],
+ "no proc macro dylib present",
),
- env: Env {
- entries: {},
+ origin: CratesIo {
+ repo: None,
},
- dependencies: [],
- proc_macro: Err(
- "no proc macro loaded for sysroot crate",
- ),
- origin: Lang(
- Other,
- ),
is_proc_macro: false,
},
},
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index b144006b4..818bbed6a 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -12,7 +12,8 @@ use base_db::{
use cfg::{CfgDiff, CfgOptions};
use paths::{AbsPath, AbsPathBuf};
use rustc_hash::{FxHashMap, FxHashSet};
-use stdx::always;
+use semver::Version;
+use stdx::{always, hash::NoHashHashMap};
use crate::{
build_scripts::BuildScriptOutput,
@@ -77,6 +78,7 @@ pub enum ProjectWorkspace {
/// different target.
rustc_cfg: Vec<CfgFlag>,
cfg_overrides: CfgOverrides,
+ toolchain: Option<Version>,
},
/// Project workspace was manually specified using a `rust-project.json` file.
Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
@@ -105,6 +107,7 @@ impl fmt::Debug for ProjectWorkspace {
rustc,
rustc_cfg,
cfg_overrides,
+ toolchain,
} => f
.debug_struct("Cargo")
.field("root", &cargo.workspace_root().file_name())
@@ -116,6 +119,7 @@ impl fmt::Debug for ProjectWorkspace {
)
.field("n_rustc_cfg", &rustc_cfg.len())
.field("n_cfg_overrides", &cfg_overrides.len())
+ .field("toolchain", &toolchain)
.finish(),
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => {
let mut debug_struct = f.debug_struct("Json");
@@ -160,6 +164,9 @@ impl ProjectWorkspace {
cmd.arg("--version");
cmd
})?;
+ let toolchain = cargo_version
+ .get("cargo ".len()..)
+ .and_then(|it| Version::parse(it.split_whitespace().next()?).ok());
let meta = CargoWorkspace::fetch_metadata(
&cargo_toml,
@@ -169,9 +176,9 @@ impl ProjectWorkspace {
)
.with_context(|| {
format!(
- "Failed to read Cargo metadata from Cargo.toml file {}, {}",
+ "Failed to read Cargo metadata from Cargo.toml file {}, {:?}",
cargo_toml.display(),
- cargo_version
+ toolchain
)
})?;
let cargo = CargoWorkspace::new(meta);
@@ -219,6 +226,7 @@ impl ProjectWorkspace {
rustc,
rustc_cfg,
cfg_overrides,
+ toolchain,
}
}
};
@@ -271,8 +279,8 @@ impl ProjectWorkspace {
progress: &dyn Fn(String),
) -> Result<WorkspaceBuildScripts> {
match self {
- ProjectWorkspace::Cargo { cargo, .. } => {
- WorkspaceBuildScripts::run(config, cargo, progress).with_context(|| {
+ ProjectWorkspace::Cargo { cargo, toolchain, .. } => {
+ WorkspaceBuildScripts::run(config, cargo, progress, toolchain).with_context(|| {
format!("Failed to run build scripts for {}", &cargo.workspace_root().display())
})
}
@@ -320,6 +328,7 @@ impl ProjectWorkspace {
rustc_cfg: _,
cfg_overrides: _,
build_scripts,
+ toolchain: _,
} => {
cargo
.packages()
@@ -425,6 +434,7 @@ impl ProjectWorkspace {
rustc_cfg,
cfg_overrides,
build_scripts,
+ toolchain: _,
} => cargo_to_crate_graph(
rustc_cfg.clone(),
cfg_overrides,
@@ -461,7 +471,7 @@ fn project_json_to_crate_graph(
.map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load));
let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default();
- let crates: FxHashMap<CrateId, CrateId> = project
+ let crates: NoHashHashMap<CrateId, CrateId> = project
.crates()
.filter_map(|(crate_id, krate)| {
let file_path = &krate.root_module;
@@ -760,7 +770,7 @@ fn handle_rustc_crates(
queue.push_back(root_pkg);
while let Some(pkg) = queue.pop_front() {
// Don't duplicate packages if they are dependended on a diamond pattern
- // N.B. if this line is ommitted, we try to analyse over 4_800_000 crates
+ // N.B. if this line is omitted, we try to analyse over 4_800_000 crates
// which is not ideal
if rustc_pkg_crates.contains_key(&pkg) {
continue;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index 07771d1b3..539258918 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -22,7 +22,8 @@ anyhow = "1.0.57"
crossbeam-channel = "0.5.5"
dissimilar = "1.0.4"
itertools = "0.10.3"
-lsp-types = { version = "0.93.0", features = ["proposed"] }
+scip = "0.1.1"
+lsp-types = { version = "0.93.1", features = ["proposed"] }
parking_lot = "0.12.1"
xflags = "0.2.4"
oorandom = "11.1.3"
@@ -88,5 +89,5 @@ in-rust-tree = [
"proc-macro-srv/sysroot-abi",
"sourcegen/in-rust-tree",
"ide/in-rust-tree",
- "syntax/in-rust-tree"
+ "syntax/in-rust-tree",
]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs
index 0b69f75bc..298814af5 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs
@@ -52,7 +52,7 @@ impl Logger {
// merge chalk filter to our main filter (from RA_LOG env).
//
// The acceptable syntax of CHALK_DEBUG is `target[span{field=value}]=level`.
- // As the value should only affect chalk crates, we'd better mannually
+ // As the value should only affect chalk crates, we'd better manually
// specify the target. And for simplicity, CHALK_DEBUG only accept the value
// that specify level.
let chalk_level_dir = std::env::var("CHALK_DEBUG")
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
index e9de23cb3..f6a680297 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
@@ -93,6 +93,7 @@ fn try_main() -> Result<()> {
flags::RustAnalyzerCmd::Ssr(cmd) => cmd.run()?,
flags::RustAnalyzerCmd::Search(cmd) => cmd.run()?,
flags::RustAnalyzerCmd::Lsif(cmd) => cmd.run()?,
+ flags::RustAnalyzerCmd::Scip(cmd) => cmd.run()?,
}
Ok(())
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
index 2f6d4706d..38e9c7dd7 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
@@ -17,6 +17,11 @@ pub(crate) fn run_rustc_skipping_cargo_checking(
rustc_executable: OsString,
args: Vec<OsString>,
) -> io::Result<ExitCode> {
+ // `CARGO_CFG_TARGET_ARCH` is only set by cargo when executing build scripts
+ // We don't want to exit out checks unconditionally with success if a build
+ // script tries to invoke checks themselves
+ // See https://github.com/rust-lang/rust-analyzer/issues/12973 for context
+ let not_invoked_by_build_script = std::env::var_os("CARGO_CFG_TARGET_ARCH").is_none();
let is_cargo_check = args.iter().any(|arg| {
let arg = arg.to_string_lossy();
// `cargo check` invokes `rustc` with `--emit=metadata` argument.
@@ -29,7 +34,7 @@ pub(crate) fn run_rustc_skipping_cargo_checking(
// The default output filename is CRATE_NAME.rmeta.
arg.starts_with("--emit=") && arg.contains("metadata") && !arg.contains("link")
});
- if is_cargo_check {
+ if not_invoked_by_build_script && is_cargo_check {
return Ok(ExitCode(Some(0)));
}
run_rustc(rustc_executable, args)
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs
index 6ccdaa86d..60ba67e25 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs
@@ -9,6 +9,7 @@ mod analysis_stats;
mod diagnostics;
mod ssr;
mod lsif;
+mod scip;
mod progress_report;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
index 52511ceb5..247007db0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -43,7 +43,7 @@ impl flags::Diagnostics {
println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
for diagnostic in analysis
.diagnostics(
- &DiagnosticsConfig::default(),
+ &DiagnosticsConfig::test_sample(),
AssistResolveStrategy::None,
file_id,
)
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
index 19907ebdd..aa32654fb 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
@@ -10,6 +10,10 @@ xflags::xflags! {
src "./src/cli/flags.rs"
/// LSP server for the Rust programming language.
+ ///
+ /// Subcommands and their flags do not provide any stability guarantees and may be removed or
+ /// changed without notice. Top-level flags that are not are marked as [Unstable] provide
+ /// backwards-compatibility and may be relied on.
cmd rust-analyzer {
/// Verbosity level, can be repeated multiple times.
repeated -v, --verbose
@@ -21,7 +25,7 @@ xflags::xflags! {
/// Flush log records to the file immediately.
optional --no-log-buffering
- /// Wait until a debugger is attached to (requires debug build).
+ /// [Unstable] Wait until a debugger is attached to (requires debug build).
optional --wait-dbg
default cmd lsp-server {
@@ -108,6 +112,10 @@ xflags::xflags! {
cmd lsif
required path: PathBuf
{}
+
+ cmd scip
+ required path: PathBuf
+ {}
}
}
@@ -136,6 +144,7 @@ pub enum RustAnalyzerCmd {
Search(Search),
ProcMacro(ProcMacro),
Lsif(Lsif),
+ Scip(Scip),
}
#[derive(Debug)]
@@ -203,6 +212,11 @@ pub struct Lsif {
pub path: PathBuf,
}
+#[derive(Debug)]
+pub struct Scip {
+ pub path: PathBuf,
+}
+
impl RustAnalyzer {
pub const HELP: &'static str = Self::HELP_;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
new file mode 100644
index 000000000..65cc993c4
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -0,0 +1,448 @@
+//! SCIP generator
+
+use std::{
+ collections::{HashMap, HashSet},
+ time::Instant,
+};
+
+use crate::line_index::{LineEndings, LineIndex, OffsetEncoding};
+use hir::Name;
+use ide::{
+ LineCol, MonikerDescriptorKind, MonikerResult, StaticIndex, StaticIndexedFile, TextRange,
+ TokenId,
+};
+use ide_db::LineIndexDatabase;
+use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace};
+use scip::types as scip_types;
+use std::env;
+
+use crate::cli::{
+ flags,
+ load_cargo::{load_workspace, LoadCargoConfig},
+ Result,
+};
+
+impl flags::Scip {
+ pub fn run(self) -> Result<()> {
+ eprintln!("Generating SCIP start...");
+ let now = Instant::now();
+ let cargo_config = CargoConfig::default();
+
+ let no_progress = &|s| (eprintln!("rust-analyzer: Loading {}", s));
+ let load_cargo_config = LoadCargoConfig {
+ load_out_dirs_from_check: true,
+ with_proc_macro: true,
+ prefill_caches: true,
+ };
+ let path = vfs::AbsPathBuf::assert(env::current_dir()?.join(&self.path));
+ let rootpath = path.normalize();
+ let manifest = ProjectManifest::discover_single(&path)?;
+
+ let workspace = ProjectWorkspace::load(manifest, &cargo_config, no_progress)?;
+
+ let (host, vfs, _) = load_workspace(workspace, &load_cargo_config)?;
+ let db = host.raw_database();
+ let analysis = host.analysis();
+
+ let si = StaticIndex::compute(&analysis);
+
+ let mut index = scip_types::Index {
+ metadata: Some(scip_types::Metadata {
+ version: scip_types::ProtocolVersion::UnspecifiedProtocolVersion.into(),
+ tool_info: Some(scip_types::ToolInfo {
+ name: "rust-analyzer".to_owned(),
+ version: "0.1".to_owned(),
+ arguments: vec![],
+ ..Default::default()
+ })
+ .into(),
+ project_root: format!(
+ "file://{}",
+ path.normalize()
+ .as_os_str()
+ .to_str()
+ .ok_or(anyhow::anyhow!("Unable to normalize project_root path"))?
+ .to_string()
+ ),
+ text_document_encoding: scip_types::TextEncoding::UTF8.into(),
+ ..Default::default()
+ })
+ .into(),
+ ..Default::default()
+ };
+
+ let mut symbols_emitted: HashSet<TokenId> = HashSet::default();
+ let mut tokens_to_symbol: HashMap<TokenId, String> = HashMap::new();
+
+ for file in si.files {
+ let mut local_count = 0;
+ let mut new_local_symbol = || {
+ let new_symbol = scip::types::Symbol::new_local(local_count);
+ local_count += 1;
+
+ new_symbol
+ };
+
+ let StaticIndexedFile { file_id, tokens, .. } = file;
+ let relative_path = match get_relative_filepath(&vfs, &rootpath, file_id) {
+ Some(relative_path) => relative_path,
+ None => continue,
+ };
+
+ let line_index = LineIndex {
+ index: db.line_index(file_id),
+ encoding: OffsetEncoding::Utf8,
+ endings: LineEndings::Unix,
+ };
+
+ let mut doc = scip_types::Document {
+ relative_path,
+ language: "rust".to_string(),
+ ..Default::default()
+ };
+
+ tokens.into_iter().for_each(|(range, id)| {
+ let token = si.tokens.get(id).unwrap();
+
+ let mut occurrence = scip_types::Occurrence::default();
+ occurrence.range = text_range_to_scip_range(&line_index, range);
+ occurrence.symbol = match tokens_to_symbol.get(&id) {
+ Some(symbol) => symbol.clone(),
+ None => {
+ let symbol = match &token.moniker {
+ Some(moniker) => moniker_to_symbol(&moniker),
+ None => new_local_symbol(),
+ };
+
+ let symbol = scip::symbol::format_symbol(symbol);
+ tokens_to_symbol.insert(id, symbol.clone());
+ symbol
+ }
+ };
+
+ if let Some(def) = token.definition {
+ if def.range == range {
+ occurrence.symbol_roles |= scip_types::SymbolRole::Definition as i32;
+ }
+
+ if !symbols_emitted.contains(&id) {
+ symbols_emitted.insert(id);
+
+ let mut symbol_info = scip_types::SymbolInformation::default();
+ symbol_info.symbol = occurrence.symbol.clone();
+ if let Some(hover) = &token.hover {
+ if !hover.markup.as_str().is_empty() {
+ symbol_info.documentation = vec![hover.markup.as_str().to_string()];
+ }
+ }
+
+ doc.symbols.push(symbol_info)
+ }
+ }
+
+ doc.occurrences.push(occurrence);
+ });
+
+ if doc.occurrences.is_empty() {
+ continue;
+ }
+
+ index.documents.push(doc);
+ }
+
+ scip::write_message_to_file("index.scip", index)
+ .map_err(|err| anyhow::anyhow!("Failed to write scip to file: {}", err))?;
+
+ eprintln!("Generating SCIP finished {:?}", now.elapsed());
+ Ok(())
+ }
+}
+
+fn get_relative_filepath(
+ vfs: &vfs::Vfs,
+ rootpath: &vfs::AbsPathBuf,
+ file_id: ide::FileId,
+) -> Option<String> {
+ Some(vfs.file_path(file_id).as_path()?.strip_prefix(&rootpath)?.as_ref().to_str()?.to_string())
+}
+
+// SCIP Ranges have a (very large) optimization that ranges if they are on the same line
+// only encode as a vector of [start_line, start_col, end_col].
+//
+// This transforms a line index into the optimized SCIP Range.
+fn text_range_to_scip_range(line_index: &LineIndex, range: TextRange) -> Vec<i32> {
+ let LineCol { line: start_line, col: start_col } = line_index.index.line_col(range.start());
+ let LineCol { line: end_line, col: end_col } = line_index.index.line_col(range.end());
+
+ if start_line == end_line {
+ vec![start_line as i32, start_col as i32, end_col as i32]
+ } else {
+ vec![start_line as i32, start_col as i32, end_line as i32, end_col as i32]
+ }
+}
+
+fn new_descriptor_str(
+ name: &str,
+ suffix: scip_types::descriptor::Suffix,
+) -> scip_types::Descriptor {
+ scip_types::Descriptor {
+ name: name.to_string(),
+ disambiguator: "".to_string(),
+ suffix: suffix.into(),
+ ..Default::default()
+ }
+}
+
+fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_types::Descriptor {
+ let mut name = name.to_string();
+ if name.contains("'") {
+ name = format!("`{}`", name);
+ }
+
+ new_descriptor_str(name.as_str(), suffix)
+}
+
+/// Loosely based on `def_to_moniker`
+///
+/// Only returns a Symbol when it's a non-local symbol.
+/// So if the visibility isn't outside of a document, then it will return None
+fn moniker_to_symbol(moniker: &MonikerResult) -> scip_types::Symbol {
+ use scip_types::descriptor::Suffix::*;
+
+ let package_name = moniker.package_information.name.clone();
+ let version = moniker.package_information.version.clone();
+ let descriptors = moniker
+ .identifier
+ .description
+ .iter()
+ .map(|desc| {
+ new_descriptor(
+ desc.name.clone(),
+ match desc.desc {
+ MonikerDescriptorKind::Namespace => Namespace,
+ MonikerDescriptorKind::Type => Type,
+ MonikerDescriptorKind::Term => Term,
+ MonikerDescriptorKind::Method => Method,
+ MonikerDescriptorKind::TypeParameter => TypeParameter,
+ MonikerDescriptorKind::Parameter => Parameter,
+ MonikerDescriptorKind::Macro => Macro,
+ MonikerDescriptorKind::Meta => Meta,
+ },
+ )
+ })
+ .collect();
+
+ scip_types::Symbol {
+ scheme: "rust-analyzer".into(),
+ package: Some(scip_types::Package {
+ manager: "cargo".to_string(),
+ name: package_name,
+ version,
+ ..Default::default()
+ })
+ .into(),
+ descriptors,
+ ..Default::default()
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use hir::Semantics;
+ use ide::{AnalysisHost, FilePosition};
+ use ide_db::defs::IdentClass;
+ use ide_db::{base_db::fixture::ChangeFixture, helpers::pick_best_token};
+ use scip::symbol::format_symbol;
+ use syntax::SyntaxKind::*;
+ use syntax::{AstNode, T};
+
+ fn position(ra_fixture: &str) -> (AnalysisHost, FilePosition) {
+ let mut host = AnalysisHost::default();
+ let change_fixture = ChangeFixture::parse(ra_fixture);
+ host.raw_database_mut().apply_change(change_fixture.change);
+ let (file_id, range_or_offset) =
+ change_fixture.file_position.expect("expected a marker ($0)");
+ let offset = range_or_offset.expect_offset();
+ (host, FilePosition { file_id, offset })
+ }
+
+ /// If expected == "", then assert that there are no symbols (this is basically local symbol)
+ #[track_caller]
+ fn check_symbol(ra_fixture: &str, expected: &str) {
+ let (host, position) = position(ra_fixture);
+
+ let FilePosition { file_id, offset } = position;
+
+ let db = host.raw_database();
+ let sema = &Semantics::new(db);
+ let file = sema.parse(file_id).syntax().clone();
+ let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
+ IDENT
+ | INT_NUMBER
+ | LIFETIME_IDENT
+ | T![self]
+ | T![super]
+ | T![crate]
+ | T![Self]
+ | COMMENT => 2,
+ kind if kind.is_trivia() => 0,
+ _ => 1,
+ })
+ .expect("OK OK");
+
+ let navs = sema
+ .descend_into_macros(original_token.clone())
+ .into_iter()
+ .filter_map(|token| {
+ IdentClass::classify_token(sema, &token).map(IdentClass::definitions).map(|it| {
+ it.into_iter().flat_map(|def| {
+ let module = def.module(db).unwrap();
+ let current_crate = module.krate();
+
+ match MonikerResult::from_def(sema.db, def, current_crate) {
+ Some(moniker_result) => Some(moniker_to_symbol(&moniker_result)),
+ None => None,
+ }
+ })
+ })
+ })
+ .flatten()
+ .collect::<Vec<_>>();
+
+ if expected == "" {
+ assert_eq!(0, navs.len(), "must have no symbols {:?}", navs);
+ return;
+ }
+
+ assert_eq!(1, navs.len(), "must have one symbol {:?}", navs);
+
+ let res = navs.get(0).unwrap();
+ let formatted = format_symbol(res.clone());
+ assert_eq!(formatted, expected);
+ }
+
+ #[test]
+ fn basic() {
+ check_symbol(
+ r#"
+//- /lib.rs crate:main deps:foo
+use foo::example_mod::func;
+fn main() {
+ func$0();
+}
+//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+pub mod example_mod {
+ pub fn func() {}
+}
+"#,
+ "rust-analyzer cargo foo 0.1.0 example_mod/func().",
+ );
+ }
+
+ #[test]
+ fn symbol_for_trait() {
+ check_symbol(
+ r#"
+//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+pub mod module {
+ pub trait MyTrait {
+ pub fn func$0() {}
+ }
+}
+"#,
+ "rust-analyzer cargo foo 0.1.0 module/MyTrait#func().",
+ );
+ }
+
+ #[test]
+ fn symbol_for_trait_constant() {
+ check_symbol(
+ r#"
+ //- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+ pub mod module {
+ pub trait MyTrait {
+ const MY_CONST$0: u8;
+ }
+ }
+ "#,
+ "rust-analyzer cargo foo 0.1.0 module/MyTrait#MY_CONST.",
+ );
+ }
+
+ #[test]
+ fn symbol_for_trait_type() {
+ check_symbol(
+ r#"
+ //- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+ pub mod module {
+ pub trait MyTrait {
+ type MyType$0;
+ }
+ }
+ "#,
+ // "foo::module::MyTrait::MyType",
+ "rust-analyzer cargo foo 0.1.0 module/MyTrait#[MyType]",
+ );
+ }
+
+ #[test]
+ fn symbol_for_trait_impl_function() {
+ check_symbol(
+ r#"
+ //- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+ pub mod module {
+ pub trait MyTrait {
+ pub fn func() {}
+ }
+
+ struct MyStruct {}
+
+ impl MyTrait for MyStruct {
+ pub fn func$0() {}
+ }
+ }
+ "#,
+ // "foo::module::MyStruct::MyTrait::func",
+ "rust-analyzer cargo foo 0.1.0 module/MyStruct#MyTrait#func().",
+ );
+ }
+
+ #[test]
+ fn symbol_for_field() {
+ check_symbol(
+ r#"
+ //- /lib.rs crate:main deps:foo
+ use foo::St;
+ fn main() {
+ let x = St { a$0: 2 };
+ }
+ //- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+ pub struct St {
+ pub a: i32,
+ }
+ "#,
+ "rust-analyzer cargo foo 0.1.0 St#a.",
+ );
+ }
+
+ #[test]
+ fn local_symbol_for_local() {
+ check_symbol(
+ r#"
+ //- /lib.rs crate:main deps:foo
+ use foo::module::func;
+ fn main() {
+ func();
+ }
+ //- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
+ pub mod module {
+ pub fn func() {
+ let x$0 = 2;
+ }
+ }
+ "#,
+ "",
+ );
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index ac0fdf85a..54dcb42d9 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -12,8 +12,8 @@ use std::{ffi::OsString, fmt, iter, path::PathBuf};
use flycheck::FlycheckConfig;
use ide::{
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
- HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayHintsConfig, JoinLinesConfig,
- Snippet, SnippetScope,
+ HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayHintsConfig,
+ JoinLinesConfig, Snippet, SnippetScope,
};
use ide_db::{
imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@@ -45,7 +45,8 @@ mod patch_old_style;
// - foo_command = overrides the subcommand, foo_overrideCommand allows full overwriting, extra args only applies for foo_command
// Defines the server-side configuration of the rust-analyzer. We generate
-// *parts* of VS Code's `package.json` config from this.
+// *parts* of VS Code's `package.json` config from this. Run `cargo test` to
+// re-generate that file.
//
// However, editor specific config, which the server doesn't know about, should
// be specified directly in `package.json`.
@@ -120,6 +121,10 @@ config_data! {
/// Cargo, you might also want to change
/// `#rust-analyzer.cargo.buildScripts.overrideCommand#`.
///
+ /// If there are multiple linked projects, this command is invoked for
+ /// each of them, with the working directory being the project root
+ /// (i.e., the folder containing the `Cargo.toml`).
+ ///
/// An example command would be:
///
/// ```bash
@@ -243,7 +248,10 @@ config_data! {
hover_actions_run_enable: bool = "true",
/// Whether to show documentation on hover.
- hover_documentation_enable: bool = "true",
+ hover_documentation_enable: bool = "true",
+ /// Whether to show keyword hover popups. Only applies when
+ /// `#rust-analyzer.hover.documentation.enable#` is set.
+ hover_documentation_keywords_enable: bool = "true",
/// Use markdown syntax for links in hover.
hover_links_enable: bool = "true",
@@ -377,6 +385,34 @@ config_data! {
/// available on a nightly build.
rustfmt_rangeFormatting_enable: bool = "false",
+ /// Inject additional highlighting into doc comments.
+ ///
+ /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
+ /// doc links.
+ semanticHighlighting_doc_comment_inject_enable: bool = "true",
+ /// Use semantic tokens for operators.
+ ///
+ /// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
+ /// they are tagged with modifiers.
+ semanticHighlighting_operator_enable: bool = "true",
+ /// Use specialized semantic tokens for operators.
+ ///
+ /// When enabled, rust-analyzer will emit special token types for operator tokens instead
+ /// of the generic `operator` token type.
+ semanticHighlighting_operator_specialization_enable: bool = "false",
+ /// Use semantic tokens for punctuations.
+ ///
+ /// When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when
+ /// they are tagged with modifiers or have a special role.
+ semanticHighlighting_punctuation_enable: bool = "false",
+ /// When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro
+ /// calls.
+ semanticHighlighting_punctuation_separate_macro_bang: bool = "false",
+ /// Use specialized semantic tokens for punctuations.
+ ///
+ /// When enabled, rust-analyzer will emit special token types for punctuation tokens instead
+ /// of the generic `punctuation` token type.
+ semanticHighlighting_punctuation_specialization_enable: bool = "false",
/// Use semantic tokens for strings.
///
/// In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
@@ -881,6 +917,7 @@ impl Config {
ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
},
+ insert_use: self.insert_use_config(),
}
}
@@ -1162,8 +1199,19 @@ impl Config {
}
}
- pub fn highlighting_strings(&self) -> bool {
- self.data.semanticHighlighting_strings_enable
+ pub fn highlighting_config(&self) -> HighlightConfig {
+ HighlightConfig {
+ strings: self.data.semanticHighlighting_strings_enable,
+ punctuation: self.data.semanticHighlighting_punctuation_enable,
+ specialize_punctuation: self
+ .data
+ .semanticHighlighting_punctuation_specialization_enable,
+ macro_bang: self.data.semanticHighlighting_punctuation_separate_macro_bang,
+ operator: self.data.semanticHighlighting_operator_enable,
+ specialize_operator: self.data.semanticHighlighting_operator_specialization_enable,
+ inject_doc_comment: self.data.semanticHighlighting_doc_comment_inject_enable,
+ syntactic_name_ref_highlighting: false,
+ }
}
pub fn hover(&self) -> HoverConfig {
@@ -1186,6 +1234,7 @@ impl Config {
HoverDocFormat::PlainText
}
}),
+ keywords: self.data.hover_documentation_keywords_enable,
}
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
index 202a01adf..f516c194d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
@@ -4,11 +4,12 @@ pub(crate) mod to_proto;
use std::{mem, sync::Arc};
use ide::FileId;
-use rustc_hash::{FxHashMap, FxHashSet};
+use ide_db::FxHashMap;
+use stdx::hash::{NoHashHashMap, NoHashHashSet};
use crate::lsp_ext;
-pub(crate) type CheckFixes = Arc<FxHashMap<FileId, Vec<Fix>>>;
+pub(crate) type CheckFixes = Arc<NoHashHashMap<usize, NoHashHashMap<FileId, Vec<Fix>>>>;
#[derive(Debug, Default, Clone)]
pub struct DiagnosticsMapConfig {
@@ -19,12 +20,12 @@ pub struct DiagnosticsMapConfig {
#[derive(Debug, Default, Clone)]
pub(crate) struct DiagnosticCollection {
- // FIXME: should be FxHashMap<FileId, Vec<ra_id::Diagnostic>>
- pub(crate) native: FxHashMap<FileId, Vec<lsp_types::Diagnostic>>,
+ // FIXME: should be NoHashHashMap<FileId, Vec<ra_id::Diagnostic>>
+ pub(crate) native: NoHashHashMap<FileId, Vec<lsp_types::Diagnostic>>,
// FIXME: should be Vec<flycheck::Diagnostic>
- pub(crate) check: FxHashMap<FileId, Vec<lsp_types::Diagnostic>>,
+ pub(crate) check: NoHashHashMap<usize, NoHashHashMap<FileId, Vec<lsp_types::Diagnostic>>>,
pub(crate) check_fixes: CheckFixes,
- changes: FxHashSet<FileId>,
+ changes: NoHashHashSet<FileId>,
}
#[derive(Debug, Clone)]
@@ -35,9 +36,19 @@ pub(crate) struct Fix {
}
impl DiagnosticCollection {
- pub(crate) fn clear_check(&mut self) {
+ pub(crate) fn clear_check(&mut self, flycheck_id: usize) {
+ if let Some(it) = Arc::make_mut(&mut self.check_fixes).get_mut(&flycheck_id) {
+ it.clear();
+ }
+ if let Some(it) = self.check.get_mut(&flycheck_id) {
+ self.changes.extend(it.drain().map(|(key, _value)| key));
+ }
+ }
+
+ pub(crate) fn clear_check_all(&mut self) {
Arc::make_mut(&mut self.check_fixes).clear();
- self.changes.extend(self.check.drain().map(|(key, _value)| key))
+ self.changes
+ .extend(self.check.values_mut().flat_map(|it| it.drain().map(|(key, _value)| key)))
}
pub(crate) fn clear_native_for(&mut self, file_id: FileId) {
@@ -47,11 +58,12 @@ impl DiagnosticCollection {
pub(crate) fn add_check_diagnostic(
&mut self,
+ flycheck_id: usize,
file_id: FileId,
diagnostic: lsp_types::Diagnostic,
fix: Option<Fix>,
) {
- let diagnostics = self.check.entry(file_id).or_default();
+ let diagnostics = self.check.entry(flycheck_id).or_default().entry(file_id).or_default();
for existing_diagnostic in diagnostics.iter() {
if are_diagnostics_equal(existing_diagnostic, &diagnostic) {
return;
@@ -59,7 +71,7 @@ impl DiagnosticCollection {
}
let check_fixes = Arc::make_mut(&mut self.check_fixes);
- check_fixes.entry(file_id).or_default().extend(fix);
+ check_fixes.entry(flycheck_id).or_default().entry(file_id).or_default().extend(fix);
diagnostics.push(diagnostic);
self.changes.insert(file_id);
}
@@ -89,11 +101,12 @@ impl DiagnosticCollection {
file_id: FileId,
) -> impl Iterator<Item = &lsp_types::Diagnostic> {
let native = self.native.get(&file_id).into_iter().flatten();
- let check = self.check.get(&file_id).into_iter().flatten();
+ let check =
+ self.check.values().filter_map(move |it| it.get(&file_id)).into_iter().flatten();
native.chain(check)
}
- pub(crate) fn take_changes(&mut self) -> Option<FxHashSet<FileId>> {
+ pub(crate) fn take_changes(&mut self) -> Option<NoHashHashSet<FileId>> {
if self.changes.is_empty() {
return None;
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
index cff4bd7f6..74689fd87 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -512,7 +512,7 @@ fn clippy_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescript
#[cfg(test)]
#[cfg(not(windows))]
mod tests {
- use std::{convert::TryInto, path::Path};
+ use std::path::Path;
use crate::{config::Config, global_state::GlobalState};
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 8f881cba4..92df4d70f 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -14,6 +14,7 @@ use parking_lot::{Mutex, RwLock};
use proc_macro_api::ProcMacroServer;
use project_model::{CargoWorkspace, ProjectWorkspace, Target, WorkspaceBuildScripts};
use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
use vfs::AnchoredPathBuf;
use crate::{
@@ -67,7 +68,7 @@ pub(crate) struct GlobalState {
pub(crate) flycheck_sender: Sender<flycheck::Message>,
pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
- pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
+ pub(crate) vfs: Arc<RwLock<(vfs::Vfs, NoHashHashMap<FileId, LineEndings>)>>,
pub(crate) vfs_config_version: u32,
pub(crate) vfs_progress_config_version: u32,
pub(crate) vfs_progress_n_total: usize,
@@ -113,8 +114,9 @@ pub(crate) struct GlobalStateSnapshot {
pub(crate) check_fixes: CheckFixes,
mem_docs: MemDocs,
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
- vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
+ vfs: Arc<RwLock<(vfs::Vfs, NoHashHashMap<FileId, LineEndings>)>>,
pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
+ pub(crate) proc_macros_loaded: bool,
}
impl std::panic::UnwindSafe for GlobalStateSnapshot {}
@@ -157,7 +159,7 @@ impl GlobalState {
flycheck_sender,
flycheck_receiver,
- vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))),
+ vfs: Arc::new(RwLock::new((vfs::Vfs::default(), NoHashHashMap::default()))),
vfs_config_version: 0,
vfs_progress_config_version: 0,
vfs_progress_n_total: 0,
@@ -176,9 +178,9 @@ impl GlobalState {
pub(crate) fn process_changes(&mut self) -> bool {
let _p = profile::span("GlobalState::process_changes");
- let mut fs_changes = Vec::new();
// A file was added or deleted
let mut has_structure_changes = false;
+ let mut workspace_structure_change = None;
let (change, changed_files) = {
let mut change = Change::new();
@@ -192,15 +194,14 @@ impl GlobalState {
if let Some(path) = vfs.file_path(file.file_id).as_path() {
let path = path.to_path_buf();
if reload::should_refresh_for_change(&path, file.change_kind) {
- self.fetch_workspaces_queue
- .request_op(format!("vfs file change: {}", path.display()));
+ workspace_structure_change = Some(path);
}
- fs_changes.push((path, file.change_kind));
if file.is_created_or_deleted() {
has_structure_changes = true;
}
}
+ // Clear native diagnostics when their file gets deleted
if !file.exists() {
self.diagnostics.clear_native_for(file.file_id);
}
@@ -226,14 +227,24 @@ impl GlobalState {
self.analysis_host.apply_change(change);
- let raw_database = &self.analysis_host.raw_database();
- self.proc_macro_changed =
- changed_files.iter().filter(|file| !file.is_created_or_deleted()).any(|file| {
- let crates = raw_database.relevant_crates(file.file_id);
- let crate_graph = raw_database.crate_graph();
+ {
+ let raw_database = self.analysis_host.raw_database();
+ // FIXME: ideally we should only trigger a workspace fetch for non-library changes
+ // but somethings going wrong with the source root business when we add a new local
+ // crate see https://github.com/rust-lang/rust-analyzer/issues/13029
+ if let Some(path) = workspace_structure_change {
+ self.fetch_workspaces_queue
+ .request_op(format!("workspace vfs file change: {}", path.display()));
+ }
+ self.proc_macro_changed =
+ changed_files.iter().filter(|file| !file.is_created_or_deleted()).any(|file| {
+ let crates = raw_database.relevant_crates(file.file_id);
+ let crate_graph = raw_database.crate_graph();
+
+ crates.iter().any(|&krate| crate_graph[krate].is_proc_macro)
+ });
+ }
- crates.iter().any(|&krate| crate_graph[krate].is_proc_macro)
- });
true
}
@@ -246,6 +257,7 @@ impl GlobalState {
check_fixes: Arc::clone(&self.diagnostics.check_fixes),
mem_docs: self.mem_docs.clone(),
semantic_tokens_cache: Arc::clone(&self.semantic_tokens_cache),
+ proc_macros_loaded: !self.fetch_build_data_queue.last_op_result().0.is_empty(),
}
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
index deb777c95..e79cf3d3f 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
@@ -51,6 +51,12 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
Ok(())
}
+pub(crate) fn handle_cancel_flycheck(state: &mut GlobalState, _: ()) -> Result<()> {
+ let _p = profile::span("handle_stop_flycheck");
+ state.flycheck.iter().for_each(|flycheck| flycheck.cancel());
+ Ok(())
+}
+
pub(crate) fn handle_analyzer_status(
snap: GlobalStateSnapshot,
params: lsp_ext::AnalyzerStatusParams,
@@ -703,10 +709,8 @@ pub(crate) fn handle_runnables(
let mut res = Vec::new();
for runnable in snap.analysis.runnables(file_id)? {
- if let Some(offset) = offset {
- if !runnable.nav.full_range.contains_inclusive(offset) {
- continue;
- }
+ if should_skip_for_offset(&runnable, offset) {
+ continue;
}
if should_skip_target(&runnable, cargo_spec.as_ref()) {
continue;
@@ -772,6 +776,14 @@ pub(crate) fn handle_runnables(
Ok(res)
}
+fn should_skip_for_offset(runnable: &Runnable, offset: Option<TextSize>) -> bool {
+ match offset {
+ None => false,
+ _ if matches!(&runnable.kind, RunnableKind::TestMod { .. }) => false,
+ Some(offset) => !runnable.nav.full_range.contains_inclusive(offset),
+ }
+}
+
pub(crate) fn handle_related_tests(
snap: GlobalStateSnapshot,
params: lsp_types::TextDocumentPositionParams,
@@ -1094,7 +1106,9 @@ pub(crate) fn handle_code_action(
}
// Fixes from `cargo check`.
- for fix in snap.check_fixes.get(&frange.file_id).into_iter().flatten() {
+ for fix in
+ snap.check_fixes.values().filter_map(|it| it.get(&frange.file_id)).into_iter().flatten()
+ {
// FIXME: this mapping is awkward and shouldn't exist. Refactor
// `snap.check_fixes` to not convert to LSP prematurely.
let intersect_fix_range = fix
@@ -1318,8 +1332,7 @@ pub(crate) fn publish_diagnostics(
.unwrap(),
}),
source: Some("rust-analyzer".to_string()),
- // https://github.com/rust-lang/rust-analyzer/issues/11404
- message: if !d.message.is_empty() { d.message } else { " ".to_string() },
+ message: d.message,
related_information: None,
tags: if d.unused { Some(vec![DiagnosticTag::UNNECESSARY]) } else { None },
data: None,
@@ -1349,7 +1362,7 @@ pub(crate) fn handle_inlay_hints(
.map(|it| {
to_proto::inlay_hint(&snap, &line_index, inlay_hints_config.render_colons, it)
})
- .collect(),
+ .collect::<Result<Vec<_>>>()?,
))
}
@@ -1491,10 +1504,12 @@ pub(crate) fn handle_semantic_tokens_full(
let text = snap.analysis.file_text(file_id)?;
let line_index = snap.file_line_index(file_id)?;
- let highlights = snap.analysis.highlight(file_id)?;
- let highlight_strings = snap.config.highlighting_strings();
- let semantic_tokens =
- to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
+ let mut highlight_config = snap.config.highlighting_config();
+ // Avoid flashing a bunch of unresolved references when the proc-macro servers haven't been spawned yet.
+ highlight_config.syntactic_name_ref_highlighting = !snap.proc_macros_loaded;
+
+ let highlights = snap.analysis.highlight(highlight_config, file_id)?;
+ let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights);
// Unconditionally cache the tokens
snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens.clone());
@@ -1512,10 +1527,12 @@ pub(crate) fn handle_semantic_tokens_full_delta(
let text = snap.analysis.file_text(file_id)?;
let line_index = snap.file_line_index(file_id)?;
- let highlights = snap.analysis.highlight(file_id)?;
- let highlight_strings = snap.config.highlighting_strings();
- let semantic_tokens =
- to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
+ let mut highlight_config = snap.config.highlighting_config();
+ // Avoid flashing a bunch of unresolved references when the proc-macro servers haven't been spawned yet.
+ highlight_config.syntactic_name_ref_highlighting = !snap.proc_macros_loaded;
+
+ let highlights = snap.analysis.highlight(highlight_config, file_id)?;
+ let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights);
let mut cache = snap.semantic_tokens_cache.lock();
let cached_tokens = cache.entry(params.text_document.uri).or_default();
@@ -1543,10 +1560,8 @@ pub(crate) fn handle_semantic_tokens_range(
let text = snap.analysis.file_text(frange.file_id)?;
let line_index = snap.file_line_index(frange.file_id)?;
- let highlights = snap.analysis.highlight_range(frange)?;
- let highlight_strings = snap.config.highlighting_strings();
- let semantic_tokens =
- to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
+ let highlights = snap.analysis.highlight_range(snap.config.highlighting_config(), frange)?;
+ let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights);
Ok(Some(semantic_tokens.into()))
}
@@ -1764,7 +1779,7 @@ fn run_rustfmt(
let line_index = snap.file_line_index(file_id)?;
- let mut rustfmt = match snap.config.rustfmt() {
+ let mut command = match snap.config.rustfmt() {
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
let mut cmd = process::Command::new(toolchain::rustfmt());
cmd.args(extra_args);
@@ -1829,12 +1844,12 @@ fn run_rustfmt(
}
};
- let mut rustfmt = rustfmt
+ let mut rustfmt = command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
- .context(format!("Failed to spawn {:?}", rustfmt))?;
+ .context(format!("Failed to spawn {:?}", command))?;
rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
@@ -1853,7 +1868,11 @@ fn run_rustfmt(
// formatting because otherwise an error is surfaced to the user on top of the
// syntax error diagnostics they're already receiving. This is especially jarring
// if they have format on save enabled.
- tracing::info!("rustfmt exited with status 1, assuming parse error and ignoring");
+ tracing::warn!(
+ ?command,
+ %captured_stderr,
+ "rustfmt exited with status 1"
+ );
Ok(None)
}
_ => {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
index 47cdd8dfc..e49a98685 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -6,8 +6,8 @@
//! code here exercise this specific completion, and thus have a fast
//! edit/compile/test cycle.
//!
-//! Note that "Rust Analyzer: Run" action does not allow running a single test
-//! in release mode in VS Code. There's however "Rust Analyzer: Copy Run Command Line"
+//! Note that "rust-analyzer: Run" action does not allow running a single test
+//! in release mode in VS Code. There's however "rust-analyzer: Copy Run Command Line"
//! which you can use to paste the command in terminal and add `--release` manually.
use std::sync::Arc;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs
index 5f0e10862..e61c8b643 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs
@@ -129,6 +129,14 @@ pub struct ExpandedMacro {
pub expansion: String,
}
+pub enum CancelFlycheck {}
+
+impl Request for CancelFlycheck {
+ type Params = ();
+ type Result = ();
+ const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
+}
+
pub enum MatchingBrace {}
impl Request for MatchingBrace {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 5845cf712..3cfbc2e4e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -2,13 +2,16 @@
//! requests/replies and notifications back to the client.
use std::{
fmt,
+ ops::Deref,
sync::Arc,
time::{Duration, Instant},
};
use always_assert::always;
use crossbeam_channel::{select, Receiver};
-use ide_db::base_db::{SourceDatabaseExt, VfsPath};
+use flycheck::FlycheckHandle;
+use ide_db::base_db::{SourceDatabase, SourceDatabaseExt, VfsPath};
+use itertools::Itertools;
use lsp_server::{Connection, Notification, Request};
use lsp_types::notification::Notification as _;
use vfs::{ChangeKind, FileId};
@@ -203,81 +206,14 @@ impl GlobalState {
}
lsp_server::Message::Response(resp) => self.complete_request(resp),
},
- Event::Task(mut task) => {
+ Event::Task(task) => {
let _p = profile::span("GlobalState::handle_event/task");
let mut prime_caches_progress = Vec::new();
- loop {
- match task {
- Task::Response(response) => self.respond(response),
- Task::Retry(req) => self.on_request(req),
- Task::Diagnostics(diagnostics_per_file) => {
- for (file_id, diagnostics) in diagnostics_per_file {
- self.diagnostics.set_native_diagnostics(file_id, diagnostics)
- }
- }
- Task::PrimeCaches(progress) => match progress {
- PrimeCachesProgress::Begin => prime_caches_progress.push(progress),
- PrimeCachesProgress::Report(_) => {
- match prime_caches_progress.last_mut() {
- Some(last @ PrimeCachesProgress::Report(_)) => {
- // Coalesce subsequent update events.
- *last = progress;
- }
- _ => prime_caches_progress.push(progress),
- }
- }
- PrimeCachesProgress::End { .. } => prime_caches_progress.push(progress),
- },
- Task::FetchWorkspace(progress) => {
- let (state, msg) = match progress {
- ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
- ProjectWorkspaceProgress::Report(msg) => {
- (Progress::Report, Some(msg))
- }
- ProjectWorkspaceProgress::End(workspaces) => {
- self.fetch_workspaces_queue.op_completed(workspaces);
-
- let old = Arc::clone(&self.workspaces);
- self.switch_workspaces("fetched workspace".to_string());
- let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
- if self.config.run_build_scripts() && workspaces_updated {
- self.fetch_build_data_queue
- .request_op(format!("workspace updated"));
- }
-
- (Progress::End, None)
- }
- };
-
- self.report_progress("Fetching", state, msg, None);
- }
- Task::FetchBuildData(progress) => {
- let (state, msg) = match progress {
- BuildDataProgress::Begin => (Some(Progress::Begin), None),
- BuildDataProgress::Report(msg) => {
- (Some(Progress::Report), Some(msg))
- }
- BuildDataProgress::End(build_data_result) => {
- self.fetch_build_data_queue.op_completed(build_data_result);
-
- self.switch_workspaces("fetched build data".to_string());
-
- (Some(Progress::End), None)
- }
- };
-
- if let Some(state) = state {
- self.report_progress("Loading", state, msg, None);
- }
- }
- }
-
- // Coalesce multiple task events into one loop turn
- task = match self.task_pool.receiver.try_recv() {
- Ok(task) => task,
- Err(_) => break,
- };
+ self.handle_task(&mut prime_caches_progress, task);
+ // Coalesce multiple task events into one loop turn
+ while let Ok(task) = self.task_pool.receiver.try_recv() {
+ self.handle_task(&mut prime_caches_progress, task);
}
for progress in prime_caches_progress {
@@ -324,118 +260,20 @@ impl GlobalState {
self.report_progress("Indexing", state, message, Some(fraction));
}
}
- Event::Vfs(mut task) => {
+ Event::Vfs(message) => {
let _p = profile::span("GlobalState::handle_event/vfs");
- loop {
- match task {
- vfs::loader::Message::Loaded { files } => {
- let vfs = &mut self.vfs.write().0;
- for (path, contents) in files {
- let path = VfsPath::from(path);
- if !self.mem_docs.contains(&path) {
- vfs.set_file_contents(path, contents);
- }
- }
- }
- vfs::loader::Message::Progress { n_total, n_done, config_version } => {
- always!(config_version <= self.vfs_config_version);
-
- self.vfs_progress_config_version = config_version;
- self.vfs_progress_n_total = n_total;
- self.vfs_progress_n_done = n_done;
-
- let state = if n_done == 0 {
- Progress::Begin
- } else if n_done < n_total {
- Progress::Report
- } else {
- assert_eq!(n_done, n_total);
- Progress::End
- };
- self.report_progress(
- "Roots Scanned",
- state,
- Some(format!("{}/{}", n_done, n_total)),
- Some(Progress::fraction(n_done, n_total)),
- )
- }
- }
- // Coalesce many VFS event into a single loop turn
- task = match self.loader.receiver.try_recv() {
- Ok(task) => task,
- Err(_) => break,
- }
+ self.handle_vfs_msg(message);
+ // Coalesce many VFS event into a single loop turn
+ while let Ok(message) = self.loader.receiver.try_recv() {
+ self.handle_vfs_msg(message);
}
}
- Event::Flycheck(mut task) => {
+ Event::Flycheck(message) => {
let _p = profile::span("GlobalState::handle_event/flycheck");
- loop {
- match task {
- flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => {
- let snap = self.snapshot();
- let diagnostics =
- crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
- &self.config.diagnostics_map(),
- &diagnostic,
- &workspace_root,
- &snap,
- );
- for diag in diagnostics {
- match url_to_file_id(&self.vfs.read().0, &diag.url) {
- Ok(file_id) => self.diagnostics.add_check_diagnostic(
- file_id,
- diag.diagnostic,
- diag.fix,
- ),
- Err(err) => {
- tracing::error!(
- "File with cargo diagnostic not found in VFS: {}",
- err
- );
- }
- };
- }
- }
-
- flycheck::Message::Progress { id, progress } => {
- let (state, message) = match progress {
- flycheck::Progress::DidStart => {
- self.diagnostics.clear_check();
- (Progress::Begin, None)
- }
- flycheck::Progress::DidCheckCrate(target) => {
- (Progress::Report, Some(target))
- }
- flycheck::Progress::DidCancel => (Progress::End, None),
- flycheck::Progress::DidFinish(result) => {
- if let Err(err) = result {
- self.show_and_log_error(
- "cargo check failed".to_string(),
- Some(err.to_string()),
- );
- }
- (Progress::End, None)
- }
- };
-
- // When we're running multiple flychecks, we have to include a disambiguator in
- // the title, or the editor complains. Note that this is a user-facing string.
- let title = if self.flycheck.len() == 1 {
- match self.config.flycheck() {
- Some(config) => format!("{}", config),
- None => "cargo check".to_string(),
- }
- } else {
- format!("cargo check (#{})", id + 1)
- };
- self.report_progress(&title, state, message, None);
- }
- }
- // Coalesce many flycheck updates into a single loop turn
- task = match self.flycheck_receiver.try_recv() {
- Ok(task) => task,
- Err(_) => break,
- }
+ self.handle_flycheck_msg(message);
+ // Coalesce many flycheck updates into a single loop turn
+ while let Ok(message) = self.flycheck_receiver.try_recv() {
+ self.handle_flycheck_msg(message);
}
}
}
@@ -444,10 +282,13 @@ impl GlobalState {
let memdocs_added_or_removed = self.mem_docs.take_changes();
if self.is_quiescent() {
- if !was_quiescent {
- for flycheck in &self.flycheck {
- flycheck.update();
- }
+ let became_quiescent = !(was_quiescent
+ || self.fetch_workspaces_queue.op_requested()
+ || self.fetch_build_data_queue.op_requested());
+
+ if became_quiescent {
+ // Project has loaded properly, kick off initial flycheck
+ self.flycheck.iter().for_each(FlycheckHandle::restart);
if self.config.prefill_caches() {
self.prime_caches_queue.request_op("became quiescent".to_string());
}
@@ -486,28 +327,40 @@ impl GlobalState {
continue;
}
- let url = file_id_to_url(&self.vfs.read().0, file_id);
+ let uri = file_id_to_url(&self.vfs.read().0, file_id);
let mut diagnostics =
self.diagnostics.diagnostics_for(file_id).cloned().collect::<Vec<_>>();
- // https://github.com/rust-lang/rust-analyzer/issues/11404
- for d in &mut diagnostics {
- if d.message.is_empty() {
- d.message = " ".to_string();
+
+ // VSCode assumes diagnostic messages to be non-empty strings, so we need to patch
+ // empty diagnostics. Neither the docs of VSCode nor the LSP spec say whether
+ // diagnostic messages are actually allowed to be empty or not and patching this
+ // in the VSCode client does not work as the assertion happens in the protocol
+ // conversion. So this hack is here to stay, and will be considered a hack
+ // until the LSP decides to state that empty messages are allowed.
+
+ // See https://github.com/rust-lang/rust-analyzer/issues/11404
+ // See https://github.com/rust-lang/rust-analyzer/issues/13130
+ let patch_empty = |message: &mut String| {
+ if message.is_empty() {
+ *message = " ".to_string();
}
- if let Some(rds) = d.related_information.as_mut() {
- for rd in rds {
- if rd.message.is_empty() {
- rd.message = " ".to_string();
- }
+ };
+
+ for d in &mut diagnostics {
+ patch_empty(&mut d.message);
+ if let Some(dri) = &mut d.related_information {
+ for dri in dri {
+ patch_empty(&mut dri.message);
}
}
}
- let version = from_proto::vfs_path(&url)
+
+ let version = from_proto::vfs_path(&uri)
.map(|path| self.mem_docs.get(&path).map(|it| it.version))
.unwrap_or_default();
self.send_notification::<lsp_types::notification::PublishDiagnostics>(
- lsp_types::PublishDiagnosticsParams { uri: url, diagnostics, version },
+ lsp_types::PublishDiagnosticsParams { uri, diagnostics, version },
);
}
}
@@ -569,11 +422,178 @@ impl GlobalState {
Ok(())
}
+ fn handle_task(&mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task) {
+ match task {
+ Task::Response(response) => self.respond(response),
+ Task::Retry(req) => self.on_request(req),
+ Task::Diagnostics(diagnostics_per_file) => {
+ for (file_id, diagnostics) in diagnostics_per_file {
+ self.diagnostics.set_native_diagnostics(file_id, diagnostics)
+ }
+ }
+ Task::PrimeCaches(progress) => match progress {
+ PrimeCachesProgress::Begin => prime_caches_progress.push(progress),
+ PrimeCachesProgress::Report(_) => {
+ match prime_caches_progress.last_mut() {
+ Some(last @ PrimeCachesProgress::Report(_)) => {
+ // Coalesce subsequent update events.
+ *last = progress;
+ }
+ _ => prime_caches_progress.push(progress),
+ }
+ }
+ PrimeCachesProgress::End { .. } => prime_caches_progress.push(progress),
+ },
+ Task::FetchWorkspace(progress) => {
+ let (state, msg) = match progress {
+ ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
+ ProjectWorkspaceProgress::Report(msg) => (Progress::Report, Some(msg)),
+ ProjectWorkspaceProgress::End(workspaces) => {
+ self.fetch_workspaces_queue.op_completed(workspaces);
+
+ let old = Arc::clone(&self.workspaces);
+ self.switch_workspaces("fetched workspace".to_string());
+ let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
+
+ if self.config.run_build_scripts() && workspaces_updated {
+ self.fetch_build_data_queue.request_op(format!("workspace updated"));
+ }
+
+ (Progress::End, None)
+ }
+ };
+
+ self.report_progress("Fetching", state, msg, None);
+ }
+ Task::FetchBuildData(progress) => {
+ let (state, msg) = match progress {
+ BuildDataProgress::Begin => (Some(Progress::Begin), None),
+ BuildDataProgress::Report(msg) => (Some(Progress::Report), Some(msg)),
+ BuildDataProgress::End(build_data_result) => {
+ self.fetch_build_data_queue.op_completed(build_data_result);
+
+ self.switch_workspaces("fetched build data".to_string());
+
+ (Some(Progress::End), None)
+ }
+ };
+
+ if let Some(state) = state {
+ self.report_progress("Loading", state, msg, None);
+ }
+ }
+ }
+ }
+
+ fn handle_vfs_msg(&mut self, message: vfs::loader::Message) {
+ match message {
+ vfs::loader::Message::Loaded { files } => {
+ let vfs = &mut self.vfs.write().0;
+ for (path, contents) in files {
+ let path = VfsPath::from(path);
+ if !self.mem_docs.contains(&path) {
+ vfs.set_file_contents(path, contents);
+ }
+ }
+ }
+ vfs::loader::Message::Progress { n_total, n_done, config_version } => {
+ always!(config_version <= self.vfs_config_version);
+
+ self.vfs_progress_config_version = config_version;
+ self.vfs_progress_n_total = n_total;
+ self.vfs_progress_n_done = n_done;
+
+ let state = if n_done == 0 {
+ Progress::Begin
+ } else if n_done < n_total {
+ Progress::Report
+ } else {
+ assert_eq!(n_done, n_total);
+ Progress::End
+ };
+ self.report_progress(
+ "Roots Scanned",
+ state,
+ Some(format!("{}/{}", n_done, n_total)),
+ Some(Progress::fraction(n_done, n_total)),
+ )
+ }
+ }
+ }
+
+ fn handle_flycheck_msg(&mut self, message: flycheck::Message) {
+ match message {
+ flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
+ let snap = self.snapshot();
+ let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
+ &self.config.diagnostics_map(),
+ &diagnostic,
+ &workspace_root,
+ &snap,
+ );
+ for diag in diagnostics {
+ match url_to_file_id(&self.vfs.read().0, &diag.url) {
+ Ok(file_id) => self.diagnostics.add_check_diagnostic(
+ id,
+ file_id,
+ diag.diagnostic,
+ diag.fix,
+ ),
+ Err(err) => {
+ tracing::error!("File with cargo diagnostic not found in VFS: {}", err);
+ }
+ };
+ }
+ }
+
+ flycheck::Message::Progress { id, progress } => {
+ let (state, message) = match progress {
+ flycheck::Progress::DidStart => {
+ self.diagnostics.clear_check(id);
+ (Progress::Begin, None)
+ }
+ flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
+ flycheck::Progress::DidCancel => (Progress::End, None),
+ flycheck::Progress::DidFailToRestart(err) => {
+ self.show_and_log_error(
+ "cargo check failed".to_string(),
+ Some(err.to_string()),
+ );
+ return;
+ }
+ flycheck::Progress::DidFinish(result) => {
+ if let Err(err) = result {
+ self.show_and_log_error(
+ "cargo check failed".to_string(),
+ Some(err.to_string()),
+ );
+ }
+ (Progress::End, None)
+ }
+ };
+
+ // When we're running multiple flychecks, we have to include a disambiguator in
+ // the title, or the editor complains. Note that this is a user-facing string.
+ let title = if self.flycheck.len() == 1 {
+ match self.config.flycheck() {
+ Some(config) => format!("{}", config),
+ None => "cargo check".to_string(),
+ }
+ } else {
+ format!("cargo check (#{})", id + 1)
+ };
+ self.report_progress(&title, state, message, None);
+ }
+ }
+ }
+
+ /// Registers and handles a request. This should only be called once per incoming request.
fn on_new_request(&mut self, request_received: Instant, req: Request) {
self.register_request(&req, request_received);
self.on_request(req);
}
+ /// Handles a request.
fn on_request(&mut self, req: Request) {
if self.shutdown_requested {
self.respond(lsp_server::Response::new_err(
@@ -602,6 +622,7 @@ impl GlobalState {
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
+ .on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
.on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
.on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
@@ -664,6 +685,7 @@ impl GlobalState {
.finish();
}
+ /// Handles an incoming notification.
fn on_notification(&mut self, not: Notification) -> Result<()> {
NotificationDispatcher { not: Some(not), global_state: self }
.on::<lsp_types::notification::Cancel>(|this, params| {
@@ -734,13 +756,82 @@ impl GlobalState {
Ok(())
})?
.on::<lsp_types::notification::DidSaveTextDocument>(|this, params| {
- for flycheck in &this.flycheck {
- flycheck.update();
+ let mut updated = false;
+ if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
+ let (vfs, _) = &*this.vfs.read();
+
+ // Trigger flychecks for all workspaces that depend on the saved file
+ if let Some(file_id) = vfs.file_id(&vfs_path) {
+ let analysis = this.analysis_host.analysis();
+ // Crates containing or depending on the saved file
+ let crate_ids: Vec<_> = analysis
+ .crate_for(file_id)?
+ .into_iter()
+ .flat_map(|id| {
+ this.analysis_host
+ .raw_database()
+ .crate_graph()
+ .transitive_rev_deps(id)
+ })
+ .sorted()
+ .unique()
+ .collect();
+
+ let crate_root_paths: Vec<_> = crate_ids
+ .iter()
+ .filter_map(|&crate_id| {
+ analysis
+ .crate_root(crate_id)
+ .map(|file_id| {
+ vfs.file_path(file_id).as_path().map(ToOwned::to_owned)
+ })
+ .transpose()
+ })
+ .collect::<ide::Cancellable<_>>()?;
+ let crate_root_paths: Vec<_> =
+ crate_root_paths.iter().map(Deref::deref).collect();
+
+ // Find all workspaces that have at least one target containing the saved file
+ let workspace_ids =
+ this.workspaces.iter().enumerate().filter(|(_, ws)| match ws {
+ project_model::ProjectWorkspace::Cargo { cargo, .. } => {
+ cargo.packages().any(|pkg| {
+ cargo[pkg].targets.iter().any(|&it| {
+ crate_root_paths.contains(&cargo[it].root.as_path())
+ })
+ })
+ }
+ project_model::ProjectWorkspace::Json { project, .. } => project
+ .crates()
+ .any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c)),
+ project_model::ProjectWorkspace::DetachedFiles { .. } => false,
+ });
+
+ // Find and trigger corresponding flychecks
+ for flycheck in &this.flycheck {
+ for (id, _) in workspace_ids.clone() {
+ if id == flycheck.id() {
+ updated = true;
+ flycheck.restart();
+ continue;
+ }
+ }
+ }
+ }
+
+ // Re-fetch workspaces if a workspace related file has changed
+ if let Some(abs_path) = vfs_path.as_path() {
+ if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) {
+ this.fetch_workspaces_queue
+ .request_op(format!("DidSaveTextDocument {}", abs_path.display()));
+ }
+ }
}
- if let Ok(abs_path) = from_proto::abs_path(&params.text_document.uri) {
- if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) {
- this.fetch_workspaces_queue
- .request_op(format!("DidSaveTextDocument {}", abs_path.display()));
+
+ // No specific flycheck was triggered, so let's trigger all of them.
+ if !updated {
+ for flycheck in &this.flycheck {
+ flycheck.restart();
}
}
Ok(())
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index eaab275bc..e47f70fff 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -196,10 +196,7 @@ impl GlobalState {
}
if let Err(error) = self.fetch_build_data_error() {
- self.show_and_log_error(
- "rust-analyzer failed to run build scripts".to_string(),
- Some(error),
- );
+ self.show_and_log_error("failed to run build scripts".to_string(), Some(error));
}
let workspaces = self
@@ -222,6 +219,7 @@ impl GlobalState {
cfg_overrides,
build_scripts: _,
+ toolchain: _,
} => Some((cargo, sysroot, rustc, rustc_cfg, cfg_overrides)),
_ => None,
};
@@ -308,6 +306,7 @@ impl GlobalState {
if self.proc_macro_clients.is_empty() {
if let Some((path, args)) = self.config.proc_macro_srv() {
+ tracing::info!("Spawning proc-macro servers");
self.proc_macro_clients = self
.workspaces
.iter()
@@ -315,21 +314,23 @@ impl GlobalState {
let mut args = args.clone();
let mut path = path.clone();
- if let ProjectWorkspace::Cargo { sysroot, .. } = ws {
- tracing::info!("Found a cargo workspace...");
+ if let ProjectWorkspace::Cargo { sysroot, .. }
+ | ProjectWorkspace::Json { sysroot, .. } = ws
+ {
+ tracing::debug!("Found a cargo workspace...");
if let Some(sysroot) = sysroot.as_ref() {
- tracing::info!("Found a cargo workspace with a sysroot...");
+ tracing::debug!("Found a cargo workspace with a sysroot...");
let server_path =
sysroot.root().join("libexec").join(&standalone_server_name);
if std::fs::metadata(&server_path).is_ok() {
- tracing::info!(
+ tracing::debug!(
"And the server exists at {}",
server_path.display()
);
path = server_path;
args = vec![];
} else {
- tracing::info!(
+ tracing::debug!(
"And the server does not exist at {}",
server_path.display()
);
@@ -337,14 +338,10 @@ impl GlobalState {
}
}
- tracing::info!(
- "Using proc-macro server at {} with args {:?}",
- path.display(),
- args
- );
+ tracing::info!(?args, "Using proc-macro server at {}", path.display(),);
ProcMacroServer::spawn(path.clone(), args.clone()).map_err(|err| {
let error = format!(
- "Failed to run proc_macro_srv from path {}, error: {:?}",
+ "Failed to run proc-macro server from path {}, error: {:?}",
path.display(),
err
);
@@ -352,8 +349,8 @@ impl GlobalState {
error
})
})
- .collect();
- }
+ .collect()
+ };
}
let watch = match files_config.watcher {
@@ -458,7 +455,7 @@ impl GlobalState {
Some(it) => it,
None => {
self.flycheck = Vec::new();
- self.diagnostics.clear_check();
+ self.diagnostics.clear_check_all();
return;
}
};
@@ -621,7 +618,10 @@ pub(crate) fn load_proc_macro(
};
let expander: Arc<dyn ProcMacroExpander> =
if dummy_replace.iter().any(|replace| &**replace == name) {
- Arc::new(DummyExpander)
+ match kind {
+ ProcMacroKind::Attr => Arc::new(IdentityExpander),
+ _ => Arc::new(EmptyExpander),
+ }
} else {
Arc::new(Expander(expander))
};
@@ -647,11 +647,11 @@ pub(crate) fn load_proc_macro(
}
}
- /// Dummy identity expander, used for proc-macros that are deliberately ignored by the user.
+ /// Dummy identity expander, used for attribute proc-macros that are deliberately ignored by the user.
#[derive(Debug)]
- struct DummyExpander;
+ struct IdentityExpander;
- impl ProcMacroExpander for DummyExpander {
+ impl ProcMacroExpander for IdentityExpander {
fn expand(
&self,
subtree: &tt::Subtree,
@@ -661,27 +661,46 @@ pub(crate) fn load_proc_macro(
Ok(subtree.clone())
}
}
+
+ /// Empty expander, used for proc-macros that are deliberately ignored by the user.
+ #[derive(Debug)]
+ struct EmptyExpander;
+
+ impl ProcMacroExpander for EmptyExpander {
+ fn expand(
+ &self,
+ _: &tt::Subtree,
+ _: Option<&tt::Subtree>,
+ _: &Env,
+ ) -> Result<tt::Subtree, ProcMacroExpansionError> {
+ Ok(tt::Subtree::default())
+ }
+ }
}
pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind) -> bool {
const IMPLICIT_TARGET_FILES: &[&str] = &["build.rs", "src/main.rs", "src/lib.rs"];
const IMPLICIT_TARGET_DIRS: &[&str] = &["src/bin", "examples", "tests", "benches"];
- let file_name = path.file_name().unwrap_or_default();
- if file_name == "Cargo.toml" || file_name == "Cargo.lock" {
+ let file_name = match path.file_name().unwrap_or_default().to_str() {
+ Some(it) => it,
+ None => return false,
+ };
+
+ if let "Cargo.toml" | "Cargo.lock" = file_name {
return true;
}
if change_kind == ChangeKind::Modify {
return false;
}
+
+ // .cargo/config{.toml}
if path.extension().unwrap_or_default() != "rs" {
- if (file_name == "config.toml" || file_name == "config")
- && path.parent().map(|parent| parent.as_ref().ends_with(".cargo")) == Some(true)
- {
- return true;
- }
- return false;
+ let is_cargo_config = matches!(file_name, "config.toml" | "config")
+ && path.parent().map(|parent| parent.as_ref().ends_with(".cargo")).unwrap_or(false);
+ return is_cargo_config;
}
+
if IMPLICIT_TARGET_FILES.iter().any(|it| path.as_ref().ends_with(it)) {
return true;
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs
index 6c78b5df1..c48410ed5 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs
@@ -8,107 +8,130 @@ use lsp_types::{
};
macro_rules! define_semantic_token_types {
- ($(($ident:ident, $string:literal)),*$(,)?) => {
- $(pub(crate) const $ident: SemanticTokenType = SemanticTokenType::new($string);)*
+ (
+ standard {
+ $($standard:ident),*$(,)?
+ }
+ custom {
+ $(($custom:ident, $string:literal)),*$(,)?
+ }
+
+ ) => {
+ $(pub(crate) const $standard: SemanticTokenType = SemanticTokenType::$standard;)*
+ $(pub(crate) const $custom: SemanticTokenType = SemanticTokenType::new($string);)*
pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
- SemanticTokenType::COMMENT,
- SemanticTokenType::KEYWORD,
- SemanticTokenType::STRING,
- SemanticTokenType::NUMBER,
- SemanticTokenType::REGEXP,
- SemanticTokenType::OPERATOR,
- SemanticTokenType::NAMESPACE,
- SemanticTokenType::TYPE,
- SemanticTokenType::STRUCT,
- SemanticTokenType::CLASS,
- SemanticTokenType::INTERFACE,
- SemanticTokenType::ENUM,
- SemanticTokenType::ENUM_MEMBER,
- SemanticTokenType::TYPE_PARAMETER,
- SemanticTokenType::FUNCTION,
- SemanticTokenType::METHOD,
- SemanticTokenType::PROPERTY,
- SemanticTokenType::MACRO,
- SemanticTokenType::VARIABLE,
- SemanticTokenType::PARAMETER,
- $($ident),*
+ $(SemanticTokenType::$standard,)*
+ $($custom),*
];
};
}
define_semantic_token_types![
- (ANGLE, "angle"),
- (ARITHMETIC, "arithmetic"),
- (ATTRIBUTE, "attribute"),
- (ATTRIBUTE_BRACKET, "attributeBracket"),
- (BITWISE, "bitwise"),
- (BOOLEAN, "boolean"),
- (BRACE, "brace"),
- (BRACKET, "bracket"),
- (BUILTIN_ATTRIBUTE, "builtinAttribute"),
- (BUILTIN_TYPE, "builtinType"),
- (CHAR, "character"),
- (COLON, "colon"),
- (COMMA, "comma"),
- (COMPARISON, "comparison"),
- (CONST_PARAMETER, "constParameter"),
- (DERIVE, "derive"),
- (DERIVE_HELPER, "deriveHelper"),
- (DOT, "dot"),
- (ESCAPE_SEQUENCE, "escapeSequence"),
- (FORMAT_SPECIFIER, "formatSpecifier"),
- (GENERIC, "generic"),
- (LABEL, "label"),
- (LIFETIME, "lifetime"),
- (LOGICAL, "logical"),
- (MACRO_BANG, "macroBang"),
- (OPERATOR, "operator"),
- (PARENTHESIS, "parenthesis"),
- (PUNCTUATION, "punctuation"),
- (SELF_KEYWORD, "selfKeyword"),
- (SELF_TYPE_KEYWORD, "selfTypeKeyword"),
- (SEMICOLON, "semicolon"),
- (TYPE_ALIAS, "typeAlias"),
- (TOOL_MODULE, "toolModule"),
- (UNION, "union"),
- (UNRESOLVED_REFERENCE, "unresolvedReference"),
+ standard {
+ COMMENT,
+ DECORATOR,
+ ENUM_MEMBER,
+ ENUM,
+ FUNCTION,
+ INTERFACE,
+ KEYWORD,
+ MACRO,
+ METHOD,
+ NAMESPACE,
+ NUMBER,
+ OPERATOR,
+ PARAMETER,
+ PROPERTY,
+ STRING,
+ STRUCT,
+ TYPE_PARAMETER,
+ VARIABLE,
+ }
+
+ custom {
+ (ANGLE, "angle"),
+ (ARITHMETIC, "arithmetic"),
+ (ATTRIBUTE, "attribute"),
+ (ATTRIBUTE_BRACKET, "attributeBracket"),
+ (BITWISE, "bitwise"),
+ (BOOLEAN, "boolean"),
+ (BRACE, "brace"),
+ (BRACKET, "bracket"),
+ (BUILTIN_ATTRIBUTE, "builtinAttribute"),
+ (BUILTIN_TYPE, "builtinType"),
+ (CHAR, "character"),
+ (COLON, "colon"),
+ (COMMA, "comma"),
+ (COMPARISON, "comparison"),
+ (CONST_PARAMETER, "constParameter"),
+ (DERIVE, "derive"),
+ (DERIVE_HELPER, "deriveHelper"),
+ (DOT, "dot"),
+ (ESCAPE_SEQUENCE, "escapeSequence"),
+ (FORMAT_SPECIFIER, "formatSpecifier"),
+ (GENERIC, "generic"),
+ (LABEL, "label"),
+ (LIFETIME, "lifetime"),
+ (LOGICAL, "logical"),
+ (MACRO_BANG, "macroBang"),
+ (PARENTHESIS, "parenthesis"),
+ (PUNCTUATION, "punctuation"),
+ (SELF_KEYWORD, "selfKeyword"),
+ (SELF_TYPE_KEYWORD, "selfTypeKeyword"),
+ (SEMICOLON, "semicolon"),
+ (TYPE_ALIAS, "typeAlias"),
+ (TOOL_MODULE, "toolModule"),
+ (UNION, "union"),
+ (UNRESOLVED_REFERENCE, "unresolvedReference"),
+ }
];
macro_rules! define_semantic_token_modifiers {
- ($(($ident:ident, $string:literal)),*$(,)?) => {
- $(pub(crate) const $ident: SemanticTokenModifier = SemanticTokenModifier::new($string);)*
+ (
+ standard {
+ $($standard:ident),*$(,)?
+ }
+ custom {
+ $(($custom:ident, $string:literal)),*$(,)?
+ }
+
+ ) => {
+
+ $(pub(crate) const $standard: SemanticTokenModifier = SemanticTokenModifier::$standard;)*
+ $(pub(crate) const $custom: SemanticTokenModifier = SemanticTokenModifier::new($string);)*
pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
- SemanticTokenModifier::DOCUMENTATION,
- SemanticTokenModifier::DECLARATION,
- SemanticTokenModifier::DEFINITION,
- SemanticTokenModifier::STATIC,
- SemanticTokenModifier::ABSTRACT,
- SemanticTokenModifier::DEPRECATED,
- SemanticTokenModifier::READONLY,
- SemanticTokenModifier::DEFAULT_LIBRARY,
- $($ident),*
+ $(SemanticTokenModifier::$standard,)*
+ $($custom),*
];
};
}
define_semantic_token_modifiers![
- (ASYNC, "async"),
- (ATTRIBUTE_MODIFIER, "attribute"),
- (CALLABLE, "callable"),
- (CONSTANT, "constant"),
- (CONSUMING, "consuming"),
- (CONTROL_FLOW, "controlFlow"),
- (CRATE_ROOT, "crateRoot"),
- (INJECTED, "injected"),
- (INTRA_DOC_LINK, "intraDocLink"),
- (LIBRARY, "library"),
- (MUTABLE, "mutable"),
- (PUBLIC, "public"),
- (REFERENCE, "reference"),
- (TRAIT_MODIFIER, "trait"),
- (UNSAFE, "unsafe"),
+ standard {
+ DOCUMENTATION,
+ DECLARATION,
+ STATIC,
+ DEFAULT_LIBRARY,
+ }
+ custom {
+ (ASYNC, "async"),
+ (ATTRIBUTE_MODIFIER, "attribute"),
+ (CALLABLE, "callable"),
+ (CONSTANT, "constant"),
+ (CONSUMING, "consuming"),
+ (CONTROL_FLOW, "controlFlow"),
+ (CRATE_ROOT, "crateRoot"),
+ (INJECTED, "injected"),
+ (INTRA_DOC_LINK, "intraDocLink"),
+ (LIBRARY, "library"),
+ (MUTABLE, "mutable"),
+ (PUBLIC, "public"),
+ (REFERENCE, "reference"),
+ (TRAIT_MODIFIER, "trait"),
+ (UNSAFE, "unsafe"),
+ }
];
#[derive(Default)]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
index 7f4fa57fa..e083b9d0e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
@@ -9,8 +9,9 @@ use ide::{
Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionItem,
CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit,
Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint,
- InlayKind, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity,
- SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
+ InlayHintLabel, InlayKind, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable,
+ Severity, SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange,
+ TextSize,
};
use itertools::Itertools;
use serde_json::to_value;
@@ -426,9 +427,16 @@ pub(crate) fn inlay_hint(
snap: &GlobalStateSnapshot,
line_index: &LineIndex,
render_colons: bool,
- inlay_hint: InlayHint,
-) -> lsp_types::InlayHint {
- lsp_types::InlayHint {
+ mut inlay_hint: InlayHint,
+) -> Result<lsp_types::InlayHint> {
+ match inlay_hint.kind {
+ InlayKind::ParameterHint if render_colons => inlay_hint.label.append_str(":"),
+ InlayKind::TypeHint if render_colons => inlay_hint.label.prepend_str(": "),
+ InlayKind::ClosureReturnTypeHint => inlay_hint.label.prepend_str(" -> "),
+ _ => {}
+ }
+
+ Ok(lsp_types::InlayHint {
position: match inlay_hint.kind {
// before annotated thing
InlayKind::ParameterHint
@@ -459,15 +467,9 @@ pub(crate) fn inlay_hint(
| InlayKind::ImplicitReborrowHint
| InlayKind::TypeHint
| InlayKind::ClosingBraceHint => false,
- InlayKind::BindingModeHint => inlay_hint.label != "&",
+ InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"),
InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
}),
- label: lsp_types::InlayHintLabel::String(match inlay_hint.kind {
- InlayKind::ParameterHint if render_colons => format!("{}:", inlay_hint.label),
- InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label),
- InlayKind::ClosureReturnTypeHint => format!(" -> {}", inlay_hint.label),
- _ => inlay_hint.label.clone(),
- }),
kind: match inlay_hint.kind {
InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER),
InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => {
@@ -506,9 +508,36 @@ pub(crate) fn inlay_hint(
})(),
tooltip: Some(match inlay_hint.tooltip {
Some(ide::InlayTooltip::String(s)) => lsp_types::InlayHintTooltip::String(s),
- _ => lsp_types::InlayHintTooltip::String(inlay_hint.label),
+ _ => lsp_types::InlayHintTooltip::String(inlay_hint.label.to_string()),
}),
- }
+ label: inlay_hint_label(snap, inlay_hint.label)?,
+ })
+}
+
+fn inlay_hint_label(
+ snap: &GlobalStateSnapshot,
+ label: InlayHintLabel,
+) -> Result<lsp_types::InlayHintLabel> {
+ Ok(match label.as_simple_str() {
+ Some(s) => lsp_types::InlayHintLabel::String(s.into()),
+ None => lsp_types::InlayHintLabel::LabelParts(
+ label
+ .parts
+ .into_iter()
+ .map(|part| {
+ Ok(lsp_types::InlayHintLabelPart {
+ value: part.text,
+ tooltip: None,
+ location: part
+ .linked_location
+ .map(|range| location(snap, range))
+ .transpose()?,
+ command: None,
+ })
+ })
+ .collect::<Result<Vec<_>>>()?,
+ ),
+ })
}
static TOKEN_RESULT_COUNTER: AtomicU32 = AtomicU32::new(1);
@@ -517,7 +546,6 @@ pub(crate) fn semantic_tokens(
text: &str,
line_index: &LineIndex,
highlights: Vec<HlRange>,
- highlight_strings: bool,
) -> lsp_types::SemanticTokens {
let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string();
let mut builder = semantic_tokens::SemanticTokensBuilder::new(id);
@@ -526,10 +554,8 @@ pub(crate) fn semantic_tokens(
if highlight_range.highlight.is_empty() {
continue;
}
+
let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
- if !highlight_strings && ty == lsp_types::SemanticTokenType::STRING {
- continue;
- }
let token_index = semantic_tokens::type_index(ty);
let modifier_bitset = mods.0;
@@ -561,55 +587,55 @@ fn semantic_token_type_and_modifiers(
let mut mods = semantic_tokens::ModifierSet::default();
let type_ = match highlight.tag {
HlTag::Symbol(symbol) => match symbol {
- SymbolKind::Attribute => semantic_tokens::ATTRIBUTE,
+ SymbolKind::Attribute => semantic_tokens::DECORATOR,
SymbolKind::Derive => semantic_tokens::DERIVE,
SymbolKind::DeriveHelper => semantic_tokens::DERIVE_HELPER,
- SymbolKind::Module => lsp_types::SemanticTokenType::NAMESPACE,
+ SymbolKind::Module => semantic_tokens::NAMESPACE,
SymbolKind::Impl => semantic_tokens::TYPE_ALIAS,
- SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY,
- SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER,
+ SymbolKind::Field => semantic_tokens::PROPERTY,
+ SymbolKind::TypeParam => semantic_tokens::TYPE_PARAMETER,
SymbolKind::ConstParam => semantic_tokens::CONST_PARAMETER,
SymbolKind::LifetimeParam => semantic_tokens::LIFETIME,
SymbolKind::Label => semantic_tokens::LABEL,
- SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER,
+ SymbolKind::ValueParam => semantic_tokens::PARAMETER,
SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD,
SymbolKind::SelfType => semantic_tokens::SELF_TYPE_KEYWORD,
- SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE,
+ SymbolKind::Local => semantic_tokens::VARIABLE,
SymbolKind::Function => {
if highlight.mods.contains(HlMod::Associated) {
- lsp_types::SemanticTokenType::METHOD
+ semantic_tokens::METHOD
} else {
- lsp_types::SemanticTokenType::FUNCTION
+ semantic_tokens::FUNCTION
}
}
SymbolKind::Const => {
mods |= semantic_tokens::CONSTANT;
- mods |= lsp_types::SemanticTokenModifier::STATIC;
- lsp_types::SemanticTokenType::VARIABLE
+ mods |= semantic_tokens::STATIC;
+ semantic_tokens::VARIABLE
}
SymbolKind::Static => {
- mods |= lsp_types::SemanticTokenModifier::STATIC;
- lsp_types::SemanticTokenType::VARIABLE
+ mods |= semantic_tokens::STATIC;
+ semantic_tokens::VARIABLE
}
- SymbolKind::Struct => lsp_types::SemanticTokenType::STRUCT,
- SymbolKind::Enum => lsp_types::SemanticTokenType::ENUM,
- SymbolKind::Variant => lsp_types::SemanticTokenType::ENUM_MEMBER,
+ SymbolKind::Struct => semantic_tokens::STRUCT,
+ SymbolKind::Enum => semantic_tokens::ENUM,
+ SymbolKind::Variant => semantic_tokens::ENUM_MEMBER,
SymbolKind::Union => semantic_tokens::UNION,
SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
- SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
- SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
+ SymbolKind::Trait => semantic_tokens::INTERFACE,
+ SymbolKind::Macro => semantic_tokens::MACRO,
SymbolKind::BuiltinAttr => semantic_tokens::BUILTIN_ATTRIBUTE,
SymbolKind::ToolModule => semantic_tokens::TOOL_MODULE,
},
HlTag::AttributeBracket => semantic_tokens::ATTRIBUTE_BRACKET,
HlTag::BoolLiteral => semantic_tokens::BOOLEAN,
HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
- HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER,
+ HlTag::ByteLiteral | HlTag::NumericLiteral => semantic_tokens::NUMBER,
HlTag::CharLiteral => semantic_tokens::CHAR,
- HlTag::Comment => lsp_types::SemanticTokenType::COMMENT,
+ HlTag::Comment => semantic_tokens::COMMENT,
HlTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE,
HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
- HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
+ HlTag::Keyword => semantic_tokens::KEYWORD,
HlTag::None => semantic_tokens::GENERIC,
HlTag::Operator(op) => match op {
HlOperator::Bitwise => semantic_tokens::BITWISE,
@@ -618,7 +644,7 @@ fn semantic_token_type_and_modifiers(
HlOperator::Comparison => semantic_tokens::COMPARISON,
HlOperator::Other => semantic_tokens::OPERATOR,
},
- HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING,
+ HlTag::StringLiteral => semantic_tokens::STRING,
HlTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
HlTag::Punctuation(punct) => match punct {
HlPunct::Bracket => semantic_tokens::BRACKET,
@@ -643,16 +669,16 @@ fn semantic_token_type_and_modifiers(
HlMod::Consuming => semantic_tokens::CONSUMING,
HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
HlMod::CrateRoot => semantic_tokens::CRATE_ROOT,
- HlMod::DefaultLibrary => lsp_types::SemanticTokenModifier::DEFAULT_LIBRARY,
- HlMod::Definition => lsp_types::SemanticTokenModifier::DECLARATION,
- HlMod::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,
+ HlMod::DefaultLibrary => semantic_tokens::DEFAULT_LIBRARY,
+ HlMod::Definition => semantic_tokens::DECLARATION,
+ HlMod::Documentation => semantic_tokens::DOCUMENTATION,
HlMod::Injected => semantic_tokens::INJECTED,
HlMod::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
HlMod::Library => semantic_tokens::LIBRARY,
HlMod::Mutable => semantic_tokens::MUTABLE,
HlMod::Public => semantic_tokens::PUBLIC,
HlMod::Reference => semantic_tokens::REFERENCE,
- HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,
+ HlMod::Static => semantic_tokens::STATIC,
HlMod::Trait => semantic_tokens::TRAIT_MODIFIER,
HlMod::Unsafe => semantic_tokens::UNSAFE,
};
@@ -1386,7 +1412,7 @@ fn main() {
#[test]
#[cfg(target_os = "windows")]
fn test_lowercase_drive_letter() {
- use std::{convert::TryInto, path::Path};
+ use std::path::Path;
let url = url_from_abs_path(Path::new("C:\\Test").try_into().unwrap());
assert_eq!(url.to_string(), "file:///c:/Test");
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs
index 18f95925d..58099a58d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs
@@ -13,9 +13,8 @@ use xshell::cmd;
fn check_code_formatting() {
let sh = &Shell::new().unwrap();
sh.change_dir(sourcegen::project_root());
- sh.set_var("RUSTUP_TOOLCHAIN", "stable");
- let out = cmd!(sh, "rustfmt --version").read().unwrap();
+ let out = cmd!(sh, "rustup run stable rustfmt --version").read().unwrap();
if !out.contains("stable") {
panic!(
"Failed to run rustfmt from toolchain 'stable'. \
@@ -23,9 +22,9 @@ fn check_code_formatting() {
)
}
- let res = cmd!(sh, "cargo fmt -- --check").run();
+ let res = cmd!(sh, "rustup run stable cargo fmt -- --check").run();
if res.is_err() {
- let _ = cmd!(sh, "cargo fmt").run();
+ let _ = cmd!(sh, "rustup run stable cargo fmt").run();
}
res.unwrap()
}
diff --git a/src/tools/rust-analyzer/crates/sourcegen/src/lib.rs b/src/tools/rust-analyzer/crates/sourcegen/src/lib.rs
index ce0224ec7..4e0ee63f3 100644
--- a/src/tools/rust-analyzer/crates/sourcegen/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/sourcegen/src/lib.rs
@@ -136,7 +136,7 @@ impl fmt::Display for Location {
}
fn ensure_rustfmt(sh: &Shell) {
- let version = cmd!(sh, "rustfmt --version").read().unwrap_or_default();
+ let version = cmd!(sh, "rustup run stable rustfmt --version").read().unwrap_or_default();
if !version.contains("stable") {
panic!(
"Failed to run rustfmt from toolchain 'stable'. \
@@ -147,13 +147,15 @@ fn ensure_rustfmt(sh: &Shell) {
pub fn reformat(text: String) -> String {
let sh = Shell::new().unwrap();
- sh.set_var("RUSTUP_TOOLCHAIN", "stable");
ensure_rustfmt(&sh);
let rustfmt_toml = project_root().join("rustfmt.toml");
- let mut stdout = cmd!(sh, "rustfmt --config-path {rustfmt_toml} --config fn_single_line=true")
- .stdin(text)
- .read()
- .unwrap();
+ let mut stdout = cmd!(
+ sh,
+ "rustup run stable rustfmt --config-path {rustfmt_toml} --config fn_single_line=true"
+ )
+ .stdin(text)
+ .read()
+ .unwrap();
if !stdout.ends_with('\n') {
stdout.push('\n');
}
diff --git a/src/tools/rust-analyzer/crates/stdx/src/hash.rs b/src/tools/rust-analyzer/crates/stdx/src/hash.rs
new file mode 100644
index 000000000..9909d71bd
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/stdx/src/hash.rs
@@ -0,0 +1,80 @@
+//! A none hashing [`Hasher`] implementation.
+use std::{
+ hash::{BuildHasher, Hasher},
+ marker::PhantomData,
+};
+
+pub type NoHashHashMap<K, V> = std::collections::HashMap<K, V, NoHashHasherBuilder<K>>;
+pub type NoHashHashSet<K> = std::collections::HashSet<K, NoHashHasherBuilder<K>>;
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct NoHashHasherBuilder<T>(PhantomData<T>);
+
+impl<T> Default for NoHashHasherBuilder<T> {
+ fn default() -> Self {
+ Self(Default::default())
+ }
+}
+
+pub trait NoHashHashable {}
+impl NoHashHashable for usize {}
+impl NoHashHashable for u32 {}
+
+pub struct NoHashHasher(u64);
+
+impl<T: NoHashHashable> BuildHasher for NoHashHasherBuilder<T> {
+ type Hasher = NoHashHasher;
+ fn build_hasher(&self) -> Self::Hasher {
+ NoHashHasher(0)
+ }
+}
+
+impl Hasher for NoHashHasher {
+ fn finish(&self) -> u64 {
+ self.0
+ }
+
+ fn write(&mut self, _: &[u8]) {
+ unimplemented!("NoHashHasher should only be used for hashing primitive integers")
+ }
+
+ fn write_u8(&mut self, i: u8) {
+ self.0 = i as u64;
+ }
+
+ fn write_u16(&mut self, i: u16) {
+ self.0 = i as u64;
+ }
+
+ fn write_u32(&mut self, i: u32) {
+ self.0 = i as u64;
+ }
+
+ fn write_u64(&mut self, i: u64) {
+ self.0 = i as u64;
+ }
+
+ fn write_usize(&mut self, i: usize) {
+ self.0 = i as u64;
+ }
+
+ fn write_i8(&mut self, i: i8) {
+ self.0 = i as u64;
+ }
+
+ fn write_i16(&mut self, i: i16) {
+ self.0 = i as u64;
+ }
+
+ fn write_i32(&mut self, i: i32) {
+ self.0 = i as u64;
+ }
+
+ fn write_i64(&mut self, i: i64) {
+ self.0 = i as u64;
+ }
+
+ fn write_isize(&mut self, i: isize) {
+ self.0 = i as u64;
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
index b4d45206c..51e109798 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
@@ -7,6 +7,7 @@ use std::{cmp::Ordering, ops, time::Instant};
use std::{io as sio, iter};
mod macros;
+pub mod hash;
pub mod process;
pub mod panic_context;
pub mod non_empty_vec;
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 62aa47839..894795435 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -343,7 +343,6 @@ Expr =
| Literal
| LoopExpr
| MacroExpr
-| MacroStmts
| MatchExpr
| MethodCallExpr
| ParenExpr
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
index e3e928aec..eadebbe8a 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
@@ -11,7 +11,7 @@ use crate::{
ted::{self, Position},
AstNode, AstToken, Direction,
SyntaxKind::{ATTR, COMMENT, WHITESPACE},
- SyntaxNode,
+ SyntaxNode, SyntaxToken,
};
use super::HasName;
@@ -248,8 +248,12 @@ impl ast::WhereClause {
}
}
-impl ast::TypeBoundList {
- pub fn remove(&self) {
+pub trait Removable: AstNode {
+ fn remove(&self);
+}
+
+impl Removable for ast::TypeBoundList {
+ fn remove(&self) {
match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
Some(colon) => ted::remove_all(colon..=self.syntax().clone().into()),
None => ted::remove(self.syntax()),
@@ -267,8 +271,8 @@ impl ast::PathSegment {
}
}
-impl ast::UseTree {
- pub fn remove(&self) {
+impl Removable for ast::UseTree {
+ fn remove(&self) {
for dir in [Direction::Next, Direction::Prev] {
if let Some(next_use_tree) = neighbor(self, dir) {
let separators = self
@@ -282,7 +286,9 @@ impl ast::UseTree {
}
ted::remove(self.syntax());
}
+}
+impl ast::UseTree {
pub fn get_or_create_use_tree_list(&self) -> ast::UseTreeList {
match self.use_tree_list() {
Some(it) => it,
@@ -373,8 +379,8 @@ impl ast::UseTreeList {
}
}
-impl ast::Use {
- pub fn remove(&self) {
+impl Removable for ast::Use {
+ fn remove(&self) {
let next_ws = self
.syntax()
.next_sibling_or_token()
@@ -444,8 +450,8 @@ impl ast::Fn {
}
}
-impl ast::MatchArm {
- pub fn remove(&self) {
+impl Removable for ast::MatchArm {
+ fn remove(&self) {
if let Some(sibling) = self.syntax().prev_sibling_or_token() {
if sibling.kind() == SyntaxKind::WHITESPACE {
ted::remove(sibling);
@@ -506,19 +512,7 @@ impl ast::RecordExprFieldList {
let position = match self.fields().last() {
Some(last_field) => {
- let comma = match last_field
- .syntax()
- .siblings_with_tokens(Direction::Next)
- .filter_map(|it| it.into_token())
- .find(|it| it.kind() == T![,])
- {
- Some(it) => it,
- None => {
- let comma = ast::make::token(T![,]);
- ted::insert(Position::after(last_field.syntax()), &comma);
- comma
- }
- };
+ let comma = get_or_insert_comma_after(last_field.syntax());
Position::after(comma)
}
None => match self.l_curly_token() {
@@ -579,19 +573,8 @@ impl ast::RecordPatFieldList {
let position = match self.fields().last() {
Some(last_field) => {
- let comma = match last_field
- .syntax()
- .siblings_with_tokens(Direction::Next)
- .filter_map(|it| it.into_token())
- .find(|it| it.kind() == T![,])
- {
- Some(it) => it,
- None => {
- let comma = ast::make::token(T![,]);
- ted::insert(Position::after(last_field.syntax()), &comma);
- comma
- }
- };
+ let syntax = last_field.syntax();
+ let comma = get_or_insert_comma_after(syntax);
Position::after(comma)
}
None => match self.l_curly_token() {
@@ -606,12 +589,53 @@ impl ast::RecordPatFieldList {
}
}
}
+
+fn get_or_insert_comma_after(syntax: &SyntaxNode) -> SyntaxToken {
+ let comma = match syntax
+ .siblings_with_tokens(Direction::Next)
+ .filter_map(|it| it.into_token())
+ .find(|it| it.kind() == T![,])
+ {
+ Some(it) => it,
+ None => {
+ let comma = ast::make::token(T![,]);
+ ted::insert(Position::after(syntax), &comma);
+ comma
+ }
+ };
+ comma
+}
+
impl ast::StmtList {
pub fn push_front(&self, statement: ast::Stmt) {
ted::insert(Position::after(self.l_curly_token().unwrap()), statement.syntax());
}
}
+impl ast::VariantList {
+ pub fn add_variant(&self, variant: ast::Variant) {
+ let (indent, position) = match self.variants().last() {
+ Some(last_item) => (
+ IndentLevel::from_node(last_item.syntax()),
+ Position::after(get_or_insert_comma_after(last_item.syntax())),
+ ),
+ None => match self.l_curly_token() {
+ Some(l_curly) => {
+ normalize_ws_between_braces(self.syntax());
+ (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly))
+ }
+ None => (IndentLevel::single(), Position::last_child_of(self.syntax())),
+ },
+ };
+ let elements: Vec<SyntaxElement<_>> = vec![
+ make::tokens::whitespace(&format!("{}{}", "\n", indent)).into(),
+ variant.syntax().clone().into(),
+ ast::make::token(T![,]).into(),
+ ];
+ ted::insert_all(position, elements);
+ }
+}
+
fn normalize_ws_between_braces(node: &SyntaxNode) -> Option<()> {
let l = node
.children_with_tokens()
@@ -661,6 +685,9 @@ impl<N: AstNode + Clone> Indent for N {}
mod tests {
use std::fmt;
+ use stdx::trim_indent;
+ use test_utils::assert_eq_text;
+
use crate::SourceFile;
use super::*;
@@ -714,4 +741,100 @@ mod tests {
}",
);
}
+
+ #[test]
+ fn add_variant_to_empty_enum() {
+ let variant = make::variant(make::name("Bar"), None).clone_for_update();
+
+ check_add_variant(
+ r#"
+enum Foo {}
+"#,
+ r#"
+enum Foo {
+ Bar,
+}
+"#,
+ variant,
+ );
+ }
+
+ #[test]
+ fn add_variant_to_non_empty_enum() {
+ let variant = make::variant(make::name("Baz"), None).clone_for_update();
+
+ check_add_variant(
+ r#"
+enum Foo {
+ Bar,
+}
+"#,
+ r#"
+enum Foo {
+ Bar,
+ Baz,
+}
+"#,
+ variant,
+ );
+ }
+
+ #[test]
+ fn add_variant_with_tuple_field_list() {
+ let variant = make::variant(
+ make::name("Baz"),
+ Some(ast::FieldList::TupleFieldList(make::tuple_field_list(std::iter::once(
+ make::tuple_field(None, make::ty("bool")),
+ )))),
+ )
+ .clone_for_update();
+
+ check_add_variant(
+ r#"
+enum Foo {
+ Bar,
+}
+"#,
+ r#"
+enum Foo {
+ Bar,
+ Baz(bool),
+}
+"#,
+ variant,
+ );
+ }
+
+ #[test]
+ fn add_variant_with_record_field_list() {
+ let variant = make::variant(
+ make::name("Baz"),
+ Some(ast::FieldList::RecordFieldList(make::record_field_list(std::iter::once(
+ make::record_field(None, make::name("x"), make::ty("bool")),
+ )))),
+ )
+ .clone_for_update();
+
+ check_add_variant(
+ r#"
+enum Foo {
+ Bar,
+}
+"#,
+ r#"
+enum Foo {
+ Bar,
+ Baz { x: bool },
+}
+"#,
+ variant,
+ );
+ }
+
+ fn check_add_variant(before: &str, expected: &str, variant: ast::Variant) {
+ let enum_ = ast_mut_from_text::<ast::Enum>(before);
+ enum_.variant_list().map(|it| it.add_variant(variant));
+ let after = enum_.to_string();
+ assert_eq_text!(&trim_indent(expected.trim()), &trim_indent(&after.trim()));
+ }
}
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index 63309a155..449402e5f 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -1526,7 +1526,6 @@ pub enum Expr {
Literal(Literal),
LoopExpr(LoopExpr),
MacroExpr(MacroExpr),
- MacroStmts(MacroStmts),
MatchExpr(MatchExpr),
MethodCallExpr(MethodCallExpr),
ParenExpr(ParenExpr),
@@ -3169,10 +3168,7 @@ impl From<ConstArg> for GenericArg {
}
impl AstNode for GenericArg {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG => true,
- _ => false,
- }
+ matches!(kind, TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -3237,12 +3233,23 @@ impl From<TupleType> for Type {
}
impl AstNode for Type {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE
- | MACRO_TYPE | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE
- | SLICE_TYPE | TUPLE_TYPE => true,
- _ => false,
- }
+ matches!(
+ kind,
+ ARRAY_TYPE
+ | DYN_TRAIT_TYPE
+ | FN_PTR_TYPE
+ | FOR_TYPE
+ | IMPL_TRAIT_TYPE
+ | INFER_TYPE
+ | MACRO_TYPE
+ | NEVER_TYPE
+ | PAREN_TYPE
+ | PATH_TYPE
+ | PTR_TYPE
+ | REF_TYPE
+ | SLICE_TYPE
+ | TUPLE_TYPE
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -3334,9 +3341,6 @@ impl From<LoopExpr> for Expr {
impl From<MacroExpr> for Expr {
fn from(node: MacroExpr) -> Expr { Expr::MacroExpr(node) }
}
-impl From<MacroStmts> for Expr {
- fn from(node: MacroStmts) -> Expr { Expr::MacroStmts(node) }
-}
impl From<MatchExpr> for Expr {
fn from(node: MatchExpr) -> Expr { Expr::MatchExpr(node) }
}
@@ -3384,15 +3388,41 @@ impl From<UnderscoreExpr> for Expr {
}
impl AstNode for Expr {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- ARRAY_EXPR | AWAIT_EXPR | BIN_EXPR | BLOCK_EXPR | BOX_EXPR | BREAK_EXPR | CALL_EXPR
- | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | FIELD_EXPR | FOR_EXPR | IF_EXPR
- | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_EXPR | MACRO_STMTS | MATCH_EXPR
- | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR
- | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR
- | YIELD_EXPR | LET_EXPR | UNDERSCORE_EXPR => true,
- _ => false,
- }
+ matches!(
+ kind,
+ ARRAY_EXPR
+ | AWAIT_EXPR
+ | BIN_EXPR
+ | BLOCK_EXPR
+ | BOX_EXPR
+ | BREAK_EXPR
+ | CALL_EXPR
+ | CAST_EXPR
+ | CLOSURE_EXPR
+ | CONTINUE_EXPR
+ | FIELD_EXPR
+ | FOR_EXPR
+ | IF_EXPR
+ | INDEX_EXPR
+ | LITERAL
+ | LOOP_EXPR
+ | MACRO_EXPR
+ | MATCH_EXPR
+ | METHOD_CALL_EXPR
+ | PAREN_EXPR
+ | PATH_EXPR
+ | PREFIX_EXPR
+ | RANGE_EXPR
+ | RECORD_EXPR
+ | REF_EXPR
+ | RETURN_EXPR
+ | TRY_EXPR
+ | TUPLE_EXPR
+ | WHILE_EXPR
+ | YIELD_EXPR
+ | LET_EXPR
+ | UNDERSCORE_EXPR
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -3413,7 +3443,6 @@ impl AstNode for Expr {
LITERAL => Expr::Literal(Literal { syntax }),
LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }),
MACRO_EXPR => Expr::MacroExpr(MacroExpr { syntax }),
- MACRO_STMTS => Expr::MacroStmts(MacroStmts { syntax }),
MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }),
@@ -3452,7 +3481,6 @@ impl AstNode for Expr {
Expr::Literal(it) => &it.syntax,
Expr::LoopExpr(it) => &it.syntax,
Expr::MacroExpr(it) => &it.syntax,
- Expr::MacroStmts(it) => &it.syntax,
Expr::MatchExpr(it) => &it.syntax,
Expr::MethodCallExpr(it) => &it.syntax,
Expr::ParenExpr(it) => &it.syntax,
@@ -3521,11 +3549,25 @@ impl From<Use> for Item {
}
impl AstNode for Item {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES
- | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true,
- _ => false,
- }
+ matches!(
+ kind,
+ CONST
+ | ENUM
+ | EXTERN_BLOCK
+ | EXTERN_CRATE
+ | FN
+ | IMPL
+ | MACRO_CALL
+ | MACRO_RULES
+ | MACRO_DEF
+ | MODULE
+ | STATIC
+ | STRUCT
+ | TRAIT
+ | TYPE_ALIAS
+ | UNION
+ | USE
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -3629,12 +3671,25 @@ impl From<ConstBlockPat> for Pat {
}
impl AstNode for Pat {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- IDENT_PAT | BOX_PAT | REST_PAT | LITERAL_PAT | MACRO_PAT | OR_PAT | PAREN_PAT
- | PATH_PAT | WILDCARD_PAT | RANGE_PAT | RECORD_PAT | REF_PAT | SLICE_PAT
- | TUPLE_PAT | TUPLE_STRUCT_PAT | CONST_BLOCK_PAT => true,
- _ => false,
- }
+ matches!(
+ kind,
+ IDENT_PAT
+ | BOX_PAT
+ | REST_PAT
+ | LITERAL_PAT
+ | MACRO_PAT
+ | OR_PAT
+ | PAREN_PAT
+ | PATH_PAT
+ | WILDCARD_PAT
+ | RANGE_PAT
+ | RECORD_PAT
+ | REF_PAT
+ | SLICE_PAT
+ | TUPLE_PAT
+ | TUPLE_STRUCT_PAT
+ | CONST_BLOCK_PAT
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -3686,12 +3741,7 @@ impl From<TupleFieldList> for FieldList {
fn from(node: TupleFieldList) -> FieldList { FieldList::TupleFieldList(node) }
}
impl AstNode for FieldList {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- RECORD_FIELD_LIST | TUPLE_FIELD_LIST => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, RECORD_FIELD_LIST | TUPLE_FIELD_LIST) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
RECORD_FIELD_LIST => FieldList::RecordFieldList(RecordFieldList { syntax }),
@@ -3717,12 +3767,7 @@ impl From<Union> for Adt {
fn from(node: Union) -> Adt { Adt::Union(node) }
}
impl AstNode for Adt {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- ENUM | STRUCT | UNION => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, ENUM | STRUCT | UNION) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
ENUM => Adt::Enum(Enum { syntax }),
@@ -3753,12 +3798,7 @@ impl From<TypeAlias> for AssocItem {
fn from(node: TypeAlias) -> AssocItem { AssocItem::TypeAlias(node) }
}
impl AstNode for AssocItem {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- CONST | FN | MACRO_CALL | TYPE_ALIAS => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, CONST | FN | MACRO_CALL | TYPE_ALIAS) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
CONST => AssocItem::Const(Const { syntax }),
@@ -3791,12 +3831,7 @@ impl From<TypeAlias> for ExternItem {
fn from(node: TypeAlias) -> ExternItem { ExternItem::TypeAlias(node) }
}
impl AstNode for ExternItem {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- FN | MACRO_CALL | STATIC | TYPE_ALIAS => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, FN | MACRO_CALL | STATIC | TYPE_ALIAS) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
FN => ExternItem::Fn(Fn { syntax }),
@@ -3827,10 +3862,7 @@ impl From<TypeParam> for GenericParam {
}
impl AstNode for GenericParam {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- CONST_PARAM | LIFETIME_PARAM | TYPE_PARAM => true,
- _ => false,
- }
+ matches!(kind, CONST_PARAM | LIFETIME_PARAM | TYPE_PARAM)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -3856,12 +3888,7 @@ impl AnyHasArgList {
}
}
impl AstNode for AnyHasArgList {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- CALL_EXPR | METHOD_CALL_EXPR => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, CALL_EXPR | METHOD_CALL_EXPR) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasArgList { syntax })
}
@@ -3875,76 +3902,76 @@ impl AnyHasAttrs {
}
impl AstNode for AnyHasAttrs {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
MACRO_CALL
- | SOURCE_FILE
- | CONST
- | ENUM
- | EXTERN_BLOCK
- | EXTERN_CRATE
- | FN
- | IMPL
- | MACRO_RULES
- | MACRO_DEF
- | MODULE
- | STATIC
- | STRUCT
- | TRAIT
- | TYPE_ALIAS
- | UNION
- | USE
- | ITEM_LIST
- | BLOCK_EXPR
- | SELF_PARAM
- | PARAM
- | RECORD_FIELD
- | TUPLE_FIELD
- | VARIANT
- | ASSOC_ITEM_LIST
- | EXTERN_ITEM_LIST
- | CONST_PARAM
- | LIFETIME_PARAM
- | TYPE_PARAM
- | LET_STMT
- | ARRAY_EXPR
- | AWAIT_EXPR
- | BIN_EXPR
- | BOX_EXPR
- | BREAK_EXPR
- | CALL_EXPR
- | CAST_EXPR
- | CLOSURE_EXPR
- | CONTINUE_EXPR
- | FIELD_EXPR
- | FOR_EXPR
- | IF_EXPR
- | INDEX_EXPR
- | LITERAL
- | LOOP_EXPR
- | MATCH_EXPR
- | METHOD_CALL_EXPR
- | PAREN_EXPR
- | PATH_EXPR
- | PREFIX_EXPR
- | RANGE_EXPR
- | REF_EXPR
- | RETURN_EXPR
- | TRY_EXPR
- | TUPLE_EXPR
- | WHILE_EXPR
- | YIELD_EXPR
- | LET_EXPR
- | UNDERSCORE_EXPR
- | STMT_LIST
- | RECORD_EXPR_FIELD_LIST
- | RECORD_EXPR_FIELD
- | MATCH_ARM_LIST
- | MATCH_ARM
- | IDENT_PAT
- | REST_PAT
- | RECORD_PAT_FIELD => true,
- _ => false,
- }
+ | SOURCE_FILE
+ | CONST
+ | ENUM
+ | EXTERN_BLOCK
+ | EXTERN_CRATE
+ | FN
+ | IMPL
+ | MACRO_RULES
+ | MACRO_DEF
+ | MODULE
+ | STATIC
+ | STRUCT
+ | TRAIT
+ | TYPE_ALIAS
+ | UNION
+ | USE
+ | ITEM_LIST
+ | BLOCK_EXPR
+ | SELF_PARAM
+ | PARAM
+ | RECORD_FIELD
+ | TUPLE_FIELD
+ | VARIANT
+ | ASSOC_ITEM_LIST
+ | EXTERN_ITEM_LIST
+ | CONST_PARAM
+ | LIFETIME_PARAM
+ | TYPE_PARAM
+ | LET_STMT
+ | ARRAY_EXPR
+ | AWAIT_EXPR
+ | BIN_EXPR
+ | BOX_EXPR
+ | BREAK_EXPR
+ | CALL_EXPR
+ | CAST_EXPR
+ | CLOSURE_EXPR
+ | CONTINUE_EXPR
+ | FIELD_EXPR
+ | FOR_EXPR
+ | IF_EXPR
+ | INDEX_EXPR
+ | LITERAL
+ | LOOP_EXPR
+ | MATCH_EXPR
+ | METHOD_CALL_EXPR
+ | PAREN_EXPR
+ | PATH_EXPR
+ | PREFIX_EXPR
+ | RANGE_EXPR
+ | REF_EXPR
+ | RETURN_EXPR
+ | TRY_EXPR
+ | TUPLE_EXPR
+ | WHILE_EXPR
+ | YIELD_EXPR
+ | LET_EXPR
+ | UNDERSCORE_EXPR
+ | STMT_LIST
+ | RECORD_EXPR_FIELD_LIST
+ | RECORD_EXPR_FIELD
+ | MATCH_ARM_LIST
+ | MATCH_ARM
+ | IDENT_PAT
+ | REST_PAT
+ | RECORD_PAT_FIELD
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasAttrs { syntax })
@@ -3959,12 +3986,29 @@ impl AnyHasDocComments {
}
impl AstNode for AnyHasDocComments {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- MACRO_CALL | SOURCE_FILE | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL
- | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION
- | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => true,
- _ => false,
- }
+ matches!(
+ kind,
+ MACRO_CALL
+ | SOURCE_FILE
+ | CONST
+ | ENUM
+ | EXTERN_BLOCK
+ | EXTERN_CRATE
+ | FN
+ | IMPL
+ | MACRO_RULES
+ | MACRO_DEF
+ | MODULE
+ | STATIC
+ | STRUCT
+ | TRAIT
+ | TYPE_ALIAS
+ | UNION
+ | USE
+ | RECORD_FIELD
+ | TUPLE_FIELD
+ | VARIANT
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasDocComments { syntax })
@@ -3979,10 +4023,7 @@ impl AnyHasGenericParams {
}
impl AstNode for AnyHasGenericParams {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION => true,
- _ => false,
- }
+ matches!(kind, ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasGenericParams { syntax })
@@ -3996,12 +4037,7 @@ impl AnyHasLoopBody {
}
}
impl AstNode for AnyHasLoopBody {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- FOR_EXPR | LOOP_EXPR | WHILE_EXPR => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, FOR_EXPR | LOOP_EXPR | WHILE_EXPR) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasLoopBody { syntax })
}
@@ -4014,12 +4050,7 @@ impl AnyHasModuleItem {
}
}
impl AstNode for AnyHasModuleItem {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- MACRO_ITEMS | SOURCE_FILE | ITEM_LIST => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, MACRO_ITEMS | SOURCE_FILE | ITEM_LIST) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasModuleItem { syntax })
}
@@ -4033,12 +4064,27 @@ impl AnyHasName {
}
impl AstNode for AnyHasName {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- CONST | ENUM | FN | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT
- | TYPE_ALIAS | UNION | RENAME | SELF_PARAM | RECORD_FIELD | VARIANT | CONST_PARAM
- | TYPE_PARAM | IDENT_PAT => true,
- _ => false,
- }
+ matches!(
+ kind,
+ CONST
+ | ENUM
+ | FN
+ | MACRO_RULES
+ | MACRO_DEF
+ | MODULE
+ | STATIC
+ | STRUCT
+ | TRAIT
+ | TYPE_ALIAS
+ | UNION
+ | RENAME
+ | SELF_PARAM
+ | RECORD_FIELD
+ | VARIANT
+ | CONST_PARAM
+ | TYPE_PARAM
+ | IDENT_PAT
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasName { syntax })
@@ -4053,10 +4099,10 @@ impl AnyHasTypeBounds {
}
impl AstNode for AnyHasTypeBounds {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED => true,
- _ => false,
- }
+ matches!(
+ kind,
+ ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasTypeBounds { syntax })
@@ -4071,13 +4117,26 @@ impl AnyHasVisibility {
}
impl AstNode for AnyHasVisibility {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- CONST | ENUM | EXTERN_CRATE | FN | IMPL | MACRO_RULES | MACRO_DEF | MODULE | STATIC
- | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => {
- true
- }
- _ => false,
- }
+ matches!(
+ kind,
+ CONST
+ | ENUM
+ | EXTERN_CRATE
+ | FN
+ | IMPL
+ | MACRO_RULES
+ | MACRO_DEF
+ | MODULE
+ | STATIC
+ | STRUCT
+ | TRAIT
+ | TYPE_ALIAS
+ | UNION
+ | USE
+ | RECORD_FIELD
+ | TUPLE_FIELD
+ | VARIANT
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| AnyHasVisibility { syntax })
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 5908dda8e..83f8bbac5 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -25,7 +25,7 @@ pub mod ext {
return from_text(&name.text());
fn from_text(text: &str) -> ast::IdentPat {
- ast_from_text(&format!("fn f({}: ())", text))
+ ast_from_text(&format!("fn f({text}: ())"))
}
}
pub fn ident_path(ident: &str) -> ast::Path {
@@ -60,10 +60,10 @@ pub mod ext {
expr_from_text("todo!()")
}
pub fn expr_ty_default(ty: &ast::Type) -> ast::Expr {
- expr_from_text(&format!("{}::default()", ty))
+ expr_from_text(&format!("{ty}::default()"))
}
pub fn expr_ty_new(ty: &ast::Type) -> ast::Expr {
- expr_from_text(&format!("{}::new()", ty))
+ expr_from_text(&format!("{ty}::new()"))
}
pub fn zero_number() -> ast::Expr {
@@ -92,18 +92,20 @@ pub mod ext {
ty_path(ident_path("bool"))
}
pub fn ty_option(t: ast::Type) -> ast::Type {
- ty_from_text(&format!("Option<{}>", t))
+ ty_from_text(&format!("Option<{t}>"))
}
pub fn ty_result(t: ast::Type, e: ast::Type) -> ast::Type {
- ty_from_text(&format!("Result<{}, {}>", t, e))
+ ty_from_text(&format!("Result<{t}, {e}>"))
}
}
-pub fn name(text: &str) -> ast::Name {
- ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text))
+pub fn name(name: &str) -> ast::Name {
+ let raw_escape = raw_ident_esc(name);
+ ast_from_text(&format!("mod {raw_escape}{name};"))
}
-pub fn name_ref(text: &str) -> ast::NameRef {
- ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text))
+pub fn name_ref(name_ref: &str) -> ast::NameRef {
+ let raw_escape = raw_ident_esc(name_ref);
+ ast_from_text(&format!("fn f() {{ {raw_escape}{name_ref}; }}"))
}
fn raw_ident_esc(ident: &str) -> &'static str {
let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
@@ -118,10 +120,10 @@ pub fn lifetime(text: &str) -> ast::Lifetime {
let mut text = text;
let tmp;
if never!(!text.starts_with('\'')) {
- tmp = format!("'{}", text);
+ tmp = format!("'{text}");
text = &tmp;
}
- ast_from_text(&format!("fn f<{}>() {{ }}", text))
+ ast_from_text(&format!("fn f<{text}>() {{ }}"))
}
// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
@@ -142,16 +144,16 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
contents.push(',');
}
- ty_from_text(&format!("({})", contents))
+ ty_from_text(&format!("({contents})"))
}
pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type {
- ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
+ ty_from_text(&if exclusive { format!("&mut {target}") } else { format!("&{target}") })
}
pub fn ty_path(path: ast::Path) -> ast::Type {
ty_from_text(&path.to_string())
}
fn ty_from_text(text: &str) -> ast::Type {
- ast_from_text(&format!("type _T = {};", text))
+ ast_from_text(&format!("type _T = {text};"))
}
pub fn assoc_item_list() -> ast::AssocItemList {
@@ -171,7 +173,7 @@ pub fn impl_(
Some(params) => params.to_string(),
None => String::new(),
};
- ast_from_text(&format!("impl{} {}{} {{}}", params, ty, ty_params))
+ ast_from_text(&format!("impl{params} {ty}{ty_params} {{}}"))
}
pub fn impl_trait(
@@ -180,7 +182,7 @@ pub fn impl_trait(
ty_params: Option<ast::GenericParamList>,
) -> ast::Impl {
let ty_params = ty_params.map_or_else(String::new, |params| params.to_string());
- ast_from_text(&format!("impl{2} {} for {}{2} {{}}", trait_, ty, ty_params))
+ ast_from_text(&format!("impl{ty_params} {trait_} for {ty}{ty_params} {{}}"))
}
pub(crate) fn generic_arg_list() -> ast::GenericArgList {
@@ -188,13 +190,13 @@ pub(crate) fn generic_arg_list() -> ast::GenericArgList {
}
pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
- ast_from_text(&format!("type __ = {};", name_ref))
+ ast_from_text(&format!("type __ = {name_ref};"))
}
pub fn path_segment_ty(type_ref: ast::Type, trait_ref: Option<ast::PathType>) -> ast::PathSegment {
let text = match trait_ref {
- Some(trait_ref) => format!("fn f(x: <{} as {}>) {{}}", type_ref, trait_ref),
- None => format!("fn f(x: <{}>) {{}}", type_ref),
+ Some(trait_ref) => format!("fn f(x: <{type_ref} as {trait_ref}>) {{}}"),
+ None => format!("fn f(x: <{type_ref}>) {{}}"),
};
ast_from_text(&text)
}
@@ -212,15 +214,15 @@ pub fn path_segment_crate() -> ast::PathSegment {
}
pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
- ast_from_text(&format!("type __ = {};", segment))
+ ast_from_text(&format!("type __ = {segment};"))
}
pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
- ast_from_text(&format!("{}::{}", qual, segment))
+ ast_from_text(&format!("{qual}::{segment}"))
}
// FIXME: path concatenation operation doesn't make sense as AST op.
pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path {
- ast_from_text(&format!("type __ = {}::{};", first, second))
+ ast_from_text(&format!("type __ = {first}::{second};"))
}
pub fn path_from_segments(
@@ -229,20 +231,20 @@ pub fn path_from_segments(
) -> ast::Path {
let segments = segments.into_iter().map(|it| it.syntax().clone()).join("::");
ast_from_text(&if is_abs {
- format!("fn f(x: ::{}) {{}}", segments)
+ format!("fn f(x: ::{segments}) {{}}")
} else {
- format!("fn f(x: {}) {{}}", segments)
+ format!("fn f(x: {segments}) {{}}")
})
}
pub fn join_paths(paths: impl IntoIterator<Item = ast::Path>) -> ast::Path {
let paths = paths.into_iter().map(|it| it.syntax().clone()).join("::");
- ast_from_text(&format!("type __ = {};", paths))
+ ast_from_text(&format!("type __ = {paths};"))
}
// FIXME: should not be pub
pub fn path_from_text(text: &str) -> ast::Path {
- ast_from_text(&format!("fn main() {{ let test = {}; }}", text))
+ ast_from_text(&format!("fn main() {{ let test = {text}; }}"))
}
pub fn use_tree_glob() -> ast::UseTree {
@@ -257,50 +259,50 @@ pub fn use_tree(
let mut buf = "use ".to_string();
buf += &path.syntax().to_string();
if let Some(use_tree_list) = use_tree_list {
- format_to!(buf, "::{}", use_tree_list);
+ format_to!(buf, "::{use_tree_list}");
}
if add_star {
buf += "::*";
}
if let Some(alias) = alias {
- format_to!(buf, " {}", alias);
+ format_to!(buf, " {alias}");
}
ast_from_text(&buf)
}
pub fn use_tree_list(use_trees: impl IntoIterator<Item = ast::UseTree>) -> ast::UseTreeList {
let use_trees = use_trees.into_iter().map(|it| it.syntax().clone()).join(", ");
- ast_from_text(&format!("use {{{}}};", use_trees))
+ ast_from_text(&format!("use {{{use_trees}}};"))
}
pub fn use_(visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use {
let visibility = match visibility {
None => String::new(),
- Some(it) => format!("{} ", it),
+ Some(it) => format!("{it} "),
};
- ast_from_text(&format!("{}use {};", visibility, use_tree))
+ ast_from_text(&format!("{visibility}use {use_tree};"))
}
pub fn record_expr(path: ast::Path, fields: ast::RecordExprFieldList) -> ast::RecordExpr {
- ast_from_text(&format!("fn f() {{ {} {} }}", path, fields))
+ ast_from_text(&format!("fn f() {{ {path} {fields} }}"))
}
pub fn record_expr_field_list(
fields: impl IntoIterator<Item = ast::RecordExprField>,
) -> ast::RecordExprFieldList {
let fields = fields.into_iter().join(", ");
- ast_from_text(&format!("fn f() {{ S {{ {} }} }}", fields))
+ ast_from_text(&format!("fn f() {{ S {{ {fields} }} }}"))
}
pub fn record_expr_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField {
return match expr {
- Some(expr) => from_text(&format!("{}: {}", name, expr)),
+ Some(expr) => from_text(&format!("{name}: {expr}")),
None => from_text(&name.to_string()),
};
fn from_text(text: &str) -> ast::RecordExprField {
- ast_from_text(&format!("fn f() {{ S {{ {}, }} }}", text))
+ ast_from_text(&format!("fn f() {{ S {{ {text}, }} }}"))
}
}
@@ -311,9 +313,9 @@ pub fn record_field(
) -> ast::RecordField {
let visibility = match visibility {
None => String::new(),
- Some(it) => format!("{} ", it),
+ Some(it) => format!("{it} "),
};
- ast_from_text(&format!("struct S {{ {}{}: {}, }}", visibility, name, ty))
+ ast_from_text(&format!("struct S {{ {visibility}{name}: {ty}, }}"))
}
// TODO
@@ -323,13 +325,13 @@ pub fn block_expr(
) -> ast::BlockExpr {
let mut buf = "{\n".to_string();
for stmt in stmts.into_iter() {
- format_to!(buf, " {}\n", stmt);
+ format_to!(buf, " {stmt}\n");
}
if let Some(tail_expr) = tail_expr {
- format_to!(buf, " {}\n", tail_expr);
+ format_to!(buf, " {tail_expr}\n");
}
buf += "}";
- ast_from_text(&format!("fn f() {}", buf))
+ ast_from_text(&format!("fn f() {buf}"))
}
/// Ideally this function wouldn't exist since it involves manual indenting.
@@ -343,18 +345,18 @@ pub fn hacky_block_expr_with_comments(
let mut buf = "{\n".to_string();
for node_or_token in elements.into_iter() {
match node_or_token {
- rowan::NodeOrToken::Node(n) => format_to!(buf, " {}\n", n),
+ rowan::NodeOrToken::Node(n) => format_to!(buf, " {n}\n"),
rowan::NodeOrToken::Token(t) if t.kind() == SyntaxKind::COMMENT => {
- format_to!(buf, " {}\n", t)
+ format_to!(buf, " {t}\n")
}
_ => (),
}
}
if let Some(tail_expr) = tail_expr {
- format_to!(buf, " {}\n", tail_expr);
+ format_to!(buf, " {tail_expr}\n");
}
buf += "}";
- ast_from_text(&format!("fn f() {}", buf))
+ ast_from_text(&format!("fn f() {buf}"))
}
pub fn expr_unit() -> ast::Expr {
@@ -362,7 +364,7 @@ pub fn expr_unit() -> ast::Expr {
}
pub fn expr_literal(text: &str) -> ast::Literal {
assert_eq!(text.trim(), text);
- ast_from_text(&format!("fn f() {{ let _ = {}; }}", text))
+ ast_from_text(&format!("fn f() {{ let _ = {text}; }}"))
}
pub fn expr_empty_block() -> ast::Expr {
@@ -373,41 +375,41 @@ pub fn expr_path(path: ast::Path) -> ast::Expr {
}
pub fn expr_continue(label: Option<ast::Lifetime>) -> ast::Expr {
match label {
- Some(label) => expr_from_text(&format!("continue {}", label)),
+ Some(label) => expr_from_text(&format!("continue {label}")),
None => expr_from_text("continue"),
}
}
// Consider `op: SyntaxKind` instead for nicer syntax at the call-site?
pub fn expr_bin_op(lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr {
- expr_from_text(&format!("{} {} {}", lhs, op, rhs))
+ expr_from_text(&format!("{lhs} {op} {rhs}"))
}
pub fn expr_break(label: Option<ast::Lifetime>, expr: Option<ast::Expr>) -> ast::Expr {
let mut s = String::from("break");
if let Some(label) = label {
- format_to!(s, " {}", label);
+ format_to!(s, " {label}");
}
if let Some(expr) = expr {
- format_to!(s, " {}", expr);
+ format_to!(s, " {expr}");
}
expr_from_text(&s)
}
pub fn expr_return(expr: Option<ast::Expr>) -> ast::Expr {
match expr {
- Some(expr) => expr_from_text(&format!("return {}", expr)),
+ Some(expr) => expr_from_text(&format!("return {expr}")),
None => expr_from_text("return"),
}
}
pub fn expr_try(expr: ast::Expr) -> ast::Expr {
- expr_from_text(&format!("{}?", expr))
+ expr_from_text(&format!("{expr}?"))
}
pub fn expr_await(expr: ast::Expr) -> ast::Expr {
- expr_from_text(&format!("{}.await", expr))
+ expr_from_text(&format!("{expr}.await"))
}
pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr {
- expr_from_text(&format!("match {} {}", expr, match_arm_list))
+ expr_from_text(&format!("match {expr} {match_arm_list}"))
}
pub fn expr_if(
condition: ast::Expr,
@@ -415,66 +417,67 @@ pub fn expr_if(
else_branch: Option<ast::ElseBranch>,
) -> ast::Expr {
let else_branch = match else_branch {
- Some(ast::ElseBranch::Block(block)) => format!("else {}", block),
- Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {}", if_expr),
+ Some(ast::ElseBranch::Block(block)) => format!("else {block}"),
+ Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {if_expr}"),
None => String::new(),
};
- expr_from_text(&format!("if {} {} {}", condition, then_branch, else_branch))
+ expr_from_text(&format!("if {condition} {then_branch} {else_branch}"))
}
pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::Expr {
- expr_from_text(&format!("for {} in {} {}", pat, expr, block))
+ expr_from_text(&format!("for {pat} in {expr} {block}"))
}
pub fn expr_loop(block: ast::BlockExpr) -> ast::Expr {
- expr_from_text(&format!("loop {}", block))
+ expr_from_text(&format!("loop {block}"))
}
pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
let token = token(op);
- expr_from_text(&format!("{}{}", token, expr))
+ expr_from_text(&format!("{token}{expr}"))
}
pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
- expr_from_text(&format!("{}{}", f, arg_list))
+ expr_from_text(&format!("{f}{arg_list}"))
}
pub fn expr_method_call(
receiver: ast::Expr,
method: ast::NameRef,
arg_list: ast::ArgList,
) -> ast::Expr {
- expr_from_text(&format!("{}.{}{}", receiver, method, arg_list))
+ expr_from_text(&format!("{receiver}.{method}{arg_list}"))
}
pub fn expr_macro_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
- expr_from_text(&format!("{}!{}", f, arg_list))
+ expr_from_text(&format!("{f}!{arg_list}"))
}
pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr {
- expr_from_text(&if exclusive { format!("&mut {}", expr) } else { format!("&{}", expr) })
+ expr_from_text(&if exclusive { format!("&mut {expr}") } else { format!("&{expr}") })
}
pub fn expr_closure(pats: impl IntoIterator<Item = ast::Param>, expr: ast::Expr) -> ast::Expr {
let params = pats.into_iter().join(", ");
- expr_from_text(&format!("|{}| {}", params, expr))
+ expr_from_text(&format!("|{params}| {expr}"))
}
pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
- expr_from_text(&format!("{}.{}", receiver, field))
+ expr_from_text(&format!("{receiver}.{field}"))
}
pub fn expr_paren(expr: ast::Expr) -> ast::Expr {
- expr_from_text(&format!("({})", expr))
+ expr_from_text(&format!("({expr})"))
}
pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::Expr {
let expr = elements.into_iter().format(", ");
- expr_from_text(&format!("({})", expr))
+ expr_from_text(&format!("({expr})"))
}
pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
- expr_from_text(&format!("{} = {}", lhs, rhs))
+ expr_from_text(&format!("{lhs} = {rhs}"))
}
fn expr_from_text(text: &str) -> ast::Expr {
- ast_from_text(&format!("const C: () = {};", text))
+ ast_from_text(&format!("const C: () = {text};"))
}
pub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr {
- ast_from_text(&format!("const _: () = while let {} = {} {{}};", pattern, expr))
+ ast_from_text(&format!("const _: () = while let {pattern} = {expr} {{}};"))
}
pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList {
- ast_from_text(&format!("fn main() {{ ()({}) }}", args.into_iter().format(", ")))
+ let args = args.into_iter().format(", ");
+ ast_from_text(&format!("fn main() {{ ()({args}) }}"))
}
pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
@@ -485,7 +488,7 @@ pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
if mut_ {
s.push_str("mut ");
}
- format_to!(s, "{}", name);
+ format_to!(s, "{name}");
s.push_str(": ())");
ast_from_text(&s)
}
@@ -494,7 +497,7 @@ pub fn wildcard_pat() -> ast::WildcardPat {
return from_text("_");
fn from_text(text: &str) -> ast::WildcardPat {
- ast_from_text(&format!("fn f({}: ())", text))
+ ast_from_text(&format!("fn f({text}: ())"))
}
}
@@ -502,7 +505,7 @@ pub fn literal_pat(lit: &str) -> ast::LiteralPat {
return from_text(lit);
fn from_text(text: &str) -> ast::LiteralPat {
- ast_from_text(&format!("fn f() {{ match x {{ {} => {{}} }} }}", text))
+ ast_from_text(&format!("fn f() {{ match x {{ {text} => {{}} }} }}"))
}
}
@@ -515,10 +518,10 @@ pub fn tuple_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat {
if count == 1 {
pats_str.push(',');
}
- return from_text(&format!("({})", pats_str));
+ return from_text(&format!("({pats_str})"));
fn from_text(text: &str) -> ast::TuplePat {
- ast_from_text(&format!("fn f({}: ())", text))
+ ast_from_text(&format!("fn f({text}: ())"))
}
}
@@ -527,46 +530,46 @@ pub fn tuple_struct_pat(
pats: impl IntoIterator<Item = ast::Pat>,
) -> ast::TupleStructPat {
let pats_str = pats.into_iter().join(", ");
- return from_text(&format!("{}({})", path, pats_str));
+ return from_text(&format!("{path}({pats_str})"));
fn from_text(text: &str) -> ast::TupleStructPat {
- ast_from_text(&format!("fn f({}: ())", text))
+ ast_from_text(&format!("fn f({text}: ())"))
}
}
pub fn record_pat(path: ast::Path, pats: impl IntoIterator<Item = ast::Pat>) -> ast::RecordPat {
let pats_str = pats.into_iter().join(", ");
- return from_text(&format!("{} {{ {} }}", path, pats_str));
+ return from_text(&format!("{path} {{ {pats_str} }}"));
fn from_text(text: &str) -> ast::RecordPat {
- ast_from_text(&format!("fn f({}: ())", text))
+ ast_from_text(&format!("fn f({text}: ())"))
}
}
pub fn record_pat_with_fields(path: ast::Path, fields: ast::RecordPatFieldList) -> ast::RecordPat {
- ast_from_text(&format!("fn f({} {}: ()))", path, fields))
+ ast_from_text(&format!("fn f({path} {fields}: ()))"))
}
pub fn record_pat_field_list(
fields: impl IntoIterator<Item = ast::RecordPatField>,
) -> ast::RecordPatFieldList {
let fields = fields.into_iter().join(", ");
- ast_from_text(&format!("fn f(S {{ {} }}: ()))", fields))
+ ast_from_text(&format!("fn f(S {{ {fields} }}: ()))"))
}
pub fn record_pat_field(name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPatField {
- ast_from_text(&format!("fn f(S {{ {}: {} }}: ()))", name_ref, pat))
+ ast_from_text(&format!("fn f(S {{ {name_ref}: {pat} }}: ()))"))
}
pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField {
- ast_from_text(&format!("fn f(S {{ {} }}: ()))", name_ref))
+ ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))"))
}
/// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise.
pub fn path_pat(path: ast::Path) -> ast::Pat {
return from_text(&path.to_string());
fn from_text(text: &str) -> ast::Pat {
- ast_from_text(&format!("fn f({}: ())", text))
+ ast_from_text(&format!("fn f({text}: ())"))
}
}
@@ -577,12 +580,12 @@ pub fn match_arm(
) -> ast::MatchArm {
let pats_str = pats.into_iter().join(" | ");
return match guard {
- Some(guard) => from_text(&format!("{} if {} => {}", pats_str, guard, expr)),
- None => from_text(&format!("{} => {}", pats_str, expr)),
+ Some(guard) => from_text(&format!("{pats_str} if {guard} => {expr}")),
+ None => from_text(&format!("{pats_str} => {expr}")),
};
fn from_text(text: &str) -> ast::MatchArm {
- ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
+ ast_from_text(&format!("fn f() {{ match () {{{text}}} }}"))
}
}
@@ -592,10 +595,10 @@ pub fn match_arm_with_guard(
expr: ast::Expr,
) -> ast::MatchArm {
let pats_str = pats.into_iter().join(" | ");
- return from_text(&format!("{} if {} => {}", pats_str, guard, expr));
+ return from_text(&format!("{pats_str} if {guard} => {expr}"));
fn from_text(text: &str) -> ast::MatchArm {
- ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
+ ast_from_text(&format!("fn f() {{ match () {{{text}}} }}"))
}
}
@@ -605,13 +608,14 @@ pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::Mat
.map(|arm| {
let needs_comma = arm.expr().map_or(true, |it| !it.is_block_like());
let comma = if needs_comma { "," } else { "" };
- format!(" {}{}\n", arm.syntax(), comma)
+ let arm = arm.syntax();
+ format!(" {arm}{comma}\n")
})
.collect::<String>();
return from_text(&arms_str);
fn from_text(text: &str) -> ast::MatchArmList {
- ast_from_text(&format!("fn f() {{ match () {{\n{}}} }}", text))
+ ast_from_text(&format!("fn f() {{ match () {{\n{text}}} }}"))
}
}
@@ -620,10 +624,10 @@ pub fn where_pred(
bounds: impl IntoIterator<Item = ast::TypeBound>,
) -> ast::WherePred {
let bounds = bounds.into_iter().join(" + ");
- return from_text(&format!("{}: {}", path, bounds));
+ return from_text(&format!("{path}: {bounds}"));
fn from_text(text: &str) -> ast::WherePred {
- ast_from_text(&format!("fn f() where {} {{ }}", text))
+ ast_from_text(&format!("fn f() where {text} {{ }}"))
}
}
@@ -632,7 +636,7 @@ pub fn where_clause(preds: impl IntoIterator<Item = ast::WherePred>) -> ast::Whe
return from_text(preds.as_str());
fn from_text(text: &str) -> ast::WhereClause {
- ast_from_text(&format!("fn f() where {} {{ }}", text))
+ ast_from_text(&format!("fn f() where {text} {{ }}"))
}
}
@@ -642,19 +646,19 @@ pub fn let_stmt(
initializer: Option<ast::Expr>,
) -> ast::LetStmt {
let mut text = String::new();
- format_to!(text, "let {}", pattern);
+ format_to!(text, "let {pattern}");
if let Some(ty) = ty {
- format_to!(text, ": {}", ty);
+ format_to!(text, ": {ty}");
}
match initializer {
- Some(it) => format_to!(text, " = {};", it),
+ Some(it) => format_to!(text, " = {it};"),
None => format_to!(text, ";"),
};
- ast_from_text(&format!("fn f() {{ {} }}", text))
+ ast_from_text(&format!("fn f() {{ {text} }}"))
}
pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
let semi = if expr.is_block_like() { "" } else { ";" };
- ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi))
+ ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))
}
pub fn item_const(
@@ -665,13 +669,13 @@ pub fn item_const(
) -> ast::Const {
let visibility = match visibility {
None => String::new(),
- Some(it) => format!("{} ", it),
+ Some(it) => format!("{it} "),
};
- ast_from_text(&format!("{} const {}: {} = {};", visibility, name, ty, expr))
+ ast_from_text(&format!("{visibility} const {name}: {ty} = {expr};"))
}
pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param {
- ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty))
+ ast_from_text(&format!("fn f({pat}: {ty}) {{ }}"))
}
pub fn self_param() -> ast::SelfParam {
@@ -679,7 +683,7 @@ pub fn self_param() -> ast::SelfParam {
}
pub fn ret_type(ty: ast::Type) -> ast::RetType {
- ast_from_text(&format!("fn f() -> {} {{ }}", ty))
+ ast_from_text(&format!("fn f() -> {ty} {{ }}"))
}
pub fn param_list(
@@ -688,30 +692,30 @@ pub fn param_list(
) -> ast::ParamList {
let args = pats.into_iter().join(", ");
let list = match self_param {
- Some(self_param) if args.is_empty() => format!("fn f({}) {{ }}", self_param),
- Some(self_param) => format!("fn f({}, {}) {{ }}", self_param, args),
- None => format!("fn f({}) {{ }}", args),
+ Some(self_param) if args.is_empty() => format!("fn f({self_param}) {{ }}"),
+ Some(self_param) => format!("fn f({self_param}, {args}) {{ }}"),
+ None => format!("fn f({args}) {{ }}"),
};
ast_from_text(&list)
}
pub fn type_param(name: ast::Name, ty: Option<ast::TypeBoundList>) -> ast::TypeParam {
let bound = match ty {
- Some(it) => format!(": {}", it),
+ Some(it) => format!(": {it}"),
None => String::new(),
};
- ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound))
+ ast_from_text(&format!("fn f<{name}{bound}>() {{ }}"))
}
pub fn lifetime_param(lifetime: ast::Lifetime) -> ast::LifetimeParam {
- ast_from_text(&format!("fn f<{}>() {{ }}", lifetime))
+ ast_from_text(&format!("fn f<{lifetime}>() {{ }}"))
}
pub fn generic_param_list(
pats: impl IntoIterator<Item = ast::GenericParam>,
) -> ast::GenericParamList {
let args = pats.into_iter().join(", ");
- ast_from_text(&format!("fn f<{}>() {{ }}", args))
+ ast_from_text(&format!("fn f<{args}>() {{ }}"))
}
pub fn visibility_pub_crate() -> ast::Visibility {
@@ -724,30 +728,33 @@ pub fn visibility_pub() -> ast::Visibility {
pub fn tuple_field_list(fields: impl IntoIterator<Item = ast::TupleField>) -> ast::TupleFieldList {
let fields = fields.into_iter().join(", ");
- ast_from_text(&format!("struct f({});", fields))
+ ast_from_text(&format!("struct f({fields});"))
}
pub fn record_field_list(
fields: impl IntoIterator<Item = ast::RecordField>,
) -> ast::RecordFieldList {
let fields = fields.into_iter().join(", ");
- ast_from_text(&format!("struct f {{ {} }}", fields))
+ ast_from_text(&format!("struct f {{ {fields} }}"))
}
pub fn tuple_field(visibility: Option<ast::Visibility>, ty: ast::Type) -> ast::TupleField {
let visibility = match visibility {
None => String::new(),
- Some(it) => format!("{} ", it),
+ Some(it) => format!("{it} "),
};
- ast_from_text(&format!("struct f({}{});", visibility, ty))
+ ast_from_text(&format!("struct f({visibility}{ty});"))
}
pub fn variant(name: ast::Name, field_list: Option<ast::FieldList>) -> ast::Variant {
let field_list = match field_list {
None => String::new(),
- Some(it) => format!("{}", it),
+ Some(it) => match it {
+ ast::FieldList::RecordFieldList(record) => format!(" {record}"),
+ ast::FieldList::TupleFieldList(tuple) => format!("{tuple}"),
+ },
};
- ast_from_text(&format!("enum f {{ {}{} }}", name, field_list))
+ ast_from_text(&format!("enum f {{ {name}{field_list} }}"))
}
pub fn fn_(
@@ -760,23 +767,22 @@ pub fn fn_(
is_async: bool,
) -> ast::Fn {
let type_params = match type_params {
- Some(type_params) => format!("{}", type_params),
+ Some(type_params) => format!("{type_params}"),
None => "".into(),
};
let ret_type = match ret_type {
- Some(ret_type) => format!("{} ", ret_type),
+ Some(ret_type) => format!("{ret_type} "),
None => "".into(),
};
let visibility = match visibility {
None => String::new(),
- Some(it) => format!("{} ", it),
+ Some(it) => format!("{it} "),
};
let async_literal = if is_async { "async " } else { "" };
ast_from_text(&format!(
- "{}{}fn {}{}{} {}{}",
- visibility, async_literal, fn_name, type_params, params, ret_type, body
+ "{visibility}{async_literal}fn {fn_name}{type_params}{params} {ret_type}{body}",
))
}
@@ -790,13 +796,10 @@ pub fn struct_(
let type_params = generic_param_list.map_or_else(String::new, |it| it.to_string());
let visibility = match visibility {
None => String::new(),
- Some(it) => format!("{} ", it),
+ Some(it) => format!("{it} "),
};
- ast_from_text(&format!(
- "{}struct {}{}{}{}",
- visibility, strukt_name, type_params, field_list, semicolon
- ))
+ ast_from_text(&format!("{visibility}struct {strukt_name}{type_params}{field_list}{semicolon}",))
}
#[track_caller]
@@ -805,7 +808,8 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
let node = match parse.tree().syntax().descendants().find_map(N::cast) {
Some(it) => it,
None => {
- panic!("Failed to make ast node `{}` from text {}", std::any::type_name::<N>(), text)
+ let node = std::any::type_name::<N>();
+ panic!("Failed to make ast node `{node}` from text {text}")
}
};
let node = node.clone_subtree();
@@ -821,7 +825,7 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken {
.descendants_with_tokens()
.filter_map(|it| it.into_token())
.find(|it| it.kind() == kind)
- .unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
+ .unwrap_or_else(|| panic!("unhandled token: {kind:?}"))
}
pub mod tokens {
@@ -860,7 +864,7 @@ pub mod tokens {
pub fn literal(text: &str) -> SyntaxToken {
assert_eq!(text.trim(), text);
- let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {}; }}", text));
+ let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {text}; }}"));
lit.syntax().first_child_or_token().unwrap().into_token().unwrap()
}
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs
index a687ba0b7..8f7b3fb60 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs
@@ -111,10 +111,10 @@ impl fmt::Display for BinaryOp {
BinaryOp::ArithOp(op) => fmt::Display::fmt(op, f),
BinaryOp::CmpOp(op) => fmt::Display::fmt(op, f),
BinaryOp::Assignment { op } => {
- f.write_str("=")?;
if let Some(op) = op {
fmt::Display::fmt(op, f)?;
}
+ f.write_str("=")?;
Ok(())
}
}
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
index 28976d837..ba72e6442 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
@@ -322,7 +322,7 @@ impl ast::IntNumber {
pub fn float_value(&self) -> Option<f64> {
let (_, text, _) = self.split_into_parts();
- text.parse::<f64>().ok()
+ text.replace('_', "").parse::<f64>().ok()
}
}
@@ -361,7 +361,7 @@ impl ast::FloatNumber {
pub fn value(&self) -> Option<f64> {
let (text, _) = self.split_into_parts();
- text.parse::<f64>().ok()
+ text.replace('_', "").parse::<f64>().ok()
}
}
@@ -397,6 +397,15 @@ mod tests {
assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.suffix(), expected.into());
}
+ fn check_float_value(lit: &str, expected: impl Into<Option<f64>> + Copy) {
+ assert_eq!(FloatNumber { syntax: make::tokens::literal(lit) }.value(), expected.into());
+ assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.float_value(), expected.into());
+ }
+
+ fn check_int_value(lit: &str, expected: impl Into<Option<u128>>) {
+ assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.value(), expected.into());
+ }
+
#[test]
fn test_float_number_suffix() {
check_float_suffix("123.0", None);
@@ -437,6 +446,14 @@ mod tests {
check_string_value(r"\nfoobar", "\nfoobar");
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
}
+
+ #[test]
+ fn test_value_underscores() {
+ check_float_value("3.141592653589793_f64", 3.141592653589793_f64);
+ check_float_value("1__0.__0__f32", 10.0);
+ check_int_value("0b__1_0_", 2);
+ check_int_value("1_1_1_1_1_1", 111111);
+ }
}
impl ast::Char {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs b/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs
index 256999fe0..7c7a60d62 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs
@@ -2,10 +2,7 @@
//!
//! We don't normally run fuzzying, so this is hopelessly bitrotten :(
-use std::{
- convert::TryInto,
- str::{self, FromStr},
-};
+use std::str::{self, FromStr};
use text_edit::Indel;
diff --git a/src/tools/rust-analyzer/crates/syntax/src/hacks.rs b/src/tools/rust-analyzer/crates/syntax/src/hacks.rs
index a047f61fa..ec3d3d444 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/hacks.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/hacks.rs
@@ -1,4 +1,4 @@
-//! Things which exist to solve practial issues, but which shouldn't exist.
+//! Things which exist to solve practical issues, but which shouldn't exist.
//!
//! Please avoid adding new usages of the functions in this module
diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
index 7fa354c0c..4f5e273a5 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
@@ -1,4 +1,4 @@
-//! Syntax Tree library used throughout the rust analyzer.
+//! Syntax Tree library used throughout the rust-analyzer.
//!
//! Properties:
//! - easy and fast incremental re-parsing
diff --git a/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs b/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
index 6d2766225..70b54843d 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
@@ -169,10 +169,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
quote! {
impl AstNode for #name {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- #(#kinds)|* => true,
- _ => false,
- }
+ matches!(kind, #(#kinds)|*)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -253,10 +250,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
}
impl AstNode for #name {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- #(#kinds)|* => true,
- _ => false,
- }
+ matches!(kind, #(#kinds)|*)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then(|| #name { syntax })
@@ -410,24 +404,17 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> String {
impl SyntaxKind {
pub fn is_keyword(self) -> bool {
- match self {
- #(#all_keywords)|* => true,
- _ => false,
- }
+ matches!(self, #(#all_keywords)|*)
}
pub fn is_punct(self) -> bool {
- match self {
- #(#punctuation)|* => true,
- _ => false,
- }
+
+ matches!(self, #(#punctuation)|*)
+
}
pub fn is_literal(self) -> bool {
- match self {
- #(#literals)|* => true,
- _ => false,
- }
+ matches!(self, #(#literals)|*)
}
pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
index f48d1ec66..6df29db47 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
@@ -471,6 +471,21 @@ pub mod future {
#[lang = "poll"]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
+
+ pub trait IntoFuture {
+ type Output;
+ type IntoFuture: Future<Output = Self::Output>;
+ #[lang = "into_future"]
+ fn into_future(self) -> Self::IntoFuture;
+ }
+
+ impl<F: Future> IntoFuture for F {
+ type Output = F::Output;
+ type IntoFuture = F;
+ fn into_future(self) -> F {
+ self
+ }
+ }
}
pub mod task {
pub enum Poll<T> {
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
index 9ee4415dc..fcc693a7d 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
@@ -14,7 +14,7 @@ tracing = "0.1.35"
jod-thread = "0.1.2"
walkdir = "2.3.2"
crossbeam-channel = "0.5.5"
-notify = "=5.0.0-pre.15"
+notify = "=5.0.0-pre.16"
vfs = { path = "../vfs", version = "0.0.0" }
paths = { path = "../paths", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
index 4d33a9afb..c95304e55 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
@@ -12,7 +12,7 @@
use std::fs;
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
-use notify::{RecommendedWatcher, RecursiveMode, Watcher};
+use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use paths::{AbsPath, AbsPathBuf};
use vfs::loader;
use walkdir::WalkDir;
@@ -40,12 +40,15 @@ impl loader::Handle for NotifyHandle {
.expect("failed to spawn thread");
NotifyHandle { sender, _thread: thread }
}
+
fn set_config(&mut self, config: loader::Config) {
self.sender.send(Message::Config(config)).unwrap();
}
+
fn invalidate(&mut self, path: AbsPathBuf) {
self.sender.send(Message::Invalidate(path)).unwrap();
}
+
fn load_sync(&mut self, path: &AbsPath) -> Option<Vec<u8>> {
read(path)
}
@@ -70,6 +73,7 @@ impl NotifyActor {
fn new(sender: loader::Sender) -> NotifyActor {
NotifyActor { sender, watched_entries: Vec::new(), watcher: None }
}
+
fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
let watcher_receiver = self.watcher.as_ref().map(|(_, receiver)| receiver);
select! {
@@ -77,18 +81,22 @@ impl NotifyActor {
recv(watcher_receiver.unwrap_or(&never())) -> it => Some(Event::NotifyEvent(it.unwrap())),
}
}
+
fn run(mut self, inbox: Receiver<Message>) {
while let Some(event) = self.next_event(&inbox) {
- tracing::debug!("vfs-notify event: {:?}", event);
+ tracing::debug!(?event, "vfs-notify event");
match event {
Event::Message(msg) => match msg {
Message::Config(config) => {
self.watcher = None;
if !config.watch.is_empty() {
let (watcher_sender, watcher_receiver) = unbounded();
- let watcher = log_notify_error(RecommendedWatcher::new(move |event| {
- watcher_sender.send(event).unwrap();
- }));
+ let watcher = log_notify_error(RecommendedWatcher::new(
+ move |event| {
+ watcher_sender.send(event).unwrap();
+ },
+ Config::default(),
+ ));
self.watcher = watcher.map(|it| (it, watcher_receiver));
}
diff --git a/src/tools/rust-analyzer/crates/vfs/Cargo.toml b/src/tools/rust-analyzer/crates/vfs/Cargo.toml
index c63773487..d7549a284 100644
--- a/src/tools/rust-analyzer/crates/vfs/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs/Cargo.toml
@@ -12,6 +12,7 @@ doctest = false
[dependencies]
rustc-hash = "1.1.0"
fst = "0.4.7"
+indexmap = "1.9.1"
paths = { path = "../paths", version = "0.0.0" }
-indexmap = "1.9.1"
+stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/vfs/src/file_set.rs b/src/tools/rust-analyzer/crates/vfs/src/file_set.rs
index 6a89263e5..e0ef737b3 100644
--- a/src/tools/rust-analyzer/crates/vfs/src/file_set.rs
+++ b/src/tools/rust-analyzer/crates/vfs/src/file_set.rs
@@ -6,6 +6,7 @@ use std::fmt;
use fst::{IntoStreamer, Streamer};
use rustc_hash::FxHashMap;
+use stdx::hash::NoHashHashMap;
use crate::{AnchoredPath, FileId, Vfs, VfsPath};
@@ -13,7 +14,7 @@ use crate::{AnchoredPath, FileId, Vfs, VfsPath};
#[derive(Default, Clone, Eq, PartialEq)]
pub struct FileSet {
files: FxHashMap<VfsPath, FileId>,
- paths: FxHashMap<FileId, VfsPath>,
+ paths: NoHashHashMap<FileId, VfsPath>,
}
impl FileSet {
diff --git a/src/tools/rust-analyzer/crates/vfs/src/lib.rs b/src/tools/rust-analyzer/crates/vfs/src/lib.rs
index 10fae41d0..afc9a0fa6 100644
--- a/src/tools/rust-analyzer/crates/vfs/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/vfs/src/lib.rs
@@ -59,12 +59,19 @@ pub use paths::{AbsPath, AbsPathBuf};
/// Handle to a file in [`Vfs`]
///
/// Most functions in rust-analyzer use this when they need to refer to a file.
-#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
+#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub struct FileId(pub u32);
+impl stdx::hash::NoHashHashable for FileId {}
+impl std::hash::Hash for FileId {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.0.hash(state);
+ }
+}
+
/// Storage for all files read by rust-analyzer.
///
-/// For more informations see the [crate-level](crate) documentation.
+/// For more information see the [crate-level](crate) documentation.
#[derive(Default)]
pub struct Vfs {
interner: PathInterner,
diff --git a/src/tools/rust-analyzer/docs/dev/README.md b/src/tools/rust-analyzer/docs/dev/README.md
index 76bbd1e91..c7f152acc 100644
--- a/src/tools/rust-analyzer/docs/dev/README.md
+++ b/src/tools/rust-analyzer/docs/dev/README.md
@@ -82,7 +82,7 @@ There's **"Run Extension (Debug Build)"** launch configuration for this in VS Co
In general, I use one of the following workflows for fixing bugs and implementing features:
If the problem concerns only internal parts of rust-analyzer (i.e. I don't need to touch the `rust-analyzer` crate or TypeScript code), there is a unit-test for it.
-So, I use **Rust Analyzer: Run** action in VS Code to run this single test, and then just do printf-driven development/debugging.
+So, I use **rust-analyzer: Run** action in VS Code to run this single test, and then just do printf-driven development/debugging.
As a sanity check after I'm done, I use `cargo xtask install --server` and **Reload Window** action in VS Code to verify that the thing works as I expect.
If the problem concerns only the VS Code extension, I use **Run Installed Extension** launch configuration from `launch.json`.
@@ -152,11 +152,11 @@ To log all communication between the server and the client, there are two choice
There are also several VS Code commands which might be of interest:
-* `Rust Analyzer: Status` shows some memory-usage statistics.
+* `rust-analyzer: Status` shows some memory-usage statistics.
-* `Rust Analyzer: Syntax Tree` shows syntax tree of the current file/selection.
+* `rust-analyzer: Syntax Tree` shows syntax tree of the current file/selection.
-* `Rust Analyzer: View Hir` shows the HIR expressions within the function containing the cursor.
+* `rust-analyzer: View Hir` shows the HIR expressions within the function containing the cursor.
You can hover over syntax nodes in the opened text file to see the appropriate
rust code that it refers to and the rust editor will also highlight the proper
diff --git a/src/tools/rust-analyzer/docs/dev/architecture.md b/src/tools/rust-analyzer/docs/dev/architecture.md
index ea4035baf..c173a239f 100644
--- a/src/tools/rust-analyzer/docs/dev/architecture.md
+++ b/src/tools/rust-analyzer/docs/dev/architecture.md
@@ -371,7 +371,7 @@ That is, rust-analyzer requires unwinding.
### Testing
-Rust Analyzer has three interesting [system boundaries](https://www.tedinski.com/2018/04/10/making-tests-a-positive-influence-on-design.html) to concentrate tests on.
+rust-analyzer has three interesting [system boundaries](https://www.tedinski.com/2018/04/10/making-tests-a-positive-influence-on-design.html) to concentrate tests on.
The outermost boundary is the `rust-analyzer` crate, which defines an LSP interface in terms of stdio.
We do integration testing of this component, by feeding it with a stream of LSP requests and checking responses.
@@ -485,7 +485,7 @@ Mind the code--architecture gap: at the moment, we are using fewer feature flags
### Serialization
In Rust, it is easy (often too easy) to add serialization to any type by adding `#[derive(Serialize)]`.
-This easiness is misleading -- serializable types impose significant backwards compatability constraints.
+This easiness is misleading -- serializable types impose significant backwards compatibility constraints.
If a type is serializable, then it is a part of some IPC boundary.
You often don't control the other side of this boundary, so changing serializable types is hard.
diff --git a/src/tools/rust-analyzer/docs/dev/guide.md b/src/tools/rust-analyzer/docs/dev/guide.md
index 47ae3f3e6..808eb5d10 100644
--- a/src/tools/rust-analyzer/docs/dev/guide.md
+++ b/src/tools/rust-analyzer/docs/dev/guide.md
@@ -63,7 +63,7 @@ Next, let's talk about what the inputs to the `Analysis` are, precisely.
## Inputs
-Rust Analyzer never does any I/O itself, all inputs get passed explicitly via
+rust-analyzer never does any I/O itself, all inputs get passed explicitly via
the `AnalysisHost::apply_change` method, which accepts a single argument, a
`Change`. [`Change`] is a builder for a single change
"transaction", so it suffices to study its methods to understand all of the
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
index 5040643d3..6d2c7d7b0 100644
--- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
+++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp_ext.rs hash: 2a188defec26cc7c
+lsp_ext.rs hash: 7b710095d773b978
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue:
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index b0f2f1614..72b925726 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -118,6 +118,10 @@ If you're changing this because you're using some tool wrapping
Cargo, you might also want to change
`#rust-analyzer.cargo.buildScripts.overrideCommand#`.
+If there are multiple linked projects, this command is invoked for
+each of them, with the working directory being the project root
+(i.e., the folder containing the `Cargo.toml`).
+
An example command would be:
```bash
@@ -318,6 +322,12 @@ Whether to show `Run` action. Only applies when
--
Whether to show documentation on hover.
--
+[[rust-analyzer.hover.documentation.keywords.enable]]rust-analyzer.hover.documentation.keywords.enable (default: `true`)::
++
+--
+Whether to show keyword hover popups. Only applies when
+`#rust-analyzer.hover.documentation.enable#` is set.
+--
[[rust-analyzer.hover.links.enable]]rust-analyzer.hover.links.enable (default: `true`)::
+
--
@@ -577,6 +587,52 @@ Enables the use of rustfmt's unstable range formatting command for the
`textDocument/rangeFormatting` request. The rustfmt option is unstable and only
available on a nightly build.
--
+[[rust-analyzer.semanticHighlighting.doc.comment.inject.enable]]rust-analyzer.semanticHighlighting.doc.comment.inject.enable (default: `true`)::
++
+--
+Inject additional highlighting into doc comments.
+
+When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
+doc links.
+--
+[[rust-analyzer.semanticHighlighting.operator.enable]]rust-analyzer.semanticHighlighting.operator.enable (default: `true`)::
++
+--
+Use semantic tokens for operators.
+
+When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
+they are tagged with modifiers.
+--
+[[rust-analyzer.semanticHighlighting.operator.specialization.enable]]rust-analyzer.semanticHighlighting.operator.specialization.enable (default: `false`)::
++
+--
+Use specialized semantic tokens for operators.
+
+When enabled, rust-analyzer will emit special token types for operator tokens instead
+of the generic `operator` token type.
+--
+[[rust-analyzer.semanticHighlighting.punctuation.enable]]rust-analyzer.semanticHighlighting.punctuation.enable (default: `false`)::
++
+--
+Use semantic tokens for punctuations.
+
+When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when
+they are tagged with modifiers or have a special role.
+--
+[[rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang]]rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang (default: `false`)::
++
+--
+When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro
+calls.
+--
+[[rust-analyzer.semanticHighlighting.punctuation.specialization.enable]]rust-analyzer.semanticHighlighting.punctuation.specialization.enable (default: `false`)::
++
+--
+Use specialized semantic tokens for punctuations.
+
+When enabled, rust-analyzer will emit special token types for punctuation tokens instead
+of the generic `punctuation` token type.
+--
[[rust-analyzer.semanticHighlighting.strings.enable]]rust-analyzer.semanticHighlighting.strings.enable (default: `true`)::
+
--
diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc
index 999a6437a..9bd3b6a69 100644
--- a/src/tools/rust-analyzer/docs/user/manual.adoc
+++ b/src/tools/rust-analyzer/docs/user/manual.adoc
@@ -479,7 +479,7 @@ You can follow instructions for installing <<rust-analyzer-language-server-binar
== Troubleshooting
Start with looking at the rust-analyzer version.
-Try **Rust Analyzer: Show RA Version** in VS Code (using **Command Palette** feature typically activated by Ctrl+Shift+P) or `rust-analyzer --version` in the command line.
+Try **rust-analyzer: Show RA Version** in VS Code (using **Command Palette** feature typically activated by Ctrl+Shift+P) or `rust-analyzer --version` in the command line.
If the date is more than a week ago, it's better to update rust-analyzer version.
The next thing to check would be panic messages in rust-analyzer's log.
@@ -492,7 +492,7 @@ To fully capture LSP messages between the editor and the server, set `"rust-anal
The root cause for many "`nothing works`" problems is that rust-analyzer fails to understand the project structure.
To debug that, first note the `rust-analyzer` section in the status bar.
If it has an error icon and red, that's the problem (hover will have somewhat helpful error message).
-**Rust Analyzer: Status** prints dependency information for the current file.
+**rust-analyzer: Status** prints dependency information for the current file.
Finally, `RA_LOG=project_model=debug` enables verbose logs during project loading.
If rust-analyzer outright crashes, try running `rust-analyzer analysis-stats /path/to/project/directory/` on the command line.
@@ -861,3 +861,14 @@ For example, if you want to run https://crates.io/crates/cargo-watch[`cargo watc
"isBackground": true
}
```
+
+==== Live Share
+
+VS Code Live Share has partial support for rust-analyzer.
+
+Live Share _requires_ the official Microsoft build of VS Code, OSS builds will not work correctly.
+
+The host's rust-analyzer instance will be shared with all guests joining the session.
+The guests do not have to have the rust-analyzer extension installed for this to work.
+
+If you are joining a Live Share session and _do_ have rust-analyzer installed locally, commands from the command palette will not work correctly since they will attempt to communicate with the local server.
diff --git a/src/tools/rust-analyzer/lib/la-arena/src/lib.rs b/src/tools/rust-analyzer/lib/la-arena/src/lib.rs
index dadee43b1..ccaaf3991 100644
--- a/src/tools/rust-analyzer/lib/la-arena/src/lib.rs
+++ b/src/tools/rust-analyzer/lib/la-arena/src/lib.rs
@@ -6,13 +6,12 @@
use std::{
fmt,
hash::{Hash, Hasher},
- iter::FromIterator,
marker::PhantomData,
ops::{Index, IndexMut, Range, RangeInclusive},
};
mod map;
-pub use map::ArenaMap;
+pub use map::{ArenaMap, Entry, OccupiedEntry, VacantEntry};
/// The raw index of a value in an arena.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -208,6 +207,16 @@ impl<T> Arena<T> {
Arena { data: Vec::new() }
}
+ /// Create a new empty arena with specific capacity.
+ ///
+ /// ```
+ /// let arena: la_arena::Arena<i32> = la_arena::Arena::with_capacity(42);
+ /// assert!(arena.is_empty());
+ /// ```
+ pub fn with_capacity(capacity: usize) -> Arena<T> {
+ Arena { data: Vec::with_capacity(capacity) }
+ }
+
/// Empties the arena, removing all contained values.
///
/// ```
@@ -313,6 +322,43 @@ impl<T> Arena<T> {
.map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
}
+ /// Returns an iterator over the arena’s values.
+ ///
+ /// ```
+ /// let mut arena = la_arena::Arena::new();
+ /// let idx1 = arena.alloc(20);
+ /// let idx2 = arena.alloc(40);
+ /// let idx3 = arena.alloc(60);
+ ///
+ /// let mut iterator = arena.values();
+ /// assert_eq!(iterator.next(), Some(&20));
+ /// assert_eq!(iterator.next(), Some(&40));
+ /// assert_eq!(iterator.next(), Some(&60));
+ /// ```
+ pub fn values(&mut self) -> impl Iterator<Item = &T> + ExactSizeIterator + DoubleEndedIterator {
+ self.data.iter()
+ }
+
+ /// Returns an iterator over the arena’s mutable values.
+ ///
+ /// ```
+ /// let mut arena = la_arena::Arena::new();
+ /// let idx1 = arena.alloc(20);
+ ///
+ /// assert_eq!(arena[idx1], 20);
+ ///
+ /// let mut iterator = arena.values_mut();
+ /// *iterator.next().unwrap() = 10;
+ /// drop(iterator);
+ ///
+ /// assert_eq!(arena[idx1], 10);
+ /// ```
+ pub fn values_mut(
+ &mut self,
+ ) -> impl Iterator<Item = &mut T> + ExactSizeIterator + DoubleEndedIterator {
+ self.data.iter_mut()
+ }
+
/// Reallocates the arena to make it take up as little space as possible.
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
diff --git a/src/tools/rust-analyzer/lib/la-arena/src/map.rs b/src/tools/rust-analyzer/lib/la-arena/src/map.rs
index d27f086d3..5f347e274 100644
--- a/src/tools/rust-analyzer/lib/la-arena/src/map.rs
+++ b/src/tools/rust-analyzer/lib/la-arena/src/map.rs
@@ -11,12 +11,52 @@ pub struct ArenaMap<IDX, V> {
}
impl<T, V> ArenaMap<Idx<T>, V> {
+ /// Creates a new empty map.
+ pub const fn new() -> Self {
+ Self { v: Vec::new(), _ty: PhantomData }
+ }
+
+ /// Create a new empty map with specific capacity.
+ pub fn with_capacity(capacity: usize) -> Self {
+ Self { v: Vec::with_capacity(capacity), _ty: PhantomData }
+ }
+
+ /// Reserves capacity for at least additional more elements to be inserted in the map.
+ pub fn reserve(&mut self, additional: usize) {
+ self.v.reserve(additional);
+ }
+
+ /// Clears the map, removing all elements.
+ pub fn clear(&mut self) {
+ self.v.clear();
+ }
+
+ /// Shrinks the capacity of the map as much as possible.
+ pub fn shrink_to_fit(&mut self) {
+ let min_len = self.v.iter().rposition(|slot| slot.is_some()).map_or(0, |i| i + 1);
+ self.v.truncate(min_len);
+ self.v.shrink_to_fit();
+ }
+
+ /// Returns whether the map contains a value for the specified index.
+ pub fn contains_idx(&self, idx: Idx<T>) -> bool {
+ matches!(self.v.get(Self::to_idx(idx)), Some(Some(_)))
+ }
+
+ /// Removes an index from the map, returning the value at the index if the index was previously in the map.
+ pub fn remove(&mut self, idx: Idx<T>) -> Option<V> {
+ self.v.get_mut(Self::to_idx(idx))?.take()
+ }
+
/// Inserts a value associated with a given arena index into the map.
- pub fn insert(&mut self, idx: Idx<T>, t: V) {
+ ///
+ /// If the map did not have this index present, None is returned.
+ /// Otherwise, the value is updated, and the old value is returned.
+ pub fn insert(&mut self, idx: Idx<T>, t: V) -> Option<V> {
let idx = Self::to_idx(idx);
self.v.resize_with((idx + 1).max(self.v.len()), || None);
- self.v[idx] = Some(t);
+ self.v[idx].replace(t)
}
/// Returns a reference to the value associated with the provided index
@@ -46,6 +86,16 @@ impl<T, V> ArenaMap<Idx<T>, V> {
self.v.iter().enumerate().filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?)))
}
+ /// Gets the given key's corresponding entry in the map for in-place manipulation.
+ pub fn entry(&mut self, idx: Idx<T>) -> Entry<'_, Idx<T>, V> {
+ let idx = Self::to_idx(idx);
+ self.v.resize_with((idx + 1).max(self.v.len()), || None);
+ match &mut self.v[idx] {
+ slot @ Some(_) => Entry::Occupied(OccupiedEntry { slot, _ty: PhantomData }),
+ slot @ None => Entry::Vacant(VacantEntry { slot, _ty: PhantomData }),
+ }
+ }
+
fn to_idx(idx: Idx<T>) -> usize {
u32::from(idx.into_raw()) as usize
}
@@ -70,6 +120,119 @@ impl<T, V> std::ops::IndexMut<Idx<V>> for ArenaMap<Idx<V>, T> {
impl<T, V> Default for ArenaMap<Idx<V>, T> {
fn default() -> Self {
- ArenaMap { v: Vec::new(), _ty: PhantomData }
+ Self::new()
+ }
+}
+
+impl<T, V> Extend<(Idx<V>, T)> for ArenaMap<Idx<V>, T> {
+ fn extend<I: IntoIterator<Item = (Idx<V>, T)>>(&mut self, iter: I) {
+ iter.into_iter().for_each(move |(k, v)| {
+ self.insert(k, v);
+ });
+ }
+}
+
+impl<T, V> FromIterator<(Idx<V>, T)> for ArenaMap<Idx<V>, T> {
+ fn from_iter<I: IntoIterator<Item = (Idx<V>, T)>>(iter: I) -> Self {
+ let mut this = Self::new();
+ this.extend(iter);
+ this
+ }
+}
+
+/// A view into a single entry in a map, which may either be vacant or occupied.
+///
+/// This `enum` is constructed from the [`entry`] method on [`ArenaMap`].
+///
+/// [`entry`]: ArenaMap::entry
+pub enum Entry<'a, IDX, V> {
+ /// A vacant entry.
+ Vacant(VacantEntry<'a, IDX, V>),
+ /// An occupied entry.
+ Occupied(OccupiedEntry<'a, IDX, V>),
+}
+
+impl<'a, IDX, V> Entry<'a, IDX, V> {
+ /// Ensures a value is in the entry by inserting the default if empty, and returns a mutable reference to
+ /// the value in the entry.
+ pub fn or_insert(self, default: V) -> &'a mut V {
+ match self {
+ Self::Vacant(ent) => ent.insert(default),
+ Self::Occupied(ent) => ent.into_mut(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the result of the default function if empty, and returns
+ /// a mutable reference to the value in the entry.
+ pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
+ match self {
+ Self::Vacant(ent) => ent.insert(default()),
+ Self::Occupied(ent) => ent.into_mut(),
+ }
+ }
+
+ /// Provides in-place mutable access to an occupied entry before any potential inserts into the map.
+ pub fn and_modify<F: FnOnce(&mut V)>(mut self, f: F) -> Self {
+ if let Self::Occupied(ent) = &mut self {
+ f(ent.get_mut());
+ }
+ self
+ }
+}
+
+impl<'a, IDX, V> Entry<'a, IDX, V>
+where
+ V: Default,
+{
+ /// Ensures a value is in the entry by inserting the default value if empty, and returns a mutable reference
+ /// to the value in the entry.
+ pub fn or_default(self) -> &'a mut V {
+ self.or_insert_with(Default::default)
+ }
+}
+
+/// A view into an vacant entry in a [`ArenaMap`]. It is part of the [`Entry`] enum.
+pub struct VacantEntry<'a, IDX, V> {
+ slot: &'a mut Option<V>,
+ _ty: PhantomData<IDX>,
+}
+
+impl<'a, IDX, V> VacantEntry<'a, IDX, V> {
+ /// Sets the value of the entry with the `VacantEntry`’s key, and returns a mutable reference to it.
+ pub fn insert(self, value: V) -> &'a mut V {
+ self.slot.insert(value)
+ }
+}
+
+/// A view into an occupied entry in a [`ArenaMap`]. It is part of the [`Entry`] enum.
+pub struct OccupiedEntry<'a, IDX, V> {
+ slot: &'a mut Option<V>,
+ _ty: PhantomData<IDX>,
+}
+
+impl<'a, IDX, V> OccupiedEntry<'a, IDX, V> {
+ /// Gets a reference to the value in the entry.
+ pub fn get(&self) -> &V {
+ self.slot.as_ref().expect("Occupied")
+ }
+
+ /// Gets a mutable reference to the value in the entry.
+ pub fn get_mut(&mut self) -> &mut V {
+ self.slot.as_mut().expect("Occupied")
+ }
+
+ /// Converts the entry into a mutable reference to its value.
+ pub fn into_mut(self) -> &'a mut V {
+ self.slot.as_mut().expect("Occupied")
+ }
+
+ /// Sets the value of the entry with the `OccupiedEntry`’s key, and returns the entry’s old value.
+ pub fn insert(&mut self, value: V) -> V {
+ self.slot.replace(value).expect("Occupied")
+ }
+
+ /// Takes the value of the entry out of the map, and returns it.
+ pub fn remove(self) -> V {
+ self.slot.take().expect("Occupied")
}
}
diff --git a/src/tools/rust-analyzer/lib/lsp-server/src/socket.rs b/src/tools/rust-analyzer/lib/lsp-server/src/socket.rs
index 4a59c4c0f..36d728456 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/src/socket.rs
+++ b/src/tools/rust-analyzer/lib/lsp-server/src/socket.rs
@@ -15,7 +15,7 @@ pub(crate) fn socket_transport(
stream: TcpStream,
) -> (Sender<Message>, Receiver<Message>, IoThreads) {
let (reader_receiver, reader) = make_reader(stream.try_clone().unwrap());
- let (writer_sender, writer) = make_write(stream.try_clone().unwrap());
+ let (writer_sender, writer) = make_write(stream);
let io_threads = make_io_threads(reader, writer);
(writer_sender, reader_receiver, io_threads)
}
diff --git a/src/tools/rust-analyzer/xtask/src/release.rs b/src/tools/rust-analyzer/xtask/src/release.rs
index 17ada5156..eda8fceef 100644
--- a/src/tools/rust-analyzer/xtask/src/release.rs
+++ b/src/tools/rust-analyzer/xtask/src/release.rs
@@ -81,7 +81,7 @@ impl flags::Promote {
let date = date_iso(sh)?;
let branch = format!("rust-analyzer-{date}");
cmd!(sh, "git switch -c {branch}").run()?;
- cmd!(sh, "git subtree pull -P src/tools/rust-analyzer rust-analyzer master").run()?;
+ cmd!(sh, "git subtree pull -m ':arrow_up: rust-analyzer' -P src/tools/rust-analyzer rust-analyzer release").run()?;
if !self.dry_run {
cmd!(sh, "git push -u origin {branch}").run()?;
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index b1d8b8649..80bb3b5d6 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -24,6 +24,7 @@ features = [
"errhandlingapi",
"evntrace",
"fibersapi",
+ "handleapi",
"in6addr",
"inaddr",
"ioapiset",
@@ -72,25 +73,14 @@ features = [
[dependencies]
bstr = { version = "0.2.17", features = ["default"] }
-byteorder = { version = "1", features = ['default', 'std'] }
clap = { version = "3.1.1", features = ["derive", "clap_derive"]}
curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
-crossbeam-utils = { version = "0.8.0", features = ["nightly"] }
-libc = { version = "0.2.79", features = ["align"] }
# Ensure default features of libz-sys, which are disabled in some scenarios.
libz-sys = { version = "1.1.2" }
-# The only user of memchr's deprecated `use_std` feature is `combine`, so this can be
-# removed if/when https://github.com/Marwes/combine/pull/348 is merged and released.
-memchr = { version = "2.5", features = ["std", "use_std"] }
# Ensure default features of regex, which are disabled in some scenarios.
regex = { version = "1.5.6" }
-proc-macro2 = { version = "1", features = ["default"] }
-quote = { version = "1", features = ["default"] }
-rand_core_0_5 = { package = "rand_core", version = "0.5.1", features = ["getrandom", "alloc", "std"] }
-serde = { version = "1.0.82", features = ['derive'] }
serde_json = { version = "1.0.31", features = ["raw_value", "unbounded_depth"] }
-smallvec = { version = "1.8.1", features = ['union', 'may_dangle'] }
-syn = { version = "1", features = ['fold', 'full', 'extra-traits', 'visit', 'visit-mut'] }
+syn = { version = "1", features = ['full', 'visit'] }
url = { version = "2.0", features = ['serde'] }
[target.'cfg(not(windows))'.dependencies]
diff --git a/src/tools/rustc-workspace-hack/README.md b/src/tools/rustc-workspace-hack/README.md
index 4a5286fae..3c6147035 100644
--- a/src/tools/rustc-workspace-hack/README.md
+++ b/src/tools/rustc-workspace-hack/README.md
@@ -2,18 +2,18 @@
This crate is a bit of a hack to make workspaces in rustc work a bit better.
The rationale for this existence is a bit subtle, but the general idea is that
-we want commands like `./x.py build src/tools/{rls,clippy,cargo}` to share as
+we want commands like `./x.py build src/tools/{clippy,cargo}` to share as
many dependencies as possible.
Each invocation is a different invocation of Cargo, however. Each time Cargo
runs a build it will re-resolve the dependency graph, notably selecting
different features sometimes for each build.
-For example, let's say there's a very deep dependency like `num-traits` in each
-of these builds. For Cargo the `num-traits`'s `default` feature is turned off.
-In RLS, however, the `default` feature is turned. This means that building Cargo
-and then the RLS will actually build Cargo twice (as a transitive dependency
-changed). This is bad!
+For example, let's say there's a very deep dependency like `winapi` in each of
+these builds. For Cargo, `winapi` has 33 features enabled. In Clippy, however,
+`winapi` has 22 features enabled. This means that building Cargo and then the
+Clippy will actually build winapi twice, which in turn will build duplicates
+of everything that depends on `winapi`. This is bad!
The goal of this crate is to solve this problem and ensure that the resolved
dependency graph for all of these tools is the same in the various subsets of
diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js
index a51218503..70d5f9447 100644
--- a/src/tools/rustdoc-gui/tester.js
+++ b/src/tools/rustdoc-gui/tester.js
@@ -201,6 +201,19 @@ async function main(argv) {
process.setMaxListeners(opts["jobs"] + 1);
}
+ // We catch this "event" to display a nicer message in case of unexpected exit (because of a
+ // missing `--no-sandbox`).
+ const exitHandling = (code) => {
+ if (!opts["no_sandbox"]) {
+ console.log("");
+ console.log(
+ "`browser-ui-test` crashed unexpectedly. Please try again with adding `--test-args \
+--no-sandbox` at the end. For example: `x.py test src/test/rustdoc-gui --test-args --no-sandbox`");
+ console.log("");
+ }
+ };
+ process.on('exit', exitHandling);
+
const tests_queue = [];
let results = {
successful: [],
@@ -247,6 +260,9 @@ async function main(argv) {
}
status_bar.finish();
+ // We don't need this listener anymore.
+ process.removeListener("exit", exitHandling);
+
if (debug) {
results.successful.sort(by_filename);
results.successful.forEach(r => {
diff --git a/src/tools/rustfmt/Processes.md b/src/tools/rustfmt/Processes.md
index 9d86d52b1..f763b5714 100644
--- a/src/tools/rustfmt/Processes.md
+++ b/src/tools/rustfmt/Processes.md
@@ -51,7 +51,3 @@ git tag -s v1.2.3 -m "Release 1.2.3"
`cargo publish`
## 5. Create a PR to rust-lang/rust to update the rustfmt submodule
-
-Note that if you are updating `rustc-ap-*` crates, then you need to update **every** submodules in the rust-lang/rust repository that depend on the crates to use the same version of those.
-
-As of 2019/05, there are two such crates: `rls` and `racer` (`racer` depends on `rustc-ap-syntax` and `rls` depends on `racer`, and `rls` is one of submodules of the rust-lang/rust repository).
diff --git a/src/tools/rustfmt/README.md b/src/tools/rustfmt/README.md
index b3a968f0c..0f9652aec 100644
--- a/src/tools/rustfmt/README.md
+++ b/src/tools/rustfmt/README.md
@@ -135,7 +135,7 @@ completed without error (whether or not changes were made).
* [Emacs](https://github.com/rust-lang/rust-mode)
* [Sublime Text 3](https://packagecontrol.io/packages/RustFmt)
* [Atom](atom.md)
-* Visual Studio Code using [vscode-rust](https://github.com/editor-rs/vscode-rust), [vsc-rustfmt](https://github.com/Connorcpu/vsc-rustfmt) or [rls_vscode](https://github.com/jonathandturner/rls_vscode) through RLS.
+* [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
* [IntelliJ or CLion](intellij.md)
diff --git a/src/tools/rustfmt/atom.md b/src/tools/rustfmt/atom.md
index f77ac1490..c7e3a991a 100644
--- a/src/tools/rustfmt/atom.md
+++ b/src/tools/rustfmt/atom.md
@@ -1,8 +1,8 @@
# Running Rustfmt from Atom
-## RLS
+## rust-analyzer
-Rustfmt is included with the Rust Language Server, itself provided by [ide-rust](https://atom.io/packages/ide-rust).
+Rustfmt can be utilized from [rust-analyzer](https://rust-analyzer.github.io/) which is provided by [ide-rust](https://atom.io/packages/ide-rust).
`apm install ide-rust`
diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs
index 41ba9a847..f5c1ee5fd 100644
--- a/src/tools/rustfmt/src/attr.rs
+++ b/src/tools/rustfmt/src/attr.rs
@@ -49,10 +49,7 @@ pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span {
}
/// Returns attributes that are within `outer_span`.
-pub(crate) fn filter_inline_attrs(
- attrs: &[ast::Attribute],
- outer_span: Span,
-) -> Vec<ast::Attribute> {
+pub(crate) fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> ast::AttrVec {
attrs
.iter()
.filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi())
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index a7b73ba78..3105882e2 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -79,7 +79,7 @@ pub(crate) fn format_expr(
if let Some(expr_rw) = rewrite_literal(context, l, shape) {
Some(expr_rw)
} else {
- if let LitKind::StrRaw(_) = l.token.kind {
+ if let LitKind::StrRaw(_) = l.token_lit.kind {
Some(context.snippet(l.span).trim().into())
} else {
None
@@ -1226,7 +1226,7 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) ->
fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -> Option<String> {
let span = lit.span;
- let symbol = lit.token.symbol.as_str();
+ let symbol = lit.token_lit.symbol.as_str();
if let Some(symbol_stripped) = symbol.strip_prefix("0x") {
let hex_lit = match context.config.hex_literal_case() {
@@ -1239,7 +1239,9 @@ fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -
format!(
"0x{}{}",
hex_lit,
- lit.token.suffix.map_or(String::new(), |s| s.to_string())
+ lit.token_lit
+ .suffix
+ .map_or(String::new(), |s| s.to_string())
),
context.config.max_width(),
shape,
diff --git a/src/tools/rustfmt/src/imports.rs b/src/tools/rustfmt/src/imports.rs
index 8d41c8815..b6530c692 100644
--- a/src/tools/rustfmt/src/imports.rs
+++ b/src/tools/rustfmt/src/imports.rs
@@ -116,7 +116,7 @@ pub(crate) struct UseTree {
// Additional fields for top level use items.
// Should we have another struct for top-level use items rather than reusing this?
visibility: Option<ast::Visibility>,
- attrs: Option<Vec<ast::Attribute>>,
+ attrs: Option<ast::AttrVec>,
}
impl PartialEq for UseTree {
@@ -417,7 +417,7 @@ impl UseTree {
list_item: Option<ListItem>,
visibility: Option<ast::Visibility>,
opt_lo: Option<BytePos>,
- attrs: Option<Vec<ast::Attribute>>,
+ attrs: Option<ast::AttrVec>,
) -> UseTree {
let span = if let Some(lo) = opt_lo {
mk_sp(lo, a.span.hi())
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index 81da72432..7a0d1736c 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -26,7 +26,7 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
pub(crate) struct Module<'a> {
ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
- inner_attr: Vec<ast::Attribute>,
+ inner_attr: ast::AttrVec,
pub(crate) span: Span,
}
@@ -35,7 +35,7 @@ impl<'a> Module<'a> {
mod_span: Span,
ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
- mod_attrs: Cow<'a, Vec<ast::Attribute>>,
+ mod_attrs: Cow<'a, ast::AttrVec>,
) -> Self {
let inner_attr = mod_attrs
.iter()
@@ -158,7 +158,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
module_item.item.span,
Some(Cow::Owned(sub_mod_kind.clone())),
Cow::Owned(vec![]),
- Cow::Owned(vec![]),
+ Cow::Owned(ast::AttrVec::new()),
),
)?;
}
@@ -185,7 +185,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
span,
Some(Cow::Owned(sub_mod_kind.clone())),
Cow::Owned(vec![]),
- Cow::Owned(vec![]),
+ Cow::Owned(ast::AttrVec::new()),
),
)?;
}
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index 268c72649..e0bd06551 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -109,7 +109,7 @@ impl<'a> Parser<'a> {
sess: &'a ParseSess,
path: &Path,
span: Span,
- ) -> Result<(Vec<ast::Attribute>, Vec<ptr::P<ast::Item>>, Span), ParserError> {
+ ) -> Result<(ast::AttrVec, Vec<ptr::P<ast::Item>>, Span), ParserError> {
let result = catch_unwind(AssertUnwindSafe(|| {
let mut parser = new_parser_from_file(sess.inner(), path, Some(span));
match parser.parse_mod(&TokenKind::Eof) {
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 23db54219..6efeee98f 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -3,6 +3,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use rustc_data_structures::sync::{Lrc, Send};
use rustc_errors::emitter::{Emitter, EmitterWriter};
+use rustc_errors::translation::Translate;
use rustc_errors::{ColorConfig, Diagnostic, Handler, Level as DiagnosticLevel};
use rustc_session::parse::ParseSess as RawParseSess;
use rustc_span::{
@@ -28,19 +29,24 @@ pub(crate) struct ParseSess {
/// Emitter which discards every error.
struct SilentEmitter;
-impl Emitter for SilentEmitter {
- fn source_map(&self) -> Option<&Lrc<SourceMap>> {
- None
- }
- fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+impl Translate for SilentEmitter {
fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
None
}
+
fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
panic!("silent emitter attempted to translate a diagnostic");
}
}
+impl Emitter for SilentEmitter {
+ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+ None
+ }
+
+ fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+}
+
fn silent_emitter() -> Box<dyn Emitter + Send> {
Box::new(SilentEmitter {})
}
@@ -62,10 +68,21 @@ impl SilentOnIgnoredFilesEmitter {
}
}
+impl Translate for SilentOnIgnoredFilesEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+ self.emitter.fluent_bundle()
+ }
+
+ fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+ self.emitter.fallback_fluent_bundle()
+ }
+}
+
impl Emitter for SilentOnIgnoredFilesEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}
+
fn emit_diagnostic(&mut self, db: &Diagnostic) {
if db.level() == DiagnosticLevel::Fatal {
return self.handle_non_ignoreable_error(db);
@@ -88,14 +105,6 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
}
self.handle_non_ignoreable_error(db);
}
-
- fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
- self.emitter.fluent_bundle()
- }
-
- fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
- self.emitter.fallback_fluent_bundle()
- }
}
fn default_handler(
@@ -340,19 +349,24 @@ mod tests {
num_emitted_errors: Lrc<AtomicU32>,
}
+ impl Translate for TestEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+ None
+ }
+
+ fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+ panic!("test emitter attempted to translate a diagnostic");
+ }
+ }
+
impl Emitter for TestEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}
+
fn emit_diagnostic(&mut self, _db: &Diagnostic) {
self.num_emitted_errors.fetch_add(1, Ordering::Release);
}
- fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
- None
- }
- fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
- panic!("test emitter attempted to translate a diagnostic");
- }
}
fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> Diagnostic {
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index 9b74b35f3..e2fe92b28 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -1,4 +1,6 @@
-use rustc_ast::ast::{self, BindingMode, Pat, PatField, PatKind, RangeEnd, RangeSyntax};
+use rustc_ast::ast::{
+ self, BindingAnnotation, ByRef, Pat, PatField, PatKind, RangeEnd, RangeSyntax,
+};
use rustc_ast::ptr;
use rustc_span::{BytePos, Span};
@@ -99,10 +101,10 @@ impl Rewrite for Pat {
write_list(&items, &fmt)
}
PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape),
- PatKind::Ident(binding_mode, ident, ref sub_pat) => {
- let (prefix, mutability) = match binding_mode {
- BindingMode::ByRef(mutability) => ("ref", mutability),
- BindingMode::ByValue(mutability) => ("", mutability),
+ PatKind::Ident(BindingAnnotation(by_ref, mutability), ident, ref sub_pat) => {
+ let prefix = match by_ref {
+ ByRef::Yes => "ref",
+ ByRef::No => "",
};
let mut_infix = format_mutability(mutability).trim();
let id_str = rewrite_ident(context, ident);
diff --git a/src/tools/rustfmt/src/skip.rs b/src/tools/rustfmt/src/skip.rs
index 0fdc097ef..032922d42 100644
--- a/src/tools/rustfmt/src/skip.rs
+++ b/src/tools/rustfmt/src/skip.rs
@@ -58,8 +58,8 @@ fn get_skip_names(kind: &str, attrs: &[ast::Attribute]) -> Vec<String> {
for attr in attrs {
// rustc_ast::ast::Path is implemented partialEq
// but it is designed for segments.len() == 1
- if let ast::AttrKind::Normal(attr_item, _) = &attr.kind {
- if pprust::path_to_string(&attr_item.path) != path {
+ if let ast::AttrKind::Normal(normal) = &attr.kind {
+ if pprust::path_to_string(&normal.item.path) != path {
continue;
}
}
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index 9a0e0752c..7bb745eeb 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -811,8 +811,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
);
} else {
match &attr.kind {
- ast::AttrKind::Normal(ref attribute_item, _)
- if self.is_unknown_rustfmt_attr(&attribute_item.path.segments) =>
+ ast::AttrKind::Normal(ref normal)
+ if self.is_unknown_rustfmt_attr(&normal.item.path.segments) =>
{
let file_name = self.parse_sess.span_to_filename(attr.span);
self.report.append(
diff --git a/src/tools/rustfmt/tests/source/issue-3217.rs b/src/tools/rustfmt/tests/source/issue-3217.rs
index 176c70200..e68ca2c59 100644
--- a/src/tools/rustfmt/tests/source/issue-3217.rs
+++ b/src/tools/rustfmt/tests/source/issue-3217.rs
@@ -1,5 +1,3 @@
-#![feature(label_break_value)]
-
fn main() {
let mut res = 0;
's_39: { if res == 0i32 { println!("Hello, world!"); } }
diff --git a/src/tools/rustfmt/tests/source/issue_4257.rs b/src/tools/rustfmt/tests/source/issue_4257.rs
index 2b887fadb..9482512ef 100644
--- a/src/tools/rustfmt/tests/source/issue_4257.rs
+++ b/src/tools/rustfmt/tests/source/issue_4257.rs
@@ -1,6 +1,3 @@
-#![feature(generic_associated_types)]
-#![allow(incomplete_features)]
-
trait Trait<T> {
type Type<'a> where T: 'a;
fn foo(x: &T) -> Self::Type<'_>;
diff --git a/src/tools/rustfmt/tests/source/issue_4911.rs b/src/tools/rustfmt/tests/source/issue_4911.rs
index 21ef6c6c4..c254db7b5 100644
--- a/src/tools/rustfmt/tests/source/issue_4911.rs
+++ b/src/tools/rustfmt/tests/source/issue_4911.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(min_type_alias_impl_trait)]
impl SomeTrait for SomeType {
diff --git a/src/tools/rustfmt/tests/source/issue_4943.rs b/src/tools/rustfmt/tests/source/issue_4943.rs
index 0793b7b4f..307d9a4a1 100644
--- a/src/tools/rustfmt/tests/source/issue_4943.rs
+++ b/src/tools/rustfmt/tests/source/issue_4943.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
impl SomeStruct {
fn process<T>(v: T) -> <Self as GAT>::R<T>
where Self: GAT<R<T> = T>
diff --git a/src/tools/rustfmt/tests/target/issue-3217.rs b/src/tools/rustfmt/tests/target/issue-3217.rs
index 5121320a0..403bf4c34 100644
--- a/src/tools/rustfmt/tests/target/issue-3217.rs
+++ b/src/tools/rustfmt/tests/target/issue-3217.rs
@@ -1,5 +1,3 @@
-#![feature(label_break_value)]
-
fn main() {
let mut res = 0;
's_39: {
diff --git a/src/tools/rustfmt/tests/target/issue_4257.rs b/src/tools/rustfmt/tests/target/issue_4257.rs
index 1ebaaf2b6..309a66c8d 100644
--- a/src/tools/rustfmt/tests/target/issue_4257.rs
+++ b/src/tools/rustfmt/tests/target/issue_4257.rs
@@ -1,6 +1,3 @@
-#![feature(generic_associated_types)]
-#![allow(incomplete_features)]
-
trait Trait<T> {
type Type<'a>
where
diff --git a/src/tools/rustfmt/tests/target/issue_4911.rs b/src/tools/rustfmt/tests/target/issue_4911.rs
index 890a62267..0f64aa7f7 100644
--- a/src/tools/rustfmt/tests/target/issue_4911.rs
+++ b/src/tools/rustfmt/tests/target/issue_4911.rs
@@ -1,4 +1,3 @@
-#![feature(generic_associated_types)]
#![feature(min_type_alias_impl_trait)]
impl SomeTrait for SomeType {
diff --git a/src/tools/rustfmt/tests/target/issue_4943.rs b/src/tools/rustfmt/tests/target/issue_4943.rs
index 318f7ebed..bc8f1a366 100644
--- a/src/tools/rustfmt/tests/target/issue_4943.rs
+++ b/src/tools/rustfmt/tests/target/issue_4943.rs
@@ -1,5 +1,3 @@
-#![feature(generic_associated_types)]
-
impl SomeStruct {
fn process<T>(v: T) -> <Self as GAT>::R<T>
where
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 96ab42b47..471d78a29 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -9,7 +9,6 @@ cargo_metadata = "0.14"
regex = "1"
lazy_static = "1"
walkdir = "2"
-crossbeam-utils = "0.8.0"
[[bin]]
name = "rust-tidy"
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index 9615c4db6..30903f56d 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -96,7 +96,9 @@ mod os_impl {
#[cfg(unix)]
pub fn check(path: &Path, bad: &mut bool) {
- const ALLOWED: &[&str] = &["configure"];
+ use std::ffi::OsStr;
+
+ const ALLOWED: &[&str] = &["configure", "x"];
crate::walk_no_read(
path,
@@ -117,9 +119,9 @@ mod os_impl {
},
&mut |entry| {
let file = entry.path();
- let filename = file.file_name().unwrap().to_string_lossy();
- let extensions = [".py", ".sh"];
- if extensions.iter().any(|e| filename.ends_with(e)) {
+ let extension = file.extension();
+ let scripts = ["py", "sh", "ps1"];
+ if scripts.into_iter().any(|e| extension == Some(OsStr::new(e))) {
return;
}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 333f85f6d..cbd8cfa01 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -31,8 +31,7 @@ const EXCEPTIONS: &[(&str, &str)] = &[
("mdbook", "MPL-2.0"), // mdbook
("openssl", "Apache-2.0"), // cargo, mdbook
("colored", "MPL-2.0"), // rustfmt
- ("ordslice", "Apache-2.0"), // rls
- ("ryu", "Apache-2.0 OR BSL-1.0"), // rls/cargo/... (because of serde)
+ ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
("bytesize", "Apache-2.0"), // cargo
("im-rc", "MPL-2.0+"), // cargo
("sized-chunks", "MPL-2.0+"), // cargo via im-rc
@@ -92,9 +91,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"autocfg",
"bitflags",
"block-buffer",
- "block-padding",
- "byte-tools",
- "byteorder",
"cc",
"cfg-if",
"chalk-derive",
@@ -119,7 +115,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"ena",
"env_logger",
"expect-test",
- "fake-simd",
"fallible-iterator", // dependency of `thorin`
"filetime",
"fixedbitset",
@@ -163,7 +158,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"object",
"odht",
"once_cell",
- "opaque-debug",
"parking_lot",
"parking_lot_core",
"pathdiff",
@@ -224,6 +218,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"time",
"tinystr",
"tinyvec",
+ "thin-vec",
"tracing",
"tracing-attributes",
"tracing-core",
@@ -247,6 +242,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"unicode-width",
"unicode-xid",
"vcpkg",
+ "valuable",
"version_check",
"wasi",
"winapi",
@@ -300,6 +296,12 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"winapi",
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
+ "windows-sys",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
];
const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[
diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs
index f0054a1c1..0a226443e 100644
--- a/src/tools/tidy/src/error_codes_check.rs
+++ b/src/tools/tidy/src/error_codes_check.rs
@@ -217,7 +217,7 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
println!("Checking which error codes lack tests...");
for path in paths {
- super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
+ super::walk(path, &mut super::filter_dirs, &mut |entry, contents| {
let file_name = entry.file_name();
let entry_path = entry.path();
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 2f22c081a..b306a527a 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -175,6 +175,35 @@ pub fn check(
tidy_error!(bad, "Found {} features without a gate test.", gate_untested.len());
}
+ let (version, channel) = get_version_and_channel(src_path);
+
+ let all_features_iter = features
+ .iter()
+ .map(|feat| (feat, "lang"))
+ .chain(lib_features.iter().map(|feat| (feat, "lib")));
+ for ((feature_name, feature), kind) in all_features_iter {
+ let since = if let Some(since) = feature.since { since } else { continue };
+ if since > version && since != Version::CurrentPlaceholder {
+ tidy_error!(
+ bad,
+ "The stabilization version {since} of {kind} feature `{feature_name}` is newer than the current {version}"
+ );
+ }
+ if channel == "nightly" && since == version {
+ tidy_error!(
+ bad,
+ "The stabilization version {since} of {kind} feature `{feature_name}` is written out but should be {}",
+ version::VERSION_PLACEHOLDER
+ );
+ }
+ if channel != "nightly" && since == Version::CurrentPlaceholder {
+ tidy_error!(
+ bad,
+ "The placeholder use of {kind} feature `{feature_name}` is not allowed on the {channel} channel",
+ );
+ }
+ }
+
if *bad {
return CollectedFeatures { lib: lib_features, lang: features };
}
@@ -195,6 +224,14 @@ pub fn check(
CollectedFeatures { lib: lib_features, lang: features }
}
+fn get_version_and_channel(src_path: &Path) -> (Version, String) {
+ let version_str = t!(std::fs::read_to_string(src_path.join("version")));
+ let version_str = version_str.trim();
+ let version = t!(std::str::FromStr::from_str(&version_str).map_err(|e| format!("{e:?}")));
+ let channel_str = t!(std::fs::read_to_string(src_path.join("ci").join("channel")));
+ (version, channel_str.trim().to_owned())
+}
+
fn format_features<'a>(
features: &'a Features,
family: &'a str,
diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs
index 620be2f98..0830c226c 100644
--- a/src/tools/tidy/src/features/version.rs
+++ b/src/tools/tidy/src/features/version.rs
@@ -5,14 +5,22 @@ use std::str::FromStr;
#[cfg(test)]
mod tests;
+pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Version {
- parts: [u32; 3],
+pub enum Version {
+ Explicit { parts: [u32; 3] },
+ CurrentPlaceholder,
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.pad(&format!("{}.{}.{}", self.parts[0], self.parts[1], self.parts[2]))
+ match self {
+ Version::Explicit { parts } => {
+ f.pad(&format!("{}.{}.{}", parts[0], parts[1], parts[2]))
+ }
+ Version::CurrentPlaceholder => f.pad(&format!("CURRENT")),
+ }
}
}
@@ -32,6 +40,9 @@ impl FromStr for Version {
type Err = ParseVersionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
+ if s == VERSION_PLACEHOLDER {
+ return Ok(Version::CurrentPlaceholder);
+ }
let mut iter = s.split('.').map(|part| Ok(part.parse()?));
let mut part = || iter.next().unwrap_or(Err(ParseVersionError::WrongNumberOfParts));
@@ -43,6 +54,6 @@ impl FromStr for Version {
return Err(ParseVersionError::WrongNumberOfParts);
}
- Ok(Self { parts })
+ Ok(Version::Explicit { parts })
}
}
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 09848462a..12d3bdcd7 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -3,12 +3,14 @@
//! This library contains the tidy lints and exposes it
//! to be used by tools.
-use std::fs::File;
-use std::io::Read;
-use walkdir::{DirEntry, WalkDir};
-
-use std::path::Path;
-
+use walk::{filter_dirs, walk, walk_many, walk_no_read};
+
+/// A helper macro to `unwrap` a result except also print out details like:
+///
+/// * The expression that failed
+/// * The error itself
+/// * (optionally) a path connected to the error (e.g. failure to open a file)
+#[macro_export]
macro_rules! t {
($e:expr, $p:expr) => {
match $e {
@@ -28,7 +30,8 @@ macro_rules! t {
macro_rules! tidy_error {
($bad:expr, $fmt:expr) => ({
*$bad = true;
- eprintln!("tidy error: {}", $fmt);
+ eprint!("tidy error: ");
+ eprintln!($fmt);
});
($bad:expr, $fmt:expr, $($arg:tt)*) => ({
*$bad = true;
@@ -52,59 +55,4 @@ pub mod target_specific_tests;
pub mod ui_tests;
pub mod unit_tests;
pub mod unstable_book;
-
-fn filter_dirs(path: &Path) -> bool {
- let skip = [
- "tidy-test-file",
- "compiler/rustc_codegen_cranelift",
- "compiler/rustc_codegen_gcc",
- "src/llvm-project",
- "library/backtrace",
- "library/portable-simd",
- "library/stdarch",
- "src/tools/cargo",
- "src/tools/clippy",
- "src/tools/miri",
- "src/tools/rls",
- "src/tools/rust-analyzer",
- "src/tools/rust-installer",
- "src/tools/rustfmt",
- "src/doc/book",
- // Filter RLS output directories
- "target/rls",
- ];
- skip.iter().any(|p| path.ends_with(p))
-}
-
-fn walk_many(
- paths: &[&Path],
- skip: &mut dyn FnMut(&Path) -> bool,
- f: &mut dyn FnMut(&DirEntry, &str),
-) {
- for path in paths {
- walk(path, skip, f);
- }
-}
-
-fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)) {
- let mut contents = String::new();
- walk_no_read(path, skip, &mut |entry| {
- contents.clear();
- if t!(File::open(entry.path()), entry.path()).read_to_string(&mut contents).is_err() {
- contents.clear();
- }
- f(&entry, &contents);
- });
-}
-
-fn walk_no_read(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry)) {
- let walker = WalkDir::new(path).into_iter().filter_entry(|e| !skip(e.path()));
- for entry in walker {
- if let Ok(entry) = entry {
- if entry.file_type().is_dir() {
- continue;
- }
- f(&entry);
- }
- }
-}
+pub mod walk;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index aa8d8b4f6..c1ce94f47 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -6,7 +6,6 @@
use tidy::*;
-use crossbeam_utils::thread::{scope, ScopedJoinHandle};
use std::collections::VecDeque;
use std::env;
use std::num::NonZeroUsize;
@@ -14,6 +13,7 @@ use std::path::PathBuf;
use std::process;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
+use std::thread::{scope, ScopedJoinHandle};
fn main() {
let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
@@ -44,7 +44,7 @@ fn main() {
handles.pop_front().unwrap().join().unwrap();
}
- let handle = s.spawn(|_| {
+ let handle = s.spawn(|| {
let mut flag = false;
$p::check($($args),* , &mut flag);
if (flag) {
@@ -102,8 +102,7 @@ fn main() {
r
};
check!(unstable_book, &src_path, collected);
- })
- .unwrap();
+ });
if bad.load(Ordering::Relaxed) {
eprintln!("some tidy checks failed");
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index c5414233f..4d86fe8be 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -59,6 +59,8 @@ const EXCEPTION_PATHS: &[&str] = &[
"library/std/src/sys_common", // Should only contain abstractions over platforms
"library/std/src/net/test.rs", // Utility helpers for tests
"library/std/src/panic.rs", // fuchsia-specific panic backtrace handling
+ "library/std/src/personality.rs",
+ "library/std/src/personality/",
];
pub fn check(path: &Path, bad: &mut bool) {
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 3cf44a2d7..dee58ff2f 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -125,16 +125,13 @@ fn should_ignore(line: &str) -> bool {
/// Returns `true` if `line` is allowed to be longer than the normal limit.
fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, line: &str) -> bool {
- if extension != "md" || is_error_code {
- if line_is_url(is_error_code, max_columns, line) || should_ignore(line) {
- return true;
- }
- } else if extension == "md" {
+ match extension {
+ // fluent files are allowed to be any length
+ "ftl" => true,
// non-error code markdown is allowed to be any length
- return true;
+ "md" if !is_error_code => true,
+ _ => line_is_url(is_error_code, max_columns, line) || should_ignore(line),
}
-
- false
}
enum Directive {
@@ -230,7 +227,7 @@ pub fn check(path: &Path, bad: &mut bool) {
super::walk(path, &mut skip, &mut |entry, contents| {
let file = entry.path();
let filename = file.file_name().unwrap().to_string_lossy();
- let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css"];
+ let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl"];
if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") {
return;
}
diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs
new file mode 100644
index 000000000..b07e80767
--- /dev/null
+++ b/src/tools/tidy/src/walk.rs
@@ -0,0 +1,66 @@
+use std::fs::File;
+use std::io::Read;
+use walkdir::{DirEntry, WalkDir};
+
+use std::path::Path;
+
+pub fn filter_dirs(path: &Path) -> bool {
+ let skip = [
+ "tidy-test-file",
+ "compiler/rustc_codegen_cranelift",
+ "compiler/rustc_codegen_gcc",
+ "src/llvm-project",
+ "library/backtrace",
+ "library/portable-simd",
+ "library/stdarch",
+ "src/tools/cargo",
+ "src/tools/clippy",
+ "src/tools/miri",
+ "src/tools/rls",
+ "src/tools/rust-analyzer",
+ "src/tools/rust-installer",
+ "src/tools/rustfmt",
+ "src/doc/book",
+ // Filter RLS output directories
+ "target/rls",
+ "src/bootstrap/target",
+ ];
+ skip.iter().any(|p| path.ends_with(p))
+}
+
+pub fn walk_many(
+ paths: &[&Path],
+ skip: &mut dyn FnMut(&Path) -> bool,
+ f: &mut dyn FnMut(&DirEntry, &str),
+) {
+ for path in paths {
+ walk(path, skip, f);
+ }
+}
+
+pub fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)) {
+ let mut contents = String::new();
+ walk_no_read(path, skip, &mut |entry| {
+ contents.clear();
+ if t!(File::open(entry.path()), entry.path()).read_to_string(&mut contents).is_err() {
+ contents.clear();
+ }
+ f(&entry, &contents);
+ });
+}
+
+pub(crate) fn walk_no_read(
+ path: &Path,
+ skip: &mut dyn FnMut(&Path) -> bool,
+ f: &mut dyn FnMut(&DirEntry),
+) {
+ let walker = WalkDir::new(path).into_iter().filter_entry(|e| !skip(e.path()));
+ for entry in walker {
+ if let Ok(entry) = entry {
+ if entry.file_type().is_dir() {
+ continue;
+ }
+ f(&entry);
+ }
+ }
+}
diff --git a/src/tools/unicode-table-generator/src/cascading_map.rs b/src/tools/unicode-table-generator/src/cascading_map.rs
new file mode 100644
index 000000000..02c754230
--- /dev/null
+++ b/src/tools/unicode-table-generator/src/cascading_map.rs
@@ -0,0 +1,78 @@
+use crate::fmt_list;
+use crate::raw_emitter::RawEmitter;
+use std::collections::HashMap;
+use std::fmt::Write as _;
+use std::ops::Range;
+
+impl RawEmitter {
+ pub fn emit_cascading_map(&mut self, ranges: &[Range<u32>]) -> bool {
+ let mut map: [u8; 256] = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ];
+
+ let points = ranges
+ .iter()
+ .flat_map(|r| (r.start..r.end).into_iter().collect::<Vec<u32>>())
+ .collect::<Vec<u32>>();
+
+ println!("there are {} points", points.len());
+
+ // how many distinct ranges need to be counted?
+ let mut codepoints_by_high_bytes = HashMap::<usize, Vec<u32>>::new();
+ for point in points {
+ // assert that there is no whitespace over the 0x3000 range.
+ assert!(point <= 0x3000, "the highest unicode whitespace value has changed");
+ let high_bytes = point as usize >> 8;
+ let codepoints = codepoints_by_high_bytes.entry(high_bytes).or_insert_with(Vec::new);
+ codepoints.push(point);
+ }
+
+ let mut bit_for_high_byte = 1u8;
+ let mut arms = Vec::<String>::new();
+
+ let mut high_bytes: Vec<usize> =
+ codepoints_by_high_bytes.keys().map(|k| k.clone()).collect();
+ high_bytes.sort();
+ for high_byte in high_bytes {
+ let codepoints = codepoints_by_high_bytes.get_mut(&high_byte).unwrap();
+ if codepoints.len() == 1 {
+ let ch = codepoints.pop().unwrap();
+ arms.push(format!("{} => c as u32 == {:#04x}", high_byte, ch));
+ continue;
+ }
+ // more than 1 codepoint in this arm
+ for codepoint in codepoints {
+ map[(*codepoint & 0xff) as usize] |= bit_for_high_byte;
+ }
+ arms.push(format!(
+ "{} => WHITESPACE_MAP[c as usize & 0xff] & {} != 0",
+ high_byte, bit_for_high_byte
+ ));
+ bit_for_high_byte <<= 1;
+ }
+
+ writeln!(&mut self.file, "static WHITESPACE_MAP: [u8; 256] = [{}];", fmt_list(map.iter()))
+ .unwrap();
+ self.bytes_used += 256;
+
+ writeln!(&mut self.file, "#[inline]").unwrap();
+ writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap();
+ writeln!(&mut self.file, " match c as u32 >> 8 {{").unwrap();
+ for arm in arms {
+ writeln!(&mut self.file, " {},", arm).unwrap();
+ }
+ writeln!(&mut self.file, " _ => false,").unwrap();
+ writeln!(&mut self.file, " }}").unwrap();
+ writeln!(&mut self.file, "}}").unwrap();
+
+ true
+ }
+}
diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs
index 4720ee702..2fe578acd 100644
--- a/src/tools/unicode-table-generator/src/main.rs
+++ b/src/tools/unicode-table-generator/src/main.rs
@@ -75,12 +75,13 @@ use std::collections::{BTreeMap, HashMap};
use std::ops::Range;
use ucd_parse::Codepoints;
+mod cascading_map;
mod case_mapping;
mod raw_emitter;
mod skiplist;
mod unicode_download;
-use raw_emitter::{emit_codepoints, RawEmitter};
+use raw_emitter::{emit_codepoints, emit_whitespace, RawEmitter};
static PROPERTIES: &[&str] = &[
"Alphabetic",
@@ -220,7 +221,7 @@ fn main() {
let write_location = std::env::args().nth(1).unwrap_or_else(|| {
eprintln!("Must provide path to write unicode tables to");
eprintln!(
- "e.g. {} library/core/unicode/unicode_data.rs",
+ "e.g. {} library/core/src/unicode/unicode_data.rs",
std::env::args().next().unwrap_or_default()
);
std::process::exit(1);
@@ -241,8 +242,13 @@ fn main() {
let mut modules = Vec::new();
for (property, ranges) in ranges_by_property {
let datapoints = ranges.iter().map(|r| r.end - r.start).sum::<u32>();
+
let mut emitter = RawEmitter::new();
- emit_codepoints(&mut emitter, &ranges);
+ if property == &"White_Space" {
+ emit_whitespace(&mut emitter, &ranges);
+ } else {
+ emit_codepoints(&mut emitter, &ranges);
+ }
modules.push((property.to_lowercase().to_string(), emitter.file));
println!(
diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs
index 39b47ce70..3a5b869f7 100644
--- a/src/tools/unicode-table-generator/src/range_search.rs
+++ b/src/tools/unicode-table-generator/src/range_search.rs
@@ -1,5 +1,6 @@
+#[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
#[inline(always)]
-fn bitset_search<
+const fn bitset_search<
const N: usize,
const CHUNK_SIZE: usize,
const N1: usize,
@@ -15,14 +16,18 @@ fn bitset_search<
let bucket_idx = (needle / 64) as usize;
let chunk_map_idx = bucket_idx / CHUNK_SIZE;
let chunk_piece = bucket_idx % CHUNK_SIZE;
- let chunk_idx = if let Some(&v) = chunk_idx_map.get(chunk_map_idx) {
- v
+ // FIXME: const-hack: Revert to `slice::get` after `const_slice_index`
+ // feature stabilizes.
+ let chunk_idx = if chunk_map_idx < chunk_idx_map.len() {
+ chunk_idx_map[chunk_map_idx]
} else {
return false;
};
let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize;
- let word = if let Some(word) = bitset_canonical.get(idx) {
- *word
+ // FIXME: const-hack: Revert to `slice::get` after `const_slice_index`
+ // feature stabilizes.
+ let word = if idx < bitset_canonical.len() {
+ bitset_canonical[idx]
} else {
let (real_idx, mapping) = bitset_canonicalized[idx - bitset_canonical.len()];
let mut word = bitset_canonical[real_idx as usize];
diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs
index ab8eaee95..890ff986c 100644
--- a/src/tools/unicode-table-generator/src/raw_emitter.rs
+++ b/src/tools/unicode-table-generator/src/raw_emitter.rs
@@ -76,7 +76,7 @@ impl RawEmitter {
writeln!(
&mut self.file,
- "static BITSET_CANONICAL: [u64; {}] = [{}];",
+ "const BITSET_CANONICAL: &'static [u64; {}] = &[{}];",
canonicalized.canonical_words.len(),
fmt_list(canonicalized.canonical_words.iter().map(|v| Bits(*v))),
)
@@ -84,7 +84,7 @@ impl RawEmitter {
self.bytes_used += 8 * canonicalized.canonical_words.len();
writeln!(
&mut self.file,
- "static BITSET_MAPPING: [(u8, u8); {}] = [{}];",
+ "const BITSET_MAPPING: &'static [(u8, u8); {}] = &[{}];",
canonicalized.canonicalized_words.len(),
fmt_list(&canonicalized.canonicalized_words),
)
@@ -96,7 +96,12 @@ impl RawEmitter {
self.blank_line();
- writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap();
+ writeln!(
+ &mut self.file,
+ r#"#[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]"#
+ )
+ .unwrap();
+ writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap();
writeln!(&mut self.file, " super::bitset_search(",).unwrap();
writeln!(&mut self.file, " c as u32,").unwrap();
writeln!(&mut self.file, " &BITSET_CHUNKS_MAP,").unwrap();
@@ -121,12 +126,8 @@ impl RawEmitter {
for chunk in compressed_words.chunks(chunk_length) {
chunks.insert(chunk);
}
- let chunk_map = chunks
- .clone()
- .into_iter()
- .enumerate()
- .map(|(idx, chunk)| (chunk, idx))
- .collect::<HashMap<_, _>>();
+ let chunk_map =
+ chunks.iter().enumerate().map(|(idx, &chunk)| (chunk, idx)).collect::<HashMap<_, _>>();
let mut chunk_indices = Vec::new();
for chunk in compressed_words.chunks(chunk_length) {
chunk_indices.push(chunk_map[chunk]);
@@ -134,7 +135,7 @@ impl RawEmitter {
writeln!(
&mut self.file,
- "static BITSET_CHUNKS_MAP: [u8; {}] = [{}];",
+ "const BITSET_CHUNKS_MAP: &'static [u8; {}] = &[{}];",
chunk_indices.len(),
fmt_list(&chunk_indices),
)
@@ -142,7 +143,7 @@ impl RawEmitter {
self.bytes_used += chunk_indices.len();
writeln!(
&mut self.file,
- "static BITSET_INDEX_CHUNKS: [[u8; {}]; {}] = [{}];",
+ "const BITSET_INDEX_CHUNKS: &'static [[u8; {}]; {}] = &[{}];",
chunk_length,
chunks.len(),
fmt_list(chunks.iter()),
@@ -170,6 +171,15 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
}
}
+pub fn emit_whitespace(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
+ emitter.blank_line();
+
+ let mut cascading = emitter.clone();
+ cascading.emit_cascading_map(&ranges);
+ *emitter = cascading;
+ emitter.desc = String::from("cascading");
+}
+
struct Canonicalized {
canonical_words: Vec<u64>,
canonicalized_words: Vec<(u8, u8)>,
diff --git a/src/tools/unicode-table-generator/src/unicode_download.rs b/src/tools/unicode-table-generator/src/unicode_download.rs
index 9b2e0a258..714bb5338 100644
--- a/src/tools/unicode-table-generator/src/unicode_download.rs
+++ b/src/tools/unicode-table-generator/src/unicode_download.rs
@@ -1,6 +1,6 @@
use crate::UNICODE_DIRECTORY;
use std::path::Path;
-use std::process::Command;
+use std::process::{Command, Output};
static URL_PREFIX: &str = "https://www.unicode.org/Public/UCD/latest/ucd/";
@@ -9,6 +9,18 @@ static README: &str = "ReadMe.txt";
static RESOURCES: &[&str] =
&["DerivedCoreProperties.txt", "PropList.txt", "UnicodeData.txt", "SpecialCasing.txt"];
+#[track_caller]
+fn fetch(url: &str) -> Output {
+ let output = Command::new("curl").arg(URL_PREFIX.to_owned() + url).output().unwrap();
+ if !output.status.success() {
+ panic!(
+ "Failed to run curl to fetch {url}: stderr: {}",
+ String::from_utf8_lossy(&output.stderr)
+ );
+ }
+ output
+}
+
pub fn fetch_latest() {
let directory = Path::new(UNICODE_DIRECTORY);
if directory.exists() {
@@ -20,27 +32,14 @@ pub fn fetch_latest() {
if let Err(e) = std::fs::create_dir_all(directory) {
panic!("Failed to create {UNICODE_DIRECTORY:?}: {e}");
}
- let output = Command::new("curl").arg(URL_PREFIX.to_owned() + README).output().unwrap();
- if !output.status.success() {
- panic!(
- "Failed to run curl to fetch readme: stderr: {}",
- String::from_utf8_lossy(&output.stderr)
- );
- }
+ let output = fetch(README);
let current = std::fs::read_to_string(directory.join(README)).unwrap_or_default();
if current.as_bytes() != &output.stdout[..] {
std::fs::write(directory.join(README), output.stdout).unwrap();
}
for resource in RESOURCES {
- let output = Command::new("curl").arg(URL_PREFIX.to_owned() + resource).output().unwrap();
- if !output.status.success() {
- panic!(
- "Failed to run curl to fetch {}: stderr: {}",
- resource,
- String::from_utf8_lossy(&output.stderr)
- );
- }
+ let output = fetch(resource);
std::fs::write(directory.join(resource), output.stdout).unwrap();
}
}
diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs
index 5a0477b4b..a9830a384 100644
--- a/src/tools/unstable-book-gen/src/main.rs
+++ b/src/tools/unstable-book-gen/src/main.rs
@@ -2,37 +2,23 @@
use std::collections::BTreeSet;
use std::env;
-use std::fs::{self, File};
-use std::io::Write;
+use std::fs::{self, write};
use std::path::Path;
use tidy::features::{collect_lang_features, collect_lib_features, Features};
+use tidy::t;
use tidy::unstable_book::{
collect_unstable_book_section_file_names, collect_unstable_feature_names, LANG_FEATURES_DIR,
LIB_FEATURES_DIR, PATH_STR,
};
-/// A helper macro to `unwrap` a result except also print out details like:
-///
-/// * The file/line of the panic
-/// * The expression that failed
-/// * The error itself
-macro_rules! t {
- ($e:expr) => {
- match $e {
- Ok(e) => e,
- Err(e) => panic!("{} failed with {}", stringify!($e), e),
- }
- };
-}
-
fn generate_stub_issue(path: &Path, name: &str, issue: u32) {
- let mut file = t!(File::create(path));
- t!(write!(file, include_str!("stub-issue.md"), name = name, issue = issue));
+ let content = format!(include_str!("stub-issue.md"), name = name, issue = issue);
+ t!(write(path, content), path);
}
fn generate_stub_no_issue(path: &Path, name: &str) {
- let mut file = t!(File::create(path));
- t!(write!(file, include_str!("stub-no-issue.md"), name = name));
+ let content = format!(include_str!("stub-no-issue.md"), name = name);
+ t!(write(path, content), path);
}
fn set_to_summary_str(set: &BTreeSet<String>, dir: &str) -> String {
@@ -52,13 +38,14 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur
let lang_features_str = set_to_summary_str(&unstable_lang_features, "language-features");
let lib_features_str = set_to_summary_str(&unstable_lib_features, "library-features");
- let mut file = t!(File::create(&path.join("src/SUMMARY.md")));
- t!(file.write_fmt(format_args!(
+ let summary_path = path.join("src/SUMMARY.md");
+ let content = format!(
include_str!("SUMMARY.md"),
compiler_flags = compiler_flags_str,
language_features = lang_features_str,
library_features = lib_features_str
- )));
+ );
+ t!(write(&summary_path, content), summary_path);
}
fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) {
diff --git a/src/version b/src/version
index 940573042..902c74186 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.64.0
+1.65.0
diff --git a/vendor/annotate-snippets-0.8.0/.cargo-checksum.json b/vendor/annotate-snippets-0.8.0/.cargo-checksum.json
deleted file mode 100644
index 413c71606..000000000
--- a/vendor/annotate-snippets-0.8.0/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"ca530d80d98754cf591aec37f089ade5a9334d358caea6262b556ae81ec0695e","Cargo.lock":"cec2d73c92b5db30dc134dd48d5233b7d589a5583a6a7a58f967776b5927de20","Cargo.toml":"acdebc9bab91be584c752d4a3e3b56c554d849f6ac8bc29f9b2270f8c6599404","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"3b0998e062248617e214b03ae83ff0da63ef6ecf08a9e84bd0deb0676958ed8a","benches/simple.rs":"f85dd74583e3addba780b2c136f250197155e173f09472ae106ebca96006ae76","examples/expected_type.rs":"ce9aad006f7aca50c460684dbc7b95007044d730583f8a079e33123c7d98b618","examples/footer.rs":"77bcb981711091d93b4fbfbbe318f262d90996485aa012ba3ff95ebd4dc3085f","examples/format.rs":"72f47847ce0b0a1025b56642a5b3fe191aaac775c16f42d76417362234298393","examples/multislice.rs":"bf10fc20f1948e6b0f325ed486ddf1b44e9a99fd22226012b81c5608846de983","src/display_list/from_snippet.rs":"49797d0f296a6af96bee70ccca8919050033fdaf7cbd1efe18ab2bead3430c6a","src/display_list/mod.rs":"a6aebdc9d666801280623b72798cfaae9172cb6f686ab9ef6c79a31dab6ef044","src/display_list/structs.rs":"3437d210c51b7bedc4a76db4e5492dda986d8328d87c0b3d5fbf548903543064","src/formatter/mod.rs":"bf40e1e852a116e90fcb0c47a3e59513d0fa7aa8a2be3575f819ed850ab7cc38","src/formatter/style.rs":"ab6e7cb90a8921bd9adfb914f234876f65cbc62cfd92b7dcfabfeeefb936d541","src/lib.rs":"fd655cb0518b4d11d5ff3a92eceefc0f45697c430197e95d3b8bed3bbf90325f","src/snippet.rs":"14a875640ac81eca9a29c351b5a99bb8e88a2970bcdddcf2ce1658de2fcbab85","src/stylesheets/color.rs":"5f8049f41a8d9636e55975e999e7c149d4b54b65b2518ea88be1ae69323b21a1","src/stylesheets/mod.rs":"16a439c043e55dd5a0084bd805154a57f4300a174775d90efd577f901784ef65","src/stylesheets/no_color.rs":"854529529a061df5cab0bf889ac43cb6d0203e674be38ae1cfb6724729beac31","tests/diff/mod.rs":"6e760d4bfda064934646da1461b940ef5ca1416a57428bda47871bb116f7add0","tests/dl_from_snippet.rs":"c1d8a69ea35b147853d392db6f94577ee7fb3bed7a0a8dfb07310d1b848b6fe7","tests/fixtures/no-color/multiline_annotation.toml":"352674f4e37f6a7cccce01cd50c0d190f9658ac344deafa06f445e222d2077f2","tests/fixtures/no-color/multiline_annotation.txt":"ee33c4a17fc72095f217a78f479c3718ad5499d745e4248937f7eaa028ee4328","tests/fixtures/no-color/multiline_annotation2.toml":"cb43d8ff232c16946b69e9b95205986a4a020bf338934212276e20384446a214","tests/fixtures/no-color/multiline_annotation2.txt":"4cdd277194e08b8f38b3045e08f3c180982b576029af66cae7519f43bfd81ca6","tests/fixtures/no-color/multiline_annotation3.toml":"93badadaaffca9382c25ac9286006b4aa59747a1e2cc2c717e003dbdd841c1a5","tests/fixtures/no-color/multiline_annotation3.txt":"66ee253f2566e40e69e8fdfb9837ee803c26bce2275d1cb950de28862bb8e0fe","tests/fixtures/no-color/multiple_annotations.toml":"c570a67e211c324edb2a1427148dba3a62cb2af0aaf5a522d1dd6a03594489b5","tests/fixtures/no-color/multiple_annotations.txt":"b284ab83d9de3aa9d014d3d04ac199517967885bc064f0462c15d6a4d71554aa","tests/fixtures/no-color/simple.toml":"6ef667b5e736fc112a1fb4722a2828aaf8049b8bbf6aacdb730a8f3427900f10","tests/fixtures/no-color/simple.txt":"2a8e4036837503bb53fca8ef761b658090e7869bf9b87197612530ca4e71b7f2","tests/fixtures_test.rs":"903f56c24c500135fed3fc0e40c77a89b98f72ce2e99322658242a6bfbf89a14","tests/formatter.rs":"0849bb94fe27f18faa174669e76694509dbe38a04687af809d1094dea2eddb23","tests/snippet/mod.rs":"06f962abc0eff7a83d3088cf774a86c26adc8889ff5652e3958cf14cc029d0c1"},"package":"d78ea013094e5ea606b1c05fe35f1dd7ea1eb1ea259908d040b25bd5ec677ee5"} \ No newline at end of file
diff --git a/vendor/annotate-snippets-0.8.0/CHANGELOG.md b/vendor/annotate-snippets-0.8.0/CHANGELOG.md
deleted file mode 100644
index e0390a71b..000000000
--- a/vendor/annotate-snippets-0.8.0/CHANGELOG.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Changelog
-
-## Unreleased
-
- - …
-
-## annotate-snippets 0.8.0 (April 14, 2020)
-
- - Replace `ansi_term` with `yansi-term` for improved performance. (#30)
- - Turn `Snippet` and `Slice` to work on borrowed slices, rather than Strings. (#32)
- - Fix `\r\n` end of lines. (#29)
-
-## annotate-snippets 0.7.0 (March 30, 2020)
-
- - Refactor API to use `fmt::Display` (#27)
- - Fix SourceAnnotation range (#27)
- - Fix column numbers (#22)
- - Derive `PartialEq` for `AnnotationType` (#19)
- - Update `ansi_term` to 0.12.
-
-## annotate-snippets 0.6.1 (July 23, 2019)
-
- - Fix too many anonymized line numbers (#5)
-
-## annotate-snippets 0.6.0 (June 26, 2019)
-
- - Add an option to anonymize line numbers (#3)
- - Transition the crate to rust-lang org.
- - Update the syntax to Rust 2018 idioms. (#4)
diff --git a/vendor/annotate-snippets-0.8.0/Cargo.lock b/vendor/annotate-snippets-0.8.0/Cargo.lock
deleted file mode 100644
index 18d8f4c0e..000000000
--- a/vendor/annotate-snippets-0.8.0/Cargo.lock
+++ /dev/null
@@ -1,630 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "annotate-snippets"
-version = "0.8.0"
-dependencies = [
- "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "yansi-term 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "bitflags"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "bstr"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "byteorder"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "cast"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "clap"
-version = "2.33.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "criterion"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
- "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "criterion-plot"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "csv"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "csv-core"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "difference"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "either"
-version = "1.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "glob"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "itertools"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "itoa"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "js-sys"
-version = "0.3.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "libc"
-version = "0.2.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "log"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "maybe-uninit"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "memchr"
-version = "2.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "memoffset"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "oorandom"
-version = "11.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "plotters"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rayon"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "regex"
-version = "1.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "rustc_version"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "ryu"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "serde"
-version = "1.0.105"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.105"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.50"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "textwrap"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "tinytemplate"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "unicode-width"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "walkdir"
-version = "2.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "web-sys"
-version = "0.3.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "yansi-term"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[metadata]
-"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
-"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-"checksum bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41"
-"checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
-"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
-"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
-"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
-"checksum criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1"
-"checksum criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545"
-"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
-"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
-"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
-"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
-"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
-"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
-"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
-"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
-"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-"checksum hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
-"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
-"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
-"checksum js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055"
-"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-"checksum libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
-"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
-"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
-"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
-"checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
-"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
-"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
-"checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405"
-"checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb"
-"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
-"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
-"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
-"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
-"checksum regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
-"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
-"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
-"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-"checksum ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
-"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)" = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff"
-"checksum serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)" = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8"
-"checksum serde_json 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867"
-"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
-"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
-"checksum tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a"
-"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
-"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
-"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
-"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
-"checksum wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
-"checksum wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
-"checksum wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
-"checksum wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
-"checksum wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
-"checksum web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb"
-"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
-"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
-"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-"checksum yansi-term 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e44ab40470a13c8746f6a9b5e042ba56dbd55e5a48921e131779b4575935bc7"
diff --git a/vendor/annotate-snippets-0.8.0/Cargo.toml b/vendor/annotate-snippets-0.8.0/Cargo.toml
deleted file mode 100644
index 3cccbbe7c..000000000
--- a/vendor/annotate-snippets-0.8.0/Cargo.toml
+++ /dev/null
@@ -1,62 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-edition = "2018"
-name = "annotate-snippets"
-version = "0.8.0"
-authors = ["Zibi Braniecki <gandalf@mozilla.com>"]
-description = "Library for building code annotations"
-readme = "README.md"
-keywords = ["code", "analysis", "ascii", "errors", "debug"]
-license = "Apache-2.0/MIT"
-repository = "https://github.com/rust-lang/annotate-snippets-rs"
-
-[[bench]]
-name = "simple"
-harness = false
-[dependencies.yansi-term]
-version = "0.1"
-optional = true
-[dev-dependencies.criterion]
-version = "0.3"
-
-[dev-dependencies.difference]
-version = "2.0"
-
-[dev-dependencies.glob]
-version = "0.3"
-
-[dev-dependencies.serde]
-version = "1.0"
-features = ["derive"]
-
-[dev-dependencies.toml]
-version = "0.5"
-
-[dev-dependencies.yansi-term]
-version = "0.1"
-
-[features]
-color = ["yansi-term"]
-default = []
-[badges.coveralls]
-branch = "master"
-repository = "rust-lang/annotate-snippets-rs"
-service = "github"
-
-[badges.maintenance]
-status = "actively-developed"
-
-[badges.travis-ci]
-branch = "master"
-repository = "rust-lang/annotate-snippets-rs"
diff --git a/vendor/annotate-snippets-0.8.0/LICENSE-APACHE b/vendor/annotate-snippets-0.8.0/LICENSE-APACHE
deleted file mode 100644
index 261eeb9e9..000000000
--- a/vendor/annotate-snippets-0.8.0/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/annotate-snippets-0.8.0/LICENSE-MIT b/vendor/annotate-snippets-0.8.0/LICENSE-MIT
deleted file mode 100644
index 5655fa311..000000000
--- a/vendor/annotate-snippets-0.8.0/LICENSE-MIT
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright 2017 Mozilla
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/annotate-snippets-0.8.0/README.md b/vendor/annotate-snippets-0.8.0/README.md
deleted file mode 100644
index 592a51e14..000000000
--- a/vendor/annotate-snippets-0.8.0/README.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# annotate-snippets
-
-`annotate-snippets` is a Rust library for annotation of programming code slices.
-
-[![crates.io](https://meritbadge.herokuapp.com/annotate-snippets)](https://crates.io/crates/annotate-snippets)
-[![Build Status](https://travis-ci.com/rust-lang/annotate-snippets-rs.svg?branch=master)](https://travis-ci.com/rust-lang/annotate-snippets-rs)
-[![Coverage Status](https://coveralls.io/repos/github/rust-lang/annotate-snippets-rs/badge.svg?branch=master)](https://coveralls.io/github/rust-lang/annotate-snippets-rs?branch=master)
-
-The library helps visualize meta information annotating source code slices.
-It takes a data structure called `Snippet` on the input and produces a `String`
-which may look like this:
-
-```text
-error[E0308]: mismatched types
- --> src/format.rs:52:1
- |
-51 | ) -> Option<String> {
- | -------------- expected `Option<String>` because of return type
-52 | / for ann in annotations {
-53 | | match (ann.range.0, ann.range.1) {
-54 | | (None, None) => continue,
-55 | | (Some(start), Some(end)) if start > end_index => continue,
-... |
-71 | | }
-72 | | }
- | |_____^ expected enum `std::option::Option`, found ()
-```
-
-[Documentation][]
-
-[Documentation]: https://docs.rs/annotate-snippets/
-
-Usage
------
-
-```rust
-use annotate_snippets::{
- display_list::DisplayList,
- formatter::DisplayListFormatter,
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
-};
-
-fn main() {
- let snippet = Snippet {
- title: Some(Annotation {
- label: Some("expected type, found `22`".to_string()),
- id: None,
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![
- Slice {
- source: r#"
-This is an example
-content of the slice
-which will be annotated
-with the list of annotations below.
- "#.to_string(),
- line_start: 26,
- origin: Some("examples/example.txt".to_string()),
- fold: false,
- annotations: vec![
- SourceAnnotation {
- label: "Example error annotation".to_string(),
- annotation_type: AnnotationType::Error,
- range: (13, 18),
- },
- SourceAnnotation {
- label: "and here's a warning".to_string(),
- annotation_type: AnnotationType::Warning,
- range: (34, 50),
- },
- ],
- },
- ],
- };
-
- let dl = DisplayList::from(snippet);
- let dlf = DisplayListFormatter::new(true, false);
- println!("{}", dlf.format(&dl));
-}
-```
-
-Local Development
------------------
-
- cargo build
- cargo test
-
-When submitting a PR please use [`cargo fmt`][] (nightly).
-
-[`cargo fmt`]: https://github.com/rust-lang/rustfmt
diff --git a/vendor/annotate-snippets-0.8.0/benches/simple.rs b/vendor/annotate-snippets-0.8.0/benches/simple.rs
deleted file mode 100644
index 4c13a8f00..000000000
--- a/vendor/annotate-snippets-0.8.0/benches/simple.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-#![allow(clippy::unit_arg)]
-#[macro_use]
-extern crate criterion;
-
-use criterion::{black_box, Criterion};
-
-use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
-};
-
-fn create_snippet() {
- let snippet = Snippet {
- slices: vec![Slice {
- source: r#") -> Option<String> {
- for ann in annotations {
- match (ann.range.0, ann.range.1) {
- (None, None) => continue,
- (Some(start), Some(end)) if start > end_index => continue,
- (Some(start), Some(end)) if start >= start_index => {
- let label = if let Some(ref label) = ann.label {
- format!(" {}", label)
- } else {
- String::from("")
- };
-
- return Some(format!(
- "{}{}{}",
- " ".repeat(start - start_index),
- "^".repeat(end - start),
- label
- ));
- }
- _ => continue,
- }
- }"#,
- line_start: 51,
- origin: Some("src/format.rs"),
- fold: false,
- annotations: vec![
- SourceAnnotation {
- label: "expected `Option<String>` because of return type",
- annotation_type: AnnotationType::Warning,
- range: (5, 19),
- },
- SourceAnnotation {
- label: "expected enum `std::option::Option`",
- annotation_type: AnnotationType::Error,
- range: (26, 724),
- },
- ],
- }],
- title: Some(Annotation {
- label: Some("mismatched types"),
- id: Some("E0308"),
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- };
-
- let dl = DisplayList::from(snippet);
- let _result = dl.to_string();
-}
-
-pub fn criterion_benchmark(c: &mut Criterion) {
- c.bench_function("format", |b| b.iter(|| black_box(create_snippet())));
-}
-
-criterion_group!(benches, criterion_benchmark);
-criterion_main!(benches);
diff --git a/vendor/annotate-snippets-0.8.0/examples/expected_type.rs b/vendor/annotate-snippets-0.8.0/examples/expected_type.rs
deleted file mode 100644
index 89f0ddc11..000000000
--- a/vendor/annotate-snippets-0.8.0/examples/expected_type.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
-};
-
-fn main() {
- let snippet = Snippet {
- title: Some(Annotation {
- label: Some("expected type, found `22`"),
- id: None,
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![Slice {
- source: r#" annotations: vec![SourceAnnotation {
- label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
- ,
- range: <22, 25>,"#,
- line_start: 26,
- origin: Some("examples/footer.rs"),
- fold: true,
- annotations: vec![
- SourceAnnotation {
- label: "",
- annotation_type: AnnotationType::Error,
- range: (205, 207),
- },
- SourceAnnotation {
- label: "while parsing this struct",
- annotation_type: AnnotationType::Info,
- range: (34, 50),
- },
- ],
- }],
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- };
-
- let dl = DisplayList::from(snippet);
- println!("{}", dl);
-}
diff --git a/vendor/annotate-snippets-0.8.0/examples/footer.rs b/vendor/annotate-snippets-0.8.0/examples/footer.rs
deleted file mode 100644
index f3c15c410..000000000
--- a/vendor/annotate-snippets-0.8.0/examples/footer.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
-};
-
-fn main() {
- let snippet = Snippet {
- title: Some(Annotation {
- label: Some("mismatched types"),
- id: Some("E0308"),
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![Annotation {
- label: Some(
- "expected type: `snippet::Annotation`\n found type: `__&__snippet::Annotation`",
- ),
- id: None,
- annotation_type: AnnotationType::Note,
- }],
- slices: vec![Slice {
- source: " slices: vec![\"A\",",
- line_start: 13,
- origin: Some("src/multislice.rs"),
- fold: false,
- annotations: vec![SourceAnnotation {
- label: "expected struct `annotate_snippets::snippet::Slice`, found reference",
- range: (21, 24),
- annotation_type: AnnotationType::Error,
- }],
- }],
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- };
-
- let dl = DisplayList::from(snippet);
- println!("{}", dl);
-}
diff --git a/vendor/annotate-snippets-0.8.0/examples/format.rs b/vendor/annotate-snippets-0.8.0/examples/format.rs
deleted file mode 100644
index 98b77a140..000000000
--- a/vendor/annotate-snippets-0.8.0/examples/format.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
-};
-
-fn main() {
- let snippet = Snippet {
- slices: vec![Slice {
- source: r#") -> Option<String> {
- for ann in annotations {
- match (ann.range.0, ann.range.1) {
- (None, None) => continue,
- (Some(start), Some(end)) if start > end_index => continue,
- (Some(start), Some(end)) if start >= start_index => {
- let label = if let Some(ref label) = ann.label {
- format!(" {}", label)
- } else {
- String::from("")
- };
-
- return Some(format!(
- "{}{}{}",
- " ".repeat(start - start_index),
- "^".repeat(end - start),
- label
- ));
- }
- _ => continue,
- }
- }"#,
- line_start: 51,
- origin: Some("src/format.rs"),
- fold: false,
- annotations: vec![
- SourceAnnotation {
- label: "expected `Option<String>` because of return type",
- annotation_type: AnnotationType::Warning,
- range: (5, 19),
- },
- SourceAnnotation {
- label: "expected enum `std::option::Option`",
- annotation_type: AnnotationType::Error,
- range: (26, 724),
- },
- ],
- }],
- title: Some(Annotation {
- label: Some("mismatched types"),
- id: Some("E0308"),
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- };
-
- let dl = DisplayList::from(snippet);
- println!("{}", dl);
-}
diff --git a/vendor/annotate-snippets-0.8.0/examples/multislice.rs b/vendor/annotate-snippets-0.8.0/examples/multislice.rs
deleted file mode 100644
index 5675a07da..000000000
--- a/vendor/annotate-snippets-0.8.0/examples/multislice.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet},
-};
-
-fn main() {
- let snippet = Snippet {
- title: Some(Annotation {
- label: Some("mismatched types"),
- id: None,
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![
- Slice {
- source: "Foo",
- line_start: 51,
- origin: Some("src/format.rs"),
- fold: false,
- annotations: vec![],
- },
- Slice {
- source: "Faa",
- line_start: 129,
- origin: Some("src/display.rs"),
- fold: false,
- annotations: vec![],
- },
- ],
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- };
-
- let dl = DisplayList::from(snippet);
- println!("{}", dl);
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/display_list/from_snippet.rs b/vendor/annotate-snippets-0.8.0/src/display_list/from_snippet.rs
deleted file mode 100644
index b3ba5a3dd..000000000
--- a/vendor/annotate-snippets-0.8.0/src/display_list/from_snippet.rs
+++ /dev/null
@@ -1,517 +0,0 @@
-//! Trait for converting `Snippet` to `DisplayList`.
-use super::*;
-use crate::{formatter::get_term_style, snippet};
-
-struct CursorLines<'a>(&'a str);
-
-impl<'a> CursorLines<'a> {
- fn new(src: &str) -> CursorLines<'_> {
- CursorLines(src)
- }
-}
-
-enum EndLine {
- EOF = 0,
- CRLF = 1,
- LF = 2,
-}
-
-impl<'a> Iterator for CursorLines<'a> {
- type Item = (&'a str, EndLine);
-
- fn next(&mut self) -> Option<Self::Item> {
- if self.0.is_empty() {
- None
- } else {
- self.0
- .find('\n')
- .map(|x| {
- let ret = if 0 < x {
- if self.0.as_bytes()[x - 1] == b'\r' {
- (&self.0[..x - 1], EndLine::LF)
- } else {
- (&self.0[..x], EndLine::CRLF)
- }
- } else {
- ("", EndLine::CRLF)
- };
- self.0 = &self.0[x + 1..];
- ret
- })
- .or_else(|| {
- let ret = Some((&self.0[..], EndLine::EOF));
- self.0 = "";
- ret
- })
- }
- }
-}
-
-fn format_label(
- label: Option<&str>,
- style: Option<DisplayTextStyle>,
-) -> Vec<DisplayTextFragment<'_>> {
- let mut result = vec![];
- if let Some(label) = label {
- for (idx, element) in label.split("__").enumerate() {
- let element_style = match style {
- Some(s) => s,
- None => {
- if idx % 2 == 0 {
- DisplayTextStyle::Regular
- } else {
- DisplayTextStyle::Emphasis
- }
- }
- };
- result.push(DisplayTextFragment {
- content: element,
- style: element_style,
- });
- }
- }
- result
-}
-
-fn format_title(annotation: snippet::Annotation<'_>) -> DisplayLine<'_> {
- let label = annotation.label.unwrap_or_default();
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::from(annotation.annotation_type),
- id: annotation.id,
- label: format_label(Some(&label), Some(DisplayTextStyle::Emphasis)),
- },
- source_aligned: false,
- continuation: false,
- })
-}
-
-fn format_annotation(annotation: snippet::Annotation<'_>) -> Vec<DisplayLine<'_>> {
- let mut result = vec![];
- let label = annotation.label.unwrap_or_default();
- for (i, line) in label.lines().enumerate() {
- result.push(DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::from(annotation.annotation_type),
- id: None,
- label: format_label(Some(line), None),
- },
- source_aligned: true,
- continuation: i != 0,
- }));
- }
- result
-}
-
-fn format_slice(
- mut slice: snippet::Slice<'_>,
- is_first: bool,
- has_footer: bool,
-) -> Vec<DisplayLine<'_>> {
- let main_range = slice.annotations.get(0).map(|x| x.range.0);
- let row = slice.line_start;
- let origin = slice.origin.take();
- let mut body = format_body(slice, has_footer);
- let header = format_header(origin, main_range, row, &body, is_first);
- let mut result = vec![];
-
- if let Some(header) = header {
- result.push(header);
- }
- result.append(&mut body);
- result
-}
-
-fn format_header<'a>(
- origin: Option<&'a str>,
- main_range: Option<usize>,
- mut row: usize,
- body: &[DisplayLine<'_>],
- is_first: bool,
-) -> Option<DisplayLine<'a>> {
- let display_header = if is_first {
- DisplayHeaderType::Initial
- } else {
- DisplayHeaderType::Continuation
- };
-
- if let Some(main_range) = main_range {
- let mut col = 1;
-
- for item in body {
- if let DisplayLine::Source {
- line: DisplaySourceLine::Content { range, .. },
- ..
- } = item
- {
- if main_range >= range.0 && main_range <= range.1 {
- col = main_range - range.0 + 1;
- break;
- }
- row += 1;
- }
- }
- if let Some(path) = origin {
- return Some(DisplayLine::Raw(DisplayRawLine::Origin {
- path,
- pos: Some((row, col)),
- header_type: display_header,
- }));
- }
- }
- if let Some(path) = origin {
- return Some(DisplayLine::Raw(DisplayRawLine::Origin {
- path,
- pos: None,
- header_type: display_header,
- }));
- }
- None
-}
-
-fn fold_body(mut body: Vec<DisplayLine<'_>>) -> Vec<DisplayLine<'_>> {
- enum Line {
- Fold(usize),
- Source(usize),
- };
-
- let mut lines = vec![];
- let mut no_annotation_lines_counter = 0;
-
- for (idx, line) in body.iter().enumerate() {
- match line {
- DisplayLine::Source {
- line: DisplaySourceLine::Annotation { .. },
- ..
- } => {
- if no_annotation_lines_counter > 2 {
- let fold_start = idx - no_annotation_lines_counter;
- let fold_end = idx;
- let pre_len = if no_annotation_lines_counter > 8 {
- 4
- } else {
- 0
- };
- let post_len = if no_annotation_lines_counter > 8 {
- 2
- } else {
- 1
- };
- for (i, _) in body
- .iter()
- .enumerate()
- .take(fold_start + pre_len)
- .skip(fold_start)
- {
- lines.push(Line::Source(i));
- }
- lines.push(Line::Fold(idx));
- for (i, _) in body
- .iter()
- .enumerate()
- .take(fold_end)
- .skip(fold_end - post_len)
- {
- lines.push(Line::Source(i));
- }
- } else {
- let start = idx - no_annotation_lines_counter;
- for (i, _) in body.iter().enumerate().take(idx).skip(start) {
- lines.push(Line::Source(i));
- }
- }
- no_annotation_lines_counter = 0;
- }
- DisplayLine::Source { .. } => {
- no_annotation_lines_counter += 1;
- continue;
- }
- _ => {
- no_annotation_lines_counter += 1;
- }
- }
- lines.push(Line::Source(idx));
- }
-
- let mut new_body = vec![];
- let mut removed = 0;
- for line in lines {
- match line {
- Line::Source(i) => {
- new_body.push(body.remove(i - removed));
- removed += 1;
- }
- Line::Fold(i) => {
- if let DisplayLine::Source {
- line: DisplaySourceLine::Annotation { .. },
- ref inline_marks,
- ..
- } = body.get(i - removed).unwrap()
- {
- new_body.push(DisplayLine::Fold {
- inline_marks: inline_marks.clone(),
- })
- } else {
- unreachable!()
- }
- }
- }
- }
-
- new_body
-}
-
-fn format_body(slice: snippet::Slice<'_>, has_footer: bool) -> Vec<DisplayLine<'_>> {
- let source_len = slice.source.chars().count();
- if let Some(bigger) = slice.annotations.iter().find_map(|x| {
- if source_len < x.range.1 {
- Some(x.range)
- } else {
- None
- }
- }) {
- panic!(
- "SourceAnnotation range `{:?}` is bigger than source length `{}`",
- bigger, source_len
- )
- }
-
- let mut body = vec![];
- let mut current_line = slice.line_start;
- let mut current_index = 0;
- let mut line_index_ranges = vec![];
-
- for (line, end_line) in CursorLines::new(slice.source) {
- let line_length = line.chars().count();
- let line_range = (current_index, current_index + line_length);
- body.push(DisplayLine::Source {
- lineno: Some(current_line),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: line,
- range: line_range,
- },
- });
- line_index_ranges.push(line_range);
- current_line += 1;
- current_index += line_length + end_line as usize;
- }
-
- let mut annotation_line_count = 0;
- let mut annotations = slice.annotations;
- for (idx, (line_start, line_end)) in line_index_ranges.into_iter().enumerate() {
- // It would be nice to use filter_drain here once it's stable.
- annotations = annotations
- .into_iter()
- .filter(|annotation| {
- let body_idx = idx + annotation_line_count;
- let annotation_type = match annotation.annotation_type {
- snippet::AnnotationType::Error => DisplayAnnotationType::None,
- snippet::AnnotationType::Warning => DisplayAnnotationType::None,
- _ => DisplayAnnotationType::from(annotation.annotation_type),
- };
- match annotation.range {
- (start, _) if start > line_end => true,
- (start, end)
- if start >= line_start && end <= line_end
- || start == line_end && end - start <= 1 =>
- {
- let range = (start - line_start, end - line_start);
- body.insert(
- body_idx + 1,
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- annotation: Annotation {
- annotation_type,
- id: None,
- label: format_label(Some(&annotation.label), None),
- },
- range,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- },
- );
- annotation_line_count += 1;
- false
- }
- (start, end) if start >= line_start && start <= line_end && end > line_end => {
- if start - line_start == 0 {
- if let DisplayLine::Source {
- ref mut inline_marks,
- ..
- } = body[body_idx]
- {
- inline_marks.push(DisplayMark {
- mark_type: DisplayMarkType::AnnotationStart,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- });
- }
- } else {
- let range = (start - line_start, start - line_start + 1);
- body.insert(
- body_idx + 1,
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::None,
- id: None,
- label: vec![],
- },
- range,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- annotation_part: DisplayAnnotationPart::MultilineStart,
- },
- },
- );
- annotation_line_count += 1;
- }
- true
- }
- (start, end) if start < line_start && end > line_end => {
- if let DisplayLine::Source {
- ref mut inline_marks,
- ..
- } = body[body_idx]
- {
- inline_marks.push(DisplayMark {
- mark_type: DisplayMarkType::AnnotationThrough,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- });
- }
- true
- }
- (start, end) if start < line_start && end >= line_start && end <= line_end => {
- if let DisplayLine::Source {
- ref mut inline_marks,
- ..
- } = body[body_idx]
- {
- inline_marks.push(DisplayMark {
- mark_type: DisplayMarkType::AnnotationThrough,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- });
- }
-
- let range = (end - line_start, end - line_start + 1);
- body.insert(
- body_idx + 1,
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![DisplayMark {
- mark_type: DisplayMarkType::AnnotationThrough,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- }],
- line: DisplaySourceLine::Annotation {
- annotation: Annotation {
- annotation_type,
- id: None,
- label: format_label(Some(&annotation.label), None),
- },
- range,
- annotation_type: DisplayAnnotationType::from(
- annotation.annotation_type,
- ),
- annotation_part: DisplayAnnotationPart::MultilineEnd,
- },
- },
- );
- annotation_line_count += 1;
- false
- }
- _ => true,
- }
- })
- .collect();
- }
-
- if slice.fold {
- body = fold_body(body);
- }
-
- body.insert(
- 0,
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Empty,
- },
- );
- if has_footer {
- body.push(DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Empty,
- });
- } else if let Some(DisplayLine::Source { .. }) = body.last() {
- body.push(DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Empty,
- });
- }
- body
-}
-
-impl<'a> From<snippet::Snippet<'a>> for DisplayList<'a> {
- fn from(
- snippet::Snippet {
- title,
- footer,
- slices,
- opt,
- }: snippet::Snippet<'a>,
- ) -> DisplayList<'a> {
- let mut body = vec![];
- if let Some(annotation) = title {
- body.push(format_title(annotation));
- }
-
- for (idx, slice) in slices.into_iter().enumerate() {
- body.append(&mut format_slice(slice, idx == 0, !footer.is_empty()));
- }
-
- for annotation in footer {
- body.append(&mut format_annotation(annotation));
- }
-
- let FormatOptions {
- color,
- anonymized_line_numbers,
- } = opt;
-
- Self {
- body,
- stylesheet: get_term_style(color),
- anonymized_line_numbers,
- }
- }
-}
-
-impl From<snippet::AnnotationType> for DisplayAnnotationType {
- fn from(at: snippet::AnnotationType) -> Self {
- match at {
- snippet::AnnotationType::Error => DisplayAnnotationType::Error,
- snippet::AnnotationType::Warning => DisplayAnnotationType::Warning,
- snippet::AnnotationType::Info => DisplayAnnotationType::Info,
- snippet::AnnotationType::Note => DisplayAnnotationType::Note,
- snippet::AnnotationType::Help => DisplayAnnotationType::Help,
- }
- }
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/display_list/mod.rs b/vendor/annotate-snippets-0.8.0/src/display_list/mod.rs
deleted file mode 100644
index 224a9f580..000000000
--- a/vendor/annotate-snippets-0.8.0/src/display_list/mod.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-//! display_list module stores the output model for the snippet.
-//!
-//! `DisplayList` is a central structure in the crate, which contains
-//! the structured list of lines to be displayed.
-//!
-//! It is made of two types of lines: `Source` and `Raw`. All `Source` lines
-//! are structured using four columns:
-//!
-//! ```text
-//! /------------ (1) Line number column.
-//! | /--------- (2) Line number column delimiter.
-//! | | /------- (3) Inline marks column.
-//! | | | /--- (4) Content column with the source and annotations for slices.
-//! | | | |
-//! =============================================================================
-//! error[E0308]: mismatched types
-//! --> src/format.rs:51:5
-//! |
-//! 151 | / fn test() -> String {
-//! 152 | | return "test";
-//! 153 | | }
-//! | |___^ error: expected `String`, for `&str`.
-//! |
-//! ```
-//!
-//! The first two lines of the example above are `Raw` lines, while the rest
-//! are `Source` lines.
-//!
-//! `DisplayList` does not store column alignment information, and those are
-//! only calculated by the implementation of `std::fmt::Display` using information such as
-//! styling.
-//!
-//! The above snippet has been built out of the following structure:
-mod from_snippet;
-mod structs;
-
-pub use self::structs::*;
diff --git a/vendor/annotate-snippets-0.8.0/src/display_list/structs.rs b/vendor/annotate-snippets-0.8.0/src/display_list/structs.rs
deleted file mode 100644
index 8f6d8fcf1..000000000
--- a/vendor/annotate-snippets-0.8.0/src/display_list/structs.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-use std::fmt;
-
-use crate::formatter::{get_term_style, style::Stylesheet};
-
-/// List of lines to be displayed.
-pub struct DisplayList<'a> {
- pub body: Vec<DisplayLine<'a>>,
- pub stylesheet: Box<dyn Stylesheet>,
- pub anonymized_line_numbers: bool,
-}
-
-impl<'a> From<Vec<DisplayLine<'a>>> for DisplayList<'a> {
- fn from(body: Vec<DisplayLine<'a>>) -> DisplayList<'a> {
- Self {
- body,
- anonymized_line_numbers: false,
- stylesheet: get_term_style(false),
- }
- }
-}
-
-impl<'a> PartialEq for DisplayList<'a> {
- fn eq(&self, other: &Self) -> bool {
- self.body == other.body && self.anonymized_line_numbers == other.anonymized_line_numbers
- }
-}
-
-impl<'a> fmt::Debug for DisplayList<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("DisplayList")
- .field("body", &self.body)
- .field("anonymized_line_numbers", &self.anonymized_line_numbers)
- .finish()
- }
-}
-
-#[derive(Debug, Default, Copy, Clone)]
-pub struct FormatOptions {
- pub color: bool,
- pub anonymized_line_numbers: bool,
-}
-
-/// Inline annotation which can be used in either Raw or Source line.
-#[derive(Debug, PartialEq)]
-pub struct Annotation<'a> {
- pub annotation_type: DisplayAnnotationType,
- pub id: Option<&'a str>,
- pub label: Vec<DisplayTextFragment<'a>>,
-}
-
-/// A single line used in `DisplayList`.
-#[derive(Debug, PartialEq)]
-pub enum DisplayLine<'a> {
- /// A line with `lineno` portion of the slice.
- Source {
- lineno: Option<usize>,
- inline_marks: Vec<DisplayMark>,
- line: DisplaySourceLine<'a>,
- },
-
- /// A line indicating a folded part of the slice.
- Fold { inline_marks: Vec<DisplayMark> },
-
- /// A line which is displayed outside of slices.
- Raw(DisplayRawLine<'a>),
-}
-
-/// A source line.
-#[derive(Debug, PartialEq)]
-pub enum DisplaySourceLine<'a> {
- /// A line with the content of the Slice.
- Content {
- text: &'a str,
- range: (usize, usize), // meta information for annotation placement.
- },
-
- /// An annotation line which is displayed in context of the slice.
- Annotation {
- annotation: Annotation<'a>,
- range: (usize, usize),
- annotation_type: DisplayAnnotationType,
- annotation_part: DisplayAnnotationPart,
- },
-
- /// An empty source line.
- Empty,
-}
-
-/// Raw line - a line which does not have the `lineno` part and is not considered
-/// a part of the snippet.
-#[derive(Debug, PartialEq)]
-pub enum DisplayRawLine<'a> {
- /// A line which provides information about the location of the given
- /// slice in the project structure.
- Origin {
- path: &'a str,
- pos: Option<(usize, usize)>,
- header_type: DisplayHeaderType,
- },
-
- /// An annotation line which is not part of any snippet.
- Annotation {
- annotation: Annotation<'a>,
-
- /// If set to `true`, the annotation will be aligned to the
- /// lineno delimiter of the snippet.
- source_aligned: bool,
- /// If set to `true`, only the label of the `Annotation` will be
- /// displayed. It allows for a multiline annotation to be aligned
- /// without displaing the meta information (`type` and `id`) to be
- /// displayed on each line.
- continuation: bool,
- },
-}
-
-/// An inline text fragment which any label is composed of.
-#[derive(Debug, PartialEq)]
-pub struct DisplayTextFragment<'a> {
- pub content: &'a str,
- pub style: DisplayTextStyle,
-}
-
-/// A style for the `DisplayTextFragment` which can be visually formatted.
-///
-/// This information may be used to emphasis parts of the label.
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum DisplayTextStyle {
- Regular,
- Emphasis,
-}
-
-/// An indicator of what part of the annotation a given `Annotation` is.
-#[derive(Debug, Clone, PartialEq)]
-pub enum DisplayAnnotationPart {
- /// A standalone, single-line annotation.
- Standalone,
- /// A continuation of a multi-line label of an annotation.
- LabelContinuation,
- /// A consequitive annotation in case multiple annotations annotate a single line.
- Consequitive,
- /// A line starting a multiline annotation.
- MultilineStart,
- /// A line ending a multiline annotation.
- MultilineEnd,
-}
-
-/// A visual mark used in `inline_marks` field of the `DisplaySourceLine`.
-#[derive(Debug, Clone, PartialEq)]
-pub struct DisplayMark {
- pub mark_type: DisplayMarkType,
- pub annotation_type: DisplayAnnotationType,
-}
-
-/// A type of the `DisplayMark`.
-#[derive(Debug, Clone, PartialEq)]
-pub enum DisplayMarkType {
- /// A mark indicating a multiline annotation going through the current line.
- AnnotationThrough,
- /// A mark indicating a multiline annotation starting on the given line.
- AnnotationStart,
-}
-
-/// A type of the `Annotation` which may impact the sigils, style or text displayed.
-///
-/// There are several ways in which the `DisplayListFormatter` uses this information
-/// when formatting the `DisplayList`:
-///
-/// * An annotation may display the name of the type like `error` or `info`.
-/// * An underline for `Error` may be `^^^` while for `Warning` it coule be `---`.
-/// * `ColorStylesheet` may use different colors for different annotations.
-#[derive(Debug, Clone, PartialEq)]
-pub enum DisplayAnnotationType {
- None,
- Error,
- Warning,
- Info,
- Note,
- Help,
-}
-
-/// Information whether the header is the initial one or a consequitive one
-/// for multi-slice cases.
-// TODO: private
-#[derive(Debug, Clone, PartialEq)]
-pub enum DisplayHeaderType {
- /// Initial header is the first header in the snippet.
- Initial,
-
- /// Continuation marks all headers of following slices in the snippet.
- Continuation,
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs b/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs
deleted file mode 100644
index e93aeb329..000000000
--- a/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs
+++ /dev/null
@@ -1,397 +0,0 @@
-use std::{
- cmp,
- fmt::{self, Display, Write},
-};
-
-pub mod style;
-
-use self::style::{Style, StyleClass, Stylesheet};
-
-#[cfg(feature = "color")]
-use crate::stylesheets::color::AnsiTermStylesheet;
-use crate::{display_list::*, stylesheets::no_color::NoColorStylesheet};
-
-fn format_repeat_char(c: char, n: usize, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- for _ in 0..n {
- f.write_char(c)?;
- }
- Ok(())
-}
-
-#[inline]
-fn is_annotation_empty(annotation: &Annotation<'_>) -> bool {
- annotation
- .label
- .iter()
- .all(|fragment| fragment.content.is_empty())
-}
-
-#[cfg(feature = "color")]
-#[inline]
-pub fn get_term_style(color: bool) -> Box<dyn Stylesheet> {
- if color {
- Box::new(AnsiTermStylesheet)
- } else {
- Box::new(NoColorStylesheet)
- }
-}
-
-#[cfg(not(feature = "color"))]
-#[inline]
-pub fn get_term_style(_color: bool) -> Box<dyn Stylesheet> {
- Box::new(NoColorStylesheet)
-}
-
-impl<'a> fmt::Display for DisplayList<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let lineno_width = self.body.iter().fold(0, |max, line| match line {
- DisplayLine::Source {
- lineno: Some(lineno),
- ..
- } => {
- // The largest line is the largest width.
- cmp::max(*lineno, max)
- }
- _ => max,
- });
- let lineno_width = if lineno_width == 0 {
- lineno_width
- } else if self.anonymized_line_numbers {
- Self::ANONYMIZED_LINE_NUM.len()
- } else {
- ((lineno_width as f64).log10().floor() as usize) + 1
- };
- let inline_marks_width = self.body.iter().fold(0, |max, line| match line {
- DisplayLine::Source { inline_marks, .. } => cmp::max(inline_marks.len(), max),
- _ => max,
- });
-
- for (i, line) in self.body.iter().enumerate() {
- self.format_line(line, lineno_width, inline_marks_width, f)?;
- if i + 1 < self.body.len() {
- f.write_char('\n')?;
- }
- }
- Ok(())
- }
-}
-
-impl<'a> DisplayList<'a> {
- const ANONYMIZED_LINE_NUM: &'static str = "LL";
- const ERROR_TXT: &'static str = "error";
- const HELP_TXT: &'static str = "help";
- const INFO_TXT: &'static str = "info";
- const NOTE_TXT: &'static str = "note";
- const WARNING_TXT: &'static str = "warning";
-
- #[inline]
- fn format_annotation_type(
- annotation_type: &DisplayAnnotationType,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- match annotation_type {
- DisplayAnnotationType::Error => f.write_str(Self::ERROR_TXT),
- DisplayAnnotationType::Help => f.write_str(Self::HELP_TXT),
- DisplayAnnotationType::Info => f.write_str(Self::INFO_TXT),
- DisplayAnnotationType::Note => f.write_str(Self::NOTE_TXT),
- DisplayAnnotationType::Warning => f.write_str(Self::WARNING_TXT),
- DisplayAnnotationType::None => Ok(()),
- }
- }
-
- fn annotation_type_len(annotation_type: &DisplayAnnotationType) -> usize {
- match annotation_type {
- DisplayAnnotationType::Error => Self::ERROR_TXT.len(),
- DisplayAnnotationType::Help => Self::HELP_TXT.len(),
- DisplayAnnotationType::Info => Self::INFO_TXT.len(),
- DisplayAnnotationType::Note => Self::NOTE_TXT.len(),
- DisplayAnnotationType::Warning => Self::WARNING_TXT.len(),
- DisplayAnnotationType::None => 0,
- }
- }
-
- fn get_annotation_style(&self, annotation_type: &DisplayAnnotationType) -> Box<dyn Style> {
- self.stylesheet.get_style(match annotation_type {
- DisplayAnnotationType::Error => StyleClass::Error,
- DisplayAnnotationType::Warning => StyleClass::Warning,
- DisplayAnnotationType::Info => StyleClass::Info,
- DisplayAnnotationType::Note => StyleClass::Note,
- DisplayAnnotationType::Help => StyleClass::Help,
- DisplayAnnotationType::None => StyleClass::None,
- })
- }
-
- fn format_label(
- &self,
- label: &[DisplayTextFragment<'_>],
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- let emphasis_style = self.stylesheet.get_style(StyleClass::Emphasis);
-
- for fragment in label {
- match fragment.style {
- DisplayTextStyle::Regular => fragment.content.fmt(f)?,
- DisplayTextStyle::Emphasis => emphasis_style.paint(&fragment.content, f)?,
- }
- }
- Ok(())
- }
-
- fn format_annotation(
- &self,
- annotation: &Annotation<'_>,
- continuation: bool,
- in_source: bool,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- let color = self.get_annotation_style(&annotation.annotation_type);
- let formatted_len = if let Some(id) = &annotation.id {
- 2 + id.len() + Self::annotation_type_len(&annotation.annotation_type)
- } else {
- Self::annotation_type_len(&annotation.annotation_type)
- };
-
- if continuation {
- format_repeat_char(' ', formatted_len + 2, f)?;
- return self.format_label(&annotation.label, f);
- }
- if formatted_len == 0 {
- self.format_label(&annotation.label, f)
- } else {
- color.paint_fn(
- Box::new(|f| {
- Self::format_annotation_type(&annotation.annotation_type, f)?;
- if let Some(id) = &annotation.id {
- f.write_char('[')?;
- f.write_str(id)?;
- f.write_char(']')?;
- }
- Ok(())
- }),
- f,
- )?;
- if !is_annotation_empty(annotation) {
- if in_source {
- color.paint_fn(
- Box::new(|f| {
- f.write_str(": ")?;
- self.format_label(&annotation.label, f)
- }),
- f,
- )?;
- } else {
- f.write_str(": ")?;
- self.format_label(&annotation.label, f)?;
- }
- }
- Ok(())
- }
- }
-
- #[inline]
- fn format_source_line(
- &self,
- line: &DisplaySourceLine<'_>,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- match line {
- DisplaySourceLine::Empty => Ok(()),
- DisplaySourceLine::Content { text, .. } => {
- f.write_char(' ')?;
- text.fmt(f)
- }
- DisplaySourceLine::Annotation {
- range,
- annotation,
- annotation_type,
- annotation_part,
- } => {
- let indent_char = match annotation_part {
- DisplayAnnotationPart::Standalone => ' ',
- DisplayAnnotationPart::LabelContinuation => ' ',
- DisplayAnnotationPart::Consequitive => ' ',
- DisplayAnnotationPart::MultilineStart => '_',
- DisplayAnnotationPart::MultilineEnd => '_',
- };
- let mark = match annotation_type {
- DisplayAnnotationType::Error => '^',
- DisplayAnnotationType::Warning => '-',
- DisplayAnnotationType::Info => '-',
- DisplayAnnotationType::Note => '-',
- DisplayAnnotationType::Help => '-',
- DisplayAnnotationType::None => ' ',
- };
- let color = self.get_annotation_style(annotation_type);
- let indent_length = match annotation_part {
- DisplayAnnotationPart::LabelContinuation => range.1,
- DisplayAnnotationPart::Consequitive => range.1,
- _ => range.0,
- };
-
- color.paint_fn(
- Box::new(|f| {
- format_repeat_char(indent_char, indent_length + 1, f)?;
- format_repeat_char(mark, range.1 - indent_length, f)
- }),
- f,
- )?;
-
- if !is_annotation_empty(&annotation) {
- f.write_char(' ')?;
- color.paint_fn(
- Box::new(|f| {
- self.format_annotation(
- annotation,
- annotation_part == &DisplayAnnotationPart::LabelContinuation,
- true,
- f,
- )
- }),
- f,
- )?;
- }
-
- Ok(())
- }
- }
- }
-
- #[inline]
- fn format_raw_line(
- &self,
- line: &DisplayRawLine<'_>,
- lineno_width: usize,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- match line {
- DisplayRawLine::Origin {
- path,
- pos,
- header_type,
- } => {
- let header_sigil = match header_type {
- DisplayHeaderType::Initial => "-->",
- DisplayHeaderType::Continuation => ":::",
- };
- let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
-
- if let Some((col, row)) = pos {
- format_repeat_char(' ', lineno_width, f)?;
- lineno_color.paint(header_sigil, f)?;
- f.write_char(' ')?;
- path.fmt(f)?;
- f.write_char(':')?;
- col.fmt(f)?;
- f.write_char(':')?;
- row.fmt(f)
- } else {
- format_repeat_char(' ', lineno_width, f)?;
- lineno_color.paint(header_sigil, f)?;
- f.write_char(' ')?;
- path.fmt(f)
- }
- }
- DisplayRawLine::Annotation {
- annotation,
- source_aligned,
- continuation,
- } => {
- if *source_aligned {
- if *continuation {
- format_repeat_char(' ', lineno_width + 3, f)?;
- self.format_annotation(annotation, *continuation, false, f)
- } else {
- let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
- format_repeat_char(' ', lineno_width, f)?;
- f.write_char(' ')?;
- lineno_color.paint("=", f)?;
- f.write_char(' ')?;
- self.format_annotation(annotation, *continuation, false, f)
- }
- } else {
- self.format_annotation(annotation, *continuation, false, f)
- }
- }
- }
- }
-
- #[inline]
- fn format_line(
- &self,
- dl: &DisplayLine<'_>,
- lineno_width: usize,
- inline_marks_width: usize,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- match dl {
- DisplayLine::Source {
- lineno,
- inline_marks,
- line,
- } => {
- let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
- if self.anonymized_line_numbers && lineno.is_some() {
- lineno_color.paint_fn(
- Box::new(|f| {
- f.write_str(Self::ANONYMIZED_LINE_NUM)?;
- f.write_str(" |")
- }),
- f,
- )?;
- } else {
- lineno_color.paint_fn(
- Box::new(|f| {
- match lineno {
- Some(n) => write!(f, "{:>width$}", n, width = lineno_width),
- None => format_repeat_char(' ', lineno_width, f),
- }?;
- f.write_str(" |")
- }),
- f,
- )?;
- }
- if *line != DisplaySourceLine::Empty {
- if !inline_marks.is_empty() || 0 < inline_marks_width {
- f.write_char(' ')?;
- self.format_inline_marks(inline_marks, inline_marks_width, f)?;
- }
- self.format_source_line(line, f)?;
- } else if !inline_marks.is_empty() {
- f.write_char(' ')?;
- self.format_inline_marks(inline_marks, inline_marks_width, f)?;
- }
- Ok(())
- }
- DisplayLine::Fold { inline_marks } => {
- f.write_str("...")?;
- if !inline_marks.is_empty() || 0 < inline_marks_width {
- format_repeat_char(' ', lineno_width, f)?;
- self.format_inline_marks(inline_marks, inline_marks_width, f)?;
- }
- Ok(())
- }
- DisplayLine::Raw(line) => self.format_raw_line(line, lineno_width, f),
- }
- }
-
- fn format_inline_marks(
- &self,
- inline_marks: &[DisplayMark],
- inline_marks_width: usize,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- format_repeat_char(' ', inline_marks_width - inline_marks.len(), f)?;
- for mark in inline_marks {
- self.get_annotation_style(&mark.annotation_type).paint_fn(
- Box::new(|f| {
- f.write_char(match mark.mark_type {
- DisplayMarkType::AnnotationThrough => '|',
- DisplayMarkType::AnnotationStart => '/',
- })
- }),
- f,
- )?;
- }
- Ok(())
- }
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/formatter/style.rs b/vendor/annotate-snippets-0.8.0/src/formatter/style.rs
deleted file mode 100644
index f76e6b0ab..000000000
--- a/vendor/annotate-snippets-0.8.0/src/formatter/style.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-//! Set of structures required to implement a stylesheet
-//!
-//! In order to provide additional styling information for the
-//! formatter, a structs can implement `Stylesheet` and `Style`
-//! traits.
-//!
-use std::fmt;
-
-/// StyleClass is a collection of named variants of style classes
-pub enum StyleClass {
- /// Message indicating an error.
- Error,
- /// Message indicating a warning.
- Warning,
- /// Message indicating an information.
- Info,
- /// Message indicating a note.
- Note,
- /// Message indicating a help.
- Help,
-
- /// Style for line numbers.
- LineNo,
-
- /// Parts of the text that are to be emphasised.
- Emphasis,
-
- /// Parts of the text that are regular. Usually a no-op.
- None,
-}
-
-/// This trait implements a return value for the `Stylesheet::get_style`.
-pub trait Style {
- /// The method used to write text with formatter
- fn paint(&self, text: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result;
- /// The method used to write display function with formatter
- fn paint_fn<'a>(
- &self,
- c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result;
- /// The method used by the DisplayListFormatter to display the message
- /// in bold font.
- fn bold(&self) -> Box<dyn Style>;
-}
-
-/// Trait to annotate structs that can provide `Style` implementations for
-/// every `StyleClass` variant.
-pub trait Stylesheet {
- /// Returns a `Style` implementer based on the requested `StyleClass` variant.
- fn get_style(&self, class: StyleClass) -> Box<dyn Style>;
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/lib.rs b/vendor/annotate-snippets-0.8.0/src/lib.rs
deleted file mode 100644
index 46b25e156..000000000
--- a/vendor/annotate-snippets-0.8.0/src/lib.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-#![deny(rust_2018_idioms)]
-
-//! A library for formatting of text or programming code snippets.
-//!
-//! It's primary purpose is to build an ASCII-graphical representation of the snippet
-//! with annotations.
-//!
-//! # Example
-//!
-//! ```text
-//! error[E0308]: mismatched types
-//! --> src/format.rs:52:1
-//! |
-//! 51 | ) -> Option<String> {
-//! | -------------- expected `Option<String>` because of return type
-//! 52 | / for ann in annotations {
-//! 53 | | match (ann.range.0, ann.range.1) {
-//! 54 | | (None, None) => continue,
-//! 55 | | (Some(start), Some(end)) if start > end_index => continue,
-//! ... |
-//! 71 | | }
-//! 72 | | }
-//! | |_____^ expected enum `std::option::Option`, found ()
-//! ```
-//!
-//! The crate uses a three stage process with two conversions between states:
-//!
-//! ```text
-//! Snippet --> DisplayList --> String
-//! ```
-//!
-//! The input type - [Snippet](self::snippet) is a structure designed
-//! to align with likely output from any parser whose code snippet is to be
-//! annotated.
-//!
-//! The middle structure - [DisplayList](self::display_list) is a
-//! structure designed to store the snippet data converted into a vector
-//! of lines containing semantic information about each line.
-//! This structure is the easiest to manipulate and organize.
-//!
-//! Finally, [DisplayListFormatter](self::formatter::DisplayListFormatter) is
-//! used to format the `DisplayList` using a `Stylesheet` into a final `String` output.
-//!
-//! A user of the crate may choose to provide their own equivalent of the input
-//! structure with an `Into<DisplayList>` trait.
-//!
-//! A user of the crate may also choose to provide their own formatter logic,
-//! to convert a `DisplayList` into a `String`, or just a `Stylesheet` to
-//! use the crate's formatting logic, but with a custom stylesheet.
-
-pub mod display_list;
-pub mod formatter;
-pub mod snippet;
-pub mod stylesheets;
diff --git a/vendor/annotate-snippets-0.8.0/src/snippet.rs b/vendor/annotate-snippets-0.8.0/src/snippet.rs
deleted file mode 100644
index bc7ba0099..000000000
--- a/vendor/annotate-snippets-0.8.0/src/snippet.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-//! Structures used as an input for the library.
-//!
-//! Example:
-//!
-//! ```
-//! use annotate_snippets::snippet::*;
-//!
-//! Snippet {
-//! title: Some(Annotation {
-//! label: Some("mismatched types"),
-//! id: None,
-//! annotation_type: AnnotationType::Error,
-//! }),
-//! footer: vec![],
-//! slices: vec![
-//! Slice {
-//! source: "Foo",
-//! line_start: 51,
-//! origin: Some("src/format.rs"),
-//! fold: false,
-//! annotations: vec![],
-//! },
-//! Slice {
-//! source: "Faa",
-//! line_start: 129,
-//! origin: Some("src/display.rs"),
-//! fold: false,
-//! annotations: vec![],
-//! },
-//! ],
-//! opt: Default::default(),
-//! };
-//! ```
-use crate::display_list::FormatOptions;
-
-/// Primary structure provided for formatting
-#[derive(Debug, Default)]
-pub struct Snippet<'a> {
- pub title: Option<Annotation<'a>>,
- pub footer: Vec<Annotation<'a>>,
- pub slices: Vec<Slice<'a>>,
- pub opt: FormatOptions,
-}
-
-/// Structure containing the slice of text to be annotated and
-/// basic information about the location of the slice.
-///
-/// One `Slice` is meant to represent a single, continuous,
-/// slice of source code that you want to annotate.
-#[derive(Debug)]
-pub struct Slice<'a> {
- pub source: &'a str,
- pub line_start: usize,
- pub origin: Option<&'a str>,
- pub annotations: Vec<SourceAnnotation<'a>>,
- /// If set explicitly to `true`, the snippet will fold
- /// parts of the slice that don't contain any annotations.
- pub fold: bool,
-}
-
-/// Types of annotations.
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum AnnotationType {
- /// Error annotations are displayed using red color and "^" character.
- Error,
- /// Warning annotations are displayed using blue color and "-" character.
- Warning,
- Info,
- Note,
- Help,
-}
-
-/// An annotation for a `Slice`.
-#[derive(Debug)]
-pub struct SourceAnnotation<'a> {
- pub range: (usize, usize),
- pub label: &'a str,
- pub annotation_type: AnnotationType,
-}
-
-/// An annotation for a `Snippet`.
-#[derive(Debug)]
-pub struct Annotation<'a> {
- /// Identifier of the annotation. Usually error code like "E0308".
- pub id: Option<&'a str>,
- pub label: Option<&'a str>,
- pub annotation_type: AnnotationType,
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/stylesheets/color.rs b/vendor/annotate-snippets-0.8.0/src/stylesheets/color.rs
deleted file mode 100644
index 024dd06f6..000000000
--- a/vendor/annotate-snippets-0.8.0/src/stylesheets/color.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use std::fmt::{self, Display};
-
-use yansi_term::{Color::Fixed, Style as AnsiTermStyle};
-
-use crate::formatter::style::{Style, StyleClass, Stylesheet};
-
-struct AnsiTermStyleWrapper {
- style: AnsiTermStyle,
-}
-
-impl Style for AnsiTermStyleWrapper {
- fn paint(&self, text: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.style.paint(text).fmt(f)
- }
-
- fn paint_fn<'a>(
- &self,
- c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- self.style.paint_fn(c).fmt(f)
- }
-
- fn bold(&self) -> Box<dyn Style> {
- Box::new(AnsiTermStyleWrapper { style: self.style })
- }
-}
-
-pub struct AnsiTermStylesheet;
-
-impl Stylesheet for AnsiTermStylesheet {
- fn get_style(&self, class: StyleClass) -> Box<dyn Style> {
- let ansi_term_style = match class {
- StyleClass::Error => Fixed(9).bold(),
- StyleClass::Warning => Fixed(11).bold(),
- StyleClass::Info => Fixed(12).bold(),
- StyleClass::Note => AnsiTermStyle::new().bold(),
- StyleClass::Help => Fixed(14).bold(),
-
- StyleClass::LineNo => Fixed(12).bold(),
-
- StyleClass::Emphasis => AnsiTermStyle::new().bold(),
-
- StyleClass::None => AnsiTermStyle::new(),
- };
- Box::new(AnsiTermStyleWrapper {
- style: ansi_term_style,
- })
- }
-}
diff --git a/vendor/annotate-snippets-0.8.0/src/stylesheets/mod.rs b/vendor/annotate-snippets-0.8.0/src/stylesheets/mod.rs
deleted file mode 100644
index 49f6ea04b..000000000
--- a/vendor/annotate-snippets-0.8.0/src/stylesheets/mod.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//! List of stylesheets that can be used by the `DisplayListFormatter`.
-//!
-//! The list depends on what optional dependencies the crate has been
-//! compiled with.
-//!
-//! By default the `no_color` is available. If the crate gets compiled
-//! with `ansi_term`, the `color` stylesheet is added.
-
-#[cfg(feature = "color")]
-pub mod color;
-pub mod no_color;
diff --git a/vendor/annotate-snippets-0.8.0/src/stylesheets/no_color.rs b/vendor/annotate-snippets-0.8.0/src/stylesheets/no_color.rs
deleted file mode 100644
index 21cb26955..000000000
--- a/vendor/annotate-snippets-0.8.0/src/stylesheets/no_color.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use std::fmt;
-
-use crate::formatter::style::{Style, StyleClass, Stylesheet};
-
-pub struct NoOpStyle {}
-
-impl Style for NoOpStyle {
- fn paint(&self, text: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(text)
- }
-
- fn paint_fn<'a>(
- &self,
- c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
- f: &mut fmt::Formatter<'_>,
- ) -> fmt::Result {
- c(f)
- }
-
- fn bold(&self) -> Box<dyn Style> {
- Box::new(NoOpStyle {})
- }
-}
-
-pub struct NoColorStylesheet;
-
-impl Stylesheet for NoColorStylesheet {
- fn get_style(&self, _class: StyleClass) -> Box<dyn Style> {
- Box::new(NoOpStyle {})
- }
-}
diff --git a/vendor/annotate-snippets-0.8.0/tests/diff/mod.rs b/vendor/annotate-snippets-0.8.0/tests/diff/mod.rs
deleted file mode 100644
index 576c6c4d6..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/diff/mod.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use difference::{Changeset, Difference};
-use yansi_term::Color::{Black, Green, Red};
-
-pub fn get_diff(left: &str, right: &str) -> String {
- let mut output = String::new();
-
- let Changeset { diffs, .. } = Changeset::new(left, right, "\n");
-
- for i in 0..diffs.len() {
- match diffs[i] {
- Difference::Same(ref x) => {
- output += &format!(" {}\n", x);
- }
- Difference::Add(ref x) => {
- match diffs[i - 1] {
- Difference::Rem(ref y) => {
- output += &format!("{}", Green.paint("+"));
- let Changeset { diffs, .. } = Changeset::new(y, x, " ");
- for c in diffs {
- match c {
- Difference::Same(ref z) => {
- output += &format!("{} ", Green.paint(z.as_str()));
- }
- Difference::Add(ref z) => {
- output += &format!("{} ", Black.on(Green).paint(z.as_str()));
- }
- _ => (),
- }
- }
- output += "\n";
- }
- _ => {
- output += &format!("+{}\n", Green.paint(x.as_str()));
- }
- };
- }
- Difference::Rem(ref x) => {
- output += &format!("-{}\n", Red.paint(x.as_str()));
- }
- }
- }
- output
-}
diff --git a/vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs b/vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs
deleted file mode 100644
index 2ed990261..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs
+++ /dev/null
@@ -1,401 +0,0 @@
-use annotate_snippets::display_list::DisplayList;
-use annotate_snippets::{display_list as dl, formatter::get_term_style, snippet};
-
-#[test]
-fn test_format_title() {
- let input = snippet::Snippet {
- title: Some(snippet::Annotation {
- id: Some("E0001"),
- label: Some("This is a title"),
- annotation_type: snippet::AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![],
- opt: Default::default(),
- };
- let output = dl::DisplayList {
- body: vec![dl::DisplayLine::Raw(dl::DisplayRawLine::Annotation {
- annotation: dl::Annotation {
- annotation_type: dl::DisplayAnnotationType::Error,
- id: Some("E0001"),
- label: vec![dl::DisplayTextFragment {
- content: "This is a title",
- style: dl::DisplayTextStyle::Emphasis,
- }],
- },
- source_aligned: false,
- continuation: false,
- })],
- stylesheet: get_term_style(input.opt.color),
- anonymized_line_numbers: input.opt.anonymized_line_numbers,
- };
- assert_eq!(dl::DisplayList::from(input), output);
-}
-
-#[test]
-fn test_format_slice() {
- let line_1 = "This is line 1";
- let line_2 = "This is line 2";
- let source = vec![line_1, line_2].join("\n");
- let input = snippet::Snippet {
- title: None,
- footer: vec![],
- slices: vec![snippet::Slice {
- source: &source,
- line_start: 5402,
- origin: None,
- annotations: vec![],
- fold: false,
- }],
- opt: Default::default(),
- };
- let output = dl::DisplayList {
- body: vec![
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- dl::DisplayLine::Source {
- lineno: Some(5402),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- text: line_1,
- range: (0, line_1.len()),
- },
- },
- dl::DisplayLine::Source {
- lineno: Some(5403),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- range: (line_1.len() + 1, source.len()),
- text: line_2,
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- ],
- stylesheet: get_term_style(input.opt.color),
- anonymized_line_numbers: input.opt.anonymized_line_numbers,
- };
- assert_eq!(dl::DisplayList::from(input), output);
-}
-
-#[test]
-fn test_format_slices_continuation() {
- let src_0 = "This is slice 1";
- let src_0_len = src_0.len();
- let src_1 = "This is slice 2";
- let src_1_len = src_1.len();
- let input = snippet::Snippet {
- title: None,
- footer: vec![],
- slices: vec![
- snippet::Slice {
- source: src_0,
- line_start: 5402,
- origin: Some("file1.rs"),
- annotations: vec![],
- fold: false,
- },
- snippet::Slice {
- source: src_1,
- line_start: 2,
- origin: Some("file2.rs"),
- annotations: vec![],
- fold: false,
- },
- ],
- opt: Default::default(),
- };
- let output = dl::DisplayList {
- body: vec![
- dl::DisplayLine::Raw(dl::DisplayRawLine::Origin {
- path: "file1.rs",
- pos: None,
- header_type: dl::DisplayHeaderType::Initial,
- }),
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- dl::DisplayLine::Source {
- lineno: Some(5402),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- text: src_0,
- range: (0, src_0_len),
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- dl::DisplayLine::Raw(dl::DisplayRawLine::Origin {
- path: "file2.rs",
- pos: None,
- header_type: dl::DisplayHeaderType::Continuation,
- }),
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- dl::DisplayLine::Source {
- lineno: Some(2),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- text: src_1,
- range: (0, src_1_len),
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- ],
- stylesheet: get_term_style(input.opt.color),
- anonymized_line_numbers: input.opt.anonymized_line_numbers,
- };
- assert_eq!(dl::DisplayList::from(input), output);
-}
-
-#[test]
-fn test_format_slice_annotation_standalone() {
- let line_1 = "This is line 1";
- let line_2 = "This is line 2";
- let source = vec![line_1, line_2].join("\n");
- // In line 2
- let range = (22, 24);
- let input = snippet::Snippet {
- title: None,
- footer: vec![],
- slices: vec![snippet::Slice {
- source: &source,
- line_start: 5402,
- origin: None,
- annotations: vec![snippet::SourceAnnotation {
- range,
- label: "Test annotation",
- annotation_type: snippet::AnnotationType::Info,
- }],
- fold: false,
- }],
- opt: Default::default(),
- };
- let output = dl::DisplayList {
- body: vec![
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- dl::DisplayLine::Source {
- lineno: Some(5402),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- range: (0, line_1.len()),
- text: line_1,
- },
- },
- dl::DisplayLine::Source {
- lineno: Some(5403),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- range: (line_1.len() + 1, source.len()),
- text: line_2,
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Annotation {
- annotation: dl::Annotation {
- annotation_type: dl::DisplayAnnotationType::Info,
- id: None,
- label: vec![dl::DisplayTextFragment {
- content: "Test annotation",
- style: dl::DisplayTextStyle::Regular,
- }],
- },
- range: (range.0 - (line_1.len() + 1), range.1 - (line_1.len() + 1)),
- annotation_type: dl::DisplayAnnotationType::Info,
- annotation_part: dl::DisplayAnnotationPart::Standalone,
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- ],
- stylesheet: get_term_style(input.opt.color),
- anonymized_line_numbers: input.opt.anonymized_line_numbers,
- };
- assert_eq!(dl::DisplayList::from(input), output);
-}
-
-#[test]
-fn test_format_label() {
- let input = snippet::Snippet {
- title: None,
- footer: vec![snippet::Annotation {
- id: None,
- label: Some("This __is__ a title"),
- annotation_type: snippet::AnnotationType::Error,
- }],
- slices: vec![],
- opt: Default::default(),
- };
- let output = dl::DisplayList {
- body: vec![dl::DisplayLine::Raw(dl::DisplayRawLine::Annotation {
- annotation: dl::Annotation {
- annotation_type: dl::DisplayAnnotationType::Error,
- id: None,
- label: vec![
- dl::DisplayTextFragment {
- content: "This ",
- style: dl::DisplayTextStyle::Regular,
- },
- dl::DisplayTextFragment {
- content: "is",
- style: dl::DisplayTextStyle::Emphasis,
- },
- dl::DisplayTextFragment {
- content: " a title",
- style: dl::DisplayTextStyle::Regular,
- },
- ],
- },
- source_aligned: true,
- continuation: false,
- })],
- stylesheet: get_term_style(input.opt.color),
- anonymized_line_numbers: input.opt.anonymized_line_numbers,
- };
- assert_eq!(dl::DisplayList::from(input), output);
-}
-
-#[test]
-#[should_panic]
-fn test_i26() {
- let source = "short";
- let label = "label";
- let input = snippet::Snippet {
- title: None,
- footer: vec![],
- slices: vec![snippet::Slice {
- annotations: vec![snippet::SourceAnnotation {
- range: (0, source.len() + 1),
- label,
- annotation_type: snippet::AnnotationType::Error,
- }],
- source,
- line_start: 0,
- origin: None,
- fold: false,
- }],
- opt: Default::default(),
- };
-
- let _ = dl::DisplayList::from(input);
-}
-
-#[test]
-fn test_i_29() {
- let snippets = snippet::Snippet {
- title: Some(snippet::Annotation {
- id: None,
- label: Some("oops"),
- annotation_type: snippet::AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![snippet::Slice {
- source: "First line\r\nSecond oops line",
- line_start: 1,
- origin: Some("<current file>"),
- annotations: vec![snippet::SourceAnnotation {
- range: (19, 23),
- label: "oops",
- annotation_type: snippet::AnnotationType::Error,
- }],
- fold: true,
- }],
- opt: Default::default(),
- };
-
- let expected = DisplayList {
- body: vec![
- dl::DisplayLine::Raw(dl::DisplayRawLine::Annotation {
- annotation: dl::Annotation {
- annotation_type: dl::DisplayAnnotationType::Error,
- id: None,
- label: vec![dl::DisplayTextFragment {
- content: "oops",
- style: dl::DisplayTextStyle::Emphasis,
- }],
- },
- source_aligned: false,
- continuation: false,
- }),
- dl::DisplayLine::Raw(dl::DisplayRawLine::Origin {
- path: "<current file>",
- pos: Some((2, 8)),
- header_type: dl::DisplayHeaderType::Initial,
- }),
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- dl::DisplayLine::Source {
- lineno: Some(1),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- text: "First line",
- range: (0, 10),
- },
- },
- dl::DisplayLine::Source {
- lineno: Some(2),
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Content {
- text: "Second oops line",
- range: (12, 28),
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Annotation {
- annotation: dl::Annotation {
- annotation_type: dl::DisplayAnnotationType::None,
- id: None,
- label: vec![dl::DisplayTextFragment {
- content: "oops",
- style: dl::DisplayTextStyle::Regular,
- }],
- },
- range: (7, 11),
- annotation_type: dl::DisplayAnnotationType::Error,
- annotation_part: dl::DisplayAnnotationPart::Standalone,
- },
- },
- dl::DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: dl::DisplaySourceLine::Empty,
- },
- ],
- stylesheet: get_term_style(false),
- anonymized_line_numbers: false,
- };
-
- assert_eq!(DisplayList::from(snippets), expected);
-}
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml
deleted file mode 100644
index bdb577f46..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml
+++ /dev/null
@@ -1,40 +0,0 @@
-[[slices]]
-source = """
-) -> Option<String> {
- for ann in annotations {
- match (ann.range.0, ann.range.1) {
- (None, None) => continue,
- (Some(start), Some(end)) if start > end_index || end < start_index => continue,
- (Some(start), Some(end)) if start >= start_index && end <= end_index => {
- let label = if let Some(ref label) = ann.label {
- format!(" {}", label)
- } else {
- String::from("")
- };
-
- return Some(format!(
- "{}{}{}",
- " ".repeat(start - start_index),
- "^".repeat(end - start),
- label
- ));
- }
- _ => continue,
- }
- }
-"""
-line_start = 51
-origin = "src/format.rs"
-fold = true
-[[slices.annotations]]
-label = "expected `std::option::Option<std::string::String>` because of return type"
-annotation_type = "Warning"
-range = [5, 19]
-[[slices.annotations]]
-label = "expected enum `std::option::Option`, found ()"
-annotation_type = "Error"
-range = [22, 765]
-[title]
-label = "mismatched types"
-id = "E0308"
-annotation_type = "Error"
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt
deleted file mode 100644
index bacdec10d..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
- --> src/format.rs:51:6
- |
-51 | ) -> Option<String> {
- | -------------- expected `std::option::Option<std::string::String>` because of return type
-52 | / for ann in annotations {
-53 | | match (ann.range.0, ann.range.1) {
-54 | | (None, None) => continue,
-55 | | (Some(start), Some(end)) if start > end_index || end < start_index => continue,
-... |
-71 | | }
-72 | | }
- | |_____^ expected enum `std::option::Option`, found ()
- |
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml
deleted file mode 100644
index 6ec0b1fe8..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[[slices]]
-source = """
- if let DisplayLine::Source {
- ref mut inline_marks,
- } = body[body_idx]
-"""
-line_start = 139
-origin = "src/display_list.rs"
-fold = false
-[[slices.annotations]]
-label = "missing fields `lineno`, `content`"
-annotation_type = "Error"
-range = [31, 127]
-
-[title]
-label = "pattern does not mention fields `lineno`, `content`"
-id = "E0027"
-annotation_type = "Error"
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt
deleted file mode 100644
index 8a00bfa20..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0027]: pattern does not mention fields `lineno`, `content`
- --> src/display_list.rs:139:32
- |
-139 | if let DisplayLine::Source {
- | ________________________________^
-140 | | ref mut inline_marks,
-141 | | } = body[body_idx]
- | |_________________________^ missing fields `lineno`, `content`
- |
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml
deleted file mode 100644
index 21bbcd857..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[[slices]]
-source = """
-This is an exampl
-e of an edge case of an annotation overflowing
-to exactly one character on next line.
-"""
-line_start = 26
-origin = "foo.txt"
-fold = false
-[[slices.annotations]]
-label = "this should not be on separate lines"
-annotation_type = "Error"
-range = [11, 18]
-
-[title]
-label = "spacing error found"
-id = "E####"
-annotation_type = "Error"
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt
deleted file mode 100644
index 12e174c56..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E####]: spacing error found
- --> foo.txt:26:12
- |
-26 | This is an exampl
- | ____________^
-27 | | e of an edge case of an annotation overflowing
- | |_^ this should not be on separate lines
-28 | to exactly one character on next line.
- | \ No newline at end of file
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml
deleted file mode 100644
index 84efc5f17..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-[[slices]]
-source = """
-fn add_title_line(result: &mut Vec<String>, main_annotation: Option<&Annotation>) {
- if let Some(annotation) = main_annotation {
- result.push(format_title_line(
- &annotation.annotation_type,
- None,
- &annotation.label,
- ));
- }
-}
-"""
-line_start = 96
-[[slices.annotations]]
-label = "Variable defined here"
-annotation_type = "Error"
-range = [100, 110]
-[[slices.annotations]]
-label = "Referenced here"
-annotation_type = "Error"
-range = [184, 194]
-[[slices.annotations]]
-label = "Referenced again here"
-annotation_type = "Error"
-range = [243, 253]
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt
deleted file mode 100644
index 26c677f7e..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt
+++ /dev/null
@@ -1,14 +0,0 @@
- |
- 96 | fn add_title_line(result: &mut Vec<String>, main_annotation: Option<&Annotation>) {
- 97 | if let Some(annotation) = main_annotation {
- | ^^^^^^^^^^ Variable defined here
- 98 | result.push(format_title_line(
- 99 | &annotation.annotation_type,
- | ^^^^^^^^^^ Referenced here
-100 | None,
-101 | &annotation.label,
- | ^^^^^^^^^^ Referenced again here
-102 | ));
-103 | }
-104 | }
- |
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml
deleted file mode 100644
index 6c38674ac..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[[slices]]
-source = """
- })
-
- for line in &self.body {"""
-line_start = 169
-origin = "src/format_color.rs"
-[[slices.annotations]]
-label = "unexpected token"
-annotation_type = "Error"
-range = [20, 23]
-[[slices.annotations]]
-label = "expected one of `.`, `;`, `?`, or an operator here"
-annotation_type = "Warning"
-range = [10, 11]
-[title]
-label = "expected one of `.`, `;`, `?`, or an operator, found `for`"
-annotation_type = "Error"
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt
deleted file mode 100644
index 752cc890f..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-error: expected one of `.`, `;`, `?`, or an operator, found `for`
- --> src/format_color.rs:171:9
- |
-169 | })
- | - expected one of `.`, `;`, `?`, or an operator here
-170 |
-171 | for line in &self.body {
- | ^^^ unexpected token
- |
diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs b/vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs
deleted file mode 100644
index e471521f2..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-mod diff;
-mod snippet;
-
-use crate::snippet::SnippetDef;
-use annotate_snippets::{display_list::DisplayList, snippet::Snippet};
-use glob::glob;
-use std::{error::Error, fs::File, io, io::prelude::*};
-
-fn read_file(path: &str) -> Result<String, io::Error> {
- let mut f = File::open(path)?;
- let mut s = String::new();
- (f.read_to_string(&mut s))?;
- Ok(s.trim_end().to_string())
-}
-
-fn read_fixture<'de>(src: &'de str) -> Result<Snippet<'de>, Box<dyn Error>> {
- Ok(toml::from_str(src).map(|a: SnippetDef| a.into())?)
-}
-
-#[test]
-fn test_fixtures() {
- for entry in glob("./tests/fixtures/no-color/**/*.toml").expect("Failed to read glob pattern") {
- let p = entry.expect("Error while getting an entry");
-
- let path_in = p.to_str().expect("Can't print path");
- let path_out = path_in.replace(".toml", ".txt");
-
- let src = read_file(&path_in).expect("Failed to read file");
- let snippet = read_fixture(&src).expect("Failed to read file");
- let expected_out = read_file(&path_out).expect("Failed to read file");
-
- let dl = DisplayList::from(snippet);
- let actual_out = dl.to_string();
- println!("{}", expected_out);
- println!("{}", actual_out.trim_end());
-
- assert_eq!(
- expected_out,
- actual_out.trim_end(),
- "\n\n\nWhile parsing: {}\nThe diff is:\n\n\n{}\n\n\n",
- path_in,
- diff::get_diff(expected_out.as_str(), actual_out.as_str())
- );
- }
-}
diff --git a/vendor/annotate-snippets-0.8.0/tests/formatter.rs b/vendor/annotate-snippets-0.8.0/tests/formatter.rs
deleted file mode 100644
index 5c7211d1e..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/formatter.rs
+++ /dev/null
@@ -1,552 +0,0 @@
-use annotate_snippets::display_list::*;
-use annotate_snippets::snippet::{self, Snippet};
-
-#[test]
-fn test_source_empty() {
- let dl = DisplayList::from(vec![DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Empty,
- }]);
-
- assert_eq!(dl.to_string(), " |");
-}
-
-#[test]
-fn test_source_content() {
- let dl = DisplayList::from(vec![
- DisplayLine::Source {
- lineno: Some(56),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "This is an example",
- range: (0, 19),
- },
- },
- DisplayLine::Source {
- lineno: Some(57),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "of content lines",
- range: (0, 19),
- },
- },
- ]);
-
- assert_eq!(
- dl.to_string(),
- "56 | This is an example\n57 | of content lines"
- );
-}
-
-#[test]
-fn test_source_annotation_standalone_singleline() {
- let dl = DisplayList::from(vec![DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::None,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Example string",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Error,
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- }]);
-
- assert_eq!(dl.to_string(), " | ^^^^^ Example string");
-}
-
-#[test]
-fn test_source_annotation_standalone_multiline() {
- let dl = DisplayList::from(vec![
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Help,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Example string",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Warning,
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Help,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Second line",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Warning,
- annotation_part: DisplayAnnotationPart::LabelContinuation,
- },
- },
- ]);
-
- assert_eq!(
- dl.to_string(),
- " | ----- help: Example string\n | Second line"
- );
-}
-
-#[test]
-fn test_source_annotation_standalone_multi_annotation() {
- let dl = DisplayList::from(vec![
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Info,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Example string",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Note,
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Info,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Second line",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Note,
- annotation_part: DisplayAnnotationPart::LabelContinuation,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Warning,
- id: None,
- label: vec![DisplayTextFragment {
- content: "This is a note",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Note,
- annotation_part: DisplayAnnotationPart::Consequitive,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Warning,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Second line of the warning",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Note,
- annotation_part: DisplayAnnotationPart::LabelContinuation,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Info,
- id: None,
- label: vec![DisplayTextFragment {
- content: "This is an info",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Info,
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 5),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Help,
- id: None,
- label: vec![DisplayTextFragment {
- content: "This is help",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::Help,
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Annotation {
- range: (0, 0),
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::None,
- id: None,
- label: vec![DisplayTextFragment {
- content: "This is an annotation of type none",
- style: DisplayTextStyle::Regular,
- }],
- },
- annotation_type: DisplayAnnotationType::None,
- annotation_part: DisplayAnnotationPart::Standalone,
- },
- },
- ]);
-
- assert_eq!(dl.to_string(), " | ----- info: Example string\n | Second line\n | warning: This is a note\n | Second line of the warning\n | ----- info: This is an info\n | ----- help: This is help\n | This is an annotation of type none");
-}
-
-#[test]
-fn test_fold_line() {
- let dl = DisplayList::from(vec![
- DisplayLine::Source {
- lineno: Some(5),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "This is line 5",
- range: (0, 19),
- },
- },
- DisplayLine::Fold {
- inline_marks: vec![],
- },
- DisplayLine::Source {
- lineno: Some(10021),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "... and now we're at line 10021",
- range: (0, 19),
- },
- },
- ]);
-
- assert_eq!(
- dl.to_string(),
- " 5 | This is line 5\n...\n10021 | ... and now we're at line 10021"
- );
-}
-
-#[test]
-fn test_raw_origin_initial_nopos() {
- let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
- path: "src/test.rs",
- pos: None,
- header_type: DisplayHeaderType::Initial,
- })]);
-
- assert_eq!(dl.to_string(), "--> src/test.rs");
-}
-
-#[test]
-fn test_raw_origin_initial_pos() {
- let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
- path: "src/test.rs",
- pos: Some((23, 15)),
- header_type: DisplayHeaderType::Initial,
- })]);
-
- assert_eq!(dl.to_string(), "--> src/test.rs:23:15");
-}
-
-#[test]
-fn test_raw_origin_continuation() {
- let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
- path: "src/test.rs",
- pos: Some((23, 15)),
- header_type: DisplayHeaderType::Continuation,
- })]);
-
- assert_eq!(dl.to_string(), "::: src/test.rs:23:15");
-}
-
-#[test]
-fn test_raw_annotation_unaligned() {
- let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Error,
- id: Some("E0001"),
- label: vec![DisplayTextFragment {
- content: "This is an error",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: false,
- continuation: false,
- })]);
-
- assert_eq!(dl.to_string(), "error[E0001]: This is an error");
-}
-
-#[test]
-fn test_raw_annotation_unaligned_multiline() {
- let dl = DisplayList::from(vec![
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Warning,
- id: Some("E0001"),
- label: vec![DisplayTextFragment {
- content: "This is an error",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: false,
- continuation: false,
- }),
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Warning,
- id: Some("E0001"),
- label: vec![DisplayTextFragment {
- content: "Second line of the error",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: false,
- continuation: true,
- }),
- ]);
-
- assert_eq!(
- dl.to_string(),
- "warning[E0001]: This is an error\n Second line of the error"
- );
-}
-
-#[test]
-fn test_raw_annotation_aligned() {
- let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Error,
- id: Some("E0001"),
- label: vec![DisplayTextFragment {
- content: "This is an error",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: true,
- continuation: false,
- })]);
-
- assert_eq!(dl.to_string(), " = error[E0001]: This is an error");
-}
-
-#[test]
-fn test_raw_annotation_aligned_multiline() {
- let dl = DisplayList::from(vec![
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Warning,
- id: Some("E0001"),
- label: vec![DisplayTextFragment {
- content: "This is an error",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: true,
- continuation: false,
- }),
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Warning,
- id: Some("E0001"),
- label: vec![DisplayTextFragment {
- content: "Second line of the error",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: true,
- continuation: true,
- }),
- ]);
-
- assert_eq!(
- dl.to_string(),
- " = warning[E0001]: This is an error\n Second line of the error"
- );
-}
-
-#[test]
-fn test_different_annotation_types() {
- let dl = DisplayList::from(vec![
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::Note,
- id: None,
- label: vec![DisplayTextFragment {
- content: "This is a note",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: false,
- continuation: false,
- }),
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::None,
- id: None,
- label: vec![DisplayTextFragment {
- content: "This is just a string",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: false,
- continuation: false,
- }),
- DisplayLine::Raw(DisplayRawLine::Annotation {
- annotation: Annotation {
- annotation_type: DisplayAnnotationType::None,
- id: None,
- label: vec![DisplayTextFragment {
- content: "Second line of none type annotation",
- style: DisplayTextStyle::Regular,
- }],
- },
- source_aligned: false,
- continuation: true,
- }),
- ]);
-
- assert_eq!(
- dl.to_string(),
- "note: This is a note\nThis is just a string\n Second line of none type annotation",
- );
-}
-
-#[test]
-fn test_inline_marks_empty_line() {
- let dl = DisplayList::from(vec![DisplayLine::Source {
- lineno: None,
- inline_marks: vec![DisplayMark {
- mark_type: DisplayMarkType::AnnotationThrough,
- annotation_type: DisplayAnnotationType::Error,
- }],
- line: DisplaySourceLine::Empty,
- }]);
-
- assert_eq!(dl.to_string(), " | |",);
-}
-
-#[test]
-fn test_anon_lines() {
- let mut dl = DisplayList::from(vec![
- DisplayLine::Source {
- lineno: Some(56),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "This is an example",
- range: (0, 19),
- },
- },
- DisplayLine::Source {
- lineno: Some(57),
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "of content lines",
- range: (0, 19),
- },
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Empty,
- },
- DisplayLine::Source {
- lineno: None,
- inline_marks: vec![],
- line: DisplaySourceLine::Content {
- text: "abc",
- range: (0, 19),
- },
- },
- ]);
-
- dl.anonymized_line_numbers = true;
- assert_eq!(
- dl.to_string(),
- "LL | This is an example\nLL | of content lines\n |\n | abc"
- );
-}
-
-#[test]
-fn test_raw_origin_initial_pos_anon_lines() {
- let mut dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
- path: "src/test.rs",
- pos: Some((23, 15)),
- header_type: DisplayHeaderType::Initial,
- })]);
-
- // Using anonymized_line_numbers should not affect the inital position
- dl.anonymized_line_numbers = true;
- assert_eq!(dl.to_string(), "--> src/test.rs:23:15");
-}
-
-#[test]
-fn test_i_29() {
- let snippets = Snippet {
- title: Some(snippet::Annotation {
- id: None,
- label: Some("oops"),
- annotation_type: snippet::AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![snippet::Slice {
- source: "First line\r\nSecond oops line",
- line_start: 1,
- origin: Some("<current file>"),
- annotations: vec![snippet::SourceAnnotation {
- range: (19, 23),
- label: "oops",
- annotation_type: snippet::AnnotationType::Error,
- }],
- fold: true,
- }],
- opt: Default::default(),
- };
- let expected = r#"error: oops
- --> <current file>:2:8
- |
-1 | First line
-2 | Second oops line
- | ^^^^ oops
- |"#;
-
- assert_eq!(DisplayList::from(snippets).to_string(), expected);
-}
diff --git a/vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs b/vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs
deleted file mode 100644
index c3348741a..000000000
--- a/vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-use serde::{Deserialize, Deserializer, Serialize};
-
-use annotate_snippets::{
- display_list::FormatOptions,
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
-};
-
-#[derive(Deserialize)]
-pub struct SnippetDef<'a> {
- #[serde(deserialize_with = "deserialize_annotation")]
- #[serde(default)]
- #[serde(borrow)]
- pub title: Option<Annotation<'a>>,
- #[serde(deserialize_with = "deserialize_annotations")]
- #[serde(default)]
- #[serde(borrow)]
- pub footer: Vec<Annotation<'a>>,
- #[serde(deserialize_with = "deserialize_opt")]
- #[serde(default)]
- pub opt: FormatOptions,
- #[serde(deserialize_with = "deserialize_slices")]
- #[serde(borrow)]
- pub slices: Vec<Slice<'a>>,
-}
-
-impl<'a> Into<Snippet<'a>> for SnippetDef<'a> {
- fn into(self) -> Snippet<'a> {
- let SnippetDef {
- title,
- footer,
- opt,
- slices,
- } = self;
- Snippet {
- title,
- footer,
- slices,
- opt,
- }
- }
-}
-
-fn deserialize_opt<'de, D>(deserializer: D) -> Result<FormatOptions, D::Error>
-where
- D: Deserializer<'de>,
-{
- #[derive(Deserialize)]
- struct Wrapper(#[serde(with = "FormatOptionsDef")] FormatOptions);
-
- Wrapper::deserialize(deserializer).map(|w| w.0)
-}
-
-#[derive(Deserialize)]
-#[serde(remote = "FormatOptions")]
-pub struct FormatOptionsDef {
- pub color: bool,
- pub anonymized_line_numbers: bool,
-}
-
-fn deserialize_slices<'de, D>(deserializer: D) -> Result<Vec<Slice<'de>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- #[derive(Deserialize)]
- struct Wrapper<'a>(
- #[serde(with = "SliceDef")]
- #[serde(borrow)]
- Slice<'a>,
- );
-
- let v = Vec::deserialize(deserializer)?;
- Ok(v.into_iter().map(|Wrapper(a)| a).collect())
-}
-
-fn deserialize_annotation<'de, D>(deserializer: D) -> Result<Option<Annotation<'de>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- #[derive(Deserialize)]
- struct Wrapper<'a>(
- #[serde(with = "AnnotationDef")]
- #[serde(borrow)]
- Annotation<'a>,
- );
-
- Option::<Wrapper>::deserialize(deserializer)
- .map(|opt_wrapped: Option<Wrapper>| opt_wrapped.map(|wrapped: Wrapper| wrapped.0))
-}
-
-fn deserialize_annotations<'de, D>(deserializer: D) -> Result<Vec<Annotation<'de>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- #[derive(Deserialize)]
- struct Wrapper<'a>(
- #[serde(with = "AnnotationDef")]
- #[serde(borrow)]
- Annotation<'a>,
- );
-
- let v = Vec::deserialize(deserializer)?;
- Ok(v.into_iter().map(|Wrapper(a)| a).collect())
-}
-
-#[derive(Deserialize)]
-#[serde(remote = "Slice")]
-pub struct SliceDef<'a> {
- #[serde(borrow)]
- pub source: &'a str,
- pub line_start: usize,
- #[serde(borrow)]
- pub origin: Option<&'a str>,
- #[serde(deserialize_with = "deserialize_source_annotations")]
- #[serde(borrow)]
- pub annotations: Vec<SourceAnnotation<'a>>,
- #[serde(default)]
- pub fold: bool,
-}
-
-fn deserialize_source_annotations<'de, D>(
- deserializer: D,
-) -> Result<Vec<SourceAnnotation<'de>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- #[derive(Deserialize)]
- struct Wrapper<'a>(
- #[serde(with = "SourceAnnotationDef")]
- #[serde(borrow)]
- SourceAnnotation<'a>,
- );
-
- let v = Vec::deserialize(deserializer)?;
- Ok(v.into_iter().map(|Wrapper(a)| a).collect())
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "SourceAnnotation")]
-pub struct SourceAnnotationDef<'a> {
- pub range: (usize, usize),
- #[serde(borrow)]
- pub label: &'a str,
- #[serde(with = "AnnotationTypeDef")]
- pub annotation_type: AnnotationType,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Annotation")]
-pub struct AnnotationDef<'a> {
- #[serde(borrow)]
- pub id: Option<&'a str>,
- #[serde(borrow)]
- pub label: Option<&'a str>,
- #[serde(with = "AnnotationTypeDef")]
- pub annotation_type: AnnotationType,
-}
-
-#[allow(dead_code)]
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "AnnotationType")]
-enum AnnotationTypeDef {
- Error,
- Warning,
- Info,
- Note,
- Help,
-}
diff --git a/vendor/anyhow/.cargo-checksum.json b/vendor/anyhow/.cargo-checksum.json
index 7b37c5570..5bbee7b7b 100644
--- a/vendor/anyhow/.cargo-checksum.json
+++ b/vendor/anyhow/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"b83515ea98aa6ba603307c3629b86b0ad85e3017df8fe9f444c4bc8e0fc18c03","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4bd4d352368ac0f5447031d82454490f6ac0c80d2fa4cb64ba0c23c614670d49","build.rs":"f82a81a4c16e3b68140e10c3d3a9ee54af48c53133a1d894fbb92190f09f0550","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/backtrace.rs":"5a60bd1fe1717c044c7ab34c062ce6651c0cb08596a5878e391c2755ecac07f9","src/chain.rs":"6edefc5f3c7d69683095862e54e3bb56faba5b3387bf2eeaed429da090007a0a","src/context.rs":"559478ae785ce913523aa21358cc1561ef4b0b95c5c87675a77890364c0162fe","src/ensure.rs":"ba404f1708d41a267f8678858aebefadc8fae717bd5533e5ebb47e219aa44f7e","src/error.rs":"6c5b1357eedd6f2be1fdaee1be645a33e68c945c481d6ff20b98c8fdedea687a","src/fmt.rs":"c2d4aad6ce20625a70a7c091e3087b6a2c19a4a87c7a12edb4c98978307245ea","src/kind.rs":"b21b15dbee77d50abe88684a9571b39659076465dd4b1956f366af8fdd26e95a","src/lib.rs":"b340e18f5666d53289ce3428054e9789009cf60ea3e9ff717b3a4028fbaba6c2","src/macros.rs":"4ff9a40d7ff06cc02b387f40d6ae296990493cd7f9755880c621c47e7e845f07","src/ptr.rs":"f4e28bc9feba1e84160ca9d185008a51b5d72e168e6546f3e942f4258c361e19","src/wrapper.rs":"1229beca67dbd95ca77c9ecce282272acc55276c267c58cb73a75388b4693dda","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"08c3e553c1cc0d2dbd936fc45f4b5b1105057186affd6865e8d261e05f0f0646","tests/test_autotrait.rs":"981e792db353be2f14c7a1cabe43b5f1329c168cb7679077cc2be786a0920d48","tests/test_backtrace.rs":"0e50edbb33b6bd07ba89ff3db72fb7c688ba2a4371fccdbbb20309ab02948b6a","tests/test_boxed.rs":"6b26db0e2eb72afe9af7352ea820837aab90f8d486294616dd5dc34c1b94038c","tests/test_chain.rs":"d5e90e3eba58abc60d241d3aade39e0b8d4006d9a14f3cf015d3d925160b5812","tests/test_context.rs":"8409c53b328562c11e822bd6c3cd17e0d4d50b9bbb8fc3617333fd77303a6a33","tests/test_convert.rs":"7e7a8b4772a427a911014ac4d1083f9519000e786177f898808980dd9bdfde61","tests/test_downcast.rs":"797e69a72d125758c4c4897e5dc776d549d52cc9a6a633e0a33193f588a62b88","tests/test_ensure.rs":"bd793da08a4d01b8211646d82bec73468e54f6caf5f520617519a12cbb6659b9","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"11f05010bc9b16319884c1286444100e30cddc2ecd1ffe5e0fd3fee5ffb32683","tests/test_repr.rs":"dbb9b04ddbe1ab31eb5331ea69f05bb3a147299da2275a3d4dcc92947b5591b9","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/chained-comparison.rs":"6504b03d95b5acc232a7f4defc9f343b2be6733bf475fa0992e8e6545b912bd4","tests/ui/chained-comparison.stderr":"7f1d0a8c251b0ede2d30b3087ec157fc660945c97a642c4a5acf5a14ec58de34","tests/ui/empty-ensure.rs":"ab5bf37c846a0d689f26ce9257a27228411ed64154f9c950f1602d88a355d94b","tests/ui/empty-ensure.stderr":"345102cbef47310f2f4066a669199873a627ca4f1fcb885505c6e17d1fc95e88","tests/ui/must-use.rs":"fb59860b43f673bf4a430a6036ba463e95028844d8dd4243cfe5ebc7f2be582f","tests/ui/must-use.stderr":"4dc15f52c3a186251c948b6a2955b777ed3c88e5da94b887f8ff945b3ecd8cee","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"39d3234c0cbb6213a422485cd1bf64b0877d2b2ea3e168b099bc8a6c1e0d33df","tests/ui/temporary-value.rs":"4dcc96271b2403e6372cf4cfc813445e5ce4365fc6e156b6bc38274098499a70","tests/ui/temporary-value.stderr":"64e448b6759cf51d41b1360307a638452bbe53ffa706f93e4a503b712d7b89a8","tests/ui/wrong-interpolation.rs":"9c44d4674c2dccd27b9dedd03341346ec02d993b41793ee89b5755202e7e367e","tests/ui/wrong-interpolation.stderr":"301e60e2eb9401782c7dc0b3580613a4cb2aafd4cc8065734a630a62e1161aa5"},"package":"c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"} \ No newline at end of file
+{"files":{"Cargo.toml":"5779c6bea2555cdabd4560de187ac5e3c88ff2df8172077397643edc51c6fcc3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4bd4d352368ac0f5447031d82454490f6ac0c80d2fa4cb64ba0c23c614670d49","build.rs":"88bf7100143c79c0af683da7f28deaac031c9b9b213a6426560dc089b0ba45aa","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/backtrace.rs":"5b4103a7d24d6f438a64b8cc0fafe28d55fc0ca090368174ce44d64e3940badd","src/chain.rs":"6edefc5f3c7d69683095862e54e3bb56faba5b3387bf2eeaed429da090007a0a","src/context.rs":"0bb1566aae147d393796dd6ede6ba329916e0a373b7cbc38335c3eeeb3d48b57","src/ensure.rs":"498bc9c7fb8b93168ed12f532cb97df6ccdda9ce25371586d7f5b1b1c98a14bf","src/error.rs":"e45d4dcfe64b1823b42fbf9bb260e6437987e8c2d51f92434db9d808b36e700a","src/fmt.rs":"c2d4aad6ce20625a70a7c091e3087b6a2c19a4a87c7a12edb4c98978307245ea","src/kind.rs":"332854c5eb07d44447c356a2e7dc585634b0da1ffbbfa81269c369deaefbc247","src/lib.rs":"82011e86fb9b41fe10ab2fde2b797b4858e697e7ead3a5f0d30b018357f1721d","src/macros.rs":"dd35f2ec2a0a25e4504fb04bcd42f6d0963bc0035aaaefc412f5ee1d78945fe1","src/ptr.rs":"f4e28bc9feba1e84160ca9d185008a51b5d72e168e6546f3e942f4258c361e19","src/wrapper.rs":"ff3ad72065a30cc32e9acb0614a30703c49c57b941a335c348b6439af684316b","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"08c3e553c1cc0d2dbd936fc45f4b5b1105057186affd6865e8d261e05f0f0646","tests/test_autotrait.rs":"981e792db353be2f14c7a1cabe43b5f1329c168cb7679077cc2be786a0920d48","tests/test_backtrace.rs":"0e50edbb33b6bd07ba89ff3db72fb7c688ba2a4371fccdbbb20309ab02948b6a","tests/test_boxed.rs":"6b26db0e2eb72afe9af7352ea820837aab90f8d486294616dd5dc34c1b94038c","tests/test_chain.rs":"d5e90e3eba58abc60d241d3aade39e0b8d4006d9a14f3cf015d3d925160b5812","tests/test_context.rs":"8409c53b328562c11e822bd6c3cd17e0d4d50b9bbb8fc3617333fd77303a6a33","tests/test_convert.rs":"7e7a8b4772a427a911014ac4d1083f9519000e786177f898808980dd9bdfde61","tests/test_downcast.rs":"797e69a72d125758c4c4897e5dc776d549d52cc9a6a633e0a33193f588a62b88","tests/test_ensure.rs":"c8137a9565685aedf02b365008b27c707f4c3d81cd2b986b3b7105b426c723b1","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"11f05010bc9b16319884c1286444100e30cddc2ecd1ffe5e0fd3fee5ffb32683","tests/test_repr.rs":"dbb9b04ddbe1ab31eb5331ea69f05bb3a147299da2275a3d4dcc92947b5591b9","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/chained-comparison.rs":"6504b03d95b5acc232a7f4defc9f343b2be6733bf475fa0992e8e6545b912bd4","tests/ui/chained-comparison.stderr":"7f1d0a8c251b0ede2d30b3087ec157fc660945c97a642c4a5acf5a14ec58de34","tests/ui/empty-ensure.rs":"ab5bf37c846a0d689f26ce9257a27228411ed64154f9c950f1602d88a355d94b","tests/ui/empty-ensure.stderr":"345102cbef47310f2f4066a669199873a627ca4f1fcb885505c6e17d1fc95e88","tests/ui/must-use.rs":"fb59860b43f673bf4a430a6036ba463e95028844d8dd4243cfe5ebc7f2be582f","tests/ui/must-use.stderr":"c2848c5f254b4c061eea6714d9baf709924aba06619eaf2a8b3aee1266b75f9e","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"9d36a96220f0b5a81db027bcba411a61a72cc2e370c38058ab556442e8bb8a8b","tests/ui/temporary-value.rs":"4dcc96271b2403e6372cf4cfc813445e5ce4365fc6e156b6bc38274098499a70","tests/ui/temporary-value.stderr":"64e448b6759cf51d41b1360307a638452bbe53ffa706f93e4a503b712d7b89a8","tests/ui/wrong-interpolation.rs":"9c44d4674c2dccd27b9dedd03341346ec02d993b41793ee89b5755202e7e367e","tests/ui/wrong-interpolation.stderr":"301e60e2eb9401782c7dc0b3580613a4cb2aafd4cc8065734a630a62e1161aa5"},"package":"98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"} \ No newline at end of file
diff --git a/vendor/anyhow/Cargo.toml b/vendor/anyhow/Cargo.toml
index 6537f7b5f..844c2bd3a 100644
--- a/vendor/anyhow/Cargo.toml
+++ b/vendor/anyhow/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.38"
name = "anyhow"
-version = "1.0.60"
+version = "1.0.65"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Flexible concrete Error type built on std::error::Error"
documentation = "https://docs.rs/anyhow"
diff --git a/vendor/anyhow/build.rs b/vendor/anyhow/build.rs
index c470ba11b..38006832e 100644
--- a/vendor/anyhow/build.rs
+++ b/vendor/anyhow/build.rs
@@ -15,15 +15,17 @@ compile_error! {
// type. If the current toolchain is able to compile it, we go ahead and use
// backtrace in anyhow.
const PROBE: &str = r#"
- #![feature(backtrace)]
- #![allow(dead_code)]
+ #![feature(error_generic_member_access, provide_any)]
+ use std::any::{Demand, Provider};
use std::backtrace::{Backtrace, BacktraceStatus};
use std::error::Error;
use std::fmt::{self, Display};
#[derive(Debug)]
- struct E;
+ struct E {
+ backtrace: Backtrace,
+ }
impl Display for E {
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
@@ -32,14 +34,26 @@ const PROBE: &str = r#"
}
impl Error for E {
- fn backtrace(&self) -> Option<&Backtrace> {
- let backtrace = Backtrace::capture();
- match backtrace.status() {
- BacktraceStatus::Captured | BacktraceStatus::Disabled | _ => {}
- }
- unimplemented!()
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ demand.provide_ref(&self.backtrace);
}
}
+
+ struct P;
+
+ impl Provider for P {
+ fn provide<'a>(&'a self, _demand: &mut Demand<'a>) {}
+ }
+
+ const _: fn() = || {
+ let backtrace: Backtrace = Backtrace::capture();
+ let status: BacktraceStatus = backtrace.status();
+ match status {
+ BacktraceStatus::Captured | BacktraceStatus::Disabled | _ => {}
+ }
+ };
+
+ const _: fn(&dyn Error) -> Option<&Backtrace> = |err| err.request_ref::<Backtrace>();
"#;
fn main() {
diff --git a/vendor/anyhow/src/backtrace.rs b/vendor/anyhow/src/backtrace.rs
index e4c907641..23c0c85ce 100644
--- a/vendor/anyhow/src/backtrace.rs
+++ b/vendor/anyhow/src/backtrace.rs
@@ -38,7 +38,7 @@ macro_rules! backtrace {
#[cfg(backtrace)]
macro_rules! backtrace_if_absent {
($err:expr) => {
- match $err.backtrace() {
+ match ($err as &dyn std::error::Error).request_ref::<std::backtrace::Backtrace>() {
Some(_) => None,
None => backtrace!(),
}
diff --git a/vendor/anyhow/src/context.rs b/vendor/anyhow/src/context.rs
index c2284130f..1b7dd31ac 100644
--- a/vendor/anyhow/src/context.rs
+++ b/vendor/anyhow/src/context.rs
@@ -4,7 +4,7 @@ use core::convert::Infallible;
use core::fmt::{self, Debug, Display, Write};
#[cfg(backtrace)]
-use std::backtrace::Backtrace;
+use std::any::Demand;
mod ext {
use super::*;
@@ -24,7 +24,7 @@ mod ext {
where
C: Display + Send + Sync + 'static,
{
- let backtrace = backtrace_if_absent!(self);
+ let backtrace = backtrace_if_absent!(&self);
Error::from_context(context, self, backtrace)
}
}
@@ -123,28 +123,29 @@ where
C: Display,
E: StdError + 'static,
{
- #[cfg(backtrace)]
- fn backtrace(&self) -> Option<&Backtrace> {
- self.error.backtrace()
- }
-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
Some(&self.error)
}
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ self.error.provide(demand);
+ }
}
impl<C> StdError for ContextError<C, Error>
where
C: Display,
{
- #[cfg(backtrace)]
- fn backtrace(&self) -> Option<&Backtrace> {
- Some(self.error.backtrace())
- }
-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
}
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ demand.provide_ref(self.error.backtrace());
+ self.error.provide(demand);
+ }
}
struct Quoted<C>(C);
diff --git a/vendor/anyhow/src/ensure.rs b/vendor/anyhow/src/ensure.rs
index 80bdab704..0ab447123 100644
--- a/vendor/anyhow/src/ensure.rs
+++ b/vendor/anyhow/src/ensure.rs
@@ -788,15 +788,15 @@ macro_rules! __fancy_ensure {
(lhs, rhs) => {
if !(lhs $op rhs) {
#[allow(unused_imports)]
- use $crate::private::{BothDebug, NotBothDebug};
+ use $crate::__private::{BothDebug, NotBothDebug};
return Err((lhs, rhs).__dispatch_ensure(
- $crate::private::concat!(
+ $crate::__private::concat!(
"Condition failed: `",
- $crate::private::stringify!($lhs),
+ $crate::__private::stringify!($lhs),
" ",
- $crate::private::stringify!($op),
+ $crate::__private::stringify!($op),
" ",
- $crate::private::stringify!($rhs),
+ $crate::__private::stringify!($rhs),
"`",
),
));
@@ -811,24 +811,24 @@ macro_rules! __fancy_ensure {
macro_rules! __fallback_ensure {
($cond:expr $(,)?) => {
if !$cond {
- return $crate::private::Err($crate::Error::msg(
- $crate::private::concat!("Condition failed: `", $crate::private::stringify!($cond), "`")
+ return $crate::__private::Err($crate::Error::msg(
+ $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`")
));
}
};
($cond:expr, $msg:literal $(,)?) => {
if !$cond {
- return $crate::private::Err($crate::__anyhow!($msg));
+ return $crate::__private::Err($crate::__anyhow!($msg));
}
};
($cond:expr, $err:expr $(,)?) => {
if !$cond {
- return $crate::private::Err($crate::__anyhow!($err));
+ return $crate::__private::Err($crate::__anyhow!($err));
}
};
($cond:expr, $fmt:expr, $($arg:tt)*) => {
if !$cond {
- return $crate::private::Err($crate::__anyhow!($fmt, $($arg)*));
+ return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*));
}
};
}
diff --git a/vendor/anyhow/src/error.rs b/vendor/anyhow/src/error.rs
index 0971146c9..9f6ce8c10 100644
--- a/vendor/anyhow/src/error.rs
+++ b/vendor/anyhow/src/error.rs
@@ -5,6 +5,8 @@ use crate::ptr::Mut;
use crate::ptr::{Own, Ref};
use crate::{Error, StdError};
use alloc::boxed::Box;
+#[cfg(backtrace)]
+use core::any::Demand;
use core::any::TypeId;
use core::fmt::{self, Debug, Display};
use core::mem::ManuallyDrop;
@@ -31,7 +33,7 @@ impl Error {
where
E: StdError + Send + Sync + 'static,
{
- let backtrace = backtrace_if_absent!(error);
+ let backtrace = backtrace_if_absent!(&error);
Error::from_std(error, backtrace)
}
@@ -522,6 +524,18 @@ impl Error {
}
}
+#[cfg(backtrace)]
+impl std::any::Provider for Error {
+ // Called by thiserror when you have `#[source] anyhow::Error`. This provide
+ // implementation includes the anyhow::Error's Backtrace if any, unlike
+ // deref'ing to dyn Error where the provide implementation would include
+ // only the original error's Backtrace from before it got wrapped into an
+ // anyhow::Error.
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ unsafe { ErrorImpl::provide(self.inner.by_ref(), demand) }
+ }
+}
+
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl<E> From<E> for Error
@@ -530,7 +544,7 @@ where
{
#[cold]
fn from(error: E) -> Self {
- let backtrace = backtrace_if_absent!(error);
+ let backtrace = backtrace_if_absent!(&error);
Error::from_std(error, backtrace)
}
}
@@ -886,13 +900,21 @@ impl ErrorImpl {
.as_ref()
.or_else(|| {
#[cfg(backtrace)]
- return Self::error(this).backtrace();
- #[cfg(all(not(backtrace), feature = "backtrace"))]
+ return Self::error(this).request_ref::<Backtrace>();
+ #[cfg(not(backtrace))]
return (vtable(this.ptr).object_backtrace)(this);
})
.expect("backtrace capture failed")
}
+ #[cfg(backtrace)]
+ unsafe fn provide<'a>(this: Ref<'a, Self>, demand: &mut Demand<'a>) {
+ if let Some(backtrace) = &this.deref().backtrace {
+ demand.provide_ref(backtrace);
+ }
+ Self::error(this).provide(demand);
+ }
+
#[cold]
pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
Chain::new(Self::error(this))
@@ -903,14 +925,14 @@ impl<E> StdError for ErrorImpl<E>
where
E: StdError,
{
- #[cfg(backtrace)]
- fn backtrace(&self) -> Option<&Backtrace> {
- Some(unsafe { ErrorImpl::backtrace(self.erase()) })
- }
-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
unsafe { ErrorImpl::error(self.erase()).source() }
}
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ unsafe { ErrorImpl::provide(self.erase(), demand) }
+ }
}
impl<E> Debug for ErrorImpl<E>
diff --git a/vendor/anyhow/src/kind.rs b/vendor/anyhow/src/kind.rs
index 59857057d..f47fe44ba 100644
--- a/vendor/anyhow/src/kind.rs
+++ b/vendor/anyhow/src/kind.rs
@@ -40,7 +40,7 @@
// The anyhow! macro will set up the call in this form:
//
// #[allow(unused_imports)]
-// use $crate::private::{AdhocKind, TraitKind};
+// use $crate::__private::{AdhocKind, TraitKind};
// let error = $msg;
// (&error).anyhow_kind().new(error)
@@ -110,7 +110,7 @@ impl BoxedKind for Box<dyn StdError + Send + Sync> {}
impl Boxed {
#[cold]
pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Error {
- let backtrace = backtrace_if_absent!(error);
+ let backtrace = backtrace_if_absent!(&*error);
Error::from_boxed(error, backtrace)
}
}
diff --git a/vendor/anyhow/src/lib.rs b/vendor/anyhow/src/lib.rs
index 976668aab..792a4d007 100644
--- a/vendor/anyhow/src/lib.rs
+++ b/vendor/anyhow/src/lib.rs
@@ -210,8 +210,8 @@
//! will require an explicit `.map_err(Error::msg)` when working with a
//! non-Anyhow error type inside a function that returns Anyhow's error type.
-#![doc(html_root_url = "https://docs.rs/anyhow/1.0.60")]
-#![cfg_attr(backtrace, feature(backtrace))]
+#![doc(html_root_url = "https://docs.rs/anyhow/1.0.65")]
+#![cfg_attr(backtrace, feature(error_generic_member_access, provide_any))]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(dead_code, unused_imports, unused_mut)]
@@ -634,7 +634,7 @@ pub fn Ok<T>(t: T) -> Result<T> {
// Not public API. Referenced by macro-generated code.
#[doc(hidden)]
-pub mod private {
+pub mod __private {
use crate::Error;
use alloc::fmt;
use core::fmt::Arguments;
diff --git a/vendor/anyhow/src/macros.rs b/vendor/anyhow/src/macros.rs
index 5dc138386..6dd22743b 100644
--- a/vendor/anyhow/src/macros.rs
+++ b/vendor/anyhow/src/macros.rs
@@ -55,13 +55,13 @@
#[macro_export]
macro_rules! bail {
($msg:literal $(,)?) => {
- return $crate::private::Err($crate::__anyhow!($msg))
+ return $crate::__private::Err($crate::__anyhow!($msg))
};
($err:expr $(,)?) => {
- return $crate::private::Err($crate::__anyhow!($err))
+ return $crate::__private::Err($crate::__anyhow!($err))
};
($fmt:expr, $($arg:tt)*) => {
- return $crate::private::Err($crate::__anyhow!($fmt, $($arg)*))
+ return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*))
};
}
@@ -120,24 +120,24 @@ macro_rules! bail {
macro_rules! ensure {
($cond:expr $(,)?) => {
if !$cond {
- return $crate::private::Err($crate::Error::msg(
- $crate::private::concat!("Condition failed: `", $crate::private::stringify!($cond), "`")
+ return $crate::__private::Err($crate::Error::msg(
+ $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`")
));
}
};
($cond:expr, $msg:literal $(,)?) => {
if !$cond {
- return $crate::private::Err($crate::__anyhow!($msg));
+ return $crate::__private::Err($crate::__anyhow!($msg));
}
};
($cond:expr, $err:expr $(,)?) => {
if !$cond {
- return $crate::private::Err($crate::__anyhow!($err));
+ return $crate::__private::Err($crate::__anyhow!($err));
}
};
($cond:expr, $fmt:expr, $($arg:tt)*) => {
if !$cond {
- return $crate::private::Err($crate::__anyhow!($fmt, $($arg)*));
+ return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*));
}
};
}
@@ -189,14 +189,14 @@ macro_rules! ensure {
#[macro_export]
macro_rules! anyhow {
($msg:literal $(,)?) => {
- $crate::private::must_use({
- let error = $crate::private::format_err($crate::private::format_args!($msg));
+ $crate::__private::must_use({
+ let error = $crate::__private::format_err($crate::__private::format_args!($msg));
error
})
};
($err:expr $(,)?) => {
- $crate::private::must_use({
- use $crate::private::kind::*;
+ $crate::__private::must_use({
+ use $crate::__private::kind::*;
let error = match $err {
error => (&error).anyhow_kind().new(error),
};
@@ -204,7 +204,7 @@ macro_rules! anyhow {
})
};
($fmt:expr, $($arg:tt)*) => {
- $crate::Error::msg($crate::private::format!($fmt, $($arg)*))
+ $crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
};
}
@@ -215,17 +215,17 @@ macro_rules! anyhow {
#[macro_export]
macro_rules! __anyhow {
($msg:literal $(,)?) => ({
- let error = $crate::private::format_err($crate::private::format_args!($msg));
+ let error = $crate::__private::format_err($crate::__private::format_args!($msg));
error
});
($err:expr $(,)?) => ({
- use $crate::private::kind::*;
+ use $crate::__private::kind::*;
let error = match $err {
error => (&error).anyhow_kind().new(error),
};
error
});
($fmt:expr, $($arg:tt)*) => {
- $crate::Error::msg($crate::private::format!($fmt, $($arg)*))
+ $crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
};
}
diff --git a/vendor/anyhow/src/wrapper.rs b/vendor/anyhow/src/wrapper.rs
index 3ebe51a88..5f18a5031 100644
--- a/vendor/anyhow/src/wrapper.rs
+++ b/vendor/anyhow/src/wrapper.rs
@@ -1,6 +1,9 @@
use crate::StdError;
use core::fmt::{self, Debug, Display};
+#[cfg(backtrace)]
+use std::any::Demand;
+
#[repr(transparent)]
pub struct MessageError<M>(pub M);
@@ -67,12 +70,12 @@ impl Display for BoxedError {
#[cfg(feature = "std")]
impl StdError for BoxedError {
- #[cfg(backtrace)]
- fn backtrace(&self) -> Option<&crate::backtrace::Backtrace> {
- self.0.backtrace()
- }
-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.0.source()
}
+
+ #[cfg(backtrace)]
+ fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ self.0.provide(demand);
+ }
}
diff --git a/vendor/anyhow/tests/test_ensure.rs b/vendor/anyhow/tests/test_ensure.rs
index 4bb12f9fa..cbcba5798 100644
--- a/vendor/anyhow/tests/test_ensure.rs
+++ b/vendor/anyhow/tests/test_ensure.rs
@@ -5,9 +5,9 @@
clippy::items_after_statements,
clippy::let_and_return,
clippy::let_underscore_drop,
- clippy::logic_bug,
clippy::match_bool,
clippy::never_loop,
+ clippy::overly_complex_bool_expr,
clippy::redundant_closure_call,
clippy::redundant_pattern_matching,
clippy::too_many_lines,
diff --git a/vendor/anyhow/tests/ui/must-use.stderr b/vendor/anyhow/tests/ui/must-use.stderr
index e9ee24b09..e10bde40f 100644
--- a/vendor/anyhow/tests/ui/must-use.stderr
+++ b/vendor/anyhow/tests/ui/must-use.stderr
@@ -1,4 +1,4 @@
-error: unused return value of `anyhow::private::must_use` that must be used
+error: unused return value of `anyhow::__private::must_use` that must be used
--> tests/ui/must-use.rs:8:9
|
8 | anyhow!("it failed");
diff --git a/vendor/anyhow/tests/ui/no-impl.stderr b/vendor/anyhow/tests/ui/no-impl.stderr
index 7c5ec503f..074dafe62 100644
--- a/vendor/anyhow/tests/ui/no-impl.stderr
+++ b/vendor/anyhow/tests/ui/no-impl.stderr
@@ -19,13 +19,13 @@ error[E0599]: the method `anyhow_kind` exists for reference `&Error`, but its tr
`&Error: Into<anyhow::Error>`
which is required by `&Error: anyhow::kind::TraitKind`
note: the following traits must be implemented
- --> $RUST/core/src/convert/mod.rs
- |
- | pub trait Into<T>: Sized {
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- |
- ::: $RUST/core/src/fmt/mod.rs
+ --> $RUST/core/src/fmt/mod.rs
|
| pub trait Display {
| ^^^^^^^^^^^^^^^^^
+ |
+ ::: $RUST/core/src/convert/mod.rs
+ |
+ | pub trait Into<T>: Sized {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/block-buffer-0.7.3/.cargo-checksum.json b/vendor/block-buffer-0.7.3/.cargo-checksum.json
deleted file mode 100644
index 779d602b1..000000000
--- a/vendor/block-buffer-0.7.3/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"e4e9e182794c2185438af0c505714df9e051d1d1b17aec7a42265be672b1d027","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"d5c22aa3118d240e877ad41c5d9fa232f9c77d757d4aac0c2f943afc0a95e0ef","src/lib.rs":"59dd4084e456153bee968153ee45e34c8e853abfb756a53571c5844ccaf18c23"},"package":"c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"} \ No newline at end of file
diff --git a/vendor/block-buffer-0.7.3/Cargo.toml b/vendor/block-buffer-0.7.3/Cargo.toml
deleted file mode 100644
index 6b10954cb..000000000
--- a/vendor/block-buffer-0.7.3/Cargo.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "block-buffer"
-version = "0.7.3"
-authors = ["RustCrypto Developers"]
-description = "Fixed size buffer for block processing of data"
-documentation = "https://docs.rs/block-buffer"
-keywords = ["block", "buffer"]
-categories = ["cryptography", "no-std"]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/RustCrypto/utils"
-[dependencies.block-padding]
-version = "0.1"
-
-[dependencies.byte-tools]
-version = "0.3"
-
-[dependencies.byteorder]
-version = "1.1"
-default-features = false
-
-[dependencies.generic-array]
-version = "0.12"
-[badges.travis-ci]
-repository = "RustCrypto/utils"
diff --git a/vendor/block-buffer-0.7.3/LICENSE-APACHE b/vendor/block-buffer-0.7.3/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/block-buffer-0.7.3/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/block-buffer-0.7.3/LICENSE-MIT b/vendor/block-buffer-0.7.3/LICENSE-MIT
deleted file mode 100644
index 502cee6e8..000000000
--- a/vendor/block-buffer-0.7.3/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2018-2019 The RustCrypto Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/block-buffer-0.7.3/src/lib.rs b/vendor/block-buffer-0.7.3/src/lib.rs
deleted file mode 100644
index d3b691655..000000000
--- a/vendor/block-buffer-0.7.3/src/lib.rs
+++ /dev/null
@@ -1,210 +0,0 @@
-#![no_std]
-pub extern crate byteorder;
-pub extern crate block_padding;
-pub extern crate generic_array;
-extern crate byte_tools;
-
-use byteorder::{ByteOrder, BE};
-use byte_tools::zero;
-use block_padding::{Padding, PadError};
-use generic_array::{GenericArray, ArrayLength};
-use core::slice;
-
-/// Buffer for block processing of data
-#[derive(Clone, Default)]
-pub struct BlockBuffer<BlockSize: ArrayLength<u8>> {
- buffer: GenericArray<u8, BlockSize>,
- pos: usize,
-}
-
-#[inline(always)]
-unsafe fn cast<N: ArrayLength<u8>>(block: &[u8]) -> &GenericArray<u8, N> {
- debug_assert_eq!(block.len(), N::to_usize());
- &*(block.as_ptr() as *const GenericArray<u8, N>)
-}
-
-
-
-impl<BlockSize: ArrayLength<u8>> BlockBuffer<BlockSize> {
- /// Process data in `input` in blocks of size `BlockSize` using function `f`.
- #[inline]
- pub fn input<F>(&mut self, mut input: &[u8], mut f: F)
- where F: FnMut(&GenericArray<u8, BlockSize>)
- {
- // If there is already data in the buffer, process it if we have
- // enough to complete the chunk.
- let rem = self.remaining();
- if self.pos != 0 && input.len() >= rem {
- let (l, r) = input.split_at(rem);
- input = r;
- self.buffer[self.pos..].copy_from_slice(l);
- self.pos = 0;
- f(&self.buffer);
- }
-
- // While we have at least a full buffer size chunks's worth of data,
- // process that data without copying it into the buffer
- while input.len() >= self.size() {
- let (block, r) = input.split_at(self.size());
- input = r;
- f(unsafe { cast(block) });
- }
-
- // Copy any remaining data into the buffer.
- self.buffer[self.pos..self.pos+input.len()].copy_from_slice(input);
- self.pos += input.len();
- }
-
- /*
- /// Process data in `input` in blocks of size `BlockSize` using function `f`, which accepts
- /// slice of blocks.
- #[inline]
- pub fn input2<F>(&mut self, mut input: &[u8], mut f: F)
- where F: FnMut(&[GenericArray<u8, BlockSize>])
- {
- // If there is already data in the buffer, process it if we have
- // enough to complete the chunk.
- let rem = self.remaining();
- if self.pos != 0 && input.len() >= rem {
- let (l, r) = input.split_at(rem);
- input = r;
- self.buffer[self.pos..].copy_from_slice(l);
- self.pos = 0;
- f(slice::from_ref(&self.buffer));
- }
-
- // While we have at least a full buffer size chunks's worth of data,
- // process it data without copying into the buffer
- let n_blocks = input.len()/self.size();
- let (left, right) = input.split_at(n_blocks*self.size());
- // safe because we guarantee that `blocks` does not point outside of `input`
- let blocks = unsafe {
- slice::from_raw_parts(
- left.as_ptr() as *const GenericArray<u8, BlockSize>,
- n_blocks,
- )
- };
- f(blocks);
-
- // Copy remaining data into the buffer.
- self.buffer[self.pos..self.pos+right.len()].copy_from_slice(right);
- self.pos += right.len();
- }
- */
-
- /// Variant that doesn't flush the buffer until there's additional
- /// data to be processed. Suitable for tweakable block ciphers
- /// like Threefish that need to know whether a block is the *last*
- /// data block before processing it.
- #[inline]
- pub fn input_lazy<F>(&mut self, mut input: &[u8], mut f: F)
- where F: FnMut(&GenericArray<u8, BlockSize>)
- {
- let rem = self.remaining();
- if self.pos != 0 && input.len() > rem {
- let (l, r) = input.split_at(rem);
- input = r;
- self.buffer[self.pos..].copy_from_slice(l);
- self.pos = 0;
- f(&self.buffer);
- }
-
- while input.len() > self.size() {
- let (block, r) = input.split_at(self.size());
- input = r;
- f(unsafe { cast(block) });
- }
-
- self.buffer[self.pos..self.pos+input.len()].copy_from_slice(input);
- self.pos += input.len();
- }
-
- /// Pad buffer with `prefix` and make sure that internall buffer
- /// has at least `up_to` free bytes. All remaining bytes get
- /// zeroed-out.
- #[inline]
- fn digest_pad<F>(&mut self, up_to: usize, f: &mut F)
- where F: FnMut(&GenericArray<u8, BlockSize>)
- {
- if self.pos == self.size() {
- f(&self.buffer);
- self.pos = 0;
- }
- self.buffer[self.pos] = 0x80;
- self.pos += 1;
-
- zero(&mut self.buffer[self.pos..]);
-
- if self.remaining() < up_to {
- f(&self.buffer);
- zero(&mut self.buffer[..self.pos]);
- }
- }
-
- /// Pad message with 0x80, zeros and 64-bit message length
- /// in a byte order specified by `B`
- #[inline]
- pub fn len64_padding<B, F>(&mut self, data_len: u64, mut f: F)
- where B: ByteOrder, F: FnMut(&GenericArray<u8, BlockSize>)
- {
- // TODO: replace `F` with `impl Trait` on MSRV bump
- self.digest_pad(8, &mut f);
- let s = self.size();
- B::write_u64(&mut self.buffer[s-8..], data_len);
- f(&self.buffer);
- self.pos = 0;
- }
-
-
- /// Pad message with 0x80, zeros and 128-bit message length
- /// in the big-endian byte order
- #[inline]
- pub fn len128_padding_be<F>(&mut self, hi: u64, lo: u64, mut f: F)
- where F: FnMut(&GenericArray<u8, BlockSize>)
- {
- // TODO: on MSRV bump replace `F` with `impl Trait`, use `u128`, add `B`
- self.digest_pad(16, &mut f);
- let s = self.size();
- BE::write_u64(&mut self.buffer[s-16..s-8], hi);
- BE::write_u64(&mut self.buffer[s-8..], lo);
- f(&self.buffer);
- self.pos = 0;
- }
-
- /// Pad message with a given padding `P`
- ///
- /// Returns `PadError` if internall buffer is full, which can only happen if
- /// `input_lazy` was used.
- #[inline]
- pub fn pad_with<P: Padding>(&mut self)
- -> Result<&mut GenericArray<u8, BlockSize>, PadError>
- {
- P::pad_block(&mut self.buffer[..], self.pos)?;
- self.pos = 0;
- Ok(&mut self.buffer)
- }
-
- /// Return size of the internall buffer in bytes
- #[inline]
- pub fn size(&self) -> usize {
- BlockSize::to_usize()
- }
-
- /// Return current cursor position
- #[inline]
- pub fn position(&self) -> usize {
- self.pos
- }
-
- /// Return number of remaining bytes in the internall buffer
- #[inline]
- pub fn remaining(&self) -> usize {
- self.size() - self.pos
- }
-
- /// Reset buffer by setting cursor position to zero
- #[inline]
- pub fn reset(&mut self) {
- self.pos = 0
- }
-}
diff --git a/vendor/block-padding/.cargo-checksum.json b/vendor/block-padding/.cargo-checksum.json
deleted file mode 100644
index e80396463..000000000
--- a/vendor/block-padding/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"f895c4794f1c00f5f01376dae2b66870d939a01b9a366ee4d177b6b7ad99bd4a","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"d5c22aa3118d240e877ad41c5d9fa232f9c77d757d4aac0c2f943afc0a95e0ef","src/lib.rs":"962c90d43c7c2761b3c96fab2713ae357a7a8d2d048e37ce4f3354941ad41b97"},"package":"fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"} \ No newline at end of file
diff --git a/vendor/block-padding/Cargo.toml b/vendor/block-padding/Cargo.toml
deleted file mode 100644
index 1b1c849a8..000000000
--- a/vendor/block-padding/Cargo.toml
+++ /dev/null
@@ -1,26 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "block-padding"
-version = "0.1.5"
-authors = ["RustCrypto Developers"]
-description = "Padding and unpadding of messages divided into blocks."
-documentation = "https://docs.rs/block-padding"
-keywords = ["padding", "pkcs7", "ansix923", "iso7816"]
-categories = ["cryptography", "no-std"]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/RustCrypto/utils"
-[dependencies.byte-tools]
-version = "0.3"
-[badges.travis-ci]
-repository = "RustCrypto/utils"
diff --git a/vendor/block-padding/LICENSE-APACHE b/vendor/block-padding/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/block-padding/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/block-padding/LICENSE-MIT b/vendor/block-padding/LICENSE-MIT
deleted file mode 100644
index 502cee6e8..000000000
--- a/vendor/block-padding/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2018-2019 The RustCrypto Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/block-padding/src/lib.rs b/vendor/block-padding/src/lib.rs
deleted file mode 100644
index 5c4c8c3b6..000000000
--- a/vendor/block-padding/src/lib.rs
+++ /dev/null
@@ -1,323 +0,0 @@
-//! Padding and unpadding of messages divided into blocks.
-//!
-//! This crate provides `Padding` trait which provides padding and unpadding
-//! operations. Additionally several common padding schemes are available out
-//! of the box.
-#![no_std]
-#![doc(html_logo_url =
- "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
-extern crate byte_tools;
-
-use byte_tools::{zero, set};
-
-/// Error for indicating failed padding operation
-#[derive(Clone, Copy, Debug)]
-pub struct PadError;
-
-/// Error for indicating failed unpadding operation
-#[derive(Clone, Copy, Debug)]
-pub struct UnpadError;
-
-/// Trait for padding messages divided into blocks
-pub trait Padding {
- /// Pads `block` filled with data up to `pos`.
- ///
- /// `pos` should be inside of the block and block must not be full, i.e.
- /// `pos < block.len()` must be true. Otherwise method will return
- /// `PadError`. Some potentially irreversible padding schemes can allow
- /// padding of the full block, in this case aforementioned condition is
- /// relaxed to `pos <= block.len()`.
- fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError>;
-
- /// Pads message with length `pos` in the provided buffer.
- ///
- /// `&buf[..pos]` is perceived as the message, the buffer must contain
- /// enough leftover space for padding: `block_size - (pos % block_size)`
- /// extra bytes must be available. Otherwise method will return
- /// `PadError`.
- fn pad(buf: &mut [u8], pos: usize, block_size: usize)
- -> Result<&mut [u8], PadError>
- {
- let bs = block_size * (pos / block_size);
- if buf.len() < bs || buf.len() - bs < block_size { Err(PadError)? }
- Self::pad_block(&mut buf[bs..bs+block_size], pos - bs)?;
- Ok(&mut buf[..bs+block_size])
- }
-
- /// Unpad given `data` by truncating it according to the used padding.
- /// In case of the malformed padding will return `UnpadError`
- fn unpad(data: &[u8]) -> Result<&[u8], UnpadError>;
-}
-
-/// Pad block with zeros.
-///
-/// ```
-/// use block_padding::{ZeroPadding, Padding};
-///
-/// let msg = b"test";
-/// let n = msg.len();
-/// let mut buffer = [0xff; 16];
-/// buffer[..n].copy_from_slice(msg);
-/// let padded_msg = ZeroPadding::pad(&mut buffer, n, 8).unwrap();
-/// assert_eq!(padded_msg, b"test\x00\x00\x00\x00");
-/// assert_eq!(ZeroPadding::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{ZeroPadding, Padding};
-/// # let msg = b"test";
-/// # let n = msg.len();
-/// # let mut buffer = [0xff; 16];
-/// # buffer[..n].copy_from_slice(msg);
-/// let padded_msg = ZeroPadding::pad(&mut buffer, n, 2).unwrap();
-/// assert_eq!(padded_msg, b"test");
-/// assert_eq!(ZeroPadding::unpad(&padded_msg).unwrap(), msg);
-/// ```
-///
-/// Note that zero padding may not be reversible if the original message ends
-/// with one or more zero bytes.
-pub enum ZeroPadding{}
-
-impl Padding for ZeroPadding {
- fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> {
- if pos > block.len() { Err(PadError)? }
- zero(&mut block[pos..]);
- Ok(())
- }
-
- fn pad(buf: &mut [u8], pos: usize, block_size: usize)
- -> Result<&mut [u8], PadError>
- {
- if pos % block_size == 0 {
- Ok(&mut buf[..pos])
- } else {
- let bs = block_size * (pos / block_size);
- let be = bs + block_size;
- if buf.len() < be { Err(PadError)? }
- Self::pad_block(&mut buf[bs..be], pos - bs)?;
- Ok(&mut buf[..be])
- }
- }
-
- fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> {
- let mut n = data.len() - 1;
- while n != 0 {
- if data[n] != 0 {
- break;
- }
- n -= 1;
- }
- Ok(&data[..n+1])
- }
-}
-
-/// Pad block with bytes with value equal to the number of bytes added.
-///
-/// PKCS#7 described in the [RFC 5652](https://tools.ietf.org/html/rfc5652#section-6.3).
-///
-/// ```
-/// use block_padding::{Pkcs7, Padding};
-///
-/// let msg = b"test";
-/// let n = msg.len();
-/// let mut buffer = [0xff; 8];
-/// buffer[..n].copy_from_slice(msg);
-/// let padded_msg = Pkcs7::pad(&mut buffer, n, 8).unwrap();
-/// assert_eq!(padded_msg, b"test\x04\x04\x04\x04");
-/// assert_eq!(Pkcs7::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{Pkcs7, Padding};
-/// # let msg = b"test";
-/// # let n = msg.len();
-/// # let mut buffer = [0xff; 8];
-/// # buffer[..n].copy_from_slice(msg);
-/// let padded_msg = Pkcs7::pad(&mut buffer, n, 2).unwrap();
-/// assert_eq!(padded_msg, b"test\x02\x02");
-/// assert_eq!(Pkcs7::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{Pkcs7, Padding};
-/// let mut buffer = [0xff; 5];
-/// assert!(Pkcs7::pad(&mut buffer, 4, 2).is_err());
-/// ```
-/// ```
-/// # use block_padding::{Pkcs7, Padding};
-/// # let buffer = [0xff; 16];
-/// assert!(Pkcs7::unpad(&buffer).is_err());
-/// ```
-///
-/// In addition to conditions stated in the `Padding` trait documentation,
-/// `pad_block` will return `PadError` if `block.len() > 255`, and in case of
-/// `pad` if `block_size > 255`.
-pub enum Pkcs7{}
-
-impl Padding for Pkcs7 {
- fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> {
- if block.len() > 255 { Err(PadError)? }
- if pos >= block.len() { Err(PadError)? }
- let n = block.len() - pos;
- set(&mut block[pos..], n as u8);
- Ok(())
- }
-
- fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> {
- if data.is_empty() { Err(UnpadError)? }
- let l = data.len();
- let n = data[l-1];
- if n == 0 || n as usize > l { Err(UnpadError)? }
- for v in &data[l-n as usize..l-1] {
- if *v != n { Err(UnpadError)? }
- }
- Ok(&data[..l - n as usize])
- }
-}
-
-/// Pad block with zeros except the last byte which will be set to the number
-/// bytes.
-///
-/// ```
-/// use block_padding::{AnsiX923, Padding};
-///
-/// let msg = b"test";
-/// let n = msg.len();
-/// let mut buffer = [0xff; 16];
-/// buffer[..n].copy_from_slice(msg);
-/// let padded_msg = AnsiX923::pad(&mut buffer, n, 8).unwrap();
-/// assert_eq!(padded_msg, b"test\x00\x00\x00\x04");
-/// assert_eq!(AnsiX923::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{AnsiX923, Padding};
-/// # let msg = b"test";
-/// # let n = msg.len();
-/// # let mut buffer = [0xff; 16];
-/// # buffer[..n].copy_from_slice(msg);
-/// let padded_msg = AnsiX923::pad(&mut buffer, n, 2).unwrap();
-/// assert_eq!(padded_msg, b"test\x00\x02");
-/// assert_eq!(AnsiX923::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{AnsiX923, Padding};
-/// # let buffer = [0xff; 16];
-/// assert!(AnsiX923::unpad(&buffer).is_err());
-/// ```
-///
-/// In addition to conditions stated in the `Padding` trait documentation,
-/// `pad_block` will return `PadError` if `block.len() > 255`, and in case of
-/// `pad` if `block_size > 255`.
-pub enum AnsiX923{}
-
-impl Padding for AnsiX923 {
- fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError>{
- if block.len() > 255 { Err(PadError)? }
- if pos >= block.len() { Err(PadError)? }
- let bs = block.len();
- zero(&mut block[pos..bs-1]);
- block[bs-1] = (bs - pos) as u8;
- Ok(())
- }
-
- fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> {
- if data.is_empty() { Err(UnpadError)? }
- let l = data.len();
- let n = data[l-1] as usize;
- if n == 0 || n > l {
- return Err(UnpadError)
- }
- for v in &data[l-n..l-1] {
- if *v != 0 { Err(UnpadError)? }
- }
- Ok(&data[..l-n])
- }
-}
-
-/// Pad block with byte sequence `\x80 00...00 00`.
-///
-/// ```
-/// use block_padding::{Iso7816, Padding};
-///
-/// let msg = b"test";
-/// let n = msg.len();
-/// let mut buffer = [0xff; 16];
-/// buffer[..n].copy_from_slice(msg);
-/// let padded_msg = Iso7816::pad(&mut buffer, n, 8).unwrap();
-/// assert_eq!(padded_msg, b"test\x80\x00\x00\x00");
-/// assert_eq!(Iso7816::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{Iso7816, Padding};
-/// # let msg = b"test";
-/// # let n = msg.len();
-/// # let mut buffer = [0xff; 16];
-/// # buffer[..n].copy_from_slice(msg);
-/// let padded_msg = Iso7816::pad(&mut buffer, n, 2).unwrap();
-/// assert_eq!(padded_msg, b"test\x80\x00");
-/// assert_eq!(Iso7816::unpad(&padded_msg).unwrap(), msg);
-/// ```
-pub enum Iso7816{}
-
-impl Padding for Iso7816 {
- fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> {
- if pos >= block.len() { Err(PadError)? }
- block[pos] = 0x80;
- zero(&mut block[pos+1..]);
- Ok(())
- }
-
- fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> {
- if data.is_empty() { Err(UnpadError)? }
- let mut n = data.len() - 1;
- while n != 0 {
- if data[n] != 0 { break; }
- n -= 1;
- }
- if data[n] != 0x80 { Err(UnpadError)? }
- Ok(&data[..n])
- }
-}
-
-/// Don't pad the data. Useful for key wrapping. Padding will fail if the data cannot be
-/// fitted into blocks without padding.
-///
-/// ```
-/// use block_padding::{NoPadding, Padding};
-///
-/// let msg = b"test";
-/// let n = msg.len();
-/// let mut buffer = [0xff; 16];
-/// buffer[..n].copy_from_slice(msg);
-/// let padded_msg = NoPadding::pad(&mut buffer, n, 4).unwrap();
-/// assert_eq!(padded_msg, b"test");
-/// assert_eq!(NoPadding::unpad(&padded_msg).unwrap(), msg);
-/// ```
-/// ```
-/// # use block_padding::{NoPadding, Padding};
-/// # let msg = b"test";
-/// # let n = msg.len();
-/// # let mut buffer = [0xff; 16];
-/// # buffer[..n].copy_from_slice(msg);
-/// let padded_msg = NoPadding::pad(&mut buffer, n, 2).unwrap();
-/// assert_eq!(padded_msg, b"test");
-/// assert_eq!(NoPadding::unpad(&padded_msg).unwrap(), msg);
-/// ```
-pub enum NoPadding {}
-
-impl Padding for NoPadding {
- fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> {
- if pos % block.len() != 0 {
- Err(PadError)?
- }
- Ok(())
- }
-
- fn pad(buf: &mut [u8], pos: usize, block_size: usize) -> Result<&mut [u8], PadError> {
- if pos % block_size != 0 {
- Err(PadError)?
- }
- Ok(&mut buf[..pos])
- }
-
- fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> {
- Ok(data)
- }
-}
diff --git a/vendor/byte-tools/.cargo-checksum.json b/vendor/byte-tools/.cargo-checksum.json
deleted file mode 100644
index 36f28b52e..000000000
--- a/vendor/byte-tools/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"0542f7bd3605206297b6708b28bfff87a2ef7fa65ccab1474ddb53072600d7e1","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"d5c22aa3118d240e877ad41c5d9fa232f9c77d757d4aac0c2f943afc0a95e0ef","src/lib.rs":"c8fb45d44cae0b1094bf8cef5059827b28b490eb14a3865fa536b61241c2c8c4"},"package":"e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"} \ No newline at end of file
diff --git a/vendor/byte-tools/Cargo.toml b/vendor/byte-tools/Cargo.toml
deleted file mode 100644
index 74c6b9a0e..000000000
--- a/vendor/byte-tools/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "byte-tools"
-version = "0.3.1"
-authors = ["RustCrypto Developers"]
-description = "Bytes related utility functions"
-documentation = "https://docs.rs/byte-tools"
-keywords = ["bytes"]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/RustCrypto/utils"
diff --git a/vendor/byte-tools/LICENSE-APACHE b/vendor/byte-tools/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/byte-tools/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/byte-tools/LICENSE-MIT b/vendor/byte-tools/LICENSE-MIT
deleted file mode 100644
index 502cee6e8..000000000
--- a/vendor/byte-tools/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2018-2019 The RustCrypto Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/byte-tools/src/lib.rs b/vendor/byte-tools/src/lib.rs
deleted file mode 100644
index b4a450f9f..000000000
--- a/vendor/byte-tools/src/lib.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-#![no_std]
-use core::ptr;
-
-/// Copy bytes from `src` to `dst`
-///
-/// Panics if `src.len() < dst.len()`
-#[inline(always)]
-pub fn copy(src: &[u8], dst: &mut [u8]) {
- assert!(dst.len() >= src.len());
- unsafe {
- ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len());
- }
-}
-
-/// Zero all bytes in `dst`
-#[inline(always)]
-pub fn zero(dst: &mut [u8]) {
- unsafe {
- ptr::write_bytes(dst.as_mut_ptr(), 0, dst.len());
- }
-}
-
-/// Sets all bytes in `dst` equal to `value`
-#[inline(always)]
-pub fn set(dst: &mut [u8], value: u8) {
- unsafe {
- ptr::write_bytes(dst.as_mut_ptr(), value, dst.len());
- }
-}
diff --git a/vendor/byteorder/.cargo-checksum.json b/vendor/byteorder/.cargo-checksum.json
deleted file mode 100644
index 434cc1a16..000000000
--- a/vendor/byteorder/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"3a745d94ee9dce0d9dc638c02078cd5001d3d9d12d58b4f220c0101e32cfc16a","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"8585455e5a0e638cf5d489a21e286e93680f835cb8a13595918b5eb7c8c7f212","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"9d57556868344534de2489317e3c6bb611348ecd44438dcb982bd8d2a55a5a1b","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"a80bf3cd446c9b6c0cca3865c4de047bdf4644b74cdf696822f8ff87adfa1fca","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/io.rs":"9612530634d0e7ce9887a23836b58c0d972c1f45b05d9ada8355961567075627","src/lib.rs":"813ce6a8beafee3fd4e63325d783108aa02e8c57e412bc97580191d84082fbc9"},"package":"14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"} \ No newline at end of file
diff --git a/vendor/byteorder/CHANGELOG.md b/vendor/byteorder/CHANGELOG.md
deleted file mode 100644
index 6b51eb076..000000000
--- a/vendor/byteorder/CHANGELOG.md
+++ /dev/null
@@ -1,139 +0,0 @@
-1.3.4
-=====
-This patch release squashes deprecation warnings for the `try!` macro, in
-accordance with byteorder's minimum supported Rust version (currently at Rust
-1.12.0).
-
-
-1.3.3
-=====
-This patch release adds `ByteOrder::write_i8_into()` as a simple, safe interface
-for ordinarily unsafe or tedious code.
-
-
-1.3.2
-=====
-This patch release adds `ReadBytesExt::read_i8_into()` as a simple, safe interface
-for ordinarily unsafe or tedious code.
-
-
-1.3.1
-=====
-This minor release performs mostly small internal changes. Going forward, these
-are not going to be incorporated into the changelog.
-
-
-1.3.0
-=====
-This new minor release now enables `i128` support automatically on Rust
-compilers that support 128-bit integers. The `i128` feature is now a no-op, but
-continues to exist for backward compatibility purposes. The crate continues to
-maintain compatibility with Rust 1.12.0.
-
-This release also deprecates the `ByteOrder` trait methods
-`read_f32_into_unchecked` and `read_f64_into_unchecked` in favor of
-`read_f32_into` and `read_f64_into`. This was an oversight from the 1.2 release
-where the corresponding methods on `ReadBytesExt` were deprecated.
-
-`quickcheck` and `rand` were bumped to `0.8` and `0.6`, respectively.
-
-A few small documentation related bugs have been fixed.
-
-
-1.2.7
-=====
-This patch release excludes some CI files from the crate release and updates
-the license field to use `OR` instead of `/`.
-
-
-1.2.6
-=====
-This patch release fixes some test compilation errors introduced by an
-over-eager release of 1.2.5.
-
-
-1.2.5
-=====
-This patch release fixes some typos in the docs, adds doc tests to methods on
-`WriteByteExt` and bumps the quickcheck dependency to `0.7`.
-
-
-1.2.4
-=====
-This patch release adds support for 48-bit integers by adding the following
-methods to the `ByteOrder` trait: `read_u48`, `read_i48`, `write_u48` and
-`write_i48`. Corresponding methods have been added to the `ReadBytesExt` and
-`WriteBytesExt` traits as well.
-
-
-1.2.3
-=====
-This patch release removes the use of `feature(i128_type)` from byteorder,
-since it has been stabilized. We leave byteorder's `i128` feature in place
-in order to continue supporting compilation on older versions of Rust.
-
-
-1.2.2
-=====
-This patch release only consists of internal improvements and refactorings.
-Notably, this removes all uses of `transmute` and instead uses pointer casts.
-
-
-1.2.1
-=====
-This patch release removes more unnecessary uses of `unsafe` that
-were overlooked in the prior `1.2.0` release. In particular, the
-`ReadBytesExt::read_{f32,f64}_into_checked` methods have been deprecated and
-replaced by more appropriately named `read_{f32,f64}_into` methods.
-
-
-1.2.0
-=====
-The most prominent change in this release of `byteorder` is the removal of
-unnecessary signaling NaN masking, and in turn, the `unsafe` annotations
-associated with methods that didn't do masking. See
-[#103](https://github.com/BurntSushi/byteorder/issues/103)
-for more details.
-
-* [BUG #102](https://github.com/BurntSushi/byteorder/issues/102):
- Fix big endian tests.
-* [BUG #103](https://github.com/BurntSushi/byteorder/issues/103):
- Remove sNaN masking.
-
-
-1.1.0
-=====
-This release of `byteorder` features a number of fixes and improvements, mostly
-as a result of the
-[Litz Blitz evaluation](https://public.etherpad-mozilla.org/p/rust-crate-eval-byteorder).
-
-Feature enhancements:
-
-* [FEATURE #63](https://github.com/BurntSushi/byteorder/issues/63):
- Add methods for reading/writing slices of numbers for a specific
- endianness.
-* [FEATURE #65](https://github.com/BurntSushi/byteorder/issues/65):
- Add support for `u128`/`i128` types. (Behind the nightly only `i128`
- feature.)
-* [FEATURE #72](https://github.com/BurntSushi/byteorder/issues/72):
- Add "panics" and "errors" sections for each relevant public API item.
-* [FEATURE #74](https://github.com/BurntSushi/byteorder/issues/74):
- Add CI badges to Cargo.toml.
-* [FEATURE #75](https://github.com/BurntSushi/byteorder/issues/75):
- Add more examples to public API items.
-* Add 24-bit read/write methods.
-* Add `BE` and `LE` type aliases for `BigEndian` and `LittleEndian`,
- respectively.
-
-Bug fixes:
-
-* [BUG #68](https://github.com/BurntSushi/byteorder/issues/68):
- Panic in {BigEndian,LittleEndian}::default.
-* [BUG #69](https://github.com/BurntSushi/byteorder/issues/69):
- Seal the `ByteOrder` trait to prevent out-of-crate implementations.
-* [BUG #71](https://github.com/BurntSushi/byteorder/issues/71):
- Guarantee that the results of `read_f32`/`read_f64` are always defined.
-* [BUG #73](https://github.com/BurntSushi/byteorder/issues/73):
- Add crates.io categories.
-* [BUG #77](https://github.com/BurntSushi/byteorder/issues/77):
- Add `html_root` doc attribute.
diff --git a/vendor/byteorder/COPYING b/vendor/byteorder/COPYING
deleted file mode 100644
index bb9c20a09..000000000
--- a/vendor/byteorder/COPYING
+++ /dev/null
@@ -1,3 +0,0 @@
-This project is dual-licensed under the Unlicense and MIT licenses.
-
-You may use this code under the terms of either license.
diff --git a/vendor/byteorder/Cargo.toml b/vendor/byteorder/Cargo.toml
deleted file mode 100644
index c71f90ba9..000000000
--- a/vendor/byteorder/Cargo.toml
+++ /dev/null
@@ -1,43 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-edition = "2018"
-name = "byteorder"
-version = "1.4.3"
-authors = ["Andrew Gallant <jamslam@gmail.com>"]
-exclude = ["/ci/*"]
-description = "Library for reading/writing numbers in big-endian and little-endian."
-homepage = "https://github.com/BurntSushi/byteorder"
-documentation = "https://docs.rs/byteorder"
-readme = "README.md"
-keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
-categories = ["encoding", "parsing", "no-std"]
-license = "Unlicense OR MIT"
-repository = "https://github.com/BurntSushi/byteorder"
-[profile.bench]
-opt-level = 3
-
-[lib]
-name = "byteorder"
-bench = false
-[dev-dependencies.quickcheck]
-version = "0.9.2"
-default-features = false
-
-[dev-dependencies.rand]
-version = "0.7"
-
-[features]
-default = ["std"]
-i128 = []
-std = []
diff --git a/vendor/byteorder/LICENSE-MIT b/vendor/byteorder/LICENSE-MIT
deleted file mode 100644
index 3b0a5dc09..000000000
--- a/vendor/byteorder/LICENSE-MIT
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Andrew Gallant
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/byteorder/README.md b/vendor/byteorder/README.md
deleted file mode 100644
index d8461c58f..000000000
--- a/vendor/byteorder/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-byteorder
-=========
-This crate provides convenience methods for encoding and decoding
-numbers in either big-endian or little-endian order.
-
-[![Build status](https://github.com/BurntSushi/byteorder/workflows/ci/badge.svg)](https://github.com/BurntSushi/byteorder/actions)
-[![](https://meritbadge.herokuapp.com/byteorder)](https://crates.io/crates/byteorder)
-
-Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).
-
-
-### Documentation
-
-https://docs.rs/byteorder
-
-
-### Installation
-
-This crate works with Cargo and is on
-[crates.io](https://crates.io/crates/byteorder). Add it to your `Cargo.toml`
-like so:
-
-```toml
-[dependencies]
-byteorder = "1"
-```
-
-If you want to augment existing `Read` and `Write` traits, then import the
-extension methods like so:
-
-```rust
-use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
-```
-
-For example:
-
-```rust
-use std::io::Cursor;
-use byteorder::{BigEndian, ReadBytesExt};
-
-let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
-// Note that we use type parameters to indicate which kind of byte order
-// we want!
-assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
-assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
-```
-
-### `no_std` crates
-
-This crate has a feature, `std`, that is enabled by default. To use this crate
-in a `no_std` context, add the following to your `Cargo.toml`:
-
-```toml
-[dependencies]
-byteorder = { version = "1", default-features = false }
-```
-
-
-### Alternatives
-
-Note that as of Rust 1.32, the standard numeric types provide built-in methods
-like `to_le_bytes` and `from_le_bytes`, which support some of the same use
-cases.
diff --git a/vendor/byteorder/UNLICENSE b/vendor/byteorder/UNLICENSE
deleted file mode 100644
index 68a49daad..000000000
--- a/vendor/byteorder/UNLICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-This is free and unencumbered software released into the public domain.
-
-Anyone is free to copy, modify, publish, use, compile, sell, or
-distribute this software, either in source code form or as a compiled
-binary, for any purpose, commercial or non-commercial, and by any
-means.
-
-In jurisdictions that recognize copyright laws, the author or authors
-of this software dedicate any and all copyright interest in the
-software to the public domain. We make this dedication for the benefit
-of the public at large and to the detriment of our heirs and
-successors. We intend this dedication to be an overt act of
-relinquishment in perpetuity of all present and future rights to this
-software under copyright law.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-For more information, please refer to <http://unlicense.org/>
diff --git a/vendor/byteorder/benches/bench.rs b/vendor/byteorder/benches/bench.rs
deleted file mode 100644
index bb00422f7..000000000
--- a/vendor/byteorder/benches/bench.rs
+++ /dev/null
@@ -1,324 +0,0 @@
-#![feature(test)]
-
-extern crate test;
-
-macro_rules! bench_num {
- ($name:ident, $read:ident, $bytes:expr, $data:expr) => {
- mod $name {
- use byteorder::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
- use test::black_box as bb;
- use test::Bencher;
-
- const NITER: usize = 100_000;
-
- #[bench]
- fn read_big_endian(b: &mut Bencher) {
- let buf = $data;
- b.iter(|| {
- for _ in 0..NITER {
- bb(BigEndian::$read(&buf, $bytes));
- }
- });
- }
-
- #[bench]
- fn read_little_endian(b: &mut Bencher) {
- let buf = $data;
- b.iter(|| {
- for _ in 0..NITER {
- bb(LittleEndian::$read(&buf, $bytes));
- }
- });
- }
-
- #[bench]
- fn read_native_endian(b: &mut Bencher) {
- let buf = $data;
- b.iter(|| {
- for _ in 0..NITER {
- bb(NativeEndian::$read(&buf, $bytes));
- }
- });
- }
- }
- };
- ($ty:ident, $max:ident,
- $read:ident, $write:ident, $size:expr, $data:expr) => {
- mod $ty {
- use byteorder::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
- use std::$ty;
- use test::black_box as bb;
- use test::Bencher;
-
- const NITER: usize = 100_000;
-
- #[bench]
- fn read_big_endian(b: &mut Bencher) {
- let buf = $data;
- b.iter(|| {
- for _ in 0..NITER {
- bb(BigEndian::$read(&buf));
- }
- });
- }
-
- #[bench]
- fn read_little_endian(b: &mut Bencher) {
- let buf = $data;
- b.iter(|| {
- for _ in 0..NITER {
- bb(LittleEndian::$read(&buf));
- }
- });
- }
-
- #[bench]
- fn read_native_endian(b: &mut Bencher) {
- let buf = $data;
- b.iter(|| {
- for _ in 0..NITER {
- bb(NativeEndian::$read(&buf));
- }
- });
- }
-
- #[bench]
- fn write_big_endian(b: &mut Bencher) {
- let mut buf = $data;
- let n = $ty::$max;
- b.iter(|| {
- for _ in 0..NITER {
- bb(BigEndian::$write(&mut buf, n));
- }
- });
- }
-
- #[bench]
- fn write_little_endian(b: &mut Bencher) {
- let mut buf = $data;
- let n = $ty::$max;
- b.iter(|| {
- for _ in 0..NITER {
- bb(LittleEndian::$write(&mut buf, n));
- }
- });
- }
-
- #[bench]
- fn write_native_endian(b: &mut Bencher) {
- let mut buf = $data;
- let n = $ty::$max;
- b.iter(|| {
- for _ in 0..NITER {
- bb(NativeEndian::$write(&mut buf, n));
- }
- });
- }
- }
- };
-}
-
-bench_num!(u16, MAX, read_u16, write_u16, 2, [1, 2]);
-bench_num!(i16, MAX, read_i16, write_i16, 2, [1, 2]);
-bench_num!(u32, MAX, read_u32, write_u32, 4, [1, 2, 3, 4]);
-bench_num!(i32, MAX, read_i32, write_i32, 4, [1, 2, 3, 4]);
-bench_num!(u64, MAX, read_u64, write_u64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-bench_num!(i64, MAX, read_i64, write_i64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-bench_num!(f32, MAX, read_f32, write_f32, 4, [1, 2, 3, 4]);
-bench_num!(f64, MAX, read_f64, write_f64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-
-bench_num!(uint_1, read_uint, 1, [1]);
-bench_num!(uint_2, read_uint, 2, [1, 2]);
-bench_num!(uint_3, read_uint, 3, [1, 2, 3]);
-bench_num!(uint_4, read_uint, 4, [1, 2, 3, 4]);
-bench_num!(uint_5, read_uint, 5, [1, 2, 3, 4, 5]);
-bench_num!(uint_6, read_uint, 6, [1, 2, 3, 4, 5, 6]);
-bench_num!(uint_7, read_uint, 7, [1, 2, 3, 4, 5, 6, 7]);
-bench_num!(uint_8, read_uint, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-
-bench_num!(int_1, read_int, 1, [1]);
-bench_num!(int_2, read_int, 2, [1, 2]);
-bench_num!(int_3, read_int, 3, [1, 2, 3]);
-bench_num!(int_4, read_int, 4, [1, 2, 3, 4]);
-bench_num!(int_5, read_int, 5, [1, 2, 3, 4, 5]);
-bench_num!(int_6, read_int, 6, [1, 2, 3, 4, 5, 6]);
-bench_num!(int_7, read_int, 7, [1, 2, 3, 4, 5, 6, 7]);
-bench_num!(int_8, read_int, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-
-bench_num!(
- u128,
- MAX,
- read_u128,
- write_u128,
- 16,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
-);
-bench_num!(
- i128,
- MAX,
- read_i128,
- write_i128,
- 16,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
-);
-
-bench_num!(uint128_1, read_uint128, 1, [1]);
-bench_num!(uint128_2, read_uint128, 2, [1, 2]);
-bench_num!(uint128_3, read_uint128, 3, [1, 2, 3]);
-bench_num!(uint128_4, read_uint128, 4, [1, 2, 3, 4]);
-bench_num!(uint128_5, read_uint128, 5, [1, 2, 3, 4, 5]);
-bench_num!(uint128_6, read_uint128, 6, [1, 2, 3, 4, 5, 6]);
-bench_num!(uint128_7, read_uint128, 7, [1, 2, 3, 4, 5, 6, 7]);
-bench_num!(uint128_8, read_uint128, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-bench_num!(uint128_9, read_uint128, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
-bench_num!(uint128_10, read_uint128, 10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
-bench_num!(uint128_11, read_uint128, 11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
-bench_num!(
- uint128_12,
- read_uint128,
- 12,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
-);
-bench_num!(
- uint128_13,
- read_uint128,
- 13,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
-);
-bench_num!(
- uint128_14,
- read_uint128,
- 14,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
-);
-bench_num!(
- uint128_15,
- read_uint128,
- 15,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
-);
-bench_num!(
- uint128_16,
- read_uint128,
- 16,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
-);
-
-bench_num!(int128_1, read_int128, 1, [1]);
-bench_num!(int128_2, read_int128, 2, [1, 2]);
-bench_num!(int128_3, read_int128, 3, [1, 2, 3]);
-bench_num!(int128_4, read_int128, 4, [1, 2, 3, 4]);
-bench_num!(int128_5, read_int128, 5, [1, 2, 3, 4, 5]);
-bench_num!(int128_6, read_int128, 6, [1, 2, 3, 4, 5, 6]);
-bench_num!(int128_7, read_int128, 7, [1, 2, 3, 4, 5, 6, 7]);
-bench_num!(int128_8, read_int128, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
-bench_num!(int128_9, read_int128, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
-bench_num!(int128_10, read_int128, 10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
-bench_num!(int128_11, read_int128, 11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
-bench_num!(
- int128_12,
- read_int128,
- 12,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
-);
-bench_num!(
- int128_13,
- read_int128,
- 13,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
-);
-bench_num!(
- int128_14,
- read_int128,
- 14,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
-);
-bench_num!(
- int128_15,
- read_int128,
- 15,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
-);
-bench_num!(
- int128_16,
- read_int128,
- 16,
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
-);
-
-macro_rules! bench_slice {
- ($name:ident, $numty:ty, $read:ident, $write:ident) => {
- mod $name {
- use std::mem::size_of;
-
- use byteorder::{BigEndian, ByteOrder, LittleEndian};
- use rand::distributions;
- use rand::{self, Rng};
- use test::Bencher;
-
- #[bench]
- fn read_big_endian(b: &mut Bencher) {
- let mut numbers: Vec<$numty> = rand::thread_rng()
- .sample_iter(&distributions::Standard)
- .take(100000)
- .collect();
- let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
- BigEndian::$write(&numbers, &mut bytes);
-
- b.bytes = bytes.len() as u64;
- b.iter(|| {
- BigEndian::$read(&bytes, &mut numbers);
- });
- }
-
- #[bench]
- fn read_little_endian(b: &mut Bencher) {
- let mut numbers: Vec<$numty> = rand::thread_rng()
- .sample_iter(&distributions::Standard)
- .take(100000)
- .collect();
- let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
- LittleEndian::$write(&numbers, &mut bytes);
-
- b.bytes = bytes.len() as u64;
- b.iter(|| {
- LittleEndian::$read(&bytes, &mut numbers);
- });
- }
-
- #[bench]
- fn write_big_endian(b: &mut Bencher) {
- let numbers: Vec<$numty> = rand::thread_rng()
- .sample_iter(&distributions::Standard)
- .take(100000)
- .collect();
- let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
-
- b.bytes = bytes.len() as u64;
- b.iter(|| {
- BigEndian::$write(&numbers, &mut bytes);
- });
- }
-
- #[bench]
- fn write_little_endian(b: &mut Bencher) {
- let numbers: Vec<$numty> = rand::thread_rng()
- .sample_iter(&distributions::Standard)
- .take(100000)
- .collect();
- let mut bytes = vec![0; numbers.len() * size_of::<$numty>()];
-
- b.bytes = bytes.len() as u64;
- b.iter(|| {
- LittleEndian::$write(&numbers, &mut bytes);
- });
- }
- }
- };
-}
-
-bench_slice!(slice_u64, u64, read_u64_into, write_u64_into);
diff --git a/vendor/byteorder/rustfmt.toml b/vendor/byteorder/rustfmt.toml
deleted file mode 100644
index aa37a218b..000000000
--- a/vendor/byteorder/rustfmt.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-max_width = 79
-use_small_heuristics = "max"
diff --git a/vendor/byteorder/src/io.rs b/vendor/byteorder/src/io.rs
deleted file mode 100644
index dfad2ca39..000000000
--- a/vendor/byteorder/src/io.rs
+++ /dev/null
@@ -1,1592 +0,0 @@
-use std::{
- io::{self, Result},
- slice,
-};
-
-use crate::ByteOrder;
-
-/// Extends [`Read`] with methods for reading numbers. (For `std::io`.)
-///
-/// Most of the methods defined here have an unconstrained type parameter that
-/// must be explicitly instantiated. Typically, it is instantiated with either
-/// the [`BigEndian`] or [`LittleEndian`] types defined in this crate.
-///
-/// # Examples
-///
-/// Read unsigned 16 bit big-endian integers from a [`Read`]:
-///
-/// ```rust
-/// use std::io::Cursor;
-/// use byteorder::{BigEndian, ReadBytesExt};
-///
-/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
-/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
-/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
-/// ```
-///
-/// [`BigEndian`]: enum.BigEndian.html
-/// [`LittleEndian`]: enum.LittleEndian.html
-/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
-pub trait ReadBytesExt: io::Read {
- /// Reads an unsigned 8 bit integer from the underlying reader.
- ///
- /// Note that since this reads a single byte, no byte order conversions
- /// are used. It is included for completeness.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read unsigned 8 bit integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::ReadBytesExt;
- ///
- /// let mut rdr = Cursor::new(vec![2, 5]);
- /// assert_eq!(2, rdr.read_u8().unwrap());
- /// assert_eq!(5, rdr.read_u8().unwrap());
- /// ```
- #[inline]
- fn read_u8(&mut self) -> Result<u8> {
- let mut buf = [0; 1];
- self.read_exact(&mut buf)?;
- Ok(buf[0])
- }
-
- /// Reads a signed 8 bit integer from the underlying reader.
- ///
- /// Note that since this reads a single byte, no byte order conversions
- /// are used. It is included for completeness.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read signed 8 bit integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::ReadBytesExt;
- ///
- /// let mut rdr = Cursor::new(vec![0x02, 0xfb]);
- /// assert_eq!(2, rdr.read_i8().unwrap());
- /// assert_eq!(-5, rdr.read_i8().unwrap());
- /// ```
- #[inline]
- fn read_i8(&mut self) -> Result<i8> {
- let mut buf = [0; 1];
- self.read_exact(&mut buf)?;
- Ok(buf[0] as i8)
- }
-
- /// Reads an unsigned 16 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read unsigned 16 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
- /// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
- /// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
- let mut buf = [0; 2];
- self.read_exact(&mut buf)?;
- Ok(T::read_u16(&buf))
- }
-
- /// Reads a signed 16 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read signed 16 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]);
- /// assert_eq!(193, rdr.read_i16::<BigEndian>().unwrap());
- /// assert_eq!(-132, rdr.read_i16::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
- let mut buf = [0; 2];
- self.read_exact(&mut buf)?;
- Ok(T::read_i16(&buf))
- }
-
- /// Reads an unsigned 24 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read unsigned 24 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x00, 0x01, 0x0b]);
- /// assert_eq!(267, rdr.read_u24::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_u24<T: ByteOrder>(&mut self) -> Result<u32> {
- let mut buf = [0; 3];
- self.read_exact(&mut buf)?;
- Ok(T::read_u24(&buf))
- }
-
- /// Reads a signed 24 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read signed 24 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0xff, 0x7a, 0x33]);
- /// assert_eq!(-34253, rdr.read_i24::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_i24<T: ByteOrder>(&mut self) -> Result<i32> {
- let mut buf = [0; 3];
- self.read_exact(&mut buf)?;
- Ok(T::read_i24(&buf))
- }
-
- /// Reads an unsigned 32 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read unsigned 32 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]);
- /// assert_eq!(267, rdr.read_u32::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
- let mut buf = [0; 4];
- self.read_exact(&mut buf)?;
- Ok(T::read_u32(&buf))
- }
-
- /// Reads a signed 32 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read signed 32 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]);
- /// assert_eq!(-34253, rdr.read_i32::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
- let mut buf = [0; 4];
- self.read_exact(&mut buf)?;
- Ok(T::read_i32(&buf))
- }
-
- /// Reads an unsigned 48 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read unsigned 48 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0xb6, 0x71, 0x6b, 0xdc, 0x2b, 0x31]);
- /// assert_eq!(200598257150769, rdr.read_u48::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_u48<T: ByteOrder>(&mut self) -> Result<u64> {
- let mut buf = [0; 6];
- self.read_exact(&mut buf)?;
- Ok(T::read_u48(&buf))
- }
-
- /// Reads a signed 48 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read signed 48 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x9d, 0x71, 0xab, 0xe7, 0x97, 0x8f]);
- /// assert_eq!(-108363435763825, rdr.read_i48::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_i48<T: ByteOrder>(&mut self) -> Result<i64> {
- let mut buf = [0; 6];
- self.read_exact(&mut buf)?;
- Ok(T::read_i48(&buf))
- }
-
- /// Reads an unsigned 64 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read an unsigned 64 bit big-endian integer from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83]);
- /// assert_eq!(918733457491587, rdr.read_u64::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
- let mut buf = [0; 8];
- self.read_exact(&mut buf)?;
- Ok(T::read_u64(&buf))
- }
-
- /// Reads a signed 64 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a signed 64 bit big-endian integer from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]);
- /// assert_eq!(i64::min_value(), rdr.read_i64::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
- let mut buf = [0; 8];
- self.read_exact(&mut buf)?;
- Ok(T::read_i64(&buf))
- }
-
- /// Reads an unsigned 128 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read an unsigned 128 bit big-endian integer from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83,
- /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83
- /// ]);
- /// assert_eq!(16947640962301618749969007319746179, rdr.read_u128::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> {
- let mut buf = [0; 16];
- self.read_exact(&mut buf)?;
- Ok(T::read_u128(&buf))
- }
-
- /// Reads a signed 128 bit integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a signed 128 bit big-endian integer from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
- /// assert_eq!(i128::min_value(), rdr.read_i128::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_i128<T: ByteOrder>(&mut self) -> Result<i128> {
- let mut buf = [0; 16];
- self.read_exact(&mut buf)?;
- Ok(T::read_i128(&buf))
- }
-
- /// Reads an unsigned n-bytes integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read an unsigned n-byte big-endian integer from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0x80, 0x74, 0xfa]);
- /// assert_eq!(8418554, rdr.read_uint::<BigEndian>(3).unwrap());
- #[inline]
- fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
- let mut buf = [0; 8];
- self.read_exact(&mut buf[..nbytes])?;
- Ok(T::read_uint(&buf[..nbytes], nbytes))
- }
-
- /// Reads a signed n-bytes integer from the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read an unsigned n-byte big-endian integer from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0xc1, 0xff, 0x7c]);
- /// assert_eq!(-4063364, rdr.read_int::<BigEndian>(3).unwrap());
- #[inline]
- fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
- let mut buf = [0; 8];
- self.read_exact(&mut buf[..nbytes])?;
- Ok(T::read_int(&buf[..nbytes], nbytes))
- }
-
- /// Reads an unsigned n-bytes integer from the underlying reader.
- #[inline]
- fn read_uint128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u128> {
- let mut buf = [0; 16];
- self.read_exact(&mut buf[..nbytes])?;
- Ok(T::read_uint128(&buf[..nbytes], nbytes))
- }
-
- /// Reads a signed n-bytes integer from the underlying reader.
- #[inline]
- fn read_int128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i128> {
- let mut buf = [0; 16];
- self.read_exact(&mut buf[..nbytes])?;
- Ok(T::read_int128(&buf[..nbytes], nbytes))
- }
-
- /// Reads a IEEE754 single-precision (4 bytes) floating point number from
- /// the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a big-endian single-precision floating point number from a `Read`:
- ///
- /// ```rust
- /// use std::f32;
- /// use std::io::Cursor;
- ///
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x40, 0x49, 0x0f, 0xdb,
- /// ]);
- /// assert_eq!(f32::consts::PI, rdr.read_f32::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
- let mut buf = [0; 4];
- self.read_exact(&mut buf)?;
- Ok(T::read_f32(&buf))
- }
-
- /// Reads a IEEE754 double-precision (8 bytes) floating point number from
- /// the underlying reader.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a big-endian double-precision floating point number from a `Read`:
- ///
- /// ```rust
- /// use std::f64;
- /// use std::io::Cursor;
- ///
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
- /// ]);
- /// assert_eq!(f64::consts::PI, rdr.read_f64::<BigEndian>().unwrap());
- /// ```
- #[inline]
- fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
- let mut buf = [0; 8];
- self.read_exact(&mut buf)?;
- Ok(T::read_f64(&buf))
- }
-
- /// Reads a sequence of unsigned 16 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of unsigned 16 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
- /// let mut dst = [0; 2];
- /// rdr.read_u16_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_u16_into<T: ByteOrder>(&mut self, dst: &mut [u16]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_u16(dst);
- Ok(())
- }
-
- /// Reads a sequence of unsigned 32 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of unsigned 32 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]);
- /// let mut dst = [0; 2];
- /// rdr.read_u32_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_u32_into<T: ByteOrder>(&mut self, dst: &mut [u32]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_u32(dst);
- Ok(())
- }
-
- /// Reads a sequence of unsigned 64 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of unsigned 64 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0, 0, 0, 0, 0, 0, 2, 5,
- /// 0, 0, 0, 0, 0, 0, 3, 0,
- /// ]);
- /// let mut dst = [0; 2];
- /// rdr.read_u64_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_u64_into<T: ByteOrder>(&mut self, dst: &mut [u64]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_u64(dst);
- Ok(())
- }
-
- /// Reads a sequence of unsigned 128 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of unsigned 128 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
- /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
- /// ]);
- /// let mut dst = [0; 2];
- /// rdr.read_u128_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_u128_into<T: ByteOrder>(
- &mut self,
- dst: &mut [u128],
- ) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_u128(dst);
- Ok(())
- }
-
- /// Reads a sequence of signed 8 bit integers from the underlying reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// Note that since each `i8` is a single byte, no byte order conversions
- /// are used. This method is included because it provides a safe, simple
- /// way for the caller to read into a `&mut [i8]` buffer. (Without this
- /// method, the caller would have to either use `unsafe` code or convert
- /// each byte to `i8` individually.)
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of signed 8 bit integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![2, 251, 3]);
- /// let mut dst = [0; 3];
- /// rdr.read_i8_into(&mut dst).unwrap();
- /// assert_eq!([2, -5, 3], dst);
- /// ```
- #[inline]
- fn read_i8_into(&mut self, dst: &mut [i8]) -> Result<()> {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)
- }
-
- /// Reads a sequence of signed 16 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of signed 16 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
- /// let mut dst = [0; 2];
- /// rdr.read_i16_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_i16_into<T: ByteOrder>(&mut self, dst: &mut [i16]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_i16(dst);
- Ok(())
- }
-
- /// Reads a sequence of signed 32 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of signed 32 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]);
- /// let mut dst = [0; 2];
- /// rdr.read_i32_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_i32_into<T: ByteOrder>(&mut self, dst: &mut [i32]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_i32(dst);
- Ok(())
- }
-
- /// Reads a sequence of signed 64 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of signed 64 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0, 0, 0, 0, 0, 0, 2, 5,
- /// 0, 0, 0, 0, 0, 0, 3, 0,
- /// ]);
- /// let mut dst = [0; 2];
- /// rdr.read_i64_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_i64_into<T: ByteOrder>(&mut self, dst: &mut [i64]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_i64(dst);
- Ok(())
- }
-
- /// Reads a sequence of signed 128 bit integers from the underlying
- /// reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of signed 128 bit big-endian integers from a `Read`:
- ///
- /// ```rust
- /// use std::io::Cursor;
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
- /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
- /// ]);
- /// let mut dst = [0; 2];
- /// rdr.read_i128_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([517, 768], dst);
- /// ```
- #[inline]
- fn read_i128_into<T: ByteOrder>(
- &mut self,
- dst: &mut [i128],
- ) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_i128(dst);
- Ok(())
- }
-
- /// Reads a sequence of IEEE754 single-precision (4 bytes) floating
- /// point numbers from the underlying reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of big-endian single-precision floating point number
- /// from a `Read`:
- ///
- /// ```rust
- /// use std::f32;
- /// use std::io::Cursor;
- ///
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x40, 0x49, 0x0f, 0xdb,
- /// 0x3f, 0x80, 0x00, 0x00,
- /// ]);
- /// let mut dst = [0.0; 2];
- /// rdr.read_f32_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([f32::consts::PI, 1.0], dst);
- /// ```
- #[inline]
- fn read_f32_into<T: ByteOrder>(&mut self, dst: &mut [f32]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_f32(dst);
- Ok(())
- }
-
- /// **DEPRECATED**.
- ///
- /// This method is deprecated. Use `read_f32_into` instead.
- ///
- /// Reads a sequence of IEEE754 single-precision (4 bytes) floating
- /// point numbers from the underlying reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of big-endian single-precision floating point number
- /// from a `Read`:
- ///
- /// ```rust
- /// use std::f32;
- /// use std::io::Cursor;
- ///
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x40, 0x49, 0x0f, 0xdb,
- /// 0x3f, 0x80, 0x00, 0x00,
- /// ]);
- /// let mut dst = [0.0; 2];
- /// rdr.read_f32_into_unchecked::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([f32::consts::PI, 1.0], dst);
- /// ```
- #[inline]
- #[deprecated(since = "1.2.0", note = "please use `read_f32_into` instead")]
- fn read_f32_into_unchecked<T: ByteOrder>(
- &mut self,
- dst: &mut [f32],
- ) -> Result<()> {
- self.read_f32_into::<T>(dst)
- }
-
- /// Reads a sequence of IEEE754 double-precision (8 bytes) floating
- /// point numbers from the underlying reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of big-endian single-precision floating point number
- /// from a `Read`:
- ///
- /// ```rust
- /// use std::f64;
- /// use std::io::Cursor;
- ///
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
- /// 0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /// ]);
- /// let mut dst = [0.0; 2];
- /// rdr.read_f64_into::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([f64::consts::PI, 1.0], dst);
- /// ```
- #[inline]
- fn read_f64_into<T: ByteOrder>(&mut self, dst: &mut [f64]) -> Result<()> {
- {
- let buf = unsafe { slice_to_u8_mut(dst) };
- self.read_exact(buf)?;
- }
- T::from_slice_f64(dst);
- Ok(())
- }
-
- /// **DEPRECATED**.
- ///
- /// This method is deprecated. Use `read_f64_into` instead.
- ///
- /// Reads a sequence of IEEE754 double-precision (8 bytes) floating
- /// point numbers from the underlying reader.
- ///
- /// The given buffer is either filled completely or an error is returned.
- /// If an error is returned, the contents of `dst` are unspecified.
- ///
- /// # Safety
- ///
- /// This method is unsafe because there are no guarantees made about the
- /// floating point values. In particular, this method does not check for
- /// signaling NaNs, which may result in undefined behavior.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Read::read_exact`].
- ///
- /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
- ///
- /// # Examples
- ///
- /// Read a sequence of big-endian single-precision floating point number
- /// from a `Read`:
- ///
- /// ```rust
- /// use std::f64;
- /// use std::io::Cursor;
- ///
- /// use byteorder::{BigEndian, ReadBytesExt};
- ///
- /// let mut rdr = Cursor::new(vec![
- /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,
- /// 0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /// ]);
- /// let mut dst = [0.0; 2];
- /// rdr.read_f64_into_unchecked::<BigEndian>(&mut dst).unwrap();
- /// assert_eq!([f64::consts::PI, 1.0], dst);
- /// ```
- #[inline]
- #[deprecated(since = "1.2.0", note = "please use `read_f64_into` instead")]
- fn read_f64_into_unchecked<T: ByteOrder>(
- &mut self,
- dst: &mut [f64],
- ) -> Result<()> {
- self.read_f64_into::<T>(dst)
- }
-}
-
-/// All types that implement `Read` get methods defined in `ReadBytesExt`
-/// for free.
-impl<R: io::Read + ?Sized> ReadBytesExt for R {}
-
-/// Extends [`Write`] with methods for writing numbers. (For `std::io`.)
-///
-/// Most of the methods defined here have an unconstrained type parameter that
-/// must be explicitly instantiated. Typically, it is instantiated with either
-/// the [`BigEndian`] or [`LittleEndian`] types defined in this crate.
-///
-/// # Examples
-///
-/// Write unsigned 16 bit big-endian integers to a [`Write`]:
-///
-/// ```rust
-/// use byteorder::{BigEndian, WriteBytesExt};
-///
-/// let mut wtr = vec![];
-/// wtr.write_u16::<BigEndian>(517).unwrap();
-/// wtr.write_u16::<BigEndian>(768).unwrap();
-/// assert_eq!(wtr, vec![2, 5, 3, 0]);
-/// ```
-///
-/// [`BigEndian`]: enum.BigEndian.html
-/// [`LittleEndian`]: enum.LittleEndian.html
-/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
-pub trait WriteBytesExt: io::Write {
- /// Writes an unsigned 8 bit integer to the underlying writer.
- ///
- /// Note that since this writes a single byte, no byte order conversions
- /// are used. It is included for completeness.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write unsigned 8 bit integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::WriteBytesExt;
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_u8(2).unwrap();
- /// wtr.write_u8(5).unwrap();
- /// assert_eq!(wtr, b"\x02\x05");
- /// ```
- #[inline]
- fn write_u8(&mut self, n: u8) -> Result<()> {
- self.write_all(&[n])
- }
-
- /// Writes a signed 8 bit integer to the underlying writer.
- ///
- /// Note that since this writes a single byte, no byte order conversions
- /// are used. It is included for completeness.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write signed 8 bit integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::WriteBytesExt;
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_i8(2).unwrap();
- /// wtr.write_i8(-5).unwrap();
- /// assert_eq!(wtr, b"\x02\xfb");
- /// ```
- #[inline]
- fn write_i8(&mut self, n: i8) -> Result<()> {
- self.write_all(&[n as u8])
- }
-
- /// Writes an unsigned 16 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write unsigned 16 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_u16::<BigEndian>(517).unwrap();
- /// wtr.write_u16::<BigEndian>(768).unwrap();
- /// assert_eq!(wtr, b"\x02\x05\x03\x00");
- /// ```
- #[inline]
- fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
- let mut buf = [0; 2];
- T::write_u16(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a signed 16 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write signed 16 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_i16::<BigEndian>(193).unwrap();
- /// wtr.write_i16::<BigEndian>(-132).unwrap();
- /// assert_eq!(wtr, b"\x00\xc1\xff\x7c");
- /// ```
- #[inline]
- fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
- let mut buf = [0; 2];
- T::write_i16(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes an unsigned 24 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write unsigned 24 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_u24::<BigEndian>(267).unwrap();
- /// wtr.write_u24::<BigEndian>(120111).unwrap();
- /// assert_eq!(wtr, b"\x00\x01\x0b\x01\xd5\x2f");
- /// ```
- #[inline]
- fn write_u24<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
- let mut buf = [0; 3];
- T::write_u24(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a signed 24 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write signed 24 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_i24::<BigEndian>(-34253).unwrap();
- /// wtr.write_i24::<BigEndian>(120111).unwrap();
- /// assert_eq!(wtr, b"\xff\x7a\x33\x01\xd5\x2f");
- /// ```
- #[inline]
- fn write_i24<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
- let mut buf = [0; 3];
- T::write_i24(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes an unsigned 32 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write unsigned 32 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_u32::<BigEndian>(267).unwrap();
- /// wtr.write_u32::<BigEndian>(1205419366).unwrap();
- /// assert_eq!(wtr, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66");
- /// ```
- #[inline]
- fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
- let mut buf = [0; 4];
- T::write_u32(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a signed 32 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write signed 32 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_i32::<BigEndian>(-34253).unwrap();
- /// wtr.write_i32::<BigEndian>(1205419366).unwrap();
- /// assert_eq!(wtr, b"\xff\xff\x7a\x33\x47\xd9\x3d\x66");
- /// ```
- #[inline]
- fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
- let mut buf = [0; 4];
- T::write_i32(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes an unsigned 48 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write unsigned 48 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_u48::<BigEndian>(52360336390828).unwrap();
- /// wtr.write_u48::<BigEndian>(541).unwrap();
- /// assert_eq!(wtr, b"\x2f\x9f\x17\x40\x3a\xac\x00\x00\x00\x00\x02\x1d");
- /// ```
- #[inline]
- fn write_u48<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
- let mut buf = [0; 6];
- T::write_u48(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a signed 48 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write signed 48 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_i48::<BigEndian>(-108363435763825).unwrap();
- /// wtr.write_i48::<BigEndian>(77).unwrap();
- /// assert_eq!(wtr, b"\x9d\x71\xab\xe7\x97\x8f\x00\x00\x00\x00\x00\x4d");
- /// ```
- #[inline]
- fn write_i48<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
- let mut buf = [0; 6];
- T::write_i48(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes an unsigned 64 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write unsigned 64 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_u64::<BigEndian>(918733457491587).unwrap();
- /// wtr.write_u64::<BigEndian>(143).unwrap();
- /// assert_eq!(wtr, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f");
- /// ```
- #[inline]
- fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
- let mut buf = [0; 8];
- T::write_u64(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a signed 64 bit integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write signed 64 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_i64::<BigEndian>(i64::min_value()).unwrap();
- /// wtr.write_i64::<BigEndian>(i64::max_value()).unwrap();
- /// assert_eq!(wtr, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff");
- /// ```
- #[inline]
- fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
- let mut buf = [0; 8];
- T::write_i64(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes an unsigned 128 bit integer to the underlying writer.
- #[inline]
- fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> {
- let mut buf = [0; 16];
- T::write_u128(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a signed 128 bit integer to the underlying writer.
- #[inline]
- fn write_i128<T: ByteOrder>(&mut self, n: i128) -> Result<()> {
- let mut buf = [0; 16];
- T::write_i128(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes an unsigned n-bytes integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Panics
- ///
- /// If the given integer is not representable in the given number of bytes,
- /// this method panics. If `nbytes > 8`, this method panics.
- ///
- /// # Examples
- ///
- /// Write unsigned 40 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_uint::<BigEndian>(312550384361, 5).unwrap();
- /// wtr.write_uint::<BigEndian>(43, 5).unwrap();
- /// assert_eq!(wtr, b"\x48\xc5\x74\x62\xe9\x00\x00\x00\x00\x2b");
- /// ```
- #[inline]
- fn write_uint<T: ByteOrder>(
- &mut self,
- n: u64,
- nbytes: usize,
- ) -> Result<()> {
- let mut buf = [0; 8];
- T::write_uint(&mut buf, n, nbytes);
- self.write_all(&buf[0..nbytes])
- }
-
- /// Writes a signed n-bytes integer to the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Panics
- ///
- /// If the given integer is not representable in the given number of bytes,
- /// this method panics. If `nbytes > 8`, this method panics.
- ///
- /// # Examples
- ///
- /// Write signed 56 bit big-endian integers to a `Write`:
- ///
- /// ```rust
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_int::<BigEndian>(-3548172039376767, 7).unwrap();
- /// wtr.write_int::<BigEndian>(43, 7).unwrap();
- /// assert_eq!(wtr, b"\xf3\x64\xf4\xd1\xfd\xb0\x81\x00\x00\x00\x00\x00\x00\x2b");
- /// ```
- #[inline]
- fn write_int<T: ByteOrder>(
- &mut self,
- n: i64,
- nbytes: usize,
- ) -> Result<()> {
- let mut buf = [0; 8];
- T::write_int(&mut buf, n, nbytes);
- self.write_all(&buf[0..nbytes])
- }
-
- /// Writes an unsigned n-bytes integer to the underlying writer.
- ///
- /// If the given integer is not representable in the given number of bytes,
- /// this method panics. If `nbytes > 16`, this method panics.
- #[inline]
- fn write_uint128<T: ByteOrder>(
- &mut self,
- n: u128,
- nbytes: usize,
- ) -> Result<()> {
- let mut buf = [0; 16];
- T::write_uint128(&mut buf, n, nbytes);
- self.write_all(&buf[0..nbytes])
- }
-
- /// Writes a signed n-bytes integer to the underlying writer.
- ///
- /// If the given integer is not representable in the given number of bytes,
- /// this method panics. If `nbytes > 16`, this method panics.
- #[inline]
- fn write_int128<T: ByteOrder>(
- &mut self,
- n: i128,
- nbytes: usize,
- ) -> Result<()> {
- let mut buf = [0; 16];
- T::write_int128(&mut buf, n, nbytes);
- self.write_all(&buf[0..nbytes])
- }
-
- /// Writes a IEEE754 single-precision (4 bytes) floating point number to
- /// the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write a big-endian single-precision floating point number to a `Write`:
- ///
- /// ```rust
- /// use std::f32;
- ///
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_f32::<BigEndian>(f32::consts::PI).unwrap();
- /// assert_eq!(wtr, b"\x40\x49\x0f\xdb");
- /// ```
- #[inline]
- fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
- let mut buf = [0; 4];
- T::write_f32(&mut buf, n);
- self.write_all(&buf)
- }
-
- /// Writes a IEEE754 double-precision (8 bytes) floating point number to
- /// the underlying writer.
- ///
- /// # Errors
- ///
- /// This method returns the same errors as [`Write::write_all`].
- ///
- /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
- ///
- /// # Examples
- ///
- /// Write a big-endian double-precision floating point number to a `Write`:
- ///
- /// ```rust
- /// use std::f64;
- ///
- /// use byteorder::{BigEndian, WriteBytesExt};
- ///
- /// let mut wtr = Vec::new();
- /// wtr.write_f64::<BigEndian>(f64::consts::PI).unwrap();
- /// assert_eq!(wtr, b"\x40\x09\x21\xfb\x54\x44\x2d\x18");
- /// ```
- #[inline]
- fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
- let mut buf = [0; 8];
- T::write_f64(&mut buf, n);
- self.write_all(&buf)
- }
-}
-
-/// All types that implement `Write` get methods defined in `WriteBytesExt`
-/// for free.
-impl<W: io::Write + ?Sized> WriteBytesExt for W {}
-
-/// Convert a slice of T (where T is plain old data) to its mutable binary
-/// representation.
-///
-/// This function is wildly unsafe because it permits arbitrary modification of
-/// the binary representation of any `Copy` type. Use with care. It's intended
-/// to be called only where `T` is a numeric type.
-unsafe fn slice_to_u8_mut<T: Copy>(slice: &mut [T]) -> &mut [u8] {
- use std::mem::size_of;
-
- let len = size_of::<T>() * slice.len();
- slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, len)
-}
diff --git a/vendor/byteorder/src/lib.rs b/vendor/byteorder/src/lib.rs
deleted file mode 100644
index cc37cca6a..000000000
--- a/vendor/byteorder/src/lib.rs
+++ /dev/null
@@ -1,4052 +0,0 @@
-/*!
-This crate provides convenience methods for encoding and decoding numbers in
-either [big-endian or little-endian order].
-
-The organization of the crate is pretty simple. A trait, [`ByteOrder`], specifies
-byte conversion methods for each type of number in Rust (sans numbers that have
-a platform dependent size like `usize` and `isize`). Two types, [`BigEndian`]
-and [`LittleEndian`] implement these methods. Finally, [`ReadBytesExt`] and
-[`WriteBytesExt`] provide convenience methods available to all types that
-implement [`Read`] and [`Write`].
-
-An alias, [`NetworkEndian`], for [`BigEndian`] is provided to help improve
-code clarity.
-
-An additional alias, [`NativeEndian`], is provided for the endianness of the
-local platform. This is convenient when serializing data for use and
-conversions are not desired.
-
-# Examples
-
-Read unsigned 16 bit big-endian integers from a [`Read`] type:
-
-```rust
-use std::io::Cursor;
-use byteorder::{BigEndian, ReadBytesExt};
-
-let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
-// Note that we use type parameters to indicate which kind of byte order
-// we want!
-assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
-assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
-```
-
-Write unsigned 16 bit little-endian integers to a [`Write`] type:
-
-```rust
-use byteorder::{LittleEndian, WriteBytesExt};
-
-let mut wtr = vec![];
-wtr.write_u16::<LittleEndian>(517).unwrap();
-wtr.write_u16::<LittleEndian>(768).unwrap();
-assert_eq!(wtr, vec![5, 2, 0, 3]);
-```
-
-# Optional Features
-
-This crate optionally provides support for 128 bit values (`i128` and `u128`)
-when built with the `i128` feature enabled.
-
-This crate can also be used without the standard library.
-
-# Alternatives
-
-Note that as of Rust 1.32, the standard numeric types provide built-in methods
-like `to_le_bytes` and `from_le_bytes`, which support some of the same use
-cases.
-
-[big-endian or little-endian order]: https://en.wikipedia.org/wiki/Endianness
-[`ByteOrder`]: trait.ByteOrder.html
-[`BigEndian`]: enum.BigEndian.html
-[`LittleEndian`]: enum.LittleEndian.html
-[`ReadBytesExt`]: trait.ReadBytesExt.html
-[`WriteBytesExt`]: trait.WriteBytesExt.html
-[`NetworkEndian`]: type.NetworkEndian.html
-[`NativeEndian`]: type.NativeEndian.html
-[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
-[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
-*/
-
-#![deny(missing_docs)]
-#![cfg_attr(not(feature = "std"), no_std)]
-
-use core::{
- convert::TryInto, fmt::Debug, hash::Hash, ptr::copy_nonoverlapping, slice,
-};
-
-#[cfg(feature = "std")]
-pub use crate::io::{ReadBytesExt, WriteBytesExt};
-
-#[cfg(feature = "std")]
-mod io;
-
-#[inline]
-fn extend_sign(val: u64, nbytes: usize) -> i64 {
- let shift = (8 - nbytes) * 8;
- (val << shift) as i64 >> shift
-}
-
-#[inline]
-fn extend_sign128(val: u128, nbytes: usize) -> i128 {
- let shift = (16 - nbytes) * 8;
- (val << shift) as i128 >> shift
-}
-
-#[inline]
-fn unextend_sign(val: i64, nbytes: usize) -> u64 {
- let shift = (8 - nbytes) * 8;
- (val << shift) as u64 >> shift
-}
-
-#[inline]
-fn unextend_sign128(val: i128, nbytes: usize) -> u128 {
- let shift = (16 - nbytes) * 8;
- (val << shift) as u128 >> shift
-}
-
-#[inline]
-fn pack_size(n: u64) -> usize {
- if n < 1 << 8 {
- 1
- } else if n < 1 << 16 {
- 2
- } else if n < 1 << 24 {
- 3
- } else if n < 1 << 32 {
- 4
- } else if n < 1 << 40 {
- 5
- } else if n < 1 << 48 {
- 6
- } else if n < 1 << 56 {
- 7
- } else {
- 8
- }
-}
-
-#[inline]
-fn pack_size128(n: u128) -> usize {
- if n < 1 << 8 {
- 1
- } else if n < 1 << 16 {
- 2
- } else if n < 1 << 24 {
- 3
- } else if n < 1 << 32 {
- 4
- } else if n < 1 << 40 {
- 5
- } else if n < 1 << 48 {
- 6
- } else if n < 1 << 56 {
- 7
- } else if n < 1 << 64 {
- 8
- } else if n < 1 << 72 {
- 9
- } else if n < 1 << 80 {
- 10
- } else if n < 1 << 88 {
- 11
- } else if n < 1 << 96 {
- 12
- } else if n < 1 << 104 {
- 13
- } else if n < 1 << 112 {
- 14
- } else if n < 1 << 120 {
- 15
- } else {
- 16
- }
-}
-
-mod private {
- /// Sealed stops crates other than byteorder from implementing any traits
- /// that use it.
- pub trait Sealed {}
- impl Sealed for super::LittleEndian {}
- impl Sealed for super::BigEndian {}
-}
-
-/// `ByteOrder` describes types that can serialize integers as bytes.
-///
-/// Note that `Self` does not appear anywhere in this trait's definition!
-/// Therefore, in order to use it, you'll need to use syntax like
-/// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
-///
-/// This crate provides two types that implement `ByteOrder`: [`BigEndian`]
-/// and [`LittleEndian`].
-/// This trait is sealed and cannot be implemented for callers to avoid
-/// breaking backwards compatibility when adding new derived traits.
-///
-/// # Examples
-///
-/// Write and read `u32` numbers in little endian order:
-///
-/// ```rust
-/// use byteorder::{ByteOrder, LittleEndian};
-///
-/// let mut buf = [0; 4];
-/// LittleEndian::write_u32(&mut buf, 1_000_000);
-/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
-/// ```
-///
-/// Write and read `i16` numbers in big endian order:
-///
-/// ```rust
-/// use byteorder::{ByteOrder, BigEndian};
-///
-/// let mut buf = [0; 2];
-/// BigEndian::write_i16(&mut buf, -5_000);
-/// assert_eq!(-5_000, BigEndian::read_i16(&buf));
-/// ```
-///
-/// [`BigEndian`]: enum.BigEndian.html
-/// [`LittleEndian`]: enum.LittleEndian.html
-pub trait ByteOrder:
- Clone
- + Copy
- + Debug
- + Default
- + Eq
- + Hash
- + Ord
- + PartialEq
- + PartialOrd
- + private::Sealed
-{
- /// Reads an unsigned 16 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 2`.
- fn read_u16(buf: &[u8]) -> u16;
-
- /// Reads an unsigned 24 bit integer from `buf`, stored in u32.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 3`.
- ///
- /// # Examples
- ///
- /// Write and read 24 bit `u32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_u24(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf));
- /// ```
- fn read_u24(buf: &[u8]) -> u32 {
- Self::read_uint(buf, 3) as u32
- }
-
- /// Reads an unsigned 32 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 4`.
- ///
- /// # Examples
- ///
- /// Write and read `u32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 4];
- /// LittleEndian::write_u32(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
- /// ```
- fn read_u32(buf: &[u8]) -> u32;
-
- /// Reads an unsigned 48 bit integer from `buf`, stored in u64.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 6`.
- ///
- /// # Examples
- ///
- /// Write and read 48 bit `u64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 6];
- /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000);
- /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf));
- /// ```
- fn read_u48(buf: &[u8]) -> u64 {
- Self::read_uint(buf, 6) as u64
- }
-
- /// Reads an unsigned 64 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 8`.
- ///
- /// # Examples
- ///
- /// Write and read `u64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 8];
- /// LittleEndian::write_u64(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf));
- /// ```
- fn read_u64(buf: &[u8]) -> u64;
-
- /// Reads an unsigned 128 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 16`.
- ///
- /// # Examples
- ///
- /// Write and read `u128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 16];
- /// LittleEndian::write_u128(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf));
- /// ```
- fn read_u128(buf: &[u8]) -> u128;
-
- /// Reads an unsigned n-bytes integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `nbytes < 1` or `nbytes > 8` or
- /// `buf.len() < nbytes`
- ///
- /// # Examples
- ///
- /// Write and read an n-byte number in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_uint(&mut buf, 1_000_000, 3);
- /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3));
- /// ```
- fn read_uint(buf: &[u8], nbytes: usize) -> u64;
-
- /// Reads an unsigned n-bytes integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `nbytes < 1` or `nbytes > 16` or
- /// `buf.len() < nbytes`
- ///
- /// # Examples
- ///
- /// Write and read an n-byte number in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3);
- /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3));
- /// ```
- fn read_uint128(buf: &[u8], nbytes: usize) -> u128;
-
- /// Writes an unsigned 16 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 2`.
- ///
- /// # Examples
- ///
- /// Write and read `u16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 2];
- /// LittleEndian::write_u16(&mut buf, 1_000);
- /// assert_eq!(1_000, LittleEndian::read_u16(&buf));
- /// ```
- fn write_u16(buf: &mut [u8], n: u16);
-
- /// Writes an unsigned 24 bit integer `n` to `buf`, stored in u32.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 3`.
- ///
- /// # Examples
- ///
- /// Write and read 24 bit `u32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_u24(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf));
- /// ```
- fn write_u24(buf: &mut [u8], n: u32) {
- Self::write_uint(buf, n as u64, 3)
- }
-
- /// Writes an unsigned 32 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 4`.
- ///
- /// # Examples
- ///
- /// Write and read `u32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 4];
- /// LittleEndian::write_u32(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
- /// ```
- fn write_u32(buf: &mut [u8], n: u32);
-
- /// Writes an unsigned 48 bit integer `n` to `buf`, stored in u64.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 6`.
- ///
- /// # Examples
- ///
- /// Write and read 48 bit `u64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 6];
- /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000);
- /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf));
- /// ```
- fn write_u48(buf: &mut [u8], n: u64) {
- Self::write_uint(buf, n as u64, 6)
- }
-
- /// Writes an unsigned 64 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 8`.
- ///
- /// # Examples
- ///
- /// Write and read `u64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 8];
- /// LittleEndian::write_u64(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf));
- /// ```
- fn write_u64(buf: &mut [u8], n: u64);
-
- /// Writes an unsigned 128 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 16`.
- ///
- /// # Examples
- ///
- /// Write and read `u128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 16];
- /// LittleEndian::write_u128(&mut buf, 1_000_000);
- /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf));
- /// ```
- fn write_u128(buf: &mut [u8], n: u128);
-
- /// Writes an unsigned integer `n` to `buf` using only `nbytes`.
- ///
- /// # Panics
- ///
- /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
- /// this method panics.
- ///
- /// # Examples
- ///
- /// Write and read an n-byte number in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_uint(&mut buf, 1_000_000, 3);
- /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3));
- /// ```
- fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
-
- /// Writes an unsigned integer `n` to `buf` using only `nbytes`.
- ///
- /// # Panics
- ///
- /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then
- /// this method panics.
- ///
- /// # Examples
- ///
- /// Write and read an n-byte number in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3);
- /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3));
- /// ```
- fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize);
-
- /// Reads a signed 16 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 2`.
- ///
- /// # Examples
- ///
- /// Write and read `i16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 2];
- /// LittleEndian::write_i16(&mut buf, -1_000);
- /// assert_eq!(-1_000, LittleEndian::read_i16(&buf));
- /// ```
- #[inline]
- fn read_i16(buf: &[u8]) -> i16 {
- Self::read_u16(buf) as i16
- }
-
- /// Reads a signed 24 bit integer from `buf`, stored in i32.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 3`.
- ///
- /// # Examples
- ///
- /// Write and read 24 bit `i32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_i24(&mut buf, -1_000_000);
- /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf));
- /// ```
- #[inline]
- fn read_i24(buf: &[u8]) -> i32 {
- Self::read_int(buf, 3) as i32
- }
-
- /// Reads a signed 32 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 4`.
- ///
- /// # Examples
- ///
- /// Write and read `i32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 4];
- /// LittleEndian::write_i32(&mut buf, -1_000_000);
- /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf));
- /// ```
- #[inline]
- fn read_i32(buf: &[u8]) -> i32 {
- Self::read_u32(buf) as i32
- }
-
- /// Reads a signed 48 bit integer from `buf`, stored in i64.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 6`.
- ///
- /// # Examples
- ///
- /// Write and read 48 bit `i64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 6];
- /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000);
- /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf));
- /// ```
- #[inline]
- fn read_i48(buf: &[u8]) -> i64 {
- Self::read_int(buf, 6) as i64
- }
-
- /// Reads a signed 64 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 8`.
- ///
- /// # Examples
- ///
- /// Write and read `i64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 8];
- /// LittleEndian::write_i64(&mut buf, -1_000_000_000);
- /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf));
- /// ```
- #[inline]
- fn read_i64(buf: &[u8]) -> i64 {
- Self::read_u64(buf) as i64
- }
-
- /// Reads a signed 128 bit integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 16`.
- ///
- /// # Examples
- ///
- /// Write and read `i128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 16];
- /// LittleEndian::write_i128(&mut buf, -1_000_000_000);
- /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf));
- /// ```
- #[inline]
- fn read_i128(buf: &[u8]) -> i128 {
- Self::read_u128(buf) as i128
- }
-
- /// Reads a signed n-bytes integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `nbytes < 1` or `nbytes > 8` or
- /// `buf.len() < nbytes`
- ///
- /// # Examples
- ///
- /// Write and read n-length signed numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_int(&mut buf, -1_000, 3);
- /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3));
- /// ```
- #[inline]
- fn read_int(buf: &[u8], nbytes: usize) -> i64 {
- extend_sign(Self::read_uint(buf, nbytes), nbytes)
- }
-
- /// Reads a signed n-bytes integer from `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `nbytes < 1` or `nbytes > 16` or
- /// `buf.len() < nbytes`
- ///
- /// # Examples
- ///
- /// Write and read n-length signed numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_int128(&mut buf, -1_000, 3);
- /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3));
- /// ```
- #[inline]
- fn read_int128(buf: &[u8], nbytes: usize) -> i128 {
- extend_sign128(Self::read_uint128(buf, nbytes), nbytes)
- }
-
- /// Reads a IEEE754 single-precision (4 bytes) floating point number.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 4`.
- ///
- /// # Examples
- ///
- /// Write and read `f32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let e = 2.71828;
- /// let mut buf = [0; 4];
- /// LittleEndian::write_f32(&mut buf, e);
- /// assert_eq!(e, LittleEndian::read_f32(&buf));
- /// ```
- #[inline]
- fn read_f32(buf: &[u8]) -> f32 {
- f32::from_bits(Self::read_u32(buf))
- }
-
- /// Reads a IEEE754 double-precision (8 bytes) floating point number.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 8`.
- ///
- /// # Examples
- ///
- /// Write and read `f64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let phi = 1.6180339887;
- /// let mut buf = [0; 8];
- /// LittleEndian::write_f64(&mut buf, phi);
- /// assert_eq!(phi, LittleEndian::read_f64(&buf));
- /// ```
- #[inline]
- fn read_f64(buf: &[u8]) -> f64 {
- f64::from_bits(Self::read_u64(buf))
- }
-
- /// Writes a signed 16 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 2`.
- ///
- /// # Examples
- ///
- /// Write and read `i16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 2];
- /// LittleEndian::write_i16(&mut buf, -1_000);
- /// assert_eq!(-1_000, LittleEndian::read_i16(&buf));
- /// ```
- #[inline]
- fn write_i16(buf: &mut [u8], n: i16) {
- Self::write_u16(buf, n as u16)
- }
-
- /// Writes a signed 24 bit integer `n` to `buf`, stored in i32.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 3`.
- ///
- /// # Examples
- ///
- /// Write and read 24 bit `i32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_i24(&mut buf, -1_000_000);
- /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf));
- /// ```
- #[inline]
- fn write_i24(buf: &mut [u8], n: i32) {
- Self::write_int(buf, n as i64, 3)
- }
-
- /// Writes a signed 32 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 4`.
- ///
- /// # Examples
- ///
- /// Write and read `i32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 4];
- /// LittleEndian::write_i32(&mut buf, -1_000_000);
- /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf));
- /// ```
- #[inline]
- fn write_i32(buf: &mut [u8], n: i32) {
- Self::write_u32(buf, n as u32)
- }
-
- /// Writes a signed 48 bit integer `n` to `buf`, stored in i64.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 6`.
- ///
- /// # Examples
- ///
- /// Write and read 48 bit `i64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 6];
- /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000);
- /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf));
- /// ```
- #[inline]
- fn write_i48(buf: &mut [u8], n: i64) {
- Self::write_int(buf, n as i64, 6)
- }
-
- /// Writes a signed 64 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 8`.
- ///
- /// # Examples
- ///
- /// Write and read `i64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 8];
- /// LittleEndian::write_i64(&mut buf, -1_000_000_000);
- /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf));
- /// ```
- #[inline]
- fn write_i64(buf: &mut [u8], n: i64) {
- Self::write_u64(buf, n as u64)
- }
-
- /// Writes a signed 128 bit integer `n` to `buf`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 16`.
- ///
- /// # Examples
- ///
- /// Write and read n-byte `i128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 16];
- /// LittleEndian::write_i128(&mut buf, -1_000_000_000);
- /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf));
- /// ```
- #[inline]
- fn write_i128(buf: &mut [u8], n: i128) {
- Self::write_u128(buf, n as u128)
- }
-
- /// Writes a signed integer `n` to `buf` using only `nbytes`.
- ///
- /// # Panics
- ///
- /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
- /// this method panics.
- ///
- /// # Examples
- ///
- /// Write and read an n-byte number in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_int(&mut buf, -1_000, 3);
- /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3));
- /// ```
- #[inline]
- fn write_int(buf: &mut [u8], n: i64, nbytes: usize) {
- Self::write_uint(buf, unextend_sign(n, nbytes), nbytes)
- }
-
- /// Writes a signed integer `n` to `buf` using only `nbytes`.
- ///
- /// # Panics
- ///
- /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then
- /// this method panics.
- ///
- /// # Examples
- ///
- /// Write and read n-length signed numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut buf = [0; 3];
- /// LittleEndian::write_int128(&mut buf, -1_000, 3);
- /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3));
- /// ```
- #[inline]
- fn write_int128(buf: &mut [u8], n: i128, nbytes: usize) {
- Self::write_uint128(buf, unextend_sign128(n, nbytes), nbytes)
- }
-
- /// Writes a IEEE754 single-precision (4 bytes) floating point number.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 4`.
- ///
- /// # Examples
- ///
- /// Write and read `f32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let e = 2.71828;
- /// let mut buf = [0; 4];
- /// LittleEndian::write_f32(&mut buf, e);
- /// assert_eq!(e, LittleEndian::read_f32(&buf));
- /// ```
- #[inline]
- fn write_f32(buf: &mut [u8], n: f32) {
- Self::write_u32(buf, n.to_bits())
- }
-
- /// Writes a IEEE754 double-precision (8 bytes) floating point number.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() < 8`.
- ///
- /// # Examples
- ///
- /// Write and read `f64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let phi = 1.6180339887;
- /// let mut buf = [0; 8];
- /// LittleEndian::write_f64(&mut buf, phi);
- /// assert_eq!(phi, LittleEndian::read_f64(&buf));
- /// ```
- #[inline]
- fn write_f64(buf: &mut [u8], n: f64) {
- Self::write_u64(buf, n.to_bits())
- }
-
- /// Reads unsigned 16 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 2*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 8];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u16_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u16_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn read_u16_into(src: &[u8], dst: &mut [u16]);
-
- /// Reads unsigned 32 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 4*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u32_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn read_u32_into(src: &[u8], dst: &mut [u32]);
-
- /// Reads unsigned 64 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 8*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u64_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn read_u64_into(src: &[u8], dst: &mut [u64]);
-
- /// Reads unsigned 128 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 16*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 64];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u128_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u128_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn read_u128_into(src: &[u8], dst: &mut [u128]);
-
- /// Reads signed 16 bit integers from `src` to `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() != 2*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 8];
- /// let numbers_given = [1, 2, 0x0f, 0xee];
- /// LittleEndian::write_i16_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i16_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- fn read_i16_into(src: &[u8], dst: &mut [i16]) {
- let dst = unsafe {
- slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u16, dst.len())
- };
- Self::read_u16_into(src, dst)
- }
-
- /// Reads signed 32 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 4*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_i32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i32_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- fn read_i32_into(src: &[u8], dst: &mut [i32]) {
- let dst = unsafe {
- slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
- };
- Self::read_u32_into(src, dst);
- }
-
- /// Reads signed 64 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 8*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_i64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i64_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- fn read_i64_into(src: &[u8], dst: &mut [i64]) {
- let dst = unsafe {
- slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
- };
- Self::read_u64_into(src, dst);
- }
-
- /// Reads signed 128 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 16*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 64];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_i128_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i128_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- fn read_i128_into(src: &[u8], dst: &mut [i128]) {
- let dst = unsafe {
- slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u128, dst.len())
- };
- Self::read_u128_into(src, dst);
- }
-
- /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
- /// `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 4*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `f32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
- /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0.0; 4];
- /// LittleEndian::read_f32_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- fn read_f32_into(src: &[u8], dst: &mut [f32]) {
- let dst = unsafe {
- slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
- };
- Self::read_u32_into(src, dst);
- }
-
- /// **DEPRECATED**.
- ///
- /// This method is deprecated. Use `read_f32_into` instead.
- /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
- /// `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 4*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `f32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
- /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0.0; 4];
- /// LittleEndian::read_f32_into_unchecked(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- #[deprecated(since = "1.3.0", note = "please use `read_f32_into` instead")]
- fn read_f32_into_unchecked(src: &[u8], dst: &mut [f32]) {
- Self::read_f32_into(src, dst);
- }
-
- /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
- /// `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 8*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `f64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
- /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0.0; 4];
- /// LittleEndian::read_f64_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- fn read_f64_into(src: &[u8], dst: &mut [f64]) {
- let dst = unsafe {
- slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
- };
- Self::read_u64_into(src, dst);
- }
-
- /// **DEPRECATED**.
- ///
- /// This method is deprecated. Use `read_f64_into` instead.
- ///
- /// Reads IEEE754 single-precision (4 bytes) floating point numbers from
- /// `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 8*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `f64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
- /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0.0; 4];
- /// LittleEndian::read_f64_into_unchecked(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- #[inline]
- #[deprecated(since = "1.3.0", note = "please use `read_f64_into` instead")]
- fn read_f64_into_unchecked(src: &[u8], dst: &mut [f64]) {
- Self::read_f64_into(src, dst);
- }
-
- /// Writes unsigned 16 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 2*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 8];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u16_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u16_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_u16_into(src: &[u16], dst: &mut [u8]);
-
- /// Writes unsigned 32 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 4*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u32_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_u32_into(src: &[u32], dst: &mut [u8]);
-
- /// Writes unsigned 64 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 8*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u64_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_u64_into(src: &[u64], dst: &mut [u8]);
-
- /// Writes unsigned 128 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 16*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `u128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 64];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_u128_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_u128_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_u128_into(src: &[u128], dst: &mut [u8]);
-
- /// Writes signed 8 bit integers from `src` into `dst`.
- ///
- /// Note that since each `i8` is a single byte, no byte order conversions
- /// are used. This method is included because it provides a safe, simple
- /// way for the caller to write from a `&[i8]` buffer. (Without this
- /// method, the caller would have to either use `unsafe` code or convert
- /// each byte to `u8` individually.)
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() != src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i8` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian, ReadBytesExt};
- ///
- /// let mut bytes = [0; 4];
- /// let numbers_given = [1, 2, 0xf, 0xe];
- /// LittleEndian::write_i8_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// bytes.as_ref().read_i8_into(&mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_i8_into(src: &[i8], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u8, src.len())
- };
- dst.copy_from_slice(src);
- }
-
- /// Writes signed 16 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `buf.len() != 2*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i16` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 8];
- /// let numbers_given = [1, 2, 0x0f, 0xee];
- /// LittleEndian::write_i16_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i16_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_i16_into(src: &[i16], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u16, src.len())
- };
- Self::write_u16_into(src, dst);
- }
-
- /// Writes signed 32 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 4*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_i32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i32_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_i32_into(src: &[i32], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
- };
- Self::write_u32_into(src, dst);
- }
-
- /// Writes signed 64 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 8*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_i64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i64_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_i64_into(src: &[i64], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
- };
- Self::write_u64_into(src, dst);
- }
-
- /// Writes signed 128 bit integers from `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `dst.len() != 16*src.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `i128` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 64];
- /// let numbers_given = [1, 2, 0xf00f, 0xffee];
- /// LittleEndian::write_i128_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0; 4];
- /// LittleEndian::read_i128_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_i128_into(src: &[i128], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u128, src.len())
- };
- Self::write_u128_into(src, dst);
- }
-
- /// Writes IEEE754 single-precision (4 bytes) floating point numbers from
- /// `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 4*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `f32` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 16];
- /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19];
- /// LittleEndian::write_f32_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0.0; 4];
- /// LittleEndian::read_f32_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_f32_into(src: &[f32], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
- };
- Self::write_u32_into(src, dst);
- }
-
- /// Writes IEEE754 double-precision (8 bytes) floating point numbers from
- /// `src` into `dst`.
- ///
- /// # Panics
- ///
- /// Panics when `src.len() != 8*dst.len()`.
- ///
- /// # Examples
- ///
- /// Write and read `f64` numbers in little endian order:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, LittleEndian};
- ///
- /// let mut bytes = [0; 32];
- /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91];
- /// LittleEndian::write_f64_into(&numbers_given, &mut bytes);
- ///
- /// let mut numbers_got = [0.0; 4];
- /// LittleEndian::read_f64_into(&bytes, &mut numbers_got);
- /// assert_eq!(numbers_given, numbers_got);
- /// ```
- fn write_f64_into(src: &[f64], dst: &mut [u8]) {
- let src = unsafe {
- slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
- };
- Self::write_u64_into(src, dst);
- }
-
- /// Converts the given slice of unsigned 16 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_u16(&mut numbers);
- /// assert_eq!(numbers, [5u16.to_be(), 65000u16.to_be()]);
- /// ```
- fn from_slice_u16(numbers: &mut [u16]);
-
- /// Converts the given slice of unsigned 32 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_u32(&mut numbers);
- /// assert_eq!(numbers, [5u32.to_be(), 65000u32.to_be()]);
- /// ```
- fn from_slice_u32(numbers: &mut [u32]);
-
- /// Converts the given slice of unsigned 64 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_u64(&mut numbers);
- /// assert_eq!(numbers, [5u64.to_be(), 65000u64.to_be()]);
- /// ```
- fn from_slice_u64(numbers: &mut [u64]);
-
- /// Converts the given slice of unsigned 128 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_u128(&mut numbers);
- /// assert_eq!(numbers, [5u128.to_be(), 65000u128.to_be()]);
- /// ```
- fn from_slice_u128(numbers: &mut [u128]);
-
- /// Converts the given slice of signed 16 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 6500];
- /// BigEndian::from_slice_i16(&mut numbers);
- /// assert_eq!(numbers, [5i16.to_be(), 6500i16.to_be()]);
- /// ```
- #[inline]
- fn from_slice_i16(src: &mut [i16]) {
- let src = unsafe {
- slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u16, src.len())
- };
- Self::from_slice_u16(src);
- }
-
- /// Converts the given slice of signed 32 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_i32(&mut numbers);
- /// assert_eq!(numbers, [5i32.to_be(), 65000i32.to_be()]);
- /// ```
- #[inline]
- fn from_slice_i32(src: &mut [i32]) {
- let src = unsafe {
- slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u32, src.len())
- };
- Self::from_slice_u32(src);
- }
-
- /// Converts the given slice of signed 64 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_i64(&mut numbers);
- /// assert_eq!(numbers, [5i64.to_be(), 65000i64.to_be()]);
- /// ```
- #[inline]
- fn from_slice_i64(src: &mut [i64]) {
- let src = unsafe {
- slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u64, src.len())
- };
- Self::from_slice_u64(src);
- }
-
- /// Converts the given slice of signed 128 bit integers to a particular
- /// endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- ///
- /// # Examples
- ///
- /// Convert the host platform's endianness to big-endian:
- ///
- /// ```rust
- /// use byteorder::{ByteOrder, BigEndian};
- ///
- /// let mut numbers = [5, 65000];
- /// BigEndian::from_slice_i128(&mut numbers);
- /// assert_eq!(numbers, [5i128.to_be(), 65000i128.to_be()]);
- /// ```
- #[inline]
- fn from_slice_i128(src: &mut [i128]) {
- let src = unsafe {
- slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u128, src.len())
- };
- Self::from_slice_u128(src);
- }
-
- /// Converts the given slice of IEEE754 single-precision (4 bytes) floating
- /// point numbers to a particular endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- fn from_slice_f32(numbers: &mut [f32]);
-
- /// Converts the given slice of IEEE754 double-precision (8 bytes) floating
- /// point numbers to a particular endianness.
- ///
- /// If the endianness matches the endianness of the host platform, then
- /// this is a no-op.
- fn from_slice_f64(numbers: &mut [f64]);
-}
-
-/// Defines big-endian serialization.
-///
-/// Note that this type has no value constructor. It is used purely at the
-/// type level.
-///
-/// # Examples
-///
-/// Write and read `u32` numbers in big endian order:
-///
-/// ```rust
-/// use byteorder::{ByteOrder, BigEndian};
-///
-/// let mut buf = [0; 4];
-/// BigEndian::write_u32(&mut buf, 1_000_000);
-/// assert_eq!(1_000_000, BigEndian::read_u32(&buf));
-/// ```
-#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub enum BigEndian {}
-
-impl Default for BigEndian {
- fn default() -> BigEndian {
- panic!("BigEndian default")
- }
-}
-
-/// A type alias for [`BigEndian`].
-///
-/// [`BigEndian`]: enum.BigEndian.html
-pub type BE = BigEndian;
-
-/// Defines little-endian serialization.
-///
-/// Note that this type has no value constructor. It is used purely at the
-/// type level.
-///
-/// # Examples
-///
-/// Write and read `u32` numbers in little endian order:
-///
-/// ```rust
-/// use byteorder::{ByteOrder, LittleEndian};
-///
-/// let mut buf = [0; 4];
-/// LittleEndian::write_u32(&mut buf, 1_000_000);
-/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
-/// ```
-#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub enum LittleEndian {}
-
-impl Default for LittleEndian {
- fn default() -> LittleEndian {
- panic!("LittleEndian default")
- }
-}
-
-/// A type alias for [`LittleEndian`].
-///
-/// [`LittleEndian`]: enum.LittleEndian.html
-pub type LE = LittleEndian;
-
-/// Defines network byte order serialization.
-///
-/// Network byte order is defined by [RFC 1700][1] to be big-endian, and is
-/// referred to in several protocol specifications. This type is an alias of
-/// [`BigEndian`].
-///
-/// [1]: https://tools.ietf.org/html/rfc1700
-///
-/// Note that this type has no value constructor. It is used purely at the
-/// type level.
-///
-/// # Examples
-///
-/// Write and read `i16` numbers in big endian order:
-///
-/// ```rust
-/// use byteorder::{ByteOrder, NetworkEndian, BigEndian};
-///
-/// let mut buf = [0; 2];
-/// BigEndian::write_i16(&mut buf, -5_000);
-/// assert_eq!(-5_000, NetworkEndian::read_i16(&buf));
-/// ```
-///
-/// [`BigEndian`]: enum.BigEndian.html
-pub type NetworkEndian = BigEndian;
-
-/// Defines system native-endian serialization.
-///
-/// Note that this type has no value constructor. It is used purely at the
-/// type level.
-///
-/// On this platform, this is an alias for [`LittleEndian`].
-///
-/// [`LittleEndian`]: enum.LittleEndian.html
-#[cfg(target_endian = "little")]
-pub type NativeEndian = LittleEndian;
-
-/// Defines system native-endian serialization.
-///
-/// Note that this type has no value constructor. It is used purely at the
-/// type level.
-///
-/// On this platform, this is an alias for [`BigEndian`].
-///
-/// [`BigEndian`]: enum.BigEndian.html
-#[cfg(target_endian = "big")]
-pub type NativeEndian = BigEndian;
-
-/// Copies $size bytes from a number $n to a &mut [u8] $dst. $ty represents the
-/// numeric type of $n and $which must be either to_be or to_le, depending on
-/// which endianness one wants to use when writing to $dst.
-///
-/// This macro is only safe to call when $ty is a numeric type and $size ==
-/// size_of::<$ty>() and where $dst is a &mut [u8].
-macro_rules! unsafe_write_num_bytes {
- ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => {{
- assert!($size <= $dst.len());
- unsafe {
- // N.B. https://github.com/rust-lang/rust/issues/22776
- let bytes = *(&$n.$which() as *const _ as *const [u8; $size]);
- copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
- }
- }};
-}
-
-/// Copies a &[u8] $src into a &mut [<numeric>] $dst for the endianness given
-/// by $which (must be either to_be or to_le).
-///
-/// This macro is only safe to call when $src and $dst are &[u8] and &mut [u8],
-/// respectively. The macro will panic if $src.len() != $size * $dst.len(),
-/// where $size represents the size of the integers encoded in $src.
-macro_rules! unsafe_read_slice {
- ($src:expr, $dst:expr, $size:expr, $which:ident) => {{
- assert_eq!($src.len(), $size * $dst.len());
-
- unsafe {
- copy_nonoverlapping(
- $src.as_ptr(),
- $dst.as_mut_ptr() as *mut u8,
- $src.len(),
- );
- }
- for v in $dst.iter_mut() {
- *v = v.$which();
- }
- }};
-}
-
-/// Copies a &[$ty] $src into a &mut [u8] $dst, where $ty must be a numeric
-/// type. This panics if size_of::<$ty>() * $src.len() != $dst.len().
-///
-/// This macro is only safe to call when $src is a slice of numeric types and
-/// $dst is a &mut [u8] and where $ty represents the type of the integers in
-/// $src.
-macro_rules! unsafe_write_slice_native {
- ($src:expr, $dst:expr, $ty:ty) => {{
- let size = core::mem::size_of::<$ty>();
- assert_eq!(size * $src.len(), $dst.len());
-
- unsafe {
- copy_nonoverlapping(
- $src.as_ptr() as *const u8,
- $dst.as_mut_ptr(),
- $dst.len(),
- );
- }
- }};
-}
-
-macro_rules! write_slice {
- ($src:expr, $dst:expr, $ty:ty, $size:expr, $write:expr) => {{
- assert!($size == ::core::mem::size_of::<$ty>());
- assert_eq!($size * $src.len(), $dst.len());
-
- for (&n, chunk) in $src.iter().zip($dst.chunks_mut($size)) {
- $write(chunk, n);
- }
- }};
-}
-
-impl ByteOrder for BigEndian {
- #[inline]
- fn read_u16(buf: &[u8]) -> u16 {
- u16::from_be_bytes(buf[..2].try_into().unwrap())
- }
-
- #[inline]
- fn read_u32(buf: &[u8]) -> u32 {
- u32::from_be_bytes(buf[..4].try_into().unwrap())
- }
-
- #[inline]
- fn read_u64(buf: &[u8]) -> u64 {
- u64::from_be_bytes(buf[..8].try_into().unwrap())
- }
-
- #[inline]
- fn read_u128(buf: &[u8]) -> u128 {
- u128::from_be_bytes(buf[..16].try_into().unwrap())
- }
-
- #[inline]
- fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
- assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
- let mut out = 0u64;
- let ptr_out = &mut out as *mut u64 as *mut u8;
- unsafe {
- copy_nonoverlapping(
- buf.as_ptr(),
- ptr_out.offset((8 - nbytes) as isize),
- nbytes,
- );
- }
- out.to_be()
- }
-
- #[inline]
- fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
- assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
- let mut out: u128 = 0;
- let ptr_out = &mut out as *mut u128 as *mut u8;
- unsafe {
- copy_nonoverlapping(
- buf.as_ptr(),
- ptr_out.offset((16 - nbytes) as isize),
- nbytes,
- );
- }
- out.to_be()
- }
-
- #[inline]
- fn write_u16(buf: &mut [u8], n: u16) {
- unsafe_write_num_bytes!(u16, 2, n, buf, to_be);
- }
-
- #[inline]
- fn write_u32(buf: &mut [u8], n: u32) {
- unsafe_write_num_bytes!(u32, 4, n, buf, to_be);
- }
-
- #[inline]
- fn write_u64(buf: &mut [u8], n: u64) {
- unsafe_write_num_bytes!(u64, 8, n, buf, to_be);
- }
-
- #[inline]
- fn write_u128(buf: &mut [u8], n: u128) {
- unsafe_write_num_bytes!(u128, 16, n, buf, to_be);
- }
-
- #[inline]
- fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
- assert!(pack_size(n) <= nbytes && nbytes <= 8);
- assert!(nbytes <= buf.len());
- unsafe {
- let bytes = *(&n.to_be() as *const u64 as *const [u8; 8]);
- copy_nonoverlapping(
- bytes.as_ptr().offset((8 - nbytes) as isize),
- buf.as_mut_ptr(),
- nbytes,
- );
- }
- }
-
- #[inline]
- fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) {
- assert!(pack_size128(n) <= nbytes && nbytes <= 16);
- assert!(nbytes <= buf.len());
- unsafe {
- let bytes = *(&n.to_be() as *const u128 as *const [u8; 16]);
- copy_nonoverlapping(
- bytes.as_ptr().offset((16 - nbytes) as isize),
- buf.as_mut_ptr(),
- nbytes,
- );
- }
- }
-
- #[inline]
- fn read_u16_into(src: &[u8], dst: &mut [u16]) {
- unsafe_read_slice!(src, dst, 2, to_be);
- }
-
- #[inline]
- fn read_u32_into(src: &[u8], dst: &mut [u32]) {
- unsafe_read_slice!(src, dst, 4, to_be);
- }
-
- #[inline]
- fn read_u64_into(src: &[u8], dst: &mut [u64]) {
- unsafe_read_slice!(src, dst, 8, to_be);
- }
-
- #[inline]
- fn read_u128_into(src: &[u8], dst: &mut [u128]) {
- unsafe_read_slice!(src, dst, 16, to_be);
- }
-
- #[inline]
- fn write_u16_into(src: &[u16], dst: &mut [u8]) {
- if cfg!(target_endian = "big") {
- unsafe_write_slice_native!(src, dst, u16);
- } else {
- write_slice!(src, dst, u16, 2, Self::write_u16);
- }
- }
-
- #[inline]
- fn write_u32_into(src: &[u32], dst: &mut [u8]) {
- if cfg!(target_endian = "big") {
- unsafe_write_slice_native!(src, dst, u32);
- } else {
- write_slice!(src, dst, u32, 4, Self::write_u32);
- }
- }
-
- #[inline]
- fn write_u64_into(src: &[u64], dst: &mut [u8]) {
- if cfg!(target_endian = "big") {
- unsafe_write_slice_native!(src, dst, u64);
- } else {
- write_slice!(src, dst, u64, 8, Self::write_u64);
- }
- }
-
- #[inline]
- fn write_u128_into(src: &[u128], dst: &mut [u8]) {
- if cfg!(target_endian = "big") {
- unsafe_write_slice_native!(src, dst, u128);
- } else {
- write_slice!(src, dst, u128, 16, Self::write_u128);
- }
- }
-
- #[inline]
- fn from_slice_u16(numbers: &mut [u16]) {
- if cfg!(target_endian = "little") {
- for n in numbers {
- *n = n.to_be();
- }
- }
- }
-
- #[inline]
- fn from_slice_u32(numbers: &mut [u32]) {
- if cfg!(target_endian = "little") {
- for n in numbers {
- *n = n.to_be();
- }
- }
- }
-
- #[inline]
- fn from_slice_u64(numbers: &mut [u64]) {
- if cfg!(target_endian = "little") {
- for n in numbers {
- *n = n.to_be();
- }
- }
- }
-
- #[inline]
- fn from_slice_u128(numbers: &mut [u128]) {
- if cfg!(target_endian = "little") {
- for n in numbers {
- *n = n.to_be();
- }
- }
- }
-
- #[inline]
- fn from_slice_f32(numbers: &mut [f32]) {
- if cfg!(target_endian = "little") {
- for n in numbers {
- unsafe {
- let int = *(n as *const f32 as *const u32);
- *n = *(&int.to_be() as *const u32 as *const f32);
- }
- }
- }
- }
-
- #[inline]
- fn from_slice_f64(numbers: &mut [f64]) {
- if cfg!(target_endian = "little") {
- for n in numbers {
- unsafe {
- let int = *(n as *const f64 as *const u64);
- *n = *(&int.to_be() as *const u64 as *const f64);
- }
- }
- }
- }
-}
-
-impl ByteOrder for LittleEndian {
- #[inline]
- fn read_u16(buf: &[u8]) -> u16 {
- u16::from_le_bytes(buf[..2].try_into().unwrap())
- }
-
- #[inline]
- fn read_u32(buf: &[u8]) -> u32 {
- u32::from_le_bytes(buf[..4].try_into().unwrap())
- }
-
- #[inline]
- fn read_u64(buf: &[u8]) -> u64 {
- u64::from_le_bytes(buf[..8].try_into().unwrap())
- }
-
- #[inline]
- fn read_u128(buf: &[u8]) -> u128 {
- u128::from_le_bytes(buf[..16].try_into().unwrap())
- }
-
- #[inline]
- fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
- assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
- let mut out = 0u64;
- let ptr_out = &mut out as *mut u64 as *mut u8;
- unsafe {
- copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
- }
- out.to_le()
- }
-
- #[inline]
- fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
- assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
- let mut out: u128 = 0;
- let ptr_out = &mut out as *mut u128 as *mut u8;
- unsafe {
- copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
- }
- out.to_le()
- }
-
- #[inline]
- fn write_u16(buf: &mut [u8], n: u16) {
- unsafe_write_num_bytes!(u16, 2, n, buf, to_le);
- }
-
- #[inline]
- fn write_u32(buf: &mut [u8], n: u32) {
- unsafe_write_num_bytes!(u32, 4, n, buf, to_le);
- }
-
- #[inline]
- fn write_u64(buf: &mut [u8], n: u64) {
- unsafe_write_num_bytes!(u64, 8, n, buf, to_le);
- }
-
- #[inline]
- fn write_u128(buf: &mut [u8], n: u128) {
- unsafe_write_num_bytes!(u128, 16, n, buf, to_le);
- }
-
- #[inline]
- fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
- assert!(pack_size(n as u64) <= nbytes && nbytes <= 8);
- assert!(nbytes <= buf.len());
- unsafe {
- let bytes = *(&n.to_le() as *const u64 as *const [u8; 8]);
- copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
- }
- }
-
- #[inline]
- fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) {
- assert!(pack_size128(n as u128) <= nbytes && nbytes <= 16);
- assert!(nbytes <= buf.len());
- unsafe {
- let bytes = *(&n.to_le() as *const u128 as *const [u8; 16]);
- copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
- }
- }
-
- #[inline]
- fn read_u16_into(src: &[u8], dst: &mut [u16]) {
- unsafe_read_slice!(src, dst, 2, to_le);
- }
-
- #[inline]
- fn read_u32_into(src: &[u8], dst: &mut [u32]) {
- unsafe_read_slice!(src, dst, 4, to_le);
- }
-
- #[inline]
- fn read_u64_into(src: &[u8], dst: &mut [u64]) {
- unsafe_read_slice!(src, dst, 8, to_le);
- }
-
- #[inline]
- fn read_u128_into(src: &[u8], dst: &mut [u128]) {
- unsafe_read_slice!(src, dst, 16, to_le);
- }
-
- #[inline]
- fn write_u16_into(src: &[u16], dst: &mut [u8]) {
- if cfg!(target_endian = "little") {
- unsafe_write_slice_native!(src, dst, u16);
- } else {
- write_slice!(src, dst, u16, 2, Self::write_u16);
- }
- }
-
- #[inline]
- fn write_u32_into(src: &[u32], dst: &mut [u8]) {
- if cfg!(target_endian = "little") {
- unsafe_write_slice_native!(src, dst, u32);
- } else {
- write_slice!(src, dst, u32, 4, Self::write_u32);
- }
- }
-
- #[inline]
- fn write_u64_into(src: &[u64], dst: &mut [u8]) {
- if cfg!(target_endian = "little") {
- unsafe_write_slice_native!(src, dst, u64);
- } else {
- write_slice!(src, dst, u64, 8, Self::write_u64);
- }
- }
-
- #[inline]
- fn write_u128_into(src: &[u128], dst: &mut [u8]) {
- if cfg!(target_endian = "little") {
- unsafe_write_slice_native!(src, dst, u128);
- } else {
- write_slice!(src, dst, u128, 16, Self::write_u128);
- }
- }
-
- #[inline]
- fn from_slice_u16(numbers: &mut [u16]) {
- if cfg!(target_endian = "big") {
- for n in numbers {
- *n = n.to_le();
- }
- }
- }
-
- #[inline]
- fn from_slice_u32(numbers: &mut [u32]) {
- if cfg!(target_endian = "big") {
- for n in numbers {
- *n = n.to_le();
- }
- }
- }
-
- #[inline]
- fn from_slice_u64(numbers: &mut [u64]) {
- if cfg!(target_endian = "big") {
- for n in numbers {
- *n = n.to_le();
- }
- }
- }
-
- #[inline]
- fn from_slice_u128(numbers: &mut [u128]) {
- if cfg!(target_endian = "big") {
- for n in numbers {
- *n = n.to_le();
- }
- }
- }
-
- #[inline]
- fn from_slice_f32(numbers: &mut [f32]) {
- if cfg!(target_endian = "big") {
- for n in numbers {
- unsafe {
- let int = *(n as *const f32 as *const u32);
- *n = *(&int.to_le() as *const u32 as *const f32);
- }
- }
- }
- }
-
- #[inline]
- fn from_slice_f64(numbers: &mut [f64]) {
- if cfg!(target_endian = "big") {
- for n in numbers {
- unsafe {
- let int = *(n as *const f64 as *const u64);
- *n = *(&int.to_le() as *const u64 as *const f64);
- }
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use quickcheck::{Arbitrary, Gen, QuickCheck, StdGen, Testable};
- use rand::{thread_rng, Rng};
-
- pub const U24_MAX: u32 = 16_777_215;
- pub const I24_MAX: i32 = 8_388_607;
- pub const U48_MAX: u64 = 281_474_976_710_655;
- pub const I48_MAX: i64 = 140_737_488_355_327;
-
- pub const U64_MAX: u64 = ::core::u64::MAX;
- pub const I64_MAX: u64 = ::core::i64::MAX as u64;
-
- macro_rules! calc_max {
- ($max:expr, $bytes:expr) => {
- calc_max!($max, $bytes, 8)
- };
- ($max:expr, $bytes:expr, $maxbytes:expr) => {
- ($max - 1) >> (8 * ($maxbytes - $bytes))
- };
- }
-
- #[derive(Clone, Debug)]
- pub struct Wi128<T>(pub T);
-
- impl<T: Clone> Wi128<T> {
- pub fn clone(&self) -> T {
- self.0.clone()
- }
- }
-
- impl<T: PartialEq> PartialEq<T> for Wi128<T> {
- fn eq(&self, other: &T) -> bool {
- self.0.eq(other)
- }
- }
-
- impl Arbitrary for Wi128<u128> {
- fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<u128> {
- let max = calc_max!(::core::u128::MAX, gen.size(), 16);
- let output = (gen.gen::<u64>() as u128)
- | ((gen.gen::<u64>() as u128) << 64);
- Wi128(output & (max - 1))
- }
- }
-
- impl Arbitrary for Wi128<i128> {
- fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<i128> {
- let max = calc_max!(::core::i128::MAX, gen.size(), 16);
- let output = (gen.gen::<i64>() as i128)
- | ((gen.gen::<i64>() as i128) << 64);
- Wi128(output & (max - 1))
- }
- }
-
- pub fn qc_sized<A: Testable>(f: A, size: u64) {
- QuickCheck::new()
- .gen(StdGen::new(thread_rng(), size as usize))
- .tests(1_00)
- .max_tests(10_000)
- .quickcheck(f);
- }
-
- macro_rules! qc_byte_order {
- ($name:ident, $ty_int:ty, $max:expr,
- $bytes:expr, $read:ident, $write:ident) => {
- mod $name {
- #[allow(unused_imports)]
- use super::{qc_sized, Wi128};
- use crate::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
-
- #[test]
- fn big_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut buf = [0; 16];
- BigEndian::$write(&mut buf, n.clone(), $bytes);
- n == BigEndian::$read(&buf[..$bytes], $bytes)
- }
- qc_sized(prop as fn($ty_int) -> bool, $max);
- }
-
- #[test]
- fn little_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut buf = [0; 16];
- LittleEndian::$write(&mut buf, n.clone(), $bytes);
- n == LittleEndian::$read(&buf[..$bytes], $bytes)
- }
- qc_sized(prop as fn($ty_int) -> bool, $max);
- }
-
- #[test]
- fn native_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut buf = [0; 16];
- NativeEndian::$write(&mut buf, n.clone(), $bytes);
- n == NativeEndian::$read(&buf[..$bytes], $bytes)
- }
- qc_sized(prop as fn($ty_int) -> bool, $max);
- }
- }
- };
- ($name:ident, $ty_int:ty, $max:expr,
- $read:ident, $write:ident) => {
- mod $name {
- #[allow(unused_imports)]
- use super::{qc_sized, Wi128};
- use crate::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
- use core::mem::size_of;
-
- #[test]
- fn big_endian() {
- fn prop(n: $ty_int) -> bool {
- let bytes = size_of::<$ty_int>();
- let mut buf = [0; 16];
- BigEndian::$write(&mut buf[16 - bytes..], n.clone());
- n == BigEndian::$read(&buf[16 - bytes..])
- }
- qc_sized(prop as fn($ty_int) -> bool, $max - 1);
- }
-
- #[test]
- fn little_endian() {
- fn prop(n: $ty_int) -> bool {
- let bytes = size_of::<$ty_int>();
- let mut buf = [0; 16];
- LittleEndian::$write(&mut buf[..bytes], n.clone());
- n == LittleEndian::$read(&buf[..bytes])
- }
- qc_sized(prop as fn($ty_int) -> bool, $max - 1);
- }
-
- #[test]
- fn native_endian() {
- fn prop(n: $ty_int) -> bool {
- let bytes = size_of::<$ty_int>();
- let mut buf = [0; 16];
- NativeEndian::$write(&mut buf[..bytes], n.clone());
- n == NativeEndian::$read(&buf[..bytes])
- }
- qc_sized(prop as fn($ty_int) -> bool, $max - 1);
- }
- }
- };
- }
-
- qc_byte_order!(
- prop_u16,
- u16,
- ::core::u16::MAX as u64,
- read_u16,
- write_u16
- );
- qc_byte_order!(
- prop_i16,
- i16,
- ::core::i16::MAX as u64,
- read_i16,
- write_i16
- );
- qc_byte_order!(
- prop_u24,
- u32,
- crate::test::U24_MAX as u64,
- read_u24,
- write_u24
- );
- qc_byte_order!(
- prop_i24,
- i32,
- crate::test::I24_MAX as u64,
- read_i24,
- write_i24
- );
- qc_byte_order!(
- prop_u32,
- u32,
- ::core::u32::MAX as u64,
- read_u32,
- write_u32
- );
- qc_byte_order!(
- prop_i32,
- i32,
- ::core::i32::MAX as u64,
- read_i32,
- write_i32
- );
- qc_byte_order!(
- prop_u48,
- u64,
- crate::test::U48_MAX as u64,
- read_u48,
- write_u48
- );
- qc_byte_order!(
- prop_i48,
- i64,
- crate::test::I48_MAX as u64,
- read_i48,
- write_i48
- );
- qc_byte_order!(
- prop_u64,
- u64,
- ::core::u64::MAX as u64,
- read_u64,
- write_u64
- );
- qc_byte_order!(
- prop_i64,
- i64,
- ::core::i64::MAX as u64,
- read_i64,
- write_i64
- );
- qc_byte_order!(
- prop_f32,
- f32,
- ::core::u64::MAX as u64,
- read_f32,
- write_f32
- );
- qc_byte_order!(
- prop_f64,
- f64,
- ::core::i64::MAX as u64,
- read_f64,
- write_f64
- );
-
- qc_byte_order!(prop_u128, Wi128<u128>, 16 + 1, read_u128, write_u128);
- qc_byte_order!(prop_i128, Wi128<i128>, 16 + 1, read_i128, write_i128);
-
- qc_byte_order!(
- prop_uint_1,
- u64,
- calc_max!(super::U64_MAX, 1),
- 1,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_2,
- u64,
- calc_max!(super::U64_MAX, 2),
- 2,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_3,
- u64,
- calc_max!(super::U64_MAX, 3),
- 3,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_4,
- u64,
- calc_max!(super::U64_MAX, 4),
- 4,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_5,
- u64,
- calc_max!(super::U64_MAX, 5),
- 5,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_6,
- u64,
- calc_max!(super::U64_MAX, 6),
- 6,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_7,
- u64,
- calc_max!(super::U64_MAX, 7),
- 7,
- read_uint,
- write_uint
- );
- qc_byte_order!(
- prop_uint_8,
- u64,
- calc_max!(super::U64_MAX, 8),
- 8,
- read_uint,
- write_uint
- );
-
- qc_byte_order!(
- prop_uint128_1,
- Wi128<u128>,
- 1,
- 1,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_2,
- Wi128<u128>,
- 2,
- 2,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_3,
- Wi128<u128>,
- 3,
- 3,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_4,
- Wi128<u128>,
- 4,
- 4,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_5,
- Wi128<u128>,
- 5,
- 5,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_6,
- Wi128<u128>,
- 6,
- 6,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_7,
- Wi128<u128>,
- 7,
- 7,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_8,
- Wi128<u128>,
- 8,
- 8,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_9,
- Wi128<u128>,
- 9,
- 9,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_10,
- Wi128<u128>,
- 10,
- 10,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_11,
- Wi128<u128>,
- 11,
- 11,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_12,
- Wi128<u128>,
- 12,
- 12,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_13,
- Wi128<u128>,
- 13,
- 13,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_14,
- Wi128<u128>,
- 14,
- 14,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_15,
- Wi128<u128>,
- 15,
- 15,
- read_uint128,
- write_uint128
- );
- qc_byte_order!(
- prop_uint128_16,
- Wi128<u128>,
- 16,
- 16,
- read_uint128,
- write_uint128
- );
-
- qc_byte_order!(
- prop_int_1,
- i64,
- calc_max!(super::I64_MAX, 1),
- 1,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_2,
- i64,
- calc_max!(super::I64_MAX, 2),
- 2,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_3,
- i64,
- calc_max!(super::I64_MAX, 3),
- 3,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_4,
- i64,
- calc_max!(super::I64_MAX, 4),
- 4,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_5,
- i64,
- calc_max!(super::I64_MAX, 5),
- 5,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_6,
- i64,
- calc_max!(super::I64_MAX, 6),
- 6,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_7,
- i64,
- calc_max!(super::I64_MAX, 7),
- 7,
- read_int,
- write_int
- );
- qc_byte_order!(
- prop_int_8,
- i64,
- calc_max!(super::I64_MAX, 8),
- 8,
- read_int,
- write_int
- );
-
- qc_byte_order!(
- prop_int128_1,
- Wi128<i128>,
- 1,
- 1,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_2,
- Wi128<i128>,
- 2,
- 2,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_3,
- Wi128<i128>,
- 3,
- 3,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_4,
- Wi128<i128>,
- 4,
- 4,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_5,
- Wi128<i128>,
- 5,
- 5,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_6,
- Wi128<i128>,
- 6,
- 6,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_7,
- Wi128<i128>,
- 7,
- 7,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_8,
- Wi128<i128>,
- 8,
- 8,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_9,
- Wi128<i128>,
- 9,
- 9,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_10,
- Wi128<i128>,
- 10,
- 10,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_11,
- Wi128<i128>,
- 11,
- 11,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_12,
- Wi128<i128>,
- 12,
- 12,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_13,
- Wi128<i128>,
- 13,
- 13,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_14,
- Wi128<i128>,
- 14,
- 14,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_15,
- Wi128<i128>,
- 15,
- 15,
- read_int128,
- write_int128
- );
- qc_byte_order!(
- prop_int128_16,
- Wi128<i128>,
- 16,
- 16,
- read_int128,
- write_int128
- );
-
- // Test that all of the byte conversion functions panic when given a
- // buffer that is too small.
- //
- // These tests are critical to ensure safety, otherwise we might end up
- // with a buffer overflow.
- macro_rules! too_small {
- ($name:ident, $maximally_small:expr, $zero:expr,
- $read:ident, $write:ident) => {
- mod $name {
- use crate::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
-
- #[test]
- #[should_panic]
- fn read_big_endian() {
- let buf = [0; $maximally_small];
- BigEndian::$read(&buf);
- }
-
- #[test]
- #[should_panic]
- fn read_little_endian() {
- let buf = [0; $maximally_small];
- LittleEndian::$read(&buf);
- }
-
- #[test]
- #[should_panic]
- fn read_native_endian() {
- let buf = [0; $maximally_small];
- NativeEndian::$read(&buf);
- }
-
- #[test]
- #[should_panic]
- fn write_big_endian() {
- let mut buf = [0; $maximally_small];
- BigEndian::$write(&mut buf, $zero);
- }
-
- #[test]
- #[should_panic]
- fn write_little_endian() {
- let mut buf = [0; $maximally_small];
- LittleEndian::$write(&mut buf, $zero);
- }
-
- #[test]
- #[should_panic]
- fn write_native_endian() {
- let mut buf = [0; $maximally_small];
- NativeEndian::$write(&mut buf, $zero);
- }
- }
- };
- ($name:ident, $maximally_small:expr, $read:ident) => {
- mod $name {
- use crate::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
-
- #[test]
- #[should_panic]
- fn read_big_endian() {
- let buf = [0; $maximally_small];
- BigEndian::$read(&buf, $maximally_small + 1);
- }
-
- #[test]
- #[should_panic]
- fn read_little_endian() {
- let buf = [0; $maximally_small];
- LittleEndian::$read(&buf, $maximally_small + 1);
- }
-
- #[test]
- #[should_panic]
- fn read_native_endian() {
- let buf = [0; $maximally_small];
- NativeEndian::$read(&buf, $maximally_small + 1);
- }
- }
- };
- }
-
- too_small!(small_u16, 1, 0, read_u16, write_u16);
- too_small!(small_i16, 1, 0, read_i16, write_i16);
- too_small!(small_u32, 3, 0, read_u32, write_u32);
- too_small!(small_i32, 3, 0, read_i32, write_i32);
- too_small!(small_u64, 7, 0, read_u64, write_u64);
- too_small!(small_i64, 7, 0, read_i64, write_i64);
- too_small!(small_f32, 3, 0.0, read_f32, write_f32);
- too_small!(small_f64, 7, 0.0, read_f64, write_f64);
- too_small!(small_u128, 15, 0, read_u128, write_u128);
- too_small!(small_i128, 15, 0, read_i128, write_i128);
-
- too_small!(small_uint_1, 1, read_uint);
- too_small!(small_uint_2, 2, read_uint);
- too_small!(small_uint_3, 3, read_uint);
- too_small!(small_uint_4, 4, read_uint);
- too_small!(small_uint_5, 5, read_uint);
- too_small!(small_uint_6, 6, read_uint);
- too_small!(small_uint_7, 7, read_uint);
-
- too_small!(small_uint128_1, 1, read_uint128);
- too_small!(small_uint128_2, 2, read_uint128);
- too_small!(small_uint128_3, 3, read_uint128);
- too_small!(small_uint128_4, 4, read_uint128);
- too_small!(small_uint128_5, 5, read_uint128);
- too_small!(small_uint128_6, 6, read_uint128);
- too_small!(small_uint128_7, 7, read_uint128);
- too_small!(small_uint128_8, 8, read_uint128);
- too_small!(small_uint128_9, 9, read_uint128);
- too_small!(small_uint128_10, 10, read_uint128);
- too_small!(small_uint128_11, 11, read_uint128);
- too_small!(small_uint128_12, 12, read_uint128);
- too_small!(small_uint128_13, 13, read_uint128);
- too_small!(small_uint128_14, 14, read_uint128);
- too_small!(small_uint128_15, 15, read_uint128);
-
- too_small!(small_int_1, 1, read_int);
- too_small!(small_int_2, 2, read_int);
- too_small!(small_int_3, 3, read_int);
- too_small!(small_int_4, 4, read_int);
- too_small!(small_int_5, 5, read_int);
- too_small!(small_int_6, 6, read_int);
- too_small!(small_int_7, 7, read_int);
-
- too_small!(small_int128_1, 1, read_int128);
- too_small!(small_int128_2, 2, read_int128);
- too_small!(small_int128_3, 3, read_int128);
- too_small!(small_int128_4, 4, read_int128);
- too_small!(small_int128_5, 5, read_int128);
- too_small!(small_int128_6, 6, read_int128);
- too_small!(small_int128_7, 7, read_int128);
- too_small!(small_int128_8, 8, read_int128);
- too_small!(small_int128_9, 9, read_int128);
- too_small!(small_int128_10, 10, read_int128);
- too_small!(small_int128_11, 11, read_int128);
- too_small!(small_int128_12, 12, read_int128);
- too_small!(small_int128_13, 13, read_int128);
- too_small!(small_int128_14, 14, read_int128);
- too_small!(small_int128_15, 15, read_int128);
-
- // Test that reading/writing slices enforces the correct lengths.
- macro_rules! slice_lengths {
- ($name:ident, $read:ident, $write:ident,
- $num_bytes:expr, $numbers:expr) => {
- mod $name {
- use crate::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
-
- #[test]
- #[should_panic]
- fn read_big_endian() {
- let bytes = [0; $num_bytes];
- let mut numbers = $numbers;
- BigEndian::$read(&bytes, &mut numbers);
- }
-
- #[test]
- #[should_panic]
- fn read_little_endian() {
- let bytes = [0; $num_bytes];
- let mut numbers = $numbers;
- LittleEndian::$read(&bytes, &mut numbers);
- }
-
- #[test]
- #[should_panic]
- fn read_native_endian() {
- let bytes = [0; $num_bytes];
- let mut numbers = $numbers;
- NativeEndian::$read(&bytes, &mut numbers);
- }
-
- #[test]
- #[should_panic]
- fn write_big_endian() {
- let mut bytes = [0; $num_bytes];
- let numbers = $numbers;
- BigEndian::$write(&numbers, &mut bytes);
- }
-
- #[test]
- #[should_panic]
- fn write_little_endian() {
- let mut bytes = [0; $num_bytes];
- let numbers = $numbers;
- LittleEndian::$write(&numbers, &mut bytes);
- }
-
- #[test]
- #[should_panic]
- fn write_native_endian() {
- let mut bytes = [0; $num_bytes];
- let numbers = $numbers;
- NativeEndian::$write(&numbers, &mut bytes);
- }
- }
- };
- }
-
- slice_lengths!(
- slice_len_too_small_u16,
- read_u16_into,
- write_u16_into,
- 3,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_u16,
- read_u16_into,
- write_u16_into,
- 5,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_small_i16,
- read_i16_into,
- write_i16_into,
- 3,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_i16,
- read_i16_into,
- write_i16_into,
- 5,
- [0, 0]
- );
-
- slice_lengths!(
- slice_len_too_small_u32,
- read_u32_into,
- write_u32_into,
- 7,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_u32,
- read_u32_into,
- write_u32_into,
- 9,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_small_i32,
- read_i32_into,
- write_i32_into,
- 7,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_i32,
- read_i32_into,
- write_i32_into,
- 9,
- [0, 0]
- );
-
- slice_lengths!(
- slice_len_too_small_u64,
- read_u64_into,
- write_u64_into,
- 15,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_u64,
- read_u64_into,
- write_u64_into,
- 17,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_small_i64,
- read_i64_into,
- write_i64_into,
- 15,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_i64,
- read_i64_into,
- write_i64_into,
- 17,
- [0, 0]
- );
-
- slice_lengths!(
- slice_len_too_small_u128,
- read_u128_into,
- write_u128_into,
- 31,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_u128,
- read_u128_into,
- write_u128_into,
- 33,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_small_i128,
- read_i128_into,
- write_i128_into,
- 31,
- [0, 0]
- );
- slice_lengths!(
- slice_len_too_big_i128,
- read_i128_into,
- write_i128_into,
- 33,
- [0, 0]
- );
-
- #[test]
- fn uint_bigger_buffer() {
- use crate::{ByteOrder, LittleEndian};
- let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
- assert_eq!(n, 0x05_0403_0201);
- }
-
- #[test]
- fn regression173_array_impl() {
- use crate::{BigEndian, ByteOrder, LittleEndian};
-
- let xs = [0; 100];
-
- let x = BigEndian::read_u16(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_u32(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_u64(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_u128(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_i16(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_i32(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_i64(&xs);
- assert_eq!(x, 0);
- let x = BigEndian::read_i128(&xs);
- assert_eq!(x, 0);
-
- let x = LittleEndian::read_u16(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_u32(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_u64(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_u128(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_i16(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_i32(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_i64(&xs);
- assert_eq!(x, 0);
- let x = LittleEndian::read_i128(&xs);
- assert_eq!(x, 0);
- }
-}
-
-#[cfg(test)]
-#[cfg(feature = "std")]
-mod stdtests {
- extern crate quickcheck;
- extern crate rand;
-
- use self::quickcheck::{QuickCheck, StdGen, Testable};
- use self::rand::thread_rng;
-
- fn qc_unsized<A: Testable>(f: A) {
- QuickCheck::new()
- .gen(StdGen::new(thread_rng(), 16))
- .tests(1_00)
- .max_tests(10_000)
- .quickcheck(f);
- }
-
- macro_rules! calc_max {
- ($max:expr, $bytes:expr) => {
- ($max - 1) >> (8 * (8 - $bytes))
- };
- }
-
- macro_rules! qc_bytes_ext {
- ($name:ident, $ty_int:ty, $max:expr,
- $bytes:expr, $read:ident, $write:ident) => {
- mod $name {
- #[allow(unused_imports)]
- use crate::test::{qc_sized, Wi128};
- use crate::{
- BigEndian, LittleEndian, NativeEndian, ReadBytesExt,
- WriteBytesExt,
- };
- use std::io::Cursor;
-
- #[test]
- fn big_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut wtr = vec![];
- wtr.$write::<BigEndian>(n.clone()).unwrap();
- let offset = wtr.len() - $bytes;
- let mut rdr = Cursor::new(&mut wtr[offset..]);
- n == rdr.$read::<BigEndian>($bytes).unwrap()
- }
- qc_sized(prop as fn($ty_int) -> bool, $max);
- }
-
- #[test]
- fn little_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut wtr = vec![];
- wtr.$write::<LittleEndian>(n.clone()).unwrap();
- let mut rdr = Cursor::new(wtr);
- n == rdr.$read::<LittleEndian>($bytes).unwrap()
- }
- qc_sized(prop as fn($ty_int) -> bool, $max);
- }
-
- #[test]
- fn native_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut wtr = vec![];
- wtr.$write::<NativeEndian>(n.clone()).unwrap();
- let offset = if cfg!(target_endian = "big") {
- wtr.len() - $bytes
- } else {
- 0
- };
- let mut rdr = Cursor::new(&mut wtr[offset..]);
- n == rdr.$read::<NativeEndian>($bytes).unwrap()
- }
- qc_sized(prop as fn($ty_int) -> bool, $max);
- }
- }
- };
- ($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => {
- mod $name {
- #[allow(unused_imports)]
- use crate::test::{qc_sized, Wi128};
- use crate::{
- BigEndian, LittleEndian, NativeEndian, ReadBytesExt,
- WriteBytesExt,
- };
- use std::io::Cursor;
-
- #[test]
- fn big_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut wtr = vec![];
- wtr.$write::<BigEndian>(n.clone()).unwrap();
- let mut rdr = Cursor::new(wtr);
- n == rdr.$read::<BigEndian>().unwrap()
- }
- qc_sized(prop as fn($ty_int) -> bool, $max - 1);
- }
-
- #[test]
- fn little_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut wtr = vec![];
- wtr.$write::<LittleEndian>(n.clone()).unwrap();
- let mut rdr = Cursor::new(wtr);
- n == rdr.$read::<LittleEndian>().unwrap()
- }
- qc_sized(prop as fn($ty_int) -> bool, $max - 1);
- }
-
- #[test]
- fn native_endian() {
- fn prop(n: $ty_int) -> bool {
- let mut wtr = vec![];
- wtr.$write::<NativeEndian>(n.clone()).unwrap();
- let mut rdr = Cursor::new(wtr);
- n == rdr.$read::<NativeEndian>().unwrap()
- }
- qc_sized(prop as fn($ty_int) -> bool, $max - 1);
- }
- }
- };
- }
-
- qc_bytes_ext!(
- prop_ext_u16,
- u16,
- ::std::u16::MAX as u64,
- read_u16,
- write_u16
- );
- qc_bytes_ext!(
- prop_ext_i16,
- i16,
- ::std::i16::MAX as u64,
- read_i16,
- write_i16
- );
- qc_bytes_ext!(
- prop_ext_u32,
- u32,
- ::std::u32::MAX as u64,
- read_u32,
- write_u32
- );
- qc_bytes_ext!(
- prop_ext_i32,
- i32,
- ::std::i32::MAX as u64,
- read_i32,
- write_i32
- );
- qc_bytes_ext!(
- prop_ext_u64,
- u64,
- ::std::u64::MAX as u64,
- read_u64,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_i64,
- i64,
- ::std::i64::MAX as u64,
- read_i64,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_f32,
- f32,
- ::std::u64::MAX as u64,
- read_f32,
- write_f32
- );
- qc_bytes_ext!(
- prop_ext_f64,
- f64,
- ::std::i64::MAX as u64,
- read_f64,
- write_f64
- );
-
- qc_bytes_ext!(prop_ext_u128, Wi128<u128>, 16 + 1, read_u128, write_u128);
- qc_bytes_ext!(prop_ext_i128, Wi128<i128>, 16 + 1, read_i128, write_i128);
-
- qc_bytes_ext!(
- prop_ext_uint_1,
- u64,
- calc_max!(crate::test::U64_MAX, 1),
- 1,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_2,
- u64,
- calc_max!(crate::test::U64_MAX, 2),
- 2,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_3,
- u64,
- calc_max!(crate::test::U64_MAX, 3),
- 3,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_4,
- u64,
- calc_max!(crate::test::U64_MAX, 4),
- 4,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_5,
- u64,
- calc_max!(crate::test::U64_MAX, 5),
- 5,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_6,
- u64,
- calc_max!(crate::test::U64_MAX, 6),
- 6,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_7,
- u64,
- calc_max!(crate::test::U64_MAX, 7),
- 7,
- read_uint,
- write_u64
- );
- qc_bytes_ext!(
- prop_ext_uint_8,
- u64,
- calc_max!(crate::test::U64_MAX, 8),
- 8,
- read_uint,
- write_u64
- );
-
- qc_bytes_ext!(
- prop_ext_uint128_1,
- Wi128<u128>,
- 1,
- 1,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_2,
- Wi128<u128>,
- 2,
- 2,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_3,
- Wi128<u128>,
- 3,
- 3,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_4,
- Wi128<u128>,
- 4,
- 4,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_5,
- Wi128<u128>,
- 5,
- 5,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_6,
- Wi128<u128>,
- 6,
- 6,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_7,
- Wi128<u128>,
- 7,
- 7,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_8,
- Wi128<u128>,
- 8,
- 8,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_9,
- Wi128<u128>,
- 9,
- 9,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_10,
- Wi128<u128>,
- 10,
- 10,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_11,
- Wi128<u128>,
- 11,
- 11,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_12,
- Wi128<u128>,
- 12,
- 12,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_13,
- Wi128<u128>,
- 13,
- 13,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_14,
- Wi128<u128>,
- 14,
- 14,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_15,
- Wi128<u128>,
- 15,
- 15,
- read_uint128,
- write_u128
- );
- qc_bytes_ext!(
- prop_ext_uint128_16,
- Wi128<u128>,
- 16,
- 16,
- read_uint128,
- write_u128
- );
-
- qc_bytes_ext!(
- prop_ext_int_1,
- i64,
- calc_max!(crate::test::I64_MAX, 1),
- 1,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_2,
- i64,
- calc_max!(crate::test::I64_MAX, 2),
- 2,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_3,
- i64,
- calc_max!(crate::test::I64_MAX, 3),
- 3,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_4,
- i64,
- calc_max!(crate::test::I64_MAX, 4),
- 4,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_5,
- i64,
- calc_max!(crate::test::I64_MAX, 5),
- 5,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_6,
- i64,
- calc_max!(crate::test::I64_MAX, 6),
- 6,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_7,
- i64,
- calc_max!(crate::test::I64_MAX, 1),
- 7,
- read_int,
- write_i64
- );
- qc_bytes_ext!(
- prop_ext_int_8,
- i64,
- calc_max!(crate::test::I64_MAX, 8),
- 8,
- read_int,
- write_i64
- );
-
- qc_bytes_ext!(
- prop_ext_int128_1,
- Wi128<i128>,
- 1,
- 1,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_2,
- Wi128<i128>,
- 2,
- 2,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_3,
- Wi128<i128>,
- 3,
- 3,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_4,
- Wi128<i128>,
- 4,
- 4,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_5,
- Wi128<i128>,
- 5,
- 5,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_6,
- Wi128<i128>,
- 6,
- 6,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_7,
- Wi128<i128>,
- 7,
- 7,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_8,
- Wi128<i128>,
- 8,
- 8,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_9,
- Wi128<i128>,
- 9,
- 9,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_10,
- Wi128<i128>,
- 10,
- 10,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_11,
- Wi128<i128>,
- 11,
- 11,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_12,
- Wi128<i128>,
- 12,
- 12,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_13,
- Wi128<i128>,
- 13,
- 13,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_14,
- Wi128<i128>,
- 14,
- 14,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_15,
- Wi128<i128>,
- 15,
- 15,
- read_int128,
- write_i128
- );
- qc_bytes_ext!(
- prop_ext_int128_16,
- Wi128<i128>,
- 16,
- 16,
- read_int128,
- write_i128
- );
-
- // Test slice serialization/deserialization.
- macro_rules! qc_slice {
- ($name:ident, $ty_int:ty, $read:ident, $write:ident, $zero:expr) => {
- mod $name {
- use super::qc_unsized;
- #[allow(unused_imports)]
- use crate::test::Wi128;
- use crate::{
- BigEndian, ByteOrder, LittleEndian, NativeEndian,
- };
- use core::mem::size_of;
-
- #[test]
- fn big_endian() {
- #[allow(unused_unsafe)]
- fn prop(numbers: Vec<$ty_int>) -> bool {
- let numbers: Vec<_> =
- numbers.into_iter().map(|x| x.clone()).collect();
- let num_bytes = size_of::<$ty_int>() * numbers.len();
- let mut bytes = vec![0; num_bytes];
-
- BigEndian::$write(&numbers, &mut bytes);
-
- let mut got = vec![$zero; numbers.len()];
- unsafe {
- BigEndian::$read(&bytes, &mut got);
- }
-
- numbers == got
- }
- qc_unsized(prop as fn(_) -> bool);
- }
-
- #[test]
- fn little_endian() {
- #[allow(unused_unsafe)]
- fn prop(numbers: Vec<$ty_int>) -> bool {
- let numbers: Vec<_> =
- numbers.into_iter().map(|x| x.clone()).collect();
- let num_bytes = size_of::<$ty_int>() * numbers.len();
- let mut bytes = vec![0; num_bytes];
-
- LittleEndian::$write(&numbers, &mut bytes);
-
- let mut got = vec![$zero; numbers.len()];
- unsafe {
- LittleEndian::$read(&bytes, &mut got);
- }
-
- numbers == got
- }
- qc_unsized(prop as fn(_) -> bool);
- }
-
- #[test]
- fn native_endian() {
- #[allow(unused_unsafe)]
- fn prop(numbers: Vec<$ty_int>) -> bool {
- let numbers: Vec<_> =
- numbers.into_iter().map(|x| x.clone()).collect();
- let num_bytes = size_of::<$ty_int>() * numbers.len();
- let mut bytes = vec![0; num_bytes];
-
- NativeEndian::$write(&numbers, &mut bytes);
-
- let mut got = vec![$zero; numbers.len()];
- unsafe {
- NativeEndian::$read(&bytes, &mut got);
- }
-
- numbers == got
- }
- qc_unsized(prop as fn(_) -> bool);
- }
- }
- };
- }
-
- qc_slice!(prop_slice_u16, u16, read_u16_into, write_u16_into, 0);
- qc_slice!(prop_slice_i16, i16, read_i16_into, write_i16_into, 0);
- qc_slice!(prop_slice_u32, u32, read_u32_into, write_u32_into, 0);
- qc_slice!(prop_slice_i32, i32, read_i32_into, write_i32_into, 0);
- qc_slice!(prop_slice_u64, u64, read_u64_into, write_u64_into, 0);
- qc_slice!(prop_slice_i64, i64, read_i64_into, write_i64_into, 0);
- qc_slice!(
- prop_slice_u128,
- Wi128<u128>,
- read_u128_into,
- write_u128_into,
- 0
- );
- qc_slice!(
- prop_slice_i128,
- Wi128<i128>,
- read_i128_into,
- write_i128_into,
- 0
- );
-
- qc_slice!(prop_slice_f32, f32, read_f32_into, write_f32_into, 0.0);
- qc_slice!(prop_slice_f64, f64, read_f64_into, write_f64_into, 0.0);
-}
diff --git a/vendor/camino/.cargo-checksum.json b/vendor/camino/.cargo-checksum.json
index 1de1f0c97..81a1f0f60 100644
--- a/vendor/camino/.cargo-checksum.json
+++ b/vendor/camino/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"886087c5abaa1078e179e173b997fd4bffd93e47b2914defd8148f3f396e98f0","CODE_OF_CONDUCT.md":"f51e207c2961ec061cac5c8aa9dd3098c3437de2c106d740c2aae90771bc0f86","Cargo.toml":"17bc7f765ef82a295aff4292261d23dc0c6c75b44e6c3016631cc087d5fe20f6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"84762d717d0f2358c56f54ee46a6ca5f1582b7d3843f7a4d6e553ea04a57ca1b","build.rs":"4e46d73efd79ec269ddc1b2578cad051c66195225bfdf012e4ed430f9f98a3ab","clippy.toml":"818cba7332cc56b019d59e09805a3498f523da788f51454742905f1987c0b563","rustfmt.toml":"bf9776adb152b3fdc0d75c0929ede148c3e28c58f909a7d052865bc332e8958f","src/lib.rs":"a59a425a4bf1e2ae8f16bc0349fadf0fe3f7ec2effa44137bd59e17c3ff15456","src/proptest_impls.rs":"aa17bad810abe4a7b6c7a2c3163ae9749b03dd8bcef5043b0c4b9d00977f981c","src/serde_impls.rs":"eb7f00d1ceb7135506047dbefd7e6acee0364b5a9194111f49dbf2d1eb3661ac","src/tests.rs":"d6108c540dc93446b17d297b50372f799ef777c2cb0280fd37824a102ec24533","tests/integration_tests.rs":"b664a7555d2e5ac9ab71384e3ccfb73c01abe4c401f8de32e234c03b4d19d0f8"},"package":"869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"2530b12d7ddf3395bbc4c10557e57531498039ba28528b91ffc3f3deefc76f77","CODE_OF_CONDUCT.md":"f51e207c2961ec061cac5c8aa9dd3098c3437de2c106d740c2aae90771bc0f86","Cargo.toml":"7bf7de17ab10cd95aadf102f37c0b8a58f0c31f90cfeee81126ead8ad3cb0a26","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"84762d717d0f2358c56f54ee46a6ca5f1582b7d3843f7a4d6e553ea04a57ca1b","build.rs":"ca6914ad35e69842b6fba6e436d0417f39dbe6ee18694d4dd89b372d31cbf715","clippy.toml":"818cba7332cc56b019d59e09805a3498f523da788f51454742905f1987c0b563","rustfmt.toml":"bf9776adb152b3fdc0d75c0929ede148c3e28c58f909a7d052865bc332e8958f","src/lib.rs":"3a744ca7df473bb8bd97e1f4a961d517cb7379b8756e38893dd9d53a169c41e1","src/proptest_impls.rs":"aa17bad810abe4a7b6c7a2c3163ae9749b03dd8bcef5043b0c4b9d00977f981c","src/serde_impls.rs":"eb7f00d1ceb7135506047dbefd7e6acee0364b5a9194111f49dbf2d1eb3661ac","src/tests.rs":"d6108c540dc93446b17d297b50372f799ef777c2cb0280fd37824a102ec24533","tests/integration_tests.rs":"b664a7555d2e5ac9ab71384e3ccfb73c01abe4c401f8de32e234c03b4d19d0f8"},"package":"88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e"} \ No newline at end of file
diff --git a/vendor/camino/CHANGELOG.md b/vendor/camino/CHANGELOG.md
index b9a04de7a..67c2ea8d3 100644
--- a/vendor/camino/CHANGELOG.md
+++ b/vendor/camino/CHANGELOG.md
@@ -3,6 +3,24 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.1.1] - 2022-08-12
+
+### Fixed
+
+- Fixed a build regression on older nightlies in the 1.63 series
+ ([#22](https://github.com/camino-rs/camino/issues/22)).
+- Documentation fixes.
+
+## [1.1.0] - 2022-08-11
+
+### Added
+
+- New methods, mirroring those in recent versions of Rust:
+ - `Utf8Path::try_exists` checks whether a path exists. Note that while `std::path::Path` only provides this method for Rust 1.58 and above, `camino` backfills the method for all Rust versions it supports.
+ - `Utf8PathBuf::shrink_to` shrinks a `Utf8PathBuf` to a given size. This was added in, and is gated on, Rust 1.56+.
+ - `Utf8PathBuf::try_reserve` and `Utf8PathBuf::try_reserve_exact` implement fallible allocations. These were added in, and are gated on, Rust 1.63+.
+- A number of `#[must_use]` annotations to APIs, mirroring those added to `Path` and `PathBuf` in recent versions of Rust. The minor version bump is due to this change.
+
## [1.0.9] - 2022-05-19
### Fixed
@@ -24,7 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `Utf8Path::is_symlink` checks whether a path is a symlink. Note that while `std::path::Path` only
- provides this method for version 1.58 and above, `camino` polyfills the method for all Rust versions
+ provides this method for version 1.58 and above, `camino` backfills the method for all Rust versions
it supports.
### Changed
@@ -83,6 +101,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Initial release.
+[1.1.1]: https://github.com/camino-rs/camino/releases/tag/camino-1.1.1
+[1.1.0]: https://github.com/camino-rs/camino/releases/tag/camino-1.1.0
[1.0.9]: https://github.com/camino-rs/camino/releases/tag/camino-1.0.9
[1.0.8]: https://github.com/camino-rs/camino/releases/tag/camino-1.0.8
[1.0.7]: https://github.com/camino-rs/camino/releases/tag/camino-1.0.7
diff --git a/vendor/camino/Cargo.toml b/vendor/camino/Cargo.toml
index cd2bd9fea..28c007855 100644
--- a/vendor/camino/Cargo.toml
+++ b/vendor/camino/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "camino"
-version = "1.0.9"
+version = "1.1.1"
authors = [
"Without Boats <saoirse@without.boats>",
"Ashley Williams <ashley666ashley@gmail.com>",
diff --git a/vendor/camino/build.rs b/vendor/camino/build.rs
index bc3e4480d..7f5cbdf9b 100644
--- a/vendor/camino/build.rs
+++ b/vendor/camino/build.rs
@@ -21,10 +21,28 @@ fn main() {
if compiler.minor >= 44 {
println!("cargo:rustc-cfg=path_buf_capacity");
}
+ if compiler.minor >= 56 {
+ println!("cargo:rustc-cfg=shrink_to");
+ }
+ // Stable and beta 1.63 have a stable try_reserve_2.
+ if (compiler.minor >= 63
+ && (compiler.channel == ReleaseChannel::Stable || compiler.channel == ReleaseChannel::Beta))
+ || compiler.minor >= 64
+ {
+ println!("cargo:rustc-cfg=try_reserve_2");
+ }
}
struct Compiler {
minor: u32,
+ channel: ReleaseChannel,
+}
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+enum ReleaseChannel {
+ Stable,
+ Beta,
+ Nightly,
}
fn rustc_version() -> Option<Compiler> {
@@ -36,5 +54,12 @@ fn rustc_version() -> Option<Compiler> {
return None;
}
let minor = pieces.next()?.parse().ok()?;
- Some(Compiler { minor })
+ let channel = if version.contains("nightly") {
+ ReleaseChannel::Nightly
+ } else if version.contains("beta") {
+ ReleaseChannel::Beta
+ } else {
+ ReleaseChannel::Stable
+ };
+ Some(Compiler { minor, channel })
}
diff --git a/vendor/camino/src/lib.rs b/vendor/camino/src/lib.rs
index 4a1b6dfd7..fcfba3805 100644
--- a/vendor/camino/src/lib.rs
+++ b/vendor/camino/src/lib.rs
@@ -120,6 +120,7 @@ impl Utf8PathBuf {
///
/// let path = Utf8PathBuf::new();
/// ```
+ #[must_use]
pub fn new() -> Utf8PathBuf {
Utf8PathBuf(PathBuf::new())
}
@@ -177,6 +178,7 @@ impl Utf8PathBuf {
/// let new_utf8_path_buf = Utf8PathBuf::from_path_buf(std_path_buf).unwrap();
/// assert_eq!(new_utf8_path_buf, "foo.txt");
/// ```
+ #[must_use = "`self` will be dropped if the result is not used"]
pub fn into_std_path_buf(self) -> PathBuf {
self.into()
}
@@ -202,6 +204,7 @@ impl Utf8PathBuf {
///
/// [`with_capacity`]: PathBuf::with_capacity
#[cfg(path_buf_capacity)]
+ #[must_use]
pub fn with_capacity(capacity: usize) -> Utf8PathBuf {
Utf8PathBuf(PathBuf::with_capacity(capacity))
}
@@ -216,6 +219,7 @@ impl Utf8PathBuf {
/// let p = Utf8PathBuf::from("/test");
/// assert_eq!(Utf8Path::new("/test"), p.as_path());
/// ```
+ #[must_use]
pub fn as_path(&self) -> &Utf8Path {
// SAFETY: every Utf8PathBuf constructor ensures that self is valid UTF-8
unsafe { Utf8Path::assume_utf8(&*self.0) }
@@ -347,6 +351,7 @@ impl Utf8PathBuf {
/// let s = p.into_string();
/// assert_eq!(s, "/the/head");
/// ```
+ #[must_use = "`self` will be dropped if the result is not used"]
pub fn into_string(self) -> String {
self.into_os_string().into_string().unwrap()
}
@@ -363,11 +368,13 @@ impl Utf8PathBuf {
/// let s = p.into_os_string();
/// assert_eq!(s, OsStr::new("/the/head"));
/// ```
+ #[must_use = "`self` will be dropped if the result is not used"]
pub fn into_os_string(self) -> OsString {
self.0.into_os_string()
}
/// Converts this `Utf8PathBuf` into a [boxed](Box) [`Utf8Path`].
+ #[must_use = "`self` will be dropped if the result is not used"]
pub fn into_boxed_path(self) -> Box<Utf8Path> {
let ptr = Box::into_raw(self.0.into_boxed_path()) as *mut Utf8Path;
// SAFETY:
@@ -384,6 +391,7 @@ impl Utf8PathBuf {
///
/// [`capacity`]: PathBuf::capacity
#[cfg(path_buf_capacity)]
+ #[must_use]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
@@ -408,6 +416,20 @@ impl Utf8PathBuf {
self.0.reserve(additional)
}
+ /// Invokes [`try_reserve`] on the underlying instance of [`PathBuf`].
+ ///
+ /// *Requires Rust 1.63 or newer.*
+ ///
+ /// [`try_reserve`]: PathBuf::try_reserve
+ #[cfg(try_reserve_2)]
+ #[inline]
+ pub fn try_reserve(
+ &mut self,
+ additional: usize,
+ ) -> Result<(), std::collections::TryReserveError> {
+ self.0.try_reserve(additional)
+ }
+
/// Invokes [`reserve_exact`] on the underlying instance of [`PathBuf`].
///
/// *Requires Rust 1.44 or newer.*
@@ -418,6 +440,20 @@ impl Utf8PathBuf {
self.0.reserve_exact(additional)
}
+ /// Invokes [`try_reserve_exact`] on the underlying instance of [`PathBuf`].
+ ///
+ /// *Requires Rust 1.63 or newer.*
+ ///
+ /// [`try_reserve_exact`]: PathBuf::try_reserve_exact
+ #[cfg(try_reserve_2)]
+ #[inline]
+ pub fn try_reserve_exact(
+ &mut self,
+ additional: usize,
+ ) -> Result<(), std::collections::TryReserveError> {
+ self.0.try_reserve_exact(additional)
+ }
+
/// Invokes [`shrink_to_fit`] on the underlying instance of [`PathBuf`].
///
/// *Requires Rust 1.44 or newer.*
@@ -427,6 +463,17 @@ impl Utf8PathBuf {
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit()
}
+
+ /// Invokes [`shrink_to`] on the underlying instance of [`PathBuf`].
+ ///
+ /// *Requires Rust 1.56 or newer.*
+ ///
+ /// [`shrink_to`]: PathBuf::shrink_to
+ #[cfg(shrink_to)]
+ #[inline]
+ pub fn shrink_to(&mut self, min_capacity: usize) {
+ self.0.shrink_to(min_capacity)
+ }
}
impl Deref for Utf8PathBuf {
@@ -586,6 +633,7 @@ impl Utf8Path {
/// ```
///
/// [`str`]: str
+ #[must_use]
pub fn as_str(&self) -> &str {
// SAFETY: every Utf8Path constructor ensures that self is valid UTF-8
unsafe { assume_utf8(self.as_os_str()) }
@@ -601,6 +649,7 @@ impl Utf8Path {
/// let os_str = Utf8Path::new("foo.txt").as_os_str();
/// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
/// ```
+ #[must_use]
pub fn as_os_str(&self) -> &OsStr {
self.0.as_os_str()
}
@@ -615,6 +664,8 @@ impl Utf8Path {
/// let path_buf = Utf8Path::new("foo.txt").to_path_buf();
/// assert_eq!(path_buf, Utf8PathBuf::from("foo.txt"));
/// ```
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
pub fn to_path_buf(&self) -> Utf8PathBuf {
Utf8PathBuf(self.0.to_path_buf())
}
@@ -637,6 +688,7 @@ impl Utf8Path {
/// ```
///
/// [`has_root`]: Utf8Path::has_root
+ #[must_use]
pub fn is_absolute(&self) -> bool {
self.0.is_absolute()
}
@@ -654,6 +706,7 @@ impl Utf8Path {
/// ```
///
/// [`is_absolute`]: Utf8Path::is_absolute
+ #[must_use]
pub fn is_relative(&self) -> bool {
self.0.is_relative()
}
@@ -674,6 +727,7 @@ impl Utf8Path {
///
/// assert!(Utf8Path::new("/etc/passwd").has_root());
/// ```
+ #[must_use]
pub fn has_root(&self) -> bool {
self.0.has_root()
}
@@ -695,6 +749,7 @@ impl Utf8Path {
/// assert_eq!(grand_parent, Utf8Path::new("/"));
/// assert_eq!(grand_parent.parent(), None);
/// ```
+ #[must_use]
pub fn parent(&self) -> Option<&Utf8Path> {
self.0.parent().map(|path| {
// SAFETY: self is valid UTF-8, so parent is valid UTF-8 as well
@@ -753,6 +808,7 @@ impl Utf8Path {
/// assert_eq!(None, Utf8Path::new("foo.txt/..").file_name());
/// assert_eq!(None, Utf8Path::new("/").file_name());
/// ```
+ #[must_use]
pub fn file_name(&self) -> Option<&str> {
self.0.file_name().map(|s| {
// SAFETY: self is valid UTF-8, so file_name is valid UTF-8 as well
@@ -818,6 +874,7 @@ impl Utf8Path {
///
/// assert!(!Utf8Path::new("/etc/foo.rs").starts_with("/etc/foo"));
/// ```
+ #[must_use]
pub fn starts_with(&self, base: impl AsRef<Path>) -> bool {
self.0.starts_with(base)
}
@@ -840,6 +897,7 @@ impl Utf8Path {
/// assert!(!path.ends_with("/resolv.conf"));
/// assert!(!path.ends_with("conf")); // use .extension() instead
/// ```
+ #[must_use]
pub fn ends_with(&self, base: impl AsRef<Path>) -> bool {
self.0.ends_with(base)
}
@@ -863,6 +921,7 @@ impl Utf8Path {
/// assert_eq!("foo", Utf8Path::new("foo.rs").file_stem().unwrap());
/// assert_eq!("foo.tar", Utf8Path::new("foo.tar.gz").file_stem().unwrap());
/// ```
+ #[must_use]
pub fn file_stem(&self) -> Option<&str> {
self.0.file_stem().map(|s| {
// SAFETY: self is valid UTF-8, so file_stem is valid UTF-8 as well
@@ -889,6 +948,7 @@ impl Utf8Path {
/// assert_eq!("rs", Utf8Path::new("foo.rs").extension().unwrap());
/// assert_eq!("gz", Utf8Path::new("foo.tar.gz").extension().unwrap());
/// ```
+ #[must_use]
pub fn extension(&self) -> Option<&str> {
self.0.extension().map(|s| {
// SAFETY: self is valid UTF-8, so extension is valid UTF-8 as well
@@ -907,6 +967,7 @@ impl Utf8Path {
///
/// assert_eq!(Utf8Path::new("/etc").join("passwd"), Utf8PathBuf::from("/etc/passwd"));
/// ```
+ #[must_use]
pub fn join(&self, path: impl AsRef<Utf8Path>) -> Utf8PathBuf {
Utf8PathBuf(self.0.join(&path.as_ref().0))
}
@@ -923,6 +984,7 @@ impl Utf8Path {
///
/// assert_eq!(Utf8Path::new("/etc").join_os("passwd"), PathBuf::from("/etc/passwd"));
/// ```
+ #[must_use]
pub fn join_os(&self, path: impl AsRef<Path>) -> PathBuf {
self.0.join(path)
}
@@ -942,6 +1004,7 @@ impl Utf8Path {
/// let path = Utf8Path::new("/tmp");
/// assert_eq!(path.with_file_name("var"), Utf8PathBuf::from("/var"));
/// ```
+ #[must_use]
pub fn with_file_name(&self, file_name: impl AsRef<str>) -> Utf8PathBuf {
Utf8PathBuf(self.0.with_file_name(file_name.as_ref()))
}
@@ -1223,6 +1286,9 @@ impl Utf8Path {
/// Returns `true` if the path points at an existing entity.
///
+ /// Warning: this method may be error-prone, consider using [`try_exists()`] instead!
+ /// It also has a risk of introducing time-of-check to time-of-use (TOCTOU) bugs.
+ ///
/// This function will traverse symbolic links to query information about the
/// destination file. In case of broken symbolic links this will return `false`.
///
@@ -1240,10 +1306,51 @@ impl Utf8Path {
///
/// This is a convenience function that coerces errors to false. If you want to
/// check errors, call [`fs::metadata`].
+ ///
+ /// [`try_exists()`]: Self::try_exists
+ #[must_use]
pub fn exists(&self) -> bool {
self.0.exists()
}
+ /// Returns `Ok(true)` if the path points at an existing entity.
+ ///
+ /// This function will traverse symbolic links to query information about the
+ /// destination file. In case of broken symbolic links this will return `Ok(false)`.
+ ///
+ /// As opposed to the [`exists()`] method, this one doesn't silently ignore errors
+ /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
+ /// denied on some of the parent directories.)
+ ///
+ /// Note that while this avoids some pitfalls of the `exists()` method, it still can not
+ /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios
+ /// where those bugs are not an issue.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use camino::Utf8Path;
+ /// assert!(!Utf8Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
+ /// assert!(Utf8Path::new("/root/secret_file.txt").try_exists().is_err());
+ /// ```
+ ///
+ /// [`exists()`]: Self::exists
+ #[inline]
+ pub fn try_exists(&self) -> io::Result<bool> {
+ // Note: this block is written this way rather than with a pattern guard to appease Rust
+ // 1.34.
+ match fs::metadata(self) {
+ Ok(_) => Ok(true),
+ Err(error) => {
+ if error.kind() == io::ErrorKind::NotFound {
+ Ok(false)
+ } else {
+ Err(error)
+ }
+ }
+ }
+ }
+
/// Returns `true` if the path exists on disk and is pointing at a regular file.
///
/// This function will traverse symbolic links to query information about the
@@ -1271,6 +1378,7 @@ impl Utf8Path {
/// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
/// a Unix-like system for example. See [`fs::File::open`] or
/// [`fs::OpenOptions::open`] for more information.
+ #[must_use]
pub fn is_file(&self) -> bool {
self.0.is_file()
}
@@ -1296,6 +1404,7 @@ impl Utf8Path {
/// This is a convenience function that coerces errors to false. If you want to
/// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
/// [`fs::Metadata::is_dir`] if it was [`Ok`].
+ #[must_use]
pub fn is_dir(&self) -> bool {
self.0.is_dir()
}
@@ -1334,6 +1443,7 @@ impl Utf8Path {
}
/// Converts a `Box<Utf8Path>` into a [`Utf8PathBuf`] without copying or allocating.
+ #[must_use = "`self` will be dropped if the result is not used"]
pub fn into_path_buf(self: Box<Utf8Path>) -> Utf8PathBuf {
let ptr = Box::into_raw(self) as *mut Path;
// SAFETY:
@@ -1397,6 +1507,7 @@ impl fmt::Debug for Utf8Path {
///
/// [`ancestors`]: Utf8Path::ancestors
#[derive(Copy, Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
#[repr(transparent)]
pub struct Utf8Ancestors<'a>(Ancestors<'a>);
@@ -1439,6 +1550,7 @@ impl<'a> FusedIterator for Utf8Ancestors<'a> {}
///
/// [`components`]: Utf8Path::components
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Utf8Components<'a>(Components<'a>);
impl<'a> Utf8Components<'a> {
@@ -1455,6 +1567,7 @@ impl<'a> Utf8Components<'a> {
///
/// assert_eq!(Utf8Path::new("foo/bar.txt"), components.as_path());
/// ```
+ #[must_use]
pub fn as_path(&self) -> &'a Utf8Path {
// SAFETY: Utf8Components was constructed from a Utf8Path, so it is guaranteed to be valid
// UTF-8
@@ -1523,6 +1636,7 @@ impl AsRef<OsStr> for Utf8Components<'_> {
///
/// [`iter`]: Utf8Path::iter
#[derive(Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a> {
inner: Utf8Components<'a>,
}
@@ -1557,6 +1671,7 @@ impl<'a> Iter<'a> {
///
/// assert_eq!(Utf8Path::new("foo/bar.txt"), iter.as_path());
/// ```
+ #[must_use]
pub fn as_path(&self) -> &'a Utf8Path {
self.inner.as_path()
}
@@ -1674,6 +1789,7 @@ impl<'a> Utf8Component<'a> {
/// let components: Vec<_> = path.components().map(|comp| comp.as_str()).collect();
/// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
/// ```
+ #[must_use]
pub fn as_str(&self) -> &'a str {
// SAFETY: Utf8Component was constructed from a Utf8Path, so it is guaranteed to be
// valid UTF-8
@@ -1691,6 +1807,7 @@ impl<'a> Utf8Component<'a> {
/// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
/// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
/// ```
+ #[must_use]
pub fn as_os_str(&self) -> &'a OsStr {
match *self {
Utf8Component::Prefix(prefix) => prefix.as_os_str(),
@@ -1821,6 +1938,7 @@ impl<'a> Utf8Prefix<'a> {
/// assert!(!UNC("server", "share").is_verbatim());
/// assert!(!Disk(b'C').is_verbatim());
/// ```
+ #[must_use]
pub fn is_verbatim(&self) -> bool {
use Utf8Prefix::*;
match self {
@@ -1872,6 +1990,7 @@ impl<'a> Utf8PrefixComponent<'a> {
///
/// See [`Utf8Prefix`]'s documentation for more information on the different
/// kinds of prefixes.
+ #[must_use]
pub fn kind(&self) -> Utf8Prefix<'a> {
// SAFETY for all the below unsafe blocks: the path self was originally constructed from was
// UTF-8 so any parts of it are valid UTF-8
@@ -1894,6 +2013,7 @@ impl<'a> Utf8PrefixComponent<'a> {
}
/// Returns the [`str`] slice for this prefix.
+ #[must_use]
pub fn as_str(&self) -> &'a str {
// SAFETY: Utf8PrefixComponent was constructed from a Utf8Path, so it is guaranteed to be
// valid UTF-8
@@ -1901,6 +2021,7 @@ impl<'a> Utf8PrefixComponent<'a> {
}
/// Returns the raw [`OsStr`] slice for this prefix.
+ #[must_use]
pub fn as_os_str(&self) -> &'a OsStr {
self.0.as_os_str()
}
@@ -2596,6 +2717,7 @@ impl<'a> IntoIterator for &'a Utf8Path {
macro_rules! impl_cmp {
($lhs:ty, $rhs: ty) => {
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool {
@@ -2603,6 +2725,7 @@ macro_rules! impl_cmp {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool {
@@ -2610,6 +2733,7 @@ macro_rules! impl_cmp {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$rhs> for $lhs {
#[inline]
fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
@@ -2617,6 +2741,7 @@ macro_rules! impl_cmp {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$lhs> for $rhs {
#[inline]
fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
@@ -2634,6 +2759,7 @@ impl_cmp!(Cow<'a, Utf8Path>, Utf8PathBuf);
macro_rules! impl_cmp_std_path {
($lhs:ty, $rhs: ty) => {
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool {
@@ -2641,6 +2767,7 @@ macro_rules! impl_cmp_std_path {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool {
@@ -2648,6 +2775,7 @@ macro_rules! impl_cmp_std_path {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$rhs> for $lhs {
#[inline]
fn partial_cmp(&self, other: &$rhs) -> Option<std::cmp::Ordering> {
@@ -2655,6 +2783,7 @@ macro_rules! impl_cmp_std_path {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$lhs> for $rhs {
#[inline]
fn partial_cmp(&self, other: &$lhs) -> Option<std::cmp::Ordering> {
@@ -2679,6 +2808,7 @@ impl_cmp_std_path!(&'a Utf8Path, PathBuf);
macro_rules! impl_cmp_str {
($lhs:ty, $rhs: ty) => {
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool {
@@ -2686,6 +2816,7 @@ macro_rules! impl_cmp_str {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool {
@@ -2693,6 +2824,7 @@ macro_rules! impl_cmp_str {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$rhs> for $lhs {
#[inline]
fn partial_cmp(&self, other: &$rhs) -> Option<std::cmp::Ordering> {
@@ -2700,6 +2832,7 @@ macro_rules! impl_cmp_str {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$lhs> for $rhs {
#[inline]
fn partial_cmp(&self, other: &$lhs) -> Option<std::cmp::Ordering> {
@@ -2724,6 +2857,7 @@ impl_cmp_str!(&'a Utf8Path, String);
macro_rules! impl_cmp_os_str {
($lhs:ty, $rhs: ty) => {
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool {
@@ -2731,6 +2865,7 @@ macro_rules! impl_cmp_os_str {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool {
@@ -2738,6 +2873,7 @@ macro_rules! impl_cmp_os_str {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$rhs> for $lhs {
#[inline]
fn partial_cmp(&self, other: &$rhs) -> Option<std::cmp::Ordering> {
@@ -2745,6 +2881,7 @@ macro_rules! impl_cmp_os_str {
}
}
+ #[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> PartialOrd<$lhs> for $rhs {
#[inline]
fn partial_cmp(&self, other: &$lhs) -> Option<std::cmp::Ordering> {
diff --git a/vendor/clap/.cargo-checksum.json b/vendor/clap/.cargo-checksum.json
index 729aee79b..22fa24875 100644
--- a/vendor/clap/.cargo-checksum.json
+++ b/vendor/clap/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.lock":"6d96d441076749454963df06d637e5680e5ecdcdd36026f160c2d181aaca3bdc","Cargo.toml":"cb59c1e945c5606119203d907c01a40606070414b8913440f32e250c5db8c211","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"b5d5ba727e9f1a8797016bb041bc7888a209099d7dc42e445a89b1f8d3ac510d","examples/README.md":"9d19f6dfb53aadbe18aca773136d34bd28352b8efd69dfee217f26ee0eb9269a","examples/cargo-example-derive.md":"53a35e48cd04dfa10d70f99eb6d97d0d74110958f7f9e4ffc460fca87a256a73","examples/cargo-example-derive.rs":"627a74b7dc6d829b8facd314d0de46418b2420c6998e883f71a3cb7639d3a22d","examples/cargo-example.md":"1f270b0a0ac9122feb9cdac0887c1c1bcf1b654fed27147871c9cfe71851a4d9","examples/cargo-example.rs":"66293c7e200a87fceca691ab858293142c8a1536ef1d2c0dd14a6056289866a2","examples/demo.md":"3e986afca0863142fdd4cc092b5969fba32a70fac8adf84a55bd652f4b30eedb","examples/demo.rs":"5361cac70b662dd6d4d785738b99cfadf1f838c90507f19ea1aeef05aba0ee72","examples/derive_ref/README.md":"be2cfd81b9e2dc5e5910243f4b2f032e0b2c8af0592dcd050705e8718be8038d","examples/derive_ref/augment_args.rs":"69057536807ceb08e35802f8cf65c0f6ddd260a66a90000c8c6294031d466be3","examples/derive_ref/augment_subcommands.rs":"5535f8ca1893101acb5eba8edc311497431ff9aa26f62f1d9743bdc147bef7a4","examples/derive_ref/custom-bool.md":"d92e441199c7584d4b888c45124366cc4802ec8ea67cdcbb3423ffaa3c5268ac","examples/derive_ref/custom-bool.rs":"f88e9c68d2447a24bc98e05124fea17836155f32cff30a2b8a03ad254383247c","examples/derive_ref/flatten_hand_args.rs":"c09b751eb4e89e825af4de25a67d735c7b4794536bcff96b0ab8ee816c34413a","examples/derive_ref/hand_subcommand.rs":"1a5464b9c5791361930b5591adeb6fcf6f14b83abdfa6443d2c80bcf0c097b3e","examples/derive_ref/interop_tests.md":"3a357e82cfc155f71e0348be33f78295aa77839c3e3a5b7c1783cbd1259e6a61","examples/escaped-positional-derive.md":"b2190ada5ad2634c3ceb7f9d98293512628762545f9519579cbee9867c6a406a","examples/escaped-positional-derive.rs":"ac3127e8cc7a8953886778824a4d6e12470488546f10eeac6f9817ecaef1532e","examples/escaped-positional.md":"b6a5c103f5cea1464b5ac8e63e1964f032a4dbb4a908e45b9b391f4857fe2684","examples/escaped-positional.rs":"aaf106cdbe8f1eb5d9f3032df485d5661885f95402f026a34c42431f98a08323","examples/git-derive.md":"1a20f30d1c6df28d7e48b527b0726e9440f54d55a1e0b9e059b2322a7960ee72","examples/git-derive.rs":"225a33b0cd84840de2ba623b6b506b2fa4b02a9f5fbf62cdc2b2626e661501bd","examples/git.md":"acb3a44f954a6e2160f8989952981fb4baea8b97b921e4227c67896bc64d5e4a","examples/git.rs":"293b1289550ea38eabf1af7c6a855065170ff785e97be113928f045c50c1a3e9","examples/multicall-busybox.md":"3cb9d00ad110fc99c298dac4aa471e2f7a304aecef51d2eda67f5fbf36c41293","examples/multicall-busybox.rs":"709f71a82295a539d0a239371d35d1eeb517eaa3bb0a4db406bb7e5d3541a4a5","examples/multicall-hostname.md":"8c2d95fa8b940d4f788f96cf6b08b81bb2541bf12adff63bdff90dfc24567c7e","examples/multicall-hostname.rs":"cc58a924dd2e57281f36e30481a1cbc8186952adbf149f9e1e13f9c673614fd9","examples/pacman.md":"e583ef465e55fa2fffef3b121e4a90835b8905ef3ffe2ec9ae91702832b7392d","examples/pacman.rs":"4aea4eed4408458d57d3ff91f0e7f8833eeee30dd71043f5a6d06968c6c9712e","examples/repl.rs":"d50c1da634c237b26989994b1efa6fd1a087874a82d1fc8c1863be4ea8deaa8c","examples/tutorial_builder/01_quick.rs":"2734001dc1f67842f8ff3486397738f10dcbdf4bdd15326c13aebd5fafe0dabd","examples/tutorial_builder/02_app_settings.rs":"ca7e0b49019a444053ed13a7df8108d460430819b4fb04c4c6097225dc630293","examples/tutorial_builder/02_apps.rs":"a7016469d10259ae0025fb6ad5b9d3c732cf082869348005d4774d2bb0722d2d","examples/tutorial_builder/02_crate.rs":"5d7397901ebf82e3975626b3737fca3a95868cde42ce74d41bb3c96429878906","examples/tutorial_builder/03_01_flag_bool.rs":"1e904b39c7aaafc407a841ab8b549152263073a1af11773d13dc04d43fd541ef","examples/tutorial_builder/03_01_flag_count.rs":"02778a53afd6170c7ef7d358909237d4fe548adc5d7e650916d26f765040c25b","examples/tutorial_builder/03_02_option.rs":"7bca1c12b4904f89516ebdb88019c959c5adcf2a84244047f988b71f82760bd4","examples/tutorial_builder/03_03_positional.rs":"290921224b17df7f77326df06421b2100462da143e7b5dbe014f7e8b6d727d2b","examples/tutorial_builder/03_04_subcommands.rs":"1d5769847403661b1bb82d7a39713c52e1decbe4027dfc3866d63f5cf6ae8a55","examples/tutorial_builder/03_05_default_values.rs":"5a4768214c57996b27989cd5af57c7b79cbccfab2f285a88a415c2b67b589e4b","examples/tutorial_builder/04_01_enum.rs":"813ce1cf91e2cacd7eb5bd7018b1125d41cd9b29970dfa3638a7cf73c06659a0","examples/tutorial_builder/04_01_possible.rs":"2ccba0ab59f6339bcd761160d17a1c7ec935716fbe137408338694c7d3ee56f0","examples/tutorial_builder/04_02_parse.rs":"9d022cb3a3af3e00fd6c7d647ee0915a275ce79e379676e98bebcd3484be344b","examples/tutorial_builder/04_02_validate.rs":"4450e7e1af3581be631ffe9afa363c88b44ee20a90ecbb4608246972d3f7fd93","examples/tutorial_builder/04_03_relations.rs":"90db469ca8a3f1c5eb90548e8c1c0afe796d163891bdac90f2d307949a400047","examples/tutorial_builder/04_04_custom.rs":"461a06cae62f5972937f71b42d04df44240dabd62e23058322f04026beceaec5","examples/tutorial_builder/05_01_assert.rs":"73c57b051550366ed412c8986f40549fd43dacf3894df7751313c5de16f46af1","examples/tutorial_builder/README.md":"027d95d9f951d4ffed9ec54a3950919ea4a3d9fd471bbda721151ed6ff6c5731","examples/tutorial_derive/01_quick.rs":"e17262c915199c4507d8950d5eafb73f3047e09b6dee2abbfe9f82ebf1b7ddd5","examples/tutorial_derive/02_app_settings.rs":"7e81f4c1640b0bfbd87aedd3eda79ae7c47c669dee79b643b35e54c1dc076ee8","examples/tutorial_derive/02_apps.rs":"e8cd02b5983b2203f1585b96858fade4cedfb124e366171d6b21fcb3f05b514e","examples/tutorial_derive/02_crate.rs":"c156589c36a8b21654b1a41f5f10240411053d3273e7af3797e91ca53fa61d28","examples/tutorial_derive/03_01_flag_bool.rs":"07c31218d0332d7437d80e19c7e3c7be711bf0f56bee3ffb1c4d6f7f253b9304","examples/tutorial_derive/03_01_flag_count.rs":"945be42994845145b9c579b3834f8c6375f239293ded84fba35754bbe9fdcf9b","examples/tutorial_derive/03_02_option.rs":"48be4cf49b498173200ad86d5d3cd64ce9381f86fdaaab70f05fc471f64a2185","examples/tutorial_derive/03_03_positional.rs":"f368ab1465ee4d84b84d175b97af6f64ce0676bec2482adef3ce966d2d8de26a","examples/tutorial_derive/03_04_subcommands.rs":"b25c8aec8f3816923b1154be91caafe0c2d2841fc1af5f0ef048f03d1273879e","examples/tutorial_derive/03_04_subcommands_alt.rs":"7ba6e81c2af6085b7e2721254500b34ee3e8622e20790b3c6f2786e165151b70","examples/tutorial_derive/03_05_default_values.rs":"0ba14153a3c72a2435ac3688b990171a1670eb3f2f7cef21886732e489fad435","examples/tutorial_derive/04_01_enum.rs":"a665af77196af86ba87f1725703011392fc27f24e3d442bbb5dfc4c0d4892c15","examples/tutorial_derive/04_02_parse.rs":"fbb23ef2d98d3cb401cec9dd29d5818e4c189cc9f54fe961a2fbd08632a9634c","examples/tutorial_derive/04_02_validate.rs":"87d9c465f912b69e5839ea87404a221a39421404012c1a7fd6e327b03ceb12f0","examples/tutorial_derive/04_03_relations.rs":"bfc12e66ad9c17182bed2ef86cd668242e6e87ab4ee20fa9bf3d2aa99385d61a","examples/tutorial_derive/04_04_custom.rs":"0e745c6dab0881c62190e82e01409b70cf3286dd0983db4a612f1be88fdd1a8d","examples/tutorial_derive/05_01_assert.rs":"4742d883a3446f32068d96c142ed18df40a50ad6ed4989e39980011f3d1adbdf","examples/tutorial_derive/README.md":"7902da25a153aa0032184e4ca54185d1a5d4c6aa53686b10a210b4decc276791","examples/typed-derive.md":"cf3ee8313709937cc9c5462e3826cca8679946a658d684e8a36e66b0950100a7","examples/typed-derive.rs":"67034bd557c0efb2a0b61ced263cab3ddddb4e4a2bff2f2901d4832f6961e17d","src/bin/stdio-fixture.rs":"e8f10afbfe1857bcf986d2f55be0ca19a50c905d9f650c6e1fd42dbacf219b04","src/builder/action.rs":"64633d218202f799a08fb43ce7f1fae6105ae5ed43386caf4aca2d8ac5352fc1","src/builder/app_settings.rs":"5a27df52d765b50f83ad1173525b66f92b156415aee62b238306b3b57c086e50","src/builder/arg.rs":"808037bb9e7084c27f9f136059653ab049630d07d9851e5e700c8a775655bd05","src/builder/arg_group.rs":"263d9c79e03015fe4e2fab4616fc73089be60fb2ec17aa2a06f3d6a24740432c","src/builder/arg_predicate.rs":"8c9fd14780cd42465f32f2e8927b97c06e686d09b5927ba3cd5bbd792af7a13d","src/builder/arg_settings.rs":"af739627b9b1451c633eb66b09536008d8b095cba518a4f28b82ea480e9400d6","src/builder/command.rs":"72d0031bce35aa6d6ebd6a2006fe26a9b222852fe5a58a23854d9ab7f27150c5","src/builder/debug_asserts.rs":"d1d5adc82cb8269445b2ef197f1e566f61e7f13d6a24afaad928e45e95aed170","src/builder/macros.rs":"904e42e72c49107ae324f45d5df24fbff13b9c7d4589f1a4ae38594add704434","src/builder/mod.rs":"205367cb5ba5d5ba7894091535ce3a5dd23b35fd436e003196d89523e7705566","src/builder/possible_value.rs":"62268b9da9eec8f4d1904ebfbd3a288fb78cfa71c357efadced28f0378bcfb93","src/builder/regex.rs":"b18891310186ecdcca9bb611833b7188cc80fe72e9fef27b63fa076b880a1acb","src/builder/tests.rs":"995c7d6be608b94c6f392f1356eba0cb8adb9ca661ffeebf7ebe6e8ad01a868c","src/builder/usage_parser.rs":"91d1af89196116aac2c0fb021f42f43f954aa3252df264e19a02a0cf5911d16b","src/builder/value_hint.rs":"0dd974d495c313430898d28b79991a70983c9aa44e88fa9aa1776d3308935438","src/builder/value_parser.rs":"1d731b5bf4e25344ae1de23c474255a310852721ecf66a98c5ef2cbca1452437","src/derive.rs":"cf3e108adf7022ef4a269a0ede687d19f8f549168e1f36c3592fbee40da51e61","src/error/context.rs":"1dc561c7877d7f9b90f04bb7915744f0b3cc4ac2aa928ae100b2825a97077142","src/error/kind.rs":"deba40c24adf04e67e87e383463d103907b7f8cc69f842fd3a5d8d81015d33c1","src/error/mod.rs":"c7bdd28240ee2fac6d9ae2c3d849483fabc3c64d5d577c0bc297c996f122a217","src/lib.rs":"9522f2b17cd505623468c5ff847f5aa906a40ae19dde0329c459a417c2b82a2b","src/macros.rs":"d39619976c3cf3b2b28eef3dfffd449080f4fcfbaa164b01901bf3e10d1a5a07","src/mkeymap.rs":"3565a5bae5d6cdcf8ba41a24eb602c510a14e150c4a6d3085ad72a35778e9c5f","src/output/fmt.rs":"efb741b5854500d946c6c09763ece1badc2b9cd3efa616cb58012039836c2b7f","src/output/help.rs":"ebdd123d6b70279c25af4b08432b547498834853adf99821ff6c6cd65dd87d4e","src/output/mod.rs":"3a61f89a4568e95114a3ab839da8f3c4c92de2a228549308f5d1be076a474917","src/output/usage.rs":"370d3544cf58a09f8d3b0bcc2d894531d7152d716eaffa745a858c6ba2e03b7c","src/parser/arg_matcher.rs":"79ab36a164df07e565d2c44b836f647ee2009463d0d55bd2e822cb72b5e009a7","src/parser/error.rs":"4568fb6b8bb05b43e81c5df4fba5f4cb8b19bfa06e6b8fc6b5af6ca4074766cf","src/parser/features/mod.rs":"6ed075e97af56bff22f22ed1ee83ff6479360e05f9d3661a3145f822c242b694","src/parser/features/suggestions.rs":"79127956b2f1adb9d658925e2779ebebfe9ddea434408762fefb60afdb545f47","src/parser/matches/any_value.rs":"7b6e711fe205e8808394c562dd6a260b56ce350cf9298a308ba9727ab012b664","src/parser/matches/arg_matches.rs":"a24fa086537ef72951821fbf1dc455a04270606ee411685991e79aaae509558c","src/parser/matches/matched_arg.rs":"fb12eb2afaf631bb60aa8c4e42b0f510a877d35a9eaa07a7afd253280c27c251","src/parser/matches/mod.rs":"1467aa752cb1c79d30e4aeaaa55e10a0bb9dcf6f3980496234251431c79c49e6","src/parser/matches/value_source.rs":"e6a477ae36f2f7155960239a97b7d142eef4eb227c41c9eefea147289547d713","src/parser/mod.rs":"358f46d3b7f43dec2563d4c35bd2536fab2491f28e300a9bcdeaf6ca0513ce12","src/parser/parser.rs":"c1339fdf44253b6cbf81fcf71f99bb68300f8d5eb5ab7f0d0d02d222ee63a873","src/parser/validator.rs":"30066cb41ab23800231fb6b028cbce57d118570859659ebc67affbe5226f31f9","src/util/color.rs":"63df5e1cda1001b4c536dc0b04e09dd85dae6d317e34e660abbe3c71e17eaa29","src/util/fnv.rs":"82492d91d990f38b62de8b3c3e67f1fad55919117b1f448aa28acf6d21919fd7","src/util/graph.rs":"f35396b6e2a427377dcbbca69b1b98737d89684a3834cfda98cbf8cc70ff9c2f","src/util/id.rs":"fc498c65887385d92a51359a2f72556c2e508ee49b8cac4b3f827512795d690d","src/util/mod.rs":"8d328a15ef06989d0ce5e65cf3b7ec79c083984b25c0b31ba177bdb22df28a10","src/util/str_to_bool.rs":"1ce90b4939a884eeefc73392722bdfcf906e3070c4398e1557c586c10c684cd0"},"package":"d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7"} \ No newline at end of file
+{"files":{"Cargo.lock":"60560d6b2bec73734ebea64f8b916cbe9361e672157119801ba0e2f89334453c","Cargo.toml":"5def59eada2aa1a035cb39b38da4ba02baec2dd9271e4ef16731a8ef06c4d58f","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"0d687e1f07b58fe68bda74668ff6326125e5e5efa184cce755cd84ac535b7058","README.md":"ee049ee3ccab683cd3fa7c980db71c22ed8577378433cad5a93c1bc2a9dbe20f","examples/cargo-example-derive.md":"8305e66dd56619ec3a1d116951c893965cc8435574f5bf8baea923492357c626","examples/cargo-example-derive.rs":"a94003c9fadd1a11c35616ea4e5132c768bad08650e207848e1de56bffd86c8f","examples/cargo-example.md":"b7e51be8f05538ae39ce232ef12c873af81ab5abb5740c079d09b7cdd27a3b71","examples/cargo-example.rs":"be19a1ccb9d91882d76e7553f692ef89fa2a7acbbc1500232ce9fb60b6e8a85b","examples/demo.md":"9db305e9ff333f5e783dcc3142683280816d7bc111a57e9dcc4127f07ca44055","examples/demo.rs":"8a18ab15a235b84efd82017e51a891ed2df5f0154adbfce2806dcac089296b64","examples/derive_ref/augment_args.rs":"93fa1e122328a5d12ca4f921d17902dff6ec47b69fb2140124e2a00809ec4a1a","examples/derive_ref/augment_subcommands.rs":"5535f8ca1893101acb5eba8edc311497431ff9aa26f62f1d9743bdc147bef7a4","examples/derive_ref/custom-bool.md":"d92e441199c7584d4b888c45124366cc4802ec8ea67cdcbb3423ffaa3c5268ac","examples/derive_ref/custom-bool.rs":"f88e9c68d2447a24bc98e05124fea17836155f32cff30a2b8a03ad254383247c","examples/derive_ref/flatten_hand_args.rs":"abdb4e55b0cb71e5c4d14fe20ae0930df6888b2dca01225a02d3c6828bcbc791","examples/derive_ref/hand_subcommand.rs":"1a5464b9c5791361930b5591adeb6fcf6f14b83abdfa6443d2c80bcf0c097b3e","examples/derive_ref/interop_tests.md":"3a357e82cfc155f71e0348be33f78295aa77839c3e3a5b7c1783cbd1259e6a61","examples/escaped-positional-derive.md":"64329a454ad399cfde7cae37c2419fb68f1dfcdf2b7d809e113bab69c5f9b947","examples/escaped-positional-derive.rs":"68b0b474509d0d0b19a2ad756c15a18a9d3b30278390ddf1b7bc11b40fe5f937","examples/escaped-positional.md":"a8259da128ad7ad1f898527bb9e3c1c55541fdc2a59a8599fcddbe9cf58a3563","examples/escaped-positional.rs":"ca33f37267df8de835eeb5817e906a957e96c4ee9bd95b97abee3af25639f3c2","examples/git-derive.md":"280909b56757f102cad3a3274a92c884a0cec4e698c0f8718d2edee73fbbd810","examples/git-derive.rs":"2e8310364f2622b1b11c916643dda7392ec4a4fd585f30d537672d2fed48ea6e","examples/git.md":"31c172433b05ce581179aaba10d610de5cf097b0da894f1330a0437ef332feab","examples/git.rs":"9da386531604fc2afbd375685e213200ad10e34100ec92b4bfa6fb5730283aa1","examples/multicall-busybox.md":"0e07a2f79f94daf4586db85bf207b4bd8f0653b59858d6b4f0b66956a5b2178f","examples/multicall-busybox.rs":"709f71a82295a539d0a239371d35d1eeb517eaa3bb0a4db406bb7e5d3541a4a5","examples/multicall-hostname.md":"b547e42135269ab1e8be8dea4da6a4e99dfaa006a320fa319198d5934e1e97ab","examples/multicall-hostname.rs":"cc58a924dd2e57281f36e30481a1cbc8186952adbf149f9e1e13f9c673614fd9","examples/pacman.md":"c91e1582caf8a2cdeca208c856d1ede3f3ff26948b288a98ef69ea695f12f555","examples/pacman.rs":"f249824b950e1c34fae37afe04389143a037452a1f699c215172ac20e0285984","examples/repl.rs":"d50c1da634c237b26989994b1efa6fd1a087874a82d1fc8c1863be4ea8deaa8c","examples/tutorial_builder/01_quick.md":"80878c8630e0ecf7bb172c2645c2c17480ca5a37e5f4f481ab99e88d3a37da8e","examples/tutorial_builder/01_quick.rs":"c19b165fce9468fb3c9d3d9354a2b9829ceea7ffba6b7134d4941a6e986429a9","examples/tutorial_builder/02_app_settings.md":"f0f7b48afa7a97c9270f9d63a0e9e0f3117733ee0201639eae2199a4aca4944e","examples/tutorial_builder/02_app_settings.rs":"dd770d131726c3f37e202c9b10c969cc4eba90249c54a05594535cea6efe2749","examples/tutorial_builder/02_apps.md":"815a9197925d403b1d93969ace87e80e32667333fa83f2c86abcbdfa17cf0d7e","examples/tutorial_builder/02_apps.rs":"a7016469d10259ae0025fb6ad5b9d3c732cf082869348005d4774d2bb0722d2d","examples/tutorial_builder/02_crate.md":"086581912b34d305bb7cf3c5a35238c151bd366fac4c0923057883253731c250","examples/tutorial_builder/02_crate.rs":"2742c6a3f1946b89b4f1146893e126d68e1cf55ad4130fb94105091900421273","examples/tutorial_builder/03_01_flag_bool.md":"068378b1e76ce624dd0153dfaa9a7ae2d1a84205b1e169f5f1a16bebd50715cf","examples/tutorial_builder/03_01_flag_bool.rs":"d49b30b527faa6a383b334e572d546fab5c4b298a5549842073ab42a33a05c94","examples/tutorial_builder/03_01_flag_count.md":"8d62fbef076eac962a1d0082afa4916de22277aee973d693de33e9fd73b16669","examples/tutorial_builder/03_01_flag_count.rs":"2bfaac3aa9bcbbf37e18e74a40d966391e208d44b45a1e9c4ab61d22fd14dd40","examples/tutorial_builder/03_02_option.md":"585793524138da00c25b9fdd883b25eb8addfaf8742365d84cde63169a9289a7","examples/tutorial_builder/03_02_option.rs":"ce43934605e0438f1e8706e5e970cfcd930f76c4ebee02450ffc63de520994bd","examples/tutorial_builder/03_03_positional.md":"46fe5085841342243efd9614e80db7db3c52ae5af7c6cdd402b569d310e63fe9","examples/tutorial_builder/03_03_positional.rs":"fc7538d0fe8501c56070f0f22be699f128890636aa4ff8478cd6c7beeea279da","examples/tutorial_builder/03_04_subcommands.md":"fc5a92c5290b3cc119a6421779cdd8f4791465a1d3f50f4f29ccb08f3063a6f5","examples/tutorial_builder/03_04_subcommands.rs":"a309a332004edbed6dc14b64b1ba6cc0cd42871f3c5b8da7daab772764839c68","examples/tutorial_builder/03_05_default_values.md":"431800610a29d9a5587b74b30d709e67af5a0b8980900de20e5876fb9491144c","examples/tutorial_builder/03_05_default_values.rs":"b277be9cfe5d87958f9cf2e8a178bb007b070723528bedc8b81163aedb3a2880","examples/tutorial_builder/04_01_enum.md":"d1310efc5c8acb5ca9c86b57deebbcbd8766869284d2e8ea51e32b3eeac38439","examples/tutorial_builder/04_01_enum.rs":"596aa44bc401674a4ccf091b81b2df79b911dbb01d61fd167fd270d1e21a3609","examples/tutorial_builder/04_01_possible.md":"308cd6530b3c389bf2a82b2b66ad33025be230d84d94835273af35a90eb6a753","examples/tutorial_builder/04_01_possible.rs":"3d781b26d257061b55a957744c2dbd99c1d2346c151230fb18fe5f576d19585c","examples/tutorial_builder/04_02_parse.md":"ea14a355913fd7a8af5aac4be2bdecfda72c039b62ccadfb91ff8d39a447955e","examples/tutorial_builder/04_02_parse.rs":"a65f596341e65f41d555b38a6f5e22a5e03aac6faa4e8b3e3c85fa0e0935a2d7","examples/tutorial_builder/04_02_validate.md":"7536f4fb1a11ab94e54b6b98b7364c77912b7600803aeda5988c5b29f3f037c8","examples/tutorial_builder/04_02_validate.rs":"af6d9f748c6956aaa1006ce96834e0d013a9dbfb6d0acc63df5eb63caac56eef","examples/tutorial_builder/04_03_relations.md":"ffc6b8a2d606856fbb6cce677c5280e08eaffbe6a4c8e40cd68ce35959370ed7","examples/tutorial_builder/04_03_relations.rs":"a2dbb6d77587f64775ef57c4bb3869a2760e5c124e2870898bbf1191ef349b99","examples/tutorial_builder/04_04_custom.md":"d562fd072b5d91e8ea145771a2b6eb0284d3d21bfac707ba48ee00e92d76ad2d","examples/tutorial_builder/04_04_custom.rs":"ea0879629da2dab2d2e7fd25bdde53386d863a3e2d468e7ea306a6f8240a5522","examples/tutorial_builder/05_01_assert.rs":"69fc5a3d330be1f90055f886d65684204d7f0585459f362cf3c43b5caf4bbd7b","examples/tutorial_derive/01_quick.md":"1416029b09409468ba6b39ae5f91c41547f7f389c2534961f867ab17260638da","examples/tutorial_derive/01_quick.rs":"e17262c915199c4507d8950d5eafb73f3047e09b6dee2abbfe9f82ebf1b7ddd5","examples/tutorial_derive/02_app_settings.md":"3f4a81ebc7b674482768763bab70acf9bc31f68cc3ecb118c6f5493feaff3d42","examples/tutorial_derive/02_app_settings.rs":"7e81f4c1640b0bfbd87aedd3eda79ae7c47c669dee79b643b35e54c1dc076ee8","examples/tutorial_derive/02_apps.md":"27d22d45e438f60b346d34508a75783871e0fe9b1ae41ec759e56118a10feff7","examples/tutorial_derive/02_apps.rs":"e8cd02b5983b2203f1585b96858fade4cedfb124e366171d6b21fcb3f05b514e","examples/tutorial_derive/02_crate.md":"eb396e17db1dd68eb7689bcd806b63dbfe01ad48dfc12c285f00c42e1d4b8c1f","examples/tutorial_derive/02_crate.rs":"0b12a0790d23cee1e5d275893f428cc0af36d5532c2af00806e64c18ef9d309c","examples/tutorial_derive/03_01_flag_bool.md":"f6dd5ab050f0f1ac5924949a4ba45f248b2d4b1bd77210d78b9d8e9b3395d111","examples/tutorial_derive/03_01_flag_bool.rs":"07c31218d0332d7437d80e19c7e3c7be711bf0f56bee3ffb1c4d6f7f253b9304","examples/tutorial_derive/03_01_flag_count.md":"74d5c8a79581ceb7e6a11ec20ae59fa8c7f42591e10464aad50bbdd3d06916fc","examples/tutorial_derive/03_01_flag_count.rs":"945be42994845145b9c579b3834f8c6375f239293ded84fba35754bbe9fdcf9b","examples/tutorial_derive/03_02_option.md":"034b65008d05c1598fe3c1918f23d654d7a14cb610dd636a3c649d9d7a3b1559","examples/tutorial_derive/03_02_option.rs":"48be4cf49b498173200ad86d5d3cd64ce9381f86fdaaab70f05fc471f64a2185","examples/tutorial_derive/03_03_positional.md":"14f6b36eee218a38733b534e7b621f68a6f799bd96682a82980cba9f6e99a40e","examples/tutorial_derive/03_03_positional.rs":"f368ab1465ee4d84b84d175b97af6f64ce0676bec2482adef3ce966d2d8de26a","examples/tutorial_derive/03_04_subcommands.md":"3e1870fb10c78a01b63903060b1164f3f4d0e51c052e449abe11e2d06c252811","examples/tutorial_derive/03_04_subcommands.rs":"b25c8aec8f3816923b1154be91caafe0c2d2841fc1af5f0ef048f03d1273879e","examples/tutorial_derive/03_04_subcommands_alt.rs":"7ba6e81c2af6085b7e2721254500b34ee3e8622e20790b3c6f2786e165151b70","examples/tutorial_derive/03_05_default_values.md":"9ac52230ba7d9c214dcb64922cbf161970947d9650e8e7ea8d0ee949eba99c0e","examples/tutorial_derive/03_05_default_values.rs":"0ba14153a3c72a2435ac3688b990171a1670eb3f2f7cef21886732e489fad435","examples/tutorial_derive/04_01_enum.md":"ee57dc12a88a560d70f344629ac79cc497f96e967e97b4c643467747c8075172","examples/tutorial_derive/04_01_enum.rs":"d30abd8570357be26871c06939dee8173d34408250b6bdc3b1e76f1cbc06f888","examples/tutorial_derive/04_02_parse.md":"f191e6c77e6b133f78bd1123cec2b09c8dfe8bb17198d6348e26adade7465daf","examples/tutorial_derive/04_02_parse.rs":"fbb23ef2d98d3cb401cec9dd29d5818e4c189cc9f54fe961a2fbd08632a9634c","examples/tutorial_derive/04_02_validate.md":"c88670017d06261d454818ff18f21a06275f35d564e637c5346ce3b7fca8a02b","examples/tutorial_derive/04_02_validate.rs":"87d9c465f912b69e5839ea87404a221a39421404012c1a7fd6e327b03ceb12f0","examples/tutorial_derive/04_03_relations.md":"5657bbeee193f21a312db682cfa216f1001a94ace024c56a959985feb2e29069","examples/tutorial_derive/04_03_relations.rs":"eb8e737733261d3d1b7f4def7a05c37ba7c1c010357c7de33ee42c8adfdf6dc2","examples/tutorial_derive/04_04_custom.md":"9627d0025c5c063682387d8e00b3fb097114d1431c1ce8808038be34f781576a","examples/tutorial_derive/04_04_custom.rs":"0e745c6dab0881c62190e82e01409b70cf3286dd0983db4a612f1be88fdd1a8d","examples/tutorial_derive/05_01_assert.rs":"653450ff2e528f29b6b31d979fd7da094ea8e74b8b61a4657935c9ac2efbc28e","examples/typed-derive.md":"c22bb8da2e294f1d3725624e0c442713e5f263b10a2ee76a22ffa07f89af735a","examples/typed-derive.rs":"1c88bb1c8cec4e2e7a452552fa52675d96ffd6f201f5384b4e98d0a70fce1e4c","src/_cookbook/cargo_example.rs":"fe7594a5233e9106a159aa1f5d5f0cde0d844356f630d55c78b8ef322327d4e5","src/_cookbook/cargo_example_derive":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/_cookbook/cargo_example_derive.rs":"badf3e931ef5d5b7f5addc4912aca057ba83ee6302c43d7eeecd1661673fd407","src/_cookbook/escaped_positional.rs":"2789d8fea126355805b29e76b52c6cea4982565014087a46e0d48e4ddfbed7ab","src/_cookbook/escaped_positional_derive.rs":"802d0b672f4ed48152235d4a26a64c97fa921b361177bdd3a1a33cbac96f665d","src/_cookbook/git.rs":"372977252a22fc776e3acaa4629e964114ccd6a49b8ef334d2b6646f12e8b5ee","src/_cookbook/git_derive.rs":"4ab7c0197efda06607ca60c2a85ea743aed3494f5fe9e408d935ea0500a345fc","src/_cookbook/mod.rs":"34c53c6273512976676a82dded921f8d99e0312dd3e823ae1549606754625827","src/_cookbook/multicall_busybox.rs":"56176b4fa15e7a39c433706971d4e68aaf26ddc2a5790078b6dbe722ee13efee","src/_cookbook/multicall_hostname.rs":"907f8decf81ea4d4cbf81639ea4cd2f925eda64d4831454a7656369b65522780","src/_cookbook/pacman.rs":"863125b2d3d7931a9e4541c8ab1242b8bfcb421d8b5c604ea681efd805f68da7","src/_cookbook/repl.rs":"1393209b2cc5c203296d57c5a065b764b4318be7855e48baf16de851e250cf90","src/_cookbook/typed_derive.rs":"3d28e78cd0b068b4fcb32a7fea6244de176f2fe75dfcb59e99c33b66a7ae4864","src/_derive/_tutorial.rs":"237d316ad5f9838dc011283e454afce24d47bf2e9c5038ba5402bafeb2959090","src/_derive/mod.rs":"7f1f6b59332044681324f0753dfb51641e52f46dee74a21b8c94a413bc06be02","src/_faq.rs":"06d10de865ae34305fa973db9b00dc31f54e0f63f8fe039805aa371c36a796b9","src/_features.rs":"bbcbf1b256136d20f89e4f8a16ff37b04f07dfee0d2d4f2b013f445467628032","src/_tutorial.rs":"e7c7359b6b6c86cf6e18f4bdc3c90ce440b82bf07ce304ca2e127fb2a04cbf9f","src/bin/stdio-fixture.rs":"e8f10afbfe1857bcf986d2f55be0ca19a50c905d9f650c6e1fd42dbacf219b04","src/builder/action.rs":"beab4d8dca6337dfd64f387ee3198a88a6dcb71ec94f5bbbfe6bb4c0175ab9ee","src/builder/app_settings.rs":"17b094a5c044b2387467706bade1b19b5703bf99fc5081ac9508f410f871a1f2","src/builder/arg.rs":"e7120b60bf72d2572fc1f325b377a32da9ece4d7ac00b4a580a0f6a42c08ea8a","src/builder/arg_group.rs":"263d9c79e03015fe4e2fab4616fc73089be60fb2ec17aa2a06f3d6a24740432c","src/builder/arg_predicate.rs":"8c9fd14780cd42465f32f2e8927b97c06e686d09b5927ba3cd5bbd792af7a13d","src/builder/arg_settings.rs":"b7966dfea529a1be1164ca2d76494b1712cb2f73b024d2a23307dcd473933887","src/builder/command.rs":"57f0076465feb3cf6a0a16610b345fae8dbde8d248e4ef94111a27051c40789b","src/builder/debug_asserts.rs":"d1d5adc82cb8269445b2ef197f1e566f61e7f13d6a24afaad928e45e95aed170","src/builder/macros.rs":"904e42e72c49107ae324f45d5df24fbff13b9c7d4589f1a4ae38594add704434","src/builder/mod.rs":"205367cb5ba5d5ba7894091535ce3a5dd23b35fd436e003196d89523e7705566","src/builder/possible_value.rs":"62268b9da9eec8f4d1904ebfbd3a288fb78cfa71c357efadced28f0378bcfb93","src/builder/regex.rs":"b18891310186ecdcca9bb611833b7188cc80fe72e9fef27b63fa076b880a1acb","src/builder/tests.rs":"995c7d6be608b94c6f392f1356eba0cb8adb9ca661ffeebf7ebe6e8ad01a868c","src/builder/usage_parser.rs":"91d1af89196116aac2c0fb021f42f43f954aa3252df264e19a02a0cf5911d16b","src/builder/value_hint.rs":"0dd974d495c313430898d28b79991a70983c9aa44e88fa9aa1776d3308935438","src/builder/value_parser.rs":"64bb7f4808bdf65f30cb434198038a06db556e5ca045d900da392cc1a3186896","src/derive.rs":"11eaddc27a06229322a6bbce4458cb1424e6a5805c79166cba342c2905093b51","src/error/context.rs":"1dc561c7877d7f9b90f04bb7915744f0b3cc4ac2aa928ae100b2825a97077142","src/error/kind.rs":"3b4f9dfe5be5843cec8380c8f8965dcb9d0beee0aaa02cadf8dcffd400626ede","src/error/mod.rs":"e5b60fee401975d95c460c2567d09e17972eaae336154a8b90d9c806083f63fa","src/lib.rs":"4a197eab3f447c58a266af4f9a787af5c98b18f4612f33d9189cce52f4f9de18","src/macros.rs":"72585e32051a6872bbb29e39f7e9f9a88334a03f39ec3c768984db2f38211001","src/mkeymap.rs":"3565a5bae5d6cdcf8ba41a24eb602c510a14e150c4a6d3085ad72a35778e9c5f","src/output/fmt.rs":"efb741b5854500d946c6c09763ece1badc2b9cd3efa616cb58012039836c2b7f","src/output/help.rs":"ebdd123d6b70279c25af4b08432b547498834853adf99821ff6c6cd65dd87d4e","src/output/mod.rs":"3a61f89a4568e95114a3ab839da8f3c4c92de2a228549308f5d1be076a474917","src/output/usage.rs":"1921d2fa362f111b3f9613fc98eb5e24686483fe112b337855da7eb17b643f71","src/parser/arg_matcher.rs":"0c9ae639ed241e8ff1f62cd9e5eab2de9e5db1be0e86f58d5d94619d6dad05fd","src/parser/error.rs":"51e8fbd7cc73bba78cca50417e9b4fb25e11eefc60ff4b957940176bdb995e5c","src/parser/features/mod.rs":"6ed075e97af56bff22f22ed1ee83ff6479360e05f9d3661a3145f822c242b694","src/parser/features/suggestions.rs":"79127956b2f1adb9d658925e2779ebebfe9ddea434408762fefb60afdb545f47","src/parser/matches/any_value.rs":"7b6e711fe205e8808394c562dd6a260b56ce350cf9298a308ba9727ab012b664","src/parser/matches/arg_matches.rs":"666e3640b5347aba5806fc15b5caa599b171e684ee15d933ddc7f8185a0d2032","src/parser/matches/matched_arg.rs":"fb12eb2afaf631bb60aa8c4e42b0f510a877d35a9eaa07a7afd253280c27c251","src/parser/matches/mod.rs":"1467aa752cb1c79d30e4aeaaa55e10a0bb9dcf6f3980496234251431c79c49e6","src/parser/matches/value_source.rs":"e6a477ae36f2f7155960239a97b7d142eef4eb227c41c9eefea147289547d713","src/parser/mod.rs":"358f46d3b7f43dec2563d4c35bd2536fab2491f28e300a9bcdeaf6ca0513ce12","src/parser/parser.rs":"9e338dfd60aa8bfbcfbbda15c73d4722767a4d2e7b8f8ed3a07c296ddd98762c","src/parser/validator.rs":"30066cb41ab23800231fb6b028cbce57d118570859659ebc67affbe5226f31f9","src/util/color.rs":"63df5e1cda1001b4c536dc0b04e09dd85dae6d317e34e660abbe3c71e17eaa29","src/util/fnv.rs":"82492d91d990f38b62de8b3c3e67f1fad55919117b1f448aa28acf6d21919fd7","src/util/graph.rs":"f35396b6e2a427377dcbbca69b1b98737d89684a3834cfda98cbf8cc70ff9c2f","src/util/id.rs":"fc498c65887385d92a51359a2f72556c2e508ee49b8cac4b3f827512795d690d","src/util/mod.rs":"8d328a15ef06989d0ce5e65cf3b7ec79c083984b25c0b31ba177bdb22df28a10","src/util/str_to_bool.rs":"1ce90b4939a884eeefc73392722bdfcf906e3070c4398e1557c586c10c684cd0"},"package":"23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"} \ No newline at end of file
diff --git a/vendor/clap/Cargo.lock b/vendor/clap/Cargo.lock
index 269dea5ad..57d007104 100644
--- a/vendor/clap/Cargo.lock
+++ b/vendor/clap/Cargo.lock
@@ -45,9 +45,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backtrace"
-version = "0.3.65"
+version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
+checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
dependencies = [
"addr2line",
"cc",
@@ -66,9 +66,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytes"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
[[package]]
name = "cc"
@@ -84,7 +84,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
-version = "3.2.5"
+version = "3.2.20"
dependencies = [
"atty",
"backtrace",
@@ -98,6 +98,7 @@ dependencies = [
"rustversion",
"shlex",
"snapbox",
+ "static_assertions",
"strsim",
"termcolor",
"terminal_size",
@@ -110,9 +111,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "3.2.5"
+version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9"
+checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [
"heck",
"proc-macro-error",
@@ -123,9 +124,9 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.2.2"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
@@ -159,9 +160,9 @@ checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449"
[[package]]
name = "crossbeam-channel"
-version = "0.5.4"
+version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
+checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
dependencies = [
"cfg-if",
"crossbeam-utils",
@@ -180,33 +181,33 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
-version = "0.9.8"
+version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
+checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
- "lazy_static",
"memoffset",
+ "once_cell",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
-version = "0.8.8"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if",
- "lazy_static",
+ "once_cell",
]
[[package]]
name = "either"
-version = "1.6.1"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
[[package]]
name = "escargot"
@@ -222,9 +223,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.26.1"
+version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
+checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
[[package]]
name = "glob"
@@ -234,9 +235,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[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 = "heck"
@@ -271,9 +272,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "1.8.1"
+version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
@@ -290,27 +291,21 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[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"
[[package]]
name = "linked-hash-map"
-version = "0.5.4"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "log"
@@ -338,9 +333,9 @@ dependencies = [
[[package]]
name = "miniz_oxide"
-version = "0.5.1"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
+checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
dependencies = [
"adler",
]
@@ -363,18 +358,18 @@ dependencies = [
[[package]]
name = "object"
-version = "0.28.3"
+version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456"
+checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "os_pipe"
@@ -418,27 +413,27 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.37"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
+checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
-version = "1.5.2"
+version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221"
+checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
dependencies = [
"autocfg",
"crossbeam-deque",
@@ -448,9 +443,9 @@ dependencies = [
[[package]]
name = "rayon-core"
-version = "1.9.2"
+version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4"
+checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@@ -460,9 +455,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.5.5"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
@@ -471,9 +466,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.25"
+version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "rustc-demangle"
@@ -483,15 +478,15 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustversion"
-version = "1.0.6"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
+checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8"
[[package]]
name = "ryu"
-version = "1.0.9"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "scopeguard"
@@ -501,18 +496,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
-version = "1.0.137"
+version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.137"
+version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
+checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
dependencies = [
"proc-macro2",
"quote",
@@ -521,9 +516,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.81"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
+checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
dependencies = [
"itoa",
"ryu",
@@ -564,6 +559,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930"
[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -571,13 +572,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
-version = "1.0.92"
+version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
+checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
@@ -620,9 +621,9 @@ dependencies = [
[[package]]
name = "toml_edit"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba98375fd631b83696f87c64e4ed8e29e6a1f3404d6aed95fa95163bad38e705"
+checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f"
dependencies = [
"combine",
"indexmap",
@@ -632,9 +633,9 @@ dependencies = [
[[package]]
name = "trybuild"
-version = "1.0.61"
+version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fc92f558afb6d1d7c6f175eb8d615b8ef49c227543e68e19c123d4ee43d8a7d"
+checksum = "764b9e244b482a9b81bde596aa37aa6f1347bf8007adab25e59f901b32b4e0a0"
dependencies = [
"glob",
"once_cell",
@@ -672,16 +673,16 @@ dependencies = [
]
[[package]]
-name = "unicode-width"
-version = "0.1.9"
+name = "unicode-ident"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
+checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
-name = "unicode-xid"
-version = "0.2.3"
+name = "unicode-width"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "version_check"
diff --git a/vendor/clap/Cargo.toml b/vendor/clap/Cargo.toml
index aba082f3a..197454c07 100644
--- a/vendor/clap/Cargo.toml
+++ b/vendor/clap/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2021"
-rust-version = "1.56.0"
+rust-version = "1.56.1"
name = "clap"
-version = "3.2.5"
+version = "3.2.20"
include = [
"build.rs",
"src/**/*",
@@ -24,7 +24,6 @@ include = [
"examples/**/*",
]
description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
-documentation = "https://docs.rs/clap/"
readme = "README.md"
keywords = [
"argument",
@@ -91,27 +90,6 @@ replace = """
[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD"""
exactly = 1
-[[package.metadata.release.pre-release-replacements]]
-file = "README.md"
-search = "github.com/clap-rs/clap/blob/[^/]+/"
-replace = "github.com/clap-rs/clap/blob/{{tag_name}}/"
-exactly = 13
-prerelease = true
-
-[[package.metadata.release.pre-release-replacements]]
-file = "README.md"
-search = 'version = "[a-z0-9\.-]+"'
-replace = "version = \"{{version}}\""
-exactly = 1
-prerelease = true
-
-[[package.metadata.release.pre-release-replacements]]
-file = "src/derive.rs"
-search = "github.com/clap-rs/clap/blob/[^/]+/"
-replace = "github.com/clap-rs/clap/blob/{{tag_name}}/"
-exactly = 4
-prerelease = true
-
[profile.bench]
lto = true
codegen-units = 1
@@ -219,10 +197,7 @@ required-features = ["cargo"]
[[example]]
name = "04_01_enum"
path = "examples/tutorial_builder/04_01_enum.rs"
-required-features = [
- "cargo",
- "derive",
-]
+required-features = ["cargo"]
[[example]]
name = "04_02_parse"
@@ -373,7 +348,7 @@ optional = true
version = "1.2"
[dependencies.clap_derive]
-version = "=3.2.5"
+version = "=3.2.18"
optional = true
[dependencies.clap_lex]
@@ -430,6 +405,9 @@ version = "1.1.0"
[dev-dependencies.snapbox]
version = "0.2.9"
+[dev-dependencies.static_assertions]
+version = "1.1.0"
+
[dev-dependencies.trybuild]
version = "1.0.18"
diff --git a/vendor/clap/LICENSE-MIT b/vendor/clap/LICENSE-MIT
index 5acedf041..7b05b8453 100644
--- a/vendor/clap/LICENSE-MIT
+++ b/vendor/clap/LICENSE-MIT
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015-2016 Kevin B. Knapp
+Copyright (c) 2015-2022 Kevin B. Knapp and Clap Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/clap/README.md b/vendor/clap/README.md
index 48b7a3cbd..eea6ba6f0 100644
--- a/vendor/clap/README.md
+++ b/vendor/clap/README.md
@@ -1,160 +1,24 @@
-<!-- omit in TOC -->
# clap
> **Command Line Argument Parser for Rust**
[![Crates.io](https://img.shields.io/crates/v/clap?style=flat-square)](https://crates.io/crates/clap)
[![Crates.io](https://img.shields.io/crates/d/clap?style=flat-square)](https://crates.io/crates/clap)
-[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/v3.2.5/LICENSE-APACHE)
-[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/v3.2.5/LICENSE-MIT)
+[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](LICENSE-APACHE)
+[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE-MIT)
[![Build Status](https://img.shields.io/github/workflow/status/clap-rs/clap/CI/staging?style=flat-square)](https://github.com/clap-rs/clap/actions/workflows/ci.yml?query=branch%3Astaging)
[![Coverage Status](https://img.shields.io/coveralls/github/clap-rs/clap/master?style=flat-square)](https://coveralls.io/github/clap-rs/clap?branch=master)
[![Contributors](https://img.shields.io/github/contributors/clap-rs/clap?style=flat-square)](https://github.com/clap-rs/clap/graphs/contributors)
Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT).
-1. [About](#about)
-2. Tutorial: [Builder API](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_builder/README.md), [Derive API](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_derive/README.md)
-3. [Examples](https://github.com/clap-rs/clap/blob/v3.2.5/examples/README.md)
-4. [API Reference](https://docs.rs/clap)
- - [Derive Reference](https://github.com/clap-rs/clap/blob/v3.2.5/examples/derive_ref/README.md)
- - [Feature Flags](#feature-flags)
-5. [CHANGELOG](https://github.com/clap-rs/clap/blob/v3.2.5/CHANGELOG.md)
-6. [FAQ](https://github.com/clap-rs/clap/blob/v3.2.5/docs/FAQ.md)
-7. [Questions & Discussions](https://github.com/clap-rs/clap/discussions)
-8. [Contributing](https://github.com/clap-rs/clap/blob/v3.2.5/CONTRIBUTING.md)
-8. [Sponsors](#sponsors)
-
## About
Create your command-line parser, with all of the bells and whistles, declaratively or procedurally.
-### Example
-
-This uses our
-[Derive API](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_derive/README.md)
-which provides access to the [Builder API](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_builder/README.md) as attributes on a `struct`:
-
-<!-- Copied from examples/demo.{rs,md} -->
-```rust,no_run
-use clap::Parser;
-
-/// Simple program to greet a person
-#[derive(Parser, Debug)]
-#[clap(author, version, about, long_about = None)]
-struct Args {
- /// Name of the person to greet
- #[clap(short, long, value_parser)]
- name: String,
-
- /// Number of times to greet
- #[clap(short, long, value_parser, default_value_t = 1)]
- count: u8,
-}
-
-fn main() {
- let args = Args::parse();
-
- for _ in 0..args.count {
- println!("Hello {}!", args.name)
- }
-}
-```
-Add this to `Cargo.toml`:
-```toml
-[dependencies]
-clap = { version = "3.2.5", features = ["derive"] }
-```
-```bash
-$ demo --help
-clap [..]
-Simple program to greet a person
-
-USAGE:
- demo[EXE] [OPTIONS] --name <NAME>
-
-OPTIONS:
- -c, --count <COUNT> Number of times to greet [default: 1]
- -h, --help Print help information
- -n, --name <NAME> Name of the person to greet
- -V, --version Print version information
-```
-*(version number and `.exe` extension on windows replaced by placeholders)*
-
-### Aspirations
-
-- Out of the box, users get a polished CLI experience
- - Including common argument behavior, help generation, suggested fixes for users, colored output, [shell completions](https://github.com/clap-rs/clap/tree/master/clap_complete), etc
-- Flexible enough to port your existing CLI interface
- - However, we won't necessarily streamline support for each use case
-- Reasonable parse performance
-- Resilient maintainership, including
- - Willing to break compatibility rather than batching up breaking changes in large releases
- - Leverage feature flags to keep to one active branch
- - Being under [WG-CLI](https://github.com/rust-cli/team/) to increase the bus factor
-- We follow semver and will wait about 6-9 months between major breaking changes
-- We will support the last two minor Rust releases (MSRV, currently 1.56.0)
-
-While these aspirations can be at odds with fast build times and low binary
-size, we will still strive to keep these reasonable for the flexibility you
-get. Check out the
-[argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs) for
-CLI parsers optimized for other use cases.
-
-### Selecting an API
-
-Why use the declarative [Derive API](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_derive/README.md):
-- Easier to read, write, and modify
-- Easier to keep the argument declaration and reading of argument in sync
-- Easier to reuse, e.g. [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag)
-
-Why use the procedural [Builder API](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_builder/README.md):
-- Faster compile times if you aren't already using other procedural macros
-- More flexible, e.g. you can look up how many times an argument showed up,
- what its values were, and what were the indexes of those values. The Derive
- API can only report presence, number of occurrences, or values but no indices
- or combinations of data.
-
-### Related Projects
-
-- [wild](https://crates.io/crates/wild) for supporting wildcards (`*`) on Windows like you do Linux
-- [argfile](https://crates.io/crates/argfile) for loading additional arguments from a file (aka response files)
-- [shadow-rs](https://crates.io/crates/shadow-rs) for generating `Command::long_version`
-- [clap_lex](https://crates.io/crates/clap_lex) for a lighter-weight, battle-tested CLI parser
-- [clap_mangen](https://crates.io/crates/clap_mangen) for generating man page source (roff)
-- [clap_complete](https://crates.io/crates/clap_complete) for shell completion support
-- [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag)
-- [clap-cargo](https://crates.io/crates/clap-cargo)
-- [concolor-clap](https://crates.io/crates/concolor-clap)
-- [Command-line Apps for Rust](https://rust-cli.github.io/book/index.html) book
-- [`trycmd`](https://crates.io/crates/trycmd): Snapshot testing
- - Or for more control, [`assert_cmd`](https://crates.io/crates/assert_cmd) and [`assert_fs`](https://crates.io/crates/assert_fs)
-
-## Feature Flags
-
-### Default Features
-
-* **std**: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner.
-* **color**: Turns on colored error messages.
-* **suggestions**: Turns on the `Did you mean '--myoption'?` feature for when users make typos.
-
-#### Optional features
-
-* **deprecated**: Guided experience to prepare for next breaking release (at different stages of development, this may become default)
-* **derive**: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above.
-* **cargo**: Turns on macros that read values from `CARGO_*` environment variables.
-* **env**: Turns on the usage of environment variables during parsing.
-* **regex**: Enables regex validators.
-* **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
-* **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
-
-#### Experimental features
-
-**Warning:** These may contain breaking changes between minor releases.
-
-* **unstable-replace**: Enable [`Command::replace`](https://github.com/clap-rs/clap/issues/2836)
-* **unstable-grouped**: Enable [`ArgMatches::grouped_values_of`](https://github.com/clap-rs/clap/issues/2924)
-* **unstable-v4**: Preview features which will be stable on the v4.0 release
+For more details, see:
+- [docs.rs](https://docs.rs/clap/latest/clap/)
+- [examples](examples/)
## Sponsors
diff --git a/vendor/clap/examples/README.md b/vendor/clap/examples/README.md
deleted file mode 100644
index 2034ab80e..000000000
--- a/vendor/clap/examples/README.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Examples
-
-- Basic demo: [derive](demo.md)
-- Typed arguments: [derive](typed-derive.md)
- - Topics:
- - Custom `parse()`
-- Custom cargo command: [builder](cargo-example.md), [derive](cargo-example-derive.md)
- - Topics:
- - Subcommands
- - Cargo plugins
-- git-like interface: [builder](git.md), [derive](git-derive.md)
- - Topics:
- - Subcommands
- - External subcommands
- - Optional subcommands
- - Default subcommands
-- pacman-like interface: [builder](pacman.md)
- - Topics:
- - Flag subcommands
- - Conflicting arguments
-- Escaped positionals with `--`: [builder](escaped-positional.md), [derive](escaped-positional-derive.md)
-- Multi-call
- - busybox: [builder](multicall-busybox.md)
- - Topics:
- - Subcommands
- - hostname: [builder](multicall-hostname.md)
- - Topics:
- - Subcommands
-- repl: [builder](repl.rs)
- - Topics:
- - Read-Eval-Print Loops / Custom command lines
-
-## Contributing
-
-New examples:
-- Building: They must be added to [Cargo.toml](../Cargo.toml) with the appropriate `required-features`.
-- Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax
-- Link the `.md` file from here
-
-See also the general [CONTRIBUTING](../CONTRIBUTING.md).
diff --git a/vendor/clap/examples/cargo-example-derive.md b/vendor/clap/examples/cargo-example-derive.md
index 994c6d4d8..2c7a11b88 100644
--- a/vendor/clap/examples/cargo-example-derive.md
+++ b/vendor/clap/examples/cargo-example-derive.md
@@ -1,5 +1,3 @@
-*Jump to [source](cargo-example-derive.rs)*
-
For more on creating a custom subcommand, see [the cargo
book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands).
The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in
diff --git a/vendor/clap/examples/cargo-example-derive.rs b/vendor/clap/examples/cargo-example-derive.rs
index 6667a4a7d..f0aad29c7 100644
--- a/vendor/clap/examples/cargo-example-derive.rs
+++ b/vendor/clap/examples/cargo-example-derive.rs
@@ -1,8 +1,6 @@
-// Note: this requires the `derive` feature
-
use clap::Parser;
-#[derive(Parser)]
+#[derive(Parser)] // requires `derive` feature
#[clap(name = "cargo")]
#[clap(bin_name = "cargo")]
enum Cargo {
diff --git a/vendor/clap/examples/cargo-example.md b/vendor/clap/examples/cargo-example.md
index 9279cc492..6fb6a3c4d 100644
--- a/vendor/clap/examples/cargo-example.md
+++ b/vendor/clap/examples/cargo-example.md
@@ -1,5 +1,3 @@
-*Jump to [source](cargo-example.rs)*
-
For more on creating a custom subcommand, see [the cargo
book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands).
The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in
diff --git a/vendor/clap/examples/cargo-example.rs b/vendor/clap/examples/cargo-example.rs
index 45ae67c81..d9a909f4f 100644
--- a/vendor/clap/examples/cargo-example.rs
+++ b/vendor/clap/examples/cargo-example.rs
@@ -1,5 +1,3 @@
-// Note: this requires the `cargo` feature
-
fn main() {
let cmd = clap::Command::new("cargo")
.bin_name("cargo")
diff --git a/vendor/clap/examples/demo.md b/vendor/clap/examples/demo.md
index 9b0e7e260..93ee49c37 100644
--- a/vendor/clap/examples/demo.md
+++ b/vendor/clap/examples/demo.md
@@ -1,8 +1,3 @@
-*Jump to [source](demo.rs)*
-
-**This requires enabling the `derive` feature flag.**
-
-Used to validate README.md's content
```console
$ demo --help
clap [..]
@@ -17,4 +12,8 @@ OPTIONS:
-n, --name <NAME> Name of the person to greet
-V, --version Print version information
+$ demo --name Me
+Hello Me!
+
```
+*(version number and `.exe` extension on windows replaced by placeholders)*
diff --git a/vendor/clap/examples/demo.rs b/vendor/clap/examples/demo.rs
index 957489724..a7cecfb0c 100644
--- a/vendor/clap/examples/demo.rs
+++ b/vendor/clap/examples/demo.rs
@@ -1,5 +1,3 @@
-// Note: this requires the `derive` feature
-
use clap::Parser;
/// Simple program to greet a person
diff --git a/vendor/clap/examples/derive_ref/README.md b/vendor/clap/examples/derive_ref/README.md
deleted file mode 100644
index a3b0c084d..000000000
--- a/vendor/clap/examples/derive_ref/README.md
+++ /dev/null
@@ -1,440 +0,0 @@
-# Derive Reference
-
-1. [Overview](#overview)
-2. [Attributes](#attributes)
- 1. [Terminology](#terminology)
- 2. [Command Attributes](#command-attributes)
- 3. [Arg Attributes](#arg-attributes)
- 4. [Arg Enum Attributes](#arg-enum-attributes)
- 5. [Possible Value Attributes](#possible-value-attributes)
-3. [Arg Types](#arg-types)
-4. [Doc Comments](#doc-comments)
-5. [Tips](#tips)
-6. [Mixing Builder and Derive APIS](#mixing-builder-and-derive-apis)
-
-## Overview
-
-To derive `clap` types, you need to enable the `derive` feature flag.
-
-See [demo.rs](../demo.rs) and [demo.md](../demo.md) for a brief example.
-
-Let's start by breaking down the anatomy of the derive attributes:
-```rust
-use clap::{Parser, Args, Subcommand, ValueEnum};
-
-/// Doc comment
-#[derive(Parser)]
-#[clap(APP ATTRIBUTE)]
-struct Cli {
- /// Doc comment
- #[clap(ARG ATTRIBUTE)]
- field: UserType,
-
- #[clap(value_enum, ARG ATTRIBUTE...)]
- field: EnumValues,
-
- #[clap(flatten)]
- delegate: Struct,
-
- #[clap(subcommand)]
- command: Command,
-}
-
-/// Doc comment
-#[derive(Args)]
-#[clap(PARENT APP ATTRIBUTE)]
-struct Struct {
- /// Doc comment
- #[clap(ARG ATTRIBUTE)]
- field: UserType,
-}
-
-/// Doc comment
-#[derive(Subcommand)]
-#[clap(PARENT APP ATTRIBUTE)]
-enum Command {
- /// Doc comment
- #[clap(APP ATTRIBUTE)]
- Variant1(Struct),
-
- /// Doc comment
- #[clap(APP ATTRIBUTE)]
- Variant2 {
- /// Doc comment
- #[clap(ARG ATTRIBUTE)]
- field: UserType,
- }
-}
-
-/// Doc comment
-#[derive(ValueEnum)]
-#[clap(ARG ENUM ATTRIBUTE)]
-enum EnumValues {
- /// Doc comment
- #[clap(POSSIBLE VALUE ATTRIBUTE)]
- Variant1,
-}
-
-fn main() {
- let cli = Cli::parse();
-}
-```
-
-- `Parser` parses arguments into a `struct` (arguments) or `enum` (subcommands).
-- `Args` allows defining a set of re-usable arguments that get merged into their parent container.
-- `Subcommand` defines available subcommands.
- - Subcommand arguments can be defined in a struct-variant or automatically flattened with a tuple-variant.
-- `ValueEnum` allows parsing a value directly into an `enum`, erroring on unsupported values.
- - The derive doesn't work on enums that contain non-unit variants, unless they are skipped
-
-See also the [tutorial](../tutorial_derive/README.md) and [examples](../README.md).
-
-## Attributes
-
-### Terminology
-
-**Raw attributes** are forwarded directly to the underlying `clap` builder. Any
-`Command`, `Arg`, or `PossibleValue` method can be used as an attribute.
-
-Raw attributes come in two different syntaxes:
-```rust
-#[clap(
- global = true, // name = arg form, neat for one-arg methods
- required_if_eq("out", "file") // name(arg1, arg2, ...) form.
-)]
-```
-
-- `method = arg` can only be used for methods which take only one argument.
-- `method(arg1, arg2)` can be used with any method.
-
-As long as `method_name` is not one of the magical methods - it will be
-translated into a mere method call.
-
-**Magic attributes** have post-processing done to them, whether that is
-- Providing of defaults
-- Special behavior is triggered off of it
-
-Magic attributes are more constrained in the syntax they support, usually just
-`<attr> = <value>` though some use `<attr>(<value>)` instead. See the specific
-magic attributes documentation for details. This allows users to access the
-raw behavior of an attribute via `<attr>(<value>)` syntax.
-
-**NOTE:** Some attributes are inferred from [Arg Types](#arg-types) and [Doc
-Comments](#doc-comments). Explicit attributes take precedence over inferred
-attributes.
-
-### Command Attributes
-
-These correspond to a `clap::Command` which is used for both top-level parsers and
-when defining subcommands.
-
-**Raw attributes:** Any [`Command` method](https://docs.rs/clap/latest/clap/type.Command.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
-- e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)`
-
-**Magic attributes:**
-- `name = <expr>`: `clap::Command::name`
- - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (`Parser` container), variant name (`Subcommand` variant)
-- `version [= <expr>]`: `clap::Command::version`
- - When not present: no version set
- - Without `<expr>`: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field)
-- `author [= <expr>]`: `clap::Command::author`
- - When not present: no author set
- - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field)
-- `about [= <expr>]`: `clap::Command::about`
- - When not present: [Doc comment summary](#doc-comments)
- - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) (`Parser` container)
- - **TIP:** When a doc comment is also present, you most likely want to add
- `#[clap(long_about = None)]` to clear the doc comment so only `about`
- gets shown with both `-h` and `--help`.
-- `long_about = <expr>`: `clap::Command::long_about`
- - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
-- `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `about` / `long_about`
-- `next_display_order`: `clap::Command::next_display_order`
-- `next_help_heading`: `clap::Command::next_help_heading`
- - When `flatten`ing `Args`, this is scoped to just the args in this struct and any struct `flatten`ed into it
-- `rename_all = <expr>`: Override default field / variant name case conversion for `Command::name` / `Arg::name`
- - When not present: `kebab-case`
- - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
-- `rename_all_env = <expr>`: Override default field name case conversion for env variables for `clap::Arg::env`
- - When not present: `SCREAMING_SNAKE_CASE`
- - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
-
-And for `Subcommand` variants:
-- `skip`: Ignore this variant
-- `flatten`: Delegates to the variant for more subcommands (must implement `Subcommand`)
-- `subcommand`: Nest subcommands under the current set of subcommands (must implement `Subcommand`)
-- `external_subcommand`: `clap::Command::allow_external_subcommand(true)`
- - Variant must be either `Variant(Vec<String>)` or `Variant(Vec<OsString>)`
-
-### Arg Attributes
-
-These correspond to a `clap::Arg`.
-
-**Raw attributes:** Any [`Arg` method](https://docs.rs/clap/latest/clap/struct.Arg.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
-- e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)`
-
-**Magic attributes**:
-- `name = <expr>`: `clap::Arg::new`
- - When not present: case-converted field name is used
-- `value_parser [= <expr>]`: `clap::Arg::value_parser`
- - When not present: will auto-select an implementation based on the field type
- - To register a custom type's `ValueParser`, implement `ValueParserFactory`
- - When present, implies `#[clap(action)]`
-- `action [= <expr>]`: `clap::Arg::action`
- - When not present: will auto-select an action based on the field type
- - When present, implies `#[clap(value_parser)]`
-- `help = <expr>`: `clap::Arg::help`
- - When not present: [Doc comment summary](#doc-comments)
-- `long_help = <expr>`: `clap::Arg::long_help`
- - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
-- `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `help` / `long_help`
-- `short [= <char>]`: `clap::Arg::short`
- - When not present: no short set
- - Without `<char>`: defaults to first character in the case-converted field name
-- `long [= <str>]`: `clap::Arg::long`
- - When not present: no long set
- - Without `<str>`: defaults to the case-converted field name
-- `env [= <str>]`: `clap::Arg::env` (needs `env` feature enabled)
- - When not present: no env set
- - Without `<str>`: defaults to the case-converted field name
-- `flatten`: Delegates to the field for more arguments (must implement `Args`)
- - Only `help_heading` can be used with `flatten`. See
- [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why
- arg attributes are not generally supported.
- - **Tip:** Though we do apply a flattened `Args`'s Parent Command Attributes, this
- makes reuse harder. Generally prefer putting the cmd attributes on the `Parser`
- or on the flattened field.
-- `subcommand`: Delegates definition of subcommands to the field (must implement `Subcommand`)
- - When `Option<T>`, the subcommand becomes optional
-- `from_global`: Read a `clap::Arg::global` argument (raw attribute), regardless of what subcommand you are in
-- `parse(<kind> [= <function>])`: `clap::Arg::validator` and `clap::ArgMatches::values_of_t`
- - **Deprecated:**
- - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str`
- - Use `action(ArgAction::Count` for `from_occurrences`
- - Use `action(ArgAction::SetTrue` for `from_flag`
- - Default: `try_from_str`
- - Warning: for `Path` / `OsString`, be sure to use `try_from_os_str`
- - See [Arg Types](#arg-types) for more details
-- `value_enum`: Parse the value using the `ValueEnum` trait
-- `skip [= <expr>]`: Ignore this field, filling in with `<expr>`
- - Without `<expr>`: fills the field with `Default::default()`
-- `default_value = <str>`: `clap::Arg::default_value` and `clap::Arg::required(false)`
-- `default_value_t [= <expr>]`: `clap::Arg::default_value` and `clap::Arg::required(false)`
- - Requires `std::fmt::Display` or `#[clap(value_enum)]`
- - Without `<expr>`, relies on `Default::default()`
-- `default_value_os_t [= <expr>]`: `clap::Arg::default_value_os` and `clap::Arg::required(false)`
- - Requires `std::convert::Into<OsString>` or `#[clap(value_enum)]`
- - Without `<expr>`, relies on `Default::default()`
-
-### Arg Enum Attributes
-
-- `rename_all = <expr>`: Override default field / variant name case conversion for `PossibleValue::new`
- - When not present: `kebab-case`
- - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
-
-### Possible Value Attributes
-
-These correspond to a `clap::PossibleValue`.
-
-**Raw attributes:** Any [`PossibleValue` method](https://docs.rs/clap/latest/clap/struct.PossibleValue.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
-- e.g. `#[clap(alias("foo"))]` would translate to `pv.alias("foo")`
-
-**Magic attributes**:
-- `name = <expr>`: `clap::PossibleValue::new`
- - When not present: case-converted field name is used
-- `help = <expr>`: `clap::PossibleValue::help`
- - When not present: [Doc comment summary](#doc-comments)
-
-## Arg Types
-
-`clap` assumes some intent based on the type used:
-
-| Type | Effect | Implies |
-|---------------------|--------------------------------------|------------------------------------------------------------------|
-| `bool` | flag | `#[clap(parse(from_flag))]` |
-| `Option<T>` | optional argument | `.takes_value(true).required(false)` |
-| `Option<Option<T>>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` |
-| `T` | required argument | `.takes_value(true).required(!has_default)` |
-| `Vec<T>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
-| `Option<Vec<T>>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
-
-Notes:
-- For custom type behavior, you can override the implied attributes/settings and/or set additional ones
- - For example, see [custom-bool](./custom-bool.md)
-- `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
- - This gives the user some flexibility in designing their argument, like with `min_values(0)`
-
-You can then support your custom type with `#[clap(parse(<kind> [= <function>]))]`:
-
-| `<kind>` | Signature | Default `<function>` |
-|--------------------------|---------------------------------------|---------------------------------|
-| `from_str` | `fn(&str) -> T` | `::std::convert::From::from` |
-| `try_from_str` (default) | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` |
-| `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` |
-| `try_from_os_str` | `fn(&OsStr) -> Result<T, E>` | (no default function) |
-| `from_occurrences` | `fn(u64) -> T` | `value as T` |
-| `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` |
-
-Notes:
-- `from_os_str`:
- - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
-- `try_from_os_str`:
- - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
-- `from_occurrences`:
- - Implies `arg.takes_value(false).multiple_occurrences(true)`
- - Reads from `clap::ArgMatches::occurrences_of` rather than a `get_one` function
- - Note: operations on values, like `default_value`, are unlikely to do what you want
-- `from_flag`
- - Implies `arg.takes_value(false)`
- - Reads from `clap::ArgMatches::is_present` rather than a `get_one` function
- - Note: operations on values, like `default_value`, are unlikely to do what you want
-
-**Warning:**
-- To support non-UTF8 paths, you should use `#[clap(value_parser)]` otherwise
- `clap` will parse it as a `String` which will fail on some paths.
-
-## Doc Comments
-
-In clap, help messages for the whole binary can be specified
-via [`Command::about`] and [`Command::long_about`] while help messages
-for individual arguments can be specified via [`Arg::help`] and [`Arg::long_help`]".
-
-`long_*` variants are used when user calls the program with
-`--help` and "short" variants are used with `-h` flag.
-
-```rust
-# use clap::Parser;
-
-#[derive(Parser)]
-#[clap(about = "I am a program and I work, just pass `-h`", long_about = None)]
-struct Foo {
- #[clap(short, help = "Pass `-h` and you'll see me!")]
- bar: String,
-}
-```
-
-For convenience, doc comments can be used instead of raw methods
-(this example works exactly like the one above):
-
-```rust
-# use clap::Parser;
-
-#[derive(Parser)]
-/// I am a program and I work, just pass `-h`
-struct Foo {
- /// Pass `-h` and you'll see me!
- bar: String,
-}
-```
-
-**NOTE:** Attributes have priority over doc comments!
-
-**Top level doc comments always generate `Command::about/long_about` calls!**
-If you really want to use the `Command::about/long_about` methods (you likely don't),
-use the `about` / `long_about` attributes to override the calls generated from
-the doc comment. To clear `long_about`, you can use
-`#[clap(long_about = None)]`.
-
-**TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time.
-
-### Pre-processing
-
-```rust
-# use clap::Parser;
-#[derive(Parser)]
-/// Hi there, I'm Robo!
-///
-/// I like beeping, stumbling, eating your electricity,
-/// and making records of you singing in a shower.
-/// Pay up, or I'll upload it to youtube!
-struct Robo {
- /// Call my brother SkyNet.
- ///
- /// I am artificial superintelligence. I won't rest
- /// until I'll have destroyed humanity. Enjoy your
- /// pathetic existence, you mere mortals.
- #[clap(long, action)]
- kill_all_humans: bool,
-}
-```
-
-A doc comment consists of three parts:
-- Short summary
-- A blank line (whitespace only)
-- Detailed description, all the rest
-
-The summary corresponds with `Command::about` / `Arg::help`. When a blank line is
-present, the whole doc comment will be passed to `Command::long_about` /
-`Arg::long_help`. Or in other words, a doc may result in just a `Command::about` /
-`Arg::help` or `Command::about` / `Arg::help` and `Command::long_about` /
-`Arg::long_help`
-
-In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including:
-
-- Strip leading and trailing whitespace from every line, if present.
-
-- Strip leading and trailing blank lines, if present.
-
-- Interpret each group of non-empty lines as a word-wrapped paragraph.
-
- We replace newlines within paragraphs with spaces to allow the output
- to be re-wrapped to the terminal width.
-
-- Strip any excess blank lines so that there is exactly one per paragraph break.
-
-- If the first paragraph ends in exactly one period,
- remove the trailing period (i.e. strip trailing periods but not trailing ellipses).
-
-Sometimes you don't want this preprocessing to apply, for example the comment contains
-some ASCII art or markdown tables, you would need to preserve LFs along with
-blank lines and the leading/trailing whitespace. When you pass use the
-`verbatim_doc_comment` magic attribute, you preserve
-them.
-
-**Note:** Keep in mind that `verbatim_doc_comment` will *still*
-- Remove one leading space from each line, even if this attribute is present,
- to allow for a space between `///` and the content.
-- Remove leading and trailing blank lines
-
-## Tips
-
-- To get access to a `Command` call `CommandFactory::command` (implemented when deriving `Parser`)
-- Proactively check for bad `Command` configurations by calling `Command::debug_assert` in a test ([example](../tutorial_derive/05_01_assert.rs))
-
-## Mixing Builder and Derive APIs
-
-The builder and derive APIs do not live in isolation. They can work together, which is especially helpful if some arguments can be specified at compile-time while others must be specified at runtime.
-
-### Using derived arguments in a builder application
-
-*[Jump to source](augment_args.rs)*
-
-When using the derive API, you can `#[clap(flatten)]` a struct deriving `Args` into a struct deriving `Args` or `Parser`. This example shows how you can augment a `Command` instance created using the builder API with `Args` created using the derive API.
-
-It uses the `Args::augment_args` method to add the arguments to the `Command` instance.
-
-Crates such as [clap-verbosity-flag](https://github.com/rust-cli/clap-verbosity-flag) provide structs that implement `Args` or `Parser`. Without the technique shown in this example, it would not be possible to use such crates with the builder API. `augment_args` to the rescue!
-
-### Using derived subcommands in a builder application
-
-*[Jump to source](augment_subcommands.rs)*
-
-When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add subcommands. The type of the field is usually an enum that derived `Parser`. However, you can also add the subcommands in that enum to a `Command` instance created with the builder API.
-
-It uses the `Subcommand::augment_subcommands` method to add the subcommands to the `Command` instance.
-
-### Adding hand-implemented subcommands to a derived application
-
-*[Jump to source](hand_subcommand.rs)*
-
-When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add subcommands. The type of the field is usually an enum that derived `Parser`. However, you can also implement the `Subcommand` trait manually on this enum (or any other type) and it can still be used inside the struct created with the derive API. The implementation of the `Subcommand` trait will use the builder API to add the subcommands to the `Command` instance created behind the scenes for you by the derive API.
-
-Notice how in the previous example we used `augment_subcommands` on an enum that derived `Parser`, whereas now we implement `augment_subcommands` ourselves, but the derive API calls it automatically since we used the `#[clap(subcommand)]` attribute.
-
-### Flattening hand-implemented args into a derived application
-
-*[Jump to source](flatten_hand_args.rs)*
-
-When using the derive API, you can use `#[clap(flatten)]` inside the struct to add arguments as if they were added directly to the containing struct. The type of the field is usually an struct that derived `Args`. However, you can also implement the `Args` trait manually on this struct (or any other type) and it can still be used inside the struct created with the derive API. The implementation of the `Args` trait will use the builder API to add the arguments to the `Command` instance created behind the scenes for you by the derive API.
-
-Notice how in the example 1 we used `augment_args` on the struct that derived `Parser`, whereas now we implement `augment_args` ourselves, but the derive API calls it automatically since we used the `#[clap(flatten)]` attribute.
diff --git a/vendor/clap/examples/derive_ref/augment_args.rs b/vendor/clap/examples/derive_ref/augment_args.rs
index 390c72f4a..310556914 100644
--- a/vendor/clap/examples/derive_ref/augment_args.rs
+++ b/vendor/clap/examples/derive_ref/augment_args.rs
@@ -1,6 +1,6 @@
-use clap::{arg, Args as _, Command, FromArgMatches as _, Parser};
+use clap::{arg, Args, Command, FromArgMatches as _};
-#[derive(Parser, Debug)]
+#[derive(Args, Debug)]
struct DerivedArgs {
#[clap(short, long, action)]
derived: bool,
@@ -12,13 +12,10 @@ fn main() {
let cli = DerivedArgs::augment_args(cli);
let matches = cli.get_matches();
- println!(
- "Value of built: {:?}",
- *matches.get_one::<bool>("built").unwrap()
- );
+ println!("Value of built: {:?}", matches.get_flag("built"));
println!(
"Value of derived via ArgMatches: {:?}",
- *matches.get_one::<bool>("derived").unwrap()
+ matches.get_flag("derived")
);
// Since DerivedArgs implements FromArgMatches, we can extract it from the unstructured ArgMatches.
diff --git a/vendor/clap/examples/derive_ref/flatten_hand_args.rs b/vendor/clap/examples/derive_ref/flatten_hand_args.rs
index 74d10edec..c10e0b29f 100644
--- a/vendor/clap/examples/derive_ref/flatten_hand_args.rs
+++ b/vendor/clap/examples/derive_ref/flatten_hand_args.rs
@@ -15,8 +15,8 @@ impl FromArgMatches for CliArgs {
}
fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result<Self, Error> {
Ok(Self {
- foo: *matches.get_one::<bool>("foo").expect("defaulted by clap"),
- bar: *matches.get_one::<bool>("bar").expect("defaulted by clap"),
+ foo: matches.get_flag("foo"),
+ bar: matches.get_flag("bar"),
quuz: matches.remove_one::<String>("quuz"),
})
}
@@ -25,8 +25,8 @@ impl FromArgMatches for CliArgs {
self.update_from_arg_matches_mut(&mut matches)
}
fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> {
- self.foo |= *matches.get_one::<bool>("foo").expect("defaulted by clap");
- self.bar |= *matches.get_one::<bool>("bar").expect("defaulted by clap");
+ self.foo |= matches.get_flag("foo");
+ self.bar |= matches.get_flag("bar");
if let Some(quuz) = matches.remove_one::<String>("quuz") {
self.quuz = Some(quuz);
}
diff --git a/vendor/clap/examples/escaped-positional-derive.md b/vendor/clap/examples/escaped-positional-derive.md
index 3b5f8fe56..fa39a2c03 100644
--- a/vendor/clap/examples/escaped-positional-derive.md
+++ b/vendor/clap/examples/escaped-positional-derive.md
@@ -1,6 +1,4 @@
-*Jump to [source](escaped-positional-derive.rs)*
-
-**This requires enabling the `derive` feature flag.**
+**This requires enabling the [`derive` feature flag][crate::_features].**
You can use `--` to escape further arguments.
diff --git a/vendor/clap/examples/escaped-positional-derive.rs b/vendor/clap/examples/escaped-positional-derive.rs
index 54dbc853b..fd8fde4ed 100644
--- a/vendor/clap/examples/escaped-positional-derive.rs
+++ b/vendor/clap/examples/escaped-positional-derive.rs
@@ -1,8 +1,6 @@
-// Note: this requires the `derive` feature
-
use clap::Parser;
-#[derive(Parser)]
+#[derive(Parser)] // requires `derive` feature
#[clap(author, version, about, long_about = None)]
struct Cli {
#[clap(short = 'f', action)]
diff --git a/vendor/clap/examples/escaped-positional.md b/vendor/clap/examples/escaped-positional.md
index 1f71a8736..987b26139 100644
--- a/vendor/clap/examples/escaped-positional.md
+++ b/vendor/clap/examples/escaped-positional.md
@@ -1,6 +1,4 @@
-*Jump to [source](escaped-positional.rs)*
-
-**This requires enabling the `cargo` feature flag.**
+**This requires enabling the [`cargo` feature flag][crate::_features].**
You can use `--` to escape further arguments.
diff --git a/vendor/clap/examples/escaped-positional.rs b/vendor/clap/examples/escaped-positional.rs
index a0fff790b..fdcb930fb 100644
--- a/vendor/clap/examples/escaped-positional.rs
+++ b/vendor/clap/examples/escaped-positional.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command, value_parser, ArgAction};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(arg!(eff: -f).action(ArgAction::SetTrue))
.arg(
arg!(pea: -p <PEAR>)
@@ -22,10 +20,7 @@ fn main() {
// This is what will happen with `myprog -f -p=bob -- sloppy slop slop`...
// -f used: true
- println!(
- "-f used: {:?}",
- *matches.get_one::<bool>("eff").expect("defaulted by clap")
- );
+ println!("-f used: {:?}", matches.get_flag("eff"));
// -p's value: Some("bob")
println!("-p's value: {:?}", matches.get_one::<String>("pea"));
// 'slops' values: Some(["sloppy", "slop", "slop"])
diff --git a/vendor/clap/examples/git-derive.md b/vendor/clap/examples/git-derive.md
index dc27776f5..aa1ca6d9d 100644
--- a/vendor/clap/examples/git-derive.md
+++ b/vendor/clap/examples/git-derive.md
@@ -1,6 +1,4 @@
-*Jump to [source](git-derive.rs)*
-
-**This requires enabling the `derive` feature flag.**
+**This requires enabling the [`derive` feature flag][crate::_features].**
Git is an example of several common subcommand patterns.
diff --git a/vendor/clap/examples/git-derive.rs b/vendor/clap/examples/git-derive.rs
index ecbda3fe9..ac500ddad 100644
--- a/vendor/clap/examples/git-derive.rs
+++ b/vendor/clap/examples/git-derive.rs
@@ -1,12 +1,10 @@
-// Note: this requires the `derive` feature
-
use std::ffi::OsString;
use std::path::PathBuf;
use clap::{Args, Parser, Subcommand};
/// A fictional versioning CLI
-#[derive(Debug, Parser)]
+#[derive(Debug, Parser)] // requires `derive` feature
#[clap(name = "git")]
#[clap(about = "A fictional versioning CLI", long_about = None)]
struct Cli {
diff --git a/vendor/clap/examples/git.md b/vendor/clap/examples/git.md
index 2cdfe653b..9e413415a 100644
--- a/vendor/clap/examples/git.md
+++ b/vendor/clap/examples/git.md
@@ -1,5 +1,3 @@
-*Jump to [source](git.rs)*
-
Git is an example of several common subcommand patterns.
Help:
diff --git a/vendor/clap/examples/git.rs b/vendor/clap/examples/git.rs
index 5536f1487..e56f427a6 100644
--- a/vendor/clap/examples/git.rs
+++ b/vendor/clap/examples/git.rs
@@ -1,5 +1,3 @@
-// Note: this requires the `cargo` feature
-
use std::ffi::OsString;
use std::path::PathBuf;
diff --git a/vendor/clap/examples/multicall-busybox.md b/vendor/clap/examples/multicall-busybox.md
index a09418403..5ca2cad5b 100644
--- a/vendor/clap/examples/multicall-busybox.md
+++ b/vendor/clap/examples/multicall-busybox.md
@@ -1,8 +1,4 @@
-*Jump to [source](multicall-busybox.rs)*
-
-Example of a busybox-style multicall program
-
-See the documentation for `clap::Command::multicall` for rationale.
+See the documentation for [`Command::multicall`][crate::App::multicall] for rationale.
This example omits every command except true and false,
which are the most trivial to implement,
diff --git a/vendor/clap/examples/multicall-hostname.md b/vendor/clap/examples/multicall-hostname.md
index 9e17ca16c..d22b85fba 100644
--- a/vendor/clap/examples/multicall-hostname.md
+++ b/vendor/clap/examples/multicall-hostname.md
@@ -1,8 +1,4 @@
-*Jump to [source](multicall-hostname.rs)*
-
-Example of a `hostname-style` multicall program
-
-See the documentation for `clap::Command::multicall` for rationale.
+See the documentation for [`Command::multicall`][crate::App::multicall] for rationale.
This example omits the implementation of displaying address config
diff --git a/vendor/clap/examples/pacman.md b/vendor/clap/examples/pacman.md
index 7f6c5a7d3..b8ddd09d9 100644
--- a/vendor/clap/examples/pacman.md
+++ b/vendor/clap/examples/pacman.md
@@ -1,5 +1,3 @@
-*Jump to [source](pacman.rs)*
-
[`pacman`](https://wiki.archlinux.org/index.php/pacman) defines subcommands via flags.
Here, `-S` is a short flag subcommand:
diff --git a/vendor/clap/examples/pacman.rs b/vendor/clap/examples/pacman.rs
index 6a60a8bf5..aee7cd892 100644
--- a/vendor/clap/examples/pacman.rs
+++ b/vendor/clap/examples/pacman.rs
@@ -89,10 +89,7 @@ fn main() {
.collect();
let values = packages.join(", ");
- if *sync_matches
- .get_one::<bool>("info")
- .expect("defaulted by clap")
- {
+ if sync_matches.get_flag("info") {
println!("Retrieving info for {}...", values);
} else {
println!("Installing {}...", values);
diff --git a/vendor/clap/examples/tutorial_builder/01_quick.md b/vendor/clap/examples/tutorial_builder/01_quick.md
new file mode 100644
index 000000000..4a9e3fca1
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/01_quick.md
@@ -0,0 +1,37 @@
+```console
+$ 01_quick --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 01_quick[EXE] [OPTIONS] [name] [SUBCOMMAND]
+
+ARGS:
+ <name> Optional name to operate on
+
+OPTIONS:
+ -c, --config <FILE> Sets a custom config file
+ -d, --debug Turn debugging information on
+ -h, --help Print help information
+ -V, --version Print version information
+
+SUBCOMMANDS:
+ help Print this message or the help of the given subcommand(s)
+ test does testing things
+
+```
+
+By default, the program does nothing:
+```console
+$ 01_quick
+Debug mode is off
+
+```
+
+But you can mix and match the various features
+```console
+$ 01_quick -dd test
+Debug mode is on
+Not printing testing lists...
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/01_quick.rs b/vendor/clap/examples/tutorial_builder/01_quick.rs
index 61cc3432d..393d6aeae 100644
--- a/vendor/clap/examples/tutorial_builder/01_quick.rs
+++ b/vendor/clap/examples/tutorial_builder/01_quick.rs
@@ -1,11 +1,9 @@
-// Note: this requires the `cargo` feature
-
use std::path::PathBuf;
use clap::{arg, command, value_parser, ArgAction, Command};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(arg!([name] "Optional name to operate on"))
.arg(
arg!(
diff --git a/vendor/clap/examples/tutorial_builder/02_app_settings.md b/vendor/clap/examples/tutorial_builder/02_app_settings.md
new file mode 100644
index 000000000..247843bcf
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/02_app_settings.md
@@ -0,0 +1,19 @@
+```console
+$ 02_app_settings --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 02_app_settings[EXE] --two <VALUE> --one <VALUE>
+
+OPTIONS:
+ --two <VALUE>
+ --one <VALUE>
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 02_app_settings --one -1 --one -3 --two 10
+two: "10"
+one: "-3"
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/02_app_settings.rs b/vendor/clap/examples/tutorial_builder/02_app_settings.rs
index 7bbedd3eb..5f374d7f0 100644
--- a/vendor/clap/examples/tutorial_builder/02_app_settings.rs
+++ b/vendor/clap/examples/tutorial_builder/02_app_settings.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command, AppSettings, ArgAction};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.global_setting(AppSettings::DeriveDisplayOrder)
.allow_negative_numbers(true)
.arg(arg!(--two <VALUE>).action(ArgAction::Set))
diff --git a/vendor/clap/examples/tutorial_builder/02_apps.md b/vendor/clap/examples/tutorial_builder/02_apps.md
new file mode 100644
index 000000000..8504b5f52
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/02_apps.md
@@ -0,0 +1,19 @@
+```console
+$ 02_apps --help
+MyApp 1.0
+Kevin K. <kbknapp@gmail.com>
+Does awesome things
+
+USAGE:
+ 02_apps[EXE] --two <VALUE> --one <VALUE>
+
+OPTIONS:
+ -h, --help Print help information
+ --one <VALUE>
+ --two <VALUE>
+ -V, --version Print version information
+
+$ 02_apps --version
+MyApp 1.0
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/02_crate.md b/vendor/clap/examples/tutorial_builder/02_crate.md
new file mode 100644
index 000000000..f76e0d608
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/02_crate.md
@@ -0,0 +1,18 @@
+```console
+$ 02_crate --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 02_crate[EXE] --two <VALUE> --one <VALUE>
+
+OPTIONS:
+ -h, --help Print help information
+ --one <VALUE>
+ --two <VALUE>
+ -V, --version Print version information
+
+$ 02_crate --version
+clap [..]
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/02_crate.rs b/vendor/clap/examples/tutorial_builder/02_crate.rs
index 16b7e7ee0..8a1722fd3 100644
--- a/vendor/clap/examples/tutorial_builder/02_crate.rs
+++ b/vendor/clap/examples/tutorial_builder/02_crate.rs
@@ -1,8 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command};
fn main() {
+ // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml`
let matches = command!()
.arg(arg!(--two <VALUE>))
.arg(arg!(--one <VALUE>))
diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.md b/vendor/clap/examples/tutorial_builder/03_01_flag_bool.md
new file mode 100644
index 000000000..b0ee2a126
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/03_01_flag_bool.md
@@ -0,0 +1,23 @@
+```console
+$ 03_01_flag_bool --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_01_flag_bool[EXE] [OPTIONS]
+
+OPTIONS:
+ -h, --help Print help information
+ -v, --verbose
+ -V, --version Print version information
+
+$ 03_01_flag_bool
+verbose: false
+
+$ 03_01_flag_bool --verbose
+verbose: true
+
+$ 03_01_flag_bool --verbose --verbose
+verbose: true
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs b/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs
index 41ecbb1d7..03f2f1756 100644
--- a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs
+++ b/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{command, Arg, ArgAction};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(
Arg::new("verbose")
.short('v')
@@ -12,10 +10,5 @@ fn main() {
)
.get_matches();
- println!(
- "verbose: {:?}",
- *matches
- .get_one::<bool>("verbose")
- .expect("defaulted by clap")
- );
+ println!("verbose: {:?}", matches.get_flag("verbose"));
}
diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_count.md b/vendor/clap/examples/tutorial_builder/03_01_flag_count.md
new file mode 100644
index 000000000..ca4bcd6eb
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/03_01_flag_count.md
@@ -0,0 +1,23 @@
+```console
+$ 03_01_flag_count --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_01_flag_count[EXE] [OPTIONS]
+
+OPTIONS:
+ -h, --help Print help information
+ -v, --verbose
+ -V, --version Print version information
+
+$ 03_01_flag_count
+verbose: 0
+
+$ 03_01_flag_count --verbose
+verbose: 1
+
+$ 03_01_flag_count --verbose --verbose
+verbose: 2
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs b/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs
index 764affbd8..7f23649d6 100644
--- a/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs
+++ b/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs
@@ -1,16 +1,9 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command, ArgAction};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(arg!(-v - -verbose).action(ArgAction::Count))
.get_matches();
- println!(
- "verbose: {:?}",
- matches
- .get_one::<u8>("verbose")
- .expect("Count always defaulted")
- );
+ println!("verbose: {:?}", matches.get_count("verbose"));
}
diff --git a/vendor/clap/examples/tutorial_builder/03_02_option.md b/vendor/clap/examples/tutorial_builder/03_02_option.md
new file mode 100644
index 000000000..6198bcc73
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/03_02_option.md
@@ -0,0 +1,32 @@
+```console
+$ 03_02_option --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_02_option[EXE] [OPTIONS]
+
+OPTIONS:
+ -h, --help Print help information
+ -n, --name <NAME>
+ -V, --version Print version information
+
+$ 03_02_option
+name: None
+
+$ 03_02_option --name bob
+name: Some("bob")
+
+$ 03_02_option --name=bob
+name: Some("bob")
+
+$ 03_02_option -n bob
+name: Some("bob")
+
+$ 03_02_option -n=bob
+name: Some("bob")
+
+$ 03_02_option -nbob
+name: Some("bob")
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/03_02_option.rs b/vendor/clap/examples/tutorial_builder/03_02_option.rs
index 80e2b9159..188244566 100644
--- a/vendor/clap/examples/tutorial_builder/03_02_option.rs
+++ b/vendor/clap/examples/tutorial_builder/03_02_option.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(arg!(-n --name <NAME>).required(false))
.get_matches();
diff --git a/vendor/clap/examples/tutorial_builder/03_03_positional.md b/vendor/clap/examples/tutorial_builder/03_03_positional.md
new file mode 100644
index 000000000..a3d7b8cf3
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/03_03_positional.md
@@ -0,0 +1,22 @@
+```console
+$ 03_03_positional --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_03_positional[EXE] [NAME]
+
+ARGS:
+ <NAME>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 03_03_positional
+NAME: None
+
+$ 03_03_positional bob
+NAME: Some("bob")
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/03_03_positional.rs b/vendor/clap/examples/tutorial_builder/03_03_positional.rs
index c6579409a..0c3a5f037 100644
--- a/vendor/clap/examples/tutorial_builder/03_03_positional.rs
+++ b/vendor/clap/examples/tutorial_builder/03_03_positional.rs
@@ -1,9 +1,9 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command};
fn main() {
- let matches = command!().arg(arg!([NAME])).get_matches();
+ let matches = command!() // requires `cargo` feature
+ .arg(arg!([NAME]))
+ .get_matches();
println!("NAME: {:?}", matches.get_one::<String>("NAME"));
}
diff --git a/vendor/clap/examples/tutorial_builder/03_04_subcommands.md b/vendor/clap/examples/tutorial_builder/03_04_subcommands.md
new file mode 100644
index 000000000..8f9efa911
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/03_04_subcommands.md
@@ -0,0 +1,64 @@
+```console
+$ 03_04_subcommands help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_04_subcommands[EXE] <SUBCOMMAND>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+SUBCOMMANDS:
+ add Adds files to myapp
+ help Print this message or the help of the given subcommand(s)
+
+$ 03_04_subcommands help add
+03_04_subcommands[EXE]-add [..]
+Adds files to myapp
+
+USAGE:
+ 03_04_subcommands[EXE] add [NAME]
+
+ARGS:
+ <NAME>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 03_04_subcommands add bob
+'myapp add' was used, name is: Some("bob")
+
+```
+
+Because we set [`Command::arg_required_else_help`][crate::Command::arg_required_else_help]:
+```console
+$ 03_04_subcommands
+? failed
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_04_subcommands[EXE] <SUBCOMMAND>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+SUBCOMMANDS:
+ add Adds files to myapp
+ help Print this message or the help of the given subcommand(s)
+
+```
+
+Because we set [`Command::propagate_version`][crate::Command::propagate_version]:
+```console
+$ 03_04_subcommands --version
+clap [..]
+
+$ 03_04_subcommands add --version
+03_04_subcommands[EXE]-add [..]
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs b/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs
index 1dd1cbf09..fbe23809e 100644
--- a/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs
+++ b/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command, Command};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.propagate_version(true)
.subcommand_required(true)
.arg_required_else_help(true)
diff --git a/vendor/clap/examples/tutorial_builder/03_05_default_values.md b/vendor/clap/examples/tutorial_builder/03_05_default_values.md
new file mode 100644
index 000000000..7b6c0307d
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/03_05_default_values.md
@@ -0,0 +1,22 @@
+```console
+$ 03_05_default_values --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_05_default_values[EXE] [NAME]
+
+ARGS:
+ <NAME> [default: alice]
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 03_05_default_values
+NAME: "alice"
+
+$ 03_05_default_values bob
+NAME: "bob"
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/03_05_default_values.rs b/vendor/clap/examples/tutorial_builder/03_05_default_values.rs
index c68e87973..cb3e3831f 100644
--- a/vendor/clap/examples/tutorial_builder/03_05_default_values.rs
+++ b/vendor/clap/examples/tutorial_builder/03_05_default_values.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(arg!([NAME]).default_value("alice"))
.get_matches();
diff --git a/vendor/clap/examples/tutorial_builder/04_01_enum.md b/vendor/clap/examples/tutorial_builder/04_01_enum.md
new file mode 100644
index 000000000..282b1e613
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/04_01_enum.md
@@ -0,0 +1,29 @@
+```console
+$ 04_01_enum --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_01_enum[EXE] <MODE>
+
+ARGS:
+ <MODE> What mode to run the program in [possible values: fast, slow]
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_01_enum fast
+Hare
+
+$ 04_01_enum slow
+Tortoise
+
+$ 04_01_enum medium
+? failed
+error: "medium" isn't a valid value for '<MODE>'
+ [possible values: fast, slow]
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/04_01_enum.rs b/vendor/clap/examples/tutorial_builder/04_01_enum.rs
index ad2177c23..e8cf70f5c 100644
--- a/vendor/clap/examples/tutorial_builder/04_01_enum.rs
+++ b/vendor/clap/examples/tutorial_builder/04_01_enum.rs
@@ -1,15 +1,49 @@
-// Note: this requires the `cargo` feature
+use clap::{arg, builder::PossibleValue, command, value_parser, ValueEnum};
-use clap::{arg, command, value_parser, ValueEnum};
-
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum Mode {
Fast,
Slow,
}
+// Can also be derived] with feature flag `derive`
+impl ValueEnum for Mode {
+ fn value_variants<'a>() -> &'a [Self] {
+ &[Mode::Fast, Mode::Slow]
+ }
+
+ fn to_possible_value<'a>(&self) -> Option<PossibleValue<'a>> {
+ Some(match self {
+ Mode::Fast => PossibleValue::new("fast"),
+ Mode::Slow => PossibleValue::new("slow"),
+ })
+ }
+}
+
+impl std::fmt::Display for Mode {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.to_possible_value()
+ .expect("no values are skipped")
+ .get_name()
+ .fmt(f)
+ }
+}
+
+impl std::str::FromStr for Mode {
+ type Err = String;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ for variant in Self::value_variants() {
+ if variant.to_possible_value().unwrap().matches(s, false) {
+ return Ok(*variant);
+ }
+ }
+ Err(format!("Invalid variant: {}", s))
+ }
+}
+
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(
arg!(<MODE>)
.help("What mode to run the program in")
diff --git a/vendor/clap/examples/tutorial_builder/04_01_possible.md b/vendor/clap/examples/tutorial_builder/04_01_possible.md
new file mode 100644
index 000000000..2909bfb17
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/04_01_possible.md
@@ -0,0 +1,29 @@
+```console
+$ 04_01_possible --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_01_possible[EXE] <MODE>
+
+ARGS:
+ <MODE> What mode to run the program in [possible values: fast, slow]
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_01_possible fast
+Hare
+
+$ 04_01_possible slow
+Tortoise
+
+$ 04_01_possible medium
+? failed
+error: "medium" isn't a valid value for '<MODE>'
+ [possible values: fast, slow]
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/04_01_possible.rs b/vendor/clap/examples/tutorial_builder/04_01_possible.rs
index f7b0cfb34..3da7aca74 100644
--- a/vendor/clap/examples/tutorial_builder/04_01_possible.rs
+++ b/vendor/clap/examples/tutorial_builder/04_01_possible.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(
arg!(<MODE>)
.help("What mode to run the program in")
diff --git a/vendor/clap/examples/tutorial_builder/04_02_parse.md b/vendor/clap/examples/tutorial_builder/04_02_parse.md
new file mode 100644
index 000000000..605bf4b59
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/04_02_parse.md
@@ -0,0 +1,31 @@
+```console
+$ 04_02_parse --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_02_parse[EXE] <PORT>
+
+ARGS:
+ <PORT> Network port to use
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_02_parse 22
+PORT = 22
+
+$ 04_02_parse foobar
+? failed
+error: Invalid value "foobar" for '<PORT>': invalid digit found in string
+
+For more information try --help
+
+$ 04_02_parse_derive 0
+? failed
+error: Invalid value "0" for '<PORT>': 0 is not in 1..=65535
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/04_02_parse.rs b/vendor/clap/examples/tutorial_builder/04_02_parse.rs
index c2f3cc533..13f41a18e 100644
--- a/vendor/clap/examples/tutorial_builder/04_02_parse.rs
+++ b/vendor/clap/examples/tutorial_builder/04_02_parse.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command, value_parser};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(
arg!(<PORT>)
.help("Network port to use")
diff --git a/vendor/clap/examples/tutorial_builder/04_02_validate.md b/vendor/clap/examples/tutorial_builder/04_02_validate.md
new file mode 100644
index 000000000..a317a8eb7
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/04_02_validate.md
@@ -0,0 +1,31 @@
+```console
+$ 04_02_validate --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_02_validate[EXE] <PORT>
+
+ARGS:
+ <PORT> Network port to use
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_02_validate 22
+PORT = 22
+
+$ 04_02_validate foobar
+? failed
+error: Invalid value "foobar" for '<PORT>': `foobar` isn't a port number
+
+For more information try --help
+
+$ 04_02_validate 0
+? failed
+error: Invalid value "0" for '<PORT>': Port not in range 1-65535
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/04_02_validate.rs b/vendor/clap/examples/tutorial_builder/04_02_validate.rs
index e60018a46..ea2f32e67 100644
--- a/vendor/clap/examples/tutorial_builder/04_02_validate.rs
+++ b/vendor/clap/examples/tutorial_builder/04_02_validate.rs
@@ -1,11 +1,9 @@
-// Note: this requires the `cargo` feature
-
use std::ops::RangeInclusive;
use clap::{arg, command};
fn main() {
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
.arg(
arg!(<PORT>)
.help("Network port to use")
diff --git a/vendor/clap/examples/tutorial_builder/04_03_relations.md b/vendor/clap/examples/tutorial_builder/04_03_relations.md
new file mode 100644
index 000000000..3ea336363
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/04_03_relations.md
@@ -0,0 +1,58 @@
+```console
+$ 04_03_relations --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_03_relations[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
+
+ARGS:
+ <INPUT_FILE> some regular input
+
+OPTIONS:
+ -c <CONFIG>
+ -h, --help Print help information
+ --major auto inc major
+ --minor auto inc minor
+ --patch auto inc patch
+ --set-ver <VER> set version manually
+ --spec-in <SPEC_IN> some special input argument
+ -V, --version Print version information
+
+$ 04_03_relations
+? failed
+error: The following required arguments were not provided:
+ <--set-ver <VER>|--major|--minor|--patch>
+
+USAGE:
+ 04_03_relations[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
+
+For more information try --help
+
+$ 04_03_relations --major
+Version: 2.2.3
+
+$ 04_03_relations --major --minor
+? failed
+error: The argument '--major' cannot be used with '--minor'
+
+USAGE:
+ 04_03_relations[EXE] <--set-ver <VER>|--major|--minor|--patch>
+
+For more information try --help
+
+$ 04_03_relations --major -c config.toml
+? failed
+error: The following required arguments were not provided:
+ <INPUT_FILE|--spec-in <SPEC_IN>>
+
+USAGE:
+ 04_03_relations[EXE] -c <CONFIG> <--set-ver <VER>|--major|--minor|--patch> <INPUT_FILE|--spec-in <SPEC_IN>>
+
+For more information try --help
+
+$ 04_03_relations --major -c config.toml --spec-in input.txt
+Version: 2.2.3
+Doing work using input input.txt and config config.toml
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/04_03_relations.rs b/vendor/clap/examples/tutorial_builder/04_03_relations.rs
index 605e5b48e..8e26d3ea9 100644
--- a/vendor/clap/examples/tutorial_builder/04_03_relations.rs
+++ b/vendor/clap/examples/tutorial_builder/04_03_relations.rs
@@ -1,12 +1,10 @@
-// Note: this requires the `cargo` feature
-
use std::path::PathBuf;
use clap::{arg, command, value_parser, ArgAction, ArgGroup};
fn main() {
// Create application like normal
- let matches = command!()
+ let matches = command!() // requires `cargo` feature
// Add the version arguments
.arg(arg!(--"set-ver" <VER> "set version manually").required(false))
.arg(arg!(--major "auto inc major").action(ArgAction::SetTrue))
@@ -52,9 +50,9 @@ fn main() {
} else {
// Increment the one requested (in a real program, we'd reset the lower numbers)
let (maj, min, pat) = (
- *matches.get_one::<bool>("major").expect("defaulted by clap"),
- *matches.get_one::<bool>("minor").expect("defaulted by clap"),
- *matches.get_one::<bool>("patch").expect("defaulted by clap"),
+ matches.get_flag("major"),
+ matches.get_flag("minor"),
+ matches.get_flag("patch"),
);
match (maj, min, pat) {
(true, _, _) => major += 1,
diff --git a/vendor/clap/examples/tutorial_builder/04_04_custom.md b/vendor/clap/examples/tutorial_builder/04_04_custom.md
new file mode 100644
index 000000000..26a3df1ab
--- /dev/null
+++ b/vendor/clap/examples/tutorial_builder/04_04_custom.md
@@ -0,0 +1,57 @@
+```console
+$ 04_04_custom --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
+
+ARGS:
+ <INPUT_FILE> some regular input
+
+OPTIONS:
+ -c <CONFIG>
+ -h, --help Print help information
+ --major auto inc major
+ --minor auto inc minor
+ --patch auto inc patch
+ --set-ver <VER> set version manually
+ --spec-in <SPEC_IN> some special input argument
+ -V, --version Print version information
+
+$ 04_04_custom
+? failed
+error: Can only modify one version field
+
+USAGE:
+ 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
+
+For more information try --help
+
+$ 04_04_custom --major
+Version: 2.2.3
+
+$ 04_04_custom --major --minor
+? failed
+error: Can only modify one version field
+
+USAGE:
+ 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
+
+For more information try --help
+
+$ 04_04_custom --major -c config.toml
+? failed
+Version: 2.2.3
+error: INPUT_FILE or --spec-in is required when using --config
+
+USAGE:
+ 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
+
+For more information try --help
+
+$ 04_04_custom --major -c config.toml --spec-in input.txt
+Version: 2.2.3
+Doing work using input input.txt and config config.toml
+
+```
diff --git a/vendor/clap/examples/tutorial_builder/04_04_custom.rs b/vendor/clap/examples/tutorial_builder/04_04_custom.rs
index 3dc080505..fb40b2fc4 100644
--- a/vendor/clap/examples/tutorial_builder/04_04_custom.rs
+++ b/vendor/clap/examples/tutorial_builder/04_04_custom.rs
@@ -1,12 +1,10 @@
-// Note: this requires the `cargo` feature
-
use std::path::PathBuf;
use clap::{arg, command, value_parser, ArgAction, ErrorKind};
fn main() {
// Create application like normal
- let mut cmd = command!()
+ let mut cmd = command!() // requires `cargo` feature
// Add the version arguments
.arg(arg!(--"set-ver" <VER> "set version manually").required(false))
.arg(arg!(--major "auto inc major").action(ArgAction::SetTrue))
@@ -36,10 +34,7 @@ fn main() {
// See if --set-ver was used to set the version manually
let version = if let Some(ver) = matches.get_one::<String>("set-ver") {
- if *matches.get_one::<bool>("major").expect("defaulted by clap")
- || *matches.get_one::<bool>("minor").expect("defaulted by clap")
- || *matches.get_one::<bool>("patch").expect("defaulted by clap")
- {
+ if matches.get_flag("major") || matches.get_flag("minor") || matches.get_flag("patch") {
cmd.error(
ErrorKind::ArgumentConflict,
"Can't do relative and absolute version change",
@@ -50,9 +45,9 @@ fn main() {
} else {
// Increment the one requested (in a real program, we'd reset the lower numbers)
let (maj, min, pat) = (
- *matches.get_one::<bool>("major").expect("defaulted by clap"),
- *matches.get_one::<bool>("minor").expect("defaulted by clap"),
- *matches.get_one::<bool>("patch").expect("defaulted by clap"),
+ matches.get_flag("major"),
+ matches.get_flag("minor"),
+ matches.get_flag("patch"),
);
match (maj, min, pat) {
(true, false, false) => major += 1,
diff --git a/vendor/clap/examples/tutorial_builder/05_01_assert.rs b/vendor/clap/examples/tutorial_builder/05_01_assert.rs
index d6f19ffe5..4b9254230 100644
--- a/vendor/clap/examples/tutorial_builder/05_01_assert.rs
+++ b/vendor/clap/examples/tutorial_builder/05_01_assert.rs
@@ -1,5 +1,3 @@
-// Note: this requires the `cargo` feature
-
use clap::{arg, command, value_parser};
fn main() {
@@ -13,14 +11,15 @@ fn main() {
}
fn cmd() -> clap::Command<'static> {
- command!().arg(
- arg!(<PORT>)
- .help("Network port to use")
- .value_parser(value_parser!(usize)),
- )
+ command!() // requires `cargo` feature
+ .arg(
+ arg!(<PORT>)
+ .help("Network port to use")
+ .value_parser(value_parser!(usize)),
+ )
}
#[test]
-fn verify_app() {
+fn verify_cmd() {
cmd().debug_assert();
}
diff --git a/vendor/clap/examples/tutorial_builder/README.md b/vendor/clap/examples/tutorial_builder/README.md
deleted file mode 100644
index 945b01e72..000000000
--- a/vendor/clap/examples/tutorial_builder/README.md
+++ /dev/null
@@ -1,658 +0,0 @@
-# Tutorial
-
-*Jump to [derive tutorial](../tutorial_derive/README.md)*
-
-1. [Quick Start](#quick-start)
-2. [Configuring the Parser](#configuring-the-parser)
-3. [Adding Arguments](#adding-arguments)
- 1. [Positionals](#positionals)
- 2. [Options](#options)
- 3. [Flags](#flags)
- 4. [Subcommands](#subcommands)
- 5. [Defaults](#defaults)
-4. Validation
- 1. [Enumerated values](#enumerated-values)
- 2. [Validated values](#validated-values)
- 3. [Argument Relations](#argument-relations)
- 4. [Custom Validation](#custom-validation)
-5. [Tips](#tips)
-6. [Contributing](#contributing)
-
-## Quick Start
-
-You can create an application with several arguments using usage strings.
-
-[Example:](01_quick.rs)
-```console
-$ 01_quick --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 01_quick[EXE] [OPTIONS] [name] [SUBCOMMAND]
-
-ARGS:
- <name> Optional name to operate on
-
-OPTIONS:
- -c, --config <FILE> Sets a custom config file
- -d, --debug Turn debugging information on
- -h, --help Print help information
- -V, --version Print version information
-
-SUBCOMMANDS:
- help Print this message or the help of the given subcommand(s)
- test does testing things
-
-```
-
-By default, the program does nothing:
-```console
-$ 01_quick
-Debug mode is off
-
-```
-
-But you can mix and match the various features
-```console
-$ 01_quick -dd test
-Debug mode is on
-Not printing testing lists...
-
-```
-
-## Configuring the Parser
-
-You use the `Command` the start building a parser.
-
-[Example:](02_apps.rs)
-```console
-$ 02_apps --help
-MyApp 1.0
-Kevin K. <kbknapp@gmail.com>
-Does awesome things
-
-USAGE:
- 02_apps[EXE] --two <VALUE> --one <VALUE>
-
-OPTIONS:
- -h, --help Print help information
- --one <VALUE>
- --two <VALUE>
- -V, --version Print version information
-
-$ 02_apps --version
-MyApp 1.0
-
-```
-
-You can use `command!()` to fill these fields in from your `Cargo.toml`
-file. **This requires the `cargo` feature flag.**
-
-[Example:](02_crate.rs)
-```console
-$ 02_crate --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 02_crate[EXE] --two <VALUE> --one <VALUE>
-
-OPTIONS:
- -h, --help Print help information
- --one <VALUE>
- --two <VALUE>
- -V, --version Print version information
-
-$ 02_crate --version
-clap [..]
-
-```
-
-You can use `Command` methods to change the application level behavior of clap.
-
-[Example:](02_app_settings.rs)
-```console
-$ 02_app_settings --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 02_app_settings[EXE] --two <VALUE> --one <VALUE>
-
-OPTIONS:
- --two <VALUE>
- --one <VALUE>
- -h, --help Print help information
- -V, --version Print version information
-
-$ 02_app_settings --one -1 --one -3 --two 10
-two: "10"
-one: "-3"
-
-```
-
-## Adding Arguments
-
-### Positionals
-
-You can have users specify values by their position on the command-line:
-
-[Example:](03_03_positional.rs)
-```console
-$ 03_03_positional --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_03_positional[EXE] [NAME]
-
-ARGS:
- <NAME>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 03_03_positional
-NAME: None
-
-$ 03_03_positional bob
-NAME: Some("bob")
-
-```
-
-### Options
-
-You can name your arguments with a flag:
-- Order doesn't matter
-- They can be optional
-- Intent is clearer
-
-[Example:](03_02_option.rs)
-```console
-$ 03_02_option --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_02_option[EXE] [OPTIONS]
-
-OPTIONS:
- -h, --help Print help information
- -n, --name <NAME>
- -V, --version Print version information
-
-$ 03_02_option
-name: None
-
-$ 03_02_option --name bob
-name: Some("bob")
-
-$ 03_02_option --name=bob
-name: Some("bob")
-
-$ 03_02_option -n bob
-name: Some("bob")
-
-$ 03_02_option -n=bob
-name: Some("bob")
-
-$ 03_02_option -nbob
-name: Some("bob")
-
-```
-
-### Flags
-
-Flags can also be switches that can be on/off:
-
-[Example:](03_01_flag_bool.rs)
-```console
-$ 03_01_flag_bool --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_01_flag_bool[EXE] [OPTIONS]
-
-OPTIONS:
- -h, --help Print help information
- -v, --verbose
- -V, --version Print version information
-
-$ 03_01_flag_bool
-verbose: false
-
-$ 03_01_flag_bool --verbose
-verbose: true
-
-$ 03_01_flag_bool --verbose --verbose
-verbose: true
-
-```
-
-Or counted.
-
-[Example:](03_01_flag_count.rs)
-```console
-$ 03_01_flag_count --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_01_flag_count[EXE] [OPTIONS]
-
-OPTIONS:
- -h, --help Print help information
- -v, --verbose
- -V, --version Print version information
-
-$ 03_01_flag_count
-verbose: 0
-
-$ 03_01_flag_count --verbose
-verbose: 1
-
-$ 03_01_flag_count --verbose --verbose
-verbose: 2
-
-```
-
-### Subcommands
-
-Subcommands are defined as `Command`s that get added via `Command::subcommand`. Each
-instance of a Subcommand can have its own version, author(s), Args, and even its own
-subcommands.
-
-[Example:](03_04_subcommands.rs)
-```console
-$ 03_04_subcommands help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_04_subcommands[EXE] <SUBCOMMAND>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-SUBCOMMANDS:
- add Adds files to myapp
- help Print this message or the help of the given subcommand(s)
-
-$ 03_04_subcommands help add
-03_04_subcommands[EXE]-add [..]
-Adds files to myapp
-
-USAGE:
- 03_04_subcommands[EXE] add [NAME]
-
-ARGS:
- <NAME>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 03_04_subcommands add bob
-'myapp add' was used, name is: Some("bob")
-
-```
-
-Because we set `Command::arg_required_else_help`:
-```console
-$ 03_04_subcommands
-? failed
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_04_subcommands[EXE] <SUBCOMMAND>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-SUBCOMMANDS:
- add Adds files to myapp
- help Print this message or the help of the given subcommand(s)
-
-```
-
-Because we set `Command::propagate_version`:
-```console
-$ 03_04_subcommands --version
-clap [..]
-
-$ 03_04_subcommands add --version
-03_04_subcommands[EXE]-add [..]
-
-```
-
-### Defaults
-
-We've previously showed that arguments can be `required` or optional. When
-optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can
-set `Arg::default_value`.
-
-[Example:](03_05_default_values.rs)
-```console
-$ 03_05_default_values --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_05_default_values[EXE] [NAME]
-
-ARGS:
- <NAME> [default: alice]
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 03_05_default_values
-NAME: "alice"
-
-$ 03_05_default_values bob
-NAME: "bob"
-
-```
-
-## Validation
-
-### Enumerated values
-
-If you have arguments of specific values you want to test for, you can use the
-`PossibleValuesParser` or `Arg::value_parser(["val1", ...])` for short.
-
-This allows you specify the valid values for that argument. If the user does not use one of
-those specific values, they will receive a graceful exit with error message informing them
-of the mistake, and what the possible valid values are
-
-[Example:](04_01_possible.rs)
-```console
-$ 04_01_possible --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_01_possible[EXE] <MODE>
-
-ARGS:
- <MODE> What mode to run the program in [possible values: fast, slow]
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_01_possible fast
-Hare
-
-$ 04_01_possible slow
-Tortoise
-
-$ 04_01_possible medium
-? failed
-error: "medium" isn't a valid value for '<MODE>'
- [possible values: fast, slow]
-
-For more information try --help
-
-```
-
-When enabling the `derive` feature, you can use `ValueEnum` to take care of the boiler plate for you, giving the same results.
-
-[Example:](04_01_enum.rs)
-```console
-$ 04_01_enum --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_01_enum[EXE] <MODE>
-
-ARGS:
- <MODE> What mode to run the program in [possible values: fast, slow]
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_01_enum fast
-Hare
-
-$ 04_01_enum slow
-Tortoise
-
-$ 04_01_enum medium
-? failed
-error: "medium" isn't a valid value for '<MODE>'
- [possible values: fast, slow]
-
-For more information try --help
-
-```
-
-### Validated values
-
-More generally, you can validate and parse into any data type.
-
-[Example:](04_02_parse.rs)
-```console
-$ 04_02_parse --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_02_parse[EXE] <PORT>
-
-ARGS:
- <PORT> Network port to use
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_02_parse 22
-PORT = 22
-
-$ 04_02_parse foobar
-? failed
-error: Invalid value "foobar" for '<PORT>': invalid digit found in string
-
-For more information try --help
-
-$ 04_02_parse_derive 0
-? failed
-error: Invalid value "0" for '<PORT>': 0 is not in 1..=65535
-
-For more information try --help
-
-```
-
-A custom parser can be used to improve the error messages or provide additional validation:
-
-[Example:](04_02_validate.rs)
-```console
-$ 04_02_validate --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_02_validate[EXE] <PORT>
-
-ARGS:
- <PORT> Network port to use
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_02_validate 22
-PORT = 22
-
-$ 04_02_validate foobar
-? failed
-error: Invalid value "foobar" for '<PORT>': `foobar` isn't a port number
-
-For more information try --help
-
-$ 04_02_validate 0
-? failed
-error: Invalid value "0" for '<PORT>': Port not in range 1-65535
-
-For more information try --help
-
-```
-
-### Argument Relations
-
-You can declare dependencies or conflicts between `Arg`s or even `ArgGroup`s.
-
-`ArgGroup`s make it easier to declare relations instead of having to list each
-individually, or when you want a rule to apply "any but not all" arguments.
-
-Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be
-present out of a given set. Imagine that you had multiple arguments, and you want one of them to
-be required, but making all of them required isn't feasible because perhaps they conflict with
-each other.
-
-[Example:](04_03_relations.rs)
-```console
-$ 04_03_relations --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_03_relations[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
-
-ARGS:
- <INPUT_FILE> some regular input
-
-OPTIONS:
- -c <CONFIG>
- -h, --help Print help information
- --major auto inc major
- --minor auto inc minor
- --patch auto inc patch
- --set-ver <VER> set version manually
- --spec-in <SPEC_IN> some special input argument
- -V, --version Print version information
-
-$ 04_03_relations
-? failed
-error: The following required arguments were not provided:
- <--set-ver <VER>|--major|--minor|--patch>
-
-USAGE:
- 04_03_relations[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
-
-For more information try --help
-
-$ 04_03_relations --major
-Version: 2.2.3
-
-$ 04_03_relations --major --minor
-? failed
-error: The argument '--major' cannot be used with '--minor'
-
-USAGE:
- 04_03_relations[EXE] <--set-ver <VER>|--major|--minor|--patch>
-
-For more information try --help
-
-$ 04_03_relations --major -c config.toml
-? failed
-error: The following required arguments were not provided:
- <INPUT_FILE|--spec-in <SPEC_IN>>
-
-USAGE:
- 04_03_relations[EXE] -c <CONFIG> <--set-ver <VER>|--major|--minor|--patch> <INPUT_FILE|--spec-in <SPEC_IN>>
-
-For more information try --help
-
-$ 04_03_relations --major -c config.toml --spec-in input.txt
-Version: 2.2.3
-Doing work using input input.txt and config config.toml
-
-```
-
-### Custom Validation
-
-As a last resort, you can create custom errors with the basics of clap's formatting.
-
-[Example:](04_04_custom.rs)
-```console
-$ 04_04_custom --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
-
-ARGS:
- <INPUT_FILE> some regular input
-
-OPTIONS:
- -c <CONFIG>
- -h, --help Print help information
- --major auto inc major
- --minor auto inc minor
- --patch auto inc patch
- --set-ver <VER> set version manually
- --spec-in <SPEC_IN> some special input argument
- -V, --version Print version information
-
-$ 04_04_custom
-? failed
-error: Can only modify one version field
-
-USAGE:
- 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
-
-For more information try --help
-
-$ 04_04_custom --major
-Version: 2.2.3
-
-$ 04_04_custom --major --minor
-? failed
-error: Can only modify one version field
-
-USAGE:
- 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
-
-For more information try --help
-
-$ 04_04_custom --major -c config.toml
-? failed
-Version: 2.2.3
-error: INPUT_FILE or --spec-in is required when using --config
-
-USAGE:
- 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
-
-For more information try --help
-
-$ 04_04_custom --major -c config.toml --spec-in input.txt
-Version: 2.2.3
-Doing work using input input.txt and config config.toml
-
-```
-
-## Tips
-
-- For more complex demonstration of features, see our [examples](../README.md).
-- Proactively check for bad `Command` configurations by calling `Command::debug_assert` in a test ([example](05_01_assert.rs))
-
-## Contributing
-
-New example code:
-- Please update the corresponding section in the [derive tutorial](../tutorial_derive/README.md)
-- Building: They must be added to [Cargo.toml](../../Cargo.toml) with the appropriate `required-features`.
-- Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax (generally they'll go in here).
-
-See also the general [CONTRIBUTING](../../CONTRIBUTING.md).
diff --git a/vendor/clap/examples/tutorial_derive/01_quick.md b/vendor/clap/examples/tutorial_derive/01_quick.md
new file mode 100644
index 000000000..6f70d2cce
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/01_quick.md
@@ -0,0 +1,37 @@
+```console
+$ 01_quick_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 01_quick_derive[EXE] [OPTIONS] [NAME] [SUBCOMMAND]
+
+ARGS:
+ <NAME> Optional name to operate on
+
+OPTIONS:
+ -c, --config <FILE> Sets a custom config file
+ -d, --debug Turn debugging information on
+ -h, --help Print help information
+ -V, --version Print version information
+
+SUBCOMMANDS:
+ help Print this message or the help of the given subcommand(s)
+ test does testing things
+
+```
+
+By default, the program does nothing:
+```console
+$ 01_quick_derive
+Debug mode is off
+
+```
+
+But you can mix and match the various features
+```console
+$ 01_quick_derive -dd test
+Debug mode is on
+Not printing testing lists...
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/02_app_settings.md b/vendor/clap/examples/tutorial_derive/02_app_settings.md
new file mode 100644
index 000000000..ee16c66df
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/02_app_settings.md
@@ -0,0 +1,19 @@
+```console
+$ 02_app_settings_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 02_app_settings_derive[EXE] --two <TWO> --one <ONE>
+
+OPTIONS:
+ --two <TWO>
+ --one <ONE>
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 02_app_settings_derive --one -1 --one -3 --two 10
+two: "10"
+one: "-3"
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/02_apps.md b/vendor/clap/examples/tutorial_derive/02_apps.md
new file mode 100644
index 000000000..0141581c4
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/02_apps.md
@@ -0,0 +1,19 @@
+```console
+$ 02_apps_derive --help
+MyApp 1.0
+Kevin K. <kbknapp@gmail.com>
+Does awesome things
+
+USAGE:
+ 02_apps_derive[EXE] --two <TWO> --one <ONE>
+
+OPTIONS:
+ -h, --help Print help information
+ --one <ONE>
+ --two <TWO>
+ -V, --version Print version information
+
+$ 02_apps_derive --version
+MyApp 1.0
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/02_crate.md b/vendor/clap/examples/tutorial_derive/02_crate.md
new file mode 100644
index 000000000..92c820758
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/02_crate.md
@@ -0,0 +1,18 @@
+```console
+$ 02_crate_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 02_crate_derive[EXE] --two <TWO> --one <ONE>
+
+OPTIONS:
+ -h, --help Print help information
+ --one <ONE>
+ --two <TWO>
+ -V, --version Print version information
+
+$ 02_crate_derive --version
+clap [..]
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/02_crate.rs b/vendor/clap/examples/tutorial_derive/02_crate.rs
index df16468d0..5576f998c 100644
--- a/vendor/clap/examples/tutorial_derive/02_crate.rs
+++ b/vendor/clap/examples/tutorial_derive/02_crate.rs
@@ -1,7 +1,7 @@
use clap::Parser;
#[derive(Parser)]
-#[clap(author, version, about, long_about = None)]
+#[clap(author, version, about, long_about = None)] // Read from `Cargo.toml`
struct Cli {
#[clap(long, value_parser)]
two: String,
diff --git a/vendor/clap/examples/tutorial_derive/03_01_flag_bool.md b/vendor/clap/examples/tutorial_derive/03_01_flag_bool.md
new file mode 100644
index 000000000..0baaa10ca
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/03_01_flag_bool.md
@@ -0,0 +1,23 @@
+```console
+$ 03_01_flag_bool_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_01_flag_bool_derive[EXE] [OPTIONS]
+
+OPTIONS:
+ -h, --help Print help information
+ -v, --verbose
+ -V, --version Print version information
+
+$ 03_01_flag_bool_derive
+verbose: false
+
+$ 03_01_flag_bool_derive --verbose
+verbose: true
+
+$ 03_01_flag_bool_derive --verbose --verbose
+verbose: true
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/03_01_flag_count.md b/vendor/clap/examples/tutorial_derive/03_01_flag_count.md
new file mode 100644
index 000000000..3d5a53084
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/03_01_flag_count.md
@@ -0,0 +1,23 @@
+```console
+$ 03_01_flag_count_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_01_flag_count_derive[EXE] [OPTIONS]
+
+OPTIONS:
+ -h, --help Print help information
+ -v, --verbose
+ -V, --version Print version information
+
+$ 03_01_flag_count_derive
+verbose: 0
+
+$ 03_01_flag_count_derive --verbose
+verbose: 1
+
+$ 03_01_flag_count_derive --verbose --verbose
+verbose: 2
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/03_02_option.md b/vendor/clap/examples/tutorial_derive/03_02_option.md
new file mode 100644
index 000000000..84ff7fa74
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/03_02_option.md
@@ -0,0 +1,32 @@
+```console
+$ 03_02_option_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_02_option_derive[EXE] [OPTIONS]
+
+OPTIONS:
+ -h, --help Print help information
+ -n, --name <NAME>
+ -V, --version Print version information
+
+$ 03_02_option_derive
+name: None
+
+$ 03_02_option_derive --name bob
+name: Some("bob")
+
+$ 03_02_option_derive --name=bob
+name: Some("bob")
+
+$ 03_02_option_derive -n bob
+name: Some("bob")
+
+$ 03_02_option_derive -n=bob
+name: Some("bob")
+
+$ 03_02_option_derive -nbob
+name: Some("bob")
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/03_03_positional.md b/vendor/clap/examples/tutorial_derive/03_03_positional.md
new file mode 100644
index 000000000..7281fe3ff
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/03_03_positional.md
@@ -0,0 +1,22 @@
+```console
+$ 03_03_positional_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_03_positional_derive[EXE] [NAME]
+
+ARGS:
+ <NAME>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 03_03_positional_derive
+name: None
+
+$ 03_03_positional_derive bob
+name: Some("bob")
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/03_04_subcommands.md b/vendor/clap/examples/tutorial_derive/03_04_subcommands.md
new file mode 100644
index 000000000..02f96e3d3
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/03_04_subcommands.md
@@ -0,0 +1,64 @@
+```console
+$ 03_04_subcommands_derive help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_04_subcommands_derive[EXE] <SUBCOMMAND>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+SUBCOMMANDS:
+ add Adds files to myapp
+ help Print this message or the help of the given subcommand(s)
+
+$ 03_04_subcommands_derive help add
+03_04_subcommands_derive[EXE]-add [..]
+Adds files to myapp
+
+USAGE:
+ 03_04_subcommands_derive[EXE] add [NAME]
+
+ARGS:
+ <NAME>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 03_04_subcommands_derive add bob
+'myapp add' was used, name is: Some("bob")
+
+```
+
+Because we used `command: Commands` instead of `command: Option<Commands>`:
+```console
+$ 03_04_subcommands_derive
+? failed
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_04_subcommands_derive[EXE] <SUBCOMMAND>
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+SUBCOMMANDS:
+ add Adds files to myapp
+ help Print this message or the help of the given subcommand(s)
+
+```
+
+Because we added `#[clap(propagate_version = true)]`:
+```console
+$ 03_04_subcommands_derive --version
+clap [..]
+
+$ 03_04_subcommands_derive add --version
+03_04_subcommands_derive[EXE]-add [..]
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/03_05_default_values.md b/vendor/clap/examples/tutorial_derive/03_05_default_values.md
new file mode 100644
index 000000000..f7315e736
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/03_05_default_values.md
@@ -0,0 +1,22 @@
+```console
+$ 03_05_default_values_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 03_05_default_values_derive[EXE] [NAME]
+
+ARGS:
+ <NAME> [default: alice]
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 03_05_default_values_derive
+name: "alice"
+
+$ 03_05_default_values_derive bob
+name: "bob"
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/04_01_enum.md b/vendor/clap/examples/tutorial_derive/04_01_enum.md
new file mode 100644
index 000000000..2523af924
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/04_01_enum.md
@@ -0,0 +1,29 @@
+```console
+$ 04_01_enum_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_01_enum_derive[EXE] <MODE>
+
+ARGS:
+ <MODE> What mode to run the program in [possible values: fast, slow]
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_01_enum_derive fast
+Hare
+
+$ 04_01_enum_derive slow
+Tortoise
+
+$ 04_01_enum_derive medium
+? failed
+error: "medium" isn't a valid value for '<MODE>'
+ [possible values: fast, slow]
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/04_01_enum.rs b/vendor/clap/examples/tutorial_derive/04_01_enum.rs
index 84b4cace4..1ac984288 100644
--- a/vendor/clap/examples/tutorial_derive/04_01_enum.rs
+++ b/vendor/clap/examples/tutorial_derive/04_01_enum.rs
@@ -1,4 +1,4 @@
-use clap::{ArgEnum, Parser};
+use clap::{Parser, ValueEnum};
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
@@ -8,7 +8,7 @@ struct Cli {
mode: Mode,
}
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum Mode {
Fast,
Slow,
diff --git a/vendor/clap/examples/tutorial_derive/04_02_parse.md b/vendor/clap/examples/tutorial_derive/04_02_parse.md
new file mode 100644
index 000000000..6079ef193
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/04_02_parse.md
@@ -0,0 +1,31 @@
+```console
+$ 04_02_parse_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_02_parse_derive[EXE] <PORT>
+
+ARGS:
+ <PORT> Network port to use
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_02_parse_derive 22
+PORT = 22
+
+$ 04_02_parse_derive foobar
+? failed
+error: Invalid value "foobar" for '<PORT>': invalid digit found in string
+
+For more information try --help
+
+$ 04_02_parse_derive 0
+? failed
+error: Invalid value "0" for '<PORT>': 0 is not in 1..=65535
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/04_02_validate.md b/vendor/clap/examples/tutorial_derive/04_02_validate.md
new file mode 100644
index 000000000..cc43440ef
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/04_02_validate.md
@@ -0,0 +1,31 @@
+```console
+$ 04_02_validate_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_02_validate_derive[EXE] <PORT>
+
+ARGS:
+ <PORT> Network port to use
+
+OPTIONS:
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ 04_02_validate_derive 22
+PORT = 22
+
+$ 04_02_validate_derive foobar
+? failed
+error: Invalid value "foobar" for '<PORT>': `foobar` isn't a port number
+
+For more information try --help
+
+$ 04_02_validate_derive 0
+? failed
+error: Invalid value "0" for '<PORT>': Port not in range 1-65535
+
+For more information try --help
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/04_03_relations.md b/vendor/clap/examples/tutorial_derive/04_03_relations.md
new file mode 100644
index 000000000..4f5703d82
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/04_03_relations.md
@@ -0,0 +1,58 @@
+```console
+$ 04_03_relations_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_03_relations_derive[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
+
+ARGS:
+ <INPUT_FILE> some regular input
+
+OPTIONS:
+ -c <CONFIG>
+ -h, --help Print help information
+ --major auto inc major
+ --minor auto inc minor
+ --patch auto inc patch
+ --set-ver <VER> set version manually
+ --spec-in <SPEC_IN> some special input argument
+ -V, --version Print version information
+
+$ 04_03_relations_derive
+? failed
+error: The following required arguments were not provided:
+ <--set-ver <VER>|--major|--minor|--patch>
+
+USAGE:
+ 04_03_relations_derive[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
+
+For more information try --help
+
+$ 04_03_relations_derive --major
+Version: 2.2.3
+
+$ 04_03_relations_derive --major --minor
+? failed
+error: The argument '--major' cannot be used with '--minor'
+
+USAGE:
+ 04_03_relations_derive[EXE] <--set-ver <VER>|--major|--minor|--patch>
+
+For more information try --help
+
+$ 04_03_relations_derive --major -c config.toml
+? failed
+error: The following required arguments were not provided:
+ <INPUT_FILE|--spec-in <SPEC_IN>>
+
+USAGE:
+ 04_03_relations_derive[EXE] -c <CONFIG> <--set-ver <VER>|--major|--minor|--patch> <INPUT_FILE|--spec-in <SPEC_IN>>
+
+For more information try --help
+
+$ 04_03_relations_derive --major -c config.toml --spec-in input.txt
+Version: 2.2.3
+Doing work using input input.txt and config config.toml
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/04_03_relations.rs b/vendor/clap/examples/tutorial_derive/04_03_relations.rs
index f8523902d..37efe95e3 100644
--- a/vendor/clap/examples/tutorial_derive/04_03_relations.rs
+++ b/vendor/clap/examples/tutorial_derive/04_03_relations.rs
@@ -44,7 +44,7 @@ fn main() {
let mut minor = 2;
let mut patch = 3;
- // See if --set-ver was used to set the version manually
+ // See if --set_ver was used to set the version manually
let version = if let Some(ver) = cli.set_ver.as_deref() {
ver.to_string()
} else {
diff --git a/vendor/clap/examples/tutorial_derive/04_04_custom.md b/vendor/clap/examples/tutorial_derive/04_04_custom.md
new file mode 100644
index 000000000..0f19bfe31
--- /dev/null
+++ b/vendor/clap/examples/tutorial_derive/04_04_custom.md
@@ -0,0 +1,57 @@
+```console
+$ 04_04_custom_derive --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ 04_04_custom_derive[EXE] [OPTIONS] [INPUT_FILE]
+
+ARGS:
+ <INPUT_FILE> some regular input
+
+OPTIONS:
+ -c <CONFIG>
+ -h, --help Print help information
+ --major auto inc major
+ --minor auto inc minor
+ --patch auto inc patch
+ --set-ver <VER> set version manually
+ --spec-in <SPEC_IN> some special input argument
+ -V, --version Print version information
+
+$ 04_04_custom_derive
+? failed
+error: Can only modify one version field
+
+USAGE:
+ clap [OPTIONS] [INPUT_FILE]
+
+For more information try --help
+
+$ 04_04_custom_derive --major
+Version: 2.2.3
+
+$ 04_04_custom_derive --major --minor
+? failed
+error: Can only modify one version field
+
+USAGE:
+ clap [OPTIONS] [INPUT_FILE]
+
+For more information try --help
+
+$ 04_04_custom_derive --major -c config.toml
+? failed
+Version: 2.2.3
+error: INPUT_FILE or --spec-in is required when using --config
+
+USAGE:
+ clap [OPTIONS] [INPUT_FILE]
+
+For more information try --help
+
+$ 04_04_custom_derive --major -c config.toml --spec-in input.txt
+Version: 2.2.3
+Doing work using input input.txt and config config.toml
+
+```
diff --git a/vendor/clap/examples/tutorial_derive/05_01_assert.rs b/vendor/clap/examples/tutorial_derive/05_01_assert.rs
index f5fa3f6c5..66dca727f 100644
--- a/vendor/clap/examples/tutorial_derive/05_01_assert.rs
+++ b/vendor/clap/examples/tutorial_derive/05_01_assert.rs
@@ -15,7 +15,7 @@ fn main() {
}
#[test]
-fn verify_app() {
+fn verify_cli() {
use clap::CommandFactory;
Cli::command().debug_assert()
}
diff --git a/vendor/clap/examples/tutorial_derive/README.md b/vendor/clap/examples/tutorial_derive/README.md
deleted file mode 100644
index 6127b6cd3..000000000
--- a/vendor/clap/examples/tutorial_derive/README.md
+++ /dev/null
@@ -1,639 +0,0 @@
-# Tutorial
-
-*Jump to [builder tutorial](../tutorial_builder/README.md)*
-
-1. [Quick Start](#quick-start)
-2. [Configuring the Parser](#configuring-the-parser)
-3. [Adding Arguments](#adding-arguments)
- 1. [Positionals](#positionals)
- 2. [Options](#options)
- 3. [Flags](#flags)
- 4. [Subcommands](#subcommands)
- 5. [Defaults](#defaults)
-4. Validation
- 1. [Enumerated values](#enumerated-values)
- 2. [Validated values](#validated-values)
- 3. [Argument Relations](#argument-relations)
- 4. [Custom Validation](#custom-validation)
-5. [Tips](#tips)
-6. [Contributing](#contributing)
-
-## Quick Start
-
-You can create an application declaratively with a `struct` and some
-attributes. **This requires enabling the `derive` feature flag.**
-
-[Example:](01_quick.rs)
-```console
-$ 01_quick_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 01_quick_derive[EXE] [OPTIONS] [NAME] [SUBCOMMAND]
-
-ARGS:
- <NAME> Optional name to operate on
-
-OPTIONS:
- -c, --config <FILE> Sets a custom config file
- -d, --debug Turn debugging information on
- -h, --help Print help information
- -V, --version Print version information
-
-SUBCOMMANDS:
- help Print this message or the help of the given subcommand(s)
- test does testing things
-
-```
-
-By default, the program does nothing:
-```console
-$ 01_quick_derive
-Debug mode is off
-
-```
-
-But you can mix and match the various features
-```console
-$ 01_quick_derive -dd test
-Debug mode is on
-Not printing testing lists...
-
-```
-
-In addition to this tutorial, see the [derive reference](../derive_ref/README.md).
-
-## Configuring the Parser
-
-You use derive `Parser` the start building a parser.
-
-[Example:](02_apps.rs)
-```console
-$ 02_apps_derive --help
-MyApp 1.0
-Kevin K. <kbknapp@gmail.com>
-Does awesome things
-
-USAGE:
- 02_apps_derive[EXE] --two <TWO> --one <ONE>
-
-OPTIONS:
- -h, --help Print help information
- --one <ONE>
- --two <TWO>
- -V, --version Print version information
-
-$ 02_apps_derive --version
-MyApp 1.0
-
-```
-
-You can use `#[clap(author, version, about)]` attribute defaults to fill these fields in from your `Cargo.toml` file.
-
-[Example:](02_crate.rs)
-```console
-$ 02_crate_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 02_crate_derive[EXE] --two <TWO> --one <ONE>
-
-OPTIONS:
- -h, --help Print help information
- --one <ONE>
- --two <TWO>
- -V, --version Print version information
-
-$ 02_crate_derive --version
-clap [..]
-
-```
-
-You can use attributes to change the application level behavior of clap. Any `Command` builder function can be used as an attribute.
-
-[Example:](02_app_settings.rs)
-```console
-$ 02_app_settings_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 02_app_settings_derive[EXE] --two <TWO> --one <ONE>
-
-OPTIONS:
- --two <TWO>
- --one <ONE>
- -h, --help Print help information
- -V, --version Print version information
-
-$ 02_app_settings_derive --one -1 --one -3 --two 10
-two: "10"
-one: "-3"
-
-```
-
-## Adding Arguments
-
-### Positionals
-
-You can have users specify values by their position on the command-line:
-
-[Example:](03_03_positional.rs)
-```console
-$ 03_03_positional_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_03_positional_derive[EXE] [NAME]
-
-ARGS:
- <NAME>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 03_03_positional_derive
-name: None
-
-$ 03_03_positional_derive bob
-name: Some("bob")
-
-```
-
-### Options
-
-You can name your arguments with a flag:
-- Order doesn't matter
-- They can be optional
-- Intent is clearer
-
-The `#[clap(short = 'c')]` and `#[clap(long = "name")]` attributes that define
-the flags are `Arg` methods that are derived from the field name when no value
-is specified (`#[clap(short)]` and `#[clap(long)]`).
-
-[Example:](03_02_option.rs)
-```console
-$ 03_02_option_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_02_option_derive[EXE] [OPTIONS]
-
-OPTIONS:
- -h, --help Print help information
- -n, --name <NAME>
- -V, --version Print version information
-
-$ 03_02_option_derive
-name: None
-
-$ 03_02_option_derive --name bob
-name: Some("bob")
-
-$ 03_02_option_derive --name=bob
-name: Some("bob")
-
-$ 03_02_option_derive -n bob
-name: Some("bob")
-
-$ 03_02_option_derive -n=bob
-name: Some("bob")
-
-$ 03_02_option_derive -nbob
-name: Some("bob")
-
-```
-
-### Flags
-
-Flags can also be switches that can be on/off. This is enabled via the
-`#[clap(parse(from_flag)]` attribute though this is implied when the field is a
-`bool`.
-
-[Example:](03_01_flag_bool.rs)
-```console
-$ 03_01_flag_bool_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_01_flag_bool_derive[EXE] [OPTIONS]
-
-OPTIONS:
- -h, --help Print help information
- -v, --verbose
- -V, --version Print version information
-
-$ 03_01_flag_bool_derive
-verbose: false
-
-$ 03_01_flag_bool_derive --verbose
-verbose: true
-
-$ 03_01_flag_bool_derive --verbose --verbose
-verbose: true
-
-```
-
-Or counted with `#[clap(action = clap::ArgAction::Count)]`:
-
-[Example:](03_01_flag_count.rs)
-```console
-$ 03_01_flag_count_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_01_flag_count_derive[EXE] [OPTIONS]
-
-OPTIONS:
- -h, --help Print help information
- -v, --verbose
- -V, --version Print version information
-
-$ 03_01_flag_count_derive
-verbose: 0
-
-$ 03_01_flag_count_derive --verbose
-verbose: 1
-
-$ 03_01_flag_count_derive --verbose --verbose
-verbose: 2
-
-```
-
-### Subcommands
-
-Subcommands are derived with `#[derive(Subcommand)]` and be added via `#[clap(subcommand)]` attribute. Each
-instance of a Subcommand can have its own version, author(s), Args, and even its own
-subcommands.
-
-[Example:](03_04_subcommands.rs)
-```console
-$ 03_04_subcommands_derive help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_04_subcommands_derive[EXE] <SUBCOMMAND>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-SUBCOMMANDS:
- add Adds files to myapp
- help Print this message or the help of the given subcommand(s)
-
-$ 03_04_subcommands_derive help add
-03_04_subcommands_derive[EXE]-add [..]
-Adds files to myapp
-
-USAGE:
- 03_04_subcommands_derive[EXE] add [NAME]
-
-ARGS:
- <NAME>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 03_04_subcommands_derive add bob
-'myapp add' was used, name is: Some("bob")
-
-```
-
-Above, we used a struct-variant to define the `add` subcommand. Alternatively,
-you can
-[use a struct for your subcommand's arguments](03_04_subcommands_alt.rs).
-
-Because we used `command: Commands` instead of `command: Option<Commands>`:
-```console
-$ 03_04_subcommands_derive
-? failed
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_04_subcommands_derive[EXE] <SUBCOMMAND>
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-SUBCOMMANDS:
- add Adds files to myapp
- help Print this message or the help of the given subcommand(s)
-
-```
-
-Because we added `#[clap(propagate_version = true)]`:
-```console
-$ 03_04_subcommands_derive --version
-clap [..]
-
-$ 03_04_subcommands_derive add --version
-03_04_subcommands_derive[EXE]-add [..]
-
-```
-
-### Defaults
-
-We've previously showed that arguments can be `required` or optional. When
-optional, you work with an `Option` and can `unwrap_or`. Alternatively, you can
-set `#[clap(default_value_t)]`.
-
-[Example:](03_05_default_values.rs)
-```console
-$ 03_05_default_values_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 03_05_default_values_derive[EXE] [NAME]
-
-ARGS:
- <NAME> [default: alice]
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 03_05_default_values_derive
-name: "alice"
-
-$ 03_05_default_values_derive bob
-name: "bob"
-
-```
-
-## Validation
-
-### Enumerated values
-
-If you have arguments of specific values you want to test for, you can derive
-`ValueEnum`.
-
-This allows you specify the valid values for that argument. If the user does not use one of
-those specific values, they will receive a graceful exit with error message informing them
-of the mistake, and what the possible valid values are
-
-[Example:](04_01_enum.rs)
-```console
-$ 04_01_enum_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_01_enum_derive[EXE] <MODE>
-
-ARGS:
- <MODE> What mode to run the program in [possible values: fast, slow]
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_01_enum_derive fast
-Hare
-
-$ 04_01_enum_derive slow
-Tortoise
-
-$ 04_01_enum_derive medium
-? failed
-error: "medium" isn't a valid value for '<MODE>'
- [possible values: fast, slow]
-
-For more information try --help
-
-```
-
-### Validated values
-
-More generally, you can validate and parse into any data type.
-
-[Example:](04_02_parse.rs)
-```console
-$ 04_02_parse_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_02_parse_derive[EXE] <PORT>
-
-ARGS:
- <PORT> Network port to use
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_02_parse_derive 22
-PORT = 22
-
-$ 04_02_parse_derive foobar
-? failed
-error: Invalid value "foobar" for '<PORT>': invalid digit found in string
-
-For more information try --help
-
-$ 04_02_parse_derive 0
-? failed
-error: Invalid value "0" for '<PORT>': 0 is not in 1..=65535
-
-For more information try --help
-
-```
-
-A custom parser can be used to improve the error messages or provide additional validation:
-
-[Example:](04_02_validate.rs)
-```console
-$ 04_02_validate_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_02_validate_derive[EXE] <PORT>
-
-ARGS:
- <PORT> Network port to use
-
-OPTIONS:
- -h, --help Print help information
- -V, --version Print version information
-
-$ 04_02_validate_derive 22
-PORT = 22
-
-$ 04_02_validate_derive foobar
-? failed
-error: Invalid value "foobar" for '<PORT>': `foobar` isn't a port number
-
-For more information try --help
-
-$ 04_02_validate_derive 0
-? failed
-error: Invalid value "0" for '<PORT>': Port not in range 1-65535
-
-For more information try --help
-
-```
-
-### Argument Relations
-
-You can declare dependencies or conflicts between `Arg`s or even `ArgGroup`s.
-
-`ArgGroup`s make it easier to declare relations instead of having to list each
-individually, or when you want a rule to apply "any but not all" arguments.
-
-Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be
-present out of a given set. Imagine that you had multiple arguments, and you want one of them to
-be required, but making all of them required isn't feasible because perhaps they conflict with
-each other.
-
-[Example:](04_03_relations.rs)
-```console
-$ 04_03_relations_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_03_relations_derive[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
-
-ARGS:
- <INPUT_FILE> some regular input
-
-OPTIONS:
- -c <CONFIG>
- -h, --help Print help information
- --major auto inc major
- --minor auto inc minor
- --patch auto inc patch
- --set-ver <VER> set version manually
- --spec-in <SPEC_IN> some special input argument
- -V, --version Print version information
-
-$ 04_03_relations_derive
-? failed
-error: The following required arguments were not provided:
- <--set-ver <VER>|--major|--minor|--patch>
-
-USAGE:
- 04_03_relations_derive[EXE] [OPTIONS] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
-
-For more information try --help
-
-$ 04_03_relations_derive --major
-Version: 2.2.3
-
-$ 04_03_relations_derive --major --minor
-? failed
-error: The argument '--major' cannot be used with '--minor'
-
-USAGE:
- 04_03_relations_derive[EXE] <--set-ver <VER>|--major|--minor|--patch>
-
-For more information try --help
-
-$ 04_03_relations_derive --major -c config.toml
-? failed
-error: The following required arguments were not provided:
- <INPUT_FILE|--spec-in <SPEC_IN>>
-
-USAGE:
- 04_03_relations_derive[EXE] -c <CONFIG> <--set-ver <VER>|--major|--minor|--patch> <INPUT_FILE|--spec-in <SPEC_IN>>
-
-For more information try --help
-
-$ 04_03_relations_derive --major -c config.toml --spec-in input.txt
-Version: 2.2.3
-Doing work using input input.txt and config config.toml
-
-```
-
-### Custom Validation
-
-As a last resort, you can create custom errors with the basics of clap's formatting.
-
-[Example:](04_04_custom.rs)
-```console
-$ 04_04_custom_derive --help
-clap [..]
-A simple to use, efficient, and full-featured Command Line Argument Parser
-
-USAGE:
- 04_04_custom_derive[EXE] [OPTIONS] [INPUT_FILE]
-
-ARGS:
- <INPUT_FILE> some regular input
-
-OPTIONS:
- -c <CONFIG>
- -h, --help Print help information
- --major auto inc major
- --minor auto inc minor
- --patch auto inc patch
- --set-ver <VER> set version manually
- --spec-in <SPEC_IN> some special input argument
- -V, --version Print version information
-
-$ 04_04_custom_derive
-? failed
-error: Can only modify one version field
-
-USAGE:
- clap [OPTIONS] [INPUT_FILE]
-
-For more information try --help
-
-$ 04_04_custom_derive --major
-Version: 2.2.3
-
-$ 04_04_custom_derive --major --minor
-? failed
-error: Can only modify one version field
-
-USAGE:
- clap [OPTIONS] [INPUT_FILE]
-
-For more information try --help
-
-$ 04_04_custom_derive --major -c config.toml
-? failed
-Version: 2.2.3
-error: INPUT_FILE or --spec-in is required when using --config
-
-USAGE:
- clap [OPTIONS] [INPUT_FILE]
-
-For more information try --help
-
-$ 04_04_custom_derive --major -c config.toml --spec-in input.txt
-Version: 2.2.3
-Doing work using input input.txt and config config.toml
-
-```
-
-## Tips
-
-- For more complex demonstration of features, see our [examples](../README.md).
-- See the [derive reference](../derive_ref/README.md) to understand how to use
- anything in the [builder API](https://docs.rs/clap/) in the derive API.
-- Proactively check for bad `Command` configurations by calling `Command::debug_assert` in a test ([example](05_01_assert.rs))
-
-## Contributing
-
-New example code:
-- Please update the corresponding section in the [builder tutorial](../tutorial_builder/README.md)
-- Building: They must be added to [Cargo.toml](../../Cargo.toml) with the appropriate `required-features`.
-- Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax (generally they'll go in here).
-
-See also the general [CONTRIBUTING](../../CONTRIBUTING.md).
diff --git a/vendor/clap/examples/typed-derive.md b/vendor/clap/examples/typed-derive.md
index 7c61f70d9..9c7615c63 100644
--- a/vendor/clap/examples/typed-derive.md
+++ b/vendor/clap/examples/typed-derive.md
@@ -1,6 +1,4 @@
-*Jump to [source](typed-derive.rs)*
-
-**This requires enabling the `derive` feature flag.**
+**This requires enabling the [`derive` feature flag][crate::_features].**
Help:
```console
diff --git a/vendor/clap/examples/typed-derive.rs b/vendor/clap/examples/typed-derive.rs
index 85c750f9c..31084029d 100644
--- a/vendor/clap/examples/typed-derive.rs
+++ b/vendor/clap/examples/typed-derive.rs
@@ -1,9 +1,7 @@
-// Note: this requires the `derive` feature
-
use clap::Parser;
use std::error::Error;
-#[derive(Parser, Debug)]
+#[derive(Parser, Debug)] // requires `derive` feature
struct Args {
/// Implicitly using `std::str::FromStr`
#[clap(short = 'O', value_parser)]
diff --git a/vendor/clap/src/_cookbook/cargo_example.rs b/vendor/clap/src/_cookbook/cargo_example.rs
new file mode 100644
index 000000000..ec5d582db
--- /dev/null
+++ b/vendor/clap/src/_cookbook/cargo_example.rs
@@ -0,0 +1,7 @@
+//! # Example: cargo subcommand (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/cargo-example.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/cargo-example.md")]
diff --git a/vendor/clap/src/_cookbook/cargo_example_derive b/vendor/clap/src/_cookbook/cargo_example_derive
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/clap/src/_cookbook/cargo_example_derive
diff --git a/vendor/clap/src/_cookbook/cargo_example_derive.rs b/vendor/clap/src/_cookbook/cargo_example_derive.rs
new file mode 100644
index 000000000..d49f956f9
--- /dev/null
+++ b/vendor/clap/src/_cookbook/cargo_example_derive.rs
@@ -0,0 +1,7 @@
+//! # Example: cargo subcommand (Derive API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/cargo-example-derive.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/cargo-example-derive.md")]
diff --git a/vendor/clap/src/_cookbook/escaped_positional.rs b/vendor/clap/src/_cookbook/escaped_positional.rs
new file mode 100644
index 000000000..99a3f83f3
--- /dev/null
+++ b/vendor/clap/src/_cookbook/escaped_positional.rs
@@ -0,0 +1,7 @@
+//! # Example (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/escaped-positional.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/escaped-positional.md")]
diff --git a/vendor/clap/src/_cookbook/escaped_positional_derive.rs b/vendor/clap/src/_cookbook/escaped_positional_derive.rs
new file mode 100644
index 000000000..e6f99ad17
--- /dev/null
+++ b/vendor/clap/src/_cookbook/escaped_positional_derive.rs
@@ -0,0 +1,7 @@
+//! # Example (Derive API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/escaped-positional-derive.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/escaped-positional-derive.md")]
diff --git a/vendor/clap/src/_cookbook/git.rs b/vendor/clap/src/_cookbook/git.rs
new file mode 100644
index 000000000..03a926ca8
--- /dev/null
+++ b/vendor/clap/src/_cookbook/git.rs
@@ -0,0 +1,7 @@
+//! # Example: git-like CLI (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/git.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/git.md")]
diff --git a/vendor/clap/src/_cookbook/git_derive.rs b/vendor/clap/src/_cookbook/git_derive.rs
new file mode 100644
index 000000000..d3119736d
--- /dev/null
+++ b/vendor/clap/src/_cookbook/git_derive.rs
@@ -0,0 +1,7 @@
+//! # Example: git-like CLI (Derive API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/git-derive.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/git-derive.md")]
diff --git a/vendor/clap/src/_cookbook/mod.rs b/vendor/clap/src/_cookbook/mod.rs
new file mode 100644
index 000000000..1a78ed11b
--- /dev/null
+++ b/vendor/clap/src/_cookbook/mod.rs
@@ -0,0 +1,55 @@
+// Contributing
+//
+// New examples:
+// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`.
+// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax
+// - Link the `.md` file from here
+
+//! # Documentation: Cookbook
+//!
+//! Typed arguments: [derive][typed_derive]
+//! - Topics:
+//! - Custom `parse()`
+//!
+//! Custom cargo command: [builder][cargo_example], [derive][cargo_example_derive]
+//! - Topics:
+//! - Subcommands
+//! - Cargo plugins
+//!
+//! git-like interface: [builder][git], [derive][git_derive]
+//! - Topics:
+//! - Subcommands
+//! - External subcommands
+//! - Optional subcommands
+//! - Default subcommands
+//!
+//! pacman-like interface: [builder][pacman]
+//! - Topics:
+//! - Flag subcommands
+//! - Conflicting arguments
+//!
+//! Escaped positionals with `--`: [builder][escaped_positional], [derive][escaped_positional_derive]
+//!
+//! Multi-call
+//! - busybox: [builder][multicall_busybox]
+//! - Topics:
+//! - Subcommands
+//! - hostname: [builder][multicall_hostname]
+//! - Topics:
+//! - Subcommands
+//!
+//! repl: [builder][repl]
+//! - Topics:
+//! - Read-Eval-Print Loops / Custom command lines
+
+pub mod cargo_example;
+pub mod cargo_example_derive;
+pub mod escaped_positional;
+pub mod escaped_positional_derive;
+pub mod git;
+pub mod git_derive;
+pub mod multicall_busybox;
+pub mod multicall_hostname;
+pub mod pacman;
+pub mod repl;
+pub mod typed_derive;
diff --git a/vendor/clap/src/_cookbook/multicall_busybox.rs b/vendor/clap/src/_cookbook/multicall_busybox.rs
new file mode 100644
index 000000000..e3384d682
--- /dev/null
+++ b/vendor/clap/src/_cookbook/multicall_busybox.rs
@@ -0,0 +1,7 @@
+//! # Example: busybox-like CLI (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/multicall-busybox.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/multicall-busybox.md")]
diff --git a/vendor/clap/src/_cookbook/multicall_hostname.rs b/vendor/clap/src/_cookbook/multicall_hostname.rs
new file mode 100644
index 000000000..9777654dc
--- /dev/null
+++ b/vendor/clap/src/_cookbook/multicall_hostname.rs
@@ -0,0 +1,7 @@
+//! # Example: hostname-like CLI (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/multicall-hostname.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/multicall-hostname.md")]
diff --git a/vendor/clap/src/_cookbook/pacman.rs b/vendor/clap/src/_cookbook/pacman.rs
new file mode 100644
index 000000000..880c58158
--- /dev/null
+++ b/vendor/clap/src/_cookbook/pacman.rs
@@ -0,0 +1,7 @@
+//! # Example: pacman-like CLI (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/pacman.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/pacman.md")]
diff --git a/vendor/clap/src/_cookbook/repl.rs b/vendor/clap/src/_cookbook/repl.rs
new file mode 100644
index 000000000..549ec8259
--- /dev/null
+++ b/vendor/clap/src/_cookbook/repl.rs
@@ -0,0 +1,5 @@
+//! # Example: Command REPL (Builder API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/repl.rs")]
+//! ```
diff --git a/vendor/clap/src/_cookbook/typed_derive.rs b/vendor/clap/src/_cookbook/typed_derive.rs
new file mode 100644
index 000000000..a5fd15ff8
--- /dev/null
+++ b/vendor/clap/src/_cookbook/typed_derive.rs
@@ -0,0 +1,7 @@
+//! # Example: Custom Types (Derive API)
+//!
+//! ```rust
+#![doc = include_str!("../../examples/typed-derive.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/typed-derive.md")]
diff --git a/vendor/clap/src/_derive/_tutorial.rs b/vendor/clap/src/_derive/_tutorial.rs
new file mode 100644
index 000000000..abd57cef8
--- /dev/null
+++ b/vendor/clap/src/_derive/_tutorial.rs
@@ -0,0 +1,205 @@
+// Contributing
+//
+// New example code:
+// - Please update the corresponding section in the derive tutorial
+// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`.
+// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax
+//
+// See also the general CONTRIBUTING
+
+//! # Documentation: Derive Tutorial
+//!
+//! 1. [Quick Start](#quick-start)
+//! 2. [Configuring the Parser](#configuring-the-parser)
+//! 3. [Adding Arguments](#adding-arguments)
+//! 1. [Positionals](#positionals)
+//! 2. [Options](#options)
+//! 3. [Flags](#flags)
+//! 4. [Subcommands](#subcommands)
+//! 5. [Defaults](#defaults)
+//! 4. Validation
+//! 1. [Enumerated values](#enumerated-values)
+//! 2. [Validated values](#validated-values)
+//! 3. [Argument Relations](#argument-relations)
+//! 4. [Custom Validation](#custom-validation)
+//! 5. [Testing](#testing)
+//!
+//! See also
+//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis]
+//! - The [cookbook][crate::_cookbook] for more application-focused examples
+//!
+//! ## Quick Start
+//!
+//! You can create an application declaratively with a `struct` and some
+//! attributes. **This requires enabling the [`derive` feature flag][crate::_features].**
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/01_quick.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/tutorial_derive/01_quick.md")]
+//!
+//! ## Configuring the Parser
+//!
+//! You use derive [`Parser`][crate::Parser] to start building a parser.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/02_apps.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/tutorial_derive/02_apps.md")]
+//!
+//! You can use `#[clap(author, version, about)]` attribute defaults to fill these fields in from your `Cargo.toml` file.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/02_crate.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/02_crate.md")]
+//!
+//! You can use attributes to change the application level behavior of clap. Any [`Command`][crate::Command]] builder function can be used as an attribute.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.md")]
+//!
+//! ## Adding Arguments
+//!
+//! ### Positionals
+//!
+//! You can have users specify values by their position on the command-line:
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.md")]
+//!
+//! ### Options
+//!
+//! You can name your arguments with a flag:
+//! - Order doesn't matter
+//! - They can be optional
+//! - Intent is clearer
+//!
+//! The `#[clap(short = 'n')]` and `#[clap(long = "name")]` attributes that define
+//! the flags are [`Arg`][crate::Args] methods that are derived from the field name when no value
+//! is specified (`#[clap(short)]` and `#[clap(long)]`).
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_02_option.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/03_02_option.md")]
+//!
+//! ### Flags
+//!
+//! Flags can also be switches that can be on/off. This is enabled via the
+//! `#[clap(action = ArgAction::SetTrue)]` attribute though this is implied when the field is a
+//! `bool`.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.md")]
+//!
+//! Or counted with `#[clap(action = clap::ArgAction::Count)]`:
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.md")]
+//!
+//! ### Subcommands
+//!
+//! Subcommands are derived with `#[derive(Subcommand)]` and be added via `#[clap(subcommand)]` attribute. Each
+//! instance of a [Subcommand][crate::Subcommand] can have its own version, author(s), Args, and even its own
+//! subcommands.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.rs")]
+//! ```
+//! We used a struct-variant to define the `add` subcommand.
+//! Alternatively, you can use a struct for your subcommand's arguments:
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands_alt.rs")]
+//! ```
+//!
+#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.md")]
+//!
+//! ### Defaults
+//!
+//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional.
+//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can
+//! set `#[clap(default_value_t)]`.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.md")]
+//!
+//! ## Validation
+//!
+//! ### Enumerated values
+//!
+//! If you have arguments of specific values you want to test for, you can derive
+//! [`ValueEnum`][crate::ValueEnum].
+//!
+//! This allows you specify the valid values for that argument. If the user does not use one of
+//! those specific values, they will receive a graceful exit with error message informing them
+//! of the mistake, and what the possible valid values are
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.md")]
+//!
+//! ### Validated values
+//!
+//! More generally, you can validate and parse into any data type.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.md")]
+//!
+//! A custom parser can be used to improve the error messages or provide additional validation:
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")]
+//!
+//! ### Argument Relations
+//!
+//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even
+//! [`ArgGroup`][crate::ArgGroup]s.
+//!
+//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list
+//! each individually, or when you want a rule to apply "any but not all" arguments.
+//!
+//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one
+//! argument to be present out of a given set. Imagine that you had multiple arguments, and you
+//! want one of them to be required, but making all of them required isn't feasible because perhaps
+//! they conflict with each other.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.md")]
+//!
+//! ### Custom Validation
+//!
+//! As a last resort, you can create custom errors with the basics of clap's formatting.
+//!
+//! ```rust
+#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.rs")]
+//! ```
+#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.md")]
+//!
+//! ## Testing
+//!
+//! clap reports most development errors as `debug_assert!`s. Rather than checking every
+//! subcommand, you should have a test that calls
+//! [`Command::debug_assert`][crate::App::debug_assert]:
+//! ```rust,no_run
+#![doc = include_str!("../../examples/tutorial_derive/05_01_assert.rs")]
+//! ```
diff --git a/vendor/clap/src/_derive/mod.rs b/vendor/clap/src/_derive/mod.rs
new file mode 100644
index 000000000..fc9f35db5
--- /dev/null
+++ b/vendor/clap/src/_derive/mod.rs
@@ -0,0 +1,510 @@
+//! # Documentation: Derive Reference
+//!
+//! 1. [Overview](#overview)
+//! 2. [Attributes](#attributes)
+//! 1. [Terminology](#terminology)
+//! 2. [Command Attributes](#command-attributes)
+//! 3. [Arg Attributes](#arg-attributes)
+//! 4. [ValueEnum Attributes](#valueenum-attributes)
+//! 5. [Possible Value Attributes](#possible-value-attributes)
+//! 3. [Arg Types](#arg-types)
+//! 4. [Doc Comments](#doc-comments)
+//! 5. [Mixing Builder and Derive APIs](#mixing-builder-and-derive-apis)
+//! 6. [Tips](#tips)
+//!
+//! ## Overview
+//!
+//! To derive `clap` types, you need to enable the [`derive` feature flag][crate::_features].
+//!
+//! Example:
+//! ```rust
+#![doc = include_str!("../../examples/demo.rs")]
+//! ```
+//!
+//! Let's start by breaking down the anatomy of the derive attributes:
+//! ```rust
+//! use clap::{Parser, Args, Subcommand, ValueEnum};
+//!
+//! /// Doc comment
+//! #[derive(Parser)]
+//! #[clap(APP ATTRIBUTE)]
+//! struct Cli {
+//! /// Doc comment
+//! #[clap(ARG ATTRIBUTE)]
+//! field: UserType,
+//!
+//! #[clap(value_enum, ARG ATTRIBUTE...)]
+//! field: EnumValues,
+//!
+//! #[clap(flatten)]
+//! delegate: Struct,
+//!
+//! #[clap(subcommand)]
+//! command: Command,
+//! }
+//!
+//! /// Doc comment
+//! #[derive(Args)]
+//! #[clap(PARENT APP ATTRIBUTE)]
+//! struct Struct {
+//! /// Doc comment
+//! #[clap(ARG ATTRIBUTE)]
+//! field: UserType,
+//! }
+//!
+//! /// Doc comment
+//! #[derive(Subcommand)]
+//! #[clap(PARENT APP ATTRIBUTE)]
+//! enum Command {
+//! /// Doc comment
+//! #[clap(APP ATTRIBUTE)]
+//! Variant1(Struct),
+//!
+//! /// Doc comment
+//! #[clap(APP ATTRIBUTE)]
+//! Variant2 {
+//! /// Doc comment
+//! #[clap(ARG ATTRIBUTE)]
+//! field: UserType,
+//! }
+//! }
+//!
+//! /// Doc comment
+//! #[derive(ValueEnum)]
+//! #[clap(VALUE ENUM ATTRIBUTE)]
+//! enum EnumValues {
+//! /// Doc comment
+//! #[clap(POSSIBLE VALUE ATTRIBUTE)]
+//! Variant1,
+//! }
+//!
+//! fn main() {
+//! let cli = Cli::parse();
+//! }
+//! ```
+//!
+//! Traits:
+//! - [`Parser`][crate::Parser] parses arguments into a `struct` (arguments) or `enum` (subcommands).
+//! - [`Args`][crate::Args] allows defining a set of re-usable arguments that get merged into their parent container.
+//! - [`Subcommand`][crate::Subcommand] defines available subcommands.
+//! - Subcommand arguments can be defined in a struct-variant or automatically flattened with a tuple-variant.
+//! - [`ValueEnum`][crate::ValueEnum] allows parsing a value directly into an `enum`, erroring on unsupported values.
+//! - The derive doesn't work on enums that contain non-unit variants, unless they are skipped
+//!
+//! *See also the [derive tutorial][crate::_derive::_tutorial] and [cookbook][crate::_cookbook]*
+//!
+//! ## Attributes
+//!
+//! ### Terminology
+//!
+//! **Raw attributes** are forwarded directly to the underlying [`clap` builder][crate::builder]. Any
+//! [`Command`][crate::Command], [`Arg`][crate::Arg], or [`PossibleValue`][crate::PossibleValue] method can be used as an attribute.
+//!
+//! Raw attributes come in two different syntaxes:
+//! ```rust,ignore
+//! #[clap(
+//! global = true, // name = arg form, neat for one-arg methods
+//! required_if_eq("out", "file") // name(arg1, arg2, ...) form.
+//! )]
+//! ```
+//!
+//! - `method = arg` can only be used for methods which take only one argument.
+//! - `method(arg1, arg2)` can be used with any method.
+//!
+//! As long as `method_name` is not one of the magical methods it will be
+//! translated into a mere method call.
+//!
+//! **Magic attributes** have post-processing done to them, whether that is
+//! - Providing of defaults
+//! - Special behavior is triggered off of it
+//!
+//! Magic attributes are more constrained in the syntax they support, usually just
+//! `<attr> = <value>` though some use `<attr>(<value>)` instead. See the specific
+//! magic attributes documentation for details. This allows users to access the
+//! raw behavior of an attribute via `<attr>(<value>)` syntax.
+//!
+//! **NOTE:** Some attributes are inferred from [Arg Types](#arg-types) and [Doc
+//! Comments](#doc-comments). Explicit attributes take precedence over inferred
+//! attributes.
+//!
+//! ### Command Attributes
+//!
+//! These correspond to a [`Command`][crate::Command] which is used for both top-level parsers and
+//! when defining subcommands.
+//!
+//! **Raw attributes:** Any [`Command` method][crate::Command] can also be used as an attribute,
+//! see [Terminology](#terminology) for syntax.
+//! - e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)`
+//!
+//! **Magic attributes:**
+//! - `name = <expr>`: [`Command::name`][crate::App::name]
+//! - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (if on [`Parser`][crate::Parser] container), variant name (if on [`Subcommand`][crate::Subcommand] variant)
+//! - `version [= <expr>]`: [`Command::version`][crate::App::version]
+//! - When not present: no version set
+//! - Without `<expr>`: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field)
+//! - `author [= <expr>]`: [`Command::author`][crate::App::author]
+//! - When not present: no author set
+//! - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field)
+//! - `about [= <expr>]`: [`Command::about`][crate::App::about]
+//! - When not present: [Doc comment summary](#doc-comments)
+//! - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) ([`Parser`][crate::Parser] container)
+//! - **TIP:** When a doc comment is also present, you most likely want to add
+//! `#[clap(long_about = None)]` to clear the doc comment so only [`about`][crate::App::about]
+//! gets shown with both `-h` and `--help`.
+//! - `long_about = <expr>`: [`Command::long_about`][crate::App::long_about]
+//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
+//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`about`][crate::App::about] / [`long_about`][crate::App::long_about]
+//! - `next_display_order`: [`Command::next_display_order`][crate::App::next_display_order]
+//! - `next_help_heading`: [`Command::next_help_heading`][crate::App::next_help_heading]
+//! - When `flatten`ing [`Args`][crate::Args], this is scoped to just the args in this struct and any struct `flatten`ed into it
+//! - `rename_all = <string_literal>`: Override default field / variant name case conversion for [`Command::name`][crate::Command::name] / [`Arg::id`][crate::Arg::id]
+//! - When not present: `"kebab-case"`
+//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"`
+//! - `rename_all_env = <string_literal>`: Override default field name case conversion for env variables for [`Arg::env`][crate::Arg::env]
+//! - When not present: `"SCREAMING_SNAKE_CASE"`
+//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"`
+//!
+//! And for [`Subcommand`][crate::Subcommand] variants:
+//! - `skip`: Ignore this variant
+//! - `flatten`: Delegates to the variant for more subcommands (must implement
+//! [`Subcommand`][crate::Subcommand])
+//! - `subcommand`: Nest subcommands under the current set of subcommands (must implement
+//! [`Subcommand`][crate::Subcommand])
+//! - `external_subcommand`: [`Command::allow_external_subcommand(true)`][crate::App::allow_external_subcommands]
+//! - Variant must be either `Variant(Vec<String>)` or `Variant(Vec<OsString>)`
+//!
+//! ### Arg Attributes
+//!
+//! These correspond to a [`Arg`][crate::Arg].
+//!
+//! **Raw attributes:** Any [`Arg` method][crate::Arg] can also be used as an attribute, see [Terminology](#terminology) for syntax.
+//! - e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)`
+//!
+//! **Magic attributes**:
+//! - `id = <expr>`: [`Arg::id`][crate::Arg::id]
+//! - When not present: case-converted field name is used
+//! - `name = <expr>`: [`Arg::id`][crate::Arg::id]
+//! - **Deprecated:** use `id`
+//! - `value_parser [= <expr>]`: [`Arg::value_parser`][crate::Arg::value_parser]
+//! - When not present: will auto-select an implementation based on the field type using
+//! [`value_parser!][crate::value_parser!]
+//! - When present but defaulted: opt-in to clap v4 semantics
+//! - Env parsing is now dependent on inferred parser
+//! - `PathBuf` will implicitly skip UTF-8 validation (before it required specifying
+//! `try_from_os_str`)
+//! - When present, implies `#[clap(action)]`
+//! - To register a custom type's [`ValueParser`][crate::builder::ValueParser], implement [`ValueParserFactory`][crate::builder::ValueParserFactory]
+//! - `action [= <expr>]`: [`Arg::action`][crate::Arg::action]
+//! - When not present: will auto-select an action based on the field type
+//! - When present but defaulted: opt-in to clap v4 semantics
+//! - When present, implies `#[clap(value_parser)]`
+//! - `args_override_self` is forced on for single flags
+//! - `help = <expr>`: [`Arg::help`][crate::Arg::help]
+//! - When not present: [Doc comment summary](#doc-comments)
+//! - `long_help = <expr>`: [`Arg::long_help`][crate::Arg::long_help]
+//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
+//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`help`][crate::Arg::help] / [`long_help`][crate::Arg::long_help]
+//! - `short [= <char>]`: [`Arg::short`][crate::Arg::short]
+//! - When not present: no short set
+//! - Without `<char>`: defaults to first character in the case-converted field name
+//! - `long [= <str>]`: [`Arg::long`][crate::Arg::long]
+//! - When not present: no long set
+//! - Without `<str>`: defaults to the case-converted field name
+//! - `env [= <str>]`: [`Arg::env`][crate::Arg::env] (needs [`env` feature][crate::_features] enabled)
+//! - When not present: no env set
+//! - Without `<str>`: defaults to the case-converted field name
+//! - `flatten`: Delegates to the field for more arguments (must implement [`Args`][crate::Args])
+//! - Only [`next_help_heading`][crate::Command::next_help_heading] can be used with `flatten`. See
+//! [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why
+//! arg attributes are not generally supported.
+//! - **Tip:** Though we do apply a flattened [`Args`][crate::Args]'s Parent Command Attributes, this
+//! makes reuse harder. Generally prefer putting the cmd attributes on the
+//! [`Parser`][crate::Parser] or on the flattened field.
+//! - `subcommand`: Delegates definition of subcommands to the field (must implement
+//! [`Subcommand`][crate::Subcommand])
+//! - When `Option<T>`, the subcommand becomes optional
+//! - `from_global`: Read a [`Arg::global`][crate::Arg::global] argument (raw attribute), regardless of what subcommand you are in
+//! - `parse(<kind> [= <function>])`: [`Arg::validator`][crate::Arg::validator] and [`ArgMatches::values_of_t`][crate::ArgMatches::values_of_t]
+//! - **Deprecated:**
+//! - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str`
+//! - Use `action(ArgAction::Count` for `from_occurrences`
+//! - Use `action(ArgAction::SetTrue` for `from_flag`
+//! - Default: `try_from_str`
+//! - Warning: for `Path` / `OsString`, be sure to use `try_from_os_str`
+//! - See [Arg Types](#arg-types) for more details
+//! - `value_enum`: Parse the value using the [`ValueEnum`][crate::ValueEnum]
+//! - `skip [= <expr>]`: Ignore this field, filling in with `<expr>`
+//! - Without `<expr>`: fills the field with `Default::default()`
+//! - `default_value = <str>`: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required]
+//! - `default_value_t [= <expr>]`: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required]
+//! - Requires `std::fmt::Display` or `#[clap(value_enum)]`
+//! - Without `<expr>`, relies on `Default::default()`
+//! - `default_values_t = <expr>`: [`Arg::default_values`][crate::Arg::default_values] and [`Arg::required(false)`][crate::Arg::required]
+//! - Requires field arg to be of type `Vec<T>` and `T` to implement `std::fmt::Display` or `#[clap(value_enum)]`
+//! - `<expr>` must implement `IntoIterator<T>`
+//! - `default_value_os_t [= <expr>]`: [`Arg::default_value_os`][crate::Arg::default_value_os] and [`Arg::required(false)`][crate::Arg::required]
+//! - Requires `std::convert::Into<OsString>` or `#[clap(value_enum)]`
+//! - Without `<expr>`, relies on `Default::default()`
+//! - `default_values_os_t = <expr>`: [`Arg::default_values_os`][crate::Arg::default_values_os] and [`Arg::required(false)`][crate::Arg::required]
+//! - Requires field arg to be of type `Vec<T>` and `T` to implement `std::convert::Into<OsString>` or `#[clap(value_enum)]`
+//! - `<expr>` must implement `IntoIterator<T>`
+//!
+//! ### ValueEnum Attributes
+//!
+//! - `rename_all = <string_literal>`: Override default field / variant name case conversion for [`PossibleValue::new`][crate::PossibleValue]
+//! - When not present: `"kebab-case"`
+//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"`
+//!
+//! ### Possible Value Attributes
+//!
+//! These correspond to a [`PossibleValue`][crate::PossibleValue].
+//!
+//! **Raw attributes:** Any [`PossibleValue` method][crate::PossibleValue] can also be used as an attribute, see [Terminology](#terminology) for syntax.
+//! - e.g. `#[clap(alias("foo"))]` would translate to `pv.alias("foo")`
+//!
+//! **Magic attributes**:
+//! - `name = <expr>`: [`PossibleValue::new`][crate::PossibleValue::new]
+//! - When not present: case-converted field name is used
+//! - `help = <expr>`: [`PossibleValue::help`][crate::PossibleValue::help]
+//! - When not present: [Doc comment summary](#doc-comments)
+//!
+//! ## Arg Types
+//!
+//! `clap` assumes some intent based on the type used:
+//!
+//! | Type | Effect | Implies |
+//! |---------------------|--------------------------------------|------------------------------------------------------------------|
+//! | `bool` | flag | `#[clap(parse(from_flag))]` |
+//! | `Option<T>` | optional argument | `.takes_value(true).required(false)` |
+//! | `Option<Option<T>>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` |
+//! | `T` | required argument | `.takes_value(true).required(!has_default)` |
+//! | `Vec<T>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
+//! | `Option<Vec<T>>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
+//!
+//! Notes:
+//! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones
+//! - For example, see [custom-bool](./custom-bool.md)
+//! - `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
+//! - This gives the user some flexibility in designing their argument, like with `min_values(0)`
+//!
+//! You can then support your custom type with `#[clap(parse(<kind> [= <function>]))]`:
+//!
+//! | `<kind>` | Signature | Default `<function>` |
+//! |--------------------------|---------------------------------------|---------------------------------|
+//! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` |
+//! | `try_from_str` (default) | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` |
+//! | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` |
+//! | `try_from_os_str` | `fn(&OsStr) -> Result<T, E>` | (no default function) |
+//! | `from_occurrences` | `fn(u64) -> T` | `value as T` |
+//! | `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` |
+//!
+//! Notes:
+//! - `from_os_str`:
+//! - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
+//! - `try_from_os_str`:
+//! - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
+//! - `from_occurrences`:
+//! - Implies `arg.takes_value(false).multiple_occurrences(true)`
+//! - Reads from `clap::ArgMatches::occurrences_of` rather than a `get_one` function
+//! - Note: operations on values, like `default_value`, are unlikely to do what you want
+//! - `from_flag`
+//! - Implies `arg.takes_value(false)`
+//! - Reads from `clap::ArgMatches::is_present` rather than a `get_one` function
+//! - Note: operations on values, like `default_value`, are unlikely to do what you want
+//!
+//! **Warning:**
+//! - To support non-UTF8 paths, you should use `#[clap(value_parser)]` otherwise
+//! `clap` will parse it as a `String` which will fail on some paths.
+//!
+//! ## Doc Comments
+//!
+//! In clap, help messages for the whole binary can be specified
+//! via [`Command::about`][crate::App::about] and [`Command::long_about`][crate::App::long_about] while help messages
+//! for individual arguments can be specified via [`Arg::help`][crate::Arg::help] and [`Arg::long_help`][crate::Arg::long_help].
+//!
+//! `long_*` variants are used when user calls the program with
+//! `--help` and "short" variants are used with `-h` flag.
+//!
+//! ```rust
+//! # use clap::Parser;
+//!
+//! #[derive(Parser)]
+//! #[clap(about = "I am a program and I work, just pass `-h`", long_about = None)]
+//! struct Foo {
+//! #[clap(short, help = "Pass `-h` and you'll see me!")]
+//! bar: String,
+//! }
+//! ```
+//!
+//! For convenience, doc comments can be used instead of raw methods
+//! (this example works exactly like the one above):
+//!
+//! ```rust
+//! # use clap::Parser;
+//!
+//! #[derive(Parser)]
+//! /// I am a program and I work, just pass `-h`
+//! struct Foo {
+//! /// Pass `-h` and you'll see me!
+//! bar: String,
+//! }
+//! ```
+//!
+//! **NOTE:** Attributes have priority over doc comments!
+//!
+//! **Top level doc comments always generate `Command::about/long_about` calls!**
+//! If you really want to use the `Command::about/long_about` methods (you likely don't),
+//! use the `about` / `long_about` attributes to override the calls generated from
+//! the doc comment. To clear `long_about`, you can use
+//! `#[clap(long_about = None)]`.
+//!
+//! **TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time.
+//!
+//! ### Pre-processing
+//!
+//! ```rust
+//! # use clap::Parser;
+//! #[derive(Parser)]
+//! /// Hi there, I'm Robo!
+//! ///
+//! /// I like beeping, stumbling, eating your electricity,
+//! /// and making records of you singing in a shower.
+//! /// Pay up, or I'll upload it to youtube!
+//! struct Robo {
+//! /// Call my brother SkyNet.
+//! ///
+//! /// I am artificial superintelligence. I won't rest
+//! /// until I'll have destroyed humanity. Enjoy your
+//! /// pathetic existence, you mere mortals.
+//! #[clap(long, action)]
+//! kill_all_humans: bool,
+//! }
+//! ```
+//!
+//! A doc comment consists of three parts:
+//! - Short summary
+//! - A blank line (whitespace only)
+//! - Detailed description, all the rest
+//!
+//! The summary corresponds with `Command::about` / `Arg::help`. When a blank line is
+//! present, the whole doc comment will be passed to `Command::long_about` /
+//! `Arg::long_help`. Or in other words, a doc may result in just a `Command::about` /
+//! `Arg::help` or `Command::about` / `Arg::help` and `Command::long_about` /
+//! `Arg::long_help`
+//!
+//! In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including:
+//!
+//! - Strip leading and trailing whitespace from every line, if present.
+//!
+//! - Strip leading and trailing blank lines, if present.
+//!
+//! - Interpret each group of non-empty lines as a word-wrapped paragraph.
+//!
+//! We replace newlines within paragraphs with spaces to allow the output
+//! to be re-wrapped to the terminal width.
+//!
+//! - Strip any excess blank lines so that there is exactly one per paragraph break.
+//!
+//! - If the first paragraph ends in exactly one period,
+//! remove the trailing period (i.e. strip trailing periods but not trailing ellipses).
+//!
+//! Sometimes you don't want this preprocessing to apply, for example the comment contains
+//! some ASCII art or markdown tables, you would need to preserve LFs along with
+//! blank lines and the leading/trailing whitespace. When you pass use the
+//! `verbatim_doc_comment` magic attribute, you preserve
+//! them.
+//!
+//! **Note:** Keep in mind that `verbatim_doc_comment` will *still*
+//! - Remove one leading space from each line, even if this attribute is present,
+//! to allow for a space between `///` and the content.
+//! - Remove leading and trailing blank lines
+//!
+//! ## Mixing Builder and Derive APIs
+//!
+//! The builder and derive APIs do not live in isolation. They can work together, which is
+//! especially helpful if some arguments can be specified at compile-time while others must be
+//! specified at runtime.
+//!
+//! ### Using derived arguments in a builder application
+//!
+//! When using the derive API, you can `#[clap(flatten)]` a struct deriving `Args` into a struct
+//! deriving `Args` or `Parser`. This example shows how you can augment a `Command` instance
+//! created using the builder API with `Args` created using the derive API.
+//!
+//! It uses the [`Args::augment_args`][crate::Args::augment_args] method to add the arguments to
+//! the `Command` instance.
+//!
+//! Crates such as [clap-verbosity-flag](https://github.com/rust-cli/clap-verbosity-flag) provide
+//! structs that implement `Args`. Without the technique shown in this example, it would not be
+//! possible to use such crates with the builder API.
+//!
+//! For example:
+//! ```rust
+#![doc = include_str!("../../examples/derive_ref/augment_args.rs")]
+//! ```
+//!
+//! ### Using derived subcommands in a builder application
+//!
+//! When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add
+//! subcommands. The type of the field is usually an enum that derived `Parser`. However, you can
+//! also add the subcommands in that enum to a `Command` instance created with the builder API.
+//!
+//! It uses the [`Subcommand::augment_subcommands`][crate::Subcommand::augment_subcommands] method
+//! to add the subcommands to the `Command` instance.
+//!
+//! For example:
+//! ```rust
+#![doc = include_str!("../../examples/derive_ref/augment_subcommands.rs")]
+//! ```
+//!
+//! ### Adding hand-implemented subcommands to a derived application
+//!
+//! When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add
+//! subcommands. The type of the field is usually an enum that derived `Parser`. However, you can
+//! also implement the `Subcommand` trait manually on this enum (or any other type) and it can
+//! still be used inside the struct created with the derive API. The implementation of the
+//! `Subcommand` trait will use the builder API to add the subcommands to the `Command` instance
+//! created behind the scenes for you by the derive API.
+//!
+//! Notice how in the previous example we used
+//! [`augment_subcommands`][crate::Subcommand::augment_subcommands] on an enum that derived
+//! `Parser`, whereas now we implement
+//! [`augment_subcommands`][crate::Subcommand::augment_subcommands] ourselves, but the derive API
+//! calls it automatically since we used the `#[clap(subcommand)]` attribute.
+//!
+//! For example:
+//! ```rust
+#![doc = include_str!("../../examples/derive_ref/hand_subcommand.rs")]
+//! ```
+//!
+//! ### Flattening hand-implemented args into a derived application
+//!
+//! When using the derive API, you can use `#[clap(flatten)]` inside the struct to add arguments as
+//! if they were added directly to the containing struct. The type of the field is usually an
+//! struct that derived `Args`. However, you can also implement the `Args` trait manually on this
+//! struct (or any other type) and it can still be used inside the struct created with the derive
+//! API. The implementation of the `Args` trait will use the builder API to add the arguments to
+//! the `Command` instance created behind the scenes for you by the derive API.
+//!
+//! Notice how in the previous example we used [`augment_args`][crate::Args::augment_args] on the
+//! struct that derived `Parser`, whereas now we implement
+//! [`augment_args`][crate::Args::augment_args] ourselves, but the derive API calls it
+//! automatically since we used the `#[clap(flatten)]` attribute.
+//!
+//! For example:
+//! ```rust
+#![doc = include_str!("../../examples/derive_ref/flatten_hand_args.rs")]
+//! ```
+//!
+//! ## Tips
+//!
+//! - To get access to a [`Command`][crate::Command] call
+//! [`CommandFactory::command`][crate::CommandFactory::command] (implemented when deriving
+//! [`Parser`][crate::Parser])
+//! - Proactively check for bad [`Command`][crate::Command] configurations by calling
+//! [`Command::debug_assert`][crate::App::debug_assert] in a test
+//! ([example](../tutorial_derive/05_01_assert.rs))
+
+pub mod _tutorial;
+#[doc(inline)]
+pub use crate::_cookbook;
diff --git a/vendor/clap/src/_faq.rs b/vendor/clap/src/_faq.rs
new file mode 100644
index 000000000..661a7e73d
--- /dev/null
+++ b/vendor/clap/src/_faq.rs
@@ -0,0 +1,95 @@
+//! # Documentation: FAQ
+//!
+//! 1. [Comparisons](#comparisons)
+//! 1. [How does `clap` compare to structopt?](#how-does-clap-compare-to-structopt)
+//! 2. [What are some reasons to use `clap`? (The Pitch)](#what-are-some-reasons-to-use-clap-the-pitch)
+//! 3. [What are some reasons *not* to use `clap`? (The Anti Pitch)](#what-are-some-reasons-not-to-use-clap-the-anti-pitch)
+//! 4. [Reasons to use `clap`](#reasons-to-use-clap)
+//! 2. [How many approaches are there to create a parser?](#how-many-approaches-are-there-to-create-a-parser)
+//! 3. [When should I use the builder vs derive APIs?](#when-should-i-use-the-builder-vs-derive-apis)
+//! 4. [Why is there a default subcommand of help?](#why-is-there-a-default-subcommand-of-help)
+//!
+//! ### Comparisons
+//!
+//! First, let me say that these comparisons are highly subjective, and not meant
+//! in a critical or harsh manner. All the argument parsing libraries out there (to
+//! include `clap`) have their own strengths and weaknesses. Sometimes it just
+//! comes down to personal taste when all other factors are equal. When in doubt,
+//! try them all and pick one that you enjoy :) There's plenty of room in the Rust
+//! community for multiple implementations!
+//!
+//! For less detailed but more broad comparisons, see
+//! [argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs).
+//!
+//! #### How does `clap` compare to [structopt](https://github.com/TeXitoi/structopt)?
+//!
+//! Simple! `clap` *is* `structopt`. `structopt` started as a derive API built on
+//! top of clap v2. With clap v3, we've forked structopt and integrated it
+//! directly into clap. structopt is in
+//! [maintenance mode](https://github.com/TeXitoi/structopt/issues/516#issuecomment-989566094)
+//! with the release of `clap_derive`.
+//!
+//! The benefits of integrating `structopt` and `clap` are:
+//! - Easier cross-linking in documentation
+//! - [Documentation parity](../examples)
+//! - Tighter design feedback loop, ensuring all new features are designed with
+//! derives in mind and easier to change `clap` in response to `structopt` bugs.
+//! - Clearer endorsement of `structopt`
+//!
+//! See also
+//! - [`clap` v3 CHANGELOG](../CHANGELOG.md#300---2021-12-31)
+//! - [`structopt` migration guide](../CHANGELOG.md#migrate-structopt)
+//!
+//! #### What are some reasons to use `clap`? (The Pitch)
+//!
+//! `clap` is as fast, and as lightweight as possible while still giving all the features you'd expect from a modern argument parser. In fact, for the amount and type of features `clap` offers it remains about as fast as `getopts`. If you use `clap` when just need some simple arguments parsed, you'll find it's a walk in the park. `clap` also makes it possible to represent extremely complex, and advanced requirements, without too much thought. `clap` aims to be intuitive, easy to use, and fully capable for wide variety use cases and needs.
+//!
+//! #### What are some reasons *not* to use `clap`? (The Anti Pitch)
+//!
+//! Depending on the style in which you choose to define the valid arguments, `clap` can be very verbose. `clap` also offers so many finetuning knobs and dials, that learning everything can seem overwhelming. I strive to keep the simple cases simple, but when turning all those custom dials it can get complex. `clap` is also opinionated about parsing. Even though so much can be tweaked and tuned with `clap` (and I'm adding more all the time), there are still certain features which `clap` implements in specific ways which may be contrary to some users use-cases.
+//!
+//! #### Reasons to use `clap`
+//!
+//! * You want all the nice CLI features your users may expect, yet you don't want to implement them all yourself. You'd like to focus your application, not argument parsing.
+//! * In addition to the point above; you don't want to sacrifice performance to get all those nice features
+//! * You have complex requirements/conflicts between your various valid args.
+//! * You want to use subcommands (although other libraries also support subcommands, they are not nearly as feature rich as those provided by `clap`)
+//! * You want some sort of custom validation built into the argument parsing process, instead of as part of your application (which allows for earlier failures, better error messages, more cohesive experience, etc.)
+//!
+//! ### How many approaches are there to create a parser?
+//!
+//! The following APIs are supported:
+//! - [Derive][crate::_derive::_tutorial]
+//! - [Builder][crate::_tutorial]
+//!
+//! Previously, we supported:
+//! - [YAML](https://github.com/clap-rs/clap/issues/3087)
+//! - [docopt](http://docopt.org/)-inspired [usage parser](https://github.com/clap-rs/clap/issues/3086)
+//! - [`clap_app!`](https://github.com/clap-rs/clap/issues/2835)
+//!
+//! There are also experiments with other APIs:
+//! - [fncmd](https://github.com/yuhr/fncmd): function attribute
+//! - [clap-serde](https://github.com/aobatact/clap-serde): create an `Command` from a deserializer
+//!
+//! ### When should I use the builder vs derive APIs?
+//!
+//! Our default answer is to use the [Derive API][crate::_derive::_tutorial]:
+//! - Easier to read, write, and modify
+//! - Easier to keep the argument declaration and reading of argument in sync
+//! - Easier to reuse, e.g. [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag)
+//!
+//! The [Builder API][crate::_tutorial] is a lower-level API that someone might want to use for
+//! - Faster compile times if you aren't already using other procedural macros
+//! - More flexibility, e.g. you can look up an [arguments values][crate::ArgMatches::get_many],
+//! their [ordering with other arguments][crate::ArgMatches::indices_of], and [what set
+//! them][crate::ArgMatches::value_source]. The Derive API can only report values and not
+//! indices of or other data.
+//!
+//! You can [interop between Derive and Builder APIs][crate::_derive#mixing-builder-and-derive-apis].
+//!
+//! ### Why is there a default subcommand of help?
+//!
+//! There is only a default subcommand of `help` when other subcommands have been defined manually. So it's opt-in(ish), being that you only get a `help` subcommand if you're actually using subcommands.
+//!
+//! Also, if the user defined a `help` subcommand themselves, the auto-generated one wouldn't be added (meaning it's only generated if the user hasn't defined one themselves).
+//!
diff --git a/vendor/clap/src/_features.rs b/vendor/clap/src/_features.rs
new file mode 100644
index 000000000..923134c45
--- /dev/null
+++ b/vendor/clap/src/_features.rs
@@ -0,0 +1,27 @@
+//! ## Documentation: Feature Flags
+//!
+//! Available [compile-time feature flags](https://doc.rust-lang.org/cargo/reference/features.html#dependency-features)
+//!
+//! #### Default Features
+//!
+//! * **std**: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner.
+//! * **color**: Turns on colored error messages.
+//! * **suggestions**: Turns on the `Did you mean '--myoption'?` feature for when users make typos.
+//!
+//! #### Optional features
+//!
+//! * **deprecated**: Guided experience to prepare for next breaking release (at different stages of development, this may become default)
+//! * **derive**: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above.
+//! * **cargo**: Turns on macros that read values from [`CARGO_*` environment variables](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates).
+//! * **env**: Turns on the usage of environment variables during parsing.
+//! * **regex**: Enables regex validators.
+//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
+//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
+//!
+//! #### Experimental features
+//!
+//! **Warning:** These may contain breaking changes between minor releases.
+//!
+//! * **unstable-replace**: Enable [`Command::replace`](https://github.com/clap-rs/clap/issues/2836)
+//! * **unstable-grouped**: Enable [`ArgMatches::grouped_values_of`](https://github.com/clap-rs/clap/issues/2924)
+//! * **unstable-v4**: Preview features which will be stable on the v4.0 release
diff --git a/vendor/clap/src/_tutorial.rs b/vendor/clap/src/_tutorial.rs
new file mode 100644
index 000000000..9dbfc6864
--- /dev/null
+++ b/vendor/clap/src/_tutorial.rs
@@ -0,0 +1,204 @@
+// Contributing
+//
+// New example code:
+// - Please update the corresponding section in the derive tutorial
+// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`.
+// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax
+//
+// See also the general CONTRIBUTING
+
+//! # Documentation: Builder Tutorial
+//!
+//! 1. [Quick Start](#quick-start)
+//! 2. [Configuring the Parser](#configuring-the-parser)
+//! 3. [Adding Arguments](#adding-arguments)
+//! 1. [Positionals](#positionals)
+//! 2. [Options](#options)
+//! 3. [Flags](#flags)
+//! 4. [Subcommands](#subcommands)
+//! 5. [Defaults](#defaults)
+//! 4. Validation
+//! 1. [Enumerated values](#enumerated-values)
+//! 2. [Validated values](#validated-values)
+//! 3. [Argument Relations](#argument-relations)
+//! 4. [Custom Validation](#custom-validation)
+//! 5. [Testing](#testing)
+//!
+//! See also
+//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis]
+//! - The [cookbook][crate::_cookbook] for more application-focused examples
+//!
+//! ## Quick Start
+//!
+//! You can create an application with several arguments using usage strings.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/01_quick.rs")]
+//! ```
+//!
+#![doc = include_str!("../examples/tutorial_builder/01_quick.md")]
+//!
+//! ## Configuring the Parser
+//!
+//! You use [`Command`][crate::Command] to start building a parser.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/02_apps.rs")]
+//! ```
+//!
+#![doc = include_str!("../examples/tutorial_builder/02_apps.md")]
+//!
+//! You can use [`command!()`][crate::command!] to fill these fields in from your `Cargo.toml`
+//! file. **This requires the [`cargo` feature flag][crate::_features].**
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/02_crate.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/02_crate.md")]
+//!
+//! You can use [`Command`][crate::Command] methods to change the application level behavior of
+//! clap.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/02_app_settings.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/02_app_settings.md")]
+//!
+//! ## Adding Arguments
+//!
+//! ### Positionals
+//!
+//! You can have users specify values by their position on the command-line:
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/03_03_positional.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/03_03_positional.md")]
+//!
+//! ### Options
+//!
+//! You can name your arguments with a flag:
+//! - Order doesn't matter
+//! - They can be optional
+//! - Intent is clearer
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/03_02_option.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/03_02_option.md")]
+//!
+//! ### Flags
+//!
+//! Flags can also be switches that can be on/off:
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.md")]
+//!
+//! Or counted.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.md")]
+//!
+//! ### Subcommands
+//!
+//! Subcommands are defined as [`Command`][crate::Command]s that get added via
+//! [`Command::subcommand`][crate::Command::subcommand]. Each instance of a Subcommand can have its
+//! own version, author(s), Args, and even its own subcommands.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.md")]
+//!
+//! ### Defaults
+//!
+//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional.
+//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can set
+//! [`Arg::default_value`][crate::Arg::default_value].
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.md")]
+//!
+//! ## Validation
+//!
+//! ### Enumerated values
+//!
+//! If you have arguments of specific values you want to test for, you can use the
+//! [`PossibleValuesParser`][crate::builder::PossibleValuesParser] or [`Arg::value_parser(["val1",
+//! ...])`][crate::Arg::value_parser] for short.
+//!
+//! This allows you specify the valid values for that argument. If the user does not use one of
+//! those specific values, they will receive a graceful exit with error message informing them
+//! of the mistake, and what the possible valid values are
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/04_01_possible.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/04_01_possible.md")]
+//!
+//! When enabling the [`derive` feature][crate::_features], you can use
+//! [`ValueEnum`][crate::ValueEnum] to take care of the boiler plate for you, giving the same
+//! results.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/04_01_enum.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/04_01_enum.md")]
+//!
+//! ### Validated values
+//!
+//! More generally, you can validate and parse into any data type.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/04_02_parse.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/04_02_parse.md")]
+//!
+//! A custom parser can be used to improve the error messages or provide additional validation:
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/04_02_validate.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/04_02_validate.md")]
+//!
+//! ### Argument Relations
+//!
+//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even
+//! [`ArgGroup`][crate::ArgGroup]s.
+//!
+//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list
+//! each individually, or when you want a rule to apply "any but not all" arguments.
+//!
+//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one
+//! argument to be present out of a given set. Imagine that you had multiple arguments, and you
+//! want one of them to be required, but making all of them required isn't feasible because perhaps
+//! they conflict with each other.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/04_03_relations.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/04_03_relations.md")]
+//!
+//! ### Custom Validation
+//!
+//! As a last resort, you can create custom errors with the basics of clap's formatting.
+//!
+//! ```rust
+#![doc = include_str!("../examples/tutorial_builder/04_04_custom.rs")]
+//! ```
+#![doc = include_str!("../examples/tutorial_builder/04_04_custom.md")]
+//!
+//! ## Testing
+//!
+//! clap reports most development errors as `debug_assert!`s. Rather than checking every
+//! subcommand, you should have a test that calls
+//! [`Command::debug_assert`][crate::App::debug_assert]:
+//! ```rust,no_run
+#![doc = include_str!("../examples/tutorial_builder/05_01_assert.rs")]
+//! ```
diff --git a/vendor/clap/src/builder/action.rs b/vendor/clap/src/builder/action.rs
index ab3314290..71a91a8b1 100644
--- a/vendor/clap/src/builder/action.rs
+++ b/vendor/clap/src/builder/action.rs
@@ -183,16 +183,16 @@ pub enum ArgAction {
/// assert!(matches.contains_id("flag"));
/// assert_eq!(matches.occurrences_of("flag"), 0);
/// assert_eq!(
- /// matches.get_one::<u8>("flag").copied(),
- /// Some(2)
+ /// matches.get_count("flag"),
+ /// 2
/// );
///
/// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap();
/// assert!(matches.contains_id("flag"));
/// assert_eq!(matches.occurrences_of("flag"), 0);
/// assert_eq!(
- /// matches.get_one::<u8>("flag").copied(),
- /// Some(0)
+ /// matches.get_count("flag"),
+ /// 0
/// );
/// ```
Count,
diff --git a/vendor/clap/src/builder/app_settings.rs b/vendor/clap/src/builder/app_settings.rs
index e2d9ba6b1..88bc243c4 100644
--- a/vendor/clap/src/builder/app_settings.rs
+++ b/vendor/clap/src/builder/app_settings.rs
@@ -400,23 +400,20 @@ pub enum AppSettings {
)]
NoAutoVersion,
- /// Deprecated, replaced with [`AppSettings::AllowHyphenValues`]
+ /// Deprecated, replaced with [`Command::allow_hyphen_values`]
#[cfg_attr(
feature = "deprecated",
- deprecated(
- since = "3.0.0",
- note = "Replaced with `AppSettings::AllowHyphenValues`"
- )
+ deprecated(since = "3.0.0", note = "Replaced with `Command::allow_hyphen_values`")
)]
#[doc(hidden)]
AllowLeadingHyphen,
- /// Deprecated, this is now the default, see [`AppSettings::AllowInvalidUtf8ForExternalSubcommands`] and [`ArgSettings::AllowInvalidUtf8`][crate::ArgSettings::AllowInvalidUtf8] for the opposite.
+ /// Deprecated, replaced with [`Command::allow_invalid_utf8_for_external_subcommands`] and [`Command::is_allow_invalid_utf8_for_external_subcommands_set`]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "This is now the default see `AppSettings::AllowInvalidUtf8ForExternalSubcommands` and `ArgSettings::AllowInvalidUtf8` for the opposite."
+ note = "Replaced with `Command::allow_invalid_utf8_for_external_subcommands` and `Command::is_allow_invalid_utf8_for_external_subcommands_set`"
)
)]
#[doc(hidden)]
@@ -462,42 +459,47 @@ pub enum AppSettings {
#[doc(hidden)]
ColorNever,
- /// Deprecated, replaced with [`AppSettings::DisableHelpFlag`]
+ /// Deprecated, replaced with [`Command::disable_help_flag`] and [`Command::is_disable_help_flag_set`]
#[cfg_attr(
feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `AppSettings::DisableHelpFlag`")
+ deprecated(
+ since = "3.0.0",
+ note = "Replaced with `Command::disable_help_flag` and `Command::is_disable_help_flag_set`"
+ )
)]
#[doc(hidden)]
DisableHelpFlags,
- /// Deprecated, replaced with [`AppSettings::DisableVersionFlag`]
+ /// Deprecated, replaced with [`Command::disable_version_flag`] and
+ /// [`Command::is_disable_version_flag_set`]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "Replaced with `AppSettings::DisableVersionFlag`"
+ note = "Replaced with `Command::disable_version_flag` and `Command::is_disable_version_flag_set`"
)
)]
#[doc(hidden)]
DisableVersion,
- /// Deprecated, replaced with [`AppSettings::PropagateVersion`]
+ /// Deprecated, replaced with [`Command::propagate_version`] and [`Command::is_propagate_version_set`]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "Replaced with `AppSettings::PropagateVersion`"
+ note = "Replaced with `Command::propagate_version` and `Command::is_propagate_version_set`"
)
)]
#[doc(hidden)]
GlobalVersion,
- /// Deprecated, replaced with [`AppSettings::HidePossibleValues`]
+ /// Deprecated, replaced with [`Command::hide_possible_values`] and
+ /// [`Arg::is_hide_possible_values_set`]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "Replaced with AppSettings::HidePossibleValues"
+ note = "Replaced with `Command::hide_possible_values` and `Arg::is_hide_possible_values_set`"
)
)]
#[doc(hidden)]
diff --git a/vendor/clap/src/builder/arg.rs b/vendor/clap/src/builder/arg.rs
index 63e88e80e..e9403d0b7 100644
--- a/vendor/clap/src/builder/arg.rs
+++ b/vendor/clap/src/builder/arg.rs
@@ -4316,6 +4316,16 @@ impl<'help> Arg<'help> {
}
}
+ /// Get *all* short aliases for this argument, if any, both visible and hidden.
+ #[inline]
+ pub fn get_all_short_aliases(&self) -> Option<Vec<char>> {
+ if self.short_aliases.is_empty() {
+ None
+ } else {
+ Some(self.short_aliases.iter().map(|(s, _)| s).copied().collect())
+ }
+ }
+
/// Get the short option name and its visible aliases, if any
#[inline]
pub fn get_short_and_visible_aliases(&self) -> Option<Vec<char>> {
@@ -4351,6 +4361,16 @@ impl<'help> Arg<'help> {
}
}
+ /// Get *all* aliases for this argument, if any, both visible and hidden.
+ #[inline]
+ pub fn get_all_aliases(&self) -> Option<Vec<&'help str>> {
+ if self.aliases.is_empty() {
+ None
+ } else {
+ Some(self.aliases.iter().map(|(s, _)| s).copied().collect())
+ }
+ }
+
/// Get the long option name and its visible aliases, if any
#[inline]
pub fn get_long_and_visible_aliases(&self) -> Option<Vec<&'help str>> {
diff --git a/vendor/clap/src/builder/arg_settings.rs b/vendor/clap/src/builder/arg_settings.rs
index 3b7faf7bf..ecc064caa 100644
--- a/vendor/clap/src/builder/arg_settings.rs
+++ b/vendor/clap/src/builder/arg_settings.rs
@@ -50,14 +50,10 @@ pub enum ArgSettings {
)
)]
MultipleValues,
- /// Deprecated, replaced with [`Arg::multiple_occurrences`] and
- /// [`Arg::is_multiple_occurrences_set`]
+ /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772))
#[cfg_attr(
feature = "deprecated",
- deprecated(
- since = "3.1.0",
- note = "Replaced with `Arg::multiple_occurrences` and `Arg::is_multiple_occurrences_set`"
- )
+ deprecated(since = "3.1.0", note = "Replaced with `Arg::action` (Issue #3772)")
)]
MultipleOccurrences,
/// Deprecated, see [`ArgSettings::MultipleOccurrences`] (most likely what you want) and
@@ -66,18 +62,17 @@ pub enum ArgSettings {
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "Split into `ArgSettings::MultipleOccurrences` (most likely what you want) and `ArgSettings::MultipleValues`"
+ note = "Split into `Arg::multiple_occurrences` (most likely what you want) and `Arg::multiple_values`"
)
)]
#[doc(hidden)]
Multiple,
- /// Deprecated, replaced with [`Arg::forbid_empty_values`] and
- /// [`Arg::is_forbid_empty_values_set`]
+ /// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.1.0",
- note = "Replaced with `Arg::forbid_empty_values` and `Arg::is_forbid_empty_values_set`"
+ note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`"
)
)]
ForbidEmptyValues,
@@ -157,12 +152,13 @@ pub enum ArgSettings {
)
)]
AllowHyphenValues,
- /// Deprecated, replaced with [`ArgSettings::AllowHyphenValues`]
+ /// Deprecated, replaced with [`Arg::allow_hyphen_values`] and
+ /// [`Arg::is_allow_hyphen_values_set`]
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "Replaced with `ArgSettings::AllowHyphenValues`"
+ note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`"
)
)]
#[doc(hidden)]
@@ -203,10 +199,13 @@ pub enum ArgSettings {
)
)]
IgnoreCase,
- /// Deprecated, replaced with [`ArgSettings::IgnoreCase`]
+ /// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`]
#[cfg_attr(
feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `ArgSettings::IgnoreCase`")
+ deprecated(
+ since = "3.0.0",
+ note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`"
+ )
)]
#[doc(hidden)]
CaseInsensitive,
diff --git a/vendor/clap/src/builder/command.rs b/vendor/clap/src/builder/command.rs
index 1fcb64ecc..de59ad8cd 100644
--- a/vendor/clap/src/builder/command.rs
+++ b/vendor/clap/src/builder/command.rs
@@ -274,6 +274,50 @@ impl<'help> App<'help> {
self
}
+ /// Allows one to mutate a [`Command`] after it's been added as a subcommand.
+ ///
+ /// This can be useful for modifying auto-generated arguments of nested subcommands with
+ /// [`Command::mut_arg`].
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use clap::Command;
+ ///
+ /// let mut cmd = Command::new("foo")
+ /// .subcommand(Command::new("bar"))
+ /// .mut_subcommand("bar", |subcmd| subcmd.disable_help_flag(true));
+ ///
+ /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar", "--help"]);
+ ///
+ /// // Since we disabled the help flag on the "bar" subcommand, this should err.
+ ///
+ /// assert!(res.is_err());
+ ///
+ /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar"]);
+ /// assert!(res.is_ok());
+ /// ```
+ #[must_use]
+ pub fn mut_subcommand<'a, T, F>(mut self, subcmd_id: T, f: F) -> Self
+ where
+ F: FnOnce(App<'help>) -> App<'help>,
+ T: Into<&'a str>,
+ {
+ let subcmd_id: &str = subcmd_id.into();
+ let id = Id::from(subcmd_id);
+
+ let pos = self.subcommands.iter().position(|s| s.id == id);
+
+ let subcmd = if let Some(idx) = pos {
+ self.subcommands.remove(idx)
+ } else {
+ App::new(subcmd_id)
+ };
+
+ self.subcommands.push(f(subcmd));
+ self
+ }
+
/// Adds an [`ArgGroup`] to the application.
///
/// [`ArgGroup`]s are a family of related arguments.
@@ -700,7 +744,7 @@ impl<'help> App<'help> {
/// [`io::stdout()`]: std::io::stdout()
pub fn print_help(&mut self) -> io::Result<()> {
self._build_self();
- let color = self.get_color();
+ let color = self.color_help();
let mut c = Colorizer::new(Stream::Stdout, color);
let usage = Usage::new(self);
@@ -725,7 +769,7 @@ impl<'help> App<'help> {
/// [`--help` (long)]: Arg::long_help()
pub fn print_long_help(&mut self) -> io::Result<()> {
self._build_self();
- let color = self.get_color();
+ let color = self.color_help();
let mut c = Colorizer::new(Stream::Stdout, color);
let usage = Usage::new(self);
@@ -1604,6 +1648,14 @@ impl<'help> App<'help> {
/// strings. After this setting is set, this will be *the only* usage string
/// displayed to the user!
///
+ /// **NOTE:** Multiple usage lines may be present in the usage argument, but
+ /// some rules need to be followed to ensure the usage lines are formatted
+ /// correctly by the default help formatter:
+ ///
+ /// - Do not indent the first usage line.
+ /// - Indent all subsequent usage lines with four spaces.
+ /// - The last line must not end with a newline.
+ ///
/// # Examples
///
/// ```no_run
@@ -1612,6 +1664,20 @@ impl<'help> App<'help> {
/// .override_usage("myapp [-clDas] <some_file>")
/// # ;
/// ```
+ ///
+ /// Or for multiple usage lines:
+ ///
+ /// ```no_run
+ /// # use clap::{Command, Arg};
+ /// Command::new("myprog")
+ /// .override_usage(
+ /// "myapp -X [-a] [-b] <file>\n \
+ /// myapp -Y [-c] <file1> <file2>\n \
+ /// myapp -Z [-d|-e]"
+ /// )
+ /// # ;
+ /// ```
+ ///
/// [`ArgMatches::usage`]: ArgMatches::usage()
#[must_use]
pub fn override_usage<S: Into<&'help str>>(mut self, usage: S) -> Self {
@@ -3512,15 +3578,21 @@ impl<'help> App<'help> {
if arg.is_global_set() {
self.get_global_arg_conflicts_with(arg)
} else {
- arg.blacklist
- .iter()
- .map(|id| {
- self.args.args().find(|arg| arg.id == *id).expect(
- "Command::get_arg_conflicts_with: \
- The passed arg conflicts with an arg unknown to the cmd",
- )
- })
- .collect()
+ let mut result = Vec::new();
+ for id in arg.blacklist.iter() {
+ if let Some(arg) = self.find(id) {
+ result.push(arg);
+ } else if let Some(group) = self.find_group(id) {
+ result.extend(
+ self.unroll_args_in_group(&group.id)
+ .iter()
+ .map(|id| self.find(id).expect(INTERNAL_ERROR_MSG)),
+ );
+ } else {
+ panic!("Command::get_arg_conflicts_with: The passed arg conflicts with an arg unknown to the cmd");
+ }
+ }
+ result
}
}
@@ -4264,7 +4336,8 @@ impl<'help> App<'help> {
use std::fmt::Write;
let mut mid_string = String::from(" ");
- if !self.is_subcommand_negates_reqs_set() {
+ if !self.is_subcommand_negates_reqs_set() && !self.is_args_conflicts_with_subcommands_set()
+ {
let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
for s in &reqs {
@@ -4347,7 +4420,9 @@ impl<'help> App<'help> {
if !self.is_set(AppSettings::BinNameBuilt) {
let mut mid_string = String::from(" ");
- if !self.is_subcommand_negates_reqs_set() {
+ if !self.is_subcommand_negates_reqs_set()
+ && !self.is_args_conflicts_with_subcommands_set()
+ {
let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
for s in &reqs {
@@ -5107,3 +5182,8 @@ where
_ => None,
}
}
+
+#[test]
+fn check_auto_traits() {
+ static_assertions::assert_impl_all!(Command: Send, Sync, Unpin);
+}
diff --git a/vendor/clap/src/builder/value_parser.rs b/vendor/clap/src/builder/value_parser.rs
index 397537c9f..0492f2782 100644
--- a/vendor/clap/src/builder/value_parser.rs
+++ b/vendor/clap/src/builder/value_parser.rs
@@ -12,7 +12,7 @@ use crate::parser::AnyValueId;
/// use within an application.
///
/// See
-/// - [`value_parser!`] for automatically selecting an implementation for a given type
+/// - [`value_parser!`][crate::value_parser] for automatically selecting an implementation for a given type
/// - [`ValueParser::new`] for additional [`TypedValueParser`] that can be used
///
/// # Example
diff --git a/vendor/clap/src/derive.rs b/vendor/clap/src/derive.rs
index bfb7bdfa2..b6ac04df6 100644
--- a/vendor/clap/src/derive.rs
+++ b/vendor/clap/src/derive.rs
@@ -19,11 +19,9 @@ use std::ffi::OsString;
///
/// See also [`Subcommand`] and [`Args`].
///
-/// See the
-/// [derive reference](https://github.com/clap-rs/clap/blob/v3.2.5/examples/derive_ref/README.md)
-/// for attributes and best practices.
+/// See the [derive reference](crate::_derive) for attributes and best practices.
///
-/// **NOTE:** Deriving requires the `derive` feature flag
+/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features]
///
/// # Examples
///
@@ -156,13 +154,13 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
.map_err(format_error::<Self>)
}
- /// Deprecated, `StructOpt::clap` replaced with [`IntoCommand::command`] (derive as part of
+ /// Deprecated, `StructOpt::clap` replaced with [`CommandFactory::command`] (derive as part of
/// [`Parser`])
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.0.0",
- note = "`StructOpt::clap` is replaced with `IntoCommand::command` (derived as part of `Parser`)"
+ note = "`StructOpt::clap` is replaced with `CommandFactory::command` (derived as part of `Parser`)"
)
)]
#[doc(hidden)]
@@ -372,11 +370,9 @@ pub trait FromArgMatches: Sized {
/// `Args`.
/// - `Variant(ChildArgs)`: No attribute is used with enum variants that impl `Args`.
///
-/// See the
-/// [derive reference](https://github.com/clap-rs/clap/blob/v3.2.5/examples/derive_ref/README.md)
-/// for attributes and best practices.
+/// See the [derive reference](crate::_derive) for attributes and best practices.
///
-/// **NOTE:** Deriving requires the `derive` feature flag
+/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features]
///
/// # Example
///
@@ -416,11 +412,9 @@ pub trait Args: FromArgMatches + Sized {
/// - `#[clap(flatten)] Variant(SubCmd)`: Attribute can only be used with enum variants that impl
/// `Subcommand`.
///
-/// See the
-/// [derive reference](https://github.com/clap-rs/clap/blob/v3.2.5/examples/derive_ref/README.md)
-/// for attributes and best practices.
+/// See the [derive reference](crate::_derive) for attributes and best practices.
///
-/// **NOTE:** Deriving requires the `derive` feature flag
+/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features]
///
/// # Example
///
@@ -460,11 +454,9 @@ pub trait Subcommand: FromArgMatches + Sized {
/// - Call [`Arg::possible_values`][crate::Arg::possible_values]
/// - Allowing using the `#[clap(default_value_t)]` attribute without implementing `Display`.
///
-/// See the
-/// [derive reference](https://github.com/clap-rs/clap/blob/v3.2.5/examples/derive_ref/README.md)
-/// for attributes and best practices.
+/// See the [derive reference](crate::_derive) for attributes and best practices.
///
-/// **NOTE:** Deriving requires the `derive` feature flag
+/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features]
///
/// # Example
///
diff --git a/vendor/clap/src/error/kind.rs b/vendor/clap/src/error/kind.rs
index 21256609a..4c3dc48b0 100644
--- a/vendor/clap/src/error/kind.rs
+++ b/vendor/clap/src/error/kind.rs
@@ -407,7 +407,7 @@ impl ErrorKind {
Self::UnrecognizedSubcommand => Some("A subcommand wasn't recognized"),
Self::EmptyValue => Some("An argument requires a value but none was supplied"),
Self::NoEquals => Some("Equal is needed when assigning values to one of the arguments"),
- Self::ValueValidation => Some("Invalid for for one of the arguments"),
+ Self::ValueValidation => Some("Invalid value for one of the arguments"),
Self::TooManyValues => Some("An argument received an unexpected value"),
Self::TooFewValues => Some("An argument requires more values"),
Self::TooManyOccurrences => Some("An argument occurred too many times"),
diff --git a/vendor/clap/src/error/mod.rs b/vendor/clap/src/error/mod.rs
index df9a84c56..fbd2b30a8 100644
--- a/vendor/clap/src/error/mod.rs
+++ b/vendor/clap/src/error/mod.rs
@@ -1147,12 +1147,7 @@ impl Display for Backtrace {
}
}
-#[cfg(test)]
-mod tests {
- /// Check `clap::Error` impls Send and Sync.
- mod clap_error_impl_send_sync {
- use crate::Error;
- trait Foo: std::error::Error + Send + Sync + 'static {}
- impl Foo for Error {}
- }
+#[test]
+fn check_auto_traits() {
+ static_assertions::assert_impl_all!(Error: Send, Sync, Unpin);
}
diff --git a/vendor/clap/src/lib.rs b/vendor/clap/src/lib.rs
index d9a97715f..5cefe6ec1 100644
--- a/vendor/clap/src/lib.rs
+++ b/vendor/clap/src/lib.rs
@@ -3,10 +3,79 @@
// (see LICENSE or <http://opensource.org/licenses/MIT>) All files in the project carrying such
// notice may not be copied, modified, or distributed except according to those terms.
+//! > **Command Line Argument Parser for Rust**
+//!
+//! Quick Links:
+//! - Derive [tutorial][_derive::_tutorial] and [reference][_derive]
+//! - Builder [tutorial][_tutorial] and [reference](index.html)
+//! - [Cookbook][_cookbook]
+//! - [FAQ][_faq]
+//! - [Discussions](https://github.com/clap-rs/clap/discussions)
+//!
+//! ## Aspirations
+//!
+//! - Out of the box, users get a polished CLI experience
+//! - Including common argument behavior, help generation, suggested fixes for users, colored output, [shell completions](https://github.com/clap-rs/clap/tree/master/clap_complete), etc
+//! - Flexible enough to port your existing CLI interface
+//! - However, we won't necessarily streamline support for each use case
+//! - Reasonable parse performance
+//! - Resilient maintainership, including
+//! - Willing to break compatibility rather than batching up breaking changes in large releases
+//! - Leverage feature flags to keep to one active branch
+//! - Being under [WG-CLI](https://github.com/rust-cli/team/) to increase the bus factor
+//! - We follow semver and will wait about 6-9 months between major breaking changes
+//! - We will support the last two minor Rust releases (MSRV, currently 1.56.1)
+//!
+//! While these aspirations can be at odds with fast build times and low binary
+//! size, we will still strive to keep these reasonable for the flexibility you
+//! get. Check out the
+//! [argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs) for
+//! CLI parsers optimized for other use cases.
+//!
+//! ## Example
+//!
+//! Run
+//! ```console
+//! $ cargo add clap --features derive
+//! ```
+//! *(See also [feature flag reference][_features])*
+//!
+//! Then define your CLI in `main.rs`:
+#![cfg_attr(not(feature = "derive"), doc = " ```ignore")]
+#![cfg_attr(feature = "derive", doc = " ```no_run")]
+#![doc = include_str!("../examples/demo.rs")]
+//! ```
+//!
+//! And try it out:
+#![doc = include_str!("../examples/demo.md")]
+//!
+//! See also the derive [tutorial][_derive::_tutorial] and [reference][_derive]
+//!
+//! ### Related Projects
+//!
+//! Augment clap:
+//! - [wild](https://crates.io/crates/wild) for supporting wildcards (`*`) on Windows like you do Linux
+//! - [argfile](https://crates.io/crates/argfile) for loading additional arguments from a file (aka response files)
+//! - [shadow-rs](https://crates.io/crates/shadow-rs) for generating `Command::long_version`
+//! - [clap_mangen](https://crates.io/crates/clap_mangen) for generating man page source (roff)
+//! - [clap_complete](https://crates.io/crates/clap_complete) for shell completion support
+//!
+//! CLI Helpers
+//! - [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag)
+//! - [clap-cargo](https://crates.io/crates/clap-cargo)
+//! - [concolor-clap](https://crates.io/crates/concolor-clap)
+//!
+//! Testing
+//! - [`trycmd`](https://crates.io/crates/trycmd): Bulk snapshot testing
+//! - [`snapbox`](https://crates.io/crates/snapbox): Specialized snapshot testing
+//! - [`assert_cmd`](https://crates.io/crates/assert_cmd) and [`assert_fs`](https://crates.io/crates/assert_fs): Customized testing
+//!
+//! Documentation:
+//! - [Command-line Apps for Rust](https://rust-cli.github.io/book/index.html) book
+//!
+
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")]
-#![cfg_attr(feature = "derive", doc = include_str!("../README.md"))]
-//! <https://github.com/clap-rs/clap>
#![warn(
missing_docs,
missing_debug_implementations,
@@ -82,9 +151,23 @@ pub use Parser as StructOpt;
)]
pub use ValueEnum as ArgEnum;
-#[cfg(any(feature = "derive", feature = "cargo"))]
+#[cfg(feature = "unstable-doc")]
+pub mod _cookbook;
+#[cfg(feature = "unstable-doc")]
+pub mod _derive;
+#[cfg(feature = "unstable-doc")]
+pub mod _faq;
+#[cfg(feature = "unstable-doc")]
+pub mod _features;
+#[cfg(feature = "unstable-doc")]
+pub mod _tutorial;
+
#[doc(hidden)]
-pub use once_cell;
+pub mod __macro_refs {
+ #[cfg(any(feature = "derive", feature = "cargo"))]
+ #[doc(hidden)]
+ pub use once_cell;
+}
#[macro_use]
#[allow(missing_docs)]
diff --git a/vendor/clap/src/macros.rs b/vendor/clap/src/macros.rs
index 0b671a37a..1f9167408 100644
--- a/vendor/clap/src/macros.rs
+++ b/vendor/clap/src/macros.rs
@@ -20,7 +20,7 @@ macro_rules! load_yaml {
#[macro_export]
#[cfg_attr(
feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::value_of_t`")
+ deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`")
)]
#[doc(hidden)]
macro_rules! value_t {
@@ -36,10 +36,7 @@ macro_rules! value_t {
#[macro_export]
#[cfg_attr(
feature = "deprecated",
- deprecated(
- since = "3.0.0",
- note = "Replaced with `ArgMatches::value_of_t_or_exit`"
- )
+ deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`")
)]
#[doc(hidden)]
macro_rules! value_t_or_exit {
@@ -55,7 +52,7 @@ macro_rules! value_t_or_exit {
#[macro_export]
#[cfg_attr(
feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::values_of_t`")
+ deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`")
)]
#[doc(hidden)]
macro_rules! values_t {
@@ -71,10 +68,7 @@ macro_rules! values_t {
#[macro_export]
#[cfg_attr(
feature = "deprecated",
- deprecated(
- since = "3.0.0",
- note = "Replaced with `ArgMatches::values_of_t_or_exit`"
- )
+ deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`")
)]
#[doc(hidden)]
macro_rules! values_t_or_exit {
@@ -88,7 +82,7 @@ macro_rules! values_t_or_exit {
#[cfg_attr(
feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `ArgEnum`")
+ deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`")
)]
#[doc(hidden)]
#[macro_export]
@@ -101,7 +95,7 @@ macro_rules! _clap_count_exprs {
/// Deprecated, replaced with [`ArgEnum`][crate::ArgEnum]
#[cfg_attr(
feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `ArgEnum`")
+ deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`")
)]
#[doc(hidden)]
#[macro_export]
@@ -256,8 +250,10 @@ macro_rules! crate_version {
#[macro_export]
macro_rules! crate_authors {
($sep:expr) => {{
- static CACHED: clap::once_cell::sync::Lazy<String> =
- clap::once_cell::sync::Lazy::new(|| env!("CARGO_PKG_AUTHORS").replace(':', $sep));
+ static CACHED: clap::__macro_refs::once_cell::sync::Lazy<String> =
+ clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ env!("CARGO_PKG_AUTHORS").replace(':', $sep)
+ });
let s: &'static str = &*CACHED;
s
diff --git a/vendor/clap/src/output/usage.rs b/vendor/clap/src/output/usage.rs
index 7adaf58c6..6f7a2cad4 100644
--- a/vendor/clap/src/output/usage.rs
+++ b/vendor/clap/src/output/usage.rs
@@ -382,73 +382,64 @@ impl<'help, 'cmd> Usage<'help, 'cmd> {
unrolled_reqs
);
- let args_in_groups = self
- .cmd
- .get_groups()
- .filter(|gn| required.contains(&gn.id))
- .flat_map(|g| self.cmd.unroll_args_in_group(&g.id))
- .collect::<Vec<_>>();
-
- for a in unrolled_reqs
- .iter()
- .chain(incls.iter())
- .filter(|name| !self.cmd.get_positionals().any(|p| &&p.id == name))
- .filter(|name| !self.cmd.get_groups().any(|g| &&g.id == name))
- .filter(|name| !args_in_groups.contains(name))
- .filter(|name| {
- !(matcher.is_some()
- && matcher
- .as_ref()
- .unwrap()
- .check_explicit(name, ArgPredicate::IsPresent))
- })
- {
- debug!("Usage::get_required_usage_from:iter:{:?}", a);
- let arg = self.cmd.find(a).expect(INTERNAL_ERROR_MSG).to_string();
- ret_val.insert(arg);
- }
- let mut g_vec: Vec<String> = vec![];
- for g in unrolled_reqs
- .iter()
- .filter(|n| self.cmd.get_groups().any(|g| g.id == **n))
- {
- // don't print requirement for required groups that have an arg.
- if let Some(m) = matcher {
- let have_group_entry = self
- .cmd
- .unroll_args_in_group(g)
- .iter()
- .any(|arg| m.check_explicit(arg, ArgPredicate::IsPresent));
- if have_group_entry {
- continue;
+ let mut required_groups_members = IndexSet::new();
+ let mut required_opts = IndexSet::new();
+ let mut required_groups = IndexSet::new();
+ let mut required_positionals = Vec::new();
+ for req in unrolled_reqs.iter().chain(incls.iter()) {
+ if let Some(arg) = self.cmd.find(req) {
+ let is_present = matcher
+ .map(|m| m.check_explicit(req, ArgPredicate::IsPresent))
+ .unwrap_or(false);
+ debug!(
+ "Usage::get_required_usage_from:iter:{:?} arg is_present={}",
+ req, is_present
+ );
+ if !is_present {
+ if arg.is_positional() {
+ if incl_last || !arg.is_last_set() {
+ required_positionals.push((arg.index.unwrap(), arg.to_string()));
+ }
+ } else {
+ required_opts.insert(arg.to_string());
+ }
+ }
+ } else {
+ debug_assert!(self.cmd.find_group(req).is_some());
+ let group_members = self.cmd.unroll_args_in_group(req);
+ let is_present = matcher
+ .map(|m| {
+ group_members
+ .iter()
+ .any(|arg| m.check_explicit(arg, ArgPredicate::IsPresent))
+ })
+ .unwrap_or(false);
+ debug!(
+ "Usage::get_required_usage_from:iter:{:?} group is_present={}",
+ req, is_present
+ );
+ if !is_present {
+ let elem = self.cmd.format_group(req);
+ required_groups.insert(elem);
+ required_groups_members.extend(
+ group_members
+ .iter()
+ .flat_map(|id| self.cmd.find(id))
+ .map(|arg| arg.to_string()),
+ );
}
- }
-
- let elem = self.cmd.format_group(g);
- if !g_vec.contains(&elem) {
- g_vec.push(elem);
}
}
- ret_val.extend(g_vec);
- let mut pvec = unrolled_reqs
- .iter()
- .chain(incls.iter())
- .filter(|a| self.cmd.get_positionals().any(|p| &&p.id == a))
- .filter(|&pos| {
- matcher.map_or(true, |m| !m.check_explicit(pos, ArgPredicate::IsPresent))
- })
- .filter_map(|pos| self.cmd.find(pos))
- .filter(|&pos| incl_last || !pos.is_last_set())
- .filter(|pos| !args_in_groups.contains(&pos.id))
- .map(|pos| (pos.index.unwrap(), pos))
- .collect::<Vec<(usize, &Arg)>>();
- pvec.sort_by_key(|(ind, _)| *ind); // sort by index
-
- for (_, p) in pvec {
- debug!("Usage::get_required_usage_from:push:{:?}", p.id);
- if !args_in_groups.contains(&p.id) {
- ret_val.insert(p.to_string());
+ required_opts.retain(|arg| !required_groups_members.contains(arg));
+ ret_val.extend(required_opts);
+
+ ret_val.extend(required_groups);
+
+ required_positionals.sort_by_key(|(ind, _)| *ind); // sort by index
+ for (_, p) in required_positionals {
+ if !required_groups_members.contains(&p) {
+ ret_val.insert(p);
}
}
diff --git a/vendor/clap/src/parser/arg_matcher.rs b/vendor/clap/src/parser/arg_matcher.rs
index 8d15c5799..22087e722 100644
--- a/vendor/clap/src/parser/arg_matcher.rs
+++ b/vendor/clap/src/parser/arg_matcher.rs
@@ -74,9 +74,7 @@ impl ArgMatcher {
// a default value of `other` myprog would have an existing MatchedArg for
// `--global-arg` where the value is `other`
let to_update = if let Some(parent_ma) = vals_map.get(global_arg) {
- if parent_ma.check_explicit(ArgPredicate::IsPresent)
- && !ma.check_explicit(ArgPredicate::IsPresent)
- {
+ if parent_ma.source() > ma.source() {
parent_ma
} else {
ma
diff --git a/vendor/clap/src/parser/error.rs b/vendor/clap/src/parser/error.rs
index bdafa9ae5..caeba4b8f 100644
--- a/vendor/clap/src/parser/error.rs
+++ b/vendor/clap/src/parser/error.rs
@@ -54,3 +54,14 @@ impl std::fmt::Display for MatchesError {
}
}
}
+
+#[test]
+fn check_auto_traits() {
+ static_assertions::assert_impl_all!(
+ MatchesError: Send,
+ Sync,
+ std::panic::RefUnwindSafe,
+ std::panic::UnwindSafe,
+ Unpin
+ );
+}
diff --git a/vendor/clap/src/parser/matches/arg_matches.rs b/vendor/clap/src/parser/matches/arg_matches.rs
index 17fa63ca6..2585c0219 100644
--- a/vendor/clap/src/parser/matches/arg_matches.rs
+++ b/vendor/clap/src/parser/matches/arg_matches.rs
@@ -119,6 +119,69 @@ impl ArgMatches {
MatchesError::unwrap(&internal_id, self.try_get_one(id))
}
+ /// Gets the value of a specific [`ArgAction::Count`][crate::ArgAction::Count] flag
+ ///
+ /// # Panic
+ ///
+ /// If the argument's action is not [`ArgAction::Count`][crate::ArgAction::Count]
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use clap::Command;
+ /// # use clap::Arg;
+ /// let cmd = Command::new("mycmd")
+ /// .arg(
+ /// Arg::new("flag")
+ /// .long("flag")
+ /// .action(clap::ArgAction::Count)
+ /// );
+ ///
+ /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
+ /// assert_eq!(
+ /// matches.get_count("flag"),
+ /// 2
+ /// );
+ /// ```
+ #[track_caller]
+ pub fn get_count(&self, id: &str) -> u8 {
+ *self
+ .get_one::<u8>(id)
+ .expect("ArgAction::Count is defaulted")
+ }
+
+ /// Gets the value of a specific [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] flag
+ ///
+ /// # Panic
+ ///
+ /// If the argument's action is not [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse]
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use clap::Command;
+ /// # use clap::Arg;
+ /// let cmd = Command::new("mycmd")
+ /// .arg(
+ /// Arg::new("flag")
+ /// .long("flag")
+ /// .action(clap::ArgAction::SetTrue)
+ /// );
+ ///
+ /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
+ /// assert!(matches.contains_id("flag"));
+ /// assert_eq!(
+ /// matches.get_flag("flag"),
+ /// true
+ /// );
+ /// ```
+ #[track_caller]
+ pub fn get_flag(&self, id: &str) -> bool {
+ *self
+ .get_one::<bool>(id)
+ .expect("ArgAction::SetTrue / ArgAction::SetFalse is defaulted")
+ }
+
/// Iterate over values of a specific option or positional argument.
///
/// i.e. an argument that takes multiple values at runtime.
@@ -604,13 +667,13 @@ impl ArgMatches {
value.and_then(MatchedArg::source)
}
- /// Deprecated, replaced with [`ArgAction::Count`][crate::ArgAction] or
- /// [`ArgMatches::get_many`]`.len()`.
+ /// Deprecated, replaced with [`ArgAction::Count`][crate::ArgAction],
+ /// [`ArgMatches::get_many`]`.len()`, or [`ArgMatches::value_source`].
#[cfg_attr(
feature = "deprecated",
deprecated(
since = "3.2.0",
- note = "Replaced with either `ArgAction::Count` or `ArgMatches::get_many(...).len()`"
+ note = "Replaced with either `ArgAction::Count`, `ArgMatches::get_many(...).len()`, or `ArgMatches::value_source`"
)
)]
#[cfg_attr(debug_assertions, track_caller)]
@@ -1742,6 +1805,11 @@ mod tests {
use super::*;
#[test]
+ fn check_auto_traits() {
+ static_assertions::assert_impl_all!(ArgMatches: Send, Sync, Unpin);
+ }
+
+ #[test]
fn test_default_values() {
#![allow(deprecated)]
let mut values: Values = Values::default();
diff --git a/vendor/clap/src/parser/parser.rs b/vendor/clap/src/parser/parser.rs
index fc95dad22..ad2bc6e9c 100644
--- a/vendor/clap/src/parser/parser.rs
+++ b/vendor/clap/src/parser/parser.rs
@@ -98,77 +98,6 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
arg_os.to_value_os().as_raw_bytes()
);
- // Correct pos_counter.
- pos_counter = {
- let is_second_to_last = pos_counter + 1 == positional_count;
-
- // The last positional argument, or second to last positional
- // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)`
- let low_index_mults = is_second_to_last
- && self
- .cmd
- .get_positionals()
- .any(|a| a.is_multiple() && (positional_count != a.index.unwrap_or(0)))
- && self
- .cmd
- .get_positionals()
- .last()
- .map_or(false, |p_name| !p_name.is_last_set());
-
- let missing_pos = self.cmd.is_allow_missing_positional_set()
- && is_second_to_last
- && !trailing_values;
-
- debug!(
- "Parser::get_matches_with: Positional counter...{}",
- pos_counter
- );
- debug!(
- "Parser::get_matches_with: Low index multiples...{:?}",
- low_index_mults
- );
-
- if low_index_mults || missing_pos {
- let skip_current = if let Some(n) = raw_args.peek(&args_cursor) {
- if let Some(arg) = self
- .cmd
- .get_positionals()
- .find(|a| a.index == Some(pos_counter))
- {
- // If next value looks like a new_arg or it's a
- // subcommand, skip positional argument under current
- // pos_counter(which means current value cannot be a
- // positional argument with a value next to it), assume
- // current value matches the next arg.
- self.is_new_arg(&n, arg)
- || self
- .possible_subcommand(n.to_value(), valid_arg_found)
- .is_some()
- } else {
- true
- }
- } else {
- true
- };
-
- if skip_current {
- debug!("Parser::get_matches_with: Bumping the positional counter...");
- pos_counter + 1
- } else {
- pos_counter
- }
- } else if trailing_values
- && (self.cmd.is_allow_missing_positional_set() || contains_last)
- {
- // Came to -- and one positional has .last(true) set, so we go immediately
- // to the last (highest index) positional
- debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
- positional_count
- } else {
- pos_counter
- }
- };
-
// Has the user already passed '--'? Meaning only positional args follow
if !trailing_values {
if self.cmd.is_subcommand_precedence_over_arg_set()
@@ -376,6 +305,77 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
}
}
+ // Correct pos_counter.
+ pos_counter = {
+ let is_second_to_last = pos_counter + 1 == positional_count;
+
+ // The last positional argument, or second to last positional
+ // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)`
+ let low_index_mults = is_second_to_last
+ && self
+ .cmd
+ .get_positionals()
+ .any(|a| a.is_multiple() && (positional_count != a.index.unwrap_or(0)))
+ && self
+ .cmd
+ .get_positionals()
+ .last()
+ .map_or(false, |p_name| !p_name.is_last_set());
+
+ let missing_pos = self.cmd.is_allow_missing_positional_set()
+ && is_second_to_last
+ && !trailing_values;
+
+ debug!(
+ "Parser::get_matches_with: Positional counter...{}",
+ pos_counter
+ );
+ debug!(
+ "Parser::get_matches_with: Low index multiples...{:?}",
+ low_index_mults
+ );
+
+ if low_index_mults || missing_pos {
+ let skip_current = if let Some(n) = raw_args.peek(&args_cursor) {
+ if let Some(arg) = self
+ .cmd
+ .get_positionals()
+ .find(|a| a.index == Some(pos_counter))
+ {
+ // If next value looks like a new_arg or it's a
+ // subcommand, skip positional argument under current
+ // pos_counter(which means current value cannot be a
+ // positional argument with a value next to it), assume
+ // current value matches the next arg.
+ self.is_new_arg(&n, arg)
+ || self
+ .possible_subcommand(n.to_value(), valid_arg_found)
+ .is_some()
+ } else {
+ true
+ }
+ } else {
+ true
+ };
+
+ if skip_current {
+ debug!("Parser::get_matches_with: Bumping the positional counter...");
+ pos_counter + 1
+ } else {
+ pos_counter
+ }
+ } else if trailing_values
+ && (self.cmd.is_allow_missing_positional_set() || contains_last)
+ {
+ // Came to -- and one positional has .last(true) set, so we go immediately
+ // to the last (highest index) positional
+ debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
+ positional_count
+ } else {
+ pos_counter
+ }
+ };
+
if let Some(arg) = self.cmd.get_keymap().get(&pos_counter) {
if arg.is_last_set() && !trailing_values {
let _ = self.resolve_pending(matcher);
@@ -738,8 +738,10 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
}
};
if long_arg.is_empty() {
- debug_assert!(long_value.is_none(), "{:?}", long_value);
- return Ok(ParseResult::NoArg);
+ debug_assert!(
+ long_value.is_some(),
+ "`--` should be filtered out before this point"
+ );
}
let arg = if let Some(arg) = self.cmd.get_keymap().get(long_arg) {
diff --git a/vendor/clap_derive/.cargo-checksum.json b/vendor/clap_derive/.cargo-checksum.json
index 8d3303f99..1dfa35a62 100644
--- a/vendor/clap_derive/.cargo-checksum.json
+++ b/vendor/clap_derive/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"29d214d0c807739f6d147a1a472dfab5d929b4dd31623f670df28a713be107e8","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"d99fca4ba5976a41b150cd7f5c17100e0d275b9bf48b51a0d964115dc81e20b9","src/attrs.rs":"dd4288ac38aeb184bbffade71af48706034f10d311068af2917c0f96d813698a","src/derives/args.rs":"27a13d33f24f7f7668c82fa653978e909514bd39e808c7996fddb0d3a3c0e570","src/derives/into_app.rs":"02c36d403ad35e3d49de6042cacecf2a724561b5e3948b5aec4b45646e031877","src/derives/mod.rs":"ff7947fddee4b3d8365e29459a02458382e13df022aee822e09bce1ac255d3bb","src/derives/parser.rs":"9ca609e6e5bfb303e22b4ecb8aca9035571179920b0df91031e9f987559252e0","src/derives/subcommand.rs":"0513c48013c2bd9f450ffc7bfcbf84b3a3290e37ff571dd070798356c2b291ac","src/derives/value_enum.rs":"27b87ccb6829925f6ffa631109217bffd81b74f61519841678bd6d8c5cfcbe40","src/dummies.rs":"02f111bbd84b8f0525faeb9189c59cb2fd2df05ae6c7b014735c82feac5ff23f","src/lib.rs":"e4be47e8db06a6555a2a4cd1802d17c16a3b51ae0ec291b3ec75ef2b6517eb0e","src/parse.rs":"f0d720da5477755bdce02fcd248a57efe74b2fbbc5e07c5dc17d9bf78b017958","src/utils/doc_comments.rs":"386859b274fd1e298aeaeafd2b20764db0957cbb4e6c9e8bab52a506a0b8ecda","src/utils/mod.rs":"ee28526587d2d80d5dba162f28191f44f6a0c296d0e52225eb74b90534d49b25","src/utils/spanned.rs":"e93600124c54985533f74fe23f096f4ada94b310eff97a16f0ce40fb0f690a3b","src/utils/ty.rs":"0a9b8c5dabfa28388b60423f4b6075a275b347258ac35301997cb0d7f763607f"},"package":"c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9"} \ No newline at end of file
+{"files":{"Cargo.toml":"eaf10a4c685b527f604ea9f84fbe7095e15fe4424225c57481d0555a89dfb054","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"0d687e1f07b58fe68bda74668ff6326125e5e5efa184cce755cd84ac535b7058","README.md":"4ec07b9c59a2ddcedcdc9d21d51c147b18157794b03ff2ea5ae57f2b5236943d","src/attrs.rs":"1c95a75fd377d19587f429d3f51544ac0ca96f868cce4ffe12d1163f7465fa73","src/derives/args.rs":"27a13d33f24f7f7668c82fa653978e909514bd39e808c7996fddb0d3a3c0e570","src/derives/into_app.rs":"02c36d403ad35e3d49de6042cacecf2a724561b5e3948b5aec4b45646e031877","src/derives/mod.rs":"ff7947fddee4b3d8365e29459a02458382e13df022aee822e09bce1ac255d3bb","src/derives/parser.rs":"9ca609e6e5bfb303e22b4ecb8aca9035571179920b0df91031e9f987559252e0","src/derives/subcommand.rs":"0513c48013c2bd9f450ffc7bfcbf84b3a3290e37ff571dd070798356c2b291ac","src/derives/value_enum.rs":"4d0958d3a767c82f2366d8fda20367c5aa033af616d09ef581e8abdb2e029a70","src/dummies.rs":"02f111bbd84b8f0525faeb9189c59cb2fd2df05ae6c7b014735c82feac5ff23f","src/lib.rs":"e4be47e8db06a6555a2a4cd1802d17c16a3b51ae0ec291b3ec75ef2b6517eb0e","src/parse.rs":"ceaac282cabccfac5bcf56ce02095c9acbf00dbfdd3c3009fa58e87bdde46218","src/utils/doc_comments.rs":"386859b274fd1e298aeaeafd2b20764db0957cbb4e6c9e8bab52a506a0b8ecda","src/utils/mod.rs":"ee28526587d2d80d5dba162f28191f44f6a0c296d0e52225eb74b90534d49b25","src/utils/spanned.rs":"e93600124c54985533f74fe23f096f4ada94b310eff97a16f0ce40fb0f690a3b","src/utils/ty.rs":"0a9b8c5dabfa28388b60423f4b6075a275b347258ac35301997cb0d7f763607f"},"package":"ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"} \ No newline at end of file
diff --git a/vendor/clap_derive/Cargo.toml b/vendor/clap_derive/Cargo.toml
index 49e3fd963..f74476e68 100644
--- a/vendor/clap_derive/Cargo.toml
+++ b/vendor/clap_derive/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2021"
-rust-version = "1.56.0"
+rust-version = "1.56.1"
name = "clap_derive"
-version = "3.2.5"
+version = "3.2.18"
include = [
"build.rs",
"src/**/*",
@@ -24,7 +24,6 @@ include = [
"examples/**/*",
]
description = "Parse command line argument by defining a struct, derive crate."
-documentation = "https://docs.rs/clap_derive"
readme = "README.md"
keywords = [
"clap",
diff --git a/vendor/clap_derive/LICENSE-MIT b/vendor/clap_derive/LICENSE-MIT
index 5acedf041..7b05b8453 100644
--- a/vendor/clap_derive/LICENSE-MIT
+++ b/vendor/clap_derive/LICENSE-MIT
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015-2016 Kevin B. Knapp
+Copyright (c) 2015-2022 Kevin B. Knapp and Clap Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/clap_derive/README.md b/vendor/clap_derive/README.md
index 1acadb355..17f649eda 100644
--- a/vendor/clap_derive/README.md
+++ b/vendor/clap_derive/README.md
@@ -3,8 +3,8 @@
Macro implementation for clap's derives.
[docs.rs](https://docs.rs/clap)
-- [Derive Tutorial](https://github.com/clap-rs/clap/blob/v3.2.5/examples/tutorial_derive/README.md)
-- [Derive Reference](https://github.com/clap-rs/clap/blob/v3.2.5/examples/derive_ref/README.md)
+- [Derive Tutorial](https://github.com/clap-rs/clap/blob/v3.2.18/examples/tutorial_derive/README.md)
+- [Derive Reference](https://github.com/clap-rs/clap/blob/v3.2.18/examples/derive_ref/README.md)
## License
diff --git a/vendor/clap_derive/src/attrs.rs b/vendor/clap_derive/src/attrs.rs
index 3c685fbe8..2c5b47d95 100644
--- a/vendor/clap_derive/src/attrs.rs
+++ b/vendor/clap_derive/src/attrs.rs
@@ -450,7 +450,7 @@ impl Attrs {
}
fn push_method(&mut self, name: Ident, arg: impl ToTokens) {
- if name == "name" {
+ if name == "name" || name == "id" {
self.name = Name::Assigned(quote!(#arg));
} else if name == "value_parser" {
self.value_parser = Some(ValueParser::Explicit(Method::new(name, quote!(#arg))));
@@ -552,7 +552,7 @@ impl Attrs {
})
} else {
quote_spanned!(ident.span()=> {
- static DEFAULT_VALUE: clap::once_cell::sync::Lazy<String> = clap::once_cell::sync::Lazy::new(|| {
+ static DEFAULT_VALUE: clap::__macro_refs::once_cell::sync::Lazy<String> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
let val: #ty = #val;
::std::string::ToString::to_string(&val)
});
@@ -564,6 +564,81 @@ impl Attrs {
self.methods.push(Method::new(raw_ident, val));
}
+ DefaultValuesT(ident, expr) => {
+ let ty = if let Some(ty) = self.ty.as_ref() {
+ ty
+ } else {
+ abort!(
+ ident,
+ "#[clap(default_values_t)] (without an argument) can be used \
+ only on field level";
+
+ note = "see \
+ https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
+ };
+
+ let container_type = Ty::from_syn_ty(ty);
+ if *container_type != Ty::Vec {
+ abort!(
+ ident,
+ "#[clap(default_values_t)] can be used only on Vec types";
+
+ note = "see \
+ https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
+ }
+ let inner_type = inner_type(ty);
+
+ // Use `Borrow<#inner_type>` so we accept `&Vec<#inner_type>` and
+ // `Vec<#inner_type>`.
+ let val = if parsed.iter().any(|a| matches!(a, ValueEnum(_))) {
+ quote_spanned!(ident.span()=> {
+ {
+ fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> Vec<&'static str>
+ where
+ T: ::std::borrow::Borrow<#inner_type>
+ {
+ iterable
+ .into_iter()
+ .map(|val| {
+ clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name()
+ })
+ .collect()
+
+ }
+
+ static DEFAULT_VALUES: clap::__macro_refs::once_cell::sync::Lazy<Vec<&str>> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ iter_to_vals(#expr)
+ });
+ &*DEFAULT_VALUES.as_slice()
+ }
+ })
+ } else {
+ quote_spanned!(ident.span()=> {
+ {
+ fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> Vec<String>
+ where
+ T: ::std::borrow::Borrow<#inner_type>
+ {
+ iterable.into_iter().map(|val| val.borrow().to_string()).collect()
+
+ }
+
+ static DEFAULT_STRINGS: clap::__macro_refs::once_cell::sync::Lazy<Vec<::std::string::String>> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ iter_to_vals(#expr)
+ });
+
+ static DEFAULT_VALUES: clap::__macro_refs::once_cell::sync::Lazy<Vec<&str>> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ DEFAULT_STRINGS.iter().map(::std::string::String::as_str).collect()
+ });
+ &*DEFAULT_VALUES.as_slice()
+ }
+ })
+ };
+
+ self.methods
+ .push(Method::new(Ident::new("default_values", ident.span()), val));
+ }
+
DefaultValueOsT(ident, expr) => {
let ty = if let Some(ty) = self.ty.as_ref() {
ty
@@ -592,7 +667,7 @@ impl Attrs {
})
} else {
quote_spanned!(ident.span()=> {
- static DEFAULT_VALUE: clap::once_cell::sync::Lazy<::std::ffi::OsString> = clap::once_cell::sync::Lazy::new(|| {
+ static DEFAULT_VALUE: clap::__macro_refs::once_cell::sync::Lazy<::std::ffi::OsString> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
let val: #ty = #val;
::std::ffi::OsString::from(val)
});
@@ -604,6 +679,84 @@ impl Attrs {
self.methods.push(Method::new(raw_ident, val));
}
+ DefaultValuesOsT(ident, expr) => {
+ let ty = if let Some(ty) = self.ty.as_ref() {
+ ty
+ } else {
+ abort!(
+ ident,
+ "#[clap(default_values_os_t)] (without an argument) can be used \
+ only on field level";
+
+ note = "see \
+ https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
+ };
+
+ let container_type = Ty::from_syn_ty(ty);
+ if *container_type != Ty::Vec {
+ abort!(
+ ident,
+ "#[clap(default_values_os_t)] can be used only on Vec types";
+
+ note = "see \
+ https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
+ }
+ let inner_type = inner_type(ty);
+
+ // Use `Borrow<#inner_type>` so we accept `&Vec<#inner_type>` and
+ // `Vec<#inner_type>`.
+ let val = if parsed.iter().any(|a| matches!(a, ValueEnum(_))) {
+ quote_spanned!(ident.span()=> {
+ {
+ fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> Vec<&'static ::std::ffi::OsStr>
+ where
+ T: ::std::borrow::Borrow<#inner_type>
+ {
+ iterable
+ .into_iter()
+ .map(|val| {
+ clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name()
+ })
+ .map(::std::ffi::OsStr::new)
+ .collect()
+
+ }
+
+ static DEFAULT_VALUES: clap::__macro_refs::once_cell::sync::Lazy<Vec<&::std::ffi::OsStr>> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ iter_to_vals(#expr)
+ });
+ &*DEFAULT_VALUES.as_slice()
+ }
+ })
+ } else {
+ quote_spanned!(ident.span()=> {
+ {
+ fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> Vec<::std::ffi::OsString>
+ where
+ T: ::std::borrow::Borrow<#inner_type>
+ {
+ iterable.into_iter().map(|val| val.borrow().into()).collect()
+
+ }
+
+ static DEFAULT_OS_STRINGS: clap::__macro_refs::once_cell::sync::Lazy<Vec<::std::ffi::OsString>> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ iter_to_vals(#expr)
+ });
+
+ static DEFAULT_VALUES: clap::__macro_refs::once_cell::sync::Lazy<Vec<&::std::ffi::OsStr>> = clap::__macro_refs::once_cell::sync::Lazy::new(|| {
+ DEFAULT_OS_STRINGS.iter().map(::std::ffi::OsString::as_os_str).collect()
+ });
+ &*DEFAULT_VALUES.as_slice()
+ }
+ })
+ };
+
+ self.methods.push(Method::new(
+ Ident::new("default_values_os", ident.span()),
+ val,
+ ));
+ }
+
NextDisplayOrder(ident, expr) => {
self.next_display_order = Some(Method::new(ident, quote!(#expr)));
}
diff --git a/vendor/clap_derive/src/derives/value_enum.rs b/vendor/clap_derive/src/derives/value_enum.rs
index b18b665c4..06d514f0e 100644
--- a/vendor/clap_derive/src/derives/value_enum.rs
+++ b/vendor/clap_derive/src/derives/value_enum.rs
@@ -84,7 +84,7 @@ fn lits(
None
} else {
if !matches!(variant.fields, Fields::Unit) {
- abort!(variant.span(), "`#[derive(ValueEnum)]` only supports non-unit variants, unless they are skipped");
+ abort!(variant.span(), "`#[derive(ValueEnum)]` only supports unit variants. Non-unit variants must be skipped");
}
let fields = attrs.field_methods(false);
let name = attrs.cased_name();
diff --git a/vendor/clap_derive/src/parse.rs b/vendor/clap_derive/src/parse.rs
index 253736cfd..7d7e19cdc 100644
--- a/vendor/clap_derive/src/parse.rs
+++ b/vendor/clap_derive/src/parse.rs
@@ -53,7 +53,9 @@ pub enum ClapAttr {
// ident = arbitrary_expr
NameExpr(Ident, Expr),
DefaultValueT(Ident, Option<Expr>),
+ DefaultValuesT(Ident, Expr),
DefaultValueOsT(Ident, Option<Expr>),
+ DefaultValuesOsT(Ident, Expr),
NextDisplayOrder(Ident, Expr),
NextHelpHeading(Ident, Expr),
HelpHeading(Ident, Expr),
@@ -122,7 +124,9 @@ impl Parse for ClapAttr {
Ok(expr) => match &*name_str {
"skip" => Ok(Skip(name, Some(expr))),
"default_value_t" => Ok(DefaultValueT(name, Some(expr))),
+ "default_values_t" => Ok(DefaultValuesT(name, expr)),
"default_value_os_t" => Ok(DefaultValueOsT(name, Some(expr))),
+ "default_values_os_t" => Ok(DefaultValuesOsT(name, expr)),
"next_display_order" => Ok(NextDisplayOrder(name, expr)),
"next_help_heading" => Ok(NextHelpHeading(name, expr)),
"help_heading" => Ok(HelpHeading(name, expr)),
diff --git a/vendor/compiler_builtins/.cargo-checksum.json b/vendor/compiler_builtins/.cargo-checksum.json
index 9324f092f..3310b9b76 100644
--- a/vendor/compiler_builtins/.cargo-checksum.json
+++ b/vendor/compiler_builtins/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.lock":"b369bba03aca1dd529671fb54000fd8dfc0d4d5b5cfe1afe71294155c974bc34","Cargo.toml":"1f727cb37da8b846367a12e034c01aca729f745a695383dd596b05b7f86ba970","README.md":"5eb36fbab30693dbbe9f0de54749c95bd06fd6e42013b5b9eff3c062b9fdd34f","build.rs":"991919d9ab1eca85e87a85acafcb86d4880f1afe9fe35d6bd87039dcb1fa9aa7","examples/intrinsics.rs":"a7aa69c17af3aa8f6edff32c214e80827d3cbe3aea386a2be42244444752d253","libm/src/math/acos.rs":"fb066ba84aba1372d706425ec14f35ff8d971756d15eeebd22ecf42a716493bb","libm/src/math/acosf.rs":"a112b82309bba1d35c4e3d6ad4d6c21ef305343d9ab601ddf4bc61d43bc9f1af","libm/src/math/acosh.rs":"56dac8538e4350cd7cf001327c89f087b68abb2e6aaad58edba8a094b09f6b0f","libm/src/math/acoshf.rs":"df5b0c4d8e37e64cf5ff2d8328b28bc35c78e84060ff769e64523ea9ff9065c1","libm/src/math/asin.rs":"095a1e98996daff45df0b154ca0ec35bbf31db964ee9fdda0207308cb20df441","libm/src/math/asinf.rs":"49cccb4db2881982643a4a7d5453f4f8daf527711bbb67313607a3c178856d61","libm/src/math/asinh.rs":"e8fc94031015fddf35e9c26b94da9f6431ee17c81cd7bd37da8ffc98f7e0b32c","libm/src/math/asinhf.rs":"8a0b8933a98a17617a66fef4c7b89eba645fdf05302000babf4a5a5f45328430","libm/src/math/atan.rs":"d4fe46e1c5739dd09997869dcfbc3c85f03c534af52e700d6c6bcf9c3fedda07","libm/src/math/atan2.rs":"2623bc8ca707d13a7092ce49adf68e9cbf4452ad1bf4a861dc40ca858606a747","libm/src/math/atan2f.rs":"dd01943e0e1f1955912e5c3ffc9467529cf64bd02ac0a6ad5ab31dbe6657f05d","libm/src/math/atanf.rs":"e41b41569474a59c970ede3538e00bda4072cf4d90040017101cc79d7dc28caa","libm/src/math/atanh.rs":"5934dbd6b7395ca4f103ace7598da723a9270e1cf6b47e7f786debe4bb3651ff","libm/src/math/atanhf.rs":"8ba4711dda19ef2dc33622be65c1483902868083543198c6bbd040d4026293de","libm/src/math/cbrt.rs":"f2c45612d2eecd93cfcdd9ebf824c754fc8f8dfd6d16862c0b9c4ccea78c2a0f","libm/src/math/cbrtf.rs":"ad0b483854aa9f17a44d36c049bf0e8ebab34c27e90b787c05f45cc230ec7d19","libm/src/math/ceil.rs":"57ba5b6e207a0ccbd34190d1aa544389ca12126be23821dfb5746497f620ce03","libm/src/math/ceilf.rs":"c922a0475a599b9ea5473e615f74700b99707cebd6927f24ea59cb2a3cb3bbc3","libm/src/math/copysign.rs":"d80c880efaf0cdf2ce0a4d4f5a68dd6c36c88d46fa997ec8ac8604bfdb26fa33","libm/src/math/copysignf.rs":"1547116071e68a42b1605eb2fc722db6466a34517dc96b92de1f29a274c3d8e3","libm/src/math/cos.rs":"74babdc13ede78e400c5ca1854c3e22d2e08cbdc5618aefa5bba6f9303ef65b6","libm/src/math/cosf.rs":"09c40f93c445b741e22477ceedf163ca33b6a47f973f7c9876cfba2692edb29c","libm/src/math/cosh.rs":"0d0a7cef18577f321996b8b87561963139f754ad7f2ea0a3b3883811f3f0693a","libm/src/math/coshf.rs":"be8ca8739e4cf1978425b349f941cb4838bba8c10cb559c7940b9fd4fdde21ad","libm/src/math/erf.rs":"9c55fc6756ba816996f0b585e07ccfa4cd87575ad525cd30c4a968b30acffda3","libm/src/math/erff.rs":"cb020e8bada9a54573a11fe3271750d73f14fed3092a881a9ceaf98fe32fd5a6","libm/src/math/exp.rs":"ca7405ad0d1993fffcf9aae96f9256307bed3c4916545aaebd1cf1d2df1807fa","libm/src/math/exp10.rs":"2deb037f88feac87a0e924b69dd496f0dd3b5d35f2a58e09d4c5166b207e517b","libm/src/math/exp10f.rs":"6979464dfe3f4f2da1f9afc909646499c4bfaef15e10a039384750e2f1586fea","libm/src/math/exp2.rs":"94a9304a2ce3bc81f6d2aefd3cde6faa30f13260d46cb13692863cdea1c9a3a1","libm/src/math/exp2f.rs":"785f2630accd35118ec07bf60273e219ed91a215b956b1552eeea5bc2a708cc8","libm/src/math/expf.rs":"ec14c18f891a9e37735ec39e6fc2e9bf674a2c2e083f22e2533b481177359c98","libm/src/math/expm1.rs":"124069f456c8ad331f265c7509d9e223b2a300e461bbfd3d6adfdcdd2ee5b8ac","libm/src/math/expm1f.rs":"18e2116d31ea8410051cc709b9d04b754b0e3ba6758ee1bf0b48749f4999b840","libm/src/math/expo2.rs":"4f4f9fecfccb43f30c2784aa7c0bb656754a52b8ab431f7d1b551c673ab133f1","libm/src/math/fabs.rs":"e6c7db39f98508098cdf64ac0c2f53866c466149a7490afb9fe22b44c4dd81b3","libm/src/math/fabsf.rs":"83a1f5f4d9ca899ba2b701d7332e18b40258b83e111db4c5d8fab2cc1be58aa3","libm/src/math/fdim.rs":"8ec091996005207297c2389ae563e1b18dbc6a9eac951de29a976c5cd7bc32a7","libm/src/math/fdimf.rs":"c7f3f2269834d55be26b6580ddc07c42531577955fa4de35bad1e2a361085614","libm/src/math/fenv.rs":"8730d45aa4c591f91dccdcc1ce533fa23e9c6df0c38defb9c57f749cb25e1cd0","libm/src/math/floor.rs":"5050804cae173af6775c0678d6c1aafb5ca2b744bc8a2f50d9d03b95dcee1fb0","libm/src/math/floorf.rs":"c903e0c57bc60a888c513eb7a873a87a4759ba68fc791b6b931652f8ee74cc03","libm/src/math/fma.rs":"d88e01c2c2d11333dd49b61166caa036ff5f08f3a8c5973b9e3c9574bf2eb675","libm/src/math/fmaf.rs":"3e0f5727e56f31218f674b9b8975d7e67b3a24a097f06a2a3eca9723cd786213","libm/src/math/fmax.rs":"f6c8e96a8b1a170648d2fa3513e7b6b459085d708c839869f82e305fe58fac37","libm/src/math/fmaxf.rs":"dff0025433232e8a5ec7bd54d847ccf596d762ea4e35f5c54fbaac9404d732fd","libm/src/math/fmin.rs":"95b6cb66ca0e0e22276f0bf88dbe8fb69796a69a196a7491bd4802efbcf2e298","libm/src/math/fminf.rs":"304bc839b15ea3d84e68d2af9f40524ec120d30a36a667b22fcb98a6c258f4c7","libm/src/math/fmod.rs":"a1c0550fc7df8164733d914e222ff0966a2ab886d6e75a1098f24fe0283ae227","libm/src/math/fmodf.rs":"ee51ed092c0eeb8195f35735ff725cfd46612e0d689a7c483538bd92fbe61828","libm/src/math/frexp.rs":"28af70026922a8ab979744c7ad4d8faba6079c4743b7eeb6d14c983a982fbbcc","libm/src/math/frexpf.rs":"2e2593ae8002ba420809ebfaf737ef001cdc912354be3d978a8c0cb930350d4d","libm/src/math/hypot.rs":"841131c4a0cea75bc8a86e29f3f6d0815a61fc99731c9984651ce83d3050d218","libm/src/math/hypotf.rs":"5f317323edc2eb699580fe54b074b7e570a7734d51a0a149c0b49b54470a836c","libm/src/math/ilogb.rs":"813413bf6266d4fc40db9c5921af3cef4f892ba93e8f6d9efe62a449d1234532","libm/src/math/ilogbf.rs":"dec462780f46682e16cfaa733238bed3b692729e951f53a44726100b6c73a716","libm/src/math/j0.rs":"9572b6396c489927d332d0e717920e61ec0618e5e9c31f7eeeec70f5e4abab06","libm/src/math/j0f.rs":"802c8254bded9b3afb6eea8b9af240038a5a4a5d811396729f69ca509e3e7d87","libm/src/math/j1.rs":"97b1af1611fa3d110c2b349ee8e4176100132ea1391b619086b47ac063b81803","libm/src/math/j1f.rs":"9c9b128752e8ea2e7d81b637ba84907ab54a545e7602c49167b313743927930b","libm/src/math/jn.rs":"847d122334e5707ad9627146cddccc082a1f2f5bcd3e5ef54399013a7007ce88","libm/src/math/jnf.rs":"4045076f7d1a1b89882ed60d4dd60a4cbbc66b85cfb90491378c8015effcc476","libm/src/math/k_cos.rs":"f34a69e44d6b8901b03b578a75972f438ab20a7b98a0903fc1903d6fde3899be","libm/src/math/k_cosf.rs":"8f7117ff21cebf8e890a5bcfd7ea858a94172f4172b79a66d53824c2cb0888b1","libm/src/math/k_expo2.rs":"eb4ca9e6a525b7ea6da868c3cb136896682cc46f8396ba2a2ebc3ae9e9ba54b0","libm/src/math/k_expo2f.rs":"d51ad5df61cb5d1258bdb90c52bfed4572bb446a9337de9c04411ed9454ae0cb","libm/src/math/k_sin.rs":"14b2aba6ca07150c92768b5a72acaf5cde6a11d6619e14896512a7ba242e289a","libm/src/math/k_sinf.rs":"2775fcc710807164e6f37a4f8da3c8143cd5f16e19ce7c31c5591522151d7a96","libm/src/math/k_tan.rs":"a72beae4ccd9631eeeb61d6365bbeecae81c8411f3120a999c515cca0d5ea5c5","libm/src/math/k_tanf.rs":"6a794be56fa4b2f60452b9bab19af01c388f174560acbf829a351378ea39495d","libm/src/math/ldexp.rs":"b647f0096e80e4d926d8dd18d294c892ee2cb1778effe2c5e1b2664ae5cb1a4e","libm/src/math/ldexpf.rs":"98743fad2cd97a7be496f40ba3157ac1438fce0d0c25d5ab90c3b8c71c3fd0ed","libm/src/math/lgamma.rs":"498552658cc8106d7754f85ae8dbc3306ac2f0a9f7eb5a796be70c5beac92c41","libm/src/math/lgamma_r.rs":"77fb6442aeb5343926d8965e1549dde3e2cc4fd09555de6b56506001d956c344","libm/src/math/lgammaf.rs":"457105f53a4c8717e8f5a117d261dcf94e222e83981337fe23602abe883fe3f7","libm/src/math/lgammaf_r.rs":"44de75babbdd53c4a5879cd6f426e7311db82669def39df5f63914d67d6cc1b1","libm/src/math/log.rs":"b5e0c5f30d9e94351488732801be3107c12b854c3f95ad37e256dd88eeca408f","libm/src/math/log10.rs":"3425ff8be001fd1646ba15e254eb6ef4bdc6ccaf0cbee27ddf1fa84e04178b90","libm/src/math/log10f.rs":"fee4f71879bc4c99259e68c0c641364901629fb29a8ebddfcc0d090102cceddd","libm/src/math/log1p.rs":"9cf400852f165e6be19b97036ae9521fb9ca857d0a9a91c117d9123221622185","libm/src/math/log1pf.rs":"2716e6d2afa271996b7c8f47fd9e4952c88f4c1fd8c07c3e8ce8c62794bf71d8","libm/src/math/log2.rs":"dbbbfbaaa8aa6a4dbefea554ea3983090a9691228b011910c751f6adca912c40","libm/src/math/log2f.rs":"92a90350d8edce21c31c285c3e620fca7c62a2366008921715945c2c73b5b79f","libm/src/math/logf.rs":"845342cffc34d3db1f5ec12d8e5b773cd5a79056e28662fcb9bcd80207596f50","libm/src/math/mod.rs":"9de65aedb36910356bc47d25b1468b40ab63faf7e319e599e478a239681bdf9c","libm/src/math/modf.rs":"d012ed5a708ef52b6d1313c22a46cadaf5764dde1220816e3df2f03a0fcc60ae","libm/src/math/modff.rs":"f8f1e4c27a85d2cdb3c8e74439d59ef64aa543b948f22c23227d02d8388d61c2","libm/src/math/nextafter.rs":"3282e7eef214a32736fb6928d490198ad394b26b402b45495115b104839eebfe","libm/src/math/nextafterf.rs":"0937dc8a8155c19842c12181e741cec1f7df1f7a00cee81fcb2475e2842761b7","libm/src/math/pow.rs":"17c38297c5bf99accd915f292b777f8716ecf328916297c8bb9dfde6fd8ce522","libm/src/math/powf.rs":"2c423a0ea57fdc4e20f3533f744c6e6288c998b4de8f2914fafaa0e78be81b04","libm/src/math/rem_pio2.rs":"3e53234977daf61c89c29c940791714aad2f676a6f38188c7d17543a2aa8806f","libm/src/math/rem_pio2_large.rs":"21762d08d72dc6f2e313123a7311683000974a09b8fcae50994d9c39239721b1","libm/src/math/rem_pio2f.rs":"07fb48f6d5cbadfd32ce4124b2b74af98b8391a2a6f36ce2a7d32e4500cb65ac","libm/src/math/remainder.rs":"63865f4370853c476b45bb27a5c54a4072146aa4a626835ae5263871a4e7e5dc","libm/src/math/remainderf.rs":"dd3fa432dbda8f2135428198be7bd69c57f8d13df3f365b12f52bf6a82352ac4","libm/src/math/remquo.rs":"3cc0bf55069f165c4843f2c358b3a27279c01e8cdd99f9057a3f7f31f45408f2","libm/src/math/remquof.rs":"cc749e18ecb7e766b8b8eeabdbf89ac99087d3d587e71e30f690676a3d2c1f9b","libm/src/math/round.rs":"f10797ef15dd34a74e912ba8621d60bc0200c87b94308c9de3cc88d7aec4feb4","libm/src/math/roundf.rs":"27e37cfcf82373709e7debf9c0c18f7ed00ae0f5d97a214c388041f7a6996d35","libm/src/math/scalbn.rs":"b5c9d6d4177fe393cbfe1c634d75ce14b754f6cbce87c5bf979a9661491748a2","libm/src/math/scalbnf.rs":"4f198d06db1896386256fb9a5ac5b805b16b836226c18780a475cf18d7c1449c","libm/src/math/sin.rs":"bb483a2138ca779e03a191222636f0c60fd75a77a2a12f263bda4b6aa9136317","libm/src/math/sincos.rs":"55b7446984db26bc118eb3d9b01f4fd2594de06558e0f9b6dc936a57888ca9be","libm/src/math/sincosf.rs":"f7b18383b242dad59e6033240d0e4a0fd08a2633e5048eff27532085f1c67f87","libm/src/math/sinf.rs":"dcddac1d56b084cbb8d0e019433c9c5fe2201d9b257a7dcf2f85c9a8f14b79cf","libm/src/math/sinh.rs":"d8ee4c7af883a526f36c1a6da13bb81fba9181b477e2f2538161a2bee97edc35","libm/src/math/sinhf.rs":"d06eb030ba9dbf7094df127262bfe99f149b4db49fa8ab8c15499660f1e46b26","libm/src/math/sqrt.rs":"824570a631c2542ccee68b65e3eb08fe79c037a29bbaaf54da5367e7b236124a","libm/src/math/sqrtf.rs":"4cf418d74f7751d522a642a9a8d6b86ee3472c6aaef44f0eb1bc26f4d8a90985","libm/src/math/tan.rs":"930ecedaadc60f704c2dfa4e15186f59713c1ba7d948529d215223b424827db5","libm/src/math/tanf.rs":"894156a3b107aee08461eb4e7e412fc049aa237d176ae705c6e3e2d7060d94e3","libm/src/math/tanh.rs":"f1f08eb98ed959a17370a7aaf0177be36e3764543424e78feb033ed3f5e8ec98","libm/src/math/tanhf.rs":"74027b0c672a4e64bdef6d7a3069b90caec50e1e7dbb2c12d2828f310502f41e","libm/src/math/tgamma.rs":"a6aabb8365410af6611f19f58694ccb74e82bb9ba9e1cdec7e1af787cfa44815","libm/src/math/tgammaf.rs":"c95bd69957387533853532164f7e2251d2b04f5e775406b9e647226ae2bdd5ad","libm/src/math/trunc.rs":"642264897cc1505e720c8cf313be81aa9fd53aae866644a2e988d01dbc77fd8a","libm/src/math/truncf.rs":"dee3607baf1af0f01deae46e429e097234c50b268eaefebbe716f19f38597900","src/arm.rs":"8ccf47608cc7862d8d834ca292d0d3d97faaab6cc6f20ba59ccf2987ff0f3f77","src/arm_linux.rs":"87136556091817b2bded52c3ece101123aae84ff13ccaf13a196826b2e3fc297","src/float/add.rs":"3ec32ceaf470a89777b54f9cde61832fdadeade0f4894f268a949e968520bc57","src/float/cmp.rs":"79b1fdc8d5f943c4ad5ea4ad32623b18f63e17ac3852fbc64a4942228007e1fc","src/float/conv.rs":"55138604371e00ef14167894159156b68f939039b0e5b2b1f3db61456e3d3870","src/float/div.rs":"bc808a5372d041b96aa603ac814165e1e7dbd690e4ab9b026d9465c1cbc2c583","src/float/extend.rs":"180b2e791c58e0526de0a798845c580ce3222c8a15c8665e6e6a4bf5cf1a34aa","src/float/mod.rs":"48d76632575789a6ecf99213b1ed38c21c86ad5a5c3fa33ccb31f77829271b79","src/float/mul.rs":"0d0c1f0c28c149ecadeafd459d3c4c9327e4cfcae2cba479957bb8010ef51a01","src/float/pow.rs":"2ada190738731eb6f24104f8fb8c4d6f03cfb16451536dbee32f2b33db0c4b19","src/float/sub.rs":"c2a87f4628f51d5d908d0f25b5d51ce0599dc559d5a72b20e131261f484d5848","src/float/trunc.rs":"d21d2a2f9a1918b4bbb594691e397972a7c04b74b2acf04016c55693abf6d24b","src/int/addsub.rs":"7ec45ce1ba15b56a5b7129d3e5722c4db764c6545306d3fa9090983bcabd6f17","src/int/leading_zeros.rs":"ccf5e9d098c80034dcf6e38437c9a2eb670fa8043558bbfb574f2293164729a6","src/int/mod.rs":"bab1b77535ceebdebb89fd4e59e7105f8c45347bb638351a626615b24544a0b1","src/int/mul.rs":"bb48d8fd42d8f9f5fe9271d8d0f7a92dbae320bf4346e19d1071eb2093cb8ed9","src/int/sdiv.rs":"ace4cb0ec388a38834e01cab2c5bc87182d31588dfc0b1ae117c11ed0c4781cf","src/int/shift.rs":"3967c28a8d61279546e91958d64745fec63f15aee9175eb0602cc6353830da6c","src/int/specialized_div_rem/asymmetric.rs":"27f5bf70a35109f9d4e4e1ad1e8003aa17da5a1e436bf3e63a493d7528a3a566","src/int/specialized_div_rem/binary_long.rs":"9f1ced81a394f000a21a329683144d68ee431a954136a3634eb55b1ee2cf6d51","src/int/specialized_div_rem/delegate.rs":"9df141af98e391361e25d71ae38d5e845a91d896edd2c041132fd46af8268e85","src/int/specialized_div_rem/mod.rs":"c32a7c416f2c81d6368720053864c3e7082417bca983c329520a8e7dc8c34736","src/int/specialized_div_rem/norm_shift.rs":"3be7ee0dea545c1f702d9daf67dad2b624bf7b17b075c8b90d3d3f7b53df4c21","src/int/specialized_div_rem/trifecta.rs":"87eef69da255b809fd710b14f2eb3f9f59e3dac625f8564ebc8ba78f9763523b","src/int/udiv.rs":"3732b490a472505411577f008b92f489287745968ce6791665201201377d3475","src/lib.rs":"557cd24974b4be235d3cdc4846eeacd8e536330ff54d037b8d56b21d99f64b3c","src/macros.rs":"4e6c006a47d7437f91a92802ecdceea63c60f3924ec98a429a14506c41c5f5dc","src/math.rs":"48bb0d97a1b56d960c6b5130b9a62a1cb1e8e5d62a522163022b8ea24c6cfcca","src/mem/impls.rs":"4517ae10a8adc2b0527529a872d8a7f98627f166d9a18a7aed6fc774b18dd843","src/mem/mod.rs":"791fa5fab759060e966de994b637e88c3c329cf2c0343efccca1da9dc80fcb66","src/mem/x86_64.rs":"912d4e955440113b97bd7dc836697df01a692524edd48cafaf599783ae277b85","src/probestack.rs":"ef5c07e9b95de7b2b77a937789fcfefd9846274317489ad6d623e377c9888601","src/riscv.rs":"8aa8cde1106a179e9a37724193bc5cea5defe212eb38e3049c23b254578f78d4","src/x86.rs":"117b50d6725ee0af0a7b3d197ea580655561f66a870ebc450d96af22bf7f39f6","src/x86_64.rs":"4f16bc9fad7757d48a6da3a078c715dd3a22154aadb4f1998d4c1b5d91396f9e"},"package":"71b72fde1d7792ca3bd654f7c3ea4508f9e4d0c826e24179eabb7fcc97a90bc3"} \ No newline at end of file
+{"files":{"Cargo.lock":"b0b1672fdd0af3eb8158670383772f3ce12d656d1481ec46657da2e9b26b19dd","Cargo.toml":"a49915bc5e86d21f27cfecb8465fe38a8e9cef628cca9619bfd2332cba170ac7","README.md":"5eb36fbab30693dbbe9f0de54749c95bd06fd6e42013b5b9eff3c062b9fdd34f","build.rs":"0c006642fbbe9fa5372a88cbbbb0bb4b391f635b2bde0c497de10740c1458c5e","examples/intrinsics.rs":"a7aa69c17af3aa8f6edff32c214e80827d3cbe3aea386a2be42244444752d253","libm/src/math/acos.rs":"fb066ba84aba1372d706425ec14f35ff8d971756d15eeebd22ecf42a716493bb","libm/src/math/acosf.rs":"a112b82309bba1d35c4e3d6ad4d6c21ef305343d9ab601ddf4bc61d43bc9f1af","libm/src/math/acosh.rs":"99de01ded7922bb93a882ad5ad8b472b5cae0059dea0bdca2077f65e94483150","libm/src/math/acoshf.rs":"10750c4d39ef6717b20a15ef1ce43e15eb851682d2f820f7e94501adec98b9a5","libm/src/math/asin.rs":"095a1e98996daff45df0b154ca0ec35bbf31db964ee9fdda0207308cb20df441","libm/src/math/asinf.rs":"49cccb4db2881982643a4a7d5453f4f8daf527711bbb67313607a3c178856d61","libm/src/math/asinh.rs":"4dd51affa71cce34a192ad66154e248f8d1c4b40fb497f29052333e425bb740f","libm/src/math/asinhf.rs":"914bfecf449f5e2bce786aa12c056d419073c6011d41c1bab7c39ba765fa4c53","libm/src/math/atan.rs":"d4fe46e1c5739dd09997869dcfbc3c85f03c534af52e700d6c6bcf9c3fedda07","libm/src/math/atan2.rs":"2623bc8ca707d13a7092ce49adf68e9cbf4452ad1bf4a861dc40ca858606a747","libm/src/math/atan2f.rs":"dd01943e0e1f1955912e5c3ffc9467529cf64bd02ac0a6ad5ab31dbe6657f05d","libm/src/math/atanf.rs":"e41b41569474a59c970ede3538e00bda4072cf4d90040017101cc79d7dc28caa","libm/src/math/atanh.rs":"57a8fb3f0f116fa4a966ac6bc2abd5f80236ead8e79013f468bd3786921f7110","libm/src/math/atanhf.rs":"6f2e57aaec1b5fc7609cb3938b3d155f51b4237dbda530739c34a0448cd9beb9","libm/src/math/cbrt.rs":"f2c45612d2eecd93cfcdd9ebf824c754fc8f8dfd6d16862c0b9c4ccea78c2a0f","libm/src/math/cbrtf.rs":"ad0b483854aa9f17a44d36c049bf0e8ebab34c27e90b787c05f45cc230ec7d19","libm/src/math/ceil.rs":"57ba5b6e207a0ccbd34190d1aa544389ca12126be23821dfb5746497f620ce03","libm/src/math/ceilf.rs":"c922a0475a599b9ea5473e615f74700b99707cebd6927f24ea59cb2a3cb3bbc3","libm/src/math/copysign.rs":"8b6440a251f0f1509d87f18122f74d0d5c03d0b60517e89e441434a3c5d84591","libm/src/math/copysignf.rs":"87d35436d224852ada93a2e93f6730cf1a727b808dd10e7d49ab4585866e336b","libm/src/math/cos.rs":"74babdc13ede78e400c5ca1854c3e22d2e08cbdc5618aefa5bba6f9303ef65b6","libm/src/math/cosf.rs":"09c40f93c445b741e22477ceedf163ca33b6a47f973f7c9876cfba2692edb29c","libm/src/math/cosh.rs":"0d0a7cef18577f321996b8b87561963139f754ad7f2ea0a3b3883811f3f0693a","libm/src/math/coshf.rs":"be8ca8739e4cf1978425b349f941cb4838bba8c10cb559c7940b9fd4fdde21ad","libm/src/math/erf.rs":"52cc9d9d54074a692001fb2d8215cd6903b645d4291ea20482455bc7f6947726","libm/src/math/erff.rs":"d37af67007fe4e9bce994c8c9805dd8af1b0ada68a10db8d8db13424dce65d09","libm/src/math/exp.rs":"ca7405ad0d1993fffcf9aae96f9256307bed3c4916545aaebd1cf1d2df1807fa","libm/src/math/exp10.rs":"2e136c6ecedd8e57a6c31796f57fae4546fcfd8bc6be66c836f553df9c74b907","libm/src/math/exp10f.rs":"9a3ce506ec587066a355ab74e0eb69a03a214ac405718087ae9772365050b20b","libm/src/math/exp2.rs":"94a9304a2ce3bc81f6d2aefd3cde6faa30f13260d46cb13692863cdea1c9a3a1","libm/src/math/exp2f.rs":"785f2630accd35118ec07bf60273e219ed91a215b956b1552eeea5bc2a708cc8","libm/src/math/expf.rs":"ec14c18f891a9e37735ec39e6fc2e9bf674a2c2e083f22e2533b481177359c98","libm/src/math/expm1.rs":"124069f456c8ad331f265c7509d9e223b2a300e461bbfd3d6adfdcdd2ee5b8ac","libm/src/math/expm1f.rs":"18e2116d31ea8410051cc709b9d04b754b0e3ba6758ee1bf0b48749f4999b840","libm/src/math/expo2.rs":"4f4f9fecfccb43f30c2784aa7c0bb656754a52b8ab431f7d1b551c673ab133f1","libm/src/math/fabs.rs":"e6c7db39f98508098cdf64ac0c2f53866c466149a7490afb9fe22b44c4dd81b3","libm/src/math/fabsf.rs":"83a1f5f4d9ca899ba2b701d7332e18b40258b83e111db4c5d8fab2cc1be58aa3","libm/src/math/fdim.rs":"8ec091996005207297c2389ae563e1b18dbc6a9eac951de29a976c5cd7bc32a7","libm/src/math/fdimf.rs":"c7f3f2269834d55be26b6580ddc07c42531577955fa4de35bad1e2a361085614","libm/src/math/fenv.rs":"916ae11e4763588518d64dee82afb41be9d1ee38ecc0679c821d4e7e22cd3dc5","libm/src/math/floor.rs":"5050804cae173af6775c0678d6c1aafb5ca2b744bc8a2f50d9d03b95dcee1fb0","libm/src/math/floorf.rs":"c903e0c57bc60a888c513eb7a873a87a4759ba68fc791b6b931652f8ee74cc03","libm/src/math/fma.rs":"d88e01c2c2d11333dd49b61166caa036ff5f08f3a8c5973b9e3c9574bf2eb675","libm/src/math/fmaf.rs":"1db6ee0d47ddbdb441cfe167edf89b431239f5805708fd0376cf5c01349a4bd6","libm/src/math/fmax.rs":"f6c8e96a8b1a170648d2fa3513e7b6b459085d708c839869f82e305fe58fac37","libm/src/math/fmaxf.rs":"dff0025433232e8a5ec7bd54d847ccf596d762ea4e35f5c54fbaac9404d732fd","libm/src/math/fmin.rs":"95b6cb66ca0e0e22276f0bf88dbe8fb69796a69a196a7491bd4802efbcf2e298","libm/src/math/fminf.rs":"304bc839b15ea3d84e68d2af9f40524ec120d30a36a667b22fcb98a6c258f4c7","libm/src/math/fmod.rs":"a1c0550fc7df8164733d914e222ff0966a2ab886d6e75a1098f24fe0283ae227","libm/src/math/fmodf.rs":"ee51ed092c0eeb8195f35735ff725cfd46612e0d689a7c483538bd92fbe61828","libm/src/math/frexp.rs":"28af70026922a8ab979744c7ad4d8faba6079c4743b7eeb6d14c983a982fbbcc","libm/src/math/frexpf.rs":"2e2593ae8002ba420809ebfaf737ef001cdc912354be3d978a8c0cb930350d4d","libm/src/math/hypot.rs":"841131c4a0cea75bc8a86e29f3f6d0815a61fc99731c9984651ce83d3050d218","libm/src/math/hypotf.rs":"5f317323edc2eb699580fe54b074b7e570a7734d51a0a149c0b49b54470a836c","libm/src/math/ilogb.rs":"d178ad7ca3439f82d565962b143f20448e45b2e2c51357b127abaec683297e32","libm/src/math/ilogbf.rs":"00f2b1b0496e21c6a42d68aea74d7156fa2ff0a735741b9051f3ca1cf0f57586","libm/src/math/j0.rs":"9572b6396c489927d332d0e717920e61ec0618e5e9c31f7eeeec70f5e4abab06","libm/src/math/j0f.rs":"802c8254bded9b3afb6eea8b9af240038a5a4a5d811396729f69ca509e3e7d87","libm/src/math/j1.rs":"97b1af1611fa3d110c2b349ee8e4176100132ea1391b619086b47ac063b81803","libm/src/math/j1f.rs":"9c9b128752e8ea2e7d81b637ba84907ab54a545e7602c49167b313743927930b","libm/src/math/jn.rs":"847d122334e5707ad9627146cddccc082a1f2f5bcd3e5ef54399013a7007ce88","libm/src/math/jnf.rs":"4045076f7d1a1b89882ed60d4dd60a4cbbc66b85cfb90491378c8015effcc476","libm/src/math/k_cos.rs":"f34a69e44d6b8901b03b578a75972f438ab20a7b98a0903fc1903d6fde3899be","libm/src/math/k_cosf.rs":"8f7117ff21cebf8e890a5bcfd7ea858a94172f4172b79a66d53824c2cb0888b1","libm/src/math/k_expo2.rs":"eb4ca9e6a525b7ea6da868c3cb136896682cc46f8396ba2a2ebc3ae9e9ba54b0","libm/src/math/k_expo2f.rs":"d51ad5df61cb5d1258bdb90c52bfed4572bb446a9337de9c04411ed9454ae0cb","libm/src/math/k_sin.rs":"14b2aba6ca07150c92768b5a72acaf5cde6a11d6619e14896512a7ba242e289a","libm/src/math/k_sinf.rs":"2775fcc710807164e6f37a4f8da3c8143cd5f16e19ce7c31c5591522151d7a96","libm/src/math/k_tan.rs":"a72beae4ccd9631eeeb61d6365bbeecae81c8411f3120a999c515cca0d5ea5c5","libm/src/math/k_tanf.rs":"6a794be56fa4b2f60452b9bab19af01c388f174560acbf829a351378ea39495d","libm/src/math/ldexp.rs":"b647f0096e80e4d926d8dd18d294c892ee2cb1778effe2c5e1b2664ae5cb1a4e","libm/src/math/ldexpf.rs":"98743fad2cd97a7be496f40ba3157ac1438fce0d0c25d5ab90c3b8c71c3fd0ed","libm/src/math/lgamma.rs":"0edd18e4f96bfcbe8b1b5af3eeca5208cd6d2d479dfa5ad117c9dfeccecf614f","libm/src/math/lgamma_r.rs":"f44a37aeccd56559ef784ae8edf217d14ad5cc2d910f0a65e70ffc86d7dc23dd","libm/src/math/lgammaf.rs":"967845357758b868a571857ec001f9f9154001110b8e97c08b6d10586bed9c49","libm/src/math/lgammaf_r.rs":"7143016d60e11fa235d53968125e57231b1104ce52149b5e1eed39629e0d1ff0","libm/src/math/log.rs":"b5e0c5f30d9e94351488732801be3107c12b854c3f95ad37e256dd88eeca408f","libm/src/math/log10.rs":"3425ff8be001fd1646ba15e254eb6ef4bdc6ccaf0cbee27ddf1fa84e04178b90","libm/src/math/log10f.rs":"fee4f71879bc4c99259e68c0c641364901629fb29a8ebddfcc0d090102cceddd","libm/src/math/log1p.rs":"9cf400852f165e6be19b97036ae9521fb9ca857d0a9a91c117d9123221622185","libm/src/math/log1pf.rs":"2716e6d2afa271996b7c8f47fd9e4952c88f4c1fd8c07c3e8ce8c62794bf71d8","libm/src/math/log2.rs":"dbbbfbaaa8aa6a4dbefea554ea3983090a9691228b011910c751f6adca912c40","libm/src/math/log2f.rs":"92a90350d8edce21c31c285c3e620fca7c62a2366008921715945c2c73b5b79f","libm/src/math/logf.rs":"845342cffc34d3db1f5ec12d8e5b773cd5a79056e28662fcb9bcd80207596f50","libm/src/math/mod.rs":"9de65aedb36910356bc47d25b1468b40ab63faf7e319e599e478a239681bdf9c","libm/src/math/modf.rs":"d012ed5a708ef52b6d1313c22a46cadaf5764dde1220816e3df2f03a0fcc60ae","libm/src/math/modff.rs":"f8f1e4c27a85d2cdb3c8e74439d59ef64aa543b948f22c23227d02d8388d61c2","libm/src/math/nextafter.rs":"3282e7eef214a32736fb6928d490198ad394b26b402b45495115b104839eebfe","libm/src/math/nextafterf.rs":"0937dc8a8155c19842c12181e741cec1f7df1f7a00cee81fcb2475e2842761b7","libm/src/math/pow.rs":"17c38297c5bf99accd915f292b777f8716ecf328916297c8bb9dfde6fd8ce522","libm/src/math/powf.rs":"2c423a0ea57fdc4e20f3533f744c6e6288c998b4de8f2914fafaa0e78be81b04","libm/src/math/rem_pio2.rs":"3e53234977daf61c89c29c940791714aad2f676a6f38188c7d17543a2aa8806f","libm/src/math/rem_pio2_large.rs":"482f31ff4e4eacf885f6130ae26a1d59f76b382059d6c742f30e5036811d3ca8","libm/src/math/rem_pio2f.rs":"07fb48f6d5cbadfd32ce4124b2b74af98b8391a2a6f36ce2a7d32e4500cb65ac","libm/src/math/remainder.rs":"63865f4370853c476b45bb27a5c54a4072146aa4a626835ae5263871a4e7e5dc","libm/src/math/remainderf.rs":"dd3fa432dbda8f2135428198be7bd69c57f8d13df3f365b12f52bf6a82352ac4","libm/src/math/remquo.rs":"3cc0bf55069f165c4843f2c358b3a27279c01e8cdd99f9057a3f7f31f45408f2","libm/src/math/remquof.rs":"cc749e18ecb7e766b8b8eeabdbf89ac99087d3d587e71e30f690676a3d2c1f9b","libm/src/math/round.rs":"f10797ef15dd34a74e912ba8621d60bc0200c87b94308c9de3cc88d7aec4feb4","libm/src/math/roundf.rs":"27e37cfcf82373709e7debf9c0c18f7ed00ae0f5d97a214c388041f7a6996d35","libm/src/math/scalbn.rs":"b5c9d6d4177fe393cbfe1c634d75ce14b754f6cbce87c5bf979a9661491748a2","libm/src/math/scalbnf.rs":"4f198d06db1896386256fb9a5ac5b805b16b836226c18780a475cf18d7c1449c","libm/src/math/sin.rs":"bb483a2138ca779e03a191222636f0c60fd75a77a2a12f263bda4b6aa9136317","libm/src/math/sincos.rs":"1cf62a16c215e367f51078a3ba23a3f257682032a8f3c657293029a886b18d82","libm/src/math/sincosf.rs":"b0f589e6ada8215944d7784f420c6721c90387d799e349ce7676674f3c475e75","libm/src/math/sinf.rs":"dcddac1d56b084cbb8d0e019433c9c5fe2201d9b257a7dcf2f85c9a8f14b79cf","libm/src/math/sinh.rs":"d8ee4c7af883a526f36c1a6da13bb81fba9181b477e2f2538161a2bee97edc35","libm/src/math/sinhf.rs":"d06eb030ba9dbf7094df127262bfe99f149b4db49fa8ab8c15499660f1e46b26","libm/src/math/sqrt.rs":"824570a631c2542ccee68b65e3eb08fe79c037a29bbaaf54da5367e7b236124a","libm/src/math/sqrtf.rs":"4cf418d74f7751d522a642a9a8d6b86ee3472c6aaef44f0eb1bc26f4d8a90985","libm/src/math/tan.rs":"930ecedaadc60f704c2dfa4e15186f59713c1ba7d948529d215223b424827db5","libm/src/math/tanf.rs":"894156a3b107aee08461eb4e7e412fc049aa237d176ae705c6e3e2d7060d94e3","libm/src/math/tanh.rs":"f1f08eb98ed959a17370a7aaf0177be36e3764543424e78feb033ed3f5e8ec98","libm/src/math/tanhf.rs":"74027b0c672a4e64bdef6d7a3069b90caec50e1e7dbb2c12d2828f310502f41e","libm/src/math/tgamma.rs":"c889cfa49bbeb4dbb0941fe9fac3b4da7d5879dcf04a3b9bb6e56de529baf374","libm/src/math/tgammaf.rs":"0737b34777095d0e4d07fe533e8f105082dd4e8ece411bba6ae5993b45b9388c","libm/src/math/trunc.rs":"642264897cc1505e720c8cf313be81aa9fd53aae866644a2e988d01dbc77fd8a","libm/src/math/truncf.rs":"dee3607baf1af0f01deae46e429e097234c50b268eaefebbe716f19f38597900","src/arm.rs":"acf149932aa46a2755cf8cd2eb7d6ae249e46b1e10ad45ce5f924561945d1273","src/arm_linux.rs":"35a4cb7b75015543feb15b0c692da0faf0e6037d3b97a4a18067ba416eae1a70","src/float/add.rs":"3ec32ceaf470a89777b54f9cde61832fdadeade0f4894f268a949e968520bc57","src/float/cmp.rs":"79b1fdc8d5f943c4ad5ea4ad32623b18f63e17ac3852fbc64a4942228007e1fc","src/float/conv.rs":"cb9a830e0d440ed825aa897f268e4ae067204da4ffc162ba963977a4b309007f","src/float/div.rs":"bc808a5372d041b96aa603ac814165e1e7dbd690e4ab9b026d9465c1cbc2c583","src/float/extend.rs":"180b2e791c58e0526de0a798845c580ce3222c8a15c8665e6e6a4bf5cf1a34aa","src/float/mod.rs":"48d76632575789a6ecf99213b1ed38c21c86ad5a5c3fa33ccb31f77829271b79","src/float/mul.rs":"0d0c1f0c28c149ecadeafd459d3c4c9327e4cfcae2cba479957bb8010ef51a01","src/float/pow.rs":"2ada190738731eb6f24104f8fb8c4d6f03cfb16451536dbee32f2b33db0c4b19","src/float/sub.rs":"c2a87f4628f51d5d908d0f25b5d51ce0599dc559d5a72b20e131261f484d5848","src/float/trunc.rs":"d21d2a2f9a1918b4bbb594691e397972a7c04b74b2acf04016c55693abf6d24b","src/int/addsub.rs":"7ec45ce1ba15b56a5b7129d3e5722c4db764c6545306d3fa9090983bcabd6f17","src/int/leading_zeros.rs":"ccf5e9d098c80034dcf6e38437c9a2eb670fa8043558bbfb574f2293164729a6","src/int/mod.rs":"bab1b77535ceebdebb89fd4e59e7105f8c45347bb638351a626615b24544a0b1","src/int/mul.rs":"bb48d8fd42d8f9f5fe9271d8d0f7a92dbae320bf4346e19d1071eb2093cb8ed9","src/int/sdiv.rs":"ace4cb0ec388a38834e01cab2c5bc87182d31588dfc0b1ae117c11ed0c4781cf","src/int/shift.rs":"3967c28a8d61279546e91958d64745fec63f15aee9175eb0602cc6353830da6c","src/int/specialized_div_rem/asymmetric.rs":"27f5bf70a35109f9d4e4e1ad1e8003aa17da5a1e436bf3e63a493d7528a3a566","src/int/specialized_div_rem/binary_long.rs":"9f1ced81a394f000a21a329683144d68ee431a954136a3634eb55b1ee2cf6d51","src/int/specialized_div_rem/delegate.rs":"9df141af98e391361e25d71ae38d5e845a91d896edd2c041132fd46af8268e85","src/int/specialized_div_rem/mod.rs":"c32a7c416f2c81d6368720053864c3e7082417bca983c329520a8e7dc8c34736","src/int/specialized_div_rem/norm_shift.rs":"3be7ee0dea545c1f702d9daf67dad2b624bf7b17b075c8b90d3d3f7b53df4c21","src/int/specialized_div_rem/trifecta.rs":"87eef69da255b809fd710b14f2eb3f9f59e3dac625f8564ebc8ba78f9763523b","src/int/udiv.rs":"3732b490a472505411577f008b92f489287745968ce6791665201201377d3475","src/lib.rs":"d0e85291d12a57c61791257e3adefb8f2222e1ba6f9e5cd4cf7fba59d26477f4","src/macros.rs":"a3261b40b1db041fb779b32bfc2bf3cba7a7c85f10fd02997163b3396658a3d7","src/math.rs":"ac6063d7c8927e3b8fe6e41acf83261db2a57e02f7c5a30bc52dbb03c0df9c72","src/mem/impls.rs":"a8d1c28a77d9b334872abbebfcba3fd1802175bef53c0b545e85242860698780","src/mem/mod.rs":"5034543d963149c14a6823bee32a1fb9dfd950c32153d37f97e9df1dc6c23129","src/mem/x86_64.rs":"9f740891f666acf384159128eef233d9e15c6120da8016370c6f9f05cc29d653","src/probestack.rs":"ef5c07e9b95de7b2b77a937789fcfefd9846274317489ad6d623e377c9888601","src/riscv.rs":"8aa8cde1106a179e9a37724193bc5cea5defe212eb38e3049c23b254578f78d4","src/x86.rs":"117b50d6725ee0af0a7b3d197ea580655561f66a870ebc450d96af22bf7f39f6","src/x86_64.rs":"4f16bc9fad7757d48a6da3a078c715dd3a22154aadb4f1998d4c1b5d91396f9e"},"package":"4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"} \ No newline at end of file
diff --git a/vendor/compiler_builtins/Cargo.lock b/vendor/compiler_builtins/Cargo.lock
index e184f7e20..e60762217 100644
--- a/vendor/compiler_builtins/Cargo.lock
+++ b/vendor/compiler_builtins/Cargo.lock
@@ -4,13 +4,13 @@ version = 3
[[package]]
name = "cc"
-version = "1.0.70"
+version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "compiler_builtins"
-version = "0.1.73"
+version = "0.1.79"
dependencies = [
"cc",
"rustc-std-workspace-core",
diff --git a/vendor/compiler_builtins/Cargo.toml b/vendor/compiler_builtins/Cargo.toml
index 765e99f94..eedf9a7b2 100644
--- a/vendor/compiler_builtins/Cargo.toml
+++ b/vendor/compiler_builtins/Cargo.toml
@@ -11,7 +11,7 @@
[package]
name = "compiler_builtins"
-version = "0.1.73"
+version = "0.1.79"
authors = ["Jorge Aparicio <japaricious@gmail.com>"]
links = "compiler-rt"
include = [
@@ -33,6 +33,7 @@ documentation = "https://docs.rs/compiler_builtins"
readme = "README.md"
license = "MIT/Apache-2.0"
repository = "https://github.com/rust-lang/compiler-builtins"
+resolver = "1"
[profile.dev]
panic = "abort"
diff --git a/vendor/compiler_builtins/build.rs b/vendor/compiler_builtins/build.rs
index 11deffb9c..73952bb9f 100644
--- a/vendor/compiler_builtins/build.rs
+++ b/vendor/compiler_builtins/build.rs
@@ -29,6 +29,7 @@ fn main() {
|| (target.contains("sgx") && target.contains("fortanix"))
|| target.contains("-none")
|| target.contains("nvptx")
+ || target.contains("uefi")
{
println!("cargo:rustc-cfg=feature=\"mem\"");
}
@@ -58,9 +59,11 @@ fn main() {
// unlikely that the C is really that much better than our own Rust.
// * nvptx - everything is bitcode, not compatible with mixed C/Rust
// * riscv - the rust-lang/rust distribution container doesn't have a C
- // compiler nor is cc-rs ready for compilation to riscv (at this
- // time). This can probably be removed in the future
- if !target.contains("wasm") && !target.contains("nvptx") && !target.starts_with("riscv") {
+ // compiler.
+ if !target.contains("wasm")
+ && !target.contains("nvptx")
+ && (!target.starts_with("riscv") || target.contains("xous"))
+ {
#[cfg(feature = "c")]
c::compile(&llvm_target, &target);
}
@@ -457,6 +460,7 @@ mod c {
("__fe_getround", "fp_mode.c"),
("__divtf3", "divtf3.c"),
("__trunctfdf2", "trunctfdf2.c"),
+ ("__trunctfsf2", "trunctfsf2.c"),
]);
}
diff --git a/vendor/compiler_builtins/libm/src/math/acosh.rs b/vendor/compiler_builtins/libm/src/math/acosh.rs
index ac7a5f1c6..d1f5b9fa9 100644
--- a/vendor/compiler_builtins/libm/src/math/acosh.rs
+++ b/vendor/compiler_builtins/libm/src/math/acosh.rs
@@ -7,6 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
/// Calculates the inverse hyperbolic cosine of `x`.
/// Is defined as `log(x + sqrt(x*x-1))`.
/// `x` must be a number greater than or equal to 1.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn acosh(x: f64) -> f64 {
let u = x.to_bits();
let e = ((u >> 52) as usize) & 0x7ff;
diff --git a/vendor/compiler_builtins/libm/src/math/acoshf.rs b/vendor/compiler_builtins/libm/src/math/acoshf.rs
index 0879e1edb..ad3455fdd 100644
--- a/vendor/compiler_builtins/libm/src/math/acoshf.rs
+++ b/vendor/compiler_builtins/libm/src/math/acoshf.rs
@@ -7,6 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
/// Calculates the inverse hyperbolic cosine of `x`.
/// Is defined as `log(x + sqrt(x*x-1))`.
/// `x` must be a number greater than or equal to 1.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn acoshf(x: f32) -> f32 {
let u = x.to_bits();
let a = u & 0x7fffffff;
diff --git a/vendor/compiler_builtins/libm/src/math/asinh.rs b/vendor/compiler_builtins/libm/src/math/asinh.rs
index 14295357a..0abd80c2f 100644
--- a/vendor/compiler_builtins/libm/src/math/asinh.rs
+++ b/vendor/compiler_builtins/libm/src/math/asinh.rs
@@ -7,6 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
///
/// Calculates the inverse hyperbolic sine of `x`.
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn asinh(mut x: f64) -> f64 {
let mut u = x.to_bits();
let e = ((u >> 52) as usize) & 0x7ff;
diff --git a/vendor/compiler_builtins/libm/src/math/asinhf.rs b/vendor/compiler_builtins/libm/src/math/asinhf.rs
index e22a29132..09c77823e 100644
--- a/vendor/compiler_builtins/libm/src/math/asinhf.rs
+++ b/vendor/compiler_builtins/libm/src/math/asinhf.rs
@@ -7,6 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
///
/// Calculates the inverse hyperbolic sine of `x`.
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn asinhf(mut x: f32) -> f32 {
let u = x.to_bits();
let i = u & 0x7fffffff;
diff --git a/vendor/compiler_builtins/libm/src/math/atanh.rs b/vendor/compiler_builtins/libm/src/math/atanh.rs
index 79a989c42..b984c4ac6 100644
--- a/vendor/compiler_builtins/libm/src/math/atanh.rs
+++ b/vendor/compiler_builtins/libm/src/math/atanh.rs
@@ -5,6 +5,7 @@ use super::log1p;
///
/// Calculates the inverse hyperbolic tangent of `x`.
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn atanh(x: f64) -> f64 {
let u = x.to_bits();
let e = ((u >> 52) as usize) & 0x7ff;
diff --git a/vendor/compiler_builtins/libm/src/math/atanhf.rs b/vendor/compiler_builtins/libm/src/math/atanhf.rs
index 7b2f34d97..a1aa314a5 100644
--- a/vendor/compiler_builtins/libm/src/math/atanhf.rs
+++ b/vendor/compiler_builtins/libm/src/math/atanhf.rs
@@ -5,6 +5,7 @@ use super::log1pf;
///
/// Calculates the inverse hyperbolic tangent of `x`.
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn atanhf(mut x: f32) -> f32 {
let mut u = x.to_bits();
let sign = (u >> 31) != 0;
diff --git a/vendor/compiler_builtins/libm/src/math/copysign.rs b/vendor/compiler_builtins/libm/src/math/copysign.rs
index 1527fb6ea..1f4a35a33 100644
--- a/vendor/compiler_builtins/libm/src/math/copysign.rs
+++ b/vendor/compiler_builtins/libm/src/math/copysign.rs
@@ -2,6 +2,7 @@
///
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn copysign(x: f64, y: f64) -> f64 {
let mut ux = x.to_bits();
let uy = y.to_bits();
diff --git a/vendor/compiler_builtins/libm/src/math/copysignf.rs b/vendor/compiler_builtins/libm/src/math/copysignf.rs
index 35148561a..6c346e3a5 100644
--- a/vendor/compiler_builtins/libm/src/math/copysignf.rs
+++ b/vendor/compiler_builtins/libm/src/math/copysignf.rs
@@ -2,6 +2,7 @@
///
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn copysignf(x: f32, y: f32) -> f32 {
let mut ux = x.to_bits();
let uy = y.to_bits();
diff --git a/vendor/compiler_builtins/libm/src/math/erf.rs b/vendor/compiler_builtins/libm/src/math/erf.rs
index a2c617d34..5e21ba578 100644
--- a/vendor/compiler_builtins/libm/src/math/erf.rs
+++ b/vendor/compiler_builtins/libm/src/math/erf.rs
@@ -219,6 +219,7 @@ fn erfc2(ix: u32, mut x: f64) -> f64 {
/// Calculates an approximation to the “error functionâ€, which estimates
/// the probability that an observation will fall within x standard
/// deviations of the mean (assuming a normal distribution).
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn erf(x: f64) -> f64 {
let r: f64;
let s: f64;
diff --git a/vendor/compiler_builtins/libm/src/math/erff.rs b/vendor/compiler_builtins/libm/src/math/erff.rs
index 384052293..f74d4b632 100644
--- a/vendor/compiler_builtins/libm/src/math/erff.rs
+++ b/vendor/compiler_builtins/libm/src/math/erff.rs
@@ -130,6 +130,7 @@ fn erfc2(mut ix: u32, mut x: f32) -> f32 {
/// Calculates an approximation to the “error functionâ€, which estimates
/// the probability that an observation will fall within x standard
/// deviations of the mean (assuming a normal distribution).
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn erff(x: f32) -> f32 {
let r: f32;
let s: f32;
diff --git a/vendor/compiler_builtins/libm/src/math/exp10.rs b/vendor/compiler_builtins/libm/src/math/exp10.rs
index 9537f76f1..559930e10 100644
--- a/vendor/compiler_builtins/libm/src/math/exp10.rs
+++ b/vendor/compiler_builtins/libm/src/math/exp10.rs
@@ -6,16 +6,17 @@ const P10: &[f64] = &[
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
];
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn exp10(x: f64) -> f64 {
let (mut y, n) = modf(x);
let u: u64 = n.to_bits();
/* fabs(n) < 16 without raising invalid on nan */
if (u >> 52 & 0x7ff) < 0x3ff + 4 {
if y == 0.0 {
- return P10[((n as isize) + 15) as usize];
+ return i!(P10, ((n as isize) + 15) as usize);
}
y = exp2(LN10 * y);
- return y * P10[((n as isize) + 15) as usize];
+ return y * i!(P10, ((n as isize) + 15) as usize);
}
return pow(10.0, x);
}
diff --git a/vendor/compiler_builtins/libm/src/math/exp10f.rs b/vendor/compiler_builtins/libm/src/math/exp10f.rs
index d45fff36e..1279bc6c5 100644
--- a/vendor/compiler_builtins/libm/src/math/exp10f.rs
+++ b/vendor/compiler_builtins/libm/src/math/exp10f.rs
@@ -6,16 +6,17 @@ const P10: &[f32] = &[
1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
];
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn exp10f(x: f32) -> f32 {
let (mut y, n) = modff(x);
let u = n.to_bits();
/* fabsf(n) < 8 without raising invalid on nan */
if (u >> 23 & 0xff) < 0x7f + 3 {
if y == 0.0 {
- return P10[((n as isize) + 7) as usize];
+ return i!(P10, ((n as isize) + 7) as usize);
}
y = exp2f(LN10_F32 * y);
- return y * P10[((n as isize) + 7) as usize];
+ return y * i!(P10, ((n as isize) + 7) as usize);
}
return exp2(LN10_F64 * (x as f64)) as f32;
}
diff --git a/vendor/compiler_builtins/libm/src/math/fenv.rs b/vendor/compiler_builtins/libm/src/math/fenv.rs
index 652e60324..c91272e82 100644
--- a/vendor/compiler_builtins/libm/src/math/fenv.rs
+++ b/vendor/compiler_builtins/libm/src/math/fenv.rs
@@ -5,7 +5,6 @@ pub(crate) const FE_UNDERFLOW: i32 = 0;
pub(crate) const FE_INEXACT: i32 = 0;
pub(crate) const FE_TONEAREST: i32 = 0;
-pub(crate) const FE_TOWARDZERO: i32 = 0;
#[inline]
pub(crate) fn feclearexcept(_mask: i32) -> i32 {
@@ -26,8 +25,3 @@ pub(crate) fn fetestexcept(_mask: i32) -> i32 {
pub(crate) fn fegetround() -> i32 {
FE_TONEAREST
}
-
-#[inline]
-pub(crate) fn fesetround(_r: i32) -> i32 {
- 0
-}
diff --git a/vendor/compiler_builtins/libm/src/math/fmaf.rs b/vendor/compiler_builtins/libm/src/math/fmaf.rs
index 03d371c55..2848f2aee 100644
--- a/vendor/compiler_builtins/libm/src/math/fmaf.rs
+++ b/vendor/compiler_builtins/libm/src/math/fmaf.rs
@@ -29,8 +29,7 @@ use core::f32;
use core::ptr::read_volatile;
use super::fenv::{
- feclearexcept, fegetround, feraiseexcept, fesetround, fetestexcept, FE_INEXACT, FE_TONEAREST,
- FE_TOWARDZERO, FE_UNDERFLOW,
+ feclearexcept, fegetround, feraiseexcept, fetestexcept, FE_INEXACT, FE_TONEAREST, FE_UNDERFLOW,
};
/*
@@ -91,16 +90,28 @@ pub fn fmaf(x: f32, y: f32, mut z: f32) -> f32 {
* If result is inexact, and exactly halfway between two float values,
* we need to adjust the low-order bit in the direction of the error.
*/
- fesetround(FE_TOWARDZERO);
- // prevent `vxy + z` from being CSE'd with `xy + z` above
- let vxy: f64 = unsafe { read_volatile(&xy) };
- let mut adjusted_result: f64 = vxy + z as f64;
- fesetround(FE_TONEAREST);
- if result == adjusted_result {
- ui = adjusted_result.to_bits();
+ let neg = ui >> 63 != 0;
+ let err = if neg == (z as f64 > xy) {
+ xy - result + z as f64
+ } else {
+ z as f64 - result + xy
+ };
+ if neg == (err < 0.0) {
ui += 1;
- adjusted_result = f64::from_bits(ui);
+ } else {
+ ui -= 1;
+ }
+ f64::from_bits(ui) as f32
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn issue_263() {
+ let a = f32::from_bits(1266679807);
+ let b = f32::from_bits(1300234242);
+ let c = f32::from_bits(1115553792);
+ let expected = f32::from_bits(1501560833);
+ assert_eq!(super::fmaf(a, b, c), expected);
}
- z = adjusted_result as f32;
- z
}
diff --git a/vendor/compiler_builtins/libm/src/math/ilogb.rs b/vendor/compiler_builtins/libm/src/math/ilogb.rs
index 0a380b7ef..7d74dcfb6 100644
--- a/vendor/compiler_builtins/libm/src/math/ilogb.rs
+++ b/vendor/compiler_builtins/libm/src/math/ilogb.rs
@@ -1,6 +1,7 @@
const FP_ILOGBNAN: i32 = -1 - 0x7fffffff;
const FP_ILOGB0: i32 = FP_ILOGBNAN;
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn ilogb(x: f64) -> i32 {
let mut i: u64 = x.to_bits();
let e = ((i >> 52) & 0x7ff) as i32;
diff --git a/vendor/compiler_builtins/libm/src/math/ilogbf.rs b/vendor/compiler_builtins/libm/src/math/ilogbf.rs
index b384fa4b2..0fa58748c 100644
--- a/vendor/compiler_builtins/libm/src/math/ilogbf.rs
+++ b/vendor/compiler_builtins/libm/src/math/ilogbf.rs
@@ -1,6 +1,7 @@
const FP_ILOGBNAN: i32 = -1 - 0x7fffffff;
const FP_ILOGB0: i32 = FP_ILOGBNAN;
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn ilogbf(x: f32) -> i32 {
let mut i = x.to_bits();
let e = ((i >> 23) & 0xff) as i32;
diff --git a/vendor/compiler_builtins/libm/src/math/lgamma.rs b/vendor/compiler_builtins/libm/src/math/lgamma.rs
index 5bc87e85e..a08bc5b64 100644
--- a/vendor/compiler_builtins/libm/src/math/lgamma.rs
+++ b/vendor/compiler_builtins/libm/src/math/lgamma.rs
@@ -1,5 +1,6 @@
use super::lgamma_r;
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn lgamma(x: f64) -> f64 {
lgamma_r(x).0
}
diff --git a/vendor/compiler_builtins/libm/src/math/lgamma_r.rs b/vendor/compiler_builtins/libm/src/math/lgamma_r.rs
index 9533e882c..b26177e6e 100644
--- a/vendor/compiler_builtins/libm/src/math/lgamma_r.rs
+++ b/vendor/compiler_builtins/libm/src/math/lgamma_r.rs
@@ -152,7 +152,7 @@ fn sin_pi(mut x: f64) -> f64 {
x = 2.0 * (x * 0.5 - floor(x * 0.5)); /* x mod 2.0 */
n = (x * 4.0) as i32;
- n = (n + 1) / 2;
+ n = div!(n + 1, 2);
x -= (n as f64) * 0.5;
x *= PI;
@@ -164,6 +164,7 @@ fn sin_pi(mut x: f64) -> f64 {
}
}
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn lgamma_r(mut x: f64) -> (f64, i32) {
let u: u64 = x.to_bits();
let mut t: f64;
diff --git a/vendor/compiler_builtins/libm/src/math/lgammaf.rs b/vendor/compiler_builtins/libm/src/math/lgammaf.rs
index dfdc87f96..a9c2da75b 100644
--- a/vendor/compiler_builtins/libm/src/math/lgammaf.rs
+++ b/vendor/compiler_builtins/libm/src/math/lgammaf.rs
@@ -1,5 +1,6 @@
use super::lgammaf_r;
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn lgammaf(x: f32) -> f32 {
lgammaf_r(x).0
}
diff --git a/vendor/compiler_builtins/libm/src/math/lgammaf_r.rs b/vendor/compiler_builtins/libm/src/math/lgammaf_r.rs
index c5e559f46..723c90daf 100644
--- a/vendor/compiler_builtins/libm/src/math/lgammaf_r.rs
+++ b/vendor/compiler_builtins/libm/src/math/lgammaf_r.rs
@@ -88,7 +88,7 @@ fn sin_pi(mut x: f32) -> f32 {
x = 2.0 * (x * 0.5 - floorf(x * 0.5)); /* x mod 2.0 */
n = (x * 4.0) as isize;
- n = (n + 1) / 2;
+ n = div!(n + 1, 2);
y = (x as f64) - (n as f64) * 0.5;
y *= 3.14159265358979323846;
match n {
@@ -99,6 +99,7 @@ fn sin_pi(mut x: f32) -> f32 {
}
}
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn lgammaf_r(mut x: f32) -> (f32, i32) {
let u = x.to_bits();
let mut t: f32;
diff --git a/vendor/compiler_builtins/libm/src/math/rem_pio2_large.rs b/vendor/compiler_builtins/libm/src/math/rem_pio2_large.rs
index 65473f0ab..db97a39d4 100644
--- a/vendor/compiler_builtins/libm/src/math/rem_pio2_large.rs
+++ b/vendor/compiler_builtins/libm/src/math/rem_pio2_large.rs
@@ -27,7 +27,7 @@ const INIT_JK: [usize; 4] = [3, 4, 4, 6];
//
// NB: This table must have at least (e0-3)/24 + jk terms.
// For quad precision (e0 <= 16360, jk = 6), this is 686.
-#[cfg(target_pointer_width = "32")]
+#[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
const IPIO2: [i32; 66] = [
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163,
0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
diff --git a/vendor/compiler_builtins/libm/src/math/sincos.rs b/vendor/compiler_builtins/libm/src/math/sincos.rs
index 4ab588412..ff5d87a1c 100644
--- a/vendor/compiler_builtins/libm/src/math/sincos.rs
+++ b/vendor/compiler_builtins/libm/src/math/sincos.rs
@@ -12,6 +12,7 @@
use super::{get_high_word, k_cos, k_sin, rem_pio2};
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn sincos(x: f64) -> (f64, f64) {
let s: f64;
let c: f64;
diff --git a/vendor/compiler_builtins/libm/src/math/sincosf.rs b/vendor/compiler_builtins/libm/src/math/sincosf.rs
index 5304e8ca0..9a4c36104 100644
--- a/vendor/compiler_builtins/libm/src/math/sincosf.rs
+++ b/vendor/compiler_builtins/libm/src/math/sincosf.rs
@@ -23,6 +23,7 @@ const S2PIO2: f32 = 2.0 * PI_2; /* 0x400921FB, 0x54442D18 */
const S3PIO2: f32 = 3.0 * PI_2; /* 0x4012D97C, 0x7F3321D2 */
const S4PIO2: f32 = 4.0 * PI_2; /* 0x401921FB, 0x54442D18 */
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn sincosf(x: f32) -> (f32, f32) {
let s: f32;
let c: f32;
diff --git a/vendor/compiler_builtins/libm/src/math/tgamma.rs b/vendor/compiler_builtins/libm/src/math/tgamma.rs
index f8ccf669a..e64eff61f 100644
--- a/vendor/compiler_builtins/libm/src/math/tgamma.rs
+++ b/vendor/compiler_builtins/libm/src/math/tgamma.rs
@@ -38,7 +38,7 @@ fn sinpi(mut x: f64) -> f64 {
/* reduce x into [-.25,.25] */
n = (4.0 * x) as isize;
- n = (n + 1) / 2;
+ n = div!(n + 1, 2);
x -= (n as f64) * 0.5;
x *= PI;
@@ -118,18 +118,19 @@ fn s(x: f64) -> f64 {
/* to avoid overflow handle large x differently */
if x < 8.0 {
for i in (0..=N).rev() {
- num = num * x + SNUM[i];
- den = den * x + SDEN[i];
+ num = num * x + i!(SNUM, i);
+ den = den * x + i!(SDEN, i);
}
} else {
for i in 0..=N {
- num = num / x + SNUM[i];
- den = den / x + SDEN[i];
+ num = num / x + i!(SNUM, i);
+ den = den / x + i!(SDEN, i);
}
}
return num / den;
}
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn tgamma(mut x: f64) -> f64 {
let u: u64 = x.to_bits();
let absx: f64;
@@ -157,7 +158,7 @@ pub fn tgamma(mut x: f64) -> f64 {
return 0.0 / 0.0;
}
if x <= FACT.len() as f64 {
- return FACT[(x as usize) - 1];
+ return i!(FACT, (x as usize) - 1);
}
}
diff --git a/vendor/compiler_builtins/libm/src/math/tgammaf.rs b/vendor/compiler_builtins/libm/src/math/tgammaf.rs
index a8f161f0c..23e3814f9 100644
--- a/vendor/compiler_builtins/libm/src/math/tgammaf.rs
+++ b/vendor/compiler_builtins/libm/src/math/tgammaf.rs
@@ -1,5 +1,6 @@
use super::tgamma;
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn tgammaf(x: f32) -> f32 {
tgamma(x as f64) as f32
}
diff --git a/vendor/compiler_builtins/src/arm.rs b/vendor/compiler_builtins/src/arm.rs
index 9c1b6ad12..e517a9ef3 100644
--- a/vendor/compiler_builtins/src/arm.rs
+++ b/vendor/compiler_builtins/src/arm.rs
@@ -22,6 +22,7 @@ intrinsics! {
// custom calling convention which can't be implemented using a normal Rust function.
#[naked]
#[cfg(not(target_env = "msvc"))]
+ #[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")]
pub unsafe extern "C" fn __aeabi_uidivmod() {
core::arch::asm!(
"push {{lr}}",
@@ -36,6 +37,7 @@ intrinsics! {
}
#[naked]
+ #[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")]
pub unsafe extern "C" fn __aeabi_uldivmod() {
core::arch::asm!(
"push {{r4, lr}}",
@@ -52,6 +54,7 @@ intrinsics! {
}
#[naked]
+ #[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")]
pub unsafe extern "C" fn __aeabi_idivmod() {
core::arch::asm!(
"push {{r0, r1, r4, lr}}",
@@ -65,6 +68,7 @@ intrinsics! {
}
#[naked]
+ #[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")]
pub unsafe extern "C" fn __aeabi_ldivmod() {
core::arch::asm!(
"push {{r4, lr}}",
diff --git a/vendor/compiler_builtins/src/arm_linux.rs b/vendor/compiler_builtins/src/arm_linux.rs
index 8fe09485b..8f22eb628 100644
--- a/vendor/compiler_builtins/src/arm_linux.rs
+++ b/vendor/compiler_builtins/src/arm_linux.rs
@@ -55,7 +55,7 @@ fn insert_aligned(aligned: u32, val: u32, shift: u32, mask: u32) -> u32 {
}
// Generic atomic read-modify-write operation
-unsafe fn atomic_rmw<T, F: Fn(u32) -> u32>(ptr: *mut T, f: F) -> u32 {
+unsafe fn atomic_rmw<T, F: Fn(u32) -> u32, G: Fn(u32, u32) -> u32>(ptr: *mut T, f: F, g: G) -> u32 {
let aligned_ptr = align_ptr(ptr);
let (shift, mask) = get_shift_mask(ptr);
@@ -65,7 +65,7 @@ unsafe fn atomic_rmw<T, F: Fn(u32) -> u32>(ptr: *mut T, f: F) -> u32 {
let newval = f(curval);
let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask);
if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) {
- return curval;
+ return g(curval, newval);
}
}
}
@@ -89,13 +89,21 @@ unsafe fn atomic_cmpxchg<T>(ptr: *mut T, oldval: u32, newval: u32) -> u32 {
}
macro_rules! atomic_rmw {
- ($name:ident, $ty:ty, $op:expr) => {
+ ($name:ident, $ty:ty, $op:expr, $fetch:expr) => {
intrinsics! {
pub unsafe extern "C" fn $name(ptr: *mut $ty, val: $ty) -> $ty {
- atomic_rmw(ptr, |x| $op(x as $ty, val) as u32) as $ty
+ atomic_rmw(ptr, |x| $op(x as $ty, val) as u32, |old, new| $fetch(old, new)) as $ty
}
}
};
+
+ (@old $name:ident, $ty:ty, $op:expr) => {
+ atomic_rmw!($name, $ty, $op, |old, _| old);
+ };
+
+ (@new $name:ident, $ty:ty, $op:expr) => {
+ atomic_rmw!($name, $ty, $op, |_, new| new);
+ };
}
macro_rules! atomic_cmpxchg {
($name:ident, $ty:ty) => {
@@ -107,101 +115,129 @@ macro_rules! atomic_cmpxchg {
};
}
-atomic_rmw!(__sync_fetch_and_add_1, u8, |a: u8, b: u8| a.wrapping_add(b));
-atomic_rmw!(__sync_fetch_and_add_2, u16, |a: u16, b: u16| a
+atomic_rmw!(@old __sync_fetch_and_add_1, u8, |a: u8, b: u8| a.wrapping_add(b));
+atomic_rmw!(@old __sync_fetch_and_add_2, u16, |a: u16, b: u16| a
+ .wrapping_add(b));
+atomic_rmw!(@old __sync_fetch_and_add_4, u32, |a: u32, b: u32| a
+ .wrapping_add(b));
+
+atomic_rmw!(@new __sync_add_and_fetch_1, u8, |a: u8, b: u8| a.wrapping_add(b));
+atomic_rmw!(@new __sync_add_and_fetch_2, u16, |a: u16, b: u16| a
.wrapping_add(b));
-atomic_rmw!(__sync_fetch_and_add_4, u32, |a: u32, b: u32| a
+atomic_rmw!(@new __sync_add_and_fetch_4, u32, |a: u32, b: u32| a
.wrapping_add(b));
-atomic_rmw!(__sync_fetch_and_sub_1, u8, |a: u8, b: u8| a.wrapping_sub(b));
-atomic_rmw!(__sync_fetch_and_sub_2, u16, |a: u16, b: u16| a
+atomic_rmw!(@old __sync_fetch_and_sub_1, u8, |a: u8, b: u8| a.wrapping_sub(b));
+atomic_rmw!(@old __sync_fetch_and_sub_2, u16, |a: u16, b: u16| a
.wrapping_sub(b));
-atomic_rmw!(__sync_fetch_and_sub_4, u32, |a: u32, b: u32| a
+atomic_rmw!(@old __sync_fetch_and_sub_4, u32, |a: u32, b: u32| a
.wrapping_sub(b));
-atomic_rmw!(__sync_fetch_and_and_1, u8, |a: u8, b: u8| a & b);
-atomic_rmw!(__sync_fetch_and_and_2, u16, |a: u16, b: u16| a & b);
-atomic_rmw!(__sync_fetch_and_and_4, u32, |a: u32, b: u32| a & b);
+atomic_rmw!(@new __sync_sub_and_fetch_1, u8, |a: u8, b: u8| a.wrapping_sub(b));
+atomic_rmw!(@new __sync_sub_and_fetch_2, u16, |a: u16, b: u16| a
+ .wrapping_sub(b));
+atomic_rmw!(@new __sync_sub_and_fetch_4, u32, |a: u32, b: u32| a
+ .wrapping_sub(b));
+
+atomic_rmw!(@old __sync_fetch_and_and_1, u8, |a: u8, b: u8| a & b);
+atomic_rmw!(@old __sync_fetch_and_and_2, u16, |a: u16, b: u16| a & b);
+atomic_rmw!(@old __sync_fetch_and_and_4, u32, |a: u32, b: u32| a & b);
+
+atomic_rmw!(@new __sync_and_and_fetch_1, u8, |a: u8, b: u8| a & b);
+atomic_rmw!(@new __sync_and_and_fetch_2, u16, |a: u16, b: u16| a & b);
+atomic_rmw!(@new __sync_and_and_fetch_4, u32, |a: u32, b: u32| a & b);
+
+atomic_rmw!(@old __sync_fetch_and_or_1, u8, |a: u8, b: u8| a | b);
+atomic_rmw!(@old __sync_fetch_and_or_2, u16, |a: u16, b: u16| a | b);
+atomic_rmw!(@old __sync_fetch_and_or_4, u32, |a: u32, b: u32| a | b);
+
+atomic_rmw!(@new __sync_or_and_fetch_1, u8, |a: u8, b: u8| a | b);
+atomic_rmw!(@new __sync_or_and_fetch_2, u16, |a: u16, b: u16| a | b);
+atomic_rmw!(@new __sync_or_and_fetch_4, u32, |a: u32, b: u32| a | b);
+
+atomic_rmw!(@old __sync_fetch_and_xor_1, u8, |a: u8, b: u8| a ^ b);
+atomic_rmw!(@old __sync_fetch_and_xor_2, u16, |a: u16, b: u16| a ^ b);
+atomic_rmw!(@old __sync_fetch_and_xor_4, u32, |a: u32, b: u32| a ^ b);
-atomic_rmw!(__sync_fetch_and_or_1, u8, |a: u8, b: u8| a | b);
-atomic_rmw!(__sync_fetch_and_or_2, u16, |a: u16, b: u16| a | b);
-atomic_rmw!(__sync_fetch_and_or_4, u32, |a: u32, b: u32| a | b);
+atomic_rmw!(@new __sync_xor_and_fetch_1, u8, |a: u8, b: u8| a ^ b);
+atomic_rmw!(@new __sync_xor_and_fetch_2, u16, |a: u16, b: u16| a ^ b);
+atomic_rmw!(@new __sync_xor_and_fetch_4, u32, |a: u32, b: u32| a ^ b);
-atomic_rmw!(__sync_fetch_and_xor_1, u8, |a: u8, b: u8| a ^ b);
-atomic_rmw!(__sync_fetch_and_xor_2, u16, |a: u16, b: u16| a ^ b);
-atomic_rmw!(__sync_fetch_and_xor_4, u32, |a: u32, b: u32| a ^ b);
+atomic_rmw!(@old __sync_fetch_and_nand_1, u8, |a: u8, b: u8| !(a & b));
+atomic_rmw!(@old __sync_fetch_and_nand_2, u16, |a: u16, b: u16| !(a & b));
+atomic_rmw!(@old __sync_fetch_and_nand_4, u32, |a: u32, b: u32| !(a & b));
-atomic_rmw!(__sync_fetch_and_nand_1, u8, |a: u8, b: u8| !(a & b));
-atomic_rmw!(__sync_fetch_and_nand_2, u16, |a: u16, b: u16| !(a & b));
-atomic_rmw!(__sync_fetch_and_nand_4, u32, |a: u32, b: u32| !(a & b));
+atomic_rmw!(@new __sync_nand_and_fetch_1, u8, |a: u8, b: u8| !(a & b));
+atomic_rmw!(@new __sync_nand_and_fetch_2, u16, |a: u16, b: u16| !(a & b));
+atomic_rmw!(@new __sync_nand_and_fetch_4, u32, |a: u32, b: u32| !(a & b));
-atomic_rmw!(__sync_fetch_and_max_1, i8, |a: i8, b: i8| if a > b {
+atomic_rmw!(@old __sync_fetch_and_max_1, i8, |a: i8, b: i8| if a > b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_max_2, i16, |a: i16, b: i16| if a > b {
+atomic_rmw!(@old __sync_fetch_and_max_2, i16, |a: i16, b: i16| if a > b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_max_4, i32, |a: i32, b: i32| if a > b {
+atomic_rmw!(@old __sync_fetch_and_max_4, i32, |a: i32, b: i32| if a > b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_umax_1, u8, |a: u8, b: u8| if a > b {
+atomic_rmw!(@old __sync_fetch_and_umax_1, u8, |a: u8, b: u8| if a > b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_umax_2, u16, |a: u16, b: u16| if a > b {
+atomic_rmw!(@old __sync_fetch_and_umax_2, u16, |a: u16, b: u16| if a > b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_umax_4, u32, |a: u32, b: u32| if a > b {
+atomic_rmw!(@old __sync_fetch_and_umax_4, u32, |a: u32, b: u32| if a > b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_min_1, i8, |a: i8, b: i8| if a < b {
+atomic_rmw!(@old __sync_fetch_and_min_1, i8, |a: i8, b: i8| if a < b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_min_2, i16, |a: i16, b: i16| if a < b {
+atomic_rmw!(@old __sync_fetch_and_min_2, i16, |a: i16, b: i16| if a < b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_min_4, i32, |a: i32, b: i32| if a < b {
+atomic_rmw!(@old __sync_fetch_and_min_4, i32, |a: i32, b: i32| if a < b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_umin_1, u8, |a: u8, b: u8| if a < b {
+atomic_rmw!(@old __sync_fetch_and_umin_1, u8, |a: u8, b: u8| if a < b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_umin_2, u16, |a: u16, b: u16| if a < b {
+atomic_rmw!(@old __sync_fetch_and_umin_2, u16, |a: u16, b: u16| if a < b {
a
} else {
b
});
-atomic_rmw!(__sync_fetch_and_umin_4, u32, |a: u32, b: u32| if a < b {
+atomic_rmw!(@old __sync_fetch_and_umin_4, u32, |a: u32, b: u32| if a < b {
a
} else {
b
});
-atomic_rmw!(__sync_lock_test_and_set_1, u8, |_: u8, b: u8| b);
-atomic_rmw!(__sync_lock_test_and_set_2, u16, |_: u16, b: u16| b);
-atomic_rmw!(__sync_lock_test_and_set_4, u32, |_: u32, b: u32| b);
+atomic_rmw!(@old __sync_lock_test_and_set_1, u8, |_: u8, b: u8| b);
+atomic_rmw!(@old __sync_lock_test_and_set_2, u16, |_: u16, b: u16| b);
+atomic_rmw!(@old __sync_lock_test_and_set_4, u32, |_: u32, b: u32| b);
atomic_cmpxchg!(__sync_val_compare_and_swap_1, u8);
atomic_cmpxchg!(__sync_val_compare_and_swap_2, u16);
diff --git a/vendor/compiler_builtins/src/float/conv.rs b/vendor/compiler_builtins/src/float/conv.rs
index 07b58f3d2..68ba63408 100644
--- a/vendor/compiler_builtins/src/float/conv.rs
+++ b/vendor/compiler_builtins/src/float/conv.rs
@@ -92,12 +92,12 @@ intrinsics! {
f64::from_bits(int_to_float::u64_to_f64_bits(i))
}
- #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
+ #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
pub extern "C" fn __floatuntisf(i: u128) -> f32 {
f32::from_bits(int_to_float::u128_to_f32_bits(i))
}
- #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
+ #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
pub extern "C" fn __floatuntidf(i: u128) -> f64 {
f64::from_bits(int_to_float::u128_to_f64_bits(i))
}
@@ -129,13 +129,13 @@ intrinsics! {
f64::from_bits(int_to_float::u64_to_f64_bits(i.unsigned_abs()) | sign_bit)
}
- #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
+ #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
pub extern "C" fn __floattisf(i: i128) -> f32 {
let sign_bit = ((i >> 127) as u32) << 31;
f32::from_bits(int_to_float::u128_to_f32_bits(i.unsigned_abs()) | sign_bit)
}
- #[cfg_attr(not(target_feature = "llvm14-builtins-abi"), unadjusted_on_win64)]
+ #[cfg_attr(any(not(target_feature = "llvm14-builtins-abi"), target_os = "uefi"), unadjusted_on_win64)]
pub extern "C" fn __floattidf(i: i128) -> f64 {
let sign_bit = ((i >> 127) as u64) << 63;
f64::from_bits(int_to_float::u128_to_f64_bits(i.unsigned_abs()) | sign_bit)
diff --git a/vendor/compiler_builtins/src/lib.rs b/vendor/compiler_builtins/src/lib.rs
index 009923d27..e7bc61e4c 100644
--- a/vendor/compiler_builtins/src/lib.rs
+++ b/vendor/compiler_builtins/src/lib.rs
@@ -6,6 +6,7 @@
#![feature(compiler_builtins)]
#![feature(core_ffi_c)]
#![feature(core_intrinsics)]
+#![feature(inline_const)]
#![feature(lang_items)]
#![feature(linkage)]
#![feature(naked_functions)]
@@ -45,6 +46,7 @@ pub mod int;
all(target_family = "wasm", target_os = "unknown"),
all(target_arch = "x86_64", target_os = "uefi"),
all(target_arch = "arm", target_os = "none"),
+ target_os = "xous",
all(target_vendor = "fortanix", target_env = "sgx")
))]
pub mod math;
diff --git a/vendor/compiler_builtins/src/macros.rs b/vendor/compiler_builtins/src/macros.rs
index 518a18d4d..7d90b7aad 100644
--- a/vendor/compiler_builtins/src/macros.rs
+++ b/vendor/compiler_builtins/src/macros.rs
@@ -174,7 +174,7 @@ macro_rules! intrinsics {
$($rest:tt)*
) => (
- #[cfg(all(windows, target_pointer_width = "64"))]
+ #[cfg(all(any(windows, all(target_os = "uefi", target_arch = "x86_64")), target_pointer_width = "64"))]
intrinsics! {
$(#[$($attr)*])*
pub extern "unadjusted" fn $name( $($argname: $ty),* ) $(-> $ret)? {
@@ -182,7 +182,7 @@ macro_rules! intrinsics {
}
}
- #[cfg(not(all(windows, target_pointer_width = "64")))]
+ #[cfg(not(all(any(windows, all(target_os = "uefi", target_arch = "x86_64")), target_pointer_width = "64")))]
intrinsics! {
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
@@ -209,13 +209,13 @@ macro_rules! intrinsics {
$($rest:tt)*
) => (
- #[cfg(all(windows, target_arch = "x86_64"))]
+ #[cfg(all(any(windows, target_os = "uefi"), target_arch = "x86_64"))]
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
$($body)*
}
- #[cfg(all(windows, target_arch = "x86_64"))]
+ #[cfg(all(any(windows, target_os = "uefi"), target_arch = "x86_64"))]
pub mod $name {
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub extern $abi fn $name( $($argname: $ty),* )
@@ -226,7 +226,7 @@ macro_rules! intrinsics {
}
}
- #[cfg(not(all(windows, target_arch = "x86_64")))]
+ #[cfg(not(all(any(windows, target_os = "uefi"), target_arch = "x86_64")))]
intrinsics! {
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
@@ -426,7 +426,7 @@ macro_rules! intrinsics {
// Hack for LLVM expectations for ABI on windows. This is used by the
// `#[win64_128bit_abi_hack]` attribute recognized above
-#[cfg(all(windows, target_pointer_width = "64"))]
+#[cfg(all(any(windows, target_os = "uefi"), target_pointer_width = "64"))]
pub mod win64_128bit_abi_hack {
#[repr(simd)]
pub struct U64x2(u64, u64);
diff --git a/vendor/compiler_builtins/src/math.rs b/vendor/compiler_builtins/src/math.rs
index fa59753f8..fa9836186 100644
--- a/vendor/compiler_builtins/src/math.rs
+++ b/vendor/compiler_builtins/src/math.rs
@@ -20,6 +20,7 @@ macro_rules! no_mangle {
target_os = "unknown",
not(target_env = "wasi")
),
+ target_os = "xous",
all(target_arch = "x86_64", target_os = "uefi"),
all(target_arch = "xtensa", target_os = "none"),
all(target_vendor = "fortanix", target_env = "sgx")
@@ -62,6 +63,8 @@ no_mangle! {
fn tanhf(n: f32) -> f32;
fn ldexp(f: f64, n: i32) -> f64;
fn ldexpf(f: f32, n: i32) -> f32;
+ fn tgamma(x: f64) -> f64;
+ fn tgammaf(x: f32) -> f32;
}
#[cfg(any(
@@ -70,6 +73,8 @@ no_mangle! {
target_os = "unknown",
not(target_env = "wasi")
),
+ target_os = "xous",
+ all(target_arch = "x86_64", target_os = "uefi"),
all(target_arch = "xtensa", target_os = "none"),
all(target_vendor = "fortanix", target_env = "sgx")
))]
@@ -93,7 +98,17 @@ no_mangle! {
fn tanf(n: f32) -> f32;
}
-#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
+#[cfg(any(target_os = "xous", target_os = "uefi"))]
+no_mangle! {
+ fn sqrtf(x: f32) -> f32;
+ fn sqrt(x: f64) -> f64;
+}
+
+#[cfg(any(
+ all(target_vendor = "fortanix", target_env = "sgx"),
+ target_os = "xous",
+ target_os = "uefi"
+))]
no_mangle! {
fn ceil(x: f64) -> f64;
fn ceilf(x: f32) -> f32;
diff --git a/vendor/compiler_builtins/src/mem/impls.rs b/vendor/compiler_builtins/src/mem/impls.rs
index 815132425..72003a5c4 100644
--- a/vendor/compiler_builtins/src/mem/impls.rs
+++ b/vendor/compiler_builtins/src/mem/impls.rs
@@ -265,3 +265,17 @@ pub unsafe fn set_bytes(mut s: *mut u8, c: u8, mut n: usize) {
}
set_bytes_bytes(s, c, n);
}
+
+#[inline(always)]
+pub unsafe fn compare_bytes(s1: *const u8, s2: *const u8, n: usize) -> i32 {
+ let mut i = 0;
+ while i < n {
+ let a = *s1.add(i);
+ let b = *s2.add(i);
+ if a != b {
+ return a as i32 - b as i32;
+ }
+ i += 1;
+ }
+ 0
+}
diff --git a/vendor/compiler_builtins/src/mem/mod.rs b/vendor/compiler_builtins/src/mem/mod.rs
index a55113861..c5b0ddc16 100644
--- a/vendor/compiler_builtins/src/mem/mod.rs
+++ b/vendor/compiler_builtins/src/mem/mod.rs
@@ -51,16 +51,7 @@ intrinsics! {
#[mem_builtin]
#[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), linkage = "weak")]
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
- let mut i = 0;
- while i < n {
- let a = *s1.add(i);
- let b = *s2.add(i);
- if a != b {
- return a as i32 - b as i32;
- }
- i += 1;
- }
- 0
+ impls::compare_bytes(s1, s2, n)
}
#[mem_builtin]
diff --git a/vendor/compiler_builtins/src/mem/x86_64.rs b/vendor/compiler_builtins/src/mem/x86_64.rs
index a7ab6f605..17b461f79 100644
--- a/vendor/compiler_builtins/src/mem/x86_64.rs
+++ b/vendor/compiler_builtins/src/mem/x86_64.rs
@@ -16,6 +16,10 @@
// feature is present at compile-time. We don't bother detecting other features.
// Note that ERMSB does not enhance the backwards (DF=1) "rep movsb".
+use core::arch::asm;
+use core::intrinsics;
+use core::mem;
+
#[inline(always)]
#[cfg(target_feature = "ermsb")]
pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) {
@@ -31,16 +35,26 @@ pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) {
#[inline(always)]
#[cfg(not(target_feature = "ermsb"))]
-pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) {
- let qword_count = count >> 3;
- let byte_count = count & 0b111;
- // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust.
- core::arch::asm!(
- "repe movsq (%rsi), (%rdi)",
- "mov {byte_count:e}, %ecx",
- "repe movsb (%rsi), (%rdi)",
- byte_count = in(reg) byte_count,
+pub unsafe fn copy_forward(mut dest: *mut u8, mut src: *const u8, count: usize) {
+ let (pre_byte_count, qword_count, byte_count) = rep_param(dest, count);
+ // Separating the blocks gives the compiler more freedom to reorder instructions.
+ asm!(
+ "rep movsb",
+ inout("ecx") pre_byte_count => _,
+ inout("rdi") dest => dest,
+ inout("rsi") src => src,
+ options(att_syntax, nostack, preserves_flags)
+ );
+ asm!(
+ "rep movsq",
inout("rcx") qword_count => _,
+ inout("rdi") dest => dest,
+ inout("rsi") src => src,
+ options(att_syntax, nostack, preserves_flags)
+ );
+ asm!(
+ "rep movsb",
+ inout("ecx") byte_count => _,
inout("rdi") dest => _,
inout("rsi") src => _,
options(att_syntax, nostack, preserves_flags)
@@ -49,22 +63,28 @@ pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) {
#[inline(always)]
pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) {
- let qword_count = count >> 3;
- let byte_count = count & 0b111;
- // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust.
- core::arch::asm!(
+ let (pre_byte_count, qword_count, byte_count) = rep_param(dest, count);
+ // We can't separate this block due to std/cld
+ asm!(
"std",
- "repe movsq (%rsi), (%rdi)",
- "movl {byte_count:e}, %ecx",
- "addq $7, %rdi",
- "addq $7, %rsi",
- "repe movsb (%rsi), (%rdi)",
+ "rep movsb",
+ "sub $7, %rsi",
+ "sub $7, %rdi",
+ "mov {qword_count}, %rcx",
+ "rep movsq",
+ "test {pre_byte_count:e}, {pre_byte_count:e}",
+ "add $7, %rsi",
+ "add $7, %rdi",
+ "mov {pre_byte_count:e}, %ecx",
+ "rep movsb",
"cld",
- byte_count = in(reg) byte_count,
- inout("rcx") qword_count => _,
- inout("rdi") dest.add(count).wrapping_sub(8) => _,
- inout("rsi") src.add(count).wrapping_sub(8) => _,
- options(att_syntax, nostack)
+ pre_byte_count = in(reg) pre_byte_count,
+ qword_count = in(reg) qword_count,
+ inout("ecx") byte_count => _,
+ inout("rdi") dest.add(count - 1) => _,
+ inout("rsi") src.add(count - 1) => _,
+ // We modify flags, but we restore it afterwards
+ options(att_syntax, nostack, preserves_flags)
);
}
@@ -83,18 +103,82 @@ pub unsafe fn set_bytes(dest: *mut u8, c: u8, count: usize) {
#[inline(always)]
#[cfg(not(target_feature = "ermsb"))]
-pub unsafe fn set_bytes(dest: *mut u8, c: u8, count: usize) {
- let qword_count = count >> 3;
- let byte_count = count & 0b111;
- // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust.
- core::arch::asm!(
- "repe stosq %rax, (%rdi)",
- "mov {byte_count:e}, %ecx",
- "repe stosb %al, (%rdi)",
- byte_count = in(reg) byte_count,
+pub unsafe fn set_bytes(mut dest: *mut u8, c: u8, count: usize) {
+ let c = c as u64 * 0x0101_0101_0101_0101;
+ let (pre_byte_count, qword_count, byte_count) = rep_param(dest, count);
+ // Separating the blocks gives the compiler more freedom to reorder instructions.
+ asm!(
+ "rep stosb",
+ inout("ecx") pre_byte_count => _,
+ inout("rdi") dest => dest,
+ in("rax") c,
+ options(att_syntax, nostack, preserves_flags)
+ );
+ asm!(
+ "rep stosq",
inout("rcx") qword_count => _,
+ inout("rdi") dest => dest,
+ in("rax") c,
+ options(att_syntax, nostack, preserves_flags)
+ );
+ asm!(
+ "rep stosb",
+ inout("ecx") byte_count => _,
inout("rdi") dest => _,
- in("rax") (c as u64) * 0x0101010101010101,
+ in("rax") c,
options(att_syntax, nostack, preserves_flags)
);
}
+
+#[inline(always)]
+pub unsafe fn compare_bytes(a: *const u8, b: *const u8, n: usize) -> i32 {
+ #[inline(always)]
+ unsafe fn cmp<T, U, F>(mut a: *const T, mut b: *const T, n: usize, f: F) -> i32
+ where
+ T: Clone + Copy + Eq,
+ U: Clone + Copy + Eq,
+ F: FnOnce(*const U, *const U, usize) -> i32,
+ {
+ // Ensure T is not a ZST.
+ const { assert!(mem::size_of::<T>() != 0) };
+
+ let end = a.add(intrinsics::unchecked_div(n, mem::size_of::<T>()));
+ while a != end {
+ if a.read_unaligned() != b.read_unaligned() {
+ return f(a.cast(), b.cast(), mem::size_of::<T>());
+ }
+ a = a.add(1);
+ b = b.add(1);
+ }
+ f(
+ a.cast(),
+ b.cast(),
+ intrinsics::unchecked_rem(n, mem::size_of::<T>()),
+ )
+ }
+ let c1 = |mut a: *const u8, mut b: *const u8, n| {
+ for _ in 0..n {
+ if a.read() != b.read() {
+ return i32::from(a.read()) - i32::from(b.read());
+ }
+ a = a.add(1);
+ b = b.add(1);
+ }
+ 0
+ };
+ let c2 = |a: *const u16, b, n| cmp(a, b, n, c1);
+ let c4 = |a: *const u32, b, n| cmp(a, b, n, c2);
+ let c8 = |a: *const u64, b, n| cmp(a, b, n, c4);
+ let c16 = |a: *const u128, b, n| cmp(a, b, n, c8);
+ c16(a.cast(), b.cast(), n)
+}
+
+/// Determine optimal parameters for a `rep` instruction.
+fn rep_param(dest: *mut u8, mut count: usize) -> (usize, usize, usize) {
+ // Unaligned writes are still slow on modern processors, so align the destination address.
+ let pre_byte_count = ((8 - (dest as usize & 0b111)) & 0b111).min(count);
+ count -= pre_byte_count;
+ let qword_count = count >> 3;
+ let byte_count = count & 0b111;
+ (pre_byte_count, qword_count, byte_count)
+}
diff --git a/vendor/crossbeam-channel/.cargo-checksum.json b/vendor/crossbeam-channel/.cargo-checksum.json
index dd210c73b..96db2f1ab 100644
--- a/vendor/crossbeam-channel/.cargo-checksum.json
+++ b/vendor/crossbeam-channel/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"704f57293fd91b9801cb8befda7622900b6f02ffe76387ea03bd7e9a041ede50","Cargo.lock":"3b56bd551cb1b7d4e733413036c67b1407ac40e4899e8a368641884e0986ce60","Cargo.toml":"d5d17d3cace2539f582aa6aa6b41c1be09e621266fd0839cdb63920db04e229a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","LICENSE-THIRD-PARTY":"b16db96b93b1d7cf7bea533f572091ec6bca3234fbe0a83038be772ff391a44c","README.md":"415a71d4978cfd338a6ae1f1b41284652eccd277a815542c304647dc437a8274","benches/crossbeam.rs":"96cb1abd23cac3ef8a7174a802e94609926b555bb02c9658c78723d433f1dd92","examples/fibonacci.rs":"4e88fa40048cdc31e9c7bb60347d46f92543d7ddf39cab3b52bfe44affdb6a02","examples/matching.rs":"63c250e164607a7a9f643d46f107bb5da846d49e89cf9069909562d20e530f71","examples/stopwatch.rs":"d02121258f08d56f1eb7997e19bcb9bacb6836cfa0abbba90a9e59d8a50ae5cf","src/channel.rs":"9538e285101c152e23c5ff6a47b0305753d94a5b27f3426499052b0e3d0f97ee","src/context.rs":"ff4d39639ddf16aaab582d4a5f3d10ef2c71afe1abbf4e60f3d9d2ddbd72c230","src/counter.rs":"c49a9f44587888850edeb62f7c8ecd1acecb39c836834254ff3ac934c478440a","src/err.rs":"44cb2024ee6b0cd6fd24996430e53720769f64b4ac35016bc3e05cb9db48681d","src/flavors/array.rs":"08e37b7c07e9a525a32cc61f89b384b897a8d852b2eda5e85ea0cf4ba7527a3f","src/flavors/at.rs":"1db64919593b7c14f838c16a22732515f1e716d2d5f6cc639f42631380e545cd","src/flavors/list.rs":"c05da598d0759b05c345050df1f6206946098203e3021260bd722f5ea24d9240","src/flavors/mod.rs":"3d9d43bc38b0adb18c96c995c2bd3421d8e33ab6c30b20c3c467d21d48e485dc","src/flavors/never.rs":"747da857aa1a7601641f23f4930e6ad00ebaf50456d9be5c7aa270e2ecc24dcb","src/flavors/tick.rs":"69b2dfe0186bc8b9fd7a73e32da59d2656d8150da1e00fba92a412e0907568a3","src/flavors/zero.rs":"d7e67264d7b33152f52f1d4d8cdb565334b53508f56308f72140528d0645aa73","src/lib.rs":"3a65706d4124844ffc4c8cb1f8cc779631ec94f449f85cbb68364ad3619404f1","src/select.rs":"3b00c3929d3a8973e46188db41f6ae0b47c89ab108cf7ec2cb348e272e77e132","src/select_macro.rs":"283acd04870356b0c4d3d4046c5070638b562c9ffb8fa29c1a5b90a2509bf3af","src/utils.rs":"0b6e6621198236c077fcb6b66203317e36dc8f1a157dd3b22ad422b6599ae389","src/waker.rs":"6839108d1c9357b3c0c1c162c8b4633ff5ac4f756e95e677ac1293e7df942635","tests/after.rs":"0154a8e152880db17a20514ecdd49dabc361d3629858d119b9746b5e932c780c","tests/array.rs":"be8176ac8f1376567f28e60c15e95b9baf8cb4c8e0e2c1de9b286a49c988dc73","tests/golang.rs":"708a4d0d94abacb2c054ac117eff79689398f76a5cb089ca188dd2b4ed53ec6b","tests/iter.rs":"25dc02135bbae9d47a30f9047661648e66bdc134e40ba78bc2fbacbb8b3819bc","tests/list.rs":"0937da0413fa9ecdcba687c4c07c9b254bc82fb85cb2f836425550890c31ed36","tests/mpsc.rs":"5a49429a29c9028ade618994e82d03d4f4405b62fb89a4464ba9d89e68a1a88d","tests/never.rs":"ee40c4fc4dd5af4983fae8de6927f52b81174d222c162f745b26c4a6c7108e4f","tests/ready.rs":"d349702f123925a0781b48d677e6dcf64fc5d1fc788a7bf1e151a3d57e81871c","tests/same_channel.rs":"2bab761443671e841e1b2476bd8082d75533a2f6be7946f5dbcee67cdc82dccb","tests/select.rs":"e5e9308e3adcc4c99f98cd7ad5f8149ec7030845d6263e9a5a27c317aa96363f","tests/select_macro.rs":"141adb62fddc1c1973b24b0cbcf87bae06fc537be4f8fbb68e12e0864e73795c","tests/thread_locals.rs":"a1ce59e2aff69161621c0cb215eb6ea238088c06a31a8507a74cf179fd5a4299","tests/tick.rs":"5f697bd14c48505d932e82065b5302ef668e1cc19cac18e8ac22e0c83c221c1d","tests/zero.rs":"54f8ee1fa8316a99457f1c6bb5a8e31c4b21d39b3b4d79b276a53c6340940c8f"},"package":"4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"f87a526ab720644e07509dd76d29c08993a5e52a6d6ec230d809fc31a1c0e403","Cargo.lock":"8af0a5f8b3d1e6f036332a5ecc91b30222343f29a465ea398bca3298c0212f4a","Cargo.toml":"81a227ee6f529cd0cf62327f63eb098fed59c04dde2a8e68aeaa0ea32dbafbcf","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","LICENSE-THIRD-PARTY":"b16db96b93b1d7cf7bea533f572091ec6bca3234fbe0a83038be772ff391a44c","README.md":"4e16587d8f6a15f2016f256535aa6c9429424672ebdcd03c1a7d964746e46127","benches/crossbeam.rs":"96cb1abd23cac3ef8a7174a802e94609926b555bb02c9658c78723d433f1dd92","examples/fibonacci.rs":"4e88fa40048cdc31e9c7bb60347d46f92543d7ddf39cab3b52bfe44affdb6a02","examples/matching.rs":"63c250e164607a7a9f643d46f107bb5da846d49e89cf9069909562d20e530f71","examples/stopwatch.rs":"d02121258f08d56f1eb7997e19bcb9bacb6836cfa0abbba90a9e59d8a50ae5cf","src/channel.rs":"9538e285101c152e23c5ff6a47b0305753d94a5b27f3426499052b0e3d0f97ee","src/context.rs":"ff4d39639ddf16aaab582d4a5f3d10ef2c71afe1abbf4e60f3d9d2ddbd72c230","src/counter.rs":"c49a9f44587888850edeb62f7c8ecd1acecb39c836834254ff3ac934c478440a","src/err.rs":"44cb2024ee6b0cd6fd24996430e53720769f64b4ac35016bc3e05cb9db48681d","src/flavors/array.rs":"508e54587fc8d9e8dfacd16446a601e33838d7bb1dfd9d7ccc3e65315b66b35a","src/flavors/at.rs":"1db64919593b7c14f838c16a22732515f1e716d2d5f6cc639f42631380e545cd","src/flavors/list.rs":"d901d9259185a71aeb5cf74be70e5c38b550c7f38b87e023196cb47fed2d1a11","src/flavors/mod.rs":"3d9d43bc38b0adb18c96c995c2bd3421d8e33ab6c30b20c3c467d21d48e485dc","src/flavors/never.rs":"747da857aa1a7601641f23f4930e6ad00ebaf50456d9be5c7aa270e2ecc24dcb","src/flavors/tick.rs":"69b2dfe0186bc8b9fd7a73e32da59d2656d8150da1e00fba92a412e0907568a3","src/flavors/zero.rs":"7458eb0ece475dc5093b4f2cde13f6de57e4f70291258850de4fa3c951c8f594","src/lib.rs":"3a65706d4124844ffc4c8cb1f8cc779631ec94f449f85cbb68364ad3619404f1","src/select.rs":"3b00c3929d3a8973e46188db41f6ae0b47c89ab108cf7ec2cb348e272e77e132","src/select_macro.rs":"283acd04870356b0c4d3d4046c5070638b562c9ffb8fa29c1a5b90a2509bf3af","src/utils.rs":"0b6e6621198236c077fcb6b66203317e36dc8f1a157dd3b22ad422b6599ae389","src/waker.rs":"6839108d1c9357b3c0c1c162c8b4633ff5ac4f756e95e677ac1293e7df942635","tests/after.rs":"0154a8e152880db17a20514ecdd49dabc361d3629858d119b9746b5e932c780c","tests/array.rs":"a57ae6264e676f573d7adb5c4b024994e98bc6811352516adb3444f880f7125e","tests/golang.rs":"284bed0d4c07857f33de96f2addc9a69c5688f864935a3e3e113c88c04bd826b","tests/iter.rs":"25dc02135bbae9d47a30f9047661648e66bdc134e40ba78bc2fbacbb8b3819bc","tests/list.rs":"3d1a4ae23bb6b4767242b8109a8efda26f1d3b28c0f90da3368f8eb9ca0eee37","tests/mpsc.rs":"d1e185c6290240132a34aa91221271225959f8652d7fc4ceb546ee9712361176","tests/never.rs":"ee40c4fc4dd5af4983fae8de6927f52b81174d222c162f745b26c4a6c7108e4f","tests/ready.rs":"d349702f123925a0781b48d677e6dcf64fc5d1fc788a7bf1e151a3d57e81871c","tests/same_channel.rs":"2bab761443671e841e1b2476bd8082d75533a2f6be7946f5dbcee67cdc82dccb","tests/select.rs":"ce12a8e0284fb9ccf6c1543bec309d9054193e6d942663aed19aa8499ef69c43","tests/select_macro.rs":"597d526fbd021ce70619d9172c931439f778ee3034ec1479aea461b65971a81a","tests/thread_locals.rs":"25ab70a8dcd8a0da9173e5476e17dcc8916caa5b68207d9c403655deaa8e8f4a","tests/tick.rs":"5f697bd14c48505d932e82065b5302ef668e1cc19cac18e8ac22e0c83c221c1d","tests/zero.rs":"9c5af802d5efb2c711f8242b8905ed29cc2601e48dbd95e41c7e6fbfe2918398"},"package":"c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"} \ No newline at end of file
diff --git a/vendor/crossbeam-channel/CHANGELOG.md b/vendor/crossbeam-channel/CHANGELOG.md
index 2f627cf26..f0d11e60c 100644
--- a/vendor/crossbeam-channel/CHANGELOG.md
+++ b/vendor/crossbeam-channel/CHANGELOG.md
@@ -1,3 +1,7 @@
+# Version 0.5.6
+
+- Bump the minimum supported Rust version to 1.38. (#877)
+
# Version 0.5.5
- Replace Spinlock with Mutex. (#835)
diff --git a/vendor/crossbeam-channel/Cargo.lock b/vendor/crossbeam-channel/Cargo.lock
index cd6eb056f..e40f83650 100644
--- a/vendor/crossbeam-channel/Cargo.lock
+++ b/vendor/crossbeam-channel/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam-channel"
-version = "0.5.5"
+version = "0.5.6"
dependencies = [
"cfg-if",
"crossbeam-utils",
@@ -21,9 +21,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.9"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978"
+checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if",
"once_cell",
@@ -67,9 +67,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "ppv-lite86"
diff --git a/vendor/crossbeam-channel/Cargo.toml b/vendor/crossbeam-channel/Cargo.toml
index c02f8595c..619fad423 100644
--- a/vendor/crossbeam-channel/Cargo.toml
+++ b/vendor/crossbeam-channel/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2018"
-rust-version = "1.36"
+rust-version = "1.38"
name = "crossbeam-channel"
-version = "0.5.5"
+version = "0.5.6"
description = "Multi-producer multi-consumer channels for message passing"
homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel"
readme = "README.md"
diff --git a/vendor/crossbeam-channel/README.md b/vendor/crossbeam-channel/README.md
index f5077c556..4c42d863c 100644
--- a/vendor/crossbeam-channel/README.md
+++ b/vendor/crossbeam-channel/README.md
@@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel#license)
https://crates.io/crates/crossbeam-channel)
[![Documentation](https://docs.rs/crossbeam-channel/badge.svg)](
https://docs.rs/crossbeam-channel)
-[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
+[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)](
https://www.rust-lang.org)
[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
@@ -48,7 +48,7 @@ crossbeam-channel = "0.5"
Crossbeam Channel supports stable Rust releases going back at least six months,
and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.36.
+version is released. Currently, the minimum supported Rust version is 1.38.
## License
diff --git a/vendor/crossbeam-channel/src/flavors/array.rs b/vendor/crossbeam-channel/src/flavors/array.rs
index 73557d385..63b82eb85 100644
--- a/vendor/crossbeam-channel/src/flavors/array.rs
+++ b/vendor/crossbeam-channel/src/flavors/array.rs
@@ -216,7 +216,7 @@ impl<T> Channel<T> {
return Err(msg);
}
- let slot: &Slot<T> = &*(token.array.slot as *const Slot<T>);
+ let slot: &Slot<T> = &*token.array.slot.cast::<Slot<T>>();
// Write the message into the slot and update the stamp.
slot.msg.get().write(MaybeUninit::new(msg));
@@ -307,7 +307,7 @@ impl<T> Channel<T> {
return Err(());
}
- let slot: &Slot<T> = &*(token.array.slot as *const Slot<T>);
+ let slot: &Slot<T> = &*token.array.slot.cast::<Slot<T>>();
// Read the message from the slot and update the stamp.
let msg = slot.msg.get().read().assume_init();
diff --git a/vendor/crossbeam-channel/src/flavors/list.rs b/vendor/crossbeam-channel/src/flavors/list.rs
index 9bda6d1cc..6090b8d47 100644
--- a/vendor/crossbeam-channel/src/flavors/list.rs
+++ b/vendor/crossbeam-channel/src/flavors/list.rs
@@ -49,6 +49,11 @@ struct Slot<T> {
}
impl<T> Slot<T> {
+ const UNINIT: Self = Self {
+ msg: UnsafeCell::new(MaybeUninit::uninit()),
+ state: AtomicUsize::new(0),
+ };
+
/// Waits until a message is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
@@ -72,13 +77,10 @@ struct Block<T> {
impl<T> Block<T> {
/// Creates an empty block.
fn new() -> Block<T> {
- // SAFETY: This is safe because:
- // [1] `Block::next` (AtomicPtr) may be safely zero initialized.
- // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
- // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it
- // holds a MaybeUninit.
- // [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
- unsafe { MaybeUninit::zeroed().assume_init() }
+ Self {
+ next: AtomicPtr::new(ptr::null_mut()),
+ slots: [Slot::UNINIT; BLOCK_CAP],
+ }
}
/// Waits until the next pointer is set.
@@ -283,7 +285,7 @@ impl<T> Channel<T> {
}
// Write the message into the slot.
- let block = token.list.block as *mut Block<T>;
+ let block = token.list.block.cast::<Block<T>>();
let offset = token.list.offset;
let slot = (*block).slots.get_unchecked(offset);
slot.msg.get().write(MaybeUninit::new(msg));
diff --git a/vendor/crossbeam-channel/src/flavors/zero.rs b/vendor/crossbeam-channel/src/flavors/zero.rs
index 31e62afac..aae2ea300 100644
--- a/vendor/crossbeam-channel/src/flavors/zero.rs
+++ b/vendor/crossbeam-channel/src/flavors/zero.rs
@@ -190,7 +190,7 @@ impl<T> Channel<T> {
// heap-allocated packet.
packet.wait_ready();
let msg = packet.msg.get().replace(None).unwrap();
- drop(Box::from_raw(token.zero.0 as *mut Packet<T>));
+ drop(Box::from_raw(token.zero.0.cast::<Packet<T>>()));
Ok(msg)
}
}
@@ -409,7 +409,7 @@ impl<T> SelectHandle for Receiver<'_, T> {
let mut inner = self.0.inner.lock().unwrap();
inner
.receivers
- .register_with_packet(oper, packet as *mut (), cx);
+ .register_with_packet(oper, packet.cast::<()>(), cx);
inner.senders.notify();
inner.senders.can_select() || inner.is_disconnected
}
@@ -417,7 +417,7 @@ impl<T> SelectHandle for Receiver<'_, T> {
fn unregister(&self, oper: Operation) {
if let Some(operation) = self.0.inner.lock().unwrap().receivers.unregister(oper) {
unsafe {
- drop(Box::from_raw(operation.packet as *mut Packet<T>));
+ drop(Box::from_raw(operation.packet.cast::<Packet<T>>()));
}
}
}
@@ -459,7 +459,7 @@ impl<T> SelectHandle for Sender<'_, T> {
let mut inner = self.0.inner.lock().unwrap();
inner
.senders
- .register_with_packet(oper, packet as *mut (), cx);
+ .register_with_packet(oper, packet.cast::<()>(), cx);
inner.receivers.notify();
inner.receivers.can_select() || inner.is_disconnected
}
@@ -467,7 +467,7 @@ impl<T> SelectHandle for Sender<'_, T> {
fn unregister(&self, oper: Operation) {
if let Some(operation) = self.0.inner.lock().unwrap().senders.unregister(oper) {
unsafe {
- drop(Box::from_raw(operation.packet as *mut Packet<T>));
+ drop(Box::from_raw(operation.packet.cast::<Packet<T>>()));
}
}
}
diff --git a/vendor/crossbeam-channel/tests/array.rs b/vendor/crossbeam-channel/tests/array.rs
index de843cd32..6fd8ffcc6 100644
--- a/vendor/crossbeam-channel/tests/array.rs
+++ b/vendor/crossbeam-channel/tests/array.rs
@@ -377,7 +377,7 @@ fn spsc() {
#[test]
fn mpmc() {
#[cfg(miri)]
- const COUNT: usize = 100;
+ const COUNT: usize = 50;
#[cfg(not(miri))]
const COUNT: usize = 25_000;
const THREADS: usize = 4;
@@ -532,16 +532,12 @@ fn drops() {
scope.spawn(|_| {
for _ in 0..steps {
r.recv().unwrap();
- #[cfg(miri)]
- std::thread::yield_now(); // https://github.com/rust-lang/miri/issues/1388
}
});
scope.spawn(|_| {
for _ in 0..steps {
s.send(DropCounter).unwrap();
- #[cfg(miri)]
- std::thread::yield_now(); // https://github.com/rust-lang/miri/issues/1388
}
});
})
diff --git a/vendor/crossbeam-channel/tests/golang.rs b/vendor/crossbeam-channel/tests/golang.rs
index 6a46c0353..8050716c6 100644
--- a/vendor/crossbeam-channel/tests/golang.rs
+++ b/vendor/crossbeam-channel/tests/golang.rs
@@ -959,7 +959,7 @@ mod chan_test {
#[test]
fn test_chan() {
#[cfg(miri)]
- const N: i32 = 20;
+ const N: i32 = 12;
#[cfg(not(miri))]
const N: i32 = 200;
@@ -1489,7 +1489,7 @@ mod chan_test {
fn test_multi_consumer() {
const NWORK: usize = 23;
#[cfg(miri)]
- const NITER: usize = 100;
+ const NITER: usize = 50;
#[cfg(not(miri))]
const NITER: usize = 271828;
@@ -1580,9 +1580,7 @@ mod race_chan_test {
}
// https://github.com/golang/go/blob/master/test/ken/chan.go
-#[cfg(not(miri))] // Miri is too slow
mod chan {
-
use super::*;
const MESSAGES_PER_CHANEL: u32 = 76;
@@ -2052,6 +2050,7 @@ mod chan {
}
#[test]
+ #[cfg_attr(miri, ignore)] // Miri is too slow
fn main() {
let mut ctx = Context {
nproc: Arc::new(Mutex::new(0)),
diff --git a/vendor/crossbeam-channel/tests/list.rs b/vendor/crossbeam-channel/tests/list.rs
index a0b908722..ebe6f6f85 100644
--- a/vendor/crossbeam-channel/tests/list.rs
+++ b/vendor/crossbeam-channel/tests/list.rs
@@ -67,6 +67,7 @@ fn len_empty_full() {
}
#[test]
+#[cfg_attr(miri, ignore)] // this test makes timing assumptions, but Miri is so slow it violates them
fn try_recv() {
let (s, r) = unbounded();
@@ -433,8 +434,6 @@ fn drops() {
scope.spawn(|_| {
for _ in 0..steps {
r.recv().unwrap();
- #[cfg(miri)]
- std::thread::yield_now(); // https://github.com/rust-lang/miri/issues/1388
}
});
diff --git a/vendor/crossbeam-channel/tests/mpsc.rs b/vendor/crossbeam-channel/tests/mpsc.rs
index 3db4812c6..d7cc8e25f 100644
--- a/vendor/crossbeam-channel/tests/mpsc.rs
+++ b/vendor/crossbeam-channel/tests/mpsc.rs
@@ -339,25 +339,22 @@ mod channel_tests {
#[test]
fn stress_shared() {
- #[cfg(miri)]
- const AMT: u32 = 100;
- #[cfg(not(miri))]
- const AMT: u32 = 10000;
- const NTHREADS: u32 = 8;
+ let amt: u32 = if cfg!(miri) { 100 } else { 10_000 };
+ let nthreads: u32 = if cfg!(miri) { 4 } else { 8 };
let (tx, rx) = channel::<i32>();
let t = thread::spawn(move || {
- for _ in 0..AMT * NTHREADS {
+ for _ in 0..amt * nthreads {
assert_eq!(rx.recv().unwrap(), 1);
}
assert!(rx.try_recv().is_err());
});
- let mut ts = Vec::with_capacity(NTHREADS as usize);
- for _ in 0..NTHREADS {
+ let mut ts = Vec::with_capacity(nthreads as usize);
+ for _ in 0..nthreads {
let tx = tx.clone();
let t = thread::spawn(move || {
- for _ in 0..AMT {
+ for _ in 0..amt {
tx.send(1).unwrap();
}
});
diff --git a/vendor/crossbeam-channel/tests/select.rs b/vendor/crossbeam-channel/tests/select.rs
index e7691f52e..bc5824dab 100644
--- a/vendor/crossbeam-channel/tests/select.rs
+++ b/vendor/crossbeam-channel/tests/select.rs
@@ -408,7 +408,6 @@ fn both_ready() {
.unwrap();
}
-#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn loop_try() {
const RUNS: usize = 20;
diff --git a/vendor/crossbeam-channel/tests/select_macro.rs b/vendor/crossbeam-channel/tests/select_macro.rs
index 91c04e1c3..119454cd6 100644
--- a/vendor/crossbeam-channel/tests/select_macro.rs
+++ b/vendor/crossbeam-channel/tests/select_macro.rs
@@ -284,7 +284,6 @@ fn both_ready() {
.unwrap();
}
-#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn loop_try() {
const RUNS: usize = 20;
diff --git a/vendor/crossbeam-channel/tests/thread_locals.rs b/vendor/crossbeam-channel/tests/thread_locals.rs
index effb6a143..fb4e577f2 100644
--- a/vendor/crossbeam-channel/tests/thread_locals.rs
+++ b/vendor/crossbeam-channel/tests/thread_locals.rs
@@ -1,6 +1,6 @@
//! Tests that make sure accessing thread-locals while exiting the thread doesn't cause panics.
-#![cfg(not(miri))] // error: abnormal termination: the evaluated program aborted execution
+#![cfg(not(miri))] // Miri detects that this test is buggy: the destructor of `FOO` uses `std::thread::current()`!
use std::thread;
use std::time::Duration;
diff --git a/vendor/crossbeam-channel/tests/zero.rs b/vendor/crossbeam-channel/tests/zero.rs
index c90d74187..74c9a3e10 100644
--- a/vendor/crossbeam-channel/tests/zero.rs
+++ b/vendor/crossbeam-channel/tests/zero.rs
@@ -328,9 +328,11 @@ fn stress_oneshot() {
}
}
-#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn stress_iter() {
+ #[cfg(miri)]
+ const COUNT: usize = 50;
+ #[cfg(not(miri))]
const COUNT: usize = 1000;
let (request_s, request_r) = bounded(0);
@@ -403,7 +405,7 @@ fn drops() {
#[cfg(not(miri))]
const RUNS: usize = 100;
#[cfg(miri)]
- const STEPS: usize = 500;
+ const STEPS: usize = 100;
#[cfg(not(miri))]
const STEPS: usize = 10_000;
@@ -485,7 +487,7 @@ fn fairness() {
#[test]
fn fairness_duplicates() {
#[cfg(miri)]
- const COUNT: usize = 50;
+ const COUNT: usize = 100;
#[cfg(not(miri))]
const COUNT: usize = 10_000;
diff --git a/vendor/crossbeam-deque/.cargo-checksum.json b/vendor/crossbeam-deque/.cargo-checksum.json
index c4f2a9329..45404d824 100644
--- a/vendor/crossbeam-deque/.cargo-checksum.json
+++ b/vendor/crossbeam-deque/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"7d5f333652da0da5f068ff91ecf259599f9ff4a4448bd987dd451699b66f0f59","Cargo.toml":"a9a138b4e005ddea76f588ca7004629ebd8f1a64cd1d55474fe36cae4c57a890","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"6b0a911f542186ef96eb56537cade0ecf1a5731d5d494b7094ff87f0fdeb7710","src/deque.rs":"64a2153dc566847fd9fa0e6b2b7adb3933af9984fbe3429b6f1200b058bb9850","src/lib.rs":"9f0581481691bc698176f369410726adf597d470b9d14e226a65f490d6aff8c6","tests/fifo.rs":"1d83f9ffeeba2cd6bd32f1ab136d843b8c73075d5045619be12dc3c27d8ab3ba","tests/injector.rs":"6812c97615e3f685b5612c390861f2e570ff469f3b9871ba97ddbed5c1f5266b","tests/lifo.rs":"b2ddc8154492322e734b23f35ce54040f9ec84ef878009de3a64d44d35c365a6","tests/steal.rs":"cdf588cc13eeb275ef1231eb18e3245faca7a2d054fa6527bfdba2a34bc8f7bf"},"package":"6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"ad5f2c10299e57aaed2d1b8f8a109faa2dfb16c52ce81f60ec5adb0ea9308d7f","Cargo.toml":"4802e7c0d5ab1dc35c162671483a6ee9bff5a3f1d6dd620a01863ac25068019e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"3c62aa0ee37cf714b5b3c304545d5caea4cc0a71020fccb1f146611d64202bb2","src/deque.rs":"cfb3c5b3bcea1f27ca2633d8b8576ff2080e1e9fc083236f2db7916bb77786ed","src/lib.rs":"ec0257a388627d691d652fd04d261c5c0590e1e31a35c8bf5912afac51fd5734","tests/fifo.rs":"3d98e0d4ca7cfddf10708b71642cf1ff05543d067ad837e48401d63cc31c0a18","tests/injector.rs":"fb054ef9fcac5f12e08b7b3451f370b96ab7589d32ef5c02e25958a473c45519","tests/lifo.rs":"57abdb3fc5920a422f785ba308b658bdc5400947532eeffb799f2395a2061549","tests/steal.rs":"cdf588cc13eeb275ef1231eb18e3245faca7a2d054fa6527bfdba2a34bc8f7bf"},"package":"715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"} \ No newline at end of file
diff --git a/vendor/crossbeam-deque/CHANGELOG.md b/vendor/crossbeam-deque/CHANGELOG.md
index 14dcc20b7..855b714f4 100644
--- a/vendor/crossbeam-deque/CHANGELOG.md
+++ b/vendor/crossbeam-deque/CHANGELOG.md
@@ -1,3 +1,7 @@
+# Version 0.8.2
+
+- Bump the minimum supported Rust version to 1.38. (#877)
+
# Version 0.8.1
- Fix deque steal race condition. (#726)
@@ -5,26 +9,40 @@
# Version 0.8.0
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Bump the minimum supported Rust version to 1.36.
- Add `Worker::len()` and `Injector::len()` methods.
- Add `std` (enabled by default) feature for forward compatibility.
+# Version 0.7.4
+
+- Fix deque steal race condition.
+
# Version 0.7.3
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Stop stealing from the same deque. (#448)
- Fix unsoundness issues by adopting `MaybeUninit`. (#458)
# Version 0.7.2
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Bump `crossbeam-epoch` to `0.8`.
- Bump `crossbeam-utils` to `0.7`.
# Version 0.7.1
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Bump the minimum required version of `crossbeam-utils`.
# Version 0.7.0
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Make `Worker::pop()` faster in the FIFO case.
- Replace `fifo()` nad `lifo()` with `Worker::new_fifo()` and `Worker::new_lifo()`.
- Add more batched steal methods.
diff --git a/vendor/crossbeam-deque/Cargo.toml b/vendor/crossbeam-deque/Cargo.toml
index 3ea5a59f6..4ff10b353 100644
--- a/vendor/crossbeam-deque/Cargo.toml
+++ b/vendor/crossbeam-deque/Cargo.toml
@@ -11,16 +11,26 @@
[package]
edition = "2018"
+rust-version = "1.38"
name = "crossbeam-deque"
-version = "0.8.1"
-authors = ["The Crossbeam Project Developers"]
+version = "0.8.2"
description = "Concurrent work-stealing deque"
homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-deque"
-documentation = "https://docs.rs/crossbeam-deque"
-keywords = ["chase-lev", "lock-free", "scheduler", "scheduling"]
-categories = ["algorithms", "concurrency", "data-structures"]
+readme = "README.md"
+keywords = [
+ "chase-lev",
+ "lock-free",
+ "scheduler",
+ "scheduling",
+]
+categories = [
+ "algorithms",
+ "concurrency",
+ "data-structures",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/crossbeam-rs/crossbeam"
+
[dependencies.cfg-if]
version = "1"
@@ -33,9 +43,13 @@ default-features = false
version = "0.8"
optional = true
default-features = false
+
[dev-dependencies.rand]
version = "0.8"
[features]
default = ["std"]
-std = ["crossbeam-epoch/std", "crossbeam-utils/std"]
+std = [
+ "crossbeam-epoch/std",
+ "crossbeam-utils/std",
+]
diff --git a/vendor/crossbeam-deque/README.md b/vendor/crossbeam-deque/README.md
index 8ad1a7278..23c8794c2 100644
--- a/vendor/crossbeam-deque/README.md
+++ b/vendor/crossbeam-deque/README.md
@@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-deque#license)
https://crates.io/crates/crossbeam-deque)
[![Documentation](https://docs.rs/crossbeam-deque/badge.svg)](
https://docs.rs/crossbeam-deque)
-[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
+[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)](
https://www.rust-lang.org)
[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
@@ -28,7 +28,7 @@ crossbeam-deque = "0.8"
Crossbeam Deque supports stable Rust releases going back at least six months,
and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.36.
+version is released. Currently, the minimum supported Rust version is 1.38.
## License
diff --git a/vendor/crossbeam-deque/src/deque.rs b/vendor/crossbeam-deque/src/deque.rs
index 802a2fef5..bda3bf820 100644
--- a/vendor/crossbeam-deque/src/deque.rs
+++ b/vendor/crossbeam-deque/src/deque.rs
@@ -3,7 +3,7 @@ use std::cmp;
use std::fmt;
use std::iter::FromIterator;
use std::marker::PhantomData;
-use std::mem::{self, MaybeUninit};
+use std::mem::{self, ManuallyDrop, MaybeUninit};
use std::ptr;
use std::sync::atomic::{self, AtomicIsize, AtomicPtr, AtomicUsize, Ordering};
use std::sync::Arc;
@@ -38,9 +38,8 @@ impl<T> Buffer<T> {
fn alloc(cap: usize) -> Buffer<T> {
debug_assert_eq!(cap, cap.next_power_of_two());
- let mut v = Vec::with_capacity(cap);
+ let mut v = ManuallyDrop::new(Vec::with_capacity(cap));
let ptr = v.as_mut_ptr();
- mem::forget(v);
Buffer { ptr, cap }
}
@@ -53,6 +52,8 @@ impl<T> Buffer<T> {
/// Returns a pointer to the task at the specified `index`.
unsafe fn at(&self, index: isize) -> *mut T {
// `self.cap` is always a power of two.
+ // We do all the loads at `MaybeUninit` because we might realize, after loading, that we
+ // don't actually have the right to access this memory.
self.ptr.offset(index & (self.cap - 1) as isize)
}
@@ -62,8 +63,8 @@ impl<T> Buffer<T> {
/// technically speaking a data race and therefore UB. We should use an atomic store here, but
/// that would be more expensive and difficult to implement generically for all types `T`.
/// Hence, as a hack, we use a volatile write instead.
- unsafe fn write(&self, index: isize, task: T) {
- ptr::write_volatile(self.at(index), task)
+ unsafe fn write(&self, index: isize, task: MaybeUninit<T>) {
+ ptr::write_volatile(self.at(index).cast::<MaybeUninit<T>>(), task)
}
/// Reads a task from the specified `index`.
@@ -71,9 +72,9 @@ impl<T> Buffer<T> {
/// This method might be concurrently called with another `write` at the same index, which is
/// technically speaking a data race and therefore UB. We should use an atomic load here, but
/// that would be more expensive and difficult to implement generically for all types `T`.
- /// Hence, as a hack, we use a volatile write instead.
- unsafe fn read(&self, index: isize) -> T {
- ptr::read_volatile(self.at(index))
+ /// Hence, as a hack, we use a volatile load instead.
+ unsafe fn read(&self, index: isize) -> MaybeUninit<T> {
+ ptr::read_volatile(self.at(index).cast::<MaybeUninit<T>>())
}
}
@@ -115,8 +116,8 @@ struct Inner<T> {
impl<T> Drop for Inner<T> {
fn drop(&mut self) {
// Load the back index, front index, and buffer.
- let b = self.back.load(Ordering::Relaxed);
- let f = self.front.load(Ordering::Relaxed);
+ let b = *self.back.get_mut();
+ let f = *self.front.get_mut();
unsafe {
let buffer = self.buffer.load(Ordering::Relaxed, epoch::unprotected());
@@ -406,7 +407,7 @@ impl<T> Worker<T> {
// Write `task` into the slot.
unsafe {
- buffer.write(b, task);
+ buffer.write(b, MaybeUninit::new(task));
}
atomic::fence(Ordering::Release);
@@ -461,7 +462,7 @@ impl<T> Worker<T> {
unsafe {
// Read the popped task.
let buffer = self.buffer.get();
- let task = buffer.read(f);
+ let task = buffer.read(f).assume_init();
// Shrink the buffer if `len - 1` is less than one fourth of the capacity.
if buffer.cap > MIN_CAP && len <= buffer.cap as isize / 4 {
@@ -509,8 +510,8 @@ impl<T> Worker<T> {
)
.is_err()
{
- // Failed. We didn't pop anything.
- mem::forget(task.take());
+ // Failed. We didn't pop anything. Reset to `None`.
+ task.take();
}
// Restore the back index to the original task.
@@ -524,7 +525,7 @@ impl<T> Worker<T> {
}
}
- task
+ task.map(|t| unsafe { t.assume_init() })
}
}
}
@@ -661,12 +662,11 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it.
- mem::forget(task);
return Steal::Retry;
}
// Return the stolen task.
- Steal::Success(task)
+ Steal::Success(unsafe { task.assume_init() })
}
/// Steals a batch of tasks and pushes them into another worker.
@@ -821,7 +821,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it and break from the loop.
- mem::forget(task);
batch_size = i;
break;
}
@@ -975,7 +974,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it.
- mem::forget(task);
return Steal::Retry;
}
@@ -992,7 +990,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it.
- mem::forget(task);
return Steal::Retry;
}
@@ -1037,7 +1034,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it and break from the loop.
- mem::forget(tmp);
batch_size = i;
break;
}
@@ -1077,7 +1073,7 @@ impl<T> Stealer<T> {
dest.inner.back.store(dest_b, Ordering::Release);
// Return with success.
- Steal::Success(task)
+ Steal::Success(unsafe { task.assume_init() })
}
}
@@ -1123,6 +1119,11 @@ struct Slot<T> {
}
impl<T> Slot<T> {
+ const UNINIT: Self = Self {
+ task: UnsafeCell::new(MaybeUninit::uninit()),
+ state: AtomicUsize::new(0),
+ };
+
/// Waits until a task is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
@@ -1146,13 +1147,10 @@ struct Block<T> {
impl<T> Block<T> {
/// Creates an empty block that starts at `start_index`.
fn new() -> Block<T> {
- // SAFETY: This is safe because:
- // [1] `Block::next` (AtomicPtr) may be safely zero initialized.
- // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
- // [3] `Slot::task` (UnsafeCell) may be safely zero initialized because it
- // holds a MaybeUninit.
- // [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
- unsafe { MaybeUninit::zeroed().assume_init() }
+ Self {
+ next: AtomicPtr::new(ptr::null_mut()),
+ slots: [Slot::UNINIT; BLOCK_CAP],
+ }
}
/// Waits until the next pointer is set.
@@ -1535,7 +1533,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add(i as isize), task);
@@ -1547,7 +1545,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add((batch_size - 1 - i) as isize), task);
@@ -1689,7 +1687,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
match dest.flavor {
Flavor::Fifo => {
@@ -1698,7 +1696,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i + 1);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add(i as isize), task);
@@ -1711,7 +1709,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i + 1);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add((batch_size - 1 - i) as isize), task);
@@ -1744,7 +1742,7 @@ impl<T> Injector<T> {
}
}
- Steal::Success(task)
+ Steal::Success(task.assume_init())
}
}
@@ -1820,9 +1818,9 @@ impl<T> Injector<T> {
impl<T> Drop for Injector<T> {
fn drop(&mut self) {
- let mut head = self.head.index.load(Ordering::Relaxed);
- let mut tail = self.tail.index.load(Ordering::Relaxed);
- let mut block = self.head.block.load(Ordering::Relaxed);
+ let mut head = *self.head.index.get_mut();
+ let mut tail = *self.tail.index.get_mut();
+ let mut block = *self.head.block.get_mut();
// Erase the lower bits.
head &= !((1 << SHIFT) - 1);
@@ -1840,7 +1838,7 @@ impl<T> Drop for Injector<T> {
p.as_mut_ptr().drop_in_place();
} else {
// Deallocate the block and move to the next one.
- let next = (*block).next.load(Ordering::Relaxed);
+ let next = *(*block).next.get_mut();
drop(Box::from_raw(block));
block = next;
}
diff --git a/vendor/crossbeam-deque/src/lib.rs b/vendor/crossbeam-deque/src/lib.rs
index 16bc728b3..b696b5f96 100644
--- a/vendor/crossbeam-deque/src/lib.rs
+++ b/vendor/crossbeam-deque/src/lib.rs
@@ -95,6 +95,7 @@
rust_2018_idioms,
unreachable_pub
)]
+#![allow(clippy::question_mark)] // https://github.com/rust-lang/rust-clippy/issues/8281
#![cfg_attr(not(feature = "std"), no_std)]
use cfg_if::cfg_if;
diff --git a/vendor/crossbeam-deque/tests/fifo.rs b/vendor/crossbeam-deque/tests/fifo.rs
index e2365fb91..f98737b58 100644
--- a/vendor/crossbeam-deque/tests/fifo.rs
+++ b/vendor/crossbeam-deque/tests/fifo.rs
@@ -71,6 +71,9 @@ fn is_empty() {
#[test]
fn spsc() {
+ #[cfg(miri)]
+ const STEPS: usize = 500;
+ #[cfg(not(miri))]
const STEPS: usize = 50_000;
let w = Worker::new_fifo();
@@ -100,6 +103,9 @@ fn spsc() {
#[test]
fn stampede() {
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
let w = Worker::new_fifo();
@@ -141,6 +147,9 @@ fn stampede() {
#[test]
fn stress() {
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
let w = Worker::new_fifo();
@@ -197,6 +206,7 @@ fn stress() {
.unwrap();
}
+#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn no_starvation() {
const THREADS: usize = 8;
@@ -258,8 +268,17 @@ fn no_starvation() {
#[test]
fn destructors() {
+ #[cfg(miri)]
+ const THREADS: usize = 2;
+ #[cfg(not(miri))]
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
+ #[cfg(miri)]
+ const STEPS: usize = 100;
+ #[cfg(not(miri))]
const STEPS: usize = 1000;
struct Elem(usize, Arc<Mutex<Vec<usize>>>);
@@ -330,7 +349,7 @@ fn destructors() {
{
let mut v = dropped.lock().unwrap();
assert_eq!(v.len(), rem);
- v.sort();
+ v.sort_unstable();
for pair in v.windows(2) {
assert_eq!(pair[0] + 1, pair[1]);
}
diff --git a/vendor/crossbeam-deque/tests/injector.rs b/vendor/crossbeam-deque/tests/injector.rs
index 3f74d1bfb..f706a8d9c 100644
--- a/vendor/crossbeam-deque/tests/injector.rs
+++ b/vendor/crossbeam-deque/tests/injector.rs
@@ -46,6 +46,9 @@ fn is_empty() {
#[test]
fn spsc() {
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 100_000;
let q = Injector::new();
@@ -58,6 +61,8 @@ fn spsc() {
assert_eq!(i, v);
break;
}
+ #[cfg(miri)]
+ std::hint::spin_loop();
}
}
@@ -73,6 +78,9 @@ fn spsc() {
#[test]
fn mpmc() {
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 25_000;
const THREADS: usize = 4;
@@ -96,6 +104,8 @@ fn mpmc() {
v[n].fetch_add(1, SeqCst);
break;
}
+ #[cfg(miri)]
+ std::hint::spin_loop();
}
}
});
@@ -111,6 +121,9 @@ fn mpmc() {
#[test]
fn stampede() {
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
let q = Injector::new();
@@ -152,6 +165,9 @@ fn stampede() {
#[test]
fn stress() {
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
let q = Injector::new();
@@ -208,6 +224,7 @@ fn stress() {
.unwrap();
}
+#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn no_starvation() {
const THREADS: usize = 8;
@@ -269,8 +286,17 @@ fn no_starvation() {
#[test]
fn destructors() {
+ #[cfg(miri)]
+ const THREADS: usize = 2;
+ #[cfg(not(miri))]
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
+ #[cfg(miri)]
+ const STEPS: usize = 100;
+ #[cfg(not(miri))]
const STEPS: usize = 1000;
struct Elem(usize, Arc<Mutex<Vec<usize>>>);
@@ -341,7 +367,7 @@ fn destructors() {
{
let mut v = dropped.lock().unwrap();
assert_eq!(v.len(), rem);
- v.sort();
+ v.sort_unstable();
for pair in v.windows(2) {
assert_eq!(pair[0] + 1, pair[1]);
}
diff --git a/vendor/crossbeam-deque/tests/lifo.rs b/vendor/crossbeam-deque/tests/lifo.rs
index 3e99e95c5..c1a65cd2e 100644
--- a/vendor/crossbeam-deque/tests/lifo.rs
+++ b/vendor/crossbeam-deque/tests/lifo.rs
@@ -71,6 +71,9 @@ fn is_empty() {
#[test]
fn spsc() {
+ #[cfg(miri)]
+ const STEPS: usize = 500;
+ #[cfg(not(miri))]
const STEPS: usize = 50_000;
let w = Worker::new_lifo();
@@ -84,6 +87,8 @@ fn spsc() {
assert_eq!(i, v);
break;
}
+ #[cfg(miri)]
+ std::hint::spin_loop();
}
}
@@ -100,6 +105,9 @@ fn spsc() {
#[test]
fn stampede() {
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
let w = Worker::new_lifo();
@@ -141,6 +149,9 @@ fn stampede() {
#[test]
fn stress() {
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
let w = Worker::new_lifo();
@@ -197,6 +208,7 @@ fn stress() {
.unwrap();
}
+#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn no_starvation() {
const THREADS: usize = 8;
@@ -258,8 +270,17 @@ fn no_starvation() {
#[test]
fn destructors() {
+ #[cfg(miri)]
+ const THREADS: usize = 2;
+ #[cfg(not(miri))]
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
+ #[cfg(miri)]
+ const STEPS: usize = 100;
+ #[cfg(not(miri))]
const STEPS: usize = 1000;
struct Elem(usize, Arc<Mutex<Vec<usize>>>);
@@ -330,7 +351,7 @@ fn destructors() {
{
let mut v = dropped.lock().unwrap();
assert_eq!(v.len(), rem);
- v.sort();
+ v.sort_unstable();
for pair in v.windows(2) {
assert_eq!(pair[0] + 1, pair[1]);
}
diff --git a/vendor/crossbeam-epoch/.cargo-checksum.json b/vendor/crossbeam-epoch/.cargo-checksum.json
index beb3eb1dd..21e5f8500 100644
--- a/vendor/crossbeam-epoch/.cargo-checksum.json
+++ b/vendor/crossbeam-epoch/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"709c5824af9170953e84db2552f4e8ae84d115314b59b768c62bdcd13c157e82","Cargo.lock":"cd480e52977de5a2e4182c1620fb5da9134fe82bfc6f696905ec0a1e1bd3d039","Cargo.toml":"1506e2615575ffc45c05dbcc248687740f04de5732b30bdb2d828ef4c4ae809b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"f946b25082979595d3851d90c4e76424be921a779e88e982f8455d44d46057ec","benches/defer.rs":"c330b704d96b2ad1aed29f72c37a99da534adef8cb06a3976d5f93bf567abb20","benches/flush.rs":"0389ac6c473632f0e93c962f223404cc360257f6699b4ec90b9b3be16bb6d74f","benches/pin.rs":"2f649a5153745c7930efdb32a52f9dc522f7b8cf548a251c5e2c82ee25dc3fff","build.rs":"aec5ae4d47d6ab1f281db6b7f7ec80ab3cc05bd0c20059643aee4446fcc0fcbf","examples/sanitize.rs":"a39d1635fa61e643e59192d7a63becc97ff81f03c1f4e03d38cedefb1525026a","no_atomic.rs":"916ed15218bb7b75a4e0d432430e7134efd27ca43ca8a8766e0c90e89febb602","src/atomic.rs":"6452c856fd808e99c8fc09fe7b563ce44342f9992b38c65613933c7c3fc5d84c","src/collector.rs":"e2d9780d8707e49360b3c33f2f829f29f70e6929307e65e23449b8ba6def6358","src/default.rs":"9c4d3951981d47efc748674d64b22eff27ecb2e3ef16369aa423592740ce6033","src/deferred.rs":"8ced786536d8d688381a8aa0b61e6e4d5e4fdd88e892cf82c0c5731e4801aa60","src/epoch.rs":"d31e66d8fe62299928e25867336d96391b26a4fe890a1cae0885dfcf36d6835b","src/guard.rs":"55c56ca1b2fbc067ae21108f0f7de4be91e5b41df2492055b635ed436782dd52","src/internal.rs":"67a6811b8c58e1152fd1dc17e389884025a0d99d79ab03dee26efcd0d6896690","src/lib.rs":"1c0765413dd66d4655e6417a69829ac5c2f4d504f66f77a87fe9c230c05e039d","src/sync/list.rs":"10aa4c59845ab9ff1d8bcb6f594b70bbe23c320fa7a2b125fdf85df88b9d61e2","src/sync/mod.rs":"cbc6334460d73761c3dea7f99ed2ccbf267d5da3bc76c812e94f85c9f4565c6a","src/sync/queue.rs":"06173b2255677d0d39178ceb49876fda2878f491e907c595eb65643dbb43c9ba","tests/loom.rs":"db772f4478966de6ec98774ca4093171dc942da635822a0d2d3257d31188cb9b"},"package":"07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"4a701ed7814fbde912aa7a1d15c95ed6b7ba3cd661c64f92c17b3b8bf67ecf5e","Cargo.lock":"018d954edeff6a45c6af01735239b639a83eed8258176481c6e9dae366085760","Cargo.toml":"4c1451a736e2ec0b31dfe6080140b69fdc614a0606db876308f1badf932dc1b9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"d67d0cf57751a019707dd95785345ee181a10ea80237789bc3c19bf28c0d45ca","benches/defer.rs":"c330b704d96b2ad1aed29f72c37a99da534adef8cb06a3976d5f93bf567abb20","benches/flush.rs":"0389ac6c473632f0e93c962f223404cc360257f6699b4ec90b9b3be16bb6d74f","benches/pin.rs":"2f649a5153745c7930efdb32a52f9dc522f7b8cf548a251c5e2c82ee25dc3fff","build.rs":"89e236e4e22dd748720129dcd02edfc08adccf708a7f0b03e41780e5bafb39cc","examples/sanitize.rs":"a39d1635fa61e643e59192d7a63becc97ff81f03c1f4e03d38cedefb1525026a","no_atomic.rs":"916ed15218bb7b75a4e0d432430e7134efd27ca43ca8a8766e0c90e89febb602","src/atomic.rs":"1bd4275c1411852024533e8a70959dfedf72029e3253544d1fbb0cc18b6fd519","src/collector.rs":"29e5911f61510247659b0090517bd1a38d11e1ed86e35811603cb599962d9a58","src/default.rs":"9c4d3951981d47efc748674d64b22eff27ecb2e3ef16369aa423592740ce6033","src/deferred.rs":"0c87df5797212778edd3c2d5fcf0cc04e8b9ed100261ecf9522f74a90804a3d5","src/epoch.rs":"d31e66d8fe62299928e25867336d96391b26a4fe890a1cae0885dfcf36d6835b","src/guard.rs":"f4439909152d38c03b6dfb6eeba6c9f07c39962187d461c92a492c27c258670b","src/internal.rs":"ac40ce276f0ed3dfd561926b78f775592eabb90790e177edde41fe50c13b8256","src/lib.rs":"1c0765413dd66d4655e6417a69829ac5c2f4d504f66f77a87fe9c230c05e039d","src/sync/list.rs":"10aa4c59845ab9ff1d8bcb6f594b70bbe23c320fa7a2b125fdf85df88b9d61e2","src/sync/mod.rs":"cbc6334460d73761c3dea7f99ed2ccbf267d5da3bc76c812e94f85c9f4565c6a","src/sync/queue.rs":"06173b2255677d0d39178ceb49876fda2878f491e907c595eb65643dbb43c9ba","tests/loom.rs":"db772f4478966de6ec98774ca4093171dc942da635822a0d2d3257d31188cb9b"},"package":"045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"} \ No newline at end of file
diff --git a/vendor/crossbeam-epoch/CHANGELOG.md b/vendor/crossbeam-epoch/CHANGELOG.md
index 2f70edba7..b05a52dfc 100644
--- a/vendor/crossbeam-epoch/CHANGELOG.md
+++ b/vendor/crossbeam-epoch/CHANGELOG.md
@@ -1,3 +1,9 @@
+# Version 0.9.10
+
+- Bump the minimum supported Rust version to 1.38. (#877)
+- Mitigate the risk of segmentation faults in buggy downstream implementations. (#879)
+- Add `{Atomic, Shared}::try_into_owned` (#701)
+
# Version 0.9.9
- Replace lazy_static with once_cell. (#817)
diff --git a/vendor/crossbeam-epoch/Cargo.lock b/vendor/crossbeam-epoch/Cargo.lock
index edb0c7378..726980a93 100644
--- a/vendor/crossbeam-epoch/Cargo.lock
+++ b/vendor/crossbeam-epoch/Cargo.lock
@@ -31,7 +31,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam-epoch"
-version = "0.9.9"
+version = "0.9.10"
dependencies = [
"autocfg",
"cfg-if",
@@ -46,9 +46,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.9"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978"
+checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if",
"loom",
@@ -57,15 +57,15 @@ dependencies = [
[[package]]
name = "generator"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee"
+checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7"
dependencies = [
"cc",
"libc",
"log",
"rustversion",
- "winapi",
+ "windows",
]
[[package]]
@@ -133,9 +133,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "pin-project-lite"
@@ -151,18 +151,18 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro2"
-version = "1.0.39"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
@@ -199,9 +199,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.5.6"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"regex-syntax",
]
@@ -217,15 +217,15 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.26"
+version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "rustversion"
-version = "1.0.6"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
+checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8"
[[package]]
name = "scoped-tls"
@@ -250,15 +250,15 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.8.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
+checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]]
name = "syn"
-version = "1.0.96"
+version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
+checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
@@ -288,9 +288,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.21"
+version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
+checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
dependencies = [
"proc-macro2",
"quote",
@@ -299,9 +299,9 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.27"
+version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
+checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
"once_cell",
"valuable",
@@ -320,13 +320,13 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.11"
+version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596"
+checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"
dependencies = [
"ansi_term",
- "lazy_static",
"matchers",
+ "once_cell",
"regex",
"sharded-slab",
"smallvec",
@@ -338,9 +338,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
+checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "valuable"
@@ -375,3 +375,46 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
+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.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
diff --git a/vendor/crossbeam-epoch/Cargo.toml b/vendor/crossbeam-epoch/Cargo.toml
index 9d68295e6..1551c3c2c 100644
--- a/vendor/crossbeam-epoch/Cargo.toml
+++ b/vendor/crossbeam-epoch/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2018"
-rust-version = "1.36"
+rust-version = "1.38"
name = "crossbeam-epoch"
-version = "0.9.9"
+version = "0.9.10"
description = "Epoch-based garbage collection"
homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch"
readme = "README.md"
diff --git a/vendor/crossbeam-epoch/README.md b/vendor/crossbeam-epoch/README.md
index eb33badff..2840ea792 100644
--- a/vendor/crossbeam-epoch/README.md
+++ b/vendor/crossbeam-epoch/README.md
@@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch#license)
https://crates.io/crates/crossbeam-epoch)
[![Documentation](https://docs.rs/crossbeam-epoch/badge.svg)](
https://docs.rs/crossbeam-epoch)
-[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
+[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)](
https://www.rust-lang.org)
[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
@@ -35,7 +35,7 @@ crossbeam-epoch = "0.9"
Crossbeam Epoch supports stable Rust releases going back at least six months,
and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.36.
+version is released. Currently, the minimum supported Rust version is 1.38.
## License
diff --git a/vendor/crossbeam-epoch/build.rs b/vendor/crossbeam-epoch/build.rs
index bba54d999..b3bd15a5a 100644
--- a/vendor/crossbeam-epoch/build.rs
+++ b/vendor/crossbeam-epoch/build.rs
@@ -41,17 +41,15 @@ fn main() {
}
};
- // Note that this is `no_*`, not `has_*`. This allows treating
- // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
- // run. This is needed for compatibility with non-cargo build systems that
- // don't run the build script.
+ // Note that this is `no_`*, not `has_*`. This allows treating as the latest
+ // stable rustc is used when the build script doesn't run. This is useful
+ // for non-cargo build systems that don't run the build script.
if NO_ATOMIC_CAS.contains(&&*target) {
println!("cargo:rustc-cfg=crossbeam_no_atomic_cas");
}
- if cfg.probe_rustc_version(1, 61) {
- // TODO: invert cfg once Rust 1.61 became stable.
- println!("cargo:rustc-cfg=crossbeam_const_fn_trait_bound");
+ if !cfg.probe_rustc_version(1, 61) {
+ println!("cargo:rustc-cfg=crossbeam_no_const_fn_trait_bound");
}
println!("cargo:rerun-if-changed=no_atomic.rs");
diff --git a/vendor/crossbeam-epoch/src/atomic.rs b/vendor/crossbeam-epoch/src/atomic.rs
index b0b6a68e7..19bab4729 100644
--- a/vendor/crossbeam-epoch/src/atomic.rs
+++ b/vendor/crossbeam-epoch/src/atomic.rs
@@ -252,7 +252,7 @@ impl<T> Pointable for [MaybeUninit<T>] {
let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * len;
let align = mem::align_of::<Array<T>>();
let layout = alloc::Layout::from_size_align(size, align).unwrap();
- let ptr = alloc::alloc(layout) as *mut Array<T>;
+ let ptr = alloc::alloc(layout).cast::<Array<T>>();
if ptr.is_null() {
alloc::handle_alloc_error(layout);
}
@@ -305,6 +305,7 @@ impl<T> Atomic<T> {
/// use crossbeam_epoch::Atomic;
///
/// let a = Atomic::new(1234);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn new(init: T) -> Atomic<T> {
Self::init(init)
@@ -320,6 +321,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// use crossbeam_epoch::Atomic;
///
/// let a = Atomic::<i32>::init(1234);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn init(init: T::Init) -> Atomic<T> {
Self::from(Owned::init(init))
@@ -342,7 +344,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
///
/// let a = Atomic::<i32>::null();
/// ```
- #[cfg(all(crossbeam_const_fn_trait_bound, not(crossbeam_loom)))]
+ #[cfg(all(not(crossbeam_no_const_fn_trait_bound), not(crossbeam_loom)))]
pub const fn null() -> Atomic<T> {
Self {
data: AtomicUsize::new(0),
@@ -351,7 +353,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
}
/// Returns a new null atomic pointer.
- #[cfg(not(all(crossbeam_const_fn_trait_bound, not(crossbeam_loom))))]
+ #[cfg(not(all(not(crossbeam_no_const_fn_trait_bound), not(crossbeam_loom))))]
pub fn null() -> Atomic<T> {
Self {
data: AtomicUsize::new(0),
@@ -373,6 +375,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// let a = Atomic::new(1234);
/// let guard = &epoch::pin();
/// let p = a.load(SeqCst, guard);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn load<'g>(&self, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
unsafe { Shared::from_usize(self.data.load(ord)) }
@@ -398,6 +401,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// let a = Atomic::new(1234);
/// let guard = &epoch::pin();
/// let p = a.load_consume(guard);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn load_consume<'g>(&self, _: &'g Guard) -> Shared<'g, T> {
unsafe { Shared::from_usize(self.data.load_consume()) }
@@ -415,8 +419,10 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// use std::sync::atomic::Ordering::SeqCst;
///
/// let a = Atomic::new(1234);
+ /// # unsafe { drop(a.load(SeqCst, &crossbeam_epoch::pin()).into_owned()); } // avoid leak
/// a.store(Shared::null(), SeqCst);
/// a.store(Owned::new(1234), SeqCst);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn store<P: Pointer<T>>(&self, new: P, ord: Ordering) {
self.data.store(new.into_usize(), ord);
@@ -437,6 +443,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// let a = Atomic::new(1234);
/// let guard = &epoch::pin();
/// let p = a.swap(Shared::null(), SeqCst, guard);
+ /// # unsafe { drop(p.into_owned()); } // avoid leak
/// ```
pub fn swap<'g, P: Pointer<T>>(&self, new: P, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
unsafe { Shared::from_usize(self.data.swap(new.into_usize(), ord)) }
@@ -471,6 +478,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// let curr = a.load(SeqCst, guard);
/// let res1 = a.compare_exchange(curr, Shared::null(), SeqCst, SeqCst, guard);
/// let res2 = a.compare_exchange(curr, Owned::new(5678), SeqCst, SeqCst, guard);
+ /// # unsafe { drop(curr.into_owned()); } // avoid leak
/// ```
pub fn compare_exchange<'g, P>(
&self,
@@ -526,6 +534,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
///
/// let mut new = Owned::new(5678);
/// let mut ptr = a.load(SeqCst, guard);
+ /// # unsafe { drop(a.load(SeqCst, guard).into_owned()); } // avoid leak
/// loop {
/// match a.compare_exchange_weak(ptr, new, SeqCst, SeqCst, guard) {
/// Ok(p) => {
@@ -546,6 +555,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// Err(err) => curr = err.current,
/// }
/// }
+ /// # unsafe { drop(curr.into_owned()); } // avoid leak
/// ```
pub fn compare_exchange_weak<'g, P>(
&self,
@@ -608,6 +618,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
///
/// let res2 = a.fetch_update(SeqCst, SeqCst, guard, |x| None);
/// assert!(res2.is_err());
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn fetch_update<'g, F>(
&self,
@@ -666,6 +677,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// let curr = a.load(SeqCst, guard);
/// let res1 = a.compare_and_set(curr, Shared::null(), SeqCst, guard);
/// let res2 = a.compare_and_set(curr, Owned::new(5678), SeqCst, guard);
+ /// # unsafe { drop(curr.into_owned()); } // avoid leak
/// ```
// TODO: remove in the next major version.
#[allow(deprecated)]
@@ -723,6 +735,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
///
/// let mut new = Owned::new(5678);
/// let mut ptr = a.load(SeqCst, guard);
+ /// # unsafe { drop(a.load(SeqCst, guard).into_owned()); } // avoid leak
/// loop {
/// match a.compare_and_set_weak(ptr, new, SeqCst, guard) {
/// Ok(p) => {
@@ -743,6 +756,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
/// Err(err) => curr = err.current,
/// }
/// }
+ /// # unsafe { drop(curr.into_owned()); } // avoid leak
/// ```
// TODO: remove in the next major version.
#[allow(deprecated)]
@@ -877,6 +891,52 @@ impl<T: ?Sized + Pointable> Atomic<T> {
Owned::from_usize(self.data.into_inner())
}
}
+
+ /// Takes ownership of the pointee if it is non-null.
+ ///
+ /// This consumes the atomic and converts it into [`Owned`]. As [`Atomic`] doesn't have a
+ /// destructor and doesn't drop the pointee while [`Owned`] does, this is suitable for
+ /// destructors of data structures.
+ ///
+ /// # Safety
+ ///
+ /// This method may be called only if the pointer is valid and nobody else is holding a
+ /// reference to the same object, or the pointer is null.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use std::mem;
+ /// # use crossbeam_epoch::Atomic;
+ /// struct DataStructure {
+ /// ptr: Atomic<usize>,
+ /// }
+ ///
+ /// impl Drop for DataStructure {
+ /// fn drop(&mut self) {
+ /// // By now the DataStructure lives only in our thread and we are sure we don't hold
+ /// // any Shared or & to it ourselves, but it may be null, so we have to be careful.
+ /// let old = mem::replace(&mut self.ptr, Atomic::null());
+ /// unsafe {
+ /// if let Some(x) = old.try_into_owned() {
+ /// drop(x)
+ /// }
+ /// }
+ /// }
+ /// }
+ /// ```
+ pub unsafe fn try_into_owned(self) -> Option<Owned<T>> {
+ // FIXME: See self.into_owned()
+ #[cfg(crossbeam_loom)]
+ let data = self.data.unsync_load();
+ #[cfg(not(crossbeam_loom))]
+ let data = self.data.into_inner();
+ if decompose_tag::<T>(data).0 == 0 {
+ None
+ } else {
+ Some(Owned::from_usize(data))
+ }
+ }
}
impl<T: ?Sized + Pointable> fmt::Debug for Atomic<T> {
@@ -925,6 +985,7 @@ impl<T: ?Sized + Pointable> From<Owned<T>> for Atomic<T> {
/// use crossbeam_epoch::{Atomic, Owned};
///
/// let a = Atomic::<i32>::from(Owned::new(1234));
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
fn from(owned: Owned<T>) -> Self {
let data = owned.data;
@@ -1108,6 +1169,7 @@ impl<T: ?Sized + Pointable> Owned<T> {
/// let o = Owned::new(1234);
/// let guard = &epoch::pin();
/// let p = o.into_shared(guard);
+ /// # unsafe { drop(p.into_owned()); } // avoid leak
/// ```
#[allow(clippy::needless_lifetimes)]
pub fn into_shared<'g>(self, _: &'g Guard) -> Shared<'g, T> {
@@ -1291,6 +1353,7 @@ impl<'g, T> Shared<'g, T> {
/// let guard = &epoch::pin();
/// let p = a.load(SeqCst, guard);
/// assert_eq!(p.as_raw(), raw);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn as_raw(&self) -> *const T {
let (raw, _) = decompose_tag::<T>(self.data);
@@ -1329,6 +1392,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
/// assert!(a.load(SeqCst, guard).is_null());
/// a.store(Owned::new(1234), SeqCst);
/// assert!(!a.load(SeqCst, guard).is_null());
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn is_null(&self) -> bool {
let (raw, _) = decompose_tag::<T>(self.data);
@@ -1365,6 +1429,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
/// unsafe {
/// assert_eq!(p.deref(), &1234);
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub unsafe fn deref(&self) -> &'g T {
let (raw, _) = decompose_tag::<T>(self.data);
@@ -1406,6 +1471,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
/// unsafe {
/// assert_eq!(p.deref(), &vec![1, 2, 3, 4, 5]);
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub unsafe fn deref_mut(&mut self) -> &'g mut T {
let (raw, _) = decompose_tag::<T>(self.data);
@@ -1442,6 +1508,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
/// unsafe {
/// assert_eq!(p.as_ref(), Some(&1234));
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub unsafe fn as_ref(&self) -> Option<&'g T> {
let (raw, _) = decompose_tag::<T>(self.data);
@@ -1481,6 +1548,36 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
Owned::from_usize(self.data)
}
+ /// Takes ownership of the pointee if it is not null.
+ ///
+ /// # Safety
+ ///
+ /// This method may be called only if the pointer is valid and nobody else is holding a
+ /// reference to the same object, or if the pointer is null.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use crossbeam_epoch::{self as epoch, Atomic};
+ /// use std::sync::atomic::Ordering::SeqCst;
+ ///
+ /// let a = Atomic::new(1234);
+ /// unsafe {
+ /// let guard = &epoch::unprotected();
+ /// let p = a.load(SeqCst, guard);
+ /// if let Some(x) = p.try_into_owned() {
+ /// drop(x);
+ /// }
+ /// }
+ /// ```
+ pub unsafe fn try_into_owned(self) -> Option<Owned<T>> {
+ if self.is_null() {
+ None
+ } else {
+ Some(Owned::from_usize(self.data))
+ }
+ }
+
/// Returns the tag stored within the pointer.
///
/// # Examples
@@ -1493,6 +1590,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
/// let guard = &epoch::pin();
/// let p = a.load(SeqCst, guard);
/// assert_eq!(p.tag(), 2);
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn tag(&self) -> usize {
let (_, tag) = decompose_tag::<T>(self.data);
@@ -1516,6 +1614,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
/// assert_eq!(p1.tag(), 0);
/// assert_eq!(p2.tag(), 2);
/// assert_eq!(p1.as_raw(), p2.as_raw());
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn with_tag(&self, tag: usize) -> Shared<'g, T> {
unsafe { Self::from_usize(compose_tag::<T>(self.data, tag)) }
@@ -1536,6 +1635,7 @@ impl<T> From<*const T> for Shared<'_, T> {
///
/// let p = Shared::from(Box::into_raw(Box::new(1234)) as *const _);
/// assert!(!p.is_null());
+ /// # unsafe { drop(p.into_owned()); } // avoid leak
/// ```
fn from(raw: *const T) -> Self {
let raw = raw as usize;
@@ -1612,7 +1712,7 @@ mod tests {
#[test]
fn array_init() {
let owned = Owned::<[MaybeUninit<usize>]>::init(10);
- let arr: &[MaybeUninit<usize>] = &*owned;
+ let arr: &[MaybeUninit<usize>] = &owned;
assert_eq!(arr.len(), 10);
}
}
diff --git a/vendor/crossbeam-epoch/src/collector.rs b/vendor/crossbeam-epoch/src/collector.rs
index 099a2ffc6..5b0851184 100644
--- a/vendor/crossbeam-epoch/src/collector.rs
+++ b/vendor/crossbeam-epoch/src/collector.rs
@@ -111,7 +111,7 @@ impl fmt::Debug for LocalHandle {
#[cfg(all(test, not(crossbeam_loom)))]
mod tests {
- use std::mem;
+ use std::mem::ManuallyDrop;
use std::sync::atomic::{AtomicUsize, Ordering};
use crossbeam_utils::thread;
@@ -402,15 +402,13 @@ mod tests {
v.push(i as i32);
}
- let ptr = v.as_mut_ptr() as usize;
let len = v.len();
+ let ptr = ManuallyDrop::new(v).as_mut_ptr() as usize;
guard.defer_unchecked(move || {
drop(Vec::from_raw_parts(ptr as *const i32 as *mut i32, len, len));
DESTROYS.fetch_add(len, Ordering::Relaxed);
});
guard.flush();
-
- mem::forget(v);
}
while DESTROYS.load(Ordering::Relaxed) < COUNT {
diff --git a/vendor/crossbeam-epoch/src/deferred.rs b/vendor/crossbeam-epoch/src/deferred.rs
index c33d51502..2f3d79fdf 100644
--- a/vendor/crossbeam-epoch/src/deferred.rs
+++ b/vendor/crossbeam-epoch/src/deferred.rs
@@ -29,6 +29,15 @@ impl fmt::Debug for Deferred {
}
impl Deferred {
+ pub(crate) const NO_OP: Self = {
+ fn no_op_call(_raw: *mut u8) {}
+ Self {
+ call: no_op_call,
+ data: MaybeUninit::uninit(),
+ _marker: PhantomData,
+ }
+ };
+
/// Constructs a new `Deferred` from a `FnOnce()`.
pub(crate) fn new<F: FnOnce()>(f: F) -> Self {
let size = mem::size_of::<F>();
@@ -37,10 +46,10 @@ impl Deferred {
unsafe {
if size <= mem::size_of::<Data>() && align <= mem::align_of::<Data>() {
let mut data = MaybeUninit::<Data>::uninit();
- ptr::write(data.as_mut_ptr() as *mut F, f);
+ ptr::write(data.as_mut_ptr().cast::<F>(), f);
unsafe fn call<F: FnOnce()>(raw: *mut u8) {
- let f: F = ptr::read(raw as *mut F);
+ let f: F = ptr::read(raw.cast::<F>());
f();
}
@@ -52,12 +61,12 @@ impl Deferred {
} else {
let b: Box<F> = Box::new(f);
let mut data = MaybeUninit::<Data>::uninit();
- ptr::write(data.as_mut_ptr() as *mut Box<F>, b);
+ ptr::write(data.as_mut_ptr().cast::<Box<F>>(), b);
unsafe fn call<F: FnOnce()>(raw: *mut u8) {
// It's safe to cast `raw` from `*mut u8` to `*mut Box<F>`, because `raw` is
// originally derived from `*mut Box<F>`.
- let b: Box<F> = ptr::read(raw as *mut Box<F>);
+ let b: Box<F> = ptr::read(raw.cast::<Box<F>>());
(*b)();
}
@@ -74,7 +83,7 @@ impl Deferred {
#[inline]
pub(crate) fn call(mut self) {
let call = self.call;
- unsafe { call(self.data.as_mut_ptr() as *mut u8) };
+ unsafe { call(self.data.as_mut_ptr().cast::<u8>()) };
}
}
diff --git a/vendor/crossbeam-epoch/src/guard.rs b/vendor/crossbeam-epoch/src/guard.rs
index 6db3750b0..ba7fe1b11 100644
--- a/vendor/crossbeam-epoch/src/guard.rs
+++ b/vendor/crossbeam-epoch/src/guard.rs
@@ -46,6 +46,7 @@ use crate::internal::Local;
/// if let Some(num) = unsafe { p.as_ref() } {
/// println!("The number is {}.", num);
/// }
+/// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
///
/// # Multiple guards
@@ -184,6 +185,7 @@ impl Guard {
/// });
/// }
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub unsafe fn defer_unchecked<F, R>(&self, f: F)
where
@@ -263,6 +265,7 @@ impl Guard {
/// guard.defer_destroy(p);
/// }
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub unsafe fn defer_destroy<T>(&self, ptr: Shared<'_, T>) {
self.defer_unchecked(move || ptr.into_owned());
@@ -320,6 +323,7 @@ impl Guard {
/// let p = a.load(SeqCst, &guard);
/// assert_eq!(unsafe { p.as_ref() }, Some(&777));
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn repin(&mut self) {
if let Some(local) = unsafe { self.local.as_ref() } {
@@ -356,6 +360,7 @@ impl Guard {
/// let p = a.load(SeqCst, &guard);
/// assert_eq!(unsafe { p.as_ref() }, Some(&777));
/// }
+ /// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
pub fn repin_after<F, R>(&mut self, f: F) -> R
where
@@ -451,6 +456,7 @@ impl fmt::Debug for Guard {
///
/// // Dropping `dummy` doesn't affect the current thread - it's just a noop.
/// }
+/// # unsafe { drop(a.into_owned()); } // avoid leak
/// ```
///
/// The most common use of this function is when constructing or destructing a data structure.
diff --git a/vendor/crossbeam-epoch/src/internal.rs b/vendor/crossbeam-epoch/src/internal.rs
index de208b13e..00c66a40a 100644
--- a/vendor/crossbeam-epoch/src/internal.rs
+++ b/vendor/crossbeam-epoch/src/internal.rs
@@ -55,9 +55,10 @@ use crate::sync::list::{Entry, IsElement, IterError, List};
use crate::sync::queue::Queue;
/// Maximum number of objects a bag can contain.
-#[cfg(not(crossbeam_sanitize))]
-const MAX_OBJECTS: usize = 62;
-#[cfg(crossbeam_sanitize)]
+#[cfg(not(any(crossbeam_sanitize, miri)))]
+const MAX_OBJECTS: usize = 64;
+// Makes it more likely to trigger any potential data races.
+#[cfg(any(crossbeam_sanitize, miri))]
const MAX_OBJECTS: usize = 4;
/// A bag of deferred functions.
@@ -106,87 +107,11 @@ impl Bag {
}
impl Default for Bag {
- #[rustfmt::skip]
fn default() -> Self {
- // TODO: [no_op; MAX_OBJECTS] syntax blocked by https://github.com/rust-lang/rust/issues/49147
- #[cfg(not(crossbeam_sanitize))]
- return Bag {
+ Bag {
len: 0,
- deferreds: [
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- ],
- };
- #[cfg(crossbeam_sanitize)]
- return Bag {
- len: 0,
- deferreds: [
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- Deferred::new(no_op_func),
- ],
- };
+ deferreds: [Deferred::NO_OP; MAX_OBJECTS],
+ }
}
}
@@ -194,7 +119,7 @@ impl Drop for Bag {
fn drop(&mut self) {
// Call all deferred functions.
for deferred in &mut self.deferreds[..self.len] {
- let no_op = Deferred::new(no_op_func);
+ let no_op = Deferred::NO_OP;
let owned_deferred = mem::replace(deferred, no_op);
owned_deferred.call();
}
@@ -210,8 +135,6 @@ impl fmt::Debug for Bag {
}
}
-fn no_op_func() {}
-
/// A pair of an epoch and a bag.
#[derive(Default, Debug)]
struct SealedBag {
@@ -375,13 +298,14 @@ pub(crate) struct Local {
// Make sure `Local` is less than or equal to 2048 bytes.
// https://github.com/crossbeam-rs/crossbeam/issues/551
-#[cfg(not(crossbeam_sanitize))] // `crossbeam_sanitize` reduces the size of `Local`
+#[cfg(not(any(crossbeam_sanitize, miri)))] // `crossbeam_sanitize` and `miri` reduce the size of `Local`
#[test]
fn local_size() {
- assert!(
- core::mem::size_of::<Local>() <= 2048,
- "An allocation of `Local` should be <= 2048 bytes."
- );
+ // TODO: https://github.com/crossbeam-rs/crossbeam/issues/869
+ // assert!(
+ // core::mem::size_of::<Local>() <= 2048,
+ // "An allocation of `Local` should be <= 2048 bytes."
+ // );
}
impl Local {
@@ -468,7 +392,10 @@ impl Local {
// Now we must store `new_epoch` into `self.epoch` and execute a `SeqCst` fence.
// The fence makes sure that any future loads from `Atomic`s will not happen before
// this store.
- if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
+ if cfg!(all(
+ any(target_arch = "x86", target_arch = "x86_64"),
+ not(miri)
+ )) {
// HACK(stjepang): On x86 architectures there are two different ways of executing
// a `SeqCst` fence.
//
diff --git a/vendor/crossbeam-queue/.cargo-checksum.json b/vendor/crossbeam-queue/.cargo-checksum.json
deleted file mode 100644
index 8dcd3f367..000000000
--- a/vendor/crossbeam-queue/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"5f8fe6dc4bfa5616834c0f60a6b0280a9dc96d282d4a14e1a77b1bd60453887f","Cargo.toml":"336728ea0b0befab0c66ff758c47ef8c1f49b4912d2f450ae8ab24611cf78790","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"2d4f1cc484ab54dfb9597bf121b3e8ef5416bb56ae52541976016a4776129447","build.rs":"ee1eaeee830c08c770bb84b40e6400af52c8db464945df0b82c8a4a4b4c681ec","no_atomic.rs":"71b5f78fd701ce604aa766dd3d825fa5bed774282aae4d6c31d7acb01b1b242f","src/array_queue.rs":"ea383caa1b70cbe09716caed20016b851118e24fa8508b2ce2498402ae5369f8","src/lib.rs":"effccc001c5168217291e435ae79f4889495cb943a6720d1e73e65b64831e4ed","src/seg_queue.rs":"be0ceb6d67a084eb511582e38c24c7d90bc89c2111778216cf05e11622d7fc4c","tests/array_queue.rs":"3ea9d2ca8c1e1f4d82f2ccd94872696baa4ffc80aca939ea2c5af737be53f817","tests/seg_queue.rs":"3b44ccad949578d2f4e5dee2687cfe6ef1fd52930ae19ed66c12bafa62cf32c2"},"package":"1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"} \ No newline at end of file
diff --git a/vendor/crossbeam-queue/CHANGELOG.md b/vendor/crossbeam-queue/CHANGELOG.md
deleted file mode 100644
index 1d8b04ff6..000000000
--- a/vendor/crossbeam-queue/CHANGELOG.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Version 0.3.5
-
-- Add `ArrayQueue::force_push`. (#789)
-
-# Version 0.3.4
-
-- Implement `IntoIterator` for `ArrayQueue` and `SegQueue`. (#772)
-
-# Version 0.3.3
-
-- Fix stacked borrows violation in `ArrayQueue` when `-Zmiri-tag-raw-pointers` is enabled. (#763)
-
-# Version 0.3.2
-
-- Support targets that do not have atomic CAS on stable Rust. (#698)
-
-# Version 0.3.1
-
-- Make `SegQueue::new` const fn. (#584)
-- Change license to "MIT OR Apache-2.0".
-
-# Version 0.3.0
-
-- Bump the minimum supported Rust version to 1.36.
-- Remove `PushError` and `PopError`.
-
-# Version 0.2.3
-
-- Fix bug in release (yanking 0.2.2)
-
-# Version 0.2.2
-
-- Fix unsoundness issues by adopting `MaybeUninit`. (#458)
-
-# Version 0.2.1
-
-- Add `no_std` support.
-
-# Version 0.2.0
-
-- Bump the minimum required version to 1.28.
-- Bump `crossbeam-utils` to `0.7`.
-
-# Version 0.1.2
-
-- Update `crossbeam-utils` to `0.6.5`.
-
-# Version 0.1.1
-
-- Update `crossbeam-utils` to `0.6.4`.
-
-# Version 0.1.0
-
-- Initial version with `ArrayQueue` and `SegQueue`.
diff --git a/vendor/crossbeam-queue/Cargo.toml b/vendor/crossbeam-queue/Cargo.toml
deleted file mode 100644
index c8093dc19..000000000
--- a/vendor/crossbeam-queue/Cargo.toml
+++ /dev/null
@@ -1,51 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2018"
-rust-version = "1.36"
-name = "crossbeam-queue"
-version = "0.3.5"
-description = "Concurrent queues"
-homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue"
-keywords = [
- "queue",
- "mpmc",
- "lock-free",
- "producer",
- "consumer",
-]
-categories = [
- "concurrency",
- "data-structures",
- "no-std",
-]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/crossbeam-rs/crossbeam"
-
-[dependencies.cfg-if]
-version = "1"
-
-[dependencies.crossbeam-utils]
-version = "0.8.5"
-default-features = false
-
-[dev-dependencies.rand]
-version = "0.8"
-
-[features]
-alloc = []
-default = ["std"]
-nightly = ["crossbeam-utils/nightly"]
-std = [
- "alloc",
- "crossbeam-utils/std",
-]
diff --git a/vendor/crossbeam-queue/README.md b/vendor/crossbeam-queue/README.md
deleted file mode 100644
index 2f30b3937..000000000
--- a/vendor/crossbeam-queue/README.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Crossbeam Queue
-
-[![Build Status](https://github.com/crossbeam-rs/crossbeam/workflows/CI/badge.svg)](
-https://github.com/crossbeam-rs/crossbeam/actions)
-[![License](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue.svg)](
-https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue#license)
-[![Cargo](https://img.shields.io/crates/v/crossbeam-queue.svg)](
-https://crates.io/crates/crossbeam-queue)
-[![Documentation](https://docs.rs/crossbeam-queue/badge.svg)](
-https://docs.rs/crossbeam-queue)
-[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
-https://www.rust-lang.org)
-[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
-
-This crate provides concurrent queues that can be shared among threads:
-
-* [`ArrayQueue`], a bounded MPMC queue that allocates a fixed-capacity buffer on construction.
-* [`SegQueue`], an unbounded MPMC queue that allocates small buffers, segments, on demand.
-
-Everything in this crate can be used in `no_std` environments, provided that `alloc` feature is
-enabled.
-
-[`ArrayQueue`]: https://docs.rs/crossbeam-queue/*/crossbeam_queue/struct.ArrayQueue.html
-[`SegQueue`]: https://docs.rs/crossbeam-queue/*/crossbeam_queue/struct.SegQueue.html
-
-## Usage
-
-Add this to your `Cargo.toml`:
-
-```toml
-[dependencies]
-crossbeam-queue = "0.3"
-```
-
-## Compatibility
-
-Crossbeam Queue supports stable Rust releases going back at least six months,
-and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.36.
-
-## License
-
-Licensed under either of
-
- * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
-
-at your option.
-
-#### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
-dual licensed as above, without any additional terms or conditions.
diff --git a/vendor/crossbeam-queue/build.rs b/vendor/crossbeam-queue/build.rs
deleted file mode 100644
index 587e0580b..000000000
--- a/vendor/crossbeam-queue/build.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// The rustc-cfg listed below are considered public API, but it is *unstable*
-// and outside of the normal semver guarantees:
-//
-// - `crossbeam_no_atomic_cas`
-// Assume the target does *not* support atomic CAS operations.
-// This is usually detected automatically by the build script, but you may
-// need to enable it manually when building for custom targets or using
-// non-cargo build systems that don't run the build script.
-//
-// With the exceptions mentioned above, the rustc-cfg emitted by the build
-// script are *not* public API.
-
-#![warn(rust_2018_idioms)]
-
-use std::env;
-
-include!("no_atomic.rs");
-
-fn main() {
- let target = match env::var("TARGET") {
- Ok(target) => target,
- Err(e) => {
- println!(
- "cargo:warning={}: unable to get TARGET environment variable: {}",
- env!("CARGO_PKG_NAME"),
- e
- );
- return;
- }
- };
-
- // Note that this is `no_*`, not `has_*`. This allows treating
- // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
- // run. This is needed for compatibility with non-cargo build systems that
- // don't run the build script.
- if NO_ATOMIC_CAS.contains(&&*target) {
- println!("cargo:rustc-cfg=crossbeam_no_atomic_cas");
- }
-
- println!("cargo:rerun-if-changed=no_atomic.rs");
-}
diff --git a/vendor/crossbeam-queue/no_atomic.rs b/vendor/crossbeam-queue/no_atomic.rs
deleted file mode 100644
index 390019ebd..000000000
--- a/vendor/crossbeam-queue/no_atomic.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-// This file is @generated by no_atomic.sh.
-// It is not intended for manual editing.
-
-const NO_ATOMIC_CAS: &[&str] = &[
- "avr-unknown-gnu-atmega328",
- "bpfeb-unknown-none",
- "bpfel-unknown-none",
- "msp430-none-elf",
- "riscv32i-unknown-none-elf",
- "riscv32im-unknown-none-elf",
- "riscv32imc-unknown-none-elf",
- "thumbv4t-none-eabi",
- "thumbv6m-none-eabi",
-];
-
-#[allow(dead_code)] // Only crossbeam-utils uses this.
-const NO_ATOMIC_64: &[&str] = &[
- "arm-linux-androideabi",
- "armebv7r-none-eabi",
- "armebv7r-none-eabihf",
- "armv4t-unknown-linux-gnueabi",
- "armv5te-unknown-linux-gnueabi",
- "armv5te-unknown-linux-musleabi",
- "armv5te-unknown-linux-uclibceabi",
- "armv6k-nintendo-3ds",
- "armv7r-none-eabi",
- "armv7r-none-eabihf",
- "avr-unknown-gnu-atmega328",
- "hexagon-unknown-linux-musl",
- "m68k-unknown-linux-gnu",
- "mips-unknown-linux-gnu",
- "mips-unknown-linux-musl",
- "mips-unknown-linux-uclibc",
- "mipsel-sony-psp",
- "mipsel-unknown-linux-gnu",
- "mipsel-unknown-linux-musl",
- "mipsel-unknown-linux-uclibc",
- "mipsel-unknown-none",
- "mipsisa32r6-unknown-linux-gnu",
- "mipsisa32r6el-unknown-linux-gnu",
- "msp430-none-elf",
- "powerpc-unknown-freebsd",
- "powerpc-unknown-linux-gnu",
- "powerpc-unknown-linux-gnuspe",
- "powerpc-unknown-linux-musl",
- "powerpc-unknown-netbsd",
- "powerpc-unknown-openbsd",
- "powerpc-wrs-vxworks",
- "powerpc-wrs-vxworks-spe",
- "riscv32gc-unknown-linux-gnu",
- "riscv32gc-unknown-linux-musl",
- "riscv32i-unknown-none-elf",
- "riscv32im-unknown-none-elf",
- "riscv32imac-unknown-none-elf",
- "riscv32imc-unknown-none-elf",
- "thumbv4t-none-eabi",
- "thumbv6m-none-eabi",
- "thumbv7em-none-eabi",
- "thumbv7em-none-eabihf",
- "thumbv7m-none-eabi",
- "thumbv8m.base-none-eabi",
- "thumbv8m.main-none-eabi",
- "thumbv8m.main-none-eabihf",
-];
-
-#[allow(dead_code)] // Only crossbeam-utils uses this.
-const NO_ATOMIC: &[&str] = &[
- "avr-unknown-gnu-atmega328",
- "msp430-none-elf",
- "riscv32i-unknown-none-elf",
- "riscv32im-unknown-none-elf",
- "riscv32imc-unknown-none-elf",
-];
diff --git a/vendor/crossbeam-queue/src/array_queue.rs b/vendor/crossbeam-queue/src/array_queue.rs
deleted file mode 100644
index c34f589e7..000000000
--- a/vendor/crossbeam-queue/src/array_queue.rs
+++ /dev/null
@@ -1,522 +0,0 @@
-//! The implementation is based on Dmitry Vyukov's bounded MPMC queue.
-//!
-//! Source:
-//! - <http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue>
-
-use alloc::boxed::Box;
-use core::cell::UnsafeCell;
-use core::fmt;
-use core::mem::MaybeUninit;
-use core::sync::atomic::{self, AtomicUsize, Ordering};
-
-use crossbeam_utils::{Backoff, CachePadded};
-
-/// A slot in a queue.
-struct Slot<T> {
- /// The current stamp.
- ///
- /// If the stamp equals the tail, this node will be next written to. If it equals head + 1,
- /// this node will be next read from.
- stamp: AtomicUsize,
-
- /// The value in this slot.
- value: UnsafeCell<MaybeUninit<T>>,
-}
-
-/// A bounded multi-producer multi-consumer queue.
-///
-/// This queue allocates a fixed-capacity buffer on construction, which is used to store pushed
-/// elements. The queue cannot hold more elements than the buffer allows. Attempting to push an
-/// element into a full queue will fail. Alternatively, [`force_push`] makes it possible for
-/// this queue to be used as a ring-buffer. Having a buffer allocated upfront makes this queue
-/// a bit faster than [`SegQueue`].
-///
-/// [`force_push`]: ArrayQueue::force_push
-/// [`SegQueue`]: super::SegQueue
-///
-/// # Examples
-///
-/// ```
-/// use crossbeam_queue::ArrayQueue;
-///
-/// let q = ArrayQueue::new(2);
-///
-/// assert_eq!(q.push('a'), Ok(()));
-/// assert_eq!(q.push('b'), Ok(()));
-/// assert_eq!(q.push('c'), Err('c'));
-/// assert_eq!(q.pop(), Some('a'));
-/// ```
-pub struct ArrayQueue<T> {
- /// The head of the queue.
- ///
- /// This value is a "stamp" consisting of an index into the buffer and a lap, but packed into a
- /// single `usize`. The lower bits represent the index, while the upper bits represent the lap.
- ///
- /// Elements are popped from the head of the queue.
- head: CachePadded<AtomicUsize>,
-
- /// The tail of the queue.
- ///
- /// This value is a "stamp" consisting of an index into the buffer and a lap, but packed into a
- /// single `usize`. The lower bits represent the index, while the upper bits represent the lap.
- ///
- /// Elements are pushed into the tail of the queue.
- tail: CachePadded<AtomicUsize>,
-
- /// The buffer holding slots.
- buffer: Box<[Slot<T>]>,
-
- /// The queue capacity.
- cap: usize,
-
- /// A stamp with the value of `{ lap: 1, index: 0 }`.
- one_lap: usize,
-}
-
-unsafe impl<T: Send> Sync for ArrayQueue<T> {}
-unsafe impl<T: Send> Send for ArrayQueue<T> {}
-
-impl<T> ArrayQueue<T> {
- /// Creates a new bounded queue with the given capacity.
- ///
- /// # Panics
- ///
- /// Panics if the capacity is zero.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::<i32>::new(100);
- /// ```
- pub fn new(cap: usize) -> ArrayQueue<T> {
- assert!(cap > 0, "capacity must be non-zero");
-
- // Head is initialized to `{ lap: 0, index: 0 }`.
- // Tail is initialized to `{ lap: 0, index: 0 }`.
- let head = 0;
- let tail = 0;
-
- // Allocate a buffer of `cap` slots initialized
- // with stamps.
- let buffer: Box<[Slot<T>]> = (0..cap)
- .map(|i| {
- // Set the stamp to `{ lap: 0, index: i }`.
- Slot {
- stamp: AtomicUsize::new(i),
- value: UnsafeCell::new(MaybeUninit::uninit()),
- }
- })
- .collect();
-
- // One lap is the smallest power of two greater than `cap`.
- let one_lap = (cap + 1).next_power_of_two();
-
- ArrayQueue {
- buffer,
- cap,
- one_lap,
- head: CachePadded::new(AtomicUsize::new(head)),
- tail: CachePadded::new(AtomicUsize::new(tail)),
- }
- }
-
- fn push_or_else<F>(&self, mut value: T, f: F) -> Result<(), T>
- where
- F: Fn(T, usize, usize, &Slot<T>) -> Result<T, T>,
- {
- let backoff = Backoff::new();
- let mut tail = self.tail.load(Ordering::Relaxed);
-
- loop {
- // Deconstruct the tail.
- let index = tail & (self.one_lap - 1);
- let lap = tail & !(self.one_lap - 1);
-
- let new_tail = if index + 1 < self.cap {
- // Same lap, incremented index.
- // Set to `{ lap: lap, index: index + 1 }`.
- tail + 1
- } else {
- // One lap forward, index wraps around to zero.
- // Set to `{ lap: lap.wrapping_add(1), index: 0 }`.
- lap.wrapping_add(self.one_lap)
- };
-
- // Inspect the corresponding slot.
- debug_assert!(index < self.buffer.len());
- let slot = unsafe { self.buffer.get_unchecked(index) };
- let stamp = slot.stamp.load(Ordering::Acquire);
-
- // If the tail and the stamp match, we may attempt to push.
- if tail == stamp {
- // Try moving the tail.
- match self.tail.compare_exchange_weak(
- tail,
- new_tail,
- Ordering::SeqCst,
- Ordering::Relaxed,
- ) {
- Ok(_) => {
- // Write the value into the slot and update the stamp.
- unsafe {
- slot.value.get().write(MaybeUninit::new(value));
- }
- slot.stamp.store(tail + 1, Ordering::Release);
- return Ok(());
- }
- Err(t) => {
- tail = t;
- backoff.spin();
- }
- }
- } else if stamp.wrapping_add(self.one_lap) == tail + 1 {
- atomic::fence(Ordering::SeqCst);
- value = f(value, tail, new_tail, slot)?;
- backoff.spin();
- tail = self.tail.load(Ordering::Relaxed);
- } else {
- // Snooze because we need to wait for the stamp to get updated.
- backoff.snooze();
- tail = self.tail.load(Ordering::Relaxed);
- }
- }
- }
-
- /// Attempts to push an element into the queue.
- ///
- /// If the queue is full, the element is returned back as an error.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::new(1);
- ///
- /// assert_eq!(q.push(10), Ok(()));
- /// assert_eq!(q.push(20), Err(20));
- /// ```
- pub fn push(&self, value: T) -> Result<(), T> {
- self.push_or_else(value, |v, tail, _, _| {
- let head = self.head.load(Ordering::Relaxed);
-
- // If the head lags one lap behind the tail as well...
- if head.wrapping_add(self.one_lap) == tail {
- // ...then the queue is full.
- Err(v)
- } else {
- Ok(v)
- }
- })
- }
-
- /// Pushes an element into the queue, replacing the oldest element if necessary.
- ///
- /// If the queue is full, the oldest element is replaced and returned,
- /// otherwise `None` is returned.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::new(2);
- ///
- /// assert_eq!(q.force_push(10), None);
- /// assert_eq!(q.force_push(20), None);
- /// assert_eq!(q.force_push(30), Some(10));
- /// assert_eq!(q.pop(), Some(20));
- /// ```
- pub fn force_push(&self, value: T) -> Option<T> {
- self.push_or_else(value, |v, tail, new_tail, slot| {
- let head = tail.wrapping_sub(self.one_lap);
- let new_head = new_tail.wrapping_sub(self.one_lap);
-
- // Try moving the head.
- if self
- .head
- .compare_exchange_weak(head, new_head, Ordering::SeqCst, Ordering::Relaxed)
- .is_ok()
- {
- // Move the tail.
- self.tail.store(new_tail, Ordering::SeqCst);
-
- // Swap the previous value.
- let old = unsafe { slot.value.get().replace(MaybeUninit::new(v)).assume_init() };
-
- // Update the stamp.
- slot.stamp.store(tail + 1, Ordering::Release);
-
- Err(old)
- } else {
- Ok(v)
- }
- })
- .err()
- }
-
- /// Attempts to pop an element from the queue.
- ///
- /// If the queue is empty, `None` is returned.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::new(1);
- /// assert_eq!(q.push(10), Ok(()));
- ///
- /// assert_eq!(q.pop(), Some(10));
- /// assert!(q.pop().is_none());
- /// ```
- pub fn pop(&self) -> Option<T> {
- let backoff = Backoff::new();
- let mut head = self.head.load(Ordering::Relaxed);
-
- loop {
- // Deconstruct the head.
- let index = head & (self.one_lap - 1);
- let lap = head & !(self.one_lap - 1);
-
- // Inspect the corresponding slot.
- debug_assert!(index < self.buffer.len());
- let slot = unsafe { self.buffer.get_unchecked(index) };
- let stamp = slot.stamp.load(Ordering::Acquire);
-
- // If the the stamp is ahead of the head by 1, we may attempt to pop.
- if head + 1 == stamp {
- let new = if index + 1 < self.cap {
- // Same lap, incremented index.
- // Set to `{ lap: lap, index: index + 1 }`.
- head + 1
- } else {
- // One lap forward, index wraps around to zero.
- // Set to `{ lap: lap.wrapping_add(1), index: 0 }`.
- lap.wrapping_add(self.one_lap)
- };
-
- // Try moving the head.
- match self.head.compare_exchange_weak(
- head,
- new,
- Ordering::SeqCst,
- Ordering::Relaxed,
- ) {
- Ok(_) => {
- // Read the value from the slot and update the stamp.
- let msg = unsafe { slot.value.get().read().assume_init() };
- slot.stamp
- .store(head.wrapping_add(self.one_lap), Ordering::Release);
- return Some(msg);
- }
- Err(h) => {
- head = h;
- backoff.spin();
- }
- }
- } else if stamp == head {
- atomic::fence(Ordering::SeqCst);
- let tail = self.tail.load(Ordering::Relaxed);
-
- // If the tail equals the head, that means the channel is empty.
- if tail == head {
- return None;
- }
-
- backoff.spin();
- head = self.head.load(Ordering::Relaxed);
- } else {
- // Snooze because we need to wait for the stamp to get updated.
- backoff.snooze();
- head = self.head.load(Ordering::Relaxed);
- }
- }
- }
-
- /// Returns the capacity of the queue.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::<i32>::new(100);
- ///
- /// assert_eq!(q.capacity(), 100);
- /// ```
- pub fn capacity(&self) -> usize {
- self.cap
- }
-
- /// Returns `true` if the queue is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::new(100);
- ///
- /// assert!(q.is_empty());
- /// q.push(1).unwrap();
- /// assert!(!q.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool {
- let head = self.head.load(Ordering::SeqCst);
- let tail = self.tail.load(Ordering::SeqCst);
-
- // Is the tail lagging one lap behind head?
- // Is the tail equal to the head?
- //
- // Note: If the head changes just before we load the tail, that means there was a moment
- // when the channel was not empty, so it is safe to just return `false`.
- tail == head
- }
-
- /// Returns `true` if the queue is full.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::new(1);
- ///
- /// assert!(!q.is_full());
- /// q.push(1).unwrap();
- /// assert!(q.is_full());
- /// ```
- pub fn is_full(&self) -> bool {
- let tail = self.tail.load(Ordering::SeqCst);
- let head = self.head.load(Ordering::SeqCst);
-
- // Is the head lagging one lap behind tail?
- //
- // Note: If the tail changes just before we load the head, that means there was a moment
- // when the queue was not full, so it is safe to just return `false`.
- head.wrapping_add(self.one_lap) == tail
- }
-
- /// Returns the number of elements in the queue.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::ArrayQueue;
- ///
- /// let q = ArrayQueue::new(100);
- /// assert_eq!(q.len(), 0);
- ///
- /// q.push(10).unwrap();
- /// assert_eq!(q.len(), 1);
- ///
- /// q.push(20).unwrap();
- /// assert_eq!(q.len(), 2);
- /// ```
- pub fn len(&self) -> usize {
- loop {
- // Load the tail, then load the head.
- let tail = self.tail.load(Ordering::SeqCst);
- let head = self.head.load(Ordering::SeqCst);
-
- // If the tail didn't change, we've got consistent values to work with.
- if self.tail.load(Ordering::SeqCst) == tail {
- let hix = head & (self.one_lap - 1);
- let tix = tail & (self.one_lap - 1);
-
- return if hix < tix {
- tix - hix
- } else if hix > tix {
- self.cap - hix + tix
- } else if tail == head {
- 0
- } else {
- self.cap
- };
- }
- }
- }
-}
-
-impl<T> Drop for ArrayQueue<T> {
- fn drop(&mut self) {
- // Get the index of the head.
- let hix = self.head.load(Ordering::Relaxed) & (self.one_lap - 1);
-
- // Loop over all slots that hold a message and drop them.
- for i in 0..self.len() {
- // Compute the index of the next slot holding a message.
- let index = if hix + i < self.cap {
- hix + i
- } else {
- hix + i - self.cap
- };
-
- unsafe {
- debug_assert!(index < self.buffer.len());
- let slot = self.buffer.get_unchecked_mut(index);
- let value = &mut *slot.value.get();
- value.as_mut_ptr().drop_in_place();
- }
- }
- }
-}
-
-impl<T> fmt::Debug for ArrayQueue<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.pad("ArrayQueue { .. }")
- }
-}
-
-impl<T> IntoIterator for ArrayQueue<T> {
- type Item = T;
-
- type IntoIter = IntoIter<T>;
-
- fn into_iter(self) -> Self::IntoIter {
- IntoIter { value: self }
- }
-}
-
-#[derive(Debug)]
-pub struct IntoIter<T> {
- value: ArrayQueue<T>,
-}
-
-impl<T> Iterator for IntoIter<T> {
- type Item = T;
-
- fn next(&mut self) -> Option<Self::Item> {
- let value = &mut self.value;
- let head = *value.head.get_mut();
- if value.head.get_mut() != value.tail.get_mut() {
- let index = head & (value.one_lap - 1);
- let lap = head & !(value.one_lap - 1);
- // SAFETY: We have mutable access to this, so we can read without
- // worrying about concurrency. Furthermore, we know this is
- // initialized because it is the value pointed at by `value.head`
- // and this is a non-empty queue.
- let val = unsafe {
- debug_assert!(index < value.buffer.len());
- let slot = value.buffer.get_unchecked_mut(index);
- slot.value.get().read().assume_init()
- };
- let new = if index + 1 < value.cap {
- // Same lap, incremented index.
- // Set to `{ lap: lap, index: index + 1 }`.
- head + 1
- } else {
- // One lap forward, index wraps around to zero.
- // Set to `{ lap: lap.wrapping_add(1), index: 0 }`.
- lap.wrapping_add(value.one_lap)
- };
- *value.head.get_mut() = new;
- Option::Some(val)
- } else {
- Option::None
- }
- }
-}
diff --git a/vendor/crossbeam-queue/src/lib.rs b/vendor/crossbeam-queue/src/lib.rs
deleted file mode 100644
index 846d7c2e1..000000000
--- a/vendor/crossbeam-queue/src/lib.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-//! Concurrent queues.
-//!
-//! This crate provides concurrent queues that can be shared among threads:
-//!
-//! * [`ArrayQueue`], a bounded MPMC queue that allocates a fixed-capacity buffer on construction.
-//! * [`SegQueue`], an unbounded MPMC queue that allocates small buffers, segments, on demand.
-
-#![doc(test(
- no_crate_inject,
- attr(
- deny(warnings, rust_2018_idioms),
- allow(dead_code, unused_assignments, unused_variables)
- )
-))]
-#![warn(
- missing_docs,
- missing_debug_implementations,
- rust_2018_idioms,
- unreachable_pub
-)]
-#![cfg_attr(not(feature = "std"), no_std)]
-
-#[cfg(not(crossbeam_no_atomic_cas))]
-cfg_if::cfg_if! {
- if #[cfg(feature = "alloc")] {
- extern crate alloc;
-
- mod array_queue;
- mod seg_queue;
-
- pub use self::array_queue::ArrayQueue;
- pub use self::seg_queue::SegQueue;
- }
-}
diff --git a/vendor/crossbeam-queue/src/seg_queue.rs b/vendor/crossbeam-queue/src/seg_queue.rs
deleted file mode 100644
index 1767775d1..000000000
--- a/vendor/crossbeam-queue/src/seg_queue.rs
+++ /dev/null
@@ -1,545 +0,0 @@
-use alloc::boxed::Box;
-use core::cell::UnsafeCell;
-use core::fmt;
-use core::marker::PhantomData;
-use core::mem::MaybeUninit;
-use core::ptr;
-use core::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
-
-use crossbeam_utils::{Backoff, CachePadded};
-
-// Bits indicating the state of a slot:
-// * If a value has been written into the slot, `WRITE` is set.
-// * If a value has been read from the slot, `READ` is set.
-// * If the block is being destroyed, `DESTROY` is set.
-const WRITE: usize = 1;
-const READ: usize = 2;
-const DESTROY: usize = 4;
-
-// Each block covers one "lap" of indices.
-const LAP: usize = 32;
-// The maximum number of values a block can hold.
-const BLOCK_CAP: usize = LAP - 1;
-// How many lower bits are reserved for metadata.
-const SHIFT: usize = 1;
-// Indicates that the block is not the last one.
-const HAS_NEXT: usize = 1;
-
-/// A slot in a block.
-struct Slot<T> {
- /// The value.
- value: UnsafeCell<MaybeUninit<T>>,
-
- /// The state of the slot.
- state: AtomicUsize,
-}
-
-impl<T> Slot<T> {
- /// Waits until a value is written into the slot.
- fn wait_write(&self) {
- let backoff = Backoff::new();
- while self.state.load(Ordering::Acquire) & WRITE == 0 {
- backoff.snooze();
- }
- }
-}
-
-/// A block in a linked list.
-///
-/// Each block in the list can hold up to `BLOCK_CAP` values.
-struct Block<T> {
- /// The next block in the linked list.
- next: AtomicPtr<Block<T>>,
-
- /// Slots for values.
- slots: [Slot<T>; BLOCK_CAP],
-}
-
-impl<T> Block<T> {
- /// Creates an empty block that starts at `start_index`.
- fn new() -> Block<T> {
- // SAFETY: This is safe because:
- // [1] `Block::next` (AtomicPtr) may be safely zero initialized.
- // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
- // [3] `Slot::value` (UnsafeCell) may be safely zero initialized because it
- // holds a MaybeUninit.
- // [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
- unsafe { MaybeUninit::zeroed().assume_init() }
- }
-
- /// Waits until the next pointer is set.
- fn wait_next(&self) -> *mut Block<T> {
- let backoff = Backoff::new();
- loop {
- let next = self.next.load(Ordering::Acquire);
- if !next.is_null() {
- return next;
- }
- backoff.snooze();
- }
- }
-
- /// Sets the `DESTROY` bit in slots starting from `start` and destroys the block.
- unsafe fn destroy(this: *mut Block<T>, start: usize) {
- // It is not necessary to set the `DESTROY` bit in the last slot because that slot has
- // begun destruction of the block.
- for i in start..BLOCK_CAP - 1 {
- let slot = (*this).slots.get_unchecked(i);
-
- // Mark the `DESTROY` bit if a thread is still using the slot.
- if slot.state.load(Ordering::Acquire) & READ == 0
- && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0
- {
- // If a thread is still using the slot, it will continue destruction of the block.
- return;
- }
- }
-
- // No thread is using the block, now it is safe to destroy it.
- drop(Box::from_raw(this));
- }
-}
-
-/// A position in a queue.
-struct Position<T> {
- /// The index in the queue.
- index: AtomicUsize,
-
- /// The block in the linked list.
- block: AtomicPtr<Block<T>>,
-}
-
-/// An unbounded multi-producer multi-consumer queue.
-///
-/// This queue is implemented as a linked list of segments, where each segment is a small buffer
-/// that can hold a handful of elements. There is no limit to how many elements can be in the queue
-/// at a time. However, since segments need to be dynamically allocated as elements get pushed,
-/// this queue is somewhat slower than [`ArrayQueue`].
-///
-/// [`ArrayQueue`]: super::ArrayQueue
-///
-/// # Examples
-///
-/// ```
-/// use crossbeam_queue::SegQueue;
-///
-/// let q = SegQueue::new();
-///
-/// q.push('a');
-/// q.push('b');
-///
-/// assert_eq!(q.pop(), Some('a'));
-/// assert_eq!(q.pop(), Some('b'));
-/// assert!(q.pop().is_none());
-/// ```
-pub struct SegQueue<T> {
- /// The head of the queue.
- head: CachePadded<Position<T>>,
-
- /// The tail of the queue.
- tail: CachePadded<Position<T>>,
-
- /// Indicates that dropping a `SegQueue<T>` may drop values of type `T`.
- _marker: PhantomData<T>,
-}
-
-unsafe impl<T: Send> Send for SegQueue<T> {}
-unsafe impl<T: Send> Sync for SegQueue<T> {}
-
-impl<T> SegQueue<T> {
- /// Creates a new unbounded queue.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::SegQueue;
- ///
- /// let q = SegQueue::<i32>::new();
- /// ```
- pub const fn new() -> SegQueue<T> {
- SegQueue {
- head: CachePadded::new(Position {
- block: AtomicPtr::new(ptr::null_mut()),
- index: AtomicUsize::new(0),
- }),
- tail: CachePadded::new(Position {
- block: AtomicPtr::new(ptr::null_mut()),
- index: AtomicUsize::new(0),
- }),
- _marker: PhantomData,
- }
- }
-
- /// Pushes an element into the queue.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::SegQueue;
- ///
- /// let q = SegQueue::new();
- ///
- /// q.push(10);
- /// q.push(20);
- /// ```
- pub fn push(&self, value: T) {
- let backoff = Backoff::new();
- let mut tail = self.tail.index.load(Ordering::Acquire);
- let mut block = self.tail.block.load(Ordering::Acquire);
- let mut next_block = None;
-
- loop {
- // Calculate the offset of the index into the block.
- let offset = (tail >> SHIFT) % LAP;
-
- // If we reached the end of the block, wait until the next one is installed.
- if offset == BLOCK_CAP {
- backoff.snooze();
- tail = self.tail.index.load(Ordering::Acquire);
- block = self.tail.block.load(Ordering::Acquire);
- continue;
- }
-
- // If we're going to have to install the next block, allocate it in advance in order to
- // make the wait for other threads as short as possible.
- if offset + 1 == BLOCK_CAP && next_block.is_none() {
- next_block = Some(Box::new(Block::<T>::new()));
- }
-
- // If this is the first push operation, we need to allocate the first block.
- if block.is_null() {
- let new = Box::into_raw(Box::new(Block::<T>::new()));
-
- if self
- .tail
- .block
- .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed)
- .is_ok()
- {
- self.head.block.store(new, Ordering::Release);
- block = new;
- } else {
- next_block = unsafe { Some(Box::from_raw(new)) };
- tail = self.tail.index.load(Ordering::Acquire);
- block = self.tail.block.load(Ordering::Acquire);
- continue;
- }
- }
-
- let new_tail = tail + (1 << SHIFT);
-
- // Try advancing the tail forward.
- match self.tail.index.compare_exchange_weak(
- tail,
- new_tail,
- Ordering::SeqCst,
- Ordering::Acquire,
- ) {
- Ok(_) => unsafe {
- // If we've reached the end of the block, install the next one.
- if offset + 1 == BLOCK_CAP {
- let next_block = Box::into_raw(next_block.unwrap());
- let next_index = new_tail.wrapping_add(1 << SHIFT);
-
- self.tail.block.store(next_block, Ordering::Release);
- self.tail.index.store(next_index, Ordering::Release);
- (*block).next.store(next_block, Ordering::Release);
- }
-
- // Write the value into the slot.
- let slot = (*block).slots.get_unchecked(offset);
- slot.value.get().write(MaybeUninit::new(value));
- slot.state.fetch_or(WRITE, Ordering::Release);
-
- return;
- },
- Err(t) => {
- tail = t;
- block = self.tail.block.load(Ordering::Acquire);
- backoff.spin();
- }
- }
- }
- }
-
- /// Pops an element from the queue.
- ///
- /// If the queue is empty, `None` is returned.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::SegQueue;
- ///
- /// let q = SegQueue::new();
- ///
- /// q.push(10);
- /// assert_eq!(q.pop(), Some(10));
- /// assert!(q.pop().is_none());
- /// ```
- pub fn pop(&self) -> Option<T> {
- let backoff = Backoff::new();
- let mut head = self.head.index.load(Ordering::Acquire);
- let mut block = self.head.block.load(Ordering::Acquire);
-
- loop {
- // Calculate the offset of the index into the block.
- let offset = (head >> SHIFT) % LAP;
-
- // If we reached the end of the block, wait until the next one is installed.
- if offset == BLOCK_CAP {
- backoff.snooze();
- head = self.head.index.load(Ordering::Acquire);
- block = self.head.block.load(Ordering::Acquire);
- continue;
- }
-
- let mut new_head = head + (1 << SHIFT);
-
- if new_head & HAS_NEXT == 0 {
- atomic::fence(Ordering::SeqCst);
- let tail = self.tail.index.load(Ordering::Relaxed);
-
- // If the tail equals the head, that means the queue is empty.
- if head >> SHIFT == tail >> SHIFT {
- return None;
- }
-
- // If head and tail are not in the same block, set `HAS_NEXT` in head.
- if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP {
- new_head |= HAS_NEXT;
- }
- }
-
- // The block can be null here only if the first push operation is in progress. In that
- // case, just wait until it gets initialized.
- if block.is_null() {
- backoff.snooze();
- head = self.head.index.load(Ordering::Acquire);
- block = self.head.block.load(Ordering::Acquire);
- continue;
- }
-
- // Try moving the head index forward.
- match self.head.index.compare_exchange_weak(
- head,
- new_head,
- Ordering::SeqCst,
- Ordering::Acquire,
- ) {
- Ok(_) => unsafe {
- // If we've reached the end of the block, move to the next one.
- if offset + 1 == BLOCK_CAP {
- let next = (*block).wait_next();
- let mut next_index = (new_head & !HAS_NEXT).wrapping_add(1 << SHIFT);
- if !(*next).next.load(Ordering::Relaxed).is_null() {
- next_index |= HAS_NEXT;
- }
-
- self.head.block.store(next, Ordering::Release);
- self.head.index.store(next_index, Ordering::Release);
- }
-
- // Read the value.
- let slot = (*block).slots.get_unchecked(offset);
- slot.wait_write();
- let value = slot.value.get().read().assume_init();
-
- // Destroy the block if we've reached the end, or if another thread wanted to
- // destroy but couldn't because we were busy reading from the slot.
- if offset + 1 == BLOCK_CAP {
- Block::destroy(block, 0);
- } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 {
- Block::destroy(block, offset + 1);
- }
-
- return Some(value);
- },
- Err(h) => {
- head = h;
- block = self.head.block.load(Ordering::Acquire);
- backoff.spin();
- }
- }
- }
- }
-
- /// Returns `true` if the queue is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::SegQueue;
- ///
- /// let q = SegQueue::new();
- ///
- /// assert!(q.is_empty());
- /// q.push(1);
- /// assert!(!q.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool {
- let head = self.head.index.load(Ordering::SeqCst);
- let tail = self.tail.index.load(Ordering::SeqCst);
- head >> SHIFT == tail >> SHIFT
- }
-
- /// Returns the number of elements in the queue.
- ///
- /// # Examples
- ///
- /// ```
- /// use crossbeam_queue::SegQueue;
- ///
- /// let q = SegQueue::new();
- /// assert_eq!(q.len(), 0);
- ///
- /// q.push(10);
- /// assert_eq!(q.len(), 1);
- ///
- /// q.push(20);
- /// assert_eq!(q.len(), 2);
- /// ```
- pub fn len(&self) -> usize {
- loop {
- // Load the tail index, then load the head index.
- let mut tail = self.tail.index.load(Ordering::SeqCst);
- let mut head = self.head.index.load(Ordering::SeqCst);
-
- // If the tail index didn't change, we've got consistent indices to work with.
- if self.tail.index.load(Ordering::SeqCst) == tail {
- // Erase the lower bits.
- tail &= !((1 << SHIFT) - 1);
- head &= !((1 << SHIFT) - 1);
-
- // Fix up indices if they fall onto block ends.
- if (tail >> SHIFT) & (LAP - 1) == LAP - 1 {
- tail = tail.wrapping_add(1 << SHIFT);
- }
- if (head >> SHIFT) & (LAP - 1) == LAP - 1 {
- head = head.wrapping_add(1 << SHIFT);
- }
-
- // Rotate indices so that head falls into the first block.
- let lap = (head >> SHIFT) / LAP;
- tail = tail.wrapping_sub((lap * LAP) << SHIFT);
- head = head.wrapping_sub((lap * LAP) << SHIFT);
-
- // Remove the lower bits.
- tail >>= SHIFT;
- head >>= SHIFT;
-
- // Return the difference minus the number of blocks between tail and head.
- return tail - head - tail / LAP;
- }
- }
- }
-}
-
-impl<T> Drop for SegQueue<T> {
- fn drop(&mut self) {
- let mut head = self.head.index.load(Ordering::Relaxed);
- let mut tail = self.tail.index.load(Ordering::Relaxed);
- let mut block = self.head.block.load(Ordering::Relaxed);
-
- // Erase the lower bits.
- head &= !((1 << SHIFT) - 1);
- tail &= !((1 << SHIFT) - 1);
-
- unsafe {
- // Drop all values between `head` and `tail` and deallocate the heap-allocated blocks.
- while head != tail {
- let offset = (head >> SHIFT) % LAP;
-
- if offset < BLOCK_CAP {
- // Drop the value in the slot.
- let slot = (*block).slots.get_unchecked(offset);
- let p = &mut *slot.value.get();
- p.as_mut_ptr().drop_in_place();
- } else {
- // Deallocate the block and move to the next one.
- let next = (*block).next.load(Ordering::Relaxed);
- drop(Box::from_raw(block));
- block = next;
- }
-
- head = head.wrapping_add(1 << SHIFT);
- }
-
- // Deallocate the last remaining block.
- if !block.is_null() {
- drop(Box::from_raw(block));
- }
- }
- }
-}
-
-impl<T> fmt::Debug for SegQueue<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.pad("SegQueue { .. }")
- }
-}
-
-impl<T> Default for SegQueue<T> {
- fn default() -> SegQueue<T> {
- SegQueue::new()
- }
-}
-
-impl<T> IntoIterator for SegQueue<T> {
- type Item = T;
-
- type IntoIter = IntoIter<T>;
-
- fn into_iter(self) -> Self::IntoIter {
- IntoIter { value: self }
- }
-}
-
-#[derive(Debug)]
-pub struct IntoIter<T> {
- value: SegQueue<T>,
-}
-
-impl<T> Iterator for IntoIter<T> {
- type Item = T;
-
- fn next(&mut self) -> Option<Self::Item> {
- let value = &mut self.value;
- let head = *value.head.index.get_mut();
- let tail = *value.tail.index.get_mut();
- if head >> SHIFT == tail >> SHIFT {
- None
- } else {
- let block = *value.head.block.get_mut();
- let offset = (head >> SHIFT) % LAP;
-
- // SAFETY: We have mutable access to this, so we can read without
- // worrying about concurrency. Furthermore, we know this is
- // initialized because it is the value pointed at by `value.head`
- // and this is a non-empty queue.
- let item = unsafe {
- let slot = (*block).slots.get_unchecked(offset);
- let p = &mut *slot.value.get();
- p.as_mut_ptr().read()
- };
- if offset + 1 == BLOCK_CAP {
- // Deallocate the block and move to the next one.
- // SAFETY: The block is initialized because we've been reading
- // from it this entire time. We can drop it b/c everything has
- // been read out of it, so nothing is pointing to it anymore.
- unsafe {
- let next = *(*block).next.get_mut();
- drop(Box::from_raw(block));
- *value.head.block.get_mut() = next;
- }
- // The last value in a block is empty, so skip it
- *value.head.index.get_mut() = head.wrapping_add(2 << SHIFT);
- // Double-check that we're pointing to the first item in a block.
- debug_assert_eq!((*value.head.index.get_mut() >> SHIFT) % LAP, 0);
- } else {
- *value.head.index.get_mut() = head.wrapping_add(1 << SHIFT);
- }
- Some(item)
- }
- }
-}
diff --git a/vendor/crossbeam-queue/tests/array_queue.rs b/vendor/crossbeam-queue/tests/array_queue.rs
deleted file mode 100644
index 9a64eac03..000000000
--- a/vendor/crossbeam-queue/tests/array_queue.rs
+++ /dev/null
@@ -1,359 +0,0 @@
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-use crossbeam_queue::ArrayQueue;
-use crossbeam_utils::thread::scope;
-use rand::{thread_rng, Rng};
-
-#[test]
-fn smoke() {
- let q = ArrayQueue::new(1);
-
- q.push(7).unwrap();
- assert_eq!(q.pop(), Some(7));
-
- q.push(8).unwrap();
- assert_eq!(q.pop(), Some(8));
- assert!(q.pop().is_none());
-}
-
-#[test]
-fn capacity() {
- for i in 1..10 {
- let q = ArrayQueue::<i32>::new(i);
- assert_eq!(q.capacity(), i);
- }
-}
-
-#[test]
-#[should_panic(expected = "capacity must be non-zero")]
-fn zero_capacity() {
- let _ = ArrayQueue::<i32>::new(0);
-}
-
-#[test]
-fn len_empty_full() {
- let q = ArrayQueue::new(2);
-
- assert_eq!(q.len(), 0);
- assert!(q.is_empty());
- assert!(!q.is_full());
-
- q.push(()).unwrap();
-
- assert_eq!(q.len(), 1);
- assert!(!q.is_empty());
- assert!(!q.is_full());
-
- q.push(()).unwrap();
-
- assert_eq!(q.len(), 2);
- assert!(!q.is_empty());
- assert!(q.is_full());
-
- q.pop().unwrap();
-
- assert_eq!(q.len(), 1);
- assert!(!q.is_empty());
- assert!(!q.is_full());
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn len() {
- const COUNT: usize = 25_000;
- const CAP: usize = 1000;
-
- let q = ArrayQueue::new(CAP);
- assert_eq!(q.len(), 0);
-
- for _ in 0..CAP / 10 {
- for i in 0..50 {
- q.push(i).unwrap();
- assert_eq!(q.len(), i + 1);
- }
-
- for i in 0..50 {
- q.pop().unwrap();
- assert_eq!(q.len(), 50 - i - 1);
- }
- }
- assert_eq!(q.len(), 0);
-
- for i in 0..CAP {
- q.push(i).unwrap();
- assert_eq!(q.len(), i + 1);
- }
-
- for _ in 0..CAP {
- q.pop().unwrap();
- }
- assert_eq!(q.len(), 0);
-
- scope(|scope| {
- scope.spawn(|_| {
- for i in 0..COUNT {
- loop {
- if let Some(x) = q.pop() {
- assert_eq!(x, i);
- break;
- }
- }
- let len = q.len();
- assert!(len <= CAP);
- }
- });
-
- scope.spawn(|_| {
- for i in 0..COUNT {
- while q.push(i).is_err() {}
- let len = q.len();
- assert!(len <= CAP);
- }
- });
- })
- .unwrap();
- assert_eq!(q.len(), 0);
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn spsc() {
- const COUNT: usize = 100_000;
-
- let q = ArrayQueue::new(3);
-
- scope(|scope| {
- scope.spawn(|_| {
- for i in 0..COUNT {
- loop {
- if let Some(x) = q.pop() {
- assert_eq!(x, i);
- break;
- }
- }
- }
- assert!(q.pop().is_none());
- });
-
- scope.spawn(|_| {
- for i in 0..COUNT {
- while q.push(i).is_err() {}
- }
- });
- })
- .unwrap();
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn spsc_ring_buffer() {
- const COUNT: usize = 100_000;
-
- let t = AtomicUsize::new(1);
- let q = ArrayQueue::<usize>::new(3);
- let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
-
- scope(|scope| {
- scope.spawn(|_| loop {
- match t.load(Ordering::SeqCst) {
- 0 if q.is_empty() => break,
-
- _ => {
- while let Some(n) = q.pop() {
- v[n].fetch_add(1, Ordering::SeqCst);
- }
- }
- }
- });
-
- scope.spawn(|_| {
- for i in 0..COUNT {
- if let Some(n) = q.force_push(i) {
- v[n].fetch_add(1, Ordering::SeqCst);
- }
- }
-
- t.fetch_sub(1, Ordering::SeqCst);
- });
- })
- .unwrap();
-
- for c in v {
- assert_eq!(c.load(Ordering::SeqCst), 1);
- }
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn mpmc() {
- const COUNT: usize = 25_000;
- const THREADS: usize = 4;
-
- let q = ArrayQueue::<usize>::new(3);
- let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
-
- scope(|scope| {
- for _ in 0..THREADS {
- scope.spawn(|_| {
- for _ in 0..COUNT {
- let n = loop {
- if let Some(x) = q.pop() {
- break x;
- }
- };
- v[n].fetch_add(1, Ordering::SeqCst);
- }
- });
- }
- for _ in 0..THREADS {
- scope.spawn(|_| {
- for i in 0..COUNT {
- while q.push(i).is_err() {}
- }
- });
- }
- })
- .unwrap();
-
- for c in v {
- assert_eq!(c.load(Ordering::SeqCst), THREADS);
- }
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn mpmc_ring_buffer() {
- const COUNT: usize = 25_000;
- const THREADS: usize = 4;
-
- let t = AtomicUsize::new(THREADS);
- let q = ArrayQueue::<usize>::new(3);
- let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
-
- scope(|scope| {
- for _ in 0..THREADS {
- scope.spawn(|_| loop {
- match t.load(Ordering::SeqCst) {
- 0 if q.is_empty() => break,
-
- _ => {
- while let Some(n) = q.pop() {
- v[n].fetch_add(1, Ordering::SeqCst);
- }
- }
- }
- });
- }
-
- for _ in 0..THREADS {
- scope.spawn(|_| {
- for i in 0..COUNT {
- if let Some(n) = q.force_push(i) {
- v[n].fetch_add(1, Ordering::SeqCst);
- }
- }
-
- t.fetch_sub(1, Ordering::SeqCst);
- });
- }
- })
- .unwrap();
-
- for c in v {
- assert_eq!(c.load(Ordering::SeqCst), THREADS);
- }
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn drops() {
- const RUNS: usize = 100;
-
- static DROPS: AtomicUsize = AtomicUsize::new(0);
-
- #[derive(Debug, PartialEq)]
- struct DropCounter;
-
- impl Drop for DropCounter {
- fn drop(&mut self) {
- DROPS.fetch_add(1, Ordering::SeqCst);
- }
- }
-
- let mut rng = thread_rng();
-
- for _ in 0..RUNS {
- let steps = rng.gen_range(0..10_000);
- let additional = rng.gen_range(0..50);
-
- DROPS.store(0, Ordering::SeqCst);
- let q = ArrayQueue::new(50);
-
- scope(|scope| {
- scope.spawn(|_| {
- for _ in 0..steps {
- while q.pop().is_none() {}
- }
- });
-
- scope.spawn(|_| {
- for _ in 0..steps {
- while q.push(DropCounter).is_err() {
- DROPS.fetch_sub(1, Ordering::SeqCst);
- }
- }
- });
- })
- .unwrap();
-
- for _ in 0..additional {
- q.push(DropCounter).unwrap();
- }
-
- assert_eq!(DROPS.load(Ordering::SeqCst), steps);
- drop(q);
- assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional);
- }
-}
-
-#[test]
-fn linearizable() {
- #[cfg(miri)]
- const COUNT: usize = 500;
- #[cfg(not(miri))]
- const COUNT: usize = 25_000;
- const THREADS: usize = 4;
-
- let q = ArrayQueue::new(THREADS);
-
- scope(|scope| {
- for _ in 0..THREADS / 2 {
- scope.spawn(|_| {
- for _ in 0..COUNT {
- while q.push(0).is_err() {}
- q.pop().unwrap();
- }
- });
-
- scope.spawn(|_| {
- for _ in 0..COUNT {
- if q.force_push(0).is_none() {
- q.pop().unwrap();
- }
- }
- });
- }
- })
- .unwrap();
-}
-
-#[test]
-fn into_iter() {
- let q = ArrayQueue::new(100);
- for i in 0..100 {
- q.push(i).unwrap();
- }
- for (i, j) in q.into_iter().enumerate() {
- assert_eq!(i, j);
- }
-}
diff --git a/vendor/crossbeam-queue/tests/seg_queue.rs b/vendor/crossbeam-queue/tests/seg_queue.rs
deleted file mode 100644
index f1304ed4a..000000000
--- a/vendor/crossbeam-queue/tests/seg_queue.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-use crossbeam_queue::SegQueue;
-use crossbeam_utils::thread::scope;
-use rand::{thread_rng, Rng};
-
-#[test]
-fn smoke() {
- let q = SegQueue::new();
- q.push(7);
- assert_eq!(q.pop(), Some(7));
-
- q.push(8);
- assert_eq!(q.pop(), Some(8));
- assert!(q.pop().is_none());
-}
-
-#[test]
-fn len_empty_full() {
- let q = SegQueue::new();
-
- assert_eq!(q.len(), 0);
- assert!(q.is_empty());
-
- q.push(());
-
- assert_eq!(q.len(), 1);
- assert!(!q.is_empty());
-
- q.pop().unwrap();
-
- assert_eq!(q.len(), 0);
- assert!(q.is_empty());
-}
-
-#[test]
-fn len() {
- let q = SegQueue::new();
-
- assert_eq!(q.len(), 0);
-
- for i in 0..50 {
- q.push(i);
- assert_eq!(q.len(), i + 1);
- }
-
- for i in 0..50 {
- q.pop().unwrap();
- assert_eq!(q.len(), 50 - i - 1);
- }
-
- assert_eq!(q.len(), 0);
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn spsc() {
- const COUNT: usize = 100_000;
-
- let q = SegQueue::new();
-
- scope(|scope| {
- scope.spawn(|_| {
- for i in 0..COUNT {
- loop {
- if let Some(x) = q.pop() {
- assert_eq!(x, i);
- break;
- }
- }
- }
- assert!(q.pop().is_none());
- });
- scope.spawn(|_| {
- for i in 0..COUNT {
- q.push(i);
- }
- });
- })
- .unwrap();
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn mpmc() {
- const COUNT: usize = 25_000;
- const THREADS: usize = 4;
-
- let q = SegQueue::<usize>::new();
- let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
-
- scope(|scope| {
- for _ in 0..THREADS {
- scope.spawn(|_| {
- for _ in 0..COUNT {
- let n = loop {
- if let Some(x) = q.pop() {
- break x;
- }
- };
- v[n].fetch_add(1, Ordering::SeqCst);
- }
- });
- }
- for _ in 0..THREADS {
- scope.spawn(|_| {
- for i in 0..COUNT {
- q.push(i);
- }
- });
- }
- })
- .unwrap();
-
- for c in v {
- assert_eq!(c.load(Ordering::SeqCst), THREADS);
- }
-}
-
-#[cfg_attr(miri, ignore)] // Miri is too slow
-#[test]
-fn drops() {
- const RUNS: usize = 100;
-
- static DROPS: AtomicUsize = AtomicUsize::new(0);
-
- #[derive(Debug, PartialEq)]
- struct DropCounter;
-
- impl Drop for DropCounter {
- fn drop(&mut self) {
- DROPS.fetch_add(1, Ordering::SeqCst);
- }
- }
-
- let mut rng = thread_rng();
-
- for _ in 0..RUNS {
- let steps = rng.gen_range(0..10_000);
- let additional = rng.gen_range(0..1000);
-
- DROPS.store(0, Ordering::SeqCst);
- let q = SegQueue::new();
-
- scope(|scope| {
- scope.spawn(|_| {
- for _ in 0..steps {
- while q.pop().is_none() {}
- }
- });
-
- scope.spawn(|_| {
- for _ in 0..steps {
- q.push(DropCounter);
- }
- });
- })
- .unwrap();
-
- for _ in 0..additional {
- q.push(DropCounter);
- }
-
- assert_eq!(DROPS.load(Ordering::SeqCst), steps);
- drop(q);
- assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional);
- }
-}
-
-#[test]
-fn into_iter() {
- let q = SegQueue::new();
- for i in 0..100 {
- q.push(i);
- }
- for (i, j) in q.into_iter().enumerate() {
- assert_eq!(i, j);
- }
-}
-
-#[test]
-fn into_iter_drop() {
- let q = SegQueue::new();
- for i in 0..100 {
- q.push(i);
- }
- for (i, j) in q.into_iter().enumerate().take(50) {
- assert_eq!(i, j);
- }
-}
diff --git a/vendor/crossbeam-utils/.cargo-checksum.json b/vendor/crossbeam-utils/.cargo-checksum.json
index f78acc358..eac87698d 100644
--- a/vendor/crossbeam-utils/.cargo-checksum.json
+++ b/vendor/crossbeam-utils/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"c2cdac68fbf3795e9c3cb0bbeace5f87736d0745fefbd3db9c07f568dc70d1d1","Cargo.toml":"fc5b0f0f821aa944d4341dc97e7c3b4d4bf658483ba359b5bf2e53d8ad945ac9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"dfa9fbed47c344c134a63c84b7c0e4651baeac1554b7b3266d0e38643743fc33","benches/atomic_cell.rs":"c927eb3cd1e5ecc4b91adbc3bde98af15ffab4086190792ba64d5cde0e24df3d","build.rs":"7e74dc72343ff57e83d0a84a9fbdd9ff1645894165909999b4c3d2fba94bc96c","no_atomic.rs":"916ed15218bb7b75a4e0d432430e7134efd27ca43ca8a8766e0c90e89febb602","src/atomic/atomic_cell.rs":"f1b407b62b981de47968236eabb932384722c4dd7b7f08f52c59943aefd0b113","src/atomic/consume.rs":"7a7736fcd64f6473dfea7653559ffc5e1a2a234df43835f8aa8734862145ac15","src/atomic/mod.rs":"94193895fa03cece415e8d7be700b73a9a8a7015774ca821253438607f9b0736","src/atomic/seq_lock.rs":"27182e6b87a9db73c5f6831759f8625f9fcdec3c2828204c444aef04f427735a","src/atomic/seq_lock_wide.rs":"9888dd03116bb89ca36d4ab8d5a0b5032107a2983a7eb8024454263b09080088","src/backoff.rs":"7cc7754e15f69b52e92a70d4f49d1bc274693455a0933a2d7eb0605806566af3","src/cache_padded.rs":"6a512698115ad0d5a5b163dbd7a83247e1f1c146c4a30f3fc74b952e3b767b59","src/lib.rs":"6f1bcf157abe06ad8458a53e865bf8efab9fad4a9424790147cee8fefb3795d8","src/sync/mod.rs":"59986f559a8f170a4b3247ab2eea2460b09809d87c8110ed88e4e7103d3519dc","src/sync/parker.rs":"3f997f5b41fec286ccedcf3d36f801d741387badb574820b8e3456117ecd9154","src/sync/sharded_lock.rs":"78433f55ee3defeea348d65abc78e03d63d6a304e09c568b27b403e9ad205771","src/sync/wait_group.rs":"32e946a7581c55f8aa9904527b92b177c538fa0cf7cbcfa1d1f25990582cb6ea","src/thread.rs":"21cf9b3e965529e5c0a6ff8fc1ec846bfe0006c41deb238a149be8d07384e955","tests/atomic_cell.rs":"bf8bc869c922a1cbf929c3b741bae0cae98f2157f572b5a4eb2873d20a407c22","tests/cache_padded.rs":"1bfaff8354c8184e1ee1f902881ca9400b60effb273b0d3f752801a483d2b66d","tests/parker.rs":"6def4721287d9d70b1cfd63ebb34e1c83fbb3376edbad2bc8aac6ef69dd99d20","tests/sharded_lock.rs":"314adeb8a651a28935f7a49c9a261b8fa1fd82bf6a16c865a5aced6216d7e40b","tests/thread.rs":"9a7d7d3028c552fd834c68598b04a1cc252a816bc20ab62cec060d6cd09cab10","tests/wait_group.rs":"ad8f0cdfed31f9594a2e0737234d418f8b924d784a4db8d7e469deab8c95f5f8"},"package":"7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"eb2f46ecf2eee5f591c4d4e789f18735bb1ed771782a5e0f16eab3a77001e7c2","Cargo.toml":"9ce8b596c9789e65bef4c952bdcac84fc88e50ba9ecb01a818036eff4e6ecfec","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"2a19af38a52dd965c2d66bb39f90a85b430b51ee9ccb29e9e1978ee7091e5087","benches/atomic_cell.rs":"c927eb3cd1e5ecc4b91adbc3bde98af15ffab4086190792ba64d5cde0e24df3d","build.rs":"4859f9c926c230023e861bf01c4b225b460035faf8cf6240108530efedbb747f","no_atomic.rs":"916ed15218bb7b75a4e0d432430e7134efd27ca43ca8a8766e0c90e89febb602","src/atomic/atomic_cell.rs":"0fc99463e633144c5d59d39c35b5477da1f1b90f5448cadc37454b7f4b97707e","src/atomic/consume.rs":"7a7736fcd64f6473dfea7653559ffc5e1a2a234df43835f8aa8734862145ac15","src/atomic/mod.rs":"94193895fa03cece415e8d7be700b73a9a8a7015774ca821253438607f9b0736","src/atomic/seq_lock.rs":"27182e6b87a9db73c5f6831759f8625f9fcdec3c2828204c444aef04f427735a","src/atomic/seq_lock_wide.rs":"9888dd03116bb89ca36d4ab8d5a0b5032107a2983a7eb8024454263b09080088","src/backoff.rs":"8fd5e3dcccc05860680e49c8498de8096bee9140bcfee8723d97117106a020d0","src/cache_padded.rs":"6a512698115ad0d5a5b163dbd7a83247e1f1c146c4a30f3fc74b952e3b767b59","src/lib.rs":"6f1bcf157abe06ad8458a53e865bf8efab9fad4a9424790147cee8fefb3795d8","src/sync/mod.rs":"59986f559a8f170a4b3247ab2eea2460b09809d87c8110ed88e4e7103d3519dc","src/sync/parker.rs":"91f3a7d4ee8d9e06b6558d180e8a0df08ff5c6cef612b4ce4790f9f75cb34f84","src/sync/sharded_lock.rs":"78433f55ee3defeea348d65abc78e03d63d6a304e09c568b27b403e9ad205771","src/sync/wait_group.rs":"32e946a7581c55f8aa9904527b92b177c538fa0cf7cbcfa1d1f25990582cb6ea","src/thread.rs":"21cf9b3e965529e5c0a6ff8fc1ec846bfe0006c41deb238a149be8d07384e955","tests/atomic_cell.rs":"bf8bc869c922a1cbf929c3b741bae0cae98f2157f572b5a4eb2873d20a407c22","tests/cache_padded.rs":"1bfaff8354c8184e1ee1f902881ca9400b60effb273b0d3f752801a483d2b66d","tests/parker.rs":"6def4721287d9d70b1cfd63ebb34e1c83fbb3376edbad2bc8aac6ef69dd99d20","tests/sharded_lock.rs":"314adeb8a651a28935f7a49c9a261b8fa1fd82bf6a16c865a5aced6216d7e40b","tests/thread.rs":"9a7d7d3028c552fd834c68598b04a1cc252a816bc20ab62cec060d6cd09cab10","tests/wait_group.rs":"02661c2a820a5abe8b0c8fe15a6650aead707b57cdda0610d1b09a2680ed6969"},"package":"51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"} \ No newline at end of file
diff --git a/vendor/crossbeam-utils/CHANGELOG.md b/vendor/crossbeam-utils/CHANGELOG.md
index 8decb6cbd..28812e1d6 100644
--- a/vendor/crossbeam-utils/CHANGELOG.md
+++ b/vendor/crossbeam-utils/CHANGELOG.md
@@ -1,3 +1,7 @@
+# Version 0.8.11
+
+- Bump the minimum supported Rust version to 1.38. (#877)
+
# Version 0.8.10
- Fix unsoundness of `AtomicCell` on types containing niches. (#834)
diff --git a/vendor/crossbeam-utils/Cargo.toml b/vendor/crossbeam-utils/Cargo.toml
index fa958df28..9e1b58628 100644
--- a/vendor/crossbeam-utils/Cargo.toml
+++ b/vendor/crossbeam-utils/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2018"
-rust-version = "1.36"
+rust-version = "1.38"
name = "crossbeam-utils"
-version = "0.8.10"
+version = "0.8.11"
description = "Utilities for concurrent programming"
homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils"
readme = "README.md"
diff --git a/vendor/crossbeam-utils/README.md b/vendor/crossbeam-utils/README.md
index 6e9a8e49a..c06ea601a 100644
--- a/vendor/crossbeam-utils/README.md
+++ b/vendor/crossbeam-utils/README.md
@@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils#license)
https://crates.io/crates/crossbeam-utils)
[![Documentation](https://docs.rs/crossbeam-utils/badge.svg)](
https://docs.rs/crossbeam-utils)
-[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
+[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)](
https://www.rust-lang.org)
[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
@@ -55,7 +55,7 @@ crossbeam-utils = "0.8"
Crossbeam Utils supports stable Rust releases going back at least six months,
and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.36.
+version is released. Currently, the minimum supported Rust version is 1.38.
## License
diff --git a/vendor/crossbeam-utils/build.rs b/vendor/crossbeam-utils/build.rs
index a7557fd59..dd6604792 100644
--- a/vendor/crossbeam-utils/build.rs
+++ b/vendor/crossbeam-utils/build.rs
@@ -41,10 +41,9 @@ fn main() {
}
};
- // Note that this is `no_*`, not `has_*`. This allows treating
- // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
- // run. This is needed for compatibility with non-cargo build systems that
- // don't run the build script.
+ // Note that this is `no_`*, not `has_*`. This allows treating as the latest
+ // stable rustc is used when the build script doesn't run. This is useful
+ // for non-cargo build systems that don't run the build script.
if NO_ATOMIC_CAS.contains(&&*target) {
println!("cargo:rustc-cfg=crossbeam_no_atomic_cas");
}
diff --git a/vendor/crossbeam-utils/src/atomic/atomic_cell.rs b/vendor/crossbeam-utils/src/atomic/atomic_cell.rs
index 9fed45d4c..7941c5c87 100644
--- a/vendor/crossbeam-utils/src/atomic/atomic_cell.rs
+++ b/vendor/crossbeam-utils/src/atomic/atomic_cell.rs
@@ -180,7 +180,7 @@ impl<T> AtomicCell<T> {
/// ```
#[inline]
pub fn as_ptr(&self) -> *mut T {
- self.value.get() as *mut T
+ self.value.get().cast::<T>()
}
}
@@ -902,12 +902,7 @@ fn lock(addr: usize) -> &'static SeqLock {
const LEN: usize = 97;
#[allow(clippy::declare_interior_mutable_const)]
const L: SeqLock = SeqLock::new();
- static LOCKS: [SeqLock; LEN] = [
- L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
- L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
- L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
- L, L, L, L, L, L, L,
- ];
+ static LOCKS: [SeqLock; LEN] = [L; LEN];
// If the modulus is a constant number, the compiler will use crazy math to transform this into
// a sequence of cheap arithmetic operations rather than using the slow modulo instruction.
@@ -973,7 +968,7 @@ macro_rules! atomic {
/// Returns `true` if operations on `AtomicCell<T>` are lock-free.
const fn atomic_is_lock_free<T>() -> bool {
- // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
+ // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in our MSRV (Rust 1.38).
let is_lock_free = can_transmute::<T, AtomicUnit>()
| can_transmute::<T, atomic::AtomicU8>()
| can_transmute::<T, atomic::AtomicU16>()
@@ -1009,10 +1004,11 @@ where
// discard the data when a data race is detected. The proper solution would be to
// do atomic reads and atomic writes, but we can't atomically read and write all
// kinds of data since `AtomicU8` is not available on stable Rust yet.
- let val = ptr::read_volatile(src);
+ // Load as `MaybeUninit` because we may load a value that is not valid as `T`.
+ let val = ptr::read_volatile(src.cast::<MaybeUninit<T>>());
if lock.validate_read(stamp) {
- return val;
+ return val.assume_init();
}
}
@@ -1072,6 +1068,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T) -> T {
///
/// This operation uses the `AcqRel` ordering. If possible, an atomic instructions is used, and a
/// global lock otherwise.
+#[allow(clippy::let_unit_value)]
unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, mut current: T, new: T) -> Result<T, T>
where
T: Copy + Eq,
diff --git a/vendor/crossbeam-utils/src/backoff.rs b/vendor/crossbeam-utils/src/backoff.rs
index 1012f06b2..9e256aaf2 100644
--- a/vendor/crossbeam-utils/src/backoff.rs
+++ b/vendor/crossbeam-utils/src/backoff.rs
@@ -201,6 +201,7 @@ impl Backoff {
/// assert_eq!(ready.load(SeqCst), false);
/// spin_wait(&ready);
/// assert_eq!(ready.load(SeqCst), true);
+ /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
/// ```
///
/// [`AtomicBool`]: std::sync::atomic::AtomicBool
@@ -269,6 +270,7 @@ impl Backoff {
/// assert_eq!(ready.load(SeqCst), false);
/// blocking_wait(&ready);
/// assert_eq!(ready.load(SeqCst), true);
+ /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
/// ```
///
/// [`AtomicBool`]: std::sync::atomic::AtomicBool
diff --git a/vendor/crossbeam-utils/src/sync/parker.rs b/vendor/crossbeam-utils/src/sync/parker.rs
index 531f5a5fc..e791c4485 100644
--- a/vendor/crossbeam-utils/src/sync/parker.rs
+++ b/vendor/crossbeam-utils/src/sync/parker.rs
@@ -44,6 +44,7 @@ use std::time::{Duration, Instant};
///
/// // Wakes up when `u.unpark()` provides the token.
/// p.park();
+/// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
/// ```
///
/// [`park`]: Parker::park
@@ -241,6 +242,7 @@ impl Unparker {
///
/// // Wakes up when `u.unpark()` provides the token.
/// p.park();
+ /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
/// ```
///
/// [`park`]: Parker::park
@@ -262,7 +264,7 @@ impl Unparker {
/// # let _ = unsafe { Unparker::from_raw(raw) };
/// ```
pub fn into_raw(this: Unparker) -> *const () {
- Arc::into_raw(this.inner) as *const ()
+ Arc::into_raw(this.inner).cast::<()>()
}
/// Converts a raw pointer into an `Unparker`.
@@ -284,7 +286,7 @@ impl Unparker {
/// ```
pub unsafe fn from_raw(ptr: *const ()) -> Unparker {
Unparker {
- inner: Arc::from_raw(ptr as *const Inner),
+ inner: Arc::from_raw(ptr.cast::<Inner>()),
}
}
}
diff --git a/vendor/crossbeam-utils/tests/wait_group.rs b/vendor/crossbeam-utils/tests/wait_group.rs
index b6c2a2437..0ec4a729c 100644
--- a/vendor/crossbeam-utils/tests/wait_group.rs
+++ b/vendor/crossbeam-utils/tests/wait_group.rs
@@ -36,6 +36,7 @@ fn wait() {
}
#[test]
+#[cfg_attr(miri, ignore)] // this test makes timing assumptions, but Miri is so slow it violates them
fn wait_and_drop() {
let wg = WaitGroup::new();
let (tx, rx) = mpsc::channel();
@@ -51,8 +52,8 @@ fn wait_and_drop() {
});
}
- // At this point, all spawned threads should be sleeping, so we shouldn't get anything from the
- // channel.
+ // At this point, all spawned threads should be in `thread::sleep`, so we shouldn't get anything
+ // from the channel.
assert!(rx.try_recv().is_err());
wg.wait();
diff --git a/vendor/crossbeam/.cargo-checksum.json b/vendor/crossbeam/.cargo-checksum.json
deleted file mode 100644
index 0bd859983..000000000
--- a/vendor/crossbeam/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"e8dcdd4c84fced11ce3e9be9246dd511e9d09b0b36497c6e569ed0427b57424a","Cargo.toml":"a1452bb8649a66814e473799942aa624243bab0e5257a5b11ce994253b41ecb4","LICENSE-APACHE":"6f712474a3e3be1386d2d0c29449850ea788da64d35cff0fc8799acf741e9ecd","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"d1d81cf88e580608f27bf4d2bb7f6f2d01c2c1f1d26be86ec1daa7aa455e9f62","no_atomic.rs":"a2621c1b029c614fb0ab8e3f5cda2e839df88d90d26133181c1b901965f7eec4","src/lib.rs":"e896ef1e4326db5202cebdd57dd606f96113d5a8700e746bfe8909978ac84a7f","tests/subcrates.rs":"69cbe766a855ad6278cc969a61ba871eba3594afb5c2d3c647dff5b794e160ab"},"package":"4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"} \ No newline at end of file
diff --git a/vendor/crossbeam/CHANGELOG.md b/vendor/crossbeam/CHANGELOG.md
deleted file mode 100644
index f756fbb73..000000000
--- a/vendor/crossbeam/CHANGELOG.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# Version 0.8.1
-
-- Support targets that do not have atomic CAS on stable Rust (#698)
-
-# Version 0.8.0
-
-- Bump the minimum supported Rust version to 1.36.
-- Bump `crossbeam-channel` to `0.5`.
-- Bump `crossbeam-deque` to `0.8`.
-- Bump `crossbeam-epoch` to `0.9`.
-- Bump `crossbeam-queue` to `0.3`.
-- Bump `crossbeam-utils` to `0.8`.
-
-# Version 0.7.3
-
-- Fix breakage with nightly feature due to rust-lang/rust#65214.
-- Bump `crossbeam-channel` to `0.4`.
-- Bump `crossbeam-epoch` to `0.8`.
-- Bump `crossbeam-queue` to `0.2`.
-- Bump `crossbeam-utils` to `0.7`.
-
-# Version 0.7.2
-
-- Bump `crossbeam-channel` to `0.3.9`.
-- Bump `crossbeam-epoch` to `0.7.2`.
-- Bump `crossbeam-utils` to `0.6.6`.
-
-# Version 0.7.1
-
-- Bump `crossbeam-utils` to `0.6.5`.
-
-# Version 0.7.0
-
-- Remove `ArcCell`, `MsQueue`, and `TreiberStack`.
-- Change the interface of `ShardedLock` to match `RwLock`.
-- Add `SegQueue::len()`.
-- Rename `SegQueue::try_pop()` to `SegQueue::pop()`.
-- Change the return type of `SegQueue::pop()` to `Result`.
-- Introduce `ArrayQueue`.
-- Update dependencies.
-
-# Version 0.6.0
-
-- Update dependencies.
-
-# Version 0.5.0
-
-- Update `crossbeam-channel` to 0.3.
-- Update `crossbeam-utils` to 0.6.
-- Add `AtomicCell`, `SharedLock`, and `WaitGroup`.
-
-# Version 0.4.1
-
-- Fix a double-free bug in `MsQueue` and `SegQueue`.
-
-# Version 0.4
-
-- Switch to the new implementation of epoch-based reclamation in
- [`crossbeam-epoch`](https://github.com/crossbeam-rs/crossbeam-epoch), fixing numerous bugs in the
- old implementation. Its API is changed in a backward-incompatible way.
-- Switch to the new implementation of `CachePadded` and scoped thread in
- [`crossbeam-utils`](https://github.com/crossbeam-rs/crossbeam-utils). The scoped thread API is
- changed in a backward-incompatible way.
-- Switch to the new implementation of Chase-Lev deque in
- [`crossbeam-deque`](https://github.com/crossbeam-rs/crossbeam-deque). Its API is changed in a
- backward-incompatible way.
-- Export channel implemented in
- [`crossbeam-channel`](https://github.com/crossbeam-rs/crossbeam-channel).
-- Remove `AtomicOption`.
-- Implement `Default` and `From` traits.
-
-# Version 0.3
-
-- Introduced `ScopedThreadBuilder` with the ability to name threads and set stack size
-- `Worker` methods in the Chase-Lev deque don't require mutable access anymore
-- Fixed a bug when unblocking `pop()` in `MsQueue`
-- Implemented `Drop` for `MsQueue`, `SegQueue`, and `TreiberStack`
-- Implemented `Default` for `TreiberStack`
-- Added `is_empty` to `SegQueue`
-- Renamed `mem::epoch` to `epoch`
-- Other bug fixes
-
-# Version 0.2
-
-- Changed existing non-blocking `pop` methods to `try_pop`
-- Added blocking `pop` support to Michael-Scott queue
-- Added Chase-Lev work-stealing deque
-
-# Version 0.1
-
-- Added [epoch-based memory management](http://aturon.github.io/blog/2015/08/27/epoch/)
-- Added Michael-Scott queue
-- Added Segmented array queue
diff --git a/vendor/crossbeam/Cargo.toml b/vendor/crossbeam/Cargo.toml
deleted file mode 100644
index 71710f835..000000000
--- a/vendor/crossbeam/Cargo.toml
+++ /dev/null
@@ -1,59 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-edition = "2018"
-name = "crossbeam"
-version = "0.8.1"
-authors = ["The Crossbeam Project Developers"]
-exclude = ["/.github", "/ci"]
-description = "Tools for concurrent programming"
-homepage = "https://github.com/crossbeam-rs/crossbeam"
-documentation = "https://docs.rs/crossbeam"
-keywords = ["atomic", "garbage", "non-blocking", "lock-free", "rcu"]
-categories = ["concurrency", "memory-management", "data-structures", "no-std"]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/crossbeam-rs/crossbeam"
-[dependencies.cfg-if]
-version = "1"
-
-[dependencies.crossbeam-channel]
-version = "0.5"
-optional = true
-default-features = false
-
-[dependencies.crossbeam-deque]
-version = "0.8"
-optional = true
-default-features = false
-
-[dependencies.crossbeam-epoch]
-version = "0.9.5"
-optional = true
-default-features = false
-
-[dependencies.crossbeam-queue]
-version = "0.3.2"
-optional = true
-default-features = false
-
-[dependencies.crossbeam-utils]
-version = "0.8.5"
-default-features = false
-[dev-dependencies.rand]
-version = "0.8"
-
-[features]
-alloc = ["crossbeam-epoch/alloc", "crossbeam-queue/alloc"]
-default = ["std"]
-nightly = ["crossbeam-epoch/nightly", "crossbeam-utils/nightly", "crossbeam-queue/nightly"]
-std = ["alloc", "crossbeam-channel/std", "crossbeam-deque/std", "crossbeam-epoch/std", "crossbeam-queue/std", "crossbeam-utils/std"]
diff --git a/vendor/crossbeam/LICENSE-APACHE b/vendor/crossbeam/LICENSE-APACHE
deleted file mode 100644
index bb9abdd7f..000000000
--- a/vendor/crossbeam/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright 2019 The Crossbeam Project Developers
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/crossbeam/LICENSE-MIT b/vendor/crossbeam/LICENSE-MIT
deleted file mode 100644
index 068d491fd..000000000
--- a/vendor/crossbeam/LICENSE-MIT
+++ /dev/null
@@ -1,27 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2019 The Crossbeam Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/crossbeam/README.md b/vendor/crossbeam/README.md
deleted file mode 100644
index 1ed435c0a..000000000
--- a/vendor/crossbeam/README.md
+++ /dev/null
@@ -1,158 +0,0 @@
-# Crossbeam
-
-[![Build Status](https://github.com/crossbeam-rs/crossbeam/workflows/CI/badge.svg)](
-https://github.com/crossbeam-rs/crossbeam/actions)
-[![License](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue.svg)](
-https://github.com/crossbeam-rs/crossbeam#license)
-[![Cargo](https://img.shields.io/crates/v/crossbeam.svg)](
-https://crates.io/crates/crossbeam)
-[![Documentation](https://docs.rs/crossbeam/badge.svg)](
-https://docs.rs/crossbeam)
-[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
-https://www.rust-lang.org)
-[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
-
-This crate provides a set of tools for concurrent programming:
-
-#### Atomics
-
-* [`AtomicCell`], a thread-safe mutable memory location.<sup>(no_std)</sup>
-* [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering.<sup>(no_std)</sup>
-
-#### Data structures
-
-* [`deque`], work-stealing deques for building task schedulers.
-* [`ArrayQueue`], a bounded MPMC queue that allocates a fixed-capacity buffer on construction.<sup>(alloc)</sup>
-* [`SegQueue`], an unbounded MPMC queue that allocates small buffers, segments, on demand.<sup>(alloc)</sup>
-
-#### Memory management
-
-* [`epoch`], an epoch-based garbage collector.<sup>(alloc)</sup>
-
-#### Thread synchronization
-
-* [`channel`], multi-producer multi-consumer channels for message passing.
-* [`Parker`], a thread parking primitive.
-* [`ShardedLock`], a sharded reader-writer lock with fast concurrent reads.
-* [`WaitGroup`], for synchronizing the beginning or end of some computation.
-
-#### Utilities
-
-* [`Backoff`], for exponential backoff in spin loops.<sup>(no_std)</sup>
-* [`CachePadded`], for padding and aligning a value to the length of a cache line.<sup>(no_std)</sup>
-* [`scope`], for spawning threads that borrow local variables from the stack.
-
-*Features marked with <sup>(no_std)</sup> can be used in `no_std` environments.*<br/>
-*Features marked with <sup>(alloc)</sup> can be used in `no_std` environments, but only if `alloc`
-feature is enabled.*
-
-[`AtomicCell`]: https://docs.rs/crossbeam/*/crossbeam/atomic/struct.AtomicCell.html
-[`AtomicConsume`]: https://docs.rs/crossbeam/*/crossbeam/atomic/trait.AtomicConsume.html
-[`deque`]: https://docs.rs/crossbeam/*/crossbeam/deque/index.html
-[`ArrayQueue`]: https://docs.rs/crossbeam/*/crossbeam/queue/struct.ArrayQueue.html
-[`SegQueue`]: https://docs.rs/crossbeam/*/crossbeam/queue/struct.SegQueue.html
-[`channel`]: https://docs.rs/crossbeam/*/crossbeam/channel/index.html
-[`Parker`]: https://docs.rs/crossbeam/*/crossbeam/sync/struct.Parker.html
-[`ShardedLock`]: https://docs.rs/crossbeam/*/crossbeam/sync/struct.ShardedLock.html
-[`WaitGroup`]: https://docs.rs/crossbeam/*/crossbeam/sync/struct.WaitGroup.html
-[`epoch`]: https://docs.rs/crossbeam/*/crossbeam/epoch/index.html
-[`Backoff`]: https://docs.rs/crossbeam/*/crossbeam/utils/struct.Backoff.html
-[`CachePadded`]: https://docs.rs/crossbeam/*/crossbeam/utils/struct.CachePadded.html
-[`scope`]: https://docs.rs/crossbeam/*/crossbeam/fn.scope.html
-
-## Crates
-
-The main `crossbeam` crate just [re-exports](src/lib.rs) tools from
-smaller subcrates:
-
-* [`crossbeam-channel`](crossbeam-channel)
- provides multi-producer multi-consumer channels for message passing.
-* [`crossbeam-deque`](crossbeam-deque)
- provides work-stealing deques, which are primarily intended for building task schedulers.
-* [`crossbeam-epoch`](crossbeam-epoch)
- provides epoch-based garbage collection for building concurrent data structures.
-* [`crossbeam-queue`](crossbeam-queue)
- provides concurrent queues that can be shared among threads.
-* [`crossbeam-utils`](crossbeam-utils)
- provides atomics, synchronization primitives, scoped threads, and other utilities.
-
-There is one more experimental subcrate that is not yet included in `crossbeam`:
-
-* [`crossbeam-skiplist`](crossbeam-skiplist)
- provides concurrent maps and sets based on lock-free skip lists.
-
-## Usage
-
-Add this to your `Cargo.toml`:
-
-```toml
-[dependencies]
-crossbeam = "0.8"
-```
-
-## Compatibility
-
-Crossbeam supports stable Rust releases going back at least six months,
-and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.36.
-
-## Contributing
-
-Crossbeam welcomes contribution from everyone in the form of suggestions, bug reports,
-pull requests, and feedback. 💛
-
-If you need ideas for contribution, there are several ways to get started:
-
-* Found a bug or have a feature request?
- [Submit an issue](https://github.com/crossbeam-rs/crossbeam/issues/new)!
-* Issues and PRs labeled with
- [feedback wanted](https://github.com/crossbeam-rs/crossbeam/issues?utf8=%E2%9C%93&q=is%3Aopen+sort%3Aupdated-desc+label%3A%22feedback+wanted%22+)
- need feedback from users and contributors.
-* Issues labeled with
- [good first issue](https://github.com/crossbeam-rs/crossbeam/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22)
- are relatively easy starter issues.
-
-#### RFCs
-
-We also have the [RFCs](https://github.com/crossbeam-rs/rfcs) repository for more
-high-level discussion, which is the place where we brainstorm ideas and propose
-substantial changes to Crossbeam.
-
-You are welcome to participate in any open
-[issues](https://github.com/crossbeam-rs/rfcs/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)
-or
-[pull requests](https://github.com/crossbeam-rs/rfcs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc).
-
-#### Learning resources
-
-If you'd like to learn more about concurrency and non-blocking data structures, there's a
-list of learning resources in our [wiki](https://github.com/crossbeam-rs/rfcs/wiki),
-which includes relevant blog posts, papers, videos, and other similar projects.
-
-Another good place to visit is [merged RFCs](https://github.com/crossbeam-rs/rfcs/tree/master/text).
-They contain elaborate descriptions and rationale for features we've introduced to
-Crossbeam, but keep in mind that some of the written information is now out of date.
-
-#### Conduct
-
-The Crossbeam project adheres to the
-[Rust Code of Conduct](https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md).
-This describes the minimum behavior expected from all contributors.
-
-## License
-
-Licensed under either of
-
- * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
-
-at your option.
-
-Some Crossbeam subcrates have additional licensing notices.
-Take a look at other readme files in this repository for more information.
-
-#### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
-dual licensed as above, without any additional terms or conditions.
diff --git a/vendor/crossbeam/no_atomic.rs b/vendor/crossbeam/no_atomic.rs
deleted file mode 100644
index 522b3b8ac..000000000
--- a/vendor/crossbeam/no_atomic.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-// This file is @generated by no_atomic.sh.
-// It is not intended for manual editing.
-
-const NO_ATOMIC_CAS: &[&str] = &[
- "avr-unknown-gnu-atmega328",
- "msp430-none-elf",
- "riscv32i-unknown-none-elf",
- "riscv32imc-unknown-none-elf",
- "thumbv4t-none-eabi",
- "thumbv6m-none-eabi",
-];
-#[allow(dead_code)]
-const NO_ATOMIC_64: &[&str] = &[
- "arm-linux-androideabi",
- "armebv7r-none-eabi",
- "armebv7r-none-eabihf",
- "armv4t-unknown-linux-gnueabi",
- "armv5te-unknown-linux-gnueabi",
- "armv5te-unknown-linux-musleabi",
- "armv5te-unknown-linux-uclibceabi",
- "armv7r-none-eabi",
- "armv7r-none-eabihf",
- "hexagon-unknown-linux-musl",
- "mips-unknown-linux-gnu",
- "mips-unknown-linux-musl",
- "mips-unknown-linux-uclibc",
- "mipsel-unknown-linux-gnu",
- "mipsel-unknown-linux-musl",
- "mipsel-unknown-linux-uclibc",
- "mipsel-unknown-none",
- "mipsisa32r6-unknown-linux-gnu",
- "mipsisa32r6el-unknown-linux-gnu",
- "powerpc-unknown-linux-gnu",
- "powerpc-unknown-linux-gnuspe",
- "powerpc-unknown-linux-musl",
- "powerpc-unknown-netbsd",
- "powerpc-unknown-openbsd",
- "powerpc-wrs-vxworks",
- "powerpc-wrs-vxworks-spe",
- "riscv32gc-unknown-linux-gnu",
- "riscv32gc-unknown-linux-musl",
- "riscv32imac-unknown-none-elf",
- "thumbv7em-none-eabi",
- "thumbv7em-none-eabihf",
- "thumbv7m-none-eabi",
- "thumbv8m.base-none-eabi",
- "thumbv8m.main-none-eabi",
- "thumbv8m.main-none-eabihf",
- "mipsel-sony-psp",
- "thumbv4t-none-eabi",
- "thumbv6m-none-eabi",
-];
-#[allow(dead_code)]
-const NO_ATOMIC: &[&str] = &[
- "avr-unknown-gnu-atmega328",
- "msp430-none-elf",
- "riscv32i-unknown-none-elf",
- "riscv32imc-unknown-none-elf",
-];
diff --git a/vendor/crossbeam/src/lib.rs b/vendor/crossbeam/src/lib.rs
deleted file mode 100644
index 9bc3ec111..000000000
--- a/vendor/crossbeam/src/lib.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-//! Tools for concurrent programming.
-//!
-//! ## Atomics
-//!
-//! * [`AtomicCell`], a thread-safe mutable memory location.
-//! * [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering.
-//!
-//! ## Data structures
-//!
-//! * [`deque`], work-stealing deques for building task schedulers.
-//! * [`ArrayQueue`], a bounded MPMC queue that allocates a fixed-capacity buffer on construction.
-//! * [`SegQueue`], an unbounded MPMC queue that allocates small buffers, segments, on demand.
-//!
-//! ## Memory management
-//!
-//! * [`epoch`], an epoch-based garbage collector.
-//!
-//! ## Thread synchronization
-//!
-//! * [`channel`], multi-producer multi-consumer channels for message passing.
-//! * [`Parker`], a thread parking primitive.
-//! * [`ShardedLock`], a sharded reader-writer lock with fast concurrent reads.
-//! * [`WaitGroup`], for synchronizing the beginning or end of some computation.
-//!
-//! ## Utilities
-//!
-//! * [`Backoff`], for exponential backoff in spin loops.
-//! * [`CachePadded`], for padding and aligning a value to the length of a cache line.
-//! * [`scope`], for spawning threads that borrow local variables from the stack.
-//!
-//! [`AtomicCell`]: atomic::AtomicCell
-//! [`AtomicConsume`]: atomic::AtomicConsume
-//! [`ArrayQueue`]: queue::ArrayQueue
-//! [`SegQueue`]: queue::SegQueue
-//! [`Parker`]: sync::Parker
-//! [`ShardedLock`]: sync::ShardedLock
-//! [`WaitGroup`]: sync::WaitGroup
-//! [`Backoff`]: utils::Backoff
-//! [`CachePadded`]: utils::CachePadded
-
-#![doc(test(
- no_crate_inject,
- attr(
- deny(warnings, rust_2018_idioms),
- allow(dead_code, unused_assignments, unused_variables)
- )
-))]
-#![warn(
- missing_docs,
- missing_debug_implementations,
- rust_2018_idioms,
- unreachable_pub
-)]
-#![cfg_attr(not(feature = "std"), no_std)]
-
-pub use crossbeam_utils::atomic;
-
-pub mod utils {
- //! Miscellaneous utilities.
- //!
- //! * [`Backoff`], for exponential backoff in spin loops.
- //! * [`CachePadded`], for padding and aligning a value to the length of a cache line.
-
- pub use crossbeam_utils::Backoff;
- pub use crossbeam_utils::CachePadded;
-}
-
-use cfg_if::cfg_if;
-
-cfg_if! {
- if #[cfg(feature = "alloc")] {
- #[doc(inline)]
- pub use crossbeam_epoch as epoch;
-
- #[doc(inline)]
- pub use crossbeam_queue as queue;
- }
-}
-
-cfg_if! {
- if #[cfg(feature = "std")] {
- #[doc(inline)]
- pub use crossbeam_deque as deque;
-
- #[doc(inline)]
- pub use crossbeam_channel as channel;
- pub use crossbeam_channel::select;
-
- pub use crossbeam_utils::sync;
-
- #[cfg(not(crossbeam_loom))]
- pub use crossbeam_utils::thread;
- #[cfg(not(crossbeam_loom))]
- pub use crossbeam_utils::thread::scope;
- }
-}
diff --git a/vendor/crossbeam/tests/subcrates.rs b/vendor/crossbeam/tests/subcrates.rs
deleted file mode 100644
index 21b99fb0e..000000000
--- a/vendor/crossbeam/tests/subcrates.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-//! Makes sure subcrates are properly re-exported.
-
-use crossbeam::select;
-
-#[test]
-fn channel() {
- let (s, r) = crossbeam::channel::bounded(1);
-
- select! {
- send(s, 0) -> res => res.unwrap(),
- recv(r) -> res => assert!(res.is_ok()),
- }
-}
-
-#[test]
-fn deque() {
- let w = crossbeam::deque::Worker::new_fifo();
- w.push(1);
- let _ = w.pop();
-}
-
-#[test]
-fn epoch() {
- crossbeam::epoch::pin();
-}
-
-#[test]
-fn queue() {
- let a = crossbeam::queue::ArrayQueue::new(10);
- let _ = a.push(1);
- let _ = a.pop();
-}
-
-#[test]
-fn utils() {
- crossbeam::utils::CachePadded::new(7);
-
- crossbeam::scope(|scope| {
- scope.spawn(|_| ());
- })
- .unwrap();
-
- crossbeam::thread::scope(|scope| {
- scope.spawn(|_| ());
- })
- .unwrap();
-}
diff --git a/vendor/digest-0.8.1/.cargo-checksum.json b/vendor/digest-0.8.1/.cargo-checksum.json
deleted file mode 100644
index ed59510b2..000000000
--- a/vendor/digest-0.8.1/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"bfdc024e55a5d9f2f415045e9083abb13159e0276c3eb3dbdca290c69f8b4824","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"5890305be2cd3d221d1c2ce295b911cc57017dc341966ba434def4a072f8bf1c","src/digest.rs":"73f564cb8084e61baf850948443bacdea81727dfbff5abeb520c0e5bb690da7a","src/dyn_digest.rs":"abfa9a30ed2dc71ad2042501961146c87fe3cbf9254b5b203fe24920d0e246b8","src/errors.rs":"2584007e98d691160313cc27e6237db9bd886e9774137b59a1289a20054e9375","src/lib.rs":"71d838697e87561de4b6b2fda94df44639a525d4469316d4ad21f0f0075a130d"},"package":"f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"} \ No newline at end of file
diff --git a/vendor/digest-0.8.1/Cargo.toml b/vendor/digest-0.8.1/Cargo.toml
deleted file mode 100644
index d36300769..000000000
--- a/vendor/digest-0.8.1/Cargo.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "digest"
-version = "0.8.1"
-authors = ["RustCrypto Developers"]
-description = "Traits for cryptographic hash functions"
-documentation = "https://docs.rs/digest"
-keywords = ["digest", "crypto", "hash"]
-categories = ["cryptography", "no-std"]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/RustCrypto/traits"
-[package.metadata.docs.rs]
-features = ["std"]
-[dependencies.blobby]
-version = "0.1"
-optional = true
-
-[dependencies.generic-array]
-version = "0.12"
-
-[features]
-dev = ["blobby"]
-std = []
-[badges.travis-ci]
-repository = "RustCrypto/traits"
diff --git a/vendor/digest-0.8.1/LICENSE-APACHE b/vendor/digest-0.8.1/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/digest-0.8.1/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/digest-0.8.1/LICENSE-MIT b/vendor/digest-0.8.1/LICENSE-MIT
deleted file mode 100644
index 8dcb85b30..000000000
--- a/vendor/digest-0.8.1/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2017 Artyom Pavlov
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/digest-0.8.1/src/dev.rs b/vendor/digest-0.8.1/src/dev.rs
deleted file mode 100644
index e9950ee79..000000000
--- a/vendor/digest-0.8.1/src/dev.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-use super::{Input, VariableOutput, ExtendableOutput, Reset, XofReader};
-use core::fmt::Debug;
-
-#[macro_export]
-macro_rules! new_test {
- ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => {
- #[test]
- fn $name() {
- use digest::blobby::Blob2Iterator;
- let data = include_bytes!(concat!("data/", $test_name, ".blb"));
-
- for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() {
- let input = row[0];
- let output = row[1];
- if let Some(desc) = $test_func::<$hasher>(input, output) {
- panic!("\n\
- Failed test â„–{}: {}\n\
- input:\t{:?}\n\
- output:\t{:?}\n",
- i, desc, input, output,
- );
- }
- }
- }
- }
-}
-
-// module to separate Digest from other traits
-mod foo {
- use super::super::Digest;
- use core::fmt::Debug;
-
- pub fn digest_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
- where D: Digest + Debug + Clone
- {
- let mut hasher = D::new();
- // Test that it works when accepting the message all at once
- hasher.input(input);
- let mut hasher2 = hasher.clone();
- if hasher.result().as_slice() != output {
- return Some("whole message");
- }
-
- // Test if reset works correctly
- hasher2.reset();
- hasher2.input(input);
- if hasher2.result().as_slice() != output {
- return Some("whole message after reset");
- }
-
- // Test that it works when accepting the message in pieces
- let mut hasher = D::new();
- let len = input.len();
- let mut left = len;
- while left > 0 {
- let take = (left + 1) / 2;
- hasher.input(&input[len - left..take + len - left]);
- left = left - take;
- }
- if hasher.result().as_slice() != output {
- return Some("message in pieces");
- }
-
- // Test processing byte-by-byte
- let mut hasher = D::new();
- for chunk in input.chunks(1) {
- hasher.input(chunk)
- }
- if hasher.result().as_slice() != output {
- return Some("message byte-by-byte");
- }
- None
- }
-
-
- pub fn one_million_a<D>(expected: &[u8])
- where D: Digest + Debug + Clone
- {
- let mut sh = D::new();
- for _ in 0..50_000 {
- sh.input(&[b'a'; 10]);
- }
- sh.input(&[b'a'; 500_000][..]);
- let out = sh.result();
- assert_eq!(out[..], expected[..]);
- }
-}
-
-pub use self::foo::{digest_test, one_million_a};
-
-pub fn xof_test<D>(input: &[u8], output: &[u8])
- -> Option<&'static str>
- where D: Input + ExtendableOutput + Default + Debug + Reset + Clone
-{
- let mut hasher = D::default();
- let mut buf = [0u8; 1024];
- // Test that it works when accepting the message all at once
- hasher.input(input);
-
- let mut hasher2 = hasher.clone();
- {
- let out = &mut buf[..output.len()];
- hasher.xof_result().read(out);
-
- if out != output { return Some("whole message"); }
- }
-
- // Test if hasher resets correctly
- hasher2.reset();
- hasher2.input(input);
-
- {
- let out = &mut buf[..output.len()];
- hasher2.xof_result().read(out);
-
- if out != output { return Some("whole message after reset"); }
- }
-
- // Test if hasher accepts message in pieces correctly
- let mut hasher = D::default();
- let len = input.len();
- let mut left = len;
- while left > 0 {
- let take = (left + 1) / 2;
- hasher.input(&input[len - left..take + len - left]);
- left = left - take;
- }
-
- {
- let out = &mut buf[..output.len()];
- hasher.xof_result().read(out);
- if out != output { return Some("message in pieces"); }
- }
-
- // Test reading from reader byte by byte
- let mut hasher = D::default();
- hasher.input(input);
-
- let mut reader = hasher.xof_result();
- let out = &mut buf[..output.len()];
- for chunk in out.chunks_mut(1) {
- reader.read(chunk);
- }
-
- if out != output { return Some("message in pieces"); }
- None
-}
-
-pub fn variable_test<D>(input: &[u8], output: &[u8])
- -> Option<&'static str>
- where D: Input + VariableOutput + Reset + Debug + Clone
-{
- let mut hasher = D::new(output.len()).unwrap();
- let mut buf = [0u8; 128];
- let buf = &mut buf[..output.len()];
- // Test that it works when accepting the message all at once
- hasher.input(input);
- let mut hasher2 = hasher.clone();
- hasher.variable_result(|res| buf.copy_from_slice(res));
- if buf != output { return Some("whole message"); }
-
- // Test if reset works correctly
- hasher2.reset();
- hasher2.input(input);
- hasher2.variable_result(|res| buf.copy_from_slice(res));
- if buf != output { return Some("whole message after reset"); }
-
- // Test that it works when accepting the message in pieces
- let mut hasher = D::new(output.len()).unwrap();
- let len = input.len();
- let mut left = len;
- while left > 0 {
- let take = (left + 1) / 2;
- hasher.input(&input[len - left..take + len - left]);
- left = left - take;
- }
- hasher.variable_result(|res| buf.copy_from_slice(res));
- if buf != output { return Some("message in pieces"); }
-
- // Test processing byte-by-byte
- let mut hasher = D::new(output.len()).unwrap();
- for chunk in input.chunks(1) {
- hasher.input(chunk)
- }
- hasher.variable_result(|res| buf.copy_from_slice(res));
- if buf != output { return Some("message byte-by-byte"); }
- None
-}
-
-
-#[macro_export]
-macro_rules! bench {
- ($name:ident, $engine:path, $bs:expr) => {
- #[bench]
- fn $name(b: &mut Bencher) {
- let mut d = <$engine>::default();
- let data = [0; $bs];
-
- b.iter(|| {
- d.input(&data[..]);
- });
-
- b.bytes = $bs;
- }
- };
-
- ($engine:path) => {
- extern crate test;
-
- use test::Bencher;
- use digest::Digest;
-
- bench!(bench1_10, $engine, 10);
- bench!(bench2_100, $engine, 100);
- bench!(bench3_1000, $engine, 1000);
- bench!(bench4_10000, $engine, 10000);
- }
-}
diff --git a/vendor/digest-0.8.1/src/digest.rs b/vendor/digest-0.8.1/src/digest.rs
deleted file mode 100644
index 50128e13e..000000000
--- a/vendor/digest-0.8.1/src/digest.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-use super::{Input, FixedOutput, Reset};
-use generic_array::{GenericArray, ArrayLength};
-use generic_array::typenum::Unsigned;
-
-/// The `Digest` trait specifies an interface common for digest functions.
-///
-/// It's a convenience wrapper around `Input`, `FixedOutput`, `Reset`, `Clone`,
-/// and `Default` traits. It also provides additional convenience methods.
-pub trait Digest {
- type OutputSize: ArrayLength<u8>;
- /// Create new hasher instance
- fn new() -> Self;
-
- /// Digest input data.
- ///
- /// This method can be called repeatedly for use with streaming messages.
- fn input<B: AsRef<[u8]>>(&mut self, data: B);
-
- /// Digest input data in a chained manner.
- fn chain<B: AsRef<[u8]>>(self, data: B) -> Self where Self: Sized;
-
- /// Retrieve result and consume hasher instance.
- fn result(self) -> GenericArray<u8, Self::OutputSize>;
-
- /// Retrieve result and reset hasher instance.
- ///
- /// This method sometimes can be more efficient compared to hasher
- /// re-creation.
- fn result_reset(&mut self) -> GenericArray<u8, Self::OutputSize>;
-
- /// Reset hasher instance to its initial state.
- fn reset(&mut self);
-
- /// Get output size of the hasher
- fn output_size() -> usize;
-
- /// Convenience function to compute hash of the `data`. It will handle
- /// hasher creation, data feeding and finalization.
- ///
- /// Example:
- ///
- /// ```rust,ignore
- /// println!("{:x}", sha2::Sha256::digest(b"Hello world"));
- /// ```
- fn digest(data: &[u8]) -> GenericArray<u8, Self::OutputSize>;
-}
-
-impl<D: Input + FixedOutput + Reset + Clone + Default> Digest for D {
- type OutputSize = <Self as FixedOutput>::OutputSize;
-
- fn new() -> Self {
- Self::default()
- }
-
- fn input<B: AsRef<[u8]>>(&mut self, data: B) {
- Input::input(self, data);
- }
-
- fn chain<B: AsRef<[u8]>>(self, data: B) -> Self where Self: Sized {
- Input::chain(self, data)
- }
-
- fn result(self) -> GenericArray<u8, Self::OutputSize> {
- self.fixed_result()
- }
-
- fn result_reset(&mut self) -> GenericArray<u8, Self::OutputSize> {
- let res = self.clone().fixed_result();
- self.reset();
- res
- }
-
- fn reset(&mut self) {
- <Self as Reset>::reset(self)
- }
-
- fn output_size() -> usize {
- Self::OutputSize::to_usize()
- }
-
- fn digest(data: &[u8]) -> GenericArray<u8, Self::OutputSize> {
- let mut hasher = Self::default();
- Input::input(&mut hasher, data);
- hasher.fixed_result()
- }
-}
diff --git a/vendor/digest-0.8.1/src/dyn_digest.rs b/vendor/digest-0.8.1/src/dyn_digest.rs
deleted file mode 100644
index 2af43a8e3..000000000
--- a/vendor/digest-0.8.1/src/dyn_digest.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-#![cfg(feature = "std")]
-use std::boxed::Box;
-
-use super::{Input, FixedOutput, Reset};
-use generic_array::typenum::Unsigned;
-
-/// The `DynDigest` trait is a modification of `Digest` trait suitable
-/// for trait objects.
-pub trait DynDigest {
- /// Digest input data.
- ///
- /// This method can be called repeatedly for use with streaming messages.
- fn input(&mut self, data: &[u8]);
-
- /// Retrieve result and reset hasher instance
- fn result_reset(&mut self) -> Box<[u8]>;
-
- /// Retrieve result and consume boxed hasher instance
- fn result(self: Box<Self>) -> Box<[u8]>;
-
- /// Reset hasher instance to its initial state.
- fn reset(&mut self);
-
- /// Get output size of the hasher
- fn output_size(&self) -> usize;
-
- /// Clone hasher state into a boxed trait object
- fn box_clone(&self) -> Box<DynDigest>;
-}
-
-impl<D: Input + FixedOutput + Reset + Clone + 'static> DynDigest for D {
- fn input(&mut self, data: &[u8]) {
- Input::input(self, data);
- }
-
- fn result_reset(&mut self) -> Box<[u8]> {
- let res = self.clone().fixed_result().to_vec().into_boxed_slice();
- Reset::reset(self);
- res
- }
-
- fn result(self: Box<Self>) -> Box<[u8]> {
- self.fixed_result().to_vec().into_boxed_slice()
- }
-
- fn reset(&mut self) {
- Reset::reset(self);
- }
-
- fn output_size(&self) -> usize {
- <Self as FixedOutput>::OutputSize::to_usize()
- }
-
- fn box_clone(&self) -> Box<DynDigest> {
- Box::new(self.clone())
- }
-}
-
-impl Clone for Box<DynDigest> {
- fn clone(&self) -> Self {
- self.box_clone()
- }
-}
diff --git a/vendor/digest-0.8.1/src/errors.rs b/vendor/digest-0.8.1/src/errors.rs
deleted file mode 100644
index aa026a21a..000000000
--- a/vendor/digest-0.8.1/src/errors.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use core::fmt;
-#[cfg(feature = "std")]
-use std::error;
-
-/// The error type for variable hasher initialization
-#[derive(Clone, Copy, Debug, Default)]
-pub struct InvalidOutputSize;
-
-impl fmt::Display for InvalidOutputSize {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str("invalid output size")
- }
-}
-
-#[cfg(feature = "std")]
-impl error::Error for InvalidOutputSize {
- fn description(&self) -> &str {
- "invalid output size"
- }
-}
diff --git a/vendor/digest-0.8.1/src/lib.rs b/vendor/digest-0.8.1/src/lib.rs
deleted file mode 100644
index f03c50107..000000000
--- a/vendor/digest-0.8.1/src/lib.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-//! This crate provides traits which describe functionality of cryptographic hash
-//! functions.
-//!
-//! Traits in this repository can be separated into two levels:
-//! - Low level traits: `Input`, `BlockInput`, `Reset`, `FixedOutput`,
-//! `VariableOutput`, `ExtendableOutput`. These traits atomically describe
-//! available functionality of hash function implementations.
-//! - Convenience trait: `Digest`, `DynDigest`. They are wrappers around
-//! low level traits for most common hash-function use-cases.
-//!
-//! Additionally hash functions implement traits from `std`: `Default`, `Clone`,
-//! `Write`. (the latter depends on enabled-by-default `std` crate feature)
-//!
-//! The `Digest` trait is the most commonly used trait.
-#![no_std]
-#![doc(html_logo_url =
- "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
-pub extern crate generic_array;
-#[cfg(feature = "std")]
-#[macro_use] extern crate std;
-#[cfg(feature = "dev")]
-pub extern crate blobby;
-use generic_array::{GenericArray, ArrayLength};
-#[cfg(feature = "std")]
-use std::vec::Vec;
-
-mod digest;
-mod dyn_digest;
-mod errors;
-#[cfg(feature = "dev")]
-pub mod dev;
-
-pub use errors::InvalidOutputSize;
-pub use digest::Digest;
-#[cfg(feature = "std")]
-pub use dyn_digest::DynDigest;
-
-/// Trait for processing input data
-pub trait Input {
- /// Digest input data.
- ///
- /// This method can be called repeatedly, e.g. for processing streaming
- /// messages.
- fn input<B: AsRef<[u8]>>(&mut self, data: B);
-
- /// Digest input data in a chained manner.
- fn chain<B: AsRef<[u8]>>(mut self, data: B) -> Self where Self: Sized {
- self.input(data);
- self
- }
-}
-
-/// Trait to indicate that digest function processes data in blocks of size
-/// `BlockSize`.
-///
-/// The main usage of this trait is for implementing HMAC generically.
-pub trait BlockInput {
- type BlockSize: ArrayLength<u8>;
-}
-
-/// Trait for returning digest result with the fixed size
-pub trait FixedOutput {
- type OutputSize: ArrayLength<u8>;
-
- /// Retrieve result and consume hasher instance.
- fn fixed_result(self) -> GenericArray<u8, Self::OutputSize>;
-}
-
-/// Trait for returning digest result with the variable size
-pub trait VariableOutput: core::marker::Sized {
- /// Create new hasher instance with the given output size.
- ///
- /// It will return `Err(InvalidOutputSize)` in case if hasher can not return
- /// specified output size. It will always return an error if output size
- /// equals to zero.
- fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
-
- /// Get output size of the hasher instance provided to the `new` method
- fn output_size(&self) -> usize;
-
- /// Retrieve result via closure and consume hasher.
- ///
- /// Closure is guaranteed to be called, length of the buffer passed to it
- /// will be equal to `output_size`.
- fn variable_result<F: FnOnce(&[u8])>(self, f: F);
-
- /// Retrieve result into vector and consume hasher.
- #[cfg(feature = "std")]
- fn vec_result(self) -> Vec<u8> {
- let mut buf = Vec::with_capacity(self.output_size());
- self.variable_result(|res| buf.extend_from_slice(res));
- buf
- }
-}
-
-/// Trait for describing readers which are used to extract extendable output
-/// from XOF (extendable-output function) result.
-pub trait XofReader {
- /// Read output into the `buffer`. Can be called unlimited number of times.
- fn read(&mut self, buffer: &mut [u8]);
-}
-
-/// Trait which describes extendable-output functions (XOF).
-pub trait ExtendableOutput: core::marker::Sized {
- type Reader: XofReader;
-
- /// Retrieve XOF reader and consume hasher instance.
- fn xof_result(self) -> Self::Reader;
-
- /// Retrieve result into vector of specified length.
- #[cfg(feature = "std")]
- fn vec_result(self, n: usize) -> Vec<u8> {
- let mut buf = vec![0u8; n];
- self.xof_result().read(&mut buf);
- buf
- }
-}
-
-/// Trait for resetting hash instances
-pub trait Reset {
- /// Reset hasher instance to its initial state and return current state.
- fn reset(&mut self);
-}
-
-#[macro_export]
-/// Implements `std::io::Write` trait for implementer of `Input`
-macro_rules! impl_write {
- ($hasher:ident) => {
- #[cfg(feature = "std")]
- impl ::std::io::Write for $hasher {
- fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> {
- Input::input(self, buf);
- Ok(buf.len())
- }
-
- fn flush(&mut self) -> ::std::io::Result<()> {
- Ok(())
- }
- }
- }
-}
diff --git a/vendor/either/.cargo-checksum.json b/vendor/either/.cargo-checksum.json
index 207aba04a..5e1f8841d 100644
--- a/vendor/either/.cargo-checksum.json
+++ b/vendor/either/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"77c37f327af7a6146ba111c1c0a3e861bd444f31cfe44c3645c8e090502f66b4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README-crates.io.md":"b775991a01ab4a0a8de6169f597775319d9ce8178f5c74ccdc634f13a286b20c","README.rst":"f948f4333e9d66477128bcaf69a449a139bf00633eb57491fa1b379a3ce30b74","src/lib.rs":"e0f7c05e75af07765c2298a1791c65ea80f3c099491ed95c2e6c771041aa9931","src/serde_untagged.rs":"e826ee0ab31616e49c3e3f3711c8441001ee424b3e7a8c4c466cfcc4f8a7701a","src/serde_untagged_optional.rs":"86265f09d0795428bb2ce013b070d1badf1e2210217844a9ff3f04b2795868ab"},"package":"3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"} \ No newline at end of file
+{"files":{"Cargo.toml":"321950b99b4f04079e2470d754419bedba9851b71d1a2d8bd9c9046e38b87640","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README-crates.io.md":"b775991a01ab4a0a8de6169f597775319d9ce8178f5c74ccdc634f13a286b20c","README.rst":"1369598deaae0ff925e8910df42354d33a43606961c40e7b71a7454a7f0b775e","src/lib.rs":"bc950126c901ea5c12ce4d02a7e58e3b1e2b428caca68bd510bad1f2488e2ced","src/serde_untagged.rs":"e826ee0ab31616e49c3e3f3711c8441001ee424b3e7a8c4c466cfcc4f8a7701a","src/serde_untagged_optional.rs":"86265f09d0795428bb2ce013b070d1badf1e2210217844a9ff3f04b2795868ab"},"package":"90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"} \ No newline at end of file
diff --git a/vendor/either/Cargo.toml b/vendor/either/Cargo.toml
index d571ff8da..eb1c5b4b5 100644
--- a/vendor/either/Cargo.toml
+++ b/vendor/either/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2018"
-rust-version = "1.31"
+rust-version = "1.36"
name = "either"
-version = "1.7.0"
+version = "1.8.0"
authors = ["bluss"]
description = """
The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases.
diff --git a/vendor/either/README.rst b/vendor/either/README.rst
index 992e49c50..43c156a9f 100644
--- a/vendor/either/README.rst
+++ b/vendor/either/README.rst
@@ -25,12 +25,23 @@ __ https://docs.rs/either/
How to use with cargo::
[dependencies]
- either = "1.7"
+ either = "1.8"
Recent Changes
--------------
+- 1.8.0
+
+ - **MSRV**: ``either`` now requires Rust 1.36 or later.
+
+ - Add new methods ``.as_pin_ref()`` and ``.as_pin_mut()`` to project a
+ pinned ``Either`` as inner ``Pin`` variants, by @cuviper (#77)
+
+ - Implement the ``Future`` trait, by @cuviper (#77)
+
+ - Specialize more methods of the ``io`` traits, by @Kixunil and @cuviper (#75)
+
- 1.7.0
- **MSRV**: ``either`` now requires Rust 1.31 or later.
diff --git a/vendor/either/src/lib.rs b/vendor/either/src/lib.rs
index a4f2a5454..9a271c351 100644
--- a/vendor/either/src/lib.rs
+++ b/vendor/either/src/lib.rs
@@ -26,9 +26,11 @@ pub mod serde_untagged_optional;
use core::convert::{AsMut, AsRef};
use core::fmt;
+use core::future::Future;
use core::iter;
use core::ops::Deref;
use core::ops::DerefMut;
+use core::pin::Pin;
#[cfg(any(test, feature = "use_std"))]
use std::error::Error;
@@ -255,6 +257,35 @@ impl<L, R> Either<L, R> {
}
}
+ /// Convert `Pin<&Either<L, R>>` to `Either<Pin<&L>, Pin<&R>>`,
+ /// pinned projections of the inner variants.
+ pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&L>, Pin<&R>> {
+ // SAFETY: We can use `new_unchecked` because the `inner` parts are
+ // guaranteed to be pinned, as they come from `self` which is pinned.
+ unsafe {
+ match *Pin::get_ref(self) {
+ Left(ref inner) => Left(Pin::new_unchecked(inner)),
+ Right(ref inner) => Right(Pin::new_unchecked(inner)),
+ }
+ }
+ }
+
+ /// Convert `Pin<&mut Either<L, R>>` to `Either<Pin<&mut L>, Pin<&mut R>>`,
+ /// pinned projections of the inner variants.
+ pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut L>, Pin<&mut R>> {
+ // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
+ // We can use `new_unchecked` because the `inner` parts are guaranteed
+ // to be pinned, as they come from `self` which is pinned, and we never
+ // offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
+ // also don't have an implementation of `Drop`, nor manual `Unpin`.
+ unsafe {
+ match *Pin::get_unchecked_mut(self) {
+ Left(ref mut inner) => Left(Pin::new_unchecked(inner)),
+ Right(ref mut inner) => Right(Pin::new_unchecked(inner)),
+ }
+ }
+ }
+
/// Convert `Either<L, R>` to `Either<R, L>`.
///
/// ```
@@ -1038,6 +1069,22 @@ where
{
}
+/// `Either<L, R>` is a future if both `L` and `R` are futures.
+impl<L, R> Future for Either<L, R>
+where
+ L: Future,
+ R: Future<Output = L::Output>,
+{
+ type Output = L::Output;
+
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut core::task::Context<'_>,
+ ) -> core::task::Poll<Self::Output> {
+ for_both!(self.as_pin_mut(), inner => inner.poll(cx))
+ }
+}
+
#[cfg(any(test, feature = "use_std"))]
/// `Either<L, R>` implements `Read` if both `L` and `R` do.
///
@@ -1051,9 +1098,17 @@ where
for_both!(*self, ref mut inner => inner.read(buf))
}
+ fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.read_exact(buf))
+ }
+
fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
for_both!(*self, ref mut inner => inner.read_to_end(buf))
}
+
+ fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_to_string(buf))
+ }
}
#[cfg(any(test, feature = "use_std"))]
@@ -1084,6 +1139,14 @@ where
fn consume(&mut self, amt: usize) {
for_both!(*self, ref mut inner => inner.consume(amt))
}
+
+ fn read_until(&mut self, byte: u8, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_until(byte, buf))
+ }
+
+ fn read_line(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_line(buf))
+ }
}
#[cfg(any(test, feature = "use_std"))]
@@ -1099,6 +1162,14 @@ where
for_both!(*self, ref mut inner => inner.write(buf))
}
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.write_all(buf))
+ }
+
+ fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.write_fmt(fmt))
+ }
+
fn flush(&mut self) -> io::Result<()> {
for_both!(*self, ref mut inner => inner.flush())
}
diff --git a/vendor/fake-simd/.cargo-checksum.json b/vendor/fake-simd/.cargo-checksum.json
deleted file mode 100644
index f91a4a68f..000000000
--- a/vendor/fake-simd/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"c63db0226f9aac6e001898735c81392b8f01dfc8b7245f37e290990562c3c0d8","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"52232c2cee3bb7d8cabe47ef367f1bf8bb607c22bdfca0219d6156cb7f446e9d","src/lib.rs":"2cd66d61acfb96f3425194c12695d8e55cf56c6fbd02de90033c45bdcc338c1a"},"package":"e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"} \ No newline at end of file
diff --git a/vendor/fake-simd/Cargo.toml b/vendor/fake-simd/Cargo.toml
deleted file mode 100644
index 135c66097..000000000
--- a/vendor/fake-simd/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "fake-simd"
-version = "0.1.2"
-authors = ["The Rust-Crypto Project Developers"]
-license = "MIT/Apache-2.0"
-description = "Crate for mimicking simd crate on stable Rust"
-documentation = "https://docs.rs/fake-simd"
-repository = "https://github.com/RustCrypto/utils"
-keywords = ["simd"]
diff --git a/vendor/fake-simd/LICENSE-APACHE b/vendor/fake-simd/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/fake-simd/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/fake-simd/LICENSE-MIT b/vendor/fake-simd/LICENSE-MIT
deleted file mode 100644
index 1da3a5f6d..000000000
--- a/vendor/fake-simd/LICENSE-MIT
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2006-2009 Graydon Hoare
-Copyright (c) 2009-2013 Mozilla Foundation
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/fake-simd/src/lib.rs b/vendor/fake-simd/src/lib.rs
deleted file mode 100644
index 22c8727ed..000000000
--- a/vendor/fake-simd/src/lib.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-#![no_std]
-use core::ops::{Add, BitAnd, BitOr, BitXor, Shl, Shr, Sub};
-
-#[derive(Clone, Copy, PartialEq, Eq)]
-#[allow(non_camel_case_types)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-impl Add for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn add(self, rhs: u32x4) -> u32x4 {
- u32x4(
- self.0.wrapping_add(rhs.0),
- self.1.wrapping_add(rhs.1),
- self.2.wrapping_add(rhs.2),
- self.3.wrapping_add(rhs.3))
- }
-}
-
-impl Sub for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn sub(self, rhs: u32x4) -> u32x4 {
- u32x4(
- self.0.wrapping_sub(rhs.0),
- self.1.wrapping_sub(rhs.1),
- self.2.wrapping_sub(rhs.2),
- self.3.wrapping_sub(rhs.3))
- }
-}
-
-impl BitAnd for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn bitand(self, rhs: u32x4) -> u32x4 {
- u32x4(self.0 & rhs.0, self.1 & rhs.1, self.2 & rhs.2, self.3 & rhs.3)
- }
-}
-
-impl BitOr for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn bitor(self, rhs: u32x4) -> u32x4 {
- u32x4(self.0 | rhs.0, self.1 | rhs.1, self.2 | rhs.2, self.3 | rhs.3)
- }
-}
-
-impl BitXor for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn bitxor(self, rhs: u32x4) -> u32x4 {
- u32x4(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2, self.3 ^ rhs.3)
- }
-}
-
-impl Shl<usize> for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn shl(self, amt: usize) -> u32x4 {
- u32x4(self.0 << amt, self.1 << amt, self.2 << amt, self.3 << amt)
- }
-}
-
-impl Shl<u32x4> for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn shl(self, rhs: u32x4) -> u32x4 {
- u32x4(self.0 << rhs.0, self.1 << rhs.1, self.2 << rhs.2, self.3 << rhs.3)
- }
-}
-
-impl Shr<usize> for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn shr(self, amt: usize) -> u32x4 {
- u32x4(self.0 >> amt, self.1 >> amt, self.2 >> amt, self.3 >> amt)
- }
-}
-
-impl Shr<u32x4> for u32x4 {
- type Output = u32x4;
-
- #[inline(always)]
- fn shr(self, rhs: u32x4) -> u32x4 {
- u32x4(self.0 >> rhs.0, self.1 >> rhs.1, self.2 >> rhs.2, self.3 >> rhs.3)
- }
-}
-
-#[derive(Clone, Copy)]
-#[allow(non_camel_case_types)]
-pub struct u64x2(pub u64, pub u64);
-
-impl Add for u64x2 {
- type Output = u64x2;
-
- #[inline(always)]
- fn add(self, rhs: u64x2) -> u64x2 {
- u64x2(self.0.wrapping_add(rhs.0), self.1.wrapping_add(rhs.1))
- }
-}
diff --git a/vendor/fortanix-sgx-abi/.cargo-checksum.json b/vendor/fortanix-sgx-abi/.cargo-checksum.json
index 54731bac0..71c7c4425 100644
--- a/vendor/fortanix-sgx-abi/.cargo-checksum.json
+++ b/vendor/fortanix-sgx-abi/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"2f11a404e7361ab1b4bfd6bf5189c18091df9dcedda93dce14dcb01b59a2d85a","src/lib.rs":"2493f0264dfaaac19471aa5cb3da8011ead8f804f3ac722195478894a7d011d1"},"package":"c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"} \ No newline at end of file
+{"files":{"Cargo.toml":"5ef38d3c4329644a02d5fe6019ea401cdd64d31c1a26fd16cf30c7d2dd87873f","src/lib.rs":"2da4a01e8baae15069a6ea32610602f1741e8deccad696f7f7d3e69035da2962"},"package":"57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"} \ No newline at end of file
diff --git a/vendor/fortanix-sgx-abi/Cargo.toml b/vendor/fortanix-sgx-abi/Cargo.toml
index 1a3b9c168..28e2993bb 100644
--- a/vendor/fortanix-sgx-abi/Cargo.toml
+++ b/vendor/fortanix-sgx-abi/Cargo.toml
@@ -3,26 +3,41 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
name = "fortanix-sgx-abi"
-version = "0.3.3"
+version = "0.5.0"
authors = ["Fortanix, Inc."]
-description = "An interface for Intel SGX enclaves. This is the interface for the\n`x86_64-fortanix-unknown-sgx` target.\n\nThis is a small yet functional interface suitable for writing larger enclaves. \nIn contrast to other enclave interfaces, this interface is primarly designed \nfor running entire applications in an enclave.\n\nThis crate fully describes the type-level interface complete with \ndocumentation. For implementors, this crate contains all the type definitions\nand a macro with the function definitions.\n"
+description = """
+An interface for Intel SGX enclaves. This is the interface for the
+`x86_64-fortanix-unknown-sgx` target.
+
+This is a small yet functional interface suitable for writing larger enclaves.
+In contrast to other enclave interfaces, this interface is primarly designed
+for running entire applications in an enclave.
+
+This crate fully describes the type-level interface complete with
+documentation. For implementors, this crate contains all the type definitions
+and a macro with the function definitions.
+"""
homepage = "https://edp.fortanix.com/"
documentation = "https://edp.fortanix.com/docs/api/fortanix_sgx_abi/"
-keywords = ["sgx", "enclave"]
+keywords = [
+ "sgx",
+ "enclave",
+]
categories = ["os"]
license = "MPL-2.0"
repository = "https://github.com/fortanix/rust-sgx"
+
[package.metadata.docs.rs]
features = ["docs"]
+
[dependencies.compiler_builtins]
version = "0.1.0"
optional = true
@@ -34,4 +49,7 @@ package = "rustc-std-workspace-core"
[features]
docs = []
-rustc-dep-of-std = ["core", "compiler_builtins/rustc-dep-of-std"]
+rustc-dep-of-std = [
+ "core",
+ "compiler_builtins/rustc-dep-of-std",
+]
diff --git a/vendor/fortanix-sgx-abi/src/lib.rs b/vendor/fortanix-sgx-abi/src/lib.rs
index 362defb8f..3511ae34b 100644
--- a/vendor/fortanix-sgx-abi/src/lib.rs
+++ b/vendor/fortanix-sgx-abi/src/lib.rs
@@ -15,7 +15,7 @@
//! The Fortanix SGX ABI (compiler target `x86_64-fortanix-unknown-sgx`) is an
//! interface for Intel SGX enclaves. It is a small yet functional interface
//! suitable for writing larger enclaves. In contrast to other enclave
-//! interfaces, this interface is primarly designed for running entire
+//! interfaces, this interface is primarily designed for running entire
//! applications in an enclave.
//!
//! The Fortanix SGX ABI specification consists of two parts:
@@ -82,7 +82,7 @@
html_root_url = "https://edp.fortanix.com/docs/api/")]
use core::ptr::NonNull;
-use core::sync::atomic::AtomicUsize;
+use core::sync::atomic::{AtomicU64, AtomicUsize};
macro_rules! invoke_with_abi_spec [
( $m:ident ) => [ $m![
@@ -186,6 +186,9 @@ pub struct ByteBuffer {
pub len: usize
}
+#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+unsafe impl Send for ByteBuffer {}
+
/// Error code definitions and space allocation.
///
/// Only non-zero positive values are valid errors. The variants are designed
@@ -222,7 +225,7 @@ pub enum Error {
UserRangeEnd = 0x7fff_ffff,
}
-/// A value indicating that the operation was succesful.
+/// A value indicating that the operation was successful.
#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
pub const RESULT_SUCCESS: Result = 0;
@@ -301,7 +304,7 @@ impl Usercalls {
/// Read up to `len` bytes from stream `fd`.
///
/// `buf` must point to a buffer in userspace with a size of at least
- /// `len`. On a succesful return, the number of bytes written is returned.
+ /// `len`. On a successful return, the number of bytes written is returned.
/// The enclave must check that the returned length is no more than `len`.
/// If `len` is `0`, this call should block until the stream is ready for
/// reading. If `len` is `0` or end of stream is reached, `0` may be
@@ -330,7 +333,7 @@ impl Usercalls {
/// Write up to `len` bytes to stream `fd`.
///
/// `buf` must point to a buffer in userspace with a size of at least
- /// `len`. On a succesful return, the number of bytes written is returned.
+ /// `len`. On a successful return, the number of bytes written is returned.
/// The enclave must check that the returned length is no more than `len`.
/// If `len` is `0`, this call should block until the stream is ready for
/// writing. If `len` is `0` or the stream is closed, `0` may be returned.
@@ -453,6 +456,10 @@ pub const EV_RETURNQ_NOT_EMPTY: u64 = 0b0000_0000_0000_0010;
/// An event that enclaves can use for synchronization.
#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
pub const EV_UNPARK: u64 = 0b0000_0000_0000_0100;
+/// An event that will be triggered by userspace when the cancel queue is not
+/// or no longer full.
+#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+pub const EV_CANCELQ_NOT_FULL: u64 = 0b0000_0000_0000_1000;
#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
pub const WAIT_NO: u64 = 0;
@@ -464,9 +471,10 @@ pub const WAIT_INDEFINITE: u64 = !0;
/// ## TCS event queues
///
/// Userspace will maintain a queue for each running TCS with events to be
-/// delivered. Each event is characterized by a bitset. Userspace or the
-/// enclave (using the `send` usercall) can put events on this queue. If the
-/// enclave isn't waiting for an event when an event is queued, the event
+/// delivered. Each event is characterized by a bitset with at least one bit
+/// set. Userspace or the enclave (using the `send` usercall) can put events on
+/// this queue.
+/// If the enclave isn't waiting for an event when an event is queued, the event
/// remains on the queue until it delivered to the enclave in a later `wait`
/// usercall. If an enclave is waiting for an event, and the queue contains an
/// event that is a subset of the waited-for event mask, that event is removed
@@ -481,7 +489,7 @@ impl Usercalls {
/// this with the number of entries into [`thread_entry`]. If no free TCSes
/// are immediately available, this may return an error.
///
- /// This function will never be succesful in [libraries]. See the
+ /// This function will never be successful in [libraries]. See the
/// [`library`] documentation on how to use threads with libraries.
///
/// [`thread_entry`]: entry/executable/fn.thread_entry.html
@@ -503,14 +511,18 @@ impl Usercalls {
/// Wait for an event to occur, or check if an event is currently pending.
///
- /// `timeout` must be [`WAIT_NO`] or [`WAIT_INDEFINITE`]. If it is another
- /// value, userspace will return an error.
+ /// `timeout` must be [`WAIT_NO`] or [`WAIT_INDEFINITE`] or a positive
+ /// value smaller than u64::MAX specifying number of nanoseconds to wait.
///
/// If `timeout` is [`WAIT_INDEFINITE`], this call will block and return
/// once a matching event is queued on this TCS. If `timeout` is
/// [`WAIT_NO`], this call will return immediately, and the return value
/// will indicate if an event was pending. If it was, it has been dequeued.
- /// If not, the [`WouldBlock`] error value will be returned.
+ /// If not, the [`WouldBlock`] error value will be returned. If `timeout`
+ /// is a value other than [`WAIT_NO`] and [`WAIT_INDEFINITE`], this call
+ /// will block until either a matching event is queued in which case the
+ /// return value will indicate the event, or the timeout is reached in
+ /// which case the [`TimedOut`] error value will be returned.
///
/// A matching event is one whose bits are equal to or a subset of
/// `event_mask`. If `event_mask` is `0`, this call will never return due
@@ -534,6 +546,7 @@ impl Usercalls {
/// [`WAIT_INDEFINITE`]: constant.WAIT_INDEFINITE.html
/// [`EV_RETURNQ_NOT_EMPTY`]: constant.EV_RETURNQ_NOT_EMPTY.html
/// [`WouldBlock`]: enum.Error.html#variant.WouldBlock
+ /// [`TimedOut`]: enum.Error.html#variant.TimedOut
pub fn wait(event_mask: u64, timeout: u64) -> (Result, u64) { unimplemented!() }
/// Send an event to one or all TCSes.
@@ -568,7 +581,7 @@ impl Usercalls {
/// Request user memory.
///
/// Request an allocation in user memory of size `size` and with alignment
- /// `align`. If succesful, a pointer to this memory will be returned. The
+ /// `align`. If successful, a pointer to this memory will be returned. The
/// enclave must check the pointer is correctly aligned and that the entire
/// range of memory pointed to is outside the enclave.
///
@@ -589,7 +602,7 @@ impl Usercalls {
/// Asynchronous usercall specification.
///
/// An asynchronous usercall allows an enclave to submit a usercall without
-/// exiting the enclave. This is necessary since enclave entries and exists are
+/// exiting the enclave. This is necessary since enclave entries and exits are
/// slow (see academic work on [SCONE], [HotCalls]). In addition, the enclave
/// can perform other tasks while it waits for the usercall to complete. Those
/// tasks may include issuing other usercalls, either synchronously or
@@ -605,18 +618,40 @@ impl Usercalls {
/// concurrent usercalls with the same `id`, but it may reuse an `id` once the
/// original usercall with that `id` has returned.
///
+/// An optional third queue can be used to cancel usercalls. To cancel an async
+/// usercall, the enclave should send the usercall's id and number on this
+/// queue. If the usercall has already been processed, the enclave may still
+/// receive a successful result for the usercall. Otherwise, the userspace will
+/// cancel the usercall's execution and return an [`Interrupted`] error on the
+/// return queue to notify the enclave of the cancellation. Note that usercalls
+/// that do not return [`Result`] cannot be cancelled and if the enclave sends
+/// a cancellation for such a usercall, the userspace should simply ignore it.
+/// Additionally, userspace may choose to ignore cancellations for non-blocking
+/// usercalls. Userspace should be able to cancel a usercall that has been sent
+/// by the enclave but not yet received by the userspace, i.e. if cancellation
+/// is received before the usercall itself. To avoid keeping such cancellations
+/// forever and preventing the enclave from re-using usercall ids, userspace
+/// should synchronize cancel queue with the usercall queue such that the
+/// following invariant is maintained: whenever the enclave writes an id to the
+/// usercall or cancel queue, the enclave will not reuse that id until the
+/// usercall queue's read pointer has advanced to the write pointer at the time
+/// the id was written.
+///
/// *TODO*: Add diagram.
///
/// [MPSC queues]: struct.FifoDescriptor.html
/// [allocated per enclave]: ../struct.Usercalls.html#method.async_queues
/// [SCONE]: https://www.usenix.org/conference/osdi16/technical-sessions/presentation/arnautov
/// [HotCalls]: http://www.ofirweisse.com/ISCA17_Ofir_Weisse.pdf
+/// [`Interrupted`]: enum.Error.html#variant.Interrupted
+/// [`Result`]: type.Result.html
///
/// # Enclave/userspace synchronization
///
/// When the enclave needs to wait on a queue, it executes the [`wait()`]
/// usercall synchronously, specifying [`EV_USERCALLQ_NOT_FULL`],
-/// [`EV_RETURNQ_NOT_EMPTY`], or both in the `event_mask`. Userspace will wake
+/// [`EV_RETURNQ_NOT_EMPTY`], [`EV_CANCELQ_NOT_FULL`], or any combination
+/// thereof in the `event_mask`. Userspace will wake
/// any or all threads waiting on the appropriate event when it is triggered.
///
/// When userspace needs to wait on a queue, it will park the current thread
@@ -627,34 +662,70 @@ impl Usercalls {
/// [`wait()`]: ../struct.Usercalls.html#method.wait
/// [`EV_USERCALLQ_NOT_FULL`]: ../constant.EV_USERCALLQ_NOT_FULL.html
/// [`EV_RETURNQ_NOT_EMPTY`]: ../constant.EV_RETURNQ_NOT_EMPTY.html
+/// [`EV_CANCELQ_NOT_FULL`]: ../constant.EV_CANCELQ_NOT_FULL.html
pub mod async {
use super::*;
- use core::sync::atomic::AtomicUsize;
+ use core::sync::atomic::{AtomicU64, AtomicUsize};
- /// An identified usercall.
#[repr(C)]
- #[derive(Copy, Clone)]
#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
- pub struct Usercall {
- /// `0` indicates this slot is empty.
- pub id: u64,
- /// The elements correspond to the RDI, RSI, RDX, R8, and R9 registers
- /// in the synchronous calling convention.
- pub args: (u64, u64, u64, u64, u64)
+ pub struct WithId<T> {
+ pub id: AtomicU64,
+ pub data: T,
+ }
+
+ /// A usercall.
+ /// The elements correspond to the RDI, RSI, RDX, R8, and R9 registers
+ /// in the synchronous calling convention.
+ #[repr(C)]
+ #[derive(Copy, Clone, Default)]
+ #[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+ pub struct Usercall(pub u64, pub u64, pub u64, pub u64, pub u64);
+
+ #[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+ impl From<Usercall> for (u64, u64, u64, u64, u64) {
+ fn from(u: Usercall) -> Self {
+ let Usercall(p1, p2, p3, p4, p5) = u;
+ (p1, p2, p3, p4, p5)
+ }
+ }
+
+ #[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+ impl From<(u64, u64, u64, u64, u64)> for Usercall {
+ fn from(p: (u64, u64, u64, u64, u64)) -> Self {
+ Usercall(p.0, p.1, p.2, p.3, p.4)
+ }
}
- /// The return value of an identified usercall.
+ /// The return value of a usercall.
+ /// The elements correspond to the RSI and RDX registers in the
+ /// synchronous calling convention.
#[repr(C)]
- #[derive(Copy, Clone)]
+ #[derive(Copy, Clone, Default)]
#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
- pub struct Return {
- /// `0` indicates this slot is empty.
- pub id: u64,
- /// The elements correspond to the RSI and RDX registers in the
- /// synchronous calling convention.
- pub value: (u64, u64)
+ pub struct Return(pub u64, pub u64);
+
+ #[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+ impl From<Return> for (u64, u64) {
+ fn from(r: Return) -> Self {
+ let Return(r1, r2) = r;
+ (r1, r2)
+ }
}
+ #[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+ impl From<(u64, u64)> for Return {
+ fn from(r: (u64, u64)) -> Self {
+ Return(r.0, r.1)
+ }
+ }
+
+ /// Cancel a usercall previously sent to userspace.
+ #[repr(C)]
+ #[derive(Copy, Clone, Default)]
+ #[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
+ pub struct Cancel;
+
/// A circular buffer used as a FIFO queue with atomic reads and writes.
///
/// The read offset is the element that was most recently read by the
@@ -679,7 +750,7 @@ pub mod async {
/// 1. Load the current offsets.
/// 2. If the queue is full, wait, then go to step 1.
/// 3. Add 1 to the write offset and do an atomic compare-and-swap (CAS)
- /// with the current offsets. If the CAS was not succesful, go to step
+ /// with the current offsets. If the CAS was not successful, go to step
/// 1\.
/// 4. Write the data, then the `id`.
/// 5. If the queue was empty in step 1, signal the reader to wake up.
@@ -695,14 +766,15 @@ pub mod async {
/// 5. If `id` is `0`, go to step 4 (spin). Spinning is OK because data is
/// expected to be written imminently.
/// 6. Read the data, then store `0` in the `id`.
- /// 7. Store the new read offset.
- /// 8. If the queue was full in step 1, signal the writer to wake up.
+ /// 7. Store the new read offset, retrieving the old offsets.
+ /// 8. If the queue was full before step 7, signal the writer to wake up.
#[repr(C)]
#[cfg_attr(feature = "rustc-dep-of-std", unstable(feature = "sgx_platform", issue = "56975"))]
pub struct FifoDescriptor<T> {
/// Pointer to the queue memory. Must have a size of
- /// `len * size_of::<T>()` bytes and have alignment `align_of::<T>`.
- pub data: *mut T,
+ /// `len * size_of::<WithId<T>>()` bytes and have alignment
+ /// `align_of::<WithId<T>>`.
+ pub data: *mut WithId<T>,
/// The number of elements pointed to by `data`. Must be a power of two
/// less than or equal to 2³¹.
pub len: usize,
@@ -735,11 +807,13 @@ pub mod async {
impl Usercalls {
/// Request FIFO queues for asynchronous usercalls. `usercall_queue`
/// and `return_queue` must point to valid user memory with the correct
- /// size and alignment for their types. On return, userspace will have
- /// filled these structures with information about the queues. A single
- /// set of queues will be allocated per enclave. Once this usercall has
- /// returned succesfully, calling this usercall again is equivalent to
- /// calling `exit(true)`.
+ /// size and alignment for their types. `cancel_queue` is optional, but
+ /// if specified (not null) it must point to valid user memory with
+ /// correct size and alignment.
+ /// On return, userspace will have filled these structures with
+ /// information about the queues. A single set of queues will be
+ /// allocated per enclave. Once this usercall has returned successfully,
+ /// calling this usercall again is equivalent to calling `exit(true)`.
///
/// May fail if the platform does not support asynchronous usercalls.
///
@@ -747,7 +821,11 @@ pub mod async {
/// [`FifoDescriptor`] is outside the enclave.
///
/// [`FifoDescriptor`]: async/struct.FifoDescriptor.html
- pub fn async_queues(usercall_queue: *mut FifoDescriptor<Usercall>, return_queue: *mut FifoDescriptor<Return>) -> Result { unimplemented!() }
+ pub fn async_queues(
+ usercall_queue: *mut FifoDescriptor<Usercall>,
+ return_queue: *mut FifoDescriptor<Return>,
+ cancel_queue: *mut FifoDescriptor<Cancel>
+ ) -> Result { unimplemented!() }
}
}
diff --git a/vendor/fs-err/.cargo-checksum.json b/vendor/fs-err/.cargo-checksum.json
index 96f6899da..0cafc2bae 100644
--- a/vendor/fs-err/.cargo-checksum.json
+++ b/vendor/fs-err/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"8b53bca7b646d3afd45cde66ce850b263218904ecdd66f47e5684ef04ec873b8","Cargo.toml":"03bb23a8e71f90f8e7e5c6120f97f22b3319b2be1adb751a5f6b312fa62c9a18","LICENSE-APACHE":"7cfd738c53d61c79f07e348f622bf7707c9084237054d37fbe07788a75f5881c","LICENSE-MIT":"36516aefdc84c5d5a1e7485425913a22dbda69eb1930c5e84d6ae4972b5194b9","README.md":"e5c3355cb080a50bade0664df1f853e3f041121a9aa5bda2074ce6e01e210437","README.tpl":"de2f4fa16d473b928004aed4e11bd70522690961c6e34094a07fc68e9a092426","src/dir.rs":"1fbc8a3ada7e5e8a8c15dc0bf0e3c94cbeeea26e4a5f2b411c62d93adc023ebb","src/errors.rs":"263370df16fb2fc2c77c7b434da301792c61841960855dc11ba99523a324a2f3","src/file.rs":"dccdbd8f2b2e4e7c167df555f3a1facbf8003292c081d842711a852f2cf4b471","src/lib.rs":"f3e2041ef73f15b88594d93370b53e8f08717f7ce142184ec0c40e42d7b73c91","src/open_options.rs":"3ea24a370732eff1da0fae2205f251d3171d4e5e03f4c38508a2114942a16466","src/os.rs":"54fe6cb71a24592de1cb4e1fcebdeaba5e58b26925dbf2dc868e8dd0b0a7bef7","src/os/unix.rs":"3e2940651ce8d7b624d10bb9f3e64334812e1bb0476d12dfec130dcb1b16fe7e","src/os/windows.rs":"6dc3099f9e48a386cba9f58599796583f0cb3c8b7123168f8d1c8e27fd8763e3","src/path.rs":"949dff5847ef0983ede9e9eec1fa0f3e6d8ffd1a35004249ad04a2d2700eb85b","tests/version-numbers.rs":"370467b40ce930d655389ba82015ae2842b3361bf24280c3dc7214d3ac163a2d"},"package":"bcd1163ae48bda72a20ae26d66a04d3094135cadab911cff418ae5e33f253431"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"fb2609e5837d71e923def1765b6addc4d11b0b5040e7eb9bdbf50d59a4a5cd42","Cargo.toml":"b468e8d560ea6e30277c2ee438ac650bbb2397f5b62da911126c180921aa5d29","LICENSE-APACHE":"7cfd738c53d61c79f07e348f622bf7707c9084237054d37fbe07788a75f5881c","LICENSE-MIT":"36516aefdc84c5d5a1e7485425913a22dbda69eb1930c5e84d6ae4972b5194b9","README.md":"adbf428f33a04028cc8db98d7b75bdcf28d0edb5e792867578bcb93f1784abec","src/dir.rs":"c5255382d7357f2fbcb0b45325a343277d347f0dd0b5f0e5ff74cb808020795d","src/errors.rs":"f04771790f55627fdc39de43a1d16f7d0125bbf48d4a1c8a70921f2670dd3eaa","src/file.rs":"4516834bc52f1219f10e369bf570fd432493ceaf5d52d239d93a5e69ceaed0aa","src/lib.rs":"1a10c04bde2bc3ae30cc328afb0aa00ac98ab80c6bfff5ae94ee7e5bdbe86ec8","src/open_options.rs":"304c5be36b5a6c5ecc2c731e2956627494945d093952c879d8f3c5b15216b1d0","src/os.rs":"54fe6cb71a24592de1cb4e1fcebdeaba5e58b26925dbf2dc868e8dd0b0a7bef7","src/os/unix.rs":"21ab862305b9e1034c41bb4be31b1f3d43e3d208ca3e622211b6b54d1bbd9acc","src/os/windows.rs":"4cf0530becb6fed439f469e1f22f57de9ae2ac15e39f2a973f4734aee6267ed0","src/path.rs":"a026ae234184ed1bbadd9051099e201c3ac6309b1fd939d1b2d2b2a7cb82230d"},"package":"64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50"} \ No newline at end of file
diff --git a/vendor/fs-err/CHANGELOG.md b/vendor/fs-err/CHANGELOG.md
index bc973e22c..ee7e4be32 100644
--- a/vendor/fs-err/CHANGELOG.md
+++ b/vendor/fs-err/CHANGELOG.md
@@ -1,5 +1,22 @@
# fs-err Changelog
+## 2.8.1
+
+* Fixed docs.rs build
+
+## 2.8.0
+
+* Implement I/O safety traits (`AsFd`/`AsHandle`, `Into<OwnedFd>`/`Into<OwnedHandle>`) for file. This feature requires Rust 1.63 or later and is gated behind the `io_safety` feature flag. ([#39](https://github.com/andrewhickman/fs-err/pull/39))
+
+## 2.7.0
+
+* Implement `From<fs_err::File> for std::fs::File` ([#38](https://github.com/andrewhickman/fs-err/pull/38))
+
+## 2.6.0
+
+* Added [`File::into_parts`](https://docs.rs/fs-err/2.6.0/fs_err/struct.File.html#method.into_parts) and [`File::file_mut`](https://docs.rs/fs-err/2.6.0/fs_err/struct.File.html#method.file_mut) to provide more access to the underlying `std::fs::File`.
+* Fixed some typos in documention ([#33](https://github.com/andrewhickman/fs-err/pull/33))
+
## 2.5.0
* Added `symlink` for unix platforms
* Added `symlink_file` and `symlink_dir` for windows
@@ -11,7 +28,7 @@
- Added trait wrappers for `std::os::{unix, windows}::fs::OpenOptionsExt` and implemented them for `fs_err::OpenOptions`
* Improved compile times by converting arguments early and forwarding only a small number of types internally. There will be a slight performance hit only in the error case.
* Reduced trait bounds on generics from `AsRef<Path> + Into<PathBuf>` to either `AsRef<Path>` or `Into<PathBuf>`, making the functions more general.
-
+
## 2.4.0
* Added `canonicalize`, `hard link`, `read_link`, `rename`, `symlink_metadata` and `soft_link`. ([#25](https://github.com/andrewhickman/fs-err/pull/25))
* Added aliases to `std::path::Path` via extension trait ([#26](https://github.com/andrewhickman/fs-err/pull/26))
diff --git a/vendor/fs-err/Cargo.toml b/vendor/fs-err/Cargo.toml
index 62c4c651c..07bada50a 100644
--- a/vendor/fs-err/Cargo.toml
+++ b/vendor/fs-err/Cargo.toml
@@ -3,28 +3,53 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "fs-err"
-version = "2.5.0"
+version = "2.8.1"
authors = ["Andrew Hickman <andrew.hickman1@sky.com>"]
+exclude = [
+ ".github",
+ ".gitignore",
+ "README.tpl",
+]
description = "A drop-in replacement for std::fs with more helpful error messages."
documentation = "https://docs.rs/fs-err"
readme = "README.md"
-categories = ["command-line-interface", "filesystem"]
+categories = [
+ "command-line-interface",
+ "filesystem",
+]
license = "MIT/Apache-2.0"
repository = "https://github.com/andrewhickman/fs-err"
+[package.metadata.release]
+tag-name = "{{version}}"
+sign-tag = true
+
+[[package.metadata.release.pre-release-replacements]]
+file = "src/lib.rs"
+search = 'html_root_url = "https://docs\.rs/fs-err/.*?"'
+replace = "html_root_url = \"https://docs.rs/fs-err/{{version}}\""
+exactly = 1
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
[dependencies]
+
[dev-dependencies.serde_json]
-version = "1.0.48"
+version = "1.0.64"
-[dev-dependencies.version-sync]
-version = "0.8.1"
+[features]
+io_safety = []
diff --git a/vendor/fs-err/README.md b/vendor/fs-err/README.md
index 70bf1fa44..0dc5fc1c3 100644
--- a/vendor/fs-err/README.md
+++ b/vendor/fs-err/README.md
@@ -11,7 +11,7 @@
fs-err is a drop-in replacement for [`std::fs`][std::fs] that provides more
helpful messages on errors. Extra information includes which operations was
-attmpted and any involved paths.
+attempted and any involved paths.
## Error Messages
diff --git a/vendor/fs-err/README.tpl b/vendor/fs-err/README.tpl
deleted file mode 100644
index 35ac8052d..000000000
--- a/vendor/fs-err/README.tpl
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- This readme is created with https://github.com/livioribeiro/cargo-readme
-
- Edit `src/lib.rs` and use `cargo readme > README.md` to update it.
--->
-
-# {{crate}}
-
-[![Crates.io](https://img.shields.io/crates/v/fs-err.svg)](https://crates.io/crates/fs-err)
-[![GitHub Actions](https://github.com/andrewhickman/fs-err/workflows/CI/badge.svg)](https://github.com/andrewhickman/fs-err/actions?query=workflow%3ACI)
-
-{{readme}}
-
-## License
-
-Licensed under either of
-
-* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
-* MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
-
-at your option.
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally
-submitted for inclusion in the work by you, as defined in the Apache-2.0
-license, shall be dual licensed as above, without any additional terms or
-conditions. \ No newline at end of file
diff --git a/vendor/fs-err/src/dir.rs b/vendor/fs-err/src/dir.rs
index adba643b9..6efa58da6 100644
--- a/vendor/fs-err/src/dir.rs
+++ b/vendor/fs-err/src/dir.rs
@@ -11,7 +11,7 @@ pub fn read_dir<P: Into<PathBuf>>(path: P) -> io::Result<ReadDir> {
match fs::read_dir(&path) {
Ok(inner) => Ok(ReadDir { inner, path }),
- Err(source) => Err(Error::new(source, ErrorKind::ReadDir, path)),
+ Err(source) => Err(Error::build(source, ErrorKind::ReadDir, path)),
}
}
@@ -32,7 +32,12 @@ impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;
fn next(&mut self) -> Option<Self::Item> {
- Some(self.inner.next()?.map(|inner| DirEntry { inner }))
+ Some(
+ self.inner
+ .next()?
+ .map_err(|source| Error::build(source, ErrorKind::ReadDir, &self.path))
+ .map(|inner| DirEntry { inner }),
+ )
}
}
@@ -55,14 +60,14 @@ impl DirEntry {
pub fn metadata(&self) -> io::Result<fs::Metadata> {
self.inner
.metadata()
- .map_err(|source| Error::new(source, ErrorKind::Metadata, self.path()))
+ .map_err(|source| Error::build(source, ErrorKind::Metadata, self.path()))
}
/// Wrapper for [`DirEntry::file_type`](https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html#method.file_type).
pub fn file_type(&self) -> io::Result<fs::FileType> {
self.inner
.file_type()
- .map_err(|source| Error::new(source, ErrorKind::Metadata, self.path()))
+ .map_err(|source| Error::build(source, ErrorKind::Metadata, self.path()))
}
/// Wrapper for [`DirEntry::file_name`](https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html#method.file_name).
diff --git a/vendor/fs-err/src/errors.rs b/vendor/fs-err/src/errors.rs
index 466d28f11..43bc4ba42 100644
--- a/vendor/fs-err/src/errors.rs
+++ b/vendor/fs-err/src/errors.rs
@@ -47,12 +47,15 @@ pub(crate) struct Error {
}
impl Error {
- pub fn new(source: io::Error, kind: ErrorKind, path: impl Into<PathBuf>) -> io::Error {
- Self::_new(source, kind, path.into())
- }
-
- fn _new(source: io::Error, kind: ErrorKind, path: PathBuf) -> io::Error {
- io::Error::new(source.kind(), Self { kind, source, path })
+ pub fn build(source: io::Error, kind: ErrorKind, path: impl Into<PathBuf>) -> io::Error {
+ io::Error::new(
+ source.kind(),
+ Self {
+ kind,
+ source,
+ path: path.into(),
+ },
+ )
}
}
@@ -131,28 +134,19 @@ pub(crate) struct SourceDestError {
}
impl SourceDestError {
- pub fn new(
+ pub fn build(
source: io::Error,
kind: SourceDestErrorKind,
from_path: impl Into<PathBuf>,
to_path: impl Into<PathBuf>,
) -> io::Error {
- Self::_new(source, kind, from_path.into(), to_path.into())
- }
-
- fn _new(
- source: io::Error,
- kind: SourceDestErrorKind,
- from_path: PathBuf,
- to_path: PathBuf,
- ) -> io::Error {
io::Error::new(
source.kind(),
Self {
kind,
source,
- from_path,
- to_path,
+ from_path: from_path.into(),
+ to_path: to_path.into(),
},
)
}
diff --git a/vendor/fs-err/src/file.rs b/vendor/fs-err/src/file.rs
index a9c8988e5..fcf54fe3c 100644
--- a/vendor/fs-err/src/file.rs
+++ b/vendor/fs-err/src/file.rs
@@ -17,12 +17,12 @@ pub struct File {
// Opens a std File and returns it or an error generator which only needs the path to produce the error.
// Exists for the `crate::read*` functions so they don't unconditionally build a PathBuf.
pub(crate) fn open(path: &Path) -> Result<std::fs::File, impl FnOnce(PathBuf) -> io::Error> {
- fs::File::open(&path).map_err(|err| |path| Error::new(err, ErrorKind::OpenFile, path))
+ fs::File::open(&path).map_err(|err| |path| Error::build(err, ErrorKind::OpenFile, path))
}
// like `open()` but for `crate::write`
pub(crate) fn create(path: &Path) -> Result<std::fs::File, impl FnOnce(PathBuf) -> io::Error> {
- fs::File::create(&path).map_err(|err| |path| Error::new(err, ErrorKind::CreateFile, path))
+ fs::File::create(&path).map_err(|err| |path| Error::build(err, ErrorKind::CreateFile, path))
}
/// Wrappers for methods from [`std::fs::File`][std::fs::File].
@@ -65,7 +65,7 @@ impl File {
let path = path.into();
match options.open(&path) {
Ok(file) => Ok(File::from_parts(file, path)),
- Err(source) => Err(Error::new(source, ErrorKind::OpenFile, path)),
+ Err(source) => Err(Error::build(source, ErrorKind::OpenFile, path)),
}
}
@@ -114,7 +114,13 @@ impl File {
.set_permissions(perm)
.map_err(|source| self.error(source, ErrorKind::SetPermissions))
}
+}
+/// Methods added by fs-err that are not available on
+/// [`std::fs::File`][std::fs::File].
+///
+/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
+impl File {
/// Creates a [`File`](struct.File.html) from a raw file and its path.
pub fn from_parts<P>(file: fs::File, path: P) -> Self
where
@@ -125,13 +131,12 @@ impl File {
path: path.into(),
}
}
-}
-/// Methods added by fs-err that are not available on
-/// [`std::fs::File`][std::fs::File].
-///
-/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
-impl File {
+ /// Extract the raw file and its path from this [`File`](struct.File.html)
+ pub fn into_parts(self) -> (fs::File, PathBuf) {
+ (self.file, self.path)
+ }
+
/// Returns a reference to the underlying [`std::fs::File`][std::fs::File].
///
/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
@@ -139,6 +144,13 @@ impl File {
&self.file
}
+ /// Returns a mutable reference to the underlying [`std::fs::File`][std::fs::File].
+ ///
+ /// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html
+ pub fn file_mut(&mut self) -> &mut fs::File {
+ &mut self.file
+ }
+
/// Returns a reference to the path that this file was created with.
pub fn path(&self) -> &Path {
&self.path
@@ -146,7 +158,7 @@ impl File {
/// Wrap the error in information specific to this `File` object.
fn error(&self, source: io::Error, kind: ErrorKind) -> io::Error {
- Error::new(source, kind, &self.path)
+ Error::build(source, kind, &self.path)
}
}
@@ -178,6 +190,12 @@ impl<'a> Read for &'a File {
}
}
+impl From<File> for fs::File {
+ fn from(file: File) -> Self {
+ file.into_parts().0
+ }
+}
+
impl Seek for File {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
self.file
@@ -266,6 +284,25 @@ mod unix {
.map_err(|err| self.error(err, ErrorKind::WriteAt))
}
}
+
+ #[cfg(feature = "io_safety")]
+ mod io_safety {
+ use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "io_safety")))]
+ impl AsFd for crate::File {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ self.file().as_fd()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "io_safety")))]
+ impl From<crate::File> for OwnedFd {
+ fn from(file: crate::File) -> Self {
+ file.into_parts().0.into()
+ }
+ }
+ }
}
#[cfg(windows)]
@@ -307,4 +344,23 @@ mod windows {
self.file.into_raw_handle()
}
}
+
+ #[cfg(feature = "io_safety")]
+ mod io_safety {
+ use std::os::windows::io::{AsHandle, BorrowedHandle, OwnedHandle};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "io_safety")))]
+ impl AsHandle for crate::File {
+ fn as_handle(&self) -> BorrowedHandle<'_> {
+ self.file().as_handle()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "io_safety")))]
+ impl From<crate::File> for OwnedHandle {
+ fn from(file: crate::File) -> Self {
+ file.into_parts().0.into()
+ }
+ }
+ }
}
diff --git a/vendor/fs-err/src/lib.rs b/vendor/fs-err/src/lib.rs
index 3cc8a3b4d..777db9535 100644
--- a/vendor/fs-err/src/lib.rs
+++ b/vendor/fs-err/src/lib.rs
@@ -1,7 +1,7 @@
/*!
fs-err is a drop-in replacement for [`std::fs`][std::fs] that provides more
helpful messages on errors. Extra information includes which operations was
-attmpted and any involved paths.
+attempted and any involved paths.
# Error Messages
@@ -66,8 +66,9 @@ println!("Program config: {:?}", decoded);
[serde_json]: https://crates.io/crates/serde_json
*/
-#![doc(html_root_url = "https://docs.rs/fs-err/2.5.0")]
+#![doc(html_root_url = "https://docs.rs/fs-err/2.8.1")]
#![deny(missing_debug_implementations, missing_docs)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
mod dir;
mod errors;
@@ -90,20 +91,20 @@ pub use path::PathExt;
/// Wrapper for [`fs::read`](https://doc.rust-lang.org/stable/std/fs/fn.read.html).
pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
let path = path.as_ref();
- let mut file = file::open(path.as_ref()).map_err(|err_gen| err_gen(path.to_path_buf()))?;
+ let mut file = file::open(path).map_err(|err_gen| err_gen(path.to_path_buf()))?;
let mut bytes = Vec::with_capacity(initial_buffer_size(&file));
file.read_to_end(&mut bytes)
- .map_err(|err| Error::new(err, ErrorKind::Read, path))?;
+ .map_err(|err| Error::build(err, ErrorKind::Read, path))?;
Ok(bytes)
}
/// Wrapper for [`fs::read_to_string`](https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html).
pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
let path = path.as_ref();
- let mut file = file::open(path.as_ref()).map_err(|err_gen| err_gen(path.to_path_buf()))?;
+ let mut file = file::open(path).map_err(|err_gen| err_gen(path.to_path_buf()))?;
let mut string = String::with_capacity(initial_buffer_size(&file));
file.read_to_string(&mut string)
- .map_err(|err| Error::new(err, ErrorKind::Read, path))?;
+ .map_err(|err| Error::build(err, ErrorKind::Read, path))?;
Ok(string)
}
@@ -113,7 +114,7 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result
file::create(path)
.map_err(|err_gen| err_gen(path.to_path_buf()))?
.write_all(contents.as_ref())
- .map_err(|err| Error::new(err, ErrorKind::Write, path))
+ .map_err(|err| Error::build(err, ErrorKind::Write, path))
}
/// Wrapper for [`fs::copy`](https://doc.rust-lang.org/stable/std/fs/fn.copy.html).
@@ -125,7 +126,7 @@ where
let from = from.as_ref();
let to = to.as_ref();
fs::copy(from, to)
- .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::Copy, from, to))
+ .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::Copy, from, to))
}
/// Wrapper for [`fs::create_dir`](https://doc.rust-lang.org/stable/std/fs/fn.create_dir.html).
@@ -134,7 +135,7 @@ where
P: AsRef<Path>,
{
let path = path.as_ref();
- fs::create_dir(path).map_err(|source| Error::new(source, ErrorKind::CreateDir, path))
+ fs::create_dir(path).map_err(|source| Error::build(source, ErrorKind::CreateDir, path))
}
/// Wrapper for [`fs::create_dir_all`](https://doc.rust-lang.org/stable/std/fs/fn.create_dir_all.html).
@@ -143,7 +144,7 @@ where
P: AsRef<Path>,
{
let path = path.as_ref();
- fs::create_dir_all(path).map_err(|source| Error::new(source, ErrorKind::CreateDir, path))
+ fs::create_dir_all(path).map_err(|source| Error::build(source, ErrorKind::CreateDir, path))
}
/// Wrapper for [`fs::remove_dir`](https://doc.rust-lang.org/stable/std/fs/fn.remove_dir.html).
@@ -152,7 +153,7 @@ where
P: AsRef<Path>,
{
let path = path.as_ref();
- fs::remove_dir(path).map_err(|source| Error::new(source, ErrorKind::RemoveDir, path))
+ fs::remove_dir(path).map_err(|source| Error::build(source, ErrorKind::RemoveDir, path))
}
/// Wrapper for [`fs::remove_dir_all`](https://doc.rust-lang.org/stable/std/fs/fn.remove_dir_all.html).
@@ -161,7 +162,7 @@ where
P: AsRef<Path>,
{
let path = path.as_ref();
- fs::remove_dir_all(path).map_err(|source| Error::new(source, ErrorKind::RemoveDir, path))
+ fs::remove_dir_all(path).map_err(|source| Error::build(source, ErrorKind::RemoveDir, path))
}
/// Wrapper for [`fs::remove_file`](https://doc.rust-lang.org/stable/std/fs/fn.remove_file.html).
@@ -170,19 +171,19 @@ where
P: AsRef<Path>,
{
let path = path.as_ref();
- fs::remove_file(path).map_err(|source| Error::new(source, ErrorKind::RemoveFile, path))
+ fs::remove_file(path).map_err(|source| Error::build(source, ErrorKind::RemoveFile, path))
}
/// Wrapper for [`fs::metadata`](https://doc.rust-lang.org/stable/std/fs/fn.metadata.html).
pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<fs::Metadata> {
let path = path.as_ref();
- fs::metadata(path).map_err(|source| Error::new(source, ErrorKind::Metadata, path))
+ fs::metadata(path).map_err(|source| Error::build(source, ErrorKind::Metadata, path))
}
/// Wrapper for [`fs::canonicalize`](https://doc.rust-lang.org/stable/std/fs/fn.canonicalize.html).
pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
let path = path.as_ref();
- fs::canonicalize(path).map_err(|source| Error::new(source, ErrorKind::Canonicalize, path))
+ fs::canonicalize(path).map_err(|source| Error::build(source, ErrorKind::Canonicalize, path))
}
/// Wrapper for [`fs::hard_link`](https://doc.rust-lang.org/stable/std/fs/fn.hard_link.html).
@@ -190,13 +191,13 @@ pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
let src = src.as_ref();
let dst = dst.as_ref();
fs::hard_link(src, dst)
- .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::HardLink, src, dst))
+ .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::HardLink, src, dst))
}
/// Wrapper for [`fs::read_link`](https://doc.rust-lang.org/stable/std/fs/fn.read_link.html).
pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
let path = path.as_ref();
- fs::read_link(path).map_err(|source| Error::new(source, ErrorKind::ReadLink, path))
+ fs::read_link(path).map_err(|source| Error::build(source, ErrorKind::ReadLink, path))
}
/// Wrapper for [`fs::rename`](https://doc.rust-lang.org/stable/std/fs/fn.rename.html).
@@ -204,7 +205,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
let from = from.as_ref();
let to = to.as_ref();
fs::rename(from, to)
- .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::Rename, from, to))
+ .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::Rename, from, to))
}
/// Wrapper for [`fs::soft_link`](https://doc.rust-lang.org/stable/std/fs/fn.soft_link.html).
@@ -215,21 +216,21 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
let dst = dst.as_ref();
#[allow(deprecated)]
fs::soft_link(src, dst)
- .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::SoftLink, src, dst))
+ .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::SoftLink, src, dst))
}
/// Wrapper for [`fs::symlink_metadata`](https://doc.rust-lang.org/stable/std/fs/fn.symlink_metadata.html).
pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<fs::Metadata> {
let path = path.as_ref();
fs::symlink_metadata(path)
- .map_err(|source| Error::new(source, ErrorKind::SymlinkMetadata, path))
+ .map_err(|source| Error::build(source, ErrorKind::SymlinkMetadata, path))
}
/// Wrapper for [`fs::set_permissions`](https://doc.rust-lang.org/stable/std/fs/fn.set_permissions.html).
pub fn set_permissions<P: AsRef<Path>>(path: P, perm: fs::Permissions) -> io::Result<()> {
let path = path.as_ref();
fs::set_permissions(path, perm)
- .map_err(|source| Error::new(source, ErrorKind::SetPermissions, path))
+ .map_err(|source| Error::build(source, ErrorKind::SetPermissions, path))
}
fn initial_buffer_size(file: &std::fs::File) -> usize {
diff --git a/vendor/fs-err/src/open_options.rs b/vendor/fs-err/src/open_options.rs
index 2a11a3974..557fa7abe 100644
--- a/vendor/fs-err/src/open_options.rs
+++ b/vendor/fs-err/src/open_options.rs
@@ -5,6 +5,7 @@ pub struct OpenOptions(fs::OpenOptions);
impl OpenOptions {
/// Wrapper for [`std::fs::OpenOptions::new`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.new)
+ #[allow(clippy::new_without_default)]
pub fn new() -> Self {
OpenOptions(fs::OpenOptions::new())
}
diff --git a/vendor/fs-err/src/os/unix.rs b/vendor/fs-err/src/os/unix.rs
index 1c0bbc24d..ad7c488c4 100644
--- a/vendor/fs-err/src/os/unix.rs
+++ b/vendor/fs-err/src/os/unix.rs
@@ -11,7 +11,7 @@ pub mod fs {
let src = src.as_ref();
let dst = dst.as_ref();
std::os::unix::fs::symlink(src, dst)
- .map_err(|err| SourceDestError::new(err, SourceDestErrorKind::Symlink, src, dst))
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Symlink, src, dst))
}
/// Wrapper for [`std::os::unix::fs::FileExt`](https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html).
@@ -30,9 +30,9 @@ pub mod fs {
/// The std traits might be extended in the future (See issue [#49961](https://github.com/rust-lang/rust/issues/49961#issuecomment-382751777)).
/// This trait is sealed and can not be implemented by other crates.
pub trait OpenOptionsExt: crate::Sealed {
- /// Wapper for [`OpenOptionsExt::mode`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.mode)
+ /// Wrapper for [`OpenOptionsExt::mode`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.mode)
fn mode(&mut self, mode: u32) -> &mut Self;
- /// Wapper for [`OpenOptionsExt::custom_flags`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.custom_flags)
+ /// Wrapper for [`OpenOptionsExt::custom_flags`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.custom_flags)
fn custom_flags(&mut self, flags: i32) -> &mut Self;
}
}
diff --git a/vendor/fs-err/src/os/windows.rs b/vendor/fs-err/src/os/windows.rs
index 3aaa4a2b8..f55985623 100644
--- a/vendor/fs-err/src/os/windows.rs
+++ b/vendor/fs-err/src/os/windows.rs
@@ -8,7 +8,7 @@ pub mod fs {
let src = src.as_ref();
let dst = dst.as_ref();
std::os::windows::fs::symlink_dir(src, dst)
- .map_err(|err| SourceDestError::new(err, SourceDestErrorKind::SymlinkDir, src, dst))
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::SymlinkDir, src, dst))
}
/// Wrapper for [std::os::windows::fs::symlink_file](https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_file.html)
@@ -16,7 +16,7 @@ pub mod fs {
let src = src.as_ref();
let dst = dst.as_ref();
std::os::windows::fs::symlink_file(src, dst)
- .map_err(|err| SourceDestError::new(err, SourceDestErrorKind::SymlinkFile, src, dst))
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::SymlinkFile, src, dst))
}
/// Wrapper for [`std::os::windows::fs::FileExt`](https://doc.rust-lang.org/std/os/windows/fs/trait.FileExt.html).
diff --git a/vendor/fs-err/src/path.rs b/vendor/fs-err/src/path.rs
index ed6b9eaf1..28549a31c 100644
--- a/vendor/fs-err/src/path.rs
+++ b/vendor/fs-err/src/path.rs
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
///
/// This trait is sealed and can not be implemented by other crates.
//
-// Because noone else can implement it, we can add methods backwards-compatibly.
+// Because no one else can implement it, we can add methods backwards-compatibly.
pub trait PathExt: crate::Sealed {
/// Wrapper for [`crate::metadata`].
fn fs_err_metadata(&self) -> io::Result<fs::Metadata>;
diff --git a/vendor/fs-err/tests/version-numbers.rs b/vendor/fs-err/tests/version-numbers.rs
deleted file mode 100644
index 41a5ea480..000000000
--- a/vendor/fs-err/tests/version-numbers.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#[test]
-fn test_readme_deps() {
- version_sync::assert_markdown_deps_updated!("README.md");
-}
-
-#[test]
-fn test_html_root_url() {
- version_sync::assert_html_root_url_updated!("src/lib.rs");
-}
diff --git a/vendor/generic-array-0.12.4/.cargo-checksum.json b/vendor/generic-array-0.12.4/.cargo-checksum.json
deleted file mode 100644
index cfe4f79f6..000000000
--- a/vendor/generic-array-0.12.4/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"ae7c1d7fcd6dceb6472568994016862441606c444d0670d4e9dffab20c5eeea3","Cargo.toml":"122428b66e56c3287df569deba1e7de4b7c316cee39e1f9e1c3e7d80c793e427","LICENSE":"ad4fcfaf8d5b12b97409c137a03d4a4e4b21024c65c54f976cc3b609c1bd5b0f","README.md":"9a1a45416eac57050036b13df6ec84d21d555e820726af3c782896bd9d37d94b","rustfmt.toml":"2a298b4ce1fe6e16b8f281a0035567b8eb15042ed3062729fd28224f29c2f75a","src/arr.rs":"d866a89232279e5602cfe80b7f4e0db2b8b1153532ca72f61d65ba4d792fa603","src/functional.rs":"a0b12be07c1cc85549a80ddf1cfa1c7d5cbc09c3710bb635a5f95c35537005dc","src/hex.rs":"45e780bf385f99eec5058cfae87f97042679b1e8cbc130c009d4c074052016aa","src/impl_serde.rs":"5556e952fd351ab0af27bb562b1b6382e96a20afe51a04300264842e1fb33747","src/impls.rs":"d3046213d058b43b7b7360a2fa9ab6794e44970f1bc1847649c42c8f1c4f2d75","src/iter.rs":"b8b130ddd52461c435b873b9435f771d6535ae835055a73d79c0f3105f6b367e","src/lib.rs":"99a3fe3bc49cbfb9f00554d4860b24abe02e8075404fdb88343f2ee389f09110","src/sequence.rs":"bdf4d8920205bb85dee95897940373991b232e7b0614ae52c03c5f4bc4e8dccc","tests/arr.rs":"97258231dfeefc52ec785c2019611cc1a339c3a13f744a26727a591f7e46a7a8","tests/generics.rs":"8da33daacab14d0fd685e0ca6292a2d19be23fa6c6e128921b554a7e1d6181a1","tests/hex.rs":"143d783defedd6609995862f8aac46b8c843272a8f877f83d2f7242de8814c02","tests/import_name.rs":"1235729ecbde47fc9a38b3bf35c750a53ed55e3cf967c9d2b24fd759dc9e9e0c","tests/iter.rs":"3e5e6a1354709e8bfa76e52969c61f3d21cb960027bb91745049c0dcdfa52bfd","tests/mod.rs":"75694855127075e14ddef490fffee3dea5a052bcdda2912878bd9995f3f2956d"},"package":"ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"} \ No newline at end of file
diff --git a/vendor/generic-array-0.12.4/CHANGELOG.md b/vendor/generic-array-0.12.4/CHANGELOG.md
deleted file mode 100644
index d5e50e7b1..000000000
--- a/vendor/generic-array-0.12.4/CHANGELOG.md
+++ /dev/null
@@ -1,51 +0,0 @@
-* **`0.12.4`**
- * Fix unsoundness in the `arr!` macro.
-
-* **`0.12.0`**
- * Allow trailing commas in `arr!` macro.
- * **BREAKING**: Serialize `GenericArray` using `serde` tuples, instead of variable-length sequences. This may not be compatible with old serialized data.
-
-* **`0.11.0`**
- * **BREAKING** Redesign `GenericSequence` with an emphasis on use in generic type parameters.
- * Add `MappedGenericSequence` and `FunctionalSequence`
- * Implements optimized `map`, `zip` and `fold` for `GenericArray`, `&GenericArray` and `&mut GenericArray`
- * **BREAKING** Remove `map_ref`, `zip_ref` and `map_slice`
- * `map_slice` is now equivalent to `GenericArray::from_iter(slice.iter().map(...))`
-* **`0.10.0`**
- * Add `GenericSequence`, `Lengthen`, `Shorten`, `Split` and `Concat` traits.
- * Redefine `transmute` to avert errors.
-* **`0.9.0`**
- * Rewrite construction methods to be well-defined in panic situations, correctly dropping elements.
- * `NoDrop` crate replaced by `ManuallyDrop` as it became stable in Rust core.
- * Add optimized `map`/`map_ref` and `zip`/`zip_ref` methods to `GenericArray`
-* **`0.8.0`**
- * Implement `AsRef`, `AsMut`, `Borrow`, `BorrowMut`, `Hash` for `GenericArray`
- * Update `serde` to `1.0`
- * Update `typenum`
- * Make macro `arr!` non-cloning
- * Implement `From<[T; N]>` up to `N=32`
- * Fix #45
-* **`0.7.0`**
- * Upgrade `serde` to `0.9`
- * Make `serde` with `no_std`
- * Implement `PartialOrd`/`Ord` for `GenericArray`
-* **`0.6.0`**
- * Fixed #30
- * Implement `Default` for `GenericArray`
- * Implement `LowerHex` and `UpperHex` for `GenericArray<u8, N>`
- * Use `precision` formatting field in hex representation
- * Add `as_slice`, `as_mut_slice`
- * Remove `GenericArray::new` in favor of `Default` trait
- * Add `from_slice` and `from_mut_slice`
- * `no_std` and `core` for crate.
-* **`0.5.0`**
- * Update `serde`
- * remove `no_std` feature, fixed #19
-* **`0.4.0`**
- * Re-export `typenum`
-* **`0.3.0`**
- * Implement `IntoIter` for `GenericArray`
- * Add `map` method
- * Add optional `serde` (de)serialization support feature.
-* **`< 0.3.0`**
- * Initial implementation in late 2015
diff --git a/vendor/generic-array-0.12.4/Cargo.toml b/vendor/generic-array-0.12.4/Cargo.toml
deleted file mode 100644
index f4f4f4616..000000000
--- a/vendor/generic-array-0.12.4/Cargo.toml
+++ /dev/null
@@ -1,40 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "generic-array"
-version = "0.12.4"
-authors = ["Bartłomiej Kamiński <fizyk20@gmail.com>", "Aaron Trent <novacrazy@gmail.com>"]
-description = "Generic types implementing functionality of arrays"
-documentation = "http://fizyk20.github.io/generic-array/generic_array/"
-readme = "README.md"
-keywords = ["generic", "array"]
-categories = ["data-structures", "no-std"]
-license = "MIT"
-repository = "https://github.com/fizyk20/generic-array.git"
-
-[lib]
-name = "generic_array"
-[dependencies.serde]
-version = "1.0"
-optional = true
-default-features = false
-
-[dependencies.typenum]
-version = "1.10"
-[dev-dependencies.bincode]
-version = "1.0"
-
-[dev-dependencies.serde_json]
-version = "1.0"
-[badges.travis-ci]
-repository = "fizyk20/generic-array"
diff --git a/vendor/generic-array-0.12.4/LICENSE b/vendor/generic-array-0.12.4/LICENSE
deleted file mode 100644
index 5968bcccc..000000000
--- a/vendor/generic-array-0.12.4/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Bartłomiej Kamiński
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE. \ No newline at end of file
diff --git a/vendor/generic-array-0.12.4/README.md b/vendor/generic-array-0.12.4/README.md
deleted file mode 100644
index 0864ed627..000000000
--- a/vendor/generic-array-0.12.4/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)](https://crates.io/crates/generic-array)
-[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)](https://travis-ci.org/fizyk20/generic-array)
-# generic-array
-
-This crate implements generic array types for Rust.
-
-[Documentation](http://fizyk20.github.io/generic-array/generic_array/)
-
-## Usage
-
-The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work:
-
-```rust
-struct Foo<N> {
- data: [i32; N]
-}
-```
-
-**generic-array** defines a new trait `ArrayLength<T>` and a struct `GenericArray<T, N: ArrayLength<T>>`, which let the above be implemented as:
-
-```rust
-struct Foo<N: ArrayLength<i32>> {
- data: GenericArray<i32, N>
-}
-```
-
-To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray<T, U5>` would work almost like `[T; 5]` :)
-
-In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below:
-
-```rust
-let array = arr![u32; 1, 2, 3];
-assert_eq!(array[2], 3);
-```
diff --git a/vendor/generic-array-0.12.4/rustfmt.toml b/vendor/generic-array-0.12.4/rustfmt.toml
deleted file mode 100644
index 3dc0db27b..000000000
--- a/vendor/generic-array-0.12.4/rustfmt.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-reorder_imports = true
-reorder_imported_names = true
-use_try_shorthand = true
diff --git a/vendor/generic-array-0.12.4/src/arr.rs b/vendor/generic-array-0.12.4/src/arr.rs
deleted file mode 100644
index ebe687500..000000000
--- a/vendor/generic-array-0.12.4/src/arr.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-//! Implementation for `arr!` macro.
-
-use super::ArrayLength;
-use core::ops::Add;
-use typenum::U1;
-
-/// Helper trait for `arr!` macro
-pub trait AddLength<T, N: ArrayLength<T>>: ArrayLength<T> {
- /// Resulting length
- type Output: ArrayLength<T>;
-}
-
-impl<T, N1, N2> AddLength<T, N2> for N1
-where
- N1: ArrayLength<T> + Add<N2>,
- N2: ArrayLength<T>,
- <N1 as Add<N2>>::Output: ArrayLength<T>,
-{
- type Output = <N1 as Add<N2>>::Output;
-}
-
-/// Helper type for `arr!` macro
-pub type Inc<T, U> = <U as AddLength<T, U1>>::Output;
-
-#[doc(hidden)]
-#[macro_export]
-macro_rules! arr_impl {
- (@replace_expr $e:expr)=>{
- 1
- };
- ($T:ty; $N:ty, [$($x:expr),*], []) => ({
- const __ARR_LENGTH:usize=0 $(+ $crate::arr_impl!(@replace_expr $x) )*;
- fn __do_transmute<'a, T, N: $crate::ArrayLength<T>>(arr: [T; __ARR_LENGTH]) -> $crate::GenericArray<T, N> {
- unsafe { $crate::transmute(arr) }
- }
-
- let _:[();<$N as $crate::typenum::Unsigned>::USIZE]=[();__ARR_LENGTH];
-
- __do_transmute::<$T,$N>([$($x),*])
- });
- ($T:ty; $N:ty, [], [$x1:expr]) => (
- $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1], [])
- );
- ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => (
- $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1], [$($x),+])
- );
- ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => (
- $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1], [])
- );
- ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => (
- $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1], [$($x),+])
- );
-}
-
-/// Macro allowing for easy generation of Generic Arrays.
-/// Example: `let test = arr![u32; 1, 2, 3];`
-#[macro_export]
-macro_rules! arr {
- ($T:ty; $(,)*) => ({
- unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) }
- });
- ($T:ty; $($x:expr),* $(,)*) => (
- arr_impl!($T; $crate::typenum::U0, [], [$($x),*])
- );
- ($($x:expr,)+) => (arr![$($x),*]);
- () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`")
-}
-
-
-mod doctests_only{
- ///
- /// # With ellision
- ///
- /// Testing that lifetimes aren't transmuted when they're ellided.
- ///
- /// ```compile_fail
- /// #[macro_use] extern crate generic_array;
- /// fn main() {
- /// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
- /// arr![&A; a][0]
- /// }
- /// }
- /// ```
- ///
- /// ```rust
- /// #[macro_use] extern crate generic_array;
- /// fn main() {
- /// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'a A {
- /// arr![&A; a][0]
- /// }
- /// }
- /// ```
- ///
- /// # Without ellision
- ///
- /// Testing that lifetimes aren't transmuted when they're specified explicitly.
- ///
- /// ```compile_fail
- /// #[macro_use] extern crate generic_array;
- /// fn main() {
- /// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
- /// arr![&'a A; a][0]
- /// }
- /// }
- /// ```
- ///
- /// ```compile_fail
- /// #[macro_use] extern crate generic_array;
- /// fn main() {
- /// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
- /// arr![&'static A; a][0]
- /// }
- /// }
- /// ```
- ///
- /// ```rust
- /// #[macro_use] extern crate generic_array;
- /// fn main() {
- /// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'a A {
- /// arr![&'a A; a][0]
- /// }
- /// }
- /// ```
- #[allow(dead_code)]
- pub enum DocTests{}
-}
diff --git a/vendor/generic-array-0.12.4/src/functional.rs b/vendor/generic-array-0.12.4/src/functional.rs
deleted file mode 100644
index 50f4a71b8..000000000
--- a/vendor/generic-array-0.12.4/src/functional.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-//! Functional programming with generic sequences
-//!
-//! Please see `tests/generics.rs` for examples of how to best use these in your generic functions.
-
-use super::ArrayLength;
-use core::iter::FromIterator;
-use sequence::*;
-
-/// Defines the relationship between one generic sequence and another,
-/// for operations such as `map` and `zip`.
-pub unsafe trait MappedGenericSequence<T, U>: GenericSequence<T>
-where
- Self::Length: ArrayLength<U>,
-{
- /// Mapped sequence type
- type Mapped: GenericSequence<U, Length = Self::Length>;
-}
-
-unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a S
-where
- &'a S: GenericSequence<T>,
- S: GenericSequence<T, Length = <&'a S as GenericSequence<T>>::Length>,
- <S as GenericSequence<T>>::Length: ArrayLength<U>,
-{
- type Mapped = <S as MappedGenericSequence<T, U>>::Mapped;
-}
-
-unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a mut S
-where
- &'a mut S: GenericSequence<T>,
- S: GenericSequence<T, Length = <&'a mut S as GenericSequence<T>>::Length>,
- <S as GenericSequence<T>>::Length: ArrayLength<U>,
-{
- type Mapped = <S as MappedGenericSequence<T, U>>::Mapped;
-}
-
-/// Accessor type for a mapped generic sequence
-pub type MappedSequence<S, T, U> =
- <<S as MappedGenericSequence<T, U>>::Mapped as GenericSequence<U>>::Sequence;
-
-/// Defines functional programming methods for generic sequences
-pub unsafe trait FunctionalSequence<T>: GenericSequence<T> {
- /// Maps a `GenericSequence` to another `GenericSequence`.
- ///
- /// If the mapping function panics, any already initialized elements in the new sequence
- /// will be dropped, AND any unused elements in the source sequence will also be dropped.
- fn map<U, F>(self, f: F) -> MappedSequence<Self, T, U>
- where
- Self: MappedGenericSequence<T, U>,
- Self::Length: ArrayLength<U>,
- F: FnMut(Self::Item) -> U,
- {
- FromIterator::from_iter(self.into_iter().map(f))
- }
-
- /// Combines two `GenericSequence` instances and iterates through both of them,
- /// initializing a new `GenericSequence` with the result of the zipped mapping function.
- ///
- /// If the mapping function panics, any already initialized elements in the new sequence
- /// will be dropped, AND any unused elements in the source sequences will also be dropped.
- #[inline]
- fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
- where
- Self: MappedGenericSequence<T, U>,
- Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
- Self::Length: ArrayLength<B> + ArrayLength<U>,
- Rhs: GenericSequence<B, Length = Self::Length>,
- F: FnMut(Self::Item, Rhs::Item) -> U,
- {
- rhs.inverted_zip2(self, f)
- }
-
- /// Folds (or reduces) a sequence of data into a single value.
- ///
- /// If the fold function panics, any unused elements will be dropped.
- fn fold<U, F>(self, init: U, f: F) -> U
- where
- F: FnMut(U, Self::Item) -> U,
- {
- self.into_iter().fold(init, f)
- }
-}
-
-unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a S
-where
- &'a S: GenericSequence<T>,
-{
-}
-
-unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a mut S
-where
- &'a mut S: GenericSequence<T>,
-{
-}
diff --git a/vendor/generic-array-0.12.4/src/hex.rs b/vendor/generic-array-0.12.4/src/hex.rs
deleted file mode 100644
index 3ef92b1b9..000000000
--- a/vendor/generic-array-0.12.4/src/hex.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//! Generic array are commonly used as a return value for hash digests, so
-//! it's a good idea to allow to hexlify them easily. This module implements
-//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
-//!
-//! Example:
-//!
-//! ```rust
-//! # #[macro_use]
-//! # extern crate generic_array;
-//! # extern crate typenum;
-//! # fn main() {
-//! let array = arr![u8; 10, 20, 30];
-//! assert_eq!(format!("{:x}", array), "0a141e");
-//! # }
-//! ```
-//!
-
-use {ArrayLength, GenericArray};
-use core::cmp::min;
-use core::fmt;
-use core::ops::Add;
-use core::str;
-use typenum::*;
-
-static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
-static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
-
-impl<T: ArrayLength<u8>> fmt::LowerHex for GenericArray<u8, T>
-where
- T: Add<T>,
- <T as Add<T>>::Output: ArrayLength<u8>,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
- let max_hex = (max_digits >> 1) + (max_digits & 1);
-
- if T::to_usize() < 1024 {
- // For small arrays use a stack allocated
- // buffer of 2x number of bytes
- let mut res = GenericArray::<u8, Sum<T, T>>::default();
-
- for (i, c) in self.iter().take(max_hex).enumerate() {
- res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
- res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
- }
- f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
- } else {
- // For large array use chunks of up to 1024 bytes (2048 hex chars)
- let mut buf = [0u8; 2048];
- let mut digits_left = max_digits;
-
- for chunk in self[..max_hex].chunks(1024) {
- for (i, c) in chunk.iter().enumerate() {
- buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
- buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
- }
- let n = min(chunk.len() * 2, digits_left);
- f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
- digits_left -= n;
- }
- }
- Ok(())
- }
-}
-
-impl<T: ArrayLength<u8>> fmt::UpperHex for GenericArray<u8, T>
-where
- T: Add<T>,
- <T as Add<T>>::Output: ArrayLength<u8>,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
- let max_hex = (max_digits >> 1) + (max_digits & 1);
-
- if T::to_usize() < 1024 {
- // For small arrays use a stack allocated
- // buffer of 2x number of bytes
- let mut res = GenericArray::<u8, Sum<T, T>>::default();
-
- for (i, c) in self.iter().take(max_hex).enumerate() {
- res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
- res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
- }
- f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
- } else {
- // For large array use chunks of up to 1024 bytes (2048 hex chars)
- let mut buf = [0u8; 2048];
- let mut digits_left = max_digits;
-
- for chunk in self[..max_hex].chunks(1024) {
- for (i, c) in chunk.iter().enumerate() {
- buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
- buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
- }
- let n = min(chunk.len() * 2, digits_left);
- f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
- digits_left -= n;
- }
- }
- Ok(())
- }
-}
diff --git a/vendor/generic-array-0.12.4/src/impl_serde.rs b/vendor/generic-array-0.12.4/src/impl_serde.rs
deleted file mode 100644
index da1df2fc0..000000000
--- a/vendor/generic-array-0.12.4/src/impl_serde.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-//! Serde serialization/deserialization implementation
-
-use core::fmt;
-use core::marker::PhantomData;
-use serde::de::{self, SeqAccess, Visitor};
-use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer};
-use {ArrayLength, GenericArray};
-
-impl<T, N> Serialize for GenericArray<T, N>
-where
- T: Serialize,
- N: ArrayLength<T>,
-{
- #[inline]
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: Serializer,
- {
- let mut tup = serializer.serialize_tuple(N::to_usize())?;
- for el in self {
- tup.serialize_element(el)?;
- }
-
- tup.end()
- }
-}
-
-struct GAVisitor<T, N> {
- _t: PhantomData<T>,
- _n: PhantomData<N>,
-}
-
-impl<'de, T, N> Visitor<'de> for GAVisitor<T, N>
-where
- T: Deserialize<'de> + Default,
- N: ArrayLength<T>,
-{
- type Value = GenericArray<T, N>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct GenericArray")
- }
-
- fn visit_seq<A>(self, mut seq: A) -> Result<GenericArray<T, N>, A::Error>
- where
- A: SeqAccess<'de>,
- {
- let mut result = GenericArray::default();
- for i in 0..N::to_usize() {
- result[i] = seq
- .next_element()?
- .ok_or_else(|| de::Error::invalid_length(i, &self))?;
- }
- Ok(result)
- }
-}
-
-impl<'de, T, N> Deserialize<'de> for GenericArray<T, N>
-where
- T: Deserialize<'de> + Default,
- N: ArrayLength<T>,
-{
- fn deserialize<D>(deserializer: D) -> Result<GenericArray<T, N>, D::Error>
- where
- D: Deserializer<'de>,
- {
- let visitor = GAVisitor {
- _t: PhantomData,
- _n: PhantomData,
- };
- deserializer.deserialize_tuple(N::to_usize(), visitor)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use bincode;
- use typenum;
-
- #[test]
- fn test_serialize() {
- let array = GenericArray::<u8, typenum::U2>::default();
- let serialized = bincode::serialize(&array);
- assert!(serialized.is_ok());
- }
-
- #[test]
- fn test_deserialize() {
- let mut array = GenericArray::<u8, typenum::U2>::default();
- array[0] = 1;
- array[1] = 2;
- let serialized = bincode::serialize(&array).unwrap();
- let deserialized = bincode::deserialize::<GenericArray<u8, typenum::U2>>(&array);
- assert!(deserialized.is_ok());
- let array = deserialized.unwrap();
- assert_eq!(array[0], 1);
- assert_eq!(array[1], 2);
- }
-
- #[test]
- fn test_serialized_size() {
- let array = GenericArray::<u8, typenum::U1>::default();
- let size = bincode::serialized_size(&array).unwrap();
- assert_eq!(size, 1);
- }
-
-}
diff --git a/vendor/generic-array-0.12.4/src/impls.rs b/vendor/generic-array-0.12.4/src/impls.rs
deleted file mode 100644
index ea5a3c4c9..000000000
--- a/vendor/generic-array-0.12.4/src/impls.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-use super::{ArrayLength, GenericArray};
-use core::borrow::{Borrow, BorrowMut};
-use core::cmp::Ordering;
-use core::fmt::{self, Debug};
-use core::hash::{Hash, Hasher};
-use functional::*;
-use sequence::*;
-
-impl<T: Default, N> Default for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline]
- fn default() -> Self {
- Self::generate(|_| T::default())
- }
-}
-
-impl<T: Clone, N> Clone for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn clone(&self) -> GenericArray<T, N> {
- self.map(Clone::clone)
- }
-}
-
-impl<T: Copy, N> Copy for GenericArray<T, N>
-where
- N: ArrayLength<T>,
- N::ArrayType: Copy,
-{
-}
-
-impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn eq(&self, other: &Self) -> bool {
- **self == **other
- }
-}
-impl<T: Eq, N> Eq for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
-}
-
-impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
- PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
- }
-}
-
-impl<T: Ord, N> Ord for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
- Ord::cmp(self.as_slice(), other.as_slice())
- }
-}
-
-impl<T: Debug, N> Debug for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- self[..].fmt(fmt)
- }
-}
-
-impl<T, N> Borrow<[T]> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline(always)]
- fn borrow(&self) -> &[T] {
- &self[..]
- }
-}
-
-impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline(always)]
- fn borrow_mut(&mut self) -> &mut [T] {
- &mut self[..]
- }
-}
-
-impl<T, N> AsRef<[T]> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline(always)]
- fn as_ref(&self) -> &[T] {
- &self[..]
- }
-}
-
-impl<T, N> AsMut<[T]> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline(always)]
- fn as_mut(&mut self) -> &mut [T] {
- &mut self[..]
- }
-}
-
-impl<T: Hash, N> Hash for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn hash<H>(&self, state: &mut H)
- where
- H: Hasher,
- {
- Hash::hash(&self[..], state)
- }
-}
-
-macro_rules! impl_from {
- ($($n: expr => $ty: ty),*) => {
- $(
- impl<T> From<[T; $n]> for GenericArray<T, $ty> {
- #[inline(always)]
- fn from(arr: [T; $n]) -> Self {
- unsafe { $crate::transmute(arr) }
- }
- }
-
- impl<T> Into<[T; $n]> for GenericArray<T, $ty> {
- #[inline(always)]
- fn into(self) -> [T; $n] {
- unsafe { $crate::transmute(self) }
- }
- }
- )*
-
- }
-}
-
-impl_from! {
- 1 => ::typenum::U1,
- 2 => ::typenum::U2,
- 3 => ::typenum::U3,
- 4 => ::typenum::U4,
- 5 => ::typenum::U5,
- 6 => ::typenum::U6,
- 7 => ::typenum::U7,
- 8 => ::typenum::U8,
- 9 => ::typenum::U9,
- 10 => ::typenum::U10,
- 11 => ::typenum::U11,
- 12 => ::typenum::U12,
- 13 => ::typenum::U13,
- 14 => ::typenum::U14,
- 15 => ::typenum::U15,
- 16 => ::typenum::U16,
- 17 => ::typenum::U17,
- 18 => ::typenum::U18,
- 19 => ::typenum::U19,
- 20 => ::typenum::U20,
- 21 => ::typenum::U21,
- 22 => ::typenum::U22,
- 23 => ::typenum::U23,
- 24 => ::typenum::U24,
- 25 => ::typenum::U25,
- 26 => ::typenum::U26,
- 27 => ::typenum::U27,
- 28 => ::typenum::U28,
- 29 => ::typenum::U29,
- 30 => ::typenum::U30,
- 31 => ::typenum::U31,
- 32 => ::typenum::U32
-}
diff --git a/vendor/generic-array-0.12.4/src/iter.rs b/vendor/generic-array-0.12.4/src/iter.rs
deleted file mode 100644
index a2d67fc67..000000000
--- a/vendor/generic-array-0.12.4/src/iter.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-//! `GenericArray` iterator implementation.
-
-use super::{ArrayLength, GenericArray};
-use core::{cmp, ptr, fmt, mem};
-use core::mem::ManuallyDrop;
-
-/// An iterator that moves out of a `GenericArray`
-pub struct GenericArrayIter<T, N: ArrayLength<T>> {
- // Invariants: index <= index_back <= N
- // Only values in array[index..index_back] are alive at any given time.
- // Values from array[..index] and array[index_back..] are already moved/dropped.
- array: ManuallyDrop<GenericArray<T, N>>,
- index: usize,
- index_back: usize,
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- fn send<I: Send>(_iter: I) {}
-
- #[test]
- fn test_send_iter() {
- send(GenericArray::from([1, 2, 3, 4]).into_iter());
- }
-}
-
-impl<T, N> GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- /// Returns the remaining items of this iterator as a slice
- #[inline]
- pub fn as_slice(&self) -> &[T] {
- &self.array.as_slice()[self.index..self.index_back]
- }
-
- /// Returns the remaining items of this iterator as a mutable slice
- #[inline]
- pub fn as_mut_slice(&mut self) -> &mut [T] {
- &mut self.array.as_mut_slice()[self.index..self.index_back]
- }
-}
-
-impl<T, N> IntoIterator for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- type Item = T;
- type IntoIter = GenericArrayIter<T, N>;
-
- fn into_iter(self) -> Self::IntoIter {
- GenericArrayIter {
- array: ManuallyDrop::new(self),
- index: 0,
- index_back: N::to_usize(),
- }
- }
-}
-
-// Based on work in rust-lang/rust#49000
-impl<T: fmt::Debug, N> fmt::Debug for GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_tuple("GenericArrayIter")
- .field(&self.as_slice())
- .finish()
- }
-}
-
-impl<T, N> Drop for GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline]
- fn drop(&mut self) {
- // Drop values that are still alive.
- for p in self.as_mut_slice() {
- unsafe {
- ptr::drop_in_place(p);
- }
- }
- }
-}
-
-// Based on work in rust-lang/rust#49000
-impl<T: Clone, N> Clone for GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- fn clone(&self) -> Self {
- // This places all cloned elements at the start of the new array iterator,
- // not at their original indices.
- unsafe {
- let mut iter = GenericArrayIter {
- array: ManuallyDrop::new(mem::uninitialized()),
- index: 0,
- index_back: 0,
- };
-
- for (dst, src) in iter.array.iter_mut().zip(self.as_slice()) {
- ptr::write(dst, src.clone());
-
- iter.index_back += 1;
- }
-
- iter
- }
- }
-}
-
-impl<T, N> Iterator for GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- type Item = T;
-
- #[inline]
- fn next(&mut self) -> Option<T> {
- if self.index < self.index_back {
- let p = unsafe { Some(ptr::read(self.array.get_unchecked(self.index))) };
-
- self.index += 1;
-
- p
- } else {
- None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let len = self.len();
- (len, Some(len))
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- fn nth(&mut self, n: usize) -> Option<T> {
- // First consume values prior to the nth.
- let ndrop = cmp::min(n, self.len());
-
- for p in &mut self.array[self.index..self.index + ndrop] {
- self.index += 1;
-
- unsafe {
- ptr::drop_in_place(p);
- }
- }
-
- self.next()
- }
-
- fn last(mut self) -> Option<T> {
- // Note, everything else will correctly drop first as `self` leaves scope.
- self.next_back()
- }
-}
-
-impl<T, N> DoubleEndedIterator for GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- fn next_back(&mut self) -> Option<T> {
- if self.index < self.index_back {
- self.index_back -= 1;
-
- unsafe { Some(ptr::read(self.array.get_unchecked(self.index_back))) }
- } else {
- None
- }
- }
-}
-
-impl<T, N> ExactSizeIterator for GenericArrayIter<T, N>
-where
- N: ArrayLength<T>,
-{
- fn len(&self) -> usize {
- self.index_back - self.index
- }
-}
-
-// TODO: Implement `FusedIterator` and `TrustedLen` when stabilized \ No newline at end of file
diff --git a/vendor/generic-array-0.12.4/src/lib.rs b/vendor/generic-array-0.12.4/src/lib.rs
deleted file mode 100644
index e98e8fd58..000000000
--- a/vendor/generic-array-0.12.4/src/lib.rs
+++ /dev/null
@@ -1,632 +0,0 @@
-//! This crate implements a structure that can be used as a generic array type.use
-//! Core Rust array types `[T; N]` can't be used generically with
-//! respect to `N`, so for example this:
-//!
-//! ```{should_fail}
-//! struct Foo<T, N> {
-//! data: [T; N]
-//! }
-//! ```
-//!
-//! won't work.
-//!
-//! **generic-array** exports a `GenericArray<T,N>` type, which lets
-//! the above be implemented as:
-//!
-//! ```
-//! # use generic_array::{ArrayLength, GenericArray};
-//! struct Foo<T, N: ArrayLength<T>> {
-//! data: GenericArray<T,N>
-//! }
-//! ```
-//!
-//! The `ArrayLength<T>` trait is implemented by default for
-//! [unsigned integer types](../typenum/uint/index.html) from
-//! [typenum](../typenum/index.html).
-//!
-//! For ease of use, an `arr!` macro is provided - example below:
-//!
-//! ```
-//! # #[macro_use]
-//! # extern crate generic_array;
-//! # extern crate typenum;
-//! # fn main() {
-//! let array = arr![u32; 1, 2, 3];
-//! assert_eq!(array[2], 3);
-//! # }
-//! ```
-
-#![deny(missing_docs)]
-#![no_std]
-
-#[cfg(feature = "serde")]
-extern crate serde;
-
-#[cfg(test)]
-extern crate bincode;
-
-pub extern crate typenum;
-
-mod hex;
-mod impls;
-
-#[cfg(feature = "serde")]
-pub mod impl_serde;
-
-use core::iter::FromIterator;
-use core::marker::PhantomData;
-use core::mem::ManuallyDrop;
-use core::ops::{Deref, DerefMut};
-use core::{mem, ptr, slice};
-use typenum::bit::{B0, B1};
-use typenum::uint::{UInt, UTerm, Unsigned};
-
-#[cfg_attr(test, macro_use)]
-pub mod arr;
-pub mod functional;
-pub mod iter;
-pub mod sequence;
-
-use functional::*;
-pub use iter::GenericArrayIter;
-use sequence::*;
-
-/// Trait making `GenericArray` work, marking types to be used as length of an array
-pub unsafe trait ArrayLength<T>: Unsigned {
- /// Associated type representing the array type for the number
- type ArrayType;
-}
-
-unsafe impl<T> ArrayLength<T> for UTerm {
- #[doc(hidden)]
- type ArrayType = ();
-}
-
-/// Internal type used to generate a struct of appropriate size
-#[allow(dead_code)]
-#[repr(C)]
-#[doc(hidden)]
-pub struct GenericArrayImplEven<T, U> {
- parent1: U,
- parent2: U,
- _marker: PhantomData<T>,
-}
-
-impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
- fn clone(&self) -> GenericArrayImplEven<T, U> {
- GenericArrayImplEven {
- parent1: self.parent1.clone(),
- parent2: self.parent2.clone(),
- _marker: PhantomData,
- }
- }
-}
-
-impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
-
-/// Internal type used to generate a struct of appropriate size
-#[allow(dead_code)]
-#[repr(C)]
-#[doc(hidden)]
-pub struct GenericArrayImplOdd<T, U> {
- parent1: U,
- parent2: U,
- data: T,
-}
-
-impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
- fn clone(&self) -> GenericArrayImplOdd<T, U> {
- GenericArrayImplOdd {
- parent1: self.parent1.clone(),
- parent2: self.parent2.clone(),
- data: self.data.clone(),
- }
- }
-}
-
-impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
-
-unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
- #[doc(hidden)]
- type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
-}
-
-unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
- #[doc(hidden)]
- type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
-}
-
-/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
-#[allow(dead_code)]
-pub struct GenericArray<T, U: ArrayLength<T>> {
- data: U::ArrayType,
-}
-
-unsafe impl<T: Send, N: ArrayLength<T>> Send for GenericArray<T, N> {}
-unsafe impl<T: Sync, N: ArrayLength<T>> Sync for GenericArray<T, N> {}
-
-impl<T, N> Deref for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- type Target = [T];
-
- #[inline(always)]
- fn deref(&self) -> &[T] {
- unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) }
- }
-}
-
-impl<T, N> DerefMut for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- #[inline(always)]
- fn deref_mut(&mut self) -> &mut [T] {
- unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) }
- }
-}
-
-/// Creates an array one element at a time using a mutable iterator
-/// you can write to with `ptr::write`.
-///
-/// Incremenent the position while iterating to mark off created elements,
-/// which will be dropped if `into_inner` is not called.
-#[doc(hidden)]
-pub struct ArrayBuilder<T, N: ArrayLength<T>> {
- array: ManuallyDrop<GenericArray<T, N>>,
- position: usize,
-}
-
-impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
- #[doc(hidden)]
- #[inline]
- pub unsafe fn new() -> ArrayBuilder<T, N> {
- ArrayBuilder {
- array: ManuallyDrop::new(mem::uninitialized()),
- position: 0,
- }
- }
-
- /// Creates a mutable iterator for writing to the array using `ptr::write`.
- ///
- /// Increment the position value given as a mutable reference as you iterate
- /// to mark how many elements have been created.
- #[doc(hidden)]
- #[inline]
- pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
- (self.array.iter_mut(), &mut self.position)
- }
-
- /// When done writing (assuming all elements have been written to),
- /// get the inner array.
- #[doc(hidden)]
- #[inline]
- pub unsafe fn into_inner(self) -> GenericArray<T, N> {
- let array = ptr::read(&self.array);
-
- mem::forget(self);
-
- ManuallyDrop::into_inner(array)
- }
-}
-
-impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
- fn drop(&mut self) {
- for value in &mut self.array[..self.position] {
- unsafe {
- ptr::drop_in_place(value);
- }
- }
- }
-}
-
-/// Consumes an array.
-///
-/// Increment the position while iterating and any leftover elements
-/// will be dropped if position does not go to N
-#[doc(hidden)]
-pub struct ArrayConsumer<T, N: ArrayLength<T>> {
- array: ManuallyDrop<GenericArray<T, N>>,
- position: usize,
-}
-
-impl<T, N: ArrayLength<T>> ArrayConsumer<T, N> {
- #[doc(hidden)]
- #[inline]
- pub unsafe fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
- ArrayConsumer {
- array: ManuallyDrop::new(array),
- position: 0,
- }
- }
-
- /// Creates an iterator and mutable reference to the internal position
- /// to keep track of consumed elements.
- ///
- /// Increment the position as you iterate to mark off consumed elements
- #[doc(hidden)]
- #[inline]
- pub unsafe fn iter_position(&mut self) -> (slice::Iter<T>, &mut usize) {
- (self.array.iter(), &mut self.position)
- }
-}
-
-impl<T, N: ArrayLength<T>> Drop for ArrayConsumer<T, N> {
- fn drop(&mut self) {
- for value in &mut self.array[self.position..N::to_usize()] {
- unsafe {
- ptr::drop_in_place(value);
- }
- }
- }
-}
-
-impl<'a, T: 'a, N> IntoIterator for &'a GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- type IntoIter = slice::Iter<'a, T>;
- type Item = &'a T;
-
- fn into_iter(self: &'a GenericArray<T, N>) -> Self::IntoIter {
- self.as_slice().iter()
- }
-}
-
-impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- type IntoIter = slice::IterMut<'a, T>;
- type Item = &'a mut T;
-
- fn into_iter(self: &'a mut GenericArray<T, N>) -> Self::IntoIter {
- self.as_mut_slice().iter_mut()
- }
-}
-
-impl<T, N> FromIterator<T> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- fn from_iter<I>(iter: I) -> GenericArray<T, N>
- where
- I: IntoIterator<Item = T>,
- {
- unsafe {
- let mut destination = ArrayBuilder::new();
-
- {
- let (destination_iter, position) = destination.iter_position();
-
- for (src, dst) in iter.into_iter().zip(destination_iter) {
- ptr::write(dst, src);
-
- *position += 1;
- }
- }
-
- if destination.position < N::to_usize() {
- from_iter_length_fail(destination.position, N::to_usize());
- }
-
- destination.into_inner()
- }
- }
-}
-
-#[inline(never)]
-#[cold]
-fn from_iter_length_fail(length: usize, expected: usize) -> ! {
- panic!(
- "GenericArray::from_iter received {} elements but expected {}",
- length, expected
- );
-}
-
-unsafe impl<T, N> GenericSequence<T> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
- Self: IntoIterator<Item = T>,
-{
- type Length = N;
- type Sequence = Self;
-
- fn generate<F>(mut f: F) -> GenericArray<T, N>
- where
- F: FnMut(usize) -> T,
- {
- unsafe {
- let mut destination = ArrayBuilder::new();
-
- {
- let (destination_iter, position) = destination.iter_position();
-
- for (i, dst) in destination_iter.enumerate() {
- ptr::write(dst, f(i));
-
- *position += 1;
- }
- }
-
- destination.into_inner()
- }
- }
-
- #[doc(hidden)]
- fn inverted_zip<B, U, F>(
- self,
- lhs: GenericArray<B, Self::Length>,
- mut f: F,
- ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
- where
- GenericArray<B, Self::Length>:
- GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
- Self: MappedGenericSequence<T, U>,
- Self::Length: ArrayLength<B> + ArrayLength<U>,
- F: FnMut(B, Self::Item) -> U,
- {
- unsafe {
- let mut left = ArrayConsumer::new(lhs);
- let mut right = ArrayConsumer::new(self);
-
- let (left_array_iter, left_position) = left.iter_position();
- let (right_array_iter, right_position) = right.iter_position();
-
- FromIterator::from_iter(left_array_iter.zip(right_array_iter).map(|(l, r)| {
- let left_value = ptr::read(l);
- let right_value = ptr::read(r);
-
- *left_position += 1;
- *right_position += 1;
-
- f(left_value, right_value)
- }))
- }
- }
-
- #[doc(hidden)]
- fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
- where
- Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
- Self: MappedGenericSequence<T, U>,
- Self::Length: ArrayLength<B> + ArrayLength<U>,
- F: FnMut(Lhs::Item, Self::Item) -> U,
- {
- unsafe {
- let mut right = ArrayConsumer::new(self);
-
- let (right_array_iter, right_position) = right.iter_position();
-
- FromIterator::from_iter(
- lhs.into_iter()
- .zip(right_array_iter)
- .map(|(left_value, r)| {
- let right_value = ptr::read(r);
-
- *right_position += 1;
-
- f(left_value, right_value)
- }),
- )
- }
- }
-}
-
-unsafe impl<T, U, N> MappedGenericSequence<T, U> for GenericArray<T, N>
-where
- N: ArrayLength<T> + ArrayLength<U>,
- GenericArray<U, N>: GenericSequence<U, Length = N>,
-{
- type Mapped = GenericArray<U, N>;
-}
-
-unsafe impl<T, N> FunctionalSequence<T> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
- Self: GenericSequence<T, Item = T, Length = N>,
-{
- fn map<U, F>(self, mut f: F) -> MappedSequence<Self, T, U>
- where
- Self::Length: ArrayLength<U>,
- Self: MappedGenericSequence<T, U>,
- F: FnMut(T) -> U,
- {
- unsafe {
- let mut source = ArrayConsumer::new(self);
-
- let (array_iter, position) = source.iter_position();
-
- FromIterator::from_iter(array_iter.map(|src| {
- let value = ptr::read(src);
-
- *position += 1;
-
- f(value)
- }))
- }
- }
-
- #[inline]
- fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
- where
- Self: MappedGenericSequence<T, U>,
- Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
- Self::Length: ArrayLength<B> + ArrayLength<U>,
- Rhs: GenericSequence<B, Length = Self::Length>,
- F: FnMut(T, Rhs::Item) -> U,
- {
- rhs.inverted_zip(self, f)
- }
-
- fn fold<U, F>(self, init: U, mut f: F) -> U
- where
- F: FnMut(U, T) -> U,
- {
- unsafe {
- let mut source = ArrayConsumer::new(self);
-
- let (array_iter, position) = source.iter_position();
-
- array_iter.fold(init, |acc, src| {
- let value = ptr::read(src);
-
- *position += 1;
-
- f(acc, value)
- })
- }
- }
-}
-
-impl<T, N> GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- /// Extracts a slice containing the entire array.
- #[inline]
- pub fn as_slice(&self) -> &[T] {
- self.deref()
- }
-
- /// Extracts a mutable slice containing the entire array.
- #[inline]
- pub fn as_mut_slice(&mut self) -> &mut [T] {
- self.deref_mut()
- }
-
- /// Converts slice to a generic array reference with inferred length;
- ///
- /// Length of the slice must be equal to the length of the array.
- #[inline]
- pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
- slice.into()
- }
-
- /// Converts mutable slice to a mutable generic array reference
- ///
- /// Length of the slice must be equal to the length of the array.
- #[inline]
- pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
- slice.into()
- }
-}
-
-impl<'a, T, N: ArrayLength<T>> From<&'a [T]> for &'a GenericArray<T, N> {
- /// Converts slice to a generic array reference with inferred length;
- ///
- /// Length of the slice must be equal to the length of the array.
- #[inline]
- fn from(slice: &[T]) -> &GenericArray<T, N> {
- assert_eq!(slice.len(), N::to_usize());
-
- unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
- }
-}
-
-impl<'a, T, N: ArrayLength<T>> From<&'a mut [T]> for &'a mut GenericArray<T, N> {
- /// Converts mutable slice to a mutable generic array reference
- ///
- /// Length of the slice must be equal to the length of the array.
- #[inline]
- fn from(slice: &mut [T]) -> &mut GenericArray<T, N> {
- assert_eq!(slice.len(), N::to_usize());
-
- unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
- }
-}
-
-impl<T: Clone, N> GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- /// Construct a `GenericArray` from a slice by cloning its content
- ///
- /// Length of the slice must be equal to the length of the array
- #[inline]
- pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
- Self::from_exact_iter(list.iter().cloned())
- .expect("Slice must be the same length as the array")
- }
-}
-
-impl<T, N> GenericArray<T, N>
-where
- N: ArrayLength<T>,
-{
- /// Creates a new `GenericArray` instance from an iterator with a known exact size.
- ///
- /// Returns `None` if the size is not equal to the number of elements in the `GenericArray`.
- pub fn from_exact_iter<I>(iter: I) -> Option<Self>
- where
- I: IntoIterator<Item = T>,
- <I as IntoIterator>::IntoIter: ExactSizeIterator,
- {
- let iter = iter.into_iter();
-
- if iter.len() == N::to_usize() {
- unsafe {
- let mut destination = ArrayBuilder::new();
-
- {
- let (destination_iter, position) = destination.iter_position();
-
- for (dst, src) in destination_iter.zip(iter.into_iter()) {
- ptr::write(dst, src);
-
- *position += 1;
- }
- }
-
- Some(destination.into_inner())
- }
- } else {
- None
- }
- }
-}
-
-/// A reimplementation of the `transmute` function, avoiding problems
-/// when the compiler can't prove equal sizes.
-#[inline]
-#[doc(hidden)]
-pub unsafe fn transmute<A, B>(a: A) -> B {
- let b = ::core::ptr::read(&a as *const A as *const B);
- ::core::mem::forget(a);
- b
-}
-
-#[cfg(test)]
-mod test {
- // Compile with:
- // cargo rustc --lib --profile test --release --
- // -C target-cpu=native -C opt-level=3 --emit asm
- // and view the assembly to make sure test_assembly generates
- // SIMD instructions instead of a niave loop.
-
- #[inline(never)]
- pub fn black_box<T>(val: T) -> T {
- use core::{mem, ptr};
-
- let ret = unsafe { ptr::read_volatile(&val) };
- mem::forget(val);
- ret
- }
-
- #[test]
- fn test_assembly() {
- use functional::*;
-
- let a = black_box(arr![i32; 1, 3, 5, 7]);
- let b = black_box(arr![i32; 2, 4, 6, 8]);
-
- let c = (&a).zip(b, |l, r| l + r);
-
- let d = a.fold(0, |a, x| a + x);
-
- assert_eq!(c, arr![i32; 3, 7, 11, 15]);
-
- assert_eq!(d, 16);
- }
-}
diff --git a/vendor/generic-array-0.12.4/src/sequence.rs b/vendor/generic-array-0.12.4/src/sequence.rs
deleted file mode 100644
index 7b928abda..000000000
--- a/vendor/generic-array-0.12.4/src/sequence.rs
+++ /dev/null
@@ -1,320 +0,0 @@
-//! Useful traits for manipulating sequences of data stored in `GenericArray`s
-
-use super::*;
-use core::{mem, ptr};
-use core::ops::{Add, Sub};
-use typenum::operator_aliases::*;
-
-/// Defines some sequence with an associated length and iteration capabilities.
-///
-/// This is useful for passing N-length generic arrays as generics.
-pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
- /// `GenericArray` associated length
- type Length: ArrayLength<T>;
-
- /// Concrete sequence type used in conjuction with reference implementations of `GenericSequence`
- type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
-
- /// Initializes a new sequence instance using the given function.
- ///
- /// If the generator function panics while initializing the sequence,
- /// any already initialized elements will be dropped.
- fn generate<F>(f: F) -> Self::Sequence
- where
- F: FnMut(usize) -> T;
-
- #[doc(hidden)]
- fn inverted_zip<B, U, F>(
- self,
- lhs: GenericArray<B, Self::Length>,
- mut f: F,
- ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
- where
- GenericArray<B, Self::Length>: GenericSequence<B, Length = Self::Length>
- + MappedGenericSequence<B, U>,
- Self: MappedGenericSequence<T, U>,
- Self::Length: ArrayLength<B> + ArrayLength<U>,
- F: FnMut(B, Self::Item) -> U,
- {
- unsafe {
- let mut left = ArrayConsumer::new(lhs);
-
- let (left_array_iter, left_position) = left.iter_position();
-
- FromIterator::from_iter(
- left_array_iter
- .zip(self.into_iter())
- .map(|(l, right_value)| {
- let left_value = ptr::read(l);
-
- *left_position += 1;
-
- f(left_value, right_value)
- })
- )
- }
- }
-
- #[doc(hidden)]
- fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
- where
- Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
- Self: MappedGenericSequence<T, U>,
- Self::Length: ArrayLength<B> + ArrayLength<U>,
- F: FnMut(Lhs::Item, Self::Item) -> U,
- {
- FromIterator::from_iter(lhs.into_iter().zip(self.into_iter()).map(|(l, r)| f(l, r)))
- }
-}
-
-/// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item`
-///
-/// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`,
-/// this can be useful for keeping things organized.
-pub type SequenceItem<T> = <T as IntoIterator>::Item;
-
-unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S
-where
- &'a S: IntoIterator,
-{
- type Length = S::Length;
- type Sequence = S::Sequence;
-
- #[inline]
- fn generate<F>(f: F) -> Self::Sequence
- where
- F: FnMut(usize) -> T,
- {
- S::generate(f)
- }
-}
-
-unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S
-where
- &'a mut S: IntoIterator,
-{
- type Length = S::Length;
- type Sequence = S::Sequence;
-
- #[inline]
- fn generate<F>(f: F) -> Self::Sequence
- where
- F: FnMut(usize) -> T,
- {
- S::generate(f)
- }
-}
-
-/// Defines any `GenericSequence` which can be lengthened or extended by appending
-/// or prepending an element to it.
-///
-/// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back`
-pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
- /// `GenericSequence` that has one more element than `Self`
- type Longer: Shorten<T, Shorter = Self>;
-
- /// Returns a new array with the given element appended to the end of it.
- ///
- /// Example:
- ///
- /// ```ignore
- /// let a = arr![i32; 1, 2, 3];
- ///
- /// let b = a.append(4);
- ///
- /// assert_eq!(b, arr![i32; 1, 2, 3, 4]);
- /// ```
- fn append(self, last: T) -> Self::Longer;
-
- /// Returns a new array with the given element prepended to the front of it.
- ///
- /// Example:
- ///
- /// ```ignore
- /// let a = arr![i32; 1, 2, 3];
- ///
- /// let b = a.prepend(4);
- ///
- /// assert_eq!(b, arr![i32; 4, 1, 2, 3]);
- /// ```
- fn prepend(self, first: T) -> Self::Longer;
-}
-
-/// Defines a `GenericSequence` which can be shortened by removing the first or last element from it.
-///
-/// Additionally, any shortened sequence can be lengthened by
-/// appending or prepending an element to it.
-pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
- /// `GenericSequence` that has one less element than `Self`
- type Shorter: Lengthen<T, Longer = Self>;
-
- /// Returns a new array without the last element, and the last element.
- ///
- /// Example:
- ///
- /// ```ignore
- /// let a = arr![i32; 1, 2, 3, 4];
- ///
- /// let (init, last) = a.pop_back();
- ///
- /// assert_eq!(init, arr![i32; 1, 2, 3]);
- /// assert_eq!(last, 4);
- /// ```
- fn pop_back(self) -> (Self::Shorter, T);
-
- /// Returns a new array without the first element, and the first element.
- /// Example:
- ///
- /// ```ignore
- /// let a = arr![i32; 1, 2, 3, 4];
- ///
- /// let (head, tail) = a.pop_front();
- ///
- /// assert_eq!(head, 1);
- /// assert_eq!(tail, arr![i32; 2, 3, 4]);
- /// ```
- fn pop_front(self) -> (T, Self::Shorter);
-}
-
-unsafe impl<T, N: ArrayLength<T>> Lengthen<T> for GenericArray<T, N>
-where
- N: Add<B1>,
- Add1<N>: ArrayLength<T>,
- Add1<N>: Sub<B1, Output = N>,
- Sub1<Add1<N>>: ArrayLength<T>,
-{
- type Longer = GenericArray<T, Add1<N>>;
-
- fn append(self, last: T) -> Self::Longer {
- let mut longer: Self::Longer = unsafe { mem::uninitialized() };
-
- unsafe {
- ptr::write(longer.as_mut_ptr() as *mut _, self);
- ptr::write(&mut longer[N::to_usize()], last);
- }
-
- longer
- }
-
- fn prepend(self, first: T) -> Self::Longer {
- let mut longer: Self::Longer = unsafe { mem::uninitialized() };
-
- let longer_ptr = longer.as_mut_ptr();
-
- unsafe {
- ptr::write(longer_ptr as *mut _, first);
- ptr::write(longer_ptr.offset(1) as *mut _, self);
- }
-
- longer
- }
-}
-
-unsafe impl<T, N: ArrayLength<T>> Shorten<T> for GenericArray<T, N>
-where
- N: Sub<B1>,
- Sub1<N>: ArrayLength<T>,
- Sub1<N>: Add<B1, Output = N>,
- Add1<Sub1<N>>: ArrayLength<T>,
-{
- type Shorter = GenericArray<T, Sub1<N>>;
-
- fn pop_back(self) -> (Self::Shorter, T) {
- let init_ptr = self.as_ptr();
- let last_ptr = unsafe { init_ptr.offset(Sub1::<N>::to_usize() as isize) };
-
- let init = unsafe { ptr::read(init_ptr as _) };
- let last = unsafe { ptr::read(last_ptr as _) };
-
- mem::forget(self);
-
- (init, last)
- }
-
- fn pop_front(self) -> (T, Self::Shorter) {
- let head_ptr = self.as_ptr();
- let tail_ptr = unsafe { head_ptr.offset(1) };
-
- let head = unsafe { ptr::read(head_ptr as _) };
- let tail = unsafe { ptr::read(tail_ptr as _) };
-
- mem::forget(self);
-
- (head, tail)
- }
-}
-
-/// Defines a `GenericSequence` that can be split into two parts at a given pivot index.
-pub unsafe trait Split<T, K>: GenericSequence<T>
-where
- K: ArrayLength<T>,
-{
- /// First part of the resulting split array
- type First: GenericSequence<T>;
- /// Second part of the resulting split array
- type Second: GenericSequence<T>;
-
- /// Splits an array at the given index, returning the separate parts of the array.
- fn split(self) -> (Self::First, Self::Second);
-}
-
-unsafe impl<T, N, K> Split<T, K> for GenericArray<T, N>
-where
- N: ArrayLength<T>,
- K: ArrayLength<T>,
- N: Sub<K>,
- Diff<N, K>: ArrayLength<T>,
-{
- type First = GenericArray<T, K>;
- type Second = GenericArray<T, Diff<N, K>>;
-
- fn split(self) -> (Self::First, Self::Second) {
- let head_ptr = self.as_ptr();
- let tail_ptr = unsafe { head_ptr.offset(K::to_usize() as isize) };
-
- let head = unsafe { ptr::read(head_ptr as _) };
- let tail = unsafe { ptr::read(tail_ptr as _) };
-
- mem::forget(self);
-
- (head, tail)
- }
-}
-
-/// Defines `GenericSequence`s which can be joined together, forming a larger array.
-pub unsafe trait Concat<T, M>: GenericSequence<T>
-where
- M: ArrayLength<T>,
-{
- /// Sequence to be concatenated with `self`
- type Rest: GenericSequence<T, Length = M>;
-
- /// Resulting sequence formed by the concatenation.
- type Output: GenericSequence<T>;
-
- /// Concatenate, or join, two sequences.
- fn concat(self, rest: Self::Rest) -> Self::Output;
-}
-
-unsafe impl<T, N, M> Concat<T, M> for GenericArray<T, N>
-where
- N: ArrayLength<T> + Add<M>,
- M: ArrayLength<T>,
- Sum<N, M>: ArrayLength<T>,
-{
- type Rest = GenericArray<T, M>;
- type Output = GenericArray<T, Sum<N, M>>;
-
- fn concat(self, rest: Self::Rest) -> Self::Output {
- let mut output: Self::Output = unsafe { mem::uninitialized() };
-
- let output_ptr = output.as_mut_ptr();
-
- unsafe {
- ptr::write(output_ptr as *mut _, self);
- ptr::write(output_ptr.offset(N::to_usize() as isize) as *mut _, rest);
- }
-
- output
- }
-}
diff --git a/vendor/generic-array-0.12.4/tests/arr.rs b/vendor/generic-array-0.12.4/tests/arr.rs
deleted file mode 100644
index c37b5d50f..000000000
--- a/vendor/generic-array-0.12.4/tests/arr.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-#[macro_use]
-extern crate generic_array;
-extern crate typenum;
-
-#[test]
-fn empty_without_trailing_comma() {
- let ar = arr![u8; ];
- assert_eq!(format!("{:x}", ar), "");
-}
-
-#[test]
-fn empty_with_trailing_comma() {
- let ar = arr![u8; , ];
- assert_eq!(format!("{:x}", ar), "");
-}
-
-#[test]
-fn without_trailing_comma() {
- let ar = arr![u8; 10, 20, 30];
- assert_eq!(format!("{:x}", ar), "0a141e");
-}
-
-#[test]
-fn with_trailing_comma() {
- let ar = arr![u8; 10, 20, 30, ];
- assert_eq!(format!("{:x}", ar), "0a141e");
-}
diff --git a/vendor/generic-array-0.12.4/tests/generics.rs b/vendor/generic-array-0.12.4/tests/generics.rs
deleted file mode 100644
index d48fe08c0..000000000
--- a/vendor/generic-array-0.12.4/tests/generics.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-#![recursion_limit = "128"]
-
-#[macro_use]
-extern crate generic_array;
-
-use generic_array::typenum::consts::U4;
-
-use std::fmt::Debug;
-use std::ops::Add;
-
-use generic_array::{GenericArray, ArrayLength};
-use generic_array::sequence::*;
-use generic_array::functional::*;
-
-/// Example function using generics to pass N-length sequences and map them
-pub fn generic_map<S>(s: S)
-where
- S: FunctionalSequence<i32>, // `.map`
- S::Item: Add<i32, Output = i32>, // `x + 1`
- S: MappedGenericSequence<i32, i32>, // `i32` -> `i32`
- MappedSequence<S, i32, i32>: Debug, // println!
-{
- let a = s.map(|x| x + 1);
-
- println!("{:?}", a);
-}
-
-/// Complex example function using generics to pass N-length sequences, zip them, and then map that result.
-///
-/// If used with `GenericArray` specifically this isn't necessary
-pub fn generic_sequence_zip_sum<A, B>(a: A, b: B) -> i32
-where
- A: FunctionalSequence<i32>, // `.zip`
- B: FunctionalSequence<i32, Length = A::Length>, // `.zip`
- A: MappedGenericSequence<i32, i32>, // `i32` -> `i32`
- B: MappedGenericSequence<i32, i32, Mapped = MappedSequence<A, i32, i32>>, // `i32` -> `i32`, prove A and B can map to the same output
- A::Item: Add<B::Item, Output = i32>, // `l + r`
- MappedSequence<A, i32, i32>: MappedGenericSequence<i32, i32> + FunctionalSequence<i32>, // `.map`
- SequenceItem<MappedSequence<A, i32, i32>>: Add<i32, Output=i32>, // `x + 1`
- MappedSequence<MappedSequence<A, i32, i32>, i32, i32>: Debug, // `println!`
- MappedSequence<MappedSequence<A, i32, i32>, i32, i32>: FunctionalSequence<i32>, // `.fold`
- SequenceItem<MappedSequence<MappedSequence<A, i32, i32>, i32, i32>>: Add<i32, Output=i32> // `x + a`, note the order
-{
- let c = a.zip(b, |l, r| l + r).map(|x| x + 1);
-
- println!("{:?}", c);
-
- c.fold(0, |a, x| x + a)
-}
-
-/// Super-simple fixed-length i32 `GenericArray`s
-pub fn generic_array_plain_zip_sum(a: GenericArray<i32, U4>, b: GenericArray<i32, U4>) -> i32 {
- a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
-}
-
-pub fn generic_array_variable_length_zip_sum<N>(a: GenericArray<i32, N>, b: GenericArray<i32, N>) -> i32
-where
- N: ArrayLength<i32>,
-{
- a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
-}
-
-pub fn generic_array_same_type_variable_length_zip_sum<T, N>(a: GenericArray<T, N>, b: GenericArray<T, N>) -> i32
-where
- N: ArrayLength<T> + ArrayLength<<T as Add<T>>::Output>,
- T: Add<T, Output=i32>,
-{
- a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
-}
-
-/// Complex example using fully generic `GenericArray`s with the same length.
-///
-/// It's mostly just the repeated `Add` traits, which would be present in other systems anyway.
-pub fn generic_array_zip_sum<A, B, N: ArrayLength<A> + ArrayLength<B>>(a: GenericArray<A, N>, b: GenericArray<B, N>) -> i32
-where
- A: Add<B>,
- N: ArrayLength<<A as Add<B>>::Output> +
- ArrayLength<<<A as Add<B>>::Output as Add<i32>>::Output>,
- <A as Add<B>>::Output: Add<i32>,
- <<A as Add<B>>::Output as Add<i32>>::Output: Add<i32, Output=i32>,
-{
- a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
-}
-
-#[test]
-fn test_generics() {
- generic_map(arr![i32; 1, 2, 3, 4]);
-
- assert_eq!(generic_sequence_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
-
- assert_eq!(generic_array_plain_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
-
- assert_eq!(generic_array_variable_length_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
-
- assert_eq!(generic_array_same_type_variable_length_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
-
- assert_eq!(generic_array_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
-} \ No newline at end of file
diff --git a/vendor/generic-array-0.12.4/tests/hex.rs b/vendor/generic-array-0.12.4/tests/hex.rs
deleted file mode 100644
index 0882e9bb3..000000000
--- a/vendor/generic-array-0.12.4/tests/hex.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-#[macro_use]
-extern crate generic_array;
-extern crate typenum;
-
-use generic_array::GenericArray;
-use std::str::from_utf8;
-use typenum::U2048;
-
-#[test]
-fn short_lower_hex() {
- let ar = arr![u8; 10, 20, 30];
- assert_eq!(format!("{:x}", ar), "0a141e");
-}
-
-#[test]
-fn short_upper_hex() {
- let ar = arr![u8; 30, 20, 10];
- assert_eq!(format!("{:X}", ar), "1E140A");
-}
-
-#[test]
-fn long_lower_hex() {
- let ar = GenericArray::<u8, U2048>::default();
- assert_eq!(format!("{:x}", ar), from_utf8(&[b'0'; 4096]).unwrap());
-}
-
-#[test]
-fn long_lower_hex_truncated() {
- let ar = GenericArray::<u8, U2048>::default();
- assert_eq!(format!("{:.3001x}", ar), from_utf8(&[b'0'; 3001]).unwrap());
-}
-
-#[test]
-fn long_upper_hex() {
- let ar = GenericArray::<u8, U2048>::default();
- assert_eq!(format!("{:X}", ar), from_utf8(&[b'0'; 4096]).unwrap());
-}
-
-#[test]
-fn long_upper_hex_truncated() {
- let ar = GenericArray::<u8, U2048>::default();
- assert_eq!(format!("{:.2777X}", ar), from_utf8(&[b'0'; 2777]).unwrap());
-}
-
-#[test]
-fn truncated_lower_hex() {
- let ar = arr![u8; 10, 20, 30, 40, 50];
- assert_eq!(format!("{:.2x}", ar), "0a");
- assert_eq!(format!("{:.3x}", ar), "0a1");
- assert_eq!(format!("{:.4x}", ar), "0a14");
-}
-
-#[test]
-fn truncated_upper_hex() {
- let ar = arr![u8; 30, 20, 10, 17, 0];
- assert_eq!(format!("{:.4X}", ar), "1E14");
- assert_eq!(format!("{:.5X}", ar), "1E140");
- assert_eq!(format!("{:.6X}", ar), "1E140A");
- assert_eq!(format!("{:.7X}", ar), "1E140A1");
- assert_eq!(format!("{:.8X}", ar), "1E140A11");
-}
diff --git a/vendor/generic-array-0.12.4/tests/import_name.rs b/vendor/generic-array-0.12.4/tests/import_name.rs
deleted file mode 100644
index 27653c9a8..000000000
--- a/vendor/generic-array-0.12.4/tests/import_name.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#[macro_use]
-extern crate generic_array as gen_arr;
-
-use gen_arr::typenum;
-
-#[test]
-fn test_different_crate_name() {
- let _: gen_arr::GenericArray<u32, typenum::U4> = arr![u32; 0, 1, 2, 3];
- let _: gen_arr::GenericArray<u32, typenum::U0> = arr![u32;];
-}
diff --git a/vendor/generic-array-0.12.4/tests/iter.rs b/vendor/generic-array-0.12.4/tests/iter.rs
deleted file mode 100644
index 47860d728..000000000
--- a/vendor/generic-array-0.12.4/tests/iter.rs
+++ /dev/null
@@ -1,164 +0,0 @@
-#[macro_use]
-extern crate generic_array;
-
-use std::cell::Cell;
-use std::ops::Drop;
-
-use generic_array::GenericArray;
-use generic_array::typenum::consts::U5;
-
-#[test]
-fn test_into_iter_as_slice() {
- let array = arr![char; 'a', 'b', 'c'];
- let mut into_iter = array.into_iter();
- assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
- let _ = into_iter.next().unwrap();
- assert_eq!(into_iter.as_slice(), &['b', 'c']);
- let _ = into_iter.next().unwrap();
- let _ = into_iter.next().unwrap();
- assert_eq!(into_iter.as_slice(), &[]);
-}
-
-#[test]
-fn test_into_iter_as_mut_slice() {
- let array = arr![char; 'a', 'b', 'c'];
- let mut into_iter = array.into_iter();
- assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
- into_iter.as_mut_slice()[0] = 'x';
- into_iter.as_mut_slice()[1] = 'y';
- assert_eq!(into_iter.next().unwrap(), 'x');
- assert_eq!(into_iter.as_slice(), &['y', 'c']);
-}
-
-#[test]
-fn test_into_iter_debug() {
- let array = arr![char; 'a', 'b', 'c'];
- let into_iter = array.into_iter();
- let debug = format!("{:?}", into_iter);
- assert_eq!(debug, "GenericArrayIter(['a', 'b', 'c'])");
-}
-
-#[test]
-fn test_into_iter_clone() {
- fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
- let v: Vec<i32> = it.collect();
- assert_eq!(&v[..], slice);
- }
- let mut it = arr![i32; 1, 2, 3].into_iter();
- iter_equal(it.clone(), &[1, 2, 3]);
- assert_eq!(it.next(), Some(1));
- let mut it = it.rev();
- iter_equal(it.clone(), &[3, 2]);
- assert_eq!(it.next(), Some(3));
- iter_equal(it.clone(), &[2]);
- assert_eq!(it.next(), Some(2));
- iter_equal(it.clone(), &[]);
- assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_into_iter_nth() {
- let v = arr![i32; 0, 1, 2, 3, 4];
- for i in 0..v.len() {
- assert_eq!(v.clone().into_iter().nth(i).unwrap(), v[i]);
- }
- assert_eq!(v.clone().into_iter().nth(v.len()), None);
-
- let mut iter = v.into_iter();
- assert_eq!(iter.nth(2).unwrap(), v[2]);
- assert_eq!(iter.nth(1).unwrap(), v[4]);
-}
-
-#[test]
-fn test_into_iter_last() {
- let v = arr![i32; 0, 1, 2, 3, 4];
- assert_eq!(v.into_iter().last().unwrap(), 4);
- assert_eq!(arr![i32; 0].into_iter().last().unwrap(), 0);
-}
-
-#[test]
-fn test_into_iter_count() {
- let v = arr![i32; 0, 1, 2, 3, 4];
- assert_eq!(v.clone().into_iter().count(), 5);
-
- let mut iter2 = v.into_iter();
- iter2.next();
- iter2.next();
- assert_eq!(iter2.count(), 3);
-}
-
-#[test]
-fn test_into_iter_flat_map() {
- assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10));
-}
-
-#[test]
-fn test_into_iter_drops() {
- struct R<'a> {
- i: &'a Cell<usize>,
- }
-
- impl<'a> Drop for R<'a> {
- fn drop(&mut self) {
- self.i.set(self.i.get() + 1);
- }
- }
-
- fn r(i: &Cell<usize>) -> R {
- R {
- i: i
- }
- }
-
- fn v(i: &Cell<usize>) -> GenericArray<R, U5> {
- arr![R; r(i), r(i), r(i), r(i), r(i)]
- }
-
- let i = Cell::new(0);
- {
- v(&i).into_iter();
- }
- assert_eq!(i.get(), 5);
-
- let i = Cell::new(0);
- {
- let mut iter = v(&i).into_iter();
- let _x = iter.next();
- assert_eq!(i.get(), 0);
- assert_eq!(iter.count(), 4);
- assert_eq!(i.get(), 4);
- }
- assert_eq!(i.get(), 5);
-
- let i = Cell::new(0);
- {
- let mut iter = v(&i).into_iter();
- let _x = iter.nth(2);
- assert_eq!(i.get(), 2);
- let _y = iter.last();
- assert_eq!(i.get(), 3);
- }
- assert_eq!(i.get(), 5);
-
- let i = Cell::new(0);
- for (index, _x) in v(&i).into_iter().enumerate() {
- assert_eq!(i.get(), index);
- }
- assert_eq!(i.get(), 5);
-
- let i = Cell::new(0);
- for (index, _x) in v(&i).into_iter().rev().enumerate() {
- assert_eq!(i.get(), index);
- }
- assert_eq!(i.get(), 5);
-}
-
-/*
-//TODO: Cover this
-#[allow(dead_code)]
-fn assert_covariance() {
- fn into_iter<'new>(i: GenericArrayIter<&'static str, U10>) -> GenericArrayIter<&'new str, U10> {
- i
- }
-}
-*/ \ No newline at end of file
diff --git a/vendor/generic-array-0.12.4/tests/mod.rs b/vendor/generic-array-0.12.4/tests/mod.rs
deleted file mode 100644
index 6c6d9eb49..000000000
--- a/vendor/generic-array-0.12.4/tests/mod.rs
+++ /dev/null
@@ -1,287 +0,0 @@
-#![recursion_limit = "128"]
-#![no_std]
-#[macro_use]
-extern crate generic_array;
-use core::cell::Cell;
-use core::ops::{Add, Drop};
-use generic_array::GenericArray;
-use generic_array::functional::*;
-use generic_array::sequence::*;
-use generic_array::typenum::{U1, U3, U4, U97};
-
-#[test]
-fn test() {
- let mut list97 = [0; 97];
- for i in 0..97 {
- list97[i] = i as i32;
- }
- let l: GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
- assert_eq!(l[0], 0);
- assert_eq!(l[1], 1);
- assert_eq!(l[32], 32);
- assert_eq!(l[56], 56);
-}
-
-#[test]
-fn test_drop() {
- #[derive(Clone)]
- struct TestDrop<'a>(&'a Cell<u32>);
-
- impl<'a> Drop for TestDrop<'a> {
- fn drop(&mut self) {
- self.0.set(self.0.get() + 1);
- }
- }
-
- let drop_counter = Cell::new(0);
- {
- let _: GenericArray<TestDrop, U3> = arr![TestDrop; TestDrop(&drop_counter),
- TestDrop(&drop_counter),
- TestDrop(&drop_counter)];
- }
- assert_eq!(drop_counter.get(), 3);
-}
-
-#[test]
-fn test_arr() {
- let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
- assert_eq!(test[1], 2);
-}
-
-#[test]
-fn test_copy() {
- let test = arr![u32; 1, 2, 3];
- let test2 = test;
- // if GenericArray is not copy, this should fail as a use of a moved value
- assert_eq!(test[1], 2);
- assert_eq!(test2[0], 1);
-}
-
-#[derive(Debug, PartialEq, Eq)]
-struct NoClone<T>(T);
-
-#[test]
-fn test_from_slice() {
- let arr = [1, 2, 3, 4];
- let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
- assert_eq!(&arr[..3], gen_arr.as_slice());
- let arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)];
- let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
- assert_eq!(&arr[..3], gen_arr.as_slice());
-}
-
-#[test]
-fn test_from_mut_slice() {
- let mut arr = [1, 2, 3, 4];
- {
- let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
- gen_arr[2] = 10;
- }
- assert_eq!(arr, [1, 2, 10, 4]);
- let mut arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)];
- {
- let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
- gen_arr[2] = NoClone(10);
- }
- assert_eq!(arr, [NoClone(1), NoClone(2), NoClone(10), NoClone(4)]);
-}
-
-#[test]
-fn test_default() {
- let arr = GenericArray::<u8, U1>::default();
- assert_eq!(arr[0], 0);
-}
-
-#[test]
-fn test_from() {
- let data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)];
- let garray: GenericArray<(usize, usize, usize), U3> = data.into();
- assert_eq!(&data, garray.as_slice());
-}
-
-#[test]
-fn test_unit_macro() {
- let arr = arr![f32; 3.14];
- assert_eq!(arr[0], 3.14);
-}
-
-#[test]
-fn test_empty_macro() {
- let _arr = arr![f32;];
-}
-
-#[test]
-fn test_cmp() {
- arr![u8; 0x00].cmp(&arr![u8; 0x00]);
-}
-
-/// This test should cause a helpful compile error if uncommented.
-// #[test]
-// fn test_empty_macro2(){
-// let arr = arr![];
-// }
-#[cfg(feature = "serde")]
-mod impl_serde {
- extern crate serde_json;
-
- use generic_array::GenericArray;
- use generic_array::typenum::U6;
-
- #[test]
- fn test_serde_implementation() {
- let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
- let string = serde_json::to_string(&array).unwrap();
- assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");
-
- let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
- assert_eq!(test_array, array);
- }
-}
-
-#[test]
-fn test_map() {
- let b: GenericArray<i32, U4> = GenericArray::generate(|i| i as i32 * 4).map(|x| x - 3);
-
- assert_eq!(b, arr![i32; -3, 1, 5, 9]);
-}
-
-#[test]
-fn test_zip() {
- let a: GenericArray<_, U4> = GenericArray::generate(|i| i + 1);
- let b: GenericArray<_, U4> = GenericArray::generate(|i| i as i32 * 4);
-
- // Uses reference and non-reference arguments
- let c = (&a).zip(b, |r, l| *r as i32 + l);
-
- assert_eq!(c, arr![i32; 1, 6, 11, 16]);
-}
-
-#[test]
-#[should_panic]
-fn test_from_iter_short() {
- use core::iter::repeat;
-
- let a: GenericArray<_, U4> = repeat(11).take(3).collect();
-
- assert_eq!(a, arr![i32; 11, 11, 11, 0]);
-}
-
-#[test]
-fn test_from_iter() {
- use core::iter::{once, repeat};
-
- let a: GenericArray<_, U4> = repeat(11).take(3).chain(once(0)).collect();
-
- assert_eq!(a, arr![i32; 11, 11, 11, 0]);
-}
-
-#[test]
-fn test_sizes() {
- #![allow(dead_code)]
- use core::mem::{size_of, size_of_val};
-
- #[derive(Debug, Copy, Clone)]
- #[repr(C)]
- #[repr(packed)]
- struct Test {
- t: u16,
- s: u32,
- r: u16,
- f: u16,
- o: u32,
- }
-
- assert_eq!(size_of::<Test>(), 14);
-
- assert_eq!(size_of_val(&arr![u8; 1, 2, 3]), size_of::<u8>() * 3);
- assert_eq!(size_of_val(&arr![u32; 1]), size_of::<u32>() * 1);
- assert_eq!(size_of_val(&arr![u64; 1, 2, 3, 4]), size_of::<u64>() * 4);
-
- assert_eq!(size_of::<GenericArray<Test, U97>>(), size_of::<Test>() * 97);
-}
-
-#[test]
-fn test_append() {
- let a = arr![i32; 1, 2, 3];
-
- let b = a.append(4);
-
- assert_eq!(b, arr![i32; 1, 2, 3, 4]);
-}
-
-#[test]
-fn test_prepend() {
- let a = arr![i32; 1, 2, 3];
-
- let b = a.prepend(4);
-
- assert_eq!(b, arr![i32; 4, 1, 2, 3]);
-}
-
-#[test]
-fn test_pop() {
- let a = arr![i32; 1, 2, 3, 4];
-
- let (init, last) = a.pop_back();
-
- assert_eq!(init, arr![i32; 1, 2, 3]);
- assert_eq!(last, 4);
-
- let (head, tail) = a.pop_front();
-
- assert_eq!(head, 1);
- assert_eq!(tail, arr![i32; 2, 3, 4]);
-}
-
-#[test]
-fn test_split() {
- let a = arr![i32; 1, 2, 3, 4];
-
- let (b, c) = a.split();
-
- assert_eq!(b, arr![i32; 1]);
- assert_eq!(c, arr![i32; 2, 3, 4]);
-
- let (e, f) = a.split();
-
- assert_eq!(e, arr![i32; 1, 2]);
- assert_eq!(f, arr![i32; 3, 4]);
-}
-
-#[test]
-fn test_concat() {
- let a = arr![i32; 1, 2];
- let b = arr![i32; 3, 4];
-
- let c = a.concat(b);
-
- assert_eq!(c, arr![i32; 1, 2, 3, 4]);
-
- let (d, e) = c.split();
-
- assert_eq!(d, arr![i32; 1]);
- assert_eq!(e, arr![i32; 2, 3, 4]);
-}
-
-#[test]
-fn test_fold() {
- let a = arr![i32; 1, 2, 3, 4];
-
- assert_eq!(10, a.fold(0, |a, x| a + x));
-}
-
-fn sum_generic<S>(s: S) -> i32
-where
- S: FunctionalSequence<i32>,
- S::Item: Add<i32, Output = i32>, // `+`
- i32: Add<S::Item, Output = i32>, // reflexive
-{
- s.fold(0, |a, x| a + x)
-}
-
-#[test]
-fn test_sum() {
- let a = sum_generic(arr![i32; 1, 2, 3, 4]);
-
- assert_eq!(a, 10);
-}
diff --git a/vendor/getrandom/.cargo-checksum.json b/vendor/getrandom/.cargo-checksum.json
index 7bdcc1bc4..adfe6c9e5 100644
--- a/vendor/getrandom/.cargo-checksum.json
+++ b/vendor/getrandom/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"e972a70c9a4729acbd6bd81ca0c3e03944cab242743b308d124d64b3552f8e63","Cargo.toml":"66283df4cc6406f65b46dded3469d23f9d1c6372a0385af8cdcde9da1b6cf5d9","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"7ae74633326a22fd6298d7f209fb14884277bd98049795f444945acbb2b0dfbd","benches/mod.rs":"5495735ff210a50cab23c2cc84191ed910af7c30395a3d9d6095b722765b3864","src/3ds.rs":"0f48fc15f89b518fb92e06aaa4838b62dc073598e8f288df56ad1e5a9251af1e","src/bsd_arandom.rs":"d2ee195acd80c7d1364a369ad0d2dad46f5f9f973f9d3960367413fd87acfcd6","src/custom.rs":"b363ee77664203d141985402433afd6808b72cc50bff586b3034d303eccfc281","src/dragonfly.rs":"28f3f7ac4f093dfb6cd2c8e7e0714f16d0f03f8c658e56caa8fe9bd03b1ff39b","src/error.rs":"110ffe8a2c6b0fa46a4e317e837efe617b343f250fedac61bcabc3c5250e7432","src/error_impls.rs":"9c34832ebb99cd5e31bc5c8ffc5beb5b3fa6f7ff0226aaa1cdf8e10e6d64b324","src/espidf.rs":"19f101486584fde6dad962f4d9792de168658047312106641a5caf6866a5bbcf","src/fuchsia.rs":"470d8509deb5b06fa6417f294c0a49e0e35a580249a5d8944c3be5aa746f64ea","src/ios.rs":"4bad4f5c096a50338b86aeac91a937c18bc55b9555e6f34806ad13732e64523d","src/js.rs":"04c750491ba3bcdad3609265938410ee09928c5d6dfd0d33d826a9884d13ac4c","src/lib.rs":"674af2d277b66ecf2e49e1059638abd58db089df095b8b65d9e347782e4bb1e0","src/linux_android.rs":"39cb80999c8534145240a350976d261b8924436bf9a4563960c7bd8c2c83c773","src/macos.rs":"b692f2fcc2319a5195f47751d5bd7dd87c7c24a61d14fa4e3dbc992ae66212b7","src/openbsd.rs":"066b2dd395c190444a658bb0b52a052eabbd68ea5a534fb729c7e5373abc0a6a","src/rdrand.rs":"79d23183b1905d61bd9df9729dc798505a2ed750d3339e342ab144e1709827e4","src/solaris_illumos.rs":"9c7004446fabe5a7a21c73d5a65d7e2115b5bd1d1dbb735c984cab3dba239785","src/solid.rs":"997035d54c9762d22a5a14f54e7fbed4dd266cdeacbdf6aab7d8aee05537e8ba","src/use_file.rs":"16e42eb0a56e375c330c1ca8eb58c444e82ef3ad35230b961fdba96a02a68804","src/util.rs":"da6964dc1523f1cb8d26365fa6a8ece46360587e6974931624b271f0c72cda8b","src/util_libc.rs":"9fd636b23121a86630f0c7891a310444f5b1bb29b0013290e130b79ed1e1f79e","src/vxworks.rs":"a5aa0e40f890e0f35626458bb656a3340b8af3111e4bacd2e12505a8d50a3505","src/wasi.rs":"02b3a75613dc80444847675ecfea59f390c2597ce1d3334612a8dba71f6082de","src/windows.rs":"e3c8f033d5d2a6b8abc5c92b005232f5aca8ce941bd94964a0f58f2436af9990","tests/common/mod.rs":"b6beee8f535d2d094a65711fe0af91a6fc220aa09729ed7269fe33cafdc9177f","tests/custom.rs":"9f2c0193193f6bcf641116ca0b3653b33d2015e0e98ce107ee1d1f60c5eeae3a","tests/normal.rs":"9e1c4b1e468a09ed0225370dfb6608f8b8135e0fabb09bbc1a718105164aade6","tests/rdrand.rs":"4474ccebf9d33c89288862a7e367018405968dddc55c7c6f97e21b5fe2264601"},"package":"9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"1289f7318d266dca92eceb373c5ff6ee81fa867a6f180ad57759d37df9fcad91","Cargo.toml":"2b0b1b62739f57c58e5069f90b70003f56f3242517d14ac1f875b9f36d227e6e","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"7ae74633326a22fd6298d7f209fb14884277bd98049795f444945acbb2b0dfbd","benches/mod.rs":"5495735ff210a50cab23c2cc84191ed910af7c30395a3d9d6095b722765b3864","src/3ds.rs":"0f48fc15f89b518fb92e06aaa4838b62dc073598e8f288df56ad1e5a9251af1e","src/bsd_arandom.rs":"d90c419d4def20f83e7535cd3f5ec07035045011a50c3652951d196a120c5d3e","src/custom.rs":"b363ee77664203d141985402433afd6808b72cc50bff586b3034d303eccfc281","src/dragonfly.rs":"47f933eac189f6ea48ecf021efd0747ebce1b43d1bece6bbf72a951bab705987","src/error.rs":"f87ce17f9299f9b59b47306dab25ed01d720a0ba53363f52b46b50e2f5e49e36","src/error_impls.rs":"9c34832ebb99cd5e31bc5c8ffc5beb5b3fa6f7ff0226aaa1cdf8e10e6d64b324","src/espidf.rs":"19f101486584fde6dad962f4d9792de168658047312106641a5caf6866a5bbcf","src/fuchsia.rs":"470d8509deb5b06fa6417f294c0a49e0e35a580249a5d8944c3be5aa746f64ea","src/ios.rs":"4bad4f5c096a50338b86aeac91a937c18bc55b9555e6f34806ad13732e64523d","src/js.rs":"04c750491ba3bcdad3609265938410ee09928c5d6dfd0d33d826a9884d13ac4c","src/lib.rs":"6f61a660fe35864a2fc8ed2fe29b1c2ddf5d29854a2871daade66f0059f65b8e","src/linux_android.rs":"ec24575aa4ae71b6991290dadfdea931b05397c3faababf24bd794f1a9624835","src/macos.rs":"6c09827ad5292cd022e063efa79523bfdb50ed08b9867ebaa007cd321b8d218e","src/openbsd.rs":"450a23ead462d4a840fee4aa0bfdab1e3d88c8f48e4bb608d457429ddeca69c0","src/rdrand.rs":"79d23183b1905d61bd9df9729dc798505a2ed750d3339e342ab144e1709827e4","src/solaris_illumos.rs":"d52fee9dd7d661f960c01894edd563c1ff8a512c111f7803092d9aa2ff98718e","src/solid.rs":"997035d54c9762d22a5a14f54e7fbed4dd266cdeacbdf6aab7d8aee05537e8ba","src/use_file.rs":"16e42eb0a56e375c330c1ca8eb58c444e82ef3ad35230b961fdba96a02a68804","src/util.rs":"da6964dc1523f1cb8d26365fa6a8ece46360587e6974931624b271f0c72cda8b","src/util_libc.rs":"2a63ac0e6dab16b85c4728b79a16e0640301e8b876f151b0a1db0b4394fa219f","src/vxworks.rs":"a5aa0e40f890e0f35626458bb656a3340b8af3111e4bacd2e12505a8d50a3505","src/wasi.rs":"dfdd0a870581948bd03abe64d49ca4295d9cfa26e09b97a526fd5e17148ad9ca","src/windows.rs":"d0b4f2afd1959660aa9abcd9477764bd7dc0b7d7048aee748804b37963c77c6f","tests/common/mod.rs":"b6beee8f535d2d094a65711fe0af91a6fc220aa09729ed7269fe33cafdc9177f","tests/custom.rs":"9f2c0193193f6bcf641116ca0b3653b33d2015e0e98ce107ee1d1f60c5eeae3a","tests/normal.rs":"9e1c4b1e468a09ed0225370dfb6608f8b8135e0fabb09bbc1a718105164aade6","tests/rdrand.rs":"4474ccebf9d33c89288862a7e367018405968dddc55c7c6f97e21b5fe2264601"},"package":"4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"} \ No newline at end of file
diff --git a/vendor/getrandom/CHANGELOG.md b/vendor/getrandom/CHANGELOG.md
index 4ab267ae0..b25704947 100644
--- a/vendor/getrandom/CHANGELOG.md
+++ b/vendor/getrandom/CHANGELOG.md
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.2.7] - 2022-06-14
+### Changed
+- Update `wasi` dependency to `0.11` [#253]
+
+### Fixed
+- Use `AtomicPtr` instead of `AtomicUsize` for Strict Provenance compatibility. [#263]
+
+### Documentation
+- Add comments explaining use of fallback mechanisms [#257] [#260]
+
+[#263]: https://github.com/rust-random/getrandom/pull/263
+[#260]: https://github.com/rust-random/getrandom/pull/260
+[#253]: https://github.com/rust-random/getrandom/pull/253
+[#257]: https://github.com/rust-random/getrandom/pull/257
+
## [0.2.6] - 2022-03-28
### Added
- Nintendo 3DS (`armv6k-nintendo-3ds`) support [#248]
@@ -291,7 +306,8 @@ Publish initial implementation.
## [0.0.0] - 2019-01-19
Publish an empty template library.
-[0.2.5]: https://github.com/rust-random/getrandom/compare/v0.2.5...v0.2.6
+[0.2.7]: https://github.com/rust-random/getrandom/compare/v0.2.6...v0.2.7
+[0.2.6]: https://github.com/rust-random/getrandom/compare/v0.2.5...v0.2.6
[0.2.5]: https://github.com/rust-random/getrandom/compare/v0.2.4...v0.2.5
[0.2.4]: https://github.com/rust-random/getrandom/compare/v0.2.3...v0.2.4
[0.2.3]: https://github.com/rust-random/getrandom/compare/v0.2.2...v0.2.3
diff --git a/vendor/getrandom/Cargo.toml b/vendor/getrandom/Cargo.toml
index 0a664244e..9b9c0880a 100644
--- a/vendor/getrandom/Cargo.toml
+++ b/vendor/getrandom/Cargo.toml
@@ -12,17 +12,29 @@
[package]
edition = "2018"
name = "getrandom"
-version = "0.2.6"
+version = "0.2.7"
authors = ["The Rand Project Developers"]
exclude = [".*"]
description = "A small cross-platform library for retrieving random data from system source"
documentation = "https://docs.rs/getrandom"
-categories = ["os", "no-std"]
+readme = "README.md"
+categories = [
+ "os",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-random/getrandom"
+
[package.metadata.docs.rs]
-features = ["std", "custom"]
-rustdoc-args = ["--cfg", "docsrs"]
+features = [
+ "std",
+ "custom",
+]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
[dependencies.cfg-if]
version = "1"
@@ -37,11 +49,20 @@ package = "rustc-std-workspace-core"
[features]
custom = []
-js = ["wasm-bindgen", "js-sys"]
+js = [
+ "wasm-bindgen",
+ "js-sys",
+]
rdrand = []
-rustc-dep-of-std = ["compiler_builtins", "core", "libc/rustc-dep-of-std", "wasi/rustc-dep-of-std"]
+rustc-dep-of-std = [
+ "compiler_builtins",
+ "core",
+ "libc/rustc-dep-of-std",
+ "wasi/rustc-dep-of-std",
+]
std = []
test-in-browser = []
+
[target."cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))".dependencies.js-sys]
version = "0.3"
optional = true
@@ -50,10 +71,13 @@ optional = true
version = "0.2.62"
optional = true
default-features = false
+
[target."cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))".dev-dependencies.wasm-bindgen-test]
version = "0.3.18"
+
[target."cfg(target_os = \"wasi\")".dependencies.wasi]
-version = "0.10"
+version = "0.11"
+
[target."cfg(unix)".dependencies.libc]
version = "0.2.120"
default-features = false
diff --git a/vendor/getrandom/src/bsd_arandom.rs b/vendor/getrandom/src/bsd_arandom.rs
index f26f2609c..d44121254 100644
--- a/vendor/getrandom/src/bsd_arandom.rs
+++ b/vendor/getrandom/src/bsd_arandom.rs
@@ -31,6 +31,7 @@ fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
}
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+ // getrandom(2) was introduced in FreeBSD 12.0 and NetBSD 10.0
#[cfg(target_os = "freebsd")]
{
use crate::util_libc::Weak;
diff --git a/vendor/getrandom/src/dragonfly.rs b/vendor/getrandom/src/dragonfly.rs
index f27e90690..8daaa4048 100644
--- a/vendor/getrandom/src/dragonfly.rs
+++ b/vendor/getrandom/src/dragonfly.rs
@@ -17,6 +17,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
+ // getrandom(2) was introduced in DragonflyBSD 5.7
if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
diff --git a/vendor/getrandom/src/error.rs b/vendor/getrandom/src/error.rs
index 661575376..b5ab2bb18 100644
--- a/vendor/getrandom/src/error.rs
+++ b/vendor/getrandom/src/error.rs
@@ -109,10 +109,6 @@ cfg_if! {
let idx = buf.iter().position(|&b| b == 0).unwrap_or(n);
core::str::from_utf8(&buf[..idx]).ok()
}
- } else if #[cfg(target_os = "wasi")] {
- fn os_err(errno: i32, _buf: &mut [u8]) -> Option<wasi::Error> {
- wasi::Error::from_raw_error(errno as _)
- }
} else {
fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> {
None
diff --git a/vendor/getrandom/src/lib.rs b/vendor/getrandom/src/lib.rs
index 888b9a510..c62056e55 100644
--- a/vendor/getrandom/src/lib.rs
+++ b/vendor/getrandom/src/lib.rs
@@ -149,7 +149,7 @@
#![doc(
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
- html_root_url = "https://docs.rs/getrandom/0.2.6"
+ html_root_url = "https://docs.rs/getrandom/0.2.7"
)]
#![no_std]
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
diff --git a/vendor/getrandom/src/linux_android.rs b/vendor/getrandom/src/linux_android.rs
index 5508fdd06..4270b67c6 100644
--- a/vendor/getrandom/src/linux_android.rs
+++ b/vendor/getrandom/src/linux_android.rs
@@ -14,6 +14,7 @@ use crate::{
};
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+ // getrandom(2) was introduced in Linux 3.17
static HAS_GETRANDOM: LazyBool = LazyBool::new();
if HAS_GETRANDOM.unsync_init(is_getrandom_available) {
sys_fill_exact(dest, |buf| unsafe {
diff --git a/vendor/getrandom/src/macos.rs b/vendor/getrandom/src/macos.rs
index 585a35abd..671a053bf 100644
--- a/vendor/getrandom/src/macos.rs
+++ b/vendor/getrandom/src/macos.rs
@@ -17,6 +17,7 @@ use core::mem;
type GetEntropyFn = unsafe extern "C" fn(*mut u8, libc::size_t) -> libc::c_int;
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+ // getentropy(2) was added in 10.12, Rust supports 10.7+
static GETENTROPY: Weak = unsafe { Weak::new("getentropy\0") };
if let Some(fptr) = GETENTROPY.ptr() {
let func: GetEntropyFn = unsafe { mem::transmute(fptr) };
diff --git a/vendor/getrandom/src/openbsd.rs b/vendor/getrandom/src/openbsd.rs
index c8d28b3d8..41371736f 100644
--- a/vendor/getrandom/src/openbsd.rs
+++ b/vendor/getrandom/src/openbsd.rs
@@ -10,6 +10,7 @@
use crate::{util_libc::last_os_error, Error};
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+ // getentropy(2) was added in OpenBSD 5.6, so we can use it unconditionally.
for chunk in dest.chunks_mut(256) {
let ret = unsafe { libc::getentropy(chunk.as_mut_ptr() as *mut libc::c_void, chunk.len()) };
if ret == -1 {
diff --git a/vendor/getrandom/src/solaris_illumos.rs b/vendor/getrandom/src/solaris_illumos.rs
index 2d1b767bb..cf3067d6d 100644
--- a/vendor/getrandom/src/solaris_illumos.rs
+++ b/vendor/getrandom/src/solaris_illumos.rs
@@ -30,6 +30,7 @@ type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) ->
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::c_int;
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+ // getrandom(2) was introduced in Solaris 11.3 for Illumos in 2015.
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { mem::transmute(fptr) };
diff --git a/vendor/getrandom/src/util_libc.rs b/vendor/getrandom/src/util_libc.rs
index 6df1cd7da..d057071a7 100644
--- a/vendor/getrandom/src/util_libc.rs
+++ b/vendor/getrandom/src/util_libc.rs
@@ -6,8 +6,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(dead_code)]
-use crate::{util::LazyUsize, Error};
-use core::{num::NonZeroU32, ptr::NonNull};
+use crate::Error;
+use core::{
+ num::NonZeroU32,
+ ptr::NonNull,
+ sync::atomic::{fence, AtomicPtr, Ordering},
+};
+use libc::c_void;
cfg_if! {
if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android"))] {
@@ -76,29 +81,57 @@ pub fn sys_fill_exact(
// A "weak" binding to a C function that may or may not be present at runtime.
// Used for supporting newer OS features while still building on older systems.
-// F must be a function pointer of type `unsafe extern "C" fn`. Based off of the
-// weak! macro in libstd.
+// Based off of the DlsymWeak struct in libstd:
+// https://github.com/rust-lang/rust/blob/1.61.0/library/std/src/sys/unix/weak.rs#L84
+// except that the caller must manually cast self.ptr() to a function pointer.
pub struct Weak {
name: &'static str,
- addr: LazyUsize,
+ addr: AtomicPtr<c_void>,
}
impl Weak {
+ // A non-null pointer value which indicates we are uninitialized. This
+ // constant should ideally not be a valid address of a function pointer.
+ // However, if by chance libc::dlsym does return UNINIT, there will not
+ // be undefined behavior. libc::dlsym will just be called each time ptr()
+ // is called. This would be inefficient, but correct.
+ // TODO: Replace with core::ptr::invalid_mut(1) when that is stable.
+ const UNINIT: *mut c_void = 1 as *mut c_void;
+
// Construct a binding to a C function with a given name. This function is
// unsafe because `name` _must_ be null terminated.
pub const unsafe fn new(name: &'static str) -> Self {
Self {
name,
- addr: LazyUsize::new(),
+ addr: AtomicPtr::new(Self::UNINIT),
}
}
- // Return a function pointer if present at runtime. Otherwise, return null.
- pub fn ptr(&self) -> Option<NonNull<libc::c_void>> {
- let addr = self.addr.unsync_init(|| unsafe {
- libc::dlsym(libc::RTLD_DEFAULT, self.name.as_ptr() as *const _) as usize
- });
- NonNull::new(addr as *mut _)
+ // Return the address of a function if present at runtime. Otherwise,
+ // return None. Multiple callers can call ptr() concurrently. It will
+ // always return _some_ value returned by libc::dlsym. However, the
+ // dlsym function may be called multiple times.
+ pub fn ptr(&self) -> Option<NonNull<c_void>> {
+ // Despite having only a single atomic variable (self.addr), we still
+ // cannot always use Ordering::Relaxed, as we need to make sure a
+ // successful call to dlsym() is "ordered before" any data read through
+ // the returned pointer (which occurs when the function is called).
+ // Our implementation mirrors that of the one in libstd, meaning that
+ // the use of non-Relaxed operations is probably unnecessary.
+ match self.addr.load(Ordering::Relaxed) {
+ Self::UNINIT => {
+ let symbol = self.name.as_ptr() as *const _;
+ let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, symbol) };
+ // Synchronizes with the Acquire fence below
+ self.addr.store(addr, Ordering::Release);
+ NonNull::new(addr)
+ }
+ addr => {
+ let func = NonNull::new(addr)?;
+ fence(Ordering::Acquire);
+ Some(func)
+ }
+ }
}
}
diff --git a/vendor/getrandom/src/wasi.rs b/vendor/getrandom/src/wasi.rs
index 2d413e020..c5121824a 100644
--- a/vendor/getrandom/src/wasi.rs
+++ b/vendor/getrandom/src/wasi.rs
@@ -9,15 +9,11 @@
//! Implementation for WASI
use crate::Error;
use core::num::NonZeroU32;
-use wasi::random_get;
+use wasi::wasi_snapshot_preview1::random_get;
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
- unsafe {
- random_get(dest.as_mut_ptr(), dest.len()).map_err(|e: wasi::Error| {
- // convert wasi's Error into getrandom's NonZeroU32 error
- // SAFETY: `wasi::Error` is `NonZeroU16` internally, so `e.raw_error()`
- // will never return 0
- NonZeroU32::new_unchecked(e.raw_error() as u32).into()
- })
+ match unsafe { random_get(dest.as_mut_ptr() as i32, dest.len() as i32) } {
+ 0 => Ok(()),
+ err => Err(unsafe { NonZeroU32::new_unchecked(err as u32) }.into()),
}
}
diff --git a/vendor/getrandom/src/windows.rs b/vendor/getrandom/src/windows.rs
index 643badd07..41dc37a5c 100644
--- a/vendor/getrandom/src/windows.rs
+++ b/vendor/getrandom/src/windows.rs
@@ -24,6 +24,7 @@ extern "system" {
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
// Prevent overflow of u32
for chunk in dest.chunks_mut(u32::max_value() as usize) {
+ // BCryptGenRandom was introduced in Windows Vista
let ret = unsafe {
BCryptGenRandom(
ptr::null_mut(),
diff --git a/vendor/gimli/.cargo-checksum.json b/vendor/gimli/.cargo-checksum.json
index 5b855e30c..759ec93de 100644
--- a/vendor/gimli/.cargo-checksum.json
+++ b/vendor/gimli/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"13bb20c4d7f171cdaf835093237311af52dd979091cbe2c46a6f978c9d783721","CONTRIBUTING.md":"5f513ec06013e4f6f097e9c9492da5a47b9f25c94c6ecadfb655a77405fe912c","Cargo.lock":"9961bcba2db19ce16584ca5cb089568de7ffcbc9668cba37fc3dd851b2e58e56","Cargo.toml":"d607f683bfe0d69d932c331701d54bdf429dbe5280b7cd3b1a5478d9dd9cdc79","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"03ac1a78a14682d70da4d485d3fa01d0ad819b65b6aed50359ee72af43158ca9","benches/bench.rs":"e0045b989683794951563aa91b37069b2f6ae55f95e288d23f5c984b46e3a7eb","examples/dwarf-validate.rs":"8a322dc48a04bff33a759030f399ca9972ddb103e63851cbb9b8c9672095f645","examples/dwarfdump.rs":"3ef93684d0b417da7dc89751e2f5d1c297b3574b478848cb79b550d4ecd83222","examples/simple.rs":"684dc9785f4aa0714fcb91a3ae1bb7c8612c9b12969be47fe1327447a2101d1c","examples/simple_line.rs":"ec5fa47c1ab019c6cd9d525223f947533f6d65d6add3131a0c40ac18fc1297db","fixtures/self/README.md":"557cd710240a14fdaa5842b216de57f2ed481151b640af09d6877984b3b2389f","fixtures/self/debug_abbrev":"7c0faa940d9c68d196d03ad55a20e5c746040fa428ff323277fa381deff82bba","fixtures/self/debug_aranges":"8c2aeb2335f61d04ecb7b747070d24f83a6517cbee79dc5c96d97fb6c53d6b6d","fixtures/self/debug_info":"42028a5983006e0703f9ca9515cd27d891ae4af70279fae5011d547f581e2661","fixtures/self/debug_inlined":"89d9516f06ff835621936037f5884fc56712bf304c1dcde52251ddd510fe8710","fixtures/self/debug_line":"b29aebcca3b38bb2bb8aa708cbe74a0dce5a3b0c18916b63d6d17282c017bec7","fixtures/self/debug_loc":"8906ccb9c204f233eb74c1d069dee97a19d18c2051f9147795d7b5364a9266aa","fixtures/self/debug_pubnames":"cf58e237f89c68afba724597fa7e260448636b45f2e69dc6f1bfe34006e27c48","fixtures/self/debug_pubtypes":"d43c1bed71c9d14d1683294cdc1833f069cf131d6e95ee808547919b4f352d81","fixtures/self/debug_ranges":"6d765ac18d33accd89186d077eeb505cbdf97d990c9201d63d9463cd7787ce7a","fixtures/self/debug_str":"9ed904b68eee77b8558b80b3b7ca03e8527f6c64483e9d6d845f40270eb21183","fixtures/self/eh_frame":"6dc3d84351cac42cf73d03452fbb532470dd94d08715154c48417e3f62095f17","fixtures/self/eh_frame_hdr":"afba7a0aa233c9a8c81c986495bd2505164844adb93272d6bc0c9e592e684716","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/arch.rs":"1c4cb3e2a322f3f42fe0b82875c9d0ce060d9af2388990139bdce9a4487c32da","src/common.rs":"392f52a58db6101187ca5525bbeafca9bda2342debd058cabca37350cd9db619","src/constants.rs":"ca3169f7a45ff1b6a504966c5627ad5c99193e2d0ec06dc9edfdf37617198093","src/endianity.rs":"1f7e62ae34f540c06bedf1e7948739211556eea7dd83731a5ca52c7d687ed0fc","src/leb128.rs":"996d5c79d027f97c010ca487bc4ff5f8265f4b9e63d62b4e4fa291383c259ee9","src/lib.rs":"427d747b0af62894e3c5ea20aecad33e5f458bec0b50fbe584e1e6aa1e5eb4f8","src/read/abbrev.rs":"c49c47ff607435c9d0b702faf366068cd1e95d175be79358b1e21244151eeab6","src/read/addr.rs":"f63f289edf889e87107bb2090fb1c50b48af7015f31b7c39c3d6ea09630a38e9","src/read/aranges.rs":"dee9500e0428bc34fca58b2dda85aef6bf0293785c4077c1a4c144109e9d87c9","src/read/cfi.rs":"e4dacfb576ecbe9248cbea3c3c682b6fd835d3843bca68bb3e18dbda55728643","src/read/dwarf.rs":"a39c24429b437ae3a1cd17bae2f01c973c9ce39f7b5f2b3435982d6860944e0e","src/read/endian_reader.rs":"320983a859c2bb0dd44a3e6fae55ff0a84dba3fa80c2edbc64aa8135c44eddf0","src/read/endian_slice.rs":"ae1c52499728f6a85648f1bf87c02dcf43bebecb5ad4e835a1246938ba4338bf","src/read/index.rs":"e79b8d591b8e2007a37f5ea85a6d71b69d56ca3739a85cf7bf361724c5b829fa","src/read/line.rs":"47ca5ebb8bd19000045954686d3320b838e9404cba917ec60525f11ea0d87095","src/read/lists.rs":"e473ff419feed9756289e245b7879bd89e7f19098a53162fe6773fac496ae5bc","src/read/loclists.rs":"2a5655c53fb2bf5cfe2df373210217edaa06e4d3addf27df0f724100cbfbe43b","src/read/lookup.rs":"0cf89ba12b9d48b1fe035dd3a497730323acb9427a9457abbc2f7c58c4c71165","src/read/mod.rs":"7ea1d01906db92a31a0915b8d2a84776b2a1b2a6587aac8a4acf5ecc48c019b6","src/read/op.rs":"2de049cdcff6c0a324c5737d3fc93431c729554b3bf38e09777b855d7058b29f","src/read/pubnames.rs":"701c1279aef596ed8eff13f19a5803f9e1070afa20c9bafbf29659d4c294edd4","src/read/pubtypes.rs":"6250112d63120ed283698cb42189b127f624fb453abb1222dfa75fe103ad077e","src/read/reader.rs":"b10ff3e77b54347e96b1f3cff30da104dfdd0c4d7a55b672950788f1f1ae3478","src/read/rnglists.rs":"e7426fa1564cbd7e84871ddd741d6a7f016596633f1ffa097885b6e685fc8da2","src/read/str.rs":"932971a6f6f3453685dbd33ff3c2d31a10820b989a209bdfeca3e8c5012cc4b8","src/read/unit.rs":"305e834d7c14e6855beab411076cb7db2615373fd761396ec253250bb0381a59","src/read/util.rs":"480acb9a1fbae7ce935dd1d1307e6a0ab222e009b63ae7817b4bcdcccb9a9ec4","src/read/value.rs":"9a961a49c43bd05061fce1765bda0da049f26420d1be2ed0584de7d1597ab836","src/test_util.rs":"291eefa6b51c6d934ba2f4a4c9bc7c403046fc1cccf4d43487820f0154bb89e2","src/write/abbrev.rs":"fa02163389e92e804d139cf84f833ab6af932083f0eb2d74464b4a70bd3237ff","src/write/cfi.rs":"5d36c6978d2bda09921f5b71b764a75a58e819551471fb44db23ce5db7c4a8e3","src/write/dwarf.rs":"8a1a0893e31134ad68993994594f3024ad0c8af7c1188b29e0ffc26b42edef21","src/write/endian_vec.rs":"1d5811986648816a677580b22630f5059757a381487d73e9adbb3008c9ae0c58","src/write/line.rs":"df7d2082c71b5e523cd52745700aae3dcfa5800f0b280e831ef5d8eb8035d6a7","src/write/loc.rs":"bb5b750c04f6603e18225db72652ea00239234ba674a8a8627c99d4ab07b47a9","src/write/mod.rs":"d8aa1da854cdee629d470d00d87e00dc6998e4bec1ca951f8d2f277730ab9d69","src/write/op.rs":"fb99e95631e24e46eaddef393281ed4f4c56ebc0713a8cbe1683893f7bdde8c6","src/write/range.rs":"5bac01e372c08e3cc19e1e07e40492d8214cdfa8881737920cb792f4aa2ba80b","src/write/section.rs":"3ce781d5e82ba365ff54fdd36e0ef58c58a2215b09a8861eb0b038efac82b77f","src/write/str.rs":"4850cc2fee55980f9cbb6b4169f9861ab9d05c2b28a85c2b790480b83a66f514","src/write/unit.rs":"213c881736f8c87fcb2f921e379791eaba2915e8d077139965a9c6211001fe44","src/write/writer.rs":"304181287f90445bbfb33349c26b34bd87002d6844fc5686bfc0756fd0a1ecd8","tests/convert_self.rs":"8fba3599ac892a704cbcd5aed53eaef51b040043da04f85f002c597ee7549046","tests/parse_self.rs":"f2da1c7daef7139545c9367c2f26199e8b4623b31d4ec6480ddd851e6980f2dc"},"package":"78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"789a696803d3f1bed3ff3566cac8e7cf15c4bf9428242d637d0ce7f3a0ad57a3","CONTRIBUTING.md":"5f513ec06013e4f6f097e9c9492da5a47b9f25c94c6ecadfb655a77405fe912c","Cargo.lock":"284bff6b09ef0fd214c34492417778d6d5b9f75dc54557015af01a95696c752a","Cargo.toml":"92dccbeaa61bc8c65da53917fbf32900b3cb2549f90b67b67e1c67672bac205e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"57e36d344dabe1c52a9c81eafb28787c309b86c47437abf8589ef17bf383fc5f","benches/bench.rs":"e0045b989683794951563aa91b37069b2f6ae55f95e288d23f5c984b46e3a7eb","examples/dwarf-validate.rs":"4aac1045e3c08bf00878eeff75c0cfc30c06171c5eab2e71d757505786729687","examples/dwarfdump.rs":"d74323c037689b32825efa9bf69614ee26a444513b266e819ecf486956ee3299","examples/simple.rs":"4c3425e8bd1880d9522f5ed2581fb5ccd452d4be678eebc0e147c48722a7be1d","examples/simple_line.rs":"ac795f859a17650dde466b5b23b8c161b2e3b8eb57e32f5b6718a3072f6bfad0","fixtures/self/README.md":"7cfd76031ec5a4b38cc4eb56ccbfe1bb590fb54c333d037550bdeaaeacfc20cb","fixtures/self/debug_abbrev":"7c0faa940d9c68d196d03ad55a20e5c746040fa428ff323277fa381deff82bba","fixtures/self/debug_aranges":"8c2aeb2335f61d04ecb7b747070d24f83a6517cbee79dc5c96d97fb6c53d6b6d","fixtures/self/debug_info":"42028a5983006e0703f9ca9515cd27d891ae4af70279fae5011d547f581e2661","fixtures/self/debug_inlined":"89d9516f06ff835621936037f5884fc56712bf304c1dcde52251ddd510fe8710","fixtures/self/debug_line":"b29aebcca3b38bb2bb8aa708cbe74a0dce5a3b0c18916b63d6d17282c017bec7","fixtures/self/debug_loc":"8906ccb9c204f233eb74c1d069dee97a19d18c2051f9147795d7b5364a9266aa","fixtures/self/debug_pubnames":"cf58e237f89c68afba724597fa7e260448636b45f2e69dc6f1bfe34006e27c48","fixtures/self/debug_pubtypes":"d43c1bed71c9d14d1683294cdc1833f069cf131d6e95ee808547919b4f352d81","fixtures/self/debug_ranges":"6d765ac18d33accd89186d077eeb505cbdf97d990c9201d63d9463cd7787ce7a","fixtures/self/debug_str":"9ed904b68eee77b8558b80b3b7ca03e8527f6c64483e9d6d845f40270eb21183","fixtures/self/eh_frame":"6dc3d84351cac42cf73d03452fbb532470dd94d08715154c48417e3f62095f17","fixtures/self/eh_frame_hdr":"afba7a0aa233c9a8c81c986495bd2505164844adb93272d6bc0c9e592e684716","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/arch.rs":"1c4cb3e2a322f3f42fe0b82875c9d0ce060d9af2388990139bdce9a4487c32da","src/common.rs":"392f52a58db6101187ca5525bbeafca9bda2342debd058cabca37350cd9db619","src/constants.rs":"358cf7924c79bc72de59d23d1fa02b2047d6c763c8fbd8be263ab8cd3e3ba7ec","src/endianity.rs":"1f7e62ae34f540c06bedf1e7948739211556eea7dd83731a5ca52c7d687ed0fc","src/leb128.rs":"996d5c79d027f97c010ca487bc4ff5f8265f4b9e63d62b4e4fa291383c259ee9","src/lib.rs":"6863b9a9d1eddf34b4095dfe60318aae56914fbf515ba5601b29024cc963f27c","src/read/abbrev.rs":"a3f550c32f1eb880d82bdb5257d35e10d32cfd039050e8131cbeedac346cc1d9","src/read/addr.rs":"f63f289edf889e87107bb2090fb1c50b48af7015f31b7c39c3d6ea09630a38e9","src/read/aranges.rs":"ba3302f87cffb7ee15f48b0530ebd707f45ad056934223078d25ae2a1b034f1c","src/read/cfi.rs":"b1064ed9b4b87169a148cc86adc7443c5a771dc2d1799129f7883f1ef6adc165","src/read/dwarf.rs":"a39c24429b437ae3a1cd17bae2f01c973c9ce39f7b5f2b3435982d6860944e0e","src/read/endian_reader.rs":"320983a859c2bb0dd44a3e6fae55ff0a84dba3fa80c2edbc64aa8135c44eddf0","src/read/endian_slice.rs":"ae1c52499728f6a85648f1bf87c02dcf43bebecb5ad4e835a1246938ba4338bf","src/read/index.rs":"e79b8d591b8e2007a37f5ea85a6d71b69d56ca3739a85cf7bf361724c5b829fa","src/read/line.rs":"af7a1520777e56632970fc5fe7377fdcd12d078eb88eeb2b0f2cc95b73ff68a7","src/read/lists.rs":"67ca9e1a36a91feb4996d035211de845205212bfda02163685d217818567ff93","src/read/loclists.rs":"1b4ea85c0dd8c6eae492a60cb70810185d56ba579df7986cb8a36385031b10fd","src/read/lookup.rs":"0cf89ba12b9d48b1fe035dd3a497730323acb9427a9457abbc2f7c58c4c71165","src/read/mod.rs":"3bafc747c31a575bcc92d3e7d5ea5a15f5acc01918a4377cec1dced0f85b5d2b","src/read/op.rs":"e5dce6520dfc90ec74c3b070ca374b89fcf55ff23101471591458175a72c79e6","src/read/pubnames.rs":"ed752ee1a7017e6d3be42d81e4ddaaac960ef08081463a19106c9f041526d4a3","src/read/pubtypes.rs":"5e75b32c0923e827aff0bb2db456797a0e8d38ba46be992558a7990b3196bcf5","src/read/reader.rs":"b10ff3e77b54347e96b1f3cff30da104dfdd0c4d7a55b672950788f1f1ae3478","src/read/rnglists.rs":"af637d283d76514382ee0556463cccab4e6f0ea4d061db9a44a594b5d57d1fd7","src/read/str.rs":"4c2f50014451621fea45969cd313f6840fcd3a99d7a2d081bfa1f8e0e434133a","src/read/unit.rs":"6ed00ba004c329008bf295d9c7d724afe961750f0c7b08430fc213fd5d998003","src/read/util.rs":"0b7d0d2225a98618070dc472ccba49a5411aa8beed5ff6696da079d06156d363","src/read/value.rs":"5a91e03ad3d41f679b264753498434b91948c6b89955e4beb4522498386d9b1d","src/test_util.rs":"291eefa6b51c6d934ba2f4a4c9bc7c403046fc1cccf4d43487820f0154bb89e2","src/write/abbrev.rs":"fa02163389e92e804d139cf84f833ab6af932083f0eb2d74464b4a70bd3237ff","src/write/cfi.rs":"3b04b0ebd82363738199cc673f64e0ceb60506a67c4f18b435a109caa62840f3","src/write/dwarf.rs":"8a1a0893e31134ad68993994594f3024ad0c8af7c1188b29e0ffc26b42edef21","src/write/endian_vec.rs":"1d5811986648816a677580b22630f5059757a381487d73e9adbb3008c9ae0c58","src/write/line.rs":"df7d2082c71b5e523cd52745700aae3dcfa5800f0b280e831ef5d8eb8035d6a7","src/write/loc.rs":"bb5b750c04f6603e18225db72652ea00239234ba674a8a8627c99d4ab07b47a9","src/write/mod.rs":"d8aa1da854cdee629d470d00d87e00dc6998e4bec1ca951f8d2f277730ab9d69","src/write/op.rs":"7b1d49b10c8c92b2d5b259e83119ff7dc95bc552535bb7b1a82ca9556a35c589","src/write/range.rs":"5bac01e372c08e3cc19e1e07e40492d8214cdfa8881737920cb792f4aa2ba80b","src/write/section.rs":"3ce781d5e82ba365ff54fdd36e0ef58c58a2215b09a8861eb0b038efac82b77f","src/write/str.rs":"4850cc2fee55980f9cbb6b4169f9861ab9d05c2b28a85c2b790480b83a66f514","src/write/unit.rs":"213c881736f8c87fcb2f921e379791eaba2915e8d077139965a9c6211001fe44","src/write/writer.rs":"304181287f90445bbfb33349c26b34bd87002d6844fc5686bfc0756fd0a1ecd8","tests/convert_self.rs":"180909b562969e1691b64628ded8654e6e0b10b3357f39917bd8ac288c5826dd","tests/parse_self.rs":"f2da1c7daef7139545c9367c2f26199e8b4623b31d4ec6480ddd851e6980f2dc"},"package":"22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"} \ No newline at end of file
diff --git a/vendor/gimli/CHANGELOG.md b/vendor/gimli/CHANGELOG.md
index da2ab0fe7..9ca6d70a8 100644
--- a/vendor/gimli/CHANGELOG.md
+++ b/vendor/gimli/CHANGELOG.md
@@ -2,6 +2,28 @@
--------------------------------------------------------------------------------
+## 0.26.2
+
+Released 2022/07/16.
+
+### Changed
+
+* Fixed CFI personality encoding when writing.
+ [#609](https://github.com/gimli-rs/gimli/pull/609)
+
+* Fixed use of raw pointer for mutation, detected by Miri.
+ [#614](https://github.com/gimli-rs/gimli/pull/614)
+
+* Fixed `DW_OP_GNU_implicit_pointer` handling for DWARF version 2.
+ [#618](https://github.com/gimli-rs/gimli/pull/618)
+
+### Added
+
+* Added `read::EhHdrTable::iter`.
+ [#619](https://github.com/gimli-rs/gimli/pull/619)
+
+--------------------------------------------------------------------------------
+
## 0.26.1
Released 2021/11/02.
diff --git a/vendor/gimli/Cargo.lock b/vendor/gimli/Cargo.lock
index d55f428d0..b4a719a0c 100644
--- a/vendor/gimli/Cargo.lock
+++ b/vendor/gimli/Cargo.lock
@@ -153,14 +153,14 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.26.1"
+version = "0.26.2"
dependencies = [
"compiler_builtins",
"crossbeam",
"fallible-iterator",
"getopts",
"indexmap",
- "memmap",
+ "memmap2",
"num_cpus",
"object",
"rayon",
@@ -216,13 +216,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
-name = "memmap"
-version = "0.7.0"
+name = "memmap2"
+version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
+checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7"
dependencies = [
"libc",
- "winapi",
]
[[package]]
@@ -256,9 +255,9 @@ dependencies = [
[[package]]
name = "object"
-version = "0.27.1"
+version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
+checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [
"flate2",
"memchr",
@@ -357,25 +356,3 @@ name = "wasmparser"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/vendor/gimli/Cargo.toml b/vendor/gimli/Cargo.toml
index d5f283c80..f36ccd936 100644
--- a/vendor/gimli/Cargo.toml
+++ b/vendor/gimli/Cargo.toml
@@ -3,25 +3,37 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "gimli"
-version = "0.26.1"
-exclude = ["/ci/*", "/releases/*", "/.github"]
+version = "0.26.2"
+exclude = [
+ "/releases/*",
+ "/.github",
+]
description = "A library for reading and writing the DWARF debugging format."
documentation = "https://docs.rs/gimli"
readme = "./README.md"
-keywords = ["DWARF", "debug", "ELF", "eh_frame"]
-categories = ["development-tools::debugging", "development-tools::profiling", "parser-implementations"]
-license = "Apache-2.0/MIT"
+keywords = [
+ "DWARF",
+ "debug",
+ "ELF",
+ "eh_frame",
+]
+categories = [
+ "development-tools::debugging",
+ "development-tools::profiling",
+ "parser-implementations",
+]
+license = "MIT OR Apache-2.0"
repository = "https://github.com/gimli-rs/gimli"
+
[profile.bench]
codegen-units = 1
debug = true
@@ -40,11 +52,18 @@ required-features = ["read"]
[[example]]
name = "dwarfdump"
-required-features = ["read", "std"]
+required-features = [
+ "read",
+ "std",
+]
[[example]]
name = "dwarf-validate"
-required-features = ["read", "std"]
+required-features = [
+ "read",
+ "std",
+]
+
[dependencies.alloc]
version = "1.0.0"
optional = true
@@ -72,20 +91,21 @@ optional = true
version = "1.1.0"
optional = true
default-features = false
+
[dev-dependencies.crossbeam]
version = "0.8"
[dev-dependencies.getopts]
version = "0.2"
-[dev-dependencies.memmap]
-version = "0.7"
+[dev-dependencies.memmap2]
+version = "0.5.5"
[dev-dependencies.num_cpus]
version = "1"
[dev-dependencies.object]
-version = "0.27.1"
+version = "0.29.0"
features = ["wasm"]
[dev-dependencies.rayon]
@@ -101,15 +121,26 @@ version = "0.1.3"
version = "2"
[features]
-default = ["read", "write", "std", "fallible-iterator", "endian-reader"]
-endian-reader = ["read", "stable_deref_trait"]
+default = [
+ "read",
+ "write",
+ "std",
+ "fallible-iterator",
+ "endian-reader",
+]
+endian-reader = [
+ "read",
+ "stable_deref_trait",
+]
read = ["read-core"]
read-core = []
-rustc-dep-of-std = ["core", "alloc", "compiler_builtins"]
-std = ["fallible-iterator/std", "stable_deref_trait/std"]
+rustc-dep-of-std = [
+ "core",
+ "alloc",
+ "compiler_builtins",
+]
+std = [
+ "fallible-iterator/std",
+ "stable_deref_trait/std",
+]
write = ["indexmap"]
-[badges.coveralls]
-repository = "gimli-rs/gimli"
-
-[badges.travis-ci]
-repository = "gimli-rs/gimli"
diff --git a/vendor/gimli/README.md b/vendor/gimli/README.md
index 56cee2531..19e7bbd0e 100644
--- a/vendor/gimli/README.md
+++ b/vendor/gimli/README.md
@@ -6,7 +6,7 @@
[![Coverage Status](https://coveralls.io/repos/github/gimli-rs/gimli/badge.svg?branch=master)](https://coveralls.io/github/gimli-rs/gimli?branch=master)
`gimli` is a blazing fast library for consuming the
-[DWARF debugging format](http://dwarfstd.org/).
+[DWARF debugging format](https://dwarfstd.org/).
* **Zero copy:** everything is just a reference to the original input buffer. No
copies of the input data get made.
@@ -30,7 +30,7 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
-gimli = "0.26.1"
+gimli = "0.26.2"
```
The minimum supported Rust version is 1.42.0.
@@ -49,7 +49,7 @@ The minimum supported Rust version is 1.42.0.
* [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
- * [`ddbug`](https://github.com/philipc/ddbug), a utility giving insight into
+ * [`ddbug`](https://github.com/gimli-rs/ddbug), a utility giving insight into
code generation by making debugging information readable.
* [`dwprod`](https://github.com/fitzgen/dwprod), a tiny utility to list the
diff --git a/vendor/gimli/examples/dwarf-validate.rs b/vendor/gimli/examples/dwarf-validate.rs
index 1eabccc11..54d8f3a1d 100644
--- a/vendor/gimli/examples/dwarf-validate.rs
+++ b/vendor/gimli/examples/dwarf-validate.rs
@@ -52,7 +52,7 @@ fn main() {
continue;
}
};
- let file = match unsafe { memmap::Mmap::map(&file) } {
+ let file = match unsafe { memmap2::Mmap::map(&file) } {
Ok(mmap) => mmap,
Err(err) => {
eprintln!("Failed to map file '{}': {}", path.display(), &err);
diff --git a/vendor/gimli/examples/dwarfdump.rs b/vendor/gimli/examples/dwarfdump.rs
index 64b233305..4b61fd572 100644
--- a/vendor/gimli/examples/dwarfdump.rs
+++ b/vendor/gimli/examples/dwarfdump.rs
@@ -490,7 +490,7 @@ fn main() {
process::exit(1);
}
};
- let mmap = match unsafe { memmap::Mmap::map(&file) } {
+ let mmap = match unsafe { memmap2::Mmap::map(&file) } {
Ok(mmap) => mmap,
Err(err) => {
eprintln!("Failed to map file '{}': {}", path, err);
@@ -531,7 +531,7 @@ fn main() {
continue;
}
};
- let file = match unsafe { memmap::Mmap::map(&file) } {
+ let file = match unsafe { memmap2::Mmap::map(&file) } {
Ok(mmap) => mmap,
Err(err) => {
eprintln!("Failed to map file '{}': {}", file_path, err);
@@ -786,17 +786,36 @@ fn dump_eh_frame<R: Reader, W: Write>(
// TODO: augmentation
writeln!(w, " code_align: {}", cie.code_alignment_factor())?;
writeln!(w, " data_align: {}", cie.data_alignment_factor())?;
- writeln!(w, " ra_register: {:#x}", cie.return_address_register().0)?;
+ writeln!(
+ w,
+ " ra_register: {}",
+ register_name(cie.return_address_register())
+ )?;
if let Some(encoding) = cie.lsda_encoding() {
- writeln!(w, " lsda_encoding: {:#02x}", encoding.0)?;
+ writeln!(
+ w,
+ " lsda_encoding: {}/{}",
+ encoding.application(),
+ encoding.format()
+ )?;
}
if let Some((encoding, personality)) = cie.personality_with_encoding() {
- write!(w, " personality: {:#02x} ", encoding.0)?;
+ write!(
+ w,
+ " personality: {}/{} ",
+ encoding.application(),
+ encoding.format()
+ )?;
dump_pointer(w, personality)?;
writeln!(w)?;
}
if let Some(encoding) = cie.fde_address_encoding() {
- writeln!(w, " fde_encoding: {:#02x}", encoding.0)?;
+ writeln!(
+ w,
+ " fde_encoding: {}/{}",
+ encoding.application(),
+ encoding.format()
+ )?;
}
let instructions = cie.instructions(&eh_frame, &bases);
dump_cfi_instructions(w, instructions, true, register_name)?;
@@ -1585,21 +1604,21 @@ fn dump_type_signature<W: Write>(w: &mut W, signature: gimli::DebugTypeSignature
fn dump_file_index<R: Reader, W: Write>(
w: &mut W,
- file: u64,
+ file_index: u64,
unit: &gimli::Unit<R>,
dwarf: &gimli::Dwarf<R>,
) -> Result<()> {
- if file == 0 {
+ if file_index == 0 && unit.header.version() <= 4 {
return Ok(());
}
let header = match unit.line_program {
Some(ref program) => program.header(),
None => return Ok(()),
};
- let file = match header.file(file) {
- Some(header) => header,
+ let file = match header.file(file_index) {
+ Some(file) => file,
None => {
- writeln!(w, "Unable to get header for file {}", file)?;
+ writeln!(w, "Unable to get header for file {}", file_index)?;
return Ok(());
}
};
@@ -1607,7 +1626,7 @@ fn dump_file_index<R: Reader, W: Write>(
if let Some(directory) = file.directory(header) {
let directory = dwarf.attr_string(unit, directory)?;
let directory = directory.to_string_lossy()?;
- if !directory.starts_with('/') {
+ if file.directory_index() != 0 && !directory.starts_with('/') {
if let Some(ref comp_dir) = unit.comp_dir {
write!(w, "{}/", comp_dir.to_string_lossy()?,)?;
}
@@ -2238,7 +2257,7 @@ fn dump_line_program<R: Reader, W: Write>(
writeln!(w, "<pc> [lno,col]")?;
}
let mut rows = program.rows();
- let mut file_index = 0;
+ let mut file_index = std::u64::MAX;
while let Some((header, row)) = rows.next_row()? {
let line = match row.line() {
Some(line) => line.get(),
diff --git a/vendor/gimli/examples/simple.rs b/vendor/gimli/examples/simple.rs
index b73ab7552..7c958d45c 100644
--- a/vendor/gimli/examples/simple.rs
+++ b/vendor/gimli/examples/simple.rs
@@ -6,7 +6,7 @@ use std::{borrow, env, fs};
fn main() {
for path in env::args().skip(1) {
let file = fs::File::open(&path).unwrap();
- let mmap = unsafe { memmap::Mmap::map(&file).unwrap() };
+ let mmap = unsafe { memmap2::Mmap::map(&file).unwrap() };
let object = object::File::parse(&*mmap).unwrap();
let endian = if object.is_little_endian() {
gimli::RunTimeEndian::Little
diff --git a/vendor/gimli/examples/simple_line.rs b/vendor/gimli/examples/simple_line.rs
index bf1114f90..87b224cda 100644
--- a/vendor/gimli/examples/simple_line.rs
+++ b/vendor/gimli/examples/simple_line.rs
@@ -6,7 +6,7 @@ use std::{borrow, env, fs, path};
fn main() {
for path in env::args().skip(1) {
let file = fs::File::open(&path).unwrap();
- let mmap = unsafe { memmap::Mmap::map(&file).unwrap() };
+ let mmap = unsafe { memmap2::Mmap::map(&file).unwrap() };
let object = object::File::parse(&*mmap).unwrap();
let endian = if object.is_little_endian() {
gimli::RunTimeEndian::Little
@@ -68,9 +68,16 @@ fn dump_file(object: &object::File, endian: gimli::RunTimeEndian) -> Result<(),
let mut path = path::PathBuf::new();
if let Some(file) = row.file(header) {
path = comp_dir.clone();
- if let Some(dir) = file.directory(header) {
- path.push(dwarf.attr_string(&unit, dir)?.to_string_lossy().as_ref());
+
+ // The directory index 0 is defined to correspond to the compilation unit directory.
+ if file.directory_index() != 0 {
+ if let Some(dir) = file.directory(header) {
+ path.push(
+ dwarf.attr_string(&unit, dir)?.to_string_lossy().as_ref(),
+ );
+ }
}
+
path.push(
dwarf
.attr_string(&unit, file.path_name())?
diff --git a/vendor/gimli/fixtures/self/README.md b/vendor/gimli/fixtures/self/README.md
index 3847c3852..91053d9b4 100644
--- a/vendor/gimli/fixtures/self/README.md
+++ b/vendor/gimli/fixtures/self/README.md
@@ -7,7 +7,7 @@ about cross platform and cross object file format issues when running examples.
# Updating and adding new sections
-## OSX
+## macOS
Use `otool` to list the sections of a binary:
diff --git a/vendor/gimli/src/constants.rs b/vendor/gimli/src/constants.rs
index c8d6a1662..c617f4e2e 100644
--- a/vendor/gimli/src/constants.rs
+++ b/vendor/gimli/src/constants.rs
@@ -1315,7 +1315,7 @@ DwEhPe(u8) {
// pointer result itself.
//
// This isn't defined in the DWARF or the `.eh_frame` standards, but is
-// generated by both GNU/Linux and OSX tooling.
+// generated by both GNU/Linux and macOS tooling.
DW_EH_PE_indirect = 0x80,
// These constants apply to both the lower and upper bits.
diff --git a/vendor/gimli/src/lib.rs b/vendor/gimli/src/lib.rs
index 7ac1820e3..ed1af9cbd 100644
--- a/vendor/gimli/src/lib.rs
+++ b/vendor/gimli/src/lib.rs
@@ -1,5 +1,5 @@
//! `gimli` is a library for reading and writing the
-//! [DWARF debugging format](http://dwarfstd.org/).
+//! [DWARF debugging format](https://dwarfstd.org/).
//!
//! See the [read](./read/index.html) and [write](./write/index.html) modules
//! for examples and API documentation.
diff --git a/vendor/gimli/src/read/abbrev.rs b/vendor/gimli/src/read/abbrev.rs
index 5f0e7bed7..1a24835a7 100644
--- a/vendor/gimli/src/read/abbrev.rs
+++ b/vendor/gimli/src/read/abbrev.rs
@@ -29,7 +29,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_abbrev` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugAbbrev, LittleEndian};
diff --git a/vendor/gimli/src/read/aranges.rs b/vendor/gimli/src/read/aranges.rs
index c2d22850c..83159b69b 100644
--- a/vendor/gimli/src/read/aranges.rs
+++ b/vendor/gimli/src/read/aranges.rs
@@ -18,7 +18,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_aranges` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugAranges, LittleEndian};
diff --git a/vendor/gimli/src/read/cfi.rs b/vendor/gimli/src/read/cfi.rs
index b6a81f3f4..2e5167349 100644
--- a/vendor/gimli/src/read/cfi.rs
+++ b/vendor/gimli/src/read/cfi.rs
@@ -63,7 +63,7 @@ where
///
/// It is the caller's responsibility to read the section and present it as
/// a `&[u8]` slice. That means using some ELF loader on Linux, a Mach-O
- /// loader on OSX, etc.
+ /// loader on macOS, etc.
///
/// ```
/// use gimli::{DebugFrame, NativeEndian};
@@ -218,6 +218,81 @@ impl<R: Reader> ParsedEhFrameHdr<R> {
}
}
+/// An iterator for `.eh_frame_hdr` section's binary search table.
+///
+/// Each table entry consists of a tuple containing an `initial_location` and `address`.
+/// The `initial location` represents the first address that the targeted FDE
+/// is able to decode. The `address` is the address of the FDE in the `.eh_frame` section.
+/// The `address` can be converted with `EhHdrTable::pointer_to_offset` and `EhFrame::fde_from_offset` to an FDE.
+#[derive(Debug)]
+pub struct EhHdrTableIter<'a, 'bases, R: Reader> {
+ hdr: &'a ParsedEhFrameHdr<R>,
+ table: R,
+ bases: &'bases BaseAddresses,
+ remain: u64,
+}
+
+impl<'a, 'bases, R: Reader> EhHdrTableIter<'a, 'bases, R> {
+ /// Yield the next entry in the `EhHdrTableIter`.
+ pub fn next(&mut self) -> Result<Option<(Pointer, Pointer)>> {
+ if self.remain == 0 {
+ return Ok(None);
+ }
+
+ let parameters = PointerEncodingParameters {
+ bases: &self.bases.eh_frame_hdr,
+ func_base: None,
+ address_size: self.hdr.address_size,
+ section: &self.hdr.section,
+ };
+
+ self.remain -= 1;
+ let from = parse_encoded_pointer(self.hdr.table_enc, &parameters, &mut self.table)?;
+ let to = parse_encoded_pointer(self.hdr.table_enc, &parameters, &mut self.table)?;
+ Ok(Some((from, to)))
+ }
+ /// Yield the nth entry in the `EhHdrTableIter`
+ pub fn nth(&mut self, n: usize) -> Result<Option<(Pointer, Pointer)>> {
+ use core::convert::TryFrom;
+ let size = match self.hdr.table_enc.format() {
+ constants::DW_EH_PE_uleb128 | constants::DW_EH_PE_sleb128 => {
+ return Err(Error::VariableLengthSearchTable);
+ }
+ constants::DW_EH_PE_sdata2 | constants::DW_EH_PE_udata2 => 2,
+ constants::DW_EH_PE_sdata4 | constants::DW_EH_PE_udata4 => 4,
+ constants::DW_EH_PE_sdata8 | constants::DW_EH_PE_udata8 => 8,
+ _ => return Err(Error::UnknownPointerEncoding),
+ };
+
+ let row_size = size * 2;
+ let n = u64::try_from(n).map_err(|_| Error::UnsupportedOffset)?;
+ self.remain = self.remain.saturating_sub(n);
+ self.table.skip(R::Offset::from_u64(n * row_size)?)?;
+ self.next()
+ }
+}
+
+#[cfg(feature = "fallible-iterator")]
+impl<'a, 'bases, R: Reader> fallible_iterator::FallibleIterator for EhHdrTableIter<'a, 'bases, R> {
+ type Item = (Pointer, Pointer);
+ type Error = Error;
+ fn next(&mut self) -> Result<Option<Self::Item>> {
+ EhHdrTableIter::next(self)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ use core::convert::TryInto;
+ (
+ self.remain.try_into().unwrap_or(0),
+ self.remain.try_into().ok(),
+ )
+ }
+
+ fn nth(&mut self, n: usize) -> Result<Option<Self::Item>> {
+ EhHdrTableIter::nth(self, n)
+ }
+}
+
/// The CFI binary search table that is an optional part of the `.eh_frame_hdr` section.
#[derive(Debug, Clone)]
pub struct EhHdrTable<'a, R: Reader> {
@@ -225,6 +300,20 @@ pub struct EhHdrTable<'a, R: Reader> {
}
impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
+ /// Return an iterator that can walk the `.eh_frame_hdr` table.
+ ///
+ /// Each table entry consists of a tuple containing an `initial_location` and `address`.
+ /// The `initial location` represents the first address that the targeted FDE
+ /// is able to decode. The `address` is the address of the FDE in the `.eh_frame` section.
+ /// The `address` can be converted with `EhHdrTable::pointer_to_offset` and `EhFrame::fde_from_offset` to an FDE.
+ pub fn iter<'bases>(&self, bases: &'bases BaseAddresses) -> EhHdrTableIter<'_, 'bases, R> {
+ EhHdrTableIter {
+ hdr: self.hdr,
+ bases,
+ remain: self.hdr.fde_count,
+ table: self.hdr.table.clone(),
+ }
+ }
/// *Probably* returns a pointer to the FDE for the given address.
///
/// This performs a binary search, so if there is no FDE for the given address,
@@ -423,19 +512,19 @@ where
Endian: Endianity,
{
/// Construct a new `EhFrame` instance from the data in the
- /// `.debug_frame` section.
+ /// `.eh_frame` section.
///
/// It is the caller's responsibility to read the section and present it as
/// a `&[u8]` slice. That means using some ELF loader on Linux, a Mach-O
- /// loader on OSX, etc.
+ /// loader on macOS, etc.
///
/// ```
/// use gimli::{EhFrame, EndianSlice, NativeEndian};
///
- /// // Use with `.debug_frame`
+ /// // Use with `.eh_frame`
/// # let buf = [0x00, 0x01, 0x02, 0x03];
- /// # let read_debug_frame_section_somehow = || &buf;
- /// let debug_frame = EhFrame::new(read_debug_frame_section_somehow(), NativeEndian);
+ /// # let read_eh_frame_section_somehow = || &buf;
+ /// let eh_frame = EhFrame::new(read_eh_frame_section_somehow(), NativeEndian);
/// ```
pub fn new(section: &'input [u8], endian: Endian) -> Self {
Self::from(EndianSlice::new(section, endian))
@@ -6211,6 +6300,39 @@ mod tests {
let table = table.unwrap();
let bases = Default::default();
+ let mut iter = table.iter(&bases);
+ assert_eq!(
+ iter.next(),
+ Ok(Some((
+ Pointer::Direct(10),
+ Pointer::Direct(0x12345 + start_of_fde1.value().unwrap() as u64)
+ )))
+ );
+ assert_eq!(
+ iter.next(),
+ Ok(Some((
+ Pointer::Direct(20),
+ Pointer::Direct(0x12345 + start_of_fde2.value().unwrap() as u64)
+ )))
+ );
+ assert_eq!(iter.next(), Ok(None));
+
+ assert_eq!(
+ table.iter(&bases).nth(0),
+ Ok(Some((
+ Pointer::Direct(10),
+ Pointer::Direct(0x12345 + start_of_fde1.value().unwrap() as u64)
+ )))
+ );
+
+ assert_eq!(
+ table.iter(&bases).nth(1),
+ Ok(Some((
+ Pointer::Direct(20),
+ Pointer::Direct(0x12345 + start_of_fde2.value().unwrap() as u64)
+ )))
+ );
+ assert_eq!(table.iter(&bases).nth(2), Ok(None));
let f = |_: &_, _: &_, o: EhFrameOffset| {
assert_eq!(o, EhFrameOffset(start_of_cie.value().unwrap() as usize));
diff --git a/vendor/gimli/src/read/line.rs b/vendor/gimli/src/read/line.rs
index 096ddf07b..0e7380bb9 100644
--- a/vendor/gimli/src/read/line.rs
+++ b/vendor/gimli/src/read/line.rs
@@ -27,7 +27,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_line` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugLine, LittleEndian};
diff --git a/vendor/gimli/src/read/lists.rs b/vendor/gimli/src/read/lists.rs
index b63c5c126..898a757d3 100644
--- a/vendor/gimli/src/read/lists.rs
+++ b/vendor/gimli/src/read/lists.rs
@@ -4,6 +4,7 @@ use crate::read::{Error, Reader, Result};
#[derive(Debug, Clone, Copy)]
pub(crate) struct ListsHeader {
encoding: Encoding,
+ #[allow(dead_code)]
offset_entry_count: u32,
}
diff --git a/vendor/gimli/src/read/loclists.rs b/vendor/gimli/src/read/loclists.rs
index 3c4da127d..3902c181b 100644
--- a/vendor/gimli/src/read/loclists.rs
+++ b/vendor/gimli/src/read/loclists.rs
@@ -24,7 +24,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_loc` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugLoc, LittleEndian};
@@ -70,7 +70,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_loclists` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugLocLists, LittleEndian};
diff --git a/vendor/gimli/src/read/mod.rs b/vendor/gimli/src/read/mod.rs
index 7291f3b96..3110957c2 100644
--- a/vendor/gimli/src/read/mod.rs
+++ b/vendor/gimli/src/read/mod.rs
@@ -48,7 +48,7 @@
//!
//! * [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
//!
-//! * [`ddbug`](https://github.com/philipc/ddbug), a utility giving insight into
+//! * [`ddbug`](https://github.com/gimli-rs/ddbug), a utility giving insight into
//! code generation by making debugging information readable
//!
//! * [`dwprod`](https://github.com/fitzgen/dwprod), a tiny utility to list the
diff --git a/vendor/gimli/src/read/op.rs b/vendor/gimli/src/read/op.rs
index 2ca6247bc..88ea20297 100644
--- a/vendor/gimli/src/read/op.rs
+++ b/vendor/gimli/src/read/op.rs
@@ -707,7 +707,13 @@ where
}
constants::DW_OP_stack_value => Ok(Operation::StackValue),
constants::DW_OP_implicit_pointer | constants::DW_OP_GNU_implicit_pointer => {
- let value = bytes.read_offset(encoding.format)?;
+ let value = if encoding.version == 2 {
+ bytes
+ .read_address(encoding.address_size)
+ .and_then(Offset::from_u64)?
+ } else {
+ bytes.read_offset(encoding.format)?
+ };
let byte_offset = bytes.read_sleb128()?;
Ok(Operation::ImplicitPointer {
value: DebugInfoOffset(value),
@@ -2738,6 +2744,19 @@ mod tests {
},
encoding8(),
);
+
+ check_op_parse(
+ |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
+ &Operation::ImplicitPointer {
+ value: DebugInfoOffset(0x1234_5678),
+ byte_offset: 0x123,
+ },
+ Encoding {
+ format: Format::Dwarf32,
+ version: 2,
+ address_size: 8,
+ },
+ )
}
}
diff --git a/vendor/gimli/src/read/pubnames.rs b/vendor/gimli/src/read/pubnames.rs
index f05861f70..e8b7e5528 100644
--- a/vendor/gimli/src/read/pubnames.rs
+++ b/vendor/gimli/src/read/pubnames.rs
@@ -58,7 +58,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_pubnames` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugPubNames, LittleEndian};
diff --git a/vendor/gimli/src/read/pubtypes.rs b/vendor/gimli/src/read/pubtypes.rs
index 0226e84d4..6723b4222 100644
--- a/vendor/gimli/src/read/pubtypes.rs
+++ b/vendor/gimli/src/read/pubtypes.rs
@@ -58,7 +58,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_pubtypes` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugPubTypes, LittleEndian};
diff --git a/vendor/gimli/src/read/rnglists.rs b/vendor/gimli/src/read/rnglists.rs
index dd68083ac..d8d49042f 100644
--- a/vendor/gimli/src/read/rnglists.rs
+++ b/vendor/gimli/src/read/rnglists.rs
@@ -24,7 +24,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_ranges` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugRanges, LittleEndian};
@@ -70,7 +70,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_rnglists`
/// section and present it as a `&[u8]` slice. That means using some ELF
- /// loader on Linux, a Mach-O loader on OSX, etc.
+ /// loader on Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugRngLists, LittleEndian};
diff --git a/vendor/gimli/src/read/str.rs b/vendor/gimli/src/read/str.rs
index dce8016af..c6b87d8f9 100644
--- a/vendor/gimli/src/read/str.rs
+++ b/vendor/gimli/src/read/str.rs
@@ -22,7 +22,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_str` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugStr, LittleEndian};
@@ -214,7 +214,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_line_str` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugLineStr, LittleEndian};
diff --git a/vendor/gimli/src/read/unit.rs b/vendor/gimli/src/read/unit.rs
index 4766b2e84..670e55efd 100644
--- a/vendor/gimli/src/read/unit.rs
+++ b/vendor/gimli/src/read/unit.rs
@@ -93,7 +93,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_info` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugInfo, LittleEndian};
@@ -3086,7 +3086,7 @@ where
///
/// It is the caller's responsibility to read the `.debug_types` section and
/// present it as a `&[u8]` slice. That means using some ELF loader on
- /// Linux, a Mach-O loader on OSX, etc.
+ /// Linux, a Mach-O loader on macOS, etc.
///
/// ```
/// use gimli::{DebugTypes, LittleEndian};
diff --git a/vendor/gimli/src/read/util.rs b/vendor/gimli/src/read/util.rs
index dd2af8181..16eafdde4 100644
--- a/vendor/gimli/src/read/util.rs
+++ b/vendor/gimli/src/read/util.rs
@@ -180,7 +180,7 @@ impl<T> ArrayVec<Vec<T>> {
let slice = Box::leak(storage);
debug_assert!(len <= slice.len());
// SAFETY: valid elements.
- unsafe { Vec::from_raw_parts(slice.as_ptr() as _, len, slice.len()) }
+ unsafe { Vec::from_raw_parts(slice.as_mut_ptr() as *mut T, len, slice.len()) }
}
}
diff --git a/vendor/gimli/src/read/value.rs b/vendor/gimli/src/read/value.rs
index fc8c355a9..6f43ebb26 100644
--- a/vendor/gimli/src/read/value.rs
+++ b/vendor/gimli/src/read/value.rs
@@ -1,7 +1,5 @@
//! Definitions for values used in DWARF expressions.
-use core::mem;
-
use crate::constants;
#[cfg(feature = "read")]
use crate::read::{AttributeValue, DebuggingInformationEntry};
diff --git a/vendor/gimli/src/write/cfi.rs b/vendor/gimli/src/write/cfi.rs
index c58eb1b1d..718cb69ad 100644
--- a/vendor/gimli/src/write/cfi.rs
+++ b/vendor/gimli/src/write/cfi.rs
@@ -239,7 +239,7 @@ impl CommonInformationEntry {
}
if let Some((eh_pe, address)) = self.personality {
w.write_u8(eh_pe.0)?;
- w.write_eh_pointer(address, constants::DW_EH_PE_absptr, encoding.address_size)?;
+ w.write_eh_pointer(address, eh_pe, encoding.address_size)?;
}
if self.fde_address_encoding != constants::DW_EH_PE_absptr {
w.write_u8(self.fde_address_encoding.0)?;
@@ -888,6 +888,19 @@ mod tests {
fde4.lsda = Some(Address::Constant(0x4400));
frames.add_fde(cie2_id, fde4.clone());
+ let mut cie3 = CommonInformationEntry::new(encoding, 1, 8, X86_64::RA);
+ cie3.fde_address_encoding = constants::DW_EH_PE_pcrel;
+ cie3.lsda_encoding = Some(constants::DW_EH_PE_pcrel);
+ cie3.personality = Some((constants::DW_EH_PE_pcrel, Address::Constant(0x1235)));
+ cie3.signal_trampoline = true;
+ let cie3_id = frames.add_cie(cie3.clone());
+ assert_ne!(cie2_id, cie3_id);
+ assert_eq!(cie3_id, frames.add_cie(cie3.clone()));
+
+ let mut fde5 = FrameDescriptionEntry::new(Address::Constant(0x5000), 0x50);
+ fde5.lsda = Some(Address::Constant(0x5500));
+ frames.add_fde(cie3_id, fde5.clone());
+
// Test writing `.debug_frame`.
let mut debug_frame = DebugFrame::from(EndianVec::new(LittleEndian));
frames.write_debug_frame(&mut debug_frame).unwrap();
diff --git a/vendor/gimli/src/write/op.rs b/vendor/gimli/src/write/op.rs
index d1cacb356..c70eec2dd 100644
--- a/vendor/gimli/src/write/op.rs
+++ b/vendor/gimli/src/write/op.rs
@@ -778,7 +778,11 @@ impl Operation {
} else {
w.write_u8(constants::DW_OP_GNU_implicit_pointer.0)?;
}
- let size = encoding.format.word_size();
+ let size = if encoding.version == 2 {
+ encoding.address_size
+ } else {
+ encoding.format.word_size()
+ };
match entry {
Reference::Symbol(symbol) => {
w.write_reference(symbol, size)?;
diff --git a/vendor/gimli/tests/convert_self.rs b/vendor/gimli/tests/convert_self.rs
index ec8b592d3..7c069ebd6 100644
--- a/vendor/gimli/tests/convert_self.rs
+++ b/vendor/gimli/tests/convert_self.rs
@@ -146,7 +146,7 @@ fn test_convert_eh_frame() {
.write_eh_frame(&mut write_eh_frame)
.expect("Should write eh_frame information");
let eh_frame = write_eh_frame.slice();
- assert_eq!(eh_frame.len(), 147152);
+ assert_eq!(eh_frame.len(), 147144);
// Convert new section
let mut eh_frame = read::EhFrame::new(&eh_frame, LittleEndian);
diff --git a/vendor/handlebars/.cargo-checksum.json b/vendor/handlebars/.cargo-checksum.json
index d41808a41..b1031c230 100644
--- a/vendor/handlebars/.cargo-checksum.json
+++ b/vendor/handlebars/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"ab776bc63c83489640577a611f7df181de9a3191bf6e5fb449012fd5f6b5e770","Cargo.lock":"fb81e47543e26596ba74d5c165e26f70ec1532911dd638dc6bee65e572b09182","Cargo.toml":"5c6beb2539b6d5e038a5beeead3ed4c044b9be7fdcd4fab60b5a16ce31121bdf","LICENSE":"63b308fad3db82dc12067a8d7ff4b672fae97d12d0b4b3bb59179e27d640b3a4","README.md":"e9dfd89edf514c3613b5b2f47c05f2ba48bf1c9afee8eca1ba395887c8a85c9d","benches/bench.rs":"276ac8c581db35dbdc00e9e4cc1e2e1940fe95522a8f5a19ab088a2c68da61ed","build-wasm.sh":"9f7226d7d0768fe0fba97f698642a4c13a600468ba7d57abcfad9285efd9f4ce","examples/decorator.rs":"010762d337c64a8ade120c66ccb97ac176653d2fc1265c6f77c35d2a7693176f","examples/decorator/template.hbs":"76fd24f08b28b469529f4727321c7cc940198abb5c1aa24d7a6dd2ab42bdda66","examples/dev_mode.rs":"8e28b0f354e14006481faba76f32401a18476472b2e4c9faeea54f222980a9ba","examples/dev_mode/template.hbs":"4a5e1b81565572e26986d890e4a431953b81893a99ce07cef303e366dd84243c","examples/error.rs":"85219ee57a7bc739185862d04c7eff203743ddf730b940f92492894e3ebb5746","examples/error/error.hbs":"4e8fac806d444a5bc41436fe0a51b4d7850c7645f8996db7a99a821c88622eef","examples/error/template.hbs":"48313b522ddb0dd4285874b96d1b705b841dc141514f440790e904a262955951","examples/partials.rs":"e102f0bdacb80a08ac9ae3c92c415991095a1a2142d55420457706823a67fba0","examples/partials/base0.hbs":"6674275ef68faaeab8a4128da0983c9d732d7552f1791c2e3563fa8c5c66fb5a","examples/partials/base1.hbs":"97b1089705f5a21a6f344190e26133d920d56d4a7fdc1fa2fb7359a720bfe182","examples/partials/template2.hbs":"6f83bc48b774a3b83f9ce5a54bf014fb03514720f9e32834dc68000d06a17618","examples/quick.rs":"96df03fc1742504afae34c6da9da05206adc41f771406da2825b41725329cb2d","examples/render.rs":"eadc1aff65d96c7f95c948fbccfb79981276075f83e19a22214fe0772ef17496","examples/render/template.hbs":"2512ef3362379633790985fe2c40e7efab3ad0f431b7cbec5b7cc644dbbef8f5","examples/render_cli/simple.hbs":"a2e0df51e7c1a25c4e9e1bbe0f4911c7c86200d358fc6c9195b61e89adddc970","examples/render_file.rs":"f5b8e788ac6a71a170c5b315120e8779896df8d9b290fb3d785f51307f5d3c45","examples/render_file/template.hbs":"8ec8d0b61a996391ad7f8b6a914f84d0ac06c62e6d7c9c5fa054ca5e2c64a52e","examples/script.rs":"df869a15d6cd8c478f74582018c54e20545b9451e84cdec2f8bb71c31a618da0","examples/script/goals.rhai":"d756fd7d39f11fae148a6e11d23160da0cdac91c29f716dcb854c07a7db09c80","examples/script/template.hbs":"1f39785157a112bc5c4e94db1361c45a73b024bc8bd0fea0a9d5da8102afb310","profile.sh":"b8e80c59bc12fca93daa67c09001c1c045e594e532831cc957c9ac313f8b2390","release.toml":"968ff7e0a0f8b99d0b91a06cb007fcee55427ccbd05012b46202829336287151","rustfmt.toml":"8e99dabd6aadb112f9f9ed8709e7388b57bf43d19cd08342c093c870534a3f97","src/block.rs":"da38a572a95c3858685e4af82a7e1920c6b3311acf8c118c53c8531b091de391","src/cli.rs":"63aed9a8fb2135ee03bd2b49330be20d2018fe3c36265c14dbdc0da9b73cb6d0","src/context.rs":"5007324a0655daa994e1b64f0eed160e67e4a4d8fb02d21eca4c549d5dcea7c2","src/decorators/inline.rs":"73b8ba6ed98dbf8b3bca228796f47c9139d49f1a1c8d5b4603cc6354098b56c2","src/decorators/mod.rs":"322d4d692331a1e3a2806780cbe1e7a3a82b343486f1182d2e8a017a8bf11085","src/error.rs":"7da2635fdb0005437d8c4a7cb889336d0039665d7627544f600d473f5b90eab8","src/grammar.pest":"aed7ff83953551d48e4e94edc25d51f7e418ec79b62df1ca8f7e728444430d0b","src/grammar.rs":"848d1b56bc1d887e8c42836c37d41b2a634ec6eb9e3880be7dde31d84a38460d","src/helpers/block_util.rs":"11a295215f9c0d14b89f97161468425405386214f050bad07683669a162f9aa1","src/helpers/helper_each.rs":"75b536114f954287936e9f02a54b0c182144e2e6a4ad0970e66cc644cc8f3a0f","src/helpers/helper_extras.rs":"0575a1518eba51cafe91ec2b09666e1c987c9a9bc98cb00193d1e0d203a8b681","src/helpers/helper_if.rs":"37c81b7000948f601398b7163b37397020d191642021077bd7eb15c181632d32","src/helpers/helper_log.rs":"272f7c1f873b97974cce156c04281f2bd8c44ccc885b4c59dd2b43e8d7cc6ef6","src/helpers/helper_lookup.rs":"a9f000e36d0e9339930b3d94dabd4f123cdbdaa85e8d77d15e4a772a99ffe9d4","src/helpers/helper_raw.rs":"6b0b5b3774a1d5c3ebf30b1e0b8cac825f6ffb8a18cb9e08bd40786258e4b597","src/helpers/helper_with.rs":"9964ec02b56ad8fb6f3aa9abb535c0d3f6f2cf3eaeba59a5afd8687ea6df2209","src/helpers/mod.rs":"31eefbd1f302b852e43a3aa8432ce4faad04db37eba7fc1bfa8cf9c25967b899","src/helpers/scripting.rs":"6b9e7e08bdbf3e2716bb82b69e0f10efd4de1174842742215aba18fb2cc507e2","src/json/mod.rs":"ef2fc8fe98e9761e2e2a4b2d2293bb29cdb689db2f44f939fc61c48c6b52f0a7","src/json/path.rs":"818bc5f002839a529ffe5d5f8eddd815ac3808a5f9ce3bac79f1f71f5702599b","src/json/value.rs":"390ea4fa8b5131a3d00ff1c80d06359220f16d851a5e836192026ea32acbb02e","src/lib.rs":"ecbb4099b2c0cc77e746083181a8ed32b7f76671aa8e54d079eb4196b24d167c","src/local_vars.rs":"91d3a16bbfabe2eccecaa9a0dd866ebe88d70ce438d2f18581d1b7d231ba0644","src/macros.rs":"86eed922319644176e8464023455b78440b8e5d0d9b13a0ce61b2edf0f10984e","src/output.rs":"10c28874f78cddba70b24eb984a849c7750b207ac605f2aa46f2abe02846b3a2","src/partial.rs":"ddcd49436b6c653b3e5db44a997c5cd9006755dd1e6c07aa5996fa495aecd382","src/registry.rs":"56d613a72ca9e4ad15953cf5b74bf6df912e81f8f008780bebe93375fb1569ed","src/render.rs":"cec805cd1396bc87f1c2bcd9d45b8c6236a65cb99c6d45f14199fab99b94d38d","src/sources.rs":"46989eb76f36edff9dcb5d27488e8bd9c7ff1749f368a70e855f4808c58d7bcf","src/support.rs":"b3d1d99440182548ff9bfcffbd9a7e08507f740ed68382f9c74ab0a92a79eab7","src/template.rs":"61625e52f43c9df92fce25f626db6c61b31a42310c06a8158b13b9f960339e12","src/util.rs":"2ebc845de5ca47455442a1b6bd664565a52e29928e82c526fbfe56ed5196410f","tests/block_context.rs":"4dce11312d2b6c0c5c2f3104516e5567e5a370611e08f4055fa3653293580385","tests/data_helper.rs":"a7f9d1d42d5415ba1dba459840067acc1294f6f6057d9a5a13d9f7e19469e850","tests/escape.rs":"a4bd25c4268a306dc09dc17806f86895c4932753a585219902f0dd85c7e65cba","tests/helper_function_lifetime.rs":"635cbd0b44742539bdf36e803a19c6a1a698399f8b765415d53f28df1acfbc2b","tests/helper_macro.rs":"4660cfb782c03e70f536bedbb2ed5afed5e8fe841d77c1812e4b2ef55d81a6a6","tests/helper_with_space.rs":"c64952ea031f964e558cb323df1bf731bb7c0bf7b226142cea61afa2fd4efbfd","tests/root_var.rs":"fda5b30bac1e692fb010f9f98e052d5a525420fece9dcc3821a4e5aeee3a8841","tests/subexpression.rs":"b36ab31adf45272ca984c0c5ed9497820ca072a8805444d69bd089b766786bb5","tests/template_names.rs":"4bbe6b48c974ae7ea1e61806794d846e2f0e8505e1568c5305fa2364dceef68a","wasm/LICENSE":"63b308fad3db82dc12067a8d7ff4b672fae97d12d0b4b3bb59179e27d640b3a4","wasm/README.md":"d67bad452550d34e9317fb8f4884b8bc07939fbb0dfdcf1be6bfce52a6851fa6","wasm/wapm.toml":"bdb286ccaa18c5c8aa0d2db25755aba9b0e3e83a59fc4d2334c1854933000ea1"},"package":"72a0ffab8c36d0436114310c7e10b59b3307e650ddfabf6d006028e29a70c6e6"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"1c33d57ecdf48bcc7011c1e7306d05359a3fca61f3c48324e5cb5b378d406ef6","Cargo.lock":"81ba21eaf5647124881eacf240b9c34ae15c4f3b56072d7ff3ec665f269c3843","Cargo.toml":"afbdf3fe79ae8e5a434f6cb126f3441e8750a499f2b159226cd86e48e4d5424e","LICENSE":"63b308fad3db82dc12067a8d7ff4b672fae97d12d0b4b3bb59179e27d640b3a4","README.md":"ae8924a77607ab2439ef2cb87a93c49b51a4da228ea144bc847ec6d2a4acffba","benches/bench.rs":"276ac8c581db35dbdc00e9e4cc1e2e1940fe95522a8f5a19ab088a2c68da61ed","build-wasm.sh":"9f7226d7d0768fe0fba97f698642a4c13a600468ba7d57abcfad9285efd9f4ce","examples/decorator.rs":"010762d337c64a8ade120c66ccb97ac176653d2fc1265c6f77c35d2a7693176f","examples/decorator/template.hbs":"76fd24f08b28b469529f4727321c7cc940198abb5c1aa24d7a6dd2ab42bdda66","examples/dev_mode.rs":"7c8cebbc56da3e834688719f5c10df1c372c059259e40df8534c79a0dda01aab","examples/dev_mode/template.hbs":"4a5e1b81565572e26986d890e4a431953b81893a99ce07cef303e366dd84243c","examples/error.rs":"6f3d4dc945628778d3ef63dccdc7abbf367e214a5ff62a5dcbeb11d8f34317d7","examples/error/error.hbs":"4e8fac806d444a5bc41436fe0a51b4d7850c7645f8996db7a99a821c88622eef","examples/error/template.hbs":"48313b522ddb0dd4285874b96d1b705b841dc141514f440790e904a262955951","examples/helper_macro.rs":"ca0c7b7a45e8f3f8c7fe25d59a5bb3189b067189dab642bfb02dda416f20774d","examples/partials.rs":"0b3ee03668338b9900705b1162ac1f602255d4b691d1827cb603efff318d3166","examples/partials/base0.hbs":"6674275ef68faaeab8a4128da0983c9d732d7552f1791c2e3563fa8c5c66fb5a","examples/partials/base1.hbs":"97b1089705f5a21a6f344190e26133d920d56d4a7fdc1fa2fb7359a720bfe182","examples/partials/template2.hbs":"6f83bc48b774a3b83f9ce5a54bf014fb03514720f9e32834dc68000d06a17618","examples/quick.rs":"96df03fc1742504afae34c6da9da05206adc41f771406da2825b41725329cb2d","examples/render.rs":"eadc1aff65d96c7f95c948fbccfb79981276075f83e19a22214fe0772ef17496","examples/render/template.hbs":"2512ef3362379633790985fe2c40e7efab3ad0f431b7cbec5b7cc644dbbef8f5","examples/render_cli/simple.hbs":"a2e0df51e7c1a25c4e9e1bbe0f4911c7c86200d358fc6c9195b61e89adddc970","examples/render_file.rs":"f5b8e788ac6a71a170c5b315120e8779896df8d9b290fb3d785f51307f5d3c45","examples/render_file/template.hbs":"8ec8d0b61a996391ad7f8b6a914f84d0ac06c62e6d7c9c5fa054ca5e2c64a52e","examples/script.rs":"5e16423dc4c8ae0e383f0d8b9e1a652850fa5e48dbc57cca3757661c3e0476bb","examples/script/goals.rhai":"d756fd7d39f11fae148a6e11d23160da0cdac91c29f716dcb854c07a7db09c80","examples/script/template.hbs":"1f39785157a112bc5c4e94db1361c45a73b024bc8bd0fea0a9d5da8102afb310","profile.sh":"b8e80c59bc12fca93daa67c09001c1c045e594e532831cc957c9ac313f8b2390","release.toml":"d1c1f8e31be9268666c07a2c3f244e73c3db7474a2a64218fac71f7ad1f20b5d","rustfmt.toml":"8e99dabd6aadb112f9f9ed8709e7388b57bf43d19cd08342c093c870534a3f97","src/block.rs":"da38a572a95c3858685e4af82a7e1920c6b3311acf8c118c53c8531b091de391","src/cli.rs":"63aed9a8fb2135ee03bd2b49330be20d2018fe3c36265c14dbdc0da9b73cb6d0","src/context.rs":"6d594b5c93cdc1e8ee08c3858f50dddc312eaa20b9ea3f4c14906bc6ebee318f","src/decorators/inline.rs":"73b8ba6ed98dbf8b3bca228796f47c9139d49f1a1c8d5b4603cc6354098b56c2","src/decorators/mod.rs":"a9189648fd11609fc6681d6df4af0deb1a1958e12c447485a0455d7e67f70fa3","src/error.rs":"a101458e111478fd6c3749910ca7af8afa973d51eb9a4bd13569e66d0aa8ae8f","src/grammar.pest":"a6754e1b61ba282f325af30f907e9e175ad21f0bec322d42e6f975a6f3bf2c7e","src/grammar.rs":"d572c6507f673c1e5c7c018f485672e6c10671d6749d0d9182f26d62e2e1537e","src/helpers/block_util.rs":"11a295215f9c0d14b89f97161468425405386214f050bad07683669a162f9aa1","src/helpers/helper_each.rs":"827de9ba0224cdd361ce52f02a9f301e879d738d6837672798517b83db68b331","src/helpers/helper_extras.rs":"0575a1518eba51cafe91ec2b09666e1c987c9a9bc98cb00193d1e0d203a8b681","src/helpers/helper_if.rs":"2fe6cc5f3b44a42611d02137e5a11466850d44b6a41a803e7a9268f3a545e487","src/helpers/helper_log.rs":"272f7c1f873b97974cce156c04281f2bd8c44ccc885b4c59dd2b43e8d7cc6ef6","src/helpers/helper_lookup.rs":"34e57dbe6a4c65afa8978d32db1b9adfb783990ec951b4833a9986a86cb38ff1","src/helpers/helper_raw.rs":"6b0b5b3774a1d5c3ebf30b1e0b8cac825f6ffb8a18cb9e08bd40786258e4b597","src/helpers/helper_with.rs":"554373544f1aff16799cde954e37a945e26b452414436f612e12b538ec8e1893","src/helpers/mod.rs":"f8c24abb40739935225acdfad97f4bc808eb1fec77d09fda1ff5779b632b7650","src/helpers/scripting.rs":"3716d77e6e11993741885a15dcddaedc11e076f0b5e9a0b844416d3fbb0a834c","src/json/mod.rs":"ef2fc8fe98e9761e2e2a4b2d2293bb29cdb689db2f44f939fc61c48c6b52f0a7","src/json/path.rs":"49b821765da4aa305e51478527898ad4038c3952c7f07c639e8b71a59732e34a","src/json/value.rs":"390ea4fa8b5131a3d00ff1c80d06359220f16d851a5e836192026ea32acbb02e","src/lib.rs":"9374528d680b4cefdfcef945529a5f9c6b03b22ba09503135cc18914ff621d56","src/local_vars.rs":"91d3a16bbfabe2eccecaa9a0dd866ebe88d70ce438d2f18581d1b7d231ba0644","src/macros.rs":"0e2d174bb155da5df279ba15ef65b92519ca890949acc8231c72196bc8364a7c","src/output.rs":"f85acedeb124a1d344c5f73b309bd32d925de5dbed701b5fdebcadbd42f3c7ad","src/partial.rs":"6362967d77d29eea5ba7000ec741774288f08afe7c685e9d28b801b603599401","src/registry.rs":"388ebf2e28734963cd04f6622109e009ab22f7377236f6042aa5441875b22cef","src/render.rs":"17594a82a37295d4887945f18dc12eebe261094078e699b53ff6b7e193fcf986","src/sources.rs":"46989eb76f36edff9dcb5d27488e8bd9c7ff1749f368a70e855f4808c58d7bcf","src/support.rs":"f9328a0674984fcc3c6e93e8a43ec63bf9b502176283f60a2d6ceb15ca34840a","src/template.rs":"5e275cd2adb00e4238607e5e6d7e7db209a1233b813df77e30ccc5df1991bc01","src/util.rs":"2ebc845de5ca47455442a1b6bd664565a52e29928e82c526fbfe56ed5196410f","tests/block_context.rs":"4dce11312d2b6c0c5c2f3104516e5567e5a370611e08f4055fa3653293580385","tests/data_helper.rs":"a7f9d1d42d5415ba1dba459840067acc1294f6f6057d9a5a13d9f7e19469e850","tests/embed.rs":"de85f16a7a0372cc0e150abe3487ae8180598532e4d73b05b4b107e7e4a0b05e","tests/escape.rs":"7b643675b7884a497d7008cda6e51809efea94a79d25996564b7771cfdbf1709","tests/helper_function_lifetime.rs":"635cbd0b44742539bdf36e803a19c6a1a698399f8b765415d53f28df1acfbc2b","tests/helper_macro.rs":"959cc218fa47c8b30835412c5b6b4f76c8387de49e9e2c73baa9a788f9564361","tests/helper_with_space.rs":"0aee174428b799998a9994b008485373a1b084bf4ea49ed455c890eb627f1ac1","tests/root_var.rs":"fda5b30bac1e692fb010f9f98e052d5a525420fece9dcc3821a4e5aeee3a8841","tests/subexpression.rs":"b36ab31adf45272ca984c0c5ed9497820ca072a8805444d69bd089b766786bb5","tests/template_names.rs":"4bbe6b48c974ae7ea1e61806794d846e2f0e8505e1568c5305fa2364dceef68a","tests/templates/hello.hbs":"4aca52692d2247a22c46856dbfd439a5c4edc47237e488ece5d01e9d8030e882","tests/whitespace.rs":"1cadfbe9cd8e2dd4ca7759fdcaf7fd05116b5e9ec59ca67722c41732fe89dfa3","wasm/LICENSE":"63b308fad3db82dc12067a8d7ff4b672fae97d12d0b4b3bb59179e27d640b3a4","wasm/README.md":"d67bad452550d34e9317fb8f4884b8bc07939fbb0dfdcf1be6bfce52a6851fa6","wasm/wapm.toml":"bdb286ccaa18c5c8aa0d2db25755aba9b0e3e83a59fc4d2334c1854933000ea1"},"package":"360d9740069b2f6cbb63ce2dbaa71a20d3185350cbb990d7bebeb9318415eb17"} \ No newline at end of file
diff --git a/vendor/handlebars/CHANGELOG.md b/vendor/handlebars/CHANGELOG.md
index 62045f53e..c3b79a657 100644
--- a/vendor/handlebars/CHANGELOG.md
+++ b/vendor/handlebars/CHANGELOG.md
@@ -1,5 +1,80 @@
# Change Log
+## [4.3.3](https://github.com/sunng87/handlebars-rust/compare/4.3.2...4.3.3) - 2022-07-20
+
+* [Fixed] Disable partial expression indentation with `{{~> partial}}` to
+ bring behavior closer in line with original javascript version. [#518]
+* [Fixed] Support for using partial context together with partial parameters
+ [#520]
+
+## [4.3.2](https://github.com/sunng87/handlebars-rust/compare/4.3.1...4.3.2) - 2022-07-14
+
+* [Added] Render functions that reuse `Context` for custom `std::io::Write`:
+ `render_with_context_to_write` and `render_template_with_context_to_write`
+
+## [4.3.1](https://github.com/sunng87/handlebars-rust/compare/4.3.0...4.3.1) - 2022-06-09
+
+* [Added] Added support for `{{~{variable}~}}` syntax [#509]
+
+## [4.3.0](https://github.com/sunng87/handlebars-rust/compare/4.2.2...4.3.0) - 2022-05-18
+
+* [Changed] update MSRV to 1.57 as rhai requires
+* [Fixed] Reimplemented indent support for partial expression `{{>
+ partial}}`, which is introduced in 4.2.0. The new implementation is
+ aligned with original javascript version, that every text line
+ generated from partial are indented as `{{> partial}}`
+ does. `prevent_indent` will turn-off this feature. [#505]
+* [Changed] changed error support library from quick_error to
+ thiserror
+
+## [4.2.2](https://github.com/sunng87/handlebars-rust/compare/4.2.1...4.2.2) - 2022-03-09
+
+* [Fixed] Block param scope leaked into partials [#496]
+* [Changed] Use Rust 2021 edition and update MSRV to 1.56
+
+## [4.2.1](https://github.com/sunng87/handlebars-rust/compare/4.2.0...4.2.1) - 2022-01-17
+
+* [Fixed] Nested partial `@partial-block` referencing issue [#488]
+* [Fixed] Docs generation on docs.rs for `rust-embed` feature
+
+## [4.2.0](https://github.com/sunng87/handlebars-rust/compare/4.1.6...4.2.0) - 2022-01-05
+
+* [Added] RustEmbed support for loading templates from [#484]
+* [Fixed] Parser support for variables begins with digit [#479]
+* [Changed] Keep indent whitespaces for partial expression `{{>
+ partial}}` as default in handlebarsjs. A new option `prevent_indent`
+ is provided on `Handlebars` to turn off this behaviour. [#486]
+* [Changed] Update MSRV to 1.51 due to dependency changes
+
+## [4.1.6](https://github.com/sunng87/handlebars-rust/compare/4.1.5...4.1.6) - 2021-12-03
+
+* [Added] Create `Context` from owned `serde_json::Value` [#477]
+
+## [4.1.5](https://github.com/sunng87/handlebars-rust/compare/4.1.4...4.1.5) - 2021-11-17
+
+* [Fixed] Single-quote string literal is supported, again [#475]
+
+## [4.1.4](https://github.com/sunng87/handlebars-rust/compare/4.1.3...4.1.4) - 2021-11-06
+
+* [Fixed] Corrected empty line stripping strategy [#473]
+
+## [4.1.3](https://github.com/sunng87/handlebars-rust/compare/4.1.2...4.1.3) - 2021-09-10
+
+* [Added] `@last` variable for `each` block with object [#466]
+* [Fixed] Missing whitespaces behind expression [#468]
+
+## [4.1.2](https://github.com/sunng87/handlebars-rust/compare/4.1.1...4.1.2) - 2021-08-11
+
+* [Added] Support for generic types in `handlebars_helper!`.
+* [Added] Getter and setter for rhai `Engine` from registry.
+* [Fixed] Improve doc for `dev_mode` that it has to be enabled before
+ adding templates.
+
+## [4.1.1](https://github.com/sunng87/handlebars-rust/compare/4.1.0...4.1.1) - 2021-07-31
+
+* [Changed] Update rhai to 1.0 [#455]
+* [Fixed] Empty line stripping for partial include statement, and other corner cases [#458]
+
## [4.1.0](https://github.com/sunng87/handlebars-rust/compare/4.0.1...4.1.0) - 2021-07-05
* [Added] export `StringOutput` as requested in #442
diff --git a/vendor/handlebars/Cargo.lock b/vendor/handlebars/Cargo.lock
index 8fc6db06f..27cc86f9b 100644
--- a/vendor/handlebars/Cargo.lock
+++ b/vendor/handlebars/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
-version = "0.15.2"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a"
+checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
]
@@ -19,22 +19,11 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877"
-dependencies = [
- "getrandom 0.2.3",
- "once_cell",
- "version_check",
-]
-
-[[package]]
-name = "ahash"
-version = "0.7.4"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
- "getrandom 0.2.3",
+ "getrandom",
"once_cell",
"version_check",
]
@@ -50,9 +39,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.41"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"
+checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "arrayvec"
@@ -64,6 +53,12 @@ dependencies = [
]
[[package]]
+name = "ascii"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109"
+
+[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -76,19 +71,19 @@ dependencies = [
[[package]]
name = "autocfg"
-version = "1.0.1"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backtrace"
-version = "0.3.60"
+version = "0.3.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282"
+checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
dependencies = [
"addr2line",
"cc",
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
"miniz_oxide",
"object",
@@ -96,16 +91,10 @@ dependencies = [
]
[[package]]
-name = "base64"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
-
-[[package]]
name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
@@ -125,7 +114,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
- "generic-array 0.14.4",
+ "generic-array 0.14.5",
]
[[package]]
@@ -139,9 +128,9 @@ dependencies = [
[[package]]
name = "bstr"
-version = "0.2.16"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
+checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
@@ -150,20 +139,10 @@ dependencies = [
]
[[package]]
-name = "buf_redux"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
-dependencies = [
- "memchr",
- "safemem",
-]
-
-[[package]]
name = "bumpalo"
-version = "3.7.0"
+version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
+checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
[[package]]
name = "byte-tools"
@@ -173,9 +152,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "bytemuck"
-version = "1.7.0"
+version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9966d2ab714d0f785dbac0a0396251a35280aeb42413281617d0209ab4898435"
+checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
[[package]]
name = "byteorder"
@@ -185,48 +164,42 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
-
-[[package]]
-name = "bytes"
-version = "1.0.1"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cast"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374"
+checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
dependencies = [
"rustc_version",
]
[[package]]
name = "cc"
-version = "1.0.68"
+version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
-version = "0.1.10"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "cfg-if"
-version = "1.0.0"
+name = "chunked_transfer"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
[[package]]
name = "clap"
-version = "2.33.3"
+version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"bitflags",
"textwrap",
@@ -234,36 +207,44 @@ dependencies = [
]
[[package]]
+name = "cmake"
+version = "0.1.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
+dependencies = [
+ "cc",
+]
+
+[[package]]
name = "cpp_demangle"
-version = "0.3.2"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44919ecaf6f99e8e737bc239408931c9a01e9a6c74814fee8242dd2506b65390"
+checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f"
dependencies = [
- "cfg-if 1.0.0",
- "glob",
+ "cfg-if",
]
[[package]]
name = "cpufeatures"
-version = "0.1.4"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
+checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
dependencies = [
"libc",
]
[[package]]
name = "criterion"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
+checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
dependencies = [
"atty",
"cast",
"clap",
"criterion-plot",
"csv",
- "itertools 0.10.1",
+ "itertools",
"lazy_static",
"num-traits",
"oorandom",
@@ -280,42 +261,43 @@ dependencies = [
[[package]]
name = "criterion-plot"
-version = "0.4.3"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
+checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
dependencies = [
"cast",
- "itertools 0.9.0",
+ "itertools",
]
[[package]]
name = "crossbeam-channel"
-version = "0.5.1"
+version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
+checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
+checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
-version = "0.9.5"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
+checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
dependencies = [
- "cfg-if 1.0.0",
+ "autocfg",
+ "cfg-if",
"crossbeam-utils",
"lazy_static",
"memoffset",
@@ -324,11 +306,11 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.5"
+version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
+checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"lazy_static",
]
@@ -340,7 +322,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
- "itoa",
+ "itoa 0.4.8",
"ryu",
"serde",
]
@@ -356,9 +338,9 @@ dependencies = [
[[package]]
name = "debugid"
-version = "0.7.2"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91cf5a8c2f2097e2a32627123508635d47ce10563d999ec1a95addf08b502ba"
+checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
dependencies = [
"uuid",
]
@@ -378,7 +360,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
- "generic-array 0.14.4",
+ "generic-array 0.14.5",
]
[[package]]
@@ -389,9 +371,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "env_logger"
-version = "0.8.4"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
dependencies = [
"atty",
"humantime",
@@ -407,88 +389,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
-name = "fixedbitset"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
-dependencies = [
- "matches",
- "percent-encoding",
-]
-
-[[package]]
-name = "futures"
-version = "0.3.15"
+name = "fastrand"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
+ "instant",
]
[[package]]
-name = "futures-channel"
-version = "0.3.15"
+name = "findshlibs"
+version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
+checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64"
dependencies = [
- "futures-core",
- "futures-sink",
+ "cc",
+ "lazy_static",
+ "libc",
+ "winapi",
]
[[package]]
-name = "futures-core"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
-
-[[package]]
-name = "futures-io"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
-
-[[package]]
-name = "futures-sink"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
-
-[[package]]
-name = "futures-task"
-version = "0.3.15"
+name = "fixedbitset"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
+checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e"
[[package]]
-name = "futures-util"
-version = "0.3.15"
+name = "form_urlencoded"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
- "autocfg",
- "futures-core",
- "futures-sink",
- "futures-task",
- "pin-project-lite",
- "pin-utils",
- "slab",
+ "matches",
+ "percent-encoding",
]
[[package]]
@@ -502,9 +436,9 @@ dependencies = [
[[package]]
name = "generic-array"
-version = "0.14.4"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
dependencies = [
"typenum",
"version_check",
@@ -512,199 +446,77 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
-dependencies = [
- "cfg-if 1.0.0",
- "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.3"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
+checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
- "wasi 0.10.2+wasi-snapshot-preview1",
+ "wasi",
]
[[package]]
name = "gimli"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
-
-[[package]]
-name = "glob"
-version = "0.3.0"
+version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-
-[[package]]
-name = "h2"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726"
-dependencies = [
- "bytes 1.0.1",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
+checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]]
name = "half"
-version = "1.7.1"
+version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
+checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "handlebars"
-version = "4.1.0"
+version = "4.3.3"
dependencies = [
"criterion",
"env_logger",
"log",
- "maplit",
"pest",
"pest_derive",
"pprof",
- "quick-error 2.0.1",
"rhai",
+ "rust-embed",
"serde",
"serde_derive",
"serde_json",
"tempfile",
- "tokio",
+ "thiserror",
+ "time",
+ "tiny_http",
"walkdir",
- "warp",
]
[[package]]
name = "hashbrown"
-version = "0.9.1"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
-
-[[package]]
-name = "headers"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855"
-dependencies = [
- "base64",
- "bitflags",
- "bytes 1.0.1",
- "headers-core",
- "http",
- "mime",
- "sha-1 0.9.6",
- "time",
-]
-
-[[package]]
-name = "headers-core"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
-dependencies = [
- "http",
-]
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
-version = "0.3.3"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
-dependencies = [
- "unicode-segmentation",
-]
+checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
-version = "0.1.18"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
-name = "http"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
-dependencies = [
- "bytes 1.0.1",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9"
-dependencies = [
- "bytes 1.0.1",
- "http",
- "pin-project-lite",
-]
-
-[[package]]
-name = "httparse"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
-
-[[package]]
-name = "httpdate"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
-
-[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
-name = "hyper"
-version = "0.14.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83"
-dependencies = [
- "bytes 1.0.1",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project-lite",
- "socket2",
- "tokio",
- "tower-service",
- "tracing",
- "want",
-]
-
-[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -717,9 +529,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "1.6.2"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
+checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
@@ -727,14 +539,14 @@ dependencies = [
[[package]]
name = "inferno"
-version = "0.10.6"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c3cbcc228d2ad2e99328c2b19f38d80ec387ca6a29f778e40e32ca9f25448c3"
+checksum = "16d4bde3a7105e59c66a4104cfe9606453af1c7a0eac78cb7d5bc263eb762a70"
dependencies = [
- "ahash 0.6.3",
+ "ahash",
"atty",
"indexmap",
- "itoa",
+ "itoa 1.0.1",
"lazy_static",
"log",
"num-format",
@@ -744,61 +556,40 @@ dependencies = [
]
[[package]]
-name = "input_buffer"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413"
-dependencies = [
- "bytes 1.0.1",
-]
-
-[[package]]
name = "instant"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
-dependencies = [
- "cfg-if 1.0.0",
-]
-
-[[package]]
-name = "itertools"
-version = "0.8.2"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
- "either",
+ "cfg-if",
]
[[package]]
name = "itertools"
-version = "0.9.0"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
"either",
]
[[package]]
-name = "itertools"
-version = "0.10.1"
+name = "itoa"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
-dependencies = [
- "either",
-]
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
-version = "0.4.7"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "js-sys"
-version = "0.3.51"
+version = "0.3.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
+checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
dependencies = [
"wasm-bindgen",
]
@@ -811,26 +602,27 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.97"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
+checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]]
name = "lock_api"
-version = "0.4.4"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
+checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
dependencies = [
+ "autocfg",
"scopeguard",
]
[[package]]
name = "log"
-version = "0.4.14"
+version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
]
[[package]]
@@ -841,81 +633,41 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matches"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "memchr"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
-name = "memmap"
-version = "0.7.0"
+name = "memmap2"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
+checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f"
dependencies = [
"libc",
- "winapi",
]
[[package]]
name = "memoffset"
-version = "0.6.4"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
-name = "mime"
-version = "0.3.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
-
-[[package]]
-name = "mime_guess"
-version = "2.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
-dependencies = [
- "mime",
- "unicase",
-]
-
-[[package]]
name = "miniz_oxide"
-version = "0.4.4"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
+checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
dependencies = [
"adler",
- "autocfg",
-]
-
-[[package]]
-name = "mio"
-version = "0.7.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
-dependencies = [
- "libc",
- "log",
- "miow",
- "ntapi",
- "winapi",
-]
-
-[[package]]
-name = "miow"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
-dependencies = [
- "winapi",
]
[[package]]
@@ -925,34 +677,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
-name = "multipart"
-version = "0.17.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4"
-dependencies = [
- "buf_redux",
- "httparse",
- "log",
- "mime",
- "mime_guess",
- "quick-error 1.2.3",
- "rand 0.7.3",
- "safemem",
- "tempfile",
- "twoway",
-]
-
-[[package]]
name = "nix"
-version = "0.17.0"
+version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
+checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9"
dependencies = [
"bitflags",
- "cc",
- "cfg-if 0.1.10",
+ "cfg-if",
"libc",
- "void",
]
[[package]]
@@ -962,57 +694,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
-name = "ntapi"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "num-format"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465"
dependencies = [
"arrayvec",
- "itoa",
+ "itoa 0.4.8",
]
[[package]]
name = "num-traits"
-version = "0.2.14"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
-version = "1.13.0"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "object"
-version = "0.25.3"
+version = "0.28.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7"
+checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.8.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
+checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "oorandom"
@@ -1034,27 +766,25 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "parking_lot"
-version = "0.11.1"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
+checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [
- "instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
-version = "0.8.3"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
+checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [
- "cfg-if 1.0.0",
- "instant",
+ "cfg-if",
"libc",
"redox_syscall",
"smallvec",
- "winapi",
+ "windows-sys",
]
[[package]]
@@ -1103,52 +833,20 @@ checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
- "sha-1 0.8.2",
+ "sha-1",
]
[[package]]
name = "petgraph"
-version = "0.5.1"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
+checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
-name = "pin-project"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
name = "plotters"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1163,91 +861,92 @@ dependencies = [
[[package]]
name = "plotters-backend"
-version = "0.3.0"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590"
+checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
[[package]]
name = "plotters-svg"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211"
+checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
dependencies = [
"plotters-backend",
]
[[package]]
name = "pprof"
-version = "0.3.20"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "937e4766a8d473f9dd3eb318c654dec77d6715a87ab50081d6e5cfceea73c105"
+checksum = "1bba88ee898c63351101af3e60c66c5398c517681ce533eef8caff10ecf11ec1"
dependencies = [
"backtrace",
+ "cfg-if",
+ "findshlibs",
"inferno",
- "lazy_static",
"libc",
"log",
"nix",
+ "once_cell",
"parking_lot",
"prost",
"prost-build",
"prost-derive",
+ "smallvec",
"symbolic-demangle",
"tempfile",
"thiserror",
]
[[package]]
-name = "ppv-lite86"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
-
-[[package]]
name = "proc-macro2"
-version = "1.0.27"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
+checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
dependencies = [
"unicode-xid",
]
[[package]]
name = "prost"
-version = "0.6.1"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
+checksum = "bc03e116981ff7d8da8e5c220e374587b98d294af7ba7dd7fda761158f00086f"
dependencies = [
- "bytes 0.5.6",
+ "bytes",
"prost-derive",
]
[[package]]
name = "prost-build"
-version = "0.6.1"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26"
+checksum = "65a1118354442de7feb8a2a76f3d80ef01426bd45542c8c1fdffca41a758f846"
dependencies = [
- "bytes 0.5.6",
+ "bytes",
+ "cfg-if",
+ "cmake",
"heck",
- "itertools 0.8.2",
+ "itertools",
+ "lazy_static",
"log",
"multimap",
"petgraph",
"prost",
"prost-types",
+ "regex",
"tempfile",
"which",
]
[[package]]
name = "prost-derive"
-version = "0.6.1"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
+checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc"
dependencies = [
"anyhow",
- "itertools 0.8.2",
+ "itertools",
"proc-macro2",
"quote",
"syn",
@@ -1255,130 +954,37 @@ dependencies = [
[[package]]
name = "prost-types"
-version = "0.6.1"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
+checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68"
dependencies = [
- "bytes 0.5.6",
+ "bytes",
"prost",
]
[[package]]
-name = "quick-error"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
-
-[[package]]
-name = "quick-error"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
-
-[[package]]
name = "quick-xml"
-version = "0.20.0"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26aab6b48e2590e4a64d1ed808749ba06257882b461d01ca71baeb747074a6dd"
+checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
-version = "1.0.9"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [
"proc-macro2",
]
[[package]]
-name = "rand"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
-dependencies = [
- "getrandom 0.1.16",
- "libc",
- "rand_chacha 0.2.2",
- "rand_core 0.5.1",
- "rand_hc 0.2.0",
-]
-
-[[package]]
-name = "rand"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
-dependencies = [
- "libc",
- "rand_chacha 0.3.1",
- "rand_core 0.6.2",
- "rand_hc 0.3.0",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.6.2",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
-dependencies = [
- "getrandom 0.1.16",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
-dependencies = [
- "getrandom 0.2.3",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
-dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
-dependencies = [
- "rand_core 0.6.2",
-]
-
-[[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",
@@ -1388,31 +994,30 @@ 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",
]
[[package]]
name = "redox_syscall"
-version = "0.2.8"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
+checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
-version = "1.5.4"
+version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
@@ -1442,20 +1047,21 @@ dependencies = [
[[package]]
name = "rgb"
-version = "0.8.27"
+version = "0.8.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fddb3b23626145d1776addfc307e1a1851f60ef6ca64f376bcb889697144cf0"
+checksum = "e74fdc210d8f24a7dbfedc13b04ba5764f5232754ccebfdf5fff1bad791ccbc6"
dependencies = [
"bytemuck",
]
[[package]]
name = "rhai"
-version = "0.20.2"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d862e125236e74d2a5033e88b9cb9404010a6a39516a388f570975494fe73bce"
+checksum = "9f06953bb8b9e4307cb7ccc0d9d018e2ddd25a30d32831f631ce4fe8f17671f7"
dependencies = [
- "ahash 0.7.4",
+ "ahash",
+ "bitflags",
"instant",
"num-traits",
"rhai_codegen",
@@ -1466,41 +1072,69 @@ dependencies = [
[[package]]
name = "rhai_codegen"
-version = "0.3.6"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faa0ff1c9dc19c9f8bba510a2a75d3f0449f6233570c2672c7e31c692a11a59a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "rust-embed"
+version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "643fd67d19aafd45a9e335afe4183dc58ba0cc6a1f43fbe34c7d92c041cdcafc"
+checksum = "9a17e5ac65b318f397182ae94e532da0ba56b88dd1200b774715d36c4943b1c3"
+dependencies = [
+ "rust-embed-impl",
+ "rust-embed-utils",
+ "walkdir",
+]
+
+[[package]]
+name = "rust-embed-impl"
+version = "6.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30"
dependencies = [
"proc-macro2",
"quote",
+ "rust-embed-utils",
"syn",
+ "walkdir",
+]
+
+[[package]]
+name = "rust-embed-utils"
+version = "7.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029"
+dependencies = [
+ "sha2",
+ "walkdir",
]
[[package]]
name = "rustc-demangle"
-version = "0.1.19"
+version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
+checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustc_version"
-version = "0.3.3"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
-
-[[package]]
-name = "safemem"
-version = "0.3.3"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
+checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "same-file"
@@ -1512,12 +1146,6 @@ dependencies = [
]
[[package]]
-name = "scoped-tls"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
-
-[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1525,36 +1153,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
-dependencies = [
- "semver-parser",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.10.2"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
-dependencies = [
- "pest",
-]
+checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
[[package]]
name = "serde"
-version = "1.0.126"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_cbor"
-version = "0.11.1"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
+checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [
"half",
"serde",
@@ -1562,9 +1178,9 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.126"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
+checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
dependencies = [
"proc-macro2",
"quote",
@@ -1573,23 +1189,11 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.64"
+version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
+checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
-dependencies = [
- "form_urlencoded",
- "itoa",
+ "itoa 1.0.1",
"ryu",
"serde",
]
@@ -1607,47 +1211,33 @@ dependencies = [
]
[[package]]
-name = "sha-1"
-version = "0.9.6"
+name = "sha2"
+version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
"block-buffer 0.9.0",
- "cfg-if 1.0.0",
+ "cfg-if",
"cpufeatures",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
[[package]]
-name = "slab"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
-
-[[package]]
name = "smallvec"
-version = "1.6.1"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
+checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "smartstring"
-version = "0.2.6"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ada87540bf8ef4cf8a1789deb175626829bb59b1fefd816cf7f7f55efcdbae9"
+checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
dependencies = [
+ "autocfg",
"static_assertions",
-]
-
-[[package]]
-name = "socket2"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
-dependencies = [
- "libc",
- "winapi",
+ "version_check",
]
[[package]]
@@ -1670,21 +1260,21 @@ checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb"
[[package]]
name = "symbolic-common"
-version = "8.2.0"
+version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f8e101b55bbcf228c855fa34fc4312e4f58b4a3251f1298bc0f97b71557815d"
+checksum = "9ea2ab8b85d27d49d184438b4b77fbd521b385cc9c5c802f60e784f2df25a03d"
dependencies = [
"debugid",
- "memmap",
+ "memmap2",
"stable_deref_trait",
"uuid",
]
[[package]]
name = "symbolic-demangle"
-version = "8.2.0"
+version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e257e28c2cbcf60a0c21089d32ff8b6cdc7efa6125b13693d29e8986aa1cd99"
+checksum = "7939b15a1c62633d1fce17f8a7b668312eaa2d3b117bf4ced5e6e77870c43b6a"
dependencies = [
"cpp_demangle",
"rustc-demangle",
@@ -1693,9 +1283,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.73"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
+checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a"
dependencies = [
"proc-macro2",
"quote",
@@ -1704,13 +1294,13 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.2.0"
+version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
+ "fastrand",
"libc",
- "rand 0.8.3",
"redox_syscall",
"remove_dir_all",
"winapi",
@@ -1718,9 +1308,9 @@ dependencies = [
[[package]]
name = "termcolor"
-version = "1.1.2"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
@@ -1736,18 +1326,18 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.25"
+version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
+checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.25"
+version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
+checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [
"proc-macro2",
"quote",
@@ -1756,170 +1346,66 @@ dependencies = [
[[package]]
name = "time"
-version = "0.1.43"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
dependencies = [
+ "itoa 1.0.1",
"libc",
- "winapi",
-]
-
-[[package]]
-name = "tinytemplate"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
-dependencies = [
+ "num_threads",
"serde",
- "serde_json",
+ "time-macros",
]
[[package]]
-name = "tinyvec"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
-
-[[package]]
-name = "tokio"
-version = "1.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aea337f72e96efe29acc234d803a5981cd9a2b6ed21655cd7fc21cfe021e8ec7"
-dependencies = [
- "autocfg",
- "bytes 1.0.1",
- "libc",
- "memchr",
- "mio",
- "num_cpus",
- "pin-project-lite",
- "tokio-macros",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tokio-stream"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066"
-dependencies = [
- "futures-core",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "tokio-tungstenite"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b"
-dependencies = [
- "futures-util",
- "log",
- "pin-project",
- "tokio",
- "tungstenite",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
-dependencies = [
- "bytes 1.0.1",
- "futures-core",
- "futures-sink",
- "log",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "tower-service"
-version = "0.3.1"
+name = "time-macros"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
+checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
[[package]]
-name = "tracing"
-version = "0.1.26"
+name = "tiny_http"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
+checksum = "e0d6ef4e10d23c1efb862eecad25c5054429a71958b4eeef85eb5e7170b477ca"
dependencies = [
- "cfg-if 1.0.0",
+ "ascii",
+ "chunked_transfer",
"log",
- "pin-project-lite",
- "tracing-core",
+ "time",
+ "url",
]
[[package]]
-name = "tracing-core"
-version = "0.1.18"
+name = "tinytemplate"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
- "lazy_static",
+ "serde",
+ "serde_json",
]
[[package]]
-name = "try-lock"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
-
-[[package]]
-name = "tungstenite"
-version = "0.12.0"
+name = "tinyvec"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
- "base64",
- "byteorder",
- "bytes 1.0.1",
- "http",
- "httparse",
- "input_buffer",
- "log",
- "rand 0.8.3",
- "sha-1 0.9.6",
- "url",
- "utf-8",
+ "tinyvec_macros",
]
[[package]]
-name = "twoway"
-version = "0.1.8"
+name = "tinyvec_macros"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
-dependencies = [
- "memchr",
-]
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "typenum"
-version = "1.13.0"
+version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "ucd-trie"
@@ -1928,22 +1414,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
-name = "unicase"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
-dependencies = [
- "version_check",
-]
-
-[[package]]
name = "unicode-bidi"
-version = "0.3.5"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
-dependencies = [
- "matches",
-]
+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-normalization"
@@ -1955,22 +1429,16 @@ dependencies = [
]
[[package]]
-name = "unicode-segmentation"
-version = "1.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
-
-[[package]]
name = "unicode-width"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
-version = "0.2.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]]
name = "url"
@@ -1985,28 +1453,16 @@ dependencies = [
]
[[package]]
-name = "utf-8"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-
-[[package]]
name = "uuid"
-version = "0.8.2"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f"
[[package]]
name = "version_check"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
-
-[[package]]
-name = "void"
-version = "1.0.2"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
@@ -2020,51 +1476,6 @@ dependencies = [
]
[[package]]
-name = "want"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
-dependencies = [
- "log",
- "try-lock",
-]
-
-[[package]]
-name = "warp"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "332d47745e9a0c38636dbd454729b147d16bd1ed08ae67b3ab281c4506771054"
-dependencies = [
- "bytes 1.0.1",
- "futures",
- "headers",
- "http",
- "hyper",
- "log",
- "mime",
- "mime_guess",
- "multipart",
- "percent-encoding",
- "pin-project",
- "scoped-tls",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "tokio",
- "tokio-stream",
- "tokio-tungstenite",
- "tokio-util",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
-
-[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2072,19 +1483,19 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
-version = "0.2.74"
+version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
+checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.74"
+version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
+checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
dependencies = [
"bumpalo",
"lazy_static",
@@ -2097,9 +1508,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.74"
+version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
+checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2107,9 +1518,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.74"
+version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
+checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
dependencies = [
"proc-macro2",
"quote",
@@ -2120,15 +1531,15 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.74"
+version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
+checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
[[package]]
name = "web-sys"
-version = "0.3.51"
+version = "0.3.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
+checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2136,10 +1547,12 @@ dependencies = [
[[package]]
name = "which"
-version = "3.1.1"
+version = "4.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
+checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
dependencies = [
+ "either",
+ "lazy_static",
"libc",
]
@@ -2173,3 +1586,46 @@ name = "winapi-x86_64-pc-windows-gnu"
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"
diff --git a/vendor/handlebars/Cargo.toml b/vendor/handlebars/Cargo.toml
index f46e0bd13..f40384c26 100644
--- a/vendor/handlebars/Cargo.toml
+++ b/vendor/handlebars/Cargo.toml
@@ -3,29 +3,45 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
-edition = "2018"
+edition = "2021"
+rust-version = "1.57"
name = "handlebars"
-version = "4.1.0"
+version = "4.3.3"
authors = ["Ning Sun <sunng@pm.me>"]
description = "Handlebars templating implemented in Rust."
homepage = "https://github.com/sunng87/handlebars-rust"
documentation = "https://docs.rs/crate/handlebars/"
readme = "README.md"
-keywords = ["handlebars", "templating", "web"]
-categories = ["template-engine", "web-programming"]
+keywords = [
+ "handlebars",
+ "templating",
+ "web",
+]
+categories = [
+ "template-engine",
+ "web-programming",
+]
license = "MIT"
repository = "https://github.com/sunng87/handlebars-rust"
+resolver = "2"
+
[package.metadata.docs.rs]
-features = ["dir_source", "script_helper"]
-rustdoc-args = ["--cfg", "docsrs"]
+features = [
+ "dir_source",
+ "script_helper",
+ "rust-embed",
+]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
[lib]
name = "handlebars"
@@ -35,9 +51,14 @@ path = "src/lib.rs"
name = "handlebars-cli"
path = "src/cli.rs"
+[[example]]
+name = "script"
+required-features = ["script_helper"]
+
[[bench]]
name = "bench"
harness = false
+
[dependencies.log]
version = "0.4.0"
@@ -47,12 +68,16 @@ version = "2.1.0"
[dependencies.pest_derive]
version = "2.1.0"
-[dependencies.quick-error]
-version = "2.0"
-
[dependencies.rhai]
-version = "0.20"
-features = ["sync", "serde"]
+version = "1.6"
+features = [
+ "sync",
+ "serde",
+]
+optional = true
+
+[dependencies.rust-embed]
+version = "6.3.0"
optional = true
[dependencies.serde]
@@ -61,17 +86,18 @@ version = "1.0.0"
[dependencies.serde_json]
version = "1.0.39"
+[dependencies.thiserror]
+version = "1"
+
[dependencies.walkdir]
version = "2.2.3"
optional = true
+
[dev-dependencies.criterion]
version = "0.3"
[dev-dependencies.env_logger]
-version = "0.8"
-
-[dev-dependencies.maplit]
-version = "1.0.0"
+version = "0.9"
[dev-dependencies.serde_derive]
version = "1.0.75"
@@ -79,20 +105,29 @@ version = "1.0.75"
[dev-dependencies.tempfile]
version = "3.0.0"
-[dev-dependencies.tokio]
-version = "1"
-features = ["macros", "rt-multi-thread"]
+[dev-dependencies.time]
+version = "0.3.7"
+features = [
+ "serde",
+ "formatting",
+ "parsing",
+]
-[dev-dependencies.warp]
-version = "0.3"
+[dev-dependencies.tiny_http]
+version = "0.11"
[features]
default = []
dir_source = ["walkdir"]
no_logging = []
script_helper = ["rhai"]
+
[target."cfg(unix)".dev-dependencies.pprof]
-version = "0.3.13"
-features = ["flamegraph", "protobuf"]
+version = "0.10"
+features = [
+ "flamegraph",
+ "prost-codec",
+]
+
[badges.maintenance]
status = "actively-developed"
diff --git a/vendor/handlebars/README.md b/vendor/handlebars/README.md
index 4a9c41827..18d21abfb 100644
--- a/vendor/handlebars/README.md
+++ b/vendor/handlebars/README.md
@@ -4,16 +4,11 @@ handlebars-rust
[Handlebars templating language](https://handlebarsjs.com) implemented
in Rust and for Rust.
-Handlebars-rust is the template engine that renders the official Rust website
-[rust-lang.org](https://www.rust-lang.org), [its
-book](https://doc.rust-lang.org/book/).
-
-[![Build Status](https://travis-ci.org/sunng87/handlebars-rust.svg?branch=master)](https://travis-ci.org/sunng87/handlebars-rust)
-[![](https://meritbadge.herokuapp.com/handlebars)](https://crates.io/crates/handlebars)
+[![CI](https://github.com/sunng87/handlebars-rust/actions/workflows/main.yml/badge.svg)](https://github.com/sunng87/handlebars-rust/actions/workflows/main.yml)
+[![](https://img.shields.io/crates/v/handlebars)](https://crates.io/crates/handlebars)
[![](https://img.shields.io/crates/d/handlebars.svg)](https://crates.io/crates/handlebars)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![Docs](https://docs.rs/handlebars/badge.svg)](https://docs.rs/crate/handlebars/)
-![rustc](https://img.shields.io/badge/rustc-1.50+-lightgray.svg)
[![Donate](https://img.shields.io/badge/donate-liberapay-yellow.svg)](https://liberapay.com/Sunng/donate)
## Getting Started
@@ -55,6 +50,8 @@ Examples are provided in source tree to demo usage of various api.
to use custom helpers.
* [render_file](https://github.com/sunng87/handlebars-rust/blob/master/examples/render_file.rs)
similar to render, but render to file instead of string
+* [helper_macro](https://github.com/sunng87/handlebars-rust/blob/master/examples/helper_macro.rs)
+ demos usage of `handlebars_helper!` to simplify helper development
* [partials](https://github.com/sunng87/handlebars-rust/blob/master/examples/partials.rs)
template inheritance with handlebars
* [decorator](https://github.com/sunng87/handlebars-rust/blob/master/examples/decorator.rs)
@@ -71,7 +68,7 @@ Examples are provided in source tree to demo usage of various api.
## Minimum Rust Version Policy
Handlebars will track Rust nightly and stable channel. When dropping
-support for previous stable versions, I will bump **major** version
+support for previous stable versions, I will bump **patch** version
and clarify in CHANGELOG.
## Document
@@ -133,7 +130,7 @@ And using it in your template:
{{hex 16}}
```
-By default, handlebars-rust ships [additional helpers](https://github.com/sunng87/handlebars-rust/blob/master/src/helpers/helper_boolean.rs#L5)
+By default, handlebars-rust ships [additional helpers](https://github.com/sunng87/handlebars-rust/blob/master/src/helpers/helper_extras.rs#L6)
(compared with original js version)
that is useful when working with `if`.
@@ -146,7 +143,7 @@ moment, and can change in future.
Every time I look into a templating system, I will investigate its
support for [template
-inheritance](https://docs.djangoproject.com/en/1.9/ref/templates/language/#template-inheritance).
+inheritance](https://docs.djangoproject.com/en/3.2/ref/templates/language/#template-inheritance).
Template include is not sufficient for template reuse. In most cases
you will need a skeleton of page as parent (header, footer, etc.), and
@@ -164,6 +161,13 @@ loaded from files or directory. This can be handy for template development.
Handlebars 3.0 can be used in WebAssembly projects.
+#### Fully scriptable
+
+With [rhai](https://github.com/rhaiscript/rhai) script support, you
+can implement your own helper with the scripting language. Together
+with the template lanaguage itself, template development can be fully
+scriptable without changing rust code.
+
## Related Projects
### Web frameworks
@@ -174,7 +178,7 @@ Handlebars 3.0 can be used in WebAssembly projects.
example](https://github.com/seanmonstar/warp/blob/master/examples/handlebars_template.rs)
* Tower-web: [Built-in](https://github.com/carllerche/tower-web)
* Actix: [handlebars
- example](https://github.com/actix/examples/blob/master/template_engines/handlebars/src/main.rs)
+ example](https://github.com/actix/examples/blob/master/templating/handlebars/src/main.rs)
* Tide: [tide-handlebars](https://github.com/No9/tide-handlebars)
### Adopters
diff --git a/vendor/handlebars/examples/dev_mode.rs b/vendor/handlebars/examples/dev_mode.rs
index 99017474f..3256eed37 100644
--- a/vendor/handlebars/examples/dev_mode.rs
+++ b/vendor/handlebars/examples/dev_mode.rs
@@ -2,10 +2,9 @@ use std::sync::Arc;
use handlebars::Handlebars;
use serde_json::json;
-use warp::{self, Filter};
+use tiny_http::{Response, Server};
-#[tokio::main]
-async fn main() {
+fn handlebars() -> Handlebars<'static> {
let mut reg = Handlebars::new();
// enable dev mode for template reloading
reg.set_dev_mode(true);
@@ -14,14 +13,19 @@ async fn main() {
reg.register_template_file("tpl", "./examples/dev_mode/template.hbs")
.unwrap();
- let hbs = Arc::new(reg);
- let route = warp::get().map(move || {
+ reg
+}
+
+fn main() {
+ let hbs = Arc::new(handlebars());
+
+ let server = Server::http("127.0.0.1:3030").expect("Failed to start demo server.");
+ println!("Edit ./examples/dev_mode/template.hbs and request http://localhost:3030 to see the change on the fly.");
+
+ for req in server.incoming_requests() {
let result = hbs
.render("tpl", &json!({"model": "t14s", "brand": "Thinkpad"}))
.unwrap_or_else(|e| e.to_string());
- warp::reply::html(result)
- });
-
- println!("Edit ./examples/dev_mode/template.hbs and request http://localhost:3030 to see the change on the run.");
- warp::serve(route).run(([127, 0, 0, 1], 3030)).await;
+ req.respond(Response::from_string(result)).unwrap();
+ }
}
diff --git a/vendor/handlebars/examples/error.rs b/vendor/handlebars/examples/error.rs
index 3fb874e2b..ed0f7c423 100644
--- a/vendor/handlebars/examples/error.rs
+++ b/vendor/handlebars/examples/error.rs
@@ -3,11 +3,44 @@ extern crate handlebars;
#[macro_use]
extern crate serde_json;
-use std::error::Error;
+use std::error::Error as StdError;
-use handlebars::Handlebars;
+use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError};
+use thiserror::Error;
-fn main() -> Result<(), Box<dyn Error>> {
+#[derive(Debug, Error)]
+pub enum HelperError {
+ #[error("db error")]
+ DbError,
+ #[error("api error")]
+ ApiError,
+}
+
+/// A helper that raise error according to parameters
+pub fn error_helper(
+ h: &Helper,
+ _: &Handlebars,
+ _: &Context,
+ _: &mut RenderContext,
+ _: &mut dyn Output,
+) -> Result<(), RenderError> {
+ let param = h
+ .param(0)
+ .ok_or(RenderError::new("Param 0 is required for error helper."))?;
+ match param.value().as_str() {
+ Some("db") => Err(RenderError::from_error(
+ "helper error",
+ HelperError::DbError,
+ )),
+ Some("api") => Err(RenderError::from_error(
+ "helper error",
+ HelperError::ApiError,
+ )),
+ _ => Ok(()),
+ }
+}
+
+fn main() -> Result<(), Box<dyn StdError>> {
env_logger::init();
let mut handlebars = Handlebars::new();
@@ -36,5 +69,18 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("{}", be1.source().unwrap());
println!("{:?}", be1.source().unwrap().source());
+ // process error generated in helper
+ handlebars.register_helper("err", Box::new(error_helper));
+ let e2 = handlebars
+ .render_template("{{err \"db\"}}", &json!({}))
+ .unwrap_err();
+ // down-casting the error to user defined type
+ match e2.source().and_then(|e| e.downcast_ref::<HelperError>()) {
+ Some(HelperError::DbError) => {
+ println!("Detected error from helper: db error",)
+ }
+ _ => {}
+ }
+
Ok(())
}
diff --git a/vendor/handlebars/examples/helper_macro.rs b/vendor/handlebars/examples/helper_macro.rs
new file mode 100644
index 000000000..dcc6ea31a
--- /dev/null
+++ b/vendor/handlebars/examples/helper_macro.rs
@@ -0,0 +1,63 @@
+use std::error::Error;
+
+use handlebars::{handlebars_helper, Handlebars, JsonRender};
+use serde_json::{json, Value};
+use time::format_description::parse;
+use time::OffsetDateTime;
+
+// define a helper using helper
+// a date format helper accept an `OffsetDateTime` as parameter
+handlebars_helper!(date: |dt: OffsetDateTime| dt.format(&parse("[year]-[month]-[day]").unwrap()).unwrap());
+
+// a helper returns number of provided parameters
+handlebars_helper!(nargs: |*args| args.len());
+
+// a helper joins all values, using both hash and parameters
+handlebars_helper!(join: |{sep:str=","}, *args|
+ args.iter().map(|a| a.render()).collect::<Vec<String>>().join(sep)
+);
+
+handlebars_helper!(isdefined: |v: Value| !v.is_null());
+
+// a helper provides format
+handlebars_helper!(date2: |dt: OffsetDateTime, {fmt:str = "[year]-[month]-[day]"}|
+ dt.format(&parse(fmt).unwrap()).unwrap()
+);
+
+fn main() -> Result<(), Box<dyn Error>> {
+ // create the handlebars registry
+ let mut handlebars = Handlebars::new();
+
+ handlebars.register_helper("date", Box::new(date));
+ handlebars.register_helper("date2", Box::new(date2));
+ handlebars.register_helper("nargs", Box::new(nargs));
+ handlebars.register_helper("join", Box::new(join));
+ handlebars.register_helper("isdefined", Box::new(isdefined));
+
+ let data = OffsetDateTime::now_utc();
+
+ println!("{}", handlebars.render_template("{{date this}}", &data)?);
+ println!("{}", handlebars.render_template("{{date2 this}}", &data)?);
+ println!(
+ "{}",
+ handlebars.render_template("{{date2 this fmt=\"[day]/[month]/[year]\"}}", &data)?
+ );
+
+ println!("{}", handlebars.render_template("{{nargs 1 2 3 4}}", &())?);
+
+ println!(
+ "{}",
+ handlebars.render_template("{{join 1 2 3 4 sep=\"|\" }}", &())?
+ );
+
+ println!(
+ "{}",
+ handlebars.render_template(
+ r#"{{isdefined a}} {{isdefined b}}
+{{#if (isdefined a)}}a{{/if}} {{#if (isdefined b)}}b{{/if}}"#,
+ &json!({"a": 1})
+ )?
+ );
+
+ Ok(())
+}
diff --git a/vendor/handlebars/examples/partials.rs b/vendor/handlebars/examples/partials.rs
index 80b20c2f7..017dd04b7 100644
--- a/vendor/handlebars/examples/partials.rs
+++ b/vendor/handlebars/examples/partials.rs
@@ -1,9 +1,8 @@
extern crate env_logger;
extern crate handlebars;
-#[macro_use]
-extern crate maplit;
use handlebars::Handlebars;
+use serde_json::json;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
@@ -15,14 +14,14 @@ fn main() -> Result<(), Box<dyn Error>> {
handlebars.register_template_file("base0", "./examples/partials/base0.hbs")?;
handlebars.register_template_file("base1", "./examples/partials/base1.hbs")?;
- let data0 = btreemap! {
- "title".to_string() => "example 0".to_string(),
- "parent".to_string() => "base0".to_string()
- };
- let data1 = btreemap! {
- "title".to_string() => "example 1".to_string(),
- "parent".to_string() => "base1".to_string()
- };
+ let data0 = json!({
+ "title": "example 0",
+ "parent": "base0"
+ });
+ let data1 = json!({
+ "title": "example 1",
+ "parent": "base1"
+ });
println!("Page 0");
println!("{}", handlebars.render("template", &data0)?);
diff --git a/vendor/handlebars/examples/script.rs b/vendor/handlebars/examples/script.rs
index bedd426cd..de89fa482 100644
--- a/vendor/handlebars/examples/script.rs
+++ b/vendor/handlebars/examples/script.rs
@@ -5,7 +5,6 @@ use std::error::Error;
#[macro_use]
extern crate serde_json;
-#[cfg(feature = "script_helper")]
fn main() -> Result<(), Box<dyn Error>> {
let mut handlebars = Handlebars::new();
@@ -31,9 +30,3 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("{}", handlebars.render("tpl", &data)?);
Ok(())
}
-
-#[cfg(not(feature = "script_helper"))]
-fn main() -> Result<(), Box<dyn Error>> {
- println!("Please enable feature flag script_helper for this example");
- Ok(())
-}
diff --git a/vendor/handlebars/release.toml b/vendor/handlebars/release.toml
index e0f365aa1..6ee7a8383 100644
--- a/vendor/handlebars/release.toml
+++ b/vendor/handlebars/release.toml
@@ -1,4 +1,6 @@
sign-commit = true
+sign-tag = true
+dev-version = true
pre-release-replacements = [
{file="CHANGELOG.md", search="Unreleased", replace="{{version}}", prerelease=false},
{file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", prerelease=false},
diff --git a/vendor/handlebars/src/context.rs b/vendor/handlebars/src/context.rs
index 10e15fd90..86f99ba4d 100644
--- a/vendor/handlebars/src/context.rs
+++ b/vendor/handlebars/src/context.rs
@@ -45,7 +45,7 @@ fn parse_json_visitor<'a, 'reg>(
for path_seg in relative_path {
match path_seg {
PathSeg::Named(the_path) => {
- if let Some((holder, base_path)) = get_in_block_params(&block_contexts, the_path) {
+ if let Some((holder, base_path)) = get_in_block_params(block_contexts, the_path) {
with_block_param = Some((holder, base_path));
}
break;
@@ -171,10 +171,7 @@ impl Context {
block_contexts: &VecDeque<BlockContext<'reg>>,
) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
// always use absolute at the moment until we get base_value lifetime issue fixed
- let resolved_visitor = parse_json_visitor(&relative_path, block_contexts, true);
-
- // debug logging
- debug!("Accessing context value: {:?}", resolved_visitor);
+ let resolved_visitor = parse_json_visitor(relative_path, block_contexts, true);
match resolved_visitor {
ResolvedPath::AbsolutePath(paths) => {
@@ -223,6 +220,12 @@ impl Context {
}
}
+impl From<Json> for Context {
+ fn from(data: Json) -> Context {
+ Context { data }
+ }
+}
+
#[cfg(test)]
mod test {
use crate::block::{BlockContext, BlockParams};
@@ -359,9 +362,9 @@ mod test {
#[test]
fn test_key_name_with_this() {
- let m = btreemap! {
- "this_name".to_string() => "the_value".to_string()
- };
+ let m = json!({
+ "this_name": "the_value"
+ });
let ctx = Context::wraps(&m).unwrap();
assert_eq!(
navigate_from_root(&ctx, "this_name").unwrap().render(),
diff --git a/vendor/handlebars/src/decorators/mod.rs b/vendor/handlebars/src/decorators/mod.rs
index b8bad900f..bd2d23458 100644
--- a/vendor/handlebars/src/decorators/mod.rs
+++ b/vendor/handlebars/src/decorators/mod.rs
@@ -105,9 +105,9 @@ mod test {
.register_template_string("t0", "{{*foo}}".to_string())
.unwrap();
- let data = btreemap! {
- "hello".to_string() => "world".to_string()
- };
+ let data = json!({
+ "hello": "world"
+ });
assert!(handlebars.render("t0", &data).is_err());
@@ -132,9 +132,9 @@ mod test {
.register_template_string("t0", "{{hello}}{{*foo}}{{hello}}".to_string())
.unwrap();
- let data = btreemap! {
- "hello".to_string() => "world".to_string()
- };
+ let data = json!({
+ "hello": "world"
+ });
handlebars.register_decorator(
"foo",
diff --git a/vendor/handlebars/src/error.rs b/vendor/handlebars/src/error.rs
index f4721623f..618d68e4f 100644
--- a/vendor/handlebars/src/error.rs
+++ b/vendor/handlebars/src/error.rs
@@ -1,10 +1,13 @@
-use std::error::Error;
-use std::fmt;
+// use std::backtrace::Backtrace;
+use std::error::Error as StdError;
+use std::fmt::{self, Write};
use std::io::Error as IOError;
use std::num::ParseIntError;
use std::string::FromUtf8Error;
use serde_json::error::Error as SerdeError;
+use thiserror::Error;
+
#[cfg(feature = "dir_source")]
use walkdir::Error as WalkdirError;
@@ -12,14 +15,16 @@ use walkdir::Error as WalkdirError;
use rhai::{EvalAltResult, ParseError};
/// Error when rendering data on template.
-#[derive(Debug, Default)]
+#[derive(Debug, Default, Error)]
pub struct RenderError {
pub desc: String,
pub template_name: Option<String>,
pub line_no: Option<usize>,
pub column_no: Option<usize>,
- cause: Option<Box<dyn Error + Send + Sync + 'static>>,
+ #[source]
+ cause: Option<Box<dyn StdError + Send + Sync + 'static>>,
unimplemented: bool,
+ // backtrace: Backtrace,
}
impl fmt::Display for RenderError {
@@ -38,14 +43,6 @@ impl fmt::Display for RenderError {
}
}
-impl Error for RenderError {
- fn source(&self) -> Option<&(dyn Error + 'static)> {
- self.cause
- .as_ref()
- .map(|e| e.as_ref() as &(dyn Error + 'static))
- }
-}
-
impl From<IOError> for RenderError {
fn from(e: IOError) -> RenderError {
RenderError::from_error("Cannot generate output.", e)
@@ -115,7 +112,7 @@ impl RenderError {
pub fn from_error<E>(error_info: &str, cause: E) -> RenderError
where
- E: Error + Send + Sync + 'static,
+ E: StdError + Send + Sync + 'static,
{
let mut e = RenderError::new(error_info);
e.cause = Some(Box::new(cause));
@@ -129,39 +126,31 @@ impl RenderError {
}
}
-quick_error! {
/// Template parsing error
- #[derive(Debug)]
- pub enum TemplateErrorReason {
- MismatchingClosedHelper(open: String, closed: String) {
- display("helper {:?} was opened, but {:?} is closing",
- open, closed)
- }
- MismatchingClosedDecorator(open: String, closed: String) {
- display("decorator {:?} was opened, but {:?} is closing",
- open, closed)
- }
- InvalidSyntax {
- display("invalid handlebars syntax.")
- }
- InvalidParam (param: String) {
- display("invalid parameter {:?}", param)
- }
- NestedSubexpression {
- display("nested subexpression is not supported")
- }
- IoError(err: IOError, name: String) {
- display("Template \"{}\": {}", name, err)
- }
- #[cfg(feature = "dir_source")]
- WalkdirError(err: WalkdirError) {
- display("Walk dir error: {}", err)
- }
- }
+#[derive(Debug, Error)]
+pub enum TemplateErrorReason {
+ #[error("helper {0:?} was opened, but {1:?} is closing")]
+ MismatchingClosedHelper(String, String),
+ #[error("decorator {0:?} was opened, but {1:?} is closing")]
+ MismatchingClosedDecorator(String, String),
+ #[error("invalid handlebars syntax.")]
+ InvalidSyntax,
+ #[error("invalid parameter {0:?}")]
+ InvalidParam(String),
+ #[error("nested subexpression is not supported")]
+ NestedSubexpression,
+ #[error("Template \"{1}\": {0}")]
+ IoError(IOError, String),
+ #[cfg(feature = "dir_source")]
+ #[error("Walk dir error: {err}")]
+ WalkdirError {
+ #[from]
+ err: WalkdirError,
+ },
}
/// Error on parsing template.
-#[derive(Debug)]
+#[derive(Debug, Error)]
pub struct TemplateError {
pub reason: TemplateErrorReason,
pub template_name: Option<String>,
@@ -194,8 +183,6 @@ impl TemplateError {
}
}
-impl Error for TemplateError {}
-
impl From<(IOError, String)> for TemplateError {
fn from(err_info: (IOError, String)) -> TemplateError {
let (e, name) = err_info;
@@ -206,7 +193,7 @@ impl From<(IOError, String)> for TemplateError {
#[cfg(feature = "dir_source")]
impl From<WalkdirError> for TemplateError {
fn from(e: WalkdirError) -> TemplateError {
- TemplateError::of(TemplateErrorReason::WalkdirError(e))
+ TemplateError::of(TemplateErrorReason::from(e))
}
}
@@ -218,7 +205,7 @@ fn template_segment(template_str: &str, line: usize, col: usize) -> String {
let mut buf = String::new();
for (line_count, line_content) in template_str.lines().enumerate() {
if line_count >= line_start && line_count <= line_end {
- buf.push_str(&format!("{:4} | {}\n", line_count, line_content));
+ let _ = writeln!(&mut buf, "{:4} | {}", line_count, line_content);
if line_count == line - 1 {
buf.push_str(" |");
for c in 0..line_content.len() {
@@ -257,16 +244,11 @@ impl fmt::Display for TemplateError {
}
#[cfg(feature = "script_helper")]
-quick_error! {
- #[derive(Debug)]
- pub enum ScriptError {
- IoError(err: IOError) {
- from()
- source(err)
- }
- ParseError(err: ParseError) {
- from()
- source(err)
- }
- }
+#[derive(Debug, Error)]
+pub enum ScriptError {
+ #[error(transparent)]
+ IoError(#[from] IOError),
+
+ #[error(transparent)]
+ ParseError(#[from] ParseError),
}
diff --git a/vendor/handlebars/src/grammar.pest b/vendor/handlebars/src/grammar.pest
index 250d9d213..ac6776ee2 100644
--- a/vendor/handlebars/src/grammar.pest
+++ b/vendor/handlebars/src/grammar.pest
@@ -14,14 +14,20 @@ literal = { string_literal |
null_literal = @{ "null" ~ !symbol_char }
boolean_literal = @{ ("true"|"false") ~ !symbol_char }
-number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? }
-json_char = {
+number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? ~ !symbol_char }
+json_char_double_quote = {
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
-string_inner = @{ json_char* }
-string_literal = ${ "\"" ~ string_inner ~ "\"" }
+json_char_single_quote = {
+ !("'" | "\\") ~ ANY
+ | "\\" ~ ("'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
+ | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
+}
+string_inner_double_quote = @{ json_char_double_quote* }
+string_inner_single_quote = @{ json_char_single_quote* }
+string_literal = ${ ("\"" ~ string_inner_double_quote ~ "\"") | ("'" ~ string_inner_single_quote ~ "'") }
array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" }
object_literal = { "{" ~ (string_literal ~ ":" ~ literal)?
~ ("," ~ string_literal ~ ":" ~ literal)* ~ "}" }
@@ -50,12 +56,17 @@ pro_whitespace_omitter = { "~" }
expression = { !invert_tag ~ "{{" ~ pre_whitespace_omitter? ~
((identifier ~ (hash|param)+) | name )
~ pro_whitespace_omitter? ~ "}}" }
-html_expression_triple_bracket = _{ "{{{" ~ pre_whitespace_omitter? ~
- ((identifier ~ (hash|param)+) | name ) ~
- pro_whitespace_omitter? ~ "}}}" }
+html_expression_triple_bracket_legacy = _{ "{{{" ~ pre_whitespace_omitter? ~
+ ((identifier ~ (hash|param)+) | name ) ~
+ pro_whitespace_omitter? ~ "}}}" }
+html_expression_triple_bracket = _{ "{{" ~ pre_whitespace_omitter? ~ "{" ~
+ ((identifier ~ (hash|param)+) | name ) ~
+ "}" ~ pro_whitespace_omitter? ~ "}}" }
+
amp_expression = _{ "{{" ~ pre_whitespace_omitter? ~ "&" ~ name ~
pro_whitespace_omitter? ~ "}}" }
-html_expression = { html_expression_triple_bracket | amp_expression }
+html_expression = { (html_expression_triple_bracket_legacy | html_expression_triple_bracket)
+ | amp_expression }
decorator_expression = { "{{" ~ pre_whitespace_omitter? ~ "*" ~ exp_line ~
pro_whitespace_omitter? ~ "}}" }
diff --git a/vendor/handlebars/src/grammar.rs b/vendor/handlebars/src/grammar.rs
index 1fd292ce1..6e61cd4e4 100644
--- a/vendor/handlebars/src/grammar.rs
+++ b/vendor/handlebars/src/grammar.rs
@@ -4,26 +4,6 @@
#[grammar = "grammar.pest"]
pub struct HandlebarsParser;
-#[inline]
-pub(crate) fn whitespace_matcher(c: char) -> bool {
- c == ' ' || c == '\t'
-}
-
-#[inline]
-pub(crate) fn newline_matcher(c: char) -> bool {
- c == '\n' || c == '\r'
-}
-
-pub(crate) fn ends_with_empty_line(text: &str) -> bool {
- text.trim_end_matches(whitespace_matcher)
- .ends_with(newline_matcher)
-}
-
-pub(crate) fn starts_with_empty_line(text: &str) -> bool {
- text.trim_start_matches(whitespace_matcher)
- .starts_with(newline_matcher)
-}
-
#[cfg(test)]
mod test {
use super::{HandlebarsParser, Rule};
@@ -191,6 +171,7 @@ mod test {
"{{exp 1}}",
"{{exp \"literal\"}}",
"{{exp \"literal with space\"}}",
+ "{{exp 'literal with space'}}",
r#"{{exp "literal with escape \\\\"}}"#,
"{{exp ref}}",
"{{exp (sub)}}",
@@ -199,6 +180,8 @@ mod test {
"{{exp {}}}",
"{{exp key=1}}",
"{{exp key=ref}}",
+ "{{exp key='literal with space'}}",
+ "{{exp key=\"literal with space\"}}",
"{{exp key=(sub)}}",
"{{exp key=(sub 0)}}",
"{{exp key=(sub 0 key=1)}}",
@@ -225,6 +208,12 @@ mod test {
"{{&html}}",
"{{{html 1}}}",
"{{{html p=true}}}",
+ "{{{~ html}}}",
+ "{{{html ~}}}",
+ "{{{~ html ~}}}",
+ "{{~{ html }~}}",
+ "{{~{ html }}}",
+ "{{{ html }~}}",
];
for i in s.iter() {
assert_rule!(Rule::html_expression, i);
diff --git a/vendor/handlebars/src/helpers/helper_each.rs b/vendor/handlebars/src/helpers/helper_each.rs
index 4b76e7ce7..2be28dc9c 100644
--- a/vendor/handlebars/src/helpers/helper_each.rs
+++ b/vendor/handlebars/src/helpers/helper_each.rs
@@ -18,7 +18,7 @@ fn update_block_context<'reg>(
is_first: bool,
value: &Json,
) {
- if let Some(ref p) = base_path {
+ if let Some(p) = base_path {
if is_first {
*block.base_path_mut() = copy_on_push_vec(p, relative_path);
} else if let Some(ptr) = block.base_path_mut().last_mut() {
@@ -83,7 +83,7 @@ impl HelperDef for EachHelper {
Json::Array(ref list)
if !list.is_empty() || (list.is_empty() && h.inverse().is_none()) =>
{
- let block_context = create_block(&value);
+ let block_context = create_block(value);
rc.push_block(block_context);
let len = list.len();
@@ -100,8 +100,8 @@ impl HelperDef for EachHelper {
block.set_local_var("last", to_json(is_last));
block.set_local_var("index", index.clone());
- update_block_context(block, array_path, i.to_string(), is_first, &v);
- set_block_param(block, h, array_path, &index, &v)?;
+ update_block_context(block, array_path, i.to_string(), is_first, v);
+ set_block_param(block, h, array_path, &index, v)?;
}
t.render(r, ctx, rc, out)?;
@@ -113,28 +113,28 @@ impl HelperDef for EachHelper {
Json::Object(ref obj)
if !obj.is_empty() || (obj.is_empty() && h.inverse().is_none()) =>
{
- let block_context = create_block(&value);
+ let block_context = create_block(value);
rc.push_block(block_context);
- let mut is_first = true;
+ let len = obj.len();
+
let obj_path = value.context_path();
- for (k, v) in obj.iter() {
+ for (i, (k, v)) in obj.iter().enumerate() {
if let Some(ref mut block) = rc.block_mut() {
- let key = to_json(k);
+ let is_first = i == 0usize;
+ let is_last = i == len - 1;
+ let key = to_json(k);
block.set_local_var("first", to_json(is_first));
+ block.set_local_var("last", to_json(is_last));
block.set_local_var("key", key.clone());
- update_block_context(block, obj_path, k.to_string(), is_first, &v);
- set_block_param(block, h, obj_path, &key, &v)?;
+ update_block_context(block, obj_path, k.to_string(), is_first, v);
+ set_block_param(block, h, obj_path, &key, v)?;
}
t.render(r, ctx, rc, out)?;
-
- if is_first {
- is_first = false;
- }
}
rc.pop_block();
@@ -159,7 +159,6 @@ pub static EACH_HELPER: EachHelper = EachHelper;
#[cfg(test)]
mod test {
- use crate::json::value::to_json;
use crate::registry::Registry;
use serde_json::value::Value as Json;
use std::collections::BTreeMap;
@@ -188,7 +187,10 @@ mod test {
)
.is_ok());
assert!(handlebars
- .register_template_string("t1", "{{#each this}}{{@first}}|{{@key}}:{{this}}|{{/each}}")
+ .register_template_string(
+ "t1",
+ "{{#each this}}{{@first}}|{{@last}}|{{@key}}:{{this}}|{{/each}}"
+ )
.is_ok());
let r0 = handlebars.render("t0", &vec![1u16, 2u16, 3u16]);
@@ -199,9 +201,13 @@ mod test {
let mut m: BTreeMap<String, u16> = BTreeMap::new();
m.insert("ftp".to_string(), 21);
+ m.insert("gopher".to_string(), 70);
m.insert("http".to_string(), 80);
let r1 = handlebars.render("t1", &m);
- assert_eq!(r1.ok().unwrap(), "true|ftp:21|false|http:80|".to_string());
+ assert_eq!(
+ r1.ok().unwrap(),
+ "true|false|ftp:21|false|false|gopher:70|false|true|http:80|".to_string()
+ );
}
#[test]
@@ -303,15 +309,15 @@ mod test {
assert!(handlebars
.register_template_string("t0", "{{#each a}}1{{else}}empty{{/each}}")
.is_ok());
- let m1 = btreemap! {
- "a".to_string() => Vec::<String>::new(),
- };
+ let m1 = json!({
+ "a": []
+ });
let r0 = handlebars.render("t0", &m1).unwrap();
assert_eq!(r0, "empty");
- let m2 = btreemap! {
- "b".to_string() => Vec::<String>::new()
- };
+ let m2 = json!({
+ "b": []
+ });
let r1 = handlebars.render("t0", &m2).unwrap();
assert_eq!(r1, "empty");
}
@@ -322,9 +328,9 @@ mod test {
assert!(handlebars
.register_template_string("t0", "{{#each a as |i|}}{{i}}{{/each}}")
.is_ok());
- let m1 = btreemap! {
- "a".to_string() => vec![1,2,3,4,5]
- };
+ let m1 = json!({
+ "a": [1,2,3,4,5]
+ });
let r0 = handlebars.render("t0", &m1).unwrap();
assert_eq!(r0, "12345");
}
@@ -337,10 +343,10 @@ mod test {
{{/each}}";
assert!(handlebars.register_template_string("t0", template).is_ok());
- let m = btreemap! {
- "ftp".to_string() => 21,
- "http".to_string() => 80
- };
+ let m = json!({
+ "ftp": 21,
+ "http": 80
+ });
let r0 = handlebars.render("t0", &m);
assert_eq!(r0.ok().unwrap(), "ftp:21|http:80|".to_string());
}
@@ -354,10 +360,10 @@ mod test {
assert!(handlebars.register_template_string("t0", template).is_ok());
- let m = btreemap! {
- "ftp".to_string() => 21,
- "http".to_string() => 80
- };
+ let m = json!({
+ "ftp": 21,
+ "http": 80
+ });
let r0 = handlebars.render("t0", &m);
assert_eq!(r0.ok().unwrap(), "ftp:21|http:80|".to_string());
}
@@ -371,12 +377,12 @@ mod test {
)
.is_ok());
- let data = btreemap! {
- "a".to_string() => to_json(&btreemap! {
- "b".to_string() => vec![btreemap!{"c".to_string() => vec![1]}]
- }),
- "d".to_string() => to_json(&1)
- };
+ let data = json!({
+ "a": {
+ "b": [{"c": [1]}]
+ },
+ "d": 1
+ });
let r0 = handlebars.render("t0", &data);
assert_eq!(r0.ok().unwrap(), "1".to_string());
@@ -389,10 +395,10 @@ mod test {
{{#if @first}}template<{{/if}}{{this}}{{#if @last}}>{{else}},{{/if}}\
{{/each}}{{/each}}";
assert!(handlebars.register_template_string("t0", template).is_ok());
- let data = btreemap! {
- "typearg".to_string() => vec!["T".to_string()],
- "variant".to_string() => vec!["1".to_string(), "2".to_string()]
- };
+ let data = json!({
+ "typearg": ["T"],
+ "variant": ["1", "2"]
+ });
let r0 = handlebars.render("t0", &data);
assert_eq!(r0.ok().unwrap(), "template<T>template<T>".to_string());
}
diff --git a/vendor/handlebars/src/helpers/helper_if.rs b/vendor/handlebars/src/helpers/helper_if.rs
index 5a6e42fc0..342c74567 100644
--- a/vendor/handlebars/src/helpers/helper_if.rs
+++ b/vendor/handlebars/src/helpers/helper_if.rs
@@ -36,7 +36,7 @@ impl HelperDef for IfHelper {
let tmpl = if value { h.template() } else { h.inverse() };
match tmpl {
- Some(ref t) => t.render(r, ctx, rc, out),
+ Some(t) => t.render(r, ctx, rc, out),
None => Ok(()),
}
}
@@ -137,6 +137,12 @@ mod test {
);
assert_eq!(
+ "yes\r\n",
+ hbs.render_template("{{#if a}}\r\nyes\r\n{{/if}}\r\n", &json!({"a": true}))
+ .unwrap()
+ );
+
+ assert_eq!(
"x\ny",
hbs.render_template("{{#if a}}x{{/if}}\ny", &json!({"a": true}))
.unwrap()
@@ -147,5 +153,37 @@ mod test {
hbs.render_template("{{#if a}}\nx\n{{^}}\ny\n{{/if}}\nz", &json!({"a": false}))
.unwrap()
);
+
+ assert_eq!(
+ r#"yes
+ foo
+ bar
+ baz"#,
+ hbs.render_template(
+ r#"yes
+ {{#if true}}
+ foo
+ bar
+ {{/if}}
+ baz"#,
+ &json!({})
+ )
+ .unwrap()
+ );
+
+ assert_eq!(
+ r#" foo
+ bar
+ baz"#,
+ hbs.render_template(
+ r#" {{#if true}}
+ foo
+ bar
+ {{/if}}
+ baz"#,
+ &json!({})
+ )
+ .unwrap()
+ );
}
}
diff --git a/vendor/handlebars/src/helpers/helper_lookup.rs b/vendor/handlebars/src/helpers/helper_lookup.rs
index bf887debe..8662d55a0 100644
--- a/vendor/handlebars/src/helpers/helper_lookup.rs
+++ b/vendor/handlebars/src/helpers/helper_lookup.rs
@@ -52,8 +52,6 @@ pub static LOOKUP_HELPER: LookupHelper = LookupHelper;
mod test {
use crate::registry::Registry;
- use std::collections::BTreeMap;
-
#[test]
fn test_lookup() {
let mut handlebars = Registry::new();
@@ -67,13 +65,11 @@ mod test {
.register_template_string("t2", "{{lookup kk \"a\"}}")
.is_ok());
- let mut m: BTreeMap<String, Vec<u16>> = BTreeMap::new();
- m.insert("v1".to_string(), vec![1u16, 2u16, 3u16]);
- m.insert("v2".to_string(), vec![9u16, 8u16, 7u16]);
+ let m = json!({"v1": [1,2,3], "v2": [9,8,7]});
- let m2 = btreemap! {
- "kk".to_string() => btreemap!{"a".to_string() => "world".to_string()}
- };
+ let m2 = json!({
+ "kk": {"a": "world"}
+ });
let r0 = handlebars.render("t0", &m);
assert_eq!(r0.ok().unwrap(), "987".to_string());
diff --git a/vendor/handlebars/src/helpers/helper_with.rs b/vendor/handlebars/src/helpers/helper_with.rs
index c4d31cd0e..2ea6bd4f6 100644
--- a/vendor/handlebars/src/helpers/helper_with.rs
+++ b/vendor/handlebars/src/helpers/helper_with.rs
@@ -25,7 +25,7 @@ impl HelperDef for WithHelper {
.ok_or_else(|| RenderError::new("Param not found for helper \"with\""))?;
if param.value().is_truthy(false) {
- let mut block = create_block(&param);
+ let mut block = create_block(param);
if let Some(block_param) = h.block_param() {
let mut params = BlockParams::new();
@@ -60,7 +60,6 @@ pub static WITH_HELPER: WithHelper = WithHelper;
#[cfg(test)]
mod test {
- use crate::json::value::to_json;
use crate::registry::Registry;
#[derive(Serialize)]
@@ -211,12 +210,12 @@ mod test {
assert!(handlebars
.register_template_string("t0", "{{#with a}}{{#with b}}{{../../d}}{{/with}}{{/with}}")
.is_ok());
- let data = btreemap! {
- "a".to_string() => to_json(&btreemap! {
- "b".to_string() => vec![btreemap!{"c".to_string() => vec![1]}]
- }),
- "d".to_string() => to_json(1)
- };
+ let data = json!({
+ "a": {
+ "b": [{"c": [1]}]
+ },
+ "d": 1
+ });
let r0 = handlebars.render("t0", &data);
assert_eq!(r0.ok().unwrap(), "1".to_string());
diff --git a/vendor/handlebars/src/helpers/mod.rs b/vendor/handlebars/src/helpers/mod.rs
index bfd50c1f4..ff5fa2495 100644
--- a/vendor/handlebars/src/helpers/mod.rs
+++ b/vendor/handlebars/src/helpers/mod.rs
@@ -32,7 +32,8 @@ pub type HelperResult = Result<(), RenderError>;
/// ```
/// use handlebars::*;
///
-/// fn upper(h: &Helper<'_, '_>, _: &Handlebars<'_>, _: &Context, rc: &mut RenderContext<'_, '_>, out: &mut Output)
+/// fn upper(h: &Helper<'_, '_>, _: &Handlebars<'_>, _: &Context, rc:
+/// &mut RenderContext<'_, '_>, out: &mut dyn Output)
/// -> HelperResult {
/// // get parameter from helper or throw an error
/// let param = h.param(0).and_then(|v| v.value().as_str()).unwrap_or("");
diff --git a/vendor/handlebars/src/helpers/scripting.rs b/vendor/handlebars/src/helpers/scripting.rs
index cec3b9763..abd567ae9 100644
--- a/vendor/handlebars/src/helpers/scripting.rs
+++ b/vendor/handlebars/src/helpers/scripting.rs
@@ -98,10 +98,16 @@ mod test {
let ast = engine.compile(&script).unwrap();
let params = vec![PathAndJson::new(None, ScopedJson::Derived(json!(true)))];
- let hash = btreemap! {
- "me" => PathAndJson::new(None, ScopedJson::Derived(json!("no"))),
- "you" => PathAndJson::new(None, ScopedJson::Derived(json!("yes"))),
- };
+
+ let mut hash = BTreeMap::new();
+ hash.insert(
+ "me",
+ PathAndJson::new(None, ScopedJson::Derived(json!("no"))),
+ );
+ hash.insert(
+ "you",
+ PathAndJson::new(None, ScopedJson::Derived(json!("yes"))),
+ );
let result = call_script_helper(&params, &hash, &engine, &ast)
.unwrap()
diff --git a/vendor/handlebars/src/json/path.rs b/vendor/handlebars/src/json/path.rs
index 8270371b2..17a7a91ee 100644
--- a/vendor/handlebars/src/json/path.rs
+++ b/vendor/handlebars/src/json/path.rs
@@ -6,7 +6,7 @@ use pest::Parser;
use crate::error::RenderError;
use crate::grammar::{HandlebarsParser, Rule};
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub enum PathSeg {
Named(String),
Ruled(Rule),
@@ -16,7 +16,7 @@ pub enum PathSeg {
///
/// It can be either a local variable like `@first`, `../@index`,
/// or a normal relative path like `a/b/c`.
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Path {
Relative((Vec<PathSeg>, String)),
Local((usize, String, String)),
diff --git a/vendor/handlebars/src/lib.rs b/vendor/handlebars/src/lib.rs
index 7e0aac830..1f9ab1ed3 100644
--- a/vendor/handlebars/src/lib.rs
+++ b/vendor/handlebars/src/lib.rs
@@ -1,4 +1,4 @@
-#![doc(html_root_url = "https://docs.rs/handlebars/4.1.0")]
+#![doc(html_root_url = "https://docs.rs/handlebars/4.3.3")]
#![cfg_attr(docsrs, feature(doc_cfg))]
//! # Handlebars
//!
@@ -73,7 +73,7 @@
//! Every time I look into a templating system, I will investigate its
//! support for [template inheritance][t].
//!
-//! [t]: https://docs.djangoproject.com/en/1.9/ref/templates/language/#template-inheritance
+//! [t]: https://docs.djangoproject.com/en/3.2/ref/templates/language/#template-inheritance
//!
//! Template include is not sufficient for template reuse. In most cases
//! you will need a skeleton of page as parent (header, footer, etc.), and
@@ -155,7 +155,7 @@
//! use handlebars::Handlebars;
//! use std::collections::BTreeMap;
//!
-//! # fn main() -> Result<(), Box<Error>> {
+//! # fn main() -> Result<(), Box<dyn Error>> {
//! let mut handlebars = Handlebars::new();
//! let source = "hello {{world}}";
//!
@@ -166,6 +166,14 @@
//! # }
//! ```
//!
+//! #### Additional features for loading template from
+//!
+//! * Feature `dir_source` enables template loading
+//! `register_templates_directory` from given directory.
+//! * Feature `rust-embed` enables template loading
+//! `register_embed_templates` from embedded resources in rust struct
+//! generated with `RustEmbed`.
+//!
//! ### Rendering Something
//!
//! Since handlebars is originally based on JavaScript type system. It supports dynamic features like duck-typing, truthy/falsey values. But for a static language like Rust, this is a little difficult. As a solution, we are using the `serde_json::value::Value` internally for data rendering.
@@ -188,7 +196,7 @@
//! age: i16,
//! }
//!
-//! # fn main() -> Result<(), Box<Error>> {
+//! # fn main() -> Result<(), Box<dyn Error>> {
//! let source = "Hello, {{name}}";
//!
//! let mut handlebars = Handlebars::new();
@@ -367,13 +375,8 @@
#[macro_use]
extern crate log;
-#[cfg(test)]
-#[macro_use]
-extern crate maplit;
#[macro_use]
extern crate pest_derive;
-#[macro_use]
-extern crate quick_error;
#[cfg(test)]
#[macro_use]
extern crate serde_derive;
diff --git a/vendor/handlebars/src/macros.rs b/vendor/handlebars/src/macros.rs
index 14cb0152c..bd1eab0bb 100644
--- a/vendor/handlebars/src/macros.rs
+++ b/vendor/handlebars/src/macros.rs
@@ -38,7 +38,7 @@
#[macro_export]
macro_rules! handlebars_helper {
- ($struct_name:ident: |$($name:ident: $tpe:tt),*
+ ($struct_name:ident: |$($name:ident: $tpe:tt$(<$($gen:ty),+>)?),*
$($(,)?{$($hash_name:ident: $hash_tpe:tt=$dft_val:literal),*})?
$($(,)?*$args:ident)?
$($(,)?**$kwargs:ident)?|
@@ -71,11 +71,11 @@ macro_rules! handlebars_helper {
stringify!($struct_name), stringify!($name),
)))
.and_then(|x|
- handlebars_helper!(@as_json_value x, $tpe)
+ handlebars_helper!(@as_json_value x, $tpe$(<$($gen),+>)?)
.ok_or_else(|| $crate::RenderError::new(&format!(
"`{}` helper: Couldn't convert parameter {} to type `{}`. \
It's {:?} as JSON. Got these params: {:?}",
- stringify!($struct_name), stringify!($name), stringify!($tpe),
+ stringify!($struct_name), stringify!($name), stringify!($tpe$(<$($gen),+>)?),
x, h.params(),
)))
)?;
@@ -117,6 +117,7 @@ macro_rules! handlebars_helper {
(@as_json_value $x:ident, bool) => { $x.as_bool() };
(@as_json_value $x:ident, null) => { $x.as_null() };
(@as_json_value $x:ident, Json) => { Some($x) };
+ (@as_json_value $x:ident, $tpe:tt$(<$($gen:ty),+>)?) => { serde_json::from_value::<$tpe$(<$($gen),+>)?>($x.clone()).ok() };
}
#[cfg(feature = "no_logging")]
diff --git a/vendor/handlebars/src/output.rs b/vendor/handlebars/src/output.rs
index f1c5865a5..67e62b849 100644
--- a/vendor/handlebars/src/output.rs
+++ b/vendor/handlebars/src/output.rs
@@ -46,3 +46,9 @@ impl StringOutput {
String::from_utf8(self.buf)
}
}
+
+impl Default for StringOutput {
+ fn default() -> Self {
+ StringOutput::new()
+ }
+}
diff --git a/vendor/handlebars/src/partial.rs b/vendor/handlebars/src/partial.rs
index a472d5d14..bcf9803fd 100644
--- a/vendor/handlebars/src/partial.rs
+++ b/vendor/handlebars/src/partial.rs
@@ -20,7 +20,7 @@ fn find_partial<'reg: 'rc, 'rc: 'a, 'a>(
d: &Decorator<'reg, 'rc>,
name: &str,
) -> Result<Option<Cow<'a, Template>>, RenderError> {
- if let Some(ref partial) = rc.get_partial(name) {
+ if let Some(partial) = rc.get_partial(name) {
return Ok(Some(Cow::Borrowed(partial)));
}
@@ -52,29 +52,38 @@ pub fn expand_partial<'reg: 'rc, 'rc>(
return Err(RenderError::new("Cannot include self in >"));
}
- // if tname == PARTIAL_BLOCK
let partial = find_partial(rc, r, d, tname)?;
if let Some(t) = partial {
// clone to avoid lifetime issue
// FIXME refactor this to avoid
let mut local_rc = rc.clone();
+
+ // if tname == PARTIAL_BLOCK
let is_partial_block = tname == PARTIAL_BLOCK;
+ // add partial block depth there are consecutive partial
+ // blocks in the stack.
if is_partial_block {
local_rc.inc_partial_block_depth();
+ } else {
+ // depth cannot be lower than 0, which is guaranted in the
+ // `dec_partial_block_depth` method
+ local_rc.dec_partial_block_depth();
}
+ let mut block = None;
let mut block_created = false;
- if let Some(ref base_path) = d.param(0).and_then(|p| p.context_path()) {
+ // create context if param given
+ if let Some(base_path) = d.param(0).and_then(|p| p.context_path()) {
// path given, update base_path
- let mut block = BlockContext::new();
- *block.base_path_mut() = base_path.to_vec();
- block_created = true;
- local_rc.push_block(block);
- } else if !d.hash().is_empty() {
- let mut block = BlockContext::new();
+ let mut block_inner = BlockContext::new();
+ *block_inner.base_path_mut() = base_path.to_vec();
+ block = Some(block_inner);
+ }
+
+ if !d.hash().is_empty() {
// hash given, update base_value
let hash_ctx = d
.hash()
@@ -86,9 +95,25 @@ pub fn expand_partial<'reg: 'rc, 'rc>(
local_rc.evaluate2(ctx, &Path::current())?.as_json(),
&hash_ctx,
);
- block.set_base_value(merged_context);
+
+ if let Some(ref mut block_inner) = block {
+ block_inner.set_base_value(merged_context);
+ } else {
+ let mut block_inner = BlockContext::new();
+ block_inner.set_base_value(merged_context);
+ block = Some(block_inner);
+ }
+ }
+
+ if let Some(block_inner) = block {
+ // because block is moved here, we need another bool variable to track
+ // its status for later cleanup
block_created = true;
- local_rc.push_block(block);
+ // clear blocks to prevent block params from parent
+ // template to be leaked into partials
+ // see `test_partial_context_issue_495` for the case.
+ local_rc.clear_blocks();
+ local_rc.push_block(block_inner);
}
// @partial-block
@@ -96,6 +121,9 @@ pub fn expand_partial<'reg: 'rc, 'rc>(
local_rc.push_partial_block(pb);
}
+ // indent
+ local_rc.set_indent_string(d.indent());
+
let result = t.render(r, ctx, &mut local_rc, out);
// cleanup
@@ -103,10 +131,6 @@ pub fn expand_partial<'reg: 'rc, 'rc>(
local_rc.pop_block();
}
- if is_partial_block {
- local_rc.dec_partial_block_depth();
- }
-
if d.template().is_some() {
local_rc.pop_partial_block();
}
@@ -174,10 +198,7 @@ mod test {
"include navbar".to_string()
);
assert_eq!(
- handlebars
- .render("t6", &btreemap! {"a".to_string() => "2".to_string()})
- .ok()
- .unwrap(),
+ handlebars.render("t6", &json!({"a": "2"})).ok().unwrap(),
"2".to_string()
);
assert_eq!(
@@ -258,6 +279,19 @@ mod test {
}
#[test]
+ fn teset_partial_context_with_both_hash_and_param() {
+ let mut hbs = Registry::new();
+ hbs.register_template_string("one", "This is a test. {{> two this name=\"fred\" }}")
+ .unwrap();
+ hbs.register_template_string("two", "Lets test {{name}} and {{root_name}}")
+ .unwrap();
+ assert_eq!(
+ "This is a test. Lets test fred and tom",
+ hbs.render("one", &json!({"root_name": "tom"})).unwrap()
+ );
+ }
+
+ #[test]
fn test_partial_subexpression_context_hash() {
let mut hbs = Registry::new();
hbs.register_template_string("one", "This is a test. {{> (x @root) name=\"fred\" }}")
@@ -297,7 +331,7 @@ mod test {
}
#[test]
- fn test_nested_partials() {
+ fn test_nested_partial_block() {
let mut handlebars = Registry::new();
let template1 = "<outer>{{> @partial-block }}</outer>";
let template2 = "{{#> t1 }}<inner>{{> @partial-block }}</inner>{{/ t1 }}";
@@ -330,4 +364,293 @@ mod test {
"fruit: carrot,fruit: tomato,"
);
}
+
+ #[test]
+ fn line_stripping_with_inline_and_partial() {
+ let tpl0 = r#"{{#*inline "foo"}}foo
+{{/inline}}
+{{> foo}}
+{{> foo}}
+{{> foo}}"#;
+ let tpl1 = r#"{{#*inline "foo"}}foo{{/inline}}
+{{> foo}}
+{{> foo}}
+{{> foo}}"#;
+
+ let hbs = Registry::new();
+ assert_eq!(
+ r#"foo
+foo
+foo
+"#,
+ hbs.render_template(tpl0, &json!({})).unwrap()
+ );
+ assert_eq!(
+ r#"
+foofoofoo"#,
+ hbs.render_template(tpl1, &json!({})).unwrap()
+ );
+ }
+
+ #[test]
+ fn test_partial_indent() {
+ let outer = r#" {{> inner inner_solo}}
+
+{{#each inners}}
+ {{> inner}}
+{{/each}}
+
+ {{#each inners}}
+ {{> inner}}
+ {{/each}}
+"#;
+ let inner = r#"name: {{name}}
+"#;
+
+ let mut hbs = Registry::new();
+
+ hbs.register_template_string("inner", inner).unwrap();
+ hbs.register_template_string("outer", outer).unwrap();
+
+ let result = hbs
+ .render(
+ "outer",
+ &json!({
+ "inner_solo": {"name": "inner_solo"},
+ "inners": [
+ {"name": "hello"},
+ {"name": "there"}
+ ]
+ }),
+ )
+ .unwrap();
+
+ assert_eq!(
+ result,
+ r#" name: inner_solo
+
+ name: hello
+ name: there
+
+ name: hello
+ name: there
+"#
+ );
+ }
+ // Rule::partial_expression should not trim leading indent by default
+
+ #[test]
+ fn test_partial_prevent_indent() {
+ let outer = r#" {{> inner inner_solo}}
+
+{{#each inners}}
+ {{> inner}}
+{{/each}}
+
+ {{#each inners}}
+ {{> inner}}
+ {{/each}}
+"#;
+ let inner = r#"name: {{name}}
+"#;
+
+ let mut hbs = Registry::new();
+ hbs.set_prevent_indent(true);
+
+ hbs.register_template_string("inner", inner).unwrap();
+ hbs.register_template_string("outer", outer).unwrap();
+
+ let result = hbs
+ .render(
+ "outer",
+ &json!({
+ "inner_solo": {"name": "inner_solo"},
+ "inners": [
+ {"name": "hello"},
+ {"name": "there"}
+ ]
+ }),
+ )
+ .unwrap();
+
+ assert_eq!(
+ result,
+ r#" name: inner_solo
+
+ name: hello
+ name: there
+
+ name: hello
+ name: there
+"#
+ );
+ }
+
+ #[test]
+ fn test_nested_partials() {
+ let mut hb = Registry::new();
+ hb.register_template_string("partial", "{{> @partial-block}}")
+ .unwrap();
+ hb.register_template_string(
+ "index",
+ r#"{{#>partial}}
+ Yo
+ {{#>partial}}
+ Yo 2
+ {{/partial}}
+{{/partial}}"#,
+ )
+ .unwrap();
+ assert_eq!(
+ r#" Yo
+ Yo 2
+"#,
+ hb.render("index", &()).unwrap()
+ );
+
+ hb.register_template_string("partial2", "{{> @partial-block}}")
+ .unwrap();
+ let r2 = hb
+ .render_template(
+ r#"{{#> partial}}
+{{#> partial2}}
+:(
+{{/partial2}}
+{{/partial}}"#,
+ &(),
+ )
+ .unwrap();
+ assert_eq!(":(\n", r2);
+ }
+
+ #[test]
+ fn test_partial_context_issue_495() {
+ let mut hb = Registry::new();
+ hb.register_template_string(
+ "t1",
+ r#"{{~#*inline "displayName"~}}
+Template:{{name}}
+{{/inline}}
+{{#each data as |name|}}
+Name:{{name}}
+{{>displayName name="aaaa"}}
+{{/each}}"#,
+ )
+ .unwrap();
+
+ hb.register_template_string(
+ "t1",
+ r#"{{~#*inline "displayName"~}}
+Template:{{this}}
+{{/inline}}
+{{#each data as |name|}}
+Name:{{name}}
+{{>displayName}}
+{{/each}}"#,
+ )
+ .unwrap();
+
+ let data = json!({
+ "data": ["hudel", "test"]
+ });
+
+ assert_eq!(
+ r#"Name:hudel
+Template:hudel
+Name:test
+Template:test
+"#,
+ hb.render("t1", &data).unwrap()
+ );
+ }
+
+ #[test]
+ fn test_multiline_partial_indent() {
+ let mut hb = Registry::new();
+
+ hb.register_template_string(
+ "t1",
+ r#"{{#*inline "thepartial"}}
+ inner first line
+ inner second line
+{{/inline}}
+ {{> thepartial}}
+outer third line"#,
+ )
+ .unwrap();
+ assert_eq!(
+ r#" inner first line
+ inner second line
+outer third line"#,
+ hb.render("t1", &()).unwrap()
+ );
+
+ hb.register_template_string(
+ "t2",
+ r#"{{#*inline "thepartial"}}inner first line
+inner second line
+{{/inline}}
+ {{> thepartial}}
+outer third line"#,
+ )
+ .unwrap();
+ assert_eq!(
+ r#" inner first line
+ inner second line
+outer third line"#,
+ hb.render("t2", &()).unwrap()
+ );
+
+ hb.register_template_string(
+ "t3",
+ r#"{{#*inline "thepartial"}}{{a}}{{/inline}}
+ {{> thepartial}}
+outer third line"#,
+ )
+ .unwrap();
+ assert_eq!(
+ r#"
+ inner first line
+ inner second lineouter third line"#,
+ hb.render("t3", &json!({"a": "inner first line\ninner second line"}))
+ .unwrap()
+ );
+
+ hb.register_template_string(
+ "t4",
+ r#"{{#*inline "thepartial"}}
+ inner first line
+ inner second line
+{{/inline}}
+ {{~> thepartial}}
+outer third line"#,
+ )
+ .unwrap();
+ assert_eq!(
+ r#" inner first line
+ inner second line
+outer third line"#,
+ hb.render("t4", &()).unwrap()
+ );
+
+ let mut hb2 = Registry::new();
+ hb2.set_prevent_indent(true);
+
+ hb2.register_template_string(
+ "t1",
+ r#"{{#*inline "thepartial"}}
+ inner first line
+ inner second line
+{{/inline}}
+ {{> thepartial}}
+outer third line"#,
+ )
+ .unwrap();
+ assert_eq!(
+ r#" inner first line
+ inner second line
+outer third line"#,
+ hb2.render("t1", &()).unwrap()
+ )
+ }
}
diff --git a/vendor/handlebars/src/registry.rs b/vendor/handlebars/src/registry.rs
index e7f5f1cfd..438f8573c 100644
--- a/vendor/handlebars/src/registry.rs
+++ b/vendor/handlebars/src/registry.rs
@@ -17,12 +17,10 @@ use crate::output::{Output, StringOutput, WriteOutput};
use crate::render::{RenderContext, Renderable};
use crate::sources::{FileSource, Source};
use crate::support::str::{self, StringWriter};
-use crate::template::Template;
+use crate::template::{Template, TemplateOptions};
#[cfg(feature = "dir_source")]
-use std::path;
-#[cfg(feature = "dir_source")]
-use walkdir::{DirEntry, WalkDir};
+use walkdir::WalkDir;
#[cfg(feature = "script_helper")]
use rhai::Engine;
@@ -30,6 +28,9 @@ use rhai::Engine;
#[cfg(feature = "script_helper")]
use crate::helpers::scripting::ScriptHelper;
+#[cfg(feature = "rust-embed")]
+use rust_embed::RustEmbed;
+
/// This type represents an *escape fn*, that is a function whose purpose it is
/// to escape potentially problematic characters in a string.
///
@@ -62,6 +63,7 @@ pub struct Registry<'reg> {
escape_fn: EscapeFn,
strict_mode: bool,
dev_mode: bool,
+ prevent_indent: bool,
#[cfg(feature = "script_helper")]
pub(crate) engine: Arc<Engine>,
@@ -90,21 +92,6 @@ impl<'reg> Default for Registry<'reg> {
}
}
-#[cfg(feature = "dir_source")]
-fn filter_file(entry: &DirEntry, suffix: &str) -> bool {
- let path = entry.path();
-
- // ignore hidden files, emacs buffers and files with wrong suffix
- !path.is_file()
- || path
- .file_name()
- .map(|s| {
- let ds = s.to_string_lossy();
- ds.starts_with('.') || ds.starts_with('#') || !ds.ends_with(suffix)
- })
- .unwrap_or(true)
-}
-
#[cfg(feature = "script_helper")]
fn rhai_engine() -> Engine {
Engine::new()
@@ -120,6 +107,7 @@ impl<'reg> Registry<'reg> {
escape_fn: Arc::new(html_escape),
strict_mode: false,
dev_mode: false,
+ prevent_indent: false,
#[cfg(feature = "script_helper")]
engine: Arc::new(rhai_engine()),
#[cfg(feature = "script_helper")]
@@ -178,7 +166,7 @@ impl<'reg> Registry<'reg> {
/// Return dev mode state, default is false
///
/// With dev mode turned on, handlebars enables a set of development
- /// firendly features, that may affect its performance.
+ /// friendly features, that may affect its performance.
pub fn dev_mode(&self) -> bool {
self.dev_mode
}
@@ -186,9 +174,30 @@ impl<'reg> Registry<'reg> {
/// Enable or disable dev mode
///
/// With dev mode turned on, handlebars enables a set of development
- /// firendly features, that may affect its performance.
+ /// friendly features, that may affect its performance.
+ ///
+ /// **Note that you have to enable dev mode before adding templates to
+ /// the registry**. Otherwise it won't take effect at all.
pub fn set_dev_mode(&mut self, enabled: bool) {
self.dev_mode = enabled;
+
+ // clear template source when disabling dev mode
+ if !enabled {
+ self.template_sources.clear();
+ }
+ }
+
+ /// Enable or disable indent for partial include tag `{{>}}`
+ ///
+ /// By default handlebars keeps indent whitespaces for partial
+ /// include tag, to change this behaviour, set this toggle to `true`.
+ pub fn set_prevent_indent(&mut self, enable: bool) {
+ self.prevent_indent = enable;
+ }
+
+ /// Return state for `prevent_indent` option, default to `false`.
+ pub fn prevent_indent(&self) -> bool {
+ self.prevent_indent
}
/// Register a `Template`
@@ -196,6 +205,9 @@ impl<'reg> Registry<'reg> {
/// This is infallible since the template has already been parsed and
/// insert cannot fail. If there is an existing template with this name it
/// will be overwritten.
+ ///
+ /// Dev mode doesn't apply for pre-compiled template because it's lifecycle
+ /// is not managed by the registry.
pub fn register_template(&mut self, name: &str, tpl: Template) {
self.templates.insert(name.to_string(), tpl);
}
@@ -211,7 +223,13 @@ impl<'reg> Registry<'reg> {
where
S: AsRef<str>,
{
- let template = Template::compile_with_name(tpl_str, name.to_owned())?;
+ let template = Template::compile2(
+ tpl_str.as_ref(),
+ TemplateOptions {
+ name: Some(name.to_owned()),
+ prevent_indent: self.prevent_indent,
+ },
+ )?;
self.register_template(name, template);
Ok(())
}
@@ -227,7 +245,10 @@ impl<'reg> Registry<'reg> {
self.register_template_string(name, partial_str)
}
- /// Register a template from a path
+ /// Register a template from a path on file system
+ ///
+ /// If dev mode is enabled, the registry will keep reading the template file
+ /// from file system everytime it's visited.
pub fn register_template_file<P>(
&mut self,
name: &str,
@@ -262,11 +283,14 @@ impl<'reg> Registry<'reg> {
///
/// This method is not available by default.
/// You will need to enable the `dir_source` feature to use it.
+ ///
+ /// When dev_mode enabled, like `register_template_file`, templates is reloaded
+ /// from file system everytime it's visied.
#[cfg(feature = "dir_source")]
#[cfg_attr(docsrs, doc(cfg(feature = "dir_source")))]
pub fn register_templates_directory<P>(
&mut self,
- tpl_extension: &'static str,
+ tpl_extension: &str,
dir_path: P,
) -> Result<(), TemplateError>
where
@@ -274,40 +298,88 @@ impl<'reg> Registry<'reg> {
{
let dir_path = dir_path.as_ref();
- let prefix_len = if dir_path
- .to_string_lossy()
- .ends_with(|c| c == '\\' || c == '/')
- // `/` will work on windows too so we still need to check
- {
- dir_path.to_string_lossy().len()
- } else {
- dir_path.to_string_lossy().len() + 1
- };
+ // Allowing dots at the beginning as to not break old
+ // applications.
+ let tpl_extension = tpl_extension.strip_prefix('.').unwrap_or(tpl_extension);
let walker = WalkDir::new(dir_path);
let dir_iter = walker
.min_depth(1)
.into_iter()
- .filter(|e| e.is_ok() && !filter_file(e.as_ref().unwrap(), tpl_extension));
+ .filter_map(|e| e.ok().map(|e| e.into_path()))
+ // Checks if extension matches
+ .filter(|tpl_path| {
+ tpl_path
+ .extension()
+ .map(|extension| extension == tpl_extension)
+ .unwrap_or(false)
+ })
+ // Rejects any hidden or temporary files.
+ .filter(|tpl_path| {
+ tpl_path
+ .file_stem()
+ .map(|stem| stem.to_string_lossy())
+ .map(|stem| !(stem.starts_with('.') || stem.starts_with('#')))
+ .unwrap_or(false)
+ })
+ .filter_map(|tpl_path| {
+ tpl_path
+ .strip_prefix(dir_path)
+ .ok()
+ .map(|tpl_canonical_name| {
+ tpl_canonical_name
+ .with_extension("")
+ .components()
+ .map(|component| component.as_os_str().to_string_lossy())
+ .collect::<Vec<_>>()
+ .join("/")
+ })
+ .map(|tpl_canonical_name| (tpl_canonical_name, tpl_path))
+ });
+
+ for (tpl_canonical_name, tpl_path) in dir_iter {
+ self.register_template_file(&tpl_canonical_name, &tpl_path)?;
+ }
- for entry in dir_iter {
- let entry = entry?;
+ Ok(())
+ }
- let tpl_path = entry.path();
- let tpl_file_path = entry.path().to_string_lossy();
+ /// Register templates using a
+ /// [RustEmbed](https://github.com/pyros2097/rust-embed) type
+ ///
+ /// File names from embed struct are used as template name.
+ ///
+ /// ```skip
+ /// #[derive(RustEmbed)]
+ /// #[folder = "templates"]
+ /// struct Assets;
+ ///
+ /// let mut hbs = Handlebars::new();
+ /// hbs.register_embed_templates::<Assets>();
+ /// ```
+ ///
+ #[cfg(feature = "rust-embed")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "rust-embed")))]
+ pub fn register_embed_templates<E>(&mut self) -> Result<(), TemplateError>
+ where
+ E: RustEmbed,
+ {
+ for item in E::iter() {
+ let file_name = item.as_ref();
+ if let Some(file) = E::get(file_name) {
+ let data = file.data;
- let tpl_name = &tpl_file_path[prefix_len..tpl_file_path.len() - tpl_extension.len()];
- // replace platform path separator with our internal one
- let tpl_canonical_name = tpl_name.replace(path::MAIN_SEPARATOR, "/");
- self.register_template_file(&tpl_canonical_name, &tpl_path)?;
+ let tpl_content = String::from_utf8_lossy(data.as_ref());
+ self.register_template_string(file_name, tpl_content)?;
+ }
}
-
Ok(())
}
/// Remove a template from the registry
pub fn unregister_template(&mut self, name: &str) {
self.templates.remove(name);
+ self.template_sources.remove(name);
}
/// Register a helper
@@ -335,7 +407,6 @@ impl<'reg> Registry<'reg> {
/// (value * 100).to_string() + label
/// ```
///
- ///
#[cfg(feature = "script_helper")]
#[cfg_attr(docsrs, doc(cfg(feature = "script_helper")))]
pub fn register_script_helper(&mut self, name: &str, script: &str) -> Result<(), ScriptError> {
@@ -347,6 +418,9 @@ impl<'reg> Registry<'reg> {
}
/// Register a [rhai](https://docs.rs/rhai/) script from file
+ ///
+ /// When dev mode is enable, script file is reloaded from original file
+ /// everytime it is called.
#[cfg(feature = "script_helper")]
#[cfg_attr(docsrs, doc(cfg(feature = "script_helper")))]
pub fn register_script_helper_file<P>(
@@ -365,6 +439,22 @@ impl<'reg> Registry<'reg> {
self.register_script_helper(name, &script)
}
+ /// Borrow a read-only reference to current rhai engine
+ #[cfg(feature = "script_helper")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "script_helper")))]
+ pub fn engine(&self) -> &Engine {
+ self.engine.as_ref()
+ }
+
+ /// Set a custom rhai engine for the registry.
+ ///
+ /// *Note that* you need to set custom engine before adding scripts.
+ #[cfg(feature = "script_helper")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "script_helper")))]
+ pub fn set_engine(&mut self, engine: Engine) {
+ self.engine = Arc::new(engine);
+ }
+
/// Register a decorator
pub fn register_decorator(
&mut self,
@@ -389,7 +479,7 @@ impl<'reg> Registry<'reg> {
/// Get a reference to the current *escape fn*.
pub fn get_escape_fn(&self) -> &dyn Fn(&str) -> String {
- &*self.escape_fn
+ self.escape_fn.as_ref()
}
/// Return `true` if a template is registered for the given name
@@ -411,7 +501,15 @@ impl<'reg> Registry<'reg> {
let r = source
.load()
.map_err(|e| TemplateError::from((e, name.to_owned())))
- .and_then(|tpl_str| Template::compile_with_name(tpl_str, name.to_owned()))
+ .and_then(|tpl_str| {
+ Template::compile2(
+ tpl_str.as_ref(),
+ TemplateOptions {
+ name: Some(name.to_owned()),
+ prevent_indent: self.prevent_indent,
+ },
+ )
+ })
.map(Cow::Owned)
.map_err(RenderError::from);
Some(r)
@@ -433,6 +531,7 @@ impl<'reg> Registry<'reg> {
}
/// Return a registered helper
+ #[inline]
pub(crate) fn get_or_load_helper(
&'reg self,
name: &str,
@@ -460,6 +559,7 @@ impl<'reg> Registry<'reg> {
}
/// Return a registered decorator
+ #[inline]
pub(crate) fn get_decorator(
&self,
name: &str,
@@ -468,6 +568,10 @@ impl<'reg> Registry<'reg> {
}
/// Return all templates registered
+ ///
+ /// **Note that** in dev mode, the template returned from this method may
+ /// not reflect its latest state. This method doesn't try to reload templates
+ /// from its source.
pub fn get_templates(&self) -> &HashMap<String, Template> {
&self.templates
}
@@ -475,6 +579,7 @@ impl<'reg> Registry<'reg> {
/// Unregister all templates
pub fn clear_templates(&mut self) {
self.templates.clear();
+ self.template_sources.clear();
}
#[inline]
@@ -489,7 +594,7 @@ impl<'reg> Registry<'reg> {
{
self.get_or_load_template(name).and_then(|t| {
let mut render_context = RenderContext::new(t.name.as_ref());
- t.render(self, &ctx, &mut render_context, output)
+ t.render(self, ctx, &mut render_context, output)
})
}
@@ -516,7 +621,7 @@ impl<'reg> Registry<'reg> {
output.into_string().map_err(RenderError::from)
}
- /// Render a registered template and write some data to the `std::io::Write`
+ /// Render a registered template and write data to the `std::io::Write`
pub fn render_to_write<T, W>(&self, name: &str, data: &T, writer: W) -> Result<(), RenderError>
where
T: Serialize,
@@ -527,6 +632,21 @@ impl<'reg> Registry<'reg> {
self.render_to_output(name, &ctx, &mut output)
}
+ /// Render a registered template using reusable `Context`, and write data to
+ /// the `std::io::Write`
+ pub fn render_with_context_to_write<W>(
+ &self,
+ name: &str,
+ ctx: &Context,
+ writer: W,
+ ) -> Result<(), RenderError>
+ where
+ W: Write,
+ {
+ let mut output = WriteOutput::new(writer);
+ self.render_to_output(name, ctx, &mut output)
+ }
+
/// Render a template string using current registry without registering it
pub fn render_template<T>(&self, template_string: &str, data: &T) -> Result<String, RenderError>
where
@@ -537,23 +657,52 @@ impl<'reg> Registry<'reg> {
Ok(writer.into_string())
}
- /// Render a template string using reused context data
+ /// Render a template string using reusable context data
pub fn render_template_with_context(
&self,
template_string: &str,
ctx: &Context,
) -> Result<String, RenderError> {
- let tpl = Template::compile(template_string)?;
+ let tpl = Template::compile2(
+ template_string,
+ TemplateOptions {
+ prevent_indent: self.prevent_indent,
+ ..Default::default()
+ },
+ )?;
let mut out = StringOutput::new();
{
let mut render_context = RenderContext::new(None);
- tpl.render(self, &ctx, &mut render_context, &mut out)?;
+ tpl.render(self, ctx, &mut render_context, &mut out)?;
}
out.into_string().map_err(RenderError::from)
}
+ /// Render a template string using resuable context, and write data into
+ /// `std::io::Write`
+ pub fn render_template_with_context_to_write<W>(
+ &self,
+ template_string: &str,
+ ctx: &Context,
+ writer: W,
+ ) -> Result<(), RenderError>
+ where
+ W: Write,
+ {
+ let tpl = Template::compile2(
+ template_string,
+ TemplateOptions {
+ prevent_indent: self.prevent_indent,
+ ..Default::default()
+ },
+ )?;
+ let mut render_context = RenderContext::new(None);
+ let mut out = WriteOutput::new(writer);
+ tpl.render(self, ctx, &mut render_context, &mut out)
+ }
+
/// Render a template string using current registry without registering it
pub fn render_template_to_write<T, W>(
&self,
@@ -565,11 +714,8 @@ impl<'reg> Registry<'reg> {
T: Serialize,
W: Write,
{
- let tpl = Template::compile(template_string)?;
let ctx = Context::wraps(data)?;
- let mut render_context = RenderContext::new(None);
- let mut out = WriteOutput::new(writer);
- tpl.render(self, &ctx, &mut render_context, &mut out)
+ self.render_template_with_context_to_write(template_string, &ctx, writer)
}
}
@@ -944,8 +1090,7 @@ mod test {
.unwrap();
assert_eq!(
"0123",
- reg.render_with_context("t0", &Context::wraps(&data).unwrap())
- .unwrap()
+ reg.render_with_context("t0", &Context::from(data)).unwrap()
);
}
@@ -1089,4 +1234,17 @@ mod test {
dir.close().unwrap();
}
+
+ #[test]
+ #[cfg(feature = "script_helper")]
+ fn test_engine_access() {
+ use rhai::Engine;
+
+ let mut registry = Registry::new();
+ let mut eng = Engine::new();
+ eng.set_max_string_size(1000);
+ registry.set_engine(eng);
+
+ assert_eq!(1000, registry.engine().max_string_size());
+ }
}
diff --git a/vendor/handlebars/src/render.rs b/vendor/handlebars/src/render.rs
index 188ea221a..036352b3a 100644
--- a/vendor/handlebars/src/render.rs
+++ b/vendor/handlebars/src/render.rs
@@ -14,6 +14,7 @@ use crate::json::value::{JsonRender, PathAndJson, ScopedJson};
use crate::output::{Output, StringOutput};
use crate::partial;
use crate::registry::Registry;
+use crate::support;
use crate::template::TemplateElement::*;
use crate::template::{
BlockParam, DecoratorTemplate, HelperTemplate, Parameter, Template, TemplateElement,
@@ -47,10 +48,11 @@ pub struct RenderContextInner<'reg: 'rc, 'rc> {
/// root template name
root_template: Option<&'reg String>,
disable_escape: bool,
+ indent_string: Option<&'reg String>,
}
impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> {
- /// Create a render context from a `Write`
+ /// Create a render context
pub fn new(root_template: Option<&'reg String>) -> RenderContext<'reg, 'rc> {
let inner = Rc::new(RenderContextInner {
partials: BTreeMap::new(),
@@ -60,6 +62,7 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> {
current_template: None,
root_template,
disable_escape: false,
+ indent_string: None,
});
let mut blocks = VecDeque::with_capacity(5);
@@ -73,7 +76,6 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> {
}
}
- // TODO: better name
pub(crate) fn new_for_block(&self) -> RenderContext<'reg, 'rc> {
let inner = self.inner.clone();
@@ -101,6 +103,10 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> {
self.blocks.pop_front();
}
+ pub(crate) fn clear_blocks(&mut self) {
+ self.blocks.clear();
+ }
+
/// Borrow a reference to current block context
pub fn block(&self) -> Option<&BlockContext<'reg>> {
self.blocks.front()
@@ -190,7 +196,19 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> {
}
pub(crate) fn dec_partial_block_depth(&mut self) {
- self.inner_mut().partial_block_depth -= 1;
+ let depth = &mut self.inner_mut().partial_block_depth;
+ if *depth > 0 {
+ *depth -= 1;
+ }
+ }
+
+ pub(crate) fn set_indent_string(&mut self, indent: Option<&'reg String>) {
+ self.inner_mut().indent_string = indent;
+ }
+
+ #[inline]
+ pub(crate) fn get_indent_string(&self) -> Option<&'reg String> {
+ self.inner.indent_string
}
/// Remove a registered partial
@@ -201,7 +219,7 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> {
fn get_local_var(&self, level: usize, name: &str) -> Option<&Json> {
self.blocks
.get(level)
- .and_then(|blk| blk.get_local_var(&name))
+ .and_then(|blk| blk.get_local_var(name))
}
/// Test if given template name is current template.
@@ -275,9 +293,10 @@ impl<'reg, 'rc> fmt::Debug for RenderContextInner<'reg, 'rc> {
f.debug_struct("RenderContextInner")
.field("partials", &self.partials)
.field("partial_block_stack", &self.partial_block_stack)
+ .field("partial_block_depth", &self.partial_block_depth)
.field("root_template", &self.root_template)
.field("current_template", &self.current_template)
- .field("disable_eacape", &self.disable_escape)
+ .field("disable_escape", &self.disable_escape)
.finish()
}
}
@@ -435,6 +454,7 @@ pub struct Decorator<'reg, 'rc> {
params: Vec<PathAndJson<'reg, 'rc>>,
hash: BTreeMap<&'reg str, PathAndJson<'reg, 'rc>>,
template: Option<&'reg Template>,
+ indent: Option<&'reg String>,
}
impl<'reg: 'rc, 'rc> Decorator<'reg, 'rc> {
@@ -463,6 +483,7 @@ impl<'reg: 'rc, 'rc> Decorator<'reg, 'rc> {
params: pv,
hash: hm,
template: dt.template.as_ref(),
+ indent: dt.indent.as_ref(),
})
}
@@ -495,6 +516,10 @@ impl<'reg: 'rc, 'rc> Decorator<'reg, 'rc> {
pub fn template(&self) -> Option<&'reg Template> {
self.template
}
+
+ pub fn indent(&self) -> Option<&'reg String> {
+ self.indent
+ }
}
/// Render trait
@@ -747,6 +772,20 @@ pub(crate) fn do_escape(r: &Registry<'_>, rc: &RenderContext<'_, '_>, content: S
}
}
+#[inline]
+fn indent_aware_write(
+ v: &str,
+ rc: &mut RenderContext<'_, '_>,
+ out: &mut dyn Output,
+) -> Result<(), RenderError> {
+ if let Some(indent) = rc.get_indent_string() {
+ out.write(support::str::with_indent(v, indent).as_ref())?;
+ } else {
+ out.write(v.as_ref())?;
+ }
+ Ok(())
+}
+
impl Renderable for TemplateElement {
fn render<'reg: 'rc, 'rc>(
&'reg self,
@@ -755,11 +794,8 @@ impl Renderable for TemplateElement {
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> Result<(), RenderError> {
- match *self {
- RawString(ref v) => {
- out.write(v.as_ref())?;
- Ok(())
- }
+ match self {
+ RawString(ref v) => indent_aware_write(v.as_ref(), rc, out),
Expression(ref ht) | HtmlExpression(ref ht) => {
let is_html_expression = matches!(self, HtmlExpression(_));
if is_html_expression {
@@ -789,8 +825,7 @@ impl Renderable for TemplateElement {
} else {
let rendered = context_json.value().render();
let output = do_escape(registry, rc, rendered);
- out.write(output.as_ref())?;
- Ok(())
+ indent_aware_write(output.as_ref(), rc, out)
}
}
} else {
@@ -1117,3 +1152,37 @@ fn test_zero_args_heler() {
"Output name: first_name not resolved"
);
}
+
+#[test]
+fn test_identifiers_starting_with_numbers() {
+ let mut r = Registry::new();
+
+ assert!(r
+ .register_template_string("r1", "{{#if 0a}}true{{/if}}")
+ .is_ok());
+ let r1 = r.render("r1", &json!({"0a": true})).unwrap();
+ assert_eq!(r1, "true");
+
+ assert!(r.register_template_string("r2", "{{eq 1a 1}}").is_ok());
+ let r2 = r.render("r2", &json!({"1a": 2, "a": 1})).unwrap();
+ assert_eq!(r2, "false");
+
+ assert!(r
+ .register_template_string("r3", "0: {{0}} {{#if (eq 0 true)}}resolved from context{{/if}}\n1a: {{1a}} {{#if (eq 1a true)}}resolved from context{{/if}}\n2_2: {{2_2}} {{#if (eq 2_2 true)}}resolved from context{{/if}}") // YUP it is just eq that barfs! is if handled specially? maybe this test should go nearer to specific helpers that fail?
+ .is_ok());
+ let r3 = r
+ .render("r3", &json!({"0": true, "1a": true, "2_2": true}))
+ .unwrap();
+ assert_eq!(
+ r3,
+ "0: true \n1a: true resolved from context\n2_2: true resolved from context"
+ );
+
+ // these should all be errors:
+ assert!(r.register_template_string("r4", "{{eq 1}}").is_ok());
+ assert!(r.register_template_string("r5", "{{eq a1}}").is_ok());
+ assert!(r.register_template_string("r6", "{{eq 1a}}").is_ok());
+ assert!(r.render("r4", &()).is_err());
+ assert!(r.render("r5", &()).is_err());
+ assert!(r.render("r6", &()).is_err());
+}
diff --git a/vendor/handlebars/src/support.rs b/vendor/handlebars/src/support.rs
index bd5564d32..b02aca6db 100644
--- a/vendor/handlebars/src/support.rs
+++ b/vendor/handlebars/src/support.rs
@@ -57,6 +57,64 @@ pub mod str {
output
}
+ /// add indent for lines but last
+ pub fn with_indent(s: &str, indent: &str) -> String {
+ let mut output = String::new();
+
+ let mut it = s.chars().peekable();
+ while let Some(c) = it.next() {
+ output.push(c);
+ // check if c is not the last character, we don't append
+ // indent for last line break
+ if c == '\n' && it.peek().is_some() {
+ output.push_str(indent);
+ }
+ }
+
+ output
+ }
+
+ #[inline]
+ pub(crate) fn whitespace_matcher(c: char) -> bool {
+ c == ' ' || c == '\t'
+ }
+
+ #[inline]
+ pub(crate) fn newline_matcher(c: char) -> bool {
+ c == '\n' || c == '\r'
+ }
+
+ #[inline]
+ pub(crate) fn strip_first_newline(s: &str) -> &str {
+ if let Some(s) = s.strip_prefix("\r\n") {
+ s
+ } else if let Some(s) = s.strip_prefix('\n') {
+ s
+ } else {
+ s
+ }
+ }
+
+ pub(crate) fn find_trailing_whitespace_chars(s: &str) -> Option<&str> {
+ let trimmed = s.trim_end_matches(whitespace_matcher);
+ if trimmed.len() == s.len() {
+ None
+ } else {
+ Some(&s[trimmed.len()..])
+ }
+ }
+
+ pub(crate) fn ends_with_empty_line(text: &str) -> bool {
+ let s = text.trim_end_matches(whitespace_matcher);
+ // also matches when text is just whitespaces
+ s.ends_with(newline_matcher) || s.is_empty()
+ }
+
+ pub(crate) fn starts_with_empty_line(text: &str) -> bool {
+ text.trim_start_matches(whitespace_matcher)
+ .starts_with(newline_matcher)
+ }
+
#[cfg(test)]
mod test {
use crate::support::str::StringWriter;
diff --git a/vendor/handlebars/src/template.rs b/vendor/handlebars/src/template.rs
index 87f853799..617f47711 100644
--- a/vendor/handlebars/src/template.rs
+++ b/vendor/handlebars/src/template.rs
@@ -9,23 +9,39 @@ use pest::{Parser, Position, Span};
use serde_json::value::Value as Json;
use crate::error::{TemplateError, TemplateErrorReason};
-use crate::grammar::{self, HandlebarsParser, Rule};
+use crate::grammar::{HandlebarsParser, Rule};
use crate::json::path::{parse_json_path_from_iter, Path};
+use crate::support;
use self::TemplateElement::*;
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub struct TemplateMapping(pub usize, pub usize);
/// A handlebars template
-#[derive(PartialEq, Clone, Debug, Default)]
+#[derive(PartialEq, Eq, Clone, Debug, Default)]
pub struct Template {
pub name: Option<String>,
pub elements: Vec<TemplateElement>,
pub mapping: Vec<TemplateMapping>,
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(Default)]
+pub(crate) struct TemplateOptions {
+ pub(crate) prevent_indent: bool,
+ pub(crate) name: Option<String>,
+}
+
+impl TemplateOptions {
+ fn name(&self) -> String {
+ self.name
+ .as_ref()
+ .cloned()
+ .unwrap_or_else(|| "Unnamed".to_owned())
+ }
+}
+
+#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Subexpression {
// we use box here avoid resursive struct definition
pub element: Box<TemplateElement>,
@@ -84,13 +100,13 @@ impl Subexpression {
}
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub enum BlockParam {
Single(Parameter),
Pair((Parameter, Parameter)),
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ExpressionSpec {
pub name: Parameter,
pub params: Vec<Parameter>,
@@ -100,7 +116,7 @@ pub struct ExpressionSpec {
pub omit_pro_ws: bool,
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Parameter {
// for helper name only
Name(String),
@@ -110,7 +126,7 @@ pub enum Parameter {
Subexpression(Subexpression),
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub struct HelperTemplate {
pub name: Parameter,
pub params: Vec<Parameter>,
@@ -122,6 +138,18 @@ pub struct HelperTemplate {
}
impl HelperTemplate {
+ pub fn new(exp: ExpressionSpec, block: bool) -> HelperTemplate {
+ HelperTemplate {
+ name: exp.name,
+ params: exp.params,
+ hash: exp.hash,
+ block_param: exp.block_param,
+ block,
+ template: None,
+ inverse: None,
+ }
+ }
+
// test only
pub(crate) fn with_path(path: Path) -> HelperTemplate {
HelperTemplate {
@@ -140,12 +168,26 @@ impl HelperTemplate {
}
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub struct DecoratorTemplate {
pub name: Parameter,
pub params: Vec<Parameter>,
pub hash: HashMap<String, Parameter>,
pub template: Option<Template>,
+ // for partial indent
+ pub indent: Option<String>,
+}
+
+impl DecoratorTemplate {
+ pub fn new(exp: ExpressionSpec) -> DecoratorTemplate {
+ DecoratorTemplate {
+ name: exp.name,
+ params: exp.params,
+ hash: exp.hash,
+ template: None,
+ indent: None,
+ }
+ }
}
impl Parameter {
@@ -380,34 +422,40 @@ impl Template {
fn remove_previous_whitespace(template_stack: &mut VecDeque<Template>) {
let t = template_stack.front_mut().unwrap();
- if let Some(el) = t.elements.last_mut() {
- if let RawString(ref mut text) = el {
- *text = text.trim_end().to_owned();
- }
+ if let Some(RawString(ref mut text)) = t.elements.last_mut() {
+ *text = text.trim_end().to_owned();
}
}
+ // in handlebars, the whitespaces around statement are
+ // automatically trimed.
+ // this function checks if current span has both leading and
+ // trailing whitespaces, which we treat as a standalone statement.
+ //
+ //
fn process_standalone_statement(
template_stack: &mut VecDeque<Template>,
source: &str,
current_span: &Span<'_>,
+ prevent_indent: bool,
) -> bool {
- let with_trailing_newline = grammar::starts_with_empty_line(&source[current_span.end()..]);
+ let with_trailing_newline =
+ support::str::starts_with_empty_line(&source[current_span.end()..]);
if with_trailing_newline {
let with_leading_newline =
- grammar::ends_with_empty_line(&source[..current_span.start()]);
+ support::str::ends_with_empty_line(&source[..current_span.start()]);
- if with_leading_newline {
+ // prevent_indent: a special toggle for partial expression
+ // (>) that leading whitespaces are kept
+ if prevent_indent && with_leading_newline {
let t = template_stack.front_mut().unwrap();
// check the last element before current
- if let Some(el) = t.elements.last_mut() {
- if let RawString(ref mut text) = el {
- // trim leading space for standalone statement
- *text = text
- .trim_end_matches(grammar::whitespace_matcher)
- .to_owned();
- }
+ if let Some(RawString(ref mut text)) = t.elements.last_mut() {
+ // trim leading space for standalone statement
+ *text = text
+ .trim_end_matches(support::str::whitespace_matcher)
+ .to_owned();
}
}
@@ -453,17 +501,17 @@ impl Template {
if trim_start {
RawString(s.trim_start().to_owned())
} else if trim_start_line {
- RawString(
- s.trim_start_matches(grammar::whitespace_matcher)
- .trim_start_matches(grammar::newline_matcher)
- .to_owned(),
- )
+ let s = s.trim_start_matches(support::str::whitespace_matcher);
+ RawString(support::str::strip_first_newline(s).to_owned())
} else {
RawString(s)
}
}
- pub fn compile<'a>(source: &'a str) -> Result<Template, TemplateError> {
+ pub(crate) fn compile2<'a>(
+ source: &'a str,
+ options: TemplateOptions,
+ ) -> Result<Template, TemplateError> {
let mut helper_stack: VecDeque<HelperTemplate> = VecDeque::new();
let mut decorator_stack: VecDeque<DecoratorTemplate> = VecDeque::new();
let mut template_stack: VecDeque<Template> = VecDeque::new();
@@ -472,14 +520,16 @@ impl Template {
// flag for newline removal of standalone statements
// this option is marked as true when standalone statement is detected
// then the leading whitespaces and newline of next rawstring will be trimed
- let mut trim_line_requiered = false;
+ let mut trim_line_required = false;
let parser_queue = HandlebarsParser::parse(Rule::handlebars, source).map_err(|e| {
let (line_no, col_no) = match e.line_col {
LineColLocation::Pos(line_col) => line_col,
LineColLocation::Span(line_col, _) => line_col,
};
- TemplateError::of(TemplateErrorReason::InvalidSyntax).at(source, line_no, col_no)
+ TemplateError::of(TemplateErrorReason::InvalidSyntax)
+ .at(source, line_no, col_no)
+ .in_template(options.name())
})?;
// dbg!(parser_queue.clone().flatten());
@@ -515,7 +565,7 @@ impl Template {
&source[prev_end..span.start()],
None,
false,
- trim_line_requiered,
+ trim_line_required,
),
line_no,
col_no,
@@ -528,12 +578,15 @@ impl Template {
&source[prev_end..span.start()],
None,
false,
- trim_line_requiered,
+ trim_line_required,
),
line_no,
col_no,
);
}
+
+ // reset standalone statement marker
+ trim_line_required = false;
}
let (line_no, col_no) = span.start_pos().line_col();
@@ -555,14 +608,14 @@ impl Template {
&source[start..span.end()],
Some(pair.clone()),
omit_pro_ws,
- trim_line_requiered,
+ trim_line_required,
),
line_no,
col_no,
);
// reset standalone statement marker
- trim_line_requiered = false;
+ trim_line_required = false;
}
Rule::helper_block_start
| Rule::raw_block_start
@@ -572,24 +625,11 @@ impl Template {
match rule {
Rule::helper_block_start | Rule::raw_block_start => {
- let helper_template = HelperTemplate {
- name: exp.name,
- params: exp.params,
- hash: exp.hash,
- block_param: exp.block_param,
- block: true,
- template: None,
- inverse: None,
- };
+ let helper_template = HelperTemplate::new(exp.clone(), true);
helper_stack.push_front(helper_template);
}
Rule::decorator_block_start | Rule::partial_block_start => {
- let decorator = DecoratorTemplate {
- name: exp.name,
- params: exp.params,
- hash: exp.hash,
- template: None,
- };
+ let decorator = DecoratorTemplate::new(exp.clone());
decorator_stack.push_front(decorator);
}
_ => unreachable!(),
@@ -602,10 +642,11 @@ impl Template {
// standalone statement check, it also removes leading whitespaces of
// previous rawstring when standalone statement detected
- trim_line_requiered = Template::process_standalone_statement(
+ trim_line_required = Template::process_standalone_statement(
&mut template_stack,
source,
&span,
+ true,
);
let t = template_stack.front_mut().unwrap();
@@ -623,10 +664,11 @@ impl Template {
// standalone statement check, it also removes leading whitespaces of
// previous rawstring when standalone statement detected
- trim_line_requiered = Template::process_standalone_statement(
+ trim_line_required = Template::process_standalone_statement(
&mut template_stack,
source,
&span,
+ true,
);
let t = template_stack.pop_front().unwrap();
@@ -640,7 +682,7 @@ impl Template {
span.as_str(),
Some(pair.clone()),
omit_pro_ws,
- trim_line_requiered,
+ trim_line_required,
),
line_no,
col_no,
@@ -664,15 +706,7 @@ impl Template {
match rule {
Rule::expression | Rule::html_expression => {
- let helper_template = HelperTemplate {
- name: exp.name,
- params: exp.params,
- hash: exp.hash,
- block_param: exp.block_param,
- block: false,
- template: None,
- inverse: None,
- };
+ let helper_template = HelperTemplate::new(exp.clone(), false);
let el = if rule == Rule::expression {
Expression(Box::new(helper_template))
} else {
@@ -682,12 +716,30 @@ impl Template {
t.push_element(el, line_no, col_no);
}
Rule::decorator_expression | Rule::partial_expression => {
- let decorator = DecoratorTemplate {
- name: exp.name,
- params: exp.params,
- hash: exp.hash,
- template: None,
- };
+ // do not auto trim ident spaces for
+ // partial_expression(>)
+ let prevent_indent = rule != Rule::partial_expression;
+ trim_line_required = Template::process_standalone_statement(
+ &mut template_stack,
+ source,
+ &span,
+ prevent_indent,
+ );
+
+ // indent for partial expression >
+ let mut indent = None;
+ if rule == Rule::partial_expression
+ && !options.prevent_indent
+ && !exp.omit_pre_ws
+ {
+ indent = support::str::find_trailing_whitespace_chars(
+ &source[..span.start()],
+ );
+ }
+
+ let mut decorator = DecoratorTemplate::new(exp.clone());
+ decorator.indent = indent.map(|s| s.to_owned());
+
let el = if rule == Rule::decorator_expression {
DecoratorExpression(Box::new(decorator))
} else {
@@ -699,10 +751,11 @@ impl Template {
Rule::helper_block_end | Rule::raw_block_end => {
// standalone statement check, it also removes leading whitespaces of
// previous rawstring when standalone statement detected
- trim_line_requiered = Template::process_standalone_statement(
+ trim_line_required = Template::process_standalone_statement(
&mut template_stack,
source,
&span,
+ true,
);
let mut h = helper_stack.pop_front().unwrap();
@@ -723,16 +776,18 @@ impl Template {
exp.name.debug_name(),
),
)
- .at(source, line_no, col_no));
+ .at(source, line_no, col_no)
+ .in_template(options.name()));
}
}
Rule::decorator_block_end | Rule::partial_block_end => {
// standalone statement check, it also removes leading whitespaces of
// previous rawstring when standalone statement detected
- trim_line_requiered = Template::process_standalone_statement(
+ trim_line_required = Template::process_standalone_statement(
&mut template_stack,
source,
&span,
+ true,
);
let mut d = decorator_stack.pop_front().unwrap();
@@ -753,17 +808,19 @@ impl Template {
exp.name.debug_name(),
),
)
- .at(source, line_no, col_no));
+ .at(source, line_no, col_no)
+ .in_template(options.name()));
}
}
_ => unreachable!(),
}
}
Rule::hbs_comment_compact => {
- trim_line_requiered = Template::process_standalone_statement(
+ trim_line_required = Template::process_standalone_statement(
&mut template_stack,
source,
&span,
+ true,
);
let text = span
@@ -774,10 +831,11 @@ impl Template {
t.push_element(Comment(text.to_owned()), line_no, col_no);
}
Rule::hbs_comment => {
- trim_line_requiered = Template::process_standalone_statement(
+ trim_line_required = Template::process_standalone_statement(
&mut template_stack,
source,
&span,
+ true,
);
let text = span
@@ -802,27 +860,36 @@ impl Template {
let t = template_stack.front_mut().unwrap();
t.push_element(RawString(text.to_owned()), line_no, col_no);
}
- let root_template = template_stack.pop_front().unwrap();
+ let mut root_template = template_stack.pop_front().unwrap();
+ root_template.name = options.name;
return Ok(root_template);
}
}
}
+ // These two compile functions are kept for compatibility with 4.x
+ // Template APIs in case that some developers are using them
+ // without registry.
+
+ pub fn compile(source: &str) -> Result<Template, TemplateError> {
+ Self::compile2(source, TemplateOptions::default())
+ }
+
pub fn compile_with_name<S: AsRef<str>>(
source: S,
name: String,
) -> Result<Template, TemplateError> {
- match Template::compile(source.as_ref()) {
- Ok(mut t) => {
- t.name = Some(name);
- Ok(t)
- }
- Err(e) => Err(e.in_template(name)),
- }
+ Self::compile2(
+ source.as_ref(),
+ TemplateOptions {
+ name: Some(name),
+ ..Default::default()
+ },
+ )
}
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug)]
pub enum TemplateElement {
RawString(String),
HtmlExpression(Box<HelperTemplate>),
diff --git a/vendor/handlebars/tests/embed.rs b/vendor/handlebars/tests/embed.rs
new file mode 100644
index 000000000..019f27db9
--- /dev/null
+++ b/vendor/handlebars/tests/embed.rs
@@ -0,0 +1,29 @@
+#[macro_use]
+extern crate serde_json;
+
+use handlebars::Handlebars;
+
+#[test]
+#[cfg(feature = "rust-embed")]
+fn test_embed() {
+ use rust_embed::RustEmbed;
+
+ #[derive(RustEmbed)]
+ #[folder = "tests/templates/"]
+ #[include = "*.hbs"]
+ struct Templates;
+
+ let mut hbs = Handlebars::new();
+ hbs.register_embed_templates::<Templates>().unwrap();
+
+ assert_eq!(1, hbs.get_templates().len());
+
+ let data = json!({
+ "name": "Andy"
+ });
+
+ assert_eq!(
+ hbs.render("hello.hbs", &data).unwrap().trim(),
+ "Hello, Andy"
+ );
+}
diff --git a/vendor/handlebars/tests/escape.rs b/vendor/handlebars/tests/escape.rs
index 563ab76b9..4a737f5ce 100644
--- a/vendor/handlebars/tests/escape.rs
+++ b/vendor/handlebars/tests/escape.rs
@@ -3,7 +3,7 @@ extern crate handlebars;
#[macro_use]
extern crate serde_json;
-use handlebars::{handlebars_helper, Handlebars};
+use handlebars::{handlebars_helper, no_escape, Handlebars};
#[test]
fn test_escape_216() {
@@ -41,3 +41,43 @@ fn test_string_no_escape_422() {
.unwrap()
);
}
+
+#[test]
+fn test_string_whitespace_467() {
+ const TEMPLATE_UNQUOTED: &str = r#"{{#each synonyms}}
+ {{this.name}} => '{{this.sym}}',
+ {{/each}}
+"#;
+
+ let mut hbs = Handlebars::new();
+ hbs.register_escape_fn(no_escape);
+ hbs.register_template_string("perl", TEMPLATE_UNQUOTED)
+ .unwrap();
+
+ let r = hbs
+ .render("perl", &json!({"synonyms": [{"name": "lt", "sym": "<"}]}))
+ .unwrap();
+ assert_eq!(" lt => '<',\n", r);
+}
+
+#[test]
+fn test_triple_bracket_expression_471() {
+ let mut hbs = Handlebars::new();
+
+ handlebars_helper!(replace: |input: str| {
+ input.replace("\n", "<br/>")
+ });
+ hbs.register_helper("replace", Box::new(replace));
+
+ assert_eq!(
+ "some&lt;br/&gt;path",
+ hbs.render_template("{{replace h}}", &json!({"h": "some\npath"}))
+ .unwrap()
+ );
+
+ assert_eq!(
+ "some<br/>path",
+ hbs.render_template("{{{replace h}}}", &json!({"h": "some\npath"}))
+ .unwrap()
+ );
+}
diff --git a/vendor/handlebars/tests/helper_macro.rs b/vendor/handlebars/tests/helper_macro.rs
index 9a8d2dc07..cc5ed914b 100644
--- a/vendor/handlebars/tests/helper_macro.rs
+++ b/vendor/handlebars/tests/helper_macro.rs
@@ -4,6 +4,8 @@ extern crate handlebars;
extern crate serde_json;
use handlebars::Handlebars;
+use time::format_description::{parse, well_known::Rfc2822};
+use time::OffsetDateTime;
handlebars_helper!(lower: |s: str| s.to_lowercase());
handlebars_helper!(upper: |s: str| s.to_uppercase());
@@ -14,6 +16,7 @@ handlebars_helper!(nargs: |*args| args.len());
handlebars_helper!(has_a: |{a:i64 = 99}, **kwargs|
format!("{}, {}", a, kwargs.get("a").is_some()));
handlebars_helper!(tag: |t: str| format!("<{}>", t));
+handlebars_helper!(date: |dt: OffsetDateTime| dt.format(&parse("[year]-[month]-[day]").unwrap()).unwrap());
#[test]
fn test_macro_helper() {
@@ -26,6 +29,7 @@ fn test_macro_helper() {
hbs.register_helper("nargs", Box::new(nargs));
hbs.register_helper("has_a", Box::new(has_a));
hbs.register_helper("tag", Box::new(tag));
+ hbs.register_helper("date", Box::new(date));
let data = json!("Teixeira");
@@ -73,4 +77,13 @@ fn test_macro_helper() {
hbs.render_template("{{{tag \"html\"}}}", &()).unwrap(),
"<html>"
);
+
+ assert_eq!(
+ hbs.render_template(
+ "{{date this}}",
+ &OffsetDateTime::parse("Wed, 18 Feb 2015 23:16:09 GMT", &Rfc2822).unwrap()
+ )
+ .unwrap(),
+ "2015-02-18"
+ );
}
diff --git a/vendor/handlebars/tests/helper_with_space.rs b/vendor/handlebars/tests/helper_with_space.rs
index 5a55ab122..853d5d24a 100644
--- a/vendor/handlebars/tests/helper_with_space.rs
+++ b/vendor/handlebars/tests/helper_with_space.rs
@@ -34,3 +34,57 @@ fn test_helper_with_space_param() {
.unwrap();
assert_eq!(s, "Output: Mozilla Firefox, Google Chrome".to_owned());
}
+
+#[test]
+fn test_empty_lines_472() {
+ let mut r = Handlebars::new();
+
+ r.register_template_string(
+ "t1",
+ r#"{{#each routes}}
+import { default as {{this.handler}} } from '{{this.file_path}}'
+{{/each}}
+
+addEventListener('fetch', (event) => {
+ event.respondWith(handleEvent(event))
+})"#,
+ )
+ .unwrap();
+
+ r.register_template_string(
+ "t2",
+ r#"addEventListener('fetch', (event) => {
+ event.respondWith(handleEvent(event))
+})
+
+{{#each routes}}
+import { default as {{this.handler}} } from '{{this.file_path}}'
+{{/each}}
+"#,
+ )
+ .unwrap();
+
+ let data = json!({"routes": [{"handler": "__hello_handler", "file_path": "./hello.js"},
+ {"handler": "__world_index_handler", "file_path": "./world/index.js"},
+ {"handler": "__index_handler", "file_path": "./index.js"}]});
+
+ let exp1 = r#"import { default as __hello_handler } from './hello.js'
+import { default as __world_index_handler } from './world/index.js'
+import { default as __index_handler } from './index.js'
+
+addEventListener('fetch', (event) => {
+ event.respondWith(handleEvent(event))
+})"#;
+
+ let exp2 = r#"addEventListener('fetch', (event) => {
+ event.respondWith(handleEvent(event))
+})
+
+import { default as __hello_handler } from './hello.js'
+import { default as __world_index_handler } from './world/index.js'
+import { default as __index_handler } from './index.js'
+"#;
+
+ assert_eq!(r.render("t1", &data).unwrap(), exp1);
+ assert_eq!(r.render("t2", &data).unwrap(), exp2);
+}
diff --git a/vendor/handlebars/tests/templates/hello.hbs b/vendor/handlebars/tests/templates/hello.hbs
new file mode 100644
index 000000000..a2344af53
--- /dev/null
+++ b/vendor/handlebars/tests/templates/hello.hbs
@@ -0,0 +1 @@
+Hello, {{name}}
diff --git a/vendor/handlebars/tests/whitespace.rs b/vendor/handlebars/tests/whitespace.rs
new file mode 100644
index 000000000..1c740556f
--- /dev/null
+++ b/vendor/handlebars/tests/whitespace.rs
@@ -0,0 +1,24 @@
+use handlebars::Handlebars;
+use serde_json::json;
+
+#[test]
+fn test_whitespaces_elision() {
+ let hbs = Handlebars::new();
+ assert_eq!(
+ "bar",
+ hbs.render_template(" {{~ foo ~}} ", &json!({"foo": "bar"}))
+ .unwrap()
+ );
+
+ assert_eq!(
+ "<bar/>",
+ hbs.render_template(" {{{~ foo ~}}} ", &json!({"foo": "<bar/>"}))
+ .unwrap()
+ );
+
+ assert_eq!(
+ "<bar/>",
+ hbs.render_template(" {{~ {foo} ~}} ", &json!({"foo": "<bar/>"}))
+ .unwrap()
+ );
+}
diff --git a/vendor/hermit-abi/.cargo-checksum.json b/vendor/hermit-abi/.cargo-checksum.json
index 5b4a93900..53188c450 100644
--- a/vendor/hermit-abi/.cargo-checksum.json
+++ b/vendor/hermit-abi/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"9bd554080e32ce81c4741c85e81e70c4009ce5adbf5e8ffe9bda02b964b3208b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"322fadd63e558e5a10caf980cbedf83ac1546ba40fd992f54492e21ce54205af","src/lib.rs":"31fa39172e2e5310a2b2179456cfe3cadcd45443852a01b4a73a601a60bcf211","src/tcplistener.rs":"c6e2db06d4265fa0956851e1c965336d60c53ab21573729aae76ecfe0ccc84c3","src/tcpstream.rs":"38a17de54213faf9de217f6146ff86ee75b67d4404a532b1419903269200936b"},"package":"1ab7905ea95c6d9af62940f9d7dd9596d54c334ae2c15300c482051292d5637f"} \ No newline at end of file
+{"files":{"Cargo.toml":"1b4c80e131e223ca0213e4efe1eda533cd665213aa94ec8920e9b65139cd2122","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"322fadd63e558e5a10caf980cbedf83ac1546ba40fd992f54492e21ce54205af","src/errno.rs":"1c0680ead2ddf26b12d34bd7fa3e1dab386df761d6ac1901889ece26682dc465","src/lib.rs":"f444c2cf2b93506719841cc46605dcded34d0a4b50ff7d5da8d56044610ca463","src/tcplistener.rs":"c6e2db06d4265fa0956851e1c965336d60c53ab21573729aae76ecfe0ccc84c3","src/tcpstream.rs":"38a17de54213faf9de217f6146ff86ee75b67d4404a532b1419903269200936b"},"package":"ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"} \ No newline at end of file
diff --git a/vendor/hermit-abi/Cargo.toml b/vendor/hermit-abi/Cargo.toml
index 81b32c9bf..314aa6ad4 100644
--- a/vendor/hermit-abi/Cargo.toml
+++ b/vendor/hermit-abi/Cargo.toml
@@ -12,18 +12,32 @@
[package]
edition = "2021"
name = "hermit-abi"
-version = "0.2.0"
+version = "0.2.6"
authors = ["Stefan Lankes"]
-description = "hermit-abi is small interface to call functions from the unikernel RustyHermit.\nIt is used to build the target `x86_64-unknown-hermit`.\n"
+description = """
+hermit-abi is small interface to call functions from the unikernel RustyHermit.
+It is used to build the target `x86_64-unknown-hermit`.
+"""
documentation = "https://hermitcore.github.io/rusty-hermit/hermit_abi"
readme = "README.md"
-keywords = ["unikernel", "libos"]
+keywords = [
+ "unikernel",
+ "libos",
+]
categories = ["os"]
license = "MIT/Apache-2.0"
repository = "https://github.com/hermitcore/rusty-hermit"
+resolver = "1"
+
[package.metadata.docs.rs]
-default-target = "x86_64-unknown-hermit"
features = ["docs"]
+default-target = "x86_64-unknown-hermit"
+
+[dependencies.alloc]
+version = "1.0.0"
+optional = true
+package = "rustc-std-workspace-alloc"
+
[dependencies.compiler_builtins]
version = "0.1"
optional = true
@@ -34,10 +48,15 @@ optional = true
package = "rustc-std-workspace-core"
[dependencies.libc]
-version = "0.2.51"
+version = "0.2"
default-features = false
[features]
default = []
docs = []
-rustc-dep-of-std = ["core", "compiler_builtins/rustc-dep-of-std", "libc/rustc-dep-of-std"]
+rustc-dep-of-std = [
+ "core",
+ "alloc",
+ "compiler_builtins/rustc-dep-of-std",
+ "libc/rustc-dep-of-std",
+]
diff --git a/vendor/hermit-abi/src/errno.rs b/vendor/hermit-abi/src/errno.rs
new file mode 100644
index 000000000..dc22dc8ce
--- /dev/null
+++ b/vendor/hermit-abi/src/errno.rs
@@ -0,0 +1,397 @@
+/// Operation not permitted
+pub const EPERM: i32 = 1;
+
+/// No such file or directory
+pub const ENOENT: i32 = 2;
+
+/// No such process
+pub const ESRCH: i32 = 3;
+
+/// Interrupted system call
+pub const EINTR: i32 = 4;
+
+/// I/O error
+pub const EIO: i32 = 5;
+
+/// No such device or address
+pub const ENXIO: i32 = 6;
+
+/// Argument list too long
+pub const E2BIG: i32 = 7;
+
+/// Exec format error
+pub const ENOEXEC: i32 = 8;
+
+/// Bad file number
+pub const EBADF: i32 = 9;
+
+/// No child processes
+pub const ECHILD: i32 = 10;
+
+/// Try again
+pub const EAGAIN: i32 = 11;
+
+/// Out of memory
+pub const ENOMEM: i32 = 12;
+
+/// Permission denied
+pub const EACCES: i32 = 13;
+
+/// Bad address
+pub const EFAULT: i32 = 14;
+
+/// Block device required
+pub const ENOTBLK: i32 = 15;
+
+/// Device or resource busy
+pub const EBUSY: i32 = 16;
+
+/// File exists
+pub const EEXIST: i32 = 17;
+
+/// Cross-device link
+pub const EXDEV: i32 = 18;
+
+/// No such device
+pub const ENODEV: i32 = 19;
+
+/// Not a directory
+pub const ENOTDIR: i32 = 20;
+
+/// Is a directory
+pub const EISDIR: i32 = 21;
+
+/// Invalid argument
+pub const EINVAL: i32 = 22;
+
+/// File table overflow
+pub const ENFILE: i32 = 23;
+
+/// Too many open files
+pub const EMFILE: i32 = 24;
+
+/// Not a typewriter
+pub const ENOTTY: i32 = 25;
+
+/// Text file busy
+pub const ETXTBSY: i32 = 26;
+
+/// File too large
+pub const EFBIG: i32 = 27;
+
+/// No space left on device
+pub const ENOSPC: i32 = 28;
+
+/// Illegal seek
+pub const ESPIPE: i32 = 29;
+
+/// Read-only file system
+pub const EROFS: i32 = 30;
+
+/// Too many links
+pub const EMLINK: i32 = 31;
+
+/// Broken pipe
+pub const EPIPE: i32 = 32;
+
+/// Math argument out of domain of func
+pub const EDOM: i32 = 33;
+
+/// Math result not representable
+pub const ERANGE: i32 = 34;
+
+/// Resource deadlock would occur
+pub const EDEADLK: i32 = 35;
+
+/// File name too long
+pub const ENAMETOOLONG: i32 = 36;
+
+/// No record locks available
+pub const ENOLCK: i32 = 37;
+
+/// Function not implemented
+pub const ENOSYS: i32 = 38;
+
+/// Directory not empty
+pub const ENOTEMPTY: i32 = 39;
+
+/// Too many symbolic links encountered
+pub const ELOOP: i32 = 40;
+
+/// Operation would block
+pub const EWOULDBLOCK: i32 = EAGAIN;
+
+/// No message of desired type
+pub const ENOMSG: i32 = 42;
+
+/// Identifier removed
+pub const EIDRM: i32 = 43;
+
+/// Channel number out of range
+pub const ECHRNG: i32 = 44;
+
+/// Level 2 not synchronized
+pub const EL2NSYNC: i32 = 45;
+
+/// Level 3 halted
+pub const EL3HLT: i32 = 46;
+
+/// Level 3 reset
+pub const EL3RST: i32 = 47;
+
+/// Link number out of range
+pub const ELNRNG: i32 = 48;
+
+/// Protocol driver not attached
+pub const EUNATCH: i32 = 49;
+
+/// No CSI structure available
+pub const ENOCSI: i32 = 50;
+
+/// Level 2 halted
+pub const EL2HLT: i32 = 51;
+
+/// Invalid exchange
+pub const EBADE: i32 = 52;
+
+/// Invalid request descriptor
+pub const EBADR: i32 = 53;
+
+/// Exchange full
+pub const EXFULL: i32 = 54;
+
+/// No anode
+pub const ENOANO: i32 = 55;
+
+/// Invalid request code
+pub const EBADRQC: i32 = 56;
+
+/// Invalid slot
+pub const EBADSLT: i32 = 57;
+
+pub const EDEADLOCK: i32 = EDEADLK;
+
+/// Bad font file format
+pub const EBFONT: i32 = 59;
+
+/// Device not a stream
+pub const ENOSTR: i32 = 60;
+
+/// No data available
+pub const ENODATA: i32 = 61;
+
+/// Timer expired
+pub const ETIME: i32 = 62;
+
+/// Out of streams resources
+pub const ENOSR: i32 = 63;
+
+/// Machine is not on the network
+pub const ENONET: i32 = 64;
+
+/// Package not installed
+pub const ENOPKG: i32 = 65;
+
+/// Object is remote
+pub const EREMOTE: i32 = 66;
+
+/// Link has been severed
+pub const ENOLINK: i32 = 67;
+
+/// Advertise error
+pub const EADV: i32 = 68;
+
+/// Srmount error
+pub const ESRMNT: i32 = 69;
+
+/// Communication error on send
+pub const ECOMM: i32 = 70;
+
+/// Protocol error
+pub const EPROTO: i32 = 71;
+
+/// Multihop attempted
+pub const EMULTIHOP: i32 = 72;
+
+/// RFS specific error
+pub const EDOTDOT: i32 = 73;
+
+/// Not a data message
+pub const EBADMSG: i32 = 74;
+
+/// Value too large for defined data type
+pub const EOVERFLOW: i32 = 75;
+
+/// Name not unique on network
+pub const ENOTUNIQ: i32 = 76;
+
+/// File descriptor in bad state
+pub const EBADFD: i32 = 77;
+
+/// Remote address changed
+pub const EREMCHG: i32 = 78;
+
+/// Can not access a needed shared library
+pub const ELIBACC: i32 = 79;
+
+/// Accessing a corrupted shared library
+pub const ELIBBAD: i32 = 80;
+
+/// .lib section in a.out corrupted
+pub const ELIBSCN: i32 = 81;
+
+/// Attempting to link in too many shared libraries
+pub const ELIBMAX: i32 = 82;
+
+/// Cannot exec a shared library directly
+pub const ELIBEXEC: i32 = 83;
+
+/// Illegal byte sequence
+pub const EILSEQ: i32 = 84;
+
+/// Interrupted system call should be restarted
+pub const ERESTART: i32 = 85;
+
+/// Streams pipe error
+pub const ESTRPIPE: i32 = 86;
+
+/// Too many users
+pub const EUSERS: i32 = 87;
+
+/// Socket operation on non-socket
+pub const ENOTSOCK: i32 = 88;
+
+/// Destination address required
+pub const EDESTADDRREQ: i32 = 89;
+
+/// Message too long
+pub const EMSGSIZE: i32 = 90;
+
+/// Protocol wrong type for socket
+pub const EPROTOTYPE: i32 = 91;
+
+/// Protocol not available
+pub const ENOPROTOOPT: i32 = 92;
+
+/// Protocol not supported
+pub const EPROTONOSUPPORT: i32 = 93;
+
+/// Socket type not supported
+pub const ESOCKTNOSUPPORT: i32 = 94;
+
+/// Operation not supported on transport endpoint
+pub const EOPNOTSUPP: i32 = 95;
+
+/// Protocol family not supported
+pub const EPFNOSUPPORT: i32 = 96;
+
+/// Address family not supported by protocol
+pub const EAFNOSUPPORT: i32 = 97;
+
+/// Address already in use
+pub const EADDRINUSE: i32 = 98;
+
+/// Cannot assign requested address
+pub const EADDRNOTAVAIL: i32 = 99;
+
+/// Network is down
+pub const ENETDOWN: i32 = 100;
+
+/// Network is unreachable
+pub const ENETUNREACH: i32 = 101;
+
+/// Network dropped connection because of reset
+pub const ENETRESET: i32 = 102;
+
+/// Software caused connection abort
+pub const ECONNABORTED: i32 = 103;
+
+/// Connection reset by peer
+pub const ECONNRESET: i32 = 104;
+
+/// No buffer space available
+pub const ENOBUFS: i32 = 105;
+
+/// Transport endpoint is already connected
+pub const EISCONN: i32 = 106;
+
+/// Transport endpoint is not connected
+pub const ENOTCONN: i32 = 107;
+
+/// Cannot send after transport endpoint shutdown
+pub const ESHUTDOWN: i32 = 108;
+
+/// Too many references: cannot splice
+pub const ETOOMANYREFS: i32 = 109;
+
+/// Connection timed out
+pub const ETIMEDOUT: i32 = 110;
+
+/// Connection refused
+pub const ECONNREFUSED: i32 = 111;
+
+/// Host is down
+pub const EHOSTDOWN: i32 = 112;
+
+/// No route to host
+pub const EHOSTUNREACH: i32 = 113;
+
+/// Operation already in progress
+pub const EALREADY: i32 = 114;
+
+/// Operation now in progress
+pub const EINPROGRESS: i32 = 115;
+
+/// Stale file handle
+pub const ESTALE: i32 = 116;
+
+/// Structure needs cleaning
+pub const EUCLEAN: i32 = 117;
+
+/// Not a XENIX named type file
+pub const ENOTNAM: i32 = 118;
+
+/// No XENIX semaphores available
+pub const ENAVAIL: i32 = 119;
+
+/// Is a named type file
+pub const EISNAM: i32 = 120;
+
+/// Remote I/O error
+pub const EREMOTEIO: i32 = 121;
+
+/// Quota exceeded
+pub const EDQUOT: i32 = 122;
+
+/// No medium found
+pub const ENOMEDIUM: i32 = 123;
+
+/// Wrong medium type
+pub const EMEDIUMTYPE: i32 = 124;
+
+/// Operation Canceled
+pub const ECANCELED: i32 = 125;
+
+/// Required key not available
+pub const ENOKEY: i32 = 126;
+
+/// Key has expired
+pub const EKEYEXPIRED: i32 = 127;
+
+/// Key has been revoked
+pub const EKEYREVOKED: i32 = 128;
+
+/// Key was rejected by service
+pub const EKEYREJECTED: i32 = 129;
+
+/// Robust mutexes: Owner died
+pub const EOWNERDEAD: i32 = 130;
+
+/// Robust mutexes: State not recoverable
+pub const ENOTRECOVERABLE: i32 = 131;
+
+/// Robust mutexes: Operation not possible due to RF-kill
+pub const ERFKILL: i32 = 132;
+
+/// Robust mutexes: Memory page has hardware error
+pub const EHWPOISON: i32 = 133;
diff --git a/vendor/hermit-abi/src/lib.rs b/vendor/hermit-abi/src/lib.rs
index 7bb4a4cb0..2a8a2e2dc 100644
--- a/vendor/hermit-abi/src/lib.rs
+++ b/vendor/hermit-abi/src/lib.rs
@@ -5,23 +5,21 @@
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::result_unit_err)]
-extern crate libc;
-
+pub mod errno;
pub mod tcplistener;
pub mod tcpstream;
+use core::mem::MaybeUninit;
+
use libc::c_void;
// sysmbols, which are part of the library operating system
-extern "Rust" {
- fn sys_secure_rand64() -> Option<u64>;
- fn sys_secure_rand32() -> Option<u32>;
-}
-
extern "C" {
fn sys_rand() -> u32;
fn sys_srand(seed: u32);
+ fn sys_secure_rand32(value: *mut u32) -> i32;
+ fn sys_secure_rand64(value: *mut u64) -> i32;
fn sys_get_processor_count() -> usize;
fn sys_malloc(size: usize, align: usize) -> *mut u8;
fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8;
@@ -34,6 +32,13 @@ extern "C" {
fn sys_read(fd: i32, buf: *mut u8, len: usize) -> isize;
fn sys_write(fd: i32, buf: *const u8, len: usize) -> isize;
fn sys_close(fd: i32) -> i32;
+ fn sys_futex_wait(
+ address: *mut u32,
+ expected: u32,
+ timeout: *const timespec,
+ flags: u32,
+ ) -> i32;
+ fn sys_futex_wake(address: *mut u32, count: i32) -> i32;
fn sys_sem_init(sem: *mut *const c_void, value: u32) -> i32;
fn sys_sem_destroy(sem: *const c_void) -> i32;
fn sys_sem_post(sem: *const c_void) -> i32;
@@ -68,8 +73,10 @@ extern "C" {
fn sys_unlink(name: *const i8) -> i32;
fn sys_network_init() -> i32;
fn sys_block_current_task();
+ fn sys_block_current_task_with_timeout(timeout: u64);
fn sys_wakeup_task(tid: Tid);
fn sys_get_priority() -> u8;
+ fn sys_set_priority(tid: Tid, prio: u8);
}
/// A thread handle type
@@ -101,6 +108,7 @@ pub const LOW_PRIO: Priority = Priority::from(1);
pub struct Handle(usize);
pub const NSEC_PER_SEC: u64 = 1_000_000_000;
+pub const FUTEX_RELATIVE_TIMEOUT: u32 = 1;
pub const CLOCK_REALTIME: u64 = 1;
pub const CLOCK_MONOTONIC: u64 = 4;
pub const STDIN_FILENO: libc::c_int = 0;
@@ -245,6 +253,33 @@ pub unsafe fn close(fd: i32) -> i32 {
sys_close(fd)
}
+/// If the value at address matches the expected value, park the current thread until it is either
+/// woken up with [`futex_wake`] (returns 0) or an optional timeout elapses (returns -ETIMEDOUT).
+///
+/// Setting `timeout` to null means the function will only return if [`futex_wake`] is called.
+/// Otherwise, `timeout` is interpreted as an absolute time measured with [`CLOCK_MONOTONIC`].
+/// If [`FUTEX_RELATIVE_TIMEOUT`] is set in `flags` the timeout is understood to be relative
+/// to the current time.
+///
+/// Returns -EINVAL if `address` is null, the timeout is negative or `flags` contains unknown values.
+#[inline(always)]
+pub unsafe fn futex_wait(
+ address: *mut u32,
+ expected: u32,
+ timeout: *const timespec,
+ flags: u32,
+) -> i32 {
+ sys_futex_wait(address, expected, timeout, flags)
+}
+
+/// Wake `count` threads waiting on the futex at `address`. Returns the number of threads
+/// woken up (saturates to `i32::MAX`). If `count` is `i32::MAX`, wake up all matching
+/// waiting threads. If `count` is negative or `address` is null, returns -EINVAL.
+#[inline(always)]
+pub unsafe fn futex_wake(address: *mut u32, count: i32) -> i32 {
+ sys_futex_wake(address, count)
+}
+
/// sem_init() initializes the unnamed semaphore at the address
/// pointed to by `sem`. The `value` argument specifies the
/// initial value for the semaphore.
@@ -459,7 +494,9 @@ pub unsafe fn srand(seed: u32) {
/// the function returns `None`.
#[inline(always)]
pub unsafe fn secure_rand32() -> Option<u32> {
- sys_secure_rand32()
+ let mut rand = MaybeUninit::uninit();
+ let res = sys_secure_rand32(rand.as_mut_ptr());
+ (res == 0).then(|| rand.assume_init())
}
/// Create a cryptographicly secure 64bit random number with the support of
@@ -467,16 +504,27 @@ pub unsafe fn secure_rand32() -> Option<u32> {
/// the function returns `None`.
#[inline(always)]
pub unsafe fn secure_rand64() -> Option<u64> {
- sys_secure_rand64()
+ let mut rand = MaybeUninit::uninit();
+ let res = sys_secure_rand64(rand.as_mut_ptr());
+ (res == 0).then(|| rand.assume_init())
}
-/// Add current task to the queue of blocked tasl. After calling `block_current_task`,
+/// Add current task to the queue of blocked tasks. After calling `block_current_task`,
/// call `yield_now` to switch to another task.
#[inline(always)]
pub unsafe fn block_current_task() {
sys_block_current_task();
}
+/// Add current task to the queue of blocked tasks, but wake it when `timeout` milliseconds
+/// have elapsed.
+///
+/// After calling `block_current_task`, call `yield_now` to switch to another task.
+#[inline(always)]
+pub unsafe fn block_current_task_with_timeout(timeout: u64) {
+ sys_block_current_task_with_timeout(timeout);
+}
+
/// Wakeup task with the thread id `tid`
#[inline(always)]
pub unsafe fn wakeup_task(tid: Tid) {
@@ -488,3 +536,9 @@ pub unsafe fn wakeup_task(tid: Tid) {
pub unsafe fn get_priority() -> Priority {
Priority::from(sys_get_priority())
}
+
+/// Determine the priority of the current thread
+#[inline(always)]
+pub unsafe fn set_priority(tid: Tid, prio: Priority) {
+ sys_set_priority(tid, prio.into());
+}
diff --git a/vendor/itoa/.cargo-checksum.json b/vendor/itoa/.cargo-checksum.json
index 3422ca4a1..4af98bbb4 100644
--- a/vendor/itoa/.cargo-checksum.json
+++ b/vendor/itoa/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"3c81fd59c059ee454f7812e8a9e90078880a4c101964ac4ce63537cec7d36c1e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"8e9d4e6ac0c740793958bf57c3dbd62827340cf77a282633c388aff70a7c1a22","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"f3b4bd0934f41b8f8a8828a22a9f5ad2af1ac1e7b632743ec2de46fbb4cb0b59","src/udiv128.rs":"16394f767854452756372d74f8025f7329fd8b61a676d81edf489681a6332ee9","tests/test.rs":"f7404fc5f7cd1bdaf74a3b64a70d5b30586241ddc1ce2c82bd1b564999fcce0e"},"package":"112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"} \ No newline at end of file
+{"files":{"Cargo.toml":"2e653183f335114876acd61d9e4eeb893b202e6842d4f128bbae40c121439432","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4bc11375d5c1c2c7cf4988b94d44c0f1fe8cdf2d68755fef127cd5ba0d70b939","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"55c938bd2421bf2adc505504ecfe44dd8f537f234b3f3555bbaf6df87d35b54b","src/udiv128.rs":"16394f767854452756372d74f8025f7329fd8b61a676d81edf489681a6332ee9","tests/test.rs":"f7404fc5f7cd1bdaf74a3b64a70d5b30586241ddc1ce2c82bd1b564999fcce0e"},"package":"6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"} \ No newline at end of file
diff --git a/vendor/itoa/Cargo.toml b/vendor/itoa/Cargo.toml
index 51506e7a1..c3a1bd601 100644
--- a/vendor/itoa/Cargo.toml
+++ b/vendor/itoa/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "itoa"
-version = "1.0.2"
+version = "1.0.3"
authors = ["David Tolnay <dtolnay@gmail.com>"]
exclude = [
"performance.png",
@@ -22,7 +22,11 @@ exclude = [
description = "Fast integer primitive to string conversion"
documentation = "https://docs.rs/itoa"
readme = "README.md"
-categories = ["value-formatting"]
+keywords = ["integer"]
+categories = [
+ "value-formatting",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/itoa"
diff --git a/vendor/itoa/README.md b/vendor/itoa/README.md
index 6e241e1c3..914d1ff30 100644
--- a/vendor/itoa/README.md
+++ b/vendor/itoa/README.md
@@ -3,7 +3,7 @@ itoa
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/itoa-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/itoa)
[<img alt="crates.io" src="https://img.shields.io/crates/v/itoa.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/itoa)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/itoa)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/itoa)
[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/itoa/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster)
This crate provides a fast conversion of integer primitives to decimal strings.
diff --git a/vendor/itoa/src/lib.rs b/vendor/itoa/src/lib.rs
index 86604aa2a..002156cb8 100644
--- a/vendor/itoa/src/lib.rs
+++ b/vendor/itoa/src/lib.rs
@@ -2,7 +2,7 @@
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
@@ -30,7 +30,7 @@
//!
//! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png)
-#![doc(html_root_url = "https://docs.rs/itoa/1.0.2")]
+#![doc(html_root_url = "https://docs.rs/itoa/1.0.3")]
#![no_std]
#![allow(
clippy::cast_lossless,
diff --git a/vendor/lazycell/.cargo-checksum.json b/vendor/lazycell/.cargo-checksum.json
new file mode 100644
index 000000000..a5316aaaf
--- /dev/null
+++ b/vendor/lazycell/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"54036052985525a153f9e6c9dda6a143b7494a477908fb28f5705f92dd387059","Cargo.toml":"79f5da117603f75361b9a7309f102a9ab70b66d5c1c269a30f66fdea58ccc657","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"03f6ccb4e6040abccf12b31551bbbd1800a5069a17950bbd6db850d85744800f","README.md":"26e4440387d4fc898f377eb5394f3432f8625ed8aa46e02ffb61aac8b2032967","src/lib.rs":"3fcef569bd4feb760925e34aef0e66739a0827cbc1b26ae033f57e322c3a2515","src/serde_impl.rs":"4903fb722748e91bdc4b481c7f3309e79e962f75c9717e7e13edcccd0242a52d"},"package":"830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"} \ No newline at end of file
diff --git a/vendor/lazycell/CHANGELOG.md b/vendor/lazycell/CHANGELOG.md
new file mode 100644
index 000000000..1ac4a6e82
--- /dev/null
+++ b/vendor/lazycell/CHANGELOG.md
@@ -0,0 +1,197 @@
+<a name="v1.3.0"></a>
+## v1.3.0 (2020-08-12)
+
+
+#### Bug Fixes
+
+* Add custom `impl Default` to support non-Default-able `<T>` types ([b49f4eab](https://github.com/indiv0/lazycell/commit/b49f4eabec49c0a5146ef01017c2506a3c357180))
+* **lazycell:** Fix unsound aliasing in `LazyCell::fill` ([e789ac1a](https://github.com/indiv0/lazycell/commit/e789ac1a99010ad79c2d09c761fec6d67053647d), closes [#98](https://github.com/indiv0/lazycell/issues/98))
+
+#### Features
+
+* Implement serde support ([e728a0b6](https://github.com/indiv0/lazycell/commit/e728a0b680e607b793a81b5af7bf7f1d2c0eb5e5))
+
+#### Documentation
+
+* fix typo ([5f5ba9d5](https://github.com/indiv0/lazycell/commit/5f5ba9d5ac3364f8376c0c872c2e5094974385ba))
+
+
+
+<a name="v1.2.1"></a>
+## v1.2.1 (2018-12-03)
+
+
+#### Features
+
+* Implement Clone for LazyCell and AtomicLazyCell ([30fe4a8f](https://github.com/indiv0/lazycell/commit/30fe4a8f568059b3c78ed149a810962a676cb2b2))
+
+
+
+<a name="v1.2.0"></a>
+## v1.2.0 (2018-09-19)
+
+
+#### Features
+
+* add `LazyCell::replace` for infallible access ([a63ffb90](https://github.com/indiv0/lazycell/commit/a63ffb9040a5e0683a9bbf9d3d5ef589f2ca8b7c))
+
+
+
+<a name="v1.1.0"></a>
+## v1.1.0 (2018-09-10)
+
+
+#### Documentation
+
+* add note regarding LazyCell::borrow_mut ([9d634d1f](https://github.com/indiv0/lazycell/commit/9d634d1fd9a21b7aa075d407bedf9fe77ba8b79f))
+* describe mutability more consistently ([b8078029](https://github.com/indiv0/lazycell/commit/b80780294611e92efddcdd33a701b3049ab5c5eb), closes [#78](https://github.com/indiv0/lazycell/issues/78))
+
+#### Improvements
+
+* add NONE constant for an empty AtomicLazyCell ([31aff0da](https://github.com/indiv0/lazycell/commit/31aff0dacf824841c5f38ef4acf0aa71ec4c36eb), closes [#87](https://github.com/indiv0/lazycell/issues/87))
+* add `LazyCell::borrow_mut_with` and `LazyCell::try_borrow_mut_with` ([fdc6d268](https://github.com/indiv0/lazycell/commit/fdc6d268f0e9a6668768302f45fe2bb4aa9a7c34), closes [#79](https://github.com/indiv0/lazycell/issues/79), [#80](https://github.com/indiv0/lazycell/issues/80))
+
+
+
+<a name="v1.0.0"></a>
+## v1.0.0 (2018-06-06)
+
+
+#### Features
+
+* Add #![no_std] ([e59f6b55](https://github.com/indiv0/lazycell/commit/e59f6b5531e310d3df26b0eb40b1431937f38096))
+
+
+
+<a name="0.6.0"></a>
+## 0.6.0 (2017-11-25)
+
+
+#### Bug Fixes
+
+* fix soundness hole in borrow_with ([d1f46bef](https://github.com/indiv0/lazycell/commit/d1f46bef9d1397570aa9c3e87e18e0d16e6d1585))
+
+#### Features
+
+* add Default derives ([71bc5088](https://github.com/indiv0/lazycell/commit/71bc50880cd8e20002038197c9b890f5b76ad096))
+* add LazyCell::try_borrow_with ([bffa4028](https://github.com/indiv0/lazycell/commit/bffa402896670b5c78a9ec050d82a58ee98de6fb))
+* add LazyCell::borrow_mut method ([fd419dea](https://github.com/indiv0/lazycell/commit/fd419dea965ff1ad3853f26f37e8d107c6ca096c))
+
+#### Breaking Changes
+
+* add `T: Send` for `AtomicLazyCell` `Sync` impl ([668bb2fa](https://github.com/indiv0/lazycell/commit/668bb2fa974fd6707c4c7edad292c76a9017d74d), closes [#67](https://github.com/indiv0/lazycell/issues/67))
+
+#### Improvements
+
+* add `T: Send` for `AtomicLazyCell` `Sync` impl ([668bb2fa](https://github.com/indiv0/lazycell/commit/668bb2fa974fd6707c4c7edad292c76a9017d74d), closes [#67](https://github.com/indiv0/lazycell/issues/67))
+
+
+
+<a name="v0.5.1"></a>
+## v0.5.1 (2017-03-24)
+
+
+#### Documentation
+
+* fix missing backticks ([44bafaaf](https://github.com/indiv0/lazycell/commit/44bafaaf93a91641261f58ee38adadcd4af6458e))
+
+#### Improvements
+
+* derive `Debug` impls ([9da0a5a2](https://github.com/indiv0/lazycell/commit/9da0a5a2ffac1fef03ef02851c2c89d26d67d225))
+
+#### Features
+
+* Add get method for Copy types ([dc8f8209](https://github.com/indiv0/lazycell/commit/dc8f8209888b6eba6d18717eba6a22614629b997))
+
+
+
+<a name="v0.5.0"></a>
+## v0.5.0 (2016-12-08)
+
+
+#### Features
+
+* add borrow_with to LazyCell ([a15efa35](https://github.com/indiv0/lazycell/commit/a15efa359ea5a31a66ba57fc5b25f90c87b4b0dd))
+
+
+
+<a name="v0.4.0"></a>
+## (2016-08-17)
+
+
+#### Breaking Changes
+
+* **LazyCell:** return Err(value) on full cell ([68f3415d](https://github.com/indiv0/lazycell/commit/68f3415dd5d6a66ba047a133b7028ebe4f1c5070), breaks [#](https://github.com/indiv0/lazycell/issues/))
+
+#### Improvements
+
+* **LazyCell:** return Err(value) on full cell ([68f3415d](https://github.com/indiv0/lazycell/commit/68f3415dd5d6a66ba047a133b7028ebe4f1c5070), breaks [#](https://github.com/indiv0/lazycell/issues/))
+
+
+
+<a name="v0.3.0"></a>
+## (2016-08-16)
+
+
+#### Features
+
+* add AtomicLazyCell which is thread-safe ([85afbd36](https://github.com/indiv0/lazycell/commit/85afbd36d8a148e14cc53654b39ddb523980124d))
+
+#### Improvements
+
+* Use UnsafeCell instead of RefCell ([3347a8e9](https://github.com/indiv0/lazycell/commit/3347a8e97d2215a47e25c1e2fc953e8052ad8eb6))
+
+
+
+<a name="v0.2.1"></a>
+## (2016-04-18)
+
+
+#### Documentation
+
+* put types in between backticks ([607cf939](https://github.com/indiv0/lazycell/commit/607cf939b05e35001ba3070ec7a0b17b064e7be1))
+
+
+
+<a name="v0.2.0"></a>
+## v0.2.0 (2016-03-28)
+
+
+#### Features
+
+* **lazycell:**
+ * add tests for `LazyCell` struct ([38f1313d](https://github.com/indiv0/lazycell/commit/38f1313d98542ca8c98b424edfa9ba9c3975f99e), closes [#30](https://github.com/indiv0/lazycell/issues/30))
+ * remove unnecessary `Default` impl ([68c16d2d](https://github.com/indiv0/lazycell/commit/68c16d2df4e9d13d5298162c06edf918246fd758))
+
+#### Documentation
+
+* **CHANGELOG:** removed unnecessary sections ([1cc0555d](https://github.com/indiv0/lazycell/commit/1cc0555d875898a01b0832ff967aed6b40e720eb))
+* **README:** add link to documentation ([c8dc33f0](https://github.com/indiv0/lazycell/commit/c8dc33f01f2c0dc187f59ee53a2b73081053012b), closes [#13](https://github.com/indiv0/lazycell/issues/13))
+
+
+
+<a name="v0.1.0"></a>
+## v0.1.0 (2016-03-16)
+
+
+#### Features
+
+* **lib.rs:** implement Default trait for LazyCell ([150a6304](https://github.com/indiv0/LazyCell/commit/150a6304a230ee1de8424e49c447ec1b2d6578ce))
+
+
+
+<a name="v0.0.1"></a>
+## v0.0.1 (2016-03-16)
+
+
+#### Bug Fixes
+
+* **Cargo.toml:** loosen restrictions on Clippy version ([84dd8f96](https://github.com/indiv0/LazyCell/commit/84dd8f960000294f9dad47d776a41b98ed812981))
+
+#### Features
+
+* add initial implementation ([4b39764a](https://github.com/indiv0/LazyCell/commit/4b39764a575bcb701dbd8047b966f72720fd18a4))
+* add initial commit ([a80407a9](https://github.com/indiv0/LazyCell/commit/a80407a907ef7c9401f120104663172f6965521a))
+
+
+
diff --git a/vendor/lazycell/Cargo.toml b/vendor/lazycell/Cargo.toml
new file mode 100644
index 000000000..fce4dd511
--- /dev/null
+++ b/vendor/lazycell/Cargo.toml
@@ -0,0 +1,34 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "lazycell"
+version = "1.3.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>", "Nikita Pekin <contact@nikitapek.in>"]
+include = ["CHANGELOG.md", "Cargo.toml", "LICENSE-MIT", "LICENSE-APACHE", "README.md", "src/**/*.rs"]
+description = "A library providing a lazily filled Cell struct"
+documentation = "http://indiv0.github.io/lazycell/lazycell/"
+readme = "README.md"
+keywords = ["lazycell", "lazy", "cell", "library"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/indiv0/lazycell"
+[dependencies.clippy]
+version = "0.0"
+optional = true
+
+[dependencies.serde]
+version = "^1"
+optional = true
+
+[features]
+nightly = []
+nightly-testing = ["clippy", "nightly"]
diff --git a/vendor/crossbeam-queue/LICENSE-APACHE b/vendor/lazycell/LICENSE-APACHE
index 16fe87b06..16fe87b06 100644
--- a/vendor/crossbeam-queue/LICENSE-APACHE
+++ b/vendor/lazycell/LICENSE-APACHE
diff --git a/vendor/crossbeam-queue/LICENSE-MIT b/vendor/lazycell/LICENSE-MIT
index 068d491fd..b4cbb4b7e 100644
--- a/vendor/crossbeam-queue/LICENSE-MIT
+++ b/vendor/lazycell/LICENSE-MIT
@@ -1,6 +1,5 @@
-The MIT License (MIT)
-
-Copyright (c) 2019 The Crossbeam Project Developers
+Original work Copyright (c) 2014 The Rust Project Developers
+Modified work Copyright (c) 2016-2018 Nikita Pekin and lazycell contributors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
diff --git a/vendor/lazycell/README.md b/vendor/lazycell/README.md
new file mode 100644
index 000000000..555fe397d
--- /dev/null
+++ b/vendor/lazycell/README.md
@@ -0,0 +1,73 @@
+# lazycell
+
+<table>
+ <tr>
+ <td><strong>Linux</strong></td>
+ <td><a href="https://travis-ci.org/indiv0/lazycell" title="Travis Build Status"><img src="https://travis-ci.org/indiv0/lazycell.svg?branch=master" alt="travis-badge"></img></a></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <a href="https://crates.io/crates/lazycell" title="Crates.io downloads"><img src="https://img.shields.io/crates/d/lazycell.svg" alt="cargo-downloads-badge"></img></a>
+ <a href="https://indiv0.github.io/lazycell/lazycell" title="API Docs"><img src="https://img.shields.io/badge/API-docs-blue.svg" alt="api-docs-badge"></img></a>
+ <a href="https://crates.io/crates/lazycell" title="Crates.io"><img src="https://img.shields.io/crates/v/lazycell.svg" alt="crates-io"></img></a>
+ <a href="#license" title="License: MIT/Apache-2.0"><img src="https://img.shields.io/crates/l/lazycell.svg" alt="license-badge"></img></a>
+ <a href="https://coveralls.io/github/indiv0/lazycell?branch=master" title="Coverage Status"><img src="https://coveralls.io/repos/github/indiv0/lazycell/badge.svg?branch=master" alt="coveralls-badge"></img></a>
+ </td>
+ </tr>
+</table>
+
+Rust library providing a lazily filled Cell.
+
+# Table of Contents
+
+* [Usage](#usage)
+* [Contributing](#contributing)
+* [Credits](#credits)
+* [License](#license)
+
+## Usage
+
+Add the following to your `Cargo.toml`:
+
+```toml
+[dependencies]
+lazycell = "1.3"
+```
+
+And in your `lib.rs` or `main.rs`:
+
+```rust
+extern crate lazycell;
+```
+
+See the [API docs][api-docs] for information on using the crate in your library.
+
+## Contributing
+
+Contributions are always welcome!
+If you have an idea for something to add (code, documentation, tests, examples,
+etc.) feel free to give it a shot.
+
+Please read [CONTRIBUTING.md][contributing] before you start contributing.
+
+## Credits
+
+The LazyCell library is based originally on work by The Rust Project Developers
+for the project [crates.io][crates-io-repo].
+
+The list of contributors to this project can be found at
+[CONTRIBUTORS.md][contributors].
+
+## License
+
+LazyCell is distributed under the terms of both the MIT license and the Apache
+License (Version 2.0).
+
+See [LICENSE-APACHE][license-apache], and [LICENSE-MIT][license-mit] for details.
+
+[api-docs]: https://indiv0.github.io/lazycell/lazycell
+[contributing]: https://github.com/indiv0/lazycell/blob/master/CONTRIBUTING.md "Contribution Guide"
+[contributors]: https://github.com/indiv0/lazycell/blob/master/CONTRIBUTORS.md "List of Contributors"
+[crates-io-repo]: https://github.com/rust-lang/crates.io "rust-lang/crates.io: Source code for crates.io"
+[license-apache]: https://github.com/indiv0/lazycell/blob/master/LICENSE-APACHE "Apache-2.0 License"
+[license-mit]: https://github.com/indiv0/lazycell/blob/master/LICENSE-MIT "MIT License"
diff --git a/vendor/lazycell/src/lib.rs b/vendor/lazycell/src/lib.rs
new file mode 100644
index 000000000..53bee073b
--- /dev/null
+++ b/vendor/lazycell/src/lib.rs
@@ -0,0 +1,680 @@
+// Original work Copyright (c) 2014 The Rust Project Developers
+// Modified work Copyright (c) 2016-2020 Nikita Pekin and the lazycell contributors
+// See the README.md file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg_attr(not(test), no_std)]
+
+#![deny(missing_docs)]
+#![cfg_attr(feature = "nightly", feature(plugin))]
+#![cfg_attr(feature = "clippy", plugin(clippy))]
+
+//! This crate provides a `LazyCell` struct which acts as a lazily filled
+//! `Cell`.
+//!
+//! With a `RefCell`, the inner contents cannot be borrowed for the lifetime of
+//! the entire object, but only of the borrows returned. A `LazyCell` is a
+//! variation on `RefCell` which allows borrows to be tied to the lifetime of
+//! the outer object.
+//!
+//! # Example
+//!
+//! The following example shows a quick example of the basic functionality of
+//! `LazyCell`.
+//!
+//! ```
+//! use lazycell::LazyCell;
+//!
+//! let lazycell = LazyCell::new();
+//!
+//! assert_eq!(lazycell.borrow(), None);
+//! assert!(!lazycell.filled());
+//! lazycell.fill(1).ok();
+//! assert!(lazycell.filled());
+//! assert_eq!(lazycell.borrow(), Some(&1));
+//! assert_eq!(lazycell.into_inner(), Some(1));
+//! ```
+//!
+//! `AtomicLazyCell` is a variant that uses an atomic variable to manage
+//! coordination in a thread-safe fashion. The limitation of an `AtomicLazyCell`
+//! is that after it is initialized, it can't be modified.
+
+
+#[cfg(not(test))]
+#[macro_use]
+extern crate core as std;
+#[cfg(feature = "serde")]
+extern crate serde;
+
+#[cfg(feature = "serde")]
+mod serde_impl;
+
+use std::cell::UnsafeCell;
+use std::mem;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+/// A lazily filled `Cell`, with mutable contents.
+///
+/// A `LazyCell` is completely frozen once filled, **unless** you have `&mut`
+/// access to it, in which case `LazyCell::borrow_mut` may be used to mutate the
+/// contents.
+#[derive(Debug)]
+pub struct LazyCell<T> {
+ inner: UnsafeCell<Option<T>>,
+}
+
+impl<T> LazyCell<T> {
+ /// Creates a new, empty, `LazyCell`.
+ pub fn new() -> LazyCell<T> {
+ LazyCell { inner: UnsafeCell::new(None) }
+ }
+
+ /// Put a value into this cell.
+ ///
+ /// This function will return `Err(value)` if the cell is already full.
+ pub fn fill(&self, value: T) -> Result<(), T> {
+ let slot = unsafe { &*self.inner.get() };
+ if slot.is_some() {
+ return Err(value);
+ }
+ let slot = unsafe { &mut *self.inner.get() };
+ *slot = Some(value);
+
+ Ok(())
+ }
+
+ /// Put a value into this cell.
+ ///
+ /// Note that this function is infallible but requires `&mut self`. By
+ /// requiring `&mut self` we're guaranteed that no active borrows to this
+ /// cell can exist so we can always fill in the value. This may not always
+ /// be usable, however, as `&mut self` may not be possible to borrow.
+ ///
+ /// # Return value
+ ///
+ /// This function returns the previous value, if any.
+ pub fn replace(&mut self, value: T) -> Option<T> {
+ mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
+ }
+
+ /// Test whether this cell has been previously filled.
+ pub fn filled(&self) -> bool {
+ self.borrow().is_some()
+ }
+
+ /// Borrows the contents of this lazy cell for the duration of the cell
+ /// itself.
+ ///
+ /// This function will return `Some` if the cell has been previously
+ /// initialized, and `None` if it has not yet been initialized.
+ pub fn borrow(&self) -> Option<&T> {
+ unsafe { &*self.inner.get() }.as_ref()
+ }
+
+ /// Borrows the contents of this lazy cell mutably for the duration of the cell
+ /// itself.
+ ///
+ /// This function will return `Some` if the cell has been previously
+ /// initialized, and `None` if it has not yet been initialized.
+ pub fn borrow_mut(&mut self) -> Option<&mut T> {
+ unsafe { &mut *self.inner.get() }.as_mut()
+ }
+
+ /// Borrows the contents of this lazy cell for the duration of the cell
+ /// itself.
+ ///
+ /// If the cell has not yet been filled, the cell is first filled using the
+ /// function provided.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the cell becomes filled as a side effect of `f`.
+ pub fn borrow_with<F: FnOnce() -> T>(&self, f: F) -> &T {
+ if let Some(value) = self.borrow() {
+ return value;
+ }
+ let value = f();
+ if self.fill(value).is_err() {
+ panic!("borrow_with: cell was filled by closure")
+ }
+ self.borrow().unwrap()
+ }
+
+ /// Borrows the contents of this `LazyCell` mutably for the duration of the
+ /// cell itself.
+ ///
+ /// If the cell has not yet been filled, the cell is first filled using the
+ /// function provided.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the cell becomes filled as a side effect of `f`.
+ pub fn borrow_mut_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
+ if !self.filled() {
+ let value = f();
+ if self.fill(value).is_err() {
+ panic!("borrow_mut_with: cell was filled by closure")
+ }
+ }
+
+ self.borrow_mut().unwrap()
+ }
+
+ /// Same as `borrow_with`, but allows the initializing function to fail.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the cell becomes filled as a side effect of `f`.
+ pub fn try_borrow_with<E, F>(&self, f: F) -> Result<&T, E>
+ where F: FnOnce() -> Result<T, E>
+ {
+ if let Some(value) = self.borrow() {
+ return Ok(value);
+ }
+ let value = f()?;
+ if self.fill(value).is_err() {
+ panic!("try_borrow_with: cell was filled by closure")
+ }
+ Ok(self.borrow().unwrap())
+ }
+
+ /// Same as `borrow_mut_with`, but allows the initializing function to fail.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the cell becomes filled as a side effect of `f`.
+ pub fn try_borrow_mut_with<E, F>(&mut self, f: F) -> Result<&mut T, E>
+ where F: FnOnce() -> Result<T, E>
+ {
+ if self.filled() {
+ return Ok(self.borrow_mut().unwrap());
+ }
+ let value = f()?;
+ if self.fill(value).is_err() {
+ panic!("try_borrow_mut_with: cell was filled by closure")
+ }
+ Ok(self.borrow_mut().unwrap())
+ }
+
+ /// Consumes this `LazyCell`, returning the underlying value.
+ pub fn into_inner(self) -> Option<T> {
+ // Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
+ // function. This unsafe can be removed when supporting Rust older than
+ // 1.25 is not needed.
+ #[allow(unused_unsafe)]
+ unsafe { self.inner.into_inner() }
+ }
+}
+
+impl<T: Copy> LazyCell<T> {
+ /// Returns a copy of the contents of the lazy cell.
+ ///
+ /// This function will return `Some` if the cell has been previously initialized,
+ /// and `None` if it has not yet been initialized.
+ pub fn get(&self) -> Option<T> {
+ unsafe { *self.inner.get() }
+ }
+}
+
+impl<T> Default for LazyCell<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl <T: Clone> Clone for LazyCell<T> {
+ /// Create a clone of this `LazyCell`
+ ///
+ /// If self has not been initialized, returns an uninitialized `LazyCell`
+ /// otherwise returns a `LazyCell` already initialized with a clone of the
+ /// contents of self.
+ fn clone(&self) -> LazyCell<T> {
+ LazyCell { inner: UnsafeCell::new(self.borrow().map(Clone::clone) ) }
+ }
+}
+
+// Tracks the AtomicLazyCell inner state
+const NONE: usize = 0;
+const LOCK: usize = 1;
+const SOME: usize = 2;
+
+/// A lazily filled and thread-safe `Cell`, with frozen contents.
+#[derive(Debug)]
+pub struct AtomicLazyCell<T> {
+ inner: UnsafeCell<Option<T>>,
+ state: AtomicUsize,
+}
+
+impl<T> AtomicLazyCell<T> {
+ /// An empty `AtomicLazyCell`.
+ pub const NONE: Self = Self {
+ inner: UnsafeCell::new(None),
+ state: AtomicUsize::new(NONE),
+ };
+
+ /// Creates a new, empty, `AtomicLazyCell`.
+ pub fn new() -> AtomicLazyCell<T> {
+ Self::NONE
+ }
+
+ /// Put a value into this cell.
+ ///
+ /// This function will return `Err(value)` if the cell is already full.
+ pub fn fill(&self, t: T) -> Result<(), T> {
+ if NONE != self.state.compare_and_swap(NONE, LOCK, Ordering::Acquire) {
+ return Err(t);
+ }
+
+ unsafe { *self.inner.get() = Some(t) };
+
+ if LOCK != self.state.compare_and_swap(LOCK, SOME, Ordering::Release) {
+ panic!("unable to release lock");
+ }
+
+ Ok(())
+ }
+
+ /// Put a value into this cell.
+ ///
+ /// Note that this function is infallible but requires `&mut self`. By
+ /// requiring `&mut self` we're guaranteed that no active borrows to this
+ /// cell can exist so we can always fill in the value. This may not always
+ /// be usable, however, as `&mut self` may not be possible to borrow.
+ ///
+ /// # Return value
+ ///
+ /// This function returns the previous value, if any.
+ pub fn replace(&mut self, value: T) -> Option<T> {
+ match mem::replace(self.state.get_mut(), SOME) {
+ NONE | SOME => {}
+ _ => panic!("cell in inconsistent state"),
+ }
+ mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
+ }
+
+ /// Test whether this cell has been previously filled.
+ pub fn filled(&self) -> bool {
+ self.state.load(Ordering::Acquire) == SOME
+ }
+
+ /// Borrows the contents of this lazy cell for the duration of the cell
+ /// itself.
+ ///
+ /// This function will return `Some` if the cell has been previously
+ /// initialized, and `None` if it has not yet been initialized.
+ pub fn borrow(&self) -> Option<&T> {
+ match self.state.load(Ordering::Acquire) {
+ SOME => unsafe { &*self.inner.get() }.as_ref(),
+ _ => None,
+ }
+ }
+
+ /// Consumes this `LazyCell`, returning the underlying value.
+ pub fn into_inner(self) -> Option<T> {
+ // Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
+ // function. This unsafe can be removed when supporting Rust older than
+ // 1.25 is not needed.
+ #[allow(unused_unsafe)]
+ unsafe { self.inner.into_inner() }
+ }
+}
+
+impl<T: Copy> AtomicLazyCell<T> {
+ /// Returns a copy of the contents of the lazy cell.
+ ///
+ /// This function will return `Some` if the cell has been previously initialized,
+ /// and `None` if it has not yet been initialized.
+ pub fn get(&self) -> Option<T> {
+ match self.state.load(Ordering::Acquire) {
+ SOME => unsafe { *self.inner.get() },
+ _ => None,
+ }
+ }
+}
+
+impl<T> Default for AtomicLazyCell<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<T: Clone> Clone for AtomicLazyCell<T> {
+ /// Create a clone of this `AtomicLazyCell`
+ ///
+ /// If self has not been initialized, returns an uninitialized `AtomicLazyCell`
+ /// otherwise returns an `AtomicLazyCell` already initialized with a clone of the
+ /// contents of self.
+ fn clone(&self) -> AtomicLazyCell<T> {
+ self.borrow().map_or(
+ Self::NONE,
+ |v| AtomicLazyCell {
+ inner: UnsafeCell::new(Some(v.clone())),
+ state: AtomicUsize::new(SOME),
+ }
+ )
+ }
+}
+
+unsafe impl<T: Sync + Send> Sync for AtomicLazyCell<T> {}
+
+unsafe impl<T: Send> Send for AtomicLazyCell<T> {}
+
+#[cfg(test)]
+mod tests {
+ use super::{AtomicLazyCell, LazyCell};
+
+ #[test]
+ fn test_borrow_from_empty() {
+ let lazycell: LazyCell<usize> = LazyCell::new();
+
+ let value = lazycell.borrow();
+ assert_eq!(value, None);
+
+ let value = lazycell.get();
+ assert_eq!(value, None);
+ }
+
+ #[test]
+ fn test_fill_and_borrow() {
+ let lazycell = LazyCell::new();
+
+ assert!(!lazycell.filled());
+ lazycell.fill(1).unwrap();
+ assert!(lazycell.filled());
+
+ let value = lazycell.borrow();
+ assert_eq!(value, Some(&1));
+
+ let value = lazycell.get();
+ assert_eq!(value, Some(1));
+ }
+
+ #[test]
+ fn test_borrow_mut() {
+ let mut lazycell = LazyCell::new();
+ assert!(lazycell.borrow_mut().is_none());
+
+ lazycell.fill(1).unwrap();
+ assert_eq!(lazycell.borrow_mut(), Some(&mut 1));
+
+ *lazycell.borrow_mut().unwrap() = 2;
+ assert_eq!(lazycell.borrow_mut(), Some(&mut 2));
+
+ // official way to reset the cell
+ lazycell = LazyCell::new();
+ assert!(lazycell.borrow_mut().is_none());
+ }
+
+ #[test]
+ fn test_already_filled_error() {
+ let lazycell = LazyCell::new();
+
+ lazycell.fill(1).unwrap();
+ assert_eq!(lazycell.fill(1), Err(1));
+ }
+
+ #[test]
+ fn test_borrow_with() {
+ let lazycell = LazyCell::new();
+
+ let value = lazycell.borrow_with(|| 1);
+ assert_eq!(&1, value);
+ }
+
+ #[test]
+ fn test_borrow_with_already_filled() {
+ let lazycell = LazyCell::new();
+ lazycell.fill(1).unwrap();
+
+ let value = lazycell.borrow_with(|| 1);
+ assert_eq!(&1, value);
+ }
+
+ #[test]
+ fn test_borrow_with_not_called_when_filled() {
+ let lazycell = LazyCell::new();
+
+ lazycell.fill(1).unwrap();
+
+ let value = lazycell.borrow_with(|| 2);
+ assert_eq!(&1, value);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_borrow_with_sound_with_reentrancy() {
+ // Kudos to dbaupp for discovering this issue
+ // https://www.reddit.com/r/rust/comments/5vs9rt/lazycell_a_rust_library_providing_a_lazilyfilled/de527xm/
+ let lazycell: LazyCell<Box<i32>> = LazyCell::new();
+
+ let mut reference: Option<&i32> = None;
+
+ lazycell.borrow_with(|| {
+ let _ = lazycell.fill(Box::new(1));
+ reference = lazycell.borrow().map(|r| &**r);
+ Box::new(2)
+ });
+ }
+
+ #[test]
+ fn test_borrow_mut_with() {
+ let mut lazycell = LazyCell::new();
+
+ {
+ let value = lazycell.borrow_mut_with(|| 1);
+ assert_eq!(&mut 1, value);
+ *value = 2;
+ }
+ assert_eq!(&2, lazycell.borrow().unwrap());
+ }
+
+ #[test]
+ fn test_borrow_mut_with_already_filled() {
+ let mut lazycell = LazyCell::new();
+ lazycell.fill(1).unwrap();
+
+ let value = lazycell.borrow_mut_with(|| 1);
+ assert_eq!(&1, value);
+ }
+
+ #[test]
+ fn test_borrow_mut_with_not_called_when_filled() {
+ let mut lazycell = LazyCell::new();
+
+ lazycell.fill(1).unwrap();
+
+ let value = lazycell.borrow_mut_with(|| 2);
+ assert_eq!(&1, value);
+ }
+
+ #[test]
+ fn test_try_borrow_with_ok() {
+ let lazycell = LazyCell::new();
+ let result = lazycell.try_borrow_with::<(), _>(|| Ok(1));
+ assert_eq!(result, Ok(&1));
+ }
+
+ #[test]
+ fn test_try_borrow_with_err() {
+ let lazycell = LazyCell::<()>::new();
+ let result = lazycell.try_borrow_with(|| Err(1));
+ assert_eq!(result, Err(1));
+ }
+
+ #[test]
+ fn test_try_borrow_with_already_filled() {
+ let lazycell = LazyCell::new();
+ lazycell.fill(1).unwrap();
+ let result = lazycell.try_borrow_with::<(), _>(|| unreachable!());
+ assert_eq!(result, Ok(&1));
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_try_borrow_with_sound_with_reentrancy() {
+ let lazycell: LazyCell<Box<i32>> = LazyCell::new();
+
+ let mut reference: Option<&i32> = None;
+
+ let _ = lazycell.try_borrow_with::<(), _>(|| {
+ let _ = lazycell.fill(Box::new(1));
+ reference = lazycell.borrow().map(|r| &**r);
+ Ok(Box::new(2))
+ });
+ }
+
+ #[test]
+ fn test_try_borrow_mut_with_ok() {
+ let mut lazycell = LazyCell::new();
+ {
+ let result = lazycell.try_borrow_mut_with::<(), _>(|| Ok(1));
+ assert_eq!(result, Ok(&mut 1));
+ *result.unwrap() = 2;
+ }
+ assert_eq!(&mut 2, lazycell.borrow().unwrap());
+ }
+
+ #[test]
+ fn test_try_borrow_mut_with_err() {
+ let mut lazycell = LazyCell::<()>::new();
+ let result = lazycell.try_borrow_mut_with(|| Err(1));
+ assert_eq!(result, Err(1));
+ }
+
+ #[test]
+ fn test_try_borrow_mut_with_already_filled() {
+ let mut lazycell = LazyCell::new();
+ lazycell.fill(1).unwrap();
+ let result = lazycell.try_borrow_mut_with::<(), _>(|| unreachable!());
+ assert_eq!(result, Ok(&mut 1));
+ }
+
+ #[test]
+ fn test_into_inner() {
+ let lazycell = LazyCell::new();
+
+ lazycell.fill(1).unwrap();
+ let value = lazycell.into_inner();
+ assert_eq!(value, Some(1));
+ }
+
+ #[test]
+ fn test_atomic_borrow_from_empty() {
+ let lazycell: AtomicLazyCell<usize> = AtomicLazyCell::new();
+
+ let value = lazycell.borrow();
+ assert_eq!(value, None);
+
+ let value = lazycell.get();
+ assert_eq!(value, None);
+ }
+
+ #[test]
+ fn test_atomic_fill_and_borrow() {
+ let lazycell = AtomicLazyCell::new();
+
+ assert!(!lazycell.filled());
+ lazycell.fill(1).unwrap();
+ assert!(lazycell.filled());
+
+ let value = lazycell.borrow();
+ assert_eq!(value, Some(&1));
+
+ let value = lazycell.get();
+ assert_eq!(value, Some(1));
+ }
+
+ #[test]
+ fn test_atomic_already_filled_panic() {
+ let lazycell = AtomicLazyCell::new();
+
+ lazycell.fill(1).unwrap();
+ assert_eq!(1, lazycell.fill(1).unwrap_err());
+ }
+
+ #[test]
+ fn test_atomic_into_inner() {
+ let lazycell = AtomicLazyCell::new();
+
+ lazycell.fill(1).unwrap();
+ let value = lazycell.into_inner();
+ assert_eq!(value, Some(1));
+ }
+
+ #[test]
+ fn normal_replace() {
+ let mut cell = LazyCell::new();
+ assert_eq!(cell.fill(1), Ok(()));
+ assert_eq!(cell.replace(2), Some(1));
+ assert_eq!(cell.replace(3), Some(2));
+ assert_eq!(cell.borrow(), Some(&3));
+
+ let mut cell = LazyCell::new();
+ assert_eq!(cell.replace(2), None);
+ }
+
+ #[test]
+ fn atomic_replace() {
+ let mut cell = AtomicLazyCell::new();
+ assert_eq!(cell.fill(1), Ok(()));
+ assert_eq!(cell.replace(2), Some(1));
+ assert_eq!(cell.replace(3), Some(2));
+ assert_eq!(cell.borrow(), Some(&3));
+ }
+
+ #[test]
+ fn clone() {
+ let mut cell = LazyCell::new();
+ let clone1 = cell.clone();
+ assert_eq!(clone1.borrow(), None);
+ assert_eq!(cell.fill(1), Ok(()));
+ let mut clone2 = cell.clone();
+ assert_eq!(clone1.borrow(), None);
+ assert_eq!(clone2.borrow(), Some(&1));
+ assert_eq!(cell.replace(2), Some(1));
+ assert_eq!(clone1.borrow(), None);
+ assert_eq!(clone2.borrow(), Some(&1));
+ assert_eq!(clone1.fill(3), Ok(()));
+ assert_eq!(clone2.replace(4), Some(1));
+ assert_eq!(clone1.borrow(), Some(&3));
+ assert_eq!(clone2.borrow(), Some(&4));
+ assert_eq!(cell.borrow(), Some(&2));
+ }
+
+ #[test]
+ fn clone_atomic() {
+ let mut cell = AtomicLazyCell::new();
+ let clone1 = cell.clone();
+ assert_eq!(clone1.borrow(), None);
+ assert_eq!(cell.fill(1), Ok(()));
+ let mut clone2 = cell.clone();
+ assert_eq!(clone1.borrow(), None);
+ assert_eq!(clone2.borrow(), Some(&1));
+ assert_eq!(cell.replace(2), Some(1));
+ assert_eq!(clone1.borrow(), None);
+ assert_eq!(clone2.borrow(), Some(&1));
+ assert_eq!(clone1.fill(3), Ok(()));
+ assert_eq!(clone2.replace(4), Some(1));
+ assert_eq!(clone1.borrow(), Some(&3));
+ assert_eq!(clone2.borrow(), Some(&4));
+ assert_eq!(cell.borrow(), Some(&2));
+ }
+
+ #[test]
+ fn default() {
+ #[derive(Default)]
+ struct Defaultable;
+ struct NonDefaultable;
+
+ let _: LazyCell<Defaultable> = LazyCell::default();
+ let _: LazyCell<NonDefaultable> = LazyCell::default();
+
+ let _: AtomicLazyCell<Defaultable> = AtomicLazyCell::default();
+ let _: AtomicLazyCell<NonDefaultable> = AtomicLazyCell::default();
+ }
+}
diff --git a/vendor/lazycell/src/serde_impl.rs b/vendor/lazycell/src/serde_impl.rs
new file mode 100644
index 000000000..8f08f7b03
--- /dev/null
+++ b/vendor/lazycell/src/serde_impl.rs
@@ -0,0 +1,86 @@
+// Copyright (c) 2020 Nikita Pekin and the lazycell contributors
+// See the README.md file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.use serde::ser::{Serialize, Serializer};
+use serde::ser::{Serialize, Serializer};
+use serde::de::{self, Deserialize, Deserializer, Visitor};
+
+use std::fmt;
+use std::marker::PhantomData;
+
+use super::{LazyCell, AtomicLazyCell};
+
+impl<T: Serialize> Serialize for LazyCell<T> {
+ fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ match self.borrow() {
+ Some(val) => serializer.serialize_some(val),
+ None => serializer.serialize_none()
+ }
+ }
+}
+
+
+impl<T: Serialize> Serialize for AtomicLazyCell<T> {
+ fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ match self.borrow() {
+ Some(val) => serializer.serialize_some(val),
+ None => serializer.serialize_none()
+ }
+ }
+}
+
+struct LazyCellVisitor<T>(PhantomData<*const T>);
+impl<'de, T: Deserialize<'de>> Visitor<'de> for LazyCellVisitor<T> {
+ type Value = LazyCell<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a LazyCell")
+ }
+
+ fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+ let mut cell = LazyCell::new();
+ cell.replace(T::deserialize(deserializer)?);
+ Ok(cell)
+ }
+
+ fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
+ Ok(LazyCell::new())
+ }
+}
+
+impl<'de, T: Deserialize<'de>> Deserialize<'de> for LazyCell<T> {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_option(LazyCellVisitor(PhantomData))
+ }
+}
+
+
+struct AtomicLazyCellVisitor<T>(PhantomData<*const T>);
+impl<'de, T: Deserialize<'de>> Visitor<'de> for AtomicLazyCellVisitor<T> {
+ type Value = AtomicLazyCell<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("an AtomicLazyCell")
+ }
+
+ fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+ let mut cell = AtomicLazyCell::new();
+ cell.replace(T::deserialize(deserializer)?);
+ Ok(cell)
+ }
+
+ fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
+ Ok(AtomicLazyCell::new())
+ }
+}
+
+
+impl<'de, T: Deserialize<'de>> Deserialize<'de> for AtomicLazyCell<T> {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_option(AtomicLazyCellVisitor(PhantomData))
+ }
+}
diff --git a/vendor/libc/.cargo-checksum.json b/vendor/libc/.cargo-checksum.json
index 26956a434..f16c56427 100644
--- a/vendor/libc/.cargo-checksum.json
+++ b/vendor/libc/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CONTRIBUTING.md":"752eea5a703d11b485c6b5f195f51bd2c79aa5159b619ce09555c779e1fb586b","Cargo.toml":"6a0abcfcbc1d9fb00a356343043a161f5b84b3f780cb0f02df4627d022b14b7f","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"8228847944f1332882fbb00275b6f30e4a8aad08a13569c25d52cac012cc2a47","build.rs":"41f9743021d9e5ed74ede55c94057cf6867a322a13b25a5d524b966656a08e38","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"bc8c46531bd1a2429f36aaf2bc137b50e42505b798de83f34eecfa94ad89179b","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"3f13d5f9b29d8969dde507661f1637524e21fe3bd34957fc778868f2f3713c46","src/macros.rs":"d7437c2573c4915768ff96b34710a61ee9f63622b23526cddeaeaf6bfb4751a2","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"2eaf0f561a32bdcbf4e0477c8895d5e7bcb5cdebd5fef7b4df2ca8e38e144d94","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"d7155927fbd1af6dd984a4c6c1a735a5932af828c96818209487eb6ae72d7d7e","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"379302e12d30807a1f973c4e2dd2205179d95343ee6fae05f33c9ed45a342799","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"467b66843ab8c1a54b01ae9e90aaf0295b32f54decbdfb64caca84523b488925","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"a7345cc3fb7372572efe06848feb2cc246dfc2c2a0cc9ccf434f4c55041a59fa","src/unix/bsd/mod.rs":"7720ec82c9334f988ec4b271784768a017c3dc2e6dfae4d02418eef753388aa7","src/unix/bsd/netbsdlike/mod.rs":"594a0f9e23c4d7702ba38afdba5a0e866be25d692ec0afd66e04d939aa6b3f04","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"cb1560bf8ffcc7b2726a27b433efac90e726292960626f3064bd2c6b7f861a55","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"816a8ef47df60a752a91967627eeccb9ca776dc718ecc53ae902d8edaee0bce9","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"d5833ff9b94daa81d2470df544453212af17530d78c5a7fb912eac915d00f329","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"d7bbbadafdb2cb2ff8e9cde3d89a03b9facaabb6b2d45705225d3ece1c5cce37","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"6454948ea98be86243229f99d67cdc7ca460e16b2a6445663ff4b5b6907c358d","src/unix/linux_like/android/mod.rs":"1247397a7e1b6269e0d2d6df88c6396bc18eb477e3ff293ff57d66a6b1380d94","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"b71d37106750f57bc2dae4e9bcb473ff098ef48235827e41a1687a39825f0aa4","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c4e20b1c63d7a03a6e22aef2046689ef95cc4651011ade7cb94176fcea1dc252","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"1b939aaf3cdf3efc7d3bd53e83e80235530d3ba0c24bb7611d4730d35d457ec1","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"84ad4a663b5fa2498179be8dca96fef5f0446ec1619215ac674424ee394e307d","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"cff23db1e0bac8c30052dfed5e89e65bc207471e4bfb3a6fa0a4df62ed9e413e","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"798a9229d70ce235394f2dd625f6c4c1e10519a94382dc5b091952b638ae2928","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"3686fc8cb2e311cda8e6b96f6dfe90b65a366714bd480312b692b1a6ca1241b6","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"9b05b1fae6bcb7cb6d909b9973977fde01684175f3e26c27dcb44223cc3933d9","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"2efe98b8166270be1624888953fa07da06f08313f15bf4c7dc2eba63f5a790a5","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"ddd223d4f574b2b92072bbdab091f12d8d89d5e05f41076ddfa6bc6af379698f","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"dd4f7a1d66d8501b4a2c4e75e6e9305ed69f1002ae99e410596a6c636878595a","src/unix/mod.rs":"d1b4ba41f9b9c106f6ba8c661b5808824b774a7a7caac7d8938bf50979ba5195","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"ff9c13e99d84912f5ebe75b7a7ea9c1e9d8f35a268716081e09899c7ea822bc6","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"976b07a13e195840b67c166a62318abfa9ffc8d5ebbb0358f199dd213ec98d1b","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"e3ad95ba54f76e74c301611fe868d3d94f6b8939b03be672f568b06b10ae71c7","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"} \ No newline at end of file
+{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"1549dc2db0ecd74316f52b2d14b15144ae970a848bf3d54c048844ed7a35df2a","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"94cbaad15021e287a1b9546a697b04c1e560f1204b52204ffaaea5975c5d03b9","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"ce753ef318b300bbd441feabdd77d00322dfb6ce9eee8c78a38afe02b57aa4c0","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"56dc7604509f49b274770cade97a1874c8955c3b0a445fb857707ae0ca6df41b","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"d0e8246063cae113806524a63a47c6c0628cc54a3ef03e938e89964f8b4f08b4","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"ec229cc7af2511cb510c078e87e90ee2625090bfe94f40eb35f73d79143533aa","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"1e35b4773384ea143810cdce4b96f47108b37446430da30c96a0d1651656d73d","src/unix/bsd/mod.rs":"817ca5719c36a74c84e52c6a56a5998b60d7f02351a405e034f08ebab079b63a","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"8f9613e50c2771b33d7cf817a735d536b389ec57f861b9486d870373c768276e","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"228505fa48292e74b06acbed96196801595a4b822da2126a6d6c7fa773cff8bc","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"df7b6b7d8dd3441665bfe87f2abc942bddc65b8b10dfa9c83dd0422f68107891","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"80e9f93fed838a48b4e2e8d77b95c72cfd7c0647bcce63851555c5ad16dad143","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"962741303dc24a5b9653f2e9b0b4ad9eb42fc54daa0a70ca70a7ce175e75094b","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"c69c90606d4362f8de89b8816df0ded724ed64b53bf55d15681fde171b7bb361","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c72a08011c32f82919e930e0d89044d8feb65fd41bf80647436756c290344eb8","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"f0db9914315d5a3d51bf5ec04a0ae6584f2e1688b9258ce132b617e67d9bd7a9","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"fd62b48974dd2f97f6e8fa2a30624e8d69fdedc5d3b0ab2f3f09516e88a8769a","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"af94b1a6d844bed87bb4c93de0a12f160ca1f918f5234d7fe17511d4e424dedc","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"1fa4974fe412b22c3555d3e240dbf00cc04a5287c751035ddf08a0470d4a7c9a","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"c7ebabc4e1bdbbd97e5065faa3a57f41f473570920582d979f9e9d4f77448546","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"c3365480375bc258ffe267e7a299d7b3bb542a908bef8881f503ddc25ba8fc1f","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"09fa012e027bfcdaabee221c1b676804a9c7e0e04a4b64fdd98a50c9b5c2f674","src/unix/mod.rs":"fbd5520d160a32a127608cd408905febe387773bbf05bfe199ef385fb5562e9c","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"816f235f4aa4baabba7f2606b31d0fdb03988c52194c966728de8690bf17299d","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"8914a68865af026c1f4fb1d5f02ba0053362ef34b813ad60cc4aa3a88aa4999e","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"090dd8fcd951d18f1905bca96188783c2e3f1433484926ecdcda144237ecec0f","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"} \ No newline at end of file
diff --git a/vendor/libc/CONTRIBUTING.md b/vendor/libc/CONTRIBUTING.md
index 5be6eb9be..3315ed3e8 100644
--- a/vendor/libc/CONTRIBUTING.md
+++ b/vendor/libc/CONTRIBUTING.md
@@ -72,6 +72,10 @@ after a certain period. The steps are:
If you're using it, please comment on #XXX").
2. If we don't see any concerns for a while, do the change actually.
+## Supported target policy
+
+When Rust removes a support for a target, the libc crate also may remove the support anytime.
+
## Releasing your change to crates.io
Now that you've done the amazing job of landing your new API or your new
diff --git a/vendor/libc/Cargo.toml b/vendor/libc/Cargo.toml
index 7983d029f..5b54eced6 100644
--- a/vendor/libc/Cargo.toml
+++ b/vendor/libc/Cargo.toml
@@ -11,7 +11,7 @@
[package]
name = "libc"
-version = "0.2.126"
+version = "0.2.132"
authors = ["The Rust Project Developers"]
build = "build.rs"
exclude = [
diff --git a/vendor/libc/README.md b/vendor/libc/README.md
index a8a3afd9f..bc5ad18f6 100644
--- a/vendor/libc/README.md
+++ b/vendor/libc/README.md
@@ -35,13 +35,16 @@ libc = "0.2"
This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`.
* `const-extern-fn`: Changes some `extern fn`s into `const extern fn`s.
- This feature requires a nightly rustc.
+ If you use Rust >= 1.62, this feature is implicitly enabled.
+ Otherwise it requires a nightly rustc.
* **deprecated**: `use_std` is deprecated, and is equivalent to `std`.
## Rust version support
-The minimum supported Rust toolchain version is **Rust 1.13.0** . APIs requiring
+The minimum supported Rust toolchain version is currently **Rust 1.13.0**.
+(libc does not currently have any policy regarding changes to the minimum
+supported Rust version; such policy is a work in progress.) APIs requiring
newer Rust features are only available on newer Rust toolchains:
| Feature | Version |
@@ -53,6 +56,7 @@ newer Rust features are only available on newer Rust toolchains:
| `core::ffi::c_void` | 1.30.0 |
| `repr(packed(N))` | 1.33.0 |
| `cfg(target_vendor)` | 1.33.0 |
+| `const-extern-fn` | 1.62.0 |
## Platform support
diff --git a/vendor/libc/build.rs b/vendor/libc/build.rs
index bc7b77f25..0a43b2a12 100644
--- a/vendor/libc/build.rs
+++ b/vendor/libc/build.rs
@@ -97,11 +97,18 @@ fn main() {
println!("cargo:rustc-cfg=libc_thread_local");
}
- if const_extern_fn_cargo_feature {
- if !is_nightly || rustc_minor_ver < 40 {
- panic!("const-extern-fn requires a nightly compiler >= 1.40")
- }
+ // Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C".
+ if rustc_minor_ver >= 62 {
println!("cargo:rustc-cfg=libc_const_extern_fn");
+ } else {
+ // Rust < 1.62.0 requires a crate feature and feature gate.
+ if const_extern_fn_cargo_feature {
+ if !is_nightly || rustc_minor_ver < 40 {
+ panic!("const-extern-fn requires a nightly compiler >= 1.40");
+ }
+ println!("cargo:rustc-cfg=libc_const_extern_fn_unstable");
+ println!("cargo:rustc-cfg=libc_const_extern_fn");
+ }
}
}
diff --git a/vendor/libc/src/fuchsia/mod.rs b/vendor/libc/src/fuchsia/mod.rs
index 99b7791b0..4a18a8daa 100644
--- a/vendor/libc/src/fuchsia/mod.rs
+++ b/vendor/libc/src/fuchsia/mod.rs
@@ -877,6 +877,11 @@ s! {
pub c_ispeed: ::speed_t,
pub c_ospeed: ::speed_t,
}
+
+ pub struct in6_pktinfo {
+ pub ipi6_addr: ::in6_addr,
+ pub ipi6_ifindex: ::c_uint,
+ }
}
s_no_extra_traits! {
@@ -1788,6 +1793,9 @@ pub const IPV6_MULTICAST_LOOP: ::c_int = 19;
pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20;
pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21;
pub const IPV6_V6ONLY: ::c_int = 26;
+pub const IPV6_RECVPKTINFO: ::c_int = 49;
+pub const IPV6_RECVTCLASS: ::c_int = 66;
+pub const IPV6_TCLASS: ::c_int = 67;
pub const TCP_NODELAY: ::c_int = 1;
pub const TCP_MAXSEG: ::c_int = 2;
@@ -2669,6 +2677,9 @@ pub const PT_GNU_EH_FRAME: u32 = 0x6474e550;
pub const PT_GNU_STACK: u32 = 0x6474e551;
pub const PT_GNU_RELRO: u32 = 0x6474e552;
+// Ethernet protocol IDs.
+pub const ETH_P_IP: ::c_int = 0x0800;
+
pub const SFD_CLOEXEC: ::c_int = 0x080000;
pub const NCCS: usize = 32;
diff --git a/vendor/libc/src/lib.rs b/vendor/libc/src/lib.rs
index d87d0d8e1..acda09159 100644
--- a/vendor/libc/src/lib.rs
+++ b/vendor/libc/src/lib.rs
@@ -13,7 +13,9 @@
improper_ctypes,
// This lint is renamed but we run CI for old stable rustc so should be here.
redundant_semicolon,
- redundant_semicolons
+ redundant_semicolons,
+ unused_macros,
+ unused_macro_rules,
)]
#![cfg_attr(libc_deny_warnings, deny(warnings))]
// Attributes needed when building as part of the standard library
@@ -24,11 +26,7 @@
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
-#![cfg_attr(
- feature = "rustc-dep-of-std",
- feature(native_link_modifiers, native_link_modifiers_bundle)
-)]
-#![cfg_attr(libc_const_extern_fn, feature(const_extern_fn))]
+#![cfg_attr(libc_const_extern_fn_unstable, feature(const_extern_fn))]
#[macro_use]
mod macros;
diff --git a/vendor/libc/src/macros.rs b/vendor/libc/src/macros.rs
index 603fa583e..fd473702f 100644
--- a/vendor/libc/src/macros.rs
+++ b/vendor/libc/src/macros.rs
@@ -6,7 +6,6 @@
///
/// This allows you to conveniently provide a long list #[cfg]'d blocks of code
/// without having to rewrite each clause multiple times.
-#[allow(unused_macros)]
macro_rules! cfg_if {
// match if/else chains with a final `else`
($(
@@ -62,7 +61,6 @@ macro_rules! cfg_if {
};
}
-#[allow(unused_macros, unused_macro_rules)]
macro_rules! s {
($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($(
s!(it: $(#[$attr])* pub $t $i { $($field)* });
@@ -87,7 +85,6 @@ macro_rules! s {
);
}
-#[allow(unused_macros)]
macro_rules! s_no_extra_traits {
($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($(
s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* });
@@ -123,7 +120,6 @@ macro_rules! s_no_extra_traits {
);
}
-#[allow(unused_macros)]
macro_rules! e {
($($(#[$attr:meta])* pub enum $i:ident { $($field:tt)* })*) => ($(
__item! {
@@ -138,7 +134,6 @@ macro_rules! e {
)*);
}
-#[allow(unused_macros)]
macro_rules! s_paren {
($($(#[$attr:meta])* pub struct $i:ident ( $($field:tt)* ); )* ) => ($(
__item! {
@@ -182,7 +177,6 @@ macro_rules! s_paren {
// 'f!' block
cfg_if! {
if #[cfg(libc_const_extern_fn)] {
- #[allow(unused_macros)]
macro_rules! f {
($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
$($arg:ident: $argty:ty),*
@@ -198,7 +192,6 @@ cfg_if! {
)*)
}
- #[allow(unused_macros)]
macro_rules! safe_f {
($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
$($arg:ident: $argty:ty),*
@@ -214,7 +207,6 @@ cfg_if! {
)*)
}
- #[allow(unused_macros)]
macro_rules! const_fn {
($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident(
$($arg:ident: $argty:ty),*
@@ -231,7 +223,6 @@ cfg_if! {
}
} else {
- #[allow(unused_macros)]
macro_rules! f {
($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
$($arg:ident: $argty:ty),*
@@ -247,7 +238,6 @@ cfg_if! {
)*)
}
- #[allow(unused_macros)]
macro_rules! safe_f {
($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
$($arg:ident: $argty:ty),*
@@ -263,7 +253,6 @@ cfg_if! {
)*)
}
- #[allow(unused_macros)]
macro_rules! const_fn {
($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident(
$($arg:ident: $argty:ty),*
@@ -281,14 +270,12 @@ cfg_if! {
}
}
-#[allow(unused_macros)]
macro_rules! __item {
($i:item) => {
$i
};
}
-#[allow(unused_macros)]
macro_rules! align_const {
($($(#[$attr:meta])*
pub const $name:ident : $t1:ty
@@ -308,7 +295,6 @@ macro_rules! align_const {
}
// This macro is used to deprecate items that should be accessed via the mach2 crate
-#[allow(unused_macros)]
macro_rules! deprecated_mach {
(pub const $id:ident: $ty:ty = $expr:expr;) => {
#[deprecated(
@@ -342,7 +328,6 @@ macro_rules! deprecated_mach {
}
}
-#[allow(unused_macros)]
#[cfg(not(libc_ptr_addr_of))]
macro_rules! ptr_addr_of {
($place:expr) => {
@@ -350,7 +335,6 @@ macro_rules! ptr_addr_of {
};
}
-#[allow(unused_macros)]
#[cfg(libc_ptr_addr_of)]
macro_rules! ptr_addr_of {
($place:expr) => {
diff --git a/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs b/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs
index 131e15b69..29db97ec7 100644
--- a/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs
+++ b/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs
@@ -15,6 +15,7 @@ s! {
pub uc_link: *mut ::ucontext_t,
pub uc_mcsize: usize,
pub uc_mcontext: mcontext_t,
+ __mcontext_data: __darwin_mcontext64,
}
pub struct __darwin_mcontext64 {
diff --git a/vendor/libc/src/unix/bsd/apple/mod.rs b/vendor/libc/src/unix/bsd/apple/mod.rs
index bd69d8aaa..a831ca850 100644
--- a/vendor/libc/src/unix/bsd/apple/mod.rs
+++ b/vendor/libc/src/unix/bsd/apple/mod.rs
@@ -53,6 +53,8 @@ pub type host_info64_t = *mut integer_t;
pub type processor_flavor_t = ::c_int;
pub type thread_flavor_t = natural_t;
pub type thread_inspect_t = ::mach_port_t;
+pub type thread_act_t = ::mach_port_t;
+pub type thread_act_array_t = *mut ::thread_act_t;
pub type policy_t = ::c_int;
pub type mach_vm_address_t = u64;
pub type mach_vm_offset_t = u64;
@@ -64,6 +66,9 @@ pub type memory_object_offset_t = ::c_ulonglong;
pub type vm_inherit_t = ::c_uint;
pub type vm_prot_t = ::c_int;
+pub type ledger_t = ::mach_port_t;
+pub type ledger_array_t = *mut ::ledger_t;
+
pub type iconv_t = *mut ::c_void;
pub type processor_cpu_load_info_t = *mut processor_cpu_load_info;
@@ -121,6 +126,7 @@ pub type vm_statistics64_t = *mut vm_statistics64;
pub type vm_statistics64_data_t = vm_statistics64;
pub type task_t = ::mach_port_t;
+pub type task_inspect_t = ::mach_port_t;
pub type sysdir_search_path_enumeration_state = ::c_uint;
@@ -672,6 +678,13 @@ s! {
pub s_addr: ::in_addr_t,
}
+ // net/ndrv.h
+ pub struct sockaddr_ndrv {
+ pub snd_len: ::c_uchar,
+ pub snd_family: ::c_uchar,
+ pub snd_name: [::c_uchar; 16] // IFNAMSIZ from if.h
+ }
+
// sys/socket.h
pub struct sa_endpoints_t {
@@ -1038,7 +1051,8 @@ s_no_extra_traits! {
pub f_fstypename: [::c_char; 16],
pub f_mntonname: [::c_char; 1024],
pub f_mntfromname: [::c_char; 1024],
- pub f_reserved: [u32; 8],
+ pub f_flags_ext: u32,
+ pub f_reserved: [u32; 7],
}
pub struct dirent {
@@ -3466,6 +3480,7 @@ pub const pseudo_AF_RTIP: ::c_int = 22;
pub const AF_IPX: ::c_int = 23;
pub const AF_SIP: ::c_int = 24;
pub const pseudo_AF_PIP: ::c_int = 25;
+pub const AF_NDRV: ::c_int = 27;
pub const AF_ISDN: ::c_int = 28;
pub const AF_E164: ::c_int = AF_ISDN;
pub const pseudo_AF_KEY: ::c_int = 29;
@@ -3508,6 +3523,7 @@ pub const PF_SIP: ::c_int = AF_SIP;
pub const PF_IPX: ::c_int = AF_IPX;
pub const PF_RTIP: ::c_int = pseudo_AF_RTIP;
pub const PF_PIP: ::c_int = pseudo_AF_PIP;
+pub const PF_NDRV: ::c_int = AF_NDRV;
pub const PF_ISDN: ::c_int = AF_ISDN;
pub const PF_KEY: ::c_int = pseudo_AF_KEY;
pub const PF_INET6: ::c_int = AF_INET6;
@@ -3552,6 +3568,7 @@ pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 70;
pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 71;
pub const IP_BLOCK_SOURCE: ::c_int = 72;
pub const IP_UNBLOCK_SOURCE: ::c_int = 73;
+pub const IPV6_BOUND_IF: ::c_int = 125;
pub const TCP_NOPUSH: ::c_int = 4;
pub const TCP_NOOPT: ::c_int = 8;
@@ -4672,6 +4689,16 @@ cfg_if! {
const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::<u32>() - 1;
p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
}
+ } else {
+ fn __DARWIN_ALIGN32(p: usize) -> usize {
+ let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::<u32>() - 1;
+ p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
+ }
+ }
+}
+
+cfg_if! {
+ if #[cfg(libc_const_size_of)] {
pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t =
(::mem::size_of::<thread_extended_policy_data_t>() / ::mem::size_of::<integer_t>())
as mach_msg_type_number_t;
@@ -4712,10 +4739,6 @@ cfg_if! {
(::mem::size_of::<vm_statistics64_data_t>() / ::mem::size_of::<integer_t>())
as mach_msg_type_number_t;
} else {
- fn __DARWIN_ALIGN32(p: usize) -> usize {
- let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::<u32>() - 1;
- p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
- }
pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t = 1;
pub const THREAD_TIME_CONSTRAINT_POLICY_COUNT: mach_msg_type_number_t = 4;
pub const THREAD_PRECEDENCE_POLICY_COUNT: mach_msg_type_number_t = 1;
@@ -5004,6 +5027,8 @@ extern "C" {
thread_info_out: thread_info_t,
thread_info_outCnt: *mut mach_msg_type_number_t,
) -> kern_return_t;
+ #[cfg_attr(doc, doc(alias = "__errno_location"))]
+ #[cfg_attr(doc, doc(alias = "errno"))]
pub fn __error() -> *mut ::c_int;
pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int;
pub fn backtrace_symbols(addrs: *const *mut ::c_void, sz: ::c_int) -> *mut *mut ::c_char;
@@ -5480,6 +5505,19 @@ extern "C" {
task_info_out: task_info_t,
task_info_count: *mut mach_msg_type_number_t,
) -> ::kern_return_t;
+ pub fn task_create(
+ target_task: ::task_t,
+ ledgers: ::ledger_array_t,
+ ledgersCnt: ::mach_msg_type_number_t,
+ inherit_memory: ::boolean_t,
+ child_task: *mut ::task_t,
+ ) -> ::kern_return_t;
+ pub fn task_terminate(target_task: ::task_t) -> ::kern_return_t;
+ pub fn task_threads(
+ target_task: ::task_inspect_t,
+ act_list: *mut ::thread_act_array_t,
+ act_listCnt: *mut ::mach_msg_type_number_t,
+ ) -> ::kern_return_t;
pub fn host_statistics(
host_priv: host_t,
flavor: host_flavor_t,
@@ -5508,12 +5546,23 @@ cfg_if! {
if #[cfg(target_os = "macos")] {
extern "C" {
pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int;
+ }
+ }
+}
+cfg_if! {
+ if #[cfg(any(target_os = "macos", target_os = "ios"))] {
+ extern "C" {
pub fn memmem(
haystack: *const ::c_void,
haystacklen: ::size_t,
needle: *const ::c_void,
needlelen: ::size_t,
) -> *mut ::c_void;
+ pub fn task_set_info(target_task: ::task_t,
+ flavor: ::task_flavor_t,
+ task_info_in: ::task_info_t,
+ task_info_inCnt: ::mach_msg_type_number_t
+ ) -> ::kern_return_t;
}
}
}
diff --git a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs
index d56362816..df7719b4b 100644
--- a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs
+++ b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs
@@ -34,6 +34,17 @@ pub type pthread_spinlock_t = ::uintptr_t;
pub type segsz_t = usize;
+pub type vm_prot_t = u8;
+pub type vm_maptype_t = u8;
+pub type vm_inherit_t = i8;
+pub type vm_subsys_t = ::c_int;
+pub type vm_eflags_t = ::c_uint;
+
+pub type vm_map_t = *mut __c_anonymous_vm_map;
+pub type vm_map_entry_t = *mut vm_map_entry;
+
+pub type pmap = __c_anonymous_pmap;
+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub enum sem {}
impl ::Copy for sem {}
@@ -336,6 +347,50 @@ s! {
kp_spare: [::c_int; 2],
}
+ pub struct __c_anonymous_vm_map {
+ _priv: [::uintptr_t; 36],
+ }
+
+ pub struct vm_map_entry {
+ _priv: [::uintptr_t; 15],
+ pub eflags: ::vm_eflags_t,
+ pub maptype: ::vm_maptype_t,
+ pub protection: ::vm_prot_t,
+ pub max_protection: ::vm_prot_t,
+ pub inheritance: ::vm_inherit_t,
+ pub wired_count: ::c_int,
+ pub id: ::vm_subsys_t,
+ }
+
+ pub struct __c_anonymous_pmap {
+ _priv1: [::uintptr_t; 32],
+ _priv2: [::uintptr_t; 32],
+ _priv3: [::uintptr_t; 32],
+ _priv4: [::uintptr_t; 32],
+ _priv5: [::uintptr_t; 8],
+ }
+
+ pub struct vmspace {
+ vm_map: __c_anonymous_vm_map,
+ vm_pmap: __c_anonymous_pmap,
+ pub vm_flags: ::c_int,
+ pub vm_shm: *mut ::c_char,
+ pub vm_rssize: ::segsz_t,
+ pub vm_swrss: ::segsz_t,
+ pub vm_tsize: ::segsz_t,
+ pub vm_dsize: ::segsz_t,
+ pub vm_ssize: ::segsz_t,
+ pub vm_taddr: *mut ::c_char,
+ pub vm_daddr: *mut ::c_char,
+ pub vm_maxsaddr: *mut ::c_char,
+ pub vm_minsaddr: *mut ::c_char,
+ _unused1: ::c_int,
+ _unused2: ::c_int,
+ pub vm_pagesupply: ::c_int,
+ pub vm_holdcnt: ::c_uint,
+ pub vm_refcnt: ::c_uint,
+ }
+
pub struct cpuctl_msr_args_t {
pub msr: ::c_int,
pub data: u64,
@@ -1613,6 +1668,20 @@ extern "C" {
pub fn freezero(ptr: *mut ::c_void, size: ::size_t);
}
+#[link(name = "kvm")]
+extern "C" {
+ pub fn kvm_vm_map_entry_first(
+ kvm: *mut ::kvm_t,
+ map: vm_map_t,
+ entry: vm_map_entry_t,
+ ) -> vm_map_entry_t;
+ pub fn kvm_vm_map_entry_next(
+ kvm: *mut ::kvm_t,
+ map: vm_map_entry_t,
+ entry: vm_map_entry_t,
+ ) -> vm_map_entry_t;
+}
+
cfg_if! {
if #[cfg(libc_thread_local)] {
mod errno;
diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs
index 8d27d8860..84e43b23e 100644
--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs
+++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs
@@ -44,10 +44,6 @@ pub type fhandle_t = fhandle;
pub type au_id_t = ::uid_t;
pub type au_asid_t = ::pid_t;
-// It's an alias over "struct __kvm_t". However, its fields aren't supposed to be used directly,
-// making the type definition system dependent. Better not bind it exactly.
-pub type kvm_t = ::c_void;
-
#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))]
#[repr(u32)]
pub enum devstat_support_flags {
@@ -3661,6 +3657,19 @@ pub const CPUCLOCK_WHICH_TID: ::c_int = 1;
pub const MFD_CLOEXEC: ::c_uint = 0x00000001;
pub const MFD_ALLOW_SEALING: ::c_uint = 0x00000002;
pub const MFD_HUGETLB: ::c_uint = 0x00000004;
+pub const MFD_HUGE_MASK: ::c_uint = 0xFC000000;
+pub const MFD_HUGE_64KB: ::c_uint = 16 << 26;
+pub const MFD_HUGE_512KB: ::c_uint = 19 << 26;
+pub const MFD_HUGE_1MB: ::c_uint = 20 << 26;
+pub const MFD_HUGE_2MB: ::c_uint = 21 << 26;
+pub const MFD_HUGE_8MB: ::c_uint = 23 << 26;
+pub const MFD_HUGE_16MB: ::c_uint = 24 << 26;
+pub const MFD_HUGE_32MB: ::c_uint = 25 << 26;
+pub const MFD_HUGE_256MB: ::c_uint = 28 << 26;
+pub const MFD_HUGE_512MB: ::c_uint = 29 << 26;
+pub const MFD_HUGE_1GB: ::c_uint = 30 << 26;
+pub const MFD_HUGE_2GB: ::c_uint = 31 << 26;
+pub const MFD_HUGE_16GB: ::c_uint = 34 << 26;
pub const SHM_LARGEPAGE_ALLOC_DEFAULT: ::c_int = 0;
pub const SHM_LARGEPAGE_ALLOC_NOWAIT: ::c_int = 1;
@@ -3772,21 +3781,21 @@ f! {
}
pub fn CPU_SET(cpu: usize, cpuset: &mut cpuset_t) -> () {
- let bitset_bits = ::mem::size_of::<::c_long>();
+ let bitset_bits = 8 * ::mem::size_of::<::c_long>();
let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits);
cpuset.__bits[idx] |= 1 << offset;
()
}
pub fn CPU_CLR(cpu: usize, cpuset: &mut cpuset_t) -> () {
- let bitset_bits = ::mem::size_of::<::c_long>();
+ let bitset_bits = 8 * ::mem::size_of::<::c_long>();
let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits);
cpuset.__bits[idx] &= !(1 << offset);
()
}
pub fn CPU_ISSET(cpu: usize, cpuset: &cpuset_t) -> bool {
- let bitset_bits = ::mem::size_of::<::c_long>();
+ let bitset_bits = 8 * ::mem::size_of::<::c_long>();
let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits);
0 != cpuset.__bits[idx] & (1 << offset)
}
@@ -3794,9 +3803,9 @@ f! {
pub fn CPU_COUNT(cpuset: &cpuset_t) -> ::c_int {
let mut s: u32 = 0;
let cpuset_size = ::mem::size_of::<cpuset_t>();
- let bitset_bits = ::mem::size_of::<::c_long>();
+ let bitset_size = ::mem::size_of::<::c_long>();
- for i in cpuset.__bits[..(cpuset_size / bitset_bits)].iter() {
+ for i in cpuset.__bits[..(cpuset_size / bitset_size)].iter() {
s += i.count_ones();
};
s as ::c_int
@@ -3839,6 +3848,8 @@ cfg_if! {
}
extern "C" {
+ #[cfg_attr(doc, doc(alias = "__errno_location"))]
+ #[cfg_attr(doc, doc(alias = "errno"))]
pub fn __error() -> *mut ::c_int;
pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int;
@@ -4272,71 +4283,39 @@ extern "C" {
#[link(name = "kvm")]
extern "C" {
- pub fn kvm_open(
- execfile: *const ::c_char,
- corefile: *const ::c_char,
- swapfile: *const ::c_char,
- flags: ::c_int,
- errstr: *const ::c_char,
- ) -> *mut kvm_t;
- pub fn kvm_close(kd: *mut kvm_t) -> ::c_int;
- pub fn kvm_dpcpu_setcpu(kd: *mut kvm_t, cpu: ::c_uint) -> ::c_int;
- pub fn kvm_getargv(kd: *mut kvm_t, p: *const kinfo_proc, nchr: ::c_int) -> *mut *mut ::c_char;
- pub fn kvm_getcptime(kd: *mut kvm_t, cp_time: *mut ::c_long) -> ::c_int;
- pub fn kvm_getenvv(kd: *mut kvm_t, p: *const kinfo_proc, nchr: ::c_int) -> *mut *mut ::c_char;
- pub fn kvm_geterr(kd: *mut kvm_t) -> *mut ::c_char;
- pub fn kvm_getloadavg(kd: *mut kvm_t, loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int;
- pub fn kvm_getmaxcpu(kd: *mut kvm_t) -> ::c_int;
- pub fn kvm_getncpus(kd: *mut kvm_t) -> ::c_int;
- pub fn kvm_getpcpu(kd: *mut kvm_t, cpu: ::c_int) -> *mut ::c_void;
- pub fn kvm_counter_u64_fetch(kd: *mut kvm_t, base: ::c_ulong) -> u64;
- pub fn kvm_getprocs(
- kd: *mut kvm_t,
- op: ::c_int,
- arg: ::c_int,
- cnt: *mut ::c_int,
- ) -> *mut kinfo_proc;
+ pub fn kvm_dpcpu_setcpu(kd: *mut ::kvm_t, cpu: ::c_uint) -> ::c_int;
+ pub fn kvm_getargv(kd: *mut ::kvm_t, p: *const kinfo_proc, nchr: ::c_int)
+ -> *mut *mut ::c_char;
+ pub fn kvm_getcptime(kd: *mut ::kvm_t, cp_time: *mut ::c_long) -> ::c_int;
+ pub fn kvm_getenvv(kd: *mut ::kvm_t, p: *const kinfo_proc, nchr: ::c_int)
+ -> *mut *mut ::c_char;
+ pub fn kvm_geterr(kd: *mut ::kvm_t) -> *mut ::c_char;
+ pub fn kvm_getmaxcpu(kd: *mut ::kvm_t) -> ::c_int;
+ pub fn kvm_getncpus(kd: *mut ::kvm_t) -> ::c_int;
+ pub fn kvm_getpcpu(kd: *mut ::kvm_t, cpu: ::c_int) -> *mut ::c_void;
+ pub fn kvm_counter_u64_fetch(kd: *mut ::kvm_t, base: ::c_ulong) -> u64;
pub fn kvm_getswapinfo(
- kd: *mut kvm_t,
+ kd: *mut ::kvm_t,
info: *mut kvm_swap,
maxswap: ::c_int,
flags: ::c_int,
) -> ::c_int;
- pub fn kvm_native(kd: *mut kvm_t) -> ::c_int;
- pub fn kvm_nlist(kd: *mut kvm_t, nl: *mut nlist) -> ::c_int;
- pub fn kvm_nlist2(kd: *mut kvm_t, nl: *mut kvm_nlist) -> ::c_int;
- pub fn kvm_openfiles(
- execfile: *const ::c_char,
- corefile: *const ::c_char,
- swapfile: *const ::c_char,
- flags: ::c_int,
- errbuf: *mut ::c_char,
- ) -> *mut kvm_t;
- pub fn kvm_read(
- kd: *mut kvm_t,
- addr: ::c_ulong,
- buf: *mut ::c_void,
- nbytes: ::size_t,
- ) -> ::ssize_t;
+ pub fn kvm_native(kd: *mut ::kvm_t) -> ::c_int;
+ pub fn kvm_nlist(kd: *mut ::kvm_t, nl: *mut nlist) -> ::c_int;
+ pub fn kvm_nlist2(kd: *mut ::kvm_t, nl: *mut kvm_nlist) -> ::c_int;
pub fn kvm_read_zpcpu(
- kd: *mut kvm_t,
+ kd: *mut ::kvm_t,
base: ::c_ulong,
buf: *mut ::c_void,
size: ::size_t,
cpu: ::c_int,
) -> ::ssize_t;
pub fn kvm_read2(
- kd: *mut kvm_t,
+ kd: *mut ::kvm_t,
addr: kvaddr_t,
buf: *mut ::c_void,
nbytes: ::size_t,
) -> ::ssize_t;
- pub fn kvm_write(
- kd: *mut kvm_t,
- addr: ::c_ulong,
- buf: *const ::c_void,
- nbytes: ::size_t,
- ) -> ::ssize_t;
}
#[link(name = "util")]
@@ -4486,10 +4465,10 @@ extern "C" {
#[link(name = "devstat")]
extern "C" {
- pub fn devstat_getnumdevs(kd: *mut kvm_t) -> ::c_int;
- pub fn devstat_getgeneration(kd: *mut kvm_t) -> ::c_long;
- pub fn devstat_getversion(kd: *mut kvm_t) -> ::c_int;
- pub fn devstat_checkversion(kd: *mut kvm_t) -> ::c_int;
+ pub fn devstat_getnumdevs(kd: *mut ::kvm_t) -> ::c_int;
+ pub fn devstat_getgeneration(kd: *mut ::kvm_t) -> ::c_long;
+ pub fn devstat_getversion(kd: *mut ::kvm_t) -> ::c_int;
+ pub fn devstat_checkversion(kd: *mut ::kvm_t) -> ::c_int;
pub fn devstat_selectdevs(
dev_select: *mut *mut device_selection,
num_selected: *mut ::c_int,
diff --git a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs
index b9d29d825..b314b6856 100644
--- a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs
+++ b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs
@@ -35,6 +35,10 @@ pub type Elf64_Xword = u64;
pub type iconv_t = *mut ::c_void;
+// It's an alias over "struct __kvm_t". However, its fields aren't supposed to be used directly,
+// making the type definition system dependent. Better not bind it exactly.
+pub type kvm_t = ::c_void;
+
cfg_if! {
if #[cfg(target_pointer_width = "64")] {
type Elf_Addr = Elf64_Addr;
@@ -1790,6 +1794,44 @@ extern "C" {
) -> ::c_int;
}
+#[link(name = "kvm")]
+extern "C" {
+ pub fn kvm_open(
+ execfile: *const ::c_char,
+ corefile: *const ::c_char,
+ swapfile: *const ::c_char,
+ flags: ::c_int,
+ errstr: *const ::c_char,
+ ) -> *mut ::kvm_t;
+ pub fn kvm_close(kd: *mut ::kvm_t) -> ::c_int;
+ pub fn kvm_getprocs(
+ kd: *mut ::kvm_t,
+ op: ::c_int,
+ arg: ::c_int,
+ cnt: *mut ::c_int,
+ ) -> *mut ::kinfo_proc;
+ pub fn kvm_getloadavg(kd: *mut kvm_t, loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int;
+ pub fn kvm_openfiles(
+ execfile: *const ::c_char,
+ corefile: *const ::c_char,
+ swapfile: *const ::c_char,
+ flags: ::c_int,
+ errbuf: *mut ::c_char,
+ ) -> *mut ::kvm_t;
+ pub fn kvm_read(
+ kd: *mut ::kvm_t,
+ addr: ::c_ulong,
+ buf: *mut ::c_void,
+ nbytes: ::size_t,
+ ) -> ::ssize_t;
+ pub fn kvm_write(
+ kd: *mut ::kvm_t,
+ addr: ::c_ulong,
+ buf: *const ::c_void,
+ nbytes: ::size_t,
+ ) -> ::ssize_t;
+}
+
cfg_if! {
if #[cfg(target_os = "freebsd")] {
mod freebsd;
diff --git a/vendor/libc/src/unix/bsd/mod.rs b/vendor/libc/src/unix/bsd/mod.rs
index 8ebca0930..20e203bde 100644
--- a/vendor/libc/src/unix/bsd/mod.rs
+++ b/vendor/libc/src/unix/bsd/mod.rs
@@ -449,6 +449,12 @@ pub const TCP_MAXSEG: ::c_int = 2;
pub const PIPE_BUF: usize = 512;
+// si_code values for SIGBUS signal
+pub const BUS_ADRALN: ::c_int = 1;
+pub const BUS_ADRERR: ::c_int = 2;
+pub const BUS_OBJERR: ::c_int = 3;
+
+// si_code values for SIGCHLD signal
pub const CLD_EXITED: ::c_int = 1;
pub const CLD_KILLED: ::c_int = 2;
pub const CLD_DUMPED: ::c_int = 3;
diff --git a/vendor/libc/src/unix/bsd/netbsdlike/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs
index d7d40bd97..a7f35ef85 100644
--- a/vendor/libc/src/unix/bsd/netbsdlike/mod.rs
+++ b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs
@@ -639,17 +639,6 @@ pub const TIOCM_DSR: ::c_int = 0o0400;
pub const TIOCM_CD: ::c_int = TIOCM_CAR;
pub const TIOCM_RI: ::c_int = TIOCM_RNG;
-// Flags for chflags(2)
-pub const UF_SETTABLE: ::c_ulong = 0x0000ffff;
-pub const UF_NODUMP: ::c_ulong = 0x00000001;
-pub const UF_IMMUTABLE: ::c_ulong = 0x00000002;
-pub const UF_APPEND: ::c_ulong = 0x00000004;
-pub const UF_OPAQUE: ::c_ulong = 0x00000008;
-pub const SF_SETTABLE: ::c_ulong = 0xffff0000;
-pub const SF_ARCHIVED: ::c_ulong = 0x00010000;
-pub const SF_IMMUTABLE: ::c_ulong = 0x00020000;
-pub const SF_APPEND: ::c_ulong = 0x00040000;
-
pub const TIMER_ABSTIME: ::c_int = 1;
#[link(name = "util")]
diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs
index 0afff1cd3..d12fd0730 100644
--- a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs
+++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs
@@ -487,6 +487,134 @@ s! {
af_arg: [[::c_char; 10]; 24],
}
+ pub struct ki_sigset_t {
+ pub __bits: [u32; 4],
+ }
+
+ pub struct kinfo_proc2 {
+ pub p_forw: u64,
+ pub p_back: u64,
+ pub p_paddr: u64,
+ pub p_addr: u64,
+ pub p_fd: u64,
+ pub p_cwdi: u64,
+ pub p_stats: u64,
+ pub p_limit: u64,
+ pub p_vmspace: u64,
+ pub p_sigacts: u64,
+ pub p_sess: u64,
+ pub p_tsess: u64,
+ pub p_ru: u64,
+ pub p_eflag: i32,
+ pub p_exitsig: i32,
+ pub p_flag: i32,
+ pub p_pid: i32,
+ pub p_ppid: i32,
+ pub p_sid: i32,
+ pub p__pgid: i32,
+ pub p_tpgid: i32,
+ pub p_uid: u32,
+ pub p_ruid: u32,
+ pub p_gid: u32,
+ pub p_rgid: u32,
+ pub p_groups: [u32; KI_NGROUPS as usize],
+ pub p_ngroups: i16,
+ pub p_jobc: i16,
+ pub p_tdev: u32,
+ pub p_estcpu: u32,
+ pub p_rtime_sec: u32,
+ pub p_rtime_usec: u32,
+ pub p_cpticks: i32,
+ pub p_pctcpu: u32,
+ pub p_swtime: u32,
+ pub p_slptime: u32,
+ pub p_schedflags: i32,
+ pub p_uticks: u64,
+ pub p_sticks: u64,
+ pub p_iticks: u64,
+ pub p_tracep: u64,
+ pub p_traceflag: i32,
+ pub p_holdcnt: i32,
+ pub p_siglist: ki_sigset_t,
+ pub p_sigmask: ki_sigset_t,
+ pub p_sigignore: ki_sigset_t,
+ pub p_sigcatch: ki_sigset_t,
+ pub p_stat: i8,
+ pub p_priority: u8,
+ pub p_usrpri: u8,
+ pub p_nice: u8,
+ pub p_xstat: u16,
+ pub p_acflag: u16,
+ pub p_comm: [::c_char; KI_MAXCOMLEN as usize],
+ pub p_wmesg: [::c_char; KI_WMESGLEN as usize],
+ pub p_wchan: u64,
+ pub p_login: [::c_char; KI_MAXLOGNAME as usize],
+ pub p_vm_rssize: i32,
+ pub p_vm_tsize: i32,
+ pub p_vm_dsize: i32,
+ pub p_vm_ssize: i32,
+ pub p_uvalid: i64,
+ pub p_ustart_sec: u32,
+ pub p_ustart_usec: u32,
+ pub p_uutime_sec: u32,
+ pub p_uutime_usec: u32,
+ pub p_ustime_sec: u32,
+ pub p_ustime_usec: u32,
+ pub p_uru_maxrss: u64,
+ pub p_uru_ixrss: u64,
+ pub p_uru_idrss: u64,
+ pub p_uru_isrss: u64,
+ pub p_uru_minflt: u64,
+ pub p_uru_majflt: u64,
+ pub p_uru_nswap: u64,
+ pub p_uru_inblock: u64,
+ pub p_uru_oublock: u64,
+ pub p_uru_msgsnd: u64,
+ pub p_uru_msgrcv: u64,
+ pub p_uru_nsignals: u64,
+ pub p_uru_nvcsw: u64,
+ pub p_uru_nivcsw: u64,
+ pub p_uctime_sec: u32,
+ pub p_uctime_usec: u32,
+ pub p_cpuid: u64,
+ pub p_realflag: u64,
+ pub p_nlwps: u64,
+ pub p_nrlwps: u64,
+ pub p_realstat: u64,
+ pub p_svuid: u32,
+ pub p_svgid: u32,
+ pub p_ename: [::c_char; KI_MAXEMULLEN as usize],
+ pub p_vm_vsize: i64,
+ pub p_vm_msize: i64,
+ }
+
+ pub struct kinfo_lwp {
+ pub l_forw: u64,
+ pub l_back: u64,
+ pub l_laddr: u64,
+ pub l_addr: u64,
+ pub l_lid: i32,
+ pub l_flag: i32,
+ pub l_swtime: u32,
+ pub l_slptime: u32,
+ pub l_schedflags: i32,
+ pub l_holdcnt: i32,
+ pub l_priority: u8,
+ pub l_usrpri: u8,
+ pub l_stat: i8,
+ l_pad1: i8,
+ l_pad2: i32,
+ pub l_wmesg: [::c_char; KI_WMESGLEN as usize],
+ pub l_wchan: u64,
+ pub l_cpuid: u64,
+ pub l_rtime_sec: u32,
+ pub l_rtime_usec: u32,
+ pub l_cpticks: u32,
+ pub l_pctcpu: u32,
+ pub l_pid: u32,
+ pub l_name: [::c_char; KI_LNAMELEN as usize],
+ }
+
pub struct kinfo_vmentry {
pub kve_start: u64,
pub kve_end: u64,
@@ -1440,10 +1568,7 @@ pub const IPPROTO_VRRP: ::c_int = 112;
/// Common Address Resolution Protocol
pub const IPPROTO_CARP: ::c_int = 112;
/// L2TPv3
-// TEMP: Disabled for now; this constant was added to NetBSD on 2017-02-16,
-// but isn't yet supported by the NetBSD rumprun kernel image used for
-// libc testing.
-//pub const IPPROTO_L2TP: ::c_int = 115;
+pub const IPPROTO_L2TP: ::c_int = 115;
/// SCTP
pub const IPPROTO_SCTP: ::c_int = 132;
/// PFSYNC
@@ -2103,9 +2228,18 @@ pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20;
pub const POSIX_SPAWN_RETURNERROR: ::c_int = 0x40;
// Flags for chflags(2)
-pub const SF_SNAPSHOT: ::c_ulong = 0x00200000;
+pub const SF_APPEND: ::c_ulong = 0x00040000;
+pub const SF_ARCHIVED: ::c_ulong = 0x00010000;
+pub const SF_IMMUTABLE: ::c_ulong = 0x00020000;
pub const SF_LOG: ::c_ulong = 0x00400000;
+pub const SF_SETTABLE: ::c_ulong = 0xffff0000;
pub const SF_SNAPINVAL: ::c_ulong = 0x00800000;
+pub const SF_SNAPSHOT: ::c_ulong = 0x00200000;
+pub const UF_APPEND: ::c_ulong = 0x00000004;
+pub const UF_IMMUTABLE: ::c_ulong = 0x00000002;
+pub const UF_NODUMP: ::c_ulong = 0x00000001;
+pub const UF_OPAQUE: ::c_ulong = 0x00000008;
+pub const UF_SETTABLE: ::c_ulong = 0x0000ffff;
// sys/sysctl.h
pub const KVME_PROT_READ: ::c_int = 0x00000001;
@@ -2121,6 +2255,22 @@ pub const KVME_FLAG_GROWS_DOWN: ::c_int = 0x000000020;
pub const NGROUPS_MAX: ::c_int = 16;
+pub const KI_NGROUPS: ::c_int = 16;
+pub const KI_MAXCOMLEN: ::c_int = 24;
+pub const KI_WMESGLEN: ::c_int = 8;
+pub const KI_MAXLOGNAME: ::c_int = 24;
+pub const KI_MAXEMULLEN: ::c_int = 16;
+pub const KI_LNAMELEN: ::c_int = 20;
+
+// sys/lwp.h
+pub const LSIDL: ::c_int = 1;
+pub const LSRUN: ::c_int = 2;
+pub const LSSLEEP: ::c_int = 3;
+pub const LSSTOP: ::c_int = 4;
+pub const LSZOMB: ::c_int = 5;
+pub const LSONPROC: ::c_int = 7;
+pub const LSSUSPENDED: ::c_int = 8;
+
const_fn! {
{const} fn _ALIGN(p: usize) -> usize {
(p + _ALIGNBYTES) & !_ALIGNBYTES
diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs
index 199473dd6..1910f24a4 100644
--- a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs
+++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs
@@ -1628,6 +1628,17 @@ pub const EPROC_SLEADER: i32 = 0x02; // session leader
pub const EPROC_UNVEIL: i32 = 0x04; // has unveil settings
pub const EPROC_LKUNVEIL: i32 = 0x08; // unveil is locked
+// Flags for chflags(2)
+pub const UF_SETTABLE: ::c_uint = 0x0000ffff;
+pub const UF_NODUMP: ::c_uint = 0x00000001;
+pub const UF_IMMUTABLE: ::c_uint = 0x00000002;
+pub const UF_APPEND: ::c_uint = 0x00000004;
+pub const UF_OPAQUE: ::c_uint = 0x00000008;
+pub const SF_SETTABLE: ::c_uint = 0xffff0000;
+pub const SF_ARCHIVED: ::c_uint = 0x00010000;
+pub const SF_IMMUTABLE: ::c_uint = 0x00020000;
+pub const SF_APPEND: ::c_uint = 0x00040000;
+
const_fn! {
{const} fn _ALIGN(p: usize) -> usize {
(p + _ALIGNBYTES) & !_ALIGNBYTES
diff --git a/vendor/libc/src/unix/haiku/mod.rs b/vendor/libc/src/unix/haiku/mod.rs
index ab1df724c..bb2e0351b 100644
--- a/vendor/libc/src/unix/haiku/mod.rs
+++ b/vendor/libc/src/unix/haiku/mod.rs
@@ -52,6 +52,9 @@ pub type Elf64_Xword = u64;
pub type ENTRY = entry;
pub type ACTION = ::c_int;
+pub type posix_spawnattr_t = *mut ::c_void;
+pub type posix_spawn_file_actions_t = *mut ::c_void;
+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub enum timezone {}
impl ::Copy for timezone {}
@@ -1051,6 +1054,7 @@ pub const LOCK_EX: ::c_int = 0x02;
pub const LOCK_NB: ::c_int = 0x04;
pub const LOCK_UN: ::c_int = 0x08;
+pub const MINSIGSTKSZ: ::size_t = 8192;
pub const SIGSTKSZ: ::size_t = 16384;
pub const IOV_MAX: ::c_int = 1024;
@@ -1067,6 +1071,9 @@ pub const SA_NOMASK: ::c_int = SA_NODEFER;
pub const SA_STACK: ::c_int = SA_ONSTACK;
pub const SA_ONESHOT: ::c_int = SA_RESETHAND;
+pub const SS_ONSTACK: ::c_int = 0x1;
+pub const SS_DISABLE: ::c_int = 0x2;
+
pub const FD_SETSIZE: usize = 1024;
pub const RTLD_LOCAL: ::c_int = 0x0;
@@ -1225,6 +1232,8 @@ pub const SO_PEERCRED: ::c_int = 0x4000000b;
pub const SCM_RIGHTS: ::c_int = 0x01;
+pub const SOMAXCONN: ::c_int = 32;
+
pub const NI_MAXHOST: ::size_t = 1025;
pub const WNOHANG: ::c_int = 0x01;
@@ -1234,6 +1243,12 @@ pub const WEXITED: ::c_int = 0x08;
pub const WSTOPPED: ::c_int = 0x10;
pub const WNOWAIT: ::c_int = 0x20;
+// si_code values for SIGBUS signal
+pub const BUS_ADRALN: ::c_int = 40;
+pub const BUS_ADRERR: ::c_int = 41;
+pub const BUS_OBJERR: ::c_int = 42;
+
+// si_code values for SIGCHLD signal
pub const CLD_EXITED: ::c_int = 60;
pub const CLD_KILLED: ::c_int = 61;
pub const CLD_DUMPED: ::c_int = 62;
@@ -1432,6 +1447,13 @@ pub const LOG_SERIAL: ::c_int = 16 << 12;
pub const LOG_PERROR: ::c_int = 32 << 12;
pub const LOG_NOWAIT: ::c_int = 64 << 12;
+// spawn.h
+pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01;
+pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02;
+pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x10;
+pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20;
+pub const POSIX_SPAWN_SETSID: ::c_int = 0x40;
+
const_fn! {
{const} fn CMSG_ALIGN(len: usize) -> usize {
len + ::mem::size_of::<usize>() - 1 & !(::mem::size_of::<usize>() - 1)
@@ -1768,8 +1790,6 @@ extern "C" {
pub fn endgrent();
pub fn getgrent() -> *mut ::group;
pub fn setgrent();
- pub fn setreuid(ruid: ::uid_t, euid: ::uid_t) -> ::c_int;
- pub fn setregid(rgid: ::gid_t, egid: ::gid_t) -> ::c_int;
pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int;
pub fn pthread_atfork(
prepare: ::Option<unsafe extern "C" fn()>,
@@ -1884,6 +1904,74 @@ extern "C" {
pub fn brk(addr: *mut ::c_void) -> ::c_int;
pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void;
+
+ pub fn posix_spawn(
+ pid: *mut ::pid_t,
+ path: *const ::c_char,
+ file_actions: *const ::posix_spawn_file_actions_t,
+ attrp: *const ::posix_spawnattr_t,
+ argv: *const *mut ::c_char,
+ envp: *const *mut ::c_char,
+ ) -> ::c_int;
+ pub fn posix_spawnp(
+ pid: *mut ::pid_t,
+ file: *const ::c_char,
+ file_actions: *const ::posix_spawn_file_actions_t,
+ attrp: *const ::posix_spawnattr_t,
+ argv: *const *mut ::c_char,
+ envp: *const *mut ::c_char,
+ ) -> ::c_int;
+
+ pub fn posix_spawn_file_actions_init(file_actions: *mut posix_spawn_file_actions_t) -> ::c_int;
+ pub fn posix_spawn_file_actions_destroy(
+ file_actions: *mut posix_spawn_file_actions_t,
+ ) -> ::c_int;
+ pub fn posix_spawn_file_actions_addopen(
+ file_actions: *mut posix_spawn_file_actions_t,
+ fildes: ::c_int,
+ path: *const ::c_char,
+ oflag: ::c_int,
+ mode: ::mode_t,
+ ) -> ::c_int;
+ pub fn posix_spawn_file_actions_addclose(
+ file_actions: *mut posix_spawn_file_actions_t,
+ fildes: ::c_int,
+ ) -> ::c_int;
+ pub fn posix_spawn_file_actions_adddup2(
+ file_actions: *mut posix_spawn_file_actions_t,
+ fildes: ::c_int,
+ newfildes: ::c_int,
+ ) -> ::c_int;
+
+ pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int;
+ pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int;
+ pub fn posix_spawnattr_getflags(
+ attr: *const posix_spawnattr_t,
+ _flags: *mut ::c_short,
+ ) -> ::c_int;
+ pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int;
+ pub fn posix_spawnattr_getpgroup(
+ attr: *const posix_spawnattr_t,
+ _pgroup: *mut ::pid_t,
+ ) -> ::c_int;
+ pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, pgroup: ::pid_t) -> ::c_int;
+ pub fn posix_spawnattr_getsigdefault(
+ attr: *const posix_spawnattr_t,
+ sigdefault: *mut ::sigset_t,
+ ) -> ::c_int;
+ pub fn posix_spawnattr_setsigdefault(
+ attr: *mut posix_spawnattr_t,
+ sigdefault: *const ::sigset_t,
+ ) -> ::c_int;
+ pub fn posix_spawnattr_getsigmask(
+ attr: *const posix_spawnattr_t,
+ _sigmask: *mut ::sigset_t,
+ ) -> ::c_int;
+ pub fn posix_spawnattr_setsigmask(
+ attr: *mut posix_spawnattr_t,
+ sigmask: *const ::sigset_t,
+ ) -> ::c_int;
+
}
#[link(name = "bsd")]
diff --git a/vendor/libc/src/unix/linux_like/android/b64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/mod.rs
index 0995c5412..67d0dacf1 100644
--- a/vendor/libc/src/unix/linux_like/android/b64/mod.rs
+++ b/vendor/libc/src/unix/linux_like/android/b64/mod.rs
@@ -346,6 +346,9 @@ cfg_if! {
} else if #[cfg(target_arch = "aarch64")] {
mod aarch64;
pub use self::aarch64::*;
+ } else if #[cfg(target_arch = "riscv64")] {
+ mod riscv64;
+ pub use self::riscv64::*;
} else {
// Unknown target_arch
}
diff --git a/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs b/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs
new file mode 100644
index 000000000..8e949963a
--- /dev/null
+++ b/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs
@@ -0,0 +1,7 @@
+s_no_extra_traits! {
+ #[allow(missing_debug_implementations)]
+ #[repr(align(16))]
+ pub struct max_align_t {
+ priv_: [f32; 8]
+ }
+}
diff --git a/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs
new file mode 100644
index 000000000..2421792cf
--- /dev/null
+++ b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs
@@ -0,0 +1,342 @@
+pub type c_char = i8;
+pub type wchar_t = u32;
+pub type greg_t = i64;
+pub type __u64 = ::c_ulonglong;
+
+s! {
+ pub struct stat {
+ pub st_dev: ::dev_t,
+ pub st_ino: ::ino_t,
+ pub st_mode: ::c_uint,
+ pub st_nlink: ::c_uint,
+ pub st_uid: ::uid_t,
+ pub st_gid: ::gid_t,
+ pub st_rdev: ::dev_t,
+ __pad1: ::c_ulong,
+ pub st_size: ::off64_t,
+ pub st_blksize: ::c_int,
+ __pad2: ::c_int,
+ pub st_blocks: ::c_long,
+ pub st_atime: ::time_t,
+ pub st_atime_nsec: ::c_long,
+ pub st_mtime: ::time_t,
+ pub st_mtime_nsec: ::c_long,
+ pub st_ctime: ::time_t,
+ pub st_ctime_nsec: ::c_long,
+ __unused4: ::c_uint,
+ __unused5: ::c_uint,
+ }
+
+ pub struct stat64 {
+ pub st_dev: ::dev_t,
+ pub st_ino: ::ino_t,
+ pub st_mode: ::c_uint,
+ pub st_nlink: ::c_uint,
+ pub st_uid: ::uid_t,
+ pub st_gid: ::gid_t,
+ pub st_rdev: ::dev_t,
+ __pad1: ::c_ulong,
+ pub st_size: ::off64_t,
+ pub st_blksize: ::c_int,
+ __pad2: ::c_int,
+ pub st_blocks: ::c_long,
+ pub st_atime: ::time_t,
+ pub st_atime_nsec: ::c_long,
+ pub st_mtime: ::time_t,
+ pub st_mtime_nsec: ::c_long,
+ pub st_ctime: ::time_t,
+ pub st_ctime_nsec: ::c_long,
+ __unused4: ::c_uint,
+ __unused5: ::c_uint,
+ }
+}
+
+pub const O_DIRECT: ::c_int = 0x40000;
+pub const O_DIRECTORY: ::c_int = 0x200000;
+pub const O_NOFOLLOW: ::c_int = 0x400000;
+pub const O_LARGEFILE: ::c_int = 0x100000;
+
+pub const SIGSTKSZ: ::size_t = 8192;
+pub const MINSIGSTKSZ: ::size_t = 2048;
+
+// From NDK's asm/hwcap.h
+pub const COMPAT_HWCAP_ISA_I: ::c_ulong = 1 << ('I' - 'A');
+pub const COMPAT_HWCAP_ISA_M: ::c_ulong = 1 << ('M' - 'A');
+pub const COMPAT_HWCAP_ISA_A: ::c_ulong = 1 << ('A' - 'A');
+pub const COMPAT_HWCAP_ISA_F: ::c_ulong = 1 << ('F' - 'A');
+pub const COMPAT_HWCAP_ISA_D: ::c_ulong = 1 << ('D' - 'A');
+pub const COMPAT_HWCAP_ISA_C: ::c_ulong = 1 << ('C' - 'A');
+
+pub const SYS_io_setup: ::c_long = 0;
+pub const SYS_io_destroy: ::c_long = 1;
+pub const SYS_io_submit: ::c_long = 2;
+pub const SYS_io_cancel: ::c_long = 3;
+pub const SYS_io_getevents: ::c_long = 4;
+pub const SYS_setxattr: ::c_long = 5;
+pub const SYS_lsetxattr: ::c_long = 6;
+pub const SYS_fsetxattr: ::c_long = 7;
+pub const SYS_getxattr: ::c_long = 8;
+pub const SYS_lgetxattr: ::c_long = 9;
+pub const SYS_fgetxattr: ::c_long = 10;
+pub const SYS_listxattr: ::c_long = 11;
+pub const SYS_llistxattr: ::c_long = 12;
+pub const SYS_flistxattr: ::c_long = 13;
+pub const SYS_removexattr: ::c_long = 14;
+pub const SYS_lremovexattr: ::c_long = 15;
+pub const SYS_fremovexattr: ::c_long = 16;
+pub const SYS_getcwd: ::c_long = 17;
+pub const SYS_lookup_dcookie: ::c_long = 18;
+pub const SYS_eventfd2: ::c_long = 19;
+pub const SYS_epoll_create1: ::c_long = 20;
+pub const SYS_epoll_ctl: ::c_long = 21;
+pub const SYS_epoll_pwait: ::c_long = 22;
+pub const SYS_dup: ::c_long = 23;
+pub const SYS_dup3: ::c_long = 24;
+pub const SYS_inotify_init1: ::c_long = 26;
+pub const SYS_inotify_add_watch: ::c_long = 27;
+pub const SYS_inotify_rm_watch: ::c_long = 28;
+pub const SYS_ioctl: ::c_long = 29;
+pub const SYS_ioprio_set: ::c_long = 30;
+pub const SYS_ioprio_get: ::c_long = 31;
+pub const SYS_flock: ::c_long = 32;
+pub const SYS_mknodat: ::c_long = 33;
+pub const SYS_mkdirat: ::c_long = 34;
+pub const SYS_unlinkat: ::c_long = 35;
+pub const SYS_symlinkat: ::c_long = 36;
+pub const SYS_linkat: ::c_long = 37;
+pub const SYS_renameat: ::c_long = 38;
+pub const SYS_umount2: ::c_long = 39;
+pub const SYS_mount: ::c_long = 40;
+pub const SYS_pivot_root: ::c_long = 41;
+pub const SYS_nfsservctl: ::c_long = 42;
+pub const SYS_fallocate: ::c_long = 47;
+pub const SYS_faccessat: ::c_long = 48;
+pub const SYS_chdir: ::c_long = 49;
+pub const SYS_fchdir: ::c_long = 50;
+pub const SYS_chroot: ::c_long = 51;
+pub const SYS_fchmod: ::c_long = 52;
+pub const SYS_fchmodat: ::c_long = 53;
+pub const SYS_fchownat: ::c_long = 54;
+pub const SYS_fchown: ::c_long = 55;
+pub const SYS_openat: ::c_long = 56;
+pub const SYS_close: ::c_long = 57;
+pub const SYS_vhangup: ::c_long = 58;
+pub const SYS_pipe2: ::c_long = 59;
+pub const SYS_quotactl: ::c_long = 60;
+pub const SYS_getdents64: ::c_long = 61;
+pub const SYS_read: ::c_long = 63;
+pub const SYS_write: ::c_long = 64;
+pub const SYS_readv: ::c_long = 65;
+pub const SYS_writev: ::c_long = 66;
+pub const SYS_pread64: ::c_long = 67;
+pub const SYS_pwrite64: ::c_long = 68;
+pub const SYS_preadv: ::c_long = 69;
+pub const SYS_pwritev: ::c_long = 70;
+pub const SYS_pselect6: ::c_long = 72;
+pub const SYS_ppoll: ::c_long = 73;
+pub const SYS_signalfd4: ::c_long = 74;
+pub const SYS_vmsplice: ::c_long = 75;
+pub const SYS_splice: ::c_long = 76;
+pub const SYS_tee: ::c_long = 77;
+pub const SYS_readlinkat: ::c_long = 78;
+pub const SYS_sync: ::c_long = 81;
+pub const SYS_fsync: ::c_long = 82;
+pub const SYS_fdatasync: ::c_long = 83;
+pub const SYS_sync_file_range: ::c_long = 84;
+pub const SYS_timerfd_create: ::c_long = 85;
+pub const SYS_timerfd_settime: ::c_long = 86;
+pub const SYS_timerfd_gettime: ::c_long = 87;
+pub const SYS_utimensat: ::c_long = 88;
+pub const SYS_acct: ::c_long = 89;
+pub const SYS_capget: ::c_long = 90;
+pub const SYS_capset: ::c_long = 91;
+pub const SYS_personality: ::c_long = 92;
+pub const SYS_exit: ::c_long = 93;
+pub const SYS_exit_group: ::c_long = 94;
+pub const SYS_waitid: ::c_long = 95;
+pub const SYS_set_tid_address: ::c_long = 96;
+pub const SYS_unshare: ::c_long = 97;
+pub const SYS_futex: ::c_long = 98;
+pub const SYS_set_robust_list: ::c_long = 99;
+pub const SYS_get_robust_list: ::c_long = 100;
+pub const SYS_nanosleep: ::c_long = 101;
+pub const SYS_getitimer: ::c_long = 102;
+pub const SYS_setitimer: ::c_long = 103;
+pub const SYS_kexec_load: ::c_long = 104;
+pub const SYS_init_module: ::c_long = 105;
+pub const SYS_delete_module: ::c_long = 106;
+pub const SYS_timer_create: ::c_long = 107;
+pub const SYS_timer_gettime: ::c_long = 108;
+pub const SYS_timer_getoverrun: ::c_long = 109;
+pub const SYS_timer_settime: ::c_long = 110;
+pub const SYS_timer_delete: ::c_long = 111;
+pub const SYS_clock_settime: ::c_long = 112;
+pub const SYS_clock_gettime: ::c_long = 113;
+pub const SYS_clock_getres: ::c_long = 114;
+pub const SYS_clock_nanosleep: ::c_long = 115;
+pub const SYS_syslog: ::c_long = 116;
+pub const SYS_ptrace: ::c_long = 117;
+pub const SYS_sched_setparam: ::c_long = 118;
+pub const SYS_sched_setscheduler: ::c_long = 119;
+pub const SYS_sched_getscheduler: ::c_long = 120;
+pub const SYS_sched_getparam: ::c_long = 121;
+pub const SYS_sched_setaffinity: ::c_long = 122;
+pub const SYS_sched_getaffinity: ::c_long = 123;
+pub const SYS_sched_yield: ::c_long = 124;
+pub const SYS_sched_get_priority_max: ::c_long = 125;
+pub const SYS_sched_get_priority_min: ::c_long = 126;
+pub const SYS_sched_rr_get_interval: ::c_long = 127;
+pub const SYS_restart_syscall: ::c_long = 128;
+pub const SYS_kill: ::c_long = 129;
+pub const SYS_tkill: ::c_long = 130;
+pub const SYS_tgkill: ::c_long = 131;
+pub const SYS_sigaltstack: ::c_long = 132;
+pub const SYS_rt_sigsuspend: ::c_long = 133;
+pub const SYS_rt_sigaction: ::c_long = 134;
+pub const SYS_rt_sigprocmask: ::c_long = 135;
+pub const SYS_rt_sigpending: ::c_long = 136;
+pub const SYS_rt_sigtimedwait: ::c_long = 137;
+pub const SYS_rt_sigqueueinfo: ::c_long = 138;
+pub const SYS_rt_sigreturn: ::c_long = 139;
+pub const SYS_setpriority: ::c_long = 140;
+pub const SYS_getpriority: ::c_long = 141;
+pub const SYS_reboot: ::c_long = 142;
+pub const SYS_setregid: ::c_long = 143;
+pub const SYS_setgid: ::c_long = 144;
+pub const SYS_setreuid: ::c_long = 145;
+pub const SYS_setuid: ::c_long = 146;
+pub const SYS_setresuid: ::c_long = 147;
+pub const SYS_getresuid: ::c_long = 148;
+pub const SYS_setresgid: ::c_long = 149;
+pub const SYS_getresgid: ::c_long = 150;
+pub const SYS_setfsuid: ::c_long = 151;
+pub const SYS_setfsgid: ::c_long = 152;
+pub const SYS_times: ::c_long = 153;
+pub const SYS_setpgid: ::c_long = 154;
+pub const SYS_getpgid: ::c_long = 155;
+pub const SYS_getsid: ::c_long = 156;
+pub const SYS_setsid: ::c_long = 157;
+pub const SYS_getgroups: ::c_long = 158;
+pub const SYS_setgroups: ::c_long = 159;
+pub const SYS_uname: ::c_long = 160;
+pub const SYS_sethostname: ::c_long = 161;
+pub const SYS_setdomainname: ::c_long = 162;
+pub const SYS_getrlimit: ::c_long = 163;
+pub const SYS_setrlimit: ::c_long = 164;
+pub const SYS_getrusage: ::c_long = 165;
+pub const SYS_umask: ::c_long = 166;
+pub const SYS_prctl: ::c_long = 167;
+pub const SYS_getcpu: ::c_long = 168;
+pub const SYS_gettimeofday: ::c_long = 169;
+pub const SYS_settimeofday: ::c_long = 170;
+pub const SYS_adjtimex: ::c_long = 171;
+pub const SYS_getpid: ::c_long = 172;
+pub const SYS_getppid: ::c_long = 173;
+pub const SYS_getuid: ::c_long = 174;
+pub const SYS_geteuid: ::c_long = 175;
+pub const SYS_getgid: ::c_long = 176;
+pub const SYS_getegid: ::c_long = 177;
+pub const SYS_gettid: ::c_long = 178;
+pub const SYS_sysinfo: ::c_long = 179;
+pub const SYS_mq_open: ::c_long = 180;
+pub const SYS_mq_unlink: ::c_long = 181;
+pub const SYS_mq_timedsend: ::c_long = 182;
+pub const SYS_mq_timedreceive: ::c_long = 183;
+pub const SYS_mq_notify: ::c_long = 184;
+pub const SYS_mq_getsetattr: ::c_long = 185;
+pub const SYS_msgget: ::c_long = 186;
+pub const SYS_msgctl: ::c_long = 187;
+pub const SYS_msgrcv: ::c_long = 188;
+pub const SYS_msgsnd: ::c_long = 189;
+pub const SYS_semget: ::c_long = 190;
+pub const SYS_semctl: ::c_long = 191;
+pub const SYS_semtimedop: ::c_long = 192;
+pub const SYS_semop: ::c_long = 193;
+pub const SYS_shmget: ::c_long = 194;
+pub const SYS_shmctl: ::c_long = 195;
+pub const SYS_shmat: ::c_long = 196;
+pub const SYS_shmdt: ::c_long = 197;
+pub const SYS_socket: ::c_long = 198;
+pub const SYS_socketpair: ::c_long = 199;
+pub const SYS_bind: ::c_long = 200;
+pub const SYS_listen: ::c_long = 201;
+pub const SYS_accept: ::c_long = 202;
+pub const SYS_connect: ::c_long = 203;
+pub const SYS_getsockname: ::c_long = 204;
+pub const SYS_getpeername: ::c_long = 205;
+pub const SYS_sendto: ::c_long = 206;
+pub const SYS_recvfrom: ::c_long = 207;
+pub const SYS_setsockopt: ::c_long = 208;
+pub const SYS_getsockopt: ::c_long = 209;
+pub const SYS_shutdown: ::c_long = 210;
+pub const SYS_sendmsg: ::c_long = 211;
+pub const SYS_recvmsg: ::c_long = 212;
+pub const SYS_readahead: ::c_long = 213;
+pub const SYS_brk: ::c_long = 214;
+pub const SYS_munmap: ::c_long = 215;
+pub const SYS_mremap: ::c_long = 216;
+pub const SYS_add_key: ::c_long = 217;
+pub const SYS_request_key: ::c_long = 218;
+pub const SYS_keyctl: ::c_long = 219;
+pub const SYS_clone: ::c_long = 220;
+pub const SYS_execve: ::c_long = 221;
+pub const SYS_swapon: ::c_long = 224;
+pub const SYS_swapoff: ::c_long = 225;
+pub const SYS_mprotect: ::c_long = 226;
+pub const SYS_msync: ::c_long = 227;
+pub const SYS_mlock: ::c_long = 228;
+pub const SYS_munlock: ::c_long = 229;
+pub const SYS_mlockall: ::c_long = 230;
+pub const SYS_munlockall: ::c_long = 231;
+pub const SYS_mincore: ::c_long = 232;
+pub const SYS_madvise: ::c_long = 233;
+pub const SYS_remap_file_pages: ::c_long = 234;
+pub const SYS_mbind: ::c_long = 235;
+pub const SYS_get_mempolicy: ::c_long = 236;
+pub const SYS_set_mempolicy: ::c_long = 237;
+pub const SYS_migrate_pages: ::c_long = 238;
+pub const SYS_move_pages: ::c_long = 239;
+pub const SYS_rt_tgsigqueueinfo: ::c_long = 240;
+pub const SYS_perf_event_open: ::c_long = 241;
+pub const SYS_accept4: ::c_long = 242;
+pub const SYS_recvmmsg: ::c_long = 243;
+pub const SYS_arch_specific_syscall: ::c_long = 244;
+pub const SYS_wait4: ::c_long = 260;
+pub const SYS_prlimit64: ::c_long = 261;
+pub const SYS_fanotify_init: ::c_long = 262;
+pub const SYS_fanotify_mark: ::c_long = 263;
+pub const SYS_name_to_handle_at: ::c_long = 264;
+pub const SYS_open_by_handle_at: ::c_long = 265;
+pub const SYS_clock_adjtime: ::c_long = 266;
+pub const SYS_syncfs: ::c_long = 267;
+pub const SYS_setns: ::c_long = 268;
+pub const SYS_sendmmsg: ::c_long = 269;
+pub const SYS_process_vm_readv: ::c_long = 270;
+pub const SYS_process_vm_writev: ::c_long = 271;
+pub const SYS_kcmp: ::c_long = 272;
+pub const SYS_finit_module: ::c_long = 273;
+pub const SYS_sched_setattr: ::c_long = 274;
+pub const SYS_sched_getattr: ::c_long = 275;
+pub const SYS_renameat2: ::c_long = 276;
+pub const SYS_seccomp: ::c_long = 277;
+pub const SYS_getrandom: ::c_long = 278;
+pub const SYS_memfd_create: ::c_long = 279;
+pub const SYS_bpf: ::c_long = 280;
+pub const SYS_execveat: ::c_long = 281;
+pub const SYS_userfaultfd: ::c_long = 282;
+pub const SYS_membarrier: ::c_long = 283;
+pub const SYS_mlock2: ::c_long = 284;
+pub const SYS_copy_file_range: ::c_long = 285;
+pub const SYS_preadv2: ::c_long = 286;
+pub const SYS_pwritev2: ::c_long = 287;
+pub const SYS_pkey_mprotect: ::c_long = 288;
+pub const SYS_pkey_alloc: ::c_long = 289;
+pub const SYS_pkey_free: ::c_long = 290;
+pub const SYS_syscalls: ::c_long = 436;
+
+cfg_if! {
+ if #[cfg(libc_align)] {
+ mod align;
+ pub use self::align::*;
+ }
+}
diff --git a/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs
index df1161820..d25b50775 100644
--- a/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs
+++ b/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs
@@ -350,6 +350,7 @@ cfg_if! {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("user_fpregs_struct")
.field("cwd", &self.cwd)
+ .field("swd", &self.swd)
.field("ftw", &self.ftw)
.field("fop", &self.fop)
.field("rip", &self.rip)
@@ -366,6 +367,7 @@ cfg_if! {
impl ::hash::Hash for user_fpregs_struct {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.cwd.hash(state);
+ self.swd.hash(state);
self.ftw.hash(state);
self.fop.hash(state);
self.rip.hash(state);
diff --git a/vendor/libc/src/unix/linux_like/android/mod.rs b/vendor/libc/src/unix/linux_like/android/mod.rs
index a57e9b7e7..cfd229a47 100644
--- a/vendor/libc/src/unix/linux_like/android/mod.rs
+++ b/vendor/libc/src/unix/linux_like/android/mod.rs
@@ -2489,6 +2489,8 @@ pub const AF_VSOCK: ::c_int = 40;
pub const PF_NFC: ::c_int = AF_NFC;
pub const PF_VSOCK: ::c_int = AF_VSOCK;
+pub const SOMAXCONN: ::c_int = 128;
+
// sys/system_properties.h
pub const PROP_VALUE_MAX: ::c_int = 92;
pub const PROP_NAME_MAX: ::c_int = 32;
@@ -2496,6 +2498,216 @@ pub const PROP_NAME_MAX: ::c_int = 32;
// sys/prctl.h
pub const PR_SET_VMA: ::c_int = 0x53564d41;
pub const PR_SET_VMA_ANON_NAME: ::c_int = 0;
+pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38;
+pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39;
+pub const PR_GET_SECCOMP: ::c_int = 21;
+pub const PR_SET_SECCOMP: ::c_int = 22;
+pub const PR_GET_TIMING: ::c_int = 13;
+pub const PR_SET_TIMING: ::c_int = 14;
+pub const PR_TIMING_STATISTICAL: ::c_int = 0;
+pub const PR_TIMING_TIMESTAMP: ::c_int = 1;
+
+// linux/if_addr.h
+pub const IFA_UNSPEC: ::c_ushort = 0;
+pub const IFA_ADDRESS: ::c_ushort = 1;
+pub const IFA_LOCAL: ::c_ushort = 2;
+pub const IFA_LABEL: ::c_ushort = 3;
+pub const IFA_BROADCAST: ::c_ushort = 4;
+pub const IFA_ANYCAST: ::c_ushort = 5;
+pub const IFA_CACHEINFO: ::c_ushort = 6;
+pub const IFA_MULTICAST: ::c_ushort = 7;
+
+pub const IFA_F_SECONDARY: u32 = 0x01;
+pub const IFA_F_TEMPORARY: u32 = 0x01;
+pub const IFA_F_NODAD: u32 = 0x02;
+pub const IFA_F_OPTIMISTIC: u32 = 0x04;
+pub const IFA_F_DADFAILED: u32 = 0x08;
+pub const IFA_F_HOMEADDRESS: u32 = 0x10;
+pub const IFA_F_DEPRECATED: u32 = 0x20;
+pub const IFA_F_TENTATIVE: u32 = 0x40;
+pub const IFA_F_PERMANENT: u32 = 0x80;
+
+// linux/if_link.h
+pub const IFLA_UNSPEC: ::c_ushort = 0;
+pub const IFLA_ADDRESS: ::c_ushort = 1;
+pub const IFLA_BROADCAST: ::c_ushort = 2;
+pub const IFLA_IFNAME: ::c_ushort = 3;
+pub const IFLA_MTU: ::c_ushort = 4;
+pub const IFLA_LINK: ::c_ushort = 5;
+pub const IFLA_QDISC: ::c_ushort = 6;
+pub const IFLA_STATS: ::c_ushort = 7;
+pub const IFLA_COST: ::c_ushort = 8;
+pub const IFLA_PRIORITY: ::c_ushort = 9;
+pub const IFLA_MASTER: ::c_ushort = 10;
+pub const IFLA_WIRELESS: ::c_ushort = 11;
+pub const IFLA_PROTINFO: ::c_ushort = 12;
+pub const IFLA_TXQLEN: ::c_ushort = 13;
+pub const IFLA_MAP: ::c_ushort = 14;
+pub const IFLA_WEIGHT: ::c_ushort = 15;
+pub const IFLA_OPERSTATE: ::c_ushort = 16;
+pub const IFLA_LINKMODE: ::c_ushort = 17;
+pub const IFLA_LINKINFO: ::c_ushort = 18;
+pub const IFLA_NET_NS_PID: ::c_ushort = 19;
+pub const IFLA_IFALIAS: ::c_ushort = 20;
+pub const IFLA_NUM_VF: ::c_ushort = 21;
+pub const IFLA_VFINFO_LIST: ::c_ushort = 22;
+pub const IFLA_STATS64: ::c_ushort = 23;
+pub const IFLA_VF_PORTS: ::c_ushort = 24;
+pub const IFLA_PORT_SELF: ::c_ushort = 25;
+pub const IFLA_AF_SPEC: ::c_ushort = 26;
+pub const IFLA_GROUP: ::c_ushort = 27;
+pub const IFLA_NET_NS_FD: ::c_ushort = 28;
+pub const IFLA_EXT_MASK: ::c_ushort = 29;
+pub const IFLA_PROMISCUITY: ::c_ushort = 30;
+pub const IFLA_NUM_TX_QUEUES: ::c_ushort = 31;
+pub const IFLA_NUM_RX_QUEUES: ::c_ushort = 32;
+pub const IFLA_CARRIER: ::c_ushort = 33;
+pub const IFLA_PHYS_PORT_ID: ::c_ushort = 34;
+pub const IFLA_CARRIER_CHANGES: ::c_ushort = 35;
+pub const IFLA_PHYS_SWITCH_ID: ::c_ushort = 36;
+pub const IFLA_LINK_NETNSID: ::c_ushort = 37;
+pub const IFLA_PHYS_PORT_NAME: ::c_ushort = 38;
+pub const IFLA_PROTO_DOWN: ::c_ushort = 39;
+pub const IFLA_GSO_MAX_SEGS: ::c_ushort = 40;
+pub const IFLA_GSO_MAX_SIZE: ::c_ushort = 41;
+pub const IFLA_PAD: ::c_ushort = 42;
+pub const IFLA_XDP: ::c_ushort = 43;
+pub const IFLA_EVENT: ::c_ushort = 44;
+pub const IFLA_NEW_NETNSID: ::c_ushort = 45;
+pub const IFLA_IF_NETNSID: ::c_ushort = 46;
+pub const IFLA_TARGET_NETNSID: ::c_ushort = IFLA_IF_NETNSID;
+pub const IFLA_CARRIER_UP_COUNT: ::c_ushort = 47;
+pub const IFLA_CARRIER_DOWN_COUNT: ::c_ushort = 48;
+pub const IFLA_NEW_IFINDEX: ::c_ushort = 49;
+pub const IFLA_MIN_MTU: ::c_ushort = 50;
+pub const IFLA_MAX_MTU: ::c_ushort = 51;
+
+pub const IFLA_INFO_UNSPEC: ::c_ushort = 0;
+pub const IFLA_INFO_KIND: ::c_ushort = 1;
+pub const IFLA_INFO_DATA: ::c_ushort = 2;
+pub const IFLA_INFO_XSTATS: ::c_ushort = 3;
+pub const IFLA_INFO_SLAVE_KIND: ::c_ushort = 4;
+pub const IFLA_INFO_SLAVE_DATA: ::c_ushort = 5;
+
+// linux/rtnetlink.h
+pub const TCA_UNSPEC: ::c_ushort = 0;
+pub const TCA_KIND: ::c_ushort = 1;
+pub const TCA_OPTIONS: ::c_ushort = 2;
+pub const TCA_STATS: ::c_ushort = 3;
+pub const TCA_XSTATS: ::c_ushort = 4;
+pub const TCA_RATE: ::c_ushort = 5;
+pub const TCA_FCNT: ::c_ushort = 6;
+pub const TCA_STATS2: ::c_ushort = 7;
+pub const TCA_STAB: ::c_ushort = 8;
+
+pub const RTM_NEWLINK: u16 = 16;
+pub const RTM_DELLINK: u16 = 17;
+pub const RTM_GETLINK: u16 = 18;
+pub const RTM_SETLINK: u16 = 19;
+pub const RTM_NEWADDR: u16 = 20;
+pub const RTM_DELADDR: u16 = 21;
+pub const RTM_GETADDR: u16 = 22;
+pub const RTM_NEWROUTE: u16 = 24;
+pub const RTM_DELROUTE: u16 = 25;
+pub const RTM_GETROUTE: u16 = 26;
+pub const RTM_NEWNEIGH: u16 = 28;
+pub const RTM_DELNEIGH: u16 = 29;
+pub const RTM_GETNEIGH: u16 = 30;
+pub const RTM_NEWRULE: u16 = 32;
+pub const RTM_DELRULE: u16 = 33;
+pub const RTM_GETRULE: u16 = 34;
+pub const RTM_NEWQDISC: u16 = 36;
+pub const RTM_DELQDISC: u16 = 37;
+pub const RTM_GETQDISC: u16 = 38;
+pub const RTM_NEWTCLASS: u16 = 40;
+pub const RTM_DELTCLASS: u16 = 41;
+pub const RTM_GETTCLASS: u16 = 42;
+pub const RTM_NEWTFILTER: u16 = 44;
+pub const RTM_DELTFILTER: u16 = 45;
+pub const RTM_GETTFILTER: u16 = 46;
+pub const RTM_NEWACTION: u16 = 48;
+pub const RTM_DELACTION: u16 = 49;
+pub const RTM_GETACTION: u16 = 50;
+pub const RTM_NEWPREFIX: u16 = 52;
+pub const RTM_GETMULTICAST: u16 = 58;
+pub const RTM_GETANYCAST: u16 = 62;
+pub const RTM_NEWNEIGHTBL: u16 = 64;
+pub const RTM_GETNEIGHTBL: u16 = 66;
+pub const RTM_SETNEIGHTBL: u16 = 67;
+pub const RTM_NEWNDUSEROPT: u16 = 68;
+pub const RTM_NEWADDRLABEL: u16 = 72;
+pub const RTM_DELADDRLABEL: u16 = 73;
+pub const RTM_GETADDRLABEL: u16 = 74;
+pub const RTM_GETDCB: u16 = 78;
+pub const RTM_SETDCB: u16 = 79;
+pub const RTM_NEWNETCONF: u16 = 80;
+pub const RTM_GETNETCONF: u16 = 82;
+pub const RTM_NEWMDB: u16 = 84;
+pub const RTM_DELMDB: u16 = 85;
+pub const RTM_GETMDB: u16 = 86;
+pub const RTM_NEWNSID: u16 = 88;
+pub const RTM_DELNSID: u16 = 89;
+pub const RTM_GETNSID: u16 = 90;
+
+pub const RTM_F_NOTIFY: ::c_uint = 0x100;
+pub const RTM_F_CLONED: ::c_uint = 0x200;
+pub const RTM_F_EQUALIZE: ::c_uint = 0x400;
+pub const RTM_F_PREFIX: ::c_uint = 0x800;
+
+pub const RTA_UNSPEC: ::c_ushort = 0;
+pub const RTA_DST: ::c_ushort = 1;
+pub const RTA_SRC: ::c_ushort = 2;
+pub const RTA_IIF: ::c_ushort = 3;
+pub const RTA_OIF: ::c_ushort = 4;
+pub const RTA_GATEWAY: ::c_ushort = 5;
+pub const RTA_PRIORITY: ::c_ushort = 6;
+pub const RTA_PREFSRC: ::c_ushort = 7;
+pub const RTA_METRICS: ::c_ushort = 8;
+pub const RTA_MULTIPATH: ::c_ushort = 9;
+pub const RTA_PROTOINFO: ::c_ushort = 10; // No longer used
+pub const RTA_FLOW: ::c_ushort = 11;
+pub const RTA_CACHEINFO: ::c_ushort = 12;
+pub const RTA_SESSION: ::c_ushort = 13; // No longer used
+pub const RTA_MP_ALGO: ::c_ushort = 14; // No longer used
+pub const RTA_TABLE: ::c_ushort = 15;
+pub const RTA_MARK: ::c_ushort = 16;
+pub const RTA_MFC_STATS: ::c_ushort = 17;
+
+pub const RTN_UNSPEC: ::c_uchar = 0;
+pub const RTN_UNICAST: ::c_uchar = 1;
+pub const RTN_LOCAL: ::c_uchar = 2;
+pub const RTN_BROADCAST: ::c_uchar = 3;
+pub const RTN_ANYCAST: ::c_uchar = 4;
+pub const RTN_MULTICAST: ::c_uchar = 5;
+pub const RTN_BLACKHOLE: ::c_uchar = 6;
+pub const RTN_UNREACHABLE: ::c_uchar = 7;
+pub const RTN_PROHIBIT: ::c_uchar = 8;
+pub const RTN_THROW: ::c_uchar = 9;
+pub const RTN_NAT: ::c_uchar = 10;
+pub const RTN_XRESOLVE: ::c_uchar = 11;
+
+pub const RTPROT_UNSPEC: ::c_uchar = 0;
+pub const RTPROT_REDIRECT: ::c_uchar = 1;
+pub const RTPROT_KERNEL: ::c_uchar = 2;
+pub const RTPROT_BOOT: ::c_uchar = 3;
+pub const RTPROT_STATIC: ::c_uchar = 4;
+
+pub const RT_SCOPE_UNIVERSE: ::c_uchar = 0;
+pub const RT_SCOPE_SITE: ::c_uchar = 200;
+pub const RT_SCOPE_LINK: ::c_uchar = 253;
+pub const RT_SCOPE_HOST: ::c_uchar = 254;
+pub const RT_SCOPE_NOWHERE: ::c_uchar = 255;
+
+pub const RT_TABLE_UNSPEC: ::c_uchar = 0;
+pub const RT_TABLE_COMPAT: ::c_uchar = 252;
+pub const RT_TABLE_DEFAULT: ::c_uchar = 253;
+pub const RT_TABLE_MAIN: ::c_uchar = 254;
+pub const RT_TABLE_LOCAL: ::c_uchar = 255;
+
+pub const RTMSG_NEWDEVICE: u32 = 0x11;
+pub const RTMSG_DELDEVICE: u32 = 0x12;
+pub const RTMSG_NEWROUTE: u32 = 0x21;
+pub const RTMSG_DELROUTE: u32 = 0x22;
f! {
pub fn CMSG_NXTHDR(mhdr: *const msghdr,
diff --git a/vendor/libc/src/unix/linux_like/emscripten/mod.rs b/vendor/libc/src/unix/linux_like/emscripten/mod.rs
index 5494aad37..31d0ebf25 100644
--- a/vendor/libc/src/unix/linux_like/emscripten/mod.rs
+++ b/vendor/libc/src/unix/linux_like/emscripten/mod.rs
@@ -1669,6 +1669,8 @@ pub const PRIO_PROCESS: ::c_int = 0;
pub const PRIO_PGRP: ::c_int = 1;
pub const PRIO_USER: ::c_int = 2;
+pub const SOMAXCONN: ::c_int = 128;
+
f! {
pub fn CMSG_NXTHDR(mhdr: *const msghdr,
cmsg: *const cmsghdr) -> *mut cmsghdr {
diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs
index 154c2c54c..cb2df378c 100644
--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs
+++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs
@@ -26,4 +26,26 @@ s! {
// auto-derive traits like Debug
__reserved: [[u64; 32]; 16],
}
+
+ #[repr(align(16))]
+ pub struct user_fpsimd_struct {
+ pub vregs: [[u64; 2]; 32],
+ pub fpsr: ::c_uint,
+ pub fpcr: ::c_uint,
+ }
+
+ #[repr(align(8))]
+ pub struct clone_args {
+ pub flags: ::c_ulonglong,
+ pub pidfd: ::c_ulonglong,
+ pub child_tid: ::c_ulonglong,
+ pub parent_tid: ::c_ulonglong,
+ pub exit_signal: ::c_ulonglong,
+ pub stack: ::c_ulonglong,
+ pub stack_size: ::c_ulonglong,
+ pub tls: ::c_ulonglong,
+ pub set_tid: ::c_ulonglong,
+ pub set_tid_size: ::c_ulonglong,
+ pub cgroup: ::c_ulonglong,
+ }
}
diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs
index 513f6acd1..60a1b6932 100644
--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs
+++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs
@@ -573,6 +573,22 @@ pub const HWCAP_PACG: ::c_ulong = 1 << 31;
//pub const HWCAP2_SVESM4: ::c_ulong = 1 << 6;
//pub const HWCAP2_FLAGM2: ::c_ulong = 1 << 7;
//pub const HWCAP2_FRINT: ::c_ulong = 1 << 8;
+//pub const HWCAP2_MTE: ::c_ulong = 1 << 18;
+
+// linux/prctl.h
+pub const PR_PAC_RESET_KEYS: ::c_int = 54;
+pub const PR_SET_TAGGED_ADDR_CTRL: ::c_int = 55;
+pub const PR_GET_TAGGED_ADDR_CTRL: ::c_int = 56;
+pub const PR_PAC_SET_ENABLED_KEYS: ::c_int = 60;
+pub const PR_PAC_GET_ENABLED_KEYS: ::c_int = 61;
+
+pub const PR_TAGGED_ADDR_ENABLE: ::c_ulong = 1;
+
+pub const PR_PAC_APIAKEY: ::c_ulong = 1 << 0;
+pub const PR_PAC_APIBKEY: ::c_ulong = 1 << 1;
+pub const PR_PAC_APDAKEY: ::c_ulong = 1 << 2;
+pub const PR_PAC_APDBKEY: ::c_ulong = 1 << 3;
+pub const PR_PAC_APGAKEY: ::c_ulong = 1 << 4;
// Syscall table
pub const SYS_io_setup: ::c_long = 0;
diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs
index 7ca870fd0..ba3075edd 100644
--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs
+++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs
@@ -5,3 +5,20 @@ s_no_extra_traits! {
priv_: [f64; 4]
}
}
+
+s! {
+ #[repr(align(8))]
+ pub struct clone_args {
+ pub flags: ::c_ulonglong,
+ pub pidfd: ::c_ulonglong,
+ pub child_tid: ::c_ulonglong,
+ pub parent_tid: ::c_ulonglong,
+ pub exit_signal: ::c_ulonglong,
+ pub stack: ::c_ulonglong,
+ pub stack_size: ::c_ulonglong,
+ pub tls: ::c_ulonglong,
+ pub set_tid: ::c_ulonglong,
+ pub set_tid_size: ::c_ulonglong,
+ pub cgroup: ::c_ulonglong,
+ }
+}
diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs
index 61242268e..7e876f2d8 100644
--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs
+++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs
@@ -626,6 +626,19 @@ pub const PTRACE_PEEKSIGINFO_SHARED: ::c_uint = 1;
pub const PTRACE_SYSEMU: ::c_uint = 31;
pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32;
+pub const PR_GET_SPECULATION_CTRL: ::c_int = 52;
+pub const PR_SET_SPECULATION_CTRL: ::c_int = 53;
+pub const PR_SPEC_NOT_AFFECTED: ::c_uint = 0;
+pub const PR_SPEC_PRCTL: ::c_uint = 1 << 0;
+pub const PR_SPEC_ENABLE: ::c_uint = 1 << 1;
+pub const PR_SPEC_DISABLE: ::c_uint = 1 << 2;
+pub const PR_SPEC_FORCE_DISABLE: ::c_uint = 1 << 3;
+pub const PR_SPEC_DISABLE_NOEXEC: ::c_uint = 1 << 4;
+pub const PR_SPEC_STORE_BYPASS: ::c_int = 0;
+pub const PR_SPEC_INDIRECT_BRANCH: ::c_int = 1;
+// FIXME: perharps for later
+//pub const PR_SPEC_L1D_FLUSH: ::c_int = 2;
+
pub const MCL_CURRENT: ::c_int = 0x0001;
pub const MCL_FUTURE: ::c_int = 0x0002;
diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs
index 8a5f9d169..88bc935f6 100644
--- a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs
+++ b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs
@@ -1025,6 +1025,8 @@ pub const STATX_ATTR_NODUMP: ::c_int = 0x0040;
pub const STATX_ATTR_ENCRYPTED: ::c_int = 0x0800;
pub const STATX_ATTR_AUTOMOUNT: ::c_int = 0x1000;
+pub const SOMAXCONN: ::c_int = 4096;
+
//sys/timex.h
pub const ADJ_OFFSET: ::c_uint = 0x0001;
pub const ADJ_FREQUENCY: ::c_uint = 0x0002;
@@ -1289,6 +1291,7 @@ extern "C" {
attr: *mut ::pthread_rwlockattr_t,
val: ::c_int,
) -> ::c_int;
+ pub fn pthread_sigqueue(thread: ::pthread_t, sig: ::c_int, value: ::sigval) -> ::c_int;
pub fn mallinfo() -> ::mallinfo;
pub fn mallinfo2() -> ::mallinfo2;
pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int;
@@ -1324,6 +1327,11 @@ extern "C" {
pub fn malloc_trim(__pad: ::size_t) -> ::c_int;
}
+extern "C" {
+ pub fn gnu_get_libc_release() -> *const ::c_char;
+ pub fn gnu_get_libc_version() -> *const ::c_char;
+}
+
cfg_if! {
if #[cfg(any(target_arch = "x86",
target_arch = "arm",
diff --git a/vendor/libc/src/unix/linux_like/linux/mod.rs b/vendor/libc/src/unix/linux_like/linux/mod.rs
index 2086f705a..aba691e5a 100644
--- a/vendor/libc/src/unix/linux_like/linux/mod.rs
+++ b/vendor/libc/src/unix/linux_like/linux/mod.rs
@@ -1565,6 +1565,7 @@ pub const MSG_INFO: ::c_int = 12;
pub const MSG_NOERROR: ::c_int = 0o10000;
pub const MSG_EXCEPT: ::c_int = 0o20000;
+pub const MSG_ZEROCOPY: ::c_int = 0x4000000;
pub const SHM_R: ::c_int = 0o400;
pub const SHM_W: ::c_int = 0o200;
@@ -1810,6 +1811,7 @@ pub const ITIMER_PROF: ::c_int = 2;
pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC;
pub const TFD_NONBLOCK: ::c_int = O_NONBLOCK;
pub const TFD_TIMER_ABSTIME: ::c_int = 1;
+pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 2;
pub const _POSIX_VDISABLE: ::cc_t = 0;
@@ -1841,6 +1843,17 @@ pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000;
pub const IPV6_RTHDR_LOOSE: ::c_int = 0;
pub const IPV6_RTHDR_STRICT: ::c_int = 1;
+// SO_MEMINFO offsets
+pub const SK_MEMINFO_RMEM_ALLOC: ::c_int = 0;
+pub const SK_MEMINFO_RCVBUF: ::c_int = 1;
+pub const SK_MEMINFO_WMEM_ALLOC: ::c_int = 2;
+pub const SK_MEMINFO_SNDBUF: ::c_int = 3;
+pub const SK_MEMINFO_FWD_ALLOC: ::c_int = 4;
+pub const SK_MEMINFO_WMEM_QUEUED: ::c_int = 5;
+pub const SK_MEMINFO_OPTMEM: ::c_int = 6;
+pub const SK_MEMINFO_BACKLOG: ::c_int = 7;
+pub const SK_MEMINFO_DROPS: ::c_int = 8;
+
pub const IUTF8: ::tcflag_t = 0x00004000;
#[cfg(not(all(target_env = "uclibc", target_arch = "mips")))]
pub const CMSPAR: ::tcflag_t = 0o10000000000;
@@ -3061,6 +3074,7 @@ pub const FUTEX_WAIT_BITSET: ::c_int = 9;
pub const FUTEX_WAKE_BITSET: ::c_int = 10;
pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11;
pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12;
+pub const FUTEX_LOCK_PI2: ::c_int = 13;
pub const FUTEX_PRIVATE_FLAG: ::c_int = 128;
pub const FUTEX_CLOCK_REALTIME: ::c_int = 256;
diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs
index 81c55c64a..a4bf9bff4 100644
--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs
+++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs
@@ -24,4 +24,19 @@ s! {
pub pstate: ::c_ulong,
__reserved: [[u64; 32]; 16],
}
+
+ #[repr(align(8))]
+ pub struct clone_args {
+ pub flags: ::c_ulonglong,
+ pub pidfd: ::c_ulonglong,
+ pub child_tid: ::c_ulonglong,
+ pub parent_tid: ::c_ulonglong,
+ pub exit_signal: ::c_ulonglong,
+ pub stack: ::c_ulonglong,
+ pub stack_size: ::c_ulonglong,
+ pub tls: ::c_ulonglong,
+ pub set_tid: ::c_ulonglong,
+ pub set_tid_size: ::c_ulonglong,
+ pub cgroup: ::c_ulonglong,
+ }
}
diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs
index cb9bb930d..1ed13f66b 100644
--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs
+++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs
@@ -458,7 +458,7 @@ pub const O_SYNC: ::c_int = 0x4010;
pub const O_RSYNC: ::c_int = 0x4010;
pub const O_DSYNC: ::c_int = 0x10;
pub const O_ASYNC: ::c_int = 0x1000;
-pub const O_LARGEFILE: ::c_int = 0;
+pub const O_LARGEFILE: ::c_int = 0x2000;
pub const EDEADLK: ::c_int = 45;
pub const ENAMETOOLONG: ::c_int = 78;
diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs
index 5fdd03d2c..cb6237abc 100644
--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs
+++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs
@@ -221,6 +221,7 @@ pub const ENOPROTOOPT: ::c_int = 92;
pub const EPROTONOSUPPORT: ::c_int = 93;
pub const ESOCKTNOSUPPORT: ::c_int = 94;
pub const EOPNOTSUPP: ::c_int = 95;
+pub const ENOTSUP: ::c_int = EOPNOTSUPP;
pub const EPFNOSUPPORT: ::c_int = 96;
pub const EAFNOSUPPORT: ::c_int = 97;
pub const ENETDOWN: ::c_int = 100;
diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs
index 7ca870fd0..94391a01a 100644
--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs
+++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs
@@ -4,4 +4,22 @@ s_no_extra_traits! {
pub struct max_align_t {
priv_: [f64; 4]
}
+
+}
+
+s! {
+ #[repr(align(8))]
+ pub struct clone_args {
+ pub flags: ::c_ulonglong,
+ pub pidfd: ::c_ulonglong,
+ pub child_tid: ::c_ulonglong,
+ pub parent_tid: ::c_ulonglong,
+ pub exit_signal: ::c_ulonglong,
+ pub stack: ::c_ulonglong,
+ pub stack_size: ::c_ulonglong,
+ pub tls: ::c_ulonglong,
+ pub set_tid: ::c_ulonglong,
+ pub set_tid_size: ::c_ulonglong,
+ pub cgroup: ::c_ulonglong,
+ }
}
diff --git a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs
index 707107345..6cdc31388 100644
--- a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs
+++ b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs
@@ -529,6 +529,8 @@ pub const MAP_ANONYMOUS: ::c_int = MAP_ANON;
pub const SOCK_DCCP: ::c_int = 6;
pub const SOCK_PACKET: ::c_int = 10;
+pub const SOMAXCONN: ::c_int = 128;
+
#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")]
pub const SIGUNUSED: ::c_int = ::SIGSYS;
diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs
index fc80f0f9d..4a01e0cd8 100644
--- a/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs
+++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs
@@ -235,6 +235,8 @@ pub const PRIO_PROCESS: ::c_int = 0;
pub const PRIO_PGRP: ::c_int = 1;
pub const PRIO_USER: ::c_int = 2;
+pub const SOMAXCONN: ::c_int = 128;
+
pub const ST_RELATIME: ::c_ulong = 4096;
pub const AF_NFC: ::c_int = PF_NFC;
diff --git a/vendor/libc/src/unix/linux_like/mod.rs b/vendor/libc/src/unix/linux_like/mod.rs
index 125c5d4e4..57600f24b 100644
--- a/vendor/libc/src/unix/linux_like/mod.rs
+++ b/vendor/libc/src/unix/linux_like/mod.rs
@@ -759,8 +759,6 @@ pub const PF_IEEE802154: ::c_int = AF_IEEE802154;
pub const PF_CAIF: ::c_int = AF_CAIF;
pub const PF_ALG: ::c_int = AF_ALG;
-pub const SOMAXCONN: ::c_int = 128;
-
pub const MSG_OOB: ::c_int = 1;
pub const MSG_PEEK: ::c_int = 2;
pub const MSG_DONTROUTE: ::c_int = 4;
@@ -1213,6 +1211,15 @@ pub const PIPE_BUF: usize = 4096;
pub const SI_LOAD_SHIFT: ::c_uint = 16;
+// si_code values for SIGBUS signal
+pub const BUS_ADRALN: ::c_int = 1;
+pub const BUS_ADRERR: ::c_int = 2;
+pub const BUS_OBJERR: ::c_int = 3;
+// Linux-specific si_code values for SIGBUS signal
+pub const BUS_MCEERR_AR: ::c_int = 4;
+pub const BUS_MCEERR_AO: ::c_int = 5;
+
+// si_code values for SIGCHLD signal
pub const CLD_EXITED: ::c_int = 1;
pub const CLD_KILLED: ::c_int = 2;
pub const CLD_DUMPED: ::c_int = 3;
@@ -1726,8 +1733,6 @@ extern "C" {
pub fn clearenv() -> ::c_int;
pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int)
-> ::c_int;
- pub fn setreuid(ruid: ::uid_t, euid: ::uid_t) -> ::c_int;
- pub fn setregid(rgid: ::gid_t, egid: ::gid_t) -> ::c_int;
pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int;
pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int;
pub fn acct(filename: *const ::c_char) -> ::c_int;
diff --git a/vendor/libc/src/unix/mod.rs b/vendor/libc/src/unix/mod.rs
index ecee44411..ecc693e3d 100644
--- a/vendor/libc/src/unix/mod.rs
+++ b/vendor/libc/src/unix/mod.rs
@@ -346,13 +346,13 @@ cfg_if! {
} else if #[cfg(target_os = "emscripten")] {
#[link(name = "c")]
extern {}
- } else if #[cfg(all(target_os = "netbsd",
- feature = "rustc-dep-of-std",
- target_vendor = "rumprun"))] {
- // Since we don't use -nodefaultlibs on Rumprun, libc is always pulled
- // in automatically by the linker. We avoid passing it explicitly, as it
- // causes some versions of binutils to crash with an assertion failure.
- #[link(name = "m")]
+ } else if #[cfg(all(target_os = "android", feature = "rustc-dep-of-std"))] {
+ #[link(name = "c", kind = "static", modifiers = "-bundle",
+ cfg(target_feature = "crt-static"))]
+ #[link(name = "m", kind = "static", modifiers = "-bundle",
+ cfg(target_feature = "crt-static"))]
+ #[link(name = "m", cfg(not(target_feature = "crt-static")))]
+ #[link(name = "c", cfg(not(target_feature = "crt-static")))]
extern {}
} else if #[cfg(any(target_os = "macos",
target_os = "ios",
@@ -901,6 +901,8 @@ extern "C" {
pub fn setpgid(pid: pid_t, pgid: pid_t) -> ::c_int;
pub fn setsid() -> pid_t;
pub fn setuid(uid: uid_t) -> ::c_int;
+ pub fn setreuid(ruid: uid_t, euid: uid_t) -> ::c_int;
+ pub fn setregid(rgid: gid_t, egid: gid_t) -> ::c_int;
#[cfg_attr(
all(target_os = "macos", target_arch = "x86"),
link_name = "sleep$UNIX2003"
diff --git a/vendor/libc/src/unix/newlib/espidf/mod.rs b/vendor/libc/src/unix/newlib/espidf/mod.rs
index 38c99c6b3..804cd6645 100644
--- a/vendor/libc/src/unix/newlib/espidf/mod.rs
+++ b/vendor/libc/src/unix/newlib/espidf/mod.rs
@@ -83,6 +83,9 @@ pub const MSG_DONTROUTE: ::c_int = 0x4;
pub const MSG_WAITALL: ::c_int = 0x02;
pub const MSG_MORE: ::c_int = 0x10;
pub const MSG_NOSIGNAL: ::c_int = 0x20;
+pub const MSG_TRUNC: ::c_int = 0x04;
+pub const MSG_CTRUNC: ::c_int = 0x08;
+pub const MSG_EOR: ::c_int = 0x08;
pub const PTHREAD_STACK_MIN: ::size_t = 768;
@@ -100,6 +103,8 @@ extern "C" {
pub fn sendmsg(s: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t;
#[link_name = "lwip_recvmsg"]
pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t;
+
+ pub fn eventfd(initval: ::c_uint, flags: ::c_int) -> ::c_int;
}
pub use crate::unix::newlib::generic::{sigset_t, stat};
diff --git a/vendor/libc/src/unix/solarish/mod.rs b/vendor/libc/src/unix/solarish/mod.rs
index 3ccdb8cab..fef08d08f 100644
--- a/vendor/libc/src/unix/solarish/mod.rs
+++ b/vendor/libc/src/unix/solarish/mod.rs
@@ -1796,6 +1796,8 @@ pub const TCP_LINGER2: ::c_int = 0x1c;
pub const UDP_NAT_T_ENDPOINT: ::c_int = 0x0103;
+pub const SOMAXCONN: ::c_int = 128;
+
pub const SOL_SOCKET: ::c_int = 0xffff;
pub const SO_DEBUG: ::c_int = 0x01;
pub const SO_ACCEPTCONN: ::c_int = 0x0002;
diff --git a/vendor/libc/src/windows/mod.rs b/vendor/libc/src/windows/mod.rs
index 08cba4edd..acb0de989 100644
--- a/vendor/libc/src/windows/mod.rs
+++ b/vendor/libc/src/windows/mod.rs
@@ -277,6 +277,16 @@ impl ::Clone for fpos_t {
}
}
+// Special handling for all print and scan type functions because of https://github.com/rust-lang/libc/issues/2860
+#[cfg_attr(
+ all(windows, target_env = "msvc"),
+ link(name = "legacy_stdio_definitions")
+)]
+extern "C" {
+ pub fn printf(format: *const c_char, ...) -> ::c_int;
+ pub fn fprintf(stream: *mut FILE, format: *const c_char, ...) -> ::c_int;
+}
+
extern "C" {
pub fn isalnum(c: c_int) -> c_int;
pub fn isalpha(c: c_int) -> c_int;
@@ -319,8 +329,6 @@ extern "C" {
pub fn feof(stream: *mut FILE) -> c_int;
pub fn ferror(stream: *mut FILE) -> c_int;
pub fn perror(s: *const c_char);
- pub fn printf(format: *const c_char, ...) -> ::c_int;
- pub fn fprintf(stream: *mut FILE, format: *const c_char, ...) -> ::c_int;
pub fn atoi(s: *const c_char) -> c_int;
pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double;
pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float;
diff --git a/vendor/lsp-types/.cargo-checksum.json b/vendor/lsp-types/.cargo-checksum.json
index d33701a46..23aeed03e 100644
--- a/vendor/lsp-types/.cargo-checksum.json
+++ b/vendor/lsp-types/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"3d00836d81d20d4f701954274ae16ebed2de2b51d3ca7f05b822c2fe292de927","Cargo.toml":"cac46ecf9c36442fc444fbbd84e8314f2370504a90e8f69a0ed0dc2e080ac129","LICENSE":"a11232911aa0d746688b560af367728021184084eeb6328a1922d60925c5eda0","README.md":"641e5aa434ddaca69fcfca228e2e6d01d6cfa88424ba3a6457ed44649c03f2bc","release.sh":"3bfea9a6cd08e825f3247a868338f3844d7f72f4342671898a6326a5df3c4e42","release.toml":"d4f0fecf904b64d9fc9babd3afeff77d3c102d8555b43ef83902c143e3becf16","src/call_hierarchy.rs":"a64967af04133a9c08838db19d2de665d2062ed294f6ca7d1d97edb49dc4096f","src/code_action.rs":"78813e0095a78e89a74d897e8dcb5876e1e1480c5e9e37d6f2fb22fdaecb6045","src/code_lens.rs":"169cc96d4ee9690d0e2e119aee7949006f0123c4a6b919bf7ac484258c93fa95","src/color.rs":"72846c6cda18691f5f9eaa29cb8df87bb4a10ae4e0803916244b250c68dc7701","src/completion.rs":"96681827c185732730e6b352e6259430a0585f92e34ff446b43b8d36e366a6db","src/document_highlight.rs":"491aad4beeb72ecc986d9f4cb43202d440304df3be861c41ab4e892b129212b5","src/document_link.rs":"8aab0d78081aa624290c712bacd30215553e7f0f99b300d3fefd103179fdfad0","src/document_symbols.rs":"063c29bf761c17f6f55c6812da0aad4a6aa04c6db3efbb6ca01b646b7757aabe","src/error_codes.rs":"60d4a1d00e797fe3f3f2c5ffd11be7fbaad82f4fc247ff98285566d6b777f0f7","src/file_operations.rs":"bfc413d4bbfd311c7a178863961e6cde6e8cc7a654370b3848ffd64941fea82a","src/folding_range.rs":"3dc85496b6f5b8c11f3a57f888c2febdac71c997010b13eec34736b29fb86965","src/formatting.rs":"548df3c2da1dec8a3a578b381249b6812f92e73c22257459653980492b21a2a2","src/hover.rs":"fece13f93144dfea0b3c3204f19fc7fc366b25a614515825a20a2596c88966c8","src/inlay_hint.rs":"26671f81e045b3dcca6af3222fd3d8095f061e46b8ff7fc738b6f481a0b631d4","src/lib.rs":"833a1c91386b4d989bf5279a5c129c0bfe464e96a86adbee181b89bad1ae79eb","src/linked_editing.rs":"a840ee445fbcfe32e37191197fb37b19732260462a73cc4ba350b8d9a2c4e607","src/lsif.rs":"c3966583d9b0afc64e93d301c8e20f84ba875ffb6b5d4bbacf4ca4a12cc58e99","src/moniker.rs":"8d8c37daca1d2504c74c17e7195969efcfb42641392026a8e507490adf49d043","src/notification.rs":"67e831168d9e7898965d83a503a33ac10f36561bcdb07195f99769f8ff00340c","src/progress.rs":"2b2189b094fbe7b790a0895f96c29615b9375538760d413413c47ce882af2007","src/references.rs":"e824f6861f67c66af04f8f08afc174793a9662a0a67cc23ccd5240ac0d408212","src/rename.rs":"2980e9452a27868a972fc09d52ac7c000361be9f1efc2de4e20c9b99100010c8","src/request.rs":"3abac2c2390c82bf89180b1305984db2986c5bc716ae9f5dbbd0af0a783ab0f7","src/selection_range.rs":"238b14ba6ac2e45ec66fea32d8ebe5f1d235bde9bc69777a794e10d519bcac9c","src/semantic_tokens.rs":"933cb74c048269227fd7d5eda68432ad9a3b21e2dda2fc79cc6b8e46029a064f","src/signature_help.rs":"02d6c70a6c803badd22a8a474233d1be0b169eb39a6ae668f744dcaee71045ab","src/trace.rs":"81ca45bf188452d074cb879060a88f6d6ec087d6e31e29c37db542fdb5363f5c","src/window.rs":"b380ed57b4a700514ec043310253f3fc57c51d35df18fff8283b685ee8aa17d2","src/workspace_folders.rs":"79b75c1d75a1d57892d515efd8a5cbf7c8fddce1b49dc7dfbd94e685b30fce27","src/workspace_symbols.rs":"a1f18eecc09c352b342c5cc011805457eb836432d5b8688dd2e447ac9bda407a","tests/lsif.rs":"89c7c7fa06a8b108f7519a9860d0e2a049ac66d35db3630697f2f33038513898","tests/tsc-unix.lsif":"5a85759de361285d806c8147cfc9f9cb5235a6a2253bacd8243174713419facd"},"package":"70c74e2173b2b31f8655d33724b4b45ac13f439386f66290f539c22b144c2212"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"055f657808a4e9314db7f8c2a3976b2e67a015068d6780066614a1e1d6d96ec3","Cargo.toml":"f9c039bc12cb20091895edd166293512d911c6d80b82bf75acd7adf3f398a5b7","LICENSE":"a11232911aa0d746688b560af367728021184084eeb6328a1922d60925c5eda0","README.md":"6814882daa9018d1d99ebdb7861d9759b3c96f976683fabfc8f4b9c9a05b032a","release.sh":"3bfea9a6cd08e825f3247a868338f3844d7f72f4342671898a6326a5df3c4e42","release.toml":"d4f0fecf904b64d9fc9babd3afeff77d3c102d8555b43ef83902c143e3becf16","src/call_hierarchy.rs":"a64967af04133a9c08838db19d2de665d2062ed294f6ca7d1d97edb49dc4096f","src/code_action.rs":"78813e0095a78e89a74d897e8dcb5876e1e1480c5e9e37d6f2fb22fdaecb6045","src/code_lens.rs":"169cc96d4ee9690d0e2e119aee7949006f0123c4a6b919bf7ac484258c93fa95","src/color.rs":"72846c6cda18691f5f9eaa29cb8df87bb4a10ae4e0803916244b250c68dc7701","src/completion.rs":"96681827c185732730e6b352e6259430a0585f92e34ff446b43b8d36e366a6db","src/document_highlight.rs":"491aad4beeb72ecc986d9f4cb43202d440304df3be861c41ab4e892b129212b5","src/document_link.rs":"8aab0d78081aa624290c712bacd30215553e7f0f99b300d3fefd103179fdfad0","src/document_symbols.rs":"063c29bf761c17f6f55c6812da0aad4a6aa04c6db3efbb6ca01b646b7757aabe","src/error_codes.rs":"60d4a1d00e797fe3f3f2c5ffd11be7fbaad82f4fc247ff98285566d6b777f0f7","src/file_operations.rs":"bfc413d4bbfd311c7a178863961e6cde6e8cc7a654370b3848ffd64941fea82a","src/folding_range.rs":"3dc85496b6f5b8c11f3a57f888c2febdac71c997010b13eec34736b29fb86965","src/formatting.rs":"548df3c2da1dec8a3a578b381249b6812f92e73c22257459653980492b21a2a2","src/hover.rs":"fece13f93144dfea0b3c3204f19fc7fc366b25a614515825a20a2596c88966c8","src/inlay_hint.rs":"26671f81e045b3dcca6af3222fd3d8095f061e46b8ff7fc738b6f481a0b631d4","src/lib.rs":"3f261ef4e59b0fce07a9e37b1edbec4c0cfddb600afd2c6323ef833c565004cc","src/linked_editing.rs":"a840ee445fbcfe32e37191197fb37b19732260462a73cc4ba350b8d9a2c4e607","src/lsif.rs":"c3966583d9b0afc64e93d301c8e20f84ba875ffb6b5d4bbacf4ca4a12cc58e99","src/moniker.rs":"8d8c37daca1d2504c74c17e7195969efcfb42641392026a8e507490adf49d043","src/notification.rs":"67e831168d9e7898965d83a503a33ac10f36561bcdb07195f99769f8ff00340c","src/progress.rs":"2b2189b094fbe7b790a0895f96c29615b9375538760d413413c47ce882af2007","src/references.rs":"e824f6861f67c66af04f8f08afc174793a9662a0a67cc23ccd5240ac0d408212","src/rename.rs":"2980e9452a27868a972fc09d52ac7c000361be9f1efc2de4e20c9b99100010c8","src/request.rs":"3abac2c2390c82bf89180b1305984db2986c5bc716ae9f5dbbd0af0a783ab0f7","src/selection_range.rs":"238b14ba6ac2e45ec66fea32d8ebe5f1d235bde9bc69777a794e10d519bcac9c","src/semantic_tokens.rs":"e6af4475567efb67df53b756bb9b0c5d469f83ea0eba863209e4c151f8c60704","src/signature_help.rs":"02d6c70a6c803badd22a8a474233d1be0b169eb39a6ae668f744dcaee71045ab","src/trace.rs":"81ca45bf188452d074cb879060a88f6d6ec087d6e31e29c37db542fdb5363f5c","src/window.rs":"b380ed57b4a700514ec043310253f3fc57c51d35df18fff8283b685ee8aa17d2","src/workspace_folders.rs":"79b75c1d75a1d57892d515efd8a5cbf7c8fddce1b49dc7dfbd94e685b30fce27","src/workspace_symbols.rs":"a1f18eecc09c352b342c5cc011805457eb836432d5b8688dd2e447ac9bda407a","tests/lsif.rs":"89c7c7fa06a8b108f7519a9860d0e2a049ac66d35db3630697f2f33038513898","tests/tsc-unix.lsif":"5a85759de361285d806c8147cfc9f9cb5235a6a2253bacd8243174713419facd"},"package":"a3bcfee315dde785ba887edb540b08765fd7df75a7d948844be6bf5712246734"} \ No newline at end of file
diff --git a/vendor/lsp-types/CHANGELOG.md b/vendor/lsp-types/CHANGELOG.md
index 8c8ed7842..1b888b1ee 100644
--- a/vendor/lsp-types/CHANGELOG.md
+++ b/vendor/lsp-types/CHANGELOG.md
@@ -1,3 +1,9 @@
+<a name="v0.93.1"></a>
+### v0.93.1 (2022-08-23)
+
+
+
+
<a name="v0.93.0"></a>
## v0.93.0 (2022-04-08)
diff --git a/vendor/lsp-types/Cargo.toml b/vendor/lsp-types/Cargo.toml
index 886afcab7..16feaa691 100644
--- a/vendor/lsp-types/Cargo.toml
+++ b/vendor/lsp-types/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "lsp-types"
-version = "0.93.0"
+version = "0.93.1"
authors = [
"Markus Westerlind <marwes91@gmail.com>",
"Bruno Medeiros <bruno.do.medeiros@gmail.com>",
@@ -29,6 +29,7 @@ keywords = [
]
license = "MIT"
repository = "https://github.com/gluon-lang/lsp-types"
+resolver = "1"
[dependencies.bitflags]
version = "1.0.1"
diff --git a/vendor/lsp-types/README.md b/vendor/lsp-types/README.md
index d59e8e11a..d46701166 100644
--- a/vendor/lsp-types/README.md
+++ b/vendor/lsp-types/README.md
@@ -11,4 +11,4 @@ Proposed 3.17 features can be activated using the `proposed` feature flag.
[Stable Protocol reference](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md)
-[Proposed Protocol reference](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-17.md) \ No newline at end of file
+[Proposed Protocol reference](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/lsp/3.17/specification.md)
diff --git a/vendor/lsp-types/src/lib.rs b/vendor/lsp-types/src/lib.rs
index 503264d19..6a4f544d2 100644
--- a/vendor/lsp-types/src/lib.rs
+++ b/vendor/lsp-types/src/lib.rs
@@ -985,7 +985,7 @@ pub type DocumentSelector = Vec<DocumentFilter>;
// ========================= Actual Protocol =========================
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct InitializeParams {
/// The process Id of the parent process that started
@@ -1099,6 +1099,7 @@ pub struct GotoCapability {
pub dynamic_registration: Option<bool>,
/// The client supports additional metadata in the form of definition links.
+ #[serde(skip_serializing_if = "Option::is_none")]
pub link_support: Option<bool>,
}
@@ -1781,7 +1782,7 @@ pub struct ServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub type_definition_provider: Option<TypeDefinitionProviderCapability>,
- /// the server provides goto implementation support.
+ /// The server provides goto implementation support.
#[serde(skip_serializing_if = "Option::is_none")]
pub implementation_provider: Option<ImplementationProviderCapability>,
diff --git a/vendor/lsp-types/src/semantic_tokens.rs b/vendor/lsp-types/src/semantic_tokens.rs
index 70e593190..f1b6d53d2 100644
--- a/vendor/lsp-types/src/semantic_tokens.rs
+++ b/vendor/lsp-types/src/semantic_tokens.rs
@@ -10,8 +10,7 @@ use crate::{
/// A set of predefined token types. This set is not fixed
/// and clients can specify additional token types via the
/// corresponding client capabilities.
-///
-/// @since 3.16.0
+/// since @3.16.0
#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]
pub struct SemanticTokenType(Cow<'static, str>);
@@ -39,6 +38,10 @@ impl SemanticTokenType {
pub const REGEXP: SemanticTokenType = SemanticTokenType::new("regexp");
pub const OPERATOR: SemanticTokenType = SemanticTokenType::new("operator");
+ /// since @3.17.0
+ #[cfg(feature = "proposed")]
+ pub const DECORATOR: SemanticTokenType = SemanticTokenType::new("decorator");
+
pub const fn new(tag: &'static str) -> Self {
SemanticTokenType(Cow::Borrowed(tag))
}
@@ -365,6 +368,31 @@ pub struct SemanticTokensClientCapabilities {
/// Whether the client supports tokens that can span multiple lines.
#[serde(skip_serializing_if = "Option::is_none")]
pub multiline_token_support: Option<bool>,
+
+ /// Whether the client allows the server to actively cancel a
+ /// semantic token request, e.g. supports returning
+ /// ErrorCodes.ServerCancelled. If a server does the client
+ /// needs to retrigger the request.
+ ///
+ /// since @3.17.0
+ #[cfg(feature = "proposed")]
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub server_cancel_support: Option<bool>,
+
+
+ /// Whether the client uses semantic tokens to augment existing
+ /// syntax tokens. If set to `true` client side created syntax
+ /// tokens and semantic tokens are both used for colorization. If
+ /// set to `false` the client only uses the returned semantic tokens
+ /// for colorization.
+ ///
+ /// If the value is `undefined` then the client behavior is not
+ /// specified.
+ ///
+ /// @since 3.17.0
+ #[cfg(feature = "proposed")]
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub augments_syntax_tokens: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
diff --git a/vendor/memmap2/.cargo-checksum.json b/vendor/memmap2/.cargo-checksum.json
index 4cb59ff03..c189c8a9c 100644
--- a/vendor/memmap2/.cargo-checksum.json
+++ b/vendor/memmap2/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"9a280d0719b9d9a1fb12d31a2da544d103cb15f01ee2cf40bdcf28c6484eb1b8","Cargo.lock":"47b6feef3907ecbd586b49aadff92eaf84695d7508214210978fbf58b4f00ab6","Cargo.toml":"b93bec2a5377b79002ab53089a9ea9c0a8107f25c1dfb796ba0c01a50e7a1dec","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"0d25d03b5ab49576178ad0cae7a2648d12c17ad0452fe49c07e55e4b59aa5257","README.md":"c7b3cd928f0d1a10faa255e2f84a2a06636e55ea3e7edd4f6334dd9215151205","examples/cat.rs":"ab0b575d19662e2d5b6c7cea2756b57530e495d56acdb4fd2b56c0ba4d768dfd","src/advice.rs":"194bfd6a32495f6b0c739d083b06230ae656927767f15c1b49b245b63431cc4d","src/lib.rs":"2fa8c6162297441c82471132b9e26d3effcb9c06ae414a0104f9d871eba0aa00","src/stub.rs":"f276bb5e4bc29c2129ebc660b01a1de173b9575e2e866ea5a34e0ee6318f1177","src/unix.rs":"4fa52c514f15dd5e990e03671599a0c3f15770b8fb5f8fea3ea6333766b1e31c","src/windows.rs":"73838f8b2dc8b0c8d37045db36c3c7eb2dc00e6f5d5a7bc0c693bdb55d3ec721"},"package":"d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"fb280b4d71ea601557e7ab637a7f82f73eb519dd9d16d38684bf6fe4e800a020","Cargo.lock":"80c9c7be560eee59e3eded68a49b53278198fc23495807c6a22e9c5190914ebe","Cargo.toml":"4738a7e9e1f236b95d41ef8837c351f895fcb1cc1cb82ab7e3bf39c72849cba4","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"0d25d03b5ab49576178ad0cae7a2648d12c17ad0452fe49c07e55e4b59aa5257","README.md":"c7b3cd928f0d1a10faa255e2f84a2a06636e55ea3e7edd4f6334dd9215151205","examples/cat.rs":"ab0b575d19662e2d5b6c7cea2756b57530e495d56acdb4fd2b56c0ba4d768dfd","src/advice.rs":"194bfd6a32495f6b0c739d083b06230ae656927767f15c1b49b245b63431cc4d","src/lib.rs":"ea214bce1c2409b8ee7a390c85f5114bc681a551d02aba23280030fe58588eb9","src/stub.rs":"f276bb5e4bc29c2129ebc660b01a1de173b9575e2e866ea5a34e0ee6318f1177","src/unix.rs":"03fe91a320d0146993019ea51e486275b8c8e13e42a995e649b8c76690e3f167","src/windows.rs":"bbb39200ac35b5517626c12efad4886f7b5d34e56256284914c556dec1567e38"},"package":"95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"} \ No newline at end of file
diff --git a/vendor/memmap2/CHANGELOG.md b/vendor/memmap2/CHANGELOG.md
index e54a78122..14f481c4e 100644
--- a/vendor/memmap2/CHANGELOG.md
+++ b/vendor/memmap2/CHANGELOG.md
@@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+## [0.5.7] - 2022-08-15
+### Changed
+- Simplify file size retrieving code.
+ [@saethlin](https://github.com/saethlin)
+
+## [0.5.6] - 2022-08-11
+### Added
+- Memory locking and unlocking. See `Mmap::lock`, `Mmap::unlock`,
+ `MmapMut::lock` and `MmapMut::unlock`.
+ [@vmx](https://github.com/vmx)
+
+## [0.5.5] - 2022-07-09
+### Fixed
+- Limit mapping length to `isize::MAX` to prevent undefined behavior
+ on calling `std::slice::from_raw_parts`. Technically affects only 32-bit systems.
+ [@adamreichold](https://github.com/adamreichold)
+
## [0.5.4] - 2022-06-04
### Added
- Add madvice operations specific to Darwin. [@turbocool3r](https://github.com/turbocool3r)
@@ -100,7 +117,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Removed
- `winapi` dependency. [memmap-rs/pull/89](https://github.com/danburkert/memmap-rs/pull/89)
-[Unreleased]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.4...HEAD
+[Unreleased]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.7...HEAD
+[0.5.7]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.6...v0.5.7
+[0.5.6]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.5...v0.5.6
+[0.5.5]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.4...v0.5.5
[0.5.4]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.3...v0.5.4
[0.5.3]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.2...v0.5.3
[0.5.2]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.1...v0.5.2
diff --git a/vendor/memmap2/Cargo.lock b/vendor/memmap2/Cargo.lock
index 7f41430a4..5a4a2b5f2 100644
--- a/vendor/memmap2/Cargo.lock
+++ b/vendor/memmap2/Cargo.lock
@@ -40,7 +40,7 @@ checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
[[package]]
name = "memmap2"
-version = "0.5.4"
+version = "0.5.7"
dependencies = [
"libc",
"owning_ref",
diff --git a/vendor/memmap2/Cargo.toml b/vendor/memmap2/Cargo.toml
index bdbc259e3..29d796270 100644
--- a/vendor/memmap2/Cargo.toml
+++ b/vendor/memmap2/Cargo.toml
@@ -12,13 +12,14 @@
[package]
edition = "2018"
name = "memmap2"
-version = "0.5.4"
+version = "0.5.7"
authors = [
"Dan Burkert <dan@danburkert.com>",
"Yevhenii Reizner <razrfalcon@gmail.com>",
]
description = "Cross-platform Rust API for memory-mapped file IO"
documentation = "https://docs.rs/memmap2"
+readme = "README.md"
keywords = [
"mmap",
"memory-map",
diff --git a/vendor/memmap2/src/lib.rs b/vendor/memmap2/src/lib.rs
index b90d1bcf6..0b92ea0e1 100644
--- a/vendor/memmap2/src/lib.rs
+++ b/vendor/memmap2/src/lib.rs
@@ -51,13 +51,14 @@ use std::fmt;
#[cfg(not(any(unix, windows)))]
use std::fs::File;
use std::io::{Error, ErrorKind, Result};
+use std::isize;
+use std::mem;
use std::ops::{Deref, DerefMut};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawHandle, RawHandle};
use std::slice;
-use std::usize;
#[cfg(not(any(unix, windows)))]
pub struct MmapRawDescriptor<'a>(&'a File);
@@ -237,15 +238,20 @@ impl MmapOptions {
}
let len = file_len - self.offset;
- // This check it not relevant on 64bit targets, because usize == u64
- #[cfg(not(target_pointer_width = "64"))]
- {
- if len > (usize::MAX as u64) {
- return Err(Error::new(
- ErrorKind::InvalidData,
- "memory map length overflows usize",
- ));
- }
+ // Rust's slice cannot be larger than isize::MAX.
+ // See https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html
+ //
+ // This is not a problem on 64-bit targets, but on 32-bit one
+ // having a file or an anonymous mapping larger than 2GB is quite normal
+ // and we have to prevent it.
+ //
+ // The code below is essentially the same as in Rust's std:
+ // https://github.com/rust-lang/rust/blob/db78ab70a88a0a5e89031d7ee4eccec835dcdbde/library/alloc/src/raw_vec.rs#L495
+ if mem::size_of::<usize>() < 8 && len > isize::MAX as u64 {
+ return Err(Error::new(
+ ErrorKind::InvalidData,
+ "memory map length overflows isize",
+ ));
}
Ok(len as usize)
@@ -457,14 +463,26 @@ impl MmapOptions {
/// Creates an anonymous memory map.
///
- /// Note: the memory map length must be configured to be greater than 0 before creating an
- /// anonymous memory map using `MmapOptions::len()`.
+ /// The memory map length should be configured using [`MmapOptions::len()`]
+ /// before creating an anonymous memory map, otherwise a zero-length mapping
+ /// will be crated.
///
/// # Errors
///
- /// This method returns an error when the underlying system call fails.
+ /// This method returns an error when the underlying system call fails or
+ /// when `len > isize::MAX`.
pub fn map_anon(&self) -> Result<MmapMut> {
- MmapInner::map_anon(self.len.unwrap_or(0), self.stack).map(|inner| MmapMut { inner })
+ let len = self.len.unwrap_or(0);
+
+ // See get_len() for details.
+ if mem::size_of::<usize>() < 8 && len > isize::MAX as usize {
+ return Err(Error::new(
+ ErrorKind::InvalidData,
+ "memory map length overflows isize",
+ ));
+ }
+
+ MmapInner::map_anon(len, self.stack).map(|inner| MmapMut { inner })
}
/// Creates a raw memory map.
@@ -611,6 +629,22 @@ impl Mmap {
pub fn advise(&self, advice: Advice) -> Result<()> {
self.inner.advise(advice)
}
+
+ /// Lock the whole memory map into RAM. Only supported on Unix.
+ ///
+ /// See [mlock()](https://man7.org/linux/man-pages/man2/mlock.2.html) map page.
+ #[cfg(unix)]
+ pub fn lock(&mut self) -> Result<()> {
+ self.inner.lock()
+ }
+
+ /// Unlock the whole memory map. Only supported on Unix.
+ ///
+ /// See [munlock()](https://man7.org/linux/man-pages/man2/munlock.2.html) map page.
+ #[cfg(unix)]
+ pub fn unlock(&mut self) -> Result<()> {
+ self.inner.unlock()
+ }
}
#[cfg(feature = "stable_deref_trait")]
@@ -856,7 +890,8 @@ impl MmapMut {
///
/// # Errors
///
- /// This method returns an error when the underlying system call fails.
+ /// This method returns an error when the underlying system call fails or
+ /// when `len > isize::MAX`.
pub fn map_anon(length: usize) -> Result<MmapMut> {
MmapOptions::new().len(length).map_anon()
}
@@ -987,6 +1022,22 @@ impl MmapMut {
pub fn advise(&self, advice: Advice) -> Result<()> {
self.inner.advise(advice)
}
+
+ /// Lock the whole memory map into RAM. Only supported on Unix.
+ ///
+ /// See [mlock()](https://man7.org/linux/man-pages/man2/mlock.2.html) map page.
+ #[cfg(unix)]
+ pub fn lock(&mut self) -> Result<()> {
+ self.inner.lock()
+ }
+
+ /// Unlock the whole memory map. Only supported on Unix.
+ ///
+ /// See [munlock()](https://man7.org/linux/man-pages/man2/munlock.2.html) map page.
+ #[cfg(unix)]
+ pub fn unlock(&mut self) -> Result<()> {
+ self.inner.unlock()
+ }
}
#[cfg(feature = "stable_deref_trait")]
@@ -1037,7 +1088,7 @@ mod test {
#[cfg(unix)]
use crate::advice::Advice;
- use std::fs::OpenOptions;
+ use std::fs::{self, OpenOptions};
use std::io::{Read, Write};
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
@@ -1158,6 +1209,17 @@ mod test {
}
#[test]
+ #[cfg(target_pointer_width = "32")]
+ fn map_anon_len_overflow() {
+ let res = MmapMut::map_anon(0x80000000);
+
+ assert_eq!(
+ res.unwrap_err().to_string(),
+ "memory map length overflows isize"
+ );
+ }
+
+ #[test]
fn file_write() {
let tempdir = tempfile::tempdir().unwrap();
let path = tempdir.path().join("mmap");
@@ -1333,7 +1395,6 @@ mod test {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn jit_x86(mut mmap: MmapMut) {
- use std::mem;
mmap[0] = 0xB8; // mov eax, 0xAB
mmap[1] = 0xAB;
mmap[2] = 0x00;
@@ -1343,7 +1404,7 @@ mod test {
let mmap = mmap.make_exec().expect("make_exec");
- let jitfn: extern "C" fn() -> u8 = unsafe { mem::transmute(mmap.as_ptr()) };
+ let jitfn: extern "C" fn() -> u8 = unsafe { std::mem::transmute(mmap.as_ptr()) };
assert_eq!(jitfn(), 0xab);
}
@@ -1557,4 +1618,56 @@ mod test {
// read values back
assert_eq!(&incr[..], &mmap[..]);
}
+
+ /// Returns true if a non-zero amount of memory is locked.
+ #[cfg(target_os = "linux")]
+ fn is_locked() -> bool {
+ let status = &fs::read_to_string("/proc/self/status")
+ .expect("/proc/self/status should be available");
+ for line in status.lines() {
+ if line.starts_with("VmLck:") {
+ let numbers = line.replace(|c: char| !c.is_ascii_digit(), "");
+ return numbers != "0";
+ }
+ }
+ panic!("cannot get VmLck information")
+ }
+
+ #[test]
+ #[cfg(unix)]
+ fn lock() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let path = tempdir.path().join("mmap_lock");
+
+ let file = OpenOptions::new()
+ .read(true)
+ .write(true)
+ .create(true)
+ .open(&path)
+ .unwrap();
+ file.set_len(128).unwrap();
+
+ let mut mmap = unsafe { Mmap::map(&file).unwrap() };
+ #[cfg(target_os = "linux")]
+ assert!(!is_locked());
+
+ mmap.lock().expect("mmap lock should be supported on unix");
+ #[cfg(target_os = "linux")]
+ assert!(is_locked());
+
+ mmap.lock()
+ .expect("mmap lock again should not cause problems");
+ #[cfg(target_os = "linux")]
+ assert!(is_locked());
+
+ mmap.unlock()
+ .expect("mmap unlock should be supported on unix");
+ #[cfg(target_os = "linux")]
+ assert!(!is_locked());
+
+ mmap.unlock()
+ .expect("mmap unlock again should not cause problems");
+ #[cfg(target_os = "linux")]
+ assert!(!is_locked());
+ }
}
diff --git a/vendor/memmap2/src/unix.rs b/vendor/memmap2/src/unix.rs
index cd3dcdbce..158d78c1f 100644
--- a/vendor/memmap2/src/unix.rs
+++ b/vendor/memmap2/src/unix.rs
@@ -1,7 +1,8 @@
extern crate libc;
-use std::mem::MaybeUninit;
-use std::os::unix::io::RawFd;
+use std::fs::File;
+use std::mem::ManuallyDrop;
+use std::os::unix::io::{FromRawFd, RawFd};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::{io, ptr};
@@ -248,6 +249,26 @@ impl MmapInner {
}
}
}
+
+ pub fn lock(&self) -> io::Result<()> {
+ unsafe {
+ if libc::mlock(self.ptr, self.len) != 0 {
+ Err(io::Error::last_os_error())
+ } else {
+ Ok(())
+ }
+ }
+ }
+
+ pub fn unlock(&self) -> io::Result<()> {
+ unsafe {
+ if libc::munlock(self.ptr, self.len) != 0 {
+ Err(io::Error::last_os_error())
+ } else {
+ Ok(())
+ }
+ }
+ }
}
impl Drop for MmapInner {
@@ -284,19 +305,10 @@ fn page_size() -> usize {
}
pub fn file_len(file: RawFd) -> io::Result<u64> {
- #[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "l4re")))]
- use libc::{fstat, stat};
- #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))]
- use libc::{fstat64 as fstat, stat64 as stat};
-
+ // SAFETY: We must not close the passed-in fd by dropping the File we create,
+ // we ensure this by immediately wrapping it in a ManuallyDrop.
unsafe {
- let mut stat = MaybeUninit::<stat>::uninit();
-
- let result = fstat(file, stat.as_mut_ptr());
- if result == 0 {
- Ok(stat.assume_init().st_size as u64)
- } else {
- Err(io::Error::last_os_error())
- }
+ let file = ManuallyDrop::new(File::from_raw_fd(file));
+ Ok(file.metadata()?.len())
}
}
diff --git a/vendor/memmap2/src/windows.rs b/vendor/memmap2/src/windows.rs
index b3b8c620a..d580995e6 100644
--- a/vendor/memmap2/src/windows.rs
+++ b/vendor/memmap2/src/windows.rs
@@ -1,8 +1,10 @@
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
+use std::fs::File;
+use std::mem::ManuallyDrop;
use std::os::raw::c_void;
-use std::os::windows::io::RawHandle;
+use std::os::windows::io::{FromRawHandle, RawHandle};
use std::{io, mem, ptr};
type BOOL = i32;
@@ -82,22 +84,6 @@ pub struct FILETIME {
pub dwHighDateTime: DWORD,
}
-#[repr(C)]
-struct BY_HANDLE_FILE_INFORMATION {
- dwFileAttributes: DWORD,
- ftCreationTime: FILETIME,
- ftLastAccessTime: FILETIME,
- ftLastWriteTime: FILETIME,
- dwVolumeSerialNumber: DWORD,
- nFileSizeHigh: DWORD,
- nFileSizeLow: DWORD,
- nNumberOfLinks: DWORD,
- nFileIndexHigh: DWORD,
- nFileIndexLow: DWORD,
-}
-
-type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
-
extern "system" {
fn GetCurrentProcess() -> HANDLE;
@@ -124,11 +110,6 @@ extern "system" {
fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
- fn GetFileInformationByHandle(
- hFile: HANDLE,
- lpFileInformation: LPBY_HANDLE_FILE_INFORMATION,
- ) -> BOOL;
-
fn FlushViewOfFile(lpBaseAddress: LPCVOID, dwNumberOfBytesToFlush: SIZE_T) -> BOOL;
fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
@@ -526,16 +507,10 @@ fn allocation_granularity() -> usize {
}
pub fn file_len(handle: RawHandle) -> io::Result<u64> {
- let info = unsafe {
- let mut info = mem::MaybeUninit::<BY_HANDLE_FILE_INFORMATION>::uninit();
-
- let ok = GetFileInformationByHandle(handle, info.as_mut_ptr());
- if ok == 0 {
- return Err(io::Error::last_os_error());
- }
-
- info.assume_init()
- };
-
- Ok((info.nFileSizeHigh as u64) << 32 | info.nFileSizeLow as u64)
+ // SAFETY: We must not close the passed-in fd by dropping the File we create,
+ // we ensure this by immediately wrapping it in a ManuallyDrop.
+ unsafe {
+ let file = ManuallyDrop::new(File::from_raw_handle(handle));
+ Ok(file.metadata()?.len())
+ }
}
diff --git a/vendor/minifier/.cargo-checksum.json b/vendor/minifier/.cargo-checksum.json
index 4760bcb0d..6ca9569c2 100644
--- a/vendor/minifier/.cargo-checksum.json
+++ b/vendor/minifier/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.lock":"adb64b1e8820e83bebfc867d6e5846154743bc324754d50a2bb13742f682f1b9","Cargo.toml":"d5c1e43fffcf2a4a384ea0adfacac7c08b41bd3b05937e7e2ad1aeb0ea2aad62","LICENSE":"d64fe3199be0c90d1f88b363e6b567d5812f64c01accc8957e71381598a3d670","README.md":"7ce7cc43ebca972096db97b9f8bd211e5ac0c688f01b1732d5e2243e8c32d02d","src/css/mod.rs":"afbab7f8a657871fb567b25c5c87cb3e1c9e88d486335e154873b8c818370506","src/css/tests.rs":"056d1d3d927be4c7cece4033b48b28fe3a142939ac2f71cb10ca93f2a28a4477","src/css/token.rs":"b9fff49884a74423e11a913f49dd923b2f8c28e5a29894b08c9d1b2fbc06b85f","src/html.rs":"7b78e2c7d1b0d85065de7e6ab7e0407a74590e23ad1d20fe106c2361f5b09447","src/js/mod.rs":"b63e9cac9cc2cf7063f1eb598892fde3aa55081d0bf926df85c008e35d8e5a30","src/js/token.rs":"81918762068fba64a53dc0328222e74e8c922e657be46bb431ae4a3ac0e9fce9","src/js/tools.rs":"50e9581d6cfa2aebf2928f3df63bbb8a72149c7a40a687f248c108cf154a74ab","src/js/utils.rs":"54d97e766cb38ca1ac7c661a376f8e01c735486f2b78ae149794bb735e8f787b","src/json/json_minifier.rs":"83b5868bff0692aa655973596ad6ff34d215001be47c5c9adad8049faeec87bb","src/json/mod.rs":"e4ff2108ba01d5e937e22108c467c1c191ffc55fffedebd9c86d2a9789abb5e4","src/json/read/byte_to_char.rs":"633cdff14eb99fe7e2ba72594444b2c681a7ec13f557fecfc791b11ce8b9f130","src/json/read/internal_buffer.rs":"459e17fcc86039dd5000dbf9e8c834bfaa02cba2a2afbd19c067c9d621ba7d0b","src/json/read/internal_reader.rs":"37d9f8a31fd6477bbed676ce923a85568e9a96ef5d46db02e92e65ba13c65dea","src/json/read/json_read.rs":"dbc2c729c0c07109860e5a7c69f4fea2c4721fc17f764622392c54bd2afb1b55","src/json/string.rs":"9b9b3a40bfdb6fcbe2f3215a0506b8edfab577dd79e4a404c492fbc486896567","src/lib.rs":"ec53713f3903f80439c83a835d46b562c3cae119f2354d7a5558c0603c86c1a7","src/main.rs":"10c62d1d5544896506962d569d1507d3396bf894f501c26586a561b904956c47","tests/files/main.js":"18f43c7672eb75f532bc7f99dd2b6d644b3a11e19662774e93405928fde4d4d4","tests/files/minified_main.js":"0952e8cff3fae6c91b13a15f2923d922ccd9bce339419cc4bd52b5314180dabb","tests/files/test.json":"e07a148ef24385057cb7420209a630758c6ce80970bd54c8ffee5be207205608","tests/js_minify.rs":"66de1b596668a5f8d11e0b65d42ace3da6bc0b2b997b2d9e2fc09a488624c5af"},"package":"ac96d1e7a65f206443f95afff6de8f1690c77c97d6fc9c9bb2d2cd0662e9ff9f"} \ No newline at end of file
+{"files":{"Cargo.lock":"57dc07ee7630f30d86a9f9729eda1a2df49abcfbd82eaa850d1583de0507a57a","Cargo.toml":"1d804870b80ebb2d7361ab20144152a8593f97b37377834fa4c0f5c399281626","LICENSE":"d64fe3199be0c90d1f88b363e6b567d5812f64c01accc8957e71381598a3d670","README.md":"7ce7cc43ebca972096db97b9f8bd211e5ac0c688f01b1732d5e2243e8c32d02d","src/css/mod.rs":"afbab7f8a657871fb567b25c5c87cb3e1c9e88d486335e154873b8c818370506","src/css/tests.rs":"056d1d3d927be4c7cece4033b48b28fe3a142939ac2f71cb10ca93f2a28a4477","src/css/token.rs":"3f949eb966daab620df03a2fb9e8309fae0f48ad4b3012603f7daa363ab9d62f","src/html.rs":"7b78e2c7d1b0d85065de7e6ab7e0407a74590e23ad1d20fe106c2361f5b09447","src/js/mod.rs":"b63e9cac9cc2cf7063f1eb598892fde3aa55081d0bf926df85c008e35d8e5a30","src/js/token.rs":"81918762068fba64a53dc0328222e74e8c922e657be46bb431ae4a3ac0e9fce9","src/js/tools.rs":"50e9581d6cfa2aebf2928f3df63bbb8a72149c7a40a687f248c108cf154a74ab","src/js/utils.rs":"54d97e766cb38ca1ac7c661a376f8e01c735486f2b78ae149794bb735e8f787b","src/json/json_minifier.rs":"83b5868bff0692aa655973596ad6ff34d215001be47c5c9adad8049faeec87bb","src/json/mod.rs":"e4ff2108ba01d5e937e22108c467c1c191ffc55fffedebd9c86d2a9789abb5e4","src/json/read/byte_to_char.rs":"633cdff14eb99fe7e2ba72594444b2c681a7ec13f557fecfc791b11ce8b9f130","src/json/read/internal_buffer.rs":"459e17fcc86039dd5000dbf9e8c834bfaa02cba2a2afbd19c067c9d621ba7d0b","src/json/read/internal_reader.rs":"37d9f8a31fd6477bbed676ce923a85568e9a96ef5d46db02e92e65ba13c65dea","src/json/read/json_read.rs":"dbc2c729c0c07109860e5a7c69f4fea2c4721fc17f764622392c54bd2afb1b55","src/json/string.rs":"9b9b3a40bfdb6fcbe2f3215a0506b8edfab577dd79e4a404c492fbc486896567","src/lib.rs":"ec53713f3903f80439c83a835d46b562c3cae119f2354d7a5558c0603c86c1a7","src/main.rs":"10c62d1d5544896506962d569d1507d3396bf894f501c26586a561b904956c47","tests/files/main.js":"18f43c7672eb75f532bc7f99dd2b6d644b3a11e19662774e93405928fde4d4d4","tests/files/minified_main.js":"0952e8cff3fae6c91b13a15f2923d922ccd9bce339419cc4bd52b5314180dabb","tests/files/test.json":"e07a148ef24385057cb7420209a630758c6ce80970bd54c8ffee5be207205608","tests/js_minify.rs":"66de1b596668a5f8d11e0b65d42ace3da6bc0b2b997b2d9e2fc09a488624c5af"},"package":"8eb022374af2f446981254e6bf9efb6e2c9e1a53176d395fca02792fd4435729"} \ No newline at end of file
diff --git a/vendor/minifier/Cargo.lock b/vendor/minifier/Cargo.lock
index 9f5453ee1..2b0a9ea5c 100644
--- a/vendor/minifier/Cargo.lock
+++ b/vendor/minifier/Cargo.lock
@@ -19,7 +19,7 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "minifier"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"regex",
]
diff --git a/vendor/minifier/Cargo.toml b/vendor/minifier/Cargo.toml
index be981e4d0..a7f02a37c 100644
--- a/vendor/minifier/Cargo.toml
+++ b/vendor/minifier/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2021"
name = "minifier"
-version = "0.2.1"
+version = "0.2.2"
authors = ["Guillaume Gomez <guillaume1.gomez@gmail.com>"]
description = "Minifier tool/lib for JS/CSS/JSON files"
documentation = "https://docs.rs/minifier-rs"
diff --git a/vendor/minifier/src/css/token.rs b/vendor/minifier/src/css/token.rs
index d2d738840..58e416fcd 100644
--- a/vendor/minifier/src/css/token.rs
+++ b/vendor/minifier/src/css/token.rs
@@ -571,9 +571,17 @@ pub(super) fn tokenize<'a>(source: &'a str) -> Result<Tokens<'a>, &'static str>
}
fn clean_tokens(mut v: Vec<Token<'_>>) -> Vec<Token<'_>> {
+ // This function may remove multiple elements from the vector. Ideally we'd
+ // use `Vec::retain`, but the traversal requires inspecting the previously
+ // retained token and the next token, which `Vec::retain` doesn't allow. So
+ // we have to use a lower-level mechanism.
let mut i = 0;
+ // Index of the previous retained token, if there is one.
+ let mut ip: Option<usize> = None;
let mut is_in_calc = false;
let mut paren = 0;
+ // A vector of bools indicating which elements are to be retained.
+ let mut b = Vec::with_capacity(v.len());
while i < v.len() {
if v[i] == Token::Other("calc") {
@@ -587,39 +595,42 @@ fn clean_tokens(mut v: Vec<Token<'_>>) -> Vec<Token<'_>> {
}
}
+ let mut retain = true;
if v[i].is_useless() {
- if i > 0 && v[i - 1] == Token::Char(ReservedChar::CloseBracket) {
+ #[allow(clippy::if_same_then_else)]
+ if ip.is_some() && v[ip.unwrap()] == Token::Char(ReservedChar::CloseBracket) {
if i + 1 < v.len()
&& (v[i + 1].is_useless()
|| v[i + 1] == Token::Char(ReservedChar::OpenCurlyBrace))
{
- v.remove(i);
- continue;
+ retain = false;
}
- } else if i > 0
- && (v[i - 1] == Token::Other("and")
- || v[i - 1] == Token::Other("or")
- || v[i - 1] == Token::Other("not"))
- {
+ } else if ip.is_some() && matches!(v[ip.unwrap()], Token::Other("and" | "or" | "not")) {
// retain the space after "and", "or" or "not"
- } else if (is_in_calc && v[i - 1].is_useless())
- || !is_in_calc
- && ((i > 0
- && ((v[i - 1].is_char()
- && v[i - 1] != Token::Char(ReservedChar::CloseParenthese))
- || v[i - 1].is_a_media()
- || v[i - 1].is_a_license()))
- || (i < v.len() - 1 && v[i + 1].is_char()))
+ } else if is_in_calc && v[ip.unwrap()].is_useless() {
+ retain = false;
+ } else if !is_in_calc
+ && ((ip.is_some() && {
+ let prev = &v[ip.unwrap()];
+ (prev.is_char() && prev != &Token::Char(ReservedChar::CloseParenthese))
+ || prev.is_a_media()
+ || prev.is_a_license()
+ }) || (i < v.len() - 1 && v[i + 1].is_char()))
{
- v.remove(i);
- continue;
+ retain = false;
}
} else if v[i].is_comment() {
- v.remove(i);
- continue;
+ retain = false;
+ }
+ if retain {
+ ip = Some(i);
}
+ b.push(retain);
i += 1;
}
+ assert_eq!(v.len(), b.len());
+ let mut b = b.into_iter();
+ v.retain(|_| b.next().unwrap());
v
}
diff --git a/vendor/once_cell/.cargo-checksum.json b/vendor/once_cell/.cargo-checksum.json
index 247fbbfc0..9dffae3ad 100644
--- a/vendor/once_cell/.cargo-checksum.json
+++ b/vendor/once_cell/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"6b2f19d43eb81a0d5e91340c27953334a1fce5f34056069ee126f4e40747606b","Cargo.lock":"dab17e5aacff6a0ede5fad63ae4aaa5173391f7a37cfac1ee51078a172816bb4","Cargo.toml":"6304404996d3c7506816b51df07b8f8fc3e4900e3d3a2c97dd7936567f20bbcc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"813d262a320611ba874c4b2488256bdb2b4073649616a1471b389d464a704301","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"90541b093ed1d1cbb73f4097ff02cf80657e28264d281d6a31d96a708fdfea90","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_pl.rs":"1959494004fb0ee7443e97c4abd8be69d7173fe2b66f8fff0bca7b5c8e512525","src/imp_std.rs":"476c60b61762bda710c68624fb83531cc457780cf3e5223f40a5362d33f3ab5c","src/lib.rs":"5320847175dc279e7abd2d98e17ab8d05b2eb7e383a4f249623b71a5209f2346","src/race.rs":"5a19afca4b5510d09ca7317b96f5642725c58b0969b2bdeb7275ed674d061e5d","tests/it.rs":"501c4ab3f4e718fa555707e9d32f3688c05e4ef8ea967e72e1c99da6bb06a0ad"},"package":"18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"1638f5757551c399130656e1daab76b0322538923a791bf39e9ec247257daf79","Cargo.lock":"417a830ee5d5359f413fdf973391bf137de7ea8b075d83dcf798f1d3de36cfda","Cargo.toml":"d083a23d498e2dbf1cb3f249bdade38715b3cb237a38b733df79f20824eec4f7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"813d262a320611ba874c4b2488256bdb2b4073649616a1471b389d464a704301","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"90541b093ed1d1cbb73f4097ff02cf80657e28264d281d6a31d96a708fdfea90","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_pl.rs":"1959494004fb0ee7443e97c4abd8be69d7173fe2b66f8fff0bca7b5c8e512525","src/imp_std.rs":"33be3a0df87e092abd68280dc72d50534d273d17eb86940e7ba2b8a45da78a70","src/lib.rs":"5320847175dc279e7abd2d98e17ab8d05b2eb7e383a4f249623b71a5209f2346","src/race.rs":"5a19afca4b5510d09ca7317b96f5642725c58b0969b2bdeb7275ed674d061e5d","tests/it.rs":"501c4ab3f4e718fa555707e9d32f3688c05e4ef8ea967e72e1c99da6bb06a0ad"},"package":"074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"} \ No newline at end of file
diff --git a/vendor/once_cell/CHANGELOG.md b/vendor/once_cell/CHANGELOG.md
index d5019bae3..ffb5b1df3 100644
--- a/vendor/once_cell/CHANGELOG.md
+++ b/vendor/once_cell/CHANGELOG.md
@@ -4,6 +4,11 @@
-
+## 1.13.1
+
+- Make implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228).
+- Upgrade `atomic-polyfill` to `1.0`
+
## 1.13.0
- Add `Lazy::get`, similar to `OnceCell::get`.
diff --git a/vendor/once_cell/Cargo.lock b/vendor/once_cell/Cargo.lock
index 27cd64c4a..2e981967f 100644
--- a/vendor/once_cell/Cargo.lock
+++ b/vendor/once_cell/Cargo.lock
@@ -13,41 +13,14 @@ dependencies = [
[[package]]
name = "atomic-polyfill"
-version = "0.1.8"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14bf7b4f565e5e717d7a7a65b2a05c0b8c96e4db636d6f780f03b15108cdd1b"
+checksum = "d299f547288d6db8d5c3a2916f7b2f66134b15b8c1ac1c4357dd3b8752af7bb2"
dependencies = [
"critical-section",
]
[[package]]
-name = "bare-metal"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
-dependencies = [
- "rustc_version",
-]
-
-[[package]]
-name = "bare-metal"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
-
-[[package]]
-name = "bit_field"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
-
-[[package]]
-name = "bitfield"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
-
-[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -60,47 +33,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "cortex-m"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd20d4ac4aa86f4f75f239d59e542ef67de87cce2c282818dc6e84155d3ea126"
-dependencies = [
- "bare-metal 0.2.5",
- "bitfield",
- "embedded-hal",
- "volatile-register",
-]
-
-[[package]]
name = "critical-section"
-version = "0.2.7"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd"
-dependencies = [
- "bare-metal 1.0.0",
- "cfg-if",
- "cortex-m",
- "riscv",
-]
+checksum = "ce181dda5a65c00fcbce2b9d44ad9be001202a54fb321865ed273ac39aa8ccbe"
[[package]]
name = "crossbeam-utils"
-version = "0.8.10"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
+checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if",
- "once_cell 1.12.1",
-]
-
-[[package]]
-name = "embedded-hal"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
-dependencies = [
- "nb 0.1.3",
- "void",
+ "once_cell 1.13.0",
]
[[package]]
@@ -111,9 +56,9 @@ checksum = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.131"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40"
[[package]]
name = "memchr"
@@ -122,29 +67,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
[[package]]
-name = "nb"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
-dependencies = [
- "nb 1.0.0",
-]
-
-[[package]]
-name = "nb"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
-
-[[package]]
name = "once_cell"
-version = "1.12.1"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac8b1a9b2518dc799a2271eff1688707eb315f0d4697aa6b0871369ca4c4da55"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "once_cell"
-version = "1.13.0"
+version = "1.13.1"
dependencies = [
"atomic-polyfill",
"crossbeam-utils",
@@ -168,9 +98,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.2.13"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
@@ -198,51 +128,6 @@ dependencies = [
]
[[package]]
-name = "riscv"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba"
-dependencies = [
- "bare-metal 1.0.0",
- "bit_field",
- "riscv-target",
-]
-
-[[package]]
-name = "riscv-target"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222"
-dependencies = [
- "lazy_static",
- "regex",
-]
-
-[[package]]
-name = "rustc_version"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-dependencies = [
- "semver",
-]
-
-[[package]]
-name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-dependencies = [
- "semver-parser",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-
-[[package]]
name = "smallvec"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -270,27 +155,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
[[package]]
-name = "vcell"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
-
-[[package]]
-name = "void"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-
-[[package]]
-name = "volatile-register"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
-dependencies = [
- "vcell",
-]
-
-[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/vendor/once_cell/Cargo.toml b/vendor/once_cell/Cargo.toml
index a815a5549..e8222f163 100644
--- a/vendor/once_cell/Cargo.toml
+++ b/vendor/once_cell/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "once_cell"
-version = "1.13.0"
+version = "1.13.1"
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
exclude = [
"*.png",
@@ -66,7 +66,7 @@ name = "test_synchronization"
required-features = ["std"]
[dependencies.atomic-polyfill]
-version = "0.1"
+version = "1"
optional = true
[dependencies.parking_lot_core]
diff --git a/vendor/once_cell/src/imp_std.rs b/vendor/once_cell/src/imp_std.rs
index 2bbe5b76e..4d5b5fd32 100644
--- a/vendor/once_cell/src/imp_std.rs
+++ b/vendor/once_cell/src/imp_std.rs
@@ -8,7 +8,7 @@ use std::{
hint::unreachable_unchecked,
marker::PhantomData,
panic::{RefUnwindSafe, UnwindSafe},
- sync::atomic::{AtomicBool, AtomicUsize, Ordering},
+ sync::atomic::{AtomicBool, AtomicPtr, Ordering},
thread::{self, Thread},
};
@@ -24,7 +24,7 @@ pub(crate) struct OnceCell<T> {
//
// State is encoded in two low bits. Only `INCOMPLETE` and `RUNNING` states
// allow waiters.
- queue: AtomicUsize,
+ queue: AtomicPtr<Waiter>,
_marker: PhantomData<*mut Waiter>,
value: UnsafeCell<Option<T>>,
}
@@ -43,7 +43,7 @@ impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
impl<T> OnceCell<T> {
pub(crate) const fn new() -> OnceCell<T> {
OnceCell {
- queue: AtomicUsize::new(INCOMPLETE),
+ queue: AtomicPtr::new(INCOMPLETE_PTR),
_marker: PhantomData,
value: UnsafeCell::new(None),
}
@@ -51,7 +51,7 @@ impl<T> OnceCell<T> {
pub(crate) const fn with_value(value: T) -> OnceCell<T> {
OnceCell {
- queue: AtomicUsize::new(COMPLETE),
+ queue: AtomicPtr::new(COMPLETE_PTR),
_marker: PhantomData,
value: UnsafeCell::new(Some(value)),
}
@@ -64,7 +64,7 @@ impl<T> OnceCell<T> {
// operations visible to us, and, this being a fast path, weaker
// ordering helps with performance. This `Acquire` synchronizes with
// `SeqCst` operations on the slow path.
- self.queue.load(Ordering::Acquire) == COMPLETE
+ self.queue.load(Ordering::Acquire) == COMPLETE_PTR
}
/// Safety: synchronizes with store to value via SeqCst read from state,
@@ -145,6 +145,8 @@ impl<T> OnceCell<T> {
const INCOMPLETE: usize = 0x0;
const RUNNING: usize = 0x1;
const COMPLETE: usize = 0x2;
+const INCOMPLETE_PTR: *mut Waiter = INCOMPLETE as *mut Waiter;
+const COMPLETE_PTR: *mut Waiter = COMPLETE as *mut Waiter;
// Mask to learn about the state. All other bits are the queue of waiters if
// this is in the RUNNING state.
@@ -156,23 +158,24 @@ const STATE_MASK: usize = 0x3;
struct Waiter {
thread: Cell<Option<Thread>>,
signaled: AtomicBool,
- next: *const Waiter,
+ next: *mut Waiter,
}
/// Drains and notifies the queue of waiters on drop.
struct Guard<'a> {
- queue: &'a AtomicUsize,
- new_queue: usize,
+ queue: &'a AtomicPtr<Waiter>,
+ new_queue: *mut Waiter,
}
impl Drop for Guard<'_> {
fn drop(&mut self) {
let queue = self.queue.swap(self.new_queue, Ordering::AcqRel);
- assert_eq!(queue & STATE_MASK, RUNNING);
+ let state = strict::addr(queue) & STATE_MASK;
+ assert_eq!(state, RUNNING);
unsafe {
- let mut waiter = (queue & !STATE_MASK) as *const Waiter;
+ let mut waiter = strict::map_addr(queue, |q| q & !STATE_MASK);
while !waiter.is_null() {
let next = (*waiter).next;
let thread = (*waiter).thread.take().unwrap();
@@ -191,17 +194,17 @@ impl Drop for Guard<'_> {
//
// Note: this is intentionally monomorphic
#[inline(never)]
-fn initialize_or_wait(queue: &AtomicUsize, mut init: Option<&mut dyn FnMut() -> bool>) {
+fn initialize_or_wait(queue: &AtomicPtr<Waiter>, mut init: Option<&mut dyn FnMut() -> bool>) {
let mut curr_queue = queue.load(Ordering::Acquire);
loop {
- let curr_state = curr_queue & STATE_MASK;
+ let curr_state = strict::addr(curr_queue) & STATE_MASK;
match (curr_state, &mut init) {
(COMPLETE, _) => return,
(INCOMPLETE, Some(init)) => {
let exchange = queue.compare_exchange(
curr_queue,
- (curr_queue & !STATE_MASK) | RUNNING,
+ strict::map_addr(curr_queue, |q| (q & !STATE_MASK) | RUNNING),
Ordering::Acquire,
Ordering::Acquire,
);
@@ -209,9 +212,9 @@ fn initialize_or_wait(queue: &AtomicUsize, mut init: Option<&mut dyn FnMut() ->
curr_queue = new_queue;
continue;
}
- let mut guard = Guard { queue, new_queue: INCOMPLETE };
+ let mut guard = Guard { queue, new_queue: INCOMPLETE_PTR };
if init() {
- guard.new_queue = COMPLETE;
+ guard.new_queue = COMPLETE_PTR;
}
return;
}
@@ -224,24 +227,24 @@ fn initialize_or_wait(queue: &AtomicUsize, mut init: Option<&mut dyn FnMut() ->
}
}
-fn wait(queue: &AtomicUsize, mut curr_queue: usize) {
- let curr_state = curr_queue & STATE_MASK;
+fn wait(queue: &AtomicPtr<Waiter>, mut curr_queue: *mut Waiter) {
+ let curr_state = strict::addr(curr_queue) & STATE_MASK;
loop {
let node = Waiter {
thread: Cell::new(Some(thread::current())),
signaled: AtomicBool::new(false),
- next: (curr_queue & !STATE_MASK) as *const Waiter,
+ next: strict::map_addr(curr_queue, |q| q & !STATE_MASK),
};
- let me = &node as *const Waiter as usize;
+ let me = &node as *const Waiter as *mut Waiter;
let exchange = queue.compare_exchange(
curr_queue,
- me | curr_state,
+ strict::map_addr(me, |q| q | curr_state),
Ordering::Release,
Ordering::Relaxed,
);
if let Err(new_queue) = exchange {
- if new_queue & STATE_MASK != curr_state {
+ if strict::addr(new_queue) & STATE_MASK != curr_state {
return;
}
curr_queue = new_queue;
@@ -255,6 +258,54 @@ fn wait(queue: &AtomicUsize, mut curr_queue: usize) {
}
}
+// Polyfill of strict provenance from https://crates.io/crates/sptr.
+//
+// Use free-standing function rather than a trait to keep things simple and
+// avoid any potential conflicts with future stabile std API.
+mod strict {
+ #[must_use]
+ #[inline]
+ pub(crate) fn addr<T>(ptr: *mut T) -> usize
+ where
+ T: Sized,
+ {
+ // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+ // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
+ // provenance).
+ unsafe { core::mem::transmute(ptr) }
+ }
+
+ #[must_use]
+ #[inline]
+ pub(crate) fn with_addr<T>(ptr: *mut T, addr: usize) -> *mut T
+ where
+ T: Sized,
+ {
+ // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
+ //
+ // In the mean-time, this operation is defined to be "as if" it was
+ // a wrapping_offset, so we can emulate it as such. This should properly
+ // restore pointer provenance even under today's compiler.
+ let self_addr = self::addr(ptr) as isize;
+ let dest_addr = addr as isize;
+ let offset = dest_addr.wrapping_sub(self_addr);
+
+ // This is the canonical desugarring of this operation,
+ // but `pointer::cast` was only stabilized in 1.38.
+ // self.cast::<u8>().wrapping_offset(offset).cast::<T>()
+ (ptr as *mut u8).wrapping_offset(offset) as *mut T
+ }
+
+ #[must_use]
+ #[inline]
+ pub(crate) fn map_addr<T>(ptr: *mut T, f: impl FnOnce(usize) -> usize) -> *mut T
+ where
+ T: Sized,
+ {
+ self::with_addr(ptr, f(addr(ptr)))
+ }
+}
+
// These test are snatched from std as well.
#[cfg(test)]
mod tests {
diff --git a/vendor/opaque-debug/.cargo-checksum.json b/vendor/opaque-debug/.cargo-checksum.json
deleted file mode 100644
index e431ffb85..000000000
--- a/vendor/opaque-debug/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"316df812f280ae0c584b6132630119bea8de32864c29772100f9bb8352196381","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"d5c22aa3118d240e877ad41c5d9fa232f9c77d757d4aac0c2f943afc0a95e0ef","src/lib.rs":"2d7d563f4a4df4b0583d6370046642103e4909f0ec2002768308f951f2d7e05c"},"package":"2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"} \ No newline at end of file
diff --git a/vendor/opaque-debug/Cargo.toml b/vendor/opaque-debug/Cargo.toml
deleted file mode 100644
index a2f9f1736..000000000
--- a/vendor/opaque-debug/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "opaque-debug"
-version = "0.2.3"
-authors = ["RustCrypto Developers"]
-description = "Macro for opaque Debug trait implementation"
-documentation = "https://docs.rs/opaque-debug"
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/RustCrypto/utils"
-
-[dependencies]
diff --git a/vendor/opaque-debug/LICENSE-APACHE b/vendor/opaque-debug/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/opaque-debug/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/opaque-debug/LICENSE-MIT b/vendor/opaque-debug/LICENSE-MIT
deleted file mode 100644
index 502cee6e8..000000000
--- a/vendor/opaque-debug/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2018-2019 The RustCrypto Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/opaque-debug/src/lib.rs b/vendor/opaque-debug/src/lib.rs
deleted file mode 100644
index 618626ead..000000000
--- a/vendor/opaque-debug/src/lib.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//! Macro for opaque `Debug` trait implementation.
-#![no_std]
-
-#[doc(hidden)]
-pub extern crate core as __core;
-
-/// Macro for defining opaque `Debug` implementation.
-///
-/// It will use the following format: "StructName { ... }". While it's
-/// convinient to have it (e.g. for including into other structs), it could be
-/// undesirable to leak internall state, which can happen for example through
-/// uncareful logging.
-#[macro_export]
-macro_rules! impl_opaque_debug {
- ($struct:ty) => {
- impl $crate::__core::fmt::Debug for $struct {
- fn fmt(&self, f: &mut $crate::__core::fmt::Formatter)
- -> Result<(), $crate::__core::fmt::Error>
- {
- write!(f, concat!(stringify!($struct), " {{ ... }}"))
- }
- }
- }
-}
diff --git a/vendor/pest/.cargo-checksum.json b/vendor/pest/.cargo-checksum.json
index e086f365c..8f4b91759 100644
--- a/vendor/pest/.cargo-checksum.json
+++ b/vendor/pest/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.lock":"dc22ac85e4f2d9721c8353751fa5375423f0713c132bbfc65bff52fa86f8fa73","Cargo.toml":"6af58a5c349afda2efbe0ef44e6be51da5bf0f569867ef6438373040dd6cc94b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"e9901b6c4d50403bfda7e08a92b5c395a8c51eba868c7bd07b03e00ccba702f3","examples/parens.rs":"24b83b7fc014813aa089fd05c3ee36926e215ce74a96b07b2c4033dad4ba15b2","src/error.rs":"40dfdd4d32fde69f5320fe9516abd3b4c92ce570a306a3a010c7328ebc542c98","src/iterators/flat_pairs.rs":"0b602eb86a8fd1c037ece03afbbabce316d5938da84f98ca027e8532c311c396","src/iterators/mod.rs":"dfb9cc6d6c0c96f7365ec69500128e3547c0b15dd4e85a5d36e125649244d57a","src/iterators/pair.rs":"510d52a9a6bdf23b20c3e5156028f92ef43e9d7ca88f526d493b5701105d92d5","src/iterators/pairs.rs":"4b8a0cf20ab10ee16d947cdcffbdea535a1d264ea6a1ec4836cb7f1baff2ca38","src/iterators/queueable_token.rs":"b6c4fd1d43437ea7c6cab45717c1fb66f71fc91aaf3ed9cf9f5686fd8ccfa8f9","src/iterators/tokens.rs":"4deea56d66805afe36afb229b9355b43db051b21836af4a88d1febcc4f762ff6","src/lib.rs":"fba1b443efda3f02f20f16094404a74000bc0c6534a80b20cf74f2314fe2a42c","src/macros.rs":"576dc3b66de8d17da494c4a353474fd9bb5ebcde9ffb0d5e9ce7e950ac5b5e7e","src/parser.rs":"2cb858fa80115bf65ff6ceedf3ad73b33fd112bab2a3db4f97be84d6aa4482b5","src/parser_state.rs":"6ba62636a4fefbd11dd92af4480b4ec03ce213ba3ef18136db84a0fb76abca69","src/position.rs":"1b28abf0c8cfefc0ed305c4072b27c4803946c2e5e0bc1d0a4d20ff70e9eb810","src/prec_climber.rs":"e56e8ef7e8e019b5277f164d44acda2d6b993979cc65457e37463204a462be1c","src/span.rs":"cc6ab623ea4c496ddac79d9f179937f47da7c08b514f917f1a3b4e16ca701f52","src/stack.rs":"4fe043bab74b30049c834132c6d8ffc5e21131bc58b7219c5026968013cd665f","src/token.rs":"4ee741dd833c06f8ae826226fb1e5eaa671732d1c68b6b79dea55856ab8b5a0a","src/unicode/binary.rs":"1dcc20ae3922e92fa753849086f8290bebd6d3a1440c2f3cb3482d2192136323","src/unicode/category.rs":"94923b31f349503958e32def13c0b682e52c08b528dd1e0853b55b17627e4ad6","src/unicode/mod.rs":"66a1525a031a7508bdbf65709829e96541d3cc4f228088107f1b94101beec8d6","tests/calculator.rs":"5787fa07560f3187d0a83042336c8613ca90d71186aea88b79ef2a2ccf06f7ab","tests/json.rs":"430913278a7ed16587ac2fcdab2c68329a96cd5d2d2b2eff01245852792e1af1"},"package":"10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"} \ No newline at end of file
+{"files":{"Cargo.lock":"d98d34674a20cc64c8bae177a8de54d9d51cf81279167ebe450876d847dc5578","Cargo.toml":"d5d80b396478e5329d5602215ddc6163ec32c362c3d991430cb48bfd884e3f68","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"01ba71f02581f9f5018962e083ca77bc8e8af2b6f8a73111bfa04e847a6440e2","examples/parens.rs":"a91a1680acc276bac82fbde4855610fab15a77f60041ce12f8adae1d1128157c","src/error.rs":"dc48b66b5e74e251e751a810e9a808deebc11ec036bb12ed1eea3fcfc1bc822c","src/iterators/flat_pairs.rs":"15c0c5b9b1a3fe1f91ce3a8cc5f2ed33319f2545cbef550270416a9a8c0c90c4","src/iterators/mod.rs":"dfb9cc6d6c0c96f7365ec69500128e3547c0b15dd4e85a5d36e125649244d57a","src/iterators/pair.rs":"4aa28ec4d851afa31d05ac21c6bbfd49c96ee452c9d1d5b97923f44a615f3ef1","src/iterators/pairs.rs":"79248afd6d8ed06df63c0cbf0dc2274dcf52b401eb4697a1263e5188915a684c","src/iterators/queueable_token.rs":"b6c4fd1d43437ea7c6cab45717c1fb66f71fc91aaf3ed9cf9f5686fd8ccfa8f9","src/iterators/tokens.rs":"4aa6d4c3eaec86e9086d6cf6499cb3c6f2b89f3269eae21fada9bfbb0c6fe57d","src/lib.rs":"aef41301bcc07e328f5c3a2b5e69d1efc8cbde46f20baa171ce0bad9b922954c","src/macros.rs":"ecbffdc94d721757ee8f11360f5ed38616c8b114c3301b9e424493b844eb1fe5","src/parser.rs":"ee93a084017c4a1da987e307d0aaa047cc4fd7df5fb12c8f730e2151145b8eca","src/parser_state.rs":"a01b978778b0b2aa44d1677d698cb2954517f7761b8e95a55676a639fa76a6f8","src/position.rs":"effe7859987f42e61e4e37e5bc408fb41d31329aa1e8760aa1faaf443e512715","src/prec_climber.rs":"e068f7abe105d39f56ba057e32c32450793b4180d243640cb1008c61f588ce48","src/span.rs":"2030645ea705c3e45a35a7e0d1b1582434fb5f48d336dac0d5c6e9f9b601b0be","src/stack.rs":"97b6fe59e60941c1388fa5fecc2a4fbf78e1cc7f1a3a7c4848cb68ae9d187628","src/token.rs":"810bd05d12ddc71c7fd9f489bbc70552b7479427bc2fe45cd88c191df69ed8c1","src/unicode/binary.rs":"f52dece4f345d1f63041ac6aa7c0673f6dc5100299a47672a35a5b6a64e5c423","src/unicode/category.rs":"7c62c0cdfe2aac27fd3617a17c156822f72e02ab84c761bc815ea01b07997064","src/unicode/mod.rs":"95b31b858565f18990066c64538529e216ce7dc79e7852992df473e4135f2dc1","tests/calculator.rs":"56cc0a279df8f7352b01fbac3ac1bb39208f2ec5227a2ad40b56cc30a5fb5b24","tests/json.rs":"e8bb5af43b4c3b326e29b976b80c7757e70ccafee4f29d8345d7f5f7bce22b59"},"package":"4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4"} \ No newline at end of file
diff --git a/vendor/pest/Cargo.lock b/vendor/pest/Cargo.lock
index a5501eddc..c364151dd 100644
--- a/vendor/pest/Cargo.lock
+++ b/vendor/pest/Cargo.lock
@@ -1,37 +1,58 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "itoa"
-version = "0.4.5"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
+checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
[[package]]
name = "pest"
-version = "2.1.3"
+version = "2.3.0"
dependencies = [
"serde",
"serde_json",
+ "thiserror",
"ucd-trie",
]
[[package]]
+name = "proc-macro2"
+version = "1.0.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
name = "ryu"
-version = "1.0.2"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "serde"
-version = "1.0.104"
+version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
+checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
[[package]]
name = "serde_json"
-version = "1.0.48"
+version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
+checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
dependencies = [
"itoa",
"ryu",
@@ -39,7 +60,44 @@ dependencies = [
]
[[package]]
+name = "syn"
+version = "1.0.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "ucd-trie"
-version = "0.1.2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
+checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
diff --git a/vendor/pest/Cargo.toml b/vendor/pest/Cargo.toml
index 5ad06075a..97246991c 100644
--- a/vendor/pest/Cargo.toml
+++ b/vendor/pest/Cargo.toml
@@ -3,25 +3,32 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
+edition = "2018"
+rust-version = "1.56"
name = "pest"
-version = "2.1.3"
+version = "2.3.0"
authors = ["DragoÈ™ Tiselice <dragostiselice@gmail.com>"]
description = "The Elegant Parser"
homepage = "https://pest-parser.github.io/"
documentation = "https://docs.rs/pest"
readme = "_README.md"
-keywords = ["pest", "parser", "peg", "grammar"]
+keywords = [
+ "pest",
+ "parser",
+ "peg",
+ "grammar",
+]
categories = ["parsing"]
license = "MIT/Apache-2.0"
repository = "https://github.com/pest-parser/pest"
+
[dependencies.serde]
version = "1.0.89"
optional = true
@@ -30,16 +37,22 @@ optional = true
version = "1.0.39"
optional = true
+[dependencies.thiserror]
+version = "1.0.31"
+optional = true
+
[dependencies.ucd-trie]
version = "0.1.1"
+default-features = false
[features]
-pretty-print = ["serde", "serde_json"]
-[badges.codecov]
-repository = "pest-parser/pest"
-
-[badges.maintenance]
-status = "actively-developed"
-
-[badges.travis-ci]
-repository = "pest-parser/pest"
+const_prec_climber = []
+default = ["std"]
+pretty-print = [
+ "serde",
+ "serde_json",
+]
+std = [
+ "ucd-trie/std",
+ "thiserror",
+]
diff --git a/vendor/pest/_README.md b/vendor/pest/_README.md
index 8e55f29a2..f91188ccb 100644
--- a/vendor/pest/_README.md
+++ b/vendor/pest/_README.md
@@ -1,3 +1,4 @@
+
<p align="center">
<img src="https://raw.github.com/pest-parser/pest/master/pest-logo.svg?sanitize=true" width="80%"/>
</p>
@@ -8,9 +9,10 @@
[![Book](https://img.shields.io/badge/book-WIP-4d76ae.svg)](https://pest-parser.github.io/book)
[![Docs](https://docs.rs/pest/badge.svg)](https://docs.rs/pest)
-[![Build Status](https://travis-ci.org/pest-parser/pest.svg?branch=master)](https://travis-ci.org/pest-parser/pest)
+[![pest Continuous Integration](https://github.com/pest-parser/pest/actions/workflows/ci.yml/badge.svg)](https://github.com/pest-parser/pest/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/pest-parser/pest/branch/master/graph/badge.svg)](https://codecov.io/gh/pest-parser/pest)
-[![Fuzzit Status](https://app.fuzzit.dev/badge?org_id=pest-parser)](https://app.fuzzit.dev/orgs/pest-parser/dashboard)
+<a href="https://blog.rust-lang.org/2021/11/01/Rust-1.56.1.html"><img alt="Rustc Version 1.56.1+" src="https://img.shields.io/badge/rustc-1.56.1%2B-lightgrey.svg"/></a>
+
[![Crates.io](https://img.shields.io/crates/d/pest.svg)](https://crates.io/crates/pest)
[![Crates.io](https://img.shields.io/crates/v/pest.svg)](https://crates.io/crates/pest)
@@ -38,7 +40,7 @@ Other helpful resources:
## Example
-The following is an example of a grammar for a list of alpha-numeric identifiers
+The following is an example of a grammar for a list of alphanumeric identifiers
where the first identifier does not start with a digit:
```rust
@@ -143,16 +145,18 @@ Digit: 2
* [pest_meta](https://github.com/pest-parser/pest/blob/master/meta/src/grammar.pest) (bootstrapped)
* [AshPaper](https://github.com/shnewto/ashpaper)
* [brain](https://github.com/brain-lang/brain)
-* [Chelone](https://github.com/Aaronepower/chelone)
+* [cicada](https://github.com/mitnk/cicada)
* [comrak](https://github.com/kivikakk/comrak)
* [elastic-rs](https://github.com/cch123/elastic-rs)
* [graphql-parser](https://github.com/Keats/graphql-parser)
* [handlebars-rust](https://github.com/sunng87/handlebars-rust)
* [hexdino](https://github.com/Luz/hexdino)
* [Huia](https://gitlab.com/jimsy/huia/)
+* [insta](https://github.com/mitsuhiko/insta)
* [jql](https://github.com/yamafaktory/jql)
* [json5-rs](https://github.com/callum-oakley/json5-rs)
* [mt940](https://github.com/svenstaro/mt940-rs)
+* [Myoxine](https://github.com/d3bate/myoxine)
* [py_literal](https://github.com/jturner314/py_literal)
* [rouler](https://github.com/jarcane/rouler)
* [RuSh](https://github.com/lwandrebeck/RuSh)
@@ -162,6 +166,17 @@ Digit: 2
* [ui_gen](https://github.com/emoon/ui_gen)
* [ukhasnet-parser](https://github.com/adamgreig/ukhasnet-parser)
* [ZoKrates](https://github.com/ZoKrates/ZoKrates)
+* [Vector](https://github.com/timberio/vector)
+* [AutoCorrect](https://github.com/huacnlee/autocorrect)
+* [yaml-peg](https://github.com/aofdev/yaml-peg)
+* [qubit](https://github.com/abhimanyu003/qubit)
+* [caith](https://github.com/Geobert/caith) (a dice roller crate)
+* [Melody](https://github.com/yoav-lavi/melody)
+
+## Minimum Supported Rust Version (MSRV)
+
+This library should always compile with default features on **Rust 1.56.1**
+or **Rust 1.61** with `const_prec_climber`.
## Special thanks
diff --git a/vendor/pest/examples/parens.rs b/vendor/pest/examples/parens.rs
index 2720f6346..566c119b4 100644
--- a/vendor/pest/examples/parens.rs
+++ b/vendor/pest/examples/parens.rs
@@ -19,7 +19,7 @@ struct ParenParser;
impl Parser<Rule> for ParenParser {
fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
fn expr(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
- state.sequence(|s| s.repeat(|s| paren(s)).and_then(|s| s.end_of_input()))
+ state.sequence(|s| s.repeat(paren).and_then(|s| s.end_of_input()))
}
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
@@ -30,7 +30,7 @@ impl Parser<Rule> for ParenParser {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
- .and_then(|s| s.repeat(|s| paren(s)))
+ .and_then(|s| s.repeat(paren))
})
})
})
diff --git a/vendor/pest/src/error.rs b/vendor/pest/src/error.rs
index d6b76a82a..a83e23a49 100644
--- a/vendor/pest/src/error.rs
+++ b/vendor/pest/src/error.rs
@@ -9,17 +9,23 @@
//! Types for different kinds of parsing failures.
-use std::cmp;
-use std::error;
-use std::fmt;
-use std::mem;
-
-use position::Position;
-use span::Span;
-use RuleType;
+use alloc::borrow::Cow;
+use alloc::borrow::ToOwned;
+use alloc::format;
+use alloc::string::String;
+use alloc::string::ToString;
+use alloc::vec::Vec;
+use core::cmp;
+use core::fmt;
+use core::mem;
+
+use crate::position::Position;
+use crate::span::Span;
+use crate::RuleType;
/// Parse-related error type.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub struct Error<R> {
/// Variant of the error
pub variant: ErrorVariant<R>,
@@ -34,6 +40,7 @@ pub struct Error<R> {
/// Different kinds of parsing errors.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum ErrorVariant<R> {
/// Generated parsing error with expected and unexpected `Rule`s
ParsingError {
@@ -94,13 +101,19 @@ impl<R: RuleType> Error<R> {
///
/// println!("{}", error);
/// ```
- #[allow(clippy::needless_pass_by_value)]
pub fn new_from_pos(variant: ErrorVariant<R>, pos: Position) -> Error<R> {
+ let visualize_ws = pos.match_char('\n') || pos.match_char('\r');
+ let line_of = pos.line_of();
+ let line = if visualize_ws {
+ visualize_whitespace(line_of)
+ } else {
+ line_of.replace(&['\r', '\n'][..], "")
+ };
Error {
variant,
location: InputLocation::Pos(pos.pos()),
path: None,
- line: visualize_whitespace(pos.line_of()),
+ line,
continued_line: None,
line_col: LineColLocation::Pos(pos.line_col()),
}
@@ -134,22 +147,33 @@ impl<R: RuleType> Error<R> {
///
/// println!("{}", error);
/// ```
- #[allow(clippy::needless_pass_by_value)]
pub fn new_from_span(variant: ErrorVariant<R>, span: Span) -> Error<R> {
let end = span.end_pos();
-
let mut end_line_col = end.line_col();
// end position is after a \n, so we want to point to the visual lf symbol
if end_line_col.1 == 1 {
- let mut visual_end = end.clone();
+ let mut visual_end = end;
visual_end.skip_back(1);
let lc = visual_end.line_col();
end_line_col = (lc.0, lc.1 + 1);
};
let mut line_iter = span.lines();
- let start_line = visualize_whitespace(line_iter.next().unwrap_or(""));
- let continued_line = line_iter.last().map(visualize_whitespace);
+ let sl = line_iter.next().unwrap_or("");
+ let mut chars = span.as_str().chars();
+ let visualize_ws = matches!(chars.next(), Some('\n') | Some('\r'))
+ || matches!(chars.last(), Some('\n') | Some('\r'));
+ let start_line = if visualize_ws {
+ visualize_whitespace(sl)
+ } else {
+ sl.to_owned().replace(&['\r', '\n'][..], "")
+ };
+ let ll = line_iter.last();
+ let continued_line = if visualize_ws {
+ ll.map(&str::to_owned)
+ } else {
+ ll.map(visualize_whitespace)
+ };
Error {
variant,
@@ -191,6 +215,40 @@ impl<R: RuleType> Error<R> {
self
}
+ /// Returns the path set using [`Error::with_path()`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use pest::error::{Error, ErrorVariant};
+ /// # use pest::Position;
+ /// # #[allow(non_camel_case_types)]
+ /// # #[allow(dead_code)]
+ /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ /// # enum Rule {
+ /// # open_paren,
+ /// # closed_paren
+ /// # }
+ /// # let input = "";
+ /// # let pos = Position::from_start(input);
+ /// # let error = Error::new_from_pos(
+ /// # ErrorVariant::ParsingError {
+ /// # positives: vec![Rule::open_paren],
+ /// # negatives: vec![Rule::closed_paren]
+ /// # },
+ /// # pos);
+ /// let error = error.with_path("file.rs");
+ /// assert_eq!(Some("file.rs"), error.path());
+ /// ```
+ pub fn path(&self) -> Option<&str> {
+ self.path.as_deref()
+ }
+
+ /// Returns the line that the error is on.
+ pub fn line(&self) -> &str {
+ self.line.as_str()
+ }
+
/// Renames all `Rule`s if this is a [`ParsingError`]. It does nothing when called on a
/// [`CustomError`].
///
@@ -297,14 +355,12 @@ impl<R: RuleType> Error<R> {
}
if let Some(end) = end {
+ underline.push('^');
if end - start > 1 {
- underline.push('^');
for _ in 2..(end - start) {
underline.push('-');
}
underline.push('^');
- } else {
- underline.push('^');
}
} else {
underline.push_str("^---")
@@ -314,13 +370,7 @@ impl<R: RuleType> Error<R> {
}
fn message(&self) -> String {
- match self.variant {
- ErrorVariant::ParsingError {
- ref positives,
- ref negatives,
- } => Error::parsing_error_message(positives, negatives, |r| format!("{:?}", r)),
- ErrorVariant::CustomError { ref message } => message.clone(),
- }
+ self.variant.message().to_string()
}
fn parsing_error_message<F>(positives: &[R], negatives: &[R], mut f: F) -> String
@@ -347,13 +397,14 @@ impl<R: RuleType> Error<R> {
1 => f(&rules[0]),
2 => format!("{} or {}", f(&rules[0]), f(&rules[1])),
l => {
+ let non_separated = f(&rules[l - 1]);
let separated = rules
.iter()
.take(l - 1)
- .map(|r| f(r))
+ .map(f)
.collect::<Vec<_>>()
.join(", ");
- format!("{}, or {}", separated, f(&rules[l - 1]))
+ format!("{}, or {}", separated, non_separated)
}
}
}
@@ -431,17 +482,53 @@ impl<R: RuleType> Error<R> {
}
}
+impl<R: RuleType> ErrorVariant<R> {
+ ///
+ /// Returns the error message for [`ErrorVariant`]
+ ///
+ /// If [`ErrorVariant`] is [`CustomError`], it returns a
+ /// [`Cow::Borrowed`] reference to [`message`]. If [`ErrorVariant`] is [`ParsingError`], a
+ /// [`Cow::Owned`] containing "expected [ErrorVariant::ParsingError::positives] [ErrorVariant::ParsingError::negatives]" is returned.
+ ///
+ /// [`ErrorVariant`]: enum.ErrorVariant.html
+ /// [`CustomError`]: enum.ErrorVariant.html#variant.CustomError
+ /// [`ParsingError`]: enum.ErrorVariant.html#variant.ParsingError
+ /// [`Cow::Owned`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html#variant.Owned
+ /// [`Cow::Borrowed`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html#variant.Borrowed
+ /// [`message`]: enum.ErrorVariant.html#variant.CustomError.field.message
+ /// # Examples
+ ///
+ /// ```
+ /// # use pest::error::ErrorVariant;
+ /// let variant = ErrorVariant::<()>::CustomError {
+ /// message: String::from("unexpected error")
+ /// };
+ ///
+ /// println!("{}", variant.message());
+ pub fn message(&self) -> Cow<str> {
+ match self {
+ ErrorVariant::ParsingError {
+ ref positives,
+ ref negatives,
+ } => Cow::Owned(Error::parsing_error_message(positives, negatives, |r| {
+ format!("{:?}", r)
+ })),
+ ErrorVariant::CustomError { ref message } => Cow::Borrowed(message),
+ }
+ }
+}
+
impl<R: RuleType> fmt::Display for Error<R> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.format())
}
}
-impl<'i, R: RuleType> error::Error for Error<R> {
- fn description(&self) -> &str {
- match self.variant {
- ErrorVariant::ParsingError { .. } => "parsing error",
- ErrorVariant::CustomError { ref message } => message,
+impl<R: RuleType> fmt::Display for ErrorVariant<R> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ ErrorVariant::ParsingError { .. } => write!(f, "parsing error: {}", self.message()),
+ ErrorVariant::CustomError { .. } => write!(f, "{}", self.message()),
}
}
}
@@ -454,6 +541,7 @@ fn visualize_whitespace(input: &str) -> String {
mod tests {
use super::super::position;
use super::*;
+ use alloc::vec;
#[test]
fn display_parsing_error_mixed() {
@@ -472,7 +560,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = unexpected 4, 5, or 6; expected 1, 2, or 3",
@@ -498,7 +586,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = expected 1 or 2",
@@ -524,7 +612,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = unexpected 4, 5, or 6",
@@ -550,7 +638,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = unknown parsing error",
@@ -575,7 +663,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = error: big one",
@@ -601,7 +689,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
"3 | efgh",
" | ^^",
" |",
@@ -628,7 +716,7 @@ mod tests {
vec![
" --> 1:2",
" |",
- "1 | abâŠ",
+ "1 | ab",
" | ...",
"3 | efgh",
" | ^^",
@@ -656,7 +744,7 @@ mod tests {
vec![
" --> 1:6",
" |",
- "1 | abcdefâŠ",
+ "1 | abcdef",
"2 | gh",
" | ^----^",
" |",
@@ -742,7 +830,7 @@ mod tests {
vec![
" --> 2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = unexpected 5, 6, or 7; expected 2, 3, or 4",
@@ -769,7 +857,7 @@ mod tests {
vec![
" --> file.rs:2:2",
" |",
- "2 | cdâŠ",
+ "2 | cd",
" | ^---",
" |",
" = unexpected 4, 5, or 6; expected 1, 2, or 3",
diff --git a/vendor/pest/src/iterators/flat_pairs.rs b/vendor/pest/src/iterators/flat_pairs.rs
index bb5bbb185..85171a3b6 100644
--- a/vendor/pest/src/iterators/flat_pairs.rs
+++ b/vendor/pest/src/iterators/flat_pairs.rs
@@ -7,13 +7,14 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::fmt;
-use std::rc::Rc;
+use alloc::rc::Rc;
+use alloc::vec::Vec;
+use core::fmt;
use super::pair::{self, Pair};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
-use RuleType;
+use crate::RuleType;
/// An iterator over [`Pair`]s. It is created by [`Pairs::flatten`].
///
@@ -151,6 +152,8 @@ impl<'i, R: Clone> Clone for FlatPairs<'i, R> {
mod tests {
use super::super::super::macros::tests::*;
use super::super::super::Parser;
+ use alloc::vec;
+ use alloc::vec::Vec;
#[test]
fn iter_for_flat_pairs() {
diff --git a/vendor/pest/src/iterators/pair.rs b/vendor/pest/src/iterators/pair.rs
index 88844a353..0a8f735a4 100644
--- a/vendor/pest/src/iterators/pair.rs
+++ b/vendor/pest/src/iterators/pair.rs
@@ -7,11 +7,15 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ptr;
-use std::rc::Rc;
-use std::str;
+use alloc::format;
+use alloc::rc::Rc;
+#[cfg(feature = "pretty-print")]
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::fmt;
+use core::hash::{Hash, Hasher};
+use core::ptr;
+use core::str;
#[cfg(feature = "pretty-print")]
use serde::ser::SerializeStruct;
@@ -19,8 +23,8 @@ use serde::ser::SerializeStruct;
use super::pairs::{self, Pairs};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
-use span::{self, Span};
-use RuleType;
+use crate::span::{self, Span};
+use crate::RuleType;
/// A matching pair of [`Token`]s and everything between them.
///
@@ -343,8 +347,8 @@ impl<'i, R: RuleType> ::serde::Serialize for Pair<'i, R> {
#[cfg(test)]
mod tests {
- use macros::tests::*;
- use parser::Parser;
+ use crate::macros::tests::*;
+ use crate::parser::Parser;
#[test]
#[cfg(feature = "pretty-print")]
diff --git a/vendor/pest/src/iterators/pairs.rs b/vendor/pest/src/iterators/pairs.rs
index abae123e1..654b7dade 100644
--- a/vendor/pest/src/iterators/pairs.rs
+++ b/vendor/pest/src/iterators/pairs.rs
@@ -7,11 +7,14 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ptr;
-use std::rc::Rc;
-use std::str;
+use alloc::format;
+use alloc::rc::Rc;
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::fmt;
+use core::hash::{Hash, Hasher};
+use core::ptr;
+use core::str;
#[cfg(feature = "pretty-print")]
use serde::ser::SerializeStruct;
@@ -20,7 +23,7 @@ use super::flat_pairs::{self, FlatPairs};
use super::pair::{self, Pair};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
-use RuleType;
+use crate::RuleType;
/// An iterator over [`Pair`]s. It is created by [`pest::state`] and [`Pair::into_inner`].
///
@@ -302,6 +305,10 @@ impl<'i, R: RuleType> ::serde::Serialize for Pairs<'i, R> {
mod tests {
use super::super::super::macros::tests::*;
use super::super::super::Parser;
+ use alloc::borrow::ToOwned;
+ use alloc::format;
+ use alloc::vec;
+ use alloc::vec::Vec;
#[test]
#[cfg(feature = "pretty-print")]
diff --git a/vendor/pest/src/iterators/tokens.rs b/vendor/pest/src/iterators/tokens.rs
index 59b75c520..f21cf072c 100644
--- a/vendor/pest/src/iterators/tokens.rs
+++ b/vendor/pest/src/iterators/tokens.rs
@@ -7,14 +7,15 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::fmt;
-use std::rc::Rc;
-use std::str;
+use alloc::rc::Rc;
+use alloc::vec::Vec;
+use core::fmt;
+use core::str;
use super::queueable_token::QueueableToken;
-use position;
-use token::Token;
-use RuleType;
+use crate::position;
+use crate::token::Token;
+use crate::RuleType;
/// An iterator over [`Token`]s. It is created by [`Pair::tokens`] and [`Pairs::tokens`].
///
@@ -132,6 +133,7 @@ mod tests {
use super::super::super::macros::tests::*;
use super::super::super::Parser;
use super::Token;
+ use alloc::vec::Vec;
#[test]
fn double_ended_iter_for_tokens() {
diff --git a/vendor/pest/src/lib.rs b/vendor/pest/src/lib.rs
index c55518c25..30f87db60 100644
--- a/vendor/pest/src/lib.rs
+++ b/vendor/pest/src/lib.rs
@@ -6,6 +6,7 @@
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
+#![no_std]
//! # pest. The Elegant Parser
//!
@@ -63,6 +64,9 @@
#![doc(html_root_url = "https://docs.rs/pest")]
+extern crate alloc;
+#[cfg(feature = "std")]
+extern crate std;
extern crate ucd_trie;
#[cfg(feature = "pretty-print")]
@@ -70,13 +74,15 @@ extern crate serde;
#[cfg(feature = "pretty-print")]
extern crate serde_json;
-pub use parser::Parser;
-pub use parser_state::{state, Atomicity, Lookahead, MatchDir, ParseResult, ParserState};
-pub use position::Position;
-pub use span::{Lines, Span};
-use std::fmt::Debug;
-use std::hash::Hash;
-pub use token::Token;
+pub use crate::parser::Parser;
+pub use crate::parser_state::{
+ set_call_limit, state, Atomicity, Lookahead, MatchDir, ParseResult, ParserState,
+};
+pub use crate::position::Position;
+pub use crate::span::{Lines, LinesSpan, Span};
+pub use crate::token::Token;
+use core::fmt::Debug;
+use core::hash::Hash;
pub mod error;
pub mod iterators;
diff --git a/vendor/pest/src/macros.rs b/vendor/pest/src/macros.rs
index 01f410610..6f5c4c6eb 100644
--- a/vendor/pest/src/macros.rs
+++ b/vendor/pest/src/macros.rs
@@ -16,28 +16,25 @@ macro_rules! consumes_to {
$rules::$name, $start);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::Start { rule, pos } => {
- let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $start {
- panic!("{}", message);
- }
+ assert!(
+ rule == $rules::$name && pos.pos() == $start,
+ "{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ )
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
$rules::$name, $end);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::End { rule, pos } => {
- let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $end {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $end,
+ "{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
};
( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr ),
@@ -47,28 +44,24 @@ macro_rules! consumes_to {
$rules::$name, $start);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::Start { rule, pos } => {
- let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $start {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $start,
+ "{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
$rules::$name, $end);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::End { rule, pos } => {
- let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $end {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $end,
+ "{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
@@ -79,14 +72,12 @@ macro_rules! consumes_to {
$rules::$name, $start);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::Start { rule, pos } => {
- let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $start {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $start,
+ "{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
@@ -95,14 +86,12 @@ macro_rules! consumes_to {
$rules::$name, $end);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::End { rule, pos } => {
- let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $end {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $end,
+ "{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
};
( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr,
@@ -114,14 +103,12 @@ macro_rules! consumes_to {
$rules::$name, $start);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::Start { rule, pos } => {
- let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $start {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $start,
+ "{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
consumes_to!($rules, $tokens, [ $( $nested_names $nested_calls ),* ]);
@@ -130,14 +117,12 @@ macro_rules! consumes_to {
$rules::$name, $end);
match $tokens.next().expect(&format!("{} but found nothing", expected)) {
$crate::Token::End { rule, pos } => {
- let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
- expected, rule, pos.pos());
-
- if rule != $rules::$name || pos.pos() != $end {
- panic!("{}", message);
- }
+ assert!(rule == $rules::$name && pos.pos() == $end,
+ "{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
+ expected, rule, pos.pos(),
+ );
},
- token => panic!("{}", format!("{} but found {:?}", expected, token))
+ token => panic!("{} but found {:?}", expected, token)
};
consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
@@ -229,11 +214,11 @@ macro_rules! parses_to {
) => {
assert!(
format!("{:?}", first_rule) == "EOI",
- format!("expected end of input, but found {:?}", rest)
+ "expected end of input, but found {:?}", rest
);
assert!(
format!("{:?}", second_rule) == "EOI",
- format!("expected end of input, but found {:?}", rest)
+ "expected end of input, but found {:?}", rest
);
}
_ => panic!("expected end of input, but found {:?}", rest)
@@ -253,7 +238,7 @@ macro_rules! parses_to {
/// * `input` - input to be tested against
/// * `rule` - `Rule` which will be run
/// * `positives` - positive `Rule` attempts that failed
-/// * `negative` - negative `Rule` attempts that failed
+/// * `negatives` - negative `Rule` attempts that failed
/// * `pos` - byte position of failure
///
/// # Examples
@@ -315,14 +300,14 @@ macro_rules! fails_with {
positives,
negatives,
} => {
- assert_eq!(positives, $positives);
- assert_eq!(negatives, $negatives);
+ assert_eq!(positives, $positives, "positives");
+ assert_eq!(negatives, $negatives, "negatives");
}
_ => unreachable!(),
};
match error.location {
- $crate::error::InputLocation::Pos(pos) => assert_eq!(pos, $pos),
+ $crate::error::InputLocation::Pos(pos) => assert_eq!(pos, $pos, "pos"),
_ => unreachable!(),
}
}
@@ -334,6 +319,9 @@ pub mod tests {
use super::super::error::Error;
use super::super::iterators::Pairs;
use super::super::{state, Parser};
+ use alloc::format;
+ use alloc::vec;
+ use alloc::vec::Vec;
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -346,7 +334,7 @@ pub mod tests {
pub struct AbcParser;
impl Parser<Rule> for AbcParser {
- fn parse<'i>(_: Rule, input: &'i str) -> Result<Pairs<'i, Rule>, Error<Rule>> {
+ fn parse(_: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
state(input, |state| {
state
.rule(Rule::a, |s| {
diff --git a/vendor/pest/src/parser.rs b/vendor/pest/src/parser.rs
index a8792d152..8dd381419 100644
--- a/vendor/pest/src/parser.rs
+++ b/vendor/pest/src/parser.rs
@@ -7,9 +7,9 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use error::Error;
-use iterators::Pairs;
-use RuleType;
+use crate::error::Error;
+use crate::iterators::Pairs;
+use crate::RuleType;
/// A trait with a single method that parses strings.
pub trait Parser<R: RuleType> {
diff --git a/vendor/pest/src/parser_state.rs b/vendor/pest/src/parser_state.rs
index 09bc92710..a4422e866 100644
--- a/vendor/pest/src/parser_state.rs
+++ b/vendor/pest/src/parser_state.rs
@@ -7,15 +7,21 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::ops::Range;
-use std::rc::Rc;
-
-use error::{Error, ErrorVariant};
-use iterators::{pairs, QueueableToken};
-use position::{self, Position};
-use span::Span;
-use stack::Stack;
-use RuleType;
+use alloc::borrow::ToOwned;
+use alloc::boxed::Box;
+use alloc::rc::Rc;
+use alloc::vec;
+use alloc::vec::Vec;
+use core::num::NonZeroUsize;
+use core::ops::Range;
+use core::sync::atomic::{AtomicUsize, Ordering};
+
+use crate::error::{Error, ErrorVariant};
+use crate::iterators::{pairs, QueueableToken};
+use crate::position::{self, Position};
+use crate::span::Span;
+use crate::stack::Stack;
+use crate::RuleType;
/// The current lookahead status of a [`ParserState`].
///
@@ -47,6 +53,49 @@ pub enum MatchDir {
TopToBottom,
}
+static CALL_LIMIT: AtomicUsize = AtomicUsize::new(0);
+
+/// Sets the maximum call limit for the parser state
+/// to prevent stack overflows or excessive execution times
+/// in some grammars.
+/// If set, the calls are tracked as a running total
+/// over all non-terminal rules that can nest closures
+/// (which are passed to transform the parser state).
+///
+/// # Arguments
+///
+/// * `limit` - The maximum number of calls. If None,
+/// the number of calls is unlimited.
+pub fn set_call_limit(limit: Option<NonZeroUsize>) {
+ CALL_LIMIT.store(limit.map(|f| f.get()).unwrap_or(0), Ordering::Relaxed);
+}
+
+#[derive(Debug)]
+struct CallLimitTracker {
+ current_call_limit: Option<(usize, usize)>,
+}
+
+impl Default for CallLimitTracker {
+ fn default() -> Self {
+ let limit = CALL_LIMIT.load(Ordering::Relaxed);
+ let current_call_limit = if limit > 0 { Some((0, limit)) } else { None };
+ Self { current_call_limit }
+ }
+}
+
+impl CallLimitTracker {
+ fn limit_reached(&self) -> bool {
+ self.current_call_limit
+ .map_or(false, |(current, limit)| current >= limit)
+ }
+
+ fn increment_depth(&mut self) {
+ if let Some((current, _)) = &mut self.current_call_limit {
+ *current += 1;
+ }
+ }
+}
+
/// The complete state of a [`Parser`].
///
/// [`Parser`]: trait.Parser.html
@@ -60,6 +109,7 @@ pub struct ParserState<'i, R: RuleType> {
attempt_pos: usize,
atomicity: Atomicity,
stack: Stack<Span<'i>>,
+ call_tracker: CallLimitTracker,
}
/// Creates a `ParserState` from a `&str`, supplying it to a closure `f`.
@@ -83,16 +133,23 @@ where
Ok(pairs::new(Rc::new(state.queue), input, 0, len))
}
Err(mut state) => {
- state.pos_attempts.sort();
- state.pos_attempts.dedup();
- state.neg_attempts.sort();
- state.neg_attempts.dedup();
-
- Err(Error::new_from_pos(
+ let variant = if state.reached_call_limit() {
+ ErrorVariant::CustomError {
+ message: "call limit reached".to_owned(),
+ }
+ } else {
+ state.pos_attempts.sort();
+ state.pos_attempts.dedup();
+ state.neg_attempts.sort();
+ state.neg_attempts.dedup();
ErrorVariant::ParsingError {
positives: state.pos_attempts.clone(),
negatives: state.neg_attempts.clone(),
- },
+ }
+ };
+
+ Err(Error::new_from_pos(
+ variant,
// TODO(performance): Guarantee state.attempt_pos is a valid position
position::Position::new(input, state.attempt_pos).unwrap(),
))
@@ -111,7 +168,6 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// let input = "";
/// let state: Box<pest::ParserState<&str>> = pest::ParserState::new(input);
/// ```
- #[allow(clippy::new_ret_no_self)]
pub fn new(input: &'i str) -> Box<Self> {
Box::new(ParserState {
position: Position::from_start(input),
@@ -122,6 +178,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
attempt_pos: 0,
atomicity: Atomicity::NonAtomic,
stack: Stack::new(),
+ call_tracker: Default::default(),
})
}
@@ -168,6 +225,20 @@ impl<'i, R: RuleType> ParserState<'i, R> {
self.atomicity
}
+ #[inline]
+ fn inc_call_check_limit(mut self: Box<Self>) -> ParseResult<Box<Self>> {
+ if self.call_tracker.limit_reached() {
+ return Err(self);
+ }
+ self.call_tracker.increment_depth();
+ Ok(self)
+ }
+
+ #[inline]
+ fn reached_call_limit(&self) -> bool {
+ self.call_tracker.limit_reached()
+ }
+
/// Wrapper needed to generate tokens. This will associate the `R` type rule to the closure
/// meant to match the rule.
///
@@ -193,6 +264,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
where
F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>,
{
+ self = self.inc_call_check_limit()?;
let actual_pos = self.position.pos();
let index = self.queue.len();
@@ -357,12 +429,13 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// assert_eq!(pairs.len(), 0);
/// ```
#[inline]
- pub fn sequence<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
+ pub fn sequence<F>(mut self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>,
{
+ self = self.inc_call_check_limit()?;
let token_index = self.queue.len();
- let initial_pos = self.position.clone();
+ let initial_pos = self.position;
let result = f(self);
@@ -406,10 +479,11 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// assert_eq!(result.unwrap().position().pos(), 0);
/// ```
#[inline]
- pub fn repeat<F>(self: Box<Self>, mut f: F) -> ParseResult<Box<Self>>
+ pub fn repeat<F>(mut self: Box<Self>, mut f: F) -> ParseResult<Box<Self>>
where
F: FnMut(Box<Self>) -> ParseResult<Box<Self>>,
{
+ self = self.inc_call_check_limit()?;
let mut result = f(self);
loop {
@@ -447,10 +521,11 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// assert!(result.is_ok());
/// ```
#[inline]
- pub fn optional<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
+ pub fn optional<F>(mut self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>,
{
+ self = self.inc_call_check_limit()?;
match f(self) {
Ok(state) | Err(state) => Ok(state),
}
@@ -728,6 +803,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
where
F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>,
{
+ self = self.inc_call_check_limit()?;
let initial_lookahead = self.lookahead;
self.lookahead = if is_positive {
@@ -742,7 +818,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
}
};
- let initial_pos = self.position.clone();
+ let initial_pos = self.position;
let result = f(self.checkpoint());
@@ -795,6 +871,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
where
F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>,
{
+ self = self.inc_call_check_limit()?;
let initial_atomicity = self.atomicity;
let should_toggle = self.atomicity != atomicity;
@@ -839,17 +916,18 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// assert_eq!(result.unwrap().position().pos(), 1);
/// ```
#[inline]
- pub fn stack_push<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
+ pub fn stack_push<F>(mut self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>,
{
- let start = self.position.clone();
+ self = self.inc_call_check_limit()?;
+ let start = self.position;
let result = f(self);
match result {
Ok(mut state) => {
- let end = state.position.clone();
+ let end = state.position;
state.stack.push(start.span(&end));
Ok(state)
}
@@ -955,7 +1033,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
return Ok(self);
}
- let mut position = self.position.clone();
+ let mut position = self.position;
let result = {
let mut iter_b2t = self.stack[range].iter();
let matcher = |span: &Span| position.match_string(span.as_str());
@@ -1016,7 +1094,7 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// ```
#[inline]
pub fn stack_match_pop(mut self: Box<Self>) -> ParseResult<Box<Self>> {
- let mut position = self.position.clone();
+ let mut position = self.position;
let mut result = true;
while let Some(span) = self.stack.pop() {
result = position.match_string(span.as_str());
diff --git a/vendor/pest/src/position.rs b/vendor/pest/src/position.rs
index 76e3383ba..c76589856 100644
--- a/vendor/pest/src/position.rs
+++ b/vendor/pest/src/position.rs
@@ -7,17 +7,17 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::cmp::Ordering;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ops::Range;
-use std::ptr;
-use std::str;
+use core::cmp::Ordering;
+use core::fmt;
+use core::hash::{Hash, Hasher};
+use core::ops::Range;
+use core::ptr;
+use core::str;
-use span;
+use crate::span;
/// A cursor position in a `&str` which provides useful methods to manually parse that string.
-#[derive(Clone)]
+#[derive(Clone, Copy)]
pub struct Position<'i> {
input: &'i str,
/// # Safety:
@@ -49,7 +49,6 @@ impl<'i> Position<'i> {
/// assert_eq!(Position::new(heart, 1), None);
/// assert_ne!(Position::new(heart, cheart.len_utf8()), None);
/// ```
- #[allow(clippy::new_ret_no_self)]
pub fn new(input: &str, pos: usize) -> Option<Position> {
input.get(pos..).map(|_| Position { input, pos })
}
@@ -318,6 +317,14 @@ impl<'i> Position<'i> {
false
}
+ /// Matches the char at the `Position` against a specified character and returns `true` if a match
+ /// was made. If no match was made, returns `false`.
+ /// `pos` will not be updated in either case.
+ #[inline]
+ pub(crate) fn match_char(&self, c: char) -> bool {
+ matches!(self.input[self.pos..].chars().next(), Some(cc) if c == cc)
+ }
+
/// Matches the char at the `Position` against a filter function and returns `true` if a match
/// was made. If no match was made, returns `false` and `pos` will not be updated.
#[inline]
@@ -427,23 +434,21 @@ impl<'i> Hash for Position<'i> {
#[cfg(test)]
mod tests {
- use std::collections::HashSet;
-
use super::*;
#[test]
fn empty() {
let input = "";
- assert_eq!(Position::new(input, 0).unwrap().match_string(""), true);
- assert_eq!(!Position::new(input, 0).unwrap().match_string("a"), true);
+ assert!(Position::new(input, 0).unwrap().match_string(""));
+ assert!(!Position::new(input, 0).unwrap().match_string("a"));
}
#[test]
fn parts() {
let input = "asdasdf";
- assert_eq!(Position::new(input, 0).unwrap().match_string("asd"), true);
- assert_eq!(Position::new(input, 3).unwrap().match_string("asdf"), true);
+ assert!(Position::new(input, 0).unwrap().match_string("asd"));
+ assert!(Position::new(input, 3).unwrap().match_string("asdf"));
}
#[test]
@@ -530,23 +535,23 @@ mod tests {
let input = "ab ac";
let pos = Position::from_start(input);
- let mut test_pos = pos.clone();
+ let mut test_pos = pos;
test_pos.skip_until(&["a", "b"]);
assert_eq!(test_pos.pos(), 0);
- test_pos = pos.clone();
+ test_pos = pos;
test_pos.skip_until(&["b"]);
assert_eq!(test_pos.pos(), 1);
- test_pos = pos.clone();
+ test_pos = pos;
test_pos.skip_until(&["ab"]);
assert_eq!(test_pos.pos(), 0);
- test_pos = pos.clone();
+ test_pos = pos;
test_pos.skip_until(&["ac", "z"]);
assert_eq!(test_pos.pos(), 3);
- test_pos = pos.clone();
+ test_pos = pos;
assert!(!test_pos.skip_until(&["z"]));
assert_eq!(test_pos.pos(), 5);
}
@@ -555,41 +560,26 @@ mod tests {
fn match_range() {
let input = "b";
- assert_eq!(Position::new(input, 0).unwrap().match_range('a'..'c'), true);
- assert_eq!(Position::new(input, 0).unwrap().match_range('b'..'b'), true);
- assert_eq!(
- !Position::new(input, 0).unwrap().match_range('a'..'a'),
- true
- );
- assert_eq!(
- !Position::new(input, 0).unwrap().match_range('c'..'c'),
- true
- );
- assert_eq!(
- Position::new(input, 0).unwrap().match_range('a'..'å—¨'),
- true
- );
+ assert!(Position::new(input, 0).unwrap().match_range('a'..'c'));
+ assert!(Position::new(input, 0).unwrap().match_range('b'..'b'));
+ assert!(!Position::new(input, 0).unwrap().match_range('a'..'a'));
+ assert!(!Position::new(input, 0).unwrap().match_range('c'..'c'));
+ assert!(Position::new(input, 0).unwrap().match_range('a'..'å—¨'));
}
#[test]
fn match_insensitive() {
let input = "AsdASdF";
- assert_eq!(
- Position::new(input, 0).unwrap().match_insensitive("asd"),
- true
- );
- assert_eq!(
- Position::new(input, 3).unwrap().match_insensitive("asdf"),
- true
- );
+ assert!(Position::new(input, 0).unwrap().match_insensitive("asd"));
+ assert!(Position::new(input, 3).unwrap().match_insensitive("asdf"));
}
#[test]
fn cmp() {
let input = "a";
let start = Position::from_start(input);
- let mut end = start.clone();
+ let mut end = start;
assert!(end.skip(1));
let result = start.cmp(&end);
@@ -605,11 +595,14 @@ mod tests {
let pos1 = Position::from_start(input1);
let pos2 = Position::from_start(input2);
- pos1.cmp(&pos2);
+ let _ = pos1.cmp(&pos2);
}
#[test]
+ #[cfg(feature = "std")]
fn hash() {
+ use std::collections::HashSet;
+
let input = "a";
let start = Position::from_start(input);
let mut positions = HashSet::new();
diff --git a/vendor/pest/src/prec_climber.rs b/vendor/pest/src/prec_climber.rs
index d8bf0a08a..d35bd52db 100644
--- a/vendor/pest/src/prec_climber.rs
+++ b/vendor/pest/src/prec_climber.rs
@@ -9,12 +9,96 @@
//! Constructs useful in infix operator parsing with the precedence climbing method.
-use std::collections::HashMap;
-use std::iter::Peekable;
-use std::ops::BitOr;
+use alloc::borrow::Cow;
+use alloc::boxed::Box;
+use alloc::vec::Vec;
+use core::iter::Peekable;
+use core::ops::BitOr;
-use iterators::Pair;
-use RuleType;
+use crate::iterators::Pair;
+use crate::RuleType;
+
+/// Macro for more convenient const fn definition of `prec_climber::PrecClimber`.
+///
+/// # Examples
+///
+/// ```
+/// # use pest::prec_climber::{Assoc, PrecClimber};
+/// # use pest::prec_climber;
+/// # #[allow(non_camel_case_types)]
+/// # #[allow(dead_code)]
+/// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+/// # enum Rule {
+/// # plus,
+/// # minus,
+/// # times,
+/// # divide,
+/// # power
+/// # }
+/// static CLIMBER: PrecClimber<Rule> = prec_climber![
+/// L plus | minus,
+/// L times | divide,
+/// R power,
+/// ];
+/// ```
+#[cfg(feature = "const_prec_climber")]
+#[macro_export]
+macro_rules! prec_climber {
+ (
+ $( $assoc:ident $rule:ident $( | $rules:ident )* ),+ $(,)?
+ ) => {{
+ prec_climber!(
+ @precedences { 1u32 }
+ $( [ $rule $( $rules )* ] )*
+ );
+
+ $crate::prec_climber::PrecClimber::new_const(
+ prec_climber!(
+ @array
+ $( $assoc $rule $(, $assoc $rules )* ),*
+ )
+ )
+ }};
+
+ ( @assoc L ) => { $crate::prec_climber::Assoc::Left };
+ ( @assoc R ) => { $crate::prec_climber::Assoc::Right };
+
+ (
+ @array
+ $(
+ $assoc:ident $rule:ident
+ ),*
+ ) => {
+ &[
+ $(
+ (
+ Rule::$rule,
+ $rule,
+ prec_climber!( @assoc $assoc ),
+ )
+ ),*
+ ]
+ };
+
+ (
+ @precedences { $precedence:expr }
+ ) => {};
+
+ (
+ @precedences { $precedence:expr }
+ [ $( $rule:ident )* ]
+ $( [ $( $rules:ident )* ] )*
+ ) => {
+ $(
+ #[allow(non_upper_case_globals)]
+ const $rule: u32 = $precedence;
+ )*
+ prec_climber!(
+ @precedences { 1u32 + $precedence }
+ $( [ $( $rules )* ] )*
+ );
+ };
+}
/// Associativity of an [`Operator`].
///
@@ -86,11 +170,54 @@ impl<R: RuleType> BitOr for Operator<R> {
/// [1]: https://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing_method
/// [`Pairs`]: ../iterators/struct.Pairs.html
#[derive(Debug)]
-pub struct PrecClimber<R: RuleType> {
- ops: HashMap<R, (u32, Assoc)>,
+pub struct PrecClimber<R: Clone + 'static> {
+ ops: Cow<'static, [(R, u32, Assoc)]>,
+}
+
+#[cfg(feature = "const_prec_climber")]
+impl<R: Clone + 'static> PrecClimber<R> {
+ /// Creates a new `PrecClimber` directly from a static slice of
+ /// `(rule: Rule, precedence: u32, associativity: Assoc)` tuples.
+ ///
+ /// Precedence starts from `1`. Entries don't have to be ordered in any way, but it's easier to read when
+ /// sorted.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use pest::prec_climber::{Assoc, PrecClimber};
+ /// # #[allow(non_camel_case_types)]
+ /// # #[allow(dead_code)]
+ /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ /// # enum Rule {
+ /// # plus,
+ /// # minus,
+ /// # times,
+ /// # divide,
+ /// # power
+ /// # }
+ /// static CLIMBER: PrecClimber<Rule> = PrecClimber::new_const(&[
+ /// (Rule::plus, 1, Assoc::Left), (Rule::minus, 1, Assoc::Left),
+ /// (Rule::times, 2, Assoc::Left), (Rule::divide, 2, Assoc::Left),
+ /// (Rule::power, 3, Assoc::Right)
+ /// ]);
+ /// ```
+ pub const fn new_const(ops: &'static [(R, u32, Assoc)]) -> PrecClimber<R> {
+ PrecClimber {
+ ops: Cow::Borrowed(ops),
+ }
+ }
}
impl<R: RuleType> PrecClimber<R> {
+ // find matching operator by `rule`
+ fn get(&self, rule: &R) -> Option<(u32, Assoc)> {
+ self.ops
+ .iter()
+ .find(|(r, _, _)| r == rule)
+ .map(|(_, precedence, assoc)| (*precedence, *assoc))
+ }
+
/// Creates a new `PrecClimber` from the `Operator`s contained in `ops`. Every entry in the
/// `Vec` has precedence *index + 1*. In order to have operators with same precedence, they need
/// to be chained with `|` between them.
@@ -119,26 +246,26 @@ impl<R: RuleType> PrecClimber<R> {
let ops = ops
.into_iter()
.zip(1..)
- .fold(HashMap::new(), |mut map, (op, prec)| {
+ .fold(Vec::new(), |mut vec, (op, prec)| {
let mut next = Some(op);
while let Some(op) = next.take() {
- match op {
- Operator {
- rule,
- assoc,
- next: op_next,
- } => {
- map.insert(rule, (prec, assoc));
- next = op_next.map(|op| *op);
- }
- }
+ let Operator {
+ rule,
+ assoc,
+ next: op_next,
+ } = op;
+
+ vec.push((rule, prec, assoc));
+ next = op_next.map(|op| *op);
}
- map
+ vec
});
- PrecClimber { ops }
+ PrecClimber {
+ ops: Cow::Owned(ops),
+ }
}
/// Performs the precedence climbing algorithm on the `pairs` in a similar manner to map-reduce.
@@ -198,7 +325,7 @@ impl<R: RuleType> PrecClimber<R> {
{
while pairs.peek().is_some() {
let rule = pairs.peek().unwrap().as_rule();
- if let Some(&(prec, _)) = self.ops.get(&rule) {
+ if let Some((prec, _)) = self.get(&rule) {
if prec >= min_prec {
let op = pairs.next().unwrap();
let mut rhs = primary(pairs.next().expect(
@@ -208,7 +335,7 @@ impl<R: RuleType> PrecClimber<R> {
while pairs.peek().is_some() {
let rule = pairs.peek().unwrap().as_rule();
- if let Some(&(new_prec, assoc)) = self.ops.get(&rule) {
+ if let Some((new_prec, assoc)) = self.get(&rule) {
if new_prec > prec || assoc == Assoc::Right && new_prec == prec {
rhs = self.climb_rec(rhs, new_prec, pairs, primary, infix);
} else {
diff --git a/vendor/pest/src/span.rs b/vendor/pest/src/span.rs
index f8beffe26..4007049c7 100644
--- a/vendor/pest/src/span.rs
+++ b/vendor/pest/src/span.rs
@@ -7,18 +7,19 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ptr;
-use std::str;
+use core::fmt;
+use core::hash::{Hash, Hasher};
+use core::ops::{Bound, RangeBounds};
+use core::ptr;
+use core::str;
-use position;
+use crate::position;
/// A span over a `&str`. It is created from either [two `Position`s] or from a [`Pair`].
///
/// [two `Position`s]: struct.Position.html#method.span
/// [`Pair`]: ../iterators/struct.Pair.html#method.span
-#[derive(Clone)]
+#[derive(Clone, Copy)]
pub struct Span<'i> {
input: &'i str,
/// # Safety
@@ -53,7 +54,6 @@ impl<'i> Span<'i> {
/// assert_eq!(None, Span::new(input, 100, 0));
/// assert!(Span::new(input, 0, input.len()).is_some());
/// ```
- #[allow(clippy::new_ret_no_self)]
pub fn new(input: &str, start: usize, end: usize) -> Option<Span> {
if input.get(start..end).is_some() {
Some(Span { input, start, end })
@@ -62,6 +62,37 @@ impl<'i> Span<'i> {
}
}
+ /// Attempts to create a new span based on a sub-range.
+ ///
+ /// ```
+ /// use pest::Span;
+ /// let input = "Hello World!";
+ /// let world = Span::new(input, 6, input.len()).unwrap();
+ /// let orl = world.get(1..=3);
+ /// assert!(orl.is_some());
+ /// assert_eq!(orl.unwrap().as_str(), "orl");
+ /// ```
+ ///
+ /// # Examples
+ pub fn get(&self, range: impl RangeBounds<usize>) -> Option<Span<'i>> {
+ let start = match range.start_bound() {
+ Bound::Included(offset) => *offset,
+ Bound::Excluded(offset) => *offset + 1,
+ Bound::Unbounded => 0,
+ };
+ let end = match range.end_bound() {
+ Bound::Included(offset) => *offset + 1,
+ Bound::Excluded(offset) => *offset,
+ Bound::Unbounded => self.as_str().len(),
+ };
+
+ self.as_str().get(start..end).map(|_| Span {
+ input: self.input,
+ start: self.start + start,
+ end: self.start + end,
+ })
+ }
+
/// Returns the `Span`'s start byte position as a `usize`.
///
/// # Examples
@@ -181,7 +212,7 @@ impl<'i> Span<'i> {
&self.input[self.start..self.end]
}
- /// Iterates over all lines (partially) covered by this span.
+ /// Iterates over all lines (partially) covered by this span. Yielding a `&str` for each line.
///
/// # Examples
///
@@ -201,6 +232,30 @@ impl<'i> Span<'i> {
#[inline]
pub fn lines(&self) -> Lines {
Lines {
+ inner: self.lines_span(),
+ }
+ }
+
+ /// Iterates over all lines (partially) covered by this span. Yielding a `Span` for each line.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use pest;
+ /// # use pest::Span;
+ /// # #[allow(non_camel_case_types)]
+ /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ /// enum Rule {}
+ ///
+ /// let input = "a\nb\nc";
+ /// let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input).skip(2).unwrap();
+ /// let start_pos = state.position().clone();
+ /// state = state.match_string("b\nc").unwrap();
+ /// let span = start_pos.span(&state.position().clone());
+ /// assert_eq!(span.lines_span().collect::<Vec<_>>(), vec![Span::new(input, 2, 4).unwrap(), Span::new(input, 4, 5).unwrap()]);
+ /// ```
+ pub fn lines_span(&self) -> LinesSpan {
+ LinesSpan {
span: self,
pos: self.start,
}
@@ -233,19 +288,19 @@ impl<'i> Hash for Span<'i> {
}
}
-/// Line iterator for Spans, created by [`Span::lines()`].
+/// Line iterator for Spans, created by [`Span::lines_span()`].
///
-/// Iterates all lines that are at least partially covered by the span.
+/// Iterates all lines that are at least _partially_ covered by the span. Yielding a `Span` for each.
///
-/// [`Span::lines()`]: struct.Span.html#method.lines
-pub struct Lines<'i> {
+/// [`Span::lines_span()`]: struct.Span.html#method.lines_span
+pub struct LinesSpan<'i> {
span: &'i Span<'i>,
pos: usize,
}
-impl<'i> Iterator for Lines<'i> {
- type Item = &'i str;
- fn next(&mut self) -> Option<&'i str> {
+impl<'i> Iterator for LinesSpan<'i> {
+ type Item = Span<'i>;
+ fn next(&mut self) -> Option<Self::Item> {
if self.pos > self.span.end {
return None;
}
@@ -253,21 +308,91 @@ impl<'i> Iterator for Lines<'i> {
if pos.at_end() {
return None;
}
- let line = pos.line_of();
+
+ let line_start = pos.find_line_start();
self.pos = pos.find_line_end();
- Some(line)
+
+ Span::new(self.span.input, line_start, self.pos)
+ }
+}
+
+/// Line iterator for Spans, created by [`Span::lines()`].
+///
+/// Iterates all lines that are at least _partially_ covered by the span. Yielding a `&str` for each.
+///
+/// [`Span::lines()`]: struct.Span.html#method.lines
+pub struct Lines<'i> {
+ inner: LinesSpan<'i>,
+}
+
+impl<'i> Iterator for Lines<'i> {
+ type Item = &'i str;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next().map(|span| span.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
+ use alloc::borrow::ToOwned;
+ use alloc::vec::Vec;
+
+ #[test]
+ fn get() {
+ let input = "abc123abc";
+ let span = Span::new(input, 3, input.len()).unwrap();
+ assert_eq!(span.as_str(), "123abc");
+ assert_eq!(span.input, input);
+
+ let span1 = span.get(..=2);
+ assert!(span1.is_some());
+ assert_eq!(span1.unwrap().input, input);
+ assert_eq!(span1.unwrap().as_str(), "123");
+
+ let span2 = span.get(..);
+ assert!(span2.is_some());
+ assert_eq!(span2.unwrap().input, input);
+ assert_eq!(span2.unwrap().as_str(), "123abc");
+
+ let span3 = span.get(3..);
+ assert!(span3.is_some());
+ assert_eq!(span3.unwrap().input, input);
+ assert_eq!(span3.unwrap().as_str(), "abc");
+
+ let span4 = span.get(0..0);
+ assert!(span4.is_some());
+ assert_eq!(span4.unwrap().input, input);
+ assert_eq!(span4.unwrap().as_str(), "");
+ }
+
+ #[test]
+ fn get_fails() {
+ let input = "abc";
+ let span = Span::new(input, 0, input.len()).unwrap();
+
+ let span1 = span.get(0..100);
+ assert!(span1.is_none());
+
+ let span2 = span.get(100..200);
+ assert!(span2.is_none());
+ }
+
+ #[test]
+ fn span_comp() {
+ let input = "abc\ndef\nghi";
+ let span = Span::new(input, 1, 7).unwrap();
+ let span2 = Span::new(input, 50, 51);
+ assert!(span2.is_none());
+ let span3 = Span::new(input, 0, 8).unwrap();
+ assert!(span != span3);
+ }
#[test]
fn split() {
let input = "a";
let start = position::Position::from_start(input);
- let mut end = start.clone();
+ let mut end = start;
assert!(end.skip(1));
@@ -281,10 +406,12 @@ mod tests {
let input = "abc\ndef\nghi";
let span = Span::new(input, 1, 7).unwrap();
let lines: Vec<_> = span.lines().collect();
- println!("{:?}", lines);
+ let lines_span: Vec<_> = span.lines_span().map(|span| span.as_str()).collect();
+
assert_eq!(lines.len(), 2);
assert_eq!(lines[0], "abc\n".to_owned());
assert_eq!(lines[1], "def\n".to_owned());
+ assert_eq!(lines, lines_span) // Verify parity with lines_span()
}
#[test]
@@ -292,10 +419,32 @@ mod tests {
let input = "abc\ndef\nghi";
let span = Span::new(input, 5, 11).unwrap();
assert!(span.end_pos().at_end());
+ assert_eq!(span.end(), 11);
let lines: Vec<_> = span.lines().collect();
- println!("{:?}", lines);
+ let lines_span: Vec<_> = span.lines_span().map(|span| span.as_str()).collect();
+
assert_eq!(lines.len(), 2);
assert_eq!(lines[0], "def\n".to_owned());
assert_eq!(lines[1], "ghi".to_owned());
+ assert_eq!(lines, lines_span) // Verify parity with lines_span()
+ }
+
+ #[test]
+ fn lines_span() {
+ let input = "abc\ndef\nghi";
+ let span = Span::new(input, 1, 7).unwrap();
+ let lines_span: Vec<_> = span.lines_span().collect();
+ let lines: Vec<_> = span.lines().collect();
+
+ assert_eq!(lines_span.len(), 2);
+ assert_eq!(lines_span[0], Span::new(input, 0, 4).unwrap());
+ assert_eq!(lines_span[1], Span::new(input, 4, 8).unwrap());
+ assert_eq!(
+ lines_span
+ .iter()
+ .map(|span| span.as_str())
+ .collect::<Vec<_>>(),
+ lines
+ );
}
}
diff --git a/vendor/pest/src/stack.rs b/vendor/pest/src/stack.rs
index dede80f1e..05ac11f67 100644
--- a/vendor/pest/src/stack.rs
+++ b/vendor/pest/src/stack.rs
@@ -7,7 +7,9 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use std::ops::{Index, Range};
+use alloc::vec;
+use alloc::vec::Vec;
+use core::ops::{Index, Range};
/// Implementation of a `Stack` which maintains an log of `StackOp`s in order to rewind the stack
/// to a previous state.
diff --git a/vendor/pest/src/token.rs b/vendor/pest/src/token.rs
index fbe544ab8..68cb1a6ee 100644
--- a/vendor/pest/src/token.rs
+++ b/vendor/pest/src/token.rs
@@ -7,7 +7,7 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use position::Position;
+use crate::position::Position;
/// A token generated by a `Parser`.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
diff --git a/vendor/pest/src/unicode/binary.rs b/vendor/pest/src/unicode/binary.rs
index 8ee9c6f97..a6c7d1d83 100644
--- a/vendor/pest/src/unicode/binary.rs
+++ b/vendor/pest/src/unicode/binary.rs
@@ -1,23 +1,29 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate.exe property-bool --trie-set ./target/ucd/
+// ucd-generate property-bool --trie-set ./target/ucd/
//
-// ucd-generate is available on crates.io.
+// Unicode version: 14.0.0.
+//
+// ucd-generate 0.2.12 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static ::ucd_trie::TrieSet)] = &[
("ASCII_Hex_Digit", ASCII_HEX_DIGIT), ("Alphabetic", ALPHABETIC),
- ("Bidi_Control", BIDI_CONTROL), ("Case_Ignorable", CASE_IGNORABLE),
- ("Cased", CASED), ("Changes_When_Casefolded", CHANGES_WHEN_CASEFOLDED),
+ ("Bidi_Control", BIDI_CONTROL), ("Bidi_Mirrored", BIDI_MIRRORED),
+ ("Case_Ignorable", CASE_IGNORABLE), ("Cased", CASED),
+ ("Changes_When_Casefolded", CHANGES_WHEN_CASEFOLDED),
("Changes_When_Casemapped", CHANGES_WHEN_CASEMAPPED),
("Changes_When_Lowercased", CHANGES_WHEN_LOWERCASED),
("Changes_When_Titlecased", CHANGES_WHEN_TITLECASED),
("Changes_When_Uppercased", CHANGES_WHEN_UPPERCASED), ("Dash", DASH),
("Default_Ignorable_Code_Point", DEFAULT_IGNORABLE_CODE_POINT),
- ("Deprecated", DEPRECATED), ("Diacritic", DIACRITIC),
- ("Extender", EXTENDER), ("Grapheme_Base", GRAPHEME_BASE),
- ("Grapheme_Extend", GRAPHEME_EXTEND), ("Grapheme_Link", GRAPHEME_LINK),
- ("Hex_Digit", HEX_DIGIT), ("Hyphen", HYPHEN),
- ("IDS_Binary_Operator", IDS_BINARY_OPERATOR),
+ ("Deprecated", DEPRECATED), ("Diacritic", DIACRITIC), ("Emoji", EMOJI),
+ ("Emoji_Component", EMOJI_COMPONENT), ("Emoji_Modifier", EMOJI_MODIFIER),
+ ("Emoji_Modifier_Base", EMOJI_MODIFIER_BASE),
+ ("Emoji_Presentation", EMOJI_PRESENTATION),
+ ("Extended_Pictographic", EXTENDED_PICTOGRAPHIC), ("Extender", EXTENDER),
+ ("Grapheme_Base", GRAPHEME_BASE), ("Grapheme_Extend", GRAPHEME_EXTEND),
+ ("Grapheme_Link", GRAPHEME_LINK), ("Hex_Digit", HEX_DIGIT),
+ ("Hyphen", HYPHEN), ("IDS_Binary_Operator", IDS_BINARY_OPERATOR),
("IDS_Trinary_Operator", IDS_TRINARY_OPERATOR),
("ID_Continue", ID_CONTINUE), ("ID_Start", ID_START),
("Ideographic", IDEOGRAPHIC), ("Join_Control", JOIN_CONTROL),
@@ -77,10 +83,10 @@ pub const ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36,
36, 36, 37, 38, 39, 40, 41, 42, 43, 44, 36, 36, 36, 36, 36, 36, 36, 36,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 31, 63, 64, 65, 66, 55, 67, 68, 69, 36, 36, 36, 70, 36, 36, 36, 36, 71,
- 72, 73, 74, 31, 75, 76, 31, 77, 78, 79, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 80, 81, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 82, 83, 36,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 36, 36, 36, 72, 36, 36, 36, 36, 73,
+ 74, 75, 76, 31, 77, 78, 31, 79, 80, 81, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 82, 83, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, 36,
84, 85, 86, 87, 88, 89, 31, 31, 31, 31, 31, 31, 31, 90, 44, 91, 92, 93,
36, 94, 95, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -88,7 +94,8 @@ pub const ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 55, 31, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 31, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -106,10 +113,9 @@ pub const ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 96, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 97, 98, 36, 36, 36, 36, 99,
- 100, 36, 96, 101, 36, 102, 103, 104, 105, 36, 106, 107, 108, 109, 110,
- 111, 112, 113, 114, 115, 116, 36, 117, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 96, 97, 36, 36, 36, 36, 98,
+ 99, 36, 100, 101, 36, 102, 103, 104, 105, 36, 106, 107, 108, 109, 110, 68,
+ 111, 112, 113, 114, 115, 36, 116, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -119,60 +125,60 @@ pub const ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 118, 119, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 36, 36, 117, 118, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, 36, 36, 36, 120, 36,
- 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 127, 128, 129, 31, 130, 36,
- 131, 132, 133, 113, 134,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, 36, 36, 36, 119, 36, 120,
+ 121, 122, 123, 124, 36, 36, 36, 36, 125, 33, 126, 127, 31, 128, 36, 129,
+ 130, 131, 112, 132,
],
tree2_level2: &[
- 0x1FFFFCFFFFFF, 0x7FF01FFFFFF, 0x3FDFFFFF00000000, 0xFFFF03F8FFF00000,
- 0xEFFFFFFFFFFFFFFF, 0xFFFE000FFFE1DFFF, 0xE3C5FDFFFFF99FEF,
- 0x1003000FB080599F, 0xC36DFDFFFFF987EE, 0x3F00005E021987,
- 0xE3EDFDFFFFFBBFEE, 0x1E00000F00011BBF, 0xE3EDFDFFFFF99FEE,
- 0x2000FB0C0199F, 0xC3FFC718D63DC7EC, 0x811DC7, 0xE3FFFDFFFFFDDFEF,
- 0xF07601DDF, 0xE3EFFDFFFFFDDFEF, 0x6000F40601DDF, 0xE7FFFFFFFFFDDFEF,
- 0xFC00000F80F05DDF, 0x2FFBFFFFFC7FFFEC, 0xC0000FF5F807F,
- 0x7FFFFFFFFFFFFFE, 0x207F, 0x3BFFECAEFEF02596, 0xF000205F, 0x1,
- 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFF03, 0, 0xF97FFFFFFFFFFFFF,
- 0xFFFFC1E7FFFF0000, 0xFFFFFFFF3000407F, 0xF7FFFFFFFFFF20BF,
- 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF,
- 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x87FFFFFF, 0xFFFFFFFF0000FFFF,
- 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF,
- 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF, 0xFFFFF000FDFFF, 0xDDFFF000FFFFF,
- 0xFFCFFFFFFFFFFFFF, 0x108001FF, 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF,
- 0xFFFF07FFFFFFFFFF, 0x3FFFFFFFFFFFFF, 0x1FF0FFF7FFFFFFF, 0x1F3FFFFFFF0000,
- 0xFFFF0FFFFFFFFFFF, 0x3FF, 0xFFFFFFFF0FFFFFFF, 0x1FFFFE7FFFFFFF,
- 0x8000000000, 0xFFEFFFFFFFFFFFFF, 0xFEF, 0xFC00F3FFFFFFFFFF,
- 0x3FFBFFFFFFFFF, 0x3FFFFFFFFC00E000, 0xE7FFFFFFFFFF01FF, 0x6FDE0000000000,
- 0x1FFF8000000000, 0xFFFFFFFF3F3FFFFF, 0x3FFFFFFFAAFF3F3F,
- 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC, 0x8002000000000000, 0x1FFF0000,
- 0xF3FFBD503E2FFC84, 0xFFFFFFFF000043E0, 0x1FF, 0xFFC0000000000000,
- 0x3FFFFFFFFFF, 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0xC781FFFFFFFFF,
+ 0x1FFFFCFFFFFF, 0xFFFF07FF01FFFFFF, 0xFFFFFFFF00007EFF,
+ 0xFFFF03F8FFF003FF, 0xEFFFFFFFFFFFFFFF, 0xFFFE000FFFE1DFFF,
+ 0xE3C5FDFFFFF99FEF, 0x1003000FB080599F, 0xC36DFDFFFFF987EE,
+ 0x3F00005E021987, 0xE3EDFDFFFFFBBFEE, 0x1E00000F00011BBF,
+ 0xE3EDFDFFFFF99FEE, 0x2000FB0C0199F, 0xC3FFC718D63DC7EC, 0x811DC7,
+ 0xE3FFFDFFFFFDDFEF, 0xF27601DDF, 0xE3EFFDFFFFFDDFEF, 0x6000F60601DDF,
+ 0xE7FFFFFFFFFDDFFF, 0xFC00000F80F05DDF, 0x2FFBFFFFFC7FFFEE,
+ 0xC0000FF5F807F, 0x7FFFFFFFFFFFFFE, 0x207F, 0x3BFFFFAFFFFFF7D6,
+ 0xF000205F, 0x1, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFF03, 0,
+ 0xF97FFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFF3C00FFFF,
+ 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF,
+ 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF,
+ 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE,
+ 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF,
+ 0xFFFFF800FFFFF, 0xDDFFF000FFFFF, 0xFFCFFFFFFFFFFFFF, 0x108001FF,
+ 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF07FFFFFFFFFF,
+ 0x3FFFFFFFFFFFFF, 0x1FF0FFF7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF,
+ 0x3FF, 0xFFFFFFFF0FFFFFFF, 0x1FFFFE7FFFFFFF, 0x8000008000000000, 0x7001,
+ 0xFFEFFFFFFFFFFFFF, 0x1FEF, 0xFC00F3FFFFFFFFFF, 0x3FFBFFFFFFFFF,
+ 0x7FFFFFFFFFFFFF, 0x3FFFFFFFFC00E000, 0xE7FFFFFFFFFF01FF,
+ 0x46FDE0000000000, 0x1FFF8000000000, 0xFFFFFFFF3F3FFFFF,
+ 0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC,
+ 0x8002000000000000, 0x1FFF0000, 0xF3FFBD503E2FFC84, 0xFFFFFFFF000043E0,
+ 0x1FF, 0xFFC0000000000000, 0x3FFFFFFFFFF, 0xC781FFFFFFFFF,
0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF, 0x7F7F7F7F007FFFFF,
0xFFFFFFFF7F7F7F7F, 0x800000000000, 0x1F3E03FE000000E0,
0xFFFFFFFEE07FFFFF, 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0,
- 0x7FFFFFF00007FFF, 0xFFFF000000000000, 0xFFFFFFFFFFFF, 0x1FFF,
- 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF, 0x8FF07FFFFFFFFFFF, 0xFFFFFFFCFF800000,
- 0x3FFFFFFFFFFF9FF, 0xFF80000000000000, 0xFFFFFFF7BB, 0xFFFFFFFFFFFFF,
- 0x68FC00000000002F, 0xFFFF07FFFFFFFC00, 0x1FFFFFFF0007FFFF,
- 0xFFF7FFFFFFFFFFFF, 0x7C00FFDF00008000, 0x7FFFFFFFFFFFFF,
- 0xC47FFFFF00003FFF, 0x7FFFFFFFFFFFFFFF, 0x3CFFFF38000005,
- 0xFFFF7F7F007E7E7E, 0xFFFF003FF7FFFFFF, 0x7FFFFFFFFFF, 0xFFFF000FFFFFFFFF,
- 0xFFFFFFFFFFFF87F, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFDFFE0F8007F,
- 0xFFFFFFFFFFFFFFDB, 0x3FFFFFFFFFFFF, 0xFFFFFFFFFFF80000,
- 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF,
- 0xFFF0000000000FF, 0xFFDF000000000000, 0x1FFFFFFFFFFFFFFF,
- 0x7FFFFFE00000000, 0xFFFFFFC007FFFFFE, 0x1CFCFCFC,
+ 0xFFFFFFFF00007FFF, 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000,
+ 0xC00FFFF1FFF, 0x8FF07FFFFFFFFFFF, 0xFFFFFFFFFFFF, 0xFFFFFFFCFF800000,
+ 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0xFFFFFFFFBF, 0xFFFFFFFFFFFFF,
+ 0xE8FC00000000002F, 0xFFFF07FFFFFFFC00, 0x1FFFFFFF0007FFFF,
+ 0xFFF7FFFFFFFFFFFF, 0x7C00FFFF00008000, 0xFC7FFFFF00003FFF,
+ 0x7FFFFFFFFFFFFFFF, 0x3CFFFF38000005, 0xFFFF7F7F007E7E7E,
+ 0xFFFF03FFF7FFFFFF, 0x7FFFFFFFFFF, 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F,
+ 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFDFFE0F8007F, 0xFFFFFFFFFFFFFFDB,
+ 0x3FFFFFFFFFFFF, 0xFFFFFFFFFFF80000, 0x3FFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFCFFFF, 0xFFF0000000000FF, 0xFFDF000000000000,
+ 0x1FFFFFFFFFFFFFFF, 0x7FFFFFE00000000, 0xFFFFFFC007FFFFFE, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 13, 14, 15, 7, 16, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 5, 11, 12, 13, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 14, 15, 16, 7, 17, 18, 7, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -181,84 +187,97 @@ pub const ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
- 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4,
- 4, 2, 2, 2, 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27,
- 28, 29, 30, 4, 2, 31, 32, 32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 4, 2,
- 35, 36, 37, 32, 38, 2, 39, 40, 4, 41, 42, 43, 44, 4, 4, 2, 45, 2, 46, 4,
- 4, 47, 48, 49, 50, 28, 4, 51, 4, 4, 4, 52, 4, 53, 54, 4, 4, 4, 4, 55, 56,
- 57, 52, 4, 4, 4, 4, 58, 59, 60, 4, 61, 62, 63, 4, 4, 4, 4, 64, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 4, 2, 66, 2, 2, 2, 67, 4, 4,
+ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15,
+ 16, 4, 2, 2, 2, 2, 17, 18, 19, 4, 20, 21, 22, 23, 24, 4, 25, 4, 26, 27,
+ 28, 29, 30, 31, 32, 4, 2, 33, 34, 34, 35, 4, 4, 4, 4, 4, 36, 4, 37, 38,
+ 39, 40, 2, 41, 42, 43, 34, 44, 2, 45, 46, 4, 47, 48, 49, 50, 4, 4, 2, 51,
+ 2, 52, 4, 4, 53, 54, 55, 56, 57, 4, 58, 59, 4, 4, 60, 4, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 60, 4, 4, 4, 4, 70, 71, 72, 4, 73, 74, 75, 4, 4, 4, 4,
+ 76, 4, 4, 77, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 78, 4, 2, 79,
+ 2, 2, 2, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 68, 81, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 68, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 59, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 52, 20, 4, 69, 16, 70, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 2, 72,
- 73, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+ 2, 2, 2, 2, 2, 2, 2, 60, 82, 55, 83, 84, 85, 86, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 2, 4, 4, 2, 87, 88, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 75,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 76, 2, 2, 2, 2, 2, 77, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 91, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 78, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 80, 81, 82, 83, 84, 2, 2,
- 2, 2, 85, 86, 87, 88, 89, 90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 91, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 2, 2, 2, 92, 2, 93, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 94, 95, 96, 4, 4, 4, 4, 4, 4, 4, 4, 4, 76, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 92, 2, 2, 2, 2, 93, 94, 2, 2, 2, 2, 2, 95, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2,
+ 4, 4, 4, 4, 2, 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 98, 99, 100, 101, 102, 2, 2, 2, 2,
+ 103, 104, 105, 106, 107, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 4, 4, 4, 109, 4, 4, 4, 110,
+ 111, 4, 4, 4, 4, 83, 112, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 113, 2, 2, 2, 114, 2, 115, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 116, 117, 118, 4, 4, 4, 4, 4, 4, 4, 4, 4, 119, 120, 121, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 122, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 60, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 123, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 124, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 125, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 126, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 102, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
0x1FFFFFFFFFFFFF, 0xFFFFFFFF1FFFFFFF, 0x1FFFF, 0xFFFFE000FFFFFFFF,
0x7FFFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F, 0xFFFF00003FFFFFFF,
- 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xFFFFFFFFF, 0x7FFFFFFFFFFFFF,
- 0xFF003FFFFF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF,
- 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEFF06F,
+ 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xF7FF000FFFFFFFFF,
+ 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x7FDFFFFFFFFFFBF,
+ 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000,
+ 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEFF06F,
0x1FFFFFFF00000000, 0x1FFFFFFF, 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF,
0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFFFF,
- 0xFFFF00801FFFFFFF, 0x3F, 0x1FFFFFFFFFFFFFC, 0x1FFFFFF0000,
- 0x47FFFFFFFF0070, 0x1400001E, 0x409FFFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F,
- 0x1FFFFFFFFFF, 0xE3EDFDFFFFF99FEF, 0xFE081199F, 0x7BB, 0xB3,
- 0x7F3FFFFFFFFFFFFF, 0x3F000000, 0x7FFFFFFFFFFFFFFF, 0x11, 0x7FFE7FFFFFF,
- 0x1FFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF,
- 0x7FE7FFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0x20FFFFCF, 0x7F7FFFFFFFFFFDFF,
- 0xFFFC000000000001, 0x7FFEFFFFFCFFFF, 0xB47FFFFFFFFFFB7F,
- 0xFFFFFDBF000000CB, 0x17B7FFF, 0x7FFFFF00000000, 0x3FFFFFF,
- 0x7FFFFFFFFFFF, 0xF, 0x7F, 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0xFFFF,
- 0x7FFFFFFFFFFF001F, 0xFFF80000, 0x300000000, 0x3FFFFFFFFFFFF,
- 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x43FF01FF,
- 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
+ 0x31BFFFFFFFFFF, 0xFFFF00801FFFFFFF, 0xFFFF00000000003F,
+ 0xFFFF000000000003, 0x7FFFFF0000001F, 0x3E00000000003F, 0x1FFFFFFFFFFFFFC,
+ 0x1FFFFFF0004, 0x47FFFFFFFF00F0, 0x1400C01E, 0x409FFFFFFFFBFFFF,
+ 0xFFFF01FFBFFFBD7F, 0x1FFFFFFFFFF, 0xE3EDFDFFFFF99FEF, 0xFE081199F,
+ 0x3800007BB, 0xB3, 0x7F3FFFFFFFFFFFFF, 0x3F000000, 0x7FFFFFFFFFFFFFFF,
+ 0x11, 0x13FFFFFFFFFFFFF, 0x7FFE7FFFFFF, 0x7F, 0x1FFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000, 0x80000000FFFFFFFF, 0x99BFFFFFFF6FF27F, 0x7,
+ 0xFFFFFCFF00000000, 0x1AFCFFFFFF, 0x7FE7FFFFFFFFFFFF, 0xFFFFFFFFFFFF0000,
+ 0xFFFF000020FFFFFF, 0x7F7FFFFFFFFFFDFF, 0xFFFC000000000001,
+ 0x7FFEFFFFFCFFFF, 0xB47FFFFFFFFFFB7F, 0xFFFFFDBF000000CB, 0x17B7FFF,
+ 0x7FFFFF00000000, 0x1000000000000, 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF,
+ 0x1FFFFFFFFFFFF, 0xFFFF00007FFFFFFF, 0x3FFFFFFF0000, 0xFFFFFFFFFFFF,
+ 0xE0FFFFF80000000F, 0xFFFF, 0xFFFFFFFFFFFF87FF, 0xFFFF80FF,
+ 0x3000B00000000, 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x6FEF000000000000,
+ 0x7FFFFFFFF, 0xFFFF00F000070000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF,
+ 0x43FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF,
0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF,
- 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x7DBF9FFFF7F, 0x1F, 0x8F, 0xAF7FE96FFFFFFEF,
- 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0xFFFF03FFFFFF03FF, 0x3FF,
- 0x7FFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF,
+ 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x7DBF9FFFF7F, 0x3F801FFFFFFFFFFF, 0x4000,
+ 0xFFFFFFFFFFF, 0x7FFF6F7F00000000, 0x1F, 0x88F, 0xAF7FE96FFFFFFEF,
+ 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0xFFFF000000000000,
+ 0xFFFF03FFFFFF03FF, 0x3FF, 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF,
+ 0x3FFFFFFF, 0x7FF,
],
};
@@ -320,88 +339,183 @@ pub const BIDI_CONTROL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
};
+pub const BIDI_MIRRORED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0x5000030000000000, 0x2800000028000000, 0x800080000000000, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 0,
+ 0, 6, 0, 0, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 12, 0, 13, 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, 18, 19, 0, 0, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 0, 21, 22, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 25, 26, 0, 0,
+ ],
+ tree2_level2: &[
+ 0, 0x3C00000000000000, 0x18000000, 0x600000000000000, 0x6000000000000060,
+ 0x6000, 0x1, 0xFA0FF857BC623F1E, 0xFFFFCFF5803C1FFF, 0xC1FFFFCC01079FFF,
+ 0xFFFF3FFFFFC33E00, 0x60300000F00, 0x3FFF0000000000, 0xFFFC70783B79,
+ 0x100FFFDF9FFFFF8, 0x33F0033A1F37C23F, 0x70307A53DFFFFC00,
+ 0xFE19BC3001800000, 0xFFFFBFCFFFFFFFFF, 0x2F88707C507FFFFF,
+ 0x4000000000000000, 0x3FF3000363C, 0x1FE00000, 0xFF3FF00, 0x307E000000,
+ 0x2800000050000300, 0xDA8000000,
+ ],
+ tree3_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0x8000000, 0x200000, 0x8000, 0x200, 0x8,
+ ],
+};
+
pub const CASE_IGNORABLE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
0x400408000000000, 0x140000000, 0x190A10000000000, 0, 0, 0, 0, 0, 0, 0,
0xFFFF000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
- 0x430FFFFFFFFFFFF, 0xB0, 0, 0, 0, 0x3F8, 0, 0, 0x2000000,
+ 0x430FFFFFFFFFFFF, 0xB0, 0, 0, 0, 0x3F8, 0, 0, 0x82000000,
0xBFFFFFFFFFFE0000, 0x100000000000B6, 0x17FF003F, 0x10000FFFFF801, 0,
0x3DFFBFC00000, 0xFFFF000000028000, 0x7FF, 0x1FFC000000000,
0x243FF80000000000,
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18,
- 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37,
- 38, 39, 40, 2, 41, 2, 2, 2, 42, 43, 44, 2, 45, 46, 47, 48, 49, 50, 2, 51,
- 52, 53, 54, 55, 2, 2, 2, 2, 2, 2, 56, 57, 58, 59, 60, 61, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 2, 63, 2, 64, 2, 65, 66,
- 2, 2, 2, 2, 2, 2, 2, 67, 2, 68, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 50, 2, 2, 2, 2, 71, 72, 73, 74, 75, 76, 77, 78, 79, 2, 2, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 2, 89, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 91, 2, 92, 93, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 96, 97, 98,
- 99, 100,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 35, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 36, 37, 38, 39, 40, 41, 42, 34, 43, 34, 34, 34, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 34, 54, 55, 56, 57, 58, 34, 34, 34, 34, 34,
+ 34, 59, 60, 61, 62, 63, 64, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 65, 34,
+ 66, 34, 67, 34, 68, 69, 34, 34, 34, 34, 34, 34, 34, 70, 34, 71, 72, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 73, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 53, 34, 34, 34, 34, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 34, 34, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 34, 92, 34, 93, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 94, 34, 95,
+ 96, 34, 34, 34, 34, 34, 34, 34, 34, 97, 98, 34, 99, 100, 101, 102, 103,
],
tree2_level2: &[
- 0x3FFFFFC00000, 0xE000000, 0, 0xFFFFFFFFFFF80000, 0x1400000000000007,
- 0x2000C00FE21FE, 0x1000000000000002, 0x4000000C0000201E,
- 0x1000000000000006, 0x23000000023986, 0xFC00000C000021BE,
- 0x9000000000000002, 0xC0040201E, 0x4, 0x2001, 0xC000000000000011,
- 0xC00603DC1, 0xC00003040, 0x1800000000000003, 0xC0000201E, 0x5C0400,
- 0x7F2000000000000, 0x7FC0, 0x1BF2000000000000, 0x3F40, 0x2A0000003000000,
- 0x7FFE000000000000, 0x1FFFFFFFFEFFE0DF, 0x40, 0x66FDE00000000000,
- 0x1E0001C3000000, 0x20002064, 0x1000000000000000, 0xE0000000,
- 0x1C0000001C0000, 0xC0000000C0000, 0x3FB0000000000000, 0x208FFE40, 0x7800,
- 0x8, 0x20000000060, 0xE04018700000000, 0x9800000, 0x9FF81FE57F400000,
- 0x7FFF008000000000, 0x17D000000000000F, 0xFF80000000004, 0x3B3C00000003,
- 0x3A34000000000, 0xCFF00000000000, 0x3F00000000000000, 0x31021FDFFF70000,
- 0xFFFFF00000000000, 0x10007FFFFFFFFFF, 0xFFFFFFFFF8000000,
- 0xFBFFFFFFFFFFFFFF, 0xA000000000000000, 0x6000E000E000E003,
- 0x7C900300F800, 0x8002FFDF00000000, 0x1FFF0000, 0x1FFFFFFFF0000,
- 0x3000000000000000, 0x3800000000000, 0x8000800000000000,
- 0xFFFFFFFF00000000, 0x800000000000, 0x83E3C0000000020, 0x7E000000,
- 0x7000000000000000, 0x200000, 0x1000, 0xBFF7800000000000, 0xF0000000,
- 0x3000000000000, 0x3FFFFFFFF, 0x1000000000000, 0x700, 0x300000000000000,
- 0x6000000844, 0x8003FFFF00000030, 0x3FC000000000, 0x3FF80,
- 0x13C8000000000007, 0x6000008000, 0x667E0000000000, 0x1001000000001008,
- 0xC19D000000000000, 0x58300020000002, 0xF8000000, 0x212000000000,
- 0x40000000, 0xFFFC000000000000, 0x3, 0xFFFF0008FFFF, 0x240000,
- 0x8000000000000000, 0x4000000004004080, 0x1000000000001, 0xC0000000,
- 0xE00000800000000,
+ 0x3FFFFFC00000, 0xE000000, 0xFF030100, 0xFFFFFFFFFFFFFE00,
+ 0x1400000000000007, 0x2000C00FE21FE, 0x1000000000000002,
+ 0x4000000C0000201E, 0x1000000000000006, 0x23000000023986,
+ 0xFC00000C000021BE, 0x9000000000000002, 0xC0060201E, 0x4, 0x2001,
+ 0xD000000000000011, 0xC00603DC1, 0xC00003040, 0x1800000000000003,
+ 0xC0000201E, 0x2, 0x5C0400, 0x7F2000000000000, 0x7FC0, 0x1FF2000000000000,
+ 0x3F40, 0x2A0000003000000, 0x7FFE000000000000, 0x1FFFFFFFFEFFE0DF, 0x40,
+ 0x66FDE00000000000, 0x1E0001C3000000, 0x20002064, 0x1000000000000000, 0,
+ 0xE0000000, 0xC0000001C0000, 0xC0000000C0000, 0x3FB0000000000000,
+ 0x208FFE40, 0xF800, 0x8, 0x20000000060, 0xE04018700000000, 0x9800000,
+ 0x9FF81FE57F400000, 0xFFFF008000000000, 0x7FFF, 0x17D000000000000F,
+ 0xFF80000000004, 0x3B3C00000003, 0x3A34000000000, 0xCFF00000000000,
+ 0x3F00000000000000, 0x31021FDFFF70000, 0xFFFFF00000000000,
+ 0x10007FFFFFFFFFF, 0xFFFFFFFFF8000000, 0xFFFFFFFFFFFFFFFF,
+ 0xA000000000000000, 0x6000E000E000E003, 0x7C900300F800,
+ 0x8002FFDF00000000, 0x1FFF0000, 0x1FFFFFFFF0000, 0x3000000000000000,
+ 0x3800000000000, 0x8000800000000000, 0xFFFFFFFF00000000, 0x800000000000,
+ 0x83E3C0000000020, 0x7E000000, 0x7000000000000000, 0x200000, 0x1000,
+ 0xBFF7800000000000, 0xF0000000, 0x3000000000000, 0x3FFFFFFFF,
+ 0x1000000000000, 0x700, 0x31C000000000000, 0x106000000844,
+ 0x8003FFFF00000030, 0x3FC000000000, 0x3FF80, 0x33C8000000000007,
+ 0x6000008000, 0x667E0000000000, 0x1001000000001008, 0xC19D000000000000,
+ 0x58300020000002, 0xE00F8000000, 0x212000000000, 0x40000000,
+ 0xFFFC000000000000, 0x7, 0xFFFF0008FFFF, 0x240000, 0x8000000000000000,
+ 0x4000000004004080, 0x1000000000001, 0xC0000000, 0xE00000800000000,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 3, 2, 2, 4, 2, 2, 2, 5, 6, 7, 8, 9, 10, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -409,51 +523,62 @@ pub const CASE_IGNORABLE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 0, 0, 17, 18, 19, 0, 0, 20, 21, 22, 23, 0, 0, 24, 25, 26, 27, 28, 0,
- 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 0, 0, 0, 0, 0, 34, 0,
- 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0, 8, 0, 0, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 0, 0, 20, 21, 22, 0, 0, 23, 24, 25, 26, 0, 0, 27, 28, 29, 30, 31, 0,
+ 32, 0, 0, 0, 33, 0, 0, 0, 34, 35, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 40, 0,
+ 41, 0, 42, 43, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,
- 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 48, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 50, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, 0, 57, 58, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60,
+ 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 64, 0, 0, 0, 0, 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 57, 0, 0, 57, 57, 57, 58, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 70, 71, 0, 0, 71, 71, 71, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x2000000000000000, 0x100000000, 0x7C0000000000000, 0x870000000000F06E,
- 0x6000000000, 0xF000000000, 0x1FFC0, 0xFF00000000000002,
- 0x800000000000007F, 0x2678000000000003, 0x2000, 0x1FEF8000000007,
- 0x8000000000000, 0x7FC0000000000003, 0x1E00, 0x40D3800000000000,
- 0x7F880000000, 0x1800000000000003, 0x1F1FC000000001, 0xFF00000000000000,
- 0x4000005C, 0x85F8000000000000, 0xD, 0xB03C000000000000, 0x30000001,
- 0xA7F8000000000000, 0x1, 0xBF280000000000, 0xFBCE0000000,
- 0x6FF800000000000, 0x79F80000000007FE, 0xE7E0080, 0x37FFC00,
- 0xBF7F000000000000, 0x6DFCFFFFFC0000, 0xB47E000000000000, 0xBF, 0xA30000,
- 0x18000000000000, 0x1F000000000000, 0x7F000000000000, 0xF, 0xFFFF8000,
- 0x300000000, 0xF60000000, 0xFFF8038000000000, 0x3C0000000FE7, 0x1C,
+ 0, 0x2000000000000000, 0x100000000, 0x7C0000000000000, 0x7FDFFFFFFFFFFBF,
+ 0x870000000000F06E, 0x6000000000, 0xF000000000, 0x180000000000, 0x1FFC0,
+ 0x3C, 0xFF00000000000002, 0x801900000000007F, 0x2678000000000003, 0x2004,
+ 0x1FEF8000000007, 0x8000000000000, 0x7FC0000000000003, 0x9E00,
+ 0x40D3800000000000, 0x7F880000000, 0x1800000000000003, 0x1F1FC000000001,
+ 0xFF00000000000000, 0x4000005C, 0x85F8000000000000, 0xD,
+ 0xB03C000000000000, 0x30000001, 0xA7F8000000000000, 0x1, 0xBF280000000000,
+ 0xFBCE0000000, 0x6FF800000000000, 0x5800000000000000, 0x8, 0x10CF00000,
+ 0x79F80000000007FE, 0xE7E0080, 0x37FFC00, 0xBF7F000000000000,
+ 0x6DFCFFFFFC0000, 0xB47E000000000000, 0xBF, 0xA30000, 0x18000000000000,
+ 0x1FF000000000000, 0x1F000000000000, 0x7F000000000000, 0xF, 0x8000,
+ 0xFFFF8000, 0x1B00000000, 0x6FEF000000000000, 0xF60000000,
+ 0xFFFF3FFFFFFFFFFF, 0x7F, 0xFFF8038000000000, 0x3C0000000FE7, 0x1C,
0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F,
- 0x7F0000, 0x7F0, 0xF800000000000000, 0xFFFFFFFF00000002,
- 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF,
+ 0x3FFF000000000000, 0x400000000000, 0xF00000000000, 0x7F0000, 0xFF0,
+ 0xF800000000000000, 0xFFFFFFFF00000002, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFF,
],
};
@@ -473,8 +598,8 @@ pub const CASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 5, 5, 0, 5, 5, 5, 5, 6, 7, 8, 9, 0, 10, 11,
0, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18,
- 5, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5,
+ 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -493,8 +618,8 @@ pub const CASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 0, 23, 5, 24, 25, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 5, 22, 23, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -507,19 +632,17 @@ pub const CASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 0,
- 0,
+ 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 0, 0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0xE7FFFFFFFFFF20BF, 0x3F3FFFFFFFFFFFFF,
0xE7FFFFFFFFFF01FF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3F3FFFFF,
0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC,
0x8002000000000000, 0x1FFF0000, 0xF21FBD503E2FFC84, 0xFFFFFFFF000043E0,
- 0x18, 0xFFC0000000000000, 0x3FFFFFFFFFF, 0xFFFF7FFFFFFFFFFF,
- 0xFFFFFFFF7FFFFFFF, 0xC781FFFFFFFFF, 0x20BFFFFFFFFF, 0x3FFFFFFFFFFF,
- 0x3FFFFFFF, 0xFFFFFFFC00000000, 0x3FFFFFFFFFF78FF, 0x700000000000000,
- 0xFFFF000000000000, 0xFFFF003FF7FFFFFF, 0xF8007F, 0x7FFFFFE00000000,
- 0x7FFFFFE,
+ 0x18, 0xFFC0000000000000, 0x3FFFFFFFFFF, 0xC781FFFFFFFFF, 0x20BFFFFFFFFF,
+ 0x3FFFFFFFFFFF, 0x3FFFFFFF, 0xFFFFFFFC00000000, 0xFFFFFFFFFFFF78FF,
+ 0x760000003EB07FF, 0xFFFF000000000000, 0xFFFF01FFF7FFFFFF, 0xF8007F,
+ 0x7FFFFFE00000000, 0x7FFFFFE,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -535,33 +658,34 @@ pub const CASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 0,
+ 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
+ 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 9,
- 10, 11, 12, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 11, 12, 13, 14, 15, 1, 1, 1, 1, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 25,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 21, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0xFFFFFFFFFFFFFFFF, 0xFFFF, 0xFFFF000000000000, 0xFFFFFFFFF0FFFFF,
+ 0xF7FF000000000000, 0x1BFBFFFBFFB7F7FF, 0x7FDFFFFFFFFFFB9,
0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xFFFFFFFFFFDFFFFF,
0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF,
0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD,
- 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0xF,
- 0xFFFF03FFFFFF03FF, 0x3FF,
+ 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7,
+ 0x7FFFFBFF, 0xF, 0xFFFF03FFFFFF03FF, 0x3FF,
],
};
@@ -600,8 +724,8 @@ pub const CHANGES_WHEN_CASEFOLDED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 24, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -614,17 +738,18 @@ pub const CHANGES_WHEN_CASEFOLDED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0,
+ 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0,
0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0x20BF, 0x3F00000000000000, 0xE7FFFFFFFFFF01FF,
0x5555555555555555, 0x555555554C155555, 0xFF00FF003F00FF00,
0xFF00AA003F00, 0x1F9CFFFFFFFFFFFF, 0x1F9C1F000F001F9C, 0x40C4000000000,
- 0xFFFF00000000, 0x8, 0xFFC0000000000000, 0xFFFF, 0x7FFFFFFFFFFF,
+ 0xFFFF00000000, 0x8, 0xFFC0000000000000, 0xFFFF, 0xFFFFFFFFFFFF,
0xC025EA9D00000000, 0x4280555555555, 0x155555555555, 0x5555555,
- 0x5554555400000000, 0x6A00555555555555, 0x15F7D5555452855,
- 0xFFFF000000000000, 0xFFFFFFFFFFFFFFFF, 0xF8007F, 0x7FFFFFE00000000,
+ 0x5554555400000000, 0x6A00555555555555, 0x555F7D5555452855,
+ 0x200000014102F5, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFFF, 0xF8007F,
+ 0x7FFFFFE00000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -640,23 +765,23 @@ pub const CHANGES_WHEN_CASEFOLDED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 4, 5, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF00000000, 0xFFFFFFFF, 0x3FFFFFFFF,
+ 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0xF7FF000000000000,
+ 0x37F7FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF, 0x3FFFFFFFF,
],
};
@@ -664,7 +789,7 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
tree1_level1: &[
0, 0x7FFFFFE07FFFFFE, 0x20000000000000, 0xFF7FFFFFFF7FFFFF,
0xFEFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xB3FFF3FFF7FFDFFF,
- 0xFFFFFFFFFFFFFFF0, 0xFC0FFFFDFFFFFFFF, 0x20269F6B1ADFFFFF, 0x60041F89, 0,
+ 0xFFFFFFFFFFFFFFF0, 0xFC0FFFFDFFFFFFFF, 0x20269F6B1ADFFFFF, 0x60041F8D, 0,
0, 0xB8CF000000000020, 0xFFFFFFFBFFFFD740, 0xEFBFFFFFFFE3FFFF,
0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFC03,
0xFFFFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFFF, 0xFFFFFFFE007FFFFF, 0xFF, 0, 0, 0,
@@ -674,10 +799,10 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 6, 6, 7, 6, 8, 9, 10, 11, 0, 0, 0,
- 0, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18,
- 6, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 6, 0, 7, 7, 8, 7, 9, 10, 11, 12, 0, 0, 0,
+ 0, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18,
+ 7, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -696,8 +821,8 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 0, 23, 24, 25, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 0, 23, 24, 25, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -710,18 +835,18 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 0,
+ 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 0,
0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0xE7FFFFFFFFFF20BF, 0x3F3FFFFFFFFFFFFF,
- 0xE7FFFFFFFFFF01FF, 0x2200000000000000, 0xFFFFFFFFFFFFFFFF,
+ 0xE7FFFFFFFFFF01FF, 0x2200000000000000, 0x4000, 0xFFFFFFFFFFFFFFFF,
0xFFFFFFFF4FFFFFFF, 0xFFFFFFFF3F3FFFFF, 0x3FFFFFFFAAFF3F3F,
0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC, 0x40C4000000000,
0xFFFFFFFF00004000, 0x18, 0xFFC0000000000000, 0x3FFFFFFFFFF,
- 0xFFFF7FFFFFFFFFFF, 0xC06DFFFF7FFFFFFF, 0xC780FFFFFFFFF, 0x20BFFFFFFFFF,
- 0x3FFFFFFFFFFF, 0xFFFFFFF, 0xFFFCFFFC00000000, 0xFE00FFFFFFFFFFFF,
- 0x3FF7FFFFFCF38FF, 0xFFFF000000080000, 0xF8007F, 0x7FFFFFE00000000,
+ 0xC06DFFFFFFFFFFFF, 0xC780FFFFFFFFF, 0x20BFFFFFFFFF, 0x3FFFFFFFFFFF,
+ 0xFFFFFFF, 0xFFFCFFFC00000000, 0xFE00FFFFFFFFFFFF, 0xFFFF7FFFFFDF38FF,
+ 0x60000003C307FF, 0xFFFF000000080000, 0xF8007F, 0x7FFFFFE00000000,
0x7FFFFFE,
],
tree3_level1: &[
@@ -738,10 +863,10 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
+ 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -749,12 +874,13 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0xFFFFFFFFFFFFFFFF, 0xFFFF, 0xFFFF000000000000, 0xFFFFFFFFF0FFFFF,
- 0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xF,
+ 0xF7FF000000000000, 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFF,
+ 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xF,
],
};
@@ -792,7 +918,7 @@ pub const CHANGES_WHEN_LOWERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 24, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -806,16 +932,16 @@ pub const CHANGES_WHEN_LOWERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0x20BF, 0x3FFFFFFFFFFFFF, 0xE7FFFFFFFFFF0000,
0x5555555555555555, 0x5555555540155555, 0xFF00FF003F00FF00,
0xFF00AA003F00, 0x1F00FF00FF00FF00, 0x1F001F000F001F00, 0x40C4000000000,
- 0xFFFF00000000, 0x8, 0xFFC0000000000000, 0xFFFF, 0x7FFFFFFFFFFF,
+ 0xFFFF00000000, 0x8, 0xFFC0000000000000, 0xFFFF, 0xFFFFFFFFFFFF,
0xC025EA9D00000000, 0x4280555555555, 0x155555555555, 0x5555555,
- 0x5554555400000000, 0x6A00555555555555, 0x15F7D5555452855,
- 0x7FFFFFE00000000,
+ 0x5554555400000000, 0x6A00555555555555, 0x555F7D5555452855,
+ 0x200000014102F5, 0x7FFFFFE00000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -831,23 +957,23 @@ pub const CHANGES_WHEN_LOWERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 4, 5, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF00000000, 0xFFFFFFFF, 0x3FFFFFFFF,
+ 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0xF7FF000000000000,
+ 0x37F7FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF, 0x3FFFFFFFF,
],
};
@@ -855,7 +981,7 @@ pub const CHANGES_WHEN_TITLECASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
tree1_level1: &[
0, 0x7FFFFFE00000000, 0x20000000000000, 0xFF7FFFFF80000000,
0x54AAAAAAAAAAAAAA, 0xD4AAAAAAAAAAAB55, 0xA251212A46241129,
- 0xAA2BAAAAB55556D0, 0x900AAAA8AAAAAAAA, 0x20269F6B1ADFAA85, 0x60041F89, 0,
+ 0xAA2BAAAAB55556D0, 0x900AAAA8AAAAAAAA, 0x20269F6B1ADFAA85, 0x60041F8D, 0,
0, 0x388A000000000020, 0xFFFFF00000010000, 0x92FAAAAAAE37FFF,
0xFFFF000000000000, 0xAAAAAAAAFFFFFFFF, 0xAAAAAAAAAAAAA802,
0xAAAAAAAAAAAAD554, 0xAAAAAAAAAAAA, 0xFFFFFFFE00000000, 0xFF, 0, 0, 0, 0,
@@ -865,10 +991,10 @@ pub const CHANGES_WHEN_TITLECASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 4, 4, 5, 4, 6, 7, 8, 9, 0, 0, 0, 0,
- 0, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 15,
- 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 4, 0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 0, 0,
+ 0, 0, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 5,
+ 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -887,8 +1013,8 @@ pub const CHANGES_WHEN_TITLECASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 0, 19, 20, 21, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, 21, 22, 23, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -901,16 +1027,17 @@ pub const CHANGES_WHEN_TITLECASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0,
+ 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0,
],
tree2_level2: &[
- 0, 0x3F00000000000000, 0x1FF, 0x2200000000000000, 0xAAAAAAAAAAAAAAAA,
- 0xAAAAAAAA0FEAAAAA, 0xFF00FF003F00FF, 0x3FFF00FF00FF003F,
- 0x40DF00FF00FF00FF, 0xDC00FF00CF00DC, 0xFFFF000000004000, 0x10,
- 0x3FFFFFF0000, 0xFFFF000000000000, 0x4815627FFFFFFF, 0x8500AAAAAAAAA,
- 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA, 0xAAAAAAA, 0xAAA8AAA800000000,
- 0x9400AAAAAAAAAAAA, 0x2A002AAAA8A10AA, 0xFFFF000000080000,
- 0xFFFFFFFFFFFFFFFF, 0xF8007F, 0x7FFFFFE,
+ 0, 0x3F00000000000000, 0x1FF, 0x2200000000000000, 0x4000,
+ 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAA0FEAAAAA, 0xFF00FF003F00FF,
+ 0x3FFF00FF00FF003F, 0x40DF00FF00FF00FF, 0xDC00FF00CF00DC,
+ 0xFFFF000000004000, 0x10, 0x3FFFFFF0000, 0xFFFF000000000000,
+ 0x481562FFFFFFFF, 0x8500AAAAAAAAA, 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA,
+ 0xAAAAAAA, 0xAAA8AAA800000000, 0x9400AAAAAAAAAAAA, 0xAAA002AAAA9A10AA,
+ 0x4000000282050A, 0xFFFF000000080000, 0xFFFFFFFFFFFFFFFF, 0xF8007F,
+ 0x7FFFFFE,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -926,23 +1053,23 @@ pub const CHANGES_WHEN_TITLECASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFC00000000, 0xF,
+ 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x1BFBFFFBFF800000,
+ 0x7FFFFFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFC00000000, 0xF,
],
};
@@ -950,7 +1077,7 @@ pub const CHANGES_WHEN_UPPERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
tree1_level1: &[
0, 0x7FFFFFE00000000, 0x20000000000000, 0xFF7FFFFF80000000,
0x54AAAAAAAAAAAAAA, 0xD4AAAAAAAAAAAB55, 0xA251212A46241129,
- 0xAA2DAAAAB5555B60, 0x900AAAA8AAAAAAAA, 0x20269F6B1ADFAA85, 0x60041F89, 0,
+ 0xAA2DAAAAB5555B60, 0x900AAAA8AAAAAAAA, 0x20269F6B1ADFAA85, 0x60041F8D, 0,
0, 0x388A000000000020, 0xFFFFF00000010000, 0x92FAAAAAAE37FFF,
0xFFFF000000000000, 0xAAAAAAAAFFFFFFFF, 0xAAAAAAAAAAAAA802,
0xAAAAAAAAAAAAD554, 0xAAAAAAAAAAAA, 0xFFFFFFFE00000000, 0xFF, 0, 0, 0, 0,
@@ -960,10 +1087,10 @@ pub const CHANGES_WHEN_UPPERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 0, 0,
- 0, 0, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 5,
- 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 5, 0, 6, 6, 7, 6, 8, 9, 10, 11, 0, 0, 0,
+ 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 6,
+ 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -982,8 +1109,8 @@ pub const CHANGES_WHEN_UPPERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, 21, 22, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -996,16 +1123,17 @@ pub const CHANGES_WHEN_UPPERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0,
+ 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0,
],
tree2_level2: &[
0, 0xE7FFFFFFFFFF0000, 0x3F00000000000000, 0x1FF, 0x2200000000000000,
- 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAA0FEAAAAA, 0xFF00FF003F00FF,
+ 0x4000, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAA0FEAAAAA, 0xFF00FF003F00FF,
0x3FFF00FF00FF003F, 0x50DFFFFFFFFFFFFF, 0x10DC00FF00CF10DC,
0xFFFF000000004000, 0x10, 0x3FFFFFF0000, 0xFFFF000000000000,
- 0x4815627FFFFFFF, 0x8500AAAAAAAAA, 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA,
- 0xAAAAAAA, 0xAAA8AAA800000000, 0x9400AAAAAAAAAAAA, 0x2A002AAAA8A10AA,
- 0xFFFF000000080000, 0xFFFFFFFFFFFFFFFF, 0xF8007F, 0x7FFFFFE,
+ 0x481562FFFFFFFF, 0x8500AAAAAAAAA, 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA,
+ 0xAAAAAAA, 0xAAA8AAA800000000, 0x9400AAAAAAAAAAAA, 0xAAA002AAAA9A10AA,
+ 0x4000000282050A, 0xFFFF000000080000, 0xFFFFFFFFFFFFFFFF, 0xF8007F,
+ 0x7FFFFFE,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1021,23 +1149,23 @@ pub const CHANGES_WHEN_UPPERCASED: &'static ::ucd_trie::TrieSet = &::ucd_trie::T
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFC00000000, 0xF,
+ 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x1BFBFFFBFF800000,
+ 0x7FFFFFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFC00000000, 0xF,
],
};
@@ -1053,7 +1181,7 @@ pub const DASH: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 9, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1086,18 +1214,36 @@ pub const DASH: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 0, 0, 12, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 0, 0, 13, 0, 0, 0,
],
tree2_level2: &[
0, 0x1, 0x40, 0x3F0000, 0x800000000080000, 0x800, 0x40000,
- 0xC00000004800000, 0x1000010000000, 0x100000000, 0x6000000000000,
- 0x801000000, 0x2000,
+ 0xC00000004800000, 0x20000001, 0x1000010000000, 0x100000000,
+ 0x6000000000000, 0x801000000, 0x2000,
],
tree3_level1: &[
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,
],
tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
],
tree3_level3: &[
+ 0, 0x200000000000,
],
};
@@ -1149,7 +1295,7 @@ pub const DEFAULT_IGNORABLE_CODE_POINT: &'static ::ucd_trie::TrieSet = &::ucd_tr
0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 0, 0, 9, 10,
],
tree2_level2: &[
- 0, 0x180000000, 0x30000000000000, 0x7800, 0x7C000000F800, 0xFFFF00000000,
+ 0, 0x180000000, 0x30000000000000, 0xF800, 0x7C000000F800, 0xFFFF00000000,
0x1000000000, 0xFFFF, 0x8000000000000000, 0x100000000, 0x1FF000000000000,
],
tree3_level1: &[
@@ -1268,14 +1414,14 @@ pub const DIACRITIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xFFFF000000000000, 0x7FF, 0x1FFC000000000, 0x3FF80000000000,
],
tree2_level1: &[
- 0, 1, 1, 2, 3, 4, 3, 5, 3, 5, 3, 6, 3, 5, 1, 5, 1, 5, 3, 5, 7, 5, 1, 8, 1,
- 9, 1, 10, 11, 1, 12, 13, 14, 1, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 17, 1, 1, 1,
- 1, 18, 19, 1, 20, 21, 22, 1, 23, 24, 1, 25, 26, 27, 1, 28, 1, 1, 1, 1, 1,
- 1, 29, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 1, 1, 1, 1, 1, 1, 1, 33, 1, 34, 3, 1,
+ 0, 1, 2, 3, 4, 5, 4, 6, 4, 6, 4, 7, 4, 8, 1, 6, 4, 6, 4, 6, 9, 6, 1, 10,
+ 1, 11, 12, 13, 14, 1, 15, 16, 17, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 1, 1, 22, 1, 1, 1, 1,
+ 23, 1, 1, 1, 1, 24, 25, 26, 27, 28, 29, 1, 30, 31, 1, 32, 33, 34, 1, 35,
+ 1, 1, 1, 1, 1, 1, 36, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 40,
+ 1, 41, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1293,8 +1439,9 @@ pub const DIACRITIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 35, 36, 37, 38, 1,
- 39, 40, 1, 1, 1, 41, 42, 43, 44, 45, 1, 46, 47, 48, 1, 49, 1, 50, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 42,
+ 43, 44, 45, 1, 46, 47, 1, 1, 1, 48, 49, 50, 51, 52, 1, 53, 54, 55, 1, 56,
+ 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1306,27 +1453,28 @@ pub const DIACRITIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 52, 1, 1, 1, 53, 54, 55, 56,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 58, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 59, 1, 1, 1, 60, 61, 62, 63,
],
tree2_level2: &[
- 0x3000000, 0, 0x7FFFFFF800000000, 0x1000000000000000, 0x20000001E2000,
- 0x2000, 0xE000000000002000, 0x1800000000000000, 0x400, 0x5F80, 0x1F00,
- 0xC2A0000003000000, 0xDC, 0x40, 0x680000000000000, 0xC00BF80, 0x200FFE00,
- 0xE00000000000000, 0x9FE0000000000000, 0x3FFF000000000000,
- 0x10000000000000, 0xFF80000000010, 0xC0000000000, 0xC0000000000000,
+ 0x3000000, 0, 0xFF000000, 0x7FFFFFF80007FE00, 0x1000000000000000,
+ 0x20000001E2000, 0x2000, 0xE000000000002000, 0x202000, 0x1800000000000000,
+ 0x400, 0x5F80, 0x400000000000000, 0x1F00, 0xC2A0000003000000, 0xDC, 0x40,
+ 0x680000000000000, 0x3E1800000000, 0xC00BF80, 0xE0000000, 0x300000,
+ 0x200FFE00, 0xE00000000000000, 0x9FE0000000000000, 0x7FFF000000000000,
+ 0xFFE, 0x10000000000000, 0xFF80000000010, 0xC0000000000, 0xC0000000000000,
0x3F00000000000000, 0x39021FFFFFF0000, 0xFFFFF00000000000, 0x7FFFFFFFFFF,
- 0xE3E000000000FFF0, 0xA000000000000000, 0x6000E000E000E003,
+ 0xFFE000000000FFF0, 0xA000000000000000, 0x6000E000E000E003,
0x3800000000000, 0x800000000000, 0xFC0000000000, 0x1E000000,
- 0xB000800000000000, 0x30000000, 0x3000000000000, 0x3FF800000, 0x100,
+ 0xB000800000000000, 0x30000000, 0x3000000000000, 0x3FFFFFFFF, 0x700,
0x300000000000000, 0x3FFFF00000010, 0x780000000000, 0x80000,
0x8000000000000, 0x2000000001, 0x3800000000000000, 0x8000000000000000,
- 0x40000000000007, 0xF8000000, 0x300000000000, 0x40000000, 0xFFFF00000000,
- 0x4000000000000000, 0x1000000000001, 0xC0000000, 0x800000000,
+ 0x40000000000007, 0xE00F8000000, 0x300000000000, 0x40000000,
+ 0xFFFF00000000, 0x4000000000000000, 0x1000000000001, 0xC0000000,
+ 0x800000000,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1340,45 +1488,55 @@ pub const DIACRITIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 6, 7, 0, 8, 9, 0, 0,
- 10, 11, 12, 0, 0, 0, 13, 0, 14, 0, 0, 15, 16, 15, 0, 17, 0, 18, 0, 0, 0,
- 5, 0, 0, 0, 0, 0, 0, 0, 19, 20, 21, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 22, 23,
+ 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 0, 7, 8, 0, 9, 10, 0, 11, 12, 0,
+ 0, 13, 14, 15, 0, 0, 0, 16, 0, 17, 0, 0, 18, 19, 18, 0, 20, 0, 21, 0, 0,
+ 0, 8, 0, 0, 0, 22, 23, 0, 1, 24, 25, 26, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0,
+ 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 26, 27, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0,
+ 0, 0, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 38, 39,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,
+ 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x100000000, 0x6000000000, 0xFC00000000, 0x1FFC0, 0x600000000000000,
- 0x18000000000000, 0x8000000000000, 0x1C01, 0x60000000000000,
- 0x60000000000, 0x1000000000000000, 0x1F1FC000002000, 0x44, 0xC,
- 0x8000000000000000, 0x1, 0xC0000000000000, 0x80000000000,
+ 0, 0x100000000, 0x7FDFFFFFFFFFFBF, 0x6000000000, 0xFC00000000, 0x1FFC0,
+ 0x3C, 0x1000000000040, 0x600000000000000, 0x18000000000000,
+ 0x8000000000000, 0x1C01, 0x60000000000000, 0x60000000000,
+ 0x1000000000000000, 0x1F1FC000002000, 0x44, 0xC, 0x8000000000000000, 0x1,
+ 0xC0000000000000, 0x80000000000, 0x6000000000000000, 0x8,
0x10000000000000, 0x80, 0x2000000, 0x34, 0x800000, 0x1F000000000000,
- 0xFFFF8000, 0xF807E38000000000, 0x3C0000000FE7, 0x7F0000, 0x770,
+ 0x7F000000000000, 0xFFFF8000, 0x3000000000000, 0x6FEF000000000000,
+ 0xFFFF3FFFFFFFFFFF, 0x7F, 0xF807E38000000000, 0x3C0000000FE7,
+ 0x400000000000, 0xF00000000000, 0x7F0000, 0x770,
],
};
-pub const EXTENDER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+pub const EMOJI: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
- 0, 0, 0x80000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0x30000, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x400000000000000,
+ 0x3FF040800000000, 0, 0x420000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level1: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4,
- 0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
+ 3, 0, 4, 0, 0, 0, 0, 0, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 18, 19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1396,9 +1554,6 @@ pub const EXTENDER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
- 0, 13, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1411,15 +1566,20 @@ pub const EXTENDER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level2: &[
- 0, 0x40, 0x400, 0x8, 0x8000000000, 0x40000000000000, 0x800000000000000,
- 0x3E000000000020, 0x60000000, 0x7000000000000000, 0x200000, 0x1000,
- 0x4000008000, 0x1000000000000, 0x18000020000000,
+ 0, 0x1000000000000000, 0x200, 0x200000400000000, 0x60003F00000,
+ 0x1000C000000, 0x70FFE0000008000, 0x4, 0x400C0000000000,
+ 0x7800000000000001, 0x700C44D2132401F, 0xC8000169800FFF05,
+ 0x60030C831AFC0000, 0x27BF0600001AC130, 0x1801022054BF24, 0x1800B85090,
+ 0x8001000200E00000, 0x30000000000000, 0x180000E0, 0x210000,
+ 0x2001000000000000, 0x2800000,
],
tree3_level1: &[
- 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1434,18 +1594,466 @@ pub const EXTENDER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 3, 4, 5, 6, 7, 0,
+ 0, 8, 9, 10, 11, 9, 9, 9, 12, 13, 14, 15, 16, 9, 17, 9, 18, 0, 0, 0, 19,
+ 0, 0, 0, 0, 20, 21, 9, 9, 0, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0x10, 0x8000, 0xC003000000000000, 0x7FE4000, 0xFFFFFFC000000000,
+ 0x7FC800004000006, 0x30000, 0xFFFFFFF3FFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFCECFFFFF, 0xFFB9FFFFFFFFFFFF, 0xBFFFFFFFFFFFFFFF,
+ 0x3FFFFFFFFFFFFFFF, 0x7F980FFFFFF7E00, 0x1006013000613C80,
+ 0xFC08810A700E001C, 0xFFFF, 0x1FF91A3FE0E7F83F, 0x10FFF00000000,
+ 0xF7FFFFFFFFFFF000, 0xFFFFFFFFFFFFFFBF, 0x1F1F000000000000,
+ 0x7FF1FFFFFFF007F, 0x7F00FF03FF003F,
+ ],
+};
+
+pub const EMOJI_COMPONENT: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0x3FF040800000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level2: &[
+ 0, 0x2000, 0x800000000, 0x8000,
+ ],
+ tree3_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0xFFFFFFC000000000, 0xF800000000000000, 0xF000000000000,
+ 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF,
+ ],
+};
+
+pub const EMOJI_MODIFIER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level1: &[
+ ],
+ tree2_level2: &[
+ ],
+ tree3_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0xF800000000000000,
+ ],
+};
+
+pub const EMOJI_MODIFIER_BASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level2: &[
+ 0, 0x20000000, 0x200000000000000, 0x3C00,
+ ],
+ tree3_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 2, 0, 3, 4, 0, 0, 5, 6, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 11, 12, 13, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0x20, 0x1C9C, 0x11FFFFC00001FFCC, 0x400000280EE, 0x430000000000000,
+ 0x610000, 0xF8E0, 0x70000800000000, 0x1001, 0x73FF0040FF009000,
+ 0x80000000000000, 0xB60000000000000, 0x3FFEE000, 0x7F000000000038,
+ ],
+};
+
+pub const EMOJI_PRESENTATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 8,
+ 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level2: &[
+ 0, 0xC000000, 0x91E0000000000, 0x6000000000000000, 0x300000,
+ 0x80000000000FFF00, 0x60000C0200080000, 0x242C040000104030, 0x10000000C20,
+ 0xB85000, 0x8001000000E00000, 0x18000000, 0x210000,
+ ],
+ tree3_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 4, 5, 6, 0,
+ 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 13, 19, 13, 20, 0, 0, 0,
+ 21, 0, 0, 0, 0, 22, 23, 13, 13, 0, 24, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0x10, 0x8000, 0x7FE4000, 0xFFFFFFC000000000, 0x77C800004000002,
+ 0x30000, 0xFFBFE001FFFFFFFF, 0xDFFFFFFFFFFFFFFF, 0xFFFFFFFF000FFFFF,
+ 0xFF11FFFF000F87FF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFD,
+ 0xFFFFFFFFFFFFFFFF, 0x9FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
+ 0x40000FFFFFF7800, 0x1000600000, 0xF800000000000000, 0xFFFF,
+ 0x1FF01800E0E7103F, 0x10FFF00000000, 0xF7FFFFFFFFFFF000,
+ 0xFFFFFFFFFFFFFFBF, 0x1F1F000000000000, 0x7FF1FFFFFFF007F,
+ 0x7F00FF03FF003F,
+ ],
+};
+
+pub const EXTENDED_PICTOGRAPHIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0, 0, 0x420000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
+ 3, 0, 4, 0, 0, 0, 0, 0, 5, 0, 6, 7, 0, 0, 0, 8, 0, 0, 9, 10, 11, 12, 13,
+ 12, 14, 15, 16, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 18, 19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree2_level2: &[
+ 0, 0x1000000000000000, 0x200, 0x200000400000000, 0x60003F00000,
+ 0x1000C000000, 0x100, 0x70FFE0000008000, 0x4, 0x400C0000000000,
+ 0x7800000000000001, 0xFFFFFFFFFFF7FFBF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFF003F, 0x1801022057FF3F, 0xF800B85090, 0x8001000200E00000,
+ 0x30000000000000, 0x180000E0, 0x210000, 0x2001000000000000, 0x2800000,
+ ],
+ tree3_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 1,
+ 1, 1, 1, 1, 8, 1, 1, 1, 1, 9, 10, 1, 1, 1, 11, 1, 1, 0, 12, 0, 13, 14, 15,
+ 16, 1, 17, 18, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 9,
+ ],
tree3_level3: &[
- 0, 0x20000000, 0x1C0, 0x1000000, 0xC, 0x300000000, 0x70,
+ 0, 0xFFFFFFFFFFFFFFFF, 0x80000000E000, 0xC003F00000000000,
+ 0xFFFFE00007FE4000, 0x3FFFFFFFFF, 0xF7FC80000400FFFE, 0xFFFFFFFFFFFFFE00,
+ 0x7FFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFC0, 0xFFFF,
+ 0xFFF0000000000000, 0xFFFFFFFFFFE00000, 0xF000, 0xFC00FF00,
+ 0xFFFFC0000000FF00, 0xF7FFFFFFFFFFF000, 0xFFFFFFFFFFFFFFBF,
+ ],
+};
+
+pub const EXTENDER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0, 0, 0x80000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0x30000, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x400000000000000,
+ ],
+ tree2_level1: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 0, 13, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ ],
+ tree2_level2: &[
+ 0, 0x200000, 0x40, 0x400, 0x8, 0x8000000000, 0x40000000000000,
+ 0x800000000000000, 0x3E000000000020, 0x60000000, 0x7000000000000000,
+ 0x1000, 0x4000008000, 0x1000000000000, 0x18000020000000,
+ ],
+ tree3_level1: &[
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2,
+ ],
+ tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ],
+ tree3_level3: &[
+ 0, 0x6, 0x20000000, 0x1C0, 0x1000000, 0xC, 0xB00000000,
+ 0x3000000000000000, 0x70,
],
};
@@ -1458,7 +2066,7 @@ pub const GRAPHEME_BASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xFCFF000000000000, 0xFFFFFFFBFFFFD7F0, 0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFC07,
0xFFFFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFFF, 0xFFFFFFFFFE7FFFFF,
- 0x400000000000E7FF, 0x1F87FFFFFF0049, 0xFFFFFFFFC800FFC0,
+ 0x400000000000E7FF, 0x1F87FFFFFF0049, 0xFFFFFFFFE800FFC0,
0xFFFEFFFF000007FF, 0xFFFFFFFFFFFFFFFF, 0xFFFFC260403FFFFF,
0xFFFFFFFD3FFF, 0xFFFFFFFFFFFFE000, 0x2003FFFFFFFFF, 0xC7F007FFFFFFFFFF,
],
@@ -1466,19 +2074,19 @@ pub const GRAPHEME_BASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36,
36, 36, 37, 38, 39, 40, 41, 42, 43, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 44, 45, 46, 47, 48, 49, 50, 45, 51, 52, 53, 54, 55, 56, 57, 58, 59, 3,
- 60, 61, 62, 63, 64, 65, 66, 67, 36, 36, 36, 3, 36, 36, 36, 36, 68, 69, 70,
- 71, 72, 73, 74, 3, 36, 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 77,
+ 36, 44, 45, 46, 47, 48, 49, 50, 45, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 36, 36, 36, 60, 36, 36, 36, 36, 69,
+ 70, 71, 72, 73, 74, 75, 76, 36, 36, 77, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 78, 79, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 80, 81, 36, 36, 36, 36,
+ 82, 83, 84, 85, 86, 36, 87, 88, 89, 36, 36, 36, 90, 91, 92, 93, 36, 94,
+ 36, 95, 96, 97, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 78, 79, 80, 81, 82, 36, 83, 84, 85,
- 86, 87, 36, 88, 89, 90, 36, 36, 36, 91, 92, 93, 94, 36, 95, 36, 96, 97,
- 82, 36, 36, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 52, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -1496,11 +2104,10 @@ pub const GRAPHEME_BASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 99, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 100, 101, 36, 36, 36, 36, 102, 103, 104,
- 105, 36, 36, 106, 107, 108, 109, 36, 110, 111, 112, 113, 114, 115, 116,
- 117, 118, 119, 120, 36, 121, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 98, 99, 36, 36, 36, 36, 100,
+ 101, 102, 103, 36, 36, 36, 104, 105, 106, 36, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 55, 36, 117, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -1509,62 +2116,63 @@ pub const GRAPHEME_BASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 97, 122, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 36, 36, 36, 36, 36, 123, 36, 124, 125,
- 126, 36, 127, 36, 36, 36, 36, 36, 128, 129, 130, 131, 132, 36, 133, 93,
- 36, 134, 135,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 96, 118, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 36, 36, 36, 36, 36, 119, 36,
+ 120, 121, 122, 36, 123, 36, 36, 36, 36, 36, 36, 124, 125, 126, 127, 36,
+ 128, 92, 36, 129, 130,
],
tree2_level2: &[
- 0x7FFF0110043FFFFF, 0x7FF41FFFFFF, 0x3FDFFFFF00000000, 0,
+ 0x7FFF0110043FFFFF, 0xFFFF07FF41FFFFFF, 0xFFFFFFFF00007FFF, 0x3FF,
0xEBFFFFFFFFFFFFF8, 0xFFFFFFF3FF01DE01, 0xA3C5FDFFFFF99FED,
0x3FFFFFC3B0005981, 0xC36DFDFFFFF987E8, 0x5CFFC05E000001,
0xE3EDFDFFFFFBBFE8, 0x203FFC300011A01, 0x23EDFDFFFFF99FEC,
0xFFFFC3B0001981, 0x83FFC718D63DC7E8, 0x7FFFFC000011DC6,
- 0x23FFFDFFFFFDDFEE, 0xFF00FFC30700001E, 0x63EFFDFFFFFDDFFD,
- 0x6FFC340000D9B, 0xA7FFFFFFFFFDDFEC, 0xFFFFFFC3FF70DDC1,
+ 0x23FFFDFFFFFDDFEE, 0xFF80FFC32700001E, 0x63EFFDFFFFFDDFFD,
+ 0x6FFC360000D9B, 0xA7FFFFFFFFFDDFFC, 0xFFFFFFC3FF70DDC1,
0x2FFBFFFFFC7FFFEC, 0x1CFFC07F03007F, 0x800DFFFFFFFFFFFE, 0xFFF807F,
- 0x200DECAEFEF02596, 0xF3FF005F, 0xFD5FFFFFFCFFFFFF, 0x80001FFFFFFFFEFF,
+ 0x200DFFAFFFFFF7D6, 0xF3FF005F, 0xFD5FFFFFFCFFFFFF, 0x80001FFFFFFFFEFF,
0xC000000000001F20, 0x7FFDFBF, 0x99021FFFFFFFFFFF, 0xFFE1FFFE3CFFFFFF,
0xFFFFFFFFDFFFDF9B, 0xFFFFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF,
0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
0xFFFFFFFFFF3DFFFF, 0x1FFFFFFF07FFFFFF, 0xFFFFFFFF03FFFFFF,
0x3F3FFFFFFFFFFFFF, 0xFFFFFFFF1FFFFFFF, 0x1FFFFFFFFFFFFFF,
- 0x63FFFF0003DFFF, 0x1DFFF0003FFFF, 0xC04FFFFFFFFFFFFF, 0x3FF03FF1FF001BF,
+ 0x73FFFF8023FFFF, 0x1DFFF0003FFFF, 0xC04FFFFFFFFFFFFF, 0x3FF03FF1FF001BF,
0xFFFFFFFF03FF07FF, 0xFFFF05FFFFFFFF9F, 0x3FFFFFFFFFFFFF,
0x1FB0E787FFFFFFF, 0x1F3FFFFFFFFFF1, 0xFFFF0FFFFFFFFFFF,
0xFFFFFFFFC7FF03FF, 0xFFFFFFFFC67FFFFF, 0x7E01A00BFFFFF, 0x3FFF03FF03FF,
- 0xE82FFFFFFFFFFFF0, 0x1FF007FFFFFF0FFB, 0xFFFFC4C3FFFFFFFC,
+ 0, 0xE80FFFFFFFFFFFF0, 0x7FF007FFFFFF1FFB, 0xFFFFC4C3FFFFFFFC,
0xF00C5CBFFFFFFFFF, 0xF8300FFFFFFFFFFF, 0xFFFFFFFFFFFFE3FF,
- 0xE7FFFFFFFFFF01FF, 0xEFDE02000800FF, 0xFFFFFFFF3F3FFFFF,
+ 0xE7FFFFFFFFFF01FF, 0x4EFDE02000800FF, 0xFFFFFFFF3F3FFFFF,
0x3FFFFFFFAAFF3F3F, 0xFFDFFFFFFFFFFFFF, 0x7FDCFFFFEFCFFFDF,
- 0xFFFF80FFFFFF07FF, 0xFFF30000FFFFFFFF, 0xFFFFFFFF1FFF7FFF,
+ 0xFFFF80FFFFFF07FF, 0xFFF30000FFFFFFFF, 0xFFFFFFFF1FFF7FFF, 0x1,
0xFFFFFFFFFFFF0FFF, 0x7FFFFFFFFF, 0xFFFFFFFF000007FF, 0xFFCFFFFFFFFFFFFF,
- 0xFFFFFFFFFF3FFFFF, 0x7FFFFFFFFFFFFDFF, 0xFFFF7FFFFFFFFFFF,
- 0xFFFFFFFF7FFFFFFF, 0xFE0C7FFFFFFFFFFF, 0xFFFF20BFFFFFFFFF,
- 0x180FFFFFFFFFF, 0x7F7F7F7F007FFFFF, 0x7F7F7F7F, 0x7FFF,
+ 0xFFFFFFFFFFBFFFFF, 0xFE0C7FFFFFFFFFFF, 0xFFFF20BFFFFFFFFF,
+ 0x180FFFFFFFFFF, 0x7F7F7F7F007FFFFF, 0x7F7F7F7F, 0x3FFFFFFF,
0xFFFFFFFFFBFFFFFF, 0xFFFFFFFFFFFFF, 0xFFF0000003FFFFF,
0xFFFF03FFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFF87FFFFF,
- 0xFFFEFFFFFFFFFFE0, 0x7FFFFFFFFFF7FFF, 0xFFFF000FFFFFFFFF,
- 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF, 0xFFFFFFFFFFFF1FFF,
- 0xFFFFFFFFFFFF007F, 0xFFFFFFFFFFF, 0xC0087FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF,
- 0xFCFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFF, 0xFF80000000000000,
- 0x3FF0F9FFFFFF7BB, 0xFFFFFFFFFFFFFF, 0x7FFC000003FFC00F,
- 0xFFFFC03FFFFFFFFF, 0x1FFFFFFF800C007F, 0xEC37FFFFFFFFFFF8,
- 0x7FFFFFDFC3FFBFFF, 0x1981FFFFFFFFFF, 0xEFFFFFFFF3FF2FF7,
- 0x3E62FFFFFFFFFFFF, 0x3FCFFFF8000005, 0xFFFF7F7F007E7E7E,
- 0xFFFF003FFFFFFFFF, 0x3FF1EDFFFFFFFFF, 0xFFFFFFFFFFFF87F,
+ 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFFFFFF7FFF, 0xFFFF000FFFFFFFFF,
+ 0xFFFFFFFF7FFFFFFF, 0xFFFFFFFFFFFF1FFF, 0xFFFFFFFFFFFF007F, 0xFFFFFFFFFFF,
+ 0xC0087FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF, 0xFCFFFFFFFFFFFF,
+ 0xFFFC000003EB07FF, 0x3FF0F9FFFFFF7BB, 0xFFFFFFFFFFFFFF,
+ 0x7FFC000003FFC00F, 0xFFFFC03FFFFFFFFF, 0x1FFFFFFF800C007F,
+ 0xCC37FFFFFFFFFFF8, 0x7FFFFFDFC3FFBFFF, 0x1981FFFFFFFFFF,
+ 0xEFFFFFFFF3FF2FF7, 0x3E62FFFFFFFFFFFF, 0x3FCFFFF8000005,
+ 0xFFFF7F7F007E7E7E, 0x3FF1EDFFFFFFFFF, 0xFFFFFFFFFFFF87F,
0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFFFFA0F8007F, 0xFFFFFFFFFFFFFFDB,
- 0xFFFFFFFFFFF80003, 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF,
- 0x3FFF0000000000FF, 0xFFFF000003FF0000, 0xFFDF0F7FFFF7FFFF,
- 0x1FFFFFFFFFFFFFFF, 0x7FFFFFFF3FFFFFFF, 0x30007F7F1CFCFCFC,
+ 0xFFFFFFFFFFF80007, 0xFFFFFFFFFFFCFFFF, 0xFFFF0000000080FF,
+ 0xFFFF000003FF0000, 0xFFDF0F7FFFF7FFFF, 0x1FFFFFFFFFFFFFFF,
+ 0x7FFFFFFF3FFFFFFF, 0x30007F7F1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 13, 14, 15, 7, 16, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -1573,100 +2181,114 @@ pub const GRAPHEME_BASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
0, 1, 2, 3, 4, 2, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 2, 2, 14, 15, 16, 17,
- 7, 7, 2, 2, 2, 2, 18, 19, 7, 7, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 7, 2, 34, 35, 36, 37, 7, 7, 7, 7, 38, 7, 7, 16, 39, 7, 7,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 7, 49, 50, 51, 52, 7, 7, 53, 54, 55,
- 56, 7, 7, 57, 58, 59, 60, 61, 62, 63, 7, 7, 7, 64, 7, 65, 66, 7, 7, 7, 7,
- 67, 68, 69, 70, 7, 7, 7, 7, 71, 72, 73, 7, 74, 75, 76, 7, 7, 7, 7, 77, 7,
- 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 78, 7, 2, 79, 2, 2, 2,
- 80, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 81, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 18, 7, 2, 2, 2, 2, 19, 20, 21, 7, 22, 23, 24, 25, 26, 7, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 7, 2, 36, 37, 38, 39, 7, 7, 7, 7, 40, 41, 7, 16, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 7, 54, 55, 56, 57, 7, 7, 58,
+ 59, 60, 61, 7, 7, 62, 63, 64, 65, 66, 67, 68, 69, 7, 7, 70, 7, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 7, 7, 7, 7, 81, 82, 83, 7, 84, 85, 86, 7, 7,
+ 7, 7, 87, 7, 7, 88, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 90, 7,
+ 2, 91, 2, 2, 2, 92, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 93, 37,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 82, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2,
- 2, 2, 2, 70, 83, 7, 84, 85, 86, 87, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 88,
- 7, 2, 89, 90, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 2, 2, 2, 2, 2, 2, 2, 2, 80, 95, 96, 97, 98, 99, 100, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 2, 101, 7, 2, 102, 103, 104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 35, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 93, 94, 2, 2, 2, 2, 2, 95, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 58, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 105, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 106, 2, 2, 2, 2, 107, 108, 2, 2, 2, 2, 2, 109, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 96, 97, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 2, 2, 2, 98, 99, 100, 101, 102, 2, 103, 7, 104, 2, 105, 7, 7, 2, 106,
- 107, 108, 109, 110, 2, 2, 2, 2, 111, 2, 2, 2, 2, 112, 2, 2, 2, 2, 2, 2, 2,
- 2, 113, 114, 115, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 110, 111, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 116, 2, 117, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 118, 119, 7, 7, 7, 7, 7, 120, 121, 122, 123, 7, 7, 7, 7, 124, 2,
- 125, 126, 127, 124, 128, 129, 130, 131, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 132, 2, 133, 2, 134, 135, 136, 137, 7, 138, 139, 140,
- 141, 7, 142, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 143, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 93, 2, 92, 2, 2, 2, 112, 113, 114,
+ 115, 116, 2, 117, 7, 118, 2, 119, 7, 7, 2, 120, 121, 122, 123, 124, 2, 2,
+ 2, 2, 125, 2, 2, 2, 2, 126, 2, 2, 2, 2, 2, 2, 2, 2, 127, 128, 129, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 130, 7, 7, 7, 7, 7, 7, 7,
+ 131, 132, 7, 7, 7, 7, 133, 134, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 135, 2, 2, 2, 136, 2, 137, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 138, 139, 7, 140, 7, 7, 7, 141, 142, 143, 144, 7, 7, 7, 7, 145, 2, 146,
+ 147, 2, 2, 148, 149, 150, 151, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 152, 2, 153, 2, 154, 155, 156, 157, 7, 2, 2, 2, 2, 2, 158, 159,
+ 160, 2, 2, 161, 162, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 119, 2, 2, 2,
- 144, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 163, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 145, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 146, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 164, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 165, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 166,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 167, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2,
- 2, 2, 2, 147, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF,
- 0xFF8FFFFFFFFFFF87, 0x10FFF7FFF, 0x1FFFFFFFFFFF0000, 0,
+ 0xFF8FFFFFFFFFFF87, 0x11FFF7FFF, 0x1FFFFFFFFFFF0000, 0,
0xFFFFFFFF1FFFFFFF, 0xFFFFFFE0001FFFF, 0xFFFFE00FFFFFFFFF,
0x3FFFFFFFFF07FF, 0xFFFFFFFFBFFFFFFF, 0x3FFF0F, 0xFFFF03FF3FFFFFFF,
- 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0x800FFFFFFFFF, 0x7FFFFFFFFFFFFF,
- 0xFF003FFFFF, 0x91BFFFFFFFFFFD3F, 0xFFFFFFFFFFBFFFFF, 0xFF807FFFFFFF,
+ 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xF7FF800FFFFFFFFF,
+ 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x7FDFFFFFFFFFFBF,
+ 0x91BFFFFFFFFFFD3F, 0xFFFFFFFFFFBFFFFF, 0xFF807FFFFFFF,
0xF837FFFF00000000, 0x83FFFFFF8FFFFFFF, 0xF0FFFFFFFFFFFFFF,
0xFFFFFFFFFFFCFFFF, 0x3FFFFFFEEF0001, 0xFFFFFFFF01FF01FF, 0xFFFFFFFF,
0x7FF81FFFFFFFFF, 0xFE3FFFFFFFFFFFFF, 0xFF07FFFFFF3FFFFF, 0xFE001E03FFFF,
0x1FF, 0x7FFFFFFFFFFFF, 0xFC07FFFFFFFFFFFF, 0x3FF000FFFFFFFFF,
- 0x7FFFFFFF00000000, 0x3FE003F, 0xFFFFFFFFFFFFFD, 0xFFFFFFFC3F80,
+ 0x7FFFFFFF00000000, 0x323FFFFFFFFFF, 0xFFFF000003FE003F,
+ 0xFFFF0000000003C3, 0x7FFFFF00000FFF, 0xFFFFFFFFFFFFFD, 0x26FFFFFFFC3F80,
0xD987FFFFFFFFFFFC, 0x3FF01FFFFFF0003, 0xFFC0107FFFFFFFF8,
- 0x77FFFFFFFF007F, 0x803FFFFFFFFFFFFC, 0x1FFFFEFFFF21FF,
+ 0x77FFFFFFFF00FF, 0x803FFFFFFFFFFFFC, 0x1FFFFEFFFF61FF,
0x3F2C7FFFFFFBFFFF, 0xFFFF03FFBFFFBD7F, 0x3FF00077FFFFFFF,
- 0xA3EDFDFFFFF99FEC, 0xFE001399E, 0xFFFFFFFFFFFFFF, 0x2BFFFFA3,
+ 0xA3EDFDFFFFF99FEC, 0xFE001399E, 0xFFFFFFFFFFFFFF, 0x3AFFFFFA3,
0x5A06FFFFFFFFFFFF, 0x3FF00F2, 0x4F037FFFFFFFFFFF, 0xFFFFFFE,
- 0x5807FFFFFFFFFFFF, 0x1FFF03FF001E, 0x40D7FFFFFFFFFF, 0x3FF,
- 0xFFFF004307FFFFFF, 0x9007FFFFFFFFFFF, 0xFFFFFFFF00000000,
- 0x8007FFFFFFFFFFFF, 0x8607FFFFFFFFF801, 0xFFFFFFFFF181007F, 0x7FC8003CF,
+ 0x5807FFFFFFFFFFFF, 0x1FFF03FF001E, 0x340D7FFFFFFFFFF, 0x3FF,
+ 0xFFFF004307FFFFFF, 0x7F, 0x9007FFFFFFFFFFF, 0xFFFFFFFF00000000,
+ 0x8007FFFFFFFFFFFF, 0xA1BEFFFFFF6FF27F, 0x3FF0077, 0xFFFFFCFF00000000,
+ 0x1EF00FFFFF, 0x8607FFFFFFFFF801, 0xFFFFFFFFF181007F, 0xFFFF0007FC8003FF,
0x1FFFFFFFFFFFFFF, 0x4000FFFFFFFFFDFF, 0xFFFF1FFFFFFF003F,
0x1202000000FFFF, 0x1FFFFFFFFFB7F, 0xFFFFFDBF03FF0040, 0x3FF01587FFF,
- 0x1E7FFFF00000000, 0x3FFFFFF, 0x1F7FFFFFFFFFFF, 0xF, 0x7FFFFFFFFFFF, 0x7F,
- 0xC3FF7FFFFFFF, 0x203FFFFFFF0000, 0xFF80FFFFFFFFFFFF, 0xE0FFFFFBFBFF003F,
- 0xFFFF, 0x7FFFFFF, 0x7FFFFFFFFFFF001F, 0xFFF80000, 0x300000000,
- 0x3FFFFFFFFFFFF, 0x7FFFFFFF, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF,
+ 0x1E7FFFF00000000, 0x1000000000000, 0x8003FFFFFFFFFFFF, 0x3FFFFFF,
+ 0x1F7FFFFFFFFFFF, 0xF, 0xFFFFFFFFFFFF0000, 0x7FFFFFFFFFFF,
+ 0xFFFFC3FF7FFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x203FFFFFFF03FF,
+ 0xFF80FFFFFFFFFFFF, 0xE0FFFFFBFBFF003F, 0xFFFF, 0x7FFFFFF,
+ 0xFFFFFFFFFFFF07FF, 0xFFF800FF, 0x3000F00000000, 0x3FFFFF,
+ 0x6FEF000000000000, 0x7FFFFFFFF, 0xFFFF00F000070000, 0xFFFFFFFFFFFFFFF,
0x1FFF07FFFFFFFFFF, 0x93FF01FF, 0x3FFFFFFFFFFFFF, 0xFFFFFE7FFFFFFFFF,
- 0x3C5FFFFFFFFF, 0xFFFFC3FFFFFFF018, 0x1FFFFFFFFFF, 0x23, 0xFFFFF00000000,
+ 0x3C5FFFFFFFFF, 0xFFFFC3FFFFFFF018, 0x7FFFFFFFFFF, 0x23, 0xFFFFF00000000,
0x1FFFFFF007FFFFF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF,
0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F,
0xFFFFFF3FFFFFFFFF, 0xFFFFFFFFFFFFCFFF, 0x780000000000000,
- 0xFFDFE00000000000, 0xFEF, 0xFF9F, 0xC3FF000F, 0xFFFE000000000000,
- 0x1FFFFFFFFFFFFF, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84,
- 0xFFFFBEE0FFFFBFF, 0x3000000000000, 0xFFFF0FFFFFFFFFFF,
- 0xFFFE7FFF000FFFFF, 0x3FFFFFFFFEFFFE, 0xFFFFFFFFFFFF1FFF, 0x1FFFFFFFFFFF,
- 0xFFFFFFC000000000, 0xFFFFFFFFFFF0007, 0x3F000301FF, 0x3FF1FFF001FFFFF,
- 0xFFFFFFFFFFFFF, 0x1FFFFFF, 0xFFFFFFFFFFFF0FFF, 0xFFFFFFFF03FF00FF,
- 0x3FFFFFFF00FF, 0x7FFFFFFFFFFF0FFF, 0xF479FFFFFFFFFFFF, 0x3FF0007FFFFFFFF,
- 0xFFFFFFFFFFFF0007, 0x3FFF00000000, 0x7FFFFF, 0xFFFFFFFF3FFFFFFF,
- 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF,
+ 0xFFDFE00000000000, 0xFEF, 0x7FFFFFFF, 0x3F801FFFFFFFFFFF, 0xC3FF,
+ 0x3FFFFFFF0000, 0x83FF0FFFFFFFFFFF, 0x7FFF6F7F00000000, 0xFF9F,
+ 0xC3FF080F, 0xFFFE000000000000, 0x1FFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFE,
+ 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x3000000000000,
+ 0xFFFF0FFFFFFFFFFF, 0xFFFE7FFF000FFFFF, 0x3FFFFFFFFEFFFE, 0x3FFFFFFFFFFF,
+ 0xFFFFFFC000000000, 0xFFFFFFFFFFF0007, 0x3F000301FF, 0x1FFF1FFFE0FFFFFF,
+ 0xFFFFFFFFFFFFF, 0x10FFF01FFFFFF, 0xFFFFFFFFFFFF0FFF, 0xFFFFFFFF03FF00FF,
+ 0x33FFFFFFF00FF, 0x1F1F3FFF000FFFFF, 0x7FF1FFFFFFF007F, 0x7F00FF03FF003F,
+ 0xFFFFFFFFFFF7FFFF, 0x3FF0000000007FF, 0xFFFFFFFF3FFFFFFF,
+ 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0x7FF,
],
};
@@ -1679,69 +2301,84 @@ pub const GRAPHEME_EXTEND: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37,
- 38, 2, 39, 2, 40, 2, 2, 2, 41, 42, 43, 2, 44, 45, 46, 47, 48, 2, 2, 49, 2,
- 2, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 51, 2, 2, 52, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53, 2, 54, 2, 55, 2, 2, 2, 2, 2, 2,
- 2, 2, 56, 2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 58, 59, 60, 2, 2, 2, 2, 61, 2, 2, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 2, 2, 2, 2, 2, 59, 2,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 35, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 36, 37, 38, 39, 40, 34, 41, 34, 42, 34, 34, 34, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 34, 34, 52, 34, 34, 34, 53, 34, 34, 34, 34, 34,
+ 34, 34, 34, 54, 34, 34, 55, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 56, 34, 57, 34, 58, 34, 34, 34, 34, 34, 34, 34, 34, 59, 34, 60, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 61, 62, 63, 34, 34, 34, 34, 64, 34, 34, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 34, 34, 34, 74, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 75, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 76, 34, 34, 34, 34, 34, 62, 34,
],
tree2_level2: &[
- 0x3EEFFBC00000, 0xE000000, 0, 0xFFFFFFFBFFF80000, 0x1400000000000007,
- 0xC00FE21FE, 0x5000000000000002, 0x4000000C0080201E, 0x1000000000000006,
- 0x23000000023986, 0xFC00000C000021BE, 0xD000000000000002, 0xC00C0201E,
- 0x4000000000000004, 0x802001, 0xC000000000000011, 0xC00603DC1,
- 0x9000000000000002, 0xC00603044, 0x5800000000000003, 0xC0080201E,
- 0x805C8400, 0x7F2000000000000, 0x7F80, 0x1BF2000000000000, 0x3F00,
- 0x2A0000003000000, 0x7FFE000000000000, 0x1FFFFFFFFEFFE0DF, 0x40,
- 0x66FDE00000000000, 0x1E0001C3000000, 0x20002064, 0xE0000000,
- 0x1C0000001C0000, 0xC0000000C0000, 0x3FB0000000000000, 0x200FFE40, 0x3800,
- 0x20000000060, 0xE04018700000000, 0x9800000, 0x9FF81FE57F400000,
- 0x7FFF000000000000, 0x17D000000000000F, 0xFF80000000004, 0x3B3C00000003,
- 0x3A34000000000, 0xCFF00000000000, 0x31021FDFFF70000, 0xFBFFFFFFFFFFFFFF,
- 0x1000, 0x1FFFFFFFF0000, 0x3800000000000, 0x8000000000000000,
- 0xFFFFFFFF00000000, 0xFC0000000000, 0x6000000, 0x3FF7800000000000,
- 0xC0000000, 0x3000000000000, 0x6000000844, 0x8003FFFF00000030,
- 0x3FC000000000, 0x3FF80, 0x13C8000000000007, 0x2000000000,
- 0x667E0000000000, 0x1000000000001008, 0xC19D000000000000,
- 0x40300000000002, 0x212000000000, 0x40000000, 0xFFFF0000FFFF,
+ 0x3EEFFBC00000, 0xE000000, 0xFF000000, 0xFFFFFFFBFFFFFC00,
+ 0x1400000000000007, 0xC00FE21FE, 0x5000000000000002, 0x4000000C0080201E,
+ 0x1000000000000006, 0x23000000023986, 0xFC00000C000021BE,
+ 0xD000000000000002, 0xC00E0201E, 0x4000000000000004, 0x802001,
+ 0xD000000000000011, 0xC00603DC1, 0x9000000000000002, 0xC00603044,
+ 0x5800000000000003, 0xC0080201E, 0x2, 0x805C8400, 0x7F2000000000000,
+ 0x7F80, 0x1FF2000000000000, 0x3F00, 0x2A0000003000000, 0x7FFE000000000000,
+ 0x1FFFFFFFFEFFE0DF, 0x40, 0x66FDE00000000000, 0x1E0001C3000000,
+ 0x20002064, 0, 0xE0000000, 0xC0000001C0000, 0xC0000000C0000,
+ 0x3FB0000000000000, 0x200FFE40, 0xB800, 0x20000000060, 0xE04018700000000,
+ 0x9800000, 0x9FF81FE57F400000, 0xFFFF000000000000, 0x7FFF,
+ 0x17F000000000000F, 0xFF80000000004, 0x3B3C00000003, 0x3A34000000000,
+ 0xCFF00000000000, 0x31021FDFFF70000, 0xFFFFFFFFFFFFFFFF, 0x1000,
+ 0x1FFFFFFFF0000, 0x3800000000000, 0x8000000000000000, 0xFFFFFFFF00000000,
+ 0xFC0000000000, 0x6000000, 0x3FF7800000000000, 0xC0000000,
+ 0x3000000000000, 0x106000000844, 0x8003FFFF00000030, 0x3FC000000000,
+ 0x3FF80, 0x33C8000000000007, 0x2000000000, 0x667E0000000000,
+ 0x1000000000001008, 0xC19D000000000000, 0x40300000000002, 0x212000000000,
+ 0x40000000, 0xFFFF0000FFFF,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1749,48 +2386,53 @@ pub const GRAPHEME_EXTEND: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15,
- 0, 0, 16, 17, 18, 0, 0, 19, 20, 21, 22, 0, 0, 23, 24, 25, 26, 27, 0, 28,
- 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 0, 0, 0, 33, 0, 34, 0,
- 35, 36, 37, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 0, 0, 19, 20, 21, 0, 0, 22, 23, 24, 25, 0, 0, 26, 27, 28, 29, 30, 0,
+ 31, 0, 0, 0, 32, 0, 0, 0, 33, 34, 0, 35, 36, 37, 38, 0, 0, 0, 0, 0, 39, 0,
+ 40, 0, 41, 42, 43, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45,
+ 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 48, 49, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 53, 53, 53,
- 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 52,
+ 0, 0, 0, 0, 0, 0, 0, 53, 54, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 57, 58, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 46, 0,
+ 0, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 62, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, 0, 0, 65, 65, 65, 66, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
],
tree3_level3: &[
0, 0x2000000000000000, 0x100000000, 0x7C0000000000000, 0x870000000000F06E,
- 0x6000000000, 0xF000000000, 0x1FFC0, 0xFF00000000000002,
- 0x800000000000007F, 0x678000000000003, 0x1FEF8000000007, 0x8000000000000,
- 0x7FC0000000000003, 0x1E00, 0x40D3800000000000, 0x7F880000000,
- 0x5800000000000003, 0x1F1FC000800001, 0xFF00000000000000, 0x4000005C,
- 0xA5F9000000000000, 0xD, 0xB03C800000000000, 0x30000001,
- 0xA7F8000000000000, 0x1, 0xBF280000000000, 0xFBCE0000000,
- 0x6FF800000000000, 0x79F80000000007FE, 0xE7E0080, 0x37FFC00,
- 0xBF7F000000000000, 0x6DFCFFFFFC0000, 0xB47E000000000000, 0xBF, 0xA30000,
- 0x18000000000000, 0x1F000000000000, 0x7F000000000000, 0x78000, 0x60000000,
- 0xF807C3A000000000, 0x3C0000000FE7, 0x1C, 0xF87FFFFFFFFFFFFF,
- 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F, 0x7F0000, 0x7F0,
- 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF,
+ 0x6000000000, 0xF000000000, 0x180000000000, 0x1FFC0, 0x3C,
+ 0xFF00000000000002, 0x801900000000007F, 0x678000000000003, 0x4,
+ 0x1FEF8000000007, 0x8000000000000, 0x7FC0000000000003, 0x9E00,
+ 0x40D3800000000000, 0x7F880000000, 0x5800000000000003, 0x1F1FC000800001,
+ 0xFF00000000000000, 0x4000005C, 0xA5F9000000000000, 0xD,
+ 0xB03C800000000000, 0x30000001, 0xA7F8000000000000, 0x1, 0xBF280000000000,
+ 0xFBCE0000000, 0x6FF800000000000, 0x5801000000000000, 0x8, 0x10CF00000,
+ 0x79F80000000007FE, 0xE7E0080, 0x37FFC00, 0xBF7F000000000000,
+ 0x6DFCFFFFFC0000, 0xB47E000000000000, 0xBF, 0xA30000, 0x18000000000000,
+ 0x1F000000000000, 0x7F000000000000, 0x8000, 0x78000, 0x1000000000,
+ 0x60000000, 0xFFFF3FFFFFFFFFFF, 0x7F, 0xF807C3A000000000, 0x3C0000000FE7,
+ 0x1C, 0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F,
+ 0x400000000000, 0xF00000000000, 0x7F0000, 0x7F0, 0xFFFFFFFF00000000,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF,
],
};
@@ -1801,7 +2443,7 @@ pub const GRAPHEME_LINK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 0, 3, 4,
- 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
0, 0, 5, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1843,9 +2485,9 @@ pub const GRAPHEME_LINK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level2: &[
0, 0x2000, 0x1800000000000000, 0x400, 0x400000000000000, 0x10,
- 0x600000000000000, 0x10000000100000, 0x40000, 0x100000000, 0xC0000000000,
- 0xC000000000000, 0x8000000000000000, 0x40, 0x80000, 0x1, 0x40000000000000,
- 0x200000000000,
+ 0x600000000000000, 0x10000000300000, 0x40000, 0x100000000, 0xC0000000000,
+ 0xC000000000000, 0x8000000000000000, 0x100000000040, 0x80000, 0x1,
+ 0x40000000000000, 0x200000000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1865,16 +2507,16 @@ pub const GRAPHEME_LINK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 4, 0, 0, 5, 6, 0, 0,
7, 0, 8, 0, 0, 0, 9, 0, 9, 0, 0, 1, 0, 1, 0, 10, 0, 11, 0, 0, 0, 3, 0, 0,
- 0, 0, 0, 0, 0, 12, 13, 14, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 15, 16, 0, 0, 0,
+ 0, 12, 0, 0, 13, 14, 15, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 18, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x8000000000000000, 0x8000000000000040, 0x200000000000000,
+ 0, 0x8000000000000000, 0x8001000000000040, 0x200000000000000,
0x18000000000000, 0x1, 0x20000000000000, 0x40000000000, 0x2000, 0x4,
- 0x40000000000000, 0x80000000000, 0x10000000000000, 0x80, 0x2000000, 0x30,
- 0x800000,
+ 0x40000000000000, 0x80000000000, 0x6000000000000000, 0x100000000,
+ 0x10000000000000, 0x80, 0x2000000, 0x30, 0x800000,
],
};
@@ -2130,16 +2772,16 @@ pub const ID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4,
35, 36, 37, 38, 39, 40, 41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46,
47, 4, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 4, 61, 4, 62,
- 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60,
- 60, 60, 60, 60, 60, 86, 42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60,
- 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 63, 64, 65, 66, 4, 4, 4, 4, 4, 4, 4, 4, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 4, 4, 4, 79, 80, 81, 82, 83, 78, 78, 78,
+ 78, 78, 78, 78, 78, 84, 42, 85, 86, 87, 4, 88, 89, 78, 78, 78, 78, 78, 78,
+ 78, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 52, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -2152,158 +2794,176 @@ pub const ID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62,
- 4, 102, 103, 104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 90, 91, 4, 4, 4, 4, 92, 93, 4, 94, 95, 4, 96, 97, 98, 62, 4,
+ 99, 100, 101, 4, 102, 103, 104, 4, 105, 106, 107, 4, 108, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114, 115, 116, 97, 117, 4, 4,
- 4, 4, 118, 119, 120, 121, 122, 123, 4, 124, 125, 126, 127, 128,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 109, 110, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 4, 4, 4, 4, 4, 100, 4, 111, 112, 113, 94, 114, 4, 4, 4, 4,
+ 115, 116, 117, 118, 119, 120, 4, 121, 122, 123, 124, 125,
],
tree2_level2: &[
- 0x3FFFFFFFFFFF, 0x7FF0FFFFFFF, 0x3FDFFFFF00000000, 0xFFFFFFFBFFF80000,
- 0xFFFFFFFFFFFFFFFF, 0xFFFEFFCFFFFFFFFF, 0xF3C5FDFFFFF99FEF,
- 0x5003FFCFB080799F, 0xD36DFDFFFFF987EE, 0x3FFFC05E023987,
- 0xF3EDFDFFFFFBBFEE, 0xFE00FFCF00013BBF, 0xF3EDFDFFFFF99FEE,
- 0x2FFCFB0C0399F, 0xC3FFC718D63DC7EC, 0xFFC000813DC7, 0xE3FFFDFFFFFDDFFF,
- 0xFFCF07603DDF, 0xF3EFFDFFFFFDDFEF, 0x6FFCF40603DDF, 0xFFFFFFFFFFFDDFEF,
- 0xFC00FFCF80F07DDF, 0x2FFBFFFFFC7FFFEC, 0xCFFC0FF5F847F,
- 0x7FFFFFFFFFFFFFE, 0x3FF7FFF, 0x3BFFECAEFEF02596, 0xF3FF3F5F,
- 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF, 0x40,
- 0xFFFFFFFFFFFF03FF, 0xFFFFFFFF3FFFFFFF, 0xF7FFFFFFFFFF20BF,
+ 0x3FFFFFFFFFFF, 0xFFFF07FF0FFFFFFF, 0xFFFFFFFFFF007EFF,
+ 0xFFFFFFFBFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFEFFCFFFFFFFFF,
+ 0xF3C5FDFFFFF99FEF, 0x5003FFCFB080799F, 0xD36DFDFFFFF987EE,
+ 0x3FFFC05E023987, 0xF3EDFDFFFFFBBFEE, 0xFE00FFCF00013BBF,
+ 0xF3EDFDFFFFF99FEE, 0x2FFCFB0E0399F, 0xC3FFC718D63DC7EC, 0xFFC000813DC7,
+ 0xF3FFFDFFFFFDDFFF, 0xFFCF27603DDF, 0xF3EFFDFFFFFDDFEF, 0x6FFCF60603DDF,
+ 0xFFFFFFFFFFFDDFFF, 0xFC00FFCF80F07DDF, 0x2FFBFFFFFC7FFFEE,
+ 0xCFFC0FF5F847F, 0x7FFFFFFFFFFFFFE, 0x3FF7FFF, 0x3FFFFFAFFFFFF7D6,
+ 0xF3FF3F5F, 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF,
+ 0x40, 0xFFFFFFFFFFFF03FF, 0xFFFFFFFF3FFFFFFF, 0xF7FFFFFFFFFF20BF,
0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
0xFFFFFFFFFF3DFFFF, 0x3FE00E7FFFFFF, 0xFFFFFFFF0000FFFF,
0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF,
- 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF, 0x1FFFFF001FDFFF, 0xDDFFF000FFFFF,
- 0x3FF308FFFFF, 0xFFFFFFFF03FF3800, 0x1FFFFFFFFFFFFFF, 0xFFFF07FFFFFFFFFF,
+ 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF, 0x1FFFFF803FFFFF, 0xDDFFF000FFFFF,
+ 0x3FF308FFFFF, 0xFFFFFFFF03FFB800, 0x1FFFFFFFFFFFFFF, 0xFFFF07FFFFFFFFFF,
0x3FFFFFFFFFFFFF, 0xFFF0FFF7FFFFFFF, 0x1F3FFFFFFFFFC0, 0xFFFF0FFFFFFFFFFF,
- 0x7FF03FF, 0xFFFFFFFF0FFFFFFF, 0x9FFFFFFF7FFFFFFF, 0x3FFF008003FF03FF, 0,
- 0xFF80003FF0FFF, 0xFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFE3FF,
- 0xE7FFFFFFFFFF01FF, 0x3FFFFFFFFF70000, 0xFBFFFFFFFFFFFFFF,
+ 0x7FF03FF, 0xFFFFFFFF0FFFFFFF, 0x9FFFFFFF7FFFFFFF, 0xBFFF008003FF03FF,
+ 0x7FFF, 0xFF80003FF1FFF, 0xFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF,
+ 0x3FFFFFFFFFFFE3FF, 0xE7FFFFFFFFFF01FF, 0x7FFFFFFFFF70000,
0xFFFFFFFF3F3FFFFF, 0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF,
0x1FDC1FFF0FCF1FDC, 0x8000000000000000, 0x8002000000100001, 0x1FFF0000,
- 0x1FFE21FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0, 0x1FF,
- 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0xFF81FFFFFFFFF,
- 0xFFFF20BFFFFFFFFF, 0x800080FFFFFFFFFF, 0x7F7F7F7F007FFFFF,
- 0xFFFFFFFF7F7F7F7F, 0x1F3EFFFE000000E0, 0xFFFFFFFEFE7FFFFF,
- 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0x7FFFFFF00007FFF,
- 0xFFFF000000000000, 0xFFFFFFFFFFFF, 0x1FFF, 0x3FFFFFFFFFFF0000,
+ 0x1FFE21FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0, 0x1FF, 0,
+ 0xFF81FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x800080FFFFFFFFFF,
+ 0x7F7F7F7F007FFFFF, 0xFFFFFFFF7F7F7F7F, 0x1F3EFFFE000000E0,
+ 0xFFFFFFFEFE7FFFFF, 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0,
+ 0xFFFFFFFF00007FFF, 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000,
0xFFFFFFF1FFF, 0xBFF0FFFFFFFFFFFF, 0x3FFFFFFFFFFFF, 0xFFFFFFFCFF800000,
- 0x3FFFFFFFFFFF9FF, 0xFF80000000000000, 0xFFFFFFFFFF, 0xE8FFFFFF03FF003F,
- 0xFFFF3FFFFFFFFFFF, 0x1FFFFFFF000FFFFF, 0x7FFFFFFF03FF8001,
- 0x7FFFFFFFFFFFFF, 0xFC7FFFFF03FF3FFF, 0x7CFFFF38000007,
- 0xFFFF7F7F007E7E7E, 0xFFFF003FF7FFFFFF, 0x3FF37FFFFFFFFFF,
- 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0x3FFFFFF, 0x5F7FFDFFE0F8007F,
- 0xFFFFFFFFFFFFFFDB, 0xFFFFFFFFFFF80000, 0x3FFFFFFFFFFFFFFF,
- 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF, 0xFFF0000000000FF,
- 0x18FFFF0000FFFF, 0xFFDF00000000E000, 0x1FFFFFFFFFFFFFFF,
- 0x87FFFFFE03FF0000, 0xFFFFFFC007FFFFFE, 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
+ 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x10FFFFFFFFFF,
+ 0xE8FFFFFF03FF003F, 0xFFFF3FFFFFFFFFFF, 0x1FFFFFFF000FFFFF,
+ 0x7FFFFFFF03FF8001, 0x7FFFFFFFFFFFFF, 0xFC7FFFFF03FF3FFF,
+ 0x7CFFFF38000007, 0xFFFF7F7F007E7E7E, 0xFFFF03FFF7FFFFFF,
+ 0x3FF37FFFFFFFFFF, 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0x3FFFFFF,
+ 0x5F7FFDFFE0F8007F, 0xFFFFFFFFFFFFFFDB, 0xFFFFFFFFFFF80000,
+ 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF,
+ 0xFFF0000000000FF, 0x18FFFF0000FFFF, 0xFFDF00000000E000,
+ 0x1FFFFFFFFFFFFFFF, 0x87FFFFFE03FF0000, 0xFFFFFFC007FFFFFE,
+ 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 12, 13, 14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16,
- 4, 4, 2, 2, 2, 2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27,
- 28, 29, 30, 31, 4, 2, 32, 33, 33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 4,
- 2, 37, 3, 38, 39, 40, 2, 41, 42, 4, 43, 44, 45, 46, 4, 4, 2, 47, 2, 48, 4,
- 4, 49, 50, 2, 51, 52, 53, 54, 4, 4, 4, 3, 4, 55, 56, 4, 4, 4, 4, 57, 58,
- 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4,
+ 17, 4, 2, 2, 2, 2, 18, 19, 20, 4, 21, 22, 23, 24, 25, 4, 26, 4, 27, 28,
+ 29, 30, 31, 32, 33, 4, 2, 34, 35, 35, 36, 4, 4, 4, 4, 4, 37, 4, 38, 39,
+ 40, 41, 2, 42, 3, 43, 44, 45, 2, 46, 47, 4, 48, 49, 50, 51, 4, 4, 2, 52,
+ 2, 53, 4, 4, 54, 55, 2, 56, 57, 58, 59, 60, 4, 4, 3, 4, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 57, 4, 4, 4, 4, 70, 71, 72, 4, 73, 74, 75, 4, 4, 4, 4,
+ 76, 4, 4, 77, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 78, 4, 2, 79,
+ 2, 2, 2, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 81, 82, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 60, 72, 4, 73, 17, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 2, 76,
- 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+ 2, 2, 2, 2, 2, 2, 2, 57, 83, 67, 84, 18, 85, 86, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 2, 4, 4, 2, 87, 88, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 80, 2, 2, 2, 2, 2, 81, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 91, 34, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 84, 85, 4, 4, 86, 4, 4, 4, 4, 4, 4, 2, 87, 88, 89, 90, 91, 2,
- 2, 2, 2, 92, 93, 94, 95, 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 98, 99, 100, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 101, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 2, 2, 2, 102, 2, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 92, 2, 2, 2, 2, 93, 94, 2, 2, 2, 2, 2, 95, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 98, 60, 4, 4, 4, 4, 4, 4, 4, 99, 100, 4, 4, 101, 4, 4,
+ 4, 4, 4, 4, 2, 102, 103, 104, 105, 106, 2, 2, 2, 2, 107, 108, 109, 110,
+ 111, 112, 4, 4, 4, 4, 4, 4, 4, 4, 113, 114, 115, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 23, 4, 4, 4, 116, 4, 4, 4, 117, 118, 4, 4, 4,
+ 4, 119, 120, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 121,
+ 2, 2, 2, 122, 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 124, 125, 126, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 128, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 2, 2, 2, 11,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 130, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2,
+ 2, 131, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 132, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 110, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 111, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 133,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
0x1FFFFFFFFFFFFF, 0x2000000000000000, 0xFFFFFFFF1FFFFFFF, 0x10001FFFF,
0xFFFFE000FFFFFFFF, 0x7FFFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F,
- 0xFFFF03FF3FFFFFFF, 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xFFFFFFFFF,
- 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF,
- 0x7FFFFFFF, 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF,
+ 0xFFFF03FF3FFFFFFF, 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF,
+ 0xF7FF000FFFFFFFFF, 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF,
+ 0x7FDFFFFFFFFFFBF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF,
+ 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF,
0x873FFFFFFEEFF06F, 0x1FFFFFFF00000000, 0x1FFFFFFF, 0x7FFFFFFEFF,
0x3FFFFFFFFFFFFF, 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF,
- 0x3FF00FFFFFFFFFF, 0xFFFF00801FFFFFFF, 0x1FFFF, 0x8000FFC00000007F,
- 0x3FF01FFFFFF0000, 0xFFDFFFFFFFFFFFFF, 0x4FFFFFFFFF0070, 0x17FF1E1F,
- 0x40FFFFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F, 0x3FF07FFFFFFFFFF,
- 0xFBEDFDFFFFF99FEF, 0x1F1FCFE081399F, 0x43FF07FF, 0x3FF00BF,
- 0xFF3FFFFFFFFFFFFF, 0x3F000001, 0x3FF0011, 0xFFFFFFFFFFFFFF, 0x3FF,
- 0x3FF0FFFE7FFFFFF, 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF,
- 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080, 0x23FFFFCF, 0x1FFFFFFFFFFFFFF,
+ 0x3FF00FFFFFFFFFF, 0x31BFFFFFFFFFF, 0xFFFF00801FFFFFFF,
+ 0xFFFF00000001FFFF, 0xFFFF00000000003F, 0x7FFFFF0000001F,
+ 0x803FFFC00000007F, 0x3FF01FFFFFF0004, 0xFFDFFFFFFFFFFFFF,
+ 0x4FFFFFFFFF00F0, 0x17FFDE1F, 0x40FFFFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F,
+ 0x3FF07FFFFFFFFFF, 0xFBEDFDFFFFF99FEF, 0x1F1FCFE081399F, 0x3C3FF07FF,
+ 0x3FF00BF, 0xFF3FFFFFFFFFFFFF, 0x3F000001, 0x3FF0011, 0x1FFFFFFFFFFFFFF,
+ 0x3FF, 0x3FF0FFFE7FFFFFF, 0x7F, 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF,
+ 0xF9BFFFFFFF6FF27F, 0x3FF000F, 0xFFFFFCFF00000000, 0x1BFCFFFFFF,
+ 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080, 0xFFFF000023FFFFFF,
0xFF7FFFFFFFFFFDFF, 0xFFFC000003FF0001, 0x7FFEFFFFFCFFFF,
0xB47FFFFFFFFFFB7F, 0xFFFFFDBF03FF00FF, 0x3FF01FB7FFF, 0x7FFFFF00000000,
- 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0x7F, 0x3FF7FFFFFFF, 0x1F3FFFFFFF0000,
- 0xE0FFFFF803FF000F, 0xFFFF, 0x7FFFFFFFFFFF001F, 0xFFFF8000, 0x300000000,
- 0x3FFFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF,
- 0x1FFF07FFFFFFFFFF, 0x63FF01FF, 0xF807E3E000000000, 0x3C0000000FE7, 0x1C,
- 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
- 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF,
- 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF,
- 0xFFFFFDFFFFFFFDFF, 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF,
- 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F, 0x7F001F, 0x3FF07FF,
- 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x7FFFFF,
- 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0xFFFFFFFFFFFF,
+ 0x1000000000000, 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0xFFFFFFFFFFFF0000,
+ 0x1FFFFFFFFFFFF, 0xFFFF03FF7FFFFFFF, 0x1F3FFFFFFF03FF, 0xE0FFFFF803FF000F,
+ 0xFFFF, 0xFFFFFFFFFFFF87FF, 0xFFFF80FF, 0x3001B00000000, 0xFFFFFFFFFFFFFF,
+ 0x3FFFFF, 0x6FEF000000000000, 0x7FFFFFFFF, 0xFFFF00F000070000,
+ 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x63FF01FF, 0xFFFF3FFFFFFFFFFF,
+ 0xF807E3E000000000, 0x3C0000000FE7, 0x1C, 0xFFFFFFFFFFDFFFFF,
+ 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF,
+ 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD,
+ 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF,
+ 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF, 0xFFFEF8000010,
+ 0x7DBF9FFFF7F, 0x3FFF1FFFFFFFFFFF, 0x43FF, 0x7FFFFFFF0000,
+ 0x3FFFFFFFFFFFFFF, 0x7FFF6F7F00000000, 0x7F001F, 0x3FF0FFF,
+ 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF,
+ 0x3FF000000000000, 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF,
+ 0x3FFFFFFF, 0x7FF, 0xFFFFFFFFFFFF,
],
};
@@ -2322,100 +2982,103 @@ pub const ID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 3, 61,
- 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34, 34, 34, 69, 70, 71, 72,
- 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 78, 79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87,
- 88, 34, 89, 90, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 53, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94, 95, 96,
- 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109,
- 110, 111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 114, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 116, 34, 117, 118,
- 119, 120, 121, 34, 34, 34, 34, 122, 123, 124, 125, 3, 126, 34, 127, 128,
- 129, 130, 131,
+ 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 35,
+ 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 35, 35, 35, 35, 35, 35, 35, 35,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 3, 58, 59, 60, 30,
+ 61, 62, 63, 64, 65, 66, 67, 68, 35, 35, 35, 30, 35, 35, 35, 35, 69, 70,
+ 71, 72, 30, 73, 74, 30, 75, 76, 77, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 78,
+ 79, 80, 81, 82, 30, 30, 30, 30, 30, 30, 30, 30, 83, 43, 84, 85, 86, 35,
+ 87, 88, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 30, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 89, 90, 35, 35, 35, 35, 91, 92,
+ 93, 94, 95, 35, 96, 97, 98, 49, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 35, 111, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 112, 113, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 114, 35, 115, 116,
+ 117, 118, 119, 35, 35, 35, 35, 120, 121, 122, 123, 30, 124, 35, 125, 126,
+ 127, 128, 129,
],
tree2_level2: &[
- 0x110043FFFFF, 0x7FF01FFFFFF, 0x3FDFFFFF00000000, 0, 0x23FFFFFFFFFFFFF0,
- 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1, 0x10030003B0004000,
- 0x36DFDFFFFF987E0, 0x1C00005E000000, 0x23EDFDFFFFFBBFE0,
- 0x200000300010000, 0x23EDFDFFFFF99FE0, 0x20003B0000000, 0x3FFC718D63DC7E8,
- 0x10000, 0x23FFFDFFFFFDDFE0, 0x307000000, 0x23EFFDFFFFFDDFE1,
- 0x6000340000000, 0x27FFFFFFFFFDDFE0, 0xFC00000380704000,
- 0x2FFBFFFFFC7FFFE0, 0x7F, 0xDFFFFFFFFFFFE, 0x200DECAEFEF02596, 0xF000005F,
- 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000,
- 0xFFFFFFFF00004003, 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF,
- 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
- 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF, 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF,
- 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE,
- 0x1FFC7FFFFFFFFFF, 0x3FFFF0003DFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF,
- 0x10800000, 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFFFF,
- 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF, 0x3FF,
- 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0xFE0,
+ 0x110043FFFFF, 0xFFFF07FF01FFFFFF, 0xFFFFFFFF00007EFF, 0x3FF,
+ 0x23FFFFFFFFFFFFF0, 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1,
+ 0x10030003B0004000, 0x36DFDFFFFF987E0, 0x1C00005E000000,
+ 0x23EDFDFFFFFBBFE0, 0x200000300010000, 0x23EDFDFFFFF99FE0,
+ 0x20003B0000000, 0x3FFC718D63DC7E8, 0x10000, 0x23FFFDFFFFFDDFE0,
+ 0x327000000, 0x23EFFDFFFFFDDFE1, 0x6000360000000, 0x27FFFFFFFFFDDFF0,
+ 0xFC00000380704000, 0x2FFBFFFFFC7FFFE0, 0x7F, 0xDFFFFFFFFFFFE,
+ 0x200DFFAFFFFFF7D6, 0xF000005F, 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0,
+ 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000, 0xFFFFFFFF00004003,
+ 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF,
+ 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF,
+ 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE,
+ 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF,
+ 0x3FFFF8003FFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF, 0x10800000,
+ 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFFFF,
+ 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF,
+ 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0x1FE0,
0xFC00C001FFFFFFF8, 0x3FFFFFFFFF, 0xFFFFFFFFF, 0x3FFFFFFFFC00E000,
- 0xE7FFFFFFFFFF01FF, 0x63DE0000000000, 0xFFFFFFFF3F3FFFFF,
+ 0xE7FFFFFFFFFF01FF, 0x46FDE0000000000, 0xFFFFFFFF3F3FFFFF,
0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC,
0x8002000000000000, 0x1FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0,
- 0x1FF, 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0xC781FFFFFFFFF,
- 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF, 0x7F7F7F7F007FFFFF, 0x7F7F7F7F,
- 0x1F3E03FE000000E0, 0xFFFFFFFEF87FFFFF, 0xF7FFFFFFFFFFFFFF,
- 0xFFFEFFFFFFFFFFE0, 0x7FFFFFF00007FFF, 0xFFFF000000000000, 0xFFFFFFFFFFFF,
- 0x1FFF, 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF, 0x80007FFFFFFFFFFF,
- 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFCFF800000, 0x3FFFFFFFFFFF9FF,
- 0xFF80000000000000, 0x7FFFFF7BB, 0xFFFFFFFFFFFFC, 0x68FC000000000000,
- 0xFFFF003FFFFFFC00, 0x1FFFFFFF0000007F, 0x7FFFFFFFFFFF0,
- 0x7C00FFDF00008000, 0x1FFFFFFFFFF, 0xC47FFFFF00000FF7, 0x3E62FFFFFFFFFFFF,
- 0x1C07FF38000005, 0xFFFF7F7F007E7E7E, 0xFFFF003FF7FFFFFF, 0x7FFFFFFFF,
- 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF,
- 0x5F7FFDFFA0F8007F, 0xFFFFFFFFFFFFFFDB, 0x3FFFFFFFFFFFF,
- 0xFFFFFFFFFFF80000, 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000,
- 0xFFFFFFFFFFFCFFFF, 0xFFF0000000000FF, 0xFFDF000000000000,
- 0x1FFFFFFFFFFFFFFF, 0x7FFFFFE00000000, 0xFFFFFFC007FFFFFE,
- 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
+ 0x1FF, 0xC781FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF,
+ 0x7F7F7F7F007FFFFF, 0x7F7F7F7F, 0x1F3E03FE000000E0, 0xFFFFFFFEF87FFFFF,
+ 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFF00007FFF,
+ 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF,
+ 0x80007FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFFFFFF,
+ 0xFFFFFFFCFF800000, 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x7FFFFF7BB,
+ 0xFFFFFFFFFFFFC, 0x68FC000000000000, 0xFFFF003FFFFFFC00,
+ 0x1FFFFFFF0000007F, 0x7FFFFFFFFFFF0, 0x7C00FFDF00008000, 0x1FFFFFFFFFF,
+ 0xC47FFFFF00000FF7, 0x3E62FFFFFFFFFFFF, 0x1C07FF38000005,
+ 0xFFFF7F7F007E7E7E, 0xFFFF03FFF7FFFFFF, 0x7FFFFFFFF, 0xFFFF000FFFFFFFFF,
+ 0xFFFFFFFFFFFF87F, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFDFFA0F8007F,
+ 0xFFFFFFFFFFFFFFDB, 0x3FFFFFFFFFFFF, 0xFFFFFFFFFFF80000,
+ 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF,
+ 0xFFF0000000000FF, 0xFFDF000000000000, 0x1FFFFFFFFFFFFFFF,
+ 0x7FFFFFE00000000, 0xFFFFFFC007FFFFFE, 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 12, 13, 14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 5, 11, 12, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 13, 14, 15, 7, 16, 17, 7, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -2427,78 +3090,90 @@ pub const ID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
- 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4,
- 4, 2, 2, 2, 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27,
- 28, 29, 30, 4, 2, 31, 32, 32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 4, 35,
- 4, 36, 37, 38, 39, 40, 41, 42, 4, 43, 20, 44, 45, 4, 4, 5, 46, 47, 48, 4,
- 4, 49, 50, 47, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, 4, 4, 4, 57, 58,
- 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 49, 2, 2, 2, 69, 4, 4,
+ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15,
+ 16, 4, 2, 2, 2, 2, 17, 18, 19, 4, 20, 21, 22, 23, 24, 4, 25, 4, 26, 27,
+ 28, 29, 30, 31, 32, 4, 2, 33, 34, 34, 35, 4, 4, 4, 4, 4, 36, 4, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4, 50, 22, 51, 52, 4, 4, 5,
+ 53, 54, 55, 4, 4, 56, 57, 54, 58, 59, 4, 60, 61, 4, 4, 62, 4, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 4, 4, 4, 4, 73, 74, 75, 4, 76, 77, 78, 4, 4,
+ 4, 4, 79, 4, 4, 80, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 81, 4, 2,
+ 56, 2, 2, 2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 83, 84, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 49, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 60, 20, 4, 71, 47, 72, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 2, 73,
- 74, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 72, 85, 86, 87, 54, 88, 75, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 2, 4, 4, 2, 89, 90, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 77, 2, 2, 2, 2, 2, 78, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 93, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 79, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 81, 82, 83, 84, 85, 2, 2,
- 2, 2, 86, 87, 88, 89, 90, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
- 2, 2, 92, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 93,
- 94, 95, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 94, 2, 2, 2, 2, 95, 96, 2, 2, 2, 2, 2, 97, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 2, 98, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 100, 101, 102, 103, 104, 2, 2,
+ 2, 2, 105, 106, 107, 108, 109, 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 111,
+ 112, 4, 4, 4, 4, 87, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 113, 2, 2, 2, 114, 2, 115, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 116, 117, 118, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 119, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 5, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 120, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 121, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 122, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
0x1FFFFFFFFFFFFF, 0xFFFFFFFF1FFFFFFF, 0x1FFFF, 0xFFFFE000FFFFFFFF,
0x3FFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F, 0xFFFF00003FFFFFFF,
- 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xFFFFFFFFF, 0x7FFFFFFFFFFFFF,
- 0xFF003FFFFF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF,
- 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
+ 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xF7FF000FFFFFFFFF,
+ 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x7FDFFFFFFFFFFBF,
+ 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000,
+ 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
0x1FFFFFFF00000000, 0x1FFFFFFF, 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF,
- 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFF00801FFFFFFF,
- 0x3F, 0xFFFFFFFFFFFFF8, 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8,
- 0x47FFFFFFFF0010, 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF,
- 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x780,
- 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF, 0xF000000, 0x10, 0x7FFFFFFFFFF,
- 0x7FFFFFF, 0xFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF,
- 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000, 0x200003CF, 0x1FFFFFFFFFFFFFF,
- 0x7FFFFFFFFDFF, 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F,
- 0xFFFFFDBF00000040, 0x10003FF, 0x7FFFF00000000, 0x3FFFFFF, 0xF, 0x7F,
- 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x1001F, 0xFFF80000, 0x300000000,
- 0x3FFFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF,
- 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF,
- 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F,
- 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF,
- 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x1F, 0xAF7FE96FFFFFFEF,
- 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x7FFFFF, 0xFFFF0003FFFFFFFF,
- 0x1FFFFFFFF, 0x3FFFFFFF,
+ 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFFF,
+ 0x303FFFFFFFFFF, 0xFFFF00801FFFFFFF, 0xFFFF00000000003F,
+ 0xFFFF000000000003, 0x7FFFFF0000001F, 0xFFFFFFFFFFFFF8, 0x26000000000000,
+ 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8, 0x47FFFFFFFF0090,
+ 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F,
+ 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x380000780, 0xFFFFFFFFFFFF, 0xB0,
+ 0x7FFFFFFFFFFF, 0xF000000, 0x10, 0x10007FFFFFFFFFF, 0x7FFFFFF, 0x7F,
+ 0xFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF, 0x8000FFFFFF6FF27F,
+ 0x2, 0xFFFFFCFF00000000, 0xA0001FFFF, 0x407FFFFFFFFF801,
+ 0xFFFFFFFFF0010000, 0xFFFF0000200003FF, 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF,
+ 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040,
+ 0x10003FF, 0x7FFFF00000000, 0x1000000000000, 0x3FFFFFF, 0xF,
+ 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF, 0xFFFF00007FFFFFFF,
+ 0x7FFFFFFFFFFFFFFF, 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x107FF,
+ 0xFFF80000, 0xB00000000, 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x6FEF000000000000,
+ 0x7FFFFFFFF, 0xFFFF00F000070000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF,
+ 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
+ 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF,
+ 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF,
+ 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x3F801FFFFFFFFFFF, 0x4000, 0x7FFF6F7F00000000,
+ 0x1F, 0x80F, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF,
+ 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0x7FF,
],
};
@@ -2519,7 +3194,7 @@ pub const IDEOGRAPHIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2532,7 +3207,7 @@ pub const IDEOGRAPHIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2546,16 +3221,15 @@ pub const IDEOGRAPHIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 5, 2, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 2, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level2: &[
- 0, 0x70003FE000000C0, 0xFFFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFF,
- 0xFFFFFFFFFFFF, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF,
+ 0, 0x70003FE000000C0, 0xFFFFFFFFFFFFFFFF, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF,
],
tree3_level1: &[
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 4, 5, 6, 1, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 4, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 5, 6, 7, 2, 8, 9, 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2564,38 +3238,43 @@ pub const IDEOGRAPHIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
],
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 1,
- 1, 1, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1,
- 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 2, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFF, 0x7FFFFFFFFFFFF,
- 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF, 0x7FFFFF, 0x1FFFFFFFFFFFFF,
- 0xFFFFFFFF3FFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF,
+ 0, 0x1000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x1FF,
+ 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF, 0xFFFFFFFF, 0x1FFFFFFFFFFFFFF,
+ 0xFFFFFFFF3FFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0x7FF,
],
};
@@ -2773,10 +3452,10 @@ pub const LOWERCASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xAAAAAAAAAAAAAAAA, 0xAAAAAAAABFEAAAAA, 0xFF00FF003F00FF,
0x3FFF00FF00FF003F, 0x40DF00FF00FF00FF, 0xDC00FF00CF00DC,
0x8002000000000000, 0x1FFF0000, 0x321080000008C400, 0xFFFF0000000043C0,
- 0x10, 0x3FFFFFF0000, 0xFFFF000000000000, 0x3FDA15627FFFFFFF,
+ 0x10, 0x3FFFFFF0000, 0xFFFF000000000000, 0x3FDA1562FFFFFFFF,
0x8501AAAAAAAAA, 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA, 0x3AAAAAAA,
- 0xAAABAAA800000000, 0x95FFAAAAAAAAAAAA, 0x2A082AAAABA50AA,
- 0x700000000000000, 0xFFFF003FF7FFFFFF, 0xF8007F, 0x7FFFFFE,
+ 0xAAABAAA800000000, 0x95FFAAAAAAAAAAAA, 0xAAA082AAAABA50AA,
+ 0x740000002AA050A, 0xFFFF01FFF7FFFFFF, 0xF8007F, 0x7FFFFFE,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2792,30 +3471,31 @@ pub const LOWERCASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFC000000, 0xFFFFDFC000,
- 0xEBC000000FFFFFFC, 0xFFFFFC000000FFEF, 0xFFFFFFC000000F, 0xFFFFFFC0000,
- 0xFC000000FFFFFFC0, 0xFFFFC000000FFFFF, 0xFFFFFFC000000FF, 0xFFFFFFC00000,
- 0x3FFFFFFC00, 0xF0000003F7FFFFFC, 0xFFC000000FDFFFFF, 0xFFFF0000003F7FFF,
- 0xFFFFFC000000FDFF, 0xBF7, 0xFFFFFFFC00000000, 0xF,
+ 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x1BFBFFFBFF800000,
+ 0x7FDFFFFFFFFFFB9, 0x7FFFFFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF00000000,
+ 0xFFFFFFC000000, 0xFFFFDFC000, 0xEBC000000FFFFFFC, 0xFFFFFC000000FFEF,
+ 0xFFFFFFC000000F, 0xFFFFFFC0000, 0xFC000000FFFFFFC0, 0xFFFFC000000FFFFF,
+ 0xFFFFFFC000000FF, 0xFFFFFFC00000, 0x3FFFFFFC00, 0xF0000003F7FFFFFC,
+ 0xFFC000000FDFFFFF, 0xFFFF0000003F7FFF, 0xFFFFFC000000FDFF, 0xBF7,
+ 0x7FFFFBFF, 0xFFFFFFFC00000000, 0xF,
],
};
@@ -2991,10 +3671,10 @@ pub const OTHER_ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
tree2_level1: &[
0, 1, 1, 2, 3, 4, 5, 6, 5, 7, 5, 8, 5, 9, 10, 11, 12, 13, 5, 13, 12, 14,
15, 16, 17, 18, 19, 18, 1, 20, 21, 1, 22, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26, 26, 27, 28, 1, 1,
- 29, 1, 30, 1, 1, 1, 31, 32, 1, 1, 33, 34, 35, 36, 37, 1, 1, 38, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 25, 26, 27, 1, 1,
+ 28, 1, 29, 1, 1, 1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 1, 1, 1, 1, 1, 1,
39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 27, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 26, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -3015,8 +3695,8 @@ pub const OTHER_ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 42, 43, 1, 1, 1, 1, 1, 44, 1, 45, 46, 47, 48, 49, 1, 50, 51, 52, 53, 1, 1,
- 1, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 42, 43, 1, 1, 1, 1, 1, 44, 1, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 1,
+ 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -3028,23 +3708,24 @@ pub const OTHER_ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
],
tree2_level2: &[
0x1EEFF8C00000, 0, 0xFFFF03F8FFF00000, 0xCC0000000000000F, 0xC00E0DFFF,
0xC00000000000000E, 0xC0080199F, 0x23000000021987, 0x1C00000C00001BBF,
0xC00C0199F, 0xC000000000000004, 0x801DC7, 0xC00000000000000F,
- 0xC00601DDF, 0xC00801DDF, 0xC, 0xC0000FF5F8000, 0x7F2000000000000, 0x2000,
+ 0xC00601DDF, 0xC00801DDF, 0xE, 0xC0000FF5F8000, 0x7F2000000000000, 0x2000,
0x1BF2000000000000, 0xFFFE000000000000, 0x1FFFFFFFFEFFE003,
- 0x797FF80000000000, 0x1E0185C3C00000, 0x3000007C, 0x80000000,
- 0xC0000000C0000, 0xFFC0000000000000, 0x1FF, 0x20000000060,
- 0x1FF0FFF00000000, 0xF800000, 0x1FFFFE7FE00000, 0xFFE000000000001F, 0xF,
- 0x33FE00000007, 0x3FF8000000000, 0x3FFFF000000000, 0xC000000000000,
- 0x1FFF8000000000, 0x3FFFFFFFFFF, 0xFFFFFFFF00000000, 0xFF0000000000000,
- 0xC0000000, 0xF800000000, 0xFFF0000000000003, 0x2F, 0x7C000000000,
- 0x7FF80, 0xFFF000000000000F, 0x7FFE0000000000, 0x3008, 0x419D000000000000,
- 0x20F80000000000, 0x7F800000000, 0x40000000,
+ 0x797FF80000000000, 0x1E3F9DC3C00000, 0x3C00BFFC, 0xC0000000C0000,
+ 0xFFC0000000000000, 0x1FF, 0x20000000060, 0x1FF0FFF00000000, 0xF800000,
+ 0x1FFFFE7FE00000, 0x8000000000000000, 0x7001, 0xFFE000000000001F, 0xF,
+ 0x33FE00000007, 0x3FF8000000000, 0x7FFFF000000000, 0x1FFF8000000000,
+ 0x3FFFFFFFFFF, 0xFFFFFFFF00000000, 0xFF0000000000000, 0xC0000000,
+ 0xF800000804, 0xFFF0000000000003, 0x800000000000002F, 0x7C000000000,
+ 0x7FF80, 0xFFF000000000000F, 0x2000000000, 0x7FFE0000000000,
+ 0x3800000000003008, 0x419D000000000000, 0x20F80000000000, 0x7F800000000,
+ 0x40000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -3062,34 +3743,36 @@ pub const OTHER_ALPHABETIC: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 7, 8, 9, 0, 10, 0,
- 0, 11, 12, 13, 0, 0, 14, 15, 16, 17, 0, 0, 18, 19, 20, 21, 22, 0, 23, 0,
- 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 28, 0, 29, 0,
- 30, 31, 32, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 0, 0, 14, 15, 16, 0, 0, 17, 18, 19, 20, 0, 0, 21, 22, 23, 24, 25, 0, 26,
+ 0, 0, 0, 27, 0, 0, 0, 28, 29, 0, 30, 31, 32, 33, 0, 0, 0, 0, 0, 34, 0, 35,
+ 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 16, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 19, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x7C0000000000000, 0xF06E, 0xF000000000, 0xFF00000000000007, 0x3F,
- 0x1FF000000000004, 0x7FF8000000007, 0x60, 0xFFF8000000000007,
- 0x409FF00000000000, 0x1FF80000000, 0xC00000000000000F, 0xC0080199F,
- 0xFFE0000000000000, 0x3B, 0xFFFF000000000000, 0x3, 0x7F3F800000000000,
- 0x30000000, 0x7FFF000000000000, 0x1, 0x3FF80000000000, 0x7FFE0000000,
- 0x1FFF00000000000, 0x7BE00000000007FE, 0xFFE0000, 0xFFFC00,
- 0x7F7F800000000000, 0x7FFEFFFFFC0000, 0xB47E000000000000, 0x8B, 0x7B7C00,
- 0x78000000000000, 0x7F000000000000, 0x7FFFFFFFFFFE0000, 0x40000000,
- 0x7DBF9FFFF7F, 0x80, 0xFFFF03FFFFFF03FF, 0x3FF,
+ 0, 0x7C0000000000000, 0xF06E, 0xF000000000, 0x180000000000,
+ 0xFF00000000000007, 0x1800000000003F, 0x1FF000000000004, 0x4,
+ 0x7FF8000000007, 0x60, 0xFFF8000000000007, 0xC000, 0x409FF00000000000,
+ 0x1FF80000000, 0xC00000000000000F, 0xC0080199F, 0xFFE0000000000000, 0x3B,
+ 0xFFFF000000000000, 0x3, 0x7F3F800000000000, 0x30000000,
+ 0x7FFF000000000000, 0x1, 0x3FF80000000000, 0x7FFE0000000,
+ 0x1FFF00000000000, 0x19BF000000000000, 0x5, 0x10FCFE0000,
+ 0x7BE00000000007FE, 0xFFE0000, 0xFFFC00, 0x7F7F800000000000,
+ 0x7FFEFFFFFC0000, 0xB47E000000000000, 0x8B, 0x7B7C00, 0x78000000000000,
+ 0xFFFFFFFFFFFE8000, 0x780FF, 0x3000000000000, 0x40000000, 0x7DBF9FFFF7F,
+ 0x80, 0xFFFF03FFFFFF03FF, 0x3FF,
],
};
@@ -3179,10 +3862,10 @@ pub const OTHER_GRAPHEME_EXTEND: &'static ::ucd_trie::TrieSet = &::ucd_trie::Tri
0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 0, 3, 1, 2, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3215,11 +3898,11 @@ pub const OTHER_GRAPHEME_EXTEND: &'static ::ucd_trie::TrieSet = &::ucd_trie::Tri
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,
],
tree2_level2: &[
- 0, 0x4000000000000000, 0x800000, 0x600004, 0x80008000, 0x1000,
- 0xC00000000000, 0xC0000000,
+ 0, 0x4000000000000000, 0x800000, 0x600004, 0x80008000, 0x20000000000000,
+ 0x1000, 0xC00000000000, 0xC0000000,
],
tree3_level1: &[
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3239,17 +3922,17 @@ pub const OTHER_GRAPHEME_EXTEND: &'static ::ucd_trie::TrieSet = &::ucd_trie::Tri
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0x4000000000000000, 0x800000, 0x2001000000000000, 0x800000000000,
- 0x7C02000000000, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF,
+ 0x1000000000000, 0x7C02000000000, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF,
],
};
@@ -3424,10 +4107,28 @@ pub const OTHER_LOWERCASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xF0000000,
],
tree3_level1: &[
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,
],
tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
],
tree3_level3: &[
+ 0, 0x7FDFFFFFFFFFFB9,
],
};
@@ -3718,7 +4419,7 @@ pub const PREPENDED_CONCATENATION_MARK: &'static ::ucd_trie::TrieSet = &::ucd_tr
0x3F, 0, 0, 0x20000000, 0x8000, 0, 0, 0,
],
tree2_level1: &[
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3760,7 +4461,7 @@ pub const PREPENDED_CONCATENATION_MARK: &'static ::ucd_trie::TrieSet = &::ucd_tr
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level2: &[
- 0, 0x400000000,
+ 0, 0x30000, 0x400000000,
],
tree3_level1: &[
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3942,7 +4643,7 @@ pub const REGIONAL_INDICATOR: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSe
pub const SENTENCE_TERMINAL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
0x8000400200000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0x200, 0, 0xC0000000, 0, 0, 0x100000, 0x7, 0, 0,
+ 0, 0, 0, 0x200, 0, 0xE0000000, 0, 0, 0x100000, 0x7, 0, 0,
0x200000000000000,
],
tree2_level1: &[
@@ -3952,7 +4653,7 @@ pub const SENTENCE_TERMINAL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 10, 1, 1, 11, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 15, 16, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -3971,8 +4672,8 @@ pub const SENTENCE_TERMINAL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 18, 1, 1, 19, 1, 1, 1, 1, 1, 20, 1, 18, 21,
- 1, 1, 22, 1, 23, 1, 24, 1, 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 18, 1, 1, 1, 1, 19, 1, 1, 20, 1, 1, 1, 1, 1, 21, 1, 19, 22,
+ 1, 1, 23, 1, 24, 1, 25, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -3985,15 +4686,15 @@ pub const SENTENCE_TERMINAL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26, 1, 1, 27, 28, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 1, 1, 28, 29, 1, 1,
],
tree2_level2: &[
0x6280000000000000, 0, 0x3000000000, 0xC00, 0x18400000000, 0x400000000000,
- 0x60000000000000, 0x208, 0x30, 0xF0000000000, 0xCC000000,
+ 0x60000000000000, 0x208, 0x30, 0xF0000000000, 0x60000000CC000000,
0x1800000000000000, 0xC000000000000000, 0x3000000000000000, 0x380,
- 0x1000400000000000, 0x4, 0x8000000000000000, 0xC000, 0x88000000000000,
- 0xC0000000000000, 0x800000000000, 0x300, 0xE0000000, 0x3000000000000,
- 0x80000000000, 0xC40000, 0x80004002, 0x200000000,
+ 0x1000400000000000, 0x180000, 0x4, 0x8000000000000000, 0xC000,
+ 0x88000000000000, 0xC0000000000000, 0x800000000000, 0x300, 0xE0000000,
+ 0x3000000000000, 0x80000000000, 0xC40000, 0x80004002, 0x200000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -4011,26 +4712,26 @@ pub const SENTENCE_TERMINAL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 4, 5, 0, 6, 0, 7, 8, 0, 9,
- 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 11, 0, 12, 0, 0, 13, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 14, 15, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 4, 5, 6, 0, 7, 0, 8, 9, 0,
+ 10, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 12, 0, 13, 0, 0, 14, 0, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 16, 17, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 18, 16, 19, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 20, 18, 21, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xC00000, 0x3E00000, 0x180, 0xC000000000000000, 0x3, 0xE, 0xC0002060,
- 0x1B00000000000000, 0x20000000000, 0x1800, 0xFFFE0C, 0x6,
- 0x7000000000000000, 0xC, 0x18000000, 0x180000000000000, 0xC00000000000,
- 0x20000000000000, 0x10, 0x1000000, 0x80000000, 0x100,
+ 0, 0xC00000, 0x3E00000, 0x3C0, 0x180, 0xC000000000000000, 0x3, 0xE,
+ 0xC0002060, 0x1B00000000000000, 0x20000000000, 0x1800, 0xFFFE0C, 0x6,
+ 0x7000000000000000, 0x50, 0xC, 0x18000000, 0x180000000000000,
+ 0xC00000000000, 0x20000000000000, 0x10, 0x1000000, 0x80000000, 0x100,
],
};
@@ -4105,19 +4806,19 @@ pub const SOFT_DOTTED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
+ 12, 0, 0, 0,
],
tree3_level3: &[
0, 0xC00000000, 0xC00000, 0xC000000000000C00, 0xC000000000000,
0xC000000000, 0xC000000, 0xC000, 0xC000000000000C, 0xC0000000000,
- 0xC0000000, 0xC0000,
+ 0xC0000000, 0xC0000, 0x4000000,
],
};
pub const TERMINAL_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
0x8C00500200000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0x4000000000000000, 0x80, 0, 0, 0, 0, 0, 0, 0, 0x200, 0x8, 0xC8001000, 0,
+ 0x4000000000000000, 0x80, 0, 0, 0, 0, 0, 0, 0, 0x200, 0x8, 0xE8001000, 0,
0, 0x100000, 0x17FF, 0, 0, 0x300000000000000,
],
tree2_level1: &[
@@ -4165,12 +4866,12 @@ pub const TERMINAL_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::Trie
],
tree2_level2: &[
0x7FFF000000000000, 0x40000000, 0, 0x3000000000, 0xC000000, 0x7E100,
- 0xC00, 0x1FE00000000, 0x600000000000, 0x380000000000, 0x60000000000000,
- 0x4700000, 0x33C, 0x30, 0xF0000000000, 0xEC000000, 0xF800000000000000,
- 0xC000000000000000, 0x3000000000000000, 0x380, 0x1000400000000000, 0x5002,
- 0x6, 0xE000, 0xF8000000000000, 0xC0000000000000, 0xC000, 0x800000000000,
- 0xE0000000, 0x3000080000000, 0x80000000000, 0xF70000, 0x8C005002,
- 0x1200000000,
+ 0xC00, 0x1FE00000000, 0x400000000000, 0x380000000000, 0x60000000000000,
+ 0x4700000, 0x33C, 0x30, 0xF0000000000, 0x60000000EC000000,
+ 0xF800000000000000, 0xC000000000000000, 0x3000000000000000, 0x380,
+ 0x1000400000000000, 0x18D002, 0x6, 0xE000, 0xF8000000000000,
+ 0xC0000000000000, 0xC000, 0x800000000000, 0xE0000000, 0x3000080000000,
+ 0x80000000000, 0xF70000, 0x8C005002, 0x1200000000,
],
tree3_level1: &[
0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 5, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -4188,31 +4889,32 @@ pub const TERMINAL_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::Trie
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 4, 0, 5, 6, 0, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 9, 10, 11, 0, 12, 0, 13, 14,
- 0, 15, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 17, 0, 18, 0, 0, 19, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 10, 11, 12, 0, 13, 0, 14, 15,
+ 0, 16, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 18, 0, 19, 0, 0, 20, 0, 0, 0,
+ 0, 0, 0, 0, 0, 21, 0, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 25, 0, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0,
+ 0, 0, 0, 0, 0, 27, 0, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0x80000000, 0x10000, 0x800000, 0xC00000, 0x3F000000000000,
- 0xFC00000000000000, 0x1E000000, 0x3E00000, 0x3F80, 0xC000000000000000,
- 0x3, 0xE, 0xC0002060, 0x1F00000000000000, 0x20000000000, 0x8003800,
- 0xFFFE3C, 0x6, 0x7000000000000000, 0xC, 0x618000000, 0x200000000000E,
- 0x180000000000000, 0x1F000000000000, 0xC00000000000, 0x20000000000000,
- 0x380000000000000, 0x10, 0x1800000, 0x780,
+ 0xFC00000000000000, 0x1E000000, 0x3E00000, 0x3C0, 0x3F80,
+ 0xC000000000000000, 0x3, 0xE, 0xC0002060, 0x1F00000000000000,
+ 0x20000000000, 0xC003800, 0xFFFE3C, 0x6, 0x7000000000000000, 0x50, 0xC,
+ 0x618000000, 0x200000000000E, 0x180000000000000, 0x1F000000000000,
+ 0xC00000000000, 0x20000000000000, 0x380000000000000, 0x10, 0x1800000,
+ 0x780,
],
};
@@ -4233,7 +4935,7 @@ pub const UNIFIED_IDEOGRAPH: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -4246,7 +4948,7 @@ pub const UNIFIED_IDEOGRAPH: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -4260,15 +4962,15 @@ pub const UNIFIED_IDEOGRAPH: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level2: &[
- 0, 0xFFFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFF, 0xFFFFFFFFFFFF, 0x39A801AC000,
+ 0, 0xFFFFFFFFFFFFFFFF, 0x39A801AC000,
],
tree3_level1: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 3, 4, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 3, 4, 1, 5, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -4295,11 +4997,13 @@ pub const UNIFIED_IDEOGRAPH: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFFFFFFFFFFFF, 0x7FFFFF, 0x1FFFFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF,
- 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF,
+ 0, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF, 0x1FFFFFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF,
+ 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x7FF,
],
};
@@ -4337,7 +5041,7 @@ pub const UPPERCASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 24, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -4351,16 +5055,16 @@ pub const UPPERCASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0x20BF, 0x3FFFFFFFFFFFFF, 0xE7FFFFFFFFFF0000,
0x5555555555555555, 0x5555555540155555, 0xFF00FF003F00FF00,
0xFF00AA003F00, 0xF00000000000000, 0xF001F000F000F00, 0xC00F3D503E273884,
- 0xFFFF00000020, 0x8, 0xFFC0000000000000, 0xFFFF, 0x7FFFFFFFFFFF,
+ 0xFFFF00000020, 0x8, 0xFFC0000000000000, 0xFFFF, 0xFFFFFFFFFFFF,
0xC025EA9D00000000, 0x4280555555555, 0x155555555555, 0x5555555,
- 0x5554555400000000, 0x6A00555555555555, 0x15F7D5555452855,
- 0x7FFFFFE00000000,
+ 0x5554555400000000, 0x6A00555555555555, 0x555F7D5555452855,
+ 0x200000014102F5, 0x7FFFFFE00000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -4376,33 +5080,34 @@ pub const UPPERCASE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 4, 5, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 24, 25, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 26, 27, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xFFF0000003FFFFFF, 0xFFFFFF0000003FFF,
- 0x3FDE64D0000003, 0x3FFFFFF0000, 0x7B0000001FDFE7B0, 0xFFFFF0000001FC5F,
- 0x3FFFFFF0000003F, 0x3FFFFFF00000, 0xF0000003FFFFFF00, 0xFFFF0000003FFFFF,
- 0xFFFFFF00000003FF, 0x7FFFFFC00000001, 0x1FFFFFF0000000, 0x7FFFFFC00000,
- 0x1FFFFFF0000, 0x400, 0x3FFFFFFFF, 0xFFFF03FFFFFF03FF, 0x3FF,
+ 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0xF7FF000000000000,
+ 0x37F7FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF,
+ 0xFFF0000003FFFFFF, 0xFFFFFF0000003FFF, 0x3FDE64D0000003, 0x3FFFFFF0000,
+ 0x7B0000001FDFE7B0, 0xFFFFF0000001FC5F, 0x3FFFFFF0000003F, 0x3FFFFFF00000,
+ 0xF0000003FFFFFF00, 0xFFFF0000003FFFFF, 0xFFFFFF00000003FF,
+ 0x7FFFFFC00000001, 0x1FFFFFF0000000, 0x7FFFFFC00000, 0x1FFFFFF0000, 0x400,
+ 0x3FFFFFFFF, 0xFFFF03FFFFFF03FF, 0x3FF,
],
};
@@ -4454,7 +5159,7 @@ pub const VARIATION_SELECTOR: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSe
0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level2: &[
- 0, 0x3800, 0xFFFF,
+ 0, 0xB800, 0xFFFF,
],
tree3_level1: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -4559,16 +5264,16 @@ pub const XID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4,
35, 36, 37, 38, 39, 40, 41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46,
47, 4, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 4, 61, 4, 62,
- 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60,
- 60, 60, 60, 60, 60, 86, 42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60,
- 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 63, 64, 65, 66, 4, 4, 4, 4, 4, 4, 4, 4, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 4, 4, 4, 79, 80, 81, 82, 83, 78, 78, 78,
+ 78, 78, 78, 78, 78, 84, 42, 85, 86, 87, 4, 88, 89, 78, 78, 78, 78, 78, 78,
+ 78, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 52, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -4581,159 +5286,176 @@ pub const XID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62,
- 4, 102, 103, 104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 90, 91, 4, 4, 4, 4, 92, 93, 4, 94, 95, 4, 96, 97, 98, 62, 4,
+ 99, 100, 101, 4, 102, 103, 104, 4, 105, 106, 107, 4, 108, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114, 115, 116, 97, 117, 4, 118,
- 4, 4, 119, 120, 121, 122, 123, 124, 4, 125, 126, 127, 128, 129,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 109, 110, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 4, 4, 4, 4, 4, 100, 4, 111, 112, 113, 94, 114, 4, 115, 4,
+ 4, 116, 117, 118, 119, 120, 121, 4, 122, 123, 124, 125, 126,
],
tree2_level2: &[
- 0x3FFFFFFFFFFF, 0x7FF0FFFFFFF, 0x3FDFFFFF00000000, 0xFFFFFFFBFFF80000,
- 0xFFFFFFFFFFFFFFFF, 0xFFFEFFCFFFFFFFFF, 0xF3C5FDFFFFF99FEF,
- 0x5003FFCFB080799F, 0xD36DFDFFFFF987EE, 0x3FFFC05E023987,
- 0xF3EDFDFFFFFBBFEE, 0xFE00FFCF00013BBF, 0xF3EDFDFFFFF99FEE,
- 0x2FFCFB0C0399F, 0xC3FFC718D63DC7EC, 0xFFC000813DC7, 0xE3FFFDFFFFFDDFFF,
- 0xFFCF07603DDF, 0xF3EFFDFFFFFDDFEF, 0x6FFCF40603DDF, 0xFFFFFFFFFFFDDFEF,
- 0xFC00FFCF80F07DDF, 0x2FFBFFFFFC7FFFEC, 0xCFFC0FF5F847F,
- 0x7FFFFFFFFFFFFFE, 0x3FF7FFF, 0x3BFFECAEFEF02596, 0xF3FF3F5F,
- 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF, 0x40,
- 0xFFFFFFFFFFFF03FF, 0xFFFFFFFF3FFFFFFF, 0xF7FFFFFFFFFF20BF,
+ 0x3FFFFFFFFFFF, 0xFFFF07FF0FFFFFFF, 0xFFFFFFFFFF007EFF,
+ 0xFFFFFFFBFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFEFFCFFFFFFFFF,
+ 0xF3C5FDFFFFF99FEF, 0x5003FFCFB080799F, 0xD36DFDFFFFF987EE,
+ 0x3FFFC05E023987, 0xF3EDFDFFFFFBBFEE, 0xFE00FFCF00013BBF,
+ 0xF3EDFDFFFFF99FEE, 0x2FFCFB0E0399F, 0xC3FFC718D63DC7EC, 0xFFC000813DC7,
+ 0xF3FFFDFFFFFDDFFF, 0xFFCF27603DDF, 0xF3EFFDFFFFFDDFEF, 0x6FFCF60603DDF,
+ 0xFFFFFFFFFFFDDFFF, 0xFC00FFCF80F07DDF, 0x2FFBFFFFFC7FFFEE,
+ 0xCFFC0FF5F847F, 0x7FFFFFFFFFFFFFE, 0x3FF7FFF, 0x3FFFFFAFFFFFF7D6,
+ 0xF3FF3F5F, 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF,
+ 0x40, 0xFFFFFFFFFFFF03FF, 0xFFFFFFFF3FFFFFFF, 0xF7FFFFFFFFFF20BF,
0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
0xFFFFFFFFFF3DFFFF, 0x3FE00E7FFFFFF, 0xFFFFFFFF0000FFFF,
0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF,
- 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF, 0x1FFFFF001FDFFF, 0xDDFFF000FFFFF,
- 0x3FF308FFFFF, 0xFFFFFFFF03FF3800, 0x1FFFFFFFFFFFFFF, 0xFFFF07FFFFFFFFFF,
+ 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF, 0x1FFFFF803FFFFF, 0xDDFFF000FFFFF,
+ 0x3FF308FFFFF, 0xFFFFFFFF03FFB800, 0x1FFFFFFFFFFFFFF, 0xFFFF07FFFFFFFFFF,
0x3FFFFFFFFFFFFF, 0xFFF0FFF7FFFFFFF, 0x1F3FFFFFFFFFC0, 0xFFFF0FFFFFFFFFFF,
- 0x7FF03FF, 0xFFFFFFFF0FFFFFFF, 0x9FFFFFFF7FFFFFFF, 0x3FFF008003FF03FF, 0,
- 0xFF80003FF0FFF, 0xFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFE3FF,
- 0xE7FFFFFFFFFF01FF, 0x3FFFFFFFFF70000, 0xFBFFFFFFFFFFFFFF,
+ 0x7FF03FF, 0xFFFFFFFF0FFFFFFF, 0x9FFFFFFF7FFFFFFF, 0xBFFF008003FF03FF,
+ 0x7FFF, 0xFF80003FF1FFF, 0xFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF,
+ 0x3FFFFFFFFFFFE3FF, 0xE7FFFFFFFFFF01FF, 0x7FFFFFFFFF70000,
0xFFFFFFFF3F3FFFFF, 0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF,
0x1FDC1FFF0FCF1FDC, 0x8000000000000000, 0x8002000000100001, 0x1FFF0000,
- 0x1FFE21FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0, 0x1FF,
- 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0xFF81FFFFFFFFF,
- 0xFFFF20BFFFFFFFFF, 0x800080FFFFFFFFFF, 0x7F7F7F7F007FFFFF,
- 0xFFFFFFFF7F7F7F7F, 0x1F3EFFFE000000E0, 0xFFFFFFFEE67FFFFF,
- 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0x7FFFFFF00007FFF,
- 0xFFFF000000000000, 0xFFFFFFFFFFFF, 0x1FFF, 0x3FFFFFFFFFFF0000,
+ 0x1FFE21FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0, 0x1FF, 0,
+ 0xFF81FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x800080FFFFFFFFFF,
+ 0x7F7F7F7F007FFFFF, 0xFFFFFFFF7F7F7F7F, 0x1F3EFFFE000000E0,
+ 0xFFFFFFFEE67FFFFF, 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0,
+ 0xFFFFFFFF00007FFF, 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000,
0xFFFFFFF1FFF, 0xBFF0FFFFFFFFFFFF, 0x3FFFFFFFFFFFF, 0xFFFFFFFCFF800000,
- 0x3FFFFFFFFFFF9FF, 0xFF80000000000000, 0xFFFFFFFFFF, 0xE8FFFFFF03FF003F,
- 0xFFFF3FFFFFFFFFFF, 0x1FFFFFFF000FFFFF, 0x7FFFFFFF03FF8001,
- 0x7FFFFFFFFFFFFF, 0xFC7FFFFF03FF3FFF, 0x7CFFFF38000007,
- 0xFFFF7F7F007E7E7E, 0xFFFF003FF7FFFFFF, 0x3FF37FFFFFFFFFF,
- 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0x3FFFFFF, 0x5F7FFDFFE0F8007F,
- 0xFFFFFFFFFFFFFFDB, 0xFFFFFFFFFFF80000, 0xFFFFFFF03FFFFFFF,
- 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF,
- 0x3FF0000000000FF, 0x18FFFF0000FFFF, 0xAA8A00000000E000,
- 0x1FFFFFFFFFFFFFFF, 0x87FFFFFE03FF0000, 0xFFFFFFC007FFFFFE,
- 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
+ 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x10FFFFFFFFFF,
+ 0xE8FFFFFF03FF003F, 0xFFFF3FFFFFFFFFFF, 0x1FFFFFFF000FFFFF,
+ 0x7FFFFFFF03FF8001, 0x7FFFFFFFFFFFFF, 0xFC7FFFFF03FF3FFF,
+ 0x7CFFFF38000007, 0xFFFF7F7F007E7E7E, 0xFFFF03FFF7FFFFFF,
+ 0x3FF37FFFFFFFFFF, 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0x3FFFFFF,
+ 0x5F7FFDFFE0F8007F, 0xFFFFFFFFFFFFFFDB, 0xFFFFFFFFFFF80000,
+ 0xFFFFFFF03FFFFFFF, 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFFFFCFFFF, 0x3FF0000000000FF, 0x18FFFF0000FFFF,
+ 0xAA8A00000000E000, 0x1FFFFFFFFFFFFFFF, 0x87FFFFFE03FF0000,
+ 0xFFFFFFC007FFFFFE, 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 12, 13, 14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16,
- 4, 4, 2, 2, 2, 2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27,
- 28, 29, 30, 31, 4, 2, 32, 33, 33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 4,
- 2, 37, 3, 38, 39, 40, 2, 41, 42, 4, 43, 44, 45, 46, 4, 4, 2, 47, 2, 48, 4,
- 4, 49, 50, 2, 51, 52, 53, 54, 4, 4, 4, 3, 4, 55, 56, 4, 4, 4, 4, 57, 58,
- 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4,
+ 17, 4, 2, 2, 2, 2, 18, 19, 20, 4, 21, 22, 23, 24, 25, 4, 26, 4, 27, 28,
+ 29, 30, 31, 32, 33, 4, 2, 34, 35, 35, 36, 4, 4, 4, 4, 4, 37, 4, 38, 39,
+ 40, 41, 2, 42, 3, 43, 44, 45, 2, 46, 47, 4, 48, 49, 50, 51, 4, 4, 2, 52,
+ 2, 53, 4, 4, 54, 55, 2, 56, 57, 58, 59, 60, 4, 4, 3, 4, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 57, 4, 4, 4, 4, 70, 71, 72, 4, 73, 74, 75, 4, 4, 4, 4,
+ 76, 4, 4, 77, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 78, 4, 2, 79,
+ 2, 2, 2, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 81, 82, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 60, 72, 4, 73, 17, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 2, 76,
- 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+ 2, 2, 2, 2, 2, 2, 2, 57, 83, 67, 84, 18, 85, 86, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 2, 4, 4, 2, 87, 88, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 80, 2, 2, 2, 2, 2, 81, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 91, 34, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 84, 85, 4, 4, 86, 4, 4, 4, 4, 4, 4, 2, 87, 88, 89, 90, 91, 2,
- 2, 2, 2, 92, 93, 94, 95, 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 98, 99, 100, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 101, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 2, 2, 2, 102, 2, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 92, 2, 2, 2, 2, 93, 94, 2, 2, 2, 2, 2, 95, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 98, 60, 4, 4, 4, 4, 4, 4, 4, 99, 100, 4, 4, 101, 4, 4,
+ 4, 4, 4, 4, 2, 102, 103, 104, 105, 106, 2, 2, 2, 2, 107, 108, 109, 110,
+ 111, 112, 4, 4, 4, 4, 4, 4, 4, 4, 113, 114, 115, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 23, 4, 4, 4, 116, 4, 4, 4, 117, 118, 4, 4, 4,
+ 4, 119, 120, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 121,
+ 2, 2, 2, 122, 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 124, 125, 126, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 128, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 2, 2, 2, 11,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 130, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 110, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 111, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2,
+ 2, 131, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 132, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 133,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
0x1FFFFFFFFFFFFF, 0x2000000000000000, 0xFFFFFFFF1FFFFFFF, 0x10001FFFF,
0xFFFFE000FFFFFFFF, 0x7FFFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F,
- 0xFFFF03FF3FFFFFFF, 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xFFFFFFFFF,
- 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF,
- 0x7FFFFFFF, 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF,
+ 0xFFFF03FF3FFFFFFF, 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF,
+ 0xF7FF000FFFFFFFFF, 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF,
+ 0x7FDFFFFFFFFFFBF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF,
+ 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF,
0x873FFFFFFEEFF06F, 0x1FFFFFFF00000000, 0x1FFFFFFF, 0x7FFFFFFEFF,
0x3FFFFFFFFFFFFF, 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF,
- 0x3FF00FFFFFFFFFF, 0xFFFF00801FFFFFFF, 0x1FFFF, 0x8000FFC00000007F,
- 0x3FF01FFFFFF0000, 0xFFDFFFFFFFFFFFFF, 0x4FFFFFFFFF0070, 0x17FF1E1F,
- 0x40FFFFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F, 0x3FF07FFFFFFFFFF,
- 0xFBEDFDFFFFF99FEF, 0x1F1FCFE081399F, 0x43FF07FF, 0x3FF00BF,
- 0xFF3FFFFFFFFFFFFF, 0x3F000001, 0x3FF0011, 0xFFFFFFFFFFFFFF, 0x3FF,
- 0x3FF0FFFE7FFFFFF, 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF,
- 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080, 0x23FFFFCF, 0x1FFFFFFFFFFFFFF,
+ 0x3FF00FFFFFFFFFF, 0x31BFFFFFFFFFF, 0xFFFF00801FFFFFFF,
+ 0xFFFF00000001FFFF, 0xFFFF00000000003F, 0x7FFFFF0000001F,
+ 0x803FFFC00000007F, 0x3FF01FFFFFF0004, 0xFFDFFFFFFFFFFFFF,
+ 0x4FFFFFFFFF00F0, 0x17FFDE1F, 0x40FFFFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F,
+ 0x3FF07FFFFFFFFFF, 0xFBEDFDFFFFF99FEF, 0x1F1FCFE081399F, 0x3C3FF07FF,
+ 0x3FF00BF, 0xFF3FFFFFFFFFFFFF, 0x3F000001, 0x3FF0011, 0x1FFFFFFFFFFFFFF,
+ 0x3FF, 0x3FF0FFFE7FFFFFF, 0x7F, 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF,
+ 0xF9BFFFFFFF6FF27F, 0x3FF000F, 0xFFFFFCFF00000000, 0x1BFCFFFFFF,
+ 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080, 0xFFFF000023FFFFFF,
0xFF7FFFFFFFFFFDFF, 0xFFFC000003FF0001, 0x7FFEFFFFFCFFFF,
0xB47FFFFFFFFFFB7F, 0xFFFFFDBF03FF00FF, 0x3FF01FB7FFF, 0x7FFFFF00000000,
- 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0x7F, 0x3FF7FFFFFFF, 0x1F3FFFFFFF0000,
- 0xE0FFFFF803FF000F, 0xFFFF, 0x7FFFFFFFFFFF001F, 0xFFFF8000, 0x300000000,
- 0x3FFFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF,
- 0x1FFF07FFFFFFFFFF, 0x63FF01FF, 0xF807E3E000000000, 0x3C0000000FE7, 0x1C,
- 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
- 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF,
- 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF,
- 0xFFFFFDFFFFFFFDFF, 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF,
- 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F, 0x7F001F, 0x3FF07FF,
- 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x7FFFFF,
- 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0xFFFFFFFFFFFF,
+ 0x1000000000000, 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0xFFFFFFFFFFFF0000,
+ 0x1FFFFFFFFFFFF, 0xFFFF03FF7FFFFFFF, 0x1F3FFFFFFF03FF, 0xE0FFFFF803FF000F,
+ 0xFFFF, 0xFFFFFFFFFFFF87FF, 0xFFFF80FF, 0x3001B00000000, 0xFFFFFFFFFFFFFF,
+ 0x3FFFFF, 0x6FEF000000000000, 0x7FFFFFFFF, 0xFFFF00F000070000,
+ 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x63FF01FF, 0xFFFF3FFFFFFFFFFF,
+ 0xF807E3E000000000, 0x3C0000000FE7, 0x1C, 0xFFFFFFFFFFDFFFFF,
+ 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF,
+ 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD,
+ 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF,
+ 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF, 0xFFFEF8000010,
+ 0x7DBF9FFFF7F, 0x3FFF1FFFFFFFFFFF, 0x43FF, 0x7FFFFFFF0000,
+ 0x3FFFFFFFFFFFFFF, 0x7FFF6F7F00000000, 0x7F001F, 0x3FF0FFF,
+ 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF,
+ 0x3FF000000000000, 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF,
+ 0x3FFFFFFF, 0x7FF, 0xFFFFFFFFFFFF,
],
};
@@ -4752,100 +5474,104 @@ pub const XID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 3, 61,
- 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34, 34, 34, 69, 70, 71, 72,
- 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 78, 79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87,
- 88, 34, 89, 90, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 53, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94, 95, 96,
- 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109,
- 110, 111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 114, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 116, 34, 117, 118,
- 119, 120, 121, 34, 122, 34, 34, 123, 124, 125, 126, 3, 127, 34, 128, 129,
- 130, 131, 132,
+ 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 35,
+ 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 35, 35, 35, 35, 35, 35, 35, 35,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 3, 58, 59, 60, 30,
+ 61, 62, 63, 64, 65, 66, 67, 68, 35, 35, 35, 30, 35, 35, 35, 35, 69, 70,
+ 71, 72, 30, 73, 74, 30, 75, 76, 77, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 78,
+ 79, 80, 81, 82, 30, 30, 30, 30, 30, 30, 30, 30, 83, 43, 84, 85, 86, 35,
+ 87, 88, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 30, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 89, 90, 35, 35, 35, 35, 91, 92,
+ 93, 94, 95, 35, 96, 97, 98, 49, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 35, 111, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 112, 113, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 114, 35, 115, 116,
+ 117, 118, 119, 35, 120, 35, 35, 121, 122, 123, 124, 30, 125, 35, 126, 127,
+ 128, 129, 130,
],
tree2_level2: &[
- 0x110043FFFFF, 0x7FF01FFFFFF, 0x3FDFFFFF00000000, 0, 0x23FFFFFFFFFFFFF0,
- 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1, 0x10030003B0004000,
- 0x36DFDFFFFF987E0, 0x1C00005E000000, 0x23EDFDFFFFFBBFE0,
- 0x200000300010000, 0x23EDFDFFFFF99FE0, 0x20003B0000000, 0x3FFC718D63DC7E8,
- 0x10000, 0x23FFFDFFFFFDDFE0, 0x307000000, 0x23EFFDFFFFFDDFE1,
- 0x6000340000000, 0x27FFFFFFFFFDDFE0, 0xFC00000380704000,
- 0x2FFBFFFFFC7FFFE0, 0x7F, 0x5FFFFFFFFFFFE, 0x2005ECAEFEF02596, 0xF000005F,
- 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000,
- 0xFFFFFFFF00004003, 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF,
- 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
- 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF, 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF,
- 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE,
- 0x1FFC7FFFFFFFFFF, 0x3FFFF0003DFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF,
- 0x10800000, 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFFFF,
- 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF, 0x3FF,
- 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0xFE0,
+ 0x110043FFFFF, 0xFFFF07FF01FFFFFF, 0xFFFFFFFF00007EFF, 0x3FF,
+ 0x23FFFFFFFFFFFFF0, 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1,
+ 0x10030003B0004000, 0x36DFDFFFFF987E0, 0x1C00005E000000,
+ 0x23EDFDFFFFFBBFE0, 0x200000300010000, 0x23EDFDFFFFF99FE0,
+ 0x20003B0000000, 0x3FFC718D63DC7E8, 0x10000, 0x23FFFDFFFFFDDFE0,
+ 0x327000000, 0x23EFFDFFFFFDDFE1, 0x6000360000000, 0x27FFFFFFFFFDDFF0,
+ 0xFC00000380704000, 0x2FFBFFFFFC7FFFE0, 0x7F, 0x5FFFFFFFFFFFE,
+ 0x2005FFAFFFFFF7D6, 0xF000005F, 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0,
+ 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000, 0xFFFFFFFF00004003,
+ 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF,
+ 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF,
+ 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE,
+ 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF,
+ 0x3FFFF8003FFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF, 0x10800000,
+ 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFFFF,
+ 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF,
+ 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0x1FE0,
0xFC00C001FFFFFFF8, 0x3FFFFFFFFF, 0xFFFFFFFFF, 0x3FFFFFFFFC00E000,
- 0xE7FFFFFFFFFF01FF, 0x63DE0000000000, 0xFFFFFFFF3F3FFFFF,
+ 0xE7FFFFFFFFFF01FF, 0x46FDE0000000000, 0xFFFFFFFF3F3FFFFF,
0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC,
0x8002000000000000, 0x1FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0,
- 0x1FF, 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0xC781FFFFFFFFF,
- 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF, 0x7F7F7F7F007FFFFF, 0x7F7F7F7F,
- 0x1F3E03FE000000E0, 0xFFFFFFFEE07FFFFF, 0xF7FFFFFFFFFFFFFF,
- 0xFFFEFFFFFFFFFFE0, 0x7FFFFFF00007FFF, 0xFFFF000000000000, 0xFFFFFFFFFFFF,
- 0x1FFF, 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF, 0x80007FFFFFFFFFFF,
- 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFCFF800000, 0x3FFFFFFFFFFF9FF,
- 0xFF80000000000000, 0x7FFFFF7BB, 0xFFFFFFFFFFFFC, 0x68FC000000000000,
- 0xFFFF003FFFFFFC00, 0x1FFFFFFF0000007F, 0x7FFFFFFFFFFF0,
- 0x7C00FFDF00008000, 0x1FFFFFFFFFF, 0xC47FFFFF00000FF7, 0x3E62FFFFFFFFFFFF,
- 0x1C07FF38000005, 0xFFFF7F7F007E7E7E, 0xFFFF003FF7FFFFFF, 0x7FFFFFFFF,
- 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF,
- 0x5F7FFDFFA0F8007F, 0xFFFFFFFFFFFFFFDB, 0x3FFFFFFFFFFFF,
- 0xFFFFFFFFFFF80000, 0xFFFFFFF03FFFFFFF, 0x3FFFFFFFFFFFFFFF,
- 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF, 0x3FF0000000000FF,
- 0xAA8A000000000000, 0x1FFFFFFFFFFFFFFF, 0x7FFFFFE00000000,
- 0xFFFFFFC007FFFFFE, 0x7FFFFFFF3FFFFFFF, 0x1CFCFCFC,
+ 0x1FF, 0xC781FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF,
+ 0x7F7F7F7F007FFFFF, 0x7F7F7F7F, 0x1F3E03FE000000E0, 0xFFFFFFFEE07FFFFF,
+ 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFF00007FFF,
+ 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF,
+ 0x80007FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFFFFFF,
+ 0xFFFFFFFCFF800000, 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x7FFFFF7BB,
+ 0xFFFFFFFFFFFFC, 0x68FC000000000000, 0xFFFF003FFFFFFC00,
+ 0x1FFFFFFF0000007F, 0x7FFFFFFFFFFF0, 0x7C00FFDF00008000, 0x1FFFFFFFFFF,
+ 0xC47FFFFF00000FF7, 0x3E62FFFFFFFFFFFF, 0x1C07FF38000005,
+ 0xFFFF7F7F007E7E7E, 0xFFFF03FFF7FFFFFF, 0x7FFFFFFFF, 0xFFFF000FFFFFFFFF,
+ 0xFFFFFFFFFFFF87F, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFDFFA0F8007F,
+ 0xFFFFFFFFFFFFFFDB, 0x3FFFFFFFFFFFF, 0xFFFFFFFFFFF80000,
+ 0xFFFFFFF03FFFFFFF, 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFFFFCFFFF, 0x3FF0000000000FF, 0xAA8A000000000000,
+ 0x1FFFFFFFFFFFFFFF, 0x7FFFFFE00000000, 0xFFFFFFC007FFFFFE,
+ 0x7FFFFFFF3FFFFFFF, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 12, 13, 14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 5, 11, 12, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 13, 14, 15, 7, 16, 17, 7, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -4857,77 +5583,89 @@ pub const XID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
- 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4,
- 4, 2, 2, 2, 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27,
- 28, 29, 30, 4, 2, 31, 32, 32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 4, 35,
- 4, 36, 37, 38, 39, 40, 41, 42, 4, 43, 20, 44, 45, 4, 4, 5, 46, 47, 48, 4,
- 4, 49, 50, 47, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, 4, 4, 4, 57, 58,
- 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 49, 2, 2, 2, 69, 4, 4,
+ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15,
+ 16, 4, 2, 2, 2, 2, 17, 18, 19, 4, 20, 21, 22, 23, 24, 4, 25, 4, 26, 27,
+ 28, 29, 30, 31, 32, 4, 2, 33, 34, 34, 35, 4, 4, 4, 4, 4, 36, 4, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4, 50, 22, 51, 52, 4, 4, 5,
+ 53, 54, 55, 4, 4, 56, 57, 54, 58, 59, 4, 60, 61, 4, 4, 62, 4, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 4, 4, 4, 4, 73, 74, 75, 4, 76, 77, 78, 4, 4,
+ 4, 4, 79, 4, 4, 80, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 81, 4, 2,
+ 56, 2, 2, 2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 83, 84, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 49, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 60, 20, 4, 71, 47, 72, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 2, 73,
- 74, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 72, 85, 86, 87, 54, 88, 75, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 2, 4, 4, 2, 89, 90, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 77, 2, 2, 2, 2, 2, 78, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 93, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 79, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 81, 82, 83, 84, 85, 2, 2,
- 2, 2, 86, 87, 88, 89, 90, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
- 2, 2, 92, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 93,
- 94, 95, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 94, 2, 2, 2, 2, 95, 96, 2, 2, 2, 2, 2, 97, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 2, 98, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 100, 101, 102, 103, 104, 2, 2,
+ 2, 2, 105, 106, 107, 108, 109, 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 111,
+ 112, 4, 4, 4, 4, 87, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 113, 2, 2, 2, 114, 2, 115, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 116, 117, 118, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 119, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 5, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 120, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 121, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 122, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
0x1FFFFFFFFFFFFF, 0xFFFFFFFF1FFFFFFF, 0x1FFFF, 0xFFFFE000FFFFFFFF,
0x3FFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F, 0xFFFF00003FFFFFFF,
- 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xFFFFFFFFF, 0x7FFFFFFFFFFFFF,
- 0xFF003FFFFF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF,
- 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
+ 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xF7FF000FFFFFFFFF,
+ 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x7FDFFFFFFFFFFBF,
+ 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000,
+ 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
0x1FFFFFFF00000000, 0x1FFFFFFF, 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF,
- 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFF00801FFFFFFF,
- 0x3F, 0xFFFFFFFFFFFFF8, 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8,
- 0x47FFFFFFFF0010, 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF,
- 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x780,
- 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF, 0xF000000, 0x10, 0x7FFFFFFFFFF,
- 0x7FFFFFF, 0xFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF,
- 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000, 0x200003CF, 0x1FFFFFFFFFFFFFF,
- 0x7FFFFFFFFDFF, 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F,
- 0xFFFFFDBF00000040, 0x10003FF, 0x7FFFF00000000, 0x3FFFFFF, 0xF, 0x7F,
- 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x1001F, 0xFFF80000, 0x300000000,
- 0x3FFFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF,
- 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF,
- 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F,
- 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF,
- 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x1F, 0xAF7FE96FFFFFFEF,
- 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x7FFFFF, 0xFFFF0003FFFFFFFF,
- 0x1FFFFFFFF, 0x3FFFFFFF,
+ 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFFF,
+ 0x303FFFFFFFFFF, 0xFFFF00801FFFFFFF, 0xFFFF00000000003F,
+ 0xFFFF000000000003, 0x7FFFFF0000001F, 0xFFFFFFFFFFFFF8, 0x26000000000000,
+ 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8, 0x47FFFFFFFF0090,
+ 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F,
+ 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x380000780, 0xFFFFFFFFFFFF, 0xB0,
+ 0x7FFFFFFFFFFF, 0xF000000, 0x10, 0x10007FFFFFFFFFF, 0x7FFFFFF, 0x7F,
+ 0xFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF, 0x8000FFFFFF6FF27F,
+ 0x2, 0xFFFFFCFF00000000, 0xA0001FFFF, 0x407FFFFFFFFF801,
+ 0xFFFFFFFFF0010000, 0xFFFF0000200003FF, 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF,
+ 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040,
+ 0x10003FF, 0x7FFFF00000000, 0x1000000000000, 0x3FFFFFF, 0xF,
+ 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF, 0xFFFF00007FFFFFFF,
+ 0x7FFFFFFFFFFFFFFF, 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x107FF,
+ 0xFFF80000, 0xB00000000, 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x6FEF000000000000,
+ 0x7FFFFFFFF, 0xFFFF00F000070000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF,
+ 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
+ 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF,
+ 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF,
+ 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x3F801FFFFFFFFFFF, 0x4000, 0x7FFF6F7F00000000,
+ 0x1F, 0x80F, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF,
+ 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0x7FF,
],
};
diff --git a/vendor/pest/src/unicode/category.rs b/vendor/pest/src/unicode/category.rs
index 87532aabd..ca39b7fcf 100644
--- a/vendor/pest/src/unicode/category.rs
+++ b/vendor/pest/src/unicode/category.rs
@@ -1,8 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate.exe general-category --trie-set ./target/ucd/
+// ucd-generate general-category --trie-set ./target/ucd/
//
-// ucd-generate is available on crates.io.
+// Unicode version: 14.0.0.
+//
+// ucd-generate 0.2.12 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static ::ucd_trie::TrieSet)] = &[
("Cased_Letter", CASED_LETTER), ("Close_Punctuation", CLOSE_PUNCTUATION),
@@ -44,8 +46,8 @@ pub const CASED_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 6, 7, 0, 8, 8, 8, 8, 9, 10, 11, 12, 0, 0, 0,
0, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 8,
- 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 8,
+ 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -64,8 +66,8 @@ pub const CASED_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 21, 22, 23, 24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -78,17 +80,17 @@ pub const CASED_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 0, 0,
+ 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 0, 0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0xE7FFFFFFFFFF20BF, 0x3F3FFFFFFFFFFFFF,
0xE7FFFFFFFFFF01FF, 0xFFFFFFFFFFF, 0xFEFFF80000000000, 0x7FFFFFF,
0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3F3FFFFF, 0x3FFFFFFFAAFF3F3F,
0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC, 0xF21FBD503E2FFC84, 0x43E0, 0x18,
- 0xFFFF7FFFFFFFFFFF, 0xCFFFFFFF7FFFFFFF, 0xC781FFFFFFFFF, 0x20BFFFFFFFFF,
- 0x3FFFFFFFFFFF, 0xFFFFFFF, 0xFFFFFFFC00000000, 0xFFFEFFFFFFFFFFFF,
- 0x3FFFFFFFFFF78FF, 0x400000000000000, 0xFFFF000000000000,
- 0xFFFF003F07FFFFFF, 0xF8007F, 0x7FFFFFE00000000, 0x7FFFFFE,
+ 0xCFFFFFFFFFFFFFFF, 0xC781FFFFFFFFF, 0x20BFFFFFFFFF, 0x3FFFFFFFFFFF,
+ 0xFFFFFFF, 0xFFFFFFFC00000000, 0xFFFEFFFFFFFFFFFF, 0xFFFFFFFFFFFF78FF,
+ 0x460000003EB07FF, 0xFFFF000000000000, 0xFFFF01FF07FFFFFF, 0xF8007F,
+ 0x7FFFFFE00000000, 0x7FFFFFE,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -104,29 +106,30 @@ pub const CASED_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
+ 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 9,
- 10, 11, 12, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10,
+ 11, 12, 13, 14, 1, 1, 1, 1, 15, 16, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0xFFFFFFFFFFFFFFFF, 0xFFFF, 0xFFFF000000000000, 0xFFFFFFFFF0FFFFF,
- 0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xFFFFFFFFFFDFFFFF,
- 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF,
- 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD,
- 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0xF,
+ 0xF7FF000000000000, 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFF,
+ 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF,
+ 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F,
+ 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF,
+ 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x7FFFFBFF, 0xF,
],
};
@@ -142,7 +145,7 @@ pub const CLOSE_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 0, 7, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10, 11, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -175,13 +178,14 @@ pub const CLOSE_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 13, 14, 0, 0, 15, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 14, 15, 0, 0, 16, 17, 0, 0,
],
tree2_level2: &[
0, 0x2800000000000000, 0x10000000, 0x4000000000000040, 0x4000,
0x40000000A00, 0x2AAA0000000000, 0xAA8000000040, 0x1555550,
- 0x200000000A000000, 0x2A800000000, 0xCAA2AA00, 0x4000000000000000,
- 0x5540000001000000, 0x54000115, 0x2000000000000200, 0x920000000,
+ 0x200000000A000000, 0x2A800000000, 0x15400000, 0xCAA2AA00,
+ 0x4000000000000000, 0x5540000001000000, 0x54000115, 0x2000000000000200,
+ 0x920000000,
],
tree3_level1: &[
],
@@ -275,7 +279,7 @@ pub const CURRENCY_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -297,7 +301,7 @@ pub const CURRENCY_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -311,15 +315,15 @@ pub const CURRENCY_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 9, 0, 0, 10, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 10, 0, 0, 11, 0, 0, 12,
],
tree2_level2: &[
0, 0x80C000000000000, 0x2000000000000, 0x200000000000000,
- 0x8000000000000000, 0x8000000, 0xFFFFFFFF00000000, 0x100000000000000,
+ 0x8000000000000000, 0x8000000, 0xFFFFFFFF00000000, 0x1, 0x100000000000000,
0x1000000000000000, 0x20000000000, 0x10, 0x6300000000,
],
tree3_level1: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -336,11 +340,13 @@ pub const CURRENCY_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x1000000000000,
+ 0, 0x1E0000000, 0x8000000000000000, 0x1000000000000,
],
};
@@ -356,7 +362,7 @@ pub const DASH_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 6, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -389,17 +395,35 @@ pub const DASH_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 10, 0, 0, 0,
],
tree2_level2: &[
- 0, 0x1, 0x40, 0x3F0000, 0xC00000004800000, 0x1000010000000, 0x100000000,
- 0x6000000000000, 0x801000000, 0x2000,
+ 0, 0x1, 0x40, 0x3F0000, 0xC00000004800000, 0x20000001, 0x1000010000000,
+ 0x100000000, 0x6000000000000, 0x801000000, 0x2000,
],
tree3_level1: &[
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,
],
tree3_level2: &[
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
],
tree3_level3: &[
+ 0, 0x200000000000,
],
};
@@ -455,7 +479,7 @@ pub const DECIMAL_NUMBER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0x3FF000000000000, 0x3FF000003FF0000,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -472,18 +496,20 @@ pub const DECIMAL_NUMBER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 4, 0, 0, 5, 0, 0, 0,
2, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 5, 0, 6, 2, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0x3FF00000000, 0x3FF000000000000, 0xFFC000000000, 0xFFC0000000000000,
@@ -613,10 +639,10 @@ pub const FORMAT: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0x1000003F, 0, 0, 0x20000000, 0x8000, 0, 0, 0,
],
tree2_level1: &[
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -652,14 +678,14 @@ pub const FORMAT: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7,
],
tree2_level2: &[
- 0, 0x400000000, 0x4000, 0x7C000000F800, 0xFFDF00000000,
+ 0, 0x30000, 0x400000000, 0x4000, 0x7C000000F800, 0xFFDF00000000,
0x8000000000000000, 0xE00000000000000,
],
tree3_level1: &[
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -667,7 +693,7 @@ pub const FORMAT: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
],
@@ -677,18 +703,21 @@ pub const FORMAT: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x2000000000000000, 0x2000, 0xF00000000, 0x7F8000000000000,
- 0xFFFFFFFF00000002, 0xFFFFFFFFFFFFFFFF,
+ 0, 0x2000000000000000, 0x2000, 0x1FF000000000000, 0xF00000000,
+ 0x7F8000000000000, 0xFFFFFFFF00000002, 0xFFFFFFFFFFFFFFFF,
],
};
@@ -765,91 +794,94 @@ pub const LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 3, 61,
- 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34, 34, 34, 69, 70, 71, 72,
- 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 78, 79, 34, 80, 81, 82, 83, 84, 85, 3, 3, 3, 3, 3, 3, 3, 86, 42, 87, 88,
- 89, 34, 90, 91, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 53, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 93, 94, 34, 34, 34, 34, 95, 96, 97,
- 64, 98, 34, 99, 100, 101, 48, 102, 103, 104, 105, 106, 107, 108, 109, 110,
- 111, 112, 113, 34, 114, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 115, 116, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 117, 34, 118, 119,
- 120, 121, 122, 34, 34, 34, 34, 123, 124, 125, 126, 3, 127, 34, 128, 129,
- 130, 131, 132,
+ 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 35,
+ 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 35, 35, 35, 35, 35, 35, 35, 35,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 3, 58, 59, 60, 30,
+ 61, 62, 63, 64, 65, 66, 67, 68, 35, 35, 35, 30, 35, 35, 35, 35, 69, 70,
+ 71, 72, 30, 73, 74, 30, 75, 76, 77, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 78,
+ 79, 80, 81, 82, 83, 30, 30, 30, 30, 30, 30, 30, 84, 43, 85, 86, 87, 35,
+ 88, 89, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 30, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 90, 91, 35, 35, 35, 35, 92, 93,
+ 94, 64, 95, 35, 96, 97, 98, 49, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 35, 111, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 112, 113, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 114, 35, 115, 116,
+ 117, 118, 119, 35, 35, 35, 35, 120, 121, 122, 123, 30, 124, 35, 125, 126,
+ 127, 128, 129,
],
tree2_level2: &[
- 0x110043FFFFF, 0x7FF01FFFFFF, 0x3FDFFFFF00000000, 0, 0x23FFFFFFFFFFFFF0,
- 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1, 0x10030003B0004000,
- 0x36DFDFFFFF987E0, 0x1C00005E000000, 0x23EDFDFFFFFBBFE0,
- 0x200000300010000, 0x23EDFDFFFFF99FE0, 0x20003B0000000, 0x3FFC718D63DC7E8,
- 0x10000, 0x23FFFDFFFFFDDFE0, 0x307000000, 0x23EFFDFFFFFDDFE1,
- 0x6000340000000, 0x27FFFFFFFFFDDFE0, 0xFC00000380704000,
- 0x2FFBFFFFFC7FFFE0, 0x7F, 0xDFFFFFFFFFFFE, 0x200DECAEFEF02596, 0xF000005F,
- 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000,
- 0xFFFFFFFF00004003, 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF,
- 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
- 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF, 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF,
- 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE,
- 0x1FE07FFFFFFFFFF, 0x3FFFF0003DFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF,
- 0x10800000, 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFF9F,
- 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF, 0x3FF,
- 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0xFE0,
+ 0x110043FFFFF, 0xFFFF07FF01FFFFFF, 0xFFFFFFFF00007EFF, 0x3FF,
+ 0x23FFFFFFFFFFFFF0, 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1,
+ 0x10030003B0004000, 0x36DFDFFFFF987E0, 0x1C00005E000000,
+ 0x23EDFDFFFFFBBFE0, 0x200000300010000, 0x23EDFDFFFFF99FE0,
+ 0x20003B0000000, 0x3FFC718D63DC7E8, 0x10000, 0x23FFFDFFFFFDDFE0,
+ 0x327000000, 0x23EFFDFFFFFDDFE1, 0x6000360000000, 0x27FFFFFFFFFDDFF0,
+ 0xFC00000380704000, 0x2FFBFFFFFC7FFFE0, 0x7F, 0xDFFFFFFFFFFFE,
+ 0x200DFFAFFFFFF7D6, 0xF000005F, 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0,
+ 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000, 0xFFFFFFFF00004003,
+ 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF,
+ 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF,
+ 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE,
+ 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE, 0x1FE07FFFFFFFFFF,
+ 0x3FFFF8003FFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF, 0x10800000,
+ 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFF9F,
+ 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF,
+ 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0x1FE0,
0xFC00C001FFFFFFF8, 0x3FFFFFFFFF, 0xFFFFFFFFF, 0x3FFFFFFFFC00E000,
- 0xE7FFFFFFFFFF01FF, 0x63DE0000000000, 0xFFFFFFFF3F3FFFFF,
+ 0xE7FFFFFFFFFF01FF, 0x46FDE0000000000, 0xFFFFFFFF3F3FFFFF,
0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC,
0x8002000000000000, 0x1FFF0000, 0xF3FFBD503E2FFC84, 0x43E0, 0x18,
- 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0xC781FFFFFFFFF,
- 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF, 0x7F7F7F7F007FFFFF, 0x7F7F7F7F,
- 0x800000000000, 0x183E000000000060, 0xFFFFFFFEE07FFFFF,
- 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0x7FFFFFF00007FFF,
- 0xFFFF000000000000, 0xFFFFFFFFFFFF, 0x1FFF, 0x3FFFFFFFFFFF0000,
- 0xC00FFFF1FFF, 0x80007FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFCFF800000,
- 0x3FFFFFFFFFFF9FF, 0xFF80000000000000, 0x7FFFFF7BB, 0xFFFFFFFFFFFFC,
+ 0xC781FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF, 0x7F7F7F7F007FFFFF,
+ 0x7F7F7F7F, 0x800000000000, 0x183E000000000060, 0xFFFFFFFEE07FFFFF,
+ 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFF00007FFF,
+ 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF,
+ 0x80007FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFCFF800000,
+ 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x7FFFFF7BB, 0xFFFFFFFFFFFFC,
0x68FC000000000000, 0xFFFF003FFFFFFC00, 0x1FFFFFFF0000007F,
0x7FFFFFFFFFFF0, 0x7C00FFDF00008000, 0x1FFFFFFFFFF, 0xC47FFFFF00000FF7,
0x3E62FFFFFFFFFFFF, 0x1C07FF38000005, 0xFFFF7F7F007E7E7E,
- 0xFFFF003FF7FFFFFF, 0x7FFFFFFFF, 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F,
+ 0xFFFF03FFF7FFFFFF, 0x7FFFFFFFF, 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F,
0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFDFFA0F8007F, 0xFFFFFFFFFFFFFFDB,
0x3FFFFFFFFFFFF, 0xFFFFFFFFFFF80000, 0x3FFFFFFFFFFFFFFF,
0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFCFFFF, 0xFFF0000000000FF,
@@ -857,8 +889,8 @@ pub const LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xFFFFFFC007FFFFFE, 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 12, 13, 14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 5, 11, 12, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 13, 14, 15, 7, 16, 17, 7, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -870,78 +902,90 @@ pub const LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
- 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 2, 2, 11, 12, 13, 14, 4,
- 4, 2, 2, 2, 2, 15, 16, 4, 4, 17, 18, 19, 20, 21, 4, 22, 4, 23, 24, 25, 26,
- 27, 28, 29, 4, 2, 30, 31, 31, 14, 4, 4, 4, 4, 4, 4, 4, 32, 33, 4, 4, 34,
- 4, 35, 36, 37, 38, 39, 40, 41, 4, 42, 19, 43, 44, 4, 4, 45, 46, 47, 48, 4,
- 4, 49, 50, 47, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, 4, 4, 4, 57, 58,
- 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 4, 4, 2, 2, 2, 69, 4, 4,
+ 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 2, 2, 11, 12, 13, 14, 15,
+ 4, 2, 2, 2, 2, 16, 17, 18, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27,
+ 28, 29, 30, 31, 4, 2, 32, 33, 33, 34, 4, 4, 4, 4, 4, 35, 4, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 4, 49, 21, 50, 51, 4, 4, 52, 53,
+ 54, 55, 4, 4, 56, 57, 54, 58, 59, 4, 60, 61, 4, 4, 62, 4, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 4, 4, 4, 4, 73, 74, 75, 4, 76, 77, 78, 4, 4, 4, 4,
+ 79, 4, 4, 80, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 81, 4, 4, 4, 2,
+ 2, 2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 83, 84, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 49, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
- 60, 19, 4, 71, 47, 72, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 2, 73,
- 74, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2,
+ 2, 2, 2, 2, 2, 2, 72, 85, 86, 87, 54, 88, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 4, 4, 2, 89, 90, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 19, 77, 2, 2, 2, 2, 2, 78, 4, 4, 4, 4,
+ 2, 2, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 93, 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 2, 79, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 81, 82, 83, 84, 85, 2, 2,
- 2, 2, 86, 87, 88, 89, 90, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
- 2, 2, 92, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 93,
- 94, 95, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 94, 2, 2, 2, 2, 95, 96, 2, 2, 2, 2, 2, 97, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 2, 98, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 100, 101, 102, 103, 104, 2, 2, 2, 2,
+ 105, 106, 107, 108, 109, 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 4, 4, 4, 4, 4, 4, 4, 111, 112,
+ 4, 4, 4, 4, 87, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 113, 2, 2, 2, 114, 2, 115, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 116, 117, 118, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 119, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 45, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 120, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 121, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 122, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 2, 2, 2, 2, 2, 2, 2, 2, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
0xFFFFFFFF1FFFFFFF, 0x1FFFF, 0xFFFFE000FFFFFFFF, 0x3FFFFFFFFF03FD,
0xFFFFFFFF3FFFFFFF, 0xFF0F, 0xFFFF00003FFFFFFF, 0xFFFFFFFFF0FFFFF,
- 0xFFFF00FFFFFFFFFF, 0xFFFFFFFFF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF,
- 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000,
- 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
- 0x1FFFFFFF00000000, 0x1FFFFFFF, 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF,
- 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFF00801FFFFFFF,
- 0x3F, 0xFFFFFFFFFFFFF8, 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8,
- 0x47FFFFFFFF0010, 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF,
- 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x1FFFFFFFFFFFFF,
- 0x780, 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF, 0xF000000, 0x10,
- 0x7FFFFFFFFFF, 0x7FFFFFF, 0xFFFFFFFFFFF, 0xFFFFFFFF00000000,
- 0x80000000FFFFFFFF, 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000, 0x200003CF,
- 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF, 0xFFFC000000000001, 0xFFFF,
- 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040, 0x10003FF, 0x7FFFF00000000,
- 0x3FFFFFF, 0xF, 0x7F, 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x1001F,
- 0xFFF80000, 0x300000000, 0x3FFFFFFFFFFFF, 0xFFFF000000000000,
+ 0xFFFF00FFFFFFFFFF, 0xF7FF000FFFFFFFFF, 0x1BFBFFFBFFB7F7FF,
+ 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x7FDFFFFFFFFFFBF, 0x91BFFFFFFFFFFD3F,
+ 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000, 0x3FFFFFF003FFFFF,
+ 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001, 0x1FFFFFFF00000000, 0x1FFFFFFF,
+ 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF, 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF,
+ 0x7FFFFFFFFFFFF, 0xFFFFFFFFF, 0x303FFFFFFFFFF, 0xFFFF00801FFFFFFF,
+ 0xFFFF00000000003F, 0xFFFF000000000003, 0x7FFFFF0000001F,
+ 0xFFFFFFFFFFFFF8, 0x26000000000000, 0xFFFFFFFFFFF8, 0x1FFFFFF0000,
+ 0x7FFFFFFFF8, 0x47FFFFFFFF0090, 0x7FFFFFFFFFFF8, 0x1400001E,
+ 0xFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000,
+ 0x1FFFFFFFFFFFFF, 0x380000780, 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF,
+ 0xF000000, 0x10, 0x10007FFFFFFFFFF, 0x7FFFFFF, 0x7F, 0xFFFFFFFFFFF,
+ 0xFFFFFFFF00000000, 0x80000000FFFFFFFF, 0x8000FFFFFF6FF27F, 0x2,
+ 0xFFFFFCFF00000000, 0xA0001FFFF, 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000,
+ 0xFFFF0000200003FF, 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF, 0xFFFC000000000001,
+ 0xFFFF, 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040, 0x10003FF, 0x7FFFF00000000,
+ 0x1000000000000, 0x3FFFFFF, 0xF, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF,
+ 0xFFFF00007FFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x3FFFFFFF0000,
+ 0xE0FFFFF80000000F, 0x107FF, 0xFFF80000, 0xB00000000, 0xFFFFFFFFFFFFFF,
+ 0x3FFFFF, 0x6FEF000000000000, 0x7FFFFFFFF, 0xFFFF00F000070000,
0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0xFFFFFFFFFFDFFFFF,
0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF,
0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD,
- 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x1F,
- 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x7FFFFF,
- 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF,
+ 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7,
+ 0x3F801FFFFFFFFFFF, 0x4000, 0x7FFF6F7F00000000, 0x1F, 0x80F,
+ 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0xFFFFFFFF,
+ 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0x7FF,
],
};
@@ -1139,9 +1183,9 @@ pub const LOWERCASE_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0xFEFFF80000000000, 0x7FFFFFF, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAABFEAAAAA,
0xFF00FF003F00FF, 0x3FFF00FF00FF003F, 0x40DF00FF00FF00FF,
0xDC00FF00CF00DC, 0x321080000008C400, 0x43C0, 0x10, 0xFFFF000000000000,
- 0xFDA15627FFFFFFF, 0x8501AAAAAAAAA, 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA,
- 0xAAAAAAA, 0xAAABAAA800000000, 0x95FEAAAAAAAAAAAA, 0x2A082AAAABA50AA,
- 0x400000000000000, 0xFFFF003F07FFFFFF, 0xFFFFFFFFFFFFFFFF, 0xF8007F,
+ 0xFDA1562FFFFFFFF, 0x8501AAAAAAAAA, 0x20BFFFFFFFFF, 0x2AAAAAAAAAAA,
+ 0xAAAAAAA, 0xAAABAAA800000000, 0x95FEAAAAAAAAAAAA, 0xAAA082AAAABA50AA,
+ 0x440000002AA050A, 0xFFFF01FF07FFFFFF, 0xFFFFFFFFFFFFFFFF, 0xF8007F,
0x7FFFFFE,
],
tree3_level1: &[
@@ -1158,30 +1202,31 @@ pub const LOWERCASE_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFC000000, 0xFFFFDFC000,
- 0xEBC000000FFFFFFC, 0xFFFFFC000000FFEF, 0xFFFFFFC000000F, 0xFFFFFFC0000,
- 0xFC000000FFFFFFC0, 0xFFFFC000000FFFFF, 0xFFFFFFC000000FF, 0xFFFFFFC00000,
- 0x3FFFFFFC00, 0xF0000003F7FFFFFC, 0xFFC000000FDFFFFF, 0xFFFF0000003F7FFF,
- 0xFFFFFC000000FDFF, 0xBF7, 0xFFFFFFFC00000000, 0xF,
+ 0, 0xFFFFFF0000000000, 0xFFFF, 0xFFFFFFFFF000000, 0x1BFBFFFBFF800000,
+ 0x7FFFFFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFC000000,
+ 0xFFFFDFC000, 0xEBC000000FFFFFFC, 0xFFFFFC000000FFEF, 0xFFFFFFC000000F,
+ 0xFFFFFFC0000, 0xFC000000FFFFFFC0, 0xFFFFC000000FFFFF, 0xFFFFFFC000000FF,
+ 0xFFFFFFC00000, 0x3FFFFFFC00, 0xF0000003F7FFFFFC, 0xFFC000000FDFFFFF,
+ 0xFFFF0000003F7FFF, 0xFFFFFC000000FDFF, 0xBF7, 0x7FFFFBFF,
+ 0xFFFFFFFC00000000, 0xF,
],
};
@@ -1194,68 +1239,83 @@ pub const MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 6, 8, 6, 9, 6, 10, 11, 12, 13, 14, 6, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 32, 33, 34, 35,
- 2, 36, 2, 37, 2, 2, 2, 38, 39, 40, 2, 41, 42, 43, 44, 45, 2, 2, 46, 2, 2,
- 2, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 48, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, 50, 2, 51, 2, 2, 2, 2, 2, 2, 2,
- 2, 52, 2, 53, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 54, 55, 56, 2, 2, 2, 2, 57, 2, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 2,
- 2, 2, 68, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 31, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 32, 33, 34, 35, 36, 30, 37, 30, 38, 30, 30, 30, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 30, 30, 48, 30, 30, 30, 49, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 50, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 51,
+ 30, 52, 30, 53, 30, 30, 30, 30, 30, 30, 30, 30, 54, 30, 55, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 56,
+ 57, 58, 30, 30, 30, 30, 59, 30, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 30, 30, 30, 70, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 71, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 72, 30, 30, 30, 30, 30, 30, 30,
],
tree2_level2: &[
- 0x3EEFFBC00000, 0xE000000, 0, 0xFFFFFFFBFFF80000, 0xDC0000000000000F,
- 0xC00FEFFFF, 0xD00000000000000E, 0x4000000C0080399F, 0x23000000023987,
- 0xFC00000C00003BBF, 0xC00C0399F, 0xC000000000000004, 0x803DC7,
- 0xC00000000000001F, 0xC00603DDF, 0xD80000000000000F, 0xC00803DDF, 0xC,
- 0xC0000FF5F8400, 0x7F2000000000000, 0x7F80, 0x1BF2000000000000, 0x3F00,
- 0xC2A0000003000000, 0xFFFE000000000000, 0x1FFFFFFFFEFFE0DF, 0x40,
- 0x7FFFF80000000000, 0x1E3F9DC3C00000, 0x3C00BFFC, 0xE0000000,
- 0x1C0000001C0000, 0xC0000000C0000, 0xFFF0000000000000, 0x200FFFFF, 0x3800,
- 0x20000000060, 0xFFF0FFF00000000, 0xF800000, 0x9FFFFFFF7FE00000,
- 0x7FFF000000000000, 0xFFF000000000001F, 0xFF8000000001F, 0x3FFE00000007,
- 0xFFFC000000000, 0xFFFFF000000000, 0x39C21FFFFF70000, 0xFBFFFFFFFFFFFFFF,
- 0x1FFFFFFFF0000, 0x3800000000000, 0x8000000000000000, 0xFFFFFFFF00000000,
- 0xFC0000000000, 0x6000000, 0x3FF7800000000000, 0xC0000000,
- 0x3000000000000, 0xF800000844, 0xFFF0000000000003, 0x8003FFFF0000003F,
- 0x3FC000000000, 0xFFF80, 0xFFF800000000000F, 0x2000000001,
- 0x7FFE0000000000, 0x3800000000003008, 0xC19D000000000000,
- 0x60F80000000002, 0x37F800000000, 0x40000000, 0xFFFF0000FFFF,
+ 0x3EEFFBC00000, 0xE000000, 0xFF000000, 0xFFFFFFFBFFFFFC00,
+ 0xDC0000000000000F, 0xC00FEFFFF, 0xD00000000000000E, 0x4000000C0080399F,
+ 0x23000000023987, 0xFC00000C00003BBF, 0xC00E0399F, 0xC000000000000004,
+ 0x803DC7, 0xD00000000000001F, 0xC00603DDF, 0xD80000000000000F,
+ 0xC00803DDF, 0xE, 0xC0000FF5F8400, 0x7F2000000000000, 0x7F80,
+ 0x1FF2000000000000, 0x3F00, 0xC2A0000003000000, 0xFFFE000000000000,
+ 0x1FFFFFFFFEFFE0DF, 0x40, 0x7FFFF80000000000, 0x1E3F9DC3C00000,
+ 0x3C00BFFC, 0, 0xE0000000, 0x1C0000003C0000, 0xC0000000C0000,
+ 0xFFF0000000000000, 0x200FFFFF, 0xB800, 0x20000000060, 0xFFF0FFF00000000,
+ 0xF800000, 0x9FFFFFFF7FE00000, 0xFFFF000000000000, 0x7FFF,
+ 0xFFF000000000001F, 0xFF8000000001F, 0x3FFE00000007, 0xFFFC000000000,
+ 0xFFFFF000000000, 0x39021FFFFF70000, 0xFFFFFFFFFFFFFFFF, 0x1FFFFFFFF0000,
+ 0x3800000000000, 0x8000000000000000, 0xFFFFFFFF00000000, 0xFC0000000000,
+ 0x6000000, 0x3FF7800000000000, 0xC0000000, 0x3000000000000,
+ 0x10F800000844, 0xFFF0000000000003, 0x8003FFFF0000003F, 0x3FC000000000,
+ 0xFFF80, 0xFFF800000000000F, 0x2000000001, 0x7FFE0000000000,
+ 0x3800000000003008, 0xC19D000000000000, 0x60F80000000002, 0x37F800000000,
+ 0x40000000, 0xFFFF0000FFFF,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1263,48 +1323,53 @@ pub const MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15,
- 0, 0, 16, 17, 18, 0, 0, 19, 20, 21, 22, 0, 0, 23, 24, 21, 25, 26, 0, 27,
- 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, 32, 0, 33, 0,
- 34, 35, 36, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 0, 0, 19, 20, 21, 0, 0, 22, 23, 24, 25, 0, 0, 26, 27, 24, 28, 29, 0,
+ 30, 0, 0, 0, 31, 0, 0, 0, 32, 33, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 38, 0,
+ 39, 0, 40, 41, 42, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 48, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 52, 52,
- 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51,
+ 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 61, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63, 63, 64, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
],
tree3_level3: &[
0, 0x2000000000000000, 0x100000000, 0x7C0000000000000, 0x870000000000F06E,
- 0x6000000000, 0xF000000000, 0x1FFC0, 0xFF00000000000007,
- 0x800000000000007F, 0x7FF000000000007, 0x1FFF8000000007, 0x8000000000060,
- 0xFFF8000000000007, 0x1E01, 0x40FFF00000000000, 0x7FF80000000,
- 0xD80000000000000F, 0x1F1FCC0080399F, 0xFFE0000000000000, 0x4000007F,
- 0xFFFF000000000000, 0xF, 0xFF3F800000000000, 0x30000001, 0x1,
- 0xFFF80000000000, 0xFFFE0000000, 0x7FFF00000000000, 0x7BF80000000007FE,
- 0xFFE0080, 0x3FFFC00, 0xFF7F800000000000, 0x7FFEFFFFFC0000,
- 0xB47E000000000000, 0xBF, 0xFB7C00, 0x78000000000000, 0x1F000000000000,
- 0x7F000000000000, 0x7FFFFFFFFFFE0000, 0x78000, 0x60000000,
- 0xF807E3E000000000, 0x3C0000000FE7, 0x1C, 0xF87FFFFFFFFFFFFF,
- 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F, 0x7F0000, 0x7F0,
- 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF,
+ 0x6000000000, 0xF000000000, 0x180000000000, 0x1FFC0, 0x3C,
+ 0xFF00000000000007, 0x801900000000007F, 0x7FF000000000007, 0x4,
+ 0x1FFF8000000007, 0x8000000000060, 0xFFF8000000000007, 0xDE01,
+ 0x40FFF00000000000, 0x7FF80000000, 0xD80000000000000F, 0x1F1FCC0080399F,
+ 0xFFE0000000000000, 0x4000007F, 0xFFFF000000000000, 0xF,
+ 0xFF3F800000000000, 0x30000001, 0x1, 0xFFF80000000000, 0xFFFE0000000,
+ 0x7FFF00000000000, 0x79BF000000000000, 0xD, 0x11FCFE0000,
+ 0x7BF80000000007FE, 0xFFE0080, 0x3FFFC00, 0xFF7F800000000000,
+ 0x7FFEFFFFFC0000, 0xB47E000000000000, 0xBF, 0xFB7C00, 0x78000000000000,
+ 0x1F000000000000, 0x7F000000000000, 0xFFFFFFFFFFFE8000, 0x780FF,
+ 0x3001000000000, 0x60000000, 0xFFFF3FFFFFFFFFFF, 0x7F, 0xF807E3E000000000,
+ 0x3C0000000FE7, 0x1C, 0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF,
+ 0xFFFEF8000010, 0x7DBF9FFFF7F, 0x400000000000, 0xF00000000000, 0x7F0000,
+ 0x7F0, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF,
],
};
@@ -1400,13 +1465,13 @@ pub const MODIFIER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0x6000000000, 0, 0, 0, 0x430000000000000,
],
tree2_level1: &[
- 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7,
- 1, 1, 1, 1, 1, 1, 8, 1, 1, 9, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12,
- 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14,
- 1, 1, 1, 15, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 16, 1, 17, 18, 1, 1, 1, 1, 1,
+ 0, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 8,
+ 1, 1, 1, 1, 1, 1, 9, 1, 1, 10, 11, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13,
+ 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15,
+ 1, 1, 1, 16, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 17, 1, 18, 19, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1424,9 +1489,9 @@ pub const MODIFIER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 20, 21, 22, 1, 23, 24, 25, 26,
- 1, 1, 1, 1, 1, 1, 1, 27, 1, 24, 1, 28, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 21, 22, 23, 1, 24, 25, 26, 27,
+ 1, 1, 1, 1, 1, 1, 1, 28, 1, 25, 1, 29, 1, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1440,40 +1505,48 @@ pub const MODIFIER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 24, 30, 1,
+ 1, 25, 31, 1,
],
tree2_level2: &[
- 0x11004000000, 0, 0x2000000000000, 0x40, 0x1000000000000000, 0x800000,
- 0x8, 0x8000000000, 0x3F00000000000000, 0xFFFFF00000000000,
+ 0x11004000000, 0, 0x200, 0x2000000000000, 0x40, 0x1000000000000000,
+ 0x800000, 0x8, 0x8000000000, 0x3F00000000000000, 0xFFFFF00000000000,
0x10007FFFFFFFFFF, 0xFFFFFFFFF8000000, 0x8002000000000000, 0x1FFF0000,
0x3000000000000000, 0x800000000000, 0x83E000000000020, 0x60000000,
0x7000000000000000, 0x200000, 0x1000, 0x8000000000000000, 0x30000000,
- 0xFF800000, 0x1000000000000, 0x100, 0x300000000000000, 0x4000008000,
- 0x18000020000000, 0xF0000000, 0xC0000000,
+ 0xFF800000, 0x1000000000000, 0x100, 0x31C000000000000, 0x4000008000,
+ 0x18000020000000, 0x200F0000000, 0xC0000000,
],
tree3_level1: &[
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,
+ ],
+ tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- ],
- tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 2, 3,
+ 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xF, 0xFFF80000, 0x300000000,
+ 0, 0x7FDFFFFFFFFFFBF, 0xF, 0xFFF80000, 0xB00000000, 0x6FEF000000000000,
+ 0x3F80000000000000, 0x800,
],
};
@@ -1484,13 +1557,14 @@ pub const MODIFIER_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0,
],
tree2_level1: &[
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1508,9 +1582,9 @@ pub const MODIFIER_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1521,13 +1595,13 @@ pub const MODIFIER_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
- 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 0, 12,
],
tree2_level2: &[
- 0, 0xA000000000000000, 0x6000E000E000E003, 0x18000000, 0x3007FFFFF, 0x600,
- 0x8000000, 0xFFFC000000000000, 0x3, 0x4000000000000000, 0x1, 0x800000000,
+ 0, 0x100, 0xA000000000000000, 0x6000E000E000E003, 0x18000000, 0x3007FFFFF,
+ 0x600, 0xC0008000000, 0xFFFC000000000000, 0x7, 0x4000000000000000, 0x1,
+ 0x800000000,
],
tree3_level1: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1564,68 +1638,83 @@ pub const NONSPACING_MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18,
- 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 34, 35, 36,
- 37, 2, 38, 2, 39, 2, 2, 2, 40, 41, 42, 2, 43, 44, 45, 46, 47, 2, 2, 48, 2,
- 2, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 2, 52, 2, 53, 2, 2, 2, 2, 2, 2,
- 2, 2, 54, 2, 55, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 56, 57, 58, 2, 2, 2, 2, 59, 2, 2, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- 2, 2, 2, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 34, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 35, 36, 37, 38, 39, 33, 40, 33, 41, 33, 33, 33, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 33, 33, 51, 33, 33, 33, 52, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 53, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 54, 33, 55, 33, 56, 33, 33, 33, 33, 33, 33, 33, 33, 57, 33, 58, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 59, 60, 61, 33, 33, 33, 33, 62, 33, 33, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 33, 33, 33, 72, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 73, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 74, 33, 33, 33, 33, 33, 33, 33,
],
tree2_level2: &[
- 0x3EEFFBC00000, 0xE000000, 0, 0xFFFFFFFBFFF80000, 0x1400000000000007,
- 0xC00FE21FE, 0x1000000000000002, 0x4000000C0000201E, 0x1000000000000006,
- 0x23000000023986, 0xFC00000C000021BE, 0x9000000000000002, 0xC0040201E,
- 0x4, 0x2001, 0xC000000000000011, 0xC00603DC1, 0xC00003040,
- 0x1800000000000003, 0xC0000201E, 0x5C0400, 0x7F2000000000000, 0x7F80,
- 0x1BF2000000000000, 0x3F00, 0x2A0000003000000, 0x7FFE000000000000,
- 0x1FFFFFFFFEFFE0DF, 0x40, 0x66FDE00000000000, 0x1E0001C3000000,
- 0x20002064, 0xE0000000, 0x1C0000001C0000, 0xC0000000C0000,
- 0x3FB0000000000000, 0x200FFE40, 0x3800, 0x20000000060, 0xE04018700000000,
- 0x9800000, 0x9FF81FE57F400000, 0x3FFF000000000000, 0x17D000000000000F,
- 0xFF80000000004, 0x3B3C00000003, 0x3A34000000000, 0xCFF00000000000,
- 0x31021FDFFF70000, 0xFBFFFFFFFFFFFFFF, 0x1FFE21FFF0000, 0x3800000000000,
- 0x8000000000000000, 0xFFFFFFFF00000000, 0x3C0000000000, 0x6000000,
- 0x3FF0800000000000, 0xC0000000, 0x3000000000000, 0x6000000844,
- 0x8003FFFF00000030, 0x3FC000000000, 0x3FF80, 0x13C8000000000007,
- 0x2000000000, 0x667E0000000000, 0x1000000000001008, 0xC19D000000000000,
- 0x40300000000002, 0x212000000000, 0x40000000, 0xFFFF0000FFFF,
+ 0x3EEFFBC00000, 0xE000000, 0xFF000000, 0xFFFFFFFBFFFFFC00,
+ 0x1400000000000007, 0xC00FE21FE, 0x1000000000000002, 0x4000000C0000201E,
+ 0x1000000000000006, 0x23000000023986, 0xFC00000C000021BE,
+ 0x9000000000000002, 0xC0060201E, 0x4, 0x2001, 0xD000000000000011,
+ 0xC00603DC1, 0xC00003040, 0x1800000000000003, 0xC0000201E, 0x2, 0x5C0400,
+ 0x7F2000000000000, 0x7F80, 0x1FF2000000000000, 0x3F00, 0x2A0000003000000,
+ 0x7FFE000000000000, 0x1FFFFFFFFEFFE0DF, 0x40, 0x66FDE00000000000,
+ 0x1E0001C3000000, 0x20002064, 0, 0xE0000000, 0xC0000001C0000,
+ 0xC0000000C0000, 0x3FB0000000000000, 0x200FFE40, 0xB800, 0x20000000060,
+ 0xE04018700000000, 0x9800000, 0x9FF81FE57F400000, 0xBFFF000000000000,
+ 0x7FFF, 0x17D000000000000F, 0xFF80000000004, 0x3B3C00000003,
+ 0x3A34000000000, 0xCFF00000000000, 0x31021FDFFF70000, 0xFFFFFFFFFFFFFFFF,
+ 0x1FFE21FFF0000, 0x3800000000000, 0x8000000000000000, 0xFFFFFFFF00000000,
+ 0x3C0000000000, 0x6000000, 0x3FF0800000000000, 0xC0000000,
+ 0x3000000000000, 0x106000000844, 0x8003FFFF00000030, 0x3FC000000000,
+ 0x3FF80, 0x33C8000000000007, 0x2000000000, 0x667E0000000000,
+ 0x1000000000001008, 0xC19D000000000000, 0x40300000000002, 0x212000000000,
+ 0x40000000, 0xFFFF0000FFFF,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1633,48 +1722,53 @@ pub const NONSPACING_MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15,
- 0, 0, 16, 17, 18, 0, 0, 19, 20, 21, 22, 0, 0, 23, 24, 25, 26, 27, 0, 28,
- 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 0, 0, 0, 33, 0, 34, 0,
- 35, 36, 37, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 0, 0, 19, 20, 21, 0, 0, 22, 23, 24, 25, 0, 0, 26, 27, 28, 29, 30, 0,
+ 31, 0, 0, 0, 32, 0, 0, 0, 33, 34, 0, 35, 36, 37, 38, 0, 0, 0, 0, 0, 39, 0,
+ 40, 0, 41, 42, 43, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45,
+ 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 48, 49, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 52, 52,
- 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 52,
+ 0, 0, 0, 0, 0, 0, 0, 53, 54, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 57, 58, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 46, 0,
+ 0, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 62, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64, 64, 65, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
],
tree3_level3: &[
0, 0x2000000000000000, 0x100000000, 0x7C0000000000000, 0x870000000000F06E,
- 0x6000000000, 0xF000000000, 0x1FFC0, 0xFF00000000000002,
- 0x800000000000007F, 0x678000000000003, 0x1FEF8000000007, 0x8000000000000,
- 0x7FC0000000000003, 0x1E00, 0x40D3800000000000, 0x7F880000000,
- 0x1800000000000003, 0x1F1FC000000001, 0xFF00000000000000, 0x4000005C,
- 0x85F8000000000000, 0xD, 0xB03C000000000000, 0x30000001,
- 0xA7F8000000000000, 0x1, 0xBF280000000000, 0xFBCE0000000,
- 0x6FF800000000000, 0x79F80000000007FE, 0xE7E0080, 0x37FFC00,
- 0xBF7F000000000000, 0x6DFCFFFFFC0000, 0xB47E000000000000, 0xBF, 0xA30000,
- 0x18000000000000, 0x1F000000000000, 0x7F000000000000, 0x78000, 0x60000000,
- 0xF800038000000000, 0x3C0000000FE7, 0x1C, 0xF87FFFFFFFFFFFFF,
- 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F, 0x7F0000, 0x7F0,
- 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF,
+ 0x6000000000, 0xF000000000, 0x180000000000, 0x1FFC0, 0x3C,
+ 0xFF00000000000002, 0x801900000000007F, 0x678000000000003, 0x4,
+ 0x1FEF8000000007, 0x8000000000000, 0x7FC0000000000003, 0x9E00,
+ 0x40D3800000000000, 0x7F880000000, 0x1800000000000003, 0x1F1FC000000001,
+ 0xFF00000000000000, 0x4000005C, 0x85F8000000000000, 0xD,
+ 0xB03C000000000000, 0x30000001, 0xA7F8000000000000, 0x1, 0xBF280000000000,
+ 0xFBCE0000000, 0x6FF800000000000, 0x5800000000000000, 0x8, 0x10CF00000,
+ 0x79F80000000007FE, 0xE7E0080, 0x37FFC00, 0xBF7F000000000000,
+ 0x6DFCFFFFFC0000, 0xB47E000000000000, 0xBF, 0xA30000, 0x18000000000000,
+ 0x1F000000000000, 0x7F000000000000, 0x8000, 0x78000, 0x1000000000,
+ 0x60000000, 0xFFFF3FFFFFFFFFFF, 0x7F, 0xF800038000000000, 0x3C0000000FE7,
+ 0x1C, 0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7DBF9FFFF7F,
+ 0x400000000000, 0xF00000000000, 0x7F0000, 0x7F0, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFF,
],
};
@@ -1753,26 +1847,26 @@ pub const NUMBER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree3_level2: &[
0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, 0, 13, 14, 0, 15, 16, 17, 0, 18,
- 19, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 22, 0, 0, 23, 24, 0, 0, 0, 25, 0, 21,
- 26, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0, 28, 0, 28, 0, 0, 0, 0, 0, 28, 0,
- 29, 30, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
- 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 22, 0, 0, 23, 24, 0, 25, 0, 26, 0, 21,
+ 27, 0, 0, 28, 0, 0, 0, 21, 0, 0, 0, 0, 0, 29, 0, 29, 0, 0, 0, 0, 0, 29, 0,
+ 30, 31, 0, 0, 0, 0, 0, 0, 32, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 29, 8, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 38, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 30, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 40, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0xFFFFFFFFFFF80, 0x1FFFFFFFFFFFFFF, 0xC00, 0xFFFFFFE00000000,
@@ -1780,11 +1874,12 @@ pub const NUMBER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xFF8000000000, 0xF800000000000000, 0xFC00000, 0x3000000000000000,
0xFFFFFFFFFFFCFFFF, 0x60000000000001FF, 0xE0000000, 0xF80000000000,
0xFF000000FF000000, 0xFE0000000000, 0xFC00000000000000, 0x3FF000000000000,
- 0x7FFFFFFF00000000, 0x7FE0000000, 0x1E0000, 0xFFFFFFFC0000,
+ 0x7FFFFFFF00000000, 0x7FE0000000, 0x1E0000, 0xFE0, 0xFFFFFFFC0000,
0xFFC0000000000000, 0x1FFFFE03FF0000, 0x3FF0000, 0x3FF, 0xFFF000000000000,
- 0x7FFFF00000000, 0x1FFFFFFF0000, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFF,
- 0x3FBFF0000, 0x7FFFFF, 0xFFFFF00000000, 0x1FFFFFF00000000,
- 0xFFFFFFFFFFFFC000, 0xFF80, 0xFFFE000000000000, 0x1EEFFFFFFFFFFF, 0x1FFF,
+ 0x7FFFF00000000, 0x1FFFFFFF0000, 0x1FFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0x7FFFFFFFFFFF, 0x3FBFF0000, 0x7FFFFF, 0xFFFFF00000000, 0x1FFFFFF00000000,
+ 0xFFFFFFFFFFFFC000, 0xFF80, 0xFFFE000000000000, 0x1EEFFFFFFFFFFF,
+ 0x3FFFBFFFFFFFFFFE, 0x1FFF,
],
};
@@ -1838,8 +1933,9 @@ pub const OPEN_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
tree2_level2: &[
0, 0x1400000000000000, 0x8000000, 0x44000000, 0x2000000000000020, 0x2000,
0x20000000500, 0x15550000000000, 0x554000000020, 0xAAAAA8,
- 0x1000000005000000, 0x15400000000, 0x4, 0x25515500, 0x8000000000000000,
- 0xAAA0000000800000, 0x2A00008A, 0x800000000000100, 0x488000000,
+ 0x1000000005000000, 0x15400000000, 0xAA00004, 0x25515500,
+ 0x8000000000000000, 0xAAA0000000800000, 0x2A00008A, 0x800000000000100,
+ 0x488000000,
],
tree3_level1: &[
],
@@ -1853,7 +1949,7 @@ pub const OTHER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
0xFFFFFFFF, 0x8000000000000000, 0x2000FFFFFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0x300000000000000, 0x40000280F, 0, 0, 0, 0, 0, 0x1000000000000,
- 0x1800000, 0x11800, 0xFFE078000000FF00, 0x3000003F, 0, 0, 0x20000000,
+ 0x1800000, 0x11800, 0xFFE078000000FF00, 0x1000003F, 0, 0, 0x20000000,
0xC000, 0x1800, 0xFFFC000000000000, 0x1800000000000000,
],
tree2_level1: &[
@@ -1861,15 +1957,15 @@ pub const OTHER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
20, 21, 22, 23, 24, 25, 26, 4, 27, 28, 29, 4, 4, 4, 30, 4, 4, 4, 4, 4, 31,
32, 33, 34, 35, 36, 37, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 38, 39, 40, 41, 4,
42, 43, 39, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 4, 54, 4, 55, 56, 57,
- 58, 59, 4, 4, 4, 60, 4, 4, 4, 4, 61, 62, 63, 64, 65, 66, 67, 68, 4, 4, 69,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 70, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 72, 73, 74, 75, 76, 4, 77, 78,
- 79, 80, 81, 4, 82, 83, 84, 4, 4, 4, 85, 4, 86, 87, 4, 88, 4, 89, 90, 76,
- 4, 4, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 58, 59, 4, 4, 4, 4, 4, 4, 4, 4, 60, 61, 62, 63, 64, 65, 66, 67, 4, 4, 68,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 69, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 71, 72, 4, 4, 4, 4, 73, 74, 75,
+ 76, 77, 4, 78, 79, 80, 4, 4, 4, 81, 4, 82, 83, 4, 84, 4, 85, 86, 87, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 45, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -1882,167 +1978,182 @@ pub const OTHER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 4, 4, 96, 4, 4, 97,
- 98, 99, 96, 4, 100, 4, 101, 4, 102, 103, 104, 4, 105, 106, 107, 4, 108, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 88, 89, 4, 4, 4, 4, 90, 4, 4, 91, 4, 4, 4, 92, 93, 91, 4,
+ 94, 4, 95, 4, 96, 97, 98, 4, 99, 100, 48, 4, 101, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 90,
- 109, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 4, 4, 4, 4, 4, 110, 4, 111, 112, 113, 4, 114,
- 4, 4, 4, 4, 4, 115, 116, 117, 36, 118, 4, 119, 86, 4, 91, 120,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 86, 102, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 4, 4, 4, 4, 4, 104, 4, 105,
+ 106, 107, 4, 108, 4, 4, 4, 4, 4, 4, 109, 110, 36, 111, 4, 112, 82, 4, 113,
+ 114,
],
tree2_level2: &[
- 0x8000C00000000000, 0xFFFFF800B0000000, 0xC0200000FFFFFFFF, 0x40007FFFF,
- 0, 0xC3A020000066010, 0x800000304F7F8660, 0x2C92020000067811,
+ 0x8000C00000000000, 0xF800B0000000, 0xFF8000, 0x400000000, 0,
+ 0xC3A020000066010, 0x800000304F7F8660, 0x2C92020000067811,
0xFF80003FA1FDC678, 0xC12020000044011, 0x1FC0030FFFEC440,
- 0xC12020000066011, 0xFF0000304F3FC660, 0x3C0038E729C23813,
- 0xF800003FFF7EC238, 0x1C00020000022000, 0xFF0030F89FC220,
- 0xC10020000022000, 0xFFF90030BF9FC220, 0x22010, 0x30000F0220,
- 0xD004000003800013, 0xFFE3003F00A07B80, 0x7800000000000001,
- 0xFFFFFFFFF0000000, 0xC4001351010FDA69, 0xFFFFFFFF0C00C0A0,
+ 0xC12020000066011, 0xFF0000304F1FC660, 0x3C0038E729C23813,
+ 0xF800003FFF7EC238, 0xC00020000022000, 0x7F0030D89FC220,
+ 0xC10020000022000, 0xFFF900309F9FC220, 0x22000, 0x30000F0220,
+ 0xD004000003800011, 0xFFE3003F00A07B80, 0x7800000000000001,
+ 0xFFFFFFFFF0000000, 0xC000005000000829, 0xFFFFFFFF0C00C0A0,
0x1E00000000100, 0x2000000001000000, 0xFFFFFFFFF8002000, 0xDF40,
0xC280C200, 0x80C200000000C200, 0x8000C2, 0xC20000, 0xE000000018000000,
0xFC000000, 0xC0C0000000000000, 0xE0000000, 0xFE00000000000000,
- 0xFF800000FFE02000, 0xFFF22000FFF00000, 0xFC00FC00C0000000, 0xFC00C000,
+ 0xFF8000007FC00000, 0xFFF22000FFF00000, 0xFC00FC00C0000000, 0xFC004000,
0xF80000000000, 0xFFC0000000000000, 0xF000F00080000000,
0xFFE0C0000000000E, 0xF00000000000, 0x3800FC00, 0x30000000,
- 0x6000000080000000, 0x8000C000FC00FC00, 0xFFFFFFFFFFFFFFFF,
- 0xE00000000000F000, 0xFF0000000000000, 0x700000000000000, 0x1C00,
- 0x180000000000FE00, 0xFC0000000000FF00, 0x400000000000000, 0xC0C00000,
- 0xC00000005500C0C0, 0x20000000000000, 0x8023000010300020, 0x7C000000F800,
- 0xCFFFF00000000, 0xE0008000, 0xFFFE00000000FFFF, 0xF000,
- 0xFFFFFF8000000000, 0xFFFFF800, 0x30000000000000, 0xC00000,
- 0x8000000000000200, 0x800000000000, 0x80000000, 0x1F0000000000000,
- 0xDF4000000000, 0x7FFE7F0000000000, 0x80808080FF800000, 0x80808080,
- 0xFFFFFFFFFFFF8000, 0x4000000, 0xFFF0000000000000, 0xF000FFFFFFC00000,
- 0x1, 0x1800000, 0x100000000001F, 0xF800000000008000, 0xFFF000000000,
- 0x8000000000000000, 0xFFFF000000000000, 0xE000, 0xFF80,
- 0xFFFFF00000000000, 0xFF00000000000000, 0xFC00000000000000,
- 0x7FFFFFFFFFFFFF, 0xFC00F00000000000, 0xFC003FC0, 0xE00000007FF00000,
- 0x800000003C004000, 0xFF80000000000000, 0xC00C000, 0xFF80000007FFFFF8,
- 0x8080FF818181, 0xFFC000000000, 0xFC00C00000000000, 0xF000000000000780,
- 0xC00000000000, 0xFFFFFFFFFC000000, 0xA08000001F07FF80, 0x24, 0x7FFFC,
- 0xFFFF, 0x30000, 0xC000FFFFFFFFFF00, 0x20F08000080000, 0xE000000000000000,
- 0xCFFF8080E3030303,
+ 0x6000000080000000, 0xC000FC00FC00, 0xFFFFFFFFFFFF8000,
+ 0x800000000000E000, 0xFF0000000000000, 0x700000000000000, 0x1C00,
+ 0x180000000000FE00, 0xF80000000000FF00, 0xC0C00000, 0xC00000005500C0C0,
+ 0x20000000000000, 0x8023000010300020, 0x7C000000F800, 0xCFFFF00000000,
+ 0xE0008000, 0xFFFE00000000FFFE, 0xF000, 0xFFFFFF8000000000, 0xFFFFF800,
+ 0x30000000000000, 0x400000, 0x1F0000000000000, 0xDF4000000000,
+ 0x7FFE7F0000000000, 0x80808080FF800000, 0x80808080, 0xFFFFFFFFC0000000,
+ 0x4000000, 0xFFF0000000000000, 0xF000FFFFFFC00000, 0x1, 0x1800000,
+ 0x100000000001F, 0x8000, 0xFFF000000000, 0x80000000, 0xE000, 0xFF80,
+ 0xFFFFF00000000000, 0xFF00000000000000, 0x3FFFFFC14F800,
+ 0xFC00E00000000000, 0xFC003FC0, 0xE00000007FF00000, 0x800000003C004000,
+ 0xFF80000000000000, 0xC00C000, 0xFF80000007FFFFF8, 0x8080FF818181,
+ 0xFC00C00000000000, 0xF000000000000780, 0xFFFFFFFFFFFFFFFF,
+ 0xC00000000000, 0xFFFFFFFFFC000000, 0xA08000001F07FF80, 0x24, 0x7FFF8,
+ 0x30000, 0xFFFFFFFF7F00, 0x20F08000080000, 0xE000000000000000,
+ 0x8000000000000000, 0xCFFF8080E3030303,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 13, 14, 15, 7, 16, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
],
tree3_level2: &[
0, 1, 2, 3, 4, 2, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 2, 2, 14, 15, 16, 17,
- 7, 7, 2, 2, 2, 2, 18, 19, 7, 7, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 7, 2, 34, 35, 36, 37, 7, 7, 7, 7, 38, 7, 7, 16, 39, 7, 7,
- 2, 40, 41, 42, 43, 44, 2, 45, 46, 7, 47, 48, 49, 50, 7, 7, 2, 51, 2, 52,
- 7, 7, 53, 54, 2, 55, 56, 57, 58, 7, 7, 7, 59, 7, 60, 61, 7, 7, 7, 7, 2,
- 62, 63, 64, 7, 7, 7, 7, 65, 66, 67, 7, 68, 69, 70, 7, 7, 7, 7, 71, 7, 7,
- 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 39, 7, 2, 72, 2, 2, 2, 73,
+ 18, 7, 2, 2, 2, 2, 19, 20, 21, 7, 22, 23, 24, 25, 26, 7, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 7, 2, 36, 37, 38, 39, 7, 7, 7, 7, 40, 41, 7, 16, 42,
+ 43, 44, 2, 45, 46, 47, 48, 49, 2, 50, 51, 7, 52, 53, 54, 55, 7, 7, 2, 56,
+ 2, 57, 7, 7, 58, 59, 2, 60, 61, 62, 63, 64, 7, 7, 65, 7, 66, 67, 68, 69,
+ 70, 71, 2, 72, 73, 74, 7, 7, 7, 7, 75, 76, 77, 7, 78, 79, 80, 7, 7, 7, 7,
+ 81, 7, 7, 82, 83, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 84, 7, 2, 85,
+ 2, 2, 2, 86, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 87, 37, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 74, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 75, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 64, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2,
- 2, 64, 76, 7, 77, 2, 78, 79, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 80, 7, 2,
- 81, 82, 83, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2,
+ 2, 2, 2, 2, 2, 2, 2, 74, 89, 90, 91, 2, 92, 93, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 2, 94, 7, 2, 95, 96, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 84, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 35, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 85, 86, 2, 2, 2, 2, 2, 59, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 99, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 2, 87, 88, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 2, 2, 2, 89, 90, 91, 2, 92, 2, 93, 7, 94, 2, 95, 7, 7, 2, 96, 97, 98, 99,
- 100, 2, 2, 2, 2, 101, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 104, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 2, 2, 2, 105, 2, 106, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 107,
- 108, 7, 7, 7, 7, 7, 109, 110, 111, 112, 7, 7, 7, 7, 113, 2, 114, 115, 116,
- 113, 117, 118, 119, 120, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 121, 2, 122, 2, 123, 124, 125, 126, 7, 127, 128, 129, 130, 7, 131, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 132,
+ 7, 7, 7, 100, 2, 2, 2, 2, 101, 102, 2, 2, 2, 2, 2, 65, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 2, 103, 104, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 105, 106, 2, 86, 2, 2, 2, 107, 108, 109, 2, 110,
+ 2, 111, 7, 112, 2, 113, 7, 7, 2, 114, 115, 116, 117, 118, 2, 2, 2, 2, 119,
+ 2, 2, 2, 2, 120, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 121, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 122, 7, 7, 7, 123, 7, 7, 7, 124, 125, 7, 7,
+ 7, 7, 126, 127, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 128, 2, 2, 2, 129, 2, 130, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 131, 132, 7,
+ 133, 7, 7, 7, 134, 135, 136, 137, 7, 7, 7, 7, 138, 2, 139, 140, 2, 2, 141,
+ 142, 143, 144, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 145, 2,
+ 146, 2, 147, 148, 149, 150, 7, 2, 2, 2, 2, 2, 151, 152, 153, 2, 2, 154,
+ 155, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 133, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 2, 2, 2, 156, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 134, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 157, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 135, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 158, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 54, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 59, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 159, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 2, 2, 2, 136, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 160, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
],
tree3_level3: &[
0x4800008000001000, 0xFFFFFFFFC000C000, 0, 0xF800000000000000,
- 0x70000000000078, 0xFFFFFFFEF0008000, 0xC00000000000FFFF,
+ 0x70000000000078, 0xFFFFFFFEE0008000, 0xC00000000000FFFF,
0xFFFFFFFFFFFFFFFF, 0xE0000000, 0xF0000000FFFE0000, 0x1FF000000000,
0xF80000000000F800, 0x40000000, 0xFFFFFFFFFFC000F0, 0xFC00C0000000,
- 0xF000000000F00000, 0xFF0000000000, 0xFFFF7FF000000000,
- 0xFF80000000000000, 0xFFFFFF00FFC00000, 0x6E400000000002C0, 0x400000,
- 0xFFFF007F80000000, 0x7C80000FFFFFFFF, 0x7C00000070000000,
- 0xF00000000000000, 0x30000, 0x78C0000001100F90, 0xFE00FE00,
- 0xFFFFFFFF00000000, 0xFF80078000000000, 0x1C0000000000000,
+ 0xF000000000F00000, 0xFF0000000000, 0x8007FF000000000, 0xE404000400480800,
+ 0xFF80000000000000, 0xFFFFFF00FFC00000, 0xF802000000000040,
+ 0x6E400000000002C0, 0x400000, 0xFFFF007F80000000, 0x7C80000FFFFFFFF,
+ 0x7C00000070000000, 0xF00000000000000, 0x30000, 0x78C0000001100F90,
+ 0xFE00FE00, 0xFFFFFFFF00000000, 0xFF80078000000000, 0x1C0000000000000,
0xF8000000C00000, 0xFFFF01FFE1FC0000, 0xFFFFFFFFFFFFFE00,
0xFFF8000000000000, 0x3F8000000000000, 0xFC00FF0000000000,
- 0x80000000FFFFFFFF, 0xFFFFFFFFFC000000, 0x7FFF00000003C000,
- 0x2000000000000000, 0xFC00FE000000FFFC, 0x20000000000000,
- 0xFF8000000000FF80, 0xFFE000010000C000, 0x8000000000040000,
- 0xFC0040004280, 0xFC00F80000000000, 0x412020000066010, 0xFFE0E0301F7EC660,
- 0xFFFFFFFF94000000, 0xFFFFFFFFFC00FF00, 0xC0000000000000,
- 0xFFFFFFFFC0000000, 0xFFFFE000FC00FFE0, 0xFF00000000000000,
- 0xFFFFFFFFFFFFFC00, 0xF00018000000, 0xF000000000000000, 0xFFFFFFFF,
- 0x7FF8000000000000, 0xFF00, 0xFFFFFFF800000030, 0xFE00000000000000,
- 0x80000000000200, 0xE0000000FFC0, 0xFF80010000030000, 0x4B80000000000480,
- 0x240FC00FF00, 0xFFFFFC00FE048000, 0xFE000000FFFFFFFF, 0xFFE0800000000000,
- 0xFFFFFFFFFFFFFFF0, 0xFFFF800000000000, 0xFFFFFFFFFFFFFF80,
- 0xFFFF3C0080000000, 0xFFC0C0000000FFFF, 0x1F0000040400FFC0,
- 0xFFFFFFFFFFFF0000, 0xFFFFFFFFF8000000, 0x800000000000FFE0,
- 0xFFFFFFFF00007FFF, 0xFFFFFFFCFFFFFFFF, 0xFFFC000000000000,
- 0xFFFFFFFF80000000, 0xFFFFFFFFFFFF, 0xE000F80000000000,
- 0xFFFFFFFF0C00FE00, 0xFFC0000000000000, 0x18000000000, 0x7F8000000000000,
- 0xFFFFFE0000000000, 0xFFFFFFFFFFFFFFC0, 0xFFF00000FFFFFFFF,
- 0xFE000000FF800000, 0x200000, 0x1400219B20000000, 0x10,
- 0x8400000020201840, 0x203A0, 0xC000000000, 0x3000, 0xFFFF000107FFF000,
- 0xFFFFF82406000080, 0xFFFFFFFFFF800060, 0xFFFFFFFF3C00F800,
- 0x1FFFFFFFFFFFF, 0xFFE0000000000000, 0xF508016900000010,
- 0xA10808695569157B, 0xF0000411F0000400, 0xFFFCFFFFFFFFFFFF,
- 0xF00000000000, 0x18000FFF00000, 0xFFC0000000010001, 0xE000,
- 0xFFFFE00000000000, 0x3FFFFFFFFF, 0xF00000000000FFF8, 0xFFFFFFC0FFFCFE00,
- 0xFC00E000FFE00000, 0xFFF0000000000000, 0xFFFFFFFFFE000000, 0xF000,
- 0xFC00FF00, 0xFFFFC0000000FF00, 0x800000000000F000, 0xB86000000000000,
- 0xFC00FFF800000000, 0xFFF8, 0xFFFFC000FFFFFFFF, 0xFFFFFFFFFF800000,
- 0xC0000000, 0xFFFC00000000, 0xFFFFFFFE00000000, 0xFFFF000000000000,
+ 0x80000000FFFFFFFF, 0xFFFCC40000000000, 0xFFFFFC000000, 0xFFFFFFFFFC00,
+ 0xFF800000FFFFF000, 0x7FC000000003C000, 0x2000000000000000,
+ 0xFC00FE000000FFF8, 0x20000000000000, 0xFF8000000000FF00,
+ 0xFFE0000100000000, 0x8000000000040000, 0xFC0040004280,
+ 0xFC00F80000000000, 0x412020000066010, 0xFFE0E0301F7EC660,
+ 0xFFFFFFFC10000000, 0xFFFFFFFFFC00FF00, 0xC0000000000000,
+ 0xFFFFFFFFC0000000, 0xFFFFE000FC00FFE0, 0xFC00000000000000,
+ 0xFFFFFFFFFFFFFC00, 0xF00018000000, 0xFFFFFFFFFFFFFF80,
+ 0xF000000000000000, 0xFFFFFFFF, 0x7FF8000000000000, 0x640000000900D80,
+ 0xFFFFFFFFFC00FF80, 0x300FFFFFFFF, 0xFFFFFFE003000000, 0xFF00,
+ 0xFFF800000000, 0xFE00000000000000, 0x80000000000200, 0xE0000000FFC0,
+ 0xFF80010000030000, 0x4B80000000000480, 0x240FC00FF00, 0xFFFFFC00FE048000,
+ 0xFE000000FFFFFFFF, 0xFFFEFFFFFFFFFFFF, 0x7FFC000000000000,
+ 0xFFFFFFFFFC000000, 0xFFE0800000000000, 0xFFFFFFFFFFFFFFF0, 0xFFFF,
+ 0xFFFF800000000000, 0x3C0080000000, 0x8000000000000000,
+ 0xFFC0C0000000FC00, 0x1F0000040400FFC0, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFF8000000, 0x7800, 0xFFFFFFFF00007F00, 0xFFFCFFE0FFFFFFFF,
+ 0xFF00000000000000, 0xFFFFFFFFFFC00000, 0x9010FFFFFFFFFFFF,
+ 0xFFFFFFF800000000, 0xFF0FFFF8FFFF, 0xE000F80000000000,
+ 0xFFFFFFFF0C00FE00, 0xC00000000000, 0xFF80, 0xFFC0000000000000,
+ 0x18000000000, 0x7F8000000000000, 0xFFFFF80000000000, 0xFFFFFFFFFFFFFFC0,
+ 0xFFF00000FFFFFFFF, 0xFE000000FF800000, 0x200000, 0x1400219B20000000,
+ 0x10, 0x8400000020201840, 0x203A0, 0xC000000000, 0x3000,
+ 0xFFFF000107FFF000, 0xFFFFFFFF80000000, 0xFFFFF82406000080,
+ 0xC000E00000000000, 0xFFFFFFFFFFFF3C00, 0xFFFF80000000FFFF,
+ 0x7C00000000000000, 0x80009080FFFFFFFF, 0xFFFFFFFFFF800060,
+ 0xFFFFFFFF3C00F000, 0x1FFFFFFFFFFFF, 0xFFE0000000000000,
+ 0xC000000000000001, 0xF508016900000010, 0xA10808695569157B,
+ 0xF0000411F0000400, 0xFFFCFFFFFFFFFFFF, 0xF00000000000, 0x18000FFF00000,
+ 0xFFC0000000010001, 0xFFFFC00000000000, 0x3FFFFFFFFF, 0xF00000000000FFF8,
+ 0xFFFFFFC0FFFCFE00, 0xE000E0001F000000, 0xFFF0000000000000,
+ 0xFFFEF000FE000000, 0xF000, 0xFC00FF00, 0xFFFCC0000000FF00,
+ 0xE0E0C000FFF00000, 0xF800E0000000FF80, 0xFF80FF00FC00FFC0, 0x80000,
+ 0xFC00FFFFFFFFF800, 0xC0000000, 0xFFFC00000000, 0xFFFFFFFE00000000,
+ 0xFFFFFFFFFFFFF800, 0xFFFF000000000000,
],
};
@@ -2055,79 +2166,84 @@ pub const OTHER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
],
tree2_level1: &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 3, 31, 32, 33, 3, 34, 34, 34, 34,
- 34, 35, 36, 37, 38, 39, 40, 3, 41, 34, 34, 34, 34, 34, 34, 34, 34, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 3, 3, 59, 60,
- 61, 62, 63, 64, 3, 65, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 66,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 67, 68,
- 69, 70, 3, 3, 3, 3, 3, 3, 3, 3, 71, 41, 72, 73, 74, 34, 75, 67, 3, 3, 3,
- 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 52, 3, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 76, 77, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 78, 79, 34, 34, 34, 34, 80, 81, 49, 62, 3, 3, 82, 83, 84, 47, 85,
- 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 3, 3, 96, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 97, 98, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34,
- 99, 34, 100, 101, 102, 103, 104, 34, 34, 34, 34, 105, 106, 107, 108, 3,
- 109, 34, 110, 3, 111, 112, 113,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 31, 35, 35, 35,
+ 35, 35, 36, 37, 38, 39, 40, 41, 31, 42, 35, 35, 35, 35, 35, 35, 35, 35,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 31,
+ 31, 60, 61, 62, 63, 64, 65, 31, 66, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 67, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 68, 69, 70, 71, 31, 31, 31, 31, 31, 31, 31, 31, 72, 42, 73, 74, 75,
+ 35, 76, 68, 31, 31, 31, 31, 31, 31, 31, 31, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 31, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 77, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 78, 79, 35, 35, 35, 35, 80,
+ 81, 50, 63, 31, 31, 82, 83, 84, 48, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 31, 31, 96, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 97,
+ 98, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 35, 35, 35, 35, 35, 99, 35, 100, 101, 102,
+ 103, 104, 35, 35, 35, 35, 105, 106, 107, 108, 31, 109, 35, 110, 31, 111,
+ 112, 113,
],
tree2_level2: &[
- 0x3FFFFF, 0x7FF01FFFFFF, 0x3FDFFFFF00000000, 0, 0x23FFFFFFFFFFFFF0,
- 0xFFFC0003FF010000, 0x23C5FDFFFFF99FE1, 0x10030003B0004000,
- 0x36DFDFFFFF987E0, 0x1C00005E000000, 0x23EDFDFFFFFBBFE0,
- 0x200000300010000, 0x23EDFDFFFFF99FE0, 0x20003B0000000, 0x3FFC718D63DC7E8,
- 0x10000, 0x23FFFDFFFFFDDFE0, 0x307000000, 0x23EFFDFFFFFDDFE1,
- 0x6000340000000, 0x27FFFFFFFFFDDFE0, 0xFC00000380704000,
- 0x2FFBFFFFFC7FFFE0, 0x7F, 0xDFFFFFFFFFFFE, 0x3F, 0x200DECAEFEF02596,
- 0xF000001F, 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0x800007FFFFFFFFFF,
- 0xFFE1C0623C3F0000, 0x4003, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF,
- 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF,
- 0xFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE,
- 0x1FE07FFFFFFFFFF, 0x3FFFF0003DFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF,
- 0x10000000, 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFF7, 0xFFFF05FFFFFFFF9F,
+ 0x3FFFFF, 0xFFFF07FF01FFFFFF, 0xFFFFFFFF00007EFF, 0x1FF,
+ 0x23FFFFFFFFFFFFF0, 0xFFFC0003FF010000, 0x23C5FDFFFFF99FE1,
+ 0x10030003B0004000, 0x36DFDFFFFF987E0, 0x1C00005E000000,
+ 0x23EDFDFFFFFBBFE0, 0x200000300010000, 0x23EDFDFFFFF99FE0,
+ 0x20003B0000000, 0x3FFC718D63DC7E8, 0x10000, 0x23FFFDFFFFFDDFE0,
+ 0x327000000, 0x23EFFDFFFFFDDFE1, 0x6000360000000, 0x27FFFFFFFFFDDFF0,
+ 0xFC00000380704000, 0x2FFBFFFFFC7FFFE0, 0x7F, 0xDFFFFFFFFFFFE, 0x3F,
+ 0x200DFFAFFFFFF7D6, 0xF000001F, 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0,
+ 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000, 0x4003, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
+ 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF, 0xFFFF, 0xFFFFFFFFFFFFFFFE,
+ 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE, 0x1FE07FFFFFFFFFF,
+ 0x3FFFF8003FFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF, 0x10000000,
+ 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFF7, 0xFFFF05FFFFFFFF9F,
0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF, 0x3FF,
- 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0xFFFFFFFFFFFE0, 0xFE0, 0xFC00C001FFFFFFF8,
- 0x3FFFFFFFFF, 0xFFFFFFFFF, 0xFFFFFFFC00E000, 0x63DE0000000000,
+ 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0xFFFFFFFFFFFE0, 0x1FE0, 0xFC00C001FFFFFFF8,
+ 0x3FFFFFFFFF, 0xFFFFFFFFF, 0xFFFFFFFC00E000, 0x46FDE0000000000,
0x1E0000000000000, 0xFFFF000000000000, 0xFFFFFFFFFF, 0x7F7F7F7F007FFFFF,
0x7F7F7F7F, 0x1000000000000040, 0xFFFFFFFE807FFFFF, 0x87FFFFFFFFFFFFFF,
- 0xFFFEFFFFFFFFFFE0, 0x7FFFFFF00007FFF, 0xFFFFFFFFFFFF, 0xFFFFFFFFFFDFFFFF,
- 0x1FFF, 0xFFFFFFFFFF0000, 0xC00FFFF0FFF, 0x400000000000, 0x8000,
+ 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFF00007FFF, 0xFFFFFFFFFFDFFFFF, 0x1FFF,
+ 0xFFFFFFFFFF0000, 0xC00FFFF0FFF, 0x400000000000, 0x8000,
0xF880000000000000, 0x7FFFFF7BB, 0xFFFFFFFFFFFFC, 0x68FC000000000000,
0xFFFF003FFFFFFC00, 0x1FFFFFFF0000007F, 0x7FFFFFFFFFFF0,
0x7C00FF9F00000000, 0x1FFFFFFFFFF, 0xC47EFFFF00000FF7, 0x3E62FFFFFFFFFFFF,
@@ -2139,8 +2255,8 @@ pub const OTHER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xFFFEFFC000000000, 0x7FFFFFFF3FFFFFFF, 0x1CFCFCFC,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 5, 10, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 11, 12, 13, 7, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 12, 13, 14, 7, 15, 16, 7, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -2154,47 +2270,52 @@ pub const OTHER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree3_level2: &[
0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 4, 11, 12, 4, 13, 14, 4,
4, 2, 2, 2, 2, 15, 16, 4, 4, 17, 18, 19, 20, 21, 4, 22, 4, 23, 24, 25, 26,
- 27, 28, 29, 4, 2, 30, 4, 4, 14, 4, 4, 4, 4, 4, 4, 4, 31, 32, 4, 4, 33, 4,
- 34, 35, 36, 37, 38, 39, 40, 4, 41, 19, 42, 43, 4, 4, 44, 45, 46, 47, 4, 4,
- 48, 49, 46, 50, 51, 4, 52, 4, 4, 4, 53, 4, 4, 54, 4, 4, 4, 4, 55, 56, 57,
- 58, 4, 4, 4, 4, 59, 60, 61, 4, 62, 63, 64, 4, 4, 4, 4, 65, 4, 4, 4, 4, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 66, 4, 4, 4, 2, 2, 2, 67, 4, 4, 4,
+ 27, 28, 29, 4, 2, 30, 4, 4, 14, 4, 4, 4, 4, 4, 31, 4, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 4, 45, 19, 46, 47, 4, 4, 48, 49, 50, 51,
+ 4, 4, 52, 53, 50, 54, 55, 4, 56, 57, 4, 4, 58, 4, 4, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 4, 4, 4, 4, 68, 69, 70, 4, 71, 72, 73, 4, 4, 4, 4, 74, 4,
+ 4, 75, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76, 4, 4, 4, 2, 2, 2,
+ 77, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11, 78, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 48, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 68, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 58,
- 19, 4, 69, 46, 70, 61, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 71, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
+ 2, 2, 2, 2, 67, 79, 80, 81, 50, 82, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 2, 83, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 2, 2, 2, 2, 19, 74, 2, 2, 2, 2, 2, 75, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 84, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 30,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 86, 87, 2, 2, 2, 2, 2, 88, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 2, 76, 77, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 89, 90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 2, 2, 2, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 79, 80, 81, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 82, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 91, 4, 4, 4, 4, 4, 4, 4, 92, 93, 4, 4,
+ 4, 4, 81, 58, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 94,
+ 2, 2, 2, 95, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 96, 97, 98, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 44, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 67, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 100, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 83, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
],
tree3_level3: &[
0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
@@ -2204,20 +2325,23 @@ pub const OTHER_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000,
0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
0x1FFFFFFF00000000, 0x1FFFFFFF, 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF,
- 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0xFFFF00801FFFFFFF, 0x3F,
- 0xFFFFFFFFFFFFF8, 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8,
- 0x47FFFFFFFF0010, 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF,
- 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x1FFFFFFFFFFFFF,
- 0x780, 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF, 0xF000000, 0x10,
- 0x7FFFFFFFFFF, 0x7FFFFFF, 0xFFFFFFFFFFF, 0x8000000000000000,
- 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000, 0x200003CF, 0x1FFFFFFFFFFFFFF,
- 0x7FFFFFFFFDFF, 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F,
- 0xFFFFFDBF00000040, 0x10003FF, 0x7FFFF00000000, 0x3FFFFFF, 0xF, 0x7F,
- 0x3FFFFFFF0000, 0xE0FFFFF800000000, 0x1001F, 0x3FFFFFFFFFFFF,
- 0x7FFFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFFFFFFFFFFFF,
- 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0x1F, 0xAF7FE96FFFFFFEF,
- 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x7FFFFF, 0xFFFF0003FFFFFFFF,
- 0x1FFFFFFFF,
+ 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x303FFFFFFFFFF, 0xFFFF00801FFFFFFF,
+ 0xFFFF00000000003F, 0xFFFF000000000003, 0x7FFFFF0000001F,
+ 0xFFFFFFFFFFFFF8, 0x26000000000000, 0xFFFFFFFFFFF8, 0x1FFFFFF0000,
+ 0x7FFFFFFFF8, 0x47FFFFFFFF0090, 0x7FFFFFFFFFFF8, 0x1400001E,
+ 0xFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000,
+ 0x1FFFFFFFFFFFFF, 0x380000780, 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF,
+ 0xF000000, 0x10, 0x10007FFFFFFFFFF, 0x7FFFFFF, 0x7F, 0xFFFFFFFFFFF,
+ 0x8000000000000000, 0x8000FFFFFF6FF27F, 0x2, 0xFFFFFCFF00000000,
+ 0xA0001FFFF, 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000, 0xFFFF0000200003FF,
+ 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF, 0xFFFC000000000001, 0xFFFF,
+ 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040, 0x10003FF, 0x7FFFF00000000,
+ 0x1000000000000, 0x3FFFFFF, 0xF, 0x1FFFFFFFFFFFF, 0xFFFF00007FFFFFFF,
+ 0x7FFFFFFFFFFFFFFF, 0x3FFFFFFF0000, 0xE0FFFFF800000000, 0x107FF,
+ 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x7FFFFFFFF, 0xFFFF00F000070000,
+ 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0x400, 0x1FFFFFFFFFFF,
+ 0x4000, 0x7FFF6F7F00000000, 0x1F, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84,
+ 0xFFFFBEE0FFFFBFF, 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x7FF,
],
};
@@ -2292,33 +2416,34 @@ pub const OTHER_NUMBER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree3_level2: &[
0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 0, 10, 11, 0, 12, 13, 14, 0, 15, 16,
- 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 18, 0, 0, 19, 20, 0, 0, 0, 21, 0, 0, 0, 0,
- 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0,
- 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 18, 0, 0, 19, 20, 0, 21, 0, 22, 0, 0, 0, 0,
+ 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0,
+ 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 28, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33, 34, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0xFFFFFFFFFFF80, 0x1E0000000000000, 0xC00, 0xFFFFFFE00000000,
0xF00000000, 0xFE000000FF000000, 0xFF8000000000, 0xF800000000000000,
0xFC00000, 0x3000000000000000, 0xFFFFFFFFFFFCFFFF, 0x60000000000001FF,
0xE0000000, 0xF80000000000, 0xFF000000FF000000, 0xFE0000000000,
- 0xFC00000000000000, 0x7FFFFFFF00000000, 0x7FE0000000, 0x1E0000,
+ 0xFC00000000000000, 0x7FFFFFFF00000000, 0x7FE0000000, 0x1E0000, 0xFE0,
0x3FFFFC0000, 0x1FFFFE00000000, 0xC00000000000000, 0x7FC0000000000,
- 0x1FFFFC000000, 0x3F8000000, 0x7FFFFF, 0xFFFFF00000000, 0x1FFFFFF00000000,
- 0xFF80, 0xFFFE000000000000, 0x1EEFFFFFFFFFFF, 0x1FFF,
+ 0x1FFFFC000000, 0x1FFFFF, 0x3F8000000, 0x7FFFFF, 0xFFFFF00000000,
+ 0x1FFFFFF00000000, 0xFF80, 0xFFFE000000000000, 0x1EEFFFFFFFFFFF,
+ 0x3FFFBFFFFFFFFFFE, 0x1FFF,
],
};
@@ -2326,17 +2451,17 @@ pub const OTHER_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
tree1_level1: &[
0x8C00D4EE00000000, 0x10000001, 0x80C0008200000000, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0x4000000000000000, 0x80, 0, 0, 0, 0, 0, 0, 0xFC000000, 0x200,
- 0x18000000000049, 0xC8003600, 0x3C0000000000, 0, 0x100000, 0x3FFF, 0, 0,
+ 0x18000000000049, 0xE8003600, 0x3C0000000000, 0, 0x100000, 0x3FFF, 0, 0,
0x380000000000000,
],
tree2_level1: &[
- 0, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 8, 2,
- 9, 2, 2, 10, 2, 11, 12, 2, 13, 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 17, 18, 2, 2, 19, 20, 2, 2, 2, 2, 21, 2,
- 2, 22, 2, 23, 2, 2, 24, 2, 25, 26, 27, 2, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 2, 2, 2, 2, 7, 8, 2, 2, 2, 2, 9, 2,
+ 10, 2, 2, 11, 2, 12, 13, 2, 14, 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 2, 18, 19, 2, 2, 20, 21, 2, 2, 2, 2, 22,
+ 2, 2, 23, 2, 24, 2, 2, 25, 2, 26, 27, 28, 2, 29, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 30, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 31, 2, 6, 2, 2, 32, 33, 2, 2, 2, 2, 2, 2, 34, 2, 2, 14, 2,
+ 2, 2, 2, 2, 2, 2, 32, 2, 6, 2, 2, 33, 34, 2, 2, 2, 2, 2, 2, 35, 2, 2, 15,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2355,8 +2480,8 @@ pub const OTHER_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 27, 2, 2, 2, 2, 35, 36, 2, 37, 2, 2,
- 2, 2, 2, 38, 2, 39, 40, 41, 2, 42, 2, 43, 2, 44, 2, 2, 2, 45, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 36, 37, 2, 38, 2,
+ 2, 2, 2, 2, 39, 2, 40, 41, 42, 2, 43, 2, 44, 2, 45, 2, 2, 2, 46, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2369,21 +2494,22 @@ pub const OTHER_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 46, 47, 2, 2, 48, 49, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 47, 48, 2, 2, 49, 50, 2, 2,
],
tree2_level2: &[
0x7FFF000000000000, 0x40000000, 0, 0x1003000000000, 0x2000000000000000,
- 0x40000000000000, 0x1000000000000, 0x10, 0x10000000000000, 0xC008000,
- 0x17FFF0, 0x20, 0x61F0000, 0xFC00, 0x800000000000000, 0x1FF00000000,
- 0x600000000000, 0x380000000000, 0x60000000000000, 0x7700000, 0x7BF, 0x30,
- 0xC0000000, 0x3F7F00000000, 0x1FC000000, 0xF000000000000000,
- 0xF800000000000000, 0xC000000000000000, 0x800FF, 0x79FF00FF00C00000,
- 0x7FEBFF8E, 0xDE00000000000000, 0xF3FF7C00CB7FC9C3, 0x7FFA,
- 0x200000000000000E, 0xE000, 0x4008000000000000, 0xFC000000000000,
- 0xF0000000000000, 0x170000000000C000, 0xC00000000000, 0x80000000,
- 0xC0003FFE, 0xF0000000, 0x30000C0000000, 0x80000000000, 0x10000027F0000,
- 0xD0380F71E60, 0x100000018C00D4EE, 0x3200000000,
+ 0x40000000000000, 0x1000000000000, 0x80000000000000, 0x10,
+ 0x10000000000000, 0xC008000, 0x17FFF0, 0x20, 0x61F0000, 0xFC00,
+ 0x800000000000000, 0x1FF00000000, 0x400000000000, 0x380000000000,
+ 0x60000000000000, 0x7700000, 0x7BF, 0x30, 0xC0000000, 0x3F7F00000000,
+ 0x60000001FC000000, 0xF000000000000000, 0xF800000000000000,
+ 0xC000000000000000, 0x800FF, 0x79FF00FF00C00000, 0x7FEBFF8E,
+ 0xDE00000000000000, 0xF3FF7C00CB7FC9C3, 0x1CFFFA, 0x200000000000000E,
+ 0xE000, 0x4008000000000000, 0xFC000000000000, 0xF0000000000000,
+ 0x170000000000C000, 0xC00000000000, 0x80000000, 0xC0003FFE, 0xF0000000,
+ 0x30000C0000000, 0x80000000000, 0x10000027F0000, 0xD0380F71E60,
+ 0x100000018C00D4EE, 0x3200000000,
],
tree3_level1: &[
0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 5, 3, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -2401,36 +2527,36 @@ pub const OTHER_PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
tree3_level2: &[
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 6, 0, 0, 0, 0, 7, 0, 8, 9, 0, 10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 13, 14, 0, 15, 0, 16,
- 17, 0, 18, 0, 0, 0, 0, 0, 0, 19, 0, 20, 0, 0, 0, 21, 0, 22, 0, 0, 23, 0,
- 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 0, 0, 13, 14, 15, 0, 16, 0,
+ 17, 18, 0, 19, 0, 0, 0, 0, 0, 0, 20, 0, 21, 0, 0, 0, 22, 0, 23, 24, 0, 25,
+ 0, 0, 0, 26, 0, 0, 0, 0, 27, 0, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 40, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 31, 0, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0x7, 0x80000000, 0x10000, 0x800000000000, 0x800000, 0x8000000080000000,
0x8000000001FF0000, 0x7F000000000000, 0xFE00000000000000, 0x1E000000,
- 0x3E00000, 0x3F80, 0xD800000000000000, 0x3, 0x3000000000000F, 0xE80021E0,
- 0x3F00000000000000, 0x20000000000, 0x2800F800, 0x40, 0xFFFFFE,
- 0x1FFF0000000E, 0x7000000000000000, 0x800000000000000, 0x8000000000000000,
- 0x7F, 0x7DC000000, 0x300000000003E, 0x180000000000000, 0x1F000000000000,
- 0xC00000000000, 0x20000000000000, 0xF80000000000000, 0x10, 0x7800000,
- 0xF80, 0xC0000000,
+ 0x3E00000, 0x3C0, 0x3F80, 0xD800000000000000, 0x3, 0x3000000000000F,
+ 0xE80021E0, 0x3F00000000000000, 0x20000000000, 0x2C00F800, 0x40, 0xFFFFFE,
+ 0x1FFF0000000E, 0x200000000000000, 0x7000000000000000, 0x800000000000000,
+ 0x70, 0x400000000, 0x8000000000000000, 0x7F, 0x7DC000000, 0x300000000003E,
+ 0x180000000000000, 0x1F000000000000, 0x6000000000000, 0xC00000000000,
+ 0x20000000000000, 0xF80000000000000, 0x10, 0x7800000, 0xF80, 0xC0000000,
],
};
@@ -2443,17 +2569,17 @@ pub const OTHER_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree2_level1: &[
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 3, 0, 4, 0, 0, 0, 5, 0, 0, 0,
0, 0, 0, 6, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 12, 0,
- 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 0, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 26, 27, 28, 26, 29, 26, 26, 26, 30, 31, 0, 26, 26, 26, 26, 0, 0, 0, 0, 0,
- 0, 0, 0, 32, 33, 34, 35, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 37, 38, 26, 26,
- 26, 39, 40, 0, 0, 0, 0, 0, 41, 42, 43, 44, 45, 46, 26, 26, 26, 26, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 13, 0,
+ 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 15, 16, 17, 18, 0, 0, 0, 0, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 27, 28, 29, 27, 30, 27, 27, 27, 31, 32, 0, 27, 27, 27, 27, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 34, 35, 27, 0, 0, 0, 36, 0, 0, 0, 0, 0, 37, 38, 39, 27, 27,
+ 27, 40, 41, 0, 0, 0, 0, 0, 42, 43, 44, 45, 46, 27, 27, 27, 27, 27, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2481,26 +2607,26 @@ pub const OTHER_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 52,
+ 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 52, 0, 0, 0, 0, 0, 0, 0, 53,
],
tree2_level2: &[
0, 0x400000000000000, 0x1000000000000, 0x5F8000000000000,
0x8000000000000000, 0x200000000008000, 0x1500000FCE8000E,
- 0xC000000000000000, 0x1E0DFBF, 0xC0000000, 0x3FF0000, 0x1,
+ 0xC000000000000000, 0x1E0DFBF, 0xC0000000, 0x3FF0000, 0x200000000000, 0x1,
0xFFFFFFFFC0000000, 0x1FF007FE00000000, 0xC0042AFC0D0037B, 0xB400,
0xFFFFBFB6F3E00C00, 0xFFFFFFFEB3FFF, 0xFFFFF9FCFFFFF0FF,
0xEFFFFFFFFFFFFFFF, 0xFFF0000007FFFFFF, 0xFFFFFFFC0FFFFFFF, 0x7FFFFFFFFF,
0x7FF, 0xFFFFFFFFF0000000, 0x3FFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
0xFF7FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFD, 0xFFFF7FFFFFFFFFFF, 0xFFFFFFFFFF,
0xFFFFFFFFFFF00000, 0xFFFFFFFFFFFF, 0xFFCFFFFFFFFFE060,
- 0xFFFFFFFFFF3FFFFF, 0x7FFFFFFFFFFFFDFF, 0x7E000000000, 0xFFFFFFFFFBFFFFFF,
+ 0xFFFFFFFFFFBFFFFF, 0x7E000000000, 0x30000, 0xFFFFFFFFFBFFFFFF,
0xFFFFFFFFFFFFF, 0xFFF0000003FFFFF, 0xC0C00001000C0010, 0xFFC30000,
0xFFFFFFFFF, 0xFFFFFC007FFFFFFF, 0xFFFFFFFF000100FF, 0x1FFFFFFFFFC00,
- 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0x7F, 0x2C00F0000000000,
- 0x380000000000000, 0x2000000000000000, 0x3000611000000000,
+ 0xFFFFFFFFFFFF0000, 0x7F, 0x2C00F0000000000, 0x380000000000000, 0xFFFF,
+ 0xE000000000008000, 0x3000611000000000,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 5, 6, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2518,36 +2644,40 @@ pub const OTHER_SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11,
- 12, 13, 14, 15, 16, 11, 17, 0, 0, 11, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 19, 20, 21, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 13, 13, 13, 15, 16, 17, 18, 19, 13,
+ 20, 0, 0, 13, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 23, 11, 24, 25, 26, 23, 27, 28, 29, 30, 0, 0, 11,
- 11, 11, 31, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 32, 11, 33, 11,
- 34, 35, 36, 37, 0, 38, 39, 40, 41, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 13, 29, 30, 31, 13, 32, 33, 34, 35, 0, 0, 13, 13, 13, 36, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 37, 13, 38, 13, 39, 40, 41, 42, 0,
+ 13, 13, 13, 13, 13, 43, 44, 45, 13, 13, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFF80000000000000, 0xFE00000000000000, 0x10FFF73FF,
+ 0, 0xFF80000000000000, 0xFE00000000000000, 0x11FFF73FF,
0x1FFFFFFFFFFF0000, 0x180000000000000, 0x100, 0x8000000000000000,
- 0xF000000000000000, 0x20, 0x10000000, 0xFFFFFFFFFFFFFFFF,
- 0x3FFFFFFFFFFFFF, 0xFFFFFE7FFFFFFFFF, 0x1C1FFFFFFFFF, 0xFFFFC3FFFFFFF018,
- 0x1FFFFFFFFFF, 0x23, 0x7FFFFF, 0x780000000000000, 0xFFDFE00000000000,
- 0x6F, 0x100000000000, 0xFFFF0FFFFFFFFFFF, 0xFFFE7FFF000FFFFF,
- 0x3FFFFFFFFEFFFE, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFF, 0xFFFFFFC000000000,
- 0xFFFFFFFFFFF0007, 0x3F000301FF, 0x7FFFFFFFFFFFFFF, 0x3FF1FFF001FFFFF,
- 0xFFFFFFFFFFFFF, 0x1FFFFFF, 0xFFFFFFFFFFFF0FFF, 0xFFFFFFFF03FF00FF,
- 0x3FFFFFFF00FF, 0x7FFFFFFFFFFF0FFF, 0xF479FFFFFFFFFFFF, 0x3FF0007FFFFFFFF,
- 0xFFFFFFFFFFFF0007, 0x3FFF00000000,
+ 0x3FFFE1FE00000, 0xF000000000000000, 0x20, 0x10000000, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFFFFFFFFF, 0xF, 0x3FFFFFFFFFFFFF, 0xFFFFFE7FFFFFFFFF,
+ 0x1C1FFFFFFFFF, 0xFFFFC3FFFFFFF018, 0x7FFFFFFFFFF, 0x23, 0x7FFFFF,
+ 0x780000000000000, 0xFFDFE00000000000, 0x6F, 0x8000, 0x100000000000,
+ 0x400000000000, 0xFFFF0FFFFFFFFFFF, 0xFFFE7FFF000FFFFF, 0x3FFFFFFFFEFFFE,
+ 0xFFFFFFFFFFFFE000, 0x3FFFFFFFFFFF, 0xFFFFFFC000000000, 0xFFFFFFFFFFF0007,
+ 0x3F000301FF, 0x7FFFFFFFFFFFFFF, 0x1FFF1FFFE0FFFFFF, 0xFFFFFFFFFFFFF,
+ 0x10FFF01FFFFFF, 0xFFFFFFFFFFFF0FFF, 0xFFFFFFFF03FF00FF, 0x33FFFFFFF00FF,
+ 0x1F1F3FFF000FFFFF, 0x7FF1FFFFFFF007F, 0x7F00FF03FF003F,
+ 0xFFFFFFFFFFF7FFFF, 0x7FF,
],
};
@@ -2691,18 +2821,18 @@ pub const PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
0x8C00F7EE00000000, 0x28000000B8000001, 0x88C0088200000000, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0x4000000000000000, 0x80, 0, 0, 0, 0, 0, 0, 0xFC000000,
- 0x4000000000000600, 0x18000000000049, 0xC8003600, 0x3C0000000000, 0,
+ 0x4000000000000600, 0x18000000000049, 0xE8003600, 0x3C0000000000, 0,
0x100000, 0x3FFF, 0, 0, 0x380000000000000,
],
tree2_level1: &[
- 0, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 8, 2,
- 9, 2, 2, 10, 2, 11, 12, 2, 13, 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2,
- 16, 2, 2, 2, 2, 2, 2, 2, 2, 17, 18, 19, 20, 2, 2, 21, 22, 2, 2, 2, 2, 23,
- 2, 2, 24, 2, 25, 2, 2, 26, 2, 27, 28, 29, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 31, 32, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 35, 2, 36, 2, 2, 2, 2, 2, 2, 37, 38, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 39, 2, 6, 2, 2, 40, 41, 2, 2, 2, 2, 2, 2, 42,
- 2, 43, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 2, 2, 2, 2, 7, 8, 2, 2, 2, 2, 9, 2,
+ 10, 2, 2, 11, 2, 12, 13, 2, 14, 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2,
+ 2, 17, 2, 2, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 2, 2, 22, 23, 2, 2, 2, 2,
+ 24, 2, 2, 25, 2, 26, 2, 2, 27, 2, 28, 29, 30, 2, 31, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 32, 33, 34, 2, 2, 2, 2, 2, 2, 2, 2, 2, 35, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 2, 37, 2, 2, 2, 2, 2, 2, 38, 39, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 40, 2, 6, 2, 2, 41, 42, 2, 2, 2, 2, 2, 2,
+ 43, 2, 44, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2720,8 +2850,9 @@ pub const PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 29, 2, 2, 2, 2, 44, 45,
- 2, 46, 2, 2, 2, 2, 2, 47, 2, 48, 49, 50, 2, 51, 2, 52, 2, 53, 2, 2, 2, 54,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 45,
+ 46, 2, 47, 2, 2, 2, 2, 2, 48, 2, 49, 50, 51, 2, 52, 2, 53, 2, 54, 2, 2, 2,
+ 55, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2734,23 +2865,23 @@ pub const PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 29, 2, 2, 2, 55, 56, 2, 2, 57, 58, 2, 2,
+ 2, 30, 2, 2, 2, 56, 57, 2, 2, 58, 59, 2, 2,
],
tree2_level2: &[
0x7FFF000000000000, 0x40000000, 0, 0x1003000000000, 0x2000000000000000,
- 0x40000000000000, 0x1000000000000, 0x10, 0x10000000000000, 0xC008000,
- 0x3C0000000017FFF0, 0x20, 0x61F0000, 0xFC00, 0x800000000000000,
- 0x1FF00000000, 0x1, 0x600000000000, 0x18000000, 0x380000000000,
- 0x60000000000000, 0x7700000, 0x7FF, 0x30, 0xC0000000, 0x3F7F00000000,
- 0x1FC000000, 0xF000000000000000, 0xF800000000000000, 0xC000000000000000,
- 0x800FF, 0xFFFF00FFFFFF0000, 0x600000007FFBFFEF, 0x6000, 0x60000000F00,
- 0x3FFF0000000000, 0xFFC000000060, 0x1FFFFF8, 0x300000000F000000,
- 0xDE00000000000000, 0xFFFF7FFFFFFFFFFF, 0x7FFF, 0x20010000FFF3FF0E,
- 0x100000000, 0xE000, 0x4008000000000000, 0xFC000000000000,
- 0xF0000000000000, 0x170000000000C000, 0xC00000000000, 0x80000000,
- 0xC0003FFE, 0xF0000000, 0x30000C0000000, 0x80000000000,
- 0xFFFF000003FF0000, 0xD0BFFF7FFFF, 0xB80000018C00F7EE, 0x3FA8000000,
+ 0x40000000000000, 0x1000000000000, 0x80000000000000, 0x10,
+ 0x10000000000000, 0xC008000, 0x3C0000000017FFF0, 0x20, 0x61F0000, 0xFC00,
+ 0x800000000000000, 0x1FF00000000, 0x1, 0x400000000000, 0x18000000,
+ 0x380000000000, 0x60000000000000, 0x7700000, 0x7FF, 0x30, 0xC0000000,
+ 0x3F7F00000000, 0x60000001FC000000, 0xF000000000000000,
+ 0xF800000000000000, 0xC000000000000000, 0x800FF, 0xFFFF00FFFFFF0000,
+ 0x600000007FFBFFEF, 0x6000, 0x60000000F00, 0x3FFF0000000000,
+ 0xFFC000000060, 0x1FFFFF8, 0x300000000F000000, 0xDE00000000000000,
+ 0xFFFF7FFFFFFFFFFF, 0x3FFCFFFF, 0x20010000FFF3FF0E, 0x100000000, 0xE000,
+ 0x4008000000000000, 0xFC000000000000, 0xF0000000000000,
+ 0x170000000000C000, 0xC00000000000, 0x80000000, 0xC0003FFE, 0xF0000000,
+ 0x30000C0000000, 0x80000000000, 0xFFFF000003FF0000, 0xD0BFFF7FFFF,
+ 0xB80000018C00F7EE, 0x3FA8000000,
],
tree3_level1: &[
0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 5, 3, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -2768,36 +2899,37 @@ pub const PUNCTUATION: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree3_level2: &[
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 6, 0, 0, 0, 0, 7, 0, 8, 9, 0, 10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 13, 14, 0, 15, 0, 16,
- 17, 0, 18, 0, 0, 0, 0, 0, 0, 19, 0, 20, 0, 0, 0, 21, 0, 22, 0, 0, 23, 0,
- 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 13, 0, 0, 14, 15, 16, 0, 17, 0,
+ 18, 19, 0, 20, 0, 0, 0, 0, 0, 0, 21, 0, 22, 0, 0, 0, 23, 0, 24, 25, 0, 26,
+ 0, 0, 0, 27, 0, 0, 0, 0, 28, 0, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 31, 0, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
],
tree3_level3: &[
0, 0x7, 0x80000000, 0x10000, 0x800000000000, 0x800000, 0x8000000080000000,
0x8000000001FF0000, 0x7F000000000000, 0xFE00000000000000, 0x1E000000,
- 0x3E00000, 0x3F80, 0xD800000000000000, 0x3, 0x3000000000000F, 0xE80021E0,
- 0x3F00000000000000, 0x20000000000, 0x2800F800, 0x40, 0xFFFFFE,
- 0x1FFF0000000E, 0x7000000000000000, 0x800000000000000, 0x8000000000000000,
- 0x7F, 0x7DC000000, 0x300000000003E, 0x180000000000000, 0x1F000000000000,
- 0xC00000000000, 0x20000000000000, 0xF80000000000000, 0x10, 0x7800000,
- 0xF80, 0xC0000000,
+ 0x200000000000, 0x3E00000, 0x3C0, 0x3F80, 0xD800000000000000, 0x3,
+ 0x3000000000000F, 0xE80021E0, 0x3F00000000000000, 0x20000000000,
+ 0x2C00F800, 0x40, 0xFFFFFE, 0x1FFF0000000E, 0x200000000000000,
+ 0x7000000000000000, 0x800000000000000, 0x70, 0x400000000,
+ 0x8000000000000000, 0x7F, 0x7DC000000, 0x300000000003E, 0x180000000000000,
+ 0x1F000000000000, 0x6000000000000, 0xC00000000000, 0x20000000000000,
+ 0xF80000000000000, 0x10, 0x7800000, 0xF80, 0xC0000000,
],
};
@@ -2925,11 +3057,11 @@ pub const SPACING_MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree2_level1: &[
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 5, 7, 8, 4, 9, 10, 11, 12, 8, 13, 3, 14, 15,
16, 0, 0, 0, 0, 9, 17, 0, 0, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 0, 0, 0, 0, 23, 0,
- 0, 0, 24, 25, 0, 0, 26, 27, 28, 29, 30, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 22, 23, 0, 0, 0, 0, 24,
+ 0, 0, 0, 25, 26, 0, 0, 27, 28, 29, 30, 31, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2948,8 +3080,8 @@ pub const SPACING_MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 34, 35, 0, 36, 37, 6, 38, 39, 0, 40, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 34, 0, 35, 36, 0, 37, 38, 6, 39, 40, 0, 41, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2970,10 +3102,10 @@ pub const SPACING_MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xC000000000000008, 0x1, 0x1A01, 0x400000000000000C, 0xC000000000000000,
0x801DC6, 0xE, 0x1E, 0x600D9F, 0x801DC1, 0xC, 0xC0000FF038000,
0x8000000000000000, 0x1902180000000000, 0x3F9C00C00000, 0x1C009F98,
- 0xC040000000000000, 0x1BF, 0x1FB0E7800000000, 0x6000000, 0x7E01A00A00000,
- 0xE820000000000010, 0x1B, 0x4C200000004, 0xC5C8000000000,
- 0x300FF000000000, 0x8C000200000000, 0xC00000000000, 0x9800000000,
- 0xFFF0000000000003, 0xF, 0xC0000, 0xEC30000000000008, 0x19800000000000,
+ 0x10000000200000, 0xC040000000000000, 0x1BF, 0x1FB0E7800000000, 0x6000000,
+ 0x7E01A00A00000, 0xE820000000000010, 0x1B, 0x4C200000004, 0xC5C8000000000,
+ 0x300FF000000000, 0x80000200000000, 0xC00000000000, 0x9800000000,
+ 0xFFF0000000000003, 0xF, 0xC0000, 0xCC30000000000008, 0x19800000000000,
0x2800000000002000, 0x20C80000000000, 0x16D800000000,
],
tree3_level1: &[
@@ -2994,22 +3126,22 @@ pub const SPACING_MARK: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 4, 5, 6, 7, 0, 0,
8, 9, 10, 0, 0, 11, 12, 13, 14, 0, 0, 15, 0, 16, 0, 17, 0, 18, 0, 0, 0,
- 19, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 0, 0, 0, 0, 0, 23, 0, 24, 0, 0, 0,
- 25, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 0, 0, 0, 20, 1, 0, 21, 22, 23, 24, 0, 0, 0, 0, 0, 25, 0, 26, 0, 0, 0,
+ 27, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0,
- 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30,
+ 31, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0x5, 0x187000000000004, 0x100000000000, 0x60, 0x8038000000000004, 0x1,
- 0x2C700000000000, 0x700000000, 0xC00000000000000C, 0xC0080399E,
+ 0, 0x5, 0x187000000000004, 0x100000000000, 0x60, 0x8038000000000004,
+ 0x4001, 0x2C700000000000, 0x700000000, 0xC00000000000000C, 0xC0080399E,
0xE0000000000000, 0x23, 0x7A07000000000000, 0x2, 0x4F03800000000000,
0x5807000000000000, 0x40D00000000000, 0x4300000000, 0x100700000000000,
- 0x200000000000000, 0x1800000, 0x800000, 0x4000800000000000,
- 0x12020000000000, 0x587C00, 0x60000000000000, 0x7FFFFFFFFFFE0000,
- 0x7E06000000000,
+ 0x21BF000000000000, 0x10F00E0000, 0x200000000000000, 0x1800000, 0x800000,
+ 0x4000800000000000, 0x12020000000000, 0x587C00, 0x60000000000000,
+ 0xFFFFFFFFFFFE0000, 0xFF, 0x3000000000000, 0x7E06000000000,
],
};
@@ -3079,19 +3211,19 @@ pub const SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0xC9C0, 0, 0, 0x6000020040000000, 0, 0, 0, 0xC040000000000000,
],
tree2_level1: &[
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 5,
- 0, 0, 0, 7, 0, 8, 9, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 13, 0, 14, 0,
- 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 0,
- 18, 19, 0, 20, 21, 22, 23, 23, 23, 23, 23, 24, 23, 23, 23, 25, 26, 27, 28,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 29, 30, 31, 23, 23, 23, 23, 23, 23,
- 32, 33, 23, 23, 23, 23, 23, 34, 35, 36, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 38,
- 39, 23, 23, 23, 40, 41, 0, 42, 0, 0, 0, 43, 44, 45, 46, 47, 48, 23, 23,
- 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 0, 7, 0, 0, 6,
+ 0, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16,
+ 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19,
+ 0, 20, 21, 15, 22, 23, 24, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 29,
+ 30, 25, 25, 25, 25, 25, 25, 25, 25, 25, 31, 32, 33, 25, 25, 25, 25, 25,
+ 25, 34, 35, 25, 25, 25, 25, 25, 36, 37, 25, 0, 0, 0, 38, 0, 0, 0, 0, 0,
+ 39, 40, 41, 25, 25, 25, 42, 43, 0, 44, 0, 0, 0, 45, 46, 47, 48, 49, 25,
+ 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3105,8 +3237,8 @@ pub const SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, 0, 0,
- 0, 0, 0, 0, 54, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 53, 0, 54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3119,29 +3251,30 @@ pub const SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 55, 0, 56, 57, 0, 0, 0, 0, 0, 0, 0, 58, 0, 59, 0, 0, 60, 61, 0,
- 62,
+ 0, 0, 0, 0, 0, 0, 57, 0, 58, 59, 0, 0, 0, 0, 0, 60, 0, 61, 0, 62, 0, 0,
+ 63, 64, 0, 65,
],
tree2_level2: &[
- 0, 0xC0C000000000000, 0x2000000000000, 0x1000000000000, 0x7F8000000000000,
- 0x8000000000000000, 0x200000000008000, 0x1500000FCE8000E,
- 0xC000000000000000, 0x1E0DFBF, 0xC0000000, 0x3FF0000, 0x8000000, 0x1,
- 0xFFFFFFFFC0000000, 0x1FF007FE00000000, 0xA000000000000000,
- 0x6000E000E000E003, 0x1C00000000040010, 0xFFFFFFFF00001C00,
- 0xC0042AFC1D0037B, 0xBC1F, 0xFFFFFFFFFFFF0C00, 0xFFFFFFFFFFFFFFFF,
- 0xFFFFF9FFFFFFF0FF, 0x7FFFFFFFFF, 0x7FF, 0xFFFFFFFFF0000000,
- 0x3FFFFFFFFFF, 0xFFFFFFFFFF, 0xFFFFFFFFFFF00000, 0xFFFF003FFFFFFF9F,
- 0xFFFFFFFFFE000007, 0xCFFFFFFFF0FFFFFF, 0xFFCFFFFFFFFFFFFF,
- 0xFFFFFFFFFF3FFFFF, 0x7FFFFFFFFFFFFDFF, 0x7E000000000, 0xFFFFFFFFFBFFFFFF,
- 0xFFFFFFFFFFFFF, 0xFFF0000003FFFFF, 0xC0C00001000C0010, 0x18000000,
- 0xFFC30000, 0xFFFFFFFFF, 0xFFFFFC007FFFFFFF, 0xFFFFFFFF000100FF,
- 0x1FFFFFFFFFC00, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000, 0x7F,
- 0x3007FFFFF, 0x600, 0x3C00F0000000000, 0x380000000000000, 0x20000000000,
- 0xFFFC000000000000, 0x3, 0x3000000000000000, 0x27400000000,
- 0x4000000070000810, 0x50000001, 0x30007F7F00000000,
+ 0, 0x100, 0xC0C000000000000, 0x2000000000000, 0x1000000000000,
+ 0x7F8000000000000, 0x8000000000000000, 0x200000000008000,
+ 0x1500000FCE8000E, 0xC000000000000000, 0x1E0DFBF, 0xC0000000, 0x3FF0000,
+ 0x200000000000, 0x8000000, 0x1, 0xFFFFFFFFC0000000, 0x1FF007FE00000000,
+ 0xA000000000000000, 0x6000E000E000E003, 0x1C00000000040010,
+ 0xFFFFFFFF00001C00, 0xC0042AFC1D0037B, 0xBC1F, 0xFFFFFFFFFFFF0C00,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFF9FFFFFFF0FF, 0x7FFFFFFFFF, 0x7FF,
+ 0xFFFFFFFFF0000000, 0x3FFFFFFFFFF, 0xFFFFFFFFFF, 0xFFFFFFFFFFF00000,
+ 0xFFFF003FFFFFFF9F, 0xFFFFFFFFFE000007, 0xCFFFFFFFF0FFFFFF,
+ 0xFFCFFFFFFFFFFFFF, 0xFFFFFFFFFFBFFFFF, 0x7E000000000, 0x30000,
+ 0xFFFFFFFFFBFFFFFF, 0xFFFFFFFFFFFFF, 0xFFF0000003FFFFF,
+ 0xC0C00001000C0010, 0x18000000, 0xFFC30000, 0xFFFFFFFFF,
+ 0xFFFFFC007FFFFFFF, 0xFFFFFFFF000100FF, 0x1FFFFFFFFFC00,
+ 0xFFFFFFFFFFFF0000, 0x7F, 0x3007FFFFF, 0x600, 0x3C00F0000000000,
+ 0x380000000000000, 0xC0008000000, 0x20000000000, 0xFFFC000000000000, 0x7,
+ 0xFFFF, 0xF000000000008000, 0x27400000000, 0x4000000070000810, 0x50000001,
+ 0x30007F7F00000000,
],
tree3_level1: &[
- 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 5, 6, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -3159,37 +3292,41 @@ pub const SYMBOL: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11,
- 12, 13, 14, 15, 16, 11, 17, 0, 0, 11, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 19, 20, 21, 22, 23, 11, 11, 11, 11, 11, 11, 11, 11, 24, 25, 26, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 13, 13, 13, 15, 16, 17, 18, 19, 13,
+ 20, 0, 0, 13, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, 24, 25,
+ 26, 13, 13, 13, 13, 13, 13, 13, 13, 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0,
- 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 29, 11, 30, 31, 32, 29, 33, 34, 35, 36, 0,
- 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 37, 11, 38,
- 11, 39, 40, 41, 42, 0, 43, 44, 45, 46, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 32, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 34, 13, 35, 36, 37, 13, 38, 39, 40, 41, 0, 0, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 42, 13, 43, 13, 44, 45, 46, 47, 0,
+ 13, 13, 13, 13, 13, 48, 49, 50, 13, 13, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFF80000000000000, 0xFE00000000000000, 0x10FFF73FF,
+ 0, 0xFF80000000000000, 0xFE00000000000000, 0x11FFF73FF,
0x1FFFFFFFFFFF0000, 0x180000000000000, 0x100, 0x8000000000000000,
- 0xF000000000000000, 0x20, 0x10000000, 0xFFFFFFFFFFFFFFFF,
- 0x3FFFFFFFFFFFFF, 0xFFFFFE7FFFFFFFFF, 0x1C1FFFFFFFFF, 0xFFFFC3FFFFFFF018,
- 0x1FFFFFFFFFF, 0x23, 0x7FFFFF, 0x800000008000002, 0x20000000200000,
- 0x800000008000, 0x20000000200, 0x8, 0x780000000000000, 0xFFDFE00000000000,
- 0x6F, 0x1100000000000, 0x3000000000000, 0xFFFF0FFFFFFFFFFF,
- 0xFFFE7FFF000FFFFF, 0x3FFFFFFFFEFFFE, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFF,
- 0xFFFFFFC000000000, 0xFFFFFFFFFFF0007, 0x3F000301FF, 0x3FF1FFF001FFFFF,
- 0xFFFFFFFFFFFFF, 0x1FFFFFF, 0xFFFFFFFFFFFF0FFF, 0xFFFFFFFF03FF00FF,
- 0x3FFFFFFF00FF, 0x7FFFFFFFFFFF0FFF, 0xF479FFFFFFFFFFFF, 0x3FF0007FFFFFFFF,
- 0xFFFFFFFFFFFF0007, 0x3FFF00000000,
+ 0x3FFFFFFE00000, 0xF000000000000000, 0x20, 0x10000000, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFFFFFFFFF, 0xF, 0x3FFFFFFFFFFFFF, 0xFFFFFE7FFFFFFFFF,
+ 0x1C1FFFFFFFFF, 0xFFFFC3FFFFFFF018, 0x7FFFFFFFFFF, 0x23, 0x7FFFFF,
+ 0x800000008000002, 0x20000000200000, 0x800000008000, 0x20000000200, 0x8,
+ 0x780000000000000, 0xFFDFE00000000000, 0x6F, 0x8000, 0x1100000000000,
+ 0x400000000000, 0x3000000000000, 0xFFFF0FFFFFFFFFFF, 0xFFFE7FFF000FFFFF,
+ 0x3FFFFFFFFEFFFE, 0xFFFFFFFFFFFFE000, 0x3FFFFFFFFFFF, 0xFFFFFFC000000000,
+ 0xFFFFFFFFFFF0007, 0x3F000301FF, 0x1FFF1FFFE0FFFFFF, 0xFFFFFFFFFFFFF,
+ 0x10FFF01FFFFFF, 0xFFFFFFFFFFFF0FFF, 0xFFFFFFFF03FF00FF, 0x33FFFFFFF00FF,
+ 0x1F1F3FFF000FFFFF, 0x7FF1FFFFFFF007F, 0x7F00FF03FF003F,
+ 0xFFFFFFFFFFF7FFFF, 0x7FF,
],
};
@@ -3254,198 +3391,209 @@ pub const TITLECASE_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
pub const UNASSIGNED: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
tree1_level1: &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x300000000000000, 0x40000280F, 0,
- 0, 0, 0, 0, 0x1000000000000, 0x1800000, 0x11800, 0xFFE078000000FF00,
- 0x20000000, 0, 0, 0, 0x4000, 0x1800, 0xFFFC000000000000,
- 0x1800000000000000,
+ 0, 0, 0, 0, 0x1000000000000, 0x1800000, 0x11800, 0xFFE078000000FF00, 0, 0,
+ 0, 0, 0x4000, 0x1800, 0xFFFC000000000000, 0x1800000000000000,
],
tree2_level1: &[
- 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 4, 27, 28, 29, 4, 4, 4, 30, 4, 4, 4, 4, 4, 31,
- 32, 33, 34, 35, 36, 37, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 38, 39, 40, 41, 4,
- 42, 43, 39, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 4, 54, 4, 55, 56, 57,
- 58, 59, 4, 4, 4, 60, 4, 4, 4, 4, 61, 62, 63, 64, 4, 65, 66, 67, 4, 4, 68,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 69, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 71, 72, 73, 74, 75, 4, 76, 77,
- 78, 79, 80, 4, 81, 82, 83, 4, 4, 4, 84, 4, 85, 86, 4, 87, 4, 88, 89, 75,
- 4, 4, 90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 45, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 91, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 93, 4, 4, 4, 4, 94, 4, 4, 95, 4, 4, 96,
- 97, 98, 95, 4, 99, 4, 100, 4, 101, 102, 103, 4, 104, 105, 106, 4, 107, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 89,
- 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 109, 4, 110, 111, 112, 4, 113,
- 4, 4, 4, 4, 4, 114, 115, 116, 36, 117, 4, 118, 85, 4, 90, 119,
+ 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 3, 26, 27, 28, 3, 3, 3, 29, 3, 3, 3, 3, 3, 30,
+ 31, 32, 33, 34, 35, 36, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 37, 38, 39, 40, 3,
+ 41, 35, 38, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 3, 52, 3, 53, 54, 55,
+ 56, 57, 3, 3, 3, 3, 3, 3, 3, 3, 58, 59, 60, 61, 3, 62, 63, 64, 3, 3, 65,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 66, 67, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 68, 69, 3, 3, 3, 3, 70, 71, 72,
+ 73, 74, 3, 75, 76, 77, 3, 3, 3, 78, 3, 79, 80, 3, 81, 3, 82, 83, 84, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 85, 86, 3, 3, 3, 3, 87, 3, 3, 88, 3, 3, 3, 89, 90, 88, 3,
+ 91, 3, 92, 3, 93, 94, 95, 3, 96, 97, 46, 3, 98, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 83, 99, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 100, 3, 101, 102, 103, 3, 104, 3, 3, 3, 3, 3, 3, 105, 106,
+ 35, 107, 3, 108, 79, 3, 109, 110,
],
tree2_level2: &[
- 0x8000C00000000000, 0xFFFFF800B0000000, 0xC0200000FFFFFFFF, 0x7FFFF, 0,
- 0xC3A020000066010, 0x800000304F7F8660, 0x2C92020000067811,
- 0xFF80003FA1FDC678, 0xC12020000044011, 0x1FC0030FFFEC440,
- 0xC12020000066011, 0xFF0000304F3FC660, 0x3C0038E729C23813,
- 0xF800003FFF7EC238, 0x1C00020000022000, 0xFF0030F89FC220,
- 0xC10020000022000, 0xFFF90030BF9FC220, 0x22010, 0x30000F0220,
- 0xD004000003800013, 0xFFE3003F00A07B80, 0x7800000000000001,
- 0xFFFFFFFFF0000000, 0xC4001351010FDA69, 0xFFFFFFFF0C00C0A0,
- 0x1E00000000100, 0x2000000001000000, 0xFFFFFFFFF8002000, 0xDF40,
- 0xC280C200, 0x80C200000000C200, 0x8000C2, 0xC20000, 0xE000000018000000,
- 0xFC000000, 0xC0C0000000000000, 0xE0000000, 0xFE00000000000000,
- 0xFF800000FFE02000, 0xFFF22000FFF00000, 0xFC00FC00C0000000, 0xFC008000,
- 0xF80000000000, 0xFFC0000000000000, 0xF000F00080000000,
- 0xFFE0C0000000000E, 0xF00000000000, 0x3800FC00, 0x30000000,
- 0x6000000080000000, 0x8000C000FC00FC00, 0xFFFFFFFFFFFFFFFF,
- 0xE00000000000F000, 0xFF0000000000000, 0x700000000000000, 0x1C00,
- 0x180000000000FE00, 0xFC0000000000FF00, 0x400000000000000, 0xC0C00000,
- 0xC00000005500C0C0, 0x20000000000000, 0x8023000010300020, 0xC002000000000,
- 0xE0008000, 0xFFFE00000000FFFF, 0xF000, 0xFFFFFF8000000000, 0xFFFFF800,
- 0x30000000000000, 0xC00000, 0x8000000000000200, 0x800000000000,
- 0x80000000, 0x1F0000000000000, 0xDF4000000000, 0x7FFE7F0000000000,
- 0x80808080FF800000, 0x80808080, 0xFFFFFFFFFFFF8000, 0x4000000,
- 0xFFF0000000000000, 0xF000FFFFFFC00000, 0x1, 0x1800000, 0x100000000001F,
- 0xF800000000008000, 0xFFF000000000, 0x8000000000000000,
- 0xFFFF000000000000, 0xE000, 0xFF80, 0xFFFFF00000000000,
- 0xFF00000000000000, 0xFC00000000000000, 0x7FFFFFFFFFFFFF,
- 0xFC00F00000000000, 0xFC003FC0, 0xE00000007FF00000, 0x800000003C004000,
- 0xFF80000000000000, 0xC00C000, 0xFF80000007FFFFF8, 0x8080FF818181,
- 0xFFC000000000, 0xFC00C00000000000, 0xF000000000000780, 0xC00000000000,
- 0xFFFFFFFFFC000000, 0xA08000001F07FF80, 0x24, 0x7FFFC, 0xFFFF, 0x30000,
- 0xC000FFFFFFFFFF00, 0x20F08000080000, 0x6000000000000000,
+ 0x8000C00000000000, 0xF800B0000000, 0xFC8000, 0, 0xC3A020000066010,
+ 0x800000304F7F8660, 0x2C92020000067811, 0xFF80003FA1FDC678,
+ 0xC12020000044011, 0x1FC0030FFFEC440, 0xC12020000066011,
+ 0xFF0000304F1FC660, 0x3C0038E729C23813, 0xF800003FFF7EC238,
+ 0xC00020000022000, 0x7F0030D89FC220, 0xC10020000022000,
+ 0xFFF900309F9FC220, 0x22000, 0x30000F0220, 0xD004000003800011,
+ 0xFFE3003F00A07B80, 0x7800000000000001, 0xFFFFFFFFF0000000,
+ 0xC000005000000829, 0xFFFFFFFF0C00C0A0, 0x1E00000000100,
+ 0x2000000001000000, 0xFFFFFFFFF8002000, 0xDF40, 0xC280C200,
+ 0x80C200000000C200, 0x8000C2, 0xC20000, 0xE000000018000000, 0xFC000000,
+ 0xC0C0000000000000, 0xE0000000, 0xFE00000000000000, 0xFF8000007FC00000,
+ 0xFFF22000FFF00000, 0xFC00FC00C0000000, 0xF80000000000,
+ 0xFFC0000000000000, 0xF000F00080000000, 0xFFE0C0000000000E,
+ 0xF00000000000, 0x3800FC00, 0x30000000, 0x6000000080000000,
+ 0xC000FC00FC00, 0xFFFFFFFFFFFF8000, 0x800000000000E000, 0xFF0000000000000,
+ 0x700000000000000, 0x1C00, 0x180000000000FE00, 0xF80000000000FF00,
+ 0xC0C00000, 0xC00000005500C0C0, 0x20000000000000, 0x8023000010300020,
+ 0xC002000000000, 0xE0008000, 0xFFFE00000000FFFE, 0xF000,
+ 0xFFFFFF8000000000, 0xFFFFF800, 0x30000000000000, 0x400000,
+ 0x1F0000000000000, 0xDF4000000000, 0x7FFE7F0000000000, 0x80808080FF800000,
+ 0x80808080, 0xFFFFFFFFC0000000, 0x4000000, 0xFFF0000000000000,
+ 0xF000FFFFFFC00000, 0x1, 0x1800000, 0x100000000001F, 0x8000,
+ 0xFFF000000000, 0x80000000, 0xE000, 0xFF80, 0xFFFFF00000000000,
+ 0xFF00000000000000, 0x3FFFFFC14F800, 0xFC00E00000000000, 0xFC003FC0,
+ 0xE00000007FF00000, 0x800000003C004000, 0xFF80000000000000, 0xC00C000,
+ 0xFF80000007FFFFF8, 0x8080FF818181, 0xFC00C00000000000,
+ 0xF000000000000780, 0xC00000000000, 0xFFFFFFFFFC000000,
+ 0xA08000001F07FF80, 0x24, 0x7FFF8, 0x30000, 0xFFFFFFFF7F00,
+ 0x20F08000080000, 0x6000000000000000, 0x8000000000000000,
0xC1FF8080E3030303,
],
tree3_level1: &[
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 13, 14, 15, 7, 16, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 19, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 19,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 22, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 22,
],
tree3_level2: &[
0, 1, 2, 3, 4, 2, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 2, 2, 14, 15, 16, 17,
- 7, 7, 2, 2, 2, 2, 18, 19, 7, 7, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 7, 2, 34, 35, 36, 37, 7, 7, 7, 7, 38, 7, 7, 16, 39, 7, 7,
- 2, 40, 2, 41, 42, 43, 2, 44, 45, 7, 46, 47, 48, 49, 7, 7, 2, 50, 2, 51, 7,
- 7, 52, 53, 2, 54, 55, 56, 57, 7, 7, 7, 58, 7, 59, 60, 7, 7, 7, 7, 2, 61,
- 62, 63, 7, 7, 7, 7, 64, 65, 66, 7, 67, 68, 69, 7, 7, 7, 7, 70, 7, 7, 7, 7,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 39, 7, 2, 71, 2, 2, 2, 72, 7, 7,
+ 18, 7, 2, 2, 2, 2, 19, 20, 21, 7, 22, 23, 24, 25, 26, 7, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 7, 2, 36, 37, 38, 39, 7, 7, 7, 7, 40, 41, 7, 16, 42,
+ 43, 44, 2, 45, 2, 46, 47, 48, 2, 49, 50, 7, 51, 52, 53, 54, 7, 7, 2, 55,
+ 2, 56, 7, 7, 57, 58, 2, 59, 60, 61, 62, 63, 7, 7, 64, 7, 65, 66, 67, 68,
+ 69, 70, 2, 71, 72, 73, 7, 7, 7, 7, 74, 75, 76, 7, 77, 78, 79, 7, 7, 7, 7,
+ 80, 7, 7, 81, 82, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 83, 7, 2, 84,
+ 2, 2, 2, 85, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 86, 37, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 73, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 74, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 63, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2,
- 63, 75, 7, 76, 2, 77, 78, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 79, 7, 2, 80,
- 81, 82, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2,
+ 2, 2, 2, 2, 2, 2, 2, 73, 88, 89, 90, 2, 91, 92, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 2, 93, 7, 2, 94, 95, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 83,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 35, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 84, 85, 2, 2, 2, 2, 2, 58, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 98, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 2, 86, 87, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2,
- 2, 2, 88, 89, 2, 2, 90, 2, 91, 7, 92, 2, 93, 7, 7, 2, 94, 95, 96, 97, 98,
- 2, 2, 2, 2, 99, 2, 2, 2, 2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 102, 7, 7, 7, 7,
+ 7, 7, 7, 99, 2, 2, 2, 2, 100, 101, 2, 2, 2, 2, 2, 64, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 2, 2, 2, 103, 2, 104, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 105, 106, 7,
- 7, 7, 7, 7, 107, 108, 109, 110, 7, 7, 7, 7, 111, 2, 112, 113, 114, 111,
- 115, 116, 117, 118, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 119, 2, 120, 2, 121, 122, 123, 124, 7, 125, 126, 127, 128, 7, 129, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 130, 2,
+ 7, 7, 7, 7, 2, 102, 103, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 104, 105, 2, 85, 2, 2, 2, 106, 107, 2, 2, 108, 2,
+ 109, 7, 110, 2, 111, 7, 7, 2, 112, 113, 114, 115, 116, 2, 2, 2, 2, 117, 2,
+ 2, 2, 2, 118, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 119, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 120, 7, 7, 7, 121, 7, 7, 7, 122, 123, 7, 7, 7,
+ 7, 124, 125, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 126,
+ 2, 2, 2, 127, 2, 128, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 129, 130, 7, 131,
+ 7, 7, 7, 132, 133, 134, 135, 7, 7, 7, 7, 136, 2, 137, 138, 2, 2, 139, 140,
+ 141, 142, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 143, 2, 144,
+ 2, 145, 146, 147, 148, 7, 2, 2, 2, 2, 2, 149, 150, 151, 2, 2, 152, 153, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 106, 2, 2, 2, 131, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 73, 2, 2, 2, 154, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 132, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 133, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 156, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 58, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 157, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 53, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 134, 2, 7,
- 7, 2, 2, 2, 135, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 158, 2, 7, 7, 2, 2, 2, 159, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 136,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 160,
],
tree3_level3: &[
0x4800008000001000, 0xFFFFFFFFC000C000, 0, 0xF800000000000000,
- 0x70000000000078, 0xFFFFFFFEF0008000, 0xC00000000000FFFF,
+ 0x70000000000078, 0xFFFFFFFEE0008000, 0xC00000000000FFFF,
0xFFFFFFFFFFFFFFFF, 0xE0000000, 0xF0000000FFFE0000, 0x1FF000000000,
0xF80000000000F800, 0x40000000, 0xFFFFFFFFFFC000F0, 0xFC00C0000000,
- 0xF000000000F00000, 0xFF0000000000, 0xFFFF7FF000000000,
- 0xFF80000000000000, 0xFFFFFF00FFC00000, 0x6E400000000002C0, 0x400000,
- 0xFFFF007F80000000, 0x7C80000FFFFFFFF, 0x7C00000070000000,
- 0xF00000000000000, 0x30000, 0x78C0000001100F90, 0xFE00FE00,
- 0xFFFFFFFF00000000, 0xFF80078000000000, 0x1C0000000000000,
+ 0xF000000000F00000, 0xFF0000000000, 0x8007FF000000000, 0xE404000400480800,
+ 0xFF80000000000000, 0xFFFFFF00FFC00000, 0xF802000000000040,
+ 0x6E400000000002C0, 0x400000, 0xFFFF007F80000000, 0x7C80000FFFFFFFF,
+ 0x7C00000070000000, 0xF00000000000000, 0x30000, 0x78C0000001100F90,
+ 0xFE00FE00, 0xFFFFFFFF00000000, 0xFF80078000000000, 0x1C0000000000000,
0xF8000000C00000, 0xFFFF01FFE1FC0000, 0xFFFFFFFFFFFFFE00,
0xFFF8000000000000, 0x3F8000000000000, 0xFC00FF0000000000,
- 0x80000000FFFFFFFF, 0xFFFFFFFFFC000000, 0x7FFF00000003C000,
- 0xFC00FE000000DFFC, 0x20000000000000, 0xFF8000000000FF80,
- 0xFFE000010000C000, 0x8000000000040000, 0xFC0040004280,
- 0xFC00F80000000000, 0x412020000066010, 0xFFE0E0301F7EC660,
- 0xFFFFFFFF94000000, 0xFFFFFFFFFC00FF00, 0xC0000000000000,
- 0xFFFFFFFFC0000000, 0xFFFFE000FC00FFE0, 0xFF00000000000000,
- 0xFFFFFFFFFFFFFC00, 0xF00018000000, 0xF000000000000000, 0xFFFFFFFF,
- 0x7FF8000000000000, 0xFF00, 0xFFFFFFF800000030, 0xFE00000000000000,
- 0x80000000000200, 0xE0000000FFC0, 0xFF80010000030000, 0x4B80000000000480,
- 0x240FC00FF00, 0xFFFFFC00FE048000, 0xFE000000FFFFFFFF, 0xFFE0800000000000,
- 0xFFFFFFFFFFFFFFF0, 0xFFFF800000000000, 0xFFFFFFFFFFFFFF80,
- 0xFFFF3C0080000000, 0xFFC0C0000000FFFF, 0x1F0000040400FFC0,
- 0xFFFFFFFFFFFF0000, 0xFFFFFFFFF8000000, 0x800000000000FFE0,
- 0xFFFFFFFF00007FFF, 0xFFFFFFFCFFFFFFFF, 0xFFFC000000000000,
- 0xFFFFFFFF80000000, 0xFFFFFFFFFFFF, 0xE000F80000000000,
- 0xFFFFFFF00C00FE00, 0xFFC0000000000000, 0x18000000000, 0xFFFFFE0000000000,
- 0xFFFFFFFFFFFFFFC0, 0xFFF00000FFFFFFFF, 0xFE000000FF800000, 0x200000,
- 0x1400219B20000000, 0x10, 0x8400000020201840, 0x203A0, 0xC000000000,
- 0x3000, 0xFFFF000107FFF000, 0xFFFFF82406000080, 0xFFFFFFFFFF800060,
- 0xFFFFFFFF3C00F800, 0x1FFFFFFFFFFFF, 0xFFE0000000000000,
- 0xF508016900000010, 0xA10808695569157B, 0xF0000411F0000400,
- 0xFFFCFFFFFFFFFFFF, 0xF00000000000, 0x18000FFF00000, 0xFFC0000000010001,
- 0xE000, 0xFFFFE00000000000, 0x3FFFFFFFFF, 0xF00000000000FFF8,
- 0xFFFFFFC0FFFCFE00, 0xFC00E000FFE00000, 0xFFF0000000000000,
- 0xFFFFFFFFFE000000, 0xF000, 0xFC00FF00, 0xFFFFC0000000FF00,
- 0x800000000000F000, 0xB86000000000000, 0xFC00FFF800000000, 0xFFF8,
- 0xFFFFC000FFFFFFFF, 0xFFFFFFFFFF800000, 0xC0000000, 0xFFFC00000000,
- 0xFFFFFFFE00000000, 0xFFFFFFFD, 0xFFFF000000000000, 0xC000000000000000,
+ 0x80000000FFFFFFFF, 0xFFFCC40000000000, 0xFFFFFC000000, 0xFFFFFFFFFC00,
+ 0xFF800000FFFFF000, 0x7FC000000003C000, 0xFC00FE000000DFF8,
+ 0x20000000000000, 0xFF8000000000FF00, 0xFFE0000100000000,
+ 0x8000000000040000, 0xFC0040004280, 0xFC00F80000000000, 0x412020000066010,
+ 0xFFE0E0301F7EC660, 0xFFFFFFFC10000000, 0xFFFFFFFFFC00FF00,
+ 0xC0000000000000, 0xFFFFFFFFC0000000, 0xFFFFE000FC00FFE0,
+ 0xFC00000000000000, 0xFFFFFFFFFFFFFC00, 0xF00018000000,
+ 0xFFFFFFFFFFFFFF80, 0xF000000000000000, 0xFFFFFFFF, 0x7FF8000000000000,
+ 0x640000000900D80, 0xFFFFFFFFFC00FF80, 0x300FFFFFFFF, 0xFFFFFFE003000000,
+ 0xFF00, 0xFFF800000000, 0xFE00000000000000, 0x80000000000200,
+ 0xE0000000FFC0, 0xFF80010000030000, 0x4B80000000000480, 0x240FC00FF00,
+ 0xFFFFFC00FE048000, 0xFE000000FFFFFFFF, 0xFFFEFFFFFFFFFFFF,
+ 0x7FFC000000000000, 0xFFFFFFFFFC000000, 0xFFE0800000000000,
+ 0xFFFFFFFFFFFFFFF0, 0xFFFF, 0xFE00800000000000, 0x3C0080000000,
+ 0x8000000000000000, 0xFFC0C0000000FC00, 0x1F0000040400FFC0,
+ 0xFFFFFFFFFFFF0000, 0xFFFFFFFFF8000000, 0x7800, 0xFFFFFFFF00007F00,
+ 0xFFFCFFE0FFFFFFFF, 0xFF00000000000000, 0xFFFFFFFFFFC00000,
+ 0x9010FFFFFFFFFFFF, 0xFFFFFFF800000000, 0xFF0FFFF8FFFF,
+ 0xE000F80000000000, 0xFFFFFFF00C00FE00, 0xC00000000000, 0xFF80,
+ 0xFFC0000000000000, 0x18000000000, 0xFFFFF80000000000, 0xFFFFFFFFFFFFFFC0,
+ 0xFFF00000FFFFFFFF, 0xFE000000FF800000, 0x200000, 0x1400219B20000000,
+ 0x10, 0x8400000020201840, 0x203A0, 0xC000000000, 0x3000,
+ 0xFFFF000107FFF000, 0xFFFFFFFF80000000, 0xFFFFF82406000080,
+ 0xC000E00000000000, 0xFFFFFFFFFFFF3C00, 0xFFFF80000000FFFF,
+ 0x7C00000000000000, 0x80009080FFFFFFFF, 0xFFFFFFFFFF800060,
+ 0xFFFFFFFF3C00F000, 0x1FFFFFFFFFFFF, 0xFFE0000000000000,
+ 0xC000000000000001, 0xF508016900000010, 0xA10808695569157B,
+ 0xF0000411F0000400, 0xFFFCFFFFFFFFFFFF, 0xF00000000000, 0x18000FFF00000,
+ 0xFFC0000000010001, 0xFFFFC00000000000, 0x3FFFFFFFFF, 0xF00000000000FFF8,
+ 0xFFFFFFC0FFFCFE00, 0xE000E0001F000000, 0xFFF0000000000000,
+ 0xFFFEF000FE000000, 0xF000, 0xFC00FF00, 0xFFFCC0000000FF00,
+ 0xE0E0C000FFF00000, 0xF800E0000000FF80, 0xFF80FF00FC00FFC0, 0x80000,
+ 0xFC00FFFFFFFFF800, 0xC0000000, 0xFFFC00000000, 0xFFFFFFFE00000000,
+ 0xFFFFFFFFFFFFF800, 0xFFFFFFFD, 0xFFFF000000000000, 0xC000000000000000,
],
};
@@ -3483,7 +3631,7 @@ pub const UPPERCASE_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 0, 19, 20, 21, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 0, 19, 20, 21, 22, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3497,15 +3645,15 @@ pub const UPPERCASE_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0,
],
tree2_level2: &[
0, 0xFFFFFFFF00000000, 0x20BF, 0x3FFFFFFFFFFFFF, 0xE7FFFFFFFFFF0000,
0x5555555555555555, 0x5555555540155555, 0xFF00FF003F00FF00,
0xFF00AA003F00, 0xF00000000000000, 0xF001F000F000F00, 0xC00F3D503E273884,
- 0x20, 0x8, 0x7FFFFFFFFFFF, 0xC025EA9D00000000, 0x4280555555555,
+ 0x20, 0x8, 0xFFFFFFFFFFFF, 0xC025EA9D00000000, 0x4280555555555,
0x155555555555, 0x5555555, 0x5554555400000000, 0x6A00555555555555,
- 0x15F7D5555452855, 0x7FFFFFE00000000,
+ 0x555F7D5555452855, 0x200000014102F5, 0x7FFFFFE00000000,
],
tree3_level1: &[
0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -3521,29 +3669,30 @@ pub const UPPERCASE_LETTER: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet
2, 2, 2, 2, 2, 2,
],
tree3_level2: &[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 4, 5, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
tree3_level3: &[
- 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0x7FFFFFFFFFFFF,
- 0xFFFFFFFF00000000, 0xFFFFFFFF, 0xFFF0000003FFFFFF, 0xFFFFFF0000003FFF,
- 0x3FDE64D0000003, 0x3FFFFFF0000, 0x7B0000001FDFE7B0, 0xFFFFF0000001FC5F,
- 0x3FFFFFF0000003F, 0x3FFFFFF00000, 0xF0000003FFFFFF00, 0xFFFF0000003FFFFF,
- 0xFFFFFF00000003FF, 0x7FFFFFC00000001, 0x1FFFFFF0000000, 0x7FFFFFC00000,
- 0x1FFFFFF0000, 0x400, 0x3FFFFFFFF,
+ 0, 0xFFFFFFFFFF, 0xFFFF000000000000, 0xFFFFF, 0xF7FF000000000000,
+ 0x37F7FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF,
+ 0xFFF0000003FFFFFF, 0xFFFFFF0000003FFF, 0x3FDE64D0000003, 0x3FFFFFF0000,
+ 0x7B0000001FDFE7B0, 0xFFFFF0000001FC5F, 0x3FFFFFF0000003F, 0x3FFFFFF00000,
+ 0xF0000003FFFFFF00, 0xFFFF0000003FFFFF, 0xFFFFFF00000003FF,
+ 0x7FFFFFC00000001, 0x1FFFFFF0000000, 0x7FFFFFC00000, 0x1FFFFFF0000, 0x400,
+ 0x3FFFFFFFF,
],
};
diff --git a/vendor/pest/src/unicode/mod.rs b/vendor/pest/src/unicode/mod.rs
index 3def67e34..912a7ecee 100644
--- a/vendor/pest/src/unicode/mod.rs
+++ b/vendor/pest/src/unicode/mod.rs
@@ -5,6 +5,8 @@
#![allow(bad_style)]
#![allow(clippy::all)]
+use alloc::boxed::Box;
+
macro_rules! char_property_functions {
{$(
mod $module:ident;
diff --git a/vendor/pest/tests/calculator.rs b/vendor/pest/tests/calculator.rs
index b78ee0d27..54a50cc67 100644
--- a/vendor/pest/tests/calculator.rs
+++ b/vendor/pest/tests/calculator.rs
@@ -40,12 +40,12 @@ impl Parser<Rule> for CalculatorParser {
s.repeat(|s| {
s.sequence(|s| {
plus(s)
- .or_else(|s| minus(s))
- .or_else(|s| times(s))
- .or_else(|s| divide(s))
- .or_else(|s| modulus(s))
- .or_else(|s| power(s))
- .and_then(|s| primary(s))
+ .or_else(minus)
+ .or_else(times)
+ .or_else(divide)
+ .or_else(modulus)
+ .or_else(power)
+ .and_then(primary)
})
})
})
@@ -57,10 +57,10 @@ impl Parser<Rule> for CalculatorParser {
state
.sequence(|s| {
s.match_string("(")
- .and_then(|s| expression(s))
+ .and_then(expression)
.and_then(|s| s.match_string(")"))
})
- .or_else(|s| number(s))
+ .or_else(number)
}
fn number(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
@@ -109,7 +109,7 @@ impl Parser<Rule> for CalculatorParser {
}
}
-fn consume<'i>(pair: Pair<'i, Rule>, climber: &PrecClimber<Rule>) -> i32 {
+fn consume(pair: Pair<Rule>, climber: &PrecClimber<Rule>) -> i32 {
let primary = |pair| consume(pair, climber);
let infix = |lhs: i32, op: Pair<Rule>, rhs: i32| match op.as_rule() {
Rule::plus => lhs + rhs,
diff --git a/vendor/pest/tests/json.rs b/vendor/pest/tests/json.rs
index 84906258a..b9338c342 100644
--- a/vendor/pest/tests/json.rs
+++ b/vendor/pest/tests/json.rs
@@ -47,16 +47,16 @@ impl Parser<Rule> for JsonParser {
state.rule(Rule::object, |s| {
s.sequence(|s| {
s.match_string("{")
- .and_then(|s| skip(s))
- .and_then(|s| pair(s))
- .and_then(|s| skip(s))
+ .and_then(skip)
+ .and_then(pair)
+ .and_then(skip)
.and_then(|s| {
s.repeat(|s| {
s.sequence(|s| {
s.match_string(",")
- .and_then(|s| skip(s))
- .and_then(|s| pair(s))
- .and_then(|s| skip(s))
+ .and_then(skip)
+ .and_then(pair)
+ .and_then(skip)
})
})
})
@@ -65,7 +65,7 @@ impl Parser<Rule> for JsonParser {
.or_else(|s| {
s.sequence(|s| {
s.match_string("{")
- .and_then(|s| skip(s))
+ .and_then(skip)
.and_then(|s| s.match_string("}"))
})
})
@@ -76,10 +76,10 @@ impl Parser<Rule> for JsonParser {
state.rule(Rule::pair, |s| {
s.sequence(|s| {
string(s)
- .and_then(|s| skip(s))
+ .and_then(skip)
.and_then(|s| s.match_string(":"))
- .and_then(|s| skip(s))
- .and_then(|s| value(s))
+ .and_then(skip)
+ .and_then(value)
})
})
}
@@ -88,16 +88,16 @@ impl Parser<Rule> for JsonParser {
state.rule(Rule::array, |s| {
s.sequence(|s| {
s.match_string("[")
- .and_then(|s| skip(s))
- .and_then(|s| value(s))
- .and_then(|s| skip(s))
+ .and_then(skip)
+ .and_then(value)
+ .and_then(skip)
.and_then(|s| {
s.repeat(|s| {
s.sequence(|s| {
s.match_string(",")
- .and_then(|s| skip(s))
- .and_then(|s| value(s))
- .and_then(|s| skip(s))
+ .and_then(skip)
+ .and_then(value)
+ .and_then(skip)
})
})
})
@@ -106,7 +106,7 @@ impl Parser<Rule> for JsonParser {
.or_else(|s| {
s.sequence(|s| {
s.match_string("[")
- .and_then(|s| skip(s))
+ .and_then(skip)
.and_then(|s| s.match_string("]"))
})
})
@@ -116,11 +116,11 @@ impl Parser<Rule> for JsonParser {
fn value(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::value, |s| {
string(s)
- .or_else(|s| number(s))
- .or_else(|s| object(s))
- .or_else(|s| array(s))
- .or_else(|s| bool(s))
- .or_else(|s| null(s))
+ .or_else(number)
+ .or_else(object)
+ .or_else(array)
+ .or_else(bool)
+ .or_else(null)
})
}
@@ -154,7 +154,7 @@ impl Parser<Rule> for JsonParser {
.or_else(|s| s.match_string("n"))
.or_else(|s| s.match_string("r"))
.or_else(|s| s.match_string("t"))
- .or_else(|s| unicode(s))
+ .or_else(unicode)
})
})
}
@@ -162,9 +162,9 @@ impl Parser<Rule> for JsonParser {
fn unicode(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.sequence(|s| {
s.match_string("u")
- .and_then(|s| hex(s))
- .and_then(|s| hex(s))
- .and_then(|s| hex(s))
+ .and_then(hex)
+ .and_then(hex)
+ .and_then(hex)
})
}
@@ -179,15 +179,15 @@ impl Parser<Rule> for JsonParser {
state.rule(Rule::number, |s| {
s.sequence(|s| {
s.optional(|s| s.match_string("-"))
- .and_then(|s| int(s))
+ .and_then(int)
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.match_string(".")
.and_then(|s| s.match_range('0'..'9'))
.and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
- .and_then(|s| s.optional(|s| exp(s)))
- .or_else(|s| exp(s))
+ .and_then(|s| s.optional(exp))
+ .or_else(exp)
})
})
})
@@ -211,7 +211,7 @@ impl Parser<Rule> for JsonParser {
.and_then(|s| {
s.optional(|s| s.match_string("+").or_else(|s| s.match_string("-")))
})
- .and_then(|s| int(s))
+ .and_then(int)
})
}
@@ -451,15 +451,12 @@ fn ast() {
.unwrap(),
);
- match ast {
- Json::Object(pairs) => {
- let vals: Vec<&Json> = pairs.values().collect();
+ if let Json::Object(pairs) = ast {
+ let vals: Vec<&Json> = pairs.values().collect();
- assert_eq!(
- **vals.get(0).unwrap(),
- Json::Array(vec![Json::Null, Json::Bool(true), Json::Number(3.4)])
- );
- }
- _ => {}
+ assert_eq!(
+ **vals.get(0).unwrap(),
+ Json::Array(vec![Json::Null, Json::Bool(true), Json::Number(3.4)])
+ );
}
}
diff --git a/vendor/pest_derive/.cargo-checksum.json b/vendor/pest_derive/.cargo-checksum.json
index 0f484603a..b9c70e450 100644
--- a/vendor/pest_derive/.cargo-checksum.json
+++ b/vendor/pest_derive/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"3616e31e313d646dd0372ba0116b596a4c9dfc21cda88625ef00001ab13b0d68","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"7c31c505c267ac538b70deaa9ad95ef0cc68720c46b4d3276df8f3a278d233e2","src/lib.rs":"f343c474ce5ff5520907bd69dd52b965b4aec42750fe3bf7eaf2b5075b08cfd6","tests/grammar.pest":"3a2212c28dd560ba3169e0e1470394ae706eb9336360ecdc0f1d9934af9fc223","tests/grammar.rs":"75261bc1ba2817d59e35fa2a7c07a661f9f2200a0144cb768837d37d3c370aa0","tests/grammar_inline.rs":"675c55697df7b8d011cef7182f2b05d52b4e73d405c869b9ea361bff5f17b63a","tests/lists.pest":"96d90ad5eb7b14648fa8720f0a48e680327080b07251a4dd74e1a023625e9c1a","tests/lists.rs":"5cc0c79494685d5056ab6164bc8893e26d29810f5c5a20d895f27c1695bab31c","tests/reporting.pest":"f5bc8405ea117b76338e0003e359731a8aaf1a36672f31a6a639a4e67a65e331","tests/reporting.rs":"d1658fd9466278f80769384f4377056274bd06fff586c2422b4fe42d39967e4b"},"package":"833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"} \ No newline at end of file
+{"files":{"Cargo.toml":"3b10f9a7d7abd7529819a9c273e1e1fe6868225f3eb14fca998ede71e81d0d9c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"01ba71f02581f9f5018962e083ca77bc8e8af2b6f8a73111bfa04e847a6440e2","src/lib.rs":"8a4edbd00a1ac7dddf041618bc088d095ade1647799fcb7621b71cc2660f0822","tests/grammar.pest":"23c99a141f9165d24f3c46cd40a15788056b87558398b80a757980fd6967f271","tests/grammar.rs":"1c583be001c7f627816507142324a465d6bd2c701e869a3382ff44e8c45050e9","tests/grammar_inline.rs":"349527e75a1fc10e0208d3d88cbac427dd5999b8a2a79d2b9c981e73af22da37","tests/lists.pest":"96d90ad5eb7b14648fa8720f0a48e680327080b07251a4dd74e1a023625e9c1a","tests/lists.rs":"2dc0cb9c07f5b077743ce9313488599347061ea486e0f5160bff50b3d07ca72c","tests/reporting.pest":"f5bc8405ea117b76338e0003e359731a8aaf1a36672f31a6a639a4e67a65e331","tests/reporting.rs":"8b88238dc33abff5dbc76434a7468dceeb9db3dfa8826d44c8ea1d13d52431e8"},"package":"905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91"} \ No newline at end of file
diff --git a/vendor/pest_derive/Cargo.toml b/vendor/pest_derive/Cargo.toml
index 47dfec41b..44212b499 100644
--- a/vendor/pest_derive/Cargo.toml
+++ b/vendor/pest_derive/Cargo.toml
@@ -3,22 +3,28 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
+edition = "2018"
+rust-version = "1.56"
name = "pest_derive"
-version = "2.1.0"
+version = "2.3.0"
authors = ["DragoÈ™ Tiselice <dragostiselice@gmail.com>"]
description = "pest's derive macro"
homepage = "https://pest-parser.github.io/"
documentation = "https://docs.rs/pest"
readme = "_README.md"
-keywords = ["pest", "parser", "peg", "grammar"]
+keywords = [
+ "pest",
+ "parser",
+ "peg",
+ "grammar",
+]
categories = ["parsing"]
license = "MIT/Apache-2.0"
repository = "https://github.com/pest-parser/pest"
@@ -26,16 +32,18 @@ repository = "https://github.com/pest-parser/pest"
[lib]
name = "pest_derive"
proc-macro = true
+
[dependencies.pest]
-version = "2.1.0"
+version = "2.3.0"
+default-features = false
[dependencies.pest_generator]
-version = "2.1.0"
-[badges.codecov]
-repository = "pest-parser/pest"
-
-[badges.maintenance]
-status = "actively-developed"
+version = "2.3.0"
+default-features = false
-[badges.travis-ci]
-repository = "pest-parser/pest"
+[features]
+default = ["std"]
+std = [
+ "pest/std",
+ "pest_generator/std",
+]
diff --git a/vendor/pest_derive/_README.md b/vendor/pest_derive/_README.md
index 2c94a7222..f91188ccb 100644
--- a/vendor/pest_derive/_README.md
+++ b/vendor/pest_derive/_README.md
@@ -1,3 +1,4 @@
+
<p align="center">
<img src="https://raw.github.com/pest-parser/pest/master/pest-logo.svg?sanitize=true" width="80%"/>
</p>
@@ -8,8 +9,10 @@
[![Book](https://img.shields.io/badge/book-WIP-4d76ae.svg)](https://pest-parser.github.io/book)
[![Docs](https://docs.rs/pest/badge.svg)](https://docs.rs/pest)
-[![Build Status](https://travis-ci.org/pest-parser/pest.svg?branch=master)](https://travis-ci.org/pest-parser/pest)
+[![pest Continuous Integration](https://github.com/pest-parser/pest/actions/workflows/ci.yml/badge.svg)](https://github.com/pest-parser/pest/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/pest-parser/pest/branch/master/graph/badge.svg)](https://codecov.io/gh/pest-parser/pest)
+<a href="https://blog.rust-lang.org/2021/11/01/Rust-1.56.1.html"><img alt="Rustc Version 1.56.1+" src="https://img.shields.io/badge/rustc-1.56.1%2B-lightgrey.svg"/></a>
+
[![Crates.io](https://img.shields.io/crates/d/pest.svg)](https://crates.io/crates/pest)
[![Crates.io](https://img.shields.io/crates/v/pest.svg)](https://crates.io/crates/pest)
@@ -37,7 +40,7 @@ Other helpful resources:
## Example
-The following is an example of a grammar for a list of alpha-numeric identifiers
+The following is an example of a grammar for a list of alphanumeric identifiers
where the first identifier does not start with a digit:
```rust
@@ -99,19 +102,16 @@ fn main() {
// Because ident_list is silent, the iterator will contain idents
for pair in pairs {
-
- let span = pair.clone().into_span();
// A pair is a combination of the rule which matched and a span of input
println!("Rule: {:?}", pair.as_rule());
- println!("Span: {:?}", span);
- println!("Text: {}", span.as_str());
+ println!("Span: {:?}", pair.as_span());
+ println!("Text: {}", pair.as_str());
// A pair can be converted to an iterator of the tokens which make it up:
for inner_pair in pair.into_inner() {
- let inner_span = inner_pair.clone().into_span();
match inner_pair.as_rule() {
- Rule::alpha => println!("Letter: {}", inner_span.as_str()),
- Rule::digit => println!("Digit: {}", inner_span.as_str()),
+ Rule::alpha => println!("Letter: {}", inner_pair.as_str()),
+ Rule::digit => println!("Digit: {}", inner_pair.as_str()),
_ => unreachable!()
};
}
@@ -143,15 +143,20 @@ Digit: 2
## Projects using pest
* [pest_meta](https://github.com/pest-parser/pest/blob/master/meta/src/grammar.pest) (bootstrapped)
+* [AshPaper](https://github.com/shnewto/ashpaper)
* [brain](https://github.com/brain-lang/brain)
-* [Chelone](https://github.com/Aaronepower/chelone)
+* [cicada](https://github.com/mitnk/cicada)
* [comrak](https://github.com/kivikakk/comrak)
+* [elastic-rs](https://github.com/cch123/elastic-rs)
* [graphql-parser](https://github.com/Keats/graphql-parser)
* [handlebars-rust](https://github.com/sunng87/handlebars-rust)
* [hexdino](https://github.com/Luz/hexdino)
* [Huia](https://gitlab.com/jimsy/huia/)
+* [insta](https://github.com/mitsuhiko/insta)
+* [jql](https://github.com/yamafaktory/jql)
* [json5-rs](https://github.com/callum-oakley/json5-rs)
* [mt940](https://github.com/svenstaro/mt940-rs)
+* [Myoxine](https://github.com/d3bate/myoxine)
* [py_literal](https://github.com/jturner314/py_literal)
* [rouler](https://github.com/jarcane/rouler)
* [RuSh](https://github.com/lwandrebeck/RuSh)
@@ -160,6 +165,18 @@ Digit: 2
* [tera](https://github.com/Keats/tera)
* [ui_gen](https://github.com/emoon/ui_gen)
* [ukhasnet-parser](https://github.com/adamgreig/ukhasnet-parser)
+* [ZoKrates](https://github.com/ZoKrates/ZoKrates)
+* [Vector](https://github.com/timberio/vector)
+* [AutoCorrect](https://github.com/huacnlee/autocorrect)
+* [yaml-peg](https://github.com/aofdev/yaml-peg)
+* [qubit](https://github.com/abhimanyu003/qubit)
+* [caith](https://github.com/Geobert/caith) (a dice roller crate)
+* [Melody](https://github.com/yoav-lavi/melody)
+
+## Minimum Supported Rust Version (MSRV)
+
+This library should always compile with default features on **Rust 1.56.1**
+or **Rust 1.61** with `const_prec_climber`.
## Special thanks
diff --git a/vendor/pest_derive/src/lib.rs b/vendor/pest_derive/src/lib.rs
index f60d5d943..d980c6ae9 100644
--- a/vendor/pest_derive/src/lib.rs
+++ b/vendor/pest_derive/src/lib.rs
@@ -55,7 +55,7 @@
//!
//! Comments start with `//` and end at the end of the line.
//!
-//! ```ignore
+//! ```text
//! // a comment
//! ```
//!
@@ -152,7 +152,7 @@
//!
//! Strings and characters follow
//! [Rust's escape mechanisms](https://doc.rust-lang.org/reference/tokens.html#byte-escapes), while
-//! identifiers can contain alpha-numeric characters and underscores (`_`), as long as they do not
+//! identifiers can contain alphanumeric characters and underscores (`_`), as long as they do not
//! start with a digit.
//!
//! 2. Non-terminals
@@ -266,7 +266,7 @@
//! ```
//!
//! For historical reasons, `PEEK_ALL` matches from top to bottom, while `PEEK[start..end]` matches
-//! from bottom to top. There is currectly no syntax to match a slice of the stack top to bottom.
+//! from bottom to top. There is currently no syntax to match a slice of the stack top to bottom.
//!
//! ## `Rule`
//!
@@ -290,7 +290,6 @@
//! * `NEWLINE` - matches either "\n" or "\r\n" or "\r"
#![doc(html_root_url = "https://docs.rs/pest_derive")]
-
extern crate pest_generator;
extern crate proc_macro;
diff --git a/vendor/pest_derive/tests/grammar.pest b/vendor/pest_derive/tests/grammar.pest
index 43a7b8cfd..126f112d3 100644
--- a/vendor/pest_derive/tests/grammar.pest
+++ b/vendor/pest_derive/tests/grammar.pest
@@ -22,6 +22,7 @@ sequence_atomic_compound = @{ sequence_compound }
sequence_nested = { string ~ string }
sequence_compound_nested = ${ sequence_nested }
choice = { string | range }
+choice_prefix = { | string | range }
optional = { string? }
repeat = { string* }
repeat_atomic = @{ string* }
@@ -36,6 +37,9 @@ repeat_max = { string{, 2} }
repeat_max_atomic = @{ string{, 2} }
soi_at_start = { SOI ~ string }
repeat_mutate_stack = { (PUSH('a'..'c') ~ ",")* ~ POP ~ POP ~ POP }
+repeat_mutate_stack_pop_all = { (PUSH('a'..'c') ~ ",")* ~ POP_ALL }
+will_fail = { repeat_mutate_stack_pop_all ~ "FAIL" }
+stack_resume_after_fail = { will_fail | repeat_mutate_stack_pop_all }
peek_ = { PUSH(range) ~ PUSH(range) ~ PEEK ~ PEEK }
peek_all = { PUSH(range) ~ PUSH(range) ~ PEEK_ALL }
peek_slice_23 = { PUSH(range) ~ PUSH(range) ~ PUSH(range) ~ PUSH(range) ~ PUSH(range) ~ PEEK[1..-2] }
diff --git a/vendor/pest_derive/tests/grammar.rs b/vendor/pest_derive/tests/grammar.rs
index 799beb7e0..57bed9072 100644
--- a/vendor/pest_derive/tests/grammar.rs
+++ b/vendor/pest_derive/tests/grammar.rs
@@ -6,6 +6,9 @@
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
+#![cfg_attr(not(feature = "std"), no_std)]
+extern crate alloc;
+use alloc::{format, vec::Vec};
#[macro_use]
extern crate pest;
@@ -246,6 +249,20 @@ fn choice_range() {
}
#[test]
+fn choice_prefix() {
+ parses_to! {
+ parser: GrammarParser,
+ input: "abc",
+ rule: Rule::choice_prefix,
+ tokens: [
+ choice_prefix(0, 3, [
+ string(0, 3)
+ ])
+ ]
+ };
+}
+
+#[test]
fn optional_string() {
parses_to! {
parser: GrammarParser,
@@ -783,6 +800,20 @@ fn repeat_mutate_stack() {
}
#[test]
+fn stack_resume_after_fail() {
+ parses_to! {
+ parser: GrammarParser,
+ input: "a,b,c,cba",
+ rule: Rule::stack_resume_after_fail,
+ tokens: [
+ stack_resume_after_fail(0, 9, [
+ repeat_mutate_stack_pop_all(0, 9)
+ ])
+ ]
+ };
+}
+
+#[test]
fn checkpoint_restore() {
parses_to! {
parser: GrammarParser,
diff --git a/vendor/pest_derive/tests/grammar_inline.rs b/vendor/pest_derive/tests/grammar_inline.rs
index 2cc730afc..549a8145e 100644
--- a/vendor/pest_derive/tests/grammar_inline.rs
+++ b/vendor/pest_derive/tests/grammar_inline.rs
@@ -4,6 +4,10 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
+#![cfg_attr(not(feature = "std"), no_std)]
+extern crate alloc;
+use alloc::{format, vec::Vec};
+
#[macro_use]
extern crate pest;
#[macro_use]
diff --git a/vendor/pest_derive/tests/lists.rs b/vendor/pest_derive/tests/lists.rs
index 4ba0effce..3678b603b 100644
--- a/vendor/pest_derive/tests/lists.rs
+++ b/vendor/pest_derive/tests/lists.rs
@@ -7,6 +7,10 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
+#![cfg_attr(not(feature = "std"), no_std)]
+extern crate alloc;
+use alloc::{format, vec::Vec};
+
#[macro_use]
extern crate pest;
#[macro_use]
diff --git a/vendor/pest_derive/tests/reporting.rs b/vendor/pest_derive/tests/reporting.rs
index aa0a974e0..8a41bef72 100644
--- a/vendor/pest_derive/tests/reporting.rs
+++ b/vendor/pest_derive/tests/reporting.rs
@@ -7,6 +7,10 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
+#![cfg_attr(not(feature = "std"), no_std)]
+extern crate alloc;
+use alloc::vec;
+
#[macro_use]
extern crate pest;
#[macro_use]
diff --git a/vendor/pest_generator/.cargo-checksum.json b/vendor/pest_generator/.cargo-checksum.json
index 54f869f8e..573d6c49f 100644
--- a/vendor/pest_generator/.cargo-checksum.json
+++ b/vendor/pest_generator/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"0f2f8b8f880c20e4281e53b2675356ee672d7c04b015f4c182509ed2ca614e6e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"e9901b6c4d50403bfda7e08a92b5c395a8c51eba868c7bd07b03e00ccba702f3","src/generator.rs":"7b0b67ec000ccde0ec8df83b26f84e0a7b2a17e255e900ab28379984e7dbba27","src/lib.rs":"1cc63047aad721587a23eeea54d4c398bf5c085d934e41100a8766954a1b6071","src/macros.rs":"03ae0a9ec0210b19c8e6becc275df11b504003d22f3ff758d8bf3ee997d2b476"},"package":"99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"} \ No newline at end of file
+{"files":{"Cargo.toml":"f047138333fb2c65ecd773393f1f61e4778ad467a376b5417d9047c300274be5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"01ba71f02581f9f5018962e083ca77bc8e8af2b6f8a73111bfa04e847a6440e2","src/generator.rs":"51081975a6237bc77cdc4535841c7fbf777e3c466b4c89c821ab68850eeb656a","src/lib.rs":"1cc63047aad721587a23eeea54d4c398bf5c085d934e41100a8766954a1b6071","src/macros.rs":"6522f9b7a2fb172d9ff6ad75c3dcfd547596b5c6ea23f3f5a386220d4f85afa4"},"package":"5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad"} \ No newline at end of file
diff --git a/vendor/pest_generator/Cargo.toml b/vendor/pest_generator/Cargo.toml
index 1ef45f99a..5db0c4b01 100644
--- a/vendor/pest_generator/Cargo.toml
+++ b/vendor/pest_generator/Cargo.toml
@@ -3,30 +3,36 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
+edition = "2018"
+rust-version = "1.56"
name = "pest_generator"
-version = "2.1.3"
+version = "2.3.0"
authors = ["DragoÈ™ Tiselice <dragostiselice@gmail.com>"]
description = "pest code generator"
homepage = "https://pest-parser.github.io/"
documentation = "https://docs.rs/pest"
readme = "_README.md"
-keywords = ["pest", "generator"]
+keywords = [
+ "pest",
+ "generator",
+]
categories = ["parsing"]
license = "MIT/Apache-2.0"
repository = "https://github.com/pest-parser/pest"
+
[dependencies.pest]
-version = "2.1.0"
+version = "2.3.0"
+default-features = false
[dependencies.pest_meta]
-version = "2.1.0"
+version = "2.3.0"
[dependencies.proc-macro2]
version = "1.0"
@@ -36,11 +42,7 @@ version = "1.0"
[dependencies.syn]
version = "1.0"
-[badges.codecov]
-repository = "pest-parser/pest"
-
-[badges.maintenance]
-status = "actively-developed"
-[badges.travis-ci]
-repository = "pest-parser/pest"
+[features]
+default = ["std"]
+std = ["pest/std"]
diff --git a/vendor/pest_generator/_README.md b/vendor/pest_generator/_README.md
index 8e55f29a2..f91188ccb 100644
--- a/vendor/pest_generator/_README.md
+++ b/vendor/pest_generator/_README.md
@@ -1,3 +1,4 @@
+
<p align="center">
<img src="https://raw.github.com/pest-parser/pest/master/pest-logo.svg?sanitize=true" width="80%"/>
</p>
@@ -8,9 +9,10 @@
[![Book](https://img.shields.io/badge/book-WIP-4d76ae.svg)](https://pest-parser.github.io/book)
[![Docs](https://docs.rs/pest/badge.svg)](https://docs.rs/pest)
-[![Build Status](https://travis-ci.org/pest-parser/pest.svg?branch=master)](https://travis-ci.org/pest-parser/pest)
+[![pest Continuous Integration](https://github.com/pest-parser/pest/actions/workflows/ci.yml/badge.svg)](https://github.com/pest-parser/pest/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/pest-parser/pest/branch/master/graph/badge.svg)](https://codecov.io/gh/pest-parser/pest)
-[![Fuzzit Status](https://app.fuzzit.dev/badge?org_id=pest-parser)](https://app.fuzzit.dev/orgs/pest-parser/dashboard)
+<a href="https://blog.rust-lang.org/2021/11/01/Rust-1.56.1.html"><img alt="Rustc Version 1.56.1+" src="https://img.shields.io/badge/rustc-1.56.1%2B-lightgrey.svg"/></a>
+
[![Crates.io](https://img.shields.io/crates/d/pest.svg)](https://crates.io/crates/pest)
[![Crates.io](https://img.shields.io/crates/v/pest.svg)](https://crates.io/crates/pest)
@@ -38,7 +40,7 @@ Other helpful resources:
## Example
-The following is an example of a grammar for a list of alpha-numeric identifiers
+The following is an example of a grammar for a list of alphanumeric identifiers
where the first identifier does not start with a digit:
```rust
@@ -143,16 +145,18 @@ Digit: 2
* [pest_meta](https://github.com/pest-parser/pest/blob/master/meta/src/grammar.pest) (bootstrapped)
* [AshPaper](https://github.com/shnewto/ashpaper)
* [brain](https://github.com/brain-lang/brain)
-* [Chelone](https://github.com/Aaronepower/chelone)
+* [cicada](https://github.com/mitnk/cicada)
* [comrak](https://github.com/kivikakk/comrak)
* [elastic-rs](https://github.com/cch123/elastic-rs)
* [graphql-parser](https://github.com/Keats/graphql-parser)
* [handlebars-rust](https://github.com/sunng87/handlebars-rust)
* [hexdino](https://github.com/Luz/hexdino)
* [Huia](https://gitlab.com/jimsy/huia/)
+* [insta](https://github.com/mitsuhiko/insta)
* [jql](https://github.com/yamafaktory/jql)
* [json5-rs](https://github.com/callum-oakley/json5-rs)
* [mt940](https://github.com/svenstaro/mt940-rs)
+* [Myoxine](https://github.com/d3bate/myoxine)
* [py_literal](https://github.com/jturner314/py_literal)
* [rouler](https://github.com/jarcane/rouler)
* [RuSh](https://github.com/lwandrebeck/RuSh)
@@ -162,6 +166,17 @@ Digit: 2
* [ui_gen](https://github.com/emoon/ui_gen)
* [ukhasnet-parser](https://github.com/adamgreig/ukhasnet-parser)
* [ZoKrates](https://github.com/ZoKrates/ZoKrates)
+* [Vector](https://github.com/timberio/vector)
+* [AutoCorrect](https://github.com/huacnlee/autocorrect)
+* [yaml-peg](https://github.com/aofdev/yaml-peg)
+* [qubit](https://github.com/abhimanyu003/qubit)
+* [caith](https://github.com/Geobert/caith) (a dice roller crate)
+* [Melody](https://github.com/yoav-lavi/melody)
+
+## Minimum Supported Rust Version (MSRV)
+
+This library should always compile with default features on **Rust 1.56.1**
+or **Rust 1.61** with `const_prec_climber`.
## Special thanks
diff --git a/vendor/pest_generator/src/generator.rs b/vendor/pest_generator/src/generator.rs
index bed56f34a..0d3051e27 100644
--- a/vendor/pest_generator/src/generator.rs
+++ b/vendor/pest_generator/src/generator.rs
@@ -17,7 +17,6 @@ use pest_meta::ast::*;
use pest_meta::optimizer::*;
use pest_meta::UNICODE_PROPERTY_NAMES;
-#[allow(clippy::needless_pass_by_value)]
pub fn generate(
name: Ident,
generics: &Generics,
@@ -52,17 +51,20 @@ pub fn generate(
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+ let result = result_type();
+
let parser_impl = quote! {
#[allow(clippy::all)]
impl #impl_generics ::pest::Parser<Rule> for #name #ty_generics #where_clause {
fn parse<'i>(
rule: Rule,
input: &'i str
- ) -> ::std::result::Result<
+ ) -> #result<
::pest::iterators::Pairs<'i, Rule>,
::pest::error::Error<Rule>
> {
mod rules {
+ #![allow(clippy::upper_case_acronyms)]
pub mod hidden {
use super::super::Rule;
#skip
@@ -98,7 +100,7 @@ fn generate_builtin_rules() -> Vec<(&'static str, TokenStream)> {
let mut builtins = Vec::new();
insert_builtin!(builtins, ANY, state.skip(1));
- insert_public_builtin!(
+ insert_builtin!(
builtins,
EOI,
state.rule(Rule::EOI, |state| state.end_of_input())
@@ -149,13 +151,15 @@ fn generate_builtin_rules() -> Vec<(&'static str, TokenStream)> {
.or_else(|state| state.match_string("\r"))
);
+ let box_ty = box_type();
+
for property in UNICODE_PROPERTY_NAMES {
let property_ident: Ident = syn::parse_str(property).unwrap();
// insert manually for #property substitution
builtins.push((property, quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
- fn #property_ident(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ fn #property_ident(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.match_char_by(::pest::unicode::#property_ident)
}
}));
@@ -183,7 +187,7 @@ fn generate_enum(rules: &[OptimizedRule], uses_eoi: bool) -> TokenStream {
.map(|rule| Ident::new(rule.name.as_str(), Span::call_site()));
if uses_eoi {
quote! {
- #[allow(dead_code, non_camel_case_types)]
+ #[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Rule {
EOI,
@@ -192,7 +196,7 @@ fn generate_enum(rules: &[OptimizedRule], uses_eoi: bool) -> TokenStream {
}
} else {
quote! {
- #[allow(dead_code, non_camel_case_types)]
+ #[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Rule {
#( #rules ),*
@@ -239,11 +243,13 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
generate_expr(rule.expr)
};
+ let box_ty = box_type();
+
match rule.ty {
RuleType::Normal => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
- pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.rule(Rule::#name, |state| {
#expr
})
@@ -252,14 +258,14 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
RuleType::Silent => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
- pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
#expr
}
},
RuleType::Atomic => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
- pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.rule(Rule::#name, |state| {
state.atomic(::pest::Atomicity::Atomic, |state| {
#expr
@@ -270,7 +276,7 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
RuleType::CompoundAtomic => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
- pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.atomic(::pest::Atomicity::CompoundAtomic, |state| {
state.rule(Rule::#name, |state| {
#expr
@@ -281,7 +287,7 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
RuleType::NonAtomic => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
- pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.atomic(::pest::Atomicity::NonAtomic, |state| {
state.rule(Rule::#name, |state| {
#expr
@@ -619,13 +625,38 @@ struct QuoteOption<T>(Option<T>);
impl<T: ToTokens> ToTokens for QuoteOption<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
+ let option = option_type();
tokens.append_all(match self.0 {
- Some(ref t) => quote! { ::std::option::Option::Some(#t) },
- None => quote! { ::std::option::Option::None },
+ Some(ref t) => quote! { #option::Some(#t) },
+ None => quote! { #option::None },
});
}
}
+fn box_type() -> TokenStream {
+ #[cfg(feature = "std")]
+ quote! { ::std::boxed::Box }
+
+ #[cfg(not(feature = "std"))]
+ quote! { ::alloc::boxed::Box }
+}
+
+fn result_type() -> TokenStream {
+ #[cfg(feature = "std")]
+ quote! { ::std::result::Result }
+
+ #[cfg(not(feature = "std"))]
+ quote! { ::core::result::Result }
+}
+
+fn option_type() -> TokenStream {
+ #[cfg(feature = "std")]
+ quote! { ::std::option::Option }
+
+ #[cfg(not(feature = "std"))]
+ quote! { ::core::option::Option }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -641,7 +672,7 @@ mod tests {
assert_eq!(
generate_enum(&rules, false).to_string(),
quote! {
- #[allow(dead_code, non_camel_case_types)]
+ #[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Rule {
f
@@ -935,6 +966,8 @@ mod tests {
expr: OptimizedExpr::Str("b".to_owned()),
}];
let defaults = vec!["ANY"];
+ let result = result_type();
+ let box_ty = box_type();
let mut current_dir = std::env::current_dir().expect("Unable to get current directory");
current_dir.push("test.pest");
let test_path = current_dir.to_str().expect("path contains invalid unicode");
@@ -944,7 +977,7 @@ mod tests {
#[allow(non_upper_case_globals)]
const _PEST_GRAMMAR_MyParser: &'static str = include_str!(#test_path);
- #[allow(dead_code, non_camel_case_types)]
+ #[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Rule {
a
@@ -955,17 +988,18 @@ mod tests {
fn parse<'i>(
rule: Rule,
input: &'i str
- ) -> ::std::result::Result<
+ ) -> #result<
::pest::iterators::Pairs<'i, Rule>,
::pest::error::Error<Rule>
> {
mod rules {
+ #![allow(clippy::upper_case_acronyms)]
pub mod hidden {
use super::super::Rule;
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
- pub fn skip(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn skip(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
Ok(state)
}
}
@@ -975,13 +1009,13 @@ mod tests {
#[inline]
#[allow(non_snake_case, unused_variables)]
- pub fn a(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn a(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.match_string("b")
}
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
- pub fn ANY(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn ANY(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.skip(1)
}
}
diff --git a/vendor/pest_generator/src/macros.rs b/vendor/pest_generator/src/macros.rs
index 9d02725da..37ef531f3 100644
--- a/vendor/pest_generator/src/macros.rs
+++ b/vendor/pest_generator/src/macros.rs
@@ -13,30 +13,26 @@ macro_rules! insert_builtin {
};
}
-macro_rules! insert_public_builtin {
- ($builtin: expr, $name: ident, $pattern: expr) => {
- $builtin.push((stringify!($name), generate_public_rule!($name, $pattern)));
- };
-}
-
+#[cfg(feature = "std")]
macro_rules! generate_rule {
($name: ident, $pattern: expr) => {
quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
- pub fn $name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn $name(state: ::std::boxed::Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState<Rule>>> {
$pattern
}
}
}
}
-macro_rules! generate_public_rule {
+#[cfg(not(feature = "std"))]
+macro_rules! generate_rule {
($name: ident, $pattern: expr) => {
quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
- pub fn $name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
+ pub fn $name(state: ::alloc::boxed::Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<::alloc::boxed::Box<::pest::ParserState<Rule>>> {
$pattern
}
}
diff --git a/vendor/pest_meta/.cargo-checksum.json b/vendor/pest_meta/.cargo-checksum.json
index f51cb5967..5a98eadb3 100644
--- a/vendor/pest_meta/.cargo-checksum.json
+++ b/vendor/pest_meta/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"adf86f275ddc1ae02311ab5e1b51a165dc034edf466fc74dea6cbe63fe80d9b3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"e9901b6c4d50403bfda7e08a92b5c395a8c51eba868c7bd07b03e00ccba702f3","src/ast.rs":"b2d0b054d66525b6c9ceed7a9b24cabcdd1074b525b230fc99a1a31019010f58","src/grammar.pest":"fac55bde3f3b59058293d220fec96ef033e61cb24fc032cad21d76aa6f963bc1","src/grammar.rs":"eb8f1f0c964467c081564de8830f3db4966499311868127342b9b651e8cee06f","src/lib.rs":"b248cf6bc5d4a8537f682c23f8d2c8910eb764ee5f1cc02b2c344b0b920943da","src/optimizer/concatenator.rs":"94c2a79d39ebeddbc413d30f2c20d0b50ae2c0e2e86bff90a029b70aa028e2fc","src/optimizer/factorizer.rs":"84df67d6e3f1b507b3e970cb8fba1ab9e2254c3ba778c4a0cf100452b36f1e08","src/optimizer/mod.rs":"69f25916112cbfa4b3d2225f8af463a03ebe706ae757d9c97be523c5601d7b3c","src/optimizer/restorer.rs":"182561b972752ec961fa45d0ca705a9852462010003e4e1ab646e5cd486bedd1","src/optimizer/rotater.rs":"e59f6c3e9197dc3cb4f21edf0c5ffb1a2638a81e4ce9b0373a2d2147a12a3bd5","src/optimizer/skipper.rs":"ab52c7a44a35aefcd1546da5e2084af642c472f07565dcb1be1bb3e2b5fc5a41","src/optimizer/unroller.rs":"99b4940906b0eb443a8b0bf6499130098d59a8141f2693ec50a653cb21c534d5","src/parser.rs":"04a93b2d36bcf199cbc5ab3e943a85cc1730529af83bb3f4a1a9f6b80e2eda4a","src/validator.rs":"5436c0cafc8fa91e45e4988e280220057c8f43ec7a796491abb8e9b22f80582d"},"package":"54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"} \ No newline at end of file
+{"files":{"Cargo.toml":"3673efe1bf8eb36b5ae86959a918a846040826779babf8729a2725d651a6d035","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","_README.md":"01ba71f02581f9f5018962e083ca77bc8e8af2b6f8a73111bfa04e847a6440e2","src/ast.rs":"782e31c3e3ad194209975d9515b5df42883f7b7e316cd342e4603bcd5b3ec8d6","src/grammar.pest":"697e32f6fee403c3199317404891481b13dee127b956d6c3ec5a6a6116d18921","src/grammar.rs":"ed08400f1d37fee264359077666a02df0b6ac0d52500040b1157957502ab04ad","src/lib.rs":"8773adeac67a4c7de66f129f0d88fcf88748acc9a44b32949d7e1a3bcd338448","src/optimizer/concatenator.rs":"b77e6ec1d4d79d5383c74435d86e888a048c134fc5cff250356de9405e0ecfab","src/optimizer/factorizer.rs":"ffe510cc8c33fdb89c2a4e575f4d54f7894f126e71e6ae010d9614679d26254e","src/optimizer/lister.rs":"706812c52df72753071bf2db039dffb1061c1a0f030e4c1af67302c632ff15cd","src/optimizer/mod.rs":"18daf1ee2e6789ee4c9afddd34e1081364c7b30b2163ca0c6bf843fee865420e","src/optimizer/restorer.rs":"8b65cfe7dfd4d812bee6ac3cdbcc3d0026e03fd2b456a7c866dd83e6fdbf26a7","src/optimizer/rotater.rs":"7256bc8c01a09c5489fdb8d1cc52461bcc5ccf826db478b1420b01473b9b6c62","src/optimizer/skipper.rs":"8a7cd27713c8ffc795a82471242225b5fbbecec221c75fe8ac48e878d5a6088e","src/optimizer/unroller.rs":"f4010f2bf3b2bb0740d17b04c73f772284f576bfb57b9cac16b98293168ffb7a","src/parser.rs":"11b030a345afb092d1a66cf1481c6653f3d192e585632fbe8fa5641b771e5236","src/validator.rs":"97be65d88cc064c0857deb3ab73c3373560882e454c6ed2cd6a4a9d8d773beaf"},"package":"1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04"} \ No newline at end of file
diff --git a/vendor/pest_meta/Cargo.toml b/vendor/pest_meta/Cargo.toml
index 74f837745..347b7db37 100644
--- a/vendor/pest_meta/Cargo.toml
+++ b/vendor/pest_meta/Cargo.toml
@@ -3,40 +3,46 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
+edition = "2018"
+rust-version = "1.56"
name = "pest_meta"
-version = "2.1.3"
+version = "2.3.0"
authors = ["DragoÈ™ Tiselice <dragostiselice@gmail.com>"]
exclude = ["src/grammar.pest"]
-include = ["Cargo.toml", "src/**/*", "src/grammar.rs", "_README.md", "LICENSE-*"]
+include = [
+ "Cargo.toml",
+ "src/**/*",
+ "src/grammar.rs",
+ "_README.md",
+ "LICENSE-*",
+]
description = "pest meta language parser and validator"
homepage = "https://pest-parser.github.io/"
documentation = "https://docs.rs/pest"
readme = "_README.md"
-keywords = ["pest", "parser", "meta", "optimizer"]
+keywords = [
+ "pest",
+ "parser",
+ "meta",
+ "optimizer",
+]
categories = ["parsing"]
license = "MIT/Apache-2.0"
repository = "https://github.com/pest-parser/pest"
-[dependencies.maplit]
-version = "1.0"
+
+[dependencies.once_cell]
+version = "1.8.0"
[dependencies.pest]
-version = "2.1.0"
+version = "2.3.0"
+
[build-dependencies.sha-1]
-version = "0.8"
+version = "0.10"
default-features = false
-[badges.codecov]
-repository = "pest-parser/pest"
-
-[badges.maintenance]
-status = "actively-developed"
-
-[badges.travis-ci]
-repository = "pest-parser/pest"
diff --git a/vendor/pest_meta/_README.md b/vendor/pest_meta/_README.md
index 8e55f29a2..f91188ccb 100644
--- a/vendor/pest_meta/_README.md
+++ b/vendor/pest_meta/_README.md
@@ -1,3 +1,4 @@
+
<p align="center">
<img src="https://raw.github.com/pest-parser/pest/master/pest-logo.svg?sanitize=true" width="80%"/>
</p>
@@ -8,9 +9,10 @@
[![Book](https://img.shields.io/badge/book-WIP-4d76ae.svg)](https://pest-parser.github.io/book)
[![Docs](https://docs.rs/pest/badge.svg)](https://docs.rs/pest)
-[![Build Status](https://travis-ci.org/pest-parser/pest.svg?branch=master)](https://travis-ci.org/pest-parser/pest)
+[![pest Continuous Integration](https://github.com/pest-parser/pest/actions/workflows/ci.yml/badge.svg)](https://github.com/pest-parser/pest/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/pest-parser/pest/branch/master/graph/badge.svg)](https://codecov.io/gh/pest-parser/pest)
-[![Fuzzit Status](https://app.fuzzit.dev/badge?org_id=pest-parser)](https://app.fuzzit.dev/orgs/pest-parser/dashboard)
+<a href="https://blog.rust-lang.org/2021/11/01/Rust-1.56.1.html"><img alt="Rustc Version 1.56.1+" src="https://img.shields.io/badge/rustc-1.56.1%2B-lightgrey.svg"/></a>
+
[![Crates.io](https://img.shields.io/crates/d/pest.svg)](https://crates.io/crates/pest)
[![Crates.io](https://img.shields.io/crates/v/pest.svg)](https://crates.io/crates/pest)
@@ -38,7 +40,7 @@ Other helpful resources:
## Example
-The following is an example of a grammar for a list of alpha-numeric identifiers
+The following is an example of a grammar for a list of alphanumeric identifiers
where the first identifier does not start with a digit:
```rust
@@ -143,16 +145,18 @@ Digit: 2
* [pest_meta](https://github.com/pest-parser/pest/blob/master/meta/src/grammar.pest) (bootstrapped)
* [AshPaper](https://github.com/shnewto/ashpaper)
* [brain](https://github.com/brain-lang/brain)
-* [Chelone](https://github.com/Aaronepower/chelone)
+* [cicada](https://github.com/mitnk/cicada)
* [comrak](https://github.com/kivikakk/comrak)
* [elastic-rs](https://github.com/cch123/elastic-rs)
* [graphql-parser](https://github.com/Keats/graphql-parser)
* [handlebars-rust](https://github.com/sunng87/handlebars-rust)
* [hexdino](https://github.com/Luz/hexdino)
* [Huia](https://gitlab.com/jimsy/huia/)
+* [insta](https://github.com/mitsuhiko/insta)
* [jql](https://github.com/yamafaktory/jql)
* [json5-rs](https://github.com/callum-oakley/json5-rs)
* [mt940](https://github.com/svenstaro/mt940-rs)
+* [Myoxine](https://github.com/d3bate/myoxine)
* [py_literal](https://github.com/jturner314/py_literal)
* [rouler](https://github.com/jarcane/rouler)
* [RuSh](https://github.com/lwandrebeck/RuSh)
@@ -162,6 +166,17 @@ Digit: 2
* [ui_gen](https://github.com/emoon/ui_gen)
* [ukhasnet-parser](https://github.com/adamgreig/ukhasnet-parser)
* [ZoKrates](https://github.com/ZoKrates/ZoKrates)
+* [Vector](https://github.com/timberio/vector)
+* [AutoCorrect](https://github.com/huacnlee/autocorrect)
+* [yaml-peg](https://github.com/aofdev/yaml-peg)
+* [qubit](https://github.com/abhimanyu003/qubit)
+* [caith](https://github.com/Geobert/caith) (a dice roller crate)
+* [Melody](https://github.com/yoav-lavi/melody)
+
+## Minimum Supported Rust Version (MSRV)
+
+This library should always compile with default features on **Rust 1.56.1**
+or **Rust 1.61** with `const_prec_climber`.
## Special thanks
diff --git a/vendor/pest_meta/src/ast.rs b/vendor/pest_meta/src/ast.rs
index b80c59630..da6ee5278 100644
--- a/vendor/pest_meta/src/ast.rs
+++ b/vendor/pest_meta/src/ast.rs
@@ -280,7 +280,7 @@ mod tests {
Box::new(Expr::Str(String::from("a"))),
Box::new(Expr::Str(String::from("b"))),
);
- let mut top_down = expr.clone().iter_top_down();
+ let mut top_down = expr.iter_top_down();
assert_eq!(top_down.next(), Some(expr));
assert_eq!(top_down.next(), Some(Expr::Str(String::from("a"))));
assert_eq!(top_down.next(), Some(Expr::Str(String::from("b"))));
diff --git a/vendor/pest_meta/src/grammar.pest b/vendor/pest_meta/src/grammar.pest
index 0d03ba899..282ca35b8 100644
--- a/vendor/pest_meta/src/grammar.pest
+++ b/vendor/pest_meta/src/grammar.pest
@@ -34,7 +34,7 @@ atomic_modifier = { "@" }
compound_atomic_modifier = { "$" }
non_atomic_modifier = { "!" }
-expression = { term ~ (infix_operator ~ term)* }
+expression = { choice_operator? ~ term ~ (infix_operator ~ term)* }
term = { prefix_operator* ~ node ~ postfix_operator* }
node = _{ opening_paren ~ expression ~ closing_paren | terminal }
terminal = _{ _push | peek_slice | identifier | string | insensitive_string | range }
diff --git a/vendor/pest_meta/src/grammar.rs b/vendor/pest_meta/src/grammar.rs
index bf94a1e3a..e42982b06 100644
--- a/vendor/pest_meta/src/grammar.rs
+++ b/vendor/pest_meta/src/grammar.rs
@@ -1,2 +1,2 @@
pub struct PestParser;
-# [ allow ( dead_code , non_camel_case_types ) ] # [ derive ( Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ] pub enum Rule { EOI , grammar_rules , grammar_rule , assignment_operator , opening_brace , closing_brace , opening_paren , closing_paren , opening_brack , closing_brack , modifier , silent_modifier , atomic_modifier , compound_atomic_modifier , non_atomic_modifier , expression , term , node , terminal , prefix_operator , infix_operator , postfix_operator , positive_predicate_operator , negative_predicate_operator , sequence_operator , choice_operator , optional_operator , repeat_operator , repeat_once_operator , repeat_exact , repeat_min , repeat_max , repeat_min_max , number , integer , comma , _push , peek_slice , identifier , alpha , alpha_num , string , insensitive_string , range , character , inner_str , inner_chr , escape , code , unicode , hex_digit , quote , single_quote , range_operator , newline , WHITESPACE , block_comment , COMMENT } # [ allow ( clippy :: all ) ] impl :: pest :: Parser < Rule > for PestParser { fn parse < 'i > ( rule : Rule , input : & 'i str ) -> :: std :: result :: Result < :: pest :: iterators :: Pairs < 'i , Rule > , :: pest :: error :: Error < Rule > > { mod rules { pub mod hidden { use super :: super :: Rule ; # [ inline ] # [ allow ( dead_code , non_snake_case , unused_variables ) ] pub fn skip ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { if state . atomicity ( ) == :: pest :: Atomicity :: NonAtomic { state . sequence ( | state | { state . repeat ( | state | super :: visible :: WHITESPACE ( state ) ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { super :: visible :: COMMENT ( state ) . and_then ( | state | { state . repeat ( | state | super :: visible :: WHITESPACE ( state ) ) } ) } ) } ) } ) } ) } else { Ok ( state ) } } } pub mod visible { use super :: super :: Rule ; # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn grammar_rules ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . sequence ( | state | { self :: SOI ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . sequence ( | state | { self :: grammar_rule ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . sequence ( | state | { state . optional ( | state | { self :: grammar_rule ( state ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { super :: hidden :: skip ( state ) . and_then ( | state | { self :: grammar_rule ( state ) } ) } ) } ) } ) } ) } ) } ) } ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: EOI ( state ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn grammar_rule ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: grammar_rule , | state | { state . sequence ( | state | { self :: identifier ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: assignment_operator ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . optional ( | state | { self :: modifier ( state ) } ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: opening_brace ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: expression ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_brace ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn assignment_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: assignment_operator , | state | { state . match_string ( "=" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn opening_brace ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: opening_brace , | state | { state . match_string ( "{" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn closing_brace ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: closing_brace , | state | { state . match_string ( "}" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn opening_paren ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: opening_paren , | state | { state . match_string ( "(" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn closing_paren ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: closing_paren , | state | { state . match_string ( ")" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn opening_brack ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: opening_brack , | state | { state . match_string ( "[" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn closing_brack ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: closing_brack , | state | { state . match_string ( "]" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn modifier ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { self :: silent_modifier ( state ) . or_else ( | state | { self :: atomic_modifier ( state ) } ) . or_else ( | state | { self :: compound_atomic_modifier ( state ) } ) . or_else ( | state | { self :: non_atomic_modifier ( state ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn silent_modifier ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: silent_modifier , | state | { state . match_string ( "_" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn atomic_modifier ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: atomic_modifier , | state | { state . match_string ( "@" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn compound_atomic_modifier ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: compound_atomic_modifier , | state | { state . match_string ( "$" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn non_atomic_modifier ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: non_atomic_modifier , | state | { state . match_string ( "!" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn expression ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: expression , | state | { state . sequence ( | state | { self :: term ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . sequence ( | state | { state . optional ( | state | { state . sequence ( | state | { self :: infix_operator ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: term ( state ) } ) } ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { super :: hidden :: skip ( state ) . and_then ( | state | { state . sequence ( | state | { self :: infix_operator ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: term ( state ) } ) } ) } ) } ) } ) } ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn term ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: term , | state | { state . sequence ( | state | { state . sequence ( | state | { state . optional ( | state | { self :: prefix_operator ( state ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { super :: hidden :: skip ( state ) . and_then ( | state | { self :: prefix_operator ( state ) } ) } ) } ) } ) } ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: node ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . sequence ( | state | { state . optional ( | state | { self :: postfix_operator ( state ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { super :: hidden :: skip ( state ) . and_then ( | state | { self :: postfix_operator ( state ) } ) } ) } ) } ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn node ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . sequence ( | state | { self :: opening_paren ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: expression ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_paren ( state ) } ) } ) . or_else ( | state | { self :: terminal ( state ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn terminal ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { self :: _push ( state ) . or_else ( | state | { self :: peek_slice ( state ) } ) . or_else ( | state | { self :: identifier ( state ) } ) . or_else ( | state | { self :: string ( state ) } ) . or_else ( | state | { self :: insensitive_string ( state ) } ) . or_else ( | state | { self :: range ( state ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn prefix_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { self :: positive_predicate_operator ( state ) . or_else ( | state | { self :: negative_predicate_operator ( state ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn infix_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { self :: sequence_operator ( state ) . or_else ( | state | { self :: choice_operator ( state ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn postfix_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { self :: optional_operator ( state ) . or_else ( | state | { self :: repeat_operator ( state ) } ) . or_else ( | state | { self :: repeat_once_operator ( state ) } ) . or_else ( | state | { self :: repeat_exact ( state ) } ) . or_else ( | state | { self :: repeat_min ( state ) } ) . or_else ( | state | { self :: repeat_max ( state ) } ) . or_else ( | state | { self :: repeat_min_max ( state ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn positive_predicate_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: positive_predicate_operator , | state | { state . match_string ( "&" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn negative_predicate_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: negative_predicate_operator , | state | { state . match_string ( "!" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn sequence_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: sequence_operator , | state | { state . match_string ( "~" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn choice_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: choice_operator , | state | { state . match_string ( "|" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn optional_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: optional_operator , | state | { state . match_string ( "?" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn repeat_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: repeat_operator , | state | { state . match_string ( "*" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn repeat_once_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: repeat_once_operator , | state | { state . match_string ( "+" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn repeat_exact ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: repeat_exact , | state | { state . sequence ( | state | { self :: opening_brace ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: number ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_brace ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn repeat_min ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: repeat_min , | state | { state . sequence ( | state | { self :: opening_brace ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: number ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: comma ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_brace ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn repeat_max ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: repeat_max , | state | { state . sequence ( | state | { self :: opening_brace ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: comma ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: number ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_brace ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn repeat_min_max ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: repeat_min_max , | state | { state . sequence ( | state | { self :: opening_brace ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: number ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: comma ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: number ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_brace ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn number ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: number , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . sequence ( | state | { state . match_range ( '0' .. '9' ) . and_then ( | state | { state . repeat ( | state | { state . match_range ( '0' .. '9' ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn integer ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: integer , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { self :: number ( state ) . or_else ( | state | { state . sequence ( | state | { state . match_string ( "-" ) . and_then ( | state | { state . repeat ( | state | { state . match_string ( "0" ) } ) } ) . and_then ( | state | { state . match_range ( '1' .. '9' ) } ) . and_then ( | state | { state . optional ( | state | { self :: number ( state ) } ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn comma ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: comma , | state | { state . match_string ( "," ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn _push ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: _push , | state | { state . sequence ( | state | { state . match_string ( "PUSH" ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: opening_paren ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: expression ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_paren ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn peek_slice ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: peek_slice , | state | { state . sequence ( | state | { state . match_string ( "PEEK" ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: opening_brack ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . optional ( | state | { self :: integer ( state ) } ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: range_operator ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . optional ( | state | { self :: integer ( state ) } ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: closing_brack ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn identifier ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: identifier , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . sequence ( | state | { state . lookahead ( false , | state | { state . match_string ( "PUSH" ) } ) . and_then ( | state | { state . match_string ( "_" ) . or_else ( | state | { self :: alpha ( state ) } ) } ) . and_then ( | state | { state . repeat ( | state | { state . match_string ( "_" ) . or_else ( | state | { self :: alpha_num ( state ) } ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn alpha ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . match_range ( 'a' .. 'z' ) . or_else ( | state | { state . match_range ( 'A' .. 'Z' ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn alpha_num ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { self :: alpha ( state ) . or_else ( | state | { state . match_range ( '0' .. '9' ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn string ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . atomic ( :: pest :: Atomicity :: CompoundAtomic , | state | { state . rule ( Rule :: string , | state | { state . sequence ( | state | { self :: quote ( state ) . and_then ( | state | { self :: inner_str ( state ) } ) . and_then ( | state | { self :: quote ( state ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn insensitive_string ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: insensitive_string , | state | { state . sequence ( | state | { state . match_string ( "^" ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: string ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn range ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: range , | state | { state . sequence ( | state | { self :: character ( state ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: range_operator ( state ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: character ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn character ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . atomic ( :: pest :: Atomicity :: CompoundAtomic , | state | { state . rule ( Rule :: character , | state | { state . sequence ( | state | { self :: single_quote ( state ) . and_then ( | state | { self :: inner_chr ( state ) } ) . and_then ( | state | { self :: single_quote ( state ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn inner_str ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: inner_str , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . sequence ( | state | { let strings = [ "\"" , "\\" ] ; state . skip_until ( & strings ) . and_then ( | state | { state . optional ( | state | { state . sequence ( | state | { self :: escape ( state ) . and_then ( | state | { self :: inner_str ( state ) } ) } ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn inner_chr ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: inner_chr , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { self :: escape ( state ) . or_else ( | state | { self :: ANY ( state ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn escape ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: escape , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . sequence ( | state | { state . match_string ( "\\" ) . and_then ( | state | { state . match_string ( "\"" ) . or_else ( | state | { state . match_string ( "\\" ) } ) . or_else ( | state | { state . match_string ( "r" ) } ) . or_else ( | state | { state . match_string ( "n" ) } ) . or_else ( | state | { state . match_string ( "t" ) } ) . or_else ( | state | { state . match_string ( "0" ) } ) . or_else ( | state | { state . match_string ( "'" ) } ) . or_else ( | state | { self :: code ( state ) } ) . or_else ( | state | { self :: unicode ( state ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn code ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: code , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . sequence ( | state | { state . match_string ( "x" ) . and_then ( | state | { self :: hex_digit ( state ) } ) . and_then ( | state | { self :: hex_digit ( state ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn unicode ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: unicode , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . sequence ( | state | { state . match_string ( "u" ) . and_then ( | state | { self :: opening_brace ( state ) } ) . and_then ( | state | { state . sequence ( | state | { self :: hex_digit ( state ) . and_then ( | state | { self :: hex_digit ( state ) } ) . and_then ( | state | { state . optional ( | state | { self :: hex_digit ( state ) } ) } ) . and_then ( | state | { state . optional ( | state | { self :: hex_digit ( state ) } ) } ) . and_then ( | state | { state . optional ( | state | { self :: hex_digit ( state ) } ) } ) . and_then ( | state | { state . optional ( | state | { self :: hex_digit ( state ) } ) } ) } ) } ) . and_then ( | state | { self :: closing_brace ( state ) } ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn hex_digit ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: hex_digit , | state | { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . match_range ( '0' .. '9' ) . or_else ( | state | { state . match_range ( 'a' .. 'f' ) } ) . or_else ( | state | { state . match_range ( 'A' .. 'F' ) } ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn quote ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: quote , | state | { state . match_string ( "\"" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn single_quote ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: single_quote , | state | { state . match_string ( "'" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn range_operator ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: range_operator , | state | { state . match_string ( ".." ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn newline ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . match_string ( "\n" ) . or_else ( | state | { state . match_string ( "\r\n" ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn WHITESPACE ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { state . match_string ( " " ) . or_else ( | state | { state . match_string ( "\t" ) } ) . or_else ( | state | { self :: newline ( state ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn block_comment ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . sequence ( | state | { state . match_string ( "/*" ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . sequence ( | state | { state . optional ( | state | { self :: block_comment ( state ) . or_else ( | state | { state . sequence ( | state | { state . lookahead ( false , | state | { state . match_string ( "*/" ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: ANY ( state ) } ) } ) } ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { super :: hidden :: skip ( state ) . and_then ( | state | { self :: block_comment ( state ) . or_else ( | state | { state . sequence ( | state | { state . lookahead ( false , | state | { state . match_string ( "*/" ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { self :: ANY ( state ) } ) } ) } ) } ) } ) } ) } ) } ) } ) } ) . and_then ( | state | { super :: hidden :: skip ( state ) } ) . and_then ( | state | { state . match_string ( "*/" ) } ) } ) } # [ inline ] # [ allow ( non_snake_case , unused_variables ) ] pub fn COMMENT ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . atomic ( :: pest :: Atomicity :: Atomic , | state | { self :: block_comment ( state ) . or_else ( | state | { state . sequence ( | state | { state . match_string ( "//" ) . and_then ( | state | { state . repeat ( | state | { state . sequence ( | state | { state . lookahead ( false , | state | { self :: newline ( state ) } ) . and_then ( | state | { self :: ANY ( state ) } ) } ) } ) } ) } ) } ) } ) } # [ inline ] # [ allow ( dead_code , non_snake_case , unused_variables ) ] pub fn SOI ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . start_of_input ( ) } # [ inline ] # [ allow ( dead_code , non_snake_case , unused_variables ) ] pub fn ANY ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . skip ( 1 ) } # [ inline ] # [ allow ( dead_code , non_snake_case , unused_variables ) ] pub fn EOI ( state : Box < :: pest :: ParserState < Rule >> ) -> :: pest :: ParseResult < Box < :: pest :: ParserState < Rule >> > { state . rule ( Rule :: EOI , | state | state . end_of_input ( ) ) } } pub use self :: visible :: * ; } :: pest :: state ( input , | state | { match rule { Rule :: grammar_rules => rules :: grammar_rules ( state ) , Rule :: grammar_rule => rules :: grammar_rule ( state ) , Rule :: assignment_operator => rules :: assignment_operator ( state ) , Rule :: opening_brace => rules :: opening_brace ( state ) , Rule :: closing_brace => rules :: closing_brace ( state ) , Rule :: opening_paren => rules :: opening_paren ( state ) , Rule :: closing_paren => rules :: closing_paren ( state ) , Rule :: opening_brack => rules :: opening_brack ( state ) , Rule :: closing_brack => rules :: closing_brack ( state ) , Rule :: modifier => rules :: modifier ( state ) , Rule :: silent_modifier => rules :: silent_modifier ( state ) , Rule :: atomic_modifier => rules :: atomic_modifier ( state ) , Rule :: compound_atomic_modifier => rules :: compound_atomic_modifier ( state ) , Rule :: non_atomic_modifier => rules :: non_atomic_modifier ( state ) , Rule :: expression => rules :: expression ( state ) , Rule :: term => rules :: term ( state ) , Rule :: node => rules :: node ( state ) , Rule :: terminal => rules :: terminal ( state ) , Rule :: prefix_operator => rules :: prefix_operator ( state ) , Rule :: infix_operator => rules :: infix_operator ( state ) , Rule :: postfix_operator => rules :: postfix_operator ( state ) , Rule :: positive_predicate_operator => rules :: positive_predicate_operator ( state ) , Rule :: negative_predicate_operator => rules :: negative_predicate_operator ( state ) , Rule :: sequence_operator => rules :: sequence_operator ( state ) , Rule :: choice_operator => rules :: choice_operator ( state ) , Rule :: optional_operator => rules :: optional_operator ( state ) , Rule :: repeat_operator => rules :: repeat_operator ( state ) , Rule :: repeat_once_operator => rules :: repeat_once_operator ( state ) , Rule :: repeat_exact => rules :: repeat_exact ( state ) , Rule :: repeat_min => rules :: repeat_min ( state ) , Rule :: repeat_max => rules :: repeat_max ( state ) , Rule :: repeat_min_max => rules :: repeat_min_max ( state ) , Rule :: number => rules :: number ( state ) , Rule :: integer => rules :: integer ( state ) , Rule :: comma => rules :: comma ( state ) , Rule :: _push => rules :: _push ( state ) , Rule :: peek_slice => rules :: peek_slice ( state ) , Rule :: identifier => rules :: identifier ( state ) , Rule :: alpha => rules :: alpha ( state ) , Rule :: alpha_num => rules :: alpha_num ( state ) , Rule :: string => rules :: string ( state ) , Rule :: insensitive_string => rules :: insensitive_string ( state ) , Rule :: range => rules :: range ( state ) , Rule :: character => rules :: character ( state ) , Rule :: inner_str => rules :: inner_str ( state ) , Rule :: inner_chr => rules :: inner_chr ( state ) , Rule :: escape => rules :: escape ( state ) , Rule :: code => rules :: code ( state ) , Rule :: unicode => rules :: unicode ( state ) , Rule :: hex_digit => rules :: hex_digit ( state ) , Rule :: quote => rules :: quote ( state ) , Rule :: single_quote => rules :: single_quote ( state ) , Rule :: range_operator => rules :: range_operator ( state ) , Rule :: newline => rules :: newline ( state ) , Rule :: WHITESPACE => rules :: WHITESPACE ( state ) , Rule :: block_comment => rules :: block_comment ( state ) , Rule :: COMMENT => rules :: COMMENT ( state ) , Rule :: EOI => rules :: EOI ( state ) } } ) } }
+# [allow (dead_code , non_camel_case_types , clippy :: upper_case_acronyms)] # [derive (Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd)] pub enum Rule { EOI , grammar_rules , grammar_rule , assignment_operator , opening_brace , closing_brace , opening_paren , closing_paren , opening_brack , closing_brack , modifier , silent_modifier , atomic_modifier , compound_atomic_modifier , non_atomic_modifier , expression , term , node , terminal , prefix_operator , infix_operator , postfix_operator , positive_predicate_operator , negative_predicate_operator , sequence_operator , choice_operator , optional_operator , repeat_operator , repeat_once_operator , repeat_exact , repeat_min , repeat_max , repeat_min_max , number , integer , comma , _push , peek_slice , identifier , alpha , alpha_num , string , insensitive_string , range , character , inner_str , inner_chr , escape , code , unicode , hex_digit , quote , single_quote , range_operator , newline , WHITESPACE , block_comment , COMMENT } # [allow (clippy :: all)] impl :: pest :: Parser < Rule > for PestParser { fn parse < 'i > (rule : Rule , input : & 'i str) -> :: std :: result :: Result < :: pest :: iterators :: Pairs < 'i , Rule > , :: pest :: error :: Error < Rule > > { mod rules { # ! [allow (clippy :: upper_case_acronyms)] pub mod hidden { use super :: super :: Rule ; # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn skip (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { if state . atomicity () == :: pest :: Atomicity :: NonAtomic { state . sequence (| state | { state . repeat (| state | super :: visible :: WHITESPACE (state)) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: visible :: COMMENT (state) . and_then (| state | { state . repeat (| state | super :: visible :: WHITESPACE (state)) }) }) }) }) }) } else { Ok (state) } } } pub mod visible { use super :: super :: Rule ; # [inline] # [allow (non_snake_case , unused_variables)] pub fn grammar_rules (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . sequence (| state | { self :: SOI (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: grammar_rule (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: grammar_rule (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: grammar_rule (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: EOI (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn grammar_rule (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: grammar_rule , | state | { state . sequence (| state | { self :: identifier (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: assignment_operator (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: modifier (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: opening_brace (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: expression (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_brace (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn assignment_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: assignment_operator , | state | { state . match_string ("=") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn opening_brace (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: opening_brace , | state | { state . match_string ("{") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn closing_brace (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: closing_brace , | state | { state . match_string ("}") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn opening_paren (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: opening_paren , | state | { state . match_string ("(") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn closing_paren (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: closing_paren , | state | { state . match_string (")") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn opening_brack (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: opening_brack , | state | { state . match_string ("[") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn closing_brack (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: closing_brack , | state | { state . match_string ("]") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn modifier (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { self :: silent_modifier (state) . or_else (| state | { self :: atomic_modifier (state) }) . or_else (| state | { self :: compound_atomic_modifier (state) }) . or_else (| state | { self :: non_atomic_modifier (state) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn silent_modifier (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: silent_modifier , | state | { state . match_string ("_") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn atomic_modifier (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: atomic_modifier , | state | { state . match_string ("@") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn compound_atomic_modifier (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: compound_atomic_modifier , | state | { state . match_string ("$") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn non_atomic_modifier (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: non_atomic_modifier , | state | { state . match_string ("!") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn expression (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: expression , | state | { state . sequence (| state | { state . optional (| state | { self :: choice_operator (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: term (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { state . sequence (| state | { self :: infix_operator (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: term (state) }) }) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { state . sequence (| state | { self :: infix_operator (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: term (state) }) }) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn term (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: term , | state | { state . sequence (| state | { state . sequence (| state | { state . optional (| state | { self :: prefix_operator (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: prefix_operator (state) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: node (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: postfix_operator (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: postfix_operator (state) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn node (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . sequence (| state | { self :: opening_paren (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: expression (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_paren (state) }) }) . or_else (| state | { self :: terminal (state) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn terminal (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { self :: _push (state) . or_else (| state | { self :: peek_slice (state) }) . or_else (| state | { self :: identifier (state) }) . or_else (| state | { self :: string (state) }) . or_else (| state | { self :: insensitive_string (state) }) . or_else (| state | { self :: range (state) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn prefix_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { self :: positive_predicate_operator (state) . or_else (| state | { self :: negative_predicate_operator (state) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn infix_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { self :: sequence_operator (state) . or_else (| state | { self :: choice_operator (state) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn postfix_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { self :: optional_operator (state) . or_else (| state | { self :: repeat_operator (state) }) . or_else (| state | { self :: repeat_once_operator (state) }) . or_else (| state | { self :: repeat_exact (state) }) . or_else (| state | { self :: repeat_min (state) }) . or_else (| state | { self :: repeat_max (state) }) . or_else (| state | { self :: repeat_min_max (state) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn positive_predicate_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: positive_predicate_operator , | state | { state . match_string ("&") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn negative_predicate_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: negative_predicate_operator , | state | { state . match_string ("!") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn sequence_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: sequence_operator , | state | { state . match_string ("~") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn choice_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: choice_operator , | state | { state . match_string ("|") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn optional_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: optional_operator , | state | { state . match_string ("?") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn repeat_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: repeat_operator , | state | { state . match_string ("*") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn repeat_once_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: repeat_once_operator , | state | { state . match_string ("+") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn repeat_exact (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: repeat_exact , | state | { state . sequence (| state | { self :: opening_brace (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: number (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_brace (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn repeat_min (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: repeat_min , | state | { state . sequence (| state | { self :: opening_brace (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: number (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: comma (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_brace (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn repeat_max (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: repeat_max , | state | { state . sequence (| state | { self :: opening_brace (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: comma (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: number (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_brace (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn repeat_min_max (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: repeat_min_max , | state | { state . sequence (| state | { self :: opening_brace (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: number (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: comma (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: number (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_brace (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn number (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: number , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { state . match_range ('0' .. '9') . and_then (| state | { state . repeat (| state | { state . match_range ('0' .. '9') }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn integer (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: integer , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { self :: number (state) . or_else (| state | { state . sequence (| state | { state . match_string ("-") . and_then (| state | { state . repeat (| state | { state . match_string ("0") }) }) . and_then (| state | { state . match_range ('1' .. '9') }) . and_then (| state | { state . optional (| state | { self :: number (state) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn comma (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: comma , | state | { state . match_string (",") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn _push (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: _push , | state | { state . sequence (| state | { state . match_string ("PUSH") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: opening_paren (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: expression (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_paren (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn peek_slice (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: peek_slice , | state | { state . sequence (| state | { state . match_string ("PEEK") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: opening_brack (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: integer (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: range_operator (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: integer (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: closing_brack (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn identifier (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: identifier , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { state . lookahead (false , | state | { state . match_string ("PUSH") }) . and_then (| state | { state . match_string ("_") . or_else (| state | { self :: alpha (state) }) }) . and_then (| state | { state . repeat (| state | { state . match_string ("_") . or_else (| state | { self :: alpha_num (state) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn alpha (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . match_range ('a' .. 'z') . or_else (| state | { state . match_range ('A' .. 'Z') }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn alpha_num (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { self :: alpha (state) . or_else (| state | { state . match_range ('0' .. '9') }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn string (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: CompoundAtomic , | state | { state . rule (Rule :: string , | state | { state . sequence (| state | { self :: quote (state) . and_then (| state | { self :: inner_str (state) }) . and_then (| state | { self :: quote (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn insensitive_string (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: insensitive_string , | state | { state . sequence (| state | { state . match_string ("^") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: string (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn range (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: range , | state | { state . sequence (| state | { self :: character (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: range_operator (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: character (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn character (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: CompoundAtomic , | state | { state . rule (Rule :: character , | state | { state . sequence (| state | { self :: single_quote (state) . and_then (| state | { self :: inner_chr (state) }) . and_then (| state | { self :: single_quote (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn inner_str (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: inner_str , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { let strings = ["\"" , "\\"] ; state . skip_until (& strings) . and_then (| state | { state . optional (| state | { state . sequence (| state | { self :: escape (state) . and_then (| state | { self :: inner_str (state) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn inner_chr (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: inner_chr , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { self :: escape (state) . or_else (| state | { self :: ANY (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn escape (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: escape , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { state . match_string ("\\") . and_then (| state | { state . match_string ("\"") . or_else (| state | { state . match_string ("\\") }) . or_else (| state | { state . match_string ("r") }) . or_else (| state | { state . match_string ("n") }) . or_else (| state | { state . match_string ("t") }) . or_else (| state | { state . match_string ("0") }) . or_else (| state | { state . match_string ("'") }) . or_else (| state | { self :: code (state) }) . or_else (| state | { self :: unicode (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn code (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: code , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { state . match_string ("x") . and_then (| state | { self :: hex_digit (state) }) . and_then (| state | { self :: hex_digit (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn unicode (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: unicode , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { state . match_string ("u") . and_then (| state | { self :: opening_brace (state) }) . and_then (| state | { state . sequence (| state | { self :: hex_digit (state) . and_then (| state | { self :: hex_digit (state) }) . and_then (| state | { state . optional (| state | { self :: hex_digit (state) }) }) . and_then (| state | { state . optional (| state | { self :: hex_digit (state) }) }) . and_then (| state | { state . optional (| state | { self :: hex_digit (state) }) }) . and_then (| state | { state . optional (| state | { self :: hex_digit (state) }) }) }) }) . and_then (| state | { self :: closing_brace (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn hex_digit (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: hex_digit , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . match_range ('0' .. '9') . or_else (| state | { state . match_range ('a' .. 'f') }) . or_else (| state | { state . match_range ('A' .. 'F') }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn quote (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: quote , | state | { state . match_string ("\"") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn single_quote (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: single_quote , | state | { state . match_string ("'") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn range_operator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: range_operator , | state | { state . match_string ("..") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn newline (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . match_string ("\n") . or_else (| state | { state . match_string ("\r\n") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn WHITESPACE (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . match_string (" ") . or_else (| state | { state . match_string ("\t") }) . or_else (| state | { self :: newline (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn block_comment (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . sequence (| state | { state . match_string ("/*") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: block_comment (state) . or_else (| state | { state . sequence (| state | { state . lookahead (false , | state | { state . match_string ("*/") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ANY (state) }) }) }) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: block_comment (state) . or_else (| state | { state . sequence (| state | { state . lookahead (false , | state | { state . match_string ("*/") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ANY (state) }) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("*/") }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn COMMENT (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: Atomic , | state | { self :: block_comment (state) . or_else (| state | { state . sequence (| state | { state . match_string ("//") . and_then (| state | { state . repeat (| state | { state . sequence (| state | { state . lookahead (false , | state | { self :: newline (state) }) . and_then (| state | { self :: ANY (state) }) }) }) }) }) }) }) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn ANY (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . skip (1) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn EOI (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: EOI , | state | state . end_of_input ()) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn SOI (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . start_of_input () } } pub use self :: visible :: * ; } :: pest :: state (input , | state | { match rule { Rule :: grammar_rules => rules :: grammar_rules (state) , Rule :: grammar_rule => rules :: grammar_rule (state) , Rule :: assignment_operator => rules :: assignment_operator (state) , Rule :: opening_brace => rules :: opening_brace (state) , Rule :: closing_brace => rules :: closing_brace (state) , Rule :: opening_paren => rules :: opening_paren (state) , Rule :: closing_paren => rules :: closing_paren (state) , Rule :: opening_brack => rules :: opening_brack (state) , Rule :: closing_brack => rules :: closing_brack (state) , Rule :: modifier => rules :: modifier (state) , Rule :: silent_modifier => rules :: silent_modifier (state) , Rule :: atomic_modifier => rules :: atomic_modifier (state) , Rule :: compound_atomic_modifier => rules :: compound_atomic_modifier (state) , Rule :: non_atomic_modifier => rules :: non_atomic_modifier (state) , Rule :: expression => rules :: expression (state) , Rule :: term => rules :: term (state) , Rule :: node => rules :: node (state) , Rule :: terminal => rules :: terminal (state) , Rule :: prefix_operator => rules :: prefix_operator (state) , Rule :: infix_operator => rules :: infix_operator (state) , Rule :: postfix_operator => rules :: postfix_operator (state) , Rule :: positive_predicate_operator => rules :: positive_predicate_operator (state) , Rule :: negative_predicate_operator => rules :: negative_predicate_operator (state) , Rule :: sequence_operator => rules :: sequence_operator (state) , Rule :: choice_operator => rules :: choice_operator (state) , Rule :: optional_operator => rules :: optional_operator (state) , Rule :: repeat_operator => rules :: repeat_operator (state) , Rule :: repeat_once_operator => rules :: repeat_once_operator (state) , Rule :: repeat_exact => rules :: repeat_exact (state) , Rule :: repeat_min => rules :: repeat_min (state) , Rule :: repeat_max => rules :: repeat_max (state) , Rule :: repeat_min_max => rules :: repeat_min_max (state) , Rule :: number => rules :: number (state) , Rule :: integer => rules :: integer (state) , Rule :: comma => rules :: comma (state) , Rule :: _push => rules :: _push (state) , Rule :: peek_slice => rules :: peek_slice (state) , Rule :: identifier => rules :: identifier (state) , Rule :: alpha => rules :: alpha (state) , Rule :: alpha_num => rules :: alpha_num (state) , Rule :: string => rules :: string (state) , Rule :: insensitive_string => rules :: insensitive_string (state) , Rule :: range => rules :: range (state) , Rule :: character => rules :: character (state) , Rule :: inner_str => rules :: inner_str (state) , Rule :: inner_chr => rules :: inner_chr (state) , Rule :: escape => rules :: escape (state) , Rule :: code => rules :: code (state) , Rule :: unicode => rules :: unicode (state) , Rule :: hex_digit => rules :: hex_digit (state) , Rule :: quote => rules :: quote (state) , Rule :: single_quote => rules :: single_quote (state) , Rule :: range_operator => rules :: range_operator (state) , Rule :: newline => rules :: newline (state) , Rule :: WHITESPACE => rules :: WHITESPACE (state) , Rule :: block_comment => rules :: block_comment (state) , Rule :: COMMENT => rules :: COMMENT (state) , Rule :: EOI => rules :: EOI (state) } }) } }
diff --git a/vendor/pest_meta/src/lib.rs b/vendor/pest_meta/src/lib.rs
index 1f9c5bcb6..4e178be6f 100644
--- a/vendor/pest_meta/src/lib.rs
+++ b/vendor/pest_meta/src/lib.rs
@@ -7,9 +7,7 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-#![allow(clippy::range_plus_one)]
-
-extern crate maplit;
+extern crate once_cell;
#[cfg(test)]
#[macro_use]
extern crate pest;
@@ -30,18 +28,19 @@ where
{
result.unwrap_or_else(|e| {
panic!(
- "grammar error\n\n".to_owned()
- + &e.into_iter()
- .map(|error| format!("{}", error))
- .collect::<Vec<_>>()
- .join("\n\n")
+ "grammar error\n\n{}",
+ &e.into_iter()
+ .map(|error| format!("{}", error))
+ .collect::<Vec<_>>()
+ .join("\n\n")
)
})
}
#[doc(hidden)]
pub static UNICODE_PROPERTY_NAMES: &[&str] = &[
- /* BINARY */ "ALPHABETIC",
+ /* BINARY */
+ "ALPHABETIC",
"BIDI_CONTROL",
"CASE_IGNORABLE",
"CASED",
@@ -93,7 +92,8 @@ pub static UNICODE_PROPERTY_NAMES: &[&str] = &[
"WHITE_SPACE",
"XID_CONTINUE",
"XID_START",
- /* CATEGORY */ "CASED_LETTER",
+ /* CATEGORY */
+ "CASED_LETTER",
"CLOSE_PUNCTUATION",
"CONNECTOR_PUNCTUATION",
"CONTROL",
diff --git a/vendor/pest_meta/src/optimizer/concatenator.rs b/vendor/pest_meta/src/optimizer/concatenator.rs
index e0aab7bc1..31d3aa531 100644
--- a/vendor/pest_meta/src/optimizer/concatenator.rs
+++ b/vendor/pest_meta/src/optimizer/concatenator.rs
@@ -7,28 +7,27 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use ast::*;
+use crate::ast::*;
pub fn concatenate(rule: Rule) -> Rule {
- match rule {
- Rule { name, ty, expr } => Rule {
- name,
- ty,
- expr: expr.map_bottom_up(|expr| {
- if ty == RuleType::Atomic {
- // TODO: Use box syntax when it gets stabilized.
- match expr {
- Expr::Seq(lhs, rhs) => match (*lhs, *rhs) {
- (Expr::Str(lhs), Expr::Str(rhs)) => Expr::Str(lhs + &rhs),
- (Expr::Insens(lhs), Expr::Insens(rhs)) => Expr::Insens(lhs + &rhs),
- (lhs, rhs) => Expr::Seq(Box::new(lhs), Box::new(rhs)),
- },
- expr => expr,
- }
- } else {
- expr
+ let Rule { name, ty, expr } = rule;
+ Rule {
+ name,
+ ty,
+ expr: expr.map_bottom_up(|expr| {
+ if ty == RuleType::Atomic {
+ // TODO: Use box syntax when it gets stabilized.
+ match expr {
+ Expr::Seq(lhs, rhs) => match (*lhs, *rhs) {
+ (Expr::Str(lhs), Expr::Str(rhs)) => Expr::Str(lhs + &rhs),
+ (Expr::Insens(lhs), Expr::Insens(rhs)) => Expr::Insens(lhs + &rhs),
+ (lhs, rhs) => Expr::Seq(Box::new(lhs), Box::new(rhs)),
+ },
+ expr => expr,
}
- }),
- },
+ } else {
+ expr
+ }
+ }),
}
}
diff --git a/vendor/pest_meta/src/optimizer/factorizer.rs b/vendor/pest_meta/src/optimizer/factorizer.rs
index 236289e14..5481870bf 100644
--- a/vendor/pest_meta/src/optimizer/factorizer.rs
+++ b/vendor/pest_meta/src/optimizer/factorizer.rs
@@ -7,32 +7,45 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use ast::*;
+use crate::ast::*;
pub fn factor(rule: Rule) -> Rule {
- match rule {
- Rule { name, ty, expr } => Rule {
- name,
- ty,
- expr: expr.map_top_down(|expr| {
- // TODO: Use box syntax when it gets stabilized.
- match expr {
- Expr::Choice(lhs, rhs) => match (*lhs, *rhs) {
- (Expr::Seq(l1, r1), Expr::Seq(l2, r2)) => {
- if l1 == l2 {
- Expr::Seq(l1, Box::new(Expr::Choice(r1, r2)))
- } else {
- Expr::Choice(
- Box::new(Expr::Seq(l1, r1)),
- Box::new(Expr::Seq(l2, r2)),
- )
- }
+ let Rule { name, ty, expr } = rule;
+ Rule {
+ name,
+ ty,
+ expr: expr.map_top_down(|expr| {
+ // TODO: Use box syntax when it gets stabilized.
+ match expr {
+ Expr::Choice(lhs, rhs) => match (*lhs, *rhs) {
+ (Expr::Seq(l1, r1), Expr::Seq(l2, r2)) => {
+ if l1 == l2 {
+ Expr::Seq(l1, Box::new(Expr::Choice(r1, r2)))
+ } else {
+ Expr::Choice(Box::new(Expr::Seq(l1, r1)), Box::new(Expr::Seq(l2, r2)))
}
- (lhs, rhs) => Expr::Choice(Box::new(lhs), Box::new(rhs)),
- },
- expr => expr,
- }
- }),
- },
+ }
+ // Converts `(rule ~ rest) | rule` to `rule ~ rest?`, avoiding trying to match `rule` twice.
+ (Expr::Seq(l1, l2), r) => {
+ if *l1 == r {
+ Expr::Seq(l1, Box::new(Expr::Opt(l2)))
+ } else {
+ Expr::Choice(Box::new(Expr::Seq(l1, l2)), Box::new(r))
+ }
+ }
+ // Converts `rule | (rule ~ rest)` to `rule` since `(rule ~ rest)`
+ // will never match if `rule` didn't.
+ (l, Expr::Seq(r1, r2)) => {
+ if l == *r1 {
+ l
+ } else {
+ Expr::Choice(Box::new(l), Box::new(Expr::Seq(r1, r2)))
+ }
+ }
+ (lhs, rhs) => Expr::Choice(Box::new(lhs), Box::new(rhs)),
+ },
+ expr => expr,
+ }
+ }),
}
}
diff --git a/vendor/pest_meta/src/optimizer/lister.rs b/vendor/pest_meta/src/optimizer/lister.rs
new file mode 100644
index 000000000..e19885032
--- /dev/null
+++ b/vendor/pest_meta/src/optimizer/lister.rs
@@ -0,0 +1,42 @@
+// pest. The Elegant Parser
+// Copyright (c) 2018 DragoÈ™ Tiselice
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+use crate::ast::*;
+
+pub fn list(rule: Rule) -> Rule {
+ let Rule { name, ty, expr } = rule;
+ Rule {
+ name,
+ ty,
+ expr: expr.map_bottom_up(|expr| {
+ // TODO: Use box syntax when it gets stabilized.
+ match expr {
+ Expr::Seq(l, r) => match *l {
+ Expr::Rep(l) => {
+ let l = *l;
+ match l {
+ Expr::Seq(l1, l2) => {
+ // Converts `(rule ~ rest)* ~ rule` to `rule ~ (rest ~ rule)*`,
+ // avoiding matching the last `rule` twice.
+ if l1 == r {
+ Expr::Seq(l1, Box::new(Expr::Rep(Box::new(Expr::Seq(l2, r)))))
+ } else {
+ Expr::Seq(Box::new(Expr::Rep(Box::new(Expr::Seq(l1, l2)))), r)
+ }
+ }
+ expr => Expr::Seq(Box::new(Expr::Rep(Box::new(expr))), r),
+ }
+ }
+ expr => Expr::Seq(Box::new(expr), r),
+ },
+ expr => expr,
+ }
+ }),
+ }
+}
diff --git a/vendor/pest_meta/src/optimizer/mod.rs b/vendor/pest_meta/src/optimizer/mod.rs
index 7013c43f9..e0cbdb0de 100644
--- a/vendor/pest_meta/src/optimizer/mod.rs
+++ b/vendor/pest_meta/src/optimizer/mod.rs
@@ -7,7 +7,7 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use ast::*;
+use crate::ast::*;
use std::collections::HashMap;
#[cfg(test)]
@@ -20,6 +20,7 @@ macro_rules! box_tree {
mod concatenator;
mod factorizer;
+mod lister;
mod restorer;
mod rotater;
mod skipper;
@@ -33,6 +34,7 @@ pub fn optimize(rules: Vec<Rule>) -> Vec<OptimizedRule> {
.map(unroller::unroll)
.map(concatenator::concatenate)
.map(factorizer::factor)
+ .map(lister::list)
.map(rule_to_optimized_rule)
.collect();
@@ -279,7 +281,7 @@ mod tests {
#[test]
fn rotate() {
let rules = {
- use ast::Expr::*;
+ use crate::ast::Expr::*;
vec![Rule {
name: "rule".to_owned(),
ty: RuleType::Normal,
@@ -293,7 +295,7 @@ mod tests {
}]
};
let rotated = {
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
vec![OptimizedRule {
name: "rule".to_owned(),
ty: RuleType::Normal,
@@ -313,7 +315,7 @@ mod tests {
#[test]
fn skip() {
let rules = {
- use ast::Expr::*;
+ use crate::ast::Expr::*;
vec![Rule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -335,7 +337,7 @@ mod tests {
#[test]
fn concat_strings() {
let rules = {
- use ast::Expr::*;
+ use crate::ast::Expr::*;
vec![Rule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -362,7 +364,7 @@ mod tests {
expr: Expr::RepExact(Box::new(Expr::Ident(String::from("a"))), 3),
}];
let unrolled = {
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
vec![OptimizedRule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -384,7 +386,7 @@ mod tests {
expr: Expr::RepMax(Box::new(Expr::Str("a".to_owned())), 3),
}];
let unrolled = {
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
vec![OptimizedRule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -406,7 +408,7 @@ mod tests {
expr: Expr::RepMin(Box::new(Expr::Str("a".to_owned())), 2),
}];
let unrolled = {
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
vec![OptimizedRule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -428,7 +430,7 @@ mod tests {
expr: Expr::RepMinMax(Box::new(Expr::Str("a".to_owned())), 2, 3),
}];
let unrolled = {
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
vec![OptimizedRule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -452,7 +454,7 @@ mod tests {
#[test]
fn concat_insensitive_strings() {
let rules = {
- use ast::Expr::*;
+ use crate::ast::Expr::*;
vec![Rule {
name: "rule".to_owned(),
ty: RuleType::Atomic,
@@ -474,7 +476,7 @@ mod tests {
#[test]
fn long_common_sequence() {
let rules = {
- use ast::Expr::*;
+ use crate::ast::Expr::*;
vec![Rule {
name: "rule".to_owned(),
ty: RuleType::Silent,
@@ -491,7 +493,7 @@ mod tests {
}]
};
let optimized = {
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
vec![OptimizedRule {
name: "rule".to_owned(),
ty: RuleType::Silent,
@@ -507,4 +509,82 @@ mod tests {
assert_eq!(optimize(rules), optimized);
}
+
+ #[test]
+ fn short_common_sequence() {
+ let rules = {
+ use crate::ast::Expr::*;
+ vec![Rule {
+ name: "rule".to_owned(),
+ ty: RuleType::Silent,
+ expr: box_tree!(Choice(
+ Seq(Ident(String::from("a")), Ident(String::from("b"))),
+ Ident(String::from("a"))
+ )),
+ }]
+ };
+ let optimized = {
+ use crate::optimizer::OptimizedExpr::*;
+ vec![OptimizedRule {
+ name: "rule".to_owned(),
+ ty: RuleType::Silent,
+ expr: box_tree!(Seq(Ident(String::from("a")), Opt(Ident(String::from("b"))))),
+ }]
+ };
+
+ assert_eq!(optimize(rules), optimized);
+ }
+
+ #[test]
+ fn impossible_common_sequence() {
+ let rules = {
+ use crate::ast::Expr::*;
+ vec![Rule {
+ name: "rule".to_owned(),
+ ty: RuleType::Silent,
+ expr: box_tree!(Choice(
+ Ident(String::from("a")),
+ Seq(Ident(String::from("a")), Ident(String::from("b")))
+ )),
+ }]
+ };
+ let optimized = {
+ use crate::optimizer::OptimizedExpr::*;
+ vec![OptimizedRule {
+ name: "rule".to_owned(),
+ ty: RuleType::Silent,
+ expr: box_tree!(Ident(String::from("a"))),
+ }]
+ };
+
+ assert_eq!(optimize(rules), optimized);
+ }
+
+ #[test]
+ fn lister() {
+ let rules = {
+ use crate::ast::Expr::*;
+ vec![Rule {
+ name: "rule".to_owned(),
+ ty: RuleType::Silent,
+ expr: box_tree!(Seq(
+ Rep(Seq(Ident(String::from("a")), Ident(String::from("b")))),
+ Ident(String::from("a"))
+ )),
+ }]
+ };
+ let optimized = {
+ use crate::optimizer::OptimizedExpr::*;
+ vec![OptimizedRule {
+ name: "rule".to_owned(),
+ ty: RuleType::Silent,
+ expr: box_tree!(Seq(
+ Ident(String::from("a")),
+ Rep(Seq(Ident(String::from("b")), Ident(String::from("a"))))
+ )),
+ }]
+ };
+
+ assert_eq!(optimize(rules), optimized);
+ }
}
diff --git a/vendor/pest_meta/src/optimizer/restorer.rs b/vendor/pest_meta/src/optimizer/restorer.rs
index 34a710eab..e128e03f1 100644
--- a/vendor/pest_meta/src/optimizer/restorer.rs
+++ b/vendor/pest_meta/src/optimizer/restorer.rs
@@ -8,19 +8,15 @@
// modified, or distributed except according to those terms.
use std::collections::HashMap;
-use optimizer::*;
+use crate::optimizer::*;
pub fn restore_on_err(
rule: OptimizedRule,
rules: &HashMap<String, OptimizedExpr>,
) -> OptimizedRule {
- match rule {
- OptimizedRule { name, ty, expr } => {
- let expr = expr.map_bottom_up(|expr| wrap_branching_exprs(expr, rules));
-
- OptimizedRule { name, ty, expr }
- }
- }
+ let OptimizedRule { name, ty, expr } = rule;
+ let expr = expr.map_bottom_up(|expr| wrap_branching_exprs(expr, rules));
+ OptimizedRule { name, ty, expr }
}
fn wrap_branching_exprs(
@@ -96,7 +92,7 @@ fn child_modifies_state(
#[cfg(test)]
mod tests {
use super::*;
- use optimizer::OptimizedExpr::*;
+ use crate::optimizer::OptimizedExpr::*;
#[test]
fn restore_no_stack_children() {
diff --git a/vendor/pest_meta/src/optimizer/rotater.rs b/vendor/pest_meta/src/optimizer/rotater.rs
index 3588738ad..7a7d8fba4 100644
--- a/vendor/pest_meta/src/optimizer/rotater.rs
+++ b/vendor/pest_meta/src/optimizer/rotater.rs
@@ -7,7 +7,7 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use ast::*;
+use crate::ast::*;
pub fn rotate(rule: Rule) -> Rule {
fn rotate_internal(expr: Expr) -> Expr {
@@ -35,11 +35,10 @@ pub fn rotate(rule: Rule) -> Rule {
}
}
- match rule {
- Rule { name, ty, expr } => Rule {
- name,
- ty,
- expr: expr.map_top_down(rotate_internal),
- },
+ let Rule { name, ty, expr } = rule;
+ Rule {
+ name,
+ ty,
+ expr: expr.map_top_down(rotate_internal),
}
}
diff --git a/vendor/pest_meta/src/optimizer/skipper.rs b/vendor/pest_meta/src/optimizer/skipper.rs
index f55edc06f..40bc5a16f 100644
--- a/vendor/pest_meta/src/optimizer/skipper.rs
+++ b/vendor/pest_meta/src/optimizer/skipper.rs
@@ -7,7 +7,7 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use ast::*;
+use crate::ast::*;
pub fn skip(rule: Rule) -> Rule {
fn populate_choices(expr: Expr, mut choices: Vec<String>) -> Option<Expr> {
@@ -28,30 +28,29 @@ pub fn skip(rule: Rule) -> Rule {
}
}
- match rule {
- Rule { name, ty, expr } => Rule {
- name,
- ty,
- expr: if ty == RuleType::Atomic {
- expr.map_top_down(|expr| {
- // TODO: Use box syntax when it gets stabilized.
- if let Expr::Rep(expr) = expr.clone() {
- if let Expr::Seq(lhs, rhs) = *expr.clone() {
- if let (Expr::NegPred(expr), Expr::Ident(ident)) = (*lhs, *rhs) {
- if ident == "ANY" {
- if let Some(expr) = populate_choices(*expr, vec![]) {
- return expr;
- }
+ let Rule { name, ty, expr } = rule;
+ Rule {
+ name,
+ ty,
+ expr: if ty == RuleType::Atomic {
+ expr.map_top_down(|expr| {
+ // TODO: Use box syntax when it gets stabilized.
+ if let Expr::Rep(expr) = expr.clone() {
+ if let Expr::Seq(lhs, rhs) = *expr {
+ if let (Expr::NegPred(expr), Expr::Ident(ident)) = (*lhs, *rhs) {
+ if ident == "ANY" {
+ if let Some(expr) = populate_choices(*expr, vec![]) {
+ return expr;
}
}
}
- };
+ }
+ };
- expr
- })
- } else {
expr
- },
+ })
+ } else {
+ expr
},
}
}
diff --git a/vendor/pest_meta/src/optimizer/unroller.rs b/vendor/pest_meta/src/optimizer/unroller.rs
index fff17336d..e3c360d90 100644
--- a/vendor/pest_meta/src/optimizer/unroller.rs
+++ b/vendor/pest_meta/src/optimizer/unroller.rs
@@ -7,61 +7,60 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-use ast::*;
+use crate::ast::*;
pub fn unroll(rule: Rule) -> Rule {
- match rule {
- Rule { name, ty, expr } => Rule {
- name,
- ty,
- expr: expr.map_bottom_up(|expr| match expr {
- Expr::RepOnce(expr) => Expr::Seq(expr.clone(), Box::new(Expr::Rep(expr))),
- Expr::RepExact(expr, num) => (1..num + 1)
- .map(|_| *expr.clone())
- .rev()
- .fold(None, |rep, expr| match rep {
- None => Some(expr),
- Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
- })
- .unwrap(),
- Expr::RepMin(expr, min) => (1..min + 2)
- .map(|i| {
- if i <= min {
- *expr.clone()
- } else {
- Expr::Rep(expr.clone())
- }
- })
- .rev()
- .fold(None, |rep, expr| match rep {
- None => Some(expr),
- Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
- })
- .unwrap(),
- Expr::RepMax(expr, max) => (1..max + 1)
- .map(|_| Expr::Opt(expr.clone()))
- .rev()
- .fold(None, |rep, expr| match rep {
- None => Some(expr),
- Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
- })
- .unwrap(),
- Expr::RepMinMax(expr, min, max) => (1..max + 1)
- .map(|i| {
- if i <= min {
- *expr.clone()
- } else {
- Expr::Opt(expr.clone())
- }
- })
- .rev()
- .fold(None, |rep, expr| match rep {
- None => Some(expr),
- Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
- })
- .unwrap(),
- expr => expr,
- }),
- },
+ let Rule { name, ty, expr } = rule;
+ Rule {
+ name,
+ ty,
+ expr: expr.map_bottom_up(|expr| match expr {
+ Expr::RepOnce(expr) => Expr::Seq(expr.clone(), Box::new(Expr::Rep(expr))),
+ Expr::RepExact(expr, num) => (1..num + 1)
+ .map(|_| *expr.clone())
+ .rev()
+ .fold(None, |rep, expr| match rep {
+ None => Some(expr),
+ Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
+ })
+ .unwrap(),
+ Expr::RepMin(expr, min) => (1..min + 2)
+ .map(|i| {
+ if i <= min {
+ *expr.clone()
+ } else {
+ Expr::Rep(expr.clone())
+ }
+ })
+ .rev()
+ .fold(None, |rep, expr| match rep {
+ None => Some(expr),
+ Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
+ })
+ .unwrap(),
+ Expr::RepMax(expr, max) => (1..max + 1)
+ .map(|_| Expr::Opt(expr.clone()))
+ .rev()
+ .fold(None, |rep, expr| match rep {
+ None => Some(expr),
+ Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
+ })
+ .unwrap(),
+ Expr::RepMinMax(expr, min, max) => (1..max + 1)
+ .map(|i| {
+ if i <= min {
+ *expr.clone()
+ } else {
+ Expr::Opt(expr.clone())
+ }
+ })
+ .rev()
+ .fold(None, |rep, expr| match rep {
+ None => Some(expr),
+ Some(rep) => Some(Expr::Seq(Box::new(expr), Box::new(rep))),
+ })
+ .unwrap(),
+ expr => expr,
+ }),
}
}
diff --git a/vendor/pest_meta/src/parser.rs b/vendor/pest_meta/src/parser.rs
index 5f6f3b374..72abd810d 100644
--- a/vendor/pest_meta/src/parser.rs
+++ b/vendor/pest_meta/src/parser.rs
@@ -15,10 +15,14 @@ use pest::iterators::{Pair, Pairs};
use pest::prec_climber::{Assoc, Operator, PrecClimber};
use pest::{Parser, Span};
-use ast::{Expr, Rule as AstRule, RuleType};
-use validator;
+use crate::ast::{Expr, Rule as AstRule, RuleType};
+use crate::validator;
-include!("grammar.rs");
+mod grammar {
+ include!("grammar.rs");
+}
+
+pub use self::grammar::*;
pub fn parse(rule: Rule, data: &str) -> Result<Pairs<Rule>, Error<Rule>> {
PestParser::parse(rule, data)
@@ -125,13 +129,9 @@ pub enum ParserExpr<'i> {
}
fn convert_rule(rule: ParserRule) -> AstRule {
- match rule {
- ParserRule { name, ty, node, .. } => {
- let expr = convert_node(node);
-
- AstRule { name, ty, expr }
- }
- }
+ let ParserRule { name, ty, node, .. } = rule;
+ let expr = convert_node(node);
+ AstRule { name, ty, expr }
}
fn convert_node(node: ParserNode) -> Expr {
@@ -174,9 +174,7 @@ pub fn consume_rules(pairs: Pairs<Rule>) -> Result<Vec<AstRule>, Vec<Error<Rule>
}
}
-fn consume_rules_with_spans<'i>(
- pairs: Pairs<'i, Rule>,
-) -> Result<Vec<ParserRule<'i>>, Vec<Error<Rule>>> {
+fn consume_rules_with_spans(pairs: Pairs<Rule>) -> Result<Vec<ParserRule>, Vec<Error<Rule>>> {
let climber = PrecClimber::new(vec![
Operator::new(Rule::choice_operator, Assoc::Left),
Operator::new(Rule::sequence_operator, Assoc::Left),
@@ -206,7 +204,13 @@ fn consume_rules_with_spans<'i>(
pairs.next().unwrap(); // opening_brace
- let node = consume_expr(pairs.next().unwrap().into_inner().peekable(), &climber)?;
+ // skip initial infix operators
+ let mut inner_nodes = pairs.next().unwrap().into_inner().peekable();
+ if inner_nodes.peek().unwrap().as_rule() == Rule::choice_operator {
+ inner_nodes.next().unwrap();
+ }
+
+ let node = consume_expr(inner_nodes, &climber)?;
Ok(ParserRule {
name,
@@ -617,6 +621,8 @@ fn unescape(string: &str) -> Option<String> {
#[cfg(test)]
mod tests {
+ use std::convert::TryInto;
+
use super::super::unwrap_or_report;
use super::*;
@@ -1073,7 +1079,7 @@ mod tests {
parser: PestParser,
input: "a = {}",
rule: Rule::grammar_rules,
- positives: vec![Rule::term],
+ positives: vec![Rule::expression],
negatives: vec![],
pos: 5
};
@@ -1092,6 +1098,18 @@ mod tests {
}
#[test]
+ fn incorrect_prefix() {
+ fails_with! {
+ parser: PestParser,
+ input: "a = { ~ b}",
+ rule: Rule::grammar_rules,
+ positives: vec![Rule::expression],
+ negatives: vec![],
+ pos: 6
+ };
+ }
+
+ #[test]
fn wrong_op() {
fails_with! {
parser: PestParser,
@@ -1228,7 +1246,7 @@ mod tests {
let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
let ast = consume_rules_with_spans(pairs).unwrap();
- let ast: Vec<_> = ast.into_iter().map(|rule| convert_rule(rule)).collect();
+ let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
assert_eq!(
ast,
@@ -1266,7 +1284,7 @@ mod tests {
let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
let ast = consume_rules_with_spans(pairs).unwrap();
- let ast: Vec<_> = ast.into_iter().map(|rule| convert_rule(rule)).collect();
+ let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
assert_eq!(
ast,
@@ -1485,4 +1503,45 @@ mod tests {
assert_eq!(unescape(string), None);
}
+
+ #[test]
+ fn handles_deep_nesting() {
+ let sample1 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample1.grammar"
+ ));
+ let sample2 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample2.grammar"
+ ));
+ let sample3 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample3.grammar"
+ ));
+ let sample4 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample4.grammar"
+ ));
+ let sample5 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample5.grammar"
+ ));
+ const ERROR: &str = "call limit reached";
+ pest::set_call_limit(Some(5_000usize.try_into().unwrap()));
+ let s1 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample1);
+ assert!(s1.is_err());
+ assert_eq!(s1.unwrap_err().variant.message(), ERROR);
+ let s2 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample2);
+ assert!(s2.is_err());
+ assert_eq!(s2.unwrap_err().variant.message(), ERROR);
+ let s3 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample3);
+ assert!(s3.is_err());
+ assert_eq!(s3.unwrap_err().variant.message(), ERROR);
+ let s4 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample4);
+ assert!(s4.is_err());
+ assert_eq!(s4.unwrap_err().variant.message(), ERROR);
+ let s5 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample5);
+ assert!(s5.is_err());
+ assert_eq!(s5.unwrap_err().variant.message(), ERROR);
+ }
}
diff --git a/vendor/pest_meta/src/validator.rs b/vendor/pest_meta/src/validator.rs
index a358dbeec..5448c3bcd 100644
--- a/vendor/pest_meta/src/validator.rs
+++ b/vendor/pest_meta/src/validator.rs
@@ -7,105 +7,67 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
+use once_cell::sync::Lazy;
use std::collections::{HashMap, HashSet};
use pest::error::{Error, ErrorVariant, InputLocation};
use pest::iterators::Pairs;
use pest::Span;
-use parser::{ParserExpr, ParserNode, ParserRule, Rule};
-use UNICODE_PROPERTY_NAMES;
-
-#[allow(clippy::needless_pass_by_value)]
-pub fn validate_pairs<'i>(pairs: Pairs<'i, Rule>) -> Result<Vec<&'i str>, Vec<Error<Rule>>> {
- let mut rust_keywords = HashSet::new();
- rust_keywords.insert("abstract");
- rust_keywords.insert("alignof");
- rust_keywords.insert("as");
- rust_keywords.insert("become");
- rust_keywords.insert("box");
- rust_keywords.insert("break");
- rust_keywords.insert("const");
- rust_keywords.insert("continue");
- rust_keywords.insert("crate");
- rust_keywords.insert("do");
- rust_keywords.insert("else");
- rust_keywords.insert("enum");
- rust_keywords.insert("extern");
- rust_keywords.insert("false");
- rust_keywords.insert("final");
- rust_keywords.insert("fn");
- rust_keywords.insert("for");
- rust_keywords.insert("if");
- rust_keywords.insert("impl");
- rust_keywords.insert("in");
- rust_keywords.insert("let");
- rust_keywords.insert("loop");
- rust_keywords.insert("macro");
- rust_keywords.insert("match");
- rust_keywords.insert("mod");
- rust_keywords.insert("move");
- rust_keywords.insert("mut");
- rust_keywords.insert("offsetof");
- rust_keywords.insert("override");
- rust_keywords.insert("priv");
- rust_keywords.insert("proc");
- rust_keywords.insert("pure");
- rust_keywords.insert("pub");
- rust_keywords.insert("ref");
- rust_keywords.insert("return");
- rust_keywords.insert("Self");
- rust_keywords.insert("self");
- rust_keywords.insert("sizeof");
- rust_keywords.insert("static");
- rust_keywords.insert("struct");
- rust_keywords.insert("super");
- rust_keywords.insert("trait");
- rust_keywords.insert("true");
- rust_keywords.insert("type");
- rust_keywords.insert("typeof");
- rust_keywords.insert("unsafe");
- rust_keywords.insert("unsized");
- rust_keywords.insert("use");
- rust_keywords.insert("virtual");
- rust_keywords.insert("where");
- rust_keywords.insert("while");
- rust_keywords.insert("yield");
-
- let mut pest_keywords = HashSet::new();
- pest_keywords.insert("_");
- pest_keywords.insert("ANY");
- pest_keywords.insert("DROP");
- pest_keywords.insert("EOI");
- pest_keywords.insert("PEEK");
- pest_keywords.insert("PEEK_ALL");
- pest_keywords.insert("POP");
- pest_keywords.insert("POP_ALL");
- pest_keywords.insert("PUSH");
- pest_keywords.insert("SOI");
-
- let mut builtins = HashSet::new();
- builtins.insert("ANY");
- builtins.insert("DROP");
- builtins.insert("EOI");
- builtins.insert("PEEK");
- builtins.insert("PEEK_ALL");
- builtins.insert("POP");
- builtins.insert("POP_ALL");
- builtins.insert("SOI");
- builtins.insert("ASCII_DIGIT");
- builtins.insert("ASCII_NONZERO_DIGIT");
- builtins.insert("ASCII_BIN_DIGIT");
- builtins.insert("ASCII_OCT_DIGIT");
- builtins.insert("ASCII_HEX_DIGIT");
- builtins.insert("ASCII_ALPHA_LOWER");
- builtins.insert("ASCII_ALPHA_UPPER");
- builtins.insert("ASCII_ALPHA");
- builtins.insert("ASCII_ALPHANUMERIC");
- builtins.insert("ASCII");
- builtins.insert("NEWLINE");
- builtins.extend(UNICODE_PROPERTY_NAMES);
-
+use crate::parser::{ParserExpr, ParserNode, ParserRule, Rule};
+use crate::UNICODE_PROPERTY_NAMES;
+
+static RUST_KEYWORDS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
+ [
+ "abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate", "do",
+ "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", "let", "loop",
+ "macro", "match", "mod", "move", "mut", "offsetof", "override", "priv", "proc", "pure",
+ "pub", "ref", "return", "Self", "self", "sizeof", "static", "struct", "super", "trait",
+ "true", "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield",
+ ]
+ .iter()
+ .cloned()
+ .collect()
+});
+
+static PEST_KEYWORDS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
+ [
+ "_", "ANY", "DROP", "EOI", "PEEK", "PEEK_ALL", "POP", "POP_ALL", "PUSH", "SOI",
+ ]
+ .iter()
+ .cloned()
+ .collect()
+});
+
+static BUILTINS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
+ [
+ "ANY",
+ "DROP",
+ "EOI",
+ "PEEK",
+ "PEEK_ALL",
+ "POP",
+ "POP_ALL",
+ "SOI",
+ "ASCII_DIGIT",
+ "ASCII_NONZERO_DIGIT",
+ "ASCII_BIN_DIGIT",
+ "ASCII_OCT_DIGIT",
+ "ASCII_HEX_DIGIT",
+ "ASCII_ALPHA_LOWER",
+ "ASCII_ALPHA_UPPER",
+ "ASCII_ALPHA",
+ "ASCII_ALPHANUMERIC",
+ "ASCII",
+ "NEWLINE",
+ ]
+ .iter()
+ .cloned()
+ .chain(UNICODE_PROPERTY_NAMES.iter().cloned())
+ .collect::<HashSet<&str>>()
+});
+
+pub fn validate_pairs(pairs: Pairs<Rule>) -> Result<Vec<&str>, Vec<Error<Rule>>> {
let definitions: Vec<_> = pairs
.clone()
.filter(|pair| pair.as_rule() == Rule::grammar_rule)
@@ -125,10 +87,10 @@ pub fn validate_pairs<'i>(pairs: Pairs<'i, Rule>) -> Result<Vec<&'i str>, Vec<Er
let mut errors = vec![];
- errors.extend(validate_rust_keywords(&definitions, &rust_keywords));
- errors.extend(validate_pest_keywords(&definitions, &pest_keywords));
+ errors.extend(validate_rust_keywords(&definitions));
+ errors.extend(validate_pest_keywords(&definitions));
errors.extend(validate_already_defined(&definitions));
- errors.extend(validate_undefined(&definitions, &called_rules, &builtins));
+ errors.extend(validate_undefined(&definitions, &called_rules));
if !errors.is_empty() {
return Err(errors);
@@ -142,22 +104,19 @@ pub fn validate_pairs<'i>(pairs: Pairs<'i, Rule>) -> Result<Vec<&'i str>, Vec<Er
Ok(defaults.cloned().collect())
}
-#[allow(clippy::implicit_hasher, clippy::ptr_arg)]
-pub fn validate_rust_keywords<'i>(
- definitions: &Vec<Span<'i>>,
- rust_keywords: &HashSet<&str>,
-) -> Vec<Error<Rule>> {
+#[allow(clippy::ptr_arg)]
+pub fn validate_rust_keywords(definitions: &Vec<Span>) -> Vec<Error<Rule>> {
let mut errors = vec![];
for definition in definitions {
let name = definition.as_str();
- if rust_keywords.contains(name) {
+ if RUST_KEYWORDS.contains(name) {
errors.push(Error::new_from_span(
ErrorVariant::CustomError {
message: format!("{} is a rust keyword", name),
},
- definition.clone(),
+ *definition,
))
}
}
@@ -165,22 +124,19 @@ pub fn validate_rust_keywords<'i>(
errors
}
-#[allow(clippy::implicit_hasher, clippy::ptr_arg)]
-pub fn validate_pest_keywords<'i>(
- definitions: &Vec<Span<'i>>,
- pest_keywords: &HashSet<&str>,
-) -> Vec<Error<Rule>> {
+#[allow(clippy::ptr_arg)]
+pub fn validate_pest_keywords(definitions: &Vec<Span>) -> Vec<Error<Rule>> {
let mut errors = vec![];
for definition in definitions {
let name = definition.as_str();
- if pest_keywords.contains(name) {
+ if PEST_KEYWORDS.contains(name) {
errors.push(Error::new_from_span(
ErrorVariant::CustomError {
message: format!("{} is a pest keyword", name),
},
- definition.clone(),
+ *definition,
))
}
}
@@ -189,7 +145,7 @@ pub fn validate_pest_keywords<'i>(
}
#[allow(clippy::ptr_arg)]
-pub fn validate_already_defined<'i>(definitions: &Vec<Span<'i>>) -> Vec<Error<Rule>> {
+pub fn validate_already_defined(definitions: &Vec<Span>) -> Vec<Error<Rule>> {
let mut errors = vec![];
let mut defined = HashSet::new();
@@ -201,7 +157,7 @@ pub fn validate_already_defined<'i>(definitions: &Vec<Span<'i>>) -> Vec<Error<Ru
ErrorVariant::CustomError {
message: format!("rule {} already defined", name),
},
- definition.clone(),
+ *definition,
))
} else {
defined.insert(name);
@@ -211,11 +167,10 @@ pub fn validate_already_defined<'i>(definitions: &Vec<Span<'i>>) -> Vec<Error<Ru
errors
}
-#[allow(clippy::implicit_hasher, clippy::ptr_arg)]
+#[allow(clippy::ptr_arg)]
pub fn validate_undefined<'i>(
definitions: &Vec<Span<'i>>,
called_rules: &Vec<Span<'i>>,
- builtins: &HashSet<&str>,
) -> Vec<Error<Rule>> {
let mut errors = vec![];
let definitions: HashSet<_> = definitions.iter().map(|span| span.as_str()).collect();
@@ -223,12 +178,12 @@ pub fn validate_undefined<'i>(
for rule in called_rules {
let name = rule.as_str();
- if !definitions.contains(name) && !builtins.contains(name) {
+ if !definitions.contains(name) && !BUILTINS.contains(name) {
errors.push(Error::new_from_span(
ErrorVariant::CustomError {
message: format!("rule {} is undefined", name),
},
- rule.clone(),
+ *rule,
))
}
}
@@ -259,7 +214,7 @@ fn is_non_progressing<'i>(
trace: &mut Vec<String>,
) -> bool {
match *expr {
- ParserExpr::Str(ref string) => string == "",
+ ParserExpr::Str(ref string) => string.is_empty(),
ParserExpr::Ident(ref ident) => {
if ident == "soi" || ident == "eoi" {
return true;
@@ -297,7 +252,7 @@ fn is_non_failing<'i>(
trace: &mut Vec<String>,
) -> bool {
match *expr {
- ParserExpr::Str(ref string) => string == "",
+ ParserExpr::Str(ref string) => string.is_empty(),
ParserExpr::Ident(ref ident) => {
if !trace.contains(ident) {
if let Some(node) = rules.get(ident) {
@@ -342,7 +297,7 @@ fn validate_repetition<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<Error<Rul
infinitely"
.to_owned()
},
- node.span.clone()
+ node.span
))
} else if is_non_progressing(&other.expr, &map, &mut vec![]) {
Some(Error::new_from_span(
@@ -352,7 +307,7 @@ fn validate_repetition<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<Error<Rul
infinitely"
.to_owned(),
},
- node.span.clone()
+ node.span
))
} else {
None
@@ -389,7 +344,7 @@ fn validate_choices<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<Error<Rule>>
"expression cannot fail; following choices cannot be reached"
.to_owned(),
},
- node.span.clone(),
+ node.span,
))
} else {
None
@@ -419,7 +374,7 @@ fn validate_whitespace_comment<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<E
&rule.name
),
},
- rule.node.span.clone(),
+ rule.node.span,
))
} else if is_non_progressing(&rule.node.expr, &map, &mut vec![]) {
Some(Error::new_from_span(
@@ -429,7 +384,7 @@ fn validate_whitespace_comment<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<E
&rule.name
),
},
- rule.node.span.clone(),
+ rule.node.span,
))
} else {
None
@@ -449,7 +404,6 @@ fn to_hash_map<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> HashMap<String, &'a P
rules.iter().map(|r| (r.name.clone(), &r.node)).collect()
}
-#[allow(clippy::needless_pass_by_value)]
fn left_recursion<'a, 'i: 'a>(rules: HashMap<String, &'a ParserNode<'i>>) -> Vec<Error<Rule>> {
fn check_expr<'a, 'i: 'a>(
node: &'a ParserNode<'i>,
@@ -475,7 +429,7 @@ fn left_recursion<'a, 'i: 'a>(rules: HashMap<String, &'a ParserNode<'i>>) -> Vec
chain
)
},
- node.span.clone()
+ node.span
));
}
@@ -499,22 +453,22 @@ fn left_recursion<'a, 'i: 'a>(rules: HashMap<String, &'a ParserNode<'i>>) -> Vec
}
}
ParserExpr::Choice(ref lhs, ref rhs) => {
- check_expr(&lhs, rules, trace).or_else(|| check_expr(&rhs, rules, trace))
+ check_expr(lhs, rules, trace).or_else(|| check_expr(rhs, rules, trace))
}
- ParserExpr::Rep(ref node) => check_expr(&node, rules, trace),
- ParserExpr::RepOnce(ref node) => check_expr(&node, rules, trace),
- ParserExpr::Opt(ref node) => check_expr(&node, rules, trace),
- ParserExpr::PosPred(ref node) => check_expr(&node, rules, trace),
- ParserExpr::NegPred(ref node) => check_expr(&node, rules, trace),
- ParserExpr::Push(ref node) => check_expr(&node, rules, trace),
+ ParserExpr::Rep(ref node) => check_expr(node, rules, trace),
+ ParserExpr::RepOnce(ref node) => check_expr(node, rules, trace),
+ ParserExpr::Opt(ref node) => check_expr(node, rules, trace),
+ ParserExpr::PosPred(ref node) => check_expr(node, rules, trace),
+ ParserExpr::NegPred(ref node) => check_expr(node, rules, trace),
+ ParserExpr::Push(ref node) => check_expr(node, rules, trace),
_ => None,
}
}
let mut errors = vec![];
- for (ref name, ref node) in &rules {
- let name = (*name).clone();
+ for (name, node) in &rules {
+ let name = name.clone();
if let Some(error) = check_expr(node, &rules, &mut vec![name]) {
errors.push(error);
diff --git a/vendor/pretty_assertions-0.7.2/.cargo-checksum.json b/vendor/pretty_assertions/.cargo-checksum.json
index 74431486b..74431486b 100644
--- a/vendor/pretty_assertions-0.7.2/.cargo-checksum.json
+++ b/vendor/pretty_assertions/.cargo-checksum.json
diff --git a/vendor/pretty_assertions-0.7.2/CHANGELOG.md b/vendor/pretty_assertions/CHANGELOG.md
index a5c81b75b..a5c81b75b 100644
--- a/vendor/pretty_assertions-0.7.2/CHANGELOG.md
+++ b/vendor/pretty_assertions/CHANGELOG.md
diff --git a/vendor/pretty_assertions-0.7.2/Cargo.lock b/vendor/pretty_assertions/Cargo.lock
index 8e433f023..8e433f023 100644
--- a/vendor/pretty_assertions-0.7.2/Cargo.lock
+++ b/vendor/pretty_assertions/Cargo.lock
diff --git a/vendor/pretty_assertions-0.7.2/Cargo.toml b/vendor/pretty_assertions/Cargo.toml
index 3f4660d5a..3f4660d5a 100644
--- a/vendor/pretty_assertions-0.7.2/Cargo.toml
+++ b/vendor/pretty_assertions/Cargo.toml
diff --git a/vendor/pretty_assertions-0.7.2/LICENSE-APACHE b/vendor/pretty_assertions/LICENSE-APACHE
index 8f71f43fe..8f71f43fe 100644
--- a/vendor/pretty_assertions-0.7.2/LICENSE-APACHE
+++ b/vendor/pretty_assertions/LICENSE-APACHE
diff --git a/vendor/pretty_assertions-0.7.2/LICENSE-MIT b/vendor/pretty_assertions/LICENSE-MIT
index 48b7653f4..48b7653f4 100644
--- a/vendor/pretty_assertions-0.7.2/LICENSE-MIT
+++ b/vendor/pretty_assertions/LICENSE-MIT
diff --git a/vendor/pretty_assertions-0.7.2/README.md b/vendor/pretty_assertions/README.md
index cc9a6ef74..cc9a6ef74 100644
--- a/vendor/pretty_assertions-0.7.2/README.md
+++ b/vendor/pretty_assertions/README.md
diff --git a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.png b/vendor/pretty_assertions/examples/pretty_assertion.png
index 1e5b645f0..1e5b645f0 100644
--- a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.png
+++ b/vendor/pretty_assertions/examples/pretty_assertion.png
Binary files differ
diff --git a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.rs b/vendor/pretty_assertions/examples/pretty_assertion.rs
index 63246c6d7..63246c6d7 100644
--- a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.rs
+++ b/vendor/pretty_assertions/examples/pretty_assertion.rs
diff --git a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion_v0_6_1.png b/vendor/pretty_assertions/examples/pretty_assertion_v0_6_1.png
index dc192d081..dc192d081 100644
--- a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion_v0_6_1.png
+++ b/vendor/pretty_assertions/examples/pretty_assertion_v0_6_1.png
Binary files differ
diff --git a/vendor/pretty_assertions-0.7.2/examples/standard_assertion.png b/vendor/pretty_assertions/examples/standard_assertion.png
index 03ea059b7..03ea059b7 100644
--- a/vendor/pretty_assertions-0.7.2/examples/standard_assertion.png
+++ b/vendor/pretty_assertions/examples/standard_assertion.png
Binary files differ
diff --git a/vendor/pretty_assertions-0.7.2/examples/standard_assertion.rs b/vendor/pretty_assertions/examples/standard_assertion.rs
index fddd512f4..fddd512f4 100644
--- a/vendor/pretty_assertions-0.7.2/examples/standard_assertion.rs
+++ b/vendor/pretty_assertions/examples/standard_assertion.rs
diff --git a/vendor/pretty_assertions-0.7.2/scripts/check b/vendor/pretty_assertions/scripts/check
index 43fb3a9b3..43fb3a9b3 100755
--- a/vendor/pretty_assertions-0.7.2/scripts/check
+++ b/vendor/pretty_assertions/scripts/check
diff --git a/vendor/pretty_assertions-0.7.2/scripts/install b/vendor/pretty_assertions/scripts/install
index 92577640c..92577640c 100755
--- a/vendor/pretty_assertions-0.7.2/scripts/install
+++ b/vendor/pretty_assertions/scripts/install
diff --git a/vendor/pretty_assertions-0.7.2/scripts/publish b/vendor/pretty_assertions/scripts/publish
index e904f03eb..e904f03eb 100755
--- a/vendor/pretty_assertions-0.7.2/scripts/publish
+++ b/vendor/pretty_assertions/scripts/publish
diff --git a/vendor/pretty_assertions-0.7.2/src/lib.rs b/vendor/pretty_assertions/src/lib.rs
index 5c1787533..5c1787533 100644
--- a/vendor/pretty_assertions-0.7.2/src/lib.rs
+++ b/vendor/pretty_assertions/src/lib.rs
diff --git a/vendor/pretty_assertions-0.7.2/src/printer.rs b/vendor/pretty_assertions/src/printer.rs
index 172b1ed6c..172b1ed6c 100644
--- a/vendor/pretty_assertions-0.7.2/src/printer.rs
+++ b/vendor/pretty_assertions/src/printer.rs
diff --git a/vendor/proc-macro2/.cargo-checksum.json b/vendor/proc-macro2/.cargo-checksum.json
index 00ef04da4..59f2a8483 100644
--- a/vendor/proc-macro2/.cargo-checksum.json
+++ b/vendor/proc-macro2/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"d6809d3069ce4c5e92828c6e49100a684c37f55e4d2d42bbe02362e0cd0297d7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"0c17148c1957c3f721d99fc99aedaefee5f2f1ba7e2336a289b02f91609099fb","build.rs":"2c6ddbeeb1700b8dba3689185a535c672dc43e9d61b54f835cf4f3cc163b4afc","src/detection.rs":"12821bd715999c994fc1c8e1b68e52e1d64677290d803c53ad096ab17c9959fb","src/fallback.rs":"21f3f0f552db6fbec0cde8c056a2c722a3c88302b1519d08a3bfe341f2a62055","src/lib.rs":"ed7b36e5b3a35852936a4d1121704ee249011379b582cd0409e1ce08fae25c24","src/marker.rs":"87fce2d0357f5b7998b6d9dfb064f4a0cbc9dabb19e33d4b514a446243ebe2e8","src/parse.rs":"44a6fdec0332de7b8c083530294d3dc0aadb626a0739fd07a16a1ec48473a99d","src/wrapper.rs":"a0ba0eadd7f30842049bd9f4dca9182f2e4f7e2a09d394959bcd48c1d752a795","tests/comments.rs":"065132797580744767b7a854d5467757bd3433a990957f8dbccdfa779bfb275f","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"cb6d776eba6a238d726b0f531883adf41957e06f2717ee8a069821c81e7081d6","tests/test.rs":"15783299f85ecccb51acd6cc95087077eccfecddce1208e56ad5dabf74d3f50a","tests/test_fmt.rs":"9357769945784354909259084ec8b34d2aa52081dd3967cac6dae3a5e3df3bc0"},"package":"dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"} \ No newline at end of file
+{"files":{"Cargo.toml":"774906eb037620dba1ef4cf6adc14ec35e7f9f81d1e2d967dfedfab8e7b603d9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"0c17148c1957c3f721d99fc99aedaefee5f2f1ba7e2336a289b02f91609099fb","build.rs":"2c6ddbeeb1700b8dba3689185a535c672dc43e9d61b54f835cf4f3cc163b4afc","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/fallback.rs":"5aab7b73e381dc192256a0c67c99706ae0850159fd9f805fb0c9418fc14b1e00","src/lib.rs":"8bd3da5c9f048acda3799d53eefb7fb2f8b4046612d48f34ec30102b10f4ab08","src/marker.rs":"344a8394f06a1d43355b514920e7e3c0c6dce507be767e3a590bbe3552edd110","src/parse.rs":"34fa3c2e03fa9ab3e63ea57595d1dea4edf0fcfa313a04057e4dd7dc7d7269e0","src/rcvec.rs":"49b6784c6ca5f32573cd8a83758b485d8acbfa126e5fb516ae439e429ef4c144","src/wrapper.rs":"a88d0dff9bb8317071ec205b0c2a79717cd8313041e03ef58e0645be65ab05e8","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"cb6d776eba6a238d726b0f531883adf41957e06f2717ee8a069821c81e7081d6","tests/test.rs":"2fe87d2eab135fb2417cac2876998e9314616fb68981918d7d76333c22b199a0","tests/test_fmt.rs":"9357769945784354909259084ec8b34d2aa52081dd3967cac6dae3a5e3df3bc0"},"package":"0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"} \ No newline at end of file
diff --git a/vendor/proc-macro2/Cargo.toml b/vendor/proc-macro2/Cargo.toml
index 2dabf8994..b8b46430d 100644
--- a/vendor/proc-macro2/Cargo.toml
+++ b/vendor/proc-macro2/Cargo.toml
@@ -13,19 +13,19 @@
edition = "2018"
rust-version = "1.31"
name = "proc-macro2"
-version = "1.0.40"
+version = "1.0.43"
authors = [
"David Tolnay <dtolnay@gmail.com>",
"Alex Crichton <alex@alexcrichton.com>",
]
autobenches = false
-description = """
-A substitute implementation of the compiler's `proc_macro` API to decouple
-token-based libraries from the procedural macro use case.
-"""
+description = "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case."
documentation = "https://docs.rs/proc-macro2"
readme = "README.md"
-keywords = ["macros"]
+keywords = [
+ "macros",
+ "syn",
+]
categories = ["development-tools::procedural-macro-helpers"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/proc-macro2"
diff --git a/vendor/proc-macro2/src/detection.rs b/vendor/proc-macro2/src/detection.rs
index d139b7365..beba7b237 100644
--- a/vendor/proc-macro2/src/detection.rs
+++ b/vendor/proc-macro2/src/detection.rs
@@ -1,4 +1,4 @@
-use std::sync::atomic::{AtomicUsize, Ordering};
+use core::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Once;
static WORKS: AtomicUsize = AtomicUsize::new(0);
diff --git a/vendor/proc-macro2/src/fallback.rs b/vendor/proc-macro2/src/fallback.rs
index 6afa790f8..378ef7e94 100644
--- a/vendor/proc-macro2/src/fallback.rs
+++ b/vendor/proc-macro2/src/fallback.rs
@@ -1,18 +1,19 @@
use crate::parse::{self, Cursor};
+use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut};
use crate::{Delimiter, Spacing, TokenTree};
#[cfg(span_locations)]
-use std::cell::RefCell;
+use core::cell::RefCell;
#[cfg(span_locations)]
-use std::cmp;
-use std::fmt::{self, Debug, Display, Write};
-use std::iter::FromIterator;
-use std::mem;
-use std::ops::RangeBounds;
+use core::cmp;
+use core::fmt::{self, Debug, Display, Write};
+use core::iter::FromIterator;
+use core::mem::ManuallyDrop;
+use core::ops::RangeBounds;
+use core::ptr;
+use core::str::FromStr;
#[cfg(procmacro2_semver_exempt)]
use std::path::Path;
use std::path::PathBuf;
-use std::str::FromStr;
-use std::vec;
/// Force use of proc-macro2's fallback implementation of the API for now, even
/// if the compiler's implementation is available.
@@ -30,7 +31,7 @@ pub fn unforce() {
#[derive(Clone)]
pub(crate) struct TokenStream {
- inner: Vec<TokenTree>,
+ inner: RcVec<TokenTree>,
}
#[derive(Debug)]
@@ -52,71 +53,69 @@ impl LexError {
impl TokenStream {
pub fn new() -> Self {
- TokenStream { inner: Vec::new() }
+ TokenStream {
+ inner: RcVecBuilder::new().build(),
+ }
}
pub fn is_empty(&self) -> bool {
self.inner.len() == 0
}
- fn take_inner(&mut self) -> Vec<TokenTree> {
- mem::replace(&mut self.inner, Vec::new())
+ fn take_inner(self) -> RcVecBuilder<TokenTree> {
+ let nodrop = ManuallyDrop::new(self);
+ unsafe { ptr::read(&nodrop.inner) }.make_owned()
}
+}
- fn push_token(&mut self, token: TokenTree) {
- // https://github.com/dtolnay/proc-macro2/issues/235
- match token {
- #[cfg(not(no_bind_by_move_pattern_guard))]
- TokenTree::Literal(crate::Literal {
- #[cfg(wrap_proc_macro)]
- inner: crate::imp::Literal::Fallback(literal),
- #[cfg(not(wrap_proc_macro))]
- inner: literal,
- ..
- }) if literal.repr.starts_with('-') => {
- push_negative_literal(self, literal);
- }
- #[cfg(no_bind_by_move_pattern_guard)]
- TokenTree::Literal(crate::Literal {
- #[cfg(wrap_proc_macro)]
- inner: crate::imp::Literal::Fallback(literal),
- #[cfg(not(wrap_proc_macro))]
- inner: literal,
- ..
- }) => {
- if literal.repr.starts_with('-') {
- push_negative_literal(self, literal);
- } else {
- self.inner
- .push(TokenTree::Literal(crate::Literal::_new_stable(literal)));
- }
- }
- _ => self.inner.push(token),
+fn push_token_from_proc_macro(mut vec: RcVecMut<TokenTree>, token: TokenTree) {
+ // https://github.com/dtolnay/proc-macro2/issues/235
+ match token {
+ #[cfg(not(no_bind_by_move_pattern_guard))]
+ TokenTree::Literal(crate::Literal {
+ #[cfg(wrap_proc_macro)]
+ inner: crate::imp::Literal::Fallback(literal),
+ #[cfg(not(wrap_proc_macro))]
+ inner: literal,
+ ..
+ }) if literal.repr.starts_with('-') => {
+ push_negative_literal(vec, literal);
}
-
- #[cold]
- fn push_negative_literal(stream: &mut TokenStream, mut literal: Literal) {
- literal.repr.remove(0);
- let mut punct = crate::Punct::new('-', Spacing::Alone);
- punct.set_span(crate::Span::_new_stable(literal.span));
- stream.inner.push(TokenTree::Punct(punct));
- stream
- .inner
- .push(TokenTree::Literal(crate::Literal::_new_stable(literal)));
+ #[cfg(no_bind_by_move_pattern_guard)]
+ TokenTree::Literal(crate::Literal {
+ #[cfg(wrap_proc_macro)]
+ inner: crate::imp::Literal::Fallback(literal),
+ #[cfg(not(wrap_proc_macro))]
+ inner: literal,
+ ..
+ }) => {
+ if literal.repr.starts_with('-') {
+ push_negative_literal(vec, literal);
+ } else {
+ vec.push(TokenTree::Literal(crate::Literal::_new_stable(literal)));
+ }
}
+ _ => vec.push(token),
}
-}
-impl From<Vec<TokenTree>> for TokenStream {
- fn from(inner: Vec<TokenTree>) -> Self {
- TokenStream { inner }
+ #[cold]
+ fn push_negative_literal(mut vec: RcVecMut<TokenTree>, mut literal: Literal) {
+ literal.repr.remove(0);
+ let mut punct = crate::Punct::new('-', Spacing::Alone);
+ punct.set_span(crate::Span::_new_stable(literal.span));
+ vec.push(TokenTree::Punct(punct));
+ vec.push(TokenTree::Literal(crate::Literal::_new_stable(literal)));
}
}
// Nonrecursive to prevent stack overflow.
impl Drop for TokenStream {
fn drop(&mut self) {
- while let Some(token) = self.inner.pop() {
+ let mut inner = match self.inner.get_mut() {
+ Some(inner) => inner,
+ None => return,
+ };
+ while let Some(token) = inner.pop() {
let group = match token {
TokenTree::Group(group) => group.inner,
_ => continue,
@@ -126,8 +125,35 @@ impl Drop for TokenStream {
crate::imp::Group::Fallback(group) => group,
crate::imp::Group::Compiler(_) => continue,
};
- let mut group = group;
- self.inner.extend(group.stream.take_inner());
+ inner.extend(group.stream.take_inner());
+ }
+ }
+}
+
+pub(crate) struct TokenStreamBuilder {
+ inner: RcVecBuilder<TokenTree>,
+}
+
+impl TokenStreamBuilder {
+ pub fn new() -> Self {
+ TokenStreamBuilder {
+ inner: RcVecBuilder::new(),
+ }
+ }
+
+ pub fn with_capacity(cap: usize) -> Self {
+ TokenStreamBuilder {
+ inner: RcVecBuilder::with_capacity(cap),
+ }
+ }
+
+ pub fn push_token_from_parser(&mut self, tt: TokenTree) {
+ self.inner.push(tt);
+ }
+
+ pub fn build(self) -> TokenStream {
+ TokenStream {
+ inner: self.inner.build(),
}
}
}
@@ -220,9 +246,11 @@ impl From<TokenStream> for proc_macro::TokenStream {
impl From<TokenTree> for TokenStream {
fn from(tree: TokenTree) -> TokenStream {
- let mut stream = TokenStream::new();
- stream.push_token(tree);
- stream
+ let mut stream = RcVecBuilder::new();
+ push_token_from_proc_macro(stream.as_mut(), tree);
+ TokenStream {
+ inner: stream.build(),
+ }
}
}
@@ -236,35 +264,38 @@ impl FromIterator<TokenTree> for TokenStream {
impl FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
- let mut v = Vec::new();
+ let mut v = RcVecBuilder::new();
- for mut stream in streams {
+ for stream in streams {
v.extend(stream.take_inner());
}
- TokenStream { inner: v }
+ TokenStream { inner: v.build() }
}
}
impl Extend<TokenTree> for TokenStream {
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, tokens: I) {
- tokens.into_iter().for_each(|token| self.push_token(token));
+ let mut vec = self.inner.make_mut();
+ tokens
+ .into_iter()
+ .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token));
}
}
impl Extend<TokenStream> for TokenStream {
fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
- self.inner.extend(streams.into_iter().flatten());
+ self.inner.make_mut().extend(streams.into_iter().flatten());
}
}
-pub(crate) type TokenTreeIter = vec::IntoIter<TokenTree>;
+pub(crate) type TokenTreeIter = RcVecIntoIter<TokenTree>;
impl IntoIterator for TokenStream {
type Item = TokenTree;
type IntoIter = TokenTreeIter;
- fn into_iter(mut self) -> TokenTreeIter {
+ fn into_iter(self) -> TokenTreeIter {
self.take_inner().into_iter()
}
}
@@ -383,7 +414,7 @@ impl SourceMap {
fn add_file(&mut self, name: &str, src: &str) -> Span {
let (len, lines) = lines_offsets(src);
let lo = self.next_start_pos();
- // XXX(nika): Shouild we bother doing a checked cast or checked add here?
+ // XXX(nika): Should we bother doing a checked cast or checked add here?
let span = Span {
lo,
hi: lo + (len as u32),
diff --git a/vendor/proc-macro2/src/lib.rs b/vendor/proc-macro2/src/lib.rs
index 6adf71a19..be5aa5114 100644
--- a/vendor/proc-macro2/src/lib.rs
+++ b/vendor/proc-macro2/src/lib.rs
@@ -86,7 +86,7 @@
//! a different thread.
// Proc-macro2 types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.40")]
+#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.43")]
#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))]
#![cfg_attr(super_unstable, feature(proc_macro_def_site))]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
@@ -120,6 +120,7 @@ extern crate proc_macro;
mod marker;
mod parse;
+mod rcvec;
#[cfg(wrap_proc_macro)]
mod detection;
@@ -136,15 +137,15 @@ use crate::fallback as imp;
mod imp;
use crate::marker::Marker;
-use std::cmp::Ordering;
+use core::cmp::Ordering;
+use core::fmt::{self, Debug, Display};
+use core::hash::{Hash, Hasher};
+use core::iter::FromIterator;
+use core::ops::RangeBounds;
+use core::str::FromStr;
use std::error::Error;
-use std::fmt::{self, Debug, Display};
-use std::hash::{Hash, Hasher};
-use std::iter::FromIterator;
-use std::ops::RangeBounds;
#[cfg(procmacro2_semver_exempt)]
use std::path::PathBuf;
-use std::str::FromStr;
/// An abstract stream of tokens, or more concretely a sequence of token trees.
///
@@ -1128,9 +1129,9 @@ impl Literal {
/// This constructor is similar to those like `Literal::i8_unsuffixed` where
/// the float's value is emitted directly into the token but no suffix is
/// used, so it may be inferred to be a `f64` later in the compiler.
- /// Literals created from negative numbers may not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and
- /// positive literal).
+ /// Literals created from negative numbers may not survive round-trips
+ /// through `TokenStream` or strings and may be broken into two tokens (`-`
+ /// and positive literal).
///
/// # Panics
///
@@ -1147,7 +1148,7 @@ impl Literal {
/// specified is the preceding part of the token and `f64` is the suffix of
/// the token. This token will always be inferred to be an `f64` in the
/// compiler. Literals created from negative numbers may not survive
- /// rountrips through `TokenStream` or strings and may be broken into two
+ /// round-trips through `TokenStream` or strings and may be broken into two
/// tokens (`-` and positive literal).
///
/// # Panics
@@ -1164,9 +1165,9 @@ impl Literal {
/// This constructor is similar to those like `Literal::i8_unsuffixed` where
/// the float's value is emitted directly into the token but no suffix is
/// used, so it may be inferred to be a `f64` later in the compiler.
- /// Literals created from negative numbers may not survive rountrips through
- /// `TokenStream` or strings and may be broken into two tokens (`-` and
- /// positive literal).
+ /// Literals created from negative numbers may not survive round-trips
+ /// through `TokenStream` or strings and may be broken into two tokens (`-`
+ /// and positive literal).
///
/// # Panics
///
@@ -1183,7 +1184,7 @@ impl Literal {
/// specified is the preceding part of the token and `f32` is the suffix of
/// the token. This token will always be inferred to be an `f32` in the
/// compiler. Literals created from negative numbers may not survive
- /// rountrips through `TokenStream` or strings and may be broken into two
+ /// round-trips through `TokenStream` or strings and may be broken into two
/// tokens (`-` and positive literal).
///
/// # Panics
@@ -1270,7 +1271,7 @@ impl Display for Literal {
pub mod token_stream {
use crate::marker::Marker;
use crate::{imp, TokenTree};
- use std::fmt::{self, Debug};
+ use core::fmt::{self, Debug};
pub use crate::TokenStream;
@@ -1290,11 +1291,16 @@ pub mod token_stream {
fn next(&mut self) -> Option<TokenTree> {
self.inner.next()
}
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
}
impl Debug for IntoIter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Debug::fmt(&self.inner, f)
+ f.write_str("TokenStream ")?;
+ f.debug_list().entries(self.clone()).finish()
}
}
diff --git a/vendor/proc-macro2/src/marker.rs b/vendor/proc-macro2/src/marker.rs
index 58729baf4..59fd09630 100644
--- a/vendor/proc-macro2/src/marker.rs
+++ b/vendor/proc-macro2/src/marker.rs
@@ -1,4 +1,4 @@
-use std::marker::PhantomData;
+use core::marker::PhantomData;
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::rc::Rc;
@@ -9,7 +9,7 @@ pub(crate) type Marker = PhantomData<ProcMacroAutoTraits>;
pub(crate) use self::value::*;
mod value {
- pub(crate) use std::marker::PhantomData as Marker;
+ pub(crate) use core::marker::PhantomData as Marker;
}
pub(crate) struct ProcMacroAutoTraits(Rc<()>);
diff --git a/vendor/proc-macro2/src/parse.rs b/vendor/proc-macro2/src/parse.rs
index f77213aa1..1c9974cfa 100644
--- a/vendor/proc-macro2/src/parse.rs
+++ b/vendor/proc-macro2/src/parse.rs
@@ -1,9 +1,10 @@
use crate::fallback::{
is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream,
+ TokenStreamBuilder,
};
use crate::{Delimiter, Punct, Spacing, TokenTree};
-use std::char;
-use std::str::{Bytes, CharIndices, Chars};
+use core::char;
+use core::str::{Bytes, CharIndices, Chars};
#[derive(Copy, Clone, Eq, PartialEq)]
pub(crate) struct Cursor<'a> {
@@ -150,14 +151,13 @@ fn word_break(input: Cursor) -> Result<Cursor, Reject> {
}
pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
- let mut trees = Vec::new();
+ let mut trees = TokenStreamBuilder::new();
let mut stack = Vec::new();
loop {
input = skip_whitespace(input);
- if let Ok((rest, tt)) = doc_comment(input) {
- trees.extend(tt);
+ if let Ok((rest, ())) = doc_comment(input, &mut trees) {
input = rest;
continue;
}
@@ -168,7 +168,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
let first = match input.bytes().next() {
Some(first) => first,
None => match stack.last() {
- None => return Ok(TokenStream::from(trees)),
+ None => return Ok(trees.build()),
#[cfg(span_locations)]
Some((lo, _frame)) => {
return Err(LexError {
@@ -191,7 +191,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
#[cfg(span_locations)]
let frame = (lo, frame);
stack.push(frame);
- trees = Vec::new();
+ trees = TokenStreamBuilder::new();
} else if let Some(close_delimiter) = match first {
b')' => Some(Delimiter::Parenthesis),
b']' => Some(Delimiter::Bracket),
@@ -209,7 +209,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
return Err(lex_error(input));
}
input = input.advance(1);
- let mut g = Group::new(open_delimiter, TokenStream::from(trees));
+ let mut g = Group::new(open_delimiter, trees.build());
g.set_span(Span {
#[cfg(span_locations)]
lo,
@@ -217,7 +217,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
hi: input.off,
});
trees = outer;
- trees.push(TokenTree::Group(crate::Group::_new_stable(g)));
+ trees.push_token_from_parser(TokenTree::Group(crate::Group::_new_stable(g)));
} else {
let (rest, mut tt) = match leaf_token(input) {
Ok((rest, tt)) => (rest, tt),
@@ -229,7 +229,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
#[cfg(span_locations)]
hi: rest.off,
}));
- trees.push(tt);
+ trees.push_token_from_parser(tt);
input = rest;
}
}
@@ -786,7 +786,7 @@ fn punct_char(input: Cursor) -> PResult<char> {
}
}
-fn doc_comment(input: Cursor) -> PResult<Vec<TokenTree>> {
+fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> {
#[cfg(span_locations)]
let lo = input.off;
let (rest, (comment, inner)) = doc_comment_contents(input)?;
@@ -806,25 +806,31 @@ fn doc_comment(input: Cursor) -> PResult<Vec<TokenTree>> {
scan_for_bare_cr = rest;
}
- let mut trees = Vec::new();
- trees.push(TokenTree::Punct(Punct::new('#', Spacing::Alone)));
+ let mut pound = Punct::new('#', Spacing::Alone);
+ pound.set_span(span);
+ trees.push_token_from_parser(TokenTree::Punct(pound));
+
if inner {
- trees.push(Punct::new('!', Spacing::Alone).into());
- }
- let mut stream = vec![
- TokenTree::Ident(crate::Ident::new("doc", span)),
- TokenTree::Punct(Punct::new('=', Spacing::Alone)),
- TokenTree::Literal(crate::Literal::string(comment)),
- ];
- for tt in &mut stream {
- tt.set_span(span);
- }
- let group = Group::new(Delimiter::Bracket, TokenStream::from(stream));
- trees.push(crate::Group::_new_stable(group).into());
- for tt in &mut trees {
- tt.set_span(span);
- }
- Ok((rest, trees))
+ let mut bang = Punct::new('!', Spacing::Alone);
+ bang.set_span(span);
+ trees.push_token_from_parser(TokenTree::Punct(bang));
+ }
+
+ let doc_ident = crate::Ident::new("doc", span);
+ let mut equal = Punct::new('=', Spacing::Alone);
+ equal.set_span(span);
+ let mut literal = crate::Literal::string(comment);
+ literal.set_span(span);
+ let mut bracketed = TokenStreamBuilder::with_capacity(3);
+ bracketed.push_token_from_parser(TokenTree::Ident(doc_ident));
+ bracketed.push_token_from_parser(TokenTree::Punct(equal));
+ bracketed.push_token_from_parser(TokenTree::Literal(literal));
+ let group = Group::new(Delimiter::Bracket, bracketed.build());
+ let mut group = crate::Group::_new_stable(group);
+ group.set_span(span);
+ trees.push_token_from_parser(TokenTree::Group(group));
+
+ Ok((rest, ()))
}
fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> {
diff --git a/vendor/proc-macro2/src/rcvec.rs b/vendor/proc-macro2/src/rcvec.rs
new file mode 100644
index 000000000..86ca7d808
--- /dev/null
+++ b/vendor/proc-macro2/src/rcvec.rs
@@ -0,0 +1,142 @@
+use core::mem;
+use core::slice;
+use std::rc::Rc;
+use std::vec;
+
+pub(crate) struct RcVec<T> {
+ inner: Rc<Vec<T>>,
+}
+
+pub(crate) struct RcVecBuilder<T> {
+ inner: Vec<T>,
+}
+
+pub(crate) struct RcVecMut<'a, T> {
+ inner: &'a mut Vec<T>,
+}
+
+#[derive(Clone)]
+pub(crate) struct RcVecIntoIter<T> {
+ inner: vec::IntoIter<T>,
+}
+
+impl<T> RcVec<T> {
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+
+ pub fn len(&self) -> usize {
+ self.inner.len()
+ }
+
+ pub fn iter(&self) -> slice::Iter<T> {
+ self.inner.iter()
+ }
+
+ pub fn make_mut(&mut self) -> RcVecMut<T>
+ where
+ T: Clone,
+ {
+ RcVecMut {
+ inner: Rc::make_mut(&mut self.inner),
+ }
+ }
+
+ pub fn get_mut(&mut self) -> Option<RcVecMut<T>> {
+ let inner = Rc::get_mut(&mut self.inner)?;
+ Some(RcVecMut { inner })
+ }
+
+ pub fn make_owned(mut self) -> RcVecBuilder<T>
+ where
+ T: Clone,
+ {
+ let vec = if let Some(owned) = Rc::get_mut(&mut self.inner) {
+ mem::replace(owned, Vec::new())
+ } else {
+ Vec::clone(&self.inner)
+ };
+ RcVecBuilder { inner: vec }
+ }
+}
+
+impl<T> RcVecBuilder<T> {
+ pub fn new() -> Self {
+ RcVecBuilder { inner: Vec::new() }
+ }
+
+ pub fn with_capacity(cap: usize) -> Self {
+ RcVecBuilder {
+ inner: Vec::with_capacity(cap),
+ }
+ }
+
+ pub fn push(&mut self, element: T) {
+ self.inner.push(element);
+ }
+
+ pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
+ self.inner.extend(iter);
+ }
+
+ pub fn as_mut(&mut self) -> RcVecMut<T> {
+ RcVecMut {
+ inner: &mut self.inner,
+ }
+ }
+
+ pub fn build(self) -> RcVec<T> {
+ RcVec {
+ inner: Rc::new(self.inner),
+ }
+ }
+}
+
+impl<'a, T> RcVecMut<'a, T> {
+ pub fn push(&mut self, element: T) {
+ self.inner.push(element);
+ }
+
+ pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
+ self.inner.extend(iter);
+ }
+
+ pub fn pop(&mut self) -> Option<T> {
+ self.inner.pop()
+ }
+
+ pub fn as_mut(&mut self) -> RcVecMut<T> {
+ RcVecMut { inner: self.inner }
+ }
+}
+
+impl<T> Clone for RcVec<T> {
+ fn clone(&self) -> Self {
+ RcVec {
+ inner: Rc::clone(&self.inner),
+ }
+ }
+}
+
+impl<T> IntoIterator for RcVecBuilder<T> {
+ type Item = T;
+ type IntoIter = RcVecIntoIter<T>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ RcVecIntoIter {
+ inner: self.inner.into_iter(),
+ }
+ }
+}
+
+impl<T> Iterator for RcVecIntoIter<T> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
diff --git a/vendor/proc-macro2/src/wrapper.rs b/vendor/proc-macro2/src/wrapper.rs
index 750e156ff..934440139 100644
--- a/vendor/proc-macro2/src/wrapper.rs
+++ b/vendor/proc-macro2/src/wrapper.rs
@@ -1,12 +1,12 @@
use crate::detection::inside_proc_macro;
use crate::{fallback, Delimiter, Punct, Spacing, TokenTree};
-use std::fmt::{self, Debug, Display};
-use std::iter::FromIterator;
-use std::ops::RangeBounds;
+use core::fmt::{self, Debug, Display};
+use core::iter::FromIterator;
+use core::ops::RangeBounds;
+use core::str::FromStr;
use std::panic;
#[cfg(super_unstable)]
use std::path::PathBuf;
-use std::str::FromStr;
#[derive(Clone)]
pub(crate) enum TokenStream {
@@ -350,12 +350,6 @@ impl Iterator for TokenTreeIter {
}
}
-impl Debug for TokenTreeIter {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("TokenTreeIter").finish()
- }
-}
-
#[derive(Clone, PartialEq, Eq)]
#[cfg(super_unstable)]
pub(crate) enum SourceFile {
diff --git a/vendor/proc-macro2/tests/comments.rs b/vendor/proc-macro2/tests/comments.rs
index 71741080c..4f7236dea 100644
--- a/vendor/proc-macro2/tests/comments.rs
+++ b/vendor/proc-macro2/tests/comments.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::assertions_on_result_states)]
+
use proc_macro2::{Delimiter, Literal, Spacing, TokenStream, TokenTree};
// #[doc = "..."] -> "..."
diff --git a/vendor/proc-macro2/tests/test.rs b/vendor/proc-macro2/tests/test.rs
index 86031db6a..16f775ed0 100644
--- a/vendor/proc-macro2/tests/test.rs
+++ b/vendor/proc-macro2/tests/test.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::non_ascii_literal)]
+#![allow(clippy::assertions_on_result_states, clippy::non_ascii_literal)]
use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
use std::panic;
@@ -548,6 +548,13 @@ fn default_tokenstream_is_empty() {
}
#[test]
+fn tokenstream_size_hint() {
+ let tokens = "a b (c d) e".parse::<TokenStream>().unwrap();
+
+ assert_eq!(tokens.into_iter().size_hint(), (4, Some(4)));
+}
+
+#[test]
fn tuple_indexing() {
// This behavior may change depending on https://github.com/rust-lang/rust/pull/71322
let mut tokens = "tuple.0.0".parse::<TokenStream>().unwrap().into_iter();
diff --git a/vendor/quick-error-1.2.3/.cargo-checksum.json b/vendor/quick-error-1.2.3/.cargo-checksum.json
deleted file mode 100644
index 5f19af61c..000000000
--- a/vendor/quick-error-1.2.3/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.lock":"b88df71c076815e9922973e1f54af221486c3a83d5be2c1af9ca650a8f8f526f","Cargo.toml":"1f24b567c7f10b4ec44f5baf033d27da39f659c09df0e8a057437d10ecdd551a","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"058f01fe181608d027fcde7e528fc03ea3cf90f30903c407644b0a9bbc54f500","README.rst":"8bd690e0089d4c38eb71f1327f5144741009f4b2f49f0b16f2547f528171e2e6","bulk.yaml":"17c2548388e0cd3a63473021a2f1e4ddedee082d79d9167cb31ad06a1890d3fc","examples/context.rs":"b9be9a4ca021a1f0ba659932bfc0cf891728bfaea49d48a8be183644c492515b","src/lib.rs":"a02c8a3c40fa1dcee8285b9c238d40cb3078cf4dded1c972fa6361a485d1667f","vagga.yaml":"b01ad1fd3aa25de2439c0f7a437c6517808ba3a7eeeb0363eb209f08e326cc8e"},"package":"a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"} \ No newline at end of file
diff --git a/vendor/quick-error-1.2.3/Cargo.lock b/vendor/quick-error-1.2.3/Cargo.lock
deleted file mode 100644
index da1963ecf..000000000
--- a/vendor/quick-error-1.2.3/Cargo.lock
+++ /dev/null
@@ -1,6 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "quick-error"
-version = "1.2.3"
-
diff --git a/vendor/quick-error-1.2.3/Cargo.toml b/vendor/quick-error-1.2.3/Cargo.toml
deleted file mode 100644
index b5d5f60b1..000000000
--- a/vendor/quick-error-1.2.3/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "quick-error"
-version = "1.2.3"
-authors = ["Paul Colomiets <paul@colomiets.name>", "Colin Kiegel <kiegel@gmx.de>"]
-description = " A macro which makes error types pleasant to write.\n"
-homepage = "http://github.com/tailhook/quick-error"
-documentation = "http://docs.rs/quick-error"
-keywords = ["macro", "error", "type", "enum"]
-categories = ["rust-patterns"]
-license = "MIT/Apache-2.0"
-repository = "http://github.com/tailhook/quick-error"
diff --git a/vendor/quick-error-1.2.3/LICENSE-APACHE b/vendor/quick-error-1.2.3/LICENSE-APACHE
deleted file mode 100644
index 8f71f43fe..000000000
--- a/vendor/quick-error-1.2.3/LICENSE-APACHE
+++ /dev/null
@@ -1,202 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
diff --git a/vendor/quick-error-1.2.3/LICENSE-MIT b/vendor/quick-error-1.2.3/LICENSE-MIT
deleted file mode 100644
index 14f715b80..000000000
--- a/vendor/quick-error-1.2.3/LICENSE-MIT
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2015 The quick-error Developers
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/quick-error-1.2.3/README.rst b/vendor/quick-error-1.2.3/README.rst
deleted file mode 100644
index e54c055c4..000000000
--- a/vendor/quick-error-1.2.3/README.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-===========
-Quick Error
-===========
-
-:Status: production-ready
-:Documentation: http://tailhook.github.io/quick-error/
-
-A macro which makes error types pleasant to write.
-
-Features:
-
-* Define enum type with arbitrary parameters
-* Concise notation of ``Display`` and ``Error`` traits
-* Full control of ``Display`` and ``Error`` trait implementation
-* Any number of ``From`` traits
-* Support for all enum-variants ``Unit``, ``Tuple`` and ``Struct``
-
-Here is the comprehensive example:
-
-.. code-block:: rust
-
- quick_error! {
- #[derive(Debug)]
- pub enum IoWrapper {
- Io(err: io::Error) {
- from()
- display("I/O error: {}", err)
- cause(err)
- }
- Other(descr: &'static str) {
- display("Error {}", descr)
- }
- IoAt { place: &'static str, err: io::Error } {
- cause(err)
- display(me) -> ("io error at {}: {}", place, err)
- from(s: String) -> {
- place: "some string",
- err: io::Error::new(io::ErrorKind::Other, s)
- }
- }
- Discard {
- from(&'static str)
- }
- }
- }
-
-=======
-License
-=======
-
-Licensed under either of
-
- * Apache License, Version 2.0, (./LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license (./LICENSE-MIT or http://opensource.org/licenses/MIT)
-
-at your option.
-
-------------
-Contribution
-------------
-
-Unless you explicitly state otherwise, any contribution intentionally
-submitted for inclusion in the work by you, as defined in the Apache-2.0
-license, shall be dual licensed as above, without any additional terms or
-conditions.
-
diff --git a/vendor/quick-error-1.2.3/bulk.yaml b/vendor/quick-error-1.2.3/bulk.yaml
deleted file mode 100644
index cdb9763b6..000000000
--- a/vendor/quick-error-1.2.3/bulk.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-minimum-bulk: v0.4.5
-
-versions:
-
-- file: Cargo.toml
- block-start: ^\[package\]
- block-end: ^\[.*\]
- regex: ^version\s*=\s*"(\S+)"
diff --git a/vendor/quick-error-1.2.3/examples/context.rs b/vendor/quick-error-1.2.3/examples/context.rs
deleted file mode 100644
index 334700a03..000000000
--- a/vendor/quick-error-1.2.3/examples/context.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-#[macro_use(quick_error)] extern crate quick_error;
-
-use std::io::{self, stderr, Read, Write};
-use std::fs::File;
-use std::env;
-use std::num::ParseIntError;
-use std::path::{Path, PathBuf};
-
-use quick_error::ResultExt;
-
-quick_error! {
- #[derive(Debug)]
- pub enum Error {
- NoFileName {
- description("no file name specified")
- }
- Io(err: io::Error, path: PathBuf) {
- display("could not read file {:?}: {}", path, err)
- context(path: &'a Path, err: io::Error)
- -> (err, path.to_path_buf())
- }
- Parse(err: ParseIntError, path: PathBuf) {
- display("could not parse file {:?}: {}", path, err)
- context(path: &'a Path, err: ParseIntError)
- -> (err, path.to_path_buf())
- }
- }
-}
-
-fn parse_file() -> Result<u64, Error> {
- let fname = try!(env::args().skip(1).next().ok_or(Error::NoFileName));
- let fname = Path::new(&fname);
- let mut file = try!(File::open(fname).context(fname));
- let mut buf = String::new();
- try!(file.read_to_string(&mut buf).context(fname));
- Ok(try!(buf.parse().context(fname)))
-}
-
-fn main() {
- match parse_file() {
- Ok(val) => {
- println!("Read: {}", val);
- }
- Err(e) => {
- writeln!(&mut stderr(), "Error: {}", e).ok();
- }
- }
-}
diff --git a/vendor/quick-error-1.2.3/src/lib.rs b/vendor/quick-error-1.2.3/src/lib.rs
deleted file mode 100644
index 17fc455d4..000000000
--- a/vendor/quick-error-1.2.3/src/lib.rs
+++ /dev/null
@@ -1,1262 +0,0 @@
-#![warn(missing_docs)]
-//! A macro which makes errors easy to write
-//!
-//! Minimum type is like this:
-//!
-//! ```rust
-//! #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//!
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! Variant1 {}
-//! }
-//! }
-//! ```
-//! Both ``pub`` and non-public types may be declared, and all meta attributes
-//! (such as ``#[derive(Debug)]``) are forwarded as is. The `Debug` must be
-//! implemented (but you may do that yourself if you like). The documentation
-//! comments ``/// something`` (as well as other meta attrbiutes) on variants
-//! are allowed.
-//!
-//! # Allowed Syntax
-//!
-//! You may add arbitrary parameters to any struct variant:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! /// IO Error
-//! Io(err: std::io::Error) {}
-//! /// Utf8 Error
-//! Utf8(err: std::str::Utf8Error) {}
-//! }
-//! }
-//! ```
-//!
-//! Note unlike in normal Enum declarations you declare names of fields (which
-//! are omitted from type). How they can be used is outlined below.
-//!
-//! Now you might have noticed trailing braces `{}`. They are used to define
-//! implementations. By default:
-//!
-//! * `Error::cause()` returns None (even if type wraps some value)
-//! * `Display` outputs debug representation
-//! * No `From` implementations are defined
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! Io(err: std::io::Error) {
-//! display("{}", err)
-//! }
-//! Utf8(err: std::str::Utf8Error) {
-//! display("utf8 error")
-//! }
-//! }
-//! }
-//! ```
-//!
-//! To change `cause` method to return some error, add `cause(value)`, for
-//! example:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! Io(err: std::io::Error) {
-//! cause(err)
-//! }
-//! Utf8(err: std::str::Utf8Error) {
-//! display("utf8 error")
-//! }
-//! Other(err: Box<std::error::Error>) {
-//! cause(&**err)
-//! }
-//! }
-//! }
-//! ```
-//! Note you don't need to wrap value in `Some`, its implicit. In case you want
-//! `None` returned just omit the `cause`. You can't return `None`
-//! conditionally.
-//!
-//! To change how each clause is `Display`ed add `display(pattern,..args)`,
-//! for example:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! Io(err: std::io::Error) {
-//! display("I/O error: {}", err)
-//! }
-//! Utf8(err: std::str::Utf8Error) {
-//! display("Utf8 error, valid up to {}", err.valid_up_to())
-//! }
-//! }
-//! }
-//! ```
-//!
-//! If you need a reference to the error when `Display`ing, you can instead use
-//! `display(x) -> (pattern, ..args)`, where `x` sets the name of the reference.
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! use std::error::Error; // put methods like `source()` of this trait into scope
-//!
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! Io(err: std::io::Error) {
-//! display(x) -> ("I/O: {}", err)
-//! }
-//! Utf8(err: std::str::Utf8Error) {
-//! display(self_) -> ("UTF-8 error. Valid up to {}", err.valid_up_to())
-//! }
-//! }
-//! }
-//! ```
-//!
-//! To convert to the type from any other, use one of the three forms of
-//! `from` clause.
-//!
-//! For example, to convert simple wrapper use bare `from()`:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! Io(err: std::io::Error) {
-//! from()
-//! }
-//! }
-//! }
-//! ```
-//!
-//! This implements ``From<io::Error>``.
-//!
-//! To convert to singleton enumeration type (discarding the value), use
-//! the `from(type)` form:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! FormatError {
-//! from(std::fmt::Error)
-//! }
-//! }
-//! }
-//! ```
-//!
-//! And the most powerful form is `from(var: type) -> (arguments...)`. It
-//! might be used to convert to type with multiple arguments or for arbitrary
-//! value conversions:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//! #
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum SomeError {
-//! FailedOperation(s: &'static str, errno: i32) {
-//! from(errno: i32) -> ("os error", errno)
-//! from(e: std::io::Error) -> ("io error", e.raw_os_error().unwrap())
-//! }
-//! /// Converts from both kinds of utf8 errors
-//! Utf8(err: std::str::Utf8Error) {
-//! from()
-//! from(err: std::string::FromUtf8Error) -> (err.utf8_error())
-//! }
-//! }
-//! }
-//! ```
-//! # Context
-//!
-//! Since quick-error 1.1 we also have a `context` declaration, which is
-//! similar to (the longest form of) `from`, but allows adding some context to
-//! the error. We need a longer example to demonstrate this:
-//!
-//! ```rust
-//! # #[macro_use] extern crate quick_error;
-//! # use std::io;
-//! # use std::fs::File;
-//! # use std::path::{Path, PathBuf};
-//! #
-//! use quick_error::ResultExt;
-//!
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum Error {
-//! File(filename: PathBuf, err: io::Error) {
-//! context(path: &'a Path, err: io::Error)
-//! -> (path.to_path_buf(), err)
-//! }
-//! }
-//! }
-//!
-//! fn openfile(path: &Path) -> Result<(), Error> {
-//! try!(File::open(path).context(path));
-//!
-//! // If we didn't have context, the line above would be written as;
-//! //
-//! // try!(File::open(path)
-//! // .map_err(|err| Error::File(path.to_path_buf(), err)));
-//!
-//! Ok(())
-//! }
-//!
-//! # fn main() {
-//! # openfile(Path::new("/etc/somefile")).ok();
-//! # }
-//! ```
-//!
-//! Each `context(a: A, b: B)` clause implements
-//! `From<Context<A, B>> for Error`. Which means multiple `context` clauses
-//! are a subject to the normal coherence rules. Unfortunately, we can't
-//! provide full support of generics for the context, but you may either use a
-//! lifetime `'a` for references or `AsRef<Type>` (the latter means `A:
-//! AsRef<Type>`, and `Type` must be concrete). It's also occasionally useful
-//! to use a tuple as a type of the first argument.
-//!
-//! You also need to `use quick_error::ResultExt` extension trait to get
-//! working `.context()` method.
-//!
-//! More info on context in [this article](http://bit.ly/1PsuxDt).
-//!
-//! All forms of `from`, `display`, `cause`, and `context`
-//! clauses can be combined and put in arbitrary order. Only `from` and
-//! `context` can be used multiple times in single variant of enumeration.
-//! Docstrings are also okay. Empty braces can be omitted as of quick_error
-//! 0.1.3.
-//!
-//! # Private Enums
-//!
-//! Since quick-error 1.2.0 we have a way to make a private enum that is
-//! wrapped by public structure:
-//!
-//! ```rust
-//! #[macro_use] extern crate quick_error;
-//! # fn main() {}
-//!
-//! quick_error! {
-//! #[derive(Debug)]
-//! pub enum PubError wraps ErrorEnum {
-//! Variant1 {}
-//! }
-//! }
-//! ```
-//!
-//! This generates data structures like this
-//!
-//! ```rust
-//!
-//! pub struct PubError(ErrorEnum);
-//!
-//! enum ErrorEnum {
-//! Variant1,
-//! }
-//!
-//! ```
-//!
-//! Which in turn allows you to export just `PubError` in your crate and keep
-//! actual enumeration private to the crate. This is useful to keep backwards
-//! compatibility for error types. Currently there is no shorcuts to define
-//! error constructors for the inner type, but we consider adding some in
-//! future versions.
-//!
-//! It's possible to declare internal enum as public too.
-//!
-//!
-
-
-/// Main macro that does all the work
-#[macro_export]
-macro_rules! quick_error {
-
- ( $(#[$meta:meta])*
- pub enum $name:ident { $($chunks:tt)* }
- ) => {
- quick_error!(SORT [pub enum $name $(#[$meta])* ]
- items [] buf []
- queue [ $($chunks)* ]);
- };
- ( $(#[$meta:meta])*
- enum $name:ident { $($chunks:tt)* }
- ) => {
- quick_error!(SORT [enum $name $(#[$meta])* ]
- items [] buf []
- queue [ $($chunks)* ]);
- };
-
- ( $(#[$meta:meta])*
- pub enum $name:ident wraps $enum_name:ident { $($chunks:tt)* }
- ) => {
- quick_error!(WRAPPER $enum_name [ pub struct ] $name $(#[$meta])*);
- quick_error!(SORT [enum $enum_name $(#[$meta])* ]
- items [] buf []
- queue [ $($chunks)* ]);
- };
-
- ( $(#[$meta:meta])*
- pub enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* }
- ) => {
- quick_error!(WRAPPER $enum_name [ pub struct ] $name $(#[$meta])*);
- quick_error!(SORT [pub enum $enum_name $(#[$meta])* ]
- items [] buf []
- queue [ $($chunks)* ]);
- };
- ( $(#[$meta:meta])*
- enum $name:ident wraps $enum_name:ident { $($chunks:tt)* }
- ) => {
- quick_error!(WRAPPER $enum_name [ struct ] $name $(#[$meta])*);
- quick_error!(SORT [enum $enum_name $(#[$meta])* ]
- items [] buf []
- queue [ $($chunks)* ]);
- };
-
- ( $(#[$meta:meta])*
- enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* }
- ) => {
- quick_error!(WRAPPER $enum_name [ struct ] $name $(#[$meta])*);
- quick_error!(SORT [pub enum $enum_name $(#[$meta])* ]
- items [] buf []
- queue [ $($chunks)* ]);
- };
-
-
- (
- WRAPPER $internal:ident [ $($strdef:tt)* ] $strname:ident
- $(#[$meta:meta])*
- ) => {
- $(#[$meta])*
- $($strdef)* $strname ( $internal );
-
- impl ::std::fmt::Display for $strname {
- fn fmt(&self, f: &mut ::std::fmt::Formatter)
- -> ::std::fmt::Result
- {
- ::std::fmt::Display::fmt(&self.0, f)
- }
- }
-
- impl From<$internal> for $strname {
- fn from(err: $internal) -> Self {
- $strname(err)
- }
- }
-
- impl ::std::error::Error for $strname {
- #[allow(deprecated)]
- fn cause(&self) -> Option<&::std::error::Error> {
- self.0.cause()
- }
- }
- };
-
- // Queue is empty, can do the work
- (SORT [enum $name:ident $( #[$meta:meta] )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [ ]
- queue [ ]
- ) => {
- quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*]
- body []
- queue [$($( #[$imeta] )*
- => $iitem: $imode [$( $ivar: $ityp ),*] )*]
- );
- quick_error!(IMPLEMENTATIONS $name {$(
- $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
- )*});
- $(
- quick_error!(ERROR_CHECK $imode $($ifuncs)*);
- )*
- };
- (SORT [pub enum $name:ident $( #[$meta:meta] )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [ ]
- queue [ ]
- ) => {
- quick_error!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*]
- body []
- queue [$($( #[$imeta] )*
- => $iitem: $imode [$( $ivar: $ityp ),*] )*]
- );
- quick_error!(IMPLEMENTATIONS $name {$(
- $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
- )*});
- $(
- quick_error!(ERROR_CHECK $imode $($ifuncs)*);
- )*
- };
- // Add meta to buffer
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )*]
- queue [ #[$qmeta:meta] $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* #[$qmeta] ]
- queue [$( $tail )*]);
- };
- // Add ident to buffer
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )*]
- queue [ $qitem:ident $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])*
- => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$(#[$bmeta])* => $qitem : UNIT [ ] ]
- queue [$( $tail )*]);
- };
- // Flush buffer on meta after ident
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )*
- => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
- queue [ #[$qmeta:meta] $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*
- $(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*]
- items [$($( #[$imeta:meta] )*
- => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
- $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
- buf [ #[$qmeta] ]
- queue [$( $tail )*]);
- };
- // Add tuple enum-variant
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
- queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),*] ]
- queue [$( $tail )*]
- );
- };
- // Add struct enum-variant - e.g. { descr: &'static str }
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
- queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
- queue [$( $tail )*]);
- };
- // Add struct enum-variant, with excess comma - e.g. { descr: &'static str, }
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
- queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
- queue [$( $tail )*]);
- };
- // Add braces and flush always on braces
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )*
- => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
- queue [ {$( $qfuncs:tt )*} $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
- $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ]
- buf [ ]
- queue [$( $tail )*]);
- };
- // Flush buffer on double ident
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )*
- => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
- queue [ $qitem:ident $( $tail:tt )*]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
- $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
- buf [ => $qitem : UNIT [ ] ]
- queue [$( $tail )*]);
- };
- // Flush buffer on end
- (SORT [$( $def:tt )*]
- items [$($( #[$imeta:meta] )*
- => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
- {$( $ifuncs:tt )*} )* ]
- buf [$( #[$bmeta:meta] )*
- => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
- queue [ ]
- ) => {
- quick_error!(SORT [$( $def )*]
- items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
- $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
- buf [ ]
- queue [ ]);
- };
- // Public enum (Queue Empty)
- (ENUM_DEFINITION [pub enum $name:ident $( #[$meta:meta] )*]
- body [$($( #[$imeta:meta] )*
- => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
- queue [ ]
- ) => {
- #[allow(unknown_lints)] // no unused_doc_comments in older rust
- #[allow(renamed_and_removed_lints)]
- #[allow(unused_doc_comment)]
- #[allow(unused_doc_comments)]
- $(#[$meta])*
- pub enum $name {
- $(
- $(#[$imeta])*
- $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
- )*
- }
- };
- // Private enum (Queue Empty)
- (ENUM_DEFINITION [enum $name:ident $( #[$meta:meta] )*]
- body [$($( #[$imeta:meta] )*
- => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
- queue [ ]
- ) => {
- #[allow(unknown_lints)] // no unused_doc_comments in older rust
- #[allow(renamed_and_removed_lints)]
- #[allow(unused_doc_comment)]
- #[allow(unused_doc_comments)]
- $(#[$meta])*
- enum $name {
- $(
- $(#[$imeta])*
- $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
- )*
- }
- };
- // Unit variant
- (ENUM_DEFINITION [$( $def:tt )*]
- body [$($( #[$imeta:meta] )*
- => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
- queue [$( #[$qmeta:meta] )*
- => $qitem:ident: UNIT [ ] $( $queue:tt )*]
- ) => {
- quick_error!(ENUM_DEFINITION [ $($def)* ]
- body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
- $( #[$qmeta] )* => $qitem () {} ]
- queue [ $($queue)* ]
- );
- };
- // Tuple variant
- (ENUM_DEFINITION [$( $def:tt )*]
- body [$($( #[$imeta:meta] )*
- => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
- queue [$( #[$qmeta:meta] )*
- => $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*]
- ) => {
- quick_error!(ENUM_DEFINITION [ $($def)* ]
- body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
- $( #[$qmeta] )* => $qitem (($( $qtyp ),*)) {} ]
- queue [ $($queue)* ]
- );
- };
- // Struct variant
- (ENUM_DEFINITION [$( $def:tt )*]
- body [$($( #[$imeta:meta] )*
- => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
- queue [$( #[$qmeta:meta] )*
- => $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*]
- ) => {
- quick_error!(ENUM_DEFINITION [ $($def)* ]
- body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
- $( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ]
- queue [ $($queue)* ]
- );
- };
- (IMPLEMENTATIONS
- $name:ident {$(
- $item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*}
- )*}
- ) => {
- #[allow(unused)]
- #[allow(unknown_lints)] // no unused_doc_comments in older rust
- #[allow(renamed_and_removed_lints)]
- #[allow(unused_doc_comment)]
- #[allow(unused_doc_comments)]
- impl ::std::fmt::Display for $name {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
- -> ::std::fmt::Result
- {
- match *self {
- $(
- $(#[$imeta])*
- quick_error!(ITEM_PATTERN
- $name $item: $imode [$( ref $var ),*]
- ) => {
- let display_fn = quick_error!(FIND_DISPLAY_IMPL
- $name $item: $imode
- {$( $funcs )*});
-
- display_fn(self, fmt)
- }
- )*
- }
- }
- }
- #[allow(unused)]
- #[allow(unknown_lints)] // no unused_doc_comments in older rust
- #[allow(renamed_and_removed_lints)]
- #[allow(unused_doc_comment)]
- #[allow(unused_doc_comments)]
- impl ::std::error::Error for $name {
- fn cause(&self) -> Option<&::std::error::Error> {
- match *self {
- $(
- $(#[$imeta])*
- quick_error!(ITEM_PATTERN
- $name $item: $imode [$( ref $var ),*]
- ) => {
- quick_error!(FIND_CAUSE_IMPL
- $item: $imode [$( $var ),*]
- {$( $funcs )*})
- }
- )*
- }
- }
- }
- $(
- quick_error!(FIND_FROM_IMPL
- $name $item: $imode [$( $var:$typ ),*]
- {$( $funcs )*});
- )*
- $(
- quick_error!(FIND_CONTEXT_IMPL
- $name $item: $imode [$( $var:$typ ),*]
- {$( $funcs )*});
- )*
- };
- (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
- { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
- ) => {
- |quick_error!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| { write!(f, $( $exprs )*) }
- };
- (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
- { display($pattern:expr) $( $tail:tt )*}
- ) => {
- |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern) }
- };
- (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
- { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*}
- ) => {
- |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern, $( $exprs )*) }
- };
- (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
- { $t:tt $( $tail:tt )*}
- ) => {
- quick_error!(FIND_DISPLAY_IMPL
- $name $item: $imode
- {$( $tail )*})
- };
- (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
- { }
- ) => {
- |self_: &$name, f: &mut ::std::fmt::Formatter| {
- write!(f, "{:?}", self_)
- }
- };
- (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
- [$( $var:ident ),*]
- { description($expr:expr) $( $tail:tt )*}
- ) => {};
- (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
- [$( $var:ident ),*]
- { $t:tt $( $tail:tt )*}
- ) => {};
- (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
- [$( $var:ident ),*]
- { }
- ) => {};
- (FIND_CAUSE_IMPL $item:ident: $imode:tt
- [$( $var:ident ),*]
- { cause($expr:expr) $( $tail:tt )*}
- ) => {
- Some($expr)
- };
- (FIND_CAUSE_IMPL $item:ident: $imode:tt
- [$( $var:ident ),*]
- { $t:tt $( $tail:tt )*}
- ) => {
- quick_error!(FIND_CAUSE_IMPL
- $item: $imode [$( $var ),*]
- { $($tail)* })
- };
- (FIND_CAUSE_IMPL $item:ident: $imode:tt
- [$( $var:ident ),*]
- { }
- ) => {
- None
- };
- // ----------------------------- FROM IMPL --------------------------
- (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
- [$( $var:ident: $typ:ty ),*]
- { from() $( $tail:tt )*}
- ) => {
- $(
- impl From<$typ> for $name {
- fn from($var: $typ) -> $name {
- $name::$item($var)
- }
- }
- )*
- quick_error!(FIND_FROM_IMPL
- $name $item: $imode [$( $var:$typ ),*]
- {$( $tail )*});
- };
- (FIND_FROM_IMPL $name:ident $item:ident: UNIT
- [ ]
- { from($ftyp:ty) $( $tail:tt )*}
- ) => {
- impl From<$ftyp> for $name {
- fn from(_discarded_error: $ftyp) -> $name {
- $name::$item
- }
- }
- quick_error!(FIND_FROM_IMPL
- $name $item: UNIT [ ]
- {$( $tail )*});
- };
- (FIND_FROM_IMPL $name:ident $item:ident: TUPLE
- [$( $var:ident: $typ:ty ),*]
- { from($fvar:ident: $ftyp:ty) -> ($( $texpr:expr ),*) $( $tail:tt )*}
- ) => {
- impl From<$ftyp> for $name {
- fn from($fvar: $ftyp) -> $name {
- $name::$item($( $texpr ),*)
- }
- }
- quick_error!(FIND_FROM_IMPL
- $name $item: TUPLE [$( $var:$typ ),*]
- { $($tail)* });
- };
- (FIND_FROM_IMPL $name:ident $item:ident: STRUCT
- [$( $var:ident: $typ:ty ),*]
- { from($fvar:ident: $ftyp:ty) -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )*}
- ) => {
- impl From<$ftyp> for $name {
- fn from($fvar: $ftyp) -> $name {
- $name::$item {
- $( $tvar: $texpr ),*
- }
- }
- }
- quick_error!(FIND_FROM_IMPL
- $name $item: STRUCT [$( $var:$typ ),*]
- { $($tail)* });
- };
- (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
- [$( $var:ident: $typ:ty ),*]
- { $t:tt $( $tail:tt )*}
- ) => {
- quick_error!(FIND_FROM_IMPL
- $name $item: $imode [$( $var:$typ ),*]
- {$( $tail )*}
- );
- };
- (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
- [$( $var:ident: $typ:ty ),*]
- { }
- ) => {
- };
- // ----------------------------- CONTEXT IMPL --------------------------
- (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE
- [$( $var:ident: $typ:ty ),*]
- { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty)
- -> ($( $texpr:expr ),*) $( $tail:tt )* }
- ) => {
- impl<T: AsRef<$ctyp>> From<$crate::Context<T, $ftyp>> for $name {
- fn from(
- $crate::Context($cvar, $fvar): $crate::Context<T, $ftyp>)
- -> $name
- {
- $name::$item($( $texpr ),*)
- }
- }
- quick_error!(FIND_CONTEXT_IMPL
- $name $item: TUPLE [$( $var:$typ ),*]
- { $($tail)* });
- };
- (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE
- [$( $var:ident: $typ:ty ),*]
- { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
- -> ($( $texpr:expr ),*) $( $tail:tt )* }
- ) => {
- impl<'a> From<$crate::Context<$ctyp, $ftyp>> for $name {
- fn from(
- $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>)
- -> $name
- {
- $name::$item($( $texpr ),*)
- }
- }
- quick_error!(FIND_CONTEXT_IMPL
- $name $item: TUPLE [$( $var:$typ ),*]
- { $($tail)* });
- };
- (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT
- [$( $var:ident: $typ:ty ),*]
- { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty)
- -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* }
- ) => {
- impl<T: AsRef<$ctyp>> From<$crate::Context<T, $ftyp>> for $name {
- fn from(
- $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>)
- -> $name
- {
- $name::$item {
- $( $tvar: $texpr ),*
- }
- }
- }
- quick_error!(FIND_CONTEXT_IMPL
- $name $item: STRUCT [$( $var:$typ ),*]
- { $($tail)* });
- };
- (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT
- [$( $var:ident: $typ:ty ),*]
- { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
- -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* }
- ) => {
- impl<'a> From<$crate::Context<$ctyp, $ftyp>> for $name {
- fn from(
- $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>)
- -> $name
- {
- $name::$item {
- $( $tvar: $texpr ),*
- }
- }
- }
- quick_error!(FIND_CONTEXT_IMPL
- $name $item: STRUCT [$( $var:$typ ),*]
- { $($tail)* });
- };
- (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt
- [$( $var:ident: $typ:ty ),*]
- { $t:tt $( $tail:tt )*}
- ) => {
- quick_error!(FIND_CONTEXT_IMPL
- $name $item: $imode [$( $var:$typ ),*]
- {$( $tail )*}
- );
- };
- (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt
- [$( $var:ident: $typ:ty ),*]
- { }
- ) => {
- };
- // ----------------------------- ITEM IMPL --------------------------
- (ITEM_BODY $(#[$imeta:meta])* $item:ident: UNIT
- ) => { };
- (ITEM_BODY $(#[$imeta:meta])* $item:ident: TUPLE
- [$( $typ:ty ),*]
- ) => {
- ($( $typ ),*)
- };
- (ITEM_BODY $(#[$imeta:meta])* $item:ident: STRUCT
- [$( $var:ident: $typ:ty ),*]
- ) => {
- {$( $var:$typ ),*}
- };
- (ITEM_PATTERN $name:ident $item:ident: UNIT []
- ) => {
- $name::$item
- };
- (ITEM_PATTERN $name:ident $item:ident: TUPLE
- [$( ref $var:ident ),*]
- ) => {
- $name::$item ($( ref $var ),*)
- };
- (ITEM_PATTERN $name:ident $item:ident: STRUCT
- [$( ref $var:ident ),*]
- ) => {
- $name::$item {$( ref $var ),*}
- };
- // This one should match all allowed sequences in "funcs" but not match
- // anything else.
- // This is to contrast FIND_* clauses which just find stuff they need and
- // skip everything else completely
- (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt from() $($tail:tt)*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*)
- => { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK TUPLE $($tail)*); };
- (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK STRUCT $($tail)*); };
-
- (ERROR_CHECK TUPLE context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
- -> ($( $e:expr ),*) $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK TUPLE $($tail)*); };
- (ERROR_CHECK STRUCT context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
- -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*)
- => { quick_error!(ERROR_CHECK STRUCT $($tail)*); };
-
- (ERROR_CHECK $imode:tt ) => {};
- // Utility functions
- (IDENT $ident:ident) => { $ident }
-}
-
-
-/// Generic context type
-///
-/// Used mostly as a transport for `ResultExt::context` method
-#[derive(Debug)]
-pub struct Context<X, E>(pub X, pub E);
-
-/// Result extension trait adding a `context` method
-pub trait ResultExt<T, E> {
- /// The method is use to add context information to current operation
- ///
- /// The context data is then used in error constructor to store additional
- /// information within error. For example, you may add a filename as a
- /// context for file operation. See crate documentation for the actual
- /// example.
- fn context<X>(self, x: X) -> Result<T, Context<X, E>>;
-}
-
-impl<T, E> ResultExt<T, E> for Result<T, E> {
- fn context<X>(self, x: X) -> Result<T, Context<X, E>> {
- self.map_err(|e| Context(x, e))
- }
-}
-
-
-
-#[cfg(test)]
-#[allow(deprecated)]
-mod test {
- use std::num::{ParseFloatError, ParseIntError};
- use std::str::Utf8Error;
- use std::string::FromUtf8Error;
- use std::error::Error;
- use std::path::{Path, PathBuf};
-
- use super::ResultExt;
-
- quick_error! {
- #[derive(Debug)]
- pub enum Bare {
- One
- Two
- }
- }
-
- #[test]
- fn bare_item_direct() {
- assert_eq!(format!("{}", Bare::One), "One".to_string());
- assert_eq!(format!("{:?}", Bare::One), "One".to_string());
- assert!(Bare::One.cause().is_none());
- }
- #[test]
- fn bare_item_trait() {
- let err: &Error = &Bare::Two;
- assert_eq!(format!("{}", err), "Two".to_string());
- assert_eq!(format!("{:?}", err), "Two".to_string());
- assert!(err.cause().is_none());
- }
-
- quick_error! {
- #[derive(Debug)]
- pub enum Wrapper wraps Wrapped {
- One
- Two(s: String) {
- display("two: {}", s)
- from()
- }
- }
- }
-
- #[test]
- fn wrapper() {
- assert_eq!(format!("{}", Wrapper::from(Wrapped::One)),
- "One".to_string());
- assert_eq!(format!("{}",
- Wrapper::from(Wrapped::from(String::from("hello")))),
- "two: hello".to_string());
- assert_eq!(format!("{:?}", Wrapper::from(Wrapped::One)),
- "Wrapper(One)".to_string());
- }
-
- quick_error! {
- #[derive(Debug, PartialEq)]
- pub enum TupleWrapper {
- /// ParseFloat Error
- ParseFloatError(err: ParseFloatError) {
- from()
- display("parse float error: {err}", err=err)
- cause(err)
- }
- Other(descr: &'static str) {
- display("Error: {}", descr)
- }
- /// FromUtf8 Error
- FromUtf8Error(err: Utf8Error, source: Vec<u8>) {
- cause(err)
- display(me) -> ("{desc} at index {pos}: {err}", desc="utf8 error", pos=err.valid_up_to(), err=err)
- from(err: FromUtf8Error) -> (err.utf8_error().clone(), err.into_bytes())
- }
- Discard {
- from(&'static str)
- }
- Singleton {
- display("Just a string")
- }
- }
- }
-
- #[test]
- fn tuple_wrapper_err() {
- let cause = "one and a half times pi".parse::<f32>().unwrap_err();
- let err = TupleWrapper::ParseFloatError(cause.clone());
- assert_eq!(format!("{}", err), format!("parse float error: {}", cause));
- assert_eq!(format!("{:?}", err), format!("ParseFloatError({:?})", cause));
- assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
- }
-
- #[test]
- fn tuple_wrapper_trait_str() {
- let desc = "hello";
- let err: &Error = &TupleWrapper::Other(desc);
- assert_eq!(format!("{}", err), format!("Error: {}", desc));
- assert_eq!(format!("{:?}", err), format!("Other({:?})", desc));
- assert!(err.cause().is_none());
- }
-
- #[test]
- fn tuple_wrapper_trait_two_fields() {
- let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
- let err: &Error = &TupleWrapper::FromUtf8Error(cause.clone(), invalid_utf8.clone());
- assert_eq!(format!("{}", err), format!("{desc} at index {pos}: {cause}", desc="utf8 error", pos=cause.valid_up_to(), cause=cause));
- assert_eq!(format!("{:?}", err), format!("FromUtf8Error({:?}, {:?})", cause, invalid_utf8));
- assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
- }
-
- #[test]
- fn tuple_wrapper_from() {
- let cause = "one and a half times pi".parse::<f32>().unwrap_err();
- let err = TupleWrapper::ParseFloatError(cause.clone());
- let err_from: TupleWrapper = From::from(cause);
- assert_eq!(err_from, err);
- }
-
- #[test]
- fn tuple_wrapper_custom_from() {
- let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err();
- let err = TupleWrapper::FromUtf8Error(cause.utf8_error().clone(), invalid_utf8);
- let err_from: TupleWrapper = From::from(cause);
- assert_eq!(err_from, err);
- }
-
- #[test]
- fn tuple_wrapper_discard() {
- let err: TupleWrapper = From::from("hello");
- assert_eq!(format!("{}", err), format!("Discard"));
- assert_eq!(format!("{:?}", err), format!("Discard"));
- assert!(err.cause().is_none());
- }
-
- #[test]
- fn tuple_wrapper_singleton() {
- let err: TupleWrapper = TupleWrapper::Singleton;
- assert_eq!(format!("{}", err), format!("Just a string"));
- assert_eq!(format!("{:?}", err), format!("Singleton"));
- assert!(err.cause().is_none());
- }
-
- quick_error! {
- #[derive(Debug, PartialEq)]
- pub enum StructWrapper {
- // Utf8 Error
- Utf8Error{ err: Utf8Error, hint: Option<&'static str> } {
- cause(err)
- display(me) -> ("{desc} at index {pos}: {err}", desc="utf8 error", pos=err.valid_up_to(), err=err)
- from(err: Utf8Error) -> { err: err, hint: None }
- }
- // Utf8 Error
- ExcessComma { descr: &'static str, } {
- display("Error: {}", descr)
- }
- }
- }
-
- #[test]
- fn struct_wrapper_err() {
- let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
- let err: &Error = &StructWrapper::Utf8Error{ err: cause.clone(), hint: Some("nonsense") };
- assert_eq!(format!("{}", err), format!("{desc} at index {pos}: {cause}", desc="utf8 error", pos=cause.valid_up_to(), cause=cause));
- assert_eq!(format!("{:?}", err), format!("Utf8Error {{ err: {:?}, hint: {:?} }}", cause, Some("nonsense")));
- assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
- }
-
- #[test]
- fn struct_wrapper_struct_from() {
- let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
- let err = StructWrapper::Utf8Error{ err: cause.clone(), hint: None };
- let err_from: StructWrapper = From::from(cause);
- assert_eq!(err_from, err);
- }
-
- #[test]
- fn struct_wrapper_excess_comma() {
- let descr = "hello";
- let err = StructWrapper::ExcessComma { descr: descr };
- assert_eq!(format!("{}", err), format!("Error: {}", descr));
- assert_eq!(format!("{:?}", err), format!("ExcessComma {{ descr: {:?} }}", descr));
- assert!(err.cause().is_none());
- }
-
- quick_error! {
- #[derive(Debug)]
- pub enum ContextErr {
- Float(src: String, err: ParseFloatError) {
- context(s: &'a str, e: ParseFloatError) -> (s.to_string(), e)
- display("Float error {:?}: {}", src, err)
- }
- Int { src: String, err: ParseIntError } {
- context(s: &'a str, e: ParseIntError)
- -> {src: s.to_string(), err: e}
- display("Int error {:?}: {}", src, err)
- }
- Utf8(path: PathBuf, err: Utf8Error) {
- context(p: AsRef<Path>, e: Utf8Error)
- -> (p.as_ref().to_path_buf(), e)
- display("Path error at {:?}: {}", path, err)
- }
- Utf8Str(s: String, err: ::std::io::Error) {
- context(s: AsRef<str>, e: ::std::io::Error)
- -> (s.as_ref().to_string(), e)
- display("Str error {:?}: {}", s, err)
- }
- }
- }
-
- #[test]
- fn parse_float_error() {
- fn parse_float(s: &str) -> Result<f32, ContextErr> {
- Ok(try!(s.parse().context(s)))
- }
- assert_eq!(format!("{}", parse_float("12ab").unwrap_err()),
- r#"Float error "12ab": invalid float literal"#);
- }
-
- #[test]
- fn parse_int_error() {
- fn parse_int(s: &str) -> Result<i32, ContextErr> {
- Ok(try!(s.parse().context(s)))
- }
- assert_eq!(format!("{}", parse_int("12.5").unwrap_err()),
- r#"Int error "12.5": invalid digit found in string"#);
- }
-
- #[test]
- fn debug_context() {
- fn parse_int(s: &str) -> i32 {
- s.parse().context(s).unwrap()
- }
- assert_eq!(parse_int("12"), 12);
- assert_eq!(format!("{:?}", "x".parse::<i32>().context("x")),
- r#"Err(Context("x", ParseIntError { kind: InvalidDigit }))"#);
- }
-
- #[test]
- fn path_context() {
- fn parse_utf<P: AsRef<Path>>(s: &[u8], p: P)
- -> Result<(), ContextErr>
- {
- try!(::std::str::from_utf8(s).context(p));
- Ok(())
- }
- let etext = parse_utf(b"a\x80\x80", "/etc").unwrap_err().to_string();
- assert!(etext.starts_with(
- "Path error at \"/etc\": invalid utf-8"));
- let etext = parse_utf(b"\x80\x80", PathBuf::from("/tmp")).unwrap_err()
- .to_string();
- assert!(etext.starts_with(
- "Path error at \"/tmp\": invalid utf-8"));
- }
-
- #[test]
- fn conditional_compilation() {
- quick_error! {
- #[allow(dead_code)]
- #[derive(Debug)]
- pub enum Test {
- #[cfg(feature = "foo")]
- Variant
- }
- }
- }
-}
diff --git a/vendor/quick-error-1.2.3/vagga.yaml b/vendor/quick-error-1.2.3/vagga.yaml
deleted file mode 100644
index 71b9be44e..000000000
--- a/vendor/quick-error-1.2.3/vagga.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-commands:
-
- cargo: !Command
- description: Run any cargo command
- container: ubuntu
- run: [cargo]
-
- test: !Command
- description: Run unit tests
- container: ubuntu
- run: [cargo, test]
-
- _bulk: !Command
- description: Run `bulk` command (for version bookkeeping)
- container: ubuntu
- run: [bulk]
-
-containers:
-
- ubuntu:
- setup:
- - !Ubuntu xenial
- - !Install [ca-certificates, build-essential, vim]
-
- - !TarInstall
- url: "https://static.rust-lang.org/dist/rust-1.16.0-x86_64-unknown-linux-gnu.tar.gz"
- script: "./install.sh --prefix=/usr \
- --components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo"
- - &bulk !Tar
- url: "https://github.com/tailhook/bulk/releases/download/v0.4.9/bulk-v0.4.9.tar.gz"
- sha256: 23471a9986274bb4b7098c03e2eb7e1204171869b72c45385fcee1c64db2d111
- path: /
-
- environ:
- HOME: /work/target
- USER: pc
diff --git a/vendor/quick-error/.cargo-checksum.json b/vendor/quick-error/.cargo-checksum.json
index 869218ba2..5f19af61c 100644
--- a/vendor/quick-error/.cargo-checksum.json
+++ b/vendor/quick-error/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.lock":"d586689373f57572b86215aba1457e8486665e3a598e00b8f3f352b129e8aab5","Cargo.toml":"65148316f0d5161bbc86cd08f3feedf44936284c0665603baacf503d933a256e","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"058f01fe181608d027fcde7e528fc03ea3cf90f30903c407644b0a9bbc54f500","README.rst":"97f715a3a68ede33bca81c98ad791375b2bb7ad0d814377b0651f5c4de8f7d4a","bulk.yaml":"17c2548388e0cd3a63473021a2f1e4ddedee082d79d9167cb31ad06a1890d3fc","examples/context.rs":"5045319e03fa5214c7b2f9ef28d6012ffd34f7095d2103b5579a4c8567ddab68","src/lib.rs":"c94106502d7afb9ffb18b57ba9b42075b28017c765529e30db75a0e612152ec0","vagga.yaml":"280ac771f03284bb3f7e1b5b50c0b8046e79cc5c54f40b7c738f7a8ebaa586f2"},"package":"3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda"} \ No newline at end of file
+{"files":{"Cargo.lock":"b88df71c076815e9922973e1f54af221486c3a83d5be2c1af9ca650a8f8f526f","Cargo.toml":"1f24b567c7f10b4ec44f5baf033d27da39f659c09df0e8a057437d10ecdd551a","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"058f01fe181608d027fcde7e528fc03ea3cf90f30903c407644b0a9bbc54f500","README.rst":"8bd690e0089d4c38eb71f1327f5144741009f4b2f49f0b16f2547f528171e2e6","bulk.yaml":"17c2548388e0cd3a63473021a2f1e4ddedee082d79d9167cb31ad06a1890d3fc","examples/context.rs":"b9be9a4ca021a1f0ba659932bfc0cf891728bfaea49d48a8be183644c492515b","src/lib.rs":"a02c8a3c40fa1dcee8285b9c238d40cb3078cf4dded1c972fa6361a485d1667f","vagga.yaml":"b01ad1fd3aa25de2439c0f7a437c6517808ba3a7eeeb0363eb209f08e326cc8e"},"package":"a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"} \ No newline at end of file
diff --git a/vendor/quick-error/Cargo.lock b/vendor/quick-error/Cargo.lock
index 4e9e64eb5..da1963ecf 100644
--- a/vendor/quick-error/Cargo.lock
+++ b/vendor/quick-error/Cargo.lock
@@ -2,4 +2,5 @@
# It is not intended for manual editing.
[[package]]
name = "quick-error"
-version = "2.0.0"
+version = "1.2.3"
+
diff --git a/vendor/quick-error/Cargo.toml b/vendor/quick-error/Cargo.toml
index f5f929231..b5d5f60b1 100644
--- a/vendor/quick-error/Cargo.toml
+++ b/vendor/quick-error/Cargo.toml
@@ -11,9 +11,8 @@
# will likely look very different (and much more reasonable)
[package]
-edition = "2018"
name = "quick-error"
-version = "2.0.0"
+version = "1.2.3"
authors = ["Paul Colomiets <paul@colomiets.name>", "Colin Kiegel <kiegel@gmx.de>"]
description = " A macro which makes error types pleasant to write.\n"
homepage = "http://github.com/tailhook/quick-error"
diff --git a/vendor/quick-error/README.rst b/vendor/quick-error/README.rst
index 67773e8ab..e54c055c4 100644
--- a/vendor/quick-error/README.rst
+++ b/vendor/quick-error/README.rst
@@ -3,7 +3,7 @@ Quick Error
===========
:Status: production-ready
-:Documentation: https://docs.rs/quick-error/
+:Documentation: http://tailhook.github.io/quick-error/
A macro which makes error types pleasant to write.
@@ -25,13 +25,13 @@ Here is the comprehensive example:
Io(err: io::Error) {
from()
display("I/O error: {}", err)
- source(err)
+ cause(err)
}
Other(descr: &'static str) {
display("Error {}", descr)
}
IoAt { place: &'static str, err: io::Error } {
- source(err)
+ cause(err)
display(me) -> ("io error at {}: {}", place, err)
from(s: String) -> {
place: "some string",
diff --git a/vendor/quick-error/examples/context.rs b/vendor/quick-error/examples/context.rs
index 1d406613e..334700a03 100644
--- a/vendor/quick-error/examples/context.rs
+++ b/vendor/quick-error/examples/context.rs
@@ -1,14 +1,19 @@
-use quick_error::{quick_error, ResultExt};
-use std::env;
-use std::fs::File;
+#[macro_use(quick_error)] extern crate quick_error;
+
use std::io::{self, stderr, Read, Write};
+use std::fs::File;
+use std::env;
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
+use quick_error::ResultExt;
+
quick_error! {
#[derive(Debug)]
pub enum Error {
- NoFileName {}
+ NoFileName {
+ description("no file name specified")
+ }
Io(err: io::Error, path: PathBuf) {
display("could not read file {:?}: {}", path, err)
context(path: &'a Path, err: io::Error)
@@ -23,12 +28,12 @@ quick_error! {
}
fn parse_file() -> Result<u64, Error> {
- let fname = env::args().skip(1).next().ok_or(Error::NoFileName)?;
+ let fname = try!(env::args().skip(1).next().ok_or(Error::NoFileName));
let fname = Path::new(&fname);
- let mut file = File::open(fname).context(fname)?;
+ let mut file = try!(File::open(fname).context(fname));
let mut buf = String::new();
- file.read_to_string(&mut buf).context(fname)?;
- Ok(buf.parse().context(fname)?)
+ try!(file.read_to_string(&mut buf).context(fname));
+ Ok(try!(buf.parse().context(fname)))
}
fn main() {
diff --git a/vendor/quick-error/src/lib.rs b/vendor/quick-error/src/lib.rs
index e5eb62e44..17fc455d4 100644
--- a/vendor/quick-error/src/lib.rs
+++ b/vendor/quick-error/src/lib.rs
@@ -45,7 +45,7 @@
//! Now you might have noticed trailing braces `{}`. They are used to define
//! implementations. By default:
//!
-//! * `Error::source()` returns None (even if type wraps some value)
+//! * `Error::cause()` returns None (even if type wraps some value)
//! * `Display` outputs debug representation
//! * No `From` implementations are defined
//!
@@ -66,7 +66,7 @@
//! }
//! ```
//!
-//! To change `source` method to return some error, add `source(value)`, for
+//! To change `cause` method to return some error, add `cause(value)`, for
//! example:
//!
//! ```rust
@@ -77,19 +77,19 @@
//! #[derive(Debug)]
//! pub enum SomeError {
//! Io(err: std::io::Error) {
-//! source(err)
+//! cause(err)
//! }
//! Utf8(err: std::str::Utf8Error) {
//! display("utf8 error")
//! }
//! Other(err: Box<std::error::Error>) {
-//! source(&**err)
+//! cause(&**err)
//! }
//! }
//! }
//! ```
//! Note you don't need to wrap value in `Some`, its implicit. In case you want
-//! `None` returned just omit the `source`. You can't return `None`
+//! `None` returned just omit the `cause`. You can't return `None`
//! conditionally.
//!
//! To change how each clause is `Display`ed add `display(pattern,..args)`,
@@ -220,12 +220,12 @@
//! }
//!
//! fn openfile(path: &Path) -> Result<(), Error> {
-//! File::open(path).context(path)?;
+//! try!(File::open(path).context(path));
//!
//! // If we didn't have context, the line above would be written as;
//! //
-//! // File::open(path)
-//! // .map_err(|err| Error::File(path.to_path_buf(), err))?;
+//! // try!(File::open(path)
+//! // .map_err(|err| Error::File(path.to_path_buf(), err)));
//!
//! Ok(())
//! }
@@ -248,7 +248,7 @@
//!
//! More info on context in [this article](http://bit.ly/1PsuxDt).
//!
-//! All forms of `from`, `display`, `source`, and `context`
+//! All forms of `from`, `display`, `cause`, and `context`
//! clauses can be combined and put in arbitrary order. Only `from` and
//! `context` can be used multiple times in single variant of enumeration.
//! Docstrings are also okay. Empty braces can be omitted as of quick_error
@@ -293,6 +293,7 @@
//!
//!
+
/// Main macro that does all the work
#[macro_export]
macro_rules! quick_error {
@@ -370,8 +371,9 @@ macro_rules! quick_error {
}
impl ::std::error::Error for $strname {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- self.0.source()
+ #[allow(deprecated)]
+ fn cause(&self) -> Option<&::std::error::Error> {
+ self.0.cause()
}
}
};
@@ -452,6 +454,8 @@ macro_rules! quick_error {
queue [ #[$qmeta:meta] $( $tail:tt )*]
) => {
quick_error!(SORT [$( $def )*]
+ enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*
+ $(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*]
items [$($( #[$imeta:meta] )*
=> $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
$bitem: $bmode [$( $bvar:$btyp ),*] {} ]
@@ -468,7 +472,7 @@ macro_rules! quick_error {
) => {
quick_error!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),+] ]
+ buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),*] ]
queue [$( $tail )*]
);
};
@@ -482,7 +486,7 @@ macro_rules! quick_error {
) => {
quick_error!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),+] ]
+ buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
queue [$( $tail )*]);
};
// Add struct enum-variant, with excess comma - e.g. { descr: &'static str, }
@@ -495,7 +499,7 @@ macro_rules! quick_error {
) => {
quick_error!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
- buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),+] ]
+ buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
queue [$( $tail )*]);
};
// Add braces and flush always on braces
@@ -557,7 +561,7 @@ macro_rules! quick_error {
pub enum $name {
$(
$(#[$imeta])*
- $iitem $(($( $ttyp ),+))* $({$( $svar: $styp ),*})*,
+ $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
)*
}
};
@@ -575,7 +579,7 @@ macro_rules! quick_error {
enum $name {
$(
$(#[$imeta])*
- $iitem $(($( $ttyp ),+))* $({$( $svar: $styp ),*})*,
+ $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
)*
}
};
@@ -601,7 +605,7 @@ macro_rules! quick_error {
) => {
quick_error!(ENUM_DEFINITION [ $($def)* ]
body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
- $( #[$qmeta] )* => $qitem (($( $qtyp ),+)) {} ]
+ $( #[$qmeta] )* => $qitem (($( $qtyp ),*)) {} ]
queue [ $($queue)* ]
);
};
@@ -654,14 +658,14 @@ macro_rules! quick_error {
#[allow(unused_doc_comment)]
#[allow(unused_doc_comments)]
impl ::std::error::Error for $name {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ fn cause(&self) -> Option<&::std::error::Error> {
match *self {
$(
$(#[$imeta])*
quick_error!(ITEM_PATTERN
$name $item: $imode [$( ref $var ),*]
) => {
- quick_error!(FIND_SOURCE_IMPL
+ quick_error!(FIND_CAUSE_IMPL
$item: $imode [$( $var ),*]
{$( $funcs )*})
}
@@ -709,21 +713,33 @@ macro_rules! quick_error {
write!(f, "{:?}", self_)
}
};
- (FIND_SOURCE_IMPL $item:ident: $imode:tt
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { description($expr:expr) $( $tail:tt )*}
+ ) => {};
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { $t:tt $( $tail:tt )*}
+ ) => {};
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { }
+ ) => {};
+ (FIND_CAUSE_IMPL $item:ident: $imode:tt
[$( $var:ident ),*]
- { source($expr:expr) $( $tail:tt )*}
+ { cause($expr:expr) $( $tail:tt )*}
) => {
Some($expr)
};
- (FIND_SOURCE_IMPL $item:ident: $imode:tt
+ (FIND_CAUSE_IMPL $item:ident: $imode:tt
[$( $var:ident ),*]
{ $t:tt $( $tail:tt )*}
) => {
- quick_error!(FIND_SOURCE_IMPL
+ quick_error!(FIND_CAUSE_IMPL
$item: $imode [$( $var ),*]
{ $($tail)* })
};
- (FIND_SOURCE_IMPL $item:ident: $imode:tt
+ (FIND_CAUSE_IMPL $item:ident: $imode:tt
[$( $var:ident ),*]
{ }
) => {
@@ -924,7 +940,9 @@ macro_rules! quick_error {
=> { quick_error!(ERROR_CHECK $imode $($tail)*); };
(ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); };
- (ERROR_CHECK $imode:tt source($expr:expr) $($tail:tt)*)
+ (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
+ => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); };
(ERROR_CHECK $imode:tt from() $($tail:tt)*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); };
@@ -947,6 +965,7 @@ macro_rules! quick_error {
(IDENT $ident:ident) => { $ident }
}
+
/// Generic context type
///
/// Used mostly as a transport for `ResultExt::context` method
@@ -970,13 +989,16 @@ impl<T, E> ResultExt<T, E> for Result<T, E> {
}
}
+
+
#[cfg(test)]
+#[allow(deprecated)]
mod test {
- use std::error::Error;
use std::num::{ParseFloatError, ParseIntError};
- use std::path::{Path, PathBuf};
use std::str::Utf8Error;
use std::string::FromUtf8Error;
+ use std::error::Error;
+ use std::path::{Path, PathBuf};
use super::ResultExt;
@@ -992,15 +1014,14 @@ mod test {
fn bare_item_direct() {
assert_eq!(format!("{}", Bare::One), "One".to_string());
assert_eq!(format!("{:?}", Bare::One), "One".to_string());
- assert!(Bare::One.source().is_none());
+ assert!(Bare::One.cause().is_none());
}
-
#[test]
fn bare_item_trait() {
- let err: &dyn Error = &Bare::Two;
+ let err: &Error = &Bare::Two;
assert_eq!(format!("{}", err), "Two".to_string());
assert_eq!(format!("{:?}", err), "Two".to_string());
- assert!(err.source().is_none());
+ assert!(err.cause().is_none());
}
quick_error! {
@@ -1016,18 +1037,13 @@ mod test {
#[test]
fn wrapper() {
- assert_eq!(
- format!("{}", Wrapper::from(Wrapped::One)),
- "One".to_string()
- );
- assert_eq!(
- format!("{}", Wrapper::from(Wrapped::from(String::from("hello")))),
- "two: hello".to_string()
- );
- assert_eq!(
- format!("{:?}", Wrapper::from(Wrapped::One)),
- "Wrapper(One)".to_string()
- );
+ assert_eq!(format!("{}", Wrapper::from(Wrapped::One)),
+ "One".to_string());
+ assert_eq!(format!("{}",
+ Wrapper::from(Wrapped::from(String::from("hello")))),
+ "two: hello".to_string());
+ assert_eq!(format!("{:?}", Wrapper::from(Wrapped::One)),
+ "Wrapper(One)".to_string());
}
quick_error! {
@@ -1037,14 +1053,14 @@ mod test {
ParseFloatError(err: ParseFloatError) {
from()
display("parse float error: {err}", err=err)
- source(err)
+ cause(err)
}
Other(descr: &'static str) {
display("Error: {}", descr)
}
/// FromUtf8 Error
FromUtf8Error(err: Utf8Error, source: Vec<u8>) {
- source(err)
+ cause(err)
display(me) -> ("{desc} at index {pos}: {err}", desc="utf8 error", pos=err.valid_up_to(), err=err)
from(err: FromUtf8Error) -> (err.utf8_error().clone(), err.into_bytes())
}
@@ -1059,68 +1075,46 @@ mod test {
#[test]
fn tuple_wrapper_err() {
- let source = "one and a half times pi".parse::<f32>().unwrap_err();
- let err = TupleWrapper::ParseFloatError(source.clone());
- assert_eq!(format!("{}", err), format!("parse float error: {}", source));
- assert_eq!(
- format!("{:?}", err),
- format!("ParseFloatError({:?})", source)
- );
- assert_eq!(
- format!("{:?}", err.source().unwrap()),
- format!("{:?}", source)
- );
+ let cause = "one and a half times pi".parse::<f32>().unwrap_err();
+ let err = TupleWrapper::ParseFloatError(cause.clone());
+ assert_eq!(format!("{}", err), format!("parse float error: {}", cause));
+ assert_eq!(format!("{:?}", err), format!("ParseFloatError({:?})", cause));
+ assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
}
#[test]
fn tuple_wrapper_trait_str() {
let desc = "hello";
- let err: &dyn Error = &TupleWrapper::Other(desc);
+ let err: &Error = &TupleWrapper::Other(desc);
assert_eq!(format!("{}", err), format!("Error: {}", desc));
assert_eq!(format!("{:?}", err), format!("Other({:?})", desc));
- assert!(err.source().is_none());
+ assert!(err.cause().is_none());
}
#[test]
fn tuple_wrapper_trait_two_fields() {
let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let source = String::from_utf8(invalid_utf8.clone())
- .unwrap_err()
- .utf8_error();
- let err: &dyn Error = &TupleWrapper::FromUtf8Error(source.clone(), invalid_utf8.clone());
- assert_eq!(
- format!("{}", err),
- format!(
- "{desc} at index {pos}: {source}",
- desc = "utf8 error",
- pos = source.valid_up_to(),
- source = source
- )
- );
- assert_eq!(
- format!("{:?}", err),
- format!("FromUtf8Error({:?}, {:?})", source, invalid_utf8)
- );
- assert_eq!(
- format!("{:?}", err.source().unwrap()),
- format!("{:?}", source)
- );
+ let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
+ let err: &Error = &TupleWrapper::FromUtf8Error(cause.clone(), invalid_utf8.clone());
+ assert_eq!(format!("{}", err), format!("{desc} at index {pos}: {cause}", desc="utf8 error", pos=cause.valid_up_to(), cause=cause));
+ assert_eq!(format!("{:?}", err), format!("FromUtf8Error({:?}, {:?})", cause, invalid_utf8));
+ assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
}
#[test]
fn tuple_wrapper_from() {
- let source = "one and a half times pi".parse::<f32>().unwrap_err();
- let err = TupleWrapper::ParseFloatError(source.clone());
- let err_from: TupleWrapper = From::from(source);
+ let cause = "one and a half times pi".parse::<f32>().unwrap_err();
+ let err = TupleWrapper::ParseFloatError(cause.clone());
+ let err_from: TupleWrapper = From::from(cause);
assert_eq!(err_from, err);
}
#[test]
fn tuple_wrapper_custom_from() {
let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let source = String::from_utf8(invalid_utf8.clone()).unwrap_err();
- let err = TupleWrapper::FromUtf8Error(source.utf8_error().clone(), invalid_utf8);
- let err_from: TupleWrapper = From::from(source);
+ let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err();
+ let err = TupleWrapper::FromUtf8Error(cause.utf8_error().clone(), invalid_utf8);
+ let err_from: TupleWrapper = From::from(cause);
assert_eq!(err_from, err);
}
@@ -1129,7 +1123,7 @@ mod test {
let err: TupleWrapper = From::from("hello");
assert_eq!(format!("{}", err), format!("Discard"));
assert_eq!(format!("{:?}", err), format!("Discard"));
- assert!(err.source().is_none());
+ assert!(err.cause().is_none());
}
#[test]
@@ -1137,7 +1131,7 @@ mod test {
let err: TupleWrapper = TupleWrapper::Singleton;
assert_eq!(format!("{}", err), format!("Just a string"));
assert_eq!(format!("{:?}", err), format!("Singleton"));
- assert!(err.source().is_none());
+ assert!(err.cause().is_none());
}
quick_error! {
@@ -1145,7 +1139,7 @@ mod test {
pub enum StructWrapper {
// Utf8 Error
Utf8Error{ err: Utf8Error, hint: Option<&'static str> } {
- source(err)
+ cause(err)
display(me) -> ("{desc} at index {pos}: {err}", desc="utf8 error", pos=err.valid_up_to(), err=err)
from(err: Utf8Error) -> { err: err, hint: None }
}
@@ -1159,47 +1153,19 @@ mod test {
#[test]
fn struct_wrapper_err() {
let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let source = String::from_utf8(invalid_utf8.clone())
- .unwrap_err()
- .utf8_error();
- let err: &dyn Error = &StructWrapper::Utf8Error {
- err: source.clone(),
- hint: Some("nonsense"),
- };
- assert_eq!(
- format!("{}", err),
- format!(
- "{desc} at index {pos}: {source}",
- desc = "utf8 error",
- pos = source.valid_up_to(),
- source = source
- )
- );
- assert_eq!(
- format!("{:?}", err),
- format!(
- "Utf8Error {{ err: {:?}, hint: {:?} }}",
- source,
- Some("nonsense")
- )
- );
- assert_eq!(
- format!("{:?}", err.source().unwrap()),
- format!("{:?}", source)
- );
+ let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
+ let err: &Error = &StructWrapper::Utf8Error{ err: cause.clone(), hint: Some("nonsense") };
+ assert_eq!(format!("{}", err), format!("{desc} at index {pos}: {cause}", desc="utf8 error", pos=cause.valid_up_to(), cause=cause));
+ assert_eq!(format!("{:?}", err), format!("Utf8Error {{ err: {:?}, hint: {:?} }}", cause, Some("nonsense")));
+ assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
}
#[test]
fn struct_wrapper_struct_from() {
let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let source = String::from_utf8(invalid_utf8.clone())
- .unwrap_err()
- .utf8_error();
- let err = StructWrapper::Utf8Error {
- err: source.clone(),
- hint: None,
- };
- let err_from: StructWrapper = From::from(source);
+ let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
+ let err = StructWrapper::Utf8Error{ err: cause.clone(), hint: None };
+ let err_from: StructWrapper = From::from(cause);
assert_eq!(err_from, err);
}
@@ -1208,11 +1174,8 @@ mod test {
let descr = "hello";
let err = StructWrapper::ExcessComma { descr: descr };
assert_eq!(format!("{}", err), format!("Error: {}", descr));
- assert_eq!(
- format!("{:?}", err),
- format!("ExcessComma {{ descr: {:?} }}", descr)
- );
- assert!(err.source().is_none());
+ assert_eq!(format!("{:?}", err), format!("ExcessComma {{ descr: {:?} }}", descr));
+ assert!(err.cause().is_none());
}
quick_error! {
@@ -1243,23 +1206,19 @@ mod test {
#[test]
fn parse_float_error() {
fn parse_float(s: &str) -> Result<f32, ContextErr> {
- Ok(s.parse().context(s)?)
+ Ok(try!(s.parse().context(s)))
}
- assert_eq!(
- format!("{}", parse_float("12ab").unwrap_err()),
- r#"Float error "12ab": invalid float literal"#
- );
+ assert_eq!(format!("{}", parse_float("12ab").unwrap_err()),
+ r#"Float error "12ab": invalid float literal"#);
}
#[test]
fn parse_int_error() {
fn parse_int(s: &str) -> Result<i32, ContextErr> {
- Ok(s.parse().context(s)?)
+ Ok(try!(s.parse().context(s)))
}
- assert_eq!(
- format!("{}", parse_int("12.5").unwrap_err()),
- r#"Int error "12.5": invalid digit found in string"#
- );
+ assert_eq!(format!("{}", parse_int("12.5").unwrap_err()),
+ r#"Int error "12.5": invalid digit found in string"#);
}
#[test]
@@ -1268,24 +1227,25 @@ mod test {
s.parse().context(s).unwrap()
}
assert_eq!(parse_int("12"), 12);
- assert_eq!(
- format!("{:?}", "x".parse::<i32>().context("x")),
- r#"Err(Context("x", ParseIntError { kind: InvalidDigit }))"#
- );
+ assert_eq!(format!("{:?}", "x".parse::<i32>().context("x")),
+ r#"Err(Context("x", ParseIntError { kind: InvalidDigit }))"#);
}
#[test]
fn path_context() {
- fn parse_utf<P: AsRef<Path>>(s: &[u8], p: P) -> Result<(), ContextErr> {
- ::std::str::from_utf8(s).context(p)?;
+ fn parse_utf<P: AsRef<Path>>(s: &[u8], p: P)
+ -> Result<(), ContextErr>
+ {
+ try!(::std::str::from_utf8(s).context(p));
Ok(())
}
let etext = parse_utf(b"a\x80\x80", "/etc").unwrap_err().to_string();
- assert!(etext.starts_with("Path error at \"/etc\": invalid utf-8"));
- let etext = parse_utf(b"\x80\x80", PathBuf::from("/tmp"))
- .unwrap_err()
+ assert!(etext.starts_with(
+ "Path error at \"/etc\": invalid utf-8"));
+ let etext = parse_utf(b"\x80\x80", PathBuf::from("/tmp")).unwrap_err()
.to_string();
- assert!(etext.starts_with("Path error at \"/tmp\": invalid utf-8"));
+ assert!(etext.starts_with(
+ "Path error at \"/tmp\": invalid utf-8"));
}
#[test]
@@ -1299,38 +1259,4 @@ mod test {
}
}
}
-
- #[test]
- #[allow(deprecated)]
- fn cause_struct_wrapper_err() {
- let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
- let cause = String::from_utf8(invalid_utf8.clone())
- .unwrap_err()
- .utf8_error();
- let err: &dyn Error = &StructWrapper::Utf8Error {
- err: cause.clone(),
- hint: Some("nonsense"),
- };
- assert_eq!(
- format!("{}", err),
- format!(
- "{desc} at index {pos}: {cause}",
- desc = "utf8 error",
- pos = cause.valid_up_to(),
- cause = cause
- )
- );
- assert_eq!(
- format!("{:?}", err),
- format!(
- "Utf8Error {{ err: {:?}, hint: {:?} }}",
- cause,
- Some("nonsense")
- )
- );
- assert_eq!(
- format!("{:?}", err.cause().unwrap()),
- format!("{:?}", cause)
- );
- }
}
diff --git a/vendor/quick-error/vagga.yaml b/vendor/quick-error/vagga.yaml
index 35eb29675..71b9be44e 100644
--- a/vendor/quick-error/vagga.yaml
+++ b/vendor/quick-error/vagga.yaml
@@ -23,12 +23,12 @@ containers:
- !Install [ca-certificates, build-essential, vim]
- !TarInstall
- url: "https://static.rust-lang.org/dist/rust-1.31.0-x86_64-unknown-linux-gnu.tar.gz"
+ url: "https://static.rust-lang.org/dist/rust-1.16.0-x86_64-unknown-linux-gnu.tar.gz"
script: "./install.sh --prefix=/usr \
--components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo"
- &bulk !Tar
- url: "https://github.com/tailhook/bulk/releases/download/v0.4.10/bulk-v0.4.10.tar.gz"
- sha256: 481513f8a0306a9857d045497fb5b50b50a51e9ff748909ecf7d2bda1de275ab
+ url: "https://github.com/tailhook/bulk/releases/download/v0.4.9/bulk-v0.4.9.tar.gz"
+ sha256: 23471a9986274bb4b7098c03e2eb7e1204171869b72c45385fcee1c64db2d111
path: /
environ:
diff --git a/vendor/quote/.cargo-checksum.json b/vendor/quote/.cargo-checksum.json
index 719c0e74c..dd217b081 100644
--- a/vendor/quote/.cargo-checksum.json
+++ b/vendor/quote/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"a3ccdf97181e3c14c424c9f3a386d7448eb16fc583a3cd0d89d1bb50cf68ec61","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"1aed9e312142718f8e1a37a0a982d8e45398dee835776b0ffa54639efdd75dfb","build.rs":"3733c86ae2733629f873f93c2f45da30164beee8de9ee0833099fac6a05a3e6b","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/ext.rs":"a9fed3a1a4c9d3f2de717ba808af99291b995db2cbf8067f4b6927c39cc62bc6","src/format.rs":"c595015418f35e6992e710441b9999f09b2afe4678b138039d670d100c0bdd86","src/ident_fragment.rs":"3ad27e331af8b54a4b97d19e7ae2bb45e01fb51dc410b24c083345ba6a0b20a8","src/lib.rs":"08555009f5ee3a9f3c81f0bcd08894c9702a993d5bf7c9736e438ed79bc78189","src/runtime.rs":"a7ed70a8f45539ef4be14c535d302ac90668bbe6213c72eb795e5d75fa286191","src/spanned.rs":"43ff919f1d2d27dff6b2db409539b1c697e913eb8c3131cf5de45a845752b7b5","src/to_tokens.rs":"a351a680577d520ebb35905633c77533e8bc4b20642a5c438a51c94b2cc85145","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"29221bc5eb9497a2fcda1b44e9535c645f7c7ca84ffc32e6040e57d94dbda2c8","tests/ui/does-not-have-iter-interpolated-dup.rs":"ad13eea21d4cdd2ab6c082f633392e1ff20fb0d1af5f2177041e0bf7f30da695","tests/ui/does-not-have-iter-interpolated-dup.stderr":"833ccb8e0b7f5327eaba20d2f1975c63c8d152a5da9bf7be50e874fd617263dc","tests/ui/does-not-have-iter-interpolated.rs":"83a5b3f240651adcbe4b6e51076d76d653ad439b37442cf4054f1fd3c073f3b7","tests/ui/does-not-have-iter-interpolated.stderr":"4f1dee2aed73362fa761b17430c34d7d050f03cedb49dbe6ef51c456a03c07af","tests/ui/does-not-have-iter-separated.rs":"fe413c48331d5e3a7ae5fef6a5892a90c72f610d54595879eb49d0a94154ba3f","tests/ui/does-not-have-iter-separated.stderr":"a731b784d867ad1503c56511ef4c25f5938a6aab86196df0e7196df5ac08c2d6","tests/ui/does-not-have-iter.rs":"09dc9499d861b63cebb0848b855b78e2dc9497bfde37ba6339f3625ae009a62f","tests/ui/does-not-have-iter.stderr":"ada583e7f9043521e0dbfc013fda9d63853acb982901ee73c4481814bc522610","tests/ui/not-quotable.rs":"5759d0884943417609f28faadc70254a3e2fd3d9bd6ff7297a3fb70a77fafd8a","tests/ui/not-quotable.stderr":"d55354e6a963b5eedce9bc68a1b04bf5b82f966c3c1bb987d1690e74c0c3d69c","tests/ui/not-repeatable.rs":"a4b115c04e4e41049a05f5b69450503fbffeba031218b4189cb931839f7f9a9c","tests/ui/not-repeatable.stderr":"b17b74b25e7fb2e37593a9c11755be033a2d8fd44090f74124c872d91154d7e7","tests/ui/wrong-type-span.rs":"6195e35ea844c0c52ba1cff5d790c3a371af6915d137d377834ad984229ef9ea","tests/ui/wrong-type-span.stderr":"c986de5cb858272636c9e36ae5f57e5ee13589d4f1a73a050b21824010314f8d"},"package":"3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"} \ No newline at end of file
+{"files":{"Cargo.toml":"f4cf791ed3ccb9a3d5840f63af9c8d6b60453d9cd2451bf71c98f413e639b5ac","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"1aed9e312142718f8e1a37a0a982d8e45398dee835776b0ffa54639efdd75dfb","build.rs":"3733c86ae2733629f873f93c2f45da30164beee8de9ee0833099fac6a05a3e6b","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/ext.rs":"9881576cac3e476a4bf04f9b601cf9a53b79399fb0ca9634e8b861ac91709843","src/format.rs":"c595015418f35e6992e710441b9999f09b2afe4678b138039d670d100c0bdd86","src/ident_fragment.rs":"66788c5f57681547d936a9bcf51873b658630c76b2e690df4b3158edf573384a","src/lib.rs":"17db85f0808d31a597ea7f56744b031b5bdba548d9474efd874cacfe6541ff60","src/runtime.rs":"79bbb2fe5b18bc3ec9f8f8143bd120b45680a3027c89f37b0a6a6b97bdaadb21","src/spanned.rs":"43ff919f1d2d27dff6b2db409539b1c697e913eb8c3131cf5de45a845752b7b5","src/to_tokens.rs":"99bb6f467289c32af6c1f7af0d45cc6ac7b31e2436774e616770152a49e6ac0f","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"29221bc5eb9497a2fcda1b44e9535c645f7c7ca84ffc32e6040e57d94dbda2c8","tests/ui/does-not-have-iter-interpolated-dup.rs":"ad13eea21d4cdd2ab6c082f633392e1ff20fb0d1af5f2177041e0bf7f30da695","tests/ui/does-not-have-iter-interpolated-dup.stderr":"be67a6c99eed689aa08b46afd0ab3ed4e71fde42e5efed41ab05741710f42fe5","tests/ui/does-not-have-iter-interpolated.rs":"83a5b3f240651adcbe4b6e51076d76d653ad439b37442cf4054f1fd3c073f3b7","tests/ui/does-not-have-iter-interpolated.stderr":"ed05bc229abf5a267ea3d194336a3a845a061bd10c1be7020b9351f81e737946","tests/ui/does-not-have-iter-separated.rs":"fe413c48331d5e3a7ae5fef6a5892a90c72f610d54595879eb49d0a94154ba3f","tests/ui/does-not-have-iter-separated.stderr":"873f4db0ec63606d64d46790f3ee24bdb4dd04379b8e57dc5ac1114cc3775fb3","tests/ui/does-not-have-iter.rs":"09dc9499d861b63cebb0848b855b78e2dc9497bfde37ba6339f3625ae009a62f","tests/ui/does-not-have-iter.stderr":"0e3de2635a79cce9226113fa8cb6bdbdc0ffcd487d7537d4dd0dc8222adf4a8a","tests/ui/not-quotable.rs":"5759d0884943417609f28faadc70254a3e2fd3d9bd6ff7297a3fb70a77fafd8a","tests/ui/not-quotable.stderr":"d55354e6a963b5eedce9bc68a1b04bf5b82f966c3c1bb987d1690e74c0c3d69c","tests/ui/not-repeatable.rs":"a4b115c04e4e41049a05f5b69450503fbffeba031218b4189cb931839f7f9a9c","tests/ui/not-repeatable.stderr":"27149da38cc074953f124e995d76e569e0f718a5431c321cb5d639b0065520b3","tests/ui/wrong-type-span.rs":"6195e35ea844c0c52ba1cff5d790c3a371af6915d137d377834ad984229ef9ea","tests/ui/wrong-type-span.stderr":"c986de5cb858272636c9e36ae5f57e5ee13589d4f1a73a050b21824010314f8d"},"package":"bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"} \ No newline at end of file
diff --git a/vendor/quote/Cargo.toml b/vendor/quote/Cargo.toml
index f7e56d6e4..b2abe6612 100644
--- a/vendor/quote/Cargo.toml
+++ b/vendor/quote/Cargo.toml
@@ -13,13 +13,16 @@
edition = "2018"
rust-version = "1.31"
name = "quote"
-version = "1.0.20"
+version = "1.0.21"
authors = ["David Tolnay <dtolnay@gmail.com>"]
autobenches = false
description = "Quasi-quoting macro quote!(...)"
documentation = "https://docs.rs/quote/"
readme = "README.md"
-keywords = ["syn"]
+keywords = [
+ "macros",
+ "syn",
+]
categories = ["development-tools::procedural-macro-helpers"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/quote"
diff --git a/vendor/quote/src/ext.rs b/vendor/quote/src/ext.rs
index 9e9b4a505..92c2315b1 100644
--- a/vendor/quote/src/ext.rs
+++ b/vendor/quote/src/ext.rs
@@ -1,7 +1,5 @@
use super::ToTokens;
-
-use std::iter;
-
+use core::iter;
use proc_macro2::{TokenStream, TokenTree};
/// TokenStream extension trait with methods for appending tokens.
diff --git a/vendor/quote/src/ident_fragment.rs b/vendor/quote/src/ident_fragment.rs
index 67e2e3393..cf74024b4 100644
--- a/vendor/quote/src/ident_fragment.rs
+++ b/vendor/quote/src/ident_fragment.rs
@@ -1,6 +1,6 @@
+use core::fmt;
use proc_macro2::{Ident, Span};
use std::borrow::Cow;
-use std::fmt;
/// Specialized formatting trait used by `format_ident!`.
///
diff --git a/vendor/quote/src/lib.rs b/vendor/quote/src/lib.rs
index 2fae3fcfa..35594827f 100644
--- a/vendor/quote/src/lib.rs
+++ b/vendor/quote/src/lib.rs
@@ -81,7 +81,7 @@
//! ```
// Quote types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/quote/1.0.20")]
+#![doc(html_root_url = "https://docs.rs/quote/1.0.21")]
#![allow(
clippy::doc_markdown,
clippy::missing_errors_doc,
diff --git a/vendor/quote/src/runtime.rs b/vendor/quote/src/runtime.rs
index 3f7e6b280..f3cdded3a 100644
--- a/vendor/quote/src/runtime.rs
+++ b/vendor/quote/src/runtime.rs
@@ -1,11 +1,11 @@
use crate::{IdentFragment, ToTokens, TokenStreamExt};
-use std::fmt;
-use std::iter;
-use std::ops::BitOr;
+use core::fmt;
+use core::iter;
+use core::ops::BitOr;
+pub use core::option::Option;
pub use proc_macro2::*;
pub use std::format;
-pub use std::option::Option;
pub struct HasIterator; // True
pub struct ThereIsNoIteratorInRepetition; // False
@@ -48,8 +48,8 @@ pub mod ext {
use super::RepInterp;
use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter};
use crate::ToTokens;
+ use core::slice;
use std::collections::btree_set::{self, BTreeSet};
- use std::slice;
/// Extension trait providing the `quote_into_iter` method on iterators.
pub trait RepIteratorExt: Iterator + Sized {
diff --git a/vendor/quote/src/to_tokens.rs b/vendor/quote/src/to_tokens.rs
index dbb8dfc36..57487217e 100644
--- a/vendor/quote/src/to_tokens.rs
+++ b/vendor/quote/src/to_tokens.rs
@@ -1,11 +1,9 @@
use super::TokenStreamExt;
-
+use core::iter;
+use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
use std::borrow::Cow;
-use std::iter;
use std::rc::Rc;
-use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
-
/// Types that can be interpolated inside a `quote!` invocation.
///
/// [`quote!`]: macro.quote.html
diff --git a/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
index bcd631db1..8087879af 100644
--- a/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
+++ b/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
| expected due to this
|
- = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr b/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
index 799837bcd..2dcf206dd 100644
--- a/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
+++ b/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
| expected due to this
|
- = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/quote/tests/ui/does-not-have-iter-separated.stderr b/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
index aa2e6938f..87a19fe07 100644
--- a/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
+++ b/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
| expected due to this
|
- = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/quote/tests/ui/does-not-have-iter.stderr b/vendor/quote/tests/ui/does-not-have-iter.stderr
index c2692fe5d..32aa62d9b 100644
--- a/vendor/quote/tests/ui/does-not-have-iter.stderr
+++ b/vendor/quote/tests/ui/does-not-have-iter.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
| expected due to this
|
- = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/quote/tests/ui/not-repeatable.stderr b/vendor/quote/tests/ui/not-repeatable.stderr
index cd5a1e4d1..f75351e33 100644
--- a/vendor/quote/tests/ui/not-repeatable.stderr
+++ b/vendor/quote/tests/ui/not-repeatable.stderr
@@ -1,47 +1,35 @@
error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
- --> tests/ui/not-repeatable.rs:7:13
- |
-3 | struct Ipv4Addr;
- | ----------------
- | |
- | method `quote_into_iter` not found for this
- | doesn't satisfy `Ipv4Addr: Iterator`
- | doesn't satisfy `Ipv4Addr: ToTokens`
- | doesn't satisfy `Ipv4Addr: quote::__private::ext::RepIteratorExt`
- | doesn't satisfy `Ipv4Addr: quote::__private::ext::RepToTokensExt`
+ --> tests/ui/not-repeatable.rs:7:13
+ |
+3 | struct Ipv4Addr;
+ | ---------------
+ | |
+ | method `quote_into_iter` not found for this struct
+ | doesn't satisfy `Ipv4Addr: Iterator`
+ | doesn't satisfy `Ipv4Addr: ToTokens`
+ | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt`
+ | doesn't satisfy `Ipv4Addr: ext::RepToTokensExt`
...
-7 | let _ = quote! { #(#ip)* };
- | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
- |
- = note: the following trait bounds were not satisfied:
- `Ipv4Addr: Iterator`
- which is required by `Ipv4Addr: quote::__private::ext::RepIteratorExt`
- `&Ipv4Addr: Iterator`
- which is required by `&Ipv4Addr: quote::__private::ext::RepIteratorExt`
- `Ipv4Addr: ToTokens`
- which is required by `Ipv4Addr: quote::__private::ext::RepToTokensExt`
- `&mut Ipv4Addr: Iterator`
- which is required by `&mut Ipv4Addr: quote::__private::ext::RepIteratorExt`
+7 | let _ = quote! { #(#ip)* };
+ | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `Ipv4Addr: Iterator`
+ which is required by `Ipv4Addr: ext::RepIteratorExt`
+ `&Ipv4Addr: Iterator`
+ which is required by `&Ipv4Addr: ext::RepIteratorExt`
+ `Ipv4Addr: ToTokens`
+ which is required by `Ipv4Addr: ext::RepToTokensExt`
+ `&mut Ipv4Addr: Iterator`
+ which is required by `&mut Ipv4Addr: ext::RepIteratorExt`
note: the following traits must be implemented
- --> $RUST/core/src/iter/traits/iterator.rs
- |
- | / pub trait Iterator {
- | | /// The type of the elements being iterated over.
- | | #[stable(feature = "rust1", since = "1.0.0")]
- | | type Item;
-... |
- | | }
- | | }
- | |__^
- |
- ::: src/to_tokens.rs
- |
- | / pub trait ToTokens {
- | | /// Write `self` to the given `TokenStream`.
- | | ///
- | | /// The token append methods provided by the [`TokenStreamExt`] extension
-... |
- | | }
- | | }
- | |_^
- = note: this error originates in the macro `$crate::quote_bind_into_iter` (in Nightly builds, run with -Z macro-backtrace for more info)
+ --> $RUST/core/src/iter/traits/iterator.rs
+ |
+ | pub trait Iterator {
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ ::: src/to_tokens.rs
+ |
+ | pub trait ToTokens {
+ | ^^^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/redox_syscall/.cargo-checksum.json b/vendor/redox_syscall/.cargo-checksum.json
index 223c03b3c..9c62b6521 100644
--- a/vendor/redox_syscall/.cargo-checksum.json
+++ b/vendor/redox_syscall/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"69f08bb56c6fc199b61cbe959b6e9f93df554f5d4e87d5e64551116cedf15067","LICENSE":"efcfee7981ff72431fffb06925cad00a23dce079ed4354f61030ad5abdb78829","README.md":"9161f18ba7f69b4ca51e844aee8ffb8237513a468c5c3b1f3a5f989044f895ac","src/arch/aarch64.rs":"61b5811b47a29257c3b5e15e7d9d15e7143bad99fbe29f0cb17ead9cbc17186f","src/arch/nonredox.rs":"9eac0fa2cf9eae07f0cafa2dd63c4a820791897a3de9ad1a933ab4f53458dbd8","src/arch/riscv64.rs":"20bf9a8db779059773b113643d0cb3737fbb5d57f45ee39b8ae9d3396b6ef636","src/arch/x86_64.rs":"f40bad2680fd5e7f100ee1afaa805f33dd0e12ec8786b956d47204f66771801d","src/call.rs":"0d3e32e33ecdf75963e5d244f9e86e94047d155c5de5fa3c0085faf18ed97b33","src/daemon.rs":"11cd633298fe2eb89906a4d8c12ab34e4ee355f759e1216cee536f24c7c679b2","src/data.rs":"bd4545d4c2fcc59ff26ae52ad7f773a697d5ccf639a2ffc253cece6b31e94d51","src/error.rs":"ef20f3817f997a1aeb7114628407f19cb8bc13c555d4e093918f38a5d098f798","src/flag.rs":"f07d6a7aa6766d30d0a303c7b3bda5bb4c473dd9dd51687cf8e0631b1bf3ec9d","src/io/dma.rs":"fbc46e924d5913f5a3fb723751d7a9dd1b079ccf058500fde4957aaf9fa7dd1c","src/io/io.rs":"e1d454ff47efac70fdaa709251a5a9c1c5637f931994ba3bf6a38c6db9145822","src/io/mmio.rs":"12d0fb4d4f45097bf2c14f73cb1ce21325eae193b537e9f18af73ed5281b5e63","src/io/mod.rs":"62438ff452c266692ea8fcfc4b6aad73184a1f67276327a4d5f71c4fbbaeab55","src/io/pio.rs":"9ee6f2229b700d1c45b4c8c6242bd99fe69634e16dcd5843d9e8d1c958047406","src/lib.rs":"d30eec6d2480c6dbc74221a10cc662a649bd24dc3ac640bbcdab9e416aab727f","src/number.rs":"fe7b47b06566aa1f8a75f50b685801259df03a1a5c85b91817b4552583cd7862","src/scheme/generate.sh":"dde4e30f4e0223fb1a24ed486a6c36e624c854dbf890862cb6866f4fa3c7a6eb","src/scheme/mod.rs":"cb622405deb0aef4ab04499ea1adfd338c9c5dd9c31a1fe9989786dbf69b49d8","src/scheme/scheme.rs":"30263996f0b4930edd76dace5f5750e48229066bc888bc13365846688d0a870b","src/scheme/scheme_block.rs":"b7a761e4349eb87d106c8af14894e8c4272769b9eb235cd500b075ac1f823683","src/scheme/scheme_block_mut.rs":"4a4fc03bce14757b64006b9bc3fa2779e95382b2d99579870146ee0c3be3f46c","src/scheme/scheme_mut.rs":"e6f0671b77f1bf5263e497c69dec553352249b75d52af62ac19477ba5127f803","src/scheme/seek.rs":"94e044de47b0f00eb0c2aea3fb21001ac2b9aa1e4b20d73fd54163fe92fa63f7","src/tests.rs":"416a428ba6a9c5f0d8f4c3dbe91d9aa940a04472ec9a2d17bc5a66c455b4416f"},"package":"62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"} \ No newline at end of file
+{"files":{"Cargo.toml":"0e92420005ca47c7854d02e9b637262cc13f800d48614aeef69be2f1119fc19b","LICENSE":"efcfee7981ff72431fffb06925cad00a23dce079ed4354f61030ad5abdb78829","README.md":"9161f18ba7f69b4ca51e844aee8ffb8237513a468c5c3b1f3a5f989044f895ac","src/arch/aarch64.rs":"61b5811b47a29257c3b5e15e7d9d15e7143bad99fbe29f0cb17ead9cbc17186f","src/arch/nonredox.rs":"9eac0fa2cf9eae07f0cafa2dd63c4a820791897a3de9ad1a933ab4f53458dbd8","src/arch/riscv64.rs":"20bf9a8db779059773b113643d0cb3737fbb5d57f45ee39b8ae9d3396b6ef636","src/arch/x86.rs":"7802186155c06638235e49e11f4c046b68f1d8145b2c849adec84497eb3cb70f","src/arch/x86_64.rs":"f40bad2680fd5e7f100ee1afaa805f33dd0e12ec8786b956d47204f66771801d","src/call.rs":"0d3e32e33ecdf75963e5d244f9e86e94047d155c5de5fa3c0085faf18ed97b33","src/daemon.rs":"11cd633298fe2eb89906a4d8c12ab34e4ee355f759e1216cee536f24c7c679b2","src/data.rs":"bd4545d4c2fcc59ff26ae52ad7f773a697d5ccf639a2ffc253cece6b31e94d51","src/error.rs":"ef20f3817f997a1aeb7114628407f19cb8bc13c555d4e093918f38a5d098f798","src/flag.rs":"f07d6a7aa6766d30d0a303c7b3bda5bb4c473dd9dd51687cf8e0631b1bf3ec9d","src/io/dma.rs":"fbc46e924d5913f5a3fb723751d7a9dd1b079ccf058500fde4957aaf9fa7dd1c","src/io/io.rs":"e1d454ff47efac70fdaa709251a5a9c1c5637f931994ba3bf6a38c6db9145822","src/io/mmio.rs":"12d0fb4d4f45097bf2c14f73cb1ce21325eae193b537e9f18af73ed5281b5e63","src/io/mod.rs":"79c2fce4fd6d75f3b9169df64b7a605feff31fab2e5ed81984ae085a1d07c0c4","src/io/pio.rs":"9ee6f2229b700d1c45b4c8c6242bd99fe69634e16dcd5843d9e8d1c958047406","src/lib.rs":"0bc9c8ca513dc6f0d9ef587bc53587114c31c1217d6b620399fc0fcbc54bf658","src/number.rs":"fe7b47b06566aa1f8a75f50b685801259df03a1a5c85b91817b4552583cd7862","src/scheme/generate.sh":"dde4e30f4e0223fb1a24ed486a6c36e624c854dbf890862cb6866f4fa3c7a6eb","src/scheme/mod.rs":"cb622405deb0aef4ab04499ea1adfd338c9c5dd9c31a1fe9989786dbf69b49d8","src/scheme/scheme.rs":"30263996f0b4930edd76dace5f5750e48229066bc888bc13365846688d0a870b","src/scheme/scheme_block.rs":"b7a761e4349eb87d106c8af14894e8c4272769b9eb235cd500b075ac1f823683","src/scheme/scheme_block_mut.rs":"4a4fc03bce14757b64006b9bc3fa2779e95382b2d99579870146ee0c3be3f46c","src/scheme/scheme_mut.rs":"e6f0671b77f1bf5263e497c69dec553352249b75d52af62ac19477ba5127f803","src/scheme/seek.rs":"94e044de47b0f00eb0c2aea3fb21001ac2b9aa1e4b20d73fd54163fe92fa63f7","src/tests.rs":"416a428ba6a9c5f0d8f4c3dbe91d9aa940a04472ec9a2d17bc5a66c455b4416f"},"package":"fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"} \ No newline at end of file
diff --git a/vendor/redox_syscall/Cargo.toml b/vendor/redox_syscall/Cargo.toml
index c6a9e03a4..74e23e8c9 100644
--- a/vendor/redox_syscall/Cargo.toml
+++ b/vendor/redox_syscall/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "redox_syscall"
-version = "0.2.13"
+version = "0.2.16"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
description = "A Rust library to access raw Redox system calls"
documentation = "https://docs.rs/redox_syscall"
diff --git a/vendor/redox_syscall/src/arch/x86.rs b/vendor/redox_syscall/src/arch/x86.rs
new file mode 100644
index 000000000..2f9301e0e
--- /dev/null
+++ b/vendor/redox_syscall/src/arch/x86.rs
@@ -0,0 +1,105 @@
+use core::{mem, slice};
+use core::arch::asm;
+use core::ops::{Deref, DerefMut};
+
+use super::error::{Error, Result};
+
+macro_rules! syscall {
+ ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => {
+ $(
+ pub unsafe fn $name(mut $a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize)?)?)?)?)?) -> Result<usize> {
+ asm!(
+ "int 0x80",
+ inout("eax") $a,
+ $(
+ in("ebx") $b,
+ $(
+ in("ecx") $c,
+ $(
+ in("edx") $d,
+ $(
+ in("esi") $e,
+ $(
+ in("edi") $f,
+ )?
+ )?
+ )?
+ )?
+ )?
+ options(nostack),
+ );
+
+ Error::demux($a)
+ }
+ )+
+ };
+}
+
+syscall! {
+ syscall0(a,);
+ syscall1(a, b,);
+ syscall2(a, b, c,);
+ syscall3(a, b, c, d,);
+ // Must be done custom because LLVM reserves ESI
+ //syscall4(a, b, c, d, e,);
+ //syscall5(a, b, c, d, e, f,);
+}
+
+pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize)
+ -> Result<usize> {
+ asm!(
+ "xchg esi, {e}
+ int 0x80
+ xchg esi, {e}",
+ e = in(reg) e,
+ inout("eax") a,
+ in("ebx") b,
+ in("ecx") c,
+ in("edx") d,
+ options(nostack),
+ );
+
+ Error::demux(a)
+}
+
+pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize)
+ -> Result<usize> {
+ asm!(
+ "xchg esi, {e}
+ int 0x80
+ xchg esi, {e}",
+ e = in(reg) e,
+ inout("eax") a,
+ in("ebx") b,
+ in("ecx") c,
+ in("edx") d,
+ in("edi") f,
+ options(nostack),
+ );
+
+ Error::demux(a)
+}
+
+#[derive(Clone, Copy, Debug, Default)]
+#[repr(packed)]
+pub struct EnvRegisters {
+ pub fsbase: u32,
+ pub gsbase: u32,
+}
+
+impl Deref for EnvRegisters {
+ type Target = [u8];
+ fn deref(&self) -> &[u8] {
+ unsafe {
+ slice::from_raw_parts(self as *const EnvRegisters as *const u8, mem::size_of::<EnvRegisters>())
+ }
+ }
+}
+
+impl DerefMut for EnvRegisters {
+ fn deref_mut(&mut self) -> &mut [u8] {
+ unsafe {
+ slice::from_raw_parts_mut(self as *mut EnvRegisters as *mut u8, mem::size_of::<EnvRegisters>())
+ }
+ }
+}
diff --git a/vendor/redox_syscall/src/io/mod.rs b/vendor/redox_syscall/src/io/mod.rs
index a9cd4c86d..a225f0650 100644
--- a/vendor/redox_syscall/src/io/mod.rs
+++ b/vendor/redox_syscall/src/io/mod.rs
@@ -4,12 +4,12 @@ pub use self::dma::*;
pub use self::io::*;
pub use self::mmio::*;
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub use self::pio::*;
mod dma;
mod io;
mod mmio;
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod pio;
diff --git a/vendor/redox_syscall/src/lib.rs b/vendor/redox_syscall/src/lib.rs
index 050ee8160..9c5939830 100644
--- a/vendor/redox_syscall/src/lib.rs
+++ b/vendor/redox_syscall/src/lib.rs
@@ -26,7 +26,7 @@ mod arch;
mod arch;
#[cfg(all(any(target_os = "none", target_os = "redox"), target_arch = "x86"))]
-#[path="arch/nonredox.rs"]
+#[path="arch/x86.rs"]
mod arch;
#[cfg(all(any(target_os = "none", target_os = "redox"), target_arch = "x86_64"))]
diff --git a/vendor/regex-syntax/.cargo-checksum.json b/vendor/regex-syntax/.cargo-checksum.json
index 127f562f7..881437810 100644
--- a/vendor/regex-syntax/.cargo-checksum.json
+++ b/vendor/regex-syntax/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"e6d037be81ec5e78c7cce40650b1082f07e43882ce6ad7c360b5d7f804003dbb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"67a3e673a9da6826fd4db5be6902841c821b52b98dc22c300f6e327872392b0a","benches/bench.rs":"d2b6ae5b939abd6093064f144b981b7739d7f474ec0698a1268052fc92406635","src/ast/mod.rs":"b0fe9af7ae15d9448246c204977634e5827bbae247bd59ab2e61411996fc68d6","src/ast/parse.rs":"ba7b2c46d18ada21fae986e2202d638515c8be3e275657a6b87b4d86d5054cd3","src/ast/print.rs":"d12f2cc75cd62f35623e1eb7a77ab8ac804b971752082700d2c4f550f834b249","src/ast/visitor.rs":"8ffcad13eb2c2a2f745f7bc8d823bd2f0bb728bd150f439455be5a245731f1d2","src/either.rs":"1758e3edd056884eccadd995708d1e374ba9aa65846bd0e13b1aae852607c560","src/error.rs":"cc99a11392b52f7665ff5ee8ea350f7386ed7c6c6bedd46e216b2f396785317f","src/hir/interval.rs":"2ffab258f204fe47bc5fe9ca84376fcd9ecb4929649f683a9412f2e382e908dc","src/hir/literal/mod.rs":"f3e9b291af6a143ab693fe0b63a7c070a2a41935c15b38ecf2cfa8ab0ab2e89c","src/hir/mod.rs":"51f1642b75e298b0847855d7f490eca2e8f445c9039dd3aa91491f533ec83f15","src/hir/print.rs":"651b5d9776532a78612a5f9081372a57bad693890639ac19e3128b4defa96662","src/hir/translate.rs":"de10ee2928001567f80c6ab602de0e280a8e3a1e615cf73def91d2dcc4f9f199","src/hir/visitor.rs":"e5bf7f8c09f6155e59c9d676fe25437f7e3700f9bf5d91101d7e246a64c11d5a","src/lib.rs":"0fc94332a971691862ca17531881302b10ef6fa4aba65c123f0b69ffb14b989a","src/parser.rs":"ce2392d748d909c2eb92f3bf7ad50065c59a615e6c46f81e87f48e9d87817061","src/unicode.rs":"3b486b36e2ffcae306cb6d7387a82069163c7269597ff2b50589a05462464c36","src/unicode_tables/LICENSE-UNICODE":"74db5baf44a41b1000312c673544b3374e4198af5605c7f9080a402cec42cfa3","src/unicode_tables/age.rs":"b0932a020d3386478dd2f4839c59e30c525e8591735052b9e791e1ce3a2e2b72","src/unicode_tables/case_folding_simple.rs":"6d1f3d095132639228faf4806d05308c70ce2baa68cce69dca01ea159c4eaa15","src/unicode_tables/general_category.rs":"d21877600d387b8a0c5fbb0942458d0330c69aad6565e28134b8a1a371d2f4f4","src/unicode_tables/grapheme_cluster_break.rs":"f03a8be4a00265b568ca2a41d99f66a5d0f5fb423cb4113494153423a1123cda","src/unicode_tables/mod.rs":"26c837099cd934c8062e24bc9a0aaecf15fe1de03f9c6da3f3e1e5ac3ca24bee","src/unicode_tables/perl_decimal.rs":"e39a5934b504eb3282ccb26bbf50ecd764e720120eb7cf6c43662a2321665ab5","src/unicode_tables/perl_space.rs":"014e5d92b66730557e408c2d5c9b2f46d3d288aa85400ab9193c218c7b98ad21","src/unicode_tables/perl_word.rs":"ddf126f39171776ef83151d7a0dbc41da8dd09186723211fb966c4b304247a5e","src/unicode_tables/property_bool.rs":"21f72bd9f3955e3443549ef6609418817ae6df3c81fb5be90a0ceee9d7d3002d","src/unicode_tables/property_names.rs":"504ea44604cd15a7e827a89066bb81a847dd5c57cef360d9f4a914cf22afcf36","src/unicode_tables/property_values.rs":"4d793ad1b664c1913db146897c8eb4fa29d181b821f096de90dc889b738edb88","src/unicode_tables/script.rs":"5a7d2a958b93056081b8b2eb87c3a5609579ad791ad5b0c42959362ce6ea5b31","src/unicode_tables/script_extension.rs":"1d5f1985f7dcae833e78c3858231666b535bf60e032cfacc09d014c22bda6690","src/unicode_tables/sentence_break.rs":"cd5f0eb7ab6b0ec1c1fb4d78496dfecd691d0d0b76495538b9f376645a753deb","src/unicode_tables/word_break.rs":"eabeacfde7558cfe7b1556b0221f09c65f049de0b08c7cd464c1669040610a6b","src/utf8.rs":"f145b2cb0324e6a39260db685fdf2d88675dead54c5b808fb1b7f73a4b530d66","test":"8a9bd1bd9fb389e08288f951319a9bbb0d4c5284a2ba63cbdab7f6afa2c2f76e"},"package":"49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"} \ No newline at end of file
+{"files":{"Cargo.toml":"91aed5795d8faeb9a9f43face557622d92417a17bb453b5f12ee87073040fb7d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"67a3e673a9da6826fd4db5be6902841c821b52b98dc22c300f6e327872392b0a","benches/bench.rs":"d2b6ae5b939abd6093064f144b981b7739d7f474ec0698a1268052fc92406635","src/ast/mod.rs":"91b277a9bb979f85a44a67e39f17f77bde033764eea1f1a93aad1b61f1250089","src/ast/parse.rs":"150b42e944f766fdca70d654dbe32f8a17498432729c78b9eb50b73ae7f91f86","src/ast/print.rs":"d12f2cc75cd62f35623e1eb7a77ab8ac804b971752082700d2c4f550f834b249","src/ast/visitor.rs":"1a7b473147e4f6b89623ef1744a9e87f665bcf160fe08a33ce8e35011811ba71","src/either.rs":"1758e3edd056884eccadd995708d1e374ba9aa65846bd0e13b1aae852607c560","src/error.rs":"b3c5903a8937d2aff229a3ec65d4571d01ec4d9874c9a242ed6562c32702bcbd","src/hir/interval.rs":"e767fed363bebe4bbda0d78b8f07e73f321eaf4f837e2d7bd14a1617387e9a89","src/hir/literal/mod.rs":"ffe9a0aff7827f97bffd29eb2f4ba96627b16953161dce6c50a2f760e76bbd98","src/hir/mod.rs":"7f83c828223a54d236d348e48d5cedf015c904812110b6c38e9d52039c2b1572","src/hir/print.rs":"651b5d9776532a78612a5f9081372a57bad693890639ac19e3128b4defa96662","src/hir/translate.rs":"c7cd9693f73760263fd49a968714d27e7985ebe840211b2d83bca6686b0602a8","src/hir/visitor.rs":"e5bf7f8c09f6155e59c9d676fe25437f7e3700f9bf5d91101d7e246a64c11d5a","src/lib.rs":"a004f65196dd5745b3112e4acc8c467b18495cecac64a58d6608b35de67371cb","src/parser.rs":"0dfb553a152e008b2755f115663e553ed99c4b8e6a4dcbcad1662737534de49d","src/unicode.rs":"2b575c75dcb8fd6becb06f2a8faa33d6f54779708bc6b103070b8acb2b3323bb","src/unicode_tables/LICENSE-UNICODE":"74db5baf44a41b1000312c673544b3374e4198af5605c7f9080a402cec42cfa3","src/unicode_tables/age.rs":"9b36dd7d359d2fa21e6ea9734a37415ba0ba9469e27b8536308f5b79139d4191","src/unicode_tables/case_folding_simple.rs":"52b74161fa1e8f2db66737156e081cece82c1f503dee604f901b2df095beb90d","src/unicode_tables/general_category.rs":"c10beb78cdab6ec14846573bfb7965b5b3a4c114d20352c21a666d8de740a049","src/unicode_tables/grapheme_cluster_break.rs":"10ba739e06f880570eaf90bddd78ec468d939c0be7cd6e39f52cfa68371a9885","src/unicode_tables/mod.rs":"26c837099cd934c8062e24bc9a0aaecf15fe1de03f9c6da3f3e1e5ac3ca24bee","src/unicode_tables/perl_decimal.rs":"2084b101c615ff368a47af72df760003a76e869dfc191e0224cd024bb88165ed","src/unicode_tables/perl_space.rs":"75b9f3c9e302fd0994ee6e9ee21ee0ab36efc513cfd083647aed9854b977a33d","src/unicode_tables/perl_word.rs":"c588d6b29b98c1160452b54e9275d43583bc3454e29aee1c07e6a18389011a9c","src/unicode_tables/property_bool.rs":"319740ac6074b2d4e6e22bf4dde7db2feb569f9b71467c893fb2553d149b9f1d","src/unicode_tables/property_names.rs":"f33b186d7d8ee5342d74ef214f7b2cfbb24345233fa49a2abf2578cae61fbdd3","src/unicode_tables/property_values.rs":"716eb87716a9a4b2a9ef2c2242d6831692564875c8e218ffa758266ca33c88b6","src/unicode_tables/script.rs":"f6020589e33bd3a058468a22ce51391f6e512f9eb88c8ac60635fae7cd641ee2","src/unicode_tables/script_extension.rs":"2ba03d13813161a064b11e9f87b87685fbf29699ef553acc6112606b7ca98169","src/unicode_tables/sentence_break.rs":"bf7635623e4dbe0195789ed8b21f83ce3394ed2c445a3005f929f4f75b2a83c3","src/unicode_tables/word_break.rs":"8f7e261a67d1adb32ea627e43cb61d6566c33a4e229113d911e86941e6997a41","src/utf8.rs":"de854b3bfb3f7dbefc422f6a25935aaeef55ead2c35386c712a1fe9bf81a7b6f","test":"8a9bd1bd9fb389e08288f951319a9bbb0d4c5284a2ba63cbdab7f6afa2c2f76e"},"package":"a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"} \ No newline at end of file
diff --git a/vendor/regex-syntax/Cargo.toml b/vendor/regex-syntax/Cargo.toml
index 16ac50e74..10e6bbf53 100644
--- a/vendor/regex-syntax/Cargo.toml
+++ b/vendor/regex-syntax/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "regex-syntax"
-version = "0.6.26"
+version = "0.6.27"
authors = ["The Rust Project Developers"]
description = "A regular expression parser."
homepage = "https://github.com/rust-lang/regex"
diff --git a/vendor/regex-syntax/src/ast/mod.rs b/vendor/regex-syntax/src/ast/mod.rs
index 9b9127b1f..387ea3a69 100644
--- a/vendor/regex-syntax/src/ast/mod.rs
+++ b/vendor/regex-syntax/src/ast/mod.rs
@@ -15,7 +15,7 @@ mod visitor;
/// An error that occurred while parsing a regular expression into an abstract
/// syntax tree.
///
-/// Note that note all ASTs represents a valid regular expression. For example,
+/// Note that not all ASTs represents a valid regular expression. For example,
/// an AST is constructed without error for `\p{Quux}`, but `Quux` is not a
/// valid Unicode property name. That particular error is reported when
/// translating an AST to the high-level intermediate representation (`HIR`).
@@ -385,7 +385,7 @@ impl PartialOrd for Position {
impl Span {
/// Create a new span with the given positions.
pub fn new(start: Position, end: Position) -> Span {
- Span { start: start, end: end }
+ Span { start, end }
}
/// Create a new span using the given position as the start and end.
@@ -427,7 +427,7 @@ impl Position {
///
/// `column` is the approximate column number, starting at `1`.
pub fn new(offset: usize, line: usize, column: usize) -> Position {
- Position { offset: offset, line: line, column: column }
+ Position { offset, line, column }
}
}
diff --git a/vendor/regex-syntax/src/ast/parse.rs b/vendor/regex-syntax/src/ast/parse.rs
index 9824661c9..6e9c9aca0 100644
--- a/vendor/regex-syntax/src/ast/parse.rs
+++ b/vendor/regex-syntax/src/ast/parse.rs
@@ -202,7 +202,7 @@ impl ParserBuilder {
/// Enable verbose mode in the regular expression.
///
- /// When enabled, verbose mode permits insigificant whitespace in many
+ /// When enabled, verbose mode permits insignificant whitespace in many
/// places in the regular expression, as well as comments. Comments are
/// started using `#` and continue until the end of the line.
///
@@ -366,7 +366,7 @@ impl Parser {
impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
/// Build an internal parser from a parser configuration and a pattern.
fn new(parser: P, pattern: &'s str) -> ParserI<'s, P> {
- ParserI { parser: parser, pattern: pattern }
+ ParserI { parser, pattern }
}
/// Return a reference to the parser state.
@@ -381,11 +381,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
/// Create a new error with the given span and error type.
fn error(&self, span: Span, kind: ast::ErrorKind) -> ast::Error {
- ast::Error {
- kind: kind,
- pattern: self.pattern().to_string(),
- span: span,
- }
+ ast::Error { kind, pattern: self.pattern().to_string(), span }
}
/// Return the current offset of the parser.
@@ -481,11 +477,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
column = column.checked_add(1).unwrap();
}
offset += self.char().len_utf8();
- self.parser().pos.set(Position {
- offset: offset,
- line: line,
- column: column,
- });
+ self.parser().pos.set(Position { offset, line, column });
self.pattern()[self.offset()..].chars().next().is_some()
}
@@ -703,8 +695,8 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
.unwrap_or(old_ignore_whitespace);
self.parser().stack_group.borrow_mut().push(
GroupState::Group {
- concat: concat,
- group: group,
+ concat,
+ group,
ignore_whitespace: old_ignore_whitespace,
},
);
@@ -899,12 +891,8 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
#[inline(never)]
fn unclosed_class_error(&self) -> ast::Error {
for state in self.parser().stack_class.borrow().iter().rev() {
- match *state {
- ClassState::Open { ref set, .. } => {
- return self
- .error(set.span, ast::ErrorKind::ClassUnclosed);
- }
- _ => {}
+ if let ClassState::Open { ref set, .. } = *state {
+ return self.error(set.span, ast::ErrorKind::ClassUnclosed);
}
}
// We are guaranteed to have a non-empty stack with at least
@@ -950,8 +938,8 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
};
let span = Span::new(lhs.span().start, rhs.span().end);
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
- kind: kind,
+ span,
+ kind,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
})
@@ -1010,7 +998,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
let ast = self.pop_group_end(concat)?;
NestLimiter::new(self).check(&ast)?;
Ok(ast::WithComments {
- ast: ast,
+ ast,
comments: mem::replace(
&mut *self.parser().comments.borrow_mut(),
vec![],
@@ -1066,9 +1054,9 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
span: ast.span().with_end(self.pos()),
op: ast::RepetitionOp {
span: Span::new(op_start, self.pos()),
- kind: kind,
+ kind,
},
- greedy: greedy,
+ greedy,
ast: Box::new(ast),
}));
Ok(concat)
@@ -1170,7 +1158,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
span: op_span,
kind: ast::RepetitionKind::Range(range),
},
- greedy: greedy,
+ greedy,
ast: Box::new(ast),
}));
Ok(concat)
@@ -1235,7 +1223,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
}
Ok(Either::Left(ast::SetFlags {
span: Span { end: self.pos(), ..open_span },
- flags: flags,
+ flags,
}))
} else {
assert_eq!(char_end, ':');
@@ -1428,7 +1416,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
let ast = Primitive::Literal(ast::Literal {
span: self.span_char(),
kind: ast::LiteralKind::Verbatim,
- c: c,
+ c,
});
self.bump();
Ok(ast)
@@ -1494,16 +1482,16 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
let span = Span::new(start, self.pos());
if is_meta_character(c) {
return Ok(Primitive::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Punctuation,
- c: c,
+ c,
}));
}
let special = |kind, c| {
Ok(Primitive::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Special(kind),
- c: c,
+ c,
}))
};
match c {
@@ -1517,19 +1505,19 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
special(ast::SpecialLiteralKind::Space, ' ')
}
'A' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::StartText,
})),
'z' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::EndText,
})),
'b' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::WordBoundary,
})),
'B' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::NotWordBoundary,
})),
_ => Err(self.error(span, ast::ErrorKind::EscapeUnrecognized)),
@@ -1569,7 +1557,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
ast::Literal {
span: Span::new(start, end),
kind: ast::LiteralKind::Octal,
- c: c,
+ c,
}
}
@@ -1645,7 +1633,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
Some(c) => Ok(ast::Literal {
span: Span::new(start, end),
kind: ast::LiteralKind::HexFixed(kind),
- c: c,
+ c,
}),
}
}
@@ -1700,7 +1688,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
Some(c) => Ok(ast::Literal {
span: Span::new(start, self.pos()),
kind: ast::LiteralKind::HexBrace(kind),
- c: c,
+ c,
}),
}
}
@@ -1927,7 +1915,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
}));
if !self.bump_and_bump_space() {
return Err(self.error(
- Span::new(start, self.pos()),
+ Span::new(start, start),
ast::ErrorKind::ClassUnclosed,
));
}
@@ -1949,7 +1937,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
}
let set = ast::ClassBracketed {
span: Span::new(start, self.pos()),
- negated: negated,
+ negated,
kind: ast::ClassSet::union(ast::ClassSetUnion {
span: Span::new(union.span.start, union.span.start),
items: vec![],
@@ -2026,8 +2014,8 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
};
Some(ast::ClassAscii {
span: Span::new(start, self.pos()),
- kind: kind,
- negated: negated,
+ kind,
+ negated,
})
}
@@ -2108,8 +2096,8 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
};
Ok(ast::ClassUnicode {
span: Span::new(start, self.pos()),
- negated: negated,
- kind: kind,
+ negated,
+ kind,
})
}
@@ -2130,7 +2118,7 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
'W' => (true, ast::ClassPerlKind::Word),
c => panic!("expected valid Perl class but got '{}'", c),
};
- ast::ClassPerl { span: span, kind: kind, negated: negated }
+ ast::ClassPerl { span, kind, negated }
}
}
@@ -2146,7 +2134,7 @@ struct NestLimiter<'p, 's, P> {
impl<'p, 's, P: Borrow<Parser>> NestLimiter<'p, 's, P> {
fn new(p: &'p ParserI<'s, P>) -> NestLimiter<'p, 's, P> {
- NestLimiter { p: p, depth: 0 }
+ NestLimiter { p, depth: 0 }
}
#[inline(never)]
@@ -2429,18 +2417,18 @@ mod tests {
/// Create a punctuation literal starting at the given position.
fn punct_lit(c: char, span: Span) -> Ast {
Ast::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Punctuation,
- c: c,
+ c,
})
}
/// Create a verbatim literal with the given span.
fn lit_with(c: char, span: Span) -> Ast {
Ast::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Verbatim,
- c: c,
+ c,
})
}
@@ -2451,12 +2439,12 @@ mod tests {
/// Create a concatenation with the given span.
fn concat_with(span: Span, asts: Vec<Ast>) -> Ast {
- Ast::Concat(ast::Concat { span: span, asts: asts })
+ Ast::Concat(ast::Concat { span, asts })
}
/// Create an alternation with the given span.
fn alt(range: Range<usize>, asts: Vec<Ast>) -> Ast {
- Ast::Alternation(ast::Alternation { span: span(range), asts: asts })
+ Ast::Alternation(ast::Alternation { span: span(range), asts })
}
/// Create a capturing group with the given span.
@@ -2498,7 +2486,7 @@ mod tests {
span: span_range(pat, range.clone()),
flags: ast::Flags {
span: span_range(pat, (range.start + 2)..(range.end - 1)),
- items: items,
+ items,
},
})
}
@@ -4208,7 +4196,7 @@ bar
Ok(Primitive::Literal(ast::Literal {
span: span(0..2),
kind: ast::LiteralKind::Special(kind.clone()),
- c: c,
+ c,
}))
);
}
@@ -4402,7 +4390,7 @@ bar
kind: ast::LiteralKind::HexFixed(
ast::HexLiteralKind::UnicodeShort
),
- c: c,
+ c,
}))
);
}
@@ -4466,7 +4454,7 @@ bar
kind: ast::LiteralKind::HexFixed(
ast::HexLiteralKind::UnicodeLong
),
- c: c,
+ c,
}))
);
}
@@ -4667,10 +4655,7 @@ bar
#[test]
fn parse_set_class() {
fn union(span: Span, items: Vec<ast::ClassSetItem>) -> ast::ClassSet {
- ast::ClassSet::union(ast::ClassSetUnion {
- span: span,
- items: items,
- })
+ ast::ClassSet::union(ast::ClassSetUnion { span, items })
}
fn intersection(
@@ -4679,7 +4664,7 @@ bar
rhs: ast::ClassSet,
) -> ast::ClassSet {
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
+ span,
kind: ast::ClassSetBinaryOpKind::Intersection,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
@@ -4692,7 +4677,7 @@ bar
rhs: ast::ClassSet,
) -> ast::ClassSet {
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
+ span,
kind: ast::ClassSetBinaryOpKind::Difference,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
@@ -4705,7 +4690,7 @@ bar
rhs: ast::ClassSet,
) -> ast::ClassSet {
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
+ span,
kind: ast::ClassSetBinaryOpKind::SymmetricDifference,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
@@ -4734,9 +4719,9 @@ bar
fn lit(span: Span, c: char) -> ast::ClassSetItem {
ast::ClassSetItem::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Verbatim,
- c: c,
+ c,
})
}
@@ -4756,7 +4741,7 @@ bar
..span.end
};
ast::ClassSetItem::Range(ast::ClassSetRange {
- span: span,
+ span,
start: ast::Literal {
span: Span { end: pos1, ..span },
kind: ast::LiteralKind::Verbatim,
@@ -4771,19 +4756,11 @@ bar
}
fn alnum(span: Span, negated: bool) -> ast::ClassAscii {
- ast::ClassAscii {
- span: span,
- kind: ast::ClassAsciiKind::Alnum,
- negated: negated,
- }
+ ast::ClassAscii { span, kind: ast::ClassAsciiKind::Alnum, negated }
}
fn lower(span: Span, negated: bool) -> ast::ClassAscii {
- ast::ClassAscii {
- span: span,
- kind: ast::ClassAsciiKind::Lower,
- negated: negated,
- }
+ ast::ClassAscii { span, kind: ast::ClassAsciiKind::Lower, negated }
}
assert_eq!(
@@ -5515,14 +5492,23 @@ bar
assert_eq!(
parser("[-").parse_set_class_open().unwrap_err(),
TestError {
- span: span(0..2),
+ span: span(0..0),
kind: ast::ErrorKind::ClassUnclosed,
}
);
assert_eq!(
parser("[--").parse_set_class_open().unwrap_err(),
TestError {
- span: span(0..3),
+ span: span(0..0),
+ kind: ast::ErrorKind::ClassUnclosed,
+ }
+ );
+
+ // See: https://github.com/rust-lang/regex/issues/792
+ assert_eq!(
+ parser("(?x)[-#]").parse_with_comments().unwrap_err(),
+ TestError {
+ span: span(4..4),
kind: ast::ErrorKind::ClassUnclosed,
}
);
diff --git a/vendor/regex-syntax/src/ast/visitor.rs b/vendor/regex-syntax/src/ast/visitor.rs
index a0d1e7dd5..78ee487cf 100644
--- a/vendor/regex-syntax/src/ast/visitor.rs
+++ b/vendor/regex-syntax/src/ast/visitor.rs
@@ -388,7 +388,7 @@ impl<'a> HeapVisitor<'a> {
Some(ClassFrame::Union { head: item, tail: &[] })
}
ast::ClassSet::BinaryOp(ref op) => {
- Some(ClassFrame::Binary { op: op })
+ Some(ClassFrame::Binary { op })
}
}
}
@@ -402,11 +402,9 @@ impl<'a> HeapVisitor<'a> {
})
}
}
- ClassInduct::BinaryOp(op) => Some(ClassFrame::BinaryLHS {
- op: op,
- lhs: &op.lhs,
- rhs: &op.rhs,
- }),
+ ClassInduct::BinaryOp(op) => {
+ Some(ClassFrame::BinaryLHS { op, lhs: &op.lhs, rhs: &op.rhs })
+ }
_ => None,
}
}
@@ -427,7 +425,7 @@ impl<'a> HeapVisitor<'a> {
}
ClassFrame::Binary { .. } => None,
ClassFrame::BinaryLHS { op, rhs, .. } => {
- Some(ClassFrame::BinaryRHS { op: op, rhs: rhs })
+ Some(ClassFrame::BinaryRHS { op, rhs })
}
ClassFrame::BinaryRHS { .. } => None,
}
diff --git a/vendor/regex-syntax/src/error.rs b/vendor/regex-syntax/src/error.rs
index 71cfa426a..1230d2fc5 100644
--- a/vendor/regex-syntax/src/error.rs
+++ b/vendor/regex-syntax/src/error.rs
@@ -182,7 +182,7 @@ impl<'p> Spans<'p> {
if line_count <= 1 { 0 } else { line_count.to_string().len() };
let mut spans = Spans {
pattern: &fmter.pattern,
- line_number_width: line_number_width,
+ line_number_width,
by_line: vec![vec![]; line_count],
multi_line: vec![],
};
@@ -288,7 +288,7 @@ fn repeat_char(c: char, count: usize) -> String {
mod tests {
use crate::ast::parse::Parser;
- fn assert_panic_message(pattern: &str, expected_msg: &str) -> () {
+ fn assert_panic_message(pattern: &str, expected_msg: &str) {
let result = Parser::new().parse(pattern);
match result {
Ok(_) => {
diff --git a/vendor/regex-syntax/src/hir/interval.rs b/vendor/regex-syntax/src/hir/interval.rs
index cfaa2cb45..56698c53a 100644
--- a/vendor/regex-syntax/src/hir/interval.rs
+++ b/vendor/regex-syntax/src/hir/interval.rs
@@ -114,8 +114,8 @@ impl<I: Interval> IntervalSet<I> {
// we're done.
let drain_end = self.ranges.len();
- let mut ita = (0..drain_end).into_iter();
- let mut itb = (0..other.ranges.len()).into_iter();
+ let mut ita = 0..drain_end;
+ let mut itb = 0..other.ranges.len();
let mut a = ita.next().unwrap();
let mut b = itb.next().unwrap();
loop {
diff --git a/vendor/regex-syntax/src/hir/literal/mod.rs b/vendor/regex-syntax/src/hir/literal/mod.rs
index 1e66d2cc3..fbc5d3c97 100644
--- a/vendor/regex-syntax/src/hir/literal/mod.rs
+++ b/vendor/regex-syntax/src/hir/literal/mod.rs
@@ -225,7 +225,7 @@ impl Literals {
if self.lits.is_empty() {
return self.to_empty();
}
- let mut old: Vec<Literal> = self.lits.iter().cloned().collect();
+ let mut old = self.lits.to_vec();
let mut new = self.to_empty();
'OUTER: while let Some(mut candidate) = old.pop() {
if candidate.is_empty() {
@@ -256,15 +256,13 @@ impl Literals {
old.push(lit3);
lit2.clear();
}
- } else {
- if let Some(i) = position(&lit2, &candidate) {
- lit2.cut();
- let mut new_candidate = candidate.clone();
- new_candidate.truncate(i);
- new_candidate.cut();
- old.push(new_candidate);
- candidate.clear();
- }
+ } else if let Some(i) = position(&lit2, &candidate) {
+ lit2.cut();
+ let mut new_candidate = candidate.clone();
+ new_candidate.truncate(i);
+ new_candidate.cut();
+ old.push(new_candidate);
+ candidate.clear();
}
// Oops, the candidate is already represented in the set.
if candidate.is_empty() {
@@ -793,7 +791,7 @@ fn repeat_range_literals<F: FnMut(&Hir, &mut Literals)>(
f(
&Hir::repetition(hir::Repetition {
kind: hir::RepetitionKind::ZeroOrMore,
- greedy: greedy,
+ greedy,
hir: Box::new(e.clone()),
}),
lits,
@@ -932,12 +930,10 @@ fn escape_unicode(bytes: &[u8]) -> String {
if c.is_whitespace() {
let escaped = if c as u32 <= 0x7F {
escape_byte(c as u8)
+ } else if c as u32 <= 0xFFFF {
+ format!(r"\u{{{:04x}}}", c as u32)
} else {
- if c as u32 <= 0xFFFF {
- format!(r"\u{{{:04x}}}", c as u32)
- } else {
- format!(r"\U{{{:08x}}}", c as u32)
- }
+ format!(r"\U{{{:08x}}}", c as u32)
};
space_escaped.push_str(&escaped);
} else {
diff --git a/vendor/regex-syntax/src/hir/mod.rs b/vendor/regex-syntax/src/hir/mod.rs
index f5cf992e5..1096e9f05 100644
--- a/vendor/regex-syntax/src/hir/mod.rs
+++ b/vendor/regex-syntax/src/hir/mod.rs
@@ -243,7 +243,7 @@ impl Hir {
info.set_match_empty(true);
info.set_literal(false);
info.set_alternation_literal(false);
- Hir { kind: HirKind::Empty, info: info }
+ Hir { kind: HirKind::Empty, info }
}
/// Creates a literal HIR expression.
@@ -268,7 +268,7 @@ impl Hir {
info.set_match_empty(false);
info.set_literal(true);
info.set_alternation_literal(true);
- Hir { kind: HirKind::Literal(lit), info: info }
+ Hir { kind: HirKind::Literal(lit), info }
}
/// Creates a class HIR expression.
@@ -285,7 +285,7 @@ impl Hir {
info.set_match_empty(false);
info.set_literal(false);
info.set_alternation_literal(false);
- Hir { kind: HirKind::Class(class), info: info }
+ Hir { kind: HirKind::Class(class), info }
}
/// Creates an anchor assertion HIR expression.
@@ -318,7 +318,7 @@ impl Hir {
if let Anchor::EndLine = anchor {
info.set_line_anchored_end(true);
}
- Hir { kind: HirKind::Anchor(anchor), info: info }
+ Hir { kind: HirKind::Anchor(anchor), info }
}
/// Creates a word boundary assertion HIR expression.
@@ -345,7 +345,7 @@ impl Hir {
if let WordBoundary::AsciiNegate = word_boundary {
info.set_always_utf8(false);
}
- Hir { kind: HirKind::WordBoundary(word_boundary), info: info }
+ Hir { kind: HirKind::WordBoundary(word_boundary), info }
}
/// Creates a repetition HIR expression.
@@ -372,7 +372,7 @@ impl Hir {
info.set_match_empty(rep.is_match_empty() || rep.hir.is_match_empty());
info.set_literal(false);
info.set_alternation_literal(false);
- Hir { kind: HirKind::Repetition(rep), info: info }
+ Hir { kind: HirKind::Repetition(rep), info }
}
/// Creates a group HIR expression.
@@ -389,7 +389,7 @@ impl Hir {
info.set_match_empty(group.hir.is_match_empty());
info.set_literal(false);
info.set_alternation_literal(false);
- Hir { kind: HirKind::Group(group), info: info }
+ Hir { kind: HirKind::Group(group), info }
}
/// Returns the concatenation of the given expressions.
@@ -480,7 +480,7 @@ impl Hir {
})
.any(|e| e.is_line_anchored_end()),
);
- Hir { kind: HirKind::Concat(exprs), info: info }
+ Hir { kind: HirKind::Concat(exprs), info }
}
}
}
@@ -542,7 +542,7 @@ impl Hir {
let x = info.is_alternation_literal() && e.is_literal();
info.set_alternation_literal(x);
}
- Hir { kind: HirKind::Alternation(exprs), info: info }
+ Hir { kind: HirKind::Alternation(exprs), info }
}
}
}
diff --git a/vendor/regex-syntax/src/hir/translate.rs b/vendor/regex-syntax/src/hir/translate.rs
index 56afbbed8..890e1608b 100644
--- a/vendor/regex-syntax/src/hir/translate.rs
+++ b/vendor/regex-syntax/src/hir/translate.rs
@@ -589,7 +589,7 @@ struct TranslatorI<'t, 'p> {
impl<'t, 'p> TranslatorI<'t, 'p> {
/// Build a new internal translator.
fn new(trans: &'t Translator, pattern: &'p str) -> TranslatorI<'t, 'p> {
- TranslatorI { trans: trans, pattern: pattern }
+ TranslatorI { trans, pattern }
}
/// Return a reference to the underlying translator.
@@ -609,7 +609,7 @@ impl<'t, 'p> TranslatorI<'t, 'p> {
/// Create a new error with the given span and error type.
fn error(&self, span: Span, kind: ErrorKind) -> Error {
- Error { kind: kind, pattern: self.pattern.to_string(), span: span }
+ Error { kind, pattern: self.pattern.to_string(), span }
}
/// Return a copy of the active flags.
@@ -779,7 +779,7 @@ impl<'t, 'p> TranslatorI<'t, 'p> {
}
ast::GroupKind::NonCapturing(_) => hir::GroupKind::NonCapturing,
};
- Hir::group(hir::Group { kind: kind, hir: Box::new(expr) })
+ Hir::group(hir::Group { kind, hir: Box::new(expr) })
}
fn hir_repetition(&self, rep: &ast::Repetition, expr: Hir) -> Hir {
@@ -802,11 +802,7 @@ impl<'t, 'p> TranslatorI<'t, 'p> {
};
let greedy =
if self.flags().swap_greed() { !rep.greedy } else { rep.greedy };
- Hir::repetition(hir::Repetition {
- kind: kind,
- greedy: greedy,
- hir: Box::new(expr),
- })
+ Hir::repetition(hir::Repetition { kind, greedy, hir: Box::new(expr) })
}
fn hir_unicode_class(
@@ -1238,7 +1234,7 @@ mod tests {
fn hir_quest(greedy: bool, expr: Hir) -> Hir {
Hir::repetition(hir::Repetition {
kind: hir::RepetitionKind::ZeroOrOne,
- greedy: greedy,
+ greedy,
hir: Box::new(expr),
})
}
@@ -1246,7 +1242,7 @@ mod tests {
fn hir_star(greedy: bool, expr: Hir) -> Hir {
Hir::repetition(hir::Repetition {
kind: hir::RepetitionKind::ZeroOrMore,
- greedy: greedy,
+ greedy,
hir: Box::new(expr),
})
}
@@ -1254,7 +1250,7 @@ mod tests {
fn hir_plus(greedy: bool, expr: Hir) -> Hir {
Hir::repetition(hir::Repetition {
kind: hir::RepetitionKind::OneOrMore,
- greedy: greedy,
+ greedy,
hir: Box::new(expr),
})
}
@@ -1262,7 +1258,7 @@ mod tests {
fn hir_range(greedy: bool, range: hir::RepetitionRange, expr: Hir) -> Hir {
Hir::repetition(hir::Repetition {
kind: hir::RepetitionKind::Range(range),
- greedy: greedy,
+ greedy,
hir: Box::new(expr),
})
}
diff --git a/vendor/regex-syntax/src/lib.rs b/vendor/regex-syntax/src/lib.rs
index 9e9af756a..1dfb38af3 100644
--- a/vendor/regex-syntax/src/lib.rs
+++ b/vendor/regex-syntax/src/lib.rs
@@ -195,7 +195,7 @@ pub fn escape_into(text: &str, buf: &mut String) {
}
}
-/// Returns true if the give character has significance in a regex.
+/// Returns true if the given character has significance in a regex.
///
/// These are the only characters that are allowed to be escaped, with one
/// exception: an ASCII space character may be escaped when extended mode (with
diff --git a/vendor/regex-syntax/src/parser.rs b/vendor/regex-syntax/src/parser.rs
index a5ee524a8..ded95b280 100644
--- a/vendor/regex-syntax/src/parser.rs
+++ b/vendor/regex-syntax/src/parser.rs
@@ -96,7 +96,7 @@ impl ParserBuilder {
/// Enable verbose mode in the regular expression.
///
- /// When enabled, verbose mode permits insigificant whitespace in many
+ /// When enabled, verbose mode permits insignificant whitespace in many
/// places in the regular expression, as well as comments. Comments are
/// started using `#` and continue until the end of the line.
///
diff --git a/vendor/regex-syntax/src/unicode.rs b/vendor/regex-syntax/src/unicode.rs
index b894c7db2..70d5954b7 100644
--- a/vendor/regex-syntax/src/unicode.rs
+++ b/vendor/regex-syntax/src/unicode.rs
@@ -99,7 +99,7 @@ pub fn simple_fold(
Ok(CASE_FOLDING_SIMPLE
.binary_search_by_key(&c, |&(c1, _)| c1)
- .map(|i| CASE_FOLDING_SIMPLE[i].1.iter().map(|&c| c))
+ .map(|i| CASE_FOLDING_SIMPLE[i].1.iter().copied())
.map_err(|i| {
if i >= CASE_FOLDING_SIMPLE.len() {
None
@@ -580,7 +580,7 @@ fn ages(canonical_age: &str) -> Result<impl Iterator<Item = Range>> {
fn imp(canonical_age: &str) -> Result<impl Iterator<Item = Range>> {
use crate::unicode_tables::age;
- const AGES: &'static [(&'static str, Range)] = &[
+ const AGES: &[(&str, Range)] = &[
("V1_1", age::V1_1),
("V2_0", age::V2_0),
("V2_1", age::V2_1),
@@ -604,13 +604,14 @@ fn ages(canonical_age: &str) -> Result<impl Iterator<Item = Range>> {
("V12_0", age::V12_0),
("V12_1", age::V12_1),
("V13_0", age::V13_0),
+ ("V14_0", age::V14_0),
];
assert_eq!(AGES.len(), age::BY_NAME.len(), "ages are out of sync");
let pos = AGES.iter().position(|&(age, _)| canonical_age == age);
match pos {
None => Err(Error::PropertyValueNotFound),
- Some(i) => Ok(AGES[..i + 1].iter().map(|&(_, classes)| classes)),
+ Some(i) => Ok(AGES[..=i].iter().map(|&(_, classes)| classes)),
}
}
diff --git a/vendor/regex-syntax/src/unicode_tables/age.rs b/vendor/regex-syntax/src/unicode_tables/age.rs
index 7772919eb..ffdfef316 100644
--- a/vendor/regex-syntax/src/unicode_tables/age.rs
+++ b/vendor/regex-syntax/src/unicode_tables/age.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate age ucd-13.0.0 --chars
+// ucd-generate age /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("V10_0", V10_0),
@@ -12,6 +12,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("V12_0", V12_0),
("V12_1", V12_1),
("V13_0", V13_0),
+ ("V14_0", V14_0),
("V1_1", V1_1),
("V2_0", V2_0),
("V2_1", V2_1),
@@ -203,69 +204,150 @@ pub const V12_0: &'static [(char, char)] = &[
pub const V12_1: &'static [(char, char)] = &[('ã‹¿', 'ã‹¿')];
pub const V13_0: &'static [(char, char)] = &[
- ('\u{8be}', '\u{8c7}'),
+ ('ࢾ', 'ࣇ'),
('\u{b55}', '\u{b55}'),
- ('\u{d04}', '\u{d04}'),
+ ('à´„', 'à´„'),
('\u{d81}', '\u{d81}'),
('\u{1abf}', '\u{1ac0}'),
- ('\u{2b97}', '\u{2b97}'),
- ('\u{2e50}', '\u{2e52}'),
- ('\u{31bb}', '\u{31bf}'),
- ('\u{4db6}', '\u{4dbf}'),
- ('\u{9ff0}', '\u{9ffc}'),
- ('\u{a7c7}', '\u{a7ca}'),
- ('\u{a7f5}', '\u{a7f6}'),
+ ('â®—', 'â®—'),
+ ('â¹', 'â¹’'),
+ ('ㆻ', 'ㆿ'),
+ ('䶶', '䶿'),
+ ('鿰', '鿼'),
+ ('Ꟈ', 'ꟊ'),
+ ('Ꟶ', 'ꟶ'),
('\u{a82c}', '\u{a82c}'),
- ('\u{ab68}', '\u{ab6b}'),
- ('\u{1019c}', '\u{1019c}'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eab}', '\u{10ead}'),
- ('\u{10eb0}', '\u{10eb1}'),
- ('\u{10fb0}', '\u{10fcb}'),
- ('\u{11147}', '\u{11147}'),
- ('\u{111ce}', '\u{111cf}'),
- ('\u{1145a}', '\u{1145a}'),
- ('\u{11460}', '\u{11461}'),
- ('\u{11900}', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
- ('\u{1193b}', '\u{11946}'),
- ('\u{11950}', '\u{11959}'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('ê­¨', 'ê­«'),
+ ('ð†œ', 'ð†œ'),
+ ('ðº€', 'ðº©'),
+ ('\u{10eab}', 'ðº­'),
+ ('ðº°', 'ðº±'),
+ ('ð¾°', 'ð¿‹'),
+ ('ð‘…‡', 'ð‘…‡'),
+ ('𑇎', '\u{111cf}'),
+ ('ð‘‘š', 'ð‘‘š'),
+ ('ð‘‘ ', 'ð‘‘¡'),
+ ('𑤀', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
+ ('\u{1193b}', '𑥆'),
+ ('ð‘¥', 'ð‘¥™'),
+ ('𑾰', '𑾰'),
('\u{16fe4}', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
- ('\u{18af3}', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('\u{1f10d}', '\u{1f10f}'),
- ('\u{1f16d}', '\u{1f16f}'),
- ('\u{1f1ad}', '\u{1f1ad}'),
- ('\u{1f6d6}', '\u{1f6d7}'),
- ('\u{1f6fb}', '\u{1f6fc}'),
- ('\u{1f8b0}', '\u{1f8b1}'),
- ('\u{1f90c}', '\u{1f90c}'),
- ('\u{1f972}', '\u{1f972}'),
- ('\u{1f977}', '\u{1f978}'),
- ('\u{1f9a3}', '\u{1f9a4}'),
- ('\u{1f9ab}', '\u{1f9ad}'),
- ('\u{1f9cb}', '\u{1f9cb}'),
- ('\u{1fa74}', '\u{1fa74}'),
- ('\u{1fa83}', '\u{1fa86}'),
- ('\u{1fa96}', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
- ('\u{1fb00}', '\u{1fb92}'),
- ('\u{1fb94}', '\u{1fbca}'),
- ('\u{1fbf0}', '\u{1fbf9}'),
- ('\u{2a6d7}', '\u{2a6dd}'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð–¿°', 'ð–¿±'),
+ ('𘫳', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('ðŸ„', 'ðŸ„'),
+ ('🅭', '🅯'),
+ ('🆭', '🆭'),
+ ('🛖', '🛗'),
+ ('🛻', '🛼'),
+ ('🢰', '🢱'),
+ ('🤌', '🤌'),
+ ('🥲', '🥲'),
+ ('🥷', '🥸'),
+ ('🦣', '🦤'),
+ ('🦫', '🦭'),
+ ('🧋', '🧋'),
+ ('🩴', '🩴'),
+ ('🪃', '🪆'),
+ ('🪖', '🪨'),
+ ('🪰', '🪶'),
+ ('🫀', '🫂'),
+ ('ðŸ«', '🫖'),
+ ('🬀', '🮒'),
+ ('🮔', '🯊'),
+ ('🯰', '🯹'),
+ ('𪛗', 'ðª›'),
+ ('ð°€€', 'ð±Š'),
+];
+
+pub const V14_0: &'static [(char, char)] = &[
+ ('Ø', 'Ø'),
+ ('ࡰ', 'ࢎ'),
+ ('\u{890}', '\u{891}'),
+ ('\u{898}', '\u{89f}'),
+ ('ࢵ', 'ࢵ'),
+ ('ࣈ', '\u{8d2}'),
+ ('\u{c3c}', '\u{c3c}'),
+ ('à±', 'à±'),
+ ('à³', 'à³'),
+ ('áœ', 'áœ'),
+ ('᜕', '᜕'),
+ ('ᜟ', 'ᜟ'),
+ ('\u{180f}', '\u{180f}'),
+ ('\u{1ac1}', '\u{1ace}'),
+ ('ᭌ', 'ᭌ'),
+ ('á­½', 'á­¾'),
+ ('\u{1dfa}', '\u{1dfa}'),
+ ('⃀', '⃀'),
+ ('â°¯', 'â°¯'),
+ ('ⱟ', 'ⱟ'),
+ ('⹓', 'â¹'),
+ ('鿽', '鿿'),
+ ('Ꟁ', 'êŸ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꟴ'),
+ ('﯂', '﯂'),
+ ('ïµ€', 'ïµ'),
+ ('ï·', 'ï·'),
+ ('ï·¾', 'ï·¿'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
+ ('ð½°', 'ð¾‰'),
+ ('\u{11070}', 'ð‘µ'),
+ ('\u{110c2}', '\u{110c2}'),
+ ('ð‘š¹', 'ð‘š¹'),
+ ('ð‘€', 'ð‘†'),
+ ('𑪰', '𑪿'),
+ ('ð’¾', 'ð’¿²'),
+ ('𖩰', '𖪾'),
+ ('𖫀', '𖫉'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛄟', '𛄢'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
+ ('ðœ½', '𜿃'),
+ ('ð‡©', 'ð‡ª'),
+ ('ð¼€', 'ð¼ž'),
+ ('ðžŠ', '\u{1e2ae}'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
+ ('ðŸ›', '🛟'),
+ ('🟰', '🟰'),
+ ('🥹', '🥹'),
+ ('🧌', '🧌'),
+ ('🩻', '🩼'),
+ ('🪩', '🪬'),
+ ('🪷', '🪺'),
+ ('🫃', '🫅'),
+ ('🫗', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
+ ('𪛞', '𪛟'),
+ ('𫜵', '𫜸'),
];
pub const V1_1: &'static [(char, char)] = &[
- ('\u{0}', 'ǵ'),
+ ('\0', 'ǵ'),
('Ǻ', 'ȗ'),
('É', 'ʨ'),
('Ê°', 'Ëž'),
diff --git a/vendor/regex-syntax/src/unicode_tables/case_folding_simple.rs b/vendor/regex-syntax/src/unicode_tables/case_folding_simple.rs
index cfb83f363..766d21b48 100644
--- a/vendor/regex-syntax/src/unicode_tables/case_folding_simple.rs
+++ b/vendor/regex-syntax/src/unicode_tables/case_folding_simple.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate case-folding-simple ucd-13.0.0 --chars --all-pairs
+// ucd-generate case-folding-simple /tmp/ucd --chars --all-pairs
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const CASE_FOLDING_SIMPLE: &'static [(char, &'static [char])] = &[
('A', &['a']),
@@ -1781,6 +1781,7 @@ pub const CASE_FOLDING_SIMPLE: &'static [(char, &'static [char])] = &[
('Ⱜ', &['ⱜ']),
('â°­', &['â±']),
('Ⱞ', &['ⱞ']),
+ ('Ⱟ', &['ⱟ']),
('â°°', &['â°€']),
('â°±', &['â°']),
('â°²', &['â°‚']),
@@ -1828,6 +1829,7 @@ pub const CASE_FOLDING_SIMPLE: &'static [(char, &'static [char])] = &[
('ⱜ', &['Ⱜ']),
('â±', &['â°­']),
('ⱞ', &['Ⱞ']),
+ ('ⱟ', &['Ⱟ']),
('Ⱡ', &['ⱡ']),
('ⱡ', &['Ⱡ']),
('â±¢', &['É«']),
@@ -2211,17 +2213,25 @@ pub const CASE_FOLDING_SIMPLE: &'static [(char, &'static [char])] = &[
('êž½', &['êž¼']),
('êž¾', &['êž¿']),
('êž¿', &['êž¾']),
+ ('Ꟁ', &['êŸ']),
+ ('êŸ', &['Ꟁ']),
('Ꟃ', &['ꟃ']),
('ꟃ', &['Ꟃ']),
('Ꞔ', &['ꞔ']),
('Ʂ', &['ʂ']),
('Ᶎ', &['ᶎ']),
- ('\u{a7c7}', &['\u{a7c8}']),
- ('\u{a7c8}', &['\u{a7c7}']),
- ('\u{a7c9}', &['\u{a7ca}']),
- ('\u{a7ca}', &['\u{a7c9}']),
- ('\u{a7f5}', &['\u{a7f6}']),
- ('\u{a7f6}', &['\u{a7f5}']),
+ ('Ꟈ', &['ꟈ']),
+ ('ꟈ', &['Ꟈ']),
+ ('Ꟊ', &['ꟊ']),
+ ('ꟊ', &['Ꟊ']),
+ ('êŸ', &['ꟑ']),
+ ('ꟑ', &['êŸ']),
+ ('Ꟗ', &['ꟗ']),
+ ('ꟗ', &['Ꟗ']),
+ ('Ꟙ', &['ꟙ']),
+ ('ꟙ', &['Ꟙ']),
+ ('Ꟶ', &['ꟶ']),
+ ('ꟶ', &['Ꟶ']),
('ê­“', &['êž³']),
('ꭰ', &['Ꭰ']),
('ꭱ', &['Ꭱ']),
@@ -2507,6 +2517,76 @@ pub const CASE_FOLDING_SIMPLE: &'static [(char, &'static [char])] = &[
('ð“¹', &['ð“‘']),
('ð“º', &['ð“’']),
('ð“»', &['ð““']),
+ ('ð•°', &['ð–—']),
+ ('ð•±', &['ð–˜']),
+ ('ð•²', &['ð–™']),
+ ('ð•³', &['ð–š']),
+ ('ð•´', &['ð–›']),
+ ('ð•µ', &['ð–œ']),
+ ('ð•¶', &['ð–']),
+ ('ð•·', &['ð–ž']),
+ ('ð•¸', &['ð–Ÿ']),
+ ('ð•¹', &['ð– ']),
+ ('ð•º', &['ð–¡']),
+ ('ð•¼', &['ð–£']),
+ ('ð•½', &['ð–¤']),
+ ('ð•¾', &['ð–¥']),
+ ('ð•¿', &['ð–¦']),
+ ('ð–€', &['ð–§']),
+ ('ð–', &['ð–¨']),
+ ('ð–‚', &['ð–©']),
+ ('ð–ƒ', &['ð–ª']),
+ ('ð–„', &['ð–«']),
+ ('ð–…', &['ð–¬']),
+ ('ð–†', &['ð–­']),
+ ('ð–‡', &['ð–®']),
+ ('ð–ˆ', &['ð–¯']),
+ ('ð–‰', &['ð–°']),
+ ('ð–Š', &['ð–±']),
+ ('ð–Œ', &['ð–³']),
+ ('ð–', &['ð–´']),
+ ('ð–Ž', &['ð–µ']),
+ ('ð–', &['ð–¶']),
+ ('ð–', &['ð–·']),
+ ('ð–‘', &['ð–¸']),
+ ('ð–’', &['ð–¹']),
+ ('ð–”', &['ð–»']),
+ ('ð–•', &['ð–¼']),
+ ('ð–—', &['ð•°']),
+ ('ð–˜', &['ð•±']),
+ ('ð–™', &['ð•²']),
+ ('ð–š', &['ð•³']),
+ ('ð–›', &['ð•´']),
+ ('ð–œ', &['ð•µ']),
+ ('ð–', &['ð•¶']),
+ ('ð–ž', &['ð•·']),
+ ('ð–Ÿ', &['ð•¸']),
+ ('ð– ', &['ð•¹']),
+ ('ð–¡', &['ð•º']),
+ ('ð–£', &['ð•¼']),
+ ('ð–¤', &['ð•½']),
+ ('ð–¥', &['ð•¾']),
+ ('ð–¦', &['ð•¿']),
+ ('ð–§', &['ð–€']),
+ ('ð–¨', &['ð–']),
+ ('ð–©', &['ð–‚']),
+ ('ð–ª', &['ð–ƒ']),
+ ('ð–«', &['ð–„']),
+ ('ð–¬', &['ð–…']),
+ ('ð–­', &['ð–†']),
+ ('ð–®', &['ð–‡']),
+ ('ð–¯', &['ð–ˆ']),
+ ('ð–°', &['ð–‰']),
+ ('ð–±', &['ð–Š']),
+ ('ð–³', &['ð–Œ']),
+ ('ð–´', &['ð–']),
+ ('ð–µ', &['ð–Ž']),
+ ('ð–¶', &['ð–']),
+ ('ð–·', &['ð–']),
+ ('ð–¸', &['ð–‘']),
+ ('ð–¹', &['ð–’']),
+ ('ð–»', &['ð–”']),
+ ('ð–¼', &['ð–•']),
('ð²€', &['ð³€']),
('ð²', &['ð³']),
('ð²‚', &['ð³‚']),
diff --git a/vendor/regex-syntax/src/unicode_tables/general_category.rs b/vendor/regex-syntax/src/unicode_tables/general_category.rs
index 33b7b7e6e..8aa6b0078 100644
--- a/vendor/regex-syntax/src/unicode_tables/general_category.rs
+++ b/vendor/regex-syntax/src/unicode_tables/general_category.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate general-category ucd-13.0.0 --chars --exclude surrogate
+// ucd-generate general-category /tmp/ucd --chars --exclude surrogate
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Cased_Letter", CASED_LETTER),
@@ -116,9 +116,7 @@ pub const CASED_LETTER: &'static [(char, char)] = &[
('â……', 'â…‰'),
('â…Ž', 'â…Ž'),
('Ↄ', 'ↄ'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('â± ', 'â±»'),
+ ('â°€', 'â±»'),
('Ȿ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
@@ -130,12 +128,14 @@ pub const CASED_LETTER: &'static [(char, char)] = &[
('Ꜣ', 'ê¯'),
('ê±', 'ꞇ'),
('Ꞌ', 'ꞎ'),
- ('êž', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', '\u{a7f6}'),
+ ('êž', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('Ꟶ', 'ꟶ'),
('ꟺ', 'ꟺ'),
('ꬰ', 'ꭚ'),
- ('ê­ ', '\u{ab68}'),
+ ('ê­ ', 'ê­¨'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
('ﬓ', 'ﬗ'),
@@ -144,6 +144,14 @@ pub const CASED_LETTER: &'static [(char, char)] = &[
('ð€', 'ð‘'),
('ð’°', 'ð““'),
('ð“˜', 'ð“»'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('𑢠', '𑣟'),
@@ -178,6 +186,8 @@ pub const CASED_LETTER: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼‰'),
+ ('ð¼‹', 'ð¼ž'),
('𞤀', '𞥃'),
];
@@ -225,6 +235,10 @@ pub const CLOSE_PUNCTUATION: &'static [(char, char)] = &[
('⸥', '⸥'),
('⸧', '⸧'),
('⸩', '⸩'),
+ ('â¹–', 'â¹–'),
+ ('⹘', '⹘'),
+ ('⹚', '⹚'),
+ ('⹜', '⹜'),
('〉', '〉'),
('》', '》'),
('ã€', 'ã€'),
@@ -266,7 +280,7 @@ pub const CONNECTOR_PUNCTUATION: &'static [(char, char)] = &[
];
pub const CONTROL: &'static [(char, char)] =
- &[('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}')];
+ &[('\0', '\u{1f}'), ('\u{7f}', '\u{9f}')];
pub const CURRENCY_SYMBOL: &'static [(char, char)] = &[
('$', '$'),
@@ -280,7 +294,7 @@ pub const CURRENCY_SYMBOL: &'static [(char, char)] = &[
('௹', '௹'),
('฿', '฿'),
('៛', '៛'),
- ('â‚ ', 'â‚¿'),
+ ('₠', '⃀'),
('ê ¸', 'ê ¸'),
('ï·¼', 'ï·¼'),
('﹩', '﹩'),
@@ -303,6 +317,7 @@ pub const DASH_PUNCTUATION: &'static [(char, char)] = &[
('⸚', '⸚'),
('⸺', '⸻'),
('â¹€', 'â¹€'),
+ ('â¹', 'â¹'),
('〜', '〜'),
('〰', '〰'),
('ã‚ ', 'ã‚ '),
@@ -310,7 +325,7 @@ pub const DASH_PUNCTUATION: &'static [(char, char)] = &[
('﹘', '﹘'),
('ï¹£', 'ï¹£'),
('ï¼', 'ï¼'),
- ('\u{10ead}', '\u{10ead}'),
+ ('ðº­', 'ðº­'),
];
pub const DECIMAL_NUMBER: &'static [(char, char)] = &[
@@ -364,17 +379,18 @@ pub const DECIMAL_NUMBER: &'static [(char, char)] = &[
('𑛀', '𑛉'),
('𑜰', '𑜹'),
('𑣠', '𑣩'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('ð‘±', '𑱙'),
('ð‘µ', '𑵙'),
('𑶠', '𑶩'),
('ð–© ', 'ð–©©'),
+ ('𖫀', '𖫉'),
('ð–­', 'ð–­™'),
('ðŸŽ', 'ðŸ¿'),
('ðž…€', 'ðž…‰'),
('𞋰', '𞋹'),
('ðž¥', '𞥙'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🯰', '🯹'),
];
pub const ENCLOSING_MARK: &'static [(char, char)] = &[
@@ -404,6 +420,7 @@ pub const FORMAT: &'static [(char, char)] = &[
('\u{61c}', '\u{61c}'),
('\u{6dd}', '\u{6dd}'),
('\u{70f}', '\u{70f}'),
+ ('\u{890}', '\u{891}'),
('\u{8e2}', '\u{8e2}'),
('\u{180e}', '\u{180e}'),
('\u{200b}', '\u{200f}'),
@@ -485,8 +502,9 @@ pub const LETTER: &'static [(char, char)] = &[
('à ¨', 'à ¨'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('ऄ', 'ह'),
('ऽ', 'ऽ'),
('à¥', 'à¥'),
@@ -551,6 +569,7 @@ pub const LETTER: &'static [(char, char)] = &[
('à°ª', 'à°¹'),
('à°½', 'à°½'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('ಀ', 'ಀ'),
('ಅ', 'ಌ'),
@@ -559,10 +578,10 @@ pub const LETTER: &'static [(char, char)] = &[
('ಪ', 'ಳ'),
('ವ', 'ಹ'),
('ಽ', 'ಽ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('à³±', 'à³²'),
- ('\u{d04}', 'ഌ'),
+ ('ഄ', 'ഌ'),
('à´Ž', 'à´'),
('à´’', 'à´º'),
('à´½', 'à´½'),
@@ -630,9 +649,8 @@ pub const LETTER: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛱ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
+ ('ᜀ', 'ᜑ'),
+ ('ᜟ', 'ᜱ'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -653,7 +671,7 @@ pub const LETTER: &'static [(char, char)] = &[
('ᨠ', 'ᩔ'),
('ᪧ', 'ᪧ'),
('ᬅ', 'ᬳ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('ᮃ', 'ᮠ'),
('ᮮ', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -704,9 +722,7 @@ pub const LETTER: &'static [(char, char)] = &[
('â……', 'â…‰'),
('â…Ž', 'â…Ž'),
('Ↄ', 'ↄ'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
('â´€', 'â´¥'),
@@ -733,11 +749,10 @@ pub const LETTER: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘟ'),
@@ -747,9 +762,11 @@ pub const LETTER: &'static [(char, char)] = &[
('ꚠ', 'ꛥ'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê '),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ê '),
('ê ƒ', 'ê …'),
('ê ‡', 'ê Š'),
('ꠌ', 'ꠢ'),
@@ -786,7 +803,7 @@ pub const LETTER: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯢ'),
('가', '힣'),
('ힰ', 'ퟆ'),
@@ -837,9 +854,20 @@ pub const LETTER: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -870,19 +898,22 @@ pub const LETTER: &'static [(char, char)] = &[
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('ð´€', 'ð´£'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('𑀃', '𑀷'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('𑂃', '𑂯'),
('ð‘ƒ', '𑃨'),
('𑄃', '𑄦'),
('ð‘…„', 'ð‘…„'),
- ('\u{11147}', '\u{11147}'),
+ ('ð‘…‡', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('𑆃', '𑆲'),
@@ -908,7 +939,7 @@ pub const LETTER: &'static [(char, char)] = &[
('ð‘', 'ð‘¡'),
('ð‘€', 'ð‘´'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -919,15 +950,16 @@ pub const LETTER: &'static [(char, char)] = &[
('𑚀', '𑚪'),
('𑚸', '𑚸'),
('𑜀', '𑜚'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', 'ð‘ «'),
('𑢠', '𑣟'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑦠', '𑦧'),
('𑦪', 'ð‘§'),
('𑧡', '𑧡'),
@@ -938,7 +970,7 @@ pub const LETTER: &'static [(char, char)] = &[
('ð‘©', 'ð‘©'),
('𑩜', '𑪉'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°®'),
('𑱀', '𑱀'),
@@ -952,13 +984,15 @@ pub const LETTER: &'static [(char, char)] = &[
('𑵪', '𑶉'),
('𑶘', '𑶘'),
('ð‘» ', 'ð‘»²'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­€', 'ð–­ƒ'),
@@ -971,9 +1005,12 @@ pub const LETTER: &'static [(char, char)] = &[
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', 'ð–¿£'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -1011,10 +1048,16 @@ pub const LETTER: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼ž'),
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞤀', '𞥃'),
('𞥋', '𞥋'),
@@ -1051,13 +1094,13 @@ pub const LETTER: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const LETTER_NUMBER: &'static [(char, char)] = &[
@@ -1510,7 +1553,7 @@ pub const LOWERCASE_LETTER: &'static [(char, char)] = &[
('â…†', 'â…‰'),
('â…Ž', 'â…Ž'),
('ↄ', 'ↄ'),
- ('ⰰ', 'ⱞ'),
+ ('ⰰ', 'ⱟ'),
('ⱡ', 'ⱡ'),
('ⱥ', 'ⱦ'),
('ⱨ', 'ⱨ'),
@@ -1679,19 +1722,29 @@ pub const LOWERCASE_LETTER: &'static [(char, char)] = &[
('êž»', 'êž»'),
('êž½', 'êž½'),
('êž¿', 'êž¿'),
+ ('êŸ', 'êŸ'),
('ꟃ', 'ꟃ'),
- ('\u{a7c8}', '\u{a7c8}'),
- ('\u{a7ca}', '\u{a7ca}'),
- ('\u{a7f6}', '\u{a7f6}'),
+ ('ꟈ', 'ꟈ'),
+ ('ꟊ', 'ꟊ'),
+ ('ꟑ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟕ'),
+ ('ꟗ', 'ꟗ'),
+ ('ꟙ', 'ꟙ'),
+ ('ꟶ', 'ꟶ'),
('ꟺ', 'ꟺ'),
('ꬰ', 'ꭚ'),
- ('ê­ ', '\u{ab68}'),
+ ('ê­ ', 'ê­¨'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
('ﬓ', 'ﬗ'),
('ï½', 'z'),
('ð¨', 'ð‘'),
('ð“˜', 'ð“»'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð³€', 'ð³²'),
('𑣀', '𑣟'),
('𖹠', '𖹿'),
@@ -1723,6 +1776,8 @@ pub const LOWERCASE_LETTER: &'static [(char, char)] = &[
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‰'),
('ðŸ‹', 'ðŸ‹'),
+ ('ð¼€', 'ð¼‰'),
+ ('ð¼‹', 'ð¼ž'),
('𞤢', '𞥃'),
];
@@ -1751,7 +1806,8 @@ pub const MARK: &'static [(char, char)] = &[
('\u{825}', '\u{827}'),
('\u{829}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('\u{898}', '\u{89f}'),
+ ('\u{8ca}', '\u{8e1}'),
('\u{8e3}', 'ः'),
('\u{93a}', '\u{93c}'),
('ा', 'à¥'),
@@ -1793,6 +1849,7 @@ pub const MARK: &'static [(char, char)] = &[
('ொ', '\u{bcd}'),
('\u{bd7}', '\u{bd7}'),
('\u{c00}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -1844,13 +1901,14 @@ pub const MARK: &'static [(char, char)] = &[
('á‚', 'á‚'),
('á‚š', '\u{109d}'),
('\u{135d}', '\u{135f}'),
- ('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1712}', '᜕'),
+ ('\u{1732}', '᜴'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
('\u{1920}', 'ᤫ'),
@@ -1859,7 +1917,7 @@ pub const MARK: &'static [(char, char)] = &[
('á©•', '\u{1a5e}'),
('\u{1a60}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1b00}', 'ᬄ'),
('\u{1b34}', 'á­„'),
('\u{1b6b}', '\u{1b73}'),
@@ -1872,8 +1930,7 @@ pub const MARK: &'static [(char, char)] = &[
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('á³·', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{20d0}', '\u{20f0}'),
('\u{2cef}', '\u{2cf1}'),
('\u{2d7f}', '\u{2d7f}'),
@@ -1926,10 +1983,14 @@ pub const MARK: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('𑀀', '𑀂'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', 'ð‘‚‚'),
('ð‘‚°', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{11134}'),
('ð‘……', 'ð‘…†'),
@@ -1937,7 +1998,7 @@ pub const MARK: &'static [(char, char)] = &[
('\u{11180}', '𑆂'),
('𑆳', '𑇀'),
('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '\u{111cf}'),
+ ('𑇎', '\u{111cf}'),
('𑈬', '\u{11237}'),
('\u{1123e}', '\u{1123e}'),
('\u{112df}', '\u{112ea}'),
@@ -1960,11 +2021,11 @@ pub const MARK: &'static [(char, char)] = &[
('\u{116ab}', '\u{116b7}'),
('\u{1171d}', '\u{1172b}'),
('ð‘ ¬', '\u{1183a}'),
- ('\u{11930}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('\u{11930}', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{1193e}'),
- ('\u{11940}', '\u{11940}'),
- ('\u{11942}', '\u{11943}'),
+ ('ð‘¥€', 'ð‘¥€'),
+ ('𑥂', '\u{11943}'),
('𑧑', '\u{119d7}'),
('\u{119da}', '\u{119e0}'),
('𑧤', '𑧤'),
@@ -1993,8 +2054,10 @@ pub const MARK: &'static [(char, char)] = &[
('𖽑', '𖾇'),
('\u{16f8f}', '\u{16f92}'),
('\u{16fe4}', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
@@ -2013,6 +2076,7 @@ pub const MARK: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e94a}'),
@@ -2102,6 +2166,7 @@ pub const MODIFIER_LETTER: &'static [(char, char)] = &[
('à š', 'à š'),
('à ¤', 'à ¤'),
('à ¨', 'à ¨'),
+ ('ࣉ', 'ࣉ'),
('ॱ', 'ॱ'),
('ๆ', 'ๆ'),
('ໆ', 'ໆ'),
@@ -2132,6 +2197,7 @@ pub const MODIFIER_LETTER: &'static [(char, char)] = &[
('ꜗ', 'ꜟ'),
('ê°', 'ê°'),
('ꞈ', 'ꞈ'),
+ ('ꟲ', 'ꟴ'),
('ꟸ', 'ꟹ'),
('ê§', 'ê§'),
('ꧦ', 'ꧦ'),
@@ -2139,13 +2205,19 @@ pub const MODIFIER_LETTER: &'static [(char, char)] = &[
('ê«', 'ê«'),
('ꫳ', 'ꫴ'),
('ꭜ', 'ꭟ'),
- ('\u{ab69}', '\u{ab69}'),
+ ('ê­©', 'ê­©'),
('ï½°', 'ï½°'),
('\u{ff9e}', '\u{ff9f}'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð–­€', 'ð–­ƒ'),
('𖾓', '𖾟'),
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', 'ð–¿£'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
('𞄷', '𞄽'),
('𞥋', '𞥋'),
];
@@ -2164,6 +2236,7 @@ pub const MODIFIER_SYMBOL: &'static [(char, char)] = &[
('˯', '˿'),
('͵', '͵'),
('΄', '΅'),
+ ('࢈', '࢈'),
('á¾½', 'á¾½'),
('᾿', 'á¿'),
('á¿', 'á¿'),
@@ -2175,8 +2248,8 @@ pub const MODIFIER_SYMBOL: &'static [(char, char)] = &[
('꜠', '꜡'),
('꞉', '꞊'),
('ê­›', 'ê­›'),
- ('\u{ab6a}', '\u{ab6b}'),
- ('﮲', 'ï¯'),
+ ('ê­ª', 'ê­«'),
+ ('﮲', '﯂'),
('ï¼¾', 'ï¼¾'),
('ï½€', 'ï½€'),
('ï¿£', 'ï¿£'),
@@ -2208,7 +2281,8 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{825}', '\u{827}'),
('\u{829}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('\u{898}', '\u{89f}'),
+ ('\u{8ca}', '\u{8e1}'),
('\u{8e3}', '\u{902}'),
('\u{93a}', '\u{93a}'),
('\u{93c}', '\u{93c}'),
@@ -2249,6 +2323,7 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{bcd}', '\u{bcd}'),
('\u{c00}', '\u{c00}'),
('\u{c04}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', '\u{c40}'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -2298,7 +2373,7 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{109d}', '\u{109d}'),
('\u{135d}', '\u{135f}'),
('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1732}', '\u{1733}'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17b5}'),
@@ -2307,6 +2382,7 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{17c9}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
('\u{1920}', '\u{1922}'),
@@ -2323,7 +2399,7 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{1a73}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
('\u{1ab0}', '\u{1abd}'),
- ('\u{1abf}', '\u{1ac0}'),
+ ('\u{1abf}', '\u{1ace}'),
('\u{1b00}', '\u{1b03}'),
('\u{1b34}', '\u{1b34}'),
('\u{1b36}', '\u{1b3a}'),
@@ -2346,8 +2422,7 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('\u{1cf8}', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{20d0}', '\u{20dc}'),
('\u{20e1}', '\u{20e1}'),
('\u{20e5}', '\u{20f0}'),
@@ -2406,11 +2481,15 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('\u{11001}', '\u{11001}'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', '\u{11081}'),
('\u{110b3}', '\u{110b6}'),
('\u{110b9}', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{1112b}'),
('\u{1112d}', '\u{11134}'),
@@ -2490,6 +2569,8 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{16f8f}', '\u{16f92}'),
('\u{16fe4}', '\u{16fe4}'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d167}', '\u{1d169}'),
('\u{1d17b}', '\u{1d182}'),
('\u{1d185}', '\u{1d18b}'),
@@ -2507,6 +2588,7 @@ pub const NONSPACING_MARK: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e94a}'),
@@ -2610,7 +2692,7 @@ pub const NUMBER: &'static [(char, char)] = &[
('ð¹ ', 'ð¹¾'),
('ð¼', 'ð¼¦'),
('ð½‘', 'ð½”'),
- ('\u{10fc5}', '\u{10fcb}'),
+ ('ð¿…', 'ð¿‹'),
('ð‘’', 'ð‘¯'),
('𑃰', '𑃹'),
('𑄶', '𑄿'),
@@ -2623,13 +2705,14 @@ pub const NUMBER: &'static [(char, char)] = &[
('𑛀', '𑛉'),
('𑜰', '𑜻'),
('ð‘£ ', 'ð‘£²'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('ð‘±', '𑱬'),
('ð‘µ', '𑵙'),
('𑶠', '𑶩'),
('ð‘¿€', 'ð‘¿”'),
('ð’€', 'ð’‘®'),
('ð–© ', 'ð–©©'),
+ ('𖫀', '𖫉'),
('ð–­', 'ð–­™'),
('ð–­›', 'ð–­¡'),
('𖺀', '𖺖'),
@@ -2646,7 +2729,7 @@ pub const NUMBER: &'static [(char, char)] = &[
('ðž´', 'ðž´­'),
('ðž´¯', 'ðž´½'),
('🄀', '🄌'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🯰', '🯹'),
];
pub const OPEN_PUNCTUATION: &'static [(char, char)] = &[
@@ -2696,6 +2779,10 @@ pub const OPEN_PUNCTUATION: &'static [(char, char)] = &[
('⸦', '⸦'),
('⸨', '⸨'),
('⹂', '⹂'),
+ ('⹕', '⹕'),
+ ('â¹—', 'â¹—'),
+ ('â¹™', 'â¹™'),
+ ('â¹›', 'â¹›'),
('〈', '〈'),
('《', '《'),
('「', '「'),
@@ -2728,7 +2815,7 @@ pub const OPEN_PUNCTUATION: &'static [(char, char)] = &[
];
pub const OTHER: &'static [(char, char)] = &[
- ('\u{0}', '\u{1f}'),
+ ('\0', '\u{1f}'),
('\u{7f}', '\u{9f}'),
('\u{ad}', '\u{ad}'),
('\u{378}', '\u{379}'),
@@ -2743,7 +2830,7 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{5c8}', '\u{5cf}'),
('\u{5eb}', '\u{5ee}'),
('\u{5f5}', '\u{605}'),
- ('\u{61c}', '\u{61d}'),
+ ('\u{61c}', '\u{61c}'),
('\u{6dd}', '\u{6dd}'),
('\u{70e}', '\u{70f}'),
('\u{74b}', '\u{74c}'),
@@ -2753,9 +2840,8 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{83f}', '\u{83f}'),
('\u{85c}', '\u{85d}'),
('\u{85f}', '\u{85f}'),
- ('\u{86b}', '\u{89f}'),
- ('\u{8b5}', '\u{8b5}'),
- ('\u{8c8}', '\u{8d2}'),
+ ('\u{86b}', '\u{86f}'),
+ ('\u{88f}', '\u{897}'),
('\u{8e2}', '\u{8e2}'),
('\u{984}', '\u{984}'),
('\u{98d}', '\u{98e}'),
@@ -2834,12 +2920,13 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{c0d}', '\u{c0d}'),
('\u{c11}', '\u{c11}'),
('\u{c29}', '\u{c29}'),
- ('\u{c3a}', '\u{c3c}'),
+ ('\u{c3a}', '\u{c3b}'),
('\u{c45}', '\u{c45}'),
('\u{c49}', '\u{c49}'),
('\u{c4e}', '\u{c54}'),
('\u{c57}', '\u{c57}'),
- ('\u{c5b}', '\u{c5f}'),
+ ('\u{c5b}', '\u{c5c}'),
+ ('\u{c5e}', '\u{c5f}'),
('\u{c64}', '\u{c65}'),
('\u{c70}', '\u{c76}'),
('\u{c8d}', '\u{c8d}'),
@@ -2850,7 +2937,7 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{cc5}', '\u{cc5}'),
('\u{cc9}', '\u{cc9}'),
('\u{cce}', '\u{cd4}'),
- ('\u{cd7}', '\u{cdd}'),
+ ('\u{cd7}', '\u{cdc}'),
('\u{cdf}', '\u{cdf}'),
('\u{ce4}', '\u{ce5}'),
('\u{cf0}', '\u{cf0}'),
@@ -2918,8 +3005,7 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{13fe}', '\u{13ff}'),
('\u{169d}', '\u{169f}'),
('\u{16f9}', '\u{16ff}'),
- ('\u{170d}', '\u{170d}'),
- ('\u{1715}', '\u{171f}'),
+ ('\u{1716}', '\u{171e}'),
('\u{1737}', '\u{173f}'),
('\u{1754}', '\u{175f}'),
('\u{176d}', '\u{176d}'),
@@ -2928,7 +3014,7 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{17de}', '\u{17df}'),
('\u{17ea}', '\u{17ef}'),
('\u{17fa}', '\u{17ff}'),
- ('\u{180e}', '\u{180f}'),
+ ('\u{180e}', '\u{180e}'),
('\u{181a}', '\u{181f}'),
('\u{1879}', '\u{187f}'),
('\u{18ab}', '\u{18af}'),
@@ -2948,9 +3034,9 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1a8a}', '\u{1a8f}'),
('\u{1a9a}', '\u{1a9f}'),
('\u{1aae}', '\u{1aaf}'),
- ('\u{1ac1}', '\u{1aff}'),
- ('\u{1b4c}', '\u{1b4f}'),
- ('\u{1b7d}', '\u{1b7f}'),
+ ('\u{1acf}', '\u{1aff}'),
+ ('\u{1b4d}', '\u{1b4f}'),
+ ('\u{1b7f}', '\u{1b7f}'),
('\u{1bf4}', '\u{1bfb}'),
('\u{1c38}', '\u{1c3a}'),
('\u{1c4a}', '\u{1c4c}'),
@@ -2958,7 +3044,6 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1cbb}', '\u{1cbc}'),
('\u{1cc8}', '\u{1ccf}'),
('\u{1cfb}', '\u{1cff}'),
- ('\u{1dfa}', '\u{1dfa}'),
('\u{1f16}', '\u{1f17}'),
('\u{1f1e}', '\u{1f1f}'),
('\u{1f46}', '\u{1f47}'),
@@ -2981,15 +3066,13 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{2072}', '\u{2073}'),
('\u{208f}', '\u{208f}'),
('\u{209d}', '\u{209f}'),
- ('\u{20c0}', '\u{20cf}'),
+ ('\u{20c1}', '\u{20cf}'),
('\u{20f1}', '\u{20ff}'),
('\u{218c}', '\u{218f}'),
('\u{2427}', '\u{243f}'),
('\u{244b}', '\u{245f}'),
('\u{2b74}', '\u{2b75}'),
('\u{2b96}', '\u{2b96}'),
- ('\u{2c2f}', '\u{2c2f}'),
- ('\u{2c5f}', '\u{2c5f}'),
('\u{2cf4}', '\u{2cf8}'),
('\u{2d26}', '\u{2d26}'),
('\u{2d28}', '\u{2d2c}'),
@@ -3005,7 +3088,7 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{2dcf}', '\u{2dcf}'),
('\u{2dd7}', '\u{2dd7}'),
('\u{2ddf}', '\u{2ddf}'),
- ('\u{2e53}', '\u{2e7f}'),
+ ('\u{2e5e}', '\u{2e7f}'),
('\u{2e9a}', '\u{2e9a}'),
('\u{2ef4}', '\u{2eff}'),
('\u{2fd6}', '\u{2fef}'),
@@ -3017,13 +3100,14 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{318f}', '\u{318f}'),
('\u{31e4}', '\u{31ef}'),
('\u{321f}', '\u{321f}'),
- ('\u{9ffd}', '\u{9fff}'),
('\u{a48d}', '\u{a48f}'),
('\u{a4c7}', '\u{a4cf}'),
('\u{a62c}', '\u{a63f}'),
('\u{a6f8}', '\u{a6ff}'),
- ('\u{a7c0}', '\u{a7c1}'),
- ('\u{a7cb}', '\u{a7f4}'),
+ ('\u{a7cb}', '\u{a7cf}'),
+ ('\u{a7d2}', '\u{a7d2}'),
+ ('\u{a7d4}', '\u{a7d4}'),
+ ('\u{a7da}', '\u{a7f1}'),
('\u{a82d}', '\u{a82f}'),
('\u{a83a}', '\u{a83f}'),
('\u{a878}', '\u{a87f}'),
@@ -3059,11 +3143,10 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{fb3f}', '\u{fb3f}'),
('\u{fb42}', '\u{fb42}'),
('\u{fb45}', '\u{fb45}'),
- ('\u{fbc2}', '\u{fbd2}'),
- ('\u{fd40}', '\u{fd4f}'),
+ ('\u{fbc3}', '\u{fbd2}'),
('\u{fd90}', '\u{fd91}'),
- ('\u{fdc8}', '\u{fdef}'),
- ('\u{fdfe}', '\u{fdff}'),
+ ('\u{fdc8}', '\u{fdce}'),
+ ('\u{fdd0}', '\u{fdef}'),
('\u{fe1a}', '\u{fe1f}'),
('\u{fe53}', '\u{fe53}'),
('\u{fe67}', '\u{fe67}'),
@@ -3106,10 +3189,20 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{104fc}', '\u{104ff}'),
('\u{10528}', '\u{1052f}'),
('\u{10564}', '\u{1056e}'),
- ('\u{10570}', '\u{105ff}'),
+ ('\u{1057b}', '\u{1057b}'),
+ ('\u{1058b}', '\u{1058b}'),
+ ('\u{10593}', '\u{10593}'),
+ ('\u{10596}', '\u{10596}'),
+ ('\u{105a2}', '\u{105a2}'),
+ ('\u{105b2}', '\u{105b2}'),
+ ('\u{105ba}', '\u{105ba}'),
+ ('\u{105bd}', '\u{105ff}'),
('\u{10737}', '\u{1073f}'),
('\u{10756}', '\u{1075f}'),
- ('\u{10768}', '\u{107ff}'),
+ ('\u{10768}', '\u{1077f}'),
+ ('\u{10786}', '\u{10786}'),
+ ('\u{107b1}', '\u{107b1}'),
+ ('\u{107bb}', '\u{107ff}'),
('\u{10806}', '\u{10807}'),
('\u{10809}', '\u{10809}'),
('\u{10836}', '\u{10836}'),
@@ -3152,13 +3245,14 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{10eae}', '\u{10eaf}'),
('\u{10eb2}', '\u{10eff}'),
('\u{10f28}', '\u{10f2f}'),
- ('\u{10f5a}', '\u{10faf}'),
+ ('\u{10f5a}', '\u{10f6f}'),
+ ('\u{10f8a}', '\u{10faf}'),
('\u{10fcc}', '\u{10fdf}'),
('\u{10ff7}', '\u{10fff}'),
('\u{1104e}', '\u{11051}'),
- ('\u{11070}', '\u{1107e}'),
+ ('\u{11076}', '\u{1107e}'),
('\u{110bd}', '\u{110bd}'),
- ('\u{110c2}', '\u{110cf}'),
+ ('\u{110c3}', '\u{110cf}'),
('\u{110e9}', '\u{110ef}'),
('\u{110fa}', '\u{110ff}'),
('\u{11135}', '\u{11135}'),
@@ -3199,11 +3293,11 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{11645}', '\u{1164f}'),
('\u{1165a}', '\u{1165f}'),
('\u{1166d}', '\u{1167f}'),
- ('\u{116b9}', '\u{116bf}'),
+ ('\u{116ba}', '\u{116bf}'),
('\u{116ca}', '\u{116ff}'),
('\u{1171b}', '\u{1171c}'),
('\u{1172c}', '\u{1172f}'),
- ('\u{11740}', '\u{117ff}'),
+ ('\u{11747}', '\u{117ff}'),
('\u{1183c}', '\u{1189f}'),
('\u{118f3}', '\u{118fe}'),
('\u{11907}', '\u{11908}'),
@@ -3218,7 +3312,7 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{119d8}', '\u{119d9}'),
('\u{119e5}', '\u{119ff}'),
('\u{11a48}', '\u{11a4f}'),
- ('\u{11aa3}', '\u{11abf}'),
+ ('\u{11aa3}', '\u{11aaf}'),
('\u{11af9}', '\u{11bff}'),
('\u{11c09}', '\u{11c09}'),
('\u{11c37}', '\u{11c37}'),
@@ -3246,13 +3340,15 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1239a}', '\u{123ff}'),
('\u{1246f}', '\u{1246f}'),
('\u{12475}', '\u{1247f}'),
- ('\u{12544}', '\u{12fff}'),
+ ('\u{12544}', '\u{12f8f}'),
+ ('\u{12ff3}', '\u{12fff}'),
('\u{1342f}', '\u{143ff}'),
('\u{14647}', '\u{167ff}'),
('\u{16a39}', '\u{16a3f}'),
('\u{16a5f}', '\u{16a5f}'),
('\u{16a6a}', '\u{16a6d}'),
- ('\u{16a70}', '\u{16acf}'),
+ ('\u{16abf}', '\u{16abf}'),
+ ('\u{16aca}', '\u{16acf}'),
('\u{16aee}', '\u{16aef}'),
('\u{16af6}', '\u{16aff}'),
('\u{16b46}', '\u{16b4f}'),
@@ -3268,8 +3364,11 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{16ff2}', '\u{16fff}'),
('\u{187f8}', '\u{187ff}'),
('\u{18cd6}', '\u{18cff}'),
- ('\u{18d09}', '\u{1afff}'),
- ('\u{1b11f}', '\u{1b14f}'),
+ ('\u{18d09}', '\u{1afef}'),
+ ('\u{1aff4}', '\u{1aff4}'),
+ ('\u{1affc}', '\u{1affc}'),
+ ('\u{1afff}', '\u{1afff}'),
+ ('\u{1b123}', '\u{1b14f}'),
('\u{1b153}', '\u{1b163}'),
('\u{1b168}', '\u{1b16f}'),
('\u{1b2fc}', '\u{1bbff}'),
@@ -3277,11 +3376,14 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1bc7d}', '\u{1bc7f}'),
('\u{1bc89}', '\u{1bc8f}'),
('\u{1bc9a}', '\u{1bc9b}'),
- ('\u{1bca0}', '\u{1cfff}'),
+ ('\u{1bca0}', '\u{1ceff}'),
+ ('\u{1cf2e}', '\u{1cf2f}'),
+ ('\u{1cf47}', '\u{1cf4f}'),
+ ('\u{1cfc4}', '\u{1cfff}'),
('\u{1d0f6}', '\u{1d0ff}'),
('\u{1d127}', '\u{1d128}'),
('\u{1d173}', '\u{1d17a}'),
- ('\u{1d1e9}', '\u{1d1ff}'),
+ ('\u{1d1eb}', '\u{1d1ff}'),
('\u{1d246}', '\u{1d2df}'),
('\u{1d2f4}', '\u{1d2ff}'),
('\u{1d357}', '\u{1d35f}'),
@@ -3308,7 +3410,8 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1d7cc}', '\u{1d7cd}'),
('\u{1da8c}', '\u{1da9a}'),
('\u{1daa0}', '\u{1daa0}'),
- ('\u{1dab0}', '\u{1dfff}'),
+ ('\u{1dab0}', '\u{1deff}'),
+ ('\u{1df1f}', '\u{1dfff}'),
('\u{1e007}', '\u{1e007}'),
('\u{1e019}', '\u{1e01a}'),
('\u{1e022}', '\u{1e022}'),
@@ -3317,9 +3420,14 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1e12d}', '\u{1e12f}'),
('\u{1e13e}', '\u{1e13f}'),
('\u{1e14a}', '\u{1e14d}'),
- ('\u{1e150}', '\u{1e2bf}'),
+ ('\u{1e150}', '\u{1e28f}'),
+ ('\u{1e2af}', '\u{1e2bf}'),
('\u{1e2fa}', '\u{1e2fe}'),
- ('\u{1e300}', '\u{1e7ff}'),
+ ('\u{1e300}', '\u{1e7df}'),
+ ('\u{1e7e7}', '\u{1e7e7}'),
+ ('\u{1e7ec}', '\u{1e7ec}'),
+ ('\u{1e7ef}', '\u{1e7ef}'),
+ ('\u{1e7ff}', '\u{1e7ff}'),
('\u{1e8c5}', '\u{1e8c6}'),
('\u{1e8d7}', '\u{1e8ff}'),
('\u{1e94c}', '\u{1e94f}'),
@@ -3373,34 +3481,35 @@ pub const OTHER: &'static [(char, char)] = &[
('\u{1f249}', '\u{1f24f}'),
('\u{1f252}', '\u{1f25f}'),
('\u{1f266}', '\u{1f2ff}'),
- ('\u{1f6d8}', '\u{1f6df}'),
+ ('\u{1f6d8}', '\u{1f6dc}'),
('\u{1f6ed}', '\u{1f6ef}'),
('\u{1f6fd}', '\u{1f6ff}'),
('\u{1f774}', '\u{1f77f}'),
('\u{1f7d9}', '\u{1f7df}'),
- ('\u{1f7ec}', '\u{1f7ff}'),
+ ('\u{1f7ec}', '\u{1f7ef}'),
+ ('\u{1f7f1}', '\u{1f7ff}'),
('\u{1f80c}', '\u{1f80f}'),
('\u{1f848}', '\u{1f84f}'),
('\u{1f85a}', '\u{1f85f}'),
('\u{1f888}', '\u{1f88f}'),
('\u{1f8ae}', '\u{1f8af}'),
('\u{1f8b2}', '\u{1f8ff}'),
- ('\u{1f979}', '\u{1f979}'),
- ('\u{1f9cc}', '\u{1f9cc}'),
('\u{1fa54}', '\u{1fa5f}'),
('\u{1fa6e}', '\u{1fa6f}'),
('\u{1fa75}', '\u{1fa77}'),
- ('\u{1fa7b}', '\u{1fa7f}'),
+ ('\u{1fa7d}', '\u{1fa7f}'),
('\u{1fa87}', '\u{1fa8f}'),
- ('\u{1faa9}', '\u{1faaf}'),
- ('\u{1fab7}', '\u{1fabf}'),
- ('\u{1fac3}', '\u{1facf}'),
- ('\u{1fad7}', '\u{1faff}'),
+ ('\u{1faad}', '\u{1faaf}'),
+ ('\u{1fabb}', '\u{1fabf}'),
+ ('\u{1fac6}', '\u{1facf}'),
+ ('\u{1fada}', '\u{1fadf}'),
+ ('\u{1fae8}', '\u{1faef}'),
+ ('\u{1faf7}', '\u{1faff}'),
('\u{1fb93}', '\u{1fb93}'),
('\u{1fbcb}', '\u{1fbef}'),
('\u{1fbfa}', '\u{1ffff}'),
- ('\u{2a6de}', '\u{2a6ff}'),
- ('\u{2b735}', '\u{2b73f}'),
+ ('\u{2a6e0}', '\u{2a6ff}'),
+ ('\u{2b739}', '\u{2b73f}'),
('\u{2b81e}', '\u{2b81f}'),
('\u{2cea2}', '\u{2ceaf}'),
('\u{2ebe1}', '\u{2f7ff}'),
@@ -3433,8 +3542,9 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('à €', 'à •'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣈ'),
('ऄ', 'ह'),
('ऽ', 'ऽ'),
('à¥', 'à¥'),
@@ -3499,6 +3609,7 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('à°ª', 'à°¹'),
('à°½', 'à°½'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('ಀ', 'ಀ'),
('ಅ', 'ಌ'),
@@ -3507,10 +3618,10 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ಪ', 'ಳ'),
('ವ', 'ಹ'),
('ಽ', 'ಽ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('à³±', 'à³²'),
- ('\u{d04}', 'ഌ'),
+ ('ഄ', 'ഌ'),
('à´Ž', 'à´'),
('à´’', 'à´º'),
('à´½', 'à´½'),
@@ -3571,9 +3682,8 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛱ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
+ ('ᜀ', 'ᜑ'),
+ ('ᜟ', 'ᜱ'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -3593,7 +3703,7 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ᨀ', 'ᨖ'),
('ᨠ', 'ᩔ'),
('ᬅ', 'ᬳ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('ᮃ', 'ᮠ'),
('ᮮ', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -3623,11 +3733,10 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ヿ', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꀔ'),
+ ('ã€', '䶿'),
+ ('一', 'ꀔ'),
('ꀖ', 'ꒌ'),
('ê“', 'ê“·'),
('ꔀ', 'ꘋ'),
@@ -3750,19 +3859,22 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ð®€', 'ð®‘'),
('ð°€', 'ð±ˆ'),
('ð´€', 'ð´£'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('𑀃', '𑀷'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('𑂃', '𑂯'),
('ð‘ƒ', '𑃨'),
('𑄃', '𑄦'),
('ð‘…„', 'ð‘…„'),
- ('\u{11147}', '\u{11147}'),
+ ('ð‘…‡', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('𑆃', '𑆲'),
@@ -3788,7 +3900,7 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ð‘', 'ð‘¡'),
('ð‘€', 'ð‘´'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -3799,14 +3911,15 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('𑚀', '𑚪'),
('𑚸', '𑚸'),
('𑜀', '𑜚'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', 'ð‘ «'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑦠', '𑦧'),
('𑦪', 'ð‘§'),
('𑧡', '𑧡'),
@@ -3817,7 +3930,7 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ð‘©', 'ð‘©'),
('𑩜', '𑪉'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°®'),
('𑱀', '𑱀'),
@@ -3831,13 +3944,15 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('𑵪', '𑶉'),
('𑶘', '𑶘'),
('ð‘» ', 'ð‘»²'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­£', 'ð–­·'),
@@ -3845,9 +3960,9 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('𖼀', '𖽊'),
('ð–½', 'ð–½'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -3855,9 +3970,15 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('ð›±°', 'ð›±¼'),
('𛲀', '𛲈'),
('ð›²', '𛲙'),
+ ('ð¼Š', 'ð¼Š'),
('𞄀', '𞄬'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞸀', '𞸃'),
('𞸅', '𞸟'),
@@ -3892,13 +4013,13 @@ pub const OTHER_LETTER: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const OTHER_NUMBER: &'static [(char, char)] = &[
@@ -3955,7 +4076,7 @@ pub const OTHER_NUMBER: &'static [(char, char)] = &[
('ð¹ ', 'ð¹¾'),
('ð¼', 'ð¼¦'),
('ð½‘', 'ð½”'),
- ('\u{10fc5}', '\u{10fcb}'),
+ ('ð¿…', 'ð¿‹'),
('ð‘’', 'ð‘¥'),
('𑇡', '𑇴'),
('𑜺', '𑜻'),
@@ -3999,7 +4120,7 @@ pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
('؉', '؊'),
('ØŒ', 'Ø'),
('Ø›', 'Ø›'),
- ('Øž', 'ØŸ'),
+ ('Ø', 'ØŸ'),
('Ùª', 'Ù­'),
('Û”', 'Û”'),
('Ü€', 'Ü'),
@@ -4036,6 +4157,7 @@ pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
('᪠', '᪦'),
('᪨', '᪭'),
('á­š', 'á­ '),
+ ('á­½', 'á­¾'),
('᯼', '᯿'),
('á°»', 'á°¿'),
('᱾', '᱿'),
@@ -4064,7 +4186,7 @@ pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
('⸼', '⸿'),
('â¹', 'â¹'),
('⹃', 'â¹'),
- ('\u{2e52}', '\u{2e52}'),
+ ('â¹’', 'â¹”'),
('ã€', '〃'),
('〽', '〽'),
('・', '・'),
@@ -4118,6 +4240,7 @@ pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
('ð¬¹', 'ð¬¿'),
('ð®™', 'ð®œ'),
('ð½•', 'ð½™'),
+ ('ð¾†', 'ð¾‰'),
('ð‘‡', 'ð‘'),
('ð‘‚»', 'ð‘‚¼'),
('ð‘‚¾', 'ð‘ƒ'),
@@ -4130,15 +4253,16 @@ pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
('𑈸', '𑈽'),
('ð‘Š©', 'ð‘Š©'),
('ð‘‘‹', 'ð‘‘'),
- ('\u{1145a}', 'ð‘‘›'),
+ ('ð‘‘š', 'ð‘‘›'),
('ð‘‘', 'ð‘‘'),
('𑓆', '𑓆'),
('ð‘—', 'ð‘——'),
('ð‘™', '𑙃'),
('𑙠', '𑙬'),
+ ('ð‘š¹', 'ð‘š¹'),
('𑜼', '𑜾'),
('ð‘ »', 'ð‘ »'),
- ('\u{11944}', '\u{11946}'),
+ ('𑥄', '𑥆'),
('𑧢', '𑧢'),
('𑨿', '𑩆'),
('𑪚', '𑪜'),
@@ -4148,6 +4272,7 @@ pub const OTHER_PUNCTUATION: &'static [(char, char)] = &[
('𑻷', '𑻸'),
('ð‘¿¿', 'ð‘¿¿'),
('ð’‘°', 'ð’‘´'),
+ ('ð’¿±', 'ð’¿²'),
('𖩮', '𖩯'),
('ð–«µ', 'ð–«µ'),
('𖬷', '𖬻'),
@@ -4240,9 +4365,9 @@ pub const OTHER_SYMBOL: &'static [(char, char)] = &[
('â­…', 'â­†'),
('â­', 'â­³'),
('⭶', '⮕'),
- ('\u{2b97}', '⯿'),
+ ('⮗', '⯿'),
('⳥', '⳪'),
- ('\u{2e50}', '\u{2e51}'),
+ ('â¹', '⹑'),
('⺀', '⺙'),
('⺛', '⻳'),
('â¼€', 'â¿•'),
@@ -4267,7 +4392,9 @@ pub const OTHER_SYMBOL: &'static [(char, char)] = &[
('ê ¶', 'ê ·'),
('ê ¹', 'ê ¹'),
('꩷', '꩹'),
- ('ï·½', 'ï·½'),
+ ('ïµ€', 'ïµ'),
+ ('ï·', 'ï·'),
+ ('ï·½', 'ï·¿'),
('¦', '¦'),
('│', '│'),
('ï¿­', 'ï¿®'),
@@ -4275,7 +4402,7 @@ pub const OTHER_SYMBOL: &'static [(char, char)] = &[
('ð„·', 'ð„¿'),
('ð…¹', 'ð†‰'),
('ð†Œ', 'ð†Ž'),
- ('ð†', '\u{1019c}'),
+ ('ð†', 'ð†œ'),
('ð† ', 'ð† '),
('ð‡', 'ð‡¼'),
('ð¡·', 'ð¡¸'),
@@ -4286,13 +4413,14 @@ pub const OTHER_SYMBOL: &'static [(char, char)] = &[
('𖬼', '𖬿'),
('ð–­…', 'ð–­…'),
('𛲜', '𛲜'),
+ ('ðœ½', '𜿃'),
('ð€€', 'ðƒµ'),
('ð„€', 'ð„¦'),
('ð„©', 'ð…¤'),
('ð…ª', 'ð…¬'),
('ð†ƒ', 'ð†„'),
('ð†Œ', 'ð†©'),
- ('ð†®', 'ð‡¨'),
+ ('ð†®', 'ð‡ª'),
('ðˆ€', 'ð‰'),
('ð‰…', 'ð‰…'),
('ðŒ€', 'ð–'),
@@ -4310,38 +4438,39 @@ pub const OTHER_SYMBOL: &'static [(char, char)] = &[
('🂱', '🂿'),
('ðŸƒ', 'ðŸƒ'),
('🃑', '🃵'),
- ('\u{1f10d}', '\u{1f1ad}'),
+ ('ðŸ„', '🆭'),
('🇦', '🈂'),
('ðŸˆ', '🈻'),
('🉀', '🉈'),
('ðŸ‰', '🉑'),
('🉠', '🉥'),
('🌀', 'ðŸº'),
- ('ðŸ€', '\u{1f6d7}'),
- ('🛠', '🛬'),
- ('🛰', '\u{1f6fc}'),
+ ('ðŸ€', '🛗'),
+ ('ðŸ›', '🛬'),
+ ('🛰', '🛼'),
('🜀', 'ðŸ³'),
('🞀', '🟘'),
('🟠', '🟫'),
+ ('🟰', '🟰'),
('🠀', '🠋'),
('ðŸ ', '🡇'),
('ðŸ¡', '🡙'),
('🡠', '🢇'),
('ðŸ¢', '🢭'),
- ('\u{1f8b0}', '\u{1f8b1}'),
- ('🤀', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🩓'),
+ ('🢰', '🢱'),
+ ('🤀', '🩓'),
('🩠', '🩭'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
- ('\u{1fb00}', '\u{1fb92}'),
- ('\u{1fb94}', '\u{1fbca}'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
+ ('🬀', '🮒'),
+ ('🮔', '🯊'),
];
pub const PARAGRAPH_SEPARATOR: &'static [(char, char)] =
@@ -4381,7 +4510,7 @@ pub const PUNCTUATION: &'static [(char, char)] = &[
('؉', '؊'),
('ØŒ', 'Ø'),
('Ø›', 'Ø›'),
- ('Øž', 'ØŸ'),
+ ('Ø', 'ØŸ'),
('Ùª', 'Ù­'),
('Û”', 'Û”'),
('Ü€', 'Ü'),
@@ -4420,6 +4549,7 @@ pub const PUNCTUATION: &'static [(char, char)] = &[
('᪠', '᪦'),
('᪨', '᪭'),
('á­š', 'á­ '),
+ ('á­½', 'á­¾'),
('᯼', '᯿'),
('á°»', 'á°¿'),
('᱾', '᱿'),
@@ -4444,7 +4574,7 @@ pub const PUNCTUATION: &'static [(char, char)] = &[
('âµ°', 'âµ°'),
('⸀', '⸮'),
('⸰', 'â¹'),
- ('\u{2e52}', '\u{2e52}'),
+ ('â¹’', 'â¹'),
('ã€', '〃'),
('〈', '】'),
('〔', '〟'),
@@ -4498,8 +4628,9 @@ pub const PUNCTUATION: &'static [(char, char)] = &[
('ð«°', 'ð«¶'),
('ð¬¹', 'ð¬¿'),
('ð®™', 'ð®œ'),
- ('\u{10ead}', '\u{10ead}'),
+ ('ðº­', 'ðº­'),
('ð½•', 'ð½™'),
+ ('ð¾†', 'ð¾‰'),
('ð‘‡', 'ð‘'),
('ð‘‚»', 'ð‘‚¼'),
('ð‘‚¾', 'ð‘ƒ'),
@@ -4512,15 +4643,16 @@ pub const PUNCTUATION: &'static [(char, char)] = &[
('𑈸', '𑈽'),
('ð‘Š©', 'ð‘Š©'),
('ð‘‘‹', 'ð‘‘'),
- ('\u{1145a}', 'ð‘‘›'),
+ ('ð‘‘š', 'ð‘‘›'),
('ð‘‘', 'ð‘‘'),
('𑓆', '𑓆'),
('ð‘—', 'ð‘——'),
('ð‘™', '𑙃'),
('𑙠', '𑙬'),
+ ('ð‘š¹', 'ð‘š¹'),
('𑜼', '𑜾'),
('ð‘ »', 'ð‘ »'),
- ('\u{11944}', '\u{11946}'),
+ ('𑥄', '𑥆'),
('𑧢', '𑧢'),
('𑨿', '𑩆'),
('𑪚', '𑪜'),
@@ -4530,6 +4662,7 @@ pub const PUNCTUATION: &'static [(char, char)] = &[
('𑻷', '𑻸'),
('ð‘¿¿', 'ð‘¿¿'),
('ð’‘°', 'ð’‘´'),
+ ('ð’¿±', 'ð’¿²'),
('𖩮', '𖩯'),
('ð–«µ', 'ð–«µ'),
('𖬷', '𖬻'),
@@ -4620,6 +4753,8 @@ pub const SPACING_MARK: &'static [(char, char)] = &[
('ႇ', 'ႌ'),
('á‚', 'á‚'),
('ႚ', 'ႜ'),
+ ('᜕', '᜕'),
+ ('᜴', '᜴'),
('ា', 'ា'),
('ើ', 'ៅ'),
('ះ', 'ៈ'),
@@ -4682,7 +4817,7 @@ pub const SPACING_MARK: &'static [(char, char)] = &[
('𑆂', '𑆂'),
('𑆳', '𑆵'),
('𑆿', '𑇀'),
- ('\u{111ce}', '\u{111ce}'),
+ ('𑇎', '𑇎'),
('𑈬', '𑈮'),
('𑈲', '𑈳'),
('𑈵', '𑈵'),
@@ -4714,11 +4849,11 @@ pub const SPACING_MARK: &'static [(char, char)] = &[
('𑜦', '𑜦'),
('ð‘ ¬', 'ð‘ ®'),
('ð‘ ¸', 'ð‘ ¸'),
- ('\u{11930}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
- ('\u{1193d}', '\u{1193d}'),
- ('\u{11940}', '\u{11940}'),
- ('\u{11942}', '\u{11942}'),
+ ('\u{11930}', '𑤵'),
+ ('𑤷', '𑤸'),
+ ('𑤽', '𑤽'),
+ ('ð‘¥€', 'ð‘¥€'),
+ ('𑥂', '𑥂'),
('𑧑', '𑧓'),
('𑧜', '𑧟'),
('𑧤', '𑧤'),
@@ -4735,7 +4870,7 @@ pub const SPACING_MARK: &'static [(char, char)] = &[
('𑶖', '𑶖'),
('𑻵', '𑻶'),
('𖽑', '𖾇'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('\u{1d165}', 'ð…¦'),
('ð…­', '\u{1d172}'),
];
@@ -4774,6 +4909,7 @@ pub const SYMBOL: &'static [(char, char)] = &[
('Û½', 'Û¾'),
('߶', '߶'),
('ß¾', 'ß¿'),
+ ('࢈', '࢈'),
('৲', '৳'),
('৺', '৻'),
('૱', '૱'),
@@ -4812,7 +4948,7 @@ pub const SYMBOL: &'static [(char, char)] = &[
('â’', 'â’'),
('âº', 'â¼'),
('₊', '₌'),
- ('â‚ ', 'â‚¿'),
+ ('₠', '⃀'),
('â„€', 'â„'),
('℃', '℆'),
('℈', '℉'),
@@ -4841,9 +4977,9 @@ pub const SYMBOL: &'static [(char, char)] = &[
('⧜', '⧻'),
('⧾', '⭳'),
('⭶', '⮕'),
- ('\u{2b97}', '⯿'),
+ ('⮗', '⯿'),
('⳥', '⳪'),
- ('\u{2e50}', '\u{2e51}'),
+ ('â¹', '⹑'),
('⺀', '⺙'),
('⺛', '⻳'),
('â¼€', 'â¿•'),
@@ -4872,10 +5008,12 @@ pub const SYMBOL: &'static [(char, char)] = &[
('ê ¶', 'ê ¹'),
('꩷', '꩹'),
('ê­›', 'ê­›'),
- ('\u{ab6a}', '\u{ab6b}'),
+ ('ê­ª', 'ê­«'),
('﬩', '﬩'),
- ('﮲', 'ï¯'),
- ('ï·¼', 'ï·½'),
+ ('﮲', '﯂'),
+ ('ïµ€', 'ïµ'),
+ ('ï·', 'ï·'),
+ ('ï·¼', 'ï·¿'),
('ï¹¢', 'ï¹¢'),
('﹤', '﹦'),
('﹩', '﹩'),
@@ -4892,7 +5030,7 @@ pub const SYMBOL: &'static [(char, char)] = &[
('ð„·', 'ð„¿'),
('ð…¹', 'ð†‰'),
('ð†Œ', 'ð†Ž'),
- ('ð†', '\u{1019c}'),
+ ('ð†', 'ð†œ'),
('ð† ', 'ð† '),
('ð‡', 'ð‡¼'),
('ð¡·', 'ð¡¸'),
@@ -4902,13 +5040,14 @@ pub const SYMBOL: &'static [(char, char)] = &[
('𖬼', '𖬿'),
('ð–­…', 'ð–­…'),
('𛲜', '𛲜'),
+ ('ðœ½', '𜿃'),
('ð€€', 'ðƒµ'),
('ð„€', 'ð„¦'),
('ð„©', 'ð…¤'),
('ð…ª', 'ð…¬'),
('ð†ƒ', 'ð†„'),
('ð†Œ', 'ð†©'),
- ('ð†®', 'ð‡¨'),
+ ('ð†®', 'ð‡ª'),
('ðˆ€', 'ð‰'),
('ð‰…', 'ð‰…'),
('ðŒ€', 'ð–'),
@@ -4939,37 +5078,38 @@ pub const SYMBOL: &'static [(char, char)] = &[
('🂱', '🂿'),
('ðŸƒ', 'ðŸƒ'),
('🃑', '🃵'),
- ('\u{1f10d}', '\u{1f1ad}'),
+ ('ðŸ„', '🆭'),
('🇦', '🈂'),
('ðŸˆ', '🈻'),
('🉀', '🉈'),
('ðŸ‰', '🉑'),
('🉠', '🉥'),
- ('🌀', '\u{1f6d7}'),
- ('🛠', '🛬'),
- ('🛰', '\u{1f6fc}'),
+ ('🌀', '🛗'),
+ ('ðŸ›', '🛬'),
+ ('🛰', '🛼'),
('🜀', 'ðŸ³'),
('🞀', '🟘'),
('🟠', '🟫'),
+ ('🟰', '🟰'),
('🠀', '🠋'),
('ðŸ ', '🡇'),
('ðŸ¡', '🡙'),
('🡠', '🢇'),
('ðŸ¢', '🢭'),
- ('\u{1f8b0}', '\u{1f8b1}'),
- ('🤀', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🩓'),
+ ('🢰', '🢱'),
+ ('🤀', '🩓'),
('🩠', '🩭'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
- ('\u{1fb00}', '\u{1fb92}'),
- ('\u{1fb94}', '\u{1fbca}'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
+ ('🬀', '🮒'),
+ ('🮔', '🯊'),
];
pub const TITLECASE_LETTER: &'static [(char, char)] = &[
@@ -4998,7 +5138,6 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{5c8}', '\u{5cf}'),
('\u{5eb}', '\u{5ee}'),
('\u{5f5}', '\u{5ff}'),
- ('\u{61d}', '\u{61d}'),
('\u{70e}', '\u{70e}'),
('\u{74b}', '\u{74c}'),
('\u{7b2}', '\u{7bf}'),
@@ -5007,9 +5146,9 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{83f}', '\u{83f}'),
('\u{85c}', '\u{85d}'),
('\u{85f}', '\u{85f}'),
- ('\u{86b}', '\u{89f}'),
- ('\u{8b5}', '\u{8b5}'),
- ('\u{8c8}', '\u{8d2}'),
+ ('\u{86b}', '\u{86f}'),
+ ('\u{88f}', '\u{88f}'),
+ ('\u{892}', '\u{897}'),
('\u{984}', '\u{984}'),
('\u{98d}', '\u{98e}'),
('\u{991}', '\u{992}'),
@@ -5087,12 +5226,13 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{c0d}', '\u{c0d}'),
('\u{c11}', '\u{c11}'),
('\u{c29}', '\u{c29}'),
- ('\u{c3a}', '\u{c3c}'),
+ ('\u{c3a}', '\u{c3b}'),
('\u{c45}', '\u{c45}'),
('\u{c49}', '\u{c49}'),
('\u{c4e}', '\u{c54}'),
('\u{c57}', '\u{c57}'),
- ('\u{c5b}', '\u{c5f}'),
+ ('\u{c5b}', '\u{c5c}'),
+ ('\u{c5e}', '\u{c5f}'),
('\u{c64}', '\u{c65}'),
('\u{c70}', '\u{c76}'),
('\u{c8d}', '\u{c8d}'),
@@ -5103,7 +5243,7 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{cc5}', '\u{cc5}'),
('\u{cc9}', '\u{cc9}'),
('\u{cce}', '\u{cd4}'),
- ('\u{cd7}', '\u{cdd}'),
+ ('\u{cd7}', '\u{cdc}'),
('\u{cdf}', '\u{cdf}'),
('\u{ce4}', '\u{ce5}'),
('\u{cf0}', '\u{cf0}'),
@@ -5171,8 +5311,7 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{13fe}', '\u{13ff}'),
('\u{169d}', '\u{169f}'),
('\u{16f9}', '\u{16ff}'),
- ('\u{170d}', '\u{170d}'),
- ('\u{1715}', '\u{171f}'),
+ ('\u{1716}', '\u{171e}'),
('\u{1737}', '\u{173f}'),
('\u{1754}', '\u{175f}'),
('\u{176d}', '\u{176d}'),
@@ -5181,7 +5320,6 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{17de}', '\u{17df}'),
('\u{17ea}', '\u{17ef}'),
('\u{17fa}', '\u{17ff}'),
- ('\u{180f}', '\u{180f}'),
('\u{181a}', '\u{181f}'),
('\u{1879}', '\u{187f}'),
('\u{18ab}', '\u{18af}'),
@@ -5201,9 +5339,9 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1a8a}', '\u{1a8f}'),
('\u{1a9a}', '\u{1a9f}'),
('\u{1aae}', '\u{1aaf}'),
- ('\u{1ac1}', '\u{1aff}'),
- ('\u{1b4c}', '\u{1b4f}'),
- ('\u{1b7d}', '\u{1b7f}'),
+ ('\u{1acf}', '\u{1aff}'),
+ ('\u{1b4d}', '\u{1b4f}'),
+ ('\u{1b7f}', '\u{1b7f}'),
('\u{1bf4}', '\u{1bfb}'),
('\u{1c38}', '\u{1c3a}'),
('\u{1c4a}', '\u{1c4c}'),
@@ -5211,7 +5349,6 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1cbb}', '\u{1cbc}'),
('\u{1cc8}', '\u{1ccf}'),
('\u{1cfb}', '\u{1cff}'),
- ('\u{1dfa}', '\u{1dfa}'),
('\u{1f16}', '\u{1f17}'),
('\u{1f1e}', '\u{1f1f}'),
('\u{1f46}', '\u{1f47}'),
@@ -5232,15 +5369,13 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{2072}', '\u{2073}'),
('\u{208f}', '\u{208f}'),
('\u{209d}', '\u{209f}'),
- ('\u{20c0}', '\u{20cf}'),
+ ('\u{20c1}', '\u{20cf}'),
('\u{20f1}', '\u{20ff}'),
('\u{218c}', '\u{218f}'),
('\u{2427}', '\u{243f}'),
('\u{244b}', '\u{245f}'),
('\u{2b74}', '\u{2b75}'),
('\u{2b96}', '\u{2b96}'),
- ('\u{2c2f}', '\u{2c2f}'),
- ('\u{2c5f}', '\u{2c5f}'),
('\u{2cf4}', '\u{2cf8}'),
('\u{2d26}', '\u{2d26}'),
('\u{2d28}', '\u{2d2c}'),
@@ -5256,7 +5391,7 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{2dcf}', '\u{2dcf}'),
('\u{2dd7}', '\u{2dd7}'),
('\u{2ddf}', '\u{2ddf}'),
- ('\u{2e53}', '\u{2e7f}'),
+ ('\u{2e5e}', '\u{2e7f}'),
('\u{2e9a}', '\u{2e9a}'),
('\u{2ef4}', '\u{2eff}'),
('\u{2fd6}', '\u{2fef}'),
@@ -5268,13 +5403,14 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{318f}', '\u{318f}'),
('\u{31e4}', '\u{31ef}'),
('\u{321f}', '\u{321f}'),
- ('\u{9ffd}', '\u{9fff}'),
('\u{a48d}', '\u{a48f}'),
('\u{a4c7}', '\u{a4cf}'),
('\u{a62c}', '\u{a63f}'),
('\u{a6f8}', '\u{a6ff}'),
- ('\u{a7c0}', '\u{a7c1}'),
- ('\u{a7cb}', '\u{a7f4}'),
+ ('\u{a7cb}', '\u{a7cf}'),
+ ('\u{a7d2}', '\u{a7d2}'),
+ ('\u{a7d4}', '\u{a7d4}'),
+ ('\u{a7da}', '\u{a7f1}'),
('\u{a82d}', '\u{a82f}'),
('\u{a83a}', '\u{a83f}'),
('\u{a878}', '\u{a87f}'),
@@ -5310,11 +5446,10 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{fb3f}', '\u{fb3f}'),
('\u{fb42}', '\u{fb42}'),
('\u{fb45}', '\u{fb45}'),
- ('\u{fbc2}', '\u{fbd2}'),
- ('\u{fd40}', '\u{fd4f}'),
+ ('\u{fbc3}', '\u{fbd2}'),
('\u{fd90}', '\u{fd91}'),
- ('\u{fdc8}', '\u{fdef}'),
- ('\u{fdfe}', '\u{fdff}'),
+ ('\u{fdc8}', '\u{fdce}'),
+ ('\u{fdd0}', '\u{fdef}'),
('\u{fe1a}', '\u{fe1f}'),
('\u{fe53}', '\u{fe53}'),
('\u{fe67}', '\u{fe67}'),
@@ -5358,10 +5493,20 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{104fc}', '\u{104ff}'),
('\u{10528}', '\u{1052f}'),
('\u{10564}', '\u{1056e}'),
- ('\u{10570}', '\u{105ff}'),
+ ('\u{1057b}', '\u{1057b}'),
+ ('\u{1058b}', '\u{1058b}'),
+ ('\u{10593}', '\u{10593}'),
+ ('\u{10596}', '\u{10596}'),
+ ('\u{105a2}', '\u{105a2}'),
+ ('\u{105b2}', '\u{105b2}'),
+ ('\u{105ba}', '\u{105ba}'),
+ ('\u{105bd}', '\u{105ff}'),
('\u{10737}', '\u{1073f}'),
('\u{10756}', '\u{1075f}'),
- ('\u{10768}', '\u{107ff}'),
+ ('\u{10768}', '\u{1077f}'),
+ ('\u{10786}', '\u{10786}'),
+ ('\u{107b1}', '\u{107b1}'),
+ ('\u{107bb}', '\u{107ff}'),
('\u{10806}', '\u{10807}'),
('\u{10809}', '\u{10809}'),
('\u{10836}', '\u{10836}'),
@@ -5404,12 +5549,13 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{10eae}', '\u{10eaf}'),
('\u{10eb2}', '\u{10eff}'),
('\u{10f28}', '\u{10f2f}'),
- ('\u{10f5a}', '\u{10faf}'),
+ ('\u{10f5a}', '\u{10f6f}'),
+ ('\u{10f8a}', '\u{10faf}'),
('\u{10fcc}', '\u{10fdf}'),
('\u{10ff7}', '\u{10fff}'),
('\u{1104e}', '\u{11051}'),
- ('\u{11070}', '\u{1107e}'),
- ('\u{110c2}', '\u{110cc}'),
+ ('\u{11076}', '\u{1107e}'),
+ ('\u{110c3}', '\u{110cc}'),
('\u{110ce}', '\u{110cf}'),
('\u{110e9}', '\u{110ef}'),
('\u{110fa}', '\u{110ff}'),
@@ -5451,11 +5597,11 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{11645}', '\u{1164f}'),
('\u{1165a}', '\u{1165f}'),
('\u{1166d}', '\u{1167f}'),
- ('\u{116b9}', '\u{116bf}'),
+ ('\u{116ba}', '\u{116bf}'),
('\u{116ca}', '\u{116ff}'),
('\u{1171b}', '\u{1171c}'),
('\u{1172c}', '\u{1172f}'),
- ('\u{11740}', '\u{117ff}'),
+ ('\u{11747}', '\u{117ff}'),
('\u{1183c}', '\u{1189f}'),
('\u{118f3}', '\u{118fe}'),
('\u{11907}', '\u{11908}'),
@@ -5470,7 +5616,7 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{119d8}', '\u{119d9}'),
('\u{119e5}', '\u{119ff}'),
('\u{11a48}', '\u{11a4f}'),
- ('\u{11aa3}', '\u{11abf}'),
+ ('\u{11aa3}', '\u{11aaf}'),
('\u{11af9}', '\u{11bff}'),
('\u{11c09}', '\u{11c09}'),
('\u{11c37}', '\u{11c37}'),
@@ -5498,14 +5644,16 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1239a}', '\u{123ff}'),
('\u{1246f}', '\u{1246f}'),
('\u{12475}', '\u{1247f}'),
- ('\u{12544}', '\u{12fff}'),
+ ('\u{12544}', '\u{12f8f}'),
+ ('\u{12ff3}', '\u{12fff}'),
('\u{1342f}', '\u{1342f}'),
('\u{13439}', '\u{143ff}'),
('\u{14647}', '\u{167ff}'),
('\u{16a39}', '\u{16a3f}'),
('\u{16a5f}', '\u{16a5f}'),
('\u{16a6a}', '\u{16a6d}'),
- ('\u{16a70}', '\u{16acf}'),
+ ('\u{16abf}', '\u{16abf}'),
+ ('\u{16aca}', '\u{16acf}'),
('\u{16aee}', '\u{16aef}'),
('\u{16af6}', '\u{16aff}'),
('\u{16b46}', '\u{16b4f}'),
@@ -5521,8 +5669,11 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{16ff2}', '\u{16fff}'),
('\u{187f8}', '\u{187ff}'),
('\u{18cd6}', '\u{18cff}'),
- ('\u{18d09}', '\u{1afff}'),
- ('\u{1b11f}', '\u{1b14f}'),
+ ('\u{18d09}', '\u{1afef}'),
+ ('\u{1aff4}', '\u{1aff4}'),
+ ('\u{1affc}', '\u{1affc}'),
+ ('\u{1afff}', '\u{1afff}'),
+ ('\u{1b123}', '\u{1b14f}'),
('\u{1b153}', '\u{1b163}'),
('\u{1b168}', '\u{1b16f}'),
('\u{1b2fc}', '\u{1bbff}'),
@@ -5530,10 +5681,13 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1bc7d}', '\u{1bc7f}'),
('\u{1bc89}', '\u{1bc8f}'),
('\u{1bc9a}', '\u{1bc9b}'),
- ('\u{1bca4}', '\u{1cfff}'),
+ ('\u{1bca4}', '\u{1ceff}'),
+ ('\u{1cf2e}', '\u{1cf2f}'),
+ ('\u{1cf47}', '\u{1cf4f}'),
+ ('\u{1cfc4}', '\u{1cfff}'),
('\u{1d0f6}', '\u{1d0ff}'),
('\u{1d127}', '\u{1d128}'),
- ('\u{1d1e9}', '\u{1d1ff}'),
+ ('\u{1d1eb}', '\u{1d1ff}'),
('\u{1d246}', '\u{1d2df}'),
('\u{1d2f4}', '\u{1d2ff}'),
('\u{1d357}', '\u{1d35f}'),
@@ -5560,7 +5714,8 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1d7cc}', '\u{1d7cd}'),
('\u{1da8c}', '\u{1da9a}'),
('\u{1daa0}', '\u{1daa0}'),
- ('\u{1dab0}', '\u{1dfff}'),
+ ('\u{1dab0}', '\u{1deff}'),
+ ('\u{1df1f}', '\u{1dfff}'),
('\u{1e007}', '\u{1e007}'),
('\u{1e019}', '\u{1e01a}'),
('\u{1e022}', '\u{1e022}'),
@@ -5569,9 +5724,14 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1e12d}', '\u{1e12f}'),
('\u{1e13e}', '\u{1e13f}'),
('\u{1e14a}', '\u{1e14d}'),
- ('\u{1e150}', '\u{1e2bf}'),
+ ('\u{1e150}', '\u{1e28f}'),
+ ('\u{1e2af}', '\u{1e2bf}'),
('\u{1e2fa}', '\u{1e2fe}'),
- ('\u{1e300}', '\u{1e7ff}'),
+ ('\u{1e300}', '\u{1e7df}'),
+ ('\u{1e7e7}', '\u{1e7e7}'),
+ ('\u{1e7ec}', '\u{1e7ec}'),
+ ('\u{1e7ef}', '\u{1e7ef}'),
+ ('\u{1e7ff}', '\u{1e7ff}'),
('\u{1e8c5}', '\u{1e8c6}'),
('\u{1e8d7}', '\u{1e8ff}'),
('\u{1e94c}', '\u{1e94f}'),
@@ -5625,34 +5785,35 @@ pub const UNASSIGNED: &'static [(char, char)] = &[
('\u{1f249}', '\u{1f24f}'),
('\u{1f252}', '\u{1f25f}'),
('\u{1f266}', '\u{1f2ff}'),
- ('\u{1f6d8}', '\u{1f6df}'),
+ ('\u{1f6d8}', '\u{1f6dc}'),
('\u{1f6ed}', '\u{1f6ef}'),
('\u{1f6fd}', '\u{1f6ff}'),
('\u{1f774}', '\u{1f77f}'),
('\u{1f7d9}', '\u{1f7df}'),
- ('\u{1f7ec}', '\u{1f7ff}'),
+ ('\u{1f7ec}', '\u{1f7ef}'),
+ ('\u{1f7f1}', '\u{1f7ff}'),
('\u{1f80c}', '\u{1f80f}'),
('\u{1f848}', '\u{1f84f}'),
('\u{1f85a}', '\u{1f85f}'),
('\u{1f888}', '\u{1f88f}'),
('\u{1f8ae}', '\u{1f8af}'),
('\u{1f8b2}', '\u{1f8ff}'),
- ('\u{1f979}', '\u{1f979}'),
- ('\u{1f9cc}', '\u{1f9cc}'),
('\u{1fa54}', '\u{1fa5f}'),
('\u{1fa6e}', '\u{1fa6f}'),
('\u{1fa75}', '\u{1fa77}'),
- ('\u{1fa7b}', '\u{1fa7f}'),
+ ('\u{1fa7d}', '\u{1fa7f}'),
('\u{1fa87}', '\u{1fa8f}'),
- ('\u{1faa9}', '\u{1faaf}'),
- ('\u{1fab7}', '\u{1fabf}'),
- ('\u{1fac3}', '\u{1facf}'),
- ('\u{1fad7}', '\u{1faff}'),
+ ('\u{1faad}', '\u{1faaf}'),
+ ('\u{1fabb}', '\u{1fabf}'),
+ ('\u{1fac6}', '\u{1facf}'),
+ ('\u{1fada}', '\u{1fadf}'),
+ ('\u{1fae8}', '\u{1faef}'),
+ ('\u{1faf7}', '\u{1faff}'),
('\u{1fb93}', '\u{1fb93}'),
('\u{1fbcb}', '\u{1fbef}'),
('\u{1fbfa}', '\u{1ffff}'),
- ('\u{2a6de}', '\u{2a6ff}'),
- ('\u{2b735}', '\u{2b73f}'),
+ ('\u{2a6e0}', '\u{2a6ff}'),
+ ('\u{2b739}', '\u{2b73f}'),
('\u{2b81e}', '\u{2b81f}'),
('\u{2cea2}', '\u{2ceaf}'),
('\u{2ebe1}', '\u{2f7ff}'),
@@ -6097,7 +6258,7 @@ pub const UPPERCASE_LETTER: &'static [(char, char)] = &[
('ℾ', 'ℿ'),
('â……', 'â……'),
('Ↄ', 'Ↄ'),
- ('â°€', 'â°®'),
+ ('â°€', 'â°¯'),
('â± ', 'â± '),
('Ɫ', 'Ɽ'),
('Ⱨ', 'Ⱨ'),
@@ -6262,13 +6423,21 @@ pub const UPPERCASE_LETTER: &'static [(char, char)] = &[
('Ꞻ', 'Ꞻ'),
('êž¼', 'êž¼'),
('êž¾', 'êž¾'),
+ ('Ꟁ', 'Ꟁ'),
('Ꟃ', 'Ꟃ'),
- ('Ꞔ', '\u{a7c7}'),
- ('\u{a7c9}', '\u{a7c9}'),
- ('\u{a7f5}', '\u{a7f5}'),
+ ('Ꞔ', 'Ꟈ'),
+ ('Ꟊ', 'Ꟊ'),
+ ('êŸ', 'êŸ'),
+ ('Ꟗ', 'Ꟗ'),
+ ('Ꟙ', 'Ꟙ'),
+ ('Ꟶ', 'Ꟶ'),
('A', 'Z'),
('ð€', 'ð§'),
('ð’°', 'ð““'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
('ð²€', 'ð²²'),
('𑢠', '𑢿'),
('𖹀', '𖹟'),
diff --git a/vendor/regex-syntax/src/unicode_tables/grapheme_cluster_break.rs b/vendor/regex-syntax/src/unicode_tables/grapheme_cluster_break.rs
index 7df9d2b93..38cfc73af 100644
--- a/vendor/regex-syntax/src/unicode_tables/grapheme_cluster_break.rs
+++ b/vendor/regex-syntax/src/unicode_tables/grapheme_cluster_break.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate grapheme-cluster-break ucd-13.0.0 --chars
+// ucd-generate grapheme-cluster-break /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("CR", CR),
@@ -25,7 +25,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
pub const CR: &'static [(char, char)] = &[('\r', '\r')];
pub const CONTROL: &'static [(char, char)] = &[
- ('\u{0}', '\t'),
+ ('\0', '\t'),
('\u{b}', '\u{c}'),
('\u{e}', '\u{1f}'),
('\u{7f}', '\u{9f}'),
@@ -71,7 +71,8 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{825}', '\u{827}'),
('\u{829}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('\u{898}', '\u{89f}'),
+ ('\u{8ca}', '\u{8e1}'),
('\u{8e3}', '\u{902}'),
('\u{93a}', '\u{93a}'),
('\u{93c}', '\u{93c}'),
@@ -116,6 +117,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{bd7}', '\u{bd7}'),
('\u{c00}', '\u{c00}'),
('\u{c04}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', '\u{c40}'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -171,7 +173,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{109d}', '\u{109d}'),
('\u{135d}', '\u{135f}'),
('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1732}', '\u{1733}'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17b5}'),
@@ -180,6 +182,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{17c9}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
('\u{1920}', '\u{1922}'),
@@ -195,7 +198,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1a65}', '\u{1a6c}'),
('\u{1a73}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1b00}', '\u{1b03}'),
('\u{1b34}', '\u{1b3a}'),
('\u{1b3c}', '\u{1b3c}'),
@@ -217,8 +220,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('\u{1cf8}', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{200c}', '\u{200c}'),
('\u{20d0}', '\u{20f0}'),
('\u{2cef}', '\u{2cf1}'),
@@ -277,11 +279,15 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('\u{11001}', '\u{11001}'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', '\u{11081}'),
('\u{110b3}', '\u{110b6}'),
('\u{110b9}', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{1112b}'),
('\u{1112d}', '\u{11134}'),
@@ -367,6 +373,8 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{16f8f}', '\u{16f92}'),
('\u{16fe4}', '\u{16fe4}'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d165}'),
('\u{1d167}', '\u{1d169}'),
('\u{1d16e}', '\u{1d172}'),
@@ -386,6 +394,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e94a}'),
@@ -1206,13 +1215,14 @@ pub const PREPEND: &'static [(char, char)] = &[
('\u{600}', '\u{605}'),
('\u{6dd}', '\u{6dd}'),
('\u{70f}', '\u{70f}'),
+ ('\u{890}', '\u{891}'),
('\u{8e2}', '\u{8e2}'),
('ൎ', 'ൎ'),
('\u{110bd}', '\u{110bd}'),
('\u{110cd}', '\u{110cd}'),
('𑇂', '𑇃'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑨺', '𑨺'),
('𑪄', '𑪉'),
('𑵆', '𑵆'),
@@ -1268,6 +1278,8 @@ pub const SPACINGMARK: &'static [(char, char)] = &[
('ျ', 'ြ'),
('á–', 'á—'),
('á‚„', 'á‚„'),
+ ('᜕', '᜕'),
+ ('᜴', '᜴'),
('ា', 'ា'),
('ើ', 'ៅ'),
('ះ', 'ៈ'),
@@ -1324,7 +1336,7 @@ pub const SPACINGMARK: &'static [(char, char)] = &[
('𑆂', '𑆂'),
('𑆳', '𑆵'),
('𑆿', '𑇀'),
- ('\u{111ce}', '\u{111ce}'),
+ ('𑇎', '𑇎'),
('𑈬', '𑈮'),
('𑈲', '𑈳'),
('𑈵', '𑈵'),
@@ -1352,15 +1364,14 @@ pub const SPACINGMARK: &'static [(char, char)] = &[
('𑚬', '𑚬'),
('𑚮', '𑚯'),
('𑚶', '𑚶'),
- ('𑜠', '𑜡'),
('𑜦', '𑜦'),
('ð‘ ¬', 'ð‘ ®'),
('ð‘ ¸', 'ð‘ ¸'),
- ('\u{11931}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
- ('\u{1193d}', '\u{1193d}'),
- ('\u{11940}', '\u{11940}'),
- ('\u{11942}', '\u{11942}'),
+ ('𑤱', '𑤵'),
+ ('𑤷', '𑤸'),
+ ('𑤽', '𑤽'),
+ ('ð‘¥€', 'ð‘¥€'),
+ ('𑥂', '𑥂'),
('𑧑', '𑧓'),
('𑧜', '𑧟'),
('𑧤', '𑧤'),
@@ -1377,7 +1388,7 @@ pub const SPACINGMARK: &'static [(char, char)] = &[
('𑶖', '𑶖'),
('𑻵', '𑻶'),
('𖽑', '𖾇'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('ð…¦', 'ð…¦'),
('ð…­', 'ð…­'),
];
diff --git a/vendor/regex-syntax/src/unicode_tables/perl_decimal.rs b/vendor/regex-syntax/src/unicode_tables/perl_decimal.rs
index 2a09259fc..9a14e4395 100644
--- a/vendor/regex-syntax/src/unicode_tables/perl_decimal.rs
+++ b/vendor/regex-syntax/src/unicode_tables/perl_decimal.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate general-category ucd-13.0.0 --chars --include decimalnumber
+// ucd-generate general-category /tmp/ucd --chars --include decimalnumber
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] =
&[("Decimal_Number", DECIMAL_NUMBER)];
@@ -60,15 +60,16 @@ pub const DECIMAL_NUMBER: &'static [(char, char)] = &[
('𑛀', '𑛉'),
('𑜰', '𑜹'),
('𑣠', '𑣩'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('ð‘±', '𑱙'),
('ð‘µ', '𑵙'),
('𑶠', '𑶩'),
('ð–© ', 'ð–©©'),
+ ('𖫀', '𖫉'),
('ð–­', 'ð–­™'),
('ðŸŽ', 'ðŸ¿'),
('ðž…€', 'ðž…‰'),
('𞋰', '𞋹'),
('ðž¥', '𞥙'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🯰', '🯹'),
];
diff --git a/vendor/regex-syntax/src/unicode_tables/perl_space.rs b/vendor/regex-syntax/src/unicode_tables/perl_space.rs
index c112dd126..bb69ce1ba 100644
--- a/vendor/regex-syntax/src/unicode_tables/perl_space.rs
+++ b/vendor/regex-syntax/src/unicode_tables/perl_space.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate property-bool ucd-13.0.0 --chars --include whitespace
+// ucd-generate property-bool /tmp/ucd --chars --include whitespace
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] =
&[("White_Space", WHITE_SPACE)];
diff --git a/vendor/regex-syntax/src/unicode_tables/perl_word.rs b/vendor/regex-syntax/src/unicode_tables/perl_word.rs
index df9eac7d7..2c8171b2b 100644
--- a/vendor/regex-syntax/src/unicode_tables/perl_word.rs
+++ b/vendor/regex-syntax/src/unicode_tables/perl_word.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate perl-word ucd-13.0.0 --chars
+// ucd-generate perl-word /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const PERL_WORD: &'static [(char, char)] = &[
('0', '9'),
@@ -57,9 +57,9 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('à €', '\u{82d}'),
('à¡€', '\u{85b}'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('\u{898}', '\u{8e1}'),
('\u{8e3}', '\u{963}'),
('०', '९'),
('ॱ', 'ঃ'),
@@ -143,11 +143,12 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('à°Ž', 'à°'),
('à°’', 'à°¨'),
('à°ª', 'à°¹'),
- ('ఽ', 'ౄ'),
+ ('\u{c3c}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
('\u{c55}', '\u{c56}'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('à± ', '\u{c63}'),
('౦', '౯'),
('ಀ', 'ಃ'),
@@ -160,7 +161,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{cc6}', 'ೈ'),
('ೊ', '\u{ccd}'),
('\u{cd5}', '\u{cd6}'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('à³ ', '\u{ce3}'),
('೦', '೯'),
('à³±', 'à³²'),
@@ -242,9 +243,8 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', '\u{1714}'),
- ('ᜠ', '\u{1734}'),
+ ('ᜀ', '᜕'),
+ ('ᜟ', '᜴'),
('á€', '\u{1753}'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -254,7 +254,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('ៜ', '\u{17dd}'),
('០', '៩'),
('\u{180b}', '\u{180d}'),
- ('á ', 'á ™'),
+ ('\u{180f}', 'á ™'),
('ᠠ', 'ᡸ'),
('ᢀ', 'ᢪ'),
('ᢰ', 'ᣵ'),
@@ -272,8 +272,8 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{1a7f}', '᪉'),
('áª', '᪙'),
('ᪧ', 'ᪧ'),
- ('\u{1ab0}', '\u{1ac0}'),
- ('\u{1b00}', 'á­‹'),
+ ('\u{1ab0}', '\u{1ace}'),
+ ('\u{1b00}', 'ᭌ'),
('á­', 'á­™'),
('\u{1b6b}', '\u{1b73}'),
('\u{1b80}', '᯳'),
@@ -285,8 +285,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('Ჽ', 'Ჿ'),
('\u{1cd0}', '\u{1cd2}'),
('\u{1cd4}', 'ᳺ'),
- ('á´€', '\u{1df9}'),
- ('\u{1dfb}', 'ἕ'),
+ ('ᴀ', 'ἕ'),
('Ἐ', 'á¼'),
('á¼ ', 'á½…'),
('Ὀ', 'á½'),
@@ -327,9 +326,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
('â’¶', 'â“©'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳳ'),
('â´€', 'â´¥'),
('â´§', 'â´§'),
@@ -358,11 +355,10 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘫ'),
@@ -371,9 +367,11 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('ꙿ', '\u{a6f1}'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê §'),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꠧ'),
('\u{a82c}', '\u{a82c}'),
('ꡀ', 'ꡳ'),
('ꢀ', '\u{a8c5}'),
@@ -400,7 +398,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯪ'),
('꯬', '\u{abed}'),
('꯰', '꯹'),
@@ -462,9 +460,20 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -499,27 +508,29 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('ð³€', 'ð³²'),
('ð´€', '\u{10d27}'),
('ð´°', 'ð´¹'),
- ('\u{10e80}', '\u{10ea9}'),
+ ('ðº€', 'ðº©'),
('\u{10eab}', '\u{10eac}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', '\u{10f50}'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', '\u{10f85}'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('ð‘€€', '\u{11046}'),
- ('ð‘¦', 'ð‘¯'),
+ ('ð‘¦', 'ð‘µ'),
('\u{1107f}', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('ð‘ƒ', '𑃨'),
('𑃰', '𑃹'),
('\u{11100}', '\u{11134}'),
('𑄶', '𑄿'),
- ('ð‘…„', '\u{11147}'),
+ ('ð‘…„', 'ð‘…‡'),
('ð‘…', '\u{11173}'),
('ð‘…¶', 'ð‘…¶'),
('\u{11180}', '𑇄'),
('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '𑇚'),
+ ('𑇎', '𑇚'),
('𑇜', '𑇜'),
('𑈀', '𑈑'),
('𑈓', '\u{11237}'),
@@ -548,7 +559,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{11370}', '\u{11374}'),
('ð‘€', 'ð‘‘Š'),
('ð‘‘', 'ð‘‘™'),
- ('\u{1145e}', '\u{11461}'),
+ ('\u{1145e}', 'ð‘‘¡'),
('ð‘’€', 'ð‘“…'),
('𑓇', '𑓇'),
('ð‘“', 'ð‘“™'),
@@ -563,16 +574,17 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('𑜀', '𑜚'),
('\u{1171d}', '\u{1172b}'),
('𑜰', '𑜹'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', '\u{1183a}'),
('𑢠', '𑣩'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{11943}'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('𑦠', '𑦧'),
('𑦪', '\u{119d7}'),
('\u{119da}', '𑧡'),
@@ -581,7 +593,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{11a47}', '\u{11a47}'),
('ð‘©', '\u{11a99}'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', '\u{11c36}'),
('\u{11c38}', '𑱀'),
@@ -603,15 +615,18 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('𑶓', '𑶘'),
('𑶠', '𑶩'),
('𑻠', '𑻶'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
('ð–© ', 'ð–©©'),
+ ('𖩰', '𖪾'),
+ ('𖫀', '𖫉'),
('ð–«', 'ð–«­'),
('\u{16af0}', '\u{16af4}'),
('𖬀', '\u{16b36}'),
@@ -625,11 +640,14 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{16f8f}', '𖾟'),
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -638,6 +656,8 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('𛲀', '𛲈'),
('ð›²', '𛲙'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
@@ -681,6 +701,7 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{1da84}', '\u{1da84}'),
('\u{1da9b}', '\u{1da9f}'),
('\u{1daa1}', '\u{1daaf}'),
+ ('ð¼€', 'ð¼ž'),
('\u{1e000}', '\u{1e006}'),
('\u{1e008}', '\u{1e018}'),
('\u{1e01b}', '\u{1e021}'),
@@ -690,7 +711,12 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('\u{1e130}', '𞄽'),
('ðž…€', 'ðž…‰'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '\u{1e2ae}'),
('𞋀', '𞋹'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('\u{1e8d0}', '\u{1e8d6}'),
('𞤀', '𞥋'),
@@ -731,13 +757,13 @@ pub const PERL_WORD: &'static [(char, char)] = &[
('🄰', '🅉'),
('ðŸ…', '🅩'),
('🅰', '🆉'),
- ('\u{1fbf0}', '\u{1fbf9}'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('🯰', '🯹'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
('\u{e0100}', '\u{e01ef}'),
];
diff --git a/vendor/regex-syntax/src/unicode_tables/property_bool.rs b/vendor/regex-syntax/src/unicode_tables/property_bool.rs
index 21cbaf9ae..8fb211030 100644
--- a/vendor/regex-syntax/src/unicode_tables/property_bool.rs
+++ b/vendor/regex-syntax/src/unicode_tables/property_bool.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate property-bool ucd-13.0.0 --chars
+// ucd-generate property-bool /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("ASCII_Hex_Digit", ASCII_HEX_DIGIT),
@@ -125,8 +125,9 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('à š', '\u{82c}'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('\u{8d4}', '\u{8df}'),
('\u{8e3}', '\u{8e9}'),
('\u{8f0}', 'ऻ'),
@@ -216,6 +217,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('\u{c4a}', '\u{c4c}'),
('\u{c55}', '\u{c56}'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('à± ', '\u{c63}'),
('ಀ', 'ಃ'),
('ಅ', 'ಌ'),
@@ -227,7 +229,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('\u{cc6}', 'ೈ'),
('ೊ', '\u{ccc}'),
('\u{cd5}', '\u{cd6}'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('à³ ', '\u{ce3}'),
('à³±', 'à³²'),
('\u{d00}', 'ഌ'),
@@ -303,9 +305,8 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', '\u{1713}'),
- ('ᜠ', '\u{1733}'),
+ ('ᜀ', '\u{1713}'),
+ ('ᜟ', '\u{1733}'),
('á€', '\u{1753}'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -329,9 +330,10 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('á©¡', '\u{1a74}'),
('ᪧ', 'ᪧ'),
('\u{1abf}', '\u{1ac0}'),
+ ('\u{1acc}', '\u{1ace}'),
('\u{1b00}', 'ᬳ'),
('\u{1b35}', 'á­ƒ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('\u{1b80}', '\u{1ba9}'),
('\u{1bac}', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -385,9 +387,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
('â’¶', 'â“©'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
('â´€', 'â´¥'),
@@ -416,11 +416,10 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘟ'),
@@ -430,9 +429,11 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ꙿ', 'ꛯ'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê …'),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꠅ'),
('ê ‡', 'ê §'),
('ꡀ', 'ꡳ'),
('ꢀ', 'ꣃ'),
@@ -463,7 +464,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯪ'),
('가', '힣'),
('ힰ', 'ퟆ'),
@@ -514,9 +515,20 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -548,24 +560,27 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('ð´€', '\u{10d27}'),
- ('\u{10e80}', '\u{10ea9}'),
+ ('ðº€', 'ðº©'),
('\u{10eab}', '\u{10eac}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('ð‘€€', '\u{11045}'),
+ ('ð‘±', 'ð‘µ'),
('𑂂', '𑂸'),
+ ('\u{110c2}', '\u{110c2}'),
('ð‘ƒ', '𑃨'),
('\u{11100}', '\u{11132}'),
- ('ð‘…„', '\u{11147}'),
+ ('ð‘…„', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('\u{11180}', '𑆿'),
('ð‘‡', '𑇄'),
- ('\u{111ce}', '\u{111cf}'),
+ ('𑇎', '\u{111cf}'),
('𑇚', '𑇚'),
('𑇜', '𑇜'),
('𑈀', '𑈑'),
@@ -594,7 +609,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ð‘€', 'ð‘‘'),
('\u{11443}', 'ð‘‘…'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘“'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -608,16 +623,17 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('𑚸', '𑚸'),
('𑜀', '𑜚'),
('\u{1171d}', '\u{1172a}'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', 'ð‘ ¸'),
('𑢠', '𑣟'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{1193c}'),
- ('\u{1193f}', '\u{11942}'),
+ ('𑤿', '𑥂'),
('𑦠', '𑦧'),
('𑦪', '\u{119d7}'),
('\u{119da}', '𑧟'),
@@ -627,7 +643,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('\u{11a35}', '\u{11a3e}'),
('ð‘©', '𑪗'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', '\u{11c36}'),
('\u{11c38}', 'ð‘°¾'),
@@ -650,14 +666,16 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('𑶓', '𑶖'),
('𑶘', '𑶘'),
('𑻠', '𑻶'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­€', 'ð–­ƒ'),
@@ -669,11 +687,14 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('\u{16f8f}', '𖾟'),
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', 'ð–¿£'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -712,6 +733,7 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼ž'),
('\u{1e000}', '\u{1e006}'),
('\u{1e008}', '\u{1e018}'),
('\u{1e01b}', '\u{1e021}'),
@@ -720,7 +742,12 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞤀', '𞥃'),
('\u{1e947}', '\u{1e947}'),
@@ -761,13 +788,13 @@ pub const ALPHABETIC: &'static [(char, char)] = &[
('🄰', '🅉'),
('ðŸ…', '🅩'),
('🅰', '🆉'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const BIDI_CONTROL: &'static [(char, char)] = &[
@@ -873,6 +900,7 @@ pub const BIDI_MIRRORED: &'static [(char, char)] = &[
('⸌', 'â¸'),
('⸜', 'â¸'),
('⸠', '⸩'),
+ ('⹕', '⹜'),
('〈', '】'),
('〔', '〛'),
('﹙', '﹞'),
@@ -936,7 +964,10 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{7fd}', '\u{7fd}'),
('\u{816}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{902}'),
+ ('࢈', '࢈'),
+ ('\u{890}', '\u{891}'),
+ ('\u{898}', '\u{89f}'),
+ ('ࣉ', '\u{902}'),
('\u{93a}', '\u{93a}'),
('\u{93c}', '\u{93c}'),
('\u{941}', '\u{948}'),
@@ -977,6 +1008,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{bcd}', '\u{bcd}'),
('\u{c00}', '\u{c00}'),
('\u{c04}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', '\u{c40}'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -1028,7 +1060,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('ჼ', 'ჼ'),
('\u{135d}', '\u{135f}'),
('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1732}', '\u{1733}'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17b5}'),
@@ -1037,7 +1069,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{17c9}', '\u{17d3}'),
('ៗ', 'ៗ'),
('\u{17dd}', '\u{17dd}'),
- ('\u{180b}', '\u{180e}'),
+ ('\u{180b}', '\u{180f}'),
('ᡃ', 'ᡃ'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
@@ -1055,7 +1087,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{1a73}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
('ᪧ', 'ᪧ'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1b00}', '\u{1b03}'),
('\u{1b34}', '\u{1b34}'),
('\u{1b36}', '\u{1b3a}'),
@@ -1081,8 +1113,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{1cf8}', '\u{1cf9}'),
('ᴬ', 'ᵪ'),
('ᵸ', 'ᵸ'),
- ('ᶛ', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('ᶛ', '\u{1dff}'),
('á¾½', 'á¾½'),
('᾿', 'á¿'),
('á¿', 'á¿'),
@@ -1123,6 +1154,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('꜀', '꜡'),
('ê°', 'ê°'),
('ꞈ', '꞊'),
+ ('ꟲ', 'ꟴ'),
('ꟸ', 'ꟹ'),
('\u{a802}', '\u{a802}'),
('\u{a806}', '\u{a806}'),
@@ -1157,12 +1189,12 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('ꫳ', 'ꫴ'),
('\u{aaf6}', '\u{aaf6}'),
('ê­›', 'ê­Ÿ'),
- ('\u{ab69}', '\u{ab6b}'),
+ ('ê­©', 'ê­«'),
('\u{abe5}', '\u{abe5}'),
('\u{abe8}', '\u{abe8}'),
('\u{abed}', '\u{abed}'),
('\u{fb1e}', '\u{fb1e}'),
- ('﮲', 'ï¯'),
+ ('﮲', '﯂'),
('\u{fe00}', '\u{fe0f}'),
('︓', '︓'),
('\u{fe20}', '\u{fe2f}'),
@@ -1181,6 +1213,9 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{101fd}', '\u{101fd}'),
('\u{102e0}', '\u{102e0}'),
('\u{10376}', '\u{1037a}'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('\u{10a01}', '\u{10a03}'),
('\u{10a05}', '\u{10a06}'),
('\u{10a0c}', '\u{10a0f}'),
@@ -1190,12 +1225,16 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('\u{11001}', '\u{11001}'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', '\u{11081}'),
('\u{110b3}', '\u{110b6}'),
('\u{110b9}', '\u{110ba}'),
('\u{110bd}', '\u{110bd}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{110cd}', '\u{110cd}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{1112b}'),
@@ -1278,8 +1317,13 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{16f8f}', '𖾟'),
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', '\u{16fe4}'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
('\u{1bc9d}', '\u{1bc9e}'),
('\u{1bca0}', '\u{1bca3}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d167}', '\u{1d169}'),
('\u{1d173}', '\u{1d182}'),
('\u{1d185}', '\u{1d18b}'),
@@ -1297,6 +1341,7 @@ pub const CASE_IGNORABLE: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '𞄽'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '𞥋'),
@@ -1384,9 +1429,7 @@ pub const CASED: &'static [(char, char)] = &[
('â… ', 'â…¿'),
('Ↄ', 'ↄ'),
('â’¶', 'â“©'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
('â´€', 'â´¥'),
@@ -1396,12 +1439,14 @@ pub const CASED: &'static [(char, char)] = &[
('Ꚁ', 'êš'),
('Ꜣ', 'ꞇ'),
('Ꞌ', 'ꞎ'),
- ('êž', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', '\u{a7f6}'),
+ ('êž', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('Ꟶ', 'ꟶ'),
('ꟸ', 'ꟺ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab68}'),
+ ('ꭜ', 'ꭨ'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
('ﬓ', 'ﬗ'),
@@ -1410,6 +1455,18 @@ pub const CASED: &'static [(char, char)] = &[
('ð€', 'ð‘'),
('ð’°', 'ð““'),
('ð“˜', 'ð“»'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
+ ('ðž€', 'ðž€'),
+ ('ðžƒ', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('𑢠', '𑣟'),
@@ -1444,6 +1501,8 @@ pub const CASED: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼‰'),
+ ('ð¼‹', 'ð¼ž'),
('𞤀', '𞥃'),
('🄰', '🅉'),
('ðŸ…', '🅩'),
@@ -1886,7 +1945,7 @@ pub const CHANGES_WHEN_CASEFOLDED: &'static [(char, char)] = &[
('â… ', 'â…¯'),
('Ↄ', 'Ↄ'),
('â’¶', 'â“'),
- ('â°€', 'â°®'),
+ ('â°€', 'â°¯'),
('â± ', 'â± '),
('Ɫ', 'Ɽ'),
('Ⱨ', 'Ⱨ'),
@@ -2051,16 +2110,24 @@ pub const CHANGES_WHEN_CASEFOLDED: &'static [(char, char)] = &[
('Ꞻ', 'Ꞻ'),
('êž¼', 'êž¼'),
('êž¾', 'êž¾'),
+ ('Ꟁ', 'Ꟁ'),
('Ꟃ', 'Ꟃ'),
- ('Ꞔ', '\u{a7c7}'),
- ('\u{a7c9}', '\u{a7c9}'),
- ('\u{a7f5}', '\u{a7f5}'),
+ ('Ꞔ', 'Ꟈ'),
+ ('Ꟊ', 'Ꟊ'),
+ ('êŸ', 'êŸ'),
+ ('Ꟗ', 'Ꟗ'),
+ ('Ꟙ', 'Ꟙ'),
+ ('Ꟶ', 'Ꟶ'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
('ﬓ', 'ﬗ'),
('A', 'Z'),
('ð€', 'ð§'),
('ð’°', 'ð““'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
('ð²€', 'ð²²'),
('𑢠', '𑢿'),
('𖹀', '𖹟'),
@@ -2156,9 +2223,7 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static [(char, char)] = &[
('â… ', 'â…¿'),
('Ↄ', 'ↄ'),
('â’¶', 'â“©'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('â± ', 'â±°'),
+ ('â°€', 'â±°'),
('â±²', 'â±³'),
('Ⱶ', 'ⱶ'),
('â±¾', 'â³£'),
@@ -2175,9 +2240,10 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static [(char, char)] = &[
('êž‹', 'êž'),
('êž', 'êž”'),
('êž–', 'êž®'),
- ('êž°', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', '\u{a7f6}'),
+ ('Ʞ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('Ꟗ', 'ꟙ'),
+ ('Ꟶ', 'ꟶ'),
('ê­“', 'ê­“'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
@@ -2187,6 +2253,14 @@ pub const CHANGES_WHEN_CASEMAPPED: &'static [(char, char)] = &[
('ð€', 'ð‘'),
('ð’°', 'ð““'),
('ð“˜', 'ð“»'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('𑢠', '𑣟'),
@@ -2620,7 +2694,7 @@ pub const CHANGES_WHEN_LOWERCASED: &'static [(char, char)] = &[
('â… ', 'â…¯'),
('Ↄ', 'Ↄ'),
('â’¶', 'â“'),
- ('â°€', 'â°®'),
+ ('â°€', 'â°¯'),
('â± ', 'â± '),
('Ɫ', 'Ɽ'),
('Ⱨ', 'Ⱨ'),
@@ -2785,13 +2859,21 @@ pub const CHANGES_WHEN_LOWERCASED: &'static [(char, char)] = &[
('Ꞻ', 'Ꞻ'),
('êž¼', 'êž¼'),
('êž¾', 'êž¾'),
+ ('Ꟁ', 'Ꟁ'),
('Ꟃ', 'Ꟃ'),
- ('Ꞔ', '\u{a7c7}'),
- ('\u{a7c9}', '\u{a7c9}'),
- ('\u{a7f5}', '\u{a7f5}'),
+ ('Ꞔ', 'Ꟈ'),
+ ('Ꟊ', 'Ꟊ'),
+ ('êŸ', 'êŸ'),
+ ('Ꟗ', 'Ꟗ'),
+ ('Ꟙ', 'Ꟙ'),
+ ('Ꟶ', 'Ꟶ'),
('A', 'Z'),
('ð€', 'ð§'),
('ð’°', 'ð““'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
('ð²€', 'ð²²'),
('𑢠', '𑢿'),
('𖹀', '𖹟'),
@@ -3237,7 +3319,7 @@ pub const CHANGES_WHEN_TITLECASED: &'static [(char, char)] = &[
('â…°', 'â…¿'),
('ↄ', 'ↄ'),
('â“', 'â“©'),
- ('ⰰ', 'ⱞ'),
+ ('ⰰ', 'ⱟ'),
('ⱡ', 'ⱡ'),
('ⱥ', 'ⱦ'),
('ⱨ', 'ⱨ'),
@@ -3402,10 +3484,14 @@ pub const CHANGES_WHEN_TITLECASED: &'static [(char, char)] = &[
('êž»', 'êž»'),
('êž½', 'êž½'),
('êž¿', 'êž¿'),
+ ('êŸ', 'êŸ'),
('ꟃ', 'ꟃ'),
- ('\u{a7c8}', '\u{a7c8}'),
- ('\u{a7ca}', '\u{a7ca}'),
- ('\u{a7f6}', '\u{a7f6}'),
+ ('ꟈ', 'ꟈ'),
+ ('ꟊ', 'ꟊ'),
+ ('ꟑ', 'ꟑ'),
+ ('ꟗ', 'ꟗ'),
+ ('ꟙ', 'ꟙ'),
+ ('ꟶ', 'ꟶ'),
('ê­“', 'ê­“'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
@@ -3413,6 +3499,10 @@ pub const CHANGES_WHEN_TITLECASED: &'static [(char, char)] = &[
('ï½', 'z'),
('ð¨', 'ð‘'),
('ð“˜', 'ð“»'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð³€', 'ð³²'),
('𑣀', '𑣟'),
('𖹠', '𖹿'),
@@ -3859,7 +3949,7 @@ pub const CHANGES_WHEN_UPPERCASED: &'static [(char, char)] = &[
('â…°', 'â…¿'),
('ↄ', 'ↄ'),
('â“', 'â“©'),
- ('ⰰ', 'ⱞ'),
+ ('ⰰ', 'ⱟ'),
('ⱡ', 'ⱡ'),
('ⱥ', 'ⱦ'),
('ⱨ', 'ⱨ'),
@@ -4024,10 +4114,14 @@ pub const CHANGES_WHEN_UPPERCASED: &'static [(char, char)] = &[
('êž»', 'êž»'),
('êž½', 'êž½'),
('êž¿', 'êž¿'),
+ ('êŸ', 'êŸ'),
('ꟃ', 'ꟃ'),
- ('\u{a7c8}', '\u{a7c8}'),
- ('\u{a7ca}', '\u{a7ca}'),
- ('\u{a7f6}', '\u{a7f6}'),
+ ('ꟈ', 'ꟈ'),
+ ('ꟊ', 'ꟊ'),
+ ('ꟑ', 'ꟑ'),
+ ('ꟗ', 'ꟗ'),
+ ('ꟙ', 'ꟙ'),
+ ('ꟶ', 'ꟶ'),
('ê­“', 'ê­“'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
@@ -4035,6 +4129,10 @@ pub const CHANGES_WHEN_UPPERCASED: &'static [(char, char)] = &[
('ï½', 'z'),
('ð¨', 'ð‘'),
('ð“˜', 'ð“»'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð³€', 'ð³²'),
('𑣀', '𑣟'),
('𖹠', '𖹿'),
@@ -4056,6 +4154,7 @@ pub const DASH: &'static [(char, char)] = &[
('⸚', '⸚'),
('⸺', '⸻'),
('â¹€', 'â¹€'),
+ ('â¹', 'â¹'),
('〜', '〜'),
('〰', '〰'),
('ã‚ ', 'ã‚ '),
@@ -4063,7 +4162,7 @@ pub const DASH: &'static [(char, char)] = &[
('﹘', '﹘'),
('ï¹£', 'ï¹£'),
('ï¼', 'ï¼'),
- ('\u{10ead}', '\u{10ead}'),
+ ('ðº­', 'ðº­'),
];
pub const DEFAULT_IGNORABLE_CODE_POINT: &'static [(char, char)] = &[
@@ -4072,7 +4171,7 @@ pub const DEFAULT_IGNORABLE_CODE_POINT: &'static [(char, char)] = &[
('\u{61c}', '\u{61c}'),
('á…Ÿ', 'á… '),
('\u{17b4}', '\u{17b5}'),
- ('\u{180b}', '\u{180e}'),
+ ('\u{180b}', '\u{180f}'),
('\u{200b}', '\u{200f}'),
('\u{202a}', '\u{202e}'),
('\u{2060}', '\u{206f}'),
@@ -4126,6 +4225,8 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('\u{7a6}', '\u{7b0}'),
('\u{7eb}', 'ßµ'),
('\u{818}', '\u{819}'),
+ ('\u{898}', '\u{89f}'),
+ ('ࣉ', '\u{8d2}'),
('\u{8e3}', '\u{8fe}'),
('\u{93c}', '\u{93c}'),
('\u{94d}', '\u{94d}'),
@@ -4142,6 +4243,7 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('\u{b4d}', '\u{b4d}'),
('\u{b55}', '\u{b55}'),
('\u{bcd}', '\u{bcd}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c4d}', '\u{c4d}'),
('\u{cbc}', '\u{cbc}'),
('\u{ccd}', '\u{ccd}'),
@@ -4168,12 +4270,14 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('á‚', 'á‚'),
('á‚š', 'á‚›'),
('\u{135d}', '\u{135f}'),
+ ('\u{1714}', '᜕'),
('\u{17c9}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{1939}', '\u{193b}'),
('\u{1a75}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
- ('\u{1ab0}', '\u{1abd}'),
+ ('\u{1ab0}', '\u{1abe}'),
+ ('\u{1ac1}', '\u{1acb}'),
('\u{1b34}', '\u{1b34}'),
('á­„', 'á­„'),
('\u{1b6b}', '\u{1b73}'),
@@ -4186,8 +4290,7 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('á³·', '\u{1cf9}'),
('ᴬ', 'ᵪ'),
('\u{1dc4}', '\u{1dcf}'),
- ('\u{1df5}', '\u{1df9}'),
- ('\u{1dfd}', '\u{1dff}'),
+ ('\u{1df5}', '\u{1dff}'),
('á¾½', 'á¾½'),
('᾿', 'á¿'),
('á¿', 'á¿'),
@@ -4218,7 +4321,7 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('\u{aabf}', 'ê«‚'),
('\u{aaf6}', '\u{aaf6}'),
('ê­›', 'ê­Ÿ'),
- ('\u{ab69}', '\u{ab6b}'),
+ ('ê­©', 'ê­«'),
('꯬', '\u{abed}'),
('\u{fb1e}', '\u{fb1e}'),
('\u{fe20}', '\u{fe2f}'),
@@ -4228,9 +4331,15 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('\u{ff9e}', '\u{ff9f}'),
('ï¿£', 'ï¿£'),
('\u{102e0}', '\u{102e0}'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('\u{10ae5}', '\u{10ae6}'),
('ð´¢', '\u{10d27}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
+ ('\u{11046}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
('\u{110b9}', '\u{110ba}'),
('\u{11133}', '\u{11134}'),
('\u{11173}', '\u{11173}'),
@@ -4250,7 +4359,7 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('𑚶', '\u{116b7}'),
('\u{1172b}', '\u{1172b}'),
('\u{11839}', '\u{1183a}'),
- ('\u{1193d}', '\u{1193e}'),
+ ('𑤽', '\u{1193e}'),
('\u{11943}', '\u{11943}'),
('\u{119e0}', '\u{119e0}'),
('\u{11a34}', '\u{11a34}'),
@@ -4263,13 +4372,19 @@ pub const DIACRITIC: &'static [(char, char)] = &[
('\u{16af0}', '\u{16af4}'),
('\u{16b30}', '\u{16b36}'),
('\u{16f8f}', '𖾟'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d167}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
('\u{1d185}', '\u{1d18b}'),
('\u{1d1aa}', '\u{1d1ad}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e946}'),
@@ -4410,25 +4525,26 @@ pub const EMOJI: &'static [(char, char)] = &[
('🗺', 'ðŸ™'),
('🚀', '🛅'),
('🛋', '🛒'),
- ('🛕', '\u{1f6d7}'),
- ('🛠', '🛥'),
+ ('🛕', '🛗'),
+ ('ðŸ›', '🛥'),
('🛩', '🛩'),
('🛫', '🛬'),
('🛰', '🛰'),
- ('🛳', '\u{1f6fc}'),
+ ('🛳', '🛼'),
('🟠', '🟫'),
- ('\u{1f90c}', '🤺'),
+ ('🟰', '🟰'),
+ ('🤌', '🤺'),
('🤼', '🥅'),
- ('🥇', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🧿'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
+ ('🥇', '🧿'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
];
pub const EMOJI_COMPONENT: &'static [(char, char)] = &[
@@ -4473,18 +4589,20 @@ pub const EMOJI_MODIFIER_BASE: &'static [(char, char)] = &[
('🚴', '🚶'),
('🛀', '🛀'),
('🛌', '🛌'),
- ('\u{1f90c}', '\u{1f90c}'),
+ ('🤌', '🤌'),
('ðŸ¤', 'ðŸ¤'),
('🤘', '🤟'),
('🤦', '🤦'),
('🤰', '🤹'),
('🤼', '🤾'),
- ('\u{1f977}', '\u{1f977}'),
+ ('🥷', '🥷'),
('🦵', '🦶'),
('🦸', '🦹'),
('🦻', '🦻'),
('ðŸ§', 'ðŸ§'),
('🧑', 'ðŸ§'),
+ ('🫃', '🫅'),
+ ('🫰', '🫶'),
];
pub const EMOJI_PRESENTATION: &'static [(char, char)] = &[
@@ -4553,22 +4671,24 @@ pub const EMOJI_PRESENTATION: &'static [(char, char)] = &[
('🚀', '🛅'),
('🛌', '🛌'),
('ðŸ›', '🛒'),
- ('🛕', '\u{1f6d7}'),
+ ('🛕', '🛗'),
+ ('ðŸ›', '🛟'),
('🛫', '🛬'),
- ('🛴', '\u{1f6fc}'),
+ ('🛴', '🛼'),
('🟠', '🟫'),
- ('\u{1f90c}', '🤺'),
+ ('🟰', '🟰'),
+ ('🤌', '🤺'),
('🤼', '🥅'),
- ('🥇', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🧿'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
+ ('🥇', '🧿'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
];
pub const EXTENDED_PICTOGRAPHIC: &'static [(char, char)] = &[
@@ -4623,13 +4743,13 @@ pub const EXTENDED_PICTOGRAPHIC: &'static [(char, char)] = &[
('㊗', '㊗'),
('㊙', '㊙'),
('🀀', '\u{1f0ff}'),
- ('\u{1f10d}', '\u{1f10f}'),
+ ('ðŸ„', 'ðŸ„'),
('🄯', '🄯'),
('🅬', '🅱'),
('🅾', '🅿'),
('🆎', '🆎'),
('🆑', '🆚'),
- ('\u{1f1ad}', '\u{1f1e5}'),
+ ('🆭', '\u{1f1e5}'),
('ðŸˆ', '\u{1f20f}'),
('🈚', '🈚'),
('🈯', '🈯'),
@@ -4646,7 +4766,7 @@ pub const EXTENDED_PICTOGRAPHIC: &'static [(char, char)] = &[
('\u{1f85a}', '\u{1f85f}'),
('\u{1f888}', '\u{1f88f}'),
('\u{1f8ae}', '\u{1f8ff}'),
- ('\u{1f90c}', '🤺'),
+ ('🤌', '🤺'),
('🤼', '🥅'),
('🥇', '\u{1faff}'),
('\u{1fc00}', '\u{1fffd}'),
@@ -4677,6 +4797,7 @@ pub const EXTENDER: &'static [(char, char)] = &[
('ê«', 'ê«'),
('ꫳ', 'ꫴ'),
('ï½°', 'ï½°'),
+ ('ðž', 'ðž‚'),
('ð‘', 'ð‘'),
('ð‘—†', 'ð‘—ˆ'),
('\u{11a98}', '\u{11a98}'),
@@ -4709,7 +4830,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ׯ', '״'),
('؆', 'Ø'),
('Ø›', 'Ø›'),
- ('Øž', 'ÙŠ'),
+ ('Ø', 'ÙŠ'),
('Ù ', 'Ù¯'),
('Ù±', 'Û•'),
('Ûž', 'Ûž'),
@@ -4730,8 +4851,8 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ࡀ', 'ࡘ'),
('à¡ž', 'à¡ž'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('ः', 'ह'),
('ऻ', 'ऻ'),
('ऽ', 'ी'),
@@ -4820,6 +4941,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('à°½', 'à°½'),
('à±', 'ౄ'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('౦', '౯'),
('౷', 'ಀ'),
@@ -4833,7 +4955,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ೃ', 'ೄ'),
('ೇ', 'ೈ'),
('ೊ', 'ೋ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('೦', '೯'),
('à³±', 'à³²'),
@@ -4922,10 +5044,10 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('á¸', 'á½'),
('á€', 'ášœ'),
('ᚠ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
- ('᜵', '᜶'),
+ ('ᜀ', 'ᜑ'),
+ ('᜕', '᜕'),
+ ('ᜟ', 'ᜱ'),
+ ('᜴', '᜶'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -4967,9 +5089,9 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ᬄ', 'ᬳ'),
('ᬻ', 'ᬻ'),
('ᬽ', 'á­'),
- ('á­ƒ', 'á­‹'),
+ ('ᭃ', 'ᭌ'),
('á­', 'á­ª'),
- ('á­´', 'á­¼'),
+ ('á­´', 'á­¾'),
('ᮂ', 'ᮡ'),
('ᮦ', 'ᮧ'),
('᮪', '᮪'),
@@ -5013,15 +5135,13 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('â°', 'â±'),
('â´', 'â‚Ž'),
('â‚', 'â‚œ'),
- ('â‚ ', 'â‚¿'),
+ ('₠', '⃀'),
('℀', '↋'),
('â†', 'â¦'),
('â‘€', 'â‘Š'),
('â‘ ', 'â­³'),
('⭶', '⮕'),
- ('\u{2b97}', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('â± ', 'â³®'),
+ ('â®—', 'â³®'),
('â³²', 'â³³'),
('â³¹', 'â´¥'),
('â´§', 'â´§'),
@@ -5037,7 +5157,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('â·ˆ', 'â·Ž'),
('â·', 'â·–'),
('â·˜', 'â·ž'),
- ('⸀', '\u{2e52}'),
+ ('⸀', 'â¹'),
('⺀', '⺙'),
('⺛', '⻳'),
('â¼€', 'â¿•'),
@@ -5050,8 +5170,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ㄱ', 'ㆎ'),
('ã†', '㇣'),
('ㇰ', '㈞'),
- ('㈠', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('㈠', 'ꒌ'),
('ê’', '꓆'),
('ê“', 'ꘫ'),
('Ꙁ', 'ꙮ'),
@@ -5059,9 +5178,11 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('꙾', 'êš'),
('ꚠ', 'ꛯ'),
('꛲', '꛷'),
- ('꜀', 'ꞿ'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê '),
+ ('꜀', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ê '),
('ê ƒ', 'ê …'),
('ê ‡', 'ê Š'),
('ꠌ', 'ꠤ'),
@@ -5103,7 +5224,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ꬑ', 'ꬖ'),
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
- ('ꬰ', '\u{ab6b}'),
+ ('ꬰ', '꭫'),
('ꭰ', 'ꯤ'),
('ꯦ', 'ꯧ'),
('ꯩ', '꯬'),
@@ -5121,11 +5242,11 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('מּ', 'מּ'),
('ï­€', 'ï­'),
('ï­ƒ', 'ï­„'),
- ('ï­†', 'ï¯'),
- ('ﯓ', '﴿'),
- ('ïµ', 'ï¶'),
+ ('צּ', '﯂'),
+ ('ﯓ', 'ï¶'),
('ﶒ', 'ﷇ'),
- ('ï·°', 'ï·½'),
+ ('ï·', 'ï·'),
+ ('ï·°', 'ï·¿'),
('ï¸', '︙'),
('︰', '﹒'),
('﹔', '﹦'),
@@ -5151,7 +5272,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð„€', 'ð„‚'),
('ð„‡', 'ð„³'),
('ð„·', 'ð†Ž'),
- ('ð†', '\u{1019c}'),
+ ('ð†', 'ð†œ'),
('ð† ', 'ð† '),
('ð‡', 'ð‡¼'),
('ðŠ€', 'ðŠœ'),
@@ -5169,10 +5290,20 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
- ('ð•¯', 'ð•¯'),
+ ('ð•¯', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -5209,18 +5340,22 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð³º', 'ð´£'),
('ð´°', 'ð´¹'),
('ð¹ ', 'ð¹¾'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10ead}', '\u{10ead}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº­', 'ðº­'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼§'),
('ð¼°', 'ð½…'),
('ð½‘', 'ð½™'),
- ('\u{10fb0}', '\u{10fcb}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾†', 'ð¾‰'),
+ ('ð¾°', 'ð¿‹'),
('ð¿ ', 'ð¿¶'),
('ð‘€€', 'ð‘€€'),
('𑀂', '𑀷'),
('ð‘‡', 'ð‘'),
('ð‘’', 'ð‘¯'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('ð‘‚‚', 'ð‘‚²'),
('𑂷', '𑂸'),
('ð‘‚»', 'ð‘‚¼'),
@@ -5229,12 +5364,12 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('𑃰', '𑃹'),
('𑄃', '𑄦'),
('𑄬', '𑄬'),
- ('𑄶', '\u{11147}'),
+ ('𑄶', '𑅇'),
('ð‘…', 'ð‘…²'),
('ð‘…´', 'ð‘…¶'),
('𑆂', '𑆵'),
('𑆿', '𑇈'),
- ('ð‘‡', '\u{111ce}'),
+ ('ð‘‡', '𑇎'),
('ð‘‡', '𑇟'),
('𑇡', '𑇴'),
('𑈀', '𑈑'),
@@ -5269,7 +5404,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð‘‘…', 'ð‘‘…'),
('𑑇', '𑑛'),
('ð‘‘', 'ð‘‘'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘’±', 'ð‘’²'),
('ð‘’¹', 'ð‘’¹'),
@@ -5293,27 +5428,27 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('𑚬', '𑚬'),
('𑚮', '𑚯'),
('𑚶', '𑚶'),
- ('𑚸', '𑚸'),
+ ('𑚸', '𑚹'),
('𑛀', '𑛉'),
('𑜀', '𑜚'),
('𑜠', '𑜡'),
('𑜦', '𑜦'),
- ('𑜰', '𑜿'),
+ ('𑜰', 'ð‘†'),
('ð‘ €', 'ð‘ ®'),
('ð‘ ¸', 'ð‘ ¸'),
('ð‘ »', 'ð‘ »'),
('ð‘¢ ', 'ð‘£²'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{11931}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
- ('\u{1193d}', '\u{1193d}'),
- ('\u{1193f}', '\u{11942}'),
- ('\u{11944}', '\u{11946}'),
- ('\u{11950}', '\u{11959}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤱', '𑤵'),
+ ('𑤷', '𑤸'),
+ ('𑤽', '𑤽'),
+ ('𑤿', '𑥂'),
+ ('𑥄', '𑥆'),
+ ('ð‘¥', 'ð‘¥™'),
('𑦠', '𑦧'),
('𑦪', '𑧓'),
('𑧜', '𑧟'),
@@ -5327,7 +5462,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('𑩜', '𑪉'),
('𑪗', '𑪗'),
('𑪚', '𑪢'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°¯'),
('ð‘°¾', 'ð‘°¾'),
@@ -5351,18 +5486,20 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('𑶠', '𑶩'),
('ð‘» ', 'ð‘»²'),
('𑻵', '𑻸'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð‘¿€', 'ð‘¿±'),
('ð‘¿¿', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('ð’‘°', 'ð’‘´'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿²'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
('ð–© ', 'ð–©©'),
- ('𖩮', '𖩯'),
+ ('𖩮', '𖪾'),
+ ('𖫀', '𖫉'),
('ð–«', 'ð–«­'),
('ð–«µ', 'ð–«µ'),
('𖬀', '𖬯'),
@@ -5376,11 +5513,14 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð–½', '𖾇'),
('𖾓', '𖾟'),
('ð–¿ ', 'ð–¿£'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -5390,6 +5530,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð›²', '𛲙'),
('𛲜', '𛲜'),
('𛲟', '𛲟'),
+ ('ðœ½', '𜿃'),
('ð€€', 'ðƒµ'),
('ð„€', 'ð„¦'),
('ð„©', 'ð…¤'),
@@ -5397,7 +5538,7 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð…ª', 'ð…­'),
('ð†ƒ', 'ð†„'),
('ð†Œ', 'ð†©'),
- ('ð†®', 'ð‡¨'),
+ ('ð†®', 'ð‡ª'),
('ðˆ€', 'ð‰'),
('ð‰…', 'ð‰…'),
('ð‹ ', 'ð‹³'),
@@ -5428,13 +5569,19 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('ð©­', 'ð©´'),
('ð©¶', 'ðªƒ'),
('ðª…', 'ðª‹'),
+ ('ð¼€', 'ð¼ž'),
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…€', 'ðž…‰'),
('ðž…Ž', 'ðž…'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
('𞋰', '𞋹'),
('ðž‹¿', 'ðž‹¿'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞣇', 'ðž£'),
('𞤀', '𞥃'),
@@ -5483,45 +5630,46 @@ pub const GRAPHEME_BASE: &'static [(char, char)] = &[
('🂱', '🂿'),
('ðŸƒ', 'ðŸƒ'),
('🃑', '🃵'),
- ('🄀', '\u{1f1ad}'),
+ ('🄀', '🆭'),
('🇦', '🈂'),
('ðŸˆ', '🈻'),
('🉀', '🉈'),
('ðŸ‰', '🉑'),
('🉠', '🉥'),
- ('🌀', '\u{1f6d7}'),
- ('🛠', '🛬'),
- ('🛰', '\u{1f6fc}'),
+ ('🌀', '🛗'),
+ ('ðŸ›', '🛬'),
+ ('🛰', '🛼'),
('🜀', 'ðŸ³'),
('🞀', '🟘'),
('🟠', '🟫'),
+ ('🟰', '🟰'),
('🠀', '🠋'),
('ðŸ ', '🡇'),
('ðŸ¡', '🡙'),
('🡠', '🢇'),
('ðŸ¢', '🢭'),
- ('\u{1f8b0}', '\u{1f8b1}'),
- ('🤀', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🩓'),
+ ('🢰', '🢱'),
+ ('🤀', '🩓'),
('🩠', '🩭'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
- ('\u{1fb00}', '\u{1fb92}'),
- ('\u{1fb94}', '\u{1fbca}'),
- ('\u{1fbf0}', '\u{1fbf9}'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
+ ('🬀', '🮒'),
+ ('🮔', '🯊'),
+ ('🯰', '🯹'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
@@ -5549,7 +5697,8 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{825}', '\u{827}'),
('\u{829}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('\u{898}', '\u{89f}'),
+ ('\u{8ca}', '\u{8e1}'),
('\u{8e3}', '\u{902}'),
('\u{93a}', '\u{93a}'),
('\u{93c}', '\u{93c}'),
@@ -5594,6 +5743,7 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{bd7}', '\u{bd7}'),
('\u{c00}', '\u{c00}'),
('\u{c04}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', '\u{c40}'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -5649,7 +5799,7 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{109d}', '\u{109d}'),
('\u{135d}', '\u{135f}'),
('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1732}', '\u{1733}'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17b5}'),
@@ -5658,6 +5808,7 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{17c9}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
('\u{1920}', '\u{1922}'),
@@ -5673,7 +5824,7 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{1a65}', '\u{1a6c}'),
('\u{1a73}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1b00}', '\u{1b03}'),
('\u{1b34}', '\u{1b3a}'),
('\u{1b3c}', '\u{1b3c}'),
@@ -5695,8 +5846,7 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('\u{1cf8}', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{200c}', '\u{200c}'),
('\u{20d0}', '\u{20f0}'),
('\u{2cef}', '\u{2cf1}'),
@@ -5755,11 +5905,15 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('\u{11001}', '\u{11001}'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', '\u{11081}'),
('\u{110b3}', '\u{110b6}'),
('\u{110b9}', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{1112b}'),
('\u{1112d}', '\u{11134}'),
@@ -5845,6 +5999,8 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{16f8f}', '\u{16f92}'),
('\u{16fe4}', '\u{16fe4}'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d165}'),
('\u{1d167}', '\u{1d169}'),
('\u{1d16e}', '\u{1d172}'),
@@ -5864,6 +6020,7 @@ pub const GRAPHEME_EXTEND: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e94a}'),
@@ -5887,8 +6044,8 @@ pub const GRAPHEME_LINK: &'static [(char, char)] = &[
('\u{eba}', '\u{eba}'),
('\u{f84}', '\u{f84}'),
('\u{1039}', '\u{103a}'),
- ('\u{1714}', '\u{1714}'),
- ('\u{1734}', '\u{1734}'),
+ ('\u{1714}', '᜕'),
+ ('᜴', '᜴'),
('\u{17d2}', '\u{17d2}'),
('\u{1a60}', '\u{1a60}'),
('á­„', 'á­„'),
@@ -5904,6 +6061,7 @@ pub const GRAPHEME_LINK: &'static [(char, char)] = &[
('\u{abed}', '\u{abed}'),
('\u{10a3f}', '\u{10a3f}'),
('\u{11046}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
('\u{1107f}', '\u{1107f}'),
('\u{110b9}', '\u{110b9}'),
('\u{11133}', '\u{11134}'),
@@ -5918,7 +6076,7 @@ pub const GRAPHEME_LINK: &'static [(char, char)] = &[
('𑚶', '𑚶'),
('\u{1172b}', '\u{1172b}'),
('\u{11839}', '\u{11839}'),
- ('\u{1193d}', '\u{1193e}'),
+ ('𑤽', '\u{1193e}'),
('\u{119e0}', '\u{119e0}'),
('\u{11a34}', '\u{11a34}'),
('\u{11a47}', '\u{11a47}'),
@@ -6007,9 +6165,9 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('à €', '\u{82d}'),
('à¡€', '\u{85b}'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('\u{898}', '\u{8e1}'),
('\u{8e3}', '\u{963}'),
('०', '९'),
('ॱ', 'ঃ'),
@@ -6093,11 +6251,12 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('à°Ž', 'à°'),
('à°’', 'à°¨'),
('à°ª', 'à°¹'),
- ('ఽ', 'ౄ'),
+ ('\u{c3c}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
('\u{c55}', '\u{c56}'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('à± ', '\u{c63}'),
('౦', '౯'),
('ಀ', 'ಃ'),
@@ -6110,7 +6269,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('\u{cc6}', 'ೈ'),
('ೊ', '\u{ccd}'),
('\u{cd5}', '\u{cd6}'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('à³ ', '\u{ce3}'),
('೦', '೯'),
('à³±', 'à³²'),
@@ -6193,9 +6352,8 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', '\u{1714}'),
- ('ᜠ', '\u{1734}'),
+ ('ᜀ', '᜕'),
+ ('ᜟ', '᜴'),
('á€', '\u{1753}'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -6205,7 +6363,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('ៜ', '\u{17dd}'),
('០', '៩'),
('\u{180b}', '\u{180d}'),
- ('á ', 'á ™'),
+ ('\u{180f}', 'á ™'),
('ᠠ', 'ᡸ'),
('ᢀ', 'ᢪ'),
('ᢰ', 'ᣵ'),
@@ -6224,8 +6382,8 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('áª', '᪙'),
('ᪧ', 'ᪧ'),
('\u{1ab0}', '\u{1abd}'),
- ('\u{1abf}', '\u{1ac0}'),
- ('\u{1b00}', 'á­‹'),
+ ('\u{1abf}', '\u{1ace}'),
+ ('\u{1b00}', 'ᭌ'),
('á­', 'á­™'),
('\u{1b6b}', '\u{1b73}'),
('\u{1b80}', '᯳'),
@@ -6237,8 +6395,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('Ჽ', 'Ჿ'),
('\u{1cd0}', '\u{1cd2}'),
('\u{1cd4}', 'ᳺ'),
- ('á´€', '\u{1df9}'),
- ('\u{1dfb}', 'ἕ'),
+ ('ᴀ', 'ἕ'),
('Ἐ', 'á¼'),
('á¼ ', 'á½…'),
('Ὀ', 'á½'),
@@ -6278,9 +6435,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('â……', 'â…‰'),
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳳ'),
('â´€', 'â´¥'),
('â´§', 'â´§'),
@@ -6307,11 +6462,10 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘫ'),
@@ -6320,9 +6474,11 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('ꙿ', '\u{a6f1}'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê §'),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꠧ'),
('\u{a82c}', '\u{a82c}'),
('ꡀ', 'ꡳ'),
('ꢀ', '\u{a8c5}'),
@@ -6349,7 +6505,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯪ'),
('꯬', '\u{abed}'),
('꯰', '꯹'),
@@ -6411,9 +6567,20 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -6448,27 +6615,29 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('ð³€', 'ð³²'),
('ð´€', '\u{10d27}'),
('ð´°', 'ð´¹'),
- ('\u{10e80}', '\u{10ea9}'),
+ ('ðº€', 'ðº©'),
('\u{10eab}', '\u{10eac}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', '\u{10f50}'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', '\u{10f85}'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('ð‘€€', '\u{11046}'),
- ('ð‘¦', 'ð‘¯'),
+ ('ð‘¦', 'ð‘µ'),
('\u{1107f}', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('ð‘ƒ', '𑃨'),
('𑃰', '𑃹'),
('\u{11100}', '\u{11134}'),
('𑄶', '𑄿'),
- ('ð‘…„', '\u{11147}'),
+ ('ð‘…„', 'ð‘…‡'),
('ð‘…', '\u{11173}'),
('ð‘…¶', 'ð‘…¶'),
('\u{11180}', '𑇄'),
('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '𑇚'),
+ ('𑇎', '𑇚'),
('𑇜', '𑇜'),
('𑈀', '𑈑'),
('𑈓', '\u{11237}'),
@@ -6497,7 +6666,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('\u{11370}', '\u{11374}'),
('ð‘€', 'ð‘‘Š'),
('ð‘‘', 'ð‘‘™'),
- ('\u{1145e}', '\u{11461}'),
+ ('\u{1145e}', 'ð‘‘¡'),
('ð‘’€', 'ð‘“…'),
('𑓇', '𑓇'),
('ð‘“', 'ð‘“™'),
@@ -6512,16 +6681,17 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('𑜀', '𑜚'),
('\u{1171d}', '\u{1172b}'),
('𑜰', '𑜹'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', '\u{1183a}'),
('𑢠', '𑣩'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{11943}'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('𑦠', '𑦧'),
('𑦪', '\u{119d7}'),
('\u{119da}', '𑧡'),
@@ -6530,7 +6700,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('\u{11a47}', '\u{11a47}'),
('ð‘©', '\u{11a99}'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', '\u{11c36}'),
('\u{11c38}', '𑱀'),
@@ -6552,15 +6722,18 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('𑶓', '𑶘'),
('𑶠', '𑶩'),
('𑻠', '𑻶'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
('ð–© ', 'ð–©©'),
+ ('𖩰', '𖪾'),
+ ('𖫀', '𖫉'),
('ð–«', 'ð–«­'),
('\u{16af0}', '\u{16af4}'),
('𖬀', '\u{16b36}'),
@@ -6574,11 +6747,14 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('\u{16f8f}', '𖾟'),
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -6587,6 +6763,8 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('𛲀', '𛲈'),
('ð›²', '𛲙'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
@@ -6630,6 +6808,7 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('\u{1da84}', '\u{1da84}'),
('\u{1da9b}', '\u{1da9f}'),
('\u{1daa1}', '\u{1daaf}'),
+ ('ð¼€', 'ð¼ž'),
('\u{1e000}', '\u{1e006}'),
('\u{1e008}', '\u{1e018}'),
('\u{1e01b}', '\u{1e021}'),
@@ -6639,7 +6818,12 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('\u{1e130}', '𞄽'),
('ðž…€', 'ðž…‰'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '\u{1e2ae}'),
('𞋀', '𞋹'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('\u{1e8d0}', '\u{1e8d6}'),
('𞤀', '𞥋'),
@@ -6677,14 +6861,14 @@ pub const ID_CONTINUE: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('\u{1fbf0}', '\u{1fbf9}'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('🯰', '🯹'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
('\u{e0100}', '\u{e01ef}'),
];
@@ -6738,8 +6922,9 @@ pub const ID_START: &'static [(char, char)] = &[
('à ¨', 'à ¨'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('ऄ', 'ह'),
('ऽ', 'ऽ'),
('à¥', 'à¥'),
@@ -6804,6 +6989,7 @@ pub const ID_START: &'static [(char, char)] = &[
('à°ª', 'à°¹'),
('à°½', 'à°½'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('ಀ', 'ಀ'),
('ಅ', 'ಌ'),
@@ -6812,10 +6998,10 @@ pub const ID_START: &'static [(char, char)] = &[
('ಪ', 'ಳ'),
('ವ', 'ಹ'),
('ಽ', 'ಽ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('à³±', 'à³²'),
- ('\u{d04}', 'ഌ'),
+ ('ഄ', 'ഌ'),
('à´Ž', 'à´'),
('à´’', 'à´º'),
('à´½', 'à´½'),
@@ -6883,9 +7069,8 @@ pub const ID_START: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
+ ('ᜀ', 'ᜑ'),
+ ('ᜟ', 'ᜱ'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -6905,7 +7090,7 @@ pub const ID_START: &'static [(char, char)] = &[
('ᨠ', 'ᩔ'),
('ᪧ', 'ᪧ'),
('ᬅ', 'ᬳ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('ᮃ', 'ᮠ'),
('ᮮ', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -6955,9 +7140,7 @@ pub const ID_START: &'static [(char, char)] = &[
('â……', 'â…‰'),
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
('â´€', 'â´¥'),
@@ -6984,11 +7167,10 @@ pub const ID_START: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘟ'),
@@ -6998,9 +7180,11 @@ pub const ID_START: &'static [(char, char)] = &[
('ꚠ', 'ꛯ'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê '),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ê '),
('ê ƒ', 'ê …'),
('ê ‡', 'ê Š'),
('ꠌ', 'ꠢ'),
@@ -7037,7 +7221,7 @@ pub const ID_START: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯢ'),
('가', '힣'),
('ힰ', 'ퟆ'),
@@ -7089,9 +7273,20 @@ pub const ID_START: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -7122,19 +7317,22 @@ pub const ID_START: &'static [(char, char)] = &[
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('ð´€', 'ð´£'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('𑀃', '𑀷'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('𑂃', '𑂯'),
('ð‘ƒ', '𑃨'),
('𑄃', '𑄦'),
('ð‘…„', 'ð‘…„'),
- ('\u{11147}', '\u{11147}'),
+ ('ð‘…‡', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('𑆃', '𑆲'),
@@ -7160,7 +7358,7 @@ pub const ID_START: &'static [(char, char)] = &[
('ð‘', 'ð‘¡'),
('ð‘€', 'ð‘´'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -7171,15 +7369,16 @@ pub const ID_START: &'static [(char, char)] = &[
('𑚀', '𑚪'),
('𑚸', '𑚸'),
('𑜀', '𑜚'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', 'ð‘ «'),
('𑢠', '𑣟'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑦠', '𑦧'),
('𑦪', 'ð‘§'),
('𑧡', '𑧡'),
@@ -7190,7 +7389,7 @@ pub const ID_START: &'static [(char, char)] = &[
('ð‘©', 'ð‘©'),
('𑩜', '𑪉'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°®'),
('𑱀', '𑱀'),
@@ -7204,14 +7403,16 @@ pub const ID_START: &'static [(char, char)] = &[
('𑵪', '𑶉'),
('𑶘', '𑶘'),
('ð‘» ', 'ð‘»²'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­€', 'ð–­ƒ'),
@@ -7224,9 +7425,12 @@ pub const ID_START: &'static [(char, char)] = &[
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', 'ð–¿£'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -7264,10 +7468,16 @@ pub const ID_START: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼ž'),
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞤀', '𞥃'),
('𞥋', '𞥋'),
@@ -7304,35 +7514,35 @@ pub const ID_START: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const IDEOGRAPHIC: &'static [(char, char)] = &[
('〆', '〇'),
('〡', '〩'),
('〸', '〺'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
+ ('ã€', '䶿'),
+ ('一', '鿿'),
('豈', '舘'),
('ï©°', 'ï«™'),
('\u{16fe4}', '\u{16fe4}'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
('𛅰', '𛋻'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const JOIN_CONTROL: &'static [(char, char)] = &[('\u{200c}', '\u{200d}')];
@@ -7787,7 +7997,7 @@ pub const LOWERCASE: &'static [(char, char)] = &[
('â…°', 'â…¿'),
('ↄ', 'ↄ'),
('â“', 'â“©'),
- ('ⰰ', 'ⱞ'),
+ ('ⰰ', 'ⱟ'),
('ⱡ', 'ⱡ'),
('ⱥ', 'ⱦ'),
('ⱨ', 'ⱨ'),
@@ -7955,19 +8165,33 @@ pub const LOWERCASE: &'static [(char, char)] = &[
('êž»', 'êž»'),
('êž½', 'êž½'),
('êž¿', 'êž¿'),
+ ('êŸ', 'êŸ'),
('ꟃ', 'ꟃ'),
- ('\u{a7c8}', '\u{a7c8}'),
- ('\u{a7ca}', '\u{a7ca}'),
- ('\u{a7f6}', '\u{a7f6}'),
+ ('ꟈ', 'ꟈ'),
+ ('ꟊ', 'ꟊ'),
+ ('ꟑ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟕ'),
+ ('ꟗ', 'ꟗ'),
+ ('ꟙ', 'ꟙ'),
+ ('ꟶ', 'ꟶ'),
('ꟸ', 'ꟺ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab68}'),
+ ('ꭜ', 'ꭨ'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
('ﬓ', 'ﬗ'),
('ï½', 'z'),
('ð¨', 'ð‘'),
('ð“˜', 'ð“»'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
+ ('ðž€', 'ðž€'),
+ ('ðžƒ', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð³€', 'ð³²'),
('𑣀', '𑣟'),
('𖹠', '𖹿'),
@@ -7999,6 +8223,8 @@ pub const LOWERCASE: &'static [(char, char)] = &[
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‰'),
('ðŸ‹', 'ðŸ‹'),
+ ('ð¼€', 'ð¼‰'),
+ ('ð¼‹', 'ð¼ž'),
('𞤢', '𞥃'),
];
@@ -8281,6 +8507,7 @@ pub const OTHER_ALPHABETIC: &'static [(char, char)] = &[
('á©•', '\u{1a5e}'),
('á©¡', '\u{1a74}'),
('\u{1abf}', '\u{1ac0}'),
+ ('\u{1acc}', '\u{1ace}'),
('\u{1b00}', 'ᬄ'),
('\u{1b35}', 'á­ƒ'),
('\u{1b80}', 'ᮂ'),
@@ -8325,14 +8552,16 @@ pub const OTHER_ALPHABETIC: &'static [(char, char)] = &[
('\u{10eab}', '\u{10eac}'),
('𑀀', '𑀂'),
('\u{11038}', '\u{11045}'),
+ ('\u{11073}', '\u{11074}'),
('ð‘‚‚', 'ð‘‚‚'),
('𑂰', '𑂸'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{11132}'),
('ð‘……', 'ð‘…†'),
('\u{11180}', '𑆂'),
('𑆳', '𑆿'),
- ('\u{111ce}', '\u{111cf}'),
+ ('𑇎', '\u{111cf}'),
('𑈬', '\u{11234}'),
('\u{11237}', '\u{11237}'),
('\u{1123e}', '\u{1123e}'),
@@ -8354,11 +8583,11 @@ pub const OTHER_ALPHABETIC: &'static [(char, char)] = &[
('\u{116ab}', '\u{116b5}'),
('\u{1171d}', '\u{1172a}'),
('ð‘ ¬', 'ð‘ ¸'),
- ('\u{11930}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('\u{11930}', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{1193c}'),
- ('\u{11940}', '\u{11940}'),
- ('\u{11942}', '\u{11942}'),
+ ('ð‘¥€', 'ð‘¥€'),
+ ('𑥂', '𑥂'),
('𑧑', '\u{119d7}'),
('\u{119da}', '𑧟'),
('𑧤', '𑧤'),
@@ -8384,7 +8613,7 @@ pub const OTHER_ALPHABETIC: &'static [(char, char)] = &[
('\u{16f4f}', '\u{16f4f}'),
('𖽑', '𖾇'),
('\u{16f8f}', '\u{16f92}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('\u{1bc9e}', '\u{1bc9e}'),
('\u{1e000}', '\u{1e006}'),
('\u{1e008}', '\u{1e018}'),
@@ -8466,6 +8695,10 @@ pub const OTHER_LOWERCASE: &'static [(char, char)] = &[
('ê°', 'ê°'),
('ꟸ', 'ꟹ'),
('ꭜ', 'ꭟ'),
+ ('ðž€', 'ðž€'),
+ ('ðžƒ', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
];
pub const OTHER_MATH: &'static [(char, char)] = &[
@@ -8651,13 +8884,14 @@ pub const PREPENDED_CONCATENATION_MARK: &'static [(char, char)] = &[
('\u{600}', '\u{605}'),
('\u{6dd}', '\u{6dd}'),
('\u{70f}', '\u{70f}'),
+ ('\u{890}', '\u{891}'),
('\u{8e2}', '\u{8e2}'),
('\u{110bd}', '\u{110bd}'),
('\u{110cd}', '\u{110cd}'),
];
pub const QUOTATION_MARK: &'static [(char, char)] = &[
- ('\"', '\"'),
+ ('"', '"'),
('\'', '\''),
('«', '«'),
('»', '»'),
@@ -8682,7 +8916,7 @@ pub const SENTENCE_TERMINAL: &'static [(char, char)] = &[
('.', '.'),
('?', '?'),
('Ö‰', 'Ö‰'),
- ('Øž', 'ØŸ'),
+ ('Ø', 'ØŸ'),
('Û”', 'Û”'),
('Ü€', 'Ü‚'),
('ß¹', 'ß¹'),
@@ -8701,12 +8935,14 @@ pub const SENTENCE_TERMINAL: &'static [(char, char)] = &[
('᪨', '᪫'),
('á­š', 'á­›'),
('á­ž', 'á­Ÿ'),
+ ('á­½', 'á­¾'),
('á°»', 'á°¼'),
('᱾', '᱿'),
('‼', '‽'),
('â‡', 'â‰'),
('⸮', '⸮'),
('⸼', '⸼'),
+ ('⹓', '⹔'),
('。', '。'),
('ê“¿', 'ê“¿'),
('꘎', 'ê˜'),
@@ -8727,6 +8963,7 @@ pub const SENTENCE_TERMINAL: &'static [(char, char)] = &[
('。', '。'),
('ð©–', 'ð©—'),
('ð½•', 'ð½™'),
+ ('ð¾†', 'ð¾‰'),
('ð‘‡', 'ð‘ˆ'),
('ð‘‚¾', 'ð‘ƒ'),
('ð‘…', 'ð‘…ƒ'),
@@ -8741,8 +8978,8 @@ pub const SENTENCE_TERMINAL: &'static [(char, char)] = &[
('ð‘—‰', 'ð‘——'),
('ð‘™', 'ð‘™‚'),
('𑜼', '𑜾'),
- ('\u{11944}', '\u{11944}'),
- ('\u{11946}', '\u{11946}'),
+ ('𑥄', '𑥄'),
+ ('𑥆', '𑥆'),
('𑩂', '𑩃'),
('𑪛', '𑪜'),
('ð‘±', '𑱂'),
@@ -8788,6 +9025,7 @@ pub const SOFT_DOTTED: &'static [(char, char)] = &[
('ð˜ª', 'ð˜«'),
('ð™ž', 'ð™Ÿ'),
('ðš’', 'ðš“'),
+ ('ð¼š', 'ð¼š'),
];
pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
@@ -8802,7 +9040,7 @@ pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
('׃', '׃'),
('،', '،'),
('Ø›', 'Ø›'),
- ('Øž', 'ØŸ'),
+ ('Ø', 'ØŸ'),
('Û”', 'Û”'),
('Ü€', 'ÜŠ'),
('܌', '܌'),
@@ -8826,6 +9064,7 @@ pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
('᪨', '᪫'),
('á­š', 'á­›'),
('á­', 'á­Ÿ'),
+ ('á­½', 'á­¾'),
('á°»', 'á°¿'),
('᱾', '᱿'),
('‼', '‽'),
@@ -8835,6 +9074,7 @@ pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
('â¹', 'â¹'),
('⹌', '⹌'),
('⹎', 'â¹'),
+ ('⹓', '⹔'),
('ã€', '。'),
('꓾', '꓿'),
('ê˜', 'ê˜'),
@@ -8865,6 +9105,7 @@ pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
('ð¬º', 'ð¬¿'),
('ð®™', 'ð®œ'),
('ð½•', 'ð½™'),
+ ('ð¾†', 'ð¾‰'),
('ð‘‡', 'ð‘'),
('ð‘‚¾', 'ð‘ƒ'),
('ð‘…', 'ð‘…ƒ'),
@@ -8874,13 +9115,13 @@ pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
('𑈸', '𑈼'),
('ð‘Š©', 'ð‘Š©'),
('ð‘‘‹', 'ð‘‘'),
- ('\u{1145a}', 'ð‘‘›'),
+ ('ð‘‘š', 'ð‘‘›'),
('ð‘—‚', 'ð‘—…'),
('ð‘—‰', 'ð‘——'),
('ð‘™', 'ð‘™‚'),
('𑜼', '𑜾'),
- ('\u{11944}', '\u{11944}'),
- ('\u{11946}', '\u{11946}'),
+ ('𑥄', '𑥄'),
+ ('𑥆', '𑥆'),
('𑩂', '𑩃'),
('𑪛', '𑪜'),
('𑪡', '𑪢'),
@@ -8898,8 +9139,8 @@ pub const TERMINAL_PUNCTUATION: &'static [(char, char)] = &[
];
pub const UNIFIED_IDEOGRAPH: &'static [(char, char)] = &[
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
+ ('ã€', '䶿'),
+ ('一', '鿿'),
('﨎', 'ï¨'),
('﨑', '﨑'),
('﨓', '﨔'),
@@ -8907,12 +9148,12 @@ pub const UNIFIED_IDEOGRAPH: &'static [(char, char)] = &[
('﨡', '﨡'),
('﨣', '﨤'),
('﨧', '﨩'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const UPPERCASE: &'static [(char, char)] = &[
@@ -9349,7 +9590,7 @@ pub const UPPERCASE: &'static [(char, char)] = &[
('â… ', 'â…¯'),
('Ↄ', 'Ↄ'),
('â’¶', 'â“'),
- ('â°€', 'â°®'),
+ ('â°€', 'â°¯'),
('â± ', 'â± '),
('Ɫ', 'Ɽ'),
('Ⱨ', 'Ⱨ'),
@@ -9514,13 +9755,21 @@ pub const UPPERCASE: &'static [(char, char)] = &[
('Ꞻ', 'Ꞻ'),
('êž¼', 'êž¼'),
('êž¾', 'êž¾'),
+ ('Ꟁ', 'Ꟁ'),
('Ꟃ', 'Ꟃ'),
- ('Ꞔ', '\u{a7c7}'),
- ('\u{a7c9}', '\u{a7c9}'),
- ('\u{a7f5}', '\u{a7f5}'),
+ ('Ꞔ', 'Ꟈ'),
+ ('Ꟊ', 'Ꟊ'),
+ ('êŸ', 'êŸ'),
+ ('Ꟗ', 'Ꟗ'),
+ ('Ꟙ', 'Ꟙ'),
+ ('Ꟶ', 'Ꟶ'),
('A', 'Z'),
('ð€', 'ð§'),
('ð’°', 'ð““'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
('ð²€', 'ð²²'),
('𑢠', '𑢿'),
('𖹀', '𖹟'),
@@ -9563,6 +9812,7 @@ pub const UPPERCASE: &'static [(char, char)] = &[
pub const VARIATION_SELECTOR: &'static [(char, char)] = &[
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{fe00}', '\u{fe0f}'),
('\u{e0100}', '\u{e01ef}'),
];
@@ -9632,9 +9882,9 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('à €', '\u{82d}'),
('à¡€', '\u{85b}'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('\u{898}', '\u{8e1}'),
('\u{8e3}', '\u{963}'),
('०', '९'),
('ॱ', 'ঃ'),
@@ -9718,11 +9968,12 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('à°Ž', 'à°'),
('à°’', 'à°¨'),
('à°ª', 'à°¹'),
- ('ఽ', 'ౄ'),
+ ('\u{c3c}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
('\u{c55}', '\u{c56}'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('à± ', '\u{c63}'),
('౦', '౯'),
('ಀ', 'ಃ'),
@@ -9735,7 +9986,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('\u{cc6}', 'ೈ'),
('ೊ', '\u{ccd}'),
('\u{cd5}', '\u{cd6}'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('à³ ', '\u{ce3}'),
('೦', '೯'),
('à³±', 'à³²'),
@@ -9818,9 +10069,8 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', '\u{1714}'),
- ('ᜠ', '\u{1734}'),
+ ('ᜀ', '᜕'),
+ ('ᜟ', '᜴'),
('á€', '\u{1753}'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -9830,7 +10080,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('ៜ', '\u{17dd}'),
('០', '៩'),
('\u{180b}', '\u{180d}'),
- ('á ', 'á ™'),
+ ('\u{180f}', 'á ™'),
('ᠠ', 'ᡸ'),
('ᢀ', 'ᢪ'),
('ᢰ', 'ᣵ'),
@@ -9849,8 +10099,8 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('áª', '᪙'),
('ᪧ', 'ᪧ'),
('\u{1ab0}', '\u{1abd}'),
- ('\u{1abf}', '\u{1ac0}'),
- ('\u{1b00}', 'á­‹'),
+ ('\u{1abf}', '\u{1ace}'),
+ ('\u{1b00}', 'ᭌ'),
('á­', 'á­™'),
('\u{1b6b}', '\u{1b73}'),
('\u{1b80}', '᯳'),
@@ -9862,8 +10112,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('Ჽ', 'Ჿ'),
('\u{1cd0}', '\u{1cd2}'),
('\u{1cd4}', 'ᳺ'),
- ('á´€', '\u{1df9}'),
- ('\u{1dfb}', 'ἕ'),
+ ('ᴀ', 'ἕ'),
('Ἐ', 'á¼'),
('á¼ ', 'á½…'),
('Ὀ', 'á½'),
@@ -9903,9 +10152,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('â……', 'â…‰'),
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳳ'),
('â´€', 'â´¥'),
('â´§', 'â´§'),
@@ -9933,11 +10180,10 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘫ'),
@@ -9946,9 +10192,11 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('ꙿ', '\u{a6f1}'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê §'),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꠧ'),
('\u{a82c}', '\u{a82c}'),
('ꡀ', 'ꡳ'),
('ꢀ', '\u{a8c5}'),
@@ -9975,7 +10223,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯪ'),
('꯬', '\u{abed}'),
('꯰', '꯹'),
@@ -10043,9 +10291,20 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -10080,27 +10339,29 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('ð³€', 'ð³²'),
('ð´€', '\u{10d27}'),
('ð´°', 'ð´¹'),
- ('\u{10e80}', '\u{10ea9}'),
+ ('ðº€', 'ðº©'),
('\u{10eab}', '\u{10eac}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', '\u{10f50}'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', '\u{10f85}'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('ð‘€€', '\u{11046}'),
- ('ð‘¦', 'ð‘¯'),
+ ('ð‘¦', 'ð‘µ'),
('\u{1107f}', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('ð‘ƒ', '𑃨'),
('𑃰', '𑃹'),
('\u{11100}', '\u{11134}'),
('𑄶', '𑄿'),
- ('ð‘…„', '\u{11147}'),
+ ('ð‘…„', 'ð‘…‡'),
('ð‘…', '\u{11173}'),
('ð‘…¶', 'ð‘…¶'),
('\u{11180}', '𑇄'),
('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '𑇚'),
+ ('𑇎', '𑇚'),
('𑇜', '𑇜'),
('𑈀', '𑈑'),
('𑈓', '\u{11237}'),
@@ -10129,7 +10390,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('\u{11370}', '\u{11374}'),
('ð‘€', 'ð‘‘Š'),
('ð‘‘', 'ð‘‘™'),
- ('\u{1145e}', '\u{11461}'),
+ ('\u{1145e}', 'ð‘‘¡'),
('ð‘’€', 'ð‘“…'),
('𑓇', '𑓇'),
('ð‘“', 'ð‘“™'),
@@ -10144,16 +10405,17 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('𑜀', '𑜚'),
('\u{1171d}', '\u{1172b}'),
('𑜰', '𑜹'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', '\u{1183a}'),
('𑢠', '𑣩'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{11943}'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('𑦠', '𑦧'),
('𑦪', '\u{119d7}'),
('\u{119da}', '𑧡'),
@@ -10162,7 +10424,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('\u{11a47}', '\u{11a47}'),
('ð‘©', '\u{11a99}'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', '\u{11c36}'),
('\u{11c38}', '𑱀'),
@@ -10184,15 +10446,18 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('𑶓', '𑶘'),
('𑶠', '𑶩'),
('𑻠', '𑻶'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
('ð–© ', 'ð–©©'),
+ ('𖩰', '𖪾'),
+ ('𖫀', '𖫉'),
('ð–«', 'ð–«­'),
('\u{16af0}', '\u{16af4}'),
('𖬀', '\u{16b36}'),
@@ -10206,11 +10471,14 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('\u{16f8f}', '𖾟'),
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -10219,6 +10487,8 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('𛲀', '𛲈'),
('ð›²', '𛲙'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
@@ -10262,6 +10532,7 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('\u{1da84}', '\u{1da84}'),
('\u{1da9b}', '\u{1da9f}'),
('\u{1daa1}', '\u{1daaf}'),
+ ('ð¼€', 'ð¼ž'),
('\u{1e000}', '\u{1e006}'),
('\u{1e008}', '\u{1e018}'),
('\u{1e01b}', '\u{1e021}'),
@@ -10271,7 +10542,12 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('\u{1e130}', '𞄽'),
('ðž…€', 'ðž…‰'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '\u{1e2ae}'),
('𞋀', '𞋹'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('\u{1e8d0}', '\u{1e8d6}'),
('𞤀', '𞥋'),
@@ -10309,14 +10585,14 @@ pub const XID_CONTINUE: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('\u{1fbf0}', '\u{1fbf9}'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('🯰', '🯹'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
('\u{e0100}', '\u{e01ef}'),
];
@@ -10370,8 +10646,9 @@ pub const XID_START: &'static [(char, char)] = &[
('à ¨', 'à ¨'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('ऄ', 'ह'),
('ऽ', 'ऽ'),
('à¥', 'à¥'),
@@ -10436,6 +10713,7 @@ pub const XID_START: &'static [(char, char)] = &[
('à°ª', 'à°¹'),
('à°½', 'à°½'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('ಀ', 'ಀ'),
('ಅ', 'ಌ'),
@@ -10444,10 +10722,10 @@ pub const XID_START: &'static [(char, char)] = &[
('ಪ', 'ಳ'),
('ವ', 'ಹ'),
('ಽ', 'ಽ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('à³±', 'à³²'),
- ('\u{d04}', 'ഌ'),
+ ('ഄ', 'ഌ'),
('à´Ž', 'à´'),
('à´’', 'à´º'),
('à´½', 'à´½'),
@@ -10515,9 +10793,8 @@ pub const XID_START: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
+ ('ᜀ', 'ᜑ'),
+ ('ᜟ', 'ᜱ'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -10537,7 +10814,7 @@ pub const XID_START: &'static [(char, char)] = &[
('ᨠ', 'ᩔ'),
('ᪧ', 'ᪧ'),
('ᬅ', 'ᬳ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('ᮃ', 'ᮠ'),
('ᮮ', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -10587,9 +10864,7 @@ pub const XID_START: &'static [(char, char)] = &[
('â……', 'â…‰'),
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
('â´€', 'â´¥'),
@@ -10616,11 +10891,10 @@ pub const XID_START: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘟ'),
@@ -10630,9 +10904,11 @@ pub const XID_START: &'static [(char, char)] = &[
('ꚠ', 'ꛯ'),
('ꜗ', 'ꜟ'),
('Ꜣ', 'ꞈ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê '),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ê '),
('ê ƒ', 'ê …'),
('ê ‡', 'ê Š'),
('ꠌ', 'ꠢ'),
@@ -10669,7 +10945,7 @@ pub const XID_START: &'static [(char, char)] = &[
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab69}'),
+ ('ꭜ', 'ꭩ'),
('ꭰ', 'ꯢ'),
('가', '힣'),
('ힰ', 'ퟆ'),
@@ -10728,9 +11004,20 @@ pub const XID_START: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -10761,19 +11048,22 @@ pub const XID_START: &'static [(char, char)] = &[
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('ð´€', 'ð´£'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('𑀃', '𑀷'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('𑂃', '𑂯'),
('ð‘ƒ', '𑃨'),
('𑄃', '𑄦'),
('ð‘…„', 'ð‘…„'),
- ('\u{11147}', '\u{11147}'),
+ ('ð‘…‡', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('𑆃', '𑆲'),
@@ -10799,7 +11089,7 @@ pub const XID_START: &'static [(char, char)] = &[
('ð‘', 'ð‘¡'),
('ð‘€', 'ð‘´'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -10810,15 +11100,16 @@ pub const XID_START: &'static [(char, char)] = &[
('𑚀', '𑚪'),
('𑚸', '𑚸'),
('𑜀', '𑜚'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', 'ð‘ «'),
('𑢠', '𑣟'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑦠', '𑦧'),
('𑦪', 'ð‘§'),
('𑧡', '𑧡'),
@@ -10829,7 +11120,7 @@ pub const XID_START: &'static [(char, char)] = &[
('ð‘©', 'ð‘©'),
('𑩜', '𑪉'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°®'),
('𑱀', '𑱀'),
@@ -10843,14 +11134,16 @@ pub const XID_START: &'static [(char, char)] = &[
('𑵪', '𑶉'),
('𑶘', '𑶘'),
('ð‘» ', 'ð‘»²'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­€', 'ð–­ƒ'),
@@ -10863,9 +11156,12 @@ pub const XID_START: &'static [(char, char)] = &[
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', 'ð–¿£'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -10903,10 +11199,16 @@ pub const XID_START: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼ž'),
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞤀', '𞥃'),
('𞥋', '𞥋'),
@@ -10943,11 +11245,11 @@ pub const XID_START: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
diff --git a/vendor/regex-syntax/src/unicode_tables/property_names.rs b/vendor/regex-syntax/src/unicode_tables/property_names.rs
index 6393df2f8..3fce1bf03 100644
--- a/vendor/regex-syntax/src/unicode_tables/property_names.rs
+++ b/vendor/regex-syntax/src/unicode_tables/property_names.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate property-names ucd-13.0.0
+// ucd-generate property-names /tmp/ucd
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const PROPERTY_NAMES: &'static [(&'static str, &'static str)] = &[
("age", "Age"),
diff --git a/vendor/regex-syntax/src/unicode_tables/property_values.rs b/vendor/regex-syntax/src/unicode_tables/property_values.rs
index c46653a7b..08a91477b 100644
--- a/vendor/regex-syntax/src/unicode_tables/property_values.rs
+++ b/vendor/regex-syntax/src/unicode_tables/property_values.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate property-values ucd-13.0.0 --include gc,script,scx,age,gcb,wb,sb
+// ucd-generate property-values /tmp/ucd --include gc,script,scx,age,gcb,wb,sb
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const PROPERTY_VALUES: &'static [(
&'static str,
@@ -19,6 +19,7 @@ pub const PROPERTY_VALUES: &'static [(
("12.0", "V12_0"),
("12.1", "V12_1"),
("13.0", "V13_0"),
+ ("14.0", "V14_0"),
("2.0", "V2_0"),
("2.1", "V2_1"),
("3.0", "V3_0"),
@@ -44,6 +45,7 @@ pub const PROPERTY_VALUES: &'static [(
("v120", "V12_0"),
("v121", "V12_1"),
("v130", "V13_0"),
+ ("v140", "V14_0"),
("v20", "V2_0"),
("v21", "V2_1"),
("v30", "V3_0"),
@@ -233,9 +235,11 @@ pub const PROPERTY_VALUES: &'static [(
("common", "Common"),
("copt", "Coptic"),
("coptic", "Coptic"),
+ ("cpmn", "Cypro_Minoan"),
("cprt", "Cypriot"),
("cuneiform", "Cuneiform"),
("cypriot", "Cypriot"),
+ ("cyprominoan", "Cypro_Minoan"),
("cyrillic", "Cyrillic"),
("cyrl", "Cyrillic"),
("deseret", "Deseret"),
@@ -391,6 +395,7 @@ pub const PROPERTY_VALUES: &'static [(
("oldsogdian", "Old_Sogdian"),
("oldsoutharabian", "Old_South_Arabian"),
("oldturkic", "Old_Turkic"),
+ ("olduyghur", "Old_Uyghur"),
("oriya", "Oriya"),
("orkh", "Old_Turkic"),
("orya", "Oriya"),
@@ -398,6 +403,7 @@ pub const PROPERTY_VALUES: &'static [(
("osge", "Osage"),
("osma", "Osmanya"),
("osmanya", "Osmanya"),
+ ("ougr", "Old_Uyghur"),
("pahawhhmong", "Pahawh_Hmong"),
("palm", "Palmyrene"),
("palmyrene", "Palmyrene"),
@@ -462,6 +468,7 @@ pub const PROPERTY_VALUES: &'static [(
("tamil", "Tamil"),
("taml", "Tamil"),
("tang", "Tangut"),
+ ("tangsa", "Tangsa"),
("tangut", "Tangut"),
("tavt", "Tai_Viet"),
("telu", "Telugu"),
@@ -476,11 +483,15 @@ pub const PROPERTY_VALUES: &'static [(
("tifinagh", "Tifinagh"),
("tirh", "Tirhuta"),
("tirhuta", "Tirhuta"),
+ ("tnsa", "Tangsa"),
+ ("toto", "Toto"),
("ugar", "Ugaritic"),
("ugaritic", "Ugaritic"),
("unknown", "Unknown"),
("vai", "Vai"),
("vaii", "Vai"),
+ ("vith", "Vithkuqi"),
+ ("vithkuqi", "Vithkuqi"),
("wancho", "Wancho"),
("wara", "Warang_Citi"),
("warangciti", "Warang_Citi"),
@@ -550,9 +561,11 @@ pub const PROPERTY_VALUES: &'static [(
("common", "Common"),
("copt", "Coptic"),
("coptic", "Coptic"),
+ ("cpmn", "Cypro_Minoan"),
("cprt", "Cypriot"),
("cuneiform", "Cuneiform"),
("cypriot", "Cypriot"),
+ ("cyprominoan", "Cypro_Minoan"),
("cyrillic", "Cyrillic"),
("cyrl", "Cyrillic"),
("deseret", "Deseret"),
@@ -708,6 +721,7 @@ pub const PROPERTY_VALUES: &'static [(
("oldsogdian", "Old_Sogdian"),
("oldsoutharabian", "Old_South_Arabian"),
("oldturkic", "Old_Turkic"),
+ ("olduyghur", "Old_Uyghur"),
("oriya", "Oriya"),
("orkh", "Old_Turkic"),
("orya", "Oriya"),
@@ -715,6 +729,7 @@ pub const PROPERTY_VALUES: &'static [(
("osge", "Osage"),
("osma", "Osmanya"),
("osmanya", "Osmanya"),
+ ("ougr", "Old_Uyghur"),
("pahawhhmong", "Pahawh_Hmong"),
("palm", "Palmyrene"),
("palmyrene", "Palmyrene"),
@@ -779,6 +794,7 @@ pub const PROPERTY_VALUES: &'static [(
("tamil", "Tamil"),
("taml", "Tamil"),
("tang", "Tangut"),
+ ("tangsa", "Tangsa"),
("tangut", "Tangut"),
("tavt", "Tai_Viet"),
("telu", "Telugu"),
@@ -793,11 +809,15 @@ pub const PROPERTY_VALUES: &'static [(
("tifinagh", "Tifinagh"),
("tirh", "Tirhuta"),
("tirhuta", "Tirhuta"),
+ ("tnsa", "Tangsa"),
+ ("toto", "Toto"),
("ugar", "Ugaritic"),
("ugaritic", "Ugaritic"),
("unknown", "Unknown"),
("vai", "Vai"),
("vaii", "Vai"),
+ ("vith", "Vithkuqi"),
+ ("vithkuqi", "Vithkuqi"),
("wancho", "Wancho"),
("wara", "Warang_Citi"),
("warangciti", "Warang_Citi"),
diff --git a/vendor/regex-syntax/src/unicode_tables/script.rs b/vendor/regex-syntax/src/unicode_tables/script.rs
index cd86cba0d..3327b76ae 100644
--- a/vendor/regex-syntax/src/unicode_tables/script.rs
+++ b/vendor/regex-syntax/src/unicode_tables/script.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate script ucd-13.0.0 --chars
+// ucd-generate script /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Adlam", ADLAM),
@@ -35,6 +35,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Coptic", COPTIC),
("Cuneiform", CUNEIFORM),
("Cypriot", CYPRIOT),
+ ("Cypro_Minoan", CYPRO_MINOAN),
("Cyrillic", CYRILLIC),
("Deseret", DESERET),
("Devanagari", DEVANAGARI),
@@ -118,6 +119,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Old_Sogdian", OLD_SOGDIAN),
("Old_South_Arabian", OLD_SOUTH_ARABIAN),
("Old_Turkic", OLD_TURKIC),
+ ("Old_Uyghur", OLD_UYGHUR),
("Oriya", ORIYA),
("Osage", OSAGE),
("Osmanya", OSMANYA),
@@ -149,6 +151,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Tai_Viet", TAI_VIET),
("Takri", TAKRI),
("Tamil", TAMIL),
+ ("Tangsa", TANGSA),
("Tangut", TANGUT),
("Telugu", TELUGU),
("Thaana", THAANA),
@@ -156,8 +159,10 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Tibetan", TIBETAN),
("Tifinagh", TIFINAGH),
("Tirhuta", TIRHUTA),
+ ("Toto", TOTO),
("Ugaritic", UGARITIC),
("Vai", VAI),
+ ("Vithkuqi", VITHKUQI),
("Wancho", WANCHO),
("Warang_Citi", WARANG_CITI),
("Yezidi", YEZIDI),
@@ -169,7 +174,7 @@ pub const ADLAM: &'static [(char, char)] =
&[('𞤀', '𞥋'), ('ðž¥', '𞥙'), ('𞥞', '𞥟')];
pub const AHOM: &'static [(char, char)] =
- &[('𑜀', '𑜚'), ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜿')];
+ &[('𑜀', '𑜚'), ('\u{1171d}', '\u{1172b}'), ('𑜰', 'ð‘†')];
pub const ANATOLIAN_HIEROGLYPHS: &'static [(char, char)] = &[('ð”€', '𔙆')];
@@ -177,23 +182,23 @@ pub const ARABIC: &'static [(char, char)] = &[
('\u{600}', '\u{604}'),
('؆', '؋'),
('Ø', '\u{61a}'),
- ('\u{61c}', '\u{61c}'),
- ('Øž', 'Øž'),
+ ('\u{61c}', 'Øž'),
('Ø ', 'Ø¿'),
('Ù', 'ÙŠ'),
('\u{656}', 'Ù¯'),
('Ù±', '\u{6dc}'),
('Ûž', 'Û¿'),
('Ý', 'Ý¿'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('ࡰ', 'ࢎ'),
+ ('\u{890}', '\u{891}'),
+ ('\u{898}', '\u{8e1}'),
('\u{8e3}', '\u{8ff}'),
- ('ï­', 'ï¯'),
+ ('ï­', '﯂'),
('ﯓ', 'ﴽ'),
- ('ïµ', 'ï¶'),
+ ('ïµ€', 'ï¶'),
('ﶒ', 'ﷇ'),
- ('ï·°', 'ï·½'),
+ ('ï·', 'ï·'),
+ ('ï·°', 'ï·¿'),
('ï¹°', 'ï¹´'),
('ﹶ', 'ﻼ'),
('ð¹ ', 'ð¹¾'),
@@ -238,7 +243,7 @@ pub const ARMENIAN: &'static [(char, char)] =
pub const AVESTAN: &'static [(char, char)] = &[('ð¬€', 'ð¬µ'), ('ð¬¹', 'ð¬¿')];
-pub const BALINESE: &'static [(char, char)] = &[('\u{1b00}', 'á­‹'), ('á­', 'á­¼')];
+pub const BALINESE: &'static [(char, char)] = &[('\u{1b00}', 'á­Œ'), ('á­', 'á­¾')];
pub const BAMUM: &'static [(char, char)] = &[('ꚠ', '꛷'), ('𖠀', '𖨸')];
@@ -268,10 +273,10 @@ pub const BHAIKSUKI: &'static [(char, char)] =
&[('ð‘°€', 'ð‘°ˆ'), ('ð‘°Š', '\u{11c36}'), ('\u{11c38}', '𑱅'), ('ð‘±', '𑱬')];
pub const BOPOMOFO: &'static [(char, char)] =
- &[('˪', '˫'), ('ㄅ', 'ㄯ'), ('ㆠ', '\u{31bf}')];
+ &[('˪', '˫'), ('ㄅ', 'ㄯ'), ('ㆠ', 'ㆿ')];
pub const BRAHMI: &'static [(char, char)] =
- &[('ð‘€€', 'ð‘'), ('ð‘’', 'ð‘¯'), ('\u{1107f}', '\u{1107f}')];
+ &[('ð‘€€', 'ð‘'), ('ð‘’', 'ð‘µ'), ('\u{1107f}', '\u{1107f}')];
pub const BRAILLE: &'static [(char, char)] = &[('⠀', '⣿')];
@@ -280,7 +285,7 @@ pub const BUGINESE: &'static [(char, char)] = &[('ᨀ', '\u{1a1b}'), ('᨞', 'á¨
pub const BUHID: &'static [(char, char)] = &[('á€', '\u{1753}')];
pub const CANADIAN_ABORIGINAL: &'static [(char, char)] =
- &[('á€', 'ᙿ'), ('ᢰ', 'ᣵ')];
+ &[('á€', 'ᙿ'), ('ᢰ', 'ᣵ'), ('𑪰', '𑪿')];
pub const CARIAN: &'static [(char, char)] = &[('ðŠ ', 'ð‹')];
@@ -288,7 +293,7 @@ pub const CAUCASIAN_ALBANIAN: &'static [(char, char)] =
&[('ð”°', 'ð•£'), ('ð•¯', 'ð•¯')];
pub const CHAKMA: &'static [(char, char)] =
- &[('\u{11100}', '\u{11134}'), ('𑄶', '\u{11147}')];
+ &[('\u{11100}', '\u{11134}'), ('𑄶', '𑅇')];
pub const CHAM: &'static [(char, char)] =
&[('ꨀ', '\u{aa36}'), ('ê©€', 'ê©'), ('ê©', 'ê©™'), ('ê©œ', 'ê©Ÿ')];
@@ -296,10 +301,10 @@ pub const CHAM: &'static [(char, char)] =
pub const CHEROKEE: &'static [(char, char)] =
&[('Ꭰ', 'áµ'), ('á¸', 'á½'), ('ê­°', 'ꮿ')];
-pub const CHORASMIAN: &'static [(char, char)] = &[('\u{10fb0}', '\u{10fcb}')];
+pub const CHORASMIAN: &'static [(char, char)] = &[('ð¾°', 'ð¿‹')];
pub const COMMON: &'static [(char, char)] = &[
- ('\u{0}', '@'),
+ ('\0', '@'),
('[', '`'),
('{', '©'),
('«', '¹'),
@@ -339,7 +344,7 @@ pub const COMMON: &'static [(char, char)] = &[
('\u{2066}', 'â°'),
('â´', 'â¾'),
('â‚€', 'â‚Ž'),
- ('â‚ ', 'â‚¿'),
+ ('₠', '⃀'),
('â„€', 'â„¥'),
('℧', '℩'),
('ℬ', 'ℱ'),
@@ -351,8 +356,8 @@ pub const COMMON: &'static [(char, char)] = &[
('①', '⟿'),
('⤀', '⭳'),
('⭶', '⮕'),
- ('\u{2b97}', '⯿'),
- ('⸀', '\u{2e52}'),
+ ('⮗', '⯿'),
+ ('⸀', 'â¹'),
('â¿°', 'â¿»'),
('\u{3000}', '〄'),
('〆', '〆'),
@@ -375,7 +380,7 @@ pub const COMMON: &'static [(char, char)] = &[
('꤮', '꤮'),
('ê§', 'ê§'),
('ê­›', 'ê­›'),
- ('\u{ab6a}', '\u{ab6b}'),
+ ('ê­ª', 'ê­«'),
('ï´¾', 'ï´¿'),
('ï¸', '︙'),
('︰', '﹒'),
@@ -393,18 +398,18 @@ pub const COMMON: &'static [(char, char)] = &[
('ð„€', 'ð„‚'),
('ð„‡', 'ð„³'),
('ð„·', 'ð„¿'),
- ('ð†', '\u{1019c}'),
+ ('ð†', 'ð†œ'),
('ð‡', 'ð‡¼'),
('ð‹¡', 'ð‹»'),
- ('ð–¿¢', 'ð–¿£'),
('\u{1bca0}', '\u{1bca3}'),
+ ('ðœ½', '𜿃'),
('ð€€', 'ðƒµ'),
('ð„€', 'ð„¦'),
('ð„©', 'ð…¦'),
('ð…ª', '\u{1d17a}'),
('ð†ƒ', 'ð†„'),
('ð†Œ', 'ð†©'),
- ('ð†®', 'ð‡¨'),
+ ('ð†®', 'ð‡ª'),
('ð‹ ', 'ð‹³'),
('ðŒ€', 'ð–'),
('ð ', 'ð¸'),
@@ -437,39 +442,40 @@ pub const COMMON: &'static [(char, char)] = &[
('🂱', '🂿'),
('ðŸƒ', 'ðŸƒ'),
('🃑', '🃵'),
- ('🄀', '\u{1f1ad}'),
+ ('🄀', '🆭'),
('🇦', '🇿'),
('ðŸˆ', '🈂'),
('ðŸˆ', '🈻'),
('🉀', '🉈'),
('ðŸ‰', '🉑'),
('🉠', '🉥'),
- ('🌀', '\u{1f6d7}'),
- ('🛠', '🛬'),
- ('🛰', '\u{1f6fc}'),
+ ('🌀', '🛗'),
+ ('ðŸ›', '🛬'),
+ ('🛰', '🛼'),
('🜀', 'ðŸ³'),
('🞀', '🟘'),
('🟠', '🟫'),
+ ('🟰', '🟰'),
('🠀', '🠋'),
('ðŸ ', '🡇'),
('ðŸ¡', '🡙'),
('🡠', '🢇'),
('ðŸ¢', '🢭'),
- ('\u{1f8b0}', '\u{1f8b1}'),
- ('🤀', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🩓'),
+ ('🢰', '🢱'),
+ ('🤀', '🩓'),
('🩠', '🩭'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
- ('\u{1fb00}', '\u{1fb92}'),
- ('\u{1fb94}', '\u{1fbca}'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
+ ('🬀', '🮒'),
+ ('🮔', '🯊'),
+ ('🯰', '🯹'),
('\u{e0001}', '\u{e0001}'),
('\u{e0020}', '\u{e007f}'),
];
@@ -483,6 +489,8 @@ pub const CUNEIFORM: &'static [(char, char)] =
pub const CYPRIOT: &'static [(char, char)] =
&[('ð €', 'ð …'), ('ð ˆ', 'ð ˆ'), ('ð Š', 'ð µ'), ('ð ·', 'ð ¸'), ('ð ¼', 'ð ¼'), ('ð ¿', 'ð ¿')];
+pub const CYPRO_MINOAN: &'static [(char, char)] = &[('ð’¾', 'ð’¿²')];
+
pub const CYRILLIC: &'static [(char, char)] = &[
('Ѐ', '\u{484}'),
('\u{487}', 'Ô¯'),
@@ -504,14 +512,14 @@ pub const DEVANAGARI: &'static [(char, char)] = &[
];
pub const DIVES_AKURU: &'static [(char, char)] = &[
- ('\u{11900}', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
- ('\u{1193b}', '\u{11946}'),
- ('\u{11950}', '\u{11959}'),
+ ('𑤀', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
+ ('\u{1193b}', '𑥆'),
+ ('ð‘¥', 'ð‘¥™'),
];
pub const DOGRA: &'static [(char, char)] = &[('ð‘ €', 'ð‘ »')];
@@ -559,6 +567,10 @@ pub const ETHIOPIC: &'static [(char, char)] = &[
('ꬑ', 'ꬖ'),
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
];
pub const GEORGIAN: &'static [(char, char)] = &[
@@ -575,8 +587,7 @@ pub const GEORGIAN: &'static [(char, char)] = &[
];
pub const GLAGOLITIC: &'static [(char, char)] = &[
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
+ ('Ⰰ', 'ⱟ'),
('\u{1e000}', '\u{1e006}'),
('\u{1e008}', '\u{1e018}'),
('\u{1e01b}', '\u{1e021}'),
@@ -696,18 +707,19 @@ pub const HAN: &'static [(char, char)] = &[
('〇', '〇'),
('〡', '〩'),
('〸', '〻'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
+ ('ã€', '䶿'),
+ ('一', '鿿'),
('豈', '舘'),
('ï©°', 'ï«™'),
- ('\u{16ff0}', '\u{16ff1}'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('ð–¿¢', 'ð–¿£'),
+ ('ð–¿°', 'ð–¿±'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const HANGUL: &'static [(char, char)] = &[
@@ -730,7 +742,7 @@ pub const HANGUL: &'static [(char, char)] = &[
pub const HANIFI_ROHINGYA: &'static [(char, char)] =
&[('ð´€', '\u{10d27}'), ('ð´°', 'ð´¹')];
-pub const HANUNOO: &'static [(char, char)] = &[('ᜠ', '\u{1734}')];
+pub const HANUNOO: &'static [(char, char)] = &[('ᜠ', '᜴')];
pub const HATRAN: &'static [(char, char)] =
&[('ð£ ', 'ð£²'), ('ð£´', 'ð£µ'), ('ð£»', 'ð£¿')];
@@ -748,7 +760,7 @@ pub const HEBREW: &'static [(char, char)] = &[
];
pub const HIRAGANA: &'static [(char, char)] =
- &[('ã', 'ã‚–'), ('ã‚', 'ã‚Ÿ'), ('ð›€', '𛄞'), ('ð›…', 'ð›…’'), ('🈀', '🈀')];
+ &[('ã', 'ã‚–'), ('ã‚', 'ã‚Ÿ'), ('ð›€', '𛄟'), ('ð›…', 'ð›…’'), ('🈀', '🈀')];
pub const IMPERIAL_ARAMAIC: &'static [(char, char)] =
&[('ð¡€', 'ð¡•'), ('ð¡—', 'ð¡Ÿ')];
@@ -759,15 +771,14 @@ pub const INHERITED: &'static [(char, char)] = &[
('\u{64b}', '\u{655}'),
('\u{670}', '\u{670}'),
('\u{951}', '\u{954}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1cd0}', '\u{1cd2}'),
('\u{1cd4}', '\u{1ce0}'),
('\u{1ce2}', '\u{1ce8}'),
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('\u{1cf8}', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{200c}', '\u{200d}'),
('\u{20d0}', '\u{20f0}'),
('\u{302a}', '\u{302d}'),
@@ -777,6 +788,8 @@ pub const INHERITED: &'static [(char, char)] = &[
('\u{101fd}', '\u{101fd}'),
('\u{102e0}', '\u{102e0}'),
('\u{1133b}', '\u{1133b}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d167}', '\u{1d169}'),
('\u{1d17b}', '\u{1d182}'),
('\u{1d185}', '\u{1d18b}'),
@@ -794,7 +807,7 @@ pub const JAVANESE: &'static [(char, char)] =
&[('\u{a980}', 'ê§'), ('ê§', '꧙'), ('꧞', '꧟')];
pub const KAITHI: &'static [(char, char)] =
- &[('\u{11080}', 'ð‘ƒ'), ('\u{110cd}', '\u{110cd}')];
+ &[('\u{11080}', '\u{110c2}'), ('\u{110cd}', '\u{110cd}')];
pub const KANNADA: &'static [(char, char)] = &[
('ಀ', 'ಌ'),
@@ -806,7 +819,7 @@ pub const KANNADA: &'static [(char, char)] = &[
('\u{cc6}', 'ೈ'),
('ೊ', '\u{ccd}'),
('\u{cd5}', '\u{cd6}'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('à³ ', '\u{ce3}'),
('೦', '೯'),
('à³±', 'à³²'),
@@ -820,7 +833,11 @@ pub const KATAKANA: &'static [(char, char)] = &[
('㌀', 'ã—'),
('ヲ', 'ッ'),
('ï½±', 'ï¾'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
('𛀀', '𛀀'),
+ ('𛄠', '𛄢'),
('ð›…¤', 'ð›…§'),
];
@@ -838,7 +855,7 @@ pub const KHAROSHTHI: &'static [(char, char)] = &[
];
pub const KHITAN_SMALL_SCRIPT: &'static [(char, char)] =
- &[('\u{16fe4}', '\u{16fe4}'), ('\u{18b00}', '\u{18cd5}')];
+ &[('\u{16fe4}', '\u{16fe4}'), ('𘬀', '𘳕')];
pub const KHMER: &'static [(char, char)] =
&[('ក', '\u{17dd}'), ('០', '៩'), ('៰', '៹'), ('᧠', '᧿')];
@@ -886,15 +903,21 @@ pub const LATIN: &'static [(char, char)] = &[
('Ⅰ', 'ↈ'),
('Ⱡ', 'Ɀ'),
('Ꜣ', 'ꞇ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ꟿ'),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꟿ'),
('ꬰ', 'ꭚ'),
('ꭜ', 'ꭤ'),
- ('ê­¦', '\u{ab69}'),
+ ('ê­¦', 'ê­©'),
('ff', 'st'),
('A', 'Z'),
('ï½', 'z'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
+ ('ð¼€', 'ð¼ž'),
];
pub const LEPCHA: &'static [(char, char)] =
@@ -921,8 +944,7 @@ pub const LINEAR_B: &'static [(char, char)] = &[
('ð‚€', 'ðƒº'),
];
-pub const LISU: &'static [(char, char)] =
- &[('ê“', 'ê“¿'), ('\u{11fb0}', '\u{11fb0}')];
+pub const LISU: &'static [(char, char)] = &[('ê“', 'ê“¿'), ('𑾰', '𑾰')];
pub const LYCIAN: &'static [(char, char)] = &[('ðŠ€', 'ðŠœ')];
@@ -978,15 +1000,8 @@ pub const MIAO: &'static [(char, char)] =
pub const MODI: &'static [(char, char)] = &[('𑘀', 'ð‘™„'), ('ð‘™', 'ð‘™™')];
-pub const MONGOLIAN: &'static [(char, char)] = &[
- ('á €', 'á '),
- ('á „', 'á „'),
- ('á †', '\u{180e}'),
- ('á ', 'á ™'),
- ('ᠠ', 'ᡸ'),
- ('ᢀ', 'ᢪ'),
- ('𑙠', '𑙬'),
-];
+pub const MONGOLIAN: &'static [(char, char)] =
+ &[('á €', 'á '), ('á „', 'á „'), ('á †', 'á ™'), ('á  ', 'ᡸ'), ('ᢀ', 'ᢪ'), ('ð‘™ ', '𑙬')];
pub const MRO: &'static [(char, char)] = &[('𖩀', '𖩞'), ('𖩠', '𖩩'), ('𖩮', '𖩯')];
@@ -1004,7 +1019,7 @@ pub const NANDINAGARI: &'static [(char, char)] =
pub const NEW_TAI_LUE: &'static [(char, char)] =
&[('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('á§', '᧚'), ('᧞', '᧟')];
-pub const NEWA: &'static [(char, char)] = &[('ð‘€', 'ð‘‘›'), ('ð‘‘', '\u{11461}')];
+pub const NEWA: &'static [(char, char)] = &[('ð‘€', 'ð‘‘›'), ('ð‘‘', 'ð‘‘¡')];
pub const NKO: &'static [(char, char)] = &[('߀', 'ߺ'), ('\u{7fd}', '߿')];
@@ -1034,6 +1049,8 @@ pub const OLD_SOUTH_ARABIAN: &'static [(char, char)] = &[('ð© ', 'ð©¿')];
pub const OLD_TURKIC: &'static [(char, char)] = &[('ð°€', 'ð±ˆ')];
+pub const OLD_UYGHUR: &'static [(char, char)] = &[('ð½°', 'ð¾‰')];
+
pub const ORIYA: &'static [(char, char)] = &[
('\u{b01}', 'ଃ'),
('ଅ', 'ଌ'),
@@ -1118,7 +1135,7 @@ pub const SYLOTI_NAGRI: &'static [(char, char)] = &[('ê €', '\u{a82c}')];
pub const SYRIAC: &'static [(char, char)] =
&[('Ü€', 'Ü'), ('\u{70f}', '\u{74a}'), ('Ý', 'Ý'), ('à¡ ', 'ࡪ')];
-pub const TAGALOG: &'static [(char, char)] = &[('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}')];
+pub const TAGALOG: &'static [(char, char)] = &[('ᜀ', '᜕'), ('ᜟ', 'ᜟ')];
pub const TAGBANWA: &'static [(char, char)] =
&[('á ', 'á¬'), ('á®', 'á°'), ('\u{1772}', '\u{1773}')];
@@ -1135,7 +1152,7 @@ pub const TAI_THAM: &'static [(char, char)] = &[
pub const TAI_VIET: &'static [(char, char)] = &[('ꪀ', 'ꫂ'), ('ꫛ', '꫟')];
-pub const TAKRI: &'static [(char, char)] = &[('𑚀', '𑚸'), ('𑛀', '𑛉')];
+pub const TAKRI: &'static [(char, char)] = &[('𑚀', '𑚹'), ('𑛀', '𑛉')];
pub const TAMIL: &'static [(char, char)] = &[
('\u{b82}', 'ஃ'),
@@ -1158,23 +1175,22 @@ pub const TAMIL: &'static [(char, char)] = &[
('ð‘¿¿', 'ð‘¿¿'),
];
-pub const TANGUT: &'static [(char, char)] = &[
- ('ð–¿ ', 'ð–¿ '),
- ('𗀀', '𘟷'),
- ('𘠀', '\u{18aff}'),
- ('\u{18d00}', '\u{18d08}'),
-];
+pub const TANGSA: &'static [(char, char)] = &[('𖩰', '𖪾'), ('𖫀', '𖫉')];
+
+pub const TANGUT: &'static [(char, char)] =
+ &[('𖿠', '𖿠'), ('𗀀', '𘟷'), ('𘠀', '𘫿'), ('𘴀', '𘴈')];
pub const TELUGU: &'static [(char, char)] = &[
('\u{c00}', 'ఌ'),
('à°Ž', 'à°'),
('à°’', 'à°¨'),
('à°ª', 'à°¹'),
- ('ఽ', 'ౄ'),
+ ('\u{c3c}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
('\u{c55}', '\u{c56}'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('à± ', '\u{c63}'),
('౦', '౯'),
('౷', '౿'),
@@ -1199,19 +1215,29 @@ pub const TIFINAGH: &'static [(char, char)] =
pub const TIRHUTA: &'static [(char, char)] = &[('ð‘’€', '𑓇'), ('ð‘“', 'ð‘“™')];
+pub const TOTO: &'static [(char, char)] = &[('ðžŠ', '\u{1e2ae}')];
+
pub const UGARITIC: &'static [(char, char)] = &[('ðŽ€', 'ðŽ'), ('ðŽŸ', 'ðŽŸ')];
pub const VAI: &'static [(char, char)] = &[('ꔀ', 'ꘫ')];
+pub const VITHKUQI: &'static [(char, char)] = &[
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
+];
+
pub const WANCHO: &'static [(char, char)] = &[('𞋀', '𞋹'), ('𞋿', '𞋿')];
pub const WARANG_CITI: &'static [(char, char)] = &[('𑢠', '𑣲'), ('𑣿', '𑣿')];
-pub const YEZIDI: &'static [(char, char)] = &[
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eab}', '\u{10ead}'),
- ('\u{10eb0}', '\u{10eb1}'),
-];
+pub const YEZIDI: &'static [(char, char)] =
+ &[('ðº€', 'ðº©'), ('\u{10eab}', 'ðº­'), ('ðº°', 'ðº±')];
pub const YI: &'static [(char, char)] = &[('ꀀ', 'ê’Œ'), ('ê’', '꓆')];
diff --git a/vendor/regex-syntax/src/unicode_tables/script_extension.rs b/vendor/regex-syntax/src/unicode_tables/script_extension.rs
index 7fca2af9d..c970e0104 100644
--- a/vendor/regex-syntax/src/unicode_tables/script_extension.rs
+++ b/vendor/regex-syntax/src/unicode_tables/script_extension.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate script-extension ucd-13.0.0 --chars
+// ucd-generate script-extension /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Adlam", ADLAM),
@@ -35,6 +35,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Coptic", COPTIC),
("Cuneiform", CUNEIFORM),
("Cypriot", CYPRIOT),
+ ("Cypro_Minoan", CYPRO_MINOAN),
("Cyrillic", CYRILLIC),
("Deseret", DESERET),
("Devanagari", DEVANAGARI),
@@ -118,6 +119,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Old_Sogdian", OLD_SOGDIAN),
("Old_South_Arabian", OLD_SOUTH_ARABIAN),
("Old_Turkic", OLD_TURKIC),
+ ("Old_Uyghur", OLD_UYGHUR),
("Oriya", ORIYA),
("Osage", OSAGE),
("Osmanya", OSMANYA),
@@ -149,6 +151,7 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Tai_Viet", TAI_VIET),
("Takri", TAKRI),
("Tamil", TAMIL),
+ ("Tangsa", TANGSA),
("Tangut", TANGUT),
("Telugu", TELUGU),
("Thaana", THAANA),
@@ -156,8 +159,10 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("Tibetan", TIBETAN),
("Tifinagh", TIFINAGH),
("Tirhuta", TIRHUTA),
+ ("Toto", TOTO),
("Ugaritic", UGARITIC),
("Vai", VAI),
+ ("Vithkuqi", VITHKUQI),
("Wancho", WANCHO),
("Warang_Citi", WARANG_CITI),
("Yezidi", YEZIDI),
@@ -166,28 +171,27 @@ pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
];
pub const ADLAM: &'static [(char, char)] =
- &[('Ù€', 'Ù€'), ('𞤀', '𞥋'), ('ðž¥', '𞥙'), ('𞥞', '𞥟')];
+ &[('ØŸ', 'ØŸ'), ('Ù€', 'Ù€'), ('𞤀', '𞥋'), ('ðž¥', '𞥙'), ('𞥞', '𞥟')];
pub const AHOM: &'static [(char, char)] =
- &[('𑜀', '𑜚'), ('\u{1171d}', '\u{1172b}'), ('𑜰', '𑜿')];
+ &[('𑜀', '𑜚'), ('\u{1171d}', '\u{1172b}'), ('𑜰', 'ð‘†')];
pub const ANATOLIAN_HIEROGLYPHS: &'static [(char, char)] = &[('ð”€', '𔙆')];
pub const ARABIC: &'static [(char, char)] = &[
('\u{600}', '\u{604}'),
- ('؆', '\u{61c}'),
- ('Øž', '\u{6dc}'),
+ ('؆', '\u{6dc}'),
('Ûž', 'Û¿'),
('Ý', 'Ý¿'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('ࡰ', 'ࢎ'),
+ ('\u{890}', '\u{891}'),
+ ('\u{898}', '\u{8e1}'),
('\u{8e3}', '\u{8ff}'),
- ('ï­', 'ï¯'),
- ('ﯓ', 'ﴽ'),
- ('ïµ', 'ï¶'),
+ ('ï­', '﯂'),
+ ('ﯓ', 'ï¶'),
('ﶒ', 'ﷇ'),
- ('ï·°', 'ï·½'),
+ ('ï·', 'ï·'),
+ ('ï·°', 'ï·¿'),
('ï¹°', 'ï¹´'),
('ﹶ', 'ﻼ'),
('\u{102e0}', 'ð‹»'),
@@ -233,7 +237,7 @@ pub const ARMENIAN: &'static [(char, char)] =
pub const AVESTAN: &'static [(char, char)] = &[('ð¬€', 'ð¬µ'), ('ð¬¹', 'ð¬¿')];
-pub const BALINESE: &'static [(char, char)] = &[('\u{1b00}', 'á­‹'), ('á­', 'á­¼')];
+pub const BALINESE: &'static [(char, char)] = &[('\u{1b00}', 'á­Œ'), ('á­', 'á­¾')];
pub const BAMUM: &'static [(char, char)] = &[('ꚠ', '꛷'), ('𖠀', '𖨸')];
@@ -284,13 +288,13 @@ pub const BOPOMOFO: &'static [(char, char)] = &[
('〷', '〷'),
('・', '・'),
('ㄅ', 'ㄯ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('﹅', '﹆'),
('。', '・'),
];
pub const BRAHMI: &'static [(char, char)] =
- &[('ð‘€€', 'ð‘'), ('ð‘’', 'ð‘¯'), ('\u{1107f}', '\u{1107f}')];
+ &[('ð‘€€', 'ð‘'), ('ð‘’', 'ð‘µ'), ('\u{1107f}', '\u{1107f}')];
pub const BRAILLE: &'static [(char, char)] = &[('⠀', '⣿')];
@@ -300,7 +304,7 @@ pub const BUGINESE: &'static [(char, char)] =
pub const BUHID: &'static [(char, char)] = &[('᜵', '᜶'), ('á€', '\u{1753}')];
pub const CANADIAN_ABORIGINAL: &'static [(char, char)] =
- &[('á€', 'ᙿ'), ('ᢰ', 'ᣵ')];
+ &[('á€', 'ᙿ'), ('ᢰ', 'ᣵ'), ('𑪰', '𑪿')];
pub const CARIAN: &'static [(char, char)] = &[('ðŠ ', 'ð‹')];
@@ -308,7 +312,7 @@ pub const CAUCASIAN_ALBANIAN: &'static [(char, char)] =
&[('ð”°', 'ð•£'), ('ð•¯', 'ð•¯')];
pub const CHAKMA: &'static [(char, char)] =
- &[('০', '৯'), ('á€', 'á‰'), ('\u{11100}', '\u{11134}'), ('𑄶', '\u{11147}')];
+ &[('০', '৯'), ('á€', 'á‰'), ('\u{11100}', '\u{11134}'), ('𑄶', 'ð‘…‡')];
pub const CHAM: &'static [(char, char)] =
&[('ꨀ', '\u{aa36}'), ('ê©€', 'ê©'), ('ê©', 'ê©™'), ('ê©œ', 'ê©Ÿ')];
@@ -316,10 +320,10 @@ pub const CHAM: &'static [(char, char)] =
pub const CHEROKEE: &'static [(char, char)] =
&[('Ꭰ', 'áµ'), ('á¸', 'á½'), ('ê­°', 'ꮿ')];
-pub const CHORASMIAN: &'static [(char, char)] = &[('\u{10fb0}', '\u{10fcb}')];
+pub const CHORASMIAN: &'static [(char, char)] = &[('ð¾°', 'ð¿‹')];
pub const COMMON: &'static [(char, char)] = &[
- ('\u{0}', '@'),
+ ('\0', '@'),
('[', '`'),
('{', '©'),
('«', '¹'),
@@ -345,7 +349,7 @@ pub const COMMON: &'static [(char, char)] = &[
('\u{2066}', 'â°'),
('â´', 'â¾'),
('â‚€', 'â‚Ž'),
- ('â‚ ', 'â‚¿'),
+ ('₠', '⃀'),
('â„€', 'â„¥'),
('℧', '℩'),
('ℬ', 'ℱ'),
@@ -357,9 +361,9 @@ pub const COMMON: &'static [(char, char)] = &[
('①', '⟿'),
('⤀', '⭳'),
('⭶', '⮕'),
- ('\u{2b97}', '⯿'),
+ ('⮗', '⯿'),
('⸀', '⹂'),
- ('⹄', '\u{2e52}'),
+ ('⹄', 'â¹'),
('â¿°', 'â¿»'),
('\u{3000}', '\u{3000}'),
('〄', '〄'),
@@ -377,8 +381,7 @@ pub const COMMON: &'static [(char, char)] = &[
('꜈', '꜡'),
('ꞈ', '꞊'),
('ê­›', 'ê­›'),
- ('\u{ab6a}', '\u{ab6b}'),
- ('ï´¾', 'ï´¿'),
+ ('ê­ª', 'ê­«'),
('ï¸', '︙'),
('︰', '﹄'),
('﹇', '﹒'),
@@ -391,16 +394,16 @@ pub const COMMON: &'static [(char, char)] = &[
('¢', '₩'),
('│', '○'),
('\u{fff9}', '�'),
- ('ð†', '\u{1019c}'),
+ ('ð†', 'ð†œ'),
('ð‡', 'ð‡¼'),
- ('ð–¿¢', 'ð–¿£'),
+ ('ðœ½', '𜿃'),
('ð€€', 'ðƒµ'),
('ð„€', 'ð„¦'),
('ð„©', 'ð…¦'),
('ð…ª', '\u{1d17a}'),
('ð†ƒ', 'ð†„'),
('ð†Œ', 'ð†©'),
- ('ð†®', 'ð‡¨'),
+ ('ð†®', 'ð‡ª'),
('ð‹ ', 'ð‹³'),
('ðŒ€', 'ð–'),
('ð²', 'ð¸'),
@@ -433,38 +436,39 @@ pub const COMMON: &'static [(char, char)] = &[
('🂱', '🂿'),
('ðŸƒ', 'ðŸƒ'),
('🃑', '🃵'),
- ('🄀', '\u{1f1ad}'),
+ ('🄀', '🆭'),
('🇦', '🇿'),
('ðŸˆ', '🈂'),
('ðŸˆ', '🈻'),
('🉀', '🉈'),
('🉠', '🉥'),
- ('🌀', '\u{1f6d7}'),
- ('🛠', '🛬'),
- ('🛰', '\u{1f6fc}'),
+ ('🌀', '🛗'),
+ ('ðŸ›', '🛬'),
+ ('🛰', '🛼'),
('🜀', 'ðŸ³'),
('🞀', '🟘'),
('🟠', '🟫'),
+ ('🟰', '🟰'),
('🠀', '🠋'),
('ðŸ ', '🡇'),
('ðŸ¡', '🡙'),
('🡠', '🢇'),
('ðŸ¢', '🢭'),
- ('\u{1f8b0}', '\u{1f8b1}'),
- ('🤀', '\u{1f978}'),
- ('🥺', '\u{1f9cb}'),
- ('ðŸ§', '🩓'),
+ ('🢰', '🢱'),
+ ('🤀', '🩓'),
('🩠', '🩭'),
- ('🩰', '\u{1fa74}'),
- ('🩸', '🩺'),
- ('🪀', '\u{1fa86}'),
- ('ðŸª', '\u{1faa8}'),
- ('\u{1fab0}', '\u{1fab6}'),
- ('\u{1fac0}', '\u{1fac2}'),
- ('\u{1fad0}', '\u{1fad6}'),
- ('\u{1fb00}', '\u{1fb92}'),
- ('\u{1fb94}', '\u{1fbca}'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🩰', '🩴'),
+ ('🩸', '🩼'),
+ ('🪀', '🪆'),
+ ('ðŸª', '🪬'),
+ ('🪰', '🪺'),
+ ('🫀', '🫅'),
+ ('ðŸ«', '🫙'),
+ ('🫠', '🫧'),
+ ('🫰', '🫶'),
+ ('🬀', '🮒'),
+ ('🮔', '🯊'),
+ ('🯰', '🯹'),
('\u{e0001}', '\u{e0001}'),
('\u{e0020}', '\u{e007f}'),
];
@@ -487,6 +491,8 @@ pub const CYPRIOT: &'static [(char, char)] = &[
('ð ¿', 'ð ¿'),
];
+pub const CYPRO_MINOAN: &'static [(char, char)] = &[('ð„€', 'ð„'), ('ð’¾', 'ð’¿²')];
+
pub const CYRILLIC: &'static [(char, char)] = &[
('Ѐ', 'ԯ'),
('ᲀ', 'ᲈ'),
@@ -512,14 +518,14 @@ pub const DEVANAGARI: &'static [(char, char)] = &[
];
pub const DIVES_AKURU: &'static [(char, char)] = &[
- ('\u{11900}', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
- ('\u{1193b}', '\u{11946}'),
- ('\u{11950}', '\u{11959}'),
+ ('𑤀', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤵'),
+ ('𑤷', '𑤸'),
+ ('\u{1193b}', '𑥆'),
+ ('ð‘¥', 'ð‘¥™'),
];
pub const DOGRA: &'static [(char, char)] =
@@ -568,6 +574,10 @@ pub const ETHIOPIC: &'static [(char, char)] = &[
('ꬑ', 'ꬖ'),
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
];
pub const GEORGIAN: &'static [(char, char)] = &[
@@ -585,8 +595,7 @@ pub const GEORGIAN: &'static [(char, char)] = &[
pub const GLAGOLITIC: &'static [(char, char)] = &[
('\u{484}', '\u{484}'),
('\u{487}', '\u{487}'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
+ ('Ⰰ', 'ⱟ'),
('⹃', '⹃'),
('\u{a66f}', '\u{a66f}'),
('\u{1e000}', '\u{1e006}'),
@@ -739,23 +748,24 @@ pub const HAN: &'static [(char, char)] = &[
('ã˜', 'ã°'),
('ã»', 'ã¿'),
('ã ', 'ã¾'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
+ ('ã€', '䶿'),
+ ('一', '鿿'),
('꜀', '꜇'),
('豈', '舘'),
('ï©°', 'ï«™'),
('﹅', '﹆'),
('。', '・'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿¢', 'ð–¿£'),
+ ('ð–¿°', 'ð–¿±'),
('ð ', 'ð±'),
('ðŸ‰', '🉑'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const HANGUL: &'static [(char, char)] = &[
@@ -823,7 +833,7 @@ pub const HIRAGANA: &'static [(char, char)] = &[
('。', '・'),
('ï½°', 'ï½°'),
('\u{ff9e}', '\u{ff9f}'),
- ('ð›€', '𛄞'),
+ ('ð›€', '𛄟'),
('ð›…', 'ð›…’'),
('🈀', '🈀'),
];
@@ -836,7 +846,7 @@ pub const INHERITED: &'static [(char, char)] = &[
('\u{343}', '\u{344}'),
('\u{346}', '\u{362}'),
('\u{953}', '\u{954}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1dc2}', '\u{1df7}'),
('\u{1df9}', '\u{1df9}'),
('\u{1dfb}', '\u{1dff}'),
@@ -845,6 +855,8 @@ pub const INHERITED: &'static [(char, char)] = &[
('\u{fe00}', '\u{fe0f}'),
('\u{fe20}', '\u{fe2d}'),
('\u{101fd}', '\u{101fd}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d167}', '\u{1d169}'),
('\u{1d17b}', '\u{1d182}'),
('\u{1d185}', '\u{1d18b}'),
@@ -861,8 +873,12 @@ pub const INSCRIPTIONAL_PARTHIAN: &'static [(char, char)] =
pub const JAVANESE: &'static [(char, char)] =
&[('\u{a980}', 'ê§'), ('ê§', '꧙'), ('꧞', '꧟')];
-pub const KAITHI: &'static [(char, char)] =
- &[('०', '९'), ('ê °', 'ê ¹'), ('\u{11080}', 'ð‘ƒ'), ('\u{110cd}', '\u{110cd}')];
+pub const KAITHI: &'static [(char, char)] = &[
+ ('०', '९'),
+ ('ê °', 'ê ¹'),
+ ('\u{11080}', '\u{110c2}'),
+ ('\u{110cd}', '\u{110cd}'),
+];
pub const KANNADA: &'static [(char, char)] = &[
('\u{951}', '\u{952}'),
@@ -876,7 +892,7 @@ pub const KANNADA: &'static [(char, char)] = &[
('\u{cc6}', 'ೈ'),
('ೊ', '\u{ccd}'),
('\u{cd5}', '\u{cd6}'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('à³ ', '\u{ce3}'),
('೦', '೯'),
('à³±', 'à³²'),
@@ -902,7 +918,11 @@ pub const KATAKANA: &'static [(char, char)] = &[
('㌀', 'ã—'),
('﹅', '﹆'),
('。', '\u{ff9f}'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
('𛀀', '𛀀'),
+ ('𛄠', '𛄢'),
('ð›…¤', 'ð›…§'),
];
@@ -920,7 +940,7 @@ pub const KHAROSHTHI: &'static [(char, char)] = &[
];
pub const KHITAN_SMALL_SCRIPT: &'static [(char, char)] =
- &[('\u{16fe4}', '\u{16fe4}'), ('\u{18b00}', '\u{18cd5}')];
+ &[('\u{16fe4}', '\u{16fe4}'), ('𘬀', '𘳕')];
pub const KHMER: &'static [(char, char)] =
&[('ក', '\u{17dd}'), ('០', '៩'), ('៰', '៹'), ('᧠', '᧿')];
@@ -976,16 +996,22 @@ pub const LATIN: &'static [(char, char)] = &[
('Ⱡ', 'Ɀ'),
('꜀', '꜇'),
('Ꜣ', 'ꞇ'),
- ('êž‹', 'êž¿'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ꟿ'),
+ ('Ꞌ', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ꟿ'),
('꤮', '꤮'),
('ꬰ', 'ꭚ'),
('ꭜ', 'ꭤ'),
- ('ê­¦', '\u{ab69}'),
+ ('ê­¦', 'ê­©'),
('ff', 'st'),
('A', 'Z'),
('ï½', 'z'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
+ ('ð¼€', 'ð¼ž'),
];
pub const LEPCHA: &'static [(char, char)] =
@@ -1016,8 +1042,7 @@ pub const LINEAR_B: &'static [(char, char)] = &[
('ð„·', 'ð„¿'),
];
-pub const LISU: &'static [(char, char)] =
- &[('ê“', 'ê“¿'), ('\u{11fb0}', '\u{11fb0}')];
+pub const LISU: &'static [(char, char)] = &[('ê“', 'ê“¿'), ('𑾰', '𑾰')];
pub const LYCIAN: &'static [(char, char)] = &[('ðŠ€', 'ðŠœ')];
@@ -1082,8 +1107,7 @@ pub const MODI: &'static [(char, char)] =
&[('ê °', 'ê ¹'), ('𑘀', 'ð‘™„'), ('ð‘™', 'ð‘™™')];
pub const MONGOLIAN: &'static [(char, char)] = &[
- ('á €', '\u{180e}'),
- ('á ', 'á ™'),
+ ('á €', 'á ™'),
('ᠠ', 'ᡸ'),
('ᢀ', 'ᢪ'),
('\u{202f}', '\u{202f}'),
@@ -1115,9 +1139,16 @@ pub const NANDINAGARI: &'static [(char, char)] = &[
pub const NEW_TAI_LUE: &'static [(char, char)] =
&[('ᦀ', 'ᦫ'), ('ᦰ', 'ᧉ'), ('á§', '᧚'), ('᧞', '᧟')];
-pub const NEWA: &'static [(char, char)] = &[('ð‘€', 'ð‘‘›'), ('ð‘‘', '\u{11461}')];
+pub const NEWA: &'static [(char, char)] = &[('ð‘€', 'ð‘‘›'), ('ð‘‘', 'ð‘‘¡')];
-pub const NKO: &'static [(char, char)] = &[('߀', 'ߺ'), ('\u{7fd}', '߿')];
+pub const NKO: &'static [(char, char)] = &[
+ ('،', '،'),
+ ('Ø›', 'Ø›'),
+ ('ØŸ', 'ØŸ'),
+ ('߀', 'ߺ'),
+ ('\u{7fd}', 'ß¿'),
+ ('ï´¾', 'ï´¿'),
+];
pub const NUSHU: &'static [(char, char)] = &[('𖿡', '𖿡'), ('𛅰', '𛋻')];
@@ -1146,6 +1177,9 @@ pub const OLD_SOUTH_ARABIAN: &'static [(char, char)] = &[('ð© ', 'ð©¿')];
pub const OLD_TURKIC: &'static [(char, char)] = &[('ð°€', 'ð±ˆ')];
+pub const OLD_UYGHUR: &'static [(char, char)] =
+ &[('Ù€', 'Ù€'), ('ð«²', 'ð«²'), ('ð½°', 'ð¾‰')];
+
pub const ORIYA: &'static [(char, char)] = &[
('\u{951}', '\u{952}'),
('।', '॥'),
@@ -1253,10 +1287,11 @@ pub const SYRIAC: &'static [(char, char)] = &[
('Ý', 'Ý'),
('ࡠ', 'ࡪ'),
('\u{1df8}', '\u{1df8}'),
+ ('\u{1dfa}', '\u{1dfa}'),
];
pub const TAGALOG: &'static [(char, char)] =
- &[('ᜀ', 'ᜌ'), ('ᜎ', '\u{1714}'), ('᜵', '᜶')];
+ &[('ᜀ', '᜕'), ('ᜟ', 'ᜟ'), ('᜵', '᜶')];
pub const TAGBANWA: &'static [(char, char)] =
&[('᜵', '᜶'), ('á ', 'á¬'), ('á®', 'á°'), ('\u{1772}', '\u{1773}')];
@@ -1275,7 +1310,7 @@ pub const TAI_THAM: &'static [(char, char)] = &[
pub const TAI_VIET: &'static [(char, char)] = &[('ꪀ', 'ꫂ'), ('ꫛ', '꫟')];
pub const TAKRI: &'static [(char, char)] =
- &[('।', '॥'), ('꠰', '꠹'), ('𑚀', '𑚸'), ('𑛀', '𑛉')];
+ &[('।', '॥'), ('꠰', '꠹'), ('𑚀', '𑚹'), ('𑛀', '𑛉')];
pub const TAMIL: &'static [(char, char)] = &[
('\u{951}', '\u{952}'),
@@ -1305,12 +1340,10 @@ pub const TAMIL: &'static [(char, char)] = &[
('ð‘¿¿', 'ð‘¿¿'),
];
-pub const TANGUT: &'static [(char, char)] = &[
- ('ð–¿ ', 'ð–¿ '),
- ('𗀀', '𘟷'),
- ('𘠀', '\u{18aff}'),
- ('\u{18d00}', '\u{18d08}'),
-];
+pub const TANGSA: &'static [(char, char)] = &[('𖩰', '𖪾'), ('𖫀', '𖫉')];
+
+pub const TANGUT: &'static [(char, char)] =
+ &[('𖿠', '𖿠'), ('𗀀', '𘟷'), ('𘠀', '𘫿'), ('𘴀', '𘴈')];
pub const TELUGU: &'static [(char, char)] = &[
('\u{951}', '\u{952}'),
@@ -1319,11 +1352,12 @@ pub const TELUGU: &'static [(char, char)] = &[
('à°Ž', 'à°'),
('à°’', 'à°¨'),
('à°ª', 'à°¹'),
- ('ఽ', 'ౄ'),
+ ('\u{c3c}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
('\u{c55}', '\u{c56}'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('à± ', '\u{c63}'),
('౦', '౯'),
('౷', '౿'),
@@ -1365,10 +1399,23 @@ pub const TIRHUTA: &'static [(char, char)] = &[
('ð‘“', 'ð‘“™'),
];
+pub const TOTO: &'static [(char, char)] = &[('ðžŠ', '\u{1e2ae}')];
+
pub const UGARITIC: &'static [(char, char)] = &[('ðŽ€', 'ðŽ'), ('ðŽŸ', 'ðŽŸ')];
pub const VAI: &'static [(char, char)] = &[('ꔀ', 'ꘫ')];
+pub const VITHKUQI: &'static [(char, char)] = &[
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
+];
+
pub const WANCHO: &'static [(char, char)] = &[('𞋀', '𞋹'), ('𞋿', '𞋿')];
pub const WARANG_CITI: &'static [(char, char)] = &[('𑢠', '𑣲'), ('𑣿', '𑣿')];
@@ -1378,9 +1425,9 @@ pub const YEZIDI: &'static [(char, char)] = &[
('Ø›', 'Ø›'),
('ØŸ', 'ØŸ'),
('Ù ', 'Ù©'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eab}', '\u{10ead}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('\u{10eab}', 'ðº­'),
+ ('ðº°', 'ðº±'),
];
pub const YI: &'static [(char, char)] = &[
diff --git a/vendor/regex-syntax/src/unicode_tables/sentence_break.rs b/vendor/regex-syntax/src/unicode_tables/sentence_break.rs
index 67d830f74..db8ad282b 100644
--- a/vendor/regex-syntax/src/unicode_tables/sentence_break.rs
+++ b/vendor/regex-syntax/src/unicode_tables/sentence_break.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate sentence-break ucd-13.0.0 --chars
+// ucd-generate sentence-break /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("ATerm", ATERM),
@@ -29,7 +29,7 @@ pub const ATERM: &'static [(char, char)] =
pub const CR: &'static [(char, char)] = &[('\r', '\r')];
pub const CLOSE: &'static [(char, char)] = &[
- ('\"', '\"'),
+ ('"', '"'),
('\'', ')'),
('[', '['),
(']', ']'),
@@ -57,6 +57,7 @@ pub const CLOSE: &'static [(char, char)] = &[
('⸜', 'â¸'),
('⸠', '⸩'),
('⹂', '⹂'),
+ ('⹕', '⹜'),
('〈', '】'),
('〔', '〛'),
('ã€', '〟'),
@@ -100,7 +101,8 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{825}', '\u{827}'),
('\u{829}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('\u{898}', '\u{89f}'),
+ ('\u{8ca}', '\u{8e1}'),
('\u{8e3}', 'ः'),
('\u{93a}', '\u{93c}'),
('ा', 'à¥'),
@@ -142,6 +144,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('ொ', '\u{bcd}'),
('\u{bd7}', '\u{bd7}'),
('\u{c00}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -193,13 +196,14 @@ pub const EXTEND: &'static [(char, char)] = &[
('á‚', 'á‚'),
('á‚š', '\u{109d}'),
('\u{135d}', '\u{135f}'),
- ('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1712}', '᜕'),
+ ('\u{1732}', '᜴'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
('\u{1920}', 'ᤫ'),
@@ -208,7 +212,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('á©•', '\u{1a5e}'),
('\u{1a60}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1b00}', 'ᬄ'),
('\u{1b34}', 'á­„'),
('\u{1b6b}', '\u{1b73}'),
@@ -221,8 +225,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('á³·', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{200c}', '\u{200d}'),
('\u{20d0}', '\u{20f0}'),
('\u{2cef}', '\u{2cf1}'),
@@ -277,10 +280,14 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('𑀀', '𑀂'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', 'ð‘‚‚'),
('ð‘‚°', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{11134}'),
('ð‘……', 'ð‘…†'),
@@ -288,7 +295,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{11180}', '𑆂'),
('𑆳', '𑇀'),
('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '\u{111cf}'),
+ ('𑇎', '\u{111cf}'),
('𑈬', '\u{11237}'),
('\u{1123e}', '\u{1123e}'),
('\u{112df}', '\u{112ea}'),
@@ -311,11 +318,11 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{116ab}', '\u{116b7}'),
('\u{1171d}', '\u{1172b}'),
('ð‘ ¬', '\u{1183a}'),
- ('\u{11930}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('\u{11930}', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{1193e}'),
- ('\u{11940}', '\u{11940}'),
- ('\u{11942}', '\u{11943}'),
+ ('ð‘¥€', 'ð‘¥€'),
+ ('𑥂', '\u{11943}'),
('𑧑', '\u{119d7}'),
('\u{119da}', '\u{119e0}'),
('𑧤', '𑧤'),
@@ -344,8 +351,10 @@ pub const EXTEND: &'static [(char, char)] = &[
('𖽑', '𖾇'),
('\u{16f8f}', '\u{16f92}'),
('\u{16fe4}', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
@@ -364,6 +373,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e94a}'),
@@ -377,6 +387,7 @@ pub const FORMAT: &'static [(char, char)] = &[
('\u{61c}', '\u{61c}'),
('\u{6dd}', '\u{6dd}'),
('\u{70f}', '\u{70f}'),
+ ('\u{890}', '\u{891}'),
('\u{8e2}', '\u{8e2}'),
('\u{180e}', '\u{180e}'),
('\u{200b}', '\u{200b}'),
@@ -833,7 +844,7 @@ pub const LOWER: &'static [(char, char)] = &[
('â…°', 'â…¿'),
('ↄ', 'ↄ'),
('â“', 'â“©'),
- ('ⰰ', 'ⱞ'),
+ ('ⰰ', 'ⱟ'),
('ⱡ', 'ⱡ'),
('ⱥ', 'ⱦ'),
('ⱨ', 'ⱨ'),
@@ -1001,19 +1012,33 @@ pub const LOWER: &'static [(char, char)] = &[
('êž»', 'êž»'),
('êž½', 'êž½'),
('êž¿', 'êž¿'),
+ ('êŸ', 'êŸ'),
('ꟃ', 'ꟃ'),
- ('\u{a7c8}', '\u{a7c8}'),
- ('\u{a7ca}', '\u{a7ca}'),
- ('\u{a7f6}', '\u{a7f6}'),
+ ('ꟈ', 'ꟈ'),
+ ('ꟊ', 'ꟊ'),
+ ('ꟑ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟕ'),
+ ('ꟗ', 'ꟗ'),
+ ('ꟙ', 'ꟙ'),
+ ('ꟶ', 'ꟶ'),
('ꟸ', 'ꟺ'),
('ꬰ', 'ꭚ'),
- ('ꭜ', '\u{ab68}'),
+ ('ꭜ', 'ꭨ'),
('ꭰ', 'ꮿ'),
('ff', 'st'),
('ﬓ', 'ﬗ'),
('ï½', 'z'),
('ð¨', 'ð‘'),
('ð“˜', 'ð“»'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
+ ('ðž€', 'ðž€'),
+ ('ðžƒ', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð³€', 'ð³²'),
('𑣀', '𑣟'),
('𖹠', '𖹿'),
@@ -1045,6 +1070,8 @@ pub const LOWER: &'static [(char, char)] = &[
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‰'),
('ðŸ‹', 'ðŸ‹'),
+ ('ð¼€', 'ð¼‰'),
+ ('ð¼‹', 'ð¼ž'),
('𞤢', '𞥃'),
];
@@ -1100,17 +1127,18 @@ pub const NUMERIC: &'static [(char, char)] = &[
('𑛀', '𑛉'),
('𑜰', '𑜹'),
('𑣠', '𑣩'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('ð‘±', '𑱙'),
('ð‘µ', '𑵙'),
('𑶠', '𑶩'),
('ð–© ', 'ð–©©'),
+ ('𖫀', '𖫉'),
('ð–­', 'ð–­™'),
('ðŸŽ', 'ðŸ¿'),
('ðž…€', 'ðž…‰'),
('𞋰', '𞋹'),
('ðž¥', '𞥙'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🯰', '🯹'),
];
pub const OLETTER: &'static [(char, char)] = &[
@@ -1146,8 +1174,9 @@ pub const OLETTER: &'static [(char, char)] = &[
('à ¨', 'à ¨'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('ऄ', 'ह'),
('ऽ', 'ऽ'),
('à¥', 'à¥'),
@@ -1212,6 +1241,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('à°ª', 'à°¹'),
('à°½', 'à°½'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('ಀ', 'ಀ'),
('ಅ', 'ಌ'),
@@ -1220,10 +1250,10 @@ pub const OLETTER: &'static [(char, char)] = &[
('ಪ', 'ಳ'),
('ವ', 'ಹ'),
('ಽ', 'ಽ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('à³±', 'à³²'),
- ('\u{d04}', 'ഌ'),
+ ('ഄ', 'ഌ'),
('à´Ž', 'à´'),
('à´’', 'à´º'),
('à´½', 'à´½'),
@@ -1286,9 +1316,8 @@ pub const OLETTER: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
+ ('ᜀ', 'ᜑ'),
+ ('ᜟ', 'ᜱ'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -1309,7 +1338,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('ᨠ', 'ᩔ'),
('ᪧ', 'ᪧ'),
('ᬅ', 'ᬳ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('ᮃ', 'ᮠ'),
('ᮮ', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -1347,11 +1376,10 @@ pub const OLETTER: &'static [(char, char)] = &[
('ー', 'ヿ'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ㇰ', 'ㇿ'),
- ('ã€', '\u{4dbf}'),
- ('一', '\u{9ffc}'),
- ('ꀀ', 'ꒌ'),
+ ('ã€', '䶿'),
+ ('一', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
('ê˜', 'ꘟ'),
@@ -1362,6 +1390,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('ꜗ', 'ꜟ'),
('ꞈ', 'ꞈ'),
('êž', 'êž'),
+ ('ꟲ', 'ꟴ'),
('ꟷ', 'ꟷ'),
('ꟻ', 'ê '),
('ê ƒ', 'ê …'),
@@ -1399,7 +1428,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('ꬑ', 'ꬖ'),
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
- ('\u{ab69}', '\u{ab69}'),
+ ('ê­©', 'ê­©'),
('ꯀ', 'ꯢ'),
('가', '힣'),
('ힰ', 'ퟆ'),
@@ -1449,6 +1478,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž', 'ðž‚'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -1477,19 +1507,22 @@ pub const OLETTER: &'static [(char, char)] = &[
('ð®€', 'ð®‘'),
('ð°€', 'ð±ˆ'),
('ð´€', 'ð´£'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('𑀃', '𑀷'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('𑂃', '𑂯'),
('ð‘ƒ', '𑃨'),
('𑄃', '𑄦'),
('ð‘…„', 'ð‘…„'),
- ('\u{11147}', '\u{11147}'),
+ ('ð‘…‡', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('𑆃', '𑆲'),
@@ -1515,7 +1548,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('ð‘', 'ð‘¡'),
('ð‘€', 'ð‘´'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -1526,14 +1559,15 @@ pub const OLETTER: &'static [(char, char)] = &[
('𑚀', '𑚪'),
('𑚸', '𑚸'),
('𑜀', '𑜚'),
+ ('ð‘€', 'ð‘†'),
('ð‘ €', 'ð‘ «'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑦠', '𑦧'),
('𑦪', 'ð‘§'),
('𑧡', '𑧡'),
@@ -1544,7 +1578,7 @@ pub const OLETTER: &'static [(char, char)] = &[
('ð‘©', 'ð‘©'),
('𑩜', '𑪉'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°®'),
('𑱀', '𑱀'),
@@ -1558,14 +1592,16 @@ pub const OLETTER: &'static [(char, char)] = &[
('𑵪', '𑶉'),
('𑶘', '𑶘'),
('ð‘» ', 'ð‘»²'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­€', 'ð–­ƒ'),
@@ -1577,9 +1613,12 @@ pub const OLETTER: &'static [(char, char)] = &[
('ð–¿ ', 'ð–¿¡'),
('ð–¿£', 'ð–¿£'),
('𗀀', '𘟷'),
- ('𘠀', '\u{18cd5}'),
- ('\u{18d00}', '\u{18d08}'),
- ('𛀀', '𛄞'),
+ ('𘠀', '𘳕'),
+ ('𘴀', '𘴈'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
+ ('𛀀', '𛄢'),
('ð›…', 'ð›…’'),
('ð›…¤', 'ð›…§'),
('𛅰', '𛋻'),
@@ -1587,10 +1626,16 @@ pub const OLETTER: &'static [(char, char)] = &[
('ð›±°', 'ð›±¼'),
('𛲀', '𛲈'),
('ð›²', '𛲙'),
+ ('ð¼Š', 'ð¼Š'),
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞥋', '𞥋'),
('𞸀', '𞸃'),
@@ -1626,13 +1671,13 @@ pub const OLETTER: &'static [(char, char)] = &[
('𞺡', '𞺣'),
('𞺥', '𞺩'),
('𞺫', '𞺻'),
- ('ð €€', '\u{2a6dd}'),
- ('𪜀', '𫜴'),
+ ('𠀀', '𪛟'),
+ ('𪜀', '𫜸'),
('ð«€', 'ð« '),
('𫠠', '𬺡'),
('𬺰', '𮯠'),
('丽', 'ð¯¨'),
- ('\u{30000}', '\u{3134a}'),
+ ('ð°€€', 'ð±Š'),
];
pub const SCONTINUE: &'static [(char, char)] = &[
@@ -1661,7 +1706,7 @@ pub const STERM: &'static [(char, char)] = &[
('!', '!'),
('?', '?'),
('Ö‰', 'Ö‰'),
- ('Øž', 'ØŸ'),
+ ('Ø', 'ØŸ'),
('Û”', 'Û”'),
('Ü€', 'Ü‚'),
('ß¹', 'ß¹'),
@@ -1680,12 +1725,14 @@ pub const STERM: &'static [(char, char)] = &[
('᪨', '᪫'),
('á­š', 'á­›'),
('á­ž', 'á­Ÿ'),
+ ('á­½', 'á­¾'),
('á°»', 'á°¼'),
('᱾', '᱿'),
('‼', '‽'),
('â‡', 'â‰'),
('⸮', '⸮'),
('⸼', '⸼'),
+ ('⹓', '⹔'),
('。', '。'),
('ê“¿', 'ê“¿'),
('꘎', 'ê˜'),
@@ -1704,6 +1751,7 @@ pub const STERM: &'static [(char, char)] = &[
('。', '。'),
('ð©–', 'ð©—'),
('ð½•', 'ð½™'),
+ ('ð¾†', 'ð¾‰'),
('ð‘‡', 'ð‘ˆ'),
('ð‘‚¾', 'ð‘ƒ'),
('ð‘…', 'ð‘…ƒ'),
@@ -1718,8 +1766,8 @@ pub const STERM: &'static [(char, char)] = &[
('ð‘—‰', 'ð‘——'),
('ð‘™', 'ð‘™‚'),
('𑜼', '𑜾'),
- ('\u{11944}', '\u{11944}'),
- ('\u{11946}', '\u{11946}'),
+ ('𑥄', '𑥄'),
+ ('𑥆', '𑥆'),
('𑩂', '𑩃'),
('𑪛', '𑪜'),
('ð‘±', '𑱂'),
@@ -2183,7 +2231,7 @@ pub const UPPER: &'static [(char, char)] = &[
('â… ', 'â…¯'),
('Ↄ', 'Ↄ'),
('â’¶', 'â“'),
- ('â°€', 'â°®'),
+ ('â°€', 'â°¯'),
('â± ', 'â± '),
('Ɫ', 'Ɽ'),
('Ⱨ', 'Ⱨ'),
@@ -2348,13 +2396,21 @@ pub const UPPER: &'static [(char, char)] = &[
('Ꞻ', 'Ꞻ'),
('êž¼', 'êž¼'),
('êž¾', 'êž¾'),
+ ('Ꟁ', 'Ꟁ'),
('Ꟃ', 'Ꟃ'),
- ('Ꞔ', '\u{a7c7}'),
- ('\u{a7c9}', '\u{a7c9}'),
- ('\u{a7f5}', '\u{a7f5}'),
+ ('Ꞔ', 'Ꟈ'),
+ ('Ꟊ', 'Ꟊ'),
+ ('êŸ', 'êŸ'),
+ ('Ꟗ', 'Ꟗ'),
+ ('Ꟙ', 'Ꟙ'),
+ ('Ꟶ', 'Ꟶ'),
('A', 'Z'),
('ð€', 'ð§'),
('ð’°', 'ð““'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
('ð²€', 'ð²²'),
('𑢠', '𑢿'),
('𖹀', '𖹟'),
diff --git a/vendor/regex-syntax/src/unicode_tables/word_break.rs b/vendor/regex-syntax/src/unicode_tables/word_break.rs
index bd23e00a8..19b2a1c64 100644
--- a/vendor/regex-syntax/src/unicode_tables/word_break.rs
+++ b/vendor/regex-syntax/src/unicode_tables/word_break.rs
@@ -1,10 +1,10 @@
// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
//
-// ucd-generate word-break ucd-13.0.0 --chars
+// ucd-generate word-break /tmp/ucd --chars
//
-// Unicode version: 13.0.0.
+// Unicode version: 14.0.0.
//
-// ucd-generate 0.2.8 is available on crates.io.
+// ucd-generate 0.2.11 is available on crates.io.
pub const BY_NAME: &'static [(&'static str, &'static [(char, char)])] = &[
("ALetter", ALETTER),
@@ -75,8 +75,9 @@ pub const ALETTER: &'static [(char, char)] = &[
('à ¨', 'à ¨'),
('ࡀ', 'ࡘ'),
('ࡠ', 'ࡪ'),
- ('ࢠ', 'ࢴ'),
- ('ࢶ', '\u{8c7}'),
+ ('ࡰ', 'ࢇ'),
+ ('ࢉ', 'ࢎ'),
+ ('ࢠ', 'ࣉ'),
('ऄ', 'ह'),
('ऽ', 'ऽ'),
('à¥', 'à¥'),
@@ -141,6 +142,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('à°ª', 'à°¹'),
('à°½', 'à°½'),
('ౘ', 'ౚ'),
+ ('à±', 'à±'),
('ౠ', 'ౡ'),
('ಀ', 'ಀ'),
('ಅ', 'ಌ'),
@@ -149,10 +151,10 @@ pub const ALETTER: &'static [(char, char)] = &[
('ಪ', 'ಳ'),
('ವ', 'ಹ'),
('ಽ', 'ಽ'),
- ('ೞ', 'ೞ'),
+ ('à³', 'ೞ'),
('ೠ', 'ೡ'),
('à³±', 'à³²'),
- ('\u{d04}', 'ഌ'),
+ ('ഄ', 'ഌ'),
('à´Ž', 'à´'),
('à´’', 'à´º'),
('à´½', 'à´½'),
@@ -197,9 +199,8 @@ pub const ALETTER: &'static [(char, char)] = &[
('áš', 'ášš'),
('ᚠ', 'ᛪ'),
('ᛮ', 'ᛸ'),
- ('ᜀ', 'ᜌ'),
- ('ᜎ', 'ᜑ'),
- ('ᜠ', 'ᜱ'),
+ ('ᜀ', 'ᜑ'),
+ ('ᜟ', 'ᜱ'),
('á€', 'á‘'),
('á ', 'á¬'),
('á®', 'á°'),
@@ -211,7 +212,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('ᤀ', 'ᤞ'),
('ᨀ', 'ᨖ'),
('ᬅ', 'ᬳ'),
- ('á­…', 'á­‹'),
+ ('ᭅ', 'ᭌ'),
('ᮃ', 'ᮠ'),
('ᮮ', 'ᮯ'),
('ᮺ', 'ᯥ'),
@@ -263,9 +264,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('â…Ž', 'â…Ž'),
('Ⅰ', 'ↈ'),
('â’¶', 'â“©'),
- ('â°€', 'â°®'),
- ('ⰰ', 'ⱞ'),
- ('Ⱡ', 'ⳤ'),
+ ('Ⰰ', 'ⳤ'),
('Ⳬ', 'ⳮ'),
('â³²', 'â³³'),
('â´€', 'â´¥'),
@@ -287,7 +286,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('〻', '〼'),
('ㄅ', 'ㄯ'),
('ㄱ', 'ㆎ'),
- ('ㆠ', '\u{31bf}'),
+ ('ㆠ', 'ㆿ'),
('ꀀ', 'ꒌ'),
('ê“', 'ꓽ'),
('ꔀ', 'ꘌ'),
@@ -296,9 +295,11 @@ pub const ALETTER: &'static [(char, char)] = &[
('Ꙁ', 'ꙮ'),
('ꙿ', 'êš'),
('ꚠ', 'ꛯ'),
- ('꜈', 'ꞿ'),
- ('Ꟃ', '\u{a7ca}'),
- ('\u{a7f5}', 'ê '),
+ ('꜈', 'ꟊ'),
+ ('êŸ', 'ꟑ'),
+ ('ꟓ', 'ꟓ'),
+ ('ꟕ', 'ꟙ'),
+ ('ꟲ', 'ê '),
('ê ƒ', 'ê …'),
('ê ‡', 'ê Š'),
('ꠌ', 'ꠢ'),
@@ -322,7 +323,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('ꬑ', 'ꬖ'),
('ꬠ', 'ꬦ'),
('ꬨ', 'ꬮ'),
- ('ꬰ', '\u{ab69}'),
+ ('ꬰ', 'ꭩ'),
('ꭰ', 'ꯢ'),
('가', '힣'),
('ힰ', 'ퟆ'),
@@ -365,9 +366,20 @@ pub const ALETTER: &'static [(char, char)] = &[
('ð“˜', 'ð“»'),
('ð”€', 'ð”§'),
('ð”°', 'ð•£'),
+ ('ð•°', 'ð•º'),
+ ('ð•¼', 'ð–Š'),
+ ('ð–Œ', 'ð–’'),
+ ('ð–”', 'ð–•'),
+ ('ð–—', 'ð–¡'),
+ ('ð–£', 'ð–±'),
+ ('ð–³', 'ð–¹'),
+ ('ð–»', 'ð–¼'),
('ð˜€', 'ðœ¶'),
('ð€', 'ð•'),
('ð ', 'ð§'),
+ ('ðž€', 'ðž…'),
+ ('ðž‡', 'ðž°'),
+ ('ðž²', 'ðžº'),
('ð €', 'ð …'),
('ð ˆ', 'ð ˆ'),
('ð Š', 'ð µ'),
@@ -398,19 +410,22 @@ pub const ALETTER: &'static [(char, char)] = &[
('ð²€', 'ð²²'),
('ð³€', 'ð³²'),
('ð´€', 'ð´£'),
- ('\u{10e80}', '\u{10ea9}'),
- ('\u{10eb0}', '\u{10eb1}'),
+ ('ðº€', 'ðº©'),
+ ('ðº°', 'ðº±'),
('ð¼€', 'ð¼œ'),
('ð¼§', 'ð¼§'),
('ð¼°', 'ð½…'),
- ('\u{10fb0}', '\u{10fc4}'),
+ ('ð½°', 'ð¾'),
+ ('ð¾°', 'ð¿„'),
('ð¿ ', 'ð¿¶'),
('𑀃', '𑀷'),
+ ('ð‘±', 'ð‘²'),
+ ('ð‘µ', 'ð‘µ'),
('𑂃', '𑂯'),
('ð‘ƒ', '𑃨'),
('𑄃', '𑄦'),
('ð‘…„', 'ð‘…„'),
- ('\u{11147}', '\u{11147}'),
+ ('ð‘…‡', 'ð‘…‡'),
('ð‘…', 'ð‘…²'),
('ð‘…¶', 'ð‘…¶'),
('𑆃', '𑆲'),
@@ -436,7 +451,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('ð‘', 'ð‘¡'),
('ð‘€', 'ð‘´'),
('𑑇', '𑑊'),
- ('ð‘‘Ÿ', '\u{11461}'),
+ ('ð‘‘Ÿ', 'ð‘‘¡'),
('ð‘’€', 'ð‘’¯'),
('ð‘“„', 'ð‘“…'),
('𑓇', '𑓇'),
@@ -448,13 +463,13 @@ pub const ALETTER: &'static [(char, char)] = &[
('𑚸', '𑚸'),
('ð‘ €', 'ð‘ «'),
('𑢠', '𑣟'),
- ('𑣿', '\u{11906}'),
- ('\u{11909}', '\u{11909}'),
- ('\u{1190c}', '\u{11913}'),
- ('\u{11915}', '\u{11916}'),
- ('\u{11918}', '\u{1192f}'),
- ('\u{1193f}', '\u{1193f}'),
- ('\u{11941}', '\u{11941}'),
+ ('𑣿', '𑤆'),
+ ('𑤉', '𑤉'),
+ ('𑤌', '𑤓'),
+ ('𑤕', '𑤖'),
+ ('𑤘', '𑤯'),
+ ('𑤿', '𑤿'),
+ ('ð‘¥', 'ð‘¥'),
('𑦠', '𑦧'),
('𑦪', 'ð‘§'),
('𑧡', '𑧡'),
@@ -465,7 +480,7 @@ pub const ALETTER: &'static [(char, char)] = &[
('ð‘©', 'ð‘©'),
('𑩜', '𑪉'),
('ð‘ª', 'ð‘ª'),
- ('𑫀', '𑫸'),
+ ('𑪰', '𑫸'),
('ð‘°€', 'ð‘°ˆ'),
('ð‘°Š', 'ð‘°®'),
('𑱀', '𑱀'),
@@ -479,14 +494,16 @@ pub const ALETTER: &'static [(char, char)] = &[
('𑵪', '𑶉'),
('𑶘', '𑶘'),
('ð‘» ', 'ð‘»²'),
- ('\u{11fb0}', '\u{11fb0}'),
+ ('𑾰', '𑾰'),
('ð’€€', 'ð’Ž™'),
('ð’€', 'ð’‘®'),
('𒒀', '𒕃'),
+ ('ð’¾', 'ð’¿°'),
('ð“€€', 'ð“®'),
('ð”€', '𔙆'),
('𖠀', '𖨸'),
('ð–©€', 'ð–©ž'),
+ ('𖩰', '𖪾'),
('ð–«', 'ð–«­'),
('𖬀', '𖬯'),
('ð–­€', 'ð–­ƒ'),
@@ -532,10 +549,16 @@ pub const ALETTER: &'static [(char, char)] = &[
('ðžŠ', 'ðž¨'),
('ðžª', 'ðŸ‚'),
('ðŸ„', 'ðŸ‹'),
+ ('ð¼€', 'ð¼ž'),
('𞄀', '𞄬'),
('𞄷', '𞄽'),
('ðž…Ž', 'ðž…Ž'),
+ ('ðžŠ', '𞊭'),
('ðž‹€', 'ðž‹«'),
+ ('𞟠', '𞟦'),
+ ('𞟨', '𞟫'),
+ ('𞟭', '𞟮'),
+ ('𞟰', '𞟾'),
('𞠀', '𞣄'),
('𞤀', '𞥃'),
('𞥋', '𞥋'),
@@ -579,7 +602,7 @@ pub const ALETTER: &'static [(char, char)] = &[
pub const CR: &'static [(char, char)] = &[('\r', '\r')];
-pub const DOUBLE_QUOTE: &'static [(char, char)] = &[('\"', '\"')];
+pub const DOUBLE_QUOTE: &'static [(char, char)] = &[('"', '"')];
pub const EXTEND: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'),
@@ -606,7 +629,8 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{825}', '\u{827}'),
('\u{829}', '\u{82d}'),
('\u{859}', '\u{85b}'),
- ('\u{8d3}', '\u{8e1}'),
+ ('\u{898}', '\u{89f}'),
+ ('\u{8ca}', '\u{8e1}'),
('\u{8e3}', 'ः'),
('\u{93a}', '\u{93c}'),
('ा', 'à¥'),
@@ -648,6 +672,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('ொ', '\u{bcd}'),
('\u{bd7}', '\u{bd7}'),
('\u{c00}', '\u{c04}'),
+ ('\u{c3c}', '\u{c3c}'),
('\u{c3e}', 'ౄ'),
('\u{c46}', '\u{c48}'),
('\u{c4a}', '\u{c4d}'),
@@ -699,13 +724,14 @@ pub const EXTEND: &'static [(char, char)] = &[
('á‚', 'á‚'),
('á‚š', '\u{109d}'),
('\u{135d}', '\u{135f}'),
- ('\u{1712}', '\u{1714}'),
- ('\u{1732}', '\u{1734}'),
+ ('\u{1712}', '᜕'),
+ ('\u{1732}', '᜴'),
('\u{1752}', '\u{1753}'),
('\u{1772}', '\u{1773}'),
('\u{17b4}', '\u{17d3}'),
('\u{17dd}', '\u{17dd}'),
('\u{180b}', '\u{180d}'),
+ ('\u{180f}', '\u{180f}'),
('\u{1885}', '\u{1886}'),
('\u{18a9}', '\u{18a9}'),
('\u{1920}', 'ᤫ'),
@@ -714,7 +740,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('á©•', '\u{1a5e}'),
('\u{1a60}', '\u{1a7c}'),
('\u{1a7f}', '\u{1a7f}'),
- ('\u{1ab0}', '\u{1ac0}'),
+ ('\u{1ab0}', '\u{1ace}'),
('\u{1b00}', 'ᬄ'),
('\u{1b34}', 'á­„'),
('\u{1b6b}', '\u{1b73}'),
@@ -727,8 +753,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1ced}', '\u{1ced}'),
('\u{1cf4}', '\u{1cf4}'),
('á³·', '\u{1cf9}'),
- ('\u{1dc0}', '\u{1df9}'),
- ('\u{1dfb}', '\u{1dff}'),
+ ('\u{1dc0}', '\u{1dff}'),
('\u{200c}', '\u{200c}'),
('\u{20d0}', '\u{20f0}'),
('\u{2cef}', '\u{2cf1}'),
@@ -783,10 +808,14 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{10d24}', '\u{10d27}'),
('\u{10eab}', '\u{10eac}'),
('\u{10f46}', '\u{10f50}'),
+ ('\u{10f82}', '\u{10f85}'),
('𑀀', '𑀂'),
('\u{11038}', '\u{11046}'),
+ ('\u{11070}', '\u{11070}'),
+ ('\u{11073}', '\u{11074}'),
('\u{1107f}', 'ð‘‚‚'),
('ð‘‚°', '\u{110ba}'),
+ ('\u{110c2}', '\u{110c2}'),
('\u{11100}', '\u{11102}'),
('\u{11127}', '\u{11134}'),
('ð‘……', 'ð‘…†'),
@@ -794,7 +823,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{11180}', '𑆂'),
('𑆳', '𑇀'),
('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '\u{111cf}'),
+ ('𑇎', '\u{111cf}'),
('𑈬', '\u{11237}'),
('\u{1123e}', '\u{1123e}'),
('\u{112df}', '\u{112ea}'),
@@ -817,11 +846,11 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{116ab}', '\u{116b7}'),
('\u{1171d}', '\u{1172b}'),
('ð‘ ¬', '\u{1183a}'),
- ('\u{11930}', '\u{11935}'),
- ('\u{11937}', '\u{11938}'),
+ ('\u{11930}', '𑤵'),
+ ('𑤷', '𑤸'),
('\u{1193b}', '\u{1193e}'),
- ('\u{11940}', '\u{11940}'),
- ('\u{11942}', '\u{11943}'),
+ ('ð‘¥€', 'ð‘¥€'),
+ ('𑥂', '\u{11943}'),
('𑧑', '\u{119d7}'),
('\u{119da}', '\u{119e0}'),
('𑧤', '𑧤'),
@@ -850,8 +879,10 @@ pub const EXTEND: &'static [(char, char)] = &[
('𖽑', '𖾇'),
('\u{16f8f}', '\u{16f92}'),
('\u{16fe4}', '\u{16fe4}'),
- ('\u{16ff0}', '\u{16ff1}'),
+ ('ð–¿°', 'ð–¿±'),
('\u{1bc9d}', '\u{1bc9e}'),
+ ('\u{1cf00}', '\u{1cf2d}'),
+ ('\u{1cf30}', '\u{1cf46}'),
('\u{1d165}', '\u{1d169}'),
('ð…­', '\u{1d172}'),
('\u{1d17b}', '\u{1d182}'),
@@ -870,6 +901,7 @@ pub const EXTEND: &'static [(char, char)] = &[
('\u{1e023}', '\u{1e024}'),
('\u{1e026}', '\u{1e02a}'),
('\u{1e130}', '\u{1e136}'),
+ ('\u{1e2ae}', '\u{1e2ae}'),
('\u{1e2ec}', '\u{1e2ef}'),
('\u{1e8d0}', '\u{1e8d6}'),
('\u{1e944}', '\u{1e94a}'),
@@ -894,6 +926,7 @@ pub const FORMAT: &'static [(char, char)] = &[
('\u{61c}', '\u{61c}'),
('\u{6dd}', '\u{6dd}'),
('\u{70f}', '\u{70f}'),
+ ('\u{890}', '\u{891}'),
('\u{8e2}', '\u{8e2}'),
('\u{180e}', '\u{180e}'),
('\u{200e}', '\u{200f}'),
@@ -932,7 +965,11 @@ pub const KATAKANA: &'static [(char, char)] = &[
('ã‹', '㋾'),
('㌀', 'ã—'),
('ヲ', 'ï¾'),
+ ('𚿰', '𚿳'),
+ ('𚿵', '𚿻'),
+ ('𚿽', '𚿾'),
('𛀀', '𛀀'),
+ ('𛄠', '𛄢'),
('ð›…¤', 'ð›…§'),
];
@@ -1031,17 +1068,18 @@ pub const NUMERIC: &'static [(char, char)] = &[
('𑛀', '𑛉'),
('𑜰', '𑜹'),
('𑣠', '𑣩'),
- ('\u{11950}', '\u{11959}'),
+ ('ð‘¥', 'ð‘¥™'),
('ð‘±', '𑱙'),
('ð‘µ', '𑵙'),
('𑶠', '𑶩'),
('ð–© ', 'ð–©©'),
+ ('𖫀', '𖫉'),
('ð–­', 'ð–­™'),
('ðŸŽ', 'ðŸ¿'),
('ðž…€', 'ðž…‰'),
('𞋰', '𞋹'),
('ðž¥', '𞥙'),
- ('\u{1fbf0}', '\u{1fbf9}'),
+ ('🯰', '🯹'),
];
pub const REGIONAL_INDICATOR: &'static [(char, char)] = &[('🇦', '🇿')];
diff --git a/vendor/regex-syntax/src/utf8.rs b/vendor/regex-syntax/src/utf8.rs
index dc055033e..b9c865532 100644
--- a/vendor/regex-syntax/src/utf8.rs
+++ b/vendor/regex-syntax/src/utf8.rs
@@ -198,7 +198,7 @@ impl<'a> IntoIterator for &'a Utf8Sequence {
type Item = &'a Utf8Range;
fn into_iter(self) -> Self::IntoIter {
- self.as_slice().into_iter()
+ self.as_slice().iter()
}
}
@@ -448,7 +448,7 @@ fn max_scalar_value(nbytes: usize) -> u32 {
1 => 0x007F,
2 => 0x07FF,
3 => 0xFFFF,
- 4 => 0x10FFFF,
+ 4 => 0x0010_FFFF,
_ => unreachable!("invalid UTF-8 byte sequence size"),
}
}
@@ -492,7 +492,7 @@ mod tests {
fn single_codepoint_one_sequence() {
// Tests that every range of scalar values that contains a single
// scalar value is recognized by one sequence of byte ranges.
- for i in 0x0..(0x10FFFF + 1) {
+ for i in 0x0..=0x0010_FFFF {
let c = match char::from_u32(i) {
None => continue,
Some(c) => c,
diff --git a/vendor/regex/.cargo-checksum.json b/vendor/regex/.cargo-checksum.json
index f05551b4f..463368b15 100644
--- a/vendor/regex/.cargo-checksum.json
+++ b/vendor/regex/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"34a39916f7d2c49f8e779257a906bab6500dda007dbb42188f31ad72c8ba9bef","Cargo.lock":"5cacc641e7eae4988d6f45ad69dee331358bfd7bc7c1180c0e1ff5fae6d4a969","Cargo.toml":"1f360fc3a09b65707c76b5c8409733718abd5e46a970b33e5d0dc09b9078c12a","HACKING.md":"17818f7a17723608f6bdbe6388ad0a913d4f96f76a16649aaf4e274b1fa0ea97","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","PERFORMANCE.md":"0d5ef3866386918dfdefb1aa9a28cfe33cb3c8ceeb79f3f8ba5b88253dd95991","README.md":"6125b1c70b9b560412529c54dc6aacdfd39cc82f69b5ad7776fa86e4cb720347","UNICODE.md":"a8a8399540eed000d19420135a527f400247a04572e44d124c786b870f518776","examples/regexdna-input.txt":"156a49710bb3e1ed4bc2bbb0af0f383b747b3d0281453cfff39c296124c598f8","examples/regexdna-output.txt":"35e85b19b70a893d752fd43e54e1e9da08bac43559191cea85b33387c24c4cc1","examples/shootout-regex-dna-bytes.rs":"fa2daedb4e0a05f64f33f4af62fbb0176db998e3676f8637ab684b725367a7b4","examples/shootout-regex-dna-cheat.rs":"1f871a6eaaf8372299fa3c762051112fa89a14235b03f734fc50ebd51ecaee72","examples/shootout-regex-dna-replace.rs":"32ffdf13ac6c4ce3fc32116a048e9cc682aa34cdb8e5beaf565a22addbdcd9ab","examples/shootout-regex-dna-single-cheat.rs":"809f75bf1e1917a53623eb6f1a3ce3b7d2ed98a6a1dbc0bd4853bec49a0c6f94","examples/shootout-regex-dna-single.rs":"1ab14f5703cd4be2e75a2e792e0ba1d322b9e4b14535d396805a4316d577f5bb","examples/shootout-regex-dna.rs":"20ea46ab63f91e3ac6a64e997eadd436a9cbc2f1bdade28e4512052f0e25bc34","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/backtrack.rs":"9018950f86564184a5dafd869a6c2cb3c4538ff302adbeccac33015f6e88f904","src/compile.rs":"5c834c2125abc10d0de3c377e34b1f2e2c10b837809631b1c688d3b536368cfd","src/dfa.rs":"2dfed56e1bd3506d328a3d2031aaa15dd87a7561f92f1a9fc1946a14cfbb64ae","src/error.rs":"71c85db839514f26ee024a689061743ea94a34eb7a3291e6c2b69b45a9682d09","src/exec.rs":"88b49098761db539e717c2965d2f56908c81aa10d91873d29a08484be7a11218","src/expand.rs":"ccba4798bd48ce40c34e91318f12258f46d8382e178a2c2b31c0d03b1ab51c5b","src/find_byte.rs":"b387247b77e3269f057c3399aefe5a815032c3af918c876f80eb4b282e4eb95e","src/freqs.rs":"255555f3d95b08a5bb3bc2f38d5a06cc100a39c0f0127fe4f50c33afa1cadc65","src/input.rs":"69595d1ea8d35351f5065ffdbf5965427d2e3fb5160a37008fa7e21d0eaa7720","src/lib.rs":"20bc28509e1853faea9581d43b21bc3ab144bb776e47fda4560082c4673854a6","src/literal/imp.rs":"5f73e0bcbee70c11041deca5ae84a8d30995963f452b29dd2fe5ab46d4978c12","src/literal/mod.rs":"533f1d68af088e9485170145e27518368e541a0337fdb44f63249ebf97310300","src/pattern.rs":"6f5909315f4542a989d9b1cee0bb3bc5b6749a665d73e32ec1c8ec4d71b78fac","src/pikevm.rs":"83423e5a94ea36e99dc6f69891ab200c1d0dadd3389ee296a816ec8d68bf556f","src/pool.rs":"942e991ae31ef349bd76efd78b2a712c01166dec965bf93742977ed0870d5a10","src/prog.rs":"78a02dcc1fc7b1d4f37a4a4eeb075eb5cc84aea1736e4de3a2cc7449a9ce5103","src/re_builder.rs":"943344bf6e2fc90902ee04b11b741c32418ac6814b21b7982cc0a3a817713f3e","src/re_bytes.rs":"c19bf2df00024e91f6f2b68be2d8971e847d6f16d7b949a04d2569736b1cdadb","src/re_set.rs":"a0cb76fafe7e33ea8c7b65aae53fa3432fc1651be186218b2284cb3c002ea966","src/re_trait.rs":"1c209fe30392b957f1bdcacdb900f222fc761a2e1634ab1c3f4ee97f315a0c22","src/re_unicode.rs":"122df2eecd8727a4169fe7efb0925a1767fdfa2e290d9b90ca0beaa137b5abfa","src/sparse.rs":"0da3ddb7972109869248a764dbb10254555f4bb51c375e89fb3fab9cafa47320","src/testdata/LICENSE":"58cf078acc03da3e280a938c2bd9943f554fc9b6ced89ad93ba35ca436872899","src/testdata/README":"45f869e37f798905c773bfbe0ef19a5fb7e585cbf0b7c21b5b5a784e8cec3c14","src/testdata/basic.dat":"b5b33aa89d48a61cd67cb1fbfd8f70e62c83e30b86256f9f915a5190dd38ff06","src/testdata/nullsubexpr.dat":"496ac0278eec3b6d9170faace14554569032dd3d909618364d9326156de39ecf","src/testdata/repetition.dat":"1f7959063015b284b18a4a2c1c8b416d438a2d6c4b1a362da43406b865f50e69","src/utf8.rs":"708615a4859110cc9766b342a9c1da6c5c4a8a04ad239046b2725385db977efe","test":"0d62fdca7da12fc19ea5306b5de1d83e68d9365a029c043d524334da138b0304","tests/api.rs":"7b2a0ef75e99b9776094967bd66e9cdeaa8e11359f5f0a12bd08ef0e8d0c11fc","tests/api_str.rs":"2ae38c04e7e8fac008b609a820d0b1561ba75f39b0edc0987d6d3d06132da77f","tests/bytes.rs":"edc50f526c5fee43df89d639ef18b237e4eb91e9d533bfc43f3cbab7417d38ba","tests/consistent.rs":"d69435154c09478076497216e43081a835ac65147181a4fbddad7bff469605b2","tests/crates_regex.rs":"91a59d470e0700b4bcb3ff735d06799f3107b8ef4875a2e9904607b164be0326","tests/crazy.rs":"c0d56380dff19bdd5d7a3eb731d0e2dc564e169a1b73c81e1879b1e87f5f5f77","tests/flags.rs":"05caace2c81a99d2168037f3a38035d4dffe9f85ef3ebd7ef18b1bc6612f1ea8","tests/fowler.rs":"d78cf914de40b1e125cc92b65ccb444d462586bd07b5e05de4e4a1b5de16aa76","tests/macros.rs":"6db70c16fc90df13e6b30d2b606f8b6dd4dc976697967f6ee001b15aab6d0b19","tests/macros_bytes.rs":"a049f528a93173a1bb176cd46932dce1880679f4a1752e099be920f0e4546fd0","tests/macros_str.rs":"e585b1461374c45a2eca44ca045bc3c1fe984b2b4212e432b0c695b420e708b7","tests/misc.rs":"395f52793fa022e4cdda78675b6a6fba1a3106b4b99c834c39f7801574054bd1","tests/multiline.rs":"1b1a3326ed976437c1357f01d81833ece7ea244f38826246eab55cacd5d0862a","tests/noparse.rs":"12b6be0eff3d80779d33c6459396c74c0f6ebf4ddc9f1d33c3e747ea9e3bf268","tests/regression.rs":"1c965fefb8c7a2b1dfdab3e3fdeebaf47846555c50c8005e5537f96a52a3e252","tests/regression_fuzz.rs":"a504ec563e0d23bd2039493b7b1767fe1f831d7d668f6f4b2ecd124fc7899bcd","tests/replace.rs":"0efa042c0d531911e8ac41ce98a6b60236cbf40954102c59f9f6dea78d9d74dd","tests/searcher.rs":"ce35e47b0a276a7e8c9060c6a0b225ffba163aebc61fbc15555a6897fa0e552c","tests/set.rs":"f1e2af6baeeaed3cc99ed347ff516fe7b2eb0027ef64b891502e1486598eaf8a","tests/shortest_match.rs":"a2c94390c0d61bc24796b4c1288c924e90c8c9c6156fdebb858175177a194a42","tests/suffix_reverse.rs":"b95f89397404871227d9efe6df23b9ded147f183db81597e608f693955c668b5","tests/test_backtrack.rs":"b70c5e5f1241efd76dd9f9dd4a4df8a7b38113bd407d1f5f56867f1176177a59","tests/test_backtrack_bytes.rs":"b8a111d4b4109c8bba7e2afb650572c495a14d357fb1f743c1076fb001f704b5","tests/test_backtrack_utf8bytes.rs":"c0c279785d18beac2b4e178e7bf6c14ed235d65f00ca467cfd9c333d79487649","tests/test_crates_regex.rs":"fd9525c2eef0e2f8cb7f787bc2b721bcd0b5d84f3bca49adfe48d657a99c721a","tests/test_default.rs":"c2dfa0298896f86f1be2abf6b0c347a7ca12f95aeac92bf614dc3b86bdfff269","tests/test_default_bytes.rs":"831d3e6bfb882feb15f700e30304bd34328f888fb4c15c7169371e25024ce9a7","tests/test_nfa.rs":"f119fc43a018249c39c813d57096b0654ff69f337345f2bbd9b0e61cc9137285","tests/test_nfa_bytes.rs":"89eae3bef6a1d0bcea6b5de5be35ad72f613f2ceb8b58fe82a6c6ef2ccdc07d0","tests/test_nfa_utf8bytes.rs":"7d830b4aa401887d7cf098b62fed4cd8017ef8b61f625c7c9a2159a6b4cfeb71","tests/unicode.rs":"4bf85f5c3d547fa8b5623194a09b6413067499dfbe7c1d29d8b50bf1cddacf6b","tests/word_boundary.rs":"7081317ddcec1e82dd4a2090a571c6abf2ff4bbfa8cd10395e1eb3f386157fae","tests/word_boundary_ascii.rs":"cd0be5b5b485de0ba7994b42e2864585556c3d2d8bf5eab05b58931d9aaf4b87","tests/word_boundary_unicode.rs":"75dbcc35d3abc0f9795c2ea99e216dc227b0a5b58e9ca5eef767815ff0513921"},"package":"d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"1034edbdcb6cbd83b9e9a1dc3dfcdfd6c852112ab402a1cc83734191ea7b3a29","Cargo.lock":"27cdf849031e8c491581b3a436b119e2cd0106fcd94e159fc84751d3337b1684","Cargo.toml":"4a10b9986b5b858cb6ff3a8537492f4b6f7394289b991e182bfc10ad29c3323b","HACKING.md":"17818f7a17723608f6bdbe6388ad0a913d4f96f76a16649aaf4e274b1fa0ea97","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","PERFORMANCE.md":"0d5ef3866386918dfdefb1aa9a28cfe33cb3c8ceeb79f3f8ba5b88253dd95991","README.md":"6125b1c70b9b560412529c54dc6aacdfd39cc82f69b5ad7776fa86e4cb720347","UNICODE.md":"a8a8399540eed000d19420135a527f400247a04572e44d124c786b870f518776","examples/regexdna-input.txt":"156a49710bb3e1ed4bc2bbb0af0f383b747b3d0281453cfff39c296124c598f8","examples/regexdna-output.txt":"35e85b19b70a893d752fd43e54e1e9da08bac43559191cea85b33387c24c4cc1","examples/shootout-regex-dna-bytes.rs":"fa2daedb4e0a05f64f33f4af62fbb0176db998e3676f8637ab684b725367a7b4","examples/shootout-regex-dna-cheat.rs":"1f871a6eaaf8372299fa3c762051112fa89a14235b03f734fc50ebd51ecaee72","examples/shootout-regex-dna-replace.rs":"32ffdf13ac6c4ce3fc32116a048e9cc682aa34cdb8e5beaf565a22addbdcd9ab","examples/shootout-regex-dna-single-cheat.rs":"809f75bf1e1917a53623eb6f1a3ce3b7d2ed98a6a1dbc0bd4853bec49a0c6f94","examples/shootout-regex-dna-single.rs":"1ab14f5703cd4be2e75a2e792e0ba1d322b9e4b14535d396805a4316d577f5bb","examples/shootout-regex-dna.rs":"20ea46ab63f91e3ac6a64e997eadd436a9cbc2f1bdade28e4512052f0e25bc34","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/backtrack.rs":"52987d80448f3d7f5d4e3545ddfc09f1f30de7602d9b5489961db4b215a377fd","src/compile.rs":"79a59be2d2db650b5a322e15e9bf1d3227944410bc780fc6089da8f4d2609b77","src/dfa.rs":"10273980d1f08aaff495e11efa240249a2b2c08a4db7c49c8d6759bc65a3b174","src/error.rs":"71c85db839514f26ee024a689061743ea94a34eb7a3291e6c2b69b45a9682d09","src/exec.rs":"21495ab6813598204a444aeea3a0121674081389fd0f07fc3443eb8858b1c677","src/expand.rs":"71220309a3bac797f55129f49e79c03e96efec894ea338c735b78695367e04ca","src/find_byte.rs":"b387247b77e3269f057c3399aefe5a815032c3af918c876f80eb4b282e4eb95e","src/freqs.rs":"255555f3d95b08a5bb3bc2f38d5a06cc100a39c0f0127fe4f50c33afa1cadc65","src/input.rs":"13f49c1bce2fadd04a45b421d374cd0f8b72bef83f7e8fda958962aaccbe799a","src/lib.rs":"de28e1ad68d4b35750667c7fbb47915e6c159ef04b148f16c3507a0a7a682f96","src/literal/imp.rs":"b7f63a861c299bea4baaab17353a420ee339c2cf76d3858c95f39342bd4463e7","src/literal/mod.rs":"533f1d68af088e9485170145e27518368e541a0337fdb44f63249ebf97310300","src/pattern.rs":"993d8b6b4bcea5e02bee3c76e17c356a5a47f8fc53c5555edfd1ebb71c0878bf","src/pikevm.rs":"6c0eaa7e878c945ac4c3c545c98f5706ad04846fc432a5086c8ee78eb030dfa7","src/pool.rs":"942e991ae31ef349bd76efd78b2a712c01166dec965bf93742977ed0870d5a10","src/prog.rs":"bebb3e50745bbc05d6c8240d972ba55a1818c51b1161dc1c21f3fe13c11d4884","src/re_builder.rs":"943344bf6e2fc90902ee04b11b741c32418ac6814b21b7982cc0a3a817713f3e","src/re_bytes.rs":"e2eddc896cea1e878716e77798a8146a67d1d8d9bcf4d053155c1caf3b8f5518","src/re_set.rs":"7921ac4a919b7a5deffe82d099a9ccaf5487aebd890dfb7a661e602c6ad3f1a9","src/re_trait.rs":"d237121b6f6b606836c72305cbcb3bbdbc54d1f6827d19a19cd0fbb4372e0145","src/re_unicode.rs":"ba4d793ff194bfd33a3735e3664c7590f5f166c452e7632a25e4558ffba14e5a","src/sparse.rs":"0da3ddb7972109869248a764dbb10254555f4bb51c375e89fb3fab9cafa47320","src/testdata/LICENSE":"58cf078acc03da3e280a938c2bd9943f554fc9b6ced89ad93ba35ca436872899","src/testdata/README":"45f869e37f798905c773bfbe0ef19a5fb7e585cbf0b7c21b5b5a784e8cec3c14","src/testdata/basic.dat":"b5b33aa89d48a61cd67cb1fbfd8f70e62c83e30b86256f9f915a5190dd38ff06","src/testdata/nullsubexpr.dat":"496ac0278eec3b6d9170faace14554569032dd3d909618364d9326156de39ecf","src/testdata/repetition.dat":"1f7959063015b284b18a4a2c1c8b416d438a2d6c4b1a362da43406b865f50e69","src/utf8.rs":"f85a356ff5d5b19e417b73ce1dd84581b21d283f6dddd195547c30af9c60bd1a","test":"0d62fdca7da12fc19ea5306b5de1d83e68d9365a029c043d524334da138b0304","tests/api.rs":"7b2a0ef75e99b9776094967bd66e9cdeaa8e11359f5f0a12bd08ef0e8d0c11fc","tests/api_str.rs":"2ae38c04e7e8fac008b609a820d0b1561ba75f39b0edc0987d6d3d06132da77f","tests/bytes.rs":"edc50f526c5fee43df89d639ef18b237e4eb91e9d533bfc43f3cbab7417d38ba","tests/consistent.rs":"d69435154c09478076497216e43081a835ac65147181a4fbddad7bff469605b2","tests/crates_regex.rs":"91a59d470e0700b4bcb3ff735d06799f3107b8ef4875a2e9904607b164be0326","tests/crazy.rs":"c0d56380dff19bdd5d7a3eb731d0e2dc564e169a1b73c81e1879b1e87f5f5f77","tests/flags.rs":"05caace2c81a99d2168037f3a38035d4dffe9f85ef3ebd7ef18b1bc6612f1ea8","tests/fowler.rs":"d78cf914de40b1e125cc92b65ccb444d462586bd07b5e05de4e4a1b5de16aa76","tests/macros.rs":"6db70c16fc90df13e6b30d2b606f8b6dd4dc976697967f6ee001b15aab6d0b19","tests/macros_bytes.rs":"a049f528a93173a1bb176cd46932dce1880679f4a1752e099be920f0e4546fd0","tests/macros_str.rs":"e585b1461374c45a2eca44ca045bc3c1fe984b2b4212e432b0c695b420e708b7","tests/misc.rs":"395f52793fa022e4cdda78675b6a6fba1a3106b4b99c834c39f7801574054bd1","tests/multiline.rs":"1b1a3326ed976437c1357f01d81833ece7ea244f38826246eab55cacd5d0862a","tests/noparse.rs":"12b6be0eff3d80779d33c6459396c74c0f6ebf4ddc9f1d33c3e747ea9e3bf268","tests/regression.rs":"1c965fefb8c7a2b1dfdab3e3fdeebaf47846555c50c8005e5537f96a52a3e252","tests/regression_fuzz.rs":"a504ec563e0d23bd2039493b7b1767fe1f831d7d668f6f4b2ecd124fc7899bcd","tests/replace.rs":"0efa042c0d531911e8ac41ce98a6b60236cbf40954102c59f9f6dea78d9d74dd","tests/searcher.rs":"ce35e47b0a276a7e8c9060c6a0b225ffba163aebc61fbc15555a6897fa0e552c","tests/set.rs":"f1e2af6baeeaed3cc99ed347ff516fe7b2eb0027ef64b891502e1486598eaf8a","tests/shortest_match.rs":"a2c94390c0d61bc24796b4c1288c924e90c8c9c6156fdebb858175177a194a42","tests/suffix_reverse.rs":"b95f89397404871227d9efe6df23b9ded147f183db81597e608f693955c668b5","tests/test_backtrack.rs":"b70c5e5f1241efd76dd9f9dd4a4df8a7b38113bd407d1f5f56867f1176177a59","tests/test_backtrack_bytes.rs":"b8a111d4b4109c8bba7e2afb650572c495a14d357fb1f743c1076fb001f704b5","tests/test_backtrack_utf8bytes.rs":"c0c279785d18beac2b4e178e7bf6c14ed235d65f00ca467cfd9c333d79487649","tests/test_crates_regex.rs":"fd9525c2eef0e2f8cb7f787bc2b721bcd0b5d84f3bca49adfe48d657a99c721a","tests/test_default.rs":"c2dfa0298896f86f1be2abf6b0c347a7ca12f95aeac92bf614dc3b86bdfff269","tests/test_default_bytes.rs":"831d3e6bfb882feb15f700e30304bd34328f888fb4c15c7169371e25024ce9a7","tests/test_nfa.rs":"f119fc43a018249c39c813d57096b0654ff69f337345f2bbd9b0e61cc9137285","tests/test_nfa_bytes.rs":"89eae3bef6a1d0bcea6b5de5be35ad72f613f2ceb8b58fe82a6c6ef2ccdc07d0","tests/test_nfa_utf8bytes.rs":"7d830b4aa401887d7cf098b62fed4cd8017ef8b61f625c7c9a2159a6b4cfeb71","tests/unicode.rs":"1af9db7f09a6b0113b8a64733e06c8415fef720b2fdef227ae398d94332287cd","tests/word_boundary.rs":"7081317ddcec1e82dd4a2090a571c6abf2ff4bbfa8cd10395e1eb3f386157fae","tests/word_boundary_ascii.rs":"cd0be5b5b485de0ba7994b42e2864585556c3d2d8bf5eab05b58931d9aaf4b87","tests/word_boundary_unicode.rs":"75dbcc35d3abc0f9795c2ea99e216dc227b0a5b58e9ca5eef767815ff0513921"},"package":"4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"} \ No newline at end of file
diff --git a/vendor/regex/CHANGELOG.md b/vendor/regex/CHANGELOG.md
index 26f9955b8..f2d45ed73 100644
--- a/vendor/regex/CHANGELOG.md
+++ b/vendor/regex/CHANGELOG.md
@@ -1,3 +1,24 @@
+1.6.0 (2022-07-05)
+==================
+This release principally includes an upgrade to Unicode 14.
+
+New features:
+
+* [FEATURE #832](https://github.com/rust-lang/regex/pull/832):
+ Clarify that `Captures::len` includes all groups, not just matching groups.
+* [FEATURE #857](https://github.com/rust-lang/regex/pull/857):
+ Add an `ExactSizeIterator` impl for `SubCaptureMatches`.
+* [FEATURE #861](https://github.com/rust-lang/regex/pull/861):
+ Improve `RegexSet` documentation examples.
+* [FEATURE #877](https://github.com/rust-lang/regex/issues/877):
+ Upgrade to Unicode 14.
+
+Bug fixes:
+
+* [BUG #792](https://github.com/rust-lang/regex/issues/792):
+ Fix error message rendering bug.
+
+
1.5.6 (2022-05-20)
==================
This release includes a few bug fixes, including a bug that produced incorrect
diff --git a/vendor/regex/Cargo.lock b/vendor/regex/Cargo.lock
index 897a4a32f..fd2c1101d 100644
--- a/vendor/regex/Cargo.lock
+++ b/vendor/regex/Cargo.lock
@@ -19,9 +19,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
@@ -36,9 +36,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[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"
[[package]]
name = "memchr"
@@ -75,7 +75,7 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.5.6"
+version = "1.6.0"
dependencies = [
"aho-corasick",
"lazy_static",
@@ -87,12 +87,12 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.26"
+version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
+version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
diff --git a/vendor/regex/Cargo.toml b/vendor/regex/Cargo.toml
index 772bdb372..abe6ac033 100644
--- a/vendor/regex/Cargo.toml
+++ b/vendor/regex/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "regex"
-version = "1.5.6"
+version = "1.6.0"
authors = ["The Rust Project Developers"]
exclude = [
"/scripts/*",
@@ -88,7 +88,7 @@ version = "2.4.0"
optional = true
[dependencies.regex-syntax]
-version = "0.6.26"
+version = "0.6.27"
default-features = false
[dev-dependencies.lazy_static]
diff --git a/vendor/regex/src/backtrack.rs b/vendor/regex/src/backtrack.rs
index a3d25d662..4d83856ca 100644
--- a/vendor/regex/src/backtrack.rs
+++ b/vendor/regex/src/backtrack.rs
@@ -93,13 +93,7 @@ impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
let mut cache = cache.borrow_mut();
let cache = &mut cache.backtrack;
let start = input.at(start);
- let mut b = Bounded {
- prog: prog,
- input: input,
- matches: matches,
- slots: slots,
- m: cache,
- };
+ let mut b = Bounded { prog, input, matches, slots, m: cache };
b.exec_(start, end)
}
@@ -220,14 +214,14 @@ impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
// job is popped and the old capture index is restored.
self.m.jobs.push(Job::SaveRestore {
slot: inst.slot,
- old_pos: old_pos,
+ old_pos,
});
self.slots[inst.slot] = Some(at.pos());
}
ip = inst.goto;
}
Split(ref inst) => {
- self.m.jobs.push(Job::Inst { ip: inst.goto2, at: at });
+ self.m.jobs.push(Job::Inst { ip: inst.goto2, at });
ip = inst.goto1;
}
EmptyLook(ref inst) => {
diff --git a/vendor/regex/src/compile.rs b/vendor/regex/src/compile.rs
index 069f445c8..90ca25015 100644
--- a/vendor/regex/src/compile.rs
+++ b/vendor/regex/src/compile.rs
@@ -149,7 +149,8 @@ impl Compiler {
self.compiled.start = dotstar_patch.entry;
}
self.compiled.captures = vec![None];
- let patch = self.c_capture(0, expr)?.unwrap_or(self.next_inst());
+ let patch =
+ self.c_capture(0, expr)?.unwrap_or_else(|| self.next_inst());
if self.compiled.needs_dotstar() {
self.fill(dotstar_patch.hole, patch.entry);
} else {
@@ -185,7 +186,7 @@ impl Compiler {
self.fill_to_next(prev_hole);
let split = self.push_split_hole();
let Patch { hole, entry } =
- self.c_capture(0, expr)?.unwrap_or(self.next_inst());
+ self.c_capture(0, expr)?.unwrap_or_else(|| self.next_inst());
self.fill_to_next(hole);
self.compiled.matches.push(self.insts.len());
self.push_compiled(Inst::Match(i));
@@ -193,7 +194,7 @@ impl Compiler {
}
let i = exprs.len() - 1;
let Patch { hole, entry } =
- self.c_capture(0, &exprs[i])?.unwrap_or(self.next_inst());
+ self.c_capture(0, &exprs[i])?.unwrap_or_else(|| self.next_inst());
self.fill(prev_hole, entry);
self.fill_to_next(hole);
self.compiled.matches.push(self.insts.len());
@@ -410,11 +411,11 @@ impl Compiler {
} else {
let entry = self.insts.len();
let hole = self.push_hole(InstHole::Save { slot: first_slot });
- let patch = self.c(expr)?.unwrap_or(self.next_inst());
+ let patch = self.c(expr)?.unwrap_or_else(|| self.next_inst());
self.fill(hole, patch.entry);
self.fill_to_next(patch.hole);
let hole = self.push_hole(InstHole::Save { slot: first_slot + 1 });
- Ok(Some(Patch { hole: hole, entry: entry }))
+ Ok(Some(Patch { hole, entry }))
}
}
@@ -448,7 +449,7 @@ impl Compiler {
self.c_class(&[hir::ClassUnicodeRange::new(c, c)])
}
} else {
- let hole = self.push_hole(InstHole::Char { c: c });
+ let hole = self.push_hole(InstHole::Char { c });
Ok(Some(Patch { hole, entry: self.insts.len() - 1 }))
}
}
@@ -458,7 +459,7 @@ impl Compiler {
assert!(!ranges.is_empty());
if self.compiled.uses_bytes() {
- Ok(Some(CompileClass { c: self, ranges: ranges }.compile()?))
+ Ok(Some(CompileClass { c: self, ranges }.compile()?))
} else {
let ranges: Vec<(char, char)> =
ranges.iter().map(|r| (r.start(), r.end())).collect();
@@ -467,9 +468,9 @@ impl Compiler {
} else {
self.extra_inst_bytes +=
ranges.len() * (size_of::<char>() * 2);
- self.push_hole(InstHole::Ranges { ranges: ranges })
+ self.push_hole(InstHole::Ranges { ranges })
};
- Ok(Some(Patch { hole: hole, entry: self.insts.len() - 1 }))
+ Ok(Some(Patch { hole, entry: self.insts.len() - 1 }))
}
}
@@ -508,8 +509,8 @@ impl Compiler {
}
fn c_empty_look(&mut self, look: EmptyLook) -> ResultOrEmpty {
- let hole = self.push_hole(InstHole::EmptyLook { look: look });
- Ok(Some(Patch { hole: hole, entry: self.insts.len() - 1 }))
+ let hole = self.push_hole(InstHole::EmptyLook { look });
+ Ok(Some(Patch { hole, entry: self.insts.len() - 1 }))
}
fn c_concat<'a, I>(&mut self, exprs: I) -> ResultOrEmpty
@@ -533,7 +534,7 @@ impl Compiler {
hole = p.hole;
}
}
- Ok(Some(Patch { hole: hole, entry: entry }))
+ Ok(Some(Patch { hole, entry }))
}
fn c_alternate(&mut self, exprs: &[Hir]) -> ResultOrEmpty {
@@ -676,7 +677,7 @@ impl Compiler {
// None).
let patch_concat = self
.c_concat(iter::repeat(expr).take(min))?
- .unwrap_or(self.next_inst());
+ .unwrap_or_else(|| self.next_inst());
if let Some(patch_rep) = self.c_repeat_zero_or_more(expr, greedy)? {
self.fill(patch_concat.hole, patch_rep.entry);
Ok(Some(Patch { hole: patch_rep.hole, entry: patch_concat.entry }))
@@ -700,7 +701,7 @@ impl Compiler {
}
// Same reasoning as in c_repeat_range_min_or_more (we know that min <
// max at this point).
- let patch_concat = patch_concat.unwrap_or(self.next_inst());
+ let patch_concat = patch_concat.unwrap_or_else(|| self.next_inst());
let initial_entry = patch_concat.entry;
// It is much simpler to compile, e.g., `a{2,5}` as:
//
@@ -879,14 +880,14 @@ impl MaybeInst {
}
MaybeInst::Split1(goto1) => {
MaybeInst::Compiled(Inst::Split(InstSplit {
- goto1: goto1,
+ goto1,
goto2: goto,
}))
}
MaybeInst::Split2(goto2) => {
MaybeInst::Compiled(Inst::Split(InstSplit {
goto1: goto,
- goto2: goto2,
+ goto2,
}))
}
_ => unreachable!(
@@ -900,9 +901,7 @@ impl MaybeInst {
fn fill_split(&mut self, goto1: InstPtr, goto2: InstPtr) {
let filled = match *self {
- MaybeInst::Split => {
- Inst::Split(InstSplit { goto1: goto1, goto2: goto2 })
- }
+ MaybeInst::Split => Inst::Split(InstSplit { goto1, goto2 }),
_ => unreachable!(
"must be called on Split instruction, \
instead it was called on: {:?}",
@@ -960,19 +959,17 @@ enum InstHole {
impl InstHole {
fn fill(&self, goto: InstPtr) -> Inst {
match *self {
- InstHole::Save { slot } => {
- Inst::Save(InstSave { goto: goto, slot: slot })
- }
+ InstHole::Save { slot } => Inst::Save(InstSave { goto, slot }),
InstHole::EmptyLook { look } => {
- Inst::EmptyLook(InstEmptyLook { goto: goto, look: look })
+ Inst::EmptyLook(InstEmptyLook { goto, look })
}
- InstHole::Char { c } => Inst::Char(InstChar { goto: goto, c: c }),
+ InstHole::Char { c } => Inst::Char(InstChar { goto, c }),
InstHole::Ranges { ref ranges } => Inst::Ranges(InstRanges {
- goto: goto,
+ goto,
ranges: ranges.clone().into_boxed_slice(),
}),
InstHole::Bytes { start, end } => {
- Inst::Bytes(InstBytes { goto: goto, start: start, end: end })
+ Inst::Bytes(InstBytes { goto, start, end })
}
}
}
@@ -1042,7 +1039,7 @@ impl<'a, 'b> CompileClass<'a, 'b> {
let mut last_hole = Hole::None;
for byte_range in seq {
let key = SuffixCacheKey {
- from_inst: from_inst,
+ from_inst,
start: byte_range.start,
end: byte_range.end,
};
@@ -1132,7 +1129,7 @@ impl SuffixCache {
}
}
*pos = self.dense.len();
- self.dense.push(SuffixCacheEntry { key: key, pc: pc });
+ self.dense.push(SuffixCacheEntry { key, pc });
None
}
@@ -1143,8 +1140,8 @@ impl SuffixCache {
fn hash(&self, suffix: &SuffixCacheKey) -> usize {
// Basic FNV-1a hash as described:
// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
- const FNV_PRIME: u64 = 1099511628211;
- let mut h = 14695981039346656037;
+ const FNV_PRIME: u64 = 1_099_511_628_211;
+ let mut h = 14_695_981_039_346_656_037;
h = (h ^ (suffix.from_inst as u64)).wrapping_mul(FNV_PRIME);
h = (h ^ (suffix.start as u64)).wrapping_mul(FNV_PRIME);
h = (h ^ (suffix.end as u64)).wrapping_mul(FNV_PRIME);
diff --git a/vendor/regex/src/dfa.rs b/vendor/regex/src/dfa.rs
index 4aee8039c..dc9952120 100644
--- a/vendor/regex/src/dfa.rs
+++ b/vendor/regex/src/dfa.rs
@@ -31,7 +31,7 @@ considerably more complex than one might expect out of a DFA. A number of
tricks are employed to make it fast. Tread carefully.
N.B. While this implementation is heavily commented, Russ Cox's series of
-articles on regexes is strongly recommended: https://swtch.com/~rsc/regexp/
+articles on regexes is strongly recommended: <https://swtch.com/~rsc/regexp/>
(As is the DFA implementation in RE2, which heavily influenced this
implementation.)
*/
@@ -454,10 +454,10 @@ impl<'a> Fsm<'a> {
let mut cache = cache.borrow_mut();
let cache = &mut cache.dfa;
let mut dfa = Fsm {
- prog: prog,
+ prog,
start: 0, // filled in below
- at: at,
- quit_after_match: quit_after_match,
+ at,
+ quit_after_match,
last_match_si: STATE_UNKNOWN,
last_cache_flush: at,
cache: &mut cache.inner,
@@ -484,10 +484,10 @@ impl<'a> Fsm<'a> {
let mut cache = cache.borrow_mut();
let cache = &mut cache.dfa_reverse;
let mut dfa = Fsm {
- prog: prog,
+ prog,
start: 0, // filled in below
- at: at,
- quit_after_match: quit_after_match,
+ at,
+ quit_after_match,
last_match_si: STATE_UNKNOWN,
last_cache_flush: at,
cache: &mut cache.inner,
@@ -515,9 +515,9 @@ impl<'a> Fsm<'a> {
let mut cache = cache.borrow_mut();
let cache = &mut cache.dfa;
let mut dfa = Fsm {
- prog: prog,
+ prog,
start: 0, // filled in below
- at: at,
+ at,
quit_after_match: false,
last_match_si: STATE_UNKNOWN,
last_cache_flush: at,
@@ -1606,11 +1606,7 @@ struct StateMap {
impl StateMap {
fn new(num_byte_classes: usize) -> StateMap {
- StateMap {
- map: HashMap::new(),
- states: vec![],
- num_byte_classes: num_byte_classes,
- }
+ StateMap { map: HashMap::new(), states: vec![], num_byte_classes }
}
fn len(&self) -> usize {
@@ -1646,7 +1642,7 @@ impl Transitions {
/// The number of byte classes corresponds to the stride. Every state will
/// have `num_byte_classes` slots for transitions.
fn new(num_byte_classes: usize) -> Transitions {
- Transitions { table: vec![], num_byte_classes: num_byte_classes }
+ Transitions { table: vec![], num_byte_classes }
}
/// Returns the total number of states currently in this table.
@@ -1696,27 +1692,27 @@ impl Transitions {
impl StateFlags {
fn is_match(&self) -> bool {
- self.0 & 0b0000000_1 > 0
+ self.0 & 0b0000_0001 > 0
}
fn set_match(&mut self) {
- self.0 |= 0b0000000_1;
+ self.0 |= 0b0000_0001;
}
fn is_word(&self) -> bool {
- self.0 & 0b000000_1_0 > 0
+ self.0 & 0b0000_0010 > 0
}
fn set_word(&mut self) {
- self.0 |= 0b000000_1_0;
+ self.0 |= 0b0000_0010;
}
fn has_empty(&self) -> bool {
- self.0 & 0b00000_1_00 > 0
+ self.0 & 0b0000_0100 > 0
}
fn set_empty(&mut self) {
- self.0 |= 0b00000_1_00;
+ self.0 |= 0b0000_0100;
}
}
diff --git a/vendor/regex/src/exec.rs b/vendor/regex/src/exec.rs
index d5fad1c0e..e75ca083a 100644
--- a/vendor/regex/src/exec.rs
+++ b/vendor/regex/src/exec.rs
@@ -288,10 +288,10 @@ impl ExecBuilder {
exprs.push(expr);
}
Ok(Parsed {
- exprs: exprs,
+ exprs,
prefixes: prefixes.unwrap_or_else(Literals::empty),
suffixes: suffixes.unwrap_or_else(Literals::empty),
- bytes: bytes,
+ bytes,
})
}
@@ -311,7 +311,7 @@ impl ExecBuilder {
match_type: MatchType::Nothing,
});
let pool = ExecReadOnly::new_pool(&ro);
- return Ok(Exec { ro: ro, pool });
+ return Ok(Exec { ro, pool });
}
let parsed = self.parse()?;
let mut nfa = Compiler::new()
@@ -340,12 +340,12 @@ impl ExecBuilder {
let mut ro = ExecReadOnly {
res: self.options.pats,
- nfa: nfa,
- dfa: dfa,
- dfa_reverse: dfa_reverse,
+ nfa,
+ dfa,
+ dfa_reverse,
suffixes: LiteralSearcher::suffixes(parsed.suffixes),
#[cfg(feature = "perf-literal")]
- ac: ac,
+ ac,
match_type: MatchType::Nothing,
};
ro.match_type = ro.choose_match_type(self.match_type);
diff --git a/vendor/regex/src/expand.rs b/vendor/regex/src/expand.rs
index fd9c2d05d..67b514926 100644
--- a/vendor/regex/src/expand.rs
+++ b/vendor/regex/src/expand.rs
@@ -127,7 +127,7 @@ impl From<usize> for Ref<'static> {
/// If no such valid reference could be found, None is returned.
fn find_cap_ref(replacement: &[u8]) -> Option<CaptureRef<'_>> {
let mut i = 0;
- let rep: &[u8] = replacement.as_ref();
+ let rep: &[u8] = replacement;
if rep.len() <= 1 || rep[0] != b'$' {
return None;
}
@@ -136,7 +136,7 @@ fn find_cap_ref(replacement: &[u8]) -> Option<CaptureRef<'_>> {
return find_cap_ref_braced(rep, i + 1);
}
let mut cap_end = i;
- while rep.get(cap_end).map_or(false, is_valid_cap_letter) {
+ while rep.get(cap_end).copied().map_or(false, is_valid_cap_letter) {
cap_end += 1;
}
if cap_end == i {
@@ -183,8 +183,8 @@ fn find_cap_ref_braced(rep: &[u8], mut i: usize) -> Option<CaptureRef<'_>> {
}
/// Returns true if and only if the given byte is allowed in a capture name.
-fn is_valid_cap_letter(b: &u8) -> bool {
- match *b {
+fn is_valid_cap_letter(b: u8) -> bool {
+ match b {
b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'_' => true,
_ => false,
}
diff --git a/vendor/regex/src/input.rs b/vendor/regex/src/input.rs
index 5d50ee340..df6c3e0c9 100644
--- a/vendor/regex/src/input.rs
+++ b/vendor/regex/src/input.rs
@@ -160,7 +160,7 @@ impl<'t> Input for CharInput<'t> {
InputAt { pos: self.len(), c: None.into(), byte: None, len: 0 }
} else {
let c = decode_utf8(&self[i..]).map(|(c, _)| c).into();
- InputAt { pos: i, c: c, byte: None, len: c.len_utf8() }
+ InputAt { pos: i, c, byte: None, len: c.len_utf8() }
}
}
@@ -231,7 +231,7 @@ pub struct ByteInput<'t> {
impl<'t> ByteInput<'t> {
/// Return a new byte-based input reader for the given string.
pub fn new(text: &'t [u8], only_utf8: bool) -> ByteInput<'t> {
- ByteInput { text: text, only_utf8: only_utf8 }
+ ByteInput { text, only_utf8 }
}
}
diff --git a/vendor/regex/src/lib.rs b/vendor/regex/src/lib.rs
index 7f2dec815..3e3b0a007 100644
--- a/vendor/regex/src/lib.rs
+++ b/vendor/regex/src/lib.rs
@@ -628,7 +628,6 @@ pub use crate::re_builder::unicode::*;
#[cfg(feature = "std")]
pub use crate::re_set::unicode::*;
#[cfg(feature = "std")]
-#[cfg(feature = "std")]
pub use crate::re_unicode::{
escape, CaptureLocations, CaptureMatches, CaptureNames, Captures,
Locations, Match, Matches, NoExpand, Regex, Replacer, ReplacerRef, Split,
diff --git a/vendor/regex/src/literal/imp.rs b/vendor/regex/src/literal/imp.rs
index 82f050a0d..90b2f1160 100644
--- a/vendor/regex/src/literal/imp.rs
+++ b/vendor/regex/src/literal/imp.rs
@@ -57,10 +57,10 @@ impl LiteralSearcher {
fn new(lits: Literals, matcher: Matcher) -> Self {
let complete = lits.all_complete();
LiteralSearcher {
- complete: complete,
+ complete,
lcp: Memmem::new(lits.longest_common_prefix()),
lcs: Memmem::new(lits.longest_common_suffix()),
- matcher: matcher,
+ matcher,
}
}
diff --git a/vendor/regex/src/pattern.rs b/vendor/regex/src/pattern.rs
index b4ffd8e16..00549e510 100644
--- a/vendor/regex/src/pattern.rs
+++ b/vendor/regex/src/pattern.rs
@@ -15,7 +15,7 @@ impl<'r, 't> Pattern<'t> for &'r Regex {
fn into_searcher(self, haystack: &'t str) -> RegexSearcher<'r, 't> {
RegexSearcher {
- haystack: haystack,
+ haystack,
it: self.find_iter(haystack),
last_step_end: 0,
next_match: None,
diff --git a/vendor/regex/src/pikevm.rs b/vendor/regex/src/pikevm.rs
index 9a1424086..8c9eac2d3 100644
--- a/vendor/regex/src/pikevm.rs
+++ b/vendor/regex/src/pikevm.rs
@@ -100,7 +100,7 @@ impl<'r, I: Input> Fsm<'r, I> {
cache.clist.resize(prog.len(), prog.captures.len());
cache.nlist.resize(prog.len(), prog.captures.len());
let at = input.at(start);
- Fsm { prog: prog, stack: &mut cache.stack, input: input }.exec_(
+ Fsm { prog, stack: &mut cache.stack, input }.exec_(
&mut cache.clist,
&mut cache.nlist,
matches,
diff --git a/vendor/regex/src/prog.rs b/vendor/regex/src/prog.rs
index 475a8112a..c211f71d8 100644
--- a/vendor/regex/src/prog.rs
+++ b/vendor/regex/src/prog.rs
@@ -233,7 +233,7 @@ impl fmt::Debug for Program {
if pc == self.start {
write!(f, " (start)")?;
}
- write!(f, "\n")?;
+ writeln!(f)?;
}
Ok(())
}
diff --git a/vendor/regex/src/re_bytes.rs b/vendor/regex/src/re_bytes.rs
index ae55d6d25..d71969257 100644
--- a/vendor/regex/src/re_bytes.rs
+++ b/vendor/regex/src/re_bytes.rs
@@ -53,7 +53,7 @@ impl<'t> Match<'t> {
/// Creates a new match from the given haystack and byte offsets.
#[inline]
fn new(haystack: &'t [u8], start: usize, end: usize) -> Match<'t> {
- Match { text: haystack, start: start, end: end }
+ Match { text: haystack, start, end }
}
}
@@ -255,7 +255,7 @@ impl Regex {
pub fn captures<'t>(&self, text: &'t [u8]) -> Option<Captures<'t>> {
let mut locs = self.capture_locations();
self.captures_read_at(&mut locs, text, 0).map(move |_| Captures {
- text: text,
+ text,
locs: locs.0,
named_groups: self.0.capture_name_idx().clone(),
})
@@ -578,7 +578,7 @@ impl Regex {
/// context into consideration. For example, the `\A` anchor can only
/// match when `start == 0`.
pub fn is_match_at(&self, text: &[u8], start: usize) -> bool {
- self.shortest_match_at(text, start).is_some()
+ self.0.searcher().is_match_at(text, start)
}
/// Returns the same as find, but starts the search at the given
@@ -723,7 +723,7 @@ impl<'r, 't> Iterator for CaptureMatches<'r, 't> {
fn next(&mut self) -> Option<Captures<'t>> {
self.0.next().map(|locs| Captures {
text: self.0.text(),
- locs: locs,
+ locs,
named_groups: self.0.regex().capture_name_idx().clone(),
})
}
@@ -877,7 +877,7 @@ impl CaptureLocations {
self.0.pos(i)
}
- /// Returns the total number of capturing groups.
+ /// Returns the total number of capture groups (even if they didn't match).
///
/// This is always at least `1` since every regex has at least `1`
/// capturing group that corresponds to the entire match.
@@ -979,7 +979,7 @@ impl<'t> Captures<'t> {
expand_bytes(self, replacement, dst)
}
- /// Returns the number of captured groups.
+ /// Returns the total number of capture groups (even if they didn't match).
///
/// This is always at least `1`, since every regex has at least one capture
/// group that corresponds to the full match.
diff --git a/vendor/regex/src/re_set.rs b/vendor/regex/src/re_set.rs
index 73d59532e..a6d886d76 100644
--- a/vendor/regex/src/re_set.rs
+++ b/vendor/regex/src/re_set.rs
@@ -59,13 +59,45 @@ $(#[$doc_regexset_example])*
/// 1. Does any regex in the set match?
/// 2. If so, which regexes in the set match?
///
-/// As with the main `Regex` type, it is cheaper to ask (1) instead of (2)
-/// since the matching engines can stop after the first match is found.
+/// As with the main [`Regex`][crate::Regex] type, it is cheaper to ask (1)
+/// instead of (2) since the matching engines can stop after the first match
+/// is found.
///
-/// Other features like finding the location of successive matches or their
-/// sub-captures aren't supported. If you need this functionality, the
-/// recommended approach is to compile each regex in the set independently and
-/// selectively match them based on which regexes in the set matched.
+/// You cannot directly extract [`Match`][crate::Match] or
+/// [`Captures`][crate::Captures] objects from a regex set. If you need these
+/// operations, the recommended approach is to compile each pattern in the set
+/// independently and scan the exact same input a second time with those
+/// independently compiled patterns:
+///
+/// ```rust
+/// use regex::{Regex, RegexSet};
+///
+/// let patterns = ["foo", "bar"];
+/// // Both patterns will match different ranges of this string.
+/// let text = "barfoo";
+///
+/// // Compile a set matching any of our patterns.
+/// let set = RegexSet::new(&patterns).unwrap();
+/// // Compile each pattern independently.
+/// let regexes: Vec<_> = set.patterns().iter()
+/// .map(|pat| Regex::new(pat).unwrap())
+/// .collect();
+///
+/// // Match against the whole set first and identify the individual
+/// // matching patterns.
+/// let matches: Vec<&str> = set.matches(text).into_iter()
+/// // Dereference the match index to get the corresponding
+/// // compiled pattern.
+/// .map(|match_idx| &regexes[match_idx])
+/// // To get match locations or any other info, we then have to search
+/// // the exact same text again, using our separately-compiled pattern.
+/// .map(|pat| pat.find(text).unwrap().as_str())
+/// .collect();
+///
+/// // Matches arrive in the order the constituent patterns were declared,
+/// // not the order they appear in the input.
+/// assert_eq!(vec!["foo", "bar"], matches);
+/// ```
///
/// # Performance
///
diff --git a/vendor/regex/src/re_trait.rs b/vendor/regex/src/re_trait.rs
index 680aa5459..d0c717df5 100644
--- a/vendor/regex/src/re_trait.rs
+++ b/vendor/regex/src/re_trait.rs
@@ -74,8 +74,19 @@ impl<'c> Iterator for SubCapturesPosIter<'c> {
self.idx += 1;
x
}
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.locs.len() - self.idx;
+ (len, Some(len))
+ }
+
+ fn count(self) -> usize {
+ self.len()
+ }
}
+impl<'c> ExactSizeIterator for SubCapturesPosIter<'c> {}
+
impl<'c> FusedIterator for SubCapturesPosIter<'c> {}
/// `RegularExpression` describes types that can implement regex searching.
@@ -139,7 +150,7 @@ pub trait RegularExpression: Sized + fmt::Debug {
/// Returns an iterator over all non-overlapping successive leftmost-first
/// matches.
fn find_iter(self, text: &Self::Text) -> Matches<'_, Self> {
- Matches { re: self, text: text, last_end: 0, last_match: None }
+ Matches { re: self, text, last_end: 0, last_match: None }
}
/// Returns an iterator over all non-overlapping successive leftmost-first
diff --git a/vendor/regex/src/re_unicode.rs b/vendor/regex/src/re_unicode.rs
index e4871a621..60d81a7d9 100644
--- a/vendor/regex/src/re_unicode.rs
+++ b/vendor/regex/src/re_unicode.rs
@@ -61,7 +61,7 @@ impl<'t> Match<'t> {
/// Creates a new match from the given haystack and byte offsets.
#[inline]
fn new(haystack: &'t str, start: usize, end: usize) -> Match<'t> {
- Match { text: haystack, start: start, end: end }
+ Match { text: haystack, start, end }
}
}
@@ -129,7 +129,7 @@ impl<'t> From<Match<'t>> for Range<usize> {
/// assert!(haystack.contains(&re));
/// assert_eq!(haystack.find(&re), Some(1));
/// assert_eq!(haystack.match_indices(&re).collect::<Vec<_>>(),
-/// vec![(1, 4), (5, 8)]);
+/// vec![(1, "111"), (5, "222")]);
/// assert_eq!(haystack.split(&re).collect::<Vec<_>>(), vec!["a", "b", "c"]);
/// ```
#[derive(Clone)]
@@ -311,7 +311,7 @@ impl Regex {
pub fn captures<'t>(&self, text: &'t str) -> Option<Captures<'t>> {
let mut locs = self.capture_locations();
self.captures_read_at(&mut locs, text, 0).map(move |_| Captures {
- text: text,
+ text,
locs: locs.0,
named_groups: self.0.capture_name_idx().clone(),
})
@@ -636,7 +636,7 @@ impl Regex {
/// context into consideration. For example, the `\A` anchor can only
/// match when `start == 0`.
pub fn is_match_at(&self, text: &str, start: usize) -> bool {
- self.shortest_match_at(text, start).is_some()
+ self.0.searcher_str().is_match_at(text, start)
}
/// Returns the same as find, but starts the search at the given
@@ -887,7 +887,7 @@ impl CaptureLocations {
self.0.pos(i)
}
- /// Returns the total number of capturing groups.
+ /// Returns the total number of capture groups (even if they didn't match).
///
/// This is always at least `1` since every regex has at least `1`
/// capturing group that corresponds to the entire match.
@@ -989,7 +989,7 @@ impl<'t> Captures<'t> {
expand_str(self, replacement, dst)
}
- /// Returns the number of captured groups.
+ /// Returns the total number of capture groups (even if they didn't match).
///
/// This is always at least `1`, since every regex has at least one capture
/// group that corresponds to the full match.
@@ -1092,8 +1092,18 @@ impl<'c, 't> Iterator for SubCaptureMatches<'c, 't> {
.next()
.map(|cap| cap.map(|(s, e)| Match::new(self.caps.text, s, e)))
}
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.it.size_hint()
+ }
+
+ fn count(self) -> usize {
+ self.it.count()
+ }
}
+impl<'c, 't> ExactSizeIterator for SubCaptureMatches<'c, 't> {}
+
impl<'c, 't> FusedIterator for SubCaptureMatches<'c, 't> {}
/// An iterator that yields all non-overlapping capture groups matching a
@@ -1114,7 +1124,7 @@ impl<'r, 't> Iterator for CaptureMatches<'r, 't> {
fn next(&mut self) -> Option<Captures<'t>> {
self.0.next().map(|locs| Captures {
text: self.0.text(),
- locs: locs,
+ locs,
named_groups: self.0.regex().capture_name_idx().clone(),
})
}
diff --git a/vendor/regex/src/utf8.rs b/vendor/regex/src/utf8.rs
index 6e0608fdb..2dfd2c0d1 100644
--- a/vendor/regex/src/utf8.rs
+++ b/vendor/regex/src/utf8.rs
@@ -108,7 +108,7 @@ pub fn decode_utf8(src: &[u8]) -> Option<(char, usize)> {
| ((b2 & !TAG_CONT) as u32) << 6
| ((b3 & !TAG_CONT) as u32);
match cp {
- 0x10000..=0x10FFFF => char::from_u32(cp).map(|cp| (cp, 4)),
+ 0x10000..=0x0010_FFFF => char::from_u32(cp).map(|cp| (cp, 4)),
_ => None,
}
}
diff --git a/vendor/regex/tests/unicode.rs b/vendor/regex/tests/unicode.rs
index 9f1cd0c01..9b3228624 100644
--- a/vendor/regex/tests/unicode.rs
+++ b/vendor/regex/tests/unicode.rs
@@ -232,3 +232,20 @@ mat!(uni_class_sb2, r"\p{sb=lower}", "\u{0469}", Some((0, 2)));
mat!(uni_class_sb3, r"\p{sb=Close}", "\u{FF60}", Some((0, 3)));
mat!(uni_class_sb4, r"\p{sb=Close}", "\u{1F677}", Some((0, 4)));
mat!(uni_class_sb5, r"\p{sb=SContinue}", "\u{FF64}", Some((0, 3)));
+
+// Test 'Vithkuqi' support, which was added in Unicode 14.
+// See: https://github.com/rust-lang/regex/issues/877
+mat!(
+ uni_vithkuqi_literal_upper,
+ r"(?i)^\u{10570}$",
+ "\u{10570}",
+ Some((0, 4))
+);
+mat!(
+ uni_vithkuqi_literal_lower,
+ r"(?i)^\u{10570}$",
+ "\u{10597}",
+ Some((0, 4))
+);
+mat!(uni_vithkuqi_word_upper, r"^\w$", "\u{10570}", Some((0, 4)));
+mat!(uni_vithkuqi_word_lower, r"^\w$", "\u{10597}", Some((0, 4)));
diff --git a/vendor/rustc_tools_util/.cargo-checksum.json b/vendor/rustc_tools_util/.cargo-checksum.json
deleted file mode 100644
index dfdd70670..000000000
--- a/vendor/rustc_tools_util/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"0b7a46457c09509e3c8b88aa27cb5988a6f944bc9e5491900220d0db2de88b16","README.md":"2a9e75d2e1fac7c92792fc7cef4a571c8fb86f8c99ba5dbd150ad08304757668","src/lib.rs":"9898dbb5d957bd7b13939db6c1181abcf7b1ae1c2fb9b26f6eaa229c211f6580"},"package":"b725dadae9fabc488df69a287f5a99c5eaf5d10853842a8a3dfac52476f544ee"} \ No newline at end of file
diff --git a/vendor/rustc_tools_util/Cargo.toml b/vendor/rustc_tools_util/Cargo.toml
deleted file mode 100644
index d3ec288f0..000000000
--- a/vendor/rustc_tools_util/Cargo.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-edition = "2018"
-name = "rustc_tools_util"
-version = "0.2.0"
-authors = ["Matthias Krüger <matthias.krueger@famsik.de>"]
-description = "small helper to generate version information for git packages"
-readme = "README.md"
-keywords = ["rustc", "tool", "git", "version", "hash"]
-categories = ["development-tools"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/rust-lang/rust-clippy"
-
-[dependencies]
diff --git a/vendor/rustc_tools_util/README.md b/vendor/rustc_tools_util/README.md
deleted file mode 100644
index 18341ca2f..000000000
--- a/vendor/rustc_tools_util/README.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# rustc_tools_util
-
-A small tool to help you generate version information
-for packages installed from a git repo
-
-## Usage
-
-Add a `build.rs` file to your repo and list it in `Cargo.toml`
-````
-build = "build.rs"
-````
-
-List rustc_tools_util as regular AND build dependency.
-````
-[dependencies]
-rustc_tools_util = "0.1"
-
-[build-dependencies]
-rustc_tools_util = "0.1"
-````
-
-In `build.rs`, generate the data in your `main()`
-````rust
-fn main() {
- println!(
- "cargo:rustc-env=GIT_HASH={}",
- rustc_tools_util::get_commit_hash().unwrap_or_default()
- );
- println!(
- "cargo:rustc-env=COMMIT_DATE={}",
- rustc_tools_util::get_commit_date().unwrap_or_default()
- );
- println!(
- "cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}",
- rustc_tools_util::get_channel().unwrap_or_default()
- );
-}
-
-````
-
-Use the version information in your main.rs
-````rust
-use rustc_tools_util::*;
-
-fn show_version() {
- let version_info = rustc_tools_util::get_version_info!();
- println!("{}", version_info);
-}
-````
-This gives the following output in clippy:
-`clippy 0.0.212 (a416c5e 2018-12-14)`
-
-
-## License
-
-Copyright 2014-2019 The Rust Project Developers
-
-Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-option. All files in the project carrying such notice may not be
-copied, modified, or distributed except according to those terms.
diff --git a/vendor/rustc_tools_util/src/lib.rs b/vendor/rustc_tools_util/src/lib.rs
deleted file mode 100644
index ec3b69219..000000000
--- a/vendor/rustc_tools_util/src/lib.rs
+++ /dev/null
@@ -1,158 +0,0 @@
-use std::env;
-
-#[macro_export]
-macro_rules! get_version_info {
- () => {{
- let major = env!("CARGO_PKG_VERSION_MAJOR").parse::<u8>().unwrap();
- let minor = env!("CARGO_PKG_VERSION_MINOR").parse::<u8>().unwrap();
- let patch = env!("CARGO_PKG_VERSION_PATCH").parse::<u16>().unwrap();
- let crate_name = String::from(env!("CARGO_PKG_NAME"));
-
- let host_compiler = option_env!("RUSTC_RELEASE_CHANNEL").map(str::to_string);
- let commit_hash = option_env!("GIT_HASH").map(str::to_string);
- let commit_date = option_env!("COMMIT_DATE").map(str::to_string);
-
- VersionInfo {
- major,
- minor,
- patch,
- host_compiler,
- commit_hash,
- commit_date,
- crate_name,
- }
- }};
-}
-
-// some code taken and adapted from RLS and cargo
-pub struct VersionInfo {
- pub major: u8,
- pub minor: u8,
- pub patch: u16,
- pub host_compiler: Option<String>,
- pub commit_hash: Option<String>,
- pub commit_date: Option<String>,
- pub crate_name: String,
-}
-
-impl std::fmt::Display for VersionInfo {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- let hash = self.commit_hash.clone().unwrap_or_default();
- let hash_trimmed = hash.trim();
-
- let date = self.commit_date.clone().unwrap_or_default();
- let date_trimmed = date.trim();
-
- if (hash_trimmed.len() + date_trimmed.len()) > 0 {
- write!(
- f,
- "{} {}.{}.{} ({} {})",
- self.crate_name, self.major, self.minor, self.patch, hash_trimmed, date_trimmed,
- )?;
- } else {
- write!(f, "{} {}.{}.{}", self.crate_name, self.major, self.minor, self.patch)?;
- }
-
- Ok(())
- }
-}
-
-impl std::fmt::Debug for VersionInfo {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(
- f,
- "VersionInfo {{ crate_name: \"{}\", major: {}, minor: {}, patch: {}",
- self.crate_name, self.major, self.minor, self.patch,
- )?;
- if self.commit_hash.is_some() {
- write!(
- f,
- ", commit_hash: \"{}\", commit_date: \"{}\" }}",
- self.commit_hash.clone().unwrap_or_default().trim(),
- self.commit_date.clone().unwrap_or_default().trim()
- )?;
- } else {
- write!(f, " }}")?;
- }
-
- Ok(())
- }
-}
-
-pub fn get_commit_hash() -> Option<String> {
- std::process::Command::new("git")
- .args(&["rev-parse", "--short", "HEAD"])
- .output()
- .ok()
- .and_then(|r| String::from_utf8(r.stdout).ok())
-}
-
-pub fn get_commit_date() -> Option<String> {
- std::process::Command::new("git")
- .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
- .output()
- .ok()
- .and_then(|r| String::from_utf8(r.stdout).ok())
-}
-
-pub fn get_channel() -> Option<String> {
- match env::var("CFG_RELEASE_CHANNEL") {
- Ok(channel) => Some(channel),
- Err(_) => {
- // if that failed, try to ask rustc -V, do some parsing and find out
- match std::process::Command::new("rustc")
- .arg("-V")
- .output()
- .ok()
- .and_then(|r| String::from_utf8(r.stdout).ok())
- {
- Some(rustc_output) => {
- if rustc_output.contains("beta") {
- Some(String::from("beta"))
- } else if rustc_output.contains("stable") {
- Some(String::from("stable"))
- } else {
- // default to nightly if we fail to parse
- Some(String::from("nightly"))
- }
- },
- // default to nightly
- None => Some(String::from("nightly")),
- }
- },
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn test_struct_local() {
- let vi = get_version_info!();
- assert_eq!(vi.major, 0);
- assert_eq!(vi.minor, 2);
- assert_eq!(vi.patch, 0);
- assert_eq!(vi.crate_name, "rustc_tools_util");
- // hard to make positive tests for these since they will always change
- assert!(vi.commit_hash.is_none());
- assert!(vi.commit_date.is_none());
- }
-
- #[test]
- fn test_display_local() {
- let vi = get_version_info!();
- assert_eq!(vi.to_string(), "rustc_tools_util 0.2.0");
- }
-
- #[test]
- fn test_debug_local() {
- let vi = get_version_info!();
- let s = format!("{:?}", vi);
- assert_eq!(
- s,
- "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 2, patch: 0 }"
- );
- }
-
-}
diff --git a/vendor/ryu/.cargo-checksum.json b/vendor/ryu/.cargo-checksum.json
index 979b4adaa..f0feb1916 100644
--- a/vendor/ryu/.cargo-checksum.json
+++ b/vendor/ryu/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.lock":"ce968acd12e9496e6626e7adfc454e9bc090f0d568ce3233964ef4082529fcb3","Cargo.toml":"434c11e0ad8ef085792f18f3535b4c0fed91d20f81241817252fe00e7b619534","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-BOOST":"c9bff75738922193e67fa726fa225535870d2aa1059f91452c411736284ad566","README.md":"91f2433b0f7134b35703c316a73e145f23d9a44c6e340eb971a72d0a4a87eea8","benches/bench.rs":"703521c8cb9c6959ee305776a9971d24754b6fff5c1737741be04f956a3692e8","examples/upstream_benchmark.rs":"f702d3598a8fac59134a8058ebf74ba90163b1f23ebbd6c5978a7bd8a888d357","src/buffer/mod.rs":"c5adf9aa037271916e78c61c9fd98e3230a0fed1fca15694d4d57166fa697125","src/common.rs":"cae347e97fc30c50a964f80425e8c3e69ece2b8ab81f9b81b9baa7fcec64a001","src/d2s.rs":"83f821f17fd8d2cf72bcc47cc8c603ab24f2377db6cd0f08638031716f8dc17c","src/d2s_full_table.rs":"9b0186acbc6d65dc55c17e16125be707a2bfb920d22b35d33234b4cc38566a36","src/d2s_intrinsics.rs":"658d00a64ce2aca7f0780a1acc5939167e4a66d836b51c46de1047820992fec1","src/d2s_small_table.rs":"7b25cfbf0793d0662d83f5d92a9f880295652db9979b5acf702b313359996508","src/digit_table.rs":"02351ca54cb8cb3679f635115dd094f32fd91750e9f66103c1ee9ec3db507072","src/f2s.rs":"55320c2301680d8be3a908620cccd9d103b0cd3ad7a7d3378589e274ffc2587b","src/f2s_intrinsics.rs":"97bab98093838e30c60f5135f54f5ccb039ff7d9f35553ac8e74437743ca47e2","src/lib.rs":"2ec3fb787f11a492e5d82c90ada3c2ea89c1880ffd281f4e02f769a30cf6e140","src/parse.rs":"7f8aa7e007caf5dcb03abdc4238157724bb742d0823a3b8a01646fa1f1129154","src/pretty/exponent.rs":"6c9aa1c707c567ae338647056e37557a94e5120781ee9f6f64e9c7071ffb50d0","src/pretty/mantissa.rs":"a3eb97fd8928bfabef4523501f204fc7254e948318d727eff8327b9b06e76242","src/pretty/mod.rs":"169c57b14075295b07fa408963c300cefa94fd0b17e098d524ef46535bd84019","src/s2d.rs":"2f572603eedaa9efbe864105999a1ceac8aa4ff4e1d2fbd96127692460194d16","src/s2f.rs":"411b1e5acdeb3d7a29f4fddfdf9ce77e6395475d1c053a05e31482d49e6bf1ee","tests/common_test.rs":"275184cf366f80c11e5f33c2d53065a073e20d81bf71ca70478c89e47fb8da36","tests/d2s_table_test.rs":"54b3a7d40aa9bec03e9dc555d15fb4512ee16a16398b3098a97819fab50c81f3","tests/d2s_test.rs":"39014777edd6e3231095186174c4ef341fd9c12ecc5510765761713b6cac3bb4","tests/exhaustive.rs":"f475ed9008a2cd86ce95abb577a4b01e9fed23fc16f7e217ccffb3b834005fa0","tests/f2s_test.rs":"10940f005e73a42bb106ff498e7a6cc4665d04d82829fef8dc7d0eb36f574e6f","tests/macros/mod.rs":"8e90a674b3960f9516cb38f4eea0e0981ff902c3b33572ebdb6c5528d3ffa72c","tests/s2d_test.rs":"75c3a1044881718db65e05f25c9f6e1d005392dddb2e8dafb799668bb6a9a5c3","tests/s2f_test.rs":"1ec06646cb65229bfe866ec913901a0d8d736668f30b812fc4b00136a43f5142"},"package":"f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"} \ No newline at end of file
+{"files":{"Cargo.lock":"2717f9b8d4230094a8c92ce37bb7bf56f5f869da3904b5b8f177b0c44f32389f","Cargo.toml":"a022feb14dc0f3979da30277ecce957cfefe78e6638d27882bf4cd1f8106e15f","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-BOOST":"c9bff75738922193e67fa726fa225535870d2aa1059f91452c411736284ad566","README.md":"6f91d4158af93dccaf61aab14ba9db78cce0413a70c8d7e63bf2823c0262be28","benches/bench.rs":"703521c8cb9c6959ee305776a9971d24754b6fff5c1737741be04f956a3692e8","examples/upstream_benchmark.rs":"f702d3598a8fac59134a8058ebf74ba90163b1f23ebbd6c5978a7bd8a888d357","src/buffer/mod.rs":"c5adf9aa037271916e78c61c9fd98e3230a0fed1fca15694d4d57166fa697125","src/common.rs":"cae347e97fc30c50a964f80425e8c3e69ece2b8ab81f9b81b9baa7fcec64a001","src/d2s.rs":"83f821f17fd8d2cf72bcc47cc8c603ab24f2377db6cd0f08638031716f8dc17c","src/d2s_full_table.rs":"9b0186acbc6d65dc55c17e16125be707a2bfb920d22b35d33234b4cc38566a36","src/d2s_intrinsics.rs":"658d00a64ce2aca7f0780a1acc5939167e4a66d836b51c46de1047820992fec1","src/d2s_small_table.rs":"7b25cfbf0793d0662d83f5d92a9f880295652db9979b5acf702b313359996508","src/digit_table.rs":"02351ca54cb8cb3679f635115dd094f32fd91750e9f66103c1ee9ec3db507072","src/f2s.rs":"55320c2301680d8be3a908620cccd9d103b0cd3ad7a7d3378589e274ffc2587b","src/f2s_intrinsics.rs":"97bab98093838e30c60f5135f54f5ccb039ff7d9f35553ac8e74437743ca47e2","src/lib.rs":"b4d5d3d390511b01f81df6321aad564d457cf390e6e2276ad3974564a54527ec","src/parse.rs":"7f8aa7e007caf5dcb03abdc4238157724bb742d0823a3b8a01646fa1f1129154","src/pretty/exponent.rs":"6c9aa1c707c567ae338647056e37557a94e5120781ee9f6f64e9c7071ffb50d0","src/pretty/mantissa.rs":"a3eb97fd8928bfabef4523501f204fc7254e948318d727eff8327b9b06e76242","src/pretty/mod.rs":"169c57b14075295b07fa408963c300cefa94fd0b17e098d524ef46535bd84019","src/s2d.rs":"2f572603eedaa9efbe864105999a1ceac8aa4ff4e1d2fbd96127692460194d16","src/s2f.rs":"411b1e5acdeb3d7a29f4fddfdf9ce77e6395475d1c053a05e31482d49e6bf1ee","tests/common_test.rs":"275184cf366f80c11e5f33c2d53065a073e20d81bf71ca70478c89e47fb8da36","tests/d2s_table_test.rs":"54b3a7d40aa9bec03e9dc555d15fb4512ee16a16398b3098a97819fab50c81f3","tests/d2s_test.rs":"39014777edd6e3231095186174c4ef341fd9c12ecc5510765761713b6cac3bb4","tests/exhaustive.rs":"f475ed9008a2cd86ce95abb577a4b01e9fed23fc16f7e217ccffb3b834005fa0","tests/f2s_test.rs":"10940f005e73a42bb106ff498e7a6cc4665d04d82829fef8dc7d0eb36f574e6f","tests/macros/mod.rs":"8e90a674b3960f9516cb38f4eea0e0981ff902c3b33572ebdb6c5528d3ffa72c","tests/s2d_test.rs":"75c3a1044881718db65e05f25c9f6e1d005392dddb2e8dafb799668bb6a9a5c3","tests/s2f_test.rs":"1ec06646cb65229bfe866ec913901a0d8d736668f30b812fc4b00136a43f5142"},"package":"4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"} \ No newline at end of file
diff --git a/vendor/ryu/Cargo.lock b/vendor/ryu/Cargo.lock
index 9c2b8d67a..0b0ca716a 100644
--- a/vendor/ryu/Cargo.lock
+++ b/vendor/ryu/Cargo.lock
@@ -10,9 +10,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
-version = "0.2.3"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
@@ -30,9 +30,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.112"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "no-panic"
@@ -57,38 +57,37 @@ dependencies = [
[[package]]
name = "ppv-lite86"
-version = "0.2.15"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro2"
-version = "1.0.34"
+version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1"
+checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
dependencies = [
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.10"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
+checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
-version = "0.8.4"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
- "rand_hc",
]
[[package]]
@@ -111,15 +110,6 @@ dependencies = [
]
[[package]]
-name = "rand_hc"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
name = "rand_xorshift"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -130,7 +120,7 @@ dependencies = [
[[package]]
name = "ryu"
-version = "1.0.10"
+version = "1.0.11"
dependencies = [
"no-panic",
"num_cpus",
@@ -140,23 +130,23 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.83"
+version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959"
+checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
-name = "unicode-xid"
-version = "0.2.2"
+name = "unicode-ident"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
+version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
diff --git a/vendor/ryu/Cargo.toml b/vendor/ryu/Cargo.toml
index a191cafc9..77181c0f6 100644
--- a/vendor/ryu/Cargo.toml
+++ b/vendor/ryu/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "ryu"
-version = "1.0.10"
+version = "1.0.11"
authors = ["David Tolnay <dtolnay@gmail.com>"]
exclude = [
"performance.png",
@@ -22,7 +22,11 @@ exclude = [
description = "Fast floating point to string conversion"
documentation = "https://docs.rs/ryu"
readme = "README.md"
-categories = ["value-formatting"]
+keywords = ["float"]
+categories = [
+ "value-formatting",
+ "no-std",
+]
license = "Apache-2.0 OR BSL-1.0"
repository = "https://github.com/dtolnay/ryu"
diff --git a/vendor/ryu/README.md b/vendor/ryu/README.md
index b4149b067..1e2248978 100644
--- a/vendor/ryu/README.md
+++ b/vendor/ryu/README.md
@@ -2,7 +2,7 @@
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/ryu-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/ryu)
[<img alt="crates.io" src="https://img.shields.io/crates/v/ryu.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/ryu)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-ryu-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/ryu)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-ryu-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/ryu)
[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/ryu/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/ryu/actions?query=branch%3Amaster)
Pure Rust implementation of Ryū, an algorithm to quickly convert floating point
diff --git a/vendor/ryu/src/lib.rs b/vendor/ryu/src/lib.rs
index 814169abe..f69638ef1 100644
--- a/vendor/ryu/src/lib.rs
+++ b/vendor/ryu/src/lib.rs
@@ -2,7 +2,7 @@
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
@@ -81,7 +81,7 @@
//! notation.
#![no_std]
-#![doc(html_root_url = "https://docs.rs/ryu/1.0.10")]
+#![doc(html_root_url = "https://docs.rs/ryu/1.0.11")]
#![allow(
clippy::cast_lossless,
clippy::cast_possible_truncation,
diff --git a/vendor/semver/.cargo-checksum.json b/vendor/semver/.cargo-checksum.json
index 26d255955..f9b5c853b 100644
--- a/vendor/semver/.cargo-checksum.json
+++ b/vendor/semver/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"05fd72553f111426202ab84ba32f5675d7d9ad6584cee93cacef60aafe142ac5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"83e92a83348171f60d768651091803e69e4cb7ea3190cdfc45918d4637f38e1e","benches/parse.rs":"6531f66f80ce2fc83878f9bf84f94c42e96f1e709466f2b88be8d95a3cec1511","build.rs":"47b42941210d44567c8561107420d7825aa1d01332c2d2f8892d9e20646a1c77","src/backport.rs":"f8866548840434c8974f135528693f25aacc4ad03639c4e3aea3be351e13fdf8","src/display.rs":"9ba42f7a6579aa9c7dd72f2380036f5c9664592f3eacd09ea25cef291a3e64e5","src/error.rs":"3bb489f4a29f38d93370e64ae8d6e4e9b451a055cd7d392b6aeacab7eb3e1953","src/eval.rs":"b7e7ec976051b9f87ddf5cfdbaad64654d98d86ae0763f7d88b14eeaeac6013c","src/identifier.rs":"601231351ac58602b7d193cb0951b5146bd868b62aba938d5cbe52cf2b93414b","src/impls.rs":"79b5a2ac6ca3d4cb46adfb1494756079f53bef780dd81c3a8d3adf86f91395c8","src/lib.rs":"7a10ff49eb30aec519f1a709c6c2e7cd40b92c120f139f26393a226b3490d67c","src/parse.rs":"ffbb84081f0f66ec47b752a1e32f1bea5f206ca84f464b99d0497451305a92f8","src/serde.rs":"e2a9b9dc3cd2cccc250eaffad049de418ef791bf8c4a34111a48f068353e0a37","tests/node/mod.rs":"2710d9b8daace2038b66db0f8f4cc522dee938e7cbc42d7739c31995343c32f4","tests/test_autotrait.rs":"070500c32ceee14a8a0110c04a01f98278b24614a0aec8c382dcea3da0343f58","tests/test_identifier.rs":"6c3da46c73df210527b60f1069131b15e2c65eb7b5d11793940d00cf66812f4d","tests/test_version.rs":"09e37c3df162205acf3683d1c760a6001e34e1c709fd4a1a265d82450e340003","tests/test_version_req.rs":"b6eea0258cc3b6d567a9f6c42693a97316345083495236c47e85374fd45f7cf0","tests/util/mod.rs":"db61c2cd86af864d8be4f2a3d5f25c86d7712201cc6ab47b715facf5f7f275b7"},"package":"a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"} \ No newline at end of file
+{"files":{"Cargo.toml":"2841cf520fc7e71e16036c48021789cdf36182786556b2a97eb8371193e0c69c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"83e92a83348171f60d768651091803e69e4cb7ea3190cdfc45918d4637f38e1e","benches/parse.rs":"6531f66f80ce2fc83878f9bf84f94c42e96f1e709466f2b88be8d95a3cec1511","build.rs":"eedfc19afa205955347175916974cdad121b55cb940e40c61931e5e7629f0e65","src/backport.rs":"f8866548840434c8974f135528693f25aacc4ad03639c4e3aea3be351e13fdf8","src/display.rs":"9ba42f7a6579aa9c7dd72f2380036f5c9664592f3eacd09ea25cef291a3e64e5","src/error.rs":"3bb489f4a29f38d93370e64ae8d6e4e9b451a055cd7d392b6aeacab7eb3e1953","src/eval.rs":"b7e7ec976051b9f87ddf5cfdbaad64654d98d86ae0763f7d88b14eeaeac6013c","src/identifier.rs":"601231351ac58602b7d193cb0951b5146bd868b62aba938d5cbe52cf2b93414b","src/impls.rs":"79b5a2ac6ca3d4cb46adfb1494756079f53bef780dd81c3a8d3adf86f91395c8","src/lib.rs":"f59b217cd6d3e26389562710c540f0f0e1af7184ac5cbf75b2200f7ed7538f1d","src/parse.rs":"ffbb84081f0f66ec47b752a1e32f1bea5f206ca84f464b99d0497451305a92f8","src/serde.rs":"e2a9b9dc3cd2cccc250eaffad049de418ef791bf8c4a34111a48f068353e0a37","tests/node/mod.rs":"2710d9b8daace2038b66db0f8f4cc522dee938e7cbc42d7739c31995343c32f4","tests/test_autotrait.rs":"070500c32ceee14a8a0110c04a01f98278b24614a0aec8c382dcea3da0343f58","tests/test_identifier.rs":"6c3da46c73df210527b60f1069131b15e2c65eb7b5d11793940d00cf66812f4d","tests/test_version.rs":"09e37c3df162205acf3683d1c760a6001e34e1c709fd4a1a265d82450e340003","tests/test_version_req.rs":"b6eea0258cc3b6d567a9f6c42693a97316345083495236c47e85374fd45f7cf0","tests/util/mod.rs":"db61c2cd86af864d8be4f2a3d5f25c86d7712201cc6ab47b715facf5f7f275b7"},"package":"93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"} \ No newline at end of file
diff --git a/vendor/semver/Cargo.toml b/vendor/semver/Cargo.toml
index 56e1833d2..e8ad37c7a 100644
--- a/vendor/semver/Cargo.toml
+++ b/vendor/semver/Cargo.toml
@@ -13,11 +13,16 @@
edition = "2018"
rust-version = "1.31"
name = "semver"
-version = "1.0.12"
+version = "1.0.13"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Parser and evaluator for Cargo's flavor of Semantic Versioning"
documentation = "https://docs.rs/semver"
readme = "README.md"
+keywords = ["cargo"]
+categories = [
+ "data-structures",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/semver"
diff --git a/vendor/semver/build.rs b/vendor/semver/build.rs
index b45af7e23..2bf4418c1 100644
--- a/vendor/semver/build.rs
+++ b/vendor/semver/build.rs
@@ -35,7 +35,7 @@ fn main() {
if compiler < 45 {
// String::strip_prefix.
- // https://doc.rust-lang.org/std/primitive.str.html#method.repeat
+ // https://doc.rust-lang.org/std/primitive.str.html#method.strip_prefix
println!("cargo:rustc-cfg=no_str_strip_prefix");
}
diff --git a/vendor/semver/src/lib.rs b/vendor/semver/src/lib.rs
index 5185b752d..b3c3ea286 100644
--- a/vendor/semver/src/lib.rs
+++ b/vendor/semver/src/lib.rs
@@ -60,7 +60,7 @@
//!
//! [Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
-#![doc(html_root_url = "https://docs.rs/semver/1.0.12")]
+#![doc(html_root_url = "https://docs.rs/semver/1.0.13")]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![cfg_attr(all(not(feature = "std"), not(no_alloc_crate)), no_std)]
#![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))]
diff --git a/vendor/serde/.cargo-checksum.json b/vendor/serde/.cargo-checksum.json
index 16ef2df3d..1149006a8 100644
--- a/vendor/serde/.cargo-checksum.json
+++ b/vendor/serde/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"0ed592ec6c003bc496f6fde49b07815cf3b41626bf195c4715f387371e7ddde6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"89cfc904243b611a8a2fc1c8724d6f1c2b61c166ca81676b903ddf80b8ff1c10","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/de/format.rs":"4b466a6a7f0070e884d14457759671c6ad7394fe9603708b7151ef6159258146","src/de/ignored_any.rs":"c69d6071191c2075372218442e9e73991335c6b4be18736a7a789f04bb305525","src/de/impls.rs":"b2fea640830a690d09b453fe126034f1f3f77e553b604a7a9ac83b043315248f","src/de/mod.rs":"3f241daf155f4ee93532cd94ee21966bd343850e091ee93fdafae90a60669ec7","src/de/seed.rs":"e8cf0233afe0af5b8fb9e4c94f301c92729c5ba417280af9e2201b732e374a72","src/de/utf8.rs":"f17524ee0af98ec3abcfd7d0b812fbd1033263bd8e2ce2f57c1e1999ce153558","src/de/value.rs":"a511298691a1505955eace480afd19bfa2d5abeb06cba3b7bc92af3d0c99968c","src/integer128.rs":"ca49591abde2d8c4f582174533fee28f0fa9139e5d71bf22b25a6b175f8abccc","src/lib.rs":"0ff39eb187609efe98b5fd1b9981daa097f74e748047cd8410698edb9337b707","src/macros.rs":"3d695a51f0a07f9f719dcb5620012c21a1b084c06a6283349cabf574ceba8123","src/private/de.rs":"ae9fd944944f9c2fb2eb07a622439c7ebdeab5e9d218cdaec9197cb5caa0941c","src/private/doc.rs":"e9801a43c3088fccd5f1fac76416698f948e65b647024aa9da17d673e1e8c217","src/private/mod.rs":"37b204775e572396515477b393ce793b2579de48e5971e6f596ba3723c489fd6","src/private/ser.rs":"3a90dfb5c17e81bf1d959fed60a9477713498e9d0934463627c98709132f066e","src/private/size_hint.rs":"605521227e9ba3100fbb9d5ea7fd5853385097c35015ce6908bd5f1ea20d59ad","src/ser/fmt.rs":"7827ed07fd8897e6324f75625ba0c926a4c4e7ec2914cd067391ce54d942ac7b","src/ser/impls.rs":"8b303e6231ec6d0c0ab8402d348d75229ce91d5e50a065f8209eb7d8a35c4a17","src/ser/impossible.rs":"db17913522c1c27389c5a085113911353b9813c1b116518681362e7c8b692c3a","src/ser/mod.rs":"19a7b66bc2e873213349011e7ae495b28d0bf1438c22ff727c46ee3dcc6e3152","src/std_error.rs":"3aac687856c035517fae44ed2906dd4a1e3184bae4bf613adcdeb73f74126c57"},"package":"fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"} \ No newline at end of file
+{"files":{"Cargo.toml":"a55cd52d7858718ed68b8c1aaac689aa8fb801d9194b904e3df31850c95b71f0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"89cfc904243b611a8a2fc1c8724d6f1c2b61c166ca81676b903ddf80b8ff1c10","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/de/format.rs":"4b466a6a7f0070e884d14457759671c6ad7394fe9603708b7151ef6159258146","src/de/ignored_any.rs":"c69d6071191c2075372218442e9e73991335c6b4be18736a7a789f04bb305525","src/de/impls.rs":"b2fea640830a690d09b453fe126034f1f3f77e553b604a7a9ac83b043315248f","src/de/mod.rs":"1ac7de9cfc47d0a8ac104c1809fd81d7febfcd01d74d6abcbf0bf31ec200f625","src/de/seed.rs":"e8cf0233afe0af5b8fb9e4c94f301c92729c5ba417280af9e2201b732e374a72","src/de/utf8.rs":"f17524ee0af98ec3abcfd7d0b812fbd1033263bd8e2ce2f57c1e1999ce153558","src/de/value.rs":"a511298691a1505955eace480afd19bfa2d5abeb06cba3b7bc92af3d0c99968c","src/integer128.rs":"ca49591abde2d8c4f582174533fee28f0fa9139e5d71bf22b25a6b175f8abccc","src/lib.rs":"ef1afaa6c1a4989102b46763c24e13d39573c8619a585ae6e9dc7c5a49efb7d9","src/macros.rs":"3d695a51f0a07f9f719dcb5620012c21a1b084c06a6283349cabf574ceba8123","src/private/de.rs":"ae9fd944944f9c2fb2eb07a622439c7ebdeab5e9d218cdaec9197cb5caa0941c","src/private/doc.rs":"e9801a43c3088fccd5f1fac76416698f948e65b647024aa9da17d673e1e8c217","src/private/mod.rs":"37b204775e572396515477b393ce793b2579de48e5971e6f596ba3723c489fd6","src/private/ser.rs":"3a90dfb5c17e81bf1d959fed60a9477713498e9d0934463627c98709132f066e","src/private/size_hint.rs":"605521227e9ba3100fbb9d5ea7fd5853385097c35015ce6908bd5f1ea20d59ad","src/ser/fmt.rs":"7827ed07fd8897e6324f75625ba0c926a4c4e7ec2914cd067391ce54d942ac7b","src/ser/impls.rs":"8b303e6231ec6d0c0ab8402d348d75229ce91d5e50a065f8209eb7d8a35c4a17","src/ser/impossible.rs":"db17913522c1c27389c5a085113911353b9813c1b116518681362e7c8b692c3a","src/ser/mod.rs":"e5008f26bd6100f52c7223184802e63f4d046651c9db56f68602752cea20745c","src/std_error.rs":"3aac687856c035517fae44ed2906dd4a1e3184bae4bf613adcdeb73f74126c57"},"package":"53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"} \ No newline at end of file
diff --git a/vendor/serde/Cargo.toml b/vendor/serde/Cargo.toml
index 9893bb79d..7424736c0 100644
--- a/vendor/serde/Cargo.toml
+++ b/vendor/serde/Cargo.toml
@@ -12,7 +12,7 @@
[package]
rust-version = "1.13"
name = "serde"
-version = "1.0.140"
+version = "1.0.143"
authors = [
"Erick Tryzelaar <erick.tryzelaar@gmail.com>",
"David Tolnay <dtolnay@gmail.com>",
@@ -35,9 +35,13 @@ keywords = [
"serialization",
"no_std",
]
-categories = ["encoding"]
+categories = [
+ "encoding",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/serde"
+resolver = "1"
[package.metadata.playground]
features = [
@@ -49,7 +53,7 @@ features = [
targets = ["x86_64-unknown-linux-gnu"]
[dependencies.serde_derive]
-version = "=1.0.140"
+version = "=1.0.143"
optional = true
[dev-dependencies.serde_derive]
diff --git a/vendor/serde/src/de/mod.rs b/vendor/serde/src/de/mod.rs
index 6100815f7..e8a47cfc1 100644
--- a/vendor/serde/src/de/mod.rs
+++ b/vendor/serde/src/de/mod.rs
@@ -30,7 +30,7 @@
//! # The Deserializer trait
//!
//! [`Deserializer`] implementations are provided by third-party crates, for
-//! example [`serde_json`], [`serde_yaml`] and [`bincode`].
+//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data formats].
@@ -104,7 +104,7 @@
//! [`Deserialize`]: ../trait.Deserialize.html
//! [`Deserializer`]: ../trait.Deserializer.html
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
-//! [`bincode`]: https://github.com/bincode-org/bincode
+//! [`postcard`]: https://github.com/jamesmunns/postcard
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
@@ -874,7 +874,7 @@ where
/// `Deserializer::deserialize_any`.
///
/// 2. The various `deserialize_*` methods. Non-self-describing formats like
-/// Bincode need to be told what is in the input in order to deserialize it.
+/// Postcard need to be told what is in the input in order to deserialize it.
/// The `deserialize_*` methods are hints to the deserializer for how to
/// interpret the next piece of input. Non-self-describing formats are not
/// able to deserialize something like `serde_json::Value` which relies on
@@ -884,7 +884,7 @@ where
/// `Deserializer::deserialize_any` unless you need to be told by the
/// Deserializer what type is in the input. Know that relying on
/// `Deserializer::deserialize_any` means your data type will be able to
-/// deserialize from self-describing formats only, ruling out Bincode and many
+/// deserialize from self-describing formats only, ruling out Postcard and many
/// others.
///
/// [Serde data model]: https://serde.rs/data-model.html
@@ -915,7 +915,7 @@ pub trait Deserializer<'de>: Sized {
/// `Deserializer::deserialize_any` unless you need to be told by the
/// Deserializer what type is in the input. Know that relying on
/// `Deserializer::deserialize_any` means your data type will be able to
- /// deserialize from self-describing formats only, ruling out Bincode and
+ /// deserialize from self-describing formats only, ruling out Postcard and
/// many others.
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
@@ -1156,7 +1156,7 @@ pub trait Deserializer<'de>: Sized {
/// Some types have a human-readable form that may be somewhat expensive to
/// construct, as well as a binary form that is compact and efficient.
/// Generally text-based formats like JSON and YAML will prefer to use the
- /// human-readable one and binary formats like Bincode will prefer the
+ /// human-readable one and binary formats like Postcard will prefer the
/// compact one.
///
/// ```edition2018
@@ -1560,7 +1560,7 @@ pub trait Visitor<'de>: Sized {
/// `Deserializer`.
///
/// This enables zero-copy deserialization of bytes in some formats. For
- /// example Bincode data containing bytes can be deserialized with zero
+ /// example Postcard data containing bytes can be deserialized with zero
/// copying into a `&'a [u8]` as long as the input data outlives `'a`.
///
/// The default implementation forwards to `visit_bytes`.
diff --git a/vendor/serde/src/lib.rs b/vendor/serde/src/lib.rs
index f1a17513c..f2b28d985 100644
--- a/vendor/serde/src/lib.rs
+++ b/vendor/serde/src/lib.rs
@@ -31,8 +31,7 @@
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
-//! - [Bincode], a compact binary format
-//! used for IPC within the Servo rendering engine.
+//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//! size without the need for version negotiation.
//! - [YAML], a self-proclaimed human-friendly configuration language that ain't
@@ -45,7 +44,6 @@
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//! definition.
//! - [JSON5], a superset of JSON including some productions from ES5.
-//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [URL] query strings, in the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//! *(deserialization only)*
@@ -59,7 +57,7 @@
//! and from DynamoDB.
//!
//! [JSON]: https://github.com/serde-rs/json
-//! [Bincode]: https://github.com/bincode-org/bincode
+//! [Postcard]: https://github.com/jamesmunns/postcard
//! [CBOR]: https://github.com/enarx/ciborium
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
@@ -69,7 +67,6 @@
//! [BSON]: https://github.com/mongodb/bson-rust
//! [Avro]: https://github.com/flavray/avro-rs
//! [JSON5]: https://github.com/callum-oakley/json5-rs
-//! [Postcard]: https://github.com/jamesmunns/postcard
//! [URL]: https://docs.rs/serde_qs
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
@@ -84,7 +81,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/serde/1.0.140")]
+#![doc(html_root_url = "https://docs.rs/serde/1.0.143")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
diff --git a/vendor/serde/src/ser/mod.rs b/vendor/serde/src/ser/mod.rs
index eb226ae96..9a21363d6 100644
--- a/vendor/serde/src/ser/mod.rs
+++ b/vendor/serde/src/ser/mod.rs
@@ -30,7 +30,7 @@
//! # The Serializer trait
//!
//! [`Serializer`] implementations are provided by third-party crates, for
-//! example [`serde_json`], [`serde_yaml`] and [`bincode`].
+//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data formats].
@@ -99,7 +99,7 @@
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
//! [`Serialize`]: ../trait.Serialize.html
//! [`Serializer`]: ../trait.Serializer.html
-//! [`bincode`]: https://github.com/bincode-org/bincode
+//! [`postcard`]: https://github.com/jamesmunns/postcard
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
@@ -314,7 +314,7 @@ pub trait Serialize {
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
/// Many Serde serializers produce text or binary data as output, for example
-/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
+/// JSON or Postcard. This is not a requirement of the `Serializer` trait, and
/// there are serializers that do not produce text or binary output. One example
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
/// serializer) that produces a `serde_json::Value` data structure in memory as
@@ -1423,7 +1423,7 @@ pub trait Serializer: Sized {
/// Some types have a human-readable form that may be somewhat expensive to
/// construct, as well as a binary form that is compact and efficient.
/// Generally text-based formats like JSON and YAML will prefer to use the
- /// human-readable one and binary formats like Bincode will prefer the
+ /// human-readable one and binary formats like Postcard will prefer the
/// compact one.
///
/// ```edition2018
diff --git a/vendor/serde_derive/.cargo-checksum.json b/vendor/serde_derive/.cargo-checksum.json
index 548b4dd75..0b2fde61e 100644
--- a/vendor/serde_derive/.cargo-checksum.json
+++ b/vendor/serde_derive/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"1b02082e05fb23a3d9291d91a1097beef2bddb443575716c4ab0e4d0159b5038","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"c01db20e19c31505b26b9e9a5aff1c5327a7501fc88917f372a9e718edcb50ab","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/bound.rs":"268b4995a5d0a129dcbd6e32ef11f587bd271df3f6c4f7230ed54bc99f5ce871","src/de.rs":"c5a41016ce15f8176a2d7a8445ba06d2eb8de0863c1fea0dab51c395dd7dccff","src/dummy.rs":"cb154465020973be8ab6079ab8574df46f38fbe028a5561cd6b1a8bfa1a35478","src/fragment.rs":"5548ba65a53d90a296f60c1328a7a7fb040db467f59c2f5210b2fb320457145d","src/internals/ast.rs":"b019865eef92c1ddbb9029423ac22179f132dc655a51c09fb2a42f4aaef172fd","src/internals/attr.rs":"778074380c4e353b77e03aff9edf15fda9e15a0e7ec25cdfc51d79a26636ddef","src/internals/case.rs":"9492f0c5142d7b7e8cd39c86d13a855e5ce4489425adb2b96aed89e1b7851ac0","src/internals/check.rs":"11ea94257d2a2ee2276938a6beb4ae11b74c39225c1e342e6df1e7d2b2924496","src/internals/ctxt.rs":"6fa544ae52914498a62a395818ebdc1b36ac2fb5903c60afb741a864ad559f1c","src/internals/mod.rs":"f32138ff19d57eb00f88ba11f6b015efab2102657804f71ebbf386a3698dad91","src/internals/receiver.rs":"cd125ba4a3dd6250ed4737555c58627bffd630a536cd7223068eed7c10a170d8","src/internals/respan.rs":"899753859c58ce5f532a3ec4584796a52f13ed5a0533191e48c953ba5c1b52ff","src/internals/symbol.rs":"3c9ce461773b7df3bb64d82aa5a0d93052c3bb0e60209db6c0b5c10ee9cfc9cf","src/lib.rs":"230ca4a6867faad035a07bed24dfcaee73dc0ab061e5c78094d97e01bb571efa","src/pretend.rs":"4aa53bf6c1350fbcfc8c4997f720cde61a8eb3aab73bb8c101b0f0a74901892b","src/ser.rs":"0d99c841f6c7bc9751ab225fe42d1f8b7fe56e36903efcb4ff10bf6e35c390ba","src/try.rs":"b171b0088c23ebf4bfa07ba457881b41ac5e547d55dd16f737ea988d34badf61"},"package":"6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"} \ No newline at end of file
+{"files":{"Cargo.toml":"9eb295576509c448841f03d77bb2ea40d587f67ad25aa1cebc3c3e99b2369123","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"c01db20e19c31505b26b9e9a5aff1c5327a7501fc88917f372a9e718edcb50ab","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/bound.rs":"268b4995a5d0a129dcbd6e32ef11f587bd271df3f6c4f7230ed54bc99f5ce871","src/de.rs":"c5a41016ce15f8176a2d7a8445ba06d2eb8de0863c1fea0dab51c395dd7dccff","src/dummy.rs":"cb154465020973be8ab6079ab8574df46f38fbe028a5561cd6b1a8bfa1a35478","src/fragment.rs":"5548ba65a53d90a296f60c1328a7a7fb040db467f59c2f5210b2fb320457145d","src/internals/ast.rs":"b019865eef92c1ddbb9029423ac22179f132dc655a51c09fb2a42f4aaef172fd","src/internals/attr.rs":"778074380c4e353b77e03aff9edf15fda9e15a0e7ec25cdfc51d79a26636ddef","src/internals/case.rs":"9492f0c5142d7b7e8cd39c86d13a855e5ce4489425adb2b96aed89e1b7851ac0","src/internals/check.rs":"11ea94257d2a2ee2276938a6beb4ae11b74c39225c1e342e6df1e7d2b2924496","src/internals/ctxt.rs":"6fa544ae52914498a62a395818ebdc1b36ac2fb5903c60afb741a864ad559f1c","src/internals/mod.rs":"f32138ff19d57eb00f88ba11f6b015efab2102657804f71ebbf386a3698dad91","src/internals/receiver.rs":"cd125ba4a3dd6250ed4737555c58627bffd630a536cd7223068eed7c10a170d8","src/internals/respan.rs":"899753859c58ce5f532a3ec4584796a52f13ed5a0533191e48c953ba5c1b52ff","src/internals/symbol.rs":"3c9ce461773b7df3bb64d82aa5a0d93052c3bb0e60209db6c0b5c10ee9cfc9cf","src/lib.rs":"0872481fb836d38af7f9819922a0269b3dbe27ce81a16443b905d44b3a03e349","src/pretend.rs":"4aa53bf6c1350fbcfc8c4997f720cde61a8eb3aab73bb8c101b0f0a74901892b","src/ser.rs":"0d99c841f6c7bc9751ab225fe42d1f8b7fe56e36903efcb4ff10bf6e35c390ba","src/try.rs":"b171b0088c23ebf4bfa07ba457881b41ac5e547d55dd16f737ea988d34badf61"},"package":"d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"} \ No newline at end of file
diff --git a/vendor/serde_derive/Cargo.toml b/vendor/serde_derive/Cargo.toml
index 08789fc4b..be824e985 100644
--- a/vendor/serde_derive/Cargo.toml
+++ b/vendor/serde_derive/Cargo.toml
@@ -12,7 +12,7 @@
[package]
rust-version = "1.31"
name = "serde_derive"
-version = "1.0.140"
+version = "1.0.143"
authors = [
"Erick Tryzelaar <erick.tryzelaar@gmail.com>",
"David Tolnay <dtolnay@gmail.com>",
@@ -33,9 +33,12 @@ keywords = [
"serde",
"serialization",
"no_std",
+ "derive",
]
+categories = ["no-std"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/serde"
+resolver = "1"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
diff --git a/vendor/serde_derive/src/lib.rs b/vendor/serde_derive/src/lib.rs
index d82e92560..edf7c4157 100644
--- a/vendor/serde_derive/src/lib.rs
+++ b/vendor/serde_derive/src/lib.rs
@@ -13,7 +13,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.140")]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.143")]
#![allow(unknown_lints, bare_trait_objects)]
// Ignored clippy lints
#![allow(
diff --git a/vendor/serde_json/.cargo-checksum.json b/vendor/serde_json/.cargo-checksum.json
index 5415825f1..8174fa507 100644
--- a/vendor/serde_json/.cargo-checksum.json
+++ b/vendor/serde_json/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CONTRIBUTING.md":"f5270cafba66223a7b51ffc0d286075a17bb7cd88762fc80d333d3102629f4d8","Cargo.toml":"c23c4deff8ae410875679db5224cff1a9e187527a1b061375e0176b3cbbdca80","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7c6217e41b058880a37e01cf8caf205daa397d33cc2199f9fa1634048bc088c5","build.rs":"20e23e5bfe6fc8155fef0e0da036ebc1f81b34078fe86f929c8247b6f4317b99","src/de.rs":"0048bb57f39c7014a491c044d527598270fe417f1676ec7ba4529fea337746bc","src/error.rs":"abb92a9bf62cb7f47141a733a9fd66ec8c369615d7e6f633d3536fd2a5ac74a2","src/features_check/error.rs":"d7359f864afbfe105a38abea9f563dc423036ebc4c956a5695a4beef144dc7ec","src/features_check/mod.rs":"2209f8d5c46b50c8a3b8dc22338dcaf0135d192e8b05d2f456cbe6a73104e958","src/io/core.rs":"9a4146802391fd202a36bebbf3b14b715ae09d8828cbe8e06a01214c470ebf5c","src/io/mod.rs":"fd1ed5080495cab21117f6f7d3c2c9e3687cad0c69a0cd087b08a145a9e672da","src/iter.rs":"f832c469cd7999d26ba9b76baa69b257a212a7edb3dfdf9b1d1bb35e8da85fa9","src/lexical/algorithm.rs":"4fbeb1994049348d1fc388dd1a29e481f8abb8fe1e28bfebf50f3bbce5fa5fbe","src/lexical/bhcomp.rs":"b7c68d74c0055eb67ec2c1bcf27bbc28bef8f1bbc43db8eb94ba69892230add6","src/lexical/bignum.rs":"4230cde10dc8eae456a713cf90ec4e48dff4b1d0c542621ce7f00f39ade2645e","src/lexical/cached.rs":"0e127398691f8042c19cde209e7f4b0161f0f3150342430145929f711e6fdac8","src/lexical/cached_float80.rs":"0f8f74a22cb7d871322a9893bffd0255ca10bf9dffd13afb2462dd3d7f51805f","src/lexical/digit.rs":"a265b9072194a62a67dfc4df3c86d4213097cf3f82280d025e0012a5a262fd9d","src/lexical/errors.rs":"6bc993febceb7dd96ac1c8c5c53b5f5a30297016c0f813ed8ff8d7938d01534d","src/lexical/exponent.rs":"387e945b97dc7ba48a7091c50d228a0dde3a1c4145703d4ab9c31191a91693b0","src/lexical/float.rs":"fe356213c92a049f4bef2f58bc0e3a26866ca06b8c1d74d0f961c5b883852cad","src/lexical/large_powers.rs":"34537f5c701afce1ec2a1fd3c14950381b2e27c9ad74f002c91f3708e8da9ca5","src/lexical/large_powers32.rs":"d533037c6141e6671102aee490c9cdeaba81e667ddca781b2b99db2c455e4a1a","src/lexical/large_powers64.rs":"745dd7c0cbe499eec027ef586248881011d9df20c7efab7929c1807b59886ba1","src/lexical/math.rs":"27e22b724cdf990cdacd0ccfc3749e6e2eb7529d43ebf6e95b1999560b9e199a","src/lexical/mod.rs":"4b4c5228779c0f135a4cb018700e3bcd495da48b74421a86f6b8b304acdef924","src/lexical/num.rs":"cf705c62612e31d704f43d94a633ea1243c6befad7ef5792e2e881a7fd21e809","src/lexical/parse.rs":"c2bfac4c70a19938ced61e991f4ec606764887cf12bac1a0978b5b5318a56aac","src/lexical/rounding.rs":"697207248ba17b7f4965aedb11d276261ada5b06d9c6265d8fd6246664ff6e3c","src/lexical/shift.rs":"bc1ed053dd63d45ac9c35302f18de9f00d94027f28af4ab749c9248439de832a","src/lexical/small_powers.rs":"4608dd218b8002435db7e1ec79d2d0fef5f47ae257b93353326d52ecc80cccda","src/lib.rs":"40e355c3d7abc85c7716a4c5cc487988e2385c1d6423c7a0f1238967488cbb78","src/macros.rs":"c9f23156faec8d5216d72b6a97eebd768efb3f75870a6e2beed824308587b998","src/map.rs":"54e5e8ba63cf12a24f2c0257b1ace12f1935ca6d862e7b657209ee6634bb771f","src/number.rs":"d154fa969227db17647c9f524d7c0795205cb53c36d17f9aec5582ea18988c6e","src/raw.rs":"ee2b4ed085d8488e72c5a19791aae9de569d6c1381e9e64ff71afa03d5cf902a","src/read.rs":"49b4b1d067b6485cbded28fb961666ab5df82c36661af722dbae756efb6b2891","src/ser.rs":"44a57aa347c2a3b234635622b675fa3b2c30b818212f5a5eef02027cf3406a84","src/value/de.rs":"64a86f6c14c2c04abc4b6f06b90bfcbda097b37b7f3e990576801f170d4af1e4","src/value/from.rs":"1968835c63dcd4058850162e3a8714b5a7e20eeec458fd4c200aa9ef0515f94c","src/value/index.rs":"8a99d8d50f5674181ced22f6e81dc529eaecb01e543e30346e51fe42cb4b8a5f","src/value/mod.rs":"99945c233836d4493dc019ac79b5fa8a57298060d14d20451a57d8f10d03fbd6","src/value/partial_eq.rs":"95de799d57f7f4310b64a9488c0a7286dee76dba4329cb69a96298a887e58586","src/value/ser.rs":"185539665cf3ab2fb5499a8e8e069ec75afbc2f07a2fbed0f8f9bcffd7ab729b","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/debug.rs":"1a6eb048f48708b3b6adc13ca7365cd67057a64e3e44eef300bc025c8d16f7cf","tests/lexical.rs":"383e06283e15e1db7c6b818da3c84a3afa0059f6e9fc994b069919d81346ab91","tests/lexical/algorithm.rs":"da378df9ee24bfa033968d5c94e91b58e52c39bf6c825dec51c3eb7250cc5874","tests/lexical/exponent.rs":"26ea92abc654a6a88a8281552bca2f76ea1fa4c17d66a1dd6defe14f7d89b666","tests/lexical/float.rs":"0440f2d85c993bcccd925096d7f4136bf624ffd66b3c7ee565d158390685eb11","tests/lexical/math.rs":"4874be2103be5fbe8b8015354414df271ffa00fd815546fc077f15fb4d7a5a37","tests/lexical/num.rs":"6e650c40de85ed72ac06b6bf1487ba161f3824e26d827df6cfdf2bbdb8d05a05","tests/lexical/parse.rs":"17c73e0a59d462716d974b8dd23a291eb6efdc3a933248874e5eab7e7209d67f","tests/lexical/rounding.rs":"6c56e39ba534616c1b2146e8efa6eb57aed322e683bf23183cd32a61fae6447e","tests/macros/mod.rs":"93aa1d54af20bc2c55b6ae8db73c1414cda2626eb9fa7bd57b9d613a3c6e6a19","tests/map.rs":"dcc5212242e4e93703c4335d54f5603b0211b33d6fb5ab410bb630cda6d46b09","tests/regression.rs":"86731134bfb9bb693d9a4fc62393027de80a8bf031109ea6c7ea475b1ebdde8d","tests/regression/issue520.rs":"d146be3472db902b48127d65fe83aa9f698143aca9074c83cd1a9d5dd28e3ec3","tests/regression/issue795.rs":"45fadebd9398c289fbf8ddf5aedda19571bf42d0da5217b9229c466d28108e94","tests/regression/issue845.rs":"8bd64588fc344e119d0e9e5e7604236e7c168c574b0692033f15278e216a6b9c","tests/stream.rs":"3d3e819bee483423cc200db5d84c51aefcf462a992e97b6f50b7c1e16f810f2b","tests/test.rs":"6fbda1ceee388ed78e2e388f2fdb28d2bc1bb0e53a1cbf89fc506f3cfa895bd1","tests/ui/missing_colon.rs":"d07e0c34d98eb43465f0a0310f2c0b5d5b0d26d243b352a1c6bbe6ad3b27eda9","tests/ui/missing_colon.stderr":"c06d58acf6890ac6513bd1622178e5e66ba0ea7a06a3841b8351f843e4d9f41b","tests/ui/missing_comma.rs":"b8a9662f99c3e6dd2b6417892c37640578ce91d3a8365bf10c1f686a3227aa87","tests/ui/missing_comma.stderr":"c6acd42b41ee78b197c77ff513fc77a9495423bb912b188ce6ea2963b65dd82c","tests/ui/missing_value.rs":"bca25d67127fb88e7c191c7b03af5a4ce8a9abb630f3d2e6a6c1e77e213dc9a4","tests/ui/missing_value.stderr":"83c85a3846f7832dc9a8b7996165255b3a1937a5f2d2fcbb859db545d1cdf2f7","tests/ui/not_found.rs":"d0a7adb309879ff65aee115b52cc33d36f4bad353cf97c4effc34a6128c2bee3","tests/ui/not_found.stderr":"359b751c0c21fab6d460daef4d5f73a265f7769c9b578f98ea3cb6cbf2387643","tests/ui/parse_expr.rs":"32e6d51f528db3d1ab0ed1e24765b865be393565c26f77413c5aa39d601ac563","tests/ui/parse_expr.stderr":"edfbaa14fa52f6fdb319c1e1aeac4f8870258930850e669d56aa94ef59ce4432","tests/ui/parse_key.rs":"18829b2af320d5cf8a0a5cd3aaf84c7e92cc874651c30e45a3acafb76c2d8b93","tests/ui/parse_key.stderr":"fcb44e060b804a4762b7291e128c41d7010ffa8ab820b8828fd13fbe6d405ca6","tests/ui/unexpected_after_array_element.rs":"a343fc3104431720bdfcf330bcc3cfcd98c8dec3e951133b495242478b0b7eb3","tests/ui/unexpected_after_array_element.stderr":"e0547b280bcc006155c481c66b49fbe2df577e9e741b7f75fcf6ab21e9e20969","tests/ui/unexpected_after_map_entry.rs":"6e3bd2def435ca610e346bbc75cdbaf61963eb2ef1885bb5f76781ba1fac37ef","tests/ui/unexpected_after_map_entry.stderr":"57b7fc4fbff089dd5e5d76f4eba56a3357273c3f4b7ce93eea60891762cc4275","tests/ui/unexpected_colon.rs":"a313cff3fed4be4c33f1eda5d0c5c98147fb835a56d36470d9f367352c1d61ef","tests/ui/unexpected_colon.stderr":"41585758c8764f485e5c98b0cf6f5ad796f5482839f8644189d980ff422316cd","tests/ui/unexpected_comma.rs":"55a8b684bde1ce905837cce719fd457d8898b61cebc27e5b420d05cb6be97256","tests/ui/unexpected_comma.stderr":"847bb88d0db4d8a89b2a339d57eeb2d75af7670f31fcfdc687373a8681cc1653"},"package":"82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"} \ No newline at end of file
+{"files":{"CONTRIBUTING.md":"f5270cafba66223a7b51ffc0d286075a17bb7cd88762fc80d333d3102629f4d8","Cargo.toml":"0b496503599dc9b1e962e41838c125db7d8811ad6f061ba6a865ed94ef43ffa0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7c6217e41b058880a37e01cf8caf205daa397d33cc2199f9fa1634048bc088c5","build.rs":"20e23e5bfe6fc8155fef0e0da036ebc1f81b34078fe86f929c8247b6f4317b99","src/de.rs":"0048bb57f39c7014a491c044d527598270fe417f1676ec7ba4529fea337746bc","src/error.rs":"abb92a9bf62cb7f47141a733a9fd66ec8c369615d7e6f633d3536fd2a5ac74a2","src/features_check/error.rs":"d7359f864afbfe105a38abea9f563dc423036ebc4c956a5695a4beef144dc7ec","src/features_check/mod.rs":"2209f8d5c46b50c8a3b8dc22338dcaf0135d192e8b05d2f456cbe6a73104e958","src/io/core.rs":"9a4146802391fd202a36bebbf3b14b715ae09d8828cbe8e06a01214c470ebf5c","src/io/mod.rs":"fd1ed5080495cab21117f6f7d3c2c9e3687cad0c69a0cd087b08a145a9e672da","src/iter.rs":"f832c469cd7999d26ba9b76baa69b257a212a7edb3dfdf9b1d1bb35e8da85fa9","src/lexical/algorithm.rs":"4fbeb1994049348d1fc388dd1a29e481f8abb8fe1e28bfebf50f3bbce5fa5fbe","src/lexical/bhcomp.rs":"b7c68d74c0055eb67ec2c1bcf27bbc28bef8f1bbc43db8eb94ba69892230add6","src/lexical/bignum.rs":"4230cde10dc8eae456a713cf90ec4e48dff4b1d0c542621ce7f00f39ade2645e","src/lexical/cached.rs":"0e127398691f8042c19cde209e7f4b0161f0f3150342430145929f711e6fdac8","src/lexical/cached_float80.rs":"0f8f74a22cb7d871322a9893bffd0255ca10bf9dffd13afb2462dd3d7f51805f","src/lexical/digit.rs":"a265b9072194a62a67dfc4df3c86d4213097cf3f82280d025e0012a5a262fd9d","src/lexical/errors.rs":"6bc993febceb7dd96ac1c8c5c53b5f5a30297016c0f813ed8ff8d7938d01534d","src/lexical/exponent.rs":"387e945b97dc7ba48a7091c50d228a0dde3a1c4145703d4ab9c31191a91693b0","src/lexical/float.rs":"fe356213c92a049f4bef2f58bc0e3a26866ca06b8c1d74d0f961c5b883852cad","src/lexical/large_powers.rs":"34537f5c701afce1ec2a1fd3c14950381b2e27c9ad74f002c91f3708e8da9ca5","src/lexical/large_powers32.rs":"d533037c6141e6671102aee490c9cdeaba81e667ddca781b2b99db2c455e4a1a","src/lexical/large_powers64.rs":"745dd7c0cbe499eec027ef586248881011d9df20c7efab7929c1807b59886ba1","src/lexical/math.rs":"27e22b724cdf990cdacd0ccfc3749e6e2eb7529d43ebf6e95b1999560b9e199a","src/lexical/mod.rs":"4b4c5228779c0f135a4cb018700e3bcd495da48b74421a86f6b8b304acdef924","src/lexical/num.rs":"cf705c62612e31d704f43d94a633ea1243c6befad7ef5792e2e881a7fd21e809","src/lexical/parse.rs":"c2bfac4c70a19938ced61e991f4ec606764887cf12bac1a0978b5b5318a56aac","src/lexical/rounding.rs":"697207248ba17b7f4965aedb11d276261ada5b06d9c6265d8fd6246664ff6e3c","src/lexical/shift.rs":"bc1ed053dd63d45ac9c35302f18de9f00d94027f28af4ab749c9248439de832a","src/lexical/small_powers.rs":"4608dd218b8002435db7e1ec79d2d0fef5f47ae257b93353326d52ecc80cccda","src/lib.rs":"25ae8f37112a5628b2919619d360dfea6d238e9089fe15cb1869fb70d01bf922","src/macros.rs":"c9f23156faec8d5216d72b6a97eebd768efb3f75870a6e2beed824308587b998","src/map.rs":"54e5e8ba63cf12a24f2c0257b1ace12f1935ca6d862e7b657209ee6634bb771f","src/number.rs":"e4e2ad248acbeed5a674f8823251387a2dbc9b3730bde831a88c8c10621e7a38","src/raw.rs":"ee2b4ed085d8488e72c5a19791aae9de569d6c1381e9e64ff71afa03d5cf902a","src/read.rs":"49b4b1d067b6485cbded28fb961666ab5df82c36661af722dbae756efb6b2891","src/ser.rs":"44a57aa347c2a3b234635622b675fa3b2c30b818212f5a5eef02027cf3406a84","src/value/de.rs":"64a86f6c14c2c04abc4b6f06b90bfcbda097b37b7f3e990576801f170d4af1e4","src/value/from.rs":"1968835c63dcd4058850162e3a8714b5a7e20eeec458fd4c200aa9ef0515f94c","src/value/index.rs":"8a99d8d50f5674181ced22f6e81dc529eaecb01e543e30346e51fe42cb4b8a5f","src/value/mod.rs":"47ff472a2426a135c7acdf59c4c83c7b7ce986269f10ec31c809a2b35152beda","src/value/partial_eq.rs":"95de799d57f7f4310b64a9488c0a7286dee76dba4329cb69a96298a887e58586","src/value/ser.rs":"185539665cf3ab2fb5499a8e8e069ec75afbc2f07a2fbed0f8f9bcffd7ab729b","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/debug.rs":"a8451217c1e127ad6e653ef11e0513525ee350e1e37dd575758a8ee9301b28fb","tests/lexical.rs":"383e06283e15e1db7c6b818da3c84a3afa0059f6e9fc994b069919d81346ab91","tests/lexical/algorithm.rs":"da378df9ee24bfa033968d5c94e91b58e52c39bf6c825dec51c3eb7250cc5874","tests/lexical/exponent.rs":"26ea92abc654a6a88a8281552bca2f76ea1fa4c17d66a1dd6defe14f7d89b666","tests/lexical/float.rs":"0440f2d85c993bcccd925096d7f4136bf624ffd66b3c7ee565d158390685eb11","tests/lexical/math.rs":"4874be2103be5fbe8b8015354414df271ffa00fd815546fc077f15fb4d7a5a37","tests/lexical/num.rs":"6e650c40de85ed72ac06b6bf1487ba161f3824e26d827df6cfdf2bbdb8d05a05","tests/lexical/parse.rs":"17c73e0a59d462716d974b8dd23a291eb6efdc3a933248874e5eab7e7209d67f","tests/lexical/rounding.rs":"6c56e39ba534616c1b2146e8efa6eb57aed322e683bf23183cd32a61fae6447e","tests/macros/mod.rs":"93aa1d54af20bc2c55b6ae8db73c1414cda2626eb9fa7bd57b9d613a3c6e6a19","tests/map.rs":"dcc5212242e4e93703c4335d54f5603b0211b33d6fb5ab410bb630cda6d46b09","tests/regression.rs":"86731134bfb9bb693d9a4fc62393027de80a8bf031109ea6c7ea475b1ebdde8d","tests/regression/issue520.rs":"d146be3472db902b48127d65fe83aa9f698143aca9074c83cd1a9d5dd28e3ec3","tests/regression/issue795.rs":"582e2e7c68113f05a4b1d2cb556a2df7cc77f2ce8164a32c5cc58ae68abb60ec","tests/regression/issue845.rs":"8bd64588fc344e119d0e9e5e7604236e7c168c574b0692033f15278e216a6b9c","tests/stream.rs":"c7d91014538ecd8f495b196d40e999ab2745f2e69fa2ff9e52521605dc6ce856","tests/test.rs":"6b0f60187c0a936dfe57686d334269863495a01446f75e1ed2e1d641861f232b","tests/ui/missing_colon.rs":"d07e0c34d98eb43465f0a0310f2c0b5d5b0d26d243b352a1c6bbe6ad3b27eda9","tests/ui/missing_colon.stderr":"8dd5c769f36ede610172f69140a3faf603cd4590cb4abc8eaa1b499fe3537ad9","tests/ui/missing_comma.rs":"b8a9662f99c3e6dd2b6417892c37640578ce91d3a8365bf10c1f686a3227aa87","tests/ui/missing_comma.stderr":"c6acd42b41ee78b197c77ff513fc77a9495423bb912b188ce6ea2963b65dd82c","tests/ui/missing_value.rs":"bca25d67127fb88e7c191c7b03af5a4ce8a9abb630f3d2e6a6c1e77e213dc9a4","tests/ui/missing_value.stderr":"15727519f300c64d6968cd99398227f7fbbf660825459a0768f2bf947eadf752","tests/ui/not_found.rs":"d0a7adb309879ff65aee115b52cc33d36f4bad353cf97c4effc34a6128c2bee3","tests/ui/not_found.stderr":"359b751c0c21fab6d460daef4d5f73a265f7769c9b578f98ea3cb6cbf2387643","tests/ui/parse_expr.rs":"32e6d51f528db3d1ab0ed1e24765b865be393565c26f77413c5aa39d601ac563","tests/ui/parse_expr.stderr":"edfbaa14fa52f6fdb319c1e1aeac4f8870258930850e669d56aa94ef59ce4432","tests/ui/parse_key.rs":"18829b2af320d5cf8a0a5cd3aaf84c7e92cc874651c30e45a3acafb76c2d8b93","tests/ui/parse_key.stderr":"fcb44e060b804a4762b7291e128c41d7010ffa8ab820b8828fd13fbe6d405ca6","tests/ui/unexpected_after_array_element.rs":"a343fc3104431720bdfcf330bcc3cfcd98c8dec3e951133b495242478b0b7eb3","tests/ui/unexpected_after_array_element.stderr":"e0547b280bcc006155c481c66b49fbe2df577e9e741b7f75fcf6ab21e9e20969","tests/ui/unexpected_after_map_entry.rs":"6e3bd2def435ca610e346bbc75cdbaf61963eb2ef1885bb5f76781ba1fac37ef","tests/ui/unexpected_after_map_entry.stderr":"57b7fc4fbff089dd5e5d76f4eba56a3357273c3f4b7ce93eea60891762cc4275","tests/ui/unexpected_colon.rs":"a313cff3fed4be4c33f1eda5d0c5c98147fb835a56d36470d9f367352c1d61ef","tests/ui/unexpected_colon.stderr":"41585758c8764f485e5c98b0cf6f5ad796f5482839f8644189d980ff422316cd","tests/ui/unexpected_comma.rs":"55a8b684bde1ce905837cce719fd457d8898b61cebc27e5b420d05cb6be97256","tests/ui/unexpected_comma.stderr":"847bb88d0db4d8a89b2a339d57eeb2d75af7670f31fcfdc687373a8681cc1653"},"package":"e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"} \ No newline at end of file
diff --git a/vendor/serde_json/Cargo.toml b/vendor/serde_json/Cargo.toml
index 0fb0d05d8..a79bb3b1c 100644
--- a/vendor/serde_json/Cargo.toml
+++ b/vendor/serde_json/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "serde_json"
-version = "1.0.82"
+version = "1.0.85"
authors = [
"Erick Tryzelaar <erick.tryzelaar@gmail.com>",
"David Tolnay <dtolnay@gmail.com>",
@@ -26,7 +26,11 @@ keywords = [
"serde",
"serialization",
]
-categories = ["encoding"]
+categories = [
+ "encoding",
+ "parser-implementations",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/json"
@@ -62,6 +66,9 @@ default-features = false
[dev-dependencies.automod]
version = "1.0"
+[dev-dependencies.indoc]
+version = "1.0"
+
[dev-dependencies.ref-cast]
version = "1.0"
diff --git a/vendor/serde_json/src/lib.rs b/vendor/serde_json/src/lib.rs
index 736ab8472..cf4b83d19 100644
--- a/vendor/serde_json/src/lib.rs
+++ b/vendor/serde_json/src/lib.rs
@@ -300,7 +300,7 @@
//! [macro]: https://docs.serde.rs/serde_json/macro.json.html
//! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
-#![doc(html_root_url = "https://docs.rs/serde_json/1.0.82")]
+#![doc(html_root_url = "https://docs.rs/serde_json/1.0.85")]
// Ignored clippy lints
#![allow(
clippy::collapsible_else_if,
@@ -308,6 +308,7 @@
clippy::deprecated_cfg_attr,
clippy::doc_markdown,
clippy::excessive_precision,
+ clippy::explicit_auto_deref,
clippy::float_cmp,
clippy::manual_range_contains,
clippy::match_like_matches_macro,
diff --git a/vendor/serde_json/src/number.rs b/vendor/serde_json/src/number.rs
index b965271fd..df8819259 100644
--- a/vendor/serde_json/src/number.rs
+++ b/vendor/serde_json/src/number.rs
@@ -292,9 +292,9 @@ impl Display for Number {
#[cfg(not(feature = "arbitrary_precision"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self.n {
- N::PosInt(u) => Display::fmt(&u, formatter),
- N::NegInt(i) => Display::fmt(&i, formatter),
- N::Float(f) => Display::fmt(&f, formatter),
+ N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
+ N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
+ N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
}
}
@@ -305,29 +305,8 @@ impl Display for Number {
}
impl Debug for Number {
- #[cfg(not(feature = "arbitrary_precision"))]
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- let mut debug = formatter.debug_tuple("Number");
- match self.n {
- N::PosInt(i) => {
- debug.field(&i);
- }
- N::NegInt(i) => {
- debug.field(&i);
- }
- N::Float(f) => {
- debug.field(&f);
- }
- }
- debug.finish()
- }
-
- #[cfg(feature = "arbitrary_precision")]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter
- .debug_tuple("Number")
- .field(&format_args!("{}", self.n))
- .finish()
+ write!(formatter, "Number({})", self)
}
}
@@ -752,13 +731,15 @@ impl_from_signed!(i8, i16, i32, i64, isize);
serde_if_integer128! {
impl From<i128> for Number {
fn from(i: i128) -> Self {
- Number { n: i.to_string() }
+ let n = itoa::Buffer::new().format(i).to_owned();
+ Number { n }
}
}
impl From<u128> for Number {
fn from(u: u128) -> Self {
- Number { n: u.to_string() }
+ let n = itoa::Buffer::new().format(u).to_owned();
+ Number { n }
}
}
}
diff --git a/vendor/serde_json/src/value/mod.rs b/vendor/serde_json/src/value/mod.rs
index 4793e93ec..c467df6cc 100644
--- a/vendor/serde_json/src/value/mod.rs
+++ b/vendor/serde_json/src/value/mod.rs
@@ -177,19 +177,17 @@ pub enum Value {
impl Debug for Value {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
- Value::Null => formatter.debug_tuple("Null").finish(),
- Value::Bool(v) => formatter.debug_tuple("Bool").field(v).finish(),
- Value::Number(v) => Debug::fmt(v, formatter),
- Value::String(v) => formatter.debug_tuple("String").field(v).finish(),
- Value::Array(v) => {
- formatter.write_str("Array(")?;
- Debug::fmt(v, formatter)?;
- formatter.write_str(")")
+ Value::Null => formatter.write_str("Null"),
+ Value::Bool(boolean) => write!(formatter, "Bool({})", boolean),
+ Value::Number(number) => Debug::fmt(number, formatter),
+ Value::String(string) => write!(formatter, "String({:?})", string),
+ Value::Array(vec) => {
+ formatter.write_str("Array ")?;
+ Debug::fmt(vec, formatter)
}
- Value::Object(v) => {
- formatter.write_str("Object(")?;
- Debug::fmt(v, formatter)?;
- formatter.write_str(")")
+ Value::Object(map) => {
+ formatter.write_str("Object ")?;
+ Debug::fmt(map, formatter)
}
}
}
diff --git a/vendor/serde_json/tests/debug.rs b/vendor/serde_json/tests/debug.rs
index d2d8448be..8ddcf5a38 100644
--- a/vendor/serde_json/tests/debug.rs
+++ b/vendor/serde_json/tests/debug.rs
@@ -1,3 +1,4 @@
+use indoc::indoc;
use serde_json::{json, Number, Value};
#[test]
@@ -26,6 +27,8 @@ fn value_number() {
assert_eq!(format!("{:?}", json!(1)), "Number(1)");
assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
+ assert_eq!(Number::from_f64(1.0).unwrap().to_string(), "1.0"); // not just "1"
+ assert_eq!(Number::from_f64(12e40).unwrap().to_string(), "1.2e41");
}
#[test]
@@ -35,12 +38,12 @@ fn value_string() {
#[test]
fn value_array() {
- assert_eq!(format!("{:?}", json!([])), "Array([])");
+ assert_eq!(format!("{:?}", json!([])), "Array []");
}
#[test]
fn value_object() {
- assert_eq!(format!("{:?}", json!({})), "Object({})");
+ assert_eq!(format!("{:?}", json!({})), "Object {}");
}
#[test]
@@ -50,19 +53,29 @@ fn error() {
assert_eq!(format!("{:?}", err), expected);
}
-const INDENTED_EXPECTED: &str = r#"Object({
- "array": Array([
- Number(
- 0,
- ),
- Number(
- 1,
- ),
- ]),
-})"#;
-
#[test]
fn indented() {
- let j = json!({ "array": [0, 1] });
- assert_eq!(format!("{:#?}", j), INDENTED_EXPECTED);
+ let j = json!({
+ "Array": [true],
+ "Bool": true,
+ "EmptyArray": [],
+ "EmptyObject": {},
+ "Null": null,
+ "Number": 1,
+ "String": "...",
+ });
+ let expected = indoc! {r#"
+ Object {
+ "Array": Array [
+ Bool(true),
+ ],
+ "Bool": Bool(true),
+ "EmptyArray": Array [],
+ "EmptyObject": Object {},
+ "Null": Null,
+ "Number": Number(1),
+ "String": String("..."),
+ }"#
+ };
+ assert_eq!(format!("{:#?}", j), expected);
}
diff --git a/vendor/serde_json/tests/regression/issue795.rs b/vendor/serde_json/tests/regression/issue795.rs
index 06b68724e..bb82852c5 100644
--- a/vendor/serde_json/tests/regression/issue795.rs
+++ b/vendor/serde_json/tests/regression/issue795.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::assertions_on_result_states)]
+
use serde::de::{
Deserialize, Deserializer, EnumAccess, IgnoredAny, MapAccess, VariantAccess, Visitor,
};
diff --git a/vendor/serde_json/tests/stream.rs b/vendor/serde_json/tests/stream.rs
index ca54e9a15..ec6b9e3d0 100644
--- a/vendor/serde_json/tests/stream.rs
+++ b/vendor/serde_json/tests/stream.rs
@@ -1,4 +1,5 @@
#![cfg(not(feature = "preserve_order"))]
+#![allow(clippy::assertions_on_result_states)]
use serde_json::{json, Deserializer, Value};
diff --git a/vendor/serde_json/tests/test.rs b/vendor/serde_json/tests/test.rs
index 13d30c490..0aeaff88d 100644
--- a/vendor/serde_json/tests/test.rs
+++ b/vendor/serde_json/tests/test.rs
@@ -1,5 +1,6 @@
#![cfg(not(feature = "preserve_order"))]
#![allow(
+ clippy::assertions_on_result_states,
clippy::cast_precision_loss,
clippy::derive_partial_eq_without_eq,
clippy::excessive_precision,
diff --git a/vendor/serde_json/tests/ui/missing_colon.stderr b/vendor/serde_json/tests/ui/missing_colon.stderr
index 9b83c1777..3cebc4fd3 100644
--- a/vendor/serde_json/tests/ui/missing_colon.stderr
+++ b/vendor/serde_json/tests/ui/missing_colon.stderr
@@ -4,4 +4,4 @@ error: unexpected end of macro invocation
4 | json!({ "a" });
| ^^^^^^^^^^^^^^ missing tokens in macro arguments
|
- = note: this error originates in the macro `json_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/serde_json/tests/ui/missing_value.stderr b/vendor/serde_json/tests/ui/missing_value.stderr
index d538d9613..a1edbc37b 100644
--- a/vendor/serde_json/tests/ui/missing_value.stderr
+++ b/vendor/serde_json/tests/ui/missing_value.stderr
@@ -4,4 +4,4 @@ error: unexpected end of macro invocation
4 | json!({ "a" : });
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
- = note: this error originates in the macro `json_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/serde_repr/.cargo-checksum.json b/vendor/serde_repr/.cargo-checksum.json
index 4012e22d8..fb30edebf 100644
--- a/vendor/serde_repr/.cargo-checksum.json
+++ b/vendor/serde_repr/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"99cae9ec2495b733e77b78630bc8cfc312afac866b84c71618d896a7c90e555d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"18848980d7a8fc120c0c03fbf02a79ea7cd9e6f446f4c76aad48782c76967634","src/lib.rs":"6991484c16826a6b5bf50924448d5b1a858e832f64770c95bd2ac24a757e632a","src/parse.rs":"687cf1436d12c0c26b1c6d06f80e56b4ec0d63a38d71e1f175b981c0fdc10c68","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"a5c4df255ded38d91a3abb4b6c59fde6710a17b0832c8a5bba2a04b455a14bfa","tests/ui/empty_enum.rs":"fe1166f2f92ee213d26a23e57572a99c65c163d446fd8d67e1520bab34f4b859","tests/ui/empty_enum.stderr":"2c8907fc146bb4dcdb926b72de4f823dae4c1c0d8de8a636c512539408f26cc7","tests/ui/missing_repr.rs":"b7ba9341111582cad52e761b82f14778c60352014c4265566e4d4d01ccdcb306","tests/ui/missing_repr.stderr":"dfcb65527963fb8962e1442e10d3c71e141f238b1732483e1739b528ae0eca43","tests/ui/multiple_others.rs":"569658516619719f21e5071873a37125d5390edb77558e4381401f03efda0c83","tests/ui/multiple_others.stderr":"a300f94d2a2049d6718866d17b5673201edc275164b9e8eba25a9ffcd71fd30f","tests/ui/non_unit_variant.rs":"0d8295ae08d882fc3ef4164857240038c5b0674ff0811da9b6ea7343e8bb955c","tests/ui/non_unit_variant.stderr":"18f2900e501b8c64b980445758ca1cb59594dc8d24a1a76abb08a48d8beb3f35","tests/ui/not_enum.rs":"ada7637821c924a6b99175363c820375991be60223f96ca553d304fde2721386","tests/ui/not_enum.stderr":"814525f9a1495225511a02ad4149c9371ea622230b8002564fe83cf52300c728"},"package":"a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed"} \ No newline at end of file
+{"files":{"Cargo.toml":"9c18626e7651c83a27fd830650fddfba5db26eecfb706efdf49a33b9dbd49376","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"390805207b02b9766faf9df282ab0a6ee03c64c97a5af07ad516d5c6e095a011","src/lib.rs":"7acb4fb05f93dd98a0f2c83de6da38ed68e882c7b7ea244aa607c1c5113f8509","src/parse.rs":"687cf1436d12c0c26b1c6d06f80e56b4ec0d63a38d71e1f175b981c0fdc10c68","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"a4ddb956ee9eafc0b50694075497a2712a347f1a682f9038e2dd654c6605af44","tests/ui/empty_enum.rs":"fe1166f2f92ee213d26a23e57572a99c65c163d446fd8d67e1520bab34f4b859","tests/ui/empty_enum.stderr":"2c8907fc146bb4dcdb926b72de4f823dae4c1c0d8de8a636c512539408f26cc7","tests/ui/missing_repr.rs":"b7ba9341111582cad52e761b82f14778c60352014c4265566e4d4d01ccdcb306","tests/ui/missing_repr.stderr":"dfcb65527963fb8962e1442e10d3c71e141f238b1732483e1739b528ae0eca43","tests/ui/multiple_others.rs":"569658516619719f21e5071873a37125d5390edb77558e4381401f03efda0c83","tests/ui/multiple_others.stderr":"a300f94d2a2049d6718866d17b5673201edc275164b9e8eba25a9ffcd71fd30f","tests/ui/non_unit_variant.rs":"0d8295ae08d882fc3ef4164857240038c5b0674ff0811da9b6ea7343e8bb955c","tests/ui/non_unit_variant.stderr":"18f2900e501b8c64b980445758ca1cb59594dc8d24a1a76abb08a48d8beb3f35","tests/ui/not_enum.rs":"ada7637821c924a6b99175363c820375991be60223f96ca553d304fde2721386","tests/ui/not_enum.stderr":"814525f9a1495225511a02ad4149c9371ea622230b8002564fe83cf52300c728"},"package":"1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"} \ No newline at end of file
diff --git a/vendor/serde_repr/Cargo.toml b/vendor/serde_repr/Cargo.toml
index 41cb6a15c..6cbdafeae 100644
--- a/vendor/serde_repr/Cargo.toml
+++ b/vendor/serde_repr/Cargo.toml
@@ -13,11 +13,20 @@
edition = "2018"
rust-version = "1.31"
name = "serde_repr"
-version = "0.1.8"
+version = "0.1.9"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Derive Serialize and Deserialize that delegates to the underlying repr of a C-like enum."
documentation = "https://docs.rs/serde_repr"
readme = "README.md"
+keywords = [
+ "serde",
+ "serialization",
+ "integer",
+]
+categories = [
+ "encoding",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/serde-repr"
diff --git a/vendor/serde_repr/README.md b/vendor/serde_repr/README.md
index c87b3cedc..8c8dee1ea 100644
--- a/vendor/serde_repr/README.md
+++ b/vendor/serde_repr/README.md
@@ -3,7 +3,7 @@ Serde repr derive
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/serde--repr-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/serde-repr)
[<img alt="crates.io" src="https://img.shields.io/crates/v/serde_repr.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/serde_repr)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-serde__repr-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/serde_repr)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-serde__repr-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/serde_repr)
[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/serde-repr/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/serde-repr/actions?query=branch%3Amaster)
This crate provides a derive macro to derive Serde's `Serialize` and
diff --git a/vendor/serde_repr/src/lib.rs b/vendor/serde_repr/src/lib.rs
index 72e2c2bdd..2ad67df06 100644
--- a/vendor/serde_repr/src/lib.rs
+++ b/vendor/serde_repr/src/lib.rs
@@ -2,7 +2,7 @@
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
diff --git a/vendor/serde_repr/tests/test.rs b/vendor/serde_repr/tests/test.rs
index 8c44827dd..d442448dd 100644
--- a/vendor/serde_repr/tests/test.rs
+++ b/vendor/serde_repr/tests/test.rs
@@ -1,4 +1,5 @@
#![allow(
+ clippy::derive_partial_eq_without_eq,
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
clippy::nonstandard_macro_braces,
clippy::wildcard_imports,
diff --git a/vendor/sha-1-0.8.2/.cargo-checksum.json b/vendor/sha-1-0.8.2/.cargo-checksum.json
deleted file mode 100644
index 4c2a775dd..000000000
--- a/vendor/sha-1-0.8.2/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.lock":"cb91ffff371524a65d00a6d075e7d94d01f253393661058750217edc1005b76e","Cargo.toml":"80517f782161bae604f15650e2ef9ddbfd4c25c68a61d023e183483412bce8dd","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"b4eb00df6e2a4d22518fcaa6a2b4646f249b3a3c9814509b22bd2091f1392ff1","benches/lib.rs":"a37a0e99c673a3049d4ffa229eb1b3e1a3006f611a76b881f12440fcb075c361","examples/sha1sum.rs":"3b52d8ba4cc4271d3111b5cb578095761eab7ded2fede3c498d11eaf68a120b8","src/aarch64.rs":"150de941565333e50edb5b156e9448ce613621fac0660f6ed114d061ab97be6a","src/consts.rs":"b4346e3e6d28ad3f0a24cc199ebc73784466202a2cab09dfc938c14a41d5b4b2","src/lib.rs":"31e1c136ed0e41bf83fc5b32e8a456b89b556e541c3fe3fd78c9284a78bf7930","src/utils.rs":"a38e6d9df1994357f292c846e9fce3026bc02374fae8cbca18b9884e8a4759c6","tests/data/one_million_a.bin":"e53c99dcb3ee1436b1c01e53799a07891009be5cdb244133e5eda0ec56d7233a","tests/data/sha1.blb":"b620d6ab76fd26fea6b7be1be720652926b6cea9901a294ff8ba855666ddf19a","tests/lib.rs":"adce369751e6faab77582c03436abcd7dae816843501e1c63cbfd72942b76100"},"package":"f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"} \ No newline at end of file
diff --git a/vendor/sha-1-0.8.2/Cargo.lock b/vendor/sha-1-0.8.2/Cargo.lock
deleted file mode 100644
index cef4543a0..000000000
--- a/vendor/sha-1-0.8.2/Cargo.lock
+++ /dev/null
@@ -1,148 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "blobby"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
-dependencies = [
- "block-padding",
- "byte-tools",
- "byteorder",
- "generic-array",
-]
-
-[[package]]
-name = "block-padding"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
-dependencies = [
- "byte-tools",
-]
-
-[[package]]
-name = "byte-tools"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
-
-[[package]]
-name = "byteorder"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
-
-[[package]]
-name = "cc"
-version = "1.0.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
-
-[[package]]
-name = "digest"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-dependencies = [
- "blobby",
- "generic-array",
-]
-
-[[package]]
-name = "fake-simd"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
-
-[[package]]
-name = "generic-array"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
-dependencies = [
- "typenum",
-]
-
-[[package]]
-name = "hex-literal"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddc2928beef125e519d69ae1baa8c37ea2e0d3848545217f6db0179c5eb1d639"
-dependencies = [
- "hex-literal-impl",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "hex-literal-impl"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520870c3213943eb8d7803e80180d12a6c7ceb4ae74602544529d1643dc4ddda"
-dependencies = [
- "proc-macro-hack",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.66"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
-
-[[package]]
-name = "opaque-debug"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
-
-[[package]]
-name = "proc-macro-hack"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "463bf29e7f11344e58c9e01f171470ab15c925c6822ad75028cc1c0e1d1eb63b"
-dependencies = [
- "proc-macro-hack-impl",
-]
-
-[[package]]
-name = "proc-macro-hack-impl"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38c47dcb1594802de8c02f3b899e2018c78291168a22c281be21ea0fb4796842"
-
-[[package]]
-name = "sha-1"
-version = "0.8.2"
-dependencies = [
- "block-buffer",
- "digest",
- "fake-simd",
- "hex-literal",
- "libc",
- "opaque-debug",
- "sha1-asm",
-]
-
-[[package]]
-name = "sha1-asm"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9dae2289dd5f5dc67fb0f341a5676c5c197415c51ce7345ae1bd0d36a6cbbfc"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "typenum"
-version = "1.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
diff --git a/vendor/sha-1-0.8.2/Cargo.toml b/vendor/sha-1-0.8.2/Cargo.toml
deleted file mode 100644
index a230700c7..000000000
--- a/vendor/sha-1-0.8.2/Cargo.toml
+++ /dev/null
@@ -1,58 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "sha-1"
-version = "0.8.2"
-authors = ["RustCrypto Developers"]
-description = "SHA-1 hash function"
-documentation = "https://docs.rs/sha-1"
-keywords = ["crypto", "sha1", "hash", "digest"]
-categories = ["cryptography", "no-std"]
-license = "MIT OR Apache-2.0"
-repository = "https://github.com/RustCrypto/hashes"
-
-[lib]
-name = "sha1"
-[dependencies.block-buffer]
-version = "0.7"
-
-[dependencies.digest]
-version = "0.8"
-
-[dependencies.fake-simd]
-version = "0.1"
-
-[dependencies.libc]
-version = "0.2"
-optional = true
-
-[dependencies.opaque-debug]
-version = "0.2"
-
-[dependencies.sha1-asm]
-version = "0.4"
-optional = true
-[dev-dependencies.digest]
-version = "0.8"
-features = ["dev"]
-
-[dev-dependencies.hex-literal]
-version = "0.1"
-
-[features]
-asm = ["sha1-asm"]
-asm-aarch64 = ["asm", "libc"]
-default = ["std"]
-std = ["digest/std"]
-[badges.travis-ci]
-repository = "RustCrypto/hashes"
diff --git a/vendor/sha-1-0.8.2/LICENSE-APACHE b/vendor/sha-1-0.8.2/LICENSE-APACHE
deleted file mode 100644
index 78173fa2e..000000000
--- a/vendor/sha-1-0.8.2/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/sha-1-0.8.2/LICENSE-MIT b/vendor/sha-1-0.8.2/LICENSE-MIT
deleted file mode 100644
index 66cf75563..000000000
--- a/vendor/sha-1-0.8.2/LICENSE-MIT
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2006-2009 Graydon Hoare
-Copyright (c) 2009-2013 Mozilla Foundation
-Copyright (c) 2016 Artyom Pavlov
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/sha-1-0.8.2/benches/lib.rs b/vendor/sha-1-0.8.2/benches/lib.rs
deleted file mode 100644
index e204e565a..000000000
--- a/vendor/sha-1-0.8.2/benches/lib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#![no_std]
-#![feature(test)]
-#[macro_use]
-extern crate digest;
-extern crate sha1;
-
-bench!(sha1::Sha1);
diff --git a/vendor/sha-1-0.8.2/examples/sha1sum.rs b/vendor/sha-1-0.8.2/examples/sha1sum.rs
deleted file mode 100644
index bde1ab4f6..000000000
--- a/vendor/sha-1-0.8.2/examples/sha1sum.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-extern crate sha1;
-
-use sha1::{Sha1, Digest};
-use std::env;
-use std::fs;
-use std::io::{self, Read};
-
-const BUFFER_SIZE: usize = 1024;
-
-/// Print digest result as hex string and name pair
-fn print_result(sum: &[u8], name: &str) {
- for byte in sum {
- print!("{:02x}", byte);
- }
- println!("\t{}", name);
-}
-
-/// Compute digest value for given `Reader` and print it
-/// On any error simply return without doing anything
-fn process<D: Digest + Default, R: Read>(reader: &mut R, name: &str) {
- let mut sh = D::default();
- let mut buffer = [0u8; BUFFER_SIZE];
- loop {
- let n = match reader.read(&mut buffer) {
- Ok(n) => n,
- Err(_) => return,
- };
- sh.input(&buffer[..n]);
- if n == 0 || n < BUFFER_SIZE {
- break;
- }
- }
- print_result(&sh.result(), name);
-}
-
-fn main() {
- let args = env::args();
- // Process files listed in command line arguments one by one
- // If no files provided process input from stdin
- if args.len() > 1 {
- for path in args.skip(1) {
- if let Ok(mut file) = fs::File::open(&path) {
- process::<Sha1, _>(&mut file, &path);
- }
- }
- } else {
- process::<Sha1, _>(&mut io::stdin(), "-");
- }
-}
diff --git a/vendor/sha-1-0.8.2/src/aarch64.rs b/vendor/sha-1-0.8.2/src/aarch64.rs
deleted file mode 100644
index d3cffecd7..000000000
--- a/vendor/sha-1-0.8.2/src/aarch64.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// TODO: Import those from libc, see https://github.com/rust-lang/libc/pull/1638
-const AT_HWCAP: u64 = 16;
-const HWCAP_SHA1: u64 = 32;
-
-#[inline(always)]
-pub fn sha1_supported() -> bool {
- let hwcaps: u64 = unsafe { ::libc::getauxval(AT_HWCAP) };
- (hwcaps & HWCAP_SHA1) != 0
-}
diff --git a/vendor/sha-1-0.8.2/src/consts.rs b/vendor/sha-1-0.8.2/src/consts.rs
deleted file mode 100644
index 628d4d6e0..000000000
--- a/vendor/sha-1-0.8.2/src/consts.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
-
-pub const STATE_LEN: usize = 5;
-
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-pub const BLOCK_LEN: usize = 16;
-
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-pub const K0: u32 = 0x5A827999u32;
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-pub const K1: u32 = 0x6ED9EBA1u32;
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-pub const K2: u32 = 0x8F1BBCDCu32;
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-pub const K3: u32 = 0xCA62C1D6u32;
-
-pub const H: [u32; STATE_LEN] = [
- 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
-];
diff --git a/vendor/sha-1-0.8.2/src/lib.rs b/vendor/sha-1-0.8.2/src/lib.rs
deleted file mode 100644
index 374c234c2..000000000
--- a/vendor/sha-1-0.8.2/src/lib.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-//! An implementation of the [SHA-1][1] cryptographic hash algorithm.
-//!
-//! # Usage
-//!
-//! ```rust
-//! # #[macro_use] extern crate hex_literal;
-//! # extern crate sha1;
-//! # fn main() {
-//! use sha1::{Sha1, Digest};
-//!
-//! // create a Sha1 object
-//! let mut hasher = Sha1::new();
-//!
-//! // process input message
-//! hasher.input(b"hello world");
-//!
-//! // acquire hash digest in the form of GenericArray,
-//! // which in this case is equivalent to [u8; 20]
-//! let result = hasher.result();
-//! assert_eq!(result[..], hex!("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"));
-//! # }
-//! ```
-//!
-//! Also see [RustCrypto/hashes][2] readme.
-//!
-//! [1]: https://en.wikipedia.org/wiki/SHA-1
-//! [2]: https://github.com/RustCrypto/hashes
-#![no_std]
-#![doc(html_logo_url =
- "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
-
-// Give relevant error messages if the user tries to enable AArch64 asm on unsupported platforms.
-#[cfg(all(feature = "asm-aarch64", target_arch = "aarch64", not(target_os = "linux")))]
-compile_error!("Your OS isn’t yet supported for runtime-checking of AArch64 features.");
-#[cfg(all(feature = "asm-aarch64", target_os = "linux", not(target_arch = "aarch64")))]
-compile_error!("Enable the \"asm\" feature instead of \"asm-aarch64\" on non-AArch64 Linux systems.");
-#[cfg(all(not(feature = "asm-aarch64"), feature = "asm", target_arch = "aarch64", target_os = "linux"))]
-compile_error!("Enable the \"asm-aarch64\" feature on AArch64 if you want to use asm.");
-
-extern crate block_buffer;
-#[macro_use] extern crate opaque_debug;
-#[macro_use] pub extern crate digest;
-#[cfg(feature = "std")]
-extern crate std;
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-extern crate fake_simd as simd;
-#[cfg(feature = "asm-aarch64")]
-extern crate libc;
-
-#[cfg(feature = "asm")]
-extern crate sha1_asm;
-#[cfg(all(feature = "asm", not(feature = "asm-aarch64")))]
-#[inline(always)]
-fn compress(state: &mut [u32; 5], block: &GenericArray<u8, U64>) {
- let block: &[u8; 64] = unsafe { core::mem::transmute(block) };
- sha1_asm::compress(state, block);
-}
-#[cfg(feature = "asm-aarch64")]
-mod aarch64;
-#[cfg(feature = "asm-aarch64")]
-#[inline(always)]
-fn compress(state: &mut [u32; 5], block: &GenericArray<u8, U64>) {
- // TODO: Replace this platform-specific call with is_aarch64_feature_detected!("sha1") once
- // that macro is stabilised and https://github.com/rust-lang/rfcs/pull/2725 is implemented
- // to let us use it on no_std.
- if aarch64::sha1_supported() {
- let block: &[u8; 64] = unsafe { core::mem::transmute(block) };
- sha1_asm::compress(state, block);
- } else {
- utils::compress(state, block);
- }
-}
-
-#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
-mod utils;
-#[cfg(not(feature = "asm"))]
-use utils::compress;
-
-pub use digest::Digest;
-use digest::{Input, BlockInput, FixedOutput, Reset};
-use digest::generic_array::GenericArray;
-use digest::generic_array::typenum::{U20, U64};
-use block_buffer::BlockBuffer;
-use block_buffer::byteorder::{BE, ByteOrder};
-
-mod consts;
-use consts::{STATE_LEN, H};
-
-/// Structure representing the state of a SHA-1 computation
-#[derive(Clone)]
-pub struct Sha1 {
- h: [u32; STATE_LEN],
- len: u64,
- buffer: BlockBuffer<U64>,
-}
-
-impl Default for Sha1 {
- fn default() -> Self {
- Sha1{ h: H, len: 0u64, buffer: Default::default() }
- }
-}
-
-impl BlockInput for Sha1 {
- type BlockSize = U64;
-}
-
-impl Input for Sha1 {
- fn input<B: AsRef<[u8]>>(&mut self, input: B) {
- let input = input.as_ref();
- // Assumes that `length_bits<<3` will not overflow
- self.len += input.len() as u64;
- let state = &mut self.h;
- self.buffer.input(input, |d| compress(state, d));
- }
-}
-
-impl FixedOutput for Sha1 {
- type OutputSize = U20;
-
- fn fixed_result(mut self) -> GenericArray<u8, Self::OutputSize> {
- {
- let state = &mut self.h;
- let l = self.len << 3;
- self.buffer.len64_padding::<BE, _>(l, |d| compress(state, d));
- }
- let mut out = GenericArray::default();
- BE::write_u32_into(&self.h,&mut out);
- out
- }
-}
-
-impl Reset for Sha1 {
- fn reset(&mut self) {
- self.h = H;
- self.len = 0;
- self.buffer.reset();
- }
-}
-
-impl_opaque_debug!(Sha1);
-impl_write!(Sha1);
diff --git a/vendor/sha-1-0.8.2/src/utils.rs b/vendor/sha-1-0.8.2/src/utils.rs
deleted file mode 100644
index e8b941a6e..000000000
--- a/vendor/sha-1-0.8.2/src/utils.rs
+++ /dev/null
@@ -1,300 +0,0 @@
-#![cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))]
-
-use consts::{BLOCK_LEN, K0, K1, K2, K3};
-use block_buffer::byteorder::{BE, ByteOrder};
-use simd::u32x4;
-use digest::generic_array::GenericArray;
-use digest::generic_array::typenum::U64;
-
-type Block = GenericArray<u8, U64>;
-
-/// Not an intrinsic, but gets the first element of a vector.
-#[inline]
-pub fn sha1_first(w0: u32x4) -> u32 {
- w0.0
-}
-
-/// Not an intrinsic, but adds a word to the first element of a vector.
-#[inline]
-pub fn sha1_first_add(e: u32, w0: u32x4) -> u32x4 {
- let u32x4(a, b, c, d) = w0;
- u32x4(e.wrapping_add(a), b, c, d)
-}
-
-/// Emulates `llvm.x86.sha1msg1` intrinsic.
-fn sha1msg1(a: u32x4, b: u32x4) -> u32x4 {
- let u32x4(_, _, w2, w3) = a;
- let u32x4(w4, w5, _, _) = b;
- a ^ u32x4(w2, w3, w4, w5)
-}
-
-/// Emulates `llvm.x86.sha1msg2` intrinsic.
-fn sha1msg2(a: u32x4, b: u32x4) -> u32x4 {
- let u32x4(x0, x1, x2, x3) = a;
- let u32x4(_, w13, w14, w15) = b;
-
- let w16 = (x0 ^ w13).rotate_left(1);
- let w17 = (x1 ^ w14).rotate_left(1);
- let w18 = (x2 ^ w15).rotate_left(1);
- let w19 = (x3 ^ w16).rotate_left(1);
-
- u32x4(w16, w17, w18, w19)
-}
-
-/// Performs 4 rounds of the message schedule update.
-/*
-pub fn sha1_schedule_x4(v0: u32x4, v1: u32x4, v2: u32x4, v3: u32x4) -> u32x4 {
- sha1msg2(sha1msg1(v0, v1) ^ v2, v3)
-}
-*/
-
-/// Emulates `llvm.x86.sha1nexte` intrinsic.
-#[inline]
-fn sha1_first_half(abcd: u32x4, msg: u32x4) -> u32x4 {
- sha1_first_add(sha1_first(abcd).rotate_left(30), msg)
-}
-
-/// Emulates `llvm.x86.sha1rnds4` intrinsic.
-/// Performs 4 rounds of the message block digest.
-fn sha1_digest_round_x4(abcd: u32x4, work: u32x4, i: i8) -> u32x4 {
- const K0V: u32x4 = u32x4(K0, K0, K0, K0);
- const K1V: u32x4 = u32x4(K1, K1, K1, K1);
- const K2V: u32x4 = u32x4(K2, K2, K2, K2);
- const K3V: u32x4 = u32x4(K3, K3, K3, K3);
-
- match i {
- 0 => sha1rnds4c(abcd, work + K0V),
- 1 => sha1rnds4p(abcd, work + K1V),
- 2 => sha1rnds4m(abcd, work + K2V),
- 3 => sha1rnds4p(abcd, work + K3V),
- _ => unreachable!("unknown icosaround index"),
- }
-}
-
-/// Not an intrinsic, but helps emulate `llvm.x86.sha1rnds4` intrinsic.
-fn sha1rnds4c(abcd: u32x4, msg: u32x4) -> u32x4 {
- let u32x4(mut a, mut b, mut c, mut d) = abcd;
- let u32x4(t, u, v, w) = msg;
- let mut e = 0u32;
-
- macro_rules! bool3ary_202 {
- ($a:expr, $b:expr, $c:expr) => ($c ^ ($a & ($b ^ $c)))
- } // Choose, MD5F, SHA1C
-
- e = e.wrapping_add(a.rotate_left(5))
- .wrapping_add(bool3ary_202!(b, c, d))
- .wrapping_add(t);
- b = b.rotate_left(30);
-
- d = d.wrapping_add(e.rotate_left(5))
- .wrapping_add(bool3ary_202!(a, b, c))
- .wrapping_add(u);
- a = a.rotate_left(30);
-
- c = c.wrapping_add(d.rotate_left(5))
- .wrapping_add(bool3ary_202!(e, a, b))
- .wrapping_add(v);
- e = e.rotate_left(30);
-
- b = b.wrapping_add(c.rotate_left(5))
- .wrapping_add(bool3ary_202!(d, e, a))
- .wrapping_add(w);
- d = d.rotate_left(30);
-
- u32x4(b, c, d, e)
-}
-
-/// Not an intrinsic, but helps emulate `llvm.x86.sha1rnds4` intrinsic.
-fn sha1rnds4p(abcd: u32x4, msg: u32x4) -> u32x4 {
- let u32x4(mut a, mut b, mut c, mut d) = abcd;
- let u32x4(t, u, v, w) = msg;
- let mut e = 0u32;
-
- macro_rules! bool3ary_150 {
- ($a:expr, $b:expr, $c:expr) => ($a ^ $b ^ $c)
- } // Parity, XOR, MD5H, SHA1P
-
- e = e.wrapping_add(a.rotate_left(5))
- .wrapping_add(bool3ary_150!(b, c, d))
- .wrapping_add(t);
- b = b.rotate_left(30);
-
- d = d.wrapping_add(e.rotate_left(5))
- .wrapping_add(bool3ary_150!(a, b, c))
- .wrapping_add(u);
- a = a.rotate_left(30);
-
- c = c.wrapping_add(d.rotate_left(5))
- .wrapping_add(bool3ary_150!(e, a, b))
- .wrapping_add(v);
- e = e.rotate_left(30);
-
- b = b.wrapping_add(c.rotate_left(5))
- .wrapping_add(bool3ary_150!(d, e, a))
- .wrapping_add(w);
- d = d.rotate_left(30);
-
- u32x4(b, c, d, e)
-}
-
-/// Not an intrinsic, but helps emulate `llvm.x86.sha1rnds4` intrinsic.
-fn sha1rnds4m(abcd: u32x4, msg: u32x4) -> u32x4 {
- let u32x4(mut a, mut b, mut c, mut d) = abcd;
- let u32x4(t, u, v, w) = msg;
- let mut e = 0u32;
-
- macro_rules! bool3ary_232 {
- ($a:expr, $b:expr, $c:expr) => (($a & $b) ^ ($a & $c) ^ ($b & $c))
- } // Majority, SHA1M
-
- e = e.wrapping_add(a.rotate_left(5))
- .wrapping_add(bool3ary_232!(b, c, d))
- .wrapping_add(t);
- b = b.rotate_left(30);
-
- d = d.wrapping_add(e.rotate_left(5))
- .wrapping_add(bool3ary_232!(a, b, c))
- .wrapping_add(u);
- a = a.rotate_left(30);
-
- c = c.wrapping_add(d.rotate_left(5))
- .wrapping_add(bool3ary_232!(e, a, b))
- .wrapping_add(v);
- e = e.rotate_left(30);
-
- b = b.wrapping_add(c.rotate_left(5))
- .wrapping_add(bool3ary_232!(d, e, a))
- .wrapping_add(w);
- d = d.rotate_left(30);
-
- u32x4(b, c, d, e)
-}
-
-/// Process a block with the SHA-1 algorithm.
-fn sha1_digest_block_u32(state: &mut [u32; 5], block: &[u32; 16]) {
-
- macro_rules! schedule {
- ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => (
- sha1msg2(sha1msg1($v0, $v1) ^ $v2, $v3)
- )
- }
-
- macro_rules! rounds4 {
- ($h0:ident, $h1:ident, $wk:expr, $i:expr) => (
- sha1_digest_round_x4($h0, sha1_first_half($h1, $wk), $i)
- )
- }
-
- // Rounds 0..20
- // TODO: replace with `u32x4::load`
- let mut h0 = u32x4(state[0], state[1], state[2], state[3]);
- let mut w0 = u32x4(block[0], block[1], block[2], block[3]);
- let mut h1 = sha1_digest_round_x4(h0, sha1_first_add(state[4], w0), 0);
- let mut w1 = u32x4(block[4], block[5], block[6], block[7]);
- h0 = rounds4!(h1, h0, w1, 0);
- let mut w2 = u32x4(block[8], block[9], block[10], block[11]);
- h1 = rounds4!(h0, h1, w2, 0);
- let mut w3 = u32x4(block[12], block[13], block[14], block[15]);
- h0 = rounds4!(h1, h0, w3, 0);
- let mut w4 = schedule!(w0, w1, w2, w3);
- h1 = rounds4!(h0, h1, w4, 0);
-
- // Rounds 20..40
- w0 = schedule!(w1, w2, w3, w4);
- h0 = rounds4!(h1, h0, w0, 1);
- w1 = schedule!(w2, w3, w4, w0);
- h1 = rounds4!(h0, h1, w1, 1);
- w2 = schedule!(w3, w4, w0, w1);
- h0 = rounds4!(h1, h0, w2, 1);
- w3 = schedule!(w4, w0, w1, w2);
- h1 = rounds4!(h0, h1, w3, 1);
- w4 = schedule!(w0, w1, w2, w3);
- h0 = rounds4!(h1, h0, w4, 1);
-
- // Rounds 40..60
- w0 = schedule!(w1, w2, w3, w4);
- h1 = rounds4!(h0, h1, w0, 2);
- w1 = schedule!(w2, w3, w4, w0);
- h0 = rounds4!(h1, h0, w1, 2);
- w2 = schedule!(w3, w4, w0, w1);
- h1 = rounds4!(h0, h1, w2, 2);
- w3 = schedule!(w4, w0, w1, w2);
- h0 = rounds4!(h1, h0, w3, 2);
- w4 = schedule!(w0, w1, w2, w3);
- h1 = rounds4!(h0, h1, w4, 2);
-
- // Rounds 60..80
- w0 = schedule!(w1, w2, w3, w4);
- h0 = rounds4!(h1, h0, w0, 3);
- w1 = schedule!(w2, w3, w4, w0);
- h1 = rounds4!(h0, h1, w1, 3);
- w2 = schedule!(w3, w4, w0, w1);
- h0 = rounds4!(h1, h0, w2, 3);
- w3 = schedule!(w4, w0, w1, w2);
- h1 = rounds4!(h0, h1, w3, 3);
- w4 = schedule!(w0, w1, w2, w3);
- h0 = rounds4!(h1, h0, w4, 3);
-
- let e = sha1_first(h1).rotate_left(30);
- let u32x4(a, b, c, d) = h0;
-
- state[0] = state[0].wrapping_add(a);
- state[1] = state[1].wrapping_add(b);
- state[2] = state[2].wrapping_add(c);
- state[3] = state[3].wrapping_add(d);
- state[4] = state[4].wrapping_add(e);
-}
-
-/// Process a block with the SHA-1 algorithm. (See more...)
-///
-/// SHA-1 is a cryptographic hash function, and as such, it operates
-/// on an arbitrary number of bytes. This function operates on a fixed
-/// number of bytes. If you call this function with anything other than
-/// 64 bytes, then it will panic! This function takes two arguments:
-///
-/// * `state` is reference to an **array** of 5 words.
-/// * `block` is reference to a **slice** of 64 bytes.
-///
-/// If you want the function that performs a message digest on an arbitrary
-/// number of bytes, then see also the `Sha1` struct above.
-///
-/// # Implementation
-///
-/// First, some background. Both ARM and Intel are releasing documentation
-/// that they plan to include instruction set extensions for SHA1 and SHA256
-/// sometime in the near future. Second, LLVM won't lower these intrinsics yet,
-/// so these functions were written emulate these instructions. Finally,
-/// the block function implemented with these emulated intrinsics turned out
-/// to be quite fast! What follows is a discussion of this CPU-level view
-/// of the SHA-1 algorithm and how it relates to the mathematical definition.
-///
-/// The SHA instruction set extensions can be divided up into two categories:
-///
-/// * message work schedule update calculation ("schedule" v., "work" n.)
-/// * message block 80-round digest calculation ("digest" v., "block" n.)
-///
-/// The schedule-related functions can be used to easily perform 4 rounds
-/// of the message work schedule update calculation, as shown below:
-///
-/// ```ignore
-/// macro_rules! schedule_x4 {
-/// ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => (
-/// sha1msg2(sha1msg1($v0, $v1) ^ $v2, $v3)
-/// )
-/// }
-///
-/// macro_rules! round_x4 {
-/// ($h0:ident, $h1:ident, $wk:expr, $i:expr) => (
-/// sha1rnds4($h0, sha1_first_half($h1, $wk), $i)
-/// )
-/// }
-/// ```
-///
-/// and also shown above is how the digest-related functions can be used to
-/// perform 4 rounds of the message block digest calculation.
-///
-pub fn compress(state: &mut [u32; 5], block: &Block) {
- let mut block_u32 = [0u32; BLOCK_LEN];
- BE::read_u32_into(block, &mut block_u32[..]);
- sha1_digest_block_u32(state, &block_u32);
-}
diff --git a/vendor/sha-1-0.8.2/tests/data/one_million_a.bin b/vendor/sha-1-0.8.2/tests/data/one_million_a.bin
deleted file mode 100644
index 0c759d80f..000000000
--- a/vendor/sha-1-0.8.2/tests/data/one_million_a.bin
+++ /dev/null
@@ -1 +0,0 @@
-4ª—<ÔÄÚ¤öë+Û­'1e4o \ No newline at end of file
diff --git a/vendor/sha-1-0.8.2/tests/data/sha1.blb b/vendor/sha-1-0.8.2/tests/data/sha1.blb
deleted file mode 100644
index 13ae2df26..000000000
--- a/vendor/sha-1-0.8.2/tests/data/sha1.blb
+++ /dev/null
@@ -1 +0,0 @@
-blobby1abc©™>6Gjº>%qxPÂlœÐØ8abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq„˜>D;Ònº®J¡ùQ)ååFpñ+The quick brown fox jumps over the lazy dog/ÔáÆz-(üí„žá»vç9“ë+The quick brown fox jumps over the lazy cogÞŸ,Ò^:úÓèZ Ñ}› ´³ \ No newline at end of file
diff --git a/vendor/sha-1-0.8.2/tests/lib.rs b/vendor/sha-1-0.8.2/tests/lib.rs
deleted file mode 100644
index 348684b1f..000000000
--- a/vendor/sha-1-0.8.2/tests/lib.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#![no_std]
-#[macro_use]
-extern crate digest;
-extern crate sha1;
-
-use digest::dev::{one_million_a, digest_test};
-
-new_test!(sha1_main, "sha1", sha1::Sha1, digest_test);
-
-#[test]
-fn sha1_1million_a() {
- let output = include_bytes!("data/one_million_a.bin");
- one_million_a::<sha1::Sha1>(output);
-}
diff --git a/vendor/syn/.cargo-checksum.json b/vendor/syn/.cargo-checksum.json
index 8ea280f0f..691cc4e06 100644
--- a/vendor/syn/.cargo-checksum.json
+++ b/vendor/syn/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"5b13c4f4b16314a07b7c6a3cc3e726579bf0c24b5b45fa2ec48ab966ccaa0e45","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"b1546652aefba564455c1ebbf0f276450d4fdb19755e08bfa03c13c8bab241fc","benches/file.rs":"af4671030b7fbc3a5dbc37b492e80fcae2893ad7a64dd43dac12cf5906c32301","benches/rust.rs":"22dfbffc39f8d091ef74cca849e7e7c69e9a47f2a06f7dec91c0382401055c14","build.rs":"b815649fd2929d3debd93a58f5da2fb8eba506047a6a5ba538347305828a87b0","src/attr.rs":"234d9cebe2c5e92cd0f5e1117bf5755037e2e905788a337000a65d4bd82b63aa","src/await.rs":"8aa22e3c201cb2bdb6b4817fa00901f308ab06817607aa7b884c58c957705969","src/bigint.rs":"efc7f64959980653d73fe4f8bc2a3a2904dc05f45b02c6dc15cd316fa3d7c338","src/buffer.rs":"24a3ba4928a5b2265199c29b84610b6f988bc422076ad07dfa30e91b6d72314f","src/custom_keyword.rs":"5c706fc3611e73d16b8c019d7ecb848a86b1ccfcd9e556f80bb6e6a4abe058a8","src/custom_punctuation.rs":"8a666298e774b0d326642f0f73284f6677d0d0a7c9e4a712c9c98d010b4d8a2c","src/data.rs":"75d2c2b5d6a01bf8a6fa2845e41663d8045a78b4b191f1a1bd7c93619d20017a","src/derive.rs":"ee24a202be2d36ccdff576dd9cd765e94b33ef2286946e6725d75b08e777d462","src/discouraged.rs":"6c6a9298f8d24f578da119557bc588f3bd928f7b79fca27d6bdfe3e786dd005f","src/error.rs":"e548cc5b7c6f742ab6c19788755980594c4cb8086f99e6709f1cbc982961102d","src/export.rs":"0cf50d70c32d5fddba8b1193032df62e560237c113df3e86ba26b565cc82838e","src/expr.rs":"0d441100457567b7b18372fdcbbe833d7516b5a43f17f1cfc4d7f354141b8206","src/ext.rs":"1f648cff1d705a1cea64b32b77482b97a82d2fe0aaf63b40cade91e5c02dc969","src/file.rs":"f86697655222ae294215114f4eae8e6b0b5e2a935d6c479ff8f8f889c4efd2e2","src/gen/clone.rs":"c43199af10b9963476a1ef6b9e0540363a8383c611f8999463235a0939817da8","src/gen/debug.rs":"12e07500a09d1d15b7a148d9155af357c7ac9b65ac100906cf0fac604403274e","src/gen/eq.rs":"e0928a9f4e81a7ede04853d1837abccaf29dd4ffb56d864fad2f4c3a4c76f1b4","src/gen/fold.rs":"43b34e7a951c180b65c6dd97c380f067ea91776f52e70f61555bd8a4120170b1","src/gen/hash.rs":"b66425846386e2168990b3bee2461f5c01695acd8c4b6360619a07108b260f3d","src/gen/visit.rs":"d559f661ab4a4c5b058af91ef244f30f906b6be82d1dd61bf0d058236f8c6a35","src/gen/visit_mut.rs":"fe384074919cdb1a6f54b93f8a9c768da7d3751e5bbfaf8c6c7133a7ebd390ae","src/gen_helper.rs":"ea6c66388365971db6a2fc86cbb208f7eacde77e245bc8623f27a3642a3d7741","src/generics.rs":"46ed41bf116448822ddfefcb62e803fd33264ca8ba672efc0612674d85b6dd11","src/group.rs":"166f0fbb365471ffa3e4f554b72c2b460cbf7e3a1f9bec6c01ef6bbbcd751041","src/ident.rs":"2443e43561abea7eea577b141422258237a663499c839923d8a5ca6fea2470db","src/item.rs":"2745d8bc068f821fc7dc8f480aceac1d10adc578a0b8b7317eb78f5c9048c68c","src/lib.rs":"81f5b18a8474d6a919af2134ea263f940584c347a2592cbc5e7f31987d3c5e15","src/lifetime.rs":"b18862ef1e690037a4f308ea897debad7bc5038584e3b26c6d8809752ea0e3c2","src/lit.rs":"9134ff103d943cfabdbfae56e78881680f91f9902172b890884a05c58131602a","src/lookahead.rs":"e2c2b6d55906421e83dab51463b58bc6dcb582f1bff9303c8b62afefb8d71e5f","src/mac.rs":"004cb89f9697564f6c9ee837e08ead68463ef946fb4c13c6c105adf2ba364b2b","src/macros.rs":"936f503c2fcde602f05220954ecaf87625c6138d0af13d33d56c7b6530110084","src/op.rs":"9d499022902743a6a0a19223b356449a979b90e60552d0446497d72750e646a4","src/parse.rs":"7b2f8caddf25a5734cbcdf7cbf043cbf9afbc07b484966cd59ddfcec9f970fb3","src/parse_macro_input.rs":"88929a1a7e5e72aa2d0b3459e52d8975afea856d159047ba4ab02ecbc5878a9c","src/parse_quote.rs":"d7d996f1382c68b5fbfd4b7327ce1d389cd43c3bb3c4f382a35994d0bb79d8ab","src/pat.rs":"1e0223ca92c160e07b17a593bb93dd5d451fc9b7014012b403377a4f0f21bfce","src/path.rs":"1ad8b8335628f67a013b7ce2f662aa2feab4583ff67bc959a9dea1dcb51be8a3","src/print.rs":"da6529c1d9d21aaf6c835f66b4e67eacb7cf91a10eb5e9a2143b49bf99b3b5e1","src/punctuated.rs":"f687c23bd3ae512e7412c28ac68030d3bc7a384d1ca8b3da6620e364b0cbbb78","src/reserved.rs":"e70e028bd55cfa43e23cab4ba29e4dc53a3d91eff685ef2b6e57efc2b87a3428","src/sealed.rs":"896a495a5340eec898527f18bd4ddca408ea03ea0ee3af30074ff48deace778d","src/span.rs":"748c51c6feb223c26d3b1701f5bb98aee823666c775c98106cfa24fe29d8cec1","src/spanned.rs":"3ca016a943637653ab98e373dfb826a120f3c159867346fa38a844439944eb39","src/stmt.rs":"8115bc96090022baad91660d7e5e986664c3f1fbd2f112d1c5d1d77e5c3f227e","src/thread.rs":"815eca6bd64f4eef7c447f0809e84108f5428ff50225224b373efd8fbb696874","src/token.rs":"5e423a696f80e281c322f37c87577f9fdc28607e9c007e24896a2b12da62d5ad","src/tt.rs":"32402645b6e82ef1e882945721b59b5fb7b0ee337d1972876362ecacef643d0f","src/ty.rs":"5c05b000d4884334bed729c3345732fbbb4136a75df9dd5002c493ebb6cd091b","src/verbatim.rs":"802a97df997432f18cac6e6200ff6ea29fb2474986005e0fcdbc2b65197f87f7","src/whitespace.rs":"e63dd0aa3d34029f17766a8b09c1a6e4479e36c552c8b7023d710a399333aace","tests/.gitignore":"22e782449a3c216db3f7215d5fb8882e316768e40beeec3833aae419ad8941db","tests/common/eq.rs":"fc4b0ced43acb32eedecb1a161bfe12148aacdd7bf57c926da55880b70b529f7","tests/common/mod.rs":"432ad35577f836a20b517d8c26ed994ac25fe73ef2f461c67688b61b99762015","tests/common/parse.rs":"81580f23583723f7a2a337c4d13ebc021057cd825562fb4e474caa7cc641fed9","tests/debug/gen.rs":"4937074a11fe8266431d05177435bad28340763d408d0a4c45bd0c0acc90a86a","tests/debug/mod.rs":"3a6bb799f478101f71c84c6f1a854a58afe2f9db43c39017909346ca20262d94","tests/macros/mod.rs":"aff805b35cfd55aef6a1359ff747e4023afcb08d69d86aff4c19465d29dda088","tests/regression.rs":"f962ebf24007f631f7e702e34e142d07581da7c9a36321ac142cafed1a0afc69","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/repo/mod.rs":"947b678f50df8716ef5c946885a3096e91ab2ec4ce2251cea83d6e6d2ab82eb5","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"cff01db49d28ab23b0b258bc6c0a5cc4071be4fe7248eef344a5d79d2fb649b7","tests/test_attribute.rs":"0ffd99384e1a52ae17d9fed5c4053e411e8f9018decef07ffa621d1faa7329d8","tests/test_derive_input.rs":"63f0b4d56f3f421e0bb523ce2924afe9e349f0ccefda52ccb8e1e5f342e6d525","tests/test_expr.rs":"a639728866a063b590430965a4840c01755e398b89be12d8d09b0aa97837ecac","tests/test_generics.rs":"54b7d2afc19aa6e9049585f4c8f7d3f0c29ac3bd11a2c769e9df76f18a4f5ecb","tests/test_grouping.rs":"6276c3c73bba649dec5c97904ad2492879f918bc887a2c425d095c654ca0d925","tests/test_ident.rs":"9eb53d1e21edf23e7c9e14dc74dcc2b2538e9221e19dbcc0a44e3acc2e90f3f6","tests/test_item.rs":"a3642c80066f1e7787becfd0278af90a6b7968d6c1249e25e81663aa454cfb2a","tests/test_iterators.rs":"53ed6078d37550bd6765d2411e3660be401aef8a31a407350cc064a7d08c7c33","tests/test_lit.rs":"19740ea9cd4a980bcab9b0dcaa4b032bb6ebb137fa5e4237140b97da1d9679fa","tests/test_meta.rs":"65d4586d131f6cac66694ca5e936748ec4e7f7423af6d8da509240e6be14800b","tests/test_parse_buffer.rs":"68d857f776396d064fcc0023c37093c2fbf75ee68e8241d4014d00d1423c18e9","tests/test_parse_stream.rs":"2f449a2c41a3dee6fd14bee24e1666a453cb808eda17332fd91afd127fcdd2a6","tests/test_pat.rs":"d4465f4fc3fd5d6e534ba8efabe1e0ed6da89de4ac7c96effa6bfb880c4287cf","tests/test_path.rs":"71092a5ae2c9143b92a8fe15a92d39958b3c28bd4d4275cfb2d22cbdd53ada07","tests/test_precedence.rs":"1069d979cec0e6c650bebb58be272d23080ce89e83d194dfa2718d22912e481d","tests/test_receiver.rs":"084eca59984b9a18651da52f2c4407355da3de1335916a12477652999e2d01cc","tests/test_round_trip.rs":"b47662e35be2729f28bacdbbea20f1879c111889430e735a7bcb5f2a5c0b9e5c","tests/test_shebang.rs":"f5772cadad5b56e3112cb16308b779f92bce1c3a48091fc9933deb2276a69331","tests/test_should_parse.rs":"1d3535698a446e2755bfc360676bdb161841a1f454cdef6e7556c6d06a95c89d","tests/test_size.rs":"1aa0dd489bd844a4a9cf32a5310abd66dad1dae3ffb24fe1288b62a26bfdd8dc","tests/test_stmt.rs":"1c39e26e262673aee7747338f0dbca01f5fc4f07b198b11414a614f36d3f9587","tests/test_token_trees.rs":"43e56a701817e3c3bfd0cae54a457dd7a38ccb3ca19da41e2b995fdf20e6ed18","tests/test_ty.rs":"f71d7f7f1c038aaabea8dd4c03c0d5752c76d570f8b4885a81659825bbb4d576","tests/test_visibility.rs":"7456fcb3a6634db509748aededff9c2d8b242d511a3e5ee3022e40b232892704","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"} \ No newline at end of file
+{"files":{"Cargo.toml":"598185e9190166e7f3217ced440d8b3e555ae2a6a84b51ee5ea0a5c7f55bdd0b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"b1546652aefba564455c1ebbf0f276450d4fdb19755e08bfa03c13c8bab241fc","benches/file.rs":"39e124e8ebb7f7171af29e87debbcaeb87c1eb465ef1436cfd8f218b340ef580","benches/rust.rs":"22dfbffc39f8d091ef74cca849e7e7c69e9a47f2a06f7dec91c0382401055c14","build.rs":"b815649fd2929d3debd93a58f5da2fb8eba506047a6a5ba538347305828a87b0","src/attr.rs":"234d9cebe2c5e92cd0f5e1117bf5755037e2e905788a337000a65d4bd82b63aa","src/await.rs":"8aa22e3c201cb2bdb6b4817fa00901f308ab06817607aa7b884c58c957705969","src/bigint.rs":"efc7f64959980653d73fe4f8bc2a3a2904dc05f45b02c6dc15cd316fa3d7c338","src/buffer.rs":"bd5762429e5eb3c899167e820620e7e2a66b4573c48e17326ed12d7461962536","src/custom_keyword.rs":"5c706fc3611e73d16b8c019d7ecb848a86b1ccfcd9e556f80bb6e6a4abe058a8","src/custom_punctuation.rs":"8a666298e774b0d326642f0f73284f6677d0d0a7c9e4a712c9c98d010b4d8a2c","src/data.rs":"75d2c2b5d6a01bf8a6fa2845e41663d8045a78b4b191f1a1bd7c93619d20017a","src/derive.rs":"ee24a202be2d36ccdff576dd9cd765e94b33ef2286946e6725d75b08e777d462","src/discouraged.rs":"6c6a9298f8d24f578da119557bc588f3bd928f7b79fca27d6bdfe3e786dd005f","src/error.rs":"e548cc5b7c6f742ab6c19788755980594c4cb8086f99e6709f1cbc982961102d","src/export.rs":"0cf50d70c32d5fddba8b1193032df62e560237c113df3e86ba26b565cc82838e","src/expr.rs":"0d441100457567b7b18372fdcbbe833d7516b5a43f17f1cfc4d7f354141b8206","src/ext.rs":"1f648cff1d705a1cea64b32b77482b97a82d2fe0aaf63b40cade91e5c02dc969","src/file.rs":"f86697655222ae294215114f4eae8e6b0b5e2a935d6c479ff8f8f889c4efd2e2","src/gen/clone.rs":"c43199af10b9963476a1ef6b9e0540363a8383c611f8999463235a0939817da8","src/gen/debug.rs":"12e07500a09d1d15b7a148d9155af357c7ac9b65ac100906cf0fac604403274e","src/gen/eq.rs":"e0928a9f4e81a7ede04853d1837abccaf29dd4ffb56d864fad2f4c3a4c76f1b4","src/gen/fold.rs":"43b34e7a951c180b65c6dd97c380f067ea91776f52e70f61555bd8a4120170b1","src/gen/hash.rs":"b66425846386e2168990b3bee2461f5c01695acd8c4b6360619a07108b260f3d","src/gen/visit.rs":"d559f661ab4a4c5b058af91ef244f30f906b6be82d1dd61bf0d058236f8c6a35","src/gen/visit_mut.rs":"fe384074919cdb1a6f54b93f8a9c768da7d3751e5bbfaf8c6c7133a7ebd390ae","src/gen_helper.rs":"ea6c66388365971db6a2fc86cbb208f7eacde77e245bc8623f27a3642a3d7741","src/generics.rs":"46ed41bf116448822ddfefcb62e803fd33264ca8ba672efc0612674d85b6dd11","src/group.rs":"166f0fbb365471ffa3e4f554b72c2b460cbf7e3a1f9bec6c01ef6bbbcd751041","src/ident.rs":"2443e43561abea7eea577b141422258237a663499c839923d8a5ca6fea2470db","src/item.rs":"2745d8bc068f821fc7dc8f480aceac1d10adc578a0b8b7317eb78f5c9048c68c","src/lib.rs":"143cbfa606d88ed75d3f80a27ca582c4b5285e2e60b78991bec02393ffebf334","src/lifetime.rs":"b18862ef1e690037a4f308ea897debad7bc5038584e3b26c6d8809752ea0e3c2","src/lit.rs":"9134ff103d943cfabdbfae56e78881680f91f9902172b890884a05c58131602a","src/lookahead.rs":"e2c2b6d55906421e83dab51463b58bc6dcb582f1bff9303c8b62afefb8d71e5f","src/mac.rs":"004cb89f9697564f6c9ee837e08ead68463ef946fb4c13c6c105adf2ba364b2b","src/macros.rs":"936f503c2fcde602f05220954ecaf87625c6138d0af13d33d56c7b6530110084","src/op.rs":"9d499022902743a6a0a19223b356449a979b90e60552d0446497d72750e646a4","src/parse.rs":"7b2f8caddf25a5734cbcdf7cbf043cbf9afbc07b484966cd59ddfcec9f970fb3","src/parse_macro_input.rs":"88929a1a7e5e72aa2d0b3459e52d8975afea856d159047ba4ab02ecbc5878a9c","src/parse_quote.rs":"d7d996f1382c68b5fbfd4b7327ce1d389cd43c3bb3c4f382a35994d0bb79d8ab","src/pat.rs":"1e0223ca92c160e07b17a593bb93dd5d451fc9b7014012b403377a4f0f21bfce","src/path.rs":"1ad8b8335628f67a013b7ce2f662aa2feab4583ff67bc959a9dea1dcb51be8a3","src/print.rs":"da6529c1d9d21aaf6c835f66b4e67eacb7cf91a10eb5e9a2143b49bf99b3b5e1","src/punctuated.rs":"f687c23bd3ae512e7412c28ac68030d3bc7a384d1ca8b3da6620e364b0cbbb78","src/reserved.rs":"e70e028bd55cfa43e23cab4ba29e4dc53a3d91eff685ef2b6e57efc2b87a3428","src/sealed.rs":"896a495a5340eec898527f18bd4ddca408ea03ea0ee3af30074ff48deace778d","src/span.rs":"748c51c6feb223c26d3b1701f5bb98aee823666c775c98106cfa24fe29d8cec1","src/spanned.rs":"3ca016a943637653ab98e373dfb826a120f3c159867346fa38a844439944eb39","src/stmt.rs":"8115bc96090022baad91660d7e5e986664c3f1fbd2f112d1c5d1d77e5c3f227e","src/thread.rs":"815eca6bd64f4eef7c447f0809e84108f5428ff50225224b373efd8fbb696874","src/token.rs":"5e423a696f80e281c322f37c87577f9fdc28607e9c007e24896a2b12da62d5ad","src/tt.rs":"32402645b6e82ef1e882945721b59b5fb7b0ee337d1972876362ecacef643d0f","src/ty.rs":"5c05b000d4884334bed729c3345732fbbb4136a75df9dd5002c493ebb6cd091b","src/verbatim.rs":"802a97df997432f18cac6e6200ff6ea29fb2474986005e0fcdbc2b65197f87f7","src/whitespace.rs":"e63dd0aa3d34029f17766a8b09c1a6e4479e36c552c8b7023d710a399333aace","tests/.gitignore":"22e782449a3c216db3f7215d5fb8882e316768e40beeec3833aae419ad8941db","tests/common/eq.rs":"529ae94214c0666045a4c16d9beab6c71eedb40e100be8f990674d44480b5ba6","tests/common/mod.rs":"432ad35577f836a20b517d8c26ed994ac25fe73ef2f461c67688b61b99762015","tests/common/parse.rs":"81580f23583723f7a2a337c4d13ebc021057cd825562fb4e474caa7cc641fed9","tests/debug/gen.rs":"4937074a11fe8266431d05177435bad28340763d408d0a4c45bd0c0acc90a86a","tests/debug/mod.rs":"3a6bb799f478101f71c84c6f1a854a58afe2f9db43c39017909346ca20262d94","tests/macros/mod.rs":"aff805b35cfd55aef6a1359ff747e4023afcb08d69d86aff4c19465d29dda088","tests/regression.rs":"f962ebf24007f631f7e702e34e142d07581da7c9a36321ac142cafed1a0afc69","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/repo/mod.rs":"947b678f50df8716ef5c946885a3096e91ab2ec4ce2251cea83d6e6d2ab82eb5","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"cff01db49d28ab23b0b258bc6c0a5cc4071be4fe7248eef344a5d79d2fb649b7","tests/test_attribute.rs":"0ffd99384e1a52ae17d9fed5c4053e411e8f9018decef07ffa621d1faa7329d8","tests/test_derive_input.rs":"62bb86aaaaf730187a46ff700a8e3b2d1a163039b109b6a483aa44ed2b6806fe","tests/test_expr.rs":"a639728866a063b590430965a4840c01755e398b89be12d8d09b0aa97837ecac","tests/test_generics.rs":"54b7d2afc19aa6e9049585f4c8f7d3f0c29ac3bd11a2c769e9df76f18a4f5ecb","tests/test_grouping.rs":"6276c3c73bba649dec5c97904ad2492879f918bc887a2c425d095c654ca0d925","tests/test_ident.rs":"9eb53d1e21edf23e7c9e14dc74dcc2b2538e9221e19dbcc0a44e3acc2e90f3f6","tests/test_item.rs":"a3642c80066f1e7787becfd0278af90a6b7968d6c1249e25e81663aa454cfb2a","tests/test_iterators.rs":"53ed6078d37550bd6765d2411e3660be401aef8a31a407350cc064a7d08c7c33","tests/test_lit.rs":"19740ea9cd4a980bcab9b0dcaa4b032bb6ebb137fa5e4237140b97da1d9679fa","tests/test_meta.rs":"65d4586d131f6cac66694ca5e936748ec4e7f7423af6d8da509240e6be14800b","tests/test_parse_buffer.rs":"68d857f776396d064fcc0023c37093c2fbf75ee68e8241d4014d00d1423c18e9","tests/test_parse_stream.rs":"2f449a2c41a3dee6fd14bee24e1666a453cb808eda17332fd91afd127fcdd2a6","tests/test_pat.rs":"d4465f4fc3fd5d6e534ba8efabe1e0ed6da89de4ac7c96effa6bfb880c4287cf","tests/test_path.rs":"71092a5ae2c9143b92a8fe15a92d39958b3c28bd4d4275cfb2d22cbdd53ada07","tests/test_precedence.rs":"1069d979cec0e6c650bebb58be272d23080ce89e83d194dfa2718d22912e481d","tests/test_receiver.rs":"084eca59984b9a18651da52f2c4407355da3de1335916a12477652999e2d01cc","tests/test_round_trip.rs":"b47662e35be2729f28bacdbbea20f1879c111889430e735a7bcb5f2a5c0b9e5c","tests/test_shebang.rs":"f5772cadad5b56e3112cb16308b779f92bce1c3a48091fc9933deb2276a69331","tests/test_should_parse.rs":"1d3535698a446e2755bfc360676bdb161841a1f454cdef6e7556c6d06a95c89d","tests/test_size.rs":"1aa0dd489bd844a4a9cf32a5310abd66dad1dae3ffb24fe1288b62a26bfdd8dc","tests/test_stmt.rs":"0601fc32131b5501dfcdc4b4248d46bf21e0a98a49eb19439e1a46869dfb30b7","tests/test_token_trees.rs":"43e56a701817e3c3bfd0cae54a457dd7a38ccb3ca19da41e2b995fdf20e6ed18","tests/test_ty.rs":"f71d7f7f1c038aaabea8dd4c03c0d5752c76d570f8b4885a81659825bbb4d576","tests/test_visibility.rs":"7456fcb3a6634db509748aededff9c2d8b242d511a3e5ee3022e40b232892704","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"} \ No newline at end of file
diff --git a/vendor/syn/Cargo.toml b/vendor/syn/Cargo.toml
index acd07cc81..d03ee2e31 100644
--- a/vendor/syn/Cargo.toml
+++ b/vendor/syn/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.31"
name = "syn"
-version = "1.0.98"
+version = "1.0.99"
authors = ["David Tolnay <dtolnay@gmail.com>"]
include = [
"/benches/**",
@@ -28,7 +28,14 @@ include = [
description = "Parser for Rust source code"
documentation = "https://docs.rs/syn"
readme = "README.md"
-categories = ["development-tools::procedural-macro-helpers"]
+keywords = [
+ "macros",
+ "syn",
+]
+categories = [
+ "development-tools::procedural-macro-helpers",
+ "parser-implementations",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/syn"
diff --git a/vendor/syn/benches/file.rs b/vendor/syn/benches/file.rs
index 86204df2d..c500dc24a 100644
--- a/vendor/syn/benches/file.rs
+++ b/vendor/syn/benches/file.rs
@@ -2,7 +2,11 @@
#![feature(rustc_private, test)]
#![recursion_limit = "1024"]
-#![allow(clippy::missing_panics_doc, clippy::must_use_candidate)]
+#![allow(
+ clippy::items_after_statements,
+ clippy::missing_panics_doc,
+ clippy::must_use_candidate
+)]
extern crate test;
@@ -15,17 +19,37 @@ mod common;
#[path = "../tests/repo/mod.rs"]
pub mod repo;
-use proc_macro2::TokenStream;
+use proc_macro2::{Span, TokenStream};
use std::fs;
use std::str::FromStr;
+use syn::parse::{ParseStream, Parser};
use test::Bencher;
const FILE: &str = "tests/rust/library/core/src/str/mod.rs";
-#[bench]
-fn parse_file(b: &mut Bencher) {
+fn get_tokens() -> TokenStream {
repo::clone_rust();
let content = fs::read_to_string(FILE).unwrap();
- let tokens = TokenStream::from_str(&content).unwrap();
+ TokenStream::from_str(&content).unwrap()
+}
+
+#[bench]
+fn baseline(b: &mut Bencher) {
+ let tokens = get_tokens();
+ b.iter(|| drop(tokens.clone()));
+}
+
+#[bench]
+fn create_token_buffer(b: &mut Bencher) {
+ let tokens = get_tokens();
+ fn immediate_fail(_input: ParseStream) -> syn::Result<()> {
+ Err(syn::Error::new(Span::call_site(), ""))
+ }
+ b.iter(|| immediate_fail.parse2(tokens.clone()));
+}
+
+#[bench]
+fn parse_file(b: &mut Bencher) {
+ let tokens = get_tokens();
b.iter(|| syn::parse2::<syn::File>(tokens.clone()));
}
diff --git a/vendor/syn/src/buffer.rs b/vendor/syn/src/buffer.rs
index 2cb6690f0..2c8e21bdb 100644
--- a/vendor/syn/src/buffer.rs
+++ b/vendor/syn/src/buffer.rs
@@ -14,7 +14,9 @@
use crate::proc_macro as pm;
use crate::Lifetime;
use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+use std::hint;
use std::marker::PhantomData;
+use std::mem;
use std::ptr;
use std::slice;
@@ -57,29 +59,39 @@ impl TokenBuffer {
// NOTE: Do not mutate the Vec returned from this function once it returns;
// the address of its backing memory must remain stable.
fn inner_new(stream: TokenStream, up: *const Entry) -> TokenBuffer {
- // Build up the entries list, recording the locations of any Groups
- // in the list to be processed later.
- let mut entries = Vec::new();
- let mut groups = Vec::new();
- for tt in stream {
+ let iterator = stream.into_iter();
+ let mut entries = Vec::with_capacity(iterator.size_hint().0 + 1);
+ let mut next_index_after_last_group = 0;
+ for tt in iterator {
match tt {
- TokenTree::Ident(sym) => {
- entries.push(Entry::Ident(sym));
+ TokenTree::Ident(ident) => {
+ entries.push(Entry::Ident(ident));
}
- TokenTree::Punct(op) => {
- entries.push(Entry::Punct(op));
+ TokenTree::Punct(punct) => {
+ entries.push(Entry::Punct(punct));
}
- TokenTree::Literal(l) => {
- entries.push(Entry::Literal(l));
+ TokenTree::Literal(literal) => {
+ entries.push(Entry::Literal(literal));
}
- TokenTree::Group(g) => {
- // Record the index of the interesting entry, and store an
- // `End(null)` there temporarily.
- groups.push((entries.len(), g));
- entries.push(Entry::End(ptr::null()));
+ TokenTree::Group(group) => {
+ // We cannot fill in a real `End` pointer until `entries` is
+ // finished growing and getting potentially reallocated.
+ // Instead, we temporarily coopt the spot where the end
+ // pointer would go, and use it to string together an
+ // intrusive linked list of all the Entry::Group entries in
+ // the vector. Later after `entries` is done growing, we'll
+ // traverse the linked list and fill in all the end
+ // pointers with a correct value.
+ let group_up =
+ ptr::null::<u8>().wrapping_add(next_index_after_last_group) as *const Entry;
+
+ let inner = Self::inner_new(group.stream(), group_up);
+ entries.push(Entry::Group(group, inner));
+ next_index_after_last_group = entries.len();
}
}
}
+
// Add an `End` entry to the end with a reference to the enclosing token
// stream which was passed in.
entries.push(Entry::End(up));
@@ -90,20 +102,36 @@ impl TokenBuffer {
// pointer into it.
let entries = entries.into_boxed_slice();
let len = entries.len();
+
// Convert boxed slice into a pointer to the first element early, to
// avoid invalidating pointers into this slice when we move the Box.
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
let entries = Box::into_raw(entries) as *mut Entry;
- for (idx, group) in groups {
- // We know that this index refers to one of the temporary
- // `End(null)` entries, and we know that the last entry is
- // `End(up)`, so the next index is also valid.
- let group_up = unsafe { entries.add(idx + 1) };
-
- // The end entry stored at the end of this Entry::Group should
- // point to the Entry which follows the Group in the list.
- let inner = Self::inner_new(group.stream(), group_up);
- unsafe { *entries.add(idx) = Entry::Group(group, inner) };
+
+ // Traverse intrusive linked list of Entry::Group entries and fill in
+ // correct End pointers.
+ while let Some(idx) = next_index_after_last_group.checked_sub(1) {
+ // We know that idx refers to one of the Entry::Group entries, and
+ // that the very last entry is an Entry::End, so the next index
+ // after any group entry is a valid index.
+ let group_up = unsafe { entries.add(next_index_after_last_group) };
+
+ // Linked list only takes us to entries which are of type Group.
+ let token_buffer = match unsafe { &*entries.add(idx) } {
+ Entry::Group(_group, token_buffer) => token_buffer,
+ _ => unsafe { hint::unreachable_unchecked() },
+ };
+
+ // Last entry in any TokenBuffer is of type End.
+ let buffer_ptr = token_buffer.ptr as *mut Entry;
+ let last_entry = unsafe { &mut *buffer_ptr.add(token_buffer.len - 1) };
+ let end_ptr_slot = match last_entry {
+ Entry::End(end_ptr_slot) => end_ptr_slot,
+ _ => unsafe { hint::unreachable_unchecked() },
+ };
+
+ // Step to next element in linked list.
+ next_index_after_last_group = mem::replace(end_ptr_slot, group_up) as usize;
}
TokenBuffer { ptr: entries, len }
@@ -275,7 +303,9 @@ impl<'a> Cursor<'a> {
pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> {
self.ignore_none();
match self.entry() {
- Entry::Punct(op) if op.as_char() != '\'' => Some((op.clone(), unsafe { self.bump() })),
+ Entry::Punct(punct) if punct.as_char() != '\'' => {
+ Some((punct.clone(), unsafe { self.bump() }))
+ }
_ => None,
}
}
@@ -285,7 +315,7 @@ impl<'a> Cursor<'a> {
pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> {
self.ignore_none();
match self.entry() {
- Entry::Literal(lit) => Some((lit.clone(), unsafe { self.bump() })),
+ Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump() })),
_ => None,
}
}
@@ -295,12 +325,12 @@ impl<'a> Cursor<'a> {
pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> {
self.ignore_none();
match self.entry() {
- Entry::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
+ Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => {
let next = unsafe { self.bump() };
match next.ident() {
Some((ident, rest)) => {
let lifetime = Lifetime {
- apostrophe: op.span(),
+ apostrophe: punct.span(),
ident,
};
Some((lifetime, rest))
@@ -334,9 +364,9 @@ impl<'a> Cursor<'a> {
pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> {
let tree = match self.entry() {
Entry::Group(group, _) => group.clone().into(),
- Entry::Literal(lit) => lit.clone().into(),
+ Entry::Literal(literal) => literal.clone().into(),
Entry::Ident(ident) => ident.clone().into(),
- Entry::Punct(op) => op.clone().into(),
+ Entry::Punct(punct) => punct.clone().into(),
Entry::End(..) => return None,
};
@@ -348,9 +378,9 @@ impl<'a> Cursor<'a> {
pub fn span(self) -> Span {
match self.entry() {
Entry::Group(group, _) => group.span(),
- Entry::Literal(l) => l.span(),
- Entry::Ident(t) => t.span(),
- Entry::Punct(o) => o.span(),
+ Entry::Literal(literal) => literal.span(),
+ Entry::Ident(ident) => ident.span(),
+ Entry::Punct(punct) => punct.span(),
Entry::End(..) => Span::call_site(),
}
}
@@ -364,7 +394,7 @@ impl<'a> Cursor<'a> {
Entry::End(..) => None,
// Treat lifetimes as a single tt for the purposes of 'skip'.
- Entry::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
+ Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => {
let next = unsafe { self.bump() };
match next.entry() {
Entry::Ident(_) => Some(unsafe { next.bump() }),
diff --git a/vendor/syn/src/lib.rs b/vendor/syn/src/lib.rs
index 608c39876..09addd3a6 100644
--- a/vendor/syn/src/lib.rs
+++ b/vendor/syn/src/lib.rs
@@ -250,15 +250,17 @@
//! dynamic library libproc_macro from rustc toolchain.
// Syn types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/syn/1.0.98")]
+#![doc(html_root_url = "https://docs.rs/syn/1.0.99")]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![allow(non_camel_case_types)]
#![allow(
clippy::cast_lossless,
clippy::cast_possible_truncation,
+ clippy::cast_ptr_alignment,
clippy::default_trait_access,
clippy::doc_markdown,
clippy::expl_impl_clone_on_copy,
+ clippy::explicit_auto_deref,
clippy::if_not_else,
clippy::inherent_to_string,
clippy::large_enum_variant,
diff --git a/vendor/syn/tests/common/eq.rs b/vendor/syn/tests/common/eq.rs
index a6c379165..ff100aa41 100644
--- a/vendor/syn/tests/common/eq.rs
+++ b/vendor/syn/tests/common/eq.rs
@@ -24,6 +24,7 @@ use rustc_ast::ast::Block;
use rustc_ast::ast::BlockCheckMode;
use rustc_ast::ast::BorrowKind;
use rustc_ast::ast::CaptureBy;
+use rustc_ast::ast::ClosureBinder;
use rustc_ast::ast::Const;
use rustc_ast::ast::Crate;
use rustc_ast::ast::Defaultness;
@@ -145,7 +146,7 @@ impl<T: ?Sized + SpanlessEq> SpanlessEq for Box<T> {
}
}
-impl<T: SpanlessEq> SpanlessEq for P<T> {
+impl<T: ?Sized + SpanlessEq> SpanlessEq for P<T> {
fn eq(&self, other: &Self) -> bool {
SpanlessEq::eq(&**self, &**other)
}
@@ -466,9 +467,10 @@ spanless_eq_enum!(BindingMode; ByRef(0) ByValue(0));
spanless_eq_enum!(BlockCheckMode; Default Unsafe(0));
spanless_eq_enum!(BorrowKind; Ref Raw);
spanless_eq_enum!(CaptureBy; Value Ref);
+spanless_eq_enum!(ClosureBinder; NotPresent For(span generic_params));
spanless_eq_enum!(Const; Yes(0) No);
spanless_eq_enum!(Defaultness; Default(0) Final);
-spanless_eq_enum!(Extern; None Implicit Explicit(0));
+spanless_eq_enum!(Extern; None Implicit(0) Explicit(0 1));
spanless_eq_enum!(FloatTy; F32 F64);
spanless_eq_enum!(FnRetTy; Default(0) Ty(0));
spanless_eq_enum!(ForeignItemKind; Static(0 1 2) Fn(0) TyAlias(0) MacCall(0));
@@ -498,7 +500,7 @@ spanless_eq_enum!(StmtKind; Local(0) Item(0) Expr(0) Semi(0) Empty MacCall(0));
spanless_eq_enum!(StrStyle; Cooked Raw(0));
spanless_eq_enum!(StructRest; Base(0) Rest(0) None);
spanless_eq_enum!(Term; Ty(0) Const(0));
-spanless_eq_enum!(TokenTree; Token(0) Delimited(0 1 2));
+spanless_eq_enum!(TokenTree; Token(0 1) Delimited(0 1 2));
spanless_eq_enum!(TraitBoundModifier; None Maybe MaybeConst MaybeConstMaybe);
spanless_eq_enum!(TraitObjectSyntax; Dyn None);
spanless_eq_enum!(UintTy; Usize U8 U16 U32 U64 U128);
@@ -512,7 +514,7 @@ spanless_eq_enum!(WherePredicate; BoundPredicate(0) RegionPredicate(0) EqPredica
spanless_eq_enum!(ExprKind; Box(0) Array(0) ConstBlock(0) Call(0 1)
MethodCall(0 1 2) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1)
Let(0 1 2) If(0 1 2) While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) Match(0 1)
- Closure(0 1 2 3 4 5) Block(0 1) Async(0 1 2) Await(0) TryBlock(0)
+ Closure(0 1 2 3 4 5 6) Block(0 1) Async(0 1 2) Await(0) TryBlock(0)
Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore Range(0 1 2)
Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0)
MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0) Yield(0) Yeet(0) Err);
@@ -610,7 +612,7 @@ impl SpanlessEq for TokenStream {
if SpanlessEq::eq(this, other) {
continue;
}
- if let (TokenTree::Token(this), TokenTree::Token(other)) = (this, other) {
+ if let (TokenTree::Token(this, _), TokenTree::Token(other, _)) = (this, other) {
if match (&this.kind, &other.kind) {
(TokenKind::Literal(this), TokenKind::Literal(other)) => {
SpanlessEq::eq(this, other)
@@ -641,10 +643,13 @@ fn doc_comment<'a>(
AttrStyle::Inner => true,
} {
match trees.next() {
- Some(TokenTree::Token(Token {
- kind: TokenKind::Not,
- span: _,
- })) => {}
+ Some(TokenTree::Token(
+ Token {
+ kind: TokenKind::Not,
+ span: _,
+ },
+ _spacing,
+ )) => {}
_ => return false,
}
}
@@ -654,21 +659,27 @@ fn doc_comment<'a>(
};
let mut trees = stream.trees();
match trees.next() {
- Some(TokenTree::Token(Token {
- kind: TokenKind::Ident(symbol, false),
- span: _,
- })) if *symbol == sym::doc => {}
+ Some(TokenTree::Token(
+ Token {
+ kind: TokenKind::Ident(symbol, false),
+ span: _,
+ },
+ _spacing,
+ )) if *symbol == sym::doc => {}
_ => return false,
}
match trees.next() {
- Some(TokenTree::Token(Token {
- kind: TokenKind::Eq,
- span: _,
- })) => {}
+ Some(TokenTree::Token(
+ Token {
+ kind: TokenKind::Eq,
+ span: _,
+ },
+ _spacing,
+ )) => {}
_ => return false,
}
match trees.next() {
- Some(TokenTree::Token(token)) => {
+ Some(TokenTree::Token(token, _spacing)) => {
is_escaped_literal_token(token, unescaped) && trees.next().is_none()
}
_ => false,
diff --git a/vendor/syn/tests/test_derive_input.rs b/vendor/syn/tests/test_derive_input.rs
index 93634e577..1eff01186 100644
--- a/vendor/syn/tests/test_derive_input.rs
+++ b/vendor/syn/tests/test_derive_input.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::too_many_lines)]
+#![allow(clippy::assertions_on_result_states, clippy::too_many_lines)]
#[macro_use]
mod macros;
diff --git a/vendor/syn/tests/test_stmt.rs b/vendor/syn/tests/test_stmt.rs
index 0bca62b04..f444e5b49 100644
--- a/vendor/syn/tests/test_stmt.rs
+++ b/vendor/syn/tests/test_stmt.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::non_ascii_literal)]
+#![allow(clippy::assertions_on_result_states, clippy::non_ascii_literal)]
#[macro_use]
mod macros;
diff --git a/vendor/thin-vec/.cargo-checksum.json b/vendor/thin-vec/.cargo-checksum.json
new file mode 100644
index 000000000..fc4888d7f
--- /dev/null
+++ b/vendor/thin-vec/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"596cca0e2a5b1abe635e3fcdd3fa1f5f7256a5f2abf63b9c6bba0cce32258b02","README.md":"9f102f13ccbabe9cdec7a206aa298d65e33dea84da9f08dd17b358ff44fe0286","src/lib.rs":"d6300952a66dc289328a464b466f4b281272b133e42e20e1e2cd0e6f8690087d"},"package":"104c2cb3180b6fb6d5b2278768e9b88b578d32ba751ea6e8d026688a40d7ed87"} \ No newline at end of file
diff --git a/vendor/thin-vec/Cargo.toml b/vendor/thin-vec/Cargo.toml
new file mode 100644
index 000000000..38908830d
--- /dev/null
+++ b/vendor/thin-vec/Cargo.toml
@@ -0,0 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "thin-vec"
+version = "0.2.8"
+authors = ["Aria Beingessner <a.beingessner@gmail.com>"]
+description = "A vec that takes up less space on the stack"
+homepage = "https://github.com/gankra/thin-vec"
+readme = "README.md"
+license = "MIT/Apache-2.0"
+repository = "https://github.com/gankra/thin-vec"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+
+[dev-dependencies.serde_test]
+version = "1.0"
+
+[features]
+default = []
+gecko-ffi = []
+unstable = []
diff --git a/vendor/thin-vec/README.md b/vendor/thin-vec/README.md
new file mode 100644
index 000000000..e8a8c90a2
--- /dev/null
+++ b/vendor/thin-vec/README.md
@@ -0,0 +1,9 @@
+![Rust CI](https://github.com/Gankra/thin-vec/workflows/Rust/badge.svg?branch=master) [![crates.io](https://img.shields.io/crates/v/thin-vec.svg)](https://crates.io/crates/thin-vec) [![](https://docs.rs/thin-vec/badge.svg)](https://docs.rs/thin-vec)
+
+# thin-vec
+
+ThinVec is a Vec that stores its length and capacity inline, making it take up
+less space.
+
+Currently this crate mostly exists to facilitate Gecko (Firefox) FFI, but it
+works perfectly fine as a native rust library as well.
diff --git a/vendor/thin-vec/src/lib.rs b/vendor/thin-vec/src/lib.rs
new file mode 100644
index 000000000..60785150e
--- /dev/null
+++ b/vendor/thin-vec/src/lib.rs
@@ -0,0 +1,3117 @@
+//! ThinVec is exactly the same as Vec, except that it stores its `len` and `capacity` in the buffer
+//! it allocates.
+//!
+//! This makes the memory footprint of ThinVecs lower; notably in cases where space is reserved for
+//! a non-existence ThinVec<T>. So `Vec<ThinVec<T>>` and `Option<ThinVec<T>>::None` will waste less
+//! space. Being pointer-sized also means it can be passed/stored in registers.
+//!
+//! Of course, any actually constructed ThinVec will theoretically have a bigger allocation, but
+//! the fuzzy nature of allocators means that might not actually be the case.
+//!
+//! Properties of Vec that are preserved:
+//! * `ThinVec::new()` doesn't allocate (it points to a statically allocated singleton)
+//! * reallocation can be done in place
+//! * `size_of::<ThinVec<T>>()` == `size_of::<Option<ThinVec<T>>>()`
+//!
+//! Properties of Vec that aren't preserved:
+//! * `ThinVec<T>` can't ever be zero-cost roundtripped to a `Box<[T]>`, `String`, or `*mut T`
+//! * `from_raw_parts` doesn't exist
+//! * ThinVec currently doesn't bother to not-allocate for Zero Sized Types (e.g. `ThinVec<()>`),
+//! but it could be done if someone cared enough to implement it.
+//!
+//!
+//!
+//! # Gecko FFI
+//!
+//! If you enable the gecko-ffi feature, ThinVec will verbatim bridge with the nsTArray type in
+//! Gecko (Firefox). That is, ThinVec and nsTArray have identical layouts *but not ABIs*,
+//! so nsTArrays/ThinVecs an be natively manipulated by C++ and Rust, and ownership can be
+//! transferred across the FFI boundary (**IF YOU ARE CAREFUL, SEE BELOW!!**).
+//!
+//! While this feature is handy, it is also inherently dangerous to use because Rust and C++ do not
+//! know about each other. Specifically, this can be an issue with non-POD types (types which
+//! have destructors, move constructors, or are `!Copy`).
+//!
+//! ## Do Not Pass By Value
+//!
+//! The biggest thing to keep in mind is that **FFI functions cannot pass ThinVec/nsTArray
+//! by-value**. That is, these are busted APIs:
+//!
+//! ```rust,ignore
+//! // BAD WRONG
+//! extern fn process_data(data: ThinVec<u32>) { ... }
+//! // BAD WRONG
+//! extern fn get_data() -> ThinVec<u32> { ... }
+//! ```
+//!
+//! You must instead pass by-reference:
+//!
+//! ```rust
+//! # use thin_vec::*;
+//! # use std::mem;
+//!
+//! // Read-only access, ok!
+//! extern fn process_data(data: &ThinVec<u32>) {
+//! for val in data {
+//! println!("{}", val);
+//! }
+//! }
+//!
+//! // Replace with empty instance to take ownership, ok!
+//! extern fn consume_data(data: &mut ThinVec<u32>) {
+//! let owned = mem::replace(data, ThinVec::new());
+//! mem::drop(owned);
+//! }
+//!
+//! // Mutate input, ok!
+//! extern fn add_data(dataset: &mut ThinVec<u32>) {
+//! dataset.push(37);
+//! dataset.push(12);
+//! }
+//!
+//! // Return via out-param, usually ok!
+//! //
+//! // WARNING: output must be initialized! (Empty nsTArrays are free, so just do it!)
+//! extern fn get_data(output: &mut ThinVec<u32>) {
+//! *output = thin_vec![1, 2, 3, 4, 5];
+//! }
+//! ```
+//!
+//! Ignorable Explanation For Those Who Really Want To Know Why:
+//!
+//! > The fundamental issue is that Rust and C++ can't currently communicate about destructors, and
+//! > the semantics of C++ require destructors of function arguments to be run when the function
+//! > returns. Whether the callee or caller is responsible for this is also platform-specific, so
+//! > trying to hack around it manually would be messy.
+//! >
+//! > Also a type having a destructor changes its C++ ABI, because that type must actually exist
+//! > in memory (unlike a trivial struct, which is often passed in registers). We don't currently
+//! > have a way to communicate to Rust that this is happening, so even if we worked out the
+//! > destructor issue with say, MaybeUninit, it would still be a non-starter without some RFCs
+//! > to add explicit rustc support.
+//! >
+//! > Realistically, the best answer here is to have a "heavier" bindgen that can secretly
+//! > generate FFI glue so we can pass things "by value" and have it generate by-reference code
+//! > behind our back (like the cxx crate does). This would muddy up debugging/searchfox though.
+//!
+//! ## Types Should Be Trivially Relocatable
+//!
+//! Types in Rust are always trivially relocatable (unless suitably borrowed/[pinned][]/hidden).
+//! This means all Rust types are legal to relocate with a bitwise copy, you cannot provide
+//! copy or move constructors to execute when this happens, and the old location won't have its
+//! destructor run. This will cause problems for types which have a significant location
+//! (types that intrusively point into themselves or have their location registered with a service).
+//!
+//! While relocations are generally predictable if you're very careful, **you should avoid using
+//! types with significant locations with Rust FFI**.
+//!
+//! Specifically, ThinVec will trivially relocate its contents whenever it needs to reallocate its
+//! buffer to change its capacity. This is the default reallocation strategy for nsTArray, and is
+//! suitable for the vast majority of types. Just be aware of this limitation!
+//!
+//! ## Auto Arrays Are Dangerous
+//!
+//! ThinVec has *some* support for handling auto arrays which store their buffer on the stack,
+//! but this isn't well tested.
+//!
+//! Regardless of how much support we provide, Rust won't be aware of the buffer's limited lifetime,
+//! so standard auto array safety caveats apply about returning/storing them! ThinVec won't ever
+//! produce an auto array on its own, so this is only an issue for transferring an nsTArray into
+//! Rust.
+//!
+//! ## Other Issues
+//!
+//! Standard FFI caveats also apply:
+//!
+//! * Rust is more strict about POD types being initialized (use MaybeUninit if you must)
+//! * `ThinVec<T>` has no idea if the C++ version of `T` has move/copy/assign/delete overloads
+//! * `nsTArray<T>` has no idea if the Rust version of `T` has a Drop/Clone impl
+//! * C++ can do all sorts of unsound things that Rust can't catch
+//! * C++ and Rust don't agree on how zero-sized/empty types should be handled
+//!
+//! The gecko-ffi feature will not work if you aren't linking with code that has nsTArray
+//! defined. Specifically, we must share the symbol for nsTArray's empty singleton. You will get
+//! linking errors if that isn't defined.
+//!
+//! The gecko-ffi feature also limits ThinVec to the legacy behaviors of nsTArray. Most notably,
+//! nsTArray has a maximum capacity of i32::MAX (~2.1 billion items). Probably not an issue.
+//! Probably.
+//!
+//! [pinned]: https://doc.rust-lang.org/std/pin/index.html
+
+#![allow(clippy::comparison_chain, clippy::missing_safety_doc)]
+
+use std::alloc::*;
+use std::borrow::*;
+use std::cmp::*;
+use std::hash::*;
+use std::iter::FromIterator;
+use std::marker::PhantomData;
+use std::ops::Bound;
+use std::ops::{Deref, DerefMut, RangeBounds};
+use std::ptr::NonNull;
+use std::slice::IterMut;
+use std::{fmt, io, mem, ptr, slice};
+
+use impl_details::*;
+
+// modules: a simple way to cfg a whole bunch of impl details at once
+
+#[cfg(not(feature = "gecko-ffi"))]
+mod impl_details {
+ pub type SizeType = usize;
+ pub const MAX_CAP: usize = !0;
+
+ #[inline(always)]
+ pub fn assert_size(x: usize) -> SizeType {
+ x
+ }
+}
+
+#[cfg(feature = "gecko-ffi")]
+mod impl_details {
+ // Support for briding a gecko nsTArray verbatim into a ThinVec.
+ //
+ // ThinVec can't see copy/move/delete implementations
+ // from C++
+ //
+ // The actual layout of an nsTArray is:
+ //
+ // ```cpp
+ // struct {
+ // uint32_t mLength;
+ // uint32_t mCapacity: 31;
+ // uint32_t mIsAutoArray: 1;
+ // }
+ // ```
+ //
+ // Rust doesn't natively support bit-fields, so we manually mask
+ // and shift the bit. When the "auto" bit is set, the header and buffer
+ // are actually on the stack, meaning the ThinVec pointer-to-header
+ // is essentially an "owned borrow", and therefore dangerous to handle.
+ // There are no safety guards for this situation.
+ //
+ // On little-endian platforms, the auto bit will be the high-bit of
+ // our capacity u32. On big-endian platforms, it will be the low bit.
+ // Hence we need some platform-specific CFGs for the necessary masking/shifting.
+ //
+ // ThinVec won't ever construct an auto array. They only happen when
+ // bridging from C++. This means we don't need to ever set/preserve the bit.
+ // We just need to be able to read and handle it if it happens to be there.
+ //
+ // Handling the auto bit mostly just means not freeing/reallocating the buffer.
+
+ pub type SizeType = u32;
+
+ pub const MAX_CAP: usize = i32::max_value() as usize;
+
+ // Little endian: the auto bit is the high bit, and the capacity is
+ // verbatim. So we just need to mask off the high bit. Note that
+ // this masking is unnecessary when packing, because assert_size
+ // guards against the high bit being set.
+ #[cfg(target_endian = "little")]
+ pub fn pack_capacity(cap: SizeType) -> SizeType {
+ cap as SizeType
+ }
+ #[cfg(target_endian = "little")]
+ pub fn unpack_capacity(cap: SizeType) -> usize {
+ (cap as usize) & !(1 << 31)
+ }
+ #[cfg(target_endian = "little")]
+ pub fn is_auto(cap: SizeType) -> bool {
+ (cap & (1 << 31)) != 0
+ }
+
+ // Big endian: the auto bit is the low bit, and the capacity is
+ // shifted up one bit. Masking out the auto bit is unnecessary,
+ // as rust shifts always shift in 0's for unsigned integers.
+ #[cfg(target_endian = "big")]
+ pub fn pack_capacity(cap: SizeType) -> SizeType {
+ (cap as SizeType) << 1
+ }
+ #[cfg(target_endian = "big")]
+ pub fn unpack_capacity(cap: SizeType) -> usize {
+ (cap >> 1) as usize
+ }
+ #[cfg(target_endian = "big")]
+ pub fn is_auto(cap: SizeType) -> bool {
+ (cap & 1) != 0
+ }
+
+ #[inline]
+ pub fn assert_size(x: usize) -> SizeType {
+ if x > MAX_CAP as usize {
+ panic!("nsTArray size may not exceed the capacity of a 32-bit sized int");
+ }
+ x as SizeType
+ }
+}
+
+// The header of a ThinVec.
+//
+// The _cap can be a bitfield, so use accessors to avoid trouble.
+//
+// In "real" gecko-ffi mode, the empty singleton will be aligned
+// to 8 by gecko. But in tests we have to provide the singleton
+// ourselves, and Rust makes it hard to "just" align a static.
+// To avoid messing around with a wrapper type around the
+// singleton *just* for tests, we just force all headers to be
+// aligned to 8 in this weird "zombie" gecko mode.
+//
+// This shouldn't affect runtime layout (padding), but it will
+// result in us asking the allocator to needlessly overalign
+// non-empty ThinVecs containing align < 8 types in
+// zombie-mode, but not in "real" geck-ffi mode. Minor.
+#[cfg_attr(all(feature = "gecko-ffi", any(test, miri)), repr(align(8)))]
+#[repr(C)]
+struct Header {
+ _len: SizeType,
+ _cap: SizeType,
+}
+
+impl Header {
+ fn len(&self) -> usize {
+ self._len as usize
+ }
+
+ fn set_len(&mut self, len: usize) {
+ self._len = assert_size(len);
+ }
+}
+
+#[cfg(feature = "gecko-ffi")]
+impl Header {
+ fn cap(&self) -> usize {
+ unpack_capacity(self._cap)
+ }
+
+ fn set_cap(&mut self, cap: usize) {
+ // debug check that our packing is working
+ debug_assert_eq!(unpack_capacity(pack_capacity(cap as SizeType)), cap);
+ // FIXME: this assert is busted because it reads uninit memory
+ // debug_assert!(!self.uses_stack_allocated_buffer());
+
+ // NOTE: this always stores a cleared auto bit, because set_cap
+ // is only invoked by Rust, and Rust doesn't create auto arrays.
+ self._cap = pack_capacity(assert_size(cap));
+ }
+
+ fn uses_stack_allocated_buffer(&self) -> bool {
+ is_auto(self._cap)
+ }
+}
+
+#[cfg(not(feature = "gecko-ffi"))]
+impl Header {
+ fn cap(&self) -> usize {
+ self._cap as usize
+ }
+
+ fn set_cap(&mut self, cap: usize) {
+ self._cap = assert_size(cap);
+ }
+}
+
+/// Singleton that all empty collections share.
+/// Note: can't store non-zero ZSTs, we allocate in that case. We could
+/// optimize everything to not do that (basically, make ptr == len and branch
+/// on size == 0 in every method), but it's a bunch of work for something that
+/// doesn't matter much.
+#[cfg(any(not(feature = "gecko-ffi"), test, miri))]
+static EMPTY_HEADER: Header = Header { _len: 0, _cap: 0 };
+
+#[cfg(all(feature = "gecko-ffi", not(test), not(miri)))]
+extern "C" {
+ #[link_name = "sEmptyTArrayHeader"]
+ static EMPTY_HEADER: Header;
+}
+
+// TODO: overflow checks everywhere
+
+// Utils for computing layouts of allocations
+
+fn alloc_size<T>(cap: usize) -> usize {
+ // Compute "real" header size with pointer math
+ let header_size = mem::size_of::<Header>();
+ let elem_size = mem::size_of::<T>();
+ let padding = padding::<T>();
+
+ // TODO: care about isize::MAX overflow?
+ let data_size = elem_size.checked_mul(cap).expect("capacity overflow");
+
+ data_size
+ .checked_add(header_size + padding)
+ .expect("capacity overflow")
+}
+
+fn padding<T>() -> usize {
+ let alloc_align = alloc_align::<T>();
+ let header_size = mem::size_of::<Header>();
+
+ if alloc_align > header_size {
+ if cfg!(feature = "gecko-ffi") {
+ panic!(
+ "nsTArray does not handle alignment above > {} correctly",
+ header_size
+ );
+ }
+ alloc_align - header_size
+ } else {
+ 0
+ }
+}
+
+fn alloc_align<T>() -> usize {
+ max(mem::align_of::<T>(), mem::align_of::<Header>())
+}
+
+fn layout<T>(cap: usize) -> Layout {
+ unsafe { Layout::from_size_align_unchecked(alloc_size::<T>(cap), alloc_align::<T>()) }
+}
+
+fn header_with_capacity<T>(cap: usize) -> NonNull<Header> {
+ debug_assert!(cap > 0);
+ unsafe {
+ let layout = layout::<T>(cap);
+ let header = alloc(layout) as *mut Header;
+
+ if header.is_null() {
+ handle_alloc_error(layout)
+ }
+
+ // "Infinite" capacity for zero-sized types:
+ (*header).set_cap(if mem::size_of::<T>() == 0 {
+ MAX_CAP
+ } else {
+ cap
+ });
+ (*header).set_len(0);
+
+ NonNull::new_unchecked(header)
+ }
+}
+
+/// See the crate's top level documentation for a description of this type.
+#[repr(C)]
+pub struct ThinVec<T> {
+ ptr: NonNull<Header>,
+ boo: PhantomData<T>,
+}
+
+unsafe impl<T: Sync> Sync for ThinVec<T> {}
+unsafe impl<T: Send> Send for ThinVec<T> {}
+
+/// Creates a `ThinVec` containing the arguments.
+///
+/// ```
+/// #[macro_use] extern crate thin_vec;
+///
+/// fn main() {
+/// let v = thin_vec![1, 2, 3];
+/// assert_eq!(v.len(), 3);
+/// assert_eq!(v[0], 1);
+/// assert_eq!(v[1], 2);
+/// assert_eq!(v[2], 3);
+///
+/// let v = thin_vec![1; 3];
+/// assert_eq!(v, [1, 1, 1]);
+/// }
+/// ```
+#[macro_export]
+macro_rules! thin_vec {
+ (@UNIT $($t:tt)*) => (());
+
+ ($elem:expr; $n:expr) => ({
+ let mut vec = $crate::ThinVec::new();
+ vec.resize($n, $elem);
+ vec
+ });
+ () => {$crate::ThinVec::new()};
+ ($($x:expr),*) => ({
+ let len = [$(thin_vec!(@UNIT $x)),*].len();
+ let mut vec = $crate::ThinVec::with_capacity(len);
+ $(vec.push($x);)*
+ vec
+ });
+ ($($x:expr,)*) => (thin_vec![$($x),*]);
+}
+
+impl<T> ThinVec<T> {
+ pub fn new() -> ThinVec<T> {
+ ThinVec::with_capacity(0)
+ }
+
+ pub fn with_capacity(cap: usize) -> ThinVec<T> {
+ // `padding` contains ~static assertions against types that are
+ // incompatible with the current feature flags. We also call it to
+ // invoke these assertions when getting a pointer to the `ThinVec`
+ // contents, but since we also get a pointer to the contents in the
+ // `Drop` impl, trippng an assertion along that code path causes a
+ // double panic. We duplicate the assertion here so that it is
+ // testable,
+ let _ = padding::<T>();
+
+ if cap == 0 {
+ unsafe {
+ ThinVec {
+ ptr: NonNull::new_unchecked(&EMPTY_HEADER as *const Header as *mut Header),
+ boo: PhantomData,
+ }
+ }
+ } else {
+ ThinVec {
+ ptr: header_with_capacity::<T>(cap),
+ boo: PhantomData,
+ }
+ }
+ }
+
+ // Accessor conveniences
+
+ fn ptr(&self) -> *mut Header {
+ self.ptr.as_ptr()
+ }
+ fn header(&self) -> &Header {
+ unsafe { self.ptr.as_ref() }
+ }
+ fn data_raw(&self) -> *mut T {
+ // `padding` contains ~static assertions against types that are
+ // incompatible with the current feature flags. Even if we don't
+ // care about its result, we should always call it before getting
+ // a data pointer to guard against invalid types!
+ let padding = padding::<T>();
+
+ // Although we ensure the data array is aligned when we allocate,
+ // we can't do that with the empty singleton. So when it might not
+ // be properly aligned, we substitute in the NonNull::dangling
+ // which *is* aligned.
+ //
+ // To minimize dynamic branches on `cap` for all accesses
+ // to the data, we include this guard which should only involve
+ // compile-time constants. Ideally this should result in the branch
+ // only be included for types with excessive alignment.
+ let empty_header_is_aligned = if cfg!(feature = "gecko-ffi") {
+ // in gecko-ffi mode `padding` will ensure this under
+ // the assumption that the header has size 8 and the
+ // static empty singleton is aligned to 8.
+ true
+ } else {
+ // In non-gecko-ffi mode, the empty singleton is just
+ // naturally aligned to the Header. If the Header is at
+ // least as aligned as T *and* the padding would have
+ // been 0, then one-past-the-end of the empty singleton
+ // *is* a valid data pointer and we can remove the
+ // `dangling` special case.
+ mem::align_of::<Header>() >= mem::align_of::<T>() && padding == 0
+ };
+
+ unsafe {
+ if !empty_header_is_aligned && self.header().cap() == 0 {
+ NonNull::dangling().as_ptr()
+ } else {
+ // This could technically result in overflow, but padding
+ // would have to be absurdly large for this to occur.
+ let header_size = mem::size_of::<Header>();
+ let ptr = self.ptr.as_ptr() as *mut u8;
+ ptr.add(header_size + padding) as *mut T
+ }
+ }
+ }
+
+ // This is unsafe when the header is EMPTY_HEADER.
+ unsafe fn header_mut(&mut self) -> &mut Header {
+ &mut *self.ptr()
+ }
+
+ pub fn len(&self) -> usize {
+ self.header().len()
+ }
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+ pub fn capacity(&self) -> usize {
+ self.header().cap()
+ }
+
+ pub unsafe fn set_len(&mut self, len: usize) {
+ if self.is_singleton() {
+ // A prerequisite of `Vec::set_len` is that `new_len` must be
+ // less than or equal to capacity(). The same applies here.
+ assert!(len == 0, "invalid set_len({}) on empty ThinVec", len);
+ } else {
+ self.header_mut().set_len(len)
+ }
+ }
+
+ // For internal use only, when setting the length and it's known to be the non-singleton.
+ unsafe fn set_len_non_singleton(&mut self, len: usize) {
+ self.header_mut().set_len(len)
+ }
+
+ pub fn push(&mut self, val: T) {
+ let old_len = self.len();
+ if old_len == self.capacity() {
+ self.reserve(1);
+ }
+ unsafe {
+ ptr::write(self.data_raw().add(old_len), val);
+ self.set_len_non_singleton(old_len + 1);
+ }
+ }
+
+ pub fn pop(&mut self) -> Option<T> {
+ let old_len = self.len();
+ if old_len == 0 {
+ return None;
+ }
+
+ unsafe {
+ self.set_len_non_singleton(old_len - 1);
+ Some(ptr::read(self.data_raw().add(old_len - 1)))
+ }
+ }
+
+ pub fn insert(&mut self, idx: usize, elem: T) {
+ let old_len = self.len();
+
+ assert!(idx <= old_len, "Index out of bounds");
+ if old_len == self.capacity() {
+ self.reserve(1);
+ }
+ unsafe {
+ let ptr = self.data_raw();
+ ptr::copy(ptr.add(idx), ptr.add(idx + 1), old_len - idx);
+ ptr::write(ptr.add(idx), elem);
+ self.set_len_non_singleton(old_len + 1);
+ }
+ }
+
+ pub fn remove(&mut self, idx: usize) -> T {
+ let old_len = self.len();
+
+ assert!(idx < old_len, "Index out of bounds");
+
+ unsafe {
+ self.set_len_non_singleton(old_len - 1);
+ let ptr = self.data_raw();
+ let val = ptr::read(self.data_raw().add(idx));
+ ptr::copy(ptr.add(idx + 1), ptr.add(idx), old_len - idx - 1);
+ val
+ }
+ }
+
+ pub fn swap_remove(&mut self, idx: usize) -> T {
+ let old_len = self.len();
+
+ assert!(idx < old_len, "Index out of bounds");
+
+ unsafe {
+ let ptr = self.data_raw();
+ ptr::swap(ptr.add(idx), ptr.add(old_len - 1));
+ self.set_len_non_singleton(old_len - 1);
+ ptr::read(ptr.add(old_len - 1))
+ }
+ }
+
+ pub fn truncate(&mut self, len: usize) {
+ unsafe {
+ // drop any extra elements
+ while len < self.len() {
+ // decrement len before the drop_in_place(), so a panic on Drop
+ // doesn't re-drop the just-failed value.
+ let new_len = self.len() - 1;
+ self.set_len_non_singleton(new_len);
+ ptr::drop_in_place(self.data_raw().add(new_len));
+ }
+ }
+ }
+
+ pub fn clear(&mut self) {
+ unsafe {
+ ptr::drop_in_place(&mut self[..]);
+ self.set_len(0); // could be the singleton
+ }
+ }
+
+ pub fn as_slice(&self) -> &[T] {
+ unsafe { slice::from_raw_parts(self.data_raw(), self.len()) }
+ }
+
+ pub fn as_mut_slice(&mut self) -> &mut [T] {
+ unsafe { slice::from_raw_parts_mut(self.data_raw(), self.len()) }
+ }
+
+ /// Reserve capacity for at least `additional` more elements to be inserted.
+ ///
+ /// May reserve more space than requested, to avoid frequent reallocations.
+ ///
+ /// Panics if the new capacity overflows `usize`.
+ ///
+ /// Re-allocates only if `self.capacity() < self.len() + additional`.
+ #[cfg(not(feature = "gecko-ffi"))]
+ pub fn reserve(&mut self, additional: usize) {
+ let len = self.len();
+ let old_cap = self.capacity();
+ let min_cap = len.checked_add(additional).expect("capacity overflow");
+ if min_cap <= old_cap {
+ return;
+ }
+ // Ensure the new capacity is at least double, to guarantee exponential growth.
+ let double_cap = if old_cap == 0 {
+ // skip to 4 because tiny ThinVecs are dumb; but not if that would cause overflow
+ if mem::size_of::<T>() > (!0) / 8 {
+ 1
+ } else {
+ 4
+ }
+ } else {
+ old_cap.saturating_mul(2)
+ };
+ let new_cap = max(min_cap, double_cap);
+ unsafe {
+ self.reallocate(new_cap);
+ }
+ }
+
+ /// Reserve capacity for at least `additional` more elements to be inserted.
+ ///
+ /// This method mimics the growth algorithm used by the C++ implementation
+ /// of nsTArray.
+ #[cfg(feature = "gecko-ffi")]
+ pub fn reserve(&mut self, additional: usize) {
+ let elem_size = mem::size_of::<T>();
+
+ let len = self.len();
+ let old_cap = self.capacity();
+ let min_cap = len.checked_add(additional).expect("capacity overflow");
+ if min_cap <= old_cap {
+ return;
+ }
+
+ // The growth logic can't handle zero-sized types, so we have to exit
+ // early here.
+ if elem_size == 0 {
+ unsafe {
+ self.reallocate(min_cap);
+ }
+ return;
+ }
+
+ let min_cap_bytes = assert_size(min_cap)
+ .checked_mul(assert_size(elem_size))
+ .and_then(|x| x.checked_add(assert_size(mem::size_of::<Header>())))
+ .unwrap();
+
+ // Perform some checked arithmetic to ensure all of the numbers we
+ // compute will end up in range.
+ let will_fit = min_cap_bytes.checked_mul(2).is_some();
+ if !will_fit {
+ panic!("Exceeded maximum nsTArray size");
+ }
+
+ const SLOW_GROWTH_THRESHOLD: usize = 8 * 1024 * 1024;
+
+ let bytes = if min_cap > SLOW_GROWTH_THRESHOLD {
+ // Grow by a minimum of 1.125x
+ let old_cap_bytes = old_cap * elem_size + mem::size_of::<Header>();
+ let min_growth = old_cap_bytes + (old_cap_bytes >> 3);
+ let growth = max(min_growth, min_cap_bytes as usize);
+
+ // Round up to the next megabyte.
+ const MB: usize = 1 << 20;
+ MB * ((growth + MB - 1) / MB)
+ } else {
+ // Try to allocate backing buffers in powers of two.
+ min_cap_bytes.next_power_of_two() as usize
+ };
+
+ let cap = (bytes - std::mem::size_of::<Header>()) / elem_size;
+ unsafe {
+ self.reallocate(cap);
+ }
+ }
+
+ /// Reserves the minimum capacity for `additional` more elements to be inserted.
+ ///
+ /// Panics if the new capacity overflows `usize`.
+ ///
+ /// Re-allocates only if `self.capacity() < self.len() + additional`.
+ pub fn reserve_exact(&mut self, additional: usize) {
+ let new_cap = self
+ .len()
+ .checked_add(additional)
+ .expect("capacity overflow");
+ let old_cap = self.capacity();
+ if new_cap > old_cap {
+ unsafe {
+ self.reallocate(new_cap);
+ }
+ }
+ }
+
+ pub fn shrink_to_fit(&mut self) {
+ let old_cap = self.capacity();
+ let new_cap = self.len();
+ if new_cap < old_cap {
+ if new_cap == 0 {
+ *self = ThinVec::new();
+ } else {
+ unsafe {
+ self.reallocate(new_cap);
+ }
+ }
+ }
+ }
+
+ /// Retains only the elements specified by the predicate.
+ ///
+ /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+ /// This method operates in place and preserves the order of the retained
+ /// elements.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[macro_use] extern crate thin_vec;
+ /// # fn main() {
+ /// let mut vec = thin_vec![1, 2, 3, 4];
+ /// vec.retain(|&x| x%2 == 0);
+ /// assert_eq!(vec, [2, 4]);
+ /// # }
+ /// ```
+ pub fn retain<F>(&mut self, mut f: F)
+ where
+ F: FnMut(&T) -> bool,
+ {
+ let len = self.len();
+ let mut del = 0;
+ {
+ let v = &mut self[..];
+
+ for i in 0..len {
+ if !f(&v[i]) {
+ del += 1;
+ } else if del > 0 {
+ v.swap(i - del, i);
+ }
+ }
+ }
+ if del > 0 {
+ self.truncate(len - del);
+ }
+ }
+
+ /// Removes consecutive elements in the vector that resolve to the same key.
+ ///
+ /// If the vector is sorted, this removes all duplicates.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[macro_use] extern crate thin_vec;
+ /// # fn main() {
+ /// let mut vec = thin_vec![10, 20, 21, 30, 20];
+ ///
+ /// vec.dedup_by_key(|i| *i / 10);
+ ///
+ /// assert_eq!(vec, [10, 20, 30, 20]);
+ /// # }
+ /// ```
+ pub fn dedup_by_key<F, K>(&mut self, mut key: F)
+ where
+ F: FnMut(&mut T) -> K,
+ K: PartialEq<K>,
+ {
+ self.dedup_by(|a, b| key(a) == key(b))
+ }
+
+ /// Removes consecutive elements in the vector according to a predicate.
+ ///
+ /// The `same_bucket` function is passed references to two elements from the vector, and
+ /// returns `true` if the elements compare equal, or `false` if they do not. Only the first
+ /// of adjacent equal items is kept.
+ ///
+ /// If the vector is sorted, this removes all duplicates.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[macro_use] extern crate thin_vec;
+ /// # fn main() {
+ /// let mut vec = thin_vec!["foo", "bar", "Bar", "baz", "bar"];
+ ///
+ /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+ ///
+ /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+ /// # }
+ /// ```
+ #[allow(clippy::swap_ptr_to_ref)]
+ pub fn dedup_by<F>(&mut self, mut same_bucket: F)
+ where
+ F: FnMut(&mut T, &mut T) -> bool,
+ {
+ // See the comments in `Vec::dedup` for a detailed explanation of this code.
+ unsafe {
+ let ln = self.len();
+ if ln <= 1 {
+ return;
+ }
+
+ // Avoid bounds checks by using raw pointers.
+ let p = self.as_mut_ptr();
+ let mut r: usize = 1;
+ let mut w: usize = 1;
+
+ while r < ln {
+ let p_r = p.add(r);
+ let p_wm1 = p.add(w - 1);
+ if !same_bucket(&mut *p_r, &mut *p_wm1) {
+ if r != w {
+ let p_w = p_wm1.add(1);
+ mem::swap(&mut *p_r, &mut *p_w);
+ }
+ w += 1;
+ }
+ r += 1;
+ }
+
+ self.truncate(w);
+ }
+ }
+
+ pub fn split_off(&mut self, at: usize) -> ThinVec<T> {
+ let old_len = self.len();
+ let new_vec_len = old_len - at;
+
+ assert!(at <= old_len, "Index out of bounds");
+
+ unsafe {
+ let mut new_vec = ThinVec::with_capacity(new_vec_len);
+
+ ptr::copy_nonoverlapping(self.data_raw().add(at), new_vec.data_raw(), new_vec_len);
+
+ new_vec.set_len(new_vec_len); // could be the singleton
+ self.set_len(at); // could be the singleton
+
+ new_vec
+ }
+ }
+
+ pub fn append(&mut self, other: &mut ThinVec<T>) {
+ self.extend(other.drain(..))
+ }
+
+ pub fn drain<R>(&mut self, range: R) -> Drain<'_, T>
+ where
+ R: RangeBounds<usize>,
+ {
+ let len = self.len();
+ let start = match range.start_bound() {
+ Bound::Included(&n) => n,
+ Bound::Excluded(&n) => n + 1,
+ Bound::Unbounded => 0,
+ };
+ let end = match range.end_bound() {
+ Bound::Included(&n) => n + 1,
+ Bound::Excluded(&n) => n,
+ Bound::Unbounded => len,
+ };
+ assert!(start <= end);
+ assert!(end <= len);
+
+ unsafe {
+ // Set our length to the start bound
+ self.set_len(start); // could be the singleton
+
+ let iter =
+ slice::from_raw_parts_mut(self.data_raw().add(start), end - start).iter_mut();
+
+ Drain {
+ iter,
+ vec: self,
+ end,
+ tail: len - end,
+ }
+ }
+ }
+
+ /// Resize the buffer and update its capacity, without changing the length.
+ /// Unsafe because it can cause length to be greater than capacity.
+ unsafe fn reallocate(&mut self, new_cap: usize) {
+ debug_assert!(new_cap > 0);
+ if self.has_allocation() {
+ let old_cap = self.capacity();
+ let ptr = realloc(
+ self.ptr() as *mut u8,
+ layout::<T>(old_cap),
+ alloc_size::<T>(new_cap),
+ ) as *mut Header;
+
+ if ptr.is_null() {
+ handle_alloc_error(layout::<T>(new_cap))
+ }
+ (*ptr).set_cap(new_cap);
+ self.ptr = NonNull::new_unchecked(ptr);
+ } else {
+ let new_header = header_with_capacity::<T>(new_cap);
+
+ // If we get here and have a non-zero len, then we must be handling
+ // a gecko auto array, and we have items in a stack buffer. We shouldn't
+ // free it, but we should memcopy the contents out of it and mark it as empty.
+ //
+ // T is assumed to be trivially relocatable, as this is ~required
+ // for Rust compatibility anyway. Furthermore, we assume C++ won't try
+ // to unconditionally destroy the contents of the stack allocated buffer
+ // (i.e. it's obfuscated behind a union).
+ //
+ // In effect, we are partially reimplementing the auto array move constructor
+ // by leaving behind a valid empty instance.
+ let len = self.len();
+ if cfg!(feature = "gecko-ffi") && len > 0 {
+ new_header
+ .as_ptr()
+ .add(1)
+ .cast::<T>()
+ .copy_from_nonoverlapping(self.data_raw(), len);
+ self.set_len_non_singleton(0);
+ }
+
+ self.ptr = new_header;
+ }
+ }
+
+ #[cfg(feature = "gecko-ffi")]
+ #[inline]
+ fn is_singleton(&self) -> bool {
+ unsafe { self.ptr.as_ptr() as *const Header == &EMPTY_HEADER }
+ }
+
+ #[cfg(not(feature = "gecko-ffi"))]
+ #[inline]
+ fn is_singleton(&self) -> bool {
+ self.ptr.as_ptr() as *const Header == &EMPTY_HEADER
+ }
+
+ #[cfg(feature = "gecko-ffi")]
+ #[inline]
+ fn has_allocation(&self) -> bool {
+ unsafe { !self.is_singleton() && !self.ptr.as_ref().uses_stack_allocated_buffer() }
+ }
+
+ #[cfg(not(feature = "gecko-ffi"))]
+ #[inline]
+ fn has_allocation(&self) -> bool {
+ !self.is_singleton()
+ }
+}
+
+impl<T: Clone> ThinVec<T> {
+ /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
+ ///
+ /// If `new_len` is greater than `len()`, the `Vec` is extended by the
+ /// difference, with each additional slot filled with `value`.
+ /// If `new_len` is less than `len()`, the `Vec` is simply truncated.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[macro_use] extern crate thin_vec;
+ /// # fn main() {
+ /// let mut vec = thin_vec!["hello"];
+ /// vec.resize(3, "world");
+ /// assert_eq!(vec, ["hello", "world", "world"]);
+ ///
+ /// let mut vec = thin_vec![1, 2, 3, 4];
+ /// vec.resize(2, 0);
+ /// assert_eq!(vec, [1, 2]);
+ /// # }
+ /// ```
+ pub fn resize(&mut self, new_len: usize, value: T) {
+ let old_len = self.len();
+
+ if new_len > old_len {
+ let additional = new_len - old_len;
+ self.reserve(additional);
+ for _ in 1..additional {
+ self.push(value.clone());
+ }
+ // We can write the last element directly without cloning needlessly
+ if additional > 0 {
+ self.push(value);
+ }
+ } else if new_len < old_len {
+ self.truncate(new_len);
+ }
+ }
+
+ pub fn extend_from_slice(&mut self, other: &[T]) {
+ self.extend(other.iter().cloned())
+ }
+}
+
+impl<T: PartialEq> ThinVec<T> {
+ /// Removes consecutive repeated elements in the vector.
+ ///
+ /// If the vector is sorted, this removes all duplicates.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #[macro_use] extern crate thin_vec;
+ /// # fn main() {
+ /// let mut vec = thin_vec![1, 2, 2, 3, 2];
+ ///
+ /// vec.dedup();
+ ///
+ /// assert_eq!(vec, [1, 2, 3, 2]);
+ /// # }
+ /// ```
+ pub fn dedup(&mut self) {
+ self.dedup_by(|a, b| a == b)
+ }
+}
+
+impl<T> Drop for ThinVec<T> {
+ #[inline]
+ fn drop(&mut self) {
+ #[cold]
+ #[inline(never)]
+ fn drop_non_singleton<T>(this: &mut ThinVec<T>) {
+ unsafe {
+ ptr::drop_in_place(&mut this[..]);
+
+ #[cfg(feature = "gecko-ffi")]
+ if this.ptr.as_ref().uses_stack_allocated_buffer() {
+ return;
+ }
+
+ dealloc(this.ptr() as *mut u8, layout::<T>(this.capacity()))
+ }
+ }
+
+ if !self.is_singleton() {
+ drop_non_singleton(self);
+ }
+ }
+}
+
+impl<T> Deref for ThinVec<T> {
+ type Target = [T];
+
+ fn deref(&self) -> &[T] {
+ self.as_slice()
+ }
+}
+
+impl<T> DerefMut for ThinVec<T> {
+ fn deref_mut(&mut self) -> &mut [T] {
+ self.as_mut_slice()
+ }
+}
+
+impl<T> Borrow<[T]> for ThinVec<T> {
+ fn borrow(&self) -> &[T] {
+ self.as_slice()
+ }
+}
+
+impl<T> BorrowMut<[T]> for ThinVec<T> {
+ fn borrow_mut(&mut self) -> &mut [T] {
+ self.as_mut_slice()
+ }
+}
+
+impl<T> AsRef<[T]> for ThinVec<T> {
+ fn as_ref(&self) -> &[T] {
+ self.as_slice()
+ }
+}
+
+impl<T> Extend<T> for ThinVec<T> {
+ #[inline]
+ fn extend<I>(&mut self, iter: I)
+ where
+ I: IntoIterator<Item = T>,
+ {
+ let iter = iter.into_iter();
+ let hint = iter.size_hint().0;
+ if hint > 0 {
+ self.reserve(hint);
+ }
+ for x in iter {
+ self.push(x);
+ }
+ }
+}
+
+impl<T: fmt::Debug> fmt::Debug for ThinVec<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&**self, f)
+ }
+}
+
+impl<T> Hash for ThinVec<T>
+where
+ T: Hash,
+{
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self[..].hash(state);
+ }
+}
+
+impl<T> PartialOrd for ThinVec<T>
+where
+ T: PartialOrd,
+{
+ #[inline]
+ fn partial_cmp(&self, other: &ThinVec<T>) -> Option<Ordering> {
+ self[..].partial_cmp(&other[..])
+ }
+}
+
+impl<T> Ord for ThinVec<T>
+where
+ T: Ord,
+{
+ #[inline]
+ fn cmp(&self, other: &ThinVec<T>) -> Ordering {
+ self[..].cmp(&other[..])
+ }
+}
+
+impl<A, B> PartialEq<ThinVec<B>> for ThinVec<A>
+where
+ A: PartialEq<B>,
+{
+ #[inline]
+ fn eq(&self, other: &ThinVec<B>) -> bool {
+ self[..] == other[..]
+ }
+}
+
+impl<A, B> PartialEq<Vec<B>> for ThinVec<A>
+where
+ A: PartialEq<B>,
+{
+ #[inline]
+ fn eq(&self, other: &Vec<B>) -> bool {
+ self[..] == other[..]
+ }
+}
+
+impl<A, B> PartialEq<[B]> for ThinVec<A>
+where
+ A: PartialEq<B>,
+{
+ #[inline]
+ fn eq(&self, other: &[B]) -> bool {
+ self[..] == other[..]
+ }
+}
+
+impl<'a, A, B> PartialEq<&'a [B]> for ThinVec<A>
+where
+ A: PartialEq<B>,
+{
+ #[inline]
+ fn eq(&self, other: &&'a [B]) -> bool {
+ self[..] == other[..]
+ }
+}
+
+// Serde impls based on
+// https://github.com/bluss/arrayvec/blob/67ec907a98c0f40c4b76066fed3c1af59d35cf6a/src/arrayvec.rs#L1222-L1267
+#[cfg(feature = "serde")]
+impl<T: serde::Serialize> serde::Serialize for ThinVec<T> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ serializer.collect_seq(self.as_slice())
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for ThinVec<T> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ use serde::de::{SeqAccess, Visitor};
+ use serde::Deserialize;
+
+ struct ThinVecVisitor<T>(PhantomData<T>);
+
+ impl<'de, T: Deserialize<'de>> Visitor<'de> for ThinVecVisitor<T> {
+ type Value = ThinVec<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "a sequence")
+ }
+
+ fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error>
+ where
+ SA: SeqAccess<'de>,
+ {
+ // Same policy as
+ // https://github.com/serde-rs/serde/blob/ce0844b9ecc32377b5e4545d759d385a8c46bc6a/serde/src/private/size_hint.rs#L13
+ let initial_capacity = seq.size_hint().unwrap_or_default().min(4096);
+ let mut values = ThinVec::<T>::with_capacity(initial_capacity);
+
+ while let Some(value) = seq.next_element()? {
+ values.push(value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ deserializer.deserialize_seq(ThinVecVisitor::<T>(PhantomData))
+ }
+}
+
+macro_rules! array_impls {
+ ($($N:expr)*) => {$(
+ impl<A, B> PartialEq<[B; $N]> for ThinVec<A> where A: PartialEq<B> {
+ #[inline]
+ fn eq(&self, other: &[B; $N]) -> bool { self[..] == other[..] }
+ }
+
+ impl<'a, A, B> PartialEq<&'a [B; $N]> for ThinVec<A> where A: PartialEq<B> {
+ #[inline]
+ fn eq(&self, other: &&'a [B; $N]) -> bool { self[..] == other[..] }
+ }
+ )*}
+}
+
+array_impls! {
+ 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 32
+}
+
+impl<T> Eq for ThinVec<T> where T: Eq {}
+
+impl<T> IntoIterator for ThinVec<T> {
+ type Item = T;
+ type IntoIter = IntoIter<T>;
+
+ fn into_iter(self) -> IntoIter<T> {
+ IntoIter {
+ vec: self,
+ start: 0,
+ }
+ }
+}
+
+impl<'a, T> IntoIterator for &'a ThinVec<T> {
+ type Item = &'a T;
+ type IntoIter = slice::Iter<'a, T>;
+
+ fn into_iter(self) -> slice::Iter<'a, T> {
+ self.iter()
+ }
+}
+
+impl<'a, T> IntoIterator for &'a mut ThinVec<T> {
+ type Item = &'a mut T;
+ type IntoIter = slice::IterMut<'a, T>;
+
+ fn into_iter(self) -> slice::IterMut<'a, T> {
+ self.iter_mut()
+ }
+}
+
+impl<T> Clone for ThinVec<T>
+where
+ T: Clone,
+{
+ #[inline]
+ fn clone(&self) -> ThinVec<T> {
+ #[cold]
+ #[inline(never)]
+ fn clone_non_singleton<T: Clone>(this: &ThinVec<T>) -> ThinVec<T> {
+ let len = this.len();
+ let mut new_vec = ThinVec::<T>::with_capacity(len);
+ let mut data_raw = new_vec.data_raw();
+ for x in this.iter() {
+ unsafe {
+ ptr::write(data_raw, x.clone());
+ data_raw = data_raw.add(1);
+ }
+ }
+ unsafe {
+ // `this` is not the singleton, but `new_vec` will be if
+ // `this` is empty.
+ new_vec.set_len(len); // could be the singleton
+ }
+ new_vec
+ }
+
+ if self.is_singleton() {
+ ThinVec::new()
+ } else {
+ clone_non_singleton(self)
+ }
+ }
+}
+
+impl<T> Default for ThinVec<T> {
+ fn default() -> ThinVec<T> {
+ ThinVec::new()
+ }
+}
+
+impl<T> FromIterator<T> for ThinVec<T> {
+ #[inline]
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> ThinVec<T> {
+ let mut vec = ThinVec::new();
+ vec.extend(iter.into_iter());
+ vec
+ }
+}
+
+pub struct IntoIter<T> {
+ vec: ThinVec<T>,
+ start: usize,
+}
+
+pub struct Drain<'a, T> {
+ iter: IterMut<'a, T>,
+ vec: *mut ThinVec<T>,
+ end: usize,
+ tail: usize,
+}
+
+impl<T> Iterator for IntoIter<T> {
+ type Item = T;
+ fn next(&mut self) -> Option<T> {
+ if self.start == self.vec.len() {
+ None
+ } else {
+ unsafe {
+ let old_start = self.start;
+ self.start += 1;
+ Some(ptr::read(self.vec.data_raw().add(old_start)))
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.vec.len() - self.start;
+ (len, Some(len))
+ }
+}
+
+impl<T> DoubleEndedIterator for IntoIter<T> {
+ fn next_back(&mut self) -> Option<T> {
+ if self.start == self.vec.len() {
+ None
+ } else {
+ // FIXME?: extra bounds check
+ self.vec.pop()
+ }
+ }
+}
+
+impl<T> Drop for IntoIter<T> {
+ #[inline]
+ fn drop(&mut self) {
+ #[cold]
+ #[inline(never)]
+ fn drop_non_singleton<T>(this: &mut IntoIter<T>) {
+ unsafe {
+ let mut vec = mem::replace(&mut this.vec, ThinVec::new());
+ ptr::drop_in_place(&mut vec[this.start..]);
+ vec.set_len_non_singleton(0)
+ }
+ }
+
+ if !self.vec.is_singleton() {
+ drop_non_singleton(self);
+ }
+ }
+}
+
+impl<'a, T> Iterator for Drain<'a, T> {
+ type Item = T;
+ fn next(&mut self) -> Option<T> {
+ self.iter.next().map(|x| unsafe { ptr::read(x) })
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
+ fn next_back(&mut self) -> Option<T> {
+ self.iter.next_back().map(|x| unsafe { ptr::read(x) })
+ }
+}
+
+impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
+
+impl<'a, T> Drop for Drain<'a, T> {
+ fn drop(&mut self) {
+ // Consume the rest of the iterator.
+ for _ in self.by_ref() {}
+
+ // Move the tail over the drained items, and update the length.
+ unsafe {
+ let vec = &mut *self.vec;
+
+ // Don't mutate the empty singleton!
+ if !vec.is_singleton() {
+ let old_len = vec.len();
+ let start = vec.data_raw().add(old_len);
+ let end = vec.data_raw().add(self.end);
+ ptr::copy(end, start, self.tail);
+ vec.set_len_non_singleton(old_len + self.tail);
+ }
+ }
+ }
+}
+
+/// Write is implemented for `ThinVec<u8>` by appending to the vector.
+/// The vector will grow as needed.
+/// This implementation is identical to the one for `Vec<u8>`.
+impl io::Write for ThinVec<u8> {
+ #[inline]
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.extend_from_slice(buf);
+ Ok(buf.len())
+ }
+
+ #[inline]
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ self.extend_from_slice(buf);
+ Ok(())
+ }
+
+ #[inline]
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
+ }
+}
+
+// TODO: a million Index impls
+
+#[cfg(test)]
+mod tests {
+ use super::{ThinVec, MAX_CAP};
+
+ #[test]
+ fn test_size_of() {
+ use std::mem::size_of;
+ assert_eq!(size_of::<ThinVec<u8>>(), size_of::<&u8>());
+
+ assert_eq!(size_of::<Option<ThinVec<u8>>>(), size_of::<&u8>());
+ }
+
+ #[test]
+ fn test_drop_empty() {
+ ThinVec::<u8>::new();
+ }
+
+ #[test]
+ fn test_data_ptr_alignment() {
+ let v = ThinVec::<u16>::new();
+ assert!(v.data_raw() as usize % 2 == 0);
+
+ let v = ThinVec::<u32>::new();
+ assert!(v.data_raw() as usize % 4 == 0);
+
+ let v = ThinVec::<u64>::new();
+ assert!(v.data_raw() as usize % 8 == 0);
+ }
+
+ #[test]
+ #[cfg_attr(feature = "gecko-ffi", should_panic)]
+ fn test_overaligned_type_is_rejected_for_gecko_ffi_mode() {
+ #[repr(align(16))]
+ struct Align16(u8);
+
+ let v = ThinVec::<Align16>::new();
+ assert!(v.data_raw() as usize % 16 == 0);
+ }
+
+ #[test]
+ fn test_partial_eq() {
+ assert_eq!(thin_vec![0], thin_vec![0]);
+ assert_ne!(thin_vec![0], thin_vec![1]);
+ assert_eq!(thin_vec![1, 2, 3], vec![1, 2, 3]);
+ }
+
+ #[test]
+ fn test_alloc() {
+ let mut v = ThinVec::new();
+ assert!(!v.has_allocation());
+ v.push(1);
+ assert!(v.has_allocation());
+ v.pop();
+ assert!(v.has_allocation());
+ v.shrink_to_fit();
+ assert!(!v.has_allocation());
+ v.reserve(64);
+ assert!(v.has_allocation());
+ v = ThinVec::with_capacity(64);
+ assert!(v.has_allocation());
+ v = ThinVec::with_capacity(0);
+ assert!(!v.has_allocation());
+ }
+
+ #[test]
+ fn test_drain_items() {
+ let mut vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![];
+ for i in vec.drain(..) {
+ vec2.push(i);
+ }
+ assert_eq!(vec, []);
+ assert_eq!(vec2, [1, 2, 3]);
+ }
+
+ #[test]
+ fn test_drain_items_reverse() {
+ let mut vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![];
+ for i in vec.drain(..).rev() {
+ vec2.push(i);
+ }
+ assert_eq!(vec, []);
+ assert_eq!(vec2, [3, 2, 1]);
+ }
+
+ #[test]
+ fn test_drain_items_zero_sized() {
+ let mut vec = thin_vec![(), (), ()];
+ let mut vec2 = thin_vec![];
+ for i in vec.drain(..) {
+ vec2.push(i);
+ }
+ assert_eq!(vec, []);
+ assert_eq!(vec2, [(), (), ()]);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_drain_out_of_bounds() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ v.drain(5..6);
+ }
+
+ #[test]
+ fn test_drain_range() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ for _ in v.drain(4..) {}
+ assert_eq!(v, &[1, 2, 3, 4]);
+
+ let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
+ for _ in v.drain(1..4) {}
+ assert_eq!(v, &[1.to_string(), 5.to_string()]);
+
+ let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
+ for _ in v.drain(1..4).rev() {}
+ assert_eq!(v, &[1.to_string(), 5.to_string()]);
+
+ let mut v: ThinVec<_> = thin_vec![(); 5];
+ for _ in v.drain(1..4).rev() {}
+ assert_eq!(v, &[(), ()]);
+ }
+
+ #[test]
+ fn test_drain_max_vec_size() {
+ let mut v = ThinVec::<()>::with_capacity(MAX_CAP);
+ unsafe {
+ v.set_len(MAX_CAP);
+ }
+ for _ in v.drain(MAX_CAP - 1..) {}
+ assert_eq!(v.len(), MAX_CAP - 1);
+ }
+
+ #[test]
+ fn test_clear() {
+ let mut v = ThinVec::<i32>::new();
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+
+ v.clear();
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+
+ v.push(1);
+ v.push(2);
+ assert_eq!(v.len(), 2);
+ assert!(v.capacity() >= 2);
+ assert_eq!(&v[..], &[1, 2]);
+
+ v.clear();
+ assert_eq!(v.len(), 0);
+ assert!(v.capacity() >= 2);
+ assert_eq!(&v[..], &[]);
+
+ v.push(3);
+ v.push(4);
+ assert_eq!(v.len(), 2);
+ assert!(v.capacity() >= 2);
+ assert_eq!(&v[..], &[3, 4]);
+
+ v.clear();
+ assert_eq!(v.len(), 0);
+ assert!(v.capacity() >= 2);
+ assert_eq!(&v[..], &[]);
+
+ v.clear();
+ assert_eq!(v.len(), 0);
+ assert!(v.capacity() >= 2);
+ assert_eq!(&v[..], &[]);
+ }
+
+ #[test]
+ fn test_empty_singleton_torture() {
+ {
+ let mut v = ThinVec::<i32>::new();
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert!(v.is_empty());
+ assert_eq!(&v[..], &[]);
+ assert_eq!(&mut v[..], &mut []);
+
+ assert_eq!(v.pop(), None);
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let v = ThinVec::<i32>::new();
+ assert_eq!(v.into_iter().count(), 0);
+
+ let v = ThinVec::<i32>::new();
+ for _ in v.into_iter() {
+ unreachable!();
+ }
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ assert_eq!(v.drain(..).len(), 0);
+
+ for _ in v.drain(..) {
+ unreachable!()
+ }
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.truncate(1);
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+
+ v.truncate(0);
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.shrink_to_fit();
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ let new = v.split_off(0);
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+
+ assert_eq!(new.len(), 0);
+ assert_eq!(new.capacity(), 0);
+ assert_eq!(&new[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ let mut other = ThinVec::<i32>::new();
+ v.append(&mut other);
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+
+ assert_eq!(other.len(), 0);
+ assert_eq!(other.capacity(), 0);
+ assert_eq!(&other[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.reserve(0);
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.reserve_exact(0);
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.reserve(0);
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let v = ThinVec::<i32>::with_capacity(0);
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let v = ThinVec::<i32>::default();
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.retain(|_| unreachable!());
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.dedup_by_key(|x| *x);
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let mut v = ThinVec::<i32>::new();
+ v.dedup_by(|_, _| unreachable!());
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+
+ {
+ let v = ThinVec::<i32>::new();
+ let v = v.clone();
+
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ assert_eq!(&v[..], &[]);
+ }
+ }
+
+ #[test]
+ fn test_clone() {
+ let mut v = ThinVec::<i32>::new();
+ assert!(v.is_singleton());
+ v.push(0);
+ v.pop();
+ assert!(!v.is_singleton());
+
+ let v2 = v.clone();
+ assert!(v2.is_singleton());
+ }
+}
+
+#[cfg(test)]
+mod std_tests {
+ #![allow(clippy::reversed_empty_ranges)]
+
+ use super::*;
+ use std::mem::size_of;
+ use std::usize;
+
+ struct DropCounter<'a> {
+ count: &'a mut u32,
+ }
+
+ impl<'a> Drop for DropCounter<'a> {
+ fn drop(&mut self) {
+ *self.count += 1;
+ }
+ }
+
+ #[test]
+ fn test_small_vec_struct() {
+ assert!(size_of::<ThinVec<u8>>() == size_of::<usize>());
+ }
+
+ #[test]
+ fn test_double_drop() {
+ struct TwoVec<T> {
+ x: ThinVec<T>,
+ y: ThinVec<T>,
+ }
+
+ let (mut count_x, mut count_y) = (0, 0);
+ {
+ let mut tv = TwoVec {
+ x: ThinVec::new(),
+ y: ThinVec::new(),
+ };
+ tv.x.push(DropCounter {
+ count: &mut count_x,
+ });
+ tv.y.push(DropCounter {
+ count: &mut count_y,
+ });
+
+ // If ThinVec had a drop flag, here is where it would be zeroed.
+ // Instead, it should rely on its internal state to prevent
+ // doing anything significant when dropped multiple times.
+ drop(tv.x);
+
+ // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
+ }
+
+ assert_eq!(count_x, 1);
+ assert_eq!(count_y, 1);
+ }
+
+ #[test]
+ fn test_reserve() {
+ let mut v = ThinVec::new();
+ assert_eq!(v.capacity(), 0);
+
+ v.reserve(2);
+ assert!(v.capacity() >= 2);
+
+ for i in 0..16 {
+ v.push(i);
+ }
+
+ assert!(v.capacity() >= 16);
+ v.reserve(16);
+ assert!(v.capacity() >= 32);
+
+ v.push(16);
+
+ v.reserve(16);
+ assert!(v.capacity() >= 33)
+ }
+
+ #[test]
+ fn test_extend() {
+ let mut v = ThinVec::<usize>::new();
+ let mut w = ThinVec::new();
+ v.extend(w.clone());
+ assert_eq!(v, &[]);
+
+ v.extend(0..3);
+ for i in 0..3 {
+ w.push(i)
+ }
+
+ assert_eq!(v, w);
+
+ v.extend(3..10);
+ for i in 3..10 {
+ w.push(i)
+ }
+
+ assert_eq!(v, w);
+
+ v.extend(w.clone()); // specializes to `append`
+ assert!(v.iter().eq(w.iter().chain(w.iter())));
+
+ // Zero sized types
+ #[derive(PartialEq, Debug)]
+ struct Foo;
+
+ let mut a = ThinVec::new();
+ let b = thin_vec![Foo, Foo];
+
+ a.extend(b);
+ assert_eq!(a, &[Foo, Foo]);
+
+ // Double drop
+ let mut count_x = 0;
+ {
+ let mut x = ThinVec::new();
+ let y = thin_vec![DropCounter {
+ count: &mut count_x
+ }];
+ x.extend(y);
+ }
+
+ assert_eq!(count_x, 1);
+ }
+
+ /* TODO: implement extend for Iter<&Copy>
+ #[test]
+ fn test_extend_ref() {
+ let mut v = thin_vec![1, 2];
+ v.extend(&[3, 4, 5]);
+
+ assert_eq!(v.len(), 5);
+ assert_eq!(v, [1, 2, 3, 4, 5]);
+
+ let w = thin_vec![6, 7];
+ v.extend(&w);
+
+ assert_eq!(v.len(), 7);
+ assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
+ }
+ */
+
+ #[test]
+ fn test_slice_from_mut() {
+ let mut values = thin_vec![1, 2, 3, 4, 5];
+ {
+ let slice = &mut values[2..];
+ assert!(slice == [3, 4, 5]);
+ for p in slice {
+ *p += 2;
+ }
+ }
+
+ assert!(values == [1, 2, 5, 6, 7]);
+ }
+
+ #[test]
+ fn test_slice_to_mut() {
+ let mut values = thin_vec![1, 2, 3, 4, 5];
+ {
+ let slice = &mut values[..2];
+ assert!(slice == [1, 2]);
+ for p in slice {
+ *p += 1;
+ }
+ }
+
+ assert!(values == [2, 3, 3, 4, 5]);
+ }
+
+ #[test]
+ fn test_split_at_mut() {
+ let mut values = thin_vec![1, 2, 3, 4, 5];
+ {
+ let (left, right) = values.split_at_mut(2);
+ {
+ let left: &[_] = left;
+ assert!(left[..left.len()] == [1, 2]);
+ }
+ for p in left {
+ *p += 1;
+ }
+
+ {
+ let right: &[_] = right;
+ assert!(right[..right.len()] == [3, 4, 5]);
+ }
+ for p in right {
+ *p += 2;
+ }
+ }
+
+ assert_eq!(values, [2, 3, 5, 6, 7]);
+ }
+
+ #[test]
+ fn test_clone() {
+ let v: ThinVec<i32> = thin_vec![];
+ let w = thin_vec![1, 2, 3];
+
+ assert_eq!(v, v.clone());
+
+ let z = w.clone();
+ assert_eq!(w, z);
+ // they should be disjoint in memory.
+ assert!(w.as_ptr() != z.as_ptr())
+ }
+
+ #[test]
+ fn test_clone_from() {
+ let mut v = thin_vec![];
+ let three: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(3)];
+ let two: ThinVec<Box<_>> = thin_vec![Box::new(4), Box::new(5)];
+ // zero, long
+ v.clone_from(&three);
+ assert_eq!(v, three);
+
+ // equal
+ v.clone_from(&three);
+ assert_eq!(v, three);
+
+ // long, short
+ v.clone_from(&two);
+ assert_eq!(v, two);
+
+ // short, long
+ v.clone_from(&three);
+ assert_eq!(v, three)
+ }
+
+ #[test]
+ fn test_retain() {
+ let mut vec = thin_vec![1, 2, 3, 4];
+ vec.retain(|&x| x % 2 == 0);
+ assert_eq!(vec, [2, 4]);
+ }
+
+ #[test]
+ fn test_dedup() {
+ fn case(a: ThinVec<i32>, b: ThinVec<i32>) {
+ let mut v = a;
+ v.dedup();
+ assert_eq!(v, b);
+ }
+ case(thin_vec![], thin_vec![]);
+ case(thin_vec![1], thin_vec![1]);
+ case(thin_vec![1, 1], thin_vec![1]);
+ case(thin_vec![1, 2, 3], thin_vec![1, 2, 3]);
+ case(thin_vec![1, 1, 2, 3], thin_vec![1, 2, 3]);
+ case(thin_vec![1, 2, 2, 3], thin_vec![1, 2, 3]);
+ case(thin_vec![1, 2, 3, 3], thin_vec![1, 2, 3]);
+ case(thin_vec![1, 1, 2, 2, 2, 3, 3], thin_vec![1, 2, 3]);
+ }
+
+ #[test]
+ fn test_dedup_by_key() {
+ fn case(a: ThinVec<i32>, b: ThinVec<i32>) {
+ let mut v = a;
+ v.dedup_by_key(|i| *i / 10);
+ assert_eq!(v, b);
+ }
+ case(thin_vec![], thin_vec![]);
+ case(thin_vec![10], thin_vec![10]);
+ case(thin_vec![10, 11], thin_vec![10]);
+ case(thin_vec![10, 20, 30], thin_vec![10, 20, 30]);
+ case(thin_vec![10, 11, 20, 30], thin_vec![10, 20, 30]);
+ case(thin_vec![10, 20, 21, 30], thin_vec![10, 20, 30]);
+ case(thin_vec![10, 20, 30, 31], thin_vec![10, 20, 30]);
+ case(thin_vec![10, 11, 20, 21, 22, 30, 31], thin_vec![10, 20, 30]);
+ }
+
+ #[test]
+ fn test_dedup_by() {
+ let mut vec = thin_vec!["foo", "bar", "Bar", "baz", "bar"];
+ vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+ assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
+ let mut vec = thin_vec![("foo", 1), ("foo", 2), ("bar", 3), ("bar", 4), ("bar", 5)];
+ vec.dedup_by(|a, b| {
+ a.0 == b.0 && {
+ b.1 += a.1;
+ true
+ }
+ });
+
+ assert_eq!(vec, [("foo", 3), ("bar", 12)]);
+ }
+
+ #[test]
+ fn test_dedup_unique() {
+ let mut v0: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(1), Box::new(2), Box::new(3)];
+ v0.dedup();
+ let mut v1: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(2), Box::new(3)];
+ v1.dedup();
+ let mut v2: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(3), Box::new(3)];
+ v2.dedup();
+ // If the boxed pointers were leaked or otherwise misused, valgrind
+ // and/or rt should raise errors.
+ }
+
+ #[test]
+ fn zero_sized_values() {
+ let mut v = ThinVec::new();
+ assert_eq!(v.len(), 0);
+ v.push(());
+ assert_eq!(v.len(), 1);
+ v.push(());
+ assert_eq!(v.len(), 2);
+ assert_eq!(v.pop(), Some(()));
+ assert_eq!(v.pop(), Some(()));
+ assert_eq!(v.pop(), None);
+
+ assert_eq!(v.iter().count(), 0);
+ v.push(());
+ assert_eq!(v.iter().count(), 1);
+ v.push(());
+ assert_eq!(v.iter().count(), 2);
+
+ for &() in &v {}
+
+ assert_eq!(v.iter_mut().count(), 2);
+ v.push(());
+ assert_eq!(v.iter_mut().count(), 3);
+ v.push(());
+ assert_eq!(v.iter_mut().count(), 4);
+
+ for &mut () in &mut v {}
+ unsafe {
+ v.set_len(0);
+ }
+ assert_eq!(v.iter_mut().count(), 0);
+ }
+
+ #[test]
+ fn test_partition() {
+ assert_eq!(
+ thin_vec![].into_iter().partition(|x: &i32| *x < 3),
+ (thin_vec![], thin_vec![])
+ );
+ assert_eq!(
+ thin_vec![1, 2, 3].into_iter().partition(|x| *x < 4),
+ (thin_vec![1, 2, 3], thin_vec![])
+ );
+ assert_eq!(
+ thin_vec![1, 2, 3].into_iter().partition(|x| *x < 2),
+ (thin_vec![1], thin_vec![2, 3])
+ );
+ assert_eq!(
+ thin_vec![1, 2, 3].into_iter().partition(|x| *x < 0),
+ (thin_vec![], thin_vec![1, 2, 3])
+ );
+ }
+
+ #[test]
+ fn test_zip_unzip() {
+ let z1 = thin_vec![(1, 4), (2, 5), (3, 6)];
+
+ let (left, right): (ThinVec<_>, ThinVec<_>) = z1.iter().cloned().unzip();
+
+ assert_eq!((1, 4), (left[0], right[0]));
+ assert_eq!((2, 5), (left[1], right[1]));
+ assert_eq!((3, 6), (left[2], right[2]));
+ }
+
+ #[test]
+ fn test_vec_truncate_drop() {
+ static mut DROPS: u32 = 0;
+ struct Elem(i32);
+ impl Drop for Elem {
+ fn drop(&mut self) {
+ unsafe {
+ DROPS += 1;
+ }
+ }
+ }
+
+ let mut v = thin_vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
+ assert_eq!(unsafe { DROPS }, 0);
+ v.truncate(3);
+ assert_eq!(unsafe { DROPS }, 2);
+ v.truncate(0);
+ assert_eq!(unsafe { DROPS }, 5);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_vec_truncate_fail() {
+ struct BadElem(i32);
+ impl Drop for BadElem {
+ fn drop(&mut self) {
+ let BadElem(ref mut x) = *self;
+ if *x == 0xbadbeef {
+ panic!("BadElem panic: 0xbadbeef")
+ }
+ }
+ }
+
+ let mut v = thin_vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
+ v.truncate(0);
+ }
+
+ #[test]
+ fn test_index() {
+ let vec = thin_vec![1, 2, 3];
+ assert!(vec[1] == 2);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_index_out_of_bounds() {
+ let vec = thin_vec![1, 2, 3];
+ let _ = vec[3];
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_slice_out_of_bounds_1() {
+ let x = thin_vec![1, 2, 3, 4, 5];
+ let _ = &x[!0..];
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_slice_out_of_bounds_2() {
+ let x = thin_vec![1, 2, 3, 4, 5];
+ let _ = &x[..6];
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_slice_out_of_bounds_3() {
+ let x = thin_vec![1, 2, 3, 4, 5];
+ let _ = &x[!0..4];
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_slice_out_of_bounds_4() {
+ let x = thin_vec![1, 2, 3, 4, 5];
+ let _ = &x[1..6];
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_slice_out_of_bounds_5() {
+ let x = thin_vec![1, 2, 3, 4, 5];
+ let _ = &x[3..2];
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_swap_remove_empty() {
+ let mut vec = ThinVec::<i32>::new();
+ vec.swap_remove(0);
+ }
+
+ #[test]
+ fn test_move_items() {
+ let vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![];
+ for i in vec {
+ vec2.push(i);
+ }
+ assert_eq!(vec2, [1, 2, 3]);
+ }
+
+ #[test]
+ fn test_move_items_reverse() {
+ let vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![];
+ for i in vec.into_iter().rev() {
+ vec2.push(i);
+ }
+ assert_eq!(vec2, [3, 2, 1]);
+ }
+
+ #[test]
+ fn test_move_items_zero_sized() {
+ let vec = thin_vec![(), (), ()];
+ let mut vec2 = thin_vec![];
+ for i in vec {
+ vec2.push(i);
+ }
+ assert_eq!(vec2, [(), (), ()]);
+ }
+
+ #[test]
+ fn test_drain_items() {
+ let mut vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![];
+ for i in vec.drain(..) {
+ vec2.push(i);
+ }
+ assert_eq!(vec, []);
+ assert_eq!(vec2, [1, 2, 3]);
+ }
+
+ #[test]
+ fn test_drain_items_reverse() {
+ let mut vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![];
+ for i in vec.drain(..).rev() {
+ vec2.push(i);
+ }
+ assert_eq!(vec, []);
+ assert_eq!(vec2, [3, 2, 1]);
+ }
+
+ #[test]
+ fn test_drain_items_zero_sized() {
+ let mut vec = thin_vec![(), (), ()];
+ let mut vec2 = thin_vec![];
+ for i in vec.drain(..) {
+ vec2.push(i);
+ }
+ assert_eq!(vec, []);
+ assert_eq!(vec2, [(), (), ()]);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_drain_out_of_bounds() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ v.drain(5..6);
+ }
+
+ #[test]
+ fn test_drain_range() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ for _ in v.drain(4..) {}
+ assert_eq!(v, &[1, 2, 3, 4]);
+
+ let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
+ for _ in v.drain(1..4) {}
+ assert_eq!(v, &[1.to_string(), 5.to_string()]);
+
+ let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
+ for _ in v.drain(1..4).rev() {}
+ assert_eq!(v, &[1.to_string(), 5.to_string()]);
+
+ let mut v: ThinVec<_> = thin_vec![(); 5];
+ for _ in v.drain(1..4).rev() {}
+ assert_eq!(v, &[(), ()]);
+ }
+
+ #[test]
+ fn test_drain_inclusive_range() {
+ let mut v = thin_vec!['a', 'b', 'c', 'd', 'e'];
+ for _ in v.drain(1..=3) {}
+ assert_eq!(v, &['a', 'e']);
+
+ let mut v: ThinVec<_> = (0..=5).map(|x| x.to_string()).collect();
+ for _ in v.drain(1..=5) {}
+ assert_eq!(v, &["0".to_string()]);
+
+ let mut v: ThinVec<String> = (0..=5).map(|x| x.to_string()).collect();
+ for _ in v.drain(0..=5) {}
+ assert_eq!(v, ThinVec::<String>::new());
+
+ let mut v: ThinVec<_> = (0..=5).map(|x| x.to_string()).collect();
+ for _ in v.drain(0..=3) {}
+ assert_eq!(v, &["4".to_string(), "5".to_string()]);
+
+ let mut v: ThinVec<_> = (0..=1).map(|x| x.to_string()).collect();
+ for _ in v.drain(..=0) {}
+ assert_eq!(v, &["1".to_string()]);
+ }
+
+ #[test]
+ #[cfg(not(feature = "gecko-ffi"))]
+ fn test_drain_max_vec_size() {
+ let mut v = ThinVec::<()>::with_capacity(usize::max_value());
+ unsafe {
+ v.set_len(usize::max_value());
+ }
+ for _ in v.drain(usize::max_value() - 1..) {}
+ assert_eq!(v.len(), usize::max_value() - 1);
+
+ let mut v = ThinVec::<()>::with_capacity(usize::max_value());
+ unsafe {
+ v.set_len(usize::max_value());
+ }
+ for _ in v.drain(usize::max_value() - 1..=usize::max_value() - 1) {}
+ assert_eq!(v.len(), usize::max_value() - 1);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_drain_inclusive_out_of_bounds() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ v.drain(5..=5);
+ }
+
+ /* TODO: implement splice?
+ #[test]
+ fn test_splice() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ let a = [10, 11, 12];
+ v.splice(2..4, a.iter().cloned());
+ assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
+ v.splice(1..3, Some(20));
+ assert_eq!(v, &[1, 20, 11, 12, 5]);
+ }
+
+ #[test]
+ fn test_splice_inclusive_range() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ let a = [10, 11, 12];
+ let t1: ThinVec<_> = v.splice(2..=3, a.iter().cloned()).collect();
+ assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
+ assert_eq!(t1, &[3, 4]);
+ let t2: ThinVec<_> = v.splice(1..=2, Some(20)).collect();
+ assert_eq!(v, &[1, 20, 11, 12, 5]);
+ assert_eq!(t2, &[2, 10]);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_splice_out_of_bounds() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ let a = [10, 11, 12];
+ v.splice(5..6, a.iter().cloned());
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_splice_inclusive_out_of_bounds() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ let a = [10, 11, 12];
+ v.splice(5..=5, a.iter().cloned());
+ }
+
+ #[test]
+ fn test_splice_items_zero_sized() {
+ let mut vec = thin_vec![(), (), ()];
+ let vec2 = thin_vec![];
+ let t: ThinVec<_> = vec.splice(1..2, vec2.iter().cloned()).collect();
+ assert_eq!(vec, &[(), ()]);
+ assert_eq!(t, &[()]);
+ }
+
+ #[test]
+ fn test_splice_unbounded() {
+ let mut vec = thin_vec![1, 2, 3, 4, 5];
+ let t: ThinVec<_> = vec.splice(.., None).collect();
+ assert_eq!(vec, &[]);
+ assert_eq!(t, &[1, 2, 3, 4, 5]);
+ }
+
+ #[test]
+ fn test_splice_forget() {
+ let mut v = thin_vec![1, 2, 3, 4, 5];
+ let a = [10, 11, 12];
+ ::std::mem::forget(v.splice(2..4, a.iter().cloned()));
+ assert_eq!(v, &[1, 2]);
+ }
+ */
+
+ /* probs won't ever impl this
+ #[test]
+ fn test_into_boxed_slice() {
+ let xs = thin_vec![1, 2, 3];
+ let ys = xs.into_boxed_slice();
+ assert_eq!(&*ys, [1, 2, 3]);
+ }
+ */
+
+ #[test]
+ fn test_append() {
+ let mut vec = thin_vec![1, 2, 3];
+ let mut vec2 = thin_vec![4, 5, 6];
+ vec.append(&mut vec2);
+ assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(vec2, []);
+ }
+
+ #[test]
+ fn test_split_off() {
+ let mut vec = thin_vec![1, 2, 3, 4, 5, 6];
+ let vec2 = vec.split_off(4);
+ assert_eq!(vec, [1, 2, 3, 4]);
+ assert_eq!(vec2, [5, 6]);
+ }
+
+ /* TODO: implement into_iter methods?
+ #[test]
+ fn test_into_iter_as_slice() {
+ let vec = thin_vec!['a', 'b', 'c'];
+ let mut into_iter = vec.into_iter();
+ assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
+ let _ = into_iter.next().unwrap();
+ assert_eq!(into_iter.as_slice(), &['b', 'c']);
+ let _ = into_iter.next().unwrap();
+ let _ = into_iter.next().unwrap();
+ assert_eq!(into_iter.as_slice(), &[]);
+ }
+
+ #[test]
+ fn test_into_iter_as_mut_slice() {
+ let vec = thin_vec!['a', 'b', 'c'];
+ let mut into_iter = vec.into_iter();
+ assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
+ into_iter.as_mut_slice()[0] = 'x';
+ into_iter.as_mut_slice()[1] = 'y';
+ assert_eq!(into_iter.next().unwrap(), 'x');
+ assert_eq!(into_iter.as_slice(), &['y', 'c']);
+ }
+
+ #[test]
+ fn test_into_iter_debug() {
+ let vec = thin_vec!['a', 'b', 'c'];
+ let into_iter = vec.into_iter();
+ let debug = format!("{:?}", into_iter);
+ assert_eq!(debug, "IntoIter(['a', 'b', 'c'])");
+ }
+
+ #[test]
+ fn test_into_iter_count() {
+ assert_eq!(thin_vec![1, 2, 3].into_iter().count(), 3);
+ }
+
+ #[test]
+ fn test_into_iter_clone() {
+ fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
+ let v: ThinVec<i32> = it.collect();
+ assert_eq!(&v[..], slice);
+ }
+ let mut it = thin_vec![1, 2, 3].into_iter();
+ iter_equal(it.clone(), &[1, 2, 3]);
+ assert_eq!(it.next(), Some(1));
+ let mut it = it.rev();
+ iter_equal(it.clone(), &[3, 2]);
+ assert_eq!(it.next(), Some(3));
+ iter_equal(it.clone(), &[2]);
+ assert_eq!(it.next(), Some(2));
+ iter_equal(it.clone(), &[]);
+ assert_eq!(it.next(), None);
+ }
+ */
+
+ /* TODO: implement CoW interop?
+ #[test]
+ fn test_cow_from() {
+ let borrowed: &[_] = &["borrowed", "(slice)"];
+ let owned = thin_vec!["owned", "(vec)"];
+ match (Cow::from(owned.clone()), Cow::from(borrowed)) {
+ (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
+ _ => panic!("invalid `Cow::from`"),
+ }
+ }
+
+ #[test]
+ fn test_from_cow() {
+ let borrowed: &[_] = &["borrowed", "(slice)"];
+ let owned = thin_vec!["owned", "(vec)"];
+ assert_eq!(ThinVec::from(Cow::Borrowed(borrowed)), thin_vec!["borrowed", "(slice)"]);
+ assert_eq!(ThinVec::from(Cow::Owned(owned)), thin_vec!["owned", "(vec)"]);
+ }
+ */
+
+ /* TODO: make drain covariant
+ #[allow(dead_code)]
+ fn assert_covariance() {
+ fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+ d
+ }
+ fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
+ i
+ }
+ }
+ */
+
+ /* TODO: specialize vec.into_iter().collect::<ThinVec<_>>();
+ #[test]
+ fn from_into_inner() {
+ let vec = thin_vec![1, 2, 3];
+ let ptr = vec.as_ptr();
+ let vec = vec.into_iter().collect::<ThinVec<_>>();
+ assert_eq!(vec, [1, 2, 3]);
+ assert_eq!(vec.as_ptr(), ptr);
+
+ let ptr = &vec[1] as *const _;
+ let mut it = vec.into_iter();
+ it.next().unwrap();
+ let vec = it.collect::<ThinVec<_>>();
+ assert_eq!(vec, [2, 3]);
+ assert!(ptr != vec.as_ptr());
+ }
+ */
+
+ /* TODO: implement higher than 16 alignment
+ #[test]
+ fn overaligned_allocations() {
+ #[repr(align(256))]
+ struct Foo(usize);
+ let mut v = thin_vec![Foo(273)];
+ for i in 0..0x1000 {
+ v.reserve_exact(i);
+ assert!(v[0].0 == 273);
+ assert!(v.as_ptr() as usize & 0xff == 0);
+ v.shrink_to_fit();
+ assert!(v[0].0 == 273);
+ assert!(v.as_ptr() as usize & 0xff == 0);
+ }
+ }
+ */
+
+ /* TODO: implement drain_filter?
+ #[test]
+ fn drain_filter_empty() {
+ let mut vec: ThinVec<i32> = thin_vec![];
+
+ {
+ let mut iter = vec.drain_filter(|_| true);
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ }
+ assert_eq!(vec.len(), 0);
+ assert_eq!(vec, thin_vec![]);
+ }
+
+ #[test]
+ fn drain_filter_zst() {
+ let mut vec = thin_vec![(), (), (), (), ()];
+ let initial_len = vec.len();
+ let mut count = 0;
+ {
+ let mut iter = vec.drain_filter(|_| true);
+ assert_eq!(iter.size_hint(), (0, Some(initial_len)));
+ while let Some(_) = iter.next() {
+ count += 1;
+ assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
+ }
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ }
+
+ assert_eq!(count, initial_len);
+ assert_eq!(vec.len(), 0);
+ assert_eq!(vec, thin_vec![]);
+ }
+
+ #[test]
+ fn drain_filter_false() {
+ let mut vec = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ let initial_len = vec.len();
+ let mut count = 0;
+ {
+ let mut iter = vec.drain_filter(|_| false);
+ assert_eq!(iter.size_hint(), (0, Some(initial_len)));
+ for _ in iter.by_ref() {
+ count += 1;
+ }
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ }
+
+ assert_eq!(count, 0);
+ assert_eq!(vec.len(), initial_len);
+ assert_eq!(vec, thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+ }
+
+ #[test]
+ fn drain_filter_true() {
+ let mut vec = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ let initial_len = vec.len();
+ let mut count = 0;
+ {
+ let mut iter = vec.drain_filter(|_| true);
+ assert_eq!(iter.size_hint(), (0, Some(initial_len)));
+ while let Some(_) = iter.next() {
+ count += 1;
+ assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
+ }
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ }
+
+ assert_eq!(count, initial_len);
+ assert_eq!(vec.len(), 0);
+ assert_eq!(vec, thin_vec![]);
+ }
+
+ #[test]
+ fn drain_filter_complex() {
+
+ { // [+xxx++++++xxxxx++++x+x++]
+ let mut vec = thin_vec![1,
+ 2, 4, 6,
+ 7, 9, 11, 13, 15, 17,
+ 18, 20, 22, 24, 26,
+ 27, 29, 31, 33,
+ 34,
+ 35,
+ 36,
+ 37, 39];
+
+ let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
+ assert_eq!(removed.len(), 10);
+ assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
+
+ assert_eq!(vec.len(), 14);
+ assert_eq!(vec, thin_vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]);
+ }
+
+ { // [xxx++++++xxxxx++++x+x++]
+ let mut vec = thin_vec![2, 4, 6,
+ 7, 9, 11, 13, 15, 17,
+ 18, 20, 22, 24, 26,
+ 27, 29, 31, 33,
+ 34,
+ 35,
+ 36,
+ 37, 39];
+
+ let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
+ assert_eq!(removed.len(), 10);
+ assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
+
+ assert_eq!(vec.len(), 13);
+ assert_eq!(vec, thin_vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]);
+ }
+
+ { // [xxx++++++xxxxx++++x+x]
+ let mut vec = thin_vec![2, 4, 6,
+ 7, 9, 11, 13, 15, 17,
+ 18, 20, 22, 24, 26,
+ 27, 29, 31, 33,
+ 34,
+ 35,
+ 36];
+
+ let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
+ assert_eq!(removed.len(), 10);
+ assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
+
+ assert_eq!(vec.len(), 11);
+ assert_eq!(vec, thin_vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]);
+ }
+
+ { // [xxxxxxxxxx+++++++++++]
+ let mut vec = thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
+ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
+
+ let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
+ assert_eq!(removed.len(), 10);
+ assert_eq!(removed, thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
+
+ assert_eq!(vec.len(), 10);
+ assert_eq!(vec, thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
+ }
+
+ { // [+++++++++++xxxxxxxxxx]
+ let mut vec = thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
+ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
+
+ let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
+ assert_eq!(removed.len(), 10);
+ assert_eq!(removed, thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
+
+ assert_eq!(vec.len(), 10);
+ assert_eq!(vec, thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
+ }
+ }
+ */
+ #[test]
+ fn test_reserve_exact() {
+ // This is all the same as test_reserve
+
+ let mut v = ThinVec::new();
+ assert_eq!(v.capacity(), 0);
+
+ v.reserve_exact(2);
+ assert!(v.capacity() >= 2);
+
+ for i in 0..16 {
+ v.push(i);
+ }
+
+ assert!(v.capacity() >= 16);
+ v.reserve_exact(16);
+ assert!(v.capacity() >= 32);
+
+ v.push(16);
+
+ v.reserve_exact(16);
+ assert!(v.capacity() >= 33)
+ }
+
+ /* TODO: implement try_reserve
+ #[test]
+ fn test_try_reserve() {
+
+ // These are the interesting cases:
+ // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
+ // * > isize::MAX should always fail
+ // * On 16/32-bit should CapacityOverflow
+ // * On 64-bit should OOM
+ // * overflow may trigger when adding `len` to `cap` (in number of elements)
+ // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
+
+ const MAX_CAP: usize = isize::MAX as usize;
+ const MAX_USIZE: usize = usize::MAX;
+
+ // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+ // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+ // Any platform that succeeds for these requests is technically broken with
+ // ptr::offset because LLVM is the worst.
+ let guards_against_isize = size_of::<usize>() < 8;
+
+ {
+ // Note: basic stuff is checked by test_reserve
+ let mut empty_bytes: ThinVec<u8> = ThinVec::new();
+
+ // Check isize::MAX doesn't count as an overflow
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ // Play it again, frank! (just to be sure)
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+
+ if guards_against_isize {
+ // Check isize::MAX + 1 does count as overflow
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
+ } else { panic!("isize::MAX + 1 should trigger an overflow!") }
+
+ // Check usize::MAX does count as overflow
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
+ } else { panic!("usize::MAX should trigger an overflow!") }
+ } else {
+ // Check isize::MAX + 1 is an OOM
+ if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP + 1) {
+ } else { panic!("isize::MAX + 1 should trigger an OOM!") }
+
+ // Check usize::MAX is an OOM
+ if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE) {
+ } else { panic!("usize::MAX should trigger an OOM!") }
+ }
+ }
+
+
+ {
+ // Same basic idea, but with non-zero len
+ let mut ten_bytes: ThinVec<u8> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if guards_against_isize {
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
+ } else {
+ if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an OOM!") }
+ }
+ // Should always overflow in the add-to-len
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
+ } else { panic!("usize::MAX should trigger an overflow!") }
+ }
+
+
+ {
+ // Same basic idea, but with interesting type size
+ let mut ten_u32s: ThinVec<u32> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if guards_against_isize {
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
+ } else {
+ if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an OOM!") }
+ }
+ // Should fail in the mul-by-size
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
+ } else {
+ panic!("usize::MAX should trigger an overflow!");
+ }
+ }
+
+ }
+
+ #[test]
+ fn test_try_reserve_exact() {
+
+ // This is exactly the same as test_try_reserve with the method changed.
+ // See that test for comments.
+
+ const MAX_CAP: usize = isize::MAX as usize;
+ const MAX_USIZE: usize = usize::MAX;
+
+ let guards_against_isize = size_of::<usize>() < 8;
+
+ {
+ let mut empty_bytes: ThinVec<u8> = ThinVec::new();
+
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+
+ if guards_against_isize {
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
+ } else { panic!("isize::MAX + 1 should trigger an overflow!") }
+
+ if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
+ } else { panic!("usize::MAX should trigger an overflow!") }
+ } else {
+ if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
+ } else { panic!("isize::MAX + 1 should trigger an OOM!") }
+
+ if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_USIZE) {
+ } else { panic!("usize::MAX should trigger an OOM!") }
+ }
+ }
+
+
+ {
+ let mut ten_bytes: ThinVec<u8> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if guards_against_isize {
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
+ } else {
+ if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an OOM!") }
+ }
+ if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
+ } else { panic!("usize::MAX should trigger an overflow!") }
+ }
+
+
+ {
+ let mut ten_u32s: ThinVec<u32> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
+ panic!("isize::MAX shouldn't trigger an overflow!");
+ }
+ if guards_against_isize {
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
+ } else {
+ if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
+ } else { panic!("isize::MAX + 1 should trigger an OOM!") }
+ }
+ if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
+ } else { panic!("usize::MAX should trigger an overflow!") }
+ }
+ }
+ */
+
+ #[test]
+ #[cfg_attr(feature = "gecko-ffi", ignore)]
+ fn test_header_data() {
+ macro_rules! assert_aligned_head_ptr {
+ ($typename:ty) => {{
+ let v: ThinVec<$typename> = ThinVec::with_capacity(1 /* ensure allocation */);
+ let head_ptr: *mut $typename = v.data_raw();
+ assert_eq!(
+ head_ptr as usize % std::mem::align_of::<$typename>(),
+ 0,
+ "expected Header::data<{}> to be aligned",
+ stringify!($typename)
+ );
+ }};
+ }
+
+ const HEADER_SIZE: usize = std::mem::size_of::<Header>();
+ assert_eq!(2 * std::mem::size_of::<usize>(), HEADER_SIZE);
+
+ #[repr(C, align(128))]
+ struct Funky<T>(T);
+ assert_eq!(padding::<Funky<()>>(), 128 - HEADER_SIZE);
+ assert_aligned_head_ptr!(Funky<()>);
+
+ assert_eq!(padding::<Funky<u8>>(), 128 - HEADER_SIZE);
+ assert_aligned_head_ptr!(Funky<u8>);
+
+ assert_eq!(padding::<Funky<[(); 1024]>>(), 128 - HEADER_SIZE);
+ assert_aligned_head_ptr!(Funky<[(); 1024]>);
+
+ assert_eq!(padding::<Funky<[*mut usize; 1024]>>(), 128 - HEADER_SIZE);
+ assert_aligned_head_ptr!(Funky<[*mut usize; 1024]>);
+ }
+
+ #[cfg(feature = "serde")]
+ use serde_test::{assert_tokens, Token};
+
+ #[test]
+ #[cfg(feature = "serde")]
+ fn test_ser_de_empty() {
+ let vec = ThinVec::<u32>::new();
+
+ assert_tokens(&vec, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);
+ }
+
+ #[test]
+ #[cfg(feature = "serde")]
+ fn test_ser_de() {
+ let mut vec = ThinVec::<u32>::new();
+ vec.push(20);
+ vec.push(55);
+ vec.push(123);
+
+ assert_tokens(
+ &vec,
+ &[
+ Token::Seq { len: Some(3) },
+ Token::U32(20),
+ Token::U32(55),
+ Token::U32(123),
+ Token::SeqEnd,
+ ],
+ );
+ }
+
+ #[test]
+ fn test_set_len() {
+ let mut vec: ThinVec<u32> = thin_vec![];
+ unsafe {
+ vec.set_len(0); // at one point this caused a crash
+ }
+ }
+
+ #[test]
+ #[should_panic(expected = "invalid set_len(1) on empty ThinVec")]
+ fn test_set_len_invalid() {
+ let mut vec: ThinVec<u32> = thin_vec![];
+ unsafe {
+ vec.set_len(1);
+ }
+ }
+}
diff --git a/vendor/thiserror-impl/.cargo-checksum.json b/vendor/thiserror-impl/.cargo-checksum.json
index a1c0ef900..002cf212c 100644
--- a/vendor/thiserror-impl/.cargo-checksum.json
+++ b/vendor/thiserror-impl/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"4089f6b56d562de455fa1c98d3122512e8289085508d055366059f00f14060e9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/ast.rs":"c7601e8394f5ee304365c520181f0dbeaa807ddaa71ce4a8618ea1a70f81b3b2","src/attr.rs":"d1fe75dde04cb8df6da4e1aaec5b38c2b0f634fa3432877993b3fec4cc08b6b5","src/expand.rs":"cf6b969e8ecaaf3a6b31ffebce395e1882a9f263985970041c6e687f0ce5a6cd","src/fmt.rs":"d63d39120c18712596f9f2a1715821148c2becd4d8bad5bc1b307210a84dbe98","src/generics.rs":"ac493703c9955400d4fab22cbbdbbc4bf4f6f72c112b34be8b784142142ff74f","src/lib.rs":"57dce312458895d25c6fd0ef3111362b053edd2f5e0ee04d19edb33bd3c1afbd","src/prop.rs":"6709932aee8f9d217f40cd644629c0ecb2f46d333ae8a1398e8d745534f4e028","src/valid.rs":"93317a8342891dc4569cfdd5f64a8c64cdec8fff49911428427b0621974eec32"},"package":"aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"} \ No newline at end of file
+{"files":{"Cargo.toml":"3171e8d362ab2f3958292eb1862426b9206637c2941edbc482460f5e0b04c9d0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/ast.rs":"c7601e8394f5ee304365c520181f0dbeaa807ddaa71ce4a8618ea1a70f81b3b2","src/attr.rs":"d1fe75dde04cb8df6da4e1aaec5b38c2b0f634fa3432877993b3fec4cc08b6b5","src/expand.rs":"791000b41cc09250c04dbf2f7adc06f1254922986c86633471e934621ce31940","src/fmt.rs":"d63d39120c18712596f9f2a1715821148c2becd4d8bad5bc1b307210a84dbe98","src/generics.rs":"2076cde22271be355a8131a77add4b93f83ab0af4317cd2df5471fffa4f95c66","src/lib.rs":"7d023310cd3db670554ce108a6afd94e1ae3c55c83661d4b9fcebdf1865b9e4b","src/prop.rs":"6709932aee8f9d217f40cd644629c0ecb2f46d333ae8a1398e8d745534f4e028","src/valid.rs":"ac95253944fd360d3578d0643a7baabb2cfa6bf9fbced7a6ce1f7b0529a3bb98"},"package":"c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09"} \ No newline at end of file
diff --git a/vendor/thiserror-impl/Cargo.toml b/vendor/thiserror-impl/Cargo.toml
index 97e0042c1..c377ae01b 100644
--- a/vendor/thiserror-impl/Cargo.toml
+++ b/vendor/thiserror-impl/Cargo.toml
@@ -13,16 +13,18 @@
edition = "2018"
rust-version = "1.31"
name = "thiserror-impl"
-version = "1.0.30"
+version = "1.0.33"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Implementation detail of the `thiserror` crate"
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/thiserror"
+
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[lib]
proc-macro = true
+
[dependencies.proc-macro2]
version = "1.0"
diff --git a/vendor/thiserror-impl/src/expand.rs b/vendor/thiserror-impl/src/expand.rs
index 435ad4847..f2f7116f2 100644
--- a/vendor/thiserror-impl/src/expand.rs
+++ b/vendor/thiserror-impl/src/expand.rs
@@ -53,51 +53,59 @@ fn impl_struct(input: Struct) -> TokenStream {
let source_method = source_body.map(|body| {
quote! {
fn source(&self) -> std::option::Option<&(dyn std::error::Error + 'static)> {
- use thiserror::private::AsDynError;
+ use thiserror::__private::AsDynError;
#body
}
}
});
- let backtrace_method = input.backtrace_field().map(|backtrace_field| {
+ let provide_method = input.backtrace_field().map(|backtrace_field| {
+ let demand = quote!(demand);
let backtrace = &backtrace_field.member;
let body = if let Some(source_field) = input.source_field() {
let source = &source_field.member;
- let source_backtrace = if type_is_option(source_field.ty) {
+ let source_provide = if type_is_option(source_field.ty) {
quote_spanned! {source.span()=>
- self.#source.as_ref().and_then(|source| source.as_dyn_error().backtrace())
+ if let std::option::Option::Some(source) = &self.#source {
+ source.as_dyn_error().provide(#demand);
+ }
}
} else {
quote_spanned! {source.span()=>
- self.#source.as_dyn_error().backtrace()
+ self.#source.as_dyn_error().provide(#demand);
}
};
- let combinator = if source == backtrace {
- source_backtrace
+ let self_provide = if source == backtrace {
+ None
} else if type_is_option(backtrace_field.ty) {
- quote! {
- #source_backtrace.or(self.#backtrace.as_ref())
- }
+ Some(quote! {
+ if let std::option::Option::Some(backtrace) = &self.#backtrace {
+ #demand.provide_ref::<std::backtrace::Backtrace>(backtrace);
+ }
+ })
} else {
- quote! {
- std::option::Option::Some(#source_backtrace.unwrap_or(&self.#backtrace))
- }
+ Some(quote! {
+ #demand.provide_ref::<std::backtrace::Backtrace>(&self.#backtrace);
+ })
};
quote! {
- use thiserror::private::AsDynError;
- #combinator
+ use thiserror::__private::AsDynError;
+ #source_provide
+ #self_provide
}
} else if type_is_option(backtrace_field.ty) {
quote! {
- self.#backtrace.as_ref()
+ if let std::option::Option::Some(backtrace) = &self.#backtrace {
+ #demand.provide_ref::<std::backtrace::Backtrace>(backtrace);
+ }
}
} else {
quote! {
- std::option::Option::Some(&self.#backtrace)
+ #demand.provide_ref::<std::backtrace::Backtrace>(&self.#backtrace);
}
};
quote! {
- fn backtrace(&self) -> std::option::Option<&std::backtrace::Backtrace> {
+ fn provide<'_demand>(&'_demand self, #demand: &mut std::any::Demand<'_demand>) {
#body
}
}
@@ -115,7 +123,7 @@ fn impl_struct(input: Struct) -> TokenStream {
let use_as_display = if display.has_bonus_display {
Some(quote! {
#[allow(unused_imports)]
- use thiserror::private::{DisplayAsDisplay, PathAsDisplay};
+ use thiserror::__private::{DisplayAsDisplay, PathAsDisplay};
})
} else {
None
@@ -177,7 +185,7 @@ fn impl_struct(input: Struct) -> TokenStream {
#[allow(unused_qualifications)]
impl #impl_generics #error_trait for #ty #ty_generics #error_where_clause {
#source_method
- #backtrace_method
+ #provide_method
}
#display_impl
#from_impl
@@ -226,7 +234,7 @@ fn impl_enum(input: Enum) -> TokenStream {
});
Some(quote! {
fn source(&self) -> std::option::Option<&(dyn std::error::Error + 'static)> {
- use thiserror::private::AsDynError;
+ use thiserror::__private::AsDynError;
#[allow(deprecated)]
match self {
#(#arms)*
@@ -237,7 +245,8 @@ fn impl_enum(input: Enum) -> TokenStream {
None
};
- let backtrace_method = if input.has_backtrace() {
+ let provide_method = if input.has_backtrace() {
+ let demand = quote!(demand);
let arms = input.variants.iter().map(|variant| {
let ident = &variant.ident;
match (variant.backtrace_field(), variant.source_field()) {
@@ -247,22 +256,26 @@ fn impl_enum(input: Enum) -> TokenStream {
let backtrace = &backtrace_field.member;
let source = &source_field.member;
let varsource = quote!(source);
- let source_backtrace = if type_is_option(source_field.ty) {
+ let source_provide = if type_is_option(source_field.ty) {
quote_spanned! {source.span()=>
- #varsource.as_ref().and_then(|source| source.as_dyn_error().backtrace())
+ if let std::option::Option::Some(source) = #varsource {
+ source.as_dyn_error().provide(#demand);
+ }
}
} else {
quote_spanned! {source.span()=>
- #varsource.as_dyn_error().backtrace()
+ #varsource.as_dyn_error().provide(#demand);
}
};
- let combinator = if type_is_option(backtrace_field.ty) {
+ let self_provide = if type_is_option(backtrace_field.ty) {
quote! {
- #source_backtrace.or(backtrace.as_ref())
+ if let std::option::Option::Some(backtrace) = backtrace {
+ #demand.provide_ref::<std::backtrace::Backtrace>(backtrace);
+ }
}
} else {
quote! {
- std::option::Option::Some(#source_backtrace.unwrap_or(backtrace))
+ #demand.provide_ref::<std::backtrace::Backtrace>(backtrace);
}
};
quote! {
@@ -271,8 +284,9 @@ fn impl_enum(input: Enum) -> TokenStream {
#source: #varsource,
..
} => {
- use thiserror::private::AsDynError;
- #combinator
+ use thiserror::__private::AsDynError;
+ #source_provide
+ #self_provide
}
}
}
@@ -281,40 +295,50 @@ fn impl_enum(input: Enum) -> TokenStream {
{
let backtrace = &backtrace_field.member;
let varsource = quote!(source);
- let source_backtrace = if type_is_option(source_field.ty) {
+ let source_provide = if type_is_option(source_field.ty) {
quote_spanned! {backtrace.span()=>
- #varsource.as_ref().and_then(|source| source.as_dyn_error().backtrace())
+ if let std::option::Option::Some(source) = #varsource {
+ source.as_dyn_error().provide(#demand);
+ }
}
} else {
quote_spanned! {backtrace.span()=>
- #varsource.as_dyn_error().backtrace()
+ #varsource.as_dyn_error().provide(#demand);
}
};
quote! {
#ty::#ident {#backtrace: #varsource, ..} => {
- use thiserror::private::AsDynError;
- #source_backtrace
+ use thiserror::__private::AsDynError;
+ #source_provide
}
}
}
(Some(backtrace_field), _) => {
let backtrace = &backtrace_field.member;
let body = if type_is_option(backtrace_field.ty) {
- quote!(backtrace.as_ref())
+ quote! {
+ if let std::option::Option::Some(backtrace) = backtrace {
+ #demand.provide_ref::<std::backtrace::Backtrace>(backtrace);
+ }
+ }
} else {
- quote!(std::option::Option::Some(backtrace))
+ quote! {
+ #demand.provide_ref::<std::backtrace::Backtrace>(backtrace);
+ }
};
quote! {
- #ty::#ident {#backtrace: backtrace, ..} => #body,
+ #ty::#ident {#backtrace: backtrace, ..} => {
+ #body
+ }
}
}
(None, _) => quote! {
- #ty::#ident {..} => std::option::Option::None,
+ #ty::#ident {..} => {}
},
}
});
Some(quote! {
- fn backtrace(&self) -> std::option::Option<&std::backtrace::Backtrace> {
+ fn provide<'_demand>(&'_demand self, #demand: &mut std::any::Demand<'_demand>) {
#[allow(deprecated)]
match self {
#(#arms)*
@@ -335,7 +359,7 @@ fn impl_enum(input: Enum) -> TokenStream {
}) {
Some(quote! {
#[allow(unused_imports)]
- use thiserror::private::{DisplayAsDisplay, PathAsDisplay};
+ use thiserror::__private::{DisplayAsDisplay, PathAsDisplay};
})
} else {
None
@@ -420,7 +444,7 @@ fn impl_enum(input: Enum) -> TokenStream {
#[allow(unused_qualifications)]
impl #impl_generics #error_trait for #ty #ty_generics #error_where_clause {
#source_method
- #backtrace_method
+ #provide_method
}
#display_impl
#(#from_impls)*
diff --git a/vendor/thiserror-impl/src/generics.rs b/vendor/thiserror-impl/src/generics.rs
index 254c2ed35..95592a737 100644
--- a/vendor/thiserror-impl/src/generics.rs
+++ b/vendor/thiserror-impl/src/generics.rs
@@ -57,6 +57,7 @@ impl InferredBounds {
}
}
+ #[allow(clippy::type_repetition_in_bounds, clippy::trait_duplication_in_bounds)] // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8771
pub fn insert(&mut self, ty: impl ToTokens, bound: impl ToTokens) {
let ty = ty.to_token_stream();
let bound = bound.to_token_stream();
diff --git a/vendor/thiserror-impl/src/lib.rs b/vendor/thiserror-impl/src/lib.rs
index a4d5ae7d5..f0fc96917 100644
--- a/vendor/thiserror-impl/src/lib.rs
+++ b/vendor/thiserror-impl/src/lib.rs
@@ -1,13 +1,16 @@
#![allow(
clippy::blocks_in_if_conditions,
+ clippy::cast_lossless,
clippy::cast_possible_truncation,
+ clippy::manual_find,
clippy::manual_map,
clippy::map_unwrap_or,
clippy::needless_pass_by_value,
clippy::option_if_let_else,
clippy::range_plus_one,
clippy::single_match_else,
- clippy::too_many_lines
+ clippy::too_many_lines,
+ clippy::wrong_self_convention
)]
extern crate proc_macro;
diff --git a/vendor/thiserror-impl/src/valid.rs b/vendor/thiserror-impl/src/valid.rs
index 7657265ef..cf5b8592c 100644
--- a/vendor/thiserror-impl/src/valid.rs
+++ b/vendor/thiserror-impl/src/valid.rs
@@ -180,7 +180,11 @@ fn check_field_attrs(fields: &[Field]) -> Result<()> {
}
}
if let Some(from_field) = from_field {
- if fields.len() > 1 + has_backtrace as usize {
+ let max_expected_fields = match backtrace_field {
+ Some(backtrace_field) => 1 + !same_member(from_field, backtrace_field) as usize,
+ None => 1 + has_backtrace as usize,
+ };
+ if fields.len() > max_expected_fields {
return Err(Error::new_spanned(
from_field.attrs.from,
"deriving From requires no fields other than source and backtrace",
diff --git a/vendor/thiserror/.cargo-checksum.json b/vendor/thiserror/.cargo-checksum.json
index 0b30f4e65..f62a31345 100644
--- a/vendor/thiserror/.cargo-checksum.json
+++ b/vendor/thiserror/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"4e67c7ab97838c17f0db6b027bbddfb59f549bf5b965f2e9e11863c522d6a80a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"a9f0f8261b1cb4b7a5e6e32242f511339e74452e44a92b6e6158c665108acb9f","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/aserror.rs":"3dd14cfcfe4a0ab8b1dd774e4ea0a0197989afe84e0687e73873b61cfa4347fa","src/display.rs":"63c492bfa8b8e9180ad5abcbe63c1173b4ad490c47ec33cac9a338f96c8f8e42","src/lib.rs":"7e740a989ed7fe4f851a0a3ea3143b655a907a81a755034a84171466ab44f94b","tests/compiletest.rs":"c61425723ca4eeb4a9079495c0e9640a9d210780b47e183fdb09ee2ad6887ce6","tests/test_backtrace.rs":"32175af055514c4d8ee20923bdf26bf64b060e8642d8be3c50b77187d81c3acf","tests/test_display.rs":"dde5540dd4b47613ae9e3a1360ced832131a86c83ccc7da2bb89042062aa5d5e","tests/test_error.rs":"994f35bba245cbdc08c094094b9c1440a0a2b48333663c73c6a96e772ae5d3d8","tests/test_expr.rs":"cd42633c0b0a0f595a5c498e576ca50b3a1c555c54b4652bdd296a4073771a61","tests/test_from.rs":"41f2fbc391d95be68aefea3e4ae59bb71074bb020b0a1e109acbdea1f45e7666","tests/test_generics.rs":"4ca6a1a47bfc0095783133b7db9f626d176f65ca077cc15847f6ef5caff2d881","tests/test_lints.rs":"c17d79d77edfcdd4b8f6dcdcd1c70ad065cfbc747e1a618ac6343315d0b59ea4","tests/test_option.rs":"a3510dc1aef5a2dc995188506a560d7597d38717408606dece0b50a30d39bc26","tests/test_path.rs":"8f25b9be8940b9c41b254ae1bd265851e593734488fb0dbf94444bb583b95944","tests/test_source.rs":"6c352c520ead863601043f9c4a23751e235e710790f5c11f56f817a8811eb94f","tests/test_transparent.rs":"410a1328202e70bf64301737d4dda700bd9f073faacd3e50bdc4a7ddeddc8aa1","tests/ui/bad-field-attr.rs":"c5b567e3091969a01061843fb2d95c5e1aa3fa81edfeecdf416a84a6fba40aa8","tests/ui/bad-field-attr.stderr":"78f576d5ec66464a77f1cdf0f5bb7dcdf18f7f04f1165983a6239ec59d908ea3","tests/ui/concat-display.rs":"3995bd6b3bdd67df7bb16499775d89600c0dd20895633fe807396a64c117078d","tests/ui/concat-display.stderr":"f8ee9f2003def1b60b482e0fe01a61a2b77fd82508454a843dc6df60b8c92051","tests/ui/duplicate-enum-source.rs":"bfe28ce18042d446a76c7411aa233598211ce1157fdd3cb87bff3b3fa7c33131","tests/ui/duplicate-enum-source.stderr":"3d32fead420b27b4497be49080bc3b78f7f0ba339ead3de6c94e5dc20302c18f","tests/ui/duplicate-fmt.rs":"af53b66445bcce076a114376747f176b42c060a156563a41ccb638ae14c451fd","tests/ui/duplicate-fmt.stderr":"998bb121ce6f1595fd99529a7a1b06451b6bf476924337dce5524a83a7a5f1a1","tests/ui/duplicate-struct-source.rs":"f3d5f8e3d6fccfcdbb630db291353709583a920c6bf46f9f9de9966b67ea4c0f","tests/ui/duplicate-struct-source.stderr":"fb761d76668ac42357cf37b03c0abdbae5de0a828034990850291c9cb6ab766d","tests/ui/duplicate-transparent.rs":"41a9447e85f1a47027023442acde55c3d8610ec46d91b39bd43a42d7a004d747","tests/ui/duplicate-transparent.stderr":"4975abad43e973df158f18098d9bcb9dc39f8e75d3e733ed5d6620d1ee065c11","tests/ui/from-not-source.rs":"744a55aeffe11066830159ac023c33aaa5576e313b341fa24440ee13dfe3ac98","tests/ui/from-not-source.stderr":"525038e8b841707b927434cca4549168f73bd305faca17552a0d1fffa542ccc4","tests/ui/lifetime.rs":"e72e0391695e47fcd07edbf3819f114e468e2097086ec687781c7c8d6b4b7da7","tests/ui/lifetime.stderr":"d889a23f71324afe95dafc5f9d15337fbdbc9977cb8924f0cafe3a3becf4ced7","tests/ui/missing-fmt.rs":"bc9e2830e54c2474ff6c27a766ed3dee88d29e40f93f30e8d64d63233866c17d","tests/ui/missing-fmt.stderr":"9a20ccee9b660fe31a5b3199307b48580bb8305cb9ce33d97d3fc767a0cfc614","tests/ui/no-display.rs":"962245372272d23e9833311c15e73221b3c7da822a2ff90189613af56ffb5c2e","tests/ui/no-display.stderr":"d1d9e24b4689cd09e784ab9b62721f77a6fa5f4372ba45300997d2569ff7aa9a","tests/ui/source-enum-not-error.rs":"7c57c63b3ec37bc456738acea2e1038de5b0f32fe7e83984037d7ad1ed921737","tests/ui/source-enum-not-error.stderr":"897d610f1114bd108fa607f038f93438d57a1cc711db26ccb4e20ef31248386a","tests/ui/source-struct-not-error.rs":"09fb7713637242dca9192585a6daeb8d732dc1c1d0fa522b74f1c98618e6d949","tests/ui/source-struct-not-error.stderr":"a310d33021a1a1ed0a61090e7d60236a3c4da478a14ae7635c124779348ce831","tests/ui/transparent-display.rs":"b3c59583eb64b0b5a246444456d03cf52d51bcdc08885023600dbb44fd87e5f2","tests/ui/transparent-display.stderr":"16d538914e0d92026bde4b4bec75660217da9ecc6b621d12d2eb81d33ed1d1da","tests/ui/transparent-enum-many.rs":"2a40a764fb4683bff57973eec61507a6c00f7d4d7a32da6e7bd0190c2e445434","tests/ui/transparent-enum-many.stderr":"f1d78c1d6d8edbef153420db4fb9ca3dc6076fa043b5b1bc0cd291daa417a3ea","tests/ui/transparent-enum-source.rs":"18f606a98ac0a53f08dc56f5f923b9cbe75d25ed34479c777b48dac305d5968c","tests/ui/transparent-enum-source.stderr":"1b2e0ac53951034575d43ec0396c4e2b3cfb272db2aef8d6baa13a7e1632cc84","tests/ui/transparent-struct-many.rs":"72c6b6c1a44c203d3bc68989b2f1ec092531ef75b745432824c3776c290326f6","tests/ui/transparent-struct-many.stderr":"7bd0536dbb54a0ce7d4a8e66ca7624a1b132d8a1d1e4fecca642ec77494ac01c","tests/ui/transparent-struct-source.rs":"863fa691ed7d27e8767da58d9ee11fd40d6642274b36338ca1074c07964ea2b3","tests/ui/transparent-struct-source.stderr":"267dab65929e67d32347fb467a00b43af931f8205d727d7671938580217fc70e","tests/ui/unexpected-field-fmt.rs":"29fba7b4d81c642ec8e47cfe053aa515acf9080a86d65e685363a48993becfe3","tests/ui/unexpected-field-fmt.stderr":"20731c4a08af04bed3ff513903adadd690b6bc532b15604557e7f25575a8338f","tests/ui/unexpected-struct-source.rs":"c6cbe882d622635c216feb8290b1bd536ce0ec4feee16bc087667a21b3641d5c","tests/ui/unexpected-struct-source.stderr":"7c8227513478f6cc09e8a28be337c8a0e758a06ca5978d774c91bd43c4a54043","tests/ui/union.rs":"331adff27cebd8b95b03b6742cc8247331fda1f961e1590ed39c8d39f50cf1d8","tests/ui/union.stderr":"5f67ad29753d6fb14bc03aef7d4a1f660ee7796e469c037efbf8b13456934ad3"},"package":"854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"} \ No newline at end of file
+{"files":{"Cargo.toml":"0de812f611be41d9b1962bdcb235479fed9d9d48eed22033fdb0c2cadbb0e602","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f774d4cb12047fef7c65a86e00eb7299f9250e0bc1aa445d16f63162ec942551","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/aserror.rs":"3dd14cfcfe4a0ab8b1dd774e4ea0a0197989afe84e0687e73873b61cfa4347fa","src/display.rs":"63c492bfa8b8e9180ad5abcbe63c1173b4ad490c47ec33cac9a338f96c8f8e42","src/lib.rs":"62b459b2bf9b53647570511189ed4980a0aed10a9f49abec7c34cef53178a6b2","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test_backtrace.rs":"43323a073ca464b16e213869d3f459f07a0f9601f1516ec81371c825fb1ec8f2","tests/test_display.rs":"20fdc8903f06da3a698ef4377cccca26a71138ca6de67310c5bdb8a9fcb39d83","tests/test_error.rs":"d06dca3c38f22d7ce4e27dadd6c0f78e5cefe3a2ebbc5fe44abc9ddd5ee1985f","tests/test_expr.rs":"388402702a3be4ffcd0574d66733e8932bf7d5de37544a00ecb0e4f8d8246da4","tests/test_from.rs":"de1347e62069f826d8616b9e45ce6cccc3a8a8049cb51bd22d6763efe6118b0c","tests/test_generics.rs":"4f33747e3f62550d5af94687679af230ef92fbb3247ae4b41df46792a040e4dc","tests/test_lints.rs":"c17d79d77edfcdd4b8f6dcdcd1c70ad065cfbc747e1a618ac6343315d0b59ea4","tests/test_option.rs":"3a82af1ad206444b9955e3f2fda508d70f887ad0b7f7986bafc17496f63b07ab","tests/test_path.rs":"ef5452c7e828a0179f5ace7e19f95b9762aa887caf10244adbfe36ded712c090","tests/test_source.rs":"f2f04f11bf8a709eddb1c68f113cda0c2be87e56800d6b9d991bedd545b4642f","tests/test_transparent.rs":"cd8d5be14d00d610a1782104bea6c013618501dab5c3625178ecfcf66e31f939","tests/ui/bad-field-attr.rs":"c5b567e3091969a01061843fb2d95c5e1aa3fa81edfeecdf416a84a6fba40aa8","tests/ui/bad-field-attr.stderr":"78f576d5ec66464a77f1cdf0f5bb7dcdf18f7f04f1165983a6239ec59d908ea3","tests/ui/concat-display.rs":"3995bd6b3bdd67df7bb16499775d89600c0dd20895633fe807396a64c117078d","tests/ui/concat-display.stderr":"256dfde61ee689ebe51588b135e2e030bdf95ba5adef1cb59f588c797bbdeef2","tests/ui/duplicate-enum-source.rs":"bfe28ce18042d446a76c7411aa233598211ce1157fdd3cb87bff3b3fa7c33131","tests/ui/duplicate-enum-source.stderr":"3d32fead420b27b4497be49080bc3b78f7f0ba339ead3de6c94e5dc20302c18f","tests/ui/duplicate-fmt.rs":"af53b66445bcce076a114376747f176b42c060a156563a41ccb638ae14c451fd","tests/ui/duplicate-fmt.stderr":"998bb121ce6f1595fd99529a7a1b06451b6bf476924337dce5524a83a7a5f1a1","tests/ui/duplicate-struct-source.rs":"f3d5f8e3d6fccfcdbb630db291353709583a920c6bf46f9f9de9966b67ea4c0f","tests/ui/duplicate-struct-source.stderr":"fb761d76668ac42357cf37b03c0abdbae5de0a828034990850291c9cb6ab766d","tests/ui/duplicate-transparent.rs":"41a9447e85f1a47027023442acde55c3d8610ec46d91b39bd43a42d7a004d747","tests/ui/duplicate-transparent.stderr":"4975abad43e973df158f18098d9bcb9dc39f8e75d3e733ed5d6620d1ee065c11","tests/ui/from-backtrace-backtrace.rs":"1fd51c5a1f7f6b6ee676d9fc798b6276ef2ce75def33d07f0e4b7bbde3291859","tests/ui/from-backtrace-backtrace.stderr":"f9774e9dad51374501ef4a55fa2dacece4d1c70e29ca18761394bdb80a9a74da","tests/ui/from-not-source.rs":"744a55aeffe11066830159ac023c33aaa5576e313b341fa24440ee13dfe3ac98","tests/ui/from-not-source.stderr":"525038e8b841707b927434cca4549168f73bd305faca17552a0d1fffa542ccc4","tests/ui/lifetime.rs":"e72e0391695e47fcd07edbf3819f114e468e2097086ec687781c7c8d6b4b7da7","tests/ui/lifetime.stderr":"d889a23f71324afe95dafc5f9d15337fbdbc9977cb8924f0cafe3a3becf4ced7","tests/ui/missing-fmt.rs":"bc9e2830e54c2474ff6c27a766ed3dee88d29e40f93f30e8d64d63233866c17d","tests/ui/missing-fmt.stderr":"9a20ccee9b660fe31a5b3199307b48580bb8305cb9ce33d97d3fc767a0cfc614","tests/ui/no-display.rs":"962245372272d23e9833311c15e73221b3c7da822a2ff90189613af56ffb5c2e","tests/ui/no-display.stderr":"40f47b286b770808a7dc5ec7970bc5cd501c9400f2e50049cf3258174929a9c1","tests/ui/source-enum-not-error.rs":"7c57c63b3ec37bc456738acea2e1038de5b0f32fe7e83984037d7ad1ed921737","tests/ui/source-enum-not-error.stderr":"44c974bf0b87431af78ccc7b4e18ebdc45135ca584a254960dff3f908ed862a8","tests/ui/source-struct-not-error.rs":"09fb7713637242dca9192585a6daeb8d732dc1c1d0fa522b74f1c98618e6d949","tests/ui/source-struct-not-error.stderr":"8e087a059c6b69de44e149ab3b5bffc4f4c6c3cbbb13c235c9a3c7c264be3245","tests/ui/transparent-display.rs":"b3c59583eb64b0b5a246444456d03cf52d51bcdc08885023600dbb44fd87e5f2","tests/ui/transparent-display.stderr":"16d538914e0d92026bde4b4bec75660217da9ecc6b621d12d2eb81d33ed1d1da","tests/ui/transparent-enum-many.rs":"2a40a764fb4683bff57973eec61507a6c00f7d4d7a32da6e7bd0190c2e445434","tests/ui/transparent-enum-many.stderr":"f1d78c1d6d8edbef153420db4fb9ca3dc6076fa043b5b1bc0cd291daa417a3ea","tests/ui/transparent-enum-source.rs":"18f606a98ac0a53f08dc56f5f923b9cbe75d25ed34479c777b48dac305d5968c","tests/ui/transparent-enum-source.stderr":"1b2e0ac53951034575d43ec0396c4e2b3cfb272db2aef8d6baa13a7e1632cc84","tests/ui/transparent-struct-many.rs":"72c6b6c1a44c203d3bc68989b2f1ec092531ef75b745432824c3776c290326f6","tests/ui/transparent-struct-many.stderr":"7bd0536dbb54a0ce7d4a8e66ca7624a1b132d8a1d1e4fecca642ec77494ac01c","tests/ui/transparent-struct-source.rs":"863fa691ed7d27e8767da58d9ee11fd40d6642274b36338ca1074c07964ea2b3","tests/ui/transparent-struct-source.stderr":"267dab65929e67d32347fb467a00b43af931f8205d727d7671938580217fc70e","tests/ui/unexpected-field-fmt.rs":"29fba7b4d81c642ec8e47cfe053aa515acf9080a86d65e685363a48993becfe3","tests/ui/unexpected-field-fmt.stderr":"20731c4a08af04bed3ff513903adadd690b6bc532b15604557e7f25575a8338f","tests/ui/unexpected-struct-source.rs":"c6cbe882d622635c216feb8290b1bd536ce0ec4feee16bc087667a21b3641d5c","tests/ui/unexpected-struct-source.stderr":"7c8227513478f6cc09e8a28be337c8a0e758a06ca5978d774c91bd43c4a54043","tests/ui/union.rs":"331adff27cebd8b95b03b6742cc8247331fda1f961e1590ed39c8d39f50cf1d8","tests/ui/union.stderr":"5f67ad29753d6fb14bc03aef7d4a1f660ee7796e469c037efbf8b13456934ad3"},"package":"3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57"} \ No newline at end of file
diff --git a/vendor/thiserror/Cargo.toml b/vendor/thiserror/Cargo.toml
index 78c99d623..5926572e3 100644
--- a/vendor/thiserror/Cargo.toml
+++ b/vendor/thiserror/Cargo.toml
@@ -13,18 +13,26 @@
edition = "2018"
rust-version = "1.31"
name = "thiserror"
-version = "1.0.30"
+version = "1.0.33"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "derive(Error)"
documentation = "https://docs.rs/thiserror"
readme = "README.md"
+keywords = [
+ "error",
+ "error-handling",
+ "derive",
+]
categories = ["rust-patterns"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/thiserror"
+
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies.thiserror-impl]
-version = "=1.0.30"
+version = "=1.0.33"
+
[dev-dependencies.anyhow]
version = "1.0"
diff --git a/vendor/thiserror/README.md b/vendor/thiserror/README.md
index e12b693ef..387a56e46 100644
--- a/vendor/thiserror/README.md
+++ b/vendor/thiserror/README.md
@@ -3,7 +3,7 @@ derive(Error)
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/thiserror-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/thiserror)
[<img alt="crates.io" src="https://img.shields.io/crates/v/thiserror.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/thiserror)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/thiserror)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/thiserror)
[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/thiserror/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/thiserror/actions?query=branch%3Amaster)
This library provides a convenient derive macro for the standard library's
diff --git a/vendor/thiserror/src/lib.rs b/vendor/thiserror/src/lib.rs
index 2fae25c54..247199ffd 100644
--- a/vendor/thiserror/src/lib.rs
+++ b/vendor/thiserror/src/lib.rs
@@ -2,7 +2,7 @@
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
@@ -205,6 +205,7 @@
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7421
clippy::doc_markdown,
clippy::module_name_repetitions,
+ clippy::return_self_not_must_use,
)]
mod aserror;
@@ -214,7 +215,7 @@ pub use thiserror_impl::*;
// Not public API.
#[doc(hidden)]
-pub mod private {
+pub mod __private {
pub use crate::aserror::AsDynError;
pub use crate::display::{DisplayAsDisplay, PathAsDisplay};
}
diff --git a/vendor/thiserror/tests/compiletest.rs b/vendor/thiserror/tests/compiletest.rs
index 641d03cbf..7974a6249 100644
--- a/vendor/thiserror/tests/compiletest.rs
+++ b/vendor/thiserror/tests/compiletest.rs
@@ -1,6 +1,5 @@
-#![deny(clippy::all, clippy::pedantic)]
-
#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
#[test]
fn ui() {
let t = trybuild::TestCases::new();
diff --git a/vendor/thiserror/tests/test_backtrace.rs b/vendor/thiserror/tests/test_backtrace.rs
index 42e37ca16..052c6f481 100644
--- a/vendor/thiserror/tests/test_backtrace.rs
+++ b/vendor/thiserror/tests/test_backtrace.rs
@@ -1,4 +1,7 @@
-#![cfg_attr(thiserror_nightly_testing, feature(backtrace))]
+#![cfg_attr(
+ thiserror_nightly_testing,
+ feature(error_generic_member_access, provide_any)
+)]
use thiserror::Error;
@@ -16,8 +19,8 @@ pub struct InnerBacktrace {
#[cfg(thiserror_nightly_testing)]
pub mod structs {
use super::{Inner, InnerBacktrace};
+ use std::any;
use std::backtrace::Backtrace;
- use std::error::Error;
use std::sync::Arc;
use thiserror::Error;
@@ -88,44 +91,44 @@ pub mod structs {
let error = PlainBacktrace {
backtrace: Backtrace::capture(),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = ExplicitBacktrace {
backtrace: Backtrace::capture(),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = OptBacktrace {
backtrace: Some(Backtrace::capture()),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = ArcBacktrace {
backtrace: Arc::new(Backtrace::capture()),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = BacktraceFrom::from(Inner);
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = CombinedBacktraceFrom::from(InnerBacktrace {
backtrace: Backtrace::capture(),
});
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = OptBacktraceFrom::from(Inner);
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = ArcBacktraceFrom::from(Inner);
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
}
}
#[cfg(thiserror_nightly_testing)]
pub mod enums {
use super::{Inner, InnerBacktrace};
+ use std::any;
use std::backtrace::Backtrace;
- use std::error::Error;
use std::sync::Arc;
use thiserror::Error;
@@ -210,36 +213,36 @@ pub mod enums {
let error = PlainBacktrace::Test {
backtrace: Backtrace::capture(),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = ExplicitBacktrace::Test {
backtrace: Backtrace::capture(),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = OptBacktrace::Test {
backtrace: Some(Backtrace::capture()),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = ArcBacktrace::Test {
backtrace: Arc::new(Backtrace::capture()),
};
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = BacktraceFrom::from(Inner);
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = CombinedBacktraceFrom::from(InnerBacktrace {
backtrace: Backtrace::capture(),
});
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = OptBacktraceFrom::from(Inner);
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
let error = ArcBacktraceFrom::from(Inner);
- assert!(error.backtrace().is_some());
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
}
}
diff --git a/vendor/thiserror/tests/test_display.rs b/vendor/thiserror/tests/test_display.rs
index 949d9eda7..8917bb054 100644
--- a/vendor/thiserror/tests/test_display.rs
+++ b/vendor/thiserror/tests/test_display.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
use std::fmt::Display;
use thiserror::Error;
diff --git a/vendor/thiserror/tests/test_error.rs b/vendor/thiserror/tests/test_error.rs
index ece7f91a9..fab934d78 100644
--- a/vendor/thiserror/tests/test_error.rs
+++ b/vendor/thiserror/tests/test_error.rs
@@ -1,4 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
#![allow(dead_code)]
use std::fmt::{self, Display};
diff --git a/vendor/thiserror/tests/test_expr.rs b/vendor/thiserror/tests/test_expr.rs
index 87a56cf58..34de56087 100644
--- a/vendor/thiserror/tests/test_expr.rs
+++ b/vendor/thiserror/tests/test_expr.rs
@@ -1,5 +1,4 @@
-#![deny(clippy::all, clippy::pedantic)]
-#![allow(clippy::option_if_let_else)]
+#![allow(clippy::iter_cloned_collect, clippy::option_if_let_else)]
use std::fmt::Display;
use thiserror::Error;
diff --git a/vendor/thiserror/tests/test_from.rs b/vendor/thiserror/tests/test_from.rs
index a25ce353d..1f387055f 100644
--- a/vendor/thiserror/tests/test_from.rs
+++ b/vendor/thiserror/tests/test_from.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
use std::io;
use thiserror::Error;
diff --git a/vendor/thiserror/tests/test_generics.rs b/vendor/thiserror/tests/test_generics.rs
index f5e1de243..4ab9f3778 100644
--- a/vendor/thiserror/tests/test_generics.rs
+++ b/vendor/thiserror/tests/test_generics.rs
@@ -1,4 +1,4 @@
-#![deny(clippy::all, clippy::pedantic)]
+#![allow(clippy::needless_late_init)]
use std::fmt::{self, Debug, Display};
use thiserror::Error;
diff --git a/vendor/thiserror/tests/test_option.rs b/vendor/thiserror/tests/test_option.rs
index ca2171385..ed5287dc9 100644
--- a/vendor/thiserror/tests/test_option.rs
+++ b/vendor/thiserror/tests/test_option.rs
@@ -1,5 +1,7 @@
-#![cfg_attr(thiserror_nightly_testing, feature(backtrace))]
-#![deny(clippy::all, clippy::pedantic)]
+#![cfg_attr(
+ thiserror_nightly_testing,
+ feature(error_generic_member_access, provide_any)
+)]
#[cfg(thiserror_nightly_testing)]
pub mod structs {
diff --git a/vendor/thiserror/tests/test_path.rs b/vendor/thiserror/tests/test_path.rs
index a10b1f342..a34a3d74e 100644
--- a/vendor/thiserror/tests/test_path.rs
+++ b/vendor/thiserror/tests/test_path.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
use ref_cast::RefCast;
use std::fmt::Display;
use std::path::{Path, PathBuf};
diff --git a/vendor/thiserror/tests/test_source.rs b/vendor/thiserror/tests/test_source.rs
index ab16097b2..637f4ac0a 100644
--- a/vendor/thiserror/tests/test_source.rs
+++ b/vendor/thiserror/tests/test_source.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
use std::error::Error as StdError;
use std::io;
use thiserror::Error;
diff --git a/vendor/thiserror/tests/test_transparent.rs b/vendor/thiserror/tests/test_transparent.rs
index 84d7c9189..6f3c03ec7 100644
--- a/vendor/thiserror/tests/test_transparent.rs
+++ b/vendor/thiserror/tests/test_transparent.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
use anyhow::anyhow;
use std::error::Error as _;
use std::io;
diff --git a/vendor/thiserror/tests/ui/concat-display.stderr b/vendor/thiserror/tests/ui/concat-display.stderr
index 6ab40481f..dbecd69f2 100644
--- a/vendor/thiserror/tests/ui/concat-display.stderr
+++ b/vendor/thiserror/tests/ui/concat-display.stderr
@@ -5,6 +5,6 @@ error: expected string literal
| ^^^^^^
...
13 | error_type!(Error, "foo");
- | -------------------------- in this macro invocation
+ | ------------------------- in this macro invocation
|
= note: this error originates in the macro `error_type` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/thiserror/tests/ui/from-backtrace-backtrace.rs b/vendor/thiserror/tests/ui/from-backtrace-backtrace.rs
new file mode 100644
index 000000000..8f411bf5d
--- /dev/null
+++ b/vendor/thiserror/tests/ui/from-backtrace-backtrace.rs
@@ -0,0 +1,10 @@
+// https://github.com/dtolnay/thiserror/issues/163
+
+use std::backtrace::Backtrace;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct Error(#[from] #[backtrace] std::io::Error, Backtrace);
+
+fn main() {}
diff --git a/vendor/thiserror/tests/ui/from-backtrace-backtrace.stderr b/vendor/thiserror/tests/ui/from-backtrace-backtrace.stderr
new file mode 100644
index 000000000..55d647b42
--- /dev/null
+++ b/vendor/thiserror/tests/ui/from-backtrace-backtrace.stderr
@@ -0,0 +1,5 @@
+error: deriving From requires no fields other than source and backtrace
+ --> tests/ui/from-backtrace-backtrace.rs:8:18
+ |
+8 | pub struct Error(#[from] #[backtrace] std::io::Error, Backtrace);
+ | ^^^^^^^
diff --git a/vendor/thiserror/tests/ui/no-display.stderr b/vendor/thiserror/tests/ui/no-display.stderr
index e6a52f5e7..82c3eea1c 100644
--- a/vendor/thiserror/tests/ui/no-display.stderr
+++ b/vendor/thiserror/tests/ui/no-display.stderr
@@ -2,7 +2,7 @@ error[E0599]: the method `as_display` exists for reference `&NoDisplay`, but its
--> tests/ui/no-display.rs:7:9
|
4 | struct NoDisplay;
- | ----------------- doesn't satisfy `NoDisplay: std::fmt::Display`
+ | ---------------- doesn't satisfy `NoDisplay: std::fmt::Display`
...
7 | #[error("thread: {thread}")]
| ^^^^^^^^^^^^^^^^^^ method cannot be called on `&NoDisplay` due to unsatisfied trait bounds
@@ -13,11 +13,5 @@ error[E0599]: the method `as_display` exists for reference `&NoDisplay`, but its
note: the following trait must be implemented
--> $RUST/core/src/fmt/mod.rs
|
- | / pub trait Display {
- | | /// Formats the value using the given formatter.
- | | ///
- | | /// # Examples
-... |
- | | fn fmt(&self, f: &mut Formatter<'_>) -> Result;
- | | }
- | |_^
+ | pub trait Display {
+ | ^^^^^^^^^^^^^^^^^
diff --git a/vendor/thiserror/tests/ui/source-enum-not-error.stderr b/vendor/thiserror/tests/ui/source-enum-not-error.stderr
index d01cba5b0..da10c6e77 100644
--- a/vendor/thiserror/tests/ui/source-enum-not-error.stderr
+++ b/vendor/thiserror/tests/ui/source-enum-not-error.stderr
@@ -1,28 +1,22 @@
error[E0599]: the method `as_dyn_error` exists for reference `&NotError`, but its trait bounds were not satisfied
- --> tests/ui/source-enum-not-error.rs:10:9
- |
-4 | pub struct NotError;
- | --------------------
- | |
- | doesn't satisfy `NotError: AsDynError`
- | doesn't satisfy `NotError: std::error::Error`
+ --> tests/ui/source-enum-not-error.rs:10:9
+ |
+4 | pub struct NotError;
+ | -------------------
+ | |
+ | doesn't satisfy `NotError: AsDynError`
+ | doesn't satisfy `NotError: std::error::Error`
...
-10 | source: NotError,
- | ^^^^^^ method cannot be called on `&NotError` due to unsatisfied trait bounds
- |
- = note: the following trait bounds were not satisfied:
- `NotError: std::error::Error`
- which is required by `NotError: AsDynError`
- `&NotError: std::error::Error`
- which is required by `&NotError: AsDynError`
+10 | source: NotError,
+ | ^^^^^^ method cannot be called on `&NotError` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `NotError: std::error::Error`
+ which is required by `NotError: AsDynError`
+ `&NotError: std::error::Error`
+ which is required by `&NotError: AsDynError`
note: the following trait must be implemented
- --> $RUST/std/src/error.rs
- |
- | / pub trait Error: Debug + Display {
- | | /// The lower-level source of this error, if any.
- | | ///
- | | /// # Examples
-... |
- | | }
- | | }
- | |_^
+ --> $RUST/core/src/error.rs
+ |
+ | pub trait Error: Debug + Display {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/vendor/thiserror/tests/ui/source-struct-not-error.stderr b/vendor/thiserror/tests/ui/source-struct-not-error.stderr
index be1331a50..cc0e67aca 100644
--- a/vendor/thiserror/tests/ui/source-struct-not-error.stderr
+++ b/vendor/thiserror/tests/ui/source-struct-not-error.stderr
@@ -1,27 +1,21 @@
error[E0599]: the method `as_dyn_error` exists for struct `NotError`, but its trait bounds were not satisfied
- --> tests/ui/source-struct-not-error.rs:9:5
- |
-4 | struct NotError;
- | ----------------
- | |
- | method `as_dyn_error` not found for this
- | doesn't satisfy `NotError: AsDynError`
- | doesn't satisfy `NotError: std::error::Error`
+ --> tests/ui/source-struct-not-error.rs:9:5
+ |
+4 | struct NotError;
+ | ---------------
+ | |
+ | method `as_dyn_error` not found for this struct
+ | doesn't satisfy `NotError: AsDynError`
+ | doesn't satisfy `NotError: std::error::Error`
...
-9 | source: NotError,
- | ^^^^^^ method cannot be called on `NotError` due to unsatisfied trait bounds
- |
- = note: the following trait bounds were not satisfied:
- `NotError: std::error::Error`
- which is required by `NotError: AsDynError`
+9 | source: NotError,
+ | ^^^^^^ method cannot be called on `NotError` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `NotError: std::error::Error`
+ which is required by `NotError: AsDynError`
note: the following trait must be implemented
- --> $RUST/std/src/error.rs
- |
- | / pub trait Error: Debug + Display {
- | | /// The lower-level source of this error, if any.
- | | ///
- | | /// # Examples
-... |
- | | }
- | | }
- | |_^
+ --> $RUST/core/src/error.rs
+ |
+ | pub trait Error: Debug + Display {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/vendor/tracing-core/.cargo-checksum.json b/vendor/tracing-core/.cargo-checksum.json
index 157a61ad4..c51d0e671 100644
--- a/vendor/tracing-core/.cargo-checksum.json
+++ b/vendor/tracing-core/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"291325b2d5ae0101a9cb9dadfa64810c1c98d04f43c7c1fcee4dc585cb34cf37","Cargo.toml":"d4029f638b3bbb553470ab93080fe78a155db13780e8e52d073d6ca10939614d","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"31f1a3504716da08f771f2fd10e06298a1fd6ecfdc2c78fd1cd66cce693d4e1c","src/callsite.rs":"6a69e08ba8e70234f4ca2a5c6215cdb5ce8d1b0e637102501787169448cbf2a1","src/dispatcher.rs":"5ffade623f3f19a7c497bc72da2d15fcdbd1ab65b1f393c9a9271dd742d99867","src/event.rs":"f2673bf5d266972e567e521c9cd92fb33f28b0c7e010937e3bc2bf9eb483087f","src/field.rs":"ec7f20bdb7a9d79b900777fc444ce82282bdfc4be4afe6223e2b7617da63964d","src/lazy.rs":"318e3558e4446abf26294287167c0788e343044a28072f9217bd985929809087","src/lib.rs":"088b29ecce4bdb5b68df9cbe3984f4b22d7124988866d5aace0e7029ea033d58","src/metadata.rs":"1019ffecd3d8a3636708c6654f34074c041af88b6221c4950037c6bbf09af835","src/parent.rs":"5d5ad733343280a64a1feb6a008e186c39305ec554f14279012b8d7915821471","src/span.rs":"dcf2135e4ca158c1be45007f0be25426c375a4081f8f3c5a4d7f7382d8a950a4","src/spin/LICENSE":"58545fed1565e42d687aecec6897d35c6d37ccb71479a137c0deb2203e125c79","src/spin/mod.rs":"c458ce5e875acb7fbfb279f23254f4924d7c6d6fee419b740800d2e8087d1524","src/spin/mutex.rs":"4d30ff2b59b18fd7909f016e1abdf9aa0c04aa11d047a46e98cffe1319e32dad","src/spin/once.rs":"3781fd4eae0db04d80c03a039906c99b1e01d1583b29ac0144e6fbbd5a0fef0b","src/stdlib.rs":"698693062b8109cace3ffea02e9c2372b7d5b5d43c0b11cb4800b0e7b1a69971","src/subscriber.rs":"916d315ca324a752f70fc3cc557089418a63779ceda54955f55f0ab3c1f3fc7b","tests/common/mod.rs":"0bbb217baa17df0f96cc1ff57dfa74ccc5a959e7f66b15bb7d25d5f43358a278","tests/dispatch.rs":"d3f000fab43734a854c82a7783142910c5e79f806cbd3f8ec5eded598c59ddb1","tests/global_dispatch.rs":"cdc05d77e448ee8b50bfb930abafa3f19b4c6f922b7bebc7797fa1dbdaa1d398","tests/macros.rs":"b1603d888b349c8d103794deceec3b1ae4538b8d3eba805f3f561899e8ad0dd2"},"package":"7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"10eae751c81a268b6118e2dea49d0d501ea4d2a69ece6350232f3800407ab2d3","Cargo.toml":"d29fae6d4ae043c79697e4305224fb8f65279515e1db6ad1211ccd27d073287f","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"f40e479c4d837f4fec140b0f4adad7aae062d55b53708f2255b93217f19d22a9","src/callsite.rs":"f5e9cdaed7fdc75dad5da6486af0ea6e9be896ab5fc1b44c49a90b8b88b33d53","src/dispatcher.rs":"1d129a0c3af976669787733101c2ce7d2f9eca794deeb2ae5a662085e966e0cf","src/event.rs":"f2673bf5d266972e567e521c9cd92fb33f28b0c7e010937e3bc2bf9eb483087f","src/field.rs":"4ec913012ffcf05d3feba2a5ea2ba99c35e2072dabfa2db75614c0e122961b7e","src/lazy.rs":"318e3558e4446abf26294287167c0788e343044a28072f9217bd985929809087","src/lib.rs":"088b29ecce4bdb5b68df9cbe3984f4b22d7124988866d5aace0e7029ea033d58","src/metadata.rs":"1a79326aee210b9e20eb08d5baa22133390f2b1e868cf4dc72a3e9bc9a37d17f","src/parent.rs":"5d5ad733343280a64a1feb6a008e186c39305ec554f14279012b8d7915821471","src/span.rs":"dcf2135e4ca158c1be45007f0be25426c375a4081f8f3c5a4d7f7382d8a950a4","src/spin/LICENSE":"58545fed1565e42d687aecec6897d35c6d37ccb71479a137c0deb2203e125c79","src/spin/mod.rs":"c458ce5e875acb7fbfb279f23254f4924d7c6d6fee419b740800d2e8087d1524","src/spin/mutex.rs":"4d30ff2b59b18fd7909f016e1abdf9aa0c04aa11d047a46e98cffe1319e32dad","src/spin/once.rs":"3781fd4eae0db04d80c03a039906c99b1e01d1583b29ac0144e6fbbd5a0fef0b","src/stdlib.rs":"698693062b8109cace3ffea02e9c2372b7d5b5d43c0b11cb4800b0e7b1a69971","src/subscriber.rs":"916d315ca324a752f70fc3cc557089418a63779ceda54955f55f0ab3c1f3fc7b","tests/common/mod.rs":"0bbb217baa17df0f96cc1ff57dfa74ccc5a959e7f66b15bb7d25d5f43358a278","tests/dispatch.rs":"d3f000fab43734a854c82a7783142910c5e79f806cbd3f8ec5eded598c59ddb1","tests/global_dispatch.rs":"cdc05d77e448ee8b50bfb930abafa3f19b4c6f922b7bebc7797fa1dbdaa1d398","tests/macros.rs":"b1603d888b349c8d103794deceec3b1ae4538b8d3eba805f3f561899e8ad0dd2"},"package":"5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"} \ No newline at end of file
diff --git a/vendor/tracing-core/CHANGELOG.md b/vendor/tracing-core/CHANGELOG.md
index c6afcb077..2db8553c9 100644
--- a/vendor/tracing-core/CHANGELOG.md
+++ b/vendor/tracing-core/CHANGELOG.md
@@ -1,3 +1,26 @@
+# 0.1.29 (July 29, 2022)
+
+This release of `tracing-core` adds `PartialEq` and `Eq` implementations for
+metadata types, and improves error messages when setting the global default
+subscriber fails.
+
+### Added
+
+- `PartialEq` and `Eq` implementations for `Metadata` ([#2229])
+- `PartialEq` and `Eq` implementations for `FieldSet` ([#2229])
+
+### Fixed
+
+- Fixed unhelpful `fmt::Debug` output for `dispatcher::SetGlobalDefaultError`
+ ([#2250])
+- Fixed compilation with `-Z minimal-versions` ([#2246])
+
+Thanks to @jswrenn and @CAD97 for contributing to this release!
+
+[#2229]: https://github.com/tokio-rs/tracing/pull/2229
+[#2246]: https://github.com/tokio-rs/tracing/pull/2246
+[#2250]: https://github.com/tokio-rs/tracing/pull/2250
+
# 0.1.28 (June 23, 2022)
This release of `tracing-core` adds new `Value` implementations, including one
diff --git a/vendor/tracing-core/Cargo.toml b/vendor/tracing-core/Cargo.toml
index 40d797d54..957194d39 100644
--- a/vendor/tracing-core/Cargo.toml
+++ b/vendor/tracing-core/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.49.0"
name = "tracing-core"
-version = "0.1.28"
+version = "0.1.29"
authors = ["Tokio Contributors <team@tokio.rs>"]
description = """
Core primitives for application-level tracing.
@@ -47,7 +47,7 @@ rustc-args = [
]
[dependencies.once_cell]
-version = "1.12"
+version = "1.13.0"
optional = true
[features]
@@ -60,7 +60,7 @@ std = ["once_cell"]
[target."cfg(tracing_unstable)".dependencies.valuable]
version = "0.1.0"
optional = true
-default_features = false
+default-features = false
[badges.maintenance]
status = "actively-developed"
diff --git a/vendor/tracing-core/README.md b/vendor/tracing-core/README.md
index f3afec07e..c6f7b0333 100644
--- a/vendor/tracing-core/README.md
+++ b/vendor/tracing-core/README.md
@@ -16,9 +16,9 @@ Core primitives for application-level tracing.
[Documentation][docs-url] | [Chat][discord-url]
[crates-badge]: https://img.shields.io/crates/v/tracing-core.svg
-[crates-url]: https://crates.io/crates/tracing-core/0.1.28
+[crates-url]: https://crates.io/crates/tracing-core/0.1.29
[docs-badge]: https://docs.rs/tracing-core/badge.svg
-[docs-url]: https://docs.rs/tracing-core/0.1.28
+[docs-url]: https://docs.rs/tracing-core/0.1.29
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
[docs-master-url]: https://tracing-rs.netlify.com/tracing_core
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
@@ -79,22 +79,22 @@ The following crate feature flags are available:
```toml
[dependencies]
- tracing-core = { version = "0.1.28", default-features = false }
+ tracing-core = { version = "0.1.29", default-features = false }
```
**Note**:`tracing-core`'s `no_std` support requires `liballoc`.
[`tracing`]: ../tracing
-[`span::Id`]: https://docs.rs/tracing-core/0.1.28/tracing_core/span/struct.Id.html
-[`Event`]: https://docs.rs/tracing-core/0.1.28/tracing_core/event/struct.Event.html
-[`Subscriber`]: https://docs.rs/tracing-core/0.1.28/tracing_core/subscriber/trait.Subscriber.html
-[`Metadata`]: https://docs.rs/tracing-core/0.1.28/tracing_core/metadata/struct.Metadata.html
-[`Callsite`]: https://docs.rs/tracing-core/0.1.28/tracing_core/callsite/trait.Callsite.html
-[`Field`]: https://docs.rs/tracing-core/0.1.28/tracing_core/field/struct.Field.html
-[`FieldSet`]: https://docs.rs/tracing-core/0.1.28/tracing_core/field/struct.FieldSet.html
-[`Value`]: https://docs.rs/tracing-core/0.1.28/tracing_core/field/trait.Value.html
-[`ValueSet`]: https://docs.rs/tracing-core/0.1.28/tracing_core/field/struct.ValueSet.html
-[`Dispatch`]: https://docs.rs/tracing-core/0.1.28/tracing_core/dispatcher/struct.Dispatch.html
+[`span::Id`]: https://docs.rs/tracing-core/0.1.29/tracing_core/span/struct.Id.html
+[`Event`]: https://docs.rs/tracing-core/0.1.29/tracing_core/event/struct.Event.html
+[`Subscriber`]: https://docs.rs/tracing-core/0.1.29/tracing_core/subscriber/trait.Subscriber.html
+[`Metadata`]: https://docs.rs/tracing-core/0.1.29/tracing_core/metadata/struct.Metadata.html
+[`Callsite`]: https://docs.rs/tracing-core/0.1.29/tracing_core/callsite/trait.Callsite.html
+[`Field`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/struct.Field.html
+[`FieldSet`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/struct.FieldSet.html
+[`Value`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/trait.Value.html
+[`ValueSet`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/struct.ValueSet.html
+[`Dispatch`]: https://docs.rs/tracing-core/0.1.29/tracing_core/dispatcher/struct.Dispatch.html
## Supported Rust Versions
diff --git a/vendor/tracing-core/src/callsite.rs b/vendor/tracing-core/src/callsite.rs
index d0fe1a3d6..bc7405ffa 100644
--- a/vendor/tracing-core/src/callsite.rs
+++ b/vendor/tracing-core/src/callsite.rs
@@ -137,6 +137,15 @@ pub trait Callsite: Sync {
/// Returns the [metadata] associated with the callsite.
///
+ /// <div class="example-wrap" style="display:inline-block">
+ /// <pre class="ignore" style="white-space:normal;font:inherit;">
+ ///
+ /// **Note:** Implementations of this method should not produce [`Metadata`]
+ /// that share the same callsite [`Identifier`] but otherwise differ in any
+ /// way (e.g., have different `name`s).
+ ///
+ /// </pre></div>
+ ///
/// [metadata]: super::metadata::Metadata
fn metadata(&self) -> &Metadata<'_>;
diff --git a/vendor/tracing-core/src/dispatcher.rs b/vendor/tracing-core/src/dispatcher.rs
index 041722c36..a3661817c 100644
--- a/vendor/tracing-core/src/dispatcher.rs
+++ b/vendor/tracing-core/src/dispatcher.rs
@@ -293,14 +293,21 @@ pub fn has_been_set() -> bool {
}
/// Returned if setting the global dispatcher fails.
-#[derive(Debug)]
pub struct SetGlobalDefaultError {
_no_construct: (),
}
+impl fmt::Debug for SetGlobalDefaultError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("SetGlobalDefaultError")
+ .field(&Self::MESSAGE)
+ .finish()
+ }
+}
+
impl fmt::Display for SetGlobalDefaultError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.pad("a global default trace dispatcher has already been set")
+ f.pad(Self::MESSAGE)
}
}
@@ -308,6 +315,10 @@ impl fmt::Display for SetGlobalDefaultError {
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl error::Error for SetGlobalDefaultError {}
+impl SetGlobalDefaultError {
+ const MESSAGE: &'static str = "a global default trace dispatcher has already been set";
+}
+
/// Executes a closure with a reference to this thread's current [dispatcher].
///
/// Note that calls to `get_default` should not be nested; if this function is
diff --git a/vendor/tracing-core/src/field.rs b/vendor/tracing-core/src/field.rs
index c9869ce2c..e103c75a9 100644
--- a/vendor/tracing-core/src/field.rs
+++ b/vendor/tracing-core/src/field.rs
@@ -145,6 +145,16 @@ pub struct Field {
pub struct Empty;
/// Describes the fields present on a span.
+///
+/// ## Equality
+///
+/// In well-behaved applications, two `FieldSet`s [initialized] with equal
+/// [callsite identifiers] will have identical fields. Consequently, in release
+/// builds, [`FieldSet::eq`] *only* checks that its arguments have equal
+/// callsites. However, the equality of field names is checked in debug builds.
+///
+/// [initialized]: Self::new
+/// [callsite identifiers]: callsite::Identifier
pub struct FieldSet {
/// The names of each field on the described span.
names: &'static [&'static str],
@@ -911,6 +921,40 @@ impl fmt::Display for FieldSet {
}
}
+impl Eq for FieldSet {}
+
+impl PartialEq for FieldSet {
+ fn eq(&self, other: &Self) -> bool {
+ if core::ptr::eq(&self, &other) {
+ true
+ } else if cfg!(not(debug_assertions)) {
+ // In a well-behaving application, two `FieldSet`s can be assumed to
+ // be totally equal so long as they share the same callsite.
+ self.callsite == other.callsite
+ } else {
+ // However, when debug-assertions are enabled, do NOT assume that
+ // the application is well-behaving; check every the field names of
+ // each `FieldSet` for equality.
+
+ // `FieldSet` is destructured here to ensure a compile-error if the
+ // fields of `FieldSet` change.
+ let Self {
+ names: lhs_names,
+ callsite: lhs_callsite,
+ } = self;
+
+ let Self {
+ names: rhs_names,
+ callsite: rhs_callsite,
+ } = &other;
+
+ // Check callsite equality first, as it is probably cheaper to do
+ // than str equality.
+ lhs_callsite == rhs_callsite && lhs_names == rhs_names
+ }
+ }
+}
+
// ===== impl Iter =====
impl Iterator for Iter {
diff --git a/vendor/tracing-core/src/metadata.rs b/vendor/tracing-core/src/metadata.rs
index 47b9388a4..a154419a7 100644
--- a/vendor/tracing-core/src/metadata.rs
+++ b/vendor/tracing-core/src/metadata.rs
@@ -35,28 +35,25 @@ use crate::stdlib::{
/// _significantly_ lower than that of creating the actual span. Therefore,
/// filtering is based on metadata, rather than on the constructed span.
///
-/// <pre class="ignore" style="white-space:normal;font:inherit;">
-/// <strong>Note</strong>: Although instances of <code>Metadata</code>
-/// cannot be compared directly, they provide a method
-/// <a href="struct.Metadata.html#method.id"><code>id</code></a>, returning
-/// an opaque <a href="../callsite/struct.Identifier.html">callsite
-/// identifier</a>which uniquely identifies the callsite where the metadata
-/// originated. This can be used to determine if two <code>Metadata</code>
-/// correspond to the same callsite.
-/// </pre>
+/// ## Equality
+///
+/// In well-behaved applications, two `Metadata` with equal
+/// [callsite identifiers] will be equal in all other ways (i.e., have the same
+/// `name`, `target`, etc.). Consequently, in release builds, [`Metadata::eq`]
+/// *only* checks that its arguments have equal callsites. However, the equality
+/// of `Metadata`'s other fields is checked in debug builds.
///
/// [span]: super::span
/// [event]: super::event
-/// [name]: Metadata::name()
-/// [target]: Metadata::target()
-/// [fields]: Metadata::fields()
-/// [verbosity level]: Metadata::level()
-/// [file name]: Metadata::file()
-/// [line number]: Metadata::line()
-/// [module path]: Metadata::module_path()
+/// [name]: Self::name
+/// [target]: Self::target
+/// [fields]: Self::fields
+/// [verbosity level]: Self::level
+/// [file name]: Self::file
+/// [line number]: Self::line
+/// [module path]: Self::module_path
/// [`Subscriber`]: super::subscriber::Subscriber
-/// [`id`]: Metadata::id
-/// [callsite identifier]: super::callsite::Identifier
+/// [callsite identifiers]: Self::callsite
pub struct Metadata<'a> {
/// The name of the span described by this metadata.
name: &'static str,
@@ -443,6 +440,62 @@ impl fmt::Debug for Kind {
}
}
+impl<'a> Eq for Metadata<'a> {}
+
+impl<'a> PartialEq for Metadata<'a> {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ if core::ptr::eq(&self, &other) {
+ true
+ } else if cfg!(not(debug_assertions)) {
+ // In a well-behaving application, two `Metadata` can be assumed to
+ // be totally equal so long as they share the same callsite.
+ self.callsite() == other.callsite()
+ } else {
+ // However, when debug-assertions are enabled, do not assume that
+ // the application is well-behaving; check every field of `Metadata`
+ // for equality.
+
+ // `Metadata` is destructured here to ensure a compile-error if the
+ // fields of `Metadata` change.
+ let Metadata {
+ name: lhs_name,
+ target: lhs_target,
+ level: lhs_level,
+ module_path: lhs_module_path,
+ file: lhs_file,
+ line: lhs_line,
+ fields: lhs_fields,
+ kind: lhs_kind,
+ } = self;
+
+ let Metadata {
+ name: rhs_name,
+ target: rhs_target,
+ level: rhs_level,
+ module_path: rhs_module_path,
+ file: rhs_file,
+ line: rhs_line,
+ fields: rhs_fields,
+ kind: rhs_kind,
+ } = &other;
+
+ // The initial comparison of callsites is purely an optimization;
+ // it can be removed without affecting the overall semantics of the
+ // expression.
+ self.callsite() == other.callsite()
+ && lhs_name == rhs_name
+ && lhs_target == rhs_target
+ && lhs_level == rhs_level
+ && lhs_module_path == rhs_module_path
+ && lhs_file == rhs_file
+ && lhs_line == rhs_line
+ && lhs_fields == rhs_fields
+ && lhs_kind == rhs_kind
+ }
+ }
+}
+
// ===== impl Level =====
impl Level {
diff --git a/vendor/tracing-subscriber/.cargo-checksum.json b/vendor/tracing-subscriber/.cargo-checksum.json
index 509cf43fc..6c6c14337 100644
--- a/vendor/tracing-subscriber/.cargo-checksum.json
+++ b/vendor/tracing-subscriber/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"29fe135a995cb47126440183c4d42f842ad08ec0b3796a701f28cc83991b73b8","Cargo.toml":"62d5ba5d1eef80f27e41b45b3d9bde666143ab488b39e2f675774855142e0022","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"5ea57d24ff4451b10feb2689f1046d8d43bf6af4ee60285e676dfd1a586c65db","benches/enter.rs":"4a94a04e2abd07950ef2f0b646f4dcdf4ff00abf6396edb5a53c8b41b7691b1a","benches/filter.rs":"6374005ffa47fa19880bb95e3e37406f40ea72a02c5136f4d5eb4c663d452b18","benches/filter_log.rs":"612716bdf9a188093e84d014a4847f18157f148f7d64e54150cd5c91ac709a8a","benches/fmt.rs":"5a0ff37967ffef3a221eebb78855d031e2e883a8a67528c8e794cc6f16cbee8a","benches/support/mod.rs":"72bef51154da9c9b3d81300195c1929a818858fa4b4fc2aa07b49ca586f4cd39","src/field/debug.rs":"4ab50198a0b042d92fefa77b5cac0aef7ba6936149fa555f4b6e2036dcd7f2d7","src/field/delimited.rs":"5e7967637dc3181c097637dcb2a95f35db16583b5fc293b30211db5779ab21ab","src/field/display.rs":"da8cfcb22a39f451f075e2c3a9ce5193c6afe19853cdbd643239657cac5b7e47","src/field/mod.rs":"cb8ab273159f42fc8ebe71c82acc63c962e546328fc4aa9fd5948ce996ef9e05","src/filter/directive.rs":"6341c3a1c8b6d33171647964c35816317c81b03bb098b493f1f1a22222f6ce84","src/filter/env/builder.rs":"8f527b1b0e3d9c572046235e0304146a574fe114b757af90a1c07851a07ba2cf","src/filter/env/directive.rs":"ecd2a7ffb882869f8ea9b0398f5af58ce1797a216b9dc9086c21363d1d500e77","src/filter/env/field.rs":"e1e32a2fc39884c9a5df1d5047128e43f1d0720c0b9daa6bf1e08ca9bcc5f537","src/filter/env/mod.rs":"8403df3f061a1c266b6ab6b30b03c6eb32c1c9354037a2d1eeb36817932e6ea5","src/filter/filter_fn.rs":"0debbc4a4b4d2a57b2a06905017ac908bf34b0a64aaf961535fbf6f4d5a700a9","src/filter/layer_filters/combinator.rs":"abf90b8d7a21486b28f20d4b648395b2b95a35b526bbdaba63bd2c0181ae9e87","src/filter/layer_filters/mod.rs":"2046a860b21751791dae61d20219b3d59049b84fb289ea1fca7796d214c5643c","src/filter/level.rs":"cc449757aac47caaf19dd5ba4d74c8efbcd7531fcd6c13da0c5f6fdda12cc9ca","src/filter/mod.rs":"8ebfd0dc92415ff27ec552f20919e598842a87186f13f120449053a96e1e3307","src/filter/targets.rs":"eaa11d620017269770da5b2b97302b3beb81187242912260ca98e6d60ea77780","src/fmt/fmt_layer.rs":"5042d3e2eba5f68e9041c94b52f26ab17b84f68c54d16e4c0edd9d3a3699f727","src/fmt/format/json.rs":"554985ed40f7c59787aae87626144241ca973929e33979c54f821b673b71fec9","src/fmt/format/mod.rs":"a5f6b879802d353192235cf85aa8653afa3e8ead09955e631a39415324ce42d2","src/fmt/format/pretty.rs":"30fac9a916f3b9f572efa3b650c6dab7d86a57ce903cdbba6c6c0a52064cf238","src/fmt/mod.rs":"d5274d1f8106dc7497d2be7c6d874aeca15b9ca0fd4e0c6775d3774e75b30099","src/fmt/time/datetime.rs":"778d4604d800e46b940087394e7b72750738b554e02aea523fa9820ab0768c08","src/fmt/time/mod.rs":"30c97a9d3abd099f52c4c91c7b5f0d29ed9d54d80d1718c6fb74bfd664589de1","src/fmt/time/time_crate.rs":"1bfd59516a583e396afc1770250aa8c06b52f6162a6e7b2cadb860b7eebd9d76","src/fmt/writer.rs":"1931125cf14019b66b42a9ff95e5794f344697f799c021b4a7d48fd7eb7b58f4","src/layer/context.rs":"77137d8b2810c9059ce7838c3b665748bcb9765487d6103b92596e08b0e9e84b","src/layer/layered.rs":"945e42296ce3e86aa405eb31efdef4346cdfd84111f36700cc73e473e3ce5b28","src/layer/mod.rs":"b4febff42ea5ae12b92b8c73b7c691d9486e671446da99669fc5348314721cc9","src/layer/tests.rs":"3e974d627c4bc4269cfa10c82c890e596c9d46af8e6bc03c6c117bde1237e948","src/lib.rs":"bbe402c3ff042550b265976a688a0e3a95ac9ece77f290992e93fd2f51643f5c","src/macros.rs":"e184bffc6b5999c48e365ad08343dca764a5fb711b789beb26bd1d5f1d767726","src/prelude.rs":"088635def33be9a4c4b6ed934dc22540c555e27d62f7625a43aa9c0e525ca467","src/registry/extensions.rs":"0418b39287bbc06cc95b8cecd6a25aa808b8e04714d842340ff75db458cafe5b","src/registry/mod.rs":"76627b056ce39d006708a6273b6418d001b688f016f58aa546e7821d1ef7f3bb","src/registry/sharded.rs":"aaac353632b1bbb804048b40cdfce9877688efa0679ae42ab36a095fd3e3877f","src/registry/stack.rs":"9ef333d6a8a28a064e80ff1e376dbb07bc597009010ec332b2dc3ab435d737c2","src/reload.rs":"478f7612e19fa606cfa16f2791e426267256fe5799c3918b57209d3ebfa70406","src/sync.rs":"7f78f3de5b618a999be0e61f936a233975e7769f1ebb55a0e48c3d199e9c45e3","src/util.rs":"55b4e9d63112f9d5a12a287273a9b1212741058384332d3edc024168cacfd627","tests/cached_layer_filters_dont_break_other_layers.rs":"b2084542a014abeff821b30b2b8c21e32bfdcffae53ce5335fb588f557fa4244","tests/duplicate_spans.rs":"3bf35184fb7d1dc5f33e5098820febbec37ef3ccd06b693d11b5585affb60ff4","tests/env_filter/main.rs":"b2d89ee7aaf94f0563e4e5b025cf43186ec61657b763b7c0ae010ff548635251","tests/env_filter/per_layer.rs":"19e9998922f24ec368fcbcda406f43a95335551c4c1669b509bbfc1ef216432a","tests/event_enabling.rs":"15e301a8ff6c74c454547dad15a47b5f11fc54e539162191f21462b6d5080830","tests/field_filter.rs":"fb8735801ba7ecabb421ca361bd1c846841aee63eecbdd665f9544a1cec70f67","tests/filter_log.rs":"086f1e708a2e7389024d7e36d963947909d94c1975db92f4fc425b5cba2af533","tests/fmt_max_level_hint.rs":"d4c6d6f976ae41ab8052fa610a7337ad7150802cbd5634cb30fc45c1f215cfcd","tests/hinted_layer_filters_dont_break_other_layers.rs":"d5ba9cfb6784cf59f007e673ad549dc722d109f6b3d4a69f6aa11b25ca10b469","tests/layer_filter_interests_are_cached.rs":"d036d1c4bc3754e94ebfdda9c841f4858ccec40aba0720f3fbf26c817bfe5a83","tests/layer_filters/boxed.rs":"04db459721a26d6502a2b3fbe42154c5a451021a9374a18c017d10971f44e0c0","tests/layer_filters/combinators.rs":"cdbfaa37fa5b0439ec2ae8028601d22120ff2a42867a2af8a3b27fc58e70cb6c","tests/layer_filters/downcast_raw.rs":"9b90ead571543cbe14e89b4fe637360d9baf3069f6f656ed3bdf65e7318648f1","tests/layer_filters/filter_scopes.rs":"02611bc58d0d8a67a127eca8cab1b2d9a9901bd2c8a8daad41adf6089b28aee0","tests/layer_filters/main.rs":"fe0ed219b79bcbb2ece4c224ee5bf05662fe3b23a224f746b273afdb1abc0fbd","tests/layer_filters/targets.rs":"138e3f9ddd68571d94c5aff9d54ee2fbc5f44724c6ee42477a411740ccb79ee6","tests/layer_filters/trees.rs":"4df7b5cf12da44a9255c56e5b80e2b0cf84820230ba916f324c67bc3ee4e4605","tests/layer_filters/vec.rs":"eaf2e7fe0a76633cc02bc729513202a5fb169e2bdb5a8042d8c7bd1f7092691d","tests/multiple_layer_filter_interests_cached.rs":"1ea195f03e58d715228ec1b604f85bda2fc82812d05b2f6370d5edd34a035f32","tests/option.rs":"071af56d21e1438b112c7698790328f4797d2d4dd4c7e4857ea8d4825f1fac89","tests/registry_max_level_hint.rs":"ba386d32b8d13832d7009163241c3d0723488c0393d85647eb9368776251e4fc","tests/registry_with_subscriber.rs":"61a545e1bf3f75efd0dd18c20bb93e8a1f2e0158b342179a94228c4cbd5bb9cc","tests/reload.rs":"9a1b0bcb838a0f11beb528db7e578f12cc26e1592236dd7c2fa849271025e72c","tests/same_len_filters.rs":"eceb745f7f5b6c8737c1860a58e2cf98a048fc486dee4379e94485f41c92c925","tests/support.rs":"d5d8ae7a143bda971e24dcba01137be0efea957d732b43502fd845c3bc952f8b","tests/unhinted_layer_filters_dont_break_other_layers.rs":"519cfef4977e511af938546d4208c645a28248c8ed8666daf180f0ad32f0a261","tests/utils.rs":"2c37d9f39010767190f72cb2b3faa3131985764aa547027197108299a9a6bb9e","tests/vec.rs":"d1176f3e1b0954129792a28282b95084d417143b0cc4e35887b95cee3c675392","tests/vec_subscriber_filter_interests_cached.rs":"115a0f097cd649c570eabe74f82791bbe15b2de32a2eef403575661798aadd82"},"package":"3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"299c9f1c6c293156f3d0b9cd203c676b40ae173c9b1c2ee32ad360c1c11351b7","Cargo.toml":"488b9c72556062f1b1a8eca5d98bbe369f2e54fb103e9a23a0c2885e4bb8a086","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"b34fd001abef8b8e1455ad0f1f5e8e13eb578aafc60ea877772adb4c2c9fc39a","benches/enter.rs":"4a94a04e2abd07950ef2f0b646f4dcdf4ff00abf6396edb5a53c8b41b7691b1a","benches/filter.rs":"6374005ffa47fa19880bb95e3e37406f40ea72a02c5136f4d5eb4c663d452b18","benches/filter_log.rs":"612716bdf9a188093e84d014a4847f18157f148f7d64e54150cd5c91ac709a8a","benches/fmt.rs":"5a0ff37967ffef3a221eebb78855d031e2e883a8a67528c8e794cc6f16cbee8a","benches/support/mod.rs":"72bef51154da9c9b3d81300195c1929a818858fa4b4fc2aa07b49ca586f4cd39","src/field/debug.rs":"4ab50198a0b042d92fefa77b5cac0aef7ba6936149fa555f4b6e2036dcd7f2d7","src/field/delimited.rs":"5e7967637dc3181c097637dcb2a95f35db16583b5fc293b30211db5779ab21ab","src/field/display.rs":"da8cfcb22a39f451f075e2c3a9ce5193c6afe19853cdbd643239657cac5b7e47","src/field/mod.rs":"cb8ab273159f42fc8ebe71c82acc63c962e546328fc4aa9fd5948ce996ef9e05","src/filter/directive.rs":"6341c3a1c8b6d33171647964c35816317c81b03bb098b493f1f1a22222f6ce84","src/filter/env/builder.rs":"8f527b1b0e3d9c572046235e0304146a574fe114b757af90a1c07851a07ba2cf","src/filter/env/directive.rs":"ecd2a7ffb882869f8ea9b0398f5af58ce1797a216b9dc9086c21363d1d500e77","src/filter/env/field.rs":"e1e32a2fc39884c9a5df1d5047128e43f1d0720c0b9daa6bf1e08ca9bcc5f537","src/filter/env/mod.rs":"8403df3f061a1c266b6ab6b30b03c6eb32c1c9354037a2d1eeb36817932e6ea5","src/filter/filter_fn.rs":"0debbc4a4b4d2a57b2a06905017ac908bf34b0a64aaf961535fbf6f4d5a700a9","src/filter/layer_filters/combinator.rs":"abf90b8d7a21486b28f20d4b648395b2b95a35b526bbdaba63bd2c0181ae9e87","src/filter/layer_filters/mod.rs":"2046a860b21751791dae61d20219b3d59049b84fb289ea1fca7796d214c5643c","src/filter/level.rs":"cc449757aac47caaf19dd5ba4d74c8efbcd7531fcd6c13da0c5f6fdda12cc9ca","src/filter/mod.rs":"8ebfd0dc92415ff27ec552f20919e598842a87186f13f120449053a96e1e3307","src/filter/targets.rs":"eaa11d620017269770da5b2b97302b3beb81187242912260ca98e6d60ea77780","src/fmt/fmt_layer.rs":"5042d3e2eba5f68e9041c94b52f26ab17b84f68c54d16e4c0edd9d3a3699f727","src/fmt/format/json.rs":"554985ed40f7c59787aae87626144241ca973929e33979c54f821b673b71fec9","src/fmt/format/mod.rs":"a5f6b879802d353192235cf85aa8653afa3e8ead09955e631a39415324ce42d2","src/fmt/format/pretty.rs":"30fac9a916f3b9f572efa3b650c6dab7d86a57ce903cdbba6c6c0a52064cf238","src/fmt/mod.rs":"d5274d1f8106dc7497d2be7c6d874aeca15b9ca0fd4e0c6775d3774e75b30099","src/fmt/time/datetime.rs":"778d4604d800e46b940087394e7b72750738b554e02aea523fa9820ab0768c08","src/fmt/time/mod.rs":"30c97a9d3abd099f52c4c91c7b5f0d29ed9d54d80d1718c6fb74bfd664589de1","src/fmt/time/time_crate.rs":"1bfd59516a583e396afc1770250aa8c06b52f6162a6e7b2cadb860b7eebd9d76","src/fmt/writer.rs":"1931125cf14019b66b42a9ff95e5794f344697f799c021b4a7d48fd7eb7b58f4","src/layer/context.rs":"77137d8b2810c9059ce7838c3b665748bcb9765487d6103b92596e08b0e9e84b","src/layer/layered.rs":"945e42296ce3e86aa405eb31efdef4346cdfd84111f36700cc73e473e3ce5b28","src/layer/mod.rs":"b4febff42ea5ae12b92b8c73b7c691d9486e671446da99669fc5348314721cc9","src/layer/tests.rs":"3e974d627c4bc4269cfa10c82c890e596c9d46af8e6bc03c6c117bde1237e948","src/lib.rs":"8c1a26a319318768432b1025a2d0b08544bf2698b0a278fbb07211e22b22cd73","src/macros.rs":"e184bffc6b5999c48e365ad08343dca764a5fb711b789beb26bd1d5f1d767726","src/prelude.rs":"088635def33be9a4c4b6ed934dc22540c555e27d62f7625a43aa9c0e525ca467","src/registry/extensions.rs":"0418b39287bbc06cc95b8cecd6a25aa808b8e04714d842340ff75db458cafe5b","src/registry/mod.rs":"76627b056ce39d006708a6273b6418d001b688f016f58aa546e7821d1ef7f3bb","src/registry/sharded.rs":"aaac353632b1bbb804048b40cdfce9877688efa0679ae42ab36a095fd3e3877f","src/registry/stack.rs":"9ef333d6a8a28a064e80ff1e376dbb07bc597009010ec332b2dc3ab435d737c2","src/reload.rs":"caec4e23cf879ccc7c16bccbc99e20b8a20e27565c4edc6c527e094b7d0bb097","src/sync.rs":"7f78f3de5b618a999be0e61f936a233975e7769f1ebb55a0e48c3d199e9c45e3","src/util.rs":"55b4e9d63112f9d5a12a287273a9b1212741058384332d3edc024168cacfd627","tests/cached_layer_filters_dont_break_other_layers.rs":"b2084542a014abeff821b30b2b8c21e32bfdcffae53ce5335fb588f557fa4244","tests/duplicate_spans.rs":"3bf35184fb7d1dc5f33e5098820febbec37ef3ccd06b693d11b5585affb60ff4","tests/env_filter/main.rs":"b2d89ee7aaf94f0563e4e5b025cf43186ec61657b763b7c0ae010ff548635251","tests/env_filter/per_layer.rs":"19e9998922f24ec368fcbcda406f43a95335551c4c1669b509bbfc1ef216432a","tests/event_enabling.rs":"15e301a8ff6c74c454547dad15a47b5f11fc54e539162191f21462b6d5080830","tests/field_filter.rs":"fb8735801ba7ecabb421ca361bd1c846841aee63eecbdd665f9544a1cec70f67","tests/filter_log.rs":"086f1e708a2e7389024d7e36d963947909d94c1975db92f4fc425b5cba2af533","tests/fmt_max_level_hint.rs":"d4c6d6f976ae41ab8052fa610a7337ad7150802cbd5634cb30fc45c1f215cfcd","tests/hinted_layer_filters_dont_break_other_layers.rs":"d5ba9cfb6784cf59f007e673ad549dc722d109f6b3d4a69f6aa11b25ca10b469","tests/layer_filter_interests_are_cached.rs":"d036d1c4bc3754e94ebfdda9c841f4858ccec40aba0720f3fbf26c817bfe5a83","tests/layer_filters/boxed.rs":"04db459721a26d6502a2b3fbe42154c5a451021a9374a18c017d10971f44e0c0","tests/layer_filters/combinators.rs":"cdbfaa37fa5b0439ec2ae8028601d22120ff2a42867a2af8a3b27fc58e70cb6c","tests/layer_filters/downcast_raw.rs":"9b90ead571543cbe14e89b4fe637360d9baf3069f6f656ed3bdf65e7318648f1","tests/layer_filters/filter_scopes.rs":"02611bc58d0d8a67a127eca8cab1b2d9a9901bd2c8a8daad41adf6089b28aee0","tests/layer_filters/main.rs":"fe0ed219b79bcbb2ece4c224ee5bf05662fe3b23a224f746b273afdb1abc0fbd","tests/layer_filters/targets.rs":"138e3f9ddd68571d94c5aff9d54ee2fbc5f44724c6ee42477a411740ccb79ee6","tests/layer_filters/trees.rs":"4df7b5cf12da44a9255c56e5b80e2b0cf84820230ba916f324c67bc3ee4e4605","tests/layer_filters/vec.rs":"eaf2e7fe0a76633cc02bc729513202a5fb169e2bdb5a8042d8c7bd1f7092691d","tests/multiple_layer_filter_interests_cached.rs":"1ea195f03e58d715228ec1b604f85bda2fc82812d05b2f6370d5edd34a035f32","tests/option.rs":"071af56d21e1438b112c7698790328f4797d2d4dd4c7e4857ea8d4825f1fac89","tests/registry_max_level_hint.rs":"ba386d32b8d13832d7009163241c3d0723488c0393d85647eb9368776251e4fc","tests/registry_with_subscriber.rs":"61a545e1bf3f75efd0dd18c20bb93e8a1f2e0158b342179a94228c4cbd5bb9cc","tests/reload.rs":"8f169b60ab67bbc171dd7e576236b901293b5baa08ea469765a042375855e0f4","tests/same_len_filters.rs":"eceb745f7f5b6c8737c1860a58e2cf98a048fc486dee4379e94485f41c92c925","tests/support.rs":"d5d8ae7a143bda971e24dcba01137be0efea957d732b43502fd845c3bc952f8b","tests/unhinted_layer_filters_dont_break_other_layers.rs":"519cfef4977e511af938546d4208c645a28248c8ed8666daf180f0ad32f0a261","tests/utils.rs":"2c37d9f39010767190f72cb2b3faa3131985764aa547027197108299a9a6bb9e","tests/vec.rs":"d1176f3e1b0954129792a28282b95084d417143b0cc4e35887b95cee3c675392","tests/vec_subscriber_filter_interests_cached.rs":"115a0f097cd649c570eabe74f82791bbe15b2de32a2eef403575661798aadd82"},"package":"60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"} \ No newline at end of file
diff --git a/vendor/tracing-subscriber/CHANGELOG.md b/vendor/tracing-subscriber/CHANGELOG.md
index 35747566e..e2ac4e7c3 100644
--- a/vendor/tracing-subscriber/CHANGELOG.md
+++ b/vendor/tracing-subscriber/CHANGELOG.md
@@ -1,3 +1,16 @@
+# 0.3.15 (Jul 20, 2022)
+
+This release fixes a bug where the `reload` layer would fail to pass through
+`max_level_hint` to the underlying layer, potentially breaking filtering.
+
+### Fixed
+
+- **reload**: pass through `max_level_hint` to the inner `Layer` ([#2204])
+
+Thanks to @guswynn for contributing to this release!
+
+[#2204]: https://github.com/tokio-rs/tracing/pull/2204
+
# 0.3.14 (Jul 1, 2022)
This release fixes multiple filtering bugs in the `Layer` implementations for
diff --git a/vendor/tracing-subscriber/Cargo.toml b/vendor/tracing-subscriber/Cargo.toml
index 1d15642a2..dd432c4ac 100644
--- a/vendor/tracing-subscriber/Cargo.toml
+++ b/vendor/tracing-subscriber/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.49.0"
name = "tracing-subscriber"
-version = "0.3.14"
+version = "0.3.15"
authors = [
"Eliza Weisman <eliza@buoyant.io>",
"David Barsky <me@davidbarsky.com>",
diff --git a/vendor/tracing-subscriber/README.md b/vendor/tracing-subscriber/README.md
index 95242b37e..ba2b4e1c3 100644
--- a/vendor/tracing-subscriber/README.md
+++ b/vendor/tracing-subscriber/README.md
@@ -21,7 +21,7 @@ Utilities for implementing and composing [`tracing`][tracing] subscribers.
[crates-badge]: https://img.shields.io/crates/v/tracing-subscriber.svg
[crates-url]: https://crates.io/crates/tracing-subscriber
[docs-badge]: https://docs.rs/tracing-subscriber/badge.svg
-[docs-url]: https://docs.rs/tracing-subscriber/0.3.14
+[docs-url]: https://docs.rs/tracing-subscriber/0.3.15
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
[docs-master-url]: https://tracing-rs.netlify.com/tracing_subscriber
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
diff --git a/vendor/tracing-subscriber/src/lib.rs b/vendor/tracing-subscriber/src/lib.rs
index 4bd61000e..9de70a90d 100644
--- a/vendor/tracing-subscriber/src/lib.rs
+++ b/vendor/tracing-subscriber/src/lib.rs
@@ -160,7 +160,7 @@
//! [`time` crate]: https://crates.io/crates/time
//! [`libstd`]: std
//! [`liballoc`]: alloc
-#![doc(html_root_url = "https://docs.rs/tracing-subscriber/0.3.14")]
+#![doc(html_root_url = "https://docs.rs/tracing-subscriber/0.3.15")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
diff --git a/vendor/tracing-subscriber/src/reload.rs b/vendor/tracing-subscriber/src/reload.rs
index 3d1743440..0c6c1c45c 100644
--- a/vendor/tracing-subscriber/src/reload.rs
+++ b/vendor/tracing-subscriber/src/reload.rs
@@ -75,7 +75,7 @@ use std::{
use tracing_core::{
callsite, span,
subscriber::{Interest, Subscriber},
- Event, Metadata,
+ Event, LevelFilter, Metadata,
};
/// Wraps a `Layer` or `Filter`, allowing it to be reloaded dynamically at runtime.
@@ -173,6 +173,11 @@ where
fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) {
try_lock!(self.inner.read()).on_id_change(old, new, ctx)
}
+
+ #[inline]
+ fn max_level_hint(&self) -> Option<LevelFilter> {
+ try_lock!(self.inner.read(), else return None).max_level_hint()
+ }
}
// ===== impl Filter =====
@@ -218,6 +223,11 @@ where
fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) {
try_lock!(self.inner.read()).on_close(id, ctx)
}
+
+ #[inline]
+ fn max_level_hint(&self) -> Option<LevelFilter> {
+ try_lock!(self.inner.read(), else return None).max_level_hint()
+ }
}
impl<L, S> Layer<L, S> {
diff --git a/vendor/tracing-subscriber/tests/reload.rs b/vendor/tracing-subscriber/tests/reload.rs
index b8b6c2b46..28662e2e6 100644
--- a/vendor/tracing-subscriber/tests/reload.rs
+++ b/vendor/tracing-subscriber/tests/reload.rs
@@ -1,13 +1,16 @@
-#![cfg(feature = "std")]
+#![cfg(feature = "registry")]
use std::sync::atomic::{AtomicUsize, Ordering};
use tracing_core::{
span::{Attributes, Id, Record},
subscriber::Interest,
- Event, Metadata, Subscriber,
+ Event, LevelFilter, Metadata, Subscriber,
};
use tracing_subscriber::{layer, prelude::*, reload::*};
pub struct NopSubscriber;
+fn event() {
+ tracing::info!("my event");
+}
impl Subscriber for NopSubscriber {
fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest {
@@ -53,9 +56,13 @@ fn reload_handle() {
};
true
}
- }
- fn event() {
- tracing::trace!("my event");
+
+ fn max_level_hint(&self) -> Option<LevelFilter> {
+ match self {
+ Filter::One => Some(LevelFilter::INFO),
+ Filter::Two => Some(LevelFilter::DEBUG),
+ }
+ }
}
let (layer, handle) = Layer::new(Filter::One);
@@ -71,7 +78,9 @@ fn reload_handle() {
assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1);
assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0);
+ assert_eq!(LevelFilter::current(), LevelFilter::INFO);
handle.reload(Filter::Two).expect("should reload");
+ assert_eq!(LevelFilter::current(), LevelFilter::DEBUG);
event();
@@ -81,7 +90,6 @@ fn reload_handle() {
}
#[test]
-#[cfg(feature = "registry")]
fn reload_filter() {
struct NopLayer;
impl<S: Subscriber> tracing_subscriber::Layer<S> for NopLayer {
@@ -111,9 +119,13 @@ fn reload_filter() {
};
true
}
- }
- fn event() {
- tracing::trace!("my event");
+
+ fn max_level_hint(&self) -> Option<LevelFilter> {
+ match self {
+ Filter::One => Some(LevelFilter::INFO),
+ Filter::Two => Some(LevelFilter::DEBUG),
+ }
+ }
}
let (filter, handle) = Layer::new(Filter::One);
@@ -131,7 +143,9 @@ fn reload_filter() {
assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1);
assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0);
+ assert_eq!(LevelFilter::current(), LevelFilter::INFO);
handle.reload(Filter::Two).expect("should reload");
+ assert_eq!(LevelFilter::current(), LevelFilter::DEBUG);
event();
diff --git a/vendor/tracing/.cargo-checksum.json b/vendor/tracing/.cargo-checksum.json
index 404d4f3c0..7b9d07340 100644
--- a/vendor/tracing/.cargo-checksum.json
+++ b/vendor/tracing/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"7d5517e1ac705d5d8574915b59a37bbd0ba5aa6e663fc272b75e5792eca572a9","Cargo.toml":"f6290faffd0bf079845dbd6c3c1ddb6c728bcf7225e3b56a4ba5a9478dc72a8b","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"a83e1a8287e3eca752383ae849872707dddfbd07b918806cc7c027a0824872c6","benches/global_subscriber.rs":"271213baed0e02054e506c1ec9c47b58696c78aaa46f0969a147f4c369f80e3d","benches/no_subscriber.rs":"495c9a91fb972ec61ced31ef8e19d2cca02ec8ffae4e98e3316e55f6a0074578","benches/subscriber.rs":"c609be119ed6e4d3fb79df77f15aa14effbd3e2f77c627a49229a50091d3ee6a","src/dispatcher.rs":"a8158e1901c50dc83d2f15b1773e6b9e31985d9af65e460be52dbf8be6874cd2","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"a8ab6b578f93b5fb833942fc59642e67caca8d343670d64fb52d47d5507a67e4","src/macros.rs":"f1a83930cea322f1f2000548d91800c22a9e28d2daf3f178c7c7c3ac8da5a02d","src/span.rs":"96b6c86be09c97b15b2ab5c607013abc5b388c2870eb648bee2cfc07837fa6e9","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"ae879c373be7ee4935f7b02a345f92ccbeb7879d61c5d37e3cc1277b3d51ddb2","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"c4ec3ac338475e9e61675551eb99df1d8a7cbefb05a0d60203994f5c1df7c784","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"dc3017cca8de9a33d8e0c3cba87b3977b1c84e1fe16ff87bc36614572ddd5832","Cargo.toml":"e4ffa43825ed68447646e39babd364b737b1353f95a7a6baa995879ad282952d","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"2a2ff5fa337287734c28e856a185afbced4cd656791a1aaeef0b982784e601d7","benches/baseline.rs":"43a3e31b6c33dba2e6328052301b707b212487b83f0dcffc843061a9c48a2319","benches/dispatch_get_clone.rs":"866239abeb74a82440741c948a4e7e0a44e92e8cc87319ec57e3b057c9e8f5dd","benches/dispatch_get_ref.rs":"dd2803259a6784c256304e676bbce05de233e4c8451ac85863787213343e9be7","benches/empty_span.rs":"9f51cf376414ea751b2f50c357f2435a545d606118286f5b8b89f185e28aad8c","benches/enter_span.rs":"4410ec73d277e7b54e9f306c00ff3b79a150d1832966b7fc29984c8e3ad8d57c","benches/event.rs":"98de3c82ed18abe0a3cbe6eda9a4f9deec2b69bca42c3aac11dea4b608b85a67","benches/shared.rs":"2623311af7d153685064e664a5903d03e7dc3179754c324f3a76f29f060515e6","benches/span_fields.rs":"9166cd43ef2783e5419dd61ea57a02e48e8cc38aa1b357e9b79fa581929b60d8","benches/span_no_fields.rs":"79cc4befacf27d7ce728246087c4f06a6066f913e831d9043caeb7941f0193f6","benches/span_repeated.rs":"e4b3c99a7a9fc15d9042b8db399a56cf647b4eebd26f29d95325bb057b68330b","src/dispatcher.rs":"a8158e1901c50dc83d2f15b1773e6b9e31985d9af65e460be52dbf8be6874cd2","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"c7edb1602b2e9d164bc90f9d0dff48abb2fad840c07c6283481255fbe5d321e6","src/macros.rs":"f1a83930cea322f1f2000548d91800c22a9e28d2daf3f178c7c7c3ac8da5a02d","src/span.rs":"372695b3eda8354a892316826d2598f821fcb835fb18e1e0271767bce730b7ad","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"8933d8766439f929c0a98a0863d20aff37b221314b3825edd9058be511149968","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"7678d1cc8a29ae8b716fbddb7cc4836422732ba3dce109ff511c8bb6100da606","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"} \ No newline at end of file
diff --git a/vendor/tracing/CHANGELOG.md b/vendor/tracing/CHANGELOG.md
index 1c527f2de..8b7d58808 100644
--- a/vendor/tracing/CHANGELOG.md
+++ b/vendor/tracing/CHANGELOG.md
@@ -1,3 +1,33 @@
+# 0.1.36 (July 29, 2022)
+
+This release adds support for owned values and fat pointers as arguments to the
+`Span::record` method, as well as updating the minimum `tracing-core` version
+and several documentation improvements.
+
+### Fixed
+
+- Incorrect docs in `dispatcher::set_default` ([#2220])
+- Compilation with `-Z minimal-versions` ([#2246])
+
+### Added
+
+- Support for owned values and fat pointers in `Span::record` ([#2212])
+- Documentation improvements ([#2208], [#2163])
+
+### Changed
+
+- `tracing-core`: updated to [0.1.29][core-0.1.29]
+
+Thanks to @fredr, @cgbur, @jyn514, @matklad, and @CAD97 for contributing to this
+release!
+
+[core-0.1.29]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.29
+[#2220]: https://github.com/tokio-rs/tracing/pull/2220
+[#2246]: https://github.com/tokio-rs/tracing/pull/2246
+[#2212]: https://github.com/tokio-rs/tracing/pull/2212
+[#2208]: https://github.com/tokio-rs/tracing/pull/2208
+[#2163]: https://github.com/tokio-rs/tracing/pull/2163
+
# 0.1.35 (June 8, 2022)
This release reduces the overhead of callsite registration by using new
diff --git a/vendor/tracing/Cargo.toml b/vendor/tracing/Cargo.toml
index dd6f1fb47..9b4b5fa80 100644
--- a/vendor/tracing/Cargo.toml
+++ b/vendor/tracing/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.49.0"
name = "tracing"
-version = "0.1.35"
+version = "0.1.36"
authors = [
"Eliza Weisman <eliza@buoyant.io>",
"Tokio Contributors <team@tokio.rs>",
@@ -52,37 +52,65 @@ rustc-args = [
]
[[bench]]
-name = "subscriber"
+name = "baseline"
harness = false
[[bench]]
-name = "no_subscriber"
+name = "dispatch_get_clone"
+harness = false
+
+[[bench]]
+name = "dispatch_get_ref"
+harness = false
+
+[[bench]]
+name = "empty_span"
+harness = false
+
+[[bench]]
+name = "enter_span"
+harness = false
+
+[[bench]]
+name = "event"
+harness = false
+
+[[bench]]
+name = "span_fields"
+harness = false
+
+[[bench]]
+name = "span_no_fields"
+harness = false
+
+[[bench]]
+name = "span_repeated"
harness = false
[dependencies.cfg-if]
version = "1.0.0"
[dependencies.log]
-version = "0.4"
+version = "0.4.17"
optional = true
[dependencies.pin-project-lite]
-version = "0.2"
+version = "0.2.9"
[dependencies.tracing-attributes]
-version = "0.1.20"
+version = "0.1.22"
optional = true
[dependencies.tracing-core]
-version = "0.1.27"
+version = "0.1.29"
default-features = false
[dev-dependencies.criterion]
-version = "0.3"
-default_features = false
+version = "0.3.6"
+default-features = false
[dev-dependencies.log]
-version = "0.4"
+version = "0.4.17"
[features]
async-await = []
diff --git a/vendor/tracing/README.md b/vendor/tracing/README.md
index 5da141a3a..16e671e05 100644
--- a/vendor/tracing/README.md
+++ b/vendor/tracing/README.md
@@ -16,9 +16,9 @@ Application-level tracing for Rust.
[Documentation][docs-url] | [Chat][discord-url]
[crates-badge]: https://img.shields.io/crates/v/tracing.svg
-[crates-url]: https://crates.io/crates/tracing/0.1.35
+[crates-url]: https://crates.io/crates/tracing
[docs-badge]: https://docs.rs/tracing/badge.svg
-[docs-url]: https://docs.rs/tracing/0.1.35
+[docs-url]: https://docs.rs/tracing
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
[docs-master-url]: https://tracing-rs.netlify.com/tracing
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
@@ -250,7 +250,7 @@ my_future
is as long as the future's.
The second, and preferred, option is through the
-[`#[instrument]`](https://docs.rs/tracing/0.1.35/tracing/attr.instrument.html)
+[`#[instrument]`](https://docs.rs/tracing/0.1.36/tracing/attr.instrument.html)
attribute:
```rust
@@ -297,7 +297,7 @@ span.in_scope(|| {
// Dropping the span will close it, indicating that it has ended.
```
-The [`#[instrument]`](https://docs.rs/tracing/0.1.35/tracing/attr.instrument.html) attribute macro
+The [`#[instrument]`](https://docs.rs/tracing/0.1.36/tracing/attr.instrument.html) attribute macro
can reduce some of this boilerplate:
```rust
@@ -395,6 +395,7 @@ maintained by the `tokio` project. These include:
framework for validating the behavior of `tracing` spans.
- [`sentry-tracing`] provides a layer for reporting events and traces to [Sentry].
- [`tracing-loki`] provides a layer for shipping logs to [Grafana Loki].
+- [`tracing-logfmt`] provides a layer that formats events and spans into the logfmt format.
If you're the maintainer of a `tracing` ecosystem crate not listed above,
please let us know! We'd love to add your project to the list!
@@ -424,6 +425,7 @@ please let us know! We'd love to add your project to the list!
[Sentry]: https://sentry.io/welcome/
[`tracing-loki`]: https://crates.io/crates/tracing-loki
[Grafana Loki]: https://grafana.com/oss/loki/
+[`tracing-logfmt`]: https://crates.io/crates/tracing-logfmt
**Note:** that some of the ecosystem crates are currently unreleased and
undergoing active development. They may be less stable than `tracing` and
diff --git a/vendor/tracing/benches/baseline.rs b/vendor/tracing/benches/baseline.rs
new file mode 100644
index 000000000..93c14f422
--- /dev/null
+++ b/vendor/tracing/benches/baseline.rs
@@ -0,0 +1,24 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+fn bench(c: &mut Criterion) {
+ use std::sync::atomic::{AtomicUsize, Ordering};
+
+ let mut group = c.benchmark_group("comparison");
+ group.bench_function("relaxed_load", |b| {
+ let foo = AtomicUsize::new(1);
+ b.iter(|| black_box(foo.load(Ordering::Relaxed)));
+ });
+ group.bench_function("acquire_load", |b| {
+ let foo = AtomicUsize::new(1);
+ b.iter(|| black_box(foo.load(Ordering::Acquire)))
+ });
+ group.bench_function("log", |b| {
+ b.iter(|| {
+ log::log!(log::Level::Info, "log");
+ })
+ });
+ group.finish();
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/dispatch_get_clone.rs b/vendor/tracing/benches/dispatch_get_clone.rs
new file mode 100644
index 000000000..15577c696
--- /dev/null
+++ b/vendor/tracing/benches/dispatch_get_clone.rs
@@ -0,0 +1,15 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_dispatches(&mut c.benchmark_group("Dispatch::get_clone"), |b| {
+ b.iter(|| {
+ let current = tracing::dispatcher::get_default(|current| current.clone());
+ black_box(current);
+ })
+ });
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/dispatch_get_ref.rs b/vendor/tracing/benches/dispatch_get_ref.rs
new file mode 100644
index 000000000..a59c34379
--- /dev/null
+++ b/vendor/tracing/benches/dispatch_get_ref.rs
@@ -0,0 +1,16 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_dispatches(&mut c.benchmark_group("Dispatch::get_ref"), |b| {
+ b.iter(|| {
+ tracing::dispatcher::get_default(|current| {
+ black_box(&current);
+ })
+ })
+ });
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/empty_span.rs b/vendor/tracing/benches/empty_span.rs
new file mode 100644
index 000000000..fb38b08e1
--- /dev/null
+++ b/vendor/tracing/benches/empty_span.rs
@@ -0,0 +1,43 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ let mut group = c.benchmark_group("empty_span");
+ shared::for_all_dispatches(&mut group, |b| {
+ b.iter(|| {
+ let span = tracing::span::Span::none();
+ black_box(&span);
+ })
+ });
+ group.bench_function("baseline_struct", |b| {
+ b.iter(|| {
+ let span = FakeEmptySpan::new();
+ black_box(&span);
+ })
+ });
+}
+
+struct FakeEmptySpan {
+ inner: Option<(usize, std::sync::Arc<()>)>,
+ meta: Option<&'static ()>,
+}
+
+impl FakeEmptySpan {
+ fn new() -> Self {
+ Self {
+ inner: None,
+ meta: None,
+ }
+ }
+}
+
+impl Drop for FakeEmptySpan {
+ fn drop(&mut self) {
+ black_box(&self.inner);
+ black_box(&self.meta);
+ }
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/enter_span.rs b/vendor/tracing/benches/enter_span.rs
new file mode 100644
index 000000000..757350a53
--- /dev/null
+++ b/vendor/tracing/benches/enter_span.rs
@@ -0,0 +1,16 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use tracing::{span, Level};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_dispatches(&mut c.benchmark_group("enter_span"), |b| {
+ let span = span!(Level::TRACE, "span");
+ b.iter(|| {
+ let _span = span.enter();
+ })
+ });
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/event.rs b/vendor/tracing/benches/event.rs
new file mode 100644
index 000000000..164932548
--- /dev/null
+++ b/vendor/tracing/benches/event.rs
@@ -0,0 +1,12 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_recording(&mut c.benchmark_group("event"), |b| {
+ b.iter(|| tracing::info!("hello world!"))
+ });
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/global_subscriber.rs b/vendor/tracing/benches/global_subscriber.rs
deleted file mode 100644
index 83519610a..000000000
--- a/vendor/tracing/benches/global_subscriber.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-use std::fmt::Write;
-
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use tracing::Level;
-
-use tracing::{span, Event, Id, Metadata};
-
-/// A subscriber that is enabled but otherwise does nothing.
-struct EnabledSubscriber;
-
-impl tracing::Subscriber for EnabledSubscriber {
- fn new_span(&self, span: &span::Attributes<'_>) -> Id {
- let _ = span;
- Id::from_u64(0xDEAD_FACE)
- }
-
- fn event(&self, event: &Event<'_>) {
- let _ = event;
- }
-
- fn record(&self, span: &Id, values: &span::Record<'_>) {
- let _ = (span, values);
- }
-
- fn record_follows_from(&self, span: &Id, follows: &Id) {
- let _ = (span, follows);
- }
-
- fn enabled(&self, metadata: &Metadata<'_>) -> bool {
- let _ = metadata;
- true
- }
-
- fn enter(&self, span: &Id) {
- let _ = span;
- }
-
- fn exit(&self, span: &Id) {
- let _ = span;
- }
-}
-
-const NOP_LOGGER: NopLogger = NopLogger;
-
-struct NopLogger;
-
-impl log::Log for NopLogger {
- fn enabled(&self, _metadata: &log::Metadata) -> bool {
- true
- }
-
- fn log(&self, record: &log::Record) {
- if self.enabled(record.metadata()) {
- let mut this = self;
- let _ = write!(this, "{}", record.args());
- }
- }
-
- fn flush(&self) {}
-}
-
-impl Write for &NopLogger {
- fn write_str(&mut self, s: &str) -> std::fmt::Result {
- black_box(s);
- Ok(())
- }
-}
-
-const N_SPANS: usize = 100;
-
-fn criterion_benchmark(c: &mut Criterion) {
- let mut c = c.benchmark_group("global/subscriber");
- let _ = tracing::subscriber::set_global_default(EnabledSubscriber);
- let _ = log::set_logger(&NOP_LOGGER);
- log::set_max_level(log::LevelFilter::Trace);
- c.bench_function("span_no_fields", |b| b.iter(|| span!(Level::TRACE, "span")));
-
- c.bench_function("event", |b| {
- b.iter(|| {
- tracing::event!(Level::TRACE, "hello");
- })
- });
-
- c.bench_function("enter_span", |b| {
- let span = span!(Level::TRACE, "span");
- #[allow(clippy::unit_arg)]
- b.iter(|| black_box(span.in_scope(|| {})))
- });
-
- c.bench_function("span_repeatedly", |b| {
- #[inline]
- fn mk_span(i: u64) -> tracing::Span {
- span!(Level::TRACE, "span", i = i)
- }
-
- let n = black_box(N_SPANS);
- b.iter(|| (0..n).fold(mk_span(0), |_, i| mk_span(i as u64)))
- });
-
- c.bench_function("span_with_fields", |b| {
- b.iter(|| {
- span!(
- Level::TRACE,
- "span",
- foo = "foo",
- bar = "bar",
- baz = 3,
- quuux = tracing::field::debug(0.99)
- )
- });
- });
-}
-
-fn bench_dispatch(c: &mut Criterion) {
- let mut group = c.benchmark_group("global/dispatch");
- let _ = tracing::subscriber::set_global_default(EnabledSubscriber);
- let _ = log::set_logger(&NOP_LOGGER);
- log::set_max_level(log::LevelFilter::Trace);
- group.bench_function("get_ref", |b| {
- b.iter(|| {
- tracing::dispatcher::get_default(|current| {
- black_box(&current);
- })
- })
- });
- group.bench_function("get_clone", |b| {
- b.iter(|| {
- let current = tracing::dispatcher::get_default(|current| current.clone());
- black_box(current);
- })
- });
- group.finish();
-}
-
-criterion_group!(benches, criterion_benchmark, bench_dispatch);
-criterion_main!(benches);
diff --git a/vendor/tracing/benches/no_subscriber.rs b/vendor/tracing/benches/no_subscriber.rs
deleted file mode 100644
index e0f82b56a..000000000
--- a/vendor/tracing/benches/no_subscriber.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use tracing::Level;
-
-struct FakeEmptySpan {
- inner: Option<(usize, std::sync::Arc<()>)>,
- meta: Option<&'static ()>,
-}
-
-impl FakeEmptySpan {
- fn new() -> Self {
- Self {
- inner: None,
- meta: None,
- }
- }
-}
-
-impl Drop for FakeEmptySpan {
- fn drop(&mut self) {
- black_box(&self.inner);
- black_box(&self.meta);
- }
-}
-
-fn bench_no_subscriber(c: &mut Criterion) {
- use std::sync::atomic::{AtomicUsize, Ordering};
-
- let mut group = c.benchmark_group("no_subscriber");
-
- group.bench_function("span", |b| {
- b.iter(|| {
- let span = tracing::span!(Level::TRACE, "span");
- black_box(&span);
- })
- });
- group.bench_function("span_enter", |b| {
- b.iter(|| {
- let span = tracing::span!(Level::TRACE, "span");
- let _e = span.enter();
- })
- });
- group.bench_function("empty_span", |b| {
- b.iter(|| {
- let span = tracing::span::Span::none();
- black_box(&span);
- });
- });
- group.bench_function("empty_struct", |b| {
- b.iter(|| {
- let span = FakeEmptySpan::new();
- black_box(&span);
- })
- });
- group.bench_function("event", |b| {
- b.iter(|| {
- tracing::event!(Level::TRACE, "hello");
- })
- });
- group.bench_function("relaxed_load", |b| {
- let foo = AtomicUsize::new(1);
- b.iter(|| black_box(foo.load(Ordering::Relaxed)));
- });
- group.bench_function("acquire_load", |b| {
- let foo = AtomicUsize::new(1);
- b.iter(|| black_box(foo.load(Ordering::Acquire)))
- });
- group.bench_function("log", |b| {
- b.iter(|| {
- log::log!(log::Level::Info, "log");
- })
- });
- group.finish();
-}
-
-fn bench_fields(c: &mut Criterion) {
- let mut group = c.benchmark_group("no_subscriber_field");
- group.bench_function("span", |b| {
- b.iter(|| {
- black_box(tracing::span!(
- Level::TRACE,
- "span",
- foo = tracing::field::display(format!("bar {:?}", 2))
- ));
- })
- });
- group.bench_function("event", |b| {
- b.iter(|| {
- tracing::event!(
- Level::TRACE,
- foo = tracing::field::display(format!("bar {:?}", 2))
- );
- })
- });
- group.bench_function("log", |b| {
- b.iter(|| log::log!(log::Level::Trace, "{}", format!("bar {:?}", 2)))
- });
- group.finish();
-}
-
-criterion_group!(benches, bench_no_subscriber, bench_fields);
-criterion_main!(benches);
diff --git a/vendor/tracing/benches/shared.rs b/vendor/tracing/benches/shared.rs
new file mode 100644
index 000000000..56508c4ab
--- /dev/null
+++ b/vendor/tracing/benches/shared.rs
@@ -0,0 +1,160 @@
+#![allow(dead_code)]
+use criterion::{black_box, measurement::WallTime, Bencher};
+use tracing::{field, span, Event, Id, Metadata};
+
+use std::{
+ fmt::{self, Write},
+ sync::{Mutex, MutexGuard},
+};
+
+pub fn for_all_recording(
+ group: &mut criterion::BenchmarkGroup<'_, WallTime>,
+ mut iter: impl FnMut(&mut Bencher<'_, WallTime>),
+) {
+ // first, run benchmarks with no subscriber
+ group.bench_function("none", &mut iter);
+
+ // then, run benchmarks with a scoped default subscriber
+ tracing::subscriber::with_default(EnabledSubscriber, || {
+ group.bench_function("scoped", &mut iter)
+ });
+
+ let subscriber = VisitingSubscriber(Mutex::new(String::from("")));
+ tracing::subscriber::with_default(subscriber, || {
+ group.bench_function("scoped_recording", &mut iter);
+ });
+
+ // finally, set a global default subscriber, and run the benchmarks again.
+ tracing::subscriber::set_global_default(EnabledSubscriber)
+ .expect("global default should not have already been set!");
+ let _ = log::set_logger(&NOP_LOGGER);
+ log::set_max_level(log::LevelFilter::Trace);
+ group.bench_function("global", &mut iter);
+}
+
+pub fn for_all_dispatches(
+ group: &mut criterion::BenchmarkGroup<'_, WallTime>,
+ mut iter: impl FnMut(&mut Bencher<'_, WallTime>),
+) {
+ // first, run benchmarks with no subscriber
+ group.bench_function("none", &mut iter);
+
+ // then, run benchmarks with a scoped default subscriber
+ tracing::subscriber::with_default(EnabledSubscriber, || {
+ group.bench_function("scoped", &mut iter)
+ });
+
+ // finally, set a global default subscriber, and run the benchmarks again.
+ tracing::subscriber::set_global_default(EnabledSubscriber)
+ .expect("global default should not have already been set!");
+ let _ = log::set_logger(&NOP_LOGGER);
+ log::set_max_level(log::LevelFilter::Trace);
+ group.bench_function("global", &mut iter);
+}
+
+const NOP_LOGGER: NopLogger = NopLogger;
+
+struct NopLogger;
+
+impl log::Log for NopLogger {
+ fn enabled(&self, _metadata: &log::Metadata) -> bool {
+ true
+ }
+
+ fn log(&self, record: &log::Record) {
+ if self.enabled(record.metadata()) {
+ let mut this = self;
+ let _ = write!(this, "{}", record.args());
+ }
+ }
+
+ fn flush(&self) {}
+}
+
+impl Write for &NopLogger {
+ fn write_str(&mut self, s: &str) -> std::fmt::Result {
+ black_box(s);
+ Ok(())
+ }
+}
+
+/// Simulates a subscriber that records span data.
+struct VisitingSubscriber(Mutex<String>);
+
+struct Visitor<'a>(MutexGuard<'a, String>);
+
+impl<'a> field::Visit for Visitor<'a> {
+ fn record_debug(&mut self, _field: &field::Field, value: &dyn fmt::Debug) {
+ let _ = write!(&mut *self.0, "{:?}", value);
+ }
+}
+
+impl tracing::Subscriber for VisitingSubscriber {
+ fn new_span(&self, span: &span::Attributes<'_>) -> Id {
+ let mut visitor = Visitor(self.0.lock().unwrap());
+ span.record(&mut visitor);
+ Id::from_u64(0xDEAD_FACE)
+ }
+
+ fn record(&self, _span: &Id, values: &span::Record<'_>) {
+ let mut visitor = Visitor(self.0.lock().unwrap());
+ values.record(&mut visitor);
+ }
+
+ fn event(&self, event: &Event<'_>) {
+ let mut visitor = Visitor(self.0.lock().unwrap());
+ event.record(&mut visitor);
+ }
+
+ fn record_follows_from(&self, span: &Id, follows: &Id) {
+ let _ = (span, follows);
+ }
+
+ fn enabled(&self, metadata: &Metadata<'_>) -> bool {
+ let _ = metadata;
+ true
+ }
+
+ fn enter(&self, span: &Id) {
+ let _ = span;
+ }
+
+ fn exit(&self, span: &Id) {
+ let _ = span;
+ }
+}
+
+/// A subscriber that is enabled but otherwise does nothing.
+struct EnabledSubscriber;
+
+impl tracing::Subscriber for EnabledSubscriber {
+ fn new_span(&self, span: &span::Attributes<'_>) -> Id {
+ let _ = span;
+ Id::from_u64(0xDEAD_FACE)
+ }
+
+ fn event(&self, event: &Event<'_>) {
+ let _ = event;
+ }
+
+ fn record(&self, span: &Id, values: &span::Record<'_>) {
+ let _ = (span, values);
+ }
+
+ fn record_follows_from(&self, span: &Id, follows: &Id) {
+ let _ = (span, follows);
+ }
+
+ fn enabled(&self, metadata: &Metadata<'_>) -> bool {
+ let _ = metadata;
+ true
+ }
+
+ fn enter(&self, span: &Id) {
+ let _ = span;
+ }
+
+ fn exit(&self, span: &Id) {
+ let _ = span;
+ }
+}
diff --git a/vendor/tracing/benches/span_fields.rs b/vendor/tracing/benches/span_fields.rs
new file mode 100644
index 000000000..5ad828982
--- /dev/null
+++ b/vendor/tracing/benches/span_fields.rs
@@ -0,0 +1,23 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use tracing::{span, Level};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_recording(&mut c.benchmark_group("span_fields"), |b| {
+ b.iter(|| {
+ let span = span!(
+ Level::TRACE,
+ "span",
+ foo = "foo",
+ bar = "bar",
+ baz = 3,
+ quuux = tracing::field::debug(0.99)
+ );
+ criterion::black_box(span)
+ })
+ });
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/span_no_fields.rs b/vendor/tracing/benches/span_no_fields.rs
new file mode 100644
index 000000000..8a1ff6e04
--- /dev/null
+++ b/vendor/tracing/benches/span_no_fields.rs
@@ -0,0 +1,13 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use tracing::{span, Level};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_recording(&mut c.benchmark_group("span_no_fields"), |b| {
+ b.iter(|| span!(Level::TRACE, "span"))
+ });
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/span_repeated.rs b/vendor/tracing/benches/span_repeated.rs
new file mode 100644
index 000000000..4c6ac409d
--- /dev/null
+++ b/vendor/tracing/benches/span_repeated.rs
@@ -0,0 +1,20 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use tracing::{span, Level};
+
+mod shared;
+
+fn bench(c: &mut Criterion) {
+ shared::for_all_recording(&mut c.benchmark_group("span_repeated"), |b| {
+ let n = black_box(N_SPANS);
+ b.iter(|| (0..n).fold(mk_span(0), |_, i| mk_span(i as u64)))
+ });
+}
+
+#[inline]
+fn mk_span(i: u64) -> tracing::Span {
+ span!(Level::TRACE, "span", i = i)
+}
+
+const N_SPANS: usize = 100;
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff --git a/vendor/tracing/benches/subscriber.rs b/vendor/tracing/benches/subscriber.rs
deleted file mode 100644
index c6418010f..000000000
--- a/vendor/tracing/benches/subscriber.rs
+++ /dev/null
@@ -1,189 +0,0 @@
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use tracing::Level;
-
-use std::{
- fmt,
- sync::{Mutex, MutexGuard},
-};
-use tracing::{field, span, Event, Id, Metadata};
-
-/// A subscriber that is enabled but otherwise does nothing.
-struct EnabledSubscriber;
-
-impl tracing::Subscriber for EnabledSubscriber {
- fn new_span(&self, span: &span::Attributes<'_>) -> Id {
- let _ = span;
- Id::from_u64(0xDEAD_FACE)
- }
-
- fn event(&self, event: &Event<'_>) {
- let _ = event;
- }
-
- fn record(&self, span: &Id, values: &span::Record<'_>) {
- let _ = (span, values);
- }
-
- fn record_follows_from(&self, span: &Id, follows: &Id) {
- let _ = (span, follows);
- }
-
- fn enabled(&self, metadata: &Metadata<'_>) -> bool {
- let _ = metadata;
- true
- }
-
- fn enter(&self, span: &Id) {
- let _ = span;
- }
-
- fn exit(&self, span: &Id) {
- let _ = span;
- }
-}
-
-/// Simulates a subscriber that records span data.
-struct VisitingSubscriber(Mutex<String>);
-
-struct Visitor<'a>(MutexGuard<'a, String>);
-
-impl<'a> field::Visit for Visitor<'a> {
- fn record_debug(&mut self, _field: &field::Field, value: &dyn fmt::Debug) {
- use std::fmt::Write;
- let _ = write!(&mut *self.0, "{:?}", value);
- }
-}
-
-impl tracing::Subscriber for VisitingSubscriber {
- fn new_span(&self, span: &span::Attributes<'_>) -> Id {
- let mut visitor = Visitor(self.0.lock().unwrap());
- span.record(&mut visitor);
- Id::from_u64(0xDEAD_FACE)
- }
-
- fn record(&self, _span: &Id, values: &span::Record<'_>) {
- let mut visitor = Visitor(self.0.lock().unwrap());
- values.record(&mut visitor);
- }
-
- fn event(&self, event: &Event<'_>) {
- let mut visitor = Visitor(self.0.lock().unwrap());
- event.record(&mut visitor);
- }
-
- fn record_follows_from(&self, span: &Id, follows: &Id) {
- let _ = (span, follows);
- }
-
- fn enabled(&self, metadata: &Metadata<'_>) -> bool {
- let _ = metadata;
- true
- }
-
- fn enter(&self, span: &Id) {
- let _ = span;
- }
-
- fn exit(&self, span: &Id) {
- let _ = span;
- }
-}
-
-const N_SPANS: usize = 100;
-
-fn criterion_benchmark(c: &mut Criterion) {
- c.bench_function("span_no_fields", |b| {
- tracing::subscriber::with_default(EnabledSubscriber, || {
- b.iter(|| span!(Level::TRACE, "span"))
- });
- });
-
- c.bench_function("enter_span", |b| {
- tracing::subscriber::with_default(EnabledSubscriber, || {
- let span = span!(Level::TRACE, "span");
- #[allow(clippy::unit_arg)]
- b.iter(|| black_box(span.in_scope(|| {})))
- });
- });
-
- c.bench_function("span_repeatedly", |b| {
- #[inline]
- fn mk_span(i: u64) -> tracing::Span {
- span!(Level::TRACE, "span", i = i)
- }
-
- let n = black_box(N_SPANS);
- tracing::subscriber::with_default(EnabledSubscriber, || {
- b.iter(|| (0..n).fold(mk_span(0), |_, i| mk_span(i as u64)))
- });
- });
-
- c.bench_function("span_with_fields", |b| {
- tracing::subscriber::with_default(EnabledSubscriber, || {
- b.iter(|| {
- span!(
- Level::TRACE,
- "span",
- foo = "foo",
- bar = "bar",
- baz = 3,
- quuux = tracing::field::debug(0.99)
- )
- })
- });
- });
-
- c.bench_function("span_with_fields_record", |b| {
- let subscriber = VisitingSubscriber(Mutex::new(String::from("")));
- tracing::subscriber::with_default(subscriber, || {
- b.iter(|| {
- span!(
- Level::TRACE,
- "span",
- foo = "foo",
- bar = "bar",
- baz = 3,
- quuux = tracing::field::debug(0.99)
- )
- })
- });
- });
-}
-
-fn bench_dispatch(c: &mut Criterion) {
- let mut group = c.benchmark_group("dispatch");
- group.bench_function("no_dispatch_get_ref", |b| {
- b.iter(|| {
- tracing::dispatcher::get_default(|current| {
- black_box(&current);
- })
- })
- });
- group.bench_function("no_dispatch_get_clone", |b| {
- b.iter(|| {
- let current = tracing::dispatcher::get_default(|current| current.clone());
- black_box(current);
- })
- });
- group.bench_function("get_ref", |b| {
- tracing::subscriber::with_default(EnabledSubscriber, || {
- b.iter(|| {
- tracing::dispatcher::get_default(|current| {
- black_box(&current);
- })
- })
- })
- });
- group.bench_function("get_clone", |b| {
- tracing::subscriber::with_default(EnabledSubscriber, || {
- b.iter(|| {
- let current = tracing::dispatcher::get_default(|current| current.clone());
- black_box(current);
- })
- })
- });
- group.finish();
-}
-
-criterion_group!(benches, criterion_benchmark, bench_dispatch);
-criterion_main!(benches);
diff --git a/vendor/tracing/src/lib.rs b/vendor/tracing/src/lib.rs
index 4743eba20..7d60c7721 100644
--- a/vendor/tracing/src/lib.rs
+++ b/vendor/tracing/src/lib.rs
@@ -743,6 +743,7 @@
//! - [`tracing-forest`] provides a subscriber that preserves contextual coherence by
//! grouping together logs from the same spans during writing.
//! - [`tracing-loki`] provides a layer for shipping logs to [Grafana Loki].
+//! - [`tracing-logfmt`] provides a layer that formats events and spans into the logfmt format.
//!
//! If you're the maintainer of a `tracing` ecosystem crate not listed above,
//! please let us know! We'd love to add your project to the list!
@@ -779,6 +780,7 @@
//! [`tracing-forest`]: https://crates.io/crates/tracing-forest
//! [`tracing-loki`]: https://crates.io/crates/tracing-loki
//! [Grafana Loki]: https://grafana.com/oss/loki/
+//! [`tracing-logfmt`]: https://crates.io/crates/tracing-logfmt
//!
//! <pre class="ignore" style="white-space:normal;font:inherit;">
//! <strong>Note</strong>: Some of these ecosystem crates are currently
@@ -809,7 +811,7 @@
//!
//! ```toml
//! [dependencies]
-//! tracing = { version = "0.1.35", default-features = false }
+//! tracing = { version = "0.1.36", default-features = false }
//! ```
//!
//! <pre class="ignore" style="white-space:normal;font:inherit;">
@@ -892,7 +894,7 @@
//! [flags]: #crate-feature-flags
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
-#![doc(html_root_url = "https://docs.rs/tracing/0.1.35")]
+#![doc(html_root_url = "https://docs.rs/tracing/0.1.36")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
diff --git a/vendor/tracing/src/span.rs b/vendor/tracing/src/span.rs
index 21358eb27..58822f4d9 100644
--- a/vendor/tracing/src/span.rs
+++ b/vendor/tracing/src/span.rs
@@ -1136,7 +1136,7 @@ impl Span {
///
/// // Now, record a value for parting as well.
/// // (note that the field name is passed as a string slice)
- /// span.record("parting", &"goodbye world!");
+ /// span.record("parting", "goodbye world!");
/// ```
/// However, it may also be used to record a _new_ value for a field whose
/// value was already recorded:
@@ -1154,7 +1154,7 @@ impl Span {
/// }
/// Err(_) => {
/// // Things are no longer okay!
- /// span.record("is_okay", &false);
+ /// span.record("is_okay", false);
/// }
/// }
/// ```
@@ -1181,17 +1181,17 @@ impl Span {
/// // Now, you try to record a value for a new field, `new_field`, which was not
/// // declared as `Empty` or populated when you created `span`.
/// // You won't get any error, but the assignment will have no effect!
- /// span.record("new_field", &"interesting_value_you_really_need");
+ /// span.record("new_field", "interesting_value_you_really_need");
///
/// // Instead, all fields that may be recorded after span creation should be declared up front,
/// // using field::Empty when a value is not known, as we did for `parting`.
/// // This `record` call will indeed replace field::Empty with "you will be remembered".
- /// span.record("parting", &"you will be remembered");
+ /// span.record("parting", "you will be remembered");
/// ```
///
/// [`field::Empty`]: super::field::Empty
/// [`Metadata`]: super::Metadata
- pub fn record<Q: ?Sized, V>(&self, field: &Q, value: &V) -> &Self
+ pub fn record<Q: ?Sized, V>(&self, field: &Q, value: V) -> &Self
where
Q: field::AsField,
V: field::Value,
@@ -1201,7 +1201,7 @@ impl Span {
self.record_all(
&meta
.fields()
- .value_set(&[(&field, Some(value as &dyn field::Value))]),
+ .value_set(&[(&field, Some(&value as &dyn field::Value))]),
);
}
}
@@ -1614,4 +1614,10 @@ mod test {
impl AssertSync for Span {}
impl AssertSync for Entered<'_> {}
impl AssertSync for EnteredSpan {}
+
+ #[test]
+ fn test_record_backwards_compat() {
+ Span::current().record("some-key", &"some text");
+ Span::current().record("some-key", &false);
+ }
}
diff --git a/vendor/tracing/src/subscriber.rs b/vendor/tracing/src/subscriber.rs
index 343dc5914..f55698d13 100644
--- a/vendor/tracing/src/subscriber.rs
+++ b/vendor/tracing/src/subscriber.rs
@@ -5,12 +5,12 @@ pub use tracing_core::subscriber::*;
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub use tracing_core::dispatcher::DefaultGuard;
-/// Sets this subscriber as the default for the duration of a closure.
+/// Sets this [`Subscriber`] as the default for the current thread for the
+/// duration of a closure.
///
/// The default subscriber is used when creating a new [`Span`] or
-/// [`Event`], _if no span is currently executing_. If a span is currently
-/// executing, new spans or events are dispatched to the subscriber that
-/// tagged that span, instead.
+/// [`Event`].
+///
///
/// [`Span`]: super::span::Span
/// [`Subscriber`]: super::subscriber::Subscriber
@@ -43,13 +43,10 @@ where
crate::dispatcher::set_global_default(crate::Dispatch::new(subscriber))
}
-/// Sets the subscriber as the default for the duration of the lifetime of the
-/// returned [`DefaultGuard`]
+/// Sets the [`Subscriber`] as the default for the current thread for the
+/// duration of the lifetime of the returned [`DefaultGuard`].
///
-/// The default subscriber is used when creating a new [`Span`] or
-/// [`Event`], _if no span is currently executing_. If a span is currently
-/// executing, new spans or events are dispatched to the subscriber that
-/// tagged that span, instead.
+/// The default subscriber is used when creating a new [`Span`] or [`Event`].
///
/// [`Span`]: super::span::Span
/// [`Subscriber`]: super::subscriber::Subscriber
diff --git a/vendor/tracing/tests/event.rs b/vendor/tracing/tests/event.rs
index ffb63c816..61df19ad3 100644
--- a/vendor/tracing/tests/event.rs
+++ b/vendor/tracing/tests/event.rs
@@ -474,3 +474,27 @@ fn option_ref_mut_values() {
handle.assert_finished();
}
+
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
+#[test]
+fn string_field() {
+ let (subscriber, handle) = subscriber::mock()
+ .event(event::mock().with_fields(field::mock("my_string").with_value(&"hello").only()))
+ .event(
+ event::mock().with_fields(field::mock("my_string").with_value(&"hello world!").only()),
+ )
+ .done()
+ .run_with_handle();
+ with_default(subscriber, || {
+ let mut my_string = String::from("hello");
+
+ tracing::event!(Level::INFO, my_string);
+
+ // the string is not moved by using it as a field!
+ my_string.push_str(" world!");
+
+ tracing::event!(Level::INFO, my_string);
+ });
+
+ handle.assert_finished();
+}
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/.cargo-checksum.json b/vendor/wasi-0.10.2+wasi-snapshot-preview1/.cargo-checksum.json
deleted file mode 100644
index 4c858cdd5..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CODE_OF_CONDUCT.md":"a13aaaf393818bd91207c618724d3fb74944ca5161201822a84af951bcf655ef","CONTRIBUTING.md":"2c908a3e263dc35dfed131c02ff907cd72fafb2c2096e4ba9b1e0cbb7a1b76df","Cargo.toml":"946b521f577983feb92abbad62bd85932fe4fe26b7a61dcaba4030d242667885","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-Apache-2.0_WITH_LLVM-exception":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","ORG_CODE_OF_CONDUCT.md":"a62b69bf86e605ee1bcbb2f0a12ba79e4cebb6983a7b6491949750aecc4f2178","README.md":"c021f687a5a61d9c308581401e7aa4454585a30c418abdd02e3a1ef71daa035f","SECURITY.md":"4d75afb09dd28eb5982e3a1f768ee398d90204669ceef3240a16b31dcf04148a","src/error.rs":"270ec14e103130ac5981997ddfa616851cb596fecd48ea7212a7a59dcb110c7f","src/lib.rs":"ce2e7ee6a6e4d5900f3835568b168afc70870d601b2bb94f1a6b9ddd2f046c3a","src/lib_generated.rs":"f92f8c522904454c5909843bc2db4c34af48ca2eae8634cc77dc51d89fa5eae2"},"package":"fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"} \ No newline at end of file
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/CODE_OF_CONDUCT.md b/vendor/wasi-0.10.2+wasi-snapshot-preview1/CODE_OF_CONDUCT.md
deleted file mode 100644
index 5c5ebdd25..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-*Note*: this Code of Conduct pertains to individuals' behavior. Please also see the [Organizational Code of Conduct][OCoC].
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Bytecode Alliance CoC team at [report@bytecodealliance.org](mailto:report@bytecodealliance.org). The CoC team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The CoC team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the Bytecode Alliance's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
-
-[OCoC]: ORG_CODE_OF_CONDUCT.md
-[homepage]: https://www.contributor-covenant.org
-[version]: https://www.contributor-covenant.org/version/1/4/
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/CONTRIBUTING.md b/vendor/wasi-0.10.2+wasi-snapshot-preview1/CONTRIBUTING.md
deleted file mode 100644
index 2db6d0ddf..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/CONTRIBUTING.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Contributing to wasi-core
-
-wasi-core follows the same development style as Cranelift, so checkout
-[Cranelift's CONTRIBUTING.md]. Of course, for wasi-core-specific issues, please
-use the [wasi-core issue tracker].
-
-[Cranelift's CONTRIBUTING.md]: https://github.com/CraneStation/cranelift/blob/master/CONTRIBUTING.md
-[wasi-core issue tracker]: https://github.com/CraneStation/wasi-core/issues/new
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/Cargo.toml b/vendor/wasi-0.10.2+wasi-snapshot-preview1/Cargo.toml
deleted file mode 100644
index 23e3b2f6e..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/Cargo.toml
+++ /dev/null
@@ -1,43 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-edition = "2018"
-name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
-authors = ["The Cranelift Project Developers"]
-description = "Experimental WASI API bindings for Rust"
-documentation = "https://docs.rs/wasi"
-readme = "README.md"
-keywords = ["webassembly", "wasm"]
-categories = ["no-std", "wasm"]
-license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
-repository = "https://github.com/bytecodealliance/wasi"
-[dependencies.compiler_builtins]
-version = "0.1"
-optional = true
-
-[dependencies.core]
-version = "1.0"
-optional = true
-package = "rustc-std-workspace-core"
-
-[dependencies.rustc-std-workspace-alloc]
-version = "1.0"
-optional = true
-
-[features]
-default = ["std"]
-rustc-dep-of-std = ["compiler_builtins", "core", "rustc-std-workspace-alloc"]
-std = []
-[badges.maintenance]
-status = "experimental"
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-APACHE b/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-APACHE
deleted file mode 100644
index 16fe87b06..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception b/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception
deleted file mode 100644
index f9d81955f..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception
+++ /dev/null
@@ -1,220 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
---- LLVM Exceptions to the Apache 2.0 License ----
-
-As an exception, if, as a result of your compiling your source code, portions
-of this Software are embedded into an Object form of such source code, you
-may redistribute such embedded portions in such Object form without complying
-with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
-
-In addition, if you combine or link compiled forms of this Software with
-software that is licensed under the GPLv2 ("Combined Software") and if a
-court of competent jurisdiction determines that the patent provision (Section
-3), the indemnity provision (Section 9) or other Section of the License
-conflicts with the conditions of the GPLv2, you may retroactively and
-prospectively choose to deem waived or otherwise exclude such Section(s) of
-the License, but only in their entirety and only with respect to the Combined
-Software.
-
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-MIT b/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-MIT
deleted file mode 100644
index 31aa79387..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/LICENSE-MIT
+++ /dev/null
@@ -1,23 +0,0 @@
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/ORG_CODE_OF_CONDUCT.md b/vendor/wasi-0.10.2+wasi-snapshot-preview1/ORG_CODE_OF_CONDUCT.md
deleted file mode 100644
index 6f4fb3f53..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/ORG_CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,143 +0,0 @@
-# Bytecode Alliance Organizational Code of Conduct (OCoC)
-
-*Note*: this Code of Conduct pertains to organizations' behavior. Please also see the [Individual Code of Conduct](CODE_OF_CONDUCT.md).
-
-## Preamble
-
-The Bytecode Alliance (BA) welcomes involvement from organizations,
-including commercial organizations. This document is an
-*organizational* code of conduct, intended particularly to provide
-guidance to commercial organizations. It is distinct from the
-[Individual Code of Conduct (ICoC)](CODE_OF_CONDUCT.md), and does not
-replace the ICoC. This OCoC applies to any group of people acting in
-concert as a BA member or as a participant in BA activities, whether
-or not that group is formally incorporated in some jurisdiction.
-
-The code of conduct described below is not a set of rigid rules, and
-we did not write it to encompass every conceivable scenario that might
-arise. For example, it is theoretically possible there would be times
-when asserting patents is in the best interest of the BA community as
-a whole. In such instances, consult with the BA, strive for
-consensus, and interpret these rules with an intent that is generous
-to the community the BA serves.
-
-While we may revise these guidelines from time to time based on
-real-world experience, overall they are based on a simple principle:
-
-*Bytecode Alliance members should observe the distinction between
- public community functions and private functions — especially
- commercial ones — and should ensure that the latter support, or at
- least do not harm, the former.*
-
-## Guidelines
-
- * **Do not cause confusion about Wasm standards or interoperability.**
-
- Having an interoperable WebAssembly core is a high priority for
- the BA, and members should strive to preserve that core. It is fine
- to develop additional non-standard features or APIs, but they
- should always be clearly distinguished from the core interoperable
- Wasm.
-
- Treat the WebAssembly name and any BA-associated names with
- respect, and follow BA trademark and branding guidelines. If you
- distribute a customized version of software originally produced by
- the BA, or if you build a product or service using BA-derived
- software, use names that clearly distinguish your work from the
- original. (You should still provide proper attribution to the
- original, of course, wherever such attribution would normally be
- given.)
-
- Further, do not use the WebAssembly name or BA-associated names in
- other public namespaces in ways that could cause confusion, e.g.,
- in company names, names of commercial service offerings, domain
- names, publicly-visible social media accounts or online service
- accounts, etc. It may sometimes be reasonable, however, to
- register such a name in a new namespace and then immediately donate
- control of that account to the BA, because that would help the project
- maintain its identity.
-
- For further guidance, see the BA Trademark and Branding Policy
- [TODO: create policy, then insert link].
-
- * **Do not restrict contributors.** If your company requires
- employees or contractors to sign non-compete agreements, those
- agreements must not prevent people from participating in the BA or
- contributing to related projects.
-
- This does not mean that all non-compete agreements are incompatible
- with this code of conduct. For example, a company may restrict an
- employee's ability to solicit the company's customers. However, an
- agreement must not block any form of technical or social
- participation in BA activities, including but not limited to the
- implementation of particular features.
-
- The accumulation of experience and expertise in individual persons,
- who are ultimately free to direct their energy and attention as
- they decide, is one of the most important drivers of progress in
- open source projects. A company that limits this freedom may hinder
- the success of the BA's efforts.
-
- * **Do not use patents as offensive weapons.** If any BA participant
- prevents the adoption or development of BA technologies by
- asserting its patents, that undermines the purpose of the
- coalition. The collaboration fostered by the BA cannot include
- members who act to undermine its work.
-
- * **Practice responsible disclosure** for security vulnerabilities.
- Use designated, non-public reporting channels to disclose technical
- vulnerabilities, and give the project a reasonable period to
- respond, remediate, and patch. [TODO: optionally include the
- security vulnerability reporting URL here.]
-
- Vulnerability reporters may patch their company's own offerings, as
- long as that patching does not significantly delay the reporting of
- the vulnerability. Vulnerability information should never be used
- for unilateral commercial advantage. Vendors may legitimately
- compete on the speed and reliability with which they deploy
- security fixes, but withholding vulnerability information damages
- everyone in the long run by risking harm to the BA project's
- reputation and to the security of all users.
-
- * **Respect the letter and spirit of open source practice.** While
- there is not space to list here all possible aspects of standard
- open source practice, some examples will help show what we mean:
-
- * Abide by all applicable open source license terms. Do not engage
- in copyright violation or misattribution of any kind.
-
- * Do not claim others' ideas or designs as your own.
-
- * When others engage in publicly visible work (e.g., an upcoming
- demo that is coordinated in a public issue tracker), do not
- unilaterally announce early releases or early demonstrations of
- that work ahead of their schedule in order to secure private
- advantage (such as marketplace advantage) for yourself.
-
- The BA reserves the right to determine what constitutes good open
- source practices and to take action as it deems appropriate to
- encourage, and if necessary enforce, such practices.
-
-## Enforcement
-
-Instances of organizational behavior in violation of the OCoC may
-be reported by contacting the Bytecode Alliance CoC team at
-[report@bytecodealliance.org](mailto:report@bytecodealliance.org). The
-CoC team will review and investigate all complaints, and will respond
-in a way that it deems appropriate to the circumstances. The CoC team
-is obligated to maintain confidentiality with regard to the reporter of
-an incident. Further details of specific enforcement policies may be
-posted separately.
-
-When the BA deems an organization in violation of this OCoC, the BA
-will, at its sole discretion, determine what action to take. The BA
-will decide what type, degree, and duration of corrective action is
-needed, if any, before a violating organization can be considered for
-membership (if it was not already a member) or can have its membership
-reinstated (if it was a member and the BA canceled its membership due
-to the violation).
-
-In practice, the BA's first approach will be to start a conversation,
-with punitive enforcement used only as a last resort. Violations
-often turn out to be unintentional and swiftly correctable with all
-parties acting in good faith.
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/README.md b/vendor/wasi-0.10.2+wasi-snapshot-preview1/README.md
deleted file mode 100644
index 801f56a4e..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/README.md
+++ /dev/null
@@ -1,94 +0,0 @@
-<div align="center">
- <h1><code>wasi</code></h1>
-
-<strong>A <a href="https://bytecodealliance.org/">Bytecode Alliance</a> project</strong>
-
- <p>
- <strong>WASI API Bindings for Rust</strong>
- </p>
-
- <p>
- <a href="https://crates.io/crates/wasi"><img src="https://img.shields.io/crates/v/wasi.svg?style=flat-square" alt="Crates.io version" /></a>
- <a href="https://crates.io/crates/wasi"><img src="https://img.shields.io/crates/d/wasi.svg?style=flat-square" alt="Download" /></a>
- <a href="https://docs.rs/wasi/"><img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square" alt="docs.rs docs" /></a>
- </p>
-</div>
-
-This crate contains API bindings for [WASI](https://github.com/WebAssembly/WASI)
-system calls in Rust, and currently reflects the `wasi_snapshot_preview1`
-module. This crate is quite low-level and provides conceptually a "system call"
-interface. In most settings, it's better to use the Rust standard library, which
-has WASI support.
-
-The `wasi` crate is also entirely procedurally generated from the `*.witx` files
-describing the WASI apis. While some conveniences are provided the bindings here
-are intentionally low-level!
-
-# Usage
-
-First you can depend on this crate via `Cargo.toml`:
-
-```toml
-[dependencies]
-wasi = "0.8.0"
-```
-
-Next you can use the APIs in the root of the module like so:
-
-```rust
-fn main() {
- let stdout = 1;
- let message = "Hello, World!\n";
- let data = [wasi::Ciovec {
- buf: message.as_ptr(),
- buf_len: message.len(),
- }];
- wasi::fd_write(stdout, &data).unwrap();
-}
-```
-
-Next you can use a tool like [`cargo
-wasi`](https://github.com/bytecodealliance/cargo-wasi) to compile and run your
-project:
-
-To compile Rust projects to wasm using WASI, use the `wasm32-wasi` target,
-like this:
-
-```
-$ cargo wasi run
- Compiling wasi v0.8.0+wasi-snapshot-preview1
- Compiling wut v0.1.0 (/code)
- Finished dev [unoptimized + debuginfo] target(s) in 0.34s
- Running `/.cargo/bin/cargo-wasi target/wasm32-wasi/debug/wut.wasm`
- Running `target/wasm32-wasi/debug/wut.wasm`
-Hello, World!
-```
-
-# Development
-
-The bulk of the `wasi` crate is generated by the `witx-bindgen` tool, which lives at
-`crates/witx-bindgen` and is part of the cargo workspace.
-
-The `src/lib_generated.rs` file can be re-generated with the following
-command:
-
-```
-cargo run -p witx-bindgen -- crates/witx-bindgen/WASI/phases/snapshot/witx/wasi_snapshot_preview1.witx > src/lib_generated.rs
-```
-
-Note that this uses the WASI standard repository as a submodule. If you do not
-have this submodule present in your source tree, run:
-```
-git submodule update --init
-```
-
-# License
-
-This project is licensed under the Apache 2.0 license with the LLVM exception.
-See [LICENSE](LICENSE) for more details.
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in this project by you, as defined in the Apache-2.0 license,
-shall be licensed as above, without any additional terms or conditions.
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/SECURITY.md b/vendor/wasi-0.10.2+wasi-snapshot-preview1/SECURITY.md
deleted file mode 100644
index 3513b9cb3..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/SECURITY.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Security Policy
-
-Building secure foundations for software development is at the core of what we do in the Bytecode Alliance. Contributions of external security researchers are a vital part of that.
-
-## Scope
-
-If you believe you've found a security issue in any website, service, or software owned or operated by the Bytecode Alliance, we encourage you to notify us.
-
-## How to Submit a Report
-
-To submit a vulnerability report to the Bytecode Alliance, please contact us at [security@bytecodealliance.org](mailto:security@bytecodealliance.org). Your submission will be reviewed and validated by a member of our security team.
-
-## Safe Harbor
-
-The Bytecode Alliance supports safe harbor for security researchers who:
-
-* Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our services.
-* Only interact with accounts you own or with explicit permission of the account holder. If you do encounter Personally Identifiable Information (PII) contact us immediately, do not proceed with access, and immediately purge any local information.
-* Provide us with a reasonable amount of time to resolve vulnerabilities prior to any disclosure to the public or a third-party.
-
-We will consider activities conducted consistent with this policy to constitute "authorized" conduct and will not pursue civil action or initiate a complaint to law enforcement. We will help to the extent we can if legal action is initiated by a third party against you.
-
-Please submit a report to us before engaging in conduct that may be inconsistent with or unaddressed by this policy.
-
-## Preferences
-
-* Please provide detailed reports with reproducible steps and a clearly defined impact.
-* Submit one vulnerability per report.
-* Social engineering (e.g. phishing, vishing, smishing) is prohibited.
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/error.rs b/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/error.rs
deleted file mode 100644
index fb8b44389..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/error.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-use super::Errno;
-use core::fmt;
-use core::num::NonZeroU16;
-
-/// A raw error returned by wasi APIs, internally containing a 16-bit error
-/// code.
-#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
-pub struct Error {
- code: NonZeroU16,
-}
-
-impl Error {
- /// Constructs a new error from a raw error code, returning `None` if the
- /// error code is zero (which means success).
- pub fn from_raw_error(error: Errno) -> Option<Error> {
- Some(Error {
- code: NonZeroU16::new(error)?,
- })
- }
-
- /// Returns the raw error code that this error represents.
- pub fn raw_error(&self) -> u16 {
- self.code.get()
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{} (error {})",
- super::errno_name(self.code.get()),
- self.code
- )?;
- Ok(())
- }
-}
-
-impl fmt::Debug for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Error")
- .field("code", &self.code)
- .field("name", &super::errno_name(self.code.get()))
- .field("message", &super::errno_docs(self.code.get()))
- .finish()
- }
-}
-
-#[cfg(feature = "std")]
-extern crate std;
-#[cfg(feature = "std")]
-impl std::error::Error for Error {}
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib.rs b/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib.rs
deleted file mode 100644
index 51f488907..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//! Raw API bindings to the WebAssembly System Interface (WASI)
-//!
-//! This crate provides Rust API bindings to WASI APIs. All WASI APIs are
-//! exported from this crate and provided with the appropriate type signatures.
-//! This crate is entirely procedurally generated from the `*.witx` files that
-//! describe the WASI API.
-//!
-//! # WASI API Version
-//!
-//! The WASI API is evolving over time. It is both gaining new features as well
-//! as tweaking the ABI of existing features. As a result it's important to
-//! understand what version of this crate you're using and how it relates to
-//! the WASI version of the spec.
-//!
-//! The WASI specification is organized into phases where there is a snapshot
-//! at any one point in time describing the current state of the specification.
-//! This crate implements a particular snapshot. You can find the snapshot
-//! version implemented in this crate in the build metadata of the crate
-//! version number. For example something like `0.9.0+wasi-snapshot-preview1`
-//! means that this crate's own personal version is 0.9.0 and it implements the
-//! `wasi-snapshot-preview1` snapshot. A major release of this crate (i.e.
-//! bumping the "0.9.0") is expected whenever the generated code changes
-//! or a new WASI snapshot is used.
-//!
-//! # Crate Features
-//!
-//! This crate supports one feature, `std`, which implements the standard
-//! `Error` trait for the exported [`Error`] type in this crate. This is
-//! enabled by default but can be disabled to make the library `no_std`
-//! compatible.
-
-#![no_std]
-
-mod error;
-mod lib_generated;
-pub use lib_generated::*;
-
-/// Special `Dircookie` value indicating the start of a directory.
-pub const DIRCOOKIE_START: Dircookie = 0;
-
-/// The "standard input" descriptor number.
-pub const FD_STDIN: Fd = 0;
-
-/// The "standard output" descriptor number.
-pub const FD_STDOUT: Fd = 1;
-
-/// The "standard error" descriptor number.
-pub const FD_STDERR: Fd = 2;
diff --git a/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib_generated.rs b/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib_generated.rs
deleted file mode 100644
index 09d58c2b3..000000000
--- a/vendor/wasi-0.10.2+wasi-snapshot-preview1/src/lib_generated.rs
+++ /dev/null
@@ -1,1940 +0,0 @@
-// This file is automatically generated, DO NOT EDIT
-//
-// To regenerate this file run the `crates/witx-bindgen` command
-
-use core::mem::MaybeUninit;
-
-pub use crate::error::Error;
-pub type Result<T, E = Error> = core::result::Result<T, E>;
-pub type Size = usize;
-pub type Filesize = u64;
-pub type Timestamp = u64;
-pub type Clockid = u32;
-/// The clock measuring real time. Time value zero corresponds with
-/// 1970-01-01T00:00:00Z.
-pub const CLOCKID_REALTIME: Clockid = 0;
-/// The store-wide monotonic clock, which is defined as a clock measuring
-/// real time, whose value cannot be adjusted and which cannot have negative
-/// clock jumps. The epoch of this clock is undefined. The absolute time
-/// value of this clock therefore has no meaning.
-pub const CLOCKID_MONOTONIC: Clockid = 1;
-/// The CPU-time clock associated with the current process.
-pub const CLOCKID_PROCESS_CPUTIME_ID: Clockid = 2;
-/// The CPU-time clock associated with the current thread.
-pub const CLOCKID_THREAD_CPUTIME_ID: Clockid = 3;
-pub type Errno = u16;
-/// No error occurred. System call completed successfully.
-pub const ERRNO_SUCCESS: Errno = 0;
-/// Argument list too long.
-pub const ERRNO_2BIG: Errno = 1;
-/// Permission denied.
-pub const ERRNO_ACCES: Errno = 2;
-/// Address in use.
-pub const ERRNO_ADDRINUSE: Errno = 3;
-/// Address not available.
-pub const ERRNO_ADDRNOTAVAIL: Errno = 4;
-/// Address family not supported.
-pub const ERRNO_AFNOSUPPORT: Errno = 5;
-/// Resource unavailable, or operation would block.
-pub const ERRNO_AGAIN: Errno = 6;
-/// Connection already in progress.
-pub const ERRNO_ALREADY: Errno = 7;
-/// Bad file descriptor.
-pub const ERRNO_BADF: Errno = 8;
-/// Bad message.
-pub const ERRNO_BADMSG: Errno = 9;
-/// Device or resource busy.
-pub const ERRNO_BUSY: Errno = 10;
-/// Operation canceled.
-pub const ERRNO_CANCELED: Errno = 11;
-/// No child processes.
-pub const ERRNO_CHILD: Errno = 12;
-/// Connection aborted.
-pub const ERRNO_CONNABORTED: Errno = 13;
-/// Connection refused.
-pub const ERRNO_CONNREFUSED: Errno = 14;
-/// Connection reset.
-pub const ERRNO_CONNRESET: Errno = 15;
-/// Resource deadlock would occur.
-pub const ERRNO_DEADLK: Errno = 16;
-/// Destination address required.
-pub const ERRNO_DESTADDRREQ: Errno = 17;
-/// Mathematics argument out of domain of function.
-pub const ERRNO_DOM: Errno = 18;
-/// Reserved.
-pub const ERRNO_DQUOT: Errno = 19;
-/// File exists.
-pub const ERRNO_EXIST: Errno = 20;
-/// Bad address.
-pub const ERRNO_FAULT: Errno = 21;
-/// File too large.
-pub const ERRNO_FBIG: Errno = 22;
-/// Host is unreachable.
-pub const ERRNO_HOSTUNREACH: Errno = 23;
-/// Identifier removed.
-pub const ERRNO_IDRM: Errno = 24;
-/// Illegal byte sequence.
-pub const ERRNO_ILSEQ: Errno = 25;
-/// Operation in progress.
-pub const ERRNO_INPROGRESS: Errno = 26;
-/// Interrupted function.
-pub const ERRNO_INTR: Errno = 27;
-/// Invalid argument.
-pub const ERRNO_INVAL: Errno = 28;
-/// I/O error.
-pub const ERRNO_IO: Errno = 29;
-/// Socket is connected.
-pub const ERRNO_ISCONN: Errno = 30;
-/// Is a directory.
-pub const ERRNO_ISDIR: Errno = 31;
-/// Too many levels of symbolic links.
-pub const ERRNO_LOOP: Errno = 32;
-/// File descriptor value too large.
-pub const ERRNO_MFILE: Errno = 33;
-/// Too many links.
-pub const ERRNO_MLINK: Errno = 34;
-/// Message too large.
-pub const ERRNO_MSGSIZE: Errno = 35;
-/// Reserved.
-pub const ERRNO_MULTIHOP: Errno = 36;
-/// Filename too long.
-pub const ERRNO_NAMETOOLONG: Errno = 37;
-/// Network is down.
-pub const ERRNO_NETDOWN: Errno = 38;
-/// Connection aborted by network.
-pub const ERRNO_NETRESET: Errno = 39;
-/// Network unreachable.
-pub const ERRNO_NETUNREACH: Errno = 40;
-/// Too many files open in system.
-pub const ERRNO_NFILE: Errno = 41;
-/// No buffer space available.
-pub const ERRNO_NOBUFS: Errno = 42;
-/// No such device.
-pub const ERRNO_NODEV: Errno = 43;
-/// No such file or directory.
-pub const ERRNO_NOENT: Errno = 44;
-/// Executable file format error.
-pub const ERRNO_NOEXEC: Errno = 45;
-/// No locks available.
-pub const ERRNO_NOLCK: Errno = 46;
-/// Reserved.
-pub const ERRNO_NOLINK: Errno = 47;
-/// Not enough space.
-pub const ERRNO_NOMEM: Errno = 48;
-/// No message of the desired type.
-pub const ERRNO_NOMSG: Errno = 49;
-/// Protocol not available.
-pub const ERRNO_NOPROTOOPT: Errno = 50;
-/// No space left on device.
-pub const ERRNO_NOSPC: Errno = 51;
-/// Function not supported.
-pub const ERRNO_NOSYS: Errno = 52;
-/// The socket is not connected.
-pub const ERRNO_NOTCONN: Errno = 53;
-/// Not a directory or a symbolic link to a directory.
-pub const ERRNO_NOTDIR: Errno = 54;
-/// Directory not empty.
-pub const ERRNO_NOTEMPTY: Errno = 55;
-/// State not recoverable.
-pub const ERRNO_NOTRECOVERABLE: Errno = 56;
-/// Not a socket.
-pub const ERRNO_NOTSOCK: Errno = 57;
-/// Not supported, or operation not supported on socket.
-pub const ERRNO_NOTSUP: Errno = 58;
-/// Inappropriate I/O control operation.
-pub const ERRNO_NOTTY: Errno = 59;
-/// No such device or address.
-pub const ERRNO_NXIO: Errno = 60;
-/// Value too large to be stored in data type.
-pub const ERRNO_OVERFLOW: Errno = 61;
-/// Previous owner died.
-pub const ERRNO_OWNERDEAD: Errno = 62;
-/// Operation not permitted.
-pub const ERRNO_PERM: Errno = 63;
-/// Broken pipe.
-pub const ERRNO_PIPE: Errno = 64;
-/// Protocol error.
-pub const ERRNO_PROTO: Errno = 65;
-/// Protocol not supported.
-pub const ERRNO_PROTONOSUPPORT: Errno = 66;
-/// Protocol wrong type for socket.
-pub const ERRNO_PROTOTYPE: Errno = 67;
-/// Result too large.
-pub const ERRNO_RANGE: Errno = 68;
-/// Read-only file system.
-pub const ERRNO_ROFS: Errno = 69;
-/// Invalid seek.
-pub const ERRNO_SPIPE: Errno = 70;
-/// No such process.
-pub const ERRNO_SRCH: Errno = 71;
-/// Reserved.
-pub const ERRNO_STALE: Errno = 72;
-/// Connection timed out.
-pub const ERRNO_TIMEDOUT: Errno = 73;
-/// Text file busy.
-pub const ERRNO_TXTBSY: Errno = 74;
-/// Cross-device link.
-pub const ERRNO_XDEV: Errno = 75;
-/// Extension: Capabilities insufficient.
-pub const ERRNO_NOTCAPABLE: Errno = 76;
-pub fn errno_name(code: u16) -> &'static str {
- match code {
- ERRNO_SUCCESS => "SUCCESS",
- ERRNO_2BIG => "2BIG",
- ERRNO_ACCES => "ACCES",
- ERRNO_ADDRINUSE => "ADDRINUSE",
- ERRNO_ADDRNOTAVAIL => "ADDRNOTAVAIL",
- ERRNO_AFNOSUPPORT => "AFNOSUPPORT",
- ERRNO_AGAIN => "AGAIN",
- ERRNO_ALREADY => "ALREADY",
- ERRNO_BADF => "BADF",
- ERRNO_BADMSG => "BADMSG",
- ERRNO_BUSY => "BUSY",
- ERRNO_CANCELED => "CANCELED",
- ERRNO_CHILD => "CHILD",
- ERRNO_CONNABORTED => "CONNABORTED",
- ERRNO_CONNREFUSED => "CONNREFUSED",
- ERRNO_CONNRESET => "CONNRESET",
- ERRNO_DEADLK => "DEADLK",
- ERRNO_DESTADDRREQ => "DESTADDRREQ",
- ERRNO_DOM => "DOM",
- ERRNO_DQUOT => "DQUOT",
- ERRNO_EXIST => "EXIST",
- ERRNO_FAULT => "FAULT",
- ERRNO_FBIG => "FBIG",
- ERRNO_HOSTUNREACH => "HOSTUNREACH",
- ERRNO_IDRM => "IDRM",
- ERRNO_ILSEQ => "ILSEQ",
- ERRNO_INPROGRESS => "INPROGRESS",
- ERRNO_INTR => "INTR",
- ERRNO_INVAL => "INVAL",
- ERRNO_IO => "IO",
- ERRNO_ISCONN => "ISCONN",
- ERRNO_ISDIR => "ISDIR",
- ERRNO_LOOP => "LOOP",
- ERRNO_MFILE => "MFILE",
- ERRNO_MLINK => "MLINK",
- ERRNO_MSGSIZE => "MSGSIZE",
- ERRNO_MULTIHOP => "MULTIHOP",
- ERRNO_NAMETOOLONG => "NAMETOOLONG",
- ERRNO_NETDOWN => "NETDOWN",
- ERRNO_NETRESET => "NETRESET",
- ERRNO_NETUNREACH => "NETUNREACH",
- ERRNO_NFILE => "NFILE",
- ERRNO_NOBUFS => "NOBUFS",
- ERRNO_NODEV => "NODEV",
- ERRNO_NOENT => "NOENT",
- ERRNO_NOEXEC => "NOEXEC",
- ERRNO_NOLCK => "NOLCK",
- ERRNO_NOLINK => "NOLINK",
- ERRNO_NOMEM => "NOMEM",
- ERRNO_NOMSG => "NOMSG",
- ERRNO_NOPROTOOPT => "NOPROTOOPT",
- ERRNO_NOSPC => "NOSPC",
- ERRNO_NOSYS => "NOSYS",
- ERRNO_NOTCONN => "NOTCONN",
- ERRNO_NOTDIR => "NOTDIR",
- ERRNO_NOTEMPTY => "NOTEMPTY",
- ERRNO_NOTRECOVERABLE => "NOTRECOVERABLE",
- ERRNO_NOTSOCK => "NOTSOCK",
- ERRNO_NOTSUP => "NOTSUP",
- ERRNO_NOTTY => "NOTTY",
- ERRNO_NXIO => "NXIO",
- ERRNO_OVERFLOW => "OVERFLOW",
- ERRNO_OWNERDEAD => "OWNERDEAD",
- ERRNO_PERM => "PERM",
- ERRNO_PIPE => "PIPE",
- ERRNO_PROTO => "PROTO",
- ERRNO_PROTONOSUPPORT => "PROTONOSUPPORT",
- ERRNO_PROTOTYPE => "PROTOTYPE",
- ERRNO_RANGE => "RANGE",
- ERRNO_ROFS => "ROFS",
- ERRNO_SPIPE => "SPIPE",
- ERRNO_SRCH => "SRCH",
- ERRNO_STALE => "STALE",
- ERRNO_TIMEDOUT => "TIMEDOUT",
- ERRNO_TXTBSY => "TXTBSY",
- ERRNO_XDEV => "XDEV",
- ERRNO_NOTCAPABLE => "NOTCAPABLE",
- _ => "Unknown error.",
- }
-}
-pub fn errno_docs(code: u16) -> &'static str {
- match code {
- ERRNO_SUCCESS => "No error occurred. System call completed successfully.",
- ERRNO_2BIG => "Argument list too long.",
- ERRNO_ACCES => "Permission denied.",
- ERRNO_ADDRINUSE => "Address in use.",
- ERRNO_ADDRNOTAVAIL => "Address not available.",
- ERRNO_AFNOSUPPORT => "Address family not supported.",
- ERRNO_AGAIN => "Resource unavailable, or operation would block.",
- ERRNO_ALREADY => "Connection already in progress.",
- ERRNO_BADF => "Bad file descriptor.",
- ERRNO_BADMSG => "Bad message.",
- ERRNO_BUSY => "Device or resource busy.",
- ERRNO_CANCELED => "Operation canceled.",
- ERRNO_CHILD => "No child processes.",
- ERRNO_CONNABORTED => "Connection aborted.",
- ERRNO_CONNREFUSED => "Connection refused.",
- ERRNO_CONNRESET => "Connection reset.",
- ERRNO_DEADLK => "Resource deadlock would occur.",
- ERRNO_DESTADDRREQ => "Destination address required.",
- ERRNO_DOM => "Mathematics argument out of domain of function.",
- ERRNO_DQUOT => "Reserved.",
- ERRNO_EXIST => "File exists.",
- ERRNO_FAULT => "Bad address.",
- ERRNO_FBIG => "File too large.",
- ERRNO_HOSTUNREACH => "Host is unreachable.",
- ERRNO_IDRM => "Identifier removed.",
- ERRNO_ILSEQ => "Illegal byte sequence.",
- ERRNO_INPROGRESS => "Operation in progress.",
- ERRNO_INTR => "Interrupted function.",
- ERRNO_INVAL => "Invalid argument.",
- ERRNO_IO => "I/O error.",
- ERRNO_ISCONN => "Socket is connected.",
- ERRNO_ISDIR => "Is a directory.",
- ERRNO_LOOP => "Too many levels of symbolic links.",
- ERRNO_MFILE => "File descriptor value too large.",
- ERRNO_MLINK => "Too many links.",
- ERRNO_MSGSIZE => "Message too large.",
- ERRNO_MULTIHOP => "Reserved.",
- ERRNO_NAMETOOLONG => "Filename too long.",
- ERRNO_NETDOWN => "Network is down.",
- ERRNO_NETRESET => "Connection aborted by network.",
- ERRNO_NETUNREACH => "Network unreachable.",
- ERRNO_NFILE => "Too many files open in system.",
- ERRNO_NOBUFS => "No buffer space available.",
- ERRNO_NODEV => "No such device.",
- ERRNO_NOENT => "No such file or directory.",
- ERRNO_NOEXEC => "Executable file format error.",
- ERRNO_NOLCK => "No locks available.",
- ERRNO_NOLINK => "Reserved.",
- ERRNO_NOMEM => "Not enough space.",
- ERRNO_NOMSG => "No message of the desired type.",
- ERRNO_NOPROTOOPT => "Protocol not available.",
- ERRNO_NOSPC => "No space left on device.",
- ERRNO_NOSYS => "Function not supported.",
- ERRNO_NOTCONN => "The socket is not connected.",
- ERRNO_NOTDIR => "Not a directory or a symbolic link to a directory.",
- ERRNO_NOTEMPTY => "Directory not empty.",
- ERRNO_NOTRECOVERABLE => "State not recoverable.",
- ERRNO_NOTSOCK => "Not a socket.",
- ERRNO_NOTSUP => "Not supported, or operation not supported on socket.",
- ERRNO_NOTTY => "Inappropriate I/O control operation.",
- ERRNO_NXIO => "No such device or address.",
- ERRNO_OVERFLOW => "Value too large to be stored in data type.",
- ERRNO_OWNERDEAD => "Previous owner died.",
- ERRNO_PERM => "Operation not permitted.",
- ERRNO_PIPE => "Broken pipe.",
- ERRNO_PROTO => "Protocol error.",
- ERRNO_PROTONOSUPPORT => "Protocol not supported.",
- ERRNO_PROTOTYPE => "Protocol wrong type for socket.",
- ERRNO_RANGE => "Result too large.",
- ERRNO_ROFS => "Read-only file system.",
- ERRNO_SPIPE => "Invalid seek.",
- ERRNO_SRCH => "No such process.",
- ERRNO_STALE => "Reserved.",
- ERRNO_TIMEDOUT => "Connection timed out.",
- ERRNO_TXTBSY => "Text file busy.",
- ERRNO_XDEV => "Cross-device link.",
- ERRNO_NOTCAPABLE => "Extension: Capabilities insufficient.",
- _ => "Unknown error.",
- }
-}
-pub type Rights = u64;
-/// The right to invoke `fd_datasync`.
-/// If `path_open` is set, includes the right to invoke
-/// `path_open` with `fdflags::dsync`.
-pub const RIGHTS_FD_DATASYNC: Rights = 0x1;
-/// The right to invoke `fd_read` and `sock_recv`.
-/// If `rights::fd_seek` is set, includes the right to invoke `fd_pread`.
-pub const RIGHTS_FD_READ: Rights = 0x2;
-/// The right to invoke `fd_seek`. This flag implies `rights::fd_tell`.
-pub const RIGHTS_FD_SEEK: Rights = 0x4;
-/// The right to invoke `fd_fdstat_set_flags`.
-pub const RIGHTS_FD_FDSTAT_SET_FLAGS: Rights = 0x8;
-/// The right to invoke `fd_sync`.
-/// If `path_open` is set, includes the right to invoke
-/// `path_open` with `fdflags::rsync` and `fdflags::dsync`.
-pub const RIGHTS_FD_SYNC: Rights = 0x10;
-/// The right to invoke `fd_seek` in such a way that the file offset
-/// remains unaltered (i.e., `whence::cur` with offset zero), or to
-/// invoke `fd_tell`.
-pub const RIGHTS_FD_TELL: Rights = 0x20;
-/// The right to invoke `fd_write` and `sock_send`.
-/// If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`.
-pub const RIGHTS_FD_WRITE: Rights = 0x40;
-/// The right to invoke `fd_advise`.
-pub const RIGHTS_FD_ADVISE: Rights = 0x80;
-/// The right to invoke `fd_allocate`.
-pub const RIGHTS_FD_ALLOCATE: Rights = 0x100;
-/// The right to invoke `path_create_directory`.
-pub const RIGHTS_PATH_CREATE_DIRECTORY: Rights = 0x200;
-/// If `path_open` is set, the right to invoke `path_open` with `oflags::creat`.
-pub const RIGHTS_PATH_CREATE_FILE: Rights = 0x400;
-/// The right to invoke `path_link` with the file descriptor as the
-/// source directory.
-pub const RIGHTS_PATH_LINK_SOURCE: Rights = 0x800;
-/// The right to invoke `path_link` with the file descriptor as the
-/// target directory.
-pub const RIGHTS_PATH_LINK_TARGET: Rights = 0x1000;
-/// The right to invoke `path_open`.
-pub const RIGHTS_PATH_OPEN: Rights = 0x2000;
-/// The right to invoke `fd_readdir`.
-pub const RIGHTS_FD_READDIR: Rights = 0x4000;
-/// The right to invoke `path_readlink`.
-pub const RIGHTS_PATH_READLINK: Rights = 0x8000;
-/// The right to invoke `path_rename` with the file descriptor as the source directory.
-pub const RIGHTS_PATH_RENAME_SOURCE: Rights = 0x10000;
-/// The right to invoke `path_rename` with the file descriptor as the target directory.
-pub const RIGHTS_PATH_RENAME_TARGET: Rights = 0x20000;
-/// The right to invoke `path_filestat_get`.
-pub const RIGHTS_PATH_FILESTAT_GET: Rights = 0x40000;
-/// The right to change a file's size (there is no `path_filestat_set_size`).
-/// If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`.
-pub const RIGHTS_PATH_FILESTAT_SET_SIZE: Rights = 0x80000;
-/// The right to invoke `path_filestat_set_times`.
-pub const RIGHTS_PATH_FILESTAT_SET_TIMES: Rights = 0x100000;
-/// The right to invoke `fd_filestat_get`.
-pub const RIGHTS_FD_FILESTAT_GET: Rights = 0x200000;
-/// The right to invoke `fd_filestat_set_size`.
-pub const RIGHTS_FD_FILESTAT_SET_SIZE: Rights = 0x400000;
-/// The right to invoke `fd_filestat_set_times`.
-pub const RIGHTS_FD_FILESTAT_SET_TIMES: Rights = 0x800000;
-/// The right to invoke `path_symlink`.
-pub const RIGHTS_PATH_SYMLINK: Rights = 0x1000000;
-/// The right to invoke `path_remove_directory`.
-pub const RIGHTS_PATH_REMOVE_DIRECTORY: Rights = 0x2000000;
-/// The right to invoke `path_unlink_file`.
-pub const RIGHTS_PATH_UNLINK_FILE: Rights = 0x4000000;
-/// If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`.
-/// If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`.
-pub const RIGHTS_POLL_FD_READWRITE: Rights = 0x8000000;
-/// The right to invoke `sock_shutdown`.
-pub const RIGHTS_SOCK_SHUTDOWN: Rights = 0x10000000;
-pub type Fd = u32;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct Iovec {
- /// The address of the buffer to be filled.
- pub buf: *mut u8,
- /// The length of the buffer to be filled.
- pub buf_len: Size,
-}
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct Ciovec {
- /// The address of the buffer to be written.
- pub buf: *const u8,
- /// The length of the buffer to be written.
- pub buf_len: Size,
-}
-pub type IovecArray<'a> = &'a [Iovec];
-pub type CiovecArray<'a> = &'a [Ciovec];
-pub type Filedelta = i64;
-pub type Whence = u8;
-/// Seek relative to start-of-file.
-pub const WHENCE_SET: Whence = 0;
-/// Seek relative to current position.
-pub const WHENCE_CUR: Whence = 1;
-/// Seek relative to end-of-file.
-pub const WHENCE_END: Whence = 2;
-pub type Dircookie = u64;
-pub type Dirnamlen = u32;
-pub type Inode = u64;
-pub type Filetype = u8;
-/// The type of the file descriptor or file is unknown or is different from any of the other types specified.
-pub const FILETYPE_UNKNOWN: Filetype = 0;
-/// The file descriptor or file refers to a block device inode.
-pub const FILETYPE_BLOCK_DEVICE: Filetype = 1;
-/// The file descriptor or file refers to a character device inode.
-pub const FILETYPE_CHARACTER_DEVICE: Filetype = 2;
-/// The file descriptor or file refers to a directory inode.
-pub const FILETYPE_DIRECTORY: Filetype = 3;
-/// The file descriptor or file refers to a regular file inode.
-pub const FILETYPE_REGULAR_FILE: Filetype = 4;
-/// The file descriptor or file refers to a datagram socket.
-pub const FILETYPE_SOCKET_DGRAM: Filetype = 5;
-/// The file descriptor or file refers to a byte-stream socket.
-pub const FILETYPE_SOCKET_STREAM: Filetype = 6;
-/// The file refers to a symbolic link inode.
-pub const FILETYPE_SYMBOLIC_LINK: Filetype = 7;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct Dirent {
- /// The offset of the next directory entry stored in this directory.
- pub d_next: Dircookie,
- /// The serial number of the file referred to by this directory entry.
- pub d_ino: Inode,
- /// The length of the name of the directory entry.
- pub d_namlen: Dirnamlen,
- /// The type of the file referred to by this directory entry.
- pub d_type: Filetype,
-}
-pub type Advice = u8;
-/// The application has no advice to give on its behavior with respect to the specified data.
-pub const ADVICE_NORMAL: Advice = 0;
-/// The application expects to access the specified data sequentially from lower offsets to higher offsets.
-pub const ADVICE_SEQUENTIAL: Advice = 1;
-/// The application expects to access the specified data in a random order.
-pub const ADVICE_RANDOM: Advice = 2;
-/// The application expects to access the specified data in the near future.
-pub const ADVICE_WILLNEED: Advice = 3;
-/// The application expects that it will not access the specified data in the near future.
-pub const ADVICE_DONTNEED: Advice = 4;
-/// The application expects to access the specified data once and then not reuse it thereafter.
-pub const ADVICE_NOREUSE: Advice = 5;
-pub type Fdflags = u16;
-/// Append mode: Data written to the file is always appended to the file's end.
-pub const FDFLAGS_APPEND: Fdflags = 0x1;
-/// Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.
-pub const FDFLAGS_DSYNC: Fdflags = 0x2;
-/// Non-blocking mode.
-pub const FDFLAGS_NONBLOCK: Fdflags = 0x4;
-/// Synchronized read I/O operations.
-pub const FDFLAGS_RSYNC: Fdflags = 0x8;
-/// Write according to synchronized I/O file integrity completion. In
-/// addition to synchronizing the data stored in the file, the implementation
-/// may also synchronously update the file's metadata.
-pub const FDFLAGS_SYNC: Fdflags = 0x10;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct Fdstat {
- /// File type.
- pub fs_filetype: Filetype,
- /// File descriptor flags.
- pub fs_flags: Fdflags,
- /// Rights that apply to this file descriptor.
- pub fs_rights_base: Rights,
- /// Maximum set of rights that may be installed on new file descriptors that
- /// are created through this file descriptor, e.g., through `path_open`.
- pub fs_rights_inheriting: Rights,
-}
-pub type Device = u64;
-pub type Fstflags = u16;
-/// Adjust the last data access timestamp to the value stored in `filestat::atim`.
-pub const FSTFLAGS_ATIM: Fstflags = 0x1;
-/// Adjust the last data access timestamp to the time of clock `clockid::realtime`.
-pub const FSTFLAGS_ATIM_NOW: Fstflags = 0x2;
-/// Adjust the last data modification timestamp to the value stored in `filestat::mtim`.
-pub const FSTFLAGS_MTIM: Fstflags = 0x4;
-/// Adjust the last data modification timestamp to the time of clock `clockid::realtime`.
-pub const FSTFLAGS_MTIM_NOW: Fstflags = 0x8;
-pub type Lookupflags = u32;
-/// As long as the resolved path corresponds to a symbolic link, it is expanded.
-pub const LOOKUPFLAGS_SYMLINK_FOLLOW: Lookupflags = 0x1;
-pub type Oflags = u16;
-/// Create file if it does not exist.
-pub const OFLAGS_CREAT: Oflags = 0x1;
-/// Fail if not a directory.
-pub const OFLAGS_DIRECTORY: Oflags = 0x2;
-/// Fail if file already exists.
-pub const OFLAGS_EXCL: Oflags = 0x4;
-/// Truncate file to size 0.
-pub const OFLAGS_TRUNC: Oflags = 0x8;
-pub type Linkcount = u64;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct Filestat {
- /// Device ID of device containing the file.
- pub dev: Device,
- /// File serial number.
- pub ino: Inode,
- /// File type.
- pub filetype: Filetype,
- /// Number of hard links to the file.
- pub nlink: Linkcount,
- /// For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
- pub size: Filesize,
- /// Last data access timestamp.
- pub atim: Timestamp,
- /// Last data modification timestamp.
- pub mtim: Timestamp,
- /// Last file status change timestamp.
- pub ctim: Timestamp,
-}
-pub type Userdata = u64;
-pub type Eventtype = u8;
-/// The time value of clock `subscription_clock::id` has
-/// reached timestamp `subscription_clock::timeout`.
-pub const EVENTTYPE_CLOCK: Eventtype = 0;
-/// File descriptor `subscription_fd_readwrite::file_descriptor` has data
-/// available for reading. This event always triggers for regular files.
-pub const EVENTTYPE_FD_READ: Eventtype = 1;
-/// File descriptor `subscription_fd_readwrite::file_descriptor` has capacity
-/// available for writing. This event always triggers for regular files.
-pub const EVENTTYPE_FD_WRITE: Eventtype = 2;
-pub type Eventrwflags = u16;
-/// The peer of this socket has closed or disconnected.
-pub const EVENTRWFLAGS_FD_READWRITE_HANGUP: Eventrwflags = 0x1;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct EventFdReadwrite {
- /// The number of bytes available for reading or writing.
- pub nbytes: Filesize,
- /// The state of the file descriptor.
- pub flags: Eventrwflags,
-}
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct Event {
- /// User-provided value that got attached to `subscription::userdata`.
- pub userdata: Userdata,
- /// If non-zero, an error that occurred while processing the subscription request.
- pub error: Errno,
- /// The type of event that occured
- pub r#type: Eventtype,
- /// The contents of the event, if it is an `eventtype::fd_read` or
- /// `eventtype::fd_write`. `eventtype::clock` events ignore this field.
- pub fd_readwrite: EventFdReadwrite,
-}
-pub type Subclockflags = u16;
-/// If set, treat the timestamp provided in
-/// `subscription_clock::timeout` as an absolute timestamp of clock
-/// `subscription_clock::id`. If clear, treat the timestamp
-/// provided in `subscription_clock::timeout` relative to the
-/// current time value of clock `subscription_clock::id`.
-pub const SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME: Subclockflags = 0x1;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct SubscriptionClock {
- /// The clock against which to compare the timestamp.
- pub id: Clockid,
- /// The absolute or relative timestamp.
- pub timeout: Timestamp,
- /// The amount of time that the implementation may wait additionally
- /// to coalesce with other events.
- pub precision: Timestamp,
- /// Flags specifying whether the timeout is absolute or relative
- pub flags: Subclockflags,
-}
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct SubscriptionFdReadwrite {
- /// The file descriptor on which to wait for it to become ready for reading or writing.
- pub file_descriptor: Fd,
-}
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub union SubscriptionUU {
- pub clock: SubscriptionClock,
- pub fd_read: SubscriptionFdReadwrite,
- pub fd_write: SubscriptionFdReadwrite,
-}
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct SubscriptionU {
- pub tag: Eventtype,
- pub u: SubscriptionUU,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct Subscription {
- /// User-provided value that is attached to the subscription in the
- /// implementation and returned through `event::userdata`.
- pub userdata: Userdata,
- /// The type of the event to which to subscribe, and its contents
- pub u: SubscriptionU,
-}
-pub type Exitcode = u32;
-pub type Signal = u8;
-/// No signal. Note that POSIX has special semantics for `kill(pid, 0)`,
-/// so this value is reserved.
-pub const SIGNAL_NONE: Signal = 0;
-/// Hangup.
-/// Action: Terminates the process.
-pub const SIGNAL_HUP: Signal = 1;
-/// Terminate interrupt signal.
-/// Action: Terminates the process.
-pub const SIGNAL_INT: Signal = 2;
-/// Terminal quit signal.
-/// Action: Terminates the process.
-pub const SIGNAL_QUIT: Signal = 3;
-/// Illegal instruction.
-/// Action: Terminates the process.
-pub const SIGNAL_ILL: Signal = 4;
-/// Trace/breakpoint trap.
-/// Action: Terminates the process.
-pub const SIGNAL_TRAP: Signal = 5;
-/// Process abort signal.
-/// Action: Terminates the process.
-pub const SIGNAL_ABRT: Signal = 6;
-/// Access to an undefined portion of a memory object.
-/// Action: Terminates the process.
-pub const SIGNAL_BUS: Signal = 7;
-/// Erroneous arithmetic operation.
-/// Action: Terminates the process.
-pub const SIGNAL_FPE: Signal = 8;
-/// Kill.
-/// Action: Terminates the process.
-pub const SIGNAL_KILL: Signal = 9;
-/// User-defined signal 1.
-/// Action: Terminates the process.
-pub const SIGNAL_USR1: Signal = 10;
-/// Invalid memory reference.
-/// Action: Terminates the process.
-pub const SIGNAL_SEGV: Signal = 11;
-/// User-defined signal 2.
-/// Action: Terminates the process.
-pub const SIGNAL_USR2: Signal = 12;
-/// Write on a pipe with no one to read it.
-/// Action: Ignored.
-pub const SIGNAL_PIPE: Signal = 13;
-/// Alarm clock.
-/// Action: Terminates the process.
-pub const SIGNAL_ALRM: Signal = 14;
-/// Termination signal.
-/// Action: Terminates the process.
-pub const SIGNAL_TERM: Signal = 15;
-/// Child process terminated, stopped, or continued.
-/// Action: Ignored.
-pub const SIGNAL_CHLD: Signal = 16;
-/// Continue executing, if stopped.
-/// Action: Continues executing, if stopped.
-pub const SIGNAL_CONT: Signal = 17;
-/// Stop executing.
-/// Action: Stops executing.
-pub const SIGNAL_STOP: Signal = 18;
-/// Terminal stop signal.
-/// Action: Stops executing.
-pub const SIGNAL_TSTP: Signal = 19;
-/// Background process attempting read.
-/// Action: Stops executing.
-pub const SIGNAL_TTIN: Signal = 20;
-/// Background process attempting write.
-/// Action: Stops executing.
-pub const SIGNAL_TTOU: Signal = 21;
-/// High bandwidth data is available at a socket.
-/// Action: Ignored.
-pub const SIGNAL_URG: Signal = 22;
-/// CPU time limit exceeded.
-/// Action: Terminates the process.
-pub const SIGNAL_XCPU: Signal = 23;
-/// File size limit exceeded.
-/// Action: Terminates the process.
-pub const SIGNAL_XFSZ: Signal = 24;
-/// Virtual timer expired.
-/// Action: Terminates the process.
-pub const SIGNAL_VTALRM: Signal = 25;
-/// Profiling timer expired.
-/// Action: Terminates the process.
-pub const SIGNAL_PROF: Signal = 26;
-/// Window changed.
-/// Action: Ignored.
-pub const SIGNAL_WINCH: Signal = 27;
-/// I/O possible.
-/// Action: Terminates the process.
-pub const SIGNAL_POLL: Signal = 28;
-/// Power failure.
-/// Action: Terminates the process.
-pub const SIGNAL_PWR: Signal = 29;
-/// Bad system call.
-/// Action: Terminates the process.
-pub const SIGNAL_SYS: Signal = 30;
-pub type Riflags = u16;
-/// Returns the message without removing it from the socket's receive queue.
-pub const RIFLAGS_RECV_PEEK: Riflags = 0x1;
-/// On byte-stream sockets, block until the full amount of data can be returned.
-pub const RIFLAGS_RECV_WAITALL: Riflags = 0x2;
-pub type Roflags = u16;
-/// Returned by `sock_recv`: Message data has been truncated.
-pub const ROFLAGS_RECV_DATA_TRUNCATED: Roflags = 0x1;
-pub type Siflags = u16;
-pub type Sdflags = u8;
-/// Disables further receive operations.
-pub const SDFLAGS_RD: Sdflags = 0x1;
-/// Disables further send operations.
-pub const SDFLAGS_WR: Sdflags = 0x2;
-pub type Preopentype = u8;
-/// A pre-opened directory.
-pub const PREOPENTYPE_DIR: Preopentype = 0;
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct PrestatDir {
- /// The length of the directory name for use with `fd_prestat_dir_name`.
- pub pr_name_len: Size,
-}
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub union PrestatU {
- pub dir: PrestatDir,
-}
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct Prestat {
- pub tag: Preopentype,
- pub u: PrestatU,
-}
-
-/// Read command-line argument data.
-/// The size of the array should match that returned by `args_sizes_get`
-pub unsafe fn args_get(argv: *mut *mut u8, argv_buf: *mut u8) -> Result<()> {
- let rc = wasi_snapshot_preview1::args_get(argv, argv_buf);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Return command-line argument data sizes.
-///
-/// ## Return
-///
-/// * `argc` - The number of arguments.
-/// * `argv_buf_size` - The size of the argument string data.
-pub unsafe fn args_sizes_get() -> Result<(Size, Size)> {
- let mut argc = MaybeUninit::uninit();
- let mut argv_buf_size = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::args_sizes_get(argc.as_mut_ptr(), argv_buf_size.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok((argc.assume_init(), argv_buf_size.assume_init()))
- }
-}
-
-/// Read environment variable data.
-/// The sizes of the buffers should match that returned by `environ_sizes_get`.
-pub unsafe fn environ_get(environ: *mut *mut u8, environ_buf: *mut u8) -> Result<()> {
- let rc = wasi_snapshot_preview1::environ_get(environ, environ_buf);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Return environment variable data sizes.
-///
-/// ## Return
-///
-/// * `environc` - The number of environment variable arguments.
-/// * `environ_buf_size` - The size of the environment variable data.
-pub unsafe fn environ_sizes_get() -> Result<(Size, Size)> {
- let mut environc = MaybeUninit::uninit();
- let mut environ_buf_size = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::environ_sizes_get(
- environc.as_mut_ptr(),
- environ_buf_size.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok((environc.assume_init(), environ_buf_size.assume_init()))
- }
-}
-
-/// Return the resolution of a clock.
-/// Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
-/// return `errno::inval`.
-/// Note: This is similar to `clock_getres` in POSIX.
-///
-/// ## Parameters
-///
-/// * `id` - The clock for which to return the resolution.
-///
-/// ## Return
-///
-/// * `resolution` - The resolution of the clock.
-pub unsafe fn clock_res_get(id: Clockid) -> Result<Timestamp> {
- let mut resolution = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::clock_res_get(id, resolution.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(resolution.assume_init())
- }
-}
-
-/// Return the time value of a clock.
-/// Note: This is similar to `clock_gettime` in POSIX.
-///
-/// ## Parameters
-///
-/// * `id` - The clock for which to return the time.
-/// * `precision` - The maximum lag (exclusive) that the returned time value may have, compared to its actual value.
-///
-/// ## Return
-///
-/// * `time` - The time value of the clock.
-pub unsafe fn clock_time_get(id: Clockid, precision: Timestamp) -> Result<Timestamp> {
- let mut time = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::clock_time_get(id, precision, time.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(time.assume_init())
- }
-}
-
-/// Provide file advisory information on a file descriptor.
-/// Note: This is similar to `posix_fadvise` in POSIX.
-///
-/// ## Parameters
-///
-/// * `offset` - The offset within the file to which the advisory applies.
-/// * `len` - The length of the region to which the advisory applies.
-/// * `advice` - The advice.
-pub unsafe fn fd_advise(fd: Fd, offset: Filesize, len: Filesize, advice: Advice) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_advise(fd, offset, len, advice);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Force the allocation of space in a file.
-/// Note: This is similar to `posix_fallocate` in POSIX.
-///
-/// ## Parameters
-///
-/// * `offset` - The offset at which to start the allocation.
-/// * `len` - The length of the area that is allocated.
-pub unsafe fn fd_allocate(fd: Fd, offset: Filesize, len: Filesize) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_allocate(fd, offset, len);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Close a file descriptor.
-/// Note: This is similar to `close` in POSIX.
-pub unsafe fn fd_close(fd: Fd) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_close(fd);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Synchronize the data of a file to disk.
-/// Note: This is similar to `fdatasync` in POSIX.
-pub unsafe fn fd_datasync(fd: Fd) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_datasync(fd);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Get the attributes of a file descriptor.
-/// Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields.
-///
-/// ## Return
-///
-/// * `stat` - The buffer where the file descriptor's attributes are stored.
-pub unsafe fn fd_fdstat_get(fd: Fd) -> Result<Fdstat> {
- let mut stat = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_fdstat_get(fd, stat.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(stat.assume_init())
- }
-}
-
-/// Adjust the flags associated with a file descriptor.
-/// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
-///
-/// ## Parameters
-///
-/// * `flags` - The desired values of the file descriptor flags.
-pub unsafe fn fd_fdstat_set_flags(fd: Fd, flags: Fdflags) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_fdstat_set_flags(fd, flags);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Adjust the rights associated with a file descriptor.
-/// This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
-///
-/// ## Parameters
-///
-/// * `fs_rights_base` - The desired rights of the file descriptor.
-pub unsafe fn fd_fdstat_set_rights(
- fd: Fd,
- fs_rights_base: Rights,
- fs_rights_inheriting: Rights,
-) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_fdstat_set_rights(fd, fs_rights_base, fs_rights_inheriting);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Return the attributes of an open file.
-///
-/// ## Return
-///
-/// * `buf` - The buffer where the file's attributes are stored.
-pub unsafe fn fd_filestat_get(fd: Fd) -> Result<Filestat> {
- let mut buf = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_filestat_get(fd, buf.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(buf.assume_init())
- }
-}
-
-/// Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
-/// Note: This is similar to `ftruncate` in POSIX.
-///
-/// ## Parameters
-///
-/// * `size` - The desired file size.
-pub unsafe fn fd_filestat_set_size(fd: Fd, size: Filesize) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_filestat_set_size(fd, size);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Adjust the timestamps of an open file or directory.
-/// Note: This is similar to `futimens` in POSIX.
-///
-/// ## Parameters
-///
-/// * `atim` - The desired values of the data access timestamp.
-/// * `mtim` - The desired values of the data modification timestamp.
-/// * `fst_flags` - A bitmask indicating which timestamps to adjust.
-pub unsafe fn fd_filestat_set_times(
- fd: Fd,
- atim: Timestamp,
- mtim: Timestamp,
- fst_flags: Fstflags,
-) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_filestat_set_times(fd, atim, mtim, fst_flags);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Read from a file descriptor, without using and updating the file descriptor's offset.
-/// Note: This is similar to `preadv` in POSIX.
-///
-/// ## Parameters
-///
-/// * `iovs` - List of scatter/gather vectors in which to store data.
-/// * `offset` - The offset within the file at which to read.
-///
-/// ## Return
-///
-/// * `nread` - The number of bytes read.
-pub unsafe fn fd_pread(fd: Fd, iovs: IovecArray<'_>, offset: Filesize) -> Result<Size> {
- let mut nread = MaybeUninit::uninit();
- let rc =
- wasi_snapshot_preview1::fd_pread(fd, iovs.as_ptr(), iovs.len(), offset, nread.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(nread.assume_init())
- }
-}
-
-/// Return a description of the given preopened file descriptor.
-///
-/// ## Return
-///
-/// * `buf` - The buffer where the description is stored.
-pub unsafe fn fd_prestat_get(fd: Fd) -> Result<Prestat> {
- let mut buf = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_prestat_get(fd, buf.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(buf.assume_init())
- }
-}
-
-/// Return a description of the given preopened file descriptor.
-///
-/// ## Parameters
-///
-/// * `path` - A buffer into which to write the preopened directory name.
-pub unsafe fn fd_prestat_dir_name(fd: Fd, path: *mut u8, path_len: Size) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_prestat_dir_name(fd, path, path_len);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Write to a file descriptor, without using and updating the file descriptor's offset.
-/// Note: This is similar to `pwritev` in POSIX.
-///
-/// ## Parameters
-///
-/// * `iovs` - List of scatter/gather vectors from which to retrieve data.
-/// * `offset` - The offset within the file at which to write.
-///
-/// ## Return
-///
-/// * `nwritten` - The number of bytes written.
-pub unsafe fn fd_pwrite(fd: Fd, iovs: CiovecArray<'_>, offset: Filesize) -> Result<Size> {
- let mut nwritten = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_pwrite(
- fd,
- iovs.as_ptr(),
- iovs.len(),
- offset,
- nwritten.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(nwritten.assume_init())
- }
-}
-
-/// Read from a file descriptor.
-/// Note: This is similar to `readv` in POSIX.
-///
-/// ## Parameters
-///
-/// * `iovs` - List of scatter/gather vectors to which to store data.
-///
-/// ## Return
-///
-/// * `nread` - The number of bytes read.
-pub unsafe fn fd_read(fd: Fd, iovs: IovecArray<'_>) -> Result<Size> {
- let mut nread = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_read(fd, iovs.as_ptr(), iovs.len(), nread.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(nread.assume_init())
- }
-}
-
-/// Read directory entries from a directory.
-/// When successful, the contents of the output buffer consist of a sequence of
-/// directory entries. Each directory entry consists of a `dirent` object,
-/// followed by `dirent::d_namlen` bytes holding the name of the directory
-/// entry.
-/// This function fills the output buffer as much as possible, potentially
-/// truncating the last directory entry. This allows the caller to grow its
-/// read buffer size in case it's too small to fit a single large directory
-/// entry, or skip the oversized directory entry.
-///
-/// ## Parameters
-///
-/// * `buf` - The buffer where directory entries are stored
-/// * `cookie` - The location within the directory to start reading
-///
-/// ## Return
-///
-/// * `bufused` - The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
-pub unsafe fn fd_readdir(fd: Fd, buf: *mut u8, buf_len: Size, cookie: Dircookie) -> Result<Size> {
- let mut bufused = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_readdir(fd, buf, buf_len, cookie, bufused.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(bufused.assume_init())
- }
-}
-
-/// Atomically replace a file descriptor by renumbering another file descriptor.
-/// Due to the strong focus on thread safety, this environment does not provide
-/// a mechanism to duplicate or renumber a file descriptor to an arbitrary
-/// number, like `dup2()`. This would be prone to race conditions, as an actual
-/// file descriptor with the same number could be allocated by a different
-/// thread at the same time.
-/// This function provides a way to atomically renumber file descriptors, which
-/// would disappear if `dup2()` were to be removed entirely.
-///
-/// ## Parameters
-///
-/// * `to` - The file descriptor to overwrite.
-pub unsafe fn fd_renumber(fd: Fd, to: Fd) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_renumber(fd, to);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Move the offset of a file descriptor.
-/// Note: This is similar to `lseek` in POSIX.
-///
-/// ## Parameters
-///
-/// * `offset` - The number of bytes to move.
-/// * `whence` - The base from which the offset is relative.
-///
-/// ## Return
-///
-/// * `newoffset` - The new offset of the file descriptor, relative to the start of the file.
-pub unsafe fn fd_seek(fd: Fd, offset: Filedelta, whence: Whence) -> Result<Filesize> {
- let mut newoffset = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_seek(fd, offset, whence, newoffset.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(newoffset.assume_init())
- }
-}
-
-/// Synchronize the data and metadata of a file to disk.
-/// Note: This is similar to `fsync` in POSIX.
-pub unsafe fn fd_sync(fd: Fd) -> Result<()> {
- let rc = wasi_snapshot_preview1::fd_sync(fd);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Return the current offset of a file descriptor.
-/// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX.
-///
-/// ## Return
-///
-/// * `offset` - The current offset of the file descriptor, relative to the start of the file.
-pub unsafe fn fd_tell(fd: Fd) -> Result<Filesize> {
- let mut offset = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_tell(fd, offset.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(offset.assume_init())
- }
-}
-
-/// Write to a file descriptor.
-/// Note: This is similar to `writev` in POSIX.
-///
-/// ## Parameters
-///
-/// * `iovs` - List of scatter/gather vectors from which to retrieve data.
-///
-/// ## Return
-///
-/// * `nwritten` - The number of bytes written.
-pub unsafe fn fd_write(fd: Fd, iovs: CiovecArray<'_>) -> Result<Size> {
- let mut nwritten = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::fd_write(fd, iovs.as_ptr(), iovs.len(), nwritten.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(nwritten.assume_init())
- }
-}
-
-/// Create a directory.
-/// Note: This is similar to `mkdirat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `path` - The path at which to create the directory.
-pub unsafe fn path_create_directory(fd: Fd, path: &str) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_create_directory(fd, path.as_ptr(), path.len());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Return the attributes of a file or directory.
-/// Note: This is similar to `stat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `flags` - Flags determining the method of how the path is resolved.
-/// * `path` - The path of the file or directory to inspect.
-///
-/// ## Return
-///
-/// * `buf` - The buffer where the file's attributes are stored.
-pub unsafe fn path_filestat_get(fd: Fd, flags: Lookupflags, path: &str) -> Result<Filestat> {
- let mut buf = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::path_filestat_get(
- fd,
- flags,
- path.as_ptr(),
- path.len(),
- buf.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(buf.assume_init())
- }
-}
-
-/// Adjust the timestamps of a file or directory.
-/// Note: This is similar to `utimensat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `flags` - Flags determining the method of how the path is resolved.
-/// * `path` - The path of the file or directory to operate on.
-/// * `atim` - The desired values of the data access timestamp.
-/// * `mtim` - The desired values of the data modification timestamp.
-/// * `fst_flags` - A bitmask indicating which timestamps to adjust.
-pub unsafe fn path_filestat_set_times(
- fd: Fd,
- flags: Lookupflags,
- path: &str,
- atim: Timestamp,
- mtim: Timestamp,
- fst_flags: Fstflags,
-) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_filestat_set_times(
- fd,
- flags,
- path.as_ptr(),
- path.len(),
- atim,
- mtim,
- fst_flags,
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Create a hard link.
-/// Note: This is similar to `linkat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `old_flags` - Flags determining the method of how the path is resolved.
-/// * `old_path` - The source path from which to link.
-/// * `new_fd` - The working directory at which the resolution of the new path starts.
-/// * `new_path` - The destination path at which to create the hard link.
-pub unsafe fn path_link(
- old_fd: Fd,
- old_flags: Lookupflags,
- old_path: &str,
- new_fd: Fd,
- new_path: &str,
-) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_link(
- old_fd,
- old_flags,
- old_path.as_ptr(),
- old_path.len(),
- new_fd,
- new_path.as_ptr(),
- new_path.len(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Open a file or directory.
-/// The returned file descriptor is not guaranteed to be the lowest-numbered
-/// file descriptor not currently open; it is randomized to prevent
-/// applications from depending on making assumptions about indexes, since this
-/// is error-prone in multi-threaded contexts. The returned file descriptor is
-/// guaranteed to be less than 2**31.
-/// Note: This is similar to `openat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `dirflags` - Flags determining the method of how the path is resolved.
-/// * `path` - The relative path of the file or directory to open, relative to the
-/// `path_open::fd` directory.
-/// * `oflags` - The method by which to open the file.
-/// * `fs_rights_base` - The initial rights of the newly created file descriptor. The
-/// implementation is allowed to return a file descriptor with fewer rights
-/// than specified, if and only if those rights do not apply to the type of
-/// file being opened.
-/// The *base* rights are rights that will apply to operations using the file
-/// descriptor itself, while the *inheriting* rights are rights that apply to
-/// file descriptors derived from it.
-///
-/// ## Return
-///
-/// * `opened_fd` - The file descriptor of the file that has been opened.
-pub unsafe fn path_open(
- fd: Fd,
- dirflags: Lookupflags,
- path: &str,
- oflags: Oflags,
- fs_rights_base: Rights,
- fs_rights_inheriting: Rights,
- fdflags: Fdflags,
-) -> Result<Fd> {
- let mut opened_fd = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::path_open(
- fd,
- dirflags,
- path.as_ptr(),
- path.len(),
- oflags,
- fs_rights_base,
- fs_rights_inheriting,
- fdflags,
- opened_fd.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(opened_fd.assume_init())
- }
-}
-
-/// Read the contents of a symbolic link.
-/// Note: This is similar to `readlinkat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `path` - The path of the symbolic link from which to read.
-/// * `buf` - The buffer to which to write the contents of the symbolic link.
-///
-/// ## Return
-///
-/// * `bufused` - The number of bytes placed in the buffer.
-pub unsafe fn path_readlink(fd: Fd, path: &str, buf: *mut u8, buf_len: Size) -> Result<Size> {
- let mut bufused = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::path_readlink(
- fd,
- path.as_ptr(),
- path.len(),
- buf,
- buf_len,
- bufused.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(bufused.assume_init())
- }
-}
-
-/// Remove a directory.
-/// Return `errno::notempty` if the directory is not empty.
-/// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
-///
-/// ## Parameters
-///
-/// * `path` - The path to a directory to remove.
-pub unsafe fn path_remove_directory(fd: Fd, path: &str) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_remove_directory(fd, path.as_ptr(), path.len());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Rename a file or directory.
-/// Note: This is similar to `renameat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `old_path` - The source path of the file or directory to rename.
-/// * `new_fd` - The working directory at which the resolution of the new path starts.
-/// * `new_path` - The destination path to which to rename the file or directory.
-pub unsafe fn path_rename(fd: Fd, old_path: &str, new_fd: Fd, new_path: &str) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_rename(
- fd,
- old_path.as_ptr(),
- old_path.len(),
- new_fd,
- new_path.as_ptr(),
- new_path.len(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Create a symbolic link.
-/// Note: This is similar to `symlinkat` in POSIX.
-///
-/// ## Parameters
-///
-/// * `old_path` - The contents of the symbolic link.
-/// * `new_path` - The destination path at which to create the symbolic link.
-pub unsafe fn path_symlink(old_path: &str, fd: Fd, new_path: &str) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_symlink(
- old_path.as_ptr(),
- old_path.len(),
- fd,
- new_path.as_ptr(),
- new_path.len(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Unlink a file.
-/// Return `errno::isdir` if the path refers to a directory.
-/// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
-///
-/// ## Parameters
-///
-/// * `path` - The path to a file to unlink.
-pub unsafe fn path_unlink_file(fd: Fd, path: &str) -> Result<()> {
- let rc = wasi_snapshot_preview1::path_unlink_file(fd, path.as_ptr(), path.len());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Concurrently poll for the occurrence of a set of events.
-///
-/// ## Parameters
-///
-/// * `r#in` - The events to which to subscribe.
-/// * `out` - The events that have occurred.
-/// * `nsubscriptions` - Both the number of subscriptions and events.
-///
-/// ## Return
-///
-/// * `nevents` - The number of events stored.
-pub unsafe fn poll_oneoff(
- r#in: *const Subscription,
- out: *mut Event,
- nsubscriptions: Size,
-) -> Result<Size> {
- let mut nevents = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::poll_oneoff(r#in, out, nsubscriptions, nevents.as_mut_ptr());
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(nevents.assume_init())
- }
-}
-
-/// Terminate the process normally. An exit code of 0 indicates successful
-/// termination of the program. The meanings of other values is dependent on
-/// the environment.
-///
-/// ## Parameters
-///
-/// * `rval` - The exit code returned by the process.
-pub unsafe fn proc_exit(rval: Exitcode) {
- wasi_snapshot_preview1::proc_exit(rval);
-}
-
-/// Send a signal to the process of the calling thread.
-/// Note: This is similar to `raise` in POSIX.
-///
-/// ## Parameters
-///
-/// * `sig` - The signal condition to trigger.
-pub unsafe fn proc_raise(sig: Signal) -> Result<()> {
- let rc = wasi_snapshot_preview1::proc_raise(sig);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Temporarily yield execution of the calling thread.
-/// Note: This is similar to `sched_yield` in POSIX.
-pub unsafe fn sched_yield() -> Result<()> {
- let rc = wasi_snapshot_preview1::sched_yield();
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Write high-quality random data into a buffer.
-/// This function blocks when the implementation is unable to immediately
-/// provide sufficient high-quality random data.
-/// This function may execute slowly, so when large mounts of random data are
-/// required, it's advisable to use this function to seed a pseudo-random
-/// number generator, rather than to provide the random data directly.
-///
-/// ## Parameters
-///
-/// * `buf` - The buffer to fill with random data.
-pub unsafe fn random_get(buf: *mut u8, buf_len: Size) -> Result<()> {
- let rc = wasi_snapshot_preview1::random_get(buf, buf_len);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-/// Receive a message from a socket.
-/// Note: This is similar to `recv` in POSIX, though it also supports reading
-/// the data into multiple buffers in the manner of `readv`.
-///
-/// ## Parameters
-///
-/// * `ri_data` - List of scatter/gather vectors to which to store data.
-/// * `ri_flags` - Message flags.
-///
-/// ## Return
-///
-/// * `ro_datalen` - Number of bytes stored in ri_data.
-/// * `ro_flags` - Message flags.
-pub unsafe fn sock_recv(
- fd: Fd,
- ri_data: IovecArray<'_>,
- ri_flags: Riflags,
-) -> Result<(Size, Roflags)> {
- let mut ro_datalen = MaybeUninit::uninit();
- let mut ro_flags = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::sock_recv(
- fd,
- ri_data.as_ptr(),
- ri_data.len(),
- ri_flags,
- ro_datalen.as_mut_ptr(),
- ro_flags.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok((ro_datalen.assume_init(), ro_flags.assume_init()))
- }
-}
-
-/// Send a message on a socket.
-/// Note: This is similar to `send` in POSIX, though it also supports writing
-/// the data from multiple buffers in the manner of `writev`.
-///
-/// ## Parameters
-///
-/// * `si_data` - List of scatter/gather vectors to which to retrieve data
-/// * `si_flags` - Message flags.
-///
-/// ## Return
-///
-/// * `so_datalen` - Number of bytes transmitted.
-pub unsafe fn sock_send(fd: Fd, si_data: CiovecArray<'_>, si_flags: Siflags) -> Result<Size> {
- let mut so_datalen = MaybeUninit::uninit();
- let rc = wasi_snapshot_preview1::sock_send(
- fd,
- si_data.as_ptr(),
- si_data.len(),
- si_flags,
- so_datalen.as_mut_ptr(),
- );
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(so_datalen.assume_init())
- }
-}
-
-/// Shut down socket send and receive channels.
-/// Note: This is similar to `shutdown` in POSIX.
-///
-/// ## Parameters
-///
-/// * `how` - Which channels on the socket to shut down.
-pub unsafe fn sock_shutdown(fd: Fd, how: Sdflags) -> Result<()> {
- let rc = wasi_snapshot_preview1::sock_shutdown(fd, how);
- if let Some(err) = Error::from_raw_error(rc) {
- Err(err)
- } else {
- Ok(())
- }
-}
-
-pub mod wasi_snapshot_preview1 {
- use super::*;
- #[link(wasm_import_module = "wasi_snapshot_preview1")]
- extern "C" {
- /// Read command-line argument data.
- /// The size of the array should match that returned by `args_sizes_get`
- pub fn args_get(argv: *mut *mut u8, argv_buf: *mut u8) -> Errno;
- /// Return command-line argument data sizes.
- pub fn args_sizes_get(argc: *mut Size, argv_buf_size: *mut Size) -> Errno;
- /// Read environment variable data.
- /// The sizes of the buffers should match that returned by `environ_sizes_get`.
- pub fn environ_get(environ: *mut *mut u8, environ_buf: *mut u8) -> Errno;
- /// Return environment variable data sizes.
- pub fn environ_sizes_get(environc: *mut Size, environ_buf_size: *mut Size) -> Errno;
- /// Return the resolution of a clock.
- /// Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
- /// return `errno::inval`.
- /// Note: This is similar to `clock_getres` in POSIX.
- pub fn clock_res_get(id: Clockid, resolution: *mut Timestamp) -> Errno;
- /// Return the time value of a clock.
- /// Note: This is similar to `clock_gettime` in POSIX.
- pub fn clock_time_get(id: Clockid, precision: Timestamp, time: *mut Timestamp) -> Errno;
- /// Provide file advisory information on a file descriptor.
- /// Note: This is similar to `posix_fadvise` in POSIX.
- pub fn fd_advise(fd: Fd, offset: Filesize, len: Filesize, advice: Advice) -> Errno;
- /// Force the allocation of space in a file.
- /// Note: This is similar to `posix_fallocate` in POSIX.
- pub fn fd_allocate(fd: Fd, offset: Filesize, len: Filesize) -> Errno;
- /// Close a file descriptor.
- /// Note: This is similar to `close` in POSIX.
- pub fn fd_close(fd: Fd) -> Errno;
- /// Synchronize the data of a file to disk.
- /// Note: This is similar to `fdatasync` in POSIX.
- pub fn fd_datasync(fd: Fd) -> Errno;
- /// Get the attributes of a file descriptor.
- /// Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields.
- pub fn fd_fdstat_get(fd: Fd, stat: *mut Fdstat) -> Errno;
- /// Adjust the flags associated with a file descriptor.
- /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
- pub fn fd_fdstat_set_flags(fd: Fd, flags: Fdflags) -> Errno;
- /// Adjust the rights associated with a file descriptor.
- /// This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
- pub fn fd_fdstat_set_rights(
- fd: Fd,
- fs_rights_base: Rights,
- fs_rights_inheriting: Rights,
- ) -> Errno;
- /// Return the attributes of an open file.
- pub fn fd_filestat_get(fd: Fd, buf: *mut Filestat) -> Errno;
- /// Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
- /// Note: This is similar to `ftruncate` in POSIX.
- pub fn fd_filestat_set_size(fd: Fd, size: Filesize) -> Errno;
- /// Adjust the timestamps of an open file or directory.
- /// Note: This is similar to `futimens` in POSIX.
- pub fn fd_filestat_set_times(
- fd: Fd,
- atim: Timestamp,
- mtim: Timestamp,
- fst_flags: Fstflags,
- ) -> Errno;
- /// Read from a file descriptor, without using and updating the file descriptor's offset.
- /// Note: This is similar to `preadv` in POSIX.
- pub fn fd_pread(
- fd: Fd,
- iovs_ptr: *const Iovec,
- iovs_len: usize,
- offset: Filesize,
- nread: *mut Size,
- ) -> Errno;
- /// Return a description of the given preopened file descriptor.
- pub fn fd_prestat_get(fd: Fd, buf: *mut Prestat) -> Errno;
- /// Return a description of the given preopened file descriptor.
- pub fn fd_prestat_dir_name(fd: Fd, path: *mut u8, path_len: Size) -> Errno;
- /// Write to a file descriptor, without using and updating the file descriptor's offset.
- /// Note: This is similar to `pwritev` in POSIX.
- pub fn fd_pwrite(
- fd: Fd,
- iovs_ptr: *const Ciovec,
- iovs_len: usize,
- offset: Filesize,
- nwritten: *mut Size,
- ) -> Errno;
- /// Read from a file descriptor.
- /// Note: This is similar to `readv` in POSIX.
- pub fn fd_read(fd: Fd, iovs_ptr: *const Iovec, iovs_len: usize, nread: *mut Size) -> Errno;
- /// Read directory entries from a directory.
- /// When successful, the contents of the output buffer consist of a sequence of
- /// directory entries. Each directory entry consists of a `dirent` object,
- /// followed by `dirent::d_namlen` bytes holding the name of the directory
- /// entry.
- /// This function fills the output buffer as much as possible, potentially
- /// truncating the last directory entry. This allows the caller to grow its
- /// read buffer size in case it's too small to fit a single large directory
- /// entry, or skip the oversized directory entry.
- pub fn fd_readdir(
- fd: Fd,
- buf: *mut u8,
- buf_len: Size,
- cookie: Dircookie,
- bufused: *mut Size,
- ) -> Errno;
- /// Atomically replace a file descriptor by renumbering another file descriptor.
- /// Due to the strong focus on thread safety, this environment does not provide
- /// a mechanism to duplicate or renumber a file descriptor to an arbitrary
- /// number, like `dup2()`. This would be prone to race conditions, as an actual
- /// file descriptor with the same number could be allocated by a different
- /// thread at the same time.
- /// This function provides a way to atomically renumber file descriptors, which
- /// would disappear if `dup2()` were to be removed entirely.
- pub fn fd_renumber(fd: Fd, to: Fd) -> Errno;
- /// Move the offset of a file descriptor.
- /// Note: This is similar to `lseek` in POSIX.
- pub fn fd_seek(
- fd: Fd,
- offset: Filedelta,
- whence: Whence,
- newoffset: *mut Filesize,
- ) -> Errno;
- /// Synchronize the data and metadata of a file to disk.
- /// Note: This is similar to `fsync` in POSIX.
- pub fn fd_sync(fd: Fd) -> Errno;
- /// Return the current offset of a file descriptor.
- /// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX.
- pub fn fd_tell(fd: Fd, offset: *mut Filesize) -> Errno;
- /// Write to a file descriptor.
- /// Note: This is similar to `writev` in POSIX.
- pub fn fd_write(
- fd: Fd,
- iovs_ptr: *const Ciovec,
- iovs_len: usize,
- nwritten: *mut Size,
- ) -> Errno;
- /// Create a directory.
- /// Note: This is similar to `mkdirat` in POSIX.
- pub fn path_create_directory(fd: Fd, path_ptr: *const u8, path_len: usize) -> Errno;
- /// Return the attributes of a file or directory.
- /// Note: This is similar to `stat` in POSIX.
- pub fn path_filestat_get(
- fd: Fd,
- flags: Lookupflags,
- path_ptr: *const u8,
- path_len: usize,
- buf: *mut Filestat,
- ) -> Errno;
- /// Adjust the timestamps of a file or directory.
- /// Note: This is similar to `utimensat` in POSIX.
- pub fn path_filestat_set_times(
- fd: Fd,
- flags: Lookupflags,
- path_ptr: *const u8,
- path_len: usize,
- atim: Timestamp,
- mtim: Timestamp,
- fst_flags: Fstflags,
- ) -> Errno;
- /// Create a hard link.
- /// Note: This is similar to `linkat` in POSIX.
- pub fn path_link(
- old_fd: Fd,
- old_flags: Lookupflags,
- old_path_ptr: *const u8,
- old_path_len: usize,
- new_fd: Fd,
- new_path_ptr: *const u8,
- new_path_len: usize,
- ) -> Errno;
- /// Open a file or directory.
- /// The returned file descriptor is not guaranteed to be the lowest-numbered
- /// file descriptor not currently open; it is randomized to prevent
- /// applications from depending on making assumptions about indexes, since this
- /// is error-prone in multi-threaded contexts. The returned file descriptor is
- /// guaranteed to be less than 2**31.
- /// Note: This is similar to `openat` in POSIX.
- pub fn path_open(
- fd: Fd,
- dirflags: Lookupflags,
- path_ptr: *const u8,
- path_len: usize,
- oflags: Oflags,
- fs_rights_base: Rights,
- fs_rights_inheriting: Rights,
- fdflags: Fdflags,
- opened_fd: *mut Fd,
- ) -> Errno;
- /// Read the contents of a symbolic link.
- /// Note: This is similar to `readlinkat` in POSIX.
- pub fn path_readlink(
- fd: Fd,
- path_ptr: *const u8,
- path_len: usize,
- buf: *mut u8,
- buf_len: Size,
- bufused: *mut Size,
- ) -> Errno;
- /// Remove a directory.
- /// Return `errno::notempty` if the directory is not empty.
- /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
- pub fn path_remove_directory(fd: Fd, path_ptr: *const u8, path_len: usize) -> Errno;
- /// Rename a file or directory.
- /// Note: This is similar to `renameat` in POSIX.
- pub fn path_rename(
- fd: Fd,
- old_path_ptr: *const u8,
- old_path_len: usize,
- new_fd: Fd,
- new_path_ptr: *const u8,
- new_path_len: usize,
- ) -> Errno;
- /// Create a symbolic link.
- /// Note: This is similar to `symlinkat` in POSIX.
- pub fn path_symlink(
- old_path_ptr: *const u8,
- old_path_len: usize,
- fd: Fd,
- new_path_ptr: *const u8,
- new_path_len: usize,
- ) -> Errno;
- /// Unlink a file.
- /// Return `errno::isdir` if the path refers to a directory.
- /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
- pub fn path_unlink_file(fd: Fd, path_ptr: *const u8, path_len: usize) -> Errno;
- /// Concurrently poll for the occurrence of a set of events.
- pub fn poll_oneoff(
- r#in: *const Subscription,
- out: *mut Event,
- nsubscriptions: Size,
- nevents: *mut Size,
- ) -> Errno;
- /// Terminate the process normally. An exit code of 0 indicates successful
- /// termination of the program. The meanings of other values is dependent on
- /// the environment.
- pub fn proc_exit(rval: Exitcode) -> !;
- /// Send a signal to the process of the calling thread.
- /// Note: This is similar to `raise` in POSIX.
- pub fn proc_raise(sig: Signal) -> Errno;
- /// Temporarily yield execution of the calling thread.
- /// Note: This is similar to `sched_yield` in POSIX.
- pub fn sched_yield() -> Errno;
- /// Write high-quality random data into a buffer.
- /// This function blocks when the implementation is unable to immediately
- /// provide sufficient high-quality random data.
- /// This function may execute slowly, so when large mounts of random data are
- /// required, it's advisable to use this function to seed a pseudo-random
- /// number generator, rather than to provide the random data directly.
- pub fn random_get(buf: *mut u8, buf_len: Size) -> Errno;
- /// Receive a message from a socket.
- /// Note: This is similar to `recv` in POSIX, though it also supports reading
- /// the data into multiple buffers in the manner of `readv`.
- pub fn sock_recv(
- fd: Fd,
- ri_data_ptr: *const Iovec,
- ri_data_len: usize,
- ri_flags: Riflags,
- ro_datalen: *mut Size,
- ro_flags: *mut Roflags,
- ) -> Errno;
- /// Send a message on a socket.
- /// Note: This is similar to `send` in POSIX, though it also supports writing
- /// the data from multiple buffers in the manner of `writev`.
- pub fn sock_send(
- fd: Fd,
- si_data_ptr: *const Ciovec,
- si_data_len: usize,
- si_flags: Siflags,
- so_datalen: *mut Size,
- ) -> Errno;
- /// Shut down socket send and receive channels.
- /// Note: This is similar to `shutdown` in POSIX.
- pub fn sock_shutdown(fd: Fd, how: Sdflags) -> Errno;
- }
-}
diff --git a/version b/version
index e5a10be83..d624c5395 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.64.0 (a55dd71d5 2022-09-19) \ No newline at end of file
+1.65.0 (897e37553 2022-11-02) \ No newline at end of file
diff --git a/x.py b/x.py
index 0289056fd..6df4033d5 100755
--- a/x.py
+++ b/x.py
@@ -1,36 +1,16 @@
-#!/usr/bin/env bash
+#!/usr/bin/env python3
+# Some systems don't have `python3` in their PATH. This isn't supported by x.py directly;
+# they should use `x` or `x.ps1` instead.
-# Modern Linux and macOS systems commonly only have a thing called `python3` and
-# not `python`, while Windows commonly does not have `python3`, so we cannot
-# directly use python in the shebang and have it consistently work. Instead we
-# embed some bash to look for a python to run the rest of the script.
-#
-# On Windows, `py -3` sometimes works. We need to try it first because `python3`
-# sometimes tries to launch the app store on Windows.
-'''':
-for PYTHON in "py -3" python3 python python2; do
- if command -v $PYTHON >/dev/null; then
- exec $PYTHON "$0" "$@"
- break
- fi
-done
-echo "$0: error: did not find python installed" >&2
-exit 1
-'''
-
-# The rest of this file is Python.
-#
# This file is only a "symlink" to bootstrap.py, all logic should go there.
import os
import sys
# If this is python2, check if python3 is available and re-execute with that
-# interpreter.
+# interpreter. Only python3 allows downloading CI LLVM.
#
-# `./x.py` would not normally benefit from this because the bash above tries
-# python3 before 2, but this matters if someone ran `python x.py` and their
-# system's `python` is python2.
+# This matters if someone's system `python` is python2.
if sys.version_info.major < 3:
try:
os.execvp("py", ["py", "-3"] + sys.argv)